diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 8a11578276dab7540913940492e1d676703fc8cb..886fa96f1ee6c66ee0db06dbb82517f8db122612 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -2,7 +2,7 @@ variables: TESTV_DIR: "/usr/local/testv" LTV_DIR: "/usr/local/ltv" EVS_BE_TEST_DIR_BASOP: "/usr/local/be_2_evs_basop" - REFERENCE_BRANCH: "ivas-float-update" + FLOAT_REF_BRANCH: "ivas-float-update" BUILD_OUTPUT: "build_output.txt" SCRIPTS_DIR: "/usr/local/scripts" EXIT_CODE_NON_BE: 123 @@ -13,25 +13,45 @@ variables: SHORT_TEST_SUITE_ENCODER: "tests/codec_be_on_mr_nonselection/test_param_file.py --param_file scripts/config/self_test_basop_encoder.prm" LONG_TEST_SUITE_ENCODER: "tests/codec_be_on_mr_nonselection/test_param_file.py --param_file scripts/config/self_test_ltv_basop_encoder.prm" TEST_SUITE: "" + # These path variables are used by the pytest calls. + # They can be overwritten in the job templates to e.g. only test encoder or decoder in the chain DUT_ENCODER_PATH: "./IVAS_cod" DUT_DECODER_PATH: "./IVAS_dec" REF_ENCODER_PATH: "./IVAS_cod_ref" REF_DECODER_PATH: "./IVAS_dec_ref" + MERGE_TARGET_ENCODER_PATH: "./IVAS_cod_merge_target" + MERGE_TARGET_DECODER_PATH: "./IVAS_dec_merge_target" + # These path variables are used for building the binaries + # They should never be overwritten! + REF_ENCODER_PATH_FOR_BUILD_DO_NOT_MODIFY: "./IVAS_cod_ref" + REF_DECODER_PATH_FOR_BUILD_DO_NOT_MODIFY: "./IVAS_dec_ref" + MERGE_TARGET_ENCODER_PATH_FOR_BUILD_DO_NOT_MODIFY: "./IVAS_cod_merge_target" + MERGE_TARGET_DECODER_PATH_FOR_BUILD_DO_NOT_MODIFY: "./IVAS_dec_merge_target" LEVEL_SCALING: "1.0" IVAS_PIPELINE_NAME: '' BASOP_CI_BRANCH_PC_REPO: "basop-ci-branch" PRM_FILES: "scripts/config/self_test.prm scripts/config/self_test_ltv.prm" TESTCASE_TIMEOUT_STV: 900 TESTCASE_TIMEOUT_LTV: 2400 - TESTCASE_TIMEOUT_STV_SANITIZERS: 1800 + TESTCASE_TIMEOUT_LTV_SANITIZERS: 6000 CI_REGRESSION_THRESH_MLD: "0.1" CI_REGRESSION_THRESH_MAX_ABS_DIFF: "50" CI_REGRESSION_THRESH_SSNR: "-1" CI_REGRESSION_THRESH_ODG: "-0.05" GIT_CLEAN_FLAGS: -ffdxq INSTR_DIR: "scripts/c-code_instrument" + TESTS_DIR_CODEC_BE_ON_MR: "tests/codec_be_on_mr_nonselection" BUILD_WITH_DEBUG_MODE_INFO: "" ENCODER_TEST: "" + DELTA_ODG: "" + COMPARE_DMX: "" + SKIP_REGRESSION_CHECK: "" + FAILED_TESTCASES_LIST: "failed-testcases.txt" + ERRORS_TESTCASES_LIST: "errors-testcases.txt" + PYTEST_CACHE_ARTIFACT: "pytest_cache.zip" + FLOAT_REF_COMMIT_FILE: "float-ref-git-sha" + CUT_COMMIT_FILE: "CuT-git-sha" + MERGE_TARGET_COMMIT_FILE: "merge-target-git-sha" MANUAL_PIPELINE_TYPE: description: "Type for the manual pipeline run. Use 'pytest-compare' to run comparison test against reference float codec." value: 'default' @@ -47,6 +67,7 @@ variables: - 'complexity' - 'coverage' - 'voip-be-test' + - 'peaq-enc-passthrough' default: @@ -95,6 +116,9 @@ workflow: - if: $CI_PIPELINE_SOURCE == 'web' && $MANUAL_PIPELINE_TYPE == 'voip-be-test' variables: IVAS_PIPELINE_NAME: 'Voip BE test on $CI_COMMIT_BRANCH' + - if: $CI_PIPELINE_SOURCE == 'web' && $MANUAL_PIPELINE_TYPE == 'peaq-enc-passthrough' + variables: + IVAS_PIPELINE_NAME: 'PEAQ encoder pass-through test: $CI_COMMIT_BRANCH' - if: $CI_PIPELINE_SOURCE == 'schedule' # Scheduled in any branch variables: IVAS_PIPELINE_NAME: 'Scheduled pipeline: $CI_COMMIT_BRANCH' @@ -104,7 +128,10 @@ stages: - .pre - prevalidate - build + - check-be - test + - compare + - postvalidate - deploy # --------------------------------------------------------------- @@ -121,38 +148,114 @@ stages: echo "Commit time was $CI_COMMIT_TIMESTAMP" date | xargs echo "System time is" +.print-common-info-windows: &print-common-info-windows + - | + echo "Printing common information for build job." + echo "Current job is run on commit $CI_COMMIT_SHA" + echo "Commit time was $CI_COMMIT_TIMESTAMP" + ("echo 'System time is'", "Get-Date -Format 'dddd dd/MM/yyyy HH:mm K'") | Invoke-Expression + +# From float CI +.mr-fetch-target-branch: &mr-fetch-target-branch + # first delete local target branch to avoid conflicts when branch is cached and there are merge conflicts during fetching + # depending on chaching, the branch may not be there, so prevent failure of this command -> should maybe be done smarter later + - git branch -D $CI_MERGE_REQUEST_TARGET_BRANCH_NAME || true + # needed when depth is lower than the number of commits in the branch + - git fetch origin $CI_MERGE_REQUEST_TARGET_BRANCH_NAME:$CI_MERGE_REQUEST_TARGET_BRANCH_NAME + +# From float CI +.mr-get-target-commit: &mr-get-target-commit # compare to last target branch commit before pipeline was created + - target_commit=$(git log $CI_MERGE_REQUEST_TARGET_BRANCH_NAME -1 --oneline --before=${CI_PIPELINE_CREATED_AT} --format=%H) + +# From float CI +.merge-request-comparison-setup-codec: &merge-request-comparison-setup-codec + ### build test binaries, initial clean for paranoia reasons + - make clean + - make -j + - mv IVAS_cod IVAS_cod_test + - mv IVAS_dec IVAS_dec_test + - mv IVAS_rend IVAS_rend_test + - git restore . + + ### store the current commit hash + - source_branch_commit_sha=$(git rev-parse HEAD) + + ### checkout version to compare against + - *mr-fetch-target-branch + - *mr-get-target-commit + - git checkout $target_commit + - echo "Building reference codec at commit $target_commit" + + ### build reference binaries + - make clean + - make -j + - mv IVAS_cod IVAS_cod_ref + - mv IVAS_dec IVAS_dec_ref + - mv IVAS_rend IVAS_rend_ref + - git restore . + + # rename test binaries back + - mv IVAS_cod_test IVAS_cod + - mv IVAS_dec_test IVAS_dec + - mv IVAS_rend_test IVAS_rend + +.merge-request-comparison-check: &merge-request-comparison-check + - echo "--------------- Running merge-request-comparison-check anchor ---------------" + - if [ $zero_errors != 1 ]; then echo "Run errors encountered!"; exit $EXIT_CODE_FAIL; fi + - if [ $exit_code -ne 0 ] && [ $non_be_flag == 0 ]; then echo "Non-bitexact cases without non-BE tag encountered!"; exit $EXIT_CODE_FAIL; fi + - if [ $exit_code -ne 0 ] && [ $non_be_flag != 0 ]; then echo "Non-bitexact cases with non-BE tag encountered"; exit $EXIT_CODE_NON_BE; fi + - exit 0 + + .activate-debug-mode-info-if-set: &activate-debug-mode-info-if-set - if [ "$BUILD_WITH_DEBUG_MODE_INFO" = "true" ]; then - sed -i.bak -e "s/\/\*\ *\(#define\ *DEBUGGING\ *\)\*\//\1/g" lib_com/options.h - sed -i.bak -e "s/\/\*\ *\(#define\ *DEBUG_MODE_INFO\ *\)\*\//\1/g" lib_com/options.h - fi -.build-reference-binaries: &build-reference-binaries +.build-float-ref-binaries: &build-float-ref-binaries + - git rev-parse HEAD > $CUT_COMMIT_FILE - current_commit_sha=$(git rev-parse HEAD) ### build reference binaries - - git checkout $REFERENCE_BRANCH - - git pull + - git checkout $FLOAT_REF_BRANCH + - git pull origin $FLOAT_REF_BRANCH - *activate-debug-mode-info-if-set - make clean - make -j - - mv ./IVAS_cod ./$REF_ENCODER_PATH - - mv ./IVAS_dec ./$REF_DECODER_PATH + - mv ./IVAS_cod ./$REF_ENCODER_PATH_FOR_BUILD_DO_NOT_MODIFY + - mv ./IVAS_dec ./$REF_DECODER_PATH_FOR_BUILD_DO_NOT_MODIFY - mv ./IVAS_rend ./IVAS_rend_ref ### Return to current branch - git restore . + - git rev-parse HEAD > $FLOAT_REF_COMMIT_FILE - git checkout $current_commit_sha +.build-merge-target-binaries: &build-merge-target-binaries + - current_commit_sha=$(git rev-parse HEAD) + ### build merge target binaries + - git checkout $CI_MERGE_REQUEST_TARGET_BRANCH_NAME + - git pull origin $CI_MERGE_REQUEST_TARGET_BRANCH_NAME + - *activate-debug-mode-info-if-set + - make clean + - make -j + - mv ./IVAS_cod ./$MERGE_TARGET_ENCODER_PATH_FOR_BUILD_DO_NOT_MODIFY + - mv ./IVAS_dec ./$MERGE_TARGET_DECODER_PATH_FOR_BUILD_DO_NOT_MODIFY + - mv ./IVAS_rend ./IVAS_rend_merge_target + ### Return to current branch + - git restore . + - git rev-parse HEAD > $MERGE_TARGET_COMMIT_FILE + - git checkout $current_commit_sha -.build-reference-and-dut-binaries: &build-reference-and-dut-binaries +.build-float-ref-and-dut-binaries: &build-float-ref-and-dut-binaries ### build reference binaries - - *build-reference-binaries + - *build-float-ref-binaries ### build dut binaries - *activate-debug-mode-info-if-set - make clean - make -j -.build-and-create-reference-outputs: &build-and-create-reference-outputs - - *build-reference-and-dut-binaries +.build-and-create-float-ref-outputs: &build-and-create-float-ref-outputs + - *build-float-ref-and-dut-binaries ### prepare pytest # create short test vectors @@ -170,7 +273,7 @@ stages: - git fetch - git restore . # Just as a precaution - git checkout $BASOP_CI_BRANCH_PC_REPO - - git pull + - git pull origin $BASOP_CI_BRANCH_PC_REPO - cd - - cp -r $SCRIPTS_DIR/ci . - cp -r $SCRIPTS_DIR/scripts . @@ -181,11 +284,31 @@ stages: - echo "Applying level scaling in scripts/testv using scale=$LEVEL_SCALING" - tests/scale_pcm.py ./scripts/testv/ $LEVEL_SCALING +.merge-request-comparison-check: &merge-request-comparison-check + - echo "--------------- Running merge-request-comparison-check anchor ---------------" + - if [ $zero_errors != 1 ]; then echo "Run errors encountered!"; exit $EXIT_CODE_FAIL; fi + - if [ $exit_code -eq 1 ] && [ $non_be_flag == 0 ]; then echo "Non-bitexact cases without non-BE tag encountered!"; exit $EXIT_CODE_FAIL; fi + - if [ $exit_code -eq 1 ] && [ $non_be_flag != 0 ]; then echo "Non-bitexact cases with non-BE tag encountered"; exit $EXIT_CODE_NON_BE; fi + - exit 0 + .update-ltv-repo: &update-ltv-repo - cd $LTV_DIR - git pull - cd - - + +.get-commits-behind-count: &get-commits-behind-count + - echo $CI_COMMIT_SHA + - echo $CI_MERGE_REQUEST_TARGET_BRANCH_NAME + - commits_behind_count=$(git rev-list --count $CI_COMMIT_SHA..origin/$CI_MERGE_REQUEST_TARGET_BRANCH_NAME) + +.check-commits-behind-count-in-compare-jobs: &check-commits-behind-count-in-compare-jobs + - | + if [ $commits_behind_count -ne 0 ]; then + echo "Your branch is not up-to-date with main -> Compare tests will not run as they can contain false negatives this way." + echo "Main might have changed during your pipeline run. Run 'git pull origin $CI_MERGE_REQUEST_TARGET_BRANCH_NAME' to update." + exit 1 + fi + .copy-ltv-files-to-testv-dir: ©-ltv-files-to-testv-dir - cp "$LTV_DIR"/*.wav scripts/testv/ - cp "$LTV_DIR"/*.met scripts/testv/ @@ -193,15 +316,57 @@ stages: .activate-Werror-linux: &activate-Werror-linux - sed -i.bak "s/^# \(CFLAGS += -Werror\)/\1/" Makefile + - sed -i.bak "s/# \(set(CMAKE_C_FLAGS \"\${CMAKE_C_FLAGS} -Werror\")\)/\1/" CMakeLists.txt + +.activate-WX-windows: &activate-WX-windows + - (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 } + +# --------------------------------------------------------------- +# Job templates +# --------------------------------------------------------------- + +# When designing templates, try not to use too much inheritance and +# if multiple templates and extended on, remember that on conflict, +# latest overwrites the parameter. + +# templates for rules +.rules-basis: + rules: + - if: $MIRROR_ACCESS_TOKEN # Don't run in the mirror update pipeline (only then MIRROR_ACCESS_TOKEN is defined) + when: never + - if: $CI_PIPELINE_SOURCE == 'schedule' # Don't run in any scheduled pipelines by default (use schedule templates below to enable again for certain conditions) + when: never + - if: $CI_PIPELINE_SOURCE == 'trigger' # Don't run triggered pipeline by default + when: never + - if: $MANUAL_PIPELINE_TYPE == 'test-be-release' # Skip all the normal jobs when testing manually against release codec + 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 + - if: $MANUAL_PIPELINE_TYPE == 'check-clipping' + when: never + - if: $MANUAL_PIPELINE_TYPE == 'test-branch-vs-input-passthrough' + when: never + - when: on_success + +.rules-merge-request: + extends: .rules-basis + rules: + - if: $CI_PIPELINE_SOURCE == 'merge_request_event' + - if: $CI_PIPELINE_SOURCE == 'push' + when: never .rules-pytest-to-ref-short: rules: + - if: $PYTEST_MLD_SHORT # Set by scheduled pipeline - if: $CI_PIPELINE_SOURCE == 'web' && $MANUAL_PIPELINE_TYPE == "pytest-compare" - if: $CI_PIPELINE_SOURCE == 'push' && $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH - if: $CI_PIPELINE_SOURCE == 'push' when: never - - if: $CI_PIPELINE_SOURCE == 'schedule' - when: never .rules-pytest-to-input-short: rules: @@ -211,20 +376,26 @@ stages: - if: $CI_PIPELINE_SOURCE == 'schedule' when: never -# TODO: only temporary as long the MR encoder tests should not compare to main -.rules-pytest-to-ref-enc-short-temp: +.rules-pytest-to-main-short: rules: - - if: $CI_PIPELINE_SOURCE == 'web' && $MANUAL_PIPELINE_TYPE == "pytest-compare" - - if: $CI_PIPELINE_SOURCE == 'push' && $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH - if: $CI_PIPELINE_SOURCE == 'merge_request_event' && $CI_MERGE_REQUEST_TARGET_BRANCH_NAME == "main" # only have MR pipelines for MRs to main - if: $CI_PIPELINE_SOURCE == 'push' when: never - - if: $CI_PIPELINE_SOURCE == 'schedule' + +.rules-mr-to-main-or-main-pc: + rules: + - if: $CI_MERGE_REQUEST_TITLE =~ /^(\[Draft\]|\(Draft\)|Draft:)/ + when: never + - if: $CI_PIPELINE_SOURCE == 'merge_request_event' && ($CI_MERGE_REQUEST_TARGET_BRANCH_NAME == "main" || $CI_MERGE_REQUEST_TARGET_BRANCH_NAME == "main-pc") + - if: $CI_PIPELINE_SOURCE == 'push' when: never -.rules-pytest-to-main-short: +.rules-mr-to-main-or-main-pc-or-manual: rules: - - if: $CI_PIPELINE_SOURCE == 'merge_request_event' && $CI_MERGE_REQUEST_TARGET_BRANCH_NAME == "main" # only have MR pipelines for MRs to main + - if: $CI_PIPELINE_SOURCE == 'web' && $MANUAL_PIPELINE_TYPE == "pytest-compare" + - if: $CI_MERGE_REQUEST_TITLE =~ /^(\[Draft\]|\(Draft\)|Draft:)/ + when: never + - if: $CI_PIPELINE_SOURCE == 'merge_request_event' && ($CI_MERGE_REQUEST_TARGET_BRANCH_NAME == "main" || $CI_MERGE_REQUEST_TARGET_BRANCH_NAME == "main-pc") - if: $CI_PIPELINE_SOURCE == 'push' when: never @@ -259,17 +430,78 @@ stages: # Job templates # --------------------------------------------------------------- +# When designing templates, try not to use too much inheritance and +# if multiple templates and extended on, remember that on conflict, +# latest overwrites the parameter. + +# templates for rules +.rules-basis: + rules: + - if: $MIRROR_ACCESS_TOKEN # Don't run in the mirror update pipeline (only then MIRROR_ACCESS_TOKEN is defined) + when: never + - if: $CI_PIPELINE_SOURCE == 'schedule' # Don't run in any scheduled pipelines by default (use schedule templates below to enable again for certain conditions) + when: never + - if: $CI_PIPELINE_SOURCE == 'trigger' # Don't run triggered pipeline by default + when: never + - if: $MANUAL_PIPELINE_TYPE == 'test-be-release' # Skip all the normal jobs when testing manually against release codec + 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 + - if: $MANUAL_PIPELINE_TYPE == 'check-clipping' + - if: $MANUAL_PIPELINE_TYPE == 'test-branch-vs-input-passthrough' + when: never + - when: on_success + +.rules-merge-request: + extends: .rules-basis + rules: + - if: $CI_PIPELINE_SOURCE == 'merge_request_event' + - if: $CI_PIPELINE_SOURCE == 'push' + when: never + +.rules-merge-request-no-draft: + extends: .rules-basis + rules: + - if: $CI_MERGE_REQUEST_TITLE =~ /^(\[Draft\]|\(Draft\)|Draft:)/ + when: never + - if: $CI_PIPELINE_SOURCE == 'merge_request_event' + - if: $CI_PIPELINE_SOURCE == 'push' + when: never + +.rules-merge-request-to-main-pc: + extends: .rules-basis + rules: + - if: $CI_MERGE_REQUEST_TITLE =~ /^(\[Draft\]|\(Draft\)|Draft:)/ + when: never + - if: $CI_PIPELINE_SOURCE == 'merge_request_event' && $CI_MERGE_REQUEST_TARGET_BRANCH_NAME == 'main-pc' + - if: $CI_PIPELINE_SOURCE == 'push' + when: never + # templates to define stages and platforms .test-job-linux: tags: - - ivas-basop-linux + - ivas-linux .build-job-linux: stage: build timeout: "2 minutes" - needs: [] tags: - - ivas-basop-linux + - ivas-linux + +.build-job-windows: + stage: build + timeout: "4 minutes" + tags: + - ivas-windows + +.print-results-banner: &print-results-banner + - set +x + - echo "" + - echo -e "==================================================================================================================\n================================================== TEST RESULTS ==================================================\n==================================================================================================================\n" # template for test jobs on linux that need the TESTV_DIR .test-job-linux-needs-testv-dir: @@ -306,11 +538,23 @@ stages: - *apply-testv-scaling - fi - - if [ "$ENCODER_TEST" = "true" ]; then BUILD_WITH_DEBUG_MODE_INFO="true"; fi - - *build-and-create-reference-outputs + - if [ "$COMPARE_DMX" = "true" ] || [ "$ENCODER_TEST" = "true" ]; then + - BUILD_WITH_DEBUG_MODE_INFO="true" + - fi + - *build-and-create-float-ref-outputs - comp_args="--mld --ssnr --odg" + + - summary_args="MLD DIFF SSNR ODG" + - REPORT_ARG="" - if [ "$ENCODER_TEST" = "true" ]; then comp_args="${comp_args} --enc_stats"; fi + - if [ "$DELTA_ODG" = "true" ]; then comp_args="${comp_args} --odg_bin"; summary_args="${summary_args} DELTA_ODG"; REPORT_ARG="--delta_odg"; fi + + # DMX comparison only in manual job with no other metrics + - if [ "$COMPARE_DMX" = "true" ]; then + - comp_args="--compare_enc_dmx" + - fi + - echo "$comp_args" ### run pytest @@ -318,10 +562,10 @@ stages: - python3 -m pytest --tb=no $TEST_SUITE -v --create_cut --html=report.html --self-contained-html --junit-xml=report-junit.xml $comp_args -n auto --testcase_timeout $testcase_timeout --ref_encoder_path $REF_ENCODER_PATH --ref_decoder_path $REF_DECODER_PATH --dut_encoder_path $DUT_ENCODER_PATH --dut_decoder_path $DUT_DECODER_PATH || exit_code=$? - zero_errors=$(cat report-junit.xml | grep -c 'errors="0"') || true - - python3 scripts/parse_xml_report.py report-junit.xml $CSV_ARTIFACT_NAME + - python3 scripts/parse_xml_report.py report-junit.xml $CSV_ARTIFACT_NAME $REPORT_ARG - mkdir $IMAGES_ARTIFACT_NAME - - for MEASURE in MLD DIFF SSNR ODG;do python3 scripts/create_histogram_summary.py $CSV_ARTIFACT_NAME $IMAGES_ARTIFACT_NAME/summary_"$MEASURE".csv $IMAGES_ARTIFACT_NAME/summary_"$MEASURE".png --measure $MEASURE; done - - python3 ci/basop-pages/create_summary_page.py $SUMMARY_HTML_ARTIFACT_NAME $CI_JOB_ID $CI_JOB_NAME + - for MEASURE in $summary_args;do python3 scripts/create_histogram_summary.py $CSV_ARTIFACT_NAME $IMAGES_ARTIFACT_NAME/summary_"$MEASURE".csv $IMAGES_ARTIFACT_NAME/summary_"$MEASURE".png --measure $MEASURE; done + - python3 ci/basop-pages/create_summary_page.py $SUMMARY_HTML_ARTIFACT_NAME $CI_JOB_ID $CI_JOB_NAME --measures $summary_args - if [ $USE_LTV -eq 1 ] && [ "$CI_COMMIT_BRANCH" == "$CI_DEFAULT_BRANCH" ]; then - id_previous=$(python3 ci/get_id_of_last_job_occurence.py $CI_DEFAULT_BRANCH $CI_JOB_NAME $CI_PROJECT_ID) @@ -369,10 +613,129 @@ stages: junit: - report-junit.xml -.ivas-pytest-on-merge-request-anchor: &ivas-pytest-on-merge-request-anchor - stage: test +.check-up-to-date-in-comparison-jobs: &check-up-to-date-in-comparison-jobs + - *get-commits-behind-count + - | + if [ $commits_behind_count -ne 0 ]; then + set +x + echo -e "Your branch is $commits_behind_count commits behind the target branch, possibly main changed during your pipeline run. Checking bitexactness or testing for regressions now can result in meaningless results. Run\n\t git pull origin $CI_MERGE_REQUEST_TARGET_BRANCH_NAME\nto update." + exit 1 + fi + +.check-be-to-target-anchor: &check-be-to-target-anchor + stage: check-be needs: ["build-codec-linux-make"] timeout: "300 minutes" + variables: + XML_REPORT: "report--$CI_JOB_NAME--sha-$CI_COMMIT_SHORT_SHA.xml" + HTML_REPORT: "report--$CI_JOB_NAME--sha-$CI_COMMIT_SHORT_SHA.html" + PYTEST_LOG_TARGET_BRANCH: "pytest-log-$CI_MERGE_REQUEST_TARGET_BRANCH_NAME.txt" + script: + - *print-common-info + + - set -euxo pipefail + + - *update-scripts-repo + - python3 tests/create_short_testvectors.py + + - if [ $USE_LTV -eq 1 ]; then + - *update-ltv-repo + - *copy-ltv-files-to-testv-dir + - testcase_timeout=$TESTCASE_TIMEOUT_LTV + - else + - testcase_timeout=$TESTCASE_TIMEOUT_STV + - fi + + - python3 ci/remove_unsupported_testcases.py $PRM_FILES + - python3 scripts/prepare_combined_format_inputs.py + + - if [ $LEVEL_SCALING != "1.0" ];then + - *apply-testv-scaling + - fi + + - *build-float-ref-binaries + - *build-merge-target-binaries + - make clean + - make -j + - *check-up-to-date-in-comparison-jobs + + - exit_code_target=0 + - python3 -m pytest $TEST_SUITE -v --update_ref 1 --create_ref -n auto --ref_encoder_path $MERGE_TARGET_ENCODER_PATH --ref_decoder_path $MERGE_TARGET_DECODER_PATH --dut_encoder_path $DUT_ENCODER_PATH --dut_decoder_path $DUT_DECODER_PATH > $PYTEST_LOG_TARGET_BRANCH || exit_code_target=$? + + - exit_code=0 + - rm -rf .pytest_cache || true + - python3 -m pytest --tb=no -q $TEST_SUITE -v --keep_files --create_cut --html=$HTML_REPORT --self-contained-html --junit-xml=$XML_REPORT --mld --ssnr --odg --ref_encoder_path $MERGE_TARGET_ENCODER_PATH --ref_decoder_path $MERGE_TARGET_DECODER_PATH --dut_encoder_path $DUT_ENCODER_PATH --dut_decoder_path $DUT_DECODER_PATH -n auto --testcase_timeout $testcase_timeout > pytest_log.txt || exit_code=$? + + - if [ $exit_code -ne 0 ]; then + - exit_code=$EXIT_CODE_NON_BE + - zip -r $PYTEST_CACHE_ARTIFACT .pytest_cache + + - grep "^FAILED" pytest_log.txt | sed "s/^FAILED /'/" | sed "s/] - .*/]'/" | tr "\n" " " > $FAILED_TESTCASES_LIST || true + - grep "^FAILED" pytest_log.txt | sed "s/^FAILED //" | sed "s/] - .*/]/" > failed_testcases_for_printing.txt || true + - num_failures=$(wc -l < failed_testcases_for_printing.txt) + + - grep "^ERROR" pytest_log.txt | sed "s/^ERROR /'/" | sed "s/] - .*/]'/" | tr "\n" " " > $ERRORS_TESTCASES_LIST || true + - grep "^ERROR" pytest_log.txt | sed "s/^ERROR //" | sed "s/] - .*/]/" > errors_testcases_for_printing.txt || true + - num_errors=$(wc -l < errors_testcases_for_printing.txt) + + - *print-results-banner + - echo "Found these $num_failures non-bitexact testcases:" + - cat failed_testcases_for_printing.txt + + - echo "Reproduce locally with:" + - echo -e "1. Create references with target branch $CI_MERGE_REQUEST_TARGET_BRANCH_NAME:\n\t- git checkout $(cat $FLOAT_REF_COMMIT_FILE)\n\t- make clean\n\t- make -j\n\t- mv IVAS_cod IVAS_cod_ref\n\t- mv IVAS_dec IVAS_dec_ref\n\t- python3 -m pytest $(cat $FAILED_TESTCASES_LIST) --update_ref 1 --ref_encoder_path $REF_ENCODER_PATH --ref_decoder_path $REF_DECODER_PATH" + - echo -e "2. Run test with source branch $CI_MERGE_REQUEST_SOURCE_BRANCH_NAME:\n\t- git checkout $(cat $CUT_COMMIT_FILE)\n\t- make clean\n\t- make -j\n\t- python3 -m pytest $(cat $FAILED_TESTCASES_LIST) --dut_encoder_path $DUT_ENCODER_PATH --dut_decoder_path $DUT_DECODER_PATH" + - echo "The individual command lines can be found in the html report in the job artifacts." + - if [ $num_errors -ne 0 ]; then + - exit_code=1 + - echo "There were errors present in the following testcases:" + - cat errors_testcases_for_printing.txt + - fi + + - exit $exit_code + - else + # create empty files to not have errors at artifact stage + - touch $FAILED_TESTCASES_LIST + - touch $ERRORS_TESTCASES_LIST + - touch $PYTEST_CACHE_ARTIFACT + - *print-results-banner + - echo "All testcases are bitexact." + - fi + - exit $exit_code + + allow_failure: + exit_codes: + - 123 + artifacts: + name: "$CI_JOB_NAME--sha-$CI_COMMIT_SHORT_SHA--results" + expire_in: 1 week + when: always + paths: + - $XML_REPORT + - $HTML_REPORT + - $FAILED_TESTCASES_LIST + - $ERRORS_TESTCASES_LIST + - pytest_log.txt + - $PYTEST_CACHE_ARTIFACT + - $FLOAT_REF_COMMIT_FILE + - $CUT_COMMIT_FILE + - $MERGE_TARGET_COMMIT_FILE + - $PYTEST_LOG_TARGET_BRANCH + expose_as: "pytest compare results" + reports: + junit: + - $XML_REPORT + - $XML_REPORT + +.overwrite-pytest-cache-with-artifact: &overwrite-pytest-cache-with-artifact + - if [ -f $PYTEST_CACHE_ARTIFACT ]; then + - rm -rf .pytest_cache || true + - unzip $PYTEST_CACHE_ARTIFACT + - fi + +.check-regressions-pytest-anchor: &check-regressions-pytest-anchor + stage: test + timeout: "300 minutes" variables: XML_REPORT_BRANCH: "report-junit-branch-$CI_JOB_NAME--sha-$CI_COMMIT_SHORT_SHA.xml" XML_REPORT_MAIN: "report-junit-main-$CI_JOB_NAME--sha-$CI_COMMIT_SHORT_SHA.xml" @@ -384,7 +747,21 @@ stages: SUMMARY_HTML_ARTIFACT_NAME: "summary_$CI_JOB_NAME.html" script: - *print-common-info + + - set -euxo pipefail + + - if [ -s $FAILED_TESTCASES_LIST ]; then + - *overwrite-pytest-cache-with-artifact + - export PYTEST_ADDOPTS=--last-failed + - else + # turn off echoing back of commands for result printout + - *print-results-banner + - echo -e "All tested cases were bit-exact between $CI_MERGE_REQUEST_TARGET_BRANCH_NAME and $CI_MERGE_REQUEST_SOURCE_BRANCH_NAME.\nNo need to check for regressions. All is fine." + - exit 0 + - fi + - *update-scripts-repo + - if [ $USE_LTV -eq 1 ]; then - *update-ltv-repo - *copy-ltv-files-to-testv-dir @@ -404,9 +781,11 @@ stages: ### run branch first # this per default builds the branch and the reference and creates the reference outputs - - *build-and-create-reference-outputs - - exit_code=0 - - python3 -m pytest --tb=no $TEST_SUITE -v --keep_files --create_cut --html=$HTML_REPORT_BRANCH --self-contained-html --junit-xml=$XML_REPORT_BRANCH --mld --ssnr --odg --ref_encoder_path $REF_ENCODER_PATH --ref_decoder_path $REF_DECODER_PATH --dut_encoder_path $DUT_ENCODER_PATH --dut_decoder_path $DUT_DECODER_PATH -n auto --testcase_timeout $testcase_timeout || exit_code=$? + - *build-and-create-float-ref-outputs + - *check-up-to-date-in-comparison-jobs + # need to restore cache again + - *overwrite-pytest-cache-with-artifact + - python3 -m pytest --tb=no -q $TEST_SUITE -v --keep_files --create_cut --html=$HTML_REPORT_BRANCH --self-contained-html --junit-xml=$XML_REPORT_BRANCH --mld --ssnr --odg --ref_encoder_path $REF_ENCODER_PATH --ref_decoder_path $REF_DECODER_PATH --dut_encoder_path $DUT_ENCODER_PATH --dut_decoder_path $DUT_DECODER_PATH -n auto --testcase_timeout $testcase_timeout || true - zero_errors_branch=$(cat $XML_REPORT_BRANCH | grep -c 'errors="0"') || true - python3 scripts/parse_xml_report.py $XML_REPORT_BRANCH $CSV_BRANCH @@ -420,44 +799,40 @@ stages: ### run main now - git checkout $CI_MERGE_REQUEST_TARGET_BRANCH_NAME - - git pull + - git pull origin $CI_MERGE_REQUEST_TARGET_BRANCH_NAME - make clean - make -j - - python3 -m pytest --tb=no $TEST_SUITE -v --keep_files --create_cut --html=$HTML_REPORT_MAIN --self-contained-html --junit-xml=$XML_REPORT_MAIN --mld --ssnr --odg --ref_encoder_path $REF_ENCODER_PATH --ref_decoder_path $REF_DECODER_PATH --dut_encoder_path $DUT_ENCODER_PATH --dut_decoder_path $DUT_DECODER_PATH -n auto --testcase_timeout $testcase_timeout || true + # need to restore cache again + - *overwrite-pytest-cache-with-artifact + - python3 -m pytest --tb=no -q $TEST_SUITE -v --keep_files --create_cut --html=$HTML_REPORT_MAIN --self-contained-html --junit-xml=$XML_REPORT_MAIN --mld --ssnr --odg --ref_encoder_path $REF_ENCODER_PATH --ref_decoder_path $REF_DECODER_PATH --dut_encoder_path $DUT_ENCODER_PATH --dut_decoder_path $DUT_DECODER_PATH -n auto --testcase_timeout $testcase_timeout || true - python3 scripts/parse_xml_report.py $XML_REPORT_MAIN $CSV_MAIN - # If outputs of main and branch are equal, have equal reports and no run errors were encountered, the job will pass. - - diff_sba=0 - - diff_param=0 - - diff_report=0 - - python3 scripts/batch_comp_audio.py --tool pyaudio3dtools -sd tests/dut/sba_bs/raw tests/dut_branch/sba_bs/raw || diff_sba=$? - - python3 scripts/batch_comp_audio.py --tool pyaudio3dtools -sd tests/dut/param_file/dec tests/dut_branch/param_file/dec || diff_param=$? - - diff $CSV_BRANCH $CSV_MAIN || diff_report=$? - - if [ $diff_param -eq 0 ] && [ $diff_sba -eq 0 ] && [ $diff_report -eq 0 ] && [ $zero_errors_branch -eq 1 ]; then - - echo "Output BE to main, identical report and no run errors encountered." - # Add dummy files to avoid warning on missing artifacts - - touch changes_crashes.csv - - touch changes_MLD.csv - - touch changes_MAXIMUM_ABS_DIFF.csv - - touch changes_MIN_SSNR.csv - - touch changes_MIN_ODG.csv - - exit 0; - - fi - ### compare the two csv files for regressions - regressions_found=0 - - python3 scripts/basop_check_for_changes_in_testcases.py $CSV_BRANCH $CSV_MAIN || regressions_found=$? + - python3 scripts/basop_check_for_changes_in_testcases.py --show_improvements --xml_report $XML_REPORT_BRANCH $CSV_BRANCH $CSV_MAIN > regression_log.txt || regressions_found=$? - - if [ $exit_code -eq 1 ]; then echo "Differences encountered"; exit_code=$EXIT_CODE_NON_BE; fi - - if [ $zero_errors_branch != 1 ]; then echo "Run errors encountered!"; exit_code=$EXIT_CODE_NON_BE; fi - - if [ $regressions_found != 0 ]; then + - exit_code=0 + - *print-results-banner + - if [ $zero_errors_branch != 1 ]; then + - echo "Run errors encountered!" + - exit_code=$EXIT_CODE_FAIL + - echo "Reproduce locally with:" + - echo -e "1. Create references with target branch $CI_MERGE_REQUEST_TARGET_BRANCH_NAME:\n\t- git checkout $(cat $FLOAT_REF_COMMIT_FILE)\n\t- make clean\n\t- make -j\n\t- mv IVAS_cod IVAS_cod_ref\n\t- mv IVAS_dec IVAS_dec_ref\n\t- python3 -m pytest $(cat $ERRORS_TESTCASES_LIST) --update_ref 1 --ref_encoder_path $REF_ENCODER_PATH --ref_decoder_path $REF_DECODER_PATH" + - echo -e "2. Run test with source branch $CI_MERGE_REQUEST_SOURCE_BRANCH_NAME:\n\t- git checkout $(cat $CUT_COMMIT_FILE)\n\t- make clean\n\t- make -j\n\t- python3 -m pytest $(cat $ERRORS_TESTCASES_LIST) --dut_encoder_path $DUT_ENCODER_PATH --dut_decoder_path $DUT_DECODER_PATH" + - echo "The individual command lines can be found in the regressions_crashes.csv files in the job artifacts." + - elif [ $regressions_found != 0 ] && [ "$SKIP_REGRESSION_CHECK" != "true" ]; then + - cat regression_log.txt - if [ $allow_regressions_flag == 0 ]; then - - echo "Detected regression wrt to main, [allow regression] not set!" + - echo "Detected regression wrt to $CI_MERGE_REQUEST_TARGET_BRANCH_NAME, [allow regression] not set!" - exit_code=$EXIT_CODE_FAIL; - else - - echo "Detected regression wrt to main, [allow regression] set." + - echo "Detected regression wrt to $CI_MERGE_REQUEST_TARGET_BRANCH_NAME, [allow regression] set." - exit_code=$EXIT_CODE_NON_BE; - fi + - echo "Reproduce locally with:" + - echo -e "1. Create references with target branch $CI_MERGE_REQUEST_TARGET_BRANCH_NAME:\n\t- git checkout $(cat $FLOAT_REF_COMMIT_FILE)\n\t- make clean\n\t- make -j\n\t- mv IVAS_cod IVAS_cod_ref\n\t- mv IVAS_dec IVAS_dec_ref\n\t- python3 -m pytest $(cat $FAILED_TESTCASES_LIST) --update_ref 1 --ref_encoder_path $REF_ENCODER_PATH --ref_decoder_path $REF_DECODER_PATH" + - echo -e "2. Run test with source branch $CI_MERGE_REQUEST_SOURCE_BRANCH_NAME:\n\t- git checkout $(cat $CUT_COMMIT_FILE)\n\t- make clean\n\t- make -j\n\t- python3 -m pytest $(cat $FAILED_TESTCASES_LIST) --dut_encoder_path $DUT_ENCODER_PATH --dut_decoder_path $DUT_DECODER_PATH" + - echo "The individual command lines can be found in the regressions_*.csv files in the job artifacts." - fi - exit $exit_code @@ -479,11 +854,19 @@ stages: - $CSV_MAIN - $SUMMARY_HTML_ARTIFACT_NAME - $IMAGES_ARTIFACT_NAME - - changes_crashes.csv - - changes_MLD.csv - - changes_MAXIMUM_ABS_DIFF.csv - - changes_MIN_SSNR.csv - - changes_MIN_ODG.csv + - $FLOAT_REF_COMMIT_FILE + - $CUT_COMMIT_FILE + - $MERGE_TARGET_COMMIT_FILE + - regressions_crashes.csv + - regressions_MLD.csv + - regressions_MAXIMUM_ABS_DIFF.csv + - regressions_MIN_SSNR.csv + - regressions_MIN_ODG.csv + - improvements_crashes.csv + - improvements_MLD.csv + - improvements_MAXIMUM_ABS_DIFF.csv + - improvements_MIN_SSNR.csv + - improvements_MIN_ODG.csv expose_as: "pytest compare results" reports: junit: @@ -505,13 +888,25 @@ stages: script: - *print-common-info - *update-scripts-repo + - *copy-ltv-files-to-testv-dir - python3 ci/remove_unsupported_testcases.py $PRM_FILES - - *build-reference-and-dut-binaries + + - *build-float-ref-binaries + - set -euxo pipefail + - make_args="CLANG=$CLANG_NUM" + - if [[ $CLANG_NUM == 3 ]]; then + - export UBSAN_OPTIONS="suppressions=scripts/ubsan_basop.supp,report_error_type=1" + - python3 scripts/basop_create_ignorelist_for_ubsan.py + - make_args="$make_args IGNORELIST=1" + - fi - make clean - - make -j CLANG=$CLANG_NUM - - if [[ $CLANG_NUM == 3 ]]; then export UBSAN_OPTIONS="suppressions=scripts/ubsan.supp,report_error_type=1"; fi - - testcase_timeout=$TESTCASE_TIMEOUT_STV_SANITIZERS - - python3 -m pytest $TEST_SUITE -v --tb=no --update_ref 1 --html=report.html --self-contained-html --junit-xml=report-junit.xml --testcase_timeout $testcase_timeout --ref_encoder_path $DUT_ENCODER_PATH --ref_decoder_path $DUT_DECODER_PATH + - make -j $make_args + - testcase_timeout_arg="--testcase_timeout $TESTCASE_TIMEOUT_LTV_SANITIZERS" + # disable per-testcase timeout for msan to evaluate what is going on that it takes so long + - if [[ $CLANG_NUM = 1 ]]; then + - testcase_timeout_arg="" + - fi + - python3 -m pytest $TEST_SUITE -v --tb=no --update_ref 1 --html=report.html --self-contained-html --junit-xml=report-junit.xml $testcase_timeout_arg --ref_encoder_path $DUT_ENCODER_PATH --ref_decoder_path $DUT_DECODER_PATH artifacts: name: "$CI_JOB_NAME--sha-$CI_COMMIT_SHORT_SHA--results" when: always @@ -545,7 +940,7 @@ stages: - if [ $LEVEL_SCALING != "1.0" ];then - *apply-testv-scaling - fi - - *build-reference-and-dut-binaries + - *build-float-ref-and-dut-binaries ### run pytest - exit_code=0 @@ -606,18 +1001,109 @@ uninterruptible: rules: - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH when: always + tags: + - ivas-linux + +# --------------------------------------------------------------- +# Validation jobs +# --------------------------------------------------------------- + +branch-is-up-to-date-with-target-pre: + extends: + - .rules-merge-request + stage: prevalidate + needs: [] tags: - ivas-basop-linux + script: + - *get-commits-behind-count + - echo $commits_behind_count + - | + if [ $commits_behind_count -ne 0 ]; then + echo "Your branch is behind the target branch, run 'git pull origin $CI_MERGE_REQUEST_TARGET_BRANCH_NAME' to update." + exit 1 + fi + +branch-is-up-to-date-with-target-post: + extends: + - .rules-merge-request + stage: postvalidate + tags: + - ivas-basop-linux + script: + - *get-commits-behind-count + - echo $commits_behind_count + - | + if [ $commits_behind_count -ne 0 ]; then + echo "Your branch is behind the target branch, possibly main changed during your pipeline run, run 'git pull origin $CI_MERGE_REQUEST_TARGET_BRANCH_NAME' to update." + exit 1 + fi + +# fail pipeline in the final stage for pipelines on Draft MRs +# this also only runs on Draft MRs, so should always fail +fail-pipeline-if-in-draft: + rules: + - if: $CI_PIPELINE_SOURCE == 'merge_request_event' && $CI_MERGE_REQUEST_TITLE =~ /^(\[Draft\]|\(Draft\)|Draft:)/ + - if: $CI_PIPELINE_SOURCE == 'push' + when: never + stage: postvalidate + tags: + - ivas-linux + script: + - echo "Your MR is still in Draft state, set it to ready to be mergable, then retrigger the pipeline." + - exit 1 + +# this branch runs on merges to main-pc only and will fail if the branch itself does not conform to the naming conventions +check-naming-of-branch-for-main-pc-merges: + extends: + - .rules-merge-request-to-main-pc + stage: prevalidate + tags: + - ivas-basop-linux + script: + - *update-scripts-repo + - if [[ ! "$CI_MERGE_REQUEST_TITLE" =~ \[skip[[:space:]_-]name[[:space:]_-]check\] ]] && [[ ! "$CI_MERGE_REQUEST_TITLE" =~ \[CI\] ]]; then + - ci/get_float_ref_branch_name.sh $CI_MERGE_REQUEST_SOURCE_BRANCH_NAME + - fi # --------------------------------------------------------------- # verification jobs # --------------------------------------------------------------- +branch-is-up-to-date-with-target-pre: + extends: + - .rules-merge-request + stage: prevalidate + needs: [] + tags: + - ivas-basop-linux + script: + - *get-commits-behind-count + - | + if [ $commits_behind_count -ne 0 ]; then + echo -e "Your branch is $commits_behind_count commits behind the target branch, run\n\tgit pull origin $CI_MERGE_REQUEST_TARGET_BRANCH_NAME\nto update." + exit 1 + fi + +branch-is-up-to-date-with-target-post: + extends: + - .rules-merge-request + stage: postvalidate + tags: + - ivas-basop-linux + script: + - *get-commits-behind-count + - | + if [ $commits_behind_count -ne 0 ]; then + echo -e "Your branch is $commits_behind_count commits behind the target branch, possibly main changed during your pipeline run, run\n\tgit pull origin $CI_MERGE_REQUEST_TARGET_BRANCH_NAME\nto update." + exit 1 + fi + clang-format-check: extends: - .test-job-linux rules: - - if: $CI_PIPELINE_SOURCE == 'merge_request_event' && $CI_MERGE_REQUEST_TARGET_BRANCH_NAME == "main" # only have MR pipelines for MRs to main + - if: $CI_PIPELINE_SOURCE == 'merge_request_event' - if: $CI_PIPELINE_SOURCE == 'push' when: never - if: $CI_PIPELINE_SOURCE == 'schedule' @@ -625,6 +1111,8 @@ clang-format-check: variables: ARTIFACT_BASE_NAME: "mr-$CI_MERGE_REQUEST_IID--sha-$CI_COMMIT_SHORT_SHA--formatting-fix" stage: prevalidate + tags: + - ivas-basop-linux needs: [] timeout: "5 minutes" script: @@ -665,6 +1153,32 @@ clang-format-check: name: "$ARTIFACT_BASE_NAME" expose_as: "formatting patch" +# from float +# needs fix to be merged from floating point repo before it can be activated +.check-bitexactness-hrtf-rom-and-file: + extends: + - .test-job-linux + - .rules-merge-request-to-main-pc + stage: test + needs: ["build-codec-linux-make"] + timeout: "5 minutes" + script: + - *print-common-info + - *update-scripts-repo + - make clean + - make -j + - python3 tests/create_short_testvectors.py --cut_len 1.0 + # TODO: run full test again once the custom binary files are supported + - python3 -m pytest -k "not diff_from_rom and not test_binary_file" 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" + # --------------------------------------------------------------- # Build jobs # --------------------------------------------------------------- @@ -680,34 +1194,90 @@ build-codec-linux-make: when: never extends: - .build-job-linux + tags: + - ivas-basop-linux script: - *print-common-info - *activate-Werror-linux - make -j +build-codec-linux-cmake: + rules: + - if: $CI_PIPELINE_SOURCE == 'web' + - if: $CI_PIPELINE_SOURCE == 'push' && $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH + - if: $CI_PIPELINE_SOURCE == 'merge_request_event' # trigger build job for all MRs + - if: $CI_PIPELINE_SOURCE == 'schedule' + - if: $CI_PIPELINE_SOURCE == 'push' + when: never + extends: + - .build-job-linux + tags: + - ivas-basop-linux + script: + - *print-common-info + - *update-scripts-repo + - cmake -B cmake-build -G "Unix Makefiles" + - cmake --build cmake-build -- -j + # ensure that codec builds on linux with instrumentation active build-codec-linux-instrumented-make: rules: - if: $CI_PIPELINE_SOURCE == 'web' - if: $CI_PIPELINE_SOURCE == 'push' && $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH - - if: $CI_PIPELINE_SOURCE == 'merge_request_event' && $CI_MERGE_REQUEST_TARGET_BRANCH_NAME == "main" # only have MR pipelines for MRs to main + - if: $CI_PIPELINE_SOURCE == 'merge_request_event' - if: $CI_PIPELINE_SOURCE == 'schedule' - if: $CI_PIPELINE_SOURCE == 'push' when: never extends: - .build-job-linux timeout: "7 minutes" + tags: + - ivas-basop-linux script: - *print-common-info - *update-scripts-repo - - bash scripts/prepare_instrumentation.sh -m MEM_ONLY -p BASOP + - bash scripts/prepare_instrumentation.sh -m MEM_ONLY - make -j -C $INSTR_DIR + +# make sure that the codec builds with msan, asan and usan +build-codec-sanitizers-linux: + extends: + - .build-job-linux + - .rules-basis + tags: + - ivas-basop-linux + script: + - *update-scripts-repo + - *print-common-info + # TODO: re-enable once all the warnings have been fixed + #- *activate-Werror-linux + - bash ci/build_codec_sanitizers_linux.sh + +build-codec-windows-msbuild: + rules: + - if: $CI_PIPELINE_SOURCE == 'web' + - if: $CI_PIPELINE_SOURCE == 'push' && $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH + - if: $CI_PIPELINE_SOURCE == 'merge_request_event' # trigger build job for all MRs + - if: $CI_PIPELINE_SOURCE == 'schedule' + - if: $CI_PIPELINE_SOURCE == 'push' + when: never + extends: + - .build-job-windows + timeout: "7 minutes" + tags: + - ivas-windows + script: + - *print-common-info-windows + - *activate-WX-windows + - MSBuild.exe -maxcpucount .\Workspace_msvc\Workspace_msvc.sln /property:Configuration=Debug + + build-codec-linux-debugging-make: rules: - if: $CI_PIPELINE_SOURCE == 'web' - if: $CI_PIPELINE_SOURCE == 'push' && $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH - - if: $CI_PIPELINE_SOURCE == 'merge_request_event' && $CI_MERGE_REQUEST_TARGET_BRANCH_NAME == "main" # only have MR pipelines for MRs to main + - if: $CI_PIPELINE_SOURCE == 'merge_request_event' - if: $CI_PIPELINE_SOURCE == 'schedule' - if: $CI_PIPELINE_SOURCE == 'push' when: never @@ -718,84 +1288,320 @@ build-codec-linux-debugging-make: BUILD_WITH_DEBUG_MODE_INFO: "true" script: - *print-common-info - - *activate-debug-mode-info-if-set + - *activate-debug-mode-info-if-set + - make -j + +# --------------------------------------------------------------- +# Test jobs for merge requests +# --------------------------------------------------------------- + +split-rendering-smoke-test: + extends: + - .test-job-linux + - .rules-merge-request + needs: ["build-codec-linux-make"] + stage: test + script: + - *print-common-info + - *update-scripts-repo + + - make -j + - testcase_timeout=10 + - python3 -m pytest -q -n auto -rA --junit-xml=report-junit.xml tests/split_rendering/test_split_rendering.py --testcase_timeout=$testcase_timeout + artifacts: + name: "mr-$CI_MERGE_REQUEST_IID--sha-$CI_COMMIT_SHORT_SHA--job-$CI_JOB_NAME--results" + expire_in: 1 week + when: always + paths: + - report-junit.xml + expose_as: "split rendering smoke results" + reports: + junit: + - report-junit.xml + +lc3-wrapper-unit-test: + extends: + - .test-job-linux + - .rules-merge-request + needs: ["build-codec-linux-make"] + stage: test + script: + - *print-common-info + - *update-scripts-repo + + - cmake -B cmake-build -G "Unix Makefiles" -DCOPY_EXECUTABLES_FROM_BUILD_DIR=true + - cmake --build cmake-build -- -j + - scripts/split_rendering/lc3plus_basop/ivas_lc3plus_unit_test + +# compare split-rendering bitexactness between target and source branch +split-rendering-pytest-on-merge-request: + extends: + - .test-job-linux-needs-testv-dir + - .rules-merge-request + needs: ["build-codec-linux-make"] + # TODO: set reasonable timeout, will most likely take less + timeout: "30 minutes" + stage: compare + script: + - *print-common-info + - *update-scripts-repo + - *get-commits-behind-count + - *check-commits-behind-count-in-compare-jobs + + # some helper variables - "|| true" to prevent failures from grep not finding anything + # write to temporary file as workaround for failures observed with piping echo + - echo $CI_MERGE_REQUEST_TITLE > tmp.txt + - non_be_flag=$(grep -c --ignore-case "\[split*[ -]*non[ -]*be\]" tmp.txt) || true + # TODO: ref_using_target comes from float repo, but does not apply here - disable for now + # - ref_using_target=$(grep -c --ignore-case "\[ref[ -]*using[ -]*target\]" tmp.txt) || true + - ref_using_target=0 + + # store the current commit hash + - source_branch_commit_sha=$(git rev-parse HEAD) + + - *mr-fetch-target-branch + - *mr-get-target-commit + - git checkout $target_commit + - echo "Building reference codec at commit $target_commit" + + # build reference binaries + - make -j + - mv IVAS_cod IVAS_cod_ref + - mv IVAS_dec IVAS_dec_ref + - mv IVAS_rend IVAS_rend_ref + + ### If ref_using_target is not set, checkout the source branch to use scripts and input from there + - if [ $ref_using_target == 0 ]; then git restore lib_com/options.h; fi # Revert changes back before checking out another branch to avoid conflicts + - if [ $ref_using_target == 0 ]; then git checkout $source_branch_commit_sha; fi + - exit_code=0 + - testcase_timeout=60 + - python3 -m pytest -q --log-level ERROR -n auto -rA --html=report.html --self-contained-html --junit-xml=report-junit.xml tests/split_rendering/test_split_rendering.py --create_ref --testcase_timeout=$testcase_timeout || exit_code=$? + + # back to source branch + - git restore lib_com/options.h # Revert changes back before checking out another branch to avoid conflicts + - git checkout $source_branch_commit_sha + - make clean - make -j + ### Run test using scripts and input from main + - if [ $ref_using_target == 1 ]; then git restore lib_com/options.h; fi # Revert changes back before checking out another branch to avoid conflicts + - if [ $ref_using_target == 1 ]; then git checkout $source_branch_commit_sha; fi + + - comp_args="--mld --ssnr --odg" + - echo "$comp_args" + + # run test + - python3 -m pytest -q --log-level ERROR -n auto -rA --html=report.html --self-contained-html --junit-xml=report-junit.xml tests/split_rendering/test_split_rendering.py $comp_args --create_cut --testcase_timeout=$testcase_timeout || exit_code=$? + - zero_errors=$(cat report-junit.xml | grep -c 'errors="0"') || true + + - *merge-request-comparison-check + + allow_failure: + exit_codes: + - 123 + artifacts: + name: "mr-$CI_MERGE_REQUEST_IID--sha-$CI_COMMIT_SHORT_SHA--job-$CI_JOB_NAME--results" + expire_in: 2 week + when: always + paths: + - report-junit.xml + - report.html + expose_as: "pytest split rendering results" + reports: + junit: + - report-junit.xml + # --------------------------------------------------------------- # Short test jobs that run in merge request pipelines # --------------------------------------------------------------- -### jobs that test fx encoder -> flt decoder -# TODO: reenable once encoder tests shall compare to main -# ivas-pytest-compare_to_main-short-enc: -# extends: -# - .rules-pytest-to-main-short -# - .test-job-linux -# before_script: -# - USE_LTV=0 -# - DUT_DECODER_PATH=./IVAS_dec_ref -# - TEST_SUITE="$SHORT_TEST_SUITE_ENCODER" -# - LEVEL_SCALING=1.0 -# <<: *ivas-pytest-on-merge-request-anchor - -# ivas-pytest-compare_to_main-short-enc-lev-10: -# extends: -# - .rules-pytest-to-main-short -# - .test-job-linux -# before_script: -# - USE_LTV=0 -# - DUT_DECODER_PATH=./IVAS_dec_ref -# - TEST_SUITE="$SHORT_TEST_SUITE_ENCODER" -# - LEVEL_SCALING=0.3162 -# <<: *ivas-pytest-on-merge-request-anchor - -# ivas-pytest-compare_to_main-short-enc-lev+10: -# extends: -# - .rules-pytest-to-main-short -# - .test-job-linux -# before_script: -# - USE_LTV=0 -# - DUT_DECODER_PATH=./IVAS_dec_ref -# - TEST_SUITE="$SHORT_TEST_SUITE_ENCODER" -# - LEVEL_SCALING=3.162 -# <<: *ivas-pytest-on-merge-request-anchor +.set-reference-for-basop-port-branch: &set-reference-for-basop-port-branch + - if [ $CI_MERGE_REQUEST_TARGET_BRANCH_NAME = "main-pc" ] && [[ ! "$CI_MERGE_REQUEST_TITLE" =~ \[skip[[:space:]_-]name[[:space:]_-]check\] ]] && [[ ! "$CI_MERGE_REQUEST_TITLE" =~ \[CI\] ]]; then + - *update-scripts-repo + # a bit awkward: write to file + standard out first so that the error message is visivle in case of failure. Then fill the variable from the file + - ci/get_float_ref_branch_name.sh $CI_MERGE_REQUEST_SOURCE_BRANCH_NAME | tee tmp_ref_branch.txt + - REFERENCE_BRANCH=$(cat tmp_ref_branch.txt) + - fi -### jobs that test flt encoder -> fx decoder -ivas-pytest-compare_to_main-short-dec: +### jobs that check for bitexactness of fx encoder and decoder +check-be-to-target-short-enc-0db: + extends: + - .rules-mr-to-main-or-main-pc + - .test-job-linux + before_script: + - USE_LTV=0 + - DUT_DECODER_PATH=./IVAS_dec_ref + - MERGE_TARGET_DECODER_PATH=./IVAS_dec_ref + - TEST_SUITE="$SHORT_TEST_SUITE_ENCODER" + - LEVEL_SCALING=1.0 + - rm -rf tests/dut tests/ref + <<: *check-be-to-target-anchor + +check-be-to-target-short-enc-+10db: + extends: + - .rules-mr-to-main-or-main-pc + - .test-job-linux + before_script: + - USE_LTV=0 + - DUT_DECODER_PATH=./IVAS_dec_ref + - MERGE_TARGET_DECODER_PATH=./IVAS_dec_ref + - TEST_SUITE="$SHORT_TEST_SUITE_ENCODER" + - LEVEL_SCALING=3.162 + - rm -rf tests/dut tests/ref + <<: *check-be-to-target-anchor + +check-be-to-target-short-enc--10db: + extends: + - .rules-mr-to-main-or-main-pc + - .test-job-linux + before_script: + - USE_LTV=0 + - DUT_DECODER_PATH=./IVAS_dec_ref + - MERGE_TARGET_DECODER_PATH=./IVAS_dec_ref + - TEST_SUITE="$SHORT_TEST_SUITE_ENCODER" + - LEVEL_SCALING=0.3162 + - rm -rf tests/dut tests/ref + <<: *check-be-to-target-anchor + +check-be-to-target-short-dec-0db: extends: - - .rules-pytest-to-main-short + - .rules-mr-to-main-or-main-pc - .test-job-linux before_script: - USE_LTV=0 - DUT_ENCODER_PATH=./IVAS_cod_ref + - MERGE_TARGET_ENCODER_PATH=./IVAS_cod_ref - TEST_SUITE="$SHORT_TEST_SUITE" - LEVEL_SCALING=1.0 - rm -rf tests/dut tests/ref - <<: *ivas-pytest-on-merge-request-anchor + <<: *check-be-to-target-anchor + +check-be-to-target-short-dec-+10db: + extends: + - .rules-mr-to-main-or-main-pc + - .test-job-linux + before_script: + - USE_LTV=0 + - DUT_ENCODER_PATH=./IVAS_cod_ref + - MERGE_TARGET_ENCODER_PATH=./IVAS_cod_ref + - TEST_SUITE="$SHORT_TEST_SUITE" + - LEVEL_SCALING=3.162 + - rm -rf tests/dut tests/ref + <<: *check-be-to-target-anchor -ivas-pytest-compare_to_main-short-dec-lev-10: +check-be-to-target-short-dec--10db: extends: - - .rules-pytest-to-main-short + - .rules-mr-to-main-or-main-pc - .test-job-linux before_script: - USE_LTV=0 - DUT_ENCODER_PATH=./IVAS_cod_ref + - MERGE_TARGET_ENCODER_PATH=./IVAS_cod_ref - TEST_SUITE="$SHORT_TEST_SUITE" - LEVEL_SCALING=0.3162 - rm -rf tests/dut tests/ref - <<: *ivas-pytest-on-merge-request-anchor + <<: *check-be-to-target-anchor + +### jobs that check for regressions on non-BE testcases +check-regressions-short-enc-0db: + stage: test + needs: + - job: "check-be-to-target-short-enc-0db" + artifacts: true + extends: + - .rules-mr-to-main-or-main-pc + - .test-job-linux + before_script: + - *set-reference-for-basop-port-branch + - USE_LTV=0 + - DUT_DECODER_PATH=./IVAS_dec_ref + - TEST_SUITE="$SHORT_TEST_SUITE_ENCODER" + - LEVEL_SCALING=1.0 + - rm -rf tests/dut tests/ref + <<: *check-regressions-pytest-anchor + +check-regressions-short-enc-+10db: + stage: test + needs: + - job: "check-be-to-target-short-enc-+10db" + artifacts: true + extends: + - .rules-mr-to-main-or-main-pc + - .test-job-linux + before_script: + - *set-reference-for-basop-port-branch + - USE_LTV=0 + - DUT_DECODER_PATH=./IVAS_dec_ref + - TEST_SUITE="$SHORT_TEST_SUITE_ENCODER" + - LEVEL_SCALING=3.162 + - rm -rf tests/dut tests/ref + <<: *check-regressions-pytest-anchor + +check-regressions-short-enc--10db: + stage: test + needs: + - job: "check-be-to-target-short-enc--10db" + artifacts: true + extends: + - .rules-mr-to-main-or-main-pc + - .test-job-linux + before_script: + - USE_LTV=0 + - DUT_DECODER_PATH=./IVAS_dec_ref + - TEST_SUITE="$SHORT_TEST_SUITE_ENCODER" + - LEVEL_SCALING=0.3162 + - rm -rf tests/dut tests/ref + <<: *check-regressions-pytest-anchor + +check-regressions-short-dec-0db: + stage: test + needs: + - job: "check-be-to-target-short-dec-0db" + artifacts: true + extends: + - .rules-mr-to-main-or-main-pc + - .test-job-linux + before_script: + - *set-reference-for-basop-port-branch + - USE_LTV=0 + - DUT_ENCODER_PATH=./IVAS_cod_ref + - TEST_SUITE="$SHORT_TEST_SUITE" + - LEVEL_SCALING=1.0 + - rm -rf tests/dut tests/ref + <<: *check-regressions-pytest-anchor -ivas-pytest-compare_to_main-short-dec-lev+10: +check-regressions-short-dec-+10db: + stage: test + needs: + - job: "check-be-to-target-short-dec-+10db" + artifacts: true extends: - - .rules-pytest-to-main-short + - .rules-mr-to-main-or-main-pc - .test-job-linux before_script: + - *set-reference-for-basop-port-branch - USE_LTV=0 - DUT_ENCODER_PATH=./IVAS_cod_ref - TEST_SUITE="$SHORT_TEST_SUITE" - LEVEL_SCALING=3.162 - rm -rf tests/dut tests/ref - <<: *ivas-pytest-on-merge-request-anchor + <<: *check-regressions-pytest-anchor + +check-regressions-short-dec--10db: + stage: test + needs: + - job: "check-be-to-target-short-dec--10db" + artifacts: true + extends: + - .rules-mr-to-main-or-main-pc + - .test-job-linux + before_script: + - USE_LTV=0 + - DUT_ENCODER_PATH=./IVAS_cod_ref + - TEST_SUITE="$SHORT_TEST_SUITE" + - LEVEL_SCALING=0.3162 + - rm -rf tests/dut tests/ref + <<: *check-regressions-pytest-anchor # --------------------------------------------------------------- # Short test jobs for running from web interface or schedule @@ -804,10 +1610,10 @@ ivas-pytest-compare_to_main-short-dec-lev+10: ### jobs that test fx encoder -> flt decoder ivas-pytest-compare_to_ref-short-enc: extends: - #- .rules-pytest-to-ref-short - - .rules-pytest-to-ref-enc-short-temp + - .rules-pytest-to-ref-short - .test-job-linux before_script: + - *set-reference-for-basop-port-branch - USE_LTV=0 - ENCODER_TEST="true" - DUT_DECODER_PATH=./$REF_DECODER_PATH @@ -817,10 +1623,10 @@ ivas-pytest-compare_to_ref-short-enc: ivas-pytest-compare_to_ref-short-enc-lev-10: extends: - #- .rules-pytest-to-ref-short - - .rules-pytest-to-ref-enc-short-temp - - .test-job-linux + - .rules-pytest-to-ref-short + - .test-job-linux before_script: + - *set-reference-for-basop-port-branch - USE_LTV=0 - ENCODER_TEST="true" - DUT_DECODER_PATH=./$REF_DECODER_PATH @@ -830,10 +1636,10 @@ ivas-pytest-compare_to_ref-short-enc-lev-10: ivas-pytest-compare_to_ref-short-enc-lev+10: extends: - #- .rules-pytest-to-ref-short - - .rules-pytest-to-ref-enc-short-temp - - .test-job-linux + - .rules-pytest-to-ref-short + - .test-job-linux before_script: + - *set-reference-for-basop-port-branch - USE_LTV=0 - ENCODER_TEST="true" - DUT_DECODER_PATH=./$REF_DECODER_PATH @@ -844,6 +1650,8 @@ ivas-pytest-compare_to_ref-short-enc-lev+10: ivas-pytest-enc-msan: extends: - .test-job-linux + tags: + - ivas-basop-linux-fast before_script: - CLANG_NUM=1 - DUT_DECODER_PATH=./$REF_DECODER_PATH @@ -853,6 +1661,8 @@ ivas-pytest-enc-msan: ivas-pytest-enc-asan: extends: - .test-job-linux + tags: + - ivas-basop-linux-fast before_script: - CLANG_NUM=2 - DUT_DECODER_PATH=./$REF_DECODER_PATH @@ -862,17 +1672,19 @@ ivas-pytest-enc-asan: ivas-pytest-enc-usan: extends: - .test-job-linux + tags: + - ivas-basop-linux-fast before_script: - CLANG_NUM=3 - DUT_DECODER_PATH=./$REF_DECODER_PATH - - TEST_SUITE=$SHORT_TEST_SUITE_ENCODER + - TEST_SUITE=$LONG_TEST_SUITE_ENCODER <<: *ivas-pytest-sanitizers-anchor ### jobs that test flt encoder -> fx decoder ivas-pytest-compare_to_ref-short-dec: extends: - .rules-pytest-to-ref-short - - .test-job-linux + - .test-job-linux before_script: - USE_LTV=0 - DUT_ENCODER_PATH=./$REF_ENCODER_PATH @@ -883,7 +1695,7 @@ ivas-pytest-compare_to_ref-short-dec: ivas-pytest-compare_to_ref-short-dec-lev-10: extends: - .rules-pytest-to-ref-short - - .test-job-linux + - .test-job-linux before_script: - USE_LTV=0 - DUT_ENCODER_PATH=./$REF_ENCODER_PATH @@ -894,7 +1706,7 @@ ivas-pytest-compare_to_ref-short-dec-lev-10: ivas-pytest-compare_to_ref-short-dec-lev+10: extends: - .rules-pytest-to-ref-short - - .test-job-linux + - .test-job-linux before_script: - USE_LTV=0 - DUT_ENCODER_PATH=./$REF_ENCODER_PATH @@ -928,28 +1740,34 @@ ivas-pytest-compare-to-input-short-enc: ivas-pytest-dec-msan: extends: - .test-job-linux + tags: + - ivas-basop-linux-fast before_script: - CLANG_NUM=1 - DUT_ENCODER_PATH=./$REF_ENCODER_PATH - - TEST_SUITE=$LONG_TEST_SUITE_SELF_TEST + - TEST_SUITE=$LONG_TEST_SUITE_NO_RENDERER <<: *ivas-pytest-sanitizers-anchor ivas-pytest-dec-asan: extends: - .test-job-linux + tags: + - ivas-basop-linux-fast before_script: - CLANG_NUM=2 - DUT_ENCODER_PATH=./$REF_ENCODER_PATH - - TEST_SUITE=$LONG_TEST_SUITE_SELF_TEST + - TEST_SUITE=$LONG_TEST_SUITE_NO_RENDERER <<: *ivas-pytest-sanitizers-anchor ivas-pytest-dec-usan: extends: - .test-job-linux + tags: + - ivas-basop-linux-fast before_script: - CLANG_NUM=3 - DUT_ENCODER_PATH=./$REF_ENCODER_PATH - - TEST_SUITE=$SHORT_TEST_SUITE + - TEST_SUITE=$LONG_TEST_SUITE_NO_RENDERER <<: *ivas-pytest-sanitizers-anchor # --------------------------------------------------------------- @@ -959,7 +1777,7 @@ ivas-pytest-dec-usan: ivas-pytest-compare_ref-long-enc: extends: - .rules-pytest-long - - .test-job-linux + - .test-job-linux before_script: - USE_LTV=1 - DUT_DECODER_PATH=./$REF_DECODER_PATH @@ -970,7 +1788,7 @@ ivas-pytest-compare_ref-long-enc: ivas-pytest-compare_ref-long-dec: extends: - .rules-pytest-long - - .test-job-linux + - .test-job-linux before_script: - USE_LTV=1 - DUT_ENCODER_PATH=./$REF_ENCODER_PATH @@ -981,7 +1799,7 @@ ivas-pytest-compare_ref-long-dec: ivas-pytest-compare_ref-long-enc-lev-10: extends: - .rules-pytest-long - - .test-job-linux + - .test-job-linux before_script: - USE_LTV=1 - DUT_DECODER_PATH=./$REF_DECODER_PATH @@ -992,7 +1810,7 @@ ivas-pytest-compare_ref-long-enc-lev-10: ivas-pytest-compare_ref-long-dec-lev-10: extends: - .rules-pytest-long - - .test-job-linux + - .test-job-linux before_script: - USE_LTV=1 - DUT_ENCODER_PATH=./$REF_ENCODER_PATH @@ -1003,7 +1821,7 @@ ivas-pytest-compare_ref-long-dec-lev-10: ivas-pytest-compare_ref-long-enc-lev+10: extends: - .rules-pytest-long - - .test-job-linux + - .test-job-linux before_script: - USE_LTV=1 - DUT_DECODER_PATH=./$REF_DECODER_PATH @@ -1014,7 +1832,7 @@ ivas-pytest-compare_ref-long-enc-lev+10: ivas-pytest-compare_ref-long-dec-lev+10: extends: - .rules-pytest-long - - .test-job-linux + - .test-job-linux before_script: - USE_LTV=1 - DUT_ENCODER_PATH=./$REF_ENCODER_PATH @@ -1077,7 +1895,7 @@ coverage-test-on-main-scheduled: - *update-scripts-repo - *update-ltv-repo - *copy-ltv-files-to-testv-dir - - *build-reference-binaries + - *build-float-ref-binaries # Build DuT binaries with GCOV - make clean - make GCOV=1 -j @@ -1127,8 +1945,10 @@ be-2-evs-26444: extends: - .test-job-linux rules: + - if: $CI_MERGE_REQUEST_TITLE =~ /^(\[Draft\]|\(Draft\)|Draft:)/ + when: never - if: $CI_PIPELINE_SOURCE == 'web' && $MANUAL_PIPELINE_TYPE == "evs-26444" - - if: $CI_PIPELINE_SOURCE == 'merge_request_event' && $CI_MERGE_REQUEST_TARGET_BRANCH_NAME == "main" + - if: $CI_PIPELINE_SOURCE == 'merge_request_event' && ($CI_MERGE_REQUEST_TARGET_BRANCH_NAME == "main" || $CI_MERGE_REQUEST_TARGET_BRANCH_NAME == "main-pc") tags: - be-2-evs-basop stage: test @@ -1171,6 +1991,18 @@ ivas-pytest-renderer: - LEVEL_SCALING=1.0 <<: *ivas-pytest-anchor +peaq-enc-passthrough: + extends: + - .test-job-linux + rules: + - if: $CI_PIPELINE_SOURCE == 'web' && $MANUAL_PIPELINE_TYPE == "peaq-enc-passthrough" + before_script: + - USE_LTV=0 + - DUT_DECODER_PATH=./$REF_DECODER_PATH + - TEST_SUITE="tests/test_enc_passthrough.py" + - DELTA_ODG="true" + - LEVEL_SCALING=1.0 + <<: *ivas-pytest-anchor # --------------------------------------------------------------- # Various other tests @@ -1193,6 +2025,161 @@ voip-be-on-merge-request: - python3 -m pytest tests/test_be_for_jbm_neutral_dly_profile.py +# --------------------------------------------------------------- +# Test jobs for merge requests +# --------------------------------------------------------------- + +# test that runs all modes with 1s input signals +# TODO: disabled temporarily, needs to be adapted to BASOP +.codec-smoke-test: + extends: + - .test-job-linux-needs-testv-dir + - .rules-merge-request-no-draft + timeout: "20 minutes" + tags: + - ivas-basop-linux + stage: test + needs: ["build-codec-linux-make"] #, "build-codec-instrumented-linux", "build-codec-sanitizers-linux"] + script: + - *print-common-info + # LTV update needed as ltv ISM metadata files are used + - *update-ltv-repo + - bash ci/smoke_test.sh + ### analyze for failures + - if ! [ -s smoke_test_output.txt ] || ! [ -s smoke_test_output_jbm.txt ] || ! [ -s smoke_test_output_hrtf.txt ]; then echo "Error in smoke test"; exit 1; fi + - ret_val=0 + - if cat smoke_test_output.txt | grep -c "failed"; then echo "Smoke test without JBM failed"; ret_val=1; fi + - if cat smoke_test_output_jbm.txt | grep -c "failed"; then echo "Smoke test JBM part failed"; ret_val=1; fi + - if cat smoke_test_output_hrtf.txt | grep -c "failed"; then echo "Smoke test with external hrtf files failed"; ret_val=1; fi + - exit $ret_val + artifacts: + name: "mr-$CI_MERGE_REQUEST_IID--sha-$CI_COMMIT_SHORT_SHA--stage-$CI_JOB_STAGE--results" + expire_in: 1 week + when: always + paths: + - smoke_test_output.txt + - smoke_test_output_jbm.txt + - smoke_test_output_hrtf.txt + expose_as: "Smoke test results" + +# compare renderer bitexactness between target and source branch +renderer-pytest-on-merge-request: + extends: + - .test-job-linux-needs-testv-dir + - .rules-merge-request-to-main-pc + needs: ["build-codec-linux-make"] + # TODO: set reasonable timeout, will most likely take less + timeout: "20 minutes" + tags: + - ivas-basop-linux + stage: compare + script: + - *print-common-info + - *get-commits-behind-count + - *check-commits-behind-count-in-compare-jobs + - *merge-request-comparison-setup-codec + + # some helper variables - "|| true" to prevent failures from grep not finding anything + # write to temporary file as workaround for failures observed with piping echo + - echo $CI_MERGE_REQUEST_TITLE > tmp.txt + - non_be_flag=$(grep -c --ignore-case "\[rend\(erer\)*[ -]*non[ -]*be\]" tmp.txt) || true + # TODO: ref_using_target comes from float repo, but does not apply here - disable for now + # - ref_using_target=$(grep -c --ignore-case "\[ref[ -]*using[ -]*target\]" tmp.txt) || true + - ref_using_target=0 + + ### If ref_using_target is not set, checkout the source branch to use scripts and input from there + - if [ $ref_using_target == 0 ]; then git checkout $source_branch_commit_sha; fi + + - exit_code=0 + - testcase_timeout=60 + - python3 -m pytest -q --log-level ERROR -n auto -rA --html=report.html --self-contained-html --junit-xml=report-junit.xml tests/renderer/test_renderer.py --create_ref --testcase_timeout=$testcase_timeout || exit_code=$? + + ### Run test using branch scripts and input + - if [ $ref_using_target == 1 ]; then git checkout $source_branch_commit_sha; fi + + # run test + - python3 -m pytest -q --log-level ERROR -n auto -rA --html=report.html --self-contained-html --junit-xml=report-junit.xml tests/renderer/test_renderer.py --create_cut --testcase_timeout=$testcase_timeout || exit_code=$? + - zero_errors=$(cat report-junit.xml | grep -c 'errors="0"') || true + + - *merge-request-comparison-check + + allow_failure: + exit_codes: + - 123 + artifacts: + name: "mr-$CI_MERGE_REQUEST_IID--sha-$CI_COMMIT_SHORT_SHA--job-$CI_JOB_NAME--results" + expire_in: 1 week + when: always + paths: + - report-junit.xml + - report.html + expose_as: "pytest renderer results" + reports: + junit: + - report-junit.xml + +# compare bit exactness between target and source branch +ivas-pytest-on-merge-request: + extends: + - .test-job-linux-needs-testv-dir + - .rules-merge-request-to-main-pc + stage: compare + # TODO: broken dependency needs to be removed temporarily, see above + # note: this step doesn't really depend on codec-smoke-test + # it's just pointless to run this step when the smoke test fails and the smoke test should be reasonably fast + # thus, overall, this should save time + needs: ["build-codec-linux-make"] #, "codec-smoke-test"] + timeout: "40 minutes" + tags: + - ivas-basop-linux + script: + - *print-common-info + - *get-commits-behind-count + - *check-commits-behind-count-in-compare-jobs + - *merge-request-comparison-setup-codec + - python3 ci/remove_unsupported_testcases.py $PRM_FILES + + # some helper variables - "|| true" to prevent failures from grep not finding anything + # write to temporary file as workaround for failures observed with piping echo + - echo $CI_MERGE_REQUEST_TITLE > tmp.txt + - non_be_flag=$(grep -c --ignore-case "\[non[ -]*be\]" tmp.txt) || true + # TODO: ref_using_target comes from float repo, but does not apply here - disable for now + # - ref_using_target=$(grep -c --ignore-case "\[ref[ -]*using[ -]*target\]" tmp.txt) || true + - ref_using_target=0 + + ### If ref_using_target is not set, checkout the source branch to use scripts and input from there + - if [ $ref_using_target == 0 ]; then git checkout $source_branch_commit_sha; fi + + ### prepare pytest + # create references + - python3 -m pytest $TESTS_DIR_CODEC_BE_ON_MR -v --update_ref 1 + + ### Run test using branch scripts and input + - if [ $ref_using_target == 1 ]; then git checkout $source_branch_commit_sha; fi + + ### run pytest + - exit_code=0 + - testcase_timeout=600 + - python3 -m pytest $TESTS_DIR_CODEC_BE_ON_MR -v --html=report.html --self-contained-html --junit-xml=report-junit.xml --testcase_timeout=$testcase_timeout || exit_code=$? + - zero_errors=$(cat report-junit.xml | grep -c 'errors="0"') || true + + - *merge-request-comparison-check + + allow_failure: + exit_codes: + - 123 + artifacts: + name: "mr-$CI_MERGE_REQUEST_IID--sha-$CI_COMMIT_SHORT_SHA--stage-$CI_JOB_STAGE--results" + expire_in: 1 week + when: always + paths: + - report-junit.xml + - report.html + expose_as: "pytest ivas results" + reports: + junit: + - report-junit.xml + # --------------------------------------------------------------- # Complexity measurement jobs # --------------------------------------------------------------- @@ -1204,6 +2191,9 @@ voip-be-on-merge-request: - job_id=$(python3 ci/get_id_of_last_job_occurence.py $CI_COMMIT_REF_NAME $CI_JOB_NAME $CI_PROJECT_ID) - echo $job_id + # this is a testing/maintenance mechanism to force getting the log history from a specific job id + # see below in the concrete complexity jobs + - if [ "$JOB_ID_INJECT" != "" ]; then job_id=$JOB_ID_INJECT; fi - curl --request GET "https://forge.3gpp.org/rep/api/v4/projects/$CI_PROJECT_ID/jobs/$job_id/artifacts" --output artifacts.zip - unzip artifacts.zip || true # this may fail on first run, when there are no artifacts there and the zip file is actually just "404"-html - ls @@ -1214,21 +2204,13 @@ voip-be-on-merge-request: - rm artifacts.zip - rm -rf $public_dir - ### 1.5.part: get the corresponding measurement from ivas-float-update-cmplx - - job_id=$(python3 ci/get_id_of_last_job_occurence.py ivas-float-update-cmplx $CI_JOB_NAME $CI_PROJECT_ID) + ### 1.5.part: get the corresponding measurement from ivas-float-update + - job_id=$(python3 ci/get_id_of_last_job_occurence.py ivas-float-update $CI_JOB_NAME $CI_PROJECT_ID) - echo $job_id - curl --request GET "https://forge.3gpp.org/rep/api/v4/projects/$CI_PROJECT_ID/jobs/$job_id/artifacts" --output artifacts_ref.zip - - unzip -j artifacts_ref.zip "*latest_WMOPS.csv" - - ### 2. part: setup specific for BASOP repo - # hack for using the reference encoder -> need to build manually to make script use ref enc and BASOP dec - - mkdir COMPLEXITY - - cp IVAS_cod_ref COMPLEXITY/IVAS_cod - # build branch code aain with instrumentation - - make clean - - bash scripts/prepare_instrumentation.sh -p BASOP -m MEM_ONLY - - make -j -C $INSTR_DIR - - cp $INSTR_DIR/IVAS_dec COMPLEXITY/IVAS_dec + - unzip -j artifacts_ref.zip "*latest_WMOPS.csv" || true + # add file to arguments only if the artifact could be retrieved to prevent error later. + - if [ -f latest_WMOPS.csv ]; then GET_WMOPS_ARGS="$GET_WMOPS_ARGS latest_WMOPS.csv"; fi .complexity-measurements-prepare-artifacts: &complexity-measurements-prepare-artifacts # prepare artifacts -> move to public directory @@ -1256,12 +2238,13 @@ voip-be-on-merge-request: stage: test variables: ret_val: 0 + GET_WMOPS_ARGS: "mem_only" timeout: 3 hours 30 minutes before_script: - *print-common-info - *update-scripts-repo - *update-ltv-repo - - *build-reference-and-dut-binaries + - *build-float-ref-and-dut-binaries - *complexity-measurements-setup - which coan artifacts: @@ -1276,10 +2259,12 @@ complexity-stereo-in-stereo-out: - .complexity-template rules: - if: $MEASURE_COMPLEXITY_LINUX + variables: + JOB_ID_INJECT: "" script: - in_format=stereo - out_format=stereo - - bash ci/complexity_measurements/getWmops.sh "$in_format" "$out_format" mem_only basop latest_WMOPS.csv || ret_val=$? + - bash ci/complexity_measurements/getWmops.sh "$in_format" "$out_format" $GET_WMOPS_ARGS || ret_val=$? - *complexity-measurements-prepare-artifacts - exit $ret_val @@ -1290,11 +2275,13 @@ complexity-ism-in-binaural-out: - if: $MEASURE_COMPLEXITY_LINUX when: delayed start_in: 1 hour + variables: + JOB_ID_INJECT: "" script: - in_format=ISM - out_format=BINAURAL - ret_val=0 - - bash ci/complexity_measurements/getWmops.sh "ISM+1 ISM+2 ISM+3 ISM+4" "$out_format" mem_only basop latest_WMOPS.csv || ret_val=$? + - bash ci/complexity_measurements/getWmops.sh "ISM+1 ISM+2 ISM+3 ISM+4" "$out_format" $GET_WMOPS_ARGS || ret_val=$? - *complexity-measurements-prepare-artifacts - exit $ret_val @@ -1305,11 +2292,13 @@ complexity-ism-in-binaural_room_ir-out: - if: $MEASURE_COMPLEXITY_LINUX when: delayed start_in: 2 hours + variables: + JOB_ID_INJECT: "" script: - in_format=ISM - out_format=BINAURAL_ROOM_IR - ret_val=0 - - bash ci/complexity_measurements/getWmops.sh "ISM+1 ISM+2 ISM+3 ISM+4" "$out_format" mem_only basop latest_WMOPS.csv || ret_val=$? + - bash ci/complexity_measurements/getWmops.sh "ISM+1 ISM+2 ISM+3 ISM+4" "$out_format" $GET_WMOPS_ARGS || ret_val=$? - *complexity-measurements-prepare-artifacts - exit $ret_val @@ -1320,11 +2309,13 @@ complexity-ism-in-ext-out: - if: $MEASURE_COMPLEXITY_LINUX when: delayed start_in: 3 hours 30 minutes + variables: + JOB_ID_INJECT: "" script: - in_format=ISM - out_format=EXT - ret_val=0 - - bash ci/complexity_measurements/getWmops.sh "ISM+1 ISM+2 ISM+3 ISM+4" "$out_format" mem_only basop latest_WMOPS.csv || ret_val=$? + - bash ci/complexity_measurements/getWmops.sh "ISM+1 ISM+2 ISM+3 ISM+4" "$out_format" $GET_WMOPS_ARGS || ret_val=$? - *complexity-measurements-prepare-artifacts - exit $ret_val @@ -1335,11 +2326,13 @@ complexity-sba-hoa3-in-hoa3-out: - if: $MEASURE_COMPLEXITY_LINUX when: delayed start_in: 4 hours 30 minutes + variables: + JOB_ID_INJECT: "" script: - in_format=HOA3 - out_format=HOA3 - ret_val=0 - - bash ci/complexity_measurements/getWmops.sh "$in_format" "$out_format" mem_only basop latest_WMOPS.csv || ret_val=$? + - bash ci/complexity_measurements/getWmops.sh "$in_format" "$out_format" $GET_WMOPS_ARGS || ret_val=$? - *complexity-measurements-prepare-artifacts - exit $ret_val @@ -1350,11 +2343,13 @@ complexity-sba-hoa3-in-binaural-out: - if: $MEASURE_COMPLEXITY_LINUX when: delayed start_in: 5 hours 30 minutes + variables: + JOB_ID_INJECT: "" script: - in_format=HOA3 - out_format=BINAURAL - ret_val=0 - - bash ci/complexity_measurements/getWmops.sh "$in_format" "$out_format" mem_only basop latest_WMOPS.csv || ret_val=$? + - bash ci/complexity_measurements/getWmops.sh "$in_format" "$out_format" $GET_WMOPS_ARGS || ret_val=$? - *complexity-measurements-prepare-artifacts - exit $ret_val @@ -1365,11 +2360,13 @@ complexity-sba-hoa3-in-binaural_room_ir-out: - if: $MEASURE_COMPLEXITY_LINUX when: delayed start_in: 6 hours 30 minutes + variables: + JOB_ID_INJECT: "" script: - in_format=HOA3 - out_format=BINAURAL_ROOM_IR - ret_val=0 - - bash ci/complexity_measurements/getWmops.sh "$in_format" "$out_format" mem_only basop latest_WMOPS.csv || ret_val=$? + - bash ci/complexity_measurements/getWmops.sh "$in_format" "$out_format" $GET_WMOPS_ARGS || ret_val=$? - *complexity-measurements-prepare-artifacts - exit $ret_val @@ -1380,11 +2377,13 @@ complexity-mc-in-7_1_4-out: - if: $MEASURE_COMPLEXITY_LINUX when: delayed start_in: 7 hours 30 minutes + variables: + JOB_ID_INJECT: "" script: - in_format=MC - out_format=7_1_4 - ret_val=0 - - bash ci/complexity_measurements/getWmops.sh "$in_format" "$out_format" mem_only basop latest_WMOPS.csv || ret_val=$? + - bash ci/complexity_measurements/getWmops.sh "$in_format" "$out_format" $GET_WMOPS_ARGS || ret_val=$? - *complexity-measurements-prepare-artifacts - exit $ret_val @@ -1395,11 +2394,13 @@ complexity-mc-in-binaural-out: - if: $MEASURE_COMPLEXITY_LINUX when: delayed start_in: 10 hours + variables: + JOB_ID_INJECT: "" script: - in_format=MC - out_format=BINAURAL - ret_val=0 - - bash ci/complexity_measurements/getWmops.sh "$in_format" "$out_format" mem_only basop latest_WMOPS.csv || ret_val=$? + - bash ci/complexity_measurements/getWmops.sh "$in_format" "$out_format" $GET_WMOPS_ARGS || ret_val=$? - *complexity-measurements-prepare-artifacts - exit $ret_val @@ -1410,11 +2411,13 @@ complexity-mc-in-binaural_room_ir-out: - if: $MEASURE_COMPLEXITY_LINUX when: delayed start_in: 12 hours 30 minutes + variables: + JOB_ID_INJECT: "" script: - in_format=MC - out_format=BINAURAL_ROOM_IR - ret_val=0 - - bash ci/complexity_measurements/getWmops.sh "$in_format" "$out_format" mem_only basop latest_WMOPS.csv || ret_val=$? + - bash ci/complexity_measurements/getWmops.sh "$in_format" "$out_format" $GET_WMOPS_ARGS || ret_val=$? - *complexity-measurements-prepare-artifacts - exit $ret_val @@ -1425,11 +2428,13 @@ complexity-masa-in-ext-out: - if: $MEASURE_COMPLEXITY_LINUX when: delayed start_in: 15 hours + variables: + JOB_ID_INJECT: "" script: - in_format=MASA - out_format=EXT - ret_val=0 - - bash ci/complexity_measurements/getWmops.sh "$in_format" "$out_format" mem_only basop latest_WMOPS.csv || ret_val=$? + - bash ci/complexity_measurements/getWmops.sh "$in_format" "$out_format" $GET_WMOPS_ARGS || ret_val=$? - *complexity-measurements-prepare-artifacts - exit $ret_val @@ -1440,11 +2445,13 @@ complexity-masa-in-binaural-out: - if: $MEASURE_COMPLEXITY_LINUX when: delayed start_in: 16 hours + variables: + JOB_ID_INJECT: "" script: - in_format=MASA - out_format=BINAURAL - ret_val=0 - - bash ci/complexity_measurements/getWmops.sh "$in_format" "$out_format" mem_only basop latest_WMOPS.csv || ret_val=$? + - bash ci/complexity_measurements/getWmops.sh "$in_format" "$out_format" $GET_WMOPS_ARGS || ret_val=$? - *complexity-measurements-prepare-artifacts - exit $ret_val @@ -1455,11 +2462,13 @@ complexity-masa-in-hoa3-out: - if: $MEASURE_COMPLEXITY_LINUX when: delayed start_in: 17 hours + variables: + JOB_ID_INJECT: "" script: - in_format=MASA - out_format=HOA3 - ret_val=0 - - bash ci/complexity_measurements/getWmops.sh "$in_format" "$out_format" mem_only basop latest_WMOPS.csv || ret_val=$? + - bash ci/complexity_measurements/getWmops.sh "$in_format" "$out_format" $GET_WMOPS_ARGS || ret_val=$? - *complexity-measurements-prepare-artifacts - exit $ret_val @@ -1470,11 +2479,13 @@ complexity-masa-in-hoa3-out: # - if: $MEASURE_COMPLEXITY_LINUX # when: delayed # start_in: 13 hours + # variables: + # JOB_ID_INJECT: "" # script: # - in_format=OMASA # - out_format=EXT # - ret_val=0 -# - bash ci/complexity_measurements/getWmops.sh "$in_format" "$out_format" mem_only basop latest_WMOPS.csv || ret_val=$? +# - bash ci/complexity_measurements/getWmops.sh "$in_format" "$out_format" $GET_WMOPS_ARGS || ret_val=$? # - *complexity-measurements-prepare-artifacts # - exit $ret_val @@ -1485,11 +2496,13 @@ complexity-omasa-in-binaural-out: - if: $MEASURE_COMPLEXITY_LINUX when: delayed start_in: 18 hours + variables: + JOB_ID_INJECT: "" script: - in_format=OMASA - out_format=BINAURAL - ret_val=0 - - bash ci/complexity_measurements/getWmops.sh "$in_format" "$out_format" mem_only basop latest_WMOPS.csv || ret_val=$? + - bash ci/complexity_measurements/getWmops.sh "$in_format" "$out_format" $GET_WMOPS_ARGS || ret_val=$? - *complexity-measurements-prepare-artifacts - exit $ret_val @@ -1500,11 +2513,13 @@ complexity-omasa-in-hoa3-out: - if: $MEASURE_COMPLEXITY_LINUX when: delayed start_in: 20 hours + variables: + JOB_ID_INJECT: "" script: - in_format=OMASA - out_format=HOA3 - ret_val=0 - - bash ci/complexity_measurements/getWmops.sh "$in_format" "$out_format" mem_only basop latest_WMOPS.csv || ret_val=$? + - bash ci/complexity_measurements/getWmops.sh "$in_format" "$out_format" $GET_WMOPS_ARGS || ret_val=$? - *complexity-measurements-prepare-artifacts - exit $ret_val @@ -1515,11 +2530,13 @@ complexity-StereoDmxEVS-stereo-in-mono-out: - if: $MEASURE_COMPLEXITY_LINUX when: delayed start_in: 22 hours + variables: + JOB_ID_INJECT: "" script: - in_format=StereoDmxEVS - out_format=mono - ret_val=0 - - bash ci/complexity_measurements/getWmops.sh "$in_format" "$out_format" mem_only basop latest_WMOPS.csv || ret_val=$? + - bash ci/complexity_measurements/getWmops.sh "$in_format" "$out_format" $GET_WMOPS_ARGS || ret_val=$? - *complexity-measurements-prepare-artifacts - exit $ret_val @@ -1534,7 +2551,7 @@ complexity-StereoDmxEVS-stereo-in-mono-out: # - in_format=OSBA # - out_format=EXT # - ret_val=0 -# - bash ci/complexity_measurements/getWmops.sh "$in_format" "$out_format" mem_only basop latest_WMOPS.csv || ret_val=$? +# - bash ci/complexity_measurements/getWmops.sh "$in_format" "$out_format" $GET_WMOPS_ARGS || ret_val=$? # - *complexity-measurements-prepare-artifacts # - exit $ret_val @@ -1545,11 +2562,13 @@ complexity-osba-in-binaural-out: - if: $MEASURE_COMPLEXITY_LINUX when: delayed start_in: 22 hours 30 minutes + variables: + JOB_ID_INJECT: "" script: - in_format=OSBA - out_format=BINAURAL - ret_val=0 - - bash ci/complexity_measurements/getWmops.sh "$in_format" "$out_format" mem_only basop latest_WMOPS.csv || ret_val=$? + - bash ci/complexity_measurements/getWmops.sh "$in_format" "$out_format" $GET_WMOPS_ARGS || ret_val=$? - *complexity-measurements-prepare-artifacts - exit $ret_val @@ -1560,11 +2579,13 @@ complexity-osba-in-binaural_room_ir-out: - if: $MEASURE_COMPLEXITY_LINUX when: delayed start_in: 25 hours + variables: + JOB_ID_INJECT: "" script: - in_format=OSBA - out_format=BINAURAL_ROOM_IR - ret_val=0 - - bash ci/complexity_measurements/getWmops.sh "$in_format" "$out_format" mem_only basop latest_WMOPS.csv || ret_val=$? + - bash ci/complexity_measurements/getWmops.sh "$in_format" "$out_format" $GET_WMOPS_ARGS || ret_val=$? - *complexity-measurements-prepare-artifacts - exit $ret_val diff --git a/.gitlab/issue_templates/float-update-porting.md b/.gitlab/issue_templates/float-update-porting.md new file mode 100644 index 0000000000000000000000000000000000000000..19bbf7ba8c6def64e62370be7af899305207a50d --- /dev/null +++ b/.gitlab/issue_templates/float-update-porting.md @@ -0,0 +1,6 @@ +# Basic Info + + +- Original merge request in float repo: + +/label ~Type:FloatUpdatePorting ~Status::ToDo diff --git a/.gitlab/merge_request_templates/float-update-porting.md b/.gitlab/merge_request_templates/float-update-porting.md new file mode 100644 index 0000000000000000000000000000000000000000..5b6d90dad72b5e2e145b118dd1fff2d5efb196f2 --- /dev/null +++ b/.gitlab/merge_request_templates/float-update-porting.md @@ -0,0 +1,6 @@ + +- Link to issue in BASOP repo: +- Link to original MR in float repo: +- Requested reviewers: + +/label Type:FloatUpdatePorting diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..adc86288c6d2062591090decdb6954098185c923 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,221 @@ +# CMake file for IVAS +# +# Usage with Unix Makefiles (Linux, OS/X): +# # create build directory +# mkdir build ; cd build +# # call CMake to generate build system, e.g. one of the following: +# cmake -D CMAKE_BUILD_TYPE=Debug ../ +# cmake -D CMAKE_BUILD_TYPE=Release ../ +# cmake -D CMAKE_BUILD_TYPE=Debug -D TARGET_PLATFORM=x86_64 ../ +# # build project +# make -j8 +# +# Usage with Visual Studio +# 1) download CMake from https://cmake.org/download/, don't use the Cygwin version! +# 2.1) build project using IDE +# In CMake GUI select the source dir (root of stereo-evs) and a new binary directory +# and press "Configure" and "Generate". Then open the Visual Studio solution file generated +# in the build directory. +# 2.2) build project using command line +# # create build directory +# mkdir build ; cd build +# # call CMake to generate build system, e.g. one of the following: +# cmake ../ +# cmake -G "Visual Studio 12 2013" ../ +# cmake -G "Visual Studio 12 2013 Win64" ../ +# # open the Visual Studio solution file generated in the build directory +# # or build on command line, e.g.: +# cmake --build . --config Debug +# cmake --build . --config Release + + +cmake_minimum_required(VERSION 3.1) + +set(CMAKE_C_STANDARD 99) + +# configuration options for UNIX +if(UNIX) + set(TARGET_PLATFORM "" CACHE STRING "i686 / x86_64") + set(CLANG "" CACHE STRING "1=msan / 2=asan / 3=usan") + set(GCOV OFF CACHE BOOL "enable GCOV") + set(STRIP OFF CACHE BOOL "enable STRIP") + + if(NOT CMAKE_BUILD_TYPE) + set(CMAKE_BUILD_TYPE "Debug" CACHE STRING "") + endif() + # TARGET_PLATFORM + if("${TARGET_PLATFORM}" MATCHES "i386" OR + "${TARGET_PLATFORM}" MATCHES "i586" OR + "${TARGET_PLATFORM}" MATCHES "i686" + ) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -m32") + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -m32") + elseif("${TARGET_PLATFORM}" MATCHES "x86_64") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -m64") + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -m64") + endif() + # C compiler flags + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -ffp-contract=off") # disable floating point operation contraction + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -pedantic -Wcast-qual -Wall -W -Wextra -Wno-long-long") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wpointer-arith -Wstrict-prototypes -Wmissing-prototypes") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-unused-parameter") + # to be uncommented in CI + # set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Werror") + + # CLANG + if(CLANG) + find_program(clangBin NAMES /home/amm-archiv/soft/Linux/clang/current/bin/clang clang REQUIRED) + set(CMAKE_C_COMPILER "${clangBin}" CACHE STRING "") + if("${CLANG}" MATCHES "1" OR "${CLANG}" MATCHES "msan") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=memory") + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fsanitize=memory") + elseif("${CLANG}" MATCHES "2" OR "${CLANG}" MATCHES "asan") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=address") + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fsanitize=address") + elseif("${CLANG}" MATCHES "3" OR "${CLANG}" MATCHES "usan") + # NOTE: keep in sync with list in Makefile + set(USAN_CHECKS_ENABLE + undefined # Default checks + # Extra checks + float-divide-by-zero + implicit-conversion + local-bounds + ) + list(JOIN USAN_CHECKS_ENABLE "," USAN_CHECKS_ENABLE) + + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=${USAN_CHECKS_ENABLE} -fsanitize-recover=${USAN_CHECKS_ENABLE}") + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fsanitize=${USAN_CHECKS_ENABLE} -fsanitize-recover=${USAN_CHECKS_ENABLE}") + else() + message(FATAL_ERROR "Unknown CLANG setting: ${CLANG}") + endif() + endif() + # GCOV + if(GCOV) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fprofile-arcs -ftest-coverage -fprofile-update=atomic") + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fprofile-arcs -ftest-coverage -fprofile-update=atomic") + endif() + # STRIP + if(STRIP) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fdata-sections -ffunction-sections") + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,-gc-sections -static") + endif() + + message("CMAKE_C_FLAGS: ${CMAKE_C_FLAGS}") + message("CMAKE_EXE_LINKER_FLAGS: ${CMAKE_EXE_LINKER_FLAGS}") + # write settings in CMake cache + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS}" CACHE STRING "") + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS}" CACHE STRING "") + set(CMAKE_C_FLAGS_DEBUG "-O0 -g3" CACHE STRING "") + set(CMAKE_C_FLAGS_RELEASE "-O2 -DRELEASE" CACHE STRING "") # TODO should contain -DNDEBUG to disable assert() +elseif(WIN32) + # MSVC compiler flags + add_definitions( + -D_CRT_SECURE_NO_WARNINGS + /MP + ) +endif() + +# configuration options for all platforms +set(WMOPS OFF CACHE BOOL "enable WMOPS") +if(WMOPS) + add_definitions("-DWMOPS=1") +endif() + +project(stereo-evs) +set_property(GLOBAL PROPERTY USE_FOLDERS ON) # make Visual Studio projects look nicer +include(CTest) + +file(GLOB libComSrcs "lib_com/*.c") +file(GLOB libComHeaders "lib_com/*.h") +add_library(lib_com ${libComSrcs} ${libComHeaders}) +if(UNIX) + target_link_libraries(lib_com PRIVATE m) +endif() +target_include_directories(lib_com PUBLIC lib_com PRIVATE lib_enc lib_dec lib_rend lib_debug lib_isar) +target_include_directories(lib_com PRIVATE lib_lc3plus) + +file(GLOB libDebugSrcs "lib_debug/*.c") +file(GLOB libDebugHeaders "lib_debug/*.h") +add_library(lib_debug ${libDebugSrcs} ${libDebugHeaders}) +target_link_libraries(lib_debug lib_com) +target_include_directories(lib_debug PUBLIC lib_debug PRIVATE lib_enc lib_dec lib_rend lib_isar) + +file(GLOB libEncSrcs "lib_enc/*.c") +file(GLOB libEncHeaders "lib_enc/*.h") +add_library(lib_enc ${libEncSrcs} ${libEncHeaders}) +target_link_libraries(lib_enc lib_com lib_debug) +target_include_directories(lib_enc PUBLIC lib_enc PRIVATE lib_dec lib_rend lib_isar) +target_include_directories(lib_enc PRIVATE lib_lc3plus) + +file(GLOB libLC3plusSrcs "lib_lc3plus/*.c") +file(GLOB libLC3plusHeaders "lib_lc3plus/*.h") +add_library(lib_lc3plus ${libLC3plusSrcs} ${libLC3plusHeaders}) +target_include_directories(lib_lc3plus PUBLIC lib_lc3plus PRIVATE lib_com lib_debug) + +file(GLOB libRendSrcs "lib_rend/*.c") +file(GLOB libRendHeaders "lib_rend/*.h") + +add_library(lib_rend ${libRendSrcs} ${libRendHeaders}) +target_link_libraries(lib_rend lib_dec lib_com lib_debug) # Todo refactor: This dependency on lib_dec should be removed. +target_link_libraries(lib_rend lib_lc3plus lib_isar) +target_include_directories(lib_rend PUBLIC lib_rend PRIVATE lib_enc lib_isar) + + +file(GLOB libDecSrcs "lib_dec/*.c") +file(GLOB libDecHeaders "lib_dec/*.h") +add_library(lib_dec ${libDecSrcs} ${libDecHeaders}) +target_link_libraries(lib_dec lib_com lib_rend lib_debug lib_isar) +target_include_directories(lib_dec PUBLIC lib_dec lib_rend PRIVATE lib_enc lib_isar) + +file(GLOB libUtilSrcs "lib_util/*.c") +file(GLOB libUtilHeaders "lib_util/*.h") +add_library(lib_util ${libUtilSrcs} ${libUtilHeaders}) +target_include_directories(lib_util PUBLIC lib_util PRIVATE lib_com lib_enc lib_dec lib_rend lib_debug) +target_include_directories(lib_util PRIVATE lib_lc3plus lib_isar) + +if(NOT WMOPS) + add_executable(ivas_lc3plus_unit_test ${CMAKE_SOURCE_DIR}/scripts/split_rendering/lc3plus_basop/ivas_lc3plus_unit_test.c) + target_link_libraries(ivas_lc3plus_unit_test lib_rend lib_dec lib_util lib_com lib_debug lib_isar) +endif() + +file(GLOB libISARSrcs "lib_isar/*.c") +file(GLOB libISARHeaders "lib_isar/*.h") + +add_library(lib_isar ${libISARSrcs} ${libISARHeaders}) +target_link_libraries(lib_isar lib_com lib_debug lib_lc3plus) # Todo refactor: This dependency on lib_dec should be removed. +target_include_directories(lib_isar PUBLIC lib_isar PRIVATE lib_enc lib_dec lib_rend) + + +add_executable(IVAS_cod apps/encoder.c) +target_link_libraries(IVAS_cod lib_enc lib_util) +if(WIN32) + target_link_libraries(IVAS_cod Ws2_32) +endif() + +add_executable(IVAS_dec apps/decoder.c) +target_link_libraries(IVAS_dec lib_dec lib_util) +if(WIN32) + target_link_libraries(IVAS_dec Ws2_32) +endif() + +add_executable(IVAS_rend apps/renderer.c) +target_link_libraries(IVAS_rend lib_rend lib_util lib_isar) +target_include_directories(IVAS_rend PRIVATE lib_enc) + +add_executable(ISAR_post_rend apps/isar_post_rend.c) +target_link_libraries(ISAR_post_rend lib_isar lib_util) +target_include_directories(ISAR_post_rend PRIVATE lib_isar) + +if(COPY_EXECUTABLES_FROM_BUILD_DIR) + # Optionally copy executables to the same place where Make puts them (useful for tests that expect executables in specific places) + add_custom_command(TARGET IVAS_cod POST_BUILD VERBATIM COMMAND "${CMAKE_COMMAND}" -E copy "$" "${CMAKE_CURRENT_SOURCE_DIR}/") + add_custom_command(TARGET IVAS_dec POST_BUILD VERBATIM COMMAND "${CMAKE_COMMAND}" -E copy "$" "${CMAKE_CURRENT_SOURCE_DIR}/") + add_custom_command(TARGET IVAS_rend POST_BUILD VERBATIM COMMAND "${CMAKE_COMMAND}" -E copy "$" "${CMAKE_CURRENT_SOURCE_DIR}/") + add_custom_command(TARGET ISAR_post_rend POST_BUILD VERBATIM COMMAND "${CMAKE_COMMAND}" -E copy "$" "${CMAKE_CURRENT_SOURCE_DIR}/") + if (NOT WMOPS) + add_custom_command(TARGET ivas_lc3plus_unit_test POST_BUILD VERBATIM COMMAND "${CMAKE_COMMAND}" -E copy "$" "${CMAKE_CURRENT_SOURCE_DIR}/scripts/split_rendering/lc3plus_basop") + endif() +endif() + +# Allow creating packages for CMake install +install(TARGETS lib_enc lib_dec lib_rend lib_com lib_util ARCHIVE DESTINATION lib) diff --git a/LICENSE.md b/LICENSE.md index 1c60a85b1afa1ba77ced378f75bed35f3ab214e6..ca74eaf483b6772614a49c5025aa865a357e063e 100644 --- a/LICENSE.md +++ b/LICENSE.md @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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/Makefile b/Makefile index 4e92bc951388c8564bc2f2319e1a646aef1e01b1..62306b6749442b18f2a15e583a3702028876336a 100644 --- a/Makefile +++ b/Makefile @@ -7,23 +7,31 @@ SRC_LIBDEBUG = lib_debug SRC_LIBDEC = lib_dec SRC_LIBENC = lib_enc SRC_LIBREND = lib_rend +SRC_LIBISAR = lib_isar +SRC_LC3PLUS = lib_lc3plus lib_lc3plus/fft SRC_LIBUTIL = lib_util SRC_APP = apps BUILD = build OBJDIR = obj -SRC_DIRS = $(sort -u $(SRC_LIBCOM) $(SRC_LIBDEBUG) $(SRC_LIBDEC) $(SRC_LIBENC) $(SRC_LIBREND) $(SRC_LIBUTIL) $(SRC_APP)) +INCLUDE_SPLIT = 1 + +SRC_DIRS = $(sort -u $(SRC_LIBCOM) $(SRC_LIBDEBUG) $(SRC_LIBDEC) $(SRC_LIBENC) $(SRC_LIBREND) $(SRC_LIBISAR) $(SRC_LC3PLUS) $(SRC_LIBUTIL) $(SRC_APP)) # Name of CLI binaries -CLI_APIDEC ?= IVAS_dec -CLI_APIENC ?= IVAS_cod -CLI_APIREND ?= IVAS_rend -LIB_LIBCOM ?= libivascom.a -LIB_LIBDEBUG ?= libivasdebug.a -LIB_LIBDEC ?= libivasdec.a -LIB_LIBENC ?= libivasenc.a -LIB_LIBREND ?= libivasrend.a -LIB_LIBUTIL ?= libivasutil.a +CLI_APIDEC ?= IVAS_dec +CLI_APIENC ?= IVAS_cod +CLI_APIREND ?= IVAS_rend +CLI_APIPOSTREND ?= ISAR_post_rend +LIB_LIBCOM ?= libivascom.a +LIB_LIBDEBUG ?= libivasdebug.a +LIB_LIBDEC ?= libivasdec.a +LIB_LIBENC ?= libivasenc.a +LIB_LIBREND ?= libivasrend.a +LIB_LIBISAR ?= libisar.a +LIB_LC3PLUS ?= liblc3plus.a +LIB_LIBUTIL ?= libivasutil.a + # Default tool settings CC ?= gcc @@ -82,10 +90,15 @@ ifeq "$(CLANG)" "3" CC = $(CCCLANG) # NOTE: keep in sync with list in CMakeLists.txt usan_checks = undefined,float-divide-by-zero,implicit-conversion,local-bounds -CFLAGS += -fsanitize=$(usan_checks) +CFLAGS += -fsanitize=$(usan_checks) CFLAGS += -fsanitize-recover=$(usan_checks) LDFLAGS += -fsanitize=$(usan_checks) LDFLAGS += -fsanitize-recover=$(usan_checks) + +ifeq "$(IGNORELIST)" "1" +CFLAGS += -fsanitize-ignorelist=ubsan_ignorelist.txt +LDFLAGS += -fsanitize-ignorelist=ubsan_ignorelist.txt +endif endif ifeq "$(RELEASE)" "1" @@ -124,8 +137,14 @@ CFLAGS += $(foreach DIR,$(SRC_DIRS),-I$(DIR)) # Source file search paths VPATH = $(SRC_DIRS) -# Filter out files that are not part of the build -EXCLUDED_FILES = +# Split rendering files +SRCS_SPLIT_REND = ivas_CQMFDecoder.c ivas_CQMFEncoder.c ivas_PerceptualModel.c ivas_PredDecoder.c \ + ivas_PredEncoder.c ivas_RMSEnvGrouping.c ivas_MSPred.c ivas_NoiseGen.c \ + ivas_splitRend_lcld_dec.c ivas_splitRend_lcld_enc.c \ + ivas_splitRendererPLC.c ivas_splitRendererPost.c ivas_splitRendererPre.c \ + ivas_splitRenderer_utils.c split_rend_bfi_file_reader.c split_render_file_read_write.c \ + ivas_lcld_tables.c + ############################################################################### @@ -135,27 +154,36 @@ SRCS_LIBDEC = $(foreach DIR,$(SRC_LIBDEC),$(patsubst $(DIR)/%,%,$(wildcard $(D SRCS_LIBENC = $(foreach DIR,$(SRC_LIBENC),$(patsubst $(DIR)/%,%,$(wildcard $(DIR)/*.c))) SRCS_LIBREND = $(foreach DIR,$(SRC_LIBREND),$(patsubst $(DIR)/%,%,$(wildcard $(DIR)/*.c))) SRCS_LIBUTIL = $(foreach DIR,$(SRC_LIBUTIL),$(patsubst $(DIR)/%,%,$(wildcard $(DIR)/*.c))) - -SRCS_LIBENC := $(filter-out $(EXCLUDED_FILES),$(SRCS_LIBENC)) +SRCS_LIBISAR = $(foreach DIR,$(SRC_LIBISAR),$(patsubst $(DIR)/%,%,$(wildcard $(DIR)/*.c))) +ifeq "$(INCLUDE_SPLIT)" "1" +SRCS_LC3PLUS = $(foreach DIR,$(SRC_LC3PLUS),$(patsubst $(DIR)/%,%,$(wildcard $(DIR)/*.c))) +else +# SRCS_LIBREND := $(filter-out $(SRCS_SPLIT_REND),$(SRCS_LIBREND)) +# SRCS_LIBUTIL := $(filter-out $(SRCS_SPLIT_REND),$(SRCS_LIBUTIL)) +endif OBJS_LIBCOM = $(addprefix $(OBJDIR)/,$(SRCS_LIBCOM:.c=.o)) OBJS_LIBDEBUG = $(addprefix $(OBJDIR)/,$(SRCS_LIBDEBUG:.c=.o)) OBJS_LIBDEC = $(addprefix $(OBJDIR)/,$(SRCS_LIBDEC:.c=.o)) OBJS_LIBENC = $(addprefix $(OBJDIR)/,$(SRCS_LIBENC:.c=.o)) OBJS_LIBREND = $(addprefix $(OBJDIR)/,$(SRCS_LIBREND:.c=.o)) +OBJS_LIBISAR = $(addprefix $(OBJDIR)/,$(SRCS_LIBISAR:.c=.o)) +OBJS_LC3PLUS = $(addprefix $(OBJDIR)/,$(SRCS_LC3PLUS:.c=.o)) OBJS_LIBUTIL = $(addprefix $(OBJDIR)/,$(SRCS_LIBUTIL:.c=.o)) OBJS_CLI_APIDEC = $(OBJDIR)/decoder.o OBJS_CLI_APIENC = $(OBJDIR)/encoder.o OBJS_CLI_APPREND = $(OBJDIR)/renderer.o +OBJS_CLI_APPPOSTREND = $(OBJDIR)/isar_post_rend.o DEPS = $(addprefix $(OBJDIR)/,$(SRCS_LIBCOM:.c=.P) $(SRCS_LIBDEBUG:.c=.P) $(SRCS_LIBDEC:.c=.P) \ - $(SRCS_LIBENC:.c=.P) $(SRCS_LIBUTIL:.c=.P) $(SRCS_LIBREND:.c=.P)) + $(SRCS_LIBENC:.c=.P) $(SRCS_LIBUTIL:.c=.P) $(SRCS_LIBREND:.c=.P) $(SRCS_LIBISAR:.c=.P) \ + $(SRCS_LC3PLUS:.c=.P)) ############################################################################### .PHONY: all clean -all: $(CLI_APIENC) $(CLI_APIDEC) $(CLI_APIREND) +all: $(CLI_APIENC) $(CLI_APIDEC) $(CLI_APIREND) $(CLI_APIPOSTREND) $(OBJDIR): $(QUIET)mkdir -p $(OBJDIR) @@ -163,37 +191,60 @@ $(OBJDIR): $(LIB_LIBCOM): $(OBJS_LIBCOM) $(QUIET_AR)$(AR) rcs $@ $^ -$(LIB_LIBDEC): $(OBJS_LIBDEC) $(OBJS_LIBREND) +$(LIB_LIBDEC): $(OBJS_LIBDEC) $(OBJS_LIBREND) $(OBJS_LIBISAR) $(QUIET_AR)$(AR) rcs $@ $^ $(LIB_LIBDEBUG): $(OBJS_LIBDEBUG) $(QUIET_AR)$(AR) rcs $@ $^ +$(LIB_LIBISAR): $(OBJS_LIBISAR) + $(QUIET_AR)$(AR) rcs $@ $^ + $(LIB_LIBENC): $(OBJS_LIBENC) $(QUIET_AR)$(AR) rcs $@ $^ -$(LIB_LIBREND): $(OBJS_LIBREND) +$(LIB_LIBREND): $(OBJS_LIBREND) $(OBJS_LIBISAR) $(QUIET_AR)$(AR) rcs $@ $^ + +$(LIB_LC3PLUS): $(OBJS_LC3PLUS) +ifeq "$(INCLUDE_SPLIT)" "1" + $(QUIET_AR)$(AR) rcs $@ $^ +else + +endif # Dependency on OBJS_LIBCOM added temporarily for unit-test to work $(LIB_LIBUTIL): $(OBJS_LIBUTIL) $(OBJS_LIBCOM) $(QUIET_AR)$(AR) rcs $@ $^ -$(CLI_APIENC): $(OBJS_CLI_APIENC) $(LIB_LIBENC) $(LIB_LIBCOM) $(LIB_LIBUTIL) $(LIB_LIBDEBUG) +$(CLI_APIENC): $(OBJS_CLI_APIENC) $(LIB_LIBENC) $(LIB_LIBCOM) $(LIB_LIBUTIL) $(LIB_LIBDEBUG) $(LIB_LC3PLUS) $(QUIET_LINK)$(CC) $(LDFLAGS) $(OBJS_CLI_APIENC) -L. -livasenc -livascom -livasutil -livasdebug $(LDLIBS) -o $(CLI_APIENC) -$(CLI_APIDEC): $(OBJS_CLI_APIDEC) $(LIB_LIBDEC) $(LIB_LIBCOM) $(LIB_LIBUTIL) $(LIB_LIBDEBUG) +$(CLI_APIDEC): $(OBJS_CLI_APIDEC) $(LIB_LIBDEC) $(LIB_LIBCOM) $(LIB_LIBUTIL) $(LIB_LIBDEBUG) $(LIB_LC3PLUS) $(LIB_LIBISAR) +ifeq "$(INCLUDE_SPLIT)" "1" + $(QUIET_LINK)$(CC) $(LDFLAGS) $(OBJS_CLI_APIDEC) -L. -livasdec -livascom -livasutil -livasdebug -llc3plus $(LDLIBS) -o $(CLI_APIDEC) +else $(QUIET_LINK)$(CC) $(LDFLAGS) $(OBJS_CLI_APIDEC) -L. -livasdec -livascom -livasutil -livasdebug $(LDLIBS) -o $(CLI_APIDEC) +endif -$(CLI_APIREND): $(OBJS_CLI_APPREND) $(LIB_LIBREND) $(LIB_LIBCOM) $(LIB_LIBUTIL) $(LIB_LIBDEBUG) $(LIB_LIBDEC) +$(CLI_APIREND): $(OBJS_CLI_APPREND) $(LIB_LIBREND) $(LIB_LIBCOM) $(LIB_LIBUTIL) $(LIB_LIBDEBUG) $(LIB_LIBDEC) $(LIB_LC3PLUS) $(LIB_LIBISAR) +ifeq "$(INCLUDE_SPLIT)" "1" + $(QUIET_LINK)$(CC) $(LDFLAGS) $(OBJS_CLI_APPREND) -L. -livasrend -lisar -livasdec -livasutil -livasdebug -livascom -llc3plus $(LDLIBS) -o $(CLI_APIREND) +else $(QUIET_LINK)$(CC) $(LDFLAGS) $(OBJS_CLI_APPREND) -L. -livasrend -livasdec -livasutil -livasdebug -livascom $(LDLIBS) -o $(CLI_APIREND) +endif + +$(CLI_APIPOSTREND): $(OBJS_CLI_APPPOSTREND) $(LIB_LIBISAR) $(LIB_LIBCOM) $(LIB_LIBUTIL) $(LIB_LIBDEBUG) $(LIB_LC3PLUS) +ifeq "$(INCLUDE_SPLIT)" "1" + $(QUIET_LINK)$(CC) $(LDFLAGS) $(OBJS_CLI_APPPOSTREND) -L. -lisar -livasutil -livasdebug -livascom -llc3plus $(LDLIBS) -o $(CLI_APIPOSTREND) +endif -libs: $(LIB_LIBENC) $(LIB_LIBDEBUG) $(LIB_LIBCOM) $(LIB_LIBDEC) $(LIB_LIBREND) $(LIB_LIBUTIL) +libs: $(LIB_LIBENC) $(LIB_LIBDEBUG) $(LIB_LIBCOM) $(LIB_LIBDEC) $(LIB_LIBREND) $(LIB_LIBISAR) $(LIB_LC3PLUS) $(LIB_LIBUTIL) clean: $(QUIET)$(RM) $(OBJS_LIBENC) $(OBJS_LIBDEC) $(DEPS) $(QUIET)$(RM) $(DEPS:.P=.d) $(QUIET)test ! -d $(OBJDIR) || rm -rf $(OBJDIR) - $(QUIET)$(RM) $(CLI_APIENC) $(CLI_APIDEC) $(CLI_APIREND) $(LIB_LIBENC) $(LIB_LIBDEBUG) $(LIB_LIBCOM) $(LIB_LIBDEC) $(LIB_LIBUTIL) $(LIB_LIBREND) + $(QUIET)$(RM) $(CLI_APIENC) $(CLI_APIDEC) $(CLI_APIREND) $(CLI_APIPOSTREND) $(LIB_LIBENC) $(LIB_LIBDEBUG) $(LIB_LIBCOM) $(LIB_LIBDEC) $(LIB_LIBUTIL) $(LIB_LIBREND) $(LIB_LIBISAR) $(LIB_LC3PLUS) $(OBJDIR)/%.o : %.c | $(OBJDIR) $(QUIET_CC)$(CC) $(CFLAGS) -c -MD -o $@ $< diff --git a/Workspace_msvc/Workspace_msvc.sln b/Workspace_msvc/Workspace_msvc.sln index a0783ddbf435ddeb6f09907e51620302fac68237..ac2e76b52f0224eefb2fb6c56cbd2a41be66812c 100644 --- a/Workspace_msvc/Workspace_msvc.sln +++ b/Workspace_msvc/Workspace_msvc.sln @@ -20,11 +20,17 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "encoder", "encoder.vcxproj" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "renderer", "renderer.vcxproj", "{12B4C8A5-1E06-4E30-B443-D1F916F52B47}" EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "lib_lc3plus", "lib_lc3plus.vcxproj", "{95030B82-70CD-4C6B-84D4-61096035BEA2}" +EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{51160D4C-55C9-4C16-A792-D94507225746}" ProjectSection(SolutionItems) = preProject ..\.clang-format = ..\.clang-format EndProjectSection EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "lib_isar", "lib_isar.vcxproj", "{869A305E-D99E-4C3A-BDB3-AA57ABCCE619}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "isar_post_rend", "isar_post_rend.vcxproj", "{12374ADC-0E5C-4FDD-B903-71D572413831}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Win32 = Debug|Win32 @@ -93,6 +99,18 @@ Global {95030B82-70CD-4C6B-84D4-61096035BEA2}.Release|Win32.ActiveCfg = Release|Win32 {95030B82-70CD-4C6B-84D4-61096035BEA2}.Release|Win32.Build.0 = Release|Win32 {95030B82-70CD-4C6B-84D4-61096035BEA2}.Release|x64.ActiveCfg = Release|Win32 + {869A305E-D99E-4C3A-BDB3-AA57ABCCE619}.Debug|Win32.ActiveCfg = Debug|Win32 + {869A305E-D99E-4C3A-BDB3-AA57ABCCE619}.Debug|Win32.Build.0 = Debug|Win32 + {869A305E-D99E-4C3A-BDB3-AA57ABCCE619}.Debug|x64.ActiveCfg = Debug|Win32 + {869A305E-D99E-4C3A-BDB3-AA57ABCCE619}.Release|Win32.ActiveCfg = Release|Win32 + {869A305E-D99E-4C3A-BDB3-AA57ABCCE619}.Release|Win32.Build.0 = Release|Win32 + {869A305E-D99E-4C3A-BDB3-AA57ABCCE619}.Release|x64.ActiveCfg = Release|Win32 + {12374ADC-0E5C-4FDD-B903-71D572413831}.Debug|Win32.ActiveCfg = Debug|Win32 + {12374ADC-0E5C-4FDD-B903-71D572413831}.Debug|Win32.Build.0 = Debug|Win32 + {12374ADC-0E5C-4FDD-B903-71D572413831}.Debug|x64.ActiveCfg = Debug|Win32 + {12374ADC-0E5C-4FDD-B903-71D572413831}.Release|Win32.ActiveCfg = Release|Win32 + {12374ADC-0E5C-4FDD-B903-71D572413831}.Release|Win32.Build.0 = Release|Win32 + {12374ADC-0E5C-4FDD-B903-71D572413831}.Release|x64.ActiveCfg = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/Workspace_msvc/decoder.vcxproj b/Workspace_msvc/decoder.vcxproj index ca0d96f44247a24937132bda883936e7f5a3dde1..3ab058c291b49c84e5424a0ba5371318187dfd3a 100644 --- a/Workspace_msvc/decoder.vcxproj +++ b/Workspace_msvc/decoder.vcxproj @@ -68,7 +68,7 @@ Disabled - ..\lib_dec;..\lib_com;..\lib_util;..\lib_debug;%(AdditionalIncludeDirectories) + ..\lib_dec;..\lib_com;..\lib_util;..\lib_debug;..\lib_isar;%(AdditionalIncludeDirectories) _CRT_SECURE_NO_WARNINGS;WIN32;$(Macros);%(PreprocessorDefinitions) EnableFastChecks @@ -112,7 +112,7 @@ Neither false false - ..\lib_dec;..\lib_com;..\lib_util;..\lib_debug;%(AdditionalIncludeDirectories) + ..\lib_dec;..\lib_com;..\lib_util;..\lib_debug;..\lib_isar;%(AdditionalIncludeDirectories) _CRT_SECURE_NO_WARNINGS;$(Macros);%(PreprocessorDefinitions) true @@ -157,6 +157,9 @@ {e822ddaf-0f5f-4cd0-a694-38ae69de74d3} false + + {869a305e-d99e-4c3a-bdb3-aa57abcce619} + {2fa8f384-0775-f3b7-f8c3-85209222fc70} false diff --git a/Workspace_msvc/isar_post_rend.vcxproj b/Workspace_msvc/isar_post_rend.vcxproj new file mode 100644 index 0000000000000000000000000000000000000000..19cb1aff7bc1584679d57f085677019b478a016d --- /dev/null +++ b/Workspace_msvc/isar_post_rend.vcxproj @@ -0,0 +1,179 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + isar_post_rend + {12374ADC-0E5C-4FDD-B903-71D572413831} + isar_post_rend + 10.0.17763.0 + + + + Application + v141 + false + MultiByte + + + Application + v141 + false + MultiByte + + + + + + + + + + + + + + + <_ProjectFileVersion>15.0.27428.2015 + + + ..\ + .\Debug_$(ProjectName)\ + false + false + ISAR_post_rend + + + ..\ + .\Release_$(ProjectName)\ + false + false + ISAR_post_rend + + + + $(IntDir)$(ProjectName).tlb + + + + Disabled + ..\lib_com;..\lib_debug;..\lib_util;..\lib_isar;..\lib_lc3plus;%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;WIN32;$(Macros);%(PreprocessorDefinitions) + + EnableFastChecks + MultiThreadedDebug + false + + + $(IntDir)$(ProjectName).pdb + Level4 + true + OldStyle + Default + %(DisableSpecificWarnings) + false + + + _DEBUG;%(PreprocessorDefinitions) + 0x0c0c + + + + $(OutDir)$(TargetName).exe + true + + true + $(IntDir)$(ProjectName).pdb + Console + false + + MachineX86 + + + + + $(IntDir)$(ProjectName).tlb + + + + MaxSpeed + AnySuitable + false + Neither + false + false + ..\lib_com;..\lib_debug;..\lib_util;..\lib_isar;..\lib_lc3plus;%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;$(Macros);%(PreprocessorDefinitions) + true + + Default + MultiThreaded + true + Precise + false + + + $(IntDir)$(ProjectName).pdb + Level4 + true + + Default + %(DisableSpecificWarnings) + false + + + NDEBUG;%(PreprocessorDefinitions) + 0x0c0c + + + $(OutDir)$(TargetName).exe + true + + false + $(IntDir)$(ProjectName).pdb + Console + false + + MachineX86 + libcmtd.lib + + + + + + + + + + {54509728-928B-44D9-A118-A6F92F08B34F} + false + + + {869a305e-d99e-4c3a-bdb3-aa57abcce619} + + + {2FA8F384-0775-F3B7-F8C3-85209222FC70} + false + + + {39ec200d-7795-4ff8-b214-b24eda5526ae} + false + + + + + + + + + + + \ No newline at end of file diff --git a/Workspace_msvc/lib_com.vcxproj b/Workspace_msvc/lib_com.vcxproj index 9182dd36282cc0652cc43986fb561b0be255385e..4f40c8799a9d989123f553116067c1996e8e7f47 100644 --- a/Workspace_msvc/lib_com.vcxproj +++ b/Workspace_msvc/lib_com.vcxproj @@ -59,8 +59,8 @@ Disabled - ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;.%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_WARNINGS;$(Macros);WIN32;%(PreprocessorDefinitions) + ..\lib_isar;..\lib_lc3plus;..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;.%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;$(Macros);WIN32;%(PreprocessorDefinitions); EnableFastChecks MultiThreadedDebug @@ -94,7 +94,7 @@ Neither false false - ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;.%(AdditionalIncludeDirectories) + ..\lib_isar;..\lib_lc3plus;..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;.%(AdditionalIncludeDirectories) _CRT_SECURE_NO_WARNINGS;$(Macros);%(PreprocessorDefinitions) true @@ -138,7 +138,6 @@ - @@ -200,45 +199,46 @@ - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + - - - - - + + + + + - + + - - - + + + - - - - - - + + + + + + + - @@ -310,21 +310,31 @@ + + + + + + + + + + - + @@ -333,6 +343,7 @@ + diff --git a/Workspace_msvc/lib_com.vcxproj.filters b/Workspace_msvc/lib_com.vcxproj.filters index 93a2b1c00c5b944283f3f7778ccbe44a5f1548ff..eaacf1ba7ad247881e7aca1e8a8b2b1064ebc275 100644 --- a/Workspace_msvc/lib_com.vcxproj.filters +++ b/Workspace_msvc/lib_com.vcxproj.filters @@ -1,88 +1,12 @@ - - common_ivas_c - - - common_ivas_c - - - common_ivas_c - - - common_ivas_c - - - common_ivas_c - - - common_ivas_c - - - common_ivas_c - - - common_ivas_c - - - common_ivas_c - - - common_ivas_c - - - common_ivas_c - - - common_ivas_c - - - common_ivas_c - - - common_ivas_c - - - common_ivas_c - - - common_ivas_c - - - common_ivas_c - - - common_ivas_c - - - common_ivas_c - - - common_ivas_c - - - common_ivas_c - - - common_ivas_c - - - common_ivas_c - - - common_ivas_c - - - common_ivas_c - common_all_c common_all_c - common_all_c @@ -161,7 +85,6 @@ common_all_c - common_evs_c @@ -216,7 +139,6 @@ common_all_c - common_all_c @@ -361,65 +283,263 @@ common_all_c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_ivas_c + + + common_ivas_c + + + common_ivas_c + + + common_ivas_c + + + common_ivas_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_ivas_c + + + common_ivas_c + + + common_ivas_c + + + common_ivas_c + + + common_ivas_c + + + common_ivas_c + + + common_ivas_c + + + common_ivas_c + + + common_ivas_c + + + common_ivas_c + + + common_ivas_c + + + common_ivas_c + + + common_ivas_c + + + common_ivas_c + + + common_ivas_c + + + common_ivas_c + + + common_ivas_c + + + common_ivas_c + + + common_ivas_c + + + common_ivas_c + + + common_ivas_c + + + common_ivas_c + + + common_ivas_c + + + common_ivas_c + + + common_ivas_c + + + common_ivas_c + + + common_ivas_c + + + common_ivas_c + + + common_ivas_c + + + common_ivas_c + + + @@ -464,9 +584,6 @@ common_h - - common_h - common_h @@ -493,7 +610,6 @@ common_h - common_h @@ -501,6 +617,23 @@ common_h + + common_h + + + common_all_c + + + + + + + + + + + + diff --git a/Workspace_msvc/lib_dec.vcxproj b/Workspace_msvc/lib_dec.vcxproj index d6e4a7c672d91bb76b7e3e30fdca199c56285df7..5c19bc811cc295a937124b8537dd239cb82d5758 100644 --- a/Workspace_msvc/lib_dec.vcxproj +++ b/Workspace_msvc/lib_dec.vcxproj @@ -68,7 +68,7 @@ Disabled - ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;.%(AdditionalIncludeDirectories) + ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;..\lib_isar;..\lib_rend;..\lib_lc3plus;.%(AdditionalIncludeDirectories) _CRT_SECURE_NO_WARNINGS;$(Macros);WIN32;%(PreprocessorDefinitions) EnableFastChecks @@ -108,7 +108,7 @@ Neither false false - ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;.%(AdditionalIncludeDirectories) + ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;..\lib_isar;..\lib_rend;..\lib_lc3plus;.%(AdditionalIncludeDirectories) _CRT_SECURE_NO_WARNINGS;$(Macros);WIN32;%(PreprocessorDefinitions) true @@ -136,297 +136,184 @@ - false - false - - - - - - - false - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + - - - - - + + + + - - - - - - - + + + + + + - - - - - - - - - - + + + + + + + - - - - - - - - + + + + + + + - - - - + + + + - - + - - + - - - + + + - + - - - - - - + + + + - - - - - - + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Workspace_msvc/lib_dec.vcxproj.filters b/Workspace_msvc/lib_dec.vcxproj.filters index b9dbd7fd5a6304a0d47586693a0d781946e88a35..8a4fc4605a1170b9da66c90a81b8bdd4134573c7 100644 --- a/Workspace_msvc/lib_dec.vcxproj.filters +++ b/Workspace_msvc/lib_dec.vcxproj.filters @@ -1,305 +1,575 @@  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + decoder_evs_c + + + decoder_evs_c + + + decoder_evs_c + + + decoder_evs_c + + + decoder_evs_c + + + decoder_evs_c + + + decoder_evs_c + + + decoder_evs_c + + + decoder_evs_c + + + decoder_evs_c + + + decoder_evs_c + + + decoder_evs_c + + + decoder_evs_c + + + decoder_evs_c + + + decoder_evs_c + + + decoder_evs_c + + + decoder_evs_c + + + decoder_evs_c + + + decoder_evs_c + + + decoder_evs_c + + + decoder_evs_c + + + decoder_evs_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + - - - - - - - - - - - - + + decoder_h + + + decoder_h + + + decoder_h + + + decoder_h + + + decoder_h + + + decoder_h + + + decoder_h + + + decoder_h + + + decoder_h + + + decoder_h + + + decoder_h + + + decoder_h + + + + + {6d564218-e0e5-4a7b-80b3-6b10661ad36c} + + + {33d78f8d-2d43-40f5-a9b1-711097bd6746} + + + {044baa49-b157-45ed-8bec-29b6d7172e82} + + + {adc81a29-2517-49f0-819f-e8cea3d49ae3} + \ No newline at end of file diff --git a/Workspace_msvc/lib_enc.vcxproj b/Workspace_msvc/lib_enc.vcxproj index 384fb8bb1855a74c55dcab5b3087c521a642062f..eb9d1330e3142d06c6744a5dc771fe4e41b56d7a 100644 --- a/Workspace_msvc/lib_enc.vcxproj +++ b/Workspace_msvc/lib_enc.vcxproj @@ -68,7 +68,7 @@ Disabled - ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;.%(AdditionalIncludeDirectories) + ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;..\lib_isar;..\lib_rend;..\lib_lc3plus;.%(AdditionalIncludeDirectories) _CRT_SECURE_NO_WARNINGS;$(Macros);WIN32;%(PreprocessorDefinitions) EnableFastChecks @@ -111,7 +111,7 @@ Neither false false - ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;.%(AdditionalIncludeDirectories) + ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;..\lib_isar;..\lib_rend;..\lib_lc3plus;.%(AdditionalIncludeDirectories) _CRT_SECURE_NO_WARNINGS;$(Macros);%(PreprocessorDefinitions) true @@ -215,149 +215,71 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - @@ -395,85 +317,29 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - - - - - - - - - - - - - - - - - - diff --git a/Workspace_msvc/lib_enc.vcxproj.filters b/Workspace_msvc/lib_enc.vcxproj.filters index 2476cdb6cf5fa921fe54ffb28616676ae9849a81..8990971637ef90b8f3a11fbd672278a29d3f89da 100644 --- a/Workspace_msvc/lib_enc.vcxproj.filters +++ b/Workspace_msvc/lib_enc.vcxproj.filters @@ -1,1052 +1,641 @@ - + - - enc_ivas_c - - - enc_ivas_c - - - enc_ivas_c - - - enc_ivas_c + + + encoder_evs_c - - enc_ivas_c + + encoder_evs_c - - enc_ivas_c + + encoder_evs_c - - enc_evs_c + + encoder_evs_c - - enc_evs_c + + encoder_evs_c - - enc_evs_c + + encoder_evs_c - - enc_evs_c + + encoder_evs_c - - enc_evs_c + + encoder_evs_c - - enc_evs_c + + encoder_evs_c - - enc_evs_c + + encoder_evs_c - - enc_evs_c + + encoder_evs_c - - enc_evs_c + + encoder_evs_c - - enc_evs_c + + encoder_evs_c - - enc_evs_c + + encoder_evs_c - - enc_evs_c + + encoder_evs_c - - enc_evs_c + + encoder_evs_c - - enc_evs_c + + encoder_evs_c - - enc_evs_c + + encoder_evs_c - - enc_evs_c + + encoder_evs_c - - enc_evs_c + + encoder_evs_c - - enc_evs_c + + encoder_evs_c - - enc_evs_c + + encoder_evs_c - - enc_evs_c + + encoder_evs_c - - enc_evs_c + + encoder_evs_c - - enc_evs_c + + encoder_evs_c - - enc_evs_c + + encoder_evs_c - - enc_evs_c + + encoder_evs_c - - enc_evs_c + + encoder_evs_c - - enc_evs_c + + encoder_evs_c - - enc_evs_c + + encoder_evs_c - - enc_evs_c + + encoder_evs_c - - enc_evs_c + + encoder_evs_c - - enc_evs_c + + encoder_evs_c - - enc_evs_c + + encoder_evs_c - - enc_evs_c + + encoder_evs_c - - enc_all_c + + encoder_ivas_c - - enc_all_c + + encoder_all_c - - enc_all_c + + encoder_all_c - - enc_all_c + + encoder_all_c - - enc_all_c + + encoder_all_c - - enc_all_c + + encoder_all_c - - enc_all_c + + encoder_all_c - - enc_all_c + + encoder_all_c - - enc_all_c + + encoder_all_c - - enc_all_c + + encoder_all_c - - enc_all_c + + encoder_all_c - - enc_all_c + + encoder_all_c - - enc_all_c + + encoder_all_c - - enc_all_c + + encoder_all_c - - enc_all_c + + encoder_all_c - enc_all_c + encoder_all_c - - enc_all_c + + encoder_all_c - - enc_all_c + + encoder_all_c - - enc_all_c + + encoder_all_c - - enc_all_c + + encoder_all_c - - enc_all_c + + encoder_all_c - - enc_all_c + + encoder_all_c - - enc_all_c + + encoder_all_c - - enc_all_c + + encoder_all_c - - enc_all_c + + encoder_all_c - - enc_all_c + + encoder_all_c - - enc_all_c + + encoder_all_c - - enc_all_c + + encoder_all_c - - enc_all_c + + encoder_all_c - - enc_all_c + + encoder_all_c - - enc_all_c + + encoder_all_c - - enc_all_c + + encoder_all_c - - enc_all_c + + encoder_all_c - - enc_all_c + + encoder_all_c - - enc_all_c + + encoder_all_c - - enc_all_c + + encoder_all_c - - enc_all_c + + encoder_all_c - - enc_all_c + + encoder_all_c - - enc_all_c + + encoder_all_c - - enc_all_c + + encoder_all_c - - enc_all_c + + encoder_all_c - - enc_all_c + + encoder_all_c - - enc_all_c + + encoder_all_c - - enc_all_c + + encoder_all_c - - enc_all_c + + encoder_all_c - - enc_all_c + + encoder_all_c - - enc_all_c + + encoder_all_c - - enc_all_c + + encoder_all_c - - enc_all_c + + encoder_all_c - - enc_all_c + + encoder_all_c - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c + encoder_all_c - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_evs_c - - - enc_evs_c - - - enc_ivas_c - - - enc_ivas_c - - - enc_ivas_c - - - enc_ivas_c - - - enc_ivas_c - - - enc_ivas_c - - - enc_ivas_c - - - enc_ivas_c - - - enc_all_c - - - enc_evs_c - - - enc_ivas_c - - - enc_ivas_c - - - enc_ivas_c - - - enc_ivas_c - - - enc_ivas_c - - - enc_ivas_c - - - enc_ivas_c - - - enc_ivas_c - - - enc_ivas_c - - - enc_ivas_c - - - enc_ivas_c - - - enc_ivas_c - - - enc_ivas_c - - - enc_ivas_c - - - enc_ivas_c - - - enc_ivas_c - - - enc_ivas_c - - - enc_ivas_c - - - enc_ivas_c - - - enc_ivas_c - - - enc_ivas_c - - - enc_ivas_c - - - enc_ivas_c - - - enc_ivas_c - - - enc_ivas_c - - - enc_ivas_c - - - enc_ivas_c - - - enc_ivas_c - - - enc_ivas_c - - - - enc_ivas_c - - - enc_ivas_c - - - enc_ivas_c - - - enc_ivas_c - - - enc_ivas_c - - - enc_ivas_c - - - enc_ivas_c - - - enc_ivas_c - - - enc_ivas_c - - - enc_ivas_c - - - enc_ivas_c - - - enc_ivas_c - - - enc_ivas_c - - - enc_ivas_c - - - enc_all_c + + encoder_all_c - - enc_evs_c + + encoder_all_c - - enc_evs_c + + encoder_all_c - - enc_evs_c + + encoder_all_c - - enc_all_c + + encoder_all_c - - enc_evs_c + + encoder_all_c - - enc_evs_c + + encoder_all_c - - enc_evs_c + + encoder_all_c - - enc_evs_c + + encoder_all_c - - enc_evs_c + + encoder_all_c - - enc_evs_c + + encoder_all_c - - enc_evs_c + + encoder_all_c - - enc_evs_c + + encoder_all_c - - enc_evs_c + + encoder_all_c - - enc_evs_c + + encoder_all_c - - enc_evs_c + + encoder_all_c - - enc_evs_c + + encoder_all_c - - enc_evs_c + + encoder_all_c - - enc_evs_c + + encoder_all_c - - enc_evs_c + + encoder_all_c - - enc_evs_c + + encoder_all_c - - enc_evs_c + + encoder_all_c - - enc_evs_c + + encoder_all_c - - enc_evs_c + + encoder_all_c - - enc_evs_c + + encoder_all_c - - enc_evs_c + + encoder_all_c - - enc_evs_c + + encoder_all_c - - enc_evs_c + + encoder_all_c - - enc_evs_c + + encoder_all_c - - enc_evs_c + + encoder_all_c - - enc_evs_c + + encoder_all_c - - enc_evs_c + + encoder_all_c - - enc_evs_c + + encoder_all_c - - enc_evs_c + + encoder_all_c - - enc_evs_c + + encoder_all_c - - enc_evs_c + + encoder_all_c - - enc_all_c + + encoder_all_c - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c + encoder_all_c - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c + encoder_all_c - - enc_all_c - - - enc_all_c + + encoder_all_c - - enc_all_c + + encoder_all_c - - enc_all_c + + encoder_all_c - - enc_all_c + + encoder_all_c - - enc_all_c + + encoder_all_c - - enc_all_c + + encoder_all_c - - enc_all_c + + encoder_all_c - - enc_all_c + + encoder_all_c - - enc_all_c + + encoder_all_c - - enc_all_c + + encoder_all_c - - enc_all_c + + encoder_all_c - - enc_all_c + + encoder_all_c - - enc_all_c + + encoder_all_c - - enc_all_c + + encoder_all_c - - enc_all_c + + encoder_all_c - - enc_all_c + + encoder_all_c - - enc_all_c + + encoder_all_c - - enc_all_c + + encoder_all_c - - enc_all_c + + encoder_all_c - - enc_all_c + + encoder_all_c - - enc_all_c + + encoder_ivas_c - - enc_all_c + + encoder_ivas_c - - enc_all_c + + encoder_ivas_c - - enc_all_c + + encoder_ivas_c - - enc_all_c + + encoder_ivas_c - - enc_all_c + + encoder_ivas_c - - enc_all_c + + encoder_ivas_c - - enc_all_c + + encoder_ivas_c - - enc_all_c + + encoder_ivas_c - - enc_all_c + + encoder_ivas_c - - enc_all_c + + encoder_ivas_c - - enc_all_c + + encoder_ivas_c - - enc_all_c + + encoder_ivas_c - - enc_all_c + + encoder_ivas_c - - enc_all_c + + encoder_ivas_c - - enc_all_c + + encoder_ivas_c - - enc_all_c + + encoder_ivas_c - - enc_all_c + + encoder_ivas_c - - enc_all_c + + encoder_ivas_c - - enc_all_c + + encoder_ivas_c - - enc_all_c + + encoder_ivas_c - - enc_all_c + + encoder_ivas_c - - enc_all_c + + encoder_ivas_c - - enc_all_c + + encoder_ivas_c - - enc_all_c + + encoder_ivas_c - - enc_all_c + + encoder_ivas_c - - enc_all_c + + encoder_ivas_c - - enc_all_c + + encoder_ivas_c - - enc_all_c + + encoder_ivas_c - - enc_all_c + + encoder_ivas_c - - enc_all_c + + encoder_ivas_c - - enc_all_c + + encoder_ivas_c - - enc_all_c + + encoder_ivas_c - - enc_all_c + + encoder_ivas_c - - enc_all_c + + encoder_ivas_c - - enc_all_c + + encoder_ivas_c - - enc_all_c + + encoder_ivas_c - - enc_all_c + + encoder_ivas_c - - enc_all_c + + encoder_ivas_c - - enc_all_c + + encoder_ivas_c - - enc_all_c + + encoder_ivas_c - - enc_all_c + + encoder_ivas_c - - enc_all_c + + encoder_ivas_c - - enc_all_c + + encoder_ivas_c - - enc_all_c + + encoder_ivas_c - - enc_all_c + + encoder_ivas_c - - enc_all_c + + encoder_ivas_c - - enc_all_c + + encoder_ivas_c - - enc_all_c + + encoder_ivas_c - - enc_all_c + + encoder_ivas_c - - enc_all_c + + encoder_ivas_c - - enc_all_c + + encoder_ivas_c - - enc_all_c + + encoder_ivas_c - - enc_evs_c + + encoder_ivas_c - - enc_evs_c + + encoder_ivas_c + - enc_h + encoder_h + + + encoder_h - enc_h + encoder_h - enc_h + encoder_h - enc_h + encoder_h - - enc_h - - - enc_h + encoder_all_c - - {b7ee0526-8b79-4554-a3ec-04e51d38475f} + + {34137975-e4fd-40f0-938f-02fd46da5e22} - - {dabed049-70a2-48f2-9da6-3b81a3664033} + + {c24a3dcd-cde3-411b-aecf-747c29d87668} - - {5717f1cb-c593-400b-b23a-45c422fd95c8} + + {e78e5d72-8d6d-4b00-a6e0-64a62c9cf8f2} - - {6cccabbe-510f-43d3-90e1-8ed5ea3837d7} + + {597ebb71-22ba-41e8-b4bf-e8691bda2e5b} \ No newline at end of file diff --git a/Workspace_msvc/lib_isar.vcxproj b/Workspace_msvc/lib_isar.vcxproj new file mode 100644 index 0000000000000000000000000000000000000000..23d80373082b8ba025da607bbc610c069d45ca54 --- /dev/null +++ b/Workspace_msvc/lib_isar.vcxproj @@ -0,0 +1,184 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + lib_isar + {869A305E-D99E-4C3A-BDB3-AA57ABCCE619} + isar + 10.0.17763.0 + + + + StaticLibrary + v141 + false + MultiByte + + + StaticLibrary + v141 + false + MultiByte + + + + + + + + + + + + + + + <_ProjectFileVersion>15.0.27428.2015 + + + .\Debug_$(ProjectName)\ + .\Debug_$(ProjectName)\ + libisar + + + .\Release_$(ProjectName)\ + .\Release_$(ProjectName)\ + libisar + + + + + + + Disabled + ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;..\lib_isar;..\lib_lc3plus;.%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;$(Macros);WIN32;%(PreprocessorDefinitions); + + EnableFastChecks + MultiThreadedDebug + + + $(IntDir)$(ProjectName).pdb + Level4 + true + OldStyle + Default + %(DisableSpecificWarnings) + + + _DEBUG;%(PreprocessorDefinitions) + 0x0c0c + + + WS2_32.lib; %(AdditionalDependencies) + $(OutDir)$(TargetName).lib + true + + + + + + + + MaxSpeed + AnySuitable + false + Neither + false + false + ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;..\lib_isar;..\lib_lc3plus;.%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;$(Macros);WIN32;%(PreprocessorDefinitions) + true + + Default + MultiThreaded + true + + + $(IntDir)$(ProjectName).pdb + Level4 + true + + Default + %(DisableSpecificWarnings) + + + NDEBUG;%(PreprocessorDefinitions) + 0x0c0c + + + WS2_32.lib; %(AdditionalDependencies) + $(OutDir)$(TargetName).lib + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {39ec200d-7795-4ff8-b214-b24eda5526ae} + false + + + {54509728-928b-44d9-a118-a6f92f08b34f} + false + + + {95030B82-70CD-4C6B-84D4-61096035BEA2} + false + + + + + + + + + + + \ No newline at end of file diff --git a/Workspace_msvc/lib_lc3plus.vcxproj b/Workspace_msvc/lib_lc3plus.vcxproj new file mode 100644 index 0000000000000000000000000000000000000000..22b5cddd3c55c39f43af6dfa39ec652305880ff2 --- /dev/null +++ b/Workspace_msvc/lib_lc3plus.vcxproj @@ -0,0 +1,195 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + {95030B82-70CD-4C6B-84D4-61096035BEA2} + Win32Proj + LC3_FL + 10.0.17763.0 + + + + StaticLibrary + true + v141 + Unicode + + + StaticLibrary + false + v141 + true + Unicode + + + + + + + + + + + + + + + liblc3plus + .\Debug_$(ProjectName)\ + .\Debug_$(ProjectName)\ + + + LC3plus + $(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\Obj\ + + + + + + Level3 + ..\lib_com;..\lib_debug;%(AdditionalIncludeDirectories) + Disabled + MultiThreadedDebug + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + 4305;4244;4996 + OldStyle + false + false + + + Console + true + + + + + Level3 + + + ..\lib_com;..\lib_debug;%(AdditionalIncludeDirectories) + MaxSpeed + MultiThreaded + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + 4244;4305;4996 + false + + + Console + true + true + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Workspace_msvc/lib_rend.vcxproj b/Workspace_msvc/lib_rend.vcxproj index fa11b23beb756bdfe1bbad4a3cf989ea5ed750bb..17b82663162d0b2d58e628269ecbaef86ab3c4cc 100644 --- a/Workspace_msvc/lib_rend.vcxproj +++ b/Workspace_msvc/lib_rend.vcxproj @@ -68,7 +68,7 @@ Disabled - ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;.%(AdditionalIncludeDirectories) + ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_isar;..\lib_rend;..\lib_lc3plus;.%(AdditionalIncludeDirectories) _CRT_SECURE_NO_WARNINGS;$(Macros);WIN32;%(PreprocessorDefinitions) EnableFastChecks @@ -108,7 +108,7 @@ Neither false false - ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;.%(AdditionalIncludeDirectories) + ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_isar;..\lib_rend;..\lib_lc3plus;.%(AdditionalIncludeDirectories) _CRT_SECURE_NO_WARNINGS;$(Macros);WIN32;%(PreprocessorDefinitions) true @@ -136,50 +136,49 @@ - - - - - - + + + + + + - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + - + @@ -196,6 +195,10 @@ {54509728-928b-44d9-a118-a6f92f08b34f} false + + {95030B82-70CD-4C6B-84D4-61096035BEA2} + false + @@ -205,4 +208,4 @@ - \ No newline at end of file + diff --git a/Workspace_msvc/lib_rend.vcxproj.filters b/Workspace_msvc/lib_rend.vcxproj.filters index 01f3dfb74b19aaa5bbfbce01fa14d68eaf0e5af8..5c4a4901111136b5ce1c1406701ffe10e156b86b 100644 --- a/Workspace_msvc/lib_rend.vcxproj.filters +++ b/Workspace_msvc/lib_rend.vcxproj.filters @@ -2,132 +2,129 @@ - + rend_c - + rend_c - + rend_c - + rend_c - + rend_c - + rend_c - + rend_c - + rend_c - + rend_c - + rend_c - + rend_c - + rend_c - + rend_c - + rend_c - + rend_c - + rend_c - + rend_c - + rend_c - + rend_c - + rend_c - + rend_c - + rend_c - + rend_c - + rend_c - + rend_c - + rend_c - + rend_c - + rend_c - + rend_c - + rend_c - + rend_c - + rend_c - + rend_c - + rend_c - + rend_c - + rend_c - + rend_c - + rend_c - + rend_c - + rend_c - - rend_h - rend_h @@ -143,7 +140,7 @@ rend_h - + rend_h diff --git a/Workspace_msvc/lib_util.vcxproj b/Workspace_msvc/lib_util.vcxproj index 86730b859969d9aae777bb89e42da970c1ce1f02..ceb342b2157dff283b4c00bde8d5070b8ee0a340 100644 --- a/Workspace_msvc/lib_util.vcxproj +++ b/Workspace_msvc/lib_util.vcxproj @@ -55,7 +55,7 @@ Disabled - ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;..\lib_util;.%(AdditionalIncludeDirectories) + ..\lib_isar;..\lib_lc3plus;..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;..\lib_util;.%(AdditionalIncludeDirectories) _CRT_SECURE_NO_WARNINGS;$(Macros);ZLIB_WINAPI;%(PreprocessorDefinitions) false @@ -78,7 +78,7 @@ AnySuitable false false - ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;..\lib_util;.%(AdditionalIncludeDirectories) + ..\lib_isar;..\lib_lc3plus;..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;..\lib_util;.%(AdditionalIncludeDirectories) _CRT_SECURE_NO_WARNINGS;$(Macros);ZLIB_WINAPI;%(PreprocessorDefinitions) true @@ -120,6 +120,8 @@ + + @@ -145,6 +147,8 @@ + + diff --git a/Workspace_msvc/renderer.vcxproj b/Workspace_msvc/renderer.vcxproj index 1f95040e1f2189e4fed248f58eddd0e27e8da7a0..1bc5b5568ccdf19549678c5ebd9f777af41b8fa0 100644 --- a/Workspace_msvc/renderer.vcxproj +++ b/Workspace_msvc/renderer.vcxproj @@ -65,7 +65,7 @@ Disabled - ..\lib_com;..\lib_debug;..\lib_util;..\lib_rend;..\lib_dec;..\lib_enc;%(AdditionalIncludeDirectories) + ..\lib_com;..\lib_debug;..\lib_util;..\lib_isar;..\lib_rend;..\lib_lc3plus;%(AdditionalIncludeDirectories) _CRT_SECURE_NO_WARNINGS;WIN32;$(Macros);%(PreprocessorDefinitions) EnableFastChecks @@ -109,7 +109,7 @@ Neither false false - ..\lib_com;..\lib_debug;..\lib_util;..\lib_rend;.%(AdditionalIncludeDirectories) + ..\lib_com;..\lib_debug;..\lib_util;..\lib_isar;..\lib_rend;..\lib_lc3plus;.%(AdditionalIncludeDirectories) _CRT_SECURE_NO_WARNINGS;$(Macros);%(PreprocessorDefinitions) true @@ -156,6 +156,9 @@ {E822DDAF-0F5F-4CD0-A694-38AE69DE74D3} false + + {869a305e-d99e-4c3a-bdb3-aa57abcce619} + {2FA8F384-0775-F3B7-F8C3-85209222FC70} false diff --git a/apps/decoder.c b/apps/decoder.c index 05872256985800658c623b48072312c7e015b132..2bff1fab63cf31dc613e8088f4dd11bb527e8a6f 100644 --- a/apps/decoder.c +++ b/apps/decoder.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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,6 +43,9 @@ #include "masa_file_writer.h" #include "render_config_reader.h" #include "rotation_file_reader.h" +#ifdef SPLIT_REND_WITH_HEAD_ROT +#include "split_render_file_read_write.h" +#endif #include "vector3_pair_file_reader.h" #include "wmc_auto.h" #include "options.h" @@ -114,6 +117,9 @@ typedef struct Word16 non_diegetic_pan_gain_fx; /* Q15 */ bool renderConfigEnabled; char *renderConfigFilename; +#ifdef SPLIT_REND_WITH_HEAD_ROT + char *outputMdFilename; +#endif IVAS_DEC_COMPLEXITY_LEVEL complexityLevel; bool tsmEnabled; IVAS_RENDER_FRAMESIZE renderFramesize; @@ -130,7 +136,11 @@ typedef struct static bool parseCmdlIVAS_dec( int16_t argc, char **argv, DecArguments *arg ); static void usage_dec( void ); +#ifdef SPLIT_REND_WITH_HEAD_ROT +static ivas_error decodeG192( DecArguments arg, BS_READER_HANDLE hBsReader, RotFileReader *headRotReader, RotFileReader *externalOrientationFileReader, RotFileReader *refRotReader, Vector3PairFileReader *referenceVectorReader, ISAR_SPLIT_REND_BITS_DATA *splitRendBits, IVAS_DEC_HANDLE hIvasDec, int16_t *pcmBuf ); +#else static ivas_error decodeG192( DecArguments arg, BS_READER_HANDLE hBsReader, RotFileReader *headRotReader, RotFileReader *externalOrientationFileReader, RotFileReader *refRotReader, Vector3PairFileReader *referenceVectorReader, IVAS_DEC_HANDLE hIvasDec, int16_t *pcmBuf ); +#endif static ivas_error decodeVoIP( DecArguments arg, BS_READER_HANDLE hBsReader, RotFileReader *headRotReader, RotFileReader *externalOrientationFileReader, RotFileReader *refRotReader, Vector3PairFileReader *referenceVectorReader, IVAS_DEC_HANDLE hIvasDec ); @@ -147,6 +157,10 @@ int main( bool mainFailed = true; /* Assume main failed until cleanup is reached without errors */ DecArguments arg; ivas_error error = IVAS_ERR_UNKNOWN; +#ifdef SPLIT_REND_WITH_HEAD_ROT + ISAR_SPLIT_REND_BITS_DATA splitRendBits; + uint8_t splitRendBitsBuf[ISAR_MAX_SPLIT_REND_BITS_BUFFER_SIZE_IN_BYTES]; +#endif /* Any handles that require cleanup must be declared here and initialized to NULL */ IVAS_DEC_HANDLE hIvasDec = NULL; @@ -166,6 +180,10 @@ int main( reset_mem( USE_BYTES ); #endif +#ifdef SPLIT_REND_WITH_HEAD_ROT + splitRendBits.bits_buf = splitRendBitsBuf; +#endif + /*------------------------------------------------------------------------------------------* * Parse command-line arguments *------------------------------------------------------------------------------------------*/ @@ -212,6 +230,18 @@ int main( } } +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( arg.outputConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) + { + fprintf( stdout, "Output metadata file: %s\n", arg.outputWavFilename ); + } + else if ( arg.outputConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) + { + fprintf( stdout, "Output synthesis file: %s\n", arg.outputWavFilename ); + fprintf( stdout, "Output metadata file: %s\n", arg.outputMdFilename ); + } + else +#endif { fprintf( stdout, "Output synthesis file: %s\n", arg.outputWavFilename ); } @@ -245,7 +275,11 @@ int main( if ( arg.enableHeadRotation ) { /* sanity check */ - if ( arg.outputConfig != IVAS_AUDIO_CONFIG_BINAURAL && arg.outputConfig != IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR && arg.outputConfig != IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) + if ( arg.outputConfig != IVAS_AUDIO_CONFIG_BINAURAL && arg.outputConfig != IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR && arg.outputConfig != IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB +#ifdef SPLIT_REND_WITH_HEAD_ROT + && arg.outputConfig != IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED && arg.outputConfig != IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM +#endif + ) { fprintf( stderr, "\nError: Head-rotation file file cannot be used in this output configuration.\n\n" ); goto cleanup; @@ -345,7 +379,12 @@ int main( if ( arg.renderConfigEnabled ) { /* sanity check */ - if ( arg.outputConfig != IVAS_AUDIO_CONFIG_BINAURAL && arg.outputConfig != IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR && arg.outputConfig != IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) + if ( arg.outputConfig != IVAS_AUDIO_CONFIG_BINAURAL && arg.outputConfig != IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR && arg.outputConfig != IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB +#ifdef SPLIT_REND_WITH_HEAD_ROT + && arg.outputConfig != IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED && arg.outputConfig != IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM && + arg.Opt_non_diegetic_pan == 0 +#endif + ) { fprintf( stderr, "\nError: Renderer configuration file cannot be used in this output configuration.\n\n" ); goto cleanup; @@ -381,10 +420,29 @@ int main( fprintf( stderr, "\nChanged render framesize, only 20ms are allowed for decoding to EXT!\n" ); } +#ifdef SPLIT_REND_WITH_HEAD_ROT /*------------------------------------------------------------------------------------------* * Configure Split rendering *------------------------------------------------------------------------------------------*/ + asked_frame_size = arg.renderFramesize; + if ( arg.outputConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || arg.outputConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) + { + if ( ( error = IVAS_DEC_EnableSplitRendering( hIvasDec ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nConfigure failed: %s\n\n", IVAS_DEC_GetErrorMessage( error ) ); + goto cleanup; + } + + if ( ( error = IVAS_DEC_GetRenderFramesize( hIvasDec, &arg.renderFramesize ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nConfigure failed: %s\n\n", IVAS_DEC_GetErrorMessage( error ) ); + goto cleanup; + } + + arg.enableHeadRotation = true; + } +#endif /*------------------------------------------------------------------------------------------* * Configure VoIP mode @@ -410,11 +468,21 @@ int main( IVAS_RENDER_CONFIG_DATA renderConfig; /* sanity check */ +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( arg.outputConfig != IVAS_AUDIO_CONFIG_BINAURAL && arg.outputConfig != IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR && arg.outputConfig != IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB && + arg.outputConfig != IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED && arg.outputConfig != IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM && + arg.Opt_non_diegetic_pan == 0 ) + { + fprintf( stderr, "\nExternal Renderer Config is supported only when binaural output configurations is used as output OR when Split rendering mode is enabled. Exiting. \n" ); + goto cleanup; + } +#else if ( arg.outputConfig != IVAS_AUDIO_CONFIG_BINAURAL && arg.outputConfig != IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR && arg.outputConfig != IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) { fprintf( stderr, "\nExternal Renderer Config is supported only for binaural output configurations. Exiting. \n\n" ); goto cleanup; } +#endif if ( ( error = IVAS_DEC_GetRenderConfig( hIvasDec, &renderConfig ) ) != IVAS_ERR_OK ) { @@ -422,7 +490,6 @@ 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 ); @@ -441,6 +508,33 @@ int main( renderConfig.directivity_fx[i * 3 + 2] = (Word16) ( renderConfig.directivity[i * 3 + 2] * ( ( 1u << 15 ) - 1 ) ); } +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( ( arg.outputConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || + arg.outputConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ) + { + if ( asked_frame_size != IVAS_RENDER_FRAMESIZE_20MS && + ( renderConfig.split_rend_config.poseCorrectionMode == ISAR_SPLIT_REND_POSE_CORRECTION_MODE_NONE || + renderConfig.split_rend_config.dof == 0 ) ) + { + arg.renderFramesize = asked_frame_size; + } + else + { + arg.renderFramesize = IVAS_RENDER_FRAMESIZE_20MS; + } + + if ( ( error = IVAS_DEC_SetRenderFramesize( hIvasDec, arg.renderFramesize ) ) != IVAS_ERR_OK ) + { + return error; + } + + if ( arg.renderFramesize != asked_frame_size ) + { + fprintf( stderr, "\nChanged render framesize, only 20ms are allowed for non-0dof split rendering!\n" ); + } + } +#endif + if ( arg.outputConfig == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) { if ( ( error = RenderConfigReader_getAcousticEnvironment( renderConfigReader, arg.acousticEnvironmentId, &renderConfig.roomAcoustics ) ) == IVAS_ERR_OK ) @@ -458,6 +552,13 @@ int main( } renderConfig.roomAcoustics.override = true; } +#ifdef SPLIT_REND_WITH_HEAD_ROT +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + /* ISAR frame size is set from command line, not renderer config file. + * This will be ignored if output format is not split rendering. */ + renderConfig.split_rend_config.isar_frame_size_ms = (int16_t) arg.renderFramesize /* given in number of 5ms subframes */ * 5; +#endif +#endif if ( ( error = IVAS_DEC_FeedRenderConfig( hIvasDec, renderConfig ) ) != IVAS_ERR_OK ) { @@ -568,13 +669,18 @@ int main( /*-----------------------------------------------------------------* * Decoding *-----------------------------------------------------------------*/ + if ( arg.voipMode ) { error = decodeVoIP( arg, hBsReader, headRotReader, externalOrientationFileReader, refRotReader, referenceVectorReader, hIvasDec ); } else { +#ifdef SPLIT_REND_WITH_HEAD_ROT + error = decodeG192( arg, hBsReader, headRotReader, externalOrientationFileReader, refRotReader, referenceVectorReader, &splitRendBits, hIvasDec, pcmBuf ); +#else error = decodeG192( arg, hBsReader, headRotReader, externalOrientationFileReader, refRotReader, referenceVectorReader, hIvasDec, pcmBuf ); +#endif } if ( error == IVAS_ERR_OK || error == IVAS_ERR_END_OF_FILE ) @@ -708,6 +814,16 @@ static IVAS_AUDIO_CONFIG cmdline2config( { output_config = IVAS_AUDIO_CONFIG_BINAURAL; } +#ifdef SPLIT_REND_WITH_HEAD_ROT + else if ( strcmp( argv_to_upper, "BINAURAL_SPLIT_CODED" ) == 0 ) + { + output_config = IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED; + } + else if ( strcmp( argv_to_upper, "BINAURAL_SPLIT_PCM" ) == 0 ) + { + output_config = IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM; + } +#endif else if ( strcmp( argv_to_upper, "BINAURAL_ROOM_IR" ) == 0 ) { output_config = IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR; @@ -775,6 +891,9 @@ static bool parseCmdlIVAS_dec( arg->renderConfigFilename = NULL; arg->Opt_dpid_on = 0; +#ifdef SPLIT_REND_WITH_HEAD_ROT + arg->outputMdFilename = NULL; +#endif arg->inputFormat = IVAS_DEC_INPUT_FORMAT_G192; arg->Opt_non_diegetic_pan = 0; @@ -1022,6 +1141,19 @@ static bool parseCmdlIVAS_dec( } i += 2; } +#ifdef SPLIT_REND_WITH_HEAD_ROT + else if ( strcmp( argv_to_upper, "-OM" ) == 0 ) + { + arg->outputMdFilename = argv[i + 1]; + if ( arg->outputMdFilename[0] == '\0' ) + { + fprintf( stderr, "Error: output metadata file path not specified\n\n" ); + usage_dec(); + return false; + } + i += 2; + } +#endif else if ( strcmp( argv_to_upper, "-NON_DIEGETIC_PAN" ) == 0 ) { i++; @@ -1172,6 +1304,14 @@ static bool parseCmdlIVAS_dec( usage_dec(); return false; } +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( arg->outputMdFilename != NULL && arg->outputConfig != IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) + { + fprintf( stderr, "Error: Output split rendering metadata file is supported for BINAURAL_SPLIT_PCM output config. only\n\n" ); + usage_dec(); + return false; + } +#endif } else { @@ -1248,8 +1388,13 @@ static void usage_dec( void ) fprintf( stdout, "Mandatory parameters:\n" ); fprintf( stdout, "---------------------\n" ); +#ifdef SPLIT_REND_WITH_HEAD_ROT + fprintf( stdout, "OutputConf : Output configuration: MONO, STEREO, 5_1, 7_1, 5_1_2, 5_1_4, 7_1_4, FOA,\n" ); + fprintf( stdout, " HOA2, HOA3, BINAURAL, BINAURAL_ROOM_IR, BINAURAL_ROOM_REVERB, BINAURAL_SPLIT_CODED, BINAURAL_SPLIT_PCM, EXT\n" ); +#else fprintf( stdout, "OutputConf : Output configuration: MONO, STEREO, 5_1, 7_1, 5_1_2, 5_1_4, 7_1_4, FOA,\n" ); fprintf( stdout, " HOA2, HOA3, BINAURAL, BINAURAL_ROOM_IR, BINAURAL_ROOM_REVERB, EXT\n" ); +#endif fprintf( stdout, " By default, channel order and loudspeaker positions are equal to the\n" ); fprintf( stdout, " encoder. For loudspeaker outputs, OutputConf can be a custom loudspeaker\n" ); fprintf( stdout, " layout file. See readme.txt for details.\n" ); @@ -1289,6 +1434,9 @@ static void usage_dec( void ) fprintf( stdout, "-rvf File : Reference vector specified by external trajectory File\n" ); fprintf( stdout, " works only in combination with '-otr ref_vec' and 'ref_vec_lev' modes\n" ); fprintf( stdout, "-render_config File : Renderer configuration File\n" ); +#ifdef SPLIT_REND_WITH_HEAD_ROT + fprintf( stdout, "-om File : Metadata output File for BINAURAL_SPLIT_PCM OutputConf (only for Fs = 48 kHz)\n" ); +#endif fprintf( stdout, "-non_diegetic_pan P : panning mono non-diegetic sound to stereo with paning P, -90<= P <=90,\n" ); fprintf( stdout, " left or l or 90->left, right or r or -90->right, center or c or 0->middle\n" ); fprintf( stdout, "-exof File : External orientation File for external orientation trajectory\n" ); @@ -1315,10 +1463,15 @@ static void usage_dec( void ) *---------------------------------------------------------------------*/ static ivas_error initOnFirstGoodFrame( - IVAS_DEC_HANDLE hIvasDec, /* i/o: */ - const DecArguments arg, /* i : */ - const int16_t numInitialBadFrames, /* i : */ - const uint16_t numOutSamples, /* i : */ + IVAS_DEC_HANDLE hIvasDec, /* i/o: */ + const DecArguments arg, /* i : */ + const int16_t numInitialBadFrames, /* i : */ +#ifdef SPLIT_REND_WITH_HEAD_ROT + int16_t *numOutSamples, /* i/o: */ + int16_t *vec_pos_len, /* i/o: */ +#else + const uint16_t numOutSamples, /* i : */ +#endif int16_t *pFullDelayNumSamples, /* o : */ int16_t *pRemainingDelayNumSamples, /* o : */ int32_t *delayTimeScale, /* o : */ @@ -1327,7 +1480,12 @@ static ivas_error initOnFirstGoodFrame( MasaFileWriter **ppMasaWriter, /* o : */ IsmFileWriter *ismWriters[IVAS_MAX_NUM_OBJECTS], /* o : */ int16_t *pNumOutChannels, /* o : */ - uint16_t *pNumObj /* o : */ +#ifdef SPLIT_REND_WITH_HEAD_ROT + uint16_t *pNumObj, /* o : */ + SplitFileReadWrite **splitRendWriter +#else + uint16_t *pNumObj /* o : */ +#endif ) { ivas_error error = IVAS_ERR_UNKNOWN; @@ -1339,6 +1497,12 @@ static ivas_error initOnFirstGoodFrame( return error; } +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( IVAS_DEC_is_split_rendering_enabled( hIvasDec ) ) + { + pFullDelayNumSamples[0] = 0; + } +#endif if ( !arg.delayCompensationEnabled ) { @@ -1360,32 +1524,166 @@ static ivas_error initOnFirstGoodFrame( return error; } - /* Open audio writer and write all previously skipped bad frames now that frame size is known */ - if ( ( error = AudioFileWriter_open( ppAfWriter, arg.outputWavFilename, arg.output_Fs, *pNumOutChannels ) ) != IVAS_ERR_OK ) +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( IVAS_DEC_is_split_rendering_enabled( hIvasDec ) ) { - fprintf( stderr, "\nUnable to open output file %s\n", arg.outputWavFilename ); - return error; + /* Open split rendering metadata writer */ + int16_t delayNumSamples_temp[3]; + int32_t delayTimeScale_temp; + ISAR_SPLIT_REND_CODEC splitRendCodec; + int16_t splitRendCodecFrameSizeMs; + ISAR_SPLIT_REND_POSE_CORRECTION_MODE poseCorrection; +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + int16_t splitRendIsarFrameSizeMs; + int16_t lc3plusHighRes; +#endif + + if ( ( error = IVAS_DEC_GetDelay( hIvasDec, delayNumSamples_temp, &delayTimeScale_temp ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nUnable to get delay of decoder: %s\n", ivas_error_to_string( error ) ); + return error; + } + + if ( ( error = IVAS_DEC_GetSplitRendBitstreamHeader( hIvasDec, + &splitRendCodec, + &poseCorrection, +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + &splitRendIsarFrameSizeMs, +#endif + &splitRendCodecFrameSizeMs +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + , + &lc3plusHighRes +#endif + ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nUnable to get split renderer bitstream header: %s\n", ivas_error_to_string( error ) ); + return error; + } + + if ( IVAS_DEC_is_split_rendering_coded_out( hIvasDec ) ) + { + if ( ( error = split_rend_writer_open( splitRendWriter, + arg.outputWavFilename, + delayNumSamples_temp[0], + delayTimeScale_temp, + splitRendCodec, + poseCorrection, + splitRendCodecFrameSizeMs +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + , + splitRendIsarFrameSizeMs, + arg.output_Fs, + lc3plusHighRes +#endif + ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nUnable to open output split rendering metadata file %s\n", arg.outputWavFilename ); + return error; + } + } + else + { + if ( arg.outputMdFilename == NULL ) + { + fprintf( stderr, "\nOutput split rendering metadata file not specified\n" ); + return IVAS_ERR_INVALID_SPLIT_REND_CONFIG; + } + + if ( ( error = split_rend_writer_open( splitRendWriter, + arg.outputMdFilename, + delayNumSamples_temp[0], + delayTimeScale_temp, + splitRendCodec, + poseCorrection, + splitRendCodecFrameSizeMs +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + , + splitRendIsarFrameSizeMs, + arg.output_Fs, + lc3plusHighRes +#endif + ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nUnable to open output split rendering metadata file %s\n", arg.outputWavFilename ); + return error; + } + } } + if ( IVAS_DEC_is_split_rendering_coded_out( hIvasDec ) == 0 ) + { +#endif + /* Open audio writer and write all previously skipped bad frames now that frame size is known */ + if ( ( error = AudioFileWriter_open( ppAfWriter, arg.outputWavFilename, arg.output_Fs, *pNumOutChannels ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nUnable to open output file %s\n", arg.outputWavFilename ); + return error; + } +#ifdef SPLIT_REND_WITH_HEAD_ROT + } +#endif + int16_t *zeroBuf = malloc( pcmFrameSize * sizeof( int16_t ) ); memset( zeroBuf, 0, pcmFrameSize * sizeof( int16_t ) ); for ( int16_t i = 0; i < numInitialBadFrames; ++i ) { +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( *splitRendWriter != NULL ) + { + ISAR_SPLIT_REND_BITS_DATA splitRendBitsZero; + splitRendBitsZero.bits_buf = NULL; + splitRendBitsZero.bits_read = 0; + splitRendBitsZero.bits_written = 0; + splitRendBitsZero.buf_len = 0; + splitRendBitsZero.codec = ISAR_SPLIT_REND_CODEC_DEFAULT; + splitRendBitsZero.pose_correction = ISAR_SPLIT_REND_POSE_CORRECTION_MODE_NONE; +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + splitRendBitsZero.codec_frame_size_ms = 0; + splitRendBitsZero.isar_frame_size_ms = 20; +#else + splitRendBitsZero.codec_frame_size_ms = 20; +#endif - if ( *pRemainingDelayNumSamples < numOutSamples ) - { - if ( ( error = AudioFileWriter_write( *ppAfWriter, zeroBuf, numOutSamples * *pNumOutChannels - ( *pRemainingDelayNumSamples * *pNumOutChannels ) ) ) != IVAS_ERR_OK ) + if ( split_rend_write_bitstream_to_file( *splitRendWriter, splitRendBitsZero.bits_buf, &splitRendBitsZero.bits_read, &splitRendBitsZero.bits_written ) != IVAS_ERR_OK ) { - fprintf( stderr, "\nOutput audio file writer error\n" ); + fprintf( stderr, "\nUnable to write to bitstream file!\n" ); return error; } - *pRemainingDelayNumSamples = 0; } else { +#endif + +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( *pRemainingDelayNumSamples < *numOutSamples ) +#else + if ( *pRemainingDelayNumSamples < numOutSamples ) +#endif + { +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( ( error = AudioFileWriter_write( *ppAfWriter, zeroBuf, *numOutSamples * *pNumOutChannels - ( *pRemainingDelayNumSamples * *pNumOutChannels ) ) ) != IVAS_ERR_OK ) +#else + if ( ( error = AudioFileWriter_write( *ppAfWriter, zeroBuf, numOutSamples * *pNumOutChannels - ( *pRemainingDelayNumSamples * *pNumOutChannels ) ) ) != IVAS_ERR_OK ) +#endif + { + fprintf( stderr, "\nOutput audio file writer error\n" ); + return error; + } + *pRemainingDelayNumSamples = 0; + } + else + { +#ifdef SPLIT_REND_WITH_HEAD_ROT + *pRemainingDelayNumSamples -= *numOutSamples; +#else *pRemainingDelayNumSamples -= numOutSamples; +#endif + } +#ifdef SPLIT_REND_WITH_HEAD_ROT } +#endif } free( zeroBuf ); @@ -1452,6 +1750,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 ) ); @@ -1470,6 +1769,27 @@ static ivas_error initOnFirstGoodFrame( } } +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( *splitRendWriter != NULL ) + { + if ( numOutSamples == NULL || vec_pos_len == NULL ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } + + /* real setting of the 5ms mode for split rendering is only known after the decoded first good frame, reset the variables needed in the main decoding loop accordingly here*/ + if ( ( error = IVAS_DEC_GetRenderFramesizeSamples( hIvasDec, numOutSamples ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nError getting render frame size in samples\n" ); + return error; + } + if ( ( error = IVAS_DEC_GetReferencesUpdateFrequency( hIvasDec, vec_pos_len ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nError getting render frame size in samples\n" ); + return error; + } + } +#endif return IVAS_ERR_OK; } @@ -1488,6 +1808,9 @@ static ivas_error decodeG192( RotFileReader *externalOrientationFileReader, RotFileReader *refRotReader, Vector3PairFileReader *referenceVectorReader, +#ifdef SPLIT_REND_WITH_HEAD_ROT + ISAR_SPLIT_REND_BITS_DATA *splitRendBits, +#endif IVAS_DEC_HANDLE hIvasDec, int16_t *pcmBuf ) @@ -1514,7 +1837,9 @@ static ivas_error decodeG192( IsmFileWriter *ismWriters[IVAS_MAX_NUM_OBJECTS]; IVAS_VECTOR3 Pos[IVAS_MAX_PARAM_SPATIAL_SUBFRAMES] = { { 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0 } }; int16_t vec_pos_update, vec_pos_len; - +#ifdef SPLIT_REND_WITH_HEAD_ROT + SplitFileReadWrite *splitRendWriter = NULL; +#endif for ( i = 0; i < IVAS_MAX_NUM_OBJECTS; ++i ) { @@ -1612,18 +1937,44 @@ static ivas_error decodeG192( { IVAS_QUATERNION Quaternions[IVAS_MAX_PARAM_SPATIAL_SUBFRAMES]; - for ( i = 0; i < num_subframes; i++ ) +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( headRotReader == NULL ) { - if ( ( error = HeadRotationFileReading( headRotReader, &Quaternions[i], &Pos[i] ) ) != IVAS_ERR_OK ) + for ( i = 0; i < num_subframes; i++ ) { - fprintf( stderr, "\nError %s while reading head orientation from %s\n", IVAS_DEC_GetErrorMessage( error ), RotationFileReader_getFilePath( headRotReader ) ); - goto cleanup; + Quaternions[i].w_fx = -12582912; + Quaternions[i].x_fx = 0; + Quaternions[i].y_fx = 0; + Quaternions[i].z_fx = 0; + Quaternions[i].q_fact = 22; + Pos[i].x_fx = 0; + Pos[i].y_fx = 0; + Pos[i].z_fx = 0; + Pos[i].q_fact = 25; } } + else + { +#endif + for ( i = 0; i < num_subframes; i++ ) + { + if ( ( error = HeadRotationFileReading( headRotReader, &Quaternions[i], &Pos[i] ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nError %s while reading head orientation from %s\n", IVAS_DEC_GetErrorMessage( error ), RotationFileReader_getFilePath( headRotReader ) ); + goto cleanup; + } + } +#ifdef SPLIT_REND_WITH_HEAD_ROT + } +#endif for ( i = 0; i < num_subframes; i++ ) { +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( ( error = IVAS_DEC_FeedHeadTrackData( hIvasDec, Quaternions[i], Pos[i], i, DEFAULT_AXIS ) ) != IVAS_ERR_OK ) +#else if ( ( error = IVAS_DEC_FeedHeadTrackData( hIvasDec, Quaternions[i], Pos[i], i ) ) != IVAS_ERR_OK ) +#endif { fprintf( stderr, "\nIVAS_DEC_FeedHeadTrackData failed: %s\n", IVAS_DEC_GetErrorMessage( error ) ); goto cleanup; @@ -1681,14 +2032,32 @@ static ivas_error decodeG192( goto cleanup; } } - if ( ( error = IVAS_DEC_GetSamples( hIvasDec, nSamplesToRender, ( pcmBuf + nOutChannels * nSamplesRendered ), &nSamplesRendered_loop, &needNewFrame ) ) != IVAS_ERR_OK ) +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( IVAS_DEC_is_split_rendering_enabled( hIvasDec ) ) { - fprintf( stderr, "\nError in IVAS_DEC_GetSamples: %s\n", IVAS_DEC_GetErrorMessage( error ) ); - goto cleanup; + if ( ( error = IVAS_DEC_GetSplitBinauralBitstream( hIvasDec, (Word16 *) ( pcmBuf + nOutChannels * nSamplesRendered ), splitRendBits, &nSamplesRendered_loop, &needNewFrame ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nError in IVAS_DEC_GetSplitBinauralBitstream: %s\n", IVAS_DEC_GetErrorMessage( error ) ); + goto cleanup; + } + + nSamplesRendered += nSamplesRendered_loop; + nSamplesToRender -= nSamplesRendered_loop; } - nSamplesRendered += nSamplesRendered_loop; - nSamplesToRender -= nSamplesRendered_loop; + else + { +#endif + if ( ( error = IVAS_DEC_GetSamples( hIvasDec, nSamplesToRender, ( pcmBuf + nOutChannels * nSamplesRendered ), &nSamplesRendered_loop, &needNewFrame ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nError in IVAS_DEC_GetSamples: %s\n", IVAS_DEC_GetErrorMessage( error ) ); + goto cleanup; + } + nSamplesRendered += nSamplesRendered_loop; + nSamplesToRender -= nSamplesRendered_loop; +#ifdef SPLIT_REND_WITH_HEAD_ROT + } +#endif if ( needNewFrame ) { @@ -1719,7 +2088,11 @@ static ivas_error decodeG192( /* Once good frame decoded, catch up */ if ( decodedGoodFrame ) { +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( ( error = initOnFirstGoodFrame( hIvasDec, arg, numInitialBadFrames, &nOutSamples, &vec_pos_len, delayNumSamples_orig, &delayNumSamples, &delayTimeScale, &bsFormat, &afWriter, &masaWriter, ismWriters, &nOutChannels, &numObj, &splitRendWriter ) ) != IVAS_ERR_OK ) +#else if ( ( error = initOnFirstGoodFrame( hIvasDec, arg, numInitialBadFrames, nOutSamples, delayNumSamples_orig, &delayNumSamples, &delayTimeScale, &bsFormat, &afWriter, &masaWriter, ismWriters, &nOutChannels, &numObj ) ) != IVAS_ERR_OK ) +#endif { goto cleanup; } @@ -1733,19 +2106,35 @@ static ivas_error decodeG192( /* Write current frame */ if ( decodedGoodFrame ) { - if ( delayNumSamples < nOutSamples ) +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( IVAS_DEC_is_split_rendering_enabled( hIvasDec ) ) { - if ( ( error = AudioFileWriter_write( afWriter, &pcmBuf[delayNumSamples * nOutChannels], nOutSamples * nOutChannels - ( delayNumSamples * nOutChannels ) ) ) != IVAS_ERR_OK ) + if ( split_rend_write_bitstream_to_file( splitRendWriter, splitRendBits->bits_buf, &splitRendBits->bits_read, &splitRendBits->bits_written ) != IVAS_ERR_OK ) { - fprintf( stderr, "\nOutput audio file writer error\n" ); + fprintf( stderr, "\nUnable to write to bitstream file!\n" ); goto cleanup; } - delayNumSamples = 0; } - else + + if ( IVAS_DEC_is_split_rendering_coded_out( hIvasDec ) == 0 ) { - delayNumSamples -= nOutSamples; +#endif + if ( delayNumSamples < nOutSamples ) + { + if ( ( error = AudioFileWriter_write( afWriter, &pcmBuf[delayNumSamples * nOutChannels], nOutSamples * nOutChannels - ( delayNumSamples * nOutChannels ) ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nOutput audio file writer error\n" ); + goto cleanup; + } + delayNumSamples = 0; + } + else + { + delayNumSamples -= nOutSamples; + } +#ifdef SPLIT_REND_WITH_HEAD_ROT } +#endif } /* Write ISm metadata to external file(s) */ @@ -1859,7 +2248,11 @@ static ivas_error decodeG192( goto cleanup; } +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( ( error = IVAS_DEC_FeedHeadTrackData( hIvasDec, Quaternion, Pos[0], 0, DEFAULT_AXIS ) ) != IVAS_ERR_OK ) +#else if ( ( error = IVAS_DEC_FeedHeadTrackData( hIvasDec, Quaternion, Pos[0], 0 ) ) != IVAS_ERR_OK ) +#endif { fprintf( stderr, "\nIVAS_DEC_FeedHeadTrackData failed: %s\n", IVAS_DEC_GetErrorMessage( error ) ); goto cleanup; @@ -1979,11 +2372,18 @@ static ivas_error decodeG192( *------------------------------------------------------------------------------------------*/ memset( pcmBuf, 0, delayNumSamples_orig[0] * nOutChannels * sizeof( int16_t ) ); - if ( ( error = AudioFileWriter_write( afWriter, pcmBuf, delayNumSamples_orig[0] * nOutChannels ) ) != IVAS_ERR_OK ) +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( afWriter != NULL ) { - fprintf( stderr, "\nError writing output file: %s\n", ivas_error_to_string( error ) ); - goto cleanup; +#endif + if ( ( error = AudioFileWriter_write( afWriter, pcmBuf, delayNumSamples_orig[0] * nOutChannels ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nError writing output file: %s\n", ivas_error_to_string( error ) ); + goto cleanup; + } +#ifdef SPLIT_REND_WITH_HEAD_ROT } +#endif /*------------------------------------------------------------------------------------------* * Close files and deallocate resources @@ -1993,6 +2393,9 @@ static ivas_error decodeG192( cleanup: +#ifdef SPLIT_REND_WITH_HEAD_ROT + split_rend_reader_writer_close( &splitRendWriter ); +#endif AudioFileWriter_close( &afWriter ); MasaFileWriter_close( &masaWriter ); for ( i = 0; i < IVAS_MAX_NUM_OBJECTS; i++ ) @@ -2239,19 +2642,46 @@ static ivas_error decodeVoIP( { IVAS_QUATERNION Quaternions[IVAS_MAX_PARAM_SPATIAL_SUBFRAMES]; - for ( i = 0; i < num_subframes; i++ ) +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( headRotReader == NULL ) { - if ( ( error = HeadRotationFileReading( headRotReader, &Quaternions[i], &Pos[i] ) ) != IVAS_ERR_OK ) + for ( i = 0; i < num_subframes; i++ ) { - fprintf( stderr, "\nError %s while reading head orientation from %s\n", IVAS_DEC_GetErrorMessage( error ), - RotationFileReader_getFilePath( headRotReader ) ); - goto cleanup; + Quaternions[i].w_fx = -12582912; + Quaternions[i].x_fx = 0; + Quaternions[i].y_fx = 0; + Quaternions[i].z_fx = 0; + Quaternions[i].q_fact = 22; + Pos[i].x = 0.0f; + Pos[i].y = 0.0f; + Pos[i].z = 0.0f; + Pos[i].q_fact = 25; } } + else + { +#endif + for ( i = 0; i < num_subframes; i++ ) + { + if ( ( error = HeadRotationFileReading( headRotReader, &Quaternions[i], &Pos[i] ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nError %s while reading head orientation from %s\n", IVAS_DEC_GetErrorMessage( error ), + RotationFileReader_getFilePath( headRotReader ) ); + goto cleanup; + } + } +#ifdef SPLIT_REND_WITH_HEAD_ROT + } +#endif for ( i = 0; i < num_subframes; i++ ) { - if ( ( error = IVAS_DEC_FeedHeadTrackData( hIvasDec, Quaternions[i], Pos[i], i ) ) != IVAS_ERR_OK ) + if ( ( error = IVAS_DEC_FeedHeadTrackData( hIvasDec, Quaternions[i], Pos[i], i +#ifdef SPLIT_REND_WITH_HEAD_ROT + , + DEFAULT_AXIS +#endif + ) ) != IVAS_ERR_OK ) { fprintf( stderr, "\nIVAS_DEC_FeedHeadTrackData failed: %s\n", IVAS_DEC_GetErrorMessage( error ) ); goto cleanup; @@ -2338,7 +2768,6 @@ static ivas_error decodeVoIP( /* decode and get samples */ - #ifdef SUPPORT_JBM_TRACEFILE if ( ( error = IVAS_DEC_VoIP_GetSamples( hIvasDec, nOutSamples, pcmBuf, systemTime_ms, writeJbmTraceFileFrameWrapper, jbmTraceWriter ) ) != IVAS_ERR_OK ) #else @@ -2379,8 +2808,15 @@ static ivas_error decodeVoIP( /* Once good frame decoded, catch up */ if ( decodedGoodFrame ) { +#ifdef SPLIT_REND_WITH_HEAD_ROT + SplitFileReadWrite *splitRendWriter = NULL; + + if ( ( error = initOnFirstGoodFrame( hIvasDec, arg, numInitialBadFrames, &nOutSamples, NULL, delayNumSamples_orig, &delayNumSamples, &delayTimeScale, + &bsFormat, &afWriter, &masaWriter, ismWriters, &nOutChannels, &numObj, &splitRendWriter ) ) != IVAS_ERR_OK ) +#else if ( ( error = initOnFirstGoodFrame( hIvasDec, arg, numInitialBadFrames, nOutSamples, delayNumSamples_orig, &delayNumSamples, &delayTimeScale, &bsFormat, &afWriter, &masaWriter, ismWriters, &nOutChannels, &numObj ) ) != IVAS_ERR_OK ) +#endif { goto cleanup; } diff --git a/apps/encoder.c b/apps/encoder.c index a1b7f0d10118e6e9388a5313036ac7c37a8ceeb0..af9554589d813007f8b04ec2df6f4f6a0369fe4c 100644 --- a/apps/encoder.c +++ b/apps/encoder.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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,6 +45,19 @@ #include "masa_file_reader.h" #include "wmc_auto.h" +#ifdef DEBUG_FORCE_DIR +/* Windows does not define the S_ISREG and S_ISDIR macros in stat.h, so we do. + We have to define _CRT_INTERNAL_NONSTDC_NAMES 1 before #including sys/stat.h + in order for Microsoft's stat.h to define names like S_IFMT, S_IFREG, and S_IFDIR, + rather than just defining _S_IFMT, _S_IFREG, and _S_IFDIR as it normally does. */ +#include +#if !defined( S_ISREG ) && defined( S_IFMT ) && defined( S_IFREG ) +#define S_ISREG( m ) ( ( (m) &S_IFMT ) == S_IFREG ) +#endif +#if !defined( S_ISDIR ) && defined( S_IFMT ) && defined( S_IFDIR ) +#define S_ISDIR( m ) ( ( (m) &S_IFMT ) == S_IFDIR ) +#endif +#endif #define WMC_TOOL_SKIP @@ -136,6 +149,9 @@ typedef struct #ifdef DEBUGGING IVAS_ENC_FORCED_MODE forcedMode; const char *forcedModeFile; +#ifdef DEBUG_FORCE_DIR + const char *forcedModeDir; +#endif #endif bool pca; bool ism_extended_metadata; @@ -353,6 +369,15 @@ int main( goto cleanup; } +#ifdef SUPPORT_FORCE_TCX10_TCX20 +#ifdef DEBUGGING + if ( arg.forcedMode == IVAS_ENC_FORCE_TCX10 && totalBitrate < 48000 ) + { + fprintf( stderr, "Warning: Enforcing the TCX10 mode is only supported for bitrates higher or equal than 48 kbps!\n\n" ); + } +#endif +#endif + /*------------------------------------------------------------------------------------------* * Configure and initialize (allocate memory for static variables) the encoder *------------------------------------------------------------------------------------------*/ @@ -680,7 +705,12 @@ int main( /* Force mode not set when configuring, set in first frame even if not reading from file */ if ( f_forcedModeProfile || frame == 0 ) { - if ( ( error = IVAS_ENC_SetForcedMode( hIvasEnc, forcedMode ) ) != IVAS_ERR_OK ) + if ( ( error = IVAS_ENC_SetForcedMode( hIvasEnc, forcedMode +#ifdef DEBUG_FORCE_DIR + , + arg.forcedModeDir +#endif + ) ) != IVAS_ERR_OK ) { fprintf( stderr, "\nIVAS_ENC_SetForcedMode failed: %s\n\n", IVAS_ENC_GetErrorMessage( error ) ); goto cleanup; @@ -851,6 +881,9 @@ static void initArgStruct( EncArguments *arg ) #ifdef DEBUGGING arg->forcedMode = IVAS_ENC_FORCE_UNFORCED; arg->forcedModeFile = NULL; +#ifdef DEBUG_FORCE_DIR + arg->forcedModeDir = NULL; +#endif #endif arg->pca = false; @@ -991,6 +1024,28 @@ static bool parseCmdlIVAS_enc( arg->forcedMode = parseForcedMode( stmp ); +#ifdef DEBUG_FORCE_DIR + if ( arg->forcedMode < IVAS_ENC_FORCE_FILE ) + { + fprintf( stdout, "Forcing codec to: %s\n", argv[i + 1] ); + } + else if ( arg->forcedMode == IVAS_ENC_FORCE_FILE ) + { + arg->forcedModeFile = argv[i + 1]; + fprintf( stdout, "Force switching file: %s\n", argv[i + 1] ); + } + else if ( arg->forcedMode == IVAS_ENC_FORCE_DIR ) + { + arg->forcedModeDir = argv[i + 1]; + fprintf( stdout, "Forcing switching directory: %s\n", argv[i + 1] ); + } + else + { + fprintf( stderr, "\nError: The force switching profile file/dir %s does not exist or could not be opened!\n\n", argv[i + 1] ); + usage_enc(); + return false; + } +#else if ( arg->forcedMode == IVAS_ENC_FORCE_UNDEFINED ) { arg->forcedModeFile = argv[i + 1]; @@ -998,8 +1053,26 @@ static bool parseCmdlIVAS_enc( } else { +#ifdef SUPPORT_FORCE_TCX10_TCX20 + if ( arg->forcedMode == IVAS_ENC_FORCE_TCX10 ) + { + strcpy( stmp, "TCX10" ); + } + else if ( arg->forcedMode == IVAS_ENC_FORCE_TCX20 ) + { + strcpy( stmp, "TCX20" ); + } + else + { + strncpy( stmp, argv[i + 1], sizeof( stmp ) ); + } + + fprintf( stdout, "Forcing codec to: %s\n", stmp ); +#else fprintf( stdout, "Forcing codec to: %s\n", argv[i + 1] ); +#endif } +#endif i += 2; } @@ -1791,6 +1864,9 @@ static void usage_enc( void ) #ifdef DEBUGGING fprintf( stdout, "-force T : Force specific mode, T = (speech, music, ACELP, GSC, TCX, HQ),\n" ); fprintf( stdout, " alternatively, T can be a text file where each line contains \"nb_frames T\"\n" ); +#ifdef DEBUG_FORCE_DIR + fprintf( stdout, " or T can be a directory containing external binary files for modes/parameters enforcement\n" ); +#endif #endif #ifdef DEBUG_MODE_INFO #ifdef DEBUG_MODE_INFO_TWEAK @@ -1900,8 +1976,72 @@ static bool readBitrate( static IVAS_ENC_FORCED_MODE parseForcedMode( char *forcedModeChar ) { +#ifdef DEBUG_FORCE_DIR + struct stat path_stat; +#endif + to_upper( forcedModeChar ); +#ifdef DEBUG_FORCE_DIR + if ( ( strcmp( forcedModeChar, "SPEECH" ) == 0 ) || ( strcmp( forcedModeChar, "'SPEECH'" ) == 0 ) || + ( strcmp( forcedModeChar, "0" ) == 0 ) ) + { + return IVAS_ENC_FORCE_SPEECH; + } + else if ( ( strcmp( forcedModeChar, "MUSIC" ) == 0 ) || ( strcmp( forcedModeChar, "'MUSIC'" ) == 0 ) || ( strcmp( forcedModeChar, "AUDIO" ) == 0 ) || ( strcmp( forcedModeChar, "'AUDIO'" ) == 0 ) || ( strcmp( forcedModeChar, "1" ) == 0 ) ) + { + return IVAS_ENC_FORCE_MUSIC; + } + else if ( ( strcmp( forcedModeChar, "ACELP" ) == 0 ) || ( strcmp( forcedModeChar, "'ACELP'" ) == 0 ) ) + { + return IVAS_ENC_FORCE_ACELP; + } + else if ( ( strcmp( forcedModeChar, "GSC" ) == 0 ) || ( strcmp( forcedModeChar, "'GSC'" ) == 0 ) ) + { + return IVAS_ENC_FORCE_GSC; + } + if ( ( strcmp( forcedModeChar, "TCX" ) == 0 ) || ( strcmp( forcedModeChar, "'TCX'" ) == 0 ) +#ifdef SUPPORT_FORCE_TCX10_TCX20 + || ( strcmp( forcedModeChar, "TCX20" ) == 0 ) || ( strcmp( forcedModeChar, "'TCX20'" ) == 0 ) +#endif + ) + { +#ifdef SUPPORT_FORCE_TCX10_TCX20 + return IVAS_ENC_FORCE_TCX20; +#else + return IVAS_ENC_FORCE_TCX; +#endif + } +#ifdef SUPPORT_FORCE_TCX10_TCX20 + if ( ( strcmp( forcedModeChar, "TCX10" ) == 0 ) || ( strcmp( forcedModeChar, "'TCX10'" ) == 0 ) ) + { + return IVAS_ENC_FORCE_TCX10; + } +#endif + else if ( ( strcmp( forcedModeChar, "HQ" ) == 0 ) || ( strcmp( forcedModeChar, "'HQ'" ) == 0 ) ) + { + return IVAS_ENC_FORCE_HQ; + } + else + { + if ( stat( forcedModeChar, &path_stat ) != 0 ) + { + return IVAS_ENC_FORCE_UNDEFINED; + } + + /* check if the argument represents an existing file or directory */ + if ( S_ISDIR( path_stat.st_mode ) ) + { + /* it's a directory */ + return IVAS_ENC_FORCE_DIR; + } + else + { + /* it's a file */ + return IVAS_ENC_FORCE_FILE; + } + } +#else if ( ( strcmp( forcedModeChar, "SPEECH" ) == 0 ) || ( strcmp( forcedModeChar, "'SPEECH'" ) == 0 ) || ( strcmp( forcedModeChar, "0" ) == 0 ) ) { @@ -1919,16 +2059,31 @@ static IVAS_ENC_FORCED_MODE parseForcedMode( { return IVAS_ENC_FORCE_GSC; } - if ( ( strcmp( forcedModeChar, "TCX" ) == 0 ) || ( strcmp( forcedModeChar, "'TCX'" ) == 0 ) ) + if ( ( strcmp( forcedModeChar, "TCX" ) == 0 ) || ( strcmp( forcedModeChar, "'TCX'" ) == 0 ) +#ifdef SUPPORT_FORCE_TCX10_TCX20 + || ( strcmp( forcedModeChar, "TCX20" ) == 0 ) || ( strcmp( forcedModeChar, "'TCX20'" ) == 0 ) +#endif + ) { +#ifdef SUPPORT_FORCE_TCX10_TCX20 + return IVAS_ENC_FORCE_TCX20; +#else return IVAS_ENC_FORCE_TCX; +#endif + } +#ifdef SUPPORT_FORCE_TCX10_TCX20 + if ( ( strcmp( forcedModeChar, "TCX10" ) == 0 ) || ( strcmp( forcedModeChar, "'TCX10'" ) == 0 ) ) + { + return IVAS_ENC_FORCE_TCX10; } +#endif if ( ( strcmp( forcedModeChar, "HQ" ) == 0 ) || ( strcmp( forcedModeChar, "'HQ'" ) == 0 ) ) { return IVAS_ENC_FORCE_HQ; } return IVAS_ENC_FORCE_UNDEFINED; +#endif } diff --git a/apps/isar_post_rend.c b/apps/isar_post_rend.c new file mode 100644 index 0000000000000000000000000000000000000000..d9095054beead45053c678af29cbdcf0aa62bb24 --- /dev/null +++ b/apps/isar_post_rend.c @@ -0,0 +1,1262 @@ +/****************************************************************************************************** + + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository. All Rights Reserved. + + This software is protected by copyright law and by international treaties. + The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository retain full ownership rights in their respective contributions in + the software. This notice grants no license of any kind, including but not limited to patent + license, nor is any license granted by implication, estoppel or otherwise. + + Contributors are required to enter into the IVAS codec Public Collaboration agreement before making + contributions. + + This software is provided "AS IS", without any express or implied warranties. The software is in the + development stage. It is intended exclusively for experts who have experience with such software and + solely for the purpose of inspection. All implied warranties of non-infringement, merchantability + and fitness for a particular purpose are hereby disclaimed and excluded. + + Any dispute, controversy or claim arising under or in relation to providing this software shall be + submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in + accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and + the United Nations Convention on Contracts on the International Sales of Goods. + +*******************************************************************************************************/ + +#include "lib_isar_post_rend.h" +//#undef IVAS_FLOAT_FIXED + +#ifndef SPLIT_REND_WITH_HEAD_ROT + +int main( int argc, char **argv ) +{ + (void) argc; + (void) argv; + ISAR_POST_REND_void_func(); + return 0; +} + +#else + +#include +#include +#include +#include "audio_file_reader.h" +#include "audio_file_writer.h" +#include "cmdl_tools.h" +#include "cmdln_parser.h" +#include "render_config_reader.h" +#include "rotation_file_reader.h" +#include "split_render_file_read_write.h" +#include "split_rend_bfi_file_reader.h" +#ifdef DEBUGGING +#include "debug.h" +#endif +#include "stl.h" +#include "wmc_auto.h" + + +#define WMC_TOOL_SKIP + +/*------------------------------------------------------------------------------------------* + * Local constants + *------------------------------------------------------------------------------------------*/ + +#define POST_REND_MAX_CLI_ARG_LENGTH ( FILENAME_MAX ) + +#define ISAR_MAX16B_FLT 32767.0f +#define ISAR_MIN16B_FLT ( -32768.0f ) +#define ISAR_MAX16B_FX 32767 +#define ISAR_MIN16B_FX ( -32768 ) + +#if !defined( DEBUGGING ) && !defined( WMOPS ) +static +#endif + int32_t frame = 0; + +#ifdef _WIN32 +#define SEP_FOLDER '\\' +#else +#define SEP_FOLDER '/' +#endif + +/*------------------------------------------------------------------------------------------* + * Local structures + *------------------------------------------------------------------------------------------*/ + +typedef struct +{ + IVAS_AUDIO_CONFIG audioConfig; + int32_t inputChannelIndex; + float gain_dB; +} RendererInput; + +typedef struct +{ + RendererInput binBuses[RENDERER_MAX_BIN_INPUTS]; + uint16_t numBinBuses; +} InputConfig; + +typedef struct +{ + IVAS_AUDIO_CONFIG audioConfig; +} OutputConfig; + +typedef struct +{ + char executableName[POST_REND_MAX_CLI_ARG_LENGTH]; + char inputFilePath[POST_REND_MAX_CLI_ARG_LENGTH]; + char outputFilePath[POST_REND_MAX_CLI_ARG_LENGTH]; + int32_t sampleRate; + InputConfig inConfig; + OutputConfig outConfig; + char inMetadataFilePaths[RENDERER_MAX_ISAR_MD_INPUTS][POST_REND_MAX_CLI_ARG_LENGTH]; + int16_t numInMetadataFiles; + char headRotationFilePath[POST_REND_MAX_CLI_ARG_LENGTH]; + char splitRendBFIFilePath[POST_REND_MAX_CLI_ARG_LENGTH]; + ISAR_POST_REND_COMPLEXITY_LEVEL complexityLevel; + bool delayCompensationEnabled; + bool quietModeEnabled; + bool sceneDescriptionInput; + IVAS_RENDER_FRAMESIZE render_framesize; +} CmdlnArgs; + +typedef enum +{ + CmdLnOptionId_inputFile = 1, + CmdLnOptionId_inputFormat, + CmdLnOptionId_outputFile, + CmdLnOptionId_sampleRate, + CmdLnOptionId_trajFile, + CmdLnOptionId_orientationTracking, + CmdLnOptionId_complexityLevel, + CmdLnOptionId_noDelayCmp, + CmdLnOptionId_quietModeEnabled, + CmdLnOptionId_inputMetadata, + CmdLnOptionId_listFormats, + CmdLnOptionId_SplitRendBFIFile, + CmdLnOptionId_framing, +} CmdLnOptionId; + +static const CmdLnParser_Option cliOptions[] = { + { + .id = CmdLnOptionId_inputFile, + .match = "input_file", + .matchShort = "i", + .description = "Path to the input file (WAV, raw PCM or scene description file)", + }, + { + .id = CmdLnOptionId_inputFormat, + .match = "input_format", + .matchShort = "if", + .description = "Audio format of input file (e.g. BINAURAL_SPLIT_PCM, use -l for a list)", + }, + { + .id = CmdLnOptionId_inputMetadata, + .match = "input_metadata", + .matchShort = "im", + .description = "Space-separated list of path to metadata files for BINAURAL_SPLIT_PCM input mode", + }, + { + .id = CmdLnOptionId_outputFile, + .match = "output_file", + .matchShort = "o", + .description = "Path to the output file", + }, + { + .id = CmdLnOptionId_sampleRate, + .match = "sample_rate", + .matchShort = "fs", + .description = "Input sampling rate in kHz (16, 32, 48) - required only with raw PCM inputs", + }, + { + .id = CmdLnOptionId_trajFile, + .match = "trajectory_file", + .matchShort = "T", + .description = "Head rotation trajectory file for simulation of head tracking", + }, + { + .id = CmdLnOptionId_SplitRendBFIFile, + .match = "post_rend_bfi_file", + .matchShort = "prbfi", + .description = "Split rendering option: bfi file", + }, + { + .id = CmdLnOptionId_noDelayCmp, + .match = "no_delay_compensation", + .matchShort = "no_delay_cmp", + .description = "[flag] Turn off delay compensation", + }, + { + .id = CmdLnOptionId_complexityLevel, + .match = "complexity_level", + .matchShort = "level", + .description = "Complexity level, level = (1, 2, 3), will be defined after characterisation.", + }, + { + .id = CmdLnOptionId_quietModeEnabled, + .match = "quiet", + .matchShort = "q", + .description = "[flag] Limit printouts to terminal", + }, + { + .id = CmdLnOptionId_listFormats, + .match = "list", + .matchShort = "l", + .description = "List supported audio formats", + }, + { + .id = CmdLnOptionId_framing, + .match = "framing", + .matchShort = "fr", + .description = "Set Render audio framing.", + }, +}; + + +/*------------------------------------------------------------------------------------------* + * Local function prototypes + *------------------------------------------------------------------------------------------*/ + +static const int32_t numCliOptions = sizeof( cliOptions ) / sizeof( CmdLnParser_Option ); + +static void printSupportedAudioConfigs( void ); + +static IVAS_AUDIO_CONFIG parseAudioConfig( const char *configString ); + +static void convertOutputBuffer( const Word32 *fixedBuffer, Word16 q, const int16_t numSamplesPerChannel, const int16_t numChannels, int16_t *intBuffer ); + +/*------------------------------------------------------------------------------------------* + * Local functions + *------------------------------------------------------------------------------------------*/ + +static ISAR_POST_REND_ReadOnlyAudioBuffer getReadOnlySubBuffer( + IVAS_REND_AudioBuffer buffer, + const int16_t chBeginIdx, + const int16_t numChannels ) +{ + ISAR_POST_REND_ReadOnlyAudioBuffer subBuffer; + + subBuffer.config = buffer.config; + subBuffer.config.numChannels = numChannels; + subBuffer.data_fx = buffer.data_fx + subBuffer.config.numSamplesPerChannel * chBeginIdx; + + return subBuffer; +} + + +static int16_t getTotalNumInChannels( + ISAR_POST_REND_HANDLE hIsarPostRend, + ISAR_POST_REND_InputId splitBinIds[RENDERER_MAX_BIN_INPUTS] ) +{ + int16_t totalNumInChannels = 0; + int16_t i, numInputChannels; + ivas_error error; + + for ( i = 0; i < RENDERER_MAX_BIN_INPUTS; ++i ) + { + if ( splitBinIds[i] == 0 ) + { + /* Skip inactive inputs */ + continue; + } + + if ( ( error = ISAR_POST_REND_GetInputNumChannels( hIsarPostRend, splitBinIds[i], &numInputChannels ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "Error: %s\n", ivas_error_to_string( error ) ); + exit( -1 ); + } + totalNumInChannels += numInputChannels; + } + + return totalNumInChannels; +} + +/*------------------------------------------------------------------------------------------* + * Local functions + *------------------------------------------------------------------------------------------*/ + +static const CmdLnParser_Option *findOptionById( + const int32_t id ) +{ + for ( int32_t i = 0; i < numCliOptions; ++i ) + { + if ( cliOptions[i].id == id ) + { + return &cliOptions[i]; + } + } + + return NULL; +} + +static bool parseInConfig( + const char *inFormatStr, + InputConfig *inConfig, + bool *sceneDescriptionInput ) +{ + char charBuf[FILENAME_MAX]; + + /* Initialize input config struct */ + inConfig->numBinBuses = 0; + + /* First check if input is being set to scene description file - this is not covered by parseAudioConfig(). */ + strncpy( charBuf, inFormatStr, sizeof( charBuf ) - 1 ); + charBuf[sizeof( charBuf ) - 1] = '\0'; + to_upper( charBuf ); + if ( strcmp( charBuf, "META" ) == 0 ) + { + *sceneDescriptionInput = true; + /* Parsing the file will be done later. At this point the actual file path + * may not be known as command line parameters are still being parsed. */ + return true; + } + + /* Check for single-format inputs. The given string should map to a member of AUDIO_CONFIG enum. */ + IVAS_AUDIO_CONFIG audioConfig = parseAudioConfig( inFormatStr ); + switch ( audioConfig ) + { + case IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED: + case IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM: + inConfig->numBinBuses = 1; + inConfig->binBuses[0].audioConfig = audioConfig; + inConfig->binBuses[0].inputChannelIndex = 0; + inConfig->binBuses[0].gain_dB = 0.0f; + break; + default: + { + /* Default case covers formats that are defined in the AUDIO_CONFIG enum, + * but cannot be used at input, e.g. BINAURAL */ + const CmdLnParser_Option *listOption = findOptionById( CmdLnOptionId_listFormats ); + fprintf( stderr, "Unsupported input format: %s. To list valid formats, use option --%s.\n", inFormatStr, listOption->match ); + return false; + } + } + + return true; +} + + +static bool parseRenderFramesize( + char *value, + IVAS_RENDER_FRAMESIZE *render_framesize ) +{ + int32_t tmp; + + *render_framesize = IVAS_RENDER_FRAMESIZE_UNKNOWN; + if ( !is_digits_only( value ) ) + { + return false; + } + tmp = (int32_t) strtol( value, NULL, 0 ); + switch ( (int16_t) tmp ) + { + case 5: + *render_framesize = IVAS_RENDER_FRAMESIZE_5MS; + break; + case 10: + *render_framesize = IVAS_RENDER_FRAMESIZE_10MS; + break; + case 20: + *render_framesize = IVAS_RENDER_FRAMESIZE_20MS; + break; + default: + return false; + } + + return true; +} + + +static IVAS_AUDIO_CONFIG parseAudioConfig( + const char *configString ) +{ + char charBuf[25]; + charBuf[24] = '\0'; + + strncpy( charBuf, configString, sizeof( charBuf ) - 1 ); + charBuf[sizeof( charBuf ) - 1] = '\0'; + to_upper( charBuf ); + + if ( strcmp( charBuf, "BINAURAL" ) == 0 ) + { + return IVAS_AUDIO_CONFIG_BINAURAL; + } + if ( strcmp( charBuf, "BINAURAL_SPLIT_PCM" ) == 0 ) + { + return IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM; + } + if ( strcmp( charBuf, "BINAURAL_SPLIT_CODED" ) == 0 ) + { + return IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED; + } + return IVAS_AUDIO_CONFIG_INVALID; +} + + +static bool checkRequiredArgs( + CmdlnArgs args ) +{ + const CmdLnParser_Option *tmpOption; + + /* Check required arguments */ + bool missingRequiredArg = false; + if ( isEmptyString( args.inputFilePath ) ) + { + tmpOption = findOptionById( CmdLnOptionId_inputFile ); + fprintf( stderr, "Missing required argument: %s (%s)\n", tmpOption->match, tmpOption->matchShort ); + missingRequiredArg = true; + } + + const bool singleInputSpecified = ( args.inConfig.numBinBuses != 0 ); + + if ( !args.sceneDescriptionInput && !singleInputSpecified ) + { + /* Neither scene description input nor single-type input was specified on command line */ + tmpOption = findOptionById( CmdLnOptionId_inputFormat ); + fprintf( stderr, "Missing required argument: %s (%s)\n", tmpOption->match, tmpOption->matchShort ); + missingRequiredArg = true; + } + if ( isEmptyString( args.outputFilePath ) ) + { + tmpOption = findOptionById( CmdLnOptionId_outputFile ); + fprintf( stderr, "Missing required argument: %s (%s)\n", tmpOption->match, tmpOption->matchShort ); + missingRequiredArg = true; + } + if ( args.sampleRate == 0 ) + { + tmpOption = findOptionById( CmdLnOptionId_sampleRate ); + fprintf( stderr, "Missing required argument: %s (%s)\n", tmpOption->match, tmpOption->matchShort ); + missingRequiredArg = true; + } + if ( missingRequiredArg ) + { + CmdLnParser_printUsage( args.executableName, cliOptions, numCliOptions ); + } + + return !missingRequiredArg; +} + +static CmdlnArgs defaultArgs( + const char *executableName ) +{ + CmdlnArgs args; + + strncpy( args.executableName, executableName, POST_REND_MAX_CLI_ARG_LENGTH ); + clearString( args.inputFilePath ); + clearString( args.outputFilePath ); + args.sampleRate = 0; + + args.outConfig.audioConfig = IVAS_AUDIO_CONFIG_INVALID; + + for ( int32_t i = 0; i < RENDERER_MAX_ISAR_MD_INPUTS; ++i ) + { + clearString( args.inMetadataFilePaths[i] ); + } + args.numInMetadataFiles = 0; + + clearString( args.headRotationFilePath ); + clearString( args.splitRendBFIFilePath ); + + args.delayCompensationEnabled = true; + args.quietModeEnabled = false; + args.sceneDescriptionInput = false; + + args.render_framesize = IVAS_RENDER_FRAMESIZE_20MS; + + return args; +} + +static void parseOption( + const int32_t optionId, + char **optionValues, + const int16_t numOptionValues, + void *pOutputStruct ) +{ + CmdlnArgs *args = pOutputStruct; + + switch ( optionId ) + { + case CmdLnOptionId_listFormats: + assert( numOptionValues == 0 ); + printSupportedAudioConfigs(); + exit( 0 ); + case CmdLnOptionId_inputFile: + assert( numOptionValues == 1 ); + strncpy( args->inputFilePath, optionValues[0], POST_REND_MAX_CLI_ARG_LENGTH - 1 ); + break; + case CmdLnOptionId_inputFormat: + assert( numOptionValues == 1 ); + if ( !parseInConfig( optionValues[0], &args->inConfig, &args->sceneDescriptionInput ) ) + { + exit( -1 ); /* Error printout handled by failing function */ + } + break; + case CmdLnOptionId_inputMetadata: + assert( numOptionValues <= RENDERER_MAX_ISAR_MD_INPUTS ); + for ( int16_t i = 0; i < numOptionValues; ++i ) + { + strncpy( args->inMetadataFilePaths[i], optionValues[i], POST_REND_MAX_CLI_ARG_LENGTH - 1 ); + } + args->numInMetadataFiles = numOptionValues; + break; + case CmdLnOptionId_outputFile: + assert( numOptionValues == 1 ); + strncpy( args->outputFilePath, optionValues[0], POST_REND_MAX_CLI_ARG_LENGTH - 1 ); + break; + case CmdLnOptionId_sampleRate: + assert( numOptionValues == 1 ); + args->sampleRate = (int32_t) ( strtol( optionValues[0], NULL, 10 ) * 1000 ); + if ( args->sampleRate == 0 ) + { + fprintf( stderr, "Invalid sampling rate specified\n" ); + exit( -1 ); + } + break; + case CmdLnOptionId_trajFile: + assert( numOptionValues == 1 ); + strncpy( args->headRotationFilePath, optionValues[0], POST_REND_MAX_CLI_ARG_LENGTH - 1 ); + break; + case CmdLnOptionId_SplitRendBFIFile: + assert( numOptionValues == 1 ); + strncpy( args->splitRendBFIFilePath, optionValues[0], POST_REND_MAX_CLI_ARG_LENGTH - 1 ); + break; + case CmdLnOptionId_complexityLevel: + assert( numOptionValues == 1 ); + args->complexityLevel = (int32_t) ( strtol( optionValues[0], NULL, 10 ) ); + if ( args->complexityLevel < ISAR_POST_REND_COMPLEXITY_LEVEL_ONE || args->complexityLevel > ISAR_POST_REND_COMPLEXITY_LEVEL_THREE ) + { + fprintf( stdout, "Invalid complexity level specified.\n" ); + exit( -1 ); + } + else if ( args->complexityLevel == ISAR_POST_REND_COMPLEXITY_LEVEL_ONE || args->complexityLevel == ISAR_POST_REND_COMPLEXITY_LEVEL_TWO ) + { + fprintf( stdout, "Complexity levels 1 and 2 will be defined after characterisation - default to level 3 (full functionality).\n" ); + } + break; + case CmdLnOptionId_noDelayCmp: + assert( numOptionValues == 0 ); + args->delayCompensationEnabled = false; + break; + case CmdLnOptionId_quietModeEnabled: + assert( numOptionValues == 0 ); + args->quietModeEnabled = true; + break; + case CmdLnOptionId_framing: + assert( numOptionValues == 1 ); + if ( !parseRenderFramesize( optionValues[0], &args->render_framesize ) ) + { + fprintf( stderr, "Unknown or invalid option for frame size: %s\n", optionValues[0] ); + exit( -1 ); + } + + break; + default: + assert( 0 && "This should be unreachable - all command line options should be explicitly handled." ); + break; + } + + return; +} + +static CmdlnArgs parseCmdlnArgs( + const int argc, + char **argv ) +{ + CmdlnArgs args = defaultArgs( argv[0] ); + + if ( CmdLnParser_parseArgs( argc, argv, cliOptions, numCliOptions, &args, parseOption ) != 0 ) + { + exit( -1 ); /* Error printout handled by failing function */ + } + + if ( !checkRequiredArgs( args ) ) + { + exit( -1 ); /* Error printout handled by failing function */ + } + + return args; +} + + +static void printSupportedAudioConfigs( void ) +{ + uint16_t i; + const char *supportedFormats[] = { + "BINAURAL (output only)", + "BINAURAL_SPLIT_PCM", + "BINAURAL_SPLIT_CODED", + }; + + fprintf( stdout, "Supported audio formats:\n" ); + for ( i = 0; i < sizeof( supportedFormats ) / sizeof( *supportedFormats ); i++ ) + { + fprintf( stdout, "%s\n", supportedFormats[i] ); + } + + return; +} + +/*--------------------------------------------------------------------------* + * convertInputBuffer() + * + * Convert input buffer from WAV/PCM file (int16_t, interleaved) to a format + * accepted by the renderer (float, packed) + *--------------------------------------------------------------------------*/ + +static void convertInputBuffer( + const int16_t *intBuffer, + const int16_t numIntSamplesPerChannel, + const int16_t numFloatSamplesPerChannel, + const int16_t numChannels, + Word32 *fixedBuffer ) +{ + int16_t chnl, smpl, i; + + i = 0; + + FOR( smpl = 0; smpl < numFloatSamplesPerChannel; ++smpl ) + { + FOR( chnl = 0; chnl < numChannels; ++chnl ) + { + IF( i < numIntSamplesPerChannel ) + { + fixedBuffer[chnl * numFloatSamplesPerChannel + smpl] = (Word32) intBuffer[i]; + } + ELSE + { + fixedBuffer[chnl * numFloatSamplesPerChannel + smpl] = 0; + } + + ++i; + } + } + + return; +} + +/*--------------------------------------------------------------------------* + * convertOutputBuffer() + * + * Convert output buffer from the renderer (float, packed) to a format ready + * for writing to a WAV/PCM file (int16_t, interleaved) + *--------------------------------------------------------------------------*/ + +static void convertOutputBuffer( + const Word32 *fixedBuffer, + Word16 q, + const int16_t numSamplesPerChannel, + const int16_t numChannels, + int16_t *intBuffer ) +{ + int16_t chnl, smpl, i; + Word32 temp; + + i = 0; + + for ( smpl = 0; smpl < numSamplesPerChannel; ++smpl ) + { + for ( chnl = 0; chnl < numChannels; ++chnl ) + { + temp = L_shr_r( fixedBuffer[chnl * numSamplesPerChannel + smpl], q ); + IF( GT_32( temp, ISAR_MAX16B_FX ) ) + { + temp = ISAR_MAX16B_FX; + } + ELSE IF( LT_32( temp, ISAR_MIN16B_FX ) ) + { + temp = ISAR_MIN16B_FX; + } + intBuffer[i] = (int16_t) temp; + + ++i; + } + } + + return; +} + +/*------------------------------------------------------------------------------------------* + * main() + * + * Main ISAR post renderer function for command-line interface + *------------------------------------------------------------------------------------------*/ + +int main( + int argc, + char **argv ) +{ + ISAR_POST_REND_HANDLE hIsarPostRend; + RotFileReader *headRotReader = NULL; + RotFileReader *externalOrientationFileReader = NULL; + SplitRendBFIFileReader *splitRendBFIReader = NULL; + AudioFileReader *audioReader = NULL; + AudioFileWriter *audioWriter; + int32_t inBufferSize; + int32_t outBufferSize; + int32_t bitsBufferSize; + int16_t *inpInt16Buffer; + Word32 *inFloatBuffer_fx; + int16_t *outInt16Buffer; + Word32 *outFloatBuffer_fx; + uint8_t *bitsBufferData = NULL; + IVAS_REND_AudioBuffer inBuffer; + IVAS_REND_AudioBuffer outBuffer; + ISAR_POST_REND_BitstreamBuffer bitsBuffer; + SplitFileReadWrite *hSplitRendFileReadWrite; + char audioFilePath[FILENAME_MAX]; + int16_t numSamplesRead; + int16_t delayNumSamples = -1; + int16_t delayNumSamples_orig = 0; + int16_t zeroPad = 0; + int16_t zeroPadToWrite = 0; + int32_t delayTimeScale = 0; + int16_t i, numChannels; + ivas_error error = IVAS_ERR_OK; + bool splitBinNeedsNewFrame = true; + +#ifdef WMOPS + reset_wmops(); + reset_mem( USE_BYTES ); +#endif + + hSplitRendFileReadWrite = NULL; + bitsBuffer.bits = NULL; + bitsBuffer.config.bitsRead = 0; + bitsBuffer.config.bitsWritten = 0; + bitsBuffer.config.bufLenInBytes = 0; + bitsBuffer.config.codec = ISAR_SPLIT_REND_CODEC_DEFAULT; + bitsBuffer.config.poseCorrection = ISAR_SPLIT_REND_POSE_CORRECTION_MODE_NONE; +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + bitsBuffer.config.codec_frame_size_ms = 5; + bitsBuffer.config.isar_frame_size_ms = 20; + bitsBuffer.config.lc3plusHighRes = 0; +#else + bitsBuffer.config.codec_frame_size_ms = 20; +#endif + + + CmdlnArgs args = parseCmdlnArgs( argc, argv ); + + convert_backslash( args.inputFilePath ); + convert_backslash( args.outputFilePath ); + convert_backslash( args.headRotationFilePath ); + + if ( !isEmptyString( args.headRotationFilePath ) ) + { + if ( RotationFileReader_open( args.headRotationFilePath, &headRotReader ) != IVAS_ERR_OK ) + { + fprintf( stderr, "Error opening file: %s\n", args.headRotationFilePath ); + exit( -1 ); + } + } + + if ( !isEmptyString( args.splitRendBFIFilePath ) ) + { + convert_backslash( args.splitRendBFIFilePath ); + SplitRendBFIFileReader_open( args.splitRendBFIFilePath, &splitRendBFIReader ); + } + +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + int32_t inFileSampleRate = 0; +#endif + strncpy( audioFilePath, args.inputFilePath, FILENAME_MAX - 1 ); + hSplitRendFileReadWrite = NULL; + if ( ( args.inConfig.numBinBuses > 0 ) && ( args.inConfig.binBuses[0].audioConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ) + { + error = split_rend_reader_open( &hSplitRendFileReadWrite, + args.inMetadataFilePaths[0], + &bitsBuffer.config.codec, + &bitsBuffer.config.poseCorrection, + &bitsBuffer.config.codec_frame_size_ms +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + , + &bitsBuffer.config.isar_frame_size_ms, + &inFileSampleRate, + &bitsBuffer.config.lc3plusHighRes +#endif + ); + if ( error != IVAS_ERR_OK ) + { + fprintf( stderr, "Could not open split rend metadata file %s\n", args.inMetadataFilePaths[0] ); + exit( -1 ); + } + + if ( AudioFileReader_open( &audioReader, audioFilePath ) != IVAS_ERR_OK ) + { + fprintf( stderr, "Error opening file: %s\n", audioFilePath ); + exit( -1 ); + } + } + + /*if split renderer is running in post renderer mode*/ + if ( ( args.inConfig.numBinBuses > 0 ) && ( args.inConfig.binBuses[0].audioConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) ) + { + error = split_rend_reader_open( &hSplitRendFileReadWrite, + args.inputFilePath, + &bitsBuffer.config.codec, + &bitsBuffer.config.poseCorrection, + &bitsBuffer.config.codec_frame_size_ms +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + , + &bitsBuffer.config.isar_frame_size_ms, + &inFileSampleRate, + &bitsBuffer.config.lc3plusHighRes +#endif + ); + if ( error != IVAS_ERR_OK ) + { + fprintf( stderr, "Could not open split rend metadata file %s\n", args.inputFilePath ); + exit( -1 ); + } + audioReader = NULL; + } + +#ifndef ISAR_BITSTREAM_UPDATE_LC3PLUS + int32_t inFileSampleRate = 0; +#endif + if ( audioReader != NULL ) + { + error = AudioFileReader_getSamplingRate( audioReader, &inFileSampleRate ); + } + else +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + if ( hSplitRendFileReadWrite == NULL ) +#endif + { + inFileSampleRate = args.sampleRate; + } + + switch ( error ) + { + case IVAS_ERR_OK: + /* If sampling rate not given on command line, use the one from SR file */ + if ( args.sampleRate == 0 ) + { + args.sampleRate = inFileSampleRate; + } + /* else if sampling rate given on command line, compare with wav file */ + else if ( inFileSampleRate != args.sampleRate ) + { + fprintf( stderr, "Sampling rate mismatch: %d Hz requested, but %d Hz found in file %s\n", args.sampleRate, inFileSampleRate, args.inputFilePath ); + exit( -1 ); + } + break; + case IVAS_ERR_SAMPLING_RATE_UNKNOWN: /* Returned when input is raw PCM */ + if ( args.sampleRate == 0 ) + { + fprintf( stderr, "Sampling rate must be specified on command line when using raw PCM input\n" ); + exit( -1 ); + } + break; + default: + fprintf( stderr, "Error: %s\n", ivas_error_to_string( error ) ); + exit( -1 ); + } + + int16_t inFileNumChannels = 0; + if ( audioReader != NULL ) + { + error = AudioFileReader_getNumChannels( audioReader, &inFileNumChannels ); + if ( error != IVAS_ERR_OK && error != IVAS_ERR_NUM_CHANNELS_UNKNOWN ) + { + fprintf( stderr, "Error: %s\n", ivas_error_to_string( error ) ); + exit( -1 ); + } + } + const int16_t frameSize_smpls = (int16_t) ( ( args.render_framesize ) * args.sampleRate * 5 / ( 1000 ) ); + args.outConfig.audioConfig = IVAS_AUDIO_CONFIG_BINAURAL; + if ( ( error = ISAR_POST_REND_open( &hIsarPostRend, args.sampleRate, args.outConfig.audioConfig, true, 0, 0, (int16_t) args.render_framesize ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "Error opening renderer handle: %s\n", ivas_error_to_string( error ) ); + exit( -1 ); + } + + /* === Configure === */ + if ( ( error = ISAR_POST_REND_InitConfig( hIsarPostRend, args.outConfig.audioConfig ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "Error in Renderer Config Init: %s\n", ivas_error_to_string( error ) ); + exit( -1 ); + } + + if ( args.inConfig.numBinBuses > 0 ) + { + if ( ( error = ISAR_REND_SetSplitRendBitstreamHeader( hIsarPostRend, + bitsBuffer.config.codec, + bitsBuffer.config.poseCorrection, + bitsBuffer.config.codec_frame_size_ms +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + , + bitsBuffer.config.isar_frame_size_ms, + bitsBuffer.config.lc3plusHighRes +#endif + ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "Error in getting split renderer bitstream header: %s\n", ivas_error_to_string( error ) ); + exit( -1 ); + } + } + + + ISAR_POST_REND_InputId splitBinIds[RENDERER_MAX_BIN_INPUTS]; + + for ( i = 0; i < RENDERER_MAX_BIN_INPUTS; i++ ) + { + splitBinIds[i] = 0u; + } + + for ( i = 0; i < args.inConfig.numBinBuses; ++i ) + { + if ( ( error = ISAR_POST_REND_AddInput( hIsarPostRend, args.inConfig.binBuses[i].audioConfig, &splitBinIds[i] ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "Error: %s\n", ivas_error_to_string( error ) ); + exit( -1 ); + } + } + + const int16_t totalNumInChannels = getTotalNumInChannels( hIsarPostRend, splitBinIds ); + + if ( inFileNumChannels != 0 /* inFileNumChannels is 0 with raw PCM input */ && totalNumInChannels != inFileNumChannels ) + { + fprintf( stderr, "Number of channels in input file does not match selected configuration\n" ); + exit( -1 ); + } + + int16_t numOutChannels = 2; + + if ( AudioFileWriter_open( &audioWriter, args.outputFilePath, args.sampleRate, numOutChannels ) != IVAS_ERR_OK ) + { + fprintf( stderr, "Failed to open file: %s\n", args.outputFilePath ); + exit( -1 ); + } + + inBufferSize = frameSize_smpls * totalNumInChannels; + outBufferSize = frameSize_smpls * numOutChannels; + inpInt16Buffer = malloc( inBufferSize * sizeof( int16_t ) ); + memset( inpInt16Buffer, 0, inBufferSize * sizeof( int16_t ) ); + + inFloatBuffer_fx = malloc( inBufferSize * sizeof( Word32 ) ); + inBuffer.config.numSamplesPerChannel = (int16_t) frameSize_smpls; + outFloatBuffer_fx = malloc( outBufferSize * sizeof( Word32 ) ); + outBuffer.config.numSamplesPerChannel = (int16_t) frameSize_smpls; + + outInt16Buffer = malloc( outBufferSize * sizeof( int16_t ) ); + + inBuffer.config.is_cldfb = 0; + inBuffer.config.numChannels = (int16_t) totalNumInChannels; + inBuffer.data_fx = inFloatBuffer_fx; + inBuffer.pq_fact = malloc( sizeof( Word16 ) ); + + outBuffer.config.is_cldfb = 0; + outBuffer.config.numChannels = (int16_t) numOutChannels; + outBuffer.data_fx = outFloatBuffer_fx; + outBuffer.pq_fact = malloc( sizeof( Word16 ) ); + + memset( outBuffer.data_fx, 0, outBuffer.config.numSamplesPerChannel * outBuffer.config.numChannels * sizeof( Word32 ) ); + + bitsBufferSize = SPLIT_REND_BITS_BUFF_SIZE; + + if ( bitsBufferSize > 0 ) + { + bitsBufferData = malloc( bitsBufferSize * sizeof( uint8_t ) ); + } + else + { + bitsBufferData = NULL; + } + + bitsBuffer.bits = bitsBufferData; + bitsBuffer.config.bitsRead = 0; + bitsBuffer.config.bitsWritten = 0; + bitsBuffer.config.bufLenInBytes = bitsBufferSize; + +#ifdef WMOPS + reset_stack(); + reset_wmops(); +#endif + + if ( !args.quietModeEnabled ) + { + fprintf( stdout, "\n------ Running the ISAR post renderer ------\n\n" ); + fprintf( stdout, "Frames processed: " ); + } + else + { + fprintf( stdout, "\n\n-- Start the ISAR post renderer (quiet mode) --\n\n" ); + } + + while ( 1 ) + { + int16_t num_in_channels; + num_in_channels = inBuffer.config.numChannels; + + numSamplesRead = 0; + if ( ( hSplitRendFileReadWrite != NULL ) && splitBinNeedsNewFrame ) + { + ivas_error error_tmp; + numSamplesRead = (int16_t) inBufferSize; + error_tmp = split_rend_read_bits_from_file( hSplitRendFileReadWrite, bitsBuffer.bits, &bitsBuffer.config.bitsRead, &bitsBuffer.config.bitsWritten ); + if ( error_tmp != IVAS_ERR_OK ) + { + if ( error_tmp == IVAS_ERR_END_OF_FILE ) + { + numSamplesRead = 0; + } + else + { + fprintf( stderr, "\nUnable to read from bitstream file!\n" ); + exit( -1 ); + } + } + } + + if ( audioReader != NULL ) + { + /* Read the input data */ + if ( ( error = AudioFileReader_read( audioReader, inpInt16Buffer, (int16_t) inBufferSize, &numSamplesRead ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nError reading from file %s\n", audioFilePath ); + exit( -1 ); + } + } + + if ( numSamplesRead == 0 && splitBinNeedsNewFrame ) + { + /* end of input data */ + break; + } + + /* Convert from int to float and from interleaved to packed */ + convertInputBuffer( inpInt16Buffer, numSamplesRead, inBuffer.config.numSamplesPerChannel, num_in_channels, inFloatBuffer_fx ); + *inBuffer.pq_fact = 0; + int16_t num_subframes, sf_idx; + num_subframes = (int16_t) args.render_framesize; + + /* Read from head rotation trajectory file if specified */ + if ( headRotReader != NULL ) + { + for ( sf_idx = 0; sf_idx < num_subframes; sf_idx++ ) + { + IVAS_QUATERNION headRot; + IVAS_VECTOR3 Pos; + + IF( ( error = HeadRotationFileReading( headRotReader, &headRot, &Pos ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "Error in Head Rotation File Reading: %s\n", ivas_error_to_string( error ) ); + exit( -1 ); + } + + if ( ( error = ISAR_POST_REND_SetHeadRotation( hIsarPostRend, headRot, Pos, DEFAULT_AXIS, sf_idx ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "Error setting Head Rotation: %s\n", ivas_error_to_string( error ) ); + exit( -1 ); + } + } + } + else + { + fprintf( stderr, "Head Rotation should be enabled in post renderer\n" ); + exit( -1 ); + } + + /* Read from split renderer bfi file if specified */ + if ( splitRendBFIReader != NULL && splitBinNeedsNewFrame ) + { + int16_t bfi; + if ( ( error = SplitRendBFIFileReading( splitRendBFIReader, &bfi ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "Error in SplitRendBFIFileReading(): %s\n", ivas_error_to_string( error ) ); + exit( -1 ); + } + + if ( ( error = ISAR_POST_REND_SetSplitRendBFI( hIsarPostRend, bfi ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "Error in ISAR_POST_REND_SetSplitRendBFI(): %s\n", ivas_error_to_string( error ) ); + exit( -1 ); + } + } + + for ( i = 0; i < args.inConfig.numBinBuses; ++i ) + { + if ( numSamplesRead > 0 ) + { + if ( ( error = ISAR_POST_REND_GetInputNumChannels( hIsarPostRend, splitBinIds[i], &numChannels ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "Error: %s\n", ivas_error_to_string( error ) ); + exit( -1 ); + } + ISAR_POST_REND_ReadOnlyAudioBuffer tmpBuffer = getReadOnlySubBuffer( inBuffer, (int16_t) args.inConfig.binBuses[i].inputChannelIndex, numChannels ); + + if ( ( error = ISAR_POST_REND_FeedInputAudio( hIsarPostRend, splitBinIds[i], tmpBuffer ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "Error: %s\n", ivas_error_to_string( error ) ); + exit( -1 ); + } + } + if ( splitBinNeedsNewFrame ) + { + if ( ( error = ISAR_POST_REND_FeedSplitBinauralBitstream( hIsarPostRend, splitBinIds[i], &bitsBuffer ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "Error: %s\n", ivas_error_to_string( error ) ); + exit( -1 ); + } + } + } + + if ( ( error = ISAR_POST_REND_GetSplitBinauralSamples( hIsarPostRend, outBuffer, &splitBinNeedsNewFrame ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "Error: %s\n", ivas_error_to_string( error ) ); + exit( -1 ); + } + + int16_t num_out_channels; + num_out_channels = outBuffer.config.numChannels; + + /* Convert from float to int and from packed to interleaved. + * Values in outFloatBuffer are guaranteed to be within range INT16_MIN:INT16_MAX */ + convertOutputBuffer( outFloatBuffer_fx, *outBuffer.pq_fact, outBuffer.config.numSamplesPerChannel, num_out_channels, outInt16Buffer ); + + if ( delayNumSamples == -1 ) + { + if ( args.delayCompensationEnabled ) + { + if ( ISAR_POST_REND_GetDelay( hIsarPostRend, &delayNumSamples, &delayTimeScale ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nUnable to get delay of renderer!\n" ); + exit( -1 ); + } + + if ( hSplitRendFileReadWrite != NULL ) + { + uint32_t pre_rend_delay_ns; + split_rend_read_pre_rend_delay_ns( hSplitRendFileReadWrite, &pre_rend_delay_ns ); + delayNumSamples += (Word16) ( ( ( (Word64) pre_rend_delay_ns * delayTimeScale ) + 500000000 ) / 1000000000 ); + } + + delayNumSamples_orig = delayNumSamples; + } + else + { + delayNumSamples = 0; + } + zeroPad = delayNumSamples; + } + + if ( audioWriter != NULL ) + { + if ( delayNumSamples * num_out_channels < outBufferSize ) + { + if ( AudioFileWriter_write( audioWriter, &outInt16Buffer[delayNumSamples * num_out_channels], outBufferSize - ( delayNumSamples * num_out_channels ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "Error writing audio file %s\n", args.outputFilePath ); + exit( -1 ); + } + delayNumSamples = 0; + } + else + { + delayNumSamples -= (int16_t) ( outBufferSize / num_out_channels ); + } + } + + bitsBuffer.config.bitsRead = 0; + bitsBuffer.config.bitsWritten = 0; + + frame++; + if ( !args.quietModeEnabled ) + { + fprintf( stdout, "%-8d\b\b\b\b\b\b\b\b", frame ); + } + +#ifdef WMOPS + update_mem(); + update_wmops(); +#endif + } + + /* add zeros at the end to have equal length of synthesized signals */ + if ( audioWriter != NULL ) + { + for ( zeroPadToWrite = zeroPad; zeroPadToWrite > frameSize_smpls; zeroPadToWrite -= frameSize_smpls ) + { + memset( outInt16Buffer, 0, outBufferSize * sizeof( int16_t ) ); + if ( ( error = AudioFileWriter_write( audioWriter, outInt16Buffer, outBufferSize ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nOutput audio file writer error\n" ); + exit( -1 ); + } + } + + memset( outInt16Buffer, 0, zeroPadToWrite * outBuffer.config.numChannels * sizeof( int16_t ) ); + if ( ( error = AudioFileWriter_write( audioWriter, outInt16Buffer, zeroPadToWrite * outBuffer.config.numChannels ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nOutput audio file writer error\n" ); + exit( -1 ); + } + zeroPadToWrite = 0; + } + + if ( !args.quietModeEnabled && args.delayCompensationEnabled ) + { + fprintf( stdout, "\nRenderer delay: %-5u [samples] - Timescale: %5u\n", delayNumSamples_orig, delayTimeScale ); + } + + fprintf( stdout, "\n\nRendering of %d frames finished\n\n", frame ); + +#ifdef DEBUGGING + int32_t cnt_frames_limited, noClipping; + if ( ( cnt_frames_limited = ISAR_POST_REND_GetCntFramesLimited( hIsarPostRend ) ) > 0 ) + { + fprintf( stdout, "Limiter applied in %d frames.\n\n", cnt_frames_limited ); + } + if ( ( noClipping = ISAR_POST_REND_GetNoCLipping( hIsarPostRend ) ) > 0 ) + { + fprintf( stdout, "Clipping (saturation) detected: %d samples clipped!!!\n\n", noClipping ); + } +#endif + + /* === Close === */ + free( inpInt16Buffer ); + free( inFloatBuffer_fx ); + free( inBuffer.pq_fact ); + free( outInt16Buffer ); + free( outFloatBuffer_fx ); + free( outBuffer.pq_fact ); + + if ( bitsBufferData != NULL ) + { + free( bitsBufferData ); + } + + split_rend_reader_writer_close( &hSplitRendFileReadWrite ); + SplitRendBFIFileReader_close( &splitRendBFIReader ); + + AudioFileReader_close( &audioReader ); + AudioFileWriter_close( &audioWriter ); + RotationFileReader_close( &headRotReader ); + RotationFileReader_close( &externalOrientationFileReader ); + + ISAR_POST_REND_Close( &hIsarPostRend ); + +#ifdef DEBUGGING + dbgclose(); +#endif +#ifdef WMOPS + print_wmops(); + print_mem( NULL ); +#endif + + return 0; +} + + +#undef WMC_TOOL_SKIP + +#endif /* SPLIT_REND_WITH_HEAD_ROT */ diff --git a/apps/renderer.c b/apps/renderer.c index 44ed320adee991ab4ce37f040724affb9ffab334..0ee2ac94dc0d4d26b8e8ea5ad71132b9c27addde 100644 --- a/apps/renderer.c +++ b/apps/renderer.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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,10 +45,13 @@ #include "masa_file_writer.h" #include "render_config_reader.h" #include "rotation_file_reader.h" +#ifdef SPLIT_REND_WITH_HEAD_ROT +#include "split_render_file_read_write.h" +#include "split_rend_bfi_file_reader.h" +#endif #include "vector3_pair_file_reader.h" #include "wmc_auto.h" -#include "prot_fx.h" #define WMC_TOOL_SKIP @@ -56,11 +59,15 @@ * Local constants *------------------------------------------------------------------------------------------*/ +#define Q15 15 +#define Q22 22 +#define Q31 31 +#define ONE_IN_Q31 0x7fffffff + #define RENDERER_MAX_CLI_ARG_LENGTH ( FILENAME_MAX ) #define RENDERER_MAX_METADATA_LENGTH 8192 #define RENDERER_MAX_METADATA_LINE_LENGTH 1024 - #define IVAS_MAX16B_FLT 32767.0f #define IVAS_MIN16B_FLT ( -32768.0f ) #define IVAS_MAX16B_FX 32767 @@ -148,7 +155,13 @@ typedef struct OutputConfig outConfig; char inMetadataFilePaths[RENDERER_MAX_ISM_INPUTS][RENDERER_MAX_CLI_ARG_LENGTH]; int16_t numInMetadataFiles; +#ifdef SPLIT_REND_WITH_HEAD_ROT + char outMetadataFilePath[RENDERER_MAX_CLI_ARG_LENGTH]; +#endif char headRotationFilePath[RENDERER_MAX_CLI_ARG_LENGTH]; +#ifdef SPLIT_REND_WITH_HEAD_ROT + char splitRendBFIFilePath[RENDERER_MAX_CLI_ARG_LENGTH]; +#endif char referenceVectorFilePath[RENDERER_MAX_CLI_ARG_LENGTH]; char referenceRotationFilePath[RENDERER_MAX_CLI_ARG_LENGTH]; char externalOrientationFilePath[RENDERER_MAX_CLI_ARG_LENGTH]; @@ -195,6 +208,10 @@ typedef enum CmdLnOptionId_inputMetadata, CmdLnOptionId_listFormats, CmdLnOptionId_inputGain, +#ifdef SPLIT_REND_WITH_HEAD_ROT + CmdLnOptionId_outputMetadata, + CmdLnOptionId_SplitRendBFIFile, +#endif CmdLnOptionId_referenceVectorFile, CmdLnOptionId_exteriorOrientationFile, CmdLnOptionId_framing, @@ -220,7 +237,11 @@ static const CmdLnParser_Option cliOptions[] = { .id = CmdLnOptionId_inputMetadata, .match = "input_metadata", .matchShort = "im", +#ifdef SPLIT_REND_WITH_HEAD_ROT + .description = "Space-separated list of path to metadata files for ISM or MASA inputs or BINAURAL_SPLIT_PCM input mode", +#else .description = "Space-separated list of path to metadata files for ISM or MASA inputs", +#endif }, { .id = CmdLnOptionId_outputFile, @@ -246,6 +267,20 @@ static const CmdLnParser_Option cliOptions[] = { .matchShort = "T", .description = "Head rotation trajectory file for simulation of head tracking (only for binaural outputs)", }, +#ifdef SPLIT_REND_WITH_HEAD_ROT + { + .id = CmdLnOptionId_outputMetadata, + .match = "output_metadata", + .matchShort = "om", + .description = "coded metadata file for BINAURAL_SPLIT_PCM output mode", + }, + { + .id = CmdLnOptionId_SplitRendBFIFile, + .match = "post_rend_bfi_file", + .matchShort = "prbfi", + .description = "Split rendering option: bfi file", + }, +#endif { .id = CmdLnOptionId_refRotFile, .match = "reference_rotation_file", @@ -403,11 +438,44 @@ static void printSupportedAudioConfigs( void ); static IVAS_AUDIO_CONFIG parseAudioConfig( const char *configString ); +#ifdef SPLIT_REND_WITH_HEAD_ROT +static void convertOutputBuffer_fx( + const Word32 *Word32Buffer, + const Word16 numSamplesPerChannel, + const Word16 numChannels, +#ifdef SPLIT_REND_WITH_HEAD_ROT + Word16 *intBuffer, + const Word16 cldfb_in_flag, + IVAS_CLDFB_FILTER_BANK_HANDLE *cldfbSyn, + Word16 out_q +#else + Word16 *intBuffer, + Word16 out_q +#endif +); +static void convertInputBuffer_fx( + const Word16 *intBuffer, + const Word16 numIntSamplesPerChannel, + const Word16 numFloatSamplesPerChannel, + const Word16 numChannels, +#ifdef SPLIT_REND_WITH_HEAD_ROT + Word32 *Word32Buffer, + Word16 in_q_factor, + const int16_t cldfb_in_flag, + IVAS_CLDFB_FILTER_BANK_HANDLE *cldfbAna, + Word16 *out_q_factor +#else + Word32 *Word32Buffer, + Word16 in_q_factor +#endif +); +#else static void convertInputBuffer( const int16_t *intBuffer, const int16_t numIntSamplesPerChannel, const int16_t numFloatSamplesPerChannel, const int16_t numChannels, float *floatBuffer ); static void convertOutputBuffer( const float *floatBuffer, const int16_t numSamplesPerChannel, const int16_t numChannels, int16_t *intBuffer ); static void convertOutputBuffer_fx( const Word32 *Word32Buffer, const Word16 numSamplesPerChannel, const Word16 numChannels, Word16 *intBuffer, Word16 q_factor ); static void convertInputBuffer_fx( const Word16 *intBuffer, const Word16 numIntSamplesPerChannel, const Word16 numFloatSamplesPerChannel, const Word16 numChannels, Word32 *Int32Buffer, Word16 in_q_factor ); +#endif /*------------------------------------------------------------------------------------------* @@ -428,6 +496,47 @@ static Word16 find_guard_bits( Word32 n ) : n <= 1024 ? 10 : 11; } + +static Word32 floatToFixed( float f, Word16 Q ) +{ + Word64 result_32; + + if ( f == 1.0f && Q == Q15 ) + return IVAS_MAX16B_FX; + if ( f == 1.0f && Q == Q31 ) + return MAXVAL_WORD32; + if ( Q < 0 ) + result_32 = (Word64) ( (float) ( f ) / (double) ( (unsigned Word64) 1 << ( -Q ) ) + ( f >= 0 ? 0.5 : -0.5 ) ); + else + result_32 = (Word64) ( f * (double) ( (unsigned Word64) 1 << Q ) + ( f >= 0 ? 0.5 : -0.5 ) ); + if ( result_32 > MAX_32 ) + return MAX_32; + if ( result_32 < MIN_32 ) + return MIN_32; + + return (Word32) result_32; +} + +/* note: This function is defined inside the library too with different name but same functionality */ +static void floatToFixed_arrL_app( float *f, Word32 *i, Word16 Q, Word16 l ) +{ + for ( int j = 0; j < l; j++ ) + { + Word64 i64_val = floatToFixed( f[j], Q ); + IF( i64_val > MAX_32 ) + { + i64_val = MAX_32; + } + ELSE IF( i64_val < MIN_32 ) + { + i64_val = MIN_32; + } + i[j] = (Word32) i64_val; + } + + return; +} + static IVAS_REND_ReadOnlyAudioBuffer getReadOnlySubBuffer( IVAS_REND_AudioBuffer buffer, const Word16 chBeginIdx, @@ -593,6 +702,44 @@ static float dBToLin( } +#ifdef SPLIT_REND_WITH_HEAD_ROT +static int16_t get_cldfb_in_flag( + const IVAS_AUDIO_CONFIG audioConfig, + const IVAS_RENDER_CONFIG_DATA *renderConfig ) +{ + int16_t cldfb_in_flag; + + cldfb_in_flag = 0; + if ( renderConfig->split_rend_config.rendererSelection == ISAR_SPLIT_REND_RENDERER_SELECTION_FASTCONV ) + { +#ifdef DEBUGGING + cldfb_in_flag = 1; +#endif + if ( audioConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) + { + cldfb_in_flag = 1; + } + } + + return cldfb_in_flag; +} + +static int16_t is_split_pre_rend_mode( + CmdlnArgs *args ) +{ + int16_t flag; + + flag = 0; + if ( args->outConfig.audioConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || args->outConfig.audioConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) + { + flag = 1; + } + + return flag; +} +#endif + + /*------------------------------------------------------------------------------------------* * main() * @@ -607,6 +754,12 @@ int main( RotFileReader *headRotReader = NULL; RotFileReader *externalOrientationFileReader = NULL; RotFileReader *referenceRotReader = NULL; +#ifdef SPLIT_REND_WITH_HEAD_ROT + IVAS_CLDFB_FILTER_BANK_HANDLE cldfbAna[IVAS_MAX_INPUT_CHANNELS]; + IVAS_CLDFB_FILTER_BANK_HANDLE cldfbSyn[IVAS_MAX_INPUT_CHANNELS]; + int16_t cldfb_in_flag, CLDFBframeSize_smpls; + SplitRendBFIFileReader *splitRendBFIReader = NULL; +#endif Vector3PairFileReader *referenceVectorReader = NULL; hrtfFileReader *hrtfFileReader = NULL; IsmPositionProvider *positionProvider; @@ -620,6 +773,9 @@ int main( AudioFileWriter *audioWriter; int32_t inBufferSize; int32_t outBufferSize; +#ifdef SPLIT_REND_WITH_HEAD_ROT + int32_t bitsBufferSize; +#endif int16_t *inpInt16Buffer; float *inFloatBuffer; int16_t *outInt16Buffer; @@ -627,8 +783,17 @@ int main( Word32 *inInt32Buffer; Word32 gain_fx; float *outFloatBuffer; +#ifdef SPLIT_REND_WITH_HEAD_ROT + uint8_t *bitsBufferData = NULL; +#endif IVAS_REND_AudioBuffer inBuffer; IVAS_REND_AudioBuffer outBuffer; +#ifdef SPLIT_REND_WITH_HEAD_ROT + IVAS_REND_BitstreamBuffer bitsBuffer; + SplitFileReadWrite *hSplitRendFileReadWrite; + int16_t delayNumSamples_temp; + int32_t delayTimeScale_temp; +#endif int16_t numSamplesRead; int16_t delayNumSamples = -1; int16_t delayNumSamples_orig = 0; @@ -637,7 +802,6 @@ int main( int32_t delayTimeScale = 0; int16_t i, numChannels; ivas_error error = IVAS_ERR_OK; - bool splitBinNeedsNewFrame = true; #ifdef WMOPS reset_wmops(); @@ -650,11 +814,33 @@ int main( hMasaMetadata[i] = NULL; } +#ifdef SPLIT_REND_WITH_HEAD_ROT + hSplitRendFileReadWrite = NULL; + CLDFBframeSize_smpls = 0; + cldfb_in_flag = 0; + bitsBuffer.bits = NULL; + bitsBuffer.config.bitsRead = 0; + bitsBuffer.config.bitsWritten = 0; + bitsBuffer.config.bufLenInBytes = 0; + bitsBuffer.config.codec = ISAR_SPLIT_REND_CODEC_DEFAULT; + bitsBuffer.config.poseCorrection = ISAR_SPLIT_REND_POSE_CORRECTION_MODE_NONE; +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + bitsBuffer.config.codec_frame_size_ms = 5; + bitsBuffer.config.isar_frame_size_ms = 20; + bitsBuffer.config.lc3plus_highres = 0; +#else + bitsBuffer.config.codec_frame_size_ms = 20; +#endif +#endif for ( i = 0; i < RENDERER_MAX_MC_INPUTS; ++i ) { lfeRoutingConfigs[i] = NULL; } +#ifdef FIX_DISCLAIMER + IVAS_REND_PrintDisclaimer(); + +#endif CmdlnArgs args = parseCmdlnArgs( argc, argv ); if ( args.nonDiegeticPan && !( ( args.inConfig.numAudioObjects == 0 && args.inConfig.multiChannelBuses[0].audioConfig == IVAS_AUDIO_CONFIG_MONO ) || @@ -706,6 +892,13 @@ int main( } } +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( !isEmptyString( args.splitRendBFIFilePath ) ) + { + convert_backslash( args.splitRendBFIFilePath ); + SplitRendBFIFileReader_open( args.splitRendBFIFilePath, &splitRendBFIReader ); + } +#endif if ( !isEmptyString( args.externalOrientationFilePath ) ) { if ( RotationFileReader_open( args.externalOrientationFilePath, &externalOrientationFileReader ) != IVAS_ERR_OK ) @@ -816,6 +1009,50 @@ int main( exit( -1 ); } +#ifdef FIX_DISCLAIMER + fprintf( stdout, "Input audio file: %s\n", args.inputFilePath ); + fprintf( stdout, "Output audio file: %s\n\n", args.outputFilePath ); + + if ( args.inConfig.numAudioObjects > 0 ) + { + if ( args.inConfig.numAudioObjects == 1 ) + { + IVAS_REND_PrintInputConfig( IVAS_AUDIO_CONFIG_ISM1 ); + } + else if ( args.inConfig.numAudioObjects == 2 ) + { + IVAS_REND_PrintInputConfig( IVAS_AUDIO_CONFIG_ISM2 ); + } + else if ( args.inConfig.numAudioObjects == 3 ) + { + IVAS_REND_PrintInputConfig( IVAS_AUDIO_CONFIG_ISM3 ); + } + else if ( args.inConfig.numAudioObjects == 4 ) + { + IVAS_REND_PrintInputConfig( IVAS_AUDIO_CONFIG_ISM4 ); + } + } + for ( i = 0; i < args.inConfig.numMultiChannelBuses; i++ ) + { + IVAS_REND_PrintInputConfig( args.inConfig.multiChannelBuses[i].audioConfig ); + } + for ( i = 0; i < args.inConfig.numMasaBuses; i++ ) + { + IVAS_REND_PrintInputConfig( args.inConfig.masaBuses[i].audioConfig ); + } + for ( i = 0; i < args.inConfig.numAmbisonicsBuses; i++ ) + { + IVAS_REND_PrintInputConfig( args.inConfig.ambisonicsBuses[i].audioConfig ); + } + + if ( ( error = IVAS_REND_PrintConfig( hIvasRend ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\n IVAS_REND_PrintConfig failed: %s\n\n", ivas_error_to_string( error ) ); + // goto cleanup; + exit( -1 ); + } + +#endif /* === Configure === */ if ( ( error = IVAS_REND_InitConfig( hIvasRend, args.outConfig.audioConfig ) ) != IVAS_ERR_OK ) { @@ -829,16 +1066,28 @@ int main( IVAS_RENDER_CONFIG_DATA renderConfig; /* sanity check */ +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( ( args.outConfig.audioConfig != IVAS_AUDIO_CONFIG_BINAURAL ) && ( args.outConfig.audioConfig != IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR ) && ( args.outConfig.audioConfig != IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) && !is_split_pre_rend_mode( &args ) ) + { + fprintf( stderr, "\nExternal Renderer Config is supported only when binaural output configurations is used as output OR when Split pre-rendering mode is enabled. Exiting. \n" ); + exit( -1 ); + } +#else if ( ( args.outConfig.audioConfig != IVAS_AUDIO_CONFIG_BINAURAL ) && ( args.outConfig.audioConfig != IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR ) && ( args.outConfig.audioConfig != IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) ) { fprintf( stderr, "\nExternal Renderer Config is only supported for binaural output configurations. Exiting. \n" ); exit( -1 ); } +#endif if ( ( error = IVAS_REND_GetRenderConfig( hIvasRend, &renderConfig ) ) != IVAS_ERR_OK ) { +#ifdef SPLIT_REND_WITH_HEAD_ROT + fprintf( stderr, "\nIVAS_DEC_GetRenderConfig failed: %s\n", ivas_error_to_string( error ) ); +#else fprintf( stderr, "\nIVAS_DEC_GetRenderConfig failed\n" ); +#endif exit( -1 ); } @@ -866,11 +1115,28 @@ int main( renderConfig.roomAcoustics.override = 1; } +#ifdef SPLIT_REND_WITH_HEAD_ROT +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + /* ISAR frame size is set from command line, not renderer config file. + * This will be ignored if output format is not split rendering. */ + renderConfig.split_rend_config.isar_frame_size_ms = (int16_t) args.render_framesize /* given in number of 5ms subframes */ * 5; +#endif +#endif + if ( ( error = IVAS_REND_FeedRenderConfig( hIvasRend, renderConfig ) ) != IVAS_ERR_OK ) { +#ifdef SPLIT_REND_WITH_HEAD_ROT + fprintf( stderr, "\nIVAS_REND_FeedRenderConfig failed: %s\n", ivas_error_to_string( error ) ); +#else fprintf( stderr, "\nIVAS_DEC_FeedRenderConfig failed\n" ); +#endif exit( -1 ); } + +#ifdef SPLIT_REND_WITH_HEAD_ROT + CLDFBframeSize_smpls = frameSize_smpls * 2; + cldfb_in_flag = get_cldfb_in_flag( args.outConfig.audioConfig, &renderConfig ); +#endif } if ( ( error = IVAS_REND_SetOrientationTrackingMode( hIvasRend, args.orientation_tracking ) ) != IVAS_ERR_OK ) @@ -882,8 +1148,8 @@ int main( /* Set up output custom layout configuration */ if ( args.outConfig.audioConfig == IVAS_AUDIO_CONFIG_LS_CUSTOM ) { - floatToFixed_arrL( args.outConfig.outSetupCustom.azimuth, args.outConfig.outSetupCustom.azimuth_fx, Q22, IVAS_MAX_OUTPUT_CHANNELS ); - floatToFixed_arrL( args.outConfig.outSetupCustom.elevation, args.outConfig.outSetupCustom.elevation_fx, Q22, IVAS_MAX_OUTPUT_CHANNELS ); + floatToFixed_arrL_app( args.outConfig.outSetupCustom.azimuth, args.outConfig.outSetupCustom.azimuth_fx, Q22, IVAS_MAX_OUTPUT_CHANNELS ); + floatToFixed_arrL_app( args.outConfig.outSetupCustom.elevation, args.outConfig.outSetupCustom.elevation_fx, Q22, IVAS_MAX_OUTPUT_CHANNELS ); if ( ( error = IVAS_REND_ConfigureCustomOutputLoudspeakerLayout( hIvasRend, args.outConfig.outSetupCustom ) ) != IVAS_ERR_OK ) { fprintf( stderr, "Error in IVAS_REND_ConfigureCustomOutputLoudspeakerLayout(): %s\n", ivas_error_to_string( error ) ); @@ -970,8 +1236,8 @@ int main( if ( args.inConfig.multiChannelBuses[i].audioConfig == IVAS_AUDIO_CONFIG_LS_CUSTOM ) { - floatToFixed_arrL( args.inConfig.inSetupCustom.azimuth, args.inConfig.inSetupCustom.azimuth_fx, Q22, IVAS_MAX_OUTPUT_CHANNELS ); - floatToFixed_arrL( args.inConfig.inSetupCustom.elevation, args.inConfig.inSetupCustom.elevation_fx, Q22, IVAS_MAX_OUTPUT_CHANNELS ); + floatToFixed_arrL_app( args.inConfig.inSetupCustom.azimuth, args.inConfig.inSetupCustom.azimuth_fx, Q22, IVAS_MAX_OUTPUT_CHANNELS ); + floatToFixed_arrL_app( args.inConfig.inSetupCustom.elevation, args.inConfig.inSetupCustom.elevation_fx, Q22, IVAS_MAX_OUTPUT_CHANNELS ); if ( ( error = IVAS_REND_ConfigureCustomInputLoudspeakerLayout( hIvasRend, mcIds[i], args.inConfig.inSetupCustom ) ) != IVAS_ERR_OK ) { fprintf( stderr, "Error in IVAS_REND_ConfigureCustomInputLoudspeakerLayout(): %s\n", ivas_error_to_string( error ) ); @@ -1125,17 +1391,173 @@ int main( exit( -1 ); } +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( cldfb_in_flag ) + { + if ( ( error = IVAS_REND_openCldfb( cldfbAna, cldfbSyn, totalNumInChannels, numOutChannels, args.sampleRate ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "Error in IVAS_REND_openCldfb(): %s\n", ivas_error_to_string( error ) ); + exit( -1 ); + } + } - if ( AudioFileWriter_open( &audioWriter, args.outputFilePath, args.sampleRate, numOutChannels ) != IVAS_ERR_OK ) + if ( args.outConfig.audioConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) { - fprintf( stderr, "Failed to open file: %s\n", args.outputFilePath ); - exit( -1 ); + + IVAS_REND_GetSplitRendBitstreamHeader( hIvasRend, + &bitsBuffer.config.codec, + &bitsBuffer.config.poseCorrection, + &bitsBuffer.config.codec_frame_size_ms +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + , + &bitsBuffer.config.isar_frame_size_ms +#endif + ); + + if ( IVAS_REND_GetDelay_fx( hIvasRend, &delayNumSamples_temp, &delayTimeScale_temp ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nUnable to get delay of renderer!\n" ); + exit( -1 ); + } + + if ( ( error = split_rend_writer_open( &hSplitRendFileReadWrite, + args.outputFilePath, + delayNumSamples_temp, + delayTimeScale_temp, + bitsBuffer.config.codec, + bitsBuffer.config.poseCorrection, + bitsBuffer.config.codec_frame_size_ms +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + , + bitsBuffer.config.isar_frame_size_ms, + args.sampleRate, + bitsBuffer.config.lc3plus_highres +#endif + ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "Could not open split rend metadata file %s\n", args.outputFilePath ); + exit( -1 ); + } + audioWriter = NULL; } + else + { + if ( args.outConfig.audioConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) + { + + IVAS_REND_GetSplitRendBitstreamHeader( hIvasRend, + &bitsBuffer.config.codec, + &bitsBuffer.config.poseCorrection, + &bitsBuffer.config.codec_frame_size_ms +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + , + &bitsBuffer.config.isar_frame_size_ms +#endif + ); + + if ( IVAS_REND_GetDelay_fx( hIvasRend, &delayNumSamples_temp, &delayTimeScale_temp ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nUnable to get delay of renderer!\n" ); + exit( -1 ); + } + + if ( ( error = split_rend_writer_open( &hSplitRendFileReadWrite, + args.outMetadataFilePath, + delayNumSamples_temp, + delayTimeScale_temp, + bitsBuffer.config.codec, + bitsBuffer.config.poseCorrection, + bitsBuffer.config.codec_frame_size_ms +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + , + bitsBuffer.config.isar_frame_size_ms, + args.sampleRate, + bitsBuffer.config.lc3plus_highres +#endif + ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "Could not open split rend metadata file %s\n", args.outMetadataFilePath ); + exit( -1 ); + } + } +#endif + + if ( AudioFileWriter_open( &audioWriter, args.outputFilePath, args.sampleRate, numOutChannels ) != IVAS_ERR_OK ) + { + fprintf( stderr, "Failed to open file: %s\n", args.outputFilePath ); + exit( -1 ); + } +#ifdef SPLIT_REND_WITH_HEAD_ROT + } +#endif inBufferSize = frameSize_smpls * totalNumInChannels; outBufferSize = frameSize_smpls * numOutChannels; inpInt16Buffer = malloc( inBufferSize * sizeof( int16_t ) ); +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( cldfb_in_flag == 0 ) + { + inFloatBuffer = malloc( inBufferSize * sizeof( float ) ); + outInt16Buffer = malloc( outBufferSize * sizeof( int16_t ) ); + outInt32Buffer = malloc( outBufferSize * sizeof( Word32 ) ); + inInt32Buffer = malloc( inBufferSize * sizeof( Word32 ) ); + outFloatBuffer = malloc( outBufferSize * sizeof( float ) ); + + inBuffer.config.numSamplesPerChannel = (int16_t) frameSize_smpls; + inBuffer.config.numChannels = (int16_t) totalNumInChannels; + + outBuffer.config.numSamplesPerChannel = (int16_t) frameSize_smpls; + outBuffer.config.numChannels = (int16_t) numOutChannels; + outBuffer.data_fx = outInt32Buffer; + inBuffer.data_fx = inInt32Buffer; + } + else + { + inFloatBuffer = malloc( CLDFBframeSize_smpls * totalNumInChannels * sizeof( float ) ); + outInt16Buffer = malloc( outBufferSize * sizeof( int16_t ) ); + outInt32Buffer = malloc( CLDFBframeSize_smpls * totalNumInChannels * sizeof( Word32 ) ); + inInt32Buffer = malloc( CLDFBframeSize_smpls * totalNumInChannels * sizeof( Word32 ) ); + outFloatBuffer = malloc( CLDFBframeSize_smpls * totalNumInChannels * sizeof( float ) ); + + inBuffer.config.numSamplesPerChannel = (int16_t) CLDFBframeSize_smpls; + inBuffer.config.numChannels = (int16_t) totalNumInChannels; + + outBuffer.config.numSamplesPerChannel = (int16_t) CLDFBframeSize_smpls; + outBuffer.config.numChannels = (int16_t) numOutChannels; + outBuffer.data_fx = outInt32Buffer; + inBuffer.data_fx = inInt32Buffer; + } + + inBuffer.config.is_cldfb = cldfb_in_flag; + outBuffer.config.is_cldfb = cldfb_in_flag; + + + memset( outBuffer.data_fx, 0, outBuffer.config.numSamplesPerChannel * outBuffer.config.numChannels * sizeof( Word32 ) ); + + if ( is_split_pre_rend_mode( &args ) ) + { + bitsBufferSize = SPLIT_REND_BITS_BUFF_SIZE; + } + else + { + bitsBufferSize = 0; + } + + if ( bitsBufferSize > 0 ) + { + bitsBufferData = malloc( bitsBufferSize * sizeof( uint8_t ) ); + } + else + { + bitsBufferData = NULL; + } + + bitsBuffer.bits = bitsBufferData; + bitsBuffer.config.bitsRead = 0; + bitsBuffer.config.bitsWritten = 0; + bitsBuffer.config.bufLenInBytes = bitsBufferSize; +#else inFloatBuffer = malloc( inBufferSize * sizeof( float ) ); outInt16Buffer = malloc( outBufferSize * sizeof( int16_t ) ); outInt32Buffer = malloc( outBufferSize * sizeof( Word32 ) ); @@ -1149,6 +1571,8 @@ int main( outBuffer.config.numChannels = (int16_t) numOutChannels; outBuffer.data_fx = outInt32Buffer; inBuffer.data_fx = inInt32Buffer; +#endif + #ifdef WMOPS reset_stack(); reset_wmops(); @@ -1174,6 +1598,8 @@ int main( num_in_channels = inBuffer.config.numChannels; const bool isCurrentFrameMultipleOf20ms = frame % ( 4 / args.render_framesize ) == 0; + numSamplesRead = 0; + /* Read the input data */ if ( ( error = AudioFileReader_read( audioReader, inpInt16Buffer, (int16_t) inBufferSize, &numSamplesRead ) ) != IVAS_ERR_OK ) { @@ -1181,16 +1607,23 @@ int main( exit( -1 ); } - if ( numSamplesRead == 0 && splitBinNeedsNewFrame ) + if ( numSamplesRead == 0 ) { /* end of input data */ break; } /* Convert from int to float and from interleaved to packed */ - convertInputBuffer( inpInt16Buffer, numSamplesRead, inBuffer.config.numSamplesPerChannel, num_in_channels, inFloatBuffer ); +#ifdef SPLIT_REND_WITH_HEAD_ROT + Word16 Q_out; + *outBuffer.pq_fact = 16 - ( gd_bits ); + convertInputBuffer_fx( inpInt16Buffer, numSamplesRead, inBuffer.config.numSamplesPerChannel, num_in_channels, inInt32Buffer, *outBuffer.pq_fact, inBuffer.config.is_cldfb, cldfbAna, &Q_out ); + *outBuffer.pq_fact = Q_out; +#else *outBuffer.pq_fact = 16 - ( gd_bits ); convertInputBuffer_fx( inpInt16Buffer, numSamplesRead, inBuffer.config.numSamplesPerChannel, num_in_channels, inInt32Buffer, *outBuffer.pq_fact ); +#endif + int16_t num_subframes, sf_idx; num_subframes = (int16_t) args.render_framesize; @@ -1247,7 +1680,11 @@ int main( exit( -1 ); } +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( ( error = IVAS_REND_SetHeadRotation( hIvasRend, headRot, Pos, DEFAULT_AXIS, sf_idx ) ) != IVAS_ERR_OK ) +#else if ( ( error = IVAS_REND_SetHeadRotation( hIvasRend, headRot, Pos, sf_idx ) ) != IVAS_ERR_OK ) +#endif { fprintf( stderr, "Error setting Head Rotation: %s\n", ivas_error_to_string( error ) ); exit( -1 ); @@ -1400,24 +1837,42 @@ int main( } } - if ( ( error = IVAS_REND_GetSamples( hIvasRend, outBuffer ) ) != IVAS_ERR_OK ) +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( args.outConfig.audioConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || args.outConfig.audioConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) { + if ( ( error = IVAS_REND_GetSplitBinauralBitstream( hIvasRend, outBuffer, &bitsBuffer ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "Error: %s\n", ivas_error_to_string( error ) ); + exit( -1 ); + } + } + else + { +#endif + if ( ( error = IVAS_REND_GetSamples( hIvasRend, outBuffer ) ) != IVAS_ERR_OK ) + { +#ifdef SPLIT_REND_WITH_HEAD_ROT + fprintf( stderr, "Error %s\n", ivas_error_to_string( error ) ); +#else fprintf( stderr, "Error in getting samples\n" ); - exit( -1 ); +#endif + exit( -1 ); + } +#ifdef SPLIT_REND_WITH_HEAD_ROT } +#endif int16_t num_out_channels; num_out_channels = outBuffer.config.numChannels; + /* Convert from float to int and from packed to interleaved. * Values in outFloatBuffer are guaranteed to be within range INT16_MIN:INT16_MAX */ - if ( *outBuffer.pq_fact == 0 ) - { - convertOutputBuffer( outFloatBuffer, outBuffer.config.numSamplesPerChannel, num_out_channels, outInt16Buffer ); - } - else - { - convertOutputBuffer_fx( outInt32Buffer, outBuffer.config.numSamplesPerChannel, num_out_channels, outInt16Buffer, *outBuffer.pq_fact ); - } +#ifdef SPLIT_REND_WITH_HEAD_ROT + convertOutputBuffer_fx( outInt32Buffer, outBuffer.config.numSamplesPerChannel, num_out_channels, outInt16Buffer, cldfb_in_flag, cldfbSyn, *outBuffer.pq_fact ); +#else + convertOutputBuffer_fx( outInt32Buffer, outBuffer.config.numSamplesPerChannel, num_out_channels, outInt16Buffer, *outBuffer.pq_fact ); +#endif + if ( delayNumSamples == -1 ) { if ( args.delayCompensationEnabled ) @@ -1438,20 +1893,42 @@ int main( zeroPad = delayNumSamples; } - if ( delayNumSamples * num_out_channels < outBufferSize ) +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( is_split_pre_rend_mode( &args ) ) { - if ( AudioFileWriter_write( audioWriter, &outInt16Buffer[delayNumSamples * num_out_channels], outBufferSize - ( delayNumSamples * num_out_channels ) ) != IVAS_ERR_OK ) + if ( split_rend_write_bitstream_to_file( hSplitRendFileReadWrite, bitsBuffer.bits, &bitsBuffer.config.bitsRead, + &bitsBuffer.config.bitsWritten ) != IVAS_ERR_OK ) { - fprintf( stderr, "Error writing audio file %s\n", args.outputFilePath ); + fprintf( stderr, "\nUnable to write to bitstream file!\n" ); exit( -1 ); } - delayNumSamples = 0; } - else + + if ( audioWriter != NULL ) { - delayNumSamples -= (int16_t) ( outBufferSize / num_out_channels ); +#endif + if ( delayNumSamples * num_out_channels < outBufferSize ) + { + if ( AudioFileWriter_write( audioWriter, &outInt16Buffer[delayNumSamples * num_out_channels], outBufferSize - ( delayNumSamples * num_out_channels ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "Error writing audio file %s\n", args.outputFilePath ); + exit( -1 ); + } + delayNumSamples = 0; + } + else + { + delayNumSamples -= (int16_t) ( outBufferSize / num_out_channels ); + } + +#ifdef SPLIT_REND_WITH_HEAD_ROT } + bitsBuffer.config.bitsRead = 0; + bitsBuffer.config.bitsWritten = 0; +#endif + + /* Write MASA metadata for MASA outputs */ if ( args.outConfig.audioConfig == IVAS_AUDIO_CONFIG_MASA1 || args.outConfig.audioConfig == IVAS_AUDIO_CONFIG_MASA2 ) { @@ -1555,23 +2032,30 @@ int main( } /* add zeros at the end to have equal length of synthesized signals */ - for ( zeroPadToWrite = zeroPad; zeroPadToWrite > frameSize_smpls; zeroPadToWrite -= frameSize_smpls ) +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( audioWriter != NULL ) { - memset( outInt16Buffer, 0, outBufferSize * sizeof( int16_t ) ); - if ( ( error = AudioFileWriter_write( audioWriter, outInt16Buffer, outBufferSize ) ) != IVAS_ERR_OK ) +#endif + for ( zeroPadToWrite = zeroPad; zeroPadToWrite > frameSize_smpls; zeroPadToWrite -= frameSize_smpls ) + { + memset( outInt16Buffer, 0, outBufferSize * sizeof( int16_t ) ); + if ( ( error = AudioFileWriter_write( audioWriter, outInt16Buffer, outBufferSize ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nOutput audio file writer error\n" ); + exit( -1 ); + } + } + + memset( outInt16Buffer, 0, zeroPadToWrite * outBuffer.config.numChannels * sizeof( int16_t ) ); + if ( ( error = AudioFileWriter_write( audioWriter, outInt16Buffer, zeroPadToWrite * outBuffer.config.numChannels ) ) != IVAS_ERR_OK ) { fprintf( stderr, "\nOutput audio file writer error\n" ); exit( -1 ); } + zeroPadToWrite = 0; +#ifdef SPLIT_REND_WITH_HEAD_ROT } - - memset( outInt16Buffer, 0, zeroPadToWrite * outBuffer.config.numChannels * sizeof( int16_t ) ); - if ( ( error = AudioFileWriter_write( audioWriter, outInt16Buffer, zeroPadToWrite * outBuffer.config.numChannels ) ) != IVAS_ERR_OK ) - { - fprintf( stderr, "\nOutput audio file writer error\n" ); - exit( -1 ); - } - zeroPadToWrite = 0; +#endif if ( args.inConfig.numAudioObjects != 0 && ( args.outConfig.audioConfig == IVAS_AUDIO_CONFIG_BINAURAL || args.outConfig.audioConfig == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) ) @@ -1594,11 +2078,27 @@ int main( free( outFloatBuffer ); free( outInt32Buffer ); free( inInt32Buffer ); + +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( bitsBufferData != NULL ) + { + free( bitsBufferData ); + } +#endif for ( i = 0; i < RENDERER_MAX_MASA_INPUTS; ++i ) { MasaFileReader_close( &masaReaders[i] ); } +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( cldfb_in_flag ) + { + IVAS_REND_closeCldfb( cldfbAna, cldfbSyn ); + } + + split_rend_reader_writer_close( &hSplitRendFileReadWrite ); + SplitRendBFIFileReader_close( &splitRendBFIReader ); +#endif for ( i = 0; i < RENDERER_MAX_MC_INPUTS; ++i ) { @@ -1898,8 +2398,13 @@ static bool parseOrientationTracking( static IVAS_AUDIO_CONFIG parseAudioConfig( const char *configString ) { +#ifndef SPLIT_REND_WITH_HEAD_ROT char charBuf[21]; charBuf[20] = '\0'; +#else + char charBuf[25]; + charBuf[24] = '\0'; +#endif strncpy( charBuf, configString, sizeof( charBuf ) - 1 ); charBuf[sizeof( charBuf ) - 1] = '\0'; @@ -1974,6 +2479,16 @@ static IVAS_AUDIO_CONFIG parseAudioConfig( { return IVAS_AUDIO_CONFIG_BINAURAL; } +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( strcmp( charBuf, "BINAURAL_SPLIT_PCM" ) == 0 ) + { + return IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM; + } + if ( strcmp( charBuf, "BINAURAL_SPLIT_CODED" ) == 0 ) + { + return IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED; + } +#endif if ( strcmp( charBuf, "BINAURAL_ROOM_IR" ) == 0 ) { return IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR; @@ -2106,6 +2621,10 @@ static CmdlnArgs defaultArgs( args.numInMetadataFiles = 0; clearString( args.headRotationFilePath ); +#ifdef SPLIT_REND_WITH_HEAD_ROT + clearString( args.outMetadataFilePath ); + clearString( args.splitRendBFIFilePath ); +#endif clearString( args.referenceVectorFilePath ); clearString( args.referenceRotationFilePath ); clearString( args.customHrtfFilePath ); @@ -2198,6 +2717,16 @@ static void parseOption( assert( numOptionValues == 1 ); strncpy( args->headRotationFilePath, optionValues[0], RENDERER_MAX_CLI_ARG_LENGTH - 1 ); break; +#ifdef SPLIT_REND_WITH_HEAD_ROT + case CmdLnOptionId_outputMetadata: + assert( numOptionValues == 1 ); + strncpy( args->outMetadataFilePath, optionValues[0], RENDERER_MAX_CLI_ARG_LENGTH - 1 ); + break; + case CmdLnOptionId_SplitRendBFIFile: + assert( numOptionValues == 1 ); + strncpy( args->splitRendBFIFilePath, optionValues[0], RENDERER_MAX_CLI_ARG_LENGTH - 1 ); + break; +#endif case CmdLnOptionId_referenceVectorFile: assert( numOptionValues == 1 ); strncpy( args->referenceVectorFilePath, optionValues[0], RENDERER_MAX_CLI_ARG_LENGTH - 1 ); @@ -3216,6 +3745,10 @@ static void printSupportedAudioConfigs( void ) "ISMx (input only)", "MASAx", "BINAURAL (output only)", +#ifdef SPLIT_REND_WITH_HEAD_ROT + "BINAURAL_SPLIT_PCM", + "BINAURAL_SPLIT_CODED", +#endif "BINAURAL_ROOM_IR (output only)", "BINAURAL_ROOM_REVERB (output only)", }; @@ -3299,44 +3832,6 @@ static ivas_error parseLfePanMtxFile( return IVAS_ERR_OK; } -/*--------------------------------------------------------------------------* - * convertInputBuffer() - * - * Convert input buffer from WAV/PCM file (int16_t, interleaved) to a format - * accepted by the renderer (float, packed) - *--------------------------------------------------------------------------*/ - -static void convertInputBuffer( - const int16_t *intBuffer, - const int16_t numIntSamplesPerChannel, - const int16_t numFloatSamplesPerChannel, - const int16_t numChannels, - float *floatBuffer ) -{ - int16_t chnl, smpl, i; - - i = 0; - - for ( smpl = 0; smpl < numFloatSamplesPerChannel; ++smpl ) - { - for ( chnl = 0; chnl < numChannels; ++chnl ) - { - if ( i < numIntSamplesPerChannel ) - { - floatBuffer[chnl * numFloatSamplesPerChannel + smpl] = (float) intBuffer[i]; - } - else - { - floatBuffer[chnl * numFloatSamplesPerChannel + smpl] = 0.f; - } - - ++i; - } - } - - return; -} - /*--------------------------------------------------------------------------* * convertInputBuffer() * @@ -3349,108 +3844,204 @@ static void convertInputBuffer_fx( const Word16 numIntSamplesPerChannel, const Word16 numFloatSamplesPerChannel, const Word16 numChannels, +#ifdef SPLIT_REND_WITH_HEAD_ROT Word32 *Word32Buffer, - Word16 in_q_factor ) + Word16 in_q_factor, + const int16_t cldfb_in_flag, + IVAS_CLDFB_FILTER_BANK_HANDLE *cldfbAna, + Word16 *out_q_factor +#else + Word32 *Word32Buffer, + Word16 in_q_factor +#endif +) { Word16 chnl, smpl, i; i = 0; - FOR( smpl = 0; smpl < numFloatSamplesPerChannel; ++smpl ) +#ifdef SPLIT_REND_WITH_HEAD_ROT + IF( cldfb_in_flag ) { - FOR( chnl = 0; chnl < numChannels; ++chnl ) + Word16 slotIdx, numCldfbBands, numFloatPcmSamples; + Word32 fIn[IVAS_MAX_OUTPUT_CHANNELS][IVAS_MAX_FRAME_SIZE]; + + numFloatPcmSamples = numFloatSamplesPerChannel >> 1; + numCldfbBands = numFloatPcmSamples / IVAS_CLDFB_NO_COL_MAX; + + /* CLDFB Analysis*/ + assert( numIntSamplesPerChannel <= IVAS_MAX_OUTPUT_CHANNELS * IVAS_MAX_FRAME_SIZE ); + FOR( smpl = 0; smpl < numFloatPcmSamples; ++smpl ) { - IF( i < numIntSamplesPerChannel ) + FOR( chnl = 0; chnl < numChannels; ++chnl ) { - Word32Buffer[chnl * numFloatSamplesPerChannel + smpl] = L_shl( (Word32) intBuffer[i], in_q_factor ); + IF( i < numIntSamplesPerChannel ) + { + fIn[chnl][smpl] = L_shl( (Word32) intBuffer[i], Q11 ); + } + ELSE + { + fIn[chnl][smpl] = 0; + } + + ++i; } - ELSE + } + + FOR( chnl = 0; chnl < numChannels; ++chnl ) + { + FOR( slotIdx = 0; slotIdx < IVAS_CLDFB_NO_COL_MAX; slotIdx++ ) { - Word32Buffer[chnl * numFloatSamplesPerChannel + smpl] = 0; + IVAS_REND_cldfbAnalysis_ts_wrapper( &fIn[chnl][numCldfbBands * slotIdx], + &Word32Buffer[( chnl * numFloatSamplesPerChannel ) + ( 2 * slotIdx * numCldfbBands )], + &Word32Buffer[numCldfbBands + ( chnl * numFloatSamplesPerChannel ) + ( 2 * slotIdx * numCldfbBands )], + numCldfbBands, cldfbAna[chnl], Q11, out_q_factor ); } + } + } + ELSE + { +#endif + FOR( smpl = 0; smpl < numFloatSamplesPerChannel; ++smpl ) + { + FOR( chnl = 0; chnl < numChannels; ++chnl ) + { + IF( i < numIntSamplesPerChannel ) + { + Word32Buffer[chnl * numFloatSamplesPerChannel + smpl] = L_shl( (Word32) intBuffer[i], in_q_factor ); + } + ELSE + { + Word32Buffer[chnl * numFloatSamplesPerChannel + smpl] = 0; + } - ++i; + ++i; + } } +#ifdef SPLIT_REND_WITH_HEAD_ROT + *out_q_factor = in_q_factor; } +#endif return; } + + /*--------------------------------------------------------------------------* - * convertOutputBuffer() + * convertOutputBuffer_fx() * - * Convert output buffer from the renderer (Word32, packed) to a format ready - * for writing to a WAV/PCM file (Word16, interleaved) + * Convert output buffer from the renderer (float, packed) to a format ready + * for writing to a WAV/PCM file (int16_t, interleaved) *--------------------------------------------------------------------------*/ + static void convertOutputBuffer_fx( const Word32 *Word32Buffer, const Word16 numSamplesPerChannel, const Word16 numChannels, +#ifdef SPLIT_REND_WITH_HEAD_ROT Word16 *intBuffer, - Word16 out_q ) + const Word16 cldfb_in_flag, + IVAS_CLDFB_FILTER_BANK_HANDLE *cldfbSyn, + Word16 out_q +#else + Word16 *intBuffer, + Word16 out_q +#endif +) { Word16 chnl, smpl, i; Word32 temp_fx; Word32 temp_fx1; i = 0; - FOR( smpl = 0; smpl < numSamplesPerChannel; ++smpl ) +#ifdef SPLIT_REND_WITH_HEAD_ROT + IF( cldfb_in_flag ) { + Word16 slotIdx, numCldfbBands, numPcmSamples, b, temp_out_q = 0; + Word32 fIn[IVAS_MAX_OUTPUT_CHANNELS][IVAS_MAX_FRAME_SIZE]; + Word32 re[IVAS_MAX_OUTPUT_CHANNELS][IVAS_CLDFB_NO_COL_MAX][IVAS_CLDFB_NO_CHANNELS_MAX]; + Word32 im[IVAS_MAX_OUTPUT_CHANNELS][IVAS_CLDFB_NO_COL_MAX][IVAS_CLDFB_NO_CHANNELS_MAX]; + + numPcmSamples = numSamplesPerChannel >> 1; + numCldfbBands = numPcmSamples / IVAS_CLDFB_NO_COL_MAX; + + /* CLDFB Synthesis*/ FOR( chnl = 0; chnl < numChannels; ++chnl ) { - temp_fx = L_add( Word32Buffer[chnl * numSamplesPerChannel + smpl], lshl( 1, ( out_q - 1 ) ) ); - temp_fx1 = L_shr( temp_fx, out_q ); - IF( GT_32( temp_fx1, IVAS_MAX16B_FX ) ) + FOR( slotIdx = 0; slotIdx < IVAS_CLDFB_NO_COL_MAX; slotIdx++ ) { - temp_fx1 = IVAS_MAX16B_FX; + FOR( b = 0; b < numCldfbBands; b++ ) + { + re[chnl][slotIdx][b] = Word32Buffer[( chnl * numSamplesPerChannel ) + ( 2 * slotIdx * numCldfbBands ) + b]; + im[chnl][slotIdx][b] = Word32Buffer[numCldfbBands + ( chnl * numSamplesPerChannel ) + ( 2 * slotIdx * numCldfbBands ) + b]; + move32(); + move32(); + } } - ELSE IF( LT_32( temp_fx1, IVAS_MIN16B_FX ) ) + } + + /* Implement CLDFB synthesis */ + FOR( chnl = 0; chnl < numChannels; ++chnl ) + { + Word32 *RealBuffer[IVAS_CLDFB_NO_COL_MAX]; + Word32 *ImagBuffer[IVAS_CLDFB_NO_COL_MAX]; + + FOR( slotIdx = 0; slotIdx < IVAS_CLDFB_NO_COL_MAX; slotIdx++ ) { - temp_fx1 = IVAS_MIN16B_FX; + RealBuffer[slotIdx] = re[chnl][slotIdx]; + ImagBuffer[slotIdx] = im[chnl][slotIdx]; + move32(); + move32(); } - intBuffer[i] = (Word16) temp_fx1; - ++i; + IVAS_REND_cldfbSynthesis_wrapper( RealBuffer, ImagBuffer, &( fIn[chnl][0] ), numCldfbBands * IVAS_CLDFB_NO_COL_MAX, cldfbSyn[chnl], out_q, &temp_out_q ); } - } - return; -} -/*--------------------------------------------------------------------------* - * convertOutputBuffer() - * - * Convert output buffer from the renderer (float, packed) to a format ready - * for writing to a WAV/PCM file (int16_t, interleaved) - *--------------------------------------------------------------------------*/ -static void convertOutputBuffer( - const float *floatBuffer, - const int16_t numSamplesPerChannel, - const int16_t numChannels, - int16_t *intBuffer ) -{ - int16_t chnl, smpl, i; - float temp; - - i = 0; - - for ( smpl = 0; smpl < numSamplesPerChannel; ++smpl ) - { - for ( chnl = 0; chnl < numChannels; ++chnl ) + FOR( smpl = 0; smpl < numPcmSamples; ++smpl ) { - temp = floatBuffer[chnl * numSamplesPerChannel + smpl]; - temp = (float) floor( temp + 0.5f ); - if ( temp > IVAS_MAX16B_FLT ) + FOR( chnl = 0; chnl < numChannels; ++chnl ) { - temp = IVAS_MAX16B_FLT; + temp_fx = L_add( fIn[chnl][smpl], lshl( 1, ( temp_out_q - 1 ) ) ); + temp_fx1 = L_shr( temp_fx, temp_out_q ); + IF( GT_32( temp_fx1, IVAS_MAX16B_FX ) ) + { + temp_fx1 = IVAS_MAX16B_FX; + } + ELSE IF( LT_32( temp_fx1, IVAS_MIN16B_FX ) ) + { + temp_fx1 = IVAS_MIN16B_FX; + } + intBuffer[i] = (Word16) temp_fx1; + ++i; } - else if ( temp < IVAS_MIN16B_FLT ) + } + } + ELSE + { +#endif + + FOR( smpl = 0; smpl < numSamplesPerChannel; ++smpl ) + { + FOR( chnl = 0; chnl < numChannels; ++chnl ) { - temp = IVAS_MIN16B_FLT; - } - intBuffer[i] = (int16_t) temp; + temp_fx = L_add( Word32Buffer[chnl * numSamplesPerChannel + smpl], lshl( 1, ( out_q - 1 ) ) ); + temp_fx1 = L_shr( temp_fx, out_q ); + IF( GT_32( temp_fx1, IVAS_MAX16B_FX ) ) + { + temp_fx1 = IVAS_MAX16B_FX; + } + ELSE IF( LT_32( temp_fx1, IVAS_MIN16B_FX ) ) + { + temp_fx1 = IVAS_MIN16B_FX; + } + intBuffer[i] = (Word16) temp_fx1; - ++i; + ++i; + } } +#ifdef SPLIT_REND_WITH_HEAD_ROT } +#endif return; } diff --git a/lib_com/ari_hm_fx.c b/lib_com/ari_hm_fx.c index 076bc8d9263d1f59c12906bb796fcbd5f245f591..46f8ecea1e78f01164d1acc083f29d3c26b145b6 100644 --- a/lib_com/ari_hm_fx.c +++ b/lib_com/ari_hm_fx.c @@ -10,7 +10,6 @@ #include "basop_util.h" #include "rom_com.h" #include "prot_fx.h" -#include "prot.h" #define GET_ADJ2( T, L, F ) ( ( ( L ) << ( F ) ) - ( T ) ) void UnmapIndex( diff --git a/lib_com/arith_coder_fx.c b/lib_com/arith_coder_fx.c index 12a4fa6702649fe221fa2124e28407fea64f51d4..846b4dceab0befaa6257563eda540e785fb7c1d9 100644 --- a/lib_com/arith_coder_fx.c +++ b/lib_com/arith_coder_fx.c @@ -6,7 +6,6 @@ #include #include "options.h" #include "prot_fx.h" -#include "prot.h" #include "basop_util.h" #include "basop_proto_func.h" #include "cnst.h" @@ -224,12 +223,8 @@ void tcx_arith_scale_envelope( tmp = norm_l( env[k] ); tmp2 = sub( 15, tmp ); -#ifdef BASOP_NOGLOB tmp = Inv16( round_fx_o( L_shl_o( env[k], tmp, &Overflow ), &Overflow ), &tmp2 ); /* exp(tmp2) */ -#else - tmp = Inv16( round_fx( L_shl( env[k], tmp ) ), &tmp2 ); -#endif - ienv[k] = L_shl( L_deposit_h( tmp ), sub( tmp2, 15 ) ); /* Q16 */ + ienv[k] = L_shl( L_deposit_h( tmp ), sub( tmp2, 15 ) ); /* Q16 */ move32(); mean = L_add( mean, ienv[k] ); /* Q16 */ } @@ -276,11 +271,7 @@ void tcx_arith_scale_envelope( tmp2 = BASOP_Util_Add_MantExp( negate( b ), b_e, tmp, tmp2, &scale ); /* exp(scale) */ scale = BASOP_Util_Divide1616_Scale( scale, round_fx( a ), &tmp ); -#ifdef BASOP_NOGLOB scale = shl_o( scale, sub( sub( add( tmp, tmp2 ), a_e ), 1 ), &Overflow ); /* Q15 */ -#else - scale = shl( scale, sub( sub( add( tmp, tmp2 ), a_e ), 1 ) ); /* Q15 */ -#endif /* iscale = 1.0f / scale; */ iscale_e = 0; @@ -329,11 +320,7 @@ void tcx_arith_scale_envelope( L_tmp = L_add( L_tmp, L_shl( Mpy_32_16_1( env[k], mult_r( 1147 /*0.035f Q15*/, iscale ) ), iscale_e ) ); /* Q16 */ tmp = norm_l( L_tmp ); -#ifdef BASOP_NOGLOB statesi = mult_r( statesi, round_fx_o( L_shl_o( L_tmp, tmp, &Overflow ), &Overflow ) ); -#else - statesi = mult_r( statesi, round_fx( L_shl( L_tmp, tmp ) ) ); -#endif bits = add( bits, sub( 15, tmp ) ); tmp = norm_s( statesi ); @@ -420,11 +407,7 @@ void tcx_arith_scale_envelope( *s_env_e = sub( add( 15, iscale_e ), tmp ); move16(); BASOP_SATURATE_WARNING_OFF_EVS; -#ifdef BASOP_NOGLOB a = L_shl_o( 1265000, sub( 15, *s_env_e ), &Overflow ); -#else /* BASOP_NOGLOB */ - a = L_shl( 1265000, sub( 15, *s_env_e ) ); -#endif BASOP_SATURATE_WARNING_ON_EVS; FOR( k = 0; k < L_frame; k++ ) diff --git a/lib_com/basop32.c b/lib_com/basop32.c index 732e33b2a5ef05c6b47458c63f0c854a73cf7b4d..7fab246607e316ca3e688971e6b850277fe9576c 100644 --- a/lib_com/basop32.c +++ b/lib_com/basop32.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other @@ -162,9 +162,7 @@ HISTORY: #include "options.h" #include "stl.h" -#ifdef BASOP_NOGLOB #include -#endif /* BASOP_NOGLOB */ #define WMC_TOOL_SKIP @@ -178,9 +176,7 @@ HISTORY: | Local Functions | |___________________________________________________________________________| */ -#ifdef BASOP_NOGLOB static Word16 saturate_o( Word32 L_var1, Flag *Overflow ); -#endif /* BASOP_NOGLOB */ static Word16 saturate( Word32 L_var1 ); @@ -189,7 +185,6 @@ static Word16 saturate( Word32 L_var1 ); | Constants and Globals | |___________________________________________________________________________| */ -#ifdef BASOP_NOGLOB #ifdef BASOP_PRINT_ON_WARNING #include @@ -416,10 +411,6 @@ Flag get_carry( const Flag *carry ) #undef B_HELPER_SET_GLOBAL #undef B_HELPER_GET_GLOBAL -#else /* BASOP_NOGLOB */ -Flag Overflow = 0; -Flag Carry = 0; -#endif /* BASOP_NOGLOB */ /*___________________________________________________________________________ | | @@ -456,30 +447,18 @@ Flag Carry = 0; | range : 0xffff 8000 <= var_out <= 0x0000 7fff. | |___________________________________________________________________________| */ -#ifndef BASOP_NOGLOB -static Word16 saturate( Word32 L_var1 ) -#else /* BASOP_NOGLOB */ static Word16 saturate_o( Word32 L_var1, Flag *Overflow ) -#endif /* BASOP_NOGLOB */ { Word16 var_out; if ( L_var1 > 0X00007fffL ) { -#ifndef BASOP_NOGLOB - Overflow = 1; -#else /* BASOP_NOGLOB */ *Overflow = 1; -#endif /* BASOP_NOGLOB */ var_out = MAX_16; } else if ( L_var1 < (Word32) 0xffff8000L ) { -#ifndef BASOP_NOGLOB - Overflow = 1; -#else /* BASOP_NOGLOB */ *Overflow = 1; -#endif /* BASOP_NOGLOB */ var_out = MIN_16; } else @@ -495,7 +474,6 @@ static Word16 saturate_o( Word32 L_var1, Flag *Overflow ) return ( var_out ); } -#ifdef BASOP_NOGLOB static Word16 saturate( Word32 L_var1 ) { Word16 var_out; @@ -522,7 +500,6 @@ static Word16 saturate( Word32 L_var1 ) return ( var_out ); } -#endif /* BASOP_NOGLOB */ /*___________________________________________________________________________ | | @@ -557,7 +534,6 @@ static Word16 saturate( Word32 L_var1 ) | range : 0xffff 8000 <= var_out <= 0x0000 7fff. | |___________________________________________________________________________| */ -#ifdef BASOP_NOGLOB Word16 add_o( Word16 var1, Word16 var2, Flag *Overflow ) { Word16 var_out; @@ -572,7 +548,6 @@ Word16 add_o( Word16 var1, Word16 var2, Flag *Overflow ) return ( var_out ); } -#endif /* BASOP_NOGLOB */ Word16 add( Word16 var1, Word16 var2 ) { Word16 var_out; @@ -586,13 +561,11 @@ Word16 add( Word16 var1, Word16 var2 ) #endif return ( var_out ); } -#ifdef BASOP_NOGLOB Word16 add_sat( Word16 var1, Word16 var2 ) { Flag Overflow; return add_o( var1, var2, &Overflow ); } -#endif /*___________________________________________________________________________ | | | Function Name : sub | @@ -626,7 +599,6 @@ Word16 add_sat( Word16 var1, Word16 var2 ) | range : 0xffff 8000 <= var_out <= 0x0000 7fff. | |___________________________________________________________________________| */ -#ifdef BASOP_NOGLOB Word16 sub_o( Word16 var1, Word16 var2, Flag *Overflow ) { Word16 var_out; @@ -641,7 +613,6 @@ Word16 sub_o( Word16 var1, Word16 var2, Flag *Overflow ) return ( var_out ); } -#endif /* BASOP_NOGLOB */ Word16 sub( Word16 var1, Word16 var2 ) { Word16 var_out; @@ -655,13 +626,11 @@ Word16 sub( Word16 var1, Word16 var2 ) #endif return ( var_out ); } -#ifdef BASOP_NOGLOB Word16 sub_sat( Word16 var1, Word16 var2 ) { Flag Overflow; return sub_o( var1, var2, &Overflow ); } -#endif /*___________________________________________________________________________ | | | Function Name : abs_s | @@ -753,11 +722,7 @@ Word16 abs_s( Word16 var1 ) | range : 0xffff 8000 <= var_out <= 0x0000 7fff. | |___________________________________________________________________________| */ -#ifndef BASOP_NOGLOB -Word16 shl( Word16 var1, Word16 var2 ) -#else /* BASOP_NOGLOB */ Word16 shl_o( Word16 var1, Word16 var2, Flag *Overflow ) -#endif /* BASOP_NOGLOB */ { Word16 var_out; Word32 result; @@ -779,11 +744,7 @@ Word16 shl_o( Word16 var1, Word16 var2, Flag *Overflow ) if ( ( var2 > 15 && var1 != 0 ) || ( result != (Word32) ( (Word16) result ) ) ) { -#ifndef BASOP_NOGLOB - Overflow = 1; -#else /* BASOP_NOGLOB */ *Overflow = 1; -#endif /* BASOP_NOGLOB */ var_out = ( var1 > 0 ) ? MAX_16 : MIN_16; } else @@ -806,7 +767,6 @@ Word16 shl_o( Word16 var1, Word16 var2, Flag *Overflow ) return ( var_out ); } -#ifdef BASOP_NOGLOB Word16 shl( Word16 var1, Word16 var2 ) { Word16 var_out; @@ -856,7 +816,6 @@ Word16 shl_sat( Word16 var1, Word16 var2 ) Flag Overflow; return shl_o( var1, var2, &Overflow ); } -#endif /* BASOP_NOGLOB */ /*___________________________________________________________________________ | | @@ -892,11 +851,7 @@ Word16 shl_sat( Word16 var1, Word16 var2 ) | range : 0xffff 8000 <= var_out <= 0x0000 7fff. | |___________________________________________________________________________| */ -#ifdef BASOP_NOGLOB Word16 shr_o( Word16 var1, Word16 var2, Flag *Overflow ) -#else /* BASOP_NOGLOB */ -Word16 shr( Word16 var1, Word16 var2 ) -#endif /* BASOP_NOGLOB */ { Word16 var_out; @@ -905,11 +860,7 @@ Word16 shr( Word16 var1, Word16 var2 ) if ( var2 < -16 ) var2 = -16; var2 = -var2; -#ifdef BASOP_NOGLOB var_out = shl_o( var1, var2, Overflow ); -#else /* BASOP_NOGLOB */ - var_out = shl( var1, var2 ); -#endif /* BASOP_NOGLOB */ #ifdef WMOPS multiCounter[currCounter].shl--; @@ -943,7 +894,6 @@ Word16 shr( Word16 var1, Word16 var2 ) return ( var_out ); } -#ifdef BASOP_NOGLOB Word16 shr( Word16 var1, Word16 var2 ) { return shr_o( var1, var2, NULL ); @@ -953,7 +903,6 @@ Word16 shr_sat( Word16 var1, Word16 var2 ) Flag Overflow; return shr_o( var1, var2, &Overflow ); } -#endif /* BASOP_NOGLOB */ /*___________________________________________________________________________ @@ -990,11 +939,7 @@ Word16 shr_sat( Word16 var1, Word16 var2 ) | range : 0xffff 8000 <= var_out <= 0x0000 7fff. | |___________________________________________________________________________| */ -#ifdef BASOP_NOGLOB Word16 mult_o( Word16 var1, Word16 var2, Flag *Overflow ) -#else /* BASOP_NOGLOB */ -Word16 mult( Word16 var1, Word16 var2 ) -#endif /* BASOP_NOGLOB */ { Word16 var_out; Word32 L_product; @@ -1006,11 +951,7 @@ Word16 mult( Word16 var1, Word16 var2 ) if ( L_product & (Word32) 0x00010000L ) L_product = L_product | (Word32) 0xffff0000L; -#ifdef BASOP_NOGLOB var_out = saturate_o( L_product, Overflow ); -#else /* BASOP_NOGLOB */ - var_out = saturate( L_product ); -#endif /* BASOP_NOGLOB */ #ifdef WMOPS multiCounter[currCounter].mult++; @@ -1019,7 +960,6 @@ Word16 mult( Word16 var1, Word16 var2 ) BASOP_CHECK(); return ( var_out ); } -#ifdef BASOP_NOGLOB Word16 mult( Word16 var1, Word16 var2 ) { Word16 var_out; @@ -1046,7 +986,6 @@ Word16 mult_sat( Word16 var1, Word16 var2 ) return mult_o( var1, var2, &Overflow ); } -#endif /*___________________________________________________________________________ | | @@ -1082,11 +1021,7 @@ Word16 mult_sat( Word16 var1, Word16 var2 ) | range : 0x8000 0000 <= L_var_out <= 0x7fff ffff. | |___________________________________________________________________________| */ -#ifndef BASOP_NOGLOB -Word32 L_mult( Word16 var1, Word16 var2 ) -#else /* BASOP_NOGLOB */ Word32 L_mult_o( Word16 var1, Word16 var2, Flag *Overflow ) -#endif /* BASOP_NOGLOB */ { Word32 L_var_out; @@ -1098,11 +1033,7 @@ Word32 L_mult_o( Word16 var1, Word16 var2, Flag *Overflow ) } else { -#ifndef BASOP_NOGLOB - Overflow = 1; -#else /* BASOP_NOGLOB */ *Overflow = 1; -#endif /* BASOP_NOGLOB */ L_var_out = MAX_32; } @@ -1115,7 +1046,6 @@ Word32 L_mult_o( Word16 var1, Word16 var2, Flag *Overflow ) return ( L_var_out ); } -#ifdef BASOP_NOGLOB Word32 L_mult( Word16 var1, Word16 var2 ) { Word32 L_var_out; @@ -1146,7 +1076,6 @@ Word32 L_mult_sat( Word16 var1, Word16 var2 ) Flag Overflow; return L_mult_o( var1, var2, &Overflow ); } -#endif /* BASOP_NOGLOB */ /*___________________________________________________________________________ | | @@ -1312,7 +1241,6 @@ Word16 extract_l( Word32 L_var1 ) | range : 0xffff 8000 <= var_out <= 0x0000 7fff. | |___________________________________________________________________________| */ -#ifdef BASOP_NOGLOB Word16 round_fx_o( Word32 L_var1, Flag *Overflow ) { Word16 var_out; @@ -1334,7 +1262,6 @@ Word16 round_fx_o( Word32 L_var1, Flag *Overflow ) return ( var_out ); } -#endif /* BASOP_NOGLOB */ Word16 round_fx( Word32 L_var1 ) { Word16 var_out; @@ -1354,13 +1281,11 @@ Word16 round_fx( Word32 L_var1 ) return ( var_out ); } -#ifdef BASOP_NOGLOB Word16 round_fx_sat( Word32 L_var1 ) { Flag Overflow; return round_fx_o( L_var1, &Overflow ); } -#endif /*___________________________________________________________________________ | | | Function Name : L_mac | @@ -1397,7 +1322,6 @@ Word16 round_fx_sat( Word32 L_var1 ) | range : 0x8000 0000 <= L_var_out <= 0x7fff ffff. | |___________________________________________________________________________| */ -#ifdef BASOP_NOGLOB Word32 L_mac_o( Word32 L_var3, Word16 var1, Word16 var2, Flag *Overflow ) { Word32 L_var_out; @@ -1415,7 +1339,6 @@ Word32 L_mac_o( Word32 L_var3, Word16 var1, Word16 var2, Flag *Overflow ) return ( L_var_out ); } -#endif /* BASOP_NOGLOB */ Word32 L_mac( Word32 L_var3, Word16 var1, Word16 var2 ) { Word32 L_var_out; @@ -1433,13 +1356,11 @@ Word32 L_mac( Word32 L_var3, Word16 var1, Word16 var2 ) return ( L_var_out ); } -#ifdef BASOP_NOGLOB Word32 L_mac_sat( Word32 L_var3, Word16 var1, Word16 var2 ) { Flag Overflow; return L_mac_o( L_var3, var1, var2, &Overflow ); } -#endif /*___________________________________________________________________________ | | | Function Name : L_msu | @@ -1476,7 +1397,6 @@ Word32 L_mac_sat( Word32 L_var3, Word16 var1, Word16 var2 ) | range : 0x8000 0000 <= L_var_out <= 0x7fff ffff. | |___________________________________________________________________________| */ -#ifdef BASOP_NOGLOB Word32 L_msu_o( Word32 L_var3, Word16 var1, Word16 var2, Flag *Overflow ) { Word32 L_var_out; @@ -1494,7 +1414,6 @@ Word32 L_msu_o( Word32 L_var3, Word16 var1, Word16 var2, Flag *Overflow ) return ( L_var_out ); } -#endif /* BASOP_NOGLOB */ Word32 L_msu( Word32 L_var3, Word16 var1, Word16 var2 ) { Word32 L_var_out; @@ -1512,13 +1431,11 @@ Word32 L_msu( Word32 L_var3, Word16 var1, Word16 var2 ) return ( L_var_out ); } -#ifdef BASOP_NOGLOB Word32 L_msu_sat( Word32 L_var3, Word16 var1, Word16 var2 ) { Flag Overflow; return L_msu_o( L_var3, var1, var2, &Overflow ); } -#endif /*___________________________________________________________________________ | | | Function Name : L_macNs | @@ -1557,21 +1474,16 @@ Word32 L_msu_sat( Word32 L_var3, Word16 var1, Word16 var2 ) | | | Caution : | | | -#ifndef BASOP_NOGLOB - | In some cases the Carry flag has to be cleared or set before using | -#else | In some cases the BASOP_Carry flag has to be cleared or set before using | -#endif | operators which take into account its value. | |___________________________________________________________________________| */ -#ifdef BASOP_NOGLOB Word32 DEPR_L_macNs( Word32 L_var3, Word16 var1, Word16 var2, Flag *Carry ) { Word32 L_var_out; L_var_out = L_mult( var1, var2 ); - L_var_out = DEPR_L_add_c( L_var3, L_var_out, Carry ); + L_var_out = L_add_c( L_var3, L_var_out, Carry ); #ifdef WMOPS multiCounter[currCounter].L_mult--; @@ -1582,25 +1494,14 @@ Word32 DEPR_L_macNs( Word32 L_var3, Word16 var1, Word16 var2, Flag *Carry ) /* BASOP_CHECK(); Do not check for overflow here, function produces the carry bit instead */ return ( L_var_out ); } -#endif -#ifdef BASOP_NOGLOB Word32 L_macNs_co( Word32 L_var3, Word16 var1, Word16 var2, Flag *Carry, Flag *Overflow ) -#else /* BASOP_NOGLOB */ -Word32 L_macNs( Word32 L_var3, Word16 var1, Word16 var2 ) -#endif /* BASOP_NOGLOB */ { Word32 L_var_out; -#ifdef BASOP_NOGLOB L_var_out = L_mult_o( var1, var2, Overflow ); L_var_out = L_add_co( L_var3, L_var_out, Carry, Overflow ); -#else /* BASOP_NOGLOB */ - L_var_out = L_mult( var1, var2 ); - L_var_out = L_add_c( L_var3, L_var_out ); -#endif /* BASOP_NOGLOB */ return ( L_var_out ); } -#ifdef BASOP_NOGLOB Word32 L_macNs( Word32 L_var3, Word16 var1, Word16 var2 ) { return L_macNs_co( L_var3, var1, var2, NULL, NULL ); @@ -1610,7 +1511,6 @@ Word32 L_macNs_sat( Word32 L_var3, Word16 var1, Word16 var2 ) Flag Carry, Overflow; return L_macNs_co( L_var3, var1, var2, &Carry, &Overflow ); } -#endif /*___________________________________________________________________________ | | | Function Name : L_msuNs | @@ -1649,28 +1549,16 @@ Word32 L_macNs_sat( Word32 L_var3, Word16 var1, Word16 var2 ) | | | Caution : | | | -#ifndef BASOP_NOGLOB - | In some cases the Carry flag has to be cleared or set before using | -#else | In some cases the BASOP_Carry flag has to be cleared or set before using | -#endif | operators which take into account its value. | |___________________________________________________________________________| */ -#ifndef BASOP_NOGLOB -Word32 L_msuNs( Word32 L_var3, Word16 var1, Word16 var2 ) -#else /* BASOP_NOGLOB */ Word32 DEPR_L_msuNs( Word32 L_var3, Word16 var1, Word16 var2, Flag *Carry ) -#endif /* BASOP_NOGLOB */ { Word32 L_var_out; L_var_out = L_mult( var1, var2 ); -#ifndef BASOP_NOGLOB - L_var_out = L_sub_c( L_var3, L_var_out ); -#else /* BASOP_NOGLOB */ L_var_out = DEPR_L_sub_c( L_var3, L_var_out, Carry ); -#endif /* BASOP_NOGLOB */ #ifdef WMOPS multiCounter[currCounter].L_mult--; @@ -1683,7 +1571,6 @@ Word32 DEPR_L_msuNs( Word32 L_var3, Word16 var1, Word16 var2, Flag *Carry ) return ( L_var_out ); } -#ifdef BASOP_NOGLOB Word32 L_msuNs_co( Word32 L_var3, Word16 var1, Word16 var2, Flag *Carry, Flag *Overflow ) { Word32 L_var_out; @@ -1704,7 +1591,6 @@ Word32 L_msuNs_sat( Word32 L_var3, Word16 var1, Word16 var2 ) Flag Carry, Overflow; return L_msuNs_co( L_var3, var1, var2, &Carry, &Overflow ); } -#endif /*___________________________________________________________________________ | | | Function Name : L_add | @@ -1736,11 +1622,7 @@ Word32 L_msuNs_sat( Word32 L_var3, Word16 var1, Word16 var2 ) | range : 0x8000 0000 <= L_var_out <= 0x7fff ffff. | |___________________________________________________________________________| */ -#ifndef BASOP_NOGLOB -Word32 L_add( Word32 L_var1, Word32 L_var2 ) -#else /* BASOP_NOGLOB */ Word32 L_add_o( Word32 L_var1, Word32 L_var2, Flag *Overflow ) -#endif /* BASOP_NOGLOB */ { Word32 L_var_out; @@ -1751,11 +1633,7 @@ Word32 L_add_o( Word32 L_var1, Word32 L_var2, Flag *Overflow ) if ( ( L_var_out ^ L_var1 ) & MIN_32 ) { L_var_out = ( L_var1 < 0 ) ? MIN_32 : MAX_32; -#ifndef BASOP_NOGLOB - Overflow = 1; -#else /* BASOP_NOGLOB */ *Overflow = 1; -#endif /* BASOP_NOGLOB */ } } @@ -1769,7 +1647,6 @@ Word32 L_add_o( Word32 L_var1, Word32 L_var2, Flag *Overflow ) return ( L_var_out ); } -#ifdef BASOP_NOGLOB Word32 L_add( Word32 L_var1, Word32 L_var2 ) { Word32 L_var_out; @@ -1795,7 +1672,6 @@ Word32 L_add_sat( Word32 L_var1, Word32 L_var2 ) Flag Overflow; return L_add_o( L_var1, L_var2, &Overflow ); } -#endif /* BASOP_NOGLOB */ /*___________________________________________________________________________ | | @@ -1828,11 +1704,7 @@ Word32 L_add_sat( Word32 L_var1, Word32 L_var2 ) | range : 0x8000 0000 <= L_var_out <= 0x7fff ffff. | |___________________________________________________________________________| */ -#ifndef BASOP_NOGLOB -Word32 L_sub( Word32 L_var1, Word32 L_var2 ) -#else /* BASOP_NOGLOB */ Word32 L_sub_o( Word32 L_var1, Word32 L_var2, Flag *Overflow ) -#endif /* BASOP_NOGLOB */ { Word32 L_var_out; @@ -1843,11 +1715,7 @@ Word32 L_sub_o( Word32 L_var1, Word32 L_var2, Flag *Overflow ) if ( ( L_var_out ^ L_var1 ) & MIN_32 ) { L_var_out = ( L_var1 < 0L ) ? MIN_32 : MAX_32; -#ifndef BASOP_NOGLOB - Overflow = 1; -#else /* BASOP_NOGLOB */ *Overflow = 1; -#endif /* BASOP_NOGLOB */ } } @@ -1860,7 +1728,6 @@ Word32 L_sub_o( Word32 L_var1, Word32 L_var2, Flag *Overflow ) return ( L_var_out ); } -#ifdef BASOP_NOGLOB Word32 L_sub( Word32 L_var1, Word32 L_var2 ) { Word32 L_var_out; @@ -1888,7 +1755,6 @@ Word32 L_sub_sat( Word32 L_var1, Word32 L_var2 ) Flag Overflow; return L_sub_o( L_var1, L_var2, &Overflow ); } -#endif /* BASOP_NOGLOB */ /*___________________________________________________________________________ | | @@ -1897,11 +1763,7 @@ Word32 L_sub_sat( Word32 L_var1, Word32 L_var2 ) | Purpose : | | | | Performs 32 bits addition of the two 32 bits variables (L_var1+L_var2+C)| -#ifndef BASOP_NOGLOB - | with carry. No saturation. Generate carry and Overflow values. The car- | -#else | with carry. No saturation. Generate carry and BASOP_Overflow values. The car- | -#endif | ry and overflow values are binary variables which can be tested and as- | | signed values. | | | @@ -1927,37 +1789,22 @@ Word32 L_sub_sat( Word32 L_var1, Word32 L_var2 ) | | | Caution : | | | -#ifndef BASOP_NOGLOB - | In some cases the Carry flag has to be cleared or set before using | -#else | In some cases the BASOP_Carry flag has to be cleared or set before using | -#endif | operators which take into account its value. | |___________________________________________________________________________| */ -#ifndef BASOP_NOGLOB -Word32 L_add_c( Word32 L_var1, Word32 L_var2 ) -#else /* BASOP_NOGLOB */ -Word32 DEPR_L_add_c( Word32 L_var1, Word32 L_var2, Flag *Carry ) -#endif /* BASOP_NOGLOB */ +Word32 L_add_c( Word32 L_var1, Word32 L_var2, Flag *Carry ) { Word32 L_var_out; Word32 L_test; Flag carry_int = 0; -#ifndef BASOP_NOGLOB - L_var_out = L_var1 + L_var2 + Carry; -#else /* BASOP_NOGLOB */ L_var_out = L_var1 + L_var2 + *Carry; -#endif /* BASOP_NOGLOB */ L_test = L_var1 + L_var2; if ( ( L_var1 > 0 ) && ( L_var2 > 0 ) && ( L_test < 0 ) ) { -#ifndef BASOP_NOGLOB - Overflow = 1; -#endif /* ! BASOP_NOGLOB */ carry_int = 0; } else @@ -1966,16 +1813,10 @@ Word32 DEPR_L_add_c( Word32 L_var1, Word32 L_var2, Flag *Carry ) { if ( L_test >= 0 ) { -#ifndef BASOP_NOGLOB - Overflow = 1; -#endif /* ! BASOP_NOGLOB */ carry_int = 1; } else { -#ifndef BASOP_NOGLOB - Overflow = 0; -#endif /* ! BASOP_NOGLOB */ carry_int = 1; } } @@ -1983,63 +1824,36 @@ Word32 DEPR_L_add_c( Word32 L_var1, Word32 L_var2, Flag *Carry ) { if ( ( ( L_var1 ^ L_var2 ) < 0 ) && ( L_test >= 0 ) ) { -#ifndef BASOP_NOGLOB - Overflow = 0; -#endif /* ! BASOP_NOGLOB */ carry_int = 1; } else { -#ifndef BASOP_NOGLOB - Overflow = 0; -#endif /* ! BASOP_NOGLOB */ carry_int = 0; } } } -#ifndef BASOP_NOGLOB - if ( Carry ) -#else /* BASOP_NOGLOB */ if ( *Carry ) -#endif /* BASOP_NOGLOB */ { if ( L_test == MAX_32 ) { -#ifndef BASOP_NOGLOB - Overflow = 1; - Carry = carry_int; -#else /* BASOP_NOGLOB */ *Carry = carry_int; -#endif /* BASOP_NOGLOB */ } else { if ( L_test == (Word32) 0xFFFFFFFFL ) { -#ifndef BASOP_NOGLOB - Carry = 1; -#else /* BASOP_NOGLOB */ *Carry = 1; -#endif /* BASOP_NOGLOB */ } else { -#ifndef BASOP_NOGLOB - Carry = carry_int; -#else /* BASOP_NOGLOB */ *Carry = carry_int; -#endif /* BASOP_NOGLOB */ } } } else { -#ifndef BASOP_NOGLOB - Carry = carry_int; -#else /* BASOP_NOGLOB */ *Carry = carry_int; -#endif /* BASOP_NOGLOB */ } #ifdef WMOPS @@ -2051,7 +1865,6 @@ Word32 DEPR_L_add_c( Word32 L_var1, Word32 L_var2, Flag *Carry ) return ( L_var_out ); } -#ifdef BASOP_NOGLOB Word32 L_add_co( Word32 L_var1, Word32 L_var2, Flag *Carry, Flag *Overflow ) { Word32 L_var_out; @@ -2121,13 +1934,12 @@ Word32 L_add_co( Word32 L_var1, Word32 L_var2, Flag *Carry, Flag *Overflow ) carry_int ? set_carry( Carry ) : unset_carry( Carry ); } +#ifdef WMOPS + multiCounter[currCounter].L_add_c++; +#endif return ( L_var_out ); } -Word32 L_add_c( Word32 L_var1, Word32 L_var2 ) -{ - return L_add_co( L_var1, L_var2, NULL, NULL ); -} -#endif + /*___________________________________________________________________________ | | | Function Name : L_sub_c | @@ -2135,11 +1947,7 @@ Word32 L_add_c( Word32 L_var1, Word32 L_var2 ) | Purpose : | | | | Performs 32 bits subtraction of the two 32 bits variables with carry | -#ifndef BASOP_NOGLOB - | (borrow) : L_var1-L_var2-C. No saturation. Generate carry and Overflow | -#else | (borrow) : L_var1-L_var2-C. No saturation. Generate carry and BASOP_Overflow | -#endif | values. The carry and overflow values are binary variables which can | | be tested and assigned values. | | | @@ -2165,42 +1973,22 @@ Word32 L_add_c( Word32 L_var1, Word32 L_var2 ) | | | Caution : | | | -#ifndef BASOP_NOGLOB - | In some cases the Carry flag has to be cleared or set before using | -#else | In some cases the BASOP_Carry flag has to be cleared or set before using | -#endif | operators which take into account its value. | |___________________________________________________________________________| */ -#ifndef BASOP_NOGLOB -Word32 L_sub_c( Word32 L_var1, Word32 L_var2 ) -#else /* BASOP_NOGLOB */ Word32 DEPR_L_sub_c( Word32 L_var1, Word32 L_var2, Flag *Carry ) -#endif /* BASOP_NOGLOB */ { Word32 L_var_out; Word32 L_test; Flag carry_int = 0; -#ifndef BASOP_NOGLOB - if ( Carry ) -#else /* BASOP_NOGLOB */ if ( *Carry ) -#endif /* BASOP_NOGLOB */ { -#ifndef BASOP_NOGLOB - Carry = 0; -#else /* BASOP_NOGLOB */ *Carry = 0; -#endif /* BASOP_NOGLOB */ if ( L_var2 != MIN_32 ) { -#ifndef BASOP_NOGLOB - L_var_out = L_add_c( L_var1, -L_var2 ); -#else /* BASOP_NOGLOB */ - L_var_out = DEPR_L_add_c( L_var1, -L_var2, Carry ); -#endif /* BASOP_NOGLOB */ + L_var_out = L_add_c( L_var1, -L_var2, Carry ); #ifdef WMOPS multiCounter[currCounter].L_add_c--; #endif @@ -2210,12 +1998,7 @@ Word32 DEPR_L_sub_c( Word32 L_var1, Word32 L_var2, Flag *Carry ) L_var_out = L_var1 - L_var2; if ( L_var1 > 0L ) { -#ifndef BASOP_NOGLOB - Overflow = 1; - Carry = 0; -#else /* BASOP_NOGLOB */ *Carry = 0; -#endif /* BASOP_NOGLOB */ } } } @@ -2226,41 +2009,23 @@ Word32 DEPR_L_sub_c( Word32 L_var1, Word32 L_var2, Flag *Carry ) if ( ( L_test < 0 ) && ( L_var1 > 0 ) && ( L_var2 < 0 ) ) { -#ifndef BASOP_NOGLOB - Overflow = 1; -#endif /* ! BASOP_NOGLOB */ carry_int = 0; } else if ( ( L_test > 0 ) && ( L_var1 < 0 ) && ( L_var2 > 0 ) ) { -#ifndef BASOP_NOGLOB - Overflow = 1; -#endif /* ! BASOP_NOGLOB */ carry_int = 1; } else if ( ( L_test > 0 ) && ( ( L_var1 ^ L_var2 ) > 0 ) ) { -#ifndef BASOP_NOGLOB - Overflow = 0; -#endif /* ! BASOP_NOGLOB */ carry_int = 1; } if ( L_test == MIN_32 ) { -#ifndef BASOP_NOGLOB - Overflow = 1; - Carry = carry_int; -#else /* BASOP_NOGLOB */ *Carry = carry_int; -#endif /* BASOP_NOGLOB */ } else { -#ifndef BASOP_NOGLOB - Carry = carry_int; -#else /* BASOP_NOGLOB */ *Carry = carry_int; -#endif /* BASOP_NOGLOB */ } } @@ -2273,7 +2038,6 @@ Word32 DEPR_L_sub_c( Word32 L_var1, Word32 L_var2, Flag *Carry ) return ( L_var_out ); } -#ifdef BASOP_NOGLOB Word32 L_sub_co( Word32 L_var1, Word32 L_var2, Flag *Carry, Flag *Overflow ) { Word32 L_var_out; @@ -2329,7 +2093,6 @@ Word32 L_sub_c( Word32 L_var1, Word32 L_var2 ) { return L_sub_co( L_var1, L_var2, NULL, NULL ); } -#endif /*___________________________________________________________________________ | | | Function Name : L_negate | @@ -2407,7 +2170,6 @@ Word32 L_negate( Word32 L_var1 ) | range : 0x8000 <= var_out <= 0x7fff. | |___________________________________________________________________________| */ -#ifdef BASOP_NOGLOB Word16 mult_ro( Word16 var1, Word16 var2, Flag *Overflow ) { Word16 var_out; @@ -2431,7 +2193,6 @@ Word16 mult_ro( Word16 var1, Word16 var2, Flag *Overflow ) return ( var_out ); } -#endif /* BASOP_NOGLOB */ Word16 mult_r( Word16 var1, Word16 var2 ) { Word16 var_out; @@ -2454,13 +2215,11 @@ Word16 mult_r( Word16 var1, Word16 var2 ) return ( var_out ); } -#ifdef BASOP_NOGLOB Word16 mult_r_sat( Word16 var1, Word16 var2 ) { Flag Overflow; return mult_ro( var1, var2, &Overflow ); } -#endif /*___________________________________________________________________________ | | | Function Name : L_shl | @@ -2494,11 +2253,7 @@ Word16 mult_r_sat( Word16 var1, Word16 var2 ) | range : 0x8000 0000 <= L_var_out <= 0x7fff ffff. | |___________________________________________________________________________| */ -#ifndef BASOP_NOGLOB -Word32 L_shl( Word32 L_var1, Word16 var2 ) -#else /* BASOP_NOGLOB */ Word32 L_shl_o( Word32 L_var1, Word16 var2, Flag *Overflow ) -#endif /* BASOP_NOGLOB */ { Word32 L_var_out = 0L; @@ -2519,11 +2274,7 @@ Word32 L_shl_o( Word32 L_var1, Word16 var2, Flag *Overflow ) { if ( L_var1 > (Word32) 0X3fffffffL ) { -#ifndef BASOP_NOGLOB - Overflow = 1; -#else /* BASOP_NOGLOB */ *Overflow = 1; -#endif /* BASOP_NOGLOB */ L_var_out = MAX_32; break; } @@ -2531,11 +2282,7 @@ Word32 L_shl_o( Word32 L_var1, Word16 var2, Flag *Overflow ) { if ( L_var1 < (Word32) 0xc0000000L ) { -#ifndef BASOP_NOGLOB - Overflow = 1; -#else /* BASOP_NOGLOB */ *Overflow = 1; -#endif /* BASOP_NOGLOB */ L_var_out = MIN_32; break; } @@ -2555,7 +2302,6 @@ Word32 L_shl_o( Word32 L_var1, Word16 var2, Flag *Overflow ) return ( L_var_out ); } -#ifdef BASOP_NOGLOB Word32 L_shl( Word32 L_var1, Word16 var2 ) { @@ -2610,7 +2356,6 @@ Word32 L_shl_sat( Word32 L_var1, Word16 var2 ) return L_shl_o( L_var1, var2, &Overflow ); } -#endif /* BASOP_NOGLOB */ /*___________________________________________________________________________ | | | Function Name : L_shr | @@ -2644,7 +2389,6 @@ Word32 L_shl_sat( Word32 L_var1, Word16 var2 ) | range : 0x8000 0000 <= L_var_out <= 0x7fff ffff. | |___________________________________________________________________________| */ -#ifdef BASOP_NOGLOB Word32 L_shr_o( Word32 L_var1, Word16 var2, Flag *Overflow ) { Word32 L_var_out; @@ -2688,7 +2432,6 @@ Word32 L_shr_o( Word32 L_var1, Word16 var2, Flag *Overflow ) return ( L_var_out ); } -#endif /* BASOP_NOGLOB */ Word32 L_shr( Word32 L_var1, Word16 var2 ) { Word32 L_var_out; @@ -2730,13 +2473,11 @@ Word32 L_shr( Word32 L_var1, Word16 var2 ) return ( L_var_out ); } -#ifdef BASOP_NOGLOB Word32 L_shr_sat( Word32 L_var1, Word16 var2 ) { Flag Overflow; return L_shr_o( L_var1, var2, &Overflow ); } -#endif /*___________________________________________________________________________ | | | Function Name : shr_r | @@ -2810,7 +2551,6 @@ Word16 shr_r( Word16 var1, Word16 var2 ) return ( var_out ); } -#ifdef BASOP_NOGLOB Word16 shr_ro( Word16 var1, Word16 var2, Flag *Overflow ) { Word16 var_out; @@ -2852,7 +2592,6 @@ Word16 shr_r_sat( Word16 var1, Word16 var2 ) Flag Overflow; return shr_ro( var1, var2, &Overflow ); } -#endif /*___________________________________________________________________________ | | | Function Name : mac_r | @@ -2891,7 +2630,6 @@ Word16 shr_r_sat( Word16 var1, Word16 var2 ) | range : 0x0000 8000 <= L_var_out <= 0x0000 7fff. | |___________________________________________________________________________| */ -#ifdef BASOP_NOGLOB Word16 mac_ro( Word32 L_var3, Word16 var1, Word16 var2, Flag *Overflow ) { Word16 var_out; @@ -2913,7 +2651,6 @@ Word16 mac_ro( Word32 L_var3, Word16 var1, Word16 var2, Flag *Overflow ) return ( var_out ); } -#endif /* BASOP_NOGLOB */ Word16 mac_r( Word32 L_var3, Word16 var1, Word16 var2 ) { Word16 var_out; @@ -2934,13 +2671,11 @@ Word16 mac_r( Word32 L_var3, Word16 var1, Word16 var2 ) return ( var_out ); } -#ifdef BASOP_NOGLOB Word16 mac_r_sat( Word32 L_var3, Word16 var1, Word16 var2 ) { Flag Overflow; return mac_ro( L_var3, var1, var2, &Overflow ); } -#endif /*___________________________________________________________________________ | | | Function Name : msu_r | @@ -2979,7 +2714,6 @@ Word16 mac_r_sat( Word32 L_var3, Word16 var1, Word16 var2 ) | range : 0x0000 8000 <= L_var_out <= 0x0000 7fff. | |___________________________________________________________________________| */ -#ifdef BASOP_NOGLOB Word16 msu_ro( Word32 L_var3, Word16 var1, Word16 var2, Flag *Overflow ) { Word16 var_out; @@ -2999,7 +2733,6 @@ Word16 msu_ro( Word32 L_var3, Word16 var1, Word16 var2, Flag *Overflow ) return ( var_out ); } -#endif /* BASOP_NOGLOB */ Word16 msu_r( Word32 L_var3, Word16 var1, Word16 var2 ) { Word16 var_out; @@ -3018,13 +2751,11 @@ Word16 msu_r( Word32 L_var3, Word16 var1, Word16 var2 ) return ( var_out ); } -#ifdef BASOP_NOGLOB Word16 msu_r_sat( Word32 L_var3, Word16 var1, Word16 var2 ) { Flag Overflow; return msu_ro( L_var3, var1, var2, &Overflow ); } -#endif /*___________________________________________________________________________ | | | Function Name : L_deposit_h | @@ -3189,7 +2920,6 @@ Word32 L_shr_r( Word32 L_var1, Word16 var2 ) return ( L_var_out ); } -#ifdef BASOP_NOGLOB Word32 L_shr_ro( Word32 L_var1, Word16 var2, Flag *Overflow ) { Word32 L_var_out; @@ -3217,7 +2947,6 @@ Word32 L_shr_r_sat( Word32 L_var1, Word16 var2 ) Flag Overflow = 0; return L_shr_ro( L_var1, var2, &Overflow ); } -#endif /*___________________________________________________________________________ | | | Function Name : L_abs | @@ -3307,11 +3036,7 @@ Word32 L_abs( Word32 L_var1 ) | range : 0x8000 0000 <= var_out <= 0x7fff ffff. | |___________________________________________________________________________| */ -#ifndef BASOP_NOGLOB -Word32 L_sat( Word32 L_var1 ) -#else /* BASOP_NOGLOB */ Word32 DEPR_L_sat_co( Word32 L_var1, Flag Overflow, Flag Carry ) -#endif /* BASOP_NOGLOB */ { Word32 L_var_out; @@ -3328,11 +3053,6 @@ Word32 DEPR_L_sat_co( Word32 L_var1, Flag Overflow, Flag Carry ) { L_var_out = MAX_32; } -#ifndef BASOP_NOGLOB - - Carry = 0; - Overflow = 0; -#endif /* ! BASOP_NOGLOB */ } #ifdef WMOPS @@ -3344,7 +3064,6 @@ Word32 DEPR_L_sat_co( Word32 L_var1, Flag Overflow, Flag Carry ) return ( L_var_out ); } -#ifdef BASOP_NOGLOB Word32 L_sat_co( Word32 L_var1, Flag Carry, Flag Overflow ) { Word32 L_var_out; @@ -3371,7 +3090,6 @@ Word32 L_sat( Word32 L_var1 ) assert( 0 ); /* Overflow and Carry are no longer global, must be passed as parameters */ return L_sat_co( L_var1, 0, 0 ); } -#endif /*___________________________________________________________________________ | | | Function Name : norm_s | @@ -3661,7 +3379,6 @@ Word16 norm_l( Word32 L_var1 ) | | |___________________________________________________________________________| */ -#ifdef BASOP_NOGLOB Word32 L_mls_o( Word32 Lv, Word16 v, Flag *Overflow ) { Word32 Temp; @@ -3683,7 +3400,6 @@ Word32 L_mls_o( Word32 Lv, Word16 v, Flag *Overflow ) return Temp; } -#endif /* BASOP_NOGLOB */ Word32 L_mls( Word32 Lv, Word16 v ) { Word32 Temp; @@ -3704,13 +3420,11 @@ Word32 L_mls( Word32 Lv, Word16 v ) return Temp; } -#ifdef BASOP_NOGLOB Word32 L_mls_sat( Word32 Lv, Word16 v ) { Flag Overflow; return L_mls_o( Lv, v, &Overflow ); } -#endif /*__________________________________________________________________________ | | @@ -3848,11 +3562,7 @@ Word16 div_l( Word32 L_num, Word16 den ) | are performed if ORIGINAL_G7231 is defined. | |___________________________________________________________________________| */ -#ifndef BASOP_NOGLOB -Word16 i_mult( Word16 a, Word16 b ) -#else /* BASOP_NOGLOB */ Word16 DEPR_i_mult( Word16 a, Word16 b ) -#endif /* BASOP_NOGLOB */ { #ifdef ORIGINAL_G7231 return a * b; @@ -3865,7 +3575,6 @@ Word16 DEPR_i_mult( Word16 a, Word16 b ) #endif } -#ifdef BASOP_NOGLOB Word16 i_mult_o( Word16 a, Word16 b, Flag *Overflow ) { #ifdef ORIGINAL_G7231 @@ -3884,7 +3593,6 @@ Word16 i_mult_sat( Word16 a, Word16 b ) Flag Overflow; return i_mult_o( a, b, &Overflow ); } -#endif /* ****************************************************************************** * The following three operators are not part of the original @@ -3964,7 +3672,6 @@ Word32 L_mult0( Word16 var1, Word16 var2 ) | range : 0x8000 0000 <= L_var_out <= 0x7fff ffff. |___________________________________________________________________________ */ -#ifdef BASOP_NOGLOB Word32 L_mac0_o( Word32 L_var3, Word16 var1, Word16 var2, Flag *Overflow ) { Word32 L_var_out; @@ -3984,7 +3691,6 @@ Word32 L_mac0_o( Word32 L_var3, Word16 var1, Word16 var2, Flag *Overflow ) return ( L_var_out ); } -#endif /* BASOP_NOGLOB */ Word32 L_mac0( Word32 L_var3, Word16 var1, Word16 var2 ) { Word32 L_var_out; @@ -4004,13 +3710,11 @@ Word32 L_mac0( Word32 L_var3, Word16 var1, Word16 var2 ) return ( L_var_out ); } -#ifdef BASOP_NOGLOB Word32 L_mac0_sat( Word32 L_var3, Word16 var1, Word16 var2 ) { Flag Overflow; return L_mac0_o( L_var3, var1, var2, &Overflow ); } -#endif /*___________________________________________________________________________ | | Function Name : L_msu0 @@ -4041,7 +3745,6 @@ Word32 L_mac0_sat( Word32 L_var3, Word16 var1, Word16 var2 ) | range : 0x8000 0000 <= L_var_out <= 0x7fff ffff. |___________________________________________________________________________ */ -#ifdef BASOP_NOGLOB Word32 L_msu0_o( Word32 L_var3, Word16 var1, Word16 var2, Flag *Overflow ) { Word32 L_var_out; @@ -4061,7 +3764,6 @@ Word32 L_msu0_o( Word32 L_var3, Word16 var1, Word16 var2, Flag *Overflow ) return ( L_var_out ); } -#endif /* BASOP_NOGLOB */ Word32 L_msu0( Word32 L_var3, Word16 var1, Word16 var2 ) { Word32 L_var_out; @@ -4081,12 +3783,10 @@ Word32 L_msu0( Word32 L_var3, Word16 var1, Word16 var2 ) return ( L_var_out ); } -#ifdef BASOP_NOGLOB Word32 L_msu0_sat( Word32 L_var3, Word16 var1, Word16 var2 ) { Flag Overflow; return L_msu0_o( L_var3, var1, var2, &Overflow ); } -#endif #undef WMC_TOOL_SKIP diff --git a/lib_com/basop32.h b/lib_com/basop32.h index 785a4bf5629ea7cd01cc505904a6b30d47a40ce5..9bbf24f1c52e1c5159ad4ff22fa6720f3bfcd60a 100644 --- a/lib_com/basop32.h +++ b/lib_com/basop32.h @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other @@ -86,17 +86,11 @@ | Constants and Globals | |___________________________________________________________________________| */ -#ifndef BASOP_NOGLOB -extern Flag Overflow, Overflow2; -extern Flag Carry; - -#else /* BASOP_NOGLOB */ /* DISABLED TO AVOID GLOBAL VARIABLES */ /* extern Flag BASOP_Overflow, BASOP_Overflow2; extern Flag BASOP_Carry; */ -#endif /* BASOP_NOGLOB */ #define BASOP_SATURATE_WARNING_ON_EVS #define BASOP_SATURATE_WARNING_OFF_EVS #define BASOP_SATURATE_ERROR_ON_EVS @@ -114,36 +108,17 @@ extern Flag BASOP_Carry; #define MAX_16 (Word16) 0x7fff #define MIN_16 (Word16) 0x8000 -#ifdef BASOP_NOGLOB void set_overflow( Flag *overflow ); void unset_overflow( Flag *overflow ); void set_carry( Flag *carry ); void unset_carry( Flag *carry ); Flag get_carry( const Flag *carry ); -#endif /* BASOP_NOGLOB */ /*___________________________________________________________________________ | | | Prototypes for basic arithmetic operators | |___________________________________________________________________________| */ -#ifndef BASOP_NOGLOB -Word16 add( Word16 var1, Word16 var2 ); /* Short add, 1 */ -Word16 sub( Word16 var1, Word16 var2 ); /* Short sub, 1 */ -Word16 abs_s( Word16 var1 ); /* Short abs, 1 */ -Word16 shl( Word16 var1, Word16 var2 ); /* Short shift left, 1 */ -Word16 shr( Word16 var1, Word16 var2 ); /* Short shift right, 1 */ -Word16 mult( Word16 var1, Word16 var2 ); /* Short mult, 1 */ -Word32 L_mult( Word16 var1, Word16 var2 ); /* Long mult, 1 */ -Word16 negate( Word16 var1 ); /* Short negate, 1 */ -Word16 extract_h( Word32 L_var1 ); /* Extract high, 1 */ -Word16 extract_l( Word32 L_var1 ); /* Extract low, 1 */ -Word16 round_fx( Word32 L_var1 ); /* Round, 1 */ -Word32 L_mac( Word32 L_var3, Word16 var1, Word16 var2 ); /* Mac, 1 */ -Word32 L_msu( Word32 L_var3, Word16 var1, Word16 var2 ); /* Msu, 1 */ -Word32 L_macNs( Word32 L_var3, Word16 var1, Word16 var2 ); /* Mac without - sat, 1 */ -#else /* BASOP_NOGLOB */ Word16 add( Word16 var1, Word16 var2 ); /* Short add, 1 */ Word16 sub( Word16 var1, Word16 var2 ); /* Short sub, 1 */ Word16 abs_s( Word16 var1 ); /* Short abs, 1 */ @@ -163,33 +138,14 @@ Word32 L_macNs( Word32 L_var3, Word16 var1, Word16 var2 ); /* Word32 L_msuNs( Word32 L_var3, Word16 var1, Word16 var2 ); /* Msu without sat, 1 */ Word32 L_add_co( Word32 L_var1, Word32 L_var2, Flag *Carry, Flag *Overflow ); Word32 L_sub_co( Word32 L_var1, Word32 L_var2, Flag *Carry, Flag *Overflow ); -Word32 L_add_c( Word32 L_var1, Word32 L_var2 ); /* Long add with c, 2 */ -Word32 L_sub_c( Word32 L_var1, Word32 L_var2 ); /* Long sub with c, 2 */ +Word32 L_sub_c( Word32 L_var1, Word32 L_var2 ); /* Long sub with c, 2 */ -#endif /* BASOP_NOGLOB */ -#ifndef BASOP_NOGLOB -Word32 L_msuNs( Word32 L_var3, Word16 var1, Word16 var2 ); /* Msu without - sat, 1 */ -#else /* BASOP_NOGLOB */ Word32 DEPR_L_msuNs( Word32 L_var3, Word16 var1, Word16 var2, Flag *Carry ); /* Msu without sat, 1 */ -#endif /* BASOP_NOGLOB */ -#ifndef BASOP_NOGLOB -Word32 L_add( Word32 L_var1, Word32 L_var2 ); /* Long add, 1 */ -Word32 L_sub( Word32 L_var1, Word32 L_var2 ); /* Long sub, 1 */ -Word32 L_add_c( Word32 L_var1, Word32 L_var2 ); /* Long add with c, 2 */ -Word32 L_sub_c( Word32 L_var1, Word32 L_var2 ); /* Long sub with c, 2 */ -Word32 L_negate( Word32 L_var1 ); /* Long negate, 1 */ -Word16 mult_r( Word16 var1, Word16 var2 ); /* Mult with round, 1 */ -Word32 L_shl( Word32 L_var1, Word16 var2 ); /* Long shift left, 1 */ -Word32 L_shr( Word32 L_var1, Word16 var2 ); /* Long shift right, 1 */ -Word16 shr_r( Word16 var1, Word16 var2 ); /* Shift right with - round, 2 */ -#else /* BASOP_NOGLOB */ Word32 L_add( Word32 L_var1, Word32 L_var2 ); /* Long add, 1 */ Word32 L_sub( Word32 L_var1, Word32 L_var2 ); /* Long sub, 1 */ -Word32 DEPR_L_add_c( Word32 L_var1, Word32 L_var2, Flag *Carry ); /* Long add with c, 2 */ +Word32 L_add_c( Word32 L_var1, Word32 L_var2, Flag *Carry ); /* Long add with c, 2 */ Word32 DEPR_L_sub_c( Word32 L_var1, Word32 L_var2, Flag *Carry ); /* Long sub with c, 2 */ Word32 L_negate( Word32 L_var1 ); /* Long negate, 1 */ Word16 mult_r( Word16 var1, Word16 var2 ); /* Mult with round, 1 */ @@ -197,67 +153,32 @@ Word32 L_shl( Word32 L_var1, Word16 var2 ); /* Word32 L_shr( Word32 L_var1, Word16 var2 ); /* Long shift right, 1 */ Word16 shr_r( Word16 var1, Word16 var2 ); /* Shift right with round, 2 */ -#endif /* BASOP_NOGLOB */ -#ifndef BASOP_NOGLOB Word16 mac_r( Word32 L_var3, Word16 var1, Word16 var2 ); /* Mac with - rounding, 1 */ -#else /* BASOP_NOGLOB */ -Word16 mac_r( Word32 L_var3, Word16 var1, Word16 var2 ); /* Mac with - rounding, 1 */ -#endif /* BASOP_NOGLOB */ -#ifndef BASOP_NOGLOB + rounding, 1 */ Word16 msu_r( Word32 L_var3, Word16 var1, Word16 var2 ); /* Msu with - rounding, 1 */ -#else /* BASOP_NOGLOB */ -Word16 msu_r( Word32 L_var3, Word16 var1, Word16 var2 ); /* Msu with - rounding, 1 */ -#endif /* BASOP_NOGLOB */ -#ifndef BASOP_NOGLOB -Word32 L_deposit_h( Word16 var1 ); /* 16 bit var1 -> MSB, 1 */ -Word32 L_deposit_l( Word16 var1 ); /* 16 bit var1 -> LSB, 1 */ -#else /* BASOP_NOGLOB */ -Word32 L_deposit_h( Word16 var1 ); /* 16 bit var1 -> MSB, 1 */ -Word32 L_deposit_l( Word16 var1 ); /* 16 bit var1 -> LSB, 1 */ -#endif /* BASOP_NOGLOB */ - -#ifndef BASOP_NOGLOB -Word32 L_shr_r( Word32 L_var1, Word16 var2 ); /* Long shift right with - round, 3 */ -#else /* BASOP_NOGLOB */ -Word32 L_shr_r( Word32 L_var1, Word16 var2 ); /* Long shift right with - round, 3 */ -#endif /* BASOP_NOGLOB */ -#ifndef BASOP_NOGLOB -Word32 L_abs( Word32 L_var1 ); /* Long abs, 1 */ -Word32 L_sat( Word32 L_var1 ); /* Long saturation, 4 */ -Word16 norm_s( Word16 var1 ); /* Short norm, 1 */ -Word16 div_s( Word16 var1, Word16 var2 ); /* Short division, 18 */ -Word16 norm_l( Word32 L_var1 ); /* Long norm, 1 */ -#else /* BASOP_NOGLOB */ -Word32 L_abs( Word32 L_var1 ); /* Long abs, 1 */ -Word32 DEPR_L_sat_co( Word32 L_var1, Flag Overflow, Flag Carry ); /* Long saturation, 4 */ -Word16 norm_s( Word16 var1 ); /* Short norm, 1 */ -Word16 div_s( Word16 var1, Word16 var2 ); /* Short division, 18 */ + rounding, 1 */ +Word32 L_deposit_h( Word16 var1 ); /* 16 bit var1 -> MSB, 1 */ +Word32 L_deposit_l( Word16 var1 ); /* 16 bit var1 -> LSB, 1 */ + +Word32 L_shr_r( Word32 L_var1, Word16 var2 ); /* Long shift right with + round, 3 */ +Word32 L_abs( Word32 L_var1 ); /* Long abs, 1 */ +Word32 DEPR_L_sat_co( Word32 L_var1, Flag Overflow, Flag Carry ); /* Long saturation, 4 */ +Word16 norm_s( Word16 var1 ); /* Short norm, 1 */ +Word16 div_s( Word16 var1, Word16 var2 ); /* Short division, 18 */ Word32 div_w( Word32 L_num, Word32 L_den ); -Word16 norm_l( Word32 L_var1 ); /* Long norm, 1 */ -Word32 L_sat( Word32 L_var1 ); /* Long saturation, 4 */ -#endif /* BASOP_NOGLOB */ +Word16 norm_l( Word32 L_var1 ); /* Long norm, 1 */ +Word32 L_sat( Word32 L_var1 ); /* Long saturation, 4 */ /* * Additional G.723.1 operators */ -#ifndef BASOP_NOGLOB -Word32 L_mls( Word32, Word16 ); /* Weight FFS; currently assigned 5 */ -Word16 div_l( Word32, Word16 ); /* Weight FFS; currently assigned 32 */ -Word16 i_mult( Word16 a, Word16 b ); /* Weight FFS; currently assigned 3 */ -#else /* BASOP_NOGLOB */ Word32 L_mls( Word32, Word16 ); /* Weight FFS; currently assigned 5 */ Word16 div_l( Word32, Word16 ); /* Weight FFS; currently assigned 32 */ Word16 i_mult( Word16 a, Word16 b ); /* Weight FFS; currently assigned 3 */ Word16 DEPR_i_mult( Word16 a, Word16 b ); /* Weight FFS; currently assigned 3 */ -#endif /* BASOP_NOGLOB */ /* * New shiftless operators, not used in G.729/G.723.1 @@ -265,7 +186,6 @@ Word16 DEPR_i_mult( Word16 a, Word16 b ); /* Weight FFS; currently assigned 3 */ Word32 L_mult0( Word16 v1, Word16 v2 ); /* 32-bit Multiply w/o shift 1 */ Word32 L_mac0( Word32 L_v3, Word16 v1, Word16 v2 ); /* 32-bit Mac w/o shift 1 */ Word32 L_msu0( Word32 L_v3, Word16 v1, Word16 v2 ); /* 32-bit Msu w/o shift 1 */ -#ifdef BASOP_NOGLOB /* * Overflowing operators @@ -296,7 +216,6 @@ Word32 L_shr_ro( Word32 L_var1, Word16 var2, Flag *Overflow ); Word32 L_macNs_co( Word32 L_var3, Word16 var1, Word16 var2, Flag *Carry, Flag *Overflow ); Word32 L_msuNs_co( Word32 L_var3, Word16 var1, Word16 var2, Flag *Carry, Flag *Overflow ); -#endif /* BASOP_NOGLOB */ /* * Saturating operators diff --git a/lib_com/basop_com_lpc.c b/lib_com/basop_com_lpc.c index 5de4fa5d38de1aedc2e7f87f90696e4141b1f29b..5cfb3bed0e55fdee2e46202c92dab4b503f14ad9 100644 --- a/lib_com/basop_com_lpc.c +++ b/lib_com/basop_com_lpc.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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_com/basop_lsf_tools.c b/lib_com/basop_lsf_tools.c index aac96ae5fc98a6ed855b0d907ae0a3cf8220e037..2c49ad4cf4d22a50ff63d8cc6e85330fe54aba98 100644 --- a/lib_com/basop_lsf_tools.c +++ b/lib_com/basop_lsf_tools.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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,9 +245,7 @@ static Word16 E_LPC_f_lsp_pol_get( Word16 Ovf = 0; Word16 Q_out; Word16 m2; -#ifdef BASOP_NOGLOB Flag Overflow; -#endif /* BASOP_NOGLOB */ move16(); // move for Ovf = 0 Q_out = 31 - 23; @@ -302,9 +300,7 @@ static Word16 E_LPC_f_lsp_pol_get( test(); IF( Overflow > 0 && isMODE1 ) { -#ifdef BASOP_NOGLOB assert( 0 ); -#endif /* BASOP_NOGLOB */ /* If an overflow is detected, redo the computation with 1 bit less */ Ovf = add( Ovf, 1 ); Ovf = E_LPC_f_lsp_pol_get( lsp, f, n, Ovf, isMODE1 ); /* Q0 */ diff --git a/lib_com/basop_proto_func.h b/lib_com/basop_proto_func.h index be8b46782642e231a8464766cff0896a35950be8..29db9c9c19e27f3b121780349c4b254cbee18307 100644 --- a/lib_com/basop_proto_func.h +++ b/lib_com/basop_proto_func.h @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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_com/basop_settings.h b/lib_com/basop_settings.h index a2ef70417c13dad0b28e0f899b4fddc100b5b0cb..9a344afc4b4ac449e9585a0f8a935a6d829ec5f2 100644 --- a/lib_com/basop_settings.h +++ b/lib_com/basop_settings.h @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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_com/basop_tcx_utils.c b/lib_com/basop_tcx_utils.c index 17f0e23babba3f832ebc632be5861669b2896442..8038c4f91e44fa3d4f3be746e03c2e3f1a7816ce 100644 --- a/lib_com/basop_tcx_utils.c +++ b/lib_com/basop_tcx_utils.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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,7 @@ #include "cnst.h" #include "basop_proto_func.h" #include "stl.h" -#include "prot.h" +#include "prot_fx.h" #include "rom_com.h" #define WMC_TOOL_SKIP diff --git a/lib_com/basop_util.c b/lib_com/basop_util.c index c4f40c6df6080faab71efb203dacdb31e808d86b..b7ee35ab3652df0a2c64aa61715c992dd4f96808 100644 --- a/lib_com/basop_util.c +++ b/lib_com/basop_util.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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,6 @@ #include "basop_settings.h" #include "cnst.h" - -#define WMC_TOOL_SKIP - extern const Word32 SqrtTable[32]; // Q31 extern const Word16 SqrtDiffTable[32]; /* Q15 */ @@ -306,11 +303,7 @@ void BASOP_Util_Divide_MantExp( Word16 a_m, /*!< Mantissa of dividend a /* normalize result */ postShift = norm_l( m32 ); -#ifdef BASOP_NOGLOB m = round_fx_o( L_shl( m32, postShift ), &Overflow ); -#else - m = round_fx( L_shl( m32, postShift ) ); -#endif /* exponent */ *ptrResult_e = sub( add( add( a_e, sub( 1, b_e ) ), preShift ), postShift ); @@ -326,9 +319,7 @@ static Word16 Sqrt16_common( Word16 m, Word16 e ) { Word16 index, frac; -#ifdef BASOP_NOGLOB Flag Overflow; -#endif assert( ( m >= 0x4000 ) || ( m == 0 ) ); @@ -344,11 +335,7 @@ static Word16 Sqrt16_common( Word16 m, if ( m != 0 ) { BASOP_SATURATE_WARNING_OFF_EVS; -#ifdef BASOP_NOGLOB m = mac_ro( SqrtTable[index], SqrtDiffTable[index], frac, &Overflow ); -#else - m = mac_r( SqrtTable[index], SqrtDiffTable[index], frac ); -#endif BASOP_SATURATE_WARNING_ON_EVS; } @@ -371,11 +358,7 @@ static Word32 Sqrt32_common( Word32 m, assert( ( m >= 0x40000000 ) || ( m == 0 ) ); -#ifdef BASOP_NOGLOB m16 = round_fx_o( m, &Overflow ); -#else /* BASOP_NOGLOB */ - m16 = round_fx( m ); -#endif /* BASOP_NOGLOB */ /* get table index (upper 6 bits minus 32) */ /* index = (m16 >> 9) - 32; */ @@ -388,11 +371,7 @@ static Word32 Sqrt32_common( Word32 m, if ( m != 0 ) { BASOP_SATURATE_WARNING_OFF_EVS; -#ifdef BASOP_NOGLOB m = L_mac_sat( SqrtTable[index], SqrtDiffTable[index], frac ); -#else - m = L_mac( SqrtTable[index], SqrtDiffTable[index], frac ); -#endif BASOP_SATURATE_WARNING_ON_EVS; } @@ -423,7 +402,9 @@ static Word16 ISqrt16_common( Word16 m, /* handle even exponents */ if ( s_and( e, 1 ) == 0 ) + { m = mult_r( m, 0x5a82 ); + } return m; } @@ -438,8 +419,7 @@ static Word32 ISqrt32_common( Word32 m, #endif assert( m >= 0x40000000 ); - -#ifdef BASOP_NOGLOB +#ifdef BASOP_NOGLOB_DECLARE_LOCAL m16 = round_fx_o( m, &Overflow ); #else m16 = round_fx( m ); @@ -457,7 +437,9 @@ static Word32 ISqrt32_common( Word32 m, /* handle even exponents */ if ( s_and( e, 1 ) == 0 ) + { m = Mpy_32_16_1( m, 0x5a82 ); + } return m; } @@ -676,13 +658,8 @@ void BASOP_Util_Sqrt_InvSqrt_MantExp( Word16 mantissa, /*!< mantissa */ /* interpolate */ BASOP_SATURATE_WARNING_OFF_EVS; -#ifdef BASOP_NOGLOB m = mac_r_sat( SqrtTable[index], SqrtDiffTable[index], frac ); mi = msu_r_sat( ISqrtTable[index], ISqrtDiffTable[index], frac ); -#else - m = mac_r( SqrtTable[index], SqrtDiffTable[index], frac ); - mi = msu_r( ISqrtTable[index], ISqrtDiffTable[index], frac ); -#endif BASOP_SATURATE_WARNING_ON_EVS; /* handle even/odd exponents */ @@ -929,11 +906,7 @@ Word16 divide3232( Word32 L_num, Word32 L_denom ) L_denom = L_shl( L_denom, z ); /* round_fx instead of extract_h improves spectral distortion in E_UTIL_lev_dur (schur version). */ -#ifdef BASOP_NOGLOB z = div_l( L_num, round_fx_o( L_denom, &Overflow ) ); -#else - z = div_l( L_num, round_fx( L_denom ) ); -#endif if ( 0 != sign ) { z = negate( z ); @@ -1436,11 +1409,7 @@ Word16 getCosWord16R2( BASOP_SATURATE_WARNING_OFF sine = negate( sine ); /* Saturation has been included based on the recommendation from the PC group */ -#ifdef BASOP_NOGLOB result = msu_r_sat( L_mult( sine, residual ), cosine, -32768 ); -#else - result = msu_r( L_mult( sine, residual ), cosine, -32768 ); -#endif BASOP_SATURATE_WARNING_ON return result; @@ -1483,11 +1452,7 @@ Word16 getSqrtWord32( Word32 val ) exp = sub( 31 - 32, exp2 ); L_temp = Isqrt_lc( L_temp2, &exp ); /* 12 clks */ -#ifdef BASOP_NOGLOB temp = round_fx_sat( L_temp ); -#else - temp = round_fx( L_temp ); -#endif L_temp = Mpy_32_16_1( L_temp2, temp ); /* 2 clks */ L_temp = L_shl( L_temp, sub( exp, exp2 ) ); @@ -1675,13 +1640,8 @@ Word32 norm_llQ31( /* o : normalized result Q31 */ /* Move MSBit of L_sum into L_c */ Carry = 0; -#ifdef BASOP_NOGLOB L_tmp = L_add_co( L_sum, L_sum, &Carry, &Overflow ); /* L_tmp = L_sum << 1 */ L_c = L_add_co( L_c, L_c, &Carry, &Overflow ); -#else /* BASOP_NOGLOB */ - L_tmp = L_add_c( L_sum, L_sum ); /* L_tmp = L_sum << 1 */ - L_c = L_add_c( L_c, L_c ); -#endif L_add( 0, 0 ); test(); IF( ( L_c != (Word32) 0L ) && ( L_c != (Word32) 0xFFFFFFFFL ) ) @@ -1777,13 +1737,8 @@ Word32 Norm32Norm( const Word32 *x, const Word16 headroom, const Word16 length, if ( L_tmp2 >= 0 ) L_tmp = L_shr( L_tmp, 2 ); -#ifdef BASOP_NOGLOB tmp = round_fx_sat( L_shl_sat( x[i], shift ) ); L_tmp = L_mac0_sat( L_tmp, tmp, tmp ); /* exponent = (1-shift*2) , Q(30+shift*2) */ -#else - tmp = round_fx( L_shl( x[i], shift ) ); - L_tmp = L_mac0( L_tmp, tmp, tmp ); /* exponent = (1-shift*2) , Q(30+shift*2) */ -#endif } move16(); @@ -2217,11 +2172,7 @@ Word16 BASOP_Util_Cmp_Mant32Exp /*!< o: flag: result of comparison */ } BASOP_SATURATE_WARNING_OFF_EVS -#ifdef BASOP_NOGLOB diff_m = L_sub_sat( a_m, b_m ); -#else - diff_m = L_sub( a_m, b_m ); -#endif BASOP_SATURATE_WARNING_ON_EVS diff_e = sub( a_e, b_e ); @@ -2392,11 +2343,7 @@ void bufferCopyFx( { FOR( i = 0; i < length; i++ ) { -#ifdef BASOP_NOGLOB *( dest + i ) = shr_sat( *( src + i ), tmp_16 ); -#else - *( dest + i ) = shr( *( src + i ), tmp_16 ); -#endif move16(); } } @@ -2710,6 +2657,3 @@ cmplx CL_mult_32x16( cmplx input, cmplx_s coeff ) #endif return result; } - - -#undef WMC_TOOL_SKIP diff --git a/lib_com/basop_util.h b/lib_com/basop_util.h index 92994542e564c3d6856f667be8e387e797c4071b..a6db7dc8d62ced0c28ff5010bf7ef9513eb04c5e 100644 --- a/lib_com/basop_util.h +++ b/lib_com/basop_util.h @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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_com/bitalloc_fx.c b/lib_com/bitalloc_fx.c index 3400b533d9ca4beb7db245b4e4df2ae4d639b7a0..30ae2d47b028021152ead282c240af1a18c6f46b 100644 --- a/lib_com/bitalloc_fx.c +++ b/lib_com/bitalloc_fx.c @@ -7,7 +7,6 @@ #include "cnst.h" /* Common constants */ #include "rom_com.h" /* Static table prototypes */ #include "prot_fx.h" /* Function prototypes */ -#include "prot.h" /* Function prototypes */ void bitalloc_fx( Word16 *y, /* i : reordered norm of sub-vectors Q0 */ @@ -55,11 +54,7 @@ void bitalloc_fx( move16(); FOR( m = 1; m < im; m++ ) { -#ifdef BASOP_NOGLOB v = sub_o( temp, y[m], &Overflow ); /* Q0 */ -#else /* BASOP_NOGLOB */ - v = sub( temp, y[m] ); -#endif temp = s_max( temp, y[m] ); if ( v < 0 ) { @@ -380,11 +375,7 @@ Word16 BitAllocF_fx( exp1 = sub( norm_l( L_tmp1 ), 1 ); exp2 = norm_s( n ); tmp = div_s( extract_h( L_shl( L_tmp1, exp1 ) ), shl( n, exp2 ) ); /*15 + 15 + exp1 - 16 - exp2*/ -#ifdef BASOP_NOGLOB - m_fx = shl_sat( tmp, sub( exp2, exp1 ) ); /*Q14*/ -#else - m_fx = shl( tmp, sub( exp2, exp1 ) ); /*Q14*/ -#endif + m_fx = shl_sat( tmp, sub( exp2, exp1 ) ); /*Q14*/ t_fx = L_deposit_l( 0 ); n = 0; move16(); @@ -451,11 +442,7 @@ Word16 BitAllocF_fx( exp1 = sub( norm_l( L_tmp2 ), 1 ); exp2 = norm_s( n ); tmp = div_s( extract_h( L_shl( L_tmp2, exp1 ) ), shl( n, exp2 ) ); /*15 + 15 + exp1 - 16 - exp2*/ -#ifdef BASOP_NOGLOB - m_fx = shl_o( tmp, sub( exp2, exp1 ), &Overflow ); /*Q14*/ -#else - m_fx = shl( tmp, sub( exp2, exp1 ) ); /*Q14*/ -#endif + m_fx = shl_o( tmp, sub( exp2, exp1 ), &Overflow ); /*Q14*/ if ( L_tmp1 < 0 ) { m_fx = negate( m_fx ); diff --git a/lib_com/bits_alloc_fx.c b/lib_com/bits_alloc_fx.c index 83a98a85f8b00d2bfa36490cd4df6db4f98682d1..88b276126a66e4b3aa9064e073b9cd8295264f27 100644 --- a/lib_com/bits_alloc_fx.c +++ b/lib_com/bits_alloc_fx.c @@ -408,7 +408,7 @@ static Word16 BITS_ALLOC_adjust_acelp_fixed_cdk( return bitsused; } -/*#ifdef IVAS_CODE Below basop operators are missing */ + /*-------------------------------------------------------------------* * fcb_table() * @@ -762,17 +762,20 @@ static ivas_error acelp_FCB_allocator_ivas( *--------------------------------------------------------------------*/ ivas_error config_acelp1( - const Word16 enc_dec, /* i : encoder/decoder flag */ - const Word32 total_brate, /* i : total bitrate */ - const Word32 core_brate_inp, /* i : core bitrate */ - const Word16 core, /* i : core */ - const Word16 extl, /* i : extension layer */ - const Word32 extl_brate, /* i : extension layer bitrate */ - const Word16 L_frame, /* i : frame length at internal Fs */ - const Word16 GSC_noisy_speech, /* i : GSC on SWB noisy speech flag */ - ACELP_config *acelp_cfg, /* i : ACELP bit-allocation */ - const Word16 signalling_bits, /* i : number of signalling bits */ - const Word16 coder_type, /* i : coder type */ + const Word16 enc_dec, /* i : encoder/decoder flag */ + const Word32 total_brate, /* i : total bitrate */ + const Word32 core_brate_inp, /* i : core bitrate */ + const Word16 core, /* i : core */ + const Word16 extl, /* i : extension layer */ + const Word32 extl_brate, /* i : extension layer bitrate */ + const Word16 L_frame, /* i : frame length at internal Fs */ + const Word16 GSC_noisy_speech, /* i : GSC on SWB noisy speech flag */ + ACELP_config *acelp_cfg, /* i : ACELP bit-allocation */ + const Word16 signalling_bits, /* i : number of signalling bits */ + const Word16 coder_type, /* i : coder type */ +#ifdef NONBE_FIX_GSC_BSTR + const Word16 inactive_coder_type_flag, /* i : AVQ (0) or GSC (1) IC flag */ +#endif const Word16 tc_subfr, /* i : TC subfr ID */ const Word16 tc_call, /* i : TC call number (0,1,2,3,5(DEC)) */ Word16 *nBits_es_Pred, /* o : number of bits for Es_pred Q */ @@ -1068,14 +1071,20 @@ ivas_error config_acelp1( { bits = sub( bits, TDM_IC_LSF_PRED_BITS ); } - /* gain Q bit-budget - part 1 */ + /* gain Q bit-budget - part 1: 'Es_pred' of memory-less gain Q */ test(); test(); test(); test(); test(); test(); +#ifdef NONBE_FIX_GSC_BSTR + IF( ( NE_16( coder_type, UNVOICED ) && NE_16( coder_type, AUDIO ) && coder_type != INACTIVE && !( LE_32( core_brate, ACELP_8k00 ) && NE_16( coder_type, TRANSITION ) ) ) /* mid bitrates in GC and VC, low+mid bitrates in TC */ || + ( coder_type == INACTIVE && !inactive_coder_type_flag ) /* AVQ inactive */ + ) +#else IF( ( NE_16( coder_type, UNVOICED ) && NE_16( coder_type, AUDIO ) && coder_type != INACTIVE && !( LE_32( core_brate, ACELP_8k00 ) && NE_16( coder_type, TRANSITION ) ) ) || ( coder_type == INACTIVE && GT_32( total_brate, MAX_GSC_INACTIVE_BRATE ) ) ) +#endif { *nBits_es_Pred = Es_pred_bits_tbl[BIT_ALLOC_IDX_fx( core_brate, coder_type, -1, -1 )]; move16(); @@ -1196,7 +1205,11 @@ ivas_error config_acelp1( { test(); test(); +#ifdef NONBE_FIX_GSC_BSTR + IF( coder_type == INACTIVE && EQ_16( L_frame, L_FRAME16k ) && inactive_coder_type_flag ) /* GSC Inactive @16kHz */ +#else IF( coder_type == INACTIVE && EQ_16( L_frame, L_FRAME16k ) && LE_32( total_brate, MAX_GSC_INACTIVE_BRATE ) ) /* GSC Inactive @16kHz */ +#endif { acelp_cfg->ltf_mode = FULL_BAND; move16(); @@ -1414,7 +1427,14 @@ ivas_error config_acelp1( acelp_cfg->fixed_cdk_index[3] = -1; move16(); } +#ifdef NONBE_FIX_GSC_BSTR + ELSE IF( ( coder_type != INACTIVE && EQ_16( nb_subfr, NB_SUBFR ) && NE_16( coder_type, AUDIO ) ) || /* @12.8kHz core except of GSC */ + ( EQ_16( nb_subfr, NB_SUBFR16k ) && ( !inactive_coder_type_flag || coder_type != INACTIVE ) ) /* @16kHz core GC, TC, AVQ inactive */ || + EQ_16( core, HQ_CORE ) /* ACELP -> HQ switching in EVS */ + ) +#else ELSE IF( ( coder_type != INACTIVE && EQ_16( nb_subfr, NB_SUBFR ) && NE_16( coder_type, AUDIO ) ) || ( EQ_16( nb_subfr, NB_SUBFR16k ) && ( GT_32( total_brate, MAX_GSC_INACTIVE_BRATE ) || coder_type != INACTIVE ) ) || EQ_16( core, HQ_CORE ) ) +#endif { /* pitch Q & gain Q bit-budget - part 2*/ FOR( i = 0; i < nb_subfr; i++ ) @@ -1478,7 +1498,13 @@ ivas_error config_acelp1( test(); test(); test(); +#ifdef NONBE_FIX_GSC_BSTR + IF( flag_hardcoded /* EVS */ || + ( GE_32( core_brate_inp, MIN_BRATE_AVQ_EXC ) && coder_type != INACTIVE ) /* high-birate ACELP except IC */ || + ( !inactive_coder_type_flag && coder_type == INACTIVE ) /* AVQ inactive */ ) +#else IF( flag_hardcoded || ( GE_32( core_brate_inp, MIN_BRATE_AVQ_EXC ) && coder_type != INACTIVE ) || ( GT_32( total_brate, MAX_GSC_INACTIVE_BRATE ) && coder_type == INACTIVE ) ) +#endif { FOR( i = 0; i < nb_subfr; i++ ) { @@ -1587,7 +1613,12 @@ ivas_error config_acelp1( test(); test(); test(); +#ifdef NONBE_FIX_GSC_BSTR + IF( ( GE_32( core_brate_inp, MIN_BRATE_AVQ_EXC ) && coder_type != INACTIVE ) /* high-birate ACELP except IC */ || + ( !inactive_coder_type_flag && coder_type == INACTIVE ) /* AVQ inactive */ ) +#else IF( ( GE_32( core_brate_inp, MIN_BRATE_AVQ_EXC ) && coder_type != INACTIVE ) || ( GT_32( total_brate, MAX_GSC_INACTIVE_BRATE ) && coder_type == INACTIVE ) ) +#endif { FOR( i = 0; i < nb_subfr; i++ ) { @@ -1627,7 +1658,13 @@ ivas_error config_acelp1( } } } +#ifdef NONBE_FIX_GSC_BSTR + ELSE IF( ( EQ_16( coder_type, UNVOICED ) && EQ_16( tdm_low_rate_mode, 1 ) && EQ_16( element_mode, IVAS_CPE_TD ) ) /* LBR secondary channel in TD stereo */ || + ( ( coder_type == INACTIVE || EQ_16( coder_type, AUDIO ) ) && EQ_16( nb_subfr, NB_SUBFR ) ) /* GSC @12.8kHz */ || + ( coder_type == INACTIVE && inactive_coder_type_flag ) /* AVQ inactive */ ) +#else ELSE IF( ( EQ_16( coder_type, UNVOICED ) && EQ_16( tdm_low_rate_mode, 1 ) && EQ_16( element_mode, IVAS_CPE_TD ) ) || ( ( coder_type == INACTIVE || EQ_16( coder_type, AUDIO ) ) && EQ_16( nb_subfr, NB_SUBFR ) ) || ( coder_type == INACTIVE && LE_32( total_brate, MAX_GSC_INACTIVE_BRATE ) ) ) +#endif { Word32 Local_BR, Pitch_BR; Word16 Pitch_CT; @@ -1768,7 +1805,12 @@ ivas_error config_acelp1( test(); test(); test(); +#ifdef NONBE_FIX_GSC_BSTR + IF( ( EQ_16( L_frame, L_FRAME16k ) && coder_type == INACTIVE && inactive_coder_type_flag ) /* GSC Inactive @16kHz */ || + ( GSC_IVAS_mode > 0 && EQ_16( L_frame, L_FRAME16k ) ) ) /* IVAS GSC @16kHz */ +#else IF( ( EQ_16( L_frame, L_FRAME16k ) && coder_type == INACTIVE && LE_32( total_brate, MAX_GSC_INACTIVE_BRATE ) ) || ( GSC_IVAS_mode > 0 && EQ_16( L_frame, L_FRAME16k ) ) ) /* GSC Inactive @16kHz */ +#endif { acelp_cfg->ubits = 0; move16(); @@ -1877,17 +1919,20 @@ ivas_error config_acelp1( *--------------------------------------------------------------------*/ ivas_error config_acelp1_IVAS( - const Word16 enc_dec, /* i : encoder/decoder flag */ - const Word32 total_brate, /* i : total bitrate */ - const Word32 core_brate_inp, /* i : core bitrate */ - const Word16 core, /* i : core */ - const Word16 extl, /* i : extension layer */ - const Word32 extl_brate, /* i : extension layer bitrate */ - const Word16 L_frame, /* i : frame length at internal Fs */ - const Word16 GSC_noisy_speech, /* i : GSC on SWB noisy speech flag */ - ACELP_config *acelp_cfg, /* i : ACELP bit-allocation */ - const Word16 signaling_bits, /* i : number of signaling bits */ - const Word16 coder_type, /* i : coder type */ + const Word16 enc_dec, /* i : encoder/decoder flag */ + const Word32 total_brate, /* i : total bitrate */ + const Word32 core_brate_inp, /* i : core bitrate */ + const Word16 core, /* i : core */ + const Word16 extl, /* i : extension layer */ + const Word32 extl_brate, /* i : extension layer bitrate */ + const Word16 L_frame, /* i : frame length at internal Fs */ + const Word16 GSC_noisy_speech, /* i : GSC on SWB noisy speech flag */ + ACELP_config *acelp_cfg, /* i : ACELP bit-allocation */ + const Word16 signaling_bits, /* i : number of signaling bits */ + const Word16 coder_type, /* i : coder type */ +#ifdef NONBE_FIX_GSC_BSTR + const Word16 inactive_coder_type_flag, /* i : AVQ (0) or GSC (1) IC flag */ +#endif const Word16 tc_subfr, /* i : TC subfr ID */ const Word16 tc_call, /* i : TC call number (0,1,2,3,5(DEC)) */ Word16 *nBits_es_Pred, /* o : number of bits for Es_pred Q */ @@ -2168,8 +2213,13 @@ ivas_error config_acelp1_IVAS( test(); test(); test(); - /* gain Q bit-budget - part 1 */ + /* gain Q bit-budget - part 1: 'Es_pred' of memory-less gain Q */ +#ifdef NONBE_FIX_GSC_BSTR + IF( ( NE_16( coder_type, UNVOICED ) && NE_16( coder_type, AUDIO ) && coder_type != INACTIVE && !( LE_32( core_brate, ACELP_8k00 ) && NE_16( coder_type, TRANSITION ) ) ) /* mid bitrates in GC and VC, low+mid bitrates in TC */ || + ( coder_type == INACTIVE && !inactive_coder_type_flag ) /* AVQ inactive */ ) +#else IF( ( NE_16( coder_type, UNVOICED ) && NE_16( coder_type, AUDIO ) && ( coder_type != INACTIVE ) && !( LE_32( core_brate, ACELP_8k00 ) && NE_16( coder_type, TRANSITION ) ) ) || ( ( coder_type == INACTIVE ) && GT_32( total_brate, MAX_GSC_INACTIVE_BRATE ) ) ) +#endif { *nBits_es_Pred = Es_pred_bits_tbl[BIT_ALLOC_IDX( core_brate, coder_type, -1, -1 )]; move16(); @@ -2294,7 +2344,11 @@ ivas_error config_acelp1_IVAS( { test(); test(); +#ifdef NONBE_FIX_GSC_BSTR + IF( coder_type == INACTIVE && EQ_16( L_frame, L_FRAME16k ) && inactive_coder_type_flag ) /* GSC Inactive @16kHz */ +#else IF( coder_type == INACTIVE && EQ_16( L_frame, L_FRAME16k ) && LE_32( total_brate, MAX_GSC_INACTIVE_BRATE ) ) /* GSC Inactive @16kHz */ +#endif { acelp_cfg->ltf_mode = FULL_BAND; move16(); @@ -2510,7 +2564,13 @@ ivas_error config_acelp1_IVAS( acelp_cfg->fixed_cdk_index[3] = -1; move16(); } +#ifdef NONBE_FIX_GSC_BSTR + ELSE IF( ( coder_type != INACTIVE && EQ_16( nb_subfr, NB_SUBFR ) && NE_16( coder_type, AUDIO ) ) /* @12.8kHz core except of GSC */ || + ( EQ_16( nb_subfr, NB_SUBFR16k ) && ( !inactive_coder_type_flag || coder_type != INACTIVE ) ) /* @16kHz core GC, TC, AVQ inactive */ || + EQ_16( core, HQ_CORE ) /* ACELP -> HQ switching in EVS */ ) +#else ELSE IF( ( coder_type != INACTIVE && EQ_16( nb_subfr, NB_SUBFR ) && NE_16( coder_type, AUDIO ) ) || ( EQ_16( nb_subfr, NB_SUBFR16k ) && ( GT_32( total_brate, MAX_GSC_INACTIVE_BRATE ) || coder_type != INACTIVE ) ) || EQ_16( core, HQ_CORE ) ) +#endif { /* pitch Q & gain Q bit-budget - part 2*/ FOR( i = 0; i < nb_subfr; i++ ) @@ -2574,7 +2634,13 @@ ivas_error config_acelp1_IVAS( test(); test(); /* algebraic codebook bit-budget */ +#ifdef NONBE_FIX_GSC_BSTR + IF( flag_hardcoded /* EVS */ || + ( GE_32( core_brate_inp, MIN_BRATE_AVQ_EXC ) && coder_type != INACTIVE ) /* high-birate ACELP except IC */ || + ( !inactive_coder_type_flag && coder_type == INACTIVE ) /* AVQ inactive */ ) +#else IF( flag_hardcoded || ( GE_32( core_brate_inp, MIN_BRATE_AVQ_EXC ) && coder_type != INACTIVE ) || ( GT_32( total_brate, MAX_GSC_INACTIVE_BRATE ) && coder_type == INACTIVE ) ) +#endif { FOR( i = 0; i < nb_subfr; i++ ) { @@ -2675,7 +2741,12 @@ ivas_error config_acelp1_IVAS( test(); test(); /* AVQ codebook */ +#ifdef NONBE_FIX_GSC_BSTR + IF( ( GE_32( core_brate_inp, MIN_BRATE_AVQ_EXC ) && coder_type != INACTIVE ) /* high-birate ACELP except IC */ || + ( !inactive_coder_type_flag && coder_type == INACTIVE ) /* AVQ inactive */ ) +#else IF( ( GE_32( core_brate_inp, MIN_BRATE_AVQ_EXC ) && coder_type != INACTIVE ) || ( GT_32( total_brate, MAX_GSC_INACTIVE_BRATE ) && coder_type == INACTIVE ) ) +#endif { FOR( i = 0; i < nb_subfr; i++ ) { @@ -2713,7 +2784,13 @@ ivas_error config_acelp1_IVAS( } } } +#ifdef NONBE_FIX_GSC_BSTR + ELSE IF( ( EQ_16( coder_type, UNVOICED ) && EQ_16( tdm_low_rate_mode, 1 ) && EQ_16( element_mode, IVAS_CPE_TD ) ) /* LBR secondary channel in TD stereo */ || + ( ( coder_type == INACTIVE || EQ_16( coder_type, AUDIO ) ) && EQ_16( nb_subfr, NB_SUBFR ) ) /* GSC @12.8kHz */ || + ( coder_type == INACTIVE && inactive_coder_type_flag ) /* AVQ inactive */ ) +#else ELSE IF( ( EQ_16( coder_type, UNVOICED ) && EQ_16( tdm_low_rate_mode, 1 ) && EQ_16( element_mode, IVAS_CPE_TD ) ) || ( ( coder_type == INACTIVE || EQ_16( coder_type, AUDIO ) ) && EQ_16( nb_subfr, NB_SUBFR ) ) || ( coder_type == INACTIVE && LE_32( total_brate, MAX_GSC_INACTIVE_BRATE ) ) ) +#endif { Word32 Local_BR, Pitch_BR; Word16 Pitch_CT; @@ -2854,7 +2931,12 @@ ivas_error config_acelp1_IVAS( test(); test(); test(); +#ifdef NONBE_FIX_GSC_BSTR + IF( ( EQ_16( L_frame, L_FRAME16k ) && coder_type == INACTIVE && inactive_coder_type_flag ) /* GSC Inactive @16kHz */ || + ( GSC_IVAS_mode > 0 && EQ_16( L_frame, L_FRAME16k ) ) ) /* IVAS GSC @16kHz */ +#else IF( ( EQ_16( L_frame, L_FRAME16k ) && coder_type == INACTIVE && LE_32( total_brate, MAX_GSC_INACTIVE_BRATE ) ) || ( GSC_IVAS_mode > 0 && EQ_16( L_frame, L_FRAME16k ) ) ) /* GSC Inactive @16kHz */ +#endif { acelp_cfg->ubits = 0; move16(); @@ -3189,4 +3271,3 @@ Word16 set_ACELP_flag_IVAS( return 0; } } -/*#endif IVAS_CODE*/ diff --git a/lib_com/bitstream.c b/lib_com/bitstream.c index 9e61c257137e4a830833d5ba88388992917bc5c1..79a659eb08094da54b43617b4ee77772b5a21c66 100644 --- a/lib_com/bitstream.c +++ b/lib_com/bitstream.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other @@ -38,13 +38,11 @@ #include #include "options.h" #include "cnst.h" -#include "prot.h" #include "prot_fx.h" #include "stat_enc.h" #include "stat_dec.h" #include "rom_com.h" #include "mime.h" -#include "ivas_prot.h" #include "ivas_cnst.h" #include "ivas_rom_com.h" #include "wmc_auto.h" @@ -1320,33 +1318,6 @@ UWord16 get_indice_st( } #define WMC_TOOL_SKIP -/*-------------------------------------------------------------------* - * reset_indices_enc() - * - * Reset the buffer of encoder indices - *-------------------------------------------------------------------*/ - -void reset_indices_enc( - BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ - const Word16 max_num_indices /* i : max number of indices */ -) -{ - Word16 i; - - hBstr->nb_bits_tot = 0; - move16(); - hBstr->nb_ind_tot = 0; - move16(); - - FOR( i = 0; i < max_num_indices; i++ ) - { - hBstr->ind_list[i].nb_bits = -1; - move16(); - } - - return; -} - /*-------------------------------------------------------------------* * reset_indices_dec() * @@ -1535,21 +1506,21 @@ static ivas_error write_indices_element_fx( { IF( st_ivas->hSCE[element_id]->hMetaData != NULL ) { - reset_indices_enc( st_ivas->hSCE[element_id]->hMetaData, st_ivas->hSCE[element_id]->hMetaData->nb_ind_tot ); + reset_indices_enc_fx( st_ivas->hSCE[element_id]->hMetaData, st_ivas->hSCE[element_id]->hMetaData->nb_ind_tot ); } - reset_indices_enc( sts[0]->hBstr, sts[0]->hBstr->nb_ind_tot ); + reset_indices_enc_fx( sts[0]->hBstr, sts[0]->hBstr->nb_ind_tot ); } ELSE { IF( st_ivas->hCPE[element_id]->hMetaData != NULL ) { - reset_indices_enc( st_ivas->hCPE[element_id]->hMetaData, st_ivas->hCPE[element_id]->hMetaData->nb_ind_tot ); + reset_indices_enc_fx( st_ivas->hCPE[element_id]->hMetaData, st_ivas->hCPE[element_id]->hMetaData->nb_ind_tot ); } FOR( n = 0; n < n_channels; n++ ) { - reset_indices_enc( sts[n]->hBstr, sts[n]->hBstr->nb_ind_tot ); + reset_indices_enc_fx( sts[n]->hBstr, sts[n]->hBstr->nb_ind_tot ); } } @@ -1884,7 +1855,7 @@ static void decision_matrix_core_dec( * Set up MDCT core switching if indicated in the bitstream *-------------------------------------------------------------------*/ -void mdct_switching_dec( +void mdct_switching_dec_ivas_fx( Decoder_State *st /* i/o: decoder state structure */ ) { @@ -2061,67 +2032,84 @@ void ivas_set_bitstream_pointers( *-------------------------------------------------------------------*/ /*! r: 1 = reading OK, 0 = problem */ -ivas_error read_indices( +ivas_error read_indices_fx( Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ - uint16_t bit_stream[], /* i : bitstream buffer */ + UWord16 bit_stream[], /* i : bitstream buffer */ UWord16 num_bits, /* i : number of bits in bitstream */ - int16_t *prev_ft_speech, - int16_t *CNG, - int16_t bfi /* i : bad frame indicator */ + Word16 *prev_ft_speech, + Word16 *CNG, + Word16 bfi /* i : bad frame indicator */ ) { - int16_t k; + Word16 k; Decoder_State **sts; - int32_t total_brate = 0; - int16_t curr_ft_good_sp, curr_ft_bad_sp; - int16_t g192_sid_first, sid_upd_bad, sid_update; - int16_t speech_bad, speech_lost; - int16_t n; + Word32 total_brate = 0; + move32(); + Word16 curr_ft_good_sp, curr_ft_bad_sp; + Word16 g192_sid_first, sid_upd_bad, sid_update; + Word16 speech_bad, speech_lost; + Word16 n; ivas_error error; error = IVAS_ERR_OK; + move32(); st_ivas->BER_detect = 0; + move16(); st_ivas->num_bits = num_bits; + move16(); sts = reset_elements( st_ivas ); st_ivas->bfi = bfi; + move16(); /* convert the frame length to total bitrate */ - total_brate = (int32_t) ( num_bits * FRAMES_PER_SEC ); + total_brate = imult3216( num_bits, FRAMES_PER_SEC ); + move32(); /* verify that a valid num bits value is present in the G.192 file */ /* only AMRWB, EVS or IVAS bitrates or 0(NO DATA) are allowed in G.192 file frame reading */ - if ( st_ivas->ivas_format != MONO_FORMAT ) + IF( NE_32( st_ivas->ivas_format, MONO_FORMAT ) ) { k = 0; - while ( k < SIZE_IVAS_BRATE_TBL && total_brate != ivas_brate_tbl[k] ) + move16(); + + test(); + WHILE( LT_16( k, SIZE_IVAS_BRATE_TBL ) && NE_32( total_brate, ivas_brate_tbl[k] ) ) { - k++; + k = add( k, 1 ); } - if ( st_ivas->ivas_format == ISM_FORMAT && ( k < SIZE_IVAS_BRATE_TBL || total_brate <= SID_2k40 ) ) + test(); + test(); + test(); + test(); + IF( EQ_32( st_ivas->ivas_format, ISM_FORMAT ) && ( LT_16( k, SIZE_IVAS_BRATE_TBL ) || LE_32( total_brate, SID_2k40 ) ) ) { st_ivas->element_mode_init = IVAS_SCE; + move16(); } - else if ( ( st_ivas->ivas_format == SBA_FORMAT || st_ivas->ivas_format == MASA_FORMAT ) && ( total_brate <= SID_2k40 ) ) + ELSE IF( ( EQ_32( st_ivas->ivas_format, SBA_FORMAT ) || EQ_32( st_ivas->ivas_format, MASA_FORMAT ) ) && LE_32( total_brate, SID_2k40 ) ) { st_ivas->element_mode_init = IVAS_SCE; + move16(); } - else if ( k == SIZE_IVAS_BRATE_TBL ) + ELSE IF( EQ_16( k, SIZE_IVAS_BRATE_TBL ) ) { return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "Error, illegal bitrate (%d) in the G.192 frame ! Exiting ! \n", total_brate ); } - else + ELSE { st_ivas->element_mode_init = -1; + move16(); } } - else /* AMRWB or EVS */ + ELSE /* AMRWB or EVS */ { st_ivas->element_mode_init = EVS_MONO; + move16(); - if ( rate2EVSmode_float( total_brate, NULL ) < 0 ) /* negative value means that a valid rate was not found */ + IF( rate2EVSmode_float( total_brate, NULL ) < 0 ) /* negative value means that a valid rate was not found */ { return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "Error, illegal bitrate (%d) in the G.192 frame ! Exiting ! \n", total_brate ); } @@ -2131,47 +2119,58 @@ ivas_error read_indices( /* handle SID_FIRST, SID_BAD, SPEECH_LOST, NO_DATA as properly as possible for the ITU-T G.192 format */ /* (total_brate, bfi , st_CNG) = rx_handler(received frame type, [previous frame type], past CNG state, past core) */ curr_ft_good_sp = 0; + move16(); curr_ft_bad_sp = 0; + move16(); - if ( is_DTXrate( total_brate ) == 0 ) + IF( is_DTXrate( total_brate ) == 0 ) { - if ( st_ivas->bfi == 0 ) + IF( st_ivas->bfi == 0 ) { curr_ft_good_sp = 1; + move16(); } - else + ELSE { curr_ft_bad_sp = 1; + move16(); } } sid_update = 0; + move16(); sid_upd_bad = 0; - if ( is_SIDrate( total_brate ) == 1 ) + move16(); + IF( EQ_16( is_SIDrate( total_brate ), 1 ) ) { - if ( st_ivas->bfi == 0 ) + IF( st_ivas->bfi == 0 ) { sid_update = 1; + move16(); } - else + ELSE { sid_upd_bad = 1; /* this frame type may happen in ETSI/3GPP CS cases, a corrupt SID frames */ + move16(); } } /* all zero indices/bits iSP AMRWB SID_update results in a valid LP filter with extremely high LP-filter-gain */ /* all zero indices/bits may be a result of CS bit errors and/or erroneously injected by gateways or by a bad dejitter handlers */ - if ( total_brate == SID_1k75 && sid_update == 1 ) + test(); + IF( EQ_32( total_brate, SID_1k75 ) && EQ_16( sid_update, 1 ) ) { /* valid sid_update received, check for very risky but formally valid content */ - int16_t sum = 0; - for ( k = 0; k < num_bits; ++k ) + Word16 sum = 0; + move16(); + FOR( k = 0; k < num_bits; ++k ) { - sum += ( bit_stream[k] == 1 ); /* check of 35 zeroes */ + sum = add( sum, extract_l( EQ_32( bit_stream[k], 1 ) ) ); /* check of 35 zeroes */ } if ( sum == 0 ) { /* all zeros */ sid_upd_bad = 1; /* initial signal as corrupt (BER likely) */ + move16(); } } @@ -2182,14 +2181,22 @@ ivas_error read_indices( Here we inhibit use of the SID-length info, even though it is available in the G.192 file format after STL/EID-XOR . */ - if ( sid_upd_bad ) + IF( sid_upd_bad ) { sid_upd_bad = 0; + move16(); total_brate = FRAME_NO_DATA; /* treat SID_BAD as a stolen signaling frame --> SPEECH LOST */ + move32(); } g192_sid_first = 0; - if ( st_ivas->ivas_format == MONO_FORMAT && sts[0]->core == AMR_WB_CORE && *prev_ft_speech && total_brate == FRAME_NO_DATA && st_ivas->bfi == 0 ) + move16(); + + test(); + test(); + test(); + test(); + if ( EQ_32( st_ivas->ivas_format, MONO_FORMAT ) && EQ_16( sts[0]->core, AMR_WB_CORE ) && *prev_ft_speech && total_brate == FRAME_NO_DATA && st_ivas->bfi == 0 ) { g192_sid_first = 1; /* SID_FIRST detected for previous AMRWB/AMRWBIO active frames only */ /* It is not possible to perfectly simulate rate switching conditions EVS->AMRWBIO where: @@ -2197,104 +2204,135 @@ ivas_error read_indices( and a good length 0 "SID_FIRST"(NO_DATA) frame is sent in AMRWBIO, due to the one frame state memory in the AMRWB legacy G.192 SID_FIRST encoding */ + move16(); } speech_bad = 0; + move16(); + + test(); if ( st_ivas->bfi != 0 && ( is_DTXrate( total_brate ) == 0 ) ) { speech_bad = 1; /* initial ft assumption, CNG_state decides what to do */ + move16(); } speech_lost = 0; + move16(); + + test(); if ( total_brate == FRAME_NO_DATA && st_ivas->bfi != 0 ) /* unsent NO_DATA or stolen NO_DATA/signaling frame */ { speech_lost = 1; /* initial ft assumption, CNG_state decides what to do */ + move16(); } /* Do not allow decoder to enter CNG-synthesis for any instantly received GOOD+LENGTH==0 frame as this frame was never transmitted, one can not know it is good and has a a length of zero ) */ - if ( *CNG != 0 ) + IF( *CNG != 0 ) { /* We were in CNG synthesis */ if ( curr_ft_good_sp != 0 ) { /* only a good speech frame makes you leave CNG synthesis */ *CNG = 0; + move16(); } } - else + ELSE { /* We were in SPEECH synthesis */ /* only a received/detected SID frame can make the decoder enter into CNG synthsis */ + test(); + test(); if ( g192_sid_first || sid_update || sid_upd_bad ) { *CNG = 1; + move16(); } } /* set bfi, total_brate pair for proper decoding */ /* handle the G.192 _simulated_ untransmitted NO_DATA frame, setting for decoder SPEECH synthesis */ + test(); + test(); if ( *CNG == 0 && total_brate == FRAME_NO_DATA && st_ivas->bfi == 0 ) { st_ivas->bfi = 1; /* SPEECH PLC code will now become active as in a real system */ /* total_brate= 0 */ + move16(); } /* handle bad/lost speech frame(and CS bad SID frame) in the decoders CNG synthesis settings pair (total_brate, bfi) */ - if ( ( - bfi != FRAMEMODE_FUTURE && - ( *CNG != 0 ) && ( ( speech_bad != 0 ) || ( speech_lost != 0 ) ) ) || /* SP_BAD or SPEECH_LOST) --> stay in CNG */ - ( sid_upd_bad != 0 ) ) /* SID_UPD_BAD --> start CNG */ + test(); + test(); + test(); + test(); + IF( ( + NE_16( bfi, FRAMEMODE_FUTURE ) && + ( *CNG != 0 ) && ( ( speech_bad != 0 ) || ( speech_lost != 0 ) ) ) || /* SP_BAD or SPEECH_LOST) --> stay in CNG */ + ( sid_upd_bad != 0 ) ) /* SID_UPD_BAD --> start CNG */ { st_ivas->bfi = 0; /* bfi=0 needed to activate CNG code */ + move16(); total_brate = FRAME_NO_DATA; + move32(); } /* update for next frame's G.192 file format's odd SID_FIRST detection (primarily for AMRWBIO) */ + test(); *prev_ft_speech = ( ( curr_ft_good_sp != 0 ) || ( curr_ft_bad_sp != 0 ) ); + move16(); /* st->total brate= total_brate; updated in a good frame below */ - for ( k = 0; k < st_ivas->nCPE; k++ ) + FOR( k = 0; k < st_ivas->nCPE; k++ ) { sts = st_ivas->hCPE[k]->hCoreCoder; - for ( n = 0; n < CPE_CHANNELS; n++ ) + FOR( n = 0; n < CPE_CHANNELS; n++ ) { sts[n]->bfi = st_ivas->bfi; + move16(); } } - for ( k = 0; k < st_ivas->nSCE; k++ ) + FOR( k = 0; k < st_ivas->nSCE; k++ ) { sts = st_ivas->hSCE[k]->hCoreCoder; sts[0]->bfi = st_ivas->bfi; + move16(); } - if ( st_ivas->bfi == 0 ) + IF( st_ivas->bfi == 0 ) { /* select Mode 1 or Mode 2 */ - if ( st_ivas->ivas_format == MONO_FORMAT ) /* EVS mono */ + IF( EQ_32( st_ivas->ivas_format, MONO_FORMAT ) ) /* EVS mono */ { decoder_selectCodec( sts[0], total_brate, bit_stream[0] ); st_ivas->hDecoderConfig->Opt_AMR_WB = sts[0]->Opt_AMR_WB; + move16(); } - else /* IVAS */ + ELSE /* IVAS */ { st_ivas->codec_mode = MODE1; + move16(); st_ivas->hDecoderConfig->Opt_AMR_WB = 0; + move16(); } } /* GOOD frame */ - if ( st_ivas->bfi == 0 || st_ivas->bfi == FRAMEMODE_FUTURE ) + test(); + if ( st_ivas->bfi == 0 || EQ_16( st_ivas->bfi, FRAMEMODE_FUTURE ) ) { /* GOOD frame - convert ITU-T G.192 words to short values */ st_ivas->hDecoderConfig->ivas_total_brate = total_brate; + move32(); } st_ivas->bit_stream = bit_stream; - if ( st_ivas->ivas_format == MONO_FORMAT ) + IF( EQ_32( st_ivas->ivas_format, MONO_FORMAT ) ) { ivas_set_bitstream_pointers( st_ivas ); } diff --git a/lib_com/bitstream_fx.c b/lib_com/bitstream_fx.c index 1acf69c2ab60437244c65c92cde2df396f7fa7ef..d4938f399607265c110c754aa2eba32587d817b8 100644 --- a/lib_com/bitstream_fx.c +++ b/lib_com/bitstream_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other @@ -543,7 +543,8 @@ UWord16 get_indice_1_fx( /* o : value of the indice */ *-------------------------------------------------------------------*/ void reset_indices_enc_fx( - BSTR_ENC_HANDLE hBstr /* i/o: encoder state structure */ + BSTR_ENC_HANDLE hBstr, /* i/o: encoder state structure */ + const Word16 max_num_indices /* i : max number of indices */ ) { Word16 i; @@ -559,7 +560,7 @@ void reset_indices_enc_fx( hBstr->last_ind_fx = -1; move16(); - FOR( i = 0; i < MAX_NUM_INDICES; i++ ) + FOR( i = 0; i < max_num_indices; i++ ) { hBstr->ind_list[i].nb_bits = -1; move16(); @@ -1547,358 +1548,6 @@ Word32 BIT_ALLOC_IDX_16KHZ_fx( Word32 brate, Word16 ctype, Word16 sfrm, Word16 t return L_temp; } - -/*-------------------------------------------------------------------* - * read_indices_fx() - * - * Read indices from an ITU-T G.192 bitstream to the buffer - * Simulate packet losses by inserting frame erasures - *-------------------------------------------------------------------*/ - -Word16 read_indices_fx( /* o : 1 = reading OK, 0 = problem */ - Decoder_State *st, /* i/o: decoder state structure */ - FILE *file, /* i : bitstream file */ - Word16 rew_flag /* i : rewind flag (rewind file after reading)*/ -) -{ - Word16 k; - UWord16 utmp, stream[2 + MAX_BITS_PER_FRAME], *pt_stream, *bit_stream_ptr; - Word16 num_bits; - Word32 total_brate; - Word32 L_tmp; - Word16 curr_ft_good_sp, curr_ft_bad_sp; - Word16 g192_sid_first, sid_upd_bad, sid_update; - Word16 speech_bad, speech_lost; - Word16 num_bits_read; - - st->bfi = 0; - move16(); - st->BER_detect = 0; - move16(); - st->mdct_sw_enable = 0; - move16(); - st->mdct_sw = 0; - move16(); - reset_indices_dec_fx( st ); - - /* read the Sync Header field from the bitstream */ - /* in case rew_flag is set, read until first good frame is encountered */ - test(); - test(); - DO - { - /* read the Sync header */ - IF( NE_32( fread( &utmp, sizeof( unsigned short ), 1, file ), 1 ) ) - { - IF( ferror( file ) ) - { - /* error during reading */ - fprintf( stderr, "\nError reading the bitstream !" ); - exit( -1 ); - } - ELSE - { - /* end of file reached */ - return 0; - } - } - - /* set the BFI indicator according the value of Sync Header */ - IF( EQ_16( utmp, SYNC_BAD_FRAME ) ) - { - st->bfi = 1; - move16(); - } - ELSE - { - st->bfi = 0; - move16(); - } - - /* read the Frame Length field from the bitstream */ - IF( NE_32( fread( &num_bits, sizeof( unsigned short ), 1, file ), 1 ) ) - { - IF( ferror( file ) ) - { - /* error during reading */ - fprintf( stderr, "\nError reading the bitstream !" ); - exit( -1 ); - } - ELSE - { - /* end of file reached */ - return 0; - } - } - /* convert the frame length to total bitrate */ - total_brate = L_mult0( num_bits, 50 ); - - /* read ITU-T G.192 serial stream of indices from file to the local buffer */ - /* Validate that the G.192 length is within the defined bit rate range - to not allow writing past the end of the "stream" buffer */ - IF( GT_16( num_bits, MAX_BITS_PER_FRAME ) ) - { - fprintf( stderr, "\nError, too large G.192 frame (size(%d))! Exiting ! \n", num_bits ); - exit( -1 ); - } - - /* verify that a valid num bits value is present in the G.192 file */ - /* only AMRWB or EVS bit rates or 0(NO DATA) are allowed in G.192 file frame reading */ - IF( rate2EVSmode( total_brate, NULL ) < 0 ) /* negative value means that a valid rate was not found */ - { - fprintf( stderr, "\nError, illegal bit rate (%d) in the G.192 frame ! Exiting ! \n", total_brate ); - exit( -1 ); - } - pt_stream = stream; - - num_bits_read = (Word16) fread( pt_stream, sizeof( unsigned short ), num_bits, file ); - move16(); - - IF( NE_16( num_bits_read, num_bits ) ) - { - fprintf( stderr, "\nError, invalid number of bits read ! Exiting ! \n" ); - exit( -1 ); - } - } - WHILE( rew_flag && ( st->bfi || ( total_brate < 2800 ) ) ); - - /* G.192 RX DTX handler*/ - IF( !rew_flag ) - { - /* handle SID_FIRST, SID_BAD, SPEECH_LOST, NO_DATA as properly as possible for the ITU-T G.192 format */ - - /* (total_brate, bfi , st_CNG) = rx_handler(received frame type, [previous frame type], past CNG state, past core) */ - curr_ft_good_sp = 0; - move16(); - curr_ft_bad_sp = 0; - move16(); - - IF( GT_32( total_brate, SID_2k40 ) ) - { - IF( st->bfi == 0 ) - { - curr_ft_good_sp = 1; - move16(); - } - ELSE - { - curr_ft_bad_sp = 1; - move16(); - } - } - sid_update = 0; - move16(); - sid_upd_bad = 0; - move16(); - - test(); - IF( total_brate == SID_1k75 || total_brate == SID_2k40 ) - { - IF( st->bfi == 0 ) - { - sid_update = 1; - move16(); - } - ELSE - { - sid_upd_bad = 1; /* may happen in CS , corrupt but detected sid frame */ - move16(); - } - } - - /* all zero indeces/bits iSP AMRWB SID_update results in a valid LP filter with extremely high LP-filter-gain */ - /* all zero indeces/bits may be a result of CS bit errors and/or erroneously injected by gateways or by a bad dejitter handlers */ - test(); - IF( EQ_32( total_brate, SID_1k75 ) && EQ_16( sid_update, 1 ) ) - { - /* valid sid_update received, check for very risky but formally valid content */ - Word16 sum = 0; - move16(); - FOR( k = 0; k < num_bits; ++k ) - { - sum = add( sum, extract_l( EQ_16( pt_stream[k], G192_BIN1 ) ) ); /* check of 35 zeroes, 35 ones */ - } - if ( sum == 0 ) - { /* all zeros */ - sid_upd_bad = 1; /* initial signal as corrupt (BER likley) */ - move16(); - } - } - - /* AMRWB 26.173 G.192 file reader (read_serial) does not declare/use SID_BAD ft, - it declares every bad synch marked frame initially as a lost_speech frame, - and then the RXDTX handler CNG state decides the decoding mode CNG/SPEECH. - While In the AMRWB ETSI/3GPP format eid a CRC error in a detected SID_UPDATE frame triggers SID_UPD_BAD. - - Here we inhibit use of the SID-length info, even though it is available in the G.192 file format after STL/EID-XOR . - */ - IF( sid_upd_bad ) - { - sid_upd_bad = 0; - move16(); - total_brate = FRAME_NO_DATA; /* treat SID_BAD as a stolen signaling frame --> SPEECH LOST */ - move32(); - } - - g192_sid_first = 0; - move16(); - - test(); - test(); - test(); - if ( EQ_16( st->core, AMR_WB_CORE ) && st->prev_ft_speech_fx && total_brate == FRAME_NO_DATA && st->bfi == 0 ) - { - g192_sid_first = 1; /* SID_FIRST detected for previous AMRWB/AMRWBIO active frames only */ - /* - It is not possible to perfectly simulate rate switching conditions EVS->AMRWBIO where: - the very first SID_FIRST detection is based on a past EVS active frame - and a good length 0 "SID_FIRST"(NO_DATA) frame is sent in AMRWBIO, - , due to the one frame state memory in the AMRWB legacy G.192 SID_FIRST encoding - */ - move16(); - } - - speech_bad = 0; - move16(); - - test(); - if ( GT_32( total_brate, SID_2k40 ) && st->bfi != 0 ) /* CS-type of CRC failure frame */ - { - speech_bad = 1; /* initial assumption, CNG_state decides what to do */ - move16(); - } - - speech_lost = 0; - move16(); - - test(); - if ( total_brate == 0 && st->bfi != 0 ) /* unsent NO_DATA or stolen NO_DATA/signaling frame */ - { - speech_lost = 1; /* initial assumption, CNG_state decides what to do */ - move16(); - } - - /* Do not allow decoder to enter CNG-synthesis for any instantly received GOOD+LENGTH==0 frame - as this frame was never transmitted, one can not know it is good and has a a length of zero ) */ - - IF( st->CNG_fx != 0 ) - { - /* We were in CNG synthesis */ - if ( curr_ft_good_sp != 0 ) - { - /* only a good speech frame makes you leave CNG synthesis */ - st->CNG_fx = 0; - move16(); - } - } - ELSE - { - /* We were in SPEECH synthesis */ - /* only a received SID frame can make the decoder enter into CNG synthsis */ - test(); - test(); - if ( g192_sid_first || sid_update || sid_upd_bad ) - { - st->CNG_fx = 1; - move16(); - } - } - - /* handle the g.192 _simulated_ untransmitted frame, setting for decoder SPEECH synthesis */ - test(); - test(); - if ( ( st->CNG_fx == 0 ) && ( total_brate == 0 && st->bfi == 0 ) ) - { - st->bfi = 1; - move16(); /* SPEECH PLC code will now become active as in a real system */ - /* total_brate= 0 */ - } - - /* handle bad speech frame(and bad sid frame) in the decoders CNG synthesis settings pair (total_brate, bfi) */ - test(); - test(); - test(); - IF( ( ( st->CNG_fx != 0 ) && ( ( speech_bad != 0 ) || ( speech_lost != 0 ) ) ) || /* SP_BAD or SPEECH_LOST) --> stay in CNG */ - ( sid_upd_bad != 0 ) ) /* SID_UPD_BAD --> start CNG */ - { - st->bfi = 0; - move16(); - total_brate = 0; - move32(); - } - /* update for next frame's G.192 file format's SID_FIRST detection (primarily for AMRWBIO) */ - test(); - st->prev_ft_speech_fx = ( ( curr_ft_good_sp != 0 ) || ( curr_ft_bad_sp != 0 ) ); - move16(); - - /* st->total brate= total_brate ; updated in a good frame below */ - } /* rew_flag */ - - /* get total bit-rate */ -#ifdef DEBUGGING - st->bfi |= file_read_FECpattern(); -#endif - test(); - IF( st->bfi == 0 && !rew_flag ) - { - /* select MODE1 or MODE2 */ - decoder_selectCodec( st, total_brate, *pt_stream ); - } - - Mpy_32_16_ss( total_brate, 5243, &L_tmp, &utmp ); /* 5243 is 1/50 in Q18. (0+18-15=3) */ - st->total_num_bits = extract_l( L_shr( L_tmp, 3 ) ); /* Q0 */ - move16(); - - /* in case rew_flag is set, rewind the file and return */ - /* (used in io_enc() to print out info about technologies and to initialize the codec) */ - IF( rew_flag ) - { - rewind( file ); - st->total_brate = total_brate; - move32(); - return 1; - } - - /* GOOD frame */ - IF( st->bfi == 0 ) - { - /* GOOD frame - convert ITU-T G.192 words to short values */ - bit_stream_ptr = st->bit_stream; - - FOR( k = 0; k < num_bits; ++k ) - { - *bit_stream_ptr++ = (UWord16) EQ_32( *pt_stream++, G192_BIN1 ); - move16(); - } - - /*add two zero bytes for arithmetic coder flush*/ - FOR( k = 0; k < 2 * 8; ++k ) - { - *bit_stream_ptr++ = 0; - move16(); - } - /*a change of the total bitrate should not be - known to the decoder, if the received frame was lost*/ - st->total_brate = total_brate; - move32(); - - mdct_switching_dec( st ); - } -#ifdef DEBUGGING - else - { - bit_stream_ptr = st->bit_stream; - - for ( k = 0; k < num_bits + 2 * 8; ++k ) - { - *bit_stream_ptr++ = 0; - } - } -#endif - return 1; -} - - /*-------------------------------------------------------------------* * read_indices_mime_handle_dtx() * diff --git a/lib_com/cldfb.c b/lib_com/cldfb.c index 480f7e5d630c1e797e4645287a6bdf0abbffa316..91b596ca5ace5c6443e19d8577176c00023b9327 100644 --- a/lib_com/cldfb.c +++ b/lib_com/cldfb.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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,7 +39,6 @@ #include "options.h" #include #include "stat_dec.h" -#include "prot.h" #include "prot_fx.h" #include "rom_com.h" #include "rom_com_fx.h" @@ -61,7 +60,6 @@ static void cldfb_init_proto_and_twiddles( HANDLE_CLDFB_FILTER_BANK hs ); static void cldfb_init_proto_and_twiddles_enc_fx( HANDLE_CLDFB_FILTER_BANK hs ); - /*-------------------------------------------------------------------* * cplxMult() * @@ -437,11 +435,11 @@ void cldfbAnalysis_ts_fx( i1_fx = Msub_32_16( i1_fx, timeBuffer_fx[( L2 + M2 - 1 - ( 2 * k ) + 3 * L2 )], ptr_pf_fx[( L2 + M2 - 1 - ( 2 * k ) + 3 * L2 )] ); // q i1_fx = Msub_32_16( i1_fx, timeBuffer_fx[( L2 + M2 - 1 - ( 2 * k ) + 4 * L2 )], ptr_pf_fx[( L2 + M2 - 1 - ( 2 * k ) + 4 * L2 )] ); // q - i2_fx = Msub_32_16( 0, timeBuffer_fx[( L2 + M2 - 1 - ( 2 * k ) + 0 * L2 )], ptr_pf_fx[( L2 + M2 - 1 - ( 2 * k ) + 0 * L2 )] ); // q - i2_fx = Msub_32_16( i2_fx, timeBuffer_fx[( L2 + M2 - 1 - ( 2 * k ) + 1 * L2 )], ptr_pf_fx[( L2 + M2 - 1 - ( 2 * k ) + 1 * L2 )] ); // q - i2_fx = Msub_32_16( i2_fx, timeBuffer_fx[( L2 + M2 - 1 - ( 2 * k ) + 2 * L2 )], ptr_pf_fx[( L2 + M2 - 1 - ( 2 * k ) + 2 * L2 )] ); // q - i2_fx = Msub_32_16( i2_fx, timeBuffer_fx[( L2 + M2 - 1 - ( 2 * k ) + 3 * L2 )], ptr_pf_fx[( L2 + M2 - 1 - ( 2 * k ) + 3 * L2 )] ); // q - i2_fx = Msub_32_16( i2_fx, timeBuffer_fx[( L2 + M2 - 1 - ( 2 * k ) + 4 * L2 )], ptr_pf_fx[( L2 + M2 - 1 - ( 2 * k ) + 4 * L2 )] ); // q + i2_fx = Msub_32_16( 0, timeBuffer_fx[( L2 - 3 * M2 + ( 2 * k ) + 0 * L2 )], ptr_pf_fx[( L2 - 3 * M2 + ( 2 * k ) + 0 * L2 )] ); // q + i2_fx = Msub_32_16( i2_fx, timeBuffer_fx[( L2 - 3 * M2 + ( 2 * k ) + 1 * L2 )], ptr_pf_fx[( L2 - 3 * M2 + ( 2 * k ) + 1 * L2 )] ); // q + i2_fx = Msub_32_16( i2_fx, timeBuffer_fx[( L2 - 3 * M2 + ( 2 * k ) + 2 * L2 )], ptr_pf_fx[( L2 - 3 * M2 + ( 2 * k ) + 2 * L2 )] ); // q + i2_fx = Msub_32_16( i2_fx, timeBuffer_fx[( L2 - 3 * M2 + ( 2 * k ) + 3 * L2 )], ptr_pf_fx[( L2 - 3 * M2 + ( 2 * k ) + 3 * L2 )] ); // q + i2_fx = Msub_32_16( i2_fx, timeBuffer_fx[( L2 - 3 * M2 + ( 2 * k ) + 4 * L2 )], ptr_pf_fx[( L2 - 3 * M2 + ( 2 * k ) + 4 * L2 )] ); // q r1_fx = Mpy_32_16_1( r1_fx, ptr_pf_sf ); // q - 1 r2_fx = Mpy_32_16_1( r2_fx, ptr_pf_sf ); // q - 1 @@ -569,6 +567,278 @@ void cldfbAnalysis_ts_fx( return; } +void cldfbAnalysis_ts_fx_var_q( + const Word32 *timeIn_fx, + /* i : time buffer */ // q + Word32 realBuffer_fx[CLDFB_NO_CHANNELS_MAX], + /* o : real value buffer */ // q_cldfb - 5 + Word32 imagBuffer_fx[CLDFB_NO_CHANNELS_MAX], + /* o : imag value buffer */ // q_cldfb - 5 + const Word16 samplesToProcess, /* i : samples to process */ + HANDLE_CLDFB_FILTER_BANK h_cldfb, /* i : filterbank state */ + Word16 *q_cldfb ) + +{ + Word16 i, k; + Word16 L2, M1, M2, M4; + Word16 no_col = h_cldfb->no_col; + move16(); + Word32 r1_fx, r2_fx, rr12_fx, ir12_fx; + Word32 i1_fx, i2_fx, ri12_fx, ii12_fx; + Word32 rBuffer_fx[2 * CLDFB_NO_CHANNELS_MAX]; + Word32 iBuffer_fx[2 * CLDFB_NO_CHANNELS_MAX]; + const Word32 *rot_vctr_re_fx; + const Word32 *rot_vctr_im_fx; + const Word32 *rot_vctr_delay_re_fx; + const Word32 *rot_vctr_delay_im_fx; + const Word16 *ptr_pf_fx; + Word16 ptr_pf_sf; + Word32 *timeBuffer_fx, buffer_fx[( CLDFB_NO_CHANNELS_MAX * CLDFB_NO_COL_MAX ) + ( 9 * CLDFB_NO_CHANNELS_MAX )]; + Word16 offset, frameSize; + + offset = sub( h_cldfb->p_filter_length, h_cldfb->no_channels ); + frameSize = i_mult( h_cldfb->no_channels, h_cldfb->no_col ); + + /* prepare input buffer */ + timeBuffer_fx = buffer_fx; + Copy32( h_cldfb->cldfb_state_fx, timeBuffer_fx, offset ); + + IF( GT_16( samplesToProcess, -1 ) ) + { + Copy32( timeIn_fx, timeBuffer_fx + offset, samplesToProcess ); + set32_fx( timeBuffer_fx + add( offset, samplesToProcess ), 0, sub( frameSize, samplesToProcess ) ); + } + ELSE + { + Copy32( timeIn_fx, timeBuffer_fx + offset, frameSize ); + } + + IF( NE_16( h_cldfb->Q_cldfb_state, *q_cldfb ) ) + { + Word16 norm_st = L_norm_arr( timeBuffer_fx, offset ); + IF( GE_16( norm_st, sub( *q_cldfb, h_cldfb->Q_cldfb_state ) ) ) + { + scale_sig32( timeBuffer_fx, offset, sub( *q_cldfb, h_cldfb->Q_cldfb_state ) ); + /* cldfb_state will get updated at end of processing with values whose q is same as + * *q_cldfb. + */ + h_cldfb->Q_cldfb_state = *q_cldfb; + move16(); + } + ELSE + { + scale_sig32( &timeBuffer_fx[offset], frameSize, sub( h_cldfb->Q_cldfb_state, *q_cldfb ) ); + *q_cldfb = h_cldfb->Q_cldfb_state; + move16(); + } + } + + /* only process needed cols */ + IF( GT_16( samplesToProcess, -1 ) ) + { + no_col = s_min( no_col, idiv1616( sub( add( samplesToProcess, h_cldfb->no_channels ), 1 ), h_cldfb->no_channels ) ); + assert( no_col == 1 ); + } + + M1 = h_cldfb->no_channels; + M2 = shr( M1, 1 ); + M4 = shr( M1, 2 ); + L2 = shl( M1, 1 ); + move16(); + + if ( s_and( M2, 1 ) ) + { + M4 = add( M4, 1 ); + } + + rot_vctr_re_fx = h_cldfb->rot_vec_ana_re_fx; // q = 29 + rot_vctr_im_fx = h_cldfb->rot_vec_ana_im_fx; // q = 29 + rot_vctr_delay_re_fx = h_cldfb->rot_vec_ana_delay_re_fx; // q = 31 + rot_vctr_delay_im_fx = h_cldfb->rot_vec_ana_delay_im_fx; // q = 31 + + ptr_pf_fx = h_cldfb->p_filter; + ptr_pf_sf = h_cldfb->p_filter_sf; // Q14 + move16(); + + FOR( i = 0; i < no_col; i++ ) + { + FOR( k = 0; k < M4; k++ ) + { + /* prototype filter */ + r1_fx = Msub_32_16( 0, timeBuffer_fx[( L2 - M2 - 1 - ( 2 * k ) + 0 * L2 )], ptr_pf_fx[( L2 - M2 - 1 - ( 2 * k ) + 0 * L2 )] ); // q + r1_fx = Msub_32_16( r1_fx, timeBuffer_fx[( L2 - M2 - 1 - ( 2 * k ) + 1 * L2 )], ptr_pf_fx[( L2 - M2 - 1 - ( 2 * k ) + 1 * L2 )] ); // q + r1_fx = Msub_32_16( r1_fx, timeBuffer_fx[( L2 - M2 - 1 - ( 2 * k ) + 2 * L2 )], ptr_pf_fx[( L2 - M2 - 1 - ( 2 * k ) + 2 * L2 )] ); // q + r1_fx = Msub_32_16( r1_fx, timeBuffer_fx[( L2 - M2 - 1 - ( 2 * k ) + 3 * L2 )], ptr_pf_fx[( L2 - M2 - 1 - ( 2 * k ) + 3 * L2 )] ); // q + r1_fx = Msub_32_16( r1_fx, timeBuffer_fx[( L2 - M2 - 1 - ( 2 * k ) + 4 * L2 )], ptr_pf_fx[( L2 - M2 - 1 - ( 2 * k ) + 4 * L2 )] ); // q + + r2_fx = Msub_32_16( 0, timeBuffer_fx[( L2 - M2 + ( 2 * k ) + 0 * L2 )], ptr_pf_fx[( L2 - M2 + ( 2 * k ) + 0 * L2 )] ); // q + r2_fx = Msub_32_16( r2_fx, timeBuffer_fx[( L2 - M2 + ( 2 * k ) + 1 * L2 )], ptr_pf_fx[( L2 - M2 + ( 2 * k ) + 1 * L2 )] ); // q + r2_fx = Msub_32_16( r2_fx, timeBuffer_fx[( L2 - M2 + ( 2 * k ) + 2 * L2 )], ptr_pf_fx[( L2 - M2 + ( 2 * k ) + 2 * L2 )] ); // q + r2_fx = Msub_32_16( r2_fx, timeBuffer_fx[( L2 - M2 + ( 2 * k ) + 3 * L2 )], ptr_pf_fx[( L2 - M2 + ( 2 * k ) + 3 * L2 )] ); // q + r2_fx = Msub_32_16( r2_fx, timeBuffer_fx[( L2 - M2 + ( 2 * k ) + 4 * L2 )], ptr_pf_fx[( L2 - M2 + ( 2 * k ) + 4 * L2 )] ); // q + + i1_fx = Msub_32_16( 0, timeBuffer_fx[( L2 - 3 * M2 + ( 2 * k ) + 0 * L2 )], ptr_pf_fx[( L2 - 3 * M2 + ( 2 * k ) + 0 * L2 )] ); // q + i1_fx = Msub_32_16( i1_fx, timeBuffer_fx[( L2 - 3 * M2 + ( 2 * k ) + 1 * L2 )], ptr_pf_fx[( L2 - 3 * M2 + ( 2 * k ) + 1 * L2 )] ); // q + i1_fx = Msub_32_16( i1_fx, timeBuffer_fx[( L2 - 3 * M2 + ( 2 * k ) + 2 * L2 )], ptr_pf_fx[( L2 - 3 * M2 + ( 2 * k ) + 2 * L2 )] ); // q + i1_fx = Msub_32_16( i1_fx, timeBuffer_fx[( L2 - 3 * M2 + ( 2 * k ) + 3 * L2 )], ptr_pf_fx[( L2 - 3 * M2 + ( 2 * k ) + 3 * L2 )] ); // q + i1_fx = Msub_32_16( i1_fx, timeBuffer_fx[( L2 - 3 * M2 + ( 2 * k ) + 4 * L2 )], ptr_pf_fx[( L2 - 3 * M2 + ( 2 * k ) + 4 * L2 )] ); // q + + i2_fx = Msub_32_16( 0, timeBuffer_fx[( L2 - 3 * M2 - 1 - ( 2 * k ) + 0 * L2 )], ptr_pf_fx[( L2 - 3 * M2 - 1 - ( 2 * k ) + 0 * L2 )] ); // q + i2_fx = Msub_32_16( i2_fx, timeBuffer_fx[( L2 - 3 * M2 - 1 - ( 2 * k ) + 1 * L2 )], ptr_pf_fx[( L2 - 3 * M2 - 1 - ( 2 * k ) + 1 * L2 )] ); // q + i2_fx = Msub_32_16( i2_fx, timeBuffer_fx[( L2 - 3 * M2 - 1 - ( 2 * k ) + 2 * L2 )], ptr_pf_fx[( L2 - 3 * M2 - 1 - ( 2 * k ) + 2 * L2 )] ); // q + i2_fx = Msub_32_16( i2_fx, timeBuffer_fx[( L2 - 3 * M2 - 1 - ( 2 * k ) + 3 * L2 )], ptr_pf_fx[( L2 - 3 * M2 - 1 - ( 2 * k ) + 3 * L2 )] ); // q + i2_fx = Msub_32_16( i2_fx, timeBuffer_fx[( L2 - 3 * M2 - 1 - ( 2 * k ) + 4 * L2 )], ptr_pf_fx[( L2 - 3 * M2 - 1 - ( 2 * k ) + 4 * L2 )] ); // q + + r1_fx = Mpy_32_16_1( r1_fx, ptr_pf_sf ); // q - 1 + r2_fx = Mpy_32_16_1( r2_fx, ptr_pf_sf ); // q - 1 + i1_fx = Mpy_32_16_1( i1_fx, ptr_pf_sf ); // q - 1 + i2_fx = Mpy_32_16_1( i2_fx, ptr_pf_sf ); // q - 1 + + /* folding + pre modulation of DST IV */ + rr12_fx = L_sub( r1_fx, r2_fx ); // q -1 + ri12_fx = L_negate( L_add( i1_fx, i2_fx ) ); // q - 1 + /*cplxMult(&rBuffer[2*k],&rBuffer[2*k+1],rr12,ri12,rot_vctr_re[k],rot_vctr_im[k]);*/ + rBuffer_fx[2 * k] = Msub_32_32( Mpy_32_32( rr12_fx, rot_vctr_re_fx[k] ), ri12_fx, rot_vctr_im_fx[k] ); // q - 3 + rBuffer_fx[2 * k + 1] = Madd_32_32( Mpy_32_32( rr12_fx, rot_vctr_im_fx[k] ), ri12_fx, rot_vctr_re_fx[k] ); // q - 3 + move32(); + move32(); + + ///* folding + pre modulation of DCT IV */ + ir12_fx = L_add( r1_fx, r2_fx ); // q - 1 + ii12_fx = L_sub( i1_fx, i2_fx ); // q - 1 + /*cplxMult(&iBuffer[2*k],&iBuffer[2*k+1],ir12,ii12,rot_vctr_re[k],rot_vctr_im[k]);*/ + iBuffer_fx[2 * k] = Msub_32_32( Mpy_32_32( ir12_fx, rot_vctr_re_fx[k] ), ii12_fx, rot_vctr_im_fx[k] ); // q - 3 + iBuffer_fx[2 * k + 1] = Madd_32_32( Mpy_32_32( ir12_fx, rot_vctr_im_fx[k] ), ii12_fx, rot_vctr_re_fx[k] ); // q - 3 + move32(); + move32(); + } + + FOR( k = M4; k < M2; k++ ) + { + /* prototype filter */ + r1_fx = Msub_32_16( 0, timeBuffer_fx[( L2 - M2 - 1 - ( 2 * k ) + 0 * L2 )], ptr_pf_fx[( L2 - M2 - 1 - ( 2 * k ) + 0 * L2 )] ); // q + r1_fx = Msub_32_16( r1_fx, timeBuffer_fx[( L2 - M2 - 1 - ( 2 * k ) + 1 * L2 )], ptr_pf_fx[( L2 - M2 - 1 - ( 2 * k ) + 1 * L2 )] ); // q + r1_fx = Msub_32_16( r1_fx, timeBuffer_fx[( L2 - M2 - 1 - ( 2 * k ) + 2 * L2 )], ptr_pf_fx[( L2 - M2 - 1 - ( 2 * k ) + 2 * L2 )] ); // q + r1_fx = Msub_32_16( r1_fx, timeBuffer_fx[( L2 - M2 - 1 - ( 2 * k ) + 3 * L2 )], ptr_pf_fx[( L2 - M2 - 1 - ( 2 * k ) + 3 * L2 )] ); // q + r1_fx = Msub_32_16( r1_fx, timeBuffer_fx[( L2 - M2 - 1 - ( 2 * k ) + 4 * L2 )], ptr_pf_fx[( L2 - M2 - 1 - ( 2 * k ) + 4 * L2 )] ); // q + + r2_fx = Msub_32_16( 0, timeBuffer_fx[( L2 - 5 * M2 + ( 2 * k ) + 0 * L2 )], ptr_pf_fx[( L2 - 5 * M2 + ( 2 * k ) + 0 * L2 )] ); // q + r2_fx = Msub_32_16( r2_fx, timeBuffer_fx[( L2 - 5 * M2 + ( 2 * k ) + 1 * L2 )], ptr_pf_fx[( L2 - 5 * M2 + ( 2 * k ) + 1 * L2 )] ); // q + r2_fx = Msub_32_16( r2_fx, timeBuffer_fx[( L2 - 5 * M2 + ( 2 * k ) + 2 * L2 )], ptr_pf_fx[( L2 - 5 * M2 + ( 2 * k ) + 2 * L2 )] ); // q + r2_fx = Msub_32_16( r2_fx, timeBuffer_fx[( L2 - 5 * M2 + ( 2 * k ) + 3 * L2 )], ptr_pf_fx[( L2 - 5 * M2 + ( 2 * k ) + 3 * L2 )] ); // q + r2_fx = Msub_32_16( r2_fx, timeBuffer_fx[( L2 - 5 * M2 + ( 2 * k ) + 4 * L2 )], ptr_pf_fx[( L2 - 5 * M2 + ( 2 * k ) + 4 * L2 )] ); // q + + i1_fx = Msub_32_16( 0, timeBuffer_fx[( L2 + M2 - 1 - ( 2 * k ) + 0 * L2 )], ptr_pf_fx[( L2 + M2 - 1 - ( 2 * k ) + 0 * L2 )] ); // q + i1_fx = Msub_32_16( i1_fx, timeBuffer_fx[( L2 + M2 - 1 - ( 2 * k ) + 1 * L2 )], ptr_pf_fx[( L2 + M2 - 1 - ( 2 * k ) + 1 * L2 )] ); // q + i1_fx = Msub_32_16( i1_fx, timeBuffer_fx[( L2 + M2 - 1 - ( 2 * k ) + 2 * L2 )], ptr_pf_fx[( L2 + M2 - 1 - ( 2 * k ) + 2 * L2 )] ); // q + i1_fx = Msub_32_16( i1_fx, timeBuffer_fx[( L2 + M2 - 1 - ( 2 * k ) + 3 * L2 )], ptr_pf_fx[( L2 + M2 - 1 - ( 2 * k ) + 3 * L2 )] ); // q + i1_fx = Msub_32_16( i1_fx, timeBuffer_fx[( L2 + M2 - 1 - ( 2 * k ) + 4 * L2 )], ptr_pf_fx[( L2 + M2 - 1 - ( 2 * k ) + 4 * L2 )] ); // q + + i2_fx = Msub_32_16( 0, timeBuffer_fx[( L2 - 3 * M2 + ( 2 * k ) + 0 * L2 )], ptr_pf_fx[( L2 - 3 * M2 + ( 2 * k ) + 0 * L2 )] ); // q + i2_fx = Msub_32_16( i2_fx, timeBuffer_fx[( L2 - 3 * M2 + ( 2 * k ) + 1 * L2 )], ptr_pf_fx[( L2 - 3 * M2 + ( 2 * k ) + 1 * L2 )] ); // q + i2_fx = Msub_32_16( i2_fx, timeBuffer_fx[( L2 - 3 * M2 + ( 2 * k ) + 2 * L2 )], ptr_pf_fx[( L2 - 3 * M2 + ( 2 * k ) + 2 * L2 )] ); // q + i2_fx = Msub_32_16( i2_fx, timeBuffer_fx[( L2 - 3 * M2 + ( 2 * k ) + 3 * L2 )], ptr_pf_fx[( L2 - 3 * M2 + ( 2 * k ) + 3 * L2 )] ); // q + i2_fx = Msub_32_16( i2_fx, timeBuffer_fx[( L2 - 3 * M2 + ( 2 * k ) + 4 * L2 )], ptr_pf_fx[( L2 - 3 * M2 + ( 2 * k ) + 4 * L2 )] ); // q + + r1_fx = Mpy_32_16_1( r1_fx, ptr_pf_sf ); // q - 1 + r2_fx = Mpy_32_16_1( r2_fx, ptr_pf_sf ); // q - 1 + i1_fx = Mpy_32_16_1( i1_fx, ptr_pf_sf ); // q - 1 + i2_fx = Mpy_32_16_1( i2_fx, ptr_pf_sf ); // q - 1 + + /* folding + pre modulation of DST IV */ + rr12_fx = L_add( r1_fx, r2_fx ); // q - 1 + ri12_fx = L_sub( i1_fx, i2_fx ); // q - 1 + /*cplxMult(&rBuffer[2*k],&rBuffer[2*k+1],rr12,ri12,rot_vctr_re[k],rot_vctr_im[k]);*/ + rBuffer_fx[2 * k] = Msub_32_32( Mpy_32_32( rr12_fx, rot_vctr_re_fx[k] ), ri12_fx, rot_vctr_im_fx[k] ); // q - 3 + rBuffer_fx[2 * k + 1] = Madd_32_32( Mpy_32_32( rr12_fx, rot_vctr_im_fx[k] ), ri12_fx, rot_vctr_re_fx[k] ); // q - 3 + move32(); + move32(); + + /* folding + pre modulation of DCT IV */ + ir12_fx = L_sub( r1_fx, r2_fx ); // q - 1 + ii12_fx = L_add( i1_fx, i2_fx ); // q - 1 + /*cplxMult(&iBuffer[2*k],&iBuffer[2*k+1],ir12,ii12,rot_vctr_re[k],rot_vctr_im[k]);*/ + iBuffer_fx[2 * k] = Msub_32_32( Mpy_32_32( ir12_fx, rot_vctr_re_fx[k] ), ii12_fx, rot_vctr_im_fx[k] ); // q - 3 + iBuffer_fx[2 * k + 1] = Madd_32_32( Mpy_32_32( ir12_fx, rot_vctr_im_fx[k] ), ii12_fx, rot_vctr_re_fx[k] ); // q - 3 + move32(); + move32(); + } + + *q_cldfb = sub( *q_cldfb, 3 ); + move16(); + + /* FFT of DST IV */ + fft_cldfb_fx( rBuffer_fx, M2 ); + + /* post modulation of DST IV */ + FOR( k = 0; k < M2; k++ ) + { + /*cplxMult(&realBuffer[M1-1-(2*k)],&realBuffer[2*k],rBuffer[2*k],rBuffer[2*k+1],rot_vctr_re[k],rot_vctr_im[k]);*/ + realBuffer_fx[( M1 - 1 ) - ( k * 2 )] = Msub_32_32( Mpy_32_32( rBuffer_fx[2 * k], rot_vctr_re_fx[k] ), rBuffer_fx[2 * k + 1], rot_vctr_im_fx[k] ); // q - 5 + realBuffer_fx[2 * k] = Madd_32_32( Mpy_32_32( rBuffer_fx[2 * k], rot_vctr_im_fx[k] ), rBuffer_fx[2 * k + 1], rot_vctr_re_fx[k] ); // q - 5 + move32(); + move32(); + } + *q_cldfb = sub( *q_cldfb, 2 ); + move16(); + + /* FFT of DCT IV */ + fft_cldfb_fx( iBuffer_fx, M2 ); + + /* post modulation of DCT IV */ + FOR( k = 0; k < M2; k++ ) + { + /* do it inplace */ + /*cplxMult(&imagBuffer[2*k],&imagBuffer[M1-1-(2*k)],iBuffer[2*k],iBuffer[2*k+1],rot_vctr_re[k],rot_vctr_im[k]);*/ + imagBuffer_fx[2 * k] = Msub_32_32( Mpy_32_32( iBuffer_fx[2 * k], rot_vctr_re_fx[k] ), iBuffer_fx[2 * k + 1], rot_vctr_im_fx[k] ); // q - 5 + imagBuffer_fx[( M1 - 1 ) - ( k * 2 )] = Madd_32_32( Mpy_32_32( iBuffer_fx[2 * k], rot_vctr_im_fx[k] ), iBuffer_fx[2 * k + 1], rot_vctr_re_fx[k] ); // q - 5 + move32(); + move32(); + } + + IF( EQ_32( h_cldfb->prototype, CLDFB_PROTOTYPE_5_00MS ) ) + { + /* rotation due to delay*/ + /*if(h_cldfb->da != M1)*/ + IF( rot_vctr_delay_re_fx != NULL ) + { + FOR( k = 0; k < M1; k++ ) + { + Word32 cplx_aux_fx; + /* delay */ + /*cplxMult(&rBuffer[k], &iBuffer[k], realBuffer[i][k], imagBuffer[i][k], cos((EVS_PI/M1)*(k+0.5)*((h_cldfb->da-M1)*0.5)), + sin((EVS_PI/M1)*(k+0.5)*((h_cldfb->da-M1)*0.5)));*/ + /*cplxMult(&rBuffer[k], &iBuffer[k], realBuffer[k], imagBuffer[k], rot_vctr_delay_re[k], rot_vctr_delay_im[k]);*/ + /*cplxMult(&realBuffer[k], &imagBuffer[k], realBuffer[k], imagBuffer[k], rot_vctr_delay_re[k], rot_vctr_delay_im[k]);*/ + /*realBuffer[k] = rBuffer[k]; + imagBuffer[k] = iBuffer[k];*/ + cplx_aux_fx = Msub_32_32( Mpy_32_32( realBuffer_fx[k], rot_vctr_delay_re_fx[k] ), imagBuffer_fx[k], rot_vctr_delay_im_fx[k] ); // q - 5 + imagBuffer_fx[k] = Madd_32_32( Mpy_32_32( realBuffer_fx[k], rot_vctr_delay_im_fx[k] ), imagBuffer_fx[k], rot_vctr_delay_re_fx[k] ); // q - 5 + realBuffer_fx[k] = cplx_aux_fx; + move32(); + move32(); + } + } + } + + timeBuffer_fx += i_mult( L2, 5 ); + timeBuffer_fx += sub( h_cldfb->no_channels, h_cldfb->p_filter_length ); + } + + /* update memory */ + IF( GT_16( samplesToProcess, -1 ) ) + { + Copy32( buffer_fx + samplesToProcess, h_cldfb->cldfb_state_fx, offset ); + } + ELSE + { + Copy32( buffer_fx + frameSize, h_cldfb->cldfb_state_fx, offset ); + } + + return; +} + + void cldfbAnalysis_ts_fx_fixed_q( const Word32 *timeIn_fx, /* i : time buffer */ // q @@ -941,7 +1211,7 @@ void cldfbSynthesis_ivas_fx( /*cplxMult(&iBuffer[2*i], &iBuffer[2*i+1],-imagBuffer[k][2*i], imagBuffer[k][M1-1-2*i], rot_vctr_re[i], rot_vctr_im[i]);*/ iBuffer_fx[2 * i] = Msub_32_32( Mpy_32_32( ( L_negate( imagBuffer_fx[k][2 * i] ) ), rot_vctr_re_fx[i] ), imagBuffer_fx[k][( M1 - 1 ) - ( i * 2 )], rot_vctr_im_fx[i] ); // Qx move32(); - iBuffer_fx[2 * i + 1] = Madd_32_32( Mpy_32_32( ( L_negate( imagBuffer_fx[k][2 * i] ) ), rot_vctr_im_fx[i] ), imagBuffer_fx[k][( M1 - 1 ) - ( i * 2 )], rot_vctr_re_fx[i] ); // Qx + iBuffer_fx[2 * i + 1] = Msub_32_32( Mpy_32_32( imagBuffer_fx[k][( M1 - 1 ) - ( i * 2 )], rot_vctr_re_fx[i] ), imagBuffer_fx[k][2 * i], rot_vctr_im_fx[i] ); // Qx move32(); } @@ -1093,8 +1363,8 @@ ivas_error openCldfb_ivas_fx( HANDLE_CLDFB_FILTER_BANK *h_cldfb, /* i/o: filter bank handle */ CLDFB_TYPE type, /* i : analysis or synthesis */ const Word32 sampling_rate, /* i : sampling rate */ - CLDFB_PROTOTYPE prototype /* i : CLDFB version (1.25ms/5ms delay) */ -) + CLDFB_PROTOTYPE prototype, /* i : CLDFB version (1.25ms/5ms delay) */ + const Word16 enc_dec ) /* i : encoder/decoder flag */ { HANDLE_CLDFB_FILTER_BANK hs; Word16 buf_len; @@ -1108,95 +1378,45 @@ ivas_error openCldfb_ivas_fx( move32(); hs->prototype = prototype; move32(); - configureCldfb_ivas_fx( hs, sampling_rate ); - hs->memory32 = NULL; - hs->FilterStates = NULL; - hs->memory_length = 0; - move16(); - - IF( EQ_32( type, CLDFB_ANALYSIS ) ) + IF( enc_dec == ENC ) { - buf_len = sub( hs->p_filter_length, hs->no_channels ); + configureCldfb_ivas_enc_fx( hs, sampling_rate ); + hs->Q_cldfb_state = 0; } ELSE { - buf_len = hs->p_filter_length; - move16(); - } - - IF( ( hs->cldfb_state_fx = (Word32 *) malloc( buf_len * sizeof( Word32 ) ) ) == NULL ) - { - return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Cannot allocate memory for CLDFB" ); + configureCldfb_ivas_fx( hs, sampling_rate ); + hs->Q_cldfb_state = Q11; } - - hs->cldfb_state_length = buf_len; // Temporarily added to store the length of buffer - move16(); - hs->cldfb_size = buf_len; /*for having original size at intermediatery conversion, will be removed on removing conversion*/ - move16(); - set32_fx( hs->cldfb_state_fx, 0, buf_len ); - hs->Q_cldfb_state = Q11; - move16(); - *h_cldfb = hs; move16(); - - return IVAS_ERR_OK; -} - -ivas_error openCldfb_ivas_enc( - HANDLE_CLDFB_FILTER_BANK *h_cldfb, /* i/o: filter bank handle */ - CLDFB_TYPE type, /* i : analysis or synthesis */ - const Word32 sampling_rate, /* i : sampling rate */ - CLDFB_PROTOTYPE prototype /* i : CLDFB version (1.25ms/5ms delay) */ -) -{ - HANDLE_CLDFB_FILTER_BANK hs; - Word16 buf_len; - - IF( ( hs = (HANDLE_CLDFB_FILTER_BANK) malloc( sizeof( CLDFB_FILTER_BANK ) ) ) == NULL ) - { - return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Cannot allocate memory for CLDFB" ); - } - - hs->type = type; - move32(); - hs->prototype = prototype; - move32(); - - configureCldfb_ivas_enc_fx( hs, sampling_rate ); + hs->memory32 = NULL; + hs->FilterStates = NULL; hs->memory_length = 0; - move32(); + move16(); - IF( type == CLDFB_ANALYSIS ) + IF( EQ_32( type, CLDFB_ANALYSIS ) ) { buf_len = sub( hs->p_filter_length, hs->no_channels ); - hs->FilterStates = (Word16 *) malloc( ( 9 + 16 ) * CLDFB_getNumChannels( sampling_rate ) * sizeof( Word16 ) ); - hs->FilterStates_eg = 0; - move16(); } ELSE { buf_len = hs->p_filter_length; move16(); - hs->FilterStates = (Word16 *) malloc( 2 * ( 9 + 16 ) * CLDFB_getNumChannels( sampling_rate ) * sizeof( Word16 ) ); - hs->FilterStates_eg = 0; - move16(); } - if ( ( hs->cldfb_state_fx = (Word32 *) malloc( buf_len * sizeof( Word32 ) ) ) == NULL ) + IF( ( hs->cldfb_state_fx = (Word32 *) malloc( buf_len * sizeof( Word32 ) ) ) == NULL ) { return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Cannot allocate memory for CLDFB" ); } + hs->cldfb_state_length = buf_len; // Temporarily added to store the length of buffer move16(); hs->cldfb_size = buf_len; /*for having original size at intermediatery conversion, will be removed on removing conversion*/ move16(); set32_fx( hs->cldfb_state_fx, 0, buf_len ); - hs->Q_cldfb_state = 0; - move16(); - set16_fx( hs->FilterStates, 0, i_mult( 9 + 16, hs->no_channels ) ); - set16_fx( hs->FilterStates_e, 0, sizeof( hs->FilterStates_e ) / sizeof( hs->FilterStates_e[0] ) ); *h_cldfb = hs; + move16(); return IVAS_ERR_OK; } @@ -1292,41 +1512,6 @@ void analysisCldfbEncoder_ivas_fx( return; } - -/*-------------------------------------------------------------------* - * GetEnergyCldfb_ivas() - * - * Remove handle - *--------------------------------------------------------------------*/ - -void deleteCldfb_ivas( - HANDLE_CLDFB_FILTER_BANK *h_cldfb /* i/o: filter bank handle */ -) -{ - HANDLE_CLDFB_FILTER_BANK hs = *h_cldfb; - - test(); - IF( h_cldfb == NULL || *h_cldfb == NULL ) - { - return; - } - - IF( hs->cldfb_state_fx ) - { - free( hs->cldfb_state_fx ); - } - - IF( hs->FilterStates ) - { - free( hs->FilterStates ); - } - - free( hs ); - *h_cldfb = NULL; - - return; -} - void deleteCldfb_ivas_fx( HANDLE_CLDFB_FILTER_BANK *h_cldfb /* i/o: filter bank handle */ ) diff --git a/lib_com/cldfb_evs.c b/lib_com/cldfb_evs.c index 923d2b8873b3f15ed2a49e3371ce98da27b4d4f2..d74b9b64671902f550e2b560d4b3a3992a05ee3e 100644 --- a/lib_com/cldfb_evs.c +++ b/lib_com/cldfb_evs.c @@ -72,7 +72,6 @@ cldfb_init_proto_and_twiddles( HANDLE_CLDFB_FILTER_BANK hs ); iyr = CL_Extract_real( CL_iy ); \ iyi = CL_Extract_imag( CL_iy ); \ rxr += sx, rxi += sx, ixr += sx, ixi += sx, cr += sr, ci += sr -#ifdef BASOP_NOGLOB #define add1( y1, y2, y3, y4, rr12, ri12, ir12, ii12, s ) \ *y1 = round_fx_sat( L_shl_sat( L_negate( L_add_sat( rr12, ii12 ) ), s ) ); \ @@ -88,21 +87,6 @@ cldfb_init_proto_and_twiddles( HANDLE_CLDFB_FILTER_BANK hs ); *y4 = round_fx_sat( L_shl_sat( L_sub_sat( rr12, ii12 ), s ) ); \ y1 += 2, y2 -= 2, y3 -= 2, y4 += 2 -#else -#define add1( y1, y2, y3, y4, rr12, ri12, ir12, ii12, s ) \ - *y1 = round_fx( L_shl( L_negate( L_add( rr12, ii12 ) ), s ) ); \ - *y2 = round_fx( L_shl( L_negate( L_add( ri12, ir12 ) ), s ) ); \ - *y3 = round_fx( L_shl( L_sub( rr12, ii12 ), s ) ); \ - *y4 = round_fx( L_shl( L_sub( ir12, ri12 ), s ) ); \ - y1 += 2, y2 -= 2, y3 -= 2, y4 += 2 - -#define add2( y1, y2, y3, y4, rr12, ri12, ir12, ii12, s ) \ - *y1 = round_fx( L_shl( L_add( ri12, ir12 ), s ) ); \ - *y2 = round_fx( L_shl( L_add( rr12, ii12 ), s ) ); \ - *y3 = round_fx( L_shl( L_sub( ir12, ri12 ), s ) ); \ - *y4 = round_fx( L_shl( L_sub( rr12, ii12 ), s ) ); \ - y1 += 2, y2 -= 2, y3 -= 2, y4 += 2 -#endif #define ptrUpdate16( y11, y12, y13, y14, r11, x11, x12, x13, x14, r12, y21, y22, y23, y24, r21, x21, x22, x23, x24, r22 ) \ y11 += 2 * N8, y12 -= 2 * N8, y13 -= 2 * N8, y14 += 2 * N8, r11 -= 1 * N8; \ @@ -497,11 +481,7 @@ void cldfbAnalysisFiltering( HANDLE_CLDFB_FILTER_BANK cldfbBank, /* move and scale filter states */ FOR( i = 0; i < offset; i++ ) { -#ifdef BASOP_NOGLOB pStates[i] = shl_sat( pStates[i + nSamplesUpd], scale ); // Q(15-(timeIn_e-FilterStates_eg)) -#else - pStates[i] = shl( pStates[i + nSamplesUpd], scale ); -#endif move16(); } @@ -509,11 +489,7 @@ void cldfbAnalysisFiltering( HANDLE_CLDFB_FILTER_BANK cldfbBank, scale = sub( timeIn_e, cldfbBank->FilterStates_eg ); FOR( i = 0; i < nSamples; i++ ) { -#ifdef BASOP_NOGLOB pStates[offset + i] = shl_sat( *timeIn, scale ); // Q(15-scale) -#else - pStates[offset + i] = shl( *timeIn, scale ); -#endif move16(); timeIn = timeIn + stride; } @@ -880,11 +856,7 @@ void cldfbSynthesisFiltering( HANDLE_CLDFB_FILTER_BANK cldfbBank, acc = L_mac( acc, nBuffer[sub( channels1, i )], *pFilterM++ ); BASOP_SATURATE_WARNING_OFF_EVS -#ifdef BASOP_NOGLOB timeOut[( offset1 - i ) * stride] = round_fx_sat( L_shl_sat( acc, outScale ) ); -#else - timeOut[( offset1 - i ) * stride] = round_fx( L_shl( acc, outScale ) ); -#endif BASOP_SATURATE_WARNING_ON_EVS move16(); } @@ -916,11 +888,7 @@ void cldfbSynthesisFiltering( HANDLE_CLDFB_FILTER_BANK cldfbBank, pFilterM++; BASOP_SATURATE_WARNING_OFF_EVS -#ifdef BASOP_NOGLOB timeOut[( offset2 - i ) * stride] = round_fx_sat( L_shl_sat( acc, outScale ) ); -#else - timeOut[( offset2 - i ) * stride] = round_fx( L_shl( acc, outScale ) ); -#endif BASOP_SATURATE_WARNING_ON_EVS move16(); } @@ -1167,13 +1135,8 @@ AnalysisPostSpectrumScaling_Fx( HANDLE_CLDFB_FILTER_BANK cldfbBank, /*!< Handle { FOR( j = 0; j < cldfbBank->no_channels; j++ ) { -#ifdef BASOP_NOGLOB rSubband16[i][j] = round_fx_sat( L_shl_sat( rSubband32[i][j], headRoom ) ); // Q(cldfbSacle_headRoom) iSubband16[i][j] = round_fx_sat( L_shl_sat( iSubband32[i][j], headRoom ) ); // Q(cldfbSacle+headRoom) -#else - rSubband16[i][j] = round_fx( L_shl( rSubband32[i][j], headRoom ) ); - iSubband16[i][j] = round_fx( L_shl( iSubband32[i][j], headRoom ) ); -#endif move16(); move16(); } @@ -1378,11 +1341,7 @@ void GetEnergyCldfb( Word32 *energyLookahead, /*!< o: Q(*sf_energyLookahead) { FOR( j = 20; j < numberBandsM; j++ ) { -#ifdef BASOP_NOGLOB nrg = L_add_o( nrg, L_shr_o( energyValues[k][j], s, &Overflow ), &Overflow ); -#else - nrg = L_add( nrg, L_shr( energyValues[k][j], s ) ); -#endif } } @@ -1405,11 +1364,7 @@ void GetEnergyCldfb( Word32 *energyLookahead, /*!< o: Q(*sf_energyLookahead) { FOR( j = 20; j < numberBandsM; j++ ) { -#ifdef BASOP_NOGLOB nrg = L_add_o( nrg, L_shr_o( energyValues[k][j], s, &Overflow ), &Overflow ); -#else - nrg = L_add( nrg, L_shr( energyValues[k][j], s ) ); -#endif } } @@ -1417,13 +1372,8 @@ void GetEnergyCldfb( Word32 *energyLookahead, /*!< o: Q(*sf_energyLookahead) sm = sub( s_min( s, 44 ), 1 ); BASOP_SATURATE_WARNING_OFF_EVS /* nrg + 6.1e-5f => value 0x40000000, scale 44 */ -#ifdef BASOP_NOGLOB *energyLookahead = L_add_sat( L_shr_sat( nrg, sub( s, sm ) ), L_shr_sat( 0x40000000, s_max( -31, s_min( 31, sub( 44, sm ) ) ) ) ); -#else - *energyLookahead = L_add( L_shr( nrg, sub( s, sm ) ), - L_shr( 0x40000000, s_max( -31, s_min( 31, sub( 44, sm ) ) ) ) ); -#endif move32(); BASOP_SATURATE_WARNING_ON_EVS *sf_energyLookahead = sm; diff --git a/lib_com/cng_exc_fx.c b/lib_com/cng_exc_fx.c index f346f3bb3e4a39ac08c5fe664f3d06f9ba6967d7..4153afa322f6b2c51a39890128b80c94034c51bd 100644 --- a/lib_com/cng_exc_fx.c +++ b/lib_com/cng_exc_fx.c @@ -47,7 +47,7 @@ void CNG_exc_fx( Word16 *cng_ener_seed1, Word16 exc3[], /*Q_exc*/ Word16 Opt_AMR_WB, - const int16_t element_mode /* i : IVAS Element mode */ + const Word16 element_mode /* i : IVAS Element mode */ ) { Word16 i, tmp, tmp2, exp, exp2, Q_ener; @@ -194,11 +194,7 @@ FOR( i_subfr = 0; i_subfr < L_frame; i_subfr += L_SUBFR ) *------------------------------------------------------------*/ L_tmp = Mult_32_16( *lp_ener, Random( cng_ener_seed ) ); // Q6 L_tmp = Mult_32_16( L_tmp, GAIN_VAR ); // Q6 -#ifdef BASOP_NOGLOB L_tmp = L_add_sat( L_tmp, *lp_ener ); -#else - L_tmp = L_add( L_tmp, *lp_ener ); -#endif L_tmp = L_max( L_tmp, 1 ); /* enr = dot_product( exc2, exc2, L_SUBFR ) + 0.01f */ @@ -234,11 +230,7 @@ FOR( i_subfr = 0; i_subfr < L_frame; i_subfr += L_SUBFR ) { /* exc2[i] *= enr */ L_tmp = L_mult( exc2[i_subfr + i], tmp ); /* Q-4 * Q_exc+19 -> Q_exc +16 */ -#ifdef BASOP_NOGLOB exc2[i_subfr + i] = round_fx_sat( L_shl_sat( L_tmp, exp ) ); -#else - exc2[i_subfr + i] = round_fx( L_shl( L_tmp, exp ) ); -#endif move16(); } } @@ -250,11 +242,7 @@ IF( NE_16( Opt_AMR_WB, 1 ) ) exp = norm_l( *Enew ); L_tmp = L_shl( *Enew, exp ); /* Q(exp+6) */ L_tmp = Mult_32_16( L_tmp, shl( L_frame, 5 ) ); /* Q(exp+6+5-15=exp-4) */ -#ifdef BASOP_NOGLOB - L_tmp = L_shr_sat( L_tmp, sub( exp, 10 ) ); /* Q6 */ -#else - L_tmp = L_shr( L_tmp, sub( exp, 10 ) ); /* Q6 */ -#endif + L_tmp = L_shr_sat( L_tmp, sub( exp, 10 ) ); /* Q6 */ exp = norm_l( L_tmp ); fra = Log2_norm_lc( L_shl( L_tmp, exp ) ); exp = sub( sub( 30, exp ), 6 ); @@ -320,19 +308,11 @@ IF( NE_16( Opt_AMR_WB, 1 ) ) FOR( i = 0; i < NUM_ENV_CNG; i++ ) { /* env[i] = 2.0f*(*ptR * *ptR + *ptI * *ptI)/L_FFT; */ - L_tmp = L_mult0( *ptR, *ptR ); /* 2*Q_exc */ -#ifdef BASOP_NOGLOB + L_tmp = L_mult0( *ptR, *ptR ); /* 2*Q_exc */ L_tmp = L_mac0_sat( L_tmp, *ptI, *ptI ); /* 2*Q_exc */ -#else - L_tmp = L_mac0( L_tmp, *ptI, *ptI ); /* 2*Q_exc */ -#endif - L_tmp = L_shr( L_tmp, 1 ); /* 2*Q_exc+6 */ + L_tmp = L_shr( L_tmp, 1 ); /* 2*Q_exc+6 */ tmp = add( Q_exc, Q_exc ); -#ifdef BASOP_NOGLOB env[i] = L_shr_sat( L_tmp, tmp ); -#else - env[i] = L_shr( L_tmp, tmp ); -#endif move32(); /* Q6 */ ptR++; ptI--; @@ -341,13 +321,8 @@ IF( NE_16( Opt_AMR_WB, 1 ) ) FOR( i = 0; i < NUM_ENV_CNG; i++ ) { /* denv[i] = lp_env[i] + 2*(*lp_ener) - env[i]; */ -#ifdef BASOP_NOGLOB L_tmp = L_add_sat( *lp_ener, *lp_ener ); denv[i] = L_sub_sat( L_add_sat( lp_env[i], L_tmp ), env[i] ); -#else - L_tmp = L_add( *lp_ener, *lp_ener ); - denv[i] = L_sub( L_add( lp_env[i], L_tmp ), env[i] ); -#endif move32(); /* Q6 */ if ( denv[i] < 0 ) @@ -384,13 +359,8 @@ IF( NE_16( Opt_AMR_WB, 1 ) ) /* itmp[i] += own_random( cng_ener_seed1 )*denv[i]*0.000011f + denv[i]; */ L_tmp = Mult_32_16( denv[i], Random( cng_ener_seed1 ) ); // Q6 L_tmp = Mult_32_16( L_tmp, GAIN_VAR ); // Q6 -#ifdef BASOP_NOGLOB L_tmp = L_add_sat( L_tmp, denv[i] ); itmp[i] = L_add_sat( L_tmp, itmp[i] ); -#else - L_tmp = L_add( L_tmp, denv[i] ); - itmp[i] = L_add( L_tmp, itmp[i] ); -#endif move32(); /* Q6 */ if ( itmp[i] < 0 ) @@ -427,19 +397,11 @@ IF( NE_16( Opt_AMR_WB, 1 ) ) L_tmp = L_deposit_h( tmp ); L_tmp = Isqrt_lc( L_tmp, &exp ); /*Q(31-exp)*/ - L_tmp2 = Mult_32_16( L_tmp, *ptR ); /*Q(16-exp)*/ -#ifdef BASOP_NOGLOB + L_tmp2 = Mult_32_16( L_tmp, *ptR ); /*Q(16-exp)*/ *ptR = extract_h( L_shl_sat( L_tmp2, add( exp, Q_exc ) ) ); /*Q_exc*/ -#else - *ptR = extract_h( L_shl( L_tmp2, add( exp, Q_exc ) ) ); /*Q_exc*/ -#endif move16(); - L_tmp2 = Mult_32_16( L_tmp, *ptI ); /*Q(16-exp)*/ -#ifdef BASOP_NOGLOB + L_tmp2 = Mult_32_16( L_tmp, *ptI ); /*Q(16-exp)*/ *ptI = extract_h( L_shl_sat( L_tmp2, add( exp, Q_exc ) ) ); /*Q_exc*/ -#else - *ptI = extract_h( L_shl( L_tmp2, add( exp, Q_exc ) ) ); /*Q_exc*/ -#endif move16(); ptR++; ptI--; @@ -518,11 +480,7 @@ IF( NE_16( Opt_AMR_WB, 1 ) ) test(); IF( NE_32( last_core_brate, SID_2k40 ) && NE_32( last_core_brate, SID_1k75 ) && ( last_core_brate != FRAME_NO_DATA ) && EQ_32( core_brate, SID_2k40 ) ) { -#ifdef BASOP_NOGLOB IF( GT_32( L_tmp, L_shl_sat( 1, sub( 31, exp ) ) ) ) -#else - IF( GT_32( L_tmp, L_shl( 1, sub( 31, exp ) ) ) ) -#endif { L_tmp = L_shl( 1, sub( 31, exp ) ); } @@ -542,11 +500,7 @@ IF( NE_16( Opt_AMR_WB, 1 ) ) { /* fft_io[i] = 0.75f*fft_io[i] + exc2[i];*/ tmp = mult( fft_io[i], 24576 /*.75f in Q15*/ ); -#ifdef BASOP_NOGLOB fft_io[i] = add_sat( tmp, exc2[i] ); -#else - fft_io[i] = add( tmp, exc2[i] ); -#endif move16(); /*Q_exc*/ } @@ -561,15 +515,9 @@ IF( NE_16( Opt_AMR_WB, 1 ) ) { L_tmp = L_mult0( *pt_fft_io, *pt_fft_io ); pt_fft_io++; -#ifdef BASOP_NOGLOB L_tmp = L_mac0_sat( L_tmp, *pt_fft_io, *pt_fft_io ); /* 2*(Q_exc) */ pt_fft_io++; L_tmp2 = L_add_sat( L_tmp2, L_shr( L_tmp, 7 ) ); /* 2*(Q_exc)+1, divide by L_frame done here */ -#else - L_tmp = L_mac0( L_tmp, *pt_fft_io, *pt_fft_io ); /* 2*(Q_exc) */ - pt_fft_io++; - L_tmp2 = L_add( L_tmp2, L_shr( L_tmp, 7 ) ); /* 2*(Q_exc)+1, divide by L_frame done here */ -#endif } } ELSE /* L_FRAME16k */ @@ -578,11 +526,7 @@ IF( NE_16( Opt_AMR_WB, 1 ) ) { L_tmp = L_mult0( *pt_fft_io, *pt_fft_io ); pt_fft_io++; -#ifdef BASOP_NOGLOB L_tmp = L_mac0_sat( L_tmp, *pt_fft_io, *pt_fft_io ); /* 2*(Q_exc) */ -#else - L_tmp = L_mac0( L_tmp, *pt_fft_io, *pt_fft_io ); /* 2*(Q_exc) */ -#endif pt_fft_io++; L_tmp2 = L_add( L_tmp2, L_shr( Mult_32_16( L_tmp, 26214 /* 256/320, Q15 */ ), 7 ) ); /* 2*(Q_exc)+15+1-16+1, divide by L_frame done here */ } @@ -614,11 +558,7 @@ IF( NE_16( Opt_AMR_WB, 1 ) ) L_tmp = L_deposit_h( tmp ); L_tmp = Isqrt_lc( L_tmp, &exp ); /*Q(31-exp)*/ -#ifdef BASOP_NOGLOB ftmp = extract_h( L_shl_sat( L_tmp, exp ) ); /* Q15 */ -#else /* BASOP_NOGLOB */ - ftmp = extract_h( L_shl( L_tmp, exp ) ); /* Q15 */ -#endif /* BASOP_NOGLOB */ FOR( i = 0; i < L_frame; i++ ) { /* fft_io[i] *= ftmp;*/ @@ -710,15 +650,9 @@ void cng_params_postupd_fx( FOR( i = 0; i < NUM_ENV_CNG; i++ ) { /* sp[i] = 2.0f*(*ptR * *ptR + *ptI * *ptI)/L_FFT; */ -#ifdef BASOP_NOGLOB L_tmp = L_mult_o( *ptR, *ptR, &Overflow ); /* 2*Q_exc+1 */ L_tmp = L_add_o( L_tmp, L_mult_o( *ptI, *ptI, &Overflow ), &Overflow ); /* 2*Q_exc+1 */ L_tmp = L_add_o( L_tmp, L_tmp, &Overflow ); /* 2*Q_exc+1 */ -#else /* BASOP_NOGLOB */ - L_tmp = L_mult( *ptR, *ptR ); /* 2*Q_exc+1 */ - L_tmp = L_add( L_tmp, L_mult( *ptI, *ptI ) ); /* 2*Q_exc+1 */ - L_tmp = L_add( L_tmp, L_tmp ); /* 2*Q_exc+1 */ -#endif /* BASOP_NOGLOB */ L_tmp = Mult_32_16( L_tmp, 128 ); /* 2*Q_exc+1 */ tmp = add( add( Q_exc, Q_exc ), 1 ); sp[i] = L_shr( L_tmp, sub( tmp, 6 ) ); @@ -835,15 +769,9 @@ void cng_params_postupd_ivas_fx( FOR( i = 0; i < NUM_ENV_CNG; i++ ) { /* sp[i] = 2.0f*(*ptR * *ptR + *ptI * *ptI)/L_FFT; */ -#ifdef BASOP_NOGLOB L_tmp = L_mult_o( *ptR, *ptR, &Overflow ); /* 2*Q_exc+1 */ L_tmp = L_add_o( L_tmp, L_mult_o( *ptI, *ptI, &Overflow ), &Overflow ); /* 2*Q_exc+1 */ L_tmp = L_add_o( L_tmp, L_tmp, &Overflow ); /* 2*Q_exc+1 */ -#else /* BASOP_NOGLOB */ - L_tmp = L_mult( *ptR, *ptR ); /* 2*Q_exc+1 */ - L_tmp = L_add( L_tmp, L_mult( *ptI, *ptI ) ); /* 2*Q_exc+1 */ - L_tmp = L_add( L_tmp, L_tmp ); /* 2*Q_exc+1 */ -#endif /* BASOP_NOGLOB */ L_tmp = Mult_32_16( L_tmp, 128 ); /* 2*Q_exc+1 */ tmp = add( add( Q_exc, Q_exc ), 1 ); // To do : Saturation to be re-validated. @@ -866,7 +794,7 @@ void cng_params_postupd_ivas_fx( apply_scale( &att_fx, bwidth, last_active_brate, scaleTableStereo, SIZE_SCALE_TABLE_STEREO ); att_fx = L_shr( Mpy_32_16_1( att_fx, 26214 ), 3 ); /* 26214 = 0.1f in Q18 */ att_fx = BASOP_Util_fPow( 1342177280 /* 10 in Q27 */, 4, att_fx, 8, &tmp ); - tmp = extract_h( L_shl( att_fx, tmp ) ); + tmp = extract_h( L_shl_sat( att_fx, tmp ) ); // Fix for 3gpp #1080 (tmp set to 1.0) } ELSE { @@ -994,17 +922,9 @@ void cng_params_upd_fx( L_tmp = L_mult0( tmpv, tmpv ); /* 2*(Q_exc+scale) */ pt_exc2++; tmpv = shl( *pt_exc2, scale ); -#ifdef BASOP_NOGLOB L_tmp = L_mac0_o( L_tmp, tmpv, tmpv, &Overflow ); -#else - L_tmp = L_mac0( L_tmp, tmpv, tmpv ); -#endif pt_exc2++; -#ifdef BASOP_NOGLOB L_ener = L_add_o( L_ener, L_shr_o( L_tmp, 7, &Overflow ), &Overflow ); /* Q(2*(Q_exc+scale)+1) ,division by L_frame done here */ -#else - L_ener = L_add( L_ener, L_shr( L_tmp, 7 ) ); /* Q(2*(Q_exc+scale)+1) ,division by L_frame done here */ -#endif } } ELSE /* L_FRAME16k */ @@ -1015,24 +935,12 @@ void cng_params_upd_fx( L_tmp = L_mult0( tmpv, tmpv ); /* 2*(Q_exc+scale) */ pt_exc2++; tmpv = shl( *pt_exc2, scale ); -#ifdef BASOP_NOGLOB L_tmp = L_mac0_o( L_tmp, tmpv, tmpv, &Overflow ); -#else - L_tmp = L_mac0( L_tmp, tmpv, tmpv ); -#endif pt_exc2++; -#ifdef BASOP_NOGLOB L_ener = L_add_o( L_ener, L_shr_o( Mult_32_16( L_tmp, 26214 /* 256/320, Q15 */ ), 7, &Overflow ), &Overflow ); /* Q(2*(Q_exc+scale)+15+1-16+1) ,division by L_frame done here */ -#else - L_ener = L_add( L_ener, L_shr( Mult_32_16( L_tmp, 26214 /* 256/320, Q15 */ ), 7 ) ); /* Q(2*(Q_exc+scale)+15+1-16+1) ,division by L_frame done here */ -#endif } } -#ifdef BASOP_NOGLOB L_ener = L_shr_o( L_ener, sub( shl( add( Q_exc, scale ), 1 ), 5 ), &Overflow ); /* Q6 (2*(Q_exc+scale)+1-2*(Q_exc+scale)+5) */ -#else /* BASOP_NOGLOB */ - L_ener = L_shr( L_ener, sub( shl( add( Q_exc, scale ), 1 ), 5 ) ); /* Q6 (2*(Q_exc+scale)+1-2*(Q_exc+scale)+5) */ -#endif /* update the circular buffer of old energies */ ho_ener_circ[*ho_circ_ptr] = L_ener; @@ -1066,16 +974,10 @@ void cng_params_upd_fx( FOR( i = 0; i < NUM_ENV_CNG; i++ ) { /* sp[i] = 2.0f*(*ptR * *ptR + *ptI * *ptI)/L_FFT; */ -#ifdef BASOP_NOGLOB L_tmp = L_mult_o( *ptR, *ptR, &Overflow ); /* 2*Q_exc+1 */ L_tmp = L_add_o( L_tmp, L_mult_o( *ptI, *ptI, &Overflow ), &Overflow ); /* 2*Q_exc+1 */ L_tmp = L_add_o( L_tmp, L_tmp, &Overflow ); /* 2*Q_exc+1 */ -#else - L_tmp = L_mult( *ptR, *ptR ); /* 2*Q_exc+1 */ - L_tmp = L_add( L_tmp, L_mult( *ptI, *ptI ) ); /* 2*Q_exc+1 */ - L_tmp = L_add( L_tmp, L_tmp ); /* 2*Q_exc+1 */ -#endif - L_tmp = Mult_32_16( L_tmp, 128 ); /* 2*Q_exc+1 */ + L_tmp = Mult_32_16( L_tmp, 128 ); /* 2*Q_exc+1 */ tmp = add( add( Q_exc, Q_exc ), 1 ); sp[i] = L_shr( L_tmp, sub( tmp, 6 ) ); move32(); /* Q6 */ @@ -1207,17 +1109,9 @@ void cng_params_upd_ivas_fx( L_tmp = L_mult0( tmpv, tmpv ); /* 2*(Q_exc+scale) */ pt_exc2++; tmpv = shl( *pt_exc2, scale ); -#ifdef BASOP_NOGLOB L_tmp = L_mac0_o( L_tmp, tmpv, tmpv, &Overflow ); -#else - L_tmp = L_mac0( L_tmp, tmpv, tmpv ); -#endif pt_exc2++; -#ifdef BASOP_NOGLOB L_ener = L_add_o( L_ener, L_shr_o( L_tmp, 7, &Overflow ), &Overflow ); /* Q(2*(Q_exc+scale)+1) ,division by L_frame done here */ -#else - L_ener = L_add( L_ener, L_shr( L_tmp, 7 ) ); /* Q(2*(Q_exc+scale)+1) ,division by L_frame done here */ -#endif } } ELSE /* L_FRAME16k */ @@ -1228,24 +1122,12 @@ void cng_params_upd_ivas_fx( L_tmp = L_mult0( tmpv, tmpv ); /* 2*(Q_exc+scale) */ pt_exc2++; tmpv = shl( *pt_exc2, scale ); -#ifdef BASOP_NOGLOB L_tmp = L_mac0_o( L_tmp, tmpv, tmpv, &Overflow ); -#else - L_tmp = L_mac0( L_tmp, tmpv, tmpv ); -#endif pt_exc2++; -#ifdef BASOP_NOGLOB L_ener = L_add_o( L_ener, L_shr_o( Mult_32_16( L_tmp, 26214 /* 256/320, Q15 */ ), 7, &Overflow ), &Overflow ); /* Q(2*(Q_exc+scale)+15+1-16+1) ,division by L_frame done here */ -#else - L_ener = L_add( L_ener, L_shr( Mult_32_16( L_tmp, 26214 /* 256/320, Q15 */ ), 7 ) ); /* Q(2*(Q_exc+scale)+15+1-16+1) ,division by L_frame done here */ -#endif } } -#ifdef BASOP_NOGLOB L_ener = L_shr_o( L_ener, sub( shl( add( Q_exc, scale ), 1 ), 5 ), &Overflow ); /* Q6 (2*(Q_exc+scale)+1-2*(Q_exc+scale)+5) */ -#else /* BASOP_NOGLOB */ - L_ener = L_shr( L_ener, sub( shl( add( Q_exc, scale ), 1 ), 5 ) ); /* Q6 (2*(Q_exc+scale)+1-2*(Q_exc+scale)+5) */ -#endif /* update the circular buffer of old energies */ ho_ener_circ[*ho_circ_ptr] = L_ener; @@ -1279,16 +1161,10 @@ void cng_params_upd_ivas_fx( FOR( i = 0; i < NUM_ENV_CNG; i++ ) { /* sp[i] = 2.0f*(*ptR * *ptR + *ptI * *ptI)/L_FFT; */ -#ifdef BASOP_NOGLOB L_tmp = L_mult_o( *ptR, *ptR, &Overflow ); /* 2*Q_exc+1 */ L_tmp = L_add_o( L_tmp, L_mult_o( *ptI, *ptI, &Overflow ), &Overflow ); /* 2*Q_exc+1 */ L_tmp = L_add_o( L_tmp, L_tmp, &Overflow ); /* 2*Q_exc+1 */ -#else - L_tmp = L_mult( *ptR, *ptR ); /* 2*Q_exc+1 */ - L_tmp = L_add( L_tmp, L_mult( *ptI, *ptI ) ); /* 2*Q_exc+1 */ - L_tmp = L_add( L_tmp, L_tmp ); /* 2*Q_exc+1 */ -#endif - L_tmp = Mult_32_16( L_tmp, 128 ); /* 2*Q_exc+1 */ + L_tmp = Mult_32_16( L_tmp, 128 ); /* 2*Q_exc+1 */ tmp = add( add( Q_exc, Q_exc ), 1 ); sp[i] = L_shr( L_tmp, sub( tmp, 6 ) ); move32(); /* Q6 */ diff --git a/lib_com/cnst.h b/lib_com/cnst.h index 7e65723827fc815ad4a78a1bf7d85249c22661a7..1bcfcdb8f3fa23325597a599a71fc696b336cee1 100644 --- a/lib_com/cnst.h +++ b/lib_com/cnst.h @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other @@ -137,6 +137,7 @@ #define FOUR_IN_Q28 1073741824 #define MAX_WORD16 32767 +#define ONE_IN_Q45 (Word64)0x200000000000 #define ONE_IN_Q62 (Word64)0x4000000000000000 /*----------------------------------------------------------------------------------* * General constants @@ -173,6 +174,7 @@ #define MIN16B_FLT_FX_IN_Q15 -1073741824//Q15 #define PCM16_TO_FLT_FAC 32768.0f #define PCM16_TO_FLT_FAC_FX 32768 //Q0 +#define PCM16_TO_FLT_FAC_FX_Q15 1073741824L //16Q15 #define MDFT_NORM_SCALING ( 1.0f / PCM16_TO_FLT_FAC ) #define MDFT_NORM_SCALING_FX 65536 //Q31 #define LOG2_MDFT_NORM_SCALING_FX -503316448 //Q25 @@ -190,8 +192,14 @@ #define FORCE_MUSIC 101 /* debugging - force music on the command line */ #define FORCE_ACELP 102 /* debugging - force ACELP core on the command line */ #define FORCE_GSC 103 /* debugging - force GSC core on the command line */ +#ifdef SUPPORT_FORCE_TCX10_TCX20 +#define FORCE_TCX10 104 /* debugging - force TCX10 core on the command line */ +#define FORCE_TCX20 105 /* debugging - force TCX20 core on the command line */ +#define FORCE_HQ 106 /* debugging - force HQ core on the command line */ +#else #define FORCE_TCX 104 /* debugging - force TCX core on the command line */ #define FORCE_HQ 105 /* debugging - force HQ core on the command line */ +#endif #define FORCE_TD_RENDERER 201 #define FORCE_CLDFB_RENDERER 202 #endif @@ -232,7 +240,7 @@ enum{ #define L_FRAME48k_EXT 1200 /* Extended MDCT frame size in samples at 48kHz */ /* Conversion of ns to samples for a given sampling frequency */ -#define NS2SA( fs, x ) ( int16_t )( ( ( ( int32_t )( fs ) / 100L ) * ( ( x ) / 100L ) ) / 100000L ) +#define NS2SA( fs, x ) ( Word16 )( ( ( ( Word32 )( fs ) / 100L ) * ( ( x ) / 100L ) ) / 100000L ) #define NRG_CHANGE_E 8 #define AVG_FLAT_E 8 #define ACTIVE_FRAME 0xFF @@ -588,6 +596,7 @@ enum #define FRAMES_PER_SEC 50 #define MAX_PARAM_SPATIAL_SUB_FRAMES_PER_SEC 200 //(FRAMES_PER_SEC * MAX_PARAM_SPATIAL_SUBFRAMES) +#define ONE_BY_SUBFRAME_LEN_MS_Q31 (429496730) #define ONE_BY_FRAMES_PER_SEC_Q31 ( 42949673 ) #define FRAMES_PER_SEC_BY_2 (FRAMES_PER_SEC >> 1) #define INV_FRAME_PER_SEC_Q15 656 @@ -747,15 +756,15 @@ enum #define PIT_UP_SAMP6 6 #define PIT_L_INTERPOL6_2 17 #define PIT_FIR_SIZE6_2 ( PIT_UP_SAMP6 * PIT_L_INTERPOL6_2 + 1 ) -#define E_MIN_Q11_FX 7 /* minimum allowable energy in Q11*/ #define E_MIN 0.0035f /* minimum allowable energy */ #define E_MIN_Q11_FX 7 /* minimum allowable energy in Q11*/ -#define E_MIN_Q16_FX 229 /* minimum allowable energy in Q16*/ #define STEP_DELTA 0.0625f /* quantization step for tilt compensation of gaussian cb. excitation */ #define GAMMA_EV 0.92f /* weighting factor for core synthesis error weighting */ #define FORMANT_SHARPENING_NOISE_THRESHOLD 21.0f /* lp_noise level above which formant sharpening is deactivated */ #define E_MIN_FX 1 /* QSCALE (Q7)*/ #define E_MIN_IVAS_FX 1835 /* (Q19) (E12) */ +#define E_MIN_IVAS_FX_Q31 7516193 /* (Q31) (0.0035f) */ + #define STEP_DELTA_FX 11 #define FORMANT_SHARPENING_NOISE_THRESHOLD_FX 5376 /* 21 (!8)lp_noise level above which formant sharpening is deactivated - at this level most of 20 dB SNR office noisy speech still uses sharpening */ @@ -780,6 +789,7 @@ enum #define CLDFB_NO_CHANNELS_MAX 60 /* CLDFB resampling - max number of CLDFB channels, == IVAS_CLDFB_NO_CHANNELS_MAX */ #define CLDFB_NO_CHANNELS_MAX_FX 30720 /*Q9*/ #define CLDFB_NO_COL_MAX 16 /* CLDFB resampling - max number of CLDFB col., == IVAS_CLDFB_NO_COL_MAX */ +#define ONE_BY_CLDFB_NO_COL_MAX_Q31 134217728 #define CLDFB_NO_COL_MAX_SWITCH 6 /* CLDFB resampling - max number of CLDFB col. for switching */ #define CLDFB_NO_COL_MAX_SWITCH_BFI 10 /* CLDFB resampling - max number of CLDFB col. for switching, BFI */ #define CLDFB_OVRLP_MIN_SLOTS 3 /* CLDFB resampling - minimize processing to minimum required for transition frame ACELP->TCX/HQ */ @@ -925,6 +935,10 @@ typedef enum #define GAIN_PRED_ORDER 4 /* Gain quantization - prediction order for gain quantizer (only for AMR-WB IO mode) */ #define MEAN_ENER 30 /* Gain quantization - average innovation energy */ +#ifdef NONBE_FIX_1277_EVS_DTX_HIGH_RATE_THRESHOLD +#define DTX_THR 5 /* DTX - lp_noise threshold for DTX at higher bitrates */ +#endif + #define DTX_HIST_SIZE 8 /* CNG & DTX - number of last signal frames used for CNG averaging */ #define CNG_ISF_FACT 0.9f /* CNG & DTX - CNG spectral envelope smoothing factor */ #define STEP_AMR_WB_SID 2.625f /* CNG & DTX - CNG energy quantization step */ @@ -1161,7 +1175,6 @@ enum #define NBITS_NOISE_FILL_LEVEL 3 /* Number of bits used for coding noise filling level for each range */ #define NF_GAIN_BITS ( NBITS_TCX_GAIN + NOISE_FILL_RANGES * NBITS_NOISE_FILL_LEVEL ) #define MIN_NOISE_FILLING_HOLE 8 -#define HOLE_SIZE_FROM_LTP_FLT( gain ) ( 4 + ( int16_t )( 2.0f * gain * ( 4.0f / 0.625f ) ) ) #define HOLE_SIZE_FROM_LTP( gain ) (add(4, extract_h(L_shr(L_mult0(gain, 0x6666), 10)))) /* gain (Q15), 0x6666 = 2.0*(4.0/0.625) (4Q11) */ #define HOLE_SIZE_FROM_LTP32( gain ) (add(4, extract_h(L_shr(Mpy_32_32(gain, 0x66666667), 11)))) /* gain (Q31), 0x66666667 = 2.0*(4.0/0.625) (4Q27) */ @@ -1226,6 +1239,7 @@ enum #define SPC 0.0234952f #define SPC_plus SPC * 1.001f #define ALPHA_SQ ( ( 0.5f / PI2 ) * ( 0.5f / PI2 ) ) +#define ALPHA_SQ_Q30 (6799549) /* ( ( 0.5f / PI2 ) * ( 0.5f / PI2 ) ) in Q30 */ #define NC M / 2 #define LSF_GAP 50.0f @@ -1457,7 +1471,7 @@ enum #define cbitsnew 16 #define stat_bitsnew 14 -#define ari_q4new ( ( (int32_t) 1 << cbitsnew ) - 1 ) +#define ari_q4new ( ( (Word32) 1 << cbitsnew ) - 1 ) #define ari_q1new ( ari_q4new / 4 + 1 ) #define ari_q2new ( 2 * ari_q1new ) #define ari_q3new ( 3 * ari_q1new ) @@ -1528,6 +1542,7 @@ enum #define SHB_OVERLAP_LEN ( L_FRAME16k - L_SHB_LAHEAD ) / ( NUM_SHB_SUBFR - 1 ) #define QUANT_DIST_INIT ( 10000000000.0f ) /* Quantiser search distance initialisation */ #define HIBND_ACB_L_FAC 5 / 2 /* SHB Interpolation Factor */ +#define HIBND_ACB_L_FAC_Q1 ( 5 ) /* SHB Interpolation Factor Q1 */ #define NUM_HILBERTS 2 #define HILBERT_ORDER1 5 #define HILBERT_ORDER2 4 @@ -1937,8 +1952,7 @@ typedef enum _DCTTYPE #define N_SMC_FEATURES 15 /* number of features */ #define N_SMC_MIXTURES 6 /* number of mixtures */ #define N_PCA_COEF 12 /* number of PCA components */ -#define HALF_N_PCA_COEF_LOG_P12_Q19 5781461//Q19 of (0.5f * N_PCA_COEF *logf( PI2 )) -#define SMC_ST_MEAN_FACT 0.5 /* forgetting factor of short-term IIR mean filter */ +#define HALF_N_PCA_COEF_LOG_P12_Q18 2890731 //Q18 of (0.5f * N_PCA_COEF *logf( PI2 )) #define SMC_ST_MEAN_RSHIFT_FACT_FX 1 /* SMC_ST_MEAN_FACT equivalent right shift factor */ #define M_LSP_SPMUS 6 /* number of LSPs used in speech/music classifier */ @@ -2776,6 +2790,7 @@ enum #define MU_MA_FX 10923 /* original prediction factor for the AMR WB tables (Q15) */ #define E_MIN_FXQ15 115 /* Q15*/ +#define E_MIN_FXQ31 7516193 /* 0.0035d in Q31*/ #define MAX_DYNAMIC_FX (82*128) #define MIN_DYNAMIC_FX (50*128) @@ -3043,6 +3058,8 @@ enum #define EVS_2PI_FX_Q27 843314856 /* 2 * pi in Q28 */ #define EVS_PI_BY_2_FX (Word16)(0x3244) // Q13 //#define EVS_PI_FX (Word16)(0x6488) +#define EVS_PI_FX16 (Word16)(0x6488) +#define PI2_FX 1686629713 //Q28 #define LG10 24660 /* 10*log10(2) in Q13 */ @@ -3056,8 +3073,13 @@ enum #define SYNC_BAD_FRAME (UWord16) 0x6B20 /* synchronization word of a "bad" frame */ #define G192_BIN0 (UWord16) 0x007F /* binary "0" according to ITU-T G.192 */ #define G192_BIN1 (UWord16) 0x0081 /* binary "1" according to ITU-T G.192 */ +#ifdef SPLIT_REND_WITH_HEAD_ROT +#define DEGREE_180 (Word32)(180.0 *ONE_IN_Q22) +#define DEGREE_360 (Word32)(360.0 *ONE_IN_Q22) +#else #define DEGREE_180 (Word32)(180.0 *ONE_IN_Q23) #define DEGREE_360 (Word32)(360.0 *ONE_IN_Q23) +#endif extern const Word16 Idx2Freq_Tbl[]; #define chk_fs(fs) diff --git a/lib_com/codec_tcx_common.c b/lib_com/codec_tcx_common.c index 85e353d597392ef3eee1c7bdb521b4dc803b53ab..1ebc2829c15493506950bd608ca397162826847c 100644 --- a/lib_com/codec_tcx_common.c +++ b/lib_com/codec_tcx_common.c @@ -6,7 +6,6 @@ #include #include #include "options.h" -#include "prot.h" #include "prot_fx.h" #include "basop_util.h" #include "rom_basop_util.h" @@ -40,11 +39,7 @@ Word16 tcxGetNoiseFillingTilt( Copy_Scale_sig( A, As, add( lpcorder, 1 ), sub( norm_s( A[0] ), 2 ) ); // Q(12) tmp = get_gain( As + 1, As, lpcorder ); BASOP_SATURATE_WARNING_OFF_EVS; -#ifdef BASOP_NOGLOB *noiseTiltFactor = add_sat( round_fx_sat( L_shl_sat( tmp, 15 ) ), 3072 /*0.09375f Q15*/ ); -#else - *noiseTiltFactor = add( round_fx( L_shl( tmp, 15 ) ), 3072 /*0.09375f Q15*/ ); -#endif move16(); BASOP_SATURATE_WARNING_ON_EVS; } @@ -144,11 +139,7 @@ void tcxFormantEnhancement( { fac = add( fac0, mult( d, extract_l( L_mult0( j, inv_int[n] ) ) ) ); BASOP_SATURATE_WARNING_OFF_EVS; -#ifdef BASOP_NOGLOB xn_buf[l + j] = s_min( xn_one, shl_o( mult( xn_buf[l + j], fac ), fac_e, &Overflow ) ); -#else - xn_buf[l + j] = s_min( xn_one, shl( mult( xn_buf[l + j], fac ), fac_e ) ); -#endif move16(); BASOP_SATURATE_WARNING_ON_EVS; } @@ -193,11 +184,7 @@ void tcxFormantEnhancement( { fac = add( fac0, mult( d, extract_l( L_mult0( j, inv_int[n] ) ) ) ); BASOP_SATURATE_WARNING_OFF_EVS; -#ifdef BASOP_NOGLOB xn_buf[l + j] = s_min( xn_one, shl_sat( mult( xn_buf[l + j], fac ), fac_e ) ); -#else - xn_buf[l + j] = s_min( xn_one, shl( mult( xn_buf[l + j], fac ), fac_e ) ); -#endif move16(); BASOP_SATURATE_WARNING_ON_EVS; } @@ -322,11 +309,7 @@ void tcxFormantEnhancement_with_shift( { fac = add( fac0, mult( d, extract_l( L_mult0( j, inv_int[n] ) ) ) ); BASOP_SATURATE_WARNING_OFF_EVS; -#ifdef BASOP_NOGLOB xn_buf[l + j] = s_min( xn_one, shl_o( mult( xn_buf[l + j], fac ), fac_e, &Overflow ) ); -#else - xn_buf[l + j] = s_min( xn_one, shl( mult( xn_buf[l + j], fac ), fac_e ) ); -#endif move16(); BASOP_SATURATE_WARNING_ON_EVS; } @@ -371,11 +354,7 @@ void tcxFormantEnhancement_with_shift( { fac = add( fac0, mult( d, extract_l( L_mult0( j, inv_int[n] ) ) ) ); BASOP_SATURATE_WARNING_OFF_EVS; -#ifdef BASOP_NOGLOB xn_buf[l + j] = s_min( xn_one, shl_o( mult( xn_buf[l + j], fac ), fac_e, &Overflow ) ); -#else - xn_buf[l + j] = s_min( xn_one, shl( mult( xn_buf[l + j], fac ), fac_e ) ); -#endif move16(); BASOP_SATURATE_WARNING_ON_EVS; } diff --git a/lib_com/common_api_types.h b/lib_com/common_api_types.h index b98f2e7d177c5b2965d400febaaa63732e89341a..3200cb21d4929ea492d2c18741d1af3c36e96296 100644 --- a/lib_com/common_api_types.h +++ b/lib_com/common_api_types.h @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other @@ -59,6 +59,12 @@ #define IVAS_MAX_PARAM_SPATIAL_SUBFRAMES 4 #define IVAS_ROOM_ABS_COEFF 6 +/* Maximum buffer length (per channel) in samples */ +#define MAX_BUFFER_LENGTH_PER_CHANNEL ( L_FRAME48k ) + +/* Frame size required when rendering to binaural */ +#define BINAURAL_RENDERING_FRAME_SIZE_MS 5 + /*----------------------------------------------------------------------------------* * Common API enum for output audio configurations *----------------------------------------------------------------------------------*/ @@ -108,9 +114,9 @@ typedef enum _IVAS_ENC_FEC_INDICATOR typedef struct _IVAS_ENC_CHANNEL_AWARE_CONFIG { - int16_t channelAwareModeEnabled; + Word16 channelAwareModeEnabled; IVAS_ENC_FEC_INDICATOR fec_indicator; - int16_t fec_offset; + Word16 fec_offset; } IVAS_ENC_CHANNEL_AWARE_CONFIG; @@ -130,13 +136,13 @@ typedef struct _IVAS_ISM_METADATA float gainFactor; float yaw; float pitch; - int16_t non_diegetic_flag; + Word16 non_diegetic_flag; } IVAS_ISM_METADATA; typedef struct { - float w, x, y, z; + // float w, x, y, z; Word32 w_fx, x_fx, y_fx, z_fx; Word16 q_fact; @@ -183,42 +189,141 @@ typedef struct ivas_LS_setup_custom IVAS_LSSETUP_CUSTOM_STRUCT; typedef struct _IVAS_LS_CUSTOM_LAYOUT { - int16_t num_spk; + Word16 num_spk; float azimuth[IVAS_MAX_OUTPUT_CHANNELS]; float elevation[IVAS_MAX_OUTPUT_CHANNELS]; Word32 azimuth_fx[IVAS_MAX_OUTPUT_CHANNELS]; // Q22 Word32 elevation_fx[IVAS_MAX_OUTPUT_CHANNELS]; // Q22 - int16_t num_lfe; - int16_t lfe_idx[IVAS_MAX_OUTPUT_CHANNELS]; + Word16 num_lfe; + Word16 lfe_idx[IVAS_MAX_OUTPUT_CHANNELS]; } IVAS_CUSTOM_LS_DATA; typedef struct _IVAS_JBM_TRACE_DATA { - uint32_t systemTimestamp_ms; - uint16_t extBufferedSamples; - uint16_t lastDecodedWasActive; - int32_t output_Fs; - int16_t dataUnit_flag; - uint16_t sequenceNumber; - uint32_t timeStamp; - uint32_t rcvTime; - - int16_t partial_frame; - int16_t partialCopyOffset; + UWord32 systemTimestamp_ms; + UWord16 extBufferedSamples; + UWord16 lastDecodedWasActive; + Word32 output_Fs; + Word16 dataUnit_flag; + UWord16 sequenceNumber; + UWord32 timeStamp; + UWord32 rcvTime; + + Word16 partial_frame; + Word16 partialCopyOffset; } IVAS_JBM_TRACE_DATA; +#ifdef SPLIT_REND_WITH_HEAD_ROT +/*----------------------------------------------------------------------------------* + * Split rendering API constants, structures, and enums + *----------------------------------------------------------------------------------*/ + +#define ISAR_MAX_SPLIT_REND_BITRATE 768000 +#define ISAR_MAX_SPLIT_REND_BITS_BUFFER_SIZE_IN_BYTES ( ( ( (int32_t) ISAR_MAX_SPLIT_REND_BITRATE / IVAS_NUM_FRAMES_PER_SEC ) + 7 ) >> 3 ) +#define ISAR_SPLIT_REND_ADDITIONAL_BYTES_TO_READ 1 +#define SPLIT_REND_BITS_BUFF_SIZE ( ISAR_MAX_SPLIT_REND_BITS_BUFFER_SIZE_IN_BYTES + ISAR_SPLIT_REND_ADDITIONAL_BYTES_TO_READ ) + +typedef enum +{ + DEFAULT_AXIS, + YAW, + PITCH, + ROLL, + YAW_PITCH, + YAW_ROLL, + PITCH_ROLL + +} ISAR_SPLIT_REND_ROT_AXIS; + +typedef enum +{ + ISAR_SPLIT_REND_POSE_CORRECTION_MODE_NONE, + ISAR_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB, + +} ISAR_SPLIT_REND_POSE_CORRECTION_MODE; + +typedef enum +{ + ISAR_SPLIT_REND_CODEC_LCLD, + ISAR_SPLIT_REND_CODEC_LC3PLUS, + ISAR_SPLIT_REND_CODEC_DEFAULT, /* Will use LCLD for CLDFB rendering paths and LC3plus for TD rendering paths */ + ISAR_SPLIT_REND_CODEC_NONE + +} ISAR_SPLIT_REND_CODEC; + +typedef enum +{ + ISAR_SPLIT_REND_RENDERER_SELECTION_CREND, + ISAR_SPLIT_REND_RENDERER_SELECTION_FASTCONV, + ISAR_SPLIT_REND_RENDERER_SELECTION_PARAMBIN, + ISAR_SPLIT_REND_RENDERER_SELECTION_TDREND, + ISAR_SPLIT_REND_RENDERER_SELECTION_DEFAULT, + +} ISAR_SPLIT_REND_RENDERER_SELECTION; + +typedef struct _ISAR_SPLIT_REND_BITS_DATA +{ + uint8_t *bits_buf; + int32_t buf_len; /*size of bits_buf in bytes. This field should be set by allocator of bits_buf*/ + int32_t bits_written; + int32_t bits_read; + int16_t codec_frame_size_ms; + ISAR_SPLIT_REND_CODEC codec; + ISAR_SPLIT_REND_POSE_CORRECTION_MODE pose_correction; +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + int16_t isar_frame_size_ms; + int16_t lc3plus_highres; +#endif + +} ISAR_SPLIT_REND_BITS_DATA, *ISAR_SPLIT_REND_BITS_HANDLE; + +typedef struct _ISAR_SPLIT_REND_CONFIG +{ + int32_t splitRendBitRate; /*Bit rate for split rendering mode, if "pcm_out" is set then "splitRendBitRate" is used as a limit for MD bitrate */ + int16_t hq_mode; /*High quality 3DOF mode with additional side information. Requires more pre-renditions. */ + int16_t dof; /*flag to specify if pose correction is needed for 1, 2 or 3 degree of freedoms*/ + /*The axis can be set dynamically per frame based on a file input */ + /*possible values: + 1 - (1dof correction. By default YAW correction) + 2 - (2dof correction. By default YAW and PITCH correction) + 3 - (3dof correction. By default YAW, PITCH and ROLL correction) + */ + int16_t codec_delay_ms; /*PLACEHOLDER (currently being ignored) : look ahead delay of the codec that is used to code BIN signal output of pre-renderer*/ +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + int16_t isar_frame_size_ms; /* ISAR bit stream frame size in milliseconds */ +#endif + int16_t codec_frame_size_ms; /* Codec frame size in milliseconds, only relevant with LC3plus */ + ISAR_SPLIT_REND_POSE_CORRECTION_MODE poseCorrectionMode; + ISAR_SPLIT_REND_CODEC codec; + ISAR_SPLIT_REND_RENDERER_SELECTION rendererSelection; +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + int16_t lc3plus_highres; +#endif + +} ISAR_SPLIT_REND_CONFIG_DATA, *ISAR_SPLIT_REND_CONFIG_HANDLE; +#endif + /*----------------------------------------------------------------------------------* * Renderer API structures and enums *----------------------------------------------------------------------------------*/ +#ifdef DEBUGGING +typedef enum +{ + IVAS_RENDER_TYPE_OVERRIDE_NONE, + IVAS_RENDER_TYPE_OVERRIDE_CREND, + IVAS_RENDER_TYPE_OVERRIDE_FASTCONV + +} IVAS_RENDER_TYPE_OVERRIDE; +#endif typedef struct _IVAS_ROOM_ACOUSTICS_CONFIG { - int16_t override; - int16_t nBands; /* Number of frequency bands for which reverb properties are provided, integer, range [2..256] */ + Word16 override; + Word16 nBands; /* Number of frequency bands for which reverb properties are provided, integer, range [2..256] */ float pFc_input[IVAS_CLDFB_NO_CHANNELS_MAX]; /* Center frequencies for which following values are provided: */ float pAcoustic_rt60[IVAS_CLDFB_NO_CHANNELS_MAX]; /* - The room's T60 per center frequency */ float pAcoustic_dsr[IVAS_CLDFB_NO_CHANNELS_MAX]; /* - The room's Diffuse to Source Ratio per center frequency */ @@ -231,21 +336,44 @@ typedef struct _IVAS_ROOM_ACOUSTICS_CONFIG Word32 inputPreDelay_fx; /* Offset in seconds from where DSR is computed in the RIR (0 = at source), float, range [0.001..10] */ /* Assumed Q-27*/ /* early reflections */ - int16_t use_er; /* ER activation flag */ - int32_t lowComplexity; /* Low complexity ER flag */ - IVAS_VECTOR3 dimensions; /* Room dimensions [m] */ - float AbsCoeff[IVAS_ROOM_ABS_COEFF]; /* Absorption coeffs */ - IVAS_VECTOR3 ListenerOrigin; /* Listener origin */ - int32_t AbsCoeff_fx[IVAS_ROOM_ABS_COEFF]; /* Absorption coeffs */ + Word16 use_er; /* ER activation flag */ + Word32 lowComplexity; /* Low complexity ER flag */ + IVAS_VECTOR3 dimensions; /* Room dimensions [m] */ + float AbsCoeff[IVAS_ROOM_ABS_COEFF]; /* Absorption coeffs */ + IVAS_VECTOR3 ListenerOrigin; /* Listener origin */ + Word32 AbsCoeff_fx[IVAS_ROOM_ABS_COEFF]; /* Absorption coeffs */ } IVAS_ROOM_ACOUSTICS_CONFIG_DATA; typedef struct _IVAS_RENDER_CONFIG { +#ifdef DEBUGGING + IVAS_RENDER_TYPE_OVERRIDE renderer_type_override; +#endif IVAS_ROOM_ACOUSTICS_CONFIG_DATA roomAcoustics; +#ifdef SPLIT_REND_WITH_HEAD_ROT + ISAR_SPLIT_REND_CONFIG_DATA split_rend_config; +#endif float directivity[IVAS_MAX_NUM_OBJECTS * 3]; Word16 directivity_fx[IVAS_MAX_NUM_OBJECTS * 3]; // has the following q-factor pattern: {6, 6, 15, 6, 6, 15, 6, 6, 15, 6, 6, 15} } IVAS_RENDER_CONFIG_DATA, *IVAS_RENDER_CONFIG_HANDLE; +typedef struct +{ + int16_t numSamplesPerChannel; + int16_t numChannels; +#ifdef SPLIT_REND_WITH_HEAD_ROT + int16_t is_cldfb; +#endif +} IVAS_REND_AudioBufferConfig; + +typedef struct +{ + IVAS_REND_AudioBufferConfig config; + Word16 q_factor; + Word16 *pq_fact; + Word32 *data_fx; + // Word16 Q_data; +} IVAS_REND_AudioBuffer; #endif /* COMMON_API_TYPES_H */ diff --git a/lib_com/core_com_config.c b/lib_com/core_com_config.c index e002617ab708ee75c42c0b8925cc424d9ff8ada5..f0ee8efd8d12c038c78487a8f39ba71dc21a3b9c 100644 --- a/lib_com/core_com_config.c +++ b/lib_com/core_com_config.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other @@ -38,10 +38,8 @@ #include #include "options.h" #include "rom_com.h" -#include "prot.h" -#include "wmc_auto.h" -#include "ivas_prot.h" #include "prot_fx.h" +#include "wmc_auto.h" #include "ivas_prot_fx.h" #define FSCALE_DENOM_BY_12800_Q15 1311 @@ -551,63 +549,6 @@ int16_t sr2fscale( return (int16_t) ( ( FSCALE_DENOM * sr_core ) / 12800 ); } -/*-------------------------------------------------------------------* - * getCoreSamplerateMode2_flt() - * - * - *-------------------------------------------------------------------*/ - -int32_t getCoreSamplerateMode2_flt( - const int16_t element_mode, /* i : IVAS element mode */ - const int32_t total_brate, /* i : total bitrate */ - const int16_t bwidth, /* i : audio bandwidth */ - const int16_t flag_ACELP16k, /* i : ACELP@16kHz flag */ - const int16_t rf_mode, /* i : flag to signal the RF mode */ - const IVAS_FORMAT is_ism_format /* i : flag indicating ISM format */ -) -{ - int32_t sr_core = 0; - - if ( bwidth == NB ) - { - sr_core = INT_FS_12k8; - } - else if ( element_mode == EVS_MONO && ( ( bwidth == WB && total_brate < ACELP_13k20 ) || ( bwidth == SWB && total_brate <= ACELP_13k20 ) || ( rf_mode == 1 ) ) ) - { - sr_core = INT_FS_12k8; - } - else if ( element_mode > EVS_MONO && flag_ACELP16k == 0 ) - { - sr_core = INT_FS_12k8; - } - else if ( bwidth == WB || ( bwidth == SWB && total_brate <= ACELP_32k ) || ( bwidth == FB && total_brate <= ACELP_32k ) ) - { - sr_core = INT_FS_16k; - } - else if ( ( bwidth == SWB || bwidth == FB ) && total_brate <= MAX_ACELP_BRATE && element_mode == IVAS_SCE && !is_ism_format ) - { - sr_core = INT_FS_16k; - } - else if ( ( bwidth == SWB || bwidth == FB ) && total_brate <= MAX_ACELP_BRATE_ISM && element_mode == IVAS_SCE && is_ism_format ) - { - sr_core = INT_FS_16k; - } - else if ( ( bwidth == SWB || bwidth == FB ) && total_brate <= MAX_ACELP_BRATE && element_mode == IVAS_SCE && is_ism_format ) - { - sr_core = 25600; - } - else if ( ( ( bwidth == SWB || bwidth == FB ) && element_mode == EVS_MONO && total_brate <= HQ_64k ) || ( element_mode > IVAS_SCE && ( ( bwidth == SWB && total_brate <= IVAS_96k ) || ( bwidth == FB && total_brate <= IVAS_96k ) ) ) ) - { - sr_core = 25600; - } - else if ( bwidth == SWB || bwidth == FB ) - { - sr_core = 32000; - } - - return sr_core; -} - Word32 getCoreSamplerateMode2( const Word16 element_mode, /* i : IVAS element mode Q0*/ const Word32 total_brate, /* i : total bitrate Q0*/ @@ -1235,8 +1176,8 @@ void init_tcx_window_cfg_fx( } /*Mid-OLA*/ /*compute minimum length for "half" window: lookahead - 5ms. It must be also multiple of 2*/ - hTcxCfg->tcx_mdct_window_half_length = extract_l( L_shr( L_mult0( L_LOOK_12k8 - NS2SA_FX2( 12800, 5000000L ), sr2fscale( sr_core ) ), LD_FSCALE_DENOM ) ); /*Q0*/ - hTcxCfg->tcx_mdct_window_half_lengthFB = extract_l( L_shr( L_mult0( L_LOOK_12k8 - NS2SA_FX2( 12800, 5000000L ), sr2fscale( input_Fs ) ), LD_FSCALE_DENOM ) ); /*Q0*/ + hTcxCfg->tcx_mdct_window_half_length = extract_l( L_shr( L_mult0( L_LOOK_12k8 - NS2SA( 12800, 5000000L ), sr2fscale( sr_core ) ), LD_FSCALE_DENOM ) ); /*Q0*/ + hTcxCfg->tcx_mdct_window_half_lengthFB = extract_l( L_shr( L_mult0( L_LOOK_12k8 - NS2SA( 12800, 5000000L ), sr2fscale( input_Fs ) ), LD_FSCALE_DENOM ) ); /*Q0*/ move16(); move16(); assert( GT_16( hTcxCfg->tcx_mdct_window_half_length, 16 ) && "Half window can not be large enough!" ); diff --git a/lib_com/deemph.c b/lib_com/deemph.c index 3f60bf44c1128c4812b7e266914009f5f2d05ee0..c03a050bca095711ea2e0c6a07e721aeb29e1dbf 100644 --- a/lib_com/deemph.c +++ b/lib_com/deemph.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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,9 +36,8 @@ #include #include "options.h" -#include "prot.h" -#include "wmc_auto.h" #include "prot_fx.h" +#include "wmc_auto.h" void deemph_fx_32( @@ -103,26 +102,16 @@ void deemph_fx( move32(); #endif - L_tmp = L_deposit_h( signal[0] ); /*Qx+16*/ -#ifdef BASOP_NOGLOB + L_tmp = L_deposit_h( signal[0] ); /*Qx+16*/ L_tmp = L_mac_o( L_tmp, *mem, mu, &Overflow ); /*Qx+16*/ signal[0] = round_fx_o( L_tmp, &Overflow ); /*Qx*/ -#else - L_tmp = L_mac( L_tmp, *mem, mu ); - signal[0] = round_fx( L_tmp ); -#endif move16(); FOR( i = 1; i < L; i++ ) { - L_tmp = L_deposit_h( signal[i] ); /*Qx+16*/ -#ifdef BASOP_NOGLOB + L_tmp = L_deposit_h( signal[i] ); /*Qx+16*/ L_tmp = L_mac_o( L_tmp, signal[i - 1], mu, &Overflow ); /*Qx+16*/ signal[i] = round_fx_o( L_tmp, &Overflow ); /*Qx*/ -#else /* BASOP_NOGLOB */ - L_tmp = L_mac( L_tmp, signal[i - 1], mu ); - signal[i] = round_fx( L_tmp ); -#endif /* BASOP_NOGLOB */ move16(); } @@ -158,12 +147,8 @@ void Deemph2( FOR( i = 1; i < L; i++ ) { - L_tmp = L_mult( x[i], 16384 /*0.5f in Q15*/ ); /*Qx+16*/ -#ifdef BASOP_NOGLOB + L_tmp = L_mult( x[i], 16384 /*0.5f in Q15*/ ); /*Qx+16*/ x[i] = mac_ro( L_tmp, x[i - 1], mu, &Overflow ); /*Qx-1*/ -#else - x[i] = mac_r( L_tmp, x[i - 1], mu ); -#endif move16(); } @@ -206,13 +191,8 @@ void E_UTIL_deemph2( Word16 shift, Word16 *x, const Word16 mu, const Word16 L, W shift = shr( -32768, shift ); /*Q15 - shift*/ FOR( i = 0; i < L; i++ ) { -#ifdef BASOP_NOGLOB L_tmp = L_msu_o( Mpy_32_16_1( L_tmp, mu ), x[i], shift, &Overflow ); /*Qx-shift+16*/ x[i] = round_fx_o( L_tmp, &Overflow ); /*Qx-shift*/ -#else - L_tmp = L_msu( Mpy_32_16_1( L_tmp, mu ), x[i], shift ); - x[i] = round_fx( L_tmp ); -#endif move16(); } } @@ -220,13 +200,8 @@ void E_UTIL_deemph2( Word16 shift, Word16 *x, const Word16 mu, const Word16 L, W { FOR( i = 0; i < L; i++ ) { -#ifdef BASOP_NOGLOB L_tmp = L_msu_o( Mpy_32_16_1( L_tmp, mu ), shr_o( x[i], shift, &Overflow ), -32768 /*1.0f in Q15*/, &Overflow ); /*Qx-shift+16*/ x[i] = round_fx_o( L_tmp, &Overflow ); /*Qx-shift*/ -#else /* BASOP_NOGLOB */ - L_tmp = L_msu( Mpy_32_16_1( L_tmp, mu ), shr( x[i], shift ), -32768 ); - x[i] = round_fx( L_tmp ); -#endif move16(); } } diff --git a/lib_com/delay_comp.c b/lib_com/delay_comp.c index 38a077f9ea1365b8ede42afc988c7f4f99728d1a..0398eb671a638c4c81a91908908983e17b8cbced 100644 --- a/lib_com/delay_comp.c +++ b/lib_com/delay_comp.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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,10 +36,9 @@ #include #include "options.h" -#include "prot.h" +#include "prot_fx.h" #include "ivas_cnst.h" #include "wmc_auto.h" -#include "prot_fx.h" /*-------------------------------------------------------------------------- * get_delay() @@ -110,7 +109,7 @@ Word32 get_delay_fx( /* o : delay value in ms #ifdef SPLIT_REND_WITH_HEAD_ROT - IF( NE_16( output_config, AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) ) + IF( NE_16( output_config, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) ) { #endif if ( hCldfb != NULL ) diff --git a/lib_com/disclaimer.c b/lib_com/disclaimer.c index 58452de2447869a116d61e533e9e34f78194e82a..1a01c2c320d249726ccf142ca9a0390f2846ac24 100644 --- a/lib_com/disclaimer.c +++ b/lib_com/disclaimer.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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,7 +36,7 @@ #include #include "options.h" -#include "prot.h" +#include "prot_fx.h" #define WMC_TOOL_SKIP @@ -44,7 +44,11 @@ int16_t print_disclaimer( FILE *fPtr ) { fprintf( fPtr, "\n==================================================================================================\n" ); +#ifdef FIX_DISCLAIMER + fprintf( fPtr, " IVAS Codec BASOP Baseline\n" ); +#else fprintf( fPtr, " IVAS Codec Baseline\n" ); +#endif fprintf( fPtr, " \n" ); fprintf( fPtr, " Based on EVS Codec (Floating Point) 3GPP TS26.443 Nov 04, 2021,\n" ); fprintf( fPtr, " Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0\n" ); diff --git a/lib_com/edct_fx.c b/lib_com/edct_fx.c index 28a5ed44adb89fe0d83c735cf750ce43c3ea0fc3..b1e2a7dd9b76719cec5ef06815655c249d617237 100644 --- a/lib_com/edct_fx.c +++ b/lib_com/edct_fx.c @@ -228,6 +228,67 @@ void edct_fx( return; } +void edct_ivas_fx( + const Word32 *x, /* i : input signal Qq */ + Word32 *y, /* o : output transform Qq */ + Word16 length, /* i : length Q0*/ + Word16 *q /* i : Q value of input signal */ +) +{ + Word16 i; + const Word16 *edct_table; /*Q16 */ + Word32 re[L_FRAME_PLUS / 2]; + Word32 im[L_FRAME_PLUS / 2]; + Word32 L_tmp; + Word16 tmp; + Word16 len1; + + edct_table = get_edct_table( length, q ); /*q*/ + len1 = shr( length, 1 ); /*Q0*/ + /* Twiddling and Pre-rotate */ + FOR( i = 0; i < len1; i++ ) + { + L_tmp = Mult_32_16( x[2 * i], edct_table[i] ); /*Q(q+1) */ + re[i] = Madd_32_16( L_tmp, x[( length - ( 1 + ( i * 2 ) ) )], edct_table[( len1 - ( 1 + i ) )] ); /*Q(q+1) */ + move32(); + + L_tmp = Mult_32_16( x[( length - ( 1 + ( i * 2 ) ) )], edct_table[i] ); /*Q(q+1) */ + im[i] = Msub_32_16( L_tmp, x[( i * 2 )], edct_table[( len1 - ( 1 + i ) )] ); /*Q(q+1) */ + move32(); + } + + *q = sub( 31, *q ); + move16(); + tmp = sub( s_min( getScaleFactor32( re, len1 ), getScaleFactor32( im, len1 ) ), find_guarded_bits_fx( len1 ) ); + scale_sig32( re, len1, tmp ); + scale_sig32( im, len1, tmp ); + + fft_fx( re, im, len1, 1 ); + *q = sub( *q, tmp ); + move16(); + + tmp = div_s( 4, length ); /*Q17 */ + tmp = round_fx( L_mult( tmp, 19302 /*0.75f * EVS_PI in Q13*/ ) ); /*Q15 */ + FOR( i = 0; i < len1; i++ ) + { + L_tmp = Msub_32_16( re[i], im[i], tmp ); + im[i] = Madd_32_16( im[i], re[i], tmp ); /*Q(q+1) */ + re[i] = L_tmp; /*Q(q+1) */ + move32(); + move32(); + } + FOR( i = 0; i < len1; i++ ) + { + y[2 * i] = L_add( Mult_32_16( re[i], edct_table[i] ), Mult_32_16( im[i], edct_table[( len1 - ( 1 + i ) )] ) ); /*Q(q+2)*/ + move32(); + y[( length - ( 1 + ( i * 2 ) ) )] = L_sub( Mult_32_16( re[i], edct_table[( len1 - ( 1 + i ) )] ), Mult_32_16( im[i], edct_table[i] ) ); /*Q(q+2)*/ + move32(); + } /*Q(q-2) */ + + *q = sub( 31 + 2, *q ); + move16(); + return; +} /*-------------------------------------------------------------------------* * FUNCTION : edst_fx() * @@ -396,23 +457,13 @@ void edct_16fx( { i2 = shl( i, 1 ); - L_tmp = L_mult( x[i2], edct_table[i] ); /*Q(Qx+16) */ -#ifdef BASOP_NOGLOB + L_tmp = L_mult( x[i2], edct_table[i] ); /*Q(Qx+16) */ Lacc = L_mac_o( L_tmp, *px, *pt, &Overflow ); /*Q(Qx+16) */ re2[i] = round_fx_o( L_shl_o( Lacc, Q_edct, &Overflow ), &Overflow ); /* Q(Qx+Q_edct) */ -#else - Lacc = L_mac( L_tmp, *px, *pt ); /*Q(Qx+16) */ - re2[i] = round_fx( L_shl( Lacc, Q_edct ) ); /* Q(Qx+Q_edct) */ -#endif move16(); - L_tmp = L_mult( *px, edct_table[i] ); /*Q(Qx+16) */ -#ifdef BASOP_NOGLOB + L_tmp = L_mult( *px, edct_table[i] ); /*Q(Qx+16) */ Lacc = L_msu_o( L_tmp, x[i2], *pt, &Overflow ); /*Q(Qx+16) */ im2[i] = round_fx_o( L_shl_o( Lacc, Q_edct, &Overflow ), &Overflow ); /* Q(Qx+Q_edct) */ -#else - Lacc = L_msu( L_tmp, x[i2], *pt ); /*Q(Qx+16) */ - im2[i] = round_fx( L_shl( Lacc, Q_edct ) ); /* Q(Qx+Q_edct) */ -#endif move16(); px -= 2; pt--; @@ -437,23 +488,13 @@ void edct_16fx( fact = round_fx( L_shl( L_tmp, 2 ) ); /*Q15 */ FOR( i = 0; i < shr( length, 1 ); i++ ) { - tmp = mult_r( im2[i], fact ); /*Q(Qx+Q_edct) */ -#ifdef BASOP_NOGLOB + tmp = mult_r( im2[i], fact ); /*Q(Qx+Q_edct) */ re[i] = sub_o( re2[i], tmp, &Overflow ); /*Q(Qx+Q_edct) */ move16(); -#else - re[i] = sub( re2[i], tmp ); /*Q(Qx+Q_edct) */ - move16(); -#endif - tmp = mult_r( re2[i], fact ); /*Q(Qx+Q_edct) */ -#ifdef BASOP_NOGLOB + tmp = mult_r( re2[i], fact ); /*Q(Qx+Q_edct) */ im[i] = add_o( im2[i], tmp, &Overflow ); /*Q(Qx+Q_edct) */ move16(); -#else - im[i] = add( im2[i], tmp ); /*Q(Qx+Q_edct) */ - move16(); -#endif } /* Post-rotate and obtain the output data */ @@ -463,23 +504,14 @@ void edct_16fx( { i2 = shl( i, 1 ); - L_tmp = L_mult( re[i], edct_table[i] ); /*Q(Qx+Q_edct+16) */ -#ifdef BASOP_NOGLOB + L_tmp = L_mult( re[i], edct_table[i] ); /*Q(Qx+Q_edct+16) */ Lacc = L_mac_o( L_tmp, im[i], *pt, &Overflow ); /*Q(Qx+Q_edct+16) */ y[i2] = round_fx_o( L_shr_o( Lacc, Q_edct, &Overflow ), &Overflow ); /* Q(Qx) */ -#else /* BASOP_NOGLOB */ - Lacc = L_mac( L_tmp, im[i], *pt ); /*Q(Qx+Q_edct+16) */ - y[i2] = round_fx( L_shr( Lacc, Q_edct ) ); /* Q(Qx) */ -#endif /* BASOP_NOGLOB */ move16(); L_tmp = L_mult( re[i], edct_table[sub( shr( length, 1 ), add( 1, i ) )] ); /*Q(Qx+Q_edct+16) */ Lacc = L_msu( L_tmp, im[i], edct_table[i] ); /*Q(Qx+Q_edct+16) */ -#ifdef BASOP_NOGLOB - *py = round_fx_o( L_shr_o( Lacc, Q_edct, &Overflow ), &Overflow ); /* Q(Qx) */ -#else /* BASOP_NOGLOB */ - *py = round_fx( L_shr( Lacc, Q_edct ) ); /* Q(Qx) */ -#endif + *py = round_fx_o( L_shr_o( Lacc, Q_edct, &Overflow ), &Overflow ); /* Q(Qx) */ move16(); py -= 2; @@ -560,11 +592,12 @@ void edxt_fx( const UWord16 synthesis /* i : nonzero for inverse Q0*/ ) { - Word16 k, m, fac; + Word16 k, m, fac, hdrm, tmp = 0; const Word16 *cosPtr, *sinPtr; Word16 n; n = 0; move16(); + move16(); cosPtr = NULL; sinPtr = NULL; IF( EQ_16( length, 512 ) ) @@ -703,7 +736,23 @@ void edxt_fx( IF( EQ_16( length, 512 ) ) { + /* Scaling down re and im buffers to avoid overflow in DoRTFTn_fx if the minimum headroom is less than 4 bits */ + hdrm = s_min( L_norm_arr( re, 512 ), L_norm_arr( im, 512 ) ); + IF( LT_16( hdrm, 4 ) ) + { + tmp = sub( hdrm, 4 ); + scale_sig32( re, 512, tmp ); + scale_sig32( im, 512, tmp ); + } + DoRTFTn_fx( re, im, 512 ); + + IF( LT_16( hdrm, 4 ) ) + { + tmp = negate( tmp ); + scale_sig32( re, 512, tmp ); + scale_sig32( im, 512, tmp ); + } } ELSE /* fft() doesn't support 512 */ { @@ -799,7 +848,23 @@ void edxt_fx( IF( EQ_16( length, 512 ) ) { + /* Scaling down re and im buffers to avoid overflow in DoRTFTn_fx if the minimum headroom is less than 4 bits */ + hdrm = s_min( L_norm_arr( re, 512 ), L_norm_arr( im, 512 ) ); + IF( LT_16( hdrm, 4 ) ) + { + tmp = sub( hdrm, 4 ); + scale_sig32( re, 512, tmp ); + scale_sig32( im, 512, tmp ); + } + DoRTFTn_fx( re, im, 512 ); + + IF( LT_16( hdrm, 4 ) ) + { + tmp = negate( tmp ); + scale_sig32( re, 512, tmp ); + scale_sig32( im, 512, tmp ); + } } ELSE /* fft() doesn't support 512 */ { diff --git a/lib_com/enh1632.c b/lib_com/enh1632.c index 04c22ae97c40afa265e386e9fc2f3e268ef10795..f397c3432b9dc63b6a376cfb394e3efb50a82bc0 100644 --- a/lib_com/enh1632.c +++ b/lib_com/enh1632.c @@ -376,21 +376,13 @@ Word32 L_lshr( Word32 L_var1, Word16 var2 ) * the range : 0xffff 8000 <= var_out <= 0x0000 7fff. * *****************************************************************************/ -#ifdef BASOP_NOGLOB Word16 shl_ro( Word16 var1, Word16 var2, Flag *Overflow ) -#else -Word16 shl_r( Word16 var1, Word16 var2 ) -#endif { Word16 var_out; if ( var2 >= 0 ) { -#ifdef BASOP_NOGLOB var_out = shl_o( var1, var2, Overflow ); -#else - var_out = shl( var1, var2 ); -#endif #ifdef WMOPS multiCounter[currCounter].shl--; #endif /* ifdef WMOPS */ @@ -398,11 +390,7 @@ Word16 shl_r( Word16 var1, Word16 var2 ) else { var2 = -var2; -#ifdef BASOP_NOGLOB var_out = shr_ro( var1, var2, Overflow ); -#else - var_out = shr_r( var1, var2 ); -#endif #ifdef WMOPS multiCounter[currCounter].shr_r--; #endif /* ifdef WMOPS */ @@ -414,12 +402,10 @@ Word16 shl_r( Word16 var1, Word16 var2 ) return ( var_out ); } -#ifdef BASOP_NOGLOB Word16 shl_r( Word16 var1, Word16 var2 ) { return shl_ro( var1, var2, NULL ); } -#endif /***************************************************************************** * * Function Name : L_shl_r @@ -630,6 +616,27 @@ Word32 L_rotr( Word32 L_var1, Word16 var2, Word16 *var3 ) } +int16_t norm_ul( uint32_t UL_var1 ) +{ + int16_t var_out; + + if ( UL_var1 == 0 ) + { + var_out = 0; + } + else + { + for ( var_out = 0; UL_var1 < (uint32_t) 0x80000000U; var_out++ ) + { + UL_var1 <<= 1; + } + } + BASOP_CHECK(); + + return ( var_out ); +} + + /***************************************************************************** * * Function Name : L_rotl diff --git a/lib_com/enh1632.h b/lib_com/enh1632.h index eed55ccad44963372710d7919bbb3e9f13eed012..f91494fb137d799d461cca6afa5bbfa5b160ba39 100644 --- a/lib_com/enh1632.h +++ b/lib_com/enh1632.h @@ -40,9 +40,7 @@ * Prototypes for enhanced 16/32 bit arithmetic operators * *****************************************************************************/ -#ifdef BASOP_NOGLOB Word16 shl_ro( Word16 var1, Word16 var2, Flag *Overflow ); -#endif Word16 shl_r( Word16 var1, Word16 var2 ); Word32 L_shl_r( Word32 L_var1, Word16 var2 ); @@ -57,6 +55,7 @@ Word16 rotl( Word16 var1, Word16 var2, Word16 *var3 ); Word32 L_rotr( Word32 var1, Word16 var2, Word16 *var3 ); Word32 L_rotl( Word32 var1, Word16 var2, Word16 *var3 ); +Word16 norm_ul( UWord32 UL_var1 ); /***************************************************************************** * diff --git a/lib_com/enh32.c b/lib_com/enh32.c index 64afe89869987ec7073e0cdef0dfe2965f57926f..cf40bbec972f96c6858e957dfe8509f9907b4e40 100644 --- a/lib_com/enh32.c +++ b/lib_com/enh32.c @@ -76,11 +76,7 @@ Word32 Mpy_32_32( Word32 L_var1, Word32 L_var2 ) #endif L64_var1 = ( (Word64) L_var1 * L_var2 ); -#ifdef BASOP_NOGLOB L64_var1 = W_shl_o( L64_var1, 1, &Overflow ); -#else /* BASOP_NOGLOB */ - L64_var1 = W_shl( L64_var1, 1 ); -#endif /* BASOP_NOGLOB */ L_var_out = W_extract_h( L64_var1 ); #ifdef WMOPS multiCounter[currCounter].Mpy_32_32++; @@ -114,11 +110,7 @@ Word32 Madd_32_16( Word32 L_var3, Word32 L_var1, Word16 var2 ) #endif L_var_out = Mpy_32_16_1( L_var1, var2 ); -#ifdef BASOP_NOGLOB L_var_out = L_add_o( L_var3, L_var_out, &Overflow ); -#else /* BASOP_NOGLOB */ - L_var_out = L_add( L_var3, L_var_out ); -#endif /* BASOP_NOGLOB */ #ifdef WMOPS multiCounter[currCounter].Mpy_32_16_1--; @@ -151,11 +143,7 @@ Word32 Msub_32_16( Word32 L_var3, Word32 L_var1, Word16 var2 ) #endif L_var_out = Mpy_32_16_1( L_var1, var2 ); -#ifdef BASOP_NOGLOB L_var_out = L_sub_o( L_var3, L_var_out, &Overflow ); -#else /* BASOP_NOGLOB */ - L_var_out = L_sub( L_var3, L_var_out ); -#endif #ifdef WMOPS multiCounter[currCounter].Mpy_32_16_1--; diff --git a/lib_com/enh40.c b/lib_com/enh40.c index 929e3a950652d6fd12162aadbaa2e7a3c2ffdb57..570f4b211ab675c8fd924a2b0d4786ddec25c679 100644 --- a/lib_com/enh40.c +++ b/lib_com/enh40.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other @@ -96,9 +96,7 @@ #include #include #include "stl.h" -#ifdef BASOP_NOGLOB #include -#endif /* BASOP_NOGLOB */ #define WMC_TOOL_SKIP @@ -160,11 +158,7 @@ * the range : MIN_40 <= L40_var_out <= MAX_40. * *****************************************************************************/ -#ifndef BASOP_NOGLOB -Word40 L40_shl( Word40 L40_var1, Word16 var2 ) -#else /* BASOP_NOGLOB */ Word40 L40_shl_o( Word40 L40_var1, Word16 var2, Flag *Overflow ) -#endif /* BASOP_NOGLOB */ { Word40 L40_var_out; @@ -194,27 +188,15 @@ Word40 L40_shl_o( Word40 L40_var1, Word16 var2, Flag *Overflow ) if ( L40_var_out > 0x003fffffffffLL ) #endif { -#ifndef BASOP_NOGLOB - Overflow = 1; - exit( 1 ); - /* L40_var_out = L40_OVERFLOW_OCCURED( L40_var_out); */ -#else /* BASOP_NOGLOB */ *Overflow = 1; L40_var_out = MAX_40; -#endif /* BASOP_NOGLOB */ break; } else if ( L40_var_out < L40_constant ) { -#ifndef BASOP_NOGLOB - Overflow = 1; - exit( 2 ); - /* L40_var_out = L40_UNDERFLOW_OCCURED( L40_var_out); */ -#else /* BASOP_NOGLOB */ *Overflow = 1; L40_var_out = MIN_40; -#endif /* BASOP_NOGLOB */ break; } @@ -234,7 +216,6 @@ Word40 L40_shl_o( Word40 L40_var1, Word16 var2, Flag *Overflow ) return ( L40_var_out ); } -#ifdef BASOP_NOGLOB Word40 L40_shl( Word40 L40_var1, Word16 var2 ) { @@ -293,7 +274,6 @@ Word40 L40_shl( Word40 L40_var1, Word16 var2 ) return ( L40_var_out ); } -#endif /* BASOP_NOGLOB */ /***************************************************************************** * @@ -422,7 +402,6 @@ Word40 L40_negate( Word40 L40_var1 ) * the range : MIN_40 <= L40_var_out <= MAX_40. * *****************************************************************************/ -#ifdef BASOP_NOGLOB Word40 L40_add_o( Word40 L40_var1, Word40 L40_var2, Flag *Overflow ) { @@ -465,7 +444,6 @@ Word40 L40_add_o( Word40 L40_var1, Word40 L40_var2, Flag *Overflow ) return ( L40_var_out ); } -#endif /* BASOP_NOGLOB */ Word40 L40_add( Word40 L40_var1, Word40 L40_var2 ) { Word40 L40_var_out; @@ -475,48 +453,24 @@ Word40 L40_add( Word40 L40_var1, Word40 L40_var2 ) #if defined( _MSC_VER ) && ( _MSC_VER <= 1200 ) if ( ( ( ( L40_var1 & 0x8000000000 ) >> 39 ) != 0 ) && ( ( ( L40_var2 & 0x8000000000 ) >> 39 ) != 0 ) && ( ( ( L40_var_out & 0x8000000000 ) >> 39 ) == 0 ) ) { -#ifndef BASOP_NOGLOB - Overflow = 1; - exit( 2 ); - /* L40_var_out = L40_UNDERFLOW_OCCURED( L40_var_out); */ -#else /* BASOP_NOGLOB */ assert( 0 ); L40_var_out = MIN_40; -#endif /* BASOP_NOGLOB */ } else if ( ( ( ( L40_var1 & 0x8000000000 ) >> 39 ) == 0 ) && ( ( ( L40_var2 & 0x8000000000 ) >> 39 ) == 0 ) && ( ( ( L40_var_out & 0x8000000000 ) >> 39 ) != 0 ) ) { -#ifndef BASOP_NOGLOB - Overflow = 1; - exit( 1 ); - /* L40_var_out = L40_OVERFLOW_OCCURED( L40_var_out); */ -#else /* BASOP_NOGLOB */ assert( 0 ); L40_var_out = MAX_40; -#endif /* BASOP_NOGLOB */ } #else if ( ( ( ( L40_var1 & 0x8000000000LL ) >> 39 ) != 0 ) && ( ( ( L40_var2 & 0x8000000000LL ) >> 39 ) != 0 ) && ( ( ( L40_var_out & 0x8000000000LL ) >> 39 ) == 0 ) ) { -#ifndef BASOP_NOGLOB - Overflow = 1; - exit( 2 ); - /* L40_var_out = L40_UNDERFLOW_OCCURED( L40_var_out); */ -#else /* BASOP_NOGLOB */ assert( 0 ); L40_var_out = MIN_40; -#endif /* BASOP_NOGLOB */ } else if ( ( ( ( L40_var1 & 0x8000000000LL ) >> 39 ) == 0 ) && ( ( ( L40_var2 & 0x8000000000LL ) >> 39 ) == 0 ) && ( ( ( L40_var_out & 0x8000000000LL ) >> 39 ) != 0 ) ) { -#ifndef BASOP_NOGLOB - Overflow = 1; - exit( 1 ); - /* L40_var_out = L40_OVERFLOW_OCCURED( L40_var_out); */ -#else /* BASOP_NOGLOB */ assert( 0 ); L40_var_out = MAX_40; -#endif /* BASOP_NOGLOB */ } #endif @@ -561,11 +515,7 @@ Word40 L40_add( Word40 L40_var1, Word40 L40_var2 ) * the range : MIN_40 <= L40_var_out <= MAX_40. * *****************************************************************************/ -#ifndef BASOP_NOGLOB -Word40 L40_sub( Word40 L40_var1, Word40 L40_var2 ) -#else /* BASOP_NOGLOB */ Word40 L40_sub_o( Word40 L40_var1, Word40 L40_var2, Flag *Overflow ) -#endif /* BASOP_NOGLOB */ { Word40 L40_var_out; @@ -574,48 +524,24 @@ Word40 L40_sub_o( Word40 L40_var1, Word40 L40_var2, Flag *Overflow ) #if defined( _MSC_VER ) && ( _MSC_VER <= 1200 ) if ( ( ( ( L40_var1 & 0x8000000000 ) >> 39 ) != 0 ) && ( ( ( L40_var2 & 0x8000000000 ) >> 39 ) == 0 ) && ( ( ( L40_var_out & 0x8000000000 ) >> 39 ) == 0 ) ) { -#ifndef BASOP_NOGLOB - Overflow = 1; - exit( 2 ); - /* L40_var_out = L40_UNDERFLOW_OCCURED( L40_var_out); */ -#else /* BASOP_NOGLOB */ *Overflow = 1; L40_var_out = MIN_40; -#endif /* BASOP_NOGLOB */ } else if ( ( ( ( L40_var1 & 0x8000000000 ) >> 39 ) == 0 ) && ( ( ( L40_var2 & 0x8000000000 ) >> 39 ) != 0 ) && ( ( ( L40_var_out & 0x8000000000 ) >> 39 ) != 0 ) ) { -#ifndef BASOP_NOGLOB - Overflow = 1; - exit( 1 ); - /* L40_var_out = L40_OVERFLOW_OCCURED( L40_var_out); */ -#else /* BASOP_NOGLOB */ *Overflow = 1; L40_var_out = MAX_40; -#endif /* BASOP_NOGLOB */ } #else if ( ( ( ( L40_var1 & 0x8000000000LL ) >> 39 ) != 0 ) && ( ( ( L40_var2 & 0x8000000000LL ) >> 39 ) == 0 ) && ( ( ( L40_var_out & 0x8000000000LL ) >> 39 ) == 0 ) ) { -#ifndef BASOP_NOGLOB - Overflow = 1; - exit( 2 ); - /* L40_var_out = L40_UNDERFLOW_OCCURED( L40_var_out); */ -#else /* BASOP_NOGLOB */ *Overflow = 1; L40_var_out = MIN_40; -#endif /* BASOP_NOGLOB */ } else if ( ( ( ( L40_var1 & 0x8000000000LL ) >> 39 ) == 0 ) && ( ( ( L40_var2 & 0x8000000000LL ) >> 39 ) != 0 ) && ( ( ( L40_var_out & 0x8000000000LL ) >> 39 ) != 0 ) ) { -#ifndef BASOP_NOGLOB - Overflow = 1; - exit( 1 ); - /* L40_var_out = L40_OVERFLOW_OCCURED( L40_var_out); */ -#else /* BASOP_NOGLOB */ *Overflow = 1; L40_var_out = MAX_40; -#endif /* BASOP_NOGLOB */ } #endif @@ -629,7 +555,6 @@ Word40 L40_sub_o( Word40 L40_var1, Word40 L40_var2, Flag *Overflow ) return ( L40_var_out ); } -#ifdef BASOP_NOGLOB Word40 L40_sub( Word40 L40_var1, Word40 L40_var2 ) { Word40 L40_var_out; @@ -669,7 +594,6 @@ Word40 L40_sub( Word40 L40_var1, Word40 L40_var2 ) return ( L40_var_out ); } -#endif /* BASOP_NOGLOB */ /***************************************************************************** * @@ -838,12 +762,8 @@ Word40 L40_min( Word40 L40_var1, Word40 L40_var2 ) * the range : 0x8000 0000 <= L_var_out <= 0x7fff ffff. * *****************************************************************************/ -#ifndef BASOP_NOGLOB -Word32 L_saturate40( Word40 L40_var1 ) -#else /* BASOP_NOGLOB */ Word32 L_saturate40_o( Word40 L40_var1, Flag *Overflow ) -#endif /* BASOP_NOGLOB */ { Word32 L_var_out; @@ -853,21 +773,13 @@ Word32 L_saturate40_o( Word40 L40_var1, Flag *Overflow ) if ( L40_var1 < UNDER_L40_var2 ) { L40_var1 = UNDER_L40_var2; -#ifndef BASOP_NOGLOB - Overflow = 1; -#else /* BASOP_NOGLOB */ *Overflow = 1; -#endif /* BASOP_NOGLOB */ } if ( L40_var1 > OVER_L40_var2 ) { L40_var1 = OVER_L40_var2; -#ifndef BASOP_NOGLOB - Overflow = 1; -#else /* BASOP_NOGLOB */ *Overflow = 1; -#endif /* BASOP_NOGLOB */ } L_var_out = L_Extract40( L40_var1 ); @@ -882,7 +794,6 @@ Word32 L_saturate40_o( Word40 L40_var1, Flag *Overflow ) return ( L_var_out ); } -#ifdef BASOP_NOGLOB Word32 L_saturate40( Word40 L40_var1 ) { Word32 L_var_out; @@ -913,7 +824,6 @@ Word32 L_saturate40( Word40 L40_var1 ) return ( L_var_out ); } -#endif /* BASOP_NOGLOB */ /***************************************************************************** * diff --git a/lib_com/enh40.h b/lib_com/enh40.h index ca78cb33e757efa0b842cccef662c45d1d96fa50..9c3742f3ef23b24bced88e87e71b85a8ac83baca 100644 --- a/lib_com/enh40.h +++ b/lib_com/enh40.h @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other @@ -56,10 +56,8 @@ #include "stl.h" -#if defined( BASOP_NOGLOB ) || defined( _MSC_VER ) #define MAX_40 ( 0x0000007fffffffff ) #define MIN_40 ( 0xffffff8000000000 ) -#endif #define L40_OVERFLOW_OCCURED( L40_var1 ) ( Overflow = 1, exit( 1 ), L40_var1 ) #define L40_UNDERFLOW_OCCURED( L40_var1 ) ( Overflow = 1, exit( 2 ), L40_var1 ) @@ -111,7 +109,6 @@ Word40 L40_max( Word40 L40_var1, Word40 L40_var2 ); Word40 L40_min( Word40 L40_var1, Word40 L40_var2 ); Word32 L_saturate40( Word40 L40_var1 ); Word16 norm_L40( Word40 L40_var1 ); -#ifdef BASOP_NOGLOB /* * Overflowing operators */ @@ -119,7 +116,6 @@ Word40 L40_shl_o( Word40 L40_var1, Word16 var2, Flag *Overflow ); Word40 L40_add_o( Word40 L40_var1, Word40 L40_var2, Flag *Overflow ); Word40 L40_sub_o( Word40 L40_var1, Word40 L40_var2, Flag *Overflow ); Word32 L_saturate40_o( Word40 L40_var1, Flag *Overflow ); -#endif /* BASOP_NOGLOB */ /*#ifdef _MSC_VER*/ static __inline Word40 L40_set( Word40 L40_var1 ) { diff --git a/lib_com/enh64.c b/lib_com/enh64.c index 9eb58c4d399848547a585ff714a0f212adecad7d..8bffb620cc8dfb0b2164e718b83fa365fb048430 100644 --- a/lib_com/enh64.c +++ b/lib_com/enh64.c @@ -161,11 +161,7 @@ Word64 W_sub_nosat( Word64 L64_var1, Word64 L64_var2 ) | range : 0x80000000 00000000LL <= L64_var1 <= 0x7fffffff ffffffffLL. | |___________________________________________________________________________| */ -#ifdef BASOP_NOGLOB Word64 W_shl_o( Word64 L64_var1, Word16 var2, Flag *Overflow ) -#else /* BASOP_NOGLOB */ -Word64 W_shl( Word64 L64_var1, Word16 var2 ) -#endif /* BASOP_NOGLOB */ { Word64 L64_var_out = 0LL; @@ -183,11 +179,7 @@ Word64 W_shl( Word64 L64_var1, Word16 var2 ) { if ( L64_var1 > (Word64) 0X3fffffffffffffffLL ) { -#ifdef BASOP_NOGLOB set_overflow( Overflow ); -#else /* BASOP_NOGLOB */ - Overflow = 1; -#endif /* BASOP_NOGLOB */ L64_var_out = (Word64) 0X7fffffffffffffffLL; break; } @@ -195,11 +187,7 @@ Word64 W_shl( Word64 L64_var1, Word16 var2 ) { if ( L64_var1 < (Word64) 0xc000000000000000LL ) { -#ifdef BASOP_NOGLOB set_overflow( Overflow ); -#else /* BASOP_NOGLOB */ - Overflow = 1; -#endif /* BASOP_NOGLOB */ L64_var_out = (Word64) 0x8000000000000000LL; break; } @@ -217,12 +205,10 @@ Word64 W_shl( Word64 L64_var1, Word16 var2 ) return ( L64_var_out ); } -#ifdef BASOP_NOGLOB Word64 W_shl( Word64 L64_var1, Word16 var2 ) { return W_shl_o( L64_var1, var2, NULL ); } -#endif /* BASOP_NOGLOB */ /*___________________________________________________________________________ @@ -1185,11 +1171,7 @@ Word32 W_shl_sat_l( Word64 L64_var, Word16 n ) | range : 0x8000 0000 <= L_var_out <= 0x7fff ffff. | |__________________________________________________________________________________| */ -#ifdef BASOP_NOGLOB Word32 W_round48_L_o( Word64 L64_var1, Flag *Overflow ) -#else /* BASOP_NOGLOB */ -Word32 W_round48_L( Word64 L64_var1 ) -#endif /* BASOP_NOGLOB */ { Word64 L64_var_out; Word32 L_result; @@ -1207,11 +1189,7 @@ Word32 W_round48_L( Word64 L64_var1 ) if ( ( L64_var_out ^ L64_var1 ) & L64_MIN ) { L64_var_out = ( L64_var1 < 0 ) ? L64_MIN : L64_MAX; -#ifdef BASOP_NOGLOB set_overflow( Overflow ); -#else /* BASOP_NOGLOB */ - Overflow = 1; -#endif /* BASOP_NOGLOB */ } } L_result = W_extract_h( L64_var_out ); @@ -1224,12 +1202,10 @@ Word32 W_round48_L( Word64 L64_var1 ) return ( L_result ); } -#ifdef BASOP_NOGLOB Word32 W_round48_L( Word64 L64_var1 ) { return W_round48_L_o( L64_var1, NULL ); } -#endif /* BASOP_NOGLOB */ /*__________________________________________________________________________________ | | @@ -1258,11 +1234,7 @@ Word32 W_round48_L( Word64 L64_var1 ) | range : 0xffff 8000 <= var_out <= 0x0000 7fff. | |__________________________________________________________________________________| */ -#ifdef BASOP_NOGLOB Word16 W_round32_s_o( Word64 L64_var1, Flag *Overflow ) -#else /* BASOP_NOGLOB */ -Word16 W_round32_s( Word64 L64_var1 ) -#endif /* BASOP_NOGLOB */ { Word64 L64_var_out; Word32 L_var; @@ -1281,11 +1253,7 @@ Word16 W_round32_s( Word64 L64_var1 ) if ( ( L64_var_out ^ L64_var1 ) & L64_MIN ) { L64_var_out = ( L64_var1 < 0 ) ? L64_MIN : L64_MAX; -#ifdef BASOP_NOGLOB set_overflow( Overflow ); -#else /* BASOP_NOGLOB */ - Overflow = 1; -#endif /* BASOP_NOGLOB */ } } L_var = W_extract_h( L64_var_out ); @@ -1300,12 +1268,10 @@ Word16 W_round32_s( Word64 L64_var1 ) return ( var_out ); } -#ifdef BASOP_NOGLOB Word16 W_round32_s( Word64 L64_var1 ) { return W_round32_s_o( L64_var1, NULL ); } -#endif /* BASOP_NOGLOB */ /*___________________________________________________________________________ | | @@ -1398,11 +1364,7 @@ Word16 W_norm( Word64 L64_var1 ) | range : 0x80000000 00000000LL <= L64_var1 <= 0x7fffffff ffffffffLL. | |_______________________________________________________________________________| */ -#ifdef BASOP_NOGLOB Word64 W_add_o( Word64 L64_var1, Word64 L64_var2, Flag *Overflow ) -#else /* BASOP_NOGLOB */ -Word64 W_add( Word64 L64_var1, Word64 L64_var2 ) -#endif /* BASOP_NOGLOB */ { Word64 L64_var_out; @@ -1413,11 +1375,7 @@ Word64 W_add( Word64 L64_var1, Word64 L64_var2 ) if ( ( L64_var_out ^ L64_var1 ) & MIN_64 ) { L64_var_out = ( L64_var1 < 0 ) ? MIN_64 : MAX_64; -#ifdef BASOP_NOGLOB set_overflow( Overflow ); -#else /* BASOP_NOGLOB */ - Overflow = 1; -#endif /* BASOP_NOGLOB */ } } @@ -1427,12 +1385,10 @@ Word64 W_add( Word64 L64_var1, Word64 L64_var2 ) return L64_var_out; } -#ifdef BASOP_NOGLOB Word64 W_add( Word64 L64_var1, Word64 L64_var2 ) { return W_add_o( L64_var1, L64_var2, NULL ); } -#endif /* BASOP_NOGLOB */ /*______________________________________________________________________________ | | @@ -1465,11 +1421,7 @@ Word64 W_add( Word64 L64_var1, Word64 L64_var2 ) | range : 0x80000000 00000000LL <= L64_var1 <= 0x7fffffff ffffffffLL. | |_______________________________________________________________________________| */ -#ifdef BASOP_NOGLOB Word64 W_sub_o( Word64 L64_var1, Word64 L64_var2, Flag *Overflow ) -#else /* BASOP_NOGLOB */ -Word64 W_sub( Word64 L64_var1, Word64 L64_var2 ) -#endif /* BASOP_NOGLOB */ { Word64 L64_var_out; @@ -1480,11 +1432,7 @@ Word64 W_sub( Word64 L64_var1, Word64 L64_var2 ) if ( ( L64_var_out ^ L64_var1 ) & MIN_64 ) { L64_var_out = ( L64_var1 < 0 ) ? MIN_64 : MAX_64; -#ifdef BASOP_NOGLOB set_overflow( Overflow ); -#else /* BASOP_NOGLOB */ - Overflow = 1; -#endif /* BASOP_NOGLOB */ } } @@ -1494,12 +1442,10 @@ Word64 W_sub( Word64 L64_var1, Word64 L64_var2 ) return L64_var_out; } -#ifdef BASOP_NOGLOB Word64 W_sub( Word64 L64_var1, Word64 L64_var2 ) { return W_sub_o( L64_var1, L64_var2, NULL ); } -#endif /* BASOP_NOGLOB */ /*______________________________________________________________________________ @@ -1529,22 +1475,14 @@ Word64 W_sub( Word64 L64_var1, Word64 L64_var2 ) | range : 0x80000000 00000000LL <= L64_var1 <= 0x7fffffff ffffffffLL. | |_______________________________________________________________________________| */ -#ifdef BASOP_NOGLOB Word64 W_neg_o( Word64 L64_var1, Flag *Overflow ) -#else /* BASOP_NOGLOB */ -Word64 W_neg( Word64 L64_var1 ) -#endif /* BASOP_NOGLOB */ { Word64 L64_var_out; if ( L64_var1 == MIN_64 ) { L64_var_out = MAX_64; -#ifdef BASOP_NOGLOB set_overflow( Overflow ); -#else /* BASOP_NOGLOB */ - Overflow = 1; -#endif /* BASOP_NOGLOB */ } else { @@ -1558,12 +1496,10 @@ Word64 W_neg( Word64 L64_var1 ) return ( L64_var_out ); } -#ifdef BASOP_NOGLOB Word64 W_neg( Word64 L64_var1 ) { return W_neg_o( L64_var1, NULL ); } -#endif /* BASOP_NOGLOB */ /*___________________________________________________________________________ @@ -1593,22 +1529,14 @@ Word64 W_neg( Word64 L64_var1 ) | range : 0x80000000 00000000LL <= L64_var1 <= 0x7fffffff ffffffffLL. | |___________________________________________________________________________| */ -#ifdef BASOP_NOGLOB Word64 W_abs_o( Word64 L64_var1, Flag *Overflow ) -#else /* BASOP_NOGLOB */ -Word64 W_abs( Word64 L64_var1 ) -#endif /* BASOP_NOGLOB */ { Word64 L64_var_out; if ( L64_var1 == MIN_64 ) { L64_var_out = MAX_64; -#ifdef BASOP_NOGLOB set_overflow( Overflow ); -#else /* BASOP_NOGLOB */ - Overflow = 1; -#endif /* BASOP_NOGLOB */ } else { @@ -1629,12 +1557,10 @@ Word64 W_abs( Word64 L64_var1 ) return ( L64_var_out ); } -#ifdef BASOP_NOGLOB Word64 W_abs( Word64 L64_var1 ) { return W_abs_o( L64_var1, NULL ); } -#endif /* BASOP_NOGLOB */ /*_________________________________________________________________________________________________ | | @@ -1668,22 +1594,14 @@ Word64 W_abs( Word64 L64_var1 ) | range : 0x80000000 00000000LL <= L64_var_out <= 0x7fffffff ffffffffLL. | |_________________________________________________________________________________________________| */ -#ifdef BASOP_NOGLOB Word64 W_mult_32_32_o( Word32 L_var1, Word32 L_var2, Flag *Overflow ) -#else /* BASOP_NOGLOB */ -Word64 W_mult_32_32( Word32 L_var1, Word32 L_var2 ) -#endif /* BASOP_NOGLOB */ { Word64 L64_var_out; if ( ( L_var1 == MIN_32 ) && ( L_var2 == MIN_32 ) ) { L64_var_out = MAX_64; -#ifdef BASOP_NOGLOB set_overflow( Overflow ); -#else /* BASOP_NOGLOB */ - Overflow = 1; -#endif /* BASOP_NOGLOB */ } else { @@ -1696,12 +1614,10 @@ Word64 W_mult_32_32( Word32 L_var1, Word32 L_var2 ) return L64_var_out; } -#ifdef BASOP_NOGLOB Word64 W_mult_32_32( Word32 L_var1, Word32 L_var2 ) { return W_mult_32_32_o( L_var1, L_var2, NULL ); } -#endif /* BASOP_NOGLOB */ /*_________________________________________________________________________________________________ | | diff --git a/lib_com/enh64.h b/lib_com/enh64.h index 8aed870a67e0688ab7e3398caa7f7aa040f186b0..c3896bb0d257aa053df48da5c84948b8255e0401 100644 --- a/lib_com/enh64.h +++ b/lib_com/enh64.h @@ -65,7 +65,6 @@ UWord64 W_lshl( UWord64 L64_var1, Word16 var2 ); UWord64 W_lshr( UWord64 L64_var1, Word16 var2 ); Word32 W_round64_L( Word64 L64_var1 ); -#ifdef BASOP_NOGLOB /* * Overflowing operators */ @@ -77,7 +76,6 @@ Word64 W_sub_o( Word64 L64_var1, Word64 L64_var2, Flag *Overflow ); Word64 W_neg_o( Word64 L64_var1, Flag *Overflow ); Word64 W_abs_o( Word64 L64_var1, Flag *Overflow ); Word64 W_mult_32_32_o( Word32 L_var1, Word32 L_var2, Flag *Overflow ); -#endif /* BASOP_NOGLOB */ #endif /* #ifdef ENH_64_BIT_OPERATOR */ diff --git a/lib_com/enhancer_fx.c b/lib_com/enhancer_fx.c index 88bc7049710728f6e8e47966219719ddc606e6e0..7df474a5d6ab88a9f6ca0ae8f706f590ae0affe7 100644 --- a/lib_com/enhancer_fx.c +++ b/lib_com/enhancer_fx.c @@ -137,11 +137,7 @@ void enhancer_fx( *-----------------------------------------------------------*/ /* tmp = 0.5f * (1.0f - voice_fac) */ -#ifdef BASOP_NOGLOB tmp = msu_r_sat( 0x40000000 /*0.5.Q31*/, voice_fac, 16384 /*0.5.Q15*/ ); /*Q15 */ /* 1=unvoiced, 0=voiced */ -#else - tmp = msu_r( 0x40000000, voice_fac, 16384 ); /*Q15 */ /* 1=unvoiced, 0=voiced */ -#endif /* fac = stab_fac * tmp */ fac = mult( stab_fac, tmp ); /*Q15*/ @@ -193,11 +189,7 @@ void enhancer_fx( test(); IF( Opt_AMR_WB && ( EQ_32( core_brate, ACELP_8k85 ) || EQ_32( core_brate, ACELP_6k60 ) ) ) { -#ifdef BASOP_NOGLOB pit_sharp = shl_sat( gain_pit, 1 ); /* saturation can occur here Q14 -> Q15 */ -#else - pit_sharp = shl( gain_pit, 1 ); /* saturation can occur here Q14 -> Q15 */ -#endif /* saturation takes care of "if (pit_sharp > 1.0) { pit_sharp=1.0; }" */ IF( GT_16( pit_sharp, 16384 /*0.5.Q15*/ ) ) { @@ -232,45 +224,27 @@ void enhancer_fx( /* pt_exc2[0] += code[0] - tmp * code[1] */ L_tmp = L_deposit_h( code[0] ); /* if Enc :Q9 * Q15 -> Q25 */ L_tmp = L_msu( L_tmp, code[1], tmp ); /* Q12 * Q15 -> Q28 */ -#ifdef BASOP_NOGLOB L_tmp = L_shl_sat( L_mult( gain_code_hi, extract_h( L_tmp ) ), sc ); pt_exc2[0] = msu_r_sat( L_tmp, -32768, pt_exc2[0] ); move16(); -#else - L_tmp = L_shl( L_mult( gain_code_hi, extract_h( L_tmp ) ), sc ); - pt_exc2[0] = msu_r( L_tmp, -32768, pt_exc2[0] ); - move16(); -#endif FOR( i = 1; i < L_SUBFR - 1; i++ ) { /* pt_exc2[i] += code[i] - tmp * code[i-1] - tmp * code[i+1] */ L_tmp = L_msu( -32768, code[i], -32768 ); L_tmp = L_msu( L_tmp, code[i + 1], tmp ); -#ifdef BASOP_NOGLOB tmp16 = msu_r_sat( L_tmp, code[i - 1], tmp ); L_tmp = L_shl_sat( L_mult( gain_code_hi, tmp16 ), sc ); pt_exc2[i] = msu_r_sat( L_tmp, -32768, pt_exc2[i] ); move16(); -#else - tmp16 = msu_r( L_tmp, code[i - 1], tmp ); - L_tmp = L_shl( L_mult( gain_code_hi, tmp16 ), sc ); - pt_exc2[i] = msu_r( L_tmp, -32768, pt_exc2[i] ); - move16(); /* in Q_exc */ -#endif } /* pt_exc2[L_SUBFR-1] += code[L_SUBFR-1] - tmp * code[L_SUBFR-2] */ L_tmp = L_deposit_h( code[L_SUBFR - 1] ); /*Q28 */ L_tmp = L_msu( L_tmp, code[L_SUBFR - 2], tmp ); /*Q28 */ L_tmp = L_shl( L_mult( gain_code_hi, extract_h( L_tmp ) ), sc ); -#ifdef BASOP_NOGLOB pt_exc2[L_SUBFR - 1] = msu_r_sat( L_tmp, -32768, pt_exc2[L_SUBFR - 1] ); move16(); -#else - pt_exc2[L_SUBFR - 1] = msu_r( L_tmp, -32768, pt_exc2[L_SUBFR - 1] ); - move16(); -#endif test(); test(); IF( Opt_AMR_WB && ( EQ_32( core_brate, ACELP_8k85 ) || EQ_32( core_brate, ACELP_6k60 ) ) ) @@ -280,11 +254,7 @@ void enhancer_fx( FOR( i = 0; i < L_SUBFR; i++ ) { /* excp[i] += pt_exc2[i] */ -#ifdef BASOP_NOGLOB excp[i] = add_sat( excp[i], pt_exc2[i] ); -#else - excp[i] = add( excp[i], pt_exc2[i] ); -#endif move16(); } agc2_fx( pt_exc2, excp, L_SUBFR ); @@ -440,11 +410,7 @@ void enhancer_ivas_fx( *-----------------------------------------------------------*/ /* tmp = 0.5f * (1.0f - voice_fac) */ -#ifdef BASOP_NOGLOB tmp = msu_r_sat( 0x40000000 /*0.5.Q31*/, voice_fac, 16384 /*0.5.Q14*/ ); /*Q15 */ /* 1=unvoiced, 0=voiced */ -#else - tmp = msu_r( 0x40000000, voice_fac, 16384 ); /*Q15 */ /* 1=unvoiced, 0=voiced */ -#endif /* fac = stab_fac * tmp */ fac = mult( stab_fac, tmp ); /*Q15*/ @@ -496,11 +462,7 @@ void enhancer_ivas_fx( test(); IF( Opt_AMR_WB && ( EQ_32( core_brate, ACELP_8k85 ) || EQ_32( core_brate, ACELP_6k60 ) ) ) { -#ifdef BASOP_NOGLOB pit_sharp = shl_sat( gain_pit, 1 ); /* saturation can occur here Q14 -> Q15 */ -#else - pit_sharp = shl( gain_pit, 1 ); /* saturation can occur here Q14 -> Q15 */ -#endif /* saturation takes care of "if (pit_sharp > 1.0) { pit_sharp=1.0; }" */ IF( GT_16( pit_sharp, 16384 /*0.5.Q15*/ ) ) { @@ -546,11 +508,7 @@ void enhancer_ivas_fx( L_tmp = L_msu( L_tmp, code[i + 1], tmp ); tmp16 = msu_r( L_tmp, code[i - 1], tmp ); L_tmp = L_shl( L_mult( gain_code_hi, tmp16 ), sc ); -#ifdef BASOP_NOGLOB pt_exc2[i] = msu_r_sat( L_tmp, -32768, pt_exc2[i] ); -#else - pt_exc2[i] = msu_r( L_tmp, -32768, pt_exc2[i] ); -#endif move16(); /* in Q_exc */ } @@ -661,11 +619,7 @@ void enhancer_ivas_fx2( *-----------------------------------------------------------*/ /* tmp = 0.5f * (1.0f - voice_fac) */ -#ifdef BASOP_NOGLOB tmp = msu_r_sat( 0x40000000 /*0.5.Q31*/, voice_fac, 16384 /*0.5.Q15*/ ); /*Q15 */ /* 1=unvoiced, 0=voiced */ -#else - tmp = msu_r( 0x40000000, voice_fac, 16384 ); /*Q15 */ /* 1=unvoiced, 0=voiced */ -#endif /* fac = stab_fac * tmp */ fac = mult( stab_fac, tmp ); /*Q15*/ @@ -717,11 +671,7 @@ void enhancer_ivas_fx2( test(); IF( Opt_AMR_WB && ( EQ_32( core_brate, ACELP_8k85 ) || EQ_32( core_brate, ACELP_6k60 ) ) ) { -#ifdef BASOP_NOGLOB pit_sharp = shl_sat( gain_pit, 1 ); /* saturation can occur here Q14 -> Q15 */ -#else - pit_sharp = shl( gain_pit, 1 ); /* saturation can occur here Q14 -> Q15 */ -#endif /* saturation takes care of "if (pit_sharp > 1.0) { pit_sharp=1.0; }" */ IF( GT_16( pit_sharp, 16384 /*0.5.Q15*/ ) ) { @@ -788,11 +738,7 @@ void enhancer_ivas_fx2( FOR( i = 0; i < L_SUBFR; i++ ) { /* excp[i] += pt_exc2[i] */ -#ifdef BASOP_NOGLOB excp[i] = add_sat( excp[i], pt_exc2[i] ); -#else - excp[i] = add( excp[i], pt_exc2[i] ); -#endif move16(); } agc2_fx( pt_exc2, excp, L_SUBFR ); @@ -877,11 +823,7 @@ Word16 E_UTIL_enhancer( /* if gain_code is computed function of energy, noise enhancer is by-passed.*/ BASOP_SATURATE_WARNING_OFF_EVS -#ifdef BASOP_NOGLOB tmp = msu_r_sat( 1073741824l /*0.5f Q31*/, 16384 /*0.5f Q15*/, voice_fac ); /* 1=unvoiced, 0=voiced */ -#else /* BASOP_NOGLOB */ - tmp = msu_r( 1073741824l /*0.5f Q31*/, 16384 /*0.5f Q15*/, voice_fac ); /* 1=unvoiced, 0=voiced */ -#endif BASOP_SATURATE_WARNING_ON_EVS fac = mult_r( stab_fac, tmp ); /* fac in Q15 */ @@ -912,13 +854,8 @@ Word16 E_UTIL_enhancer( /* exponent of code: 31-16 + 15-11 - tmp + code_exp */ code_exp = sub( add( 31 - 16 + 15 - 11, code_exp ), tmp ); -#ifdef BASOP_NOGLOB L_tmp = L_shl_sat( L_tmp, tmp ); gain = round_fx_sat( L_tmp ); -#else - L_tmp = L_shl( L_tmp, tmp ); - gain = round_fx( L_tmp ); -#endif FOR( i = 0; i < L_subfr; i++ ) { @@ -948,24 +885,15 @@ Word16 E_UTIL_enhancer( L_tmp = L_msu0( L_tmp, tmp, code[1] ); IF( gain ) { -#ifdef BASOP_NOGLOB L_tmp = L_shl_sat( L_tmp, gain ); -#else - L_tmp = L_shl( L_tmp, gain ); -#endif } -#ifdef BASOP_NOGLOB exc2[0] = msu_r_sat( L_tmp, -32768, exc2[0] ); -#else - exc2[0] = msu_r( L_tmp, -32768, exc2[0] ); -#endif move16(); FOR( i = 1; i < L_subfr - 1; i++ ) { /* exc2[i] = exc2[i] + code[i] - tmp*(code[i+1]+code[i-1]); */ L_tmp = L_mult( code[i], 16384 ); -#ifdef BASOP_NOGLOB L_tmp = L_msu0_sat( L_tmp, tmp, code[i - 1] ); L_tmp = L_msu0_sat( L_tmp, tmp, code[i + 1] ); IF( gain ) @@ -973,34 +901,16 @@ Word16 E_UTIL_enhancer( L_tmp = L_shl_sat( L_tmp, gain ); } exc2[i] = msu_r_sat( L_tmp, -32768, exc2[i] ); -#else - L_tmp = L_msu0( L_tmp, tmp, code[i - 1] ); - L_tmp = L_msu0( L_tmp, tmp, code[i + 1] ); - if ( gain ) - { - L_tmp = L_shl( L_tmp, gain ); - } - exc2[i] = msu_r( L_tmp, -32768, exc2[i] ); -#endif move16(); } /* exc2[L_subfr-1] = exc2[L_subfr-1] + code[L_subfr-1] - tmp*code[L_subfr-2]; */ L_tmp = L_mult( code[i], 16384 ); -#ifdef BASOP_NOGLOB L_tmp = L_msu0_sat( L_tmp, tmp, code[i - 1] ); IF( gain ) { L_tmp = L_shl_sat( L_tmp, gain ); } exc2[i] = msu_r_sat( L_tmp, -32768, exc2[i] ); -#else - L_tmp = L_msu0( L_tmp, tmp, code[i - 1] ); - if ( gain ) - { - L_tmp = L_shl( L_tmp, gain ); - } - exc2[i] = msu_r( L_tmp, -32768, exc2[i] ); -#endif move16(); return code_exp; @@ -1079,11 +989,7 @@ static void phase_dispersion_fx( prev_gain_pit[0] = gain_pit; move16(); -#ifdef BASOP_NOGLOB IF( GT_32( L_sub_sat( gain_code, *prev_gain_code ), L_shl_sat( *prev_gain_code, 1 ) ) ) -#else - IF( GT_32( L_sub( gain_code, *prev_gain_code ), L_shl( *prev_gain_code, 1 ) ) ) -#endif { state = s_min( add( state, 1 ), 2 ); } @@ -1208,11 +1114,7 @@ static void agc2_fx( FOR( i = 1; i < l_trm; i++ ) { temp = shr( sig_out[i], 2 ); -#ifdef BASOP_NOGLOB s = L_mac0_sat( s, temp, temp ); -#else - s = L_mac0( s, temp, temp ); -#endif } IF( s != 0 ) { @@ -1225,11 +1127,7 @@ static void agc2_fx( FOR( i = 1; i < l_trm; i++ ) { temp = shr( sig_in[i], 2 ); -#ifdef BASOP_NOGLOB s = L_mac0_sat( s, temp, temp ); -#else - s = L_mac0( s, temp, temp ); -#endif } g0 = 0; @@ -1237,11 +1135,7 @@ static void agc2_fx( IF( s != 0 ) { i = norm_l( s ); -#ifdef BASOP_NOGLOB gain_in = round_fx_sat( L_shl_sat( s, i ) ); -#else - gain_in = round_fx( L_shl( s, i ) ); -#endif exp = sub( exp, i ); /*---------------------------------------------------* @@ -1251,21 +1145,13 @@ static void agc2_fx( s = L_shr( s, exp ); /* add exponent */ s = Isqrt( s ); -#ifdef BASOP_NOGLOB g0 = round_fx_sat( L_shl_sat( s, 9 ) ); -#else - g0 = round_fx( L_shl( s, 9 ) ); -#endif } /* sig_out(n) = gain(n) sig_out(n) */ FOR( i = 0; i < l_trm; i++ ) { -#ifdef BASOP_NOGLOB sig_out[i] = round_fx_sat( L_shl_sat( L_mac( -8192, sig_out[i], g0 ), 2 ) ); -#else - sig_out[i] = round_fx( L_shl( L_mac( -8192, sig_out[i], g0 ), 2 ) ); -#endif move16(); } } diff --git a/lib_com/enr_1_az.c b/lib_com/enr_1_az.c index 8bc24ddbedd500b2b50d451125cf677c19801305..5c99cdfa5e27692d9373f9e5bec6e1b046f8b380 100644 --- a/lib_com/enr_1_az.c +++ b/lib_com/enr_1_az.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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,23 +37,15 @@ #include #include "options.h" #include "cnst.h" -#include "prot.h" -#include "wmc_auto.h" #include "prot_fx.h" +#include "wmc_auto.h" -#ifdef BASOP_NOGLOB Word16 Enr_1_Az_fx_o( /* o : impulse response energy Q3 */ const Word16 Aq[], /* i : LP filter coefs Qx based on the fact that Aq[0] == 1.0 */ const Word16 len, /* i : impulse response length Q0 */ Flag *Overflow_out /* o : propagating the Overflow flag to upper level */ ) -#else -Word16 Enr_1_Az_fx( /* o : impulse response energy Q3 */ - const Word16 Aq[], /* i : LP filter coefs Qx based on the fact that Aq[0] == 1.0 */ - const Word16 len /* i : impulse response length Q0 */ -) -#endif { Word16 h1[2 * L_SUBFR]; Word16 *y; @@ -94,23 +86,13 @@ Word16 Enr_1_Az_fx( /* o : impulse response energy Q3 L_tmp = L_msu( 0, Aq[1], y[-1] ); FOR( j = 2; j <= i; j++ ) { -#ifdef BASOP_NOGLOB L_tmp = L_msu_o( L_tmp, Aq[j], y[-j], &Overflow ); -#else - L_tmp = L_msu( L_tmp, Aq[j], y[-j] ); -#endif } -#ifdef BASOP_NOGLOB L_tmp = L_shl_o( L_tmp, q, &Overflow ); *y = round_fx_o( L_tmp, &Overflow ); move16(); L_tmp2 = L_mac_o( L_tmp2, *y, *y, &Overflow ); -#else - L_tmp = L_shl( L_tmp, q ); - *y = round_fx( L_tmp ); - L_tmp2 = L_mac( L_tmp2, *y, *y ); -#endif y++; } /* Normal Filtering */ @@ -119,34 +101,19 @@ Word16 Enr_1_Az_fx( /* o : impulse response energy Q3 L_tmp = L_msu( 0, Aq[1], y[-1] ); FOR( j = 2; j <= M; j++ ) { -#ifdef BASOP_NOGLOB L_tmp = L_msu_o( L_tmp, Aq[j], y[-j], &Overflow ); -#else - L_tmp = L_msu( L_tmp, Aq[j], y[-j] ); -#endif } -#ifdef BASOP_NOGLOB L_tmp = L_shl_o( L_tmp, q, &Overflow ); *y = round_fx_o( L_tmp, &Overflow ); move16(); L_tmp2 = L_mac_o( L_tmp2, *y, *y, &Overflow ); -#else - L_tmp = L_shl( L_tmp, q ); - *y = round_fx( L_tmp ); - L_tmp2 = L_mac( L_tmp2, *y, *y ); -#endif y++; } -#ifdef BASOP_NOGLOB *Overflow_out = Overflow; move32(); return round_fx_o( L_tmp2, Overflow_out ); /* Q19 to Q3 */ -#else - return round_fx( L_tmp2 ); /* Q19 to Q3 */ -#endif } -#ifdef BASOP_NOGLOB Word16 Enr_1_Az_fx( /* o : impulse response energy Q3 */ const Word16 Aq[], /* i : LP filter coefs Qx based on the fact that Aq[0] == 1.0 */ const Word16 len /* i : impulse response length Q0 */ @@ -156,4 +123,3 @@ Word16 Enr_1_Az_fx( /* o : impulse response energy Q3 move32(); return Enr_1_Az_fx_o( Aq, len, &Overflow ); } -#endif diff --git a/lib_com/env_adj.c b/lib_com/env_adj.c index d0e3877ded0f17a6edf0d832cd140b69df105e8e..5a83dbe5fa8af935aa151a8fdb7d87738100c789 100644 --- a/lib_com/env_adj.c +++ b/lib_com/env_adj.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other @@ -38,9 +38,8 @@ #include "options.h" #include "cnst.h" #include "rom_com.h" -#include "prot.h" -#include "wmc_auto.h" #include "prot_fx.h" +#include "wmc_auto.h" /*--------------------------------------------------------------------------* * env_adj() @@ -145,12 +144,8 @@ void env_adj_fx( IF( EQ_16( att_state, 1 ) ) /* End of attenuation region found */ { /* tmp = min(1, max(0, len-ENV_ADJ_START)*(1.0f/ENV_ADJ_INCL)); */ -#ifdef BASOP_NOGLOB tmp = round_fx_sat( L_shl_sat( L_mult0( s_max( 0, sub( len, ENV_ADJ_START_FX ) ), ENV_ADJ_INV_INCL_FX ), 16 ) ); /* Q15 (15+16-16) */ -#else - tmp = round_fx( L_shl( L_mult0( s_max( 0, sub( len, ENV_ADJ_START_FX ) ), ENV_ADJ_INV_INCL_FX ), 16 ) ); /* Q15 (15+16-16) */ -#endif - tmp_diff = sub( MAX_16, tmp ); /* Q15 */ + tmp_diff = sub( MAX_16, tmp ); /* Q15 */ FOR( j = start; j < i; j++ ) { /* adj[j] = max(tmp + (1-tmp)*adj[j],env_stab); */ @@ -192,12 +187,8 @@ void env_adj_fx( IF( EQ_16( att_state, 1 ) ) { /* tmp = min(1, max(0, len-ENV_ADJ_START)*(1.0f/ENV_ADJ_INCL)); */ -#ifdef BASOP_NOGLOB tmp = round_fx_sat( L_shl_sat( L_mult0( s_max( 0, sub( len, ENV_ADJ_START_FX ) ), ENV_ADJ_INV_INCL_FX ), 16 ) ); /* Q15 (15+16-16) */ -#else - tmp = round_fx( L_shl( L_mult0( s_max( 0, sub( len, ENV_ADJ_START_FX ) ), ENV_ADJ_INV_INCL_FX ), 16 ) ); /* Q15 (15+16-16) */ -#endif - tmp_diff = sub( MAX_16, tmp ); /* Q15 */ + tmp_diff = sub( MAX_16, tmp ); /* Q15 */ move16(); FOR( j = start; j < i; j++ ) { diff --git a/lib_com/env_stab.c b/lib_com/env_stab.c index 0a04508b6c22a7d255e3a1c8bfdf6309efe4db5a..a3140b4e498beb79ffa011af6baa60bbeb0a2bad 100644 --- a/lib_com/env_stab.c +++ b/lib_com/env_stab.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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,11 +39,10 @@ #include "options.h" #include #include "cnst.h" -#include "prot.h" +#include "prot_fx.h" #include "rom_com.h" #include "wmc_auto.h" #include "stl.h" -#include "prot_fx.h" /*--------------------------------------------------------------------------* * Local constants *--------------------------------------------------------------------------*/ @@ -88,11 +87,7 @@ Word16 env_stability_fx( /* in Q15 */ } Overflow = 0; move16(); -#ifdef BASOP_NOGLOB /* Critical Overflow */ env_delta = shl_o( *mem_env_delta, 1, &Overflow ); -#else - env_delta = shl( *mem_env_delta, 1 ); -#endif } ELSE { @@ -125,29 +120,15 @@ Word16 env_stability_fx( /* in Q15 */ } exp = shr( exp, 1 ); -#ifdef BASOP_NOGLOB /* Critical Overflow */ env_delta = round_fx_sat( L_shl_sat( L_tmp, sub( 26, exp ) ) ); /* Q10 */ -#else - env_delta = round_fx( L_shl( L_tmp, sub( 26, exp ) ) ); /* Q10 */ -#endif L_tmp = L_mult0( 26214, env_delta ); /* 26214 is 0.1 in Q18. Q28 */ -#ifdef BASOP_NOGLOB /* Critical Overflow */ L_tmp = L_mac_sat( L_tmp, 29491, *mem_env_delta ); /* 29491 is 0.9 in Q15. Q28 */ *mem_env_delta = round_fx_sat( L_tmp ); /* Q12 */ -#else - L_tmp = L_mac( L_tmp, 29491, *mem_env_delta ); /* 29491 is 0.9 in Q15. Q28 */ - - *mem_env_delta = round_fx( L_tmp ); /* Q12 */ -#endif Overflow = 0; move16(); -#ifdef BASOP_NOGLOB /* Critical Overflow */ env_delta = round_fx_o( L_shl_o( L_tmp, 1, &Overflow ), &Overflow ); /* Q13 */ -#else - env_delta = round_fx( L_shl( L_tmp, 1 ) ); /* Q13 */ -#endif } IF( Overflow != 0 ) /* Saturated due to the above up-shifting operation. */ { @@ -245,13 +226,8 @@ Word16 env_stab_smo_fx( /* Q0 */ /*tmp = shl(tmp, add(exp, 1));*/ /* Q15 */ FOR( i = 0; i < NUM_ENV_STAB_PLC_STATES; i++ ) { -#ifdef BASOP_NOGLOB env_stab_state_p[i] = round_fx_o( L_shl_o( L_mult_o( env_stab_state_p[i], tmp, &Overflow ), add( exp, 1 ), &Overflow ), &Overflow ); /* Q15 */ move16(); -#else - env_stab_state_p[i] = round_fx( L_shl( L_mult( env_stab_state_p[i], tmp ), add( exp, 1 ) ) ); /* Q15 */ - move16(); -#endif } /* find maximum index as return value */ diff --git a/lib_com/env_stab_trans.c b/lib_com/env_stab_trans.c index e3f98d881d68c12d48a9e99503ce650feea844c5..829bef5f40f99a7245b65102c1f3aad4f685aa7d 100644 --- a/lib_com/env_stab_trans.c +++ b/lib_com/env_stab_trans.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other @@ -38,10 +38,9 @@ #include "options.h" #include #include "cnst.h" -#include "prot.h" +#include "prot_fx.h" #include "rom_com.h" #include "wmc_auto.h" -#include "prot_fx.h" /*--------------------------------------------------------------------------* * env_stab_transient_detect() * diff --git a/lib_com/est_tilt_fx.c b/lib_com/est_tilt_fx.c index d47a47191a7adeed24e8fd12b3f4e64528cd0aa8..4ff9c6c1129555fe39b5ea34e4200f9afe451741 100644 --- a/lib_com/est_tilt_fx.c +++ b/lib_com/est_tilt_fx.c @@ -40,18 +40,12 @@ Word16 est_tilt_fx( /* o : tilt of the code const Word32 gain_code, /* i : algebraic code gain Q16 */ Word16 *voice_fac, /* o : voicing factor Q15 */ const Word16 Q_exc /* i : Scaling factor of excitation Q0 */ -#ifdef ADD_LRTD - , - const Word16 L_subfr /* i : Sub frame length */ -#endif ) { Word16 i, tmp, exp, ener1, exp1, ener2, exp2; Word32 L_tmp; Word16 tilt_code; -#ifdef ADD_LRTD - PMT( "FIX POINT NEED to be adapted for 16 kHz frame length " ) -#endif + ener1 = extract_h( Dot_product12( exc, exc, L_SUBFR, &exp1 ) ); exp1 = sub( exp1, add( Q_exc, Q_exc ) ); L_tmp = L_mult( gain_pit, gain_pit ); /* energy of pitch excitation */ @@ -70,13 +64,8 @@ Word16 est_tilt_fx( /* o : tilt of the code i = sub( exp1, exp2 ); BASOP_SATURATE_WARNING_OFF_EVS -#ifdef BASOP_NOGLOB ener1 = shr_sat( ener1, sub( 1, s_min( i, 0 ) ) ); ener2 = shr_sat( ener2, add( s_max( 0, i ), 1 ) ); -#else - ener1 = shr( ener1, sub( 1, s_min( i, 0 ) ) ); - ener2 = shr( ener2, add( s_max( 0, i ), 1 ) ); -#endif BASOP_SATURATE_WARNING_ON_EVS tmp = sub( ener1, ener2 ); ener1 = add( add( ener1, ener2 ), 1 ); @@ -122,26 +111,23 @@ Word16 est_tilt_fx( /* o : tilt of the code /* RETURN ARGUMENTS : */ /* _ (Word16) tolt_code : tilt of the code Q15 */ /*=======================================================================*/ -Word16 est_tilt_ivas_fx( /* o : tilt of the code Q15 */ - const Word16 *exc, /* i : adaptive excitation vector Qx */ - const Word16 gain_pit, /* i : adaptive gain Q14 */ - const Word16 *code, /* i : algebraic excitation vector Q9 */ - const Word32 gain_code, /* i : algebraic code gain Q16 */ - Word16 *voice_fac, /* o : voicing factor Q15 */ - const Word16 Q_exc /* i : Scaling factor of excitation Q0 */ -#if 1 // def ADD_LRTD - , - const Word16 L_subfr, /* i : Sub frame length */ - const Word16 flag_tilt /* i : flag for special tilt */ -#endif + +/* o : tilt of the code Q15 */ +Word16 est_tilt_ivas_fx( + const Word16 *exc, /* i : adaptive excitation vector Qx */ + const Word16 gain_pit, /* i : adaptive gain Q14 */ + const Word16 *code, /* i : algebraic excitation vector Q9 */ + const Word32 gain_code, /* i : algebraic code gain Q16 */ + Word16 *voice_fac, /* o : voicing factor Q15 */ + const Word16 Q_exc, /* i : Scaling factor of excitation Q0 */ + const Word16 L_subfr, /* i : Sub frame length */ + const Word16 flag_tilt /* i : flag for special tilt */ ) { Word16 i, tmp, exp, ener1, exp1, ener2, exp2; Word32 L_tmp; Word16 tilt_code; -#ifdef ADD_LRTD - PMT( "FIX POINT NEED to be adapted for 16 kHz frame length " ) -#endif + ener1 = extract_h( Dot_product12( exc, exc, L_subfr, &exp1 ) ); exp1 = sub( exp1, add( Q_exc, Q_exc ) ); L_tmp = L_mult( gain_pit, gain_pit ); /* energy of pitch excitation */ @@ -160,13 +146,8 @@ Word16 est_tilt_ivas_fx( /* o : tilt of the code i = sub( exp1, exp2 ); BASOP_SATURATE_WARNING_OFF_EVS -#ifdef BASOP_NOGLOB ener1 = shr_sat( ener1, sub( 1, s_min( i, 0 ) ) ); ener2 = shr_sat( ener2, add( s_max( 0, i ), 1 ) ); -#else - ener1 = shr( ener1, sub( 1, s_min( i, 0 ) ) ); - ener2 = shr( ener2, add( s_max( 0, i ), 1 ) ); -#endif BASOP_SATURATE_WARNING_ON_EVS tmp = sub( ener1, ener2 ); ener1 = add( add( ener1, ener2 ), 1 ); @@ -341,21 +322,13 @@ void E_UTIL_voice_factor( Word16 *exc, /* i : pointer to the excitation f IF( i >= 0 ) { ener = L_shr( ener, 1 ); -#ifdef BASOP_NOGLOB tmp = L_shr_sat( tmp, add( 1, i ) ); -#else - tmp = L_shr( tmp, add( 1, i ) ); -#endif } ELSE { tmp = L_shr( tmp, 1 ); BASOP_SATURATE_WARNING_OFF_EVS -#ifdef BASOP_NOGLOB ener = L_shr_sat( ener, sub( 1, i ) ); -#else - ener = L_shr( ener, sub( 1, i ) ); -#endif BASOP_SATURATE_WARNING_ON_EVS } diff --git a/lib_com/fd_cng_com_fx.c b/lib_com/fd_cng_com_fx.c index 86e27427ece5aabcaea4b905c56f1dcf588fe6ea..78809ed2c6a0dd5a4ca9ba595896388b03106c75 100644 --- a/lib_com/fd_cng_com_fx.c +++ b/lib_com/fd_cng_com_fx.c @@ -12,7 +12,6 @@ #include "prot_fx.h" #include "prot_fx_enc.h" #include "ivas_prot_fx.h" -#include "prot.h" #define FFT_SCALING_512 1073741824 // Q22 #define FFT_SCALING_640 1342177280 // Q22 @@ -566,11 +565,6 @@ void minimum_statistics( Word16 *msPeriodogBuf, /* i/o: Buffer of periodograms (energies) */ Word16 *msPeriodogBufPtr, /* i/o: Counter */ HANDLE_FD_CNG_COM hFdCngCom /* i/o: FD_CNG structure containing all buffers and variables */ -#ifdef IVAS_CODE_CNG - , - const Word16 enc_dec, /* i : encoder/decoder indicator */ - const Word16 element_mode /* i : IVAS element mode type */ -#endif ) { Word16 i, j, k, s, s1, s2, s3; @@ -692,11 +686,7 @@ void minimum_statistics( { /* calculate scalar with normalized msPeriodogSum[cnt], exponent -2*s1 */ s1 = norm_l( msPeriodogSum[cnt] ); -#ifdef BASOP_NOGLOB msPeriodogSum16 = round_fx_sat( L_shl_sat( msPeriodogSum[cnt], s1 ) ); -#else - msPeriodogSum16 = round_fx( L_shl( msPeriodogSum[cnt], s1 ) ); -#endif scalar = L_mult( msPeriodogSum16, msPeriodogSum16 ); /* calculate difference, both elements in 16Q15 format, use absolute value @@ -710,11 +700,7 @@ void minimum_statistics( /* use absolute value to avoid -1.0 x -1.0 multiplications */ s2 = norm_l( scalar2 ); } -#ifdef BASOP_NOGLOB scalar216 = round_fx_o( L_shl_o( scalar2, s2, &Overflow ), &Overflow ); -#else - scalar216 = round_fx( L_shl( scalar2, s2 ) ); -#endif scalar2 = L_mult( scalar216, scalar216 ); /* find common exponent */ @@ -864,11 +850,7 @@ void minimum_statistics( s2 = s_min( s2, WORD32_BITS - 1 ); /* beta: scaled by s2 */ -#ifdef BASOP_NOGLOB tmp16 = round_fx_o( L_shl_o( tmp, s1, &Overflow ), &Overflow ); -#else - tmp16 = round_fx( L_shl( tmp, s1 ) ); -#endif beta = mult_r( tmp16, tmp16 ); /* scalar3: scaled by s3 */ @@ -956,11 +938,7 @@ void minimum_statistics( move32(); /* exponent msCurrentMinSubWindow[j]: CNG_S */ BASOP_SATURATE_WARNING_OFF_EVS; -#ifdef BASOP_NOGLOB msCurrentMinSubWindow[j] = L_shl_o( Mpy_32_32( scalar, msBminSubWin[j] ), 5, &Overflow ); -#else /* BASOP_NOGLOB */ - msCurrentMinSubWindow[j] = L_shl( Mpy_32_32( scalar, msBminSubWin[j] ), 5 ); -#endif /* BASOP_NOGLOB */ move32(); BASOP_SATURATE_WARNING_ON_EVS; } @@ -1327,11 +1305,7 @@ void minimum_statistics_fx( /* use absolute value to avoid -1.0 x -1.0 multiplications */ s2 = norm_l( scalar2 ); } -#ifdef BASOP_NOGLOB scalar216 = round_fx_o( L_shl_o( scalar2, s2, &Overflow ), &Overflow ); -#else - scalar216 = round_fx( L_shl( scalar2, s2 ) ); -#endif scalar2 = L_mult( scalar216, scalar216 ); /* find common exponent */ @@ -1479,11 +1453,7 @@ void minimum_statistics_fx( s2 = s_min( s2, WORD32_BITS - 1 ); /* beta: scaled by s2 */ -#ifdef BASOP_NOGLOB tmp16 = round_fx_o( L_shl_o( tmp, s1, &Overflow ), &Overflow ); -#else - tmp16 = round_fx( L_shl( tmp, s1 ) ); -#endif beta = mult_r( tmp16, tmp16 ); /* scalar3: scaled by s3 */ @@ -1571,11 +1541,7 @@ void minimum_statistics_fx( move32(); /* exponent msCurrentMinSubWindow[j]: CNG_S */ BASOP_SATURATE_WARNING_OFF_EVS; -#ifdef BASOP_NOGLOB msCurrentMinSubWindow[j] = L_shl_o( Mpy_32_32( scalar, msBminSubWin[j] ), 5, &Overflow ); -#else /* BASOP_NOGLOB */ - msCurrentMinSubWindow[j] = L_shl( Mpy_32_32( scalar, msBminSubWin[j] ), 5 ); -#endif /* BASOP_NOGLOB */ move32(); BASOP_SATURATE_WARNING_ON_EVS; } @@ -2044,11 +2010,7 @@ void scalebands( s = norm_l( tmp ); s1 = sub( delta_s, s ); -#ifdef BASOP_NOGLOB delta = round_fx_sat( L_shl_sat( tmp, s ) ); // Q(14+s) -#else - delta = round_fx( L_shl( tmp, s ) ); -#endif /* Choose scale such that the interpolation start and end point both are representable and add 1 additional bit hr. */ delta_s = sub( s_min( norm_l( partpow[j - 1] ), norm_l( partpow[j] ) ), 1 ); val = L_shl( partpow[j - 1], delta_s ); @@ -2192,11 +2154,7 @@ void scalebands_fx( s = norm_l( tmp ); s1 = sub( delta_s, s ); -#ifdef BASOP_NOGLOB delta = round_fx_sat( L_shl_sat( tmp, s ) ); // Q(14+s) -#else - delta = round_fx( L_shl( tmp, s ) ); -#endif /* Choose scale such that the interpolation start and end point both are representable and add 1 additional bit hr. */ delta_s = sub( s_min( norm_l( partpow[j - 1] ), norm_l( partpow[j] ) ), 1 ); val = L_shl( partpow[j - 1], delta_s ); @@ -2306,11 +2264,7 @@ static void getmidbands( move16(); FOR( j = 0; j < npart; j++ ) { -#ifdef BASOP_NOGLOB psize_norm[j] = shl_o( psize[j], shift, &Overflow ); // Q(15 - psize_norm_exp) -#else /* BASOP_NOGLOB */ - psize_norm[j] = shl( psize[j], shift ); -#endif move16(); } /* minimum_statistics needs fixed exponent of 6 */ @@ -2364,13 +2318,8 @@ void AnalysisSTFT( { move32(); move32(); -#ifdef BASOP_NOGLOB fftBuffer[i + len] = L_mult( shr_sat( timeDomainInput[i], Q ), mult_r( olapWin[i].v.re, 23170 /*1.4142135623730950488016887242097 Q14*/ ) ); fftBuffer[i + len + len2] = L_mult( shr_sat( timeDomainInput[i + len2], Q ), mult_r( olapWin[len2 - 1 - i].v.im, 23170 /*1.4142135623730950488016887242097 Q14*/ ) ); -#else - fftBuffer[i + len] = L_mult( shr( timeDomainInput[i], Q ), mult_r( olapWin[i].v.re, 23170 /*1.4142135623730950488016887242097 Q14*/ ) ); - fftBuffer[i + len + len2] = L_mult( shr( timeDomainInput[i + len2], Q ), mult_r( olapWin[len2 - 1 - i].v.im, 23170 /*1.4142135623730950488016887242097 Q14*/ ) ); -#endif } /* Perform FFT */ @@ -2378,11 +2327,7 @@ void AnalysisSTFT( FOR( i = 0; i < len; i++ ) { -#ifdef BASOP_NOGLOB olapBuffer[i] = shr_sat( timeDomainInput[sub( hFdCngCom->frameSize, len ) + i], Q ); -#else - olapBuffer[i] = shr( timeDomainInput[sub( hFdCngCom->frameSize, len ) + i], Q ); -#endif move16(); } } @@ -3064,11 +3009,7 @@ void lpc_from_spectrum( maxVal = L_max( maxVal, L_abs( powspec[i] ) ); } s1 = norm_l( maxVal ); -#ifdef BASOP_NOGLOB nf = L_shr_r_sat( 1099511680l /*1e-3f Q40*/, add( sub( powspec_exp, s1 ), 9 ) ); -#else - nf = L_shr_r( 1099511680l /*1e-3f Q40*/, add( sub( powspec_exp, s1 ), 9 ) ); -#endif ptr = fftBuffer; pti = fftBuffer + 1; diff --git a/lib_com/fft.c b/lib_com/fft.c index be42d29cbf7914d72d4dc9def11afe41019a9359..e262f3909f179ea67b91c160866b1f62cd2b411a 100644 --- a/lib_com/fft.c +++ b/lib_com/fft.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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,7 +39,7 @@ #include "options.h" #include #include "cnst.h" -#include "prot.h" +#include "prot_fx.h" #include "rom_com.h" #include "wmc_auto.h" diff --git a/lib_com/fft_cldfb_fx.c b/lib_com/fft_cldfb_fx.c index 80e643362413412f0b5560b715917cd7a6eccb00..b26b1bc9f43782686e744fef2c90db2d70157cc9 100644 --- a/lib_com/fft_cldfb_fx.c +++ b/lib_com/fft_cldfb_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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_com/fft_evs.c b/lib_com/fft_evs.c index e53404f0b7f4a8d0cdc9ed405d74f91f119a51c2..94c2dea8ff0a7df4fc62fb898eb379e5d2d31a79 100644 --- a/lib_com/fft_evs.c +++ b/lib_com/fft_evs.c @@ -505,7 +505,7 @@ static void fft15_with_cmplx_data( cmplx *inp_data /*Qx*/ ) */ void fft16( Word32 *re, Word32 *im, Word16 s, Word16 bScale ) { - int i; + Word16 i; if ( s == 2 ) { fft16_with_cmplx_data( (cmplx *) re, bScale ); diff --git a/lib_com/fft_fx.c b/lib_com/fft_fx.c index c4237bcc9b2efce09f1c19e027f163bfcd63c2b0..7b63e9c679ce1219a018d92196ed50bc04861795 100644 --- a/lib_com/fft_fx.c +++ b/lib_com/fft_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other @@ -44,7 +44,7 @@ #include "options.h" #include #include "cnst.h" -// #include "prot.h" +// #include "prot_fx.h" #include "prot_fx.h" //#include "cnst_fx.h" #include "rom_com.h" @@ -4727,6 +4727,16 @@ static void fft_len16( cmplx t[4]; cmplx y[16]; +#ifdef OPT_STEREO_32KBPS_V1 + s[0] = x[0]; // Qx + move64(); + s[1] = x[4]; // Qx + move64(); + s[2] = x[8]; // Qx + move64(); + s[3] = x[12]; // Qx + move64(); +#else /* OPT_STEREO_32KBPS_V1 */ s[0] = CL_shr( x[0], SCALEFACTOR16 ); // Qx move64(); s[1] = CL_shr( x[4], SCALEFACTOR16 ); // Qx @@ -4735,6 +4745,7 @@ static void fft_len16( move64(); s[3] = CL_shr( x[12], SCALEFACTOR16 ); // Qx move64(); +#endif /* OPT_STEREO_32KBPS_V1 */ t[0] = CL_add( s[0], s[2] ); move64(); @@ -4754,6 +4765,16 @@ static void fft_len16( y[3] = CL_add( t[1], t[3] ); move64(); +#ifdef OPT_STEREO_32KBPS_V1 + s[0] = x[1]; // Qx + move64(); + s[1] = x[5]; // Qx + move64(); + s[2] = x[9]; // Qx + move64(); + s[3] = x[13]; // Qx + move64(); +#else /* OPT_STEREO_32KBPS_V1 */ s[0] = CL_shr( x[1], SCALEFACTOR16 ); // Qx move64(); s[1] = CL_shr( x[5], SCALEFACTOR16 ); // Qx @@ -4762,6 +4783,7 @@ static void fft_len16( move64(); s[3] = CL_shr( x[13], SCALEFACTOR16 ); // Qx move64(); +#endif /* OPT_STEREO_32KBPS_V1 */ t[0] = CL_add( s[0], s[2] ); move64(); @@ -4781,6 +4803,16 @@ static void fft_len16( y[7] = CL_add( t[1], t[3] ); move64(); +#ifdef OPT_STEREO_32KBPS_V1 + s[0] = x[2]; // Qx + move64(); + s[1] = x[6]; // Qx + move64(); + s[2] = x[10]; // Qx + move64(); + s[3] = x[14]; // Qx + move64(); +#else /* OPT_STEREO_32KBPS_V1 */ s[0] = CL_shr( x[2], SCALEFACTOR16 ); // Qx move64(); s[1] = CL_shr( x[6], SCALEFACTOR16 ); // Qx @@ -4789,6 +4821,7 @@ static void fft_len16( move64(); s[3] = CL_shr( x[14], SCALEFACTOR16 ); // Qx move64(); +#endif /* OPT_STEREO_32KBPS_V1 */ t[0] = CL_add( s[0], s[2] ); move64(); @@ -4810,6 +4843,16 @@ static void fft_len16( y[11] = CL_add( t[1], t[3] ); move64(); +#ifdef OPT_STEREO_32KBPS_V1 + s[0] = x[3]; // Qx + move64(); + s[1] = x[7]; // Qx + move64(); + s[2] = x[11]; // Qx + move64(); + s[3] = x[15]; // Qx + move64(); +#else /* OPT_STEREO_32KBPS_V1 */ s[0] = CL_shr( x[3], SCALEFACTOR16 ); // Qx move64(); s[1] = CL_shr( x[7], SCALEFACTOR16 ); // Qx @@ -4818,6 +4861,7 @@ static void fft_len16( move64(); s[3] = CL_shr( x[15], SCALEFACTOR16 ); // Qx move64(); +#endif /* OPT_STEREO_32KBPS_V1 */ t[0] = CL_add( s[0], s[2] ); move64(); @@ -4978,6 +5022,18 @@ static void fft_len20_fx( cmplx tt[4]; cmplx y[20]; +#ifdef OPT_STEREO_32KBPS_V1 + xx[0] = x[0]; // Qx + move64(); + xx[1] = x[16]; // Qx + move64(); + xx[2] = x[12]; // Qx + move64(); + xx[3] = x[8]; // Qx + move64(); + xx[4] = x[4]; // Qx + move64(); +#else /* OPT_STEREO_32KBPS_V1 */ xx[0] = CL_shr( x[0], SCALEFACTOR20 ); // Qx move64(); xx[1] = CL_shr( x[16], SCALEFACTOR20 ); // Qx @@ -4988,6 +5044,7 @@ static void fft_len20_fx( move64(); xx[4] = CL_shr( x[4], SCALEFACTOR20 ); // Qx move64(); +#endif /* OPT_STEREO_32KBPS_V1 */ s[0] = CL_add( xx[1], xx[4] ); move64(); @@ -5023,6 +5080,18 @@ static void fft_len20_fx( y[12] = CL_msu_j( s[2], s[3] ); move64(); +#ifdef OPT_STEREO_32KBPS_V1 + xx[0] = x[5]; + move64(); + xx[1] = x[1]; + move64(); + xx[2] = x[17]; + move64(); + xx[3] = x[13]; + move64(); + xx[4] = x[9]; + move64(); +#else /* OPT_STEREO_32KBPS_V1 */ xx[0] = CL_shr( x[5], SCALEFACTOR20 ); move64(); xx[1] = CL_shr( x[1], SCALEFACTOR20 ); @@ -5033,6 +5102,7 @@ static void fft_len20_fx( move64(); xx[4] = CL_shr( x[9], SCALEFACTOR20 ); move64(); +#endif /* OPT_STEREO_32KBPS_V1 */ s[0] = CL_add( xx[1], xx[4] ); move64(); @@ -5068,6 +5138,18 @@ static void fft_len20_fx( y[13] = CL_msu_j( s[2], s[3] ); move64(); +#ifdef OPT_STEREO_32KBPS_V1 + xx[0] = x[10]; + move64(); + xx[1] = x[6]; + move64(); + xx[2] = x[2]; + move64(); + xx[3] = x[18]; + move64(); + xx[4] = x[14]; + move64(); +#else /* OPT_STEREO_32KBPS_V1 */ xx[0] = CL_shr( x[10], SCALEFACTOR20 ); move64(); xx[1] = CL_shr( x[6], SCALEFACTOR20 ); @@ -5078,6 +5160,7 @@ static void fft_len20_fx( move64(); xx[4] = CL_shr( x[14], SCALEFACTOR20 ); move64(); +#endif /* OPT_STEREO_32KBPS_V1 */ s[0] = CL_add( xx[1], xx[4] ); move64(); @@ -5113,6 +5196,18 @@ static void fft_len20_fx( y[14] = CL_msu_j( s[2], s[3] ); move64(); +#ifdef OPT_STEREO_32KBPS_V1 + xx[0] = x[15]; + move64(); + xx[1] = x[11]; + move64(); + xx[2] = x[7]; + move64(); + xx[3] = x[3]; + move64(); + xx[4] = x[19]; + move64(); +#else /* OPT_STEREO_32KBPS_V1 */ xx[0] = CL_shr( x[15], SCALEFACTOR20 ); move64(); xx[1] = CL_shr( x[11], SCALEFACTOR20 ); @@ -5123,6 +5218,7 @@ static void fft_len20_fx( move64(); xx[4] = CL_shr( x[19], SCALEFACTOR20 ); move64(); +#endif /* OPT_STEREO_32KBPS_V1 */ s[0] = CL_add( xx[1], xx[4] ); move64(); @@ -6501,6 +6597,239 @@ static void fft_lenN( cmplx s[8]; cmplx y[8]; +#ifdef OPT_STEREO_32KBPS_V1 + y[1] = xx[1 * dim1]; + move64(); + y[2] = xx[2 * dim1]; + move64(); + y[3] = xx[3 * dim1]; + move64(); + y[4] = xx[4 * dim1]; + move64(); + y[5] = xx[5 * dim1]; + move64(); + y[6] = xx[6 * dim1]; + move64(); + y[7] = xx[7 * dim1]; + move64(); + + test(); + test(); + IF( EQ_16( dim1, 8 ) || EQ_16( dim1, 16 ) || EQ_16( dim1, 32 ) ) + { + FOR( i = 0; i < dim1; i++ ) + { + { + y[0] = xx[i]; + move64(); + }; + IF( i > 0 ) + { + { + y[1] = CL_mac_j( CL_scale( xx[( i + ( 1 * dim1 ) )], W[( ( ( sc * i ) + ( ( sc * 1 ) * dim1 ) ) - Woff )] ), + CL_scale( xx[( i + ( 1 * dim1 ) )], W[( ( ( ( sc * i ) + ( ( sc * 1 ) * dim1 ) ) + 1 ) - Woff )] ) ); // Qx + move64(); + }; + { + y[2] = CL_mac_j( CL_scale( xx[( i + ( 2 * dim1 ) )], W[( ( ( sc * i ) + ( ( sc * 2 ) * dim1 ) ) - Woff )] ), + CL_scale( xx[( i + ( 2 * dim1 ) )], W[( ( ( ( sc * i ) + ( ( sc * 2 ) * dim1 ) ) + 1 ) - Woff )] ) ); // Qx + move64(); + }; + { + y[3] = CL_mac_j( CL_scale( xx[( i + ( 3 * dim1 ) )], W[( ( ( sc * i ) + ( ( sc * 3 ) * dim1 ) ) - Woff )] ), + CL_scale( xx[( i + ( 3 * dim1 ) )], W[( ( ( ( sc * i ) + ( ( sc * 3 ) * dim1 ) ) + 1 ) - Woff )] ) ); // Qx + move64(); + }; + { + y[4] = CL_mac_j( CL_scale( xx[( i + ( 4 * dim1 ) )], W[( ( ( sc * i ) + ( ( sc * 4 ) * dim1 ) ) - Woff )] ), + CL_scale( xx[( i + ( 4 * dim1 ) )], W[( ( ( ( sc * i ) + ( ( sc * 4 ) * dim1 ) ) + 1 ) - Woff )] ) ); // Qx + move64(); + }; + { + y[5] = CL_mac_j( CL_scale( xx[( i + ( 5 * dim1 ) )], W[( ( ( sc * i ) + ( ( sc * 5 ) * dim1 ) ) - Woff )] ), + CL_scale( xx[( i + ( 5 * dim1 ) )], W[( ( ( ( sc * i ) + ( ( sc * 5 ) * dim1 ) ) + 1 ) - Woff )] ) ); // Qx + move64(); + }; + { + y[6] = CL_mac_j( CL_scale( xx[( i + ( 6 * dim1 ) )], W[( ( ( sc * i ) + ( ( sc * 6 ) * dim1 ) ) - Woff )] ), + CL_scale( xx[( i + ( 6 * dim1 ) )], W[( ( ( ( sc * i ) + ( ( sc * 6 ) * dim1 ) ) + 1 ) - Woff )] ) ); // Qx + move64(); + }; + { + y[7] = CL_mac_j( CL_scale( xx[( i + ( 7 * dim1 ) )], W[( ( ( sc * i ) + ( ( sc * 7 ) * dim1 ) ) - Woff )] ), + CL_scale( xx[( i + ( 7 * dim1 ) )], W[( ( ( ( sc * i ) + ( ( sc * 7 ) * dim1 ) ) + 1 ) - Woff )] ) ); // Qx + move64(); + }; + } + + t[0] = CL_add( y[0], y[4] ); + move64(); + t[1] = CL_sub( y[0], y[4] ); + move64(); + t[2] = CL_add( y[1], y[5] ); + move64(); + t[3] = CL_sub( y[1], y[5] ); + move64(); + t[4] = CL_add( y[2], y[6] ); + move64(); + t[5] = CL_sub( y[2], y[6] ); + move64(); + t[6] = CL_add( y[3], y[7] ); + move64(); + t[7] = CL_sub( y[3], y[7] ); + move64(); + + s[0] = CL_add( t[0], t[4] ); + move64(); + s[2] = CL_sub( t[0], t[4] ); + move64(); + s[4] = CL_mac_j( t[1], t[5] ); + move64(); + s[5] = CL_msu_j( t[1], t[5] ); + move64(); + s[1] = CL_add( t[2], t[6] ); + move64(); + s[3] = CL_swap_real_imag( CL_sub( CL_conjugate( t[2] ), CL_conjugate( t[6] ) ) ); + move64(); + + t[0] = CL_swap_real_imag( CL_add( t[3], t[7] ) ); + move64(); + t[1] = CL_sub( t[3], t[7] ); + move64(); + + s[6] = CL_scale( CL_add( CL_conjugate( t[0] ), t[1] ), FFT_C81 ); // Qx + move64(); + s[7] = CL_scale( CL_sub( t[0], CL_conjugate( t[1] ) ), FFT_C81 ); // Qx + move64(); + s[7] = CL_conjugate( s[7] ); + move64(); + + x[i] = CL_add( s[0], s[1] ); + move64(); + x[( i + ( 1 * dim1 ) )] = CL_add( s[5], s[6] ); + move64(); + x[( i + ( 2 * dim1 ) )] = CL_sub( s[2], s[3] ); + move64(); + x[( i + ( 3 * dim1 ) )] = CL_add( s[4], s[7] ); + move64(); + x[( i + ( 4 * dim1 ) )] = CL_sub( s[0], s[1] ); + move64(); + x[( i + ( 5 * dim1 ) )] = CL_sub( s[5], s[6] ); + move64(); + x[( i + ( 6 * dim1 ) )] = CL_add( s[2], s[3] ); + move64(); + x[( i + ( 7 * dim1 ) )] = CL_sub( s[4], s[7] ); + move64(); + } + } + ELSE + { + FOR( i = 0; i < dim1; i++ ) + { + { + y[0] = xx[i]; + move64(); + }; + IF( i > 0 ) + { + { + y[1] = CL_mac_j( CL_scale( xx[( i + ( 1 * dim1 ) )], W[( ( ( sc * i ) + ( ( ( sc * 1 ) * dim1 ) << 1 ) ) - Woff )] ), + CL_scale( xx[( i + ( 1 * dim1 ) )], W[( ( ( ( sc * i ) + ( ( ( sc * 1 ) * dim1 ) << 1 ) ) + 1 ) - Woff )] ) ); // Qx + move64(); + }; + { + y[2] = CL_mac_j( CL_scale( xx[( i + ( 2 * dim1 ) )], W[( ( ( sc * i ) + ( ( ( sc * 2 ) * dim1 ) << 1 ) ) - Woff )] ), + CL_scale( xx[( i + ( 2 * dim1 ) )], W[( ( ( ( sc * i ) + ( ( ( sc * 2 ) * dim1 ) << 1 ) ) + 1 ) - Woff )] ) ); // Qx + move64(); + }; + { + y[3] = CL_mac_j( CL_scale( xx[( i + ( 3 * dim1 ) )], W[( ( ( sc * i ) + ( ( ( sc * 3 ) * dim1 ) << 1 ) ) - Woff )] ), + CL_scale( xx[( i + ( 3 * dim1 ) )], W[( ( ( ( sc * i ) + ( ( ( sc * 3 ) * dim1 ) << 1 ) ) + 1 ) - Woff )] ) ); // Qx + move64(); + }; + { + y[4] = CL_mac_j( CL_scale( xx[( i + ( 4 * dim1 ) )], W[( ( ( sc * i ) + ( ( ( sc * 4 ) * dim1 ) << 1 ) ) - Woff )] ), + CL_scale( xx[( i + ( 4 * dim1 ) )], W[( ( ( ( sc * i ) + ( ( ( sc * 4 ) * dim1 ) << 1 ) ) + 1 ) - Woff )] ) ); // Qx + move64(); + }; + { + y[5] = CL_mac_j( CL_scale( xx[( i + ( 5 * dim1 ) )], W[( ( ( sc * i ) + ( ( ( sc * 5 ) * dim1 ) << 1 ) ) - Woff )] ), + CL_scale( xx[( i + ( 5 * dim1 ) )], W[( ( ( ( sc * i ) + ( ( ( sc * 5 ) * dim1 ) << 1 ) ) + 1 ) - Woff )] ) ); // Qx + move64(); + }; + { + y[6] = CL_mac_j( CL_scale( xx[( i + ( 6 * dim1 ) )], W[( ( ( sc * i ) + ( ( ( sc * 6 ) * dim1 ) << 1 ) ) - Woff )] ), + CL_scale( xx[( i + ( 6 * dim1 ) )], W[( ( ( ( sc * i ) + ( ( ( sc * 6 ) * dim1 ) << 1 ) ) + 1 ) - Woff )] ) ); // Qx + move64(); + }; + { + y[7] = CL_mac_j( CL_scale( xx[( i + ( 7 * dim1 ) )], W[( ( ( sc * i ) + ( ( ( sc * 7 ) * dim1 ) << 1 ) ) - Woff )] ), + CL_scale( xx[( i + ( 7 * dim1 ) )], W[( ( ( ( sc * i ) + ( ( ( sc * 7 ) * dim1 ) << 1 ) ) + 1 ) - Woff )] ) ); // Qx + move64(); + }; + } + + t[0] = CL_add( y[0], y[4] ); + move64(); + t[1] = CL_sub( y[0], y[4] ); + move64(); + t[2] = CL_add( y[1], y[5] ); + move64(); + t[3] = CL_sub( y[1], y[5] ); + move64(); + t[4] = CL_add( y[2], y[6] ); + move64(); + t[5] = CL_sub( y[2], y[6] ); + move64(); + t[6] = CL_add( y[3], y[7] ); + move64(); + t[7] = CL_sub( y[3], y[7] ); + move64(); + + s[0] = CL_add( t[0], t[4] ); + move64(); + s[2] = CL_sub( t[0], t[4] ); + move64(); + s[4] = CL_mac_j( t[1], t[5] ); + move64(); + s[5] = CL_msu_j( t[1], t[5] ); + move64(); + s[1] = CL_add( t[2], t[6] ); + move64(); + s[3] = CL_swap_real_imag( CL_sub( CL_conjugate( t[2] ), CL_conjugate( t[6] ) ) ); + move64(); + + t[0] = CL_swap_real_imag( CL_add( t[3], t[7] ) ); + move64(); + t[1] = CL_sub( t[3], t[7] ); + move64(); + + s[6] = CL_scale( CL_add( CL_conjugate( t[0] ), t[1] ), FFT_C81 ); // Qx + move64(); + s[7] = CL_scale( CL_sub( t[0], CL_conjugate( t[1] ) ), FFT_C81 ); // Qx + move64(); + s[7] = CL_conjugate( s[7] ); + move64(); + + x[i] = CL_add( s[0], s[1] ); + move64(); + x[( i + ( 1 * dim1 ) )] = CL_add( s[5], s[6] ); + move64(); + x[( i + ( 2 * dim1 ) )] = CL_sub( s[2], s[3] ); + move64(); + x[( i + ( 3 * dim1 ) )] = CL_add( s[4], s[7] ); + move64(); + x[( i + ( 4 * dim1 ) )] = CL_sub( s[0], s[1] ); + move64(); + x[( i + ( 5 * dim1 ) )] = CL_sub( s[5], s[6] ); + move64(); + x[( i + ( 6 * dim1 ) )] = CL_add( s[2], s[3] ); + move64(); + x[( i + ( 7 * dim1 ) )] = CL_sub( s[4], s[7] ); + move64(); + } + } +#else /* OPT_STEREO_32KBPS_V1 */ test(); test(); test(); @@ -6781,6 +7110,7 @@ static void fft_lenN( move64(); } } +#endif /* OPT_STEREO_32KBPS_V1 */ BREAK; } @@ -7173,7 +7503,11 @@ void rfft_fx( move32(); x[( length - ( i << 1 ) )] = Mpy_32_16_1( L_add( t1, t3 ), 16384 /*0.5.Q15*/ ); move32(); +#ifdef OPT_STEREO_32KBPS_V1 + x[( ( length - ( i << 1 ) ) + 1 )] = Mpy_32_16_1( L_add( t2, t4 ), -16384 /*0.5.Q15*/ ); +#else /* OPT_STEREO_32KBPS_V1 */ x[( ( length - ( i << 1 ) ) + 1 )] = Mpy_32_16_1( L_negate( L_add( t2, t4 ) ), 16384 /*0.5.Q15*/ ); +#endif /* OPT_STEREO_32KBPS_V1 */ move32(); } @@ -7257,7 +7591,7 @@ Word16 find_guarded_bits_fx( Word32 n ) } } -Word16 L_norm_arr( Word32 *arr, Word16 size ) +Word16 L_norm_arr( const Word32 *arr, Word16 size ) { Word16 q = 31; move16(); @@ -7282,6 +7616,46 @@ Word16 L_norm_arr( Word32 *arr, Word16 size ) return q; } +Word16 norm_arr( Word16 *arr, Word16 size ) +{ + Word16 q = 15; + Word16 exp = 0; + move16(); + move16(); + FOR( Word16 i = 0; i < size; i++ ) + { + if ( arr[i] != 0 ) + { + exp = norm_s( arr[i] ); + } + if ( arr[i] != 0 ) + { + q = s_min( q, exp ); + } + } + return q; +} + +Word16 W_norm_arr( Word64 *arr, Word16 size ) +{ + Word16 q = 63; + Word16 exp = 0; + move16(); + move16(); + FOR( Word16 i = 0; i < size; i++ ) + { + if ( arr[i] != 0 ) + { + exp = W_norm( arr[i] ); + } + if ( arr[i] != 0 ) + { + q = s_min( q, exp ); + } + } + return q; +} + Word16 get_min_scalefactor( Word32 x, Word32 y ) { #ifndef FIX_1104_OPT_GETMINSCALEFAC diff --git a/lib_com/fft_fx_evs.c b/lib_com/fft_fx_evs.c index e2fce166cce3c92ef431fcb91aba2f248974075e..b6f2bb2acee04e556e60e2a0cd36c85d7c81763d 100644 --- a/lib_com/fft_fx_evs.c +++ b/lib_com/fft_fx_evs.c @@ -1096,34 +1096,18 @@ static void fft5_shift4_16fx( move16(); T3 = zRe[i4]; move16(); -#ifdef BASOP_NOGLOB T4 = add_sat( T2, T3 ); -#else - T4 = add( T2, T3 ); -#endif T5 = zRe[i2]; move16(); T6 = zRe[i3]; move16(); -#ifdef BASOP_NOGLOB T7 = add_sat( T5, T6 ); T8 = add_sat( T4, T7 ); Tt = sub_sat( T5, T6 ); -#else - T7 = add( T5, T6 ); - T8 = add( T4, T7 ); - Tt = sub( T5, T6 ); -#endif /* T9 = KP559016994 * (T4 - T7); */ -#ifdef BASOP_NOGLOB L_tmp = Mult_32_16( KP559016994_16FX, sub_sat( T4, T7 ) ); // Q(16 +x) T9 = round_fx_sat( L_tmp ); // Qx Ts = sub_sat( T2, T3 ); -#else - L_tmp = Mult_32_16( KP559016994_16FX, sub( T4, T7 ) ); - T9 = round_fx( L_tmp ); - Ts = sub( T2, T3 ); -#endif T2 = zIm[i1]; move16(); @@ -1134,52 +1118,27 @@ static void fft5_shift4_16fx( move16(); T6 = zIm[i3]; move16(); -#ifdef BASOP_NOGLOB T7 = add_sat( T5, T6 ); Te = sub_sat( T2, T3 ); Tp = add_sat( T4, T7 ); Th = sub_sat( T5, T6 ); -#else - T7 = add( T5, T6 ); - Te = sub( T2, T3 ); - Tp = add( T4, T7 ); - Th = sub( T5, T6 ); -#endif -#ifdef BASOP_NOGLOB /* Tn = KP559016994 * (T4 - T7); */ L_tmp = Mult_32_16( KP559016994_16FX, sub_sat( T4, T7 ) ); // Q(16 +x) Tn = round_fx_sat( L_tmp ); // Qx zRe[i0] = add_sat( T1, T8 ); move16(); zIm[i0] = add_sat( To, Tp ); -#else - /* Tn = KP559016994 * (T4 - T7); */ - L_tmp = Mult_32_16( KP559016994_16FX, sub( T4, T7 ) ); - Tn = round_fx( L_tmp ); - zRe[i0] = add( T1, T8 ); - move16(); - zIm[i0] = add( To, Tp ); -#endif move16(); /* T2 = KP951056516*Te + KP587785252*Th; */ L_tmp = Mult_32_16( KP951056516_16FX, Te ); // Q(16 +x) L_tmp = Madd_32_16( L_tmp, KP587785252_16FX, Th ); // Q(16 +x) -#ifdef BASOP_NOGLOB - T2 = round_fx_sat( L_tmp ); // Qx -#else - T2 = round_fx( L_tmp ); -#endif + T2 = round_fx_sat( L_tmp ); // Qx /*T3 = KP951056516*Th - KP587785252*Te; */ L_tmp = Mult_32_16( KP951056516_16FX, Th ); // Q(16 +x) L_tmp = Msub_32_16( L_tmp, KP587785252_16FX, Te ); // Q(16 +x) -#ifdef BASOP_NOGLOB - T3 = round_fx_sat( L_tmp ); // Qx -#else - T3 = round_fx( L_tmp ); -#endif -#ifdef BASOP_NOGLOB + T3 = round_fx_sat( L_tmp ); // Qx T6 = sub_sat( T1, shr_sat( T8, 2 ) ); T4 = add_sat( T9, T6 ); T5 = sub_sat( T6, T9 ); @@ -1191,38 +1150,16 @@ static void fft5_shift4_16fx( move16(); zRe[i3] = sub_sat( T5, T3 ); move16(); -#else - T6 = sub( T1, shr( T8, 2 ) ); - T4 = add( T9, T6 ); - T5 = sub( T6, T9 ); - zRe[i1] = sub( T4, T2 ); - move16(); - zRe[i2] = add( T5, T3 ); - move16(); - zRe[i4] = add( T4, T2 ); - move16(); - zRe[i3] = sub( T5, T3 ); - move16(); -#endif /* T2 = KP951056516 * Ts + KP587785252 * Tt; */ L_tmp = Mult_32_16( KP951056516_16FX, Ts ); // Q(16 +x) L_tmp = Madd_32_16( L_tmp, KP587785252_16FX, Tt ); // Q(16 +x) -#ifdef BASOP_NOGLOB - T2 = round_fx_sat( L_tmp ); // Qx -#else - T2 = round_fx( L_tmp ); -#endif + T2 = round_fx_sat( L_tmp ); // Qx /* T3 = KP951056516 * Tt - KP587785252 * Ts; */ L_tmp = Mult_32_16( KP951056516_16FX, Tt ); // Q(16 +x) L_tmp = Msub_32_16( L_tmp, KP587785252_16FX, Ts ); // Q(16 +x) -#ifdef BASOP_NOGLOB - T3 = round_fx_sat( L_tmp ); // Qx -#else - T3 = round_fx( L_tmp ); -#endif -#ifdef BASOP_NOGLOB - T6 = sub_sat( To, shr( Tp, 2 ) ); // To - (Tp / 4) + T3 = round_fx_sat( L_tmp ); // Qx + T6 = sub_sat( To, shr( Tp, 2 ) ); // To - (Tp / 4) T4 = add_sat( Tn, T6 ); T5 = sub_sat( T6, Tn ); zIm[i4] = sub_sat( T4, T2 ); @@ -1233,19 +1170,6 @@ static void fft5_shift4_16fx( move16(); zIm[i3] = add_sat( T3, T5 ); move16(); -#else - T6 = sub( To, shr( Tp, 2 ) ); - T4 = add( Tn, T6 ); - T5 = sub( T6, Tn ); - zIm[i4] = sub( T4, T2 ); - move16(); - zIm[i2] = sub( T5, T3 ); - move16(); - zIm[i1] = add( T2, T4 ); - move16(); - zIm[i3] = add( T3, T5 ); - move16(); -#endif return; } @@ -1287,7 +1211,6 @@ static void fft5_32_16fx( T3 = zRe[i4]; // Qx move16(); -#ifdef BASOP_NOGLOB T4 = add_sat( T2, T3 ); T5 = zRe[i2]; move16(); @@ -1296,17 +1219,6 @@ static void fft5_32_16fx( T7 = add_o( T5, T6, &Overflow ); T8 = add_o( T4, T7, &Overflow ); Tt = sub_o( T5, T6, &Overflow ); -#else - T4 = add( T2, T3 ); - T5 = zRe[i2]; - move16(); - T6 = zRe[i3]; - move16(); - T7 = add( T5, T6 ); - T8 = add( T4, T7 ); - Tt = sub( T5, T6 ); -#endif -#ifdef BASOP_NOGLOB /* T9 = KP559016994 * (T4 - T7); */ L_tmp = Mult_32_16( KP559016994_16FX, sub_sat( T4, T7 ) ); // Q(16 +x) T9 = round_fx_sat( L_tmp ); // Qx @@ -1327,43 +1239,13 @@ static void fft5_32_16fx( Th = sub_sat( T5, T6 ); L_tmp = Mult_32_16( KP559016994_16FX, sub_sat( T4, T7 ) ); // Q(16 +x) Tn = round_fx_sat( L_tmp ); // Qx -#else - /* T9 = KP559016994 * (T4 - T7); */ - L_tmp = Mult_32_16( KP559016994_16FX, sub( T4, T7 ) ); - T9 = round_fx( L_tmp ); - Ts = sub( T2, T3 ); - - T2 = zIm[i1]; - move16(); - T3 = zIm[i4]; - move16(); - T4 = add( T2, T3 ); - T5 = zIm[i2]; - move16(); - T6 = zIm[i3]; - move16(); - T7 = add( T5, T6 ); - Te = sub( T2, T3 ); - Tp = add( T4, T7 ); - Th = sub( T5, T6 ); - L_tmp = Mult_32_16( KP559016994_16FX, sub( T4, T7 ) ); - Tn = round_fx( L_tmp ); -#endif -#ifdef BASOP_NOGLOB zRe[i0] = add_o( T1, T8, &Overflow ); move16(); zIm[i0] = add_o( To, Tp, &Overflow ); move32(); -#else - zRe[i0] = add( T1, T8 ); - move16(); - zIm[i0] = add( To, Tp ); - move32(); -#endif -#ifdef BASOP_NOGLOB /*T2 = KP951056516*Te + KP587785252*Th; */ L_tmp = Mult_32_16( KP951056516_16FX, Te ); // Q(16 +x) L_tmp = Madd_32_16( L_tmp, KP587785252_16FX, Th ); // Q(16 +x) @@ -1387,31 +1269,6 @@ static void fft5_32_16fx( move32(); zRe[i4] = sub_o( T5, T3, &Overflow ); move32(); -#else - /*T2 = KP951056516*Te + KP587785252*Th; */ - L_tmp = Mult_32_16( KP951056516_16FX, Te ); - L_tmp = Madd_32_16( L_tmp, KP587785252_16FX, Th ); - T2 = round_fx( L_tmp ); - - /*T3 = KP951056516*Th - KP587785252*Te; */ - L_tmp = Mult_32_16( KP951056516_16FX, Th ); - L_tmp = Msub_32_16( L_tmp, KP587785252_16FX, Te ); - T3 = round_fx( L_tmp ); - - - T6 = sub( T1, shr( T8, 2 ) ); - T4 = add( T9, T6 ); - T5 = sub( T6, T9 ); - - zRe[i3] = sub( T4, T2 ); - move32(); - zRe[i1] = add( T5, T3 ); - move32(); - zRe[i2] = add( T4, T2 ); - move32(); - zRe[i4] = sub( T5, T3 ); - move32(); -#endif /* T2 = KP951056516 * Ts + KP587785252 * Tt; */ L_tmp = Mult_32_16( KP951056516_16FX, Ts ); // Q(16 +x) @@ -1422,7 +1279,6 @@ static void fft5_32_16fx( L_tmp = Mult_32_16( KP951056516_16FX, Tt ); // Q(16 +x) L_tmp = Msub_32_16( L_tmp, KP587785252_16FX, Ts ); // Q(16 +x) -#ifdef BASOP_NOGLOB T3 = round_fx_sat( L_tmp ); // Qx T6 = sub_sat( To, shr( Tp, 2 ) ); @@ -1436,21 +1292,6 @@ static void fft5_32_16fx( move16(); zIm[i4] = add_sat( T3, T5 ); move16(); -#else - T3 = round_fx( L_tmp ); - - T6 = sub( To, shr( Tp, 2 ) ); - T4 = add( Tn, T6 ); - T5 = sub( T6, Tn ); - zIm[i2] = sub( T4, T2 ); - move16(); - zIm[i1] = sub( T5, T3 ); - move16(); - zIm[i3] = add( T2, T4 ); - move16(); - zIm[i4] = add( T3, T5 ); - move16(); -#endif return; } @@ -1890,7 +1731,6 @@ static void cftfsub_16fx( { FOR( j = 0; j < l; j += 2 ) { -#ifdef BASOP_NOGLOB j1 = add_o( j, l, &Overflow ); x0r = sub_o( a[j], a[j1], &Overflow ); x0i = sub_o( a[j + 1], a[j1 + 1], &Overflow ); @@ -1902,19 +1742,6 @@ static void cftfsub_16fx( move16(); a[j1 + 1] = x0i; move16(); -#else - j1 = add( j, l ); - x0r = sub( a[j], a[j1] ); - x0i = sub( a[j + 1], a[j1 + 1] ); - a[j] = add( a[j], a[j1] ); - move16(); - a[j + 1] = add( a[j + 1], a[j1 + 1] ); - move16(); - a[j1] = x0r; - move16(); - a[j1 + 1] = x0i; - move16(); -#endif } } return; @@ -1940,7 +1767,6 @@ static void cft1st_16fx( move32(); #endif -#ifdef BASOP_NOGLOB x0r = add_o( a[0], a[2], &Overflow ); x0i = add_o( a[1], a[3], &Overflow ); x1r = sub_o( a[0], a[2], &Overflow ); @@ -1964,36 +1790,9 @@ static void cft1st_16fx( a[6] = add_o( x1r, x3i, &Overflow ); move16(); a[7] = sub_o( x1i, x3r, &Overflow ); -#else - x0r = add( a[0], a[2] ); - x0i = add( a[1], a[3] ); - x1r = sub( a[0], a[2] ); - x1i = sub( a[1], a[3] ); - x2r = add( a[4], a[6] ); - x2i = add( a[5], a[7] ); - x3r = sub( a[4], a[6] ); - x3i = sub( a[5], a[7] ); - a[0] = add( x0r, x2r ); - move16(); - a[1] = add( x0i, x2i ); - move16(); - a[4] = sub( x0r, x2r ); - move16(); - a[5] = sub( x0i, x2i ); - move16(); - a[2] = sub( x1r, x3i ); - move16(); - a[3] = add( x1i, x3r ); - move16(); - a[6] = add( x1r, x3i ); - move16(); - a[7] = sub( x1i, x3r ); - move16(); -#endif wk1r = w[2]; move32(); -#ifdef BASOP_NOGLOB x0r = add_o( a[8], a[10], &Overflow ); x0i = add_o( a[9], a[11], &Overflow ); x1r = sub_o( a[8], a[10], &Overflow ); @@ -2014,31 +1813,8 @@ static void cft1st_16fx( x0r = sub_o( x1r, x3i, &Overflow ); x0i = add_o( x1i, x3r, &Overflow ); tmp = sub_o( x0r, x0i, &Overflow ); -#else - x0r = add( a[8], a[10] ); - x0i = add( a[9], a[11] ); - x1r = sub( a[8], a[10] ); - x1i = sub( a[9], a[11] ); - x2r = add( a[12], a[14] ); - x2i = add( a[13], a[15] ); - x3r = sub( a[12], a[14] ); - x3i = sub( a[13], a[15] ); - a[8] = add( x0r, x2r ); - move16(); - a[9] = add( x0i, x2i ); - move16(); - a[12] = sub( x2i, x0i ); - move16(); - a[13] = sub( x0r, x2r ); - move16(); - - x0r = sub( x1r, x3i ); - x0i = add( x1i, x3r ); - tmp = sub( x0r, x0i ); -#endif L_tmp = Mult_32_16( wk1r, tmp ); /*Q(15+Qx+Q_edct) */ -#ifdef BASOP_NOGLOB a[10] = round_fx_o( L_shl_o( L_tmp, 1, &Overflow ), &Overflow ); /*Q(Qx+Q_edct) */ move16(); @@ -2058,23 +1834,6 @@ static void cft1st_16fx( L_tmp = Mult_32_16( wk1r, tmp ); /*Q(15+Qx+Q_edct) */ a[15] = round_fx_o( L_shl_o( L_tmp, 1, &Overflow ), &Overflow ); /*Q(Qx+Q_edct) */ move16(); -#else - a[10] = round_fx( L_shl( L_tmp, 1 ) ); /*Q(Qx+Q_edct) */ - - tmp = add( x0r, x0i ); - L_tmp = Mult_32_16( wk1r, tmp ); /*Q(15+Qx+Q_edct) */ - a[11] = round_fx( L_shl( L_tmp, 1 ) ); /* Q(Qx+Q_edct) */ - - x0r = add( x3i, x1r ); - x0i = sub( x3r, x1i ); - tmp = sub( x0i, x0r ); - L_tmp = Mult_32_16( wk1r, tmp ); /*Q(15+Qx+Q_edct) */ - a[14] = round_fx( L_shl( L_tmp, 1 ) ); /*Q(Qx+Q_edct) */ - - tmp = add( x0i, x0r ); - L_tmp = Mult_32_16( wk1r, tmp ); /*Q(15+Qx+Q_edct) */ - a[15] = round_fx( L_shl( L_tmp, 1 ) ); /*Q(Qx+Q_edct) */ -#endif k1 = 0; move16(); @@ -2097,7 +1856,6 @@ static void cft1st_16fx( L_tmp = L_shl( Mult_32_32( wk2i, wk1r ), 1 ); /*Q29 */ wk3i = L_sub( L_shl( L_tmp, 1 ), wk1i ); /*Q30 */ -#ifdef BASOP_NOGLOB x0r = add_o( a[j], a[j + 2], &Overflow ); x0i = add_o( a[j + 1], a[j + 3], &Overflow ); x1r = sub_o( a[j], a[j + 2], &Overflow ); @@ -2208,106 +1966,6 @@ static void cft1st_16fx( L_tmp = Madd_32_16( L_tmp, wk3i, x0r ); /*Q(15+Qx+Q_edct) */ a[j + 15] = round_fx_o( L_shl_o( L_tmp, 1, &Overflow ), &Overflow ); /*Q(Qx+Q_edct) */ move16(); -#else - x0r = add( a[j], a[j + 2] ); - x0i = add( a[j + 1], a[j + 3] ); - x1r = sub( a[j], a[j + 2] ); - x1i = sub( a[j + 1], a[j + 3] ); - x2r = add( a[j + 4], a[j + 6] ); - x2i = add( a[j + 5], a[j + 7] ); - x3r = sub( a[j + 4], a[j + 6] ); - x3i = sub( a[j + 5], a[j + 7] ); - a[j] = add( x0r, x2r ); - move16(); - a[j + 1] = add( x0i, x2i ); - move16(); - - x0r = sub( x0r, x2r ); - x0i = sub( x0i, x2i ); - L_tmp = Mult_32_16( wk2r, x0r ); /*Q(15+Qx+Q_edct) */ - L_tmp = Msub_32_16( L_tmp, wk2i, x0i ); /*Q(15+Qx+Q_edct) */ - a[j + 4] = round_fx( L_shl( L_tmp, 1 ) ); /*Q(Qx+Q_edct) */ - - L_tmp = Mult_32_16( wk2r, x0i ); /*Q(15+Qx+Q_edct) */ - L_tmp = Madd_32_16( L_tmp, wk2i, x0r ); /*Q(15+Qx+Q_edct) */ - a[j + 5] = round_fx( L_shl( L_tmp, 1 ) ); /*Q(Qx+Q_edct) */ - - x0r = sub( x1r, x3i ); - x0i = add( x1i, x3r ); - L_tmp = Mult_32_16( wk1r, x0r ); /*Q(15+Qx+Q_edct) */ - L_tmp = Msub_32_16( L_tmp, wk1i, x0i ); /*Q(15+Qx+Q_edct) */ - a[j + 2] = round_fx( L_shl( L_tmp, 1 ) ); /*Q(Qx+Q_edct) */ - - L_tmp = Mult_32_16( wk1r, x0i ); /*Q(15+Qx+Q_edct) */ - L_tmp = Madd_32_16( L_tmp, wk1i, x0r ); /*Q(15+Qx+Q_edct) */ - a[j + 3] = round_fx( L_shl( L_tmp, 1 ) ); /*Q(Qx+Q_edct) */ - - x0r = add( x1r, x3i ); - x0i = sub( x1i, x3r ); - L_tmp = Mult_32_16( wk3r, x0r ); /*Q(15+Qx+Q_edct) */ - L_tmp = Msub_32_16( L_tmp, wk3i, x0i ); /*Q(15+Qx+Q_edct) */ - a[j + 6] = round_fx( L_shl( L_tmp, 1 ) ); /*Q(Qx+Q_edct) */ - - L_tmp = Mult_32_16( wk3r, x0i ); /*Q(15+Qx+Q_edct) */ - L_tmp = Madd_32_16( L_tmp, wk3i, x0r ); /*Q(15+Qx+Q_edct) */ - a[j + 7] = round_fx( L_shl( L_tmp, 1 ) ); /*Q(Qx+Q_edct) */ - - wk1r = w[k2 + 2]; - move32(); - wk1i = w[k2 + 3]; - move32(); - L_tmp = L_shl( Mult_32_32( wk2r, wk1i ), 1 ); /*Q29 */ - wk3r = L_sub( wk1r, L_shl( L_tmp, 1 ) ); /*Q30 */ - - L_tmp = L_shl( Mult_32_32( wk2r, wk1r ), 1 ); /*Q29 */ - wk3i = L_sub( L_shl( L_tmp, 1 ), wk1i ); /*Q30 */ - - x0r = add( a[j + 8], a[j + 10] ); - x0i = add( a[j + 9], a[j + 11] ); - x1r = sub( a[j + 8], a[j + 10] ); - x1i = sub( a[j + 9], a[j + 11] ); - x2r = add( a[j + 12], a[j + 14] ); - x2i = add( a[j + 13], a[j + 15] ); - x3r = sub( a[j + 12], a[j + 14] ); - x3i = sub( a[j + 13], a[j + 15] ); - a[j + 8] = add( x0r, x2r ); - move16(); - a[j + 9] = add( x0i, x2i ); - move16(); - - x0r = sub( x0r, x2r ); - x0i = sub( x0i, x2i ); - tmp = negate( x0r ); - L_tmp = Mult_32_16( wk2i, tmp ); /*Q(15+Qx+Q_edct) */ - L_tmp = Msub_32_16( L_tmp, wk2r, x0i ); /*Q(15+Qx+Q_edct) */ - a[j + 12] = round_fx( L_shl( L_tmp, 1 ) ); /*Q(Qx+Q_edct) */ - - tmp = negate( x0i ); - L_tmp = Mult_32_16( wk2i, tmp ); /*Q(15+Qx+Q_edct) */ - L_tmp = Madd_32_16( L_tmp, wk2r, x0r ); /*Q(15+Qx+Q_edct) */ - a[j + 13] = round_fx( L_shl( L_tmp, 1 ) ); /*Q(Qx+Q_edct) */ - - x0r = sub( x1r, x3i ); - x0i = add( x1i, x3r ); - L_tmp = Mult_32_16( wk1r, x0r ); /*Q(15+Qx+Q_edct) */ - L_tmp = Msub_32_16( L_tmp, wk1i, x0i ); /*Q(15+Qx+Q_edct) */ - a[j + 10] = round_fx( L_shl( L_tmp, 1 ) ); /*Q(Qx+Q_edct) */ - - L_tmp = Mult_32_16( wk1r, x0i ); /*Q(15+Qx+Q_edct) */ - L_tmp = Madd_32_16( L_tmp, wk1i, x0r ); /*Q(15+Qx+Q_edct) */ - a[j + 11] = round_fx( L_shl( L_tmp, 1 ) ); /*Q(Qx+Q_edct) */ - - x0r = add( x1r, x3i ); - x0i = sub( x1i, x3r ); - - L_tmp = Mult_32_16( wk3r, x0r ); /*Q(15+Qx+Q_edct) */ - L_tmp = Msub_32_16( L_tmp, wk3i, x0i ); /*Q(15+Qx+Q_edct) */ - a[j + 14] = round_fx( L_shl( L_tmp, 1 ) ); /*Q(Qx+Q_edct) */ - - L_tmp = Mult_32_16( wk3r, x0i ); /*Q(15+Qx+Q_edct) */ - L_tmp = Madd_32_16( L_tmp, wk3i, x0r ); /*Q(15+Qx+Q_edct) */ - a[j + 15] = round_fx( L_shl( L_tmp, 1 ) ); /*Q(Qx+Q_edct) */ -#endif } return; @@ -2337,7 +1995,6 @@ static void cftmdl_16fx( m = shl( l, 2 ); FOR( j = 0; j < l; j += 2 ) { -#ifdef BASOP_NOGLOB j1 = add_o( j, l, &Overflow ); j2 = add_o( j1, l, &Overflow ); j3 = add_o( j2, l, &Overflow ); @@ -2365,35 +2022,6 @@ static void cftmdl_16fx( move16(); a[j3 + 1] = sub_o( x1i, x3r, &Overflow ); move16(); -#else - j1 = add( j, l ); - j2 = add( j1, l ); - j3 = add( j2, l ); - x0r = add( a[j], a[j1] ); - x0i = add( a[j + 1], a[j1 + 1] ); - x1r = sub( a[j], a[j1] ); - x1i = sub( a[j + 1], a[j1 + 1] ); - x2r = add( a[j2], a[j3] ); - x2i = add( a[j2 + 1], a[j3 + 1] ); - x3r = sub( a[j2], a[j3] ); - x3i = sub( a[j2 + 1], a[j3 + 1] ); - a[j] = add( x0r, x2r ); - move16(); - a[j + 1] = add( x0i, x2i ); - move16(); - a[j2] = sub( x0r, x2r ); - move16(); - a[j2 + 1] = sub( x0i, x2i ); - move16(); - a[j1] = sub( x1r, x3i ); - move16(); - a[j1 + 1] = add( x1i, x3r ); - move16(); - a[j3] = add( x1r, x3i ); - move16(); - a[j3 + 1] = sub( x1i, x3r ); - move16(); -#endif } wk1r = w[2]; @@ -2401,7 +2029,6 @@ static void cftmdl_16fx( tmp2 = add( l, m ); FOR( j = m; j < tmp2; j += 2 ) { -#ifdef BASOP_NOGLOB j1 = add_o( j, l, &Overflow ); j2 = add_o( j1, l, &Overflow ); j3 = add_o( j2, l, &Overflow ); @@ -2445,47 +2072,6 @@ static void cftmdl_16fx( L_tmp = Mult_32_16( wk1r, tmp ); /*Q(15+Qx+Q_edct) */ a[j3 + 1] = round_fx_o( L_shl_o( L_tmp, 1, &Overflow ), &Overflow ); /*Q(Qx+Q_edct) */ move16(); -#else - j1 = add( j, l ); - j2 = add( j1, l ); - j3 = add( j2, l ); - x0r = add( a[j], a[j1] ); - x0i = add( a[j + 1], a[j1 + 1] ); - x1r = sub( a[j], a[j1] ); - x1i = sub( a[j + 1], a[j1 + 1] ); - x2r = add( a[j2], a[j3] ); - x2i = add( a[j2 + 1], a[j3 + 1] ); - x3r = sub( a[j2], a[j3] ); - x3i = sub( a[j2 + 1], a[j3 + 1] ); - a[j] = add( x0r, x2r ); - move16(); - a[j + 1] = add( x0i, x2i ); - move16(); - a[j2] = sub( x2i, x0i ); - move16(); - a[j2 + 1] = sub( x0r, x2r ); - move16(); - - x0r = sub( x1r, x3i ); - x0i = add( x1i, x3r ); - tmp = sub( x0r, x0i ); - L_tmp = Mult_32_16( wk1r, tmp ); /*Q(15+Qx+Q_edct) */ - a[j1] = round_fx( L_shl( L_tmp, 1 ) ); /*Q(Qx+Q_edct) */ - - tmp = add( x0r, x0i ); - L_tmp = Mult_32_16( wk1r, tmp ); /*Q(15+Qx+Q_edct) */ - a[j1 + 1] = round_fx( L_shl( L_tmp, 1 ) ); /*Q(Qx+Q_edct) */ - - x0r = add( x3i, x1r ); - x0i = sub( x3r, x1i ); - tmp = sub( x0i, x0r ); - L_tmp = Mult_32_16( wk1r, tmp ); /*Q(15+Qx+Q_edct) */ - a[j3] = round_fx( L_shl( L_tmp, 1 ) ); /*Q(Qx+Q_edct) */ - - tmp = add( x0i, x0r ); - L_tmp = Mult_32_16( wk1r, tmp ); /*Q(15+Qx+Q_edct) */ - a[j3 + 1] = round_fx( L_shl( L_tmp, 1 ) ); /*Q(Qx+Q_edct) */ -#endif } k1 = 0; @@ -2512,7 +2098,6 @@ static void cftmdl_16fx( tmp2 = add( l, k ); FOR( j = k; j < tmp2; j += 2 ) { -#ifdef BASOP_NOGLOB j1 = add_o( j, l, &Overflow ); j2 = add_o( j1, l, &Overflow ); j3 = add_o( j2, l, &Overflow ); @@ -2568,80 +2153,20 @@ static void cftmdl_16fx( L_tmp = Madd_32_16( L_tmp, wk3i, x0r ); /*Q(15+Qx+Q_edct) */ a[j3 + 1] = round_fx_o( L_shl_o( L_tmp, 1, &Overflow ), &Overflow ); /*Q(Qx+Q_edct) */ move16(); -#else - j1 = add( j, l ); - j2 = add( j1, l ); - j3 = add( j2, l ); - x0r = add( a[j], a[j1] ); - x0i = add( a[j + 1], a[j1 + 1] ); - x1r = sub( a[j], a[j1] ); - x1i = sub( a[j + 1], a[j1 + 1] ); - x2r = add( a[j2], a[j3] ); - x2i = add( a[j2 + 1], a[j3 + 1] ); - x3r = sub( a[j2], a[j3] ); - x3i = sub( a[j2 + 1], a[j3 + 1] ); - a[j] = add( x0r, x2r ); - move16(); - a[j + 1] = add( x0i, x2i ); - move16(); - - x0r = sub( x0r, x2r ); - x0i = sub( x0i, x2i ); - - L_tmp = Mult_32_16( wk2r, x0r ); /*Q(15+Qx+Q_edct) */ - L_tmp = Msub_32_16( L_tmp, wk2i, x0i ); /*Q(15+Qx+Q_edct) */ - a[j2] = round_fx( L_shl( L_tmp, 1 ) ); /*Q(Qx+Q_edct) */ - - L_tmp = Mult_32_16( wk2r, x0i ); /*Q(15+Qx+Q_edct) */ - L_tmp = Madd_32_16( L_tmp, wk2i, x0r ); /*Q(15+Qx+Q_edct) */ - a[j2 + 1] = round_fx( L_shl( L_tmp, 1 ) ); /*Q(Qx+Q_edct) */ - - x0r = sub( x1r, x3i ); - x0i = add( x1i, x3r ); - - L_tmp = Mult_32_16( wk1r, x0r ); /*Q(15+Qx+Q_edct) */ - L_tmp = Msub_32_16( L_tmp, wk1i, x0i ); /*Q(15+Qx+Q_edct) */ - a[j1] = round_fx( L_shl( L_tmp, 1 ) ); /*Q(Qx+Q_edct) */ - - L_tmp = Mult_32_16( wk1r, x0i ); /*Q(15+Qx+Q_edct) */ - L_tmp = Madd_32_16( L_tmp, wk1i, x0r ); /*Q(15+Qx+Q_edct) */ - a[j1 + 1] = round_fx( L_shl( L_tmp, 1 ) ); /*Q(Qx+Q_edct) */ - - L_x0r = L_add( (Word32) x1r, (Word32) x3i ); - L_x0i = L_sub( (Word32) x1i, (Word32) x3r ); - x0r = extract_l( L_x0r ); - x0i = extract_l( L_x0i ); - L_tmp = Mult_32_16( wk3r, x0r ); /*Q(15+Qx+Q_edct) */ - L_tmp = Msub_32_16( L_tmp, wk3i, x0i ); /*Q(15+Qx+Q_edct) */ - a[j3] = round_fx( L_shl( L_tmp, 1 ) ); /*Q(Qx+Q_edct) */ - - L_tmp = Mult_32_16( wk3r, x0i ); /*Q(15+Qx+Q_edct) */ - L_tmp = Madd_32_16( L_tmp, wk3i, x0r ); /*Q(15+Qx+Q_edct) */ - a[j3 + 1] = round_fx( L_shl( L_tmp, 1 ) ); /*Q(Qx+Q_edct) */ -#endif } wk1r = w[k2 + 2]; move32(); wk1i = w[k2 + 3]; move32(); -#ifdef BASOP_NOGLOB L_tmp = L_shl_o( Mult_32_32( wk2r, wk1i ), 1, &Overflow ); /*Q29 */ wk3r = L_sub_o( wk1r, L_shl_o( L_tmp, 1, &Overflow ), &Overflow ); /*Q30 */ L_tmp = L_shl_o( Mult_32_32( wk2r, wk1r ), 1, &Overflow ); /*Q29 */ wk3i = L_sub_o( L_shl_o( L_tmp, 1, &Overflow ), wk1i, &Overflow ); /*Q30 */ -#else - L_tmp = L_shl( Mult_32_32( wk2r, wk1i ), 1 ); /*Q29 */ - wk3r = L_sub( wk1r, L_shl( L_tmp, 1 ) ); /*Q30 */ - - L_tmp = L_shl( Mult_32_32( wk2r, wk1r ), 1 ); /*Q29 */ - wk3i = L_sub( L_shl( L_tmp, 1 ), wk1i ); /*Q30 */ -#endif tmp2 = add( l, add( k, m ) ); FOR( j = add( k, m ); j < tmp2; j += 2 ) { -#ifdef BASOP_NOGLOB j1 = add_o( j, l, &Overflow ); j2 = add_o( j1, l, &Overflow ); j3 = add_o( j2, l, &Overflow ); @@ -2698,58 +2223,6 @@ static void cftmdl_16fx( L_tmp = Madd_32_16( L_tmp, wk3i, x0r ); /*Q(15+Qx+Q_edct) */ a[j3 + 1] = round_fx_o( L_shl_o( L_tmp, 1, &Overflow ), &Overflow ); /*Q(Qx+Q_edct) */ move16(); -#else - j1 = add( j, l ); - j2 = add( j1, l ); - j3 = add( j2, l ); - x0r = add( a[j], a[j1] ); - x0i = add( a[j + 1], a[j1 + 1] ); - x1r = sub( a[j], a[j1] ); - x1i = sub( a[j + 1], a[j1 + 1] ); - x2r = add( a[j2], a[j3] ); - x2i = add( a[j2 + 1], a[j3 + 1] ); - x3r = sub( a[j2], a[j3] ); - x3i = sub( a[j2 + 1], a[j3 + 1] ); - a[j] = add( x0r, x2r ); - move16(); - a[j + 1] = add( x0i, x2i ); - move16(); - - x0r = sub( x0r, x2r ); - x0i = sub( x0i, x2i ); - - tmp = negate( x0r ); - L_tmp = Mult_32_16( wk2i, tmp ); /*Q(15+Qx+Q_edct) */ - L_tmp = Msub_32_16( L_tmp, wk2r, x0i ); /*Q(15+Qx+Q_edct) */ - a[j2] = round_fx( L_shl( L_tmp, 1 ) ); /*Q(Qx+Q_edct) */ - - tmp = negate( x0i ); - L_tmp = Mult_32_16( wk2i, tmp ); /*Q(15+Qx+Q_edct) */ - L_tmp = Madd_32_16( L_tmp, wk2r, x0r ); /*Q(15+Qx+Q_edct) */ - a[j2 + 1] = round_fx( L_shl( L_tmp, 1 ) ); /*Q(Qx+Q_edct) */ - - x0r = sub( x1r, x3i ); - x0i = add( x1i, x3r ); - - L_tmp = Mult_32_16( wk1r, x0r ); /*Q(15+Qx+Q_edct) */ - L_tmp = Msub_32_16( L_tmp, wk1i, x0i ); /*Q(15+Qx+Q_edct) */ - a[j1] = round_fx( L_shl( L_tmp, 1 ) ); /*Q(Qx+Q_edct) */ - - L_tmp = Mult_32_16( wk1r, x0i ); /*Q(15+Qx+Q_edct) */ - L_tmp = Madd_32_16( L_tmp, wk1i, x0r ); /*Q(15+Qx+Q_edct) */ - a[j1 + 1] = round_fx( L_shl( L_tmp, 1 ) ); /*Q(Qx+Q_edct) */ - - x0r = add( x1r, x3i ); - x0i = sub( x1i, x3r ); - - L_tmp = Mult_32_16( wk3r, x0r ); /*Q(15+Qx+Q_edct) */ - L_tmp = Msub_32_16( L_tmp, wk3i, x0i ); /*Q(15+Qx+Q_edct) */ - a[j3] = round_fx( L_shl( L_tmp, 1 ) ); /*Q(Qx+Q_edct) */ - - L_tmp = Mult_32_16( wk3r, x0i ); /*Q(15+Qx+Q_edct) */ - L_tmp = Madd_32_16( L_tmp, wk3i, x0r ); /*Q(15+Qx+Q_edct) */ - a[j3 + 1] = round_fx( L_shl( L_tmp, 1 ) ); /*Q(Qx+Q_edct) */ -#endif } } @@ -2854,13 +2327,9 @@ void fft3_fx( const Word16 X[] /*Qx*/, Word16 Y[] /*Qx*/, const Word16 n ) move16(); /* special case: i = 0 */ - acc = L_mult( *RZ0++, 0x4000 /*1.Q14*/ ); // Q15 + Qx - acc = L_mac( acc, *RZ1++, 0x4000 /*1.Q14*/ ); // Q15 + Qx -#ifdef BASOP_NOGLOB + acc = L_mult( *RZ0++, 0x4000 /*1.Q14*/ ); // Q15 + Qx + acc = L_mac( acc, *RZ1++, 0x4000 /*1.Q14*/ ); // Q15 + Qx *RY++ = mac_r_sat( acc, *RZ2++, 0x4000 /*1.Q14*/ ); // Qx -#else - *RY++ = mac_r( acc, *RZ2++, 0x4000 ); -#endif move16(); /* first 3/12-- from 1 to (3*m/8)-1 */ @@ -3456,21 +2925,12 @@ void ifft3_fx( const Word16 Z[] /*Qx*/, Word16 X[] /*Qx*/, const Word16 n ) pX = X; FOR( i = 0; i < m; i++ ) { -#ifdef BASOP_NOGLOB *pX++ = shl_sat( mult_r( *y0++, FFT3_ONE_THIRD ), 1 ); // Qx move16(); *pX++ = shl_sat( mult_r( *y1++, FFT3_ONE_THIRD ), 1 ); // Qx move16(); *pX++ = shl_sat( mult_r( *y2++, FFT3_ONE_THIRD ), 1 ); // Qx move16(); -#else - *pX++ = shl( mult_r( *y0++, FFT3_ONE_THIRD ), 1 ); - move16(); - *pX++ = shl( mult_r( *y1++, FFT3_ONE_THIRD ), 1 ); - move16(); - *pX++ = shl( mult_r( *y2++, FFT3_ONE_THIRD ), 1 ); - move16(); -#endif } return; diff --git a/lib_com/fft_rel.c b/lib_com/fft_rel.c index 88f80e798703ed2b34902db2703d30753c1b7698..1d020cabdd7d013f554eeb3d0a697e73682881d9 100644 --- a/lib_com/fft_rel.c +++ b/lib_com/fft_rel.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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,10 +36,9 @@ #include #include "options.h" -#include "prot.h" +#include "prot_fx.h" #include "rom_com.h" #include "wmc_auto.h" -#include "prot_fx.h" /*---------------------------------------------------------------------* * Local constants @@ -301,6 +300,168 @@ void fft_rel( return; } +void fft_rel_16_32fx( + Word16 x[], /* i/o: input/output vector Qx */ + Word16 *q_x, /* extra scaling added on speech buffer*/ + Word16 i_subfr, + const Word16 n, /* i : vector length */ + const Word16 m /* i : log2 of vector length */ +) +{ + Word16 i, j, k, n1, n2, n4; + Word16 step; + Word32 xt, t1, t2; + Word32 *x0, *x1, *x2; + const Word16 *s, *c; + Word32 *xi2, *xi3, *xi4, *xi1; + + Word32 fft_bff32[L_FFT]; + Copy_Scale_sig_16_32_no_sat( x, fft_bff32, L_FFT, 0 ); // copying x to fft_bff32 without scaling + + /*-----------------------------------------------------------------* + * Digit reverse counter + *-----------------------------------------------------------------*/ + + j = 0; + move16(); + x0 = &fft_bff32[0]; // Qx + FOR( i = 0; i < n - 1; i++ ) + { + IF( LT_16( i, j ) ) + { + xt = fft_bff32[j]; // Qx + move32(); + fft_bff32[j] = *x0; // Qx + move32(); + *x0 = xt; // Qx + move32(); + } + x0++; + k = shr( n, 1 ); + WHILE( ( k <= j ) ) + { + j = sub( j, k ); + k = shr( k, 1 ); + } + j = add( j, k ); + } + + /*-----------------------------------------------------------------* + * Length two butterflies + *-----------------------------------------------------------------*/ + + x0 = &fft_bff32[0]; + x1 = &fft_bff32[1]; + FOR( i = 0; i < ( n >> 1 ); i++ ) + { + xt = *x0; + move32(); + *x0 = L_add( xt, *x1 ); + move32(); + *x1 = L_sub( xt, *x1 ); + move32(); + x0++; + x0++; + x1++; + x1++; + } + + /*-----------------------------------------------------------------* + * Other butterflies + * + * The implementation described in [1] has been changed by using + * table lookup for evaluating sine and cosine functions. The + * variable ind and its increment step are needed to access table + * entries. Note that this implementation assumes n4 to be so + * small that ind will never exceed the table. Thus the input + * argument n and the constant N_MAX_SAS must be set properly. + *-----------------------------------------------------------------*/ + + n2 = 1; + move16(); + /* step = N_MAX_SAS/4; */ + FOR( k = 2; k <= m; k++ ) + { + n4 = n2; + move16(); + n2 = shl( n4, 1 ); + n1 = shl( n2, 1 ); + + step = idiv1616( N_MAX_SAS, n1 ); + + x0 = fft_bff32; + x1 = fft_bff32 + n2; + x2 = fft_bff32 + add( n2, n4 ); + FOR( i = 0; i < n; i += n1 ) + { + xt = *x0; + move32(); /* xt = x[i]; */ + *x0 = L_add( xt, *x1 ); + move32(); /* x[i] = xt + x[i+n2]; */ + *x1 = L_sub( xt, *x1 ); + move32(); /* x[i+n2] = xt - x[i+n2]; */ + *x2 = L_negate( *x2 ); + move32(); /* x[i+n2+n4] = -x[i+n2+n4]; */ + + + s = sincos_t_fx + step; // Q15 + c = s + 64; // Q15 + xi1 = fft_bff32 + add( i, 1 ); + xi3 = xi1 + n2; + xi2 = xi3 - 2; + xi4 = xi1 + sub( n1, 2 ); + + FOR( j = 1; j < n4; j++ ) + { + t1 = L_add( Mpy_32_16_1( *xi3, *c ), Mpy_32_16_1( *xi4, *s ) ); /* t1 = *xi3**(pt_c+ind) + *xi4**(pt_s+ind); Qx */ + t2 = L_sub( Mpy_32_16_1( *xi3, *s ), Mpy_32_16_1( *xi4, *c ) ); /* t2 = *xi3**(pt_s+ind) - *xi4**(pt_c+ind); Qx */ + *xi4 = L_sub( *xi2, t2 ); + move32(); + *xi3 = L_negate( L_add( *xi2, t2 ) ); + move32(); + *xi2 = L_sub( *xi1, t1 ); + move32(); + *xi1 = L_add( *xi1, t1 ); + move32(); + + xi4--; + xi2--; + xi3++; + xi1++; + c += step; + s += step; /* autoincrement by ar0 */ + } + + x0 += n1; + x1 += n1; + x2 += n1; + } + /* step = shr(step, 1); */ + } + Word16 norm = L_norm_arr( fft_bff32, L_FFT ); + IF( i_subfr == 0 ) + { + Copy_Scale_sig32_16( fft_bff32, x, L_FFT, norm ); + *q_x = sub( norm, 16 ); + move16(); + } + ELSE + { + IF( LT_16( sub( norm, 16 ), *q_x ) ) + { + scale_sig( x - L_FFT, L_FFT, sub( sub( norm, 16 ), *q_x ) ); + Copy_Scale_sig32_16( fft_bff32, x, L_FFT, norm ); + *q_x = sub( norm, 16 ); + move16(); + } + ELSE + { + Copy_Scale_sig32_16( fft_bff32, x, L_FFT, add( 16, *q_x ) ); + } + } + + return; +} void fft_rel_fx( Word16 x[], /* i/o: input/output vector Qx */ @@ -361,17 +522,9 @@ void fft_rel_fx( { xt = *x0; move16(); -#ifdef BASOP_NOGLOB *x0 = add_o( xt, *x1, &Overflow ); -#else - *x0 = add( xt, *x1 ); -#endif move16(); -#ifdef BASOP_NOGLOB *x1 = sub_o( xt, *x1, &Overflow ); -#else - *x1 = sub( xt, *x1 ); -#endif move16(); x0++; x0++; @@ -409,17 +562,9 @@ void fft_rel_fx( { xt = *x0; move16(); /* xt = x[i]; */ -#ifdef BASOP_NOGLOB *x0 = add_o( xt, *x1, &Overflow ); -#else /* BASOP_NOGLOB */ - *x0 = add( xt, *x1 ); -#endif /* BASOP_NOGLOB */ move16(); /* x[i] = xt + x[i+n2]; */ -#ifdef BASOP_NOGLOB *x1 = sub_o( xt, *x1, &Overflow ); -#else /* BASOP_NOGLOB */ - *x1 = sub( xt, *x1 ); -#endif /* BASOP_NOGLOB */ move16(); /* x[i+n2] = xt - x[i+n2]; */ *x2 = negate( *x2 ); move16(); /* x[i+n2+n4] = -x[i+n2+n4]; */ @@ -434,33 +579,15 @@ void fft_rel_fx( FOR( j = 1; j < n4; j++ ) { -#ifdef BASOP_NOGLOB t1 = add_o( mult_r( *xi3, *c ), mult_r( *xi4, *s ), &Overflow ); /* t1 = *xi3**(pt_c+ind) + *xi4**(pt_s+ind); Qx */ t2 = sub_o( mult_r( *xi3, *s ), mult_r( *xi4, *c ), &Overflow ); /* t2 = *xi3**(pt_s+ind) - *xi4**(pt_c+ind); Qx */ *xi4 = sub_o( *xi2, t2, &Overflow ); -#else /* BASOP_NOGLOB */ - t1 = add( mult_r( *xi3, *c ), mult_r( *xi4, *s ) ); /* t1 = *xi3**(pt_c+ind) + *xi4**(pt_s+ind); */ - t2 = sub( mult_r( *xi3, *s ), mult_r( *xi4, *c ) ); /* t2 = *xi3**(pt_s+ind) - *xi4**(pt_c+ind); */ - *xi4 = sub( *xi2, t2 ); -#endif /* BASOP_NOGLOB */ move16(); -#ifdef BASOP_NOGLOB *xi3 = negate( add_o( *xi2, t2, &Overflow ) ); -#else /* BASOP_NOGLOB */ - *xi3 = negate( add( *xi2, t2 ) ); -#endif /* BASOP_NOGLOB */ move16(); -#ifdef BASOP_NOGLOB *xi2 = sub_o( *xi1, t1, &Overflow ); -#else /* BASOP_NOGLOB */ - *xi2 = sub( *xi1, t1 ); -#endif /* BASOP_NOGLOB */ move16(); -#ifdef BASOP_NOGLOB *xi1 = add_o( *xi1, t1, &Overflow ); -#else /* BASOP_NOGLOB */ - *xi1 = add( *xi1, t1 ); -#endif /* BASOP_NOGLOB */ move16(); xi4--; diff --git a/lib_com/fft_rel_fx.c b/lib_com/fft_rel_fx.c index 1285049bcb6afd76f90b084ac1a759671f2dbfec..5461ce55baae37f1bfdd25c36fac6607fd69e0c1 100644 --- a/lib_com/fft_rel_fx.c +++ b/lib_com/fft_rel_fx.c @@ -136,26 +136,15 @@ static void c_fft_fx( input_ptr1 = in_ptr + ( const Word16 )( (uintptr_t) ( *table_ptr++ ) >> (uintptr_t) shift ); -#ifdef BASOP_NOGLOB tmp1 = msu_r_sat( L_tmp1, *input_ptr1, 16384 ); tmp3 = mac_r_sat( L_tmp1, *input_ptr1++, 16384 ); -#else - tmp1 = msu_r( L_tmp1, *input_ptr1, 16384 ); - tmp3 = mac_r( L_tmp1, *input_ptr1++, 16384 ); -#endif input_ptr2 = in_ptr + ( const Word16 )( (uintptr_t) ( *table_ptr++ ) >> (uintptr_t) shift ); input_ptr3 = in_ptr + ( const Word16 )( (uintptr_t) ( *table_ptr++ ) >> (uintptr_t) shift ); L_tmp1 = L_mult( *input_ptr2++, 16384 ); -#ifdef BASOP_NOGLOB tmp2 = mac_r_sat( L_tmp1, *input_ptr3, 16384 ); tmp4 = msu_r_sat( L_tmp1, *input_ptr3++, 16384 ); -#else - tmp2 = mac_r( L_tmp1, *input_ptr3, 16384 ); - tmp4 = msu_r( L_tmp1, *input_ptr3++, 16384 ); -#endif L_tmp1 = L_mult( tmp3, 16384 ); -#ifdef BASOP_NOGLOB out_ptr[k] = mac_r_sat( L_tmp1, tmp2, 16384 ); move16(); out_ptr[k + 4] = msu_r_sat( L_tmp1, tmp2, 16384 ); @@ -163,57 +152,25 @@ static void c_fft_fx( tmp2 = mac_r_sat( L_tmp2, *input_ptr1, 16384 ); tmp3 = msu_r_sat( L_tmp2, *input_ptr1, 16384 ); -#else - out_ptr[k] = mac_r( L_tmp1, tmp2, 16384 ); - move16(); - out_ptr[k + 4] = msu_r( L_tmp1, tmp2, 16384 ); - move16(); - - tmp2 = mac_r( L_tmp2, *input_ptr1, 16384 ); - tmp3 = msu_r( L_tmp2, *input_ptr1, 16384 ); -#endif L_tmp2 = L_mult( *input_ptr2, 16384 ); L_tmp1 = L_mult( tmp1, 16384 ); -#ifdef BASOP_NOGLOB tmp1 = msu_r_sat( L_tmp2, *input_ptr3, 16384 ); out_ptr[k + 2] = mac_r_sat( L_tmp1, tmp1, 16384 ); move16(); out_ptr[k + 6] = msu_r_sat( L_tmp1, tmp1, 16384 ); move16(); -#else - tmp1 = msu_r( L_tmp2, *input_ptr3, 16384 ); - out_ptr[k + 2] = mac_r( L_tmp1, tmp1, 16384 ); - move16(); - out_ptr[k + 6] = msu_r( L_tmp1, tmp1, 16384 ); - move16(); -#endif L_tmp1 = L_mult( tmp2, 16384 ); -#ifdef BASOP_NOGLOB tmp2 = mac_r_sat( L_tmp2, *input_ptr3, 16384 ); out_ptr[k + 1] = mac_r_sat( L_tmp1, tmp2, 16384 ); move16(); out_ptr[k + 5] = msu_r_sat( L_tmp1, tmp2, 16384 ); move16(); -#else - tmp2 = mac_r( L_tmp2, *input_ptr3, 16384 ); - out_ptr[k + 1] = mac_r( L_tmp1, tmp2, 16384 ); - move16(); - out_ptr[k + 5] = msu_r( L_tmp1, tmp2, 16384 ); - move16(); -#endif L_tmp1 = L_mult( tmp3, 16384 ); -#ifdef BASOP_NOGLOB out_ptr[k + 3] = msu_r_sat( L_tmp1, tmp4, 16384 ); move16(); out_ptr[k + 7] = mac_r_sat( L_tmp1, tmp4, 16384 ); move16(); -#else - out_ptr[k + 3] = msu_r( L_tmp1, tmp4, 16384 ); - move16(); - out_ptr[k + 7] = mac_r( L_tmp1, tmp4, 16384 ); - move16(); -#endif } /* Remaining Stages */ @@ -333,7 +290,6 @@ static void c_fft_fx( kj = add( k, jj ); /* kj is butterfly bottom */ /* Butterfly computations */ -#ifdef BASOP_NOGLOB tmp1 = mac_r_sat( L_mult_sat( out_ptr[kj], table_ptr[ji] ), out_ptr[kj + 1], table_ptr[ji + 1] ); tmp2 = msu_r_sat( L_mult_sat( out_ptr[kj + 1], table_ptr[ji] ), out_ptr[kj], table_ptr[ji + 1] ); @@ -346,22 +302,6 @@ static void c_fft_fx( move16(); out_ptr[k + 1] = add_sat( out_ptr[k + 1], tmp2 ); move16(); -#else - tmp1 = mac_r( L_mult( out_ptr[kj], table_ptr[ji] ), - out_ptr[kj + 1], table_ptr[ji + 1] ); - - tmp2 = msu_r( L_mult( out_ptr[kj + 1], table_ptr[ji] ), - out_ptr[kj], table_ptr[ji + 1] ); - - out_ptr[kj] = sub( out_ptr[k], tmp1 ); - move16(); - out_ptr[kj + 1] = sub( out_ptr[k + 1], tmp2 ); - move16(); - out_ptr[k] = add( out_ptr[k], tmp1 ); - move16(); - out_ptr[k + 1] = add( out_ptr[k + 1], tmp2 ); - move16(); -#endif } ji = add( ji, ii ); } @@ -420,7 +360,6 @@ void r_fft_fx_lc( FOR( i = 2; i <= SIZE2; i += 2 ) { Ltmp1_imag = L_mult( temp[i + 1], 16384 ); -#ifdef BASOP_NOGLOB Ltmp1_imag = L_msu_sat( Ltmp1_imag, *ptrDn, 16384 ); tmp2_real = add_sat( temp[i + 1], *ptrDn-- ); @@ -439,26 +378,6 @@ void r_fft_fx_lc( move16(); *ptRealDn-- = mac_r_sat( Ltmp1_real, tmp2_real, *phstbl_ptrDn-- ); move16(); -#else - Ltmp1_imag = L_msu( Ltmp1_imag, *ptrDn, 16384 ); - tmp2_real = add( temp[i + 1], *ptrDn-- ); - - Ltmp1_real = L_mult( temp[i], 16384 ); - Ltmp1_real = L_mac( Ltmp1_real, *ptrDn, 16384 ); - tmp2_imag = sub( *ptrDn--, temp[i] ); - - - *ptRealUp++ = msu_r( L_mac( Ltmp1_real, tmp2_real, phs_tbl[i] ), tmp2_imag, phs_tbl[i + 1] ); - move16(); - *ptImaDn-- = mac_r( L_mac( Ltmp1_imag, tmp2_imag, phs_tbl[i] ), tmp2_real, phs_tbl[i + 1] ); - move16(); - Ltmp1 = L_mac( L_negate( Ltmp1_imag ), tmp2_real, *phstbl_ptrDn ); - Ltmp1_real = L_mac( Ltmp1_real, tmp2_imag, *phstbl_ptrDn-- ); - *ptImaUp++ = msu_r( Ltmp1, tmp2_imag, *phstbl_ptrDn ); - move16(); - *ptRealDn-- = mac_r( Ltmp1_real, tmp2_real, *phstbl_ptrDn-- ); - move16(); -#endif } } ELSE /* The ifFT part */ @@ -486,7 +405,6 @@ void r_fft_fx_lc( /* Now, handle the remaining positive frequencies */ FOR( i = 2; i <= SIZE2; i += 2 ) { -#ifdef BASOP_NOGLOB Ltmp1_imag = L_mult( *ptImaDn, 16384 ); Ltmp1_imag = L_msu_sat( Ltmp1_imag, *ptImaUp, 16384 ); tmp2_real = add_sat( *ptImaDn--, *ptImaUp++ ); @@ -503,26 +421,6 @@ void r_fft_fx_lc( move16(); *ptrDn-- = msu_r_sat( Ltmp1_real, tmp2_real, *phstbl_ptrDn-- ); move16(); -#else - Ltmp1_imag = L_mult( *ptImaDn, 16384 ); - Ltmp1_imag = L_msu( Ltmp1_imag, *ptImaUp, 16384 ); - tmp2_real = add( *ptImaDn--, *ptImaUp++ ); - Ltmp1_real = L_mult( *ptRealUp, 16384 ); - Ltmp1_real = L_mac( Ltmp1_real, *ptRealDn, 16384 ); - tmp2_imag = sub( *ptRealUp++, *ptRealDn-- ); - - - temp[i] = mac_r( L_msu( Ltmp1_real, tmp2_real, phs_tbl[i] ), tmp2_imag, phs_tbl[i + 1] ); - move16(); - temp[i + 1] = mac_r( L_mac( Ltmp1_imag, tmp2_imag, phs_tbl[i] ), tmp2_real, phs_tbl[i + 1] ); - move16(); - Ltmp1 = L_mac( L_negate( Ltmp1_imag ), tmp2_real, *phstbl_ptrDn ); - Ltmp1_real = L_msu( Ltmp1_real, tmp2_imag, *phstbl_ptrDn-- ); - *ptrDn-- = msu_r( Ltmp1, tmp2_imag, *phstbl_ptrDn ); - move16(); - *ptrDn-- = msu_r( Ltmp1_real, tmp2_real, *phstbl_ptrDn-- ); - move16(); -#endif } /* Perform the complex ifFT */ diff --git a/lib_com/fill_spectrum.c b/lib_com/fill_spectrum.c index 111ac6d2fdd84f8e6d115a17a6e3aea35c131f6a..bd9080a7bd41747ba25f9a5cecce507c5ac55e63 100644 --- a/lib_com/fill_spectrum.c +++ b/lib_com/fill_spectrum.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other @@ -38,9 +38,8 @@ #include "options.h" #include "cnst.h" #include "rom_com.h" -#include "prot.h" -#include "wmc_auto.h" #include "prot_fx.h" +#include "wmc_auto.h" #include "ivas_prot_fx.h" @@ -263,7 +262,7 @@ void ivas_fill_spectrum_fx( } ELSE IF( EQ_16( HQ_mode, HQ_GEN_SWB ) || EQ_16( HQ_mode, HQ_GEN_FB ) ) { - hq_bwe_fx( HQ_mode, L_coeff_out1, hq_generic_fenv, L_coeff_out, hq_generic_offset, prev_L_swb_norm, hq_generic_exc_clas, sfm_end, num_sfm, num_env_bands, R ); + hq_bwe_ivas_fx( HQ_mode, L_coeff_out1, hq_generic_fenv, L_coeff_out, hq_generic_offset, prev_L_swb_norm, hq_generic_exc_clas, sfm_end, num_sfm, num_env_bands, R ); } /*----------------------------------------------------------------* diff --git a/lib_com/findpulse.c b/lib_com/findpulse.c index cc7d2bf3b5c1684696e24500ce7446af497f49f0..68853e06142c91523103ce2ae595215b69bbe61c 100644 --- a/lib_com/findpulse.c +++ b/lib_com/findpulse.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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,10 +37,9 @@ #include #include "options.h" #include -#include "prot.h" +#include "prot_fx.h" #include "cnst.h" #include "wmc_auto.h" -#include "prot_fx.h" /*----------------------------------------------------------------------------------* * findpulse() diff --git a/lib_com/float_to_fix_ops.c b/lib_com/float_to_fix_ops.c index 41d90359f4a2643524d1abd16276b9c1e374512e..8b69e05e8811edbc273a3cd78e735d1bc0f99375 100644 --- a/lib_com/float_to_fix_ops.c +++ b/lib_com/float_to_fix_ops.c @@ -3,7 +3,6 @@ #include #include #include "options.h" -#include "prot.h" #include "prot_fx.h" #define WMC_TOOL_SKIP @@ -184,14 +183,14 @@ Word16 Q_factor( float x ) { Word16 Q = 15; if ( x >= 1 || x <= -1 ) - Q = norm_s( (Word16) abs( (Word32) x ) ); + Q = norm_s( (Word16) L_abs( (Word32) x ) ); return Q; } Word16 Q_factor_L( float x ) { Word16 Q = 31; if ( x >= 1 || x <= -1 ) - Q = norm_l( abs( (Word32) x ) ); + Q = norm_l( L_abs( (Word32) x ) ); return Q; } Word16 Q_factor_L_32( Word32 x ) @@ -207,7 +206,7 @@ Word16 Q_factor_arr( float *x, Word16 l ) for ( int i = 0; i < l; i++ ) { if ( x[i] >= 1 || x[i] <= -1 ) - Q = s_min( Q, norm_s( (Word16) abs( (Word32) x[i] ) ) ); + Q = s_min( Q, norm_s( (Word16) L_abs( (Word32) x[i] ) ) ); } return Q; } @@ -217,7 +216,7 @@ Word16 Q_factor_arrL( float *x, Word16 l ) for ( int i = 0; i < l; i++ ) { if ( x[i] >= 1 || x[i] <= -1 ) - Q = s_min( Q, norm_l( (Word32) abs( (Word32) x[i] ) ) ); + Q = s_min( Q, norm_l( (Word32) L_abs( (Word32) x[i] ) ) ); } return Q; } diff --git a/lib_com/frame_ener.c b/lib_com/frame_ener.c deleted file mode 100644 index 03e31126aa4322d8e3a86564b535ab5a14f196cd..0000000000000000000000000000000000000000 --- a/lib_com/frame_ener.c +++ /dev/null @@ -1,359 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include -#include "cnst.h" -#include "prot.h" -#include "wmc_auto.h" -#include "prot_fx.h" -/*----------------------------------------------------------------------------------* - * fer_energy() - * - * Estimation of pitch-synchronous (voiced sounds) or half-frame energy - *----------------------------------------------------------------------------------*/ - -#ifndef IVAS_FLOAT_FIXED -void fer_energy( - const int16_t L_frame, /* i : frame length */ - const int16_t clas, /* i : frame classification */ - const float *synth, /* i : synthesized speech at Fs = 12k8 Hz */ - const float pitch, /* i : pitch period */ - float *enr, /* o : pitch-synchronous or half_frame energy */ - const int16_t offset /* i : speech pointer offset (0 or L_frame) */ -) -{ - int16_t len; - const float *pt_synth; - - if ( clas == VOICED_CLAS || clas == ONSET || clas == SIN_ONSET ) /* Voiced or Onset current frame */ - { - len = (int16_t) ( pitch + 0.5f ); /* pitch value */ - - pt_synth = synth; - if ( offset != 0 ) - { - pt_synth = synth + L_frame - len; - } - - emaximum( pt_synth, len, enr ); /* pitch synchronous E */ - } - else - { - pt_synth = synth; - if ( offset != 0 ) - { - pt_synth = synth + L_frame / 2; - } - - *enr = dotp( pt_synth, pt_synth, L_frame / 2 ); - *enr /= (float) ( L_frame / 2 ); - } - return; -} -#endif - -void fer_energy_fx( - const Word16 L_frame, /* i : frame length */ - const Word16 clas, /* i : frame classification */ - const Word32 *synth, /* i : synthesized speech at Fs = 12k8 Hz Q(q_synth) */ - const Word16 q_synth, /* i : synthesized speech at Fs = 12k8 Hz */ - const Word16 pitch, /* i : pitch period Q0 */ - Word32 *enr, /* o : pitch-synchronous or half_frame energy Q0 */ - const Word16 offset /* i : speech pointer offset (0 or L_frame) */ -) -{ - Word16 len, shift, exp; - const Word32 *pt_synth; - Word16 enr_tmp, i; - Word64 W_tmp; - - test(); - test(); - IF( EQ_16( clas, VOICED_CLAS ) || EQ_16( clas, ONSET ) || EQ_16( clas, SIN_ONSET ) ) /* Voiced or Onset current frame */ - { - len = ( pitch ); /* pitch value */ - move16(); - - pt_synth = synth; - IF( offset != 0 ) - { - pt_synth = synth + sub( L_frame, len ); - } - - emaximum_32fx( q_synth, pt_synth, len, enr ); /* pitch synchronous E */ - } - ELSE - { - pt_synth = synth; - IF( offset != 0 ) - { - pt_synth = synth + shr( L_frame, 1 ); - } - - W_tmp = 0; - move64(); - FOR( i = 0; i < L_frame / 2; i++ ) - { - W_tmp = W_add( W_tmp, W_mult0_32_32( pt_synth[i], pt_synth[i] ) ); // Q = q_synth * 2 - } - shift = W_norm( W_tmp ); - W_tmp = W_shl( W_tmp, shift ); // Q = q_synth * 2 + shift - *enr = W_extract_h( W_tmp ); // Q = q_synth * 2 + shift - 32 - move32(); - - enr_tmp = BASOP_Util_Divide3216_Scale( *enr, shr( L_frame, 1 ) /*Q0*/, &exp ); - *enr = L_shr( L_deposit_l( enr_tmp ), sub( sub( sub( shift, 32 ), exp ), 1 ) ); /*Q0*/ - move32(); - } - return; -} - - -/*----------------------------------------------------------------------------------* - * frame_ener() - * - * Estimation of pitch-synchronous (voiced) or mean half-frame (unvoiced) energy - *----------------------------------------------------------------------------------*/ -Word16 frame_ener_fx( - const Word16 L_frame, /* i : length of the frame */ - const Word16 clas, /* i : frame classification */ - const Word16 *synth, /* i : synthesized speech at Fs = 12k8 Hz Q_new */ - const Word16 pitch, /* i : pitch period Q0 */ - Word32 *enr_q, /* o : pitch-synchronous or half_frame energy Q0 */ - const Word16 offset, /* i : speech pointer offset (0 or L_FRAME) */ - const Word16 Q_new, /* i : Scaling factor */ - Word16 shift, /* i : Shift need to obtain 12 bits vectors */ - const Word16 enc /* i : Encoder/decoder */ -) -{ - Word16 len, exp_enrq, exp_tmp, pos; - Word16 i; - const Word16 *pt_synth; - Word32 Ltmp; - - exp_enrq = 0; - move16(); - test(); - test(); - IF( ( EQ_16( clas, VOICED_CLAS ) ) || ( EQ_16( clas, ONSET ) ) || ( EQ_16( clas, SIN_ONSET ) ) ) /* current frame is voiced */ - { - /* current frame is voiced */ - len = pitch; - move16(); /* pitch value at the end of frame */ - pt_synth = synth; - if ( offset != 0 ) - { - pt_synth = synth + sub( L_frame, len ); - } - emaximum_fx( Q_new, pt_synth, len, enr_q ); - IF( enc != 0 ) - { - exp_enrq = norm_l( *enr_q ); - *enr_q = L_shl( *enr_q, exp_enrq ); - move32(); - exp_enrq = sub( exp_enrq, 2 ); - } - } - ELSE - { - /* current frame is unvoiced */ - Word16 L_frame2, exp2, enr_q_tmp; - - L_frame2 = shr( L_frame, 1 ); - pos = 0; - move16(); - - if ( offset != 0 ) - { - pos = sub( L_frame, L_frame2 ); - } -#ifdef BASOP_NOGLOB - Ltmp = L_mult_sat( synth[pos], synth[pos] ); /*2 * Qnew + 1*/ -#else - Ltmp = L_mult( synth[pos], synth[pos] ); -#endif - FOR( i = 1; i < L_frame2; i++ ) - { -#ifdef BASOP_NOGLOB - Ltmp = L_mac_sat( Ltmp, synth[pos + i], synth[pos + i] ); /*2 * Qnew + 1*/ -#else /* BASOP_NOGLOB */ - Ltmp = L_mac( Ltmp, synth[pos + i], synth[pos + i] ); -#endif - } - test(); - IF( EQ_32( Ltmp, MAX_32 ) || enc != 0 ) - { - /* scale down when overflow occurs */ - *enr_q = Energy_scale( synth + pos, L_frame2, shift, &exp_enrq ); - move32(); - } - ELSE - { - shift = 0; - move16(); - /* Normalize acc in Q31 (energy already calculated) */ - pos = norm_l( Ltmp ); - Ltmp = L_shl( Ltmp, pos ); - exp_enrq = sub( 30, pos ); /* exponent = 0..30 */ - *enr_q = Ltmp; - move32(); - } - - /* enr2 = 1.0f/L_FRAME2 * dot_product(synth, synth, L_FRAME2) */ - exp_enrq = sub( exp_enrq, shl( shift, 1 ) ); - - IF( enc != 0 ) - { - assert( L_frame == 256 || L_frame == 320 ); - - exp_tmp = add( shl( Q_new, 1 ), -2 + 7 ); /* L_subfr == L_SUBFR */ - exp_enrq = sub( exp_enrq, exp_tmp ); - exp_enrq = sub( 31, exp_enrq ); - - IF( EQ_16( L_frame, 320 ) ) - { - *enr_q = Mult_32_16( *enr_q, 26214 ); /*x 0.8 to get /160*/ - move32(); - i = norm_l( *enr_q ); - *enr_q = L_shl( *enr_q, i ); - move32(); - exp_enrq = add( i, exp_enrq ); - } - } - ELSE - { - exp_enrq = sub( exp_enrq, add( Q_new, Q_new ) ); - enr_q_tmp /*Q30 exp2+exp_enrq*/ = BASOP_Util_Divide3216_Scale( *enr_q /*Q31*/, L_frame2 /*Q0*/, &exp2 ); - *enr_q = L_shr( L_deposit_l( enr_q_tmp ), sub( 30, add( exp2, exp_enrq ) ) ); /*Q0*/ - move32(); - *enr_q = L_add( *enr_q, 1 ); - move32(); - exp_enrq = 0; - move16(); - } - } - - return exp_enrq; -} - -/*------------------------------------------------------------------------* - * frame_energy() - * - * Compute pitch-synchronous energy at the frame end - *------------------------------------------------------------------------*/ -Word16 frame_energy_fx( /* o : Frame energy in Q8 */ - Word16 L_frame, - const Word16 *pitch, /* i : pitch values for each subframe Q6 */ - const Word16 *speech, /* i : pointer to speech signal for E computation Q_syn*/ - const Word16 lp_speech, /* i : long term active speech energy average Q8 */ - Word16 *frame_ener, /* o : pitch-synchronous energy at frame end Q8 */ - const Word16 Q_syn /* i : Synthesis scaling */ -) -{ - Word32 Ltmp; - const Word16 *pt1; - Word16 tmp16, exp1, exp2, tmp1, tmp2; - Word16 len, enern; -#ifdef BASOP_NOGLOB_DECLARE_LOCAL - Flag Overflow = 0; - move32(); -#endif - - - /* len = (0.5f * (pitch[2]/64.0 + pitch[3]/64.0) + 0.5f) */ -#ifdef BASOP_NOGLOB - len = mult_r( add_o( pitch[2], pitch[3], &Overflow ), 256 ); -#else - len = mult_r( add( pitch[2], pitch[3] ), 256 ); -#endif - - if ( LT_16( len, L_SUBFR ) ) - { - len = shl( len, 1 ); - } - pt1 = speech + sub( L_frame, len ); - - /* *frame_ener = 10.0f * log10(dot_product(pt1, pt1, len) / (float)len) */ - - tmp1 = norm_s( len ); - tmp2 = shl( len, tmp1 ); - tmp1 = sub( 15, tmp1 ); - - Ltmp = Dot_productSq16HQ( 0, pt1, len, &exp1 ); - exp1 = sub( exp1, shl( Q_syn, 1 ) ); - exp1 = sub( exp1, 1 ); /* compensation of leftshift caused by mac operation in dot_productSq16HQ */ - tmp16 = BASOP_Util_Divide3216_Scale( Ltmp, len, &exp2 ); - - exp1 = add( exp1, exp2 ); - exp1 = add( exp1, 1 ); /* compensate result of division Q-1 */ - - - tmp2 = norm_s( tmp16 ); - Ltmp = L_shl( L_deposit_h( tmp16 ), tmp2 ); /*Q16, (exp1-tmp2) = Q31, exp1-tmp2+15*/ - - Ltmp = BASOP_Util_Log2( Ltmp ); /*Q(31-6) = Q25*/ - exp1 = sub( 15 + exp1, tmp2 ); - - /*add ld(2^exp1)=exp1 but check format, first*/ - tmp16 = sub( sub( 15, norm_s( exp1 ) ), 5 ); /*factor to shift Ltmp and exp1 with (shr) to avoid overflows when adding*/ -#ifdef BASOP_NOGLOB - Ltmp = L_shr_o( Ltmp, tmp16, &Overflow ); /*Q25, tmp16*/ -#else - Ltmp = L_shr( Ltmp, tmp16 ); /*Q25, tmp16*/ -#endif - exp2 = shr( exp1, tmp16 ); /*Q0 , tmp16*/ -#ifdef BASOP_NOGLOB - Ltmp = L_add_o( Ltmp, L_shl( L_deposit_l( exp2 ), 25 ), &Overflow ); /*Q25, tmp16, normalized*/ -#else - Ltmp = L_add( Ltmp, L_shl( L_deposit_l( exp2 ), 25 ) ); /*Q25, tmp16, normalized*/ -#endif - - /*make 10*log10 out of log2*/ - Ltmp = Mpy_32_16_1( Ltmp, LG10 ); /*Q25,tmp16 * Q13 = Q23, tmp16*/ -#ifdef BASOP_NOGLOB - *frame_ener = extract_h( L_shl_o( Ltmp, add( tmp16, 1 ), &Overflow ) ); /*Q8*/ - move16(); - enern = sub_o( *frame_ener, lp_speech, &Overflow ); /*Q8*/ -#else - *frame_ener = extract_h( L_shl( Ltmp, add( tmp16, 1 ) ) ); /*Q8*/ - move16(); - enern = sub( *frame_ener, lp_speech ); /*Q8*/ -#endif - - return enern; -} diff --git a/lib_com/frame_ener_fx.c b/lib_com/frame_ener_fx.c index e9075a02497f53a2a1858bf29e13a3a85b1b99ef..68fdf33c3a2db5ba8703f436ddc1e1043d17eef4 100644 --- a/lib_com/frame_ener_fx.c +++ b/lib_com/frame_ener_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other @@ -38,9 +38,8 @@ #include "options.h" #include #include "cnst.h" -#include "prot.h" -#include "wmc_auto.h" #include "prot_fx.h" +#include "wmc_auto.h" /*----------------------------------------------------------------------------------* * fer_energy() * @@ -161,18 +160,10 @@ Word16 frame_ener_fx( { pos = sub( L_frame, L_frame2 ); } -#ifdef BASOP_NOGLOB Ltmp = L_mult_sat( synth[pos], synth[pos] ); /*2 * Qnew + 1*/ -#else - Ltmp = L_mult( synth[pos], synth[pos] ); -#endif FOR( i = 1; i < L_frame2; i++ ) { -#ifdef BASOP_NOGLOB Ltmp = L_mac_sat( Ltmp, synth[pos + i], synth[pos + i] ); /*2 * Qnew + 1*/ -#else /* BASOP_NOGLOB */ - Ltmp = L_mac( Ltmp, synth[pos + i], synth[pos + i] ); -#endif } test(); IF( EQ_32( Ltmp, MAX_32 ) || enc != 0 ) @@ -255,11 +246,7 @@ Word16 frame_energy_fx( /* o : Frame energy in Q8 /* len = (0.5f * (pitch[2]/64.0 + pitch[3]/64.0) + 0.5f) */ -#ifdef BASOP_NOGLOB len = mult_r( add_o( pitch[2], pitch[3], &Overflow ), 256 ); -#else - len = mult_r( add( pitch[2], pitch[3] ), 256 ); -#endif if ( LT_16( len, L_SUBFR ) ) { @@ -289,30 +276,16 @@ Word16 frame_energy_fx( /* o : Frame energy in Q8 exp1 = sub( 15 + exp1, tmp2 ); /*add ld(2^exp1)=exp1 but check format, first*/ - tmp16 = sub( sub( 15, norm_s( exp1 ) ), 5 ); /*factor to shift Ltmp and exp1 with (shr) to avoid overflows when adding*/ -#ifdef BASOP_NOGLOB - Ltmp = L_shr_o( Ltmp, tmp16, &Overflow ); /*Q25, tmp16*/ -#else - Ltmp = L_shr( Ltmp, tmp16 ); /*Q25, tmp16*/ -#endif - exp2 = shr( exp1, tmp16 ); /*Q0 , tmp16*/ -#ifdef BASOP_NOGLOB + tmp16 = sub( sub( 15, norm_s( exp1 ) ), 5 ); /*factor to shift Ltmp and exp1 with (shr) to avoid overflows when adding*/ + Ltmp = L_shr_o( Ltmp, tmp16, &Overflow ); /*Q25, tmp16*/ + exp2 = shr( exp1, tmp16 ); /*Q0 , tmp16*/ Ltmp = L_add_o( Ltmp, L_shl( L_deposit_l( exp2 ), 25 ), &Overflow ); /*Q25, tmp16, normalized*/ -#else - Ltmp = L_add( Ltmp, L_shl( L_deposit_l( exp2 ), 25 ) ); /*Q25, tmp16, normalized*/ -#endif /*make 10*log10 out of log2*/ - Ltmp = Mpy_32_16_1( Ltmp, LG10 ); /*Q25,tmp16 * Q13 = Q23, tmp16*/ -#ifdef BASOP_NOGLOB + Ltmp = Mpy_32_16_1( Ltmp, LG10 ); /*Q25,tmp16 * Q13 = Q23, tmp16*/ *frame_ener = extract_h( L_shl_o( Ltmp, add( tmp16, 1 ), &Overflow ) ); /*Q8*/ move16(); enern = sub_o( *frame_ener, lp_speech, &Overflow ); /*Q8*/ -#else - *frame_ener = extract_h( L_shl( Ltmp, add( tmp16, 1 ) ) ); /*Q8*/ - move16(); - enern = sub( *frame_ener, lp_speech ); /*Q8*/ -#endif return enern; } diff --git a/lib_com/get_gain.c b/lib_com/get_gain.c deleted file mode 100644 index d222bd68d9f64dab5fc2c943f2220092ae65774a..0000000000000000000000000000000000000000 --- a/lib_com/get_gain.c +++ /dev/null @@ -1,179 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include "prot.h" -#include "wmc_auto.h" -#include "prot_fx.h" - -/*----------------------------------------------------------------------------------* - * get_gain() - * - * - *----------------------------------------------------------------------------------*/ - -#ifndef IVAS_FLOAT_FIXED -/*! r: codebook gain (adaptive or fixed) */ -float get_gain_flt( - const float x[], /* i : target signal */ - const float y[], /* i : filtered codebook excitation */ - const int16_t n, /* i : segment length */ - float *en_y /* o : energy of y (sum of y[]^2, optional) */ -) -{ - float corr = 0.0f, ener = 1e-6f; - int16_t i; - - for ( i = 0; i < n; i++ ) - { - corr += x[i] * y[i]; - ener += y[i] * y[i]; - } - - if ( en_y ) - { - *en_y = ener; - } - - return ( corr / ener ); -} -#endif - -Word32 get_gain( /* output: codebook gain (adaptive or fixed) Q16 */ - const Word16 x[], /* input : target signal Qx */ - const Word16 y[], /* input : filtered codebook excitation Qx */ - const Word16 n /* input : segment length */ -) -{ - Word32 tcorr, tener, Lgain; - Word16 exp_c, exp_e, exp, tmp; -#ifdef BASOP_NOGLOB_DECLARE_LOCAL - Flag Overflow = 0; - move32(); -#endif - - - tcorr = L_deposit_l( 0 ); - tener = L_deposit_l( 0 ); - - - /*----------------------------------------------------------------* - * Find gain based on inter-correlation product - *----------------------------------------------------------------*/ - - tcorr = Dot_product16HQ( 0, x, y, n, &exp_c ); - tener = Dot_productSq16HQ( 0, y, n, &exp_e ); - -#ifdef BASOP_NOGLOB - BASOP_Util_Divide_MantExp( round_fx_o( tcorr, &Overflow ), exp_c, s_max( round_fx_o( tener, &Overflow ), 1 ), exp_e, &tmp, &exp ); - Lgain = L_shl_o( L_deposit_l( tmp ) /*Q15*/, add( 1, exp ), &Overflow ) /*Q16*/; -#else - BASOP_Util_Divide_MantExp( round_fx( tcorr ), exp_c, s_max( round_fx( tener ), 1 ), exp_e, &tmp, &exp ); - Lgain = L_shl( L_deposit_l( tmp ) /*Q15*/, add( 1, exp ) ) /*Q16*/; -#endif - - return Lgain; -} - -Word32 get_gain2( /* output: codebook gain (adaptive or fixed) Q16 */ - const Word16 x[], /* input : target signal */ - const Word16 y[], /* input : filtered codebook excitation */ - const Word16 n /* input : segment length */ -) -{ - Word32 tcorr, tener, Lgain; - Word16 m_corr, m_ener, negative, Q_corr, Q_ener; -#ifdef BASOP_NOGLOB_DECLARE_LOCAL - Flag Overflow = 0; - move32(); -#endif - - negative = 0; - move16(); - - /*----------------------------------------------------------------* - * Find gain based on inter-correlation product - *----------------------------------------------------------------*/ - tcorr = Dot_product16HQ( 0, x, y, n, &Q_corr ); - tener = Dot_productSq16HQ( 0, y, n, &Q_ener ); - - tener = L_max( tener, 1 ); - - if ( tcorr <= 0 ) - { - negative = 1; - move16(); - } - BASOP_SATURATE_WARNING_OFF_EVS /*tcorr max be negative maxvall - not critical*/ - tcorr = L_abs( tcorr ); - BASOP_SATURATE_WARNING_ON_EVS - - m_corr = extract_h( tcorr ); - - m_ener = extract_h( tener ); - - IF( GT_16( m_corr, m_ener ) ) - { - m_corr = shr( m_corr, 1 ); - Q_corr = add( Q_corr, 1 ); - } - if ( m_ener == 0 ) - { - move16(); - m_corr = 0x7FFF; - } - IF( m_ener != 0 ) - { - m_corr = div_s( m_corr, m_ener ); - } - - Q_corr = sub( Q_corr, Q_ener ); - -#ifdef BASOP_NOGLOB - Lgain = L_shl_o( L_deposit_l( m_corr ), add( Q_corr, 1 ), &Overflow ); /* Lgain in Q16 */ -#else - Lgain = L_shl( L_deposit_l( m_corr ), add( Q_corr, 1 ) ); /* Lgain in Q16 */ -#endif - - if ( negative != 0 ) - { - Lgain = L_negate( Lgain ); /* Lgain in Q16 */ - } - - - return Lgain; -} diff --git a/lib_com/get_gain_fx.c b/lib_com/get_gain_fx.c index be4d063e75f103c5905a7d52f8cd3cde6d4eaa9d..8ec4f5a40314afa27263cb7a4a77d8a31dd8d53c 100644 --- a/lib_com/get_gain_fx.c +++ b/lib_com/get_gain_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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,9 +36,8 @@ #include #include "options.h" -#include "prot.h" -#include "wmc_auto.h" #include "prot_fx.h" +#include "wmc_auto.h" /*----------------------------------------------------------------------------------* * get_gain() @@ -71,13 +70,8 @@ Word32 get_gain( /* output: codebook gain (adaptive or fixed) tcorr = Dot_product16HQ( 0, x, y, n, &exp_c ); tener = Dot_productSq16HQ( 0, y, n, &exp_e ); -#ifdef BASOP_NOGLOB BASOP_Util_Divide_MantExp( round_fx_o( tcorr, &Overflow ), exp_c, s_max( round_fx_o( tener, &Overflow ), 1 ), exp_e, &tmp, &exp ); Lgain = L_shl_o( L_deposit_l( tmp ) /*Q15*/, add( 1, exp ), &Overflow ) /*Q16*/; -#else - BASOP_Util_Divide_MantExp( round_fx( tcorr ), exp_c, s_max( round_fx( tener ), 1 ), exp_e, &tmp, &exp ); - Lgain = L_shl( L_deposit_l( tmp ) /*Q15*/, add( 1, exp ) ) /*Q16*/; -#endif return Lgain; } @@ -136,11 +130,7 @@ Word32 get_gain2( /* output: codebook gain (adaptive or fixed) Q_corr = sub( Q_corr, Q_ener ); -#ifdef BASOP_NOGLOB Lgain = L_shl_o( L_deposit_l( m_corr ), add( Q_corr, 1 ), &Overflow ); /* Lgain in Q16 */ -#else - Lgain = L_shl( L_deposit_l( m_corr ), add( Q_corr, 1 ) ); /* Lgain in Q16 */ -#endif if ( negative != 0 ) { diff --git a/lib_com/gs_bitallocation_fx.c b/lib_com/gs_bitallocation_fx.c index 5bd82fdab724b3e4a871d45e85d42b7ef077c81e..87ba794d46728dabaed82ef6287774aad7c09f14 100644 --- a/lib_com/gs_bitallocation_fx.c +++ b/lib_com/gs_bitallocation_fx.c @@ -95,12 +95,8 @@ void bands_and_bit_alloc_fx( set16_fx( out_bits_per_bands, 0, MBANDS_GN_BITALLOC16k ); /* To adapt current energy band to PVQ freq band for sorting*/ -#ifdef BASOP_NOGLOB ener_vec[0] = add_o( Ener_per_bd_iQ[0], Ener_per_bd_iQ[1], &Overflow ); /*Q12 */ -#else /* BASOP_NOGLOB */ - ener_vec[0] = add( Ener_per_bd_iQ[0], Ener_per_bd_iQ[1] ); /*Q12 */ -#endif - Copy( Ener_per_bd_iQ_tmp + 1, ener_vec, MBANDS_GN - 1 ); /*Q12 */ + Copy( Ener_per_bd_iQ_tmp + 1, ener_vec, MBANDS_GN - 1 ); /*Q12 */ ener_vec[MBANDS_GN - 1] = ener_vec[MBANDS_GN - 2]; move16(); IF( EQ_16( L_frame, L_FRAME16k ) ) @@ -124,40 +120,7 @@ void bands_and_bit_alloc_fx( move16(); bit_new_bands = 5; move16(); -#ifdef ADD_LRTD - if ( GT_32( core_brate, ACELP_16k40 ) && EQ_16( L_frame, L_FRAME16k ) ) - { - bit_new_bands = 7; - move16(); - } - - i = 0; - move16(); - WHILE( LT_16( i, SIZE_BRATE_INTERMED_TBL ) ) - { - IF( LE_32( core_brate, brate_intermed_tbl[i] ) ) - { - BREAK; - } - - IF( EQ_32( brate_intermed_tbl[i], ACELP_24k40 ) ) - { - BREAK; - } - - i = add( i, 1 ); - } - - if ( GT_16( element_mode, EVS_MONO ) && EQ_16( coder_type, AUDIO ) && - LE_32( core_brate, STEREO_GSC_BIT_RATE_ALLOC ) && EQ_32( brate_intermed_tbl[i], ACELP_9k60 ) ) /* Bit allocation should be mapped to 8 kb/s instead of 9.6 kb/s in this case */ - { - i = sub( i, 1 ); - } - - bit_index = i_mult2( BRATE2IDX_fx( brate_intermed_tbl[i] ), 17 ); -#else bit_index = i_mult2( BRATE2IDX_fx( core_brate ), 17 ); -#endif bit_index_mem = bit_index; move16(); @@ -193,668 +156,330 @@ void bands_and_bit_alloc_fx( move16(); } -#ifdef ADD_LRTD - if ( L_frame == L_FRAME16k ) + IF( EQ_16( GSC_noisy_speech, 1 ) ) { - *bit -= 8; - } + SWB_bit_budget = *bit; + move16(); + nb_bands = 5; + move16(); - if ( coder_type == INACTIVE && core_brate <= GSC_LRES_GAINQ_LIMIT ) /* can happen only for 2nd channel inactive */ - { - *bit += GSC_LRES_NB_NITS; - } + st_band = nb_bands; + move16(); - if ( *bit > 0 ) - { - if ( GSC_IVAS_mode > 0 ) - { - SWB_bit_budget = *bit; - st_band = 5; + set32_fx( bits_per_bands, 0, MBANDS_GN ); + /*bit_fracf = (1.0f/nb_bands)*(SWB_bit_budget); */ + bit_fracf = L_mult( div_s( 1, nb_bands ), shl( SWB_bit_budget, 2 ) ); /* Q18 */ - set_f( bits_per_bands, 0, MBANDS_GN_BITALLOC16k ); + nb_tot_bands = sub( nb_bands_max, 6 ); + nb_tot_bands = s_min( nb_tot_bands, 16 ); - /* 2- Decide the pourcentage of bits allocated to LF (between 50-75%) depending of the temporal contribution in GSC */ - bit_fracf = ( -0.125f * Diff_len + 76.0f ) / 100; - bit_fracf = check_bounds( bit_fracf, 0.50f, 0.75f ); + FOR( j = 0; j < 2; j++ ) + { + i = j; + move16(); + max_ener_band[j] = i; + move16(); + ener_vec[i] = 0; + move16(); + } - /* Adjusment of the bitrate between LF and HF base on the content type */ - /* 1 = new GSC bit alloc - 2 = GSC bit alloc for tc frame - 3 = more music like (should not happen often given music is coded with dft) */ + FOR( ; j < nb_bands; j++ ) + { + i = maximum_fx( ener_vec, nb_tot_bands, &etmp ); + max_ener_band[j] = i; + move16(); + ener_vec[i] = 0; + move16(); + } - if ( GSC_IVAS_mode <= 3 ) - { - nb_bands_max -= 6; - } + set32_fx( bits_per_bands, bit_fracf, nb_bands ); + } + ELSE + { + bit_index++; + bit_tmp = sub( *bit, GSC_freq_bits[bit_index] ); + bit_index++; + nb_bands_max = add( nb_bands_max, GSC_freq_bits[bit_index] ); + bit_index++; - if ( GSC_IVAS_mode == 2 ) - { - bit_fracf += 0.1f; - nb_bands_max--; - } + *pvq_len = 112; + move16(); + st_band = 7; + move16(); - if ( GSC_IVAS_mode == 3 ) - { - bit_fracf -= 0.1f; - nb_bands_max += 3; - } + IF( LE_32( core_brate, ACELP_9k60 ) ) + { + *pvq_len = 80; + move16(); + st_band = 5; + move16(); - /* First find how much we want to share between LF and HF, at low bitrate, a miminum of bits is needed in LF by limitating the number of bands*/ - /* Adjust the number of band based on the content type and bitrate */ - nb_bands_adj = 1.0f; - if ( GSC_IVAS_mode == 1 && core_brate < GSC_L_RATE_STG ) - { - nb_bands_adj = 0.0125f * SWB_bit_budget - 0.75f; - } - else if ( GSC_IVAS_mode != 2 && core_brate > GSC_H_RATE_STG ) + IF( Diff_len == 0 ) { - nb_bands_adj = 0.02f * SWB_bit_budget - 1.2f; + nb_bands_max = add( nb_bands_max, 2 ); + bit_tmp = sub( bit_tmp, 13 ); } - nb_bands_max = (int16_t) ( nb_bands_max * nb_bands_adj + 0.5f ); - nb_bands_max = check_bounds_s( nb_bands_max, 5, nb_tot_bands ); + } - bit_fracf *= SWB_bit_budget; + ELSE IF( Diff_len == 0 ) + { + nb_bands_max = add( nb_bands_max, 2 ); + bit_tmp = sub( bit_tmp, 17 ); + } - /* Estimation of the number of bit used in HF */ - /* with only the first weigthing The number of bits in max_ener_band[st_band-1] = 17% of bit_fracf */ - mb = .17f * bit_fracf; - mp = ( 2.0f * DSR_NB_PULSE ); - if ( core_brate < GSC_L_RATE_STG && GSC_IVAS_mode == 3 ) - { - mp = 1.5f * DSR_NB_PULSE; - } - else if ( core_brate < GSC_L_RATE_STG ) + nb_bands = shr( *pvq_len, 4 ); + + /*------------------------------------------------------------------------ + * Ajustement of the maximum number of bands in function of the + * dynamics of the spectrum (more or less speech like) + *-----------------------------------------------------------------------*/ + test(); + test(); + test(); + test(); + IF( EQ_16( coder_type, INACTIVE ) || GE_16( noise_lev, NOISE_LEVEL_SP3 ) ) + { + /* Probably classification error -> concentrate bits on LF */ + if ( GE_32( core_brate, ACELP_8k00 ) ) { - mp = DSR_NB_PULSE; + nb_bands_max = add( nb_bands, 1 ); } - - /* We want max_ener_band[st_band] <= max_ener_band[st_band-1] and max_ener_band[nb_bands_max-1] <= max_ener_band[st_band]*/ - /* We will estimate the number of bits to allocate of HF and put the remaining bits, if any, back on LF */ - /* compute the total possible number of band to be coded */ - nb_tot_bands = (int16_t) ( ( SWB_bit_budget - bit_fracf ) / ( mp + ( mb - mp ) / 2.0f ) ); - mp = min( mp, mb ); - if ( nb_tot_bands + st_band > nb_bands_max ) + else { - bit_adj = ( ( mb + mp ) / 2 ) * ( nb_tot_bands + st_band - nb_bands_max ); - bit_adj = max( 0, bit_adj ); - nb_tot_bands = nb_bands_max - st_band; - bit_fracf += bit_adj; + nb_bands_max = nb_bands; + move16(); } - nb_tot_bands += st_band; + } + ELSE IF( GE_16( noise_lev, NOISE_LEVEL_SP2 ) || + ( LE_32( core_brate, ACELP_13k20 ) && GE_32( core_brate, ACELP_9k60 ) && cor_strong_limit == 0 ) ) /* Very low dynamic, tend to speech, do not try to code HF at all */ + { + nb_bands_max = sub( nb_bands_max, 2 ); + } + ELSE IF( GE_16( noise_lev, NOISE_LEVEL_SP1 ) ) /* Very low dynamic, tend to speech, code less HF */ + { + nb_bands_max = sub( nb_bands_max, 1 ); + } - /* Allocate bits to LF */ - etmp = 0.23f; - for ( j = 0; j < st_band; j++ ) - { - i = j; - max_ener_band[j] = i; - ener_vec[i] = MIN16B; - bits_per_bands[j] = etmp * bit_fracf; - etmp -= 0.015f; - } + test(); + if ( ( EQ_16( bwidth, NB ) ) && GT_16( nb_bands_max, 10 ) ) + { + nb_bands_max = 10; + move16(); + } - SWB_bit_budget -= bit_fracf; + /*------------------------------------------------------------------------ + * Find extra number of band to code according to bit rate availables + *-----------------------------------------------------------------------*/ + test(); + WHILE( GE_16( bit_tmp, bit_new_bands ) && LE_16( nb_bands, sub( nb_bands_max, 1 ) ) ) + { + test(); + bit_tmp = sub( bit_tmp, bit_new_bands ); + nb_bands = add( nb_bands, 1 ); + } - /* Find low energy band in HF */ - set_s( nb_pulse_per_band, 2, MBANDS_GN_BITALLOC16k ); - for ( i = st_band + 2; i < nb_tot_bands - 1; i++ ) - { - if ( ener_vec[i] < ener_vec[i - 1] && ener_vec[i] < ener_vec[i + 1] ) - { - nb_pulse_per_band[i] = 1; - } - } - for ( j = st_band; j < nb_tot_bands; j++ ) - { - if ( j > 6 ) - { - i = maximum( ener_vec, nb_tot_bands, &etmp ); - } - else - { - i = j; - } + /*------------------------------------------------------------------------ + * Fractional bits to distribute on the first x bands + *-----------------------------------------------------------------------*/ - max_ener_band[j] = i; - ener_vec[i] = MIN16B; - } + { + bit_fracf = L_mult( div_s( 1, st_band ), shl( bit_tmp, 2 ) ); /* Q18 */ + } + /*------------------------------------------------------------------------ + * Complete the bit allocation per frequency band + *-----------------------------------------------------------------------*/ + imax = 5; + move16(); - /* Recompute the final bit distribution for HF */ - if ( nb_tot_bands > st_band ) - { - bit_fracf = DSR_NB_PULSE; - mb = ( SWB_bit_budget * 2 / ( nb_tot_bands - st_band ) ) - mp; - bit_fracf = ( mb - mp ) / ( nb_tot_bands - st_band ); - mb -= bit_fracf; - /* Do the distribution */ - for ( j = st_band; j < nb_tot_bands; j++ ) - { - if ( nb_pulse_per_band[max_ener_band[j]] > 1 ) - { - bits_per_bands[max_ener_band[j]] = mb; - } - else - { - bits_per_bands[max_ener_band[j]] = 4.5f; - } - mb -= bit_fracf; - SWB_bit_budget -= bits_per_bands[max_ener_band[j]]; - } - } + if ( GT_32( core_brate, ACELP_9k60 ) ) + { + imax = 7; + move16(); + } + FOR( i = 0; i < imax; i++ ) + { + bits_per_bands[i] = L_add( GSC_freq_bits_fx[bit_index], bit_fracf ); + move32(); /* Q18 */ + bit_index = add( bit_index, 1 ); + } - /* Series of verification in case bit allocated != the budget */ - if ( SWB_bit_budget > 0 ) + IF( Diff_len == 0 ) + { + bit_index = add( bit_index_mem, 10 ); + FOR( i = 0; i < 7; i++ ) { - i = st_band - 1; - while ( SWB_bit_budget > 0 ) - { - bits_per_bands[i]++; - SWB_bit_budget--; - i--; - if ( i == -1 ) - { - i = st_band - 1; - } - } + bits_per_bands[i] = L_add( bits_per_bands[i], GSC_freq_bits_fx[bit_index] ); + move32(); /*chk Q18 */ + bit_index = add( bit_index, 1 ); } + } - nb_bands = nb_tot_bands; - - sum_bit = 0; - j = 0; - for ( i = 0; i < nb_bands; i++ ) - { - if ( bits_per_bands[i] > 112 ) - { - sum_bit += bits_per_bands[i] - 112; - bits_per_bands[i] = 112; - j = i + 1; - } - - /* safety check for overage bit reallocation */ - else if ( bits_per_bands[i] + sum_bit / 3 > 112 ) - { - j = i + 1; - } - } + /*-------------------------------------------------------------------------- + * Complete the bit allocation per frequency band for 16kHz high brate mode + *--------------------------------------------------------------------------*/ - if ( sum_bit != 0 ) + { + FOR( j = st_band; j < nb_bands; j++ ) { - sum_bit /= ( nb_bands - j ); - for ( i = j; i < nb_bands; i++ ) - { - bits_per_bands[i] += sum_bit; - } + bits_per_bands[j] = L_shl( bit_new_bands, 18 ); + move32(); /*chk Q18 */ } } - else -#endif - IF( EQ_16( GSC_noisy_speech, 1 ) ) - { - SWB_bit_budget = *bit; - move16(); - nb_bands = 5; - move16(); - -#ifdef ADD_LRTD - - fzero_val = 0.0f; - if ( element_mode > EVS_MONO ) - { - fzero_val = MIN16B_FLT; - } - if ( coder_type == UNVOICED && element_mode > EVS_MONO ) - { - nb_bands = 3; - if ( SWB_bit_budget > 20 ) - { - nb_bands = 5; - } - } - else if ( bwidth < SWB ) - { - nb_bands = 7; - } - -#endif + /*-------------------------------------------------------------------------- + * Compute a maximum band (band offset) for the search on maximal energy + * This is function of the spectral dynamic and the bitrate + *--------------------------------------------------------------------------*/ - st_band = nb_bands; - move16(); + bandoffset = sub( nb_tot_bands, add( nb_bands, 2 ) ); - set32_fx( bits_per_bands, 0, MBANDS_GN ); - /*bit_fracf = (1.0f/nb_bands)*(SWB_bit_budget); */ - bit_fracf = L_mult( div_s( 1, nb_bands ), shl( SWB_bit_budget, 2 ) ); /* Q18 */ + test(); + test(); + test(); + test(); + test(); + IF( LE_16( noise_lev, NOISE_LEVEL_SP1a ) ) + { + bandoffset = sub( bandoffset, 1 ); + } + ELSE IF( ( LE_32( core_brate, ACELP_13k20 ) && ( EQ_16( coder_type, INACTIVE ) || GE_16( noise_lev, NOISE_LEVEL_SP3 ) ) ) || + ( LE_32( core_brate, ACELP_13k20 ) && GE_32( core_brate, ACELP_9k60 ) && cor_strong_limit == 0 ) ) + { + bandoffset = add( bandoffset, 1 ); + } - nb_tot_bands = sub( nb_bands_max, 6 ); - nb_tot_bands = s_min( nb_tot_bands, 16 ); + bandoffset = s_max( bandoffset, 0 ); - FOR( j = 0; j < 2; j++ ) - { - i = j; - move16(); - max_ener_band[j] = i; - move16(); - ener_vec[i] = 0; - move16(); - } -#ifdef ADD_LRTD - if ( bwidth < SWB ) - { - if ( coder_type == UNVOICED && element_mode > EVS_MONO ) - { - nb_tot_bands = 5; - } -#endif - FOR( ; j < nb_bands; j++ ) - { - i = maximum_fx( ener_vec, nb_tot_bands, &etmp ); - max_ener_band[j] = i; - move16(); - ener_vec[i] = 0; - move16(); - } -#ifdef ADD_LRTD - } - else - { - for ( ; j < nb_bands; j++ ) - { - i = maximum( ener_vec, nb_tot_bands, &etmp ); - max_ener_band[j] = i; - ener_vec[i] = fzero_val; - } - } -#endif - set32_fx( bits_per_bands, bit_fracf, nb_bands ); - } - ELSE + /*-------------------------------------------------------------------------- + * Initiazed sorted vector + * For the first x bands to be included in th final sorted vector + * Sort the remaining bands in decrease energy order + *--------------------------------------------------------------------------*/ + FOR( j = 0; j < nb_tot_bands; j++ ) { - bit_index++; - bit_tmp = sub( *bit, GSC_freq_bits[bit_index] ); - bit_index++; - nb_bands_max = add( nb_bands_max, GSC_freq_bits[bit_index] ); - bit_index++; - - *pvq_len = 112; + max_ener_band[j] = -10; move16(); - st_band = 7; + } + FOR( j = 0; j < st_band; j++ ) + { + max_ener_band[j] = j; move16(); -#ifdef ADD_LRTD - if ( L_frame == L_FRAME16k && core_brate > ACELP_16k40 ) - { - *pvq_len = 160; - st_band = 10; - nb_bands = *pvq_len / 16; - bit_tmp -= 35; - bit_new_bands = 5; - } -#endif - IF( LE_32( core_brate, ACELP_9k60 ) ) - { - *pvq_len = 80; - move16(); - st_band = 5; - move16(); - - IF( Diff_len == 0 ) - { - nb_bands_max = add( nb_bands_max, 2 ); - bit_tmp = sub( bit_tmp, 13 ); - } - } - - ELSE IF( Diff_len == 0 ) - { - nb_bands_max = add( nb_bands_max, 2 ); - bit_tmp = sub( bit_tmp, 17 ); - } - - nb_bands = shr( *pvq_len, 4 ); -#ifdef ADD_LRTD - nb_bands_max = min( nb_bands_max, MBANDS_GN_BITALLOC16k ); -#endif - /*------------------------------------------------------------------------ - * Ajustement of the maximum number of bands in function of the - * dynamics of the spectrum (more or less speech like) - *-----------------------------------------------------------------------*/ - test(); - test(); - test(); - test(); - IF( EQ_16( coder_type, INACTIVE ) || GE_16( noise_lev, NOISE_LEVEL_SP3 ) ) - { - /* Probably classification error -> concentrate bits on LF */ -#ifdef ADD_LRTD - if ( L_frame == L_FRAME16k && core_brate >= ACELP_24k40 ) - { - nb_bands_max = nb_tot_bands - 2; - } - else if ( core_brate >= ACELP_16k40 ) - { - nb_bands_max = nb_bands + 2; - } - else -#endif - if ( GE_32( core_brate, ACELP_8k00 ) ) - { - nb_bands_max = add( nb_bands, 1 ); - } - else - { - nb_bands_max = nb_bands; - move16(); - } - } - ELSE IF( GE_16( noise_lev, NOISE_LEVEL_SP2 ) || - ( LE_32( core_brate, ACELP_13k20 ) && GE_32( core_brate, ACELP_9k60 ) && cor_strong_limit == 0 ) ) /* Very low dynamic, tend to speech, do not try to code HF at all */ - { - nb_bands_max = sub( nb_bands_max, 2 ); - } - ELSE IF( GE_16( noise_lev, NOISE_LEVEL_SP1 ) ) /* Very low dynamic, tend to speech, code less HF */ - { - nb_bands_max = sub( nb_bands_max, 1 ); - } -#ifdef ADD_LRTD - if ( L_frame == L_FRAME16k ) - { - if ( core_brate < ACELP_24k40 ) - { - nb_bands_max -= 4; - } - else if ( core_brate < ACELP_32k ) - { - if ( Diff_len > 0 || noise_lev >= NOISE_LEVEL_SP2 ) - { - nb_bands_max -= 2; - bit_new_bands *= 2; - } - } - else if ( core_brate >= ACELP_32k ) - { - bit_new_bands *= 2; - } - } - -#endif - test(); - if ( ( EQ_16( bwidth, NB ) ) && GT_16( nb_bands_max, 10 ) ) - { - nb_bands_max = 10; - move16(); - } - - /*------------------------------------------------------------------------ - * Find extra number of band to code according to bit rate availables - *-----------------------------------------------------------------------*/ - test(); - WHILE( GE_16( bit_tmp, bit_new_bands ) && LE_16( nb_bands, sub( nb_bands_max, 1 ) ) ) - { - test(); - bit_tmp = sub( bit_tmp, bit_new_bands ); - nb_bands = add( nb_bands, 1 ); - } - - /*------------------------------------------------------------------------ - * Fractional bits to distribute on the first x bands - *-----------------------------------------------------------------------*/ -#ifdef ADD_LRTD - if ( L_frame == L_FRAME16k && core_brate > ACELP_32k ) - { - bit_fracf = 0; - } - else -#endif - { - bit_fracf = L_mult( div_s( 1, st_band ), shl( bit_tmp, 2 ) ); /* Q18 */ - } - /*------------------------------------------------------------------------ - * Complete the bit allocation per frequency band - *-----------------------------------------------------------------------*/ - imax = 5; + ener_vec[j] = -10; move16(); + } + pos = st_band; + move16(); + FOR( ; j < nb_bands; j++ ) + { + i = maximum_fx( ener_vec, sub( nb_tot_bands, bandoffset ), &etmp ); + pos = s_max( pos, i ); + max_ener_band[j] = i; + move16(); + ener_vec[i] = -10; + move16(); + } - if ( GT_32( core_brate, ACELP_9k60 ) ) + /* re-allocate bits to the frames such that the highest band with allocated bits is higher than the threshold */ + test(); + test(); + test(); + IF( GT_16( sub( nb_tot_bands, bandoffset ), nb_bands ) && ( GT_16( pos, 7 ) && EQ_32( core_brate, ACELP_8k00 ) ) && EQ_16( bwidth, WB ) ) + { + band = sub( nb_tot_bands, add( bandoffset, nb_bands ) ); + FOR( j = 0; j < band; j++ ) { - imax = 7; + i = maximum_fx( ener_vec, sub( nb_tot_bands, bandoffset ), &etmp ); + max_ener_band[add( nb_bands, j )] = i; move16(); + ener_vec[i] = -10; + move16(); + bits_per_bands[add( nb_bands, j )] = 1310720; + move32(); /*Q18 */ } - FOR( i = 0; i < imax; i++ ) - { - bits_per_bands[i] = L_add( GSC_freq_bits_fx[bit_index], bit_fracf ); - move32(); /* Q18 */ - bit_index = add( bit_index, 1 ); - } -#ifdef ADD_LRTD - if ( L_frame == L_FRAME16k && core_brate > ACELP_16k40 ) - { - bit_index = 0; - i = imax - 1; - bits_per_bands[i] += Compl_GSC_freq_bits[bit_index]; - i++; - bit_index++; + nb_bands = add( nb_bands, band ); - for ( ; i < 10; i++ ) - { - bits_per_bands[i] += Compl_GSC_freq_bits[bit_index] + bit_fracf; - bit_index++; - } - } -#endif - IF( Diff_len == 0 ) - { - bit_index = add( bit_index_mem, 10 ); - FOR( i = 0; i < 7; i++ ) - { - bits_per_bands[i] = L_add( bits_per_bands[i], GSC_freq_bits_fx[bit_index] ); - move32(); /*chk Q18 */ - bit_index = add( bit_index, 1 ); - } - } -#ifdef ADD_LRTD - if ( bit_fracf < 0 ) - { - for ( j = 0; j < nb_tot_bands; j++ ) - { - bits_per_bands[j] = max( bits_per_bands[j], 0 ); - } - } + bit_tmp = i_mult2( band, 5 ); -#endif - /*-------------------------------------------------------------------------- - * Complete the bit allocation per frequency band for 16kHz high brate mode - *--------------------------------------------------------------------------*/ -#ifdef ADD_LRTD - if ( L_frame == L_FRAME16k && core_brate > ACELP_32k ) + IF( LE_16( band, 2 ) ) { - for ( j = st_band; j < nb_bands; j++ ) + FOR( j = sub( st_band, 1 ); j < nb_bands; j++ ) { - bits_per_bands[j] = bit_new_bands; + bits_per_bands[j] = L_add( bits_per_bands[j], 262144 ); /*Q18 */ + move32(); } - - bit_fracf = ( 1.0f / nb_bands ) * ( bit_tmp ); - - etmp = 2.0f * bit_fracf / ( nb_bands + 1 ); - bit_fracf = etmp; - for ( j = nb_bands - 1; j >= 0; j-- ) - { - bits_per_bands[j] += etmp; - etmp += bit_fracf; - } - } - else -#endif - { - FOR( j = st_band; j < nb_bands; j++ ) - { - bits_per_bands[j] = L_shl( bit_new_bands, 18 ); - move32(); /*chk Q18 */ - } - } - - /*-------------------------------------------------------------------------- - * Compute a maximum band (band offset) for the search on maximal energy - * This is function of the spectral dynamic and the bitrate - *--------------------------------------------------------------------------*/ - - bandoffset = sub( nb_tot_bands, add( nb_bands, 2 ) ); - - test(); - test(); - test(); - test(); - test(); - IF( LE_16( noise_lev, NOISE_LEVEL_SP1a ) ) - { - bandoffset = sub( bandoffset, 1 ); - } - ELSE IF( ( LE_32( core_brate, ACELP_13k20 ) && ( EQ_16( coder_type, INACTIVE ) || GE_16( noise_lev, NOISE_LEVEL_SP3 ) ) ) || - ( LE_32( core_brate, ACELP_13k20 ) && GE_32( core_brate, ACELP_9k60 ) && cor_strong_limit == 0 ) ) - { - bandoffset = add( bandoffset, 1 ); + bit_tmp = add( bit_tmp, add( sub( nb_bands, st_band ), 1 ) ); } - bandoffset = s_max( bandoffset, 0 ); - - /*-------------------------------------------------------------------------- - * Initiazed sorted vector - * For the first x bands to be included in th final sorted vector - * Sort the remaining bands in decrease energy order - *--------------------------------------------------------------------------*/ - FOR( j = 0; j < nb_tot_bands; j++ ) - { - max_ener_band[j] = -10; - move16(); - } - FOR( j = 0; j < st_band; j++ ) - { - max_ener_band[j] = j; - move16(); - ener_vec[j] = -10; - move16(); - } - pos = st_band; + i = 0; move16(); - FOR( ; j < nb_bands; j++ ) - { - i = maximum_fx( ener_vec, sub( nb_tot_bands, bandoffset ), &etmp ); - pos = s_max( pos, i ); - max_ener_band[j] = i; - move16(); - ener_vec[i] = -10; - move16(); - } - - /* re-allocate bits to the frames such that the highest band with allocated bits is higher than the threshold */ - test(); - test(); - test(); - IF( GT_16( sub( nb_tot_bands, bandoffset ), nb_bands ) && ( GT_16( pos, 7 ) && EQ_32( core_brate, ACELP_8k00 ) ) && EQ_16( bwidth, WB ) ) + j = 0; + move16(); + FOR( ; bit_tmp > 0; bit_tmp-- ) { - band = sub( nb_tot_bands, add( bandoffset, nb_bands ) ); - FOR( j = 0; j < band; j++ ) + bits_per_bands[j] = L_sub( bits_per_bands[j], 262144 ); /*Q18 */ + j = add( j, 1 ); + if ( EQ_16( j, sub( st_band, i ) ) ) { - i = maximum_fx( ener_vec, sub( nb_tot_bands, bandoffset ), &etmp ); - max_ener_band[add( nb_bands, j )] = i; + j = 0; move16(); - ener_vec[i] = -10; - move16(); - bits_per_bands[add( nb_bands, j )] = 1310720; - move32(); /*Q18 */ - } - nb_bands = add( nb_bands, band ); - - bit_tmp = i_mult2( band, 5 ); - - IF( LE_16( band, 2 ) ) - { - FOR( j = sub( st_band, 1 ); j < nb_bands; j++ ) - { - bits_per_bands[j] = L_add( bits_per_bands[j], 262144 ); /*Q18 */ - move32(); - } - bit_tmp = add( bit_tmp, add( sub( nb_bands, st_band ), 1 ) ); } - - i = 0; - move16(); - j = 0; - move16(); - FOR( ; bit_tmp > 0; bit_tmp-- ) + test(); + if ( j == 0 && LT_16( i, sub( st_band, 1 ) ) ) { - bits_per_bands[j] = L_sub( bits_per_bands[j], 262144 ); /*Q18 */ - j = add( j, 1 ); - if ( EQ_16( j, sub( st_band, i ) ) ) - { - j = 0; - move16(); - } - test(); - if ( j == 0 && LT_16( i, sub( st_band, 1 ) ) ) - { - i = add( i, 1 ); - } + i = add( i, 1 ); } } } - /*-------------------------------------------------------------------------- - * Bit sum verification for GSC inactive at very high rate - * The maximum number of bits per band of length 16 is 112 - * Redistribute the overage bits if needed - *--------------------------------------------------------------------------*/ - sum_bit = 0; - move16(); - j = 0; - move16(); - FOR( i = 0; i < nb_bands; i++ ) - { - L_tmp = Mult_32_16( sum_bit, 10923 ); - - IF( GT_32( bits_per_bands[i], 29360128 ) ) /* 112 in Q18 */ - { - sum_bit = L_add( sum_bit, L_sub( bits_per_bands[i], 29360128 ) ); /* Q18 */ - bits_per_bands[i] = 29360128; - move32(); - j = add( i, 1 ); - } - ELSE IF( GT_32( L_add( bits_per_bands[i], L_tmp ), 29360128 ) ) /* Q18 */ - { - j = add( i, 1 ); - } - } + } + /*-------------------------------------------------------------------------- + * Bit sum verification for GSC inactive at very high rate + * The maximum number of bits per band of length 16 is 112 + * Redistribute the overage bits if needed + *--------------------------------------------------------------------------*/ + sum_bit = 0; + move16(); + j = 0; + move16(); + FOR( i = 0; i < nb_bands; i++ ) + { + L_tmp = Mult_32_16( sum_bit, 10923 ); - IF( sum_bit != 0 ) - { - tmp = sub( nb_bands, j ); - sum_bit = Mult_32_16( sum_bit, div_s( 1, tmp ) ); /* Q18 */ - FOR( i = j; i < nb_bands; i++ ) - { - bits_per_bands[i] = L_add( bits_per_bands[i], sum_bit ); - move32(); /* Q18 */ - } - } - /*-------------------------------------------------------------------------- - * second step of bit sum verification, normally sum_bit == *bit - *--------------------------------------------------------------------------*/ - w_sum_bit = 0; - move16(); - FOR( i = 0; i < nb_bands; i++ ) + IF( GT_32( bits_per_bands[i], 29360128 ) ) /* 112 in Q18 */ { - out_bits_per_bands[i] = shl( extract_l( L_shr( bits_per_bands[i], 18 ) ), 3 ); - move16(); - w_sum_bit = add( w_sum_bit, out_bits_per_bands[i] ); /* Q3 */ + sum_bit = L_add( sum_bit, L_sub( bits_per_bands[i], 29360128 ) ); /* Q18 */ + bits_per_bands[i] = 29360128; + move32(); + j = add( i, 1 ); } - tmp = shl( *bit, 3 ); -#ifdef ADD_LRTD - if ( GSC_IVAS_mode != 0 && sum_bit < *bit ) /* If we need to add bits, we are doing it on the LF */ + ELSE IF( GT_32( L_add( bits_per_bands[i], L_tmp ), 29360128 ) ) /* Q18 */ { - reajust_bits( bits_per_bands, 0, nb_bands, (int16_t) sum_bit, *bit ); + j = add( i, 1 ); } - else + } + + IF( sum_bit != 0 ) + { + tmp = sub( nb_bands, j ); + sum_bit = Mult_32_16( sum_bit, div_s( 1, tmp ) ); /* Q18 */ + FOR( i = j; i < nb_bands; i++ ) { - reajust_bits( bits_per_bands, nb_bands - 1, 0, (int16_t) sum_bit, *bit ); + bits_per_bands[i] = L_add( bits_per_bands[i], sum_bit ); + move32(); /* Q18 */ } -#else + } + /*-------------------------------------------------------------------------- + * second step of bit sum verification, normally sum_bit == *bit + *--------------------------------------------------------------------------*/ + w_sum_bit = 0; + move16(); + FOR( i = 0; i < nb_bands; i++ ) + { + out_bits_per_bands[i] = shl( extract_l( L_shr( bits_per_bands[i], 18 ) ), 3 ); + move16(); + w_sum_bit = add( w_sum_bit, out_bits_per_bands[i] ); /* Q3 */ + } + tmp = shl( *bit, 3 ); + IF( GT_16( tmp, w_sum_bit ) ) { i = sub( nb_bands, 1 ); @@ -870,88 +495,24 @@ void bands_and_bit_alloc_fx( } } } -#endif - /*-------------------------------------------------------------------------- - * Recompute the real number/length of frequency bands to encode - *--------------------------------------------------------------------------*/ - *nb_subbands = nb_bands; - move16(); - *pvq_len = shl( *nb_subbands, 4 ); - /*-------------------------------------------------------------------------- - * Concatenate bands (encoder only) - *--------------------------------------------------------------------------*/ - IF( exc_diff != NULL ) - { - FOR( j = 0; j < nb_bands; j++ ) - { - Copy( exc_diff + shl( max_ener_band[j], 4 ), concat_in + shl( j, 4 ), 16 ); - } - } -#ifdef ADD_LRTD - } - else /* *bit == 0 */ - { - set_s( bits_per_bands_s, 0, nb_tot_bands ); - *nb_subbands = 0; - *pvq_len = 0; - } -#endif - return; -} -#ifdef ADD_LRTD -/*-------------------------------------------------------------------* - * reajust_bits() - * - * - *-------------------------------------------------------------------*/ - -static void reajust_bits( - float *bits_per_bands, - const int16_t st_band, - const int16_t end_band, - const int16_t sum_bit_in, - const int16_t bit_bdgt_in ) -{ - int16_t i, amount_to_add, incr; - int16_t bit_bdgt, sum_bit; - - incr = 1; - if ( end_band < st_band ) - { - incr = -1; - } - - if ( bit_bdgt_in < sum_bit_in ) - { - amount_to_add = -1; - bit_bdgt = sum_bit_in; - sum_bit = bit_bdgt_in; - } - else - { - bit_bdgt = bit_bdgt_in; - sum_bit = sum_bit_in; - amount_to_add = 1; - } + /*-------------------------------------------------------------------------- + * Recompute the real number/length of frequency bands to encode + *--------------------------------------------------------------------------*/ + *nb_subbands = nb_bands; + move16(); + *pvq_len = shl( *nb_subbands, 4 ); - i = st_band; - while ( bit_bdgt > sum_bit ) + /*-------------------------------------------------------------------------- + * Concatenate bands (encoder only) + *--------------------------------------------------------------------------*/ + IF( exc_diff != NULL ) { - if ( amount_to_add > 0 || ( amount_to_add < 0 && bits_per_bands[i] > 1 ) ) + FOR( j = 0; j < nb_bands; j++ ) { - bits_per_bands[i] += amount_to_add; - sum_bit += (int16_t) abs( amount_to_add ); - } - - i += incr; - if ( i == end_band ) - { - i = st_band; + Copy( exc_diff + shl( max_ener_band[j], 4 ), concat_in + shl( j, 4 ), 16 ); } } return; } - -#endif diff --git a/lib_com/gs_bitallocation_ivas_fx.c b/lib_com/gs_bitallocation_ivas_fx.c index 787d562c74404faf382b0a45929405c3fe75ceed..9243f640e890348f577688a0dc77aff03e10a148 100644 --- a/lib_com/gs_bitallocation_ivas_fx.c +++ b/lib_com/gs_bitallocation_ivas_fx.c @@ -2,13 +2,11 @@ EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0 ====================================================================================*/ #include -#include "options.h" /* Compilation switches */ -#include "cnst.h" /* Common constants */ -#include "rom_com.h" /* Static table prototypes */ -#include "prot.h" /* Function prototypes */ -#include "prot_fx.h" /* Function prototypes */ -#include "ivas_prot.h" /* Function prototypes */ -#include "assert.h" /* Debug prototypes */ +#include "options.h" /* Compilation switches */ +#include "cnst.h" /* Common constants */ +#include "rom_com.h" /* Static table prototypes */ +#include "prot_fx.h" /* Function prototypes */ +#include "assert.h" /* Debug prototypes */ #include "stl.h" #include "ivas_prot_fx.h" @@ -103,8 +101,8 @@ void bands_and_bit_alloc_ivas_fx( Word16 etmp; Word16 tmp; Word16 pos, band; - Word32 SWB_bit_budget; // Q0 -> Q18 - Word32 bits_per_bands[MBANDS_GN_BITALLOC16k]; // Q18 + Word32 SWB_bit_budget; /* Q0 -> Q18 */ + Word32 bits_per_bands[MBANDS_GN_BITALLOC16k]; /* Q18 */ Word16 w_sum_bit; Word16 fzero_val; #ifdef BASOP_NOGLOB_DECLARE_LOCAL @@ -122,11 +120,7 @@ void bands_and_bit_alloc_ivas_fx( set16_fx( out_bits_per_bands, 0, MBANDS_GN_BITALLOC16k ); /* To adapt current energy band to PVQ freq band for sorting*/ -#ifdef BASOP_NOGLOB ener_vec[0] = add_o( Ener_per_bd_iQ[0], Ener_per_bd_iQ[1], &Overflow ); /*Q12 */ -#else /* BASOP_NOGLOB */ - ener_vec[0] = add( Ener_per_bd_iQ[0], Ener_per_bd_iQ[1] ); /*Q12 */ -#endif move16(); Copy( Ener_per_bd_iQ + 1, ener_vec, MBANDS_GN - 1 ); /*Q12 */ ener_vec[MBANDS_GN - 1] = ener_vec[MBANDS_GN - 2]; @@ -152,7 +146,7 @@ void bands_and_bit_alloc_ivas_fx( move16(); bit_new_bands = 5; move16(); -#if 1 // def ADD_LRTD + test(); if ( GT_32( core_brate, ACELP_16k40 ) && EQ_16( L_frame, L_FRAME16k ) ) { @@ -187,9 +181,6 @@ void bands_and_bit_alloc_ivas_fx( } bit_index = i_mult2( BRATE2IDX_fx( brate_intermed_tbl[i] ), 17 ); -#else - bit_index = i_mult2( BRATE2IDX_fx( core_brate ), 17 ); -#endif bit_index_mem = bit_index; move16(); @@ -225,7 +216,6 @@ void bands_and_bit_alloc_ivas_fx( move16(); } -#if 1 // def ADD_LRTD IF( EQ_16( L_frame, L_FRAME16k ) ) { *bit = sub( *bit, 8 ); @@ -246,18 +236,12 @@ void bands_and_bit_alloc_ivas_fx( nb_tot_bands = Find_bit_alloc_IVAS_fx( core_brate, GSC_IVAS_mode, Diff_len, nb_tot_bands, bit, max_ener_band, ener_vec, bits_per_bands ); nb_bands = nb_tot_bands; } - ELSE -#endif - IF( EQ_16( GSC_noisy_speech, 1 ) ) + ELSE IF( EQ_16( GSC_noisy_speech, 1 ) ) { SWB_bit_budget = *bit; /*Q0*/ move32(); nb_bands = 5; move16(); - -#if 1 // def ADD_LRTD - - // fzero_val = 0.0f; fzero_val = 0; move16(); @@ -285,8 +269,6 @@ void bands_and_bit_alloc_ivas_fx( move16(); } -#endif - st_band = nb_bands; move16(); @@ -302,11 +284,10 @@ void bands_and_bit_alloc_ivas_fx( move16(); max_ener_band[j] = i; move16(); - // ener_vec[i] = 0; ener_vec[i] = fzero_val; move16(); } -#if 1 // def ADD_LRTD + IF( LT_16( bwidth, SWB ) ) { test(); @@ -315,17 +296,15 @@ void bands_and_bit_alloc_ivas_fx( nb_tot_bands = 5; move16(); } -#endif + FOR( ; j < nb_bands; j++ ) { i = maximum_fx( ener_vec, nb_tot_bands, &etmp ); max_ener_band[j] = i; move16(); - // ener_vec[i] = 0; ener_vec[i] = fzero_val; move16(); } -#if 1 // def ADD_LRTD } ELSE { @@ -338,7 +317,7 @@ void bands_and_bit_alloc_ivas_fx( move16(); } } -#endif + set32_fx( bits_per_bands, bit_fracf, nb_bands ); } ELSE @@ -353,7 +332,7 @@ void bands_and_bit_alloc_ivas_fx( move16(); st_band = 7; move16(); -#if 1 // def ADD_LRTD + test(); IF( EQ_16( L_frame, L_FRAME16k ) && GT_32( core_brate, ACELP_16k40 ) ) { @@ -366,7 +345,7 @@ void bands_and_bit_alloc_ivas_fx( bit_new_bands = 5; move16(); } -#endif + IF( LE_32( core_brate, ACELP_9k60 ) ) { *pvq_len = 80; @@ -388,9 +367,8 @@ void bands_and_bit_alloc_ivas_fx( } nb_bands = shr( *pvq_len, 4 ); -#if 1 // def ADD_LRTD nb_bands_max = s_min( nb_bands_max, MBANDS_GN_BITALLOC16k ); -#endif + /*------------------------------------------------------------------------ * Ajustement of the maximum number of bands in function of the * dynamics of the spectrum (more or less speech like) @@ -402,7 +380,6 @@ void bands_and_bit_alloc_ivas_fx( IF( coder_type == INACTIVE || GE_16( noise_lev, NOISE_LEVEL_SP3 ) ) { /* Probably classification error -> concentrate bits on LF */ -#if 1 // def ADD_LRTD IF( EQ_16( L_frame, L_FRAME16k ) && GE_32( core_brate, ACELP_24k40 ) ) { nb_bands_max = sub( nb_tot_bands, 2 ); @@ -411,9 +388,7 @@ void bands_and_bit_alloc_ivas_fx( { nb_bands_max = add( nb_bands, 2 ); } - ELSE -#endif - IF( GE_32( core_brate, ACELP_8k00 ) ) + ELSE IF( GE_32( core_brate, ACELP_8k00 ) ) { nb_bands_max = add( nb_bands, 1 ); } @@ -432,7 +407,7 @@ void bands_and_bit_alloc_ivas_fx( { nb_bands_max = sub( nb_bands_max, 1 ); } -#if 1 // def ADD_LRTD + IF( EQ_16( L_frame, L_FRAME16k ) ) { IF( LT_32( core_brate, ACELP_24k40 ) ) @@ -454,7 +429,6 @@ void bands_and_bit_alloc_ivas_fx( } } -#endif test(); if ( ( bwidth == NB ) && GT_16( nb_bands_max, 10 ) ) { @@ -476,7 +450,7 @@ void bands_and_bit_alloc_ivas_fx( /*------------------------------------------------------------------------ * Fractional bits to distribute on the first x bands *-----------------------------------------------------------------------*/ -#if 1 // def ADD_LRTD + test(); IF( EQ_16( L_frame, L_FRAME16k ) && GT_32( core_brate, ACELP_32k ) ) { @@ -484,10 +458,10 @@ void bands_and_bit_alloc_ivas_fx( move32(); } ELSE -#endif { bit_fracf = Find_bit_frac_fx( st_band, bit_tmp ); /*Q18*/ } + /*------------------------------------------------------------------------ * Complete the bit allocation per frequency band *-----------------------------------------------------------------------*/ @@ -505,13 +479,12 @@ void bands_and_bit_alloc_ivas_fx( move32(); /* Q18 */ bit_index = add( bit_index, 1 ); } -#if 1 // def ADD_LRTD + IF( EQ_16( L_frame, L_FRAME16k ) && GT_32( core_brate, ACELP_16k40 ) ) { bit_index = 0; move16(); i = sub( imax, 1 ); - // bits_per_bands[i] += Compl_GSC_freq_bits[bit_index]; bits_per_bands[i] = L_add( bits_per_bands[i], L_shl( Compl_GSC_freq_bits[bit_index], Q18 ) ); /*Q18*/ move32(); i = add( i, 1 ); @@ -519,13 +492,12 @@ void bands_and_bit_alloc_ivas_fx( FOR( ; i < 10; i++ ) { - // bits_per_bands[i] += Compl_GSC_freq_bits[bit_index] + bit_fracf; bits_per_bands[i] = L_add( bits_per_bands[i], L_add( L_shl( Compl_GSC_freq_bits[bit_index], Q18 ), bit_fracf ) ); /*Q18*/ move32(); bit_index = add( bit_index, 1 ); } } -#endif + IF( Diff_len == 0 ) { bit_index = add( bit_index_mem, 10 ); @@ -536,7 +508,7 @@ void bands_and_bit_alloc_ivas_fx( bit_index = add( bit_index, 1 ); } } -#if 1 // def ADD_LRTD + IF( bit_fracf < 0 ) { FOR( j = 0; j < nb_tot_bands; j++ ) @@ -546,39 +518,33 @@ void bands_and_bit_alloc_ivas_fx( } } -#endif /*-------------------------------------------------------------------------- * Complete the bit allocation per frequency band for 16kHz high brate mode *--------------------------------------------------------------------------*/ -#if 1 // def ADD_LRTD + test(); IF( EQ_16( L_frame, L_FRAME16k ) && GT_32( core_brate, ACELP_32k ) ) { FOR( j = st_band; j < nb_bands; j++ ) { - // bits_per_bands[j] = bit_new_bands; bits_per_bands[j] = L_shl( bit_new_bands, Q18 ); move32(); } - // bit_fracf = (1.0f / nb_bands) * (bit_tmp); bit_fracf = L_shl( L_mult0( idiv1616( 16384, nb_bands ), bit_tmp ), 4 ); /*Q18*/ - // etmp = 2.0f * bit_fracf / (nb_bands + 1); - etmp = divide3216( L_shr( bit_fracf, Q2 ), add( nb_bands, 1 ) ); // Q15 - // bit_fracf = etmp; - bit_fracf = L_shl( etmp, Q3 ); // Q18 + etmp = divide3216( L_shr( bit_fracf, Q2 ), add( nb_bands, 1 ) ); /* Q15 */ + + bit_fracf = L_shl( etmp, Q3 ); /* Q18 */ + FOR( j = nb_bands - 1; j >= 0; j-- ) { - // bits_per_bands[j] = etmp; - // etmp += bit_fracf; - bits_per_bands[j] = L_add( bits_per_bands[j], L_shl( etmp, Q3 ) ); // Q18 + bits_per_bands[j] = L_add( bits_per_bands[j], L_shl( etmp, Q3 ) ); /* Q18 */ move32(); etmp = extract_l( L_add( etmp, L_shr( bit_fracf, Q3 ) ) ); } } ELSE -#endif { FOR( j = st_band; j < nb_bands; j++ ) { @@ -692,6 +658,7 @@ void bands_and_bit_alloc_ivas_fx( } } } + /*-------------------------------------------------------------------------- * Bit sum verification for GSC inactive at very high rate * The maximum number of bits per band of length 16 is 112 @@ -728,19 +695,20 @@ void bands_and_bit_alloc_ivas_fx( move32(); /* Q18 */ } } + /*-------------------------------------------------------------------------- * second step of bit sum verification, normally sum_bit == *bit *--------------------------------------------------------------------------*/ -#if 1 // def ADD_LRTD + sum_bit = 0; move32(); FOR( i = 0; i < nb_bands; i++ ) { - // bits_per_bands[i] = (float)floor(bits_per_bands[i]); bits_per_bands[i] = L_shl( L_shr( bits_per_bands[i], Q18 ), Q18 ); move32(); sum_bit = L_add( sum_bit, L_shr( bits_per_bands[i], Q18 ) ); /*Q0*/ } + test(); IF( GSC_IVAS_mode != 0 && LT_32( sum_bit, *bit ) ) /* If we need to add bits, we are doing it on the LF */ { @@ -759,23 +727,7 @@ void bands_and_bit_alloc_ivas_fx( w_sum_bit = add( w_sum_bit, out_bits_per_bands[i] ); /* Q3 */ } tmp = shl( *bit, 3 ); -#else - IF( GT_16( tmp, w_sum_bit ) ) - { - i = sub( nb_bands, 1 ); - move16(); - FOR( ; tmp > w_sum_bit; w_sum_bit += ( 1 << 3 ) ) - { - out_bits_per_bands[i] = add( out_bits_per_bands[i], 1 << 3 ); - move16(); - i = sub( i, 1 ); - IF( i == 0 ) - { - i = sub( nb_bands, 1 ); - } - } - } -#endif + /*-------------------------------------------------------------------------- * Recompute the real number/length of frequency bands to encode *--------------------------------------------------------------------------*/ @@ -794,7 +746,6 @@ void bands_and_bit_alloc_ivas_fx( Copy( exc_diff + shl( max_ener_band[j], 4 ), concat_in + shl( j, 4 ), 16 ); } } -#if 1 // def ADD_LRTD } ELSE /* *bit == 0 */ { @@ -804,10 +755,11 @@ void bands_and_bit_alloc_ivas_fx( *pvq_len = 0; move16(); } -#endif + return; } -#if 1 // def ADD_LRTD + + /*-------------------------------------------------------------------* * reajust_bits() * @@ -928,26 +880,28 @@ static Word32 Find_bit_frac_fx( return ( L_out ); } -static Word16 Find_bit_alloc_IVAS_fx( /*o: Number of band to encode */ - const Word32 core_brate, /* i : core bit rate */ - const Word16 GSC_IVAS_mode, /* i : GSC IVAS mode */ - const Word16 Diff_len, /* i : Length of the difference signal (before pure spectral)*/ - const Word16 nb_tot_bands_in, /* i : total number of band */ - Word16 *bit, /* i/o: Number of bit allowed for frequency quantization */ - Word16 *max_ener_band, /* i/o: Energy based sorted order */ - Word16 *ener_vec, /* i/o: Energy per band order */ - Word32 *bits_per_bands /* o : Number of bit allowed per allowed subband Q18 */ + +/* o : Number of band to encode */ +static Word16 Find_bit_alloc_IVAS_fx( + const Word32 core_brate, /* i : core bit rate */ + const Word16 GSC_IVAS_mode, /* i : GSC IVAS mode */ + const Word16 Diff_len, /* i : Length of the difference signal (before pure spectral)*/ + const Word16 nb_tot_bands_in, /* i : total number of band */ + Word16 *bit, /* i/o: Number of bit allowed for frequency quantization */ + Word16 *max_ener_band, /* i/o: Energy based sorted order */ + Word16 *ener_vec, /* i/o: Energy per band order */ + Word32 *bits_per_bands /* o : Number of bit allowed per allowed subband Q18 */ ) { Word32 mp, mb, nb_bands_adj, bit_adj; Word16 nb_pulse_per_band[MBANDS_GN_BITALLOC16k]; - Word32 SWB_bit_budget; // Q0 -> Q18 + Word32 SWB_bit_budget; /* Q0 -> Q18 */ Word16 i, j, nb_bands_max, st_band, nb_tot_bands_loc, etmp; Word32 sum_bit /*Q18*/, bit_fracf /*Q18*/; Word16 d_tmp, e_div, tmp16; Word32 Ltmp, etmp_32fx; - SWB_bit_budget = *bit; // Q0 + SWB_bit_budget = *bit; /* Q0 */ st_band = 5; nb_bands_max = nb_tot_bands_in; @@ -997,12 +951,12 @@ static Word16 Find_bit_alloc_IVAS_fx( /*o: Number IF( EQ_16( GSC_IVAS_mode, 1 ) && LT_32( core_brate, GSC_L_RATE_STG ) ) { /* nb_bands_adj = 0.0125f * SWB_bit_budget - 0.75f;*/ - nb_bands_adj = L_sub( Mpy_32_32( Q31_0_0125, L_shl( SWB_bit_budget, Q18 ) ), Q18_0_75 ); // Q18 + nb_bands_adj = L_sub( Mpy_32_32( Q31_0_0125, L_shl( SWB_bit_budget, Q18 ) ), Q18_0_75 ); /* Q18 */ } ELSE IF( NE_16( GSC_IVAS_mode, 2 ) && GT_32( core_brate, GSC_H_RATE_STG ) ) { /*nb_bands_adj = 0.02f * SWB_bit_budget - 1.2f;*/ - nb_bands_adj = L_sub( Mpy_32_32( Q31_0_02, L_shl( SWB_bit_budget, Q18 ) ), Q18_1_2 ); // Q18 + nb_bands_adj = L_sub( Mpy_32_32( Q31_0_02, L_shl( SWB_bit_budget, Q18 ) ), Q18_1_2 ); /* Q18 */ } /*nb_bands_max = (int16_t)(nb_bands_max * nb_bands_adj + 0.5f);*/ @@ -1135,7 +1089,7 @@ static Word16 Find_bit_alloc_IVAS_fx( /*o: Number move32(); } mb = L_sub( mb, bit_fracf ); - SWB_bit_budget = L_sub( SWB_bit_budget, bits_per_bands[max_ener_band[j]] ); // Q18 + SWB_bit_budget = L_sub( SWB_bit_budget, bits_per_bands[max_ener_band[j]] ); /* Q18 */ } } @@ -1196,17 +1150,23 @@ static Word16 Find_bit_alloc_IVAS_fx( /*o: Number move32(); } } + return nb_tot_bands_loc; } -static Word16 Find_norm_inv_fx( const Word32 ToDivide, Word16 *e_div ) /* Find normalized 1 / ToDivide */ + +/* Find normalized 1 / ToDivide */ +static Word16 Find_norm_inv_fx( + const Word32 ToDivide, + Word16 *e_div ) { Word16 d_tmp, e_tmp; + e_tmp = norm_l( ToDivide ); d_tmp = round_fx( L_shl( ToDivide, e_tmp ) ); d_tmp = div_s( 16384, d_tmp ); /* 1.0 in Q14, dividend is normalize so >= 16384 as required for the division */ *e_div = sub( 14, e_tmp ); move16(); + return d_tmp; } -#endif diff --git a/lib_com/gs_gains.c b/lib_com/gs_gains.c index 13fdbd67ca68c7cf8f20b01fa974dea2859a4cf1..8fa7694755c7c5ac9f912f26abdff9211895ff07 100644 --- a/lib_com/gs_gains.c +++ b/lib_com/gs_gains.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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,7 +39,6 @@ #include #include "cnst.h" #include "rom_com.h" -#include "prot.h" #include "prot_fx.h" #include "wmc_auto.h" diff --git a/lib_com/gs_gains_fx.c b/lib_com/gs_gains_fx.c index 8e603e15c957782c1dfac68f08c646f84724ac08..35236b6032acbd590fb57c68e3063ca671292c21 100644 --- a/lib_com/gs_gains_fx.c +++ b/lib_com/gs_gains_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other @@ -104,13 +104,8 @@ void Comp_and_apply_gain_fx( FOR( i = StartBin; i < NB_Qbins + StartBin; i++ ) { -#ifdef BASOP_NOGLOB L32 = L_shl_o( L_mult( exc_diffQ[i], y_gain ), tmp_exp, &Overflow ); /*Q_exc+16 */ exc_diffQ[i] = round_fx_o( L32, &Overflow ); /*Q_exc */ -#else /* BASOP_NOGLOB */ - L32 = L_shl( L_mult( exc_diffQ[i], y_gain ), tmp_exp ); /*Q_exc+16 */ - exc_diffQ[i] = round_fx( L32 ); /*Q_exc */ -#endif /* BASOP_NOGLOB */ move16(); } } @@ -127,23 +122,15 @@ void Comp_and_apply_gain_fx( y_gain = extract_l( Pow2( 14, frac ) ); /* Put 14 as exponent so that */ /* output of Pow2() will be: */ /* 16384 < Pow2() <= 32767 */ -#ifdef BASOP_NOGLOB Ener_per_bd_yQ[i_band] = shl_o( y_gain, sub( exp1, 13 ), &Overflow ); -#else /* BASOP_NOGLOB */ - Ener_per_bd_yQ[i_band] = shl( y_gain, sub( exp1, 13 ) ); -#endif /* BASOP_NOGLOB */ move16(); /*Q1 */ tmp_exp = add( add( exp1, 1 ), sub( Q_exc, Qexc_diff ) ); FOR( i = StartBin; i < NB_Qbins + StartBin; i++ ) { - L32 = L_mult( exc_diffQ[i], y_gain ); /*Qexc_diff+15 */ -#ifdef BASOP_NOGLOB + L32 = L_mult( exc_diffQ[i], y_gain ); /*Qexc_diff+15 */ exc_diffQ[i] = round_fx_o( L_shl_o( L32, tmp_exp, &Overflow ), &Overflow ); /*Q_exc */ move16(); -#else /* BASOP_NOGLOB */ - exc_diffQ[i] = round_fx( L_shl( L32, tmp_exp ) ); /*Q_exc */ -#endif } } } @@ -190,13 +177,8 @@ void Comp_and_apply_gain_ivas_fx( FOR( i = StartBin; i < NB_Qbins + StartBin; i++ ) { -#ifdef BASOP_NOGLOB L32 = L_mult( exc_diffQ[i], y_gain ); /*Q_exc+16-tmp_exp */ exc_diffQ[i] = round_fx_o( L32, &Overflow ); /*Q_exc-tmp_exp */ -#else /* BASOP_NOGLOB */ - L32 = L_mult( exc_diffQ[i], y_gain ); /*Q_exc+16 */ - exc_diffQ[i] = round_fx( L32 ); /*Q_exc */ -#endif /* BASOP_NOGLOB */ move16(); IF( exc_diffQ[i] ) { @@ -215,29 +197,21 @@ void Comp_and_apply_gain_ivas_fx( * y_gain = pow(10.0, (Ener_per_bd_iQ[i_band]-Ener_per_bd_yQ[i_band])) * = pow(2, 3.321928*(Ener_per_bd_iQ[i_band]-Ener_per_bd_yQ[i_band])) *-----------------------------------------------------------------*/ - L16 = sub_sat( Ener_per_bd_iQ[i_band], Ener_per_bd_yQ[i_band] ); /*Q12 */ - L32 = L_mult( L16, 27213 ); /* 3.321928 in Q13 -> Q26 */ - L32 = L_shr( L32, 10 ); /* From Q26 to Q16 */ - frac = L_Extract_lc( L32, &exp1 ); /* Extract exponent of gcode0 */ - y_gain = extract_l( Pow2( 14, frac ) ); /* Put 14 as exponent so that */ - /* output of Pow2() will be: */ - /* 16384 < Pow2() <= 32767 */ -#ifdef BASOP_NOGLOB + L16 = sub_sat( Ener_per_bd_iQ[i_band], Ener_per_bd_yQ[i_band] ); /*Q12 */ + L32 = L_mult( L16, 27213 ); /* 3.321928 in Q13 -> Q26 */ + L32 = L_shr( L32, 10 ); /* From Q26 to Q16 */ + frac = L_Extract_lc( L32, &exp1 ); /* Extract exponent of gcode0 */ + y_gain = extract_l( Pow2( 14, frac ) ); /* Put 14 as exponent so that */ + /* output of Pow2() will be: */ + /* 16384 < Pow2() <= 32767 */ Ener_per_bd_yQ[i_band] = shl_o( y_gain, sub( exp1, 13 ), &Overflow ); /*Q13*/ -#else /* BASOP_NOGLOB */ - Ener_per_bd_yQ[i_band] = shl( y_gain, sub( exp1, 13 ) ); -#endif /* BASOP_NOGLOB */ move16(); /*Q1 */ tmp_exp = add( add( exp1, 1 ), sub( *Q_exc, Qexc_diff ) ); FOR( i = StartBin; i < NB_Qbins + StartBin; i++ ) { - L32 = L_mult( exc_diffQ[i], y_gain ); /*Qexc_diff+15 */ -#ifdef BASOP_NOGLOB + L32 = L_mult( exc_diffQ[i], y_gain ); /*Qexc_diff+15 */ exc_diffQ[i] = round_fx_o( L32, &Overflow ); /*Q_exc-tmp_exp */ -#else /* BASOP_NOGLOB */ - exc_diffQ[i] = round_fx( L_shl( L32, tmp_exp ) ); /*Q_exc */ -#endif move16(); IF( exc_diffQ[i] ) { diff --git a/lib_com/gs_inact_switching_fx.c b/lib_com/gs_inact_switching_fx.c index 18bff8d43c5a53393d593f2cc7ea841c3e2ad445..c0feb91f53993f4027fe1d1f6818023af94b5e13 100644 --- a/lib_com/gs_inact_switching_fx.c +++ b/lib_com/gs_inact_switching_fx.c @@ -129,14 +129,9 @@ void Inac_swtch_ematch_fx( { FOR( j = 0; j < 8; j++ ) { - L_tmp = L_mult( *pt_exc, ftmp ); /* Q_exc*Q0 -> Q(Q_exc+1) */ -#ifdef BASOP_NOGLOB + L_tmp = L_mult( *pt_exc, ftmp ); /* Q_exc*Q0 -> Q(Q_exc+1) */ L_tmp = L_shl_sat( L_tmp, add( exp, 15 ) ); /* Q(Q_exc+1) -> Q(16+Q_exc)*/ *pt_exc = round_fx_sat( L_tmp ); -#else - L_tmp = L_shl( L_tmp, add( exp, 15 ) ); /* Q(Q_exc+1) -> Q(16+Q_exc)*/ - *pt_exc = round_fx( L_tmp ); -#endif move16(); pt_exc++; } @@ -145,14 +140,9 @@ void Inac_swtch_ematch_fx( { FOR( j = 0; j < 16; j++ ) { - L_tmp = L_mult( *pt_exc, ftmp ); /* Q_exc*Q0 -> Q(Q_exc+1) */ -#ifdef BASOP_NOGLOB + L_tmp = L_mult( *pt_exc, ftmp ); /* Q_exc*Q0 -> Q(Q_exc+1) */ L_tmp = L_shl_sat( L_tmp, add( exp, 15 ) ); /* Q(Q_exc+1) -> Q(16+Q_exc)*/ *pt_exc = round_fx_sat( L_tmp ); /*Q_exc*/ -#else - L_tmp = L_shl( L_tmp, add( exp, 15 ) ); /* Q(Q_exc+1) -> Q(16+Q_exc)*/ - *pt_exc = round_fx( L_tmp ); /*Q_exc*/ -#endif move16(); pt_exc++; } @@ -172,15 +162,17 @@ void Inac_switch_ematch_ivas_fx( Word16 dct_exc_tmp[], /* i : GSC excitation in DCT domain */ Word16 lt_ener_per_band[], /* i/o: Long term energy per band Q12 */ const Word16 coder_type, /* i : Coding mode */ - const Word16 L_frame, /* i : Frame lenght */ - const Word32 total_brate, /* i : total bit rate */ - const Word16 Q_exc /* i : input and output format of exc2 */ - , - const Word16 bfi /* i : frame lost indicator */ - , - const Word16 last_core, /* i : Last core used */ - const Word16 last_codec_mode /* i : Last codec mode */ - , +#ifdef NONBE_FIX_GSC_BSTR + const Word16 inactive_coder_type_flag, /* i : AVQ (0) or GSC (1) IC flag */ +#endif + const Word16 L_frame, /* i : Frame lenght */ +#ifndef NONBE_FIX_GSC_BSTR + const Word32 total_brate, /* i : total bit rate */ +#endif + const Word16 Q_exc, /* i : input and output format of exc2 */ + const Word16 bfi, /* i : frame lost indicator */ + const Word16 last_core, /* i : Last core used */ + const Word16 last_codec_mode, /* i : Last codec mode */ const Word16 tdm_low_rate_mode, /* i : secondary channel low rate mode flag*/ const Word16 element_mode /* i : element mode */ ) @@ -232,7 +224,11 @@ void Inac_switch_ematch_ivas_fx( move16(); } } +#ifdef NONBE_FIX_GSC_BSTR + ELSE IF( ( coder_type == INACTIVE ) && inactive_coder_type_flag ) +#else ELSE IF( ( coder_type == INACTIVE ) && LE_32( total_brate, MAX_GSC_INACTIVE_BRATE ) ) +#endif { /* Find spectrum and energy per band for inactive frames */ edct_16fx( exc2, dct_exc_tmp, L_frame, 5, element_mode ); diff --git a/lib_com/gs_noisefill_fx.c b/lib_com/gs_noisefill_fx.c index 3761debf22ac219f23d2cbff1b1af687065c3554..2e00e4641e177d2e17d2bbecbe6c93f93c522e1a 100644 --- a/lib_com/gs_noisefill_fx.c +++ b/lib_com/gs_noisefill_fx.c @@ -470,15 +470,11 @@ static void Decreas_freqPeak_fx( { tmp = abs_s( *src ); exp = norm_s( max_val ); - tmp1 = div_s( shl( 1, sub( 14, exp ) ), max_val ); /*Q(29 - exp - Q_exc) */ - L_tmp = L_mult( tmp, tmp1 ); /*Q(30 - exp) */ -#ifdef BASOP_NOGLOB + tmp1 = div_s( shl( 1, sub( 14, exp ) ), max_val ); /*Q(29 - exp - Q_exc) */ + L_tmp = L_mult( tmp, tmp1 ); /*Q(30 - exp) */ tmp = round_fx_o( L_shl_o( L_tmp, exp, &Overflow ), &Overflow ); /*Q14 */ -#else - tmp = round_fx( L_shl( L_tmp, exp ) ); /*Q14 */ -#endif - tmp = sub( 32767, tmp ); /*Q14 */ - L_tmp = L_mult( avrg, tmp ); /*Q_exc +15 */ + tmp = sub( 32767, tmp ); /*Q14 */ + L_tmp = L_mult( avrg, tmp ); /*Q_exc +15 */ tmp = round_fx( L_shl( L_tmp, 1 ) ); tmp1 = negate( tmp ); @@ -569,11 +565,7 @@ static void envelop_modify_fx( /* output of Pow2() will be: */ /* 16384 < Pow2() <= 32767 */ exp = sub( exp, 14 ); -#ifdef BASOP_NOGLOB Ener1_fx = mult_ro( 13107, shl_o( tmp, exp, &Overflow ), &Overflow ); /*Q0 */ -#else /* BASOP_NOGLOB */ - Ener1_fx = mult_r( 13107, shl( tmp, exp ) ); /*Q0 */ -#endif /* BASOP_NOGLOB */ FOR( j = 0; j < 16; j++ ) { @@ -599,11 +591,7 @@ static void envelop_modify_fx( /* output of Pow2() will be: */ /* 16384 < Pow2() <= 32767 */ exp = sub( exp, 14 ); -#ifdef BASOP_NOGLOB Ener1_fx = mult_r( 13107, shl_o( tmp, exp, &Overflow ) ); /*Q0 */ -#else /* BASOP_NOGLOB */ - Ener1_fx = mult_r( 13107, shl( tmp, exp ) ); /*Q0 */ -#endif /* BASOP_NOGLOB */ src_fx = &exc_diffQ_fx[224]; FOR( j = 0; j < 32; j++ ) @@ -720,17 +708,9 @@ void highband_exc_dct_in_fx( /* output of Pow2() will be: */ /* 16384 < Pow2() <= 32767 */ exp = sub( exp, 14 ); -#ifdef BASOP_NOGLOB tmp1 = shl_o( tmp, exp, &Overflow ); -#else /* BASOP_NOGLOB */ - tmp1 = shl( tmp, exp ); -#endif /* BASOP_NOGLOB */ move16(); -#ifdef BASOP_NOGLOB ener = add_o( tmp1, ener, &Overflow ); /*Q0 */ -#else /* BASOP_NOGLOB */ - ener = add( tmp1, ener ); /*Q0 */ -#endif /* BASOP_NOGLOB */ } test(); @@ -813,7 +793,6 @@ void highband_exc_dct_in_fx( { IF( exc_diffQ[i] == 0 ) { - // PMT("code below to be validated for IVAS use") /* exc_diffQ[i] += 2.0f * noisepb[0] * ((float)own_random(seed_tcx) / PCM16_TO_FLT_FAC);*/ tmp = mult( shl( noisepb[0], 1 ), Random( seed_tcx ) ); /*Q15 */ tmp = shr( tmp, sub( 15, Qexc_diffQ ) ); /*qNoise_fac */ @@ -896,66 +875,7 @@ void highband_exc_dct_in_fx( /*--------------------------------------------------------------------------------------* * Apply decoded gain onto the difference signal *--------------------------------------------------------------------------------------*/ -#ifdef ADD_LRTD - if ( GSC_IVAS_mode >= 1 ) - { - float scale_factLF = 0.9f; - float scale_factHF = 0.9f; - if ( GSC_IVAS_mode == 1 && GSC_noisy_speech == 0 ) - { - scale_factHF = 0.8f; - } - else if ( GSC_IVAS_mode == 2 || GSC_noisy_speech == 1 ) - { - scale_factHF = 0.71f; - } - else if ( GSC_IVAS_mode == 3 ) - { - scale_factHF = 0.9f; - } - for ( i = 0; i < pit_band_idx * 16; i++ ) - { - exc_diffQ[i] *= scale_factLF; - } - for ( ; i < L_frame; i++ ) - { - exc_diffQ[i] *= scale_factHF; - } - } - else if ( GSC_noisy_speech ) - { - float scale_fact = 0.9f; - - if ( element_mode == IVAS_CPE_TD ) - { - if ( coder_type == INACTIVE ) - { - scale_fact = 1.0f; - } - else - { - scale_fact = 0.95f; - } - } - else if ( element_mode > IVAS_SCE ) - { - scale_fact = 0.71f; - } - - for ( i = 0; i < L_frame; i++ ) - { - exc_diffQ[i] *= scale_fact; - } - } - if ( GSC_noisy_speech && element_mode > IVAS_SCE && core_brate < ACELP_7k20 ) - { - for ( i = 80; i < L_frame; i++ ) - { - exc_diffQ[i] *= ( +0.0024f * (float) i + 1.192f ); - } - } -#else IF( GSC_noisy_speech ) { FOR( i = 0; i < L_frame; i++ ) @@ -964,7 +884,7 @@ void highband_exc_dct_in_fx( move16(); } } -#endif + Comp_and_apply_gain_fx( exc_diffQ, Ener_per_bd_iQ, Ener_per_bd_yQ, last_bin, 0, Qexc_diffQ, Q_exc ); IF( exc_wo_nf != NULL ) @@ -1019,14 +939,10 @@ void highband_exc_dct_in_fx( FOR( i = sub( L_FRAME, 16 ); i < L_FRAME; i++ ) { /*exc_dct_in[i] *= (0.067f*i-15.f); */ - tmp = mult_r( 17564, shl( i, 6 ) ); /*0.067 in Q18 and i in Q6= Q9 */ - tmp = sub( tmp, 7680 ); /*15 in Q9 = Q9 */ - L_tmp = L_mult( exc_dct_in[i], tmp ); /*Q(Q_exc+10) */ -#ifdef BASOP_NOGLOB + tmp = mult_r( 17564, shl( i, 6 ) ); /*0.067 in Q18 and i in Q6= Q9 */ + tmp = sub( tmp, 7680 ); /*15 in Q9 = Q9 */ + L_tmp = L_mult( exc_dct_in[i], tmp ); /*Q(Q_exc+10) */ exc_dct_in[i] = round_fx_o( L_shl_o( L_tmp, 6, &Overflow ), &Overflow ); /*Q_exc */ -#else /* BASOP_NOGLOB */ - exc_dct_in[i] = round_fx( L_shl( L_tmp, 6 ) ); /*Q_exc */ -#endif /* BASOP_NOGLOB */ } } @@ -1061,15 +977,9 @@ void highband_exc_dct_in_fx( IF( GT_16( tmp, abs_s( *dst ) ) ) { tmp2 = *src; -#ifdef BASOP_NOGLOB *src = mult_r( 16384, sub_o( *src, abs_s( *dst ), &Overflow ) ); /*Q_exc */ move16(); tmp = mult_r( 16384, add_o( tmp2, abs_s( *dst ), &Overflow ) ); /*Q_exc */ -#else /* BASOP_NOGLOB */ - *src = mult_r( 16384, sub( *src, abs_s( *dst ) ) ); /*Q_exc */ - move16(); - tmp = mult_r( 16384, add( tmp2, abs_s( *dst ) ) ); /*Q_exc */ -#endif if ( tmp2 > 0 ) { *src = tmp; @@ -1176,17 +1086,9 @@ void highband_exc_dct_in_ivas_fx( /* output of Pow2() will be: */ /* 16384 < Pow2() <= 32767 */ exp = sub( exp, 14 ); -#ifdef BASOP_NOGLOB tmp1 = shl_o( tmp, exp, &Overflow ); -#else /* BASOP_NOGLOB */ - tmp1 = shl( tmp, exp ); -#endif /* BASOP_NOGLOB */ move16(); -#ifdef BASOP_NOGLOB ener = add_o( tmp1, ener, &Overflow ); /*Q0 */ -#else /* BASOP_NOGLOB */ - ener = add( tmp1, ener ); /*Q0 */ -#endif /* BASOP_NOGLOB */ } test(); @@ -1270,7 +1172,6 @@ void highband_exc_dct_in_ivas_fx( { IF( exc_diffQ[i] == 0 ) { - // PMT("code below to be validated for IVAS use") /* exc_diffQ[i] += 2.0f * noisepb[0] * ((float)own_random(seed_tcx) / PCM16_TO_FLT_FAC);*/ tmp = mult( shl( noisepb[0], 1 ), Random( seed_tcx ) ); /*Q15 */ tmp = shr( tmp, sub( 15, Qexc_diffQ ) ); /*qNoise_fac */ @@ -1351,105 +1252,86 @@ void highband_exc_dct_in_ivas_fx( } } } + /*--------------------------------------------------------------------------------------* * Apply decoded gain onto the difference signal *--------------------------------------------------------------------------------------*/ -#if 1 // def ADD_LRTD + IF( GSC_IVAS_mode >= 1 ) { - // float scale_factLF = 0.9f; - Word16 scale_factLF = 29491; + Word16 scale_factLF = 29491; /* 0.9f */ move16(); - // float scale_factHF = 0.9f; - Word16 scale_factHF = 29491; + Word16 scale_factHF = 29491; /* 0.9f */ move16(); test(); test(); IF( EQ_16( GSC_IVAS_mode, 1 ) && GSC_noisy_speech == 0 ) { - // scale_factHF = 0.8f; scale_factHF = 26214; move16(); } ELSE IF( EQ_16( GSC_IVAS_mode, 2 ) || EQ_16( GSC_noisy_speech, 1 ) ) { - // scale_factHF = 0.71f; - scale_factHF = 23265; + scale_factHF = 23265; /* 0.71f */ move16(); } ELSE IF( EQ_16( GSC_IVAS_mode, 3 ) ) { - // scale_factHF = 0.9f; - scale_factHF = 29491; + scale_factHF = 29491; /* 0.9f */ move16(); } FOR( i = 0; i < pit_band_idx * 16; i++ ) { - // exc_diffQ[i] *= scale_factLF; exc_diffQ[i] = mult_r( exc_diffQ[i], scale_factLF ); } FOR( ; i < L_frame; i++ ) { - // exc_diffQ[i] *= scale_factHF; exc_diffQ[i] = mult_r( exc_diffQ[i], scale_factHF ); move16(); } } ELSE IF( GSC_noisy_speech ) { - // float scale_fact = 0.9f; - Word16 scale_fact = 29491; + Word16 scale_fact = 29491; /* 0.9f */ move16(); IF( EQ_16( element_mode, IVAS_CPE_TD ) ) { IF( coder_type == INACTIVE ) { - // scale_fact = 1.0f; - scale_fact = 32767; + scale_fact = 32767; /* 1.0f */ move16(); } ELSE { - // scale_fact = 0.95f; - scale_fact = 31129; + scale_fact = 31129; /* 0.95f */ move16(); } } ELSE IF( GT_16( element_mode, IVAS_SCE ) ) { - // scale_fact = 0.71f; - scale_fact = 23265; + scale_fact = 23265; /* 0.71f */ move16(); } FOR( i = 0; i < L_frame; i++ ) { - // exc_diffQ[i] *= scale_fact; exc_diffQ[i] = mult_r( exc_diffQ[i], scale_fact ); move16(); } } + IF( GSC_noisy_speech && GT_16( element_mode, IVAS_SCE ) && LT_32( core_brate, ACELP_7k20 ) ) { FOR( i = 80; i < L_frame; i++ ) { - // exc_diffQ[i] *= (+0.0024f * (float)i + 1.192f); + /* exc_diffQ[i] *= (+0.0024f * (float)i + 1.192f); */ exc_diffQ[i] = mult_r( shl( exc_diffQ[i], 1 ) /*Q16*/, (Word16) L_shr( L_add( 629 * i, 312475 ) /*Q18*/, Q4 ) /*Q14*/ ); move16(); } } -#else - IF( GSC_noisy_speech ) - { - FOR( i = 0; i < L_frame; i++ ) - { - exc_diffQ[i] = mult_r( exc_diffQ[i], 29491 ); - move16(); - } - } -#endif + Word16 Q_tmp = *Q_exc; move16(); Word16 Q_old = *Q_exc; @@ -1533,14 +1415,10 @@ void highband_exc_dct_in_ivas_fx( FOR( i = sub( L_FRAME, 16 ); i < L_FRAME; i++ ) { /*exc_dct_in[i] *= (0.067f*i-15.f); */ - tmp = mult_r( 17564, shl( i, 6 ) ); /*0.067 in Q18 and i in Q6= Q9 */ - tmp = sub( tmp, 7680 ); /*15 in Q9 = Q9 */ - L_tmp = L_mult( exc_dct_in[i], tmp ); /*Q(Q_exc+10) */ -#ifdef BASOP_NOGLOB + tmp = mult_r( 17564, shl( i, 6 ) ); /*0.067 in Q18 and i in Q6= Q9 */ + tmp = sub( tmp, 7680 ); /*15 in Q9 = Q9 */ + L_tmp = L_mult( exc_dct_in[i], tmp ); /*Q(Q_exc+10) */ exc_dct_in[i] = round_fx_o( L_shl_o( L_tmp, 6, &Overflow ), &Overflow ); /*Q_exc */ -#else /* BASOP_NOGLOB */ - exc_dct_in[i] = round_fx( L_shl( L_tmp, 6 ) ); /*Q_exc */ -#endif /* BASOP_NOGLOB */ } } @@ -1575,15 +1453,9 @@ void highband_exc_dct_in_ivas_fx( IF( GT_16( tmp, abs_s( *dst ) ) ) { tmp2 = *src; -#ifdef BASOP_NOGLOB *src = mult_r( 16384, sub_o( *src, abs_s( *dst ), &Overflow ) ); /*Q_exc */ move16(); tmp = mult_r( 16384, add_o( tmp2, abs_s( *dst ), &Overflow ) ); /*Q_exc */ -#else /* BASOP_NOGLOB */ - *src = mult_r( 16384, sub( *src, abs_s( *dst ) ) ); /*Q_exc */ - move16(); - tmp = mult_r( 16384, add( tmp2, abs_s( *dst ) ) ); /*Q_exc */ -#endif IF( tmp2 > 0 ) { *src = tmp; diff --git a/lib_com/gs_preech.c b/lib_com/gs_preech.c deleted file mode 100644 index 092558fb85c4a12571164954832f0eeb71419692..0000000000000000000000000000000000000000 --- a/lib_com/gs_preech.c +++ /dev/null @@ -1,397 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include -#include "cnst.h" -#include "rom_com.h" -#include "prot.h" -#include "wmc_auto.h" -#include "prot_fx.h" - -/*-------------------------------------------------------------------* - * Local constants - *-------------------------------------------------------------------*/ - -#define ATT_LENGHT16k 80 -#ifndef IVAS_FLOAT_FIXED -#define INV_L_FRAME16k ( 1.0f / L_FRAME16k ) -#endif - -#define ATT_LENGHT 64 -#define ATT_SEG_LEN ( L_FRAME / ATT_LENGHT ) - -#ifndef IVAS_FLOAT_FIXED -#define INV_ATT_SEG_LEN ( 1.0f / ATT_SEG_LEN ) -#define INV_L_FRAME ( 1.0f / L_FRAME ) -#endif - -#ifndef IVAS_FLOAT_FIXED -/*-------------------------------------------------------------------* - * pre_echo_att() - * - * Attenuation of the pre-echo when encoder specifies an attack - *-------------------------------------------------------------------*/ - -void pre_echo_att( - float *Last_frame_ener, /* i/o: Energy of the last frame */ - float *exc, /* i/o: Excitation of the current frame */ - const int16_t attack_flag, /* i : attack flag (GSC or TC) */ - const int16_t last_coder_type, /* i : Last coder type */ - const int16_t L_frame /* i : frame length */ -) -{ - float etmp; - float etmp1; - float finc[ATT_LENGHT16k], ratio_float, inv_l_frame; - int16_t att_len; - int16_t attack_pos, i; - - if ( attack_flag > 0 && last_coder_type == AUDIO ) - { - /*-------------------------------------------------------------------------* - * Find where the onset (attack) occurs by computing the energy per section - * The inverse weighting aims to favor the first maxima in case of - * gradual onset - *-------------------------------------------------------------------------*/ - - att_len = ATT_LENGHT; - if ( L_frame == L_FRAME16k ) - { - att_len = ATT_LENGHT16k; - } - for ( i = 0; i < att_len; i++ ) - { - finc[i] = sum2_f( exc + i * ATT_SEG_LEN, ATT_SEG_LEN ) * ( (float) ( att_len - i ) / ( att_len ) ); - } - etmp = -1; - attack_pos = maximum( finc, att_len, &etmp ); - - /* Scaled the maximum energy and allowed 6 dB increase*/ - etmp *= INV_ATT_SEG_LEN; - etmp1 = etmp; - *Last_frame_ener *= 4.0f; - - /* If the maximum normalized energy > last frame energy + 6dB */ - if ( etmp > *Last_frame_ener && attack_pos > 0 ) - { - /* Find the average energy before the attack */ - etmp = sum_f( finc, attack_pos ) + 0.01f; - etmp /= ( attack_pos * ATT_SEG_LEN ); - - /* Find the correction factor and apply it before the attack */ - ratio_float = (float) sqrt( *Last_frame_ener / etmp ); - - - /* Pre-echo atttenuation should never increase the energy */ - ratio_float = min( ratio_float, 1.0f ); - for ( i = 0; i < attack_pos * ATT_SEG_LEN; i++ ) - { - exc[i] *= ratio_float; - } - } - *Last_frame_ener = etmp1; - } - else - { - /*-------------------------------------------------------* - * In normal cases, just compute the energy of the frame - *-------------------------------------------------------*/ - - etmp = sum2_f( exc, L_frame ) + 0.01f; - inv_l_frame = INV_L_FRAME; - if ( L_frame == L_FRAME16k ) - { - inv_l_frame = INV_L_FRAME16k; - } - etmp *= inv_l_frame; - *Last_frame_ener = etmp; - } - - return; -} -#endif - -void pre_echo_att_fx( - Word32 *Last_frame_ener_fx, /* i/o: Energy of the last frame 2*Q_new+1*/ - Word16 *exc_fx, /* i/o: Excitation of the current frame Q_new*/ - const Word16 gsc_attack_flag_fx, /* i : flag signalling attack encoded by AC mode (GSC) Q0*/ - const Word16 Q_new, - const Word16 last_coder_type, /* i : Last coding mode Q0*/ - const Word16 L_frame /* i : Frame length Q0*/ -) -{ - Word32 etmp_fx; - Word32 finc_fx[ATT_LENGHT16k] = { 0 }; - move16(); - Word16 ratio_fx; - Word16 attack_pos_fx, i; - Word32 L_tmp, L_tmp1; - Word16 tmp, n1, n2, exp, frac1, frac2; - Word32 etmp1_fx; - Word16 att_len; - - test(); - IF( gsc_attack_flag_fx > 0 && EQ_16( last_coder_type, AUDIO ) ) /*gsc_attack_flag_fx does not get set for all the test cases */ - { - /*-------------------------------------------------------------------------* - * Find where the onset (attack) occurs by computing the energy per section - * The inverse weighting aims to favor the first maxima in case of - * gradual onset - *-------------------------------------------------------------------------*/ - att_len = ATT_LENGHT; /* Q0 */ - move16(); - if ( EQ_16( L_frame, L_FRAME16k ) ) - { - att_len = ATT_LENGHT16k; /* Q0 */ - move16(); - } - FOR( i = 0; i < att_len; i++ ) - { - L_tmp = sum2_fx( &exc_fx[i * 4], ATT_SEG_LEN ); /*2*Q_new+1, //ATT_SEG_LEN=(L_FRAME/ATT_LENGHT)=4(=shl(x,2))*/ - tmp = div_s( sub( att_len, i ), att_len ); /*Q15 */ - L_tmp = Mult_32_16( L_tmp, tmp ); /*2*Q_new+1 */ - finc_fx[i] = L_tmp; - move32(); /*2*Q_new+1 */ - } - - attack_pos_fx = maximum_32_fx( finc_fx, att_len, &etmp_fx ); - - /* Scaled the maximum energy and allowed 6 dB increase*/ - etmp_fx = L_shr( etmp_fx, add( 2 + 1 - 4, shl( Q_new, 1 ) ) ); /*2*Q_new+1 //INV_ATT_SEG_LEN=1/4(=shr(x,2)) -> Q4 */ - etmp1_fx = etmp_fx; - move32(); -#ifdef BASOP_NOGLOB - *Last_frame_ener_fx = L_shl_sat( *Last_frame_ener_fx, 2 ); -#else - *Last_frame_ener_fx = L_shl( *Last_frame_ener_fx, 2 ); -#endif - move32(); /*2*Q_new+1 */ - - /* If the maximum normalized energy > last frame energy + 6dB */ - test(); - IF( GT_32( etmp_fx, *Last_frame_ener_fx ) && attack_pos_fx > 0 ) - { - /* Find the average energy before the attack */ - L_tmp = sum32_fx( finc_fx, attack_pos_fx ); /*Q1 */ - L_tmp1 = L_shr( L_mult( attack_pos_fx, attack_pos_fx ), 1 ); /*Q0 */ - tmp = round_fx( Isqrt( L_tmp1 ) ); /*Q15 */ - L_tmp = L_shr( L_tmp, 2 ); /*Q1 ; ATT_SEG_LEN=4 */ - etmp_fx = Mult_32_16( L_tmp, tmp ); /*Q1 */ - - etmp_fx = L_shr( etmp_fx, add( 1 - 4, shl( Q_new, 1 ) ) ); /* makes etmp i nQ4 as *Last_frame_ener_fx */ - /* Find the correction factor and apply it before the attack */ - /* ratio = (float)sqrt(*Last_frame_ener/etmp);*/ - /* = isqrt(etmp/(*Last_frame_ener)) */ - etmp_fx = L_max( etmp_fx, 1 ); - *Last_frame_ener_fx = L_max( *Last_frame_ener_fx, 1 ); - move32(); - n1 = norm_l( etmp_fx ); - n2 = norm_l( *Last_frame_ener_fx ); - - n1 = sub( n1, 1 ); - exp = sub( n1, n2 ); - - frac1 = round_fx( L_shl( etmp_fx, n1 ) ); -#ifdef BASOP_NOGLOB - frac2 = round_fx_sat( L_shl_sat( *Last_frame_ener_fx, n2 ) ); -#else - frac2 = round_fx( L_shl( *Last_frame_ener_fx, n2 ) ); -#endif - L_tmp = L_mult0( 128, div_s( frac1, frac2 ) ); /* s = gain_out / gain_in */ - L_tmp = L_shr( L_tmp, exp ); /* add exponent */ - - L_tmp = Isqrt( L_tmp ); - ratio_fx = round_fx( L_shl( L_tmp, 9 ) ); /* Q13 */ - - /* Pre-echo atttenuation should never increase the energy */ - ratio_fx = s_min( ratio_fx, 8192 /* 1 in Q13 */ ); /* Q13 */ - FOR( i = 0; i < attack_pos_fx * ATT_SEG_LEN; i++ ) - { - /*exc_fx[i] *= ratio_fx;*/ - exc_fx[i] = round_fx( L_shl( L_mac( -8192, exc_fx[i], ratio_fx ), 2 ) ); - move16(); - } - } - *Last_frame_ener_fx = etmp1_fx; /*2*Q_new+1*/ - move32(); - } - ELSE - { - /*-------------------------------------------------------* - * In normal cases, just compute the energy of the frame - *-------------------------------------------------------*/ - - etmp_fx = sum2_fx( exc_fx, L_frame ); /*2*Q_new+1 */ -#ifdef ADD_LRTD - PMTE() - etmp_fx = L_shr( etmp_fx, add( 8 + 1 - 4, shl( Q_new, 1 ) ) ); /*2*Q_new+1 //INV_L_FRAME = 1/256 -> Q4*/ -#else - etmp_fx = L_shr( etmp_fx, add( 8 + 1 - 4, shl( Q_new, 1 ) ) ); /*2*Q_new+1 //INV_L_FRAME = 1/256 -> Q4*/ -#endif - *Last_frame_ener_fx = etmp_fx; - move32(); /*2*Q_new+1*/ - } - - return; -} - - -void pre_echo_att_ivas_fx( - Word32 *Last_frame_ener_fx, /* i/o: Energy of the last frame 2*Q_new+1*/ - Word16 *exc_fx, /* i/o: Excitation of the current frame Q_new*/ - const Word16 gsc_attack_flag_fx, /* i : flag signalling attack encoded by AC mode (GSC) Q0*/ - const Word16 Q_new, - const Word16 last_coder_type, /* i : Last coding mode Q0*/ - const Word16 L_frame /* i : Frame length Q0*/ -) -{ - Word32 etmp_fx; - Word32 finc_fx[ATT_LENGHT16k] = { 0 }; - move16(); - Word16 ratio_fx; - Word16 attack_pos_fx, i; - Word32 L_tmp, L_tmp1; - Word16 tmp, n1, n2, exp, frac1, frac2; - Word32 etmp1_fx; - Word16 att_len; - - test(); - IF( gsc_attack_flag_fx > 0 && EQ_16( last_coder_type, AUDIO ) ) /*gsc_attack_flag_fx does not get set for all the test cases */ - { - /*-------------------------------------------------------------------------* - * Find where the onset (attack) occurs by computing the energy per section - * The inverse weighting aims to favor the first maxima in case of - * gradual onset - *-------------------------------------------------------------------------*/ - att_len = ATT_LENGHT; /* Q0 */ - move16(); - if ( EQ_16( L_frame, L_FRAME16k ) ) - { - att_len = ATT_LENGHT16k; /* Q0 */ - move16(); - } - FOR( i = 0; i < att_len; i++ ) - { - L_tmp = sum2_fx( &exc_fx[i * 4], ATT_SEG_LEN ); /*2*Q_new+1, //ATT_SEG_LEN=(L_FRAME/ATT_LENGHT)=4(=shl(x,2))*/ - tmp = div_s( sub( att_len, i ), att_len ); /*Q15 */ - L_tmp = Mult_32_16( L_tmp, tmp ); /*2*Q_new+1 */ - finc_fx[i] = L_tmp; - move32(); /*2*Q_new+1 */ - } - - attack_pos_fx = maximum_32_fx( finc_fx, att_len, &etmp_fx ); - - /* Scaled the maximum energy and allowed 6 dB increase*/ - etmp_fx = L_shr( etmp_fx, add( 2 + 1 - 4, shl( Q_new, 1 ) ) ); /*2*Q_new+1 //INV_ATT_SEG_LEN=1/4(=shr(x,2)) -> Q4 */ - etmp1_fx = etmp_fx; - move32(); -#ifdef BASOP_NOGLOB - *Last_frame_ener_fx = L_shl_sat( *Last_frame_ener_fx, 2 ); -#else - *Last_frame_ener_fx = L_shl( *Last_frame_ener_fx, 2 ); -#endif - move32(); /*2*Q_new+1 */ - - /* If the maximum normalized energy > last frame energy + 6dB */ - test(); - IF( GT_32( etmp_fx, *Last_frame_ener_fx ) && attack_pos_fx > 0 ) - { - /* Find the average energy before the attack */ - L_tmp = sum32_fx( finc_fx, attack_pos_fx ); /*Q1 */ - L_tmp1 = L_shr( L_mult( attack_pos_fx, attack_pos_fx ), 1 ); /*Q0 */ - tmp = round_fx( Isqrt( L_tmp1 ) ); /*Q15 */ - L_tmp = L_shr( L_tmp, 2 ); /*Q1 ; ATT_SEG_LEN=4 */ - etmp_fx = Mult_32_16( L_tmp, tmp ); /*Q1 */ - - etmp_fx = L_shr( etmp_fx, add( 1 - 4, shl( Q_new, 1 ) ) ); /* makes etmp i nQ4 as *Last_frame_ener_fx */ - /* Find the correction factor and apply it before the attack */ - /* ratio = (float)sqrt(*Last_frame_ener/etmp);*/ - /* = isqrt(etmp/(*Last_frame_ener)) */ - etmp_fx = L_max( etmp_fx, 1 ); - *Last_frame_ener_fx = L_max( *Last_frame_ener_fx, 1 ); - move32(); - n1 = norm_l( etmp_fx ); - n2 = norm_l( *Last_frame_ener_fx ); - - n1 = sub( n1, 1 ); - exp = sub( n1, n2 ); - - frac1 = round_fx( L_shl( etmp_fx, n1 ) ); -#ifdef BASOP_NOGLOB - frac2 = round_fx_sat( L_shl_sat( *Last_frame_ener_fx, n2 ) ); -#else - frac2 = round_fx( L_shl( *Last_frame_ener_fx, n2 ) ); -#endif - L_tmp = L_mult0( 128, div_s( frac1, frac2 ) ); /* s = gain_out / gain_in */ - L_tmp = L_shr( L_tmp, exp ); /* add exponent */ - - L_tmp = Isqrt( L_tmp ); - ratio_fx = round_fx( L_shl( L_tmp, 9 ) ); - - /* Pre-echo atttenuation should never increase the energy */ - ratio_fx = s_min( ratio_fx, 8192 /* 1 in Q13 */ ); /* Q13 */ - FOR( i = 0; i < attack_pos_fx * ATT_SEG_LEN; i++ ) - { - /*exc_fx[i] *= ratio_fx;*/ - exc_fx[i] = round_fx( L_shl( L_mac( -8192, exc_fx[i], ratio_fx ), 2 ) ); - move16(); - } - } - *Last_frame_ener_fx = etmp1_fx; /* 2 * Q_new + 1 */ - move32(); - } - ELSE - { - /*-------------------------------------------------------* - * In normal cases, just compute the energy of the frame - *-------------------------------------------------------*/ - Word16 exp_etmp = sub( 15, Q_new ); - etmp_fx = sum2_16_exp_fx( exc_fx, L_frame, &exp_etmp, 7 ); /* Q = 31-exp_etmp */ - - etmp_fx = L_shr( etmp_fx, 8 ); /*31-exp_etmp//INV_L_FRAME = 1/256*/ - - IF( EQ_16( L_frame, L_FRAME16k ) ) - { - etmp_fx = Mpy_32_16_1( etmp_fx, 26214 /* 0.8 in Q15 */ ); /*31 - exp_etmp*/ - } - *Last_frame_ener_fx = L_shl( etmp_fx, sub( shl( Q_new, 1 ), sub( 30 /*31-1*/, exp_etmp ) ) ); /*2*Q_new+1*/ - move32(); /*2*Q_new+1*/ - } - - return; -} diff --git a/lib_com/gs_preech_fx.c b/lib_com/gs_preech_fx.c index 548cba204f55601d6cfc57deb9ea5944478db8bf..3b3eaa7776b9ff3c7403e4cb7f30decf8bf77a2b 100644 --- a/lib_com/gs_preech_fx.c +++ b/lib_com/gs_preech_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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,8 @@ #include #include "cnst.h" #include "rom_com.h" -#include "prot.h" -#include "wmc_auto.h" #include "prot_fx.h" +#include "wmc_auto.h" /*-------------------------------------------------------------------* * Local constants @@ -101,11 +100,7 @@ void pre_echo_att_fx( etmp_fx = L_shr( etmp_fx, add( 2 + 1 - 4, shl( Q_new, 1 ) ) ); /*2*Q_new+1 //INV_ATT_SEG_LEN=1/4(=shr(x,2)) -> Q4 */ etmp1_fx = etmp_fx; move32(); -#ifdef BASOP_NOGLOB *Last_frame_ener_fx = L_shl_sat( *Last_frame_ener_fx, 2 ); -#else - *Last_frame_ener_fx = L_shl( *Last_frame_ener_fx, 2 ); -#endif move32(); /*2*Q_new+1 */ /* If the maximum normalized energy > last frame energy + 6dB */ @@ -133,11 +128,7 @@ void pre_echo_att_fx( exp = sub( n1, n2 ); frac1 = round_fx( L_shl( etmp_fx, n1 ) ); -#ifdef BASOP_NOGLOB frac2 = round_fx_sat( L_shl_sat( *Last_frame_ener_fx, n2 ) ); -#else - frac2 = round_fx( L_shl( *Last_frame_ener_fx, n2 ) ); -#endif L_tmp = L_mult0( 128, div_s( frac1, frac2 ) ); /* s = gain_out / gain_in */ L_tmp = L_shr( L_tmp, exp ); /* add exponent */ @@ -162,13 +153,8 @@ void pre_echo_att_fx( * In normal cases, just compute the energy of the frame *-------------------------------------------------------*/ - etmp_fx = sum2_fx( exc_fx, L_frame ); /*2*Q_new+1 */ -#ifdef ADD_LRTD - PMTE() - etmp_fx = L_shr( etmp_fx, add( 8 + 1 - 4, shl( Q_new, 1 ) ) ); /*2*Q_new+1 //INV_L_FRAME = 1/256 -> Q4*/ -#else + etmp_fx = sum2_fx( exc_fx, L_frame ); /*2*Q_new+1 */ etmp_fx = L_shr( etmp_fx, add( 8 + 1 - 4, shl( Q_new, 1 ) ) ); /*2*Q_new+1 //INV_L_FRAME = 1/256 -> Q4*/ -#endif *Last_frame_ener_fx = etmp_fx; move32(); /*2*Q_new+1*/ } @@ -226,11 +212,7 @@ void pre_echo_att_ivas_fx( etmp_fx = L_shr( etmp_fx, add( 2 + 1 - 4, shl( Q_new, 1 ) ) ); /*2*Q_new+1 //INV_ATT_SEG_LEN=1/4(=shr(x,2)) -> Q4 */ etmp1_fx = etmp_fx; move32(); -#ifdef BASOP_NOGLOB *Last_frame_ener_fx = L_shl_sat( *Last_frame_ener_fx, 2 ); -#else - *Last_frame_ener_fx = L_shl( *Last_frame_ener_fx, 2 ); -#endif move32(); /*2*Q_new+1 */ /* If the maximum normalized energy > last frame energy + 6dB */ @@ -258,11 +240,7 @@ void pre_echo_att_ivas_fx( exp = sub( n1, n2 ); frac1 = round_fx( L_shl( etmp_fx, n1 ) ); -#ifdef BASOP_NOGLOB frac2 = round_fx_sat( L_shl_sat( *Last_frame_ener_fx, n2 ) ); -#else - frac2 = round_fx( L_shl( *Last_frame_ener_fx, n2 ) ); -#endif L_tmp = L_mult0( 128, div_s( frac1, frac2 ) ); /* s = gain_out / gain_in */ L_tmp = L_shr( L_tmp, exp ); /* add exponent */ diff --git a/lib_com/hp50.c b/lib_com/hp50.c deleted file mode 100644 index 02c11ce6cb3427c6706d659f70056eb300c73ef5..0000000000000000000000000000000000000000 --- a/lib_com/hp50.c +++ /dev/null @@ -1,798 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include -#include "options.h" -#include "prot.h" -#include "wmc_auto.h" -#include "prot_fx.h" - -/* - * hp20 - * - * Function: - * 2nd order high pass filter with nominal cut off frequency at 20 Hz. - * - * Returns: - * void - */ - -#ifndef IVAS_FLOAT_FIXED -void hp20_flt( - Float32 signal[], - const Word16 lg, - Float32 mem[], - const Word32 Fs ) -{ - Word16 i; - Float32 x0, x1, x2, y0, y1, y2; - Float32 a1, a2, b1, b2; - - y1 = mem[0]; - y2 = mem[1]; - x0 = mem[2]; - x1 = mem[3]; - - if ( Fs == 8000 ) - { - /* hp filter 20Hz at 3dB for 8000KHz input sampling rate - [b,a] = butter(2, 20.0/4000.0, 'high'); - b = [0.988954248067140 -1.977908496134280 0.988954248067140] - a =[1.000000000000000 -1.977786483776764 0.978030508491796]*/ - a1 = 1.977786483776764f; - a2 = -0.978030508491796f; - b1 = -1.977908496134280f; - b2 = 0.988954248067140f; - } - else if ( Fs == 16000 ) - { - /* hp filter 20Hz at 3dB for 16000KHz sampling rate - [b,a] = butter(2, 20.0/8000.0, 'high'); - b =[ 0.994461788958195 -1.988923577916390 0.994461788958195] - a =[1.000000000000000 -1.988892905899653 0.988954249933127] */ - a1 = 1.988892905899653f; - a2 = -0.988954249933127f; - b1 = -1.988923577916390f; - b2 = 0.994461788958195f; - } - else if ( Fs == 32000 ) - { - /* hp filter 20Hz at 3dB for 32000KHz sampling rate - [b,a] = butter(2, 20.0/16000.0, 'high'); - b =[0.997227049904470 -1.994454099808940 0.997227049904470] - a =[1.000000000000000 -1.994446410541927 0.994461789075954]*/ - a1 = 1.994446410541927f; - a2 = -0.994461789075954f; - b1 = -1.994454099808940f; - b2 = 0.997227049904470f; - } - else - { - /* hp filter 20Hz at 3dB for 48000KHz sampling rate - [b,a] = butter(2, 20.0/24000.0, 'high'); - b =[ 0.998150511190452 -1.996301022380904 0.998150511190452] - a =[1.000000000000000 -1.996297601769122 0.996304442992686]*/ - a1 = 1.996297601769122f; - a2 = -0.996304442992686f; - b1 = -1.996301022380904f; - b2 = 0.998150511190452f; - } - - for ( i = 0; i < lg; i++ ) - { - x2 = x1; - x1 = x0; - x0 = signal[i]; - y0 = ( y1 * a1 ) + ( y2 * a2 ) + ( x0 * b2 ) + ( x1 * b1 ) + ( x2 * b2 ); - signal[i] = y0; - y2 = y1; - y1 = y0; - } - - mem[0] = ( ( y1 > 1e-10 ) | ( y1 < -1e-10 ) ) ? y1 : 0; - mem[1] = ( ( y2 > 1e-10 ) | ( y2 < -1e-10 ) ) ? y2 : 0; - mem[2] = ( ( x0 > 1e-10 ) | ( x0 < -1e-10 ) ) ? x0 : 0; - mem[3] = ( ( x1 > 1e-10 ) | ( x1 < -1e-10 ) ) ? x1 : 0; - - return; -} -#endif - - -#define HP20_COEFF_SCALE ( 2 ) -/* - * hp20 - * - * Function: - * 2nd order high pass filter with nominal cut off frequency at 20 Hz. - * - * Returns: - * void - */ - -static Word32 HP50_Mode2_Mpy_32_16_fix( Word32 a, Word16 b ) -{ - Word32 result = Mpy_32_16_1( a, b ); - /* perform rounding towards lower value for negative results */ - if ( result < 0 ) - result = L_add( result, 1 ); - return result; -} - -static Word32 HP50_Mpy_32_32_fix( Word32 a, Word32 b ) -{ - Word32 result = Mpy_32_32( a, b ); - /* perform rounding towards lower value for negative results */ - if ( result < 0 ) - result = L_add( result, 1 ); - return result; -} - - -static void filter_2nd_order( - Word16 signal[], - const Word16 stride, - const Word16 prescale, - const Word16 lg, - Word32 mem[4], - Word32 a1, - Word32 a2, - Word32 b1, - Word32 b2 ) -{ - - Word16 i; - Word16 x2, x1; - Word32 L_sum, L_y1, L_y2; -#ifdef BASOP_NOGLOB_DECLARE_LOCAL - Flag Overflow = 0; -#endif - - - /* - * Saturation: The states of the filter, namely L_y1 and L_y2 shall - * never saturate, because that causes error in the filter feedback. - * The final output written into signal[] might saturate because of - * unavoidable filter overshoot. - */ - - /* Execute first 2 iterations with 32-bit x anx y memory values */ - BASOP_SATURATE_ERROR_ON_EVS - L_sum = HP50_Mpy_32_32_fix( b2, mem[2] ); /* b2*x2 */ - L_sum = L_add( L_sum, HP50_Mpy_32_32_fix( b1, mem[3] ) ); /* b1*x1 */ - x2 = shr( signal[0], prescale ); - L_sum = L_add( L_sum, HP50_Mode2_Mpy_32_16_fix( b2, x2 ) ); /* b2*x0 */ - L_sum = L_add( L_sum, HP50_Mpy_32_32_fix( mem[0], a2 ) ); /* y2*a2 */ - L_sum = L_add( L_sum, HP50_Mpy_32_32_fix( mem[1], a1 ) ); /* y1*a1 */ - -#ifdef BASOP_NOGLOB - L_y2 = L_shl_o( L_sum, HP20_COEFF_SCALE, &Overflow ); -#else - L_y2 = L_shl( L_sum, HP20_COEFF_SCALE ); -#endif - BASOP_SATURATE_ERROR_OFF_EVS - BASOP_SATURATE_WARNING_OFF_EVS -#ifdef BASOP_NOGLOB - signal[0] = round_fx_o( L_shl_o( L_y2, prescale, &Overflow ), &Overflow ); -#else /* BASOP_NOGLOB */ - signal[0] = round_fx( L_shl( L_y2, prescale ) ); -#endif /* BASOP_NOGLOB */ - BASOP_SATURATE_WARNING_ON_EVS - - BASOP_SATURATE_ERROR_ON_EVS - L_sum = HP50_Mpy_32_32_fix( b2, mem[3] ); /* b2*x2 */ - L_sum = L_add( L_sum, HP50_Mode2_Mpy_32_16_fix( b1, x2 ) ); /* b1*x1 */ - x1 = shr( signal[stride], prescale ); - L_sum = L_add( L_sum, HP50_Mode2_Mpy_32_16_fix( b2, x1 ) ); /* b2*x0 */ - L_sum = L_add( L_sum, HP50_Mpy_32_32_fix( mem[1], a2 ) ); /* y2*a2 */ - L_sum = L_add( L_sum, HP50_Mpy_32_32_fix( L_y2, a1 ) ); /* y1*a1 */ - -#ifdef BASOP_NOGLOB - L_y1 = L_shl_o( L_sum, HP20_COEFF_SCALE, &Overflow ); -#else - L_y1 = L_shl( L_sum, HP20_COEFF_SCALE ); -#endif - BASOP_SATURATE_ERROR_OFF_EVS - BASOP_SATURATE_WARNING_OFF_EVS -#ifdef BASOP_NOGLOB - signal[stride] = round_fx_o( L_shl_o( L_y1, prescale, &Overflow ), &Overflow ); -#else /* BASOP_NOGLOB */ - signal[stride] = round_fx( L_shl( L_y1, prescale ) ); -#endif /* BASOP_NOGLOB */ - BASOP_SATURATE_WARNING_ON_EVS - move16(); - - /* New we use a trick and toggle x1/x2 and L_y1/L_y2 to save a few cycles unrolling the loop by 2 */ - FOR( i = 2; i < lg; i += 2 ) - { - /* y[i+0] = b2*x[i-2] + b1*x[i-1] + b2*x[i-0] + a2*y[i-2] + a1*y[i-1]; */ - BASOP_SATURATE_ERROR_ON_EVS - L_sum = HP50_Mode2_Mpy_32_16_fix( b2, x2 ); - L_sum = L_add( L_sum, HP50_Mode2_Mpy_32_16_fix( b1, x1 ) ); - x2 = shr( signal[i * stride], prescale ); - L_sum = L_add( L_sum, HP50_Mode2_Mpy_32_16_fix( b2, x2 ) ); - L_sum = L_add( L_sum, HP50_Mpy_32_32_fix( L_y2, a2 ) ); - L_sum = L_add( L_sum, HP50_Mpy_32_32_fix( L_y1, a1 ) ); - -#ifdef BASOP_NOGLOB - L_y2 = L_shl_o( L_sum, HP20_COEFF_SCALE, &Overflow ); -#else - L_y2 = L_shl( L_sum, HP20_COEFF_SCALE ); -#endif - BASOP_SATURATE_ERROR_OFF_EVS - BASOP_SATURATE_WARNING_OFF_EVS -#ifdef BASOP_NOGLOB - signal[i_mult( i, stride )] = round_fx_o( L_shl_o( L_y2, prescale, &Overflow ), &Overflow ); -#else /* BASOP_NOGLOB */ - signal[i_mult( i, stride )] = round_fx( L_shl( L_y2, prescale ) ); - move16(); -#endif /* BASOP_NOGLOB */ - BASOP_SATURATE_WARNING_ON_EVS - /* y[i+1] = b2*x[i-1] + b1*x[i-0] + b2*x[i+1] + a2*y[i-1] + a1*y[i+0]; */ - BASOP_SATURATE_ERROR_ON_EVS - L_sum = HP50_Mode2_Mpy_32_16_fix( b2, x1 ); - L_sum = L_add( L_sum, HP50_Mode2_Mpy_32_16_fix( b1, x2 ) ); - x1 = shr( signal[( i + 1 ) * stride], prescale ); - L_sum = L_add( L_sum, HP50_Mode2_Mpy_32_16_fix( b2, x1 ) ); - L_sum = L_add( L_sum, HP50_Mpy_32_32_fix( L_y1, a2 ) ); - L_sum = L_add( L_sum, HP50_Mpy_32_32_fix( L_y2, a1 ) ); - -#ifdef BASOP_NOGLOB - L_y1 = L_shl_o( L_sum, HP20_COEFF_SCALE, &Overflow ); -#else - L_y1 = L_shl( L_sum, HP20_COEFF_SCALE ); -#endif - BASOP_SATURATE_ERROR_OFF_EVS - BASOP_SATURATE_WARNING_OFF_EVS -#ifdef BASOP_NOGLOB - signal[i_mult( add( i, 1 ), stride )] = round_fx_o( L_shl_o( L_y1, prescale, &Overflow ), &Overflow ); -#else /* BASOP_NOGLOB */ - signal[i_mult( add( i, 1 ), stride )] = round_fx( L_shl( L_y1, prescale ) ); -#endif - BASOP_SATURATE_WARNING_ON_EVS - move16(); - } - /* update static filter memory from variables */ - mem[0] = L_y2; - move32(); - mem[1] = L_y1; - move32(); - mem[2] = L_deposit_h( x2 ); - move32(); - mem[3] = L_deposit_h( x1 ); - move32(); - - - return; -} - - -void hp20( Word16 signal[], /* i/o: signal to filter any */ - const Word16 stride, /* i : stride to be applied accessing signal */ - const Word16 lg, /* i : length of signal (integer) Q0 */ - Word32 mem[5], /* i/o: static filter memory with this layout: */ - /* mem[0]: y[-2] (32-bit) */ - /* mem[1]; y[-1] (32-bit) */ - /* mem[2]: x[-2] << 16 */ - /* mem[3]: x[-1] << 16 */ - /* Note: mem[0..3] need to be scaled per frame */ - /* mem[4]: states scale */ - const Word32 sFreq ) /* i : input sampling rate Q0 */ -{ - Word32 a1, b1, a2, b2; - Word16 prescale, prescaleOld, diff; -#ifdef BASOP_NOGLOB_DECLARE_LOCAL - Flag Overflow = 0; -#endif - - - prescale = getScaleFactor16( signal, lg ); - prescaleOld = extract_l( mem[4] ); -#ifdef BASOP_NOGLOB - diff = norm_l( L_shl_sat( mem[2], prescaleOld ) ); -#else - diff = norm_l( L_shl( mem[2], prescaleOld ) ); -#endif - if ( mem[2] != 0 ) - { - prescale = s_min( prescale, diff ); - } -#ifdef BASOP_NOGLOB - diff = norm_l( L_shl_o( mem[3], prescaleOld, &Overflow ) ); -#else - diff = norm_l( L_shl( mem[3], prescaleOld ) ); -#endif - if ( mem[3] != 0 ) - { - prescale = s_min( prescale, diff ); - } - /* Take into account the left shift performed into the loop + 1 bit headroom*/ - prescale = s_max( -12, sub( 1 + HP20_COEFF_SCALE, prescale ) ); - IF( prescale != prescaleOld ) - { - diff = sub( prescale, prescaleOld ); -#ifdef BASOP_NOGLOB - mem[0] = L_shr_o( mem[0], diff, &Overflow ); - move32(); - mem[1] = L_shr_o( mem[1], diff, &Overflow ); - move32(); - mem[2] = L_shr_o( mem[2], diff, &Overflow ); - move32(); - mem[3] = L_shr_o( mem[3], diff, &Overflow ); - move32(); -#else - mem[0] = L_shr( mem[0], diff ); - move32(); - mem[1] = L_shr( mem[1], diff ); - move32(); - mem[2] = L_shr( mem[2], diff ); - move32(); - mem[3] = L_shr( mem[3], diff ); - move32(); -#endif - mem[4] = L_deposit_l( prescale ); - } - - IF( EQ_32( sFreq, 8000 ) ) - { - /* hp filter 20Hz at 3dB for 8000 Hz input sampling rate - [b,a] = butter(2, 20.0/4000.0, 'high'); - b = [0.988954248067140 -1.977908496134280 0.988954248067140] - a = [1.000000000000000 -1.977786483776764 0.978030508491796]*/ - a1 = 1061816033l /* 1.977786483776764 Q29*/; - move32(); - a2 = -525076131l /*-0.978030508491796 Q29*/; - move32(); - b1 = -1061881538l /*-1.977908496134280 Q29*/; - move32(); - b2 = 530940769l /* 0.988954248067140 Q29*/; - move32(); - } - ELSE IF( EQ_32( sFreq, 16000 ) ) - { - /* hp filter 20Hz at 3dB for 16000KHz sampling rate - [b,a] = butter(2, 20.0/8000.0, 'high'); - b = [0.994461788958195 -1.988923577916390 0.994461788958195] - a = [1.000000000000000 -1.988892905899653 0.988954249933127] */ - a1 = 1067778748l /* 1.988892905899653 Q29*/; - move32(); - a2 = -530940770l /*-0.988954249933127 Q29*/; - move32(); - b1 = -1067795215l /*-1.988923577916390 Q29*/; - move32(); - b2 = 533897608l /* 0.994461788958195 Q29*/; - move32(); - } - ELSE IF( EQ_32( sFreq, 32000 ) ) - { - /* hp filter 20Hz at 3dB for 32000KHz sampling rate - [b,a] = butter(2, 20.0/16000.0, 'high'); - b = [0.997227049904470 -1.994454099808940 0.997227049904470] - a = [1.000000000000000 -1.994446410541927 0.994461789075954]*/ - a1 = 1070760263l /* 1.994446410541927 Q29*/; - move32(); - a2 = -533897608l /*-0.994461789075954 Q29*/; - move32(); - b1 = -1070764392l /*-1.994454099808940 Q29*/; - move32(); - b2 = 535382196l /* 0.997227049904470 Q29*/; - move32(); - } - ELSE - { - assert( sFreq == 48000 ); - /* hp filter 20Hz at 3dB for 48000KHz sampling rate - [b,a] = butter(2, 20.0/24000.0, 'high'); - b =[0.998150511190452 -1.996301022380904 0.998150511190452] - a =[1.000000000000000 -1.996297601769122 0.996304442992686]*/ - a1 = 1071754114l /* 1.996297601769122 Q29*/; - move32(); - a2 = -534886875l /*-0.996304442992686 Q29*/; - move32(); - b1 = -1071755951l /*-1.996301022380904 Q29*/; - move32(); - b2 = 535877975l /* 0.998150511190452 Q29*/; - move32(); - } - - - filter_2nd_order( signal, stride, prescale, lg, - mem, a1, a2, b1, b2 ); - - return; -} - - -#ifdef HP20_FIX32_RECODING -void hp20_fx_32( - Word32 signal_fx[], - const Word16 lg, - Word32 mem_fx[], - const Word32 Fs ) -{ - Word32 i; - Word32 a1_fx, a2_fx, b1_fx, b2_fx; - Word32 diff_pos, diff_neg; -#ifdef BASOP_NOGLOB - Flag Overflow = 0; -#endif - Word16 prescale, prescaleOld, prescale_current_frame, diff; - - prescale = getScaleFactor32( signal_fx, lg ); - prescale_current_frame = s_min( 3, sub( 1 + HP20_COEFF_SCALE, prescale ) ); - - - prescaleOld = extract_l( mem_fx[4] ); - -#ifdef BASOP_NOGLOB - diff_pos = norm_l( L_shl_o( L_max( mem_fx[2], mem_fx[3] ), prescaleOld, &Overflow ) ); - diff_neg = norm_l( L_shl_o( L_min( mem_fx[2], mem_fx[3] ), prescaleOld, &Overflow ) ); -#else - diff_pos = norm_l( L_shl( L_max( mem_fx[2], mem_fx[3] ), prescaleOld ) ); - diff_neg = norm_l( L_shl( L_min( mem_fx[2], mem_fx[3] ), prescaleOld ) ); -#endif - - diff = L_max( diff_pos, diff_neg ); - - IF( NE_16( diff, 0 ) ) - { - prescale = s_min( prescale, diff ); - } - - prescale = s_min( 3, sub( 1 + HP20_COEFF_SCALE, prescale ) ); - - diff = sub( prescale, prescaleOld ); -#ifdef BASOP_NOGLOB - mem_fx[0] = L_shr_o( mem_fx[0], diff, &Overflow ); - move32(); - mem_fx[1] = L_shr_o( mem_fx[1], diff, &Overflow ); - move32(); - mem_fx[2] = L_shr_o( mem_fx[2], diff, &Overflow ); - move32(); - mem_fx[3] = L_shr_o( mem_fx[3], diff, &Overflow ); - move32(); -#else - mem_fx[0] = L_shr( mem_fx[0], diff ); - move32(); - mem_fx[1] = L_shr( mem_fx[1], diff ); - move32(); - mem_fx[2] = L_shr( mem_fx[2], diff ); - move32(); - mem_fx[3] = L_shr( mem_fx[3], diff ); - move32(); -#endif - mem_fx[4] = L_deposit_l( prescale_current_frame ); - move32(); - - IF( EQ_32( Fs, 8000 ) ) - { - /* hp filter 20Hz at 3dB for 8000KHz input sampling rate - [b,a] = butter(2, 20.0/4000.0, 'high'); - b = [0.988954248067140 -1.977908496134280 0.988954248067140] - a =[1.000000000000000 -1.977786483776764 0.978030508491796]*/ - a1_fx = 1061816033l /* 1.977786483776764 Q29*/; - a2_fx = -525076131l /*-0.978030508491796 Q29*/; - b1_fx = -1061881538l /*-1.977908496134280 Q29*/; - b2_fx = 530940769l /* 0.988954248067140 Q29*/; - } - ELSE IF( EQ_32( Fs, 16000 ) ) - { - /* hp filter 20Hz at 3dB for 16000KHz sampling rate - [b,a] = butter(2, 20.0/8000.0, 'high'); - b =[ 0.994461788958195 -1.988923577916390 0.994461788958195] - a =[1.000000000000000 -1.988892905899653 0.988954249933127] */ - a1_fx = 1067778748l /* 1.988892905899653 Q29*/; - a2_fx = -530940770l /*-0.988954249933127 Q29*/; - b1_fx = -1067795215l /*-1.988923577916390 Q29*/; - b2_fx = 533897608l /* 0.994461788958195 Q29*/; - } - ELSE IF( EQ_32( Fs, 32000 ) ) - { - /* hp filter 20Hz at 3dB for 32000KHz sampling rate - [b,a] = butter(2, 20.0/16000.0, 'high'); - b =[0.997227049904470 -1.994454099808940 0.997227049904470] - a =[1.000000000000000 -1.994446410541927 0.994461789075954]*/ - a1_fx = 1070760263l /* 1.994446410541927 Q29*/; - a2_fx = -533897608l /*-0.994461789075954 Q29*/; - b1_fx = -1070764392l /*-1.994454099808940 Q29*/; - b2_fx = 535382196l /* 0.997227049904470 Q29*/; - } - ELSE - { - /* hp filter 20Hz at 3dB for 48000KHz sampling rate - [b,a] = butter(2, 20.0/24000.0, 'high'); - b =[ 0.998150511190452 -1.996301022380904 0.998150511190452] - a =[1.000000000000000 -1.996297601769122 0.996304442992686]*/ - a1_fx = 1071754114l /* 1.996297601769122 Q29*/; - a2_fx = -534886875l /*-0.996304442992686 Q29*/; - b1_fx = -1071755951l /*-1.996301022380904 Q29*/; - b2_fx = 535877975l /* 0.998150511190452 Q29*/; - } - move32(); - move32(); - move32(); - move32(); - Word64 W_sum, W_y0, W_y1, W_y2; - Word32 x0, x1, x2; - - W_sum = W_mult_32_32( b2_fx, mem_fx[2] ); /* b2*x2 */ - W_sum = W_mac_32_32( W_sum, b1_fx, mem_fx[3] ); /* b1*x1 */ - x2 = L_shr( signal_fx[0], prescale ); - W_sum = W_mac_32_32( W_sum, b2_fx, x2 ); /* b2*x0 */ - W_sum = W_mac_32_32( W_sum, mem_fx[0], a2_fx ); /* y2*a2 */ - W_sum = W_mac_32_32( W_sum, mem_fx[1], a1_fx ); /* y1*a1 */ - W_y2 = W_shl( W_sum, HP20_COEFF_SCALE ); - signal_fx[0] = W_extract_h( W_shl( W_y2, prescale ) ); - move32(); - - W_sum = W_mult_32_32( b2_fx, mem_fx[3] ); /* b2*x2 */ - W_sum = W_mac_32_32( W_sum, b1_fx, x2 ); /* b1*x1 */ - x1 = L_shr( signal_fx[1], prescale ); - W_sum = W_mac_32_32( W_sum, b2_fx, x1 ); /* b2*x0 */ - W_sum = W_mac_32_32( W_sum, mem_fx[1], a2_fx ); /* y2*a2 */ - W_sum = W_mac_32_32( W_sum, W_extract_h( W_y2 ), a1_fx ); /* y1*a1 */ - W_y1 = W_shl( W_sum, HP20_COEFF_SCALE ); - signal_fx[1] = W_extract_h( W_shl( W_y1, prescale ) ); - move32(); - - diff = sub( prescale_current_frame, prescale ); - W_y1 = W_shr( W_y1, diff ); - W_y2 = W_shr( W_y2, diff ); - x2 = L_shr( x2, diff ); - x1 = L_shr( x1, diff ); - - FOR( i = 2; i < lg; i++ ) - { - W_sum = W_mult_32_32( b2_fx, x2 ); /* b2*x2 */ - W_sum = W_mac_32_32( W_sum, b1_fx, x1 ); /* b1*x1 */ - x0 = L_shr( signal_fx[i], prescale_current_frame ); - W_sum = W_mac_32_32( W_sum, b2_fx, x0 ); /* b2*x0 */ - W_sum = W_mac_32_32( W_sum, W_extract_h( W_y2 ), a2_fx ); /* y2*a2 */ - W_sum = W_mac_32_32( W_sum, W_extract_h( W_y1 ), a1_fx ); /* y1*a1 */ - W_y0 = W_shl( W_sum, HP20_COEFF_SCALE ); - - signal_fx[i] = W_extract_h( W_shl( W_y0, prescale_current_frame ) ); - move32(); - - x2 = x1; - x1 = x0; - W_y2 = W_y1; - W_y1 = W_y0; - - move32(); - move32(); - move64(); - move64(); - } - - mem_fx[0] = W_extract_h( W_y2 ); - mem_fx[1] = W_extract_h( W_y1 ); - mem_fx[2] = x2; - mem_fx[3] = x1; - - move32(); - move32(); - move32(); - move32(); - - return; -} -#else -void hp20_fx_32( - Word32 signal_fx[], - const Word16 lg, - Word32 mem_fx[], - const Word32 Fs ) -{ - Word16 i; - Word32 a1_fx, a2_fx, b1_fx, b2_fx; - Word16 Qx0, Qx1, Qx2, Qy1, Qprev_y1, Qy2, Qprev_y2, Qmin; - Word64 x0_fx64, x1_fx64, x2_fx64, y0_fx64, y1_fx64, y2_fx64, R1, R2, R3, R4, R5; - - IF( EQ_32( Fs, 8000 ) ) - { - /* hp filter 20Hz at 3dB for 8000KHz input sampling rate - [b,a] = butter(2, 20.0/4000.0, 'high'); - b = [0.988954248067140 -1.977908496134280 0.988954248067140] - a =[1.000000000000000 -1.977786483776764 0.978030508491796]*/ - a1_fx = 1061816033l /* 1.977786483776764 Q29*/; - a2_fx = -525076131l /*-0.978030508491796 Q29*/; - b1_fx = -1061881538l /*-1.977908496134280 Q29*/; - b2_fx = 530940769l /* 0.988954248067140 Q29*/; - } - ELSE IF( EQ_32( Fs, 16000 ) ) - { - /* hp filter 20Hz at 3dB for 16000KHz sampling rate - [b,a] = butter(2, 20.0/8000.0, 'high'); - b =[ 0.994461788958195 -1.988923577916390 0.994461788958195] - a =[1.000000000000000 -1.988892905899653 0.988954249933127] */ - a1_fx = 1067778748l /* 1.988892905899653 Q29*/; - a2_fx = -530940770l /*-0.988954249933127 Q29*/; - b1_fx = -1067795215l /*-1.988923577916390 Q29*/; - b2_fx = 533897608l /* 0.994461788958195 Q29*/; - } - ELSE IF( EQ_32( Fs, 32000 ) ) - { - /* hp filter 20Hz at 3dB for 32000KHz sampling rate - [b,a] = butter(2, 20.0/16000.0, 'high'); - b =[0.997227049904470 -1.994454099808940 0.997227049904470] - a =[1.000000000000000 -1.994446410541927 0.994461789075954]*/ - a1_fx = 1070760263l /* 1.994446410541927 Q29*/; - a2_fx = -533897608l /*-0.994461789075954 Q29*/; - b1_fx = -1070764392l /*-1.994454099808940 Q29*/; - b2_fx = 535382196l /* 0.997227049904470 Q29*/; - } - ELSE - { - /* hp filter 20Hz at 3dB for 48000KHz sampling rate - [b,a] = butter(2, 20.0/24000.0, 'high'); - b =[ 0.998150511190452 -1.996301022380904 0.998150511190452] - a =[1.000000000000000 -1.996297601769122 0.996304442992686]*/ - a1_fx = 1071754114l /* 1.996297601769122 Q29*/; - a2_fx = -534886875l /*-0.996304442992686 Q29*/; - b1_fx = -1071755951l /*-1.996301022380904 Q29*/; - b2_fx = 535877975l /* 0.998150511190452 Q29*/; - } - move32(); - move32(); - move32(); - move32(); - - Qprev_y1 = extract_l( mem_fx[4] ); - Qprev_y2 = extract_l( mem_fx[5] ); - y1_fx64 = W_deposit32_l( mem_fx[0] ); - y2_fx64 = W_deposit32_l( mem_fx[1] ); - x0_fx64 = W_deposit32_l( mem_fx[2] ); - x1_fx64 = W_deposit32_l( mem_fx[3] ); - - FOR( i = 0; i < lg; i++ ) - { - x2_fx64 = x1_fx64; - move64(); - x1_fx64 = x0_fx64; - move64(); - x0_fx64 = W_deposit32_l( signal_fx[i] ); - - Qy1 = W_norm( y1_fx64 ); - if ( y1_fx64 == 0 ) - { - Qy1 = 62; - move16(); - } - Qy1 = sub( Qy1, 34 ); - R1 = W_mult0_32_32( W_extract_l( W_shl( y1_fx64, Qy1 ) ), a1_fx ); - Qy1 = add( Qy1, Qprev_y1 ); - - Qy2 = W_norm( y2_fx64 ); - if ( y2_fx64 == 0 ) - { - Qy2 = 62; - move16(); - } - Qy2 = sub( Qy2, 34 ); - R2 = W_mult0_32_32( W_extract_l( W_shl( y2_fx64, Qy2 ) ), a2_fx ); - Qy2 = add( Qy2, Qprev_y2 ); - - Qx0 = W_norm( x0_fx64 ); - if ( x0_fx64 == 0 ) - { - Qx0 = 62; - move16(); - } - Qx0 = sub( Qx0, 34 ); - R3 = W_mult0_32_32( W_extract_l( W_shl( x0_fx64, Qx0 ) ), b2_fx ); - - Qx1 = W_norm( x1_fx64 ); - if ( x1_fx64 == 0 ) - { - Qx1 = 62; - move16(); - } - Qx1 = sub( Qx1, 34 ); - R4 = W_mult0_32_32( W_extract_l( W_shl( x1_fx64, Qx1 ) ), b1_fx ); - - Qx2 = W_norm( x2_fx64 ); - if ( x2_fx64 == 0 ) - { - Qx2 = 62; - move16(); - } - Qx2 = sub( Qx2, 34 ); - R5 = W_mult0_32_32( W_extract_l( W_shl( x2_fx64, Qx2 ) ), b2_fx ); - - Qmin = s_min( Qy1, Qy2 ); - - y0_fx64 = W_add( W_shr( R1, sub( Qy1, Qmin ) ), W_shr( R2, sub( Qy2, Qmin ) ) ); - - Qmin = s_min( Qmin, Qx0 ); - Qmin = s_min( Qmin, Qx1 ); - Qmin = s_min( Qmin, Qx2 ); - - y0_fx64 = W_add( W_shr( y0_fx64, sub( s_min( Qy1, Qy2 ), Qmin ) ), W_add( W_shr( R3, sub( Qx0, Qmin ) ), W_add( W_shr( R4, sub( Qx1, Qmin ) ), W_shr( R5, sub( Qx2, Qmin ) ) ) ) ); - - y0_fx64 = W_shr( y0_fx64, 29 ); - - signal_fx[i] = W_extract_l( W_shr( y0_fx64, Qmin ) ); - move32(); - IF( signal_fx[i] < 0 ) - { - signal_fx[i] = L_add( signal_fx[i], 1 ); - move32(); - } - - y2_fx64 = y1_fx64; - y1_fx64 = y0_fx64; - Qprev_y2 = Qprev_y1; - Qprev_y1 = Qmin; - move64(); - move64(); - move16(); - move16(); - } - - Qy1 = W_norm( y1_fx64 ); - test(); - IF( y1_fx64 != 0 && LT_16( Qy1, 32 ) ) - { - y1_fx64 = W_shr( y1_fx64, sub( 32, Qy1 ) ); - Qprev_y1 = sub( Qprev_y1, sub( 32, Qy1 ) ); - } - - Qy2 = W_norm( y2_fx64 ); - test(); - IF( y2_fx64 != 0 && LT_16( Qy2, 32 ) ) - { - y2_fx64 = W_shr( y2_fx64, sub( 32, Qy2 ) ); - Qprev_y2 = sub( Qprev_y2, sub( 32, Qy2 ) ); - } - - mem_fx[0] = W_extract_l( y1_fx64 ); - mem_fx[1] = W_extract_l( y2_fx64 ); - mem_fx[2] = W_extract_l( x0_fx64 ); - mem_fx[3] = W_extract_l( x1_fx64 ); - mem_fx[4] = Qprev_y1; - mem_fx[5] = Qprev_y2; - move32(); - move32(); - move32(); - move32(); - move32(); - move32(); - - return; -} -#endif diff --git a/lib_com/hp50_fx.c b/lib_com/hp50_fx.c index 78e358a80881101ca146b9e16c50d2452ec748bf..f5e7105cfcf9dfeebad0e4bff0d5a262cc8a7dd8 100644 --- a/lib_com/hp50_fx.c +++ b/lib_com/hp50_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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,19 +37,8 @@ #include #include #include "options.h" -#include "prot.h" -#include "wmc_auto.h" #include "prot_fx.h" - -/* - * hp20 - * - * Function: - * 2nd order high pass filter with nominal cut off frequency at 20 Hz. - * - * Returns: - * void - */ +#include "wmc_auto.h" #define HP20_COEFF_SCALE ( 2 ) @@ -118,18 +107,10 @@ static void filter_2nd_order( L_sum = L_add( L_sum, HP50_Mpy_32_32_fix( mem[0], a2 ) ); /* y2*a2 */ L_sum = L_add( L_sum, HP50_Mpy_32_32_fix( mem[1], a1 ) ); /* y1*a1 */ -#ifdef BASOP_NOGLOB L_y2 = L_shl_o( L_sum, HP20_COEFF_SCALE, &Overflow ); -#else - L_y2 = L_shl( L_sum, HP20_COEFF_SCALE ); -#endif BASOP_SATURATE_ERROR_OFF_EVS BASOP_SATURATE_WARNING_OFF_EVS -#ifdef BASOP_NOGLOB signal[0] = round_fx_o( L_shl_o( L_y2, prescale, &Overflow ), &Overflow ); -#else /* BASOP_NOGLOB */ - signal[0] = round_fx( L_shl( L_y2, prescale ) ); -#endif /* BASOP_NOGLOB */ BASOP_SATURATE_WARNING_ON_EVS BASOP_SATURATE_ERROR_ON_EVS @@ -140,18 +121,10 @@ static void filter_2nd_order( L_sum = L_add( L_sum, HP50_Mpy_32_32_fix( mem[1], a2 ) ); /* y2*a2 */ L_sum = L_add( L_sum, HP50_Mpy_32_32_fix( L_y2, a1 ) ); /* y1*a1 */ -#ifdef BASOP_NOGLOB L_y1 = L_shl_o( L_sum, HP20_COEFF_SCALE, &Overflow ); -#else - L_y1 = L_shl( L_sum, HP20_COEFF_SCALE ); -#endif BASOP_SATURATE_ERROR_OFF_EVS BASOP_SATURATE_WARNING_OFF_EVS -#ifdef BASOP_NOGLOB signal[stride] = round_fx_o( L_shl_o( L_y1, prescale, &Overflow ), &Overflow ); -#else /* BASOP_NOGLOB */ - signal[stride] = round_fx( L_shl( L_y1, prescale ) ); -#endif /* BASOP_NOGLOB */ BASOP_SATURATE_WARNING_ON_EVS move16(); @@ -167,19 +140,10 @@ static void filter_2nd_order( L_sum = L_add( L_sum, HP50_Mpy_32_32_fix( L_y2, a2 ) ); L_sum = L_add( L_sum, HP50_Mpy_32_32_fix( L_y1, a1 ) ); -#ifdef BASOP_NOGLOB L_y2 = L_shl_o( L_sum, HP20_COEFF_SCALE, &Overflow ); -#else - L_y2 = L_shl( L_sum, HP20_COEFF_SCALE ); -#endif BASOP_SATURATE_ERROR_OFF_EVS BASOP_SATURATE_WARNING_OFF_EVS -#ifdef BASOP_NOGLOB signal[i_mult( i, stride )] = round_fx_o( L_shl_o( L_y2, prescale, &Overflow ), &Overflow ); -#else /* BASOP_NOGLOB */ - signal[i_mult( i, stride )] = round_fx( L_shl( L_y2, prescale ) ); - move16(); -#endif /* BASOP_NOGLOB */ BASOP_SATURATE_WARNING_ON_EVS /* y[i+1] = b2*x[i-1] + b1*x[i-0] + b2*x[i+1] + a2*y[i-1] + a1*y[i+0]; */ BASOP_SATURATE_ERROR_ON_EVS @@ -190,18 +154,10 @@ static void filter_2nd_order( L_sum = L_add( L_sum, HP50_Mpy_32_32_fix( L_y1, a2 ) ); L_sum = L_add( L_sum, HP50_Mpy_32_32_fix( L_y2, a1 ) ); -#ifdef BASOP_NOGLOB L_y1 = L_shl_o( L_sum, HP20_COEFF_SCALE, &Overflow ); -#else - L_y1 = L_shl( L_sum, HP20_COEFF_SCALE ); -#endif BASOP_SATURATE_ERROR_OFF_EVS BASOP_SATURATE_WARNING_OFF_EVS -#ifdef BASOP_NOGLOB signal[i_mult( add( i, 1 ), stride )] = round_fx_o( L_shl_o( L_y1, prescale, &Overflow ), &Overflow ); -#else /* BASOP_NOGLOB */ - signal[i_mult( add( i, 1 ), stride )] = round_fx( L_shl( L_y1, prescale ) ); -#endif BASOP_SATURATE_WARNING_ON_EVS move16(); } @@ -241,20 +197,12 @@ void hp20( Word16 signal[], /* i/o: signal to filter any * prescale = getScaleFactor16( signal, lg ); prescaleOld = extract_l( mem[4] ); -#ifdef BASOP_NOGLOB diff = norm_l( L_shl_sat( mem[2], prescaleOld ) ); -#else - diff = norm_l( L_shl( mem[2], prescaleOld ) ); -#endif if ( mem[2] != 0 ) { prescale = s_min( prescale, diff ); } -#ifdef BASOP_NOGLOB diff = norm_l( L_shl_o( mem[3], prescaleOld, &Overflow ) ); -#else - diff = norm_l( L_shl( mem[3], prescaleOld ) ); -#endif if ( mem[3] != 0 ) { prescale = s_min( prescale, diff ); @@ -264,7 +212,6 @@ void hp20( Word16 signal[], /* i/o: signal to filter any * IF( prescale != prescaleOld ) { diff = sub( prescale, prescaleOld ); -#ifdef BASOP_NOGLOB mem[0] = L_shr_o( mem[0], diff, &Overflow ); move32(); mem[1] = L_shr_o( mem[1], diff, &Overflow ); @@ -273,16 +220,6 @@ void hp20( Word16 signal[], /* i/o: signal to filter any * move32(); mem[3] = L_shr_o( mem[3], diff, &Overflow ); move32(); -#else - mem[0] = L_shr( mem[0], diff ); - move32(); - mem[1] = L_shr( mem[1], diff ); - move32(); - mem[2] = L_shr( mem[2], diff ); - move32(); - mem[3] = L_shr( mem[3], diff ); - move32(); -#endif mem[4] = L_deposit_l( prescale ); } @@ -366,9 +303,7 @@ void hp20_fx_32( Word32 i; Word32 a1_fx, a2_fx, b1_fx, b2_fx; Word32 diff_pos, diff_neg; -#ifdef BASOP_NOGLOB Flag Overflow = 0; -#endif Word16 prescale, prescaleOld, prescale_current_frame, diff; prescale = getScaleFactor32( signal_fx, lg ); @@ -377,13 +312,8 @@ void hp20_fx_32( prescaleOld = extract_l( mem_fx[4] ); -#ifdef BASOP_NOGLOB diff_pos = norm_l( L_shl_o( L_max( mem_fx[2], mem_fx[3] ), prescaleOld, &Overflow ) ); diff_neg = norm_l( L_shl_o( L_min( mem_fx[2], mem_fx[3] ), prescaleOld, &Overflow ) ); -#else - diff_pos = norm_l( L_shl( L_max( mem_fx[2], mem_fx[3] ), prescaleOld ) ); - diff_neg = norm_l( L_shl( L_min( mem_fx[2], mem_fx[3] ), prescaleOld ) ); -#endif diff = L_max( diff_pos, diff_neg ); @@ -395,7 +325,6 @@ void hp20_fx_32( prescale = s_min( 3, sub( 1 + HP20_COEFF_SCALE, prescale ) ); diff = sub( prescale, prescaleOld ); -#ifdef BASOP_NOGLOB mem_fx[0] = L_shr_o( mem_fx[0], diff, &Overflow ); move32(); mem_fx[1] = L_shr_o( mem_fx[1], diff, &Overflow ); @@ -404,16 +333,6 @@ void hp20_fx_32( move32(); mem_fx[3] = L_shr_o( mem_fx[3], diff, &Overflow ); move32(); -#else - mem_fx[0] = L_shr( mem_fx[0], diff ); - move32(); - mem_fx[1] = L_shr( mem_fx[1], diff ); - move32(); - mem_fx[2] = L_shr( mem_fx[2], diff ); - move32(); - mem_fx[3] = L_shr( mem_fx[3], diff ); - move32(); -#endif mem_fx[4] = L_deposit_l( prescale_current_frame ); move32(); @@ -539,8 +458,14 @@ void hp20_fx_32( { Word16 i; Word32 a1_fx, a2_fx, b1_fx, b2_fx; +#ifdef OPT_STEREO_32KBPS_V1 + Word16 Qy1, Qy2, Qmin; + Word64 y0_fx64, y1_fx64, y2_fx64; + Word32 x0, x1, x2; +#else /* OPT_STEREO_32KBPS_V1 */ Word16 Qx0, Qx1, Qx2, Qy1, Qprev_y1, Qy2, Qprev_y2, Qmin; Word64 x0_fx64, x1_fx64, x2_fx64, y0_fx64, y1_fx64, y2_fx64, R1, R2, R3, R4, R5; +#endif /* OPT_STEREO_32KBPS_V1 */ IF( EQ_32( Fs, 8000 ) ) { @@ -591,15 +516,64 @@ void hp20_fx_32( move32(); move32(); +#ifdef OPT_STEREO_32KBPS_V1 + y1_fx64 = W_add( W_deposit32_l( mem_fx[0] ), W_deposit32_h( mem_fx[1] ) ); + y2_fx64 = W_add( W_deposit32_l( mem_fx[2] ), W_deposit32_h( mem_fx[3] ) ); + + x0 = mem_fx[4]; + move32(); + x1 = mem_fx[5]; + move32(); +#else /* OPT_STEREO_32KBPS_V1 */ Qprev_y1 = extract_l( mem_fx[4] ); Qprev_y2 = extract_l( mem_fx[5] ); y1_fx64 = W_deposit32_l( mem_fx[0] ); y2_fx64 = W_deposit32_l( mem_fx[1] ); x0_fx64 = W_deposit32_l( mem_fx[2] ); x1_fx64 = W_deposit32_l( mem_fx[3] ); +#endif /* OPT_STEREO_32KBPS_V1 */ FOR( i = 0; i < lg; i++ ) { +#ifdef OPT_STEREO_32KBPS_V1 + x2 = x1; + move32(); + x1 = x0; + move32(); + x0 = signal_fx[i]; + move32(); + + Qy1 = W_norm( y1_fx64 ); + if ( y1_fx64 == 0 ) + { + Qy1 = 62; + move16(); + } + + Qy2 = W_norm( y2_fx64 ); + if ( y2_fx64 == 0 ) + { + Qy2 = 62; + move16(); + } + + Qmin = s_min( Qy1, Qy2 ); + + Qmin = sub( Qmin, 34 ); + + y0_fx64 = W_mac_32_32( W_mult_32_32( W_shl_sat_l( y1_fx64, Qmin ), a1_fx ), W_shl_sat_l( y2_fx64, Qmin ), a2_fx ); // Qmin + Q29 + Q30 + 1 + + Word64 temp = W_mac_32_32( W_mac_32_32( W_mult_32_32( x2, b2_fx ), x1, b1_fx ), x0, b2_fx ); // Q30 + Word64 y0_fx = W_shr( y0_fx64, add( Qmin, Q30 ) ); // Q30 + y0_fx64 = W_add( temp, y0_fx ); // Q30 + signal_fx[i] = W_shl_sat_l( y0_fx64, -Q30 ); + move32(); + + y2_fx64 = y1_fx64; + move64(); + y1_fx64 = y0_fx64; + move64(); +#else /* OPT_STEREO_32KBPS_V1 */ x2_fx64 = x1_fx64; move64(); x1_fx64 = x0_fx64; @@ -681,8 +655,17 @@ void hp20_fx_32( move64(); move16(); move16(); +#endif /* OPT_STEREO_32KBPS_V1 */ } +#ifdef OPT_STEREO_32KBPS_V1 + mem_fx[0] = W_extract_l( y1_fx64 ); + mem_fx[1] = W_extract_h( y1_fx64 ); + mem_fx[2] = W_extract_l( y2_fx64 ); + mem_fx[3] = W_extract_h( y2_fx64 ); + mem_fx[4] = x0; + mem_fx[5] = x1; +#else /* OPT_STEREO_32KBPS_V1 */ Qy1 = W_norm( y1_fx64 ); test(); IF( y1_fx64 != 0 && LT_16( Qy1, 32 ) ) @@ -705,6 +688,8 @@ void hp20_fx_32( mem_fx[3] = W_extract_l( x1_fx64 ); mem_fx[4] = Qprev_y1; mem_fx[5] = Qprev_y2; +#endif /* OPT_STEREO_32KBPS_V1 */ + move32(); move32(); move32(); diff --git a/lib_com/hq2_bit_alloc_fx.c b/lib_com/hq2_bit_alloc_fx.c index 395854d5f678aa22df3ce3c5e1113ab17fa6bbda..61d00ce987958b6092975f5464c0108192b6ea7b 100644 --- a/lib_com/hq2_bit_alloc_fx.c +++ b/lib_com/hq2_bit_alloc_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other @@ -312,11 +312,9 @@ void hq2_bit_alloc_har_fx( Word16 exp_shift; -#ifdef BASOP_NOGLOB Flag Overflow; Overflow = 0; move32(); -#endif L_THR1 = L_shl( L_deposit_l( THR1 ), SWB_BWE_LR_QRk ); L_THR2 = L_shl( L_deposit_l( THR2 ), SWB_BWE_LR_QRk ); @@ -572,13 +570,9 @@ void hq2_bit_alloc_har_fx( L_temp = Mult_32_16( L_Ravg_sub[GRP_SB - 1], sub( GRP_SB, 1 ) ); /* Qbe+0+1 */ L_temp = Mult_32_16( L_temp, Inv_norm_sum_fx ); /* Qbe+1+QIpb+1 */ -#ifdef BASOP_NOGLOB lf_hf_ge_r_fx = round_fx_o( L_shl_o( L_temp, sub( 15 + 16, sub( add( SWB_BWE_LR_Qbe, QIns ), 30 ) ), &Overflow ), &Overflow ); Overflow = 0; /* reset BASOP Overflow */ move32(); -#else - lf_hf_ge_r_fx = round_fx( L_shl( L_temp, sub( 15 + 16, sub( add( SWB_BWE_LR_Qbe, QIns ), 30 ) ) ) ); -#endif exp_normn = norm_s( norm_sum_fx ); exp_normn = sub( exp_normn, 1 ); diff --git a/lib_com/hq2_core_com.c b/lib_com/hq2_core_com.c index a30655394a5efef3975152f8327db05f171ee71b..121dae06a1ef18c4cd878c09921758a9d0ced65e 100644 --- a/lib_com/hq2_core_com.c +++ b/lib_com/hq2_core_com.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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,7 +39,7 @@ #include #include "cnst.h" #include "rom_com.h" -#include "prot.h" +#include "prot_fx.h" #include "basop_util.h" #include "basop_proto_func.h" #include "wmc_auto.h" diff --git a/lib_com/hq2_core_com_fx.c b/lib_com/hq2_core_com_fx.c index a7c71ea9fd1722bec49321c65c6a5d1433740496..bf0af5e87d969e7f2f4a226b008982dc83a97ac9 100644 --- a/lib_com/hq2_core_com_fx.c +++ b/lib_com/hq2_core_com_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other @@ -163,11 +163,7 @@ void mdct_spectrum_denorm_fx( pd_fx = div_s( shl( npulses[k], exp_normn ), shl( band_width[k], exp_normd ) ); /* 15 + (exp_norm - exp_normd) */ Qpd = add( sub( exp_normn, exp_normd ), 15 ); -#ifdef BASOP_NOGLOB cond_fx = sub( shl_o( pd_fx, sub( 15, Qpd ), &Overflow ), pd_thresh_fx /*Q15*/ ); /* Q15 */ -#else /* BASOP_NOGLOB */ - cond_fx = sub( shl( pd_fx, sub( 15, Qpd ) ), pd_thresh_fx /*Q15*/ ); -#endif Overflow = 0; move16(); /* allow overflow happen. */ IF( cond_fx < 0 ) @@ -200,11 +196,7 @@ void mdct_spectrum_denorm_fx( /*gamma *= gain_tweak; */ L_tmp = L_mult( gamma_fx, gain_tweak_fx ); /* Qgamma+Qtweak+1 */ exp_norm = norm_l( L_tmp ); -#ifdef BASOP_NOGLOB gamma_fx = round_fx_o( L_shl_o( L_tmp, exp_norm, &Overflow ), &Overflow ); -#else - gamma_fx = round_fx( L_shl( L_tmp, exp_norm ) ); -#endif Qgamma = sub( add( add( Qgamma, Qtweak ), exp_norm ), 15 ); /*Qgamma+Qtweak+1+exp_norm-16; */ } @@ -343,11 +335,7 @@ void mdct_spectrum_denorm_ivas_fx( pd_fx = div_s( shl( npulses[k], exp_normn ), shl( band_width[k], exp_normd ) ); /* 15 + (exp_normn + exp_normd) */ Qpd = add( sub( exp_normn, exp_normd ), 15 ); -#ifdef BASOP_NOGLOB cond_fx = sub( shl_o( pd_fx, sub( 15, Qpd ), &Overflow ), pd_thresh_fx /*Q15*/ ); /* Q15 */ -#else /* BASOP_NOGLOB */ - cond_fx = sub( shl( pd_fx, sub( 15, Qpd ) ), pd_thresh_fx /*Q15*/ ); -#endif Overflow = 0; move16(); /* allow overflow happen. */ IF( cond_fx < 0 ) @@ -380,11 +368,7 @@ void mdct_spectrum_denorm_ivas_fx( /*gamma *= gain_tweak; */ L_tmp = L_mult( gamma_fx, gain_tweak_fx ); /* Qgamma+Qtweak+1 */ exp_norm = norm_l( L_tmp ); -#ifdef BASOP_NOGLOB gamma_fx = round_fx_o( L_shl_o( L_tmp, exp_norm, &Overflow ), &Overflow ); -#else - gamma_fx = round_fx( L_shl( L_tmp, exp_norm ) ); -#endif Qgamma = sub( add( add( Qgamma, Qtweak ), exp_norm ), 15 ); /*Qgamma+Qtweak+1+exp_norm-16; */ } diff --git a/lib_com/hq2_noise_inject_fx.c b/lib_com/hq2_noise_inject_fx.c index c37ae1236e3e30a092fe30396e3aaca1207e1986..bc96fe0f8fd62525c23e6b49845f01cdcd68d515 100644 --- a/lib_com/hq2_noise_inject_fx.c +++ b/lib_com/hq2_noise_inject_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other @@ -90,13 +90,8 @@ void hq2_noise_inject_fx( FOR( i = 0; i < bands; i++ ) { -#ifdef BASOP_NOGLOB Ep_fx[i] = L_shl_o( Ep_fx[i], 6, &Overflow ); /* Q-6 -> Q0 */ move32(); -#else /* BASOP_NOGLOB */ - Ep_fx[i] = L_shl( Ep_fx[i], 6 ); /* Q-6 -> Q0 */ - move32(); -#endif /* BASOP_NOGLOB */ } tmp = add( band_end[bands - 1], 1 ); @@ -160,11 +155,7 @@ void hq2_noise_inject_fx( Q_env_fx[k] = sub( 31, exp2 ); move16(); tmp = sub( 17, Q_env_fx[k] ); -#ifdef BASOP_NOGLOB env_fx2[k] = extract_h( L_shl_o( env_fx[k], tmp, &Overflow ) ); /*Q1 */ -#else /* BASOP_NOGLOB */ - env_fx2[k] = extract_h( L_shl( env_fx[k], tmp ) ); /*Q1 */ -#endif /* BASOP_NOGLOB */ peak_fx[k] = 0; move16(); count[k] = 0; @@ -175,11 +166,7 @@ void hq2_noise_inject_fx( FOR( i = band_start[k]; i <= band_end[k]; i++ ) { L_tmp = L_mult0( y2hat_fx[i], y2hat_fx[i] ); /* Q0 */ -#ifdef BASOP_NOGLOB Ep_fx[k] = L_sub_o( Ep_fx[k], L_tmp, &Overflow ); -#else /* BASOP_NOGLOB */ - Ep_fx[k] = L_sub( Ep_fx[k], L_tmp ); -#endif /* BASOP_NOGLOB */ move32(); /* Q0 */ IF( GT_16( abs_s( y2hat_fx[i] ), peak_fx[k] ) ) { @@ -399,12 +386,8 @@ void hq2_noise_inject_fx( } ELSE IF( count[k - 1] == 0 && tmp4 > 0 ) { - L_tmp = L_mult( env_fx2[k - 1], tmp ); /* Q(1+Q_speech+1 = Q_speech+2) */ -#ifdef BASOP_NOGLOB + L_tmp = L_mult( env_fx2[k - 1], tmp ); /* Q(1+Q_speech+1 = Q_speech+2) */ fac_fx = extract_h( L_shl_o( L_tmp, sub( 26, Q_speech ), &Overflow ) ); /*Q12 */ -#else - fac_fx = extract_h( L_shl( L_tmp, sub( 26, Q_speech ) ) ); /*Q12 */ -#endif } } @@ -453,11 +436,7 @@ void hq2_noise_inject_fx( tmp = sub( Q_env_fx[k], Q_Ep_fx[k] ); tmp = sub( tmp, Q_speech ); tmp = add( tmp, 25 ); -#ifdef BASOP_NOGLOB - L_tmp = L_shr_sat( L_tmp2, tmp ); /*Q7 */ -#else - L_tmp = L_shr( L_tmp2, tmp ); /*Q7 */ -#endif + L_tmp = L_shr_sat( L_tmp2, tmp ); /*Q7 */ tmp = extract_l( L_min( L_tmp, 192 /* 1.5 in Q7 */ ) ); /* */ fac_fx = extract_h( L_shl( L_mult( fac_fx, tmp ), 8 ) ); /*Q12 */ } @@ -467,11 +446,7 @@ void hq2_noise_inject_fx( L_tmp2 = Mult_32_16( env_fx[k], tmp ); /*Q(Q_env_fx[k]+0-15 = Q_env_fx[k]-15) */ L_tmp2 = Mult_32_16( L_tmp2, 20480 /* 1.25 in Q14 */ ); /*Q(Q_env_fx[k]-15+14-15 = Q_env_fx[k]-16) */ tmp = sub( Q_env_fx[k], 23 ); -#ifdef BASOP_NOGLOB - L_tmp = L_shr_sat( L_tmp2, tmp ); /*Q7 */ -#else - L_tmp = L_shr( L_tmp2, tmp ); /*Q7 */ -#endif + L_tmp = L_shr_sat( L_tmp2, tmp ); /*Q7 */ tmp = extract_l( ( L_min( L_tmp, 192 /* 1.5 in Q7 */ ) ) ); /* Q7 */ fac_fx = extract_h( L_shl( L_mult( fac_fx, tmp ), 8 ) ); /*Q12 */ } @@ -492,11 +467,7 @@ void hq2_noise_inject_fx( } L_tmp = Mult_32_16( Ep_fx[k], fac_fx ); /*Q(Q_Ep_fx[k]+12-15 = Q_Ep_fx[k]-3) */ -#ifdef BASOP_NOGLOB ni_gain_fx[k] = L_shr_o( L_tmp, sub( Q_Ep_fx[k], 20 ), &Overflow ); -#else /* BASOP_NOGLOB */ - ni_gain_fx[k] = L_shr( L_tmp, sub( Q_Ep_fx[k], 20 ) ); -#endif move32(); /*Q17 */ } ELSE @@ -618,22 +589,14 @@ void hq2_noise_inject_fx( L_tmp = Mult_32_16( Ep_fx[k], tmp ); /*Q(Q_Ep_fx[k]+28-Q_speech-15 = Q_Ep_fx[k]+13-Q_speech) */ tmp = sub( Q_Ep_fx[k], Q_speech ); tmp = sub( 15, tmp ); -#ifdef BASOP_NOGLOB tmp = extract_h( L_shl_o( L_tmp, tmp, &Overflow ) ); /*Q12 */ -#else - tmp = extract_h( L_shl( L_tmp, tmp ) ); /*Q12 */ -#endif } ELSE { tmp = 0x7fff; /*Q0 */ L_tmp = Mult_32_16( Ep_fx[k], tmp ); /*Q(Q_Ep_fx[k]+0-15 = Q_Ep_fx[k]-15) */ tmp = sub( 43, Q_Ep_fx[k] ); -#ifdef BASOP_NOGLOB tmp = extract_h( L_shl_o( L_tmp, tmp, &Overflow ) ); /*Q12 */ -#else - tmp = extract_h( L_shl( L_tmp, tmp ) ); /*Q12 */ -#endif } fac_fx = s_max( tmp, 4096 /* 1 in Q12 */ ); /*Q12 */ @@ -645,12 +608,8 @@ void hq2_noise_inject_fx( IF( band_width[k] != 0 ) { Q_speech = norm_s( band_width[k] ); -#ifdef BASOP_NOGLOB tmp = shl_o( band_width[k], Q_speech, &Overflow ); /*Q(Q_speech) */ -#else - tmp = shl( band_width[k], Q_speech ); /*Q(Q_speech) */ -#endif - tmp = div_s( 16384 /* 0.5 in Q15 */, tmp ); /*Q(15+14-Q_speech) */ + tmp = div_s( 16384 /* 0.5 in Q15 */, tmp ); /*Q(15+14-Q_speech) */ } ELSE { @@ -659,16 +618,12 @@ void hq2_noise_inject_fx( move16(); move16(); } - tmp1 = sub( fac_fx, 4096 /* 1 in Q12 */ ); /*Q12 */ - L_tmp = L_mult( tmp1, j ); /*Q13 */ - L_tmp = Mult_32_16( L_tmp, tmp ); /*Q(13+29-Q_speech-15 = 27-Q_speech) */ -#ifdef BASOP_NOGLOB + tmp1 = sub( fac_fx, 4096 /* 1 in Q12 */ ); /*Q12 */ + L_tmp = L_mult( tmp1, j ); /*Q13 */ + L_tmp = Mult_32_16( L_tmp, tmp ); /*Q(13+29-Q_speech-15 = 27-Q_speech) */ tmp = extract_h( L_shl_o( L_tmp, add( 1, Q_speech ), &Overflow ) ); /*Q12 */ -#else - tmp = extract_h( L_shl( L_tmp, add( 1, Q_speech ) ) ); /*Q12 */ -#endif - tmp = sub( fac_fx, tmp ); /*Q12 */ - L_tmp = Mult_32_16( ni_gain_fx[k], tmp ); /*Q(17+12-15=14) */ + tmp = sub( fac_fx, tmp ); /*Q12 */ + L_tmp = Mult_32_16( ni_gain_fx[k], tmp ); /*Q(17+12-15=14) */ L_y2[i] = L_add( L_y2[i], L_shr( Mult_32_16( L_tmp, rand_fx ), 2 ) ); move32(); /*Q12 */ } diff --git a/lib_com/hq_conf.c b/lib_com/hq_conf.c index 84b843fb49ed0868b71fa1b70d309a36dc7635f8..90a256ceab3e43b00c51885fe3e3ac35efea1113 100644 --- a/lib_com/hq_conf.c +++ b/lib_com/hq_conf.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other @@ -38,9 +38,8 @@ #include "options.h" #include "cnst.h" #include "rom_com.h" -#include "prot.h" -#include "wmc_auto.h" #include "prot_fx.h" +#include "wmc_auto.h" void hq_configure_fx( diff --git a/lib_com/hq_tools_fx.c b/lib_com/hq_tools_fx.c index 468bdd9a52c64a538da9e1909e78c475a657ec43..cf3ce202e0f0951c92b3610319cb5e7db95146b8 100644 --- a/lib_com/hq_tools_fx.c +++ b/lib_com/hq_tools_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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,7 +39,6 @@ #include "rom_com.h" /* Static table prototypes FIP version */ #include "stl.h" /* required for wmc_tool */ #include "prot_fx.h" -#include "prot.h" #include "ivas_prot_fx.h" /*--------------------------------------------------------------------------* @@ -84,12 +83,8 @@ void hq_swb_harmonic_calc_norm_envelop_fx( FOR( n_lag = 0; n_lag < n_lag_now; n_lag++ ) { - L_tmp = L_abs( L_SWB_signal[n_lag] ); /*Q12*/ -#ifdef BASOP_NOGLOB + L_tmp = L_abs( L_SWB_signal[n_lag] ); /*Q12*/ L_envelope[env_index] = L_add_sat( L_envelope[env_index], L_tmp ); /*Q12*/ -#else - L_envelope[env_index] = L_add( L_envelope[env_index], L_tmp ); -#endif move32(); } env_index = add( env_index, 1 ); @@ -105,12 +100,8 @@ void hq_swb_harmonic_calc_norm_envelop_fx( move16(); FOR( n_lag = 0; n_lag < n_lag_now; n_lag++ ) { - L_tmp = L_abs( L_SWB_signal[( n_freq + n_lag )] ); /*Q12*/ -#ifdef BASOP_NOGLOB + L_tmp = L_abs( L_SWB_signal[( n_freq + n_lag )] ); /*Q12*/ L_envelope[env_index] = L_add_sat( L_envelope[env_index], L_tmp ); /*Q12*/ -#else - L_envelope[env_index] = L_add( L_envelope[env_index], L_tmp ); -#endif move32(); } env_index = add( env_index, 1 ); @@ -127,12 +118,8 @@ void hq_swb_harmonic_calc_norm_envelop_fx( move32(); FOR( n_lag = 0; n_lag < n_lag_now; n_lag++ ) { - L_tmp = L_abs( L_SWB_signal[( n_freq + n_lag )] ); /*Q12*/ -#ifdef BASOP_NOGLOB + L_tmp = L_abs( L_SWB_signal[( n_freq + n_lag )] ); /*Q12*/ L_envelope[env_index] = L_add_sat( L_envelope[env_index], L_tmp ); /*Q12*/ -#else - L_envelope[env_index] = L_add( L_envelope[env_index], L_tmp ); -#endif move32(); } env_index = add( env_index, 1 ); @@ -560,11 +547,7 @@ void harm_bwe_fine_fx( norm_signal = norm_l( envelope[i] ); enve_lo[i] = L_Extract_lc( L_shl( envelope[i], norm_signal ), &enve_hi[i] ); /*Q12+norm_signal-16*/ L_signal[i] = Div_32( L_signal[i], enve_hi[i], enve_lo[i] ); /*Q31 - norm_signal*/ -#ifdef BASOP_NOGLOB - SWB_signal[i] = round_fx_sat( L_shl_sat( L_signal[i], norm_signal ) ); /*Q15*/ -#else - SWB_signal[i] = round_fx( L_shl( L_signal[i], norm_signal ) ); -#endif + SWB_signal[i] = round_fx_sat( L_shl_sat( L_signal[i], norm_signal ) ); /*Q15*/ move16(); move16(); move32(); @@ -574,11 +557,7 @@ void harm_bwe_fine_fx( norm_signal = norm_l( envelope[i] ); enve_lo[i] = L_Extract_lc( L_shl( envelope[i], norm_signal ), &enve_hi[i] ); /*Q12+norm_signal-16*/ L_signal[i] = L_negate( Div_32( L_negate( L_signal[i] ), enve_hi[i], enve_lo[i] ) ); /*Q31 - norm_signal*/ -#ifdef BASOP_NOGLOB - SWB_signal[i] = round_fx_sat( L_shl_sat( L_signal[i], norm_signal ) ); /*Q15*/ -#else - SWB_signal[i] = round_fx( L_shl( L_signal[i], norm_signal ) ); -#endif + SWB_signal[i] = round_fx_sat( L_shl_sat( L_signal[i], norm_signal ) ); /*Q15*/ move16(); move16(); move32(); @@ -659,11 +638,7 @@ void hvq_bwe_fine_fx( /*SWB_signal[i] = SWB_signal[i] / envelope[i]; */ shift = norm_l( L_envelope[i] ); -#ifdef BASOP_NOGLOB tmp = round_fx_sat( L_shl_sat( L_envelope[i], shift ) ); /* 12+s-16=Q(-4+s) */ -#else - tmp = round_fx( L_shl( L_envelope[i], shift ) ); /* 12+s-16=Q(-4+s) */ -#endif /* Avoid division by zero */ if ( tmp == 0 ) { @@ -962,34 +937,19 @@ void ivas_harm_bwe_fx( L_tmp2 = L_deposit_h( tmp1 ); L_tmp2 = Isqrt_lc( L_tmp2, &exp1 ); /*Q31 - exp1*/ -#ifdef BASOP_NOGLOB beta = round_fx_sat( L_shl_sat( L_tmp2, exp1 ) ); /*Q15 */ beta = shr( beta, 1 ); /*Q15*/ -#else - beta = round_fx( L_shl( L_tmp2, exp1 ) ); - beta = shr( beta, 1 ); /*Q15 */ -#endif FOR( sfm = sfm_start[i]; sfm < sfm_end[i]; sfm++ ) { - L_tmp = Mult_32_16( E_L, coeff_fine[sfm] ); /*Q19 19 + 15 +1-16 */ -#ifdef BASOP_NOGLOB - L_tmp = L_shl_sat( L_tmp, 9 ); /*Q28 */ -#else - L_tmp = L_shl( L_tmp, 9 ); /*Q28 */ -#endif - tmp = Random( bwe_seed ); /*Q15 */ - L_tmp2 = L_shr( L_mult( beta, tmp ), 3 ); /* Q28 31-3 15+15 +1-3 */ -#ifdef BASOP_NOGLOB + L_tmp = Mult_32_16( E_L, coeff_fine[sfm] ); /*Q19 19 + 15 +1-16 */ + L_tmp = L_shl_sat( L_tmp, 9 ); /*Q28 */ + tmp = Random( bwe_seed ); /*Q15 */ + L_tmp2 = L_shr( L_mult( beta, tmp ), 3 ); /* Q28 31-3 15+15 +1-3 */ L_tmp = L_add_sat( L_tmp, L_tmp2 ); /*Q28 */ coeff_out[sfm] = L_shl_sat( Mult_32_32( L_tmp, normq ), 1 ); /*Q12 28 +14 +1 -31 */ move32(); -#else - L_tmp = L_add( L_tmp, L_tmp2 ); /*Q28 */ - coeff_out[sfm] = L_shl( Mult_32_32( L_tmp, normq ), 1 ); /*Q12 28 +14 +1 -31 */ - move32(); -#endif } } @@ -1152,23 +1112,13 @@ void harm_bwe_fx( FOR( sfm = sfm_start[i]; sfm < sfm_end[i]; sfm++ ) { - L_tmp = Mult_32_16( E_L, coeff_fine[sfm] ); /*Q19 19 + 15 +1-16 */ -#ifdef BASOP_NOGLOB - L_tmp = L_shl_sat( L_tmp, 9 ); /*Q28 */ -#else - L_tmp = L_shl( L_tmp, 9 ); /*Q28 */ -#endif - tmp = Random( bwe_seed ); /*Q15 */ - L_tmp2 = L_shr( L_mult( beta, tmp ), 3 ); /* Q28 31-3 15+15 +1-3 */ -#ifdef BASOP_NOGLOB + L_tmp = Mult_32_16( E_L, coeff_fine[sfm] ); /*Q19 19 + 15 +1-16 */ + L_tmp = L_shl_sat( L_tmp, 9 ); /*Q28 */ + tmp = Random( bwe_seed ); /*Q15 */ + L_tmp2 = L_shr( L_mult( beta, tmp ), 3 ); /* Q28 31-3 15+15 +1-3 */ L_tmp = L_add_sat( L_tmp, L_tmp2 ); /*Q28 */ coeff_out[sfm] = L_shl_sat( Mult_32_32( L_tmp, normq ), 1 ); /*Q12 28 +14 +1 -31 */ move32(); -#else - L_tmp = L_add( L_tmp, L_tmp2 ); /*Q28 */ - coeff_out[sfm] = L_shl( Mult_32_32( L_tmp, normq ), 1 ); /*Q12 28 +14 +1 -31 */ - move32(); -#endif } } @@ -2151,6 +2101,36 @@ void hq_bwe_fx( return; } +void hq_bwe_ivas_fx( + const Word16 HQ_mode, /* i : HQ mode Q0*/ + Word32 *coeff_out1, /* i/o: BWE input & temporary buffer Q12*/ + const Word16 *hq_generic_fenv, /* i : SWB frequency envelopes Q1*/ + Word32 *coeff_out, /* o : SWB signal in MDCT domain Q12*/ + const Word16 hq_generic_offset, /* i : frequency offset for representing hq generic Q0*/ + Word16 *prev_L_swb_norm, /* i/o: last normalize length Q0*/ + const Word16 hq_generic_exc_clas, /* i : hq generic hf excitation class Q0*/ + const Word16 *sfm_end, /* i : End of bands Q0*/ + const Word16 num_sfm, /* i : Number of bands Q0*/ + const Word16 num_env_bands, /* i : Number of coded envelope bands Q0*/ + const Word16 *R /* i : Bit allocation Q0*/ +) +{ + Word16 n_swb_overlap_offset, n_swb_overlap; + Word32 hq_swb_overlap_buf_fx[L_FRAME32k]; + + n_swb_overlap_offset = add( swb_bwe_subband[0], hq_generic_offset ); + n_swb_overlap = sub( sfm_end[( num_env_bands - 1 )], n_swb_overlap_offset ); /*Q0*/ + + + Copy32( &coeff_out[n_swb_overlap_offset], hq_swb_overlap_buf_fx, sub( add( n_swb_overlap, sfm_end[( num_sfm - 1 )] ), sfm_end[( num_env_bands - 1 )] ) ); /*Q12*/ + + hq_generic_decoding_ivas_fx( HQ_mode, coeff_out1, hq_generic_fenv, coeff_out, hq_generic_offset, prev_L_swb_norm, hq_generic_exc_clas, R ); + + overlap_hq_bwe_fx( hq_swb_overlap_buf_fx, coeff_out, n_swb_overlap_offset, n_swb_overlap, R, num_env_bands, num_sfm, sfm_end ); + + return; +} + /*--------------------------------------------------------------------------* * hq_wb_nf_bwe() * @@ -2216,14 +2196,10 @@ void hq_wb_nf_bwe_fx( IF( GT_16( last_sfm, 8 ) && total_bit > 0 ) { exp = norm_s( total_bit ); - tmp = shl( total_bit, exp ); /*Q(exp) */ - tmp = div_s( 16384, tmp ); /*Q(15+14-exp) */ - L_tmp = L_mult( tmp, bitalloc_var_fx ); /*Q(29-exp+1) */ -#ifdef BASOP_NOGLOB + tmp = shl( total_bit, exp ); /*Q(exp) */ + tmp = div_s( 16384, tmp ); /*Q(15+14-exp) */ + L_tmp = L_mult( tmp, bitalloc_var_fx ); /*Q(29-exp+1) */ bitalloc_var_fx = round_fx_sat( L_shl_sat( L_tmp, exp ) ); /*Q14 */ -#else - bitalloc_var_fx = round_fx( L_shl( L_tmp, exp ) ); /*Q14 */ -#endif } ELSE { @@ -2239,11 +2215,7 @@ void hq_wb_nf_bwe_fx( { tmp = shl( sfmsize[sfm], 9 ); /*Q9 */ tmp = mult( rat_fx[sfm], tmp ); /*Q(14+9-15=8) */ -#ifdef BASOP_NOGLOB IF( GE_16( shl_sat( R[sfm], 8 ), tmp ) ) -#else - IF( GE_16( shl( R[sfm], 8 ), tmp ) ) -#endif { peak_fx = 0; move16(); @@ -2251,12 +2223,8 @@ void hq_wb_nf_bwe_fx( move16(); FOR( i = sfm_start[sfm]; i < sfm_end[sfm]; i++ ) { - fabs_coeff_out_fx = L_abs( L_coeff_out[i] ); /*Q12*/ -#ifdef BASOP_NOGLOB + fabs_coeff_out_fx = L_abs( L_coeff_out[i] ); /*Q12*/ mean_fx = L_add_sat( mean_fx, fabs_coeff_out_fx ); /*Q12 */ -#else - mean_fx = L_add( mean_fx, fabs_coeff_out_fx ); /*Q12 */ -#endif if ( GT_32( fabs_coeff_out_fx, peak_fx ) ) { peak_fx = fabs_coeff_out_fx; /*Q12 */ @@ -2267,13 +2235,8 @@ void hq_wb_nf_bwe_fx( IF( mean_fx != 0 ) { exp = norm_l( mean_fx ); -#ifdef BASOP_NOGLOB - mean_fx = L_shl_sat( mean_fx, exp ); /*Q(exp+12) */ - tmp = round_fx_sat( mean_fx ); /*Q(exp-4) */ -#else - mean_fx = L_shl( mean_fx, exp ); /*Q(exp+12) */ - tmp = round_fx( mean_fx ); /*Q(exp-4) */ -#endif + mean_fx = L_shl_sat( mean_fx, exp ); /*Q(exp+12) */ + tmp = round_fx_sat( mean_fx ); /*Q(exp-4) */ tmp = div_s( 16384, tmp ); /*Q(15+14-exp+4 = 33-exp) */ L_tmp = Mult_32_16( peak_fx, tmp ); /*Q(12+33-exp-15 = 30-exp) */ tmp = shl( sfmsize[sfm], 9 ); /*Q9 */ @@ -2312,14 +2275,10 @@ void hq_wb_nf_bwe_fx( tmp = div_s( 1, last_sfm ); /*Q15 */ } - L_tmp = L_mult( 5, sharp_fx ); /*Q15 */ - L_tmp = Mult_32_16( L_tmp, tmp ); /*Q15 */ -#ifdef BASOP_NOGLOB + L_tmp = L_mult( 5, sharp_fx ); /*Q15 */ + L_tmp = Mult_32_16( L_tmp, tmp ); /*Q15 */ step_fx = round_fx_sat( L_shl_sat( L_tmp, 16 ) ); /*Q15 */ -#else - step_fx = round_fx( L_shl( L_tmp, 16 ) ); /*Q15 */ -#endif - alfa_fx = 20480; /*Q13 = 2.5 */ + alfa_fx = 20480; /*Q13 = 2.5 */ move16(); /* fill noise for the insaturable subbands */ FOR( sfm = 0; sfm < num_sfm; sfm++ ) @@ -2455,18 +2414,10 @@ void hq_wb_nf_bwe_fx( exp = sub( 45, exp ); } -#ifdef BASOP_NOGLOB sharp_fx = add_sat( sharp_fx, shr( step_fx, 1 ) ); /*Q14*/ -#else - sharp_fx = add( sharp_fx, shr( step_fx, 1 ) ); -#endif } -#ifdef BASOP_NOGLOB IF( GT_32( L_tmp2, L_shl_sat( min_coef_fx, sub( exp, 13 ) ) ) ) /*exp */ -#else - IF( GT_32( L_tmp2, L_shl( min_coef_fx, sub( exp, 13 ) ) ) ) /*exp */ -#endif { L_tmp2 = L_shr( min_coef_fx, 1 ); exp = 12; @@ -2483,11 +2434,7 @@ void hq_wb_nf_bwe_fx( /* smooth the noise magnitudes between inter-frame */ test(); test(); -#ifdef BASOP_NOGLOB IF( GT_32( prev_avrg_norm_fx, L_shr( avrg_norm_fx, 1 ) ) && LT_32( prev_avrg_norm_fx, L_shl_sat( avrg_norm_fx, 1 ) ) && prev_is_transient == 0 ) -#else - IF( GT_32( prev_avrg_norm_fx, L_shr( avrg_norm_fx, 1 ) ) && LT_32( prev_avrg_norm_fx, L_shl( avrg_norm_fx, 1 ) ) && prev_is_transient == 0 ) -#endif { exp1 = norm_l( prev_env_fx[sfm] ); L_tmp1 = L_shl( prev_env_fx[sfm], exp1 ); /* prev_env_Q[sfm] +exp1 */ @@ -2545,11 +2492,7 @@ void hq_wb_nf_bwe_fx( test(); test(); test(); -#ifdef BASOP_NOGLOB IF( EQ_16( sfm, sub( SFM_N_WB, 1 ) ) && prev_is_transient == 0 && GT_32( prev_normq_fx[sfm], L_shr( L_normq_v[sfm], 1 ) ) && LT_32( prev_normq_fx[sfm], L_shl_sat( L_normq_v[sfm], 1 ) ) && LE_16( bitalloc_var_fx, 4915 ) ) -#else - IF( EQ_16( sfm, sub( SFM_N_WB, 1 ) ) && prev_is_transient == 0 && GT_32( prev_normq_fx[sfm], L_shr( L_normq_v[sfm], 1 ) ) && LT_32( prev_normq_fx[sfm], L_shl( L_normq_v[sfm], 1 ) ) && LE_16( bitalloc_var_fx, 4915 ) ) -#endif { Word32 *p_prev_coeff_out = prev_coeff_out_fx; /*Q12*/ FOR( i = add( sfm_start[sfm], 12 ); i < sfm_end[sfm]; i++ ) @@ -2558,17 +2501,9 @@ void hq_wb_nf_bwe_fx( test(); test(); test(); -#ifdef BASOP_NOGLOB IF( GT_32( L_abs( L_coeff_out[i] ), L_shl_sat( L_abs( *p_prev_coeff_out ), 2 ) ) || LT_32( L_abs( L_coeff_out[i] ), L_shr( L_abs( *p_prev_coeff_out ), 2 ) ) || ( ( R[sfm] == 0 || *prev_R == 0 ) && add_sat( R[sfm], *prev_R ) != 0 ) ) -#else - IF( GT_32( L_abs( L_coeff_out[i] ), L_shl( L_abs( *p_prev_coeff_out ), 2 ) ) || LT_32( L_abs( L_coeff_out[i] ), L_shr( L_abs( *p_prev_coeff_out ), 2 ) ) || ( ( R[sfm] == 0 || *prev_R == 0 ) && add( R[sfm], *prev_R ) != 0 ) ) -#endif { -#ifdef BASOP_NOGLOB L_tmp = L_add_sat( L_shr( L_abs( L_coeff_out[i] ), 1 ), L_shr( L_abs( *p_prev_coeff_out ), 1 ) ); /*Q12*/ -#else - L_tmp = L_add( L_shr( L_abs( L_coeff_out[i] ), 1 ), L_shr( L_abs( *p_prev_coeff_out ), 1 ) ); -#endif if ( L_coeff_out[i] <= 0 ) { L_tmp = L_negate( L_tmp ); /*Q12*/ diff --git a/lib_com/ifft_rel.c b/lib_com/ifft_rel.c index 40383cf3c0e76a55f6772d507367959c2c033138..9e64a4e254f17bd36d456d3d45bf35d36612720d 100644 --- a/lib_com/ifft_rel.c +++ b/lib_com/ifft_rel.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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,10 +36,9 @@ #include #include "options.h" -#include "prot.h" +#include "prot_fx.h" #include "rom_com.h" #include "wmc_auto.h" -#include "prot_fx.h" /*-----------------------------------------------------------------* * Local constants *-----------------------------------------------------------------*/ @@ -109,66 +108,28 @@ void ifft_rel_fx( FOR( i = is; i < n; i += id ) { -#ifdef BASOP_NOGLOB t1 = sub_o( *xi1, *xi3, &Overflow ); /*Qx*/ *xi1 = add_o( *xi1, *xi3, &Overflow ); /*Qx*/ -#else /* BASOP_NOGLOB */ - t1 = sub( *xi1, *xi3 ); - *xi1 = add( *xi1, *xi3 ); -#endif /* BASOP_NOGLOB */ move16(); -#ifdef BASOP_NOGLOB *xi2 = shl_o( *xi2, 1, &Overflow ); /*Qx*/ -#else /* BASOP_NOGLOB */ - *xi2 = shl( *xi2, 1 ); -#endif /* BASOP_NOGLOB */ move16(); -#ifdef BASOP_NOGLOB *xi3 = sub_o( t1, shl_o( *xi4, 1, &Overflow ), &Overflow ); /*Qx*/ -#else /* BASOP_NOGLOB */ - *xi3 = sub( t1, shl( *xi4, 1 ) ); -#endif /* BASOP_NOGLOB */ move16(); -#ifdef BASOP_NOGLOB *xi4 = add_o( t1, shl_o( *xi4, 1, &Overflow ), &Overflow ); /*Qx*/ -#else /* BASOP_NOGLOB */ - *xi4 = add( t1, shl( *xi4, 1 ) ); -#endif /* BASOP_NOGLOB */ move16(); IF( NE_16( n4, 1 ) ) { -#ifdef BASOP_NOGLOB t1 = mult_r( sub_o( *( xi2 + n8 ), *( xi1 + n8 ), &Overflow ), INV_SQR2_FX /*Q15*/ ); /*Qx*/ t2 = mult_r( add_o( *( xi4 + n8 ), *( xi3 + n8 ), &Overflow ), INV_SQR2_FX /*Q15*/ ); /*Qx*/ -#else /* BASOP_NOGLOB */ - t1 = mult_r( sub( *( xi2 + n8 ), *( xi1 + n8 ) ), INV_SQR2_FX ); - t2 = mult_r( add( *( xi4 + n8 ), *( xi3 + n8 ) ), INV_SQR2_FX ); -#endif /* BASOP_NOGLOB */ -#ifdef BASOP_NOGLOB *( xi1 + n8 ) = add_o( *( xi1 + n8 ), *( xi2 + n8 ), &Overflow ); /*Qx*/ -#else /* BASOP_NOGLOB */ - *( xi1 + n8 ) = add( *( xi1 + n8 ), *( xi2 + n8 ) ); -#endif /* BASOP_NOGLOB */ move16(); -#ifdef BASOP_NOGLOB *( xi2 + n8 ) = sub_o( *( xi4 + n8 ), *( xi3 + n8 ), &Overflow ); /*Qx*/ -#else /* BASOP_NOGLOB */ - *( xi2 + n8 ) = sub( *( xi4 + n8 ), *( xi3 + n8 ) ); -#endif /* BASOP_NOGLOB */ move16(); -#ifdef BASOP_NOGLOB *( xi3 + n8 ) = negate( shl_o( add_o( t2, t1, &Overflow ), 1, &Overflow ) ); /*Qx*/ -#else /* BASOP_NOGLOB */ - *( xi3 + n8 ) = negate( shl( add( t2, t1 ), 1 ) ); -#endif /* BASOP_NOGLOB */ move16(); -#ifdef BASOP_NOGLOB *( xi4 + n8 ) = shl_o( sub_o( t1, t2, &Overflow ), 1, &Overflow ); /*Qx*/ -#else /* BASOP_NOGLOB */ - *( xi4 + n8 ) = shl( sub( t1, t2 ), 1 ); -#endif /* BASOP_NOGLOB */ move16(); } xi1 += id; @@ -217,82 +178,42 @@ void ifft_rel_fx( FOR( i = is; i < n; i += id ) { -#ifdef BASOP_NOGLOB t1 = sub_o( *xup1, *xdn6, &Overflow ); /*Qx*/ *xup1 = add_o( *xup1, *xdn6, &Overflow ); /*Qx*/ -#else /* BASOP_NOGLOB */ - t1 = sub( *xup1, *xdn6 ); - *xup1 = add( *xup1, *xdn6 ); -#endif /* BASOP_NOGLOB */ move16(); xup1 += n4; xdn6 -= n4; -#ifdef BASOP_NOGLOB t2 = sub_o( *xdn6, *xup1, &Overflow ); /*Qx*/ *xdn6 = add_o( *xup1, *xdn6, &Overflow ); /*Qx*/ -#else /* BASOP_NOGLOB */ - t2 = sub( *xdn6, *xup1 ); - *xdn6 = add( *xup1, *xdn6 ); -#endif /* BASOP_NOGLOB */ move16(); xdn6 += n4; -#ifdef BASOP_NOGLOB t3 = add_o( *xdn8, *xup3, &Overflow ); /*Qx*/ *xdn6 = sub_o( *xdn8, *xup3, &Overflow ); /*Qx*/ -#else /* BASOP_NOGLOB */ - t3 = add( *xdn8, *xup3 ); - *xdn6 = sub( *xdn8, *xup3 ); -#endif /* BASOP_NOGLOB */ move16(); xup3 += n4; xdn8 -= n4; -#ifdef BASOP_NOGLOB t4 = add_o( *xup3, *xdn8, &Overflow ); /*Qx*/ *xup1 = sub_o( *xup3, *xdn8, &Overflow ); /*Qx*/ -#else /* BASOP_NOGLOB */ - t4 = add( *xup3, *xdn8 ); - *xup1 = sub( *xup3, *xdn8 ); -#endif /* BASOP_NOGLOB */ move16(); -#ifdef BASOP_NOGLOB t5 = sub_o( t1, t4, &Overflow ); /*Qx*/ t1 = add_o( t1, t4, &Overflow ); /*Qx*/ t4 = sub_o( t2, t3, &Overflow ); /*Qx*/ t2 = add_o( t2, t3, &Overflow ); /*Qx*/ *xup3 = sub_o( mult_r( t1, cc3 ), mult_r( t2, ss3 ), &Overflow ); /*Qx*/ -#else /* BASOP_NOGLOB */ - t5 = sub( t1, t4 ); - t1 = add( t1, t4 ); - t4 = sub( t2, t3 ); - t2 = add( t2, t3 ); - *xup3 = sub( mult_r( t1, cc3 ), mult_r( t2, ss3 ) ); -#endif /* BASOP_NOGLOB */ move16(); xup3 -= n4; -#ifdef BASOP_NOGLOB *xup3 = add_o( mult_r( t5, cc1 ), mult_r( t4, ss1 ), &Overflow ); /*Qx*/ -#else /* BASOP_NOGLOB */ - *xup3 = add( mult_r( t5, cc1 ), mult_r( t4, ss1 ) ); -#endif /* BASOP_NOGLOB */ move16(); -#ifdef BASOP_NOGLOB *xdn8 = sub_o( mult_r( t5, ss1 ), mult_r( t4, cc1 ), &Overflow ); /*Qx*/ -#else /* BASOP_NOGLOB */ - *xdn8 = sub( mult_r( t5, ss1 ), mult_r( t4, cc1 ) ); -#endif /* BASOP_NOGLOB */ move16(); xdn8 += n4; -#ifdef BASOP_NOGLOB *xdn8 = add_o( mult_r( t2, cc3 ), mult_r( t1, ss3 ), &Overflow ); /*Qx*/ -#else /* BASOP_NOGLOB */ - *xdn8 = add( mult_r( t2, cc3 ), mult_r( t1, ss3 ) ); -#endif /* BASOP_NOGLOB */ move16(); xup1 -= n4; @@ -324,17 +245,9 @@ void ifft_rel_fx( { r1 = *xi0; move16(); -#ifdef BASOP_NOGLOB *xi0 = add_o( r1, *xi1, &Overflow ); /*Qx*/ -#else /* BASOP_NOGLOB */ - *xi0 = add( r1, *xi1 ); -#endif /* BASOP_NOGLOB */ move16(); -#ifdef BASOP_NOGLOB *xi1 = sub_o( r1, *xi1, &Overflow ); /*Qx*/ -#else /* BASOP_NOGLOB */ - *xi1 = sub( r1, *xi1 ); -#endif move16(); xi0 += id; xi1 += id; diff --git a/lib_com/igf_base_fx.c b/lib_com/igf_base_fx.c index 5670088d3caef37e94378d5bd21ee60bdf243362..fbccdb5191fe889c5aab51fa4dd2bc4c9a07c6ed 100644 --- a/lib_com/igf_base_fx.c +++ b/lib_com/igf_base_fx.c @@ -1142,19 +1142,11 @@ void IGFCommonFuncsCalcSfbEnergyPowerSpec( const Word16 startSfb, /**< in { Carry = 0; move16(); -#ifdef BASOP_NOGLOB sfbEnergy[sfb] = L_add_co( sfbEnergy[sfb], pPowerSpectrum[line], &Carry, &Overflow ); -#else /* BASOP_NOGLOB */ - sfbEnergy[sfb] = L_add_c( sfbEnergy[sfb], pPowerSpectrum[line] ); -#endif /* BASOP_NOGLOB */ move32(); Overflow = 0; move16(); -#ifdef BASOP_NOGLOB L_c = L_macNs_co( L_c, 0, 0, &Carry, &Overflow ); -#else /* BASOP_NOGLOB */ - L_c = L_macNs( L_c, 0, 0 ); -#endif } sfbEnergy[sfb] = norm_llQ31( L_c, sfbEnergy[sfb], &( sfbEnergy_exp[sfb] ) ); move32(); @@ -1194,12 +1186,8 @@ void IGFCommonFuncsMDCTSquareSpec( const Word16 sqrtBgn, /**< in FOR( i = sqrtBgn; i < sqrtEnd; i++ ) { -#ifdef BASOP_NOGLOB tmp = round_fx_sat( L_shl_sat( mdctSpec[i], s1 ) ); /*(15 - mdctSpec_e)+ S1*/ -#else - tmp = round_fx( L_shl( mdctSpec[i], s1 ) ); -#endif - mdctSquareSpec[j++] = L_mult0( tmp, tmp ); /*31 - mdctSquareSpec_e*/ + mdctSquareSpec[j++] = L_mult0( tmp, tmp ); /*31 - mdctSquareSpec_e*/ move32(); } } diff --git a/lib_com/int_lsp.c b/lib_com/int_lsp.c index 37ca1ca4b350f7e21a4efafd2f5656db498c3d45..570e9ebd987527155d240e94341b7224aa876224 100644 --- a/lib_com/int_lsp.c +++ b/lib_com/int_lsp.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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,10 +37,9 @@ #include #include "options.h" #include "cnst.h" -#include "prot.h" +#include "prot_fx.h" #include "rom_com.h" #include "wmc_auto.h" -#include "prot_fx.h" void int_lsp_fx( diff --git a/lib_com/interleave_spectrum.c b/lib_com/interleave_spectrum.c index f65b7a5c5d6087ed678c97ad02906fe38a7c32a1..5c4c98e291e33db70a7fa6a8763926f963fe485c 100644 --- a/lib_com/interleave_spectrum.c +++ b/lib_com/interleave_spectrum.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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,10 +37,9 @@ #include #include "options.h" #include "cnst.h" -#include "prot.h" +#include "prot_fx.h" #include "rom_com.h" #include "wmc_auto.h" -#include "prot_fx.h" #include "ivas_prot_fx.h" diff --git a/lib_com/interpol.c b/lib_com/interpol.c index 7d74298b1be318e8fec8ef462195714d11760a76..a490a755269c9fa7d3f9bdeb440b60bf7f483253 100644 --- a/lib_com/interpol.c +++ b/lib_com/interpol.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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,10 +36,9 @@ #include #include "options.h" -#include "prot.h" +#include "prot_fx.h" #include "wmc_auto.h" #include "rom_com.h" -#include "prot_fx.h" #include "prot_fx_enc.h" @@ -73,11 +72,7 @@ Word32 Interpol_lc_fx( /* o : interpolated value } L_sum = W_sat_l( L_sum64 ); /*Q14*/ } -#ifdef BASOP_NOGLOB L_sum = L_shl_sat( L_sum, 1 ); /*Q15*/ -#else - L_sum = L_shl( L_sum, 1 ); -#endif return L_sum; } @@ -108,15 +103,7 @@ Word16 Interpol_4( /* Qx o : interpolated value */ } BASOP_SATURATE_WARNING_OFF_EVS /* Here, saturation might occur by intention */ -#ifdef BASOP_NOGLOB L_sum = L_shl_o( L_sum, 1, &Overflow ); /*Qx+14+2*/ -#else /* BASOP_NOGLOB */ - L_sum = L_shl( L_sum, 1 ); -#endif /* BASOP_NOGLOB */ BASOP_SATURATE_WARNING_ON_EVS -#ifdef BASOP_NOGLOB return round_fx_o( L_sum, &Overflow ); /*Qx*/ -#else /* BASOP_NOGLOB */ - return round_fx( L_sum ); -#endif } diff --git a/lib_com/isf_dec_amr_wb_fx.c b/lib_com/isf_dec_amr_wb_fx.c index 3b98b13461ba94bfdad3e96cfd68b23943a9256e..5ab82ee6dc158e877fd24f908e16cd20545f4f5c 100644 --- a/lib_com/isf_dec_amr_wb_fx.c +++ b/lib_com/isf_dec_amr_wb_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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_com/ivas_agc_com_fx.c b/lib_com/ivas_agc_com_fx.c index 9159fa2599af27a55ca80dbf6a6df75a08d1a08a..3f6e181efb2154cf8fc2ce949321b0959c1dab90 100644 --- a/lib_com/ivas_agc_com_fx.c +++ b/lib_com/ivas_agc_com_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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,11 +34,10 @@ #include "options.h" #include "cnst.h" #include "ivas_cnst.h" -#include "ivas_prot.h" #include "ivas_prot_fx.h" #include #include "wmc_auto.h" -#include "prot.h" +#include "prot_fx.h" #include "rom_com.h" /*------------------------------------------------------------------------------------------* * Local constants diff --git a/lib_com/ivas_arith.c b/lib_com/ivas_arith_fx.c similarity index 98% rename from lib_com/ivas_arith.c rename to lib_com/ivas_arith_fx.c index 56f4c599c141fa375fb253d17ea60e927fe6d75f..311bccff8e206cbdb862bba20cd4f6e89d62ecc2 100644 --- a/lib_com/ivas_arith.c +++ b/lib_com/ivas_arith_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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,8 +33,6 @@ #include #include "options.h" #include "wmc_auto.h" -#include "prot.h" -#include "ivas_prot.h" #include "prot_fx.h" #include "ivas_prot_fx.h" #include "stat_dec.h" diff --git a/lib_com/ivas_avq_pos_reorder_com.c b/lib_com/ivas_avq_pos_reorder_com_fx.c similarity index 97% rename from lib_com/ivas_avq_pos_reorder_com.c rename to lib_com/ivas_avq_pos_reorder_com_fx.c index cd50e9ab230e93625ae18dfe1a2b6ea8b3d4debd..25f8be3ad2ae64b4b05bc88bfc19b22043377621 100644 --- a/lib_com/ivas_avq_pos_reorder_com.c +++ b/lib_com/ivas_avq_pos_reorder_com_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other @@ -32,7 +32,7 @@ #include #include "options.h" -#include "prot.h" +#include "prot_fx.h" #include "wmc_auto.h" /*-----------------------------------------------------------------* diff --git a/lib_com/ivas_cnst.h b/lib_com/ivas_cnst.h index 1cc4f2a8e5411270f718867305ad9cf01da3002d..2abb790f1629a172b0dc5b3e82ac1e5fb82ce6ed 100644 --- a/lib_com/ivas_cnst.h +++ b/lib_com/ivas_cnst.h @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other @@ -53,7 +53,7 @@ #define PI_OVER_180_Q25 ( 585635 ) // Q25 #define _180_IN_Q22 ( 754974720 ) // Q22 #define _360_IN_Q22 ( 1509949440 ) // Q22 -#define _180_OVER_PI_FX ( (Word32) ( ( 180.0f / EVS_PI ) * ONE_IN_Q10 ) ) +#define _180_OVER_PI_FX ( 58670 ) // Q10 #define PI_OVER_180_Q15 ( 572 ) // Q15 #define _180_OVER_PI_Q9 ( 29335 ) // Q9 #define PI_OVER_4_Q29 ( 421657440 ) // Q29 @@ -61,7 +61,7 @@ #define PI_OVER_Q29 ( 1686629760 ) // Q29 #define Q31_0_99 ( 2126008811 ) // Q31 #define Q31_0_01 ( 21474836 ) // Q31 -#define PI_OVER_180_FX ( (Word32) ( ( EVS_PI / 180.0f ) * ONE_IN_Q31 ) ) // Q31 +#define PI_OVER_180_FX ( 37480660 ) // Q31 #define PI_OVER_4_Q29 ( 421657440 ) // Q29 #define PI_OVER_Q29 ( 1686629760 ) // Q29 #define PI2_C_ADP_RATE_Q31 ( 449767936 ) // Q31 (2.0f * EVS_PI * pOTR->centerAdaptationRate) @@ -150,6 +150,7 @@ typedef enum RENDERER_OSBA_LS } RENDERER_TYPE; +#define MAX_FREQUENCY_BANDS 64 /*----------------------------------------------------------------------------------* * IVAS general constants @@ -765,6 +766,7 @@ enum #define UNCLR_L_ETOT 3 #define UNCLR_L_RELE 10 +#define ONE_BY_UNCLR_L_RELE_Q31 214748365 #define UNCLR_RC_ORDER 20 #define MAX_UV_CNT 100 @@ -1438,12 +1440,12 @@ typedef enum _COV_SMOOTHING_TYPE } COV_SMOOTHING_TYPE; typedef struct { - const int32_t *value; - const uint16_t *length; + const Word32 *value; + const UWord16 *length; } HUFF_TAB; typedef struct { - int32_t value[81]; + Word32 value[81]; unsigned short length[81]; } HUFF_ELEMENTS; @@ -1465,8 +1467,8 @@ typedef struct { typedef struct { - const int16_t (*alpha)[2]; - const int16_t (*beta)[2]; + const Word16 (*alpha)[2]; + const Word16 (*beta)[2]; } HUFF_NODE_TABLE; /*----------------------------------------------------------------------------------* diff --git a/lib_com/ivas_cov_smooth.c b/lib_com/ivas_cov_smooth_fx.c similarity index 99% rename from lib_com/ivas_cov_smooth.c rename to lib_com/ivas_cov_smooth_fx.c index 8b13f3fd1011f40f0d729178d59a1cf94191aeb6..3a93ed1f577c0a8f2536607f5d25256674bd4f5c 100644 --- a/lib_com/ivas_cov_smooth.c +++ b/lib_com/ivas_cov_smooth_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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,7 @@ #include #include "options.h" #include "cnst.h" -#include "ivas_prot.h" #include "wmc_auto.h" -#include "prot.h" #include "prot_fx.h" #include "ivas_prot_fx.h" diff --git a/lib_com/ivas_dirac_com.c b/lib_com/ivas_dirac_com_fx.c similarity index 95% rename from lib_com/ivas_dirac_com.c rename to lib_com/ivas_dirac_com_fx.c index 138d86eaff789e0cbcf0e154dfb60d45b3637806..14658779137939c6407057e31a2236065e7a1150 100644 --- a/lib_com/ivas_dirac_com.c +++ b/lib_com/ivas_dirac_com_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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,11 +36,9 @@ #include #include "ivas_cnst.h" #include "ivas_rom_com.h" -#include "ivas_prot.h" -#include "prot.h" +#include "prot_fx.h" #include "cnst.h" #include "wmc_auto.h" -#include "prot_fx.h" #include "ivas_prot_fx.h" #include "ivas_rom_com_fx.h" @@ -610,7 +608,12 @@ void computeDirectionVectors_fixed( Word32 *direction_vector_x, /* o: Q30*/ Word32 *direction_vector_y, /* o: Q30*/ Word32 *direction_vector_z, /* o: Q30*/ - Word16 i_e /*Exponent of all the intensity buffers*/ ) + Word16 i_e /*Exponent of all the intensity buffers*/ +#ifdef NONBE_IMPROVE_DIRAC_INTENSITY_PREC + , + Word16 *i_e_band +#endif +) { Word16 i; Word32 intensityNorm; @@ -628,9 +631,25 @@ void computeDirectionVectors_fixed( scaled_x = L_shl( *intensity_real_x, norm_x ); scaled_y = L_shl( *intensity_real_y, norm_y ); scaled_z = L_shl( *intensity_real_z, norm_z ); +#ifdef NONBE_IMPROVE_DIRAC_INTENSITY_PREC + IF( i_e_band != NULL ) + { + e_x = sub( Q31, add( i_e_band[i - enc_param_start_band], norm_x ) ); + e_y = sub( Q31, add( i_e_band[i - enc_param_start_band], norm_y ) ); + e_z = sub( Q31, add( i_e_band[i - enc_param_start_band], norm_z ) ); + } + ELSE + { + e_x = sub( i_e, norm_x ); + e_y = sub( i_e, norm_y ); + e_z = sub( i_e, norm_z ); + } +#else + e_x = sub( i_e, norm_x ); e_y = sub( i_e, norm_y ); e_z = sub( i_e, norm_z ); +#endif temp1 = BASOP_Util_Add_Mant32Exp( Mult_32_32( scaled_x, scaled_x ), shl( e_x, 1 ), Mult_32_32( scaled_y, scaled_y ), shl( e_y, 1 ), &exp1 ); intensityNorm = BASOP_Util_Add_Mant32Exp( temp1, exp1, Mult_32_32( scaled_z, scaled_z ), shl( e_z, 1 ), &intensityNorm_e ); @@ -945,42 +964,115 @@ void computeDiffuseness_fixed( p_tmp_c = buffer_energy + i * num_freq_bands; q_tmp = add( q_factor_energy[i], min_q_shift1 ); + + +#ifdef FIX_1072_SPEEDUP_COMPUTEDIFUSENESS + Word16 shift_q = sub( q_tmp, q_ene ); + Word32 shiftEquiv = L_add( 0, 0 ); + Word16 shift_qtotal; + if ( shift_q < 0 ) + { +#ifdef FIX_USAN_ISSUES + shiftEquiv = L_lshl( (Word32) 0x80000000, shift_q ); +#else + shiftEquiv = L_lshl( 0x80000000, shift_q ); +#endif + } + if ( shift_q >= 0 ) + { + shiftEquiv = L_add( 0x7FFFFFFF, 0 ); + } + shift_qtotal = sub( min_q_shift1, s_max( shift_q, 0 ) ); + FOR( k = 0; k < num_freq_bands; k++ ) { - tmp = L_shl( p_tmp_c[k], min_q_shift1 ); - IF( LT_16( q_tmp, q_ene ) ) + tmp = L_shl( p_tmp_c[k], shift_qtotal ); + energy_slow[k] = Madd_32_32_r( tmp, energy_slow[k], shiftEquiv ); + move32(); + } +#else + Word16 shift_q = sub( q_tmp, q_ene ); + IF( shift_q < 0 ) + { + FOR( k = 0; k < num_freq_bands; k++ ) { - energy_slow[k] = L_add( L_shr( energy_slow[k], sub( q_ene, q_tmp ) ), tmp ); + tmp = L_shl( p_tmp_c[k], min_q_shift1 ); + energy_slow[k] = L_add( L_shl( energy_slow[k], shift_q ), tmp ); move32(); } - ELSE + } + ELSE + { + FOR( k = 0; k < num_freq_bands; k++ ) { - energy_slow[k] = L_add( energy_slow[k], L_shr( tmp, sub( q_tmp, q_ene ) ) ); + tmp = L_shl( p_tmp_c[k], min_q_shift1 ); + energy_slow[k] = L_add( energy_slow[k], L_shr( tmp, shift_q ) ); move32(); } } +#endif + + q_ene = s_min( q_ene, q_tmp ); /* Intensity slow */ q_tmp = add( q_factor_intensity[i], min_q_shift2 ); + + shift_q = sub( q_tmp, q_intensity ); +#ifdef FIX_1072_SPEEDUP_COMPUTEDIFUSENESS + if ( shift_q < 0 ) + { +#ifdef FIX_USAN_ISSUES + shiftEquiv = L_lshl( (Word32) 0x80000000, shift_q ); +#else + shiftEquiv = L_lshl( 0x80000000, shift_q ); +#endif + } + if ( shift_q >= 0 ) + { + shiftEquiv = L_lshl( 0x7FFFFFFF, 0 ); + } + shift_qtotal = sub( min_q_shift2, s_max( shift_q, 0 ) ); + FOR( j = 0; j < DIRAC_NUM_DIMS; ++j ) { p_tmp = buffer_intensity[j][i]; FOR( k = 0; k < num_freq_bands; k++ ) { - tmp = L_shl( p_tmp[k], min_q_shift2 ); - IF( LT_16( q_intensity, q_tmp ) ) + tmp = L_shl( p_tmp[k], shift_qtotal ); + intensity_slow[j * num_freq_bands + k] = Madd_32_32_r( tmp, intensity_slow[j * num_freq_bands + k], shiftEquiv ); + move32(); + } + } +#else + IF( shift_q > 0 ) + { + FOR( j = 0; j < DIRAC_NUM_DIMS; ++j ) + { + p_tmp = buffer_intensity[j][i]; + FOR( k = 0; k < num_freq_bands; k++ ) { - intensity_slow[j * num_freq_bands + k] = L_add( intensity_slow[j * num_freq_bands + k], L_shr( tmp, sub( q_tmp, q_intensity ) ) ); + tmp = L_shl( p_tmp[k], min_q_shift2 ); + intensity_slow[j * num_freq_bands + k] = L_add( intensity_slow[j * num_freq_bands + k], L_shr( tmp, shift_q ) ); move32(); } - ELSE + } + } + ELSE + { + FOR( j = 0; j < DIRAC_NUM_DIMS; ++j ) + { + p_tmp = buffer_intensity[j][i]; + FOR( k = 0; k < num_freq_bands; k++ ) { - intensity_slow[j * num_freq_bands + k] = L_add( L_shr( intensity_slow[j * num_freq_bands + k], sub( q_intensity, q_tmp ) ), tmp ); + tmp = L_shl( p_tmp[k], min_q_shift2 ); + intensity_slow[j * num_freq_bands + k] = L_add( L_shl( intensity_slow[j * num_freq_bands + k], shift_q ), tmp ); move32(); } } } +#endif + q_intensity = s_min( q_intensity, q_tmp ); } @@ -996,9 +1088,7 @@ void computeDiffuseness_fixed( FOR( k = 0; k < num_freq_bands; k++ ) { - p_tmp[k] = Mpy_32_32( p_tmp[k], p_tmp[k] ); - move32(); - intensity_slow_abs[k] = L_add( intensity_slow_abs[k], p_tmp[k] ); + intensity_slow_abs[k] = Madd_32_32( intensity_slow_abs[k], p_tmp[k], p_tmp[k] ); move32(); } } diff --git a/lib_com/ivas_entropy_coder_common.c b/lib_com/ivas_entropy_coder_common_fx.c similarity index 99% rename from lib_com/ivas_entropy_coder_common.c rename to lib_com/ivas_entropy_coder_common_fx.c index 8793723cdd9a55f61fa98ed43fec72a91edd11af..f52d59859e7833964f125b0837b23a7d18c91dce 100644 --- a/lib_com/ivas_entropy_coder_common.c +++ b/lib_com/ivas_entropy_coder_common_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other @@ -32,10 +32,9 @@ #include #include "options.h" -#include "ivas_prot.h" #include "ivas_rom_com.h" #include "math.h" -#include "prot.h" +#include "prot_fx.h" #include "wmc_auto.h" #include "ivas_prot_fx.h" diff --git a/lib_com/ivas_error.h b/lib_com/ivas_error.h index 1198008f647080f71550e28f940ff6f115dec98d..506c6ac00564f3eb7bdf78f05a1e54ec2995d588 100644 --- a/lib_com/ivas_error.h +++ b/lib_com/ivas_error.h @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other @@ -97,6 +97,12 @@ typedef enum * input data errors * *----------------------------------------*/ IVAS_ERR_INVALID_BITSTREAM = 0x2000, +#ifdef SPLIT_REND_WITH_HEAD_ROT +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + IVAS_ERR_UNEXPECTED_LC3PLUS_BITSTREAM, + IVAS_ERR_UNEXPECTED_LC3PLUS_BITSTREAM_CONFIG, +#endif +#endif /*----------------------------------------* * hardware errors * @@ -135,6 +141,10 @@ typedef enum IVAS_ERR_ACOUSTIC_ENVIRONMENT_MISSING, IVAS_ERR_INVALID_ER_PARAM, IVAS_ERR_DIRECTIVITY_PATTERN_ID_MISSING, +#ifdef SPLIT_REND_WITH_HEAD_ROT + IVAS_ERR_LC3PLUS_INVALID_BITRATE, + IVAS_ERR_INVALID_SPLIT_REND_CONFIG, +#endif /*----------------------------------------* * unknown error * @@ -233,6 +243,12 @@ static inline const char *ivas_error_to_string( ivas_error error_code ) return "Wrong mode"; case IVAS_ERR_HEAD_ROTATION_NOT_SUPPORTED: return "Head rotation not supported"; +#ifdef SPLIT_REND_WITH_HEAD_ROT + case IVAS_ERR_LC3PLUS_INVALID_BITRATE: + return "Specified split rendering bit rate is not supported"; + case IVAS_ERR_INVALID_SPLIT_REND_CONFIG: + return "Specified split rendering configuration is invalid"; +#endif case IVAS_ERR_EXT_ORIENTATION_NOT_SUPPORTED: return "External orientation not supported"; case IVAS_ERR_DIRECTIVITY_NOT_SUPPORTED: diff --git a/lib_com/ivas_error_utils.h b/lib_com/ivas_error_utils.h index b686cf28333e63cdef4b611368e50cacf8846eed..0c3d5ce042d74d7b9ea0c4be32729f5c161889de 100644 --- a/lib_com/ivas_error_utils.h +++ b/lib_com/ivas_error_utils.h @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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_com/ivas_fb_mixer.c b/lib_com/ivas_fb_mixer_fx.c similarity index 95% rename from lib_com/ivas_fb_mixer.c rename to lib_com/ivas_fb_mixer_fx.c index 78603c1db43c9d913d5cff69c6bcb7fce4d16d27..d5cd8d4f17875b44cbcecb447e9bf0463a25f056 100644 --- a/lib_com/ivas_fb_mixer.c +++ b/lib_com/ivas_fb_mixer_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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,13 +34,11 @@ #include #include #include "options.h" -#include "prot.h" -#include "ivas_prot.h" +#include "prot_fx.h" #include "rom_com.h" #include "ivas_rom_com.h" #include "wmc_auto.h" #include "ivas_prot_fx.h" -#include "prot_fx.h" #include "ivas_rom_com_fx.h" @@ -560,7 +558,11 @@ void ivas_fb_mixer_pcm_ingest_fx( move16(); ivas_mdft_fx( ppOut_pcm[fb_cfg->remix_order[i]], hFbMixer->ppFilterbank_inFR_re_fx[fb_cfg->remix_order[i]], hFbMixer->ppFilterbank_inFR_im_fx[fb_cfg->remix_order[i]], shl( frame_len, 1 ), frame_len ); - hFbMixer->q_ppFilterbank_inFR[fb_cfg->remix_order[i]] = q_ppOut_pcm[fb_cfg->remix_order[i]]; + q_shift = L_norm_arr( hFbMixer->ppFilterbank_inFR_re_fx[fb_cfg->remix_order[i]], frame_len ); + q_shift = s_min( q_shift, L_norm_arr( hFbMixer->ppFilterbank_inFR_im_fx[fb_cfg->remix_order[i]], frame_len ) ); + scale_sig32( hFbMixer->ppFilterbank_inFR_re_fx[fb_cfg->remix_order[i]], frame_len, q_shift ); + scale_sig32( hFbMixer->ppFilterbank_inFR_im_fx[fb_cfg->remix_order[i]], frame_len, q_shift ); + hFbMixer->q_ppFilterbank_inFR[fb_cfg->remix_order[i]] = add( q_shift, q_ppOut_pcm[fb_cfg->remix_order[i]] ); move16(); } @@ -915,7 +917,10 @@ static Word16 ivas_calculate_abs_fr_fx( move16(); Word16 idx_short_stride_bin_to_band = 0; move16(); + Word16 quo, tmp, exp_diff; + Word32 temp = Mpy_32_32( sampling_rate, 42949673 /* FRAMES_PER_SEC in Q31 */ ); + frame_len = extract_l( temp ); FOR( i = 0; i < bands; i++ ) { @@ -932,13 +937,11 @@ static Word16 ivas_calculate_abs_fr_fx( Word32 short_stride_pow_spec_fx[MDFT_FB_BANDS_240]; Word32 short_stride_nrg_fx = 0; move16(); - Word16 exp_diff = 0, tmp; + exp_diff = 0; move16(); - Word32 cldfb_nrg_fx = 0; - Word16 cldfb_nrg_e = 0; - move16(); - move16(); + Word64 cldfb_nrg_fx = 0; + move64(); Word16 short_stride = pFb->fb_bin_to_band.short_stride; move16(); Word32 res_dec1, res_frac, res_dec2; @@ -959,38 +962,24 @@ static Word16 ivas_calculate_abs_fr_fx( { Word32 sq_abs_fx; - Word16 sq_abs_e; // Word32 real = L_shr( *long_mdft_ptr_re_fx, 3 ); // Q27 Word32 real = *long_mdft_ptr_re_fx; // Q30 move32(); // Word32 imag = L_shr( *long_mdft_ptr_im_fx, 3 ); // Q27 Word32 imag = *long_mdft_ptr_im_fx; // Q30 - - Word16 real_exp, imag_exp; move32(); - - Word32 real_sq, imag_sq; - - real_sq = Mpy_32_32( real, real ); // Q30 + Q30 - 31 = Q29 - real_exp = 2; - move32(); - imag_sq = Mpy_32_32( imag, imag ); // Q30 + Q30 - 31 = Q29 - imag_exp = 2; - move32(); - - sq_abs_fx = BASOP_Util_Add_Mant32Exp( real_sq, real_exp, imag_sq, imag_exp, &sq_abs_e ); // Q(31 - sq_abs_e) - + Word64 acc = W_mac_32_32( W_mult_32_32( real, real ), imag, imag ); // Q61 + sq_abs_fx = W_extract_h( acc ); // Q28 long_mdft_ptr_re_fx++; long_mdft_ptr_im_fx++; /* accumulate bin energies within a short stride bin */ - short_stride_nrg_fx = L_add( short_stride_nrg_fx, L_shl( sq_abs_fx, sub( Q22, sub( Q31, sq_abs_e ) ) ) ); - short_stride_nrg_fx = L_add( short_stride_nrg_fx, L_shl( sq_abs_fx, sub( Q22, sub( Q31, sq_abs_e ) ) ) ); // Q(31 - sq_abs_e) -> Q22 + short_stride_nrg_fx = L_add( short_stride_nrg_fx, L_shr( sq_abs_fx, 6 ) ); // Q22 move32(); - IF( !( ( j + 1 ) % num_bins_per_short_stride_bin ) ) + IF( !( add( j, 1 ) % num_bins_per_short_stride_bin ) ) { /* new short stride bin */ short_stride_pow_spec_fx[j / num_bins_per_short_stride_bin] = short_stride_nrg_fx; /* energy rather than magnitude works better for covariance weighting*/ @@ -1001,33 +990,38 @@ static Word16 ivas_calculate_abs_fr_fx( } /* accumulate bin energies within a CLDFB band */ - cldfb_nrg_fx = BASOP_Util_Add_Mant32Exp( cldfb_nrg_fx, cldfb_nrg_e, sq_abs_fx, sq_abs_e, &cldfb_nrg_e ); + cldfb_nrg_fx = W_mac_32_32( cldfb_nrg_fx, sq_abs_fx, 1 ); // Q29 - IF( !( ( j + 1 ) % num_bins_per_cldfb_band ) ) + IF( !( add( j, 1 ) % num_bins_per_cldfb_band ) ) { - Word32 temp = Sqrt32( cldfb_nrg_fx, &cldfb_nrg_e ); - temp = L_shl( temp, sub( cldfb_nrg_e, Q9 ) ); // Q22 + Word16 exp = W_norm( cldfb_nrg_fx ); + cldfb_nrg_fx = W_shl( cldfb_nrg_fx, exp ); + exp = sub( 34, exp ); // 31 - (Q29 + exp -32) + temp = Sqrt32( W_extract_h( cldfb_nrg_fx ), &exp ); + temp = L_shl( temp, sub( exp, Q9 ) ); // Q22 pFb->fb_bin_to_band.pp_cldfb_weights_per_spar_band_fx[j / num_bins_per_cldfb_band][i] = temp; // Q22 move32(); cldfb_nrg_fx = 0; move32(); - cldfb_nrg_e = 0; - move16(); } } + quo = BASOP_Util_Divide3232_Scale( ONE_IN_Q30, short_stride_max_per_spar_band_fx, &exp_diff ); + /* Q of quo = Q30 - Q22 + (15 - exp_diff) --> Q23 - exp_diff. + With Mult_32_16, Q23 - exp_diff - 15 --> Q8 - exp_diff */ + exp_diff = sub( Q8, exp_diff ); + /*loop over the short MDFT bins*/ FOR( j = 0; j < short_stride; j++ ) { - tmp = BASOP_Util_Divide3232_Scale( short_stride_pow_spec_fx[j], short_stride_max_per_spar_band_fx, &exp_diff ); - short_stride_pow_spec_fx[j] = L_shl( L_deposit_l( tmp ), add( Q7, exp_diff ) ); // Q22 + short_stride_pow_spec_fx[j] = L_shr( Mult_32_16( short_stride_pow_spec_fx[j], quo ), exp_diff ); // Q22 move32(); short_stride_pow_spec_fx[j] = L_max( L_sub( short_stride_pow_spec_fx[j], 1258291 ), 0 ); // 0.3f * ONE_IN_Q22 move32(); - tmp = BASOP_Util_Divide3232_Scale( short_stride_pow_spec_fx[j], 2936012, &exp_diff ); // 0.7f * ONE_IN_Q22 - short_stride_pow_spec_fx[j] = L_shl( L_deposit_l( tmp ), add( Q7, exp_diff ) ); // Q22 + short_stride_pow_spec_fx[j] = L_shl( Mpy_32_32( short_stride_pow_spec_fx[j], 1533916891 /* 1/0.7 in Q30 */ ), 1 ); // Q22 move32(); + IF( short_stride_pow_spec_fx[j] > 0 ) { assert( idx_short_stride_bin_to_band < 2 * MDFT_FB_BANDS_240 ); /* array size of p_short_stride_bin_to_band */ @@ -1083,6 +1077,13 @@ static Word16 ivas_calculate_abs_fr_fx( sum_over_spar_bands_fx = L_max( sum_over_spar_bands_fx, EPSILON_FX ); // Q22 move32(); + exp_diff = 0; + move16(); + tmp = BASOP_Util_Divide3232_Scale( ONE_IN_Q30, sum_over_spar_bands_fx, &exp_diff ); + /* Q of quo = Q30 - Q22 + (15 - exp_diff) --> Q23 - exp_diff. + With Mult_32_16, Q23 - exp_diff - 15 --> Q8 - exp_diff */ + exp_diff = sub( Q8, exp_diff ); + FOR( i = 0; i < bands; i++ ) { test(); @@ -1096,20 +1097,13 @@ static Word16 ivas_calculate_abs_fr_fx( move16(); } - Word16 exp_diff = 0; - move16(); - Word16 tmp = BASOP_Util_Divide3232_Scale( pFb->fb_bin_to_band.pp_cldfb_weights_per_spar_band_fx[j][i], sum_over_spar_bands_fx, &exp_diff ); - pFb->fb_bin_to_band.pp_cldfb_weights_per_spar_band_fx[j][i] = L_shl( L_deposit_l( tmp ), add( Q7, exp_diff ) ); // Q22 + pFb->fb_bin_to_band.pp_cldfb_weights_per_spar_band_fx[j][i] = L_shr( Mult_32_16( pFb->fb_bin_to_band.pp_cldfb_weights_per_spar_band_fx[j][i], tmp ), exp_diff ); move32(); } pFb->fb_bin_to_band.p_spar_start_bands[j] = spar_start; move16(); } - Word16 exp; - frame_len = BASOP_Util_Divide3232_Scale( sampling_rate, FRAMES_PER_SEC, &exp ); - frame_len = shr( frame_len, sub( 15, exp ) ); - set32_fx( ppFilterbank_FRs_s_fx, 0, frame_len ); /*Commented logic is for calculating number of active bands, can be removed if not needed */ @@ -1136,7 +1130,7 @@ static Word16 ivas_calculate_abs_fr_fx( Word32 temp_fx = 0; move32(); - Word16 exp_diff = 0; + exp_diff = 0; move16(); Word32 real = L_shr( *pFilterbank_bin_to_band_re_fx, 3 ); // Q27 Word32 imag = L_shr( *pFilterbank_bin_to_band_im_fx, 3 ); // Q27 @@ -1195,7 +1189,7 @@ static Word16 ivas_calculate_abs_fr_fx( { Word16 abs_active_bins = pFb->fb_bin_to_band.pFb_active_bins_per_band[j]; Word16 abs_start_offset = pFb->fb_bin_to_band.pFb_start_bin_per_band[j]; - Word16 exp_diff = 0, tmp; + exp_diff = 0; move16(); move16(); @@ -1293,7 +1287,7 @@ static ivas_error ivas_filterbank_setup_fx( ivas_get_active_bins_fx( &pAll_bins_per_band, &pAll_bins_per_band_abs, &pAll_bins_start_offset, &pAll_bins_start_offset_abs, sampling_rate ); - IF( EQ_16( pCfg->fb_latency, NS2SA( sampling_rate, DELAY_FB_1_NS ) ) ) + IF( EQ_16( pCfg->fb_latency, NS2SA_FX2( sampling_rate, DELAY_FB_1_NS ) ) ) { pAll_fb_fr_fx[0] = ivas_fb_fr_12band_1ms_re_fx; // Q30 move32(); @@ -1482,7 +1476,7 @@ static ivas_error ivas_fb_mixer_get_window_fx( error = IVAS_ERR_OK; move32(); - IF( EQ_16( fade_len, NS2SA( sampling_rate, DELAY_FB_4_NS ) ) ) + IF( EQ_16( fade_len, NS2SA_FX2( sampling_rate, DELAY_FB_4_NS ) ) ) { SWITCH( sampling_rate ) { @@ -1499,7 +1493,7 @@ static ivas_error ivas_fb_mixer_get_window_fx( return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "Unsupported Sampling frequency!" ); } } - ELSE IF( EQ_16( fade_len, NS2SA( sampling_rate, DELAY_FB_1_NS ) ) ) + ELSE IF( EQ_16( fade_len, NS2SA_FX2( sampling_rate, DELAY_FB_1_NS ) ) ) { SWITCH( sampling_rate ) { diff --git a/lib_com/ivas_filters.c b/lib_com/ivas_filters_fx.c similarity index 99% rename from lib_com/ivas_filters.c rename to lib_com/ivas_filters_fx.c index 32ebe479ff26e38dccced55c702e6b7cf64ad713..1e9aaf0c20771fffa77bbebf43f7109a95cc50b5 100644 --- a/lib_com/ivas_filters.c +++ b/lib_com/ivas_filters_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other @@ -32,7 +32,6 @@ #include #include "options.h" -#include "ivas_prot.h" #include "ivas_cnst.h" #include "ivas_stat_com.h" #include "wmc_auto.h" diff --git a/lib_com/ivas_ism_com.c b/lib_com/ivas_ism_com_fx.c similarity index 99% rename from lib_com/ivas_ism_com.c rename to lib_com/ivas_ism_com_fx.c index 1dd7f0f8784132b4f3c550fc6d28041dc2058e00..5f1a13afb7ca1a431d823a6d5461813e136c34a0 100644 --- a/lib_com/ivas_ism_com.c +++ b/lib_com/ivas_ism_com_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other @@ -35,15 +35,12 @@ #include "cnst.h" #include "ivas_cnst.h" #include "rom_com.h" -#include "prot.h" -#include "ivas_prot.h" +#include "prot_fx.h" #include "ivas_stat_com.h" #include "ivas_rom_com.h" #include "wmc_auto.h" #include "ivas_prot_fx.h" -#include "prot_fx.h" -#define IVAS_FLOAT_FIXED_TO_BE_REMOVED /*-----------------------------------------------------------------------* * Local constants diff --git a/lib_com/ivas_lfe_com.c b/lib_com/ivas_lfe_com_fx.c similarity index 98% rename from lib_com/ivas_lfe_com.c rename to lib_com/ivas_lfe_com_fx.c index 56f14a18b424a16018594990233ae180fe8a1817..3d1e7aee66e4b495f8aadbff57788cacdcc5389c 100644 --- a/lib_com/ivas_lfe_com.c +++ b/lib_com/ivas_lfe_com_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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,8 +34,7 @@ #include "math.h" #include "options.h" #include "ivas_stat_com.h" -#include "prot.h" -#include "ivas_prot.h" +#include "prot_fx.h" #include "rom_com.h" #include "ivas_rom_com.h" #include "cnst.h" diff --git a/lib_rend/ivas_limiter.c b/lib_com/ivas_limiter_fx.c similarity index 99% rename from lib_rend/ivas_limiter.c rename to lib_com/ivas_limiter_fx.c index 17211d1c6da8b2ef59e0a8a3c3f6f23073cc1920..4250d7a7a46db4ebc5500b6754d015d1f25a601d 100644 --- a/lib_rend/ivas_limiter.c +++ b/lib_com/ivas_limiter_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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,10 @@ #include #include "options.h" #include -#include "prot.h" -#include "ivas_prot_rend.h" +#include "prot_fx.h" +#include "ivas_prot_rend_fx.h" #include "ivas_rom_rend.h" +#include "ivas_rom_com.h" #include "wmc_auto.h" #include #include "ivas_prot_fx.h" diff --git a/lib_com/ivas_masa_com.c b/lib_com/ivas_masa_com_fx.c similarity index 99% rename from lib_com/ivas_masa_com.c rename to lib_com/ivas_masa_com_fx.c index 1ff43334435d86db53d149122027d31ea33c94be..cfed06357fe908e6c3fda28720aa7272ca67adb0 100644 --- a/lib_com/ivas_masa_com.c +++ b/lib_com/ivas_masa_com_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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,14 +34,12 @@ #include #include "options.h" #include -#include "prot.h" +#include "prot_fx.h" #include "ivas_cnst.h" -#include "ivas_prot.h" #include "ivas_rom_com.h" #include "ivas_stat_dec.h" #include "wmc_auto.h" #include "ivas_rom_com_fx.h" -#include "prot_fx.h" #include "ivas_prot_fx.h" diff --git a/lib_com/ivas_mc_com.c b/lib_com/ivas_mc_com_fx.c similarity index 98% rename from lib_com/ivas_mc_com.c rename to lib_com/ivas_mc_com_fx.c index 39ba64d0e21976c9879554bfec77aff0770fbf8a..8201037a1a5f89eb53acb0e81787b0a87f68da5c 100644 --- a/lib_com/ivas_mc_com.c +++ b/lib_com/ivas_mc_com_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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,8 +34,7 @@ #include #include "options.h" #include -#include "prot.h" -#include "ivas_prot.h" +#include "prot_fx.h" #include "wmc_auto.h" #include "ivas_prot_fx.h" diff --git a/lib_com/ivas_mc_param_com.c b/lib_com/ivas_mc_param_com_fx.c similarity index 99% rename from lib_com/ivas_mc_param_com.c rename to lib_com/ivas_mc_param_com_fx.c index be3f35606f874df9d56e143ee1f6964adafd4274..4469e7f93d82856a3e2db90e362e3e02265108be 100644 --- a/lib_com/ivas_mc_param_com.c +++ b/lib_com/ivas_mc_param_com_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other @@ -35,9 +35,7 @@ #include #include "options.h" #include "ivas_cnst.h" -#include "prot.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "ivas_stat_com.h" #include "ivas_rom_com.h" #include "wmc_auto.h" diff --git a/lib_com/ivas_mcmasa_com.c b/lib_com/ivas_mcmasa_com-fx.c similarity index 98% rename from lib_com/ivas_mcmasa_com.c rename to lib_com/ivas_mcmasa_com-fx.c index fe29c84866f60c39eb8f043d71c8fb500a5046ab..23a3800fb792ba9eeee06ef4cd26001a9b54d5e6 100644 --- a/lib_com/ivas_mcmasa_com.c +++ b/lib_com/ivas_mcmasa_com-fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other @@ -31,7 +31,6 @@ *******************************************************************************************************/ #include "ivas_cnst.h" -#include "ivas_prot.h" #include "options.h" #include "wmc_auto.h" #include "ivas_prot_fx.h" diff --git a/lib_com/ivas_mct_com.c b/lib_com/ivas_mct_com_fx.c similarity index 98% rename from lib_com/ivas_mct_com.c rename to lib_com/ivas_mct_com_fx.c index 3d2d4c99b72ac9f2ce9ec43da94fa5793c8b5ac3..81a56df146d9ba7378dbcadacb6aeb39b98f28b0 100644 --- a/lib_com/ivas_mct_com.c +++ b/lib_com/ivas_mct_com_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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,8 +33,8 @@ #include #include "options.h" #include "ivas_cnst.h" -#include "ivas_prot.h" -#include "prot.h" +#include "prot_fx.h" +#include "ivas_prot_fx.h" #include "wmc_auto.h" #include diff --git a/lib_com/ivas_mdct_core_com.c b/lib_com/ivas_mdct_core_com_fx.c similarity index 97% rename from lib_com/ivas_mdct_core_com.c rename to lib_com/ivas_mdct_core_com_fx.c index f3ad466ccee734a1fd4d88b1d9c9ede34b26f7d3..fe313eecdd7c3be915f9d9aa73c37081e79b61ac 100644 --- a/lib_com/ivas_mdct_core_com.c +++ b/lib_com/ivas_mdct_core_com_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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,8 @@ #include #include "options.h" #include "ivas_cnst.h" -#include "ivas_prot.h" -#include "prot.h" -#include "wmc_auto.h" #include "prot_fx.h" +#include "wmc_auto.h" #include "ivas_prot_fx.h" /*--------------------------------------------------------------------------* diff --git a/lib_com/ivas_mdct_imdct_fx.c b/lib_com/ivas_mdct_imdct_fx.c index 37c5251098d3dbd3c4fee6a0006386a71567aa02..542f5ca745df2f4a678581ab9c1968ba2966137e 100644 --- a/lib_com/ivas_mdct_imdct_fx.c +++ b/lib_com/ivas_mdct_imdct_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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_com/ivas_mdft_imdft.c b/lib_com/ivas_mdft_imdft_fx.c similarity index 99% rename from lib_com/ivas_mdft_imdft.c rename to lib_com/ivas_mdft_imdft_fx.c index 4ed267ba50dec81360f68bc87c50ee6862b7be57..5d7bee1a6929347ac19968f7d8996878878f8897 100644 --- a/lib_com/ivas_mdft_imdft.c +++ b/lib_com/ivas_mdft_imdft_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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,14 +33,12 @@ #include #include "options.h" -#include "prot.h" -#include "ivas_prot.h" +#include "prot_fx.h" #include "ivas_rom_com.h" #include #include "wmc_auto.h" #include #include -#include "prot_fx.h" #include "debug.h" #include "ivas_rom_com_fx.h" #include "ivas_prot_fx.h" diff --git a/lib_com/ivas_omasa_com.c b/lib_com/ivas_omasa_com_fx.c similarity index 99% rename from lib_com/ivas_omasa_com.c rename to lib_com/ivas_omasa_com_fx.c index a86f90acb7246eb84a9a47e5c9410cc55f51f6db..1c1d4bf6cb6ca87def78b29f60c793547d2f3e4d 100644 --- a/lib_com/ivas_omasa_com.c +++ b/lib_com/ivas_omasa_com_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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,13 +33,11 @@ #include "options.h" #include #include "ivas_cnst.h" -#include "ivas_prot.h" #include "ivas_prot_fx.h" -#include "prot.h" +#include "prot_fx.h" #include "ivas_rom_com.h" #include "rom_com.h" #include -#include "prot_fx.h" /*--------------------------------------------------------------- * Local constants diff --git a/lib_com/ivas_pca_tools.c b/lib_com/ivas_pca_tools_fx.c similarity index 99% rename from lib_com/ivas_pca_tools.c rename to lib_com/ivas_pca_tools_fx.c index 6ccc07523ad68f96f1c1ba8ba06c732f0c320e2d..c84078a7d4291080687cfe2597eafe8af3aba784 100644 --- a/lib_com/ivas_pca_tools.c +++ b/lib_com/ivas_pca_tools_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other @@ -32,13 +32,11 @@ #include #include "options.h" -#include "ivas_prot.h" #include "ivas_cnst.h" #include #include #include "ivas_rom_com.h" #include "wmc_auto.h" -#include "prot.h" #include "prot_fx.h" #include "ivas_prot_fx.h" diff --git a/lib_com/ivas_prot.h b/lib_com/ivas_prot.h deleted file mode 100644 index 7a7126490db82d87e25a8f2c7f077977b198387f..0000000000000000000000000000000000000000 --- a/lib_com/ivas_prot.h +++ /dev/null @@ -1,4119 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -#ifndef IVAS_PROT_H -#define IVAS_PROT_H - -#include -#include "options.h" -#include -#include "typedef.h" -#include "stat_enc.h" -#include "stat_dec.h" -#include "stat_com.h" -#include "ivas_stat_enc.h" -#include "ivas_stat_dec.h" -#include "ivas_stat_com.h" -#include "ivas_error_utils.h" - -#define IVAS_FLOAT_FIXED_TO_BE_REMOVED - -/* clang-format off */ - -/*----------------------------------------------------------------------------------* - * General IVAS prototypes - *----------------------------------------------------------------------------------*/ - -ivas_error ivas_enc( - Encoder_Struct *st_ivas, /* i : IVAS encoder structure */ - const int16_t *data, /* i : input signal */ - const int16_t n_samples /* i : number of input samples */ -); - -void stereo_dmx_evs_enc( - STEREO_DMX_EVS_ENC_HANDLE hStereoDmxEVS, /* i/o: Stereo downmix for EVS encoder handle */ - const int32_t input_Fs, /* i : input sampling rate */ - int16_t data[CPE_CHANNELS * L_FRAME48k], /* i/o: input signal */ - const int16_t n_samples, /* i : number of input samples */ - const bool is_binaural /* i : indication that input is binaural audio */ -); - -/*! r: number of channels to be analysed */ - -void copy_encoder_config( - Encoder_Struct *st_ivas, /* i : IVAS encoder structure */ - Encoder_State *st, /* o : encoder state structure */ - const int16_t flag_all /* i : flag 1==update all, 0=partial update */ -); - - - -ivas_error create_sce_enc( - Encoder_Struct *st_ivas, /* i/o: IVAS encoder structure */ - const int16_t sce_id, /* i : SCE # identifier */ - const int32_t element_brate /* i : element bitrate */ -); - -ivas_error create_evs_sce_enc( - Encoder_Struct *st_ivas, /* i/o: IVAS encoder structure */ - const int16_t sce_id, /* i : SCE # identifier */ - const int32_t element_brate /* i : element bitrate */ -); - -ivas_error create_cpe_enc( - Encoder_Struct *st_ivas, /* i/o: IVAS encoder structure */ - const int16_t cpe_id, /* i : CPE # identifier */ - const int32_t element_brate /* i : element bitrate */ -); - -ivas_error create_mct_enc( - Encoder_Struct *st_ivas /* i/o: IVAS encoder structure */ -); - -ivas_error ivas_sba_enc_reconfigure( - Encoder_Struct *st_ivas /* i/o: IVAS encoder structure */ -); - -void destroy_sce_enc( - SCE_ENC_HANDLE hSCE, /* i/o: SCE encoder structure */ - Flag is_evs /* i : Flag to indicate EVS encoder */ -); - -void destroy_cpe_enc( - CPE_ENC_HANDLE hCPE /* i/o: CPE encoder structure */ -); - -void ivas_mct_enc_close( - MCT_ENC_HANDLE *hMCT /* i/o: MCT encoder structure */ -); - -ivas_error ivas_corecoder_enc_reconfig( - Encoder_Struct *st_ivas, /* i/o: IVAS encoder structure */ - const int16_t nSCE_old, /* i : number of SCEs in previous frame */ - const int16_t nCPE_old, /* i : number of CPEs in previous frame */ - const int16_t nchan_transport_old, /* i : number of TCs in previous frame */ - const int32_t brate_SCE, /* i : bitrate to be set for the SCEs */ - const int32_t brate_CPE, /* i : bitrate to be set for the CPEs */ - const MC_MODE last_mc_mode /* i : switching between MC modes: last mode */ -); - -ivas_error ivas_sce_enc( - Encoder_Struct *st_ivas, /* i/o: IVAS encoder structure */ - const int16_t sce_id, /* i : SCE # identifier */ - const float data_f[], /* i : input signal for single channel */ - const int16_t input_frame, /* i : input frame length per channel */ - const int16_t nb_bits_metadata /* i : number of metadata bits */ -); - - -ivas_error ivas_cpe_enc( - Encoder_Struct *st_ivas, /* i/o: IVAS encoder structure */ - const Word16 cpe_id, /* i : CPE # identifier */ - float data_f_ch0[], /* i : input signal for channel 0 */ - float data_f_ch1[], /* i : input signal for channel 1 */ - const Word16 input_frame, /* i : input frame length per channel */ - const Word16 nb_bits_metadata /* i : number of metadata bits */ -); - -ivas_error ivas_mct_enc( - Encoder_Struct *st_ivas, /* i/o: IVAS encoder structure */ - float *data[MCT_MAX_CHANNELS], /* i : input signal buffers */ - const int16_t input_frame, /* i : input frame length per channel */ - const int16_t nb_bits_metadata /* i : number of metadata bits */ -); - -ivas_error pre_proc_front_ivas( - SCE_ENC_HANDLE hSCE, /* i/o: SCE encoder structure */ - CPE_ENC_HANDLE hCPE, /* i/o: CPE encoder structure */ - const int32_t element_brate, /* i : SCE/CPE element bitrate */ - const int16_t nb_bits_metadata, /* i : number of metadata bits */ - const int16_t input_frame, /* i : frame length */ - const int16_t n, /* i : channel number */ - float old_inp_12k8[], /* o : buffer of old input signal */ - float old_inp_16k[], /* o : buffer of old input signal @16kHz */ - float *ener, /* o : residual energy from Levinson-Durbin */ - float *relE, /* o : frame relative energy */ - float A[NB_SUBFR16k * ( M + 1 )], /* o : A(z) unquantized for the 4 subframes */ - float Aw[NB_SUBFR16k * ( M + 1 )], /* o : weighted A(z) unquantized for subframes */ - float epsP[M + 1], /* o : LP prediction errors */ - float lsp_new[M], /* o : LSPs at the end of the frame */ - float lsp_mid[M], /* o : LSPs in the middle of the frame */ - int16_t *vad_hover_flag, /* o : VAD hangover flag */ - int16_t *attack_flag, /* o : flag signaling attack */ - float realBuffer[CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], /* i/o: real buffer */ - float imagBuffer[CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], /* i/o: imag buffer */ - float old_wsp[], /* o : weighted input signal buffer */ - float pitch_fr[NB_SUBFR], /* o : fractional pitch values */ - float voicing_fr[NB_SUBFR], /* o : fractional pitch gains */ - int16_t *loc_harm, /* o : harmonicity flag */ - float *cor_map_sum, /* o : speech/music clasif. parameter */ - int16_t *vad_flag_dtx, /* o : HE-SAD flag with additional DTX HO */ - float enerBuffer[CLDFB_NO_CHANNELS_MAX], /* o : energy buffer */ - float fft_buff[2 * L_FFT], /* o : FFT buffer */ - const float tdm_A_PCh[M + 1], /* i : unq. LP coeff. of primary channel */ - const float tdm_lsp_new_PCh[M], /* i : unq. LSPs of primary channel */ - const float currFlatness, /* i : flatness parameter */ - const int16_t tdm_ratio_idx, /* i : Current Ratio_L index */ - float fr_bands_LR[][2 * NB_BANDS], /* i : energy in frequency bands */ - const float Etot_LR[], /* i : total energy Left & Right channel */ - float lf_E_LR[][2 * VOIC_BINS], /* i : per bin spectrum energy in lf, LR channels */ - const int16_t localVAD_HE_SAD_LR[], /* i : HE-SAD flag without hangover, LR channels */ - float band_energies_LR[2 * NB_BANDS], /* o : energy in critical bands without minimum noise floor E_MIN */ - const int16_t flag_16k_smc, /* i : flag to indicate if the OL SMC is run at 16 kHz */ - const int16_t front_vad_flag, /* i : front-VAD flag to overwrite VAD decision */ - const int16_t force_front_vad, /* i : flag to force VAD decision */ - const int16_t front_vad_dtx_flag, /* i : front-VAD DTX flag to overwrite VAD decision*/ - const IVAS_FORMAT ivas_format, /* i : IVAS format */ - const int16_t MCT_flag, /* i : hMCT handle allocated (1) or not (0) */ - const int32_t ivas_total_brate /* i : IVAS total bitrate */ -); - -ivas_error pre_proc_front_ivas_fx( - SCE_ENC_HANDLE hSCE, /* i/o: SCE encoder structure */ - CPE_ENC_HANDLE hCPE, /* i/o: CPE encoder structure */ - const Word32 element_brate, /* i : SCE/CPE element bitrate */ - const Word16 nb_bits_metadata, /* i : number of metadata bits */ - const Word16 input_frame, /* i : frame length */ - const Word16 n, /* i : channel number */ - Word16 old_inp_12k8_fx[], /* o : (Q-1) buffer of old input signal */ - Word16 old_inp_16k_fx[], /* o : buffer of old input signal @16kHz Q-1 */ - Word32 *ener_fx, /* o : residual energy from Levinson-Durbin Q_r */ - Word16 *relE_fx, /* o : frame relative energy Q8 */ - Word16 A_fx[NB_SUBFR16k * ( M + 1 )], /* o : A(z) unquantized for the 4 subframes */ - Word16 Aw_fx[NB_SUBFR16k * ( M + 1 )], /* o : weighted A(z) unquantized for subframes */ - Word32 epsP_fx[M + 1], /* o : LP prediction errors */ - Word16 *epsP_fx_q, - Word16 lsp_new_fx[M], /* o : LSPs at the end of the frame Q15 */ - Word16 lsp_mid_fx[M], /* o : LSPs in the middle of the frame Q15 */ - Word16 *vad_hover_flag, /* o : VAD hangover flag */ - Word16 *attack_flag, /* o : flag signaling attack */ - Word32 realBuffer_fx[CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], /* i/o: real buffer Q(q_re_im_buf) */ - Word32 imagBuffer_fx[CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], /* i/o: imag buffer Q(q_re_im_buf) */ - Word16 *q_re_im_buf, /* i/o: Q-factor of real and imag buffer */ - Word16 old_wsp[], /* o : weighted input signal buffer q_old_wsp*/ - Word16 *q_old_wsp, - Word16 pitch_fr_fx[NB_SUBFR], /* o : fractional pitch values Q6 */ - Word16 voicing_fr_fx[NB_SUBFR], /* o : fractional pitch gains Q15 */ - Word16 *loc_harm, /* o : harmonicity flag */ - Word16 *cor_map_sum_fx, /* o : speech/music clasif. parameter Q8 */ - Word16 *vad_flag_dtx, /* o : HE-SAD flag with additional DTX HO */ - Word32 enerBuffer_fx[CLDFB_NO_CHANNELS_MAX], /* o : energy buffer */ - Word16 *enerBuffer_fx_exp, /* o : energy buffer */ - Word16 fft_buff_fx[2 * L_FFT], /* o : FFT buffer */ - Word16 *fft_buff_fx_q, /* o : FFT buffer */ - const Word16 tdm_A_PCh_fx[M + 1], /* i : unq. LP coeff. of primary channel Q12 */ - const Word16 tdm_lsp_new_PCh_fx[M], /* i : unq. LSPs of primary channel Q15 */ - const Word16 currFlatness_fx, /* i : flatness parameter Q7 */ - const Word16 tdm_ratio_idx, /* i : Current Ratio_L index */ - Word32 fr_bands_LR_fx[][2 * NB_BANDS], /* i : energy in frequency bands (fr_bands_LR_fx_q) */ - Word16 fr_bands_LR_fx_q, - const Word16 Etot_LR_fx[], /* i : total energy Left & Right channel Q8*/ - Word32 lf_E_LR_fx[][2 * VOIC_BINS], /* i : per bin spectrum energy in lf, LR channels (lf_E_LR_fx_q) */ - Word16 lf_E_LR_fx_q, - const Word16 localVAD_HE_SAD_LR[], /* i : HE-SAD flag without hangover, LR channels */ - Word32 band_energies_LR_fx[2 * NB_BANDS], /* o : energy in critical bands without minimum noise floor E_MIN (band_energies_LR_fx_q) */ - Word16 band_energies_LR_fx_q, - const Word16 flag_16k_smc, /* i : flag to indicate if the OL SMC is run at 16 kHz */ - const Word16 front_vad_flag, /* i : front-VAD flag to overwrite VAD decision */ - const Word16 force_front_vad, /* i : flag to force VAD decision */ - const Word16 front_vad_dtx_flag, /* i : front-VAD DTX flag to overwrite VAD decision*/ - const IVAS_FORMAT ivas_format, /* i : IVAS format */ - const Word16 MCT_flag, /* i : hMCT handle allocated (1) or not (0) */ - const Word32 ivas_total_brate, /* i : IVAS total bitrate - for setting the DTX */ - Word16 *Q_new -#ifdef DEBUG_MODE_INFO - , - const Word16 ch_idx -#endif -); -ivas_error pre_proc_ivas( - Encoder_State *st, /* i/o: encoder state structure */ - const Word16 last_element_mode, /* i : last element mode */ - const Word32 element_brate, /* i : element bitrate */ - const Word32 last_element_brate, /* i : last element bitrate */ - const Word16 input_frame, /* i : frame length */ - Word16 old_inp_12k8_fx[], /* i/o: buffer of old input signal */ - Word16 old_inp_16k_fx[], /* i/o: buffer of old input signal @ 16kHz */ - Word16 **inp_fx, /* o : ptr. to inp. signal in the current frame*/ - Word32 *ener_fx, /* o : residual energy from Levinson-Durbin Q6 */ - Word16 A_fx[NB_SUBFR16k * ( M + 1 )], /* i/o: A(z) unquantized for the 4 subframes */ - Word16 Aw_fx[NB_SUBFR16k * ( M + 1 )], /* i/o: weighted A(z) unquantized for subframes */ - Word32 epsP_fx[M + 1], /* i : LP prediction errors epsP_fx_q */ - Word16 *epsP_fx_q, /* i : LP prediction errors */ - Word16 lsp_new_fx[M], /* i/o: LSPs at the end of the frame */ - Word16 lsp_mid_fx[M], /* i/o: LSPs in the middle of the frame */ - Word16 *new_inp_resamp16k_fx, /* o : new input signal @16kHz, non pre-emphasised, used by the WB TBE/BWE */ - Word16 *Voicing_flag, /* o : voicing flag for HQ FEC */ - Word16 old_wsp_fx[], /* i : weighted input signal buffer */ - Word16 e_old_wsp, - const Word16 loc_harm, /* i : harmonicity flag */ - const Word16 vad_flag_dtx, /* i : HE-SAD flag with additional DTX HO */ - const Word16 MCT_flag, /* i : hMCT handle allocated (1) or not (0) */ - const Word16 vad_hover_flag, /* i : VAD hangover flag */ - const Word16 flag_16k_smc, /* i : flag to indicate if the OL SMC is run at 16 kHz */ - Word32 enerBuffer_fx[CLDFB_NO_CHANNELS_MAX], - Word16 e_enerBuffer, - Word16 fft_buff_fx[2 * L_FFT], - Word16 cor_map_sum_fx, // Q8 - Word16 *Q_new -); -/*! r: number of clipped samples */ -void ivas_initialize_handles_enc( - Encoder_Struct *st_ivas /* i/o: IVAS encoder structure */ -); - -ivas_error ivas_init_encoder( - Encoder_Struct *st_ivas /* i/o: IVAS encoder structure */ -); - -void ivas_destroy_enc( - Encoder_Struct *st_ivas /* i/o: IVAS encoder structure */ -); - -ivas_error ivas_initialize_MD_bstr_enc( - BSTR_ENC_HANDLE *hBstr, /* o : encoder MD bitstream handle */ - Encoder_Struct *st_ivas /* i/o: IVAS encoder structure */ -); - -void ivas_destroy_MD_bstr_enc( - BSTR_ENC_HANDLE *hMetaData /* i/o: encoder MD bitstream handle */ -); - -ivas_error ivas_init_decoder_front( - Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */ -); - -ivas_error ivas_init_decoder( - Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */ -); - -ivas_error ivas_output_buff_dec( - float *p_output_f[], /* i/o: output audio buffers */ - const int16_t nchan_out_buff_old, /* i : previous frame number of output channels*/ - const int16_t nchan_out_buff /* i : number of output channels */ -); -#endif - -ivas_error stereo_dmx_evs_init_encoder( - STEREO_DMX_EVS_ENC_HANDLE *hStereoDmxEVS, /* o : Stereo downmix for EVS encoder handle */ - const int32_t input_Fs /* i : input sampling rate */ -); - -void stereo_dmx_evs_close_encoder( - STEREO_DMX_EVS_ENC_HANDLE *hStereoDmxEVS /* i/o: Stereo downmix for EVS encoder handle */ -); - -ivas_error ivas_dec( - Decoder_Struct *st_ivas, /* i : IVAS decoder structure */ - int16_t *data /* o : output synthesis signal */ -); - - -ivas_error mct_dec_reconfigure( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ - const uint16_t b_nchan_change /* i : flag indicating different channel count */ -); - - -void ivas_mct_dec_close( - MCT_DEC_HANDLE *hMCT /* i/o: MCT decoder structure */ -); - -ivas_error ivas_corecoder_dec_reconfig( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ - const int16_t nSCE_old, /* i : number of SCEs in previous frame */ - int16_t nCPE_old, /* i : number of CPEs in previous frame */ - const int16_t nchan_transport_old, /* i : number of TCs in previous frame */ - const int16_t sba_dirac_stereo_flag_old, /* i : signal stereo rendering using DFT upmix in previous frame */ - const int32_t brate_SCE, /* i : bitrate to be set for the SCEs */ - const int32_t brate_CPE /* i : bitrate to be set for the CPEs */ -); - -ivas_error ivas_hp20_dec_reconfig( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ - const int16_t nchan_hp20_old /* i : number of HP20 filters in previous frame*/ -); - -ivas_error ivas_sce_dec( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ - const int16_t sce_id, /* i : SCE # identifier */ - float *output[1], /* o : output synthesis signal */ - const int16_t output_frame, /* i : output frame length per channel */ - const int16_t nb_bits_metadata /* i : number of metadata bits */ -); - -ivas_error ivas_cpe_dec( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ - const int16_t cpe_id, /* i : CPE # identifier */ - float *output[CPE_CHANNELS], /* o : output synthesis signal */ - const int16_t output_frame, /* i : output frame length per channel */ - const int16_t nb_bits_metadata /* i : number of metadata bits */ -); - -ivas_error ivas_mct_dec( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */ - float *output[], /* o : output synthesis signal */ - const int16_t output_frame, /* i : output frame length per channel */ - const int16_t nb_bits_metadata /* i : number of metadata bits */ -); - -/*! r: number of channels to be synthesised */ - -void copy_decoder_config( - Decoder_Struct *st_ivas, /* i : IVAS decoder structure */ - Decoder_State *st /* o : decoder state structure */ -); - -void destroy_core_dec( - DEC_CORE_HANDLE hCoreCoder /* i/o: core decoder structure */ -); - - -void ivas_initialize_handles_dec( - Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */ -); - -ivas_error ivas_core_enc( - SCE_ENC_HANDLE hSCE, /* i/o: SCE encoder structure */ - CPE_ENC_HANDLE hCPE, /* i/o: CPE encoder structure */ - MCT_ENC_HANDLE hMCT, /* i/o: MCT encoder structure */ - const int16_t n_CoreChannels, /* i : number of core channels to be coded */ - Word16 old_inp_12k8_fx[][L_INP_12k8], /* i : buffer of old input signal */ - Word16 old_inp_16k_fx[][L_INP], /* i : buffer of old input signal */ - Word16 Q_new[], - Word32 ener_fx[], /* i : residual energy from Levinson-Durbin Q6*/ - Word16 A_fx[][NB_SUBFR16k * ( M + 1 )], /* i : A(z) unquantized for the 4 subframes */ - Word16 Aw_fx[][NB_SUBFR16k * ( M + 1 )], /* i : weighted A(z) unquantized for subframes*/ - Word32 epsP_fx[][M + 1], /* i : LP prediction errors epsP_fx_q */ - Word16 epsP_fx_q[], /* i : LP prediction errors */ - Word16 lsp_new[][M], /* i : LSPs at the end of the frame Q15 */ - Word16 lsp_mid[][M], /* i : LSPs in the middle of the frame Q15 */ - const int16_t vad_hover_flag[], /* i : VAD hanglover flag */ - int16_t attack_flag[], /* i : attack flag (GSC or TC) */ - Word32 realBuffer_fx[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], /* i/o: real buffer */ - Word32 imagBuffer_fx[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], /* i/o: imag buffer */ - Word16 *q_re_im_buf, - Word16 old_wsp_fx[][L_WSP], /* i : weighted input signal buffer */ - Word16 e_old_wsp[], - const int16_t loc_harm[], /* i : harmonicity flag */ - const Word16 cor_map_sum[], /* i : speech/music clasif. parameter Q8 */ - const int16_t vad_flag_dtx[], /* i : HE-SAD flag with additional DTX HO */ - Word32 enerBuffer_fx[][CLDFB_NO_CHANNELS_MAX], /* o : energy buffer */ - Word16 enerBuffer_fx_exp[], /* o : energy buffer */ - Word16 fft_buff_fx[][2 * L_FFT], /* i : FFT buffer */ - const int16_t tdm_SM_flag, /* i : channel combination scheme flag */ - const int16_t ivas_format, /* i : IVAS format */ - const int16_t flag_16k_smc /* i : flag to indicate if the OL SMC is run at 16 kHz */ -); - - - -void decod_gen_2sbfr( - Decoder_State *st, /* i/o: decoder static memory */ - const int16_t sharpFlag, /* i : formant sharpening flag */ - const float *Aq, /* i : LP filter coefficient */ - float *pitch_buf, /* o : floating pitch values for each subframe */ - float *voice_factors, /* o : voicing factors */ - float *exc, /* i/o: adapt. excitation exc */ - float *exc2, /* i/o: adapt. excitation/total exc */ - float *bwe_exc, /* o : excitation for SWB TBE */ - float *gain_buf, /* o : floating pitch gain for each subframe */ - const int16_t tdm_Pitch_reuse_flag, /* i : primary channel pitch reuse flag */ - const float tdm_Pri_pitch_buf[] /* i : pitch values for primary channel */ -); - -void synchro_synthesis( - const int32_t ivas_total_brate, /* i : IVAS total bitrate */ - CPE_DEC_HANDLE hCPE, /* i/o: CPE decoder structure */ - float *output[CPE_CHANNELS], /* i/o: output synthesis signal */ - const int16_t output_frame, /* i : Number of samples */ - const int16_t sba_dirac_stereo_flag /* i : signal stereo output for SBA DirAC */ -); - -void synchro_synthesis_fixed( - const int32_t ivas_total_brate, /* i : IVAS total bitrate */ - CPE_DEC_HANDLE hCPE, /* i/o: CPE decoder structure */ - float *output[CPE_CHANNELS], /* i/o: output synthesis signal */ - const int16_t output_frame, /* i : Number of samples */ - const int16_t sba_dirac_stereo_flag /* i : signal stereo output for SBA DirAC */ -); - -void stereo_tcx_init_enc( - Encoder_State *st /* i/o: encoder state structure */ -); - - - - -void stereo_tcx_init_dec( - Decoder_State *st, /* i/o: decoder state structure */ - const int16_t MCT_flag, /* i : hMCT handle allocated (1) or not (0) */ - const int16_t last_element_mode /* i : element mode of previous frame */ -); - -/*! r: S/M decision (0 = speech or noise, 1 = unclear, 2 = music) */ -int16_t ivas_smc_gmm( - Encoder_State *st, /* i/o: encoder state structure */ - STEREO_CLASSIF_HANDLE hStereoClassif, /* i/o: stereo classifier structure */ - const int16_t localVAD_HE_SAD, /* i : HE-SAD flag without hangover */ - const float Etot, /* i : total frame energy */ - const float lsp_new[M], /* i : LSPs in current frame */ - const float cor_map_sum, /* i : correlation map sum (from multi-harmonic anal.) */ - const float epsP[M + 1], /* i : LP prediciton error */ - const float PS[], /* i : energy spectrum */ - const float non_sta, /* i : unbound non-stationarity */ - const float relE, /* i : relative frame energy */ - int16_t *high_lpn_flag, /* i/o: sp/mus LPN flag */ - const int16_t flag_spitch /* i : flag to indicate very short stable pitch */ -); - -void ivas_smc_mode_selection( - Encoder_State *st, /* i/o: encoder state structure */ - const int32_t element_brate, /* i : element bitrate */ - int16_t smc_dec, /* i : raw decision of the 1st stage classifier */ - const float relE, /* i : relative frame energy */ - const float Etot, /* i : total frame energy */ - int16_t *attack_flag, /* i/o: attack flag (GSC or TC) */ - const float *inp, /* i : input signal */ - const float S_map[], /* i : short-term correlation map */ - const int16_t flag_spitch /* i : flag to indicate very short stable pitch */ -); - -/*! r: S/M decision (0=speech or noise,1=unclear,2=music) */ -int16_t ivas_acelp_tcx20_switching( - Encoder_State *st, /* i/o: encoder state structure */ - const float *inp, /* i : new input signal */ - const float *wsp, /* i : input weighted signal */ - const float non_staX, /* i : unbound non-stationarity for sp/mu clas */ - const float *pitch_fr, /* i : fraction pitch values */ - const float *voicing_fr, /* i : fractional voicing values */ - const float currFlatness, /* i : flatness */ - const float lsp_mid[M], /* i : LSPs at the middle of the frame */ - const float stab_fac, /* i : LP filter stability */ - float *res_cod_SNR_M, - const int16_t flag_16k_smc /* i : flag to indicate if the OL SMC is run at 16 kHz */ -); - - - -void ivas_decision_matrix_dec( - Decoder_State *st, /* i/o: decoder state structure */ - int16_t *sharpFlag, /* o : formant sharpening flag */ - int16_t *core_switching_flag, /* o : ACELP->HQ switching frame flag */ - const int32_t element_brate, /* i : element bitrate */ - const int16_t nchan_out /* i : Number of output channels */ -); - -void set_bw_stereo( - CPE_ENC_HANDLE hCPE /* i/o: CPE encoder structures */ -); - -/*! r: flag indicating whether the coded BW has changed */ -int16_t set_bw_mct( - CPE_ENC_HANDLE hCPE[MCT_MAX_BLOCKS], /* i/o: CPE encoder structures */ - const int16_t nCPE /* i : number of CPEs */ -); -void dec_acelp_fast( - Decoder_State *st, /* i/o: decoder state structure */ - const int16_t cdk_index, /* i : codebook index */ - float code[], /* o : algebraic (fixed) codebook excitation */ - const int16_t L_subfr /* i : subframe length */ -); - -void set_transient_stereo( - CPE_ENC_HANDLE hCPE, /* i : CPE structure */ - float currFlatness[] /* i/o: current flatness */ -); - -/*! r: preliminary flag to force ACELP */ -int16_t transient_analysis( - TRAN_DET_HANDLE hTranDet, /* i : handle transient detection */ - const float cor_map_LT[], /* i : LT correlation map */ - const float multi_harm_limit /* i : multi harminic threshold */ -); - -void ivas_post_proc( - SCE_DEC_HANDLE hSCE, /* i/o: SCE decoder structure */ - CPE_DEC_HANDLE hCPE, /* i/o: CPE decoder structure */ - const int16_t n, /* i : channel number */ - float synth[], /* i/o: output synthesis signal */ - float *output[CPE_CHANNELS], /* i/o: output synthesis signal */ - const int16_t output_frame, /* i : output frame length */ - const int16_t sba_dirac_stereo_flag /* i : signal stereo output for SBA DirAC */ -); - -void ivas_renderer_select( - Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */ -); - -ivas_error ivas_mc_enc_config_fx( - Encoder_Struct *st_ivas /* i/o: IVAS encoder structure */ -); - -ivas_error ivas_mc_dec_config( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ - const int16_t idx, /* i : LS config. index */ - uint16_t *nSamplesRendered, /* o : samples flushed from last frame (JBM) */ - int16_t *data /* o : output synthesis signal */ -); - -/*! r: MC format mode (MCT, McMASA, ParamMC) */ -MC_MODE ivas_mc_mode_select( - const MC_LS_SETUP mc_ls_setup, /* i : MC loudspeaker setup */ - const int32_t total_brate /* i : IVAS total bitrate */ -); - -/*! r: number of loudspeaker channels */ -int16_t ivas_mc_ls_setup_get_num_channels( - const MC_LS_SETUP mc_ls_setup /* i : loudspeaker setup (CICP) */ -); - -/*! r: output configuration*/ -AUDIO_CONFIG ivas_mc_map_ls_setup_to_output_config( - const MC_LS_SETUP mc_ls_setup /* i : multi channel loudspeaker setup */ -); - -/*! r: multi channel loudspeaker setup */ -MC_LS_SETUP ivas_mc_map_output_config_to_mc_ls_setup( - const AUDIO_CONFIG output_config /* i : output audio configuration */ -); - -void smooth_dft2td_transition( - CPE_DEC_HANDLE hCPE, /* i/o: CPE decoder structure */ - float *output[CPE_CHANNELS], /* i/o: synthesis @external Fs */ - const int16_t output_frame /* i : output frame length */ -); - - -/*! r: flag indicating a valid bitrate */ -Word16 is_IVAS_bitrate_fx( - const Word32 ivas_total_brate /* i : IVAS total bitrate */ -); - -int16_t is_DTXrate( - const int32_t ivas_total_brate /* i : IVAS total bitrate */ -); - - -void TonalMdctConceal_create_concealment_noise_ivas( - float concealment_noise[L_FRAME48k], - CPE_DEC_HANDLE hCPE, - const int16_t L_frameTCX, - const int16_t L_frame, - const int16_t idchan, - const int16_t subframe_idx, - const int16_t core, - const float crossfade_gain, - const TONALMDCTCONC_NOISE_GEN_MODE noise_gen_mode -); - -void TonalMdctConceal_whiten_noise_shape_ivas( - Decoder_State *st, - const int16_t L_frame, - const TONALMDCTCONC_NOISE_SHAPE_WHITENING_MODE -); - -void dtx_read_padding_bits( - DEC_CORE_HANDLE st, - const int16_t num_bits -); - - - -/*----------------------------------------------------------------------------------* - * JBM prototypes - *----------------------------------------------------------------------------------*/ - - - -ivas_error ivas_jbm_dec_flush_renderer( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ - const int16_t tc_granularity_new, /* i : new renderer granularity */ - const RENDERER_TYPE renderer_type_old, /* i : old renderer type */ - const AUDIO_CONFIG intern_config_old, /* i : old internal config */ - const IVAS_OUTPUT_SETUP_HANDLE hIntSetupOld, /* i : old internal output setup */ - const MC_MODE mc_mode_old, /* i : old MC mode */ - const ISM_MODE ism_mode_old, /* i : old ISM mode */ - uint16_t *nSamplesRendered, /* o : number of samples flushed */ - int16_t *data /* o : output synthesis signal */ -); - -void ivas_jbm_dec_feed_tc_to_renderer( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ - const int16_t nSamplesForRendering, /* i : number of TC samples available for rendering */ - int16_t *nSamplesResidual, /* o : number of samples not fitting into the renderer grid and buffer for the next call*/ - float *data /* i/o: transport channels/output synthesis signal */ -); - -ivas_error ivas_jbm_dec_set_discard_samples( - Decoder_Struct *st_ivas /* i/o: main IVAS decoder structre */ -); - -void ivas_jbm_dec_get_adapted_linear_interpolator( - const int16_t default_interp_length, /* i : default length of the (full-frame) interpolator */ - const int16_t interp_length, /* i : length of the interpolator to be created */ - float *interpolator /* o : the interpolator */ -); - - - -int16_t ivas_jbm_dec_get_num_tc_channels( - Decoder_Struct *st_ivas /* i : IVAS decoder handle */ -); - -void ivas_jbm_dec_copy_tc_no_tsm( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */ - float *tc[], /* i : transport channels */ - const int16_t output_frame /* i : output frame size */ -); - - -TC_BUFFER_MODE ivas_jbm_dec_get_tc_buffer_mode( - Decoder_Struct *st_ivas /* i : IVAS decoder handle */ -); - -/*! r: render granularity */ -int16_t ivas_jbm_dec_get_render_granularity_flt( - const RENDERER_TYPE rendererType, /* i : renderer type */ - const IVAS_FORMAT ivas_format, /* i : ivas format */ - const MC_MODE mc_mode, /* i : MC mode */ - const int32_t output_Fs /* i : sampling rate */ -); - -ivas_error ivas_jbm_dec_tc_buffer_open( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ - const TC_BUFFER_MODE tc_buffer_mode, /* i : buffer mode */ - const int16_t nchan_transport_jbm, /* i : number of real transport channels */ - const int16_t nchan_transport_internal, /* i : number of totally buffered channels */ - const int16_t nchan_full, /* i : number of channels to fully store */ - const int16_t n_samples_granularity /* i : granularity of the renderer/buffer */ -); - -ivas_error ivas_jbm_dec_tc_buffer_reconfigure( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ - const TC_BUFFER_MODE tc_buffer_mode, /* i : new buffer mode */ - const int16_t nchan_transport_jbm, /* i : new number of real transport channels */ - const int16_t nchan_transport_internal, /* i : new number of totally buffered channels */ - const int16_t nchan_full, /* i : new number of channels to fully store */ - const int16_t n_samples_granularity /* i : new granularity of the renderer/buffer */ -); - -void ivas_jbm_dec_tc_buffer_close( - DECODER_TC_BUFFER_HANDLE *phTcBuffer /* i/o: TC buffer handle */ -); - -void ivas_jbm_dec_td_renderers_adapt_subframes( - Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */ -); - -ivas_error ivas_jbm_dec_metadata_open( - Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */ -); - -void ivas_jbm_masa_sf_to_sf_map( - Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */ -); - - -/*----------------------------------------------------------------------------------* - * ISM prototypes - *----------------------------------------------------------------------------------*/ - -void bitbudget_to_brate( - const Word16 x[], /* i : bitbudgets Q0 */ - Word32 y[], /* o : bitrates Q0 */ - const Word16 N /* i : number of entries to be converted */ -); - -void ivas_ism_reset_metadata( - ISM_METADATA_HANDLE hIsmMeta /* i/o: ISM metadata handles */ -); - -void ivas_ism_reset_metadata_enc( - ISM_METADATA_HANDLE hIsmMeta /* i/o: ISM metadata handle */ -); -void ivas_ism_reset_metadata_API( - ISM_METADATA_HANDLE hIsmMeta /* i/o: ISM metadata handles */ -); - -/*! r: index of the winning codeword */ -Word16 ism_quant_meta_fx( - const Word32 val, /* i : scalar value to quantize Q22 */ - Word32 *valQ, /* o : quantized value Q22 */ - const Word32 borders_fx[], /* i : level borders Q22 */ - const Word32 q_step_fx, /* i : quantization step Q22 */ - const Word32 q_step_border_fx, /* i : quantization step at the border Q22 */ - const Word16 cbsize /* i : codebook size */ -); - -ivas_error ivas_ism_metadata_enc_create( - Encoder_Struct *st_ivas, /* i/o: IVAS encoder structure */ - const int16_t n_ISms, /* i : number of objects */ - int32_t element_brate_tmp[] /* o : element bitrate per object */ -); - -ivas_error ivas_ism_metadata_dec_create( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ - const int16_t n_ISms, /* i : number of objects */ - int32_t element_brate_tmp[] /* o : element bitrate per object */ -); - -ivas_error ivas_ism_enc( - Encoder_Struct *st_ivas, /* i/o: IVAS encoder structure */ - float *data[], /* i : input signal [channels][samples] */ - const int16_t input_frame, /* i : input frame length per channel */ - int16_t *nb_bits_metadata, /* i : number of metadata bits */ - const int16_t flag_omasa_ener_brate /* i : less bitrate for objects in OMASA flag */ -); - -ivas_error ivas_ism_metadata_dec( - const int32_t ism_total_brate, /* i : ISM total bitrate */ - const int16_t nchan_ism, /* i : number of ISM channels */ - int16_t *nchan_transport, /* o : number of transport channels */ - ISM_METADATA_HANDLE hIsmMeta[], /* i/o: ISM metadata handles */ - SCE_DEC_HANDLE hSCE[], /* i/o: SCE decoder handles */ - const int16_t bfi, /* i : bfi flag */ - int16_t nb_bits_metadata[], /* o : number of metadata bits */ - ISM_MODE ism_mode, /* i : ISM mode */ - ISM_DTX_DATA_DEC hISMDTX, /* i/o: ISM DTX structure */ - const PARAM_ISM_CONFIG_HANDLE hParamIsm, /* i : Param ISM Config Handle */ - int16_t *ism_extended_metadata_flag, /* i/o: Extended metadata active in renderer */ - int16_t *ism_extmeta_cnt, /* i/o: Number of change frames observed */ - DEC_CORE_HANDLE st0 /* i : core-coder handle */ -); - - -/*----------------------------------------------------------------------------------* - * Parametric ISM prototypes - *----------------------------------------------------------------------------------*/ - -/*! r: ISM format mode */ - -ivas_error ivas_param_ism_enc_open( - Encoder_Struct *st_ivas /* i/o: IVAS encoder structure */ -); - -void ivas_param_ism_enc_close( - PARAM_ISM_CONFIG_HANDLE *hParamIsm, /* i/o: ParamISM handle */ - const int32_t input_Fs /* i : input sampling_rate */ -); - -void ivas_ism_metadata_close( - ISM_METADATA_HANDLE hIsmMetaData[], /* i/o : object metadata handles */ - const int16_t first_idx /* i : index of first handle to deallocate */ -); - - -ivas_error ivas_ism_enc_config( - Encoder_Struct *st_ivas /* i/o: IVAS encoder structure */ -); - - - - -void ivas_param_ism_dec( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ - float *output_f[] /* i/o: synthesized core-coder transport channels/DirAC output */ -); - -void ivas_ism_dec_digest_tc( - Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */ -); - - - -void ivas_param_ism_dec_render( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */ - const uint16_t nSamplesAsked, /* i : number of CLDFB slots requested */ - uint16_t *nSamplesRendered, /* o : number of CLDFB slots rendered */ - uint16_t *nSamplesAvailable, /* o : number of CLDFB slots still to render */ - float *output_f[] /* o : rendered time signal */ -); - -void ivas_param_ism_params_to_masa_param_mapping( - Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */ -); - - -/*----------------------------------------------------------------------------------* - * ISM DTX prototypes - *----------------------------------------------------------------------------------*/ - -ivas_error ivas_ism_dtx_open( - Encoder_Struct *st_ivas /* i/o: IVAS encoder structure */ -); - -/*! r: indication of DTX frame */ -int16_t ivas_ism_dtx_enc( - ISM_DTX_HANDLE hISMDTX, /* i/o: ISM DTX handle */ - SCE_ENC_HANDLE hSCE[MAX_SCE], /* i/o: SCE encoder structure */ - const int32_t ivas_total_brate, /* i : IVAS total bitrate */ - const int16_t nchan_ism, /* i : number of objects */ - const int16_t nchan_transport, /* i : number of transport channels */ - int16_t vad_flag[MAX_NUM_OBJECTS], /* i : VAD flag */ - ISM_METADATA_HANDLE hIsmMeta[], /* i/o: ISM metadata handles */ - int16_t md_diff_flag[], /* o : metadata differential flag */ - int16_t *sid_flag /* o : indication of SID frame */ -); - -void ivas_ism_dtx_dec( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ - int16_t *nb_bits_metadata /* o : number of metadata bits */ -); - -void ivas_ism_metadata_sid_enc( - ISM_DTX_HANDLE hISMDTX, /* i/o: ISM DTX handle */ - const int16_t flag_noisy_speech, /* i : noisy speech flag */ - const int16_t nchan_ism, /* i : number of objects */ - const int16_t nchan_transport, /* i : number of transport channels */ - const ISM_MODE ism_mode, /* i : ISM mode */ - ISM_METADATA_HANDLE hIsmMeta[], /* i/o: ISM metadata handles */ - const int16_t sid_flag, /* i : indication of SID frame */ - const int16_t md_diff_flag[], /* i : metadata differental flag */ - BSTR_ENC_HANDLE hBstr, /* i/o: bitstream handle */ - int16_t nb_bits_metadata[] /* o : number of metadata bits */ -); - -void ivas_ism_metadata_sid_dec( - SCE_DEC_HANDLE hSCE[MAX_SCE], /* i/o: SCE decoder structure */ - const int32_t ism_total_brate, /* i : ISM total bitrate */ - const int16_t bfi, /* i : bfi flag */ - const int16_t nchan_ism, /* i : number of objects */ - const int16_t nchan_transport, /* i : number of transport channels */ - const ISM_MODE ism_mode, /* i : ISM mode */ - int16_t *flag_noisy_speech, /* o : noisy speech flag */ - int16_t *sce_id_dtx, /* o : SCE DTX ID */ - ISM_METADATA_HANDLE hIsmMeta[], /* i/o: ISM metadata handles */ - int16_t nb_bits_metadata[] /* o : number of metadata bits */ -); - - -void ivas_param_ism_compute_noisy_speech_flag( - Encoder_Struct *st_ivas /* i/o: IVAS encoder structure */ -); - - -void update_last_metadata( - const int16_t nchan_ism, /* i : number of objects */ - ISM_METADATA_HANDLE hIsmMeta[], /* i/o: ISM metadata handles */ - const int16_t updt_flag[] /* i : last metadata update flag */ -); - -void ivas_ism_dtx_limit_noise_energy_for_near_silence( - SCE_DEC_HANDLE hSCE[], /* i/o: SCE decoder structures */ - const int16_t sce_id_dtx, /* i : SCE DTX ID */ - const int16_t nchan_transport /* i : number of transport channels */ -); - -/*----------------------------------------------------------------------------------* - * DFT Stereo prototypes - *----------------------------------------------------------------------------------*/ - - -void stereo_dft_enc_analyze( - Encoder_State **sts, /* i/o: encoder state structure */ - const int16_t n_channels, /* i : number of input channels */ - const int16_t input_frame, /* i : input frame length */ - STEREO_DFT_ENC_DATA_HANDLE hStereoDft, /* i/o: encoder DFT stereo handle */ - STEREO_MDCT_ENC_DATA_HANDLE hStereoMdct, /* i/o: encoder MDCT stereo handle */ - float DFT[CPE_CHANNELS][STEREO_DFT_N_MAX_ENC], /* o : DFT buffers */ - float *input_mem[CPE_CHANNELS] /* i/o: input buffer memory */ -); - -float stereo_dft_enc_synthesize( - STEREO_DFT_ENC_DATA_HANDLE hStereoDft, /* i/o: encoder DFT stereo handle */ - float *output, /* o : output synthesis */ - const int16_t chan, /* i : channel number */ - const int32_t input_Fs, /* i : input sampling rate */ - const int32_t output_sampling_rate, /* i : output sampling rate */ - const int16_t L_frame /* i : frame length at internal Fs */ -); - - - - -void stereo_dtf_cng( - CPE_DEC_HANDLE hCPE, /* i/o: CPE decoder structure */ - const int32_t ivas_total_brate, /* i : IVAS total bitrate */ - float DFT[CPE_CHANNELS][STEREO_DFT_BUF_MAX], /* i/o: DFT buffers */ - const int16_t output_frame /* i : output frame size */ -); - -void stereo_dft_cng_side_gain( - STEREO_DFT_ENC_DATA_HANDLE hStereoDft, /* i/o: DFT stereo encoder handle */ - STEREO_CNG_ENC_HANDLE hStereoCng, /* i/o: Stereo CNG data structure */ - const int32_t core_brate, /* i : core bitrate */ - const int32_t last_core_brate, /* i : last core bitrate */ - const int16_t bwidth /* i : audio band-width */ -); - - -void stereo_dft_dequantize_itd( - int16_t *ind, - float *out, - const int32_t output_Fs -); - - - -void stereo_dft_dec_sid_coh( - Decoder_State *st, /* i/o: decoder state structure */ - const int16_t nbands, /* i : number of DFT stereo bands */ - float *coh, /* i/o: coherence */ - int16_t *nb_bits /* i/o: number of bits read */ -); - -ivas_error stereo_dft_dec_create( - STEREO_DFT_DEC_DATA_HANDLE *hStereoDft, /* i/o: decoder DFT stereo handle */ - const int32_t element_brate, /* i : element bitrate */ - const int32_t output_Fs, /* i : output sampling rate */ - const int16_t sba_dirac_stereo_flag, /* i : signal stereo output for SBA DirAC */ - const int16_t nchan_transport /* i : number of transport channels */ -); - -void stereo_dft_dec_reset( - STEREO_DFT_DEC_DATA_HANDLE hStereoDft /* i/o: decoder DFT stereo handle */ -); - -void stereo_dft_dec_update( - STEREO_DFT_DEC_DATA_HANDLE hStereoDft, /* i/o: decoder DFT stereo handle */ - const int16_t output_frame, /* i : output frame length */ - const int16_t sba_dirac_stereo_flag /* i : signal stereo output for SBA DirAC */ -); - -void stereo_dft_dec_destroy( - STEREO_DFT_DEC_DATA_HANDLE *hStereoDft /* i/o: decoder DFT stereo handle */ -); - -void stereo_dft_dec_analyze( - CPE_DEC_HANDLE hCPE, /* i/o: CPE decoder structure */ - const float *input, /* i : input signal */ - float out_DFT[CPE_CHANNELS][STEREO_DFT_BUF_MAX], /* o : DFT buffers */ - const int16_t chan, /* i : channel number */ - const int16_t input_frame, /* i : input frame size */ - const int16_t output_frame, /* i : output frame size */ - const DFT_STEREO_DEC_ANA_TYPE ana_type, /* i : signal type to analyze */ - const int16_t k_offset, /* i : offset of DFT */ - const int16_t delay /* i : delay in samples for input signal */ -); - -void stereo_dft_dec_synthesize( - CPE_DEC_HANDLE hCPE, /* i/o: CPE decoder structure */ - float DFT[CPE_CHANNELS][STEREO_DFT_BUF_MAX], /* i : DFT buffers */ - const int16_t chan, /* i : channel number */ - float output[L_FRAME48k], /* o : output synthesis signal */ - const int16_t output_frame /* i : output frame length */ -); - - -void stereo_dft_res_ecu( - STEREO_DFT_DEC_DATA_HANDLE hStereoDft, /* i/o: Decoder DFT stereo handle */ - float *pDFT_RES, /* i/o: residual signal */ - float *const DFT_PRED_RES, /* i/o: residual prediction signal */ - const int16_t k, /* i : Subframe index */ - const int16_t output_frame, /* i : Output frame length */ - const int16_t prev_bfi, /* i : Previous BFI */ - const float dmx_nrg, /* i : Down-mix energy */ - int16_t *num_plocs, /* i/o: Number of peak locations */ - int16_t *plocs, /* i/o: Peak locations (bin) */ - float *plocsi, /* i/o: Peak locations (fractional) */ - float *input_mem /* o : Residual DFT buffer input mem */ -); - -void stereo_dft_res_subst_spec( - STEREO_DFT_DEC_DATA_HANDLE hStereoDft, /* i/o: Decoder DFT stereo handle */ - float *pDFT_RES, /* i/o: residual signal */ - const float *const DFT_PRED_RES, /* i : residual prediction signal */ - const int16_t time_offs, /* i : Time offset for phase adjustm. */ - const int16_t L_res, /* i : bandwidth of residual signal */ - const int16_t L_ana, /* i : Length of FFT analysis */ - const int16_t k, /* i : Subframe index */ - int16_t *num_plocs, /* i/o: Number of peak locations */ - int16_t *plocs, /* i/o: Peak locations (bin) */ - float *plocsi, /* i/o: Peak locations (fractional) */ - const int16_t analysis_flag /* i : Flag for running peak analysis */ -); - -void stereo_dft_res_ecu_burst_att( - STEREO_DFT_DEC_DATA_HANDLE hStereoDft, /* i/o: Decoder DFT stereo handle */ - float *pDFT_RES, /* i/o: residual signal /att. residual */ - const float dmx_nrg, /* i : dmx energy of current frame */ - const int16_t L_res, /* i : Bandwidth of residual */ - const int16_t L_ana /* i : Length of FFT analysis */ -); - -/*! r: total energy of downmix with maximum swb bandwidth max */ -float stereo_dft_dmx_swb_nrg( - const float *dmx_k0, /* i : first subframe spectrum */ - const float *dmx_k1, /* i : second subframe spectrum */ - const int16_t frame_length /* i : frame lanegth */ -); - -int16_t stereo_dft_sg_recovery( - STEREO_DFT_DEC_DATA_HANDLE hStereoDft /* i/o: Decoder DFT stereo handle */ -); - -void stereo_dft_dec_res( - CPE_DEC_HANDLE hCPE, /* i/o: decoder CPE handle */ - float res_buf[STEREO_DFT_N_8k], /* i : residual buffer */ - float *output /* o : output frame */ -); - -/*! r: Decision to enable or disable BPF on DFT stereo residual */ - -void bpf_pitch_coherence( - Decoder_State *st, /* i/o: decoder state structure */ - const float pitch_buf[] /* i : pitch for each subframe [0,1,2,3] */ -); - -void stereo_dft_dec_read_BS( - const int32_t ivas_total_brate, /* i : IVAS total bitrate */ - const int32_t element_brate, /* i : element bitrate */ - int32_t *total_brate, /* o : total bitrate */ - Decoder_State *st, /* i/o: decoder state structure */ - STEREO_DFT_DEC_DATA_HANDLE hStereoDft, /* i/o: decoder DFT stereo handle */ - const int16_t bwidth, /* i : bandwidth */ - const int16_t output_frame, /* i : output frame length */ - float res_buf[STEREO_DFT_N_8k], /* o : residual buffer */ - int16_t *nb_bits, /* o : number of bits read */ - float *coh, /* i/o: Coherence */ - const int16_t ivas_format /* i : ivas format */ -); - -void stereo_dft_dec_smooth_parameters( - STEREO_DFT_DEC_DATA_HANDLE hStereoDft, /* i/o: decoder DFT stereo handle */ - const int16_t prev_sid_nodata, /* i : Previous SID/No data indicator */ - const int16_t active_frame_counter, /* i : Active frame counter */ - const int32_t element_brate /* i : Element bitrate */ -); - -void stereo_dft_generate_res_pred( - STEREO_DFT_DEC_DATA_HANDLE hStereoDft, /* i/o: decoder DFT stereo handle */ - const float samp_ratio, /* i : sampling ratio */ - float *pDFT_DMX, /* i : downmix signal */ - float *DFT_PRED_RES, /* o : residual prediction signal */ - float *pPredGain, /* i : residual prediction gains */ - const int16_t k, /* i : subframe index */ - float *ap_filt_DMX, /* i : enhanced stereo filling signal */ - int16_t *stop, /* o : last FD stereo filling bin */ - const int16_t bfi /* i : BFI flag */ -); - -void stereo_dft_dec_core_switching( - CPE_DEC_HANDLE hCPE, /* i/o: CPE decoder structure */ - float output[], /* i/o: synthesis @internal Fs */ - float synth[], /* i : synthesis @output Fs */ - float hb_synth[], /* i/o: hb synthesis */ - float DFT[CPE_CHANNELS][STEREO_DFT_BUF_MAX], /* o : DFT buffers */ - const int16_t output_frame, /* i : output frame length */ - const int16_t use_cldfb_for_dft, /* i : flag to use of CLDFB for DFT Stereo */ - const int16_t sba_dirac_stereo_dtx_flag /* i : DTX indicator for SBA DirAC stereo */ -); - -void init_basic_allpass( - basic_allpass_t *ap, /* i/o: basic allpass structure */ - const float *gains, /* i : allpass filter gains */ - const int16_t *delays /* i : allpass filter delays */ -); - -void filter_with_allpass( - const float *sig, /* i : allpass input signal */ - float *out, /* o : filtered output */ - const int16_t len, /* i : length of input */ - basic_allpass_t *ap /* i/o: basic allpass structure */ -); - -/*! r: used GR order */ - -/*! r: used GR order */ - - -/*! r: number of bits written */ - -/*! r: number of bits written */ - - -void stereo_dft_enc_compute_itd( - CPE_ENC_HANDLE hCPE, /* i/o: CPE encoder structure */ - float *DFT_L, - float *DFT_R, - const int16_t k_offset, - const int16_t input_frame, - const int16_t vad_flag_dtx[], - const int16_t vad_hover_flag[], - float *bin_nrgL, - float *bin_nrgR -); - -void stereo_dft_config( - STEREO_DFT_CONFIG_DATA_HANDLE hConfig, /* o : DFT stereo configuration */ - const int32_t brate, /* i : IVAS/CPE/nominal total bitrate */ - int16_t *bits_frame_nominal, /* o : primary channel nominal bits per frame */ - int16_t *bits_frame_nominal_2 /* o : secondary channel nominal bits per frame*/ -); - -int16_t stereo_dft_band_config( - int16_t *band_limits, /* o : DFT band limits */ - const int16_t band_res, /* i : DFT band resolution */ - const int16_t NFFT, /* i : analysis/synthesis window length */ - const int16_t enc_dec /* i : flag to indicate enc vs dec */ -); - -void stereo_dft_dmx_out_reset( - STEREO_DFT_DMX_DATA_HANDLE hStereoDftDmx /* i/o: DFT stereo DMX decoder */ -); - -void stereo_dft_unify_dmx( - STEREO_DFT_DEC_DATA_HANDLE hStereoDft, /* i/o: decoder stereo handle */ - Decoder_State *st0, /* i/o: decoder state structure */ - float DFT[CPE_CHANNELS][STEREO_DFT_BUF_MAX], /* i/o: DFT buffers */ - float *input_mem, /* i/o: mem of buffer DFT analysis */ - const int16_t prev_sid_nodata /* i : Previous SID/No data indicator */ -); - -void add_HB_to_mono_dmx( - CPE_DEC_HANDLE hCPE, /* i/o: CPE decoder structure */ - float output[L_FRAME48k], /* i/o: output synthesis */ - float outputHB[L_FRAME48k], /* i : HB synthesis */ - const int16_t last_core, /* i : last core, primary channel */ - const int16_t output_frame /* i : frame length */ -); - -/*----------------------------------------------------------------------------------* - * Range Coder prototypes - *----------------------------------------------------------------------------------*/ - -void rc_uni_enc_init( - RangeUniEncState *rc_st_enc /* i/o: RC state handle */ -); - -void rc_uni_enc_encode_fast( - RangeUniEncState *rc_st_enc, /* i/o: RC state handle */ - const uint16_t cum_freq, /* i : Cumulative frequency up to symbol */ - const uint16_t sym_freq, /* i : Symbol frequency */ - const uint16_t tot_shift /* i : Total frequency as a power of 2 */ -); - -void rc_uni_enc_encode_symbol_fastS( - RangeUniEncState *rc_st_enc, /* i/o: Encoder state */ - const uint16_t symbol, /* i : Symbol to encode */ - const uint16_t cum_freq[], /* i : Cumulative frequency up to symbol */ - const uint16_t sym_freq[], /* i : Symbol frequency */ - const uint16_t tot_shift /* i : Total frequency as a power of 2 */ -); - -void rc_uni_enc_encode_bits( - RangeUniEncState *rc_st_enc, /* i/o: RC state handle */ - const uint16_t value, /* i : Value to encode */ - const int16_t bits /* i : Number of bits */ -); - -/*! r: Total number of bits produced */ -int16_t rc_uni_enc_virtual_finish( - RangeUniEncState *rc_st_enc /* i : RC state handle */ -); - -/*! r: Total number of bits produced */ -int16_t rc_uni_enc_finish( - RangeUniEncState *rc_st_enc /* i/o: RC state handle */ -); - -void rc_uni_dec_init( - RangeUniDecState *rc_st_dec, /* i/o: RC state handle */ - uint16_t *bit_buffer, /* i : Bit buffer */ - const int16_t max_available_bits /* i : Total maximum bits available */ -); - -/*! r: Read symbol */ -uint16_t rc_uni_dec_read_symbol_fastS( - RangeUniDecState *rc_st_dec, /* i/o: Decoder State */ - const uint16_t cum_freq_table[], /* i : Cumulative frequency up to symbol */ - const uint16_t sym_freq_table[], /* i : Symbol frequency */ - const uint16_t alphabet_size, /* i : Number of symbols in the alphabet */ - const uint16_t tot_shift /* i : Total frequency as a power of 2 */ -); - -/*! r: Read bit */ -uint16_t rc_uni_dec_read_bit( - RangeUniDecState *rc_st_dec /* i/o: RC state handle */ -); - -/*! r: Read bit */ -uint16_t rc_uni_dec_read_bit_prob_fast( - RangeUniDecState *rc_st_dec, /* i/o: RC state handle */ - const int16_t freq0, /* i : Frequency for symbol 0 */ - const uint16_t tot_shift /* i : Total frequency as a power of 2 */ -); - -/*! r: Read bits */ -uint16_t rc_uni_dec_read_bits( - RangeUniDecState *rc_st_dec, /* i/o: RC state handle */ - const int16_t bits /* i : Number of bits */ -); - -/*! r: Total number of bits consumed */ -int16_t rc_uni_dec_virtual_finish( - RangeUniDecState *rc_st_dec /* i/o: RC state handle */ -); - -/*! r: Total number of bits consumed */ -int16_t rc_uni_dec_finish( - RangeUniDecState *rc_st_dec /* i/o: RC state handle */ -); - - -/*----------------------------------------------------------------------------------* - * ECLVQ Stereo prototypes - *----------------------------------------------------------------------------------*/ - -float ECSQ_dequantize_gain( - const int16_t index -); - - - -void ECSQ_init_instance( - ECSQ_instance *ecsq_inst, - const int16_t config_index, - void *ac_handle -); - - - -void ECSQ_dequantize_vector( - const int16_t *input, - const float global_gain, - const int16_t N, - float *output -); - - -/*----------------------------------------------------------------------------------* - * ICA Stereo prototypes - *----------------------------------------------------------------------------------*/ - -void stereo_tca_init_enc( - STEREO_TCA_ENC_HANDLE hStereoTCA, /* i/o: Stereo TCA encoder handle */ - const int32_t input_Fs /* i : input sampling frequency */ -); - -void stereo_tca_enc( - CPE_ENC_HANDLE hCPE, /* i : CPE encoder structure */ - const int16_t input_frame /* i : length of a frame per channel */ -); - -void stereo_tca_init_dec( - STEREO_TCA_DEC_HANDLE hStereoTCA /* i/o: Stereo TCA handle */ -); - -void stereo_tca_dec( - CPE_DEC_HANDLE hCPE, /* i/o: CPE decoder structure */ - float *synth[CPE_CHANNELS], /* i/o: output synth */ - const int16_t output_frame /* i : length of a frame per channel */ -); - -void stereo_tca_scale_R_channel( - CPE_DEC_HANDLE hCPE, /* i/o: CPE decoder structure */ - float *output, /* i/o: output synthesis, R channel */ - const int16_t output_frame /* i : frame length */ -); - -void adjustTargetSignal( - float *target, - const int16_t prevShift, - const int16_t currShift, - const int16_t L_shift_adapt, - const int16_t method -); - -/*----------------------------------------------------------------------------------* - * IC-BWE Stereo prototypes - *----------------------------------------------------------------------------------*/ - - -void stereo_icBWE_preproc( - CPE_ENC_HANDLE hCPE, /* i/o: CPE encoder structure */ - const int16_t input_frame, /* i : input frame length */ - float shb_speech_nonref[] /* o : SHB speech non-ref channel */ -); - -void stereo_icBWE_enc( - CPE_ENC_HANDLE hCPE, /* i/o: CPE encoder structure */ - const float shb_speech_ref[], /* i : SHB speech ref channel */ - float shb_speech_nonref[], /* i/o: SHB speech non-ref channel */ - const float *voice_factors /* i : voicing factors */ -); - -void stereo_icBWE_init_dec( - STEREO_ICBWE_DEC_HANDLE hStereoICBWE /* i/o: Stereo inter-channel BWE handle */ -); - -void stereo_icBWE_dec( - CPE_DEC_HANDLE hCPE, /* i/o: CPE decoder structure */ - float *synthRef, /* i/o: Reference channel HB synthesis at output Fs */ - float *synth, /* o : Non reference channel HB synthesis at output Fs */ - const float *fb_synth_ref, /* i : ref. high-band synthesis 16-20 kHz */ - const float *voice_factors, /* i : voicing factors */ - const int16_t output_frame /* i : frame length */ -); - -void stereo_icBWE_decproc( - CPE_DEC_HANDLE hCPE, /* i/o: CPE decoder structure */ - float *output[CPE_CHANNELS], /* i/o: output symthesis */ - float outputHB[CPE_CHANNELS][L_FRAME48k], /* i : HB synthesis */ - const int16_t last_core, /* i : last core, primary channel */ - const int16_t last_bwidth, /* i : last bandwidth */ - const int16_t output_frame /* i : frame length */ -); - - -/*----------------------------------------------------------------------------------* - * Stereo classifiers prototypes - *----------------------------------------------------------------------------------*/ - -/*! r: element mode */ -int16_t select_stereo_mode( - CPE_ENC_HANDLE hCPE, /* i/o: CPE encoder structure */ - const IVAS_FORMAT ivas_format /* i : IVAS format */ -); - - -void stereo_classifier_features( - STEREO_CLASSIF_HANDLE hStereoClassif, /* i/o: stereo classifier structure */ - const int16_t idchan, /* i : channel ID */ - const int16_t element_mode, /* i : element mode */ - const int16_t vad_flag, /* i : VAD flag */ - const float lsf_new[], /* i : LSFs at the end of the frame */ - const float epsP[], /* i : LP analysis residual energies for each iteration*/ - const int16_t pitch[], /* i : open-loop pitch values for quantiz. */ - const float voicing[], /* i : OL maximum normalized correlation */ - const float cor_map_sum, /* i : speech/music clasif. parameter */ - const float non_staX, /* i : unbound non-stationarity for sp/mu clas. */ - const float sp_div, /* i : spectral diversity feature */ - const int16_t clas /* i : signal class */ -); - - -void xtalk_classifier_dft( - CPE_ENC_HANDLE hCPE, /* i/o: CPE encoder structure */ - const int16_t itd, /* i : ITD from DFT stereo - used as a feature */ - const float gcc_phat[] /* i : GPHAT cross-channel correlation function */ -); - -/*----------------------------------------------------------------------------------* - * TD Stereo prototypes - *----------------------------------------------------------------------------------*/ - -void stereo_td_init_enc( - STEREO_TD_ENC_DATA_HANDLE hStereoTD, /* i/o: TD stereo encoder handle */ - const int16_t last_element_mode /* i : last element mode */ -); - - - -void stereo_tdm_downmix( - STEREO_TD_ENC_DATA_HANDLE hStereoTD, /* i : TD stereo IVAS encoder structure */ - float *Left_in, /* i/o: Left channel -> Primary channel */ - float *Right_in, /* i/o: Right channel -> Secondary channel */ - const int16_t input_frame, /* i : Number of samples */ - const int16_t tdm_ratio_idx, /* i : TDM ratio index */ - const int16_t tdm_SM_flag, /* i : channel combination scheme flag */ - const int16_t tdm_ratio_idx_SM /* i : TDM ratio index for SM mode */ -); - -void stereo_td_init_dec( - STEREO_TD_DEC_DATA_HANDLE hStereoTD, /* i/o: TD stereo decoder handle */ - const int16_t last_element_mode /* i : last element mode */ -); - -void tdm_configure_dec( - const int16_t ivas_format, /* i : IVAS format */ - const int16_t ism_mode, /* i : ISM mode in combined format */ - CPE_DEC_HANDLE hCPE, /* i/o: CPE decoder structure */ - int16_t *tdm_ratio_idx, /* o : ratio index */ - const int16_t nb_bits_metadata /* i : number of metadata bits */ -); - -void tdm_upmix_plain( - float Left[], /* o : left channel */ - float Right[], /* o : right channel */ - const float PCh_2_L[], /* i : primary channel */ - const float SCh_2_R[], /* i : secondary channel */ - const float LR_ratio, /* i : mixing ratio */ - const float inv_den_LR_ratio, /* i : inverse mixing ration */ - const int16_t start_index, /* i : start index */ - const int16_t end_index, /* i : end index */ - const int16_t plus_minus_flag /* i : plus/minus flag */ -); - -void stereo_tdm_combine( - CPE_DEC_HANDLE hCPE, /* i/o: CPE decoder structure */ - float *PCh_2_L, /* i/o: Primary channel -> output as L channel */ - float *SCh_2_R, /* i/o: Seconday channel -> output as R channel */ - const int16_t output_frame, /* i : Number of samples */ - const int16_t flag_HB, /* i : flag to distinguish between core (0) and HB (1) synthesis */ - const int16_t tdm_ratio_idx /* i : TDM ratio index */ -); - -/*! r: replication decision; 1 = Use old LP */ -void tdm_ol_pitch_comparison( - CPE_ENC_HANDLE hCPE, /* i : CPE encoder structure */ - float pitch_fr[CPE_CHANNELS][NB_SUBFR], /* i/o: fractional pitch values */ - float voicing_fr[CPE_CHANNELS][NB_SUBFR] /* i/o: fractional pitch gains */ -); - -void tdm_configure_enc( - const int16_t ivas_format, /* i : IVAS format */ - const int16_t ism_mode, /* i : ISM mode in combined format */ - CPE_ENC_HANDLE hCPE, /* i : CPE encoder structure */ - const float Etot_last[CPE_CHANNELS], /* i/o: Energy of last frame */ - const int16_t tdm_SM_or_LRTD_Pri, /* i : channel combination scheme flag in TD stereo OR LRTD primary channel */ - const int16_t tdm_ratio_idx, /* i : ratio index */ - const int16_t tdm_ratio_idx_SM, /* i : ratio index in SM mode */ - const int16_t attack_flag, /* i : Primary channel attack flag */ - const int16_t nb_bits_metadata /* i : number of metadata bits */ -); - - -void tdm_bit_alloc( - const int16_t ivas_format, /* i : IVAS format */ - const int16_t ism_mode, /* i : ISM mode in combined format */ - const int32_t element_brate_wo_meta, /* i : element bitrate without metadata */ - const int16_t tdm_lp_reuse_flag, /* i : LPC reusage flag */ - int32_t *total_brate_pri, /* o : Allocated primary channel bitrate */ - int32_t *total_brate_sec, /* o : Allocated secondary channel bitrate */ - int16_t *tdm_low_rate_mode, /* o : secondary channel low rate mode flag */ - const int16_t coder_type, /* i : secondary channel coder type */ - const int16_t ener_ratio_idx, /* i : correlation ratio indexe */ - const int16_t tdm_Pitch_reuse_flag, /* i : primary channel pitch reuse flag */ - const int16_t bwidth_pri, /* i : bandwidth of the primary channel */ - const int16_t bwidth_sec, /* i : bandwidth of the secondary channel */ - const int16_t flag_ACELP16k_pri, /* i : ACELP@16kHz core flag, primary chan. */ - const int16_t tdm_LRTD_flag, /* i : LRTD stereo mode flag */ - const int16_t coder_type0, /* i : coder type (temporary in the encoder, from bitstream in decoder) */ - const int16_t tdm_inst_ratio_idx /* i : instantaneous correlation ratio index */ -); - - -/*! r: value of the indice */ -uint16_t get_indice_st( - Decoder_State *st, /* i/o: decoder state structure */ - const int32_t element_brate, /* i : element bitrate */ - const int16_t pos, /* i : absolute position in the bitstream */ - const int16_t nb_bits /* i : number of bits to quantize the indice */ -); - -void tdm_low_rate_dec( - Decoder_State *st, /* i/o: decoder static memory */ - float dct_epit[], /* o : GSC excitation in DCT domain */ - float *tmp_noise, /* o : long term temporary noise energy */ - float *pitch_buf, /* o : floating pitch values for each subframe */ - float *voice_factors, /* o : voicing factors */ - float *exc, /* i/o: adapt. excitation exc */ - float *exc2, /* i/o: adapt. excitation/total exc */ - float *bwe_exc, /* o : excitation for SWB TBE */ - const float *lsf_new /* i : ISFs at the end of the frame */ -); - -void tdm_SCh_LSF_intra_pred( - const int32_t element_brate, /* i : element bitrate */ - const float *tdm_lsfQ_PCh, /* i : primary channel LSFs */ - float *pred_lsf_SCh /* o : predicted secondary channel LSFs */ -); - - -void first_VQstages( - const float *const *cb, - const float u[], /* i : vector to be encoded (prediction and mean removed) */ - const int16_t *levels, /* i : number of levels in each stage */ - const int16_t stagesVQ, /* i : number of stages */ - const float w[], /* i : weights */ - const int16_t N, /* i : vector dimension */ - const int16_t max_inner, /* i : maximum number of swaps in inner loop */ - int16_t indices_VQstage[] -); - - -void deindex_lvq_SHB( - UWord32 index, - float *out, - const int16_t nbits, - const int16_t mode -); - -/*----------------------------------------------------------------------------------* - * MDCT Stereo prototypes - *----------------------------------------------------------------------------------*/ - -void stereo_td_itd_mdct_stereo( - CPE_ENC_HANDLE hCPE, /* i/o: CPE encoder handle */ - const int16_t vad_flag_dtx[], /* i : VAD dtx flags */ - const int16_t vad_hover_flag[], /* i : VAD hangover flags */ - const int16_t input_frame /* i : frame length */ -); - -void QuantizeTCXSpectrum( - Encoder_State *st, /* i : state handle */ - const int16_t frame_cnt, /* i : frame counter in the super_frame */ - const float *x_orig, /* i : shaped MDCT spectrum */ - const float *gainlpc, /* i : FDNS gains */ - const Word16 *Aqind, /* i : frame-independent quantized coefficients (M+1) */ - const int16_t tnsSize, /* i : number of tns parameters put into prm */ - const int16_t nb_bits, /* i : bit budget */ - const int16_t vad_hover_flag, /* i : VAD hangover flag */ - int16_t *pL_frameTCX, /* o : full frame length */ - int16_t *pL_frame, /* o : frame length */ - int16_t *pL_spec, /* o : length of the coded spectrum */ - int16_t *ptcx_offset, /* o : folding point offset relative to the end of the previous frame */ - int16_t *pnoiseFillingBorder, /* o : noise filling border */ - float spectrum[], /* o : quantized MDCT spectrum */ - CONTEXT_HM_CONFIG *hm_cfg, /* o : Context-based harmonic model configuration */ - int16_t *hm_active, /* o : flag indicating if the harmonic model is active */ - float lf_deemph_fact[], /* o : low frequency deemphasis factors */ - int16_t *nf_seed, /* o : noise filling random seed */ - float *ener, /* o : energy of the quantized spectrum */ - float *gain_tcx, /* o : global gain */ - int16_t prm[] /* o : tcx parameters */ -); - -void EstimateStereoTCXNoiseLevel( - Encoder_State **sts, /* i : state handle */ - float *q_spectrum[CPE_CHANNELS][NB_DIV], /* i : quantized MDCT spectrum */ - float gain_tcx[][NB_DIV], /* i : global gain */ - int16_t L_frame[][NB_DIV], /* i : frame length */ - int16_t noiseFillingBorder[][NB_DIV], /* i : noise filling border */ - int16_t hm_active[][NB_DIV], /* i : flag indicating if the harmonic model is active */ - const int16_t ignore_chan[], /* i : flag indicating whether the channel should be ignored */ - float fac_ns[][NB_DIV], /* o : noise filling level */ - int16_t param_core[][NB_DIV * NPRM_DIV], /* o : quantized noise filling level */ - const int16_t MCT_flag /* i : hMCT handle allocated (1) or not (0) */ -); - -void TNSAnalysisStereo( - Encoder_State **sts, /* i : state handle */ - float *mdst_spectrum[CPE_CHANNELS][NB_DIV], /* o : MDST spectrum */ - const int16_t bWhitenedDomain, /* i : whitened domain flag */ - int16_t tnsSize[CPE_CHANNELS][NB_DIV], /* i : number of tns parameters put into prm */ - int16_t tnsBits[CPE_CHANNELS][NB_DIV], /* i : number of tns bits in the frame */ - int16_t param_core[][NB_DIV * NPRM_DIV], /* o : quantized noise filling level */ - const int16_t mct_on /* i : flag mct block (1) or stereo (0) */ -); - -void InternalTCXDecoder( - Encoder_State *st, /* i/o: state handle */ - const int16_t frame_cnt, /* i : frame counter in the super_frame */ - const int16_t L_frameTCX, /* i : full frame length */ - const int16_t L_frame, /* i : frame length */ - const int16_t L_spec, /* i : length of the coded spectrum */ - const int16_t tcx_offset, /* i : folding point offset relative to the end of the previous frame */ - const int16_t noiseFillingBorder, /* i : noise filling border */ - const float *x_quant, /* i : quantized spectrum */ - const float ener, /* i : energy of the quantized spectrum */ - float lf_deemph_fact[], /* i/o: low frequency deemphasis factors */ - const float fac_ns, /* i : noise filling level */ - const int16_t nf_seed, /* i : noise filling random seed */ - const float *A, /* i : LPC representation of the FDNS gains */ - float *gainlpc, /* i/o: FDNS gains */ - const int16_t hm_active, /* i : flag indicating if the harmonic model is active */ - float gain_tcx, /* i/o: global gain / quantized global gain */ - float spectrum[], /* o : dequantized spectrum */ - float synth[], /* o : time domain signal */ - int16_t *gain_tcx_q /* o : quantized global gain (at low bitrates) */ -); - -void stereo_mdct_core_enc_fx( - CPE_ENC_HANDLE hCPE, /* i/o: CPE encoder structure */ - Word16 new_samples[CPE_CHANNELS][L_INP], /* i : new samples */ - Word16 old_wsp[CPE_CHANNELS][L_WSP], /* i : 12.8kHz weighted speech (for LTP */ - Word16 pitch_buf_fx[CPE_CHANNELS][NB_SUBFR16k] /* o : floating pitch for each subframe */ -); - -void initMdctStereoEncData( - STEREO_MDCT_ENC_DATA *hStereoMdct, /* i/o: mdct stereo parameters structure */ - const IVAS_FORMAT ivas_format, /* i : IVAS format */ - const int16_t element_mode, /* i : element mode */ - const int32_t element_brate, /* i : element bitrate */ - const int16_t bwidth, /* i : bandwidth */ - const int16_t igf, /* i : flag indicating IGF activity */ - const H_IGF_GRID hIgfGrid, /* i : IGF grid setup */ - const int16_t mem_init /* i : initialize memory after malloc */ -); - -ivas_error initMdctItdHandling( - STEREO_MDCT_ENC_DATA *hStereoMdct, /* i/o: mdct stereo parameters structure */ - const int32_t input_Fs /* i : input sampling rate */ -); - -void stereo_mdct_enc_destroy( - STEREO_MDCT_ENC_DATA_HANDLE *hStereoMdct /* i/o: encoder MDCT stereo handle */ -); - -void initMdctStereoDecData( - STEREO_MDCT_DEC_DATA *hStereoMdct, /* i/o: mdct stereo parameters structure */ - const int16_t igf, /* i : flag indicating IGF activity */ - const H_IGF_GRID igfGrid, /* i : IGF grid configuration */ - const int32_t element_brate, /* i : element bitrate */ - const int16_t bwidth /* i : audio bandwidth */ -); - -void stereo_mdct_init_bands( - const int16_t L_frame, /* i : frame length */ - const int16_t tmp_tcx_mode, /* i : tcx mode (TCX10, TCX 20), -1 if transition frame */ - const int32_t element_brate, /* i : element bitrate */ - const int16_t igf, /* i : flag indicating if IGF is used */ - const H_IGF_GRID hIgfGrid, /* i : IGF grid setup */ - int16_t *sfbOffset, /* o : sfb offset table */ - int16_t *sfbCnt /* o : number of sfbs */ -); - -void stereo_mdct_init_igf_start_band( - STEREO_MDCT_BAND_PARAMETERS *stbParams, /* i/o: stereo frequency band parameters */ - const float transFac, /* i : transform factor */ - const int16_t bwidth, /* i : audio bandwidth */ - const int32_t element_brate /* i : element bitrate */ -); - -void init_tcx_enc_info( - Encoder_State *st, /* i : coder memory state */ - int16_t *L_frame, - int16_t *L_frameTCX, - int16_t *L_spec -); - -void decoder_tcx_invQ( - Decoder_State *st, /* i/o: coder memory state */ - int16_t prm[], /* i : parameters */ - float A[], /* i : coefficients NxAz[M+1] */ - Word16 Aind[], /* i : frame-independent coefficients Az[M+1] */ - const int16_t L_spec, - const int16_t L_frame, - const int16_t L_frameTCX, - float x[], - float gainlpc2[], - float xn_buf[], - int16_t *fUseTns, /* o : flag that is set if TNS data is present */ - STnsData *tnsData, - float *gain_tcx, - const int16_t **prm_sqQ, - int16_t *nf_seed, - const int16_t bfi, /* i : Bad frame indicator */ - const int16_t frame_cnt /* i : frame counter in the super frame */ -); - -void decoder_tcx_noisefilling( - Decoder_State *st, /* i/o: coder memory state */ - float concealment_noise[L_FRAME48k], - const float A[], /* i : coefficients NxAz[M+1] */ - const int16_t L_frameTCX_glob, - const int16_t L_spec, - const int16_t L_frame, - const int16_t L_frameTCX, - float x[], - float gainlpc2[], - int16_t *temp_concealment_method, - const float gain_tcx, - const int16_t *prm_sqQ, - int16_t nf_seed, - const int16_t bfi, /* i : Bad frame indicator */ - const int16_t MCT_flag, /* i : hMCT handle allocated (1) or not (0) */ - const int16_t frame_cnt /* i : frame counter in the super frame */ -); - -void decoder_tcx_noiseshaping_igf( - Decoder_State *st, /* i/o: coder memory state */ - const int16_t L_spec, - const int16_t L_frame, - const int16_t L_frameTCX, - const int16_t left_rect, - float x[], - const float gainlpc2[], - int16_t *temp_concealment_method, - const int16_t bfi /* i : Bad frame indicator */ -); - -void decoder_tcx_tns( - Decoder_State *st, /* i/o: coder memory state */ - const int16_t L_frame_glob, - const int16_t L_spec, - const int16_t L_frame, - const int16_t L_frameTCX, - float x[N_MAX], - const int16_t fUseTns, /* i : flag that is set if TNS data is present */ - STnsData *tnsData, - const int16_t bfi, /* i : Bad frame indicator */ - const int16_t frame_cnt, /* i : frame counter in the super frame */ - const int16_t whitenedDomain -); - -void decoder_tcx_imdct( - Decoder_State *st, /* i/o: coder memory state */ - const int16_t L_frame_glob, /* i : frame length */ - const int16_t L_frameTCX_glob, - const int16_t L_spec, - const int16_t tcx_offset, - const int16_t tcx_offsetFB, - const int16_t L_frame, - const int16_t L_frameTCX, - const int16_t left_rect, - float x[N_MAX], - float xn_buf[], - const uint16_t kernelType, /* i : TCX transform kernel type */ - const int16_t fUseTns, /* i : flag that is set if TNS data is present */ - float synth[], /* i/o: synth[-M..L_frame] */ - float synthFB[], - const int16_t bfi, /* i : Bad frame indicator */ - const int16_t frame_cnt, /* i : frame counter in the super frame */ - const int16_t sba_dirac_stereo_flag /* i : signal stereo output for SBA DirAC */ -); - -void init_tcx_info( - Decoder_State *st, /* i/o: coder memory state */ - const int16_t L_frame_glob, /* i : global frame length */ - const int16_t L_frameTCX_glob, /* i : FB global frame length */ - const int16_t frame_cnt, /* i : frame counter in the super_frame */ - const int16_t bfi, /* i : bad frame indicator */ - int16_t *tcx_offset, /* o : folding point offset relative to the end of the previous frame */ - int16_t *tcx_offsetFB, /* o : FB folding point offset relative to the end of the previous frame*/ - int16_t *L_frame, /* o : frame length */ - int16_t *L_frameTCX, /* o : TCX frame length */ - int16_t *left_rect, /* o : left part is rectangular */ - int16_t *L_spec /* o : spectrum length */ -); - -void decoder_tcx_IGF_mono( - Decoder_State *st, /* i/o: coder memory state */ - float x[], /* o : de-quatized coefficients */ - const int16_t L_frame, /* i : frame length */ - const int16_t left_rect, /* i : left part is rectangular */ - const int16_t bfi, /* i : bad frame indicator */ - const int16_t frame_cnt /* i : frame counter in the super_frame */ -); - -void decoder_tcx_IGF_stereo( - Decoder_State **sts, /* i/o: coder memory states */ - STEREO_MDCT_DEC_DATA_HANDLE hStereoMdct, /* i/o: MDCT stereo structure */ - int16_t ms_mask[NB_DIV][MAX_SFB], /* i : bandwise MS mask */ - float *x[CPE_CHANNELS][NB_DIV], /* o : de-quatized coefficients */ - const int16_t L_frame, /* i : frame length */ - const int16_t left_rect, /* i : left part is rectangular */ - const int16_t k, /* i : Subframe index */ - const int16_t bfi, /* i : bad frame indicator */ - const int16_t MCT_flag /* i : hMCT handle allocated (1) or not (0) */ -); - -void ms_processing( - STEREO_MDCT_ENC_DATA_HANDLE hStereoMdct, /* i/o: MDCT encoder structure */ - Encoder_State **sts, /* i/o: Encoder state structure */ - int16_t ms_mask[NB_DIV][MAX_SFB], /* i : bandwise MS mask */ - const int16_t iSubframe, /* i : subframe number */ - float x_0[], /* i/o: spectrum 1 */ - float x_1[], /* i/o: spectrum 2 */ - int16_t maxSfb /* i : number of stereo frequency bands */ -); - -void ms_inv_mask_processing( - STEREO_MDCT_ENC_DATA_HANDLE hStereoMdct, /* i/o: MDCT encoder structure */ - Encoder_State **sts, /* i/o: Encoder state structure */ - int16_t ms_mask[NB_DIV][MAX_SFB], /* i : bandwise MS mask */ - const int16_t iSubframe, /* i : subframe number */ - const float x_0[], /* i : spectrum 1 */ - const float x_1[], /* i : spectrum 2 */ - float x_inv_0[], /* o : inverse spectrum 1 */ - float x_inv_1[], /* o : inverse spectrum 2 */ - int16_t maxSfb /* i : number of stereo frequency bands */ -); - -void IGFDecApplyStereo_flt( - const IGF_DEC_INSTANCE_HANDLE hIGFDecL, /* i : instance handle of IGF Decoder */ - const IGF_DEC_INSTANCE_HANDLE hIGFDecR, /* i : instance handle of IGF Decoder */ - float *spectrumL, /* i/o: L MDCT spectrum */ - float *spectrumR, /* i/o: R MDCT spectrum */ - const int16_t igfGridIdx, /* i : in case of CELP->TCX switching, use 1.25 framelength */ - const int16_t *coreMsMask, - const int16_t restrict_hopsize, - const int16_t bfi, /* i : frame loss == 1, frame good == 0 */ - const int16_t bfi_apply_damping /* i : decoder element mode */ -); - -void IGFEncStereoEncoder( - STEREO_MDCT_BAND_PARAMETERS *sfbParam, /* i/o: sfb parameters for the right channel */ - const IGF_ENC_INSTANCE_HANDLE hIGFEnc, /* i : IGF handle */ - const float *mdctSpectrumL, /* i : left spectrum */ - const float *mdctSpectrumR, /* i : right spectrum */ - int16_t *msMask, /* i/o: MS mask */ - int16_t *igfStereoMode, /* o : IGF stereo mode */ - const int16_t mdct_stereo_mode, /* i : MDCT stereo mode */ - const int16_t isTCX20, /* i : flag for indicating TCX20 */ - const int16_t isTransition /* i : flag for transtition */ -); - -void IGFDecReplicateTCX10State_flt( - IGF_DEC_INSTANCE_HANDLE hIGFDec /* i/o: instance handle of IGF Decoder */ -); - - -void InitPsychLPC( - const int32_t sr_core, /* i : sampling rate of core-coder */ - const int16_t L_frame, /* i : frame length */ - const TCX_CONFIG_HANDLE hTcxCfg /* i : TCX configuration handle */ -); - - -void stereo_coder_tcx( - STEREO_MDCT_ENC_DATA_HANDLE hStereoMdct, /* i/o: MDCT encoder structure */ - Encoder_State **sts, /* i/o: encoder state structure */ - int16_t ms_mask[NB_DIV][MAX_SFB], /* i : bandwise MS mask */ - float *mdst_spectrum[CPE_CHANNELS][NB_DIV], /* i/o: MDST spectrum */ - float *inv_spectrum[CPE_CHANNELS][NB_DIV], /* i/o: inverse spectrum */ - float *inv_mdst_spectrum[CPE_CHANNELS][NB_DIV], /* i/o: inverse MDST spectrum */ - const int16_t mct_on /* i : flag mct block (1) or stereo (0) */ -); - -void stereo_decoder_tcx( - STEREO_MDCT_DEC_DATA *hStereoMdct, /* i/o: MDCT stereo decoder structure */ - int16_t ms_mask[NB_DIV][MAX_SFB], /* i : bandwise MS mask */ - float *spec_r_0[NB_DIV], /* i/o: spectrum right channel */ - float *spec_l[], /* i/o: spectrum left channel [NB_DIV][N] */ - float *spec_r[], /* i/o: spectrum right channel [NB_DIV][N] */ - const int16_t mdct_stereo_mode[], /* i : stereo mode (FB/band wise MS, dual mono */ - const int16_t core_l, /* i : core for left channel (TCX20/TCX10) */ - const int16_t core_r, /* i : core for right channel (TCX20/TCX10) */ - const int16_t igf, /* i : flag for IGF activity */ - const int16_t L_frameTCX_l, /* i : TCX frame length of left channel */ - const int16_t L_frameTCX_r, /* i : TCX frame length of right channel */ - const int16_t mct_on, /* i : flag mct block (1) or stereo (0) */ - const int16_t last_core_l, /* i : last core for left channel */ - const int16_t last_core_r, /* i : last core for right channel */ - const int16_t tmp_plc_upmix /* i : indicates temp upmix for PLC decision */ -); - -void stereo_mdct_core_dec( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ - CPE_DEC_HANDLE hCPE, /* i/o: CPE decoder structure */ - float *signal_out[CPE_CHANNELS], /* o : synthesis @internal_FS */ - float signal_outFB[CPE_CHANNELS][L_FRAME48k] /* o : synthesis @output_FS */ -); - -void splitAvailableBits( - const int16_t total_bits, /* i : total available bits for TCX coding */ - const int16_t split_ratio, /* i : split ratio */ - const int16_t isSBAStereoMode, /* i : signal core coding for SBA */ - int16_t *bits_ch0, /* o : bits for channel 0 */ - int16_t *bits_ch1 /* o : bits for channel 1 */ -); - -int16_t write_stereo_to_bitstream -( - STEREO_MDCT_ENC_DATA_HANDLE hStereoMdct, /* i/o: Stereo MDCT encoder structure */ - Encoder_State **sts, /* i/o: Encoder state structure */ - int16_t ms_mask[NB_DIV][MAX_SFB], /* i : bandwise MS mask */ - const int16_t mct_on, /* i : flag mct block (1) or stereo (0) */ - BSTR_ENC_HANDLE hBstr /* i/o: bitstream handle */ -); - - - -void ComputeSpectrumNoiseMeasure( - const float *powerSpec, - const int16_t L_frame, - const int16_t startLine, - const int16_t resetMemory, - int8_t *noiseFlags, - const int16_t lowpassLine -); - -void IGFSaveSpectrumForITF( - IGF_ENC_INSTANCE_HANDLE hIGFEnc, /* i/o: instance handle of IGF Encoder */ - const int16_t igfGridIdx, /* i : IGF grid index */ - const float *pITFSpectrum /* i : MDCT spectrum */ -); - -void convert_coeffs_to_higher_res( - const float *in1, /* i : first subframe input */ - const float *in2, /* i : second subframe input */ - float *out, /* o : converted output */ - const int16_t len /* i : length of subframes */ -); - -int16_t quantize_sns( - float sns_in[CPE_CHANNELS][NB_DIV][M], - float snsQ_out[CPE_CHANNELS][NB_DIV][M], - Encoder_State **sts, - int16_t *indices, - int16_t *zero_side_flag, - int16_t *sns_stereo_mode -); - -void dequantize_sns( - int16_t indices[CPE_CHANNELS][NPRM_LPC_NEW], - float snsQ_out[CPE_CHANNELS][NB_DIV][M], - Decoder_State **sts -); - -void sns_avq_dec( - int16_t *index, /* i : Quantization indices */ - float SNS_Q[NB_DIV][M], /* o : Quantized SNS vectors */ - const int16_t L_frame, /* i : frame length */ - const int16_t numlpc /* i : Number of sets of lpc */ -); - -void sns_avq_dec_stereo( - int16_t *indexl, /* i : Quantization indices (left channel) */ - int16_t *indexr, /* i : Quantization indices (right channe) */ - const int16_t L_frame, /* i : frame length */ - float *SNS_Ql, /* o : Quantized SNS vectors (left channel) */ - float *SNS_Qr /* o : Quantized SNS vectors (right channe) */ -); - -void convertToMS( - const int16_t L_frame, /* i : frame length */ - float x0[], /* i/o: mid/left channel coefficients */ - float x1[], /* i/o: side/right channel coefficients */ - const float norm_fac /* i : normalization factor */ -); - -void inverseMS( - const int16_t L_frame, /* i : frame length */ - float x0[], /* i/o: mid/left channel coefficients */ - float x1[], /* i/o: side/right channel coefficients */ - const float norm_fac /* i : normalization factor */ -); - -void stereoFdCngCoherence( - Encoder_State **sts, /* i/o: core encoder structures */ - const int16_t last_element_mode, /* i : last element mode */ - float fft_buff[CPE_CHANNELS][2 * L_FFT] /* i : fft buffers for L and R channels */ -); - -void FdCngEncodeMDCTStereoSID( - CPE_ENC_HANDLE hCPE /* i/o: CPE encoder state structure */ -); - -void FdCngDecodeMDCTStereoSID( - CPE_DEC_HANDLE hCPE /* i/o: CPE decoder state structure */ -); - -ivas_error initMdctStereoDtxData( - CPE_DEC_HANDLE hCPE /* i/o: CPE decoder handle */ -); - -void synchonize_channels_mdct_sid( - Decoder_State *sts[CPE_CHANNELS], /* i/o: decoder state structure */ - const int16_t n /* i : channel number */ -); - -void updateBuffersForDmxMdctStereo( - CPE_DEC_HANDLE hCPE, /* i/o: CPE handle */ - const int16_t output_frame, /* i : output frame length */ - float *output[CPE_CHANNELS], /* i/o: decoder output */ - float synth[CPE_CHANNELS][L_FRAME48k] /* i/o: decoder synthesis */ -); - -void applyDmxMdctStereo( - const CPE_DEC_HANDLE hCPE, /* i : CPE handle */ - float *output[CPE_CHANNELS], /* o : output from core decoder */ - const int16_t output_frame /* i : output frame length */ -); - -/*----------------------------------------------------------------------------------* - * Front-VAD prototypes - *----------------------------------------------------------------------------------*/ - -ivas_error front_vad_create( - FRONT_VAD_ENC_HANDLE *hFrontVad, /* i/o: front-VAD handle */ - const ENCODER_CONFIG_HANDLE hEncoderConfig /* i : configuration structure */ -); - -void front_vad_destroy( - FRONT_VAD_ENC_HANDLE *hFrontVad /* i/o: front-VAD handle */ -); - -ivas_error front_vad( - CPE_ENC_HANDLE hCPE, /* i/o: CPE encoder structure, nullable */ - Encoder_State *st, /* i/o: encoder state structure */ - const ENCODER_CONFIG_HANDLE hEncoderConfig, /* i : configuration structure */ - FRONT_VAD_ENC_HANDLE *hFrontVads, /* i/o: front-VAD handles */ - const int16_t MCT_flag, /* i : hMCT handle allocated (1) or not (0) */ - const int16_t input_frame, /* i : frame length */ - int16_t vad_flag_dtx[], /* o : HE-SAD flag with additional DTX HO */ - float fr_bands[][2 * NB_BANDS], /* i : energy in frequency bands */ - float Etot_LR[], /* o : total energy Left & Right channel */ - float lf_E[][2 * VOIC_BINS], /* i : per bin spectrum energy in lf, LR channels */ - int16_t localVAD_HE_SAD[], /* o : HE-SAD flag without hangover, LR channels */ - int16_t vad_hover_flag[], /* o : VAD hangover flag */ - float band_energies_LR[2 * NB_BANDS], /* o : energy in critical bands without minimum noise floor E_MIN */ - float *PS_out, /* o : energy spectrum */ - float *Bin_E_out /* o : log-energy spectrum of the current frame*/ -); - -ivas_error front_vad_spar( - SPAR_ENC_HANDLE hSpar, /* i/o: SPAR encoder structure */ - const float *omni_in, /* i : omnidirectional input signal */ - ENCODER_CONFIG_HANDLE hEncoderConfig, /* i : encoder configuration handle */ - const int16_t input_frame /* i : input frame length */ -); - - -/*----------------------------------------------------------------------------------* - * Stereo CNG prototypes - *----------------------------------------------------------------------------------*/ - -void stereo_enc_cng_init( - STEREO_CNG_ENC_HANDLE hStereoCng /* i/o: stereo CNG encoder structure */ -); - -void stereo_cng_upd_counters( - STEREO_CNG_ENC_HANDLE hStereoCng, /* i/o: Stereo CNG data structure */ - const int32_t element_mode, /* i : element mode */ - const int16_t nbands, /* i : Number of bands in active */ - const float sidSideGain[], /* i : SID side gains */ - const int16_t burst_ho_count, /* i : Hang-over count */ - int16_t *coh_fade_counter /* i : Coherence fade counter */ -); - -void stereo_cng_init_dec( - STEREO_CNG_DEC_HANDLE hStereoCng, /* i/o: stereo CNG decoder structure */ - const int16_t *frameSize /* i : pointer to frameSize of channel 0 to be used for channel 1 */ -); - -void stereo_cng_compute_PScorr( - float *output[CPE_CHANNELS], /* i : Output signal */ - float *c_PS_LT, /* i/o: Correlation */ - const int16_t L_frame_0, /* i : L_frame channel 0 */ - const int16_t L_frame_1 /* i : L_frame channel 1 */ -); - -void stereo_cng_dec_update( - CPE_DEC_HANDLE hCPE, /* i/o: CPE decoder structure */ - const int32_t ivas_total_brate /* i : IVAS total bitrate Q0*/ -); - -void stereo_cna_update_params( - CPE_DEC_HANDLE hCPE, /* i/o: CPE decoder structure */ - float *output[CPE_CHANNELS], /* i : Output signal */ - const int16_t output_frame, /* i : Output frame length */ - const int16_t tdm_ratio_idx /* i : TDM ratio index */ -); - -void dtx_enc_init( - Encoder_State *st, /* i : Encoder state handle */ - const int16_t var_SID_rate_flag, /* i : flag for variable SID update rate */ - const int16_t interval_SID /* i : interval for SID update */ -); - - -/*----------------------------------------------------------------------------------* - * Framework general prototypes - *----------------------------------------------------------------------------------*/ - -void mvc2c( - const uint8_t x[], /* i : input vector */ - uint8_t y[], /* o : output vector */ - const int16_t n /* i : vector size */ -); - -/*! r: Adjusted value */ -ivas_error stereo_memory_dec( - const int32_t ivas_total_brate, /* i : IVAS total bitrate */ - CPE_DEC_HANDLE hCPE, /* i : CPE decoder structure */ - const int16_t nb_bits_metadata, /* i : number of metadata bits */ - const int32_t output_Fs, /* i : output sampling rate */ - const IVAS_FORMAT ivas_format, /* i : IVAS format */ - const MC_MODE mc_mode, /* i : MC mode */ - const int16_t nchan_transport /* i : number of transport channels */ -); - -void stereo_switching_dec( - CPE_DEC_HANDLE hCPE, /* i/o: CPE decoder structure */ - const Word32 ivas_total_brate /* i : IVAS total bitrate Q0*/ -); - -void stereo_td2dft_update( - CPE_DEC_HANDLE hCPE, /* i/o: CPE decoder structure */ - const int16_t n, /* i : channel number */ - float output[], /* i/o: synthesis @internal Fs */ - float synth[], /* i/o: synthesis @output Fs */ - float hb_synth[], /* i/o: hb synthesis */ - const int16_t output_frame /* i : frame length */ -); - -void stereo_mdct2dft_update( - CPE_DEC_HANDLE hCPE, /* i/o: CPE decoder structure */ - float output0[], /* i/o: synthesis @internal Fs, ch0 */ - float synth0[] /* i/o: synthesis @output Fs, ch0 */ -); - - -/*! r: number of bits written */ - - - -/*----------------------------------------------------------------------------------* - * MCT prototypes - *----------------------------------------------------------------------------------*/ -void ivas_mdct_core_whitening_enc_fx( - CPE_ENC_HANDLE hCPE, /* i/o: CPE encoder structure */ - Word16 new_samples_fx[CPE_CHANNELS][L_INP], /* i : new samples */ - Word16 old_wsp_fx[CPE_CHANNELS][L_WSP], /* i : 12.8kHz weighted speech (for LTP */ - Word16 pitch_buf[CPE_CHANNELS][NB_SUBFR16k], /* o : floating pitch for each subframe */ - Word32 *mdst_spectrum_long[CPE_CHANNELS], /* o : buffer for MDST spectrum */ - int16_t tnsBits[CPE_CHANNELS][NB_DIV], /* o : buffer TNS bits */ - Word32 *orig_spectrum_long[CPE_CHANNELS], /* o : origingal spectrum w/o whitening */ - int16_t tnsSize[CPE_CHANNELS][NB_DIV], /* o : size of TNS */ - int16_t p_param[CPE_CHANNELS][NB_DIV], /* o : pointer to parameter array */ - BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ - const int16_t mct_on, /* i : flag mct block (1) or stereo (0) */ - const int16_t nChannels, /* i : total number of coded channels */ -Word16 mdst_spectrum_e[CPE_CHANNELS][NB_DIV], -Word16 orig_spectrum_e[CPE_CHANNELS][NB_DIV] -); -void ivas_mct_core_enc( - const IVAS_FORMAT ivas_format, /* i : IVAS format */ - MCT_ENC_HANDLE hMCT, /* i/o: MCT encoder structure */ - CPE_ENC_HANDLE hCPE[MCT_MAX_BLOCKS], /* i/o: CPE encoder structures */ - const int16_t nChannels, /* i : number of channels to be coded */ - const int32_t ivas_total_brate, /* i : IVAS total bitrate */ - const int16_t switch_bw, /* i : flag bandwidth switch occurance */ - const int16_t lfe_bits, /* i : bits spent for LFE */ - const int16_t sba_order /* i : Ambisonic (SBA) order */ -); - -void ivas_mdct_quant_coder( - CPE_ENC_HANDLE hCPE, /* i/o: Encoder CPE handle */ - int16_t tnsBits[CPE_CHANNELS][NB_DIV], /* i : bits needed for TNS parameters */ - int16_t tnsSize[CPE_CHANNELS][NB_DIV], /* i : size of TNS */ - int16_t p_param[CPE_CHANNELS][NB_DIV], /* i : pointer to parameter array */ - const int16_t MCT_flag /* i : hMCT handle allocated (1) or not (0) */ -); - -void apply_MCT_enc( - MCT_ENC_HANDLE hMCT, /* i/o: MCT encoder structure */ - Encoder_State **sts, /* i/o: encoder state structure */ - float *mdst_spectrum[MCT_MAX_CHANNELS][NB_DIV], /* i/o: MDST spectrum */ - float *inv_spectrum[MCT_MAX_CHANNELS][NB_DIV], /* i/o: inverse spectrum */ - float *inv_mdst_spectrum[MCT_MAX_CHANNELS][NB_DIV], /* i/o: inverse MDST spectrum */ - const int16_t nchan /* i : number of channels */ -); - -void write_mct_bitstream( - Encoder_State **sts, /* i/o: encoder state structure */ - MCT_ENC_HANDLE hMCT, /* i/o: MCT encoder structure */ - const int16_t nchan /* i : number of channels */ -); - -void splitAvailableBitsMCT_fx( - void **sts, /* i/o: encoder/decoder state structure */ - const Word16 total_bits, /* i : total number of available bits */ - const Word16 split_ratio[MCT_MAX_CHANNELS], /* i : ratio for splitting the bits Q0 */ - const Word16 enc_dec, /* i : encoder or decoder flag */ - const Word16 nchan /* i : number of channels */ -); - -void getChannelEnergies( - Encoder_State **sts, /* i : Encoder state structure */ - float nrg[MCT_MAX_CHANNELS], /* o : energies */ - const int16_t nchan /* i : number of channels */ -); - -void mctStereoIGF_enc( - MCT_ENC_HANDLE hMCT, /* i/o: MCT encoder structure */ - Encoder_State **sts, /* i/o: encoder state structure */ - float *orig_spectrum[MCT_MAX_CHANNELS][NB_DIV], /* i : MDCT spectrum for ITF */ - float powerSpec[MCT_MAX_CHANNELS][L_FRAME48k], /* i/o: MDCT^2 + MDST^2 spectrum,or estimate */ - float *powerSpecMsInv[MCT_MAX_CHANNELS][NB_DIV], /* i : same as above but for inverse spect. */ - float *inv_spectrum[MCT_MAX_CHANNELS][NB_DIV], /* i : inverse spectrum */ - const int16_t sp_aud_decision0[MCT_MAX_CHANNELS] /* i : speech audio decision */ -); - -void ivas_mdct_dec_side_bits_frame_channel( - CPE_DEC_HANDLE hCPE, /* i/o: CPE decoder structure */ - int16_t param_lpc[CPE_CHANNELS][NPRM_LPC_NEW], /* o : lpc_parameters */ - int16_t p_param[CPE_CHANNELS][NB_DIV], /* o : pointer to param buffer */ - Decoder_State *st0, /* i : pointer to bitstream handle */ - int16_t nTnsBitsTCX10[CPE_CHANNELS][NB_DIV], /* o : number of bits for TNS */ - int16_t param[CPE_CHANNELS][DEC_NPRM_DIV * NB_DIV], /* i/o: parameters buffer */ - const int16_t MCT_flag, /* i : hMCT handle allocated (1) or not (0) */ - const int16_t odd_channel_cpe /* i : flag cpe with odd nb of tc channels */ -); - -void ivas_mct_side_bits( - MCT_DEC_HANDLE hMCT, /* i/o: MCT decoder structure */ - CPE_DEC_HANDLE hCPE[MCT_MAX_BLOCKS], /* i/o: CPE decoder structure */ - const int16_t nCPE, /* i : number of CPEs */ - Decoder_State *st0, /* i : decoder handle for Bstr */ - const int16_t bfi, /* i : BFI flag */ - uint16_t *bitstream, /* o : bitstream indices */ - const int32_t ivas_total_brate, /* i : IVAS total bitrate */ - const int16_t nb_bits_metadata /* i : number of metadata bits */ -); - -void ivas_mdct_core_invQ( - CPE_DEC_HANDLE hCPE, /* i/o: CPE handle */ - int16_t nTnsBitsTCX10[CPE_CHANNELS][NB_DIV], /* i : number of TNS bits */ - int16_t p_param[CPE_CHANNELS][NB_DIV], /* i : pointer to param buffer */ - int16_t param_lpc[CPE_CHANNELS][NPRM_LPC_NEW], /* i : lpc parameters */ - int16_t param[CPE_CHANNELS][DEC_NPRM_DIV * NB_DIV], /* i : param buffer */ - int16_t fUseTns[CPE_CHANNELS][NB_DIV], /* i : flag TNS enabled */ - STnsData tnsData[CPE_CHANNELS][NB_DIV], /* i : TNS parameter */ - float *x_0[CPE_CHANNELS][NB_DIV], /* i/o: signal buffer */ - float *x[CPE_CHANNELS][NB_DIV], /* i/o: signal buffer */ - float Aq[CPE_CHANNELS][( NB_SUBFR16k + 1 ) * ( M + 1 )], /* i : LP coefficients */ - int16_t ms_mask[NB_DIV][MAX_SFB], /* i : M/S mask */ - const int16_t MCT_flag /* i : hMCT handle allocated (1) or not (0) */ -); - -void ivas_mdct_core_reconstruct( - CPE_DEC_HANDLE hCPE, /* i/o: CPE decoder structure */ - float *x[][NB_DIV], /* i/o: pointers to synthesis @internal_FS */ - float signal_outFB[CPE_CHANNELS][L_FRAME_PLUS], /* o : synthesis @output_FS */ - int16_t fUseTns[CPE_CHANNELS][NB_DIV], /* i : flage TNS enabled */ - const int16_t MCT_flag /* i : hMCT handle allocated (1) or not (0) */ -); - -void ivas_mdct_core_tns_ns( - CPE_DEC_HANDLE hCPE, /* i/o: CPE decoder structure */ - int16_t fUseTns[CPE_CHANNELS][NB_DIV], /* i : two entries for each channel in TCX10 */ - STnsData tnsData[CPE_CHANNELS][NB_DIV], /* o : TNS parameter */ - float *x[CPE_CHANNELS][NB_DIV], /* o : synthesis @internal_FS */ - float Aq[CPE_CHANNELS][( NB_SUBFR16k + 1 ) * ( M + 1 )], /* o : LP coefficients */ - const int16_t MCT_flag /* i : hMCT handle allocated (1) or not (0) */ -); - - -void ivas_mct_dec_mct( - MCT_DEC_HANDLE hMCT, /* i/o: MCT decoder structure */ - Decoder_State **sts, /* i/o: decoder state structure */ - const int16_t nchan /* i : number of channels */ -); - -void apply_MCT_dec( - MCT_DEC_HANDLE hMCT, /* i/o: MCT decoder structure */ - Decoder_State **sts, /* i/o: decoder state structure */ - float *x[MCT_MAX_CHANNELS][NB_DIV] /* i/o: decoded and dequan. spect. input to MCT */ -); - -void mctStereoIGF_dec( - MCT_DEC_HANDLE hMCT, /* i/o: MCT decoder structure */ - Decoder_State **sts, /* i/o: decoder state structure */ - float *x[MCT_MAX_CHANNELS][NB_DIV], /* i/o: decoded and dequantized spectrum */ - const int16_t bfi /* i : bad frame flag */ -); - -void enc_prm_igf_mdct( - Encoder_State *st, /* i : Encoder state handle */ - BSTR_ENC_HANDLE hBstr /* i/o: Bitstream handle */ -); - -void mdct_read_IGF_bits( - Decoder_State *st, /* i/o: Encoder state handle */ - Decoder_State *st0 /* i : pointer to handle where bstr is read */ -); - - -/*----------------------------------------------------------------------------------* - * Q Metadata prototypes for DirAC and MASA - *----------------------------------------------------------------------------------*/ - -ivas_error ivas_qmetadata_enc_encode( - BSTR_ENC_HANDLE hMetaData, /* i/o: metadata bitstream handle */ - IVAS_QMETADATA *hQMetaData, /* i/o: q_metadata handle */ - const int16_t hodirac_flag /* i : flag to indicate HO-DirAC mode */ -); - -ivas_error ivas_qmetadata_enc_encode_hr_384_512( - BSTR_ENC_HANDLE hMetaData, /* i/o: metadata bitstream handle */ - IVAS_QMETADATA *hQMetaData, /* i/o: metadata handle */ - const int16_t bits_sph_idx, - const int16_t bits_sp_coh -); - -void deindex_sph_idx( - const uint16_t sphIndex, /* i : Spherical index */ - const SPHERICAL_GRID_DATA *gridData, /* i : Prepared spherical grid */ - float *theta, /* o : Elevation */ - float *phi /* o : Azimuth */ -); - -/*! r: output index for direction */ -uint16_t index_theta_phi_16( - float * p_theta, /* i/o: input elevation to be indexed */ - float * p_phi, /* i/o: input azimuth to be indexed */ - const SPHERICAL_GRID_DATA *gridData /* i : generated grid data */ -); - -void reset_metadata_spatial( - const IVAS_FORMAT ivas_format, /* i : IVAS format */ - BSTR_ENC_HANDLE hMetaData, /* i/o: Metadata bitstream handle */ - const int32_t element_brate, /* i : element bitrate */ - int32_t *total_brate, /* o : total bitrate */ - const int32_t core_brate, /* i : core bitrate */ - const int16_t nb_bits_metadata /* i : number of meatdata bits */ -); - -/*! r: number of bits written */ - -/*! r: number of bits read */ -int16_t ivas_qmetadata_dec_decode( - IVAS_QMETADATA_HANDLE hQMetaData, /* i/o: q_metadata handle */ - uint16_t *bitstream, /* i : bitstream */ - int16_t *index, /* i/o: bitstream position */ - const int16_t hodirac_flag /* i : flag to indicate HO-DirAC mode */ -); - -/*! r: number of bits read */ -int16_t ivas_qmetadata_dec_decode_hr_384_512( - IVAS_QMETADATA_HANDLE hQMetaData, /* i/o: hQMetaData handle */ - uint16_t *bitstream, /* i : bitstream */ - int16_t *index, /* i/o: bitstream position */ - const SPHERICAL_GRID_DATA *sph_grid16, /* i : spherical grid for deindexing */ - const int16_t bits_sph_idx, - const int16_t bits_sp_coh, - const uint8_t ncoding_bands_config -); - -/*! r: number of bits read */ -int16_t ivas_qmetadata_dec_sid_decode( - IVAS_QMETADATA_HANDLE hQMetaData, /* i/o: q_metadata handle */ - uint16_t *bitstream, /* i : bitstream */ - int16_t *index, /* i/o: bitstream position */ - const int16_t nchan_transport, /* i : number of transport channels */ - int16_t *element_mode, /* o : element mode */ - const int16_t ivas_format /* i : IVAS format */ -); - - - - -void restore_metadata_buffer( - BSTR_ENC_HANDLE hMetaData, - const int16_t next_ind_start, - const int16_t bit_pos_start -); - -/*! r: codeword index */ -int16_t masa_sq( - const float in, /* i : input value */ - const float *threshold, /* i : partition */ - const int16_t cb_sz /* i : codebook size */ -); - -void ivas_qmetadata_azimuth_elevation_to_direction_vector( - const float az, /* i : azimuth */ - const float el, /* i : elevation */ - float *dv /* o : direction vector */ -); - -ivas_error only_reduce_bits_direction( - int16_t *reduce_bits_out, - IVAS_QDIRECTION *q_direction, /* i/o: quantized direction structure */ - int16_t reduce_bits, - const int16_t coding_subbands, - const int16_t no_subframes, - int16_t *ind_order -); - -void quantize_direction_frame( - IVAS_QDIRECTION *q_direction, /* i/o: quantized direction structure */ - float azimuth_orig[MASA_MAXIMUM_CODING_SUBBANDS][MAX_PARAM_SPATIAL_SUBFRAMES], - float elevation_orig[MASA_MAXIMUM_CODING_SUBBANDS][MAX_PARAM_SPATIAL_SUBFRAMES], - const int16_t hrmasa_flag /* i : flag indicating high-rate MASA MD coding*/ -); - -/*! r: quantized spherical index */ -uint16_t quantize_direction( - const float theta, /* i : input elevation value */ - float phi, /* i : input azimuth value */ - const int16_t no_bits, /* i : number of bits */ - float *theta_q, /* o : quantized elevation */ - float *phi_q, /* o : quantized azimuth */ - uint16_t *index_theta, /* o : quantized elevation index */ - uint16_t *index_phi, /* o : quantized azimuth index */ - const MC_LS_SETUP mc_format /* i : channel format if in MC-mode */ -); - -int16_t quantize_direction2D( - float phi, /* i : input azimuth value */ - const int16_t no_cw, /* i : number of bits */ - float *phi_q, /* o : quantized azimuth value */ - uint16_t *index_phi, /* o : quantized azimuth index */ - const MC_LS_SETUP mc_format /* i : channel format if in MC-mode */ -); - -void quantize_direction_frame2D( - IVAS_QDIRECTION *q_direction, /* i/o: quantized direction structure */ - float azimuth_orig[MASA_MAXIMUM_CODING_SUBBANDS][MAX_PARAM_SPATIAL_SUBFRAMES], /* i : input azimuth values */ - float elevation_orig[MASA_MAXIMUM_CODING_SUBBANDS][MAX_PARAM_SPATIAL_SUBFRAMES] /* i : input elevation values */ -); - -void small_requantize_direction_frame( - IVAS_QDIRECTION *q_direction, /* i/o: quantized direction structure */ - float azimuth_orig[MASA_MAXIMUM_CODING_SUBBANDS][MAX_PARAM_SPATIAL_SUBFRAMES], /* i : input azimuth values */ - float elevation_orig[MASA_MAXIMUM_CODING_SUBBANDS][MAX_PARAM_SPATIAL_SUBFRAMES], /* i : input elevation values */ - const int16_t raw_flag[MASA_MAXIMUM_CODING_SUBBANDS], /* i : raw/EC encoding mode for each subband */ - int16_t bits_dir_bands[MASA_MAXIMUM_CODING_SUBBANDS], /* i/o: number of bits per subband */ - int16_t *diff /* i/o: number of bits to be reduced */ -); - -/*! r: index azimuth */ -int16_t quantize_phi( - float phi, /* i : azimuth value */ - const int16_t flag_delta, /* i : flag indicating if the azimuth codebook is translated or not */ - float *phi_hat, /* o : quantized azimuth */ - const int16_t n /* i : azimuth codebook size */ -); - -/*! r: decoded elevation value */ -float deindex_elevation( - uint16_t *id_th, /* i : input index */ - const int16_t no_bits, /* i : number of bits for the spherical grid */ - const MC_LS_SETUP mc_format /* i : channel format if in MC-mode */ -); - -float deindex_azimuth( - int16_t id_phi, /* i : index */ - const int16_t no_bits, /* i : number of bits for the spherical grid */ - const int16_t id_th, /* i : elevation index */ - const int16_t remap, /* i : remapping flag */ - const MC_LS_SETUP mc_format /* i : channel format if in MC-mode */ -); - -UWord16 ivas_qmetadata_reorder_generic_fx( - const Word16 signed_value -); - -void ivas_sba_config( - const int32_t sba_total_brate, /* i : SBA total bitrate */ - int16_t sba_order, /* i : Ambisonic (SBA) order */ - int16_t nb_channels, /* i : Number of Ambisonic (SBA) channels */ - int16_t *nchan_transport, /* o : number of transport channels */ - const int16_t sba_planar, /* i : SBA planar flag */ - int16_t *nSCE, /* o : number of SCEs */ - int16_t *nCPE, /* o : number of CPEs */ - int16_t *element_mode /* o : element mode of the core coder */ -); - -void ivas_sba_set_cna_cng_flag( - Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */ -); - -ivas_error ivas_sba_dec_reconfigure( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ - uint16_t *nSamplesFlushed, /* o : number of samples flushed */ - int16_t *data /* o : output synthesis signal */ -); - -ivas_error ivas_sba_digest_tc( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */ - const int16_t nchan_transport, /* i : number of transport channels */ - const int16_t nCldfbSlots, /* i : number of CLDFB slots */ - const int16_t nSamplesForRendering, /* i : number of samples provided */ - float *data[] /* i : transport channel samples */ -); - - - -/*! r: Ambisonic (SBA) order */ -int16_t ivas_sba_get_order( - const int16_t nb_channels, /* i : Number of ambisonic channels */ - const int16_t sba_planar /* i : SBA planar flag */ -); - -/*! r: number of Ambisonic channels */ -int16_t ivas_sba_get_nchan( - const int16_t sba_order, /* i : Ambisonic (SBA) order */ - const int16_t sba_planar /* i : SBA planar flag */ -); - -/*! r: number of ambisonics metadata channels */ - -void ivas_sba_getTCs( - float *sba_data[], /* i : SBA signals */ - Encoder_Struct *st_ivas, /* i/o: Encoder struct */ - const int16_t input_frame /* i : frame length */ -); - -int16_t ivas_sba_remapTCs( - float *sba_data[], /* i/o: SBA signals */ - Decoder_Struct *st_ivas, /* i/o: decoder struct */ - const int16_t output_frame /* i : frame length */ -); - -void ivas_sba_dirac_stereo_dec( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ - float *output[CPE_CHANNELS], /* o : output synthesis signal */ - const int16_t output_frame, /* i : output frame length per channel */ - const int16_t mcmasa /* i : McMASA flag */ -); - -void ivas_sba_dirac_stereo_config( - STEREO_DFT_CONFIG_DATA_HANDLE hConfig /* o : DFT stereo configuration */ -); - - -Word16 ivas_get_sba_dirac_stereo_flag( - Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */ -); - -void ivas_sba_dirac_stereo_smooth_parameters( - STEREO_DFT_DEC_DATA_HANDLE hStereoDft, /* i/o: encoder DFT stereo handle */ - ivas_spar_md_dec_state_t *hMdDec, /* i/o: SPAR MD handle for upmixing */ - const int16_t cross_fade_start_offset, /* i : SPAR mixer delay compensation */ - const int32_t output_Fs, /* i : Fs for delay calculation */ - const int16_t num_md_sub_frames /* i : number of subframes in mixing matrix */ -); - - -/*----------------------------------------------------------------------------------* - * DirAC prototypes - *----------------------------------------------------------------------------------*/ - - -ivas_error ivas_dirac_enc_reconfigure( - Encoder_Struct *st_ivas /* i/o: IVAS encoder handle */ -); - - - -ivas_error ivas_dirac_config( - void *st_ivas, /* i/o: IVAS encoder/decoder state structure */ - const int16_t enc_dec /* i : encoder or decoder flag */ -); - -void ivas_dirac_config_bands( - int16_t *band_grouping, /* o : band grouping */ - const int16_t nbands, /* i : number of bands */ - const int16_t max_band, /* i : maximal band index +1 */ - int16_t *dirac_to_spar_md_bands, /* o : mapping of DirAC parameter band index to SPAR FB band index */ - const int8_t useLowerBandRes, /* i : flag indicating lower band resolution for DirAC */ - const int16_t enc_param_start_band, /* i : band index of first DirAC parameter band */ - IVAS_FB_MIXER_HANDLE hFbMdft -); - -void ivas_get_dirac_sba_max_md_bits( - const int32_t sba_total_brate, - int16_t *bits_frame_nominal, - int16_t *metadata_max_bits, - int16_t *qmetadata_max_bit_req, - const int16_t nbands - , - IVAS_FORMAT ivas_format -); - -ivas_error ivas_dirac_sba_config( - IVAS_QMETADATA_HANDLE hQMetaData, /* i/o: q_metadata handle */ - int16_t *element_mode, /* o : element mode of the core coder */ - int32_t sba_total_brate, /* i : SBA total bitrate */ - const int16_t sba_order, /* i : Ambisonic (SBA) order */ - const int16_t nbands /* i : number of frequency bands */ - , - IVAS_FORMAT ivas_format -); - -ivas_error ivas_dirac_dec_config( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ - const DIRAC_CONFIG_FLAG flag_configopen /* i/ : Flag determining if we open or reconfigure the DirAC decoder */ -); - -void ivas_dirac_dec_close( - DIRAC_DEC_HANDLE *hDirAC_out -); - -void ivas_dirac_dec_read_BS( - const int32_t ivas_total_brate, /* i : IVAS total bitrate */ - Decoder_State *st, /* i/o: decoder Core state structure */ - DIRAC_DEC_HANDLE hDirAC, /* i/o: decoder DirAC handle */ - SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom, /* i/o: common spatial rendering data handle */ - IVAS_QMETADATA_HANDLE hQMetaData, /* i/o: q metadata */ - int16_t *nb_bits, /* o : number of bits read */ - const int16_t last_bit_pos, /* i : last read bitstream position */ - const int16_t hodirac_flag, /* i : flag to indicate HO-DirAC mode */ - int16_t *dirac_to_spar_md_bands /* o : DirAC->SPAR MD bands */ -); - -void generate_masking_noise_lb_dirac( - HANDLE_FD_CNG_COM hFdCngCom, /* i/o: FD_CNG structure containing all buffers and variables */ - float *tdBuffer, /* i/o: time-domain signal, if NULL no LB-CNA */ - const int16_t nCldfbTs, /* i : number of CLDFB slots that will be rendered */ - const int16_t cna_flag /* i : CNA flag for LB and HB */ -); - - -void ivas_dirac_dec_render( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */ - const int16_t nchan_transport, /* i : number of transport channels */ - const uint16_t nSamplesAsked, /* i : number of CLDFB slots requested */ - uint16_t *nSamplesRendered, /* o : number of CLDFB slots rendered */ - uint16_t *nSamplesAvailable, /* o : number of CLDFB slots still to render */ - float *output_f[] /* o : rendered time signal */ -); - -void ivas_dirac_dec_render_sf( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ - float *output_f[], /* i/o: synthesized core-coder transport channels/DirAC output */ - const int16_t nchan_transport, /* i : number of transport channels */ - float *pppQMfFrame_ts_re[IVAS_MAX_FB_MIXER_IN_CH][CLDFB_NO_COL_MAX], - float *pppQMfFrame_ts_im[IVAS_MAX_FB_MIXER_IN_CH][CLDFB_NO_COL_MAX] -); - - -void computeDirectionVectors( - float *intensity_real_x, - float *intensity_real_y, - float *intensity_real_z, - const int16_t enc_param_start_band, - const int16_t num_frequency_bands, - float *direction_vector_x, - float *direction_vector_y, - float *direction_vector_z -); - -void computeDiffuseness( - float *buffer_intensity[DIRAC_NUM_DIMS][DIRAC_NO_COL_AVG_DIFF], - const float *buffer_energy, - const int16_t num_freq_bands, - float *diffuseness -); - -void ivas_dirac_dec_get_response( - const int16_t azimuth, - const int16_t elevation, - float *response, - const int16_t ambisonics_order -); - - - -ivas_error ivas_mc_paramupmix_enc_open( - Encoder_Struct *st_ivas /* i/o: IVAS encoder handle */ -); - -void ivas_mc_paramupmix_enc_close( - MC_PARAMUPMIX_ENC_HANDLE *hMCParamUpmix, /* i/o: MC Param-Upmix encoder handle */ - const int32_t input_Fs /* i : input sampling rate */ -); - -ivas_error ivas_mc_paramupmix_dec_open( - Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */ -); - -void ivas_mc_paramupmix_dec_close( - MC_PARAMUPMIX_DEC_HANDLE *hMCParamUpmix_out /* i/o: Parametric MC decoder handle */ -); - -void ivas_mc_paramupmix_dec_read_BS( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ - Decoder_State *st, /* i/o: decoder state structure */ - MC_PARAMUPMIX_DEC_HANDLE hMCParamUpmix, /* i/o: decoder MC Param-Upmix handle */ - int16_t *nb_bits /* o : number of bits written */ -); - -void ivas_mc_paramupmix_dec_digest_tc( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */ - const uint8_t nCldfbSlots, /* i : number of CLFBS slots in the transport channels */ - const int16_t nSamplesForRendering /* i : number of samples provided */ -); - -void ivas_param_mc_set_coded_bands_fx( - HANDLE_IVAS_PARAM_MC_METADATA hMetadataPMC /* i/o: handle for the Parametric MC parameter coding state */ -); - -/*! r: number of IVAS transport channels */ - -ivas_error ivas_param_mc_enc_open( - Encoder_Struct *st_ivas /* i/o: IVAS encoder handle */ -); - -ivas_error ivas_param_mc_enc_reconfig( - Encoder_Struct *st_ivas /* i/o: IVAS encoder handle */ -); - -void ivas_param_mc_enc_close( - PARAM_MC_ENC_HANDLE *hParamMC, /* i/o: Parametric MC encoder handle */ - const int32_t input_Fs /* i : input sampling rate */ -); - -void ivas_param_mc_enc( - Encoder_Struct *st_ivas, /* i/o: IVAS Encoder handle */ - BSTR_ENC_HANDLE hMetaData, /* i/o: IVAS Metadata bitstream handle */ - float *data_f[], /* i/o: input/transport MC data */ - const int16_t input_frame /* i : input frame length */ -); - -ivas_error ivas_param_mc_dec_open( - Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */ -); - -ivas_error ivas_param_mc_dec_reconfig( - Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */ -); - - - -void ivas_param_mc_dec_digest_tc( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */ - const uint8_t nCldfbSlots, /* i : number of CLFBS slots in the transport channels */ - float *transport_channels_f[] /* i : synthesized core-coder transport channels/DirAC output*/ -); - -void ivas_param_mc_dec_render( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */ - const uint16_t nSamplesAsked, /* i : number of CLDFB slots requested */ - uint16_t *nSamplesRendered, /* o : number of CLDFB slots rendered */ - uint16_t *nSamplesAvailable, /* o : number of CLDFB slots still to render */ - float *output_f[] /* o : rendered time signal */ -); - -void ivas_param_mc_dec( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */ - float *output_f[] /* i/o: synthesized core-coder transport channels/DirAC output */ -); - -/*! r: number of cldfb synthesis instances */ -int16_t param_mc_get_num_cldfb_syntheses( - Decoder_Struct *st_ivas /* i : IVAS decoder structure */ -); - -UWord16 ivas_param_mc_get_configuration_index_fx( - const MC_LS_SETUP mc_ls_setup, /* i : MC ls setup */ - const Word32 ivas_total_brate /* i : IVAS total bitrate */ -); - -ivas_error ivas_dirac_dec_output_synthesis_cov_open( - DIRAC_OUTPUT_SYNTHESIS_PARAMS *h_dirac_output_synthesis_params, /* i/o: handle for the covariance synthesis parameters */ - DIRAC_OUTPUT_SYNTHESIS_COV_STATE *h_dirac_output_synthesis_state, /* i/o: handle for the covariance synthesis state */ - const int16_t max_band_decorr, /* i : uppermost frequency band where decorrelation is applied */ - const int16_t interp_length, /* i : length for interpolating the mixing matrices in time slots */ - const int16_t num_param_bands, /* i : number of parameter bands */ - const int16_t num_param_bands_residual, /* i : number of parameter bands with a residual mixing matrix (i.e. decorrelation */ - const int16_t nchan_in, /* i : number of input (transport) channels */ - const int16_t nchan_out, /* i : number of output channels */ - const float *proto_matrix /* i : the prototype (upmix) matrix (only used if mode == 1) */ -); - -void ivas_dirac_dec_output_synthesis_get_interpolator( - DIRAC_OUTPUT_SYNTHESIS_PARAMS *h_dirac_output_synthesis_params, /* i/o: handle for the covariance synthesis parameters */ - const uint16_t interp_length /* i : interpolator length */ -); - -void ivas_dirac_dec_output_synthesis_cov_init( - DIRAC_OUTPUT_SYNTHESIS_COV_STATE *h_dirac_output_synthesis_state, /* i/o: pointer to the state of the covariance synthesis */ - const int16_t nchan_in, /* i : number of input (tranport) channels */ - const int16_t nchan_out, /* i : number of output channels */ - const int16_t n_param_bands, /* i : number of total parameter bands */ - const int16_t n_param_bands_res /* i : number of parameter bands with a residual mixing matrix (i.e. decorrelation */ -); - -void ivas_dirac_dec_output_synthesis_cov_close( - DIRAC_OUTPUT_SYNTHESIS_PARAMS *h_dirac_output_synthesis_params, /* i : handle for the covariance synthesis parameters */ - DIRAC_OUTPUT_SYNTHESIS_COV_STATE *h_dirac_output_synthesis_state /* i/o: handle for the covariance synthesis state */ -); - - -void ivas_dirac_dec_output_synthesis_cov_param_mc_synthesise_slot( - float *Cldfb_RealBuffer_in, /* i : input channel filter bank samples (real part) */ - float *Cldfb_ImagBuffer_in, /* i : input channel filter bank samples (imaginary part) */ - float Cldfb_RealBuffer[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* o : output channel filter bank samples (real part) */ - float Cldfb_ImagBuffer[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* o : output channel filter bank samples (imaginary part) */ - float *mixing_matrix[], /* i : parameter band wise mixing matrices (direct part) */ - float *mixing_matrix_res[], /* i : parameter band wise mixing matrices (residual part) */ - const uint16_t slot_idx_sfr, /* i : time slot index for the current slot within the current subframe */ - const uint16_t slot_idx_tot, /* i : time slot index for the current slot within the frame */ - const int16_t nX, /* i : number of input channels */ - const int16_t nY, /* i : number of output channels */ - PARAM_MC_DEC_HANDLE hParamMC /* i : handle to the Parametric MC decoder state */ -); - - -void FdCngEncodeDiracMDCTStereoSID( - CPE_ENC_HANDLE hCPE /* i/o: CPE encoder state structure */ -); - -void FdCngDecodeDiracMDCTStereoSID( - CPE_DEC_HANDLE hCPE /* i/o: CPE decoder state structure */ -); - - -/*----------------------------------------------------------------------------------* - * SPAR prototypes - *----------------------------------------------------------------------------------*/ - -ivas_error ivas_spar_enc_open( - Encoder_Struct *st_ivas, /* i/o: IVAS encoder handle */ - const int16_t spar_reconfig_flag /* i : SPAR reconfiguration flag */ -); - -ivas_error ivas_spar_enc( - Encoder_Struct *st_ivas, /* i/o: IVAS encoder structure */ - float *data_f[], /* i/o: input/transport audio channels */ - const int16_t input_frame, /* i : input frame length */ - int16_t *nb_bits_metadata, /* i : number of MD bits written */ - BSTR_ENC_HANDLE hMetaData /* o : MetaData handle */ -); - -ivas_error ivas_spar_dec_open( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */ - const int16_t spar_reconfig_flag /* i : SPAR reconfiguration flag */ -); - - -ivas_error ivas_spar_dec( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder struct */ - int16_t *nb_bits_read /* o : number of MD bits read */ -); - -void ivas_spar_config( - int32_t ivas_total_brate, /* i : codec total bitrate */ - const int16_t sba_order, /* i : Ambisonic (SBA) order */ - int16_t *nchan_transport, /* o : number of transport channels */ - int16_t *nSCE, /* o : number of SCEs */ - int16_t *nCPE, /* o : number of CPEs */ - int32_t *core_nominal_brate, /* o : core-coding nominal bitrate */ - const int16_t sid_format /* i : IVAS format indicator from SID frame */ -); - -ivas_error ivas_sba_linear_renderer( - float *output_f[], /* i/o: synthesized core-coder transport channels/DirAC output */ - const int16_t output_frame, /* i : output frame length per channel */ - const int16_t nchan_in, /* i : number of input ambisonics channels */ - const int16_t nchan_ism, /* i : number of objects */ - const AUDIO_CONFIG output_config, /* i : output audio configuration */ - const IVAS_OUTPUT_SETUP output_setup /* i : output format setup */ -); - -void ivas_sba_mix_matrix_determiner( - SPAR_DEC_HANDLE hSpar, /* i/o: SPAR decoder handle */ - float *output[], /* i/o: transport/output audio channels */ - const int16_t bfi, /* i : BFI flag */ - const int16_t nchan_remapped, /* i : num channels after remapping of TCs */ - const int16_t output_frame, /* i : output frame length */ - const int16_t num_md_sub_frames /* i : number of subframes in mixing matrix */ -); - -/* AGC */ -/*! r: AGC enable flag */ - -ivas_error ivas_spar_agc_enc_open( - ivas_agc_enc_state_t **hAgcEnc, /* i/o: AGC decoder handle */ - const int32_t input_Fs, /* i : input sampling rate */ - const int16_t nchan_inp /* i : number of input channels */ -); - -void ivas_spar_agc_enc_close( - ivas_agc_enc_state_t **hAgcEnc /* i/o: AGC encoder handle */ -); - -void ivas_agc_enc_process( - ivas_agc_enc_state_t *hAgcEnc, /* i/o: AGC encoder handle */ - BSTR_ENC_HANDLE hMetaData, /* i/o: MetaData handle */ - float **ppPcm_in, /* i : input audio channels */ - float **ppPcm_out, /* o : output audio channels */ - const int16_t n_channels, /* i : number of channels */ - const ENCODER_CONFIG_HANDLE hEncoderConfig /* i : configuration structure */ -); - -ivas_error ivas_spar_agc_dec_open( - ivas_agc_dec_state_t **hAgcDec, /* i/o: AGC decoder handle */ - const int32_t output_Fs /* i : output sampling rate */ -); - -void ivas_spar_agc_dec_close( - ivas_agc_dec_state_t **hAgcDec /* i/o: AGC decoder handle */ -); - - -void ivas_agc_dec_process( - ivas_agc_dec_state_t *hAgcDec, /* i/o: AGC decoder handle */ - float *pcm_in[], /* i : input audio channels */ - float *pcm_out[], /* o : output audio channels */ - const int16_t n_channels, /* i : number of channels */ - const int16_t output_Fs /* i : output sampling rate */ -); - -void ivas_agc_read_bits( - ivas_agc_dec_state_t *hAgcDec, /* i/o: AGC decoder handle */ - Decoder_State *st0, /* i/o: decoder state structure - for bitstream handling*/ - const int16_t n_channels, /* i : number of channels */ - const int16_t AGC_flag /* i : AGC on/off flag */ -); - -void ivas_agc_initWindowFunc( - float *pWinFunc, - const int16_t length -); - -void ivas_agc_calcGainParams( - uint16_t *absEmin, - uint16_t *betaE, - uint16_t *maxAttExp, - const int16_t numCoeffs -); - -float ivas_get_mdct_scaling_gain( - const int16_t dct_len_by_2 -); - -void ivas_get_twid_factors( - const int16_t length, - const float **pTwid_re, - const float **pTwid_im -); - -int16_t ivas_get_bw_idx_from_sample_rate( - const int32_t sampling_rate /* i : sampling rate */ -); - -/*! r: config. table index */ -int16_t ivas_get_spar_table_idx( - const int32_t ivas_total_brate, /* i : IVAS total bitrate */ - const int16_t sba_order, /* i : IVAS SBA order */ - const int16_t bwidth, /* i : audio bandwidth */ - int16_t *bitlen, /* o : number of bits */ - int16_t *ind /* o : indice */ -); - -/*! r: number of transport channels */ -int16_t ivas_get_sba_num_TCs( - const int32_t ivas_total_brate, /* i : IVAS total bitrate */ - const int16_t sba_order /* i : IVAS SBA order */ -); - - -void ivas_spar_bitrate_dist( - int32_t core_brates_act[], /* o : bitrates per core-coder */ - const int16_t nAvailBits, /* i : number of available bits */ - const int32_t ivas_total_brate, /* i : IVAS total bitrate */ - const int16_t sba_order, /* i : Ambisonic (SBA) order */ - const int16_t bwidth /* i : audio bandwidth */ -); - -void ivas_mdct( - const float *pIn, - float *pOut, - const int16_t length -); - -void ivas_dct_windowing( - const int16_t fade_len, - const int16_t full_len, - const int16_t dct_len, - const int16_t zero_pad_len, - const float *pWindow_coeffs, - const int16_t frame_len, - float *pOut_buf, - float *pBuffer_prev, - float *pTemp_lfe -); - -void ivas_tda( - const float *pIn, - float *pOut, - const int16_t length -); - -void ivas_imdct( - const float *pIn, - float *pOut, - const int16_t length -); - -void ivas_itda( - const float *re, - float *pOut, - const int16_t length -); - -void ivas_spar_get_cldfb_gains( - SPAR_DEC_HANDLE hSpar, - HANDLE_CLDFB_FILTER_BANK cldfbAnaDec0, - HANDLE_CLDFB_FILTER_BANK cldfbSynDec0, - const DECODER_CONFIG_HANDLE hDecoderConfig -); - -/*! r: 1 if prediction residual channel */ - -void ivas_spar_dec_agc_pca( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */ - float *output[], /* i/o: input/output audio channels */ - const Word16 output_frame /* i : output frame length */ -); - -void ivas_spar_dec_set_render_map( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ - const int16_t nCldfbTs /* i : number of CLDFB time slots */ -); - -void ivas_spar_dec_set_render_params( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */ - const int16_t n_cldfb_slots /* i : number of cldfb slots in this frame */ -); - -void ivas_spar_dec_digest_tc( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */ - const int16_t nchan_transport, /* i : number of transport channels */ - const int16_t nCldfbSlots, /* i : number of CLDFB slots */ - const int16_t nSamplesForRendering /* i : number of samples provided */ -); - -void ivas_sba_dec_digest_tc( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */ - const int16_t nCldfbSlots, /* i : number of CLDFB slots */ - const int16_t nSamplesForRendering /* i : number of samples provided */ -); - -ivas_error ivas_sba_dec_render( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */ - const uint16_t nSamplesAsked, /* i : number of CLDFB slots requested */ - uint16_t *nSamplesRendered, /* o : number of CLDFB slots rendered */ - uint16_t *nSamplesAvailable, /* o : number of CLDFB slots still to render */ - float *output_f[] /* o : rendered time signal */ -); - -void ivas_spar_dec_upmixer_sf( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */ - float *output[], /* o : output audio channels */ - const int16_t nchan_internal /* i : number of internal channels */ -); - -void ivas_spar_dec_upmixer( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */ - float *output[], /* i/o: input/output audio channels */ - const int16_t nchan_internal, /* i : number of internal channels */ - const int16_t output_frame /* i : output frame length */ -); - -/* MD module */ - -void ivas_spar_md_enc_close( - ivas_spar_md_enc_state_t **hMdEnc /* i/o: SPAR MD encoder handle */ -); - -void ivas_compute_spar_params( - float *pppCov_mat_re[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH], - float dm_fv_re[IVAS_SPAR_MAX_CH - 1][IVAS_MAX_NUM_BANDS], - const int16_t i_ts, - float ***mixer_mat, - const int16_t start_band, - const int16_t end_band, - const int16_t dtx_vad, - const int16_t num_ch, - const int16_t bands_bw, - const int16_t active_w, - const int16_t active_w_vlbr, - ivas_spar_md_com_cfg *hSparCfg, - ivas_spar_md_t *hSparMd, - float *pWscale, - const int16_t from_dirac, - const int16_t dyn_active_w_flag -); - -void ivas_create_fullr_dmx_mat( - float pred_coeffs_re[IVAS_SPAR_MAX_CH - 1][IVAS_MAX_NUM_BANDS], - float dm_fv_re[IVAS_SPAR_MAX_CH - 1][IVAS_MAX_NUM_BANDS], - float ***mixer_mat, - const int16_t in_chans, - const int16_t start_band, - const int16_t end_band, - const int16_t active_w, - ivas_spar_md_com_cfg *hMdCfg -); - -void ivas_calc_c_p_coeffs( - ivas_spar_md_t *pSparMd, - float *pppCov_mat_re[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH], - const int16_t i_ts, - float ***mixer_mat, - const int16_t num_ch, - const int16_t num_dmx, - const int16_t band_idx, - const int16_t dtx_vad, - const int16_t compute_p_flag, - const int16_t dyn_active_w_flag -); - -void ivas_get_spar_md_from_dirac( - float azi_dirac[IVAS_MAX_NUM_BANDS][MAX_PARAM_SPATIAL_SUBFRAMES], - float ele_dirac[IVAS_MAX_NUM_BANDS][MAX_PARAM_SPATIAL_SUBFRAMES], - float diffuseness[IVAS_MAX_NUM_BANDS], - const int16_t n_ts, - float ***mixer_mat, - ivas_spar_md_t *hSpar_md, - ivas_spar_md_com_cfg *hSpar_md_cfg, - const int16_t start_band, - const int16_t end_band, - const int16_t order, - const int16_t dtx_vad, - float Wscale_d[IVAS_MAX_NUM_BANDS], - const uint8_t useLowerRes, - const int16_t active_w_vlbr, - const int16_t dyn_active_w_flag -); - -/*! r: number of MD subframes */ - -ivas_error ivas_spar_md_dec_matrix_open( - ivas_spar_md_dec_state_t *hMdDec, /* i/o: SPAR MD decoder handle */ - const int16_t num_channels, /* i : number of internal channels */ - const int16_t num_md_sub_frames -); - -void ivas_spar_md_dec_matrix_close( - ivas_spar_md_dec_state_t *hMdDecoder, /* i/o: SPAR MD decoder handle */ - const int16_t num_channels /* i : number of internal channels */ -); - -ivas_error ivas_spar_md_dec_open( - ivas_spar_md_dec_state_t **hMdDec_out, /* i/o: SPAR MD decoder handle */ - const DECODER_CONFIG_HANDLE hDecoderConfig, /* i : configuration structure */ - const int16_t num_channels, /* i : number of internal channels */ - const int16_t sba_order, /* i : SBA order */ - const int16_t sid_format, /* i : SID format */ - const int32_t last_active_ivas_total_brate /* i : IVAS last active bitrate */ -); - -void ivas_spar_md_dec_close( - ivas_spar_md_dec_state_t **hMdDec /* i/o: SPAR MD decoder handle */ -); - -void ivas_spar_get_parameters( - SPAR_DEC_HANDLE hSpar, /* i/o: SPAR decoder handle */ - const DECODER_CONFIG_HANDLE hDecoderConfig, /* i : configuration structure */ - const int16_t ts, /* i : time slot index */ - const int16_t num_ch_out, /* i : number of channels out */ - const int16_t num_ch_in, /* i : number of channels in */ - const int16_t num_spar_bands, /* i : number of SPAR bands */ - float par_mat[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH][IVAS_MAX_NUM_BANDS] /* o : mixing matrix */ -); - -ivas_error ivas_spar_md_dec_init( - ivas_spar_md_dec_state_t *hMdDec, /* i/o: SPAR MD decoder handle */ - const DECODER_CONFIG_HANDLE hDecoderConfig, /* i : configuration structure */ - const int16_t num_channels, /* i : number of internal channels */ - const int16_t sba_order /* i : SBA order */ -); - -void ivas_spar_md_dec_process( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */ - Decoder_State *st0, /* i/o: decoder state structure - for bitstream handling*/ - const int16_t num_bands_out, /* i : number of output bands */ - const int16_t sba_order /* i : SBA order */ -); - -void ivas_spar_to_dirac( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */ - ivas_spar_md_dec_state_t *hMdDec, /* i/o: SPAR MD decoder handle */ - const int16_t dtx_vad, /* i : DTX frame flag */ - const int16_t num_bands_out, /* i : number of output bands */ - const int16_t bw, /* i : band joining factor */ - const int16_t dyn_active_w_flag /* i : dynamic active W flag */ -); - -void ivas_spar_update_md_hist( - ivas_spar_md_dec_state_t *hMdDec /* i/o: SPAR MD decoder handle */ -); - -int16_t ivas_spar_chk_zero_coefs( - Decoder_Struct *st_ivas /* i/o: IVAS decoder handle */ -); - -void ivas_spar_smooth_md_dtx( - ivas_spar_md_dec_state_t *hMdDec, /* i/o: SPAR MD decoder handle */ - const int16_t num_bands_out, /* i : number of output bands */ - const int16_t num_md_sub_frames /* i : number of metadata subframes */ -); - -void ivas_spar_setup_md_smoothing( - ivas_spar_md_dec_state_t *hMdDec, /* i/o: SPAR MD decoder handle */ - const int16_t num_bands_out, /* i : number of output bands */ - const int16_t num_md_sub_frames /* i : number of metadata subframes */ -); - -void ivas_spar_dec_gen_umx_mat( - ivas_spar_md_dec_state_t *hMdDec, /* i/o: SPAR MD decoder handle */ - const int16_t nchan_transport, /* i : number of transport channels */ - const int16_t num_bands_out, /* i : number of output bands */ - const int16_t bfi, /* i : bad frame indicator */ - const int16_t num_md_sub_frames -); - - - - - -/* Transient detector module */ -ivas_error ivas_transient_det_open_fx( - ivas_trans_det_state_t **hTranDet, /* i/o: Transient detector handle */ - const Word32 sampling_rate /* i : sampling rate */ -); - -void ivas_transient_det_close_fx( - ivas_trans_det_state_t **hTranDet /* i/o: Transient detector handle */ -); - -void ivas_transient_det_process( - ivas_trans_det_state_t *hTranDet, /* i/o: SPAR TD handle */ - float *pIn_pcm, /* i : input audio channels */ - const int16_t frame_len, /* i : frame length in samples */ - int16_t transient_det[2] /* o : transient det outputs */ -); - -void ivas_td_decorr_get_ducking_gains( - ivas_trans_det_state_t *hTranDet, /* i/o: Transient detector handle */ - float *pIn_pcm, - float *pIn_duck_gains, - float *pOut_duck_gains, - const int16_t frame_len, - const int16_t tdet_flag -); - -#define IVAS_CMULT_FLOAT( in1_re, in1_im, in2_re, in2_im, out1_re, out1_im ) \ - out1_re = ( in1_re * in2_re ) - ( in1_im * in2_im ); MAC(1); MULT(1); \ - out1_im = ( in1_re * in2_im ) + ( in2_re * in1_im ); MAC(1); MULT(1); - -#define IVAS_CALCULATE_ABS( re, im, out ) \ - out = sqrtf( ( re * re ) + ( im * im ) ); MAC(1); MULT(1); SQRT(1); - -#define IVAS_CALCULATE_RABS( re, out ) \ - out = sqrtf( re * re ); MULT(1); SQRT(1); - -#define IVAS_CALCULATE_SQ_ABS( re, im, out ) \ - out = (float) ( ( re * re ) + ( im * im ) ); MAC(1); MULT(1); - -#define IVAS_RMULT_DOUBLE( in1_re, in2_re, out1_re ) \ - out1_re = ( in1_re * in2_re ); DMULT(1); \ - -#define IVAS_CALCULATE_SQ_ABS_N( re, out ) \ - out = (float) ( re * re ); MULT(1); - -#define IVAS_RMULT_FLOAT( in1_re, in2_re, out1_re ) \ - out1_re = ( in1_re * in2_re ); MULT(1); - - -/* PCA */ -void ivas_pca_enc_init( - PCA_ENC_STATE *hPCA /* i/o: PCA encoder structure */ -); - -void ivas_pca_read_bits( - Decoder_State *st0, /* i/o: decoder state structure - for bitstream handling*/ - PCA_DEC_STATE *hPCA /* i/o: PCA encoder structure */ -); - -void ivas_pca_dec_init( - PCA_DEC_STATE *hPCA /* i/o: PCA decoder structure */ -); - -void ivas_pca_dec( - PCA_DEC_STATE *hPCA, /* i/o: PCA decoder structure */ - const int16_t n_samples, /* i : output frame length */ - const int16_t n_channels, /* i : number of channels */ - const int32_t ivas_total_brate, /* i : IVAS total bitrate */ - const int32_t last_ivas_total_brate, /* i : last IVAS total bitrate */ - const int16_t bfi, /* i : bad frame indicator */ - float *pcm_out[] /* o : output audio channels */ -); - -void pca_dec_s3( - const int32_t index, - float *q -); - - -void ivas_huffman_encode( - ivas_huffman_cfg_t *huff_cfg, - int16_t in, - int16_t *hcode, - int16_t *hlen -); - - - -ivas_error ivas_huffman_decode( - ivas_huffman_cfg_t *huff_cfg, - Decoder_State *st0, - int16_t *dec_out -); - -void ivas_arith_decode_cmplx_cell_array( - ivas_arith_t *pArith_re, - ivas_arith_t *pArith_re_diff, - Decoder_State *st0, - ivas_cell_dim_t *pCell_dims, - int16_t *pDo_diff, const int16_t nB, - int16_t *pSymbol_re, - int16_t *pSymbol_re_old -); - - - - -void ivas_ari_done_encoding_14bits( - BSTR_ENC_HANDLE hBstr, Tastat *s -); - - -void ivas_wrap_arround( - int16_t *pArr, - const int16_t min_val, - const int16_t max_val, - const int16_t length -); - -void ivas_get_cum_freq_model( - const int16_t *pFreq_model, - const int16_t length, - int16_t *pCum_freq_model -); - -int16_t ivas_map_num_pred_r_to_idx( - const int16_t num_quant_points_pred_r, - const int16_t active_w_flag -); - -int16_t ivas_map_num_drct_r_to_idx( - const int16_t num_quant_points_drct_r -); - -int16_t ivas_map_num_decd_r_to_idx( - const int16_t num_quant_points_decd_r -); - -/* Quantization utilities */ -void ivas_quantise_real_values( - const float *values, - const int16_t q_levels, - const float min_value, - const float max_value, - int16_t *index, - float *quant, - const int16_t dim -); - - -void ivas_spar_quant_dtx_init( - ivas_spar_md_t *spar_md, - float *min_max -); - -void ivas_map_prior_coeffs_quant( - ivas_spar_md_prev_t *pSpar_md_prior, - ivas_spar_md_com_cfg *pSpar_md_cfg, - const int16_t qsi, - const int16_t nB -); - - -void ivas_clear_band_coeffs( - ivas_band_coeffs_t *pband_coeffs, - const uint16_t num_bands -); - -void ivas_clear_band_coeff_idx( - ivas_band_coeffs_ind_t *pband_coeff_idx, - const uint16_t num_bands -); - - -/*----------------------------------------------------------------------------------* - * MASA prototypes - *----------------------------------------------------------------------------------*/ - -ivas_error ivas_masa_decode( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder struct */ - Decoder_State *st, /* i/o: decoder state structure */ - int16_t *nb_bits_read /* o : number of bits read */ -); - -void generate_gridEq( - SPHERICAL_GRID_DATA *data /* o : data structure for grid */ -); - -ivas_error ivas_masa_enc_open( - Encoder_Struct *st_ivas /* i/o: IVAS encoder handle */ -); - -void ivas_masa_enc_close( - MASA_ENCODER_HANDLE *hMasa /* i/o: MASA metadata structure */ -); - -void ivas_masa_enc_reconfigure( - Encoder_Struct *st_ivas /* i/o: IVAS encoder structure */ -); - -ivas_error ivas_masa_dec_reconfigure( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ - uint16_t *nSamplesRendered, /* o : number of samples flushed from the previous frame (JBM) */ - int16_t *data /* o : output synthesis signal */ -); - -ivas_error ivas_masa_encode( - MASA_ENCODER_HANDLE hMasa, /* i/o: MASA encoder structure */ - IVAS_QMETADATA_HANDLE hQMetaData, /* i/o: q_metadata handle */ - BSTR_ENC_HANDLE hMetaData, /* i/o: Metadata bitstream handle */ - int16_t *nb_bits_metadata, /* o : number of metadata bits written */ - const int16_t nchan_transport, /* i : number of MASA input/transport channels */ - const IVAS_FORMAT ivas_format, /* i : IVAS format */ - const int32_t ivas_total_brate, /* i : IVAS total bitrate */ - const int16_t Opt_DTX_ON, /* i : DTX on flag */ - const int16_t element_mode, /* i : element mode */ - const ISM_MODE ism_mode, /* i : ISM format mode */ - const int16_t nchan_ism, /* i : number of ISM channels */ - ISM_METADATA_HANDLE hIsmMetaData[MAX_NUM_OBJECTS], /* i : ISM metadata handle */ - const int16_t idx_separated_object, /* i : index of the separated object */ - OMASA_ENC_HANDLE hOMasa, /* i : OMASA encoder handle */ - const int16_t ism_imp, /* i : importance of separated object */ - const int16_t flag_omasa_ener_brate /* i : less bitrate for objects in OMASA flag */ -); - -void ivas_masa_estimate_energy( - MASA_ENCODER_HANDLE hMasa, /* i/o: MASA encoder structure */ - float *data_f[], /* i : Input audio channels */ - const int16_t input_frame, /* i : frame length */ - const int16_t nchan_transport /* i : number of MASA input/transport channels */ -); - - -void ivas_masa_set_elements( - const int32_t ivas_total_brate, /* i : codec total bitrate */ - const int16_t mc_mode, /* i : MC format mode */ - const int16_t nchan_transport, /* i : number of MASA input/transport channels */ - IVAS_QMETADATA_HANDLE hQMetaData, /* i/o: q_metadata handle */ - int16_t *element_mode, /* o : element mode */ - int16_t *nSCE, /* o : number of SCEs */ - int16_t *nCPE, /* o : number of CPEs */ - const int16_t ivas_format, /* i : IVAS format */ - const ISM_MODE ism_mode, /* i : ISM mode */ - const int32_t ism_total_brate /* i : initial ISM total bitrate */ -); - -/*! r: valid or not 1/0 */ -int16_t valid_ratio_index( - int16_t index, /* i : index to be checked */ - const int16_t K, /* i : L1 norm to check against */ - const int16_t len /* i : vector length */ -); - -void reconstruct_ism_ratios( - int16_t *ratio_ism_idx, - const int16_t nchan_ism, - const float step, - float *q_energy_ratio_ism -); - -void distribute_evenly_ism( - int16_t *idx, - const int16_t K, - const int16_t nchan_ism -); - - -int16_t ivas_qmetadata_encode_extended_gr_length( - const uint16_t value, - const uint16_t alphabet_size, - const int16_t gr_param); - -void ivas_qmetadata_encode_extended_gr( - BSTR_ENC_HANDLE hMetaData, /* i/o: q_metadata handle */ - const uint16_t value, /* i : value to be encoded */ - const uint16_t alphabet_size, /* i : alphabet size */ - const int16_t gr_param); /* i : GR order */ - -/*! r: CPE bitrate value */ -int32_t calculate_cpe_brate_MASA_ISM( - const ISM_MODE ism_mode, /* i : ism mode */ - const int32_t ivas_total_brate, /* i : IVAS total bitrate */ - const int16_t nchan_ism /* i : number of objects */ -); - -void ivas_merge_masa_metadata( - MASA_ENCODER_HANDLE hMasa, /* i/o: MASA enc handle. source for MASA metadata and combined metadata will be here */ - OMASA_SPATIAL_META_HANDLE hOMasaMeta /* i : ISM-object metadata to be merged with the MASA metadata */ -); - - -/*!r : number of bits for ISM ratio index */ -int16_t bits_index_ism_ratio( - const int16_t nchan_ism /* i : number of objects */ -); - -void calculate_nbits_meta( - const int16_t nchan_ism, - float q_energy_ratio_ism[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS][MAX_NUM_OBJECTS], - float masa_to_total_energy_ratio[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], - const int16_t numSf, - const int16_t numCodingBands, - int16_t* bits_ism, - const int16_t idx_sep_obj, - const int16_t ism_imp -); - -/*! r: limitation flag */ -int16_t calculate_brate_limit_flag( - const int16_t ism_imp[], /* i : ISM importance flags */ - const int16_t nchan_ism /* i : number of objects */ -); - -void ivas_masa_set_coding_config( - MASA_CODEC_CONFIG* config, /* i/o: MASA coding config structure */ - int16_t* band_mapping, /* o : Band mapping used */ - const int32_t ivas_total_brate, /* i : codec total bitrate */ - const int16_t nchan_transport, /* i : number of transport channel (mono/stereo) */ - const uint8_t isMcMasa /* i : toggle for selecting McMASA specific config */ -); - -/*! r: Surround coherence significant flag */ -uint8_t ivas_masa_surrcoh_signicant( - float surroundingCoherence[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], /* i : Surround coherence */ - float diffuse_to_total_ratio[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], /* i : Diffuse to total ratio */ - const int16_t nSubFrames, /* i : Number of sub frames */ - const int16_t nBands /* i : Number of frequency bands */ -); - -void masa_compensate_two_dir_energy_ratio_index( - const int16_t ratio_index_1, /* i : Input ratio for direction 1 */ - const int16_t ratio_index_2, /* i : Input ratio for direction 2 */ - int16_t *ratio_index_mod1, /* o : Output modified ratio for direction 1 */ - int16_t *ratio_index_mod2, /* o : Output modified ratio for direction 2 */ - const int16_t hodirac_flag /* i : flag to indicate HO-DirAC mode */ -); - -void ivas_set_qmetadata_maxbit_req_fx( - IVAS_QMETADATA_HANDLE hQMetaData, /* o : qmetadata structure where the requirement value is set */ - const IVAS_FORMAT ivas_format /* i : IVAS format */ -); - -void masa_sample_rate_band_correction( - MASA_CODEC_CONFIG *config, /* i/o: MASA codec config */ - int16_t *band_mapping, /* i/o: Band mapping used and modified */ - IVAS_QMETADATA_HANDLE hQMetaData, /* i/o: QMetadata structure for modification */ - const uint8_t maxBand, /* i : max band */ - uint8_t is_encoder, /* i : signals if called at encoder */ - MASA_DECODER_EXT_OUT_META_HANDLE hExtOutMeta /* i/o: MASA decoder metadata ext out buffer */ -); - -void invdct4_transform( - float *v, /* i : input vector */ - uint8_t *invdct_v /* o : transformed vector */ -); - - -void ivas_spar_param_to_masa_param_mapping( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder struct */ - float inRe[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], /* i : Input audio in CLDFB domain, real */ - float inIm[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], /* i : Input audio in CLDFB domain, imag */ - const int16_t subframe /* i : Subframe to map */ -); - -/*---------------------------------------------------------------------------------* - * Binaural FastConv Renderer Prototypes -*-----------------------------------------------------------------------------------*/ - - -void ivas_binaural_hrtf_close( - HRTFS_FASTCONV_HANDLE *hHrtfFastConv /* i/o: decoder binaural hrtf handle */ -); - -void ivas_binRenderer( - BINAURAL_RENDERER_HANDLE hBinRenderer, /* i/o: binaural renderer handle */ - COMBINED_ORIENTATION_HANDLE hCombinedOrientationData, /* i : combined head and external orientation handle */ - const int16_t numTimeSlots, /* i : number of time slots to process */ - float Cldfb_RealBuffer_Binaural[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* o : Binaural signals */ - float Cldfb_ImagBuffer_Binaural[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* o : Binaural signals */ - float RealBuffer[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* i : LS signals */ - float ImagBuffer[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX] /* i : LS signals */ -); - -void ivas_binaural_add_LFE( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ - int16_t output_frame, /* i : length of input frame */ - float *input_f[], /* i : transport channels */ - float *output_f[] /* o : synthesized core-coder transport channels/DirAC output */ -); - -/*----------------------------------------------------------------------------------* - * renderer prototypes - *----------------------------------------------------------------------------------*/ - -ivas_error ivas_ism_renderer_open( - Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */ -); - -void ivas_ism_renderer_close( - ISM_RENDERER_HANDLE *hIsmRendererData /* i/o: ISM renderer handle */ -); - -void ivas_ism_render_sf( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ - float *output_f[], /* i/o: core-coder transport channels/object output */ - const int16_t n_samples_to_render /* i : output frame length per channel */ -); - - -void ivas_mc2sba( - IVAS_OUTPUT_SETUP hIntSetup, /* i : Format of decoder output */ - float *in_buffer_td[], /* i : MC signals (on input) and the HOA3 (on output) */ - float *buffer_td[], /* o : MC signals (on input) and the HOA3 (on output) */ - const int16_t output_frame, /* i : output frame length per channel */ - const int16_t sba_order, /* i : SBA order */ - const float gain_lfe /* i : gain for LFE, 0=ignore LFE */ -); - -void ivas_param_mc_mc2sba_cldfb( - IVAS_OUTPUT_SETUP hTransSetup, /* i : transported MC Format */ - float *hoa_encoder, /* i : HOA3 encoder for the transported MC format */ - const int16_t slot_idx, /* i : current slot in the subframe */ - float Cldfb_RealBuffer[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* i/o: Contains the MC signals (on input) and the HOA3 (on output) */ - float Cldfb_ImagBuffer[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* i/o: Contains the MC signals (on input) and the HOA3 (on output) */ - const int16_t nBands, /* i : number of synth CLDFB bands */ - const float gain_lfe /* i : gain applied to LFE */ -); - - -/*----------------------------------------------------------------------------------* - * Amplitude Panning VBAP prototypes - *----------------------------------------------------------------------------------*/ - -void panning_wrap_angles( - const float azi_deg, /* i : azimuth in degrees for panning direction (positive left) */ - const float ele_deg, /* i : elevation in degrees for panning direction (positive up) */ - float *azi_wrapped, /* o : wrapped azimuth component */ - float *ele_wrapped /* o : wrapped elevation component */ -); - -/*----------------------------------------------------------------------------------* - * LS Renderer prototypes - *----------------------------------------------------------------------------------*/ - -ivas_error ivas_ls_setup_conversion_open( - Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */ -); - -void ivas_ls_setup_conversion_close( - LSSETUP_CONVERSION_HANDLE *hLsSetUpConversion /* i/o: LS converter handle */ -); - - -void ivas_ls_setup_conversion( - Decoder_Struct *st_ivas, /* i : IVAS decoder structure */ - const int16_t input_chans, /* i : number of input channels to the renderer */ - const int16_t output_frame, /* i : frame length */ - float *input[], /* i : LS input/output synthesis signal */ - float *output[] /* i/o: LS input/output synthesis signal */ -); - -void ivas_ls_setup_conversion_process_mdct( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ - float *output[] /* i/o: output synthesis signal */ -); - -void ivas_ls_setup_conversion_process_mdct_param_mc( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ - float *x[][NB_DIV] /* i/o: output synthesis signal */ -); - -void ivas_lssetupconversion_process_param_mc( - Decoder_Struct *st_ivas, /* i/o: LS setup conversion renderer handle */ - const int16_t num_timeslots, /* i : number of time slots to process */ - float Cldfb_RealBuffer_InOut[MAX_CICP_CHANNELS][PARAM_MC_MAX_NSLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX], /* i/o: LS signals */ - float Cldfb_ImagBuffer_InOut[MAX_CICP_CHANNELS][PARAM_MC_MAX_NSLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX], /* i/o: LS signals */ - int16_t channel_active[MAX_CICP_CHANNELS] /* i : bitmap indicating which output channels are active */ -); - - -/*----------------------------------------------------------------------------------* - * Custom loudspeaker setup prototypes - *----------------------------------------------------------------------------------*/ - -ivas_error ivas_ls_custom_open( - LSSETUP_CUSTOM_HANDLE *hLsSetupCustom /* o : Custom loudspeaker setup handle */ -); - - - -/*----------------------------------------------------------------------------------* - * McMASA prototypes - *----------------------------------------------------------------------------------*/ - - -ivas_error ivas_mcmasa_dec_reconfig( - Decoder_Struct *st_ivas /* i/o: IVAS decoder handle */ -); - -void ivas_mcmasa_setNumTransportChannels( - int16_t* nchan_transport, /* o : Pointer to number of transport channels to be set */ - int16_t* element_mode, /* o : Pointer to element mode to be set */ - const int32_t ivas_total_brate /* i : Total bitrate of IVAS */ -); - -void ivas_mcmasa_set_separate_channel_mode( - uint8_t *separateChannelEnabled, /* o : Pointer to separate channel toggle */ - int16_t *separateChannelIndex, /* o : Pointer to separate channel index */ - const int32_t ivas_total_brate /* i : Total bitrate of IVAS */ -); - -void ivas_mcmasa_split_brate( - const uint8_t separateChannelEnabled, /* i : Transport running in "separate channel" mode */ - const int32_t ivas_total_brate, /* i : Total bitrate available to be split */ - const int16_t nSCE, /* i : Number of SCEs in use (0 or 1) */ - const int16_t nCPE, /* i : Number of CPEs in use (0 or 1) */ - int32_t *brate_sce, /* o : Pointer to SCE element bitrate */ - int32_t *brate_cpe /* o : Pointer to CPE element bitrate */ -); - - -void ivas_mcmasa_dmx_modify_fx( - const Word16 n_samples, /* i : input frame length in samples */ - Word32 dmx_fx[][L_FRAME48k + NS2SA(48000, IVAS_FB_ENC_DELAY_NS)], /* i/o: downmix signal to be transformed into another format Qx*/ - const Word16 n_chnls_dmx_old, /* i : number of downmix channels in the old format Q0*/ - const Word16 n_chnls_dmx_new /* i : number of downmix channels in the target format Q0*/ -); - -ivas_error ivas_mono_dmx_renderer_open( - Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */ -); - - -void ivas_mono_dmx_renderer_close( - MONO_DOWNMIX_RENDERER_HANDLE *hMonoDmxRenderer /* i/ i/o: Mono downmix structure */ -); - -void ivas_mono_downmix_render_passive( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ - float *output_f[], /* i/o: synthesized core-coder transport channels/mono output */ - const int16_t output_frame /* i : output frame length */ -); - - -/*----------------------------------------------------------------------------------* - * LFE encoder low pass filter prototypes - *----------------------------------------------------------------------------------*/ - -ivas_error ivas_create_lfe_lpf_enc( - ivas_filters_process_state_t **hLfeLpf, /* o : LFE LPF handle */ - const int32_t input_Fs /* i : input sampling rate */ -); - -void ivas_lfe_lpf_enc_close( - ivas_filters_process_state_t **hLfeLpf /* i/o: LFE LPF handle */ -); - -void ivas_lfe_lpf_enc_apply( - ivas_filters_process_state_t *hLfeLpf, /* i/o: LFE LPF handle */ - float data_lfe_ch[], /* i/o: LFE signal */ - const int16_t input_frame /* i : input frame length per channel */ -); - - -/*----------------------------------------------------------------------------------* - * LFE Coding prototypes - *----------------------------------------------------------------------------------*/ - -ivas_error ivas_create_lfe_enc( - LFE_ENC_HANDLE *hLFE, /* o : IVAS LFE encoder structure */ - const int32_t input_Fs /* i : input sampling rate */ -); - -void ivas_lfe_enc_close( - LFE_ENC_HANDLE *hLFE /* i/o: LFE encoder handle */ -); - -void ivas_lfe_enc( - LFE_ENC_HANDLE hLFE, /* i/o: LFE encoder handle */ - float data_lfe_ch[], /* i : input LFE signal */ - const int16_t input_frame, /* i : input frame length per channel */ - BSTR_ENC_HANDLE hBstr /* i/o: bitstream handle */ -); - -void ivas_lfe_tdplc( - LFE_DEC_HANDLE hLFE, /* i/o: LFE decoder handle */ - float *prevsynth, /* i : previous frame synthesis */ - float *ytda, /* o : output time-domain buffer */ - const int16_t output_frame /* i : output frame length */ -); -void ivas_lfe_window_init( - LFE_WINDOW_HANDLE hLFEWindow, /* i/o: LFE window handle */ - const int32_t sampling_rate, /* i : sampling rate */ - const int16_t frame_len /* i : frame length in samples */ -); - -void ivas_lfe_lpf_select_filt_coeff( - const int32_t sampling_rate, /* i : sampling rate */ - const int16_t order, /* i : filter order */ - const float **ppFilt_coeff /* o : filter coefficients */ -); - -void ivas_filters_init( - ivas_filters_process_state_t *filter_state, /* i/o: filter state handle */ - const float *filt_coeff, /* i : filter coefficients */ - const int16_t order /* i : filter order */ -); - -void ivas_filters_init_fx( - ivas_filters_process_state_t *filter_state, /* i/o: filter state handle */ - const Word32 *filt_coeff_fx, /* i : filter coefficients Q31- *filt_coeff_e */ - const Word16 *filt_coeff_e, /* i : exponents of filter coefficients */ - const Word16 order ) ; - -void ivas_filter_process( - ivas_filters_process_state_t *filter_state, /* i/o: filter state handle */ - float *pIn_Out, /* i : signal subject to filtering */ - const int16_t length /* i : filter order */ -); - -void ivas_filter_process_fx( - ivas_filters_process_state_t *filter_state, /* i/o: filter state handle */ - Word32 *pIn_Out_fx, /* i/o: signal subject to filtering Q(q_factor) */ - const Word16 length, /* i : filter order */ - Word16 q_factor ); - -/*----------------------------------------------------------------------------------* - * OSBA prototypes - *----------------------------------------------------------------------------------*/ -ivas_error ivas_osba_enc_reconfig( - Encoder_Struct *st_ivas /* i/o: IVAS encoder structure */ -); -ivas_error ivas_osba_data_open( - Decoder_Struct *st_ivas /* i/o: IVAS decoder handle */ -); - -ivas_error ivas_osba_dirac_td_binaural_jbm( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ - const uint16_t nSamplesAsked, /* i : number of CLDFB slots requested */ - uint16_t *nSamplesRendered, /* o : number of CLDFB slots rendered */ - uint16_t *nSamplesAvailable, /* o : number of CLDFB slots still to render */ - float *output_f[] /* o : rendered time signal */ -); - - -void ivas_osba_data_close( - SBA_ISM_DATA_HANDLE *hSbaIsmData /* i/o: OSBA rendering handle */ -); - - -/*----------------------------------------------------------------------------------* -* OMASA prototypes -*---------------------------------------------------------------------------------*/ - -ivas_error ivas_omasa_enc_open( - Encoder_Struct *st_ivas /* i/o: IVAS encoder handle */ -); - -void ivas_omasa_enc_close( - OMASA_ENC_HANDLE *hOMasa /* i/o: encoder OMASA handle */ -); - - -ivas_error ivas_omasa_dec_config( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ - uint16_t *nSamplesRendered, /* o : number of samples flushed from the previous frame (JBM) */ - int16_t *data /* o : output synthesis signal */ -); - - - - -void ivas_set_surplus_brate_enc( - Encoder_Struct *st_ivas /* i/o: IVAS encoder structure */ -#ifdef DEBUG_MODE_INFO - , - const int16_t *nb_bits_metadata /* i : number of metadata bits */ -#endif -); - -void ivas_set_surplus_brate_dec( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ - int32_t *ism_total_brate /* i : ISM total bitrate */ -); - - -void ivas_set_ism_importance_interformat( - const int32_t ism_total_brate, /* i/o: ISms total bitrate */ - const int16_t nchan_transport, /* i : number of transported channels */ - ISM_METADATA_HANDLE hIsmMeta[], /* i/o: ISM metadata handles */ - SCE_ENC_HANDLE hSCE[], /* i/o: SCE encoder handles */ - const float lp_noise_CPE, /* i : LP filtered total noise estimation */ - int16_t ism_imp[] /* o : ISM importance flags */ -); - - -/*! r: adjusted bitrate */ -int32_t ivas_interformat_brate( - const ISM_MODE ism_mode, /* i : ISM mode */ - const int16_t nchan_ism, /* i : number of ISM channels */ - const int32_t element_brate, /* i : element bitrate */ - const int16_t ism_imp, /* i : ISM importance flag */ - const int16_t limit_flag /* i : flag to limit the bitrate increase */ -); - -void ivas_combined_format_brate_sanity( - const int32_t element_brate, /* i : element bitrate */ - const int16_t core, /* i : core */ - const int32_t total_brate, /* i : total bitrate */ - int32_t *core_brate, /* i/o: core bitrate */ - int16_t *inactive_coder_type_flag, /* o : inactive coder_type flag */ - int16_t *diff_nBits /* o : number of differential bits */ -); - -ISM_MODE ivas_omasa_ism_mode_select( - const int32_t ivas_total_brate, /* i : IVAS total bitrate */ - const int16_t nchan_ism /* i : number of input ISM's */ -); - -void ivas_set_omasa_TC( - const ISM_MODE ism_mode, /* i : ISM mode */ - const int16_t nchan_ism, /* i : number of input ISMs */ - int16_t *nSCE, /* o : number of SCEs */ - int16_t *nCPE /* o : number of CPEs */ -); - -void ivas_merge_masa_transports( - float data_in_f1[][L_FRAME48k], /* i : Transport audio signals 1 */ - float *data_in_f2[], /* i : Transport audio signals 2 */ - float *data_out_f[], /* o : Merged transport audio signals */ - const int16_t input_frame, /* i : Input frame size */ - const int16_t num_transport_channels /* i : Number of transport audio signals */ -); - - -ivas_error ivas_omasa_ism_metadata_dec( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ - const int32_t ism_total_brate, /* i : ISM total bitrate */ - int16_t *nchan_ism, /* o : number of ISM separated channels */ - int16_t *nchan_transport_ism, /* o : number of ISM TCs */ - const int16_t dirac_bs_md_write_idx, /* i : DirAC bitstream write index */ - int16_t nb_bits_metadata[] /* o : number of ISM metadata bits */ -); - -void ivas_omasa_preProcessStereoTransportsForMovedObjects( - Decoder_Struct *st_ivas, - float inRe[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], - float inIm[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], - const int16_t nBins, - const int16_t subframe -); - -ivas_error ivas_omasa_separate_object_renderer_open( - Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */ -); - -void ivas_omasa_separate_object_renderer_close( - Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */ -); - -void ivas_omasa_separate_object_render_jbm( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ - const uint16_t nSamplesRendered, /* i : number of samples rendered */ - float input_f[][L_FRAME48k], /* i : separated object signal */ - float *output_f[], /* o : rendered time signal */ - const int16_t subframes_rendered, /* i : number of subframes rendered */ - const int16_t slots_rendered /* i : number of CLDFB slots rendered */ -); - -void ivas_omasa_encode_masa_to_total( - float masa_to_total_ratio[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], - BSTR_ENC_HANDLE hMetaData, - const int16_t low_bitrate_mode, - const int16_t nbands, - const int16_t nblocks -); - -void ivas_omasa_decode_masa_to_total( - uint16_t *bit_stream, - int16_t *index, - float masa_to_total_energy_ratio[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], - const int16_t nbands, - const int16_t nblocks -); - -void ivas_omasa_modify_masa_energy_ratios( - IVAS_QMETADATA_HANDLE hQMetaData, /* i/o: q_metadata handle */ - float masa_to_total_energy_ratio[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_MAXIMUM_CODING_SUBBANDS] -); - - -/*----------------------------------------------------------------------------------* - * TD Binaural Object renderer - *----------------------------------------------------------------------------------*/ - -ivas_error ivas_td_binaural_renderer( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ - float *output[], /* i/o: SCE channels / Binaural synthesis */ - const int16_t output_frame /* i : output frame length */ -); - -ivas_error ivas_td_binaural_renderer_sf( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ - float *output[], /* i/o: SCE channels / Binaural synthesis */ - const int16_t n_samples_granularity /* i : granularity of the renderer/buffer */ -); - -/*----------------------------------------------------------------------------------* - * Filter-bank (FB) Mixer - *----------------------------------------------------------------------------------*/ - -ivas_error ivas_fb_set_cfg( - IVAS_FB_CFG **pFb_cfg_out, /* o : FB config. handle */ - const int16_t ivas_format, /* i : IVAS format */ - const int16_t num_in_chans, /* i : number of FB input channels */ - const int16_t num_out_chans, /* i : number of FB output channels */ - const int16_t active_w_mixing, /* i : active_w_mixing flag */ - const int32_t sampling_Fs, /* i : sampling rate */ - const int16_t nachan_dirac_ana /* i : number of DirAR analysis channels */ -); - -void ivas_fb_mixer_pcm_ingest( - IVAS_FB_MIXER_HANDLE hFbMixer, /* i/o: FB mixer handle */ - float *pcm_in[], /* i : input audio channels */ - float **ppOut_pcm, /* o : output audio channels */ - const int16_t frame_length, /* i : frame length */ - const int16_t HOA_md_ind[IVAS_SPAR_MAX_CH] -); - -void ivas_fb_mixer_update_prior_input( - IVAS_FB_MIXER_HANDLE hFbMixer, /* i/o: FB mixer handle */ - float *pcm_in[], /* i : input audio channels */ - const int16_t length, /* i : length of time slot */ - const int16_t nchan_fb_in /* i : number of analysis channels */ -); - -void ivas_fb_mixer_get_windowed_fr( - IVAS_FB_MIXER_HANDLE hFbMixer, /* i/o: FB mixer handle */ - float *pcm_in[], /* i : input audio channels */ - float *frame_f_real[], /* o : real freq domain values */ - float *frame_f_imag[], /* o : imag freq domain values */ - const int16_t length, /* i : number of new samples in time slot */ - const int16_t mdft_len, /* i : MDFT frame length */ - const int16_t nchan_fb_in /* i : number of analysis channels */ -); - -/*! r: number of spectral bands */ - -/* clang-format on */ diff --git a/lib_com/ivas_prot_fx.h b/lib_com/ivas_prot_fx.h index 6fd0c777fb04e5fd0fd5f8c67e88a7735d58a080..afbcff3890ec93eaf9e7e4302778070496721fb0 100644 --- a/lib_com/ivas_prot_fx.h +++ b/lib_com/ivas_prot_fx.h @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other @@ -42,6 +42,7 @@ #include "stat_com.h" #include "ivas_stat_enc.h" #include "ivas_stat_dec.h" +#include "ivas_stat_rend.h" #include "ivas_stat_com.h" #include "ivas_error_utils.h" @@ -53,6 +54,17 @@ void ivas_masa_dec_close_fx( MASA_DECODER_HANDLE *hMasa /* i/o: MASA metadata structure */ ); +ivas_error create_evs_sce_enc_fx( + Encoder_Struct *st_ivas, /* i/o: IVAS encoder structure */ + const Word16 sce_id, /* i : SCE # identifier */ + const Word32 element_brate /* i : element bitrate */ +); + +void destroy_sce_enc_fx( + SCE_ENC_HANDLE hSCE, /* i/o: SCE encoder structure */ + Flag is_evs /* i : Flag to indicate EVS encoder */ +); + void generate_gridEq_fx( SPHERICAL_GRID_DATA *data /* o : data structure for grid */ ); @@ -1303,6 +1315,20 @@ Word16 matrix_diag_product_fx( Word32 *Z, /* o : resulting matrix after the matrix multiplication */ Word16 *Z_e ); +#ifdef OPT_BASOP_ADD_v1 +Word16 matrix_diag_product_fx_2( + const Word32 *X, /* i : left hand matrix Q31 - X_e*/ + const Word16 X_e, + const Word16 rowsX, /* i : number of rows of the left hand matrix Q0*/ + const Word16 colsX, /* i : number of columns of the left hand matrix Q0*/ + const Word16 transpX, /* i : flag indicating the transposition of the left hand matrix prior to the multiplication Q0*/ + const Word32 *Y, /* i : right hand diagonal matrix as vector containing the diagonal elements Q31 - Y_e*/ + const Word16 *Y_e, + const Word16 entriesY, /* i : number of entries in the diagonal Q0*/ + Word32 *Z, /* o : resulting matrix after the matrix multiplication Q31 - Z_e*/ + Word16 *Z_e ); +#endif /* OPT_BASOP_ADD_v1 */ + Word16 matrix_diag_product_fx_1( const Word32 *X, /* i : left hand matrix */ const Word16 *X_e, @@ -1868,7 +1894,7 @@ void ivas_wb_tbe_dec_fx( Word16 *synth, /* o : WB synthesis/final synthesis */ Word16 *Q_synth ); -void ivas_GenShapedWBExcitation_fx( +void GenShapedWBExcitation_ivas_fx( Word16 *excSHB, /* o : synthesized shaped shb exctiation Q_bwe_exc*/ const Word16 *lpc_shb, /* i : lpc coefficients Q12*/ Word16 *exc4kWhtnd, /* o : whitened synthesized shb excitation Q_bwe_exc*/ @@ -2226,11 +2252,7 @@ void ivas_mct_side_bits_fx( const Word16 nb_bits_metadata /* i : number of metadata bits */ ); -#ifdef BASOP_NOGLOB /*Critical overflow */ Flag conv_fx_32( -#else -void conv_fx_32( -#endif const Word16 x[], /* i : i vector Q_new*/ const Word16 h[], /* i : impulse response (or second i vector) Q(15)*/ Word32 y[], /* o : output vetor (result of convolution) 12 bits*/ @@ -2608,6 +2630,52 @@ Word16 getNumChanAnalysis_fx( Encoder_Struct *st_ivas /* i : IVAS encoder structure */ ); +/*----------------------------------------------------------------------------------* + * Limiter prototypes + *----------------------------------------------------------------------------------*/ + + +ivas_error ivas_limiter_open( + IVAS_LIMITER_HANDLE *hLimiter_out, /* o : limiter struct handle */ + const int16_t num_channels, /* i : number of I/O channels */ + const int32_t sampling_rate /* i : sampling rate for processing */ +); + +void ivas_limiter_close( + IVAS_LIMITER_HANDLE *phLimiter /* i/o: pointer to limiter handle, can be NULL */ +); + +void ivas_limiter_dec( + IVAS_LIMITER_HANDLE hLimiter, /* i/o: limiter struct handle */ + float *output[MAX_OUTPUT_CHANNELS], /* i/o: input/output buffer */ + const int16_t num_channels, /* i : number of channels to be processed */ + const int16_t output_frame, /* i : number of samples per channel in the buffer */ + const int16_t BER_detect /* i : BER detect flag */ +); +void ivas_limiter_dec_fx( + IVAS_LIMITER_HANDLE hLimiter, /* i/o: limiter struct handle */ + Word32 *output[MAX_OUTPUT_CHANNELS], /* i/o: input/output buffer */ + const Word16 num_channels, /* i : number of channels to be processed */ + const Word16 output_frame, /* i : number of samples per channel in the buffer */ + const Word16 BER_detect, /* i : BER detect flag */ + Word16 q_factor /* i : Q factor of the output samples */ +); +void limiter_process( + IVAS_LIMITER_HANDLE hLimiter, /* i/o: limiter struct handle */ + const int16_t output_frame, /* i : number of samples to be processed per channel in the I/O buffer */ + const float threshold, /* i : signal amplitude above which limiting starts to be applied */ + const int16_t BER_detect, /* i : BER detect flag */ + int16_t *strong_saturation_cnt /* i/o: counter of strong saturations (can be NULL) */ +); +void limiter_process_fx( + IVAS_LIMITER_HANDLE hLimiter, /* i/o: limiter struct handle */ + const Word16 output_frame, /* i : number of samples to be processed per channel in the I/O buffer */ + const Word32 threshold, /* i : signal amplitude above which limiting starts to be applied */ + const Word16 BER_detect, /* i : BER detect flag */ + Word16 *strong_saturation_cnt, /* i/o: counter of strong saturations (can be NULL) */ + Word16 q_factor /* i : Q factor of output samples */ +); + ivas_error ivas_limiter_open_fx( IVAS_LIMITER_HANDLE *hLimiter_out, /* o : limiter struct handle */ const Word16 max_num_channels, /* i : maximum number of I/O channels to be processed */ @@ -2805,18 +2873,18 @@ Word16 mdct_classifier_ivas_fx( * Range Coder prototypes *----------------------------------------------------------------------------------*/ -void rc_uni_enc_init( +void rc_uni_enc_init_fx( RangeUniEncState *rc_st_enc /* i/o: RC state handle */ ); -void rc_uni_enc_encode_fast( +void rc_uni_enc_encode_fast_fx( RangeUniEncState *rc_st_enc, /* i/o: RC state handle */ const UWord16 cum_freq, /* i : Cumulative frequency up to symbol */ const UWord16 sym_freq, /* i : Symbol frequency */ const UWord16 tot_shift /* i : Total frequency as a power of 2 */ ); -void rc_uni_enc_encode_symbol_fastS( +void rc_uni_enc_encode_symbol_fastS_fx( RangeUniEncState *rc_st_enc, /* i/o: Encoder state */ const UWord16 symbol, /* i : Symbol to encode */ const UWord16 cum_freq[], /* i : Cumulative frequency up to symbol */ @@ -2825,16 +2893,16 @@ void rc_uni_enc_encode_symbol_fastS( ); /*! r: Total number of bits produced */ -Word16 rc_uni_enc_finish( +Word16 rc_uni_enc_finish_fx( RangeUniEncState *rc_st_enc /* i/o: RC state handle */ ); /*! r: Total number of bits produced */ -Word16 rc_uni_enc_virtual_finish( +Word16 rc_uni_enc_virtual_finish_fx( RangeUniEncState *rc_st_enc /* i : RC state handle */ ); -void rc_uni_enc_encode_bits( +void rc_uni_enc_encode_bits_fx( RangeUniEncState *rc_st_enc, /* i/o: RC state handle */ const UWord16 value, /* i : Value to encode */ const Word16 bits /* i : Number of bits */ @@ -2901,7 +2969,7 @@ void stereo_dft_enc_write_BS_fx( void stereo_dft_enc_res_fx( STEREO_DFT_ENC_DATA_HANDLE hStereoDft, /* i/o: encoder stereo handle */ - const Word32 *input_8k, /* i : input buffer sampled at 8kHz Q16 */ + const Word32 *input_8k, /* i : input buffer sampled at 8kHz Q15 */ BSTR_ENC_HANDLE hBstr, /* i/o: bitstream handle */ Word16 *nb_bits, /* o : number of bits written */ const Word16 max_bits ); @@ -3101,6 +3169,12 @@ void ivas_smc_mode_selection_fx( const Word16 flag_spitch /* i : flag to indicate very short stable pitch*/ ); +/*! r: element mode */ +Word16 select_stereo_mode_fx( + CPE_ENC_HANDLE hCPE, /* i/o: CPE encoder structure */ + const IVAS_FORMAT ivas_format /* i : IVAS format */ +); + void stereo_classifier_features_ivas_fx( STEREO_CLASSIF_HANDLE hStereoClassif, /* i/o: stereo classifier structure */ const Word16 idchan, /* i : channel ID */ @@ -3228,7 +3302,12 @@ void computeDirectionVectors_fixed( Word32 *direction_vector_x, /*Q30*/ Word32 *direction_vector_y, /*Q30*/ Word32 *direction_vector_z, /*Q30*/ - Word16 i_e /*Exponent of all the intensity buffers*/ ); + Word16 i_e /*Exponent of all the intensity buffers*/ +#ifdef NONBE_IMPROVE_DIRAC_INTENSITY_PREC + , + Word16 *i_e_band +#endif +); UWord8 ivas_masa_surrcoh_signicant_fx( @@ -3323,15 +3402,16 @@ void ivas_omasa_enc_fx( ); void mctStereoIGF_enc_fx( - MCT_ENC_HANDLE hMCT, /* i/o: MCT encoder structure */ - Encoder_State **sts, /* i/o: encoder state structure */ - Word32 *orig_spectrum_fx[MCT_MAX_CHANNELS][2], /* i : MDCT spectrum for ITF */ - Word16 q_origSpec, /* i : Q for MDCT spectrum */ - Word32 powerSpec_fx[MCT_MAX_CHANNELS][L_FRAME48k], /* i/o: MDCT^2 + MDST^2 spectrum,or estimate*/ - Word32 *powerSpecMsInv_fx[MCT_MAX_CHANNELS][NB_DIV], /* i : same as above but for inverse spect.*/ - Word16 q_powerSpec[MCT_MAX_CHANNELS], /* i : Q for powSpec_fx and powSpecMsInv_fx*/ - Word32 *inv_spectrum_fx[MCT_MAX_CHANNELS][NB_DIV], /* i : inverse spectrum */ - const Word16 sp_aud_decision0[MCT_MAX_CHANNELS] /* i : speech audio decision */ + MCT_ENC_HANDLE hMCT, /* i/o: MCT encoder structure */ + Encoder_State **sts, /* i/o: encoder state structure */ + Word32 *orig_spectrum_fx[MCT_MAX_CHANNELS][2], /* i : MDCT spectrum for ITF */ + Word16 q_origSpec, /* i : Q for MDCT spectrum */ + Word32 powerSpec_fx[MCT_MAX_CHANNELS][L_FRAME48k], /* i/o: MDCT^2 + MDST^2 spectrum,or estimate */ + Word16 q_powerSpec[MCT_MAX_CHANNELS], /* i : Q for powSpec_fx */ + Word32 *powerSpecMsInv_fx[MCT_MAX_CHANNELS][NB_DIV], /* i : same as powerSpec_fx but for inverse spect.*/ + Word16 q_powerSpecMsInv[MCT_MAX_CHANNELS], /* i : Q for powSpecMsInv_fx */ + Word32 *inv_spectrum_fx[MCT_MAX_CHANNELS][NB_DIV], /* i : inverse spectrum */ + const Word16 sp_aud_decision0[MCT_MAX_CHANNELS] /* i : speech audio decision */ ); void ivas_mct_core_enc_fx( @@ -3439,17 +3519,18 @@ ivas_error ivas_param_mc_enc_reconfig_fx( Encoder_Struct *st_ivas /* i/o: IVAS encoder handle */ ); -Word16 ivas_arith_encode_cmplx_cell_array( +Word16 ivas_arith_encode_cmplx_cell_array_fx( ivas_arith_t *pArith_re, ivas_arith_t *pArith_re_diff, - const Word16 *pDo_diff, - const Word16 nB, - Word16 *pSymbol_re, - Word16 *pSymbol_old_re, + const Word16 *pDo_diff, /* Q0 */ + const Word16 nB, /* Q0 */ + Word16 *pSymbol_re, /* Q0 */ + Word16 *pSymbol_old_re, /* Q0 */ ivas_cell_dim_t *pCell_dims, BSTR_ENC_HANDLE hMetaData, - const Word16 any_diff, - const Word16 wc_strat_arith ); + const Word16 any_diff, /* Q0 */ + const Word16 wc_strat_arith /* Q0 */ +); ivas_error stereo_dmx_evs_init_encoder_fx( STEREO_DMX_EVS_ENC_HANDLE *hStereoDmxEVS_out, /* o : Stereo downmix for EVS encoder handle */ @@ -3641,14 +3722,22 @@ ivas_error ivas_allocate_binaural_hrtf_fx( ); void ivas_binRenderer_fx( - BINAURAL_RENDERER_HANDLE hBinRenderer, /* i/o: binaural renderer handle */ - COMBINED_ORIENTATION_HANDLE hCombinedOrientationData, /* i : combined head and external orientation handle*/ - const Word16 numTimeSlots, /* i : number of time slots to render */ + BINAURAL_RENDERER_HANDLE hBinRenderer, /* i/o: binaural renderer handle */ +#ifdef SPLIT_REND_WITH_HEAD_ROT + const MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, +#endif + COMBINED_ORIENTATION_HANDLE hCombinedOrientationData, /* i : combined head and external orientation handle*/ + const Word16 numTimeSlots, /* i : number of time slots to render */ +#ifdef SPLIT_REND_WITH_HEAD_ROT + Word32 Cldfb_RealBuffer_Binaural_fx[][BINAURAL_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* o : Rotated Binaural signals */ + Word32 Cldfb_ImagBuffer_Binaural_fx[][BINAURAL_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* o : Rotated Binaural signals */ +#else Word32 Cldfb_RealBuffer_Binaural_fx[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* o : Binaural signals */ Word32 Cldfb_ImagBuffer_Binaural_fx[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* o : Binaural signals */ - Word32 RealBuffer_fx[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* i : LS signals */ - Word32 ImagBuffer_fx[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* i : LS signals */ - Word16 *Q_in /* i : LS signals exp */ +#endif + Word32 RealBuffer_fx[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* i : LS signals */ + Word32 ImagBuffer_fx[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* i : LS signals */ + Word16 *Q_in /* i : LS signals exp */ ); void ivas_binaural_add_LFE_fx( @@ -4122,7 +4211,7 @@ ivas_error ivas_set_ism_metadata_fx( const Word16 non_diegetic_flag /* i : non-diegetic object flag */ ); -ivas_error ivas_ism_metadata_enc( +ivas_error ivas_ism_metadata_enc_fx( Word32 *ism_total_brate, /* i/o: ISM total bitrate */ const Word16 nchan_ism, /* i : number of ISM channels */ const Word16 nchan_transport, /* i : number of transport channels */ @@ -4276,7 +4365,7 @@ void stereo_dft_dec_read_BS_fx( const Word16 ivas_format /* i : ivas format Q0*/ ); -Word16 write_bitstream_adapt_GR( +Word16 write_bitstream_adapt_GR_fx( BSTR_ENC_HANDLE hBstr, /* i/o: Encoder bitstream handle */ const Word16 ind, /* i : bitstream index */ const Word16 *in, /* i : values to be written in bitstream */ @@ -4302,7 +4391,7 @@ Word16 adapt_GR_ief_fx( const Word16 try_diff /* i : diff coding allowed 1/0 */ ); -Word16 adapt_GR_rpg1_ief( +Word16 adapt_GR_rpg1_ief_fx( const Word16 *in, /* i : res pred gains input vector */ Word16 *in_diff, /* o : encoded symbols in case of differential encoding */ const Word16 *prev, /* i : previous frame data */ @@ -4316,14 +4405,14 @@ Word16 adapt_GR_rpg1_ief( const Word16 try_diff /* i : diff coding allowed 1/0 */ ); -Word16 write_GR1( +Word16 write_GR1_fx( BSTR_ENC_HANDLE hBstr, /* i/o: Encoder bitstream handle */ const Word16 ind, /* i : bitstream index */ const Word16 *in, /* i : data to be encoded */ const Word16 len /* i : input data length */ ); -Word16 write_bitstream_GR( +Word16 write_bitstream_GR_fx( BSTR_ENC_HANDLE hBstr, /* i/o: Encoder bitstream handle */ const Word16 ind, /* i : bitstream index */ const Word16 *in, /* i : input vector */ @@ -4559,13 +4648,17 @@ ivas_error front_vad_fx( const Word16 MCT_flag, /* i : hMCT handle allocated (1) or not (0) */ const Word16 input_frame, /* i : frame length */ Word16 vad_flag_dtx[], /* o : HE-SAD flag with additional DTX HO */ - Word32 fr_bands_fx[][2 * NB_BANDS], /* o : energy in frequency bands Q_buffer[n] + QSCALE + 2 */ + Word32 fr_bands_fx[][2 * NB_BANDS], /* o : energy in frequency bands q_fr_bands_fx */ + Word16 q_fr_bands[], /* o : Q of fr_bands_fx Q0 */ Word16 Etot_LR_fx[], /* o : total energy Left & Right channel Q8 */ - Word32 lf_E_fx[][2 * VOIC_BINS], /* i : per bin spectrum energy in lf, LR channels Q_buffer[n] + QSCALE */ + Word32 lf_E_fx[][2 * VOIC_BINS], /* i : per bin spectrum energy in lf, LR channels q_lf_E */ + Word16 q_lf_E[], /* o : Q of lf_E_fx */ Word16 localVAD_HE_SAD[], /* o : HE-SAD flag without hangover, LR channels */ Word16 vad_hover_flag[], /* o : VAD hangover flag */ - Word32 band_energies_LR_fx[2 * NB_BANDS], /* o : energy in critical bands without minimum noise floor E_MIN Q_buffer[1] + QSCALE + 2 - band_ener_guardbits*/ - Word32 *PS_out_fx, /* o : energy spectrum Q_buffer + QSCALE */ + Word32 band_energies_LR_fx[2 * NB_BANDS], /* o : energy in critical bands without minimum noise floor E_MIN q_band_energies_LR */ + Word16 *q_band_energies_LR, /* o : Q of band_energies_LR_fx */ + Word32 *PS_out_fx, /* o : energy spectrum q_PS_out */ + Word16 *q_PS_out, /* o : Q of PS_out_fx Q0 */ Word16 *Bin_E_out_fx, /* o : log-energy spectrum of the current frame Q7 */ Word16 Q_inp, Word16 *Q_buffer, @@ -4623,13 +4716,12 @@ Word32 logsumexp_fx( const Word16 N /* i : number of elements in array x */ ); Word32 lin_interp32_fx( - const Word32 x, /* i : the value to be mapped */ - const Word32 x1, /* i : source range interval: low end */ - const Word32 y1, /* i : source range interval: high end */ - const Word32 x2, /* i : target range interval: low */ - const Word32 y2, /* i : target range interval: high */ - const Word16 flag_sat, /* i : flag to indicate whether to apply saturation */ - Word16 *Q_io /*i/o : i/o Q factor of the output*/ + const Word32 x, /* i : the value to be mapped */ + const Word32 x1, /* i : source range interval: low end */ + const Word32 y1, /* i : source range interval: high end */ + const Word32 x2, /* i : target range interval: low */ + const Word32 y2, /* i : target range interval: high */ + const Word16 flag_sat /* i : flag to indicate whether to apply saturation */ ); void v_addc_fx( @@ -4683,6 +4775,8 @@ Word32 dot_product_cholesky_fx( const Word32 *A, /* i : Cholesky matrix A */ const Word16 N /* i : vector & matrix size */ ); + +#ifndef DOT_PROD_CHOLESKY_64BIT Word32 dot_product_cholesky_fixed( const Word32 *x, /* i : vector x */ const Word32 *A, /* i : Cholesky matrix A */ @@ -4690,6 +4784,13 @@ Word32 dot_product_cholesky_fixed( const Word16 exp_x, const Word16 exp_A, Word16 *exp_sum ); +#else +Word64 dot_product_cholesky_fixed( + const Word32 *x, /* i : vector x */ + const Word32 *A, /* i : Cholesky matrix A */ + const Word16 N /* i : vector & matrix size */ +); +#endif void v_mult_mat_fx( Word32 *y_fx, /* o : the product x*A */ @@ -4752,7 +4853,7 @@ void stereo_mdct2dft_update_fx( Word32 synth0_fx[] /* i/o: synthesis @output Fs, ch0 Q11*/ ); -Word16 write_GR0( +Word16 write_GR0_fx( BSTR_ENC_HANDLE hBstr, /* i/o: Encoder bitstream handle */ const Word16 ind, /* i : bitstream index */ const Word16 *in, /* i : data to be encoded */ @@ -4841,7 +4942,8 @@ void ivas_dirac_param_est_enc_fx( const Word16 hodirac_flag, const Word16 nchan_fb_in, Word16 *mono_frame_count, - Word16 *dirac_mono_flag ); + Word16 *dirac_mono_flag, + const Word16 shift ); ivas_error ivas_cldfb_dec_reconfig_fx( Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ @@ -4850,6 +4952,10 @@ ivas_error ivas_cldfb_dec_reconfig_fx( const Word16 numCldfbSyntheses_old /* i : number of CLDFB synthesis instances in previous frame */ ); +ivas_error ivas_sba_enc_reconfigure_fx( + Encoder_Struct *st_ivas /* i/o: IVAS encoder structure */ +); + Word16 ivas_sba_get_order_fx( const Word16 nb_channels, /* i : Number of ambisonic channels */ const Word16 sba_planar /* i : SBA planar flag */ @@ -4928,17 +5034,6 @@ void ivas_dirac_dec_set_md_map( const Word16 nCldfbTs /* i : number of CLDFB time slots */ ); -void computeDirectionVectors_fixed( - Word32 *intensity_real_x, - Word32 *intensity_real_y, - Word32 *intensity_real_z, - const Word16 enc_param_start_band, - const Word16 num_frequency_bands, - Word32 *direction_vector_x, /*Q30*/ - Word32 *direction_vector_y, /*Q30*/ - Word32 *direction_vector_z, /*Q30*/ - Word16 i_e /*Exponent of all the intensity buffers*/ ); - void computeDirectionVectors_fx( Word32 *intensity_real_x, Word32 *intensity_real_y, @@ -5752,8 +5847,8 @@ ivas_error ivas_dirac_enc_fx( const Word16 input_frame, /* i : input frame length */ const Word16 dtx_vad, /* i : DTX vad flag */ const IVAS_FORMAT ivas_format, /* i : ivas format */ - const Word16 hodirac_flag /* i : hodirac flag */ -); + const Word16 hodirac_flag, /* i : hodirac flag */ + const Word16 shift ); ivas_error ivas_spar_md_enc_init_fx( ivas_spar_md_enc_state_t *hMdEnc, /* o : MD encoder handle */ @@ -5840,8 +5935,7 @@ ivas_error ivas_compute_core_buffers_fx( Word16 lsp_mid_fx[M], /* i/o: LSPs in the middle of the frame */ Word16 Q_old_inp_16k, Word16 Q_r[2], - Word16 *Q_new, - Word16 downscale_buf_speech_enc_pe ); + Word16 *Q_new ); ivas_error ivas_enc_fx( Encoder_Struct *st_ivas, /* i/o: IVAS encoder structure */ @@ -5857,4 +5951,859 @@ void reset_metadata_spatial_fx( const Word32 core_brate, /* i : core bitrate */ const Word16 nb_bits_metadata /* i : number of meatdata bits */ ); + +void Euler2Quat_fx( + const Word32 yaw, /* i : yaw (x) Q22 */ + const Word32 pitch, /* i : pitch (y) Q22 */ + const Word32 roll, /* i : roll (z) Q22 */ + IVAS_QUATERNION *quat /* o : quaternion describing the rotation */ +); +float deg2rad( + float degrees ); + +Word32 deg2rad_fx( + Word32 degrees ); + +#ifdef SPLIT_REND_WITH_HEAD_ROT +void Quat2EulerDegree_fx( + const IVAS_QUATERNION quat, /* i : quaternion describing the rotation */ + Word32 *yaw_fx, /* o : yaw */ + Word32 *pitch_fx, /* o : pitch */ + Word32 *roll_fx /* o : roll */ +); + +void Copy_Quat_fx( + const IVAS_QUATERNION *in_quat, /* i : quaternion describing the rotation */ + IVAS_QUATERNION *out_quat /* i : quaternion describing the rotation */ +); + +void modify_Quat_q_fx( + const IVAS_QUATERNION *in_quat, /* i : quaternion describing the rotation */ + IVAS_QUATERNION *out_quat, /* i : quaternion describing the rotation */ + Word16 q_new /* i : quaternion describing the rotation */ +); + +void modify_Rmat_q_fx( + Word32 Rmat_in[3][3], /* i : real-space rotation matrix for this rotation */ + Word32 Rmat_out[3][3], /* o : real-space rotation matrix for this rotation*/ + Word16 q_cur, /* i : current q factor for rotation matrix */ + Word16 q_new /* i : target q factor for rotation matrix */ +); +#endif +/*=============================================================================================*/ +/* clang-format off */ + +/*----------------------------------------------------------------------------------* + * General IVAS prototypes + *----------------------------------------------------------------------------------*/ + +/*! r: number of channels to be analysed */ + +void copy_encoder_config_ivas_fx( + Encoder_Struct *st_ivas, /* i : IVAS encoder structure */ + Encoder_State *st, /* o : encoder state structure */ + const Word16 flag_all /* i : flag 1==update all, 0=partial update Q0*/ +); + +ivas_error create_mct_enc_fx( + Encoder_Struct *st_ivas /* i/o: IVAS encoder structure */ +); + +void destroy_cpe_enc( + CPE_ENC_HANDLE hCPE /* i/o: CPE encoder structure */ +); + +void ivas_mct_enc_close_fx( + MCT_ENC_HANDLE *hMCT /* i/o: MCT encoder structure */ +); + +ivas_error pre_proc_front_ivas_fx( + SCE_ENC_HANDLE hSCE, /* i/o: SCE encoder structure */ + CPE_ENC_HANDLE hCPE, /* i/o: CPE encoder structure */ + const Word32 element_brate, /* i : SCE/CPE element bitrate Q0*/ + const Word16 nb_bits_metadata, /* i : number of metadata bits Q0*/ + const Word16 input_frame, /* i : frame length Q0*/ + const Word16 n, /* i : channel number Q0*/ + Word16 old_inp_12k8_fx[], /* o : buffer of old input signal Q_new-1*/ + Word16 old_inp_16k_fx[], /* o : buffer of old input signal @16kHz Q_new-1*/ + Word32 *ener_fx, /* o : residual energy from Levinson-Durbin epsP_fx_q*/ + Word16 *relE_fx, /* o : frame relative energy Q8*/ + Word16 A_fx[NB_SUBFR16k * ( M + 1 )], /* o : A(z) unquantized for the 4 subframes Q12*/ + Word16 Aw_fx[NB_SUBFR16k * ( M + 1 )], /* o : weighted A(z) unquantized for subframes Q12*/ + Word32 epsP_fx[M + 1], /* o : LP prediction errors epsP_fx_q*/ + Word16 *epsP_fx_q, + Word16 lsp_new_fx[M], /* o : LSPs at the end of the frame Q15*/ + Word16 lsp_mid_fx[M], /* o : LSPs in the middle of the frame Q15*/ + Word16 *vad_hover_flag, /* o : VAD hangover flag Q0*/ + Word16 *attack_flag, /* o : flag signaling attack Q0*/ + Word32 realBuffer_fx[CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], /* i/o: real buffer Q(q_re_im_buf)*/ + Word32 imagBuffer_fx[CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], /* i/o: imag buffer Q(q_re_im_buf)*/ + Word16 *q_re_im_buf, /* i/o: Q-factor of real and imag buffer */ + Word16 old_wsp_fx[], /* o : weighted input signal buffer q_old_wsp*/ + Word16 *q_old_wsp, + Word16 pitch_fr_fx[NB_SUBFR], /* o : fractional pitch values Q6*/ + Word16 voicing_fr_fx[NB_SUBFR], /* o : fractional pitch gains Q15*/ + Word16 *loc_harm, /* o : harmonicity flag Q0*/ + Word16 *cor_map_sum_fx, /* o : speech/music clasif. parameter Q8*/ + Word16 *vad_flag_dtx, /* o : HE-SAD flag with additional DTX HO Q0*/ + Word32 enerBuffer_fx[CLDFB_NO_CHANNELS_MAX], /* o : energy buffer enerBuffer_fx_exp*/ + Word16 *enerBuffer_fx_exp, /* o : energy buffer */ + Word16 fft_buff_fx[2 * L_FFT], /* o : FFT buffer fft_buff_fx_q*/ + Word16 *fft_buff_fx_q, /* o : FFT buffer */ + const Word16 tdm_A_PCh_fx[M + 1], /* i : unq. LP coeff. of primary channel Q12*/ + const Word16 tdm_lsp_new_PCh_fx[M], /* i : unq. LSPs of primary channel Q15*/ + const Word16 currFlatness_fx, /* i : flatness parameter Q7*/ + const Word16 tdm_ratio_idx, /* i : Current Ratio_L index Q0*/ + Word32 fr_bands_LR_fx[][2 * NB_BANDS], /* i : energy in frequency bands (fr_bands_LR_fx_q) fr_bands_LR_fx_q*/ + Word16 fr_bands_LR_fx_q[CPE_CHANNELS], + const Word16 Etot_LR_fx[], /* i : total energy Left & Right channel Q8*/ + Word32 lf_E_LR_fx[][2 * VOIC_BINS], /* i : per bin spectrum energy in lf, LR channels (lf_E_LR_fx_q)*/ + Word16 lf_E_LR_fx_q, + const Word16 localVAD_HE_SAD_LR[], /* i : HE-SAD flag without hangover, LR channels Q0*/ + Word32 band_energies_LR_fx[2 * NB_BANDS], /* o : energy in critical bands without minimum noise floor E_MIN (band_energies_LR_fx_q)*/ + Word16 band_energies_LR_fx_q, + const Word16 flag_16k_smc, /* i : flag to indicate if the OL SMC is run at 16 kHz Q0*/ + const Word16 front_vad_flag, /* i : front-VAD flag to overwrite VAD decision Q0*/ + const Word16 force_front_vad, /* i : flag to force VAD decision Q0*/ + const Word16 front_vad_dtx_flag, /* i : front-VAD DTX flag to overwrite VAD decision Q0*/ + const IVAS_FORMAT ivas_format, /* i : IVAS format */ + const Word16 MCT_flag, /* i : hMCT handle allocated (1) or not (0) Q0*/ +#ifdef NONBE_1211_DTX_BR_SWITCHING + const Word32 last_ivas_total_brate, /* i : last IVAS total bitrate Q0*/ +#endif + const Word32 ivas_total_brate, /* i : IVAS total bitrate - for setting the DTX Q0*/ + Word16 *Q_new +#ifdef DEBUG_MODE_INFO + , + const Word16 ch_idx +#endif +); +ivas_error pre_proc_ivas_fx( + Encoder_State *st, /* i/o: encoder state structure */ + const Word16 last_element_mode, /* i : last element mode Q0*/ + const Word32 element_brate, /* i : element bitrate Q0*/ + const Word32 last_element_brate, /* i : last element bitrate Q0*/ + const Word16 input_frame, /* i : frame length Q0*/ + Word16 old_inp_12k8_fx[], /* i/o: buffer of old input signal Q_new-1 */ + Word16 old_inp_16k_fx[], /* i/o: buffer of old input signal @ 16kHz Q_new-1 */ + Word16 **inp_fx, /* o : ptr. to inp. signal in the current frame Q_new*/ + Word32 *ener_fx, /* o : residual energy from Levinson-Durbin epsP_fx_q*/ + Word16 A_fx[NB_SUBFR16k * ( M + 1 )], /* i/o: A(z) unquantized for the 4 subframes Q12*/ + Word16 Aw_fx[NB_SUBFR16k * ( M + 1 )], /* i/o: weighted A(z) unquantized for subframes Q14*/ + Word32 epsP_fx[M + 1], /* i : LP prediction errors epsP_fx_q*/ + Word16 *epsP_fx_q, /* i : LP prediction errors */ + Word16 lsp_new_fx[M], /* i/o: LSPs at the end of the frame Q15*/ + Word16 lsp_mid_fx[M], /* i/o: LSPs in the middle of the frame Q15*/ + Word16 *new_inp_resamp16k_fx, /* o : new input signal @16kHz, non pre-emphasised, used by the WB TBE/BWE Q_new-1*/ + Word16 *Voicing_flag, /* o : voicing flag for HQ FEC Q0*/ + Word16 old_wsp_fx[], /* i : weighted input signal buffer e_old_wsp*/ + Word16 e_old_wsp, + const Word16 loc_harm, /* i : harmonicity flag Q0*/ + const Word16 vad_flag_dtx, /* i : HE-SAD flag with additional DTX HO Q0*/ + const Word16 MCT_flag, /* i : hMCT handle allocated (1) or not (0) Q0*/ + const Word16 vad_hover_flag, /* i : VAD hangover flag Q0*/ + const Word16 flag_16k_smc, /* i : flag to indicate if the OL SMC is run at 16 kHz Q0*/ + Word32 enerBuffer_fx[CLDFB_NO_CHANNELS_MAX], /* e_enerBuffer */ + Word16 e_enerBuffer, + Word16 fft_buff_fx[2 * L_FFT], /* Qx */ + Word16 cor_map_sum_fx, /* Q8 */ + Word16 *Q_new +); +/*! r: number of clipped samples */ +void ivas_initialize_handles_enc_fx( + Encoder_Struct *st_ivas /* i/o: IVAS encoder structure */ +); + +ivas_error ivas_init_encoder( + Encoder_Struct *st_ivas /* i/o: IVAS encoder structure */ +); + +void ivas_destroy_enc_fx( + Encoder_Struct *st_ivas /* i/o: IVAS encoder structure */ +); + +ivas_error ivas_initialize_MD_bstr_enc_fx( + BSTR_ENC_HANDLE *hBstr, /* o : encoder MD bitstream handle */ + Encoder_Struct *st_ivas /* i/o: IVAS encoder structure */ +); + +void ivas_destroy_MD_bstr_enc_fx( + BSTR_ENC_HANDLE *hMetaData /* i/o: encoder MD bitstream handle */ +); + +ivas_error ivas_init_decoder_front( + Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */ +); + + +void ivas_mct_dec_close( + MCT_DEC_HANDLE *hMCT /* i/o: MCT decoder structure */ +); + +/*! r: number of channels to be synthesised */ + +void copy_decoder_config( + Decoder_Struct *st_ivas, /* i : IVAS decoder structure */ + Decoder_State *st /* o : decoder state structure */ +); + +void ivas_initialize_handles_dec( + Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */ +); + +ivas_error ivas_core_enc_fx( + SCE_ENC_HANDLE hSCE, /* i/o: SCE encoder structure */ + CPE_ENC_HANDLE hCPE, /* i/o: CPE encoder structure */ + MCT_ENC_HANDLE hMCT, /* i/o: MCT encoder structure */ + const Word16 n_CoreChannels, /* i : number of core channels to be coded Q0*/ + Word16 old_inp_12k8_fx[][L_INP_12k8], /* i : buffer of old input signal Q_new-1*/ + Word16 old_inp_16k_fx[][L_INP], /* i : buffer of old input signal Q_new-1*/ + Word16 Q_new[], + Word32 ener_fx[], /* i : residual energy from Levinson-Durbin epsP_fx_q*/ + Word16 A_fx[][NB_SUBFR16k * ( M + 1 )], /* i : A(z) unquantized for the 4 subframes Q12*/ + Word16 Aw_fx[][NB_SUBFR16k * ( M + 1 )], /* i : weighted A(z) unquantized for subframes Q12*/ + Word32 epsP_fx[][M + 1], /* i : LP prediction errors epsP_fx_q*/ + Word16 epsP_fx_q[], /* i : LP prediction errors */ + Word16 lsp_new_fx[][M], /* i : LSPs at the end of the frame Q15*/ + Word16 lsp_mid_fx[][M], /* i : LSPs in the middle of the frame Q15*/ + const Word16 vad_hover_flag[], /* i : VAD hanglover flag Q0*/ + Word16 attack_flag[], /* i : attack flag (GSC or TC) Q0*/ + Word32 realBuffer_fx[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], /* i/o: real buffer q_re_im_buf*/ + Word32 imagBuffer_fx[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], /* i/o: imag buffer q_re_im_buf*/ + Word16 *q_re_im_buf, + Word16 old_wsp_fx[][L_WSP], /* i : weighted input signal buffer e_old_wsp*/ + Word16 e_old_wsp[], + const Word16 loc_harm[], /* i : harmonicity flag Q0*/ + const Word16 cor_map_sum_fx[], /* i : speech/music clasif. parameter Q8*/ + const Word16 vad_flag_dtx[], /* i : HE-SAD flag with additional DTX HO Q0*/ + Word32 enerBuffer_fx[][CLDFB_NO_CHANNELS_MAX], /* o : energy buffer enerBuffer_fx_exp*/ + Word16 enerBuffer_fx_exp[], /* o : energy buffer */ + Word16 fft_buff_fx[][2 * L_FFT], /* i : FFT buffer Qx*/ + const Word16 tdm_SM_or_LRTD_Pri, /* i : channel combination scheme flag Q0*/ + const Word16 ivas_format, /* i : IVAS format Q0*/ + const Word16 flag_16k_smc /* i : flag to indicate if the OL SMC is run at 16 kHz Q0*/ +); + +void ivas_renderer_select( + Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */ +); + +ivas_error ivas_mc_enc_config_fx( + Encoder_Struct *st_ivas /* i/o: IVAS encoder structure */ +); + +/*! r: flag indicating a valid bitrate */ +Word16 is_IVAS_bitrate_fx( + const Word32 ivas_total_brate /* i : IVAS total bitrate */ +); + +int16_t is_DTXrate( + const int32_t ivas_total_brate /* i : IVAS total bitrate */ +); + + +/*----------------------------------------------------------------------------------* + * JBM prototypes + *----------------------------------------------------------------------------------*/ + +ivas_error ivas_jbm_dec_set_discard_samples( + Decoder_Struct *st_ivas /* i/o: main IVAS decoder structre */ +); + +TC_BUFFER_MODE ivas_jbm_dec_get_tc_buffer_mode( + Decoder_Struct *st_ivas /* i : IVAS decoder handle */ +); + +void ivas_jbm_dec_tc_buffer_close( + DECODER_TC_BUFFER_HANDLE *phTcBuffer /* i/o: TC buffer handle */ +); + +void ivas_jbm_dec_td_renderers_adapt_subframes( + Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */ +); + +ivas_error ivas_jbm_dec_metadata_open( + Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */ +); + +void ivas_jbm_masa_sf_to_sf_map( + Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */ +); + + +/*----------------------------------------------------------------------------------* + * ISM prototypes + *----------------------------------------------------------------------------------*/ + +void bitbudget_to_brate( + const Word16 x[], /* i : bitbudgets Q0 */ + Word32 y[], /* o : bitrates Q0 */ + const Word16 N /* i : number of entries to be converted */ +); + +void ivas_ism_reset_metadata( + ISM_METADATA_HANDLE hIsmMeta /* i/o: ISM metadata handles */ +); + +void ivas_ism_reset_metadata_enc( + ISM_METADATA_HANDLE hIsmMeta /* i/o: ISM metadata handle */ +); +void ivas_ism_reset_metadata_API( + ISM_METADATA_HANDLE hIsmMeta /* i/o: ISM metadata handles */ +); + +/*! r: index of the winning codeword */ +Word16 ism_quant_meta_fx( + const Word32 val, /* i : scalar value to quantize Q22 */ + Word32 *valQ, /* o : quantized value Q22 */ + const Word32 borders_fx[], /* i : level borders Q22 */ + const Word32 q_step_fx, /* i : quantization step Q22 */ + const Word32 q_step_border_fx, /* i : quantization step at the border Q22 */ + const Word16 cbsize /* i : codebook size */ +); + +ivas_error ivas_ism_metadata_enc_create_fx( + Encoder_Struct *st_ivas, /* i/o: IVAS encoder structure */ + const Word16 n_ISms, /* i : number of objects */ + Word32 element_brate_tmp[] /* o : element bitrate per object */ +); + +/*----------------------------------------------------------------------------------* + * Parametric ISM prototypes + *----------------------------------------------------------------------------------*/ + +/*! r: ISM format mode */ + +ivas_error ivas_param_ism_enc_open_fx( + Encoder_Struct *st_ivas /* i/o: IVAS encoder structure */ +); + +void ivas_param_ism_enc_close_fx( + PARAM_ISM_CONFIG_HANDLE *hParamIsm, /* i/o: ParamISM handle */ + const Word32 input_Fs /* i : input sampling_rate */ +); + +void ivas_ism_metadata_close( + ISM_METADATA_HANDLE hIsmMetaData[], /* i/o : object metadata handles */ + const Word16 first_idx /* i : index of first handle to deallocate */ +); + + +ivas_error ivas_ism_enc_config( + Encoder_Struct *st_ivas /* i/o: IVAS encoder structure */ +); + +/*----------------------------------------------------------------------------------* + * ISM DTX prototypes + *----------------------------------------------------------------------------------*/ + +ivas_error ivas_ism_dtx_open( + Encoder_Struct *st_ivas /* i/o: IVAS encoder structure */ +); + +void ivas_ism_metadata_sid_enc_fx( + ISM_DTX_HANDLE hISMDTX, /* i/o: ISM DTX handle */ + const Word16 flag_noisy_speech, /* i : noisy speech flag */ + const Word16 nchan_ism, /* i : number of objects */ + const Word16 nchan_transport, /* i : number of transport channels */ + const ISM_MODE ism_mode, /* i : ISM mode */ + ISM_METADATA_HANDLE hIsmMeta[], /* i/o: ISM metadata handles */ + const Word16 sid_flag, /* i : indication of SID frame */ + const Word16 md_diff_flag[], /* i : metadata differental flag */ + BSTR_ENC_HANDLE hBstr, /* i/o: bitstream handle */ + Word16 nb_bits_metadata[] /* o : number of metadata bits */ +); + + + +void ivas_param_ism_compute_noisy_speech_flag_fx( + Encoder_Struct *st_ivas /* i/o: IVAS encoder structure */ +); + +/*----------------------------------------------------------------------------------* + * DFT Stereo prototypes + *----------------------------------------------------------------------------------*/ + +void stereo_dft_dec_destroy( + STEREO_DFT_DEC_DATA_HANDLE *hStereoDft /* i/o: decoder DFT stereo handle */ +); + +/*----------------------------------------------------------------------------------* + * Range Coder prototypes + *----------------------------------------------------------------------------------*/ + +/*! r: Read bit */ +UWord16 rc_uni_dec_read_bit( + RangeUniDecState *rc_st_dec /* i/o: RC state handle */ +); + +/*! r: Read bit */ +UWord16 rc_uni_dec_read_bit_prob_fast( + RangeUniDecState *rc_st_dec, /* i/o: RC state handle */ + const Word16 freq0, /* i : Frequency for symbol 0 */ + const UWord16 tot_shift /* i : Total frequency as a power of 2 */ +); + +/*! r: Read bits */ +UWord16 rc_uni_dec_read_bits( + RangeUniDecState *rc_st_dec, /* i/o: RC state handle */ + const Word16 bits /* i : Number of bits */ +); + + +/*----------------------------------------------------------------------------------* + * TD Stereo prototypes + *----------------------------------------------------------------------------------*/ + +void tdm_bit_alloc( + const Word16 ivas_format, /* i : IVAS format */ + const Word16 ism_mode, /* i : ISM mode in combined format */ + const Word32 element_brate_wo_meta, /* i : element bitrate without metadata */ + const Word16 tdm_lp_reuse_flag, /* i : LPC reusage flag */ + Word32 *total_brate_pri, /* o : Allocated primary channel bitrate */ + Word32 *total_brate_sec, /* o : Allocated secondary channel bitrate */ + Word16 *tdm_low_rate_mode, /* o : secondary channel low rate mode flag */ + const Word16 coder_type, /* i : secondary channel coder type */ + const Word16 ener_ratio_idx, /* i : correlation ratio indexe */ + const Word16 tdm_Pitch_reuse_flag, /* i : primary channel pitch reuse flag */ + const Word16 bwidth_pri, /* i : bandwidth of the primary channel */ + const Word16 bwidth_sec, /* i : bandwidth of the secondary channel */ + const Word16 flag_ACELP16k_pri, /* i : ACELP@16kHz core flag, primary chan. */ + const Word16 tdm_LRTD_flag, /* i : LRTD stereo mode flag */ + const Word16 coder_type0, /* i : coder type (temporary in the encoder, from bitstream in decoder) */ + const Word16 tdm_inst_ratio_idx /* i : instantaneous correlation ratio index */ +); + + +/*! r: value of the indice */ +uint16_t get_indice_st( + Decoder_State *st, /* i/o: decoder state structure */ + const Word32 element_brate, /* i : element bitrate */ + const Word16 pos, /* i : absolute position in the bitstream */ + const Word16 nb_bits /* i : number of bits to quantize the indice */ +); + +/*----------------------------------------------------------------------------------* + * MDCT Stereo prototypes + *----------------------------------------------------------------------------------*/ + +void stereo_mdct_core_enc_fx( + CPE_ENC_HANDLE hCPE, /* i/o: CPE encoder structure */ + Word16 new_samples[CPE_CHANNELS][L_INP], /* i : new samples Q0*/ + Word16 old_wsp[CPE_CHANNELS][L_WSP], /* i : 12.8kHz weighted speech (for LTP Qx*/ + Word16 pitch_buf_fx[CPE_CHANNELS][NB_SUBFR16k] /* o : floating pitch for each subframe Q6*/ +); + +Word16 write_stereo_to_bitstream_fx +( + STEREO_MDCT_ENC_DATA_HANDLE hStereoMdct, /* i/o: Stereo MDCT encoder structure */ + Encoder_State **sts, /* i/o: Encoder state structure */ + Word16 ms_mask[NB_DIV][MAX_SFB], /* i : bandwise MS mask Q0*/ + const Word16 mct_on, /* i : flag mct block (1) or stereo (0) Q0*/ + BSTR_ENC_HANDLE hBstr /* i/o: bitstream handle */ +); + +/*----------------------------------------------------------------------------------* + * Stereo CNG prototypes + *----------------------------------------------------------------------------------*/ +void stereo_cng_dec_update( + CPE_DEC_HANDLE hCPE, /* i/o: CPE decoder structure */ + const Word32 ivas_total_brate /* i : IVAS total bitrate Q0*/ +); + + +/*----------------------------------------------------------------------------------* + * Framework general prototypes + *----------------------------------------------------------------------------------*/ + +void mvc2c( + const uint8_t x[], /* i : input vector */ + uint8_t y[], /* o : output vector */ + const int16_t n /* i : vector size */ +); + +void stereo_switching_dec( + CPE_DEC_HANDLE hCPE, /* i/o: CPE decoder structure */ + const Word32 ivas_total_brate /* i : IVAS total bitrate Q0*/ +); + + +/*! r: number of bits written */ + + + +/*----------------------------------------------------------------------------------* + * MCT prototypes + *----------------------------------------------------------------------------------*/ +void ivas_mdct_core_whitening_enc_fx( + CPE_ENC_HANDLE hCPE, /* i/o: CPE encoder structure */ + Word16 new_samples_fx[CPE_CHANNELS][L_INP], /* i : new samples */ + Word16 old_wsp_fx[CPE_CHANNELS][L_WSP], /* i : 12.8kHz weighted speech (for LTP */ + Word16 pitch_buf[CPE_CHANNELS][NB_SUBFR16k], /* o : floating pitch for each subframe */ + Word32 *mdst_spectrum_long[CPE_CHANNELS], /* o : buffer for MDST spectrum */ + Word16 tnsBits[CPE_CHANNELS][NB_DIV], /* o : buffer TNS bits */ + Word32 *orig_spectrum_long[CPE_CHANNELS], /* o : origingal spectrum w/o whitening */ + Word16 tnsSize[CPE_CHANNELS][NB_DIV], /* o : size of TNS */ + Word16 p_param[CPE_CHANNELS][NB_DIV], /* o : pointer to parameter array */ + BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ + const Word16 mct_on, /* i : flag mct block (1) or stereo (0) */ + const Word16 nChannels, /* i : total number of coded channels */ +Word16 mdst_spectrum_e[CPE_CHANNELS][NB_DIV], +Word16 orig_spectrum_e[CPE_CHANNELS][NB_DIV] +); + +void splitAvailableBitsMCT_fx( + void **sts, /* i/o: encoder/decoder state structure */ + const Word16 total_bits, /* i : total number of available bits */ + const Word16 split_ratio[MCT_MAX_CHANNELS], /* i : ratio for splitting the bits Q0 */ + const Word16 enc_dec, /* i : encoder or decoder flag */ + const Word16 nchan /* i : number of channels */ +); + +void enc_prm_igf_mdct( + Encoder_State *st, /* i : Encoder state handle */ + BSTR_ENC_HANDLE hBstr /* i/o: Bitstream handle */ +); + +/*----------------------------------------------------------------------------------* + * Q Metadata prototypes for DirAC and MASA + *----------------------------------------------------------------------------------*/ +/*! r: number of bits written */ + +/*! r: number of bits read */ +Word16 ivas_qmetadata_dec_decode( + IVAS_QMETADATA_HANDLE hQMetaData, /* i/o: q_metadata handle */ + UWord16 *bitstream, /* i : bitstream */ + Word16 *index, /* i/o: bitstream position */ + const Word16 hodirac_flag /* i : flag to indicate HO-DirAC mode */ +); + +/*! r: number of bits read */ +Word16 ivas_qmetadata_dec_decode_hr_384_512( + IVAS_QMETADATA_HANDLE hQMetaData, /* i/o: hQMetaData handle */ + UWord16 *bitstream, /* i : bitstream */ + Word16 *index, /* i/o: bitstream position */ + const SPHERICAL_GRID_DATA *sph_grid16, /* i : spherical grid for deindexing */ + const Word16 bits_sph_idx, + const Word16 bits_sp_coh, + const UWord8 ncoding_bands_config +); + +/*! r: number of bits read */ +Word16 ivas_qmetadata_dec_sid_decode( + IVAS_QMETADATA_HANDLE hQMetaData, /* i/o: q_metadata handle */ + UWord16 *bitstream, /* i : bitstream */ + Word16 *index, /* i/o: bitstream position */ + const Word16 nchan_transport, /* i : number of transport channels */ + Word16 *element_mode, /* o : element mode */ + const Word16 ivas_format /* i : IVAS format */ +); + + +UWord16 ivas_qmetadata_reorder_generic_fx( + const Word16 signed_value +); + +void ivas_sba_set_cna_cng_flag( + Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */ +); + +/*! r: number of ambisonics metadata channels */ + +void ivas_sba_dirac_stereo_config( + STEREO_DFT_CONFIG_DATA_HANDLE hConfig /* o : DFT stereo configuration */ +); + + +Word16 ivas_get_sba_dirac_stereo_flag( + Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */ +); + + +/*----------------------------------------------------------------------------------* + * DirAC prototypes + *----------------------------------------------------------------------------------*/ + + +ivas_error ivas_dirac_enc_reconfigure( + Encoder_Struct *st_ivas /* i/o: IVAS encoder handle */ +); + +ivas_error ivas_mc_paramupmix_enc_open_fx( + Encoder_Struct *st_ivas /* i/o: IVAS encoder handle */ +); + +void ivas_mc_paramupmix_enc_close_fx( + MC_PARAMUPMIX_ENC_HANDLE *hMCParamUpmix, /* i/o: MC Param-Upmix encoder handle */ + const int32_t input_Fs /* i : input sampling rate */ +); + +ivas_error ivas_mc_paramupmix_dec_open( + Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */ +); + +void ivas_mc_paramupmix_dec_close( + MC_PARAMUPMIX_DEC_HANDLE *hMCParamUpmix_out /* i/o: Parametric MC decoder handle */ +); + +void ivas_mc_paramupmix_dec_read_BS( + Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ + Decoder_State *st, /* i/o: decoder state structure */ + MC_PARAMUPMIX_DEC_HANDLE hMCParamUpmix, /* i/o: decoder MC Param-Upmix handle */ + Word16 *nb_bits /* o : number of bits written */ +); + +void ivas_mc_paramupmix_dec_digest_tc( + Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */ + const UWord8 nCldfbSlots, /* i : number of CLFBS slots in the transport channels */ + const Word16 nSamplesForRendering /* i : number of samples provided */ +); + +void ivas_param_mc_set_coded_bands_fx( + HANDLE_IVAS_PARAM_MC_METADATA hMetadataPMC /* i/o: handle for the Parametric MC parameter coding state */ +); + +UWord16 ivas_param_mc_get_configuration_index_fx( + const MC_LS_SETUP mc_ls_setup, /* i : MC ls setup */ + const Word32 ivas_total_brate /* i : IVAS total bitrate */ +); + +/*----------------------------------------------------------------------------------* + * SPAR prototypes + *----------------------------------------------------------------------------------*/ + +/* MD module */ + +/*! r: number of MD subframes */ +ivas_error ivas_spar_md_dec_open( + ivas_spar_md_dec_state_t **hMdDec_out, /* i/o: SPAR MD decoder handle */ + const DECODER_CONFIG_HANDLE hDecoderConfig, /* i : configuration structure */ + const Word16 num_channels, /* i : number of internal channels */ + const Word16 sba_order, /* i : SBA order */ + const Word16 sid_format, /* i : SID format */ + const Word32 last_active_ivas_total_brate /* i : IVAS last active bitrate */ +); + +void ivas_spar_md_dec_close( + ivas_spar_md_dec_state_t **hMdDec /* i/o: SPAR MD decoder handle */ +); + +ivas_error ivas_spar_md_dec_init( + ivas_spar_md_dec_state_t *hMdDec, /* i/o: SPAR MD decoder handle */ + const DECODER_CONFIG_HANDLE hDecoderConfig, /* i : configuration structure */ + const Word16 num_channels, /* i : number of internal channels */ + const Word16 sba_order /* i : SBA order */ +); + +/* Transient detector module */ +ivas_error ivas_transient_det_open_fx( + ivas_trans_det_state_t **hTranDet, /* i/o: Transient detector handle */ + const Word32 sampling_rate /* i : sampling rate */ +); + +void ivas_transient_det_close_fx( + ivas_trans_det_state_t **hTranDet /* i/o: Transient detector handle */ +); + +void ivas_huffman_encode_fx( + ivas_huffman_cfg_t *huff_cfg, + Word16 in, + Word16 *hcode, + Word16 *hlen +); + +ivas_error ivas_huffman_decode( + ivas_huffman_cfg_t *huff_cfg, + Decoder_State *st0, + Word16 *dec_out +); + +void ivas_arith_decode_cmplx_cell_array( + ivas_arith_t *pArith_re, + ivas_arith_t *pArith_re_diff, + Decoder_State *st0, + ivas_cell_dim_t *pCell_dims, + Word16 *pDo_diff, const Word16 nB, + Word16 *pSymbol_re, + Word16 *pSymbol_re_old +); + +void ivas_map_prior_coeffs_quant( + ivas_spar_md_prev_t *pSpar_md_prior, + ivas_spar_md_com_cfg *pSpar_md_cfg, + const Word16 qsi, + const Word16 nB +); + +void ivas_clear_band_coeff_idx( + ivas_band_coeffs_ind_t *pband_coeff_idx, + const UWord16 num_bands +); + + +/*----------------------------------------------------------------------------------* + * MASA prototypes + *----------------------------------------------------------------------------------*/ +ivas_error ivas_masa_enc_open_fx( + Encoder_Struct *st_ivas /* i/o: IVAS encoder handle */ +); + +void ivas_masa_enc_close_fx( + MASA_ENCODER_HANDLE *hMasa /* i/o: MASA metadata structure */ +); + +int16_t ivas_qmetadata_encode_extended_gr_length_fx( + const UWord16 value, + const UWord16 alphabet_size, + const Word16 gr_param); + +void ivas_qmetadata_encode_extended_gr_fx( + BSTR_ENC_HANDLE hMetaData, /* i/o: q_metadata handle */ + const UWord16 value, /* i : value to be encoded */ + const UWord16 alphabet_size, /* i : alphabet size */ + const Word16 gr_param); /* i : GR order */ + + +void ivas_set_qmetadata_maxbit_req_fx( + IVAS_QMETADATA_HANDLE hQMetaData, /* o : qmetadata structure where the requirement value is set */ + const IVAS_FORMAT ivas_format /* i : IVAS format */ +); + + +/*---------------------------------------------------------------------------------* + * Binaural FastConv Renderer Prototypes +*-----------------------------------------------------------------------------------*/ + + +void ivas_binaural_hrtf_close( + HRTFS_FASTCONV_HANDLE *hHrtfFastConv /* i/o: decoder binaural hrtf handle */ +); + +/*----------------------------------------------------------------------------------* + * renderer prototypes + *----------------------------------------------------------------------------------*/ + +void ivas_ism_renderer_close( + ISM_RENDERER_HANDLE *hIsmRendererData /* i/o: ISM renderer handle */ +); + + +/*----------------------------------------------------------------------------------* + * Amplitude Panning VBAP prototypes + *----------------------------------------------------------------------------------*/ + +void panning_wrap_angles( + const float azi_deg, /* i : azimuth in degrees for panning direction (positive left) */ + const float ele_deg, /* i : elevation in degrees for panning direction (positive up) */ + float *azi_wrapped, /* o : wrapped azimuth component */ + float *ele_wrapped /* o : wrapped elevation component */ +); + + +/*----------------------------------------------------------------------------------* + * McMASA prototypes + *----------------------------------------------------------------------------------*/ + + +ivas_error ivas_mcmasa_dec_reconfig( + Decoder_Struct *st_ivas /* i/o: IVAS decoder handle */ +); + +void ivas_mcmasa_dmx_modify_fx( + const Word16 n_samples, /* i : input frame length in samples */ + Word32 dmx_fx[][L_FRAME48k + NS2SA(48000, IVAS_FB_ENC_DELAY_NS)], /* i/o: downmix signal to be transformed into another format Qx*/ + Word16 dmx_Q[], /* i/o : Q of the intput signal which is being transformed*/ + const Word16 n_chnls_dmx_old, /* i : number of downmix channels in the old format Q0 */ + const Word16 n_chnls_dmx_new /* i : number of downmix channels in the target format Q0*/ +); + +ivas_error ivas_mono_dmx_renderer_open( + Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */ +); + + +void ivas_mono_dmx_renderer_close( + MONO_DOWNMIX_RENDERER_HANDLE *hMonoDmxRenderer /* i/ i/o: Mono downmix structure */ +); + + +/*----------------------------------------------------------------------------------* + * LFE encoder low pass filter prototypes + *----------------------------------------------------------------------------------*/ + +void ivas_lfe_lpf_enc_close_fx( + ivas_filters_process_state_t **hLfeLpf /* i/o: LFE LPF handle */ +); + + +/*----------------------------------------------------------------------------------* + * LFE Coding prototypes + *----------------------------------------------------------------------------------*/ + +ivas_error ivas_create_lfe_enc_fx( + LFE_ENC_HANDLE *hLFE, /* o : IVAS LFE encoder structure */ + const Word32 input_Fs /* i : input sampling rate */ +); + +void ivas_lfe_enc_close_fx( + LFE_ENC_HANDLE *hLFE /* i/o: LFE encoder handle */ +); + +void ivas_filters_init_fx( + ivas_filters_process_state_t *filter_state, /* i/o: filter state handle */ + const Word32 *filt_coeff_fx, /* i : filter coefficients Q31- *filt_coeff_e */ + const Word16 *filt_coeff_e, /* i : exponents of filter coefficients */ + const Word16 order ) ; + +void ivas_filter_process_fx( + ivas_filters_process_state_t *filter_state, /* i/o: filter state handle */ + Word32 *pIn_Out_fx, /* i/o: signal subject to filtering Q(q_factor) */ + const Word16 length, /* i : filter order */ + Word16 q_factor ); + +/*----------------------------------------------------------------------------------* + * OSBA prototypes + *----------------------------------------------------------------------------------*/ +ivas_error ivas_osba_enc_reconfig( + Encoder_Struct *st_ivas /* i/o: IVAS encoder structure */ +); + +void ivas_set_surplus_brate_enc( + Encoder_Struct *st_ivas /* i/o: IVAS encoder structure */ +#ifdef DEBUG_MODE_INFO + , + const int16_t *nb_bits_metadata /* i : number of metadata bits */ +#endif +); + +void ivas_set_surplus_brate_dec( + Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ + int32_t *ism_total_brate /* i : ISM total bitrate */ +); + +ivas_error ivas_omasa_separate_object_renderer_open( + Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */ +); + +void ivas_omasa_separate_object_renderer_close( + Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */ +); + +/*----------------------------------------------------------------------------------* + * Filter-bank (FB) Mixer + *----------------------------------------------------------------------------------*/ + +ivas_error ivas_fb_set_cfg( + IVAS_FB_CFG **pFb_cfg_out, /* o : FB config. handle */ + const Word16 ivas_format, /* i : IVAS format */ + const Word16 num_in_chans, /* i : number of FB input channels */ + const Word16 num_out_chans, /* i : number of FB output channels */ + const Word16 active_w_mixing, /* i : active_w_mixing flag */ + const Word32 sampling_Fs, /* i : sampling rate */ + const Word16 nachan_dirac_ana /* i : number of DirAR analysis channels */ +); + + +/*=============================================================================================*/ + #endif diff --git a/lib_com/ivas_qmetadata_com.c b/lib_com/ivas_qmetadata_com_fx.c similarity index 99% rename from lib_com/ivas_qmetadata_com.c rename to lib_com/ivas_qmetadata_com_fx.c index 73b85c7a529daaf94a6641cbf2a69d89c9621cc4..c9ad840979d7af9f492d83747fb9abbfc4c8d99b 100644 --- a/lib_com/ivas_qmetadata_com.c +++ b/lib_com/ivas_qmetadata_com_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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,11 +36,9 @@ #include "options.h" #include "ivas_cnst.h" #include "ivas_rom_com.h" -#include "ivas_prot.h" -#include "prot.h" +#include "prot_fx.h" #include "cnst.h" #include "wmc_auto.h" -#include "prot_fx.h" #include "ivas_prot_fx.h" #include "ivas_rom_com_fx.h" @@ -280,8 +278,8 @@ void ivas_qmetadata_close_fx( /*! r: codeword index */ Word16 masa_sq_fx( - const Word32 in, /* i : input value */ - const Word32 *threshold, /* i : partition */ + const Word32 in, /* i : input value Q30*/ + const Word32 *threshold, /* i : partition Q30*/ const Word16 cb_sz /* i : codebook size */ ) { diff --git a/lib_com/ivas_qspherical_com.c b/lib_com/ivas_qspherical_com_fx.c similarity index 98% rename from lib_com/ivas_qspherical_com.c rename to lib_com/ivas_qspherical_com_fx.c index 499585221bbb9c682fea3d63886c15bc0e54d5f9..6661026a8cde298b8d2f618156313e3cdef73a1f 100644 --- a/lib_com/ivas_qspherical_com.c +++ b/lib_com/ivas_qspherical_com_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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,13 +36,10 @@ #include #include "ivas_cnst.h" #include "ivas_rom_com.h" -#include "ivas_prot.h" -#include "prot.h" +#include "prot_fx.h" #include "cnst.h" #include "wmc_auto.h" #include "ivas_prot_fx.h" -#include "prot_fx.h" -#include "prot_fx.h" #include "ivas_rom_com_fx.h" @@ -668,15 +665,7 @@ Word16 quantize_phi_chan_compand_fx( delta_phi = L_shr( delta_phi, sub( 9, tmp_e ) ); // Q22 // id_phi = (int16_t) round_f( ( phi / (float) delta_phi ) ); id_phi = BASOP_Util_Divide3232_Scale( phi, delta_phi, &tmp_e ); // Q15 - IF( GE_16( abs_s( id_phi ), shl_sat( 1, sub( 15, tmp_e ) ) ) ) - { - id_phi = shr( id_phi, sub( 15, tmp_e ) ); // Q0 - } - ELSE - { - id_phi = 0; - move16(); - } + id_phi = round_fx( L_shl( id_phi, add( tmp_e, 1 ) ) ); // Q0 IF( add( id_phi, shr( n, 1 ) ) < 0 ) { diff --git a/lib_com/ivas_rom_com.c b/lib_com/ivas_rom_com.c index 5a864835cf67f9c253d74e680c78ae94eb14a267..c7977001b7cfbd70c374a79c6ef97e6fee1a6f9c 100644 --- a/lib_com/ivas_rom_com.c +++ b/lib_com/ivas_rom_com.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other @@ -52,6 +52,826 @@ const Word32 ivas_brate_tbl[SIZE_IVAS_BRATE_TBL] = IVAS_192k, IVAS_256k, IVAS_384k, IVAS_512k }; +/*----------------------------------------------------------------------------------* + * IVAS limiter table + *----------------------------------------------------------------------------------*/ +const Word32 release_cnst_table[4][201] = // Q31 +{ + { + 1913946752, + 1919716352, + 1925351680, + 1930855552, + 1936230784, + 1941479808, + 1946605312, + 1951609728, + 1956495744, + 1961265792, + 1965922304, + 1970467584, + 1974904320, + 1979234560, + 1983460736, + 1987585024, + 1991609856, + 1995537280, + 1999369344, + 2003108480, + 2006756480, + 2010315520, + 2013787520, + 2017174528, + 2020478464, + 2023701248, + 2026844672, + 2029910656, + 2032900992, + 2035817344, + 2038661376, + 2041435008, + 2044139648, + 2046777088, + 2049348864, + 2051856384, + 2054301440, + 2056685312, + 2059009536, + 2061275520, + 2063484672, + 2065638272, + 2067737856, + 2069784448, + 2071779584, + 2073724416, + 2075620096, + 2077467904, + 2079268992, + 2081024512, + 2082735488, + 2084403200, + 2086028416, + 2087612544, + 2089156352, + 2090660864, + 2092127104, + 2093555968, + 2094948480, + 2096305408, + 2097627776, + 2098916352, + 2100172032, + 2101395584, + 2102587776, + 2103749504, + 2104881408, + 2105984384, + 2107059072, + 2108106112, + 2109126400, + 2110120448, + 2111088896, + 2112032512, + 2112951808, + 2113847552, + 2114720128, + 2115570304, + 2116398592, + 2117205504, + 2117991552, + 2118757504, + 2119503616, + 2120230400, + 2120938496, + 2121628288, + 2122300288, + 2122954880, + 2123592576, + 2124213760, + 2124818944, + 2125408384, + 2125982592, + 2126541952, + 2127086848, + 2127617664, + 2128134656, + 2128638336, + 2129128832, + 2129606784, + 2130072192, + 2130525568, + 2130967296, + 2131397376, + 2131816448, + 2132224640, + 2132622080, + 2133009408, + 2133386496, + 2133753856, + 2134111744, + 2134460288, + 2134799744, + 2135130368, + 2135452416, + 2135766144, + 2136071680, + 2136369152, + 2136659072, + 2136941312, + 2137216256, + 2137484160, + 2137744896, + 2137998976, + 2138246400, + 2138487424, + 2138722176, + 2138950656, + 2139173376, + 2139390208, + 2139601408, + 2139807104, + 2140007424, + 2140202624, + 2140392576, + 2140577664, + 2140758016, + 2140933504, + 2141104512, + 2141271040, + 2141433216, + 2141591168, + 2141745024, + 2141894912, + 2142040832, + 2142182912, + 2142321408, + 2142456192, + 2142587392, + 2142715264, + 2142839808, + 2142961152, + 2143079296, + 2143194240, + 2143306240, + 2143415424, + 2143521664, + 2143625216, + 2143725952, + 2143824128, + 2143919744, + 2144012800, + 2144103424, + 2144191744, + 2144277760, + 2144361472, + 2144443136, + 2144522496, + 2144599936, + 2144675200, + 2144748544, + 2144820096, + 2144889600, + 2144957440, + 2145023488, + 2145087744, + 2145150336, + 2145211264, + 2145270656, + 2145328512, + 2145384832, + 2145439616, + 2145493120, + 2145545088, + 2145595776, + 2145645056, + 2145693184, + 2145739904, + 2145785472, + 2145829888, + 2145873152, + 2145915136, + 2145956224, + 2145996032, + 2146034944, + 2146072832, + 2146109696, + 2146145664, + 2146180608, + 2146214656, + 2146247808, + }, + { + 2027355264, + 2030408704, + 2033386624, + 2036290944, + 2039123328, + 2041885440, + 2044578944, + 2047205376, + 2049766528, + 2052263680, + 2054698496, + 2057072384, + 2059387008, + 2061643520, + 2063843328, + 2065987968, + 2068078720, + 2070116864, + 2072103552, + 2074040192, + 2075927936, + 2077767936, + 2079561472, + 2081309568, + 2083013376, + 2084673920, + 2086292352, + 2087869696, + 2089406976, + 2090905216, + 2092365184, + 2093788032, + 2095174528, + 2096525824, + 2097842432, + 2099125632, + 2100375808, + 2101594240, + 2102781312, + 2103938048, + 2105065216, + 2106163456, + 2107233536, + 2108276096, + 2109292032, + 2110281728, + 2111246080, + 2112185728, + 2113101056, + 2113992960, + 2114861824, + 2115708288, + 2116532992, + 2117336448, + 2118119168, + 2118881792, + 2119624704, + 2120348416, + 2121053440, + 2121740288, + 2122409344, + 2123061120, + 2123696128, + 2124314624, + 2124917120, + 2125504128, + 2126075776, + 2126632832, + 2127175296, + 2127703808, + 2128218624, + 2128720000, + 2129208448, + 2129684352, + 2130147712, + 2130599168, + 2131038976, + 2131467264, + 2131884416, + 2132290816, + 2132686592, + 2133072256, + 2133447680, + 2133813504, + 2134169856, + 2134516864, + 2134854784, + 2135184000, + 2135504640, + 2135816960, + 2136121216, + 2136417536, + 2136706048, + 2136987136, + 2137260928, + 2137527552, + 2137787264, + 2138040192, + 2138286592, + 2138526464, + 2138760192, + 2138987776, + 2139209472, + 2139425408, + 2139635712, + 2139840512, + 2140039936, + 2140234240, + 2140423424, + 2140607744, + 2140787200, + 2140962048, + 2141132288, + 2141298048, + 2141459584, + 2141616896, + 2141769984, + 2141919232, + 2142064512, + 2142205952, + 2142343808, + 2142478080, + 2142608768, + 2142736128, + 2142860032, + 2142980864, + 2143098368, + 2143212928, + 2143324544, + 2143433088, + 2143538944, + 2143641984, + 2143742336, + 2143840000, + 2143935232, + 2144027904, + 2144118144, + 2144206080, + 2144291712, + 2144375168, + 2144456320, + 2144535424, + 2144612480, + 2144687488, + 2144760448, + 2144831616, + 2144900992, + 2144968448, + 2145034112, + 2145098112, + 2145160448, + 2145221248, + 2145280256, + 2145337856, + 2145393920, + 2145448576, + 2145501696, + 2145553536, + 2145603968, + 2145653120, + 2145700992, + 2145747456, + 2145792896, + 2145837056, + 2145880064, + 2145922048, + 2145962880, + 2146002560, + 2146041344, + 2146078976, + 2146115712, + 2146151424, + 2146186240, + 2146220160, + 2146253184, + 2146285312, + 2146316672, + 2146347136, + 2146376832, + 2146405760, + 2146433920, + 2146461440, + 2146488192, + 2146514176, + 2146539520, + 2146564224, + 2146588160, + 2146611584, + 2146634368, + 2146656640, + 2146678272, + 2146699264, + 2146719744, + 2146739712, + 2146759168, + 2146778112, + 2146796544, + 2146814464, + 2146832000, + 2146849024, + 2146865664, + }, + { + 2086555136, + 2088125824, + 2089656576, + 2091148416, + 2092602240, + 2094018944, + 2095399680, + 2096745088, + 2098056192, + 2099333888, + 2100578816, + 2101792000, + 2102974080, + 2104125824, + 2105248128, + 2106341760, + 2107407232, + 2108445440, + 2109456896, + 2110442496, + 2111402624, + 2112338176, + 2113249664, + 2114137728, + 2115002880, + 2115845760, + 2116666880, + 2117466880, + 2118246272, + 2119005568, + 2119745280, + 2120465920, + 2121167872, + 2121851776, + 2122517888, + 2123166976, + 2123799168, + 2124414976, + 2125014912, + 2125599360, + 2126168704, + 2126723200, + 2127263360, + 2127789568, + 2128302208, + 2128801408, + 2129287808, + 2129761536, + 2130222976, + 2130672512, + 2131110272, + 2131536768, + 2131952128, + 2132356736, + 2132750848, + 2133134720, + 2133508736, + 2133872896, + 2134227584, + 2134573184, + 2134909696, + 2135237504, + 2135556736, + 2135867648, + 2136170624, + 2136465536, + 2136752896, + 2137032832, + 2137305344, + 2137570816, + 2137829376, + 2138081280, + 2138326528, + 2138565504, + 2138798080, + 2139024768, + 2139245440, + 2139460480, + 2139669888, + 2139873792, + 2140072320, + 2140265856, + 2140454144, + 2140637696, + 2140816384, + 2140990464, + 2141159936, + 2141325056, + 2141485824, + 2141642368, + 2141794944, + 2141943424, + 2142088064, + 2142228992, + 2142366208, + 2142499840, + 2142630016, + 2142756736, + 2142880128, + 2143000448, + 2143117440, + 2143231488, + 2143342592, + 2143450752, + 2143556096, + 2143658624, + 2143758592, + 2143855872, + 2143950592, + 2144043008, + 2144132864, + 2144220416, + 2144305664, + 2144388608, + 2144469504, + 2144548224, + 2144624896, + 2144699648, + 2144772352, + 2144843264, + 2144912256, + 2144979328, + 2145044864, + 2145108480, + 2145170560, + 2145231104, + 2145289856, + 2145347200, + 2145403008, + 2145457408, + 2145510400, + 2145561984, + 2145612160, + 2145661056, + 2145708672, + 2145755136, + 2145800192, + 2145844224, + 2145887104, + 2145928832, + 2145969408, + 2146008960, + 2146047616, + 2146085120, + 2146121600, + 2146157184, + 2146191872, + 2146225664, + 2146258560, + 2146290560, + 2146321792, + 2146352128, + 2146381696, + 2146410496, + 2146438528, + 2146465920, + 2146492416, + 2146518400, + 2146543616, + 2146568192, + 2146592128, + 2146615424, + 2146638080, + 2146660224, + 2146681728, + 2146702720, + 2146723072, + 2146743040, + 2146762368, + 2146781184, + 2146799616, + 2146817408, + 2146834816, + 2146851840, + 2146868352, + 2146884352, + 2146900096, + 2146915328, + 2146930176, + 2146944640, + 2146958720, + 2146972416, + 2146985856, + 2146998784, + 2147011456, + 2147023872, + 2147035904, + 2147047552, + 2147058944, + 2147070080, + 2147080832, + 2147091456, + 2147101696, + 2147111680, + 2147121408, + 2147130880, + 2147140096, + 2147149056, + 2147157760, + 2147166336, + 2147174656, + }, + { + 2106670080, + 2107727232, + 2108757120, + 2109760640, + 2110738432, + 2111691008, + 2112619136, + 2113523328, + 2114404352, + 2115262592, + 2116098816, + 2116913408, + 2117707136, + 2118480256, + 2119233536, + 2119967360, + 2120682240, + 2121378688, + 2122057088, + 2122717952, + 2123361792, + 2123988992, + 2124599936, + 2125195136, + 2125774848, + 2126339584, + 2126889728, + 2127425536, + 2127947520, + 2128456064, + 2128951296, + 2129433856, + 2129903744, + 2130361600, + 2130807424, + 2131241728, + 2131664768, + 2132076928, + 2132478208, + 2132869248, + 2133250048, + 2133620992, + 2133982208, + 2134334080, + 2134676864, + 2135010688, + 2135335936, + 2135652608, + 2135961088, + 2136261504, + 2136554112, + 2136839168, + 2137116800, + 2137387136, + 2137650560, + 2137907072, + 2138156928, + 2138400256, + 2138637184, + 2138867968, + 2139092864, + 2139311744, + 2139524992, + 2139732736, + 2139934976, + 2140131968, + 2140323840, + 2140510720, + 2140692736, + 2140870016, + 2141042688, + 2141210752, + 2141374592, + 2141534080, + 2141689344, + 2141840640, + 2141987968, + 2142131456, + 2142271232, + 2142407424, + 2142539904, + 2142669056, + 2142794752, + 2142917248, + 2143036544, + 2143152640, + 2143265792, + 2143375872, + 2143483264, + 2143587712, + 2143689472, + 2143788544, + 2143885056, + 2143979136, + 2144070656, + 2144159872, + 2144246656, + 2144331264, + 2144413568, + 2144493824, + 2144571904, + 2144647936, + 2144722048, + 2144794240, + 2144864512, + 2144932864, + 2144999552, + 2145064448, + 2145127680, + 2145189248, + 2145249152, + 2145307520, + 2145364480, + 2145419776, + 2145473792, + 2145526272, + 2145577472, + 2145627264, + 2145675776, + 2145723008, + 2145768960, + 2145813760, + 2145857408, + 2145899904, + 2145941376, + 2145981696, + 2146020864, + 2146059136, + 2146096384, + 2146132608, + 2146167936, + 2146202368, + 2146235776, + 2146268416, + 2146300160, + 2146331136, + 2146361216, + 2146390528, + 2146419200, + 2146446976, + 2146474112, + 2146500480, + 2146526208, + 2146551168, + 2146575488, + 2146599296, + 2146622464, + 2146644864, + 2146666880, + 2146688128, + 2146708992, + 2146729216, + 2146748928, + 2146768128, + 2146786816, + 2146805120, + 2146822784, + 2146840064, + 2146856960, + 2146873344, + 2146889216, + 2146904832, + 2146919936, + 2146934656, + 2146948992, + 2146962944, + 2146976640, + 2146989824, + 2147002752, + 2147015296, + 2147027584, + 2147039488, + 2147051136, + 2147062400, + 2147073408, + 2147084160, + 2147094528, + 2147104768, + 2147114624, + 2147124352, + 2147133696, + 2147142912, + 2147151744, + 2147160448, + 2147168896, + 2147177088, + 2147185152, + 2147192960, + 2147200512, + 2147207936, + 2147215104, + 2147222144, + 2147229056, + 2147235712, + 2147242112, + 2147248384, + 2147254656, + 2147260544, + 2147266432, + 2147272064, + 2147277568, + }, + + +}; /*------------------------------------------------------------------------- * DFT Stereo ROM tables @@ -2901,3 +3721,5 @@ const Word16 ivas_param_upmx_mx_qmap[33] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 7, 6, 5, 4, 3, 2, 1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 7, 6, 5, 4, 3, 2, 1, 0 }; + +/* clang-format on */ diff --git a/lib_com/ivas_rom_com.h b/lib_com/ivas_rom_com.h index b58e183ebda207962993ac3a75678cbc2ef4ce1d..6cd11215df85ee5f3beec5ccd7dce360e62407d3 100644 --- a/lib_com/ivas_rom_com.h +++ b/lib_com/ivas_rom_com.h @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other @@ -326,5 +326,8 @@ extern const Word16 sns_1st_means_32k[2][16]; extern const Word16 ivas_param_upmx_mx_qmap[33]; + +extern const Word32 release_cnst_table[4][201]; // Q31 + /* IVAS_ROM_COM_H */ #endif diff --git a/lib_com/ivas_rom_com_fx.c b/lib_com/ivas_rom_com_fx.c index ac47365616ae6dc38b6b80d115ebd47bb02c3e3e..a7a8bdcbfd6176743ab5f8571aa3cb82905bd5fc 100644 --- a/lib_com/ivas_rom_com_fx.c +++ b/lib_com/ivas_rom_com_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other @@ -1356,6 +1356,16 @@ const UWord32 tdm_ratio_tabl_fx[TDM_NQ + 1] = { 2147483647, 2147483647, 2147483647 }; +// Q30 +const Word32 tdm_ratio_tabl_fx_Q30[] = { + 0, 0, 11703786, 26306674, 46385648, 71940704, 102542344, 137868448, + 177596896, 221298192, 268435456, 318471840, 370977792, 425201760, 480714208, + 536870912, 593027584, 648540032, 702764032, 755270016, 805306368, 852443648, + 896144896, 935873344, 971199488, 1001801152, 1027356160, 1047435136, + 1062038016, 1073741824, 1073741824, 1073741824 +}; + + // Q24 const Word32 tdm_ratio_tabl_fx_Q24[TDM_NQ + 1] = { 0, 0, 182871, 411041, 724775, 1124073, 1602224, 2154194, @@ -1607,23 +1617,23 @@ const Word32 coherence_cb1_masa_fx[MASA_NO_CV_COH1 * MASA_MAXIMUM_CODING_SUBBAND }; /* Multi-channel input and output setups */ -const int16_t ls_azimuth_CICP2_idx[2] = { 1, 2 }; -const int16_t ls_elevation_CICP2_idx[2] = { 0, 0 }; +const Word16 ls_azimuth_CICP2_idx[2] = { 1, 2 }; +const Word16 ls_elevation_CICP2_idx[2] = { 0, 0 }; -const int16_t ls_azimuth_CICP6_idx[5] = { 1, 2, 0, 7, 8 }; -const int16_t ls_elevation_CICP6_idx[5] = { 0, 0, 0, 0, 0 }; +const Word16 ls_azimuth_CICP6_idx[5] = { 1, 2, 0, 7, 8 }; +const Word16 ls_elevation_CICP6_idx[5] = { 0, 0, 0, 0, 0 }; -const int16_t ls_azimuth_CICP12_idx[7] = { 1, 2, 0, 7, 8, 9, 10 }; -const int16_t ls_elevation_CICP12_idx[7] = { 0, 0, 0, 0, 0, 0, 0 }; +const Word16 ls_azimuth_CICP12_idx[7] = { 1, 2, 0, 7, 8, 9, 10 }; +const Word16 ls_elevation_CICP12_idx[7] = { 0, 0, 0, 0, 0, 0, 0 }; -const int16_t ls_azimuth_CICP14_idx[7] = { 1, 2, 0, 7, 8, 1, 2 }; -const int16_t ls_elevation_CICP14_idx[7] = { 0, 0, 0, 0, 0, 3, 4 }; +const Word16 ls_azimuth_CICP14_idx[7] = { 1, 2, 0, 7, 8, 1, 2 }; +const Word16 ls_elevation_CICP14_idx[7] = { 0, 0, 0, 0, 0, 3, 4 }; -const int16_t ls_azimuth_CICP16_idx[9] = { 1, 2, 0, 7, 8, 1, 2, 7, 8 }; -const int16_t ls_elevation_CICP16_idx[9] = { 0, 0, 0, 0, 0, 3, 3, 3, 3 }; +const Word16 ls_azimuth_CICP16_idx[9] = { 1, 2, 0, 7, 8, 1, 2, 7, 8 }; +const Word16 ls_elevation_CICP16_idx[9] = { 0, 0, 0, 0, 0, 3, 3, 3, 3 }; -const int16_t ls_azimuth_CICP19_idx[11] = { 1, 2, 0, 9, 10, 5, 6, 1, 2, 9, 10 }; -const int16_t ls_elevation_CICP19_idx[11] = { 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3 }; +const Word16 ls_azimuth_CICP19_idx[11] = { 1, 2, 0, 9, 10, 5, 6, 1, 2, 9, 10 }; +const Word16 ls_elevation_CICP19_idx[11] = { 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3 }; const Word32 shoebox_sin_cos_tbl_fx[11][2] = { { 0, 1073741824 }, // 0 { 536870912, 929887680 }, diff --git a/lib_com/ivas_rom_com_fx.h b/lib_com/ivas_rom_com_fx.h index 88bbaabbc1ff3dc34004d6192170ae7b2639044d..3344a35d208b8ed225895c9bab0f66db88ac7978 100644 --- a/lib_com/ivas_rom_com_fx.h +++ b/lib_com/ivas_rom_com_fx.h @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other @@ -108,6 +108,7 @@ extern const Word16 pow_10_icbwe_gsMappingDFT_tbl_fx[]; *----------------------------------------------------------------------------------*/ extern const UWord32 tdm_ratio_tabl_fx[TDM_NQ + 1]; +extern const Word32 tdm_ratio_tabl_fx_Q30[TDM_NQ + 1]; extern const Word32 tdm_ratio_tabl_fx_Q24[TDM_NQ + 1]; extern const UWord32 tdm_den_ratio_tabl_fx[]; extern const Word16 icbwe_gsMapping_tbl_fx[]; // Q12 diff --git a/lib_com/ivas_rotation_com.c b/lib_com/ivas_rotation_com.c new file mode 100644 index 0000000000000000000000000000000000000000..6e31f96d5b13bed79fd99209745e40ee8752b95b --- /dev/null +++ b/lib_com/ivas_rotation_com.c @@ -0,0 +1,273 @@ +/****************************************************************************************************** + + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository. All Rights Reserved. + + This software is protected by copyright law and by international treaties. + The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository retain full ownership rights in their respective contributions in + the software. This notice grants no license of any kind, including but not limited to patent + license, nor is any license granted by implication, estoppel or otherwise. + + Contributors are required to enter into the IVAS codec Public Collaboration agreement before making + contributions. + + This software is provided "AS IS", without any express or implied warranties. The software is in the + development stage. It is intended exclusively for experts who have experience with such software and + solely for the purpose of inspection. All implied warranties of non-infringement, merchantability + and fitness for a particular purpose are hereby disclaimed and excluded. + + Any dispute, controversy or claim arising under or in relation to providing this software shall be + submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in + accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and + the United Nations Convention on Contracts on the International Sales of Goods. + +*******************************************************************************************************/ + +#include "ivas_cnst.h" +#include +#include +#include "options.h" +#include +#include "cnst.h" +#include "prot_fx.h" +#include "ivas_prot_fx.h" +#ifdef DEBUGGING +#include "debug.h" +#endif +#include "wmc_auto.h" +#include "basop_util.h" +#include "enh64.h" +/*------------------------------------------------------------------------- + * Euler2Quat() + * + * Calculate corresponding Quaternion from Euler angles in radians + *------------------------------------------------------------------------*/ +void Euler2Quat_fx( + const Word32 yaw, /* i : yaw (x) Q22 */ + const Word32 pitch, /* i : pitch (y) Q22 */ + const Word32 roll, /* i : roll (z) Q22 */ + IVAS_QUATERNION *quat /* o : quaternion describing the rotation Q22*/ +) +{ + Word16 cr = getCosWord16( extract_l( L_shr_r( roll, 10 ) ) ); // Q14 + Word16 sr = shr( getSinWord16( extract_l( L_shr_r( roll, 10 ) ) ), 1 ); // Q14 + Word16 cp = getCosWord16( extract_l( L_shr_r( pitch, 10 ) ) ); + Word16 sp = shr( getSinWord16( extract_l( L_shr_r( pitch, 10 ) ) ), 1 ); // Q14 + Word16 cy = getCosWord16( extract_l( L_shr_r( yaw, 10 ) ) ); + Word16 sy = shr( getSinWord16( extract_l( L_shr_r( yaw, 10 ) ) ), 1 ); // Q14 + quat->w_fx = L_shr_r( L_add( Mpy_32_16_1( L_mult0( cr, cp ), cy ), Mpy_32_16_1( L_mult0( sr, sp ), sy ) ), 5 ); // Q22 + move32(); + quat->x_fx = L_shr_r( L_sub( Mpy_32_16_1( L_mult0( sr, cp ), cy ), Mpy_32_16_1( L_mult0( cr, sp ), sy ) ), 5 ); // Q22 + move32(); + quat->y_fx = L_shr_r( L_add( Mpy_32_16_1( L_mult0( sr, cp ), sy ), Mpy_32_16_1( L_mult0( cr, sp ), cy ) ), 5 ); // Q22 + move32(); + quat->z_fx = L_shr_r( L_sub( Mpy_32_16_1( L_mult0( cr, cp ), sy ), Mpy_32_16_1( L_mult0( sr, sp ), cy ) ), 5 ); // Q22 + move32(); + + quat->q_fact = Q22; + move16(); + + return; +} + + +#ifdef SPLIT_REND_WITH_HEAD_ROT + +/*------------------------------------------------------------------------- + * Copy_Quat_fx() + * + * Quaternion q factor modification + *------------------------------------------------------------------------*/ +void Copy_Quat_fx( + const IVAS_QUATERNION *in_quat, /* i : quaternion describing the rotation */ + IVAS_QUATERNION *out_quat /* i : quaternion describing the rotation */ +) +{ + out_quat->q_fact = in_quat->q_fact; + out_quat->w_fx = in_quat->w_fx; + out_quat->x_fx = in_quat->x_fx; + out_quat->y_fx = in_quat->y_fx; + out_quat->z_fx = in_quat->z_fx; + move16(); + move32(); + move32(); + move32(); + move32(); + + return; +} + +/*------------------------------------------------------------------------- + * Scale_Quat_fx() + * + * Quaternion q factor modification + *------------------------------------------------------------------------*/ +void modify_Quat_q_fx( + const IVAS_QUATERNION *in_quat, /* i : quaternion describing the rotation */ + IVAS_QUATERNION *out_quat, /* i : quaternion describing the rotation */ + Word16 q_new /* i : quaternion describing the rotation */ +) +{ + out_quat->w_fx = L_shl_sat( in_quat->w_fx, sub( q_new, in_quat->q_fact ) ); // q_new + out_quat->x_fx = L_shl_sat( in_quat->x_fx, sub( q_new, in_quat->q_fact ) ); // q_new + out_quat->y_fx = L_shl_sat( in_quat->y_fx, sub( q_new, in_quat->q_fact ) ); // q_new + out_quat->z_fx = L_shl_sat( in_quat->z_fx, sub( q_new, in_quat->q_fact ) ); // q_new + out_quat->q_fact = q_new; + return; +} + +/*------------------------------------------------------------------------- + * modify_Rmat_q_fx() + * + * Rotation matrix q factor modification + *------------------------------------------------------------------------*/ +void modify_Rmat_q_fx( + Word32 Rmat_in[3][3], /* i : real-space rotation matrix for this rotation */ + Word32 Rmat_out[3][3], /* o : real-space rotation matrix for this rotation*/ + Word16 q_cur, /* i : current q factor for rotation matrix */ + Word16 q_new /* i : target q factor for rotation matrix */ +) +{ + Word16 j, k; + + FOR( j = 0; j < 3; j++ ) + { + FOR( k = 0; k < 3; k++ ) + { + Rmat_out[j][k] = L_shl( Rmat_in[j][k], sub( q_new, q_cur ) ); + move32(); + } + } + return; +} + +/*------------------------------------------------------------------------- + * Quat2EulerDegree() + * + * Quaternion handling: calculate corresponding Euler angles in degrees + *------------------------------------------------------------------------*/ +void Quat2EulerDegree_fx( + const IVAS_QUATERNION quat, /* i : quaternion describing the rotation */ + Word32 *yaw_fx, /* o : yaw */ + Word32 *pitch_fx, /* o : pitch */ + Word32 *roll_fx /* o : roll */ +) +{ + IF( NE_32( quat.w_fx, L_negate( 12582912 ) /*3.0f in Q22*/ ) ) + { + Word32 tmp1 = W_extract_l( W_shr( W_mult0_32_32( quat.w_fx, quat.x_fx ), Q22 ) ); // Q22 + Word32 tmp2 = W_extract_l( W_shr( W_mult0_32_32( quat.y_fx, quat.z_fx ), Q22 ) ); // Q22 + Word32 tmp3 = L_shl( L_add( tmp1, tmp2 ), 1 ); // Q22 + + Word32 tmp4 = W_extract_l( W_shr( W_mult0_32_32( quat.x_fx, quat.x_fx ), Q22 ) ); // Q22 + Word32 tmp5 = W_extract_l( W_shr( W_mult0_32_32( quat.y_fx, quat.y_fx ), Q22 ) ); // Q22 + Word32 tmp6 = L_shl( L_add( tmp4, tmp5 ), 1 ); + Word32 tmp7 = L_sub( ONE_IN_Q22, tmp6 ); + + IF( tmp3 >= -2 && tmp3 <= 2 ) + { + tmp3 = 0; + } + IF( tmp7 >= -2 && tmp7 <= 2 ) + { + tmp7 = 0; + } + + Word16 yaw_fx_16 = BASOP_util_atan2( tmp3, tmp7, 0 ); // Q13 + *yaw_fx = Mpy_32_16_1( 961263669 /*_180_OVER_PI in Q24*/, yaw_fx_16 ); + + Word32 p_fx; + Word32 tmp8 = W_extract_l( W_shr( W_mult0_32_32( quat.w_fx, quat.y_fx ), Q22 ) ); // Q22 + Word32 tmp9 = W_extract_l( W_shr( W_mult0_32_32( quat.z_fx, quat.x_fx ), Q22 ) ); // Q22 + p_fx = L_shl( L_sub( tmp8, tmp9 ), 1 ); + p_fx = max( L_negate( ONE_IN_Q22 ), min( ONE_IN_Q22, p_fx ) ); // Q22 + + Word32 p_fx_sq = W_extract_l( W_shr( W_mult0_32_32( p_fx, p_fx ), Q22 ) ); + Word16 res_exp = 0; + Word32 one_minus_p_fx_sq = BASOP_Util_Add_Mant32Exp( ONE_IN_Q30, 1, L_negate( p_fx_sq ), 31 - Q22, &res_exp ); + Word32 sqrt_one_minus_p_fx_sq = Sqrt32( one_minus_p_fx_sq, &res_exp ); + + Word16 pitch_fx_16 = BASOP_util_atan2( p_fx, sqrt_one_minus_p_fx_sq, ( 31 - Q22 ) - res_exp ); + + *pitch_fx = Mpy_32_16_1( 961263669 /*_180_OVER_PI in Q24*/, pitch_fx_16 ); + + Word32 tmp10 = W_extract_l( W_shr( W_mult0_32_32( quat.w_fx, quat.z_fx ), Q22 ) ); // Q22 + Word32 tmp11 = W_extract_l( W_shr( W_mult0_32_32( quat.x_fx, quat.y_fx ), Q22 ) ); // Q22 + Word32 tmp12 = L_shl( L_add( tmp10, tmp11 ), 1 ); // Q22 + + Word32 tmp13 = W_extract_l( W_shr( W_mult0_32_32( quat.y_fx, quat.y_fx ), Q22 ) ); // Q22 + Word32 tmp14 = W_extract_l( W_shr( W_mult0_32_32( quat.z_fx, quat.z_fx ), Q22 ) ); // Q22 + Word32 tmp15 = L_shl( L_add( tmp13, tmp14 ), 1 ); // Q22 + Word32 tmp16 = L_sub( ONE_IN_Q22, tmp15 ); // Q22 + + IF( tmp12 >= -2 && tmp12 <= 2 ) + { + tmp12 = 0; + } + IF( tmp16 >= -2 && tmp16 <= 2 ) + { + tmp16 = 0; + } + Word16 roll_fx_16 = BASOP_util_atan2( tmp12, tmp16, 0 ); // Q13 + *roll_fx = Mpy_32_16_1( 961263669 /*_180_OVER_PI in Q24*/, roll_fx_16 ); + } + ELSE + { + /* Euler angles in R_X(roll)*R_Y(pitch)*R_Z(yaw) convention + * + * yaw: rotate scene counter-clockwise in the horizontal plane + * pitch: rotate scene in the median plane, increase elevation with positive values + * roll: rotate scene from the right ear to the top + */ + *yaw_fx = quat.z_fx; + *pitch_fx = quat.y_fx; + *roll_fx = quat.x_fx; + } + + return; +} + +#endif + +/*------------------------------------------------------------------------- + * deg2rad() + * + * Converts degrees to normalized radians + *------------------------------------------------------------------------*/ +Word32 deg2rad_fx( + Word32 degrees // Q22 +) +{ + WHILE( GE_32( degrees, DEGREE_180 ) ) + { + degrees = L_sub( degrees, DEGREE_360 ); + } + WHILE( LE_32( degrees, -DEGREE_180 ) ) + { + degrees = L_add( degrees, DEGREE_360 ); + } + + return Mpy_32_32( PI_OVER_180_FX, degrees ); // Q22 +} + +float deg2rad( + float degrees ) +{ + while ( degrees >= 180.0f ) + { + degrees = degrees - 360.0f; + } + while ( degrees <= -180.0f ) + { + degrees = degrees + 360.0f; + } + + return PI_OVER_180 * degrees; +} diff --git a/lib_com/ivas_sba_config.c b/lib_com/ivas_sba_config_fx.c similarity index 99% rename from lib_com/ivas_sba_config.c rename to lib_com/ivas_sba_config_fx.c index 370e8caa4db8076b09502f24bb7f344d85f8ba0f..b3a0806d4af63519605efa1c7ff5da40ba095d2e 100644 --- a/lib_com/ivas_sba_config.c +++ b/lib_com/ivas_sba_config_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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,8 +37,7 @@ #include "cnst.h" #include "ivas_cnst.h" #include "rom_com.h" -#include "prot.h" -#include "ivas_prot.h" +#include "prot_fx.h" #include "ivas_stat_com.h" #include "ivas_rom_com.h" #include "wmc_auto.h" diff --git a/lib_com/ivas_sns_com_fx.c b/lib_com/ivas_sns_com_fx.c index 5931c4ea1345e88bdad1ca30b998dfbcae89a882..fa64b0092d6de30d78c2199930ea32e99629cb3a 100644 --- a/lib_com/ivas_sns_com_fx.c +++ b/lib_com/ivas_sns_com_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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,7 @@ #include #include "options.h" #include "cnst.h" -#include "prot.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "rom_com.h" #include "ivas_rom_com.h" #include @@ -62,12 +60,11 @@ void sns_compute_scf_fx( Word64 sum; Word32 L_tmp; const Word32 *pow_tilt; + Word16 q_shift, q_out, f_tmp; + Word16 bw, inv_bw, exp; const UWord8 nBands = pPsychParams->nBands; move16(); const UWord8 *bandLengths = pPsychParams->bandLengths; - Word8 bw = 0; - move16(); - Word16 q_shift; const Word16 w_0 = 2730; // (1.0f / 12.0f) in Q15 move16(); @@ -89,91 +86,83 @@ void sns_compute_scf_fx( IF( bandLengths == NULL ) { - bw = (Word8) shr( L_frame, 6 ); + bw = shr( L_frame, 6 ); move16(); + + exp = norm_s( bw ); + inv_bw = div_s( ONE_IN_Q14, shl( bw, exp ) ); // Q:15+14-exp = 29-exp + inv_bw = shl( inv_bw, sub( exp, 14 ) ); // Q15 + /* Energy per band */ k = 0; move16(); FOR( i = 0; i < nBands; ++i ) { - x_64[i] = 0; + sum = 0; move64(); FOR( n = 0; n < bw; ( ++n, ++k ) ) { - x_64[i] = W_add( x_64[i], W_deposit32_l( spectrum[k] ) ); // Q_in - move64(); + /* x[i] += spectrum[k]; + inv_bw is for x[i] /= bw; */ + sum = W_mac_32_16( sum, spectrum[k], inv_bw ); // Q_in+15+1 } + x_64[i] = sum; // Q_in+16 + move64(); } } ELSE { /* Energy per band */ k = 0; - move32(); + move16(); FOR( i = 0; i < nBands; ++i ) { - x_64[i] = 0; + exp = norm_s( bandLengths[i] ); + inv_bw = div_s( ONE_IN_Q14, shl( bandLengths[i], exp ) ); // Q:15+14-exp + inv_bw = shl( inv_bw, sub( exp, 14 ) ); // Q15 + + sum = 0; move64(); FOR( n = 0; n < bandLengths[i]; ( ++n, ++k ) ) { - x_64[i] = W_add( x_64[i], W_deposit32_l( spectrum[k] ) ); // Q_in - move64(); + /* x[i] += spectrum[k]; + inv_bw is for x[i] /= bandLengths[i]; */ + sum = W_mac_32_16( sum, spectrum[k], inv_bw ); // Q_in+15+1 } + x_64[i] = sum; // Q_in+16 + move64(); } } /* Move accumulated values to 32-bit */ - q_shift = 0; - move16(); - IF( x_64[0] != 0 ) + q_shift = W_norm_arr( x_64, nBands ); // W_norm_arr return 63 when all the values of the input buffer are zeroes + IF( EQ_16( q_shift, 63 ) ) { - q_shift = W_norm( x_64[0] ); - } - FOR( i = 1; i < nBands; ++i ) - { - IF( x_64[i] != 0 ) - { - q_shift = s_min( q_shift, W_norm( x_64[i] ) ); - } - } - FOR( i = 0; i < nBands; ++i ) - { - x[i] = W_extract_l( W_shl( x_64[i], sub( q_shift, 32 ) ) ); // Q_in + (q_shift - 32) - } + /* If all the values of x_64 are zeros, the scale factor (scf) values will be calculated as zeroes as per the below operations. + To avoid extra computations in such a case, set scf values as zeroes and return. */ - IF( bandLengths == NULL ) - { - Word16 inv_bw; - bw = (Word8) shr( L_frame, 6 ); - move16(); - inv_bw = div_l( ONE_IN_Q16 /*1 Q16*/, bw ); // Q15 - FOR( i = 0; i < nBands; ++i ) - { - x[i] = Mpy_32_16_1( x[i], inv_bw ); // Q_in + (q_shift - 32) - move32(); - } + set_zero_fx( scf, SNS_NPTS ); + + return; } - ELSE + + FOR( i = 0; i < nBands; ++i ) { - FOR( i = 0; i < nBands; ++i ) - { - Word16 inv_bw = div_l( ONE_IN_Q16 /*1 Q16*/, bandLengths[i] ); // Q15 - x[i] = Mpy_32_16_1( x[i], inv_bw ); // Q_in + (q_shift - 32) - move32(); - } + x[i] = W_extract_h( W_shl( x_64[i], q_shift ) ); // Q: Q_in+16+q_shift-32 = Q_in+q_shift-16 + move32(); } /* Smoothing */ - xs[0] = L_add( Mpy_32_16_1( x[0], 24576 /* 0.75 in Q15 */ ), Mpy_32_16_1( x[1], 8192 /* 0.25 in Q15 */ ) ); // Q_in + (q_shift - 32) + xs[0] = Madd_32_16( Mpy_32_16_1( x[0], 24576 /* 0.75 in Q15 */ ), x[1], 8192 /* 0.25 in Q15 */ ); // Q_in+q_shift-16 move32(); FOR( i = 1; i < FDNS_NPTS - 1; i++ ) { - xs[i] = L_add( L_add( Mpy_32_16_1( x[i], 16384 /* 0.5 in Q15 */ ), Mpy_32_16_1( x[i - 1], 8192 /* 0.25 in Q15 */ ) ), Mpy_32_16_1( x[i + 1], 8192 /* 0.25 in Q15 */ ) ); // Q_in + (q_shift - 32) + xs[i] = Madd_32_16( Madd_32_16( Mpy_32_16_1( x[i], 16384 /* 0.5 in Q15 */ ), x[i - 1], 8192 /* 0.25 in Q15 */ ), x[i + 1], 8192 /* 0.25 in Q15 */ ); // Q_in+q_shift-16 move32(); } - xs[FDNS_NPTS - 1] = L_add( Mpy_32_16_1( x[FDNS_NPTS - 1], 24576 /* 0.75 in Q15 */ ), Mpy_32_16_1( x[FDNS_NPTS - 2], 8192 /* 0.25 in Q15 */ ) ); // Q_in + (q_shift - 32) + xs[FDNS_NPTS - 1] = Madd_32_16( Mpy_32_16_1( x[FDNS_NPTS - 1], 24576 /* 0.75 in Q15 */ ), x[FDNS_NPTS - 2], 8192 /* 0.25 in Q15 */ ); // Q_in+q_shift-16 move32(); /* Pre-emphasis */ @@ -195,86 +184,83 @@ void sns_compute_scf_fx( FOR( i = 0; i < FDNS_NPTS; i++ ) { - xs[i] = Mpy_32_32( xs[i], pow_tilt[i] ); // Q_in + (q_shift - 32) + xs[i] = Mpy_32_32( xs[i], pow_tilt[i] ); // Q_in+q_shift-16+23-31 = Q_in+q_shift-24 move32(); } /* Noise floor at -40dB */ sum = 0; move64(); - FOR( Word16 ind = 0; ind < FDNS_NPTS; ind++ ) + FOR( i = 0; i < FDNS_NPTS; i++ ) { - sum = W_add( sum, W_deposit32_l( xs[ind] ) ); // Q_in + (q_shift - 32) + sum = W_mac_32_16( sum, xs[i], 1 ); // Q_in+q_shift-24+1 } - mean = W_extract_l( W_shr( sum, 6 ) ); // Q_in + (q_shift - 32) - nf = Mpy_32_32( mean, 214748 /* powf( 10.0f, -4.0f ) in Q31 */ ); // Q_in + (q_shift - 32) - nf = L_max( nf, 0 /* powf( 2.0f, -32.0f ) in Q31 */ ); // Q_in + (q_shift - 32) + q_out = sub( add( Q_in, q_shift ), 24 ); + + /* mean = sum / FDNS_NPTS; + -Q6 is for division with FDNS_NPTS and -Q1 is to reduce Q by one */ + mean = W_shl_sat_l( sum, -Q7 ); // q_out + nf = Mpy_32_32( mean, 214748 /* powf( 10.0f, -4.0f ) in Q31 */ ); // q_out + nf = L_max( nf, L_shl( 256, sub( q_out, 40 ) ) /* powf( 2.0f, -32.0f ) in Q40 */ ); // q_out FOR( i = 0; i < FDNS_NPTS; i++ ) { - if ( LT_32( xs[i], nf ) ) - { - xs[i] = nf; // Q_in + (q_shift - 32) - move32(); - } + xs[i] = L_max( xs[i], nf ); // q_out + move32(); } /* Log-domain */ FOR( i = 0; i < FDNS_NPTS; i++ ) { - Word16 e_tmp = norm_l( xs[i] ); - Word16 f_tmp = Log2_norm_lc( L_shl( xs[i], e_tmp ) ); /*Q16*/ - e_tmp = sub( sub( 34, e_tmp ), Q_in ); - /* Note: Mpy_32_16 is used temporarily for this computation, It needs to be replaced with appropriate BASOP. */ - xl[i] = Mpy_32_16( e_tmp, f_tmp, 16384 ); /* Q16 */ + /* xl[i] = logf( xs[i] ) * scale_log; + scale_log = INV_LOG_2 * 0.5f; */ + + exp = norm_l( xs[i] ); + f_tmp = Log2_norm_lc( L_shl( xs[i], exp ) ); // Q15 + exp = sub( sub( 30, exp ), q_out ); + L_tmp = L_mac( L_deposit_h( exp ), f_tmp, 1 ); // Q16 + xl[i] = L_shr( L_tmp, 1 ); // Q16 move32(); } /* Downsampling */ - L_tmp = L_deposit_l( 0 ); - L_tmp = Madd_32_16( L_tmp, xl[0], w_0 ); // Q16 - L_tmp = Madd_32_16( L_tmp, xl[0], w_1 ); // Q16 - L_tmp = Madd_32_16( L_tmp, xl[1], w_2 ); // Q16 - L_tmp = Madd_32_16( L_tmp, xl[2], w_3 ); // Q16 - L_tmp = Madd_32_16( L_tmp, xl[3], w_4 ); // Q16 - L_tmp = Madd_32_16( L_tmp, xl[4], w_5 ); // Q16 - xl4[0] = L_tmp; // Q16 - move32(); + L_tmp = Madd_32_16( Mpy_32_16_1( xl[0], w_0 ), xl[0], w_1 ); // Q16 + L_tmp = Madd_32_16( L_tmp, xl[1], w_2 ); // Q16 + L_tmp = Madd_32_16( L_tmp, xl[2], w_3 ); // Q16 + L_tmp = Madd_32_16( L_tmp, xl[3], w_4 ); // Q16 + xl4[0] = Madd_32_16( L_tmp, xl[4], w_5 ); // Q16 + FOR( n = 1; n < SNS_NPTS - 1; n++ ) { - Word16 n4 = shl( n, 2 ); - - L_tmp = L_deposit_l( 0 ); - L_tmp = Madd_32_16( L_tmp, xl[n4 - 1], w_0 ); // Q16 - L_tmp = Madd_32_16( L_tmp, xl[n4], w_1 ); // Q16 - L_tmp = Madd_32_16( L_tmp, xl[n4 + 1], w_2 ); // Q16 - L_tmp = Madd_32_16( L_tmp, xl[n4 + 2], w_3 ); // Q16 - L_tmp = Madd_32_16( L_tmp, xl[n4 + 3], w_4 ); // Q16 - L_tmp = Madd_32_16( L_tmp, xl[n4 + 4], w_5 ); // Q16 - xl4[n] = L_tmp; // Q16 + L_tmp = Mpy_32_16_1( xl[4 * n - 1], w_0 ); // Q16 + L_tmp = Madd_32_16( L_tmp, xl[4 * n], w_1 ); // Q16 + L_tmp = Madd_32_16( L_tmp, xl[4 * n + 1], w_2 ); // Q16 + L_tmp = Madd_32_16( L_tmp, xl[4 * n + 2], w_3 ); // Q16 + L_tmp = Madd_32_16( L_tmp, xl[4 * n + 3], w_4 ); // Q16 + xl4[n] = Madd_32_16( L_tmp, xl[4 * n + 4], w_5 ); // Q16 move32(); } - L_tmp = L_deposit_l( 0 ); - L_tmp = Madd_32_16( L_tmp, xl[FDNS_NPTS - 5], w_0 ); // Q16 - L_tmp = Madd_32_16( L_tmp, xl[FDNS_NPTS - 4], w_1 ); // Q16 - L_tmp = Madd_32_16( L_tmp, xl[FDNS_NPTS - 3], w_2 ); // Q16 - L_tmp = Madd_32_16( L_tmp, xl[FDNS_NPTS - 2], w_3 ); // Q16 - L_tmp = Madd_32_16( L_tmp, xl[FDNS_NPTS - 1], w_4 ); // Q16 - L_tmp = Madd_32_16( L_tmp, xl[FDNS_NPTS - 1], w_5 ); // Q16 - xl4[SNS_NPTS - 1] = L_tmp; // Q16 + L_tmp = Mpy_32_16_1( xl[FDNS_NPTS - 5], w_0 ); // Q16 + L_tmp = Madd_32_16( L_tmp, xl[FDNS_NPTS - 4], w_1 ); // Q16 + L_tmp = Madd_32_16( L_tmp, xl[FDNS_NPTS - 3], w_2 ); // Q16 + L_tmp = Madd_32_16( L_tmp, xl[FDNS_NPTS - 2], w_3 ); // Q16 + L_tmp = Madd_32_16( L_tmp, xl[FDNS_NPTS - 1], w_4 ); // Q16 + xl4[SNS_NPTS - 1] = Madd_32_16( L_tmp, xl[FDNS_NPTS - 1], w_5 ); // Q16 move32(); /* Remove mean and scaling */ sum = 0; move64(); - FOR( Word16 ind = 0; ind < SNS_NPTS; ind++ ) + FOR( i = 0; i < SNS_NPTS; i++ ) { - sum = W_add( sum, W_deposit32_l( xl4[ind] ) ); // Q16 + sum = W_mac_32_16( sum, xl4[i], 1 ); // Q16+1 } - mean = W_extract_l( W_shr( sum, 4 ) ); // Q16 + /* mean = sum / SNS_NPTS; + -Q4 is for division with SNS_NPTS and -Q1 is to reduce Q by one */ + mean = W_shl_sat_l( sum, -Q5 ); // Q16 FOR( i = 0; i < SNS_NPTS; i++ ) { diff --git a/lib_com/ivas_spar_com.c b/lib_com/ivas_spar_com_fx.c similarity index 98% rename from lib_com/ivas_spar_com.c rename to lib_com/ivas_spar_com_fx.c index 7ab41d5edd70313a46658b38f859772a1d34005a..929eaa2c5cd8b94aa689decdc59f27ce2110b67b 100644 --- a/lib_com/ivas_spar_com.c +++ b/lib_com/ivas_spar_com_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other @@ -35,9 +35,7 @@ #include "options.h" #include "basop_util.h" #include "ivas_stat_com.h" -#include "prot.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "rom_com.h" #include "ivas_rom_com.h" #include "cnst.h" @@ -2633,7 +2631,11 @@ static void ivas_calc_p_coeffs_per_band_enc_fx( test(); IF( W_norm( re ) == 0 || W_norm( recon_uu_re[i][j] ) == 0 ) { - re1[m] = L_shr( re1[m], 1 ); // q_recon_uu_re[i][j]-1 +#ifdef FIX_ISSUE_1122 + recon_uu_re[i][j] = L_shr( recon_uu_re[i][j], 1 ); // q_recon_uu_re[i][j] - 1 +#else + re1[m] = L_shr( re1[m], 1 ); // q_recon_uu_re[i][j]-1 +#endif move32(); q_recon_uu_re[i][j] = sub( q_recon_uu_re[i][j], 1 ); move16(); @@ -3804,7 +3806,7 @@ void ivas_compute_spar_params_fx( { Word32 pred_coeffs_re[IVAS_SPAR_MAX_CH - 1][IVAS_MAX_NUM_BANDS]; - Word16 b, i, ndm; + Word16 b, i, ndm, j; Word16 q_pred_coeffs; ivas_get_pred_coeffs_fx( cov_real, pred_coeffs_re, dm_fv_re, num_ch, start_band, end_band, active_w, active_w_vlbr, dtx_vad, from_dirac, dyn_active_w_flag, hSparMd->res_ind, &q_pred_coeffs, q_dm_fv_re ); @@ -3832,7 +3834,11 @@ void ivas_compute_spar_params_fx( } ELSE { +#ifdef FIX_11_1_IVAS_SPAR_DEC_UPMIXER_SF_RND_COEFFS + hSparMd->band_coeffs[b + ( i_ts * IVAS_MAX_NUM_BANDS )].pred_re_fx[i] = L_shr_r( hSparMd->band_coeffs[b + ( i_ts * IVAS_MAX_NUM_BANDS )].pred_re_fx[i], sub( tmp, 22 ) ); // q22 +#else hSparMd->band_coeffs[b + ( i_ts * IVAS_MAX_NUM_BANDS )].pred_re_fx[i] = L_shr( hSparMd->band_coeffs[b + ( i_ts * IVAS_MAX_NUM_BANDS )].pred_re_fx[i], sub( tmp, 22 ) ); // q22 +#endif move32(); } } @@ -3862,7 +3868,7 @@ void ivas_compute_spar_params_fx( #ifdef MSAN_FIX FOR( i = 0; i < ( num_ch - ndm ); i++ ) { - FOR( Word16 j = 0; j < sub( ndm, 1 ); j++ ) + FOR( j = 0; j < sub( ndm, 1 ); j++ ) { hSparMd->band_coeffs[b + ( i_ts * IVAS_MAX_NUM_BANDS )].C_re_fx[i][j] = L_shr( hSparMd->band_coeffs[b + ( i_ts * IVAS_MAX_NUM_BANDS )].C_re_fx[i][j], sub( q_tmp, 22 ) ); // q22 move32(); @@ -3871,7 +3877,7 @@ void ivas_compute_spar_params_fx( #else for ( i = 0; i < IVAS_SPAR_MAX_CH - IVAS_SPAR_MAX_DMX_CHS; i++ ) { - for ( int j = 0; j < IVAS_SPAR_MAX_DMX_CHS - 1; j++ ) + for ( j = 0; j < IVAS_SPAR_MAX_DMX_CHS - 1; j++ ) { hSparMd->band_coeffs[b + i_ts * IVAS_MAX_NUM_BANDS].C_re_fx[i][j] = L_shr( hSparMd->band_coeffs[b + i_ts * IVAS_MAX_NUM_BANDS].C_re_fx[i][j], sub( q_tmp, 22 ) ); } @@ -3884,7 +3890,7 @@ void ivas_compute_spar_params_fx( q_tmp = hSparMd->band_coeffs[b + ( i_ts * IVAS_MAX_NUM_BANDS )].q_P_re_fx; move16(); - FOR( Word16 j = 0; j < sub( IVAS_SPAR_MAX_CH, 1 ); j++ ) + FOR( j = 0; j < sub( IVAS_SPAR_MAX_CH, 1 ); j++ ) { hSparMd->band_coeffs[b + ( i_ts * IVAS_MAX_NUM_BANDS )].P_re_fx[j] = L_shr( hSparMd->band_coeffs[b + ( i_ts * IVAS_MAX_NUM_BANDS )].P_re_fx[j], sub( q_tmp, 22 ) ); // q22 move32(); @@ -3997,7 +4003,8 @@ void ivas_get_spar_md_from_dirac_enc_fx( move16(); P_norm_fx[0] = 0; move32(); - FOR( i = 0; i < max( 0, sub( foa_ch, ndm ) ); i++ ) + Word16 len = s_max( 0, sub( foa_ch, ndm ) ); + FOR( i = 0; i < len; i++ ) { P_norm_fx[0] = L_add( P_norm_fx[0], Mpy_32_32( hSpar_md->band_coeffs[start_band - 1].P_re_fx[i], hSpar_md->band_coeffs[start_band - 1].P_re_fx[i] ) ); // 2*q_P_re - 31 move32(); @@ -4007,7 +4014,8 @@ void ivas_get_spar_md_from_dirac_enc_fx( P_norm_fx[1] = 0; move32(); - FOR( ; i < max( 0, ( min( num_ch, hoa2_ch ) - ndm ) ); i++ ) + len = s_max( 0, sub( s_min( num_ch, hoa2_ch ), ndm ) ); + FOR( ; i < len; i++ ) // max( 0, ( min( num_ch, hoa2_ch ) - ndm ) ) { P_norm_fx[1] = L_add( P_norm_fx[1], Mpy_32_32( hSpar_md->band_coeffs[start_band - 1].P_re_fx[i], hSpar_md->band_coeffs[start_band - 1].P_re_fx[i] ) ); // 2*q_P_re - 31 move32(); @@ -4024,8 +4032,8 @@ void ivas_get_spar_md_from_dirac_enc_fx( } P_norm_fx[2] = Mpy_32_32( L_shl( P_norm_fx[2], 3 ), diff_norm_order3_table[min( diff_norm_order3_fx, max( 0, ( num_ch - ndm ) ) )] ); // 2*q_P_re - 31 move32(); - - FOR( i = 0; i < max( 0, ( foa_ch - ndm ) ); i++ ) + len = s_max( 0, sub( foa_ch, ndm ) ); + FOR( i = 0; i < len; i++ ) // i < max( 0, ( foa_ch - ndm ) ) { idx = sub( remix_order[i + ndm], ndm ); P_dir_fact_fx[idx] = Mpy_32_32( hSpar_md->band_coeffs[start_band - 1].P_re_fx[i], hSpar_md->band_coeffs[start_band - 1].P_re_fx[i] ); // 2*q_P_re - 31 @@ -4038,7 +4046,8 @@ void ivas_get_spar_md_from_dirac_enc_fx( move32(); } } - FOR( ; i < max( 0, ( min( num_ch, hoa2_ch ) - ndm ) ); i++ ) + len = s_max( 0, sub( s_min( num_ch, hoa2_ch ), ndm ) ); + FOR( ; i < len; i++ ) // i < max( 0, ( min( num_ch, hoa2_ch ) - ndm ) ) { idx = sub( remix_order[i + ndm], ndm ); P_dir_fact_fx[idx] = Mpy_32_32( hSpar_md->band_coeffs[start_band - 1].P_re_fx[i], hSpar_md->band_coeffs[start_band - 1].P_re_fx[i] ); // 2*q_P_re - 31 @@ -4050,6 +4059,7 @@ void ivas_get_spar_md_from_dirac_enc_fx( move32(); } } + FOR( ; i < ( num_ch - ndm ); i++ ) { idx = sub( remix_order[i + ndm], ndm ); @@ -4215,7 +4225,8 @@ void ivas_get_spar_md_from_dirac_enc_fx( /*normalize 2nd order*/ norm_fx = 0; move32(); - FOR( ch = foa_ch; ch < min( hoa2_ch_order, num_ch_order ); ch++ ) + Word16 min_ch_order = s_min( hoa2_ch_order, num_ch_order ); + FOR( ch = foa_ch; ch < min_ch_order; ch++ ) { norm_fx = L_add( norm_fx, Mpy_32_32( response_avg_fx[ch], response_avg_fx[ch] ) ); // q29 } @@ -4236,7 +4247,8 @@ void ivas_get_spar_md_from_dirac_enc_fx( move16(); } norm_fx = L_shr( norm_fx, sub( 1, norm_q ) ); // q30 - FOR( ch = foa_ch; ch < min( hoa2_ch_order, num_ch_order ); ch++ ) + min_ch_order = s_min( hoa2_ch_order, num_ch_order ); + FOR( ch = foa_ch; ch < min_ch_order; ch++ ) { IF( LT_32( norm_fx, EPSILON_FX_THR ) ) { @@ -4550,7 +4562,8 @@ void ivas_get_spar_md_from_dirac_fx( move16(); P_norm_fx[0] = 0; move32(); - FOR( i = 0; i < max( 0, sub( foa_ch, ndm ) ); i++ ) + Word16 len = s_max( 0, sub( foa_ch, ndm ) ); + FOR( i = 0; i < len; i++ ) // i < max( 0, sub( foa_ch, ndm ) ) { P_norm_fx[0] = L_add( P_norm_fx[0], Mpy_32_32( hSpar_md->band_coeffs[start_band - 1].P_re_fx[i], hSpar_md->band_coeffs[start_band - 1].P_re_fx[i] ) ); // 2*q_P_re - 31 move32(); @@ -4560,7 +4573,8 @@ void ivas_get_spar_md_from_dirac_fx( P_norm_fx[1] = 0; move32(); - FOR( ; i < max( 0, ( min( num_ch, hoa2_ch ) - ndm ) ); i++ ) + len = s_max( 0, sub( s_min( num_ch, hoa2_ch ), ndm ) ); + FOR( ; i < len; i++ ) // i < max( 0, ( min( num_ch, hoa2_ch ) - ndm ) ) { P_norm_fx[1] = L_add( P_norm_fx[1], Mpy_32_32( hSpar_md->band_coeffs[start_band - 1].P_re_fx[i], hSpar_md->band_coeffs[start_band - 1].P_re_fx[i] ) ); // 2*q_P_re - 31 move32(); @@ -4577,8 +4591,8 @@ void ivas_get_spar_md_from_dirac_fx( } P_norm_fx[2] = Mpy_32_32( L_shl( P_norm_fx[2], 3 ), diff_norm_order3_table[min( diff_norm_order3_fx, max( 0, ( num_ch - ndm ) ) )] ); // 2*q_P_re - 31 move32(); - - FOR( i = 0; i < max( 0, ( foa_ch - ndm ) ); i++ ) + len = s_max( 0, sub( foa_ch, ndm ) ); + FOR( i = 0; i < len; i++ ) // i < max( 0, ( foa_ch - ndm ) ) { idx = sub( remix_order[i + ndm], ndm ); P_dir_fact_fx[idx] = Mpy_32_32( hSpar_md->band_coeffs[start_band - 1].P_re_fx[i], hSpar_md->band_coeffs[start_band - 1].P_re_fx[i] ); // 2*q_P_re - 31 @@ -4591,7 +4605,8 @@ void ivas_get_spar_md_from_dirac_fx( move32(); } } - FOR( ; i < max( 0, ( min( num_ch, hoa2_ch ) - ndm ) ); i++ ) + len = s_max( 0, sub( s_min( num_ch, hoa2_ch ), ndm ) ); + FOR( ; i < len; i++ ) // i < max( 0, ( min( num_ch, hoa2_ch ) - ndm ) ) { idx = sub( remix_order[i + ndm], ndm ); P_dir_fact_fx[idx] = Mpy_32_32( hSpar_md->band_coeffs[start_band - 1].P_re_fx[i], hSpar_md->band_coeffs[start_band - 1].P_re_fx[i] ); // 2*q_P_re - 31 @@ -4768,7 +4783,8 @@ void ivas_get_spar_md_from_dirac_fx( /*normalize 2nd order*/ norm_fx = 0; move32(); - FOR( ch = foa_ch; ch < min( hoa2_ch_order, num_ch_order ); ch++ ) + Word16 min_ch_order = s_min( hoa2_ch_order, num_ch_order ); + FOR( ch = foa_ch; ch < min_ch_order; ch++ ) { norm_fx = L_add( norm_fx, Mpy_32_32( response_avg_fx[ch], response_avg_fx[ch] ) ); // q29 } @@ -4789,7 +4805,8 @@ void ivas_get_spar_md_from_dirac_fx( move16(); } norm_fx = L_shr( norm_fx, sub( 1, norm_q ) ); // q30 - FOR( ch = foa_ch; ch < min( hoa2_ch_order, num_ch_order ); ch++ ) + min_ch_order = s_min( hoa2_ch_order, num_ch_order ); + FOR( ch = foa_ch; ch < min_ch_order; ch++ ) { IF( LT_32( norm_fx, EPSILON_FX_THR ) ) { @@ -7040,7 +7057,7 @@ void ivas_dirac_dec_get_response_fx( Word16 Q_out ) { Word16 index_azimuth, index_elevation; - Word16 el, e, az; + Word16 el, e, az, q_diff; Word32 cos_1_fx, cos_2_fx, sin_1_fx, cos_az_fx[3]; Word32 sin_az_fx[3]; Word32 f_fx; @@ -7051,49 +7068,39 @@ void ivas_dirac_dec_get_response_fx( index_azimuth = add( azimuth, 180 ) % 360; move16(); index_elevation = add( elevation, 90 ); - IF( GT_16( index_elevation, 90 ) ) + + e = 1; + move16(); + + if ( GT_16( index_elevation, 90 ) ) { e = -1; - move16(); - } - ELSE - { - e = 1; - move16(); } - IF( GT_16( index_elevation, 90 ) ) + el = index_elevation; + move16(); + + if ( GT_16( index_elevation, 90 ) ) { el = sub( 180, index_elevation ); - move16(); - } - ELSE - { - el = index_elevation; - move16(); } - IF( GT_16( index_azimuth, 180 ) ) + az = index_azimuth; + move16(); + + if ( GT_16( index_azimuth, 180 ) ) { az = sub( 360, index_azimuth ); - move16(); - } - ELSE - { - az = index_azimuth; - move16(); } - IF( GT_16( index_azimuth, 180 ) ) + f_fx = 1; + move16(); + + if ( GT_16( index_azimuth, 180 ) ) { f_fx = -1; - move16(); - } - ELSE - { - f_fx = 1; - move16(); } + cos_1_fx = L_shr( dirac_gains_trg_term_fx[az][0], 1 ); // q30 cos_2_fx = L_shl( Mpy_32_32( cos_1_fx, cos_1_fx ), 1 ); // q30 sin_1_fx = L_shr( dirac_gains_trg_term_fx[az][1], 1 ); // q30 @@ -7118,54 +7125,54 @@ void ivas_dirac_dec_get_response_fx( response_fx[0] = L_shl_sat( 1, Q_out ); // Q_out move32(); + q_diff = sub( Q_out, 29 ); + FOR( l = 1; l <= ambisonics_order; l++ ) { b_2 = imult1616( l, l ); - b1_2 = add( imult1616( l, l ), shl( l, 1 ) ); + b1_2 = add( b_2, shl( l, 1 ) ); FOR( m = 0; m < l; m += 2 ) { - b = add( b_2, m ); + b = b_2 + m; a = dirac_gains_P_idx[b]; - move16(); + c_fx_better = local_result_table[el][a]; // q30 move32(); - response_fx[b] = L_shl( Mpy_32_32( c_fx_better, sin_az_fx[l - m - 1] ), sub( Q_out, 29 ) ); // Q_out + response_fx[b] = L_shl( Mpy_32_32( c_fx_better, sin_az_fx[l - m - 1] ), q_diff ); // Q_out move32(); - b1 = sub( b1_2, m ); - response_fx[b1] = L_shl( Mpy_32_32( c_fx_better, cos_az_fx[l - m - 1] ), sub( Q_out, 29 ) ); // Q_out + b1 = b1_2 - m; + response_fx[b1] = L_shl( Mpy_32_32( c_fx_better, cos_az_fx[l - m - 1] ), q_diff ); // Q_out move32(); } FOR( m = 1; m < l; m += 2 ) { - b = add( b_2, m ); + b = b_2 + m; a = dirac_gains_P_idx[b]; - move16(); c_fx_better = local_result_table[el][a]; // q30 move32(); if ( EQ_16( e, -1 ) ) { c_fx_better = L_negate( c_fx_better ); // q30 } - response_fx[b] = L_shl( Mpy_32_32( c_fx_better, sin_az_fx[l - m - 1] ), sub( Q_out, 29 ) ); // Q_out + response_fx[b] = L_shl( Mpy_32_32( c_fx_better, sin_az_fx[l - m - 1] ), q_diff ); // Q_out move32(); - b1 = sub( b1_2, m ); - response_fx[b1] = L_shl( Mpy_32_32( c_fx_better, cos_az_fx[l - m - 1] ), sub( Q_out, 29 ) ); // Q_out + + b1 = b1_2 - m; + response_fx[b1] = L_shl( Mpy_32_32( c_fx_better, cos_az_fx[l - m - 1] ), q_diff ); // Q_out move32(); } b = add( b_2, l ); a = dirac_gains_P_idx[b]; - move16(); c_fx_better = local_result_table_2[el][a]; // q30 move32(); - IF( EQ_16( ( l % 2 ), 1 ) ) + IF( EQ_16( s_and( l, 0x01 ), 1 ) ) { if ( EQ_16( e, -1 ) ) { c_fx_better = L_negate( c_fx_better ); // q30 - move32(); } } response_fx[b] = L_shl( c_fx_better, sub( Q_out, 30 ) ); // Q_out diff --git a/lib_com/ivas_spar_com_quant_util.c b/lib_com/ivas_spar_com_quant_util_fx.c similarity index 99% rename from lib_com/ivas_spar_com_quant_util.c rename to lib_com/ivas_spar_com_quant_util_fx.c index 81044fb4025dde086941967a651c15711b6b3540..cfd03a3b3e68d51d66045229266e9f412a564231 100644 --- a/lib_com/ivas_spar_com_quant_util.c +++ b/lib_com/ivas_spar_com_quant_util_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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,7 @@ #include #include "options.h" #include "math.h" -#include "prot.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "ivas_rom_com.h" #include #include "wmc_auto.h" diff --git a/lib_com/ivas_stat_com.h b/lib_com/ivas_stat_com.h index 090db04dbb413f44c2491d822da03799d7a990f9..fb11d3934486f3c09af3e8e5482ec78c90f6bc7a 100644 --- a/lib_com/ivas_stat_com.h +++ b/lib_com/ivas_stat_com.h @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other @@ -46,18 +46,18 @@ typedef struct { - int16_t last_angle1_idx; /* last frame index of coded azimuth/yaw */ - int16_t angle1_diff_cnt; /* FEC counter of consecutive differentially azimuth/yaw coded frames */ - int16_t last_angle2_idx; /* last frame index of coded elevation/pitch */ - int16_t angle2_diff_cnt; /* FEC counter of consecutive differentially elevation/pitch coded frames */ + Word16 last_angle1_idx; /* last frame index of coded azimuth/yaw */ + Word16 angle1_diff_cnt; /* FEC counter of consecutive differentially azimuth/yaw coded frames */ + Word16 last_angle2_idx; /* last frame index of coded elevation/pitch */ + Word16 angle2_diff_cnt; /* FEC counter of consecutive differentially elevation/pitch coded frames */ } ISM_METADATA_ANGLE, *ISM_METADATA_ANGLE_HANDLE; /* ISM metadata handle (storage for one frame of read ISM metadata) */ typedef struct { - int16_t ism_metadata_flag; /* flag whether metadata are coded in particular frame of particular object */ - int16_t last_ism_metadata_flag; /* last frame ism_metadata_flag */ + Word16 ism_metadata_flag; /* flag whether metadata are coded in particular frame of particular object */ + Word16 last_ism_metadata_flag; /* last frame ism_metadata_flag */ Word32 azimuth_fx; /* azimuth value read from the input metadata file */ /* Q22 */ Word32 elevation_fx; /* elevation value read from the input metadata file */ /* Q22 */ @@ -65,25 +65,25 @@ typedef struct Word32 yaw_fx; /* yaw value read from the input metadata file */ /* Q22 */ Word32 pitch_fx; /* pitch value read from the input metadata file */ /* Q22 */ - int16_t non_diegetic_flag; /* Non-diegetic (non-headtracked) object flag */ + Word16 non_diegetic_flag; /* Non-diegetic (non-headtracked) object flag */ ISM_METADATA_ANGLE position_angle; /* Angle structs for azimuth and elevation */ ISM_METADATA_ANGLE orientation_angle; /* Angle structs for yaw and pitch */ - int16_t last_radius_idx; /* last frame index of coded radius */ - int16_t radius_diff_cnt; /* FEC counter of consecutive differentially radius coded frames */ + Word16 last_radius_idx; /* last frame index of coded radius */ + Word16 radius_diff_cnt; /* FEC counter of consecutive differentially radius coded frames */ Word32 last_azimuth_fx; /* MD smoothing in DTX- last Q azimuth value */ /* Q22 */ Word32 last_elevation_fx; /* MD smoothing in DTX - last Q elevation value */ /* Q22 */ Word32 last_true_azimuth_fx; /* MD smoothing in DTX- last true Q azimuth value */ /* Q22 */ Word32 last_true_elevation_fx; /* MD smoothing in DTX- last true Q elevation value */ /* Q22 */ - int16_t ism_md_fec_cnt_enc; /* counter of continuous frames where MD are not transmitted */ - int16_t ism_md_inc_diff_cnt; /* counter of continuous frames where MD are transmitted in inactive segments when MD significantly changes */ - Word16 last_true_radius_fx; /* last true Q radius value */ + Word16 ism_md_fec_cnt_enc; /* counter of continuous frames where MD are not transmitted */ + Word16 ism_md_inc_diff_cnt; /* counter of continuous frames where MD are transmitted in inactive segments when MD significantly changes */ + Word16 last_true_radius_fx; /* last true Q radius value */ - int16_t ism_imp; /* ISM importance flag */ - int16_t ism_md_null_flag; - int16_t ism_md_lowrate_flag; + Word16 ism_imp; /* ISM importance flag */ + Word16 ism_md_null_flag; + Word16 ism_md_lowrate_flag; Word32 q_azimuth_old_fx; Word32 q_elevation_old_fx; @@ -96,15 +96,15 @@ typedef struct typedef struct stereo_dft_config_data_struct { - int16_t dmx_active; - int16_t band_res; - int16_t prm_res; /* Send prm every # DFT frames */ - int16_t res_pred_mode; /* mode : from 0 (off) to 1 (on) */ - int16_t res_cod_mode; /* mode : from 0 (off) to 3 */ - int16_t hybrid_itd_flag; - int16_t ada_wb_res_cod_mode; /* res_cod_mode for adaptive wide band residual coding */ + Word16 dmx_active; + Word16 band_res; + Word16 prm_res; /* Send prm every # DFT frames */ + Word16 res_pred_mode; /* mode : from 0 (off) to 1 (on) */ + Word16 res_cod_mode; /* mode : from 0 (off) to 3 */ + Word16 hybrid_itd_flag; + Word16 ada_wb_res_cod_mode; /* res_cod_mode for adaptive wide band residual coding */ - int16_t force_mono_transmission; + Word16 force_mono_transmission; } STEREO_DFT_CONFIG_DATA, *STEREO_DFT_CONFIG_DATA_HANDLE; @@ -115,20 +115,20 @@ typedef struct stereo_dft_config_data_struct typedef struct { - uint8_t const bandLengthsTCX20[SMDCT_MAX_STEREO_BANDS_TCX20]; /* Length of a band in number of bins. Range is 4..160 */ - const int16_t bdnCnt_TCX20[4]; /* uppermost band for FB,SWB,WB,NB */ - uint8_t const bandLengthsTCX10[SMDCT_MAX_STEREO_BANDS_TCX10]; /* Length of a band in number of bins. Range is 2..80, always divisible by 2 */ - const int16_t bndCnt_TCX10[4]; /* uppermost band for FB,SWB,WB,NB */ + UWord8 const bandLengthsTCX20[SMDCT_MAX_STEREO_BANDS_TCX20]; /* Length of a band in number of bins. Range is 4..160 */ + const Word16 bdnCnt_TCX20[4]; /* uppermost band for FB,SWB,WB,NB */ + UWord8 const bandLengthsTCX10[SMDCT_MAX_STEREO_BANDS_TCX10]; /* Length of a band in number of bins. Range is 2..80, always divisible by 2 */ + const Word16 bndCnt_TCX10[4]; /* uppermost band for FB,SWB,WB,NB */ } MDCTStereoBands_config; /* MDCT stereo frequency band structure */ typedef struct stereo_mdct_dec_band_parameters_struct { - int16_t sfbOffset[MAX_SFB + 1]; /* stereo frequency band start offsets */ - int16_t sfbCnt; /* number of stereo frequency bands */ - int16_t nBandsStereoCore; /* number of stereo frequency bands in the core */ - int16_t sfbIgfStart; /*index for first IGF band*/ + Word16 sfbOffset[MAX_SFB + 1]; /* stereo frequency band start offsets */ + Word16 sfbCnt; /* number of stereo frequency bands */ + Word16 nBandsStereoCore; /* number of stereo frequency bands in the core */ + Word16 sfbIgfStart; /*index for first IGF band*/ } STEREO_MDCT_BAND_PARAMETERS; @@ -139,9 +139,9 @@ typedef struct stereo_mdct_dec_band_parameters_struct typedef struct { - int16_t config_index; - int16_t encoding_active; /* internal state specifying if actual encoding is active or only length evaluation is active */ - int32_t bit_count_estimate; /* uses 22Q10 fixed-point representation */ + Word16 config_index; + Word16 encoding_active; /* internal state specifying if actual encoding is active or only length evaluation is active */ + Word32 bit_count_estimate; /* uses 22Q10 fixed-point representation */ void *ac_handle; } ECSQ_instance; @@ -153,9 +153,9 @@ typedef struct typedef struct ivas_dirac_config_data_struct { - int16_t enc_param_start_band; - int16_t dec_param_estim; - int16_t nbands; + Word16 enc_param_start_band; + Word16 dec_param_estim; + Word16 nbands; } DIRAC_CONFIG_DATA, *DIRAC_CONFIG_DATA_HANDLE; @@ -180,9 +180,9 @@ typedef struct ivas_band_coeffs_t typedef struct ivas_band_coeffs_ind_t { - int16_t pred_index_re[IVAS_SPAR_MAX_CH - 1]; - int16_t drct_index_re[IVAS_SPAR_MAX_C_COEFF]; - int16_t decd_index_re[IVAS_SPAR_MAX_CH - 1]; + Word16 pred_index_re[IVAS_SPAR_MAX_CH - 1]; + Word16 drct_index_re[IVAS_SPAR_MAX_C_COEFF]; + Word16 decd_index_re[IVAS_SPAR_MAX_CH - 1]; } ivas_band_coeffs_ind_t; @@ -192,7 +192,7 @@ typedef struct ivas_spar_md_t ivas_band_coeffs_ind_t band_coeffs_idx[IVAS_MAX_NUM_BANDS]; Word16 num_bands; Word32 min_max_fx[2]; /*q28*/ - int16_t dtx_vad; + Word16 dtx_vad; Word32 en_ratio_slow_fx[IVAS_MAX_NUM_BANDS]; Word32 ref_pow_slow_fx[IVAS_MAX_NUM_BANDS]; Word16 res_ind; @@ -210,7 +210,7 @@ typedef struct ivas_quant_coeffs_t { Word32 min_fx; /* Q28 */ Word32 max_fx; /* Q28 */ - int16_t q_levels[2]; + Word16 q_levels[2]; } ivas_quant_coeffs_t; typedef struct ivas_quant_strat_t @@ -224,23 +224,23 @@ typedef struct ivas_quant_strat_t typedef struct ivas_spar_md_com_cfg { - int16_t max_freq_per_chan[IVAS_SPAR_MAX_CH]; - int16_t num_dmx_chans_per_band[IVAS_MAX_NUM_BANDS]; - int16_t num_decorr_per_band[IVAS_MAX_NUM_BANDS]; - int16_t active_w; - int16_t remix_unmix_order; + Word16 max_freq_per_chan[IVAS_SPAR_MAX_CH]; + Word16 num_dmx_chans_per_band[IVAS_MAX_NUM_BANDS]; + Word16 num_decorr_per_band[IVAS_MAX_NUM_BANDS]; + Word16 active_w; + Word16 remix_unmix_order; ivas_quant_strat_t quant_strat[MAX_QUANT_STRATS]; - int16_t quant_strat_bits; - int16_t nchan_transport; - int16_t num_quant_strats; - int16_t prior_strat; - int16_t tgt_bits_per_blk; - int16_t max_bits_per_blk; - int16_t prev_quant_idx; - int16_t agc_bits_ch_idx; - int16_t planarCP; - int16_t num_umx_chs; - int16_t max_md_bits_spar; + Word16 quant_strat_bits; + Word16 nchan_transport; + Word16 num_quant_strats; + Word16 prior_strat; + Word16 tgt_bits_per_blk; + Word16 max_bits_per_blk; + Word16 prev_quant_idx; + Word16 agc_bits_ch_idx; + Word16 planarCP; + Word16 num_umx_chs; + Word16 max_md_bits_spar; } ivas_spar_md_com_cfg; @@ -248,26 +248,26 @@ typedef struct ivas_spar_md_com_cfg /* arithmetic coder structures */ typedef struct ivas_cell_dim_t { - int16_t dim1; - int16_t dim2; + Word16 dim1; + Word16 dim2; } ivas_cell_dim_t; typedef struct ivas_freq_models_t { - int16_t freq_model[IVAS_NUM_PROB_MODELS][IVAS_MAX_QUANT_LEVELS]; - int16_t diff_freq_model[IVAS_NUM_PROB_MODELS][IVAS_MAX_QUANT_LEVELS]; - int16_t vals[IVAS_MAX_QUANT_LEVELS]; - int16_t diff_vals[IVAS_MAX_QUANT_LEVELS]; - int16_t num_models; - int16_t diff_num_models; + Word16 freq_model[IVAS_NUM_PROB_MODELS][IVAS_MAX_QUANT_LEVELS]; + Word16 diff_freq_model[IVAS_NUM_PROB_MODELS][IVAS_MAX_QUANT_LEVELS]; + Word16 vals[IVAS_MAX_QUANT_LEVELS]; + Word16 diff_vals[IVAS_MAX_QUANT_LEVELS]; + Word16 num_models; + Word16 diff_num_models; } ivas_freq_models_t; typedef struct ivas_huff_models_t { - int16_t code_book[IVAS_MAX_QUANT_LEVELS][3]; - int16_t diff_code_book[IVAS_MAX_QUANT_LEVELS][3]; + Word16 code_book[IVAS_MAX_QUANT_LEVELS][3]; + Word16 diff_code_book[IVAS_MAX_QUANT_LEVELS][3]; } ivas_huff_models_t; @@ -275,22 +275,22 @@ typedef struct ivas_huff_models_t /* Entropy coder structures */ typedef struct ivas_huffman_cfg_t { - const int16_t *codebook; - int16_t min_len; - int16_t max_len; - int16_t sym_len; + const Word16 *codebook; + Word16 min_len; + Word16 max_len; + Word16 sym_len; } ivas_huffman_cfg_t; typedef struct ivas_arith_t { - int16_t dyn_model_bits; - const int16_t *pFreq_model; - const int16_t *pAlt_freq_models[IVAS_NUM_PROB_MODELS]; - const int16_t *vals; - int16_t cum_freq[IVAS_NUM_PROB_MODELS][IVAS_MAX_QUANT_LEVELS]; - int16_t range; - int16_t num_models; + Word16 dyn_model_bits; + const Word16 *pFreq_model; + const Word16 *pAlt_freq_models[IVAS_NUM_PROB_MODELS]; + const Word16 *vals; + Word16 cum_freq[IVAS_NUM_PROB_MODELS][IVAS_MAX_QUANT_LEVELS]; + Word16 range; + Word16 num_models; Word32 saved_dist_arr[IVAS_NUM_PROB_MODELS][IVAS_MAX_QUANT_LEVELS]; /* Q15 */ } ivas_arith_t; @@ -338,18 +338,18 @@ typedef struct ivas_cov_smooth_state_t Word32 *pPrior_cov_real_fx[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH]; Word16 *q_cov_real_per_band[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH]; Word16 *q_prior_cov_real_per_band[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH]; - int16_t prior_bank_idx; + Word16 prior_bank_idx; Word32 *pSmoothing_factor_fx; /* Q31 */ - int16_t num_bins; + Word16 num_bins; } ivas_cov_smooth_state_t; typedef struct ivas_cov_smooth_cfg_t { Word32 max_update_rate_fx; /* Q31 */ - int16_t min_pool_size; - int16_t max_bands; - int16_t num_bins; + Word16 min_pool_size; + Word16 max_bands; + Word16 num_bins; } ivas_cov_smooth_cfg_t; @@ -357,20 +357,20 @@ typedef struct ivas_cov_smooth_cfg_t /* SPAR bitrate constant table structure */ typedef struct ivas_spar_br_table_t { - int32_t ivas_total_brate; - int16_t isPlanar; - int16_t sba_order; - int16_t bwidth; - int16_t fpcs; - int16_t nchan_transport; + Word32 ivas_total_brate; + Word16 isPlanar; + Word16 sba_order; + Word16 bwidth; + Word16 fpcs; + Word16 nchan_transport; ivas_spar_pmx_strings_t dmx_str; - int16_t active_w; - int16_t tmode; - int32_t core_brs[FOA_CHANNELS][3]; - int16_t q_lvls[MAX_QUANT_STRATS][NUM_MD_Q_COEFS_SET]; - int16_t td_ducking; - int16_t agc_bits_ch_idx; /* 0-3, Indicates core-coder channel index from which AGC bits have been taken from*/ - int16_t usePlanarCoeff; + Word16 active_w; + Word16 tmode; + Word32 core_brs[FOA_CHANNELS][3]; + Word16 q_lvls[MAX_QUANT_STRATS][NUM_MD_Q_COEFS_SET]; + Word16 td_ducking; + Word16 agc_bits_ch_idx; /* 0-3, Indicates core-coder channel index from which AGC bits have been taken from*/ + Word16 usePlanarCoeff; } ivas_spar_br_table_t; @@ -419,7 +419,7 @@ typedef struct ivas_masa_common_spatial_meta_struct typedef struct ivas_omasa_meta_struct { - uint8_t num_dirs; + UWord8 num_dirs; MASA_DIRECTIONAL_SPATIAL_META directional_meta[MASA_MAXIMUM_DIRECTIONS]; MASA_COMMON_SPATIAL_META common_meta; @@ -435,16 +435,16 @@ typedef struct ivas_masa_metadata_frame_struct typedef struct ivas_masa_config_struct { - uint16_t max_metadata_bits; - int16_t block_grouping[5]; - int16_t band_grouping[MASA_FREQUENCY_BANDS + 1]; - uint8_t numCodingBands; - uint8_t numTwoDirBands; - uint8_t numberOfDirections; - uint8_t joinedSubframes; - uint8_t useCoherence; - uint8_t coherencePresent; - uint8_t mergeRatiosOverSubframes; + UWord16 max_metadata_bits; + Word16 block_grouping[5]; + Word16 band_grouping[MASA_FREQUENCY_BANDS + 1]; + UWord8 numCodingBands; + UWord8 numTwoDirBands; + UWord8 numberOfDirections; + UWord8 joinedSubframes; + UWord8 useCoherence; + UWord8 coherencePresent; + UWord8 mergeRatiosOverSubframes; IVAS_FORMAT input_ivas_format; } MASA_CODEC_CONFIG; @@ -456,11 +456,11 @@ typedef struct ivas_masa_config_struct typedef struct { - int16_t nbands; - int16_t nblocks; - int16_t start_band; - uint8_t inactiveBands; - int16_t search_effort; + Word16 nbands; + Word16 nblocks; + Word16 start_band; + UWord8 inactiveBands; + Word16 search_effort; MC_LS_SETUP mc_ls_setup; } IVAS_METADATA_CONFIG; @@ -615,10 +615,10 @@ typedef struct ivas_parametric_mc_metadata_struct typedef struct ivas_lfe_window { - int16_t dct_len; - int16_t fade_len; - int16_t zero_pad_len; - int16_t full_len; + Word16 dct_len; + Word16 fade_len; + Word16 zero_pad_len; + Word16 full_len; const Word32 *pWindow_coeffs_fx; @@ -626,14 +626,14 @@ typedef struct ivas_lfe_window typedef struct ivas_lfe_freq_models { - uint16_t entropy_coder_model_fine_sg1[65]; - uint16_t entropy_coder_model_fine_sg2[33]; - uint16_t entropy_coder_model_fine_sg3[9]; - uint16_t entropy_coder_model_fine_sg4[3]; - uint16_t entropy_coder_model_coarse_sg1[33]; - uint16_t entropy_coder_model_coarse_sg2[17]; - uint16_t entropy_coder_model_coarse_sg3[5]; - uint16_t entropy_coder_model_coarse_sg4; + UWord16 entropy_coder_model_fine_sg1[65]; + UWord16 entropy_coder_model_fine_sg2[33]; + UWord16 entropy_coder_model_fine_sg3[9]; + UWord16 entropy_coder_model_fine_sg4[3]; + UWord16 entropy_coder_model_coarse_sg1[33]; + UWord16 entropy_coder_model_coarse_sg2[17]; + UWord16 entropy_coder_model_coarse_sg3[5]; + UWord16 entropy_coder_model_coarse_sg4; } ivas_lfe_freq_models; diff --git a/lib_com/ivas_stereo_dft_com.c b/lib_com/ivas_stereo_dft_com_fx.c similarity index 98% rename from lib_com/ivas_stereo_dft_com.c rename to lib_com/ivas_stereo_dft_com_fx.c index 8b377bdbc73facd67aafe66145d2b5c1c00c1af3..6d63bc6d1565160d0a3a3edb4f84b812077e882e 100644 --- a/lib_com/ivas_stereo_dft_com.c +++ b/lib_com/ivas_stereo_dft_com_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other @@ -35,8 +35,7 @@ #include "options.h" #include "ivas_cnst.h" #include "ivas_rom_com.h" -#include "ivas_prot.h" -#include "prot.h" +#include "prot_fx.h" #include "cnst.h" #include "wmc_auto.h" #include "ivas_prot_fx.h" diff --git a/lib_com/ivas_stereo_eclvq_com_fx.c b/lib_com/ivas_stereo_eclvq_com_fx.c index 30d95afe95fa091b3d98cc883553707bce28c372..958781473910ff0f164ad50b9eb076fd3e0796e3 100644 --- a/lib_com/ivas_stereo_eclvq_com_fx.c +++ b/lib_com/ivas_stereo_eclvq_com_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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,11 +33,10 @@ #include #include "options.h" #include -#include "ivas_prot.h" #include "ivas_prot_fx.h" #include "ivas_cnst.h" #include -#include "prot.h" +#include "prot_fx.h" #include "wmc_auto.h" /*--------------------------------------------------------------- diff --git a/lib_com/ivas_stereo_ica_com_fx.c b/lib_com/ivas_stereo_ica_com_fx.c index 3ebfd99c1e065ba93c7f0a8deeee608c1acb3ce0..8548797a4134d1805618080459a0f8ec38631269 100644 --- a/lib_com/ivas_stereo_ica_com_fx.c +++ b/lib_com/ivas_stereo_ica_com_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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,9 +36,7 @@ #include "options.h" #include "cnst.h" #include "ivas_cnst.h" -#include "prot.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "wmc_auto.h" #include "rom_com.h" #include "ivas_rom_com.h" @@ -131,17 +129,7 @@ static void interpTargetChannel_fx( Word32 spread_factor2_fx; Word64 tempD1_fx, tempD2_fx; - d = negate( sub( currShift, prevShift ) ); - IF( d >= 0 ) - { - signShift = 1; - move16(); - } - ELSE - { - signShift = -1; - move16(); - } + d = sub( prevShift, currShift ); IF( d == 0 ) { @@ -149,6 +137,15 @@ static void interpTargetChannel_fx( return; } + signShift = 1; + move16(); + + if ( d < 0 ) + { + signShift = -1; + move16(); + } + N = L_shift_adapt; move16(); Word32 *table_pointer = NULL; @@ -207,7 +204,7 @@ static void interpTargetChannel_fx( FOR( j = lim1; j <= lim2; j++ ) { - ptr2_fx[i] = L_add( Mpy_32_32( win_fx[j * INTERP_FACTOR1 - i], ptr1_fx[j] ), ptr2_fx[i] ); // qsynth + ptr2_fx[i] = Madd_32_32( ptr2_fx[i], win_fx[j * INTERP_FACTOR1 - i], ptr1_fx[j] ); // qsynth move32(); } } @@ -225,44 +222,31 @@ static void interpTargetChannel_fx( tempD1_fx = W_deposit32_l( table_D1_pointer[abs( d )] ); // Q35 tempD2_fx = W_mult0_32_32( 3, table_D1_pointer[abs( d )] ); // Q35 - IF( EQ_16( signShift, 1 ) ) + tempF1_fx = -ONE_IN_Q12; // Q12 + move32(); + + if ( EQ_16( signShift, 1 ) ) { tempF1_fx = ONE_IN_Q12; // Q12 move32(); } - ELSE - { - tempF1_fx = -ONE_IN_Q12; // Q12 - move32(); - } + tempF1_fx = L_sub( imult3216( factor_fx, d ), tempF1_fx ); // Q12 - FOR( k = 0; k < sub( N, 1 ); k++ ) + FOR( k = 0; k < N - 1; k++ ) { - Word32 local = L_sub( W_extract_l( W_shr( W_mult0_32_32( tempF1_fx, spread_factor2_fx ), 31 ) ), ONE_IN_Q12 ); // Q12 - Word32 sign_local; - IF( local > 0 ) - { - sign_local = 1; - move32(); - } - ELSE - { - sign_local = -1; - move32(); - } - Word32 local_int = W_extract_l( W_shr( W_abs( local ), 12 ) ); // Q0 + Word32 local = Madd_32_32( -ONE_IN_Q12, tempF1_fx, spread_factor2_fx ); // Q12 + Word32 local_int = L_shr( local, 12 ); // Q0 Word32 res_a1, res_a2, res_a3; Word32 res_b1, res_b2, res_b3; Word32 res_c1, res_c2, res_c3; Word32 res_d1, res_d2, res_d3; - Word64 local_int_scaled; + Word32 local_int_scaled; Word64 res_a, res_b, res_c, res_d; Word64 tempa, tempb; Word64 mult_a_D1, mult_b_D2; - local_int = W_extract_l( W_mult0_32_32( sign_local, local_int ) ); // Q0 - local_int_scaled = W_deposit32_l( L_shl( local_int, 12 ) ); // Q12 - lim1 = extract_l( local_int ); // Q0 - IF( W_sub( local_int_scaled, local ) > 0 ) // Q21 + local_int_scaled = L_shl( local_int, 12 ); // Q12 + lim1 = extract_l( local_int ); // Q0 + if ( L_sub( local_int_scaled, local ) > 0 ) // Q12 { lim1 = sub( lim1, 1 ); // Q0 } @@ -387,7 +371,7 @@ static void targetCh_AlignStereoDFT_fx( } FOR( i = 0; i < L_shift_adapt; i++ ) { - target_fx[i] = L_add( Mpy_32_32( alpha_fx, fadeInBuff_fx[i] ), Mpy_32_32( L_sub( ONE_IN_Q31, alpha_fx ), fadeOutBuff_fx[i] ) ); // qsynth + target_fx[i] = Madd_32_32( Mpy_32_32( alpha_fx, fadeInBuff_fx[i] ), L_sub( ONE_IN_Q31, alpha_fx ), fadeOutBuff_fx[i] ); // qsynth move32(); alpha_fx = L_add_sat( alpha_fx, winSlope_fx ); // Q31 diff --git a/lib_com/ivas_stereo_mdct_bands_com.c b/lib_com/ivas_stereo_mdct_bands_com_fx.c similarity index 98% rename from lib_com/ivas_stereo_mdct_bands_com.c rename to lib_com/ivas_stereo_mdct_bands_com_fx.c index 153f477b6ebe97ddce6be91ef867060c7f20a456..43f2f16c7efc13d125717975cc63064027644d3d 100644 --- a/lib_com/ivas_stereo_mdct_bands_com.c +++ b/lib_com/ivas_stereo_mdct_bands_com_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other @@ -35,22 +35,16 @@ #include "options.h" #include "ivas_cnst.h" #include "ivas_rom_com.h" -#include "ivas_prot.h" #include "rom_com.h" -#include "prot.h" -#include "wmc_auto.h" #include "prot_fx.h" +#include "wmc_auto.h" #include "ivas_prot_fx.h" /*-------------------------------------------------------------------* * Local union *-------------------------------------------------------------------*/ -#ifndef BASOP_NOGLOB -typedef union -#else /* BASOP_NOGLOB */ typedef union -#endif /* BASOP_NOGLOB */ { MDCTStereoBands_config const *steBands; SpectrumWarping const *lpcBndsParam; diff --git a/lib_com/ivas_stereo_mdct_stereo_com.c b/lib_com/ivas_stereo_mdct_stereo_com_fx.c similarity index 97% rename from lib_com/ivas_stereo_mdct_stereo_com.c rename to lib_com/ivas_stereo_mdct_stereo_com_fx.c index 45e734fea13b312b70d3083adafb53e990dca369..0a773169d07313155482bed27f0613b1cccb7a40 100644 --- a/lib_com/ivas_stereo_mdct_stereo_com.c +++ b/lib_com/ivas_stereo_mdct_stereo_com_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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,7 +33,6 @@ #include #include "options.h" #include "ivas_cnst.h" -#include "ivas_prot.h" #include "wmc_auto.h" #include #include "prot_fx.h" diff --git a/lib_com/ivas_stereo_psychlpc_com.c b/lib_com/ivas_stereo_psychlpc_com_fx.c similarity index 98% rename from lib_com/ivas_stereo_psychlpc_com.c rename to lib_com/ivas_stereo_psychlpc_com_fx.c index e34e8fd18884f0c2aff9175befd9f467510955d5..df514089560c440dde31ff103bf87fd0b1ff740f 100644 --- a/lib_com/ivas_stereo_psychlpc_com.c +++ b/lib_com/ivas_stereo_psychlpc_com_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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,7 @@ #include #include "options.h" #include "ivas_rom_com.h" -#include "ivas_prot.h" -#include "prot.h" -#include "ivas_prot.h" +#include "prot_fx.h" #include "wmc_auto.h" #include diff --git a/lib_com/ivas_stereo_td_bit_alloc.c b/lib_com/ivas_stereo_td_bit_alloc_fx.c similarity index 99% rename from lib_com/ivas_stereo_td_bit_alloc.c rename to lib_com/ivas_stereo_td_bit_alloc_fx.c index 0f5eb402e0c5db0f6eff2d506e7c934bfa908201..b54c1d3deb5ae86bf589fe0fd34d0e9359885734 100644 --- a/lib_com/ivas_stereo_td_bit_alloc.c +++ b/lib_com/ivas_stereo_td_bit_alloc_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other @@ -35,12 +35,10 @@ #include "cnst.h" #include "stat_enc.h" #include "rom_com.h" -#include "ivas_prot.h" #include "ivas_rom_com.h" #include "ivas_cnst.h" -#include "prot.h" -#include "wmc_auto.h" #include "prot_fx.h" +#include "wmc_auto.h" #include "ivas_prot_fx.h" #include "ivas_rom_com_fx.h" diff --git a/lib_com/ivas_tools.c b/lib_com/ivas_tools_fx.c similarity index 83% rename from lib_com/ivas_tools.c rename to lib_com/ivas_tools_fx.c index 5738b6feb7715c9474c06907d2ae9b6e3e46186a..04d6f7bf50be3f68f9684774ee1d4c7da7412cdf 100644 --- a/lib_com/ivas_tools.c +++ b/lib_com/ivas_tools_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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,11 +34,9 @@ #include #include "options.h" #include -#include "prot.h" -#include "ivas_prot.h" +#include "prot_fx.h" #include "wmc_auto.h" #include "ivas_rom_com.h" -#include "prot_fx.h" #include "ivas_prot_fx.h" #define ANGLE_90_DEG_Q22 377487360 @@ -606,6 +604,7 @@ void v_sub32_fx( * Therefore, S=A*A' where A is upper triangular matrix of size (m*m+m)/2 (zeros ommitted, column-wise) *---------------------------------------------------------------------*/ +#ifndef DOT_PROD_CHOLESKY_64BIT /*! r: the dot product x'*A*A'*x */ Word32 dot_product_cholesky_fixed( const Word32 *x, /* i : vector x Q31 - exp_x*/ @@ -642,6 +641,44 @@ Word32 dot_product_cholesky_fixed( return suma; } +#else +/*! r: the dot product x'*A*A'*x */ +Word64 dot_product_cholesky_fixed( + const Word32 *x, /* i : vector x Q31 - exp_x*/ + const Word32 *A, /* i : Cholesky matrix A Q31 - exp_A*/ + const Word16 N /* i : vector & matrix size Q0*/ +) +{ + Word16 i, j; + Word64 suma, tmp_sum; + Word32 mul; + Word32 tmp; + const Word32 *pt_x, *pt_A; + pt_A = A; + suma = 0; + move64(); + + FOR( i = 0; i < N; i++ ) + { + tmp_sum = 0; + move32(); + pt_x = x; + + FOR( j = 0; j <= i; j++ ) + { + mul = Mpy_32_32( *pt_x++, *pt_A++ ); + tmp_sum = W_add( tmp_sum, W_deposit32_l( mul ) ); + } + + tmp_sum = W_shr( tmp_sum, 4 ); // to make sure that the tmp_sum will not overflow + tmp = W_extract_l( tmp_sum ); + suma = W_mac_32_32( suma, tmp, tmp ); + } + + return suma; +} +#endif + void v_mult_mat_fixed( Word32 *y, /* o : the product x*A Qx - guardbits*/ const Word32 *x, /* i : vector x Qx*/ @@ -834,21 +871,18 @@ Word32 logsumexp_fx( *---------------------------------------------------------------------*/ /*! r: mapped output value */ Word32 lin_interp32_fx( - const Word32 x, /* i : the value to be mapped Qin*/ - const Word32 x1, /* i : source range interval: low end Qin*/ - const Word32 y1, /* i : source range interval: high end Qin*/ - const Word32 x2, /* i : target range interval: low Qin*/ - const Word32 y2, /* i : target range interval: high Qin*/ - const Word16 flag_sat, /* i : flag to indicate whether to apply saturation Q0*/ - Word16 *Q_io /*i/o : i/o Q factor of the output*/ + const Word32 x, /* i : the value to be mapped Qx */ + const Word32 x1, /* i : source range interval: low end Qx */ + const Word32 y1, /* i : source range interval: high end Q31 */ + const Word32 x2, /* i : target range interval: low Qx */ + const Word32 y2, /* i : target range interval: high Q31 */ + const Word16 flag_sat /* i : flag to indicate whether to apply saturation */ ) { Word32 temp32; Word32 temp_div; - Word16 temp_e = 0; - Word16 exp_out = 0; - move16(); - move16(); + Word16 exp_out; + IF( L_sub( x2, x1 ) == 0 ) { return y1; @@ -865,12 +899,12 @@ Word32 lin_interp32_fx( } } - temp32 = Mpy_32_32( L_sub( x, x1 ), L_sub( y2, y1 ) ); // Qin*2 -31 - temp_div = L_deposit_h( BASOP_Util_Divide3232_Scale( temp32, L_sub( x2, x1 ), &temp_e ) ); // 31-temp_e + 2*Qin -31 - Qin = Qin-temp_e - temp32 = BASOP_Util_Add_Mant32Exp( y1, sub( 31, *Q_io ), temp_div, sub( 31, sub( *Q_io, temp_e ) ), &exp_out ); // Qin-temp_e - *Q_io = sub( 31, exp_out ); - move16(); - return temp32; /*Q_io*/ + temp32 = Mpy_32_32( L_sub( x, x1 ), L_sub( y2, y1 ) ); /* Qx */ + temp_div = L_deposit_h( BASOP_Util_Divide3232_Scale( temp32, L_sub( x2, x1 ), &exp_out ) ); + temp32 = BASOP_Util_Add_Mant32Exp( y1, 0, temp_div, exp_out, &exp_out ); + temp32 = L_shl_sat( temp32, exp_out ); /* Q31 */ + + return temp32; } /*-------------------------------------------------------------------* @@ -944,7 +978,15 @@ Word16 matrix_product_mant_exp_fx( Word16 out_e[MAX_OUTPUT_CHANNELS * MAX_OUTPUT_CHANNELS]; Word16 *Zp_fx_e = out_e; Word16 row, col; +#ifndef OPT_BASOP_ADD_v1 Word16 x_idx, y_idx; +#endif /* OPT_BASOP_ADD_v1 */ + Word64 temp; + Word16 temp_e; + Word16 prod_e = add( X_fx_e, Y_fx_e ); + + Word16 max_exp = -31; + move16(); /* Processing */ test(); @@ -960,17 +1002,32 @@ Word16 matrix_product_mant_exp_fx( { FOR( i = 0; i < colsX; ++i ) { - ( *Zp_fx ) = 0; - move32(); - ( *Zp_fx_e ) = 0; - move16(); + temp = 0; + move64(); + FOR( k = 0; k < rowsX; ++k ) { - x_idx = add( k, imult1616( i, rowsX ) ); - y_idx = add( k, imult1616( j, rowsY ) ); - ( *Zp_fx ) = BASOP_Util_Add_Mant32Exp( *Zp_fx, *Zp_fx_e, Mpy_32_32( X_fx[x_idx], Y_fx[y_idx] ), add( X_fx_e, Y_fx_e ), Zp_fx_e ); /*Q31 - Zp_fx_e*/ - move32(); +#ifdef OPT_BASOP_ADD_v1 + temp = W_mac_32_32( temp, X_fx[k + i * rowsX], Y_fx[k + j * rowsY] ); // X_fx_e + Y_fx_e +#else /* OPT_BASOP_ADD_v1 */ + x_idx = k + i * rowsX; + y_idx = k + j * rowsY; + temp = W_mac_32_32( temp, X_fx[x_idx], Y_fx[y_idx] ); // X_fx_e + Y_fx_e +#endif /* OPT_BASOP_ADD_v1 */ } + /* Maximize accumulated value to 32-bit */ + temp_e = W_norm( temp ); + temp = W_shl( temp, temp_e ); + if ( 0 == temp ) + { + temp_e = prod_e; + move16(); + } + *Zp_fx_e = sub( prod_e, temp_e ); + move16(); + ( *Zp_fx ) = W_extract_h( temp ); + move32(); + max_exp = s_max( max_exp, *Zp_fx_e ); // Find the max exp Zp_fx++; Zp_fx_e++; } @@ -990,17 +1047,31 @@ Word16 matrix_product_mant_exp_fx( { FOR( i = 0; i < rowsX; ++i ) { - ( *Zp_fx ) = 0; - move32(); - ( *Zp_fx_e ) = 0; - move16(); + temp = 0; + move64(); FOR( k = 0; k < colsX; ++k ) { - x_idx = add( i, imult1616( k, rowsX ) ); - y_idx = add( j, imult1616( k, rowsY ) ); - ( *Zp_fx ) = BASOP_Util_Add_Mant32Exp( *Zp_fx, *Zp_fx_e, Mpy_32_32( X_fx[x_idx], Y_fx[y_idx] ), add( X_fx_e, Y_fx_e ), Zp_fx_e ); /*Q31 - Zp_fx_e*/ - move32(); +#ifdef OPT_BASOP_ADD_v1 + temp = W_mac_32_32( temp, X_fx[i + k * rowsX], Y_fx[j + k * rowsY] ); // X_fx_e + Y_fx_e +#else /* OPT_BASOP_ADD_v1 */ + x_idx = i + k * rowsX; + y_idx = j + k * rowsY; + temp = W_mac_32_32( temp, X_fx[x_idx], Y_fx[y_idx] ); // X_fx_e + Y_fx_e +#endif /* OPT_BASOP_ADD_v1 */ + } + /* Maximize accumulated value to 32-bit */ + temp_e = W_norm( temp ); + temp = W_shl( temp, temp_e ); + if ( 0 == temp ) + { + temp_e = prod_e; + move16(); } + *Zp_fx_e = sub( prod_e, temp_e ); + move16(); + ( *Zp_fx ) = W_extract_h( temp ); + move32(); + max_exp = s_max( max_exp, *Zp_fx_e ); // Find the max exp Zp_fx++; Zp_fx_e++; } @@ -1020,18 +1091,31 @@ Word16 matrix_product_mant_exp_fx( { FOR( i = 0; i < colsX; ++i ) { - ( *Zp_fx ) = 0; - move32(); - ( *Zp_fx_e ) = 0; - move16(); + temp = 0; + move64(); FOR( k = 0; k < colsX; ++k ) { - x_idx = add( k, imult1616( i, rowsX ) ); - y_idx = add( j, imult1616( k, rowsY ) ); - ( *Zp_fx ) = BASOP_Util_Add_Mant32Exp( *Zp_fx, *Zp_fx_e, Mpy_32_32( X_fx[x_idx], Y_fx[y_idx] ), add( X_fx_e, Y_fx_e ), Zp_fx_e ); /*Q31 - Zp_fx_e*/ - move32(); +#ifdef OPT_BASOP_ADD_v1 + temp = W_mac_32_32( temp, X_fx[k + i * rowsX], Y_fx[j + k * rowsY] ); // X_fx_e + Y_fx_e +#else /* OPT_BASOP_ADD_v1 */ + x_idx = k + i * rowsX; + y_idx = j + k * rowsY; + temp = W_mac_32_32( temp, X_fx[x_idx], Y_fx[y_idx] ); // X_fx_e + Y_fx_e +#endif /* OPT_BASOP_ADD_v1 */ } - + /* Maximize accumulated value to 32-bit */ + temp_e = W_norm( temp ); + temp = W_shl( temp, temp_e ); + if ( 0 == temp ) + { + temp_e = prod_e; + move16(); + } + *Zp_fx_e = sub( prod_e, temp_e ); + move16(); + ( *Zp_fx ) = W_extract_h( temp ); + move32(); + max_exp = s_max( max_exp, *Zp_fx_e ); // Find the max exp Zp_fx++; Zp_fx_e++; } @@ -1052,17 +1136,30 @@ Word16 matrix_product_mant_exp_fx( { FOR( i = 0; i < rowsX; ++i ) { - ( *Zp_fx ) = 0; - move32(); - ( *Zp_fx_e ) = 0; - move16(); + temp = 0; + move64(); FOR( k = 0; k < colsX; ++k ) { - x_idx = add( i, imult1616( k, rowsX ) ); - y_idx = add( k, imult1616( j, rowsY ) ); - ( *Zp_fx ) = BASOP_Util_Add_Mant32Exp( *Zp_fx, *Zp_fx_e, Mpy_32_32( X_fx[x_idx], Y_fx[y_idx] ), add( X_fx_e, Y_fx_e ), Zp_fx_e ); /*Q31 - Zp_fx_e*/ - move32(); +#ifdef OPT_BASOP_ADD_v1 + temp = W_mac_32_32( temp, X_fx[i + k * rowsX], Y_fx[k + j * rowsY] ); // X_fx_e + Y_fx_e +#else /* OPT_BASOP_ADD_v1 */ + x_idx = i + k * rowsX; + y_idx = k + j * rowsY; + temp = W_mac_32_32( temp, X_fx[x_idx], Y_fx[y_idx] ); // X_fx_e + Y_fx_e +#endif /* OPT_BASOP_ADD_v1 */ + } + /* Maximize accumulated value to 32-bit */ + temp_e = W_norm( temp ); + temp = W_shl( temp, temp_e ); + if ( 0 == temp ) + { + temp_e = prod_e; } + *Zp_fx_e = sub( prod_e, temp_e ); + move16(); + ( *Zp_fx ) = W_extract_h( temp ); + move32(); + max_exp = s_max( max_exp, *Zp_fx_e ); // Find the max exp Zp_fx++; Zp_fx_e++; } @@ -1073,18 +1170,11 @@ Word16 matrix_product_mant_exp_fx( move16(); } Zp_fx = Z_fx; /*Q31 - Zp_fx_e*/ + Zp_fx_e = out_e; - Word16 max_exp = -31; move16(); - FOR( j = 0; j < row; ++j ) - { - FOR( i = 0; i < col; ++i ) - { - max_exp = s_max( max_exp, *Zp_fx_e ); - Zp_fx_e++; - } - } - Zp_fx_e = out_e; + + *Z_fx_e = max_exp; move16(); FOR( j = 0; j < row; ++j ) @@ -1114,7 +1204,9 @@ Word16 matrix_product_fx( ) { Word16 i, j, k; +#ifndef OPT_BASOP_ADD_v1 Word16 x_idx, y_idx; +#endif /* OPT_BASOP_ADD_v1 */ Word32 *Zp_fx = Z_fx; /* Processing */ @@ -1135,9 +1227,13 @@ Word16 matrix_product_fx( move32(); FOR( k = 0; k < rowsX; ++k ) { - x_idx = add( k, imult1616( i, rowsX ) ); /*Q0*/ - y_idx = add( k, imult1616( j, rowsY ) ); /*Q0*/ - ( *Zp_fx ) = L_add( *Zp_fx, Mpy_32_32( X_fx[x_idx], Y_fx[y_idx] ) ); /*Qx + Qy - 31*/ +#ifdef OPT_BASOP_ADD_v1 + ( *Zp_fx ) = Madd_32_32( *Zp_fx, X_fx[k + i * rowsX], Y_fx[k + j * rowsY] ); /*Qx + Qy - 31*/ +#else /* OPT_BASOP_ADD_v1 */ + x_idx = add( k, imult1616( i, rowsX ) ); /*Q0*/ + y_idx = add( k, imult1616( j, rowsY ) ); /*Q0*/ + ( *Zp_fx ) = L_add( *Zp_fx, Mpy_32_32( X_fx[x_idx], Y_fx[y_idx] ) ); /*Qx + Qy - 31*/ +#endif /* OPT_BASOP_ADD_v1 */ move32(); } Zp_fx++; @@ -1158,9 +1254,13 @@ Word16 matrix_product_fx( move32(); FOR( k = 0; k < colsX; ++k ) { - x_idx = add( i, imult1616( k, rowsX ) ); /*Q0*/ - y_idx = add( j, imult1616( k, rowsY ) ); /*Q0*/ - ( *Zp_fx ) = L_add( *Zp_fx, Mpy_32_32( X_fx[x_idx], Y_fx[y_idx] ) ); /*Qx + Qy - 31*/ +#ifdef OPT_BASOP_ADD_v1 + ( *Zp_fx ) = Madd_32_32( *Zp_fx, X_fx[i + k * rowsX], Y_fx[j + k * rowsY] ); /*Qx + Qy - 31*/ +#else /* OPT_BASOP_ADD_v1 */ + x_idx = add( i, imult1616( k, rowsX ) ); /*Q0*/ + y_idx = add( j, imult1616( k, rowsY ) ); /*Q0*/ + ( *Zp_fx ) = L_add( *Zp_fx, Mpy_32_32( X_fx[x_idx], Y_fx[y_idx] ) ); /*Qx + Qy - 31*/ +#endif /* OPT_BASOP_ADD_v1 */ move32(); } Zp_fx++; @@ -1181,9 +1281,13 @@ Word16 matrix_product_fx( move32(); FOR( k = 0; k < colsX; ++k ) { - x_idx = add( k, imult1616( i, rowsX ) ); /*Q0*/ - y_idx = add( j, imult1616( k, rowsY ) ); /*Q0*/ - ( *Zp_fx ) = L_add( *Zp_fx, Mpy_32_32( X_fx[x_idx], Y_fx[y_idx] ) ); /*Qx + Qy - 31*/ +#ifdef OPT_BASOP_ADD_v1 + ( *Zp_fx ) = Madd_32_32( *Zp_fx, X_fx[k + i * rowsX], Y_fx[j + k * rowsY] ); /*Qx + Qy - 31*/ +#else /* OPT_BASOP_ADD_v1 */ + x_idx = add( k, imult1616( i, rowsX ) ); /*Q0*/ + y_idx = add( j, imult1616( k, rowsY ) ); /*Q0*/ + ( *Zp_fx ) = L_add( *Zp_fx, Mpy_32_32( X_fx[x_idx], Y_fx[y_idx] ) ); /*Qx + Qy - 31*/ +#endif /* OPT_BASOP_ADD_v1 */ move32(); } @@ -1206,9 +1310,13 @@ Word16 matrix_product_fx( move32(); FOR( k = 0; k < colsX; ++k ) { +#ifdef OPT_BASOP_ADD_v1 + ( *Zp_fx ) = L_add_sat( *Zp_fx, Mpy_32_32( X_fx[i + k * rowsX], Y_fx[k + j * rowsY] ) ); /*Qx + Qy - 31*/ +#else /* OPT_BASOP_ADD_v1 */ x_idx = add( i, imult1616( k, rowsX ) ); /*Q0*/ y_idx = add( k, imult1616( j, rowsY ) ); /*Q0*/ ( *Zp_fx ) = L_add_sat( *Zp_fx, Mpy_32_32( X_fx[x_idx], Y_fx[y_idx] ) ); /*Qx + Qy - 31*/ +#endif /* OPT_BASOP_ADD_v1 */ // TODO: overflow of Z_fx to be checked move32(); } @@ -1233,7 +1341,9 @@ Word16 matrix_product_q30_fx( ) { Word16 i, j, k; +#ifndef OPT_BASOP_ADD_v1 Word16 x_idx, y_idx; +#endif /* OPT_BASOP_ADD_v1 */ Word32 *Zp_fx = Z_fx; Word64 W_tmp; @@ -1256,10 +1366,14 @@ Word16 matrix_product_q30_fx( move64(); FOR( k = 0; k < rowsX; ++k ) { +#ifdef OPT_BASOP_ADD_v1 + W_tmp = W_add( W_tmp, W_mult0_32_32( X_fx[k + i * rowsX], Y_fx[k + j * rowsY] ) ); // Q56 +#else /* OPT_BASOP_ADD_v1 */ //( *Zp_fx ) = L_add( *Zp_fx, Mpy_32_32( X_fx[k + i * rowsX], Y_fx[k + j * rowsY] ) ); x_idx = add( k, imult1616( i, rowsX ) ); /*Q0*/ y_idx = add( k, imult1616( j, rowsY ) ); /*Q0*/ W_tmp = W_add( W_tmp, W_mult0_32_32( X_fx[x_idx], Y_fx[y_idx] ) ); // Q56 +#endif /* OPT_BASOP_ADD_v1 */ } W_tmp = W_shl( W_tmp, 6 ); /*Q62*/ ( *Zp_fx ) = W_round64_L( W_tmp ); /*Q30*/ @@ -1283,10 +1397,14 @@ Word16 matrix_product_q30_fx( move64(); FOR( k = 0; k < colsX; ++k ) { +#ifdef OPT_BASOP_ADD_v1 + W_tmp = W_add( W_tmp, W_mult0_32_32( X_fx[i + k * rowsX], Y_fx[j + k * rowsY] ) ); // Q56 +#else /* OPT_BASOP_ADD_v1 */ //( *Zp_fx ) = L_add( *Zp_fx, Mpy_32_32( X_fx[i + k * rowsX], Y_fx[j + k * rowsY] ) ); x_idx = add( i, imult1616( k, rowsX ) ); /*Q0*/ y_idx = add( j, imult1616( k, rowsY ) ); /*Q0*/ W_tmp = W_add( W_tmp, W_mult0_32_32( X_fx[x_idx], Y_fx[y_idx] ) ); // Q56 +#endif /* OPT_BASOP_ADD_v1 */ } W_tmp = W_shl( W_tmp, 6 ); /*Q62*/ ( *Zp_fx ) = W_round64_L( W_tmp ); /*Q30*/ @@ -1310,9 +1428,11 @@ Word16 matrix_product_q30_fx( move64(); FOR( k = 0; k < colsX; ++k ) { +#ifndef OPT_BASOP_ADD_v1 //( *Zp_fx ) = L_add( *Zp_fx, Mpy_32_32( X_fx[k + i * rowsX], Y_fx[j + k * rowsY] ) ); x_idx = add( k, imult1616( i, rowsX ) ); /*Q0*/ y_idx = add( j, imult1616( k, rowsY ) ); /*Q0*/ +#endif /* OPT_BASOP_ADD_v1 */ W_tmp = W_add( W_tmp, W_mult0_32_32( X_fx[k + i * rowsX], Y_fx[j + k * rowsY] ) ); // Q56 } @@ -1339,10 +1459,14 @@ Word16 matrix_product_q30_fx( move64(); FOR( k = 0; k < colsX; ++k ) { +#ifdef OPT_BASOP_ADD_v1 + W_tmp = W_add( W_tmp, W_mult0_32_32( X_fx[i + k * rowsX], Y_fx[k + j * rowsY] ) ); // Q56 +#else /* OPT_BASOP_ADD_v1 */ //( *Zp_fx ) = L_add( *Zp_fx, Mpy_32_32( X_fx[i + k * rowsX], Y_fx[k + j * rowsY] ) ); x_idx = add( i, imult1616( k, rowsX ) ); /*Q0*/ y_idx = add( k, imult1616( j, rowsY ) ); /*Q0*/ W_tmp = W_add( W_tmp, W_mult0_32_32( X_fx[x_idx], Y_fx[y_idx] ) ); // Q56 +#endif /* OPT_BASOP_ADD_v1 */ } W_tmp = W_shl( W_tmp, 6 ); /*Q62*/ ( *Zp_fx ) = W_round64_L( W_tmp ); /*Q30*/ @@ -1375,7 +1499,9 @@ Word16 matrix_product_mant_exp( Word16 *Zp_e = Z_e; Word32 L_tmp; Word16 tmp_e; +#ifndef OPT_BASOP_ADD_v1 Word16 x_idx, y_idx; +#endif /* OPT_BASOP_ADD_v1 */ /* Processing */ test(); @@ -1397,11 +1523,16 @@ Word16 matrix_product_mant_exp( move16(); FOR( k = 0; k < rowsX; ++k ) { - x_idx = add( k, imult1616( i, rowsX ) ); /*Q0*/ - y_idx = add( k, imult1616( j, rowsY ) ); /*Q0*/ +#ifdef OPT_BASOP_ADD_v1 + L_tmp = Mpy_32_32( X_fx[k + i * rowsX], Y_fx[k + j * rowsY] ); /*Q31 - (X_e + Y_e)*/ + tmp_e = add( X_e[k + i * rowsX], Y_e[k + j * rowsY] ); +#else /* OPT_BASOP_ADD_v1 */ + x_idx = add( k, imult1616( i, rowsX ) ); /*Q0*/ + y_idx = add( k, imult1616( j, rowsY ) ); /*Q0*/ //( *Zp ) += X[k + i * rowsX] * Y[k + j * rowsY]; L_tmp = Mpy_32_32( X_fx[x_idx], Y_fx[y_idx] ); /*Q31 - (X_e + Y_e)*/ tmp_e = add( X_e[x_idx], Y_e[y_idx] ); +#endif /* OPT_BASOP_ADD_v1 */ ( *Zp ) = BASOP_Util_Add_Mant32Exp( *Zp, *Zp_e, L_tmp, tmp_e, &tmp_e ); move32(); @@ -1429,11 +1560,16 @@ Word16 matrix_product_mant_exp( move16(); FOR( k = 0; k < colsX; ++k ) { +#ifdef OPT_BASOP_ADD_v1 + L_tmp = Mpy_32_32( X_fx[i + k * rowsX], Y_fx[j + k * rowsY] ); /*Q31 - (X_e + Y_e)*/ + tmp_e = add( X_e[i + k * rowsX], Y_e[j + k * rowsY] ); +#else /* OPT_BASOP_ADD_v1 */ x_idx = add( i, imult1616( k, rowsX ) ); /*Q0*/ y_idx = add( j, imult1616( k, rowsY ) ); /*Q0*/ //( *Zp ) += X_fx[i + k * rowsX] * Y_fx[j + k * rowsY]; L_tmp = Mpy_32_32( X_fx[x_idx], Y_fx[y_idx] ); /*Q31 - (X_e + Y_e)*/ tmp_e = add( X_e[x_idx], Y_e[y_idx] ); +#endif /* OPT_BASOP_ADD_v1 */ ( *Zp ) = BASOP_Util_Add_Mant32Exp( *Zp, *Zp_e, L_tmp, tmp_e, &tmp_e ); ( *Zp_e ) = tmp_e; @@ -1460,11 +1596,16 @@ Word16 matrix_product_mant_exp( move16(); FOR( k = 0; k < colsX; ++k ) { +#ifdef OPT_BASOP_ADD_v1 + L_tmp = Mpy_32_32( X_fx[k + i * rowsX], Y_fx[j + k * rowsY] ); /*Q31 - (X_e + Y_e)*/ + tmp_e = add( X_e[k + i * rowsX], Y_e[j + k * rowsY] ); +#else /* OPT_BASOP_ADD_v1 */ x_idx = add( k, imult1616( i, rowsX ) ); /*Q0*/ y_idx = add( j, imult1616( k, rowsY ) ); /*Q0*/ //( *Zp ) += X_fx[k + i * rowsX] * Y_fx[j + k * rowsY]; L_tmp = Mpy_32_32( X_fx[x_idx], Y_fx[y_idx] ); /*Q31 - (X_e + Y_e)*/ tmp_e = add( X_e[x_idx], Y_e[y_idx] ); +#endif /* OPT_BASOP_ADD_v1 */ ( *Zp ) = BASOP_Util_Add_Mant32Exp( *Zp, *Zp_e, L_tmp, tmp_e, &tmp_e ); move32(); @@ -1494,11 +1635,16 @@ Word16 matrix_product_mant_exp( move16(); FOR( k = 0; k < colsX; ++k ) { +#ifdef OPT_BASOP_ADD_v1 + L_tmp = Mpy_32_32( X_fx[i + k * rowsX], Y_fx[k + j * rowsY] ); /*Q31 - (X_e + Y_e)*/ + tmp_e = add( X_e[i + k * rowsX], Y_e[k + j * rowsY] ); +#else /* OPT_BASOP_ADD_v1 */ x_idx = add( i, imult1616( k, rowsX ) ); /*Q0*/ y_idx = add( k, imult1616( j, rowsY ) ); /*Q0*/ //( *Zp ) += X_fx[i + k * rowsX] * Y_fx[k + j * rowsY]; L_tmp = Mpy_32_32( X_fx[x_idx], Y_fx[y_idx] ); /*Q31 - (X_e + Y_e)*/ tmp_e = add( X_e[x_idx], Y_e[y_idx] ); +#endif /* OPT_BASOP_ADD_v1 */ ( *Zp ) = BASOP_Util_Add_Mant32Exp( *Zp, *Zp_e, L_tmp, tmp_e, &tmp_e ); move32(); @@ -1529,7 +1675,9 @@ Word16 matrix_diag_product_fx( { Word16 i, j; Word32 *Zp = Z; +#ifndef OPT_BASOP_ADD_v1 Word16 tmp; +#endif /* OPT_BASOP_ADD_v1 */ /* Processing */ IF( EQ_16( transpX, 1 ) ) /* We use X transpose */ @@ -1542,8 +1690,12 @@ Word16 matrix_diag_product_fx( { FOR( i = 0; i < colsX; ++i ) { +#ifdef OPT_BASOP_ADD_v1 + *( Zp ) = Mpy_32_32( X[j + i * rowsX], Y[j] ); /*Q31 - (X_e + Y_e)*/ +#else /* OPT_BASOP_ADD_v1 */ tmp = add( j, imult1616( i, rowsX ) ); - *( Zp ) = Mpy_32_32( X[tmp], Y[j] ); /*Q31 - (X_e + Y_e)*/ + *( Zp ) = Mpy_32_32( X[tmp], Y[j] ); /*Q31 - (X_e + Y_e)*/ +#endif /* OPT_BASOP_ADD_v1 */ move32(); Zp++; } @@ -1574,6 +1726,100 @@ Word16 matrix_diag_product_fx( return EXIT_SUCCESS; } +#ifdef OPT_BASOP_ADD_v1 +Word16 matrix_diag_product_fx_2( + const Word32 *X, /* i : left hand matrix Q31 - X_e*/ + const Word16 X_e, + const Word16 rowsX, /* i : number of rows of the left hand matrix Q0*/ + const Word16 colsX, /* i : number of columns of the left hand matrix Q0*/ + const Word16 transpX, /* i : flag indicating the transposition of the left hand matrix prior to the multiplication Q0*/ + const Word32 *Y, /* i : right hand diagonal matrix as vector containing the diagonal elements Q31 - Y_e*/ + const Word16 *Y_e, + const Word16 entriesY, /* i : number of entries in the diagonal Q0*/ + Word32 *Z, /* o : resulting matrix after the matrix multiplication Q31 - Z_e*/ + Word16 *Z_e ) +{ + Word16 i, j; + Word32 *Zp = Z; + Word16 *Z_ep = Z_e; + Word16 tmp; + Word16 max_exp = -31; + move16(); + + /* Processing */ + IF( EQ_16( transpX, 1 ) ) /* We use X transpose */ + { + IF( NE_16( rowsX, entriesY ) ) + { + return EXIT_FAILURE; + } + FOR( j = 0; j < entriesY; ++j ) + { + FOR( i = 0; i < colsX; ++i ) + { + tmp = j + i * rowsX; /*Q0*/ + *( Zp ) = Mpy_32_32( X[tmp], Y[j] ); /*Q31 - (X_e + Y_e)*/ + move32(); + Zp++; + *( Z_ep ) = add( X_e, Y_e[j] ); + move16(); + max_exp = s_max( max_exp, *Z_ep ); // Find the max exp + Z_ep++; + } + } + + Zp = Z; + Z_ep = Z_e; + FOR( j = 0; j < entriesY; ++j ) + { + FOR( i = 0; i < colsX; ++i ) + { + *Zp = L_shr( *Zp, sub( max_exp, *Z_ep ) ); + *Z_ep = max_exp; + Zp++; + Z_ep++; + } + } + } + ELSE /* Regular case */ + { + IF( NE_16( colsX, entriesY ) ) + { + return EXIT_FAILURE; + } + + FOR( j = 0; j < entriesY; ++j ) + { + FOR( i = 0; i < rowsX; ++i ) + { + *( Zp ) = Mpy_32_32( *( X ), Y[j] ); /*Q31 - (X_e + Y_e)*/ + move32(); + Zp++; + *( Z_ep ) = add( X_e, Y_e[j] ); + move16(); + max_exp = s_max( max_exp, *Z_ep ); // Find the max exp + Z_ep++; + X++; + } + } + Zp = Z; + Z_ep = Z_e; + FOR( j = 0; j < entriesY; ++j ) + { + FOR( i = 0; i < rowsX; ++i ) + { + *Zp = L_shr( *Zp, sub( max_exp, *Z_ep ) ); + *Z_ep = max_exp; + Zp++; + Z_ep++; + } + } + } + + return EXIT_SUCCESS; +} +#endif /* OPT_BASOP_ADD_v1 */ + Word16 matrix_diag_product_fx_1( const Word32 *X, /* i : left hand matrix Q31 - X_e*/ const Word16 *X_e, @@ -1589,7 +1835,9 @@ Word16 matrix_diag_product_fx_1( Word16 i, j; Word32 *Zp = Z; Word16 *Z_ep = Z_e; +#ifndef OPT_BASOP_ADD_v1 Word16 tmp; +#endif /* OPT_BASOP_ADD_v1 */ /* Processing */ IF( EQ_16( transpX, 1 ) ) /* We use X transpose */ @@ -1602,11 +1850,19 @@ Word16 matrix_diag_product_fx_1( { FOR( i = 0; i < colsX; ++i ) { +#ifdef OPT_BASOP_ADD_v1 + *( Zp ) = Mpy_32_32( X[j + i * rowsX], Y[j] ); /*Q31 - (X_e + Y_e)*/ +#else /* OPT_BASOP_ADD_v1 */ tmp = add( j, imult1616( i, rowsX ) ); /*Q0*/ *( Zp ) = Mpy_32_32( X[tmp], Y[j] ); /*Q31 - (X_e + Y_e)*/ +#endif /* OPT_BASOP_ADD_v1 */ move32(); Zp++; +#ifdef OPT_BASOP_ADD_v1 + *( Z_ep ) = add( X_e[j + i * rowsX], Y_e[j] ); +#else /* OPT_BASOP_ADD_v1 */ *( Z_ep ) = add( X_e[tmp], Y_e[j] ); +#endif /* OPT_BASOP_ADD_v1 */ move16(); Z_ep++; } @@ -1652,7 +1908,9 @@ Word16 diag_matrix_product_fx( { Word16 i, j; Word32 *Zp = Z; +#ifndef OPT_BASOP_ADD_v1 Word16 tmp; +#endif /* OPT_BASOP_ADD_v1 */ /* Processing */ IF( EQ_16( transpX, 1 ) ) /* We use X transpose */ @@ -1665,8 +1923,12 @@ Word16 diag_matrix_product_fx( { FOR( j = 0; j < entriesY; ++j ) { - tmp = add( i, imult1616( j, rowsX ) ); /*Q0*/ - *( Zp ) = Mpy_32_32( X[tmp], Y[j] ); /*Q31 - (X_e + Y_e)*/ +#ifdef OPT_BASOP_ADD_v1 + *( Zp ) = Mpy_32_32( X[i + j * rowsX], Y[j] ); /*Q31 - (X_e + Y_e)*/ +#else /* OPT_BASOP_ADD_v1 */ + tmp = add( i, imult1616( j, rowsX ) ); /*Q0*/ + *( Zp ) = Mpy_32_32( X[tmp], Y[j] ); /*Q31 - (X_e + Y_e)*/ +#endif /* OPT_BASOP_ADD_v1 */ move32(); Zp++; } @@ -1712,7 +1974,9 @@ Word16 matrix_product_diag_fx( { Word16 j, k; Word32 *Zp = Z; +#ifndef OPT_BASOP_ADD_v1 Word16 y_idx, x_idx; +#endif /* OPT_BASOP_ADD_v1 */ /* Processing */ test(); @@ -1731,9 +1995,13 @@ Word16 matrix_product_diag_fx( move32(); FOR( k = 0; k < rowsX; ++k ) { +#ifdef OPT_BASOP_ADD_v1 + ( *Zp ) = Madd_32_32( ( *Zp ), X[k + j * rowsX], Y[k + j * rowsY] ); /*Q31 - (X_e + Y_e)*/ +#else /* OPT_BASOP_ADD_v1 */ x_idx = add( k, imult1616( j, rowsX ) ); /*Q0*/ y_idx = add( k, imult1616( j, rowsY ) ); /*Q0*/ ( *Zp ) = L_add( ( *Zp ), Mpy_32_32( X[x_idx], Y[y_idx] ) ); /*Q31 - (X_e + Y_e)*/ +#endif /* OPT_BASOP_ADD_v1 */ move32(); } Zp++; @@ -1751,9 +2019,13 @@ Word16 matrix_product_diag_fx( move32(); FOR( k = 0; k < colsX; ++k ) { +#ifdef OPT_BASOP_ADD_v1 + ( *Zp ) = Madd_32_32( ( *Zp ), X[j + k * rowsX], Y[j + k * rowsY] ); /*Q31 - (X_e + Y_e)*/ +#else /* OPT_BASOP_ADD_v1 */ x_idx = add( j, imult1616( k, rowsX ) ); /*Q0*/ y_idx = add( j, imult1616( k, rowsY ) ); /*Q0*/ ( *Zp ) = L_add( ( *Zp ), Mpy_32_32( X[x_idx], Y[y_idx] ) ); /*Q31 - (X_e + Y_e)*/ +#endif /* OPT_BASOP_ADD_v1 */ move32(); } Zp++; @@ -1773,9 +2045,13 @@ Word16 matrix_product_diag_fx( move32(); FOR( k = 0; k < colsX; ++k ) { +#ifdef OPT_BASOP_ADD_v1 + ( *Zp ) = Madd_32_32( ( *Zp ), X[k + j * rowsX], Y[j + k * rowsY] ); /*Q31 - (X_e + Y_e)*/ +#else /* OPT_BASOP_ADD_v1 */ x_idx = add( k, imult1616( j, rowsX ) ); /*Q0*/ y_idx = add( j, imult1616( k, rowsY ) ); /*Q0*/ ( *Zp ) = L_add( ( *Zp ), Mpy_32_32( X[x_idx], Y[y_idx] ) ); /*Q31 - (X_e + Y_e)*/ +#endif /* OPT_BASOP_ADD_v1 */ move32(); } @@ -1795,9 +2071,13 @@ Word16 matrix_product_diag_fx( move32(); FOR( k = 0; k < colsX; ++k ) { +#ifdef OPT_BASOP_ADD_v1 + ( *Zp ) = Madd_32_32( ( *Zp ), X[j + k * rowsX], Y[k + j * rowsY] ); /*Q31 - (X_e + Y_e)*/ +#else /* OPT_BASOP_ADD_v1 */ x_idx = add( j, imult1616( k, rowsX ) ); /*Q0*/ y_idx = add( k, imult1616( j, rowsY ) ); /*Q0*/ ( *Zp ) = L_add( ( *Zp ), Mpy_32_32( X[x_idx], Y[y_idx] ) ); /*Q31 - (X_e + Y_e)*/ +#endif /* OPT_BASOP_ADD_v1 */ move32(); } Zp++; @@ -2689,7 +2969,7 @@ Word64 var_32_fx( Word16 q /* q : q-factor for the array */ ) { - + Word16 i; Word64 mean, var; mean = 0; @@ -2697,14 +2977,14 @@ Word64 var_32_fx( var = 0; move64(); - FOR( int i = 0; i < len; i++ ) + FOR( i = 0; i < len; i++ ) { mean = W_add( mean, x[i] ); /*q*/ } mean = mean / len; /* NOTE: No BASOP for 64 bit division q*/ - FOR( int i = 0; i < len; i++ ) + FOR( i = 0; i < len; i++ ) { var = W_add( var, Mpy_32_32( L_sub( x[i], W_extract_l( mean ) ), L_sub( x[i], W_extract_l( mean ) ) ) ); /*q + q - 31*/ } diff --git a/lib_com/ivas_transient_det.c b/lib_com/ivas_transient_det_fx.c similarity index 96% rename from lib_com/ivas_transient_det.c rename to lib_com/ivas_transient_det_fx.c index 8f8905fdd66d59d6dd59589f9519afd9b55f09ec..3b9a8cfd7ebf1e22ec6513d4a5f5229e53c9d53d 100644 --- a/lib_com/ivas_transient_det.c +++ b/lib_com/ivas_transient_det_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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,11 +34,9 @@ #include "options.h" #include "math.h" #include "wmc_auto.h" -#include "prot.h" +#include "prot_fx.h" #include "ivas_cnst.h" -#include "ivas_prot.h" #include "ivas_prot_fx.h" -#include "prot_fx.h" #include "ivas_stat_com.h" /*------------------------------------------------------------------------------------------* @@ -344,26 +342,26 @@ static Word32 ivas_calc_duck_gain_fx( Word32 duck_gain_out, L_tmp; Word16 tmp_e; - duck_gain_out = L_add( L_shl( Mpy_32_32( L_sub( duck_gain, ONE_IN_Q30 ), duck_coeff ), Q1 ), ONE_IN_Q30 ); /*Q30*/ + duck_gain_out = L_add( Mpy_32_32( L_sub( duck_gain, ONE_IN_Q30 ), duck_coeff ), ONE_IN_Q29 ); /*Q29*/ - IF( EQ_16( BASOP_Util_Cmp_Mant32Exp( Mpy_32_32( duck_mult_fac, env_1 ), add( 2, env1_e ), Mpy_32_32( duck_gain_out, env_2 ), add( 1, env2_e ) ), -1 ) ) + IF( LT_64( W_mult0_32_32( duck_mult_fac, env_1 ), W_shr( W_mult0_32_32( duck_gain_out, env_2 ), sub( env1_e, env2_e ) ) ) ) { + + duck_gain_out = 0; + move32(); + test(); - IF( ( env_1 == 0 ) || ( env_2 == 0 ) ) - { - duck_gain_out = 0; - move32(); - } - ELSE + IF( ( env_1 != 0 ) && ( env_2 != 0 ) ) { L_tmp = BASOP_Util_Divide3232_Scale_cadence( env_1, env_2, &tmp_e ); L_tmp = L_shl( L_tmp, add( sub( env1_e, env2_e ), tmp_e ) ); duck_gain_out = Mpy_32_32( duck_mult_fac, L_tmp ); /*Q29*/ - duck_gain_out = L_shl( duck_gain_out, Q1 ); /*Q30*/ } } + duck_gain_out = L_shl( duck_gain_out, Q1 ); /*Q30*/ + return duck_gain_out; /*Q30*/ } /*-----------------------------------------------------------------------------------------* diff --git a/lib_com/lag_wind.c b/lib_com/lag_wind.c index 505cc0753b337600b9777af016703153dbceec27..9fb2872711d553565e75f883d9ddeafaef19cd40 100644 --- a/lib_com/lag_wind.c +++ b/lib_com/lag_wind.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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,7 +37,6 @@ #include #include #include "options.h" -#include "prot.h" #include "prot_fx.h" #include "cnst.h" #include "rom_com.h" diff --git a/lib_com/lerp.c b/lib_com/lerp.c index ed2ee211c0fb1576f7b6c4a4027e6c01d35acca7..4e306b93698eaff8917a518ff6f531615683af53 100644 --- a/lib_com/lerp.c +++ b/lib_com/lerp.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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,154 +36,25 @@ #include #include "options.h" -#include "prot.h" #include "prot_fx.h" #include "wmc_auto.h" - /*-------------------------------------------------------------* * Local function prototypes *-------------------------------------------------------------*/ -static void lerp_proc_flt( const float *f, float *f_out, const int16_t bufferNewSize, const int16_t bufferOldSize ); - - /*-------------------------------------------------------------* * procedure lerp_flt() * * * * * *-------------------------------------------------------------*/ -void lerp_flt( - const float *f, - float *f_out, - const int16_t bufferNewSize, - const int16_t bufferOldSize_inp ) -{ - float maxFac; - int16_t bufferOldSize, tmpNewSize; - - maxFac = 507.0 / 128.0; - bufferOldSize = bufferOldSize_inp; - - if ( (float) bufferNewSize / bufferOldSize > maxFac ) - { - tmpNewSize = bufferOldSize * 2; - while ( bufferNewSize > bufferOldSize ) - { - if ( (float) bufferNewSize / bufferOldSize <= maxFac ) - { - tmpNewSize = bufferNewSize; - } - - lerp_proc_flt( f, f_out, tmpNewSize, bufferOldSize ); - - f = f_out; - bufferOldSize = tmpNewSize; - tmpNewSize *= 2; - } - } - else if ( (float) bufferOldSize / bufferNewSize > maxFac ) - { - tmpNewSize = bufferOldSize / 2; - while ( bufferNewSize < bufferOldSize ) - { - if ( (float) bufferOldSize / bufferNewSize <= maxFac ) - { - tmpNewSize = bufferNewSize; - } - - lerp_proc_flt( f, f_out, tmpNewSize, bufferOldSize ); - - f = f_out; - bufferOldSize = tmpNewSize; - tmpNewSize /= 2; - } - } - else - { - lerp_proc_flt( f, f_out, bufferNewSize, bufferOldSize ); - } - - return; -} - /*-------------------------------------------------------------* * procedure lerp_proc_flt() * * * * * *-------------------------------------------------------------*/ -static void lerp_proc_flt( - const float *f, - float *f_out, - const int16_t bufferNewSize, - const int16_t bufferOldSize ) -{ - int16_t i, idx; - float pos, shift, diff; - float buf[2 * L_FRAME_MAX]; - Word16 tmp; - - if ( bufferNewSize == bufferOldSize ) - { - mvr2r( f, buf, bufferNewSize ); - mvr2r( buf, f_out, bufferNewSize ); - return; - } - - /* Using the basop code to avoid reading beyond end of input for bufferOldSize=320, bufferNewSize=640 */ - tmp = div_s( bufferOldSize, shl( bufferNewSize, 4 ) ); - shift = (float) ( L_shl( L_deposit_l( tmp ), 4 - 15 + 16 ) ) / 65536.0f; - pos = 0.5f * shift - 0.5f; - - if ( shift < 0.3f ) - { - pos = pos - 0.13f; - } - - /* first point of interpolation */ - if ( pos < 0 ) - { - buf[0] = f[0] + pos * ( f[1] - f[0] ); - } - else - { - idx = (int16_t) pos; - diff = pos - idx; - buf[0] = f[idx] + diff * ( f[idx + 1] - f[idx] ); - } - - pos += shift; - - for ( i = 1; i < bufferNewSize - 1; i++ ) - { - idx = (int16_t) pos; - diff = pos - idx; - - buf[i] = f[idx] + diff * ( f[idx + 1] - f[idx] ); - pos += shift; - } - - - /* last point */ - idx = (int16_t) pos; - - if ( pos > bufferOldSize - 1 ) - { - idx = bufferOldSize - 2; - } - - diff = pos - idx; - - buf[bufferNewSize - 1] = f[idx] + diff * ( f[idx + 1] - f[idx] ); - - mvr2r( buf, f_out, bufferNewSize ); - - return; -} - - /*-------------------------------------------------------------* * Local constants *-------------------------------------------------------------*/ @@ -310,11 +181,7 @@ static void lerp_proc( const Word16 *f /*Qx*/, Word16 *f_out /*Qx*/, Word16 buff diff = shr( extract_l( pos ), 1 ); /*Q15*/ /*buf[0]=f[0]+pos*(f[1]-f[0]);*/ move16(); -#ifdef BASOP_NOGLOB *ptr++ = add_sat( f[0], msu_r( L_mult( diff, f[1] ), diff, f[0] ) ); /*Qx*/ -#else - *ptr++ = add( f[0], msu_r( L_mult( diff, f[1] ), diff, f[0] ) ); -#endif } ELSE { @@ -324,11 +191,7 @@ static void lerp_proc( const Word16 *f /*Qx*/, Word16 *f_out /*Qx*/, Word16 buff diff = lshr( extract_l( pos ), 1 ); /*Q15*/ move16(); -#ifdef BASOP_NOGLOB *ptr++ = add_sat( f[idx], msu_r_sat( L_mult( diff, f[idx + 1] ), diff, f[idx] ) ); /*Qx*/ -#else - *ptr++ = add( f[idx], msu_r( L_mult( diff, f[idx + 1] ), diff, f[idx] ) ); -#endif } pos = L_add( pos, shift ); @@ -343,11 +206,7 @@ static void lerp_proc( const Word16 *f /*Qx*/, Word16 *f_out /*Qx*/, Word16 buff diff = sub( 16384 /*0.5f Q15*/, diff ); /*Q15*/ } move16(); -#ifdef BASOP_NOGLOB *ptr++ = add_sat( f[idx], msu_r_sat( L_mult( diff, f[idx + 1] ), diff, f[idx] ) ); /*Qx*/ -#else - *ptr++ = add( f[idx], msu_r( L_mult( diff, f[idx + 1] ), diff, f[idx] ) ); -#endif pos = L_add( pos, shift ); @@ -366,11 +225,7 @@ static void lerp_proc( const Word16 *f /*Qx*/, Word16 *f_out /*Qx*/, Word16 buff diff = lshr( extract_l( L_shr( L_sub( pos, L_deposit_h( idx ) ), 1 ) ), 1 ); /*Q15*/ move16(); -#ifdef BASOP_NOGLOB *ptr++ = add_sat( f[idx], shl_sat( msu_r_sat( L_mult( diff, f[idx + 1] ), diff, f[idx] ), 1 ) ); /*Qx*/ -#else - *ptr++ = add( f[idx], shl( msu_r( L_mult( diff, f[idx + 1] ), diff, f[idx] ), 1 ) ); -#endif test(); test(); test(); @@ -446,7 +301,7 @@ static void lerp_proc32( Word32 *f /*Qx*/, Word32 *f_out /*Qx*/, Word16 bufferNe { diff = sub( 16384 /*0.5f Q15*/, diff ); /*Q15*/ } - *ptr++ = L_add_sat( f[idx], Mpy_32_16_1( L_sub( f[idx + 1], f[idx] ), diff ) ); /*Qx*/ + *ptr++ = L_add_sat( f[idx], L_sub( Mpy_32_16_1( f[idx + 1], diff ), Mpy_32_16_1( f[idx], diff ) ) ); /*Qx*/ move32(); pos = L_add( pos, shift ); /*Q16*/ idx = extract_h( pos ); diff --git a/lib_com/limit_t0.c b/lib_com/limit_t0.c deleted file mode 100644 index dfbfbb796cd91e6c78e58f20b751a8b81ee1e19d..0000000000000000000000000000000000000000 --- a/lib_com/limit_t0.c +++ /dev/null @@ -1,231 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include "cnst.h" -#include "prot.h" -#include "wmc_auto.h" - -/*-------------------------------------------------* - * Local constants - *-------------------------------------------------*/ - -#define LIMIT_PIT_REL_LOWER 2 /* delta interval to extend pitch coding in relative Q */ -#define LIMIT_PIT_REL_UPPER 0 - -/*-------------------------------------------------* - * limit_T0() - * - * Close-loop pitch lag search limitation - *-------------------------------------------------*/ - -void limit_T0( - const int16_t L_frame, /* i : length of the frame */ - const int16_t delta, /* i : Half the close-loop searched interval */ - const int16_t pit_flag, /* i : selecting absolute(0) or delta(1) pitch quantization */ - const int16_t limit_flag, /* i : flag for Q limits (0=restrained, 1=extended) */ - const int16_t T0, /* i : rough pitch estimate around which the search is done */ - const int16_t T0_frac, /* i : pitch estimate fractional part */ - int16_t *T0_min, /* o : lower pitch limit */ - int16_t *T0_max /* o : higher pitch limit */ -) -{ - int16_t delta2, T1; - int16_t pit_min, pit_max; - - if ( limit_flag == 0 ) /* restrained Q limits */ - { - /* set limits */ - if ( L_frame == L_FRAME ) - { - pit_max = PIT_MAX; - pit_min = PIT_MIN; - } - else /* L_frame == L_FRAME16k */ - { - pit_max = PIT16k_MAX; - pit_min = PIT16k_MIN; - } - - delta2 = 2 * delta - 1; - - T1 = T0; - if ( T0_frac >= 2 ) - { - T1++; - } - *T0_min = T1 - delta; - - if ( *T0_min < pit_min ) - { - *T0_min = pit_min; - } - *T0_max = *T0_min + delta2; - - if ( *T0_max > pit_max ) - { - *T0_max = pit_max; - *T0_min = *T0_max - delta2; - } - } - else /* extended Q limits */ - { - - /* set limits */ - if ( L_frame == L_FRAME ) - { - pit_max = PIT_MAX; - pit_min = PIT_MIN_EXTEND; - - if ( limit_flag == 2 ) - { - pit_min = PIT_MIN_DOUBLEEXTEND; - } - } - else /* L_frame == L_FRAME16k */ - { - pit_max = PIT16k_MAX; - pit_min = PIT16k_MIN_EXTEND; - } - - delta2 = 2 * delta - 1; - - T1 = T0; - if ( T0_frac >= 2 ) - { - T1++; - } - *T0_min = T1 - delta; - - if ( pit_flag == 0 ) - { - /* subframes with absolute search: keep Q range */ - if ( *T0_min < pit_min ) - { - *T0_min = pit_min; - } - *T0_max = *T0_min + delta2; - - if ( *T0_max > pit_max ) - { - *T0_max = pit_max; - *T0_min = *T0_max - delta2; - } - } - else - { - /* subframes with relative search: extend Q range */ - if ( *T0_min < pit_min - LIMIT_PIT_REL_LOWER ) - { - *T0_min = pit_min - LIMIT_PIT_REL_LOWER; - } - - if ( *T0_min < L_INTERPOL ) - { - *T0_min = L_INTERPOL; - } - *T0_max = *T0_min + delta2; - - if ( *T0_max > pit_max + LIMIT_PIT_REL_UPPER ) - { - *T0_max = pit_max + LIMIT_PIT_REL_UPPER; - *T0_min = *T0_max - delta2; - } - } - } - - return; -} - - -/*-------------------------------------------------* - * Routine limit_T0_voiced_ivas() - * - * Close-loop pitch lag search limitation - *-------------------------------------------------*/ - -void limit_T0_voiced_ivas( - const int16_t nbits, - const int16_t res, - const int16_t T0, /* i : rough pitch estimate around which the search is done */ - const int16_t T0_frac, /* i : pitch estimate fractional part */ - const int16_t T0_res, /* i : pitch resolution */ - int16_t *T0_min, /* o : lower pitch limit */ - int16_t *T0_min_frac, /* o : lower pitch limit */ - int16_t *T0_max, /* o : higher pitch limit */ - int16_t *T0_max_frac, /* o : higher pitch limit */ - const int16_t pit_min, /* i : Minimum pitch lag */ - const int16_t pit_max /* i : Maximum pitch lag */ -) -{ - int16_t T1, temp1, temp2; - - /* Mid-point */ - T1 = T0; - if ( ( T0_res > 1 ) && ( T0_frac >= ( T0_res >> 1 ) ) ) - { - T1++; - } - - /* Lower-bound */ - temp1 = ( T1 * res ) - ( 1 << ( nbits - 1 ) ); - temp2 = temp1 / res; - *T0_min = temp2; - *T0_min_frac = temp1 - temp2 * res; - if ( *T0_min < pit_min ) - { - *T0_min = pit_min; - *T0_min_frac = 0; - } - - /* Higher-bound */ - temp1 = ( *T0_min * res ) + *T0_min_frac + ( 1 << nbits ) - 1; - temp2 = temp1 / res; - *T0_max = temp2; - *T0_max_frac = temp1 - temp2 * res; - if ( *T0_max > pit_max ) - { - *T0_max = pit_max; - *T0_max_frac = res - 1; - temp1 = ( *T0_max * res ) + *T0_max_frac - ( 1 << nbits ) + 1; - temp2 = temp1 / res; - *T0_min = temp2; - *T0_min_frac = temp1 - temp2 * res; - } - - return; -} diff --git a/lib_com/log2.c b/lib_com/log2.c index 1fef489e9ab140faae3ba2ce127067af8effd941..3df1a960ec4728e537d09f4aaa9a8eb0a13e1d32 100644 --- a/lib_com/log2.c +++ b/lib_com/log2.c @@ -193,11 +193,7 @@ Word32 pow_10( Word32 x, Word16 *Q ) /*o : Q15, i: Q26*/ { Overflow = 0; move16(); -#ifdef BASOP_NOGLOB /* Critical Overflow */ L_tmp = L_shl_o( L_tmp, i, &Overflow ); -#else - L_tmp = L_shl( L_tmp, i ); -#endif if ( Overflow ) { count = add( count, 1 ); diff --git a/lib_com/logqnorm_fx.c b/lib_com/logqnorm_fx.c index c7852bbe422a8dd1d2fc186e9dfc582174403527..833ff03fb572f67dff94fca968c9136a5baec042 100644 --- a/lib_com/logqnorm_fx.c +++ b/lib_com/logqnorm_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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_com/longarith.c b/lib_com/longarith.c index 68ba282d58ccc11258e538c2ac26fc0f4c0c568a..72a763de3dc933db4fae6d7de78b0893b436a2c9 100644 --- a/lib_com/longarith.c +++ b/lib_com/longarith.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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,10 +37,9 @@ #include #include #include "options.h" -#include "prot.h" +#include "prot_fx.h" #include "wmc_auto.h" #include "ivas_prot_fx.h" -#include "prot_fx.h" /*-------------------------------------------------------------------* @@ -53,27 +52,27 @@ *--------------------------------------------------------------------*/ void longadd( - uint16_t a[], /* i/o: vector of the length lena */ - const uint16_t b[], /* i/o: vector of the length lenb */ - const int16_t lena, /* i/o: length of vector a[] */ - const int16_t lenb /* i/o: length of vector b[] */ + UWord16 a[], /* i/o: vector of the length lena */ + const UWord16 b[], /* i/o: vector of the length lenb */ + const Word16 lena, /* i/o: length of vector a[] */ + const Word16 lenb /* i/o: length of vector b[] */ ) { - int16_t h; - int32_t carry = 0; + Word16 h; + Word32 carry = 0; assert( lena >= lenb ); for ( h = 0; h < lenb; h++ ) { carry += ( (uint32_t) a[h] ) + ( (uint32_t) b[h] ); - a[h] = (uint16_t) carry; + a[h] = (UWord16) carry; carry = carry >> 16; } for ( ; h < lena; h++ ) { carry = ( (uint32_t) a[h] ) + carry; - a[h] = (uint16_t) carry; + a[h] = (UWord16) carry; carry = carry >> 16; } @@ -92,14 +91,14 @@ void longadd( *--------------------------------------------------------------------*/ void longshiftright( - uint16_t a[], /* i : vector of the length lena */ - const int16_t b, /* i : number of bit positions to shift right */ - uint16_t d[], /* o : vector of the length lend */ - int16_t lena, /* i : length of vector a[] */ - const int16_t lend /* i : length of vector d[] */ + UWord16 a[], /* i : vector of the length lena */ + const Word16 b, /* i : number of bit positions to shift right */ + UWord16 d[], /* o : vector of the length lend */ + Word16 lena, /* i : length of vector a[] */ + const Word16 lend /* i : length of vector d[] */ ) { - int16_t intb, fracb, fracb_u, k; + Word16 intb, fracb, fracb_u, k; intb = b >> 4; @@ -165,16 +164,16 @@ void longshr( *--------------------------------------------------------------------*/ void longshiftleft( - const uint16_t a[], /* i : vector of the length len */ - const int16_t b, /* i : number of bit positions to shift left */ - uint16_t d[], /* o : vector of the length len */ - const int16_t len /* i : length of vector a[] and d[] */ + const UWord16 a[], /* i : vector of the length len */ + const Word16 b, /* i : number of bit positions to shift left */ + UWord16 d[], /* o : vector of the length len */ + const Word16 len /* i : length of vector a[] and d[] */ ) { - int16_t intb; /* integer part of b */ - int16_t fracb; /* shift left value for all upper words a[k] */ - int16_t fracb_l; /* shift right value for all lower words a[k-1] */ - int16_t k = len - 1; + Word16 intb; /* integer part of b */ + Word16 fracb; /* shift left value for all upper words a[k] */ + Word16 fracb_l; /* shift right value for all lower words a[k-1] */ + Word16 k = len - 1; intb = b >> 4; fracb = b & 0xF; diff --git a/lib_com/low_rate_band_att_fx.c b/lib_com/low_rate_band_att_fx.c index be06b8b0184b1d3cb7730c21276e3827b4915465..9958b9d5fdef77ec8782e1aaf261baa60b7111b0 100644 --- a/lib_com/low_rate_band_att_fx.c +++ b/lib_com/low_rate_band_att_fx.c @@ -82,14 +82,10 @@ void ivas_fine_gain_pred_fx( Word16 tmp1, tmp_exp = sub( 15, norm ); tmp1 = Sqrt16( shl( bw, norm ), &tmp_exp ); tmp1 = shr( tmp1, sub( sub( 15, tmp_exp ), Q11 ) ); - Mpy_32_16_ss( L_tmp, tmp1, &L_tmp, &lsb ); /*31-exp+11-15=27-exp */ + Mpy_32_16_ss( L_tmp, tmp1, &L_tmp, &lsb ); /*31-exp+11-15=27-exp */ #endif -#ifdef BASOP_NOGLOB gp = round_fx_o( L_shl_o( L_tmp, add( 1, exp ), &Overflow ), &Overflow ); /*27-exp+1+exp-16=12 */ -#else - gp = round_fx( L_shl( L_tmp, add( 1, exp ) ) ); /*27-exp+1+exp-16=12 */ -#endif test(); test(); IF( EQ_16( core, HQ_CORE ) && R != NULL && LE_16( R[i_sort[band]], 256 ) ) /* 256 is 32 in Q3 */ @@ -104,12 +100,8 @@ void ivas_fine_gain_pred_fx( exp = add( exp, exp2 ); /*gp *= 1.0f - 0.05f / accuracy; */ - tmp = div_s( 13107, accuracy ); /* 0.05 in Q18 */ -#ifdef BASOP_NOGLOB + tmp = div_s( 13107, accuracy ); /* 0.05 in Q18 */ tmp = shr_o( tmp, sub( 34, exp ), &Overflow ); /*15+18-exp+16-15=34-exp */ -#else /* BASOP_NOGLOB */ - tmp = shr( tmp, sub( 34, exp ) ); /*15+18-exp+16-15=34-exp */ -#endif tmp = sub( 32767, tmp ); tmp = s_max( 27554, tmp ); /* Limit attenuation to norm quantizer error, 2^-0.25 in Q15 */ gp = mult_r( tmp, gp ); /*15+12+1-16=12 */ @@ -199,13 +191,9 @@ void fine_gain_pred_fx( exp = norm_l( xx ); L_tmp = L_shl( xx, exp ); /*2*(15-shift)+exp */ exp = sub( 31, add( exp, sub( 30, shl( shift, 1 ) ) ) ); - L_tmp = Isqrt_lc( L_tmp, &exp ); /*31 - exp */ - Mpy_32_16_ss( L_tmp, fine_gain_pred_sqrt_bw[bw_idx], &L_tmp, &lsb ); /*31-exp+11-15=27-exp */ -#ifdef BASOP_NOGLOB + L_tmp = Isqrt_lc( L_tmp, &exp ); /*31 - exp */ + Mpy_32_16_ss( L_tmp, fine_gain_pred_sqrt_bw[bw_idx], &L_tmp, &lsb ); /*31-exp+11-15=27-exp */ gp = round_fx_o( L_shl_o( L_tmp, add( 1, exp ), &Overflow ), &Overflow ); /*27-exp+1+exp-16=12 */ -#else - gp = round_fx( L_shl( L_tmp, add( 1, exp ) ) ); /*27-exp+1+exp-16=12 */ -#endif test(); test(); IF( EQ_16( core, HQ_CORE ) && R != NULL && LE_16( R[i_sort[band]], 256 ) ) /* 256 is 32 in Q3 */ @@ -220,12 +208,8 @@ void fine_gain_pred_fx( exp = add( exp, exp2 ); /*gp *= 1.0f - 0.05f / accuracy; */ - tmp = div_s( 13107, accuracy ); /* 0.05 in Q18 */ -#ifdef BASOP_NOGLOB + tmp = div_s( 13107, accuracy ); /* 0.05 in Q18 */ tmp = shr_o( tmp, sub( 34, exp ), &Overflow ); /*15+18-exp+16-15=34-exp */ -#else /* BASOP_NOGLOB */ - tmp = shr( tmp, sub( 34, exp ) ); /*15+18-exp+16-15=34-exp */ -#endif tmp = sub( 32767, tmp ); tmp = s_max( 27554, tmp ); /* Limit attenuation to norm quantizer error, 2^-0.25 in Q15 */ gp = mult_r( tmp, gp ); /*15+12+1-16=12 */ diff --git a/lib_com/lpc_tools_fx.c b/lib_com/lpc_tools_fx.c index 8f478dde7c7fdb0d863b2221394b262df3dcba21..bde05b4f4ebc1d9ab7a4ac99776af5f25b97036d 100644 --- a/lib_com/lpc_tools_fx.c +++ b/lib_com/lpc_tools_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other @@ -427,11 +427,7 @@ static Word32 Div_32_opt( Word32 L_num /*Q31*/, Word16 denom_hi /*Qx -16*/, Word L_32 = Mpy_32_32( L_num, L_32 ); -#ifdef BASOP_NOGLOB L_32 = L_shl_o( L_32, 2, &Overflow ); -#else /* BASOP_NOGLOB */ - L_32 = L_shl( L_32, 2 ); -#endif /* BASOP_NOGLOB */ return ( L_32 ); } @@ -530,21 +526,12 @@ Word16 E_LPC_lev_dur_stab( const Word16 Rh[] /*QR -16*/, const Word16 Rl[] /*QR t0 = Mac_32( t0, Rh[j], Rl[j], Ah[i - j], Al[i - j] ); } -#ifdef BASOP_NOGLOB t0 = L_shl_o( t0, 4, &Overflow ); /* result in Q27 -> convert to Q31 */ -#else /* BASOP_NOGLOB */ - t0 = L_shl( t0, 4 ); /* result in Q27 -> convert to Q31 */ -#endif /* BASOP_NOGLOB */ /* No overflow possible */ /* Compose and add R[i] in Q3 */ -#ifdef BASOP_NOGLOB t0 = L_mac_o( t0, Rl[i], 1, &Overflow ); t0 = L_msu_o( t0, Rh[i], -32768, &Overflow ); -#else /* BASOP_NOGLOB */ - t0 = L_mac( t0, Rl[i], 1 ); - t0 = L_msu( t0, Rh[i], -32768 ); -#endif /* BASOP_NOGLOB */ /* K = -t0 / Alpha */ t1 = L_abs( t0 ); @@ -559,11 +546,7 @@ Word16 E_LPC_lev_dur_stab( const Word16 Rh[] /*QR -16*/, const Word16 Rl[] /*QR { t2 = L_negate( t2 ); /* K =-t0/Alpha */ } -#ifdef BASOP_NOGLOB t2 = L_shl_o( t2, alp_exp, &Overflow ); /* denormalize; compare to Alpha */ -#else /* BASOP_NOGLOB */ - t2 = L_shl( t2, alp_exp ); /* denormalize; compare to Alpha */ -#endif /* BASOP_NOGLOB */ test(); if ( ( mem != NULL ) && ( ( GT_16( abs_s( extract_h( t2 ) ), k_max ) ) ) ) { @@ -602,11 +585,7 @@ Word16 E_LPC_lev_dur_stab( const Word16 Rh[] /*QR -16*/, const Word16 Rl[] /*QR L_Extract( t2, &Ah[i], &Al[i] ); /* An[i] in Q27 */ /* Alpha = Alpha * (1-K**2) */ -#ifdef BASOP_NOGLOB t1 = L_mult_o( Kh, Kh, &Overflow ); /* K*K in Q31 */ -#else /* BASOP_NOGLOB */ - t1 = L_mult( Kh, Kh ); /* K*K in Q31 */ -#endif /* BASOP_NOGLOB */ t0 = L_mac( t1, mult( Kh, Kl ), 2 ); t0 = L_abs( t0 ); /* Some case <0 !! */ t0 = L_sub( (Word32) 0x7fffffffL, t0 ); /* 1 - K*K in Q31 */ @@ -642,11 +621,7 @@ Word16 E_LPC_lev_dur_stab( const Word16 Rh[] /*QR -16*/, const Word16 Rl[] /*QR FOR( i = 1; i <= order; i++ ) { t0 = L_Comp( Ah[i], Al[i] ); -#ifdef BASOP_NOGLOB A[i] = round_fx_o( L_shl_o( t0, k, &Overflow ), &Overflow ); -#else - A[i] = round_fx( L_shl( t0, k ) ); -#endif move16(); } @@ -745,21 +720,12 @@ Word16 E_LPC_lev_dur_stab_ivas_fx( const Word16 Rh[], const Word16 Rl[], Word16 t0 = Mac_32( t0, Rh[j], Rl[j], Ah[i - j], Al[i - j] ); } -#ifdef BASOP_NOGLOB t0 = L_shl_o( t0, 4, &Overflow ); /* result in Q27 -> convert to Q31 */ -#else /* BASOP_NOGLOB */ - t0 = L_shl( t0, 4 ); /* result in Q27 -> convert to Q31 */ -#endif /* BASOP_NOGLOB */ /* No overflow possible */ /* Compose and add R[i] in Q3 */ -#ifdef BASOP_NOGLOB t0 = L_mac_o( t0, Rl[i], 1, &Overflow ); t0 = L_msu_o( t0, Rh[i], -32768, &Overflow ); -#else /* BASOP_NOGLOB */ - t0 = L_mac( t0, Rl[i], 1 ); - t0 = L_msu( t0, Rh[i], -32768 ); -#endif /* BASOP_NOGLOB */ /* K = -t0 / Alpha */ t1 = L_abs( t0 ); @@ -774,11 +740,7 @@ Word16 E_LPC_lev_dur_stab_ivas_fx( const Word16 Rh[], const Word16 Rl[], Word16 { t2 = L_negate( t2 ); /* K =-t0/Alpha */ } -#ifdef BASOP_NOGLOB t2 = L_shl_o( t2, alp_exp, &Overflow ); /* denormalize; compare to Alpha */ -#else /* BASOP_NOGLOB */ - t2 = L_shl( t2, alp_exp ); /* denormalize; compare to Alpha */ -#endif /* BASOP_NOGLOB */ test(); if ( ( mem != NULL ) && ( ( GT_16( abs_s( extract_h( t2 ) ), k_max ) ) ) ) { @@ -817,11 +779,7 @@ Word16 E_LPC_lev_dur_stab_ivas_fx( const Word16 Rh[], const Word16 Rl[], Word16 L_Extract( t2, &Ah[i], &Al[i] ); /* An[i] in Q27 */ /* Alpha = Alpha * (1-K**2) */ -#ifdef BASOP_NOGLOB t1 = L_mult_o( Kh, Kh, &Overflow ); /* K*K in Q31 */ -#else /* BASOP_NOGLOB */ - t1 = L_mult( Kh, Kh ); /* K*K in Q31 */ -#endif /* BASOP_NOGLOB */ t0 = L_mac( t1, mult( Kh, Kl ), 2 ); t0 = L_abs( t0 ); /* Some case <0 !! */ t0 = L_sub( (Word32) 0x7fffffffL, t0 ); /* 1 - K*K in Q31 */ @@ -857,11 +815,7 @@ Word16 E_LPC_lev_dur_stab_ivas_fx( const Word16 Rh[], const Word16 Rl[], Word16 FOR( i = 1; i <= order; i++ ) { t0 = L_Comp( Ah[i], Al[i] ); -#ifdef BASOP_NOGLOB A[i] = round_fx_o( L_shl_o( t0, k, &Overflow ), &Overflow ); -#else - A[i] = round_fx( L_shl( t0, k ) ); -#endif move16(); } @@ -961,21 +915,12 @@ Word16 E_LPC_lev_dur_stab_fx( const Word16 Rh[] /*QR -16*/, const Word16 Rl[] /* t0 = Mac_32( t0, Rh[j], Rl[j], Ah[i - j], Al[i - j] ); } -#ifdef BASOP_NOGLOB t0 = L_shl_o( t0, 4, &Overflow ); /* result in Q27 -> convert to Q31 */ -#else /* BASOP_NOGLOB */ - t0 = L_shl( t0, 4 ); /* result in Q27 -> convert to Q31 */ -#endif /* BASOP_NOGLOB */ /* No overflow possible */ /* Compose and add R[i] in Q3 */ -#ifdef BASOP_NOGLOB t0 = L_mac_o( t0, Rl[i], 1, &Overflow ); t0 = L_msu_o( t0, Rh[i], -32768, &Overflow ); -#else /* BASOP_NOGLOB */ - t0 = L_mac( t0, Rl[i], 1 ); - t0 = L_msu( t0, Rh[i], -32768 ); -#endif /* BASOP_NOGLOB */ /* K = -t0 / Alpha */ t1 = L_abs( t0 ); @@ -990,11 +935,7 @@ Word16 E_LPC_lev_dur_stab_fx( const Word16 Rh[] /*QR -16*/, const Word16 Rl[] /* { t2 = L_negate( t2 ); /* K =-t0/Alpha */ } -#ifdef BASOP_NOGLOB t2 = L_shl_o( t2, alp_exp, &Overflow ); /* denormalize; compare to Alpha */ -#else /* BASOP_NOGLOB */ - t2 = L_shl( t2, alp_exp ); /* denormalize; compare to Alpha */ -#endif /* BASOP_NOGLOB */ test(); if ( ( mem != NULL ) && ( ( GT_16( abs_s( extract_h( t2 ) ), k_max ) ) ) ) { @@ -1033,11 +974,7 @@ Word16 E_LPC_lev_dur_stab_fx( const Word16 Rh[] /*QR -16*/, const Word16 Rl[] /* L_Extract( t2, &Ah[i], &Al[i] ); /* An[i] in Q27 */ /* Alpha = Alpha * (1-K**2) */ -#ifdef BASOP_NOGLOB t1 = L_mult_o( Kh, Kh, &Overflow ); /* K*K in Q31 */ -#else /* BASOP_NOGLOB */ - t1 = L_mult( Kh, Kh ); /* K*K in Q31 */ -#endif /* BASOP_NOGLOB */ t0 = L_mac( t1, mult( Kh, Kl ), 2 ); t0 = L_abs( t0 ); /* Some case <0 !! */ t0 = L_sub( (Word32) 0x7fffffffL, t0 ); /* 1 - K*K in Q31 */ @@ -1073,11 +1010,7 @@ Word16 E_LPC_lev_dur_stab_fx( const Word16 Rh[] /*QR -16*/, const Word16 Rl[] /* FOR( i = 1; i <= order; i++ ) { t0 = L_Comp( Ah[i], Al[i] ); -#ifdef BASOP_NOGLOB A[i] = L_shl_o( t0, k, &Overflow ); -#else - A[i] = L_shl(t0, k)); -#endif move16(); } @@ -1277,6 +1210,91 @@ Word16 E_LPC_lsp_unweight( return 0; } +/* + * E_LPC_schur_ivas + * + * Parameters: + * R I: Rh[M+1] Vector of autocorrelations (msb) + * reflCoeff O: rc[M] Reflection coefficients. Q15 + * epsP O: error vector + * + * Function: + * Schur algorithm to compute + * the LPC parameters from the autocorrelations of speech. + * + * Returns: + * void + */ +Word32 E_LPC_schur_ivas( Word32 r[] /*Qr*/, Word16 reflCoeff[] /*Q15*/, const Word16 m ) +{ + Word16 i, j, temp16, mMi, s; + Word32 g0[M], *g1, tmp32; + const Word32 min_epsP = 1; /* > 0.01f*2^27/2^30 */ + Word32 tmp_epsP; + + s = getScaleFactor32( r, add( m, 1 ) ); + IF( s != 0 ) + { + scale_sig32( r, add( m, 1 ), s ); /* scale in-place */ + } + + g1 = r; + Copy32( r + 1, g0, m ); + + /* compute g0[0]/g1[0], where g0[0] < g1[0] */ + temp16 = negate( divide3232( g0[0], g1[0] ) ); + reflCoeff[0] = temp16; + move16(); + // epsP[0] = r[0]; + move32(); + + + FOR( i = 0; i < m; i++ ) + { + /* g1[0] = g0[0]*temp16 + g1[0]; */ + tmp32 = Mpy_32_16_1( g0[0], temp16 ); + g1[0] = L_add( g1[0], tmp32 ); + move32(); + + mMi = sub( m, i ); + FOR( j = 1; j < mMi; j++ ) + { + /* g0[j-1] = g0[j] + g1[j]*temp16; + g1[j] = g0[j]*temp16 + g1[j]; */ + g0[j - 1] = L_add( g0[j], Mpy_32_16_1( g1[j], temp16 ) ); + move32(); + g1[j] = L_add( g1[j], Mpy_32_16_1( g0[j], temp16 ) ); + move32(); + } + temp16 = negate( divide3232( g0[0], g1[0] ) ); + reflCoeff[i + 1] = temp16; + move16(); + + /* Prediction errors */ + tmp_epsP = L_shr( g1[0], s ); + if ( tmp_epsP <= 0 ) + { + tmp_epsP = min_epsP; + move32(); + } + // epsP[i + 1] = tmp_epsP; + move32(); + } + + /* epsP[i+1] = g0[0]*temp16 + g1[0]; */ + tmp_epsP = L_add( g1[0], Mpy_32_16_1( g0[0], temp16 ) ); + tmp_epsP = L_shr( tmp_epsP, s ); + if ( tmp_epsP <= 0 ) + { + tmp_epsP = min_epsP; + move32(); + } + + /* prediction gain = divide3232(L_shr(epsP[0], PRED_GAIN_E), g1[0]); */ + + + return g1[0]; +} /* * E_LPC_schur @@ -1638,30 +1656,20 @@ void E_LPC_a_lsf_isf_conversion( Word16 *lpcCoeffs /*Qx*/, Word16 *lsf /*15Q16*/ Word16 ImAr = extract_h( L_sub( ImagFFT[i], ImagFFT[N / 2 - i] ) ); Word16 ImBr = extract_h( L_add( ImagFFT[i], ImagFFT[N / 2 - i] ) ); BASOP_SATURATE_WARNING_OFF_EVS -#ifdef BASOP_NOGLOB tmpw15.v.re = mac_ro( L_mult( ptwiddle->v.re, pwn17->v.re ), ptwiddle->v.im, pwn17->v.im, &Overflow ); move16(); tmpw15.v.im = msu_ro( L_mult( ptwiddle->v.re, pwn17->v.im ), ptwiddle->v.im, pwn17->v.re, &Overflow ); move16(); -#else /* BASOP_NOGLOB */ - tmpw15.v.re = mac_r( L_mult( ptwiddle->v.re, pwn17->v.re ), ptwiddle->v.im, pwn17->v.im ); - tmpw15.v.im = msu_r( L_mult( ptwiddle->v.re, pwn17->v.im ), ptwiddle->v.im, pwn17->v.re ); -#endif /* BASOP_NOGLOB */ BASOP_SATURATE_WARNING_ON_EVS RealOut[i] = mac_r( L_msu( L_msu( L_mult( ReAr, pwn17->v.re ), ImAr, pwn17->v.im ), ReBr, pwn15->v.im ), ImBr, pwn15->v.re ); move16(); ImagOut[i] = mac_r( L_mac( L_mac( L_mult( ReAr, pwn17->v.im ), ImAr, pwn17->v.re ), ReBr, pwn15->v.re ), ImBr, pwn15->v.im ); move16(); BASOP_SATURATE_WARNING_OFF_EVS -#ifdef BASOP_NOGLOB tmpw15.v.re = msu_ro( L_mult( ptwiddle->v.im, pwn17i->v.im ), ptwiddle->v.re, pwn17i->v.re, &Overflow ); move16(); tmpw15.v.im = mac_ro( L_mult( ptwiddle->v.re, pwn17i->v.im ), ptwiddle->v.im, pwn17i->v.re, &Overflow ); move16(); -#else /* BASOP_NOGLOB */ - tmpw15.v.re = msu_r( L_mult( ptwiddle->v.im, pwn17i->v.im ), ptwiddle->v.re, pwn17i->v.re ); - tmpw15.v.im = mac_r( L_mult( ptwiddle->v.re, pwn17i->v.im ), ptwiddle->v.im, pwn17i->v.re ); -#endif /* BASOP_NOGLOB */ BASOP_SATURATE_WARNING_ON_EVS RealOut[N / 2 - i] = msu_r( L_mac( L_mac( L_mult( ReAr, pwn17i->v.re ), ImAr, pwn17i->v.im ), ImBr, pwn15i->v.re ), ReBr, pwn15i->v.im ); move16(); @@ -1682,30 +1690,20 @@ void E_LPC_a_lsf_isf_conversion( Word16 *lpcCoeffs /*Qx*/, Word16 *lsf /*15Q16*/ Word16 ImAr = extract_h( L_sub( ImagFFT[i], ImagFFT[N / 2 - i] ) ); Word16 ImBr = extract_h( L_add( ImagFFT[i], ImagFFT[N / 2 - i] ) ); BASOP_SATURATE_WARNING_OFF_EVS -#ifdef BASOP_NOGLOB tmpw15.v.re = mac_ro( L_mult( ptwiddle->v.im, pwn17->v.re ), ptwiddle->v.re, pwn17->v.im, &Overflow ); move16(); tmpw15.v.im = msu_ro( L_mult( ptwiddle->v.im, pwn17->v.im ), ptwiddle->v.re, pwn17->v.re, &Overflow ); move16(); -#else /* BASOP_NOGLOB */ - tmpw15.v.re = mac_r( L_mult( ptwiddle->v.im, pwn17->v.re ), ptwiddle->v.re, pwn17->v.im ); - tmpw15.v.im = msu_r( L_mult( ptwiddle->v.im, pwn17->v.im ), ptwiddle->v.re, pwn17->v.re ); -#endif /* BASOP_NOGLOB */ BASOP_SATURATE_WARNING_ON_EVS RealOut[i] = mac_r( L_msu( L_msu( L_mult( ReAr, pwn17->v.re ), ImAr, pwn17->v.im ), ReBr, pwn15->v.im ), ImBr, pwn15->v.re ); move16(); ImagOut[i] = mac_r( L_mac( L_mac( L_mult( ReAr, pwn17->v.im ), ImAr, pwn17->v.re ), ReBr, pwn15->v.re ), ImBr, pwn15->v.im ); move16(); BASOP_SATURATE_WARNING_OFF_EVS -#ifdef BASOP_NOGLOB tmpw15.v.re = msu_ro( L_mult( ptwiddle->v.re, pwn17i->v.im ), ptwiddle->v.im, pwn17i->v.re, &Overflow ); move16(); tmpw15.v.im = mac_ro( L_mult( ptwiddle->v.im, pwn17i->v.im ), ptwiddle->v.re, pwn17i->v.re, &Overflow ); move16(); -#else /* BASOP_NOGLOB */ - tmpw15.v.re = msu_r( L_mult( ptwiddle->v.re, pwn17i->v.im ), ptwiddle->v.im, pwn17i->v.re ); - tmpw15.v.im = mac_r( L_mult( ptwiddle->v.im, pwn17i->v.im ), ptwiddle->v.re, pwn17i->v.re ); -#endif BASOP_SATURATE_WARNING_ON_EVS RealOut[N / 2 - i] = msu_r( L_mac( L_mac( L_mult( ReAr, pwn17i->v.re ), ImAr, pwn17i->v.im ), ImBr, pwn15i->v.re ), ReBr, pwn15i->v.im ); move16(); @@ -1723,15 +1721,10 @@ void E_LPC_a_lsf_isf_conversion( Word16 *lpcCoeffs /*Qx*/, Word16 *lsf /*15Q16*/ Word16 ImAr = extract_h( L_sub( ImagFFT[i], ImagFFT[N / 2 - i] ) ); Word16 ImBr = extract_h( ( L_negate( L_add( ImagFFT[i], ImagFFT[N / 2 - i] ) ) ) ); BASOP_SATURATE_WARNING_OFF_EVS -#ifdef BASOP_NOGLOB tmpw15.v.re = mac_r_sat( L_mult( ptwiddle->v.im, pwn17->v.re ), ptwiddle->v.re, pwn17->v.im ); move16(); tmpw15.v.im = msu_r_sat( L_mult( ptwiddle->v.im, pwn17->v.im ), ptwiddle->v.re, pwn17->v.re ); move16(); -#else - tmpw15.v.re = mac_r( L_mult( ptwiddle->v.im, pwn17->v.re ), ptwiddle->v.re, pwn17->v.im ); - tmpw15.v.im = msu_r( L_mult( ptwiddle->v.im, pwn17->v.im ), ptwiddle->v.re, pwn17->v.re ); -#endif BASOP_SATURATE_WARNING_ON_EVS RealOut[i] = msu_r( L_msu( L_msu( L_mult( ReAr, pwn17->v.re ), ImAr, pwn17->v.im ), ReBr, pwn15->v.im ), ImBr, pwn15->v.re ); move16(); diff --git a/lib_com/lsf_dec_bfi_fx.c b/lib_com/lsf_dec_bfi_fx.c index 6292630af70ea7d15bd23afe34d9148ccc50db9d..33de5d9ac09d01ac656426a142cbec602cb610c9 100644 --- a/lib_com/lsf_dec_bfi_fx.c +++ b/lib_com/lsf_dec_bfi_fx.c @@ -36,7 +36,7 @@ void lsf_dec_bfi( const Word16 Last_GSC_pit_band_idx, const Word16 Opt_AMR_WB, /* i : IO flag */ const Word8 tcxonly, - const short bwidth /* i: coded bandwidth */ + const Word16 bwidth /* i: coded bandwidth */ ) { Word16 i; diff --git a/lib_com/lsf_tools_fx.c b/lib_com/lsf_tools_fx.c index 21857fd103a62a8ed20039fee4e56fa0c1e5238a..6437cc393c2d82d488fe5f6a373235bb0e53edbb 100644 --- a/lib_com/lsf_tools_fx.c +++ b/lib_com/lsf_tools_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other @@ -109,22 +109,14 @@ static Word16 chebyshev( Word16 x, Word32 *f, const Word16 n, const Word16 shift /* i = 5 */ t0 = Mpy_32_16_1( b2, x ); /* t0 = x*b1 */ if ( !cheb ) -#ifdef BASOP_NOGLOB t0 = L_shl_o( t0, 1, &Overflow ); /* t0 = 2*x*b1 */ -#else /* BASOP_NOGLOB */ - t0 = L_shl( t0, 1 ); /* t0 = 2*x*b1 */ -#endif /* BASOP_NOGLOB */ t0 = L_sub( t0, b1 ); /* t0 = 2*x*b1 - b2 */ b1 = L_add( t0, *f++ ); /* b0 = 2*x*b1 - b2 + f[i] */ /* i = 6 */ t0 = Mpy_32_16_1( b1, x ); /* t0 = x*b1 */ if ( !cheb ) -#ifdef BASOP_NOGLOB t0 = L_shl_o( t0, 1, &Overflow ); /* t0 = 2*x*b1 */ -#else /* BASOP_NOGLOB */ - t0 = L_shl( t0, 1 ); /* t0 = 2*x*b1 */ -#endif /* BASOP_NOGLOB */ t0 = L_sub( t0, b2 ); /* t0 = 2*x*b1 - b2 */ } /* IF (sub(n,8) == 0) */ @@ -134,11 +126,7 @@ static Word16 chebyshev( Word16 x, Word32 *f, const Word16 n, const Word16 shift /* i = 7 */ t0 = Mpy_32_16_1( b2, x ); /* t0 = x*b1 */ if ( !cheb ) -#ifdef BASOP_NOGLOB t0 = L_shl_o( t0, 1, &Overflow ); /* t0 = 2*x*b1 */ -#else /* BASOP_NOGLOB */ - t0 = L_shl( t0, 1 ); /* t0 = 2*x*b1 */ -#endif /* BASOP_NOGLOB */ t0 = L_sub( t0, b1 ); /* t0 = 2*x*b1 - b2 */ /*b1 = L_add(b2,0);*/ } @@ -158,13 +146,8 @@ static Word16 chebyshev( Word16 x, Word32 *f, const Word16 n, const Word16 shift BASOP_SATURATE_WARNING_OFF_EVS -#ifdef BASOP_NOGLOB t0 = L_shl_o( t0, shift, &Overflow ); /* Qx to Q30 with saturation */ cheb = round_fx_o( t0, &Overflow ); /* Result in Q14 */ -#else /* BASOP_NOGLOB */ - t0 = L_shl( t0, shift ); /* Qx to Q30 with saturation */ - cheb = round_fx( t0 ); /* Result in Q14 */ -#endif /* BASOP_NOGLOB */ cheb = s_max( -32767, cheb ); /* to avoid saturation */ BASOP_SATURATE_WARNING_ON_EVS return ( cheb ); @@ -303,11 +286,7 @@ void E_LPC_a_isp_conversion( const Word16 a[], Word16 isp[], const Word16 old_is * xint = xlow - ylow*(xhigh-xlow)/(yhigh-ylow) *--------------------------------------------------------*/ -#ifdef BASOP_NOGLOB y = sub_o( yhigh, ylow, &Overflow ); -#else - y = sub( yhigh, ylow ); -#endif IF( y != 0 ) { x = sub( xhigh, xlow ); @@ -466,15 +445,9 @@ void E_LPC_f_isp_a_conversion( const Word16 *isp, Word16 *a, const Word16 m ) BASOP_SATURATE_WARNING_OFF_EVS /*overflow handling in loop expression*/ -#ifdef BASOP_NOGLOB t0 = L_shl_o( t0, q, &Overflow ); t0n = L_sub_o( t0, 0x7FFFFFFF, &Overflow ); /*check for positive overflow*/ t0p = L_sub_o( t0, 0x80000000, &Overflow ); /*check for negative overflow*/ -#else /* BASOP_NOGLOB */ - t0 = L_shl( t0, q ); - t0n = L_sub( t0, 0x7FFFFFFF ); /*check for positive overflow*/ - t0p = L_sub( t0, 0x80000000 ); /*check for negative overflow*/ -#endif /* BASOP_NOGLOB */ BASOP_SATURATE_WARNING_ON_EVS q = sub( q, 1 ); /*decrease q in case of overflow*/ @@ -631,6 +604,153 @@ Word16 lpc2lsp_fx( return ( 1 ); } +#ifdef FIX_ISSUE_1165 +/*===================================================================*/ +/* FUNCTION : lpc2lsp_ivas_fx () */ +/*-------------------------------------------------------------------*/ +/* PURPOSE : Convert LPC coefficients to LSP coefficients */ +/*-------------------------------------------------------------------*/ +/* INPUT ARGUMENTS : */ +/* */ +/* _ (Word32 []) a : LPC coefficients, Q27 */ +/* _ (Word16 []) old_freq: Previous frame LSP coefficients, Q15 */ +/* _ (Word16 []) order: LPC order */ +/*-------------------------------------------------------------------*/ +/* OUTPUT ARGUMENTS : */ +/* _ (Word16 []) freq: LSP coefficients, Q15 */ +/*-------------------------------------------------------------------*/ +/* INPUT/OUTPUT ARGUMENTS : */ +/* _ None */ +/*-------------------------------------------------------------------*/ +/* RETURN ARGUMENTS : */ +/* _ (Word16) flag: 1 means all 10 LSPs are found, 0 otherwise */ +/*===================================================================*/ + +/*NOTE: This function was created to avoid a crash that happens in the*/ +/* first for loop of this function while performing L_shl on a in*/ +/* lpc2lsp_fx, this computation assigns value to Lacc, which is */ +/* kept in Q26 here to avoid L_shl when a has saturated value. */ +Word16 lpc2lsp_ivas_fx( + Word32 *a, + Word16 *freq, + Word16 *old_freq, + Word16 order ) +{ + Word16 i; + Word16 rt, low, high, prev_rt, rc; + Word32 p[11], q[11]; /* Q26 */ + Word32 Ltemp, v_low; + Word32 Lacc; + Word16 tfreq[21]; + + /* First construct the P,Q polynomial */ + /* p[0] = q[0] = 1 */ + /* p[i] = -lpcCoeff[i] - lpcCoeff[11-i] - p[i-1] ( 1<=i<=5)*/ + /* q[i] = -lpcCoeff[i] + lpcCoeff[11-i] + q[i-1] ( 1<=i<=5)*/ + Ltemp = L_deposit_h( 0x400 ); /* Ltemp is 1.0 in Q26 */ + + p[0] = Ltemp; + move32(); + q[0] = Ltemp; + move32(); + + FOR( i = 1; i < ( order / 2 ) + 1; i++ ) + { + Lacc = L_shr( a[order - i], 1 ); + move32(); /* Q26 */ + Lacc = L_sub( Lacc, L_shr( a[i - 1], 1 ) ); /* Lacc=-lpcCoeff[i-1] + lpcCoeff[order-i]//Q26 */ + q[i] = L_add( ( Lacc ), q[i - 1] ); + move32(); /* Q26 */ + + Lacc = L_add( Lacc, a[i - 1] ); /* Lacc=lpcCoeff[i-1] + lpcCoeff[order-i]//Q26 */ + + p[i] = L_sub( L_negate( Lacc ), p[i - 1] ); + move32(); /* Q26 */ + } + + /* Search roots of the P and Q polynomials */ + + v_low = polynomial_eval_fx( 0, p, order ); /* Q25 */ + move16(); + move16(); + move16(); + move16(); + low = 0; + high = 8; + prev_rt = 0; + rc = 0; /* root counter */ + FOR( i = 0; i < 32; i++ ) + { + rt = root_search_fx( low, high, &v_low, p, order ); + low = high; + move16(); + high = add( high, 8 ); + + IF( GE_16( rt, prev_rt ) ) + { + tfreq[rc] = rt; + move16(); + rc = add( rc, 2 ); + } + prev_rt = add( rt, 6 ); + } /* End for P roots */ + + tfreq[rc] = 0x3f80; + move16(); /* Set a high enough value as fake root for Q search */ + + IF( LT_16( rc, order ) ) + { + /* lost P root */ + /* copy from previous LSP and return */ + FOR( i = 0; i < order; i++ ) + { + move16(); + freq[i] = old_freq[i]; + } + return ( 0 ); + } + ELSE + { + /* Search for Q roots between P roots */ + v_low = L_deposit_h( 0x800 ); /* Init a positive value for v_low */ + rc = 1; + move16(); + FOR( i = 0; i < order / 2; i++ ) + { + low = shr( tfreq[rc - 1], 6 ); + high = add( shr( tfreq[rc + 1], 6 ), 1 ); + rt = root_search_fx( low, high, &v_low, q, order ); + + IF( rt < 0 ) + { + /* No Q root in this interval */ + /* copy from previous LSP and return */ + FOR( i = 0; i < order; i++ ) + { + move16(); + freq[i] = old_freq[i]; + } + return ( 0 ); + } + ELSE + { + move16(); + tfreq[rc] = rt; + rc = add( rc, 2 ); + } /* end else, find Q root */ + } /* end for */ + } /* end else */ + + FOR( i = 0; i < order; i++ ) + { + freq[i] = tfreq[i]; + move16(); + } + + return ( 1 ); +} +#endif + /*===================================================================*/ /* FUNCTION : lsp2lpc_fx () */ /*-------------------------------------------------------------------*/ @@ -683,11 +803,7 @@ void lsp2lpc_fx( move16(); FOR( i = 0; i < order / 2; i++ ) { -#ifdef BASOP_NOGLOB /* Critical Overflow */ Ltemp = L_add_o( pq[i], pq[i + 1], &Overflow ); -#else - Ltemp = L_add( pq[i], pq[i + 1] ); -#endif giOverflow = (Word16) Overflow; move16(); IF( EQ_16( giOverflow, 1 ) ) @@ -719,11 +835,7 @@ void lsp2lpc_fx( FOR( i = 0; i < order / 2; i++ ) { -#ifdef BASOP_NOGLOB /* Critical Overflow */ Ltemp = L_sub_o( pq[i + 1], pq[i], &Overflow ); -#else - Ltemp = L_sub( pq[i + 1], pq[i] ); -#endif giOverflow = (Word16) Overflow; move16(); IF( EQ_16( giOverflow, 1 ) ) @@ -749,11 +861,7 @@ void lsp2lpc_fx( { Overflow = 0; move16(); -#ifdef BASOP_NOGLOB /* Critical Overflow */ Lacc = L_add_o( p[i], q[i], &Overflow ); /* p[i], q[i] in Q24 */ -#else - Lacc = L_add( p[i], q[i] ); /* p[i], q[i] in Q24 */ -#endif if ( Overflow ) { giOverflow = 1; @@ -763,11 +871,7 @@ void lsp2lpc_fx( Lacc = L_negate( Lacc ); /* Lacc=-(p[i]-q[i])/2 in Q25 */ Overflow = 0; move16(); -#ifdef BASOP_NOGLOB /* Critical Overflow */ Lacc = L_add_o( L_shl_o( Lacc, 3, &Overflow ), 0x08000, &Overflow ); /* rounding */ -#else - Lacc = L_add( L_shl( Lacc, 3 ), 0x08000 ); /* rounding */ -#endif if ( Overflow ) { giOverflow = 1; @@ -785,11 +889,7 @@ void lsp2lpc_fx( { Overflow = 0; move16(); -#ifdef BASOP_NOGLOB /* Critical Overflow */ Lacc = L_sub_o( q[i], p[i], &Overflow ); /* p[i], q[i] in Q24 */ -#else - Lacc = L_sub( q[i], p[i] ); /* p[i], q[i] in Q24 */ -#endif if ( Overflow ) { giOverflow = 1; @@ -797,11 +897,7 @@ void lsp2lpc_fx( } Overflow = 0; move16(); -#ifdef BASOP_NOGLOB /* Critical Overflow */ Lacc = L_add_o( L_shl_o( Lacc, 3, &Overflow ), 0x08000, &Overflow ); /* rounding */ -#else - Lacc = L_add( L_shl( Lacc, 3 ), 0x08000 ); /* rounding */ -#endif if ( Overflow ) { giOverflow = 1; @@ -890,22 +986,13 @@ Word16 E_LPC_f_lsp_pol_get( const Word16 lsp[], Word32 f[], const Word16 n, cons Overflow = 0; move16(); plsp = lsp; -#ifdef BASOP_NOGLOB /* Critical Overflow and all those below*/ f[0] = L_shl_o( 1, sub( 31, Q_out ), &Overflow ); -#else - f[0] = L_shl( 1, sub( 31, Q_out ) ); -#endif move32(); /*b = -2.0f * *plsp;*/ b = *plsp; move16(); -#ifdef BASOP_NOGLOB /* Critical Overflow */ m2 = shl_o( -2, sub( 15, Q_out ), &Overflow ); f[1] = L_mult_o( b, m2, &Overflow ); -#else - m2 = shl( -2, sub( 15, Q_out ) ); - f[1] = L_mult( b, m2 ); -#endif move32(); FOR( i = 2; i <= n; i++ ) @@ -914,35 +1001,19 @@ Word16 E_LPC_f_lsp_pol_get( const Word16 lsp[], Word32 f[], const Word16 n, cons /*b = 2.0f * *plsp;*/ move16(); b = *plsp; -#ifdef BASOP_NOGLOB /* Critical Overflow */ b32 = L_mult_o( b, m2, &Overflow ); -#else - b32 = L_mult( b, m2 ); -#endif /*f[i] = -b*f[i-1] + 2.0f*f[i-2];*/ move32(); -#ifdef BASOP_NOGLOB /* Critical Overflow */ f[i] = L_shl_o( L_sub_o( f[i - 2], Mpy_32_16_1( f[i - 1], b ), &Overflow ), 1, &Overflow ); -#else - f[i] = L_shl( L_sub( f[i - 2], Mpy_32_16_1( f[i - 1], b ) ), 1 ); -#endif FOR( j = i - 1; j > 1; j-- ) { /*f[j] += b*f[j-1] + f[j-2];*/ move32(); -#ifdef BASOP_NOGLOB /* Critical Overflow */ f[j] = L_add_o( f[j], L_sub_o( f[j - 2], L_shl_o( Mpy_32_16_1( f[j - 1], b ), 1, &Overflow ), &Overflow ), &Overflow ); -#else - f[j] = L_add( f[j], L_sub( f[j - 2], L_shl( Mpy_32_16_1( f[j - 1], b ), 1 ) ) ); -#endif } move32(); -#ifdef BASOP_NOGLOB /* Critical Overflow */ f[1] = L_add_o( f[1], b32, &Overflow ); -#else - f[1] = L_add( f[1], b32 ); -#endif } @@ -1186,11 +1257,7 @@ void E_LPC_f_lsp_a_conversion( const Word16 *lsp, Word16 *a, const Word16 m ) { f1[nc - i] = L_add( f1[nc - i], f1[nc - i - 1] ); move32(); -#ifdef BASOP_NOGLOB f2[nc - i] = L_sub_o( f2[nc - i], f2[nc - i - 1], &Overflow ); -#else - f2[nc - i] = L_sub( f2[nc - i], f2[nc - i - 1] ); -#endif move32(); } @@ -1202,13 +1269,8 @@ void E_LPC_f_lsp_a_conversion( const Word16 *lsp, Word16 *a, const Word16 m ) t0 = L_deposit_l( 0 ); FOR( i = 1; i <= nc; i++ ) { -#ifdef BASOP_NOGLOB t0 = L_max( t0, L_abs( L_add_o( f1[i], f2[i], &Overflow ) ) ); t0 = L_max( t0, L_abs( L_sub_o( f1[i], f2[i], &Overflow ) ) ); -#else - t0 = L_max( t0, L_abs( L_add( f1[i], f2[i] ) ) ); - t0 = L_max( t0, L_abs( L_sub( f1[i], f2[i] ) ) ); -#endif } k = s_min( norm_l( t0 ), 6 ); a[0] = shl( 256, k ); @@ -1223,30 +1285,14 @@ void E_LPC_f_lsp_a_conversion( const Word16 *lsp, Word16 *a, const Word16 m ) FOR( i = 1; i <= nc; i++ ) { /* a[i] = 0.5*(f1[i] + f2[i]) */ -#ifdef BASOP_NOGLOB t0 = L_add_o( f1[i], f2[i], &Overflow ); -#else - t0 = L_add( f1[i], f2[i] ); -#endif t0 = L_shl( t0, k ); -#ifdef BASOP_NOGLOB a[i] = round_fx_o( t0, &Overflow ); /* from Q23 to Qx and * 0.5 */ -#else - a[i] = round_fx( t0 ); /* from Q23 to Qx and * 0.5 */ -#endif /* a[j] = 0.5*(f1[i] - f2[i]) */ -#ifdef BASOP_NOGLOB t0 = L_sub_o( f1[i], f2[i], &Overflow ); -#else - t0 = L_sub( f1[i], f2[i] ); -#endif t0 = L_shl( t0, k ); -#ifdef BASOP_NOGLOB a[j] = round_fx_o( t0, &Overflow ); /* from Q23 to Qx and * 0.5 */ -#else - a[j] = round_fx( t0 ); /* from Q23 to Qx and * 0.5 */ -#endif j--; } @@ -1459,6 +1505,80 @@ void lsp_weights_fx( move16(); } +void lsp_weights_ivas_fx( + Word16 lsp_nq_fx[], + Word16 w[], + Word16 Order, + Word16 *Qout ) +{ + Word16 i; + Word16 q_weight[20]; + Word32 weight[20]; + Word16 delta1, delta2; + Word32 L_tmp; + Word16 q_min; + + delta1 = lsp_nq_fx[0]; // Q15 + move16(); + delta2 = sub( lsp_nq_fx[1], lsp_nq_fx[0] ); // Q15 + + L_tmp = L_mult0( delta1, delta2 ); // Q30 // Q30 + L_tmp = root_a_over_b_ivas_fx( ALPHA_SQ_Q30, Q30, L_tmp, Q30, &q_weight[0] ); // q_weight[0] + + weight[0] = Mpy_32_16_1( L_tmp, 32000 /* 250 in Q7*/ ); // q_weight[0]-8 + q_weight[0] = sub( q_weight[0], 8 ); + move32(); + move16(); + + q_min = q_weight[0]; + move16(); + + FOR( i = 1; i < Order - 1; i++ ) + { + delta1 = sub( lsp_nq_fx[i], lsp_nq_fx[i - 1] ); // Q15 + delta2 = sub( lsp_nq_fx[i + 1], lsp_nq_fx[i] ); // Q15 + + L_tmp = L_mult0( delta1, delta2 ); // Q30 + L_tmp = root_a_over_b_ivas_fx( ALPHA_SQ_Q30, Q30, L_tmp, Q30, &q_weight[i] ); // q_weight[i] + + weight[i] = Mpy_32_16_1( L_tmp, 32000 /* 250 in Q7*/ ); // q_weight[i] + q_weight[i] = sub( q_weight[i], 8 ); + move32(); + move16(); + + q_min = s_min( q_min, q_weight[i] ); + } + delta1 = sub( lsp_nq_fx[i], lsp_nq_fx[i - 1] ); // Q15 + delta2 = sub( 16384 /* 0.5 in Q15*/, lsp_nq_fx[i] ); // Q15 + + L_tmp = L_mult0( delta1, delta2 ); // Q30 + L_tmp = root_a_over_b_ivas_fx( ALPHA_SQ_Q30, Q30, L_tmp, Q30, &q_weight[i] ); // q_weight[i] + + weight[i] = Mpy_32_16_1( L_tmp, 32000 /* 250 in Q7*/ ); // q_weight[i] + q_weight[i] = sub( q_weight[i], 8 ); + move32(); + move16(); + + q_min = s_min( q_min, q_weight[i] ); + + FOR( i = 0; i < Order; i++ ) + { + w[i] = round_fx( L_shl( weight[i], sub( q_min, q_weight[i] ) ) ); /* q_min-16 */ + move16(); + } + + IF( Order != LPC_SHB_ORDER_WB ) + { + w[3] = round_fx( L_shl( L_mult( w[3], 18022 ), 1 ) ); /* q_min-16 */ + w[4] = round_fx( L_shl( L_mult( w[4], 18022 ), 1 ) ); /* q_min-16 */ + move16(); + move16(); + } + + *Qout = sub( q_min, 16 ); + move16(); +} + /* * E_LPC_isf_isp_conversion * @@ -1678,41 +1798,23 @@ void a2rc_fx( const Word16 *a, /* i: can be any Q */ FOR( j = 0; j < m / 2; j++ ) { n = sub( sub( m, (Word16) 1 ), j ); - L_tmp1 = L_mult( denom_mant, f_fx[j] ); /* denom*f[j]. Q15*Q12 = Q28 (floating with exp) */ -#ifdef BASOP_NOGLOB + L_tmp1 = L_mult( denom_mant, f_fx[j] ); /* denom*f[j]. Q15*Q12 = Q28 (floating with exp) */ L_tmp1 = L_mac_o( L_tmp1, tmp, f_fx[n], &Overflow ); /* denom*f[j]+km*denom*f[n] in Q28 (floating with exp) */ -#else - L_tmp1 = L_mac( L_tmp1, tmp, f_fx[n] ); /* denom*f[j]+km*denom*f[n] in Q28 (floating with exp) */ -#endif - L_tmp2 = L_mult( denom_mant, f_fx[n] ); /* denom*f[n]. Q15*Q12 = Q28 (floating with exp) */ -#ifdef BASOP_NOGLOB + L_tmp2 = L_mult( denom_mant, f_fx[n] ); /* denom*f[n]. Q15*Q12 = Q28 (floating with exp) */ L_tmp2 = L_mac_o( L_tmp2, tmp, f_fx[j], &Overflow ); /* denom*f[n]+km*denom*f[j] in Q28 (floating with exp) */ L_tmp1 = L_shr_o( L_tmp1, exp, &Overflow ); /* bringing to true Q28 */ L_tmp2 = L_shr_o( L_tmp2, exp, &Overflow ); /* bringing to true Q28 */ f_fx[j] = round_fx_o( L_tmp1, &Overflow ); /* extracting in q_a */ f_fx[n] = round_fx_o( L_tmp2, &Overflow ); /* extracting in q_a */ -#else - L_tmp2 = L_mac( L_tmp2, tmp, f_fx[j] ); /* denom*f[n]+km*denom*f[j] in Q28 (floating with exp) */ - L_tmp1 = L_shr( L_tmp1, exp ); /* bringing to true Q28 */ - L_tmp2 = L_shr( L_tmp2, exp ); /* bringing to true Q28 */ - f_fx[j] = round_fx( L_tmp1 ); /* extracting in q_a */ - f_fx[n] = round_fx( L_tmp2 ); /* extracting in q_a */ -#endif } IF( m & 1 ) { - L_tmp1 = L_mult( denom_mant, f_fx[j] ); /* denom*f[j]. Q15*Q12 = Q28 (floating with exp) */ -#ifdef BASOP_NOGLOB + L_tmp1 = L_mult( denom_mant, f_fx[j] ); /* denom*f[j]. Q15*Q12 = Q28 (floating with exp) */ L_tmp1 = L_mac_o( L_tmp1, tmp, f_fx[j], &Overflow ); /* denom*f[j]+km*denom*f[j] in Q28 (floating with exp) */ L_tmp1 = L_shr_o( L_tmp1, exp, &Overflow ); /* bringing to true Q28 */ f_fx[j] = round_fx_o( L_tmp1, &Overflow ); /* extracting in q_a */ move16(); -#else - L_tmp1 = L_mac( L_tmp1, tmp, f_fx[j] ); /* denom*f[j]+km*denom*f[j] in Q28 (floating with exp) */ - L_tmp1 = L_shr( L_tmp1, exp ); /* bringing to true Q28 */ - f_fx[j] = round_fx( L_tmp1 ); /* extracting in q_a */ -#endif } } @@ -2211,18 +2313,10 @@ Word16 lsf_stab_fx( /* o : LP filter stability Q15*/ } e = sub( 30 - 21 - 1, e ); -#ifdef BASOP_NOGLOB tmp = round_fx_o( L_shl_o( L_tmp, e, &Overflow ), &Overflow ); /*Q14*/ -#else /* BASOP_NOGLOB */ - tmp = round_fx( L_shl( L_tmp, e ) ); /*Q14*/ -#endif /* BASOP_NOGLOB */ - tmp = sub( 20480, tmp ); /* 1.25 - tmp in Q14 */ -#ifdef BASOP_NOGLOB + tmp = sub( 20480, tmp ); /* 1.25 - tmp in Q14 */ tmp = shl_o( tmp, 1, &Overflow ); /* Q14 -> Q15 with saturation */ -#else /* BASOP_NOGLOB */ - tmp = shl( tmp, 1 ); /* Q14 -> Q15 with saturation */ -#endif tmp = s_max( tmp, 0 ); @@ -2312,20 +2406,12 @@ Word16 lsf_stab_ivas_fx( /* o : LP filter stability } e = sub( 30 - 21 - 1, e ); -#ifdef BASOP_NOGLOB tmp = round_fx_o( L_shl_o( L_tmp, e, &Overflow ), &Overflow ); /*Q12*/ -#else /* BASOP_NOGLOB */ - tmp = round_fx( L_shl( L_tmp, e ) ); /*Q14*/ -#endif /* BASOP_NOGLOB */ // tmp = sub(20480, tmp); /* 1.25 - tmp in Q14 */ tmp = sub( 5120, tmp ); /* 1.25 - tmp in Q12 */ -#ifdef BASOP_NOGLOB // tmp = shl_o(tmcp, 1, &Overflow); /* Q14 -> Q15 with saturation */ tmp = shl_sat( tmp, 3 ); /* Q12 -> Q15 with saturation */ -#else /* BASOP_NOGLOB */ - tmp = shl( tmp, 1 ); /* Q14 -> Q15 with saturation */ -#endif tmp = s_max( tmp, 0 ); @@ -2547,11 +2633,7 @@ void lsf2lsp_fx( { offset = negate( offset ); } -#ifdef BASOP_NOGLOB L_tmp = L_mult( sub_sat( offset, lsf_tmp ), round_fx( L_shl( L_and( L_tmp, 0xFFFF ), 15 ) ) ); -#else - L_tmp = L_mult( sub( offset, lsf_tmp ), round_fx( L_shl( L_and( L_tmp, 0xFFFF ), 15 ) ) ); -#endif L_tmp = L_msu( L_tmp, lsf_tmp, -32768 ); lsp[i] = round_fx( L_tmp ); } @@ -3324,10 +3406,6 @@ void msvq_dec( maxn = n; move16(); } - if ( maxn % 4 ) - { - n = n; - } assert( ( maxn % 4 ) == 0 ); N34 = mult( maxn, 24576 /*0.75 Q15*/ ); @@ -3828,13 +3906,9 @@ Word16 root_search_fx( Word16 low, L_tmp1 = L_shl( L_tmp, exp1 ); tmp = extract_h( L_tmp1 ); exp1 = sub( 30 - 25, exp1 ); - tmp = div_s( 16384, tmp ); /* 15+exp1 */ - Ltmp = Mult_32_16( *v_low, tmp ); /* 15+exp1+25-15 */ -#ifdef BASOP_NOGLOB + tmp = div_s( 16384, tmp ); /* 15+exp1 */ + Ltmp = Mult_32_16( *v_low, tmp ); /* 15+exp1+25-15 */ Ltemp = L_shl_o( Ltmp, ( 6 - exp1 ), &Overflow ); /* Q31 */ -#else - Ltemp = L_shl( Ltmp, ( 6 - exp1 ) ); /* Q31 */ -#endif if ( LT_32( *v_low, vh ) ) { Ltemp = L_negate( Ltemp ); @@ -4286,7 +4360,7 @@ void dctT2_N_apply_matrix_fx( *pt_y = L_add( *pt_y, Mpy_32_32( ( *pt_x++ ), ( *pt_A ) ) ); move32(); pt_A += mat_step_col; /* step +maxtrunc or +1 */ /* ptr indexing*/ - MAC( 1 ); + MAC_C( 1 ); #undef WMC_TOOL_SKIP } pt_y++; @@ -4338,7 +4412,7 @@ void extend_dctN_input_fx( ext_sig[i] = L_add( ext_sig[i], Mpy_32_32( dct_input[j], ptr[i_rev][j] ) ); /* sum up scaled and extended basis vector */ // Q31 + Q - Q31 -> Q move32(); - MAC( 1 ); + MAC_C( 1 ); #undef WMC_TOOL_SKIP } } diff --git a/lib_com/lsp_conv_poly_fx.c b/lib_com/lsp_conv_poly_fx.c index 6c2c5552037189d3b9d500cc0d22f1e56dc4dc6e..4f493cacde1c222cba29c4859e08beb17776da29 100644 --- a/lib_com/lsp_conv_poly_fx.c +++ b/lib_com/lsp_conv_poly_fx.c @@ -6,10 +6,9 @@ #include "options.h" #include "cnst.h" #include "rom_com.h" -#include "prot.h" +#include "prot_fx.h" #include "wmc_auto.h" -#include "prot_fx.h" /*-------------------------------------------------------------------* * Local constants @@ -346,18 +345,10 @@ static Word32 b_inv_sq( exp_den = add( sub( 30, exp_den ), sub( 16, exp_in ) ); m_den = mult_r( m_den, m_den ); -#ifdef BASOP_NOGLOB exp_den = shl_o( exp_den, 1, &Overflow ); -#else /* BASOP_NOGLOB */ - exp_den = shl( exp_den, 1 ); -#endif /* BASOP_NOGLOB */ div_out = div_s( 8192, m_den ); -#ifdef BASOP_NOGLOB Ltmp = L_shl_o( div_out, add( sub( 30 - 13, exp_den ), 15 ), &Overflow ); /*Q15*/ -#else /* BASOP_NOGLOB */ - Ltmp = L_shl( div_out, add( sub( 30 - 13, exp_den ), 15 ) ); /*Q15*/ -#endif /* BASOP_NOGLOB */ return Ltmp; } @@ -387,11 +378,7 @@ static Word32 inv_pow( { exp1 = norm_l( re ); tmp = extract_h( L_shl( re, exp1 ) ); -#ifdef BASOP_NOGLOB L_tmp = L_shr( L_mult_o( tmp, tmp, &Overflow ), 1 ); -#else /* BASOP_NOGLOB */ - L_tmp = L_shr( L_mult( tmp, tmp ), 1 ); -#endif /* BASOP_NOGLOB */ Mpy_32_16_ss( L_tmp, x, &mh, &ml ); r0 = L_add( L_tmp, mh ); } @@ -406,11 +393,7 @@ static Word32 inv_pow( { exp2 = norm_l( se ); tmp = extract_h( L_shl( se, exp2 ) ); -#ifdef BASOP_NOGLOB L_tmp = L_shr( L_mult_o( tmp, tmp, &Overflow ), 1 ); -#else /* BASOP_NOGLOB */ - L_tmp = L_shr( L_mult( tmp, tmp ), 1 ); -#endif /* BASOP_NOGLOB */ Mpy_32_16_ss( L_tmp, x, &mh, &ml ); s0 = L_sub( L_tmp, mh ); } @@ -440,11 +423,7 @@ static Word32 inv_pow( } tmp = div_s( (Word16) ( ( 1 << 14 ) - 1 ), tmp ); exp1 = add( exp1, exp2 ); -#ifdef BASOP_NOGLOB L_tmp = L_shr_o( tmp, sub( 31, exp1 ), &Overflow ); /* result in Q15 */ -#else /* BASOP_NOGLOB */ - L_tmp = L_shr( tmp, sub( 31, exp1 ) ); /* result in Q15 */ -#endif /* BASOP_NOGLOB */ return ( L_tmp ); } @@ -546,11 +525,7 @@ static void spectautocorr_fx( move32(); FOR( i = 2; i < N - 1; i++ ) { -#ifdef BASOP_NOGLOB r[0] = L_add_o( r[0], G[i], &Overflow ); -#else /* BASOP_NOGLOB */ - r[0] = L_add( r[0], G[i] ); -#endif /* BASOP_NOGLOB */ move32(); } @@ -584,20 +559,12 @@ static void spectautocorr_fx( move16(); /* 1.0 in Q15 */ FOR( i = 1; i < imid; i++ ) { -#ifdef BASOP_NOGLOB gp = L_add_o( G[i], G[N - i - 1], &Overflow ); -#else /* BASOP_NOGLOB */ - gp = L_add( G[i], G[N - i - 1] ); -#endif /* BASOP_NOGLOB */ gn = L_sub( G[i], G[N - i - 1] ); /*r[1] = L_mac(r[1], x[i-1], gn);*/ Mpy_32_16_ss( gn, x[i - 1], &mh, &ml ); -#ifdef BASOP_NOGLOB r[1] = L_add_o( r[1], mh, &Overflow ); -#else - r[1] = L_add( r[1], mh ); -#endif move32(); c[1] = x[i - 1]; move16(); @@ -606,55 +573,31 @@ static void spectautocorr_fx( { c[j] = mult_r( c[j - 1], x[i - 1] ); move16(); -#ifdef BASOP_NOGLOB c[j] = add_o( c[j], sub_o( c[j], c[j - 2], &Overflow ), &Overflow ); -#else /* BASOP_NOGLOB */ - c[j] = add( c[j], sub( c[j], c[j - 2] ) ); -#endif /* BASOP_NOGLOB */ move16(); /*r[j] = L_mac(r[j], c[j], gp);*/ Mpy_32_16_ss( gp, c[j], &mh, &ml ); -#ifdef BASOP_NOGLOB r[j] = L_add_o( r[j], mh, &Overflow ); -#else /* BASOP_NOGLOB */ - r[j] = L_add( r[j], mh ); -#endif /* BASOP_NOGLOB */ move32(); c[j + 1] = mult_r( c[j], x[i - 1] ); move16(); -#ifdef BASOP_NOGLOB c[j + 1] = add_o( c[j + 1], sub_o( c[j + 1], c[j - 1], &Overflow ), &Overflow ); -#else /* BASOP_NOGLOB */ - c[j + 1] = add( c[j + 1], sub( c[j + 1], c[j - 1] ) ); -#endif /* BASOP_NOGLOB */ move16(); /*r[j+1] = L_mac(r[j+1], c[j+1], gn);*/ Mpy_32_16_ss( gn, c[j + 1], &mh, &ml ); -#ifdef BASOP_NOGLOB r[j + 1] = L_add_o( r[j + 1], mh, &Overflow ); -#else /* BASOP_NOGLOB */ - r[j + 1] = L_add( r[j + 1], mh ); -#endif /* BASOP_NOGLOB */ move32(); } c[j] = mult_r( c[j - 1], x[i - 1] ); move16(); -#ifdef BASOP_NOGLOB c[j] = add_o( c[j], sub_o( c[j], c[j - 2], &Overflow ), &Overflow ); -#else /* BASOP_NOGLOB */ - c[j] = add( c[j], sub( c[j], c[j - 2] ) ); -#endif /* BASOP_NOGLOB */ move16(); Mpy_32_16_ss( gp, c[j], &mh, &ml ); -#ifdef BASOP_NOGLOB r[j] = L_add_o( r[j], mh, &Overflow ); -#else /* BASOP_NOGLOB */ - r[j] = L_add( r[j], mh ); -#endif /* BASOP_NOGLOB */ move32(); } @@ -662,31 +605,18 @@ static void spectautocorr_fx( * Add the endpoints x = cos(0) = 1 and x = cos(pi) = -1 as * well as the lower half of the unit circle. *---------------------------------------------------------------------*/ -#ifdef BASOP_NOGLOB gp = L_shr( L_add_o( G[0], G[N - 1], &Overflow ), 1 ); -#else /* BASOP_NOGLOB */ - gp = L_shr( L_add( G[0], G[N - 1] ), 1 ); -#endif /* BASOP_NOGLOB */ gn = L_shr( L_sub( G[0], G[N - 1] ), 1 ); -#ifdef BASOP_NOGLOB r[0] = L_add_o( r[0], gp, &Overflow ); -#else /* BASOP_NOGLOB */ - r[0] = L_add( r[0], gp ); -#endif /* BASOP_NOGLOB */ move32(); exp0 = norm_l( r[0] ); L_Extract( L_shl( r[0], exp0 ), &rh[0], &rl[0] ); FOR( j = 1; j < M; j += 2 ) { -#ifdef BASOP_NOGLOB L_Extract( L_shl( L_add_o( r[j], gn, &Overflow ), exp0 ), &rh[j], &rl[j] ); L_Extract( L_shl( L_add_o( r[j + 1], gp, &Overflow ), exp0 ), &rh[j + 1], &rl[j + 1] ); -#else /* BASOP_NOGLOB */ - L_Extract( L_shl( L_add( r[j], gn ), exp0 ), &rh[j], &rl[j] ); - L_Extract( L_shl( L_add( r[j + 1], gp ), exp0 ), &rh[j + 1], &rl[j + 1] ); -#endif } return; diff --git a/lib_com/math_op.c b/lib_com/math_op.c index ea0a7ef6cbb808a2979725570cd532101007b6b7..7014988b887944d6c9417a15c0d07363e7245c79 100644 --- a/lib_com/math_op.c +++ b/lib_com/math_op.c @@ -169,7 +169,6 @@ Word32 Pow2( /* (o) Q0 : result (range: 0<=val<=0x7fffff |___________________________________________________________________________| */ -#ifdef BASOP_NOGLOB Word32 Dot_product12_o( /* (o) Q31: normalized result (1 < val <= -1) */ const Word16 x[], /* (i) 12bits: x vector */ const Word16 y[], /* (i) 12bits: y vector */ @@ -177,33 +176,15 @@ Word32 Dot_product12_o( /* (o) Q31: normalized result (1 < va Word16 *exp, /* (o) : exponent of result (0..+30) */ Flag *Overflow_out /* o : propagating the Overflow flag to upper level, set to NULL to ignore internal overflows */ ) -#else /* BASOP_NOGLOB */ -Word32 Dot_product12( /* (o) Q31: normalized result (1 < val <= -1) */ - const Word16 x[], /* (i) 12bits: x vector */ - const Word16 y[], /* (i) 12bits: y vector */ - const Word16 lg, /* (i) : vector length */ - Word16 *exp /* (o) : exponent of result (0..+30) */ -) -#endif /* BASOP_NOGLOB */ { Word16 i, sft; Word32 L_sum; -#ifdef BASOP_NOGLOB Flag Overflow_ignored = 0; -#endif /* BASOP_NOGLOB */ -#ifdef BASOP_NOGLOB L_sum = L_mac_o( 1, x[0], y[0], &Overflow_ignored ); -#else - L_sum = L_mac( 1, x[0], y[0] ); -#endif FOR( i = 1; i < lg; i++ ) { -#ifdef BASOP_NOGLOB L_sum = L_mac_o( L_sum, x[i], y[i], Overflow_out ? Overflow_out : &Overflow_ignored ); -#else /* BASOP_NOGLOB */ - L_sum = L_mac( L_sum, x[i], y[i] ); -#endif /* BASOP_NOGLOB */ } /* Normalize acc in Q31 */ @@ -217,7 +198,6 @@ Word32 Dot_product12( /* (o) Q31: normalized result (1 < val < return L_sum; } -#ifdef BASOP_NOGLOB Word32 Dot_product12( /* (o) Q31: normalized result (1 < val <= -1) */ const Word16 x[], /* (i) 12bits: x vector */ const Word16 y[], /* (i) 12bits: y vector */ @@ -228,7 +208,6 @@ Word32 Dot_product12( /* (o) Q31: normalized result (1 < val < /* Ignore internal overflows */ return Dot_product12_o( x, y, lg, exp, NULL ); } -#endif /* BASOP_NOGLOB */ /*___________________________________________________________________________ | | @@ -258,18 +237,10 @@ Word32 Energy_scale( /* (o) : Q31: normalized result (1 < val IF( expi == 0 ) { -#ifdef BASOP_NOGLOB L_sum = L_mac_o( 1, x[0], x[0], &Overflow ); -#else - L_sum = L_mac( 1, x[0], x[0] ); -#endif FOR( i = 1; i < lg; i++ ) { -#ifdef BASOP_NOGLOB L_sum = L_mac_o( L_sum, x[i], x[i], &Overflow ); -#else /* BASOP_NOGLOB */ - L_sum = L_mac( L_sum, x[i], x[i] ); -#endif } } IF( expi < 0 ) @@ -280,16 +251,11 @@ Word32 Energy_scale( /* (o) : Q31: normalized result (1 < val FOR( i = 1; i < lg; i++ ) { tmp = mult_r( x[i], sft ); -#ifdef BASOP_NOGLOB L_sum = L_mac_o( L_sum, tmp, tmp, &Overflow ); -#else - L_sum = L_mac( L_sum, tmp, tmp ); -#endif } } IF( expi > 0 ) { -#ifdef BASOP_NOGLOB tmp = shl_o( x[0], expi, &Overflow ); L_sum = L_mac_o( 1, tmp, tmp, &Overflow ); FOR( i = 1; i < lg; i++ ) @@ -297,15 +263,6 @@ Word32 Energy_scale( /* (o) : Q31: normalized result (1 < val tmp = shl_o( x[i], expi, &Overflow ); L_sum = L_mac_o( L_sum, tmp, tmp, &Overflow ); } -#else - tmp = shl( x[0], expi ); - L_sum = L_mac( 1, tmp, tmp ); - FOR( i = 1; i < lg; i++ ) - { - tmp = shl( x[i], expi ); - L_sum = L_mac( L_sum, tmp, tmp ); - } -#endif } /* Normalize acc in Q31 */ diff --git a/lib_com/mime.h b/lib_com/mime.h index 80d984617615fe5122fe62b9fe478058eb2de6c0..6e9e5fc87f48c20b650b2872fcf0401ec05bcbfa 100644 --- a/lib_com/mime.h +++ b/lib_com/mime.h @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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_com/modif_fs.c b/lib_com/modif_fs.c index 06119b69e7edaf177945cdcf64adaa37177b2afc..7ed3cb59b62389a3fa6166306cc6d632a9d44885 100644 --- a/lib_com/modif_fs.c +++ b/lib_com/modif_fs.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other @@ -38,10 +38,9 @@ #include "options.h" #include #include "cnst.h" -#include "prot.h" +#include "prot_fx.h" #include "rom_com.h" #include "wmc_auto.h" -#include "prot_fx.h" void Interpolate_allpass_steep_32( @@ -115,6 +114,22 @@ void Decimate_allpass_steep_fx32( /* upper allpass filter chain */ FOR( k = 0; k < N / 2; k++ ) { +#ifdef OPT_STEREO_32KBPS_V1 + temp[0] = Madd_32_16( mem[0], in[2 * k], AP1_STEEP_FX[0] ); // Qx + move32(); + mem[0] = Msub_32_16( in[2 * k], temp[0], AP1_STEEP_FX[0] ); // Qx + move32(); + + temp[1] = Madd_32_16( mem[1], temp[0], AP1_STEEP_FX[1] ); // Qx + move32(); + mem[1] = Msub_32_16( temp[0], temp[1], AP1_STEEP_FX[1] ); // Qx + move32(); + + out[k] = Madd_32_16( mem[ALLPASSSECTIONS_STEEP - 1], temp[ALLPASSSECTIONS_STEEP - 2], AP1_STEEP_FX[ALLPASSSECTIONS_STEEP - 1] ); // Qx + move32(); + mem[ALLPASSSECTIONS_STEEP - 1] = Msub_32_16( temp[ALLPASSSECTIONS_STEEP - 2], out[k], AP1_STEEP_FX[ALLPASSSECTIONS_STEEP - 1] ); // Qx + move32(); +#else /* OPT_STEREO_32KBPS_V1 */ temp[0] = L_add( mem[0], Mpy_32_16_1( in[2 * k], AP1_STEEP_FX[0] ) ); // Qx move32(); mem[0] = L_sub( in[2 * k], Mpy_32_16_1( temp[0], AP1_STEEP_FX[0] ) ); // Qx @@ -129,17 +144,31 @@ void Decimate_allpass_steep_fx32( move32(); mem[ALLPASSSECTIONS_STEEP - 1] = L_sub( temp[ALLPASSSECTIONS_STEEP - 2], Mpy_32_16_1( out[k], AP1_STEEP_FX[ALLPASSSECTIONS_STEEP - 1] ) ); // Qx move32(); +#endif /* OPT_STEREO_32KBPS_V1 */ } /* lower allpass filter chain */ +#ifdef OPT_STEREO_32KBPS_V1 + temp[0] = Madd_32_16( mem[ALLPASSSECTIONS_STEEP], mem[2 * ALLPASSSECTIONS_STEEP], AP2_STEEP_FX[0] ); // Qx + move32(); + mem[ALLPASSSECTIONS_STEEP] = Msub_32_16( mem[2 * ALLPASSSECTIONS_STEEP], temp[0], AP2_STEEP_FX[0] ); // Qx + move32(); +#else /* OPT_STEREO_32KBPS_V1 */ temp[0] = L_add( mem[ALLPASSSECTIONS_STEEP], Mpy_32_16_1( mem[2 * ALLPASSSECTIONS_STEEP], AP2_STEEP_FX[0] ) ); // Qx move32(); mem[ALLPASSSECTIONS_STEEP] = L_sub( mem[2 * ALLPASSSECTIONS_STEEP], Mpy_32_16_1( temp[0], AP2_STEEP_FX[0] ) ); // Qx move32(); +#endif /* OPT_STEREO_32KBPS_V1 */ /* for better performance, unroll this loop */ FOR( n = 1; n < ALLPASSSECTIONS_STEEP - 1; n++ ) { +#ifdef OPT_STEREO_32KBPS_V1 + temp[n] = Madd_32_16( mem[ALLPASSSECTIONS_STEEP + n], temp[n - 1], AP2_STEEP_FX[n] ); // Qx + move32(); + mem[ALLPASSSECTIONS_STEEP + 1] = Msub_32_16( temp[n - 1], temp[n], AP2_STEEP_FX[n] ); // Qx + move32(); +#else /* OPT_STEREO_32KBPS_V1 */ temp[n] = L_add( mem[ALLPASSSECTIONS_STEEP + n], Mpy_32_16_1( temp[n - 1], AP2_STEEP_FX[n] ) ); // Qx move32(); /*if ( fabs( temp[n] ) < 1e-12 ) @@ -148,26 +177,48 @@ void Decimate_allpass_steep_fx32( }*/ mem[ALLPASSSECTIONS_STEEP + 1] = L_sub( temp[n - 1], Mpy_32_16_1( temp[n], AP2_STEEP_FX[n] ) ); // Qx move32(); +#endif /* OPT_STEREO_32KBPS_V1 */ } +#ifdef OPT_STEREO_32KBPS_V1 + temp[ALLPASSSECTIONS_STEEP - 1] = Madd_32_16( mem[2 * ALLPASSSECTIONS_STEEP - 1], temp[ALLPASSSECTIONS_STEEP - 2], AP2_STEEP_FX[ALLPASSSECTIONS_STEEP - 1] ); // Qx + move32(); + + mem[2 * ALLPASSSECTIONS_STEEP - 1] = Msub_32_16( temp[ALLPASSSECTIONS_STEEP - 2], temp[ALLPASSSECTIONS_STEEP - 1], AP2_STEEP_FX[ALLPASSSECTIONS_STEEP - 1] ); // Qx + move32(); +#else /* OPT_STEREO_32KBPS_V1 */ temp[ALLPASSSECTIONS_STEEP - 1] = L_add( mem[2 * ALLPASSSECTIONS_STEEP - 1], Mpy_32_16_1( temp[ALLPASSSECTIONS_STEEP - 2], AP2_STEEP_FX[ALLPASSSECTIONS_STEEP - 1] ) ); // Qx move32(); mem[2 * ALLPASSSECTIONS_STEEP - 1] = L_sub( temp[ALLPASSSECTIONS_STEEP - 2], Mpy_32_16_1( temp[ALLPASSSECTIONS_STEEP - 1], AP2_STEEP_FX[ALLPASSSECTIONS_STEEP - 1] ) ); // Qx move32(); +#endif /* OPT_STEREO_32KBPS_V1 */ out[0] = W_round48_L( W_mac_32_16( W_mult_32_16( out[0], 16384 /*0.5 in Q15*/ ), temp[ALLPASSSECTIONS_STEEP - 1], 16384 /*0.5 in Q15*/ ) ); // Qx move32(); FOR( k = 1; k < N / 2; k++ ) { +#ifdef OPT_STEREO_32KBPS_V1 + temp[0] = Madd_32_16( mem[ALLPASSSECTIONS_STEEP], in[2 * k - 1], AP2_STEEP_FX[0] ); // Qx + move32(); + mem[ALLPASSSECTIONS_STEEP] = Msub_32_16( in[2 * k - 1], temp[0], AP2_STEEP_FX[0] ); // Qx + move32(); +#else /* OPT_STEREO_32KBPS_V1 */ temp[0] = L_add( mem[ALLPASSSECTIONS_STEEP], Mpy_32_16_1( in[sub( shl( k, 1 ), 1 )], AP2_STEEP_FX[0] ) ); // Qx move32(); mem[ALLPASSSECTIONS_STEEP] = L_sub( in[sub( shl( k, 1 ), 1 )], Mpy_32_16_1( temp[0], AP2_STEEP_FX[0] ) ); // Qx move32(); +#endif /* OPT_STEREO_32KBPS_V1 */ /* for better performance, unroll this loop */ FOR( n = 1; n < ALLPASSSECTIONS_STEEP - 1; n++ ) { +#ifdef OPT_STEREO_32KBPS_V1 + temp[n] = Madd_32_16( mem[ALLPASSSECTIONS_STEEP + n], temp[n - 1], AP2_STEEP_FX[n] ); // Qx + move32(); + mem[ALLPASSSECTIONS_STEEP + n] = Msub_32_16( temp[n - 1], temp[n], AP2_STEEP_FX[n] ); // Qx + move32(); +#else /* OPT_STEREO_32KBPS_V1 */ temp[n] = L_add( mem[ALLPASSSECTIONS_STEEP + n], Mpy_32_16_1( temp[n - 1], AP2_STEEP_FX[n] ) ); // Qx move32(); /*if ( fabs( temp[n] ) < 1e-12 ) @@ -176,12 +227,20 @@ void Decimate_allpass_steep_fx32( }*/ mem[ALLPASSSECTIONS_STEEP + n] = L_sub( temp[n - 1], Mpy_32_16_1( temp[n], AP2_STEEP_FX[n] ) ); // Qx move32(); +#endif /* OPT_STEREO_32KBPS_V1 */ } +#ifdef OPT_STEREO_32KBPS_V1 + temp[ALLPASSSECTIONS_STEEP - 1] = Madd_32_16( mem[2 * ALLPASSSECTIONS_STEEP - 1], temp[ALLPASSSECTIONS_STEEP - 2], AP2_STEEP_FX[ALLPASSSECTIONS_STEEP - 1] ); // Qx + move32(); + mem[2 * ALLPASSSECTIONS_STEEP - 1] = Msub_32_16( temp[ALLPASSSECTIONS_STEEP - 2], temp[ALLPASSSECTIONS_STEEP - 1], AP2_STEEP_FX[ALLPASSSECTIONS_STEEP - 1] ); // Qx + move32(); +#else /* OPT_STEREO_32KBPS_V1 */ temp[ALLPASSSECTIONS_STEEP - 1] = L_add( mem[2 * ALLPASSSECTIONS_STEEP - 1], Mpy_32_16_1( temp[ALLPASSSECTIONS_STEEP - 2], AP2_STEEP_FX[ALLPASSSECTIONS_STEEP - 1] ) ); // Qx move32(); mem[2 * ALLPASSSECTIONS_STEEP - 1] = L_sub( temp[ALLPASSSECTIONS_STEEP - 2], Mpy_32_16_1( temp[ALLPASSSECTIONS_STEEP - 1], AP2_STEEP_FX[ALLPASSSECTIONS_STEEP - 1] ) ); // Qx move32(); +#endif /* OPT_STEREO_32KBPS_V1 */ out[k] = W_round48_L( W_mac_32_16( W_mult_32_16( out[k], 16384 /*0.5 in Q15*/ ), temp[ALLPASSSECTIONS_STEEP - 1], 16384 /*0.5 in Q15*/ ) ); // Qx move32(); } @@ -211,12 +270,21 @@ void interpolate_3_over_2_allpass_32( FOR( i = 0; i < len; i++ ) { /* Upper branch */ +#ifdef OPT_STEREO_32KBPS_V1 + Vu[0] = Madd_32_16( mem[0], L_sub( input[i], mem[1] ), filt_coeff[0] ); // Qx + Q15 - Q15 -> Qx + move32(); + Vu[1] = Madd_32_16( mem[1], L_sub( Vu[0], mem[2] ), filt_coeff[1] ); // Qx + Q15 - Q15 -> Qx + move32(); + mem[3] = Madd_32_16( mem[2], L_sub( Vu[1], mem[3] ), filt_coeff[2] ); // Qx + Q15 - Q15 -> Qx + move32(); +#else /* OPT_STEREO_32KBPS_V1 */ Vu[0] = L_add( mem[0], Mpy_32_16_1( L_sub( input[i], mem[1] ), filt_coeff[0] ) ); // Qx + Q15 - Q15 -> Qx move32(); Vu[1] = L_add( mem[1], Mpy_32_16_1( L_sub( Vu[0], mem[2] ), filt_coeff[1] ) ); // Qx + Q15 - Q15 -> Qx move32(); mem[3] = L_add( mem[2], Mpy_32_16_1( L_sub( Vu[1], mem[3] ), filt_coeff[2] ) ); // Qx + Q15 - Q15 -> Qx move32(); +#endif /* OPT_STEREO_32KBPS_V1 */ mem[1] = Vu[0]; // Qx move32(); @@ -226,12 +294,21 @@ void interpolate_3_over_2_allpass_32( move32(); /* Middle branch */ +#ifdef OPT_STEREO_32KBPS_V1 + Vm[0] = Madd_32_16( mem[0], L_sub( input[i], mem[4] ), filt_coeff[3] ); // Qx + Q15 - Q15 -> Qx + move32(); + Vm[1] = Madd_32_16( mem[4], L_sub( Vm[0], mem[5] ), filt_coeff[4] ); // Qx + Q15 - Q15 -> Qx + move32(); + mem[6] = Madd_32_16( mem[5], L_sub( Vm[1], mem[6] ), filt_coeff[5] ); // Qx + Q15 - Q15 -> Qx + move32(); +#else /* OPT_STEREO_32KBPS_V1 */ Vm[0] = L_add( mem[0], Mpy_32_16_1( L_sub( input[i], mem[4] ), filt_coeff[3] ) ); // Qx + Q15 - Q15 -> Qx move32(); Vm[1] = L_add( mem[4], Mpy_32_16_1( L_sub( Vm[0], mem[5] ), filt_coeff[4] ) ); // Qx + Q15 - Q15 -> Qx move32(); mem[6] = L_add( mem[5], Mpy_32_16_1( L_sub( Vm[1], mem[6] ), filt_coeff[5] ) ); // Qx + Q15 - Q15 -> Qx move32(); +#endif /* OPT_STEREO_32KBPS_V1 */ mem[4] = Vm[0]; // Qx move32(); @@ -241,12 +318,21 @@ void interpolate_3_over_2_allpass_32( move32(); /* Lower branch */ +#ifdef OPT_STEREO_32KBPS_V1 + Vl[0] = Madd_32_16( mem[0], L_sub( input[i], mem[7] ), filt_coeff[6] ); // Qx + Q15 - Q15 -> Qx + move32(); + Vl[1] = Madd_32_16( mem[7], L_sub( Vl[0], mem[8] ), filt_coeff[7] ); // Qx + Q15 - Q15 -> Qx + move32(); + mem[9] = Madd_32_16( mem[8], L_sub( Vl[1], mem[9] ), filt_coeff[8] ); // Qx + Q15 - Q15 -> Qx + move32(); +#else /* OPT_STEREO_32KBPS_V1 */ Vl[0] = L_add( mem[0], Mpy_32_16_1( L_sub( input[i], mem[7] ), filt_coeff[6] ) ); // Qx + Q15 - Q15 -> Qx move32(); Vl[1] = L_add( mem[7], Mpy_32_16_1( L_sub( Vl[0], mem[8] ), filt_coeff[7] ) ); // Qx + Q15 - Q15 -> Qx move32(); mem[9] = L_add( mem[8], Mpy_32_16_1( L_sub( Vl[1], mem[9] ), filt_coeff[8] ) ); // Qx + Q15 - Q15 -> Qx move32(); +#endif /* OPT_STEREO_32KBPS_V1 */ mem[0] = input[i]; // Qx move32(); @@ -265,10 +351,17 @@ void interpolate_3_over_2_allpass_32( { mem_temp = out1_buff[2 * i]; move32(); +#ifdef OPT_STEREO_32KBPS_V1 + out[i] = Madd_32_16( Mpy_32_16_1( L_add( mem_temp, mem[10] ), 1550 ), L_add( mem[11], mem[14] ), -4965 ); // Qx + Q15 - Q15 -> Qx + // 0.0473147f in Q15 -> 1550, -0.151521f in Q15 -> -4965 + out[i] = Madd_32_16( out[i], L_add( mem[12], mem[13] ), 20125 ); + // 0.614152f in Q15 -> 20125 +#else /* OPT_STEREO_32KBPS_V1 */ out[i] = L_add( Mpy_32_16_1( L_add( mem_temp, mem[10] ), 1550 ), Mpy_32_16_1( L_add( mem[11], mem[14] ), -4965 ) ); // Qx + Q15 - Q15 -> Qx // 0.0473147f in Q15 -> 1550, -0.151521f in Q15 -> -4965 out[i] = L_add( out[i], Mpy_32_16_1( L_add( mem[12], mem[13] ), 20125 ) ); // 0.614152f in Q15 -> 20125 +#endif /* OPT_STEREO_32KBPS_V1 */ mem[10] = mem[11]; // Qx move32(); mem[11] = mem[12]; // Qx diff --git a/lib_com/modif_fs_fx.c b/lib_com/modif_fs_fx.c index b53bb9d1ca18e0bbfaffa7e90245fcec66a9a64d..6079e5db5a5ef4c1a8b073b8a5c1ac8e450170ce 100644 --- a/lib_com/modif_fs_fx.c +++ b/lib_com/modif_fs_fx.c @@ -206,13 +206,8 @@ Word16 modify_Fs_ivas_fx( /* o : length of output Q { sigPtr = signal_fx + add( lg, add( mem_len, i ) ); L_tmp = syn_kern_16( 0, A_fx, sigPtr ); -#ifdef BASOP_NOGLOB L_tmp = L_shl_sat( L_tmp, 3 ); *sigPtr = round_fx_sat( L_tmp ); /* AZ ringing padding */ -#else - L_tmp = L_shl( L_tmp, 3 ); - *sigPtr = round_fx( L_tmp ); /* AZ ringing padding */ -#endif move16(); } mem_preemph_fx = signal_fx[mem_len + lg - LEN_WIN_SSS - 1]; @@ -238,11 +233,7 @@ Word16 modify_Fs_ivas_fx( /* o : length of output Q Word16 norm_cfg_ptr = norm_s( sub( cfg_ptr_fx->filter_fx[0], 1 ) ); FOR( i = 0; i < lg_out; i++ ) { -#ifdef BASOP_NOGLOB sigOut_fx[i] = round_fx_sat( Interpol_lc_fx( sigIn_ptr, cfg_ptr_fx->filter_fx, frac, fac_num, filt_len_tmp ) ); -#else - sigOut_fx[i] = round_fx( Interpol_lc_fx( sigIn_ptr, cfg_ptr_fx->filter_fx, frac, fac_num, filt_len_tmp ) ); -#endif move16(); frac = add( frac, fracstep ); @@ -282,13 +273,9 @@ Word16 modify_Fs_ivas_fx( /* o : length of output Q test(); IF( GT_32( fin, 16000 ) && ( EQ_16( lg_out, L_FRAME ) || EQ_16( lg_out, L_FRAME16k ) || EQ_16( lg_out, 512 ) ) ) { -#ifdef BASOP_NOGLOB num_den = shl_o( num_den, 1, &Overflow ); *Q_new_inp = add( *Q_new_inp, 1 ); move16(); -#else - num_den = shl( num_den, 1 ); -#endif } FOR( i = 0; i < lg_out; i++ ) { @@ -512,13 +499,8 @@ Word16 modify_Fs_fx( /* o : length of output Q0 */ sigPtr = signal_fx + add( add( lg, mem_len ), i ); move16(); /*+i*/ L_tmp = syn_kern_16( 0, A_fx, sigPtr ); -#ifdef BASOP_NOGLOB L_tmp = L_shl_sat( L_tmp, 3 ); *sigPtr = round_fx_sat( L_tmp ); /* AZ ringing padding */ -#else - L_tmp = L_shl( L_tmp, 3 ); - *sigPtr = round_fx( L_tmp ); /* AZ ringing padding */ -#endif } mem_preemph_fx = signal_fx[mem_len + lg - LEN_WIN_SSS - 1]; move16(); @@ -542,11 +524,7 @@ Word16 modify_Fs_fx( /* o : length of output Q0 */ FOR( i = 0; i < lg_out; i++ ) { -#ifdef BASOP_NOGLOB sigOut_fx[i] = round_fx_sat( Interpol_lc_fx( sigIn_ptr, cfg_ptr_fx->filter_fx, frac, fac_num, filt_len_tmp ) ); -#else - sigOut_fx[i] = round_fx( Interpol_lc_fx( sigIn_ptr, cfg_ptr_fx->filter_fx, frac, fac_num, filt_len_tmp ) ); -#endif move16(); frac = add( frac, fracstep ); @@ -584,12 +562,8 @@ Word16 modify_Fs_fx( /* o : length of output Q0 */ test(); if ( GT_32( fin, 16000 ) && ( EQ_16( lg_out, L_FRAME ) || EQ_16( lg_out, L_FRAME16k ) || EQ_16( lg_out, 512 ) ) ) { -#ifdef BASOP_NOGLOB num_den = shl_o( num_den, 1, &Overflow ); //*Q_new_inp = 2; -#else - num_den = shl( num_den, 1 ); -#endif } FOR( i = 0; i < lg_out; i++ ) { @@ -980,112 +954,63 @@ void Decimate_allpass_steep_fx( FOR( k = 0; k < N / 2; k++ ) { - Lacc = L_deposit_h( mem[0] ); /* Q(16+x) */ -#ifdef BASOP_NOGLOB + Lacc = L_deposit_h( mem[0] ); /* Q(16+x) */ Lacc = L_mac_o( Lacc, AP1_STEEP_FX[0], in_fx[2 * k], &Overflow ); /* Q(16+x) */ -#else - Lacc = L_mac( Lacc, AP1_STEEP_FX[0], in_fx[2 * k] ); /* Q(16+x) */ -#endif - Lacc1 = L_deposit_h( in_fx[2 * k] ); /* Q16+Qx */ - temp1 = extract_h( Lacc ); /* Qx */ -#ifdef BASOP_NOGLOB - Lacc1 = L_msu_o( Lacc1, AP1_STEEP_FX[0], temp1, &Overflow ); /* Q16+Qx */ -#else - Lacc1 = L_msu( Lacc1, AP1_STEEP_FX[0], temp1 ); /* Q16+Qx */ -#endif - mem[0] = extract_h( Lacc1 ); /* Qx */ + Lacc1 = L_deposit_h( in_fx[2 * k] ); /* Q16+Qx */ + temp1 = extract_h( Lacc ); /* Qx */ + Lacc1 = L_msu_o( Lacc1, AP1_STEEP_FX[0], temp1, &Overflow ); /* Q16+Qx */ + mem[0] = extract_h( Lacc1 ); /* Qx */ temp[0] = temp1; move16(); move16(); - Lacc1 = L_deposit_h( mem[1] ); /* Q16+Qx */ -#ifdef BASOP_NOGLOB + Lacc1 = L_deposit_h( mem[1] ); /* Q16+Qx */ Lacc1 = ( L_mac_o( Lacc1, AP1_STEEP_FX[1], temp1, &Overflow ) ); /* Q16+Qx */ -#else - Lacc1 = ( L_mac( Lacc1, AP1_STEEP_FX[1], temp1 ) ); /* Q16+Qx */ -#endif - temp2 = extract_h( Lacc1 ); /* Qx */ -#ifdef BASOP_NOGLOB + temp2 = extract_h( Lacc1 ); /* Qx */ Lacc = L_msu_o( Lacc, AP1_STEEP_FX[1], temp2, &Overflow ); /* Q16+Qx */ -#else - Lacc = L_msu( Lacc, AP1_STEEP_FX[1], temp2 ); /* Q16+Qx */ -#endif - mem[1] = extract_h( Lacc ); /* Qx */ + mem[1] = extract_h( Lacc ); /* Qx */ temp[1] = temp2; move16(); move16(); - Lacc = L_deposit_h( mem[ALLPASSSECTIONS_STEEP - 1] ); /* Q(16+x) */ -#ifdef BASOP_NOGLOB + Lacc = L_deposit_h( mem[ALLPASSSECTIONS_STEEP - 1] ); /* Q(16+x) */ out_fx[k] = extract_h( L_mac_o( Lacc, AP1_STEEP_FX[ALLPASSSECTIONS_STEEP - 1], temp2, &Overflow ) ); /* Qx format */ move16(); mem[ALLPASSSECTIONS_STEEP - 1] = extract_h( L_msu_o( Lacc1, AP1_STEEP_FX[ALLPASSSECTIONS_STEEP - 1], out_fx[k], &Overflow ) ); /* Qx */ move16(); -#else - out_fx[k] = extract_h( L_mac( Lacc, AP1_STEEP_FX[ALLPASSSECTIONS_STEEP - 1], temp2 ) ); /* Qx format */ - mem[ALLPASSSECTIONS_STEEP - 1] = extract_h( L_msu( Lacc1, AP1_STEEP_FX[ALLPASSSECTIONS_STEEP - 1], out_fx[k] ) ); /* Qx */ -#endif } /* lower allpass filter chain */ - Lacc = L_deposit_h( mem[ALLPASSSECTIONS_STEEP] ); /* Q(16+x) */ -#ifdef BASOP_NOGLOB + Lacc = L_deposit_h( mem[ALLPASSSECTIONS_STEEP] ); /* Q(16+x) */ Lacc = L_mac_o( Lacc, AP2_STEEP_FX[0], mem[2 * ALLPASSSECTIONS_STEEP], &Overflow ); /*Q(16+x) */ -#else - Lacc = L_mac( Lacc, AP2_STEEP_FX[0], mem[2 * ALLPASSSECTIONS_STEEP] ); /*Q(16+x) */ -#endif - Lacc1 = L_deposit_h( mem[2 * ALLPASSSECTIONS_STEEP] ); /* Q(16+x) */ - temp1 = extract_h( Lacc ); /* Qx */ -#ifdef BASOP_NOGLOB - Lacc1 = L_msu_o( Lacc1, AP2_STEEP_FX[0], temp1, &Overflow ); /* Q(16+x) */ -#else - Lacc1 = L_msu( Lacc1, AP2_STEEP_FX[0], temp1 ); /* Q(16+x) */ -#endif + Lacc1 = L_deposit_h( mem[2 * ALLPASSSECTIONS_STEEP] ); /* Q(16+x) */ + temp1 = extract_h( Lacc ); /* Qx */ + Lacc1 = L_msu_o( Lacc1, AP2_STEEP_FX[0], temp1, &Overflow ); /* Q(16+x) */ mem[ALLPASSSECTIONS_STEEP] = extract_h( Lacc1 ); temp[0] = temp1; move16(); - Lacc1 = L_deposit_h( mem[ALLPASSSECTIONS_STEEP + 1] ); /* Q(16+x) */ -#ifdef BASOP_NOGLOB + Lacc1 = L_deposit_h( mem[ALLPASSSECTIONS_STEEP + 1] ); /* Q(16+x) */ Lacc1 = L_mac_o( Lacc1, AP2_STEEP_FX[1], temp1, &Overflow ); /* Q(16+x) */ -#else - Lacc1 = L_mac( Lacc1, AP2_STEEP_FX[1], temp1 ); /* Q(16+x) */ -#endif - temp2 = extract_h( Lacc1 ); /* Qx */ + temp2 = extract_h( Lacc1 ); /* Qx */ temp[1] = temp2; move16(); -#ifdef BASOP_NOGLOB Lacc = L_msu_o( Lacc, AP2_STEEP_FX[1], temp2, &Overflow ); /* Q(16+x) */ -#else - Lacc = L_msu( Lacc, AP2_STEEP_FX[1], temp2 ); /* Q(16+x) */ -#endif - mem[ALLPASSSECTIONS_STEEP + 1] = extract_h( Lacc ); /* Qx */ + mem[ALLPASSSECTIONS_STEEP + 1] = extract_h( Lacc ); /* Qx */ move16(); - Lacc = L_deposit_h( mem[2 * ALLPASSSECTIONS_STEEP - 1] ); /* Q(16+x) */ -#ifdef BASOP_NOGLOB + Lacc = L_deposit_h( mem[2 * ALLPASSSECTIONS_STEEP - 1] ); /* Q(16+x) */ Lacc = L_mac_o( Lacc, AP2_STEEP_FX[ALLPASSSECTIONS_STEEP - 1], temp2, &Overflow ); /* Q(16+x) temp[ALLPASSSECTIONS_STEEP-1] */ -#else - Lacc = L_mac( Lacc, AP2_STEEP_FX[ALLPASSSECTIONS_STEEP - 1], temp2 ); /* Q(16+x) temp[ALLPASSSECTIONS_STEEP-1] */ -#endif - temp[2] = extract_h( Lacc ); /* temp[2] in Qx */ + temp[2] = extract_h( Lacc ); /* temp[2] in Qx */ move16(); -#ifdef BASOP_NOGLOB Lacc1 = L_msu_o( Lacc1, AP2_STEEP_FX[ALLPASSSECTIONS_STEEP - 1], temp[2], &Overflow ); /* Q(16+x) */ -#else - Lacc1 = L_msu( Lacc1, AP2_STEEP_FX[ALLPASSSECTIONS_STEEP - 1], temp[2] ); /* Q(16+x) */ -#endif - mem[2 * ALLPASSSECTIONS_STEEP - 1] = extract_h( Lacc1 ); /* Qx */ + mem[2 * ALLPASSSECTIONS_STEEP - 1] = extract_h( Lacc1 ); /* Qx */ move16(); - sum = mult_r( out_fx[0], 16384 ); /* Qx */ -#ifdef BASOP_NOGLOB + sum = mult_r( out_fx[0], 16384 ); /* Qx */ out_fx[0] = add_sat( sum, mult_r( temp[ALLPASSSECTIONS_STEEP - 1], 16384 ) ); /* Qx */ -#else - out_fx[0] = add( sum, mult_r( temp[ALLPASSSECTIONS_STEEP - 1], 16384 ) ); /* Qx */ -#endif move16(); @@ -1093,19 +1018,11 @@ void Decimate_allpass_steep_fx( { - Lacc = L_deposit_h( mem[ALLPASSSECTIONS_STEEP] ); /* Q(16+x) */ -#ifdef BASOP_NOGLOB + Lacc = L_deposit_h( mem[ALLPASSSECTIONS_STEEP] ); /* Q(16+x) */ Lacc = L_mac_o( Lacc, AP2_STEEP_FX[0], in_fx[2 * k - 1], &Overflow ); /* Q(16+x):temp[0] */ -#else - Lacc = L_mac( Lacc, AP2_STEEP_FX[0], in_fx[2 * k - 1] ); /* Q(16+x):temp[0] */ -#endif - Lacc1 = L_deposit_h( in_fx[2 * k - 1] ); /* Q(16+x) */ - temp1 = extract_h( Lacc ); /* Qx */ -#ifdef BASOP_NOGLOB - Lacc1 = L_msu_o( Lacc1, AP2_STEEP_FX[0], temp1, &Overflow ); /* Q(16+x) */ -#else - Lacc1 = L_msu( Lacc1, AP2_STEEP_FX[0], temp1 ); /* Q(16+x) */ -#endif + Lacc1 = L_deposit_h( in_fx[2 * k - 1] ); /* Q(16+x) */ + temp1 = extract_h( Lacc ); /* Qx */ + Lacc1 = L_msu_o( Lacc1, AP2_STEEP_FX[0], temp1, &Overflow ); /* Q(16+x) */ mem[ALLPASSSECTIONS_STEEP] = extract_h( Lacc1 ); /* Qx */ move16(); @@ -1113,45 +1030,25 @@ void Decimate_allpass_steep_fx( move16(); - Lacc1 = L_deposit_h( mem[ALLPASSSECTIONS_STEEP + 1] ); /* Q(16+x) */ -#ifdef BASOP_NOGLOB + Lacc1 = L_deposit_h( mem[ALLPASSSECTIONS_STEEP + 1] ); /* Q(16+x) */ Lacc1 = L_mac_o( Lacc1, AP2_STEEP_FX[1], temp1, &Overflow ); /* Q(16+x) */ -#else - Lacc1 = L_mac( Lacc1, AP2_STEEP_FX[1], temp1 ); /* Q(16+x) */ -#endif - temp2 = extract_h( Lacc1 ); /* Qx */ + temp2 = extract_h( Lacc1 ); /* Qx */ temp[1] = temp2; move16(); -#ifdef BASOP_NOGLOB Lacc = L_msu_o( Lacc, AP2_STEEP_FX[1], temp2, &Overflow ); /* Q(16+x) */ -#else - Lacc = L_msu( Lacc, AP2_STEEP_FX[1], temp2 ); /* Q(16+x) */ -#endif - mem[ALLPASSSECTIONS_STEEP + 1] = extract_h( Lacc ); /* Qx */ + mem[ALLPASSSECTIONS_STEEP + 1] = extract_h( Lacc ); /* Qx */ - Lacc = L_deposit_h( mem[2 * ALLPASSSECTIONS_STEEP - 1] ); /* Q(16+x) */ -#ifdef BASOP_NOGLOB - Lacc = L_mac_o( Lacc, AP2_STEEP_FX[ALLPASSSECTIONS_STEEP - 1], temp[1], &Overflow ); /* Q(16+x) temp[ALLPASSSECTIONS_STEEP-1] */ -#else - Lacc = L_mac( Lacc, AP2_STEEP_FX[ALLPASSSECTIONS_STEEP - 1], temp[1] ); /* Q(16+x) temp[ALLPASSSECTIONS_STEEP-1] */ -#endif - temp[2] = extract_h( Lacc ); /*temp[2] in Qx */ -#ifdef BASOP_NOGLOB + Lacc = L_deposit_h( mem[2 * ALLPASSSECTIONS_STEEP - 1] ); /* Q(16+x) */ + Lacc = L_mac_o( Lacc, AP2_STEEP_FX[ALLPASSSECTIONS_STEEP - 1], temp[1], &Overflow ); /* Q(16+x) temp[ALLPASSSECTIONS_STEEP-1] */ + temp[2] = extract_h( Lacc ); /*temp[2] in Qx */ Lacc1 = L_msu_o( Lacc1, AP2_STEEP_FX[ALLPASSSECTIONS_STEEP - 1], temp[2], &Overflow ); /* Q(16+x) */ -#else - Lacc1 = L_msu( Lacc1, AP2_STEEP_FX[ALLPASSSECTIONS_STEEP - 1], temp[2] ); /* Q(16+x) */ -#endif - mem[2 * ALLPASSSECTIONS_STEEP - 1] = extract_h( Lacc1 ); /* Qx */ + mem[2 * ALLPASSSECTIONS_STEEP - 1] = extract_h( Lacc1 ); /* Qx */ sum = mult_r( out_fx[k], 16384 ); /* Qx */ -#ifdef BASOP_NOGLOB out_fx[k] = add_sat( sum, mult_r( temp[ALLPASSSECTIONS_STEEP - 1], 16384 ) ); move16(); -#else - out_fx[k] = add( sum, mult_r( temp[ALLPASSSECTIONS_STEEP - 1], 16384 ) ); -#endif move16(); /* Qx */ } @@ -1188,109 +1085,56 @@ void Interpolate_allpass_steep_fx( FOR( k = 0; k < N; k++ ) { - Lacc = L_deposit_h( mem[0] ); /* Q(16+x) */ -#ifdef BASOP_NOGLOB + Lacc = L_deposit_h( mem[0] ); /* Q(16+x) */ Lacc = L_mac_o( Lacc, AP2_STEEP_FX[0], in_fx[k], &Overflow ); /* Q(16+x):temp[0] */ -#else - Lacc = L_mac( Lacc, AP2_STEEP_FX[0], in_fx[k] ); /* Q(16+x):temp[0] */ -#endif - Lacc1 = L_deposit_h( in_fx[k] ); /* Q(16+x) */ -#ifdef BASOP_NOGLOB - temp1 = round_fx_o( Lacc, &Overflow ); /* Qx */ - Lacc1 = L_msu_o( Lacc1, AP2_STEEP_FX[0], temp1, &Overflow ); /* Q(16+x) */ + Lacc1 = L_deposit_h( in_fx[k] ); /* Q(16+x) */ + temp1 = round_fx_o( Lacc, &Overflow ); /* Qx */ + Lacc1 = L_msu_o( Lacc1, AP2_STEEP_FX[0], temp1, &Overflow ); /* Q(16+x) */ mem[0] = round_fx_o( Lacc1, &Overflow ); move16(); -#else - temp1 = round_fx( Lacc ); /* Qx */ - Lacc1 = L_msu( Lacc1, AP2_STEEP_FX[0], temp1 ); /* Q(16+x) */ - - mem[0] = round_fx( Lacc1 ); -#endif - Lacc1 = L_deposit_h( mem[1] ); /* Q(16+x) */ -#ifdef BASOP_NOGLOB + Lacc1 = L_deposit_h( mem[1] ); /* Q(16+x) */ Lacc1 = ( L_mac_o( Lacc1, AP2_STEEP_FX[1], temp1, &Overflow ) ); /* Q(16+x):temp[1] */ -#else - Lacc1 = ( L_mac( Lacc1, AP2_STEEP_FX[1], temp1 ) ); /* Q(16+x):temp[1] */ -#endif Lacc = L_deposit_h( temp1 ); -#ifdef BASOP_NOGLOB temp2 = round_fx_o( Lacc1, &Overflow ); /* Qx */ Lacc = L_msu_o( Lacc, AP2_STEEP_FX[1], temp2, &Overflow ); /* Q(16+x) */ mem[1] = round_fx_o( Lacc, &Overflow ); /* Qx */ move16(); -#else - temp2 = round_fx( Lacc1 ); /* Qx */ - Lacc = L_msu( Lacc, AP2_STEEP_FX[1], temp2 ); /* Q(16+x) */ - mem[1] = round_fx( Lacc ); /* Qx */ -#endif Lacc1 = L_deposit_h( temp2 ); - Lacc = L_deposit_h( mem[ALLPASSSECTIONS_STEEP - 1] ); /* Q(16+x) */ -#ifdef BASOP_NOGLOB + Lacc = L_deposit_h( mem[ALLPASSSECTIONS_STEEP - 1] ); /* Q(16+x) */ out_fx[2 * k + 1] = round_fx_o( L_mac_o( Lacc, AP2_STEEP_FX[ALLPASSSECTIONS_STEEP - 1], temp2, &Overflow ), &Overflow ); /* Qx format */ move16(); mem[ALLPASSSECTIONS_STEEP - 1] = round_fx_o( L_msu_o( Lacc1, AP2_STEEP_FX[ALLPASSSECTIONS_STEEP - 1], out_fx[2 * k + 1], &Overflow ), &Overflow ); /* Qx */ move16(); -#else - out_fx[2 * k + 1] = round_fx( L_mac( Lacc, AP2_STEEP_FX[ALLPASSSECTIONS_STEEP - 1], temp2 ) ); /* Qx format */ - mem[ALLPASSSECTIONS_STEEP - 1] = round_fx( L_msu( Lacc1, AP2_STEEP_FX[ALLPASSSECTIONS_STEEP - 1], out_fx[2 * k + 1] ) ); /* Qx */ -#endif } /* lower allpass filter chain */ FOR( k = 0; k < N; k++ ) { - Lacc = L_deposit_h( mem[ALLPASSSECTIONS_STEEP] ); /* Q(16+x) */ -#ifdef BASOP_NOGLOB + Lacc = L_deposit_h( mem[ALLPASSSECTIONS_STEEP] ); /* Q(16+x) */ Lacc = L_mac_o( Lacc, AP1_STEEP_FX[0], in_fx[k], &Overflow ); /* Q(16+x):temp[0] */ -#else - Lacc = L_mac( Lacc, AP1_STEEP_FX[0], in_fx[k] ); /* Q(16+x):temp[0] */ -#endif - Lacc1 = L_deposit_h( in_fx[k] ); /* Q(16+x) */ -#ifdef BASOP_NOGLOB - temp1 = round_fx_o( Lacc, &Overflow ); /* Qx */ - Lacc1 = L_msu_o( Lacc1, AP1_STEEP_FX[0], temp1, &Overflow ); /* Q(16+x) */ + Lacc1 = L_deposit_h( in_fx[k] ); /* Q(16+x) */ + temp1 = round_fx_o( Lacc, &Overflow ); /* Qx */ + Lacc1 = L_msu_o( Lacc1, AP1_STEEP_FX[0], temp1, &Overflow ); /* Q(16+x) */ mem[ALLPASSSECTIONS_STEEP] = round_fx_o( Lacc1, &Overflow ); -#else - temp1 = round_fx( Lacc ); /* Qx */ - Lacc1 = L_msu( Lacc1, AP1_STEEP_FX[0], temp1 ); /* Q(16+x) */ - - mem[ALLPASSSECTIONS_STEEP] = round_fx( Lacc1 ); -#endif - Lacc1 = L_deposit_h( mem[ALLPASSSECTIONS_STEEP + 1] ); /* Q(16+x) */ -#ifdef BASOP_NOGLOB + Lacc1 = L_deposit_h( mem[ALLPASSSECTIONS_STEEP + 1] ); /* Q(16+x) */ Lacc1 = L_mac_o( Lacc1, AP1_STEEP_FX[1], temp1, &Overflow ); /* Q(16+x):temp[1] */ temp2 = round_fx_o( Lacc1, &Overflow ); /* Qx */ -#else - Lacc1 = L_mac( Lacc1, AP1_STEEP_FX[1], temp1 ); /* Q(16+x):temp[1] */ - - temp2 = round_fx( Lacc1 ); /* Qx */ -#endif Lacc = L_deposit_h( temp1 ); -#ifdef BASOP_NOGLOB Lacc = L_msu_o( Lacc, AP1_STEEP_FX[1], temp2, &Overflow ); /* Q(16+x) */ mem[ALLPASSSECTIONS_STEEP + 1] = round_fx_o( Lacc, &Overflow ); /* Qx */ -#else - Lacc = L_msu( Lacc, AP1_STEEP_FX[1], temp2 ); /* Q(16+x) */ - mem[ALLPASSSECTIONS_STEEP + 1] = round_fx( Lacc ); /* Qx */ -#endif Lacc = L_deposit_h( mem[2 * ALLPASSSECTIONS_STEEP - 1] ); /* Q(16+x) */ Lacc1 = L_deposit_h( temp2 ); -#ifdef BASOP_NOGLOB out_fx[2 * k] = round_fx_o( L_mac_o( Lacc, AP1_STEEP_FX[ALLPASSSECTIONS_STEEP - 1], temp2, &Overflow ), &Overflow ); /* Qx format */ move16(); mem[2 * ALLPASSSECTIONS_STEEP - 1] = round_fx_o( L_msu_o( Lacc1, AP1_STEEP_FX[ALLPASSSECTIONS_STEEP - 1], out_fx[2 * k], &Overflow ), &Overflow ); /* Qx */ move16(); -#else - out_fx[2 * k] = round_fx( L_mac( Lacc, AP1_STEEP_FX[ALLPASSSECTIONS_STEEP - 1], temp2 ) ); /* Qx format */ - mem[2 * ALLPASSSECTIONS_STEEP - 1] = round_fx( L_msu( Lacc1, AP1_STEEP_FX[ALLPASSSECTIONS_STEEP - 1], out_fx[2 * k] ) ); /* Qx */ -#endif } return; @@ -1346,19 +1190,11 @@ void interpolate_3_over_2_allpass_fx( Vu[1] = mem[1] + filt_coeff[1] * ( Vu[0] - mem[2] ); mem[3] = mem[2] + filt_coeff[2] * ( Vu[1] - mem[3] );*/ -#ifdef BASOP_NOGLOB Vu[0] = add_sat( mem_fx[0], mult_r_sat( filt_coeff_fx[0], sub_sat( input_fx_temp[i], mem_fx[1] ) ) ); move16(); /* all Vu's in : Q_current*/ Vu[1] = add_sat( mem_fx[1], mult_r_sat( filt_coeff_fx[1], sub_sat( Vu[0], mem_fx[2] ) ) ); move16(); mem_fx[3] = add_sat( mem_fx[2], mult_r_sat( filt_coeff_fx[2], sub_sat( Vu[1], mem_fx[3] ) ) ); -#else - Vu[0] = add( mem_fx[0], mult_r( filt_coeff_fx[0], sub( input_fx_temp[i], mem_fx[1] ) ) ); - move16(); /* all Vu's in : Q_current*/ - Vu[1] = add( mem_fx[1], mult_r( filt_coeff_fx[1], sub( Vu[0], mem_fx[2] ) ) ); - move16(); - mem_fx[3] = add( mem_fx[2], mult_r( filt_coeff_fx[2], sub( Vu[1], mem_fx[3] ) ) ); -#endif move16(); @@ -1373,21 +1209,12 @@ void interpolate_3_over_2_allpass_fx( /* Vm[0] = mem[0] + filt_coeff[3] * (input[i]-mem[4]); Vm[1] = mem[4] + filt_coeff[4] * (Vm[0]-mem[5]); mem[6] = mem[5] + filt_coeff[5] * (Vm[1]-mem[6]); */ -#ifdef BASOP_NOGLOB Vm[0] = add_sat( mem_fx[0], mult_r_sat( filt_coeff_fx[3], sub_sat( input_fx_temp[i], mem_fx[4] ) ) ); move16(); Vm[1] = add_sat( mem_fx[4], mult_r_sat( filt_coeff_fx[4], sub_sat( Vm[0], mem_fx[5] ) ) ); move16(); mem_fx[6] = add_sat( mem_fx[5], mult_r_sat( filt_coeff_fx[5], sub_sat( Vm[1], mem_fx[6] ) ) ); move16(); -#else - Vm[0] = add( mem_fx[0], mult_r( filt_coeff_fx[3], sub( input_fx_temp[i], mem_fx[4] ) ) ); - move16(); - Vm[1] = add( mem_fx[4], mult_r( filt_coeff_fx[4], sub( Vm[0], mem_fx[5] ) ) ); - move16(); - mem_fx[6] = add( mem_fx[5], mult_r( filt_coeff_fx[5], sub( Vm[1], mem_fx[6] ) ) ); - move16(); -#endif mem_fx[4] = Vm[0]; move16(); mem_fx[5] = Vm[1]; @@ -1399,21 +1226,12 @@ void interpolate_3_over_2_allpass_fx( /* Vl[0] = mem[0] + filt_coeff[6] * (input[i]-mem[7]); Vl[1] = mem[7] + filt_coeff[7] * (Vl[0]-mem[8]); mem[9] = mem[8] + filt_coeff[8] * (Vl[1]-mem[9]); */ -#ifdef BASOP_NOGLOB Vl[0] = add_sat( mem_fx[0], mult_r_sat( filt_coeff_fx[6], sub_sat( input_fx_temp[i], mem_fx[7] ) ) ); move16(); Vl[1] = add_sat( mem_fx[7], mult_r_sat( filt_coeff_fx[7], sub_sat( Vl[0], mem_fx[8] ) ) ); move16(); mem_fx[9] = add_sat( mem_fx[8], mult_r_sat( filt_coeff_fx[8], sub_sat( Vl[1], mem_fx[9] ) ) ); move16(); -#else - Vl[0] = add( mem_fx[0], mult_r( filt_coeff_fx[6], sub( input_fx_temp[i], mem_fx[7] ) ) ); - move16(); - Vl[1] = add( mem_fx[7], mult_r( filt_coeff_fx[7], sub( Vl[0], mem_fx[8] ) ) ); - move16(); - mem_fx[9] = add( mem_fx[8], mult_r( filt_coeff_fx[8], sub( Vl[1], mem_fx[9] ) ) ); - move16(); -#endif mem_fx[0] = input_fx_temp[i]; move16(); mem_fx[7] = Vl[0]; @@ -1432,13 +1250,8 @@ void interpolate_3_over_2_allpass_fx( { mem_temp = out1_buff[shl( i, 1 )]; move16(); -#ifdef BASOP_NOGLOB out_fx[i] = add_sat( mult_r_sat( 1550 /* 0.0473147f Q15*/, add_sat( mem_temp, mem_fx[10] ) ), mult_r_sat( -4965 /*-0.151521f Q15*/, add_sat( mem_fx[11], mem_fx[14] ) ) ); out_fx[i] = add_sat( out_fx[i], mult_r_sat( 20125 /*0.614152f Q15*/, add_sat( mem_fx[12], mem_fx[13] ) ) ); -#else - out_fx[i] = add( mult_r( 1550 /* 0.0473147f Q15*/, add( mem_temp, mem_fx[10] ) ), mult_r( -4965 /*-0.151521f Q15*/, add( mem_fx[11], mem_fx[14] ) ) ); - out_fx[i] = add( out_fx[i], mult_r( 20125 /*0.614152f Q15*/, add( mem_fx[12], mem_fx[13] ) ) ); -#endif mem_fx[10] = mem_fx[11]; move16(); mem_fx[11] = mem_fx[12]; @@ -1581,23 +1394,11 @@ void interpolate_3_over_1_allpass_fx( Vu[1] = mem[1] + filt_coeff[1] * ( Vu[0] - mem[2] ); mem[3] = mem[2] + filt_coeff[2] * ( Vu[1] - mem[3] );*/ -#ifdef BASOP_NOGLOB Vu[0] = add_sat( mem_fx[0], mult_r( filt_coeff_fx[0], sub_sat( input_fx[i], mem_fx[1] ) ) ); -#else - Vu[0] = add( mem_fx[0], mult_r( filt_coeff_fx[0], sub( input_fx[i], mem_fx[1] ) ) ); -#endif move16(); /* all Vu's in : Q_current*/ -#ifdef BASOP_NOGLOB Vu[1] = add_sat( mem_fx[1], mult_r( filt_coeff_fx[1], sub_sat( Vu[0], mem_fx[2] ) ) ); -#else - Vu[1] = add( mem_fx[1], mult_r( filt_coeff_fx[1], sub( Vu[0], mem_fx[2] ) ) ); -#endif move16(); -#ifdef BASOP_NOGLOB mem_fx[3] = add_sat( mem_fx[2], mult_r( filt_coeff_fx[2], sub_sat( Vu[1], mem_fx[3] ) ) ); -#else - mem_fx[3] = add( mem_fx[2], mult_r( filt_coeff_fx[2], sub( Vu[1], mem_fx[3] ) ) ); -#endif move16(); @@ -1612,23 +1413,11 @@ void interpolate_3_over_1_allpass_fx( /* Vm[0] = mem[0] + filt_coeff[3] * (input[i]-mem[4]); Vm[1] = mem[4] + filt_coeff[4] * (Vm[0]-mem[5]); mem[6] = mem[5] + filt_coeff[5] * (Vm[1]-mem[6]); */ -#ifdef BASOP_NOGLOB Vm[0] = add_sat( mem_fx[0], mult_r( filt_coeff_fx[3], sub_sat( input_fx[i], mem_fx[4] ) ) ); -#else - Vm[0] = add( mem_fx[0], mult_r( filt_coeff_fx[3], sub( input_fx[i], mem_fx[4] ) ) ); -#endif move16(); -#ifdef BASOP_NOGLOB Vm[1] = add_sat( mem_fx[4], mult_r( filt_coeff_fx[4], sub_sat( Vm[0], mem_fx[5] ) ) ); -#else - Vm[1] = add( mem_fx[4], mult_r( filt_coeff_fx[4], sub( Vm[0], mem_fx[5] ) ) ); -#endif move16(); -#ifdef BASOP_NOGLOB mem_fx[6] = add_sat( mem_fx[5], mult_r( filt_coeff_fx[5], sub_sat( Vm[1], mem_fx[6] ) ) ); -#else - mem_fx[6] = add( mem_fx[5], mult_r( filt_coeff_fx[5], sub( Vm[1], mem_fx[6] ) ) ); -#endif move16(); mem_fx[4] = Vm[0]; @@ -1642,23 +1431,11 @@ void interpolate_3_over_1_allpass_fx( /* Vl[0] = mem[0] + filt_coeff[6] * (input[i]-mem[7]); Vl[1] = mem[7] + filt_coeff[7] * (Vl[0]-mem[8]); mem[9] = mem[8] + filt_coeff[8] * (Vl[1]-mem[9]); */ -#ifdef BASOP_NOGLOB Vl[0] = add_sat( mem_fx[0], mult_r( filt_coeff_fx[6], sub_sat( input_fx[i], mem_fx[7] ) ) ); -#else - Vl[0] = add( mem_fx[0], mult_r( filt_coeff_fx[6], sub( input_fx[i], mem_fx[7] ) ) ); -#endif move16(); -#ifdef BASOP_NOGLOB Vl[1] = add_sat( mem_fx[7], mult_r( filt_coeff_fx[7], sub_sat( Vl[0], mem_fx[8] ) ) ); -#else - Vl[1] = add( mem_fx[7], mult_r( filt_coeff_fx[7], sub( Vl[0], mem_fx[8] ) ) ); -#endif move16(); -#ifdef BASOP_NOGLOB mem_fx[9] = add_sat( mem_fx[8], mult_r( filt_coeff_fx[8], sub_sat( Vl[1], mem_fx[9] ) ) ); -#else - mem_fx[9] = add( mem_fx[8], mult_r( filt_coeff_fx[8], sub( Vl[1], mem_fx[9] ) ) ); -#endif move16(); mem_fx[0] = input_fx[i]; @@ -1675,11 +1452,7 @@ void interpolate_3_over_1_allpass_fx( { mem_temp = out_fx[i]; move16(); -#ifdef BASOP_NOGLOB out_fx[i] = sub_sat( mult_r( 18768 /*0.57276865021499168f Q15*/, add_sat( mem_fx[12], mem_fx[11] ) ), mult_r( 2425 /*0.074004974641176793f Q15*/, add_sat( mem_temp, mem_fx[10] ) ) ); -#else - out_fx[i] = sub( mult_r( 18768 /*0.57276865021499168f Q15*/, add( mem_fx[12], mem_fx[11] ) ), mult_r( 2425 /*0.074004974641176793f Q15*/, add( mem_temp, mem_fx[10] ) ) ); -#endif mem_fx[10] = mem_fx[11]; move16(); mem_fx[11] = mem_fx[12]; diff --git a/lib_com/move.h b/lib_com/move.h index 5c325fb1d5dc2d1b88edbfa6fb222e171e8928d7..7762ec79a10ad01297c253311190f95af13d647b 100644 --- a/lib_com/move.h +++ b/lib_com/move.h @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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_com/mslvq_com.c b/lib_com/mslvq_com.c index bab16f16599e15dd4f3bb2f28c3ebeb1dcef628b..12234a4c055664712312c284ce500a2a019c119a 100644 --- a/lib_com/mslvq_com.c +++ b/lib_com/mslvq_com.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other @@ -38,10 +38,8 @@ #include "options.h" #include "cnst.h" #include "rom_com.h" -#include "prot.h" -#include "wmc_auto.h" -#include "ivas_prot.h" #include "prot_fx.h" +#include "wmc_auto.h" #include "ivas_prot_fx.h" /*-----------------------------------------------------------------* @@ -76,10 +74,10 @@ static void make_offset_scale( void create_offset( UWord32 *offset_scale1, UWord32 *offset_scale2, - const int16_t mode, - const int16_t prediction_flag ) + const Word16 mode, + const Word16 prediction_flag ) { - int16_t tmp, tmp1; + Word16 tmp, tmp1; if ( prediction_flag == 0 ) { diff --git a/lib_com/mslvq_com_fx.c b/lib_com/mslvq_com_fx.c index 7c6658e8fbc6e75464f0e5d791875c32a71f488f..10e5604335a7b1ad471ffb3cf631bf2b8c6856aa 100644 --- a/lib_com/mslvq_com_fx.c +++ b/lib_com/mslvq_com_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other @@ -31,7 +31,6 @@ *******************************************************************************************************/ #include "options.h" -#include "prot.h" #include "prot_fx.h" #include "ivas_cnst.h" #include "stl.h" @@ -122,9 +121,33 @@ void init_lvq_fx( ) { Word16 i, j; +#ifdef OPT_STEREO_32KBPS_V1 + Word16 k; +#endif /* OPT_STEREO_32KBPS_V1 */ /* safety-net mode */ FOR( i = 0; i < MAX_NO_MODES; i++ ) { +#ifdef OPT_STEREO_32KBPS_V1 + FOR( ( j = 0, k = 0 ); j < MAX_NO_SCALES; ( j++, k++ ) ) + { + if ( ( no_lead_fx[i][j] <= 0 ) ) + { + j = MAX_NO_SCALES; + } + } + no_scales[i][0] = k; + move16(); + + FOR( k = 0; j < MAX_NO_SCALES << 1; ( j++, k++ ) ) + { + if ( no_lead_fx[i][j] <= 0 ) + { + j = MAX_NO_SCALES << 1; + } + } + no_scales[i][1] = k; + move16(); +#else /* OPT_STEREO_32KBPS_V1 */ j = 0; move16(); test(); @@ -143,10 +166,35 @@ void init_lvq_fx( } no_scales[i][1] = sub( j, MAX_NO_SCALES ); move16(); +#endif /* OPT_STEREO_32KBPS_V1 */ } /* predictive mode */ FOR( i = 0; i < MAX_NO_MODES_p; i++ ) { +#ifdef OPT_STEREO_32KBPS_V1 + FOR( ( j = 0, k = 0 ); j < MAX_NO_SCALES; ( j++, k++ ) ) + { + + if ( ( no_lead_p_fx[i][j] <= 0 ) ) + { + j = MAX_NO_SCALES; + } + } + no_scales_p[i][0] = k; + move16(); + + FOR( k = 0; j < MAX_NO_SCALES << 1; ( j++, k++ ) ) + { + + if ( ( no_lead_p_fx[i][j] <= 0 ) ) + { + j = MAX_NO_SCALES << 1; + } + } + + no_scales_p[i][1] = k; + move16(); +#else /* OPT_STEREO_32KBPS_V1 */ j = 0; move16(); WHILE( ( LT_16( j, MAX_NO_SCALES ) ) && ( no_lead_p_fx[i][j] > 0 ) ) @@ -165,6 +213,7 @@ void init_lvq_fx( } no_scales_p[i][1] = sub( j, MAX_NO_SCALES ); move16(); +#endif /* OPT_STEREO_32KBPS_V1 */ } /* index offsets for each truncation */ init_offset_fx( offset_scale1, offset_scale2, offset_scale1_p, offset_scale2_p, no_scales, no_scales_p ); diff --git a/lib_com/nelp_fx.c b/lib_com/nelp_fx.c index b37d57093f1a1e98164d7479c1a62568aec0b72a..39d57299e7dad568f0bf2d5c65e1f454d250f127 100644 --- a/lib_com/nelp_fx.c +++ b/lib_com/nelp_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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_com/oper_32b.c b/lib_com/oper_32b.c index 0b01cf957a32a65b2f5a11f0a5c8f8270b553ed3..be34a12481f96713597bce743c203af7811e3719 100644 --- a/lib_com/oper_32b.c +++ b/lib_com/oper_32b.c @@ -128,15 +128,9 @@ Word32 Mpy_32( Word16 hi1, Word16 lo1, Word16 hi2, Word16 lo2 ) Flag Overflow = 0; #endif -#ifdef BASOP_NOGLOB L_32 = L_mult( hi1, hi2 ); L_32 = L_mac_o( L_32, mult( hi1, lo2 ), 1, &Overflow ); L_32 = L_mac_o( L_32, mult( lo1, hi2 ), 1, &Overflow ); -#else - L_32 = L_mult( hi1, hi2 ); - L_32 = L_mac( L_32, mult( hi1, lo2 ), 1 ); - L_32 = L_mac( L_32, mult( lo1, hi2 ), 1 ); -#endif return ( L_32 ); } @@ -169,15 +163,9 @@ Word32 Mac_32( Word32 L_num, Word16 hi1, Word16 lo1, Word16 hi2, Word16 lo2 ) Flag Overflow = 0; #endif -#ifdef BASOP_NOGLOB L_32 = L_mac_o( L_num, hi1, hi2, &Overflow ); L_32 = L_mac_o( L_32, mult( hi1, lo2 ), 1, &Overflow ); L_32 = L_mac_o( L_32, mult( lo1, hi2 ), 1, &Overflow ); -#else - L_32 = L_mac( L_num, hi1, hi2 ); - L_32 = L_mac( L_32, mult( hi1, lo2 ), 1 ); - L_32 = L_mac( L_32, mult( lo1, hi2 ), 1 ); -#endif return ( L_32 ); } @@ -209,13 +197,8 @@ Word32 Sqr_32( Word16 hi, Word16 lo ) Flag Overflow = 0; #endif -#ifdef BASOP_NOGLOB L_32 = L_mult_o( hi, hi, &Overflow ); L_32 = L_mac_o( L_32, mult( hi, lo ), 2, &Overflow ); -#else - L_32 = L_mult( hi, hi ); - L_32 = L_mac( L_32, mult( hi, lo ), 2 ); -#endif return ( L_32 ); } @@ -402,11 +385,7 @@ Word32 Div_32( Word32 L_num, Word16 denom_hi, Word16 denom_lo ) lo = L_Extract_lc( L_32, &hi ); n_lo = L_Extract_lc( L_num, &n_hi ); L_32 = Mpy_32( n_hi, n_lo, hi, lo ); -#ifdef BASOP_NOGLOB L_32 = L_shl_sat( L_32, 2 ); -#else - L_32 = L_shl( L_32, 2 ); -#endif return ( L_32 ); } diff --git a/lib_com/options.h b/lib_com/options.h old mode 100644 new mode 100755 index 5d8f7fbee69782fb504c48684517c48751fc31e6..1b33049745599199a1612d5655d602450a7c877a --- a/lib_com/options.h +++ b/lib_com/options.h @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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,16 +41,14 @@ /* ################### Start DEBUGGING switches ######################## */ -#ifdef _MSC_VER -#pragma warning(disable:4310) /* cast truncates constant value this affects mainly constants tables*/ -#endif - /*#define DEBUGGING*/ /* Allows debugging message to be printed out during runtime */ #ifdef DEBUGGING #define DEBUG_MODE_INFO /* Define to output most important parameters to the subdirectory "res/" */ #define DEBUG_MODE_INFO_TWEAK /* Enable command line switch to specify subdirectory for debug info output inside "./res/" */ -#define DEBUG_FORCE_MDCT_STEREO_MODE /* Force stereo mode decision for MDCT stereo: -stereo 3 1 forces L/R coding and -stereo 3 2 forces full M/S coding */ +#define DEBUG_FORCE_MDCT_STEREO_MODE /* Force stereo mode decision for MDCT stereo: -stereo 3 1 forces L/R coding and -stereo 3 2 forces full M/S coding */ +/*#define DEBUG_FORCE_DIR*/ /* Force modes/parameters by reading from external binary files */ /*#define DBG_WAV_WRITER*/ /* Enable dbgwrite_wav() function for generating ".wav" files */ +#define SUPPORT_FORCE_TCX10_TCX20 /* VA: Enable -force tcx10|tcx20 command-line option */ #endif #define SUPPORT_JBM_TRACEFILE /* Support for JBM tracefile, which is needed for 3GPP objective/subjective testing, but not relevant for real-world implementations */ @@ -65,20 +63,15 @@ /* #################### End DEBUGGING switches ############################ */ -#define BASOP_NOGLOB /* Disable global symbols in BASOPs, Overflow/Carry in BASOPs disabled, additional BASOPs in case of Overflow */ #ifndef BASOP_NOGLOB_DEV_USE_GLOBALS #define BASOP_NOGLOB_DECLARE_LOCAL #endif -#define IVAS_FLOAT_FIXED #define IVAS_FLOAT_FIXED_CONVERSIONS /* Temporary macro to keep track of intermediate flt to fixed and fixed to flt conversions */ #define MSAN_FIX -#define ISM_DISABLE #define FIX_TMP_714 #define BASOP_NOGLOB_TMP_715 #define EVS_FUNC_MODIFIED -//#define EVS_FLOAT_ENC -#define IVAS_CNST #define REMOVE_IVAS_UNUSED_PARAMETERS_WARNING /*temporary operation on unused EVS parameters to remove warnings, these parameters will be used in IVAS */ #define MOD_BIT_ALLOC_ROM_TABLE /* Just to highlight modification in bit allocation table and to ensure these modifications doesn't affect EVS modes*/ #define SIMPLIFY_CODE_BE // Simplify synthesis loop @@ -89,9 +82,10 @@ #define NONBE_1233_HQ_CLASSIFIER_DIV_BY_ZERO /* Eri: issue 1233: Address possible division by zero in hf_spectrum_sparseness() */ #define FIX_ISSUE_1062_AND_1068_TON_ENE_EST_FX #define FIX_ISSUE_987 -#define FIX_1054_IF_ELSE_CMPLX /* VA: Fix 1054 incorrect counting of complexity when ELSE-IF sequence is encoutered in two functions */ -#define FIX_1052_COPY_CMPLX_DISCREPANCY /* VA: modify IF-ELSE statements used in Copy*() functions to avoid dependency on x[] and y[] in RAM */ +#define FIX_1054_IF_ELSE_CMPLX /* VA: Fix 1054 incorrect counting of complexity when ELSE-IF sequence is encoutered in two functions */ +#define FIX_1052_COPY_CMPLX_DISCREPANCY /* VA: modify IF-ELSE statements used in Copy*() functions to avoid dependency on x[] and y[] in RAM */ #define FIX_1049_SHR_RO_COMPLEXITY /* VA: fix for issue 1049: incorrect counting of complexity in the shr_ro() function */ +#define NONBE_IMPROVE_DIRAC_INTENSITY_PREC #define FIX_1103_OPT_L_NORM_ARR /* FhG: Optimize L_norm_arr(), avoid IF */ #define FIX_1105_OPT_MINIMUM_SL /* FhG: Optimize minimum_s(), minimum_l(), avoid IF */ #define FIX_1104_OPT_GETMINSCALEFAC /* FhG: Optimize get_min_scalefactor(), avoid IF */ @@ -100,7 +94,95 @@ #define FIX_1009_OPT_PARAMMC_RENDER /* FhG: Optimize ivas_param_mc_dec_render_fx() */ #define FIX_1109_OPTIM_MCT_STEREO_IGF_DEC /* FhG: optimize mctStereoIGF_dec_fx() */ #define FIX_1110_OPTIM_DIRAC_DECORR_PROC /* FhG: optimize ivas_dirac_dec_decorr_process() */ +#define FIX_1127_IMPROVE_SBA_MLD /* Ittiam: Avoid saturation for DiRAC reference power */ #define FIX_1100_REMOVE_LPC_RESCALING /* VA: Remove the rescaling of LPC coefficient to Q12 as residu and syn-filt are already taking care of it*/ +#define FIX_1133_IMPROVE_MC_MLD /* Ittiam: Correcting wrong updation of exponents in ivas_mc_paramupmix_param_est_enc_fx() */ +#define FIX_ISSUE_1122 /* Ittiam: Fix issue 1122: corrected incorrect scaling of a buffer leading to incorrect metadata bits */ +#define FIX_ISSUE_1125 /* Ittiam: Fix issue 1125: interfering talker flag not triggered on short test vector */ +#define FIX_1132_STACK_CORRUPTION /* Stack corruption issue due of extending index access*/ +#define FIX_ISSUE_1092 /* Ittiam: Fix for Issue 1092: BASOP asserts in stereo fx encoder for selection test inputs*/ +#define FIX_ISSUE_1135 /* Ittiam: Fix for Issue 1135: downmixing difference between float and fixed-point (DFT - stereo) */ +#define FIX_ISSUE_1148 +#define FIX_ISSUE_1147 /* Ittiam: Fix for issue 1147: Added saturation in DetectTnsFilt_fx.*/ +#define FIX_ISSUE_1150 /* Ittiam: Fix for Issue 1150: Assertion error observed in evs_enc_fx (with option stereo_dmx_evs) from tcx_ltp_find_gain function*/ +#define FIX_ISSUE_1151 /* Ittiam: Fix for Issue 1151: Assertion error observed in evs_enc_fx (with option stereo_dmx_evs) from sp_mus_classif_gmm_fx function*/ +#define FIX_ISSUE_1153 /* Ittiam: Fix for Issue 1153: Assertion error observed in stereo_dmx_evs_enc_fx from calc_poc_fx function*/ +#define FIX_ISSUE_1154 /* Ittiam: Fix for Issue 1154: Encoder crash for ParamMC 7.1 at 96kbps in ivas_param_mc_param_est_enc_fx() */ +#define FIX_ISSUE_1157 /* Ittiam: Fix for Issue 1157: Encoder crash for Stereo at 48/64kbps DTX on/off in kernel_switch_trafo_fx() */ +#define FIX_ISSUE_1152 /* Ittiam: Fix for issue 1152: Assertion error observed in evs_enc_fx (with option stereo_dmx_evs) from find_tilt_fx function*/ +#define FIX_ISSUE_1156 /* Ittiam: Fix for Issue 1156: Encoder crash for Stereo at 32kbps in SWB_BWE_encoding_ivas_fx() */ +#define FIX_DISCLAIMER /* VA: Add disclaimer for external renderer + Add info about IVAS reference version (FLP issue 1225) */ +#define FIX_ISSUE_1167 /* Ittiam: Fix for Issue 1167: Encoder crash for OSBA ISM3SBA1 at 13.2 and 16.4 kbps in gauss_L2_ivas_fx() */ +#define FIX_1009_REPLACE_DIV_SQRT_BY_ISQRT_LC /* FhG: Reduce workload of binaural rendering: replace 1./tmp & sqrt by Isqrt32 */ +#define FIX_1113_OPT_DIRAC_BIN_REND /* FhG: Various optimizations to ivas_dirac_dec_binaual_functions.c */ +#define FIX_ISSUE_1187 /* Ittiam: Fix for issue 1187: Assertion error observed in evs_enc_fx (with option stereo_dmx_evs) from bass_pf_enc_fx function*/ +#define FIX_ISSUE_1186 /* Ittiam: Fix for Issue 1186: Energy/scaling issue for ISM-1 at all bitrates */ +#define FIX_ISSUE_1165 /* Ittiam: Fix for issue 1165: Assertion in lpc2lsp_fx for OMASA LTV input */ +#define FIX_ISSUE_1185 /* Ittiam: Fix for issue 1185: Assertion in ivas_dirac_dec_binaural_internal_fx() for crash in decoder in fft30_with_cmplx_data()*/ +#define FIX_ISSUE_1209 /* Ittiam: Fix for issue 1209: Assertion exit in BASOP encoder (stereo_dmx_evs)*/ +#define FIX_ISSUE_1218 /* Ittiam: Fix for issue 1218: Assert in stereo_dft_generate_comfort_noise_fx of BASOP decoder with BASOP MASA DTX bitstream at 32 kbps*/ +#define FIX_ISSUE_1290 /* Ittiam: Fix for issue 1218: Assert in stereo_dft_generate_comfort_noise_fx of BASOP decoder with BASOP MASA DTX bitstream at 32 kbps*/ +#define IVAS_ISSUE_1188_EVS_CRASH /* Ittiam: Fix for issue 1188: Issue due to ASAN */ +#define FIX_ISSUE_1155 /* Ittiam: Fix for issue 1155: Encoder crash for Stereo at 32kbps in PostShortTerm_ivas_enc_fx()*/ +#define FIX_1010_OPT_DIV /* FhG: SVD complexity optimizations (non-be) */ +#define FIX_1010_OPT_SINGLE_RESCALE /* FhG: SVD complexity optimizations (non-be) */ +#define FIX_1010_OPT_GIVENS /* FhG: SVD complexity optimizations (non-be) */ +#define FIX_1010_OPT_GIVENS_INV /* FhG: SVD complexity optimizations (non-be) */ +#define FIX_1010_OPT_NORM_NOSAT /* FhG: SVD complexity optimizations (non-be) */ +#define FIX_1010_OPT_SEC_SINGLE_RESCALE /* FhG: SVD complexity optimizations (non-be) */ +#define FIX_1072_SPEEDUP_matrixTransp2Mul_fx /* FhG: complexity optimization (non-be) */ +#define FIX_1072_REDUCE_DIVS /* FhG: complexity optimization (non-be) */ +#define FIX_ISSUE_1230 /* Ittiam: Fix for issue 1230: Basop Enc audible differences and distortion @16kbps */ +#define NONBE_1211_DTX_BR_SWITCHING /* VA: port float issue 1211: fix crash in MASA DTX bitrate switching */ +#define FIX_1189_GSC_IVAS_OMASA /* VA: Fix for issue 1189: Bitstream desynchornization due to reading/writing of the GSC_IVAS_mode parameter */ +#define NONBE_1273_ISM_METADATA_COUNTER /* VA: BASOP issue 1265, FLP issue 1273: fix counter overflow in ISM metadata encoder */ +#define NONBE_FIX_GSC_BSTR /* VA: issue 1264 FLP (1189 BASOP): Fix bitstream synchronization between encoder and decoder in ACELP GSC in OMASA */ +#define FIX_1101_IVAS_SPAR_DEC_UPMIXER_SF /* FhG: fix for issue 1101: complexity of spar dec upmixer */ +/* Note: each compile switch (FIX_1101_...) is independent from the other ones */ +#define FIX_1101_IVAS_SPAR_DEC_UPMIXER_SF_USE_MADD_ADD_WEIGHTS /* FhG: Defines 1.0f-weight variables, uses Madd operation instead of L_add_sat */ +#define FIX_1101_IVAS_SPAR_DEC_UPMIXER_SF_SPLIT_LOOPS /* FhG: Splits single loop with IF-statements into two low-complex loops */ +#define FIX_1101_IVAS_SPAR_DEC_UPMIXER_SF_HQ_CONSTANTS /* FhG: IMPROVE PRECISION: Uses 1/6 and 1/20 in full-precise Q31 constants instead of Q15 */ +#define FIX_1101_IVAS_SPAR_DEC_UPMIXER_SF_USE_UNIQUE_SHL /* FhG: Uses unique shift amount in each loop iteration */ +#define FIX_11_1_IVAS_SPAR_DEC_UPMIXER_SF_RND_COEFFS /* FhG ivas_spar_com.c: Zeroes very small negative coeffs via L_shr_r (was L_shr) */ +#define FIX_ISSUE_1237 /* VA: replacement of Copy_Scale_sig_16_32_DEPREC() that are doing 16 bits left shift by Copy_Scale_sig_16_32_no_sat() */ +#define FIX_ISSUE_1237_KEEP_EVS_BE /* VA: Fix to keep EVS bitexactness to 26.444 */ +#define FIX_ISSUE_1214 /* Ittiam: Fix for issue 1214: Energy leakage in IGF tiles for MDCT-stereo @64kbps SWB*/ +#define FIX_881_HILBERT_FILTER /* VA: improve the precision of the Hilbert filter to remove 2kHz unwanted tone */ +#define FIX_ISSUE_1245 /* Ittiam: Fix for issue 1245: Basop Encoder: Audible noise for silent Stereo input DTX on @24.4 kbps, @32 kbps*/ +#define FIX_ISSUE_1291 /* Ittiam: Wrong use of imult1616() in ACELP rescaling */ +#define FIX_920_IGF_INIT_ERROR /* FhG: issue 920: fix bitrate mismatch in initial IGF config to avoid error message in same cases */ +#define FIX_MINOR_SVD_WMOPS_MR1010X /* FhG: Minor WMOPS tuning, bit-exact to previous version, saves about 8.2 WMOPS for MR1010 */ +#define FIX_USAN_ISSUES /* Ittiam: Fix issues reported by USAN */ +#define SVD_WMOPS_OPT /* Ittiam : SVD related optimizations */ +#define NONBE_FIX_1087_OOB_SBA_DTX_RS /* VA: issue 1087: Extend the length of the buffer for MCT decoding to avoid out-of-bound writing in SBA SID bitrate switching decoding */ +#define FIX_ISSUE_1279 /* VA: correction of wrong scaling update */ +#define FIX_ISSUE_1247 +#define NONBE_FIX_1087_OOB_SBA_DTX_RS /* VA: issue 1087: Extend the length of the buffer for MCT decoding to avoid out-of-bound writing in SBA SID bitrate switching decoding */ +#define FIX_1285_DECODER_CRASH +#define FIX_1072_SPEEDUP_gainpanning /* FhG: Minor WMOPS tuning, nonbe */ +#define FIX_1072_SPEEDUP_COMPUTEDIFUSENESS /* FhG: Minor WMOPS tuning, nonbe */ +#define FIX_1320_LOWRATE_ACELP +#define FIX_1297_OVERFLOW /* VA: fixes issue with overflows in pre-processing */ +#define FIX_1298 /* VA: fix possible assert in gaus_enc */ +#define FIX_1300_ICA_SHIFT_QUANT_IMPROV /* VA: Fix to 1300 to improve precision of the lag quantizer */ +#define FIX_1301_CORRECT_TD_CNST /* VA: Fix 1301, correct wrong constant in TD stereo */ +#define NONBE_FIX_1277_EVS_DTX_HIGH_RATE_THRESHOLD /* VA/Eri: FLP issue 1277: Fix Mismatch in DTX high-rate threshold between EVS float and BASOP */ +#define NONBE_FIX_708_OSBA_BR_SWITCHING_CRASH /* FhG: issue 708: fix crash in OSBA BR switching with long test vectors */ +//#define OPT_STEREO_32KBPS_V1 /* Optimization made in stereo decoding path for 32kbps decoding */ +#define DOT_PROD_CHOLESKY_64BIT /* FhG: Issue 1323, optimized 64 bit implementation of dot_product_cholesky() */ +#define OPT_BASOP_ADD_v1 /* optimizations to avoid usage of BASOP_Util_Add_MantExp */ +#define FIX_ISSUE_1327 /* Ittiam: Fix for issue 1327: Glitch when stereo is switching from TD to FD*/ + +/* #################### Start BASOP porting switches ############################ */ + +#define SPLIT_REND_WITH_HEAD_ROT /* Dlb,FhG: Split Rendering contributions 21 and 35 */ +#ifdef SPLIT_REND_WITH_HEAD_ROT +#define SPLIT_REND_POSE_CORRECTION_UNUSED_BITS +#define ISAR_BITSTREAM_UPDATE_LC3PLUS /* FhG: Multiple improvements to the ISAR bitstream when LC3plus is used. See MR 1456 for details. */ +#endif + #define NONBE_FIX_855_JBM_FLUSH_OFFSET /* FhG: issue #855: add missing switch here for the code in JBM flushing */ +/* #################### End BASOP porting switches ############################ */ + #endif diff --git a/lib_com/parameter_bitmaping_fx.c b/lib_com/parameter_bitmaping_fx.c index 180275d8fa5a74888eac160af018d1e3936fa3a1..0846c618be15583797a4c64ccbae74c7a21fa224 100644 --- a/lib_com/parameter_bitmaping_fx.c +++ b/lib_com/parameter_bitmaping_fx.c @@ -58,15 +58,15 @@ static Word16 FixedWidthEncoding( Word16 value, Word16 index ) void GetParameters( ParamsBitMap const *paramsBitMap, - const int16_t nArrayLength, + const Word16 nArrayLength, void const *pParameter, - int16_t **pStream, - int16_t *pnSize, - int16_t *pnBits ) + Word16 **pStream, + Word16 *pnSize, + Word16 *pnBits ) { - int16_t index; - int16_t iParam, nParams; - int16_t value; + Word16 index; + Word16 iParam, nParams; + Word16 value; void const *pSubStruct; assert( ( paramsBitMap != NULL ) && ( nArrayLength > 0 ) && ( pParameter != NULL ) && ( pStream != NULL ) && ( pnSize != NULL ) && ( pnBits != NULL ) ); @@ -168,14 +168,14 @@ void GetParameters_fx( void SetParameters( ParamsBitMap const *paramsBitMap, - const int16_t nArrayLength, + const Word16 nArrayLength, void *pParameter, - const int16_t **pStream, - int16_t *pnSize ) + const Word16 **pStream, + Word16 *pnSize ) { - int16_t index; - int16_t iParam, nParams; - int16_t value; + Word16 index; + Word16 iParam, nParams; + Word16 value; void *pSubStruct; assert( ( paramsBitMap != NULL ) && ( nArrayLength > 0 ) && ( pParameter != NULL ) && ( pStream != NULL ) && ( pnSize != NULL ) ); diff --git a/lib_com/phase_dispersion_fx.c b/lib_com/phase_dispersion_fx.c index 16feab1917e55311b85814a1317c1a21639b6c5c..723d173bcd2bda0a3699a95b67f46997665660f5 100644 --- a/lib_com/phase_dispersion_fx.c +++ b/lib_com/phase_dispersion_fx.c @@ -57,11 +57,7 @@ void phase_dispersion( move16(); prev_gain_pit[0] = gain_pit; -#ifdef BASOP_NOGLOB IF( GT_32( gain_code, L_add_o( *prev_gain_code, L_shl_o( *prev_gain_code, 1, &Overflow ), &Overflow ) ) ) -#else - IF( GT_32( gain_code, L_add( *prev_gain_code, L_shl( *prev_gain_code, 1 ) ) ) ) -#endif { IF( LT_16( state, 2 ) ) { @@ -118,13 +114,8 @@ void phase_dispersion( scale2 = getScaleFactor32( x32, L_subfr ); FOR( i = 0; i < L_subfr / 2 - 1; i++ ) { -#ifdef BASOP_NOGLOB code[i] = round_fx_sat( L_shl_sat( x32[2 * i + 0], scale2 ) ); code[L_subfr - 1 - i] = round_fx_sat( L_shl_sat( x32[2 * i + 3], scale2 ) ); -#else - code[i] = round_fx( L_shl( x32[2 * i + 0], scale2 ) ); - code[L_subfr - 1 - i] = round_fx( L_shl( x32[2 * i + 3], scale2 ) ); -#endif } code[L_subfr / 2 - 1] = round_fx( L_shl( x32[L_subfr - 2], scale2 ) ); @@ -174,12 +165,8 @@ void phase_dispersion( scale2 = getScaleFactor32( x32, L_subfr ); FOR( i = 0; i < L_subfr; i++ ) { -#ifdef BASOP_NOGLOB code[i] = round_fx_o( L_shl_o( x32[i], scale2, &Overflow ), &Overflow ); move16(); -#else - code[i] = round_fx( L_shl( x32[i], scale2 ) ); -#endif } j = sub( j, scale2 ); } diff --git a/lib_com/ppp_fx.c b/lib_com/ppp_fx.c index 92831ce2b7ed3a15c23d47e3a36e2915c3fedc6b..cc6b59bdba01a0428f477f792a6a8809e5594d80 100644 --- a/lib_com/ppp_fx.c +++ b/lib_com/ppp_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other @@ -115,11 +115,7 @@ void deemph_lpc_fx( { /* LPC_de_curr[k] = a[0]*b[k] + a[1]*b[k+1]; */ temp = mult( a_fx[0], b_fx[k] ); /* Q12 */ -#ifdef BASOP_NOGLOB LPC_de_curr_fx[k] = add_o( temp, b_fx[k + 1], &Overflow ); -#else - LPC_de_curr_fx[k] = add( temp, b_fx[k + 1] ); -#endif move16(); /* Q12 */ } @@ -141,11 +137,7 @@ void deemph_lpc_fx( { /* LPC_de_old[k] = a[0]*b[k] + a[1]*b[k+1]; */ temp = mult( a_fx[0], b_fx[k] ); /* Q12 */ -#ifdef BASOP_NOGLOB LPC_de_old_fx[k] = add_o( temp, b_fx[k + 1], &Overflow ); -#else - LPC_de_old_fx[k] = add( temp, b_fx[k + 1] ); -#endif move16(); /* Q12 */ } } diff --git a/lib_com/pred_lt4_fx.c b/lib_com/pred_lt4_fx.c index 935e6b33f9348b7cbad105a629eb3c97f22b3481..4f8dd871289b8fc78c85678a24cb737da7378c84 100644 --- a/lib_com/pred_lt4_fx.c +++ b/lib_com/pred_lt4_fx.c @@ -71,19 +71,11 @@ void pred_lt4( s = W_sat_l( s64 ); /* Q_exc + Q14 */ } #if ( INTERP_EXP != -1 ) -#ifdef BASOP_NOGLOB s = L_shl_o( s, INTERP_EXP + 1, &Overflow ); /* Q_exc + Q15 */ -#else /* BASOP_NOGLOB */ - s = L_shl( s, INTERP_EXP + 1 ); -#endif /* BASOP_NOGLOB */ #endif -#ifdef BASOP_NOGLOB excO[j] = round_fx_o( s, &Overflow ); /* Q_exc */ move16(); -#else /* BASOP_NOGLOB */ - excO[j] = round_fx( s ); -#endif } return; } @@ -163,25 +155,15 @@ void pred_lt4_tc_fx( k += UP_SAMP; L_sum = L_mac( L_sum, x0[i], win[k] ); /* Q15 */ } -#ifdef BASOP_NOGLOB L_sum = L_shl_o( L_sum, 1, &Overflow ); /* Q16 */ excO[j] = round_fx_o( L_sum, &Overflow ); /* Q0 */ move16(); -#else - L_sum = L_shl( L_sum, 1 ); /*Q0h */ - - excO[j] = round_fx( L_sum ); -#endif x0++; } FOR( i = T0; i < L_SUBFR; i++ ) { -#ifdef BASOP_NOGLOB exc[i + i_subfr] = add_o( exc[i + i_subfr], mult_r( PIT_SHARP_fx, excO[i] ), &Overflow ); /* Q0 */ -#else - exc[i + i_subfr] = add( exc[i + i_subfr], mult_r( PIT_SHARP_fx, excO[i] ) ); -#endif move16(); } } diff --git a/lib_com/preemph.c b/lib_com/preemph.c index 66a12c621786682d4a0ca6dba5f031d6d1c0616f..9ebc0f72a81c39542312ff9e6bbd3d76b5a49197 100644 --- a/lib_com/preemph.c +++ b/lib_com/preemph.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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,7 +36,7 @@ #include #include "options.h" -#include "prot.h" +#include "prot_fx.h" #include "wmc_auto.h" /*-------------------------------------------------------------* diff --git a/lib_com/preemph_fx.c b/lib_com/preemph_fx.c index 0864323b41f02ad4a6449df110d23fb1b8b3eeb1..0790f6c3f2c8fdda954347962a335a029e7057f1 100644 --- a/lib_com/preemph_fx.c +++ b/lib_com/preemph_fx.c @@ -26,18 +26,10 @@ void preemph_copy_fx( move16(); FOR( i = lg - 1; i > 0; i-- ) { -#ifdef BASOP_NOGLOB y[i] = msu_ro( L_deposit_h( x[i] ), x[i - 1], mu, &Overflow ); /* Qx */ -#else - y[i] = msu_r( L_deposit_h( x[i] ), x[i - 1], mu ); -#endif move16(); } -#ifdef BASOP_NOGLOB y[0] = msu_ro( L_deposit_h( x[0] ), *mem, mu, &Overflow ); /* Qx */ -#else - y[0] = msu_r( L_deposit_h( x[0] ), *mem, mu ); -#endif move16(); *mem = temp; /* Qx */ @@ -61,18 +53,10 @@ void preemph_copy_32fx( move16(); FOR( i = lg - 1; i > 0; i-- ) { -#ifdef BASOP_NOGLOB y[i] = L_msu_o( L_deposit_h( x[i] ), x[i - 1], mu, &Overflow ); /* Qx+16 */ -#else - y[i] = L_msu( L_deposit_h( x[i] ), x[i - 1], mu ); -#endif move16(); } -#ifdef BASOP_NOGLOB y[0] = L_msu_o( L_deposit_h( x[0] ), *mem, mu, &Overflow ); /* Qx+16 */ -#else - y[0] = L_msu( L_deposit_h( x[0] ), *mem, mu ); -#endif move16(); *mem = temp; /* Qx */ @@ -114,30 +98,18 @@ void E_UTIL_f_preemph2( FOR( i = lg - 1; i > 0; i-- ) { - L_tmp = L_mult( signal[i], 16384 ); /* Qx + 15 */ -#ifdef BASOP_NOGLOB + L_tmp = L_mult( signal[i], 16384 ); /* Qx + 15 */ L_tmp = L_msu0_o( L_tmp, signal[i - 1], mu, &Overflow ); /* Qx + 15 */ L_tmp = L_shl_o( L_tmp, add( shift, 1 ), &Overflow ); /* Qx + shift + 16 */ signal[i] = round_fx_o( L_tmp, &Overflow ); /* Qx + shift */ move16(); -#else - L_tmp = L_msu0( L_tmp, signal[i - 1], mu ); - L_tmp = L_shl( L_tmp, add( shift, 1 ) ); - signal[i] = round_fx( L_tmp ); -#endif } - L_tmp = L_mult( signal[0], 16384 ); /* Qx + 15 */ -#ifdef BASOP_NOGLOB + L_tmp = L_mult( signal[0], 16384 ); /* Qx + 15 */ L_tmp = L_msu0_o( L_tmp, *mem, mu, &Overflow ); /* Qx + 15 */ L_tmp = L_shl_o( L_tmp, add( shift, 1 ), &Overflow ); /* Qx + shift + 16 */ signal[0] = round_fx_o( L_tmp, &Overflow ); /* Qx + shift */ move16(); -#else - L_tmp = L_msu0( L_tmp, *mem, mu ); - L_tmp = L_shl( L_tmp, add( shift, 1 ) ); - signal[0] = round_fx( L_tmp ); -#endif *mem = temp; /* Qx */ move16(); diff --git a/lib_com/prot.h b/lib_com/prot.h deleted file mode 100644 index c55786ae4d8aafbb747c9a1e264bde1b661aa8f3..0000000000000000000000000000000000000000 --- a/lib_com/prot.h +++ /dev/null @@ -1,8379 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#ifndef PROT_H -#define PROT_H - -#include -#include -#include -#include "options.h" -#include "typedef.h" -#include "stat_enc.h" -#include "stat_dec.h" -#include "stat_com.h" -#include "ivas_stat_com.h" -#include "ivas_stat_enc.h" -#include "ivas_stat_dec.h" -#include "cnst.h" -#include "stl.h" -#include "ivas_error_utils.h" - - -/*----------------------------------------------------------------------------------* - * Prototypes of global macros - *----------------------------------------------------------------------------------*/ - -#ifndef min -#define min( x, y ) ( ( x ) < ( y ) ? ( x ) : ( y ) ) -#endif - -#ifndef max -#define max( x, y ) ( ( x ) > ( y ) ? ( x ) : ( y ) ) -#endif - -#ifndef TRUNC -#define TRUNC( x ) ( (int16_t) ( ( ( x ) >= 32767. ? 32767 : ( ( x ) <= -32768. ? -32768 : ( x ) ) ) + 0.5 ) ) -#endif - -#define log_base_2( x ) ( (double) log( (double) ( x ) ) * 1.4426950408889634074f ) -#define round_f( x ) ( ( ( x ) > 0 ) ? (int32_t) ( ( x ) + 0.5f ) : ( -(int32_t) ( ( -x ) + 0.5f ) ) ) - -#ifndef ABSVAL -#define ABSVAL( a ) ( ( a ) >= 0 ? ( a ) : ( -( a ) ) ) -#endif - -#ifndef SQR -#define SQR( a ) ( ( a ) * ( a ) ) -#endif - -#ifndef SWAP -#define SWAP( a, b ) \ - { \ - tempr = ( a ); \ - ( a ) = ( b ); \ - ( b ) = tempr; \ - } -#endif - -#ifndef swap -#define swap( x, y, type ) \ - { \ - type u__p; \ - u__p = x; \ - x = y; \ - y = u__p; \ - } -#endif - -#define set_max( a, b ) \ - { \ - if ( ( b ) > *a ) \ - { \ - *a = ( b ); \ - } \ - } /* If the first argument is already the highes or lowest, nothing is done. */ -#define set_min( a, b ) \ - { \ - if ( ( b ) < *a ) \ - { \ - *a = ( b ); \ - } \ - } /* Otherwise, the 2nd arg is stored at the address of the first arg. */ - - -/*----------------------------------------------------------------------------------* - * MODE1 prototypes - *----------------------------------------------------------------------------------*/ - -/*! r: inverse square root of input value */ -float inv_sqrt( - const float x /* i : input value */ -); - -/*! r: output random value */ -int16_t own_random( - int16_t *seed /* i/o: random seed */ -); - -/*! r: sign of x (+1/-1) */ -float sign( - const float x /* i : input value of x */ -); - -/*! r: logarithm2 of x */ -float log2_f( - const float x /* i : input value of x */ -); - -int16_t norm_ul_float( - uint32_t UL_var1 ); - -/*! r: sum of all vector elements */ -int16_t sum_s( - const int16_t *vec, /* i : input vector */ - const int16_t lvec /* i : length of input vector */ -); - -/*! r: sum of all vector elements */ -int32_t sum_l( - const int32_t *vec, /* i : input vector */ - const int16_t lvec /* i : length of input vector */ -); - -/*! r: sum of all vector elements */ -float sum_f( - const float *vec, /* i : input vector */ - const int16_t lvec /* i : length of input vector */ -); - -/*! r: sum of all squared vector elements */ -float sum2_f( - const float *vec, /* i : input vector */ - const int16_t lvec /* i : length of input vector */ -); - -void set_c( - int8_t y[], /* i/o: Vector to set */ - const int8_t a, /* i : Value to set the vector to */ - const int32_t N /* i : Length of the vector */ -); - -void set_s( - int16_t y[], /* i/o: Vector to set */ - const int16_t a, /* i : Value to set the vector to */ - const int16_t N /* i : Lenght of the vector */ -); - -void set_l( - int32_t y[], /* i/o: Vector to set */ - const int32_t a, /* i : Value to set the vector to */ - const int16_t N /* i : Length of the vector */ -); - -void set_f( - float y[], /* i/o: Vector to set */ - const float a, /* i : Value to set the vector to */ - const int16_t N /* i : Lenght of the vector */ -); - -void set_zero_fx( - Word32 *vec, /* o : input vector */ - const Word16 lvec /* i : length of the vector */ -); -void set_zero2_fx( - Word32 *vec, /* o : input vector */ - const Word32 lvec /* i : length of the vector */ -); -void set16_zero_fx( - Word16 *vec, /* o : input vector */ - const Word16 lvec /* i : length of the vector */ -); - -void set_zero( - float *vec, /* o : input vector */ - const int16_t lvec /* i : length of the vector */ -); - -void mvr2r( - const float x[], /* i : input vector */ - float y[], /* o : output vector */ - const int16_t n /* i : vector size */ -); - -void mvs2s( - const int16_t x[], /* i : input vector */ - int16_t y[], /* o : output vector */ - const int16_t n /* i : vector size */ -); - -uint32_t mvr2s( - const float x[], /* i : input vector */ - int16_t y[], /* o : output vector */ - const int16_t n /* i : vector size */ -); - -void mvs2r( - const int16_t x[], /* i : input vector */ - float y[], /* o : output vector */ - const int16_t n /* i : vector size */ -); - -void mvl2l( - const int32_t x[], /* i : input vector */ - int32_t y[], /* o : output vector */ - const int16_t n /* i : vector size */ -); - - -/*! r: index of the maximum value in the input vector */ -int16_t maximum( - const float *vec, /* i : input vector */ - const int16_t lvec, /* i : length of input vector */ - float *max_val /* o : maximum value in the input vector */ -); -/*! r: index of the maximum value in the input vector */ -int16_t maximumAbs( - const float *vec, /* i : input vector */ - const int16_t lvec, /* i : length of input vector */ - float *max_val /* o : maximum value in the input vector */ -); - -Word16 maximumAbs_l( - const Word32 *vec, /* i : input vector */ - const Word16 lvec, /* i : length of input vector */ - Word32 *max_val /* o : maximum value in the input vector */ -); - -/*! r: index of the minimum value in the input vector */ -int16_t minimum( - const float *vec, /* i : input vector */ - const int16_t lvec, /* i : length of input vector */ - float *min_val /* o : minimum value in the input vector */ -); - -/*! r: index of the minimum value in the input vector */ -int16_t minimum_s( - const int16_t *vec, /* i : Input vector */ - const int16_t lvec, /* i : Vector length */ - int16_t *min_val /* o : minimum value in the input vector */ -); - -/*! r: return index with max energy value in vector */ -int16_t emaximum( - const float *vec, /* i : input vector */ - const int16_t lvec, /* i : length of input vector */ - float *ener_max /* o : maximum energy value */ -); - -/*! r: vector mean */ -float mean( - const float *vec, /* i : input vector */ - const int16_t lvec /* i : length of input vector */ -); - -/*! r: dot product of x[] and y[] */ -float dotp( - const float x[], /* i : vector x[] */ - const float y[], /* i : vector y[] */ - const int16_t n /* i : vector length */ -); - -void conv( - const float x[], /* i : input vector */ - const float h[], /* i : impulse response (or second input vector) */ - float y[], /* o : output vetor (result of convolution) */ - const int16_t L /* i : vector size */ -); - -void fir( - const float x[], /* i : input vector */ - const float h[], /* i : impulse response of the FIR filter */ - float y[], /* o : output vector (result of filtering) */ - float mem[], /* i/o: memory of the input signal (M samples) */ - const int16_t L, /* i : input vector size */ - const int16_t K, /* i : order of the FIR filter (M+1 coefs.) */ - const int16_t upd /* i : 1 = update the memory, 0 = not */ -); - -void v_add( - const float x1[], /* i : Input vector 1 */ - const float x2[], /* i : Input vector 2 */ - float y[], /* o : Output vector that contains vector 1 + vector 2 */ - const int16_t N /* i : Vector length */ -); - -void v_sub( - const float x1[], /* i : Input vector 1 */ - const float x2[], /* i : Input vector 2 */ - float y[], /* o : Output vector that contains vector 1 - vector 2 */ - const int16_t N /* i : Vector length */ -); - -void v_mult( - const float x1[], /* i : Input vector 1 */ - const float x2[], /* i : Input vector 2 */ - float y[], /* o : Output vector that contains vector 1 .* vector 2*/ - const int16_t N /* i : Vector length */ -); - -void v_multc( - const float x[], /* i : Input vector */ - const float c, /* i : Constant */ - float y[], /* o : Output vector that contains c*x */ - const int16_t N /* i : Vector length */ -); - -/*! r: index of the winning codeword */ -int16_t squant( - const float x, /* i : scalar value to quantize */ - float *xq, /* o : quantized value */ - const float cb[], /* i : codebook */ - const int16_t cbsize /* i : codebook size */ -); - -int16_t squant_int( - uint8_t x, /* i : scalar value to quantize */ - uint8_t *xq, /* o : quantized value */ - const uint8_t *cb, /* i : codebook */ - const int16_t cbsize /* i : codebook size */ -); - -/*! r: index of the winning codevector */ -int16_t vquant( - float x[], /* i : vector to quantize */ - const float x_mean[], /* i : vector mean to subtract (0 if none) */ - float xq[], /* o : quantized vector */ - const float cb[], /* i : codebook */ - const int16_t dim, /* i : dimension of codebook vectors */ - const int16_t cbsize /* i : codebook size */ -); - -/*! r: index of the winning codevector */ -int16_t w_vquant( - float x[], /* i : vector to quantize */ - const float x_mean[], /* i : vector mean to subtract (0 if none) */ - const int16_t weights[], /* i : error weights */ - float xq[], /* o : quantized vector */ - const float cb[], /* i : codebook */ - const int16_t dim, /* i : dimension of codebook vectors */ - const int16_t cbsize, /* i : codebook size */ - const int16_t reverse /* i : reverse codebook vectors */ -); - -/*! r: index of the winning codeword */ -int16_t usquant( - const float x, /* i : scalar value to quantize */ - float *xq, /* o : quantized value */ - const float qlow, /* i : lowest codebook entry (index 0) */ - const float delta, /* i : quantization step */ - const int16_t cbsize /* i : codebook size */ -); - -/*! r: dequanzited gain */ -float usdequant( - const int16_t idx, /* i : quantizer index */ - const float qlow, /* i : lowest codebook entry (index 0) */ - const float delta /* i : quantization step */ -); - -void v_sort_float( - float *r, /* i/o: Vector to be sorted in place */ - const int16_t lo, /* i : Low limit of sorting range */ - const int16_t up /* i : High limit of sorting range */ -); - -void sort( - uint16_t *x, /* i/o: Vector to be sorted */ - uint16_t len /* i/o: vector length */ -); - -void sort_l( - Word32 *x, /* i/o: Vector to be sorted */ - Word16 len /* i/o: vector length */ -); - -/*! r: variance of vector */ -float var( - const float *x, /* i : input vector */ - const int16_t len /* i : length of inputvector */ -); - -/*! r: standard deviation */ -float std_dev( - const float *x, /* i : input vector */ - const int16_t len /* i : length of the input vector */ -); - -/*! r: the dot product x'*A*x */ -float dot_product_mat( - const float *x, /* i : vector x */ - const float *A, /* i : matrix A */ - const int16_t m /* i : vector length */ -); - -float root_a( - float a ); - -float root_a_over_b( - float a, - float b ); - -void polezero_filter( - const float *in, /* i : input vector */ - float *out, /* o : output vector */ - const int16_t N, /* i : input vector size */ - const float *b, /* i : numerator coefficients */ - const float *a, /* i : denominator coefficients */ - const int16_t order, /* i : filter order */ - float *mem /* i/o: filter memory */ -); - -double rint_new( - double x /* i/o: Round to the nearest integer with mid point exception */ -); - -double anint( - double x /* i/o: Round to the nearest integer */ -); - -/*! r: Output either 1 if Numeric, 0 if NaN or Inf */ -int16_t is_numeric_float( - float x /* i : Input value which is checked if numeric or not */ -); - -void delay_signal_float( - float x[], /* i/o: signal to be delayed */ - const int16_t len, /* i : length of the input signal */ - float mem[], /* i/o: synchronization memory */ - const int16_t delay /* i : delay in samples */ -); - -ivas_error push_indice( - BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ - int16_t id, /* i : ID of the indice */ - uint16_t value, /* i : value of the quantized indice */ - int16_t nb_bits /* i : number of bits used to quantize the indice */ -); - -ivas_error push_next_indice( - BSTR_ENC_HANDLE hBstr, - UWord16 value, /* i : value of the quantized indice */ - Word16 nb_bits /* i : number of bits used to quantize the indice */ -); - -ivas_error push_next_bits( - BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ - const UWord16 bits[], /* i : bit buffer to pack, sequence of single bits */ - const Word16 nb_bits /* i : number of bits to pack */ -); - -/*! r: maximum number of indices */ -Word16 get_ivas_max_num_indices_fx( - const IVAS_FORMAT ivas_format, /* i : IVAS format */ - const Word32 ivas_total_brate /* i : IVAS total bitrate */ -); - -/*! r: maximum number of indices */ -int16_t get_BWE_max_num_indices( - const int32_t extl_brate /* i : extensiona layer bitrate */ -); - -/*! r: maximum number of indices */ -Word16 get_ivas_max_num_indices_metadata_fx( - const IVAS_FORMAT ivas_format, /* i : IVAS format */ - const Word32 ivas_total_brate /* i : IVAS total bitrate */ -); -ivas_error ind_list_realloc( - INDICE_HANDLE old_ind_list, /* i : pointer to the beginning of the old buffer of indices */ - const int16_t max_num_indices, /* i : new maximum number of allowed indices in the list */ - Encoder_Struct *st_ivas /* i : IVAS encoder structure */ -); - -ivas_error check_ind_list_limits( - BSTR_ENC_HANDLE hBstr /* i/o: encoder bitstream handle */ -); - -void move_indices( - INDICE_HANDLE old_ind_list, /* i/o: old location of indices */ - INDICE_HANDLE new_ind_list, /* i/o: new location of indices */ - const int16_t nb_indices /* i : number of moved indices */ -); - -/*! r: index of the indice in the list, -1 if not found */ -int16_t find_indice( - BSTR_ENC_HANDLE hBstr, /* i : encoder bitstream handle */ - const int16_t id, /* i : ID of the indice */ - uint16_t *value, /* o : value of the quantized indice */ - int16_t *nb_bits /* o : number of bits used to quantize the indice */ -); - -/*! r: number of deleted indices */ -uint16_t delete_indice( - BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ - const int16_t id /* i : ID of the indice */ -); - -/*! r: value of the indice */ -uint16_t get_next_indice( - Decoder_State *st, /* i/o: decoder state structure */ - int16_t nb_bits /* i : number of bits that were used to quantize the indice */ -); - -/*! r: value of the indice */ -uint16_t get_next_indice_1( - Decoder_State *st /* i/o: decoder state structure */ -); - -void get_next_indice_tmp( - Decoder_State *st, /* o : decoder state structure */ - int16_t nb_bits /* i : number of bits that were used to quantize the indice */ -); - -/*! r: value of the indice */ -uint16_t get_indice( - Decoder_State *st, /* i/o: decoder state structure */ - int16_t pos, /* i : absolute position in the bitstream */ - int16_t nb_bits /* i : number of bits that were used to quantize the indice */ -); - -/*! r: value of the indice */ -uint16_t get_indice_1( - Decoder_State *st, /* i/o: decoder state structure */ - int16_t pos /* i : absolute position in the bitstream */ -); - -void reset_indices_enc( - BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ - const int16_t max_num_indices /* i : max number of indices */ -); - -void reset_indices_dec( - Decoder_State *st /* i/o: decoder state structure */ -); - -ivas_error write_indices_ivas( - Encoder_Struct *st_ivas, /* i/o: encoder state structure */ - uint16_t *bit_stream, /* i/o: output bitstream */ - uint16_t *num_bits /* i/o: number of bits written to output */ -); - -Word16 rate2EVSmode_float( - const Word32 brate, /* i : bitrate */ - int16_t *is_amr_wb /* o : (flag) does the bitrate belong to AMR-WB? Can be NULL */ -); - - -/*! r: 1 = OK, 0 = something wrong */ -ivas_error read_indices( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ - uint16_t bit_stream[], /* i : bitstream buffer */ - UWord16 num_bits, /* i : number of bits in bitstream */ - int16_t *prev_ft_speech, - int16_t *CNG, - int16_t bfi /* i : bad frame indicator */ -); - - -void ivas_set_bitstream_pointers( - Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */ -); - -Decoder_State **reset_elements( - Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */ -); - - -void convertSerialToBytestream( - const uint16_t *const serial, /* i : input serial bitstream with values 0 and 1 */ - const uint16_t num_bits, /* i : number of bits in the input bitstream */ - uint8_t *const bytestream /* o : output compact bitstream (bytestream) */ -); - -void convertBytestreamToSerial( - const uint8_t *const bytestream, /* i : input compact bitstream (bytestream) */ - const uint16_t num_bits, /* i : number of bits in the input bitstream */ - uint16_t *const serial /* o : output serial bitstream with values 0 and 1 */ -); - -void mdct_switching_dec( - Decoder_State *st /* i/o: decoder state structure */ -); - -void evs_dec_previewFrame_float( - uint8_t *bitstream, /* i : bitstream pointer */ - int16_t bitstreamSize, /* i : bitstream size */ - int16_t *partialCopyFrameType, /* o : frame type of the partial copy */ - int16_t *partialCopyOffset /* o : offset of the partial copy relative to the primary copy */ -); - - -void getPartialCopyInfo_float( - Decoder_State *st, /* i : decoder state structure */ - int16_t *sharpFlag ); - -void get_NextCoderType( - uint8_t *bitstream, /* i : bitstream */ - int16_t *next_coder_type /* o : next coder type */ -); - -int16_t print_disclaimer( - FILE *fPtr ); - - -/*! r: delay value in ns */ -int32_t get_delay( - const int16_t enc_dec, /* i : encoder/decoder flag */ - const int32_t io_fs, /* i : input/output sampling frequency */ - const IVAS_FORMAT ivas_format, /* i : IVAS format */ - HANDLE_CLDFB_FILTER_BANK hCldfb /* i : Handle of Cldfb analysis */ -); - -void decision_matrix_enc( - Encoder_State *st, /* i/o: encoder state structure */ - int16_t *hq_core_type /* o : HQ core type */ -); - -void signaling_enc( - Encoder_State *st /* i : encoder state structure */ -); - -int16_t signaling_mode1_tcx20_enc( - Encoder_State *st, /* i/o: encoder state structure */ - const int16_t push /* i : flag to push indice */ -); - -void decision_matrix_dec( - Decoder_State *st, /* i/o: decoder state structure */ - int16_t *sharpFlag, /* o : formant sharpening flag */ - int16_t *hq_core_type, /* o : HQ core type */ - int16_t *core_switching_flag /* o : ACELP->HQ switching frame flag */ -); - - -void amr_wb_dec_init( - AMRWB_IO_DEC_HANDLE hAmrwb_IO /* i/o: AMR-WB IO data handle */ -); - -void hf_synth_amr_wb_init( - AMRWB_IO_DEC_HANDLE hAmrwb_IO /* i/o: AMR-WB IO data handle */ -); - -void hf_synth_amr_wb_reset( - AMRWB_IO_DEC_HANDLE hAmrwb_IO, /* i/o: AMR-WB IO data handle */ - ZERO_BWE_DEC_HANDLE hBWE_zero /* o : zero BWE decoder handle */ -); - -void hf_synth_amr_wb( - AMRWB_IO_DEC_HANDLE hAmrwb_IO, /* i/o: AMR-WB IO data handle */ - ZERO_BWE_DEC_HANDLE hBWE_zero, /* o : zero BWE decoder handle */ - const int32_t core_brate, /* i : core bitrate */ - const int16_t output_frame, /* i : output frame length */ - const float *Aq, /* i : quantized Az */ - const float *exc, /* i : excitation at 12.8 kHz */ - float *synth, /* i/o: synthesis signal at 12.8 kHz */ - int16_t *amr_io_class, /* i : signal class (determined by FEC algorithm) */ - float *synth_out, /* i/o: synthesis signal at output Fs */ - float fmerit, /* i : classify parameter from FEC */ - const int16_t *hf_gain, /* i : decoded HF gain */ - const float *voice_factors, /* i : voicing factors */ - const float pitch_buf[], /* i : pitch buffer */ - const float ng_ener_ST, /* i : Noise gate - short-term energy */ - const float *lsf_new /* i : ISF vector */ -); - -void hf_cod_init( - float *mem_hp400_enc, /* o : memory of hp 400 Hz filter */ - float *mem_hf1_enc, /* o : HF band-pass filter memory */ - float *mem_syn_hf_enc, /* o : HF synthesis memory */ - float *mem_hf2_enc, /* o : HF band-pass filter memory */ - float *gain_alpha /* o : smoothing gain for transitions between active and inactive frames */ -); - -void hf_cod( - const int32_t core_brate, /* i : core bitrate */ - const float *speech16k, /* i : original speech at 16 kHz */ - const float Aq[], /* i : quantized Aq */ - const float exc[], /* i : excitation at 12.8 kHz */ - float synth[], /* i : 12.8kHz synthesis signal */ - int16_t *seed2_enc, /* i/o: random seed for HF noise gen */ - float *mem_hp400_enc, /* i/o: memory of hp 400 Hz filter */ - float *mem_syn_hf_enc, /* i/o: HF synthesis memory */ - float *mem_hf1_enc, /* i/o: HF band-pass filter memory */ - float *mem_hf2_enc, /* i/o: HF band-pass filter memory */ - const int16_t *dtxHangoverCount, - float *gain_alpha, /* i/o: smoothing gain for transitions between active and inactive frames */ - int16_t *hf_gain /* o : HF gain to be transmitted to decoder */ -); - -void hf_synth_init( - ZERO_BWE_DEC_HANDLE hBWE_zero /* o : zero BWE decoder handle */ -); - -void hf_synth_reset( - ZERO_BWE_DEC_HANDLE hBWE_zero /* o : zero BWE decoder handle */ -); - -void hf_synth( - ZERO_BWE_DEC_HANDLE hBWE_zero, /* o : zero BWE decoder handle */ - const int32_t core_brate, /* i : core bitrate */ - const int16_t output_frame, /* i : output frame length */ - const float *Aq, /* i : quantized Az */ - const float *exc, /* i : excitation at 12.8 kHz */ - float *synth, /* i/o: 12.8kHz synthesis signal */ - float *synth16k /* i/o: 16kHz synthesis signal */ -); - -void fft_rel( - float x[], /* i/o: input/output vector */ - const int16_t n, /* i : vector length */ - const int16_t m /* i : log2 of vector length */ -); - -void ifft_rel( - float io[], /* i/o: input/output vector */ - const int16_t n, /* i : vector length */ - const int16_t m /* i : log2 of vector length */ -); - -void preemph( - float *signal, /* i/o: signal */ - const float mu, /* i : preemphasis factor */ - const int16_t L, /* i : vector size */ - float *mem /* i/o: memory (x[-1]) */ -); -void preemph_ivas_fx( - Word32 *signal, /* i/o: signal Qx*/ - const Word16 mu, /* i : preemphasis factor Q15*/ - const Word16 L, /* i : vector size Q0*/ - Word32 *mem /* i/o: memory (x[-1]) Qx*/ -); -void cb_shape( - const int16_t preemphFlag, /* i : flag for pre-emphasis */ - const int16_t pitchFlag, /* i : flag for pitch sharpening */ - const int16_t scramblingFlag, /* i : flag for phase scrambling */ - const int16_t formantFlag, /* i : flag for formant sharpening */ - const int16_t formantTiltFlag, /* i : flag for formant tilt */ - const float g1, /* i : formant sharpening numerator weighting */ - const float g2, /* i : formant sharpening denominator weighting */ - const float *p_Aq, /* i : LP filter coefficients */ - float *code, /* i/o: signal to shape */ - const float tilt_code, /* i : tilt of code */ - const float pt_pitch, /* i : pointer to current subframe fractional pitch*/ - const int16_t L_subfr /* i : subfframe length */ -); - -void CNG_exc( - const int32_t core_brate, /* i : core bitrate */ - const int16_t L_frame, /* i : length of the frame */ - float *Enew, /* i/o: decoded SID energy */ - int16_t *seed, /* i/o: random generator seed */ - float exc[], /* o : current non-enhanced excitation */ - float exc2[], /* o : current enhanced excitation */ - float *lp_ener, /* i/o: LP filtered E */ - const int32_t last_core_brate, /* i : previous frame core bitrate */ - int16_t *first_CNG, /* i/o: first CNG frame flag for energy init. */ - int16_t *cng_ener_seed, /* i/o: random generator seed for CNG energy */ - float bwe_exc[], /* o : excitation for SWB TBE */ - const int16_t allow_cn_step, /* i : allow CN step */ - int16_t *last_allow_cn_step, /* i/o: last CN_step */ - const int16_t num_ho, /* i : number of selected hangover frames */ - float q_env[], - float *lp_env, - float *old_env, - float *exc_mem, - float *exc_mem1, - int16_t *sid_bw, - int16_t *cng_ener_seed1, - float exc3[], - const int16_t Opt_AMR_WB, /* i : AMR-WB interop flag */ - const int16_t element_mode /* i : IVAS Element mode */ -); - - -void cng_params_postupd( - const int16_t ho_circ_ptr, /* i : pointer for CNG averaging buffers */ - int16_t *cng_buf_cnt, /* i/o: counter for CNG store buffers */ - const float *cng_exc2_buf, /* i : Excitation buffer */ - const int32_t *cng_brate_buf, /* i : bitrate buffer */ - float ho_env_circ[], /* i/o: Envelope buffer */ - const int16_t element_mode, /* i : Element mode */ - const int16_t bwidth /* i : audio bandwidth */ -); - -void calculate_hangover_attenuation_gain( - Encoder_State *st, /* i : encoder state structure */ - float *att, /* o : attenuation factor */ - const int16_t vad_hover_flag /* i : VAD hangover flag */ -); - -int16_t get_cng_mode_ivas( - const int32_t last_active_brate /* i : last active bitrate */ -); - -void disf_ns_28b( - int16_t *indice, /* i : quantized indices, use indice[0] = -1 in the decoder*/ - float *isf_q /* o : ISF in the frequency domain (0..6400) */ -); - -void limit_T0( - const int16_t L_frame, /* i : length of the frame */ - const int16_t delta, /* i : Half the close-loop searched interval */ - const int16_t pit_flag, /* i : selecting absolute(0) or delta(1) pitch quantization */ - const int16_t limit_flag, /* i : flag for limits (0=restrained, 1=extended) */ - const int16_t T0, /* i : rough pitch estimate around which the search is done */ - const int16_t T0_frac, /* i : pitch estimate fractional part */ - int16_t *T0_min, /* o : lower pitch limit */ - int16_t *T0_max /* o : higher pitch limit */ -); - -/*! r: interpolated value */ -float interpolation( - const float *x, /* i : input vector */ - const float *win, /* i : interpolation window */ - const int16_t frac, /* i : fraction */ - const int16_t up_samp, /* i : upsampling factor */ - const int16_t nb_coef /* i : nb of filter coef */ -); - -void deemph( - float *signal, /* i/o: signal */ - const float mu, /* i : deemphasis factor */ - const int16_t L, /* i : vector size */ - float *mem /* i/o: memory (y[-1]) */ -); - -void weight_a( - const float *a, /* i : LP filter coefficients */ - float *ap, /* o : weighted LP filter coefficients */ - const float gamma, /* i : weighting factor */ - const int16_t m /* i : order of LP filter */ -); - -void weight_a_subfr( - const int16_t nb_subfr, /* i : number of subframes */ - const float *a, /* i : LP filter coefficients */ - float *ap, /* o : weighted LP filter coefficients */ - const float gamma, /* i : weighting factor */ - const int16_t m /* i : order of LP filter */ -); - -void syn_12k8( - const int16_t L_frame, /* i : length of the frame */ - const float *Aq, /* i : LP filter coefficients */ - const float *exc, /* i : input signal */ - float *synth, /* o : output signal */ - float *mem, /* i/o: initial filter states */ - const int16_t update_m /* i : update memory flag: 0 --> no memory update */ -); /* 1 --> update of memory */ - -void syn_filt( - const float a[], /* i : LP filter coefficients */ - const int16_t m, /* i : order of LP filter */ - const float x[], /* i : input signal */ - float y[], /* o : output signal */ - const int16_t l, /* i : size of filtering */ - float mem[], /* i/o: initial filter states */ - const int16_t update_m /* i : update memory flag: 0 --> no memory update */ -); /* 1 --> update of memory */ - -void synth_mem_updt2_flt( - const int16_t L_frame, /* i : frame length */ - const int16_t last_L_frame, /* i : frame length */ - float old_exc[], /* i/o: excitation buffer */ - float mem_syn_r[], /* i/o: synthesis filter memory */ - float mem_syn2[], /* o : synthesis filter memory for find_target */ - float mem_syn[], /* o : synthesis filter memory for find_target */ - const int16_t dec /* i : flag for decoder indication */ -); - -void int_lsp( - const int16_t L_frame, /* i : length of the frame */ - const float lsp_old[], /* i : LSPs from past frame */ - const float lsp_new[], /* i : LSPs from present frame */ - float *Aq, /* o : LP coefficients in both subframes */ - const int16_t m, /* i : order of LP filter */ - const float *int_coeffs, /* i : interpolation coefficients */ - const int16_t Opt_AMR_WB /* i : flag indicating AMR-WB IO mode */ -); - -void int_lsp4( - const int16_t L_frame, /* i : length of the frame */ - const float lsp_old[], /* i : previous end-frame LSPs */ - const float lsp_mid[], /* i : current mid-frame LSPs */ - const float lsp_new[], /* i : current end-frame LSPs */ - float *Aq, /* o : LP coefficients in both subframes */ - const int16_t m, /* i : order of LP filter */ - int16_t relax_prev_lsf_interp /* i : relax prev frame lsf interp after erasure */ -); - -/*! r: length of output */ -int16_t modify_Fs( - const float sigIn[], /* i : signal to decimate */ - const int16_t lg, /* i : length of input */ - const int32_t fin, /* i : frequency of input */ - float sigOut[], /* o : decimated signal */ - const int32_t fout, /* i : frequency of output */ - float mem[], /* i/o: filter memory */ - const int16_t nblp /* i : flag indicating if NB low-pass is applied */ -); - -void pred_lt4_flt( - const float excI[], /* i : input excitation buffer */ - float excO[], /* o : output excitation buffer */ - const int16_t T0, /* i : integer pitch lag */ - int16_t frac, /* i : fraction of lag */ - const int16_t L_subfr, /* i : subframe size */ - const float *win, /* i : interpolation window */ - const int16_t nb_coef, /* i : nb of filter coef */ - const int16_t up_sample /* i : up_sample */ -); - -void pred_lt4_tc_flt( - float exc[], /* i : excitation buffer */ - const int16_t T0, /* i : integer pitch lag */ - int16_t frac, /* i : fraction of lag */ - const float *win, /* i : interpolation window */ - const int16_t imp_pos, /* i : glottal impulse position */ - const int16_t i_subfr /* i : subframe index */ -); - -void residu( - const float *a, /* i : LP filter coefficients */ - const int16_t m, /* i : order of LP filter */ - const float *x, /* i : input signal (usually speech) */ - float *y, /* o : output signal (usually residual) */ - const int16_t l /* i : size of filtering */ -); - -void calc_residu( - const float *speech, /* i : weighted speech signal */ - float *res, /* o : residual signal */ - const float *p_Aq, /* i : quantized LP filter coefficients */ - const int16_t L_frame /* i : size of frame */ -); - -/*! r: impulse response energy */ -float enr_1_Az( - const float Aq[], /* i : LP filter coefs */ - const int16_t len /* i : impulse response length */ -); - -void Es_pred_enc( - float *Es_pred, /* o : predicited scaled innovation energy */ - int16_t *Es_pred_indice, /* o : indice corresponding to above parameter */ - const int16_t L_frame, /* i : length of the frame */ - const int16_t L_subfr, /* i : length of the subframe */ - const float *res, /* i : residual signal */ - const float *voicing, /* i : normal. correlattion in three 1/2frames */ - const int16_t nb_bits, /* i : allocated number of bits */ - const int16_t no_ltp /* i : no_ltp flag */ -); - -void create_offset( - UWord32 *offset_scale1, - UWord32 *offset_scale2, - const int16_t mode, - const int16_t prediction_flag ); - -float mslvq( - float *pTmp, /* i : M-dimensional input vector */ - float *quant, /* o : quantized vector */ - float *cv_out, /* o : corresponding 8-dim lattice codevectors (without the scaling) */ - int16_t *idx_lead, /* o : leader index for each 8-dim subvector */ - int16_t *idx_scale, /* o : scale index for each subvector */ - const float *w, /* i : weights for LSF quantization */ - const int16_t mode, /* i : number indicating the coding mode */ - const int16_t mode_glb, /* i : LVQ coding mode */ - const int16_t pred_flag /* i : prediction flag (0: safety net, 1 - predictive )*/ -); - -void permute( - float *pTmp1, /* i/o: vector whose components are to be permuted */ - const int16_t *perm /* i : permutation info (indexes that should be interchanged), max two perms */ -); - -void sort_desc_ind( - float *s, - const int16_t len, - int16_t *ind ); - -float mslvq_cng( - int16_t idx_cv, /* i : index of cv from previous stage */ - float *pTmp, /* i : 16 dimensional input vector */ - float *quant, /* o : quantized vector */ - float *cv_out, /* o : corresponding 8-dim lattice codevectors (without the scaling) */ - int16_t *idx_lead, /* o : leader index for each 8-dim subvector */ - int16_t *idx_scale, /* o : scale index for each subvector */ - const float *w /* i : weights for LSF quantization */ -); - -int16_t deindex_lvq_cng( - int16_t *index, /* i : index to be decoded, as an array of 3 short */ - float *x_lvq, /* o : decoded codevector */ - const int16_t idx_cv, /* i : relative mode_lvq, wrt START_CNG */ - const int16_t no_bits /* i : number of bits for lattice */ -); - -void multiply32_32_64( - UWord32 x, /* i : operand 1 */ - UWord32 y, /* i : operand 2 */ - UWord32 *res /* o : result as array of two uint32 */ -); - -int16_t deindex_lvq( - int16_t *index, /* i : index to be decoded, as an array of 3 short */ - float *x_lvq, /* o : decoded codevector */ - const int16_t mode, /* i : LVQ coding mode (select scales & no_lead ), or idx_cv */ - const int16_t sf_flag, /* i : safety net flag */ - const int16_t no_bits /* i : number of bits for lattice */ -); - -void index_lvq( - float *quant, /* i : codevector to be indexed (2 8-dim subvectors) */ - int16_t *idx_lead, /* i : leader class index for each subvector */ - int16_t *idx_scale, /* i : scale index for each subvector */ - const int16_t mode, /* i : integer signaling the quantizer structure for the current bitrate */ - int16_t *index, /* o : encoded index (represented on 3 short each with 15 bits ) */ - const int16_t prediction_flag /* i : predictive mode or not */ -); - -int16_t qlsf_ARSN_tcvq_Dec_16k( - float *y, /* o : Quantized LSF vector */ - int16_t *indice, /* i : Indices */ - const int16_t nBits /* i : number of bits */ -); - - -int16_t lsf_bctcvq_decprm_ivas( - Decoder_State *st, - int16_t *param_lpc ); - - -void disf_2s_36b( - int16_t *indice, /* i : quantized indices (use indice[0] = -1 in the decoder) */ - float *isf_q, /* o : quantized ISFs in the cosine domain */ - float *mem_AR, /* i/o: quantizer memory for AR model */ - float *mem_MA /* i/o: quantizer memory for MA model */ -); - -void disf_2s_46b( - int16_t *indice, /* i : quantized indices (use indice[0] = -1 in the decoder) */ - float *isf_q, /* o : quantized ISFs in the cosine domain */ - float *mem_AR, /* o : quantizer memory for AR model */ - float *mem_MA /* i/o: quantizer memory for MA model */ -); - -void re8_k2y( - const int16_t *k, /* i : Voronoi index k[0..7] */ - const int16_t m, /* i : Voronoi modulo (m = 2^r = 1<=2) */ - int16_t *y /* o : 8-dimensional point y[0..7] in RE8 */ -); - -void re8_PPV( - const float x[], /* i : point in R^8 */ - int16_t y[] /* o : point in RE8 (8-dimensional integer vector) */ -); - -void enhancer( - const int16_t codec_mode, /* i : flag indicating Codec Mode */ - const int32_t core_brate, /* i : core bitrate */ - const int16_t cbk_index, /* i : */ - const int16_t Opt_AMR_WB, /* i : flag indicating AMR-WB IO mode */ - const int16_t coder_type, /* i : coding type */ - const int16_t L_frame, /* i : frame size */ - const float voice_fac, /* i : subframe voicing estimation */ - const float stab_fac, /* i : LP filter stablility measure */ - const float norm_gain_code, /* i : normalized innovative cb. gain */ - const float gain_inov, /* i : gain of the unscaled innovation */ - float *gc_threshold, /* i/o: code threshold */ - float *code, /* i/o: innovation */ - float *exc2, /* i/o: adapt. excitation/total exc. */ - const float gain_pit, /* i : Quantized pitch gain */ - float *dispMem /* i/o: Phase dispersion algorithm memory */ -); - -void phase_dispersion_flt( - const float gain_code, /* i : gain of code */ - const float gain_pit, /* i : gain of pitch */ - float code[], /* i/o: code vector */ - const int16_t mode, /* i : level, 0=hi, 1=lo, 2=off */ - float disp_mem[] /* i/o: static memory (size = 8) */ -); - -void re8_vor( - int16_t y[], /* i : point in RE8 (8-dimensional integer vector) */ - int16_t *n, /* o : codebook number n=0,2,3,4,... (scalar integer) */ - int16_t k[], /* o : Voronoi index (integer vector of dimension 8) used only if n>4 */ - int16_t c[], /* o : codevector in Q0, Q2, Q3, or Q4 if n<=4, y=c */ - int16_t *ka /* o : identifier of absolute leader (needed to index c)*/ -); - -void DoRTFT480( - float *x, /* i/o: real part of input and output data */ - float *y /* i/o: imaginary part of input and output data */ -); - -void DoRTFT320( - float *x, /* i/o: real part of input and output data */ - float *y /* i/o: imaginary part of input and output data */ -); - -void DoRTFT160( - float *x, /* i/o: real part of input and output data */ - float *y /* i/o: imaginary part of input and output data */ -); - -void DoRTFT128( - float *x, /* i/o: real part of input and output data */ - float *y /* i/o: imaginary part of input and output data */ -); - -void DoRTFT120( - float *x, /* i/o: real part of input and output data */ - float *y /* i/o: imaginary part of input and output data */ -); - -void DoRTFT80( - float *x, /* i/o: real part of input and output data */ - float *y /* i/o: imaginary part of input and output data */ -); - -void DoRTFT20( - float *x, /* i/o: real part of input and output data */ - float *y /* i/o: imaginary part of input and output data */ -); - -void DoRTFT40( - float *x, /* i/o: real part of input and output data */ - float *y /* i/o: imaginary part of input and output data */ -); - -void DoRTFTn( - float *x, /* i/o: real part of input and output data */ - float *y, /* i/o: imaginary part of input and output data */ - const int16_t n /* i : size of the FFT n=(2^k) up to 1024 */ -); - -void BASOP_cfft_ivas( - Word32 *re, /* i/o: real part */ - Word32 *im, /* i/o: imag part */ - Word16 s, /* i : stride real and imag part */ - Word16 *scale /* i : scalefactor */ -); - -void fft( - float *re, /* i/o: real part */ - float *im, /* i/o: imag part */ - const int16_t length, /* i : length of fft */ - const int16_t s /* i : sign */ -); - -void rfft( - float *x, /* i/o: values */ - const float *w, /* i : window */ - const int16_t length, /* i : length of fft */ - const int16_t isign /* i : sign */ -); - -void sinq( - const float tmp, /* i : sinus factor cos(tmp*i+phi) */ - const float phi, /* i : sinus phase cos(tmp*i+phi) */ - const int16_t N, /* i : size of output */ - float x[] /* o : output vector */ -); - -void edct2( - const int16_t n, - const int16_t isgn, - float *in, - float *a, - const int16_t *ip, - const float *w ); - -void stat_noise_uv_mod( - const int16_t coder_type, /* i : coder type */ - float noisiness, /* i : noisiness parameter */ - const float *const lsp_old, /* i : old LSP vector at 4th sfr */ - const float *const lsp_new, /* i : LSP vector at 4th sfr */ - const float *const lsp_mid, /* i : LSP vector at 2nd sfr */ - float *Aq, /* o : A(z) quantized for the 4 subframes */ - float *exc2, /* o : excitation buffer */ - const int16_t bfi, /* i : bad frame indicator */ - float *ge_sm, /* i/o: smoothed excitation gain */ - int16_t *uv_count, /* i/o: unvoiced counter */ - int16_t *act_count, /* i/o: activation counter */ - float lspold_s[], /* i/o: old LSP */ - int16_t *noimix_seed, /* i/o: mixture seed */ - float *st_min_alpha, /* i/o: minimum alpha */ - float *exc_pe, /* i/o: memory of the preemphasis filter */ - const int32_t bitrate, /* i : core bitrate */ - const int16_t bwidth /* i : audio bandwidth */ -); - -void limit_band_noise_level_calc( - const int16_t *wnorm, /* i : reordered norm of sub-vectors */ - int16_t *limit, /* o : highest band of bit allocation */ - const int32_t core_brate, /* i : core bitrate */ - float *noise_level /* o : noise level */ -); - -/*! r: hqswb_clas */ -int16_t peak_avrg_ratio( - const int32_t total_brate, /* i : total bitrate */ - const float *input_hi, /* i : input signal */ - const int16_t N, /* i : number of coefficients */ - int16_t *mode_count, /* i/o: HQ_HARMONIC mode count */ - int16_t *mode_count1 /* i/o: HQ_NORMAL mode count */ -); - -/*! r: Number of coefficients in nf codebook */ -int16_t build_nf_codebook( - const int16_t flag_32K_env_ho, /* i : Envelope attenuation hangover flag */ - const float *coeff, /* i : Coded spectral coefficients */ - const int16_t *sfm_start, /* i : Subband start indices */ - const int16_t *sfmsize, /* i : Subband widths */ - const int16_t *sfm_end, /* i : Subband end indices */ - const int16_t nb_sfm, /* i : Last coded band */ - const int16_t *R, /* i : Per-band bit allocation */ - float *CodeBook, /* o : Noise-fill codebook */ - float *CodeBook_mod /* o : Densified noise-fill codebook */ -); - -void apply_noisefill_HQ( - const int16_t *R, /* i : bit allocation */ - const int16_t length, /* i : input frame length */ - const int16_t flag_32K_env_ho, /* i : envelope stability hangover flag */ - const int32_t core_brate, /* i : core bitrate */ - const int16_t last_sfm, /* i : last coded subband */ - const float *CodeBook, /* i : Noise-fill codebook */ - const float *CodeBook_mod, /* i : Densified noise-fill codebook */ - const int16_t cb_size, /* i : Codebook length */ - const int16_t *sfm_start, /* i : Subband start coefficient */ - const int16_t *sfm_end, /* i : Subband end coefficient */ - const int16_t *sfmsize, /* i : Subband band width */ - float *coeff /* i/o: coded/noisefilled spectrum */ -); - -void harm_bwe_fine( - const int16_t *R, /* i : bit allocation */ - const int16_t last_sfm, /* i : last coded subband */ - const int16_t high_sfm, /* i : higher transition band to BWE */ - const int16_t num_sfm, /* i : total number of bands */ - const int16_t *norm, /* i : quantization indices for norms */ - const int16_t *sfm_start, /* i : Subband start coefficient */ - const int16_t *sfm_end, /* i : Subband end coefficient */ - int16_t *prev_L_swb_norm, /* i/o: last normalize length */ - float *coeff, /* i/o: coded/noisefilled normalized spectrum */ - float *coeff_out, /* o : coded/noisefilled spectrum */ - float *coeff_fine /* o : BWE fine structure */ -); - -void hvq_bwe_fine( - const int16_t last_sfm, /* i : last coded subband */ - const int16_t num_sfm, /* i : total number of bands */ - const int16_t *sfm_end, /* i : Subband end coefficient */ - const int16_t *peak_idx, /* i : Peak index */ - const int16_t Npeaks, /* i : Number of peaks */ - int16_t *peak_pos, /* i/o: Peak positions */ - int16_t *prev_L_swb_norm, /* i/o: last normalize length */ - float *coeff, /* i/o: coded/noisefilled normalized spectrum */ - int16_t *bwe_peaks, /* o : Positions of peaks in BWE */ - float *coeff_fine /* o : HVQ BWE fine structure */ -); - -void hq_fold_bwe( - const int16_t last_sfm, /* i : last coded subband */ - const int16_t *sfm_end, /* i : Subband end coefficient */ - const int16_t num_sfm, /* i : Number of subbands */ - float *coeff /* i/o: coded/noisefilled normalized spectrum */ -); - -void apply_nf_gain( - const int16_t nf_idx, /* i : noise fill gain index */ - const int16_t last_sfm, /* i : last coded subband */ - const int16_t *R, /* i : bit allocation */ - const int16_t *sfm_start, /* i : Subband start coefficient */ - const int16_t *sfm_end, /* i : Subband end coefficient */ - float *coeff /* i/o: coded/noisefilled normalized spectrum */ - -); - -void hq_generic_fine( - float *coeff, /* i : coded/noisefilled normalized spectrum */ - const int16_t last_sfm, /* i : Last coded band */ - const int16_t *sfm_start, /* i : Subband start coefficient */ - const int16_t *sfm_end, /* i : Subband end coefficient */ - int16_t *bwe_seed, /* i/o: random seed for generating BWE input */ - float *coeff_out1 /* o : HQ GENERIC input */ -); - -void harm_bwe( - const float *coeff_fine, /* i : fine structure for BWE */ - const float *coeff, /* i : coded/noisefilled normalized spectrum */ - const int16_t num_sfm, /* i : Number of subbands */ - const int16_t *sfm_start, /* i : Subband start coefficient */ - const int16_t *sfm_end, /* i : Subband end coefficient */ - const int16_t last_sfm, /* i : last coded subband */ - const int16_t high_sfm, /* i : higher transition band to BWE */ - const int16_t *R, /* i : bit allocation */ - const int16_t prev_hq_mode, /* i : previous hq mode */ - int16_t *norm, /* i/o: quantization indices for norms */ - float *noise_level, /* i/o: noise levels for harmonic modes */ - float *prev_noise_level, /* i/o: noise factor in previous frame */ - int16_t *bwe_seed, /* i/o: random seed for generating BWE input */ - float *coeff_out, /* o : coded/noisefilled spectrum */ - const int16_t element_mode /* i : element mode */ -); - -void hvq_bwe( - const float *coeff, /* i : coded/noisefilled spectrum */ - const float *coeff_fine, /* i : BWE fine structure */ - const int16_t *sfm_start, /* i : Subband start coefficient */ - const int16_t *sfm_end, /* i : Subband end coefficient */ - const int16_t *sfm_len, /* i : Subband length */ - const int16_t last_sfm, /* i : last coded subband */ - const int16_t prev_hq_mode, /* i : previous hq mode */ - const int16_t *bwe_peaks, /* i : HVQ bwe peaks */ - const int16_t bin_th, /* i : HVQ transition bin */ - const int16_t num_sfm, /* i : Number of bands */ - const int32_t core_brate, /* i : Core bitrate */ - const int16_t *R, /* i : Bit allocation */ - int16_t *norm, /* i/o: quantization indices for norms */ - float *noise_level, /* i/o: noise levels for harmonic modes */ - float *prev_noise_level, /* i/o: noise factor in previous frame */ - int16_t *bwe_seed, /* i/o: random seed for generating BWE input */ - float *coeff_out /* o : coded/noisefilled spectrum */ -); - -void hvq_concat_bands( - const int16_t pvq_bands, /* i : Number of bands in concatenated PVQ target */ - const int16_t *sel_bnds, /* i : Array of selected high bands */ - const int16_t n_sel_bnds, /* i : Number of selected high bands */ - int16_t *hvq_band_start, /* o : Band start indices */ - int16_t *hvq_band_width, /* o : Band widths */ - int16_t *hvq_band_end /* o : Band end indices */ -); - -void hq_generic_bwe( - const int16_t HQ_mode, /* i : HQ mode */ - float *coeff_out1, /* i/o: BWE input & temporary buffer */ - const float *hq_generic_fenv, /* i : SWB frequency envelopes */ - float *coeff_out, /* o : SWB signal in MDCT domain */ - const int16_t hq_generic_offset, /* i : frequency offset for representing hq generic*/ - int16_t *prev_L_swb_norm, /* i/o: last normalize length */ - const int16_t hq_generic_exc_clas, /* i : hq generic hf excitation class */ - const int16_t *sfm_end, /* i : End of bands */ - const int16_t num_sfm, /* i : Number of bands */ - const int16_t num_env_bands, /* i : Number of coded envelope bands */ - const int16_t *R /* i : Bit allocation */ -); - -void map_hq_generic_fenv_norm( - const int16_t hqswb_clas, /* i : signal classification flag */ - const float *hq_generic_fenv, /* i : HQ GENERIC envelope */ - int16_t *ynrm, /* o : high band norm indices */ - int16_t *normqlg2, /* o : high band norm values */ - const int16_t num_env_bands, /* i : Number coded envelope bands */ - const int16_t nb_sfm, /* i : Number of envelope bands */ - const int16_t hq_generic_offset /* i : Freq offset for HQ GENERIC */ -); - -/*! r: Number of bits consumed for the delta coding */ -int16_t calc_nor_delta_hf( - BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ - const float *t_audio, /* i : transform-domain coefficients */ - int16_t *ynrm, /* i/o: norm indices */ - int16_t *Rsubband, /* i/o: sub-band bit allocation */ - const int16_t num_env_bands, /* i : Number coded envelope bands */ - const int16_t nb_sfm, /* i : Number of envelope bands */ - const int16_t *sfmsize, /* i : band length */ - const int16_t *sfm_start, /* i : Start index of bands */ - const int16_t core_sfm /* i : index of the end band for core */ -); - -/*! r: Number of bits consumed for the delta coding */ -int16_t get_nor_delta_hf( - Decoder_State *st, /* i/o: Decoder state */ - int16_t *ynrm, /* i/o: norm indices */ - int16_t *Rsubband, /* i/o: sub-band bit allocation */ - const int16_t num_env_bands, /* i : Number coded envelope bands */ - const int16_t nb_sfm, /* i : Number of envelope bands */ - const int16_t core_sfm ); /* i : index of the end band for core */ - -void hq_wb_nf_bwe( - const float *coeff, /* i : coded/noisefilled normal. spectrum */ - const int16_t is_transient, /* i : is transient flag */ - const int16_t prev_bfi, /* i : previous bad frame indicator */ - const float *normq_v, /* i : norms */ - const int16_t num_sfm, /* i : Number of subbands */ - const int16_t *sfm_start, /* i : Subband start coefficient */ - const int16_t *sfm_end, /* i : Subband end coefficient */ - const int16_t *sfmsize, /* i : Subband band width */ - const int16_t last_sfm, /* i : last coded subband */ - const int16_t *R, /* i : bit allocation */ - const int16_t prev_is_transient, /* i : previous transient flag */ - float *prev_normq, /* i/o: previous norms */ - float *prev_env, /* i/o: previous noise envelopes */ - int16_t *bwe_seed, /* i/o: random seed for generating BWE input */ - float *prev_coeff_out, /* i/o: decoded spectrum in previous frame */ - int16_t *prev_R, /* i/o: previous frame bit allocation info. */ - float *coeff_out /* o : coded/noisefilled spectrum */ -); - -/*! r: Number of bits */ -int16_t encode_envelope_indices( - BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ - const int16_t num_sfm, /* i : Number of subbands */ - const int16_t numnrmibits, /* i : Bitrate of fall-back coding mode */ - int16_t *difidx, /* i/o: Diff indices/encoded diff indices */ - int16_t *LCmode, /* o : Coding mode */ - const int16_t flag_pack, /* i : indicator of packing or estimating bits */ - const int16_t flag_HQ2, /* i : indicator of HQ2 core */ - const int16_t is_transient /* i : transient flag */ -); - -void diff_envelope_coding( - const int16_t is_transient, /* i : transient indicator */ - const int16_t num_env_bands, /* i : number of envelope bands to code */ - const int16_t start_norm, /* i : start of envelope coding */ - int16_t *ynrm, /* i/o: quantization indices for norms */ - int16_t *normqlg2, /* i/o: quantized norms */ - int16_t *difidx /* o : differential code */ -); - -/*! r: Number of bits */ -int16_t decode_envelope_indices( - Decoder_State *st, /* i/o: decoder state structure */ - const int16_t start_norm, /* i : First SDE encoded norm */ - const int16_t num_sfm, /* i : Number of norms */ - const int16_t numnrmibits, /* i : Bitrate of fall-back coding mode */ - int16_t *ynrm, /* o : Decoded norm indices */ - const int16_t flag_HQ2, /* i : indicator of HQ2 core */ - const int16_t is_transient /* i : transient flag */ -); - -/*! r: Number of bits */ -void dequantize_norms( - Decoder_State *st, /* i/o: decoder state structure */ - const int16_t start_norm, /* i : First SDE encoded norm */ - const int16_t num_sfm, /* i : Number of norms */ - const int16_t is_transient, /* i : Transient flag */ - int16_t *ynrm, /* o : Decoded norm indices */ - int16_t *normqlg2 /* o : Log2 of decoded norms */ -); - -void hq_configure( - const int16_t length, /* i : Frame length */ - const int16_t hqswb_clas, /* i : HQ SWB class */ - const int32_t core_brate, /* i : core bitrate */ - int16_t *num_sfm, /* o : Total number of subbands */ - int16_t *nb_sfm, /* o : Total number of coded bands */ - int16_t *start_norm, /* o : First norm to be SDE encoded */ - int16_t *num_sde_norm, /* o : Number of norms for SDE encoding */ - int16_t *numnrmibits, /* o : Number of bits in fall-back norm encoding */ - int16_t *hq_generic_offset, /* o : Freq offset for HQ GENERIC */ - int16_t *sfmsize, /* o : Subband bandwidths */ - int16_t *sfm_start, /* o : Subband start coefficients */ - int16_t *sfm_end /* o : Subband end coefficients */ -); - -/*! r: Consumed bits */ -int16_t hvq_enc( - BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ - const int16_t bwidth, /* i : audio bandwidth */ - const int32_t core_brate, /* i : core bitrate */ - const int16_t hvq_bits, /* i : HVQ bit budget */ - const int16_t Npeaks, /* i : Number of peaks */ - const int16_t *ynrm, /* i : Envelope coefficients */ - int16_t *R, /* i/o: Bit allocation/updated bit allocation */ - int16_t *peaks, /* i/o: Peak pos. / Encoded peak pos. */ - float *nf_gains, /* i/o: Noise fill gains / Quant. nf gains */ - float *noise_level, /* o : Quantized noise level */ - const float *pe_gains, /* i : Peak gains */ - const float *coefs, /* i : spectrum coefficients */ - float *coefs_out /* o : encoded spectrum coefficients */ -); -/*! r: Consumed bits */ -int16_t hq_classifier_dec( - Decoder_State *st, /* i/o: decoder state structure */ - const int32_t core_brate, /* i : Core bitrate */ - const int16_t length, /* i : Frame length */ - int16_t *is_transient, /* o : Transient flag */ - int16_t *hqswb_clas /* o : HQ class */ -); - -void hq_bit_allocation( - const int32_t core_brate, /* i : Core bitrate */ - const int16_t length, /* i : Frame length */ - const int16_t hqswb_clas, /* i : HQ class */ - int16_t *num_bits, /* i/o: Remaining bit budget */ - const int16_t *normqlg2, /* i : Quantized norms */ - const int16_t nb_sfm, /* i : Number sub bands to be encoded */ - const int16_t *sfmsize, /* i : Sub band bandwidths */ - float *noise_level, /* o : HVQ noise level */ - int16_t *R, /* o : Bit allocation per sub band */ - int16_t *Rsubband, /* o : Fractional bit allocation (Q3) */ - int16_t *sum, /* o : Sum of allocated shape bits */ - int16_t *core_sfm, /* o : Last coded band in core */ - const int16_t num_env_bands /* i : Number sub bands to be encoded for HQ_SWB_BWE */ -); - -void enforce_zero_for_min_envelope( - const int16_t hqswb_clas, /* i : HQ coding class */ - const int16_t *ynrm, /* i : Envelope indices */ - float *coefsq, /* i/o: Quantized spectrum/zeroed spectrum */ - int16_t nb_sfm, /* i : Number of coded sub bands */ - const int16_t *sfm_start, /* i : Sub band start indices */ - const int16_t *sfm_end /* i : Sub band end indices */ -); - -void apply_envelope( - const float *coeff, /* i/o: Coded/noisefilled normalized spectrum */ - const int16_t *norm, /* i : Envelope */ - const float *norm_adj, /* i : Envelope adjustment */ - const int16_t num_sfm, /* i : Total number of bands */ - const int16_t last_sfm, /* i : Last coded band */ - const int16_t HQ_mode, /* i : HQ mode */ - const int16_t length, /* i : Frame length */ - const int16_t *sfm_start, /* i : Sub band start indices */ - const int16_t *sfm_end, /* i : Sub band end indices */ - float *normq_v, /* o : Envelope with adjustment */ - float *coeff_out, /* o : coded/noisefilled spectrum */ - float *coeff_out1 /* o : noisefilled spectrum for HQ SWB BWE */ -); - -void apply_envelope_enc( - float *coeff, /* i/o: Normalized/scaled normalized spectrum */ - const int16_t *norm, /* i : Envelope */ - const int16_t num_sfm, /* i : Total number of bands */ - const int16_t *sfm_start, /* i : Sub band start indices */ - const int16_t *sfm_end /* i : Sub band end indices */ -); - -/*! r: Leading_sign_index, index, size, k_val */ -PvqEntry mpvq_encode_vec( - const int16_t *vec_in, /* i : Signed pulse train */ - const int16_t dim_in, /* i : Dimension */ - int16_t k_val_local /* i/o: Num unit pulses */ -); - -/*! r: Size, dim, k_val */ -PvqEntry get_size_mpvq_calc_offset( - const int16_t dim_in, /* i : Dimension */ - const int16_t k_val_in, /* i : Num unit pulses */ - uint32_t *h_mem /* o : Offsets */ -); - -void mpvq_decode_vec( - const PvqEntry *entry, /* i : Sign_ind, index, dim, k_val */ - uint32_t *h_mem, /* i : A/U offsets */ - int16_t *vec_out /* o : Pulse train */ -); - -/*! r: Multiplication result */ -uint32_t UMult_32_32( - const uint32_t UL_var1, /* i : factor 1 */ - const uint32_t UL_var2 /* i : factor 2 */ -); - -/*! r: inverse */ -uint32_t UL_inverse_float( - const uint32_t UL_val, /* i : input value Q_exp */ - int16_t *exp /* i/o: input exp / result exp */ -); - -/*! r: ratio */ -Word16 ratio_float( - const Word32 numer, /* i : numerator */ - const Word32 denom, /* i : denominator */ - Word16 *expo /* i/o: input exp / result exp */ -); - -/*! r: Angle between 0 and EVS_PI/2 radian (Q14) */ -Word16 atan2_fx_flt( - const Word32 y, /* i : near side (Argument must be positive) (Q15) */ - const Word32 x /* i : opposite side (Q15) */ -); - -void pvq_encode_frame( - BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ - const float *coefs_norm, /* i : normalized coefficients to encode */ - float *coefs_quant, /* o : quantized coefficients */ - float *gopt, /* o : optimal shape gains */ - int16_t *npulses, /* o : number of pulses per band */ - int16_t *pulse_vector, /* o : non-normalized pulse shapes */ - const int16_t *sfm_start, /* i : indices of first coefficients in the bands */ - const int16_t *sfm_end, /* i : indices of last coefficients in the bands */ - const int16_t *sfmsize, /* i : band sizes */ - const int16_t nb_sfm, /* i : total number of bands */ - const int16_t *R, /* i : bitallocation per band (Q3) */ - const int16_t pvq_bits, /* i : number of bits avaiable */ - const int16_t core /* i : core */ -); - -void pvq_decode_frame( - Decoder_State *st, /* i/o: Decoder state */ - float *coefs_quant, /* o : quantized coefficients */ - int16_t *npulses, /* o : number of pulses per band */ - int16_t *pulse_vector, /* o : non-normalized pulse shapes */ - const int16_t *sfm_start, /* i : indices of first coeffs in the bands */ - const int16_t *sfm_end, /* i : indices of last coeffs in the bands */ - const int16_t *sfmsize, /* i : band sizes */ - const int16_t nb_sfm, /* i : total number of bands */ - const int16_t *R, /* i : bitallocation per band (Q3) */ - const int16_t pvq_bits, /* i : number of bits avaiable */ - const int16_t core /* i : core */ -); - -void srt_vec_ind( - const int16_t *linear, /* linear input */ - int16_t *srt, /* sorted output */ - int16_t *I, /* index for sorted output */ - const int16_t length ); - -void srt_vec_ind_f( - const float *linear, /* linear input */ - float *srt, /* sorted output */ - int16_t *I, /* index for sorted output */ - const int16_t length /* length of vector */ -); - -/*! r: floor(sqrt(input)) */ -uint32_t floor_sqrt_exact( - const uint32_t input /* i : unsigned input [0.. UINT_MAX/4] */ -); - -void fine_gain_quant( - BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ - const int16_t *ord, /* i : Indices for energy order */ - const int16_t num_sfm, /* i : Number of bands */ - const int16_t *gain_bits, /* i : Gain adjustment bits per sub band */ - float *fg_pred, /* i/o: Predicted gains / Corrected gains */ - const float *gopt /* i : Optimal gains */ -); - -void apply_gain( - const int16_t *ord, /* i : Indices for energy order */ - const int16_t *band_start, /* i : Sub band start indices */ - const int16_t *band_end, /* i : Sub band end indices */ - const int16_t num_sfm, /* i : Number of bands */ - const float *gains, /* i : Band gain vector */ - float *xq /* i/o: float synthesis / gain adjusted synth */ -); - -void fine_gain_pred( - const int16_t *sfm_start, /* i : Sub band start indices */ - const int16_t *sfm_end, /* i : Sub band end indices */ - const int16_t *sfm_size, /* i : Sub band bandwidths */ - const int16_t *i_sort, /* i : Energy sorting indices */ - const int16_t *K, /* i : Number of pulses per band */ - const int16_t *maxpulse, /* i : Maximum pulse per band */ - const int16_t *R, /* i : Bits per sub band (Q3) */ - const int16_t num_sfm, /* i : Number of sub bands */ - float *xq, /* i/o: Quantized vector /quantized vector with finegain adj */ - int16_t *y, /* i/o: Quantized vector */ - float *fg_pred, /* o : Predicted fine gains */ - const int16_t core /* i : Core */ -); - -void fine_gain_dec( - Decoder_State *st, /* i/o: Decoder state struct */ - const int16_t *ord, /* i : Indices for energy order */ - const int16_t num_sfm, /* i : Number of bands */ - const int16_t *gain_bits, /* i : Gain adjustment bits per sub band */ - float *fg_pred /* i/o: Predicted gains / Corrected gains */ -); - -void get_max_pulses( - const int16_t *band_start, /* i : Sub band start indices */ - const int16_t *band_end, /* i : Sub band end indices */ - const int16_t *k_sort, /* i : Indices for sorting by energy */ - const int16_t *npulses, /* i : Pulses per sub band */ - const int16_t BANDS, /* i : Number of bands */ - int16_t *inp_vector, /* i/o: Encoded shape vectors */ - int16_t *maxpulse /* o : Maximum pulse height per band */ -); - -Word32 ar_div_ivas( - Word32 num, - Word32 denum ); - -void ar_encoder_start( - PARCODEC arInst, - TCQ_PBITSTREAM bsInst, - int16_t max_bits ); - -void ar_decoder_start( - PARCODEC arInst, - TCQ_PBITSTREAM bsInst ); - -void ar_encoder_done( - PARCODEC arInst ); - -void ar_decoder_done( - PARCODEC arInst ); - - -Word32 Mult_32_16( - Word32 a, - Word16 b ); - -Word32 Mult_32_32( - Word32 a, - Word32 b ); - - -void decode_mangitude_tcq_fx_ivas( - ARCODEC *pardec, - Word16 size, - Word16 npulses, - Word16 nzpos, - Word32 *positions, - Word32 *out, - Word32 *surplus_fx ); - -void decode_signs_fx_ivas( - ARCODEC *pardec, - Word16 size, - Word32 *out ); - -void srt_vec_ind_fx_ivas( - const Word32 *linear, - Word32 *srt, - Word16 *I, - Word16 length ); - - -void bit_allocation_second_fx2( - Word32 *Rk, - Word32 *Rk_sort, - Word16 BANDS, - const Word16 *band_width, - Word16 *k_sort, - Word16 *k_num, - const Word16 *p2a_flags, - const Word16 p2a_bands, - const Word16 *last_bitalloc, - const Word16 input_frame ); - - -Word32 encode_magnitude_tcq_fx_ivas( - ARCODEC *parenc, - float *magn_fx, - Word16 size, - Word16 npulses, - Word16 nzpos, - Word32 *savedstates, - Word32 *est_frame_bits_fx ); - -Word32 encode_signs_fx_ivas( - ARCODEC *parenc, - float *magn, - Word16 size, - Word16 npos, - Word32 *est_frame_bits_fx ); - -Word32 encode_magnitude_usq_fx_ivas( - ARCODEC *parenc, - float *magn_fx, - Word16 size, - Word16 npulses, - Word16 nzpos, - Word32 *est_frame_bits_fx ); - -ivas_error tcq_core_LR_enc( - BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ - int32_t inp_vector[], - const float coefs_norm[], - float coefs_quant[], - const int16_t bit_budget, /* number of bits */ - const int16_t nb_sfm, - const int16_t *sfm_start, - const int16_t *sfm_end, - const int16_t *sfmsize, - Word32 *Rk_fx, - int16_t *npulses, - int16_t *k_sort, - const int16_t *p2a_flags, - const int16_t p2a_bands, - const int16_t *last_bitalloc, - const int16_t input_frame, - const int16_t adjustFlag, - const int16_t is_transient ); - -void tcq_core_LR_dec( - Decoder_State *st, - int32_t *inp_vector, - const int16_t bit_budget, - const int16_t bands, - const int16_t *band_start, - const int16_t *band_width, - Word32 *Rk_fx, - int16_t npulses[], - int16_t *k_sort, - const int16_t *p2a_flags, - const int16_t p2a_bands, - const int16_t *last_bitalloc, - const int16_t input_frame, - const int16_t adjustFlag, - const int16_t *is_transient ); - - -void TCQLSB( - int16_t bcount, - float *abuffer, - float *mbuffer, - float *sbuffer, - int16_t *dpath ); - -void RestoreTCQ( - float *magn, - int16_t size, - int16_t *bcount, - float *mbuffer ); - -void SaveTCQdata( - PARCODEC arInst, - int16_t *dpath, - int16_t bcount ); - -void LoadTCQdata( - PARCODEC arInst, - int16_t *dpath, - int16_t bcount ); - -void RestoreTCQdec( - int32_t *magn, - int16_t size, - int16_t *bcount, - float *mbuffer ); - -void TCQLSBdec( - int16_t *dpath, - float *mbuffer, - int16_t bcount ); - -void bit_allocation_second_fx2( - Word32 *Rk, - Word32 *Rk_sort, - Word16 BANDS, - const Word16 *band_width, - Word16 *k_sort, - Word16 *k_num, - const Word16 *p2a_flags, - const Word16 p2a_bands, - const Word16 *last_bitalloc, - const Word16 input_frame ); - -void io_ini_enc( - const int32_t argc, /* i : command line arguments number */ - char *argv[], /* i : command line arguments */ - FILE **f_input, /* o : input signal file */ - FILE **f_stream, /* o : output bitstream file */ - FILE **f_rate, /* o : bitrate switching profile (0 if N/A) */ - FILE **f_bwidth, /* o : bandwidth switching profile (0 if N/A) */ - FILE **f_metadata, /* o : metadata files (NULL if N/A) */ -#ifdef DEBUGGING - FILE **f_force, /* o : force switching profile (0 if N/A) */ -#endif - FILE **f_rf, /* o : channel aware configuration file */ - int16_t *quietMode, /* o : limit printouts */ - int16_t *noDelayCmp, /* o : turn off delay compensation */ - Encoder_Struct *st /* o : IVAS encoder structure */ -); - -void read_next_rfparam( - int16_t *rf_fec_offset, /* o : RF offset */ - int16_t *rf_fec_indicator, /* o : RF FEC indicator */ - FILE *f_rf /* i : file pointer to read parameters */ -); - -void read_next_brate( - int32_t *total_brate, /* i/o: total bitrate */ - const int32_t last_total_brate, /* i : last total bitrate */ - FILE *f_rate, /* i : bitrate switching profile (0 if N/A) */ - const int16_t element_mode, /* i : IVAS element mode */ - int32_t input_Fs, /* i : input sampling frequency */ - int16_t *Opt_AMR_WB, /* i : flag indicating AMR-WB IO mode */ - int16_t *Opt_SC_VBR, /* i/o: SC-VBR flag */ - int16_t *codec_mode /* i/o: Mode 1 or 2 */ -); - -void read_next_bwidth( - int16_t *max_bwidth, /* i/o: maximum encoded bandwidth */ - FILE *f_bwidth, /* i : bandwidth switching profile (0 if N/A) */ - int32_t *bwidth_profile_cnt, /* i/o: counter of frames for bandwidth switching profile file */ - int32_t input_Fs /* i : input sampling rate */ -); - -#ifdef DEBUGGING -void read_next_force( - int16_t *force, /* i/o: force value (0/1, 0 = speech, 1 = music)*/ - FILE *f_force, /* i : force switching profile (0 if N/A) */ - int32_t *force_profile_cnt /* i/o: counter of frames for force switching profile file */ -); -#endif - -ivas_error init_encoder_ivas_fx( - Encoder_State *st, /* i/o: state structure */ - Encoder_Struct *st_ivas, /* i/o: encoder state structure */ - const Word16 idchan, /* i : channel ID */ - const Word16 var_SID_rate_flag, /* i : flag for variable SID update rate */ - const Word16 interval_SID, /* i : interval for SID update */ - const Word16 vad_only_flag, /* i : flag to indicate front-VAD structure */ - const ISM_MODE ism_mode, /* i : ISM mode */ - const Word32 element_brate /* i : element bitrate */ -); - -void LPDmem_enc_init( - LPD_state_HANDLE hLPDmem /* i/o: LP memories */ -); - -ivas_error evs_enc( - Encoder_State *st, /* i/o: state structure */ - const int16_t *data, /* i : input signal */ - float *mem_hp20_in, /* i/o: hp20 filter memory */ - const int16_t n_samples /* i : number of input samples */ -); -void amr_wb_enc( - Encoder_State *st, /* i/o: encoder state structure */ - const int16_t *data, /* i : input signal */ - float *mem_hp20_in, /* i/o: hp20 filter memory */ - const int16_t n_samples /* i : number of input samples */ -); - -void sc_vbr_enc_init( - SC_VBR_ENC_HANDLE hSC_VBR /* i/o: SC-VBR encoder handle */ -); - -void amr_wb_enc_init( - AMRWB_IO_ENC_HANDLE hAmrwb_IO /* i/o: AMR-WB IO encoder handle */ -); - -void pre_proc( - Encoder_State *st, /* i/o: encoder state structure */ - const int16_t input_frame, /* i : frame length */ - float old_inp_12k8[], /* i/o: buffer of old input signal */ - float old_inp_16k[], /* i/o: buffer of old input signal @ 16kHz */ - float **inp, /* o : ptr. to inp. signal in the current frame*/ - float fr_bands[2 * NB_BANDS], /* i : energy in frequency bands */ - float *ener, /* o : residual energy from Levinson-Durbin */ - int16_t pitch_orig[3], /* o : open-loop pitch values for quantization */ - float A[NB_SUBFR16k * ( M + 1 )], /* i/o: A(z) unquantized for the 4 subframes */ - float Aw[NB_SUBFR16k * ( M + 1 )], /* i/o: weighted A(z) unquantized for subframes */ - float epsP[M + 1], /* i/o: LP prediction errors */ - float lsp_new[M], /* i/o: LSPs at the end of the frame */ - float lsp_mid[M], /* i/o: LSPs in the middle of the frame */ - int16_t *vad_hover_flag, /* i : VAD hangover flag */ - int16_t *attack_flag, /* o : attack flag */ - float *new_inp_resamp16k, /* o : new input signal @16kHz, non pre-emphasised, used by the WB TBE/BWE */ - int16_t *Voicing_flag, /* o : voicing flag for HQ FEC */ - float realBuffer[CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], /* i/o: real buffer */ - float imagBuffer[CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], /* i/o: imag buffer */ - int16_t *hq_core_type /* o : HQ core type */ -); - - -/*! r: HQ_CORE/TCX_20_CORE decision */ -int16_t mdct_classifier( - Encoder_State *st, /* i/o: Encoder state variable */ - const float *fft_buff, /* i : FFT spectrum from fft_rel */ - const float enerBuffer[], /* i : energy buffer */ - const int32_t brate /* i : current brate, IVAS: nominal bitrate, EVS: st->total_brate */ -); - -void MDCT_selector( - Encoder_State *st, /* i/o: Encoder State */ - const float sp_floor, /* i : Noise floor estimate */ - const float Etot, /* i : Total energy */ - const float cor_map_sum, /* i : sum of correlation map */ - const float enerBuffer[] /* i : energy buffer */ -); - -ivas_error acelp_core_enc( - Encoder_State *st, /* i/o: encoder state structure */ - const Word16 inp[], /* i : input signal of the current frame */ - Word16 A[NB_SUBFR16k * ( M + 1 )], /* i : A(z) unquantized for the 4 subframes */ - Word16 Aw[NB_SUBFR16k * ( M + 1 )], /* i : weighted A(z) unquant. for subframes */ - const Word32 epsP[M + 1], /* i : LP prediction errors */ - Word16 lsp_new[M], /* i : LSPs at the end of the frame */ - Word16 lsp_mid[M], /* i : LSPs in the middle of the frame */ - const Word16 vad_hover_flag, /* i : VAD hangover flag */ - const Word16 attack_flag, /* i : attack flag (GSC or TC) */ - Word32 bwe_exc_extended_fx[], /* i/o: bandwidth extended excitation 2*Q_new */ - Word16 *voice_factors_fx, /* o : voicing factors Q15 */ - Word16 old_syn_12k8_16k[], /* o : ACELP core synthesis at 12.8kHz or 16kHz to be used by SWB BWE */ - Word16 *q_old_syn_12k8_16, - Word16 pitch_buf[NB_SUBFR16k], /* o : floating pitch for each subframe */ - Word16 *unbits, /* o : number of unused bits */ - STEREO_TD_ENC_DATA_HANDLE hStereoTD, /* i/o: TD stereo encoder handle */ - Word16 tdm_lsfQ_PCh[M], /* i : Q LSFs for primary channel */ - Word16 Q_new ); - -ivas_error acelp_core_switch_dec_bfi( - Decoder_State *st /* i/o: decoder state structure */ -); - -void acelp_core_switch_enc( - Encoder_State *st, /* i/o: encoder state structure */ - const float inp12k8[], /* i : input signal @12.8 kHz */ - const float inp16k[], /* i : input signal @16 kHz */ - const float A[NB_SUBFR16k * ( M + 1 )] /* i : A(z) unquantized for the 4 subframes */ -); - -/*! r: length of output */ -int16_t modify_Fs_intcub3m_sup( - const float sigIn[], /* i : signal to decimate with memory of 2 samples (indexes -2 & -1) */ - const int16_t lg, /* i : length of input */ - const int32_t fin, /* i : frequency of input */ - float sigOut[], /* o : decimated signal */ - const int32_t fout, /* i : frequency of output */ - int16_t *delayout /* o : delay of output */ -); - -void core_switching_OLA( - const float *mem_over_hp, /* i : upsampling filter memory */ - const int16_t last_L_frame, /* i : last L_frame lengthture */ - const int32_t output_Fs, /* i : output sampling rate */ - float *synth, /* i/o: synthesized signal from HQ core */ - const float *synth_subfr_out, /* i : synthesized signal from ACELP core */ - float *synth_subfr_bwe, /* i : synthesized BWE from ACELP core */ - const int16_t output_frame, /* i : output frame length */ - const int16_t bwidth /* i : output bandwidth */ -); - -void retro_interp4_5( - const float *syn, - float *pst_old_syn ); - -void retro_interp5_4( - float *pst_old_syn ); -void core_switching_hq_prepare_dec( - Decoder_State *st, /* i/o: decoder state structure */ - int16_t *num_bits, /* i/o: bit budget update */ - const int16_t input_frame /* i : input frame length */ -); - -ivas_error acelp_core_switch_dec( - Decoder_State *st, /* i/o: decoder structure */ - float *synth_subfr_out, /* o : synthesized ACELP subframe */ - float *tmp_synth_bwe, /* o : synthesized ACELP subframe BWE */ - const int16_t output_frame, /* i : input frame length */ - const int16_t core_switching_flag, /* i : core switching flag */ - float *mem_synth, /* o : synthesis to overlap */ - const int16_t nchan_out /* i : number of output channels */ -); - -void ResetSHBbuffer_Enc( - TD_BWE_ENC_HANDLE hBWE_TD /* i/o: TD BWE data handle */ -); - -void ResetSHBbuffer_Dec( - TD_BWE_DEC_HANDLE hBWE_TD, /* i/o: TD BWE data handle */ - const int16_t extl /* i : BWE extension layer */ -); - -void calc_st_filt( - const float *apond2, /* i : coefficients of numerator */ - const float *apond1, /* i : coefficients of denominator */ - float *parcor0, /* o : 1st parcor calcul. on composed filter */ - float *sig_ltp_ptr, /* i/o: input of 1/A(gamma1) : scaled by 1/g0 */ - float *mem_zero, /* i/o: All zero memory */ - const int16_t L_subfr, /* i : the length of subframe */ - const int16_t extl /* i : extension layer info */ -); - - -void scale_st_ivas( - const float *sig_in, /* i : postfilter input signal */ - float *sig_out, /* i/o: postfilter output signal */ - float *gain_prec, /* i/o: last value of gain for subframe */ - const int16_t L_subfr, /* i : the length of subframe */ - const int16_t extl /* i : extension layer info */ -); - -void filt_mu( - const float *sig_in, /* i : signal (beginning at sample -1) */ - float *sig_out, /* o : output signal */ - const float parcor0, /* i : parcor0 (mu = parcor0 * gamma3) */ - const int16_t L_subfr, /* i : the length of subframe */ - const int16_t extl /* i : extension layer info */ -); - -void PostShortTerm( - float *sig_in, /* i : input signal (ptr. to current subframe */ - float *lpccoeff, /* i : LPC coefficients for current subframe */ - float *sig_out, /* o : postfiltered output */ - float *mem_stp, /* i/o: postfilter memory */ - float *ptr_mem_stp, /* i/o: pointer to postfilter memory */ - float *ptr_gain_prec, /* i/o: for gain adjustment */ - float *mem_zero, /* i/o: null memory to compute h_st */ - const float formant_fac /* i : Strength of post-filter [0,1] */ -); - -/*! r: Formant filter strength [0,1] */ -float swb_formant_fac( - const float lpc_shb2, /* i : 2nd HB LPC coefficient */ - float *tilt_mem /* i/o: Tilt smoothing memory */ -); - -void GenShapedSHBExcitation( - float *excSHB, /* o : synthesized shaped shb exctiation */ - const float *lpc_shb, /* i : lpc coefficients */ - float *exc16kWhtnd, /* o : whitened synthesized shb excitation */ - float *mem_csfilt, /* i/o: memory */ - float *mem_genSHBexc_filt_down_shb, /* i/o: memory */ - float *state_lpc_syn, /* i/o: memory */ - const int16_t coder_type, /* i : coding type */ - const float *bwe_exc_extended, /* i : bandwidth extended excitation */ - int16_t bwe_seed[], /* i/o: random number generator seed */ - float voice_factors[], /* i : voicing factor */ - const int16_t extl, /* i : extension layer */ - float *tbe_demph, /* i/o: de-emphasis memory */ - float *tbe_premph, /* i/o: pre-emphasis memory */ - float *lpc_shb_sf, /* i : LP coefficients */ - float *shb_ener_sf, /* i : SHB subframe energies */ - float *shb_res_gshape, /* i : SHB LP residual gain shape */ - float *shb_res, /* i : SHB residual used in encoder only */ - int16_t *vf_ind, /* i/o: Mixing factor index */ - const float formant_fac, /* i : Formant sharpening factor [0..1] */ - float fb_state_lpc_syn[], /* i/o: memory */ - float *fb_tbe_demph, /* i/o: fb de-emphasis memory */ - const int32_t total_brate, /* i : overall bitrate */ - const int16_t prev_bfi, /* i : previous frame was lost flag */ - const int16_t element_mode, /* i : element mode */ - const int16_t flag_ACELP16k, /* i : ACELP@16kHz flag */ - float *nlExc16k, /* i/o: NL exc for IC-BWE */ - float *mixExc16k, /* i/o: exc spreading for IC-BWE */ - const int32_t extl_brate, /* i : TD BWE bitrate */ - const int16_t MSFlag, /* i : Multi-source flag */ - float EnvSHBres_4k[], /* i/o: TD envelope of the SHB residual signal */ - float *prev_pow_exc16kWhtnd, /* i/o: power of the LB excitation signal in the previous frame */ - float *prev_mix_factor, /* i/o: mixing factor in the previous frame */ - float *Env_error, /* o : error in SHB residual envelope modelling*/ - float Env_error_part[] /* o : per-segment error in SHB residual envelope modelling */ -); - -void GenSHBSynth( - const float *shb_target_speech, /* i : input synthesized speech */ - float *shb_syn_speech_32k, /* o : output highband component */ - float Hilbert_Mem[], /* i/o: memory */ - float state_lsyn_filt_shb_local[], /* i/o: memory */ - const int16_t L_frame, /* i : ACELP Frame length */ - int16_t *syn_dm_phase ); - -void ScaleShapedSHB( - const int16_t length, /* i : SHB overlap length */ - float *synSHB, /* i/o: synthesized shb signal */ - float *overlap, /* i/o: buffer for overlap-add */ - const float *subgain, /* i : subframe gain */ - const float frame_gain, /* i : frame gain */ - const float *win, /* i : window */ - const float *subwin /* i : subframes window */ -); - -void Interpolate_allpass_steep( - const float *in, /* i : input array of size N */ - float *mem, /* i/o: memory */ - const int16_t N, /* i : number of input samples */ - float *out /* o : output array of size 2*N */ -); - -void Decimate_allpass_steep( - const float *in, /* i : input array of size N */ - float *mem, /* i/o: memory */ - const int16_t N, /* i : number of input samples */ - float *out /* o : output array of size N/2 */ -); - -void interpolate_3_over_2_allpass( - const float *input, /* i : input signal */ - const int16_t len, /* i : number of input samples */ - float *out, /* o : output signal */ - float *mem /* i/o: memory */ -); - -void decimate_2_over_3_allpass( - const float *input, /* i : input signal */ - const int16_t len, /* i : number of input samples */ - float *out, /* o : output signal */ - float *mem, /* i/o: memory */ - float *lp_mem ); - -void interpolate_3_over_1_allpass( - const float *input, /* i : input signal */ - const int16_t len, /* i : number of input samples */ - float *out, /* o : output signal */ - float *mem /* i/o: memory */ -); - -void InitSWBencBuffer( - TD_BWE_ENC_HANDLE hBWE_TD /* i/o: TD BWE data handle */ -); - -void InitSWBencBufferStates( - TD_BWE_ENC_HANDLE hBWE_TD, /* i/o: TD BWE data handle */ - float *shb_speech /* o : SHB target signal (6-14kHz) at 16kHz */ -); - -void swb_tbe_enc( - Encoder_State *st, /* i/o: encoder state structure */ - STEREO_ICBWE_ENC_HANDLE hStereoICBWE, /* i/o: IC-BWE state structure */ - const float *new_speech, /* i : original input signal */ - const float *bwe_exc_extended, /* i : bandwidth extended exciatation */ - const float voice_factors[], /* i : voicing factors */ - float *White_exc16k, /* o : shaped white excitation for the FB TBE */ - const float pitch_buf[] /* i : pitch for each subframe */ -); - -void swb_tbe_dec( - Decoder_State *st, /* i/o: decoder state structure */ - STEREO_ICBWE_DEC_HANDLE hStereoICBWE, /* i/o: IC-BWE state structure */ - const float *bwe_exc_extended, /* i : bandwidth extended exciatation */ - const float voice_factors[], /* i : voicing factors */ - const float old_syn_12k8_16k[], /* i : low band synthesis at 12.8kHz or 16kHz */ - float *White_exc16k, /* o : shaped white excitation for the FB TBE */ - float *synth, /* i/o: ACELP core synthesis/final synthesis */ - float *pitch_buf ); - -void flip_and_downmix_generic( - float input[], /* i : input spectrum */ - float output[], /* o : output spectrum */ - const int16_t length, /* i : length of spectra */ - float mem1_ext[HILBERT_ORDER1], /* i/o: Hilbert filter memory */ - float mem2_ext[2 * HILBERT_ORDER2], /* i/o: memory */ - float mem3_ext[2 * HILBERT_ORDER2], /* i/o: memory */ - int16_t *phase_state /* i/o: Phase state in case frequency isn't multiple of 50 Hz */ -); -void flip_and_downmix_generic_fx_32( - Word32 input[], /* i : input spectrum Qx*/ - Word32 output[], /* o : output spectrum Qx*/ - const Word16 length, /* i : length of spectra */ - Word32 mem1_ext[HILBERT_ORDER1], /* i/o: memory Qx*/ - Word32 mem2_ext[2 * HILBERT_ORDER2], /* i/o: memory Qx*/ - Word32 mem3_ext[2 * HILBERT_ORDER2], /* i/o: memory Qx*/ - Word16 *phase_state /* i/o: Phase state in case frequency isn't multiple of 50 Hz */ -); -void non_linearity( - const float input[], /* i : input signal */ - float output[], /* i : output signal */ - float old_bwe_exc_extended[], /* i/o: memory bugffer */ - const int16_t length, /* i : input length */ - float *prev_scale, /* i/o: memory */ - const int16_t coder_type, /* i : Coder Type */ - const float *voice_factors, /* i : Voice Factors */ - const int16_t L_frame /* i : ACELP frame length */ -); - -void interp_code_5over2( - const float inp_code[], /* i : input vector */ - float interp_code[], /* o : output vector */ - const int16_t inp_length /* i : length of the input vector */ -); - -void interp_code_4over2( - const float inp_code[], /* i : input vector */ - float interp_code[], /* o : output vector */ - const int16_t inp_length /* i : length of the input vector */ -); - -void flip_spectrum_and_decimby4( - const float input[], /* i : input spectrum */ - float output[], /* o : output spectrum */ - const int16_t length, /* i : vector length */ - float mem1[], /* i/o: memory */ - float mem2[], /* i/o: memory */ - const int16_t ramp_flag /* i : flag to trigger slow ramp-up of output */ -); - -void GenShapedWBExcitation( - float *excSHB, /* o : synthesized shaped shb exctiation */ - const float *lpc_shb, /* i : lpc coefficients */ - float *exc4kWhtnd, /* o : whitened synthesized shb excitation */ - float *mem_csfilt, /* i/o: memory */ - float *mem_genSHBexc_filt_down1, /* i/o: memory */ - float *mem_genSHBexc_filt_down2, /* i/o: memory */ - float *mem_genSHBexc_filt_down3, /* i/o: memory */ - float *state_lpc_syn, /* i/o: memory */ - const int16_t coder_type, /* i : coding type */ - const float *bwe_exc_extended, /* i : bandwidth extended exciatation */ - int16_t bwe_seed[], /* i/o: random number generator seed */ - const float voice_factors[], /* i : voicing factor */ - const int16_t uv_flag, /* i : unvoiced flag */ - const int16_t igf_flag ); - -void GenWBSynth( - const float *input_synspeech, /* i : input synthesized speech */ - float *shb_syn_speech_16k, /* o : output highband compnent */ - float *state_lsyn_filt_shb1, /* i/o: memory */ - float *state_lsyn_filt_shb2 /* i/o: memory */ -); - -void wb_tbe_enc( - Encoder_State *st, /* i/o: encoder state structure */ - const float *hb_speech, /* i : HB target signal (6-8kHz) at 16kHz */ - const float *bwe_exc_extended, /* i : bandwidth extended exciatation */ - const float pitch_buf[], /* i : pitch for each subframe */ - const float voicing[] /* o : OL maximum normalized correlation */ -); - -void wb_tbe_dec( - Decoder_State *st, /* i/o: decoder state structure */ - const float *bwe_exc_extended, /* i : bandwidth extended exciatation */ - const float voice_factors[], /* i : voicing factors */ - float *synth /* i/o: ACELP core synthesis/final synthesis */ -); - -void tbe_write_bitstream( - Encoder_State *st /* i/o: encoder state structure */ -); - -void tbe_read_bitstream( - Decoder_State *st /* i/o: decoder state structure */ -); - -void GenTransition( - TD_BWE_DEC_HANDLE hBWE_TD, /* i/o: TD BWE data handle */ - float *outputHB, /* o : synthesized HB transitions signal */ - const int32_t output_Fs, /* i : output sampling rate */ - const int16_t element_mode, /* i : element mode */ - const int16_t L_frame, /* i : ACELP frame length */ - const int16_t rf_flag, /* i : RF flag */ - const int32_t total_brate /* i : total bitrate */ -); - - -void GenTransition_fixed( - TD_BWE_DEC_HANDLE hBWE_TD, /* i/o: TD BWE data handle */ - Word32 *outputHB_fx, /* o : synthesized HB transitions signal : Q11 */ - const Word32 output_Fs, /* i : output sampling rate : Q0 */ - const Word16 element_mode, /* i : element mode : Q0 */ - const Word16 L_frame, /* i : ACELP frame length : Q0 */ - const Word16 rf_flag, /* i : RF flag : Q0 */ - const Word32 total_brate, /* i : total bitrate : Q0 */ - const Word16 prev_Qx ); - -void GenTransition_WB( - TD_BWE_DEC_HANDLE hBWE_TD, /* i/o: TD BWE data handle */ - float *outputHB, /* o : synthesized HB transitions signal */ - const int32_t output_Fs /* i : output sampling rate */ -); - -void GenTransition_WB_fixed( - TD_BWE_DEC_HANDLE hBWE_TD, /* i/o: TD BWE data handle */ - Word32 *outputHB_fx, /* o : synthesized HB transitions signal : Q11 */ - const Word32 output_Fs /* i : output sampling rate */ -); - -void td_bwe_dec_init( - TD_BWE_DEC_HANDLE hBWE_TD, /* i/o: TD BWE data handle */ - const int16_t extl, /* i : BWE extension layer */ - const int32_t output_Fs /* i : output sampling rate */ -); - -void TBEreset_enc( - TD_BWE_ENC_HANDLE hBWE_TD, /* i/o: TD BWE data handle */ - const int16_t last_core, /* i : last core */ - const int16_t bwidth /* i : audio bandwidth */ -); - -void TBEreset_dec( - Decoder_State *st /* i/o: decoder state structure */ -); - -/*! r: TBE bit consumption per frame */ -int16_t get_tbe_bits( - const int32_t total_brate, /* i : overall bitrate */ - const int16_t bwidth, /* i : audio bandwidth */ - const int16_t rf_mode /* i : channel aware mode */ -); - -void fb_tbe_enc( - Encoder_State *st, /* i/o: encoder state structure */ - const float new_input[], /* i : input speech at 48 kHz sample rate */ - const float fb_exc[] /* i : FB excitation from the SWB part */ -); - -void fb_tbe_dec( - Decoder_State *st, /* i/o: decoder state structure */ - const float fb_exc[], /* i : FB excitation from the SWB part */ - float *hb_synth, /* i/o: high-band synthesis */ - float *fb_synth_ref, /* o : high-band synthesis 16-20 kHz */ - const int16_t output_frame /* i : output frame length */ -); - -void calc_tilt_bwe( - const float *sp, /* i : input signal */ - float *tilt, /* o : signal tilt */ - const int16_t N /* i : signal length */ -); - -void fd_bwe_enc_init( - FD_BWE_ENC_HANDLE hBWE_FD /* i/o: FD BWE data handle */ -); - -void swb_pre_proc( - Encoder_State *st, /* i/o: encoder state structure */ - float *new_swb_speech, /* o : original input signal at 32kHz */ - float *shb_speech, /* o : SHB target signal (6-14kHz) at 16kHz */ - float realBuffer[CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], /* i : real buffer */ - float imagBuffer[CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], /* i : imag buffer */ - CPE_ENC_HANDLE hCPE /* i/o: CPE encoder structure */ -); - -void wb_pre_proc( - Encoder_State *st, /* i/o: encoder state structure */ - const int16_t last_element_mode, /* i : last element mode */ - const float *new_inp_resamp16k, /* i : original input signal */ - float *hb_speech /* o : HB target signal (6-8kHz) at 16kHz */ -); - -void wb_bwe_enc( - Encoder_State *st, /* i/o: encoder state structure */ - const float *new_wb_speech /* i : original input signal at 16kHz */ -); - -void wb_bwe_dec_flt( - Decoder_State *st, /* i/o: decoder state structure */ - const float output[], /* i : synthesis @internal Fs */ - float *synth, /* i/o: ACELP core synthesis/final synthesis */ - float *hb_synth, /* o : SHB synthesis/final synthesis */ - const int16_t use_cldfb_for_dft, /* i : flag to use of CLDFB for DFT Stereo */ - const int16_t output_frame, /* i : frame length */ - const float voice_factors[], /* i : voicing factors */ - const float pitch_buf[] /* i : pitch buffer */ -); - -void swb_bwe_enc( - Encoder_State *st, /* i/o: encoder state structure */ - const int16_t last_element_mode, /* i : last element mode */ - const float *old_input_12k8, /* i : input signal @12.8kHz for SWB BWE */ - const float *old_input_16k, /* i : input signal @16kHz for SWB BWE */ - const float *old_syn_12k8_16k, /* i : ACELP core synthesis at 12.8kHz or 16kHz*/ - const float *new_swb_speech, /* i : original input signal at 32kHz */ - const float *shb_speech /* i : SHB target signal (6-14kHz) at 16kHz */ -); - -void swb_bwe_enc_hr( - Encoder_State *st, /* i/o: encoder state structure */ - const float *new_input, /* i : input signal */ - const int16_t input_frame, /* i : frame length */ - const int16_t unbits /* i : number of core unused bits */ -); - -void fd_bwe_dec_init_flt( - FD_BWE_DEC_HANDLE hBWE_FD /* i/o: FD BWE data handle */ -); - -void swb_bwe_dec_flt( - Decoder_State *st, /* i/o: decoder state structure */ - const float output[], /* i : synthesis @internal Fs */ - const float *synth, /* i : ACELP core synthesis/final synthesis */ - float *hb_synth, /* o : SHB synthesis/final synthesis */ - const int16_t use_cldfb_for_dft, /* i : flag to use of CLDFB for DFT Stereo */ - const int16_t output_frame /* i : frame length */ -); - -void hr_bwe_dec_init_flt( - HR_BWE_DEC_HANDLE hBWE_FD_HR /* i/o: HR BWE data handle */ -); - -void swb_bwe_dec_hr( - Decoder_State *st, /* i/o: decoder state structure */ - const float *syn_12k8_16k, /* i : ACELP core synthesis @16kHz */ - float *hb_synth, /* o : SHB synthesis */ - const int16_t output_frame, /* i : frame length */ - const int16_t unbits, /* i : number of core unused bits */ - const float pitch_buf[] /* i : pitch buffer */ -); - - -void calc_normal_length( - const int16_t core, /* i : core */ - const float *sp, /* i : input signal */ - const int16_t mode, /* i : input mode */ - const int16_t extl, /* i : extension layer */ - int16_t *L_swb_norm, /* o : normalize length */ - int16_t *prev_L_swb_norm /* i/o: last normalize length */ -); - -void calc_norm_envelop( - const float SWB_signal[], /* i : SWB spectrum */ - float *envelope, /* o : normalized envelope */ - const int16_t L_swb_norm, /* i : length of envelope */ - const int16_t SWB_flength, /* i : Length of input/output */ - const int16_t st_offset /* i : offset */ -); - -void time_envelop_shaping( - float werr[], /* i/o: SHB synthesis */ - float SWB_tenv[], /* i/o: frequency envelope */ - const int16_t L /* i : frame length */ -); - -void time_reduce_pre_echo( - const float *synth, /* i : ACELP core synthesis */ - float *error, /* o : SHB BWE synthesis */ - float prev_td_energy, /* o : last td energy */ - const int16_t L /* i : subframe length */ -); - -int16_t WB_BWE_gain_pred( - float *WB_fenv, /* o : WB frequency envelopes */ - const float *core_dec_freq, /* i : Frequency domain core decoded signal */ - const int16_t coder_type, /* i : coding type */ - const int16_t prev_code_type, /* i : coding type of last frame */ - const float prev_WB_fenv, /* i : envelope for last frame */ - const float voice_factors[], /* i : voicing factors */ - const float pitch_buf[], /* i : pitch buffer */ - const int32_t last_core_brate, /* i : previous frame core bitrate */ - const float last_wb_bwe_ener, /* i : previous frame wb bwe signal energy */ - const int16_t last_extl, /* i : extl. layer for last frame */ - const float tilt ); - -void WB_BWE_decoding( - const float *core_dec_freq, /* i : Frequency domain core decoded signal */ - float *WB_fenv, /* i : WB frequency envelopes */ - float *WB_signal, /* o : WB signal in MDCT domain */ - const int16_t WB_flength, /* i : Length of input/output */ - const int16_t mode, /* i : classification for WB signal */ - const int16_t last_extl, /* i : extl. layer for last frame */ - float *prev_Energy, /* i/o: energy for last frame */ - float *prev_WB_fenv, /* i/o: envelope for last frame */ - int16_t *prev_L_wb_norm, /* i/o: length for last frame wb norm */ - const int16_t extl, /* i : extension layer */ - const int16_t coder_type, /* i : coding type */ - const int32_t total_brate, /* i : core layer bitrate */ - int16_t *Seed, /* i/o: random generator seed */ - int16_t *prev_flag, /* i/o: attenu flag of last frame */ - int16_t prev_coder_type /* i : coding type of last frame */ -); - -void SWB_BWE_decoding( - const float *core_dec_freq, /* i : Frequency domain core decoded signal */ - float *SWB_fenv, /* i/o: SWB frequency envelopes */ - float *SWB_signal, /* o : SWB signal in MDCT domain */ - const int16_t SWB_flength, /* i : Length of input/output */ - const int16_t mode, /* i : classification for SWB signal */ - int16_t *frica_flag, /* o : fricative signal flag */ - float *prev_Energy, /* i/o: energy for last frame */ - float *prev_SWB_fenv, /* i/o: envelope for last frame */ - int16_t *prev_L_swb_norm, /* i/o: length for last frame wb norm */ - const float tilt_nb, /* i : tilt of synthesis wb signal */ - int16_t *Seed, /* i/o: random generator seed */ - const int16_t st_offset, /* i : offset value due to different core */ - float *prev_weight, /* i/o: excitation weight value of last frame */ - const int16_t extl, /* i : extension layer */ - const int16_t last_extl /* i : extension layer of last frame */ -); - -void CNG_reset_enc( - Encoder_State *st, /* i/o: encoder state structure */ - float *pitch_buf, /* o : floating pitch for each subframe */ - float *voice_factors, /* o : voicing factors */ - int16_t VBR_cng_reset_flag ); - -/*! r: stability flag */ -uint16_t a2rc( - const float *a, /* i : LPC coefficients */ - float *refl, /* o : Reflection co-efficients */ - const int16_t lpcorder /* i : LPC order */ -); - - -void analy_sp( - const int16_t element_mode, /* i : element mode */ - CPE_ENC_HANDLE hCPE, /* i/o: CPE encoder structure */ - const int32_t input_Fs, /* i : input sampling rate */ - float *speech, /* i : speech buffer */ - float *Bin_E, /* o : per bin log energy spectrum */ - float *Bin_E_old, /* o : per bin log energy spectrum for mid-frame */ - float *fr_bands, /* o : per band energy spectrum (2 analyses) */ - float lf_E[], /* o : per bin E for first VOIC_BINS bins (without DC) */ - float *Etot, /* o : total input energy */ - const int16_t min_band, /* i : minimum critical band */ - const int16_t max_band, /* i : maximum critical band */ - float *band_ener, /* o : energy in critical frequency bands without minimum noise floor E_MIN */ - float *PS, /* o : Per bin energy spectrum */ - float *fft_buff /* o : FFT coefficients */ -); - -void CNG_enc( - Encoder_State *st, /* i/o: State structure */ - float Aq[], /* o : LP coefficients */ - const float *speech, /* i : pointer to current frame input speech buffer */ - float enr, /* i : frame energy output from Levinson recursion */ - const float *lsp_mid, /* i : mid frame LSPs */ - float *lsp_new, /* i/o: current frame LSPs */ - float *lsf_new, /* i/o: current frame LSFs */ - int16_t *allow_cn_step, /* o : allow CN step */ - float *q_env, - int16_t *sid_bw ); - -void swb_CNG_enc( - Encoder_State *st, /* i/o: State structure */ - const float *shb_speech, /* i : SHB target signal (6-14kHz) at 16kHz */ - const float *syn_12k8_16k /* i : ACELP core synthesis at 12.8kHz or 16kHz */ -); - -void lsf_enc( - Encoder_State *st, /* i/o: state structure */ - float *lsf_new, /* o : quantized LSF vector */ - float *lsp_new, /* i/o: LSP vector to quantize/quantized */ - float *lsp_mid, /* i : mid-frame LSP vector */ - float *Aq, /* o : quantized A(z) for 4 subframes */ - const int16_t tdm_low_rate_mode, /* i : secondary channel low rate mode flag */ - const int16_t GSC_IVAS_mode, /* i : GSC IVAS mode */ - const float tdm_lsfQ_PCh[M] /* i : Q LSFs for primary channel */ -); - -void isf_enc_amr_wb( - Encoder_State *st, /* i/o: state structure */ - float *isf_new, /* o : quantized ISF vector */ - float *isp_new, /* i/o: ISP vector to quantize/quantized */ - float *Aq /* o : quantized A(z) for 4 subframes */ -); - -void find_targets( - const float *speech, /* i : pointer to the speech frame */ - const float *mem_syn, /* i : memory of the synthesis filter */ - const int16_t i_subfr, /* i : subframe index */ - float *mem_w0, /* i/o: weighting filter denominator memory */ - const float *p_Aq, /* i : interpolated quantized A(z) filter */ - const float *res, /* i : residual signal */ - const int16_t L_subfr, /* i : length of vectors for gain quantization */ - const float *Ap, /* i : unquantized A(z) filter with bandwidth expansion */ - const float tilt_fac, /* i : tilt factor */ - float *xn, /* o : Close-loop Pitch search target vector */ - float *cn, /* o : target vector in residual domain */ - float *h1 /* o : impulse response of weighted synthesis filter */ -); - -Word16 quant_2p_2N1_fx( /* o: return (2*N)+1 bits */ - const Word16 pos1, /* i: position of the pulse 1 */ - const Word16 pos2, /* i: position of the pulse 2 */ - const Word16 N /* i: number of bits FOR position */ -); -void find_tilt( - const float fr_bands[], /* i : energy in frequency bands */ - const float bckr[], /* i : per band background noise energy estimate */ - float ee[2], /* o : lf/hf E ration for present frame */ - const int16_t pitch[3], /* i : open loop pitch values for 3 half-frames */ - const float voicing[3], /* i : normalized correlation for 3 half-frames */ - const float *lf_E, /* i : per bin energy for low frequencies */ - const float corr_shift, /* i : normalized correlation correction */ - const int16_t bwidth, /* i : input signal bandwidth */ - const int16_t max_band, /* i : maximum critical band */ - float hp_E[], /* o : energy in HF */ - const int16_t codec_mode, /* i : Mode 1 or 2 */ - float *bckr_tilt_lt, /* i/o: lf/hf E ratio of background noise */ - int16_t Opt_vbr_mode ); - -void init_gp_clip( - float mem[] /* o : memory of gain of pitch clipping algorithm */ -); - -int16_t gp_clip( - const int16_t element_mode, /* i : element mode */ - const int32_t core_brate, /* i : core bitrate */ - const float *voicing, /* i : normalized correlations (from OL pitch) */ - const int16_t i_subfr, /* i : subframe index */ - const int16_t coder_type, /* i : coding type */ - const float xn[], /* i : target vector */ - float mem[] /* i/o: memory of gain of pitch clipping algorithm */ -); - -void gp_clip_test_lsf( - const int16_t element_mode, /* i : element mode */ - const int32_t core_brate, /* i : core bitrate */ - const float lsf[], /* i : LSF vector */ - float mem[], /* i/o: memory of gain of pitch clipping algorithm */ - const int16_t Opt_AMR_WB /* i : flag indicating AMR-WB IO mode */ -); - -void gp_clip_test_gain_pit( - const int16_t element_mode, /* i : element mode */ - const int32_t core_brate, /* i : core bitrate */ - const float gain_pit, /* i : gain of quantized pitch */ - float mem[] /* i/o: memory of gain of pitch clipping algorithm */ -); - -void analy_lp( - const float speech[], /* i : pointer to the denoised speech frame */ - const int16_t L_frame, /* i : length of the frame */ - const int16_t L_look, /* i : look-ahead length */ - float *ener, /* o : residual signal energy */ - float A[], /* o : A(z) filter coefficients */ - float epsP[], /* o : LP analysis residual energies for each iteration */ - float lsp_new[], /* o : current frame ISPs */ - float lsp_mid[], /* o : current mid-frame ISPs */ - float lsp_old[], /* i/o: previous frame unquantized ISPs */ - const int16_t Top[2], /* i : open loop pitch lag */ - const float Tnc[2], /* i : open loop pitch gain */ - const int32_t sr_core, /* i : internal sampling rate */ - const int16_t sec_chan_low_rate /* i : TD secondary channel flag */ -); - -void analy_lp_AMR_WB( - const float speech[], /* i : pointer to the speech frame */ - float *ener, /* o : residual energy from Levinson-Durbin */ - float A[], /* o : A(z) filter coefficients */ - float epsP[], /* o : LP analysis residual energies for each iteration */ - float isp_new[], /* o : current frame ISPs */ - float isp_old[], /* i/o: previous frame unquantized ISPs */ - float isf_new[], /* o : current frame ISFs */ - const int16_t Top, /* i : open loop pitch lag */ - const float Tnc /* i : open loop pitch gain */ -); - -void noise_est_init( - NOISE_EST_HANDLE hNoiseEst /* i/o: Noise estimation handle */ -); - -void speech_music_clas_init( - SP_MUS_CLAS_HANDLE hSpMusClas /* i/o: speech/music classifier handle */ -); - -void long_enr( - Encoder_State *st, /* i/o: encoder state structure */ - const float Etot, /* i : total channel energy */ - const int16_t localVAD_HE_SAD, /* i : HE-SAD flag without hangover */ - const int16_t high_lpn_flag, /* i : sp/mus LPN flag */ - FRONT_VAD_ENC_HANDLE hFrontVad[], /* i/o: front-VAD handles */ - const int16_t n_chan, /* i : number of channels */ - const int16_t localVAD_HE_SAD_LR[], /* i : HE-SAD flag without hangover LR channels */ - const float Etot_LR[] /* i : total channel energy LR channels */ -); - -void noise_est_pre( - const float Etot, /* i : Energy of current frame */ - const int16_t ini_frame, /* i : Frame number (init) */ - NOISE_EST_HANDLE hNoiseEst, /* i/o: Noise estimation data handle */ - const int16_t idchan, /* i : channel ID */ - const int16_t element_mode, /* i : element mode */ - const int16_t last_element_mode /* i : last element mode */ -); - -void noise_est_down( - const float fr_bands[], /* i : per band input energy (contains 2 vectors) */ - float bckr[], /* i/o: per band background noise energy estimate */ - float tmpN[], /* o : temporary noise update */ - float enr[], /* o : averaged energy over both subframes */ - const int16_t min_band, /* i : minimum critical band */ - const int16_t max_band, /* i : maximum critical band */ - float *totalNoise, /* o : noise estimate over all critical bands */ - const float Etot, /* i : Energy of current frame */ - float *Etot_last, /* i/o: Energy of last frame */ - float *Etot_v_h2 /* i/o: Energy variaions of noise frames */ -); - -void noise_est( - Encoder_State *st, /* i/o: encoder state structure */ - const int16_t old_pitch1, /* i : previous frame OL pitch[1] */ - const float tmpN[], /* i : temporary noise update */ - const float *epsP, /* i : LP prediction error energies */ - const float Etot, /* i : total channel E */ - const float relE, /* i : relative frame energy */ - const float corr_shift, /* i : normalized correlation correction */ - const float enr[], /* i : averaged energy over both subframes */ - float fr_bands[], /* i : spectrum per critical bands of the current frame */ - float *cor_map_sum, /* o : sum of correlation map from mult-harm analysis */ - float *ncharX, /* o : noise character for sp/mus classifier */ - float *sp_div, /* o : soectral diversity feature */ - float *non_staX, /* o : non-stationarity for sp/mus classifier */ - int16_t *loc_harm, /* o : multi-harmonicity flag for UV classifier */ - const float *lf_E, /* i : per bin energy for low frequencies */ - int16_t *st_harm_cor_cnt, /* i : 1st harm correlation timer */ - const float Etot_l_lp, /* i : Smoothed low energy */ - float *sp_floor, /* o : noise floor estimate */ - float S_map[], /* o : short-term correlation map */ - STEREO_CLASSIF_HANDLE hStereoClassif, /* i/o: stereo classifier structure */ - FRONT_VAD_ENC_HANDLE hFrontVad, /* i/o: front-VAD handle */ - const int16_t ini_frame /* i : Frame number (init) */ -); - -void vad_param_updt( - Encoder_State *st, /* i/o: encoder state structure */ - const float corr_shift, /* i : correlation shift */ - const float corr_shiftR, /* i : correlation shift right channel */ - const float A[], /* i : A(z) unquantized for the 4 subframes */ - const int16_t old_pitch1, /* i : previous frame OL pitch[1] */ - FRONT_VAD_ENC_HANDLE hFrontVad[], /* i/o: front-VAD handles */ - const int16_t n_channels /* i : number of channels */ -); - - -void lp_gain_updt( - const int16_t i_subfr, /* i : subframe number */ - const float gain_pit, /* i : Decoded gain pitch */ - const float norm_gain_code, /* i : Normalised gain code */ - float *lp_gainp, /* i/o: LP-filtered pitch gain(FEC) */ - float *lp_gainc, /* i/o: LP-filtered code gain (FEC) */ - const int16_t L_frame /* i : length of the frame */ -); - -void GSC_enc_init( - GSC_ENC_HANDLE hGSCEnc /* i/o: GSC data handle */ -); - - -/*! r: index of the last band where pitch contribution is significant */ -int16_t Pit_exc_contribution_len( - Encoder_State *st, /* i/o: state structure */ - const float *dct_res, /* i : DCT of residual */ - float *dct_pitex, /* i/o: DCT of pitch contribution */ - float *pitch_buf, /* i/o: Pitch per subframe */ - int16_t *hangover /* i : Hangover for the time contribution switching */ -); - -int16_t stab_est( - float etot, /* i : Total energy of the current frame */ - float *lt_diff_etot, /* i/o: Long term total energy variation */ - float *mem_etot, /* i/o: Total energy memory */ - int16_t *nb_thr_3, /* i/o: Number of consecutives frames of level 3 */ - int16_t *nb_thr_1, /* i/o: Number of consecutives frames of level 1 */ - float *thresh, /* i/o: Detection thresold */ - int16_t *last_music_flag, /* i/o: Previous music detection ouptut */ - const int16_t vad_flag /* i : VAD flag */ -); - -float gsc_gainQ( - BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ - const int16_t element_mode, /* i : element mode */ - const int16_t idchan, /* i : channel ID */ - const float y_gain4[], /* i : gain per band */ - float y_gainQ[], /* o : quantized gain per band */ - const int32_t core_brate, /* i : Core rate */ - const int16_t coder_type, /* i : coding type */ - const int16_t bwidth, /* i : input signal bandwidth */ - const int16_t L_frame, /* i : frame length */ - const int16_t tdm_LRTD_flag, /* i : LRTD stereo mode flag */ - const int32_t core_brate_inp /* i : true core brate */ -); - -void Comp_and_apply_gain( - float exc_diffQ[], /* i/o: gain per band */ - float Ener_per_bd_iQ[], /* o : Quant Ener per band */ - float Ener_per_bd_yQ[], /* o : Ener per band for quantize y */ - int16_t Mbands_gn, /* i : number of bands */ - const int16_t ReUseGain /* i : Reuse the gain in Ener_per_bd_yQ */ -); - -void bands_and_bit_alloc_ivas_fx( - const Word16 cor_strong_limit, /* i : HF correlation */ - const Word16 noise_lev, /* i : dwn scaling factor */ - const Word32 core_brate, /* i : core bit rate */ - const Word16 Diff_len, /* i : Lenght of the difference signal (before pure spectral)*/ - const Word16 bits_used, /* i : Number of bit used before frequency Q */ - Word16 *bit, /* i/o: Number of bit allowed for frequency quantization */ - const Word16 *Ener_per_bd_iQ, /* i/o: Quantized energy vector */ - Word16 *max_ener_band, /* o : Sorted order */ - Word16 *out_bits_per_bands, /* i/o: Number of bit allowed per allowed subband Q3 */ - Word16 *nb_subbands, /* o : Number of subband allowed */ - const Word16 *exc_diff, /* i : Difference signal to quantize (encoder side only) */ - Word16 *concat_in, /* o : Concatened PVQ's input vector (encoder side only) */ - Word16 *pvq_len, /* o : Number of bin covered with the PVQ */ - const Word16 coder_type, /* i : coding type */ - const Word16 bwidth, /* i : input signal bandwidth */ - const Word16 GSC_noisy_speech, /* i : GSC noisy speech flag */ - const Word16 L_frame, /* i : frame length */ - const Word16 element_mode, /* i : element mode */ - const Word16 GSC_IVAS_mode /* i : GSC IVAS mode */ -); - -void GSC_dec_init_ivas( - GSC_DEC_HANDLE hGSCDec /* i/o: GSC data handle */ -); - -void decod_audio( - Decoder_State *st, /* i/o: decoder static memory */ - float dct_epit[], /* o : GSC excitation in DCT domain */ - const float *Aq, /* i : LP filter coefficient */ - float *tmp_noise, /* o : long term temporary noise energy */ - float *pitch_buf, /* o : floating pitch values for each subframe */ - float *voice_factors, /* o : voicing factors */ - float *exc_dct_in, /* i/o: adapt. excitation exc */ - float *exc2, /* i/o: adapt. excitation/total exc */ - float *bwe_exc, /* o : excitation for SWB TBE */ - float *lsf_new, /* i : current frame ISF vector */ - float *gain_buf, /* o : floating pitch gain for each subframe */ - const int16_t tdm_lp_reuse_flag, /* i : LPC reuse flag */ - const int16_t tdm_low_rate_mode, /* i : secondary channel low rate mode flag */ - const int16_t tdm_Pitch_reuse_flag, /* i : primary channel pitch reuse flag */ - const float tdm_Pri_pitch_buf[] /* i : primary channel pitch buffer */ -); - -void gsc_dec( - Decoder_State *st, /* i/o: State structure */ - float exc_dct_in[], /* i/o: dct of pitch-only/total excitation */ - const int16_t pit_band_idx, /* i : pitch band index */ - const int16_t Diff_len, /* i : */ - const int16_t bits_used, /* i : total number of bits used */ - const int16_t nb_subfr, /* i : Number of subframe considered */ - const int16_t coder_type, /* i : coding type */ - int16_t *last_bin, /* i : last bin of bit allocation */ - const float *lsf_new, /* i : ISFs at the end of the frame */ - float *exc_wo_nf, /* o : excitation (in f domain) without noisefill*/ - float *tmp_noise /* o : long-term noise energy */ -); - -void dec_pit_exc( - Decoder_State *st, /* i/o: decoder static memory */ - const int16_t L_frame, /* i : length of the frame */ - const float *Aq, /* i : LP filter coefficient */ - const float Es_pred, /* i : predicted scaled innov. energy */ - float *pitch_buf, /* o : floating pitch values for each subframe */ - float *code, /* o : innovation */ - float *exc, /* i/o: adapt. excitation exc */ - const int16_t nb_subfr, /* i : Number of subframe considered */ - float *gain_buf, /* o : floating pitch gain for each subframe */ - const int16_t tdm_Pitch_reuse_flag, /* i : primary channel pitch reuse flag */ - const float tdm_Pri_pitch_buf[] /* i : primary channel pitch buffer */ -); - -void music_postfilt_init_flt( - MUSIC_POSTFILT_HANDLE hMusicPF /* i/o: LD music postfilter handle */ -); - -void LD_music_post_filter( - MUSIC_POSTFILT_HANDLE hMusicPF, /* i/o: LD music postfilter handle */ - const float dtc_in[], /* i : input synthesis */ - float dtc_out[], /* o : output synthesis */ - const int32_t core_brate, /* i : core bitrate */ - const int16_t coder_type, /* i : Coder type : -1 in case of IO */ - const int16_t Last_coder_type /* i : last Coder type */ -); - -void Post_music_postP( - float dct_buffer_in[], /* i/o: excitation buffer */ - float exc_buffer_out[], /* o : DCT output buffer */ - float *exc2, /* i/o: Current excitation to be overwriten */ - const float *mem_tmp, /* i : previous frame synthesis memory */ - float *st_mem_syn2, /* i/o: current frame synthesis memory */ - const float *Aq, /* i : LPC filter coefficients */ - float *syn /* i/o: 12k8 synthesis */ -); - -void Prep_music_postP( - float exc_buffer_in[], /* i/o: excitation buffer */ - float dct_buffer_out[], /* o : DCT output buffer */ - float filt_lfE[], /* i/o: long term spectrum energy */ - const int16_t last_core, /* i : last core */ - const float *pitch_buf, /* i : current frame pitch information */ - float *LDm_enh_lp_gbin /* o : smoothed suppression gain, per bin FFT */ -); - -void speech_music_classif( - Encoder_State *st, /* i/o: encoder state structure */ - const float *new_inp, /* i : new input signal */ - const float *inp, /* i : input signal to locate attach position */ - const int16_t localVAD_HE_SAD, /* i : HE-SAD flag without hangover */ - const float lsp_new[M], /* i : LSPs in current frame */ - const float cor_map_sum, /* i : correlation map sum (from multi-harmonic anal.) */ - const float epsP[M + 1], /* i : LP prediciton error */ - const float PS[], /* i : energy spectrum */ - const float Etot, /* i : total frame energy */ - const float old_cor, /* i : max correlation from previous frame */ - int16_t *attack_flag, /* o : attack flag (GSC or TC) */ - const float non_staX, /* i : unbound non-stationarity for sp/mus classifier */ - const float relE, /* i : relative frame energy */ - int16_t *high_lpn_flag, /* o : sp/mus LPN flag */ - const int16_t flag_spitch /* i : flag to indicate very short stable pitch */ -); -void ivas_find_wsp( - const Word16 L_frame, /* i : length of the frame */ - const Word16 L_subfr, /* i : length of subframe */ - const Word16 nb_subfr, /* i : number of subframes */ - const Word16 *A_fx, /* i : A(z) filter coefficients */ - Word16 *Aw_fx, /* o : weighted A(z) filter coefficients */ - const Word16 *speech_fx, /* i : pointer to the denoised speech frame */ - const Word16 tilt_fact, /* i : tilt factor */ - Word16 *wsp_fx, /* o : poitnter to the weighted speech frame */ - Word16 *mem_wsp_fx, /* i/o: W(Z) denominator memory */ - const Word16 gamma, /* i : weighting factor */ - const Word16 L_look /* i : look-ahead */ -); -void find_wsp( - const int16_t L_frame, /* i : length of the frame */ - const int16_t L_subfr, /* i : length of subframe */ - const int16_t nb_subfr, /* i : number of subframes */ - const float *A, /* i : A(z) filter coefficients */ - float *Aw, /* o : weighted A(z) filter coefficients */ - const float *speech, /* i : pointer to the denoised speech frame */ - const float tilt_fact, /* i : tilt factor */ - float *wsp, /* o : poitnter to the weighted speech frame */ - float *mem_wsp, /* i/o: W(Z) denominator memory */ - const float gamma, /* i : weighting factor */ - const int16_t L_look /* i : look-ahead */ -); - -void gain_enc_amr_wb( - BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ - const float *xn, /* i : target vector */ - const float *y1, /* i : zero-memory filtered adaptive excitation */ - const float *y2, /* i : zero-memory filtered algebraic codebook excitation */ - const float *code, /* i : algebraic excitation */ - const int32_t core_brate, /* i : core bitrate */ - float *gain_pit, /* i/o: Pitch gain / Quantized pitch gain */ - float *gain_code, /* o : Quantized codebook gain */ - float *gain_inov, /* o : innovation gain */ - float *norm_gain_code, /* o : norm. gain of the codebook excitation */ - float *coeff, /* i/o: correlations , -2,, -2 and 2 */ - const int16_t clip_gain, /* i : gain pitch clipping flag (1 = clipping) */ - float *past_qua_en /* i/o: gain quantization memory (4 words) */ -); - -void gain_enc_lbr( - BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ - const int16_t gains_mode[], /* i : gain bits */ - const int16_t coder_type, /* i : coding type */ - const int16_t i_subfr, /* i : subframe index */ - const float *xn, /* i : target vector */ - const float *y1, /* i : zero-memory filtered adaptive excitation */ - const float *y2, /* i : zero-memory filtered algebraic codebook excitation */ - const float *code, /* i : algebraic excitation */ - float *gain_pit, /* o : quantized pitch gain */ - float *gain_code, /* o : quantized codebook gain */ - float *gain_inov, /* o : gain of the innovation (used for normalization) */ - float *norm_gain_code, /* o : norm. gain of the codebook excitation */ - float *g_corr, /* i/o: correlations , -2,, -2 and 2 */ - float gains_mem[], /* i/o: pitch gain and code gain from previous subframes */ - const int16_t clip_gain, /* i : gain pitch clipping flag (1 = clipping) */ - const int16_t L_subfr /* i : subfr Lenght */ -); - -void gain_enc_mless( - BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ - const int16_t gains_mode[], /* i : gain bits */ - const int16_t element_mode, /* i : element mode */ - const int16_t L_frame, /* i : length of the frame */ - const int16_t i_subfr, /* i : subframe index */ - const int16_t tc_subfr, /* i : TC subframe index */ - const float *xn, /* i : target vector */ - const float *y1, /* i : zero-memory filtered adaptive excitation */ - const float *y2, /* i : zero-memory filtered algebraic codebook excitation */ - const float *code, /* i : algebraic excitation */ - const float Es_pred, /* i : predicted scaled innovation energy */ - float *gain_pit, /* o : quantized pitch gain */ - float *gain_code, /* o : quantized codebook gain */ - float *gain_inov, /* o : innovation gain */ - float *norm_gain_code, /* o : norm. gain of the codebook excitation */ - float *coeff, /* i/o: correlations , -2,, -2 and 2 */ - const int16_t clip_gain /* i : gain pitch clipping flag (1 = clipping) */ -); - -void gain_enc_SQ( - BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ - const int16_t gains_mode[], /* i : gain bits */ - const int16_t i_subfr, /* i : subframe index */ - const float *xn, /* i : target vector */ - const float *yy1, /* i : zero-memory filtered adaptive excitation */ - const float *y2, /* i : zero-memory filtered algebraic codebook excitation */ - const float *code, /* i : algebraic excitation */ - const float Es_pred, /* i : predicted scaled innovation energy */ - float *gain_pit, /* o : quantized pitch gain */ - float *gain_code, /* o : quantized codebook gain */ - float *gain_inov, /* o : gain of the innovation (used for normalization) */ - float *norm_gain_code, /* o : norm. gain of the codebook excitation */ - float *g_corr, /* i/o: correlations , -2,, -2 and 2 */ - const int16_t clip_gain /* i : gain pitch clipping flag (1 = clipping) */ -); - -/*! r: Return index of quantization */ -int16_t gain_enc_gaus( - float *gain, /* i/o: Code gain to quantize */ - const int16_t bits, /* i : number of bits to quantize */ - const float lowBound, /* i : lower bound of quantizer (dB) */ - const float topBound /* i : upper bound of quantizer (dB) */ -); - -void E_corr_xy2( - const float xn[], /* i : target vector */ - const float y1[], /* i : filtered excitation components 1 */ - const float y2[], /* i : filtered excitation components 2 */ - float g_corr[], /* o : correlations between x, y1, y2, y3, y4 */ - const int16_t L_subfr /* i : subframe size */ -); - - -/*! r: coding type */ -int16_t find_uv( - Encoder_State *st, /* i/o: encoder state structure */ - const float *pitch_fr, /* i : pointer to adjusted fractional pitch (4 val.) */ - const float *voicing_fr, /* i : refined correlation for each subframes */ - const float *speech, /* i : pointer to speech signal for E computation */ - const float *ee, /* i : lf/hf Energy ratio for present frame */ - float *dE1X, /* o : sudden energy increase for S/M classifier */ - const float corr_shift, /* i : normalized correlation correction in noise */ - const float relE, /* i : relative frame energy */ - const float Etot, /* i : total energy */ - const float hp_E[], /* i : energy in HF */ - int16_t *flag_spitch, /* i/o: flag to indicate very short stable pitch and high correlation */ - const int16_t last_core_orig, /* i : original last core */ - STEREO_CLASSIF_HANDLE hStereoClf /* i/o: stereo classifier structure */ -); - -/*! r: classification for current frames */ -int16_t signal_clas( - Encoder_State *st, /* i/o: encoder state structure */ - const float *speech, /* i : pointer to speech signal for E computation */ - const float *ee, /* i : lf/hf E ration for 2 half-frames */ - const float relE, /* i : frame relative E to the long term average */ - const int16_t L_look, /* i : look-ahead */ - int16_t *clas_mod /* o : class flag for NOOP detection */ -); - -void select_TC( - const int16_t codec_mode, /* i : codec mode */ - const int16_t tc_cnt, /* i : TC frame counter */ - int16_t *coder_type, /* i/o: coder type */ - const int16_t localVAD /* i : VAD without hangover */ -); - - -void wb_vad_init( - VAD_HANDLE hVAD /* i/o: VAD data handle */ -); - -int16_t dtx_hangover_addition( - Encoder_State *st, /* i/o: encoder state structure */ - const int16_t vad_flag, /* i : VAD flag */ - const float snr, /* i : input single SNR estimate */ - const int16_t cldfb_subtraction, /* i : */ - int16_t *vad_hover_flag, /* o : VAD hangover flag */ - VAD_HANDLE hVAD, /* i/o: VAD handle for L or R channel */ - NOISE_EST_HANDLE hNoiseEst, /* i : Noise estimation handle */ - int16_t *rem_dtx_ho /* o : Expected remaining hangover frames */ -); - -int16_t wb_vad( - Encoder_State *st, /* i/o: encoder state structure */ - const float fr_bands[], /* i : per band input energy (contains 2 vectors) */ - int16_t *noisy_speech_HO, /* o : SC-VBR noisy speech HO flag */ - int16_t *clean_speech_HO, /* o : SC-VBR clean speech HO flag */ - int16_t *NB_speech_HO, /* o : SC-VBR NB speech HO flag */ - float *snr_sum_he, /* i : voicing metric from SAD */ - int16_t *localVAD_HE_SAD, /* o : HE_SAD decision without hangovers */ - int16_t *flag_noisy_speech_snr, /* o : */ - VAD_HANDLE hVAD, /* i/o: VAD handle */ - NOISE_EST_HANDLE hNoiseEst, /* i/o: Noise estimation handle */ - float lp_speech, /* i : long term active speech energy average */ - float lp_noise /* i : long term noise energy */ -); - -void bw_detect( - Encoder_State *st, /* i/o: Encoder State */ - const float signal_in[], /* i : input signal */ - float *spectrum, /* i : MDCT spectrum */ - const float *enerBuffer, /* i : energy buffer */ - const IVAS_FORMAT ivas_format, /* i : IVAS format */ - const int16_t mct_on /* i : flag MCT mode */ -); - -void set_bw( - const int16_t element_mode, /* i : element mode */ - const int32_t element_brate, /* i : element bitrate */ - Encoder_State *st, /* i/o: Encoder State */ - const int16_t codec_mode /* i : codec mode */ -); - -float gaus_encode( - Encoder_State *st, /* i/o: encoder state structure */ - const int16_t i_subfr, /* i : subframe index */ - const float *h1, /* i : weighted filter input response */ - const float *xn, /* i : target vector */ - float *exc, /* o : pointer to excitation signal frame */ - float *mem_w0, /* o : weighting filter denominator memory */ - float *gp_clip_mem, /* o : memory of gain of pitch clipping algorithm */ - float *tilt_code, /* o : synthesis excitation spectrum tilt */ - float *code, /* o : algebraic excitation */ - float *gain_code, /* o : Code gain. */ - float *y2, /* o : zero-memory filtered adaptive excitation */ - float *gain_inov, /* o : innovation gain */ - float *voice_fac, /* o : voicing factor */ - float *gain_pit, /* o : adaptive excitation gain */ - float *norm_gain_code /* o : normalized innovative cb. gain */ -); - -void td_cng_enc_init( - TD_CNG_ENC_HANDLE hTdCngEnc, /* i/o: DTX/TD CNG data handle */ - const int16_t Opt_DTX_ON, /* i : flag indicating DTX operation */ - const int16_t max_bwidth /* i : maximum encoded bandwidth */ -); - -void dtx( - Encoder_State *st, /* i/o: encoder state structure */ - const int32_t ivas_total_brate, /* i : IVAS total bitrate */ - const int16_t vad, /* i : VAD flag for DTX */ - const float speech[] /* i : Pointer to the speech frame */ -); - -void dtx_hangover_control( - Encoder_State *st, /* i/o: encoder state structure */ - const float lsp_new[M] /* i : current frame LSPs */ -); - - -void updt_enc_common( - Encoder_State *st /* i/o: encoder state structure */ -); - -void updt_IO_switch_enc( - Encoder_State *st, /* i/o: state structure */ - const int16_t input_frame /* i : input frame length */ -); - -void transition_enc( - Encoder_State *st, /* i/o: encoder state structure */ - const int16_t i_subfr, /* i : subframe index */ - int16_t *tc_subfr, /* i/o: TC subframe index */ - int16_t *Jopt_flag, /* i : joint optimization flag */ - int16_t *position, /* i/o: maximum of residual signal index */ - int16_t *T0, /* i/o: close loop integer pitch */ - int16_t *T0_frac, /* i/o: close loop fractional part of the pitch */ - int16_t *T0_min, /* i/o: lower limit for close-loop search */ - int16_t *T0_max, /* i/o: higher limit for close-loop search */ - float *exc, /* i/o: pointer to excitation signal frame */ - float *y1, /* o : zero-memory filtered adaptive excitation */ - const float *h1, /* i : weighted filter input response */ - const float *xn, /* i : target vector */ - float *xn2, /* o : target vector for innovation search */ - float *gp_cl, /* i/o: memory of gain of pitch clipping algorithm */ - float *gain_pit, /* o : adaptive excitation gain */ - float *g_corr, /* o : ACELP correlation values */ - int16_t *clip_gain, /* i/o: adaptive gain clipping flag */ - float **pt_pitch, /* o : floating pitch values */ - float *bwe_exc, /* i/o: excitation for SWB TBE */ - int16_t *unbits /* i/o: unused bits */ -); - -void tc_classif_enc( - const int16_t L_frame, /* i : length of the frame */ - int16_t *tc_subfr, /* i/o: TC subframe index */ - int16_t *position, /* i/o: maximum of residual signal index */ - const int16_t attack_flag, /* i : attack flag */ - const int16_t pitch, /* i : open loop pitch estimates for first halfframe */ - const float *res /* i : pointer to the LP residual signal frame */ -); - - -void gain_enc_tc( - BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ - const int16_t gains_mode[], /* i : gain bits */ - const int16_t i_subfr, /* i : subframe index */ - const float xn[], /* i : target vector */ - const float y2[], /* i : zero-memory filtered algebraic codebook excitation */ - const float code[], /* i : algebraic excitation */ - const float Es_pred, /* i : predicted scaled innovation energy */ - float *gain_pit, /* o : pitch gain / Quantized pitch gain */ - float *gain_code, /* o : quantized codebook gain */ - float *gain_inov, /* o : innovation gain */ - float *norm_gain_code /* o : norm. gain of the codebook excitation */ -); - - -/*! r: comfort noise gain factor */ -float AVQ_cod( - const float xri[], /* i : vector to quantize */ - int16_t xriq[], /* o : quantized normalized vector (assuming the bit budget is enough) */ - const int16_t nb_bits, /* i : number of allocated bits */ - const int16_t Nsv /* i : number of subvectors (lg=Nsv*8) */ -); - -void AVQ_encmux( - BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ - const int16_t extl, /* i : extension layer */ - int16_t xriq[], /* i/o: rounded subvectors [0..8*Nsv-1] followed by rounded bit allocations [8*Nsv..8*Nsv+Nsv-1] */ - int16_t *nb_bits, /* i/o: number of allocated bits */ - const int16_t Nsv, /* i : number of subvectors */ - int16_t nq[], /* o : AVQ nq index */ - int16_t avq_bit_sFlag, /* i : flag indicating AVQ bit savings */ - int16_t trgtSvPos /* i : target SV for AVQ bit savings */ -); - -void ordr_esti( - const int16_t k, /* i : sub-vector index */ - int16_t *Mpos, /* i/o: dominant sub-vector position from ACV */ - int16_t svOrder[], /* i/o: AVQ sub-vector order */ - const int16_t Nsv /* i : total sub-vectors in a sub-frames */ -); - -void re8_cod( - int16_t x[], /* i : point in RE8 (8-dimensional integer vector) */ - int16_t *n, /* i : codebook number (*n is an integer defined in {0,2,3,4,..,n_max}) */ - uint16_t *I, /* o : index of c (pointer to unsigned 16-bit word) */ - int16_t k[] /* o : index of v (8-dimensional vector of binary indices) = Voronoi index */ -); - -void pre_exc( - const int16_t Opt_AMR_WB, /* i : flag indicating AMR-WB IO mode */ - const int16_t L_frame, /* i : frame length */ - const float *speech, /* i : input speech */ - const float *p_Aq, /* i : 12k8 Lp coefficient */ - const float *p_A, /* i : unquantized A(q) filter with bandwidth expansion */ - const int16_t coder_type, /* i : coding type */ - const int16_t i_subfr, /* i : current sub frame indicator */ - float *Ap, /* o : weighted LP filter coefficients */ - const float *res, /* i : residual signal */ - float *h1, /* o : impulse response of weighted synthesis filter */ - float *xn, /* o : close-loop Pitch search target vector */ - float *cn, /* o : target vector in residual domain */ - float *mem_syn, /* i/o: memory of the synthesis filter */ - float *mem_w0, /* i/o: weighting filter denominator memory */ - const int16_t L_subfr /* i : subframe length */ -); - - -void encod_amr_wb( - Encoder_State *st, /* i/o: state structure */ - const float speech[], /* i : input speech */ - const float Aw[], /* i : weighted A(z) unquantized for subframes */ - const float Aq[], /* i : 12k8 Lp coefficient */ - const float *res, /* i : residual signal */ - float *syn, /* i/o: core synthesis */ - float *exc, /* i/o: current non-enhanced excitation */ - float *exc2, /* i/o: current enhanced excitation */ - float *pitch_buf, /* i/o: floating pitch values for each subframe */ - int16_t hf_gain[NB_SUBFR], /* o : decoded HF gain */ - const float *speech16k /* i : input speech @16kHz */ -); - -void stat_noise_uv_enc( - Encoder_State *st, /* i/o: state structure */ - const float *epsP, /* i : LP prediction errors */ - const float *isp_new, /* i : immittance spectral pairs at 4th sfr */ - const float *isp_mid, /* i : immittance spectral pairs at 2nd sfr */ - float *Aq, /* i/o: A(z) quantized for the 4 subframes */ - float *exc2, /* i/o: excitation buffer */ - const int16_t uc_two_stage_flag /* o : flag undicating two-stage UC */ -); - -void re8_compute_base_index( - const int16_t *x, /* i : Elemen of Q2, Q3 or Q4 */ - const int16_t ka, /* i : Identifier of the absolute leader related to x */ - uint16_t *I /* o : index */ -); - -void transf_cdbk_enc( - Encoder_State *st, /* i/o: encoder state structure */ - const int16_t harm_flag_acelp, /* i : harmonic flag for higher rates ACELP */ - const int16_t i_subfr, /* i : subframe index */ - float cn[], /* i/o: target vector in residual domain */ - float exc[], /* i/o: pointer to excitation signal frame */ - const float *p_Aq, /* i : 12k8 Lp coefficient */ - const float Ap[], /* i : weighted LP filter coefficients */ - const float h1[], /* i : weighted filter input response */ - float xn[], /* i/o: target vector */ - float xn2[], /* i/o: target vector for innovation search */ - float y1[], /* i/o: zero-memory filtered adaptive excitation */ - const float y2[], /* i : zero-memory filtered innovative excitation */ - const float Es_pred, /* i : predicited scaled innovation energy */ - float *gain_pit, /* i/o: adaptive excitation gain */ - const float gain_code, /* i : innovative excitation gain */ - float g_corr[], /* o : ACELP correlation values */ - const int16_t clip_gain, /* i : adaptive gain clipping flag */ - float *gain_preQ, /* o : prequantizer excitation gain */ - float code_preQ[], /* o : prequantizer excitation */ - int16_t *unbits /* i/o: number of AVQ unused bits */ -); -void deemph_lpc( - float *p_Aq_cuerr, /* i : LP coefficients current frame */ - float *p_Aq_old, /* i : LP coefficients previous frame */ - float *LPC_de_curr, /* o : De-emphasized LP coefficients current frame */ - float *LPC_de_old, /* o : De-emphasized LP coefficients previous frame*/ - const int16_t deemph_old ); - -void Interpol_delay( - float *out, /* o : pitch interpolation output */ - float *last, /* i : last frame pitch lag */ - float *current, /* i : current frame pitch lag */ - int16_t SubNum, /* i : subframe number */ - const float *frac /* i : interpolation constant */ -); - -void dequantize_uvg( - int16_t iG1, /* i : gain 1 index */ - int16_t *iG2, /* i : gain 2 index */ - float *G, /* o : quantized gain */ - const int16_t bwidth /* i : audio bandwidth */ -); - -void generate_nelp_excitation( - int16_t *seed, /* i/o: random number seed */ - float *Gains, /* i : excitation gains */ - float *output, /* o : excitation output */ - float gain_fac /* i : gain factor */ -); - -void nelp_encoder( - Encoder_State *st, /* i/o: encoder state */ - float *in, /* i : residual signal */ - float *exc, /* o : NELP quantized excitation signal */ - const int16_t reduce_gains ); - -void encod_nelp( - Encoder_State *st, /* i/o: state structure */ - const float *speech, /* i : input speech */ - const float Aw[], /* i : weighted A(z) unquantized for subframes */ - const float *Aq, /* i : 12k8 Lp coefficient */ - float *res, /* o : residual signal */ - float *synth, /* o : core synthesis */ - float *tmp_noise, /* o : long-term noise energy */ - float *exc, /* i/o: current non-enhanced excitation */ - float *exc2, /* i/o: current enhanced excitation */ - float *pitch_buf, /* o : floating pitch values for each subframe */ - float *voice_factors, /* o : voicing factors */ - float *bwe_exc /* o : excitation for SWB TBE */ -); - -void realft( - float *data, /* i/o: data array */ - int16_t n, /* i : length of data array */ - int16_t isign /* i : sign +1 or -1 */ -); - -ivas_error DTFS_new( - DTFS_STRUCTURE **dtfs_out ); - -void DTFS_copy( - DTFS_STRUCTURE *Xout, /* o : DTFS */ - DTFS_STRUCTURE Xinp /* i : DTFS */ -); - -void DTFS_sub( - DTFS_STRUCTURE *tmp, /* o : output DFTS */ - DTFS_STRUCTURE X1, /* i : DTFS input 1 */ - DTFS_STRUCTURE X2 /* i : DTFS input 2 */ -); - -void DTFS_to_fs( - const float *x, /* i : Time domain signal */ - const int16_t N, /* i : Length of input vector */ - DTFS_STRUCTURE *X, /* o : DTFS structure with a, b, lag */ - const int32_t sampling_rate, - const int16_t FR_flag /* i : FR flag */ -); - -void DTFS_fs_inv( - DTFS_STRUCTURE *X, /* i : DTFS */ - float *x, /* o : time domain sig */ - const int16_t N, /* i : Output length */ - float ph0 /* i : Input phase */ -); - -void DTFS_car2pol( - DTFS_STRUCTURE *X /* i/o: DTFS structure a, b, lag */ - /* input in Cartesion, output in Polar */ -); - -void DTFS_pol2car( - DTFS_STRUCTURE *X /* i/o: DTFS structure a, b, lag */ - /* input in Polar, output in Cartesian */ -); - -/*! r: Return Input RMS between f1/f2 b4 scaling */ -float DTFS_setEngyHarm( - float f1, /* i : lower band freq of input to control energy */ - float f2, /* i : upper band freq of input to control energy */ - float g1, /* i : lower band freq of output to control energy */ - float g2, /* i : upper band freq of output to control energy */ - float en2, /* i : Target Energy to set the DTFS to */ - DTFS_STRUCTURE *X /* i/o: DTFS to adjust the energy of */ -); - -void DTFS_to_erb( - DTFS_STRUCTURE X, /* i : DTFS input */ - float *out /* o : ERB output */ -); - -void DTFS_zeroPadd( - const int16_t N, /* i : Target lag */ - DTFS_STRUCTURE *X /* i/o: DTFS */ -); - -/*! r: Energy */ -float DTFS_getEngy( - DTFS_STRUCTURE X /* i : DTFS to compute energy of */ -); - -void DTFS_adjustLag( - DTFS_STRUCTURE *X_DTFS, /* i/o: DTFS to adjust lag for */ - const int16_t N /* i : Target lag */ -); - -void DTFS_poleFilter( - DTFS_STRUCTURE *X, /* i/o: DTFS to poleFilter inplace */ - const float *LPC, /* i : LPCs */ - const int16_t N /* i : LPCORDER */ -); - -void DTFS_zeroFilter( - DTFS_STRUCTURE *X, /* i/o: DTFS to zeroFilter inplace */ - const float *LPC, /* i : LPCs */ - const int16_t N /* i : LPCORDER */ -); - -float DTFS_alignment_full( - DTFS_STRUCTURE X1_DTFS, /* i : reference DTFS */ - DTFS_STRUCTURE X2_DTFS, /* i : DTFS to shift */ - const int16_t num_steps /* i : resolution */ -); - -void DTFS_phaseShift( - DTFS_STRUCTURE *X, /* i : DTFS to shift */ - float ph /* i : phase to shift */ -); - -void erb_add( - float *curr_erb, /* i/o: current ERB */ - const int16_t l, /* i : current lag */ - const float *prev_erb, /* i : previous ERB */ - const int16_t pl, /* i : previous lag */ - const int16_t *index, /* i : ERB index */ - const int16_t num_erb /* i : number of ERBs */ -); - -void erb_slot( - int16_t lag, /* i : input lag */ - int16_t *out, /* o : ERB slots */ - float *mfreq, /* i : ERB frequencies */ - int16_t num_erb /* i : number of ERBs */ -); - -void erb_diff( - const float *prev_erb, /* i : previous ERB */ - const int16_t pl, /* i : previous lag */ - const float *curr_erb, /* i : current ERB */ - const int16_t l, /* i : current lag */ - const float *curr_lsp, /* i : current LSP coefficients */ - float *out, /* o : ERB difference */ - int16_t *index, /* i : ERB index */ - const int16_t num_erb /* i : Number of ERBs */ -); - -void DTFS_erb_inv( - float *in, /* i : ERB inpt */ - int16_t *slot, /* i : ERB slots filled based on lag */ - float *mfreq, /* i : erb frequence edges */ - DTFS_STRUCTURE *X, /* o : DTFS after erb-inv */ - const int16_t num_erb /* i : Number of ERB bands */ -); - -ivas_error ppp_quarter_encoder( - int16_t *returnFlag, /* o : return value */ - BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ - DTFS_STRUCTURE *CURRCW_Q, /* o : Quantized (amp/phase) DTFS */ - DTFS_STRUCTURE *TARGETCW, /* o : DTFS with quant phase but unquant Amp */ - const int16_t prevCW_lag, /* i : previous lag */ - DTFS_STRUCTURE vCURRCW_NQ, /* i : Unquantized DTFS */ - const float *curr_lpc, /* i : LPCS */ - float *lastLgainE, /* i/o: last low band gain */ - float *lastHgainE, /* i/o: last high band gain */ - float *lasterbE, /* i/o: last ERB vector */ - DTFS_STRUCTURE PREV_CW_E /* i : past DTFS */ -); - -ivas_error WIsyn( - DTFS_STRUCTURE PREVCW, /* i : Prev frame DTFS */ - DTFS_STRUCTURE *CURR_CW_DTFS, /* i/o: Curr frame DTFS */ - const float *curr_lpc, /* i : LPC */ - float *ph_offset, /* i/o: Phase offset to line up at end of frame */ - float *out, /* o : Waveform Interpolated time domain signal */ - const int16_t N, /* i : Number of samples of output to generate */ - const int16_t FR_flag /* i : called for post-smoothing in FR */ -); - -void set_ppp_mode( - Encoder_State *st, /* i/o: encoder state structure */ - const int16_t noisy_speech_HO, /* i : SC-VBR noisy speech HO flag */ - const int16_t clean_speech_HO, /* i : SC-VBR clean speech HO flag */ - const int16_t NB_speech_HO, /* i : SC-VBR NB speech HO flag */ - const int16_t localVAD_he /* i : HE-SAD flag without hangover */ -); - -ivas_error ppp_voiced_encoder( - BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ - SC_VBR_ENC_HANDLE hSC_VBR, /* i/o: SC-VBR state structure */ - const int16_t bwidth, /* i : audio bandwidth */ - const int16_t last_coder_type_raw, /* i : raw last_coder_type */ - const float old_pitch_buf[], /* i : buffer of old subframe pitch values */ - float *in, /* i : residual signal */ - float *out, /* o : Quantized residual signal */ - const int16_t delay, /* i : open loop pitch */ - float *lpc1, /* i : prev frame de-emphasized LPC */ - float *lpc2, /* i : current frame de-emphasized LPC */ - float *exc, /* i : previous frame quantized excitation */ - float *pitch /* o : floating pitch values for each subframe */ -); - -ivas_error encod_ppp( - Encoder_State *st, /* i/o: state structure */ - const float speech[], /* i : input speech */ - const float Aw[], /* i : weighted A(z) unquantized for subframes */ - const float Aq[], /* i : 12k8 Lp coefficient */ - float *res, /* i/o: residual signal */ - float *synth, /* i/o: core synthesis */ - float *exc, /* i/o: current non-enhanced excitation */ - float *exc2, /* i/o: current enhanced excitation */ - float *pitch_buf, /* i/o: floating pitch values for each subframe */ - float *voice_factors, /* o : voicing factors */ - float *bwe_exc /* o : excitation for SWB TBE */ -); - -void reset_rf_indices( - RF_ENC_HANDLE hRF, /* i/o: RF state structure */ - const int16_t L_frame, /* i : frame length */ - int16_t *rf_target_bits_write ); - -void signaling_enc_rf( - Encoder_State *st /* i/o: encoder state structure */ -); - -ivas_error acelp_core_dec( - Decoder_State *st, /* i/o: Decoder state structure */ - float output[], /* o : synthesis @internal Fs */ - float synth[], /* o : synthesis */ - float save_hb_synth[], /* o : HB synthesis */ - float bwe_exc_extended[], /* i/o: bandwidth extended excitation */ - float *voice_factors, /* o : voicing factors */ - float old_syn_12k8_16k[], /* o : intermediate ACELP synthesis at 12.8kHz or 16kHz to be used by SWB BWE */ - const int16_t sharpFlag, /* i : formant sharpening flag */ - float pitch_buf[NB_SUBFR16k], /* o : floating pitch for each subframe */ - int16_t *unbits, /* o : number of unused bits */ - int16_t *sid_bw, /* o : 0-NB/WB, 1-SWB SID */ - STEREO_TD_DEC_DATA_HANDLE hStereoTD, /* i/o: TD stereo decoder handle */ - const float tdm_lspQ_PCh[M], /* i : Q LSPs for primary channel */ - const float tdm_lsfQ_PCh[M], /* i : Q LSFs for primary channel */ - const int16_t use_cldfb_for_dft, /* i : flag to use of CLDFB for DFT Stereo */ - const int16_t last_element_mode, /* i : last element mode */ - const int32_t last_element_brate, /* i : last element bitrate */ - const int16_t flag_sec_CNA, /* i : CNA flag for secondary channel */ - const int16_t nchan_out, /* i : number of output channels */ - STEREO_CNG_DEC_HANDLE hStereoCng, /* i : stereo CNG handle */ - const int16_t read_sid_info /* i : read SID info flag */ -); - -void bass_psfilter_init( - BPF_DEC_HANDLE hBPF /* o : BPF data handle */ -); - -void bass_psfilter( - BPF_DEC_HANDLE hBPF, /* o : BPF data handle */ - const int16_t Opt_AMR_WB, /* i : AMR-WB IO flag */ - const float synth_in[], /* i : synthesis (at 16kHz) */ - const int16_t L_frame, /* i : length of the last frame */ - const float pitch_buf[], /* i : pitch for every subfr [0,1,2,3] */ - const int16_t bpf_off, /* i : do not use BPF when set to 1 */ - float v_stab, /* i : stability factor */ - float *v_stab_smooth, /* i : smoothed stability factor */ - const int16_t coder_type, /* i : coder_type */ - float bpf_noise_buf[] /* o : BPF error signal (at int_fs) */ -); - -void CNG_reset_dec( - Decoder_State *st, /* i/o: decoder state structure */ - float *pitch_buf, /* o : floating pitch for each subframe */ - float *voice_factors /* o : voicing factors */ -); - -void updt_dec( - Decoder_State *st, /* i/o: state structure */ - const float *old_exc, /* i : buffer of excitation */ - const float *pitch_buf, /* i : floating pitch values for each subframe */ - const float Es_pred, /* i : predicited scaled innovation energy */ - const float *Aq, /* i : A(z) quantized for all subframes */ - const float *lsf_new, /* i : current frame LSF vector */ - const float *lsp_new, /* i : current frame LSP vector */ - const float voice_factors[], /* i : voicing factors */ - const float *old_bwe_exc, /* i : buffer of excitation */ - const float *gain_buf /* o : floating pitch gain for each subframe */ -); - -void updt_IO_switch_dec( - const int16_t output_frame, /* i : output frame length */ - Decoder_State *st /* i/o: state structure */ -); - -void updt_dec_common( - Decoder_State *st, /* i/o: decoder state structure */ - const int16_t hq_core_type, /* i : HQ core type */ - const int16_t concealWholeFrameTmp, /* i : concealWholeFrameTmp flag */ - const float *synth /* i : decoded synthesis */ -); - -void td_cng_dec_init( - DEC_CORE_HANDLE st /* i/o: decoder state structure */ -); - -void CNG_dec( - Decoder_State *st, /* i/o: State structure */ - const int16_t last_element_mode, /* i : last element mode */ - float Aq[], /* o : LP coefficients */ - float *lsp_new, /* i/o: current frame LSPs */ - float *lsf_new, /* i/o: current frame LSFs */ - int16_t *allow_cn_step, /* o : allow cn step */ - int16_t *sid_bw, /* o : 0-NB/WB, 1-SWB SID */ - float *q_env ); - -void swb_CNG_dec( - Decoder_State *st, /* i/o: State structure */ - const float *synth, /* i : ACELP core synthesis at 32kHz */ - float *shb_synth, /* o : high-band CNG synthesis */ - const int16_t sid_bw /* i : 0-NB/WB, 1-SWB SID */ -); - -void lsf_dec( - Decoder_State *st, /* i/o: State structure */ - const int16_t tc_subfr, /* i : TC subframe index */ - float *Aq, /* o : quantized A(z) for 4 subframes */ - int16_t *LSF_Q_prediction, /* o : LSF prediction mode */ - float *lsf_new, /* o : de-quantized LSF vector */ - float *lsp_new, /* o : de-quantized LSP vector */ - float *lsp_mid, /* o : de-quantized mid-frame LSP vector */ - const int16_t tdm_low_rate_mode, /* i : secondary channel low rate mode flag */ - const float tdm_lsfQ_PCh[M] /* i : Q LSFs for primary channel */ -); - -void isf_dec_amr_wb( - Decoder_State *st, /* i/o: State structure */ - float *Aq, /* o : quantized A(z) for 4 subframes */ - float *isf_new, /* o : de-quantized ISF vector */ - float *isp_new /* o : de-quantized ISP vector */ -); - -void Es_pred_dec( - float *Es_pred, /* o : predicted scaled innovation energy */ - const int16_t enr_idx, /* i : indice */ - const int16_t nb_bits, /* i : number of bits */ - const int16_t no_ltp /* i : no LTP flag */ -); - -void gaus_dec( - Decoder_State *st, /* i/o: decoder state structure */ - const int16_t i_subfr, /* i : subframe index */ - float *code, /* o : gaussian excitation */ - float *norm_gain_code, /* o : gain of the normalized gaussian excitation */ - float *lp_gainp, /* i/o: lp filtered pitch gain(FER) */ - float *lp_gainc, /* i/o: lp filtered code gain (FER) */ - float *gain_inov, /* o : unscaled innovation gain */ - float *tilt_code, /* o : synthesis excitation spectrum tilt */ - float *voice_fac, /* o : estimated voicing factor */ - float *gain_pit, /* o : reset pitch gain */ - float *pt_pitch, /* o : reset floating pitch buffer */ - float *exc, /* o : excitation signal frame */ - float *gain_code, /* o : gain of the gaussian excitation */ - float *exc2 /* o : scaled excitation signal frame */ -); - -void gain_dec_amr_wb( - Decoder_State *st, /* i/o: decoder state structure */ - const int32_t core_brate, /* i : core bitrate */ - float *gain_pit, /* o : Quantized pitch gain */ - float *gain_code, /* o : Quantized codeebook gain */ - float *past_qua_en, /* i/o: gain quantization memory (4 words) */ - float *gain_inov, /* o : unscaled innovation gain */ - const float *code, /* i : algebraic code excitation */ - float *norm_gain_code /* o : norm. gain of the codebook excitation */ -); - -void gain_dec_lbr( - Decoder_State *st, /* i/o: decoder state structure */ - const int16_t coder_type, /* i : coding type */ - const int16_t i_subfr, /* i : subframe index */ - const float *code, /* i : algebraic excitation */ - float *gain_pit, /* o : quantized pitch gain */ - float *gain_code, /* o : quantized codebook gain */ - float *gain_inov, /* o : gain of the innovation (used for normalization) */ - float *norm_gain_code, /* o : norm. gain of the codebook excitation */ - float gains_mem[], /* i/o: pitch gain and code gain from previous subframes */ - const int16_t L_subfr /* i : subframe length */ -); - -void gain_dec_mless( - Decoder_State *st, /* i/o: decoder state structure */ - const int16_t L_frame, /* i : length of the frame */ - const int16_t coder_type, /* i : coding type */ - const int16_t i_subfr, /* i : subframe number */ - const int16_t tc_subfr, /* i : TC subframe index */ - const float *code, /* i : algebraic code excitation */ - const float Es_pred, /* i : predicted scaled innov. energy */ - float *gain_pit, /* o : Quantized pitch gain */ - float *gain_code, /* o : Quantized codeebook gain */ - float *gain_inov, /* o : unscaled innovation gain */ - float *norm_gain_code /* o : norm. gain of the codebook excitation */ -); - -void gain_dec_SQ( - Decoder_State *st, /* i/o: decoder state structure */ - const int16_t i_subfr, /* i : subframe number */ - const float *code, /* i : algebraic code excitation */ - const float Es_pred, /* i : predicted scaled innov. energy */ - float *gain_pit, /* o : Quantized pitch gain */ - float *gain_code, /* o : Quantized codeebook gain */ - float *gain_inov, /* o : unscaled innovation gain */ - float *norm_gain_code /* o : norm. gain of the codebook excitation */ -); - -/*! r: quantized codebook gain */ -float gain_dec_gaus( - const int16_t index, /* i : quantization index */ - const int16_t bits, /* i : number of bits to quantize */ - const float lowBound, /* i : lower bound of quantizer (dB) */ - const float topBound, /* i : upper bound of quantizer (dB) */ - const float gain_inov, /* i : unscaled innovation gain */ - float *norm_gain_code /* o : gain of normalized gaus. excit. */ -); - -/*! r: floating pitch value */ -float pit_decode_flt( - Decoder_State *st, /* i/o: decoder state structure */ - const int32_t core_brate, /* i : core bitrate */ - const int16_t Opt_AMR_WB, /* i : flag indicating AMR-WB IO mode */ - const int16_t L_frame, /* i : length of the frame */ - int16_t i_subfr, /* i : subframe index */ - const int16_t coder_type, /* i : coding type */ - int16_t *limit_flag, /* i/o: restrained(0) or extended(1) Q limits */ - int16_t *T0, /* o : close loop integer pitch */ - int16_t *T0_frac, /* o : close loop fractional part of the pitch */ - int16_t *T0_min, /* i/o: delta search min for sf 2 & 4 */ - int16_t *T0_max, /* i/o: delta search max for sf 2 & 4 */ - const int16_t L_subfr, /* i : subframe length */ - const int16_t tdm_Pitch_reuse_flag, /* i : primary channel pitch reuse flag */ - const float tdm_Pri_pitch_buf[] /* i : primary channel pitch buffer */ -); - -void abs_pit_dec_flt( - const int16_t fr_steps, /* i : fractional resolution steps (0, 2, 4) */ - int16_t pitch_index, /* i : pitch index */ - const int16_t limit_flag, /* i : restrained(0) or extended(1) Q limits */ - int16_t *T0, /* o : integer pitch lag */ - int16_t *T0_frac /* o : pitch fraction */ -); - -void delta_pit_dec_flt( - const int16_t fr_steps, /* i : fractional resolution steps (0, 2, 4) */ - const int16_t pitch_index, /* i : pitch index */ - int16_t *T0, /* o : integer pitch lag */ - int16_t *T0_frac, /* o : pitch fraction */ - const int16_t T0_min /* i : delta search min */ -); - -void pit_Q_dec_flt( - const int16_t Opt_AMR_WB, /* i : flag indicating AMR-WB IO mode */ - const int16_t pitch_index, /* i : pitch index */ - const int16_t nBits, /* i : # of Q bits */ - const int16_t delta, /* i : Half the CL searched interval */ - const int16_t pit_flag, /* i : absolute(0) or delta(1) pitch Q */ - const int16_t limit_flag, /* i : restrained(0) or extended(1) Q limits */ - int16_t *T0, /* o : integer pitch lag */ - int16_t *T0_frac, /* o : pitch fraction */ - int16_t *T0_min, /* i/o: delta search min */ - int16_t *T0_max, /* i/o: delta search max */ - int16_t *BER_detect /* o : BER detect flag */ -); - -void pit16k_Q_dec_flt( - const int16_t pitch_index, /* i : pitch index */ - const int16_t nBits, /* i : # of Q bits */ - const int16_t limit_flag, /* i : restrained(0) or extended(1) Q limits */ - int16_t *T0, /* o : integer pitch lag */ - int16_t *T0_frac, /* o : pitch fraction */ - int16_t *T0_min, /* i/o: delta search min */ - int16_t *T0_max, /* i/o: delta search max */ - int16_t *BER_detect /* o : BER detect flag */ -); - - -void inov_decode( - Decoder_State *st, /* i/o: decoder state structure */ - const int32_t core_brate, /* i : core bitrate */ - const int16_t Opt_AMR_WB, /* i : flag indicating AMR-WB IO mode */ - const int16_t L_frame, /* i : length of the frame */ - const int16_t sharpFlag, /* i : formant sharpening flag */ - const int16_t i_subfr, /* i : subframe index */ - const float *p_Aq, /* i : LP filter coefficients */ - const float tilt_code, /* i : tilt of of the excitation of previous subframe */ - const float pt_pitch, /* i : pointer to current subframe fractional pitch */ - float *code, /* o : algebraic excitation */ - const int16_t L_subfr /* i : subframe length */ -); - -void dec_acelp_1t64( - Decoder_State *st, /* i/o: decoder state structure */ - float code[], /* o : algebraic (fixed) codebook excitation */ - const int16_t L_subfr /* i : subframe length */ -); - -void dec_acelp_2t32( - Decoder_State *st, /* i/o: decoder state structure */ - float code[] /* o : algebraic (fixed) codebook excitation */ -); - -void dec_acelp_4t64( - Decoder_State *st, /* i/o: decoder state structure */ - int16_t nbbits, /* i : number of bits per codebook */ - float code[], /* o : algebraic (fixed) codebook excitation */ - const int16_t Opt_AMR_WB /* i : flag indicating AMR-WB IO mode */ -); - - -void FEC_exc_estim( - Decoder_State *st, /* i/o: Decoder static memory */ - const int16_t L_frame, /* i : length of the frame */ - float *old_exc, /* i/o: excitation buffer */ - float *exc2, /* o : excitation buffer (for synthesis) */ - float *exc_dct_in, /* o : GSC excitation in DCT domain */ - float *pitch_buf, /* o : Floating pitch for each subframe */ - float *tmp_tc, /* o : FEC pitch */ - float *voice_factors, /* o : voicing factors */ - float *bwe_exc, /* i/o: excitation for SWB TBE */ - float *lsf_new, /* i : ISFs at the end of the frame */ - float *tmp_noise /* o : long-term noise energy */ -); - -void FEC_lsf2lsp_interp_flt( - Decoder_State *st, /* i/o: Decoder static memory */ - const int16_t L_frame, /* i : length of the frame */ - float *Aq, /* o : calculated A(z) for 4 subframes */ - float *lsf, /* o : estimated LSF vector */ - float *lsp /* o : estimated LSP vector */ -); - -void FEC_lsf_estim_enc( - Encoder_State *st, /* i : Encoder static memory */ - float *lsf /* o : estimated LSF vector */ -); - -float frame_energy( - const int16_t L_frame, /* i : length of the frame */ - const float *pitch, /* i : pitch values for each subframe */ - const float *speech, /* i : pointer to speech signal for E computation */ - const float lp_speech, /* i : long term active speech energy average */ - float *frame_ener /* o : pitch-synchronous energy at frame end */ -); - -void FEC_SinOnset( - float *exc, /* i/o: exc vector to modify */ - int16_t puls_pos, /* i : Last pulse position desired */ - int16_t T0, /* i : decoded first frame pitch */ - float enr_q, /* i : energy provided by the encoder */ - float *Aq, /* i : Lsp coefficient */ - const int16_t L_frame /* i : Frame length */ -); - -int16_t FEC_enhACB( - const int16_t L_frame, /* i : Frame length */ - const int16_t last_L_frame, /* i : frame length of last frame */ - float *exc_io, /* i/o: Adaptive codebook memory */ - const int16_t new_pit, /* i : decoded first frame pitch */ - const int16_t puls_pos, /* i : decoder position of the last glottal pulses decoded in the previous frame */ - const float bfi_pitch /* i : Pitch used for concealment */ -); - -void FEC_scale_syn( - const int16_t L_frame, /* i : length of the frame */ - int16_t clas, /* i/o: frame classification */ - const int16_t last_good, /* i : last good frame classification */ - float *synth, /* i/o: synthesized speech at Fs = 12k8 Hz */ - const float *pitch, /* i : pitch values for each subframe */ - float enr_old, /* i : energy at the end of prvious frame */ - float enr_q, /* i : transmitted energy for current frame */ - const int16_t coder_type, /* i : coding type */ - const int16_t LSF_Q_prediction, /* i : LSF prediction mode */ - int16_t *scaling_flag, /* i/o: flag to indicate energy control of syn */ - float *lp_ener_FEC_av, /* i/o: averaged voiced signal energy */ - float *lp_ener_FEC_max, /* i/o: averaged voiced signal energy */ - const int16_t bfi, /* i : current frame BFI */ - const int32_t total_brate, /* i : total bitrate */ - const int16_t prev_bfi, /* i : previous frame BFI */ - const int32_t last_core_brate, /* i : previous frame core bitrate */ - float *exc, /* i/o: excitation signal without enhancement */ - float *exc2, /* i/o: excitation signal with enhancement */ - const float Aq[], /* i : LP filter coefs */ - float *old_enr_LP, /* i/o: LP filter E of last good voiced frame */ - const float *mem_tmp, /* i : temp. initial synthesis filter states */ - float *mem_syn, /* o : initial synthesis filter states */ - const int16_t avoid_lpc_burst_on_recovery, /* i : if true the excitation energy is limited if LP has big gain */ - const int16_t force_scaling /* i : force scaling */ -); - -void FEC_pitch_estim( - const int16_t Opt_AMR_WB, /* i : flag indicating AMR-WB IO mode */ - const int16_t last_core, /* i : last core */ - const int16_t L_frame, /* i : length of the frame */ - const int16_t clas, /* i : current frame classification */ - const int16_t last_good, /* i : last good clas information */ - const float pitch_buf[], /* i : Floating pitch for each subframe */ - const float old_pitch_buf[], /* i : buffer of old subframe pitch values */ - float *bfi_pitch, /* i/o: update of the estimated pitch for FEC */ - int16_t *bfi_pitch_frame, /* o : frame length when pitch was updated */ - int16_t *upd_cnt, /* i/o: update counter */ - const int16_t coder_type ); - -void FEC_encode( - BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ - const ACELP_config acelp_cfg, /* i : configuration of the ACELP */ - const float *synth, /* i : pointer to synthesized speech for E computation */ - const int16_t coder_type, /* i : type of coder */ - int16_t clas, /* i : signal clas for current frame */ - const float *fpit, /* i : close loop fractional pitch buffer */ - const float *res, /* i : LP residual signal frame */ - int16_t *last_pulse_pos, /* i/o: Position of the last pulse */ - const int16_t L_frame, /* i : Frame length */ - const int32_t total_brate /* i : total codec bitrate */ -); - -int16_t FEC_pos_dec( - Decoder_State *st, /* i/o: decoder state structure */ - int16_t *last_pulse_pos, /* o : Last glottal pulse position in the lost ACB */ - float *enr_q, /* o : Decoded energy */ - const int16_t nBits_es_Pred /* i : number of bits for Es_pred Q */ -); - -void improv_amr_wb_gs( - const int16_t clas, /* i : bitrate allocated to the core */ - const int16_t coder_type, /* i : coder_type */ - const int32_t core_brate, /* i : bitrate allocated to the core */ - int16_t *seed_tcx, /* i/o: Seed used for noise generation */ - float *old_Aq, /* i/o: old LPC filter coefficient */ - float *mem_syn2, /* i/o: synthesis memory */ - const float lt_voice_fac, /* i/o: long term voice factor */ - const int16_t locattack, /* i : Flag for a detected attack */ - float *Aq, /* i/o: Decoded LP filter coefficient */ - float *exc2, /* i/o: Decoded complete excitation */ - float *mem_tmp, /* i/o: synthesis temporary memory */ - float *syn, /* i/o: Decoded synthesis to be updated */ - const float *pitch_buf, /* i : Decoded pitch buffer */ - const float Last_ener, /* i : Last energy */ - const int16_t rate_switching_reset, /* i : rate switching reset flag */ - const int16_t last_coder_type, /* i : Last coder_type */ - const int16_t VeryLowRateSTflag /* i : Enable the noise enhancement for very low rate stereo generic mode */ -); - -int16_t tc_classif( - Decoder_State *st /* i/o: decoder state structure */ -); - -void transition_dec( - Decoder_State *st, /* i/o: decoder state structure */ - const int16_t L_frame, /* i : length of the frame */ - const int16_t i_subfr, /* i : subframe index */ - const int16_t tc_subfr, /* i : TC subframe index */ - int16_t *Jopt_flag, /* i : joint optimization flag */ - float *exc, /* i/o: current frame excitation signal */ - int16_t *T0, /* o : close loop integer pitch */ - int16_t *T0_frac, /* o : close loop fractional part of the pitch */ - int16_t *T0_min, /* i/o: delta search min for sf 2 & 4 */ - int16_t *T0_max, /* i/o: delta search max for sf 2 & 4 */ - float **pt_pitch, /* o : floating pitch values */ - int16_t *position, /* i/o: first glottal impulse position in frame */ - float *bwe_exc /* i/o: excitation for SWB TBE */ -); - -void gain_dec_tc( - Decoder_State *st, /* i/o: decoder state structure */ - const int16_t i_subfr, /* i : subframe number */ - const float Es_pred, /* i : predicted scaled innov. energy */ - const float *code, /* i : algebraic code excitation */ - float *gain_pit, /* o : pitch gain */ - float *gain_code, /* o : Quantized codeebook gain */ - float *gain_inov, /* o : unscaled innovation gain */ - float *norm_gain_code /* o : norm. gain of the codebook excit. */ -); - -void stat_noise_uv_dec( - Decoder_State *st, /* i/o: decoder static memory */ - const float *lsp_new, /* i : end-frame LSP vector */ - const float *lsp_mid, /* i : mid-frame LSP vector */ - float *Aq, /* o : A(z) quantized for the 4 subframes */ - float *exc2, /* i/o: excitation buffer */ - const int16_t uc_two_stage_flag /* 1 : flag undicating two-stage UC */ -); - -void sc_vbr_dec_init_flt( - SC_VBR_DEC_HANDLE hSC_VBR /* i/o: SC-VBR decoder handle */ -); - -void decod_nelp( - Decoder_State *st, /* i/o: decoder static memory */ - float *tmp_noise, /* o : long term temporary noise energy */ - float *pitch_buf, /* o : floating pitch values for each subframe */ - float *exc, /* o : adapt. excitation exc */ - float *exc2, /* o : adapt. excitation/total exc */ - float *voice_factors, /* o : voicing factors */ - float *bwe_exc, /* o : excitation for SWB TBE */ - const int16_t bfi, /* i : bad frame indicator */ - float *gain_buf /* o : floating pitch gain for each subframe */ -); - -void nelp_decoder( - Decoder_State *st, /* i/o: decoder static memory */ - float *exc_nelp, /* o : adapt. excitation/total exc */ - float *exc, /* o : adapt. excitation exc */ - int16_t bfi, /* i : frame error rate */ - const int16_t coder_type, /* i : coding type */ - float *gain_buf /* o : floating pitch gain for each subframe */ -); - -ivas_error decod_ppp( - Decoder_State *st, /* i/o: state structure */ - const float Aq[], /* i : 12k8 Lp coefficient */ - float *pitch_buf, /* i/o: floating pitch values for each subframe */ - float *exc, /* i/o: current non-enhanced excitation */ - float *exc2, /* i/o: current enhanced excitation */ - float *voice_factors, /* o : voicing factors */ - float *bwe_exc, /* o : excitation for SWB TBE */ - float *gain_buf, /* o : floating pitch gain for each subframe */ - const int16_t bfi /* i : BFI flag */ -); - -ivas_error ppp_quarter_decoder( - Decoder_State *st, /* i/o: decoder state structure */ - DTFS_STRUCTURE *CURRCW_Q_DTFS, /* i/o: Current CW DTFS */ - int16_t prevCW_lag, /* i : Previous lag */ - float *lastLgainD, /* i/o: Last gain lowband */ - float *lastHgainD, /* i/o: Last gain highwband */ - float *lasterbD, /* i/o: Last ERB vector */ - int16_t bfi, /* i : FER flag */ - DTFS_STRUCTURE PREV_CW_D /* i : Previous DTFS */ -); - -ivas_error ppp_voiced_decoder( - Decoder_State *st, /* i/o: state structure */ - float *out, /* o : residual signal */ - const float *lpc2, /* i : current frame LPC */ - float *exc, /* i : previous frame excitation */ - float *pitch, /* o : floating pitch values for each subframe */ - const int16_t bfi /* i : BFI flag */ -); - -void AVQ_demuxdec( - Decoder_State *st, /* i/o: decoder state structure */ - int16_t xriq[], /* o : decoded subvectors [0..8*Nsv-1] */ - int16_t *nb_bits, /* i/o: number of allocated bits */ - const int16_t Nsv, /* i : number of subvectors */ - int16_t nq[], /* i/o: AVQ nq index */ - int16_t avq_bit_sFlag, /* i : flag for AVQ bit saving solution*/ - int16_t trgtSvPos /* i : target SV for AVQ bit savings */ -); - - -void Init_post_filter_ivas( - PFSTAT_HANDLE hPFstat /* i : post-filter state memories */ -); - -void nb_post_filt_ivas( - const int16_t L_frame, /* i : frame length */ - const int16_t L_subfr, /* i : sub-frame length */ - PFSTAT_HANDLE hPFstat, /* i/o: Post filter related memories */ - float *lp_noise, /* i/o: long term noise energy */ - const float tmp_noise, /* i : noise energy */ - float *synth, /* i/o: synthesis */ - const float *Aq, /* i : LP filter coefficient */ - const float *pitch_buf, /* i : Floating pitch for each subframe */ - const int16_t coder_type, /* i : coder_type -> deactivated in AUDIO */ - const int16_t BER_detect, /* i : BER detect flag */ - const int16_t disable_hpf /* i : flag to diabled HPF */ -); - -void decod_unvoiced( - Decoder_State *st, /* i/o: decoder static memory */ - const float *Aq, /* i : LP filter coefficient */ - const float Es_pred, /* i : predicted scaled innov. energy */ - const int16_t uc_two_stage_flag, /* i : flag indicating two-stage UC */ - float *tmp_noise, /* o : long term temporary noise energy */ - float *pitch_buf, /* o : floating pitch values for each subframe */ - float *voice_factors, /* o : voicing factors */ - float *exc, /* o : adapt. excitation exc */ - float *exc2, /* o : adapt. excitation/total exc */ - float *bwe_exc, /* i/o: excitation for SWB TBE */ - float *gain_buf /* o : floating pitch gain for each subfram */ -); - -void decod_tran( - Decoder_State *st, /* i/o: decoder static memory */ - const int16_t L_frame, /* i : length of the frame */ - const int16_t tc_subfr, /* i : TC subframe index */ - const float *Aq, /* i : LP filter coefficient */ - const float Es_pred, /* i : predicted scaled innov. energy */ - float *pitch_buf, /* o : floating pitch values for each subframe */ - float *voice_factors, /* o : voicing factors */ - float *exc, /* i/o: adapt. excitation exc */ - float *exc2, /* i/o: adapt. excitation/total exc */ - float *bwe_exc, /* i/o: excitation for SWB TBE */ - int16_t *unbits, /* i/o: number of unused bits */ - const int16_t sharpFlag, /* i : formant sharpening flag */ - float *gain_buf /* o : floating pitch gain for each subframe */ -); - -ivas_error decod_gen_voic( - Decoder_State *st, /* i/o: decoder static memory */ - const int16_t L_frame, /* i : length of the frame */ - const int16_t sharpFlag, /* i : formant sharpening flag */ - const float *Aq, /* i : LP filter coefficient */ - const float Es_pred, /* i : predicted scaled innov. energy */ - const int16_t do_WI, /* i : FEC fast recovery flag */ - float *pitch_buf, /* o : floating pitch for each subframe */ - float *voice_factors, /* o : voicing factors */ - float *exc, /* i/o: adapt. excitation exc */ - float *exc2, /* i/o: adapt. excitation/total exc */ - float *bwe_exc, /* i/o: excitation for SWB TBE */ - int16_t *unbits, /* i/o: number of unused bits */ - float *gain_buf, /* o : floating pitch gain for each subframe */ - const int16_t tdm_Pitch_reuse_flag, /* i : primary channel pitch reuse flag */ - const float tdm_Pri_pitch_buf[] /* i : primary channel pitch buffer */ -); - -void decod_amr_wb( - Decoder_State *st, /* i/o: decoder static memory */ - const float *Aq, /* i : LP filter coefficients */ - float *pitch_buf, /* o : floating pitch values for each subframe */ - float *exc, /* i/o: adapt. excitation exc */ - float *exc2, /* i/o: adapt. excitation/total exc */ - int16_t hf_gain[NB_SUBFR], /* o : decoded HF gain */ - float *voice_factors, /* o : voicing factors */ - float *gain_buf /* o : floating pitch gain for each subframe */ -); - -ivas_error init_decoder( - Decoder_State *st, /* o : Decoder static variables structure */ - const int16_t idchan, /* i : channel ID */ - const MC_MODE mc_mode /* i : MC mode */ -); - -void destroy_cldfb_decoder_flt( - Decoder_State *st /* o : Decoder static variables structure */ -); - -void HQ_core_dec_init_flt( - HQ_DEC_HANDLE hHQ_core /* i/o: HQ core data handle */ -); - -void HQ_nbfec_init_flt( - HQ_NBFEC_HANDLE hHQ_nbfec /* i/o: HQ NB FEC data handle */ -); - -ivas_error evs_dec( - Decoder_State *st, /* i/o: Decoder state structure */ - float mem_hp20_out[L_HP20_MEM], /* i/o: HP filter memory for synthesis */ - float *output, /* o : output synthesis signal */ - FRAME_MODE frameMode /* i : Decoder frame mode */ -); - -void get_next_frame_parameters( - Decoder_State *st /* i/o: Decoder state structure */ -); - -ivas_error amr_wb_dec( - Decoder_State *st, /* i/o: decoder state structure */ - float mem_hp20_out[L_HP20_MEM], /* i/o: HP filter memory for synthesis */ - float *output /* o : synthesis output */ -); - -void transf_cdbk_dec( - Decoder_State *st, /* i/o: decoder state structure */ - const int16_t harm_flag_acelp, /* i : harmonic flag for higher rates ACELP */ - const int16_t i_subfr, /* i : subframe index */ - const float Es_pred, /* i : predicited scaled innovation energy */ - const float gain_code, /* i : innovative excitation gain */ - float *gain_preQ, /* o : prequantizer excitation gain */ - float *norm_gain_preQ, /* o : normalized prequantizer excitation gain */ - float code_preQ[], /* o : prequantizer excitation */ - int16_t *unbits /* o : number of AVQ unused bits */ -); - -/*! r: decoded gain */ -float gain_dequant( - int16_t index, /* i : quantization index */ - const float min_val, /* i : value of lower limit */ - const float max_val, /* i : value of upper limit */ - const int16_t bits /* i : number of bits to dequantize */ -); - -void hq_core_enc( - Encoder_State *st, /* i/o: encoder state structure */ - const float *audio, /* i : input audio signal */ - const int16_t input_frame, /* i : frame length */ - const int16_t hq_core_type, /* i : HQ core type */ - const int16_t Voicing_flag, /* i : Voicing flag for FER method selection */ - const int16_t vad_hover_flag /* i : VAD hangover flag */ -); - -int16_t detect_transient( - Encoder_State *st, /* i/o: encoder state structure */ - const float *in, /* i : input signal */ - const int16_t L /* i : length */ -); - -void wtda( - const float *new_audio, /* i : input audio */ - float *wtda_audio, /* o : windowed audio */ - float *old_wtda, /* i/o: windowed audio from previous frame */ - const int16_t left_mode, /* i : window overlap of previous frame (0: full, 2: none, or 3: half) */ - const int16_t right_mode, /* i : window overlap of current frame (0: full, 2: none, or 3: half) */ - const int16_t L /* i : length */ -); - -void wtda_ext( - const float *new_audio, /* i : input audio */ - float *wtda_audio, /* o : windowed audio */ - const int16_t left_mode, /* i : window overlap of previous frame (0: full, 2: none, or 3: half) */ - const int16_t right_mode, /* i : window overlap of current frame (0: full, 2: none, or 3: half) */ - const int16_t L, /* i : length */ - const uint16_t kernel_type /* i : transform kernel type (0 - 3) */ -); - -void tcx_get_windows_mode1_flt( - const int16_t left_mode, /* i : overlap mode of left window half */ - const int16_t right_mode, /* i : overlap mode of right window half */ - float *left_win, /* o : left overlap window */ - float *right_win, /* o : right overlap window */ - float *left_win_int, /* o : left overlap window */ - float *right_win_int, /* o : right overlap window */ - const int16_t L /* i : length */ -); - -void direct_transform( - const float *in32, /* i : input signal */ - float *out32, /* o : output transformation */ - const int16_t is_transient, /* i : transient flag */ - const int16_t L, /* i : length */ - const int16_t element_mode /* i : IVAS element mode */ -); - - -void interleave_spectrum( - float *coefs, /* i/o: input and output coefficients */ - const int16_t length /* i : length of spectrum */ -); - -void hq_hr_enc( - Encoder_State *st, /* i/o: encoder state structure */ - float *coefs, /* i/o: transform-domain coefficients */ - const int16_t length, /* i : length of spectrum */ - int16_t *num_bits, /* i/o: number of available bits */ - const int16_t is_transient, /* i : transient flag */ - const int16_t vad_hover_flag /* i : VAD hangover flag */ -); - -void huff_dec( - Decoder_State *st, /* i/o: decoder state structure */ - const int16_t N, /* i : Number of codewords to decode */ - const int16_t buffer_len, /* i : Number of bits to read */ - const int16_t num_lengths, /* i : Number of different huffman codeword lengths */ - const int16_t *thres, /* i : Threshold of first codeword of each length */ - const int16_t *offset, /* i : Offset for first codeword */ - const int16_t *huff_tab, /* i : Huffman table order by codeword lengths */ - int16_t *index /* o : Decoded index */ -); - -void reordernorm( - const int16_t *ynrm, /* i : quantization indices for norms */ - const int16_t *normqlg2, /* i : quantized norms */ - int16_t *idxbuf, /* o : reordered quantization indices */ - int16_t *normbuf, /* o : reordered quantized norms */ - const int16_t nb_sfm /* i : number of bands */ -); - -void diffcod( - const int16_t N, /* i : number of sub-vectors */ - int16_t *y, /* i/o: indices of quantized norms */ - int16_t *difidx /* o : differential code */ -); - -void diffcod_lrmdct( - const int16_t N, /* i : number of sub-vectors */ - const int16_t be_ref, /* i : band energy reference */ - int16_t *y, /* i/o: indices of quantized norms */ - int16_t *difidx, /* o : differential code */ - const int16_t is_transient /* i : transient flag */ -); - -void bitallocsum( - int16_t *R, /* i : bit-allocation vector */ - const int16_t nb_sfm, /* i : number of sub-vectors */ - int16_t *sum, /* o : total number of bits allocated */ - int16_t *Rsubband, /* o : rate per subband (Q3) */ - const int16_t num_bits, /* i : number of bits */ - const int16_t length, /* i : length of spectrum */ - const int16_t *sfmsize /* i : Length of bands */ -); -/*! r: BWE class */ -int16_t swb_bwe_gain_deq_flt( - Decoder_State *st, /* i/o: decoder state structure */ - const int16_t core, /* i : core */ - float *SWB_tenv, /* o : time-domain BWE envelope */ - float *SWB_fenv, /* o : frequency-domain BWE envelope */ - const int16_t hr_flag, /* i : high rate flag */ - const int16_t hqswb_clas /* i : HQ BWE class */ -); - -void save_old_syn( - const int16_t L_frame, /* i : frame length */ - const float syn[], /* i : ACELP synthesis */ - float old_syn[], /* o : old synthesis buffer */ - float old_syn_12k8_16k[], /* i/o: old synthesis buffer */ - const float preemph_fac, /* i : preemphasis factor */ - float *mem_deemph /* i/o: deemphasis filter memory */ -); - -void hq_generic_hf_decoding( - const int16_t HQ_mode, /* i : HQ mode */ - float *coeff_out1, /* i/o: BWE input & temporary buffer */ - const float *hq_generic_fenv, /* i : SWB frequency envelopes */ - float *coeff_out, /* o : SWB signal in MDCT domain */ - const int16_t hq_generic_offset, /* i : frequency offset for representing hq swb bwe*/ - int16_t *prev_L_swb_norm, /* i/o: last normalize length */ - const int16_t hq_swb_bwe_exc_clas, /* i : bwe excitation class */ - const int16_t *R ); - -void hq_core_dec( - Decoder_State *st, /* i/o: decoder state structure */ - float out[], /* o : output synthesis */ - const int16_t output_frame, /* i : output frame length */ - const int16_t hq_core_type, /* i : HQ core type */ - const int16_t core_switching_flag, /* i : ACELP->HQ switching frame flag */ - float *output /* o : LB synthesis in case of ACELP-HQ switch */ -); - -void IMDCT( - float *x, - float *old_syn_overl, - float *syn_Overl_TDAC, - float *xn_buf, - const float *tcx_aldo_window_1_trunc, - const float *tcx_aldo_window_2, - const float *tcx_mdct_window_half, - const float *tcx_mdct_window_minimum, - const float *tcx_mdct_window_trans, - const int16_t tcx_mdct_window_half_length, - const int16_t tcx_mdct_window_min_length, - int16_t index, - const uint16_t kernel_type, /* i : TCX transform kernel type */ - const int16_t left_rect, - const int16_t tcx_offset, - const int16_t overlap, - const int16_t L_frame, - const int16_t L_frameTCX, - const int16_t L_spec_TCX5, - const int16_t L_frame_glob, - const int16_t frame_cnt, - const int16_t bfi, - float *old_out, - const int16_t FB_flag, - Decoder_State *st, - const int16_t fullband, - float *acelp_zir ); - -void hq_hr_dec( - Decoder_State *st, /* i/o: decoder state structure */ - float *t_audio_q, /* o : transform-domain coefficients */ - const int16_t length, /* i : frame length */ - const int16_t num_bits, /* i : number of available bits */ - int16_t *ynrm, /* o : norm quantization index vector */ - int16_t *is_transient, /* o : transient flag */ - int16_t *hqswb_clas, /* o : HQ SWB class */ - float *SWB_fenv, /* o : SWB frequency envelopes */ - const int16_t core_switching_flag /* i : Core switching flag */ - -); - -void hdecnrm_context( - Decoder_State *st, /* i/o: decoder state structure */ - const int16_t N, /* i : number of norms */ - int16_t *index, /* o : indices of quantized norms */ - int16_t *n_length /* o : decoded stream length */ -); - -void hdecnrm_tran( - Decoder_State *st, /* i/o: decoder state structure */ - const int16_t N, /* i : number of norms */ - int16_t *index /* o : indices of quantized norms */ -); - -void hdecnrm_resize( - Decoder_State *st, /* i/o: decoder state structure */ - const int16_t N, /* i : number of SFMs */ - int16_t *index /* o : norm quantization index vector */ -); - -void hdecnrm( - Decoder_State *st, /* i/o: decoder state structure */ - const int16_t N, /* i : number of norms */ - int16_t *index /* o : indices of quantized norms */ -); - -/*! r: index of last band */ -int16_t find_last_band( - const int16_t *bitalloc, /* i : bit allocation */ - const int16_t nb_sfm /* i : number of possibly coded bands */ -); - -void fill_spectrum( - float *coeff, /* i/o: normalized MLT spectrum / nf spectrum */ - int16_t *R, /* i : number of pulses per band */ - const int16_t is_transient, /* i : transient flag */ - int16_t norm[], /* i : quantization indices for norms */ - const float *hq_generic_fenv, /* i : HQ GENERIC envelope */ - const int16_t hq_generic_offset, /* i : HQ GENERIC offset */ - const int16_t nf_idx, /* i : noise fill index */ - const int16_t length, /* i : Length of spectrum (32 or 48 kHz) */ - const float env_stab, /* i : Envelope stability measure [0..1] */ - int16_t *no_att_hangover, /* i/o: Frame counter for attenuation hangover */ - float *energy_lt, /* i/o: Long-term energy measure for transient detection */ - int16_t *bwe_seed, /* i/o: random seed for generating BWE input */ - const int16_t hq_generic_exc_clas, /* i : HF excitation class */ - const int16_t core_sfm, /* i : index of the end band for core */ - int16_t HQ_mode, /* i : HQ mode */ - float noise_level[], /* i : noise level for harmonic modes */ - int32_t core_brate, /* i : target bitrate */ - float prev_noise_level[], /* i/o: noise factor in previous frame */ - int16_t *prev_R, /* i/o: bit allocation info. in previous frame */ - float *prev_coeff_out, /* i/o: decoded spectrum in previous frame */ - const int16_t *peak_idx, /* i : peak positions */ - const int16_t Npeaks, /* i : number of peaks */ - const int16_t *npulses, /* i : Number of assigned pulses per band */ - int16_t prev_is_transient, /* i : previous transient flag */ - float *prev_normq, /* i : previous norms */ - float *prev_env, /* i : previous noise envelopes */ - int16_t prev_bfi, /* i : previous bad frame indicator */ - const int16_t *sfmsize, /* i : Length of bands */ - const int16_t *sfm_start, /* i : Start of bands */ - const int16_t *sfm_end, /* i : End of bands */ - int16_t *prev_L_swb_norm, /* i/o: last normalize length for harmonic mode */ - int16_t prev_hq_mode, /* i : previous HQ mode */ - const int16_t num_sfm, /* i : Number of bands */ - const int16_t num_env_bands, /* i : Number of envelope bands */ - const int16_t element_mode /* i : element mode */ -); - -void de_interleave_spectrum( - float *coefs, /* i/o: input and output coefficients */ - int16_t length /* i : length of spectrum */ -); - -void inverse_transform( - const float *InMDCT, /* i : input MDCT vector */ - float *Out, /* o : output vector */ - const int16_t IsTransient, /* i : transient flag */ - const int16_t L, /* i : output frame length */ - const int16_t L_inner, /* i : length of the transform */ - const int16_t element_mode /* i : IVAS element mode */ -); - -void window_ola( - const float *ImdctOut, /* i : input */ - float *auOut, /* o : output audio */ - float *OldauOut, /* i/o: audio from previous frame */ - const int16_t L, /* i : length */ - const int16_t right_mode, - const int16_t left_mode, /* i : window overlap of current frame (0: full, 2: none, or 3: half) */ - const int16_t use_bfi_win, /* i : use BFI windowing */ - const int16_t oldHqVoicing, /* i : previous HqVoicing */ - float *oldgapsynth /* i : previous gapsynth */ -); - -void window_ola_ext( - const float *ImdstOut, /* i : input */ - float *auOut, /* o : output audio */ - float *OldauOut, /* i/o: audio from previous frame */ - const int16_t L, /* i : length */ - const int16_t right_mode, - const int16_t left_mode, /* i : window overlap of current frame (0: full, 2: none, or 3: half) */ - const uint16_t kernel_type /* i : transform kernel type */ -); - -void map_quant_weight( - const int16_t normqlg2[], /* i : quantized norms */ - int16_t wnorm[], /* o : weighted norm */ - const int16_t is_transient /* i : transient flag */ -); - -void recovernorm( - const int16_t *const idxbuf, /* i : reordered quantization indices */ - int16_t *ynrm, /* o : recovered quantization indices */ - int16_t *normqlg2, /* o : recovered quantized norms */ - const int16_t nb_sfm /* i : number of subbands */ -); - -void reordvct( - int16_t *y, /* i/o: vector to rearrange */ - const int16_t N, /* i : dimensions */ - int16_t *idx /* o : reordered vector index */ -); - -void bitalloc( - int16_t *y, /* i : reordered norm of sub-vectors */ - int16_t *idx, /* i : reordered sub-vector indices */ - int16_t sum, /* i : number of available bits */ - int16_t N, /* i : number of norms */ - int16_t K, /* i : maximum number of bits per dimension */ - int16_t *r, /* o : bit-allacation vector */ - const int16_t *sfmsize, /* i : Length of bands */ - const int16_t hqswb_clas /* i : signal classification flag */ -); - -/*! r: Integer (truncated) number of allocated bits */ -int16_t BitAllocF( - int16_t *y, /* i : norm of sub-vectors */ - int32_t bit_rate, /* i : bitrate */ - int16_t B, /* i : number of available bits */ - int16_t N, /* i : number of sub-vectors */ - int16_t *R, /* o : bit-allocation indicator */ - int16_t *Rsubband, /* o : sub-band bit-allocation vector (Q3) */ - const int16_t hqswb_clas, /* i : hq swb class */ - const int16_t num_env_bands /* i : Number sub bands to be encoded for HQ_SWB_BWE */ -); - -/*! r: Integer (truncated) number of allocated bits */ -int16_t BitAllocWB( - int16_t *y, /* i : norm of sub-vectors */ - int16_t B, /* i : number of available bits */ - int16_t N, /* i : number of sub-vectors */ - int16_t *R, /* o : bit-allocation indicator */ - int16_t *Rsubband ); /* o : sub-band bit-allocation vector (Q3) */ - -/*! r: Number of low frequency bands */ -int16_t hvq_pvq_bitalloc( - int16_t num_bits, /* i/o: Number of available bits (including gain bits) */ - const int32_t core_brate, /* i : bitrate */ - const int16_t bwidth, /* i : Encoded bandwidth */ - const int16_t *ynrm, /* i : Envelope coefficients */ - const int32_t manE_peak, /* i : Peak energy mantissa */ - const int16_t expE_peak, /* i : Peak energy exponent */ - int16_t *Rk, /* o : bit allocation for concatenated vector */ - int16_t *R, /* i/o: Global bit allocation */ - int16_t *sel_bands, /* o : Selected bands for encoding */ - int16_t *n_sel_bands /* o : No. of selected bands for encoding */ -); - -void floating_point_add_float( - int32_t *mx, /* i/o: mantissa of the addend Q31 */ - int16_t *ex, /* i/o: exponent of the addend Q0 */ - const int32_t my, /* i : mantissa of the adder Q31 */ - const int16_t ey /* i : exponent of the adder Q0 */ -); - -/*! r: Number of bits needed */ -int16_t rc_get_bits2( - const int16_t N, /* i : Number of bits currently used */ - const uint32_t range /* i : Range of range coder */ -); - -void rc_enc_init( - PVQ_ENC_HANDLE hPVQ, /* i/o: PVQ encoder handle */ - int16_t tot_bits /* i : Total bit budget */ -); - -void rc_encode( - BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ - PVQ_ENC_HANDLE hPVQ, /* i/o: PVQ encoder handle */ - const uint32_t cum_freq, /* i : Cumulative frequency up to symbol */ - const uint32_t sym_freq, /* i : Symbol probability */ - const uint32_t tot /* i : Total cumulative frequency */ -); - -void rc_enc_finish( - BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ - PVQ_ENC_HANDLE hPVQ /* i/o: PVQ encoder handle */ -); - -void rc_enc_bits( - BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ - PVQ_ENC_HANDLE hPVQ, /* i/o: PVQ encoder handle */ - const uint32_t value, /* i : Value to encode */ - const int16_t bits /* i : Number of bits used */ -); - -void rc_enc_uniform( - BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ - PVQ_ENC_HANDLE hPVQ, /* i/o: PVQ encoder handle */ - uint32_t value, /* i : Value to encode */ - uint32_t tot /* i : Maximum value */ -); - -void rc_dec_init( - Decoder_State *st, /* i/o: Decoder State */ - PVQ_DEC_HANDLE hPVQ, /* i/o: PVQ decoder handle */ - int16_t tot_bits /* i : Total bit budget */ -); - -/*! r: Decoded value */ -uint32_t rc_decode( - int16_t *BER_detect, /* o : Bit error detection flag */ - PVQ_DEC_HANDLE hPVQ, /* i/o: PVQ decoder handle */ - uint32_t tot /* i : Total cumulative frequency */ -); - -void rc_dec_update( - Decoder_State *st, /* i/o: Decoder State */ - PVQ_DEC_HANDLE hPVQ, /* i/o: PVQ decoder handle */ - const uint32_t cum_freq, /* i : Cumulative frequency */ - const uint32_t sym_freq /* i : Symbol frequency */ -); - -/*! r: Decoded value */ -uint32_t rc_dec_bits( - Decoder_State *st, /* i/o: Decoder State */ - PVQ_DEC_HANDLE hPVQ, /* i/o: PVQ decoder handle */ - const int16_t bits /* i : Number of bits */ -); - -/*! r: Decoded value */ -uint32_t rc_dec_uniform( - Decoder_State *st, /* i/o: Decoder State */ - PVQ_DEC_HANDLE hPVQ, /* i/o: PVQ decoder handle */ - const uint32_t tot /* i : Maximum value */ -); - -void rc_dec_finish( - Decoder_State *st, /* i/o: decoder state structure */ - PVQ_DEC_HANDLE hPVQ /* i/o: PVQ decoder handle */ -); - -/*! r: number of bits encoded */ -int16_t pvq_core_enc( - BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ - float coefs_norm[], /* i/o: normalized coefficients to encode */ - float coefs_quant[], /* o : quantized coefficients */ - const int16_t bits_tot, /* i : total number of bits */ - const int16_t nb_sfm, /* i : number of bands */ - const int16_t *sfm_start, /* i : Subband start coefficient */ - const int16_t *sfm_end, /* i : Subband end coefficient */ - const int16_t *sfmsize, /* i : subband width */ - int16_t *R, /* i/o: Bit allocation/Adjusted bit alloc. (Q3) */ - int16_t *Rs, /* i/o: Integer bit allocation */ - int16_t *npulses, /* o : number of pulses */ - int16_t *maxpulse, /* i : maximum pulse per band */ - const int16_t core /* i : number of bands */ -); - -/*! r: number of bits decoded */ -int16_t pvq_core_dec( - Decoder_State *st, /* i/o: Decoder state */ - const int16_t *sfm_start, /* i : indices of first coeffs in the bands */ - const int16_t *sfm_end, /* i : indices of last coeffs in the bands */ - const int16_t *sfmsize, /* i : band sizes */ - float coefs_quant[], /* o : output MDCT */ - const int16_t bits_tot, /* i : bit budget */ - const int16_t nb_sfm, /* i : number of bands */ - int16_t *R, /* i/o: Bit allocation/Adjusted bit alloc.(Q3) */ - int16_t *Rs, /* i/o: Integer bit allocation */ - int16_t *npulses, /* o : number of pulses per band */ - int16_t *maxpulse, /* o : maximum pulse per band */ - const int16_t core /* i : core */ -); - -void pvq_encode( - BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ - PVQ_ENC_HANDLE hPVQ, /* i/o: PVQ encoder handle */ - const float *x, /* i : vector to quantize */ - int16_t *y, /* o : quantized vector (non-scaled integer)*/ - float *xq, /* o : quantized vector (scaled float) */ - const int16_t pulses, /* i : number of allocated pulses */ - const int16_t N, /* i : Length of vector */ - const float gain /* i : Gain */ -); - -void pvq_decode( - Decoder_State *st, /* i/o: Decoder State */ - PVQ_DEC_HANDLE hPVQ, /* i/o: PVQ decoder handle */ - float *xq, /* o : decoded vector (scaled float) */ - int16_t *y, /* o : decoded vector (non-scaled short)*/ - const int16_t K, /* i : number of allocated pulses */ - const int16_t N, /* i : Length of vector */ - const float gain /* i : Gain */ -); - -void rangeCoderFinalizationFBits( - const int16_t Brc, /* i : Current number of decoded bits */ - const uint32_t INTrc, /* i : Range coder state */ - int16_t *FBits /* i : Fractional finalization bits */ -); - -void bandBitsAdjustment( - const int16_t Brc, /* i : Current number of read quanta in range coder */ - const uint32_t INTrc, /* i : Range coder state */ - const int16_t Bavail, /* i : Available number of quanta */ - const int16_t Nbands, /* i : Number of bands */ - const int16_t D, /* i : Remaining number of bands to encode */ - const int16_t L, /* i : Size of current band */ - const int16_t Bband, /* i : Quanta allocation for current band */ - const int16_t Breserv, /* i : Quanta reservoir */ - int16_t *Bband_adj, /* o : Actual used number of quanta */ - int16_t *Brem, /* o : Quanta remaining */ - int16_t *Breservplus /* o : Quanta pool size */ -); - -void conservativeL1Norm( - const int16_t L, /* i : Length of vector segment */ - const int16_t Qvec, /* i : Assigned number of quanta */ - const int16_t Fcons, /* i : Conservative rounding flag */ - const int16_t Qavail, /* i : Input quanta remaining */ - const int16_t Qreserv, /* i : Input quanta in reservoir */ - const int16_t Dspec, /* i : assigned diracs from bitalloc */ - int16_t *Dvec, /* o : actual number of diracs */ - int16_t *Qspare, /* o : Output quanta remaining */ - int16_t *Qreservplus, /* o : Output quanta in reservoir */ - int16_t *Dspecplus /* o : Output number of diracs */ -); - -void NearOppSplitAdjustment( - const int16_t qband, /* i : quanta for current band */ - const int16_t qzero, /* i : range coder finalization quanta */ - const int16_t Qac, /* i : range coder current quanta */ - const uint32_t INTac, /* i : range coder state */ - const int16_t qglobal, /* i : quanta input */ - const int16_t FlagCons, /* i : conservative rounding flag */ - const int16_t Np, /* i : number of parts */ - const int16_t Nhead, /* i : first part */ - const int16_t Ntail, /* i : remaining parts */ - const int16_t Nnear, /* i : length of near component */ - const int16_t Nopp, /* i : length of opposite component */ - int16_t oppRQ3, /* i : ratio */ - int16_t *qnear, /* o : quantized near */ - int16_t *qopp, /* o : quantized opposite */ - int16_t *qglobalupd /* o : quanta remaining */ -); - -/*! r: Approximate integer division for positive input */ -int32_t intLimCDivPos( - const int32_t NUM, /* i : numerator */ - const int16_t DEN /* i : denominator */ -); - -/*! r: Approximate integer division */ -int16_t shrtCDivSignedApprox_flt( - const int16_t num, /* i : numerator */ - const int16_t den /* i : denominator */ -); - -void QuantaPerDsDirac( - const int16_t td, /* i : Length of vector segment */ - const int16_t dsDiracIndex, /* i : Quanta table index */ - const uint8_t *const *dimFrQuanta, /* i : Quanta lookup table */ - int16_t *Quanta /* i : Quanta */ -); - -void obtainEnergyQuantizerDensity( - const int16_t L_in, /* i : left vector energy */ - const int16_t R_in, /* i : right vector energy */ - int16_t *Density /* o : quantizer density */ -); - -void densityAngle2RmsProjDec( - const int16_t D, /* i : density */ - const int16_t indexphi, /* i : decoded index from AR dec */ - int16_t *oppQ15, /* o : opposite */ - int16_t *nearQ15, /* o : near */ - int16_t *oppRatioQ3 /* o : ratio */ -); - -void densityAngle2RmsProjEnc( - const int16_t D, /* i : density */ - const int16_t phiQ14uq, /* i : angle */ - int16_t *indexphi, /* o : index */ - int16_t *oppQ15, /* o : opposite */ - int16_t *nearQ15, /* o : near */ - int16_t *oppRatioQ3 /* o : ratio */ -); - -void env_adj( - const int16_t *pulses, /* i : number of pulses per band */ - const int16_t length, /* i : length of spectrum */ - const int16_t last_sfm, /* i : Index of last band */ - float *adj, /* o : Adjustment factors for the envelope */ - const float env_stab, /* i : Envelope stability parameter */ - const int16_t *sfmsize /* i : Length of bands */ -); - -float env_stability( - const int16_t *ynrm, /* i : Norm vector for current frame */ - const int16_t nb_sfm, /* i : Number of sub-bands */ - int16_t *mem_norm, /* i/o: Norm vector memory from past frame */ - int16_t *mem_env_delta, /* i/o: Envelope stability memory for smoothing*/ - const int16_t core_switching_flag /* i : Core switching flag */ -); - -/*! r: New speech/music state */ -float env_stab_smo( - float env_stab, /* i : env_stab value */ - float *env_stab_state_p, /* i/o: env_stab state probabilities */ - int16_t *ho_cnt /* i/o: hangover counter for speech state */ -); -void core_switching_post_enc( - Encoder_State *st, /* i/o: encoder state structure */ - // const float *old_inp_12k8, /* i : old input signal @12.8kHz */ - float *old_inp_12k8, /* i : old input signal @12.8kHz */ - // const float *old_inp_16k, /* i : old input signal @16kHz */ - float *old_inp_16k, /* i : old input signal @16kHz */ - // const float A[] /* i : unquant. LP filter coefs. */ - Word16 A_fx[], /* i : unquant. LP filter coefs. */ - Word16 Q_new ); -ivas_error core_switching_post_dec( - Decoder_State *st, /* i/o: decoder state structure */ - float *synth, /* i/o: output synthesis */ - float *output, /* i/o: LB synth/upsampled LB synth */ - float output_mem[], /* i : OLA memory from last TCX/HQ frame */ - const IVAS_FORMAT ivas_format, /* i : IVAS format */ - const int16_t use_cldfb_for_dft, /* i : flag to use of CLDFB for DFT Stereo */ - const int16_t output_frame, /* i : frame length */ - const int16_t core_switching_flag, /* i : ACELP->HQ switching frame flag */ - const int16_t sba_dirac_stereo_flag, /* i : signal stereo output for SBA DirAC */ - const int16_t nchan_out, /* i : number of output channels */ - const int16_t last_element_mode /* i : element mode of previous frame */ -); - -ivas_error core_switching_pre_dec( - Decoder_State *st, /* i/o: decoder state structure */ - const int16_t output_frame, /* i : frame length */ - const int32_t last_core_brate_st0, /* i : channel 0 last core bitrate */ - const int16_t nchan_out, /* i : number of output channels */ - const int16_t last_element_mode, /* i : last_element_mode */ - const int32_t last_element_brate /* i : last element bitrate */ -); - -void bandwidth_switching_detect( - Decoder_State *st /* i/o: decoder state structure */ -); - -void bw_switching_pre_proc( - Decoder_State *st, /* i/o: decoder state structure */ - const float *old_syn_12k8_16k, /* i : ACELP core synthesis @ 12.8kHz or 16kHz */ - const int32_t last_element_brate, /* i : last element bitrate */ - const int16_t nchan_out /* i : number of output channels */ -); - -void updt_bw_switching( - Decoder_State *st, /* i/o: decoder state structure */ - const float *synth /* i : float synthesis signal */ -); - -void swb_tbe_reset( - float mem_csfilt[], - float mem_genSHBexc_filt_down_shb[], - float state_lpc_syn[], - float syn_overlap[], - float state_syn_shbexc[], - float *tbe_demph, - float *tbe_premph, - float mem_stp_swb[], - float *gain_prec_swb ); - -void swb_tbe_reset_synth( - float genSHBsynth_Hilbert_Mem[], - float genSHBsynth_state_lsyn_filt_shb_local[] ); - -void find_td_envelope( - const float inp[], - const int16_t len, - const int16_t len_h, - float mem_h[], - float out[] ); - -void fb_tbe_reset_enc( - float elliptic_bpf_2_48k_mem[][4], - float *prev_fb_energy ); - -void fb_tbe_reset_synth( - float fbbwe_hpf_mem[][4], - float *prev_fbbwe_ratio ); - -void wb_tbe_extras_reset( - float mem_genSHBexc_filt_down_wb2[], - float mem_genSHBexc_filt_down_wb3[] ); - -void wb_tbe_extras_reset_synth( - float state_lsyn_filt_shb[], - float state_lsyn_filt_dwn_shb[], - float mem_resamp_HB[] ); - -void tbe_celp_exc_flt( - const int16_t element_mode, /* i : element mode */ - const int16_t idchan, /* i : channel ID */ - float *bwe_exc, /* i/o: BWE excitation */ - const int16_t L_frame, /* i : frame length */ - const int16_t L_subfr, /* i : subframe length */ - const int16_t i_subfr, /* i : subframe index */ - const int16_t T0, /* i : integer pitch lag */ - const int16_t T0_frac, /* i : fraction of lag */ - float *error, /* i/o: error */ - const int16_t tdm_LRTD_flag /* i : LRTD stereo mode flag */ -); - -void prep_tbe_exc( - const int16_t L_frame, /* i : length of the frame */ - const int16_t L_subfr, /* i : subframe length */ - const int16_t i_subfr, /* i : subframe index */ - const float gain_pit, /* i : Pitch gain */ - const float gain_code, /* i : algebraic codebook gain */ - const float code[], /* i : algebraic excitation */ - const float voice_fac, /* i : voicing factor */ - float *voice_factors, /* o : TBE voicing factor */ - float bwe_exc[], /* i/o: excitation for TBE */ - const float gain_preQ, /* i : prequantizer excitation gain */ - const float code_preQ[], /* i : prequantizer excitation */ - const int16_t T0, /* i : integer pitch variables */ - const int16_t coder_type, /* i : coding type */ - const int32_t core_brate, /* i : core bitrate */ - const int16_t element_mode, /* i : element mode */ - const int16_t idchan, /* i : channel ID */ - const int16_t flag_TD_BWE, /* i : flag indicating whether hTD_BWE exists */ - const int16_t tdm_LRTD_flag /* i : LRTD stereo mode flag */ -); - -void synthesise_fb_high_band( - const float excitation_in[], /* i : full band excitation */ - float output[], /* o : high band speech - 14.0 to 20 kHz */ - const float fb_exc_energy, /* i : full band excitation energy */ - const float ratio_float, /* i : energy ratio */ - const int16_t L_frame, /* i : ACELP frame length */ - const int16_t bfi, /* i : BFI flag */ - float *prev_fbbwe_ratio, /* o : previous frame energy for FEC */ - float bpf_memory[][4] /* i/o: memory for elliptic bpf 48k */ -); - -void elliptic_bpf_48k_generic( - const float input[], /* i : input signal */ - float output[], /* o : output signal */ - float memory[][4], /* i/o: 4 arrays for memory */ - const float full_band_bpf[][5] /* i : filter coefficients b0,b1,b2,a0,a1,a2 */ -); - -void HQ_FEC_processing( - Decoder_State *st, /* i/o: decoder state structure */ - float *t_audio_q, /* o : MDCT coeffs. (for synthesis) */ - int16_t is_transient, /* i : Old flag for transient */ - float ynrm_values[][MAX_PGF], /* i : Old average Norm values for each group of bands */ - float r_p_values[][MAX_ROW], /* i : Computed y-intercept and slope by Regression */ - int16_t num_Sb, /* i : Number of sub-band group */ - int16_t nb_sfm, /* i : Number of sub-band */ - int16_t *Num_bands_p, /* i : Number of coeffs. for each sub-band */ - int16_t output_frame, /* i : Frame size */ - const int16_t *sfm_start, /* i : Start of bands */ - const int16_t *sfm_end /* i : End of bands */ -); - -void HQ_FEC_Mem_update( - Decoder_State *st, /* i/o: decoder state structure */ - const float *t_audio_q, - float *normq, - int16_t *ynrm, - const int16_t *Num_bands_p, - const int16_t is_transient, - const int16_t hqswb_clas, - const int16_t c_switching_flag, - const int16_t nb_sfm, - const int16_t num_Sb, - float *mean_en_high, - const int16_t hq_core_type, /* i : normal or low-rate MDCT(HQ) core */ - const int16_t output_frame /* i : Frame size */ -); - -void time_domain_FEC_HQ( - Decoder_State *st, /* i : Decoder State */ - float *wtda_audio, /* i : input */ - float *out, /* o : output audio */ - const float mean_en_high, /* i : transient flag */ - const int16_t output_frame /* i : Frame size */ -); - -void save_synthesis_hq_fec( - Decoder_State *st, /* i/o: decoder state structure */ - const float *output, /* i : decoded synthesis */ - const int16_t output_frame, /* i : decoded synthesis */ - CPE_DEC_HANDLE hCPE /* i : CPE decoder structure */ -); - -void Next_good_after_burst_erasures( - const float *ImdctOut, /* i : input */ - float *auOut, /* o : output audio */ - float *OldauOut, /* i/o: audio from previous frame */ - const int16_t ol_size /* i : overlap size */ -); - - -void reset_preecho_dec( - HQ_DEC_HANDLE hHQ_core /* i/o: HQ decoder handle */ -); - -void preecho_sb( - const int32_t core_brate, /* i : core bitrate */ - const float wtda_audio[], /* i : imdct signal */ - float *rec_sig, /* i : reconstructed signal, output of the imdct transform */ - const int16_t framelength, /* i : frame length */ - float *memfilt_lb, /* i/o: memory */ - float *mean_prev_hb, /* i/o: memory */ - float *smoothmem, /* i/o: memory */ - float *mean_prev, /* i/o: memory */ - float *mean_prev_nc, /* i/o: memory */ - float *wmold_hb, /* i/o: memory */ - int16_t *prevflag, /* i/o: flag */ - int16_t *pastpre, /* i/o: flag */ - const int16_t bwidth /* i : audio bandwidth */ -); - -void hq2_core_configure( - const int16_t frame_length, /* i : frame length */ - const int16_t num_bits, /* i : number of bits */ - const int16_t is_transient, /* i : transient flag */ - int16_t *bands, - int16_t *length, - int16_t band_width[], - int16_t band_start[], - int16_t band_end[], - Word32 *L_qint, /* o : Q29 */ - Word16 *eref_fx, /* o : Q10 */ - Word16 *bit_alloc_weight_fx, /* o : Q13 */ - int16_t *gqlevs, - int16_t *Ngq, - int16_t *p2a_bands, - float *p2a_th, - float *pd_thresh, - float *ld_slope, - float *ni_coef, - float *ni_pd_th, - int32_t bwe_br ); - -void hq_lr_enc( - Encoder_State *st, /* i/o: encoder state structure */ - float t_audio[], /* i/o: transform-domain coefs. */ - const int16_t inner_frame, /* i : inner frame length */ - int16_t *num_bits, /* i/o: number of available bits */ - const int16_t is_transient /* i : transient flag */ -); - -void hq_lr_dec( - Decoder_State *st, /* i/o: decoder state structure */ - float yout[], /* o : transform-domain output coefs. */ - const int16_t inner_frame, /* i : inner frame length */ - int16_t num_bits, /* i : number of available bits */ - int16_t *is_transient /* o : transient flag */ -); - -void hq2_bit_alloc( - const float band_energy[], /* i : band energy of each subband */ - const int16_t bands, /* i : total number of subbands in a frame */ - Word32 L_Rk[], /* i/o: Bit allocation/Adjusted bit alloc. */ - int16_t *bit_budget, /* i/o: bit bugdet */ - int16_t *p2a_flags, /* i : HF tonal indicator */ - const Word16 weight_fx, /* i : weight (Q13) */ - const int16_t band_width[], /* i : Sub band bandwidth */ - const int16_t num_bits, /* i : available bits */ - const int16_t hqswb_clas, /* i : HQ2 class information */ - const int16_t bwidth, /* i : input bandwidth */ - const int16_t is_transient /* i : indicator HQ_TRANSIENT or not */ -); - -void hq2_noise_inject( - float y2hat[], - const int16_t band_start[], - const int16_t band_end[], - const int16_t band_width[], - float Ep[], - float Rk[], - const int16_t npulses[], - int16_t ni_seed, - const int16_t bands, - const int16_t ni_start_band, - const int16_t bw_low, - const int16_t bw_high, - const float enerL, - const float enerH, - float last_ni_gain[], - float last_env[], - int16_t *last_max_pos_pulse, - int16_t *p2a_flags, - int16_t p2a_bands, - const int16_t hqswb_clas, - const int16_t bwidth, - const int32_t bwe_br ); - -void mdct_spectrum_denorm( - const int32_t inp_vector[], - float y2[], - const int16_t band_start[], - const int16_t band_end[], - const int16_t band_width[], - const float band_energy[], - const int16_t npulses[], - const int16_t bands, - const float ld_slope, - const float pd_thresh ); - -void reverse_transient_frame_energies( - float band_energy[], /* o : band energies */ - const int16_t bands /* i : number of bands */ -); - - -void hvq_dec( - Decoder_State *st, /* i/o: decoder state structure */ - const int16_t num_bits, /* i : Number of available bits */ - const int32_t core_brate, /* i : Core bitrate */ - const int16_t *ynrm, /* i : Envelope coefficients */ - int16_t *R, /* i/o: Bit allocation/updated bit allocation */ - float *noise_level, /* o : Noise level */ - int16_t *peak_idx, /* o : Peak position vector */ - int16_t *Npeaks, /* o : Total number of peaks */ - float *coefsq_norm, /* o : Output vector */ - const int16_t core /* i : Core */ -); - -void hq_configure_bfi( - int16_t *nb_sfm, /* o : Number of sub bands */ - int16_t *num_Sb, /* o : Number of FEC sub bands ? */ - int16_t *num_bands_p, /* o : FEC sub bands */ - const int16_t **sfmsize, /* o : Subband bandwidths */ - const int16_t **sfm_start, /* o : Subband start coefficients */ - const int16_t **sfm_end /* o : Subband end coefficients */ -); - -void swb_bwe_enc_lr( - Encoder_State *st, /* i/o: encoder state structure */ - const float m_core[], /* i : core synthesis (MDCT) */ - const float m_orig[], /* i/o: scaled orig signal (MDCT) */ - float m[], /* o : output, SWB part (MDCT) */ - const int32_t total_brate, /* i : total bitrate for selecting subband pattern */ - int16_t BANDS, - int16_t *band_start, - int16_t *band_end, - float *band_energy, - int16_t *p2a_flags, - const int16_t hqswb_clas, - int16_t lowlength, - int16_t highlength, - int16_t *prev_frm_index, - const int16_t har_bands, - int16_t *prev_frm_hfe2, - int16_t *prev_stab_hfe2, - int16_t band_width[], - const float y2_ni[], - int16_t *ni_seed ); - -void swb_bwe_dec_lr( - Decoder_State *st, /* i/o: decoder state structure */ - const float m_core[], /* i : lowband synthesis */ - float m[], /* o : highband synthesis with lowband zeroed */ - const int32_t total_brate, /* i : total bitrate for selecting subband pattern */ - int16_t BANDS, - int16_t *band_start, - int16_t *band_end, - float *band_energy, - int16_t *p2a_flags, - const int16_t hqswb_clas, - int16_t lowlength, - int16_t highlength, - const int16_t har_bands, - int16_t *prev_frm_hfe2, - int16_t *prev_stab_hfe2, - int16_t band_width[], - const float y2_ni[], - int16_t *ni_seed ); - -int16_t get_usebit_npswb( - const int16_t hqswb_clas ); - -void GetPredictedSignal( - const float *predBuf, /* i : prediction buffer */ - float *outBuf, /* o : output buffer */ - const int16_t lag, /* i : prediction buffer offset */ - const int16_t fLen, /* i : length of loop (output) */ - const float gain /* i : gain to be applied */ -); - -void convert_lagIndices_pls2smp( - int16_t lagIndices_in[], - int16_t nBands_search, - int16_t lagIndices_out[], - const float sspectra[], - const int16_t sbWidth[], - const int16_t fLenLow ); - -void FindNBiggest2_simple( - const float *inBuf, /* i : input buffer (searched) */ - GainItem *g, /* o : N biggest components found */ - const int16_t nIdx, /* i : search length */ - int16_t *n, /* i : number of components searched (N biggest) */ - const int16_t N_NBIGGESTSEARCH ); - -void updat_prev_frm( - float y2[], - float t_audio[], - const int32_t bwe_br, - const int16_t length, - const int16_t inner_frame, - const int16_t bands, - const int16_t bwidth, - const int16_t is_transient, - const int16_t hqswb_clas, - int16_t *prev_hqswb_clas, - int16_t *prev_SWB_peak_pos, - int16_t prev_SWB_peak_pos_tmp[], - int16_t *prev_frm_hfe2, - int16_t *prev_stab_hfe2, - const int16_t bws_cnt ); - -void hf_parinitiz( - const int32_t total_brate, - const int16_t hqswb_clas, - int16_t lowlength, - int16_t highlength, - int16_t wBands[], - const int16_t **subband_search_offset, - const int16_t **subband_offsets, - int16_t *nBands, - int16_t *nBands_search, - int16_t *swb_lowband, - int16_t *swb_highband ); - -float spectrumsmooth_noiseton( - float spectra[], - const float spectra_ni[], - float sspectra[], - float sspectra_diff[], - float sspectra_ni[], - const int16_t fLenLow, - int16_t *ni_seed ); - -void noiseinj_hf( - float xSynth_har[], - const float th_g[], - const float band_energy[], - float *prev_En_sb, - const int16_t p2a_flags[], - const int16_t BANDS, - const int16_t band_start[], - const int16_t band_end[], - const int16_t fLenLow ); - -void noise_extr_corcod( - float spectra[], - const float spectra_ni[], - float sspectra[], - float sspectra_diff[], - float sspectra_ni[], - const int16_t fLenLow, - int16_t prev_hqswb_clas, - float *prev_ni_ratio ); - -void genhf_noise( - float noise_flr[], - float xSynth_har[], - float *predBuf, - int16_t bands, /* i : total number of subbands in a frame */ - int16_t harmonic_band, /* i : Number of LF harmonic frames */ - int16_t har_freq_est2, - int16_t pos_max_hfe2, - int16_t *pul_res, - GainItem pk_sf[], - const int16_t fLenLow, - const int16_t fLenHigh, - const int16_t sbWidth[], - const int16_t lagIndices[], - const int16_t subband_offsets[], - const int16_t subband_search_offset[] ); - -void ton_ene_est( - float xSynth_har[], - float be_tonal[], - float band_energy[], - int16_t band_start[], - int16_t band_end[], - int16_t band_width[], - const int16_t fLenLow, - const int16_t fLenHigh, - int16_t bands, - int16_t har_bands, - float ni_lvl, - GainItem pk_sf[], - int16_t *pul_res ); - -void Gettonl_scalfact( - float *outBuf, /* o : synthesized spectrum */ - const float *codbuf, /* i : core coder */ - const int16_t fLenLow, /* i : lowband length */ - const int16_t fLenHigh, /* i : highband length */ - int16_t harmonic_band, /* i : Number of LF harmonic frames */ - int16_t bands, /* i : total number of subbands in a frame */ - float *band_energy, /* i : band energy of each subband */ - int16_t *band_start, /* i : subband start indices */ - int16_t *band_end, /* i : subband end indices */ - const int16_t p2aflags[], - float be_tonal[], - GainItem *pk_sf, - int16_t *pul_res ); - -void SpectrumSmoothing( - float *inBuf, - float *outBuf, - const int16_t fLen, - const float th_cut ); - -void hq2_bit_alloc_har( - float *y, /* i : band energy of sub-vectors */ - int16_t B, /* i : number of available bits */ - int16_t N, /* i : number of sub-vectors */ - Word32 *L_Rsubband, - int16_t p2a_bands, - int32_t core_brate, /* i : core bitrate */ - int16_t p2a_flags[], - int16_t band_width[] ); - -void GetSynthesizedSpecThinOut( - const float *predBuf, - float *outBuf, - const int16_t nBands, - const int16_t *sbWidth, - const int16_t *lagIndices, - const float *lagGains, - const int16_t predBufLen ); - -void return_bits_normal2( - int16_t *bit_budget, - const int16_t p2a_flags[], - const int16_t bands, - const int16_t bits_lagIndices[] ); - -void GetlagGains( - const float *predBuf, - const float *band_energy, - const int16_t nBands, - const int16_t *sbWidth, - const int16_t *lagIndices, - const int16_t predBufLen, - float *lagGains ); - -void preset_hq2_swb( - const int16_t hqswb_clas, - const int16_t band_end[], - int16_t *har_bands, - int16_t p2a_bands, - const int16_t length, - const int16_t bands, - int16_t *lowlength, - int16_t *highlength, - float m[] ); - -void post_hq2_swb( - const float m[], - const int16_t lowlength, - const int16_t highlength, - const int16_t hqswb_clas, - const int16_t har_bands, - const int16_t bands, - const int16_t p2a_flags[], - const int16_t band_start[], - const int16_t band_end[], - float y2[], - int16_t npulses[] ); - -void har_denorm_pulcnt( - float spectra[], /* i/o: MDCT domain spectrum */ - const int16_t band_start[], /* i : Number subbands/Frame */ - const int16_t band_end[], /* i : Band Start of each SB */ - const float band_energy[], /* i : Band end of each SB */ - const int16_t band_width[], - const int16_t npulses[], - const int16_t har_bands /* i : No. of harmonic bands */ -); - -int16_t har_est( - float spectra[], - const int16_t N, - int16_t *har_freq_est1, - int16_t *har_freq_est2, - int16_t *flag_dis, - int16_t *prev_frm_hfe2, - const int16_t subband_search_offset[], - const int16_t sbWidth[], - int16_t *prev_stab_hfe2 ); - -void spt_shorten_domain_pre( - const int16_t band_start[], - const int16_t band_end[], - const int16_t prev_SWB_peak_pos[], - const int16_t BANDS, - const int32_t bwe_br, - int16_t new_band_start[], - int16_t new_band_end[], - int16_t new_band_width[] ); - -void spt_shorten_domain_band_save( - const int16_t bands, - const int16_t band_start[], - const int16_t band_end[], - const int16_t band_width[], - int16_t org_band_start[], - int16_t org_band_end[], - int16_t org_band_width[] ); - -void spt_shorten_domain_band_restore( - const int16_t bands, - int16_t band_start[], - int16_t band_end[], - int16_t band_width[], - const int16_t org_band_start[], - const int16_t org_band_end[], - const int16_t org_band_width[] ); - -void spt_swb_peakpos_tmp_save( - const float y2[], - const int16_t bands, - const int16_t band_start[], - const int16_t band_end[], - int16_t prev_SWB_peak_pos_tmp[] ); - -void hq_ecu( - const float *prevsynth, /* i : buffer of previously synthesized signal */ - float *ecu_rec, /* o : reconstructed frame in tda domain */ - int16_t *time_offs, /* i/o: Sample offset for consecutive frame losses*/ - float *X_sav, /* i/o: Stored spectrum of prototype frame */ - int16_t *num_p, /* i/o: Number of identified peaks */ - int16_t *plocs, /* i/o: Peak locations */ - float *plocsi, /* i/o: Interpolated peak locations */ - const float env_stab, /* i : Envelope stability parameter */ - int16_t *last_fec, /* i/o: Flag for usage of pitch dependent ECU */ - const int16_t ph_ecu_HqVoicing, /* i : HQ Voicing flag */ - int16_t *ph_ecu_active, /* i : Phase ECU active flag */ - float *gapsynth, /* o : Gap synthesis */ - const int16_t prev_bfi, /* i : indicating burst frame error */ - const int16_t old_is_transient[2], /* i : flags indicating previous transient frames*/ - float *mag_chg_1st, /* i/o: per band magnitude modifier for transients*/ - float Xavg[LGW_MAX], /* i/o: Frequency group average gain to fade to */ - float *beta_mute, /* o : Factor for long-term mute */ - const int16_t output_frame, /* i : frame length */ - Decoder_State *st /* i/o: decoder state structure */ -); - -void peakfinder( - const float *x0, /* i : vector from which the maxima will be found */ - const int16_t len0, /* i : length of input vector */ - int16_t *plocs, /* o : the indicies of the identified peaks in x0 */ - int16_t *cInd, /* o : number of identified peaks */ - const float sel, /* i : The amount above surrounding data for a peak to be identified */ - const int16_t endpoints /* i : Flag to include endpoints in peak search */ -); - -/*! r: interpolated maximum position */ -float imax_pos( - const float *y /* i : Input vector for peak interpolation */ -); - - -void fft3( - const float X[], /* i : input frame */ - float Y[], /* o : DFT of input frame */ - const int16_t n /* i : block length (must be radix 3) */ -); - -void ifft3( - const float X[], /* i : input frame */ - float Y[], /* o : iDFT of input frame */ - const int16_t n /* i : block length (must be radix 3) */ -); - -/*! r: updated estimate of background noise */ -void minimumStatistics( - float *noiseLevelMemory, /* i/o: internal state */ - int16_t *noiseLevelIndex, /* i/o: internal state */ - int16_t *currLevelIndex, /* i/o: internal state (circular buffer) */ - float *noiseEstimate, /* i/o: previous estimate of background noise */ - float *lastFrameLevel, /* i/o: level of the last frame */ - float currentFrameLevel, /* i : level of the current frame */ - const float minLev, /* i : minimum level */ - const int16_t buffSize /* i : buffer size */ -); - -void E_ACELP_toeplitz_mul( - const float R[], - const float c[], - float d[] ); - -void E_ACELP_innovative_codebook( - const float *exc, /* i : pointer to the excitation frame */ - const int16_t T0, /* i : integer pitch lag */ - const int16_t T0_frac, /* i : fraction of lag */ - const int16_t T0_res, /* i : pitch resolution */ - const float pitch_gain, /* i : adaptive codebook gain */ - const float tilt_code, /* i : tilt factor */ - ACELP_config *acelp_cfg, /* i/o: configuration of the ACELP */ - const int16_t i_subfr, /* i : subframe index */ - const float *Aq, /* i : quantized LPC coefficients */ - const float *h1, /* i : impulse response of weighted synthesis filter */ - const float *xn, /* i : Close-loop Pitch search target vector */ - const float *cn, /* i : Innovative codebook search target vector */ - const float *y1, /* i : zero-memory filtered adaptive excitation */ - float *y2, /* o : zero-memory filtered algebraic excitation */ - const int16_t acelpautoc, /* i : autocorrelation mode enabled */ - int16_t **pt_indice, /* i/o: quantization indices pointer */ - float *code, /* o : innovative codebook */ - const int16_t L_frame, /* i : length of the frame */ - const int16_t last_L_frame, /* i : length of the last frame */ - const int32_t total_brate /* i : total bitrate */ -); - -int16_t E_ACELP_code43bit( - const float code[], - uint32_t *ps, - int16_t *p, - uint16_t idxs[] ); -void D_ACELP_indexing_ivas( - float code[], - PulseConfig config, - const int16_t num_tracks, - int16_t prm[], - int16_t *BER_detect ); - -void D_ACELP_decode_43bit( - uint16_t idxs[], - float code[], - int16_t *pulsestrack ); - -void fcb_pulse_track_joint_decode_ivas( - uint16_t *idxs, - const int16_t wordcnt, - uint32_t *index_n, - const int16_t *pulse_num, - const int16_t track_num ); - -void lag_wind_flt( - float r[], /* i/o: autocorrelations */ - const int16_t m, /* i : order of LP filter */ - const int32_t sr_core, /* i : sampling rate */ - const int16_t strength /* i : LAGW_WEAK, LAGW_MEDIUM, or LAGW_STRONG */ -); - -void adapt_lag_wind_fx( - float r[], /* i/o: autocorrelations */ - const int16_t m, /* i : order of LP filter */ - const int16_t Top, /* i : open loop pitch lags from curr. frame (or NULL if n/a) */ - const float Tnc, /* i : open loop pitch gains from curr. frame (NULL if n/a) */ - const int32_t sr_core /* i : core sampling rate */ -); - -void init_coder_ace_plus( - Encoder_State *st, /* i : Encoder state handle */ - const int32_t last_total_brate, /* i : last total bitrate */ - const int16_t MCT_flag /* i : hMCT handle allocated (1) or not (0)*/ -); - -void core_coder_reconfig( - Encoder_State *st, /* i/o: encoder state structure */ - const int32_t last_total_brate /* i : last total bitrate */ -); - -void core_coder_mode_switch( - Encoder_State *st, /* i/o: encoder state structure */ - const int32_t last_total_brate, /* i : last bitrate */ - const int16_t MCT_flag /* i : hMCT handle allocated (1) or not (0)*/ -); - -void enc_acelp_tcx_main( - Encoder_State *st, /* i/o: encoder state structure */ - const float new_samples[], /* i : new samples */ - float Aw[NB_SUBFR16k * ( M + 1 )], /* i : weighted A(z) unquant. for subframes*/ - const float lsp_new[M], /* i : LSPs at the end of the frame */ - const float lsp_mid[M], /* i : LSPs at the middle of the frame */ - float bwe_exc_extended[], /* i/o: bandwidth extended excitation */ - float *voice_factors, /* o : voicing factors */ - float pitch_buf[], /* o : floating pitch for each subframe */ - const int16_t vad_hover_flag /* i : VAD hangover flag */ -); - -void getTCXMode_ivas( - Decoder_State *st, /* i/o: decoder memory state */ - Decoder_State *st0, /* i : bitstream */ - const Word16 MCT_flag /* i : hMCT handle allocated (1) or not (0)*/ -); - -void getTCXWindowing_ivas( - const Word16 core, /* i : current frame mode */ - const Word16 last_core, /* i : last frame mode */ - const Word16 element_mode, /* i : element mode */ - TCX_CONFIG_HANDLE hTcxCfg, /* i/o: TCX configuration handle */ - Decoder_State *st0 /* i : bitstream */ -); - -void getLPCparam_ivas( - Decoder_State *st, /* i/o: decoder memory state */ - int16_t param_lpc[], /* o : LTP parameters */ - Decoder_State *st0, /* i : bitstream */ - const int16_t ch, /* i : channel */ - const int16_t sns_low_br_mode /* i : SNS low-bitrate mode */ -); - -void getTCXparam_ivas( - Decoder_State *st, /* i/o: Decoder State handle */ - Decoder_State *st0, /* i : bitstream */ - CONTEXT_HM_CONFIG hm_cfg, /* i/o: HM config */ - int16_t param[], /* o : decoded parameters */ - const int16_t bits_common, /* i : number of common bits */ - const int16_t start_bit_pos, /* i : position of the start bit */ - const int16_t *no_param_tns, /* i : number of TNS parameters per subframe */ - int16_t p_param[2], /* o : pointer to parameters for next round of bs reading*/ - int16_t nTnsBitsTCX10[2], - const int16_t pre_past_flag ); - -void pitch_pred_linear_fit_flt( - const int16_t nbLostCmpt, /* i : bfi counter */ - const int16_t last_good, /* i : last classification type */ - float *old_pitch_buf, /* i : pitch lag buffer */ - float *old_fpitch, /* i/o: pitch used for initial ACB generation */ - float *T0_out, /* o : estimated close loop pitch */ - const int16_t pit_min, /* i : Minimum pitch lag */ - const int16_t pit_max, /* i : Maximum pitch lag */ - float *mem_pitch_gain, /* i : lag pitch gain [0] is the most recent subfr lag */ - const int16_t limitation, - const int16_t plc_use_future_lag, /* i : number of subframes to predict */ - int16_t *extrapolationFailed, /* o : flag if extrap decides not to change the pitch */ - const int16_t nb_subfr /* i : number of ACELP subframes */ -); - -void get_subframe_pitch_flt( - const int16_t nSubframes, /* i : number of subframes */ - float pitchStart, /* i : starting pitch lag (in subframe -1) */ - float pitchEnd, /* i : ending pitch lag (in subframe nSubframes-1) */ - float *pitchBuf /* o : interpolated pitch lag per subframe */ -); - -void core_encode_openloop( - Encoder_State *st, /* i/o: encoder state structure */ - const float Aw[NB_SUBFR16k * ( M + 1 )], /* i : weighted A(z) unquant. for subframes*/ - const float lsp_new[M], /* i : LSPs at the end of the frame */ - const float lsp_mid[M], /* i : LSPs at the middle of the frame */ - float *pitch_buf, /* i/o: floating pitch values for each subfr*/ - float *voice_factors, /* o : voicing factors */ - float *ptr_bwe_exc, /* o : excitation for SWB TBE */ - const int16_t vad_hover_flag /* i : VAD hangover flag */ -); - -void core_acelp_tcx20_switching( - Encoder_State *st, /* i/o: encoder state structure */ - float non_staX, /* i : unbound non-stationarity for sp/mu clas */ - float *pitch_fr, /* i/o: fraction pitch values */ - float *voicing_fr, /* i/o: fractional voicing values */ - const float currTempFlatness, /* i : flatness */ - const float lsp_mid[M], /* i : LSPs at the middle of the frame */ - const float stab_fac /* i : LP filter stability */ -); - -void core_encode_twodiv( - Encoder_State *st, /* i/o: coder memory state */ - const float new_samples[], /* i : new samples */ - float Aw[NB_SUBFR16k * ( M + 1 )], /* i : weighted A(z) unquant. for subframes*/ - const int16_t vad_hover_flag /* i : VAD hangover flag */ -); - -void core_encode_update( - Encoder_State *st /* i/o: encoder state structure */ -); - -void core_encode_update_cng( - Encoder_State *st, /* i/o: encoder state structure */ - float *timeDomainBuffer, - float *A, - const float Aw[] /* i : weighted A(z) unquant. for subframes*/ -); - -void core_signal_analysis_high_bitrate( - const float *new_samples, - const int16_t T_op[3], /* i : open-loop pitch values for quantiz. */ - float lsp_new[], - float lsp_mid[], - Encoder_State *st, - float *mdst_spectrum[2], - int16_t pTnsSize[], - int16_t pTnsBits[], - int16_t param_core[], - int16_t *ltpBits, - float *windowed_samples, /* i/o: backup of windowed time signal */ - const int16_t L_frame, - const int16_t L_frameTCX, - const int16_t last_element_mode, - const int16_t vad_hover_flag /* i : VAD hangover flag */ -); - -void encode_acelp_gains( - const float *code, - const int16_t gains_mode, - const float mean_ener_code, - const int16_t clip_gain, - ACELP_CbkCorr *g_corr, - float *gain_pit, - float *gain_code, - int16_t **pt_indice, - float *past_gcode, - float *gain_inov, - const int16_t L_subfr, - float *code2, - float *gain_code2, - const int16_t noisy_speech_flag ); - -int16_t gain_enc_gacelp_uv( - const float *code, /* i : algebraic excitation */ - const float *code2, /* i : gaussian excitation */ - const int16_t lcode, /* i : Subframe size */ - const float mean_ener, /* i : quantized mean energy of the frame */ - float *gain_pit, /* o : quantized pitch gain */ - float *gain_code, /* o : quantized codebook gain */ - float *gain_code2, /* o : quantized codebook gain */ - ACELP_CbkCorr *coeff, /* i/o: correlations , -2,, -2 and 2 */ - float *past_gcode, /* i/o: past gain of code */ - float *gain_inov, /* o : unscaled innovation gain */ - const int16_t noisy_speech_flag /* i : noisy speech flag */ -); - -int16_t Mode2_gain_enc_mless( - const float *code, /* i : algebraic excitation */ - const int16_t lcode, /* i : Subframe size */ - float *gain_pit, /* o : quantized pitch gain */ - float *gain_code, /* o : quantized codebook gain */ - ACELP_CbkCorr *coeff, /* i/o: correlations , -2,, -2 and 2 */ - const float mean_ener, /* i : mean_ener defined in open-loop (3 bits) */ - const int16_t clip_gain, /* i : gain pitch clipping flag (1 = clipping) */ - float *past_gcode, /* i/o: past gain of code */ - float *gain_inov, /* o : unscaled innovation gain */ - const int16_t coder_type /* i : type of coder */ -); - -void decode_acelp_gains( - const float *code, - const int16_t gains_mode, - const float mean_ener_code, - float *gain_pit, - float *gain_code, - int16_t **pt_indice, - float *past_gpit, - float *past_gcode, - float *gain_inov, - const int16_t L_subfr, - float *code2, - float *gain_code2 ); - -void gain_dec_gacelp_uv( - int16_t index, /* i/o: Quantization index vector */ - const float *code, /* i : algebraic code excitation */ - const float *code2, /* i : algebraic code excitation */ - const float mean_ener, /* i : mean energy */ - const int16_t lcode, /* i : Subframe size */ - float *gain_pit, /* o : Quantized pitch gain */ - float *gain_code, /* o : Quantized codebook gain */ - float *gain_code2, /* o : Quantized codebook gain */ - float *past_gpit, /* i/o: past gain of pitch */ - float *past_gcode, /* i/o: past energy of code */ - float *gain_inov /* o : unscaled innovation gain */ -); - -void limit_T0_voiced_ivas( - const int16_t nbits, - const int16_t res, - const int16_t T0, /* i : rough pitch estimate around which the search is done */ - const int16_t T0_frac, /* i : pitch estimate fractional part */ - const int16_t T0_res, /* i : pitch resolution */ - int16_t *T0_min, /* o : lower pitch limit */ - int16_t *T0_min_frac, /* o : lower pitch limit */ - int16_t *T0_max, /* o : higher pitch limit */ - int16_t *T0_max_frac, /* o : higher pitch limit */ - const int16_t pit_min, /* i : Minimum pitch lag */ - const int16_t pit_max /* i : Maximum pitch lag */ -); - - -/*! r: floating pitch value */ -float Mode2_pit_decode_flt( - const int16_t coder_type, /* i : coding model */ - const int16_t i_subfr, /* i : subframe index */ - const int16_t L_subfr, /* i : sub-frame length */ - int16_t **pt_indice, /* i/o: quantization indices pointer */ - int16_t *T0, /* o : close loop integer pitch */ - int16_t *T0_frac, /* o : close loop fractional part of the pitch */ - int16_t *T0_res, /* i/o: pitch resolution */ - int16_t *T0_min, /* i/o: lower limit for close-loop search */ - int16_t *T0_min_frac, /* i/o: lower limit for close-loop search */ - int16_t *T0_max, /* i/o: higher limit for close-loop search */ - int16_t *T0_max_frac, /* i/o: higher limit for close-loop search */ - const int16_t pit_min, - const int16_t pit_fr1, - const int16_t pit_fr1b, - const int16_t pit_fr2, - const int16_t pit_max, - const int16_t pit_res_max ); - -void Mode2_abs_pit_dec_flt( - int16_t *T0, /* o : integer pitch lag */ - int16_t *T0_frac, /* o : pitch fraction */ - int16_t *T0_res, /* o : pitch resolution */ - int16_t **pt_indice, /* i/o: pointer to Vector of Q indexes */ - const int16_t pit_min, - const int16_t pit_fr1, - const int16_t pit_fr2, - const int16_t pit_res_max ); - -void Mode2_delta_pit_dec_flt( - int16_t *T0, /* o : integer pitch lag */ - int16_t *T0_frac, /* o : pitch fraction */ - int16_t T0_res, /* i : pitch resolution */ - int16_t *T0_min, /* i : delta search min */ - int16_t *T0_min_frac, /* i : delta search min */ - int16_t **pt_indice /* i/o: pointer to Vector of Q indexes */ -); - -void formant_post_filt_ivas( - PFSTAT_HANDLE hPFstat, /* i/o: Post filter related memories */ - float *synth_in, /* i : 12k8 synthesis */ - const float *Aq, /* i : LP filter coefficient */ - float *synth_out, /* i/o: input signal */ - const int16_t L_frame, /* i : frame length */ - const int16_t L_subfr, /* i : sub-frame length */ - const float lp_noise, /* i : background noise energy */ - const int32_t brate, /* i : bitrate */ - const int16_t off_flag /* i : Off flag */ -); - - -int16_t dlpc_avq( - int16_t *index, /* i : Quantization indices */ - float *LSF_Q, /* o : Quantized LSF vectors */ - const int16_t numlpc, /* i : Number of sets of lpc */ - const int32_t sr_core /* i : internal sampling rate */ -); - -int16_t decode_lpc_avq( - Decoder_State *st, /* i/o: decoder state structure */ - const int16_t numlpc, /* i : Number of sets of lpc */ - int16_t *param_lpc, /* o : lpc parameters */ - const int16_t ch, /* i : channel */ - const int16_t element_mode, /* i : element mode */ - const int16_t sns_low_br_mode /* i : SNS low-bitrate mode */ -); - - -void vlpc_2st_dec_flt( - float *lsfq, /* i/o: i:1st stage o:1st+2nd stage */ - int16_t *indx, /* i : index[] (4 bits per words) */ - const int16_t mode, /* i : 0=abs, >0=rel */ - const int32_t sr_core /* i : internal sampling rate */ -); - -void lsf_weight_2st_flt( - const float *lsfq, - float *w, - const int16_t mode, - const int32_t sr_core ); - -void mdct_window_sine_flt( - float *window, - const int32_t Fs, - const int16_t n, - const int16_t window_type, - const int16_t element_mode ); - -void mdct_window_aldo_flt( - float *window1, - float *window2, - const int16_t n ); - -void AVQ_cod_lpc( - const float nvec[], /* i : vector to quantize */ - int16_t nvecq[], /* o : quantized normalized vector (assuming the bit budget is enough) */ - int16_t *indx, /* o : index[] (4 bits per words) */ - const int16_t Nsv /* i : number of subvectors (lg=Nsv*8) */ -); - -void AVQ_dec_lpc_ivas( - const int16_t indx[], /* i : index[] (4 bits per words) */ - int16_t nvecq[], /* o : vector quantized */ - const int16_t Nsv /* i : number of subvectors (lg=Nsv*8) */ -); - -void vlpc_1st_dec_flt( - const int16_t index, /* i : codebook index */ - float *lsfq, /* i/o: i:prediction o:quantized lsf */ - const int32_t sr_core ); - -void WindowSignal_flt( - TCX_CONFIG_HANDLE hTcxCfg, /* i : configuration of TCX */ - int16_t offset, /* i : left folding point offset relative to the input signal pointer */ - const int16_t left_overlap_mode, /* i : overlap mode of left window half */ - const int16_t right_overlap_mode, /* i : overlap mode of right window half */ - int16_t *left_overlap_length, /* o : TCX window left overlap length */ - int16_t *right_overlap_length, /* o : TCX window right overlap length */ - const float in[], /* i : input signal */ - int16_t *L_frame, /* i/o: frame length */ - float out[], /* o : output windowed signal */ - const int16_t truncate_aldo, /* i : nonzero to truncate long ALDO slope */ - const int16_t fullband /* i : fullband flag */ -); - -void HBAutocorrelation( - TCX_CONFIG_HANDLE hTcxCfg, /* i : configuration of TCX */ - const int16_t left_mode, /* i : overlap mode of left window half */ - const int16_t right_mode, /* i : overlap mode of right window half */ - float speech[], /* i : speech */ - int16_t L_frame_glob, /* i/o: frame length */ - float *r /* o : autocorrelations vector */ -); - -void TNSAnalysis( - TCX_CONFIG_HANDLE hTcxCfg, /* i : configuration of TCX */ - const int16_t L_frame, /* i : frame length */ - int16_t L_spec, /* i : length of the spectrum */ - const int16_t transform_type, /* i : transform type for the frame/subframe - TCX20 | TCX10 | TCX 5 (meaning 2 x TCX 5) */ - const int16_t isAfterACELP, /* i : Flag indicating if the last frame was ACELP. For the second TCX subframe it should be 0 */ - float spectrum[], /* i : MDCT spectrum of the subframe */ - TRAN_DET_HANDLE hTranDet, /* i : handle transient detection */ - const float ltp_gain, /* i : ltp gain */ - STnsData *pTnsData, /* o : TNS data */ - int8_t *pfUseTns, /* o : Flag indicating if TNS is used */ - float *predictionGain /* o : TNS prediction gain */ -); - -void CalculateTnsFilt( - STnsConfig const *pTnsConfig, /* i : TNS Configuration struct */ - const float pSpectrum[], /* i : MDCT spectrum */ - STnsData *pTnsData, /* o : TNS data struct */ - float *predictionGain /* o : TNS prediction gain */ -); - -void ShapeSpectrum( - TCX_CONFIG_HANDLE hTcxCfg, /* i : configuration of TCX */ - const float A[], /* i : quantized coefficients NxAz_q[M+1] */ - float gainlpc[], /* o : MDCT gains for the previous frame */ - const int16_t L_frame_glob, /* i : frame length */ - int16_t L_spec, /* i : length of the spectrum */ - float spectrum[], /* i/o: MDCT spectrum */ - const int8_t fUseTns, /* i : Flag indicating if TNS is used */ - Encoder_State *st, /* i/o: encoder state structure */ - float *scf /* i : scale factors */ -); - -void QuantizeSpectrum( - Encoder_State *st, /* i/o: encoder state structure */ - const float A[], /* i : quantized coefficients NxAz_q[M+1] */ - const Word16 Aqind[], /* i : frame-independent quantized coeffs (M+1) */ - float gainlpc[], /* i : MDCT gains of the previous frame */ - float synth[], /* o : synthesis buffer */ - const int16_t nb_bits, /* i : bit budget */ - const int16_t tnsSize, /* i : number of tns parameters put into prm */ - int16_t prm[], /* o : tcx parameters */ - const int16_t frame_cnt, /* i : frame counter in the super_frame */ - CONTEXT_HM_CONFIG *hm_cfg, /* i : HM configuration */ - const int16_t vad_hover_flag /* i : VAD hangover flag */ -); - -/*! r: index of next coefficient */ -int16_t get_next_coeff_mapped_ivas( - int16_t ii[2], /* i/o: coefficient indexes */ - int32_t *pp, /* o : peak(1)/hole(0) indicator */ - int16_t *idx, /* o : index in unmapped domain */ - CONTEXT_HM_CONFIG *hm_cfg /* i : HM configuration */ -); - - -void ACcontextMapping_encode2_no_mem_s17_LC( - BSTR_ENC_HANDLE hBstr, /* i/o: bitstream handle */ - int16_t *x, - int16_t nt, - int16_t lastnz, - int16_t nbbits, - int16_t resQMaxBits, - CONTEXT_HM_CONFIG *hm_cfg ); - -int16_t ACcontextMapping_decode2_no_mem_s17_LC_ivas( - Decoder_State *st, /* i/o: decoder state */ - int16_t *x, /* o : decoded spectrum */ - int16_t nt, /* i : size of spectrum */ - int16_t nbbits, /* i : bit budget */ - int16_t resQMaxBits, /* i : residual coding maximum bits */ - CONTEXT_HM_CONFIG *hm_cfg /* i : context-based harmonic model configuration */ -); - -int16_t ACcontextMapping_encode2_estimate_no_mem_s17_LC( - const int16_t *x, - const int16_t nt, - int16_t *lastnz, - int16_t *nEncoded, - const int16_t target, - int16_t *stop, - CONTEXT_HM_CONFIG *hm_cfg ); - -void RCcontextMapping_encode2_no_mem_s17_LCS( - BSTR_ENC_HANDLE hBstr, /* i/o: bitstream handle */ - int16_t *x, - const int16_t nt, - int16_t lastnz, - const int16_t nbbits, - const int16_t resQMaxBits, - CONTEXT_HM_CONFIG *hm_cfg ); - -int16_t RCcontextMapping_decode2_no_mem_s17_LCS( - Decoder_State *st, /* i/o: decoder state */ - int16_t *x, /* o : decoded spectrum */ - const int16_t nt, /* i : size of spectrum */ - const int16_t nbbits, /* i : bit budget */ - const int16_t resQMaxBits, /* i : residual coding maximum bits */ - CONTEXT_HM_CONFIG *hm_cfg /* i : context-based harmonic model configuration */ -); - -int16_t RCcontextMapping_encode2_estimate_no_mem_s17_LCS( - int16_t *x, /* Spectral coefficients */ - const int16_t nt, /* L - size of spectrum (no. of spectral coefficients) */ - int16_t *lastnz_out, - int16_t *nEncoded, /* No. of spectral coefficients that can be coded without an overflow occuring */ - const int16_t target, /* Target bits */ - int16_t *stop, - int16_t mode, - CONTEXT_HM_CONFIG *hm_cfg /* context-based harmonic model configuration */ -); - -int16_t RCcontextMapping_encode2_estimate_bandWise_start( - int16_t *x, - const int16_t nt, - const int16_t target, - HANDLE_RC_CONTEXT_MEM hContextMem ); - -int16_t RCcontextMapping_encode2_estimate_bandWise( - int16_t *x, - const int16_t start_line, - const int16_t end_line, - HANDLE_RC_CONTEXT_MEM hContextMem ); - -void tcx_get_windows_flt( - TCX_CONFIG_HANDLE hTcxCfg, /* i : TCX configuration */ - const int16_t left_mode, /* i : overlap mode of left window half */ - const int16_t right_mode, /* i : overlap mode of right window half */ - int16_t *left_overlap, /* o : left overlap length */ - const float **left_win, /* o : left overlap window */ - int16_t *right_overlap, /* o : right overlap length */ - const float **right_win, /* o : right overlap window */ - const int16_t fullband /* i : fullband flag */ -); - -void tcx_windowing_analysis_flt( - const float *signal, /* i : signal vector */ - const int16_t L_frame, /* i : frame length */ - const int16_t left_overlap, /* i : left overlap length */ - const float *left_win, /* i : left overlap window */ - const int16_t right_overlap, /* i : right overlap length */ - const float *right_win, /* i : right overlap window */ - float *output /* o : windowed signal vector */ -); - -void tcx_windowing_synthesis_current_frame_flt( - float *signal, /* i/o: signal vector */ - const float *window, /* i : TCX window vector */ - const float *window_half, /* i : TCX window vector for half-overlap window */ - const float *window_min, /* i : TCX minimum overlap window */ - const int16_t window_length, /* i : TCX window length */ - const int16_t window_half_length, /* i : TCX half window length */ - const int16_t window_min_length, /* i : TCX minimum overlap length */ - const int16_t left_rect, /* i : left part is rectangular */ - const int16_t left_mode, /* i : overlap mode of left window half */ - float *acelp_zir, /* i/o: acelp ZIR */ - const float *old_syn, /* i : old synthesis */ - const float *syn_overl, /* i : overlap synthesis */ - const float *A_zir, - const float *window_trans, /* i : window for transition from ACELP */ - int16_t acelp_zir_len, - const int16_t acelp_mem_len, - const int16_t last_core_bfi, /* i : last mode */ - const int16_t last_is_cng, - const int16_t fullbandScale ); - -void tcx_windowing_synthesis_past_frame_flt( - float *signal, /* i/o: signal vector */ - const float *window, /* i : TCX window vector */ - const float *window_half, /* i : TCX window vector for half-overlap window */ - const float *window_min, /* i : TCX minimum overlap window */ - const int16_t window_length, /* i : TCX window length */ - const int16_t window_half_length, /* i : TCX half window length */ - const int16_t window_min_length, /* i : TCX minimum overlap length */ - const int16_t right_mode /* i : overlap mode (left_mode of current frame) */ -); - -void ProcessIGF( - Encoder_State *st, /* i : Encoder state */ - float *pMDCTSpectrum, /* i : MDCT spectrum */ - const float *pITFMDCTSpectrum, /* i : MDCT spectrum fir ITF */ - float *pPowerSpectrum, /* i : MDCT^2 + MDST^2 spectrum, or estimate */ - const int16_t isTCX20, /* i : flag indicating if the input is TCX20 or TCX10/2xTCX5 */ - const int16_t frameno, /* i : flag indicating index of current subframe */ - const int16_t sp_aud_decision0, /* i : first stage switching decision */ - const int16_t vad_hover_flag /* i : VAD hangover flag */ -); - -void ProcessStereoIGF( - STEREO_MDCT_ENC_DATA_HANDLE hStereoMdct, - Encoder_State *sts[CPE_CHANNELS], /* i : Encoder state */ - int16_t ms_mask[2][MAX_SFB], /* i : bandwise MS mask */ - float *pITFMDCTSpectrum[CPE_CHANNELS][NB_DIV], /* i : MDCT spectrum fir ITF */ - float *pPowerSpectrum[CPE_CHANNELS], /* i/o: MDCT^2 + MDST^2 spectrum, or estimate */ - float *pPowerSpectrumMsInv[CPE_CHANNELS][NB_DIV], /* i : inverse power spectrum */ - float *inv_spectrum[CPE_CHANNELS][NB_DIV], /* i : inverse spectrum */ - const int16_t frameno, /* i : flag indicating index of current subframe*/ - const int16_t sp_aud_decision0, /* i : sp_aud_decision0 */ - const int32_t element_brate, /* i : element bitrate */ - const int16_t mct_on /* i : flag mct block (1) or stereo (0) */ -); - -void AnalyzePowerSpectrum( - Encoder_State *st, /* i/o: encoder states */ - const int16_t L_frame, /* i : frame length */ - const int16_t L_frameTCX, /* i : full band frame length */ - const int16_t left_overlap, /* i : left overlap length */ - const int16_t right_overlap, /* i : right overlap length */ - const float mdctSpectrum[], /* i : MDCT spectrum */ - const float signal[], /* i : windowed signal corresponding to mdctSpectrum */ - float powerSpec[] /* o : Power spectrum */ -); - -void lpc2mdct_flt( - float *lpcCoeffs, - const int16_t lpcOrder, - float mdct_gains[], - const int16_t length, - const int16_t noInverse ); - -void mdct_preShaping( - float x[], - const int16_t lg, - const float gains[] ); - -void mdct_noiseShaping_flt( - float x[], - const int16_t lg, - const float gains[], - const int16_t nBands ); - - -void PsychAdaptLowFreqDeemph_flt( - float x[], - const float lpcGains[], - float lf_deemph_factors[] ); - -void AdaptLowFreqDeemph_flt( - float x[], - int16_t tcx_lpc_shaped_ari, - const float lpcGains[], - const int16_t lg, - float lf_deemph_factors[] ); - - -void tcx_noise_filling_flt( - float *Q, - const int16_t noiseFillSeed, - const int16_t iFirstLine, - const int16_t lowpassLine, - const int16_t nTransWidth, - const int16_t L_frame, - const float tiltCompFactor, - float fac_ns, - Word16 *infoTCXNoise, - const int16_t element_mode /* i : IVAS element mode */ -); - - -void tcx_decoder_memory_update_flt( - Decoder_State *st, /* i/o: decoder memory state */ - const float *xn_buf, /* i : mdct output buffer */ - float *synth, /* i/o: synth */ - const float *A /* i : Quantized LPC coefficients */ -); - - -/*! r: number of bits used (including "bits") */ -int16_t tcx_ari_res_invQ_spec_flt( - float x_Q[], /* i/o: quantized spectrum */ - const int16_t L_frame, /* i : number of lines */ - const int16_t prm[], /* i : bitstream */ - int16_t target_bits, /* i : number of bits available */ - int16_t bits, /* i : number of bits used so far */ - const float deadzone, /* i : quantizer deadzone */ - const float x_fac[] /* i : spectrum post-quantization factors */ -); - - -void ari_copy_states( - Tastat *source, - Tastat *dest ); - - -void ari_start_encoding_14bits( - Tastat *s ); - - -void ari_start_decoding_14bits_ivas( - Decoder_State *st, - Tastat *s ); - -int16_t ari_start_decoding_14bits_prm_ivas( - const int16_t *ptr, - int16_t bp, - Tastat *s ); - -void ari_decode_14bits_s17_ext_ivas( - Decoder_State *st, - uint16_t *res, - Tastat *s, - const uint16_t *cum_freq ); - -void ari_decode_14bits_s27_ext_ivas( - Decoder_State *st, - uint16_t *res, - Tastat *s, - const uint16_t *cum_freq ); - -void ari_decode_14bits_bit_ext_ivas( - Decoder_State *st, - uint16_t *res, - Tastat *s ); - -/*! r: Q15 */ -Word16 expfp_evs_fx( - const Word16 x, /* i : mantissa Q15-e */ - const Word16 x_e /* i : exponent Q0 */ -); - - -void tcx_arith_render_envelope_ivas_fx( - const Word16 A_ind[], /* i : LPC coefficients of signal envelope Q12*/ - const Word16 L_frame, /* i : number of spectral lines Q0*/ - const Word16 L_spec, /* i : length of the coded spectrum Q0*/ - const Word16 preemph_fac, /* i : pre-emphasis factor Q15*/ - const Word16 gamma_w, /* i : A_ind -> weighted envelope factor Q15*/ - const Word16 gamma_uw, /* i : A_ind -> non-weighted envelope factor Q14*/ - Word32 env[] /* o : shaped signal envelope Q16*/ -); - -int16_t ari_encode_14bits_range( - int16_t *ptr, - int16_t bp, - int32_t bits, - Tastat *s, - uint16_t cum_freq_low, - uint16_t cum_freq_high ); - - -int16_t ari_done_cbr_encoding_14bits( - int16_t *ptr, - int16_t bp, - int32_t bits, - Tastat *s ); - - -void tcx_arith_encode_envelope( - float spectrum[], /* i/o: MDCT coefficients */ - int16_t signs[], /* o : signs (spectrum[.]<0) */ - const int16_t L_frame, /* i : frame or MDCT length */ - const int16_t L_spec, /* i : length w/o BW limitation */ - Encoder_State *st, /* i/o: coder state */ - const Word16 A_ind[], /* i : quantised LPC coefficients */ - int16_t target_bits, /* i : number of available bits */ - int16_t prm[], /* o : bitstream parameters */ - const int16_t use_hm, /* i : use HM in current frame? */ - int16_t prm_hm[], /* o : HM parameter area */ - const int16_t tcxltp_pitch, /* i : TCX LTP pitch in FD, -1 if n/a*/ - int16_t *arith_bits, /* o : bits used for ari. coding */ - int16_t *signaling_bits, /* o : bits used for signaling */ - const int16_t low_complexity /* i : low-complexity flag */ -); - -void tcx_arith_decode_envelope( - Decoder_State *st, /* i/o: coder state */ - float q_spectrum[], /* o : quantised MDCT coefficients */ - const int16_t L_frame, /* i : frame or MDCT length */ - int16_t L_spec, /* i : length w/o BW limitation */ - const Word16 A_ind[], /* i : quantised LPC coefficients */ - const int16_t target_bits, /* i : number of available bits */ - const int16_t prm[], /* i : bitstream parameters */ - const int16_t use_hm, /* i : use HM in current frame? */ - const int16_t prm_hm[], /* i : HM parameter area */ - int16_t tcxltp_pitch, /* i : TCX LTP pitch in FD, -1 if n/a*/ - int16_t *arith_bits, /* o : bits used for ari. coding */ - int16_t *signaling_bits, /* o : bits used for signaling */ - const int16_t low_complexity /* i : low-complexity flag */ -); - -void tcx_arith_decode_envelope_ivas_fx( - Decoder_State *st, /* i/o: coder state */ - Word32 q_spectrum[], /* o : quantised MDCT coefficients */ - Word16 *q_spectrum_e, /* o : MDCT exponent */ - const Word16 L_frame, /* i : frame or MDCT length */ - Word16 L_spec, /* i : length w/o BW limitation */ - const Word16 A_ind[], /* i : quantised LPC coefficients */ - const Word16 target_bits, /* i : number of available bits */ - Word16 prm[], /* i : bitstream parameters */ - const Word16 use_hm, /* i : use HM in current frame? */ - const Word16 prm_hm[], /* i : HM parameter area */ - Word16 tcxltp_pitch, /* i : TCX LTP pitch in FD, -1 if n/a*/ - Word16 *arith_bits, /* o : bits used for ari. coding */ - Word16 *signaling_bits, /* o : bits used for signaling */ - const Word16 low_complexity /* i : low-complexity flag */ -); - - -void UnmapIndex_fx( - const Word16 PeriodicityIndex, /* Q0 */ - const Word16 Bandwidth, /* Q0 */ - const Word16 LtpPitchLag, /* Q0 */ - const Word8 SmallerLags, /* Q0 */ - Word16 *FractionalResolution, /* Q0 */ - Word32 *Lag /* Q0 */ -); - -/*! r: PeriodicityIndex */ -int16_t SearchPeriodicityIndex( - const float Mdct[], /* i : Coefficients, Mdct[0..NumCoeffs-1] */ - const float UnfilteredMdct[], /* i : Unfiltered coefficients, UnfilteredMdct[0..NumCoeffs-1] */ - const int16_t NumCoeffs, /* i : Number of coefficients */ - const int16_t shortTargetBits, /* i : Target bit budget (excl. Done flag) */ - const int16_t LtpPitchLag, /* i : TCX-LTP pitch */ - const float LtpGain, /* i : LTP gain */ - float *RelativeScore /* o : Energy concentration factor */ -); - - -int16_t EncodeIndex( - const int16_t Bandwidth, /* o : NB, 1: (S)WB */ - int16_t PeriodicityIndex, - BSTR_ENC_HANDLE hBstr ); - - -Word16 CountIndexBits_fx( - Word16 Bandwidth, /* 0: NB, 1: (S)WB Q0*/ - Word16 PeriodicityIndex /* Q0 */ -); - -int16_t DecodeIndex( - Decoder_State *st, - const int16_t Bandwidth, /* o : NB, 1: (S)WB */ - int16_t *PeriodicityIndex ); - -#define GET_ADJ( T, L ) GET_ADJ2( T, L, *FractionalResolution ) -#define GET_ADJ2( T, L, F ) ( ( ( L ) << ( F ) ) - ( T ) ) - - -Word32 tcx_hm_render_fx( - const Word32 lag, /* i: pitch lag Q0 */ - const Word16 fract_res, /* i: fractional resolution of the lag Q0 */ - Word16 p[] /* o: harmonic model Q13 */ -); - - -void tcx_hm_modify_envelope_fx( - const Word16 gain, /* i: HM gain Q11 */ - const Word32 lag, /* i: pitch lag Q0 */ - const Word16 fract_res, /* i: fractional resolution of the lag Q0 */ - const Word16 p[], /* i: harmonic model Q13 */ - Word32 env[], /* i/o: envelope Q16 */ - const Word16 L_frame /* i: number of spectral lines Q0 */ -); - -void tcx_hm_analyse( - const float abs_spectrum[], /* i : absolute spectrum */ - const int16_t L_frame, /* i : number of spectral lines */ - Word32 env[], /* i/o: envelope shape (Q16) */ - const int16_t targetBits, /* i : target bit budget */ - const int16_t coder_type, /* i : GC/VC coder type */ - int16_t prm_hm[], /* o : HM parameters */ - int16_t LtpPitchLag, /* i : LTP pitch lag or -1 if none */ - const float LtpGain, /* i : LTP gain */ - int16_t *hm_bits /* o : bit consumption */ -); - -void tcx_hm_decode_ivas( - const int16_t L_frame, /* i : number of spectral lines */ - Word32 env[], /* i/o: envelope shape (Q16) */ - const int16_t targetBits, /* i : target bit budget */ - const int16_t coder_type, /* i : GC/VC coder type */ - const int16_t prm_hm[], /* i : HM parameters */ - const int16_t LtpPitchLag, /* i : LTP pitch lag or -1 if none */ - int16_t *hm_bits /* o : bit consumption */ -); - -void tcx_hm_decode( - const Word16 L_frame, /* i : number of spectral lines */ - Word32 env[], /* i/o: envelope shape (Q16) */ - const Word16 targetBits, /* i : target bit budget */ - const Word16 coder_type, /* i : GC/VC coder type */ - const Word16 prm_hm[], /* i : HM parameters */ - const Word16 LtpPitchLag, /* i : LTP pitch lag or -1 if none */ - Word16 *hm_bits /* o : bit consumption */ -); - -void coder_tcx( - Encoder_State *st, /* i/o: encoder state structure */ - TCX_CONFIG_HANDLE hTcxCfg, /* i : configuration of TCX */ - const float A[], /* i : quantized coefficients NxAz_q[M+1] */ - const Word16 Aqind[], /* i : frame-independent quantized coefficients (M+1) */ - float synth[], /* o : decoded synthesis */ - const int16_t L_frame_glob, /* i : frame length */ - const int16_t L_frameTCX_glob, - const int16_t L_spec, - int16_t nb_bits, /* i : bit budget */ - float spectrum[], /* i/o: MDCT spectrum */ - int16_t prm[], /* o : tcx parameters */ - CONTEXT_HM_CONFIG *hm_cfg, - const int16_t vad_hover_flag /* i : VAD hangover flag */ -); - -void coder_tcx_post( - Encoder_State *st, /* i/o: encoder memory state */ - float *A, /* o : Quantized LPC coefficients */ - const float *Ai /* i : Unquantized (interpolated) LPC coefficients */ -); - -void decoder_tcx( - Decoder_State *st, /* i/o: coder memory state */ - int16_t prm[], /* i : parameters */ - float A[], /* i : coefficients NxAz[M+1] */ - Word16 Aind[], /* i : frame-independent coefficients Az[M+1]*/ - float synth[], /* i/o: synth[-M..lg] */ - float synthFB[], /* i/o: encoder memory state */ - const int16_t bfi, /* i : Bad frame indicator */ - const int16_t frame_cnt, /* i : frame counter in the super_frame */ - const int16_t sba_dirac_stereo_flag /* i : signal stereo output for SBA DirAC */ -); - -void decoder_tcx_post( - Decoder_State *st, /* i/o: decoder memory state */ - float *synth, - float *synthFB, - float *A, /* i : A(z) filter coefficients */ - const int16_t bfi, - const int16_t isMCT ); - -void coder_acelp( - Encoder_State *st, /* i/o: coder memory state */ - const float A[], /* i : coefficients 4xAz[M+1] */ - const float Aq[], /* i : coefficients 4xAz_q[M+1] */ - const float speech[], /* i : speech[-M..lg] */ - LPD_state *LPDmem, /* i/o: ACELP memories */ - int16_t *prm, /* o : acelp parameters */ - const float stab_fac, - const int16_t target_bits, - float *gain_pitch_buf, /* o : gain pitch values */ - float *gain_code_buf, /* o : gain code values */ - float *pitch_buf, /* o : pitch values for each subfr.*/ - float *voice_factors, /* o : voicing factors */ - float *bwe_exc /* o : excitation for SWB TBE */ -); - -void coder_acelp_rf( - const int16_t target_bits, /* i : target bits */ - const float speech[], /* i : speech[-M..lg] */ - const int16_t coder_type, /* i : coding type */ - const int16_t rf_frame_type, /* i : rf_frame_type */ - const float A[], /* i : coefficients 4xAz[M+1] */ - const float Aq[], /* i : coefficients 4xAz_q[M+1] */ - const float voicing[], /* i : open-loop LTP gain */ - const int16_t T_op[], /* i : open-loop LTP lag */ - const float stab_fac, /* i : LP stability factor */ - Encoder_State *st, /* i/o: coder memory state */ - ACELP_config *acelp_cfg, /* i/o: configuration of the ACELP */ - float *exc_rf, /* i/o: pointer to RF excitation */ - float *syn_rf /* i/o: pointer to RF synthesis */ -); - -void decoder_acelp( - Decoder_State *st, /* i/o: coder memory state */ - int16_t prm[], /* i : parameters */ - const float A[], /* i : coefficients NxAz[M+1] */ - ACELP_config acelp_cfg, /* i : ACELP config */ - float synth[], /* i/o: synthesis */ - int16_t *pT, /* o : pitch for all subframe */ - float *pgainT, /* o : pitch gain for all subfr */ - const float stab_fac, /* i : stability of isf */ - float *pitch_buffer, /* o : pitch values for each subfr.*/ - float *voice_factors, /* o : voicing factors */ - const int16_t LSF_Q_prediction, /* i : LSF prediction mode */ - float *bwe_exc /* o : excitation for SWB TBE */ -); - -void writeTCXMode( - Encoder_State *st, /* i/o: encoder state structure */ - BSTR_ENC_HANDLE hBstr, /* i/o: bitstream handle */ - const int16_t MCT_flag, /* i : hMCT handle allocated (1) or not (0)*/ - int16_t *nbits_start /* o : nbits start */ -); - -void writeTCXWindowing( - BSTR_ENC_HANDLE hBstr, /* i/o: bitstream handle */ - const int16_t overlap_mode /* i : overlap mode */ -); - -void writeLPCparam( - Encoder_State *st, /* i/o: encoder state structure */ - BSTR_ENC_HANDLE hBstr, /* i/o: bitstream handle */ - const int16_t param_lpc[], /* i : LPC parameters to write */ - const int16_t bits_param_lpc[], /* i : bits per LPC parameter */ - const int16_t no_param_lpc, /* i : number of LPC parameters */ - int16_t *nbits_lpc /* o : LPC bits written */ -); - -void enc_prm( - Encoder_State *st, /* i/o: encoder state structure */ - int16_t param[], /* i : parameters */ - int16_t param_lpc[], /* i : LPC parameters */ - CONTEXT_HM_CONFIG hm_cfg[], - const int16_t bits_param_lpc[], - const int16_t no_param_lpc ); - -void writeTCXparam( - Encoder_State *st, /* i/o: Encoder State handle */ - BSTR_ENC_HANDLE hBstr, /* i/o: bitstream handle */ - CONTEXT_HM_CONFIG hm_cfg[], /* i/o: HM config */ - int16_t param[], /* i : parameters */ - const int16_t nbits_header, - const int16_t nbits_start, - const int16_t nbits_lpc, - const int16_t *no_param_tns, /* i : number of TNS parameters per subframe */ - int16_t p_param[2], /* i/o: pointer to parameters from previous bs writing */ - const int16_t target_bitsTCX10[2], - const int16_t pre_past_flag ); - -void enc_prm_rf( - Encoder_State *st, /* i/o: encoder memory state */ - const int16_t rf_frame_type, - const int16_t fec_offset ); - -void dec_prm_hm_ivas( - Decoder_State *st, /* i/o: decoder memory state */ - int16_t *prm_hm, - const int16_t hm_size ); - -void dec_prm_ivas( - Decoder_State *st, /* i/o: decoder memory state */ - int16_t param[], /* o : decoded parameters */ - int16_t param_lpc[], /* i : LPC parameters */ - int16_t *total_nbbits, /* i/o: number of bits / decoded bits */ - int16_t *bitsRead ); -void gaus_L2_dec_flt( - float *code, /* o : decoded gaussian codevector */ - float tilt_code, - const float *A, - float formant_enh_num, - int16_t *seed_acelp /* i/o: random seed */ -); - -/*! r: interpolated value */ -float interpolation( - const float *x, /* i : input vector */ - const float *win, /* i : interpolation window */ - const int16_t frac, /* i : fraction */ - const int16_t up_samp, /* i : upsampling factor */ - const int16_t nb_coef /* i : nb of filter coef */ -); - -void predict_signal_flt( - const float excI[], /* i : input excitation buffer */ - float excO[], /* o : output excitation buffer */ - const int16_t T0, /* i : integer pitch lag */ - int16_t frac, /* i : fraction of lag */ - const int16_t frac_max, /* i : max fraction */ - const int16_t L_subfr /* i : subframe size */ -); - -void tcx_ltp_encode( - Encoder_State *st, - const int16_t tcxMode, - const int16_t L_frame, - const float *speech, - float *speech_ltp, - const float *wsp, - const int16_t Top[], - int16_t *ltp_param, - int16_t *ltp_bits, - float *A, - const int16_t disable_ltp, - const int16_t element_mode ); - -void tcx_ltp_post_flt( - Decoder_State *st, - TCX_LTP_DEC_HANDLE hTcxLtpDec, - const int16_t core, - const int16_t output_frame, - const int16_t L_frame, - float sig[], - const float tcx_buf[] ); - -int16_t tcx_ltp_decode_params_flt( - int16_t *ltp_param, - int16_t *pitch_int, - int16_t *pitch_fr, - float *gain, - const int16_t pitmin, - const int16_t pitfr1, - const int16_t pitfr2, - const int16_t pitmax, - const int16_t pitres ); - -void create_IDCT_N_Matrix( - float *inv_matrixFloatQ, /* i/o: RAM buffer */ - const int16_t N, /* i : DCT length, number of time samples */ - const int16_t n_cols, /* i : number of dct coeffs (as DCT may be truncated) */ - const int16_t alloc_size /* i : RAM buffer size in elements */ -); - -void dctT2_N_apply_matrix( - const float *input, /* i : input in fdcng or DCT(fdcng) domain */ - float *output, /* o : output in DCT(fdcng) or fdcng ordomain */ - const int16_t dct_dim, /* i : dct processing dim possibly truncated */ - const int16_t fdcngvq_dim, /* i : fdcng domain length */ - const float *matrix, /* i : IDCT matrix */ - const int16_t matrix_row_dim, /* i : */ - const DCTTYPE dcttype /* i : matrix operation type */ -); - -void extend_dctN_input( - const float *input, /* i : input in fdcng domain */ - const float *dct_input, /* i : input in dctN(fdcng) domain */ - const int16_t in_dim, /* i : in_dim == N */ - float *ext_sig, /* o : extended output in fdcng domain */ - const int16_t out_dim, /* i : output total dim */ - float *matrix, /* i : idct synthesis matrix N rows, n_cols columns */ - const int16_t n_cols, /* i : number of columns == DCT truncation length */ - const DCTTYPE dcttype /* i : matrix operation type */ -); - - -void PulseResynchronization( - const float *src_exc, /* i : Input excitation buffer */ - float *dst_exc, /* o : output excitation buffer */ - const int16_t nFrameLength, /* i : frame length */ - const int16_t nSubframes, /* i : Number of subframes */ - const float pitchStart, /* i : Pitch at the end of the last frame */ - const float pitchEnd /* i : Pitch at the end of the current frame */ -); - -void con_acelp( - float A[], /* i : coefficients NxAz[M+1] */ - const int16_t coder_type, /* i : ACELP coder type */ - float synth[], /* i/o: synthesis */ - int16_t *pT, /* o : pitch for all subframe */ - float *pgainT, /* o : pitch gain for all subfr */ - float stab_fac, /* i : stability of isf */ - Decoder_State *st, /* i/o: coder memory state */ - float pitch_buffer[], /* i/o: floating pitch values for each subframe */ - float *voice_factors, /* o : voicing factors */ - float *bwe_exc /* o : excitation for SWB TBE */ -); - -void con_tcx( - Decoder_State *st, /* i/o: coder memory state */ - float synth[], /* i/o: synth[] */ - const float coh, /* i : coherence of stereo signal */ - int16_t *noise_seed, /* i/o: noise seed for stereo */ - const int16_t only_left, /* i : TD-PLC only in left channel */ - const float A_cng[] /* i : CNG LP filter coefficients */ -); - -int16_t lsf_msvq_ma_decprm_ivas( - Decoder_State *st, - int16_t *param_lpc ); - -int16_t dec_lsf_tcxlpc_ivas( - Decoder_State *st, /* i : Decoder state */ - int16_t **indices, /* o : Ptr to VQ indices */ - const int16_t narrowband, /* i : narrowband flag */ - const int16_t cdk /* i : codebook selector */ -); - -int16_t D_lsf_tcxlpc_ivas( - const int16_t indices[], /* i : VQ indices */ - float lsf_q[], /* o : quantized lsf */ - Word16 lsp_q_ind[], /* o : quantized lsp (w/o MA prediction) */ - const int16_t narrowband, /* i : narrowband flag */ - const int16_t cdk, /* i : codebook selector */ - const float mem_MA[] /* i : MA memory */ -); - -int16_t Q_lsf_tcxlpc( - /* const */ float lsf[], /* i : original lsf */ - float lsf_q[], /* o : quantized lsf */ - Word16 lsp_q_ind[], /* o : quantized lsp (w/o MA prediction) */ - int16_t indices[], /* o : VQ indices */ - const int16_t narrowband, /* i : narrowband flag */ - const int16_t cdk, /* i : codebook selector */ - const float mem_MA[], /* i : MA memory */ - const int16_t coder_type, /* i : acelp extended mode */ - const float *Bin_Ener /* i : Spectrum energy */ -); - -void midlsf_enc( - const float qlsf0[], - const float qlsf1[], - const float lsf[], - int16_t *idx, - const int16_t N, - const float *Bin_Ener, - const int16_t narrowBand, - const int32_t sr_core, - const int16_t coder_type ); - -void lsf_end_enc( - Encoder_State *st, - const float *lsf, - float *qlsf, - const int16_t nBits, - const int16_t coder_type_org, - const int16_t force_sf, - int16_t *lpc_param, - int16_t *no_stages, - int16_t *bits_param_lpc, - const int16_t coder_type_raw, - const float tdm_lsfQ_PCh[M] /* i : Q LSFs for primary channel */ -); - -void lsf_end_dec( - Decoder_State *st, /* i/o: decoder state structure */ - const int16_t coder_type_org, /* i : coding type */ - const int16_t bwidth, /* i : input signal bandwidth */ - const int16_t nBits, /* i : number of bits used for ISF quantization*/ - float *qlsf, /* o : quantized LSFs in the cosine domain */ - int16_t *lpc_param, /* i : LPC parameters */ - int16_t *LSF_Q_prediction, /* o : LSF prediction mode */ - int16_t *nb_indices, /* o : number of indices */ - const float tdm_lsfQ_PCh[M] /* i : Q LSFs for primary channel */ -); - -void lpc_quantization( - Encoder_State *st, - const float lsp[], - const float lspmid[], - float lsp_q[], - float lsf_q[], - float lspmid_q[], - const int16_t coder_type, - const int16_t acelp_midLpc, - int16_t param_lpc[], - int16_t nbits_lpc[], - int16_t *bits_param_lpc, - int16_t *no_param_lpc ); - -void lpc_unquantize( - Decoder_State *st, - float *lsf, - float *lsp, - int16_t *param_lpc, - float *lspmid, - float *lsfmid, - const int16_t coder_type, - int16_t *LSF_Q_prediction /* o : LSF prediction mode */ -); - -void dlpc_bfi_flt( - const int16_t L_frame, - float *lsf_q, /* o : quantized lsfs */ - const float *lsfold, /* i : past quantized lsf */ - const int16_t last_good, /* i : last good received frame */ - const int16_t nbLostCmpt, /* i : counter of consecutive bad frames */ - float mem_MA[], /* i/o: quantizer memory for MA model */ - float mem_AR[], /* i/o: quantizer memory for MA model */ - float *stab_fac, /* i : lsf stability factor */ - float *lsf_adaptive_mean, /* i : lsf adaptive mean, updated when BFI==0 */ - const int16_t numlpc, /* i : Number of division per superframe */ - float lsf_cng[], - const int16_t plcBackgroundNoiseUpdated, - float *lsf_q_cng, /* o : quantized lsfs of background noise */ - float *old_lsf_q_cng, /* o : old quantized lsfs for background noise */ - const float lsfBase[] /* i : base for differential lsf coding */ -); - -void Unified_weighting( - const float Bin_Ener_128[], /* i : FFT Bin energy 128 bins in two sets */ - const float lsf[], /* i : LSF vector */ - float w[], /* o : LP weighting filter (numerator) */ - const int16_t narrowBand, /* i : flag for Narrowband */ - const int16_t unvoiced, /* i : flag for Unvoiced frame */ - const int32_t sr_core, /* i : sampling rate of core-coder */ - const int16_t order /* i : LP order */ -); - -int16_t vad_init( - VAD_CLDFB_HANDLE hVAD_CLDFB /* i/o: CLDFB VAD state */ -); - -int16_t vad_proc( - float realValues[16][60], /* i : CLDFB real values */ - float imagValues[16][60], /* i : CLDFB imag values */ - float *sb_power, /* i/o: Energy of CLDFB data */ - const int16_t numBands, /* i : number of input bands */ - VAD_CLDFB_HANDLE hVAD_CLDFB, /* i/o: CLDFB VAD state */ - int16_t *cldfb_addition, - const int16_t vada_flag /* i : VAD flag */ -); - - -int16_t update_decision( - VAD_CLDFB_HANDLE hVAD_CLDFB, /* i/o: CLDFB VAD state */ - const float snr, /* i : frequency domain SNR */ - const float tsnr, /* i : time domain SNR */ - const float frame_energy, /* i : current frame energy */ - const float high_eng, /* i : current frame high frequency energy */ - const int16_t vad_flag, /* i : VAD flag */ - const int16_t music_backgound_f /* i : background music flag */ -); - -void frame_spec_dif_cor_rate( - float spec_amp[], /* i : spectral amplitude */ - float pre_spec_low_dif[], /* i/o: low spectrum different */ - float f_tonality_rate[] /* o : tonality rate */ -); - - -void SNR_calc( - const float frame_sb_energy[], /* i : energy of sub-band divided non-uniformly*/ - const float sb_bg_energy[], /* i : sub-band background energy */ - const float t_bg_energy, /* i : time background energy of several frames*/ - float *snr, /* o : frequency domain SNR */ - float *tsnr, /* o : time domain SNR */ - const float frame_energy, /* i : current frame energy */ - const int16_t bwidth /* i : audio bandwidth */ -); - -void background_update( - VAD_CLDFB_HANDLE hVAD_CLDFB, /* i/o: CLDFB VAD state */ - float frame_energy, /* i : current frame energy 2 */ - const int16_t update_flag, /* i : current frame update flag */ - const int16_t music_backgound_f, /* i : background music flag */ - const float snr ); - -void bg_music_decision( - VAD_CLDFB_HANDLE hVAD_CLDFB, /* i/o: CLDFB VAD state */ - int16_t *music_backgound_f, /* i : background music flag */ - const float frame_energy /* i : current frame energy 1 */ -); - -void est_energy( - float sb_power[], /* o : energy of sub-band divided uniformly */ - float frame_sb_energy[], /* o : energy of sub-band divided non-uniformly*/ - float *p_frame_energy, /* o : frame energy 1 */ - float *p_frame_energy2, /* o : frame energy 2 */ - float *p_high_energy, /* o : high frequency energy */ - const int16_t bw /* i : bandwidth */ -); - - -int16_t comvad_decision( - VAD_CLDFB_HANDLE hVAD_CLDFB, /* i/o: CLDFB VAD state */ - const float snr, /* i : frequency domain SNR */ - const float tsnr, /* i : time domain SNR */ - const float snr_flux, /* i : average tsnr of several frames */ - const float lt_snr, /* i : long time SNR calculated by fg_energy and bg_energy*/ - const float lt_snr_org, /* i : original long time SNR */ - const float lf_snr, /* i : long time frequency domain SNR calculated by l_speech_snr and l_silence_snr*/ - const float frame_energy, /* i : current frame energy */ - const int16_t music_backgound_f, /* i : background music flag */ - int16_t *cldfb_addition, - const int16_t vada_flag /* i : VAD flag */ -); - -void calc_snr_flux( - float tsnr, /* i : time-domain SNR */ - float pre_snr[], /* i/o: time-domain SNR storage */ - float *snr_flux /* o : average tsnr */ -); - -void calc_lt_snr( - float *lt_snr_org, /* o : original long time SNR */ - float *lt_snr, /* o : long time SNR calculated by fg_energy and bg_energy*/ - const float fg_energy, /* i : foreground energy sum */ - const int16_t fg_energy_count, /* i : number of the foreground energy frame */ - const float bg_energy, /* i : background energy sum */ - const int16_t bg_energy_count, /* i : number of the background energy frame */ - const int16_t bw_index, /* i : band width index */ - const float lt_noise_sp_center0 /* i : long time noise spectral center by 0 */ -); - -void calc_lf_snr( - float *lf_snr_smooth, /* o : smoothed lf_snr */ - float *lf_snr, /* o : long time frequency domain SNR calculated by l_speech_snr and l_silence_snr*/ - const float l_speech_snr, /* i : sum of active frames snr */ - const int16_t l_speech_snr_count, /* i : number of the active frame */ - const float l_silence_snr, /* i : sum of the nonactive frames snr */ - const int16_t l_silence_snr_count, /* i : number of the nonactive frame */ - const int16_t fg_energy_count, /* i : number of the foreground energy frame */ - const int16_t bg_energy_count, /* i : number of the background energy frame */ - const int16_t bw_index /* i : band width index */ -); - -float construct_snr_thresh( - const float sp_center[], /* i : spectral center */ - const float snr_flux, /* i : snr flux */ - const float lt_snr, /* i : long time time domain snr */ - const float lf_snr, /* i : long time frequency domain snr */ - const int16_t continuous_speech_num, /* i : continuous speech number */ - const int16_t continuous_noise_num, /* i : continuous noise number */ - const int16_t fg_energy_est_start, /* i : whether if estimated energy */ - const int16_t bw_index /* i : band width index */ -); - -void minimum_statistics_flt( - const int16_t len, /* i : Vector length */ - const int16_t lenFFT, /* i : Length of the FFT part of the vectors */ - float *psize_flt, - float *msPeriodog, /* i : Periodograms */ - float *msNoiseFloor, - float *msNoiseEst, /* o : Noise estimates */ - float *msAlpha, - float *msPsd, - float *msPsdFirstMoment, - float *msPsdSecondMoment, - float *msMinBuf, - float *msBminWin, - float *msBminSubWin, - float *msCurrentMin, - float *msCurrentMinOut, - float *msCurrentMinSubWindow, - int16_t *msLocalMinFlag, - int16_t *msNewMinFlag, - float *msPeriodogBuf, - int16_t *msPeriodogBufPtr, - HANDLE_FD_CNG_COM hFdCngCom, /* i/o: FD_CNG structure containing all buffers and variables */ - const int16_t enc_dec, /* i : encoder/decoder indicator */ - const int16_t element_mode /* i : IVAS element mode */ -); - -void generate_comfort_noise_enc( - Encoder_State *st /* i/o: encoder state structure */ -); - -void generate_comfort_noise_dec( - float **bufferReal, /* o : Real part of input bands */ - float **bufferImag, /* o : Imaginary part of input bands */ - Decoder_State *st, /* i/o: decoder state structure */ - const int16_t nchan_out /* i : number of output channels */ -); - -void generate_comfort_noise_dec_hf( - float **bufferReal, /* o : Real part of input bands */ - float **bufferImag, /* o : Imaginary part of input bands */ - HANDLE_FD_CNG_COM hFdCngCom, /* i/o: FD_CNG structure containing all buffers and variables */ - const int16_t cng_flag /* i : CNG Flag */ -); - -void generate_masking_noise( - float *timeDomainBuffer, /* i/o: time-domain signal */ - HANDLE_FD_CNG_COM hFdCngCom, /* i/o: FD_CNG structure containing all buffers and variables */ - const int16_t length, /* i : frame size */ - const int16_t core, /* i : core */ - const int16_t return_noise, /* i : noise is returned instead of added */ - const int16_t secondary, /* i : indicator for secondary channel */ - const int16_t element_mode, /* i : element mode */ - STEREO_CNG_DEC_HANDLE hStereoCng, /* i : stereo CNG handle */ - const int16_t nchan_out /* i : number of output channels */ -); - -void generate_masking_noise_update_seed( - HANDLE_FD_CNG_COM hFdCngCom /* i/o: FD_CNG structure containing all buffers and variables */ -); - -void generate_masking_noise_mdct( - float *mdctBuffer, /* i/o: time-domain signal */ - HANDLE_FD_CNG_COM hFdCngCom /* i/o: FD_CNG structure containing all buffers and variables */ -); - -void SynthesisSTFT_dirac_flt( - float *fftBuffer, /* i : FFT bins */ - float *timeDomainOutput, - float *olapBuffer, - const float *olapWin, - const int16_t samples_out, - HANDLE_FD_CNG_COM hFdCngCom /* i/o: FD_CNG structure containing all buffers and variables */ -); - -void generate_masking_noise_dirac( - HANDLE_FD_CNG_COM hFdCngCom, /* i/o: FD_CNG structure containing all buffers and variables */ - HANDLE_CLDFB_FILTER_BANK h_cldfb, /* i : filterbank state */ - float *tdBuffer, /* i/o: time-domain signal, if NULL no LB-CNA */ - float *Cldfb_RealBuffer, /* o : CLDFD real buffer */ - float *Cldfb_ImagBuffer, /* o : CLDFD imaginary buffer */ - const int16_t slot_index, /* i : CLDFB slot index */ - const int16_t cna_flag, /* i : CNA flag for LB and HB */ - const int16_t fd_cng_flag /* i : FD-CNG flag for HB */ -); - -void generate_stereo_masking_noise( - float *syn, /* i/o: time-domain signal */ - Decoder_State *st, /* i/o: decoder state structure */ - STEREO_TD_DEC_DATA_HANDLE hStereoTD, /* i : TD stereo structure */ - const int16_t flag_sec_CNA, /* i : CNA flag for secondary channel */ - const int16_t fadeOut, /* i : only fade out of previous state */ - STEREO_CNG_DEC_HANDLE hStereoCng, /* i : stereo CNG handle */ - const int16_t nchan_out /* i : number of output channels */ -); - -void apply_scale_flt( - float *scale, /* i : scale factor */ - const int16_t bwidth, /* i : audio bandwidth */ - const int32_t brate, /* i : Bit rate */ - const SCALE_SETUP *scaleTable, /* i : Scale table */ - const int16_t scaleTableSize /* i : Size of scale table */ -); - -void compress_range_flt( - float *in, - float *out, - const int16_t len ); - -void expand_range_flt( - float *in, - float *out, - const int16_t len ); - -void bandcombinepow_flt( - const float *bandpow, /* i : Power for each band */ - const int16_t nband, /* i : Number of bands */ - int16_t *part, /* i : Partition upper boundaries (band indices starting from 0) */ - const int16_t npart, /* i : Number of partitions */ - const float *psize_inv_flt, /* i : Inverse partition sizes */ - float *partpow /* o : Power for each partition */ -); - -void scalebands_flt( - const float *partpow, /* i : Power for each partition */ - int16_t *part, /* i : Partition upper boundaries (band indices starting from 0) */ - const int16_t npart, /* i : Number of partitions */ - int16_t *midband, /* i : Central band of each partition */ - const int16_t nFFTpart, /* i : Number of FFT partitions */ - const int16_t nband, /* i : Number of bands */ - float *bandpow, /* o : Power for each band */ - const int16_t flag_fft_en ); - -void AnalysisSTFT_flt( - const float *timeDomainInput, - float *fftBuffer, /* o : FFT bins */ - HANDLE_FD_CNG_COM st /* i/o: FD_CNG structure containing all buffers and variables */ -); - -void SynthesisSTFT_flt( - float *fftBuffer, - float *timeDomainOutput, - float *olapBuffer, - const float *olapWin, - const int16_t tcx_transition, - HANDLE_FD_CNG_COM hFdCngCom, - const int16_t element_mode, /* i : element mode */ - const int16_t nchan_out /* i : number of output channels */ -); - -void lpc_from_spectrum_flt( - HANDLE_FD_CNG_COM hFdCngCom, - const int16_t start, - const int16_t stop, - const float preemph_fac ); - -ivas_error createFdCngDec( - HANDLE_FD_CNG_DEC *hFdCngDec ); - -void deleteFdCngDec( - HANDLE_FD_CNG_DEC *hFdCngDec ); - -void initFdCngDec( - DEC_CORE_HANDLE st /* i/o: decoder state structure */ -); - -void configureFdCngDec( - HANDLE_FD_CNG_DEC hFdCngDec, /* i/o: Contains the variables related to the FD-based CNG process */ - const int16_t bwidth, - const int32_t total_brate, - const int16_t L_frame, - const int16_t last_L_frame, - const int16_t element_mode ); - -void ApplyFdCng( - float *timeDomainInput, - float *powerSpectrum, - float **realBuffer, /* i/o: Real part of the buffer */ - float **imagBuffer, /* i/o: Imaginary part of the buffer */ - Decoder_State *st, - const int16_t concealWholeFrame, /* i : binary flag indicating frame loss */ - const int16_t is_music ); - -void generate_comfort_noise_dec( - float **bufferReal, /* o : Real part of input bands */ - float **bufferImag, /* o : Imaginary part of input bands */ - Decoder_State *st, /* i/o: decoder state structure */ - const int16_t nchan_out /* i : number of output channels */ -); - -/*! r: CNG energy */ -float cng_energy( - const int16_t element_mode, /* i : element mode */ - const int16_t bwidth, /* i : audio bandwidh */ - const int16_t CNG_mode, /* i : mode for DTX configuration */ - const float CNG_att, /* i : attenuation factor for CNG */ - const float *inputBuffer, /* i : input signal */ - const int16_t len /* i : vector length */ -); - -void FdCng_decodeSID( - Decoder_State *st /* i/o: decoder state structure */ -); - -void FdCng_exc_flt( - HANDLE_FD_CNG_COM hFdCngCom, - int16_t *CNG_mode, - const int16_t L_frame, - const float *lsp_old, - const int16_t first_CNG, - float *lsp_CNG, - float *Aq, /* o : LPC coeffs */ - float *lsp_new, /* o : lsp */ - float *lsf_new, /* o : lsf */ - float *exc, /* o : LP excitation */ - float *exc2, /* o : LP excitation */ - float *bwe_exc /* o : LP excitation for BWE */ -); - -void noisy_speech_detection( - HANDLE_FD_CNG_DEC hFdCngDec, /* i/o: FD_CNG structure */ - const int16_t vad, /* i : VAD flag */ - const float syn[] /* i : input time-domain frame */ -); - -void deleteFdCngEnc( - HANDLE_FD_CNG_ENC *hFdCngEnc /* i/o: FD_CNG structure */ -); - - -void resetFdCngEnc( - Encoder_State *st /* i/o: encoder state structure */ -); - -void perform_noise_estimation_enc( - float *band_energies, /* i : energy in critical bands without minimum noise floor E_MIN */ - float *enerBuffer, /* i : energy buffer */ - HANDLE_FD_CNG_ENC hFdCngEnc, /* i/o: CNG structure containing all buffers and variables */ - const int32_t input_Fs, /* i : input sampling rate */ - CPE_ENC_HANDLE hCPE ); - -void AdjustFirstSID( - Encoder_State *st /* i/o: encoder state structure */ -); - -void FdCng_encodeSID( - Encoder_State *st /* i/o: encoder state structure */ -); - -void GetParameters( - ParamsBitMap const *paramsBitMap, - const int16_t nParams, - void const *pParameter, - int16_t **pStream, - int16_t *pnSize, - int16_t *pnBits ); - -void SetParameters( - ParamsBitMap const *paramsBitMap, - const int16_t nParams, - void *pParameter, - const int16_t **pStream, - int16_t *pnSize ); - -void WriteToBitstream( - ParamsBitMap const *paramsBitMap, - const int16_t nParams, - const int16_t **pStream, - int16_t *pnSize, - BSTR_ENC_HANDLE hBstr, - int16_t *pnBits ); - -void ReadFromBitstream( - ParamsBitMap const *paramsBitMap, - const int16_t nArrayLength, - Decoder_State *st, - int16_t **pStream, - int16_t *pnSize ); - -void const *GetTnsOnWhite( void const *p, const int16_t index, int16_t *pValue ); -void *SetTnsOnWhite( void *p, const int16_t index, const int16_t value ); -void const *GetNumOfTnsFilters_flt( void const *p, const int16_t index, int16_t *pValue ); -void *SetNumOfTnsFilters_flt( void *p, const int16_t index, const int16_t value ); - -int16_t DecodeSWBTCX10TnsFilterCoeff_flt( Decoder_State *st, const int16_t index, int16_t *pValue ); -int16_t DecodeSWBTCX20TnsFilterCoeff_flt( Decoder_State *st, const int16_t index, int16_t *pValue ); - -int16_t DecodeWBTCX20TnsFilterCoeff_flt( Decoder_State *st, const int16_t index, int16_t *pValue ); - -int16_t DecodeTnsFilterOrderSWBTCX10_flt( Decoder_State *st, const int16_t index, int16_t *pValue ); -int16_t DecodeTnsFilterOrderSWBTCX20_flt( Decoder_State *st, const int16_t index, int16_t *pValue ); - -int16_t EncodeTnsFilterOrderSWBTCX10_flt( const int16_t value, const int16_t index ); - -int16_t GetTnsFilterOrderBitsSWBTCX10_flt( const int16_t value, const int16_t index ); -int16_t DecodeTnsFilterOrder_flt( Decoder_State *st, const int16_t index, int16_t *pValue ); - -void ResetTnsData_flt( - STnsData *pTnsData ); - -void ClearTnsFilterCoefficients_flt( - STnsFilter *pTnsFilter ); - - -int16_t DetectTnsFilt( - const STnsConfig *pTnsConfig, /* i : TNS Configuration struct */ - const float pSpectrum[], /* i : MDCT spectrum */ - TRAN_DET_HANDLE hTranDet, /* i : transient detection handle */ - const int16_t isTCX10, /* i : TCX10 or TCX20? */ - const float ltp_gain, /* i : LTP gain */ - STnsData *pTnsData, /* o : TNS data struct */ - float *predictionGain /* o : TNS prediction gain */ -); - -void EncodeTnsData( - STnsConfig const *pTnsConfig, /* i : TNS Configuration struct */ - STnsData const *pTnsData, /* i : TNS data struct (quantized param) */ - int16_t *stream, /* o : internal data stream */ - int16_t *pnSize, /* o : number of written parameters */ - int16_t *pnBits /* o : number of written bits */ -); - -int16_t DecodeTnsData_ivas( - STnsConfig const *pTnsConfig, - const int16_t *stream, - int16_t *pnSize, - STnsData *pTnsData ); - -void WriteTnsData( - const STnsConfig *pTnsConfig, /* i : TNS Configuration struct */ - const int16_t *stream, /* i : internal data stream */ - int16_t *pnSize, /* o : number of written parameters */ - BSTR_ENC_HANDLE hBstr, /* o : bitstream */ - int16_t *pnBits /* o : number of written bits */ -); - -void ReadTnsData_ivas( - STnsConfig const *pTnsConfig, - Decoder_State *st, - int16_t *pnBits, - int16_t *stream, - int16_t *pnSize ); - -void cldfbAnalysis_ivas( - const float *timeIn, /* i : time buffer */ - float **realBuffer, /* o : real value buffer */ - float **imagBuffer, /* o : imag value buffer */ - const int16_t samplesToProcess, /* i : number of input samples */ - HANDLE_CLDFB_FILTER_BANK h_cldfb /* i : filterbank state */ -); - -void cldfbAnalysis_ts_ivas( - const float *timeIn, /* i : time buffer */ - float realBuffer[CLDFB_NO_CHANNELS_MAX], /* o : real value buffer */ - float imagBuffer[CLDFB_NO_CHANNELS_MAX], /* o : imag value buffer */ - const int16_t samplesToProcess, /* i : samples to process */ - HANDLE_CLDFB_FILTER_BANK h_cldfb /* i : filterbank state */ -); - -void cldfbSynthesis_ivas( - float **realBuffer, /* i : real values */ - float **imagBuffer, /* i : imag values */ - float *timeOut, /* o : synthesized output */ - const int16_t samplesToProcess, /* i : number of samples */ - HANDLE_CLDFB_FILTER_BANK h_cldfb /* i : filter bank state */ -); - -void configureCldfb_ivas( - HANDLE_CLDFB_FILTER_BANK h_cldfb, /* i/o: filter bank handle */ - const int32_t sampling_rate /* i : sampling rate */ -); - - -void analysisCldfbEncoder_ivas( - Encoder_State *st, /* i/o: encoder state structure */ - const float *timeIn, - const int16_t samplesToProcess, - float realBuffer[CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], - float imagBuffer[CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], - float *ppBuf_Ener ); - -void analysisCldfbEncoder_ivas_fx( - Encoder_State *st, /* i/o: encoder state structure */ - Word32 *timeIn, /*q11*/ - Word16 timeInq, /*q0*/ - Word16 samplesToProcess, /*q0*/ - Word32 realBuffer[CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], - Word32 imagBuffer[CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], - Word16 realBuffer16[CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], - Word16 imagBuffer16[CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], - Word32 *ppBuf_Ener, - Word16 *enerBuffSum_exp, - CLDFB_SCALE_FACTOR *scale ); - -ivas_error openCldfb_ivas( - HANDLE_CLDFB_FILTER_BANK *h_cldfb, /* i/o: filter bank handle */ - CLDFB_TYPE type, /* i : analysis or synthesis */ - const int32_t sampling_rate, /* i : sampling rate */ - CLDFB_PROTOTYPE prototype /* i : CLDFB version (1.25ms/5ms delay) */ -); - -ivas_error openCldfb_ivas_enc( - HANDLE_CLDFB_FILTER_BANK *h_cldfb, /* i/o: filter bank handle */ - CLDFB_TYPE type, /* i : analysis or synthesis */ - const Word32 sampling_rate, /* i : sampling rate */ - CLDFB_PROTOTYPE prototype /* i : CLDFB version (1.25ms/5ms delay) */ -); - -void resampleCldfb_ivas( - HANDLE_CLDFB_FILTER_BANK hs, /* i/o: filter bank handle */ - const int32_t newSamplerate /* i : new samplerate to operate */ -); - -ivas_error cldfb_save_memory_ivas( - HANDLE_CLDFB_FILTER_BANK hs /* i/o: filter bank handle */ -); - -void cldfb_restore_memory_ivas( - HANDLE_CLDFB_FILTER_BANK hs /* i/o: filter bank handle */ -); - -void cldfb_reset_memory_ivas( - HANDLE_CLDFB_FILTER_BANK hs /* i/o: filter bank handle */ -); - -void deleteCldfb_ivas( - HANDLE_CLDFB_FILTER_BANK *h_cldfb /* i/o: filter bank handle */ -); - -void fft_cldfb( - float *data, /* i/o: input/output vector */ - const int16_t size /* i : size of fft operation */ -); - -void BITS_ALLOC_init_config_acelp_IVAS( - const int32_t bit_rate, - const int16_t narrowBand, - const int16_t nb_subfr, - ACELP_config *acelp_cfg /* o : configuration structure of ACELP */ -); - -int16_t BITS_ALLOC_config_acelp_IVAS( - const int16_t bits_frame, /* i : remaining bit budget for the frame */ - const int16_t coder_type, /* i : acelp coder type */ - ACELP_config *acelp_cfg, /* i/o: configuration structure of ACELP */ - const int16_t narrowband, /* i : narrowband flag */ - const int16_t nb_subfr /* i : number of subframes */ -); - -ivas_error config_acelp1_IVAS( - const int16_t enc_dec, /* i : encoder/decoder flag */ - const int32_t total_brate, /* i : total bitrate */ - const int32_t core_brate_inp, /* i : core bitrate */ - const int16_t core, /* i : core */ - const int16_t extl, /* i : extension layer */ - const int32_t extl_brate, /* i : extension layer bitrate */ - const int16_t L_frame, /* i : frame length at internal Fs */ - const int16_t GSC_noisy_speech, /* i : GSC on SWB noisy speech flag */ - ACELP_config *acelp_cfg, /* i : ACELP bit-allocation */ - const int16_t signaling_bits, /* i : number of signaling bits */ - const int16_t coder_type, /* i : coder type */ - const int16_t tc_subfr, /* i : TC subfr ID */ - const int16_t tc_call, /* i : TC call number (0,1,2) */ - int16_t *nBits_es_Pred, /* o : number of bits for Es_pred Q */ - int16_t *unbits, /* o : number of unused bits */ - const int16_t element_mode, /* i : element mode */ - int16_t *uc_two_stage_flag, /* o : flag undicating two-stage UC */ - const int16_t tdm_lp_reuse_flag, /* i : LPC reuse flag (can be 1 only with secondary channel*/ - const int16_t tdm_low_rate_mode, /* i : secondary channel low rate mode flag*/ - const int16_t idchan, /* i : channel id */ - const int16_t active_cnt, /* i : Active frame counter */ - const int16_t tdm_Pitch_reuse_flag, /* i : primary channel pitch reuse flag */ - const int16_t tdm_LRTD_flag, /* i : LRTD stereo mode flag */ - const int16_t GSC_IVAS_mode /* i : GSC IVAS mode */ -); - -/*! r: ACELP16k flag */ - - -void FEC_clas_estim( - const float *syn, - const float *pitch, /* i : pitch values for each subframe */ - const int16_t L_frame, /* i : length of the frame */ - const int16_t coder_type, /* i : coder type */ - const int16_t codec_mode, /* i : codec mode */ - float *mem_syn_clas_estim, /* i/o: memory of the synthesis signal for frame class estimation */ - int16_t *clas, /* i/o: frame classification */ - float *lp_speech, /* i/o: long term active speech energy average */ - const int16_t Opt_AMR_WB, /* i : flag indicating AMR-WB IO mode */ - int16_t *decision_hyst, /* i/o: hysteresis of the music/speech decision */ - int16_t *locattack, /* i/o: detection of attack (mainly to localized speech burst) */ - int16_t *UV_cnt, /* i/o: number of consecutives frames classified as UV */ - float *LT_UV_cnt, /* i/o: long term consecutives frames classified as UV */ - float *Last_ener, /* i/o: last_energy frame */ - int16_t *amr_io_class, /* i/o: classification for AMR-WB IO mode */ - float *lt_diff_etot, /* i/o: long-term total energy variation */ - float *class_para, /* o : classification para. fmerit1 */ - const float LTP_Gain, /* i : */ - const int16_t narrowBand, /* i : */ - const SIGNAL_CLASSIFIER_MODE mode, /* i : */ - const int16_t bfi, /* i : */ - const float preemph_fac, /* i : */ - const int16_t tcxonly, /* i : */ - const int32_t last_core_brate, /* i : last core bitrate */ - const int16_t FEC_mode /* i : ACELP FEC mode */ -); - - -void SetTCXModeInfo( - Encoder_State *st, /* i/o: encoder state structure */ - TRAN_DET_HANDLE hTranDet, /* i/o: transient detection handle */ - int16_t *tcxModeOverlap /* o : window overlap of current frame */ -); - -void TCX_MDCT_flt( - const float *x, - float *y, - const int16_t l, - const int16_t m, - const int16_t r, - const int16_t element_mode ); - -void TCX_MDST_flt( - const float *x, - float *y, - const int16_t l, - const int16_t m, - const int16_t r, - const int16_t element_mode ); - -void TCX_MDCT_Inverse_flt( - const float *x, - float *y, - const int16_t l, - const int16_t m, - const int16_t r, - const int16_t element_mode ); - -void TCX_MDST_Inverse_flt( - const float *x, - float *y, - const int16_t l, - const int16_t m, - const int16_t r, - const int16_t element_mode ); - -void TCX_MDXT_Inverse_flt( - const float *x, - float *y, - const int16_t l, - const int16_t m, - const int16_t r, - const uint16_t kernel_type ); - -void post_decoder_flt( - Decoder_State *st, - float synth_buf[], - const float pit_gain[], - const int16_t pitch[], - float signal_out[], - float bpf_noise_buf[] ); -void cldfb_synth_set_bandsToZero_flt( - Decoder_State *st, /* i/o: decoder state structure */ - float **rAnalysis, - float **iAnalysis, - const int16_t nTimeSlots ); - -void longadd( - uint16_t a[], /* i/o: vector of the length lena */ - const uint16_t b[], /* i/o: vector of the length lenb */ - const int16_t lena, /* i/o: length of vector a[] */ - const int16_t lenb /* i/o: length of vector b[] */ -); - -void longshiftright( - uint16_t a[], /* i : vector of the length lena */ - const int16_t b, /* i : number of bit positions to shift right */ - uint16_t d[], /* o : vector of the length lend */ - int16_t lena, /* i : length of vector a[] */ - const int16_t lend /* i : length of vector d[] */ -); - -void longshiftleft( - const uint16_t a[], /* i : vector of the length len */ - const int16_t b, /* i : number of bit positions to shift left */ - uint16_t d[], /* o : vector of the length len */ - const int16_t len /* i : length of vector a[] and d[] */ -); - -void open_decoder_LPD( - Decoder_State *st, /* i/o: decoder state structure */ - const int32_t total_brate, /* i : total bitrate */ - const int32_t last_total_brate, /* i : last total bitrate */ - const int16_t bwidth, /* i : audio bandwidth */ - const int16_t MCT_flag, /* i : hMCT handle allocated (1) or not (0) */ - const int16_t last_element_mode, /* i : last element mode */ - const int16_t is_init /* i : indicate call during initialization */ -); - -void acelp_plc_mdct_transition( - Decoder_State *st /* i/o: Decoder state */ -); - -void tcxltp_dec_init( - TCX_LTP_DEC_HANDLE hTcxLtpDec, - const int16_t ini_frame, - const int16_t last_codec_mode, - const int16_t element_mode, - const int16_t pit_max, - const int32_t sr_core ); - -void reset_tcx_overl_buf( - TCX_DEC_HANDLE hTcxDec /* i/o: TCX decoder handle */ -); - -void update_decoder_LPD_cng_flt( - Decoder_State *st, /* i/o: decoder state structure */ - float *timeDomainBuffer, - float *A, - float *bpf_noise_buf ); - -void reconfig_decoder_LPD_ivas( - Decoder_State *st, /* i/o: decoder state structure */ - const int16_t bits_frame, /* i : bit budget */ - const int16_t bwidth, /* i : audio bandwidth */ - const int32_t total_brate, /* i : total bitrate */ - const int16_t L_frame_old /* i : frame length */ -); - -void mode_switch_decoder_LPD( - Decoder_State *st, /* i/o: decoder state structure */ - const int16_t bwidth, /* i : audio bandwidth */ - const int32_t total_brate, /* i : total bitrate */ - const int32_t last_total_brate, /* i : last frame total bitrate */ - const int16_t frame_size_index, /* i : index determining the frame size */ - const int16_t MCT_flag, /* i : hMCT handle allocated (1) or not (0)*/ - const int16_t last_element_mode /* i : last element mode */ -); - -void dec_acelp_tcx_frame( - Decoder_State *st, /* i/o: decoder state structure */ - int16_t *concealWholeFrame, /* i/o: concealment flag */ - float *output, /* o : synthesis */ - float *bpf_noise_buf, /* i/o: BPF noise buffer */ - float *pcmbufFB, /* o : synthesis @output_FS */ - float bwe_exc_extended[], /* i/o: bandwidth extended excitation */ - float *voice_factors, /* o : voicing factors */ - float pitch_buf[], /* o : floating pitch for each subframe */ - STEREO_CNG_DEC_HANDLE hStereoCng /* i : stereo CNG handle */ -); - -void decoder_LPD( - Decoder_State *st, /* i/o: decoder memory state pointer */ - float signal_out[], /* o : signal with LPD delay (7 subfrs) */ - float signal_outFB[], /* o : synthesis @output_FS */ - int16_t *total_nbbits, /* i/o: number of bits / decoded bits */ - float *bpf_noise_buf, /* i/o: BPF noise buffer */ - int16_t bfi, /* i : BFI flag */ - int16_t *bitsRead, /* o : number of read bits */ - int16_t param[], /* o : buffer of parameters */ - float *pitch_buf, /* i/o: floating pitch values for each subfr*/ - float *voice_factors, /* o : voicing factors */ - float *ptr_bwe_exc /* o : excitation for SWB TBE */ -); - -int16_t tcxGetNoiseFillingTilt_flt( - const float A[], - const int16_t L_frame, - const int16_t mode, - float *noiseTiltFactor ); - -void tcxFormantEnhancement_flt( - float xn_buf[], - const float *gainlpc, - float spectrum[], - const int16_t L_frame ); - -void tcxInvertWindowGrouping_flt( - TCX_CONFIG_HANDLE hTcxCfg, - float xn_buf[], - float spectrum[], - const int16_t L_frame, - const int8_t fUseTns, - const int16_t last_core, - const int16_t index, - const int16_t frame_cnt, - const int16_t bfi ); - -void tcx5SpectrumInterleaving( - const int16_t tcx5Size, - float *spectrum ); - -void tcx5SpectrumDeinterleaving( - const int16_t tcx5Size, - float *spectrum ); - -void tcx5TnsGrouping( - const int16_t L_frame, - const int16_t L_spec, - float *spectrum ); - -void tcx5TnsUngrouping( - const int16_t L_frame, - const int16_t L_spec, - float *spectrum, - const int16_t enc_dec ); - -void lerp_flt( - const float *f, - float *f_out, - const int16_t bufferNewSize, - const int16_t bufferOldSize ); - -void encoderSideLossSimulation( - Encoder_State *st, - PLC_ENC_EVS_HANDLE hPlc_Ext, - float *isf_q, - const float stab_fac, - const int16_t calcOnlyISF, - const int16_t L_frame ); - -void enc_prm_side_Info( - PLC_ENC_EVS_HANDLE hPlc_Ext, - Encoder_State *st ); - -void GplcTcxEncSetup( - const int16_t tcxltp_pitch_int, - PLC_ENC_EVS_HANDLE hPlc_Ext ); - -int16_t encSideSpecPowDiffuseDetector( - float *isf_ref, - float *isf_con, - const int32_t sr_core, - float *prev_isf4_mean, - const int16_t sw, - const int16_t coder_type ); - -void updateSpecPowDiffuseIdx( - const float gain_pitch_buf[], /* i : gain pitch values */ - const float gain_code_buf[], /* i : gain pitch values */ - int16_t glr_idx[2], /* o : */ - float mean_gc[2] /* o : */ -); - -void getLookAheadResSig_flt( - float *speechLookAhead, - const float *A, - float *res, - const int16_t L_frame, - const int16_t L_subfr, - const int16_t m, - const int16_t numSubFrame ); - -void updatelsfForConcealment_flt( - PLC_ENC_EVS_HANDLE decState, - float *lsf ); - -void getConcealedLP_flt( - PLC_ENC_EVS_HANDLE memDecState, - float *AqCon, - const float xsfBase[], - const int32_t sr_core, - const int16_t last_good, - const int16_t L_frame ); - -void RecLpcSpecPowDiffuseLc_flt( - float *ispq, - float *isp_old, - float *isfq, - Decoder_State *st, - const int16_t reset_q ); - -void modify_lsf_flt( - float *lsf, - const int16_t n, - const int32_t sr_core, - const int16_t reset_q ); - -void init_PLC_enc( - PLC_ENC_EVS_HANDLE hPlcExt, - const int32_t sr_core ); - -void gPLC_encInfo( - PLC_ENC_EVS_HANDLE hPlcExt, - const int32_t total_brate, - const int16_t bwidth, - const int16_t last_clas, - const int16_t coder_type ); - -void resetTecDec( - TEC_DEC_HANDLE hTecDec ); - -void calcGainTemp_TBE( - float **pCldfbRealSrc, - float **pCldfbImagSrc, - float *loBuffer, - const int16_t startPos, /*!< Start position of the current envelope. */ - const int16_t stopPos, /*!< Stop position of the current envelope. */ - const int16_t lowSubband, /* lowSubband */ - float *pGainTemp, - const int16_t code ); - -void procTecTfa_TBE( - float *hb_synth, - float *gain, - const int16_t flat_flag, - const int16_t last_core, - const int16_t L_subfr, - const int16_t code ); - -void resetTecEnc( - TEC_ENC_HANDLE hTecEnc, - const int16_t flag ); - -void calcHiEnvLoBuff( - const int16_t noCols, - const int16_t *pFreqBandTable, /* i : freqbandTable */ - const int16_t nSfb, /* i : Number of scalefactors */ - float **pYBuf, - float *loBuf, - float *hiTempEnv ); - -void calcLoEnvCheckCorrHiLo( - const int16_t noCols, - const int16_t *pFreqBandTable, /* i : freqbandTable */ - float *loBuf, - float *loTempEnv, - float *loTempEnv_ns, - float *hiTempEnv, - int16_t *corr_flag /* o : 0 for original, 1 for TEC */ -); - - -void tecEnc_TBE( - int16_t *corrFlag, - const float *voicing, - const int16_t coder_type ); - -void set_TEC_TFA_code( - const int16_t corrFlag, - int16_t *tec_flag, - int16_t *tfa_flag ); - -float Damping_fact_flt( - const int16_t coder_type, /* i : ACELP core coder type */ - const int16_t nbLostCmpt, /* i : compt for number of consecutive lost frame */ - int16_t last_good, /* i : class of last good received frame */ - float stab_fac, /* i : LSF stability factor */ - float *lp_gainp, /* i/o: low passed pitch gain used for concealment */ - const int16_t core /* i : current core: ACELP = 0, TCX20 = 1, TCX10 = 2 */ -); - -float getLevelSynDeemph( - const float h1Init[], /* i : input value or vector to be processed */ - const float A[], /* i : LPC coefficients */ - const int16_t lenLpcExc, /* i : length of the LPC excitation buffer */ - const float preemph_fac, /* i : preemphasis factor */ - const int16_t numLoops /* i : number of loops */ -); - -void genPlcFiltBWAdap( - const int32_t sr_core, /* i : core sampling rate */ - float *lpFiltAdapt, /* o : filter coefficients for filtering codebooks in case of flc */ - const int16_t type, /* i : type of filter, either 0 : lowpass or 1 : highpass */ - const float alpha /* i : fade out factor [0 1) used decrease filter tilt */ -); - -void highPassFiltering( - const int16_t last_good, /* i : last classification type */ - const int16_t L_buffer, /* i : buffer length */ - float exc2[], /* i/o: unvoiced excitation before the high pass filtering */ - const float hp_filt[], /* i : high pass filter coefficients */ - const int16_t l_fir_fer /* i : high pass filter length */ -); - -int16_t GetPLCModeDecision( - Decoder_State *st /* i/o: decoder memory state pointer */ -); - -void addBassPostFilter( - const float *harm_timeIn, - const int16_t samplesToProcess, - float **rAnalysis, - float **iAnalysis, - HANDLE_CLDFB_FILTER_BANK cldfb ); - -ivas_error TonalMDCTConceal_Init_ivas( - TonalMDCTConcealPtr hTonalMDCTConc, - const uint16_t samplesPerBlock, - const uint16_t nSamplesCore, - const uint16_t nScaleFactors, - TCX_CONFIG_HANDLE hTcxCfg ); - -void TonalMDCTConceal_SaveFreqSignal_ivas( - TonalMDCTConcealPtr hTonalMDCTConc, - const float *mdctSpectrum, - const uint16_t numSamples, - const uint16_t nNewSamplesCore, - const float *scaleFactors, - const int16_t infoIGFStartLine ); - -void TonalMDCTConceal_UpdateState_ivas( - TonalMDCTConcealPtr hTonalMDCTConc, - const int16_t numSamples, - const float pitchLag, - const int16_t badBlock, - const int16_t tonalConcealmentActive ); - -void TonalMDCTConceal_SaveTimeSignal_ivas( - TonalMDCTConcealPtr hTonalMDCTConc, - float *timeSignal, - const int16_t numSamples ); - -void TonalMDCTConceal_Detect_ivas( - const TonalMDCTConcealPtr hTonalMDCTConc, /*IN */ - const float pitchLag, /*IN */ - int16_t *umIndices, /*OUT*/ - const PsychoacousticParameters *psychParamsCurrent /*IN*/ -); - -void TonalMDCTConceal_Apply_ivas( - TonalMDCTConcealPtr hTonalMDCTConc, /*IN */ - float *mdctSpectrum, /*OUT*/ - const PsychoacousticParameters *psychParamsCurrent /*IN*/ -); - -void TonalMDCTConceal_InsertNoise_ivas( - const TonalMDCTConcealPtr hTonalMDCTConc, /*IN */ - float *mdctSpectrum, /*OUT*/ - const int16_t tonalConcealmentActive, - int16_t *pSeed, /*IN/OUT*/ - const float tiltCompFactor, - const float crossfadeGain, - const float concealment_noise[L_FRAME48k], - const float cngLevelBackgroundTrace_bfi, - const int16_t crossOverFreq ); - -void DetectTonalComponents_flt( - uint16_t indexOfTonalPeak[], - uint16_t lowerIndex[], - uint16_t upperIndex[], - uint16_t *pNumIndexes, - const float lastPitchLag, - const float currentPitchLag, - const float lastMDCTSpectrum[], - const float scaleFactors[], - const float secondLastPowerSpectrum[], - const uint16_t nSamples, - const uint16_t nSamplesCore, - float floorPowerSpectrum, - const PsychoacousticParameters *psychParamsCurrent ); - -void RefineTonalComponents_flt( - uint16_t indexOfTonalPeak[], - uint16_t lowerIndex[], - uint16_t upperIndex[], - float phaseDiff[], - float phases[], - uint16_t *pNumIndexes, - const float lastPitchLag, - const float currentPitchLag, - const float lastMDCTSpectrum[], - const float scaleFactors[], - const float secondLastPowerSpectrum[], - const uint16_t nSamples, - const uint16_t nSamplesCore, - float floorPowerSpectrum, - const PsychoacousticParameters *psychParamsCurrent ); - -ivas_error PsychoacousticParameters_Init( - const int32_t sr_core, /* i : sampling rate of core-coder */ - const int16_t nBins, /* i : Number of bins (spectral lines) */ - const int8_t nBands, /* i : Number of spectrum subbands */ - const int16_t isTCX20, /* i : Flag indicating if the subband division is for TCX20 or TCX10 */ - const int16_t isWarped, /* i : Flag indicating if the scale is linear or warped */ - PsychoacousticParameters *pPsychParams ); - -void concealment_init( - const int16_t L_frameTCX, - T_PLCInfo_HANDLE hPlcInfo ); - -void concealment_decode( - const int16_t core, - float *invkoef, - T_PLCInfo_HANDLE hPlcInfo ); - -void concealment_update( - const int16_t bfi, - const int16_t core, - const int16_t harmonic, - float *invkoef, - T_PLCInfo_HANDLE hPlcInfo ); - -void concealment_update2( - const float *outx_new, - T_PLCInfo_HANDLE hPlcInfo, - const int16_t L_frameTCX ); - -void concealment_signal_tuning( - Decoder_State *st, - const int16_t bfi, - float *outx_new, - const int16_t past_core_mode ); - -void waveform_adj2( - T_PLCInfo_HANDLE hPlcInfo, - float *overlapbuf, - float *outx_new, - const int16_t delay, - const int16_t bfi_cnt, - const int16_t bfi ); - -float SFM_Cal( - const float fcoef[], - const int16_t n ); - -void set_state_ivas( - int16_t *state, - const int16_t num, - const int16_t N ); - -int16_t RFFTN( - float *afftData, - const float *trigPtr, - const int16_t len, - const int16_t isign ); - -void DoFFT( - float *re2, - float *im2, - const int16_t length ); - -/*! r: flag indicating a valid bitrate */ -int16_t is_EVS_bitrate( - const int32_t ivas_total_brate, /* i : EVS total bitrate */ - int16_t *Opt_AMR_WB /* i : AMR-WB IO flag */ -); - -int16_t getTcxonly_ivas( - const int16_t element_mode, /* i : IVAS element mode */ - const int32_t total_brate, /* i : total bitrate */ - const int16_t MCT_flag, /* i : hMCT handle allocated (1) or not (0)*/ - const int16_t is_ism_format /* i : flag indicating ISM format */ -); - -int16_t getTnsAllowed( - const int32_t total_brate, /* i : total bitrate */ - const int16_t igf, /* i : flag indicating IGF activity*/ - const int16_t element_mode /* i : IVAS element mode */ -); - -int16_t getCtxHm( - const int16_t element_mode, /* i : IVAS element mode */ - const int32_t total_brate, /* i : total bitrate */ - const int16_t rf_flag /* i : flag to signal the RF mode */ -); - -int16_t getResq( - const int32_t total_brate /* i : total bitrate */ -); - -int16_t getMdctWindowLength( - const int16_t fscale ); - -int16_t sr2fscale( - const int32_t sr_core /* i : internal sampling rate */ -); - -int32_t getCoreSamplerateMode2_flt( - const int16_t element_mode, /* i : IVAS element mode */ - const int32_t total_brate, /* i : total bitrate */ - const int16_t bwidth, /* i : audio bandwidth */ - const int16_t flag_ACELP16k, /* i : ACELP@16kHz flag */ - const int16_t rf_mode, /* i : flag to signal the RF mode */ - const IVAS_FORMAT is_ism_format /* i : flag indicating ISM format */ -); - -float getTcxBandwidth_flt( - const int16_t bwidth /* i : audio bandwidth */ -); - - -int16_t getCnaPresent( - const int16_t element_mode, /* i : element mode */ - const int32_t element_brate, /* i : element bitrate */ - const int32_t total_brate, /* i : total bitrate */ - const int16_t bwidth /* i : audio bandwidth */ -); - -int16_t getTcxLtp( - const int32_t sr_core /* i : internal sampling rate */ -); - -int16_t initPitchLagParameters( - const int32_t sr_core, /* i : internal sampling rate */ - int16_t *pit_min, - int16_t *pit_fr1, - int16_t *pit_fr1b, - int16_t *pit_fr2, - int16_t *pit_max ); - -void attenuateNbSpectrum( - const int16_t L_frame, - float *spectrum ); - -void SetModeIndex( - Encoder_State *st, /* i : Encoder state */ - const int32_t last_total_brate, /* i : last total bitrate */ - const int16_t last_element_mode, /* i : last IVAS element mode */ - const int16_t MCT_flag /* i : hMCT handle allocated (1) or not (0) */ -); - -int16_t getNumTcxCodedLines( - const int16_t bwidth /* i : audio bandwidth */ -); - -int16_t getTcxLpcShapedAri( - const int32_t total_brate, /* i : total bitrate */ - const int16_t rf_mode, /* i : flag to signal the RF mode */ - const int16_t element_mode /* i : IVAS element mode */ -); - -void IGFEncApplyMono( - Encoder_State *st, /* i : Encoder state */ - const int16_t igfGridIdx, /* i : IGF grid index */ - float *pMDCTSpectrum, /* i/o: MDCT spectrum */ - float *pPowerSpectrum, /* i/o: MDCT^2 + MDST^2 spectrum, or estimate */ - const int16_t isTCX20, /* i : flag indicating if the input is TCX20 or TCX10/2xTCX5 */ - const int16_t isTNSActive, /* i : flag indicating if the TNS is active */ - const int16_t sp_aud_decision0, /* i : first stage switching decision */ - const int16_t vad_hover_flag /* i : VAD hangover flag */ -); - -void IGFEncApplyStereo( - STEREO_MDCT_ENC_DATA_HANDLE hStereoMdct, /* i/o: MDCT stereo encoder structure */ - int16_t ms_mask[2][MAX_SFB], /* i : bandwise MS mask */ - const IGF_ENC_INSTANCE_HANDLE hIGFEnc[CPE_CHANNELS], /* i : instance handle of IGF Encoder */ - const int16_t igfGridIdx, /* i : IGF grid index */ - Encoder_State *sts[CPE_CHANNELS], /* i : Encoder state */ - float *pPowerSpectrum[CPE_CHANNELS], /* i/o: MDCT^2 + MDST^2 spectrum, or estimate */ - float *pPowerSpectrumMsInv[CPE_CHANNELS][NB_DIV], /* i/o: inverse power spectrum */ - float *inv_spectrum[CPE_CHANNELS][NB_DIV], /* i : inverse spectrum */ - const int16_t frameno, /* i : flag indicating index of current subframe */ - const int16_t sp_aud_decision0, /* i : sp_aud_decision0 */ - const int32_t element_brate, /* i : element bitrate */ - const int16_t mct_on /* i : flag mct block (1) or stereo (0) */ -); - - -void IGFEncResetTCX10BitCounter( - const IGF_ENC_INSTANCE_HANDLE hIGFEnc /* i : instance handle of IGF Encoder */ -); - -ivas_error IGF_Reconfig( - IGF_ENC_INSTANCE_HANDLE *hIGFEnc, /* i/o: instance handle of IGF Encoder */ - const int16_t igf, /* i : IGF on/off */ - const int16_t reset, /* i : reset flag */ - const int32_t brate, /* i : bitrate for configuration */ - const int16_t bwidth, /* i : signal bandwidth */ - const int16_t element_mode, /* i : IVAS element mode */ - const int16_t rf_mode /* i : flag to signal the RF mode */ -); - -void IGFEncSetMode( - const IGF_ENC_INSTANCE_HANDLE hIGFEnc, /* i : instance handle of IGF Encoder */ - const int32_t total_brate, /* i : encoder total bitrate */ - const int16_t bwidth, /* i : encoder audio bandwidth */ - const int16_t element_mode, /* i : IVAS element mode */ - const int16_t rf_mode /* i : flag to signal the RF mode */ -); - -/*! r: number of bits written per frame */ -int16_t IGFEncWriteBitstream( - const IGF_ENC_INSTANCE_HANDLE hIGFEnc, /* i : instance handle of IGF Encoder */ - BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ - int16_t *pBitOffset, /* i : ptr to bitOffset counter */ - const int16_t igfGridIdx, /* i : igf grid index see declaration of IGF_GRID_IDX for details */ - const int16_t isIndepFlag /* i : if 1 frame is independent, 0 = frame is coded with data from previous frame */ -); - -/*! r: total number of bits written */ -int16_t IGFEncWriteConcatenatedBitstream( - const IGF_ENC_INSTANCE_HANDLE hIGFEnc, /* i : instance handle of IGF Encoder */ - BSTR_ENC_HANDLE hBstr /* i/o: encoder bitstream handle */ -); - -void IGFDecApplyMono_flt( - const IGF_DEC_INSTANCE_HANDLE hIGFDec, /* i : instance handle of IGF Decoder */ - float *spectrum, /* i/o: MDCT spectrum */ - const int16_t igfGridIdx, /* i : in case of CELP->TCX switching, use 1.25 framelength */ - const int16_t bfi, /* i : frame loss == 1, frame good == 0 */ - const int16_t element_mode /* i : IVAS element mode */ -); - -void IGFDecCopyLPCFlatSpectrum_flt( - const IGF_DEC_INSTANCE_HANDLE hIGFDec, /* i/o: instance handle of IGF Decoder */ - const float *pSpectrumFlat, /* i : LPC flattend spectrum from TCX dec */ - const int16_t igfGridIdx /* i : IGF grid index */ -); - -void IGFDecReadData_flt( - const IGF_DEC_INSTANCE_HANDLE hIGFDec, /* i/o: instance handle of IGF Deccoder */ - Decoder_State *st, /* i : decoder state */ - const int16_t igfGridIdx, /* i : in case of CELP->TCX switching, use 1.25 framelength */ - const int16_t isIndepFrame /* i : if 1: arith dec force reset, if 0: no reset */ -); - -/*! r: return igfAllZero flag indicating if no envelope is transmitted */ -int16_t IGFDecReadLevel_flt( - const IGF_DEC_INSTANCE_HANDLE hIGFDec, /* i/o: instance handle of IGF Deccoder */ - Decoder_State *st, /* i : decoder state */ - const int16_t igfGridIdx, /* i : in case of CELP->TCX switching, use 1.25 framelength */ - const int16_t isIndepFrame /* i : if 1: arith dec force reset, if 0: no reset */ -); - -void IGFDecRestoreTCX10SubFrameData_flt( - const IGF_DEC_INSTANCE_HANDLE hIGFDec, /* o : instance handle of IGF Decoder */ - const int16_t subFrameIdx /* i : index of subframe */ -); - -void init_igf_dec_flt( - IGF_DEC_INSTANCE_HANDLE hIGFDec /* i/o: IGF decoder handle */ -); - -void IGFDecSetMode_flt( - const IGF_DEC_INSTANCE_HANDLE hIGFDec, /* o : instance handle of IGF Decoder */ - const int32_t total_brate, /* i : bitrate */ - const int16_t bwidth, /* i : audio bandwidth */ - const int16_t element_mode, /* i : IVAS element mode */ - const int16_t defaultStartLine, /* i : default start subband index */ - const int16_t defaultStopLine, /* i : default stop subband index */ - const int16_t rf_mode /* i : flag to signal the RF mode */ -); - -void IGFDecStoreTCX10SubFrameData_flt( - const IGF_DEC_INSTANCE_HANDLE hIGFDec, /* i/o: instance handle of IGF Decoder */ - const int16_t subFrameIdx /* i : index of subframe */ -); - -void IGFDecUpdateInfo_flt( - const IGF_DEC_INSTANCE_HANDLE hIGFDec, /* i/o: instance handle of IGF Decoder */ - const int16_t subFrameIdx, /* i : subframe index */ - const int16_t igfGridIdx /* i : IGF grid index */ -); - -/*! r: error value: 0 -> error, 1 -> ok */ -int16_t IGFCommonFuncsIGFConfiguration_flt( - const int32_t total_brate, /* i : bitrate in bs e.g. 9600 for 9.6kbs */ - const int16_t bwidth, /* i : audio bandwidth */ - const int16_t element_mode, /* i : IVAS element mode */ - H_IGF_INFO hIGFInfo, /* o : IGF info handle */ - const int16_t rf_mode /* i : flag to signal the RF mode */ -); - -/*! r: error value: 0 -> error, 1 -> ok */ -int16_t IGFCommonFuncsIGFGetCFTables_flt( - const int32_t total_brate, /* i : bitrate in bs e.g. 9600 for 9.6kbs */ - const int16_t bwidth, /* i : audio bandwidth */ - const int16_t element_mode, /* i : element mode */ - const int16_t rf_mode, /* i : flag to signal the RF mode */ - const uint16_t **cf_se00, /* i : CF table for t == 0 and f == 0 */ - const uint16_t **cf_se01, /* i : CF table for t == 0 and f == 1 */ - int16_t *cf_off_se01, /* o : offset for CF table above */ - const uint16_t **cf_se02, /* i : CF tables for t == 0 and f >= 2 */ - const int16_t **cf_off_se02, /* o : offsets for CF tables above */ - const uint16_t **cf_se10, /* i : CF table for t == 1 and f == 0 */ - int16_t *cf_off_se10, /* o : offset for CF table above */ - const uint16_t **cf_se11, /* i : CF tables for t == 1 and f >= 1 */ - const int16_t **cf_off_se11 /* o : offsets for CF tables above */ -); - -/*! r: multiplication factor */ -int16_t IGF_ApplyTransFac_flt( - const int16_t val, /* i : input value for multiplication, Q15 */ - const float transFac /* i : multiplicator for variable val, Q14: 1.25f=0x5000, 1.0f=0x4000, 0.5f=0x2000 */ -); - -/*! r: return bitrate index */ -int16_t IGF_MapBitRateToIndex_flt( - const int32_t brate, /* i : bitrate */ - const int16_t bwidth, /* i : audio bandwidth */ - const int16_t element_mode, /* i : element mode */ - const int16_t rf_mode /* i : flag to signal the RF mode */ -); - - -void IGFSCFDecoderOpen_ivas( - IGFSCFDEC_INSTANCE_HANDLE hPublicData, /* i : handle to public data */ - H_IGF_INFO hIgfInfo, /* i : IGF info handle */ - const int32_t total_brate, - const int16_t bwidth, - const int16_t element_mode, - const int16_t rf_mode ); - -void IGFSCFDecoderReset_ivas( - IGFSCFDEC_INSTANCE_HANDLE hPublicData /* i : handle to public data or NULL in case there was no instance created */ -); - -void IGFSCFDecoderDecode_ivas( - IGFSCFDEC_INSTANCE_HANDLE hPublicData, /* i : handle to public data or NULL in case there was no instance created */ - Decoder_State *st, /* i/o: pointer to decoder state */ - int16_t *sfe, /* o : ptr to an array which will contain the decoded quantized coefficients */ - const int16_t igfGridIdx, /* i : igf grid index see declaration of IGF_GRID_IDX for details */ - const int16_t indepFlag /* i : if 1 on input the decoder will be forced to reset, - if 0 on input the decoder will be forced to encode without a reset */ -); - -/*! r: offset value */ -int16_t tbe_celp_exc_offset_flt( - const int16_t T0, /* i : Integer pitch */ - const int16_t T0_frac /* i : Fractional part of the pitch */ -); - -void blend_subfr2_flt( - float *sigIn1, /* i : input signal for fade-out */ - float *sigIn2, /* i : input signal for fade-in */ - float *sigOut /* o : output signal */ -); - -void init_tcx_window_cfg( - TCX_CONFIG_HANDLE hTcxCfg, /* i : TCX Config handle */ - const int32_t sr_core, /* i : SR core */ - const int32_t input_Fs, /* i : input/output SR */ - const int16_t L_frame, /* i : L_frame at sr_core */ - const int16_t L_frameTCX, /* i : L_frame at i/o SR */ - const int16_t encoderLookahead_enc, /* i : encoder LA at sr_core */ - const int16_t encoderLookahead_FB, /* i : encoder LA at i/o SR */ - const int16_t mdctWindowLength, /* i : window length at sr_core */ - const int16_t mdctWindowLengthFB, /* i : window length at i/o SR */ - const int16_t element_mode /* i : mode of CPE/SCE */ -); - -void init_tcx_cfg( - TCX_CONFIG_HANDLE hTcxCfg, - const int32_t total_brate, - const int32_t sr_core, - const int32_t input_Fs, - const int16_t L_frame, - const int16_t bwidth, - const int16_t L_frameTCX, - const int16_t fscale, - const int16_t encoderLookahead_enc, - const int16_t encoderLookahead_FB, - const float preemph_fac, - const int16_t tcxonly, - const int16_t rf_mode, - const int16_t igf, - const int16_t infoIGFStopFreq, - const int16_t element_mode, - const int16_t ini_frame, - const int16_t MCT_flag /* i : hMCT handle allocated (1) or not (0) */ -); - -#endif diff --git a/lib_com/prot_fx.h b/lib_com/prot_fx.h index 13ab9bebda58d7f9eb2fcdd4e174590c30d9f7fd..bb0ac1c90d133258980f685b4a2f285a92238892 100644 --- a/lib_com/prot_fx.h +++ b/lib_com/prot_fx.h @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other @@ -49,14 +49,59 @@ #include "ivas_cnst.h" #include "stat_enc.h" #include "stat_dec.h" +#include "stat_com.h" #include "ivas_stat_enc.h" #include "ivas_stat_dec.h" +#include "ivas_stat_com.h" #include "ivas_error.h" #include "ivas_error_utils.h" #include "complex_basop.h" #define TCX_IMDCT_SCALE 15 #define TCX_IMDCT_HEADROOM 1 + +/*----------------------------------------------------------------------------------* + * Prototypes of global macros + *----------------------------------------------------------------------------------*/ + +#ifndef min +#define min( x, y ) ( ( x ) < ( y ) ? ( x ) : ( y ) ) +#endif + +#ifndef max +#define max( x, y ) ( ( x ) > ( y ) ? ( x ) : ( y ) ) +#endif + +#define log_base_2( x ) ( (double) log( (double) ( x ) ) * 1.4426950408889634074f ) +#define round_f( x ) ( ( ( x ) > 0 ) ? (int32_t) ( ( x ) + 0.5f ) : ( -(int32_t) ( ( -x ) + 0.5f ) ) ) + +#ifndef ABSVAL +#define ABSVAL( a ) ( ( a ) >= 0 ? ( a ) : ( -( a ) ) ) +#endif + +#ifndef SQR +#define SQR( a ) ( ( a ) * ( a ) ) +#endif + +#ifndef SWAP +#define SWAP( a, b ) \ + { \ + tempr = ( a ); \ + ( a ) = ( b ); \ + ( b ) = tempr; \ + } +#endif + +#ifndef swap +#define swap( x, y, type ) \ + { \ + type u__p; \ + u__p = x; \ + x = y; \ + y = u__p; \ + } +#endif + /*================================================================================*/ /* conversion functions: */ /*================================================================================*/ @@ -128,7 +173,7 @@ Word32 sum_l_fx( const Word32 *vec, /* i : input vector */ const Word16 lvec /* i : length of input vector */ ); -Word16 norm_ul( UWord32 UL_var1 ); + Word32 Mult_32_16( Word32 a, @@ -206,12 +251,23 @@ void Scale_sig( const Word16 exp0 /* i : exponent: x = round(x << exp) Qx ?exp */ ); +void scale_sig( + Word16 x[], /* i/o: signal to scale Qx */ + const Word16 lg, /* i : size of x[] Q0 */ + const Word16 exp0 /* i : exponent: x = round(x << exp) Qx ?exp */ +); + // tools.c Word32 sum2_fx( /* o : sum of all squared vector elements Q(2x+1)*/ const Word16 *vec, /* i : i vector Qx*/ const Word16 lvec /* i : length of i vector */ ); +Word64 sum2_fx_no_sat( /* o : sum of all squared vector elements Q(2x)*/ + const Word16 *vec, /* i : i vector Qx*/ + const Word16 lvec /* i : length of i vector */ +); + Word16 sign_fx( const Word32 x /* i : input value of x */ ); @@ -423,6 +479,16 @@ void hq_generic_decoding_fx( const Word16 hq_generic_exc_clas, /* i : bwe excitation class */ const Word16 *R ); +void hq_generic_decoding_ivas_fx( + const Word16 HQ_mode, /* i : HQ mode */ + Word32 *coeff_out1_fx, /* i/o: BWE i & temporary buffer */ + const Word16 *hq_generic_fenv_fx, /* i : SWB frequency envelopes */ + Word32 *coeff_out_fx, /* o : SWB signal in MDCT domain */ + const Word16 hq_generic_offset, /* i : frequency offset for representing hq generic*/ + Word16 *prev_L_swb_norm, /* i/o: last normalize length */ + const Word16 hq_generic_exc_clas, /* i : bwe excitation class */ + const Word16 *R ); + void save_old_syn_fx( const Word16 L_frame, /* i : frame length */ const Word16 syn[], /* i : ACELP synthesis */ @@ -695,6 +761,19 @@ void hq_bwe_fx( const Word16 num_env_bands, const Word16 *R ); +void hq_bwe_ivas_fx( + const Word16 HQ_mode, /* i : HQ mode */ + Word32 *coeff_out1, /* i/o: BWE i & temporary buffer */ + const Word16 *hq_generic_fenv, /* i : SWB frequency envelopes */ + Word32 *coeff_out, /* o : SWB signal in MDCT domain */ + const Word16 hq_generic_offset, /* i : frequency offset for representing hq generic bwe*/ + Word16 *prev_L_swb_norm, /*i/o : last normalize length */ + const Word16 hq_generic_exc_clas, /* i : bwe excitation class */ + const Word16 *sfm_end, /* i : End of bands */ + const Word16 num_sfm, + const Word16 num_env_bands, + const Word16 *R ); + void hq_wb_nf_bwe_fx( const Word16 *coeff_fx, /* i : coded/noisefilled normalized spectrum */ const Word16 is_transient, @@ -802,6 +881,14 @@ Word16 lpc2lsp_fx( Word16 *old_freq, Word16 order ); +#ifdef FIX_ISSUE_1165 +Word16 lpc2lsp_ivas_fx( + Word32 *a, + Word16 *freq, + Word16 *old_freq, + Word16 order ); +#endif + void lsp2lpc_fx( Word16 *a, Word16 *freq, @@ -1065,6 +1152,12 @@ void lsp_weights_fx( Word16 Order, Word16 *Qout ); +void lsp_weights_ivas_fx( + Word16 lsp_nq_fx[], + Word16 w[], + Word16 Order, + Word16 *Qout ); + void space_lsfs_fx( Word16 *lsfs, /* i/o: Line spectral frequencies */ const Word16 order /* i : order of LP analysis */ @@ -1150,6 +1243,7 @@ Word16 E_LPC_lsp_unweight( ); Word32 E_LPC_schur( Word32 r[] /*Qr*/, Word16 reflCoeff[] /*Q15*/, Word32 epsP[] /*Qr*/, const Word16 m ); +Word32 E_LPC_schur_ivas( Word32 r[] /*Qr*/, Word16 reflCoeff[] /*Q15*/, const Word16 m ); void E_LPC_a_lsf_isf_conversion( Word16 *lpcCoeffs /*Qx*/, Word16 *lsf /*15Q16*/, const Word16 *old_lsf /*15Q16*/, Word16 lpcOrder, Word8 lpcRep /*Q0*/ ); @@ -1229,7 +1323,8 @@ UWord16 get_indice_1_fx( /* o : value of the indice */ ); void reset_indices_enc_fx( - BSTR_ENC_HANDLE hBstr /* i/o: encoder state structure */ + BSTR_ENC_HANDLE hBstr, /* i/o: encoder state structure */ + const Word16 max_num_indices /* i : max number of indices */ ); void reset_indices_dec_fx( @@ -1273,12 +1368,6 @@ Word16 BRATE2IDX16k_fx( Word32 brate ); Word32 BIT_ALLOC_IDX_fx( Word32 brate, Word16 ctype, Word16 sfrm, Word16 tc ); Word32 BIT_ALLOC_IDX_16KHZ_fx( Word32 brate, Word16 ctype, Word16 sfrm, Word16 tc ); -Word16 read_indices_fx( /* o : 1 = OK, 0 = something wrong */ - Decoder_State *st_fx, /* i/o: decoder state structure */ - FILE *file, /* i : bitstream file */ - Word16 rew_flag /* i : rewind flag (rewind file after reading) */ -); - Word16 read_indices_mime( /* o : 1 = reading OK, 0 = problem */ Decoder_State *st, /* i/o: decoder state structure */ FILE *file, /* i : bitstream file */ @@ -1453,6 +1542,13 @@ void fft_rel_fx( const Word16 n, /* i : vector length */ const Word16 m /* i : log2 of vector length */ ); +void fft_rel_16_32fx( + Word16 x[], /* i/o: input/output vector Qx */ + Word16 *q_x, /* extra scaling added on speech buffer*/ + Word16 i_subfr, + const Word16 n, /* i : vector length */ + const Word16 m /* i : log2 of vector length */ +); void fft_rel_fx32( Word32 x[], /* i/o: i /output vector */ const Word16 n, /* i : vector length */ @@ -1683,13 +1779,11 @@ Word16 Enr_1_Az_fx( /* o : impulse response energy Q3 const Word16 Aq[], /* i : LP filter coefs Qx based on the fact that Aq[0] == 1.0 */ const Word16 len /* i : impulse response length Q0 */ ); -#ifdef BASOP_NOGLOB Word16 Enr_1_Az_fx_o( /* o : impulse response energy Q3 */ const Word16 Aq[], /* i : LP filter coefs Qx based on the fact that Aq[0] == 1.0 */ const Word16 len, /* i : impulse response length Q0 */ Flag *Overflow_out /* o : propagating the Overflow flag to upper level */ ); -#endif // gs_gains_fx.c void Ener_per_band_comp_fx( @@ -2374,6 +2468,20 @@ void syn_filt_fx( const Word16 update_m /* i : update memory flag Q0 : 0 --> no memory update */ ); /* 1 --> update of memory */ +void syn_filt_fx32( + const Word16 a_e, /* i : exp of LP coeffs Q0 */ + const Word32 a[], /* i : LP filter coefficients Q12 */ + const Word16 m, /* i : order of LP filter Q0 */ + const Word32 x[], /* i : input signal Qx */ + const Word16 x_e, /* i : input signal Qx */ + Word32 y[], /* o : output signal Qx */ + Word16 *y_e, /* o : output signal Qx */ + const Word16 l, /* i : size of filtering Q0 */ + Word32 mem[], /* i/o: initial filter states Qx */ + Word16 *mem_e, /* i/o: initial filter states Qx */ + const Word16 update_m /* i : update memory flag Q0 : 0 --> no memory update */ +); + void E_UTIL_synthesis( const Word16 shift, const Word16 a[], const Word16 x[], Word16 y[], const Word16 lg, Word16 mem[], const Word16 update, const Word16 m ); void E_UTIL_synthesis_fx( const Word16 shift, const Word32 a[], const Word32 x[], Word32 y[], const Word16 lg, Word32 mem[], const Word16 update, const Word16 m ); @@ -2727,6 +2835,12 @@ void time_envelop_shaping_fx( const Word16 L, /* i : frame length */ Word16 *Q_synth ); +void time_envelop_shaping_ivas_fx( + Word16 werr[], /* i/o: SHB synthesis Q_synth*/ + Word32 SWB_tenv[], /* i/o: frequency envelope Q15*/ + const Word16 L, /* i : frame length */ + Word16 *Q_synth ); + void time_reduce_pre_echo_fx( const Word16 *synth, /* i : ACELP core synthesis Q_syn*/ Word16 *error, /* i/o: SHB BWE synthesis Q0*/ @@ -2843,6 +2957,11 @@ void Calc_rc0_h( Word16 *rc0 /* o : 1st parcor */ ); +void Calc_rc0_h_ivas_enc_fx( + Word16 *h, /* i : impulse response of composed filter */ + Word16 *rc0 /* o : 1st parcor */ +); + void PostShortTerm_fx( Word16 *sig_in, /* i : i signal (pointer to current subframe */ Word16 *lpccoeff, /* i : LPC coefficients for current subframe */ @@ -2957,7 +3076,7 @@ void GenShapedSHBExcitation_fx( void GenShapedSHBExcitation_ivas_enc_fx( Word16 *excSHB, /* o : synthesized shaped shb excitation Q_bwe_exc*/ const Word16 *lpc_shb, /* i : lpc coefficients Q12*/ - Word16 *White_exc16k_FB, /* o : white excitation for the Fullband extension Q_bwe_exc */ + Word16 *White_exc16k_FB, /* o : white excitation for the Fullband extension Q_bwe_exc_fb */ Word32 *mem_csfilt, /* i/o: memory */ Word16 *mem_genSHBexc_filt_down_shb, /* i/o: memory */ Word16 *state_lpc_syn, /* i/o: memory */ @@ -2982,21 +3101,21 @@ void GenShapedSHBExcitation_ivas_enc_fx( Word16 n_mem2, /* i : n_mem2 scale factor to adjust 24.4/32kbps memories */ Word16 prev_Q_bwe_syn, /* i : st_fx->prev_Q_bwe_syn */ const Word32 bitrate, - const Word16 prev_bfi -#if 1 // def ADD_IVAS_TBE_CODE - , /* i : previous frame was concealed */ - const Word16 element_mode, /* i : element mode */ - const Word16 flag_ACELP16k, /* i : ACELP@16kHz flag */ - Word16 *nlExc16k, /* i/o: NL exc for IC-BWE */ - Word16 *mixExc16k, /* i/o: exc spreading for IC-BWE */ - const Word32 extl_brate, /* i : extension layer bitarte */ - const Word16 MSFlag, /* i : Multi Source flag */ - Word16 EnvSHBres_4k[], /* i/o: TD envelope of the SHB residual signal */ + const Word16 prev_bfi, + const Word16 element_mode, /* i : element mode */ + const Word16 flag_ACELP16k, /* i : ACELP@16kHz flag */ + Word16 *nlExc16k, /* i/o: NL exc for IC-BWE */ + Word16 *nlExc16k_e, /* i/o: exp of nlExc16k */ + Word16 *mixExc16k, /* i/o: exc spreading for IC-BWE */ + Word16 *mixExc16k_e, /* i/o: exp of mixExc16k_fx */ + const Word32 extl_brate, /* i : extension layer bitarte */ + const Word16 MSFlag, /* i : Multi Source flag */ + Word16 EnvSHBres_4k[], /* i/o: TD envelope of the SHB residual signal */ + Word16 Q_EnvSHBres_4k, Word32 *prev_pow_exc16kWhtnd, /* i/o: power of the LB excitation signal in the previous frame */ Word16 *prev_mix_factor, /* i/o: mixing factor in the previous frame */ Word16 *Env_error, /* o : error in SHB residual envelope modelling*/ Word16 Env_error_part[] /* o : per-segment error in SHB residual envelope modelling */ -#endif ); void GenShapedSHBExcitation_ivas_dec_fx( @@ -3584,6 +3703,16 @@ Word16 ITF_Detect_fx( Word32 const pSpectrum[], Word16 *curr_order, Word16 Q ); +Word16 ITF_Detect_ivas_fx( Word32 const pSpectrum[], + const Word16 startLine, + const Word16 stopLine, + const Word16 maxOrder, + Word16 *A, + Word16 *Q_A, + Word16 *predictionGain, + Word16 *curr_order, + Word16 Q ); + void ITF_Apply_fx( Word32 spectrum[], Word16 startLine, Word16 stopLine, @@ -3668,58 +3797,64 @@ gp_clips_fx.c /========================================================================================================*/ void init_gp_clip_fx( - Word16 mem[] /* o : memory of gain of pitch clipping algorithm */ + Word16 mem[] /* o : memory of gain of pitch clipping algorithm [2.56x,Q14,Q8,Q0,Q14,Q14]*/ ); Word16 gp_clip_fx( - const Word16 element_mode, /* i : element mode */ - const Word32 core_brate, /* i : core bitrate */ - const Word16 *voicing, /* i : normalized correlations (from OL pitch) */ - const Word16 i_subfr, /* i : subframe index */ - const Word16 coder_type, /* i : type of coder */ - const Word16 xn[], /* i : target vector */ - Word16 mem[], /* i/o: memory of gain of pitch clipping algorithm */ + const Word16 element_mode, /* i : element mode Q0*/ + const Word32 core_brate, /* i : core bitrate Q0*/ + const Word16 *voicing, /* i : normalized correlations (from OL pitch) Q15*/ + const Word16 i_subfr, /* i : subframe index Q0*/ + const Word16 coder_type, /* i : type of coder Q0*/ + const Word16 xn[], /* i : target vector Q_new*/ + Word16 mem[], /* i/o: memory of gain of pitch clipping algorithm [2.56x,Q14,Q8,Q0,Q14,Q14]*/ const Word16 Q_new /* i : scaling factor */ ); void gp_clip_test_isf_fx( - const Word16 element_mode, /* i : element mode */ - const Word32 core_brate, /* i : core bitrate */ - const Word16 isf[], /* i : isf values (in frequency domain) */ - Word16 mem[], /* i/o: memory of gain of pitch clipping algorithm */ - const Word16 Opt_AMR_WB /* i : flag indicating AMR-WB IO mode */ + const Word16 element_mode, /* i : element mode Q0*/ + const Word32 core_brate, /* i : core bitrate Q0*/ + const Word16 isf[], /* i : isf values (in frequency domain) Q2.56*/ + Word16 mem[], /* i/o: memory of gain of pitch clipping algorithm Q15*/ + const Word16 Opt_AMR_WB /* i : flag indicating AMR-WB IO mode Q0*/ ); void gp_clip_test_gain_pit_fx( - const Word16 element_mode, /* i : element mode */ - const Word32 core_brate, /* i : core bitrate */ - const Word16 gain_pit, /* i : gain of quantized pitch Q14 */ - Word16 mem[] /* i/o: memory of gain of pitch clipping algorithm 1Q14 */ + const Word16 element_mode, /* i : element mode Q0*/ + const Word32 core_brate, /* i : core bitrate Q0*/ + const Word16 gain_pit, /* i : gain of quantized pitch Q14*/ + Word16 mem[] /* i/o: memory of gain of pitch clipping algorithm 1Q14*/ ); -Word16 Mode2_gp_clip( - const Word16 *voicing, /* i : normalized correlations (from OL pitch) */ - const Word16 i_subfr, /* i : subframe index */ - const Word16 coder_type, /* i : type of coder */ - const Word16 xn[], /* i : target vector */ +Word16 Mode2_gp_clip_fx( + const Word16 *voicing, /* i : normalized correlations from OL pitch Q15 */ + const Word16 i_subfr, /* i : subframe index Q0 */ + const Word16 coder_type, /* i : type of coder Q0 */ + const Word16 xn[], /* i : target vector Q_xn */ Word16 mem[], /* i/o: memory of gain of pitch clipping algorithm */ - const Word16 L_subfr, - const Word16 Q_xn /* i : xn data format */ + /* mem[0]: Q0 */ + /* mem[1]: 1Q14 */ + /* mem[2]: 8Q7 */ + /* mem[3]: Q0 (integer) */ + /* mem[4]: Q14 */ + /* mem[5]: Q14 */ + const Word16 L_subfr, /* Q0 */ + const Word16 Q_xn /* i : scaling factor of vector xn[] */ ); void gp_clip_test_lsf_fx( - const Word16 element_mode, /* i : element mode */ - const Word16 lsf[], /* i : lsf values (in frequency domain) 14Q1*1.28 */ - Word16 mem[], /* i/o: memory of gain of pitch clipping algorithm */ - const Word16 m /* i : dimension of lsf */ + const Word16 element_mode, /* i : element mode Q0*/ + const Word16 lsf[], /* i : lsf values (in frequency domain) 14Q1*1.28*/ + Word16 mem[], /* i/o: memory of gain of pitch clipping algorithm [2.56x,Q14,Q8,Q0,Q14,Q14]*/ + const Word16 m /* i : dimension of lsf Q0*/ ); void gp_clip_test_lsf_ivas_fx( - const Word16 element_mode, /* i : element mode */ - const Word32 core_brate, /* i : core bitrate */ - const Word16 lsf[], /* i : LSF vector */ - Word16 mem[], /* i/o: memory of gain of pitch clipping algorithm */ - const Word16 Opt_AMR_WB /* i : flag indicating AMR-WB IO mode */ + const Word16 element_mode, /* i : element mode Q0*/ + const Word32 core_brate, /* i : core bitrate Q0*/ + const Word16 lsf[], /* i : LSF vector 14Q1*1.28*/ + Word16 mem[], /* i/o: memory of gain of pitch clipping algorithm [2.56x,Q14,Q8,Q0,Q14,Q14]*/ + const Word16 Opt_AMR_WB /* i : flag indicating AMR-WB IO mode Q0*/ ); /*========================================================================================================/ @@ -4437,6 +4572,13 @@ void edct_fx( Word16 *q /* i : Q value of i signal */ ); +void edct_ivas_fx( + const Word32 *x, /* i : input signal Qq */ + Word32 *y, /* o : output transform Qq */ + Word16 length, /* i : length Q0*/ + Word16 *q /* i : Q value of input signal */ +); + void edst_fx( const Word32 *x, /* i : i signal Qq */ Word32 *y, /* o : output transform Qq */ @@ -4552,7 +4694,9 @@ void DoRTFTn_fx_ivas( Word16 find_guarded_bits_fx( Word32 n ); -Word16 L_norm_arr( Word32 *arr, Word16 size ); +Word16 L_norm_arr( const Word32 *arr, Word16 size ); +Word16 norm_arr( Word16 *arr, Word16 size ); +Word16 W_norm_arr( Word64 *arr, Word16 size ); Word16 get_min_scalefactor( Word32 x, Word32 y ); @@ -4705,17 +4849,20 @@ Word16 BITS_ALLOC_config_acelp( const Word16 nb_subfr ); ivas_error config_acelp1( - const Word16 enc_dec, /* i : encoder/decoder flag */ - const Word32 total_brate, /* i : total bitrate */ - const Word32 core_brate_inp, /* i : core bitrate */ - const Word16 core, /* i : core */ - const Word16 extl, /* i : extension layer */ - const Word32 extl_brate, /* i : extension layer bitrate */ - const Word16 L_frame, /* i : frame length at internal Fs */ - const Word16 GSC_noisy_speech, /* i : GSC on SWB noisy speech flag */ - ACELP_config *acelp_cfg, /* i : ACELP bit-allocation */ - const Word16 signalling_bits, /* i : number of signalling bits */ - const Word16 coder_type, /* i : coder type */ + const Word16 enc_dec, /* i : encoder/decoder flag */ + const Word32 total_brate, /* i : total bitrate */ + const Word32 core_brate_inp, /* i : core bitrate */ + const Word16 core, /* i : core */ + const Word16 extl, /* i : extension layer */ + const Word32 extl_brate, /* i : extension layer bitrate */ + const Word16 L_frame, /* i : frame length at internal Fs */ + const Word16 GSC_noisy_speech, /* i : GSC on SWB noisy speech flag */ + ACELP_config *acelp_cfg, /* i : ACELP bit-allocation */ + const Word16 signalling_bits, /* i : number of signalling bits */ + const Word16 coder_type, /* i : coder type */ +#ifdef NONBE_FIX_GSC_BSTR + const Word16 inactive_coder_type_flag, /* i : AVQ (0) or GSC (1) IC flag */ +#endif const Word16 tc_subfr, /* i : TC subfr ID */ const Word16 tc_call, /* i : TC call number (0,1,2,3,5(DEC)) */ Word16 *nBits_es_Pred, /* o : number of bits for Es_pred Q */ @@ -4760,24 +4907,18 @@ Word16 est_tilt_fx( /* o : tilt of the code const Word32 gain_code, /* i : algebraic code gain Q16 */ Word16 *voice_fac, /* o : voicing factor Q15 */ const Word16 Q_exc /* i : Scaling factor of excitation Q0 */ -#ifdef ADD_LRTD - , - const Word16 L_subfr /* i : Sub frame lenght */ -#endif ); -Word16 est_tilt_ivas_fx( /* o : tilt of the code Q15 */ - const Word16 *exc, /* i : adaptive excitation vector Qx */ - const Word16 gain_pit, /* i : adaptive gain Q14 */ - const Word16 *code, /* i : algebraic excitation vector Q9 */ - const Word32 gain_code, /* i : algebraic code gain Q16 */ - Word16 *voice_fac, /* o : voicing factor Q15 */ - const Word16 Q_exc /* i : Scaling factor of excitation Q0 */ -#if 1 // def ADD_LRTD - , - const Word16 L_subfr, /* i : Sub frame length */ - const Word16 flag_tilt /* i : flag for special tilt */ -#endif +/* o : tilt of the code Q15 */ +Word16 est_tilt_ivas_fx( + const Word16 *exc, /* i : adaptive excitation vector Qx */ + const Word16 gain_pit, /* i : adaptive gain Q14 */ + const Word16 *code, /* i : algebraic excitation vector Q9 */ + const Word32 gain_code, /* i : algebraic code gain Q16 */ + Word16 *voice_fac, /* o : voicing factor Q15 */ + const Word16 Q_exc, /* i : Scaling factor of excitation Q0 */ + const Word16 L_subfr, /* i : Sub frame length */ + const Word16 flag_tilt /* i : flag for special tilt */ ); Word16 Est_tilt2( /* o : tilt of the code */ @@ -4938,12 +5079,12 @@ void fine_gain_quant_fx( const Word16 *gopt /* i : Optimal gains Q12 */ ); void fine_gain_quant_ivas_fx( - BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ - const Word16 *ord, /* i : Indices for energy order Q0 */ - const Word16 num_sfm, /* i : Number of bands Q0 */ - const Word16 *gain_bits, /* i : Gain adjustment bits per sub band Q0 */ - Word16 *fg_pred, /* i/o: Predicted gains / Corrected gains Q12 */ - const Word16 *gopt /* i : Optimal gains Q12 */ + BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ + const Word16 *ord, /* i : Indices for energy order Q0 */ + const Word16 num_sfm, /* i : Number of bands Q0 */ + const Word16 *gain_bits, /* i : Gain adjustment bits per sub band Q0 */ + Word16 *fg_pred, /* i/o: Predicted gains / Corrected gains i:Q12 / o:Q11 */ + const Word16 *gopt /* i : Optimal gains Q12 */ ); void get_max_pulses_fx( const Word16 *band_start, /* i : Sub band start indices */ @@ -5692,16 +5833,14 @@ void tcx_ltp_post32( // gs_inact_switching_fx.c void Inac_swtch_ematch_fx( - Word16 exc2[], /* i/o: CELP/GSC excitation buffer Q_exc*/ - Word16 dct_exc_tmp[], /* i : GSC excitation in DCT domain */ - Word16 lt_ener_per_band[], /* i/o: Long term energy per band Q12 */ - const Word16 coder_type, /* i : Coding mode */ - const Word16 L_frame, /* i : Frame lenght */ - const Word32 core_brate, /* i : Core bit rate */ - const Word16 Q_exc /* i : i and output format of exc2 */ - , - const Word16 bfi /* i : frame lost indicator */ - , + Word16 exc2[], /* i/o: CELP/GSC excitation buffer Q_exc*/ + Word16 dct_exc_tmp[], /* i : GSC excitation in DCT domain */ + Word16 lt_ener_per_band[], /* i/o: Long term energy per band Q12 */ + const Word16 coder_type, /* i : Coding mode */ + const Word16 L_frame, /* i : Frame lenght */ + const Word32 core_brate, /* i : Core bit rate */ + const Word16 Q_exc, /* i : i and output format of exc2 */ + const Word16 bfi, /* i : frame lost indicator */ const short last_core, /* i : Last core used */ const short last_codec_mode /* i : Last codec mode */ ); @@ -5711,15 +5850,17 @@ void Inac_switch_ematch_ivas_fx( Word16 dct_exc_tmp[], /* i : GSC excitation in DCT domain */ Word16 lt_ener_per_band[], /* i/o: Long term energy per band Q12 */ const Word16 coder_type, /* i : Coding mode */ - const Word16 L_frame, /* i : Frame lenght */ - const Word32 core_brate, /* i : Core bit rate */ - const Word16 Q_exc /* i : input and output format of exc2 */ - , - const Word16 bfi /* i : frame lost indicator */ - , - const Word16 last_core, /* i : Last core used */ - const Word16 last_codec_mode /* i : Last codec mode */ - , +#ifdef NONBE_FIX_GSC_BSTR + const Word16 inactive_coder_type_flag, /* i : AVQ (0) or GSC (1) IC flag */ +#endif + const Word16 L_frame, /* i : Frame lenght */ +#ifndef NONBE_FIX_GSC_BSTR + const Word32 core_brate, /* i : Core bit rate */ +#endif + const Word16 Q_exc, /* i : input and output format of exc2 */ + const Word16 bfi, /* i : frame lost indicator */ + const Word16 last_core, /* i : Last core used */ + const Word16 last_codec_mode, /* i : Last codec mode */ const Word16 tdm_low_rate_mode, /* i : secondary channel low rate mode flag*/ const Word16 element_mode /* i : element mode */ ); @@ -5957,10 +6098,7 @@ void TBEreset_dec_fx( void td_bwe_dec_init_fx( Decoder_State *st_fx, /* i/o: SHB decoder structure */ TD_BWE_DEC_HANDLE hBWE_TD, /* i/o: TD BWE data handle */ -#ifdef ADD_IVAS_BWE - const Word16 extl, /* i : BWE extension layer */ -#endif - const Word32 output_Fs /* i : output sampling rate */ + const Word32 output_Fs /* i : output sampling rate */ ); // lsf_dec_fx.c @@ -6556,7 +6694,7 @@ void nb_post_filt_fx( const Word16 tmp_noise, /* i : noise energy Q0 */ Word16 *Synth, /* i : 12k8 synthesis Qsyn */ const Word16 *Aq, /* i : LP filter coefficient Q12 */ - const Word16 *Pitch_buf, /* i : Fractionnal subframe pitch buffer Q6 */ + const Word16 *Pitch_buf, /* i : Fractionnal subframe pitch buffer Q0 */ const Word16 coder_type, /* i : coder_type */ const Word16 BER_detect, /* i : BER detect flag */ const Word16 disable_hpf /* i : flag to diabled HPF */ @@ -7021,30 +7159,21 @@ void dec_pit_exc_fx( const Word16 nb_subfr_fx /* i : Number of subframe considered */ , Word16 *gain_buf /*Q14*/ -#ifdef ADD_LRTD - , - const Word16 tdm_Pitch_reuse_flag, /* i : primary channel pitch reuse flag */ - const Word16 tdm_Pri_pitch_buf[] /* i : primary channel pitch buffer */ -#endif ); void dec_pit_exc_ivas_fx( - Decoder_State *st_fx, /* i/o: decoder static memory */ - const Word16 *Aq_fx, /* i : LP filter coefficient */ - const Word16 coder_type, /* i : coding type */ - const Word16 Es_pred_fx, /* i : predicted scaled innov. energy */ - Word16 *pitch_buf_fx, /* o : floating pitch values for each subframe */ - Word16 *code_fx, /* o : innovation */ - Word16 *exc_fx, /* i/o: adapt. excitation exc */ - Word16 *bwe_exc_fx, /* o : excitation for SWB TBE */ - const Word16 nb_subfr_fx /* i : Number of subframe considered */ - , - Word16 *gain_buf /*Q14*/ -#if 1 // def ADD_LRTD - , + Decoder_State *st_fx, /* i/o: decoder static memory */ + const Word16 *Aq_fx, /* i : LP filter coefficient */ + const Word16 coder_type, /* i : coding type */ + const Word16 Es_pred_fx, /* i : predicted scaled innov. energy */ + Word16 *pitch_buf_fx, /* o : floating pitch values for each subframe */ + Word16 *code_fx, /* o : innovation */ + Word16 *exc_fx, /* i/o: adapt. excitation exc */ + Word16 *bwe_exc_fx, /* o : excitation for SWB TBE */ + const Word16 nb_subfr_fx, /* i : Number of subframe considered */ + Word16 *gain_buf, /*Q14*/ const Word16 tdm_Pitch_reuse_flag, /* i : primary channel pitch reuse flag */ const Word16 tdm_Pri_pitch_buf[] /* i : primary channel pitch buffer */ -#endif ); // pit_dec_fx.c @@ -7099,28 +7228,24 @@ Word16 pit_decode_fx( /* o : floating pitch value Word16 *T0_min, /* i/o: delta search min for sf 2 & 4 */ Word16 *T0_max, /* i/o: delta search max for sf 2 & 4 */ const Word16 L_subfr /* i : subframe length */ -#ifdef ADD_LRTD - , - const Word16 tdm_Pitch_reuse_flag, /* i : primary channel pitch reuse flag */ - const Word16 tdm_Pri_pitch_buf[] /* i : primary channel pitch buffer */ -#endif ); -Word16 pit_decode_ivas_fx( /* o : floating pitch value */ - Decoder_State *st_fx, /* i/o: decoder state structure */ - const Word32 core_brate, /* i : core bitrate */ - const Word16 Opt_AMR_WB, /* i : flag indicating AMR-WB IO mode */ - const Word16 L_frame, /* i : length of the frame */ - Word16 i_subfr, /* i : subframe index */ - const Word16 coder_type, /* i : coding type */ - Word16 *limit_flag, /* i/o: restrained(0) or extended(1) Q limits */ - Word16 *T0, /* o : close loop integer pitch */ - Word16 *T0_frac, /* o : close loop fractional part of the pitch */ - Word16 *T0_min, /* i/o: delta search min for sf 2 & 4 */ - Word16 *T0_max, /* i/o: delta search max for sf 2 & 4 */ - const Word16 L_subfr, /* i : subframe length */ - const Word16 tdm_Pitch_reuse_flag, /* i : primary channel pitch reuse flag */ - const Word16 tdm_Pri_pitch_buf[] /* i : primary channel pitch buffer Q6 */ +/* o : floating pitch value */ +Word16 pit_decode_ivas_fx( + Decoder_State *st_fx, /* i/o: decoder state structure */ + const Word32 core_brate, /* i : core bitrate */ + const Word16 Opt_AMR_WB, /* i : flag indicating AMR-WB IO mode */ + const Word16 L_frame, /* i : length of the frame */ + Word16 i_subfr, /* i : subframe index */ + const Word16 coder_type, /* i : coding type */ + Word16 *limit_flag, /* i/o: restrained(0) or extended(1) Q limits */ + Word16 *T0, /* o : close loop integer pitch */ + Word16 *T0_frac, /* o : close loop fractional part of the pitch */ + Word16 *T0_min, /* i/o: delta search min for sf 2 & 4 */ + Word16 *T0_max, /* i/o: delta search max for sf 2 & 4 */ + const Word16 L_subfr, /* i : subframe length */ + const Word16 tdm_Pitch_reuse_flag, /* i : primary channel pitch reuse flag */ + const Word16 tdm_Pri_pitch_buf[] /* i : primary channel pitch buffer Q6 */ ); void pit_Q_dec_fx( @@ -7501,15 +7626,6 @@ void perform_noise_estimation_dec_fx( float *power_spectrum, #endif HANDLE_FD_CNG_DEC hFdCngDec /* i/o: FD_CNG structure containing all buffers and variables */ -#ifdef IVAS_CODE_CNG - , - const Word16 element_mode, /* i : element mode */ - const Word16 bwidth, /* i : audio bandwidth */ - const Word16 L_frame, /* i : frame length at internal Fs */ - const Word16 last_L_frame, /* i : frame length of the last frame at internal Fs */ - const Word32 last_core_brate, /* i : previous frame core bitrate */ - const Word16 VAD /* i : VAD flag in the decoder */ -#endif ); void perform_noise_estimation_dec_ivas_fx( @@ -7622,19 +7738,12 @@ Word16 WB_BWE_gain_deq_fx( ); Word16 wb_bwe_dec_fx( -#ifdef ADD_IVAS_BWE - const Word16 output[], /* i : suntehsis @ internal Fs */ -#endif - Word16 *synth_fx, /* i/o: ACELP core synthesis/final synthesis Q0/Qpost */ - Word16 *hb_synth_fx, /* o : SHB synthesis/final synthesis Q_syn_hb */ -#ifdef ADD_IVAS_BWE - const Word16 use_cldfb_for_dft, /* i : flag to use of CLDFB for DFT Stereo */ -#endif + Word16 *synth_fx, /* i/o: ACELP core synthesis/final synthesis Q0/Qpost */ + Word16 *hb_synth_fx, /* o : SHB synthesis/final synthesis Q_syn_hb */ const Word16 output_frame, /* i : frame length */ Word16 *voice_factors_fx, /* i : voicing factors Q15 */ const Word16 pitch_buf_fx[], /* i : pitch buffer Q6 */ - Decoder_State *st_fx /* i/o: decoder state structure */ - , + Decoder_State *st_fx, /* i/o: decoder state structure */ Word16 *Qpost ); Word16 swb_bwe_gain_deq_fx( /* o : BWE class */ @@ -7646,18 +7755,11 @@ Word16 swb_bwe_gain_deq_fx( /* o : BWE class const Word16 hqswb_clas /* i : HQ BWE class */ ); -Word16 swb_bwe_dec_fx( /*o :Q_syn_hb*/ -#ifdef ADD_IVAS_BWE - const Word16 output[], /* i : suntehsis @ internal Fs */ -#endif - Decoder_State *st_fx, /* i/o: decoder state structure */ - Word16 *synth_fx, /* i/o: ACELP core synthesis/final synthesis (might be rescaled inside wtda() ) Q0/Qpost */ - Word16 *hb_synth_fx, /* o : SHB synthesis/final synthesis Q_syn_hb */ -#ifdef ADD_IVAS_BWE - const Word16 use_cldfb_for_dft, /* i : flag to use of CLDFB for DFT Stereo */ -#endif - const Word16 output_frame /* i : frame length */ - , +Word16 swb_bwe_dec_fx( /*o :Q_syn_hb*/ + Decoder_State *st_fx, /* i/o: decoder state structure */ + Word16 *synth_fx, /* i/o: ACELP core synthesis/final synthesis (might be rescaled inside wtda() ) Q0/Qpost */ + Word16 *hb_synth_fx, /* o : SHB synthesis/final synthesis Q_syn_hb */ + const Word16 output_frame, /* i : frame length */ Word16 *Qpost ); void fd_bwe_dec_init( @@ -7668,10 +7770,10 @@ void fd_bwe_dec_init( void hq_core_enc_ivas_fx( Encoder_State *st, /* i/o: encoder state structure */ const Word16 *audio_fx, /* i : input audio signal Q0 */ - const Word16 input_frame, /* i : frame length */ - const Word16 hq_core_type, /* i : HQ core type */ - const Word16 Voicing_flag, /* i : Voicing flag for FER method selection */ - const Word16 vad_hover_flag /* i : VAD hangover flag */ + const Word16 input_frame, /* i : frame length Q0*/ + const Word16 hq_core_type, /* i : HQ core type Q0*/ + const Word16 Voicing_flag, /* i : Voicing flag for FER method selection Q0*/ + const Word16 vad_hover_flag /* i : VAD hangover flag Q0*/ ); // hq_core_dec_fx.c @@ -7933,22 +8035,12 @@ ivas_error core_switching_pre_dec_fx( ); ivas_error core_switching_post_dec_fx( - Decoder_State *st_fx, /* i/o: decoder state structure */ - Word16 *synth, /* i/o: output synthesis Qsynth Qsynth*/ -#ifdef IVAS_CODE_SWITCHING - float *output, /* i/o: LB synth/upsampled LB synth */ - float output_mem[], /* i : OLA memory from last TCX/HQ frame */ - const IVAS_FORMAT ivas_format, /* i : IVAS format */ - const Word16 use_cldfb_for_dft, /* i : flag to use of CLDFB for DFT Stereo */ -#endif + Decoder_State *st_fx, /* i/o: decoder state structure */ + Word16 *synth, /* i/o: output synthesis Qsynth Qsynth*/ const Word16 output_frame, /* i : frame length Q0*/ const Word16 core_switching_flag, /* i : ACELP->HQ switching flag Q0*/ -#ifdef IVAS_CODE_SWITCHING - const Word16 sba_dirac_stereo_flag, /* i : signal stereo output for SBA DirAC */ - const Word16 nchan_out, /* i : number of output channels */ -#endif - const Word16 last_element_mode, /* i : element mode of previous frame Q0*/ - Word16 *Qsynth /* i/o: Scaling of ACELP exit (Q_syn2-1) or HQ exit (Qsynth); changes after this function */ + const Word16 last_element_mode, /* i : element mode of previous frame Q0*/ + Word16 *Qsynth /* i/o: Scaling of ACELP exit (Q_syn2-1) or HQ exit (Qsynth); changes after this function */ ); ivas_error core_switching_post_dec_ivas_fx( @@ -8460,7 +8552,6 @@ Word16 FEC_synchro_exc_fx( /* o : do_WI flag // dec_uv_fx.c void decod_unvoiced_fx( Decoder_State *st_fx, /* i/o: decoder static memory */ - const Word16 *Aq_fx, /* Q12 i : LP filter coefficient */ const Word16 coder_type, /* Q0 i : coding type */ Word16 *tmp_noise_fx, /* Q5 o : long term temporary noise energy */ Word16 *pitch_buf_fx, /* Q6 o : floating pitch values for each subframe */ @@ -8638,10 +8729,6 @@ Word16 dec_acelp_tcx_frame_fx( Word32 bwe_exc_extended[], /* i/o: bandwidth extended excitation */ Word16 *voice_factors, /* o : voicing factors */ Word16 pitch_buf[] /* o : floating pitch for each subframe */ -#ifdef IVAS_CODE_CNG - , - STEREO_CNG_DEC_HANDLE hStereoCng /* i : stereo CNG handle */ -#endif ); // dec_LPD_fx.c @@ -9588,6 +9675,17 @@ void cldfbAnalysis_ts_fx( Word16 *q_cldfb ); Word16 floor_log_2( Word32 num ); +void cldfbAnalysis_ts_fx_var_q( + const Word32 *timeIn_fx, + /* i : time buffer */ // q + Word32 realBuffer_fx[CLDFB_NO_CHANNELS_MAX], + /* o : real value buffer */ // q_cldfb - 5 + Word32 imagBuffer_fx[CLDFB_NO_CHANNELS_MAX], + /* o : imag value buffer */ // q_cldfb - 5 + const Word16 samplesToProcess, /* i : samples to process */ + HANDLE_CLDFB_FILTER_BANK h_cldfb, /* i : filterbank state */ + Word16 *q_cldfb ); + void cldfbAnalysis_ts_fx_fixed_q( const Word32 *timeIn_fx, /* i : time buffer */ // q @@ -9699,8 +9797,8 @@ ivas_error openCldfb_ivas_fx( HANDLE_CLDFB_FILTER_BANK *h_cldfb, /* i/o: filter bank handle */ CLDFB_TYPE type, /* i : analysis or synthesis */ const Word32 sampling_rate, /* i : sampling rate */ - CLDFB_PROTOTYPE prototype /* i : CLDFB version (1.25ms/5ms delay) */ -); + CLDFB_PROTOTYPE prototype, /* i : CLDFB version (1.25ms/5ms delay) */ + const Word16 enc_dec ); /* i : encoder/decoder flag */ Word32 rand_gauss_fx( Word32 *x, @@ -9906,14 +10004,14 @@ void tcx_scalar_quantization_ivas_fx( Word8 const *memQuantZeros_fx, /* i: coefficients to be set to 0 */ const Word16 alfe_flag ); -Word16 RCcontextMapping_encode2_estimate_no_mem_s17_LCS( - Word16 *x, /* Spectral coefficients */ - const Word16 nt, /* L - size of spectrum (no. of spectral coefficients) */ - Word16 *lastnz_out, - Word16 *nEncoded, /* No. of spectral coefficients that can be coded without an overflow occuring */ - const Word16 target, /* Target bits */ - Word16 *stop, - Word16 mode, +Word16 RCcontextMapping_encode2_estimate_no_mem_s17_LCS_fx( + Word16 *x, /* Spectral coefficients Q0*/ + const Word16 nt, /* L - size of spectrum (no. of spectral coefficients) Q0*/ + Word16 *lastnz_out, /* Q0 */ + Word16 *nEncoded, /* No. of spectral coefficients that can be coded without an overflow occuring Q0*/ + const Word16 target, /* Target bits Q0*/ + Word16 *stop, /* Q0 */ + Word16 mode, /* Q0 */ CONTEXT_HM_CONFIG *hm_cfg /* context-based harmonic model configuration */ ); @@ -9962,7 +10060,7 @@ void Scale_sig32( const Word16 exp0 /* i : exponent: x = round(x << exp) Qx ?exp */ ); -void Copy_Scale_sig_16_32( +void Copy_Scale_sig_16_32_DEPREC( const Word16 x[], /* i : signal to scale i Qx */ Word32 y[], /* o : scaled signal output Qx */ const Word16 lg, /* i : size of x[] Q0 */ @@ -10032,6 +10130,12 @@ Word16 maximum_fx( /* o : index of the maximum value in t Word16 *max_fx /* o : maximum value in the input vector */ ); +Word16 maximum_exp_fx( /* o : index of the maximum value in the input vector */ + const Word16 *vec_fx, /* i : input vector */ + const Word16 *exp_vec, /* i : exponents of input vector */ + const Word16 lvec_fx /* i : length of input vector */ +); + Word16 maximum_abs_16_fx( /* o : index of the maximum abs value in the input vector */ const Word16 *vec, /* i : input vector */ const Word16 lvec, /* i : length of input vector */ @@ -10221,6 +10325,13 @@ Word32 root_a_over_b_fx( Word16 Q_b, Word16 *exp_out ); +Word32 root_a_over_b_ivas_fx( + Word32 a, /* Q(Q_a) */ + Word16 Q_a, + Word32 b, /* Q(Q_b) */ + Word16 Q_b, + Word16 *exp_out ); + void fir_fx( const Word16 x[], /* i : input vector Qx*/ const Word16 h[], /* i : impulse response of the FIR filter Q12*/ Word16 y[], /* o : output vector (result of filtering) Qx*/ @@ -10771,16 +10882,18 @@ Word32 sum2_32_fx( Word16 *e ); void ProcessStereoIGF_fx( STEREO_MDCT_ENC_DATA_HANDLE hStereoMdct, - Encoder_State *sts[CPE_CHANNELS], /* i : Encoder state */ - Word16 ms_mask[2][MAX_SFB], /* i : bandwise MS mask */ - Word32 *pITFMDCTSpectrum_fx[CPE_CHANNELS][NB_DIV], /* i : MDCT spectrum fir ITF */ + Encoder_State *sts[CPE_CHANNELS], /* i : Encoder state */ + Word16 ms_mask[2][MAX_SFB], /* i : bandwise MS mask */ + Word32 *pITFMDCTSpectrum_fx[CPE_CHANNELS][NB_DIV], /* i : MDCT spectrum fir ITF */ + Word16 q_pITFMDCTSpectrum_1, + Word16 q_pITFMDCTSpectrum_2, Word32 *pPowerSpectrum_fx[CPE_CHANNELS], /* i/o: MDCT^2 + MDST^2 spectrum, or estimate */ Word32 *pPowerSpectrumMsInv_fx[CPE_CHANNELS][NB_DIV], /* i : inverse power spectrum */ Word32 *inv_spectrum_fx[CPE_CHANNELS][NB_DIV], /* i : inverse spectrum */ const Word16 frameno, /* i : flag indicating index of current subfr. */ const Word16 sp_aud_decision0, /* i : sp_aud_decision0 */ - const Word32 element_brate /* i : element bitrate */ -); + const Word32 element_brate, /* i : element bitrate */ + const Word16 mct_on ); /*igf_enc.c*/ void IGFEncApplyStereo_fx( STEREO_MDCT_ENC_DATA_HANDLE hStereoMdct, /* i/o: MDCT stereo encoder structure */ @@ -10793,14 +10906,14 @@ void IGFEncApplyStereo_fx( Word32 *inv_spectrum_fx[CPE_CHANNELS][NB_DIV], /* i : inverse spectrum */ const Word16 frameno, /* i : flag indicating index of current subfr. */ const Word16 sp_aud_decision0, /* i : sp_aud_decision0 */ - const Word32 element_brate /* i : element bitrate */ -); + const Word32 element_brate, /* i : element bitrate */ + const Word16 mct_on ); void IGFSaveSpectrumForITF_ivas_fx( IGF_ENC_INSTANCE_HANDLE hIGFEnc, /* i/o: instance handle of IGF Encoder */ const Word16 igfGridIdx, /* i : IGF grid index */ - const Word32 *pITFSpectrum /* i : MDCT spectrum */ -); + const Word32 *pITFSpectrum, /* i : MDCT spectrum */ + Word16 exp_pITFSpectrum ); Word16 IGFEncWriteBitstream_ivas_fx( const IGF_ENC_INSTANCE_HANDLE hIGFEnc, /* i : instance handle of IGF Encoder */ BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ @@ -10809,7 +10922,7 @@ Word16 IGFEncWriteBitstream_ivas_fx( const Word16 isIndepFlag /* i : if 1 frame is independent, 0 = frame is coded with data from previous frame */ ); /*igf_scf_enc.c*/ -Word16 IGFSCFEncoderEncode( +Word16 IGFSCFEncoderEncode_ivas_fx( IGFSCFENC_INSTANCE_HANDLE hPublicData, /* i/o: handle to public data or NULL in case there was no instance created */ BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ const Word16 bitCount, /* i : offset to the first bit in bitbuffer which should be readed by iisArithDecoderDecode function */ @@ -10818,19 +10931,24 @@ Word16 IGFSCFEncoderEncode( const Word16 indepFlag /* i : if 1 frame is independent, 0 = frame is coded with data from previous frame */ ); /*ari_enc.c*/ -Word16 ari_encode_14bits_ext( - Word16 *ptr, - Word16 bp, +Word16 ari_encode_14bits_ext_ivas_fx( + Word16 *ptr, /* Q0 */ + Word16 bp, /* Q0 */ Tastat *s, - Word32 symbol, - const UWord16 *cum_freq ); -Word16 ari_encode_14bits_sign( - Word16 *ptr, - Word16 bp, - Word32 bits, + Word32 symbol, /* Q0 */ + UWord16 const *cum_freq /* Q0 */ +); +Word16 ari_encode_14bits_sign_ivas_fx( + Word16 *ptr, /* Q0 */ + Word16 bp, /* Q0 */ + Word32 bits, /* Q0 */ Tastat *s, - Word16 sign ); -Word16 ari_done_encoding_14bits( Word16 *ptr, Word16 bp, Tastat *s ); + Word16 sign /* Q0 */ +); +Word16 ari_done_encoding_14bits_ivas_fx( + Word16 *ptr, /* Q0 */ + Word16 bp, /* Q0 */ + Tastat *s ); void pack_bit( const Word16 bit, /* i: bit to be packed */ UWord8 **pt, /* i/o: pointer to octet array into which bit will be placed */ @@ -10842,7 +10960,6 @@ void IGFEncConcatenateBitstream( BSTR_ENC_HANDLE hBstr /* i/o: bitstream handle */ ); -#endif void hq_generic_hf_encoding_fx( const Word32 *coefs_fx, /* i : MDCT coefficients of weighted original */ @@ -10887,17 +11004,20 @@ void lsf_syn_mem_backup_ivas_fx( Word16 *pstreaklen ); ivas_error config_acelp1_IVAS( - const Word16 enc_dec, /* i : encoder/decoder flag */ - const Word32 total_brate, /* i : total bitrate */ - const Word32 core_brate_inp, /* i : core bitrate */ - const Word16 core, /* i : core */ - const Word16 extl, /* i : extension layer */ - const Word32 extl_brate, /* i : extension layer bitrate */ - const Word16 L_frame, /* i : frame length at internal Fs */ - const Word16 GSC_noisy_speech, /* i : GSC on SWB noisy speech flag */ - ACELP_config *acelp_cfg, /* i : ACELP bit-allocation */ - const Word16 signaling_bits, /* i : number of signaling bits */ - const Word16 coder_type, /* i : coder type */ + const Word16 enc_dec, /* i : encoder/decoder flag */ + const Word32 total_brate, /* i : total bitrate */ + const Word32 core_brate_inp, /* i : core bitrate */ + const Word16 core, /* i : core */ + const Word16 extl, /* i : extension layer */ + const Word32 extl_brate, /* i : extension layer bitrate */ + const Word16 L_frame, /* i : frame length at internal Fs */ + const Word16 GSC_noisy_speech, /* i : GSC on SWB noisy speech flag */ + ACELP_config *acelp_cfg, /* i : ACELP bit-allocation */ + const Word16 signaling_bits, /* i : number of signaling bits */ + const Word16 coder_type, /* i : coder type */ +#ifdef NONBE_FIX_GSC_BSTR + const Word16 inactive_coder_type_flag, /* i : AVQ (0) or GSC (1) IC flag */ +#endif const Word16 tc_subfr, /* i : TC subfr ID */ const Word16 tc_call, /* i : TC call number (0,1,2,3,5(DEC)) */ Word16 *nBits_es_Pred, /* o : number of bits for Es_pred Q */ @@ -10934,12 +11054,12 @@ Word16 get_next_coeff_mapped_ivas_fx( ); void RCcontextMapping_encode2_no_mem_s17_LCS_fx( - BSTR_ENC_HANDLE hBstr, /* i/o: bitstream handle */ - Word16 *x, - const Word16 nt, - Word16 lastnz, - const Word16 nbbits, - const Word16 resQMaxBits, + BSTR_ENC_HANDLE hBstr, /* i/o: bitstream handle */ + Word16 *x, /* Q0 */ + const Word16 nt, /* Q0 */ + Word16 lastnz, /* Q0 */ + const Word16 nbbits, /* Q0 */ + const Word16 resQMaxBits, /* Q0 */ CONTEXT_HM_CONFIG *hm_cfg ); void writeTCXparam_fx( @@ -10964,11 +11084,15 @@ void calculate_hangover_attenuation_gain_ivas_fx( void init_coder_ace_plus_ivas_fx( Encoder_State *st, /* i : Encoder state */ const Word32 last_total_brate, /* i : last total bitrate */ - const Word16 MCT_flag /* i : hMCT handle allocated (1) or not (0) */ +#ifdef FIX_920_IGF_INIT_ERROR + const Word32 igf_brate, /* i : IGF configuration bitrate */ +#endif + const Word16 MCT_flag /* i : hMCT handle allocated (1) or not (0) */ ); void core_coder_reconfig_ivas_fx( - Encoder_State *st ); + Encoder_State *st, + const Word32 last_total_brate ); void core_coder_mode_switch_ivas_fx( Encoder_State *st, /* i/o: encoder state structure */ @@ -10978,8 +11102,9 @@ void core_coder_mode_switch_ivas_fx( void configureFdCngEnc_ivas_fx( HANDLE_FD_CNG_ENC hFdCngEnc, /* i/o: Contains the variables related to the FD-based CNG process */ - const Word16 bwidth, - const Word32 total_brate ); + const Word16 bwidth, /* Q0 */ + const Word32 total_brate /* Q0 */ +); Word16 getTcxonly_ivas_fx( const Word16 element_mode, /* i : IVAS element mode */ @@ -10991,9 +11116,9 @@ Word16 getTcxonly_ivas_fx( void SetModeIndex_ivas_fx( Encoder_State *st, /* i : Encoder state */ - const Word32 last_total_brate, /* i : last total bitrate */ - const Word16 last_element_mode, /* i : last IVAS element mode */ - const Word16 MCT_flag /* i : hMCT handle allocated (1) or not (0) */ + const Word32 last_total_brate, /* i : last total bitrate Q0*/ + const Word16 last_element_mode, /* i : last IVAS element mode Q0*/ + const Word16 MCT_flag /* i : hMCT handle allocated (1) or not (0) Q0*/ ); void IGFEncSetMode_ivas_fx( @@ -11059,16 +11184,16 @@ Word16 msvq_stage1_dct_recalc_candidates_fdcng_wb_fx( ); void FEC_encode_ivas_fx( - BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ - const ACELP_config acelp_cfg, /* i/o: configuration of the ACELP */ - const Word16 *synth, /* i : pointer to synthesized speech for E computation */ - const Word16 coder_type, /* i : type of coder */ - Word16 clas, /* i : signal clas for current frame */ - const Word16 *fpit, /* i : close loop fractional pitch buffer Q6 */ - const Word16 *res, /* i : LP residual signal frame */ - Word16 *last_pulse_pos, /* i/o: Position of the last pulse */ - const Word16 L_frame, /* i : Frame length */ - const Word32 total_brate, /* i : total codec bitrate */ + BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ + const ACELP_config acelp_cfg, /* i/o: configuration of the ACELP */ + const Word16 *synth, /* i : pointer to synthesized speech for E computation Q_Synth*/ + const Word16 coder_type, /* i : type of coder Q0*/ + Word16 clas, /* i : signal clas for current frame Q0*/ + const Word16 *fpit, /* i : close loop fractional pitch buffer Q6*/ + const Word16 *res, /* i : LP residual signal frame Qx*/ + Word16 *last_pulse_pos, /* i/o: Position of the last pulse Q0*/ + const Word16 L_frame, /* i : Frame length Q0*/ + const Word32 total_brate, /* i : total codec bitrate Q0*/ const Word16 Q_synth /* i : input scaling */ ); @@ -11119,3 +11244,730 @@ void WriteToBitstream_ivas_fx( Word16 *pnSize, BSTR_ENC_HANDLE hBstr, Word16 *pnBits ); + + +/*===========================================================================================*/ +/*----------------------------------------------------------------------------------* + * MODE1 prototypes + *----------------------------------------------------------------------------------*/ + +/*! r: inverse square root of input value */ +float inv_sqrt( + const float x /* i : input value */ +); + +/*! r: output random value */ +int16_t own_random( + int16_t *seed /* i/o: random seed */ +); + +/*! r: sign of x (+1/-1) */ +float sign( + const float x /* i : input value of x */ +); + +/*! r: logarithm2 of x */ +float log2_f( + const float x /* i : input value of x */ +); + +int16_t norm_ul_float( + uint32_t UL_var1 ); + +/*! r: sum of all vector elements */ +int16_t sum_s( + const int16_t *vec, /* i : input vector */ + const int16_t lvec /* i : length of input vector */ +); + +/*! r: sum of all vector elements */ +int32_t sum_l( + const int32_t *vec, /* i : input vector */ + const int16_t lvec /* i : length of input vector */ +); + +/*! r: sum of all squared vector elements */ +float sum2_f( + const float *vec, /* i : input vector */ + const int16_t lvec /* i : length of input vector */ +); + +void set_c( + int8_t y[], /* i/o: Vector to set */ + const int8_t a, /* i : Value to set the vector to */ + const int32_t N /* i : Length of the vector */ +); + +void set_s( + int16_t y[], /* i/o: Vector to set */ + const int16_t a, /* i : Value to set the vector to */ + const int16_t N /* i : Lenght of the vector */ +); + +void set_l( + int32_t y[], /* i/o: Vector to set */ + const int32_t a, /* i : Value to set the vector to */ + const int16_t N /* i : Length of the vector */ +); + +void set_f( + float y[], /* i/o: Vector to set */ + const float a, /* i : Value to set the vector to */ + const int16_t N /* i : Lenght of the vector */ +); + +void set_zero_fx( + Word32 *vec, /* o : input vector */ + const Word16 lvec /* i : length of the vector */ +); +void set_zero2_fx( + Word32 *vec, /* o : input vector */ + const Word32 lvec /* i : length of the vector */ +); +void set16_zero_fx( + Word16 *vec, /* o : input vector */ + const Word16 lvec /* i : length of the vector */ +); + +void set_zero( + float *vec, /* o : input vector */ + const int16_t lvec /* i : length of the vector */ +); + +void mvr2r( + const float x[], /* i : input vector */ + float y[], /* o : output vector */ + const int16_t n /* i : vector size */ +); + +void mvs2s( + const int16_t x[], /* i : input vector */ + int16_t y[], /* o : output vector */ + const int16_t n /* i : vector size */ +); + +uint32_t mvr2s( + const float x[], /* i : input vector */ + int16_t y[], /* o : output vector */ + const int16_t n /* i : vector size */ +); + +void mvs2r( + const int16_t x[], /* i : input vector */ + float y[], /* o : output vector */ + const int16_t n /* i : vector size */ +); + +void mvl2l( + const int32_t x[], /* i : input vector */ + int32_t y[], /* o : output vector */ + const int16_t n /* i : vector size */ +); + + +/*! r: index of the maximum value in the input vector */ +int16_t maximum( + const float *vec, /* i : input vector */ + const int16_t lvec, /* i : length of input vector */ + float *max_val /* o : maximum value in the input vector */ +); +/*! r: index of the maximum value in the input vector */ +int16_t maximumAbs( + const float *vec, /* i : input vector */ + const int16_t lvec, /* i : length of input vector */ + float *max_val /* o : maximum value in the input vector */ +); + +Word16 maximumAbs_l( + const Word32 *vec, /* i : input vector */ + const Word16 lvec, /* i : length of input vector */ + Word32 *max_val /* o : maximum value in the input vector */ +); + +/*! r: index of the minimum value in the input vector */ +int16_t minimum( + const float *vec, /* i : input vector */ + const int16_t lvec, /* i : length of input vector */ + float *min_val /* o : minimum value in the input vector */ +); + +/*! r: index of the minimum value in the input vector */ +int16_t minimum_s( + const int16_t *vec, /* i : Input vector */ + const int16_t lvec, /* i : Vector length */ + int16_t *min_val /* o : minimum value in the input vector */ +); + +/*! r: return index with max energy value in vector */ +int16_t emaximum( + const float *vec, /* i : input vector */ + const int16_t lvec, /* i : length of input vector */ + float *ener_max /* o : maximum energy value */ +); + +/*! r: vector mean */ +float mean( + const float *vec, /* i : input vector */ + const int16_t lvec /* i : length of input vector */ +); + +/*! r: dot product of x[] and y[] */ +float dotp( + const float x[], /* i : vector x[] */ + const float y[], /* i : vector y[] */ + const int16_t n /* i : vector length */ +); + +void v_add( + const float x1[], /* i : Input vector 1 */ + const float x2[], /* i : Input vector 2 */ + float y[], /* o : Output vector that contains vector 1 + vector 2 */ + const int16_t N /* i : Vector length */ +); + +void v_sub( + const float x1[], /* i : Input vector 1 */ + const float x2[], /* i : Input vector 2 */ + float y[], /* o : Output vector that contains vector 1 - vector 2 */ + const int16_t N /* i : Vector length */ +); + +/*! r: dequanzited gain */ +float usdequant( + const int16_t idx, /* i : quantizer index */ + const float qlow, /* i : lowest codebook entry (index 0) */ + const float delta /* i : quantization step */ +); + +void sort( + uint16_t *x, /* i/o: Vector to be sorted */ + uint16_t len /* i/o: vector length */ +); + +void sort_l( + Word32 *x, /* i/o: Vector to be sorted */ + Word16 len /* i/o: vector length */ +); + + +ivas_error push_indice( + BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ + int16_t id, /* i : ID of the indice */ + uint16_t value, /* i : value of the quantized indice */ + int16_t nb_bits /* i : number of bits used to quantize the indice */ +); + +ivas_error push_next_indice( + BSTR_ENC_HANDLE hBstr, + UWord16 value, /* i : value of the quantized indice */ + Word16 nb_bits /* i : number of bits used to quantize the indice */ +); + +ivas_error push_next_bits( + BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ + const UWord16 bits[], /* i : bit buffer to pack, sequence of single bits */ + const Word16 nb_bits /* i : number of bits to pack */ +); + +/*! r: maximum number of indices */ +Word16 get_ivas_max_num_indices_fx( + const IVAS_FORMAT ivas_format, /* i : IVAS format */ + const Word32 ivas_total_brate /* i : IVAS total bitrate */ +); + +/*! r: maximum number of indices */ +int16_t get_BWE_max_num_indices( + const int32_t extl_brate /* i : extensiona layer bitrate */ +); + +/*! r: maximum number of indices */ +Word16 get_ivas_max_num_indices_metadata_fx( + const IVAS_FORMAT ivas_format, /* i : IVAS format */ + const Word32 ivas_total_brate /* i : IVAS total bitrate */ +); +ivas_error ind_list_realloc( + INDICE_HANDLE old_ind_list, /* i : pointer to the beginning of the old buffer of indices */ + const int16_t max_num_indices, /* i : new maximum number of allowed indices in the list */ + Encoder_Struct *st_ivas /* i : IVAS encoder structure */ +); + +ivas_error check_ind_list_limits( + BSTR_ENC_HANDLE hBstr /* i/o: encoder bitstream handle */ +); + +void move_indices( + INDICE_HANDLE old_ind_list, /* i/o: old location of indices */ + INDICE_HANDLE new_ind_list, /* i/o: new location of indices */ + const int16_t nb_indices /* i : number of moved indices */ +); + +/*! r: index of the indice in the list, -1 if not found */ +int16_t find_indice( + BSTR_ENC_HANDLE hBstr, /* i : encoder bitstream handle */ + const int16_t id, /* i : ID of the indice */ + uint16_t *value, /* o : value of the quantized indice */ + int16_t *nb_bits /* o : number of bits used to quantize the indice */ +); + +/*! r: number of deleted indices */ +uint16_t delete_indice( + BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ + const int16_t id /* i : ID of the indice */ +); + +/*! r: value of the indice */ +uint16_t get_next_indice( + Decoder_State *st, /* i/o: decoder state structure */ + int16_t nb_bits /* i : number of bits that were used to quantize the indice */ +); + +/*! r: value of the indice */ +uint16_t get_next_indice_1( + Decoder_State *st /* i/o: decoder state structure */ +); + +void get_next_indice_tmp( + Decoder_State *st, /* o : decoder state structure */ + int16_t nb_bits /* i : number of bits that were used to quantize the indice */ +); + +/*! r: value of the indice */ +uint16_t get_indice( + Decoder_State *st, /* i/o: decoder state structure */ + int16_t pos, /* i : absolute position in the bitstream */ + int16_t nb_bits /* i : number of bits that were used to quantize the indice */ +); + +void reset_indices_dec( + Decoder_State *st /* i/o: decoder state structure */ +); + +Word16 rate2EVSmode_float( + const Word32 brate, /* i : bitrate */ + int16_t *is_amr_wb /* o : (flag) does the bitrate belong to AMR-WB? Can be NULL */ +); + + +/*! r: 1 = OK, 0 = something wrong */ +ivas_error read_indices_fx( + Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ + UWord16 bit_stream[], /* i : bitstream buffer */ + UWord16 num_bits, /* i : number of bits in bitstream */ + Word16 *prev_ft_speech, + Word16 *CNG, + Word16 bfi /* i : bad frame indicator */ +); + + +void ivas_set_bitstream_pointers( + Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */ +); + +Decoder_State **reset_elements( + Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */ +); + +void mdct_switching_dec_ivas_fx( + Decoder_State *st /* i/o: decoder state structure */ +); + +int16_t print_disclaimer( + FILE *fPtr ); + +void fft_rel( + float x[], /* i/o: input/output vector */ + const int16_t n, /* i : vector length */ + const int16_t m /* i : log2 of vector length */ +); + +void preemph_ivas_fx( + Word32 *signal, /* i/o: signal Qx*/ + const Word16 mu, /* i : preemphasis factor Q15*/ + const Word16 L, /* i : vector size Q0*/ + Word32 *mem /* i/o: memory (x[-1]) Qx*/ +); + +void create_offset( + UWord32 *offset_scale1, + UWord32 *offset_scale2, + const int16_t mode, + const int16_t prediction_flag ); + +void BASOP_cfft_ivas( + Word32 *re, /* i/o: real part */ + Word32 *im, /* i/o: imag part */ + Word16 s, /* i : stride real and imag part */ + Word16 *scale /* i : scalefactor */ +); + +Word32 ar_div_ivas( + Word32 num, + Word32 denum ); + +Word32 Mult_32_16( + Word32 a, + Word16 b ); + +Word32 Mult_32_32( + Word32 a, + Word32 b ); + + +void bit_allocation_second_fx2( + Word32 *Rk, + Word32 *Rk_sort, + Word16 BANDS, + const Word16 *band_width, + Word16 *k_sort, + Word16 *k_num, + const Word16 *p2a_flags, + const Word16 p2a_bands, + const Word16 *last_bitalloc, + const Word16 input_frame ); + +void bit_allocation_second_fx2( + Word32 *Rk, + Word32 *Rk_sort, + Word16 BANDS, + const Word16 *band_width, + Word16 *k_sort, + Word16 *k_num, + const Word16 *p2a_flags, + const Word16 p2a_bands, + const Word16 *last_bitalloc, + const Word16 input_frame ); + +#ifdef DEBUGGING +void read_next_force( + int16_t *force, /* i/o: force value (0/1, 0 = speech, 1 = music)*/ + FILE *f_force, /* i : force switching profile (0 if N/A) */ + int32_t *force_profile_cnt /* i/o: counter of frames for force switching profile file */ +); +#endif + +ivas_error init_encoder_ivas_fx( + Encoder_State *st, /* i/o: state structure */ + Encoder_Struct *st_ivas, /* i/o: encoder state structure */ + const Word16 idchan, /* i : channel ID */ + const Word16 var_SID_rate_flag, /* i : flag for variable SID update rate */ + const Word16 interval_SID, /* i : interval for SID update */ + const Word16 vad_only_flag, /* i : flag to indicate front-VAD structure */ + const ISM_MODE ism_mode, /* i : ISM mode */ + const Word32 element_brate /* i : element bitrate */ +); + +ivas_error acelp_core_enc_ivas_fx( + Encoder_State *st, /* i/o: encoder state structure */ + const Word16 inp[], /* i : input signal of the current frame Q_new*/ + Word16 A[NB_SUBFR16k * ( M + 1 )], /* i : A(z) unquantized for the 4 subframes Q12*/ + Word16 Aw[NB_SUBFR16k * ( M + 1 )], /* i : weighted A(z) unquant. for subframes Q12*/ + const Word32 epsP[M + 1], /* i : LP prediction errors Qx*/ + Word16 lsp_new[M], /* i : LSPs at the end of the frame Q15*/ + Word16 lsp_mid[M], /* i : LSPs in the middle of the frame Q15*/ + const Word16 vad_hover_flag, /* i : VAD hangover flag Q0*/ + const Word16 attack_flag, /* i : attack flag (GSC or TC) Q0*/ + Word32 bwe_exc_extended_fx[], /* i/o: bandwidth extended excitation st->prev_Q_bwe_exc*/ + Word16 *voice_factors_fx, /* o : voicing factors Q15*/ + Word16 old_syn_12k8_16k[], /* o : intermediate ACELP synthesis at 12.8kHz or 16kHz to be used by SWB BWE q_old_syn_12k8_16*/ + Word16 *q_old_syn_12k8_16, + Word16 pitch_buf[NB_SUBFR16k], /* o : floating pitch for each subframe Q6*/ + Word16 *unbits, /* o : number of unused bits Q0*/ + STEREO_TD_ENC_DATA_HANDLE hStereoTD, /* i/o: TD stereo encoder handle */ + Word16 tdm_lsfQ_PCh[M], /* i : Q LSFs for primary channel X2.56*/ + Word16 Q_new ); + +void flip_and_downmix_generic_fx_32( + Word32 input[], /* i : input spectrum Qx*/ + Word32 output[], /* o : output spectrum Qx*/ + const Word16 length, /* i : length of spectra */ + Word32 mem1_ext[HILBERT_ORDER1], /* i/o: memory Qx*/ + Word32 mem2_ext[2 * HILBERT_ORDER2], /* i/o: memory Qx*/ + Word32 mem3_ext[2 * HILBERT_ORDER2], /* i/o: memory Qx*/ + Word16 *phase_state /* i/o: Phase state in case frequency isn't multiple of 50 Hz */ +); + +void GenTransition_fixed( + TD_BWE_DEC_HANDLE hBWE_TD, /* i/o: TD BWE data handle */ + Word32 *outputHB_fx, /* o : synthesized HB transitions signal : Q11 */ + const Word32 output_Fs, /* i : output sampling rate : Q0 */ + const Word16 element_mode, /* i : element mode : Q0 */ + const Word16 L_frame, /* i : ACELP frame length : Q0 */ + const Word16 rf_flag, /* i : RF flag : Q0 */ + const Word32 total_brate, /* i : total bitrate : Q0 */ + const Word16 prev_Qx ); + +void GenTransition_WB_fixed( + TD_BWE_DEC_HANDLE hBWE_TD, /* i/o: TD BWE data handle */ + Word32 *outputHB_fx, /* o : synthesized HB transitions signal : Q11 */ + const Word32 output_Fs /* i : output sampling rate */ +); + +Word16 quant_2p_2N1_fx( /* o: return (2*N)+1 bits */ + const Word16 pos1, /* i: position of the pulse 1 */ + const Word16 pos2, /* i: position of the pulse 2 */ + const Word16 N /* i: number of bits FOR position */ +); + +void bands_and_bit_alloc_ivas_fx( + const Word16 cor_strong_limit, /* i : HF correlation */ + const Word16 noise_lev, /* i : dwn scaling factor */ + const Word32 core_brate, /* i : core bit rate */ + const Word16 Diff_len, /* i : Lenght of the difference signal (before pure spectral)*/ + const Word16 bits_used, /* i : Number of bit used before frequency Q */ + Word16 *bit, /* i/o: Number of bit allowed for frequency quantization */ + const Word16 *Ener_per_bd_iQ, /* i/o: Quantized energy vector */ + Word16 *max_ener_band, /* o : Sorted order */ + Word16 *out_bits_per_bands, /* i/o: Number of bit allowed per allowed subband Q3 */ + Word16 *nb_subbands, /* o : Number of subband allowed */ + const Word16 *exc_diff, /* i : Difference signal to quantize (encoder side only) */ + Word16 *concat_in, /* o : Concatened PVQ's input vector (encoder side only) */ + Word16 *pvq_len, /* o : Number of bin covered with the PVQ */ + const Word16 coder_type, /* i : coding type */ + const Word16 bwidth, /* i : input signal bandwidth */ + const Word16 GSC_noisy_speech, /* i : GSC noisy speech flag */ + const Word16 L_frame, /* i : frame length */ + const Word16 element_mode, /* i : element mode */ + const Word16 GSC_IVAS_mode /* i : GSC IVAS mode */ +); + +void ivas_find_wsp_fx( + const Word16 L_frame, /* i : length of the frame Q0*/ + const Word16 L_subfr, /* i : length of subframe Q0*/ + const Word16 nb_subfr, /* i : number of subframes Q0*/ + const Word16 *A_fx, + /* i : A(z) filter coefficients */ // Q12 + Word16 *Aw_fx, + /* o : weighted A(z) filter coefficients */ // Q12 + const Word16 *speech_fx, + /* i : pointer to the denoised speech frame */ // Q_new + const Word16 tilt_fact, + /* i : tilt factor */ // Q15 + Word16 *wsp_fx, + /* o : poitnter to the weighted speech frame */ // Q_new + Word16 *mem_wsp_fx, + /* i/o: W(Z) denominator memory */ // Q_new + const Word16 gamma, + /* i : weighting factor */ // Q15 + const Word16 L_look /* i : look-ahead Q0*/ +); + +Word16 RCcontextMapping_encode2_estimate_bandWise_start_fx( + Word16 *x, /* Q0 */ + const Word16 nt, /* Q0 */ + const Word16 target, /* Q0 */ + HANDLE_RC_CONTEXT_MEM hContextMem ); + +Word16 RCcontextMapping_encode2_estimate_bandWise_fx( + Word16 *x, /* Q0 */ + const Word16 start_line, /* Q0 */ + const Word16 end_line, /* Q0 */ + HANDLE_RC_CONTEXT_MEM hContextMem /* Q0 */ +); + + +/*! r: Q15 */ +Word16 expfp_evs_fx( + const Word16 x, /* i : mantissa Q15-e */ + const Word16 x_e /* i : exponent Q0 */ +); + + +void tcx_arith_render_envelope_ivas_fx( + const Word16 A_ind[], /* i : LPC coefficients of signal envelope Q12*/ + const Word16 L_frame, /* i : number of spectral lines Q0*/ + const Word16 L_spec, /* i : length of the coded spectrum Q0*/ + const Word16 preemph_fac, /* i : pre-emphasis factor Q15*/ + const Word16 gamma_w, /* i : A_ind -> weighted envelope factor Q15*/ + const Word16 gamma_uw, /* i : A_ind -> non-weighted envelope factor Q14*/ + Word32 env[] /* o : shaped signal envelope Q16*/ +); + +void tcx_arith_decode_envelope_ivas_fx( + Decoder_State *st, /* i/o: coder state */ + Word32 q_spectrum[], /* o : quantised MDCT coefficients */ + Word16 *q_spectrum_e, /* o : MDCT exponent */ + const Word16 L_frame, /* i : frame or MDCT length */ + Word16 L_spec, /* i : length w/o BW limitation */ + const Word16 A_ind[], /* i : quantised LPC coefficients */ + const Word16 target_bits, /* i : number of available bits */ + Word16 prm[], /* i : bitstream parameters */ + const Word16 use_hm, /* i : use HM in current frame? */ + const Word16 prm_hm[], /* i : HM parameter area */ + Word16 tcxltp_pitch, /* i : TCX LTP pitch in FD, -1 if n/a*/ + Word16 *arith_bits, /* o : bits used for ari. coding */ + Word16 *signaling_bits, /* o : bits used for signaling */ + const Word16 low_complexity /* i : low-complexity flag */ +); + + +void UnmapIndex_fx( + const Word16 PeriodicityIndex, /* Q0 */ + const Word16 Bandwidth, /* Q0 */ + const Word16 LtpPitchLag, /* Q0 */ + const Word8 SmallerLags, /* Q0 */ + Word16 *FractionalResolution, /* Q0 */ + Word32 *Lag /* Q0 */ +); + +#define GET_ADJ( T, L ) GET_ADJ2( T, L, *FractionalResolution ) +#define GET_ADJ2( T, L, F ) ( ( ( L ) << ( F ) ) - ( T ) ) + + +Word32 tcx_hm_render_fx( + const Word32 lag, /* i: pitch lag Q0 */ + const Word16 fract_res, /* i: fractional resolution of the lag Q0 */ + Word16 p[] /* o: harmonic model Q13 */ +); + + +void tcx_hm_modify_envelope_fx( + const Word16 gain, /* i: HM gain Q11 */ + const Word32 lag, /* i: pitch lag Q0 */ + const Word16 fract_res, /* i: fractional resolution of the lag Q0 */ + const Word16 p[], /* i: harmonic model Q13 */ + Word32 env[], /* i/o: envelope Q16 */ + const Word16 L_frame /* i: number of spectral lines Q0 */ +); + +void tcx_hm_decode( + const Word16 L_frame, /* i : number of spectral lines */ + Word32 env[], /* i/o: envelope shape (Q16) */ + const Word16 targetBits, /* i : target bit budget */ + const Word16 coder_type, /* i : GC/VC coder type */ + const Word16 prm_hm[], /* i : HM parameters */ + const Word16 LtpPitchLag, /* i : LTP pitch lag or -1 if none */ + Word16 *hm_bits /* o : bit consumption */ +); + +void writeTCXMode_fx( + Encoder_State *st, /* i/o: encoder state structure */ + BSTR_ENC_HANDLE hBstr, /* i/o: bitstream handle */ + const Word16 MCT_flag, /* i : hMCT handle allocated (1) or not (0) Q0*/ + Word16 *nbits_start /* o : nbits start Q0*/ +); + +void writeTCXWindowing_fx( + BSTR_ENC_HANDLE hBstr, /* i/o: bitstream handle */ + const Word16 overlap_mode /* i : overlap mode Q0*/ +); + +void writeLPCparam( + Encoder_State *st, /* i/o: encoder state structure */ + BSTR_ENC_HANDLE hBstr, /* i/o: bitstream handle */ + const int16_t param_lpc[], /* i : LPC parameters to write */ + const int16_t bits_param_lpc[], /* i : bits per LPC parameter */ + const int16_t no_param_lpc, /* i : number of LPC parameters */ + int16_t *nbits_lpc /* o : LPC bits written */ +); + +void const *GetTnsOnWhite( void const *p, const int16_t index, int16_t *pValue ); +void *SetTnsOnWhite( void *p, const int16_t index, const int16_t value ); +void const *GetNumOfTnsFilters_flt( void const *p, const int16_t index, int16_t *pValue ); +void *SetNumOfTnsFilters_flt( void *p, const int16_t index, const int16_t value ); + +int16_t DecodeSWBTCX10TnsFilterCoeff_flt( Decoder_State *st, const int16_t index, int16_t *pValue ); +int16_t DecodeSWBTCX20TnsFilterCoeff_flt( Decoder_State *st, const int16_t index, int16_t *pValue ); + +int16_t DecodeWBTCX20TnsFilterCoeff_flt( Decoder_State *st, const int16_t index, int16_t *pValue ); + +int16_t DecodeTnsFilterOrderSWBTCX10_flt( Decoder_State *st, const int16_t index, int16_t *pValue ); +int16_t DecodeTnsFilterOrderSWBTCX20_flt( Decoder_State *st, const int16_t index, int16_t *pValue ); + +int16_t EncodeTnsFilterOrderSWBTCX10_flt( const int16_t value, const int16_t index ); + +int16_t GetTnsFilterOrderBitsSWBTCX10_flt( const int16_t value, const int16_t index ); +int16_t DecodeTnsFilterOrder_flt( Decoder_State *st, const int16_t index, int16_t *pValue ); + +void ResetTnsData_flt( + STnsData *pTnsData ); + +void ClearTnsFilterCoefficients_flt( + STnsFilter *pTnsFilter ); + +void EncodeTnsData( + STnsConfig const *pTnsConfig, /* i : TNS Configuration struct */ + STnsData const *pTnsData, /* i : TNS data struct (quantized param) */ + Word16 *stream, /* o : internal data stream */ + Word16 *pnSize, /* o : number of written parameters */ + Word16 *pnBits /* o : number of written bits */ +); + +Word16 DecodeTnsData_ivas( + STnsConfig const *pTnsConfig, + const Word16 *stream, + Word16 *pnSize, + STnsData *pTnsData ); + +void WriteTnsData( + const STnsConfig *pTnsConfig, /* i : TNS Configuration struct */ + const Word16 *stream, /* i : internal data stream */ + Word16 *pnSize, /* o : number of written parameters */ + BSTR_ENC_HANDLE hBstr, /* o : bitstream */ + Word16 *pnBits /* o : number of written bits */ +); + +void ReadTnsData_ivas( + STnsConfig const *pTnsConfig, + Decoder_State *st, + Word16 *pnBits, + Word16 *stream, + Word16 *pnSize ); + +void analysisCldfbEncoder_ivas_fx( + Encoder_State *st, /* i/o: encoder state structure */ + Word32 *timeIn, /*q11*/ + Word16 timeInq, /*q0*/ + Word16 samplesToProcess, /*q0*/ + Word32 realBuffer[CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + Word32 imagBuffer[CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + Word16 realBuffer16[CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + Word16 imagBuffer16[CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + Word32 *ppBuf_Ener, + Word16 *enerBuffSum_exp, + CLDFB_SCALE_FACTOR *scale ); + +ivas_error openCldfb_ivas( + HANDLE_CLDFB_FILTER_BANK *h_cldfb, /* i/o: filter bank handle */ + CLDFB_TYPE type, /* i : analysis or synthesis */ + const int32_t sampling_rate, /* i : sampling rate */ + CLDFB_PROTOTYPE prototype /* i : CLDFB version (1.25ms/5ms delay) */ +); + +void resampleCldfb_ivas( + HANDLE_CLDFB_FILTER_BANK hs, /* i/o: filter bank handle */ + const Word32 newSamplerate /* i : new samplerate to operate */ +); + +ivas_error cldfb_save_memory_ivas( + HANDLE_CLDFB_FILTER_BANK hs /* i/o: filter bank handle */ +); + +/*! r: flag indicating a valid bitrate */ +Word16 is_EVS_bitrate( + const Word32 ivas_total_brate, /* i : EVS total bitrate */ + Word16 *Opt_AMR_WB /* i : AMR-WB IO flag */ +); + +void IGFEncResetTCX10BitCounter_ivas_fx( + const IGF_ENC_INSTANCE_HANDLE hIGFEnc /* i : instance handle of IGF Encoder */ +); + +ivas_error IGF_Reconfig( + IGF_ENC_INSTANCE_HANDLE *hIGFEnc, /* i/o: instance handle of IGF Encoder */ + const Word16 igf, /* i : IGF on/off */ + const Word16 reset, /* i : reset flag */ + const Word32 brate, /* i : bitrate for configuration */ + const Word16 bwidth, /* i : signal bandwidth */ + const Word16 element_mode, /* i : IVAS element mode */ + const Word16 rf_mode /* i : flag to signal the RF mode */ +); + +void ordr_esti( + const Word16 k, /* i : sub-vector index */ + Word16 *Mpos, /* i/o: dominant sub-vector position from ACV */ + Word16 svOrder[], /* i/o: AVQ sub-vector order */ + const Word16 Nsv /* i : total sub-vectors in a sub-frames */ +); + +/*===========================================================================================*/ +#endif diff --git a/lib_com/pvq_com_fx.c b/lib_com/pvq_com_fx.c index 48ee402ef182f83254b64a6aa52a8a7a8bc26b09..479bc04d9c357ca0101de7e154b903b3e4d75924 100644 --- a/lib_com/pvq_com_fx.c +++ b/lib_com/pvq_com_fx.c @@ -4,7 +4,6 @@ #include #include "options.h" /* Compilation switches */ #include "prot_fx.h" /* Function prototypes */ -#include "prot.h" /* Function prototypes */ #include "cnst.h" /* Common constants */ #include "rom_com.h" /* Static table prototypes */ @@ -457,11 +456,7 @@ void NearOppSplitAdjustment_fx( } *qnear = qboth; /* Q3 */ move16(); -#ifdef BASOP_NOGLOB QIb = extract_h( L_shl_o( L_QIb, 16, &Overflow ) ); /* may saturate Q0*/ -#else - QIb = extract_h( L_shl( L_QIb, 16 ) ); /* may saturate */ -#endif if ( LE_16( QIb, qboth ) ) { *qnear = QIb; /* Q0 */ @@ -515,12 +510,12 @@ void apply_gain_fx( * Fine gain quantization *--------------------------------------------------------------------------*/ void fine_gain_quant_ivas_fx( - BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ - const Word16 *ord, /* i : Indices for energy order Q0 */ - const Word16 num_sfm, /* i : Number of bands Q0 */ - const Word16 *gain_bits, /* i : Gain adjustment bits per sub band Q0 */ - Word16 *fg_pred, /* i/o: Predicted gains / Corrected gains Q11 */ - const Word16 *gopt /* i : Optimal gains Q12 */ + BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ + const Word16 *ord, /* i : Indices for energy order Q0 */ + const Word16 num_sfm, /* i : Number of bands Q0 */ + const Word16 *gain_bits, /* i : Gain adjustment bits per sub band Q0 */ + Word16 *fg_pred, /* i/o: Predicted gains / Corrected gains i:Q12 / o:Q11 */ + const Word16 *gopt /* i : Optimal gains Q12 */ ) { Word16 band; @@ -557,11 +552,7 @@ void fine_gain_quant_ivas_fx( tmp1 = sub( tmp1, exp1 ); L_tmp = L_Comp( tmp1, exp2 ); Mpy_32_16_ss( L_tmp, 24660, &L_tmp, &lsb ); /* 24660 = 20*log10(2) in Q12 */ /*16+12-15=13 */ -#ifdef BASOP_NOGLOB - gain_db = round_fx_sat( L_shl_o( L_tmp, 17, &Overflow ) ); /* Q14 */ -#else /* BASOP_NOGLOB */ - gain_db = round_fx( L_shl( L_tmp, 17 ) ); -#endif + gain_db = round_fx_sat( L_shl_o( L_tmp, 17, &Overflow ) ); /* Q14 */ idx = squant_fx( gain_db, &gain_dbq, finegain_fx[gbits - 1], gain_cb_size[gbits - 1] ); /* Q0 */ push_indice( hBstr, IND_PVQ_FINE_GAIN, idx, gbits ); @@ -577,6 +568,10 @@ void fine_gain_quant_ivas_fx( fg_pred[band] = round_fx( L_shl( L_tmp, sub( 15, exp1 ) ) ); /*12+exp1+16-exp1-16=12 - 1-> Q11*/ move16(); } + ELSE + { + fg_pred[band] = shr( fg_pred[band], 1 ); // Q12 -> Q11 To align all the fg_pred indices in same Q. + } } return; @@ -624,11 +619,7 @@ void fine_gain_quant_fx( tmp1 = sub( tmp1, exp1 ); L_tmp = L_Comp( tmp1, exp2 ); Mpy_32_16_ss( L_tmp, 24660, &L_tmp, &lsb ); /* 24660 = 20*log10(2) in Q12 */ /*16+12-15=13 */ -#ifdef BASOP_NOGLOB gain_db = round_fx_sat( L_shl_o( L_tmp, 17, &Overflow ) ); -#else /* BASOP_NOGLOB */ - gain_db = round_fx( L_shl( L_tmp, 17 ) ); -#endif idx = squant_fx( gain_db, &gain_dbq, finegain_fx[gbits - 1], gain_cb_size[gbits - 1] ); push_indice_fx( hBstr, IND_PVQ_FINE_GAIN, idx, gbits ); diff --git a/lib_com/re8_util_fx.c b/lib_com/re8_util_fx.c index 746b7152ba401e6ac47dc6c51966b9cd9dbbc99a..de70279ebf63772e0a2bd841a2c5633ea1e94dca 100644 --- a/lib_com/re8_util_fx.c +++ b/lib_com/re8_util_fx.c @@ -275,11 +275,7 @@ static Word16 re8_identify_absolute_leader_fx( /* o : integer i { Ls = L_mac( Ls, y[i], y[i] ); /* Q1 */ } -#ifdef BASOP_NOGLOB s = extract_h( L_shl_sat( Ls, 16 - ( 3 + 1 ) ) ); /* s can saturate here */ -#else - s = extract_h( L_shl( Ls, 16 - ( 3 + 1 ) ) ); /* s can saturate here */ -#endif /*-----------------------------------------------------------------------* * compute the index 0 <= ka <= NB_LEADER+1 which identifies an absolute leader of Q0, Q2, Q3 or Q4 * diff --git a/lib_com/reordvct_fx.c b/lib_com/reordvct_fx.c index 3b741203a824b9240d6c4b6ddbbca3d6e795e1d4..62eb2f352665c97f24322207fc2092e4ac2e5c64 100644 --- a/lib_com/reordvct_fx.c +++ b/lib_com/reordvct_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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_com/residu_fx.c b/lib_com/residu_fx.c index 156e81eada140b1322e377afc47e24e24b15efd8..32d18d1feb543401666d751fb554240dce4e8e6f 100644 --- a/lib_com/residu_fx.c +++ b/lib_com/residu_fx.c @@ -7,7 +7,6 @@ #include "cnst.h" /* Common constants */ #include "rom_com.h" /* Static table prototypes */ #include "prot_fx.h" -#include "prot.h" /*--------------------------------------------------------------------* * residu_ivas_fx() @@ -73,62 +72,32 @@ void Residu3_lc_fx( { q = add( q, shift ); } -#ifdef BASOP_NOGLOB *y++ = shl_o( x[0], shift, &Overflow ); -#else - *y++ = shl( x[0], shift ); -#endif move16(); FOR( i = 1; i < m; i++ ) { -#ifdef BASOP_NOGLOB s = L_mult_o( x[i], a[0], &Overflow ); -#else - s = L_mult( x[i], a[0] ); -#endif /* Stop at i to Avoid Mults with Zeros */ FOR( j = 1; j <= i; j++ ) { -#ifdef BASOP_NOGLOB s = L_mac_o( s, x[i - j], a[j], &Overflow ); -#else - s = L_mac( s, x[i - j], a[j] ); -#endif } -#ifdef BASOP_NOGLOB s = L_shl_o( s, q, &Overflow ); *y++ = round_fx_o( s, &Overflow ); -#else - s = L_shl( s, q ); - *y++ = round_fx( s ); -#endif } FOR( ; i < lg; i++ ) { -#ifdef BASOP_NOGLOB s = L_mult_o( x[i], a[0], &Overflow ); -#else - s = L_mult( x[i], a[0] ); -#endif FOR( j = 1; j <= m; j++ ) { -#ifdef BASOP_NOGLOB s = L_mac_o( s, x[i - j], a[j], &Overflow ); -#else - s = L_mac( s, x[i - j], a[j] ); -#endif } -#ifdef BASOP_NOGLOB s = L_shl_o( s, q, &Overflow ); *y++ = round_fx_o( s, &Overflow ); -#else - s = L_shl( s, q ); - *y++ = round_fx( s ); -#endif } } @@ -161,11 +130,7 @@ void Residu3_10_fx( s64 = W_mac_16_16( s64, x[i - j], a[j] ); } s = W_shl_sat_l( s64, q ); -#ifdef BASOP_NOGLOB y[i] = round_fx_sat( s ); -#else - y[i] = round_fx( s ); -#endif } } /*--------------------------------------------------------------------* @@ -205,12 +170,8 @@ void Residu3_fx( } s64 = W_mac_16_16( s64, x[i - 16], a[16] ); s32 = W_shl_sat_l( s64, q ); -#ifdef BASOP_NOGLOB y[i] = round_fx_o( s32, &Overflow ); move16(); -#else /* BASOP_NOGLOB */ - y[i] = round_fx( s32 ); -#endif } } /*==========================================================================*/ diff --git a/lib_com/rom_basop_util.c b/lib_com/rom_basop_util.c index 4a0eed6b617dfd1bc85101be3a0ea2f24eaed5e8..eb79cc02648c67df6dbd075f3da2a9704142e2f8 100644 --- a/lib_com/rom_basop_util.c +++ b/lib_com/rom_basop_util.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other @@ -1449,7 +1449,7 @@ void BASOP_getTables( const PWord16 **ptwiddle /*Q15*/, const PWord16 **sin_twid ld2_length = sub( 16 - 1 - 1, norm_s( length ) ); /* Extract sort of "eigenvalue" (the 5 left most bits) of length. */ - SWITCH( (unsigned short) L_shl( length, sub( 15, ld2_length ) ) ) + SWITCH( (UWord16) L_shl( length, sub( 15, ld2_length ) ) ) { case 0xa000: /* 640 */ move16(); diff --git a/lib_com/rom_basop_util.h b/lib_com/rom_basop_util.h index f2e81f0a175ccb7bc2f948519e2a5e58a1d8eb8a..e7811db89fa50d2dce8a529ae386ae1654dd03bc 100644 --- a/lib_com/rom_basop_util.h +++ b/lib_com/rom_basop_util.h @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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_com/rom_com.c b/lib_com/rom_com.c index 612e30bdf6d5a833984683cc135d7797466c2f83..172dadf82da9d517192d902c04d101cc1f3c6453 100644 --- a/lib_com/rom_com.c +++ b/lib_com/rom_com.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other @@ -38,10 +38,9 @@ #include "options.h" #include "cnst.h" #include "rom_com.h" -#include "prot.h" +#include "prot_fx.h" #include "basop_util.h" #include "wmc_auto.h" -#include "prot_fx.h" /* clang-format off */ @@ -14271,6 +14270,25 @@ const Word16 win_lpc_hb_wb_fx[(L_LOOK_12k8 + L_SUBFR + L_FRAME) * 5 / 32] = 32611, 32698, 32751 }; +const Word16 win_lpc_hb_wb_ivas_fx[(L_LOOK_12k8 + L_SUBFR + L_FRAME) * 5 / 32] = +{//Q15 + 6, 51, 140, 274, + 453, 675, 940, 1247, + 1596, 1985, 2414, 2882, + 3386, 3926, 4499, 5106, + 5743, 6410, 7104, 7823, + 8566, 9331, 10114, 10915, + 11731, 12559, 13398, 14245, + 15099, 15955, 16813, 17669, + 18523, 19370, 20209, 21037, + 21853, 22654, 23437, 24202, + 24945, 25664, 26358, 27025, + 27662, 28269, 28842, 29382, + 29886, 30354, 30783, 31172, + 31521, 31828, 32093, 32315, + 32494, 32628, 32717, 32762 +}; + const Word16 ola_win_shb_switch_fold_fx[L_SUBFR16k] = {//Q15 diff --git a/lib_com/rom_com.h b/lib_com/rom_com.h index 431c6b7047870558f861250a47cbd42b32b68e73..33661fb581a9db3b345637c5505c79c3b1c7d62d 100644 --- a/lib_com/rom_com.h +++ b/lib_com/rom_com.h @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other @@ -66,7 +66,7 @@ typedef struct Word16 filt_len; /* number of filter coeff. */ Word16 filt_len_fx; /* number of filter coeff. Q0 */ - uint16_t flags; /* flags from config. table */ + UWord16 flags; /* flags from config. table */ UWord16 flags_fx; /* flags from config. table Q0 */ // UNS_Word16 flags_fx; /* flags from config. table Q0 */ @@ -612,6 +612,7 @@ extern const Word16 cos_fb_exc_fx[32]; // Q15 extern const Word16 win_lpc_shb_fx[]; // Q15 /* Window for calculating SHB LPC coeffs */ extern const Word16 win_lpc_hb_wb_fx[]; // Q15 +extern const Word16 win_lpc_hb_wb_ivas_fx[]; // Q15 extern const Word16 ola_win_shb_switch_fold_fx[]; // Q15 extern const Word16 win_flatten_fx[]; // Q15 extern const Word16 win_flatten_4k_fx[]; // Q15 diff --git a/lib_com/rom_com_fx.c b/lib_com/rom_com_fx.c index e669a899593f299b38e4b84a13926a140188c5d1..49f50e1622ba4a26b851bc236695c6e4b472078d 100644 --- a/lib_com/rom_com_fx.c +++ b/lib_com/rom_com_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other @@ -38,7 +38,7 @@ EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 ====================================================================================*/ -#include "prot.h" +#include "prot_fx.h" #include "basop_util.h" #include "wmc_auto.h" #include "rom_com_fx.h" diff --git a/lib_com/rom_com_fx.h b/lib_com/rom_com_fx.h index 5c30ad5da6d01b2350a609285938fef00a34e265..29e7637574ac2d2085f44ff635a71493440b7444 100644 --- a/lib_com/rom_com_fx.h +++ b/lib_com/rom_com_fx.h @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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_com/scale_mem_fx.c b/lib_com/scale_mem_fx.c index 9dd997680bf4a009fc03d4e30d3a29f2b9e91eb9..2ce2ffd12b8aad3cf41c48a53bfb7c253b1ee80b 100644 --- a/lib_com/scale_mem_fx.c +++ b/lib_com/scale_mem_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other @@ -307,8 +307,15 @@ void scale_sig32( /* saturation can occur here */ x[i] = L_shl( x[i], exp0 ); move32(); +#ifdef OPT_STEREO_32KBPS_V1 + if ( 0 == exp0 ) + { + i = lg; + } +#endif /* OPT_STEREO_32KBPS_V1 */ } } + void scale_sig32_r( Word32 x[], /* i/o: signal to scale Qx */ const Word16 lg, /* i : size of x[] Q0 */ @@ -322,6 +329,12 @@ void scale_sig32_r( /* saturation can occur here */ x[i] = L_shl_r( x[i], exp0 ); move32(); +#ifdef OPT_STEREO_32KBPS_V1 + if ( 0 == exp0 ) + { + i = lg; + } +#endif /* OPT_STEREO_32KBPS_V1 */ } } diff --git a/lib_com/stab_est_fx.c b/lib_com/stab_est_fx.c index 73d58af44d8490e334a6e8f734a20a43392a6684..15cd254dfb9fbb09fc2dcacf3828682921c94baf 100644 --- a/lib_com/stab_est_fx.c +++ b/lib_com/stab_est_fx.c @@ -73,11 +73,7 @@ Word16 stab_est_fx( { /*fcorr += ftmp_c*ftmp_c;*/ tmp16 = sub( lt_diff_etot[i], mean_diff ); -#ifdef BASOP_NOGLOB L_tmp = L_mac0_sat( L_tmp, tmp16, tmp16 ); -#else - L_tmp = L_mac0( L_tmp, tmp16, tmp16 ); -#endif } /*------------------------------------------------------------------------* * Update @@ -96,22 +92,14 @@ Word16 stab_est_fx( exp1 = norm_l( L_tmp ); L_tmp = L_shl( L_tmp, exp1 ); -#ifdef BASOP_NOGLOB tmp16 = round_fx_sat( L_tmp ); -#else - tmp16 = round_fx( L_tmp ); -#endif exp2 = sub( 31, exp1 ); L_tmp = Isqrt_lc( L_tmp, &exp2 ); L_tmp = Mpy_32_16_1( L_tmp, tmp16 ); /* we now have sqrt(L_corr) Q24 (8+16)*/ exp2 = sub( 31 - 15, sub( exp1, exp2 ) ); /* for Q8 (because of -8^2 from Etot)*/ - L_tmp = L_shl( L_tmp, exp2 ); /* Q8 + Q16*/ -#ifdef BASOP_NOGLOB + L_tmp = L_shl( L_tmp, exp2 ); /* Q8 + Q16*/ dev = extract_h( L_shl_sat( L_tmp, 3 ) ); /* Q(24+3-16) -> Q11 */ -#else /* BASOP_NOGLOB */ - dev = extract_h( L_shl( L_tmp, 3 ) ); /* Q(24+3-16) -> Q11 */ -#endif /*------------------------------------------------------------------------* * State machine to decide level of inter-harmonic noise reduction and diff --git a/lib_com/stat_com.h b/lib_com/stat_com.h index 78d358be577431cdc976dc0c1702b2317a471d24..c96dcc88479af40b7cff82494dd4069a4dde2ebf 100644 --- a/lib_com/stat_com.h +++ b/lib_com/stat_com.h @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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,7 @@ typedef struct typedef struct { Word16 lead_sign_ind; - uint32_t index, size; + UWord32 index, size; Word16 dim, k_val; } PvqEntry; @@ -102,6 +102,13 @@ typedef struct } ARCODEC, *PARCODEC; +struct dispMem_fx +{ + Word16 prev_state; /*Q0 */ + Word32 prev_gain_code; /*Q16 */ + Word16 prev_gain_pit[6]; /*Q14 */ +}; + /*---------------------------------------------------------------* * ACELP Encoder/Decoder Static RAM * *---------------------------------------------------------------*/ @@ -190,6 +197,8 @@ typedef struct TNS_filter_structure Word16 order; /* Filter order. */ Word16 coefIndex[TNS_MAX_FILTER_ORDER]; /* Quantized filter coefficients. */ Word16 predictionGain; /* Prediction gain. The ratio of a signal and TNS residual energy. E(PRED_GAIN_E), Q7 */ + Word32 predictionGain32; /* Prediction gain. The ratio of a signal and TNS residual energy. predictionGain_e */ + Word16 predictionGain_e; /*Exponent for predictionGain32 */ Word16 avgSqrCoef; /* Average squared filter coefficient. E(0), Q15 */ } STnsFilter; @@ -304,7 +313,7 @@ typedef struct { Word32 low; Word32 high; - uint32_t value; + UWord32 value; Word32 bits_to_follow; } Tastat; typedef struct @@ -411,7 +420,7 @@ typedef struct Word16 psize_norm[NPART]; /* Partition sizes, fractional variable Q15-psize_norm_exp*/ Word16 psize_inv[NPART]; /* Inverse of partition sizes Q15*/ // Word16 FFTscalingFactor; /* Squared ratio between core signal analysis FFT and noise estimator FFT */ - Word16 scalingFactor; // Q15 + Word16 scalingFactor; // exp = -15 Word16 invScalingFactor; // Q15 Word16 nCLDFBpart; /* Number of CLDFB spectral partitions */ Word16 CLDFBpart[NPARTCLDFB]; /* CLDFB Partition upper boundaries (band indices starting from 0 above the core coder bands) */ @@ -481,15 +490,6 @@ typedef Word16 ( *TEncodeValue )( Word16 value, Word16 index ); */ typedef Word16 ( *TDecodeValue )( struct Decoder_State *st, Word16 index, Word16 *pValue ); -/** Linear prediction analysis/synthesis filter definition. - * @param order filter order. - * @param parCoeff filter (PARCOR) coefficients. - * @param state state of the filter. Must be at least of 'order' size. - * @param x the current input value. - * @return the output of the filter. - */ -typedef float ( *TLinearPredictionFilter_flt )( const int16_t order, const float parCoeff[], float *state, float x ); - /** Structure that defines mapping between a parameter and a bitstream. */ typedef struct ParamBitMap { diff --git a/lib_com/stat_noise_uv_mod_fx.c b/lib_com/stat_noise_uv_mod_fx.c index e4771a1834bc6c5bb5d3bdf397e8ad9abc8ff4f3..67ca21cd29c3dd2ffae186785dfcd32794b3201f 100644 --- a/lib_com/stat_noise_uv_mod_fx.c +++ b/lib_com/stat_noise_uv_mod_fx.c @@ -109,11 +109,7 @@ void stat_noise_uv_mod_fx( move16(); tmp_res = div_l( L_tmp_res, tmp_den ); move16(); -#ifdef BASOP_NOGLOB min_alpha = add_o( tmp_res, 16384, &Overflow ); -#else /* BASOP_NOGLOB */ - min_alpha = add( tmp_res, 16384 ); -#endif /* BASOP_NOGLOB */ move16(); /**st_min_alpha = sub(*st_min_alpha, 1638); move16();*/ @@ -164,12 +160,8 @@ void stat_noise_uv_mod_fx( { FOR( i_subfr = 0; i_subfr < L_FRAME; i_subfr += L_SUBFR ) { - exctilt = calc_tilt_fx( &Exc2_local[i_subfr], En_shift, L_SUBFR ); /*Q15 */ -#ifdef BASOP_NOGLOB + exctilt = calc_tilt_fx( &Exc2_local[i_subfr], En_shift, L_SUBFR ); /*Q15 */ exctilt = mult( shl_o( sub( TILT_COMP_LIM_FX, min_alpha ), 2, &Overflow ), exctilt ); /*Q15 */ -#else /* BASOP_NOGLOB */ - exctilt = mult( shl( sub( TILT_COMP_LIM_FX, min_alpha ), 2 ), exctilt ); /*Q15 */ -#endif /* BASOP_NOGLOB */ PREEMPH_FX( &Exc2_local[i_subfr], exctilt, L_SUBFR, exc_pe ); } @@ -194,11 +186,7 @@ void stat_noise_uv_mod_fx( tmp_shift = norm_s( tmp_den ); tmp_den = shl( tmp_den, tmp_shift ); tmp_res = div_s( tmp_nom, tmp_den ); -#ifdef BASOP_NOGLOB tmp_res = shl_o( tmp_res, tmp_shift, &Overflow ); -#else /* BASOP_NOGLOB */ - tmp_res = shl( tmp_res, tmp_shift ); -#endif alpha = add( 32767, mult( tmp_res, sub( min_alpha, 32767 ) ) ); *act_count = 0; @@ -213,11 +201,7 @@ void stat_noise_uv_mod_fx( FOR( i = 1; i < L_FRAME; i++ ) { Tmp = shr( Exc2_local[i], En_shift ); -#ifdef BASOP_NOGLOB vare = L_mac_sat( vare, Tmp, Tmp ); /* positive accumulation only */ -#else - vare = L_mac( vare, Tmp, Tmp ); /* positive accumulation only */ -#endif } /* obtain Ge in Q_local with safety saturation */ @@ -261,20 +245,12 @@ void stat_noise_uv_mod_fx( /* L_Ge might be 0 in unvoiced WB */ L_Ge = L_max( L_Ge, 1 ); tmp_shift = norm_l( L_Ge ); - tmp_den = extract_h( L_shl( L_Ge, tmp_shift ) ); /* Q_local+Q_ge+tmp_shift-16 */ - tmp_res = div_s( 1 << 14, tmp_den ); /* 15+14-Q_local-tmp_shift-Q_ge+16 */ - L_tmp_res = Mult_32_16( *ge_sm, tmp_res ); /* Q_stat_noise_ge+45-Q_local-Q_ge-tmp_shift-15 */ - L_tmp_res = Mult_32_16( L_tmp_res, sub( 32767, beta ) ); /*30-Q_local-tmp_shift+15-15 */ -#ifdef BASOP_NOGLOB + tmp_den = extract_h( L_shl( L_Ge, tmp_shift ) ); /* Q_local+Q_ge+tmp_shift-16 */ + tmp_res = div_s( 1 << 14, tmp_den ); /* 15+14-Q_local-tmp_shift-Q_ge+16 */ + L_tmp_res = Mult_32_16( *ge_sm, tmp_res ); /* Q_stat_noise_ge+45-Q_local-Q_ge-tmp_shift-15 */ + L_tmp_res = Mult_32_16( L_tmp_res, sub( 32767, beta ) ); /*30-Q_local-tmp_shift+15-15 */ L_tmp_res = L_add_sat( L_shl_sat( L_tmp_res, sub( add( Q_local, tmp_shift ), 15 ) ), beta ); /* Q15 */ -#else - L_tmp_res = L_add( L_shl( L_tmp_res, sub( add( Q_local, tmp_shift ), 15 ) ), beta ); /* Q15 */ -#endif -#ifdef BASOP_NOGLOB - tmp_res = extract_h( L_shl_o( L_tmp_res, 15, &Overflow ) ); /* 15+15-16=14 */ -#else - tmp_res = extract_h( L_shl( L_tmp_res, 15 ) ); /* 15+15-16=14 */ -#endif + tmp_res = extract_h( L_shl_o( L_tmp_res, 15, &Overflow ) ); /* 15+15-16=14 */ Noimix_fract = extract_l( Mult_32_16( L_tmp_res, Noimix_fract ) ); /*15+15-15 */ @@ -292,15 +268,11 @@ void stat_noise_uv_mod_fx( randval = mult_r( 28378, randval ); /* Q downscaled by 2 bits ends up in Q14 */ /*sqrt(12.0f) in Q13*/ randval = extract_l( L_shl( Mult_32_16( L_Ge, randval ), 1 - *Q_stat_noise_ge ) ); /*Q_local+Q_ge+14-15+1-Q_ge=Q_local */ - L_tmp = L_mult( Exc2_local[i], alpha ); /* Q_local + 16 */ - L_tmp = L_mac( L_tmp, randval, alpha_m1 ); /* Q_local + 16 */ - L_tmp3 = Mult_32_16( L_tmp, Noimix_fract ); /* Q_local+16+15-15 */ -#ifdef BASOP_NOGLOB + L_tmp = L_mult( Exc2_local[i], alpha ); /* Q_local + 16 */ + L_tmp = L_mac( L_tmp, randval, alpha_m1 ); /* Q_local + 16 */ + L_tmp3 = Mult_32_16( L_tmp, Noimix_fract ); /* Q_local+16+15-15 */ L_tmp = L_add_sat( L_tmp3, L_shl_sat( Mult_32_16( L_tmp, tmp_res ), 1 ) ); /* Q_local+16+14-15+1 */ -#else - L_tmp = L_add( L_tmp3, L_shl( Mult_32_16( L_tmp, tmp_res ), 1 ) ); /* Q_local+16+14-15+1 */ -#endif - Exc2_local[i] = extract_h( L_tmp ); /*Q_local */ + Exc2_local[i] = extract_h( L_tmp ); /*Q_local */ move16(); } *Q_stat_noise = Q_local; /* update for next call, routine can only be called once every frame */ @@ -443,11 +415,7 @@ void stat_noise_uv_mod_ivas_fx( L_tmp_res = L_shl( L_tmp_res, sub( tmp_shift, 1 ) ); tmp_den = shl( tmp_den, tmp_shift ); tmp_res = div_l( L_tmp_res, tmp_den ); -#ifdef BASOP_NOGLOB min_alpha = add_o( tmp_res, 16384, &Overflow ); -#else /* BASOP_NOGLOB */ - min_alpha = add( tmp_res, 16384 ); -#endif /* BASOP_NOGLOB */ /**st_min_alpha = sub(*st_min_alpha, 1638); move16();*/ min_alpha = s_max( min_alpha, sub( *st_min_alpha, 1638 ) ); @@ -497,12 +465,8 @@ void stat_noise_uv_mod_ivas_fx( { FOR( i_subfr = 0; i_subfr < L_FRAME; i_subfr += L_SUBFR ) { - exctilt = calc_tilt_fx( &Exc2_local[i_subfr], En_shift, L_SUBFR ); /*Q15 */ -#ifdef BASOP_NOGLOB + exctilt = calc_tilt_fx( &Exc2_local[i_subfr], En_shift, L_SUBFR ); /*Q15 */ exctilt = mult( shl_o( sub( TILT_COMP_LIM_FX, min_alpha ), 2, &Overflow ), exctilt ); /*Q15 */ -#else /* BASOP_NOGLOB */ - exctilt = mult( shl( sub( TILT_COMP_LIM_FX, min_alpha ), 2 ), exctilt ); /*Q15 */ -#endif /* BASOP_NOGLOB */ PREEMPH_FX( &Exc2_local[i_subfr], exctilt, L_SUBFR, exc_pe ); } @@ -527,11 +491,7 @@ void stat_noise_uv_mod_ivas_fx( tmp_shift = norm_s( tmp_den ); tmp_den = shl( tmp_den, tmp_shift ); tmp_res = div_s( tmp_nom, tmp_den ); -#ifdef BASOP_NOGLOB tmp_res = shl_o( tmp_res, tmp_shift, &Overflow ); -#else /* BASOP_NOGLOB */ - tmp_res = shl( tmp_res, tmp_shift ); -#endif alpha = add( 32767, mult( tmp_res, sub( min_alpha, 32767 ) ) ); *act_count = 0; @@ -546,11 +506,7 @@ void stat_noise_uv_mod_ivas_fx( FOR( i = 1; i < L_FRAME; i++ ) { Tmp = shr( Exc2_local[i], En_shift ); -#ifdef BASOP_NOGLOB vare = L_mac_sat( vare, Tmp, Tmp ); /* positive accumulation only */ -#else - vare = L_mac( vare, Tmp, Tmp ); /* positive accumulation only */ -#endif } /* obtain Ge in Q_local with safety saturation */ @@ -594,20 +550,12 @@ void stat_noise_uv_mod_ivas_fx( /* L_Ge might be 0 in unvoiced WB */ L_Ge = L_max( L_Ge, 1 ); tmp_shift = norm_l( L_Ge ); - tmp_den = extract_h( L_shl( L_Ge, tmp_shift ) ); /* Q_local+Q_ge+tmp_shift-16 */ - tmp_res = div_s( 1 << 14, tmp_den ); /* 15+14-Q_local-tmp_shift-Q_ge+16 */ - L_tmp_res = Mult_32_16( *ge_sm, tmp_res ); /* Q_stat_noise_ge+45-Q_local-Q_ge-tmp_shift-15 */ - L_tmp_res = Mult_32_16( L_tmp_res, sub( 32767, beta ) ); /*30-Q_local-tmp_shift+15-15 */ -#ifdef BASOP_NOGLOB + tmp_den = extract_h( L_shl( L_Ge, tmp_shift ) ); /* Q_local+Q_ge+tmp_shift-16 */ + tmp_res = div_s( 1 << 14, tmp_den ); /* 15+14-Q_local-tmp_shift-Q_ge+16 */ + L_tmp_res = Mult_32_16( *ge_sm, tmp_res ); /* Q_stat_noise_ge+45-Q_local-Q_ge-tmp_shift-15 */ + L_tmp_res = Mult_32_16( L_tmp_res, sub( 32767, beta ) ); /*30-Q_local-tmp_shift+15-15 */ L_tmp_res = L_add_sat( L_shl_sat( L_tmp_res, sub( add( Q_local, tmp_shift ), 15 ) ), beta ); /* Q15 */ -#else - L_tmp_res = L_add( L_shl( L_tmp_res, sub( add( Q_local, tmp_shift ), 15 ) ), beta ); /* Q15 */ -#endif -#ifdef BASOP_NOGLOB - tmp_res = extract_h( L_shl_o( L_tmp_res, 15, &Overflow ) ); /* 15+15-16=14 */ -#else - tmp_res = extract_h( L_shl( L_tmp_res, 15 ) ); /* 15+15-16=14 */ -#endif + tmp_res = extract_h( L_shl_o( L_tmp_res, 15, &Overflow ) ); /* 15+15-16=14 */ Noimix_fract = extract_l( Mult_32_16( L_tmp_res, Noimix_fract ) ); /*15+15-15 */ @@ -625,15 +573,11 @@ void stat_noise_uv_mod_ivas_fx( randval = mult_r( 28378, randval ); /* Q downscaled by 2 bits ends up in Q14 */ /*sqrt(12.0f) in Q13*/ randval = extract_l( L_shl( Mult_32_16( L_Ge, randval ), sub( 1, *Q_stat_noise_ge ) ) ); /*Q_local+Q_ge+14-15+1-Q_ge=Q_local */ - L_tmp = L_mult( Exc2_local[i], alpha ); /* Q_local + 16 */ - L_tmp = L_mac( L_tmp, randval, alpha_m1 ); /* Q_local + 16 */ - L_tmp3 = Mult_32_16( L_tmp, Noimix_fract ); /* Q_local+16+15-15 */ -#ifdef BASOP_NOGLOB + L_tmp = L_mult( Exc2_local[i], alpha ); /* Q_local + 16 */ + L_tmp = L_mac( L_tmp, randval, alpha_m1 ); /* Q_local + 16 */ + L_tmp3 = Mult_32_16( L_tmp, Noimix_fract ); /* Q_local+16+15-15 */ L_tmp = L_add_sat( L_tmp3, L_shl_sat( Mult_32_16( L_tmp, tmp_res ), 1 ) ); /* Q_local+16+14-15+1 */ -#else - L_tmp = L_add( L_tmp3, L_shl( Mult_32_16( L_tmp, tmp_res ), 1 ) ); /* Q_local+16+14-15+1 */ -#endif - Exc2_local[i] = extract_h( L_tmp ); /*Q_local */ + Exc2_local[i] = extract_h( L_tmp ); /*Q_local */ move16(); } *Q_stat_noise = Q_local; /* update for next call, routine can only be called once every frame */ @@ -717,17 +661,9 @@ static Word16 calc_tilt_fx( /* o : Excitation tilt Q15*/ { /* r0 = L_mac(r0,x[i],x[i]) */ /* r1 = L_mac(r1,x[i],x[i+1]) -> correlation loop can be optimized */ -#ifdef BASOP_NOGLOB r0 = L_mac_sat( r0, xi, xi ); -#else - r0 = L_mac( r0, xi, xi ); -#endif xi_p1 = shr( x[i + 1], Q_shift ); -#ifdef BASOP_NOGLOB r1 = L_mac_sat( r1, xi, xi_p1 ); -#else - r1 = L_mac( r1, xi, xi_p1 ); -#endif xi = xi_p1; move16(); } @@ -749,11 +685,7 @@ static Word16 calc_tilt_fx( /* o : Excitation tilt Q15*/ r1 = L_abs( r1 ); L_tmp_res = Div_32( r1, extract_h( r0 ), extract_l( r0 ) ); -#ifdef BASOP_NOGLOB L_tmp_res = L_shl_sat( L_tmp_res, tmp_shift ); /*Q31 */ -#else - L_tmp_res = L_shl( L_tmp_res, tmp_shift ); /*Q31 */ -#endif if ( tmp_sign != 0 ) { L_tmp_res = L_negate( L_tmp_res ); /*Q31 */ diff --git a/lib_com/stl.h b/lib_com/stl.h index 6643f5948d80c4a7260efbc6de80b2b20a4a1aee..0de974226623ff746492cf57aea4be1210dfbd37 100644 --- a/lib_com/stl.h +++ b/lib_com/stl.h @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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_com/swb_bwe_com_fx.c b/lib_com/swb_bwe_com_fx.c index bd22e7e4259ec48ffc7a2626da5143c2fec263bc..eda099cd93a4d2bf25843d1e4db24e9c4b98ba47 100644 --- a/lib_com/swb_bwe_com_fx.c +++ b/lib_com/swb_bwe_com_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other @@ -99,31 +99,19 @@ Word16 WB_BWE_gain_pred_fx( enerL = L_deposit_l( 0 ); FOR( n_freq = 128; n_freq < 192; n_freq++ ) { -#ifdef BASOP_NOGLOB enerL = L_mac0_sat( enerL, core_dec_freq[n_freq], core_dec_freq[n_freq] ); /*2(Q_syn) */ -#else - enerL = L_mac0( enerL, core_dec_freq[n_freq], core_dec_freq[n_freq] ); /*2(Q_syn) */ -#endif } L_WB_fenv0 = L_deposit_l( 0 ); FOR( n_freq = 192; n_freq < 224; n_freq++ ) { -#ifdef BASOP_NOGLOB L_WB_fenv0 = L_mac0_sat( L_WB_fenv0, core_dec_freq[n_freq], core_dec_freq[n_freq] ); /*2*Q_syn */ -#else - L_WB_fenv0 = L_mac0( L_WB_fenv0, core_dec_freq[n_freq], core_dec_freq[n_freq] ); /*2*Q_syn */ -#endif } L_WB_fenv1 = L_deposit_l( 0 ); FOR( n_freq = 224; n_freq < 256; n_freq++ ) { -#ifdef BASOP_NOGLOB L_WB_fenv1 = L_mac0_sat( L_WB_fenv1, core_dec_freq[n_freq], core_dec_freq[n_freq] ); /*2*Q_syn */ -#else - L_WB_fenv1 = L_mac0( L_WB_fenv1, core_dec_freq[n_freq], core_dec_freq[n_freq] ); /*2*Q_syn */ -#endif } L_tmp = sum16_32_fx( voice_factors, 4 ); @@ -141,11 +129,7 @@ Word16 WB_BWE_gain_pred_fx( } test(); -#ifdef BASOP_NOGLOB IF( GT_32( L_WB_fenv0, L_shl_sat( L_WB_fenv1, 1 ) ) ) -#else - IF( GT_32( L_WB_fenv0, L_shl( L_WB_fenv1, 1 ) ) ) -#endif { exp = norm_l( L_WB_fenv0 ); tmp = extract_h( L_shl( L_WB_fenv0, exp ) ); @@ -156,11 +140,7 @@ Word16 WB_BWE_gain_pred_fx( alfa = s_max( tmp, 3277 /* 0.1 in Q15 */ ); /*Q15 */ L_WB_fenv0 = Mult_32_16( L_WB_fenv0, alfa ); /*2*Q_syn+15-15->2*Q_syn */ } -#ifdef BASOP_NOGLOB ELSE IF( GT_32( L_WB_fenv1, L_shl_sat( L_WB_fenv0, 1 ) ) && NE_16( coder_type, UNVOICED ) ) -#else - ELSE IF( GT_32( L_WB_fenv1, L_shl( L_WB_fenv0, 1 ) ) && NE_16( coder_type, UNVOICED ) ) -#endif { exp = norm_l( L_WB_fenv1 ); tmp = extract_h( L_shl( L_WB_fenv1, exp ) ); @@ -187,11 +167,7 @@ Word16 WB_BWE_gain_pred_fx( enerL = L_deposit_l( 1 ); } -#ifdef BASOP_NOGLOB L_tmp = L_add_sat( L_WB_fenv0, L_WB_fenv1 ); /* In 2*Q_syn */ -#else - L_tmp = L_add( L_WB_fenv0, L_WB_fenv1 ); /* In 2*Q_syn */ -#endif exp = norm_l( L_tmp ); tmp = extract_h( L_shl( L_tmp, exp ) ); /*exp = sub(exp, 30-(2*Q_syn+6)); //+6(/64) */ @@ -201,21 +177,13 @@ Word16 WB_BWE_gain_pred_fx( L_tmp = L_deposit_h( tmp ); L_tmp = Isqrt_lc( L_tmp, &exp ); -#ifdef BASOP_NOGLOB WB_fenv[0] = round_fx_sat( L_shl_sat( L_tmp, sub( exp, 12 ) ) ); /* Q3 */ move16(); -#else - WB_fenv[0] = round_fx( L_shl( L_tmp, sub( exp, 12 ) ) ); /* Q3 */ -#endif test(); test(); IF( NE_16( coder_type, AUDIO ) && NE_16( coder_type, UNVOICED ) && ener_var_flag == 0 ) { -#ifdef BASOP_NOGLOB WB_fenv[0] = add_sat( WB_fenv[0], mult_r_sat( WB_fenv[0], 16384 /* 0.5 in Q15 */ ) ); -#else - WB_fenv[0] = add( WB_fenv[0], mult_r( WB_fenv[0], 16384 /* 0.5 in Q15 */ ) ); -#endif move16(); } @@ -226,12 +194,8 @@ Word16 WB_BWE_gain_pred_fx( tmp = div_s( 16384, tmp ); L_tmp = L_deposit_h( tmp ); L_tmp = Isqrt_lc( L_tmp, &exp ); -#ifdef BASOP_NOGLOB enerL_16 = round_fx_sat( L_shl_sat( L_tmp, sub( exp, 15 ) ) ); /* Q0 */ -#else - enerL_16 = round_fx( L_shl( L_tmp, sub( exp, 15 ) ) ); /* Q0 */ -#endif - enerL_40 = mult_r( 6554 /* 0.2 in Q15 */, enerL_16 ); /*1/40 in Q18 ->Q3 */ + enerL_40 = mult_r( 6554 /* 0.2 in Q15 */, enerL_16 ); /*1/40 in Q18 ->Q3 */ test(); test(); @@ -245,13 +209,9 @@ Word16 WB_BWE_gain_pred_fx( IF( WB_fenv[0] != 0 ) { exp = norm_s( WB_fenv[0] ); - tmp = div_s( shl( 1, sub( 14, exp ) ), WB_fenv[0] ); /*Q(29-exp-3) */ - L_tmp = L_mult( enerL_40, tmp ); /*Q(30-exp) */ -#ifdef BASOP_NOGLOB + tmp = div_s( shl( 1, sub( 14, exp ) ), WB_fenv[0] ); /*Q(29-exp-3) */ + L_tmp = L_mult( enerL_40, tmp ); /*Q(30-exp) */ tmp = round_fx_sat( L_shl_sat( L_tmp, sub( exp, 2 ) ) ); /*Q12 */ -#else - tmp = round_fx( L_shl( L_tmp, sub( exp, 2 ) ) ); /*Q12 */ -#endif tmp = s_min( tmp, 16384 /*4 in Q12*/ ); L_tmp = L_shr( L_mult0( tmp, WB_fenv[0] ), 12 ); /*Q15 */ WB_fenv[0] = extract_l( L_tmp ); /*Q3 */ @@ -270,13 +230,9 @@ Word16 WB_BWE_gain_pred_fx( tmp1 = extract_l( L_shr( L_tmp, 13 ) ); exp = norm_s( pitch ); - tmp = div_s( shl( 1, sub( 14, exp ) ), pitch ); /*Q(29-exp-5) */ - L_tmp = L_mult0( tmp1, tmp ); /*29-exp-5->24-exp */ -#ifdef BASOP_NOGLOB + tmp = div_s( shl( 1, sub( 14, exp ) ), pitch ); /*Q(29-exp-5) */ + L_tmp = L_mult0( tmp1, tmp ); /*29-exp-5->24-exp */ tmp = round_fx_sat( L_shl_sat( L_tmp, add( exp, 6 ) ) ); /*14 */ -#else - tmp = round_fx( L_shl( L_tmp, add( exp, 6 ) ) ); /*14 */ -#endif tmp1 = s_max( tmp, 8192 /* 0.5 in Q14 */ ); alfa = s_min( 24576 /* 1.5 in Q14 */, tmp1 ); /*Q14 */ @@ -285,12 +241,8 @@ Word16 WB_BWE_gain_pred_fx( tmp = extract_l( L_tmp ); enerL = L_deposit_l( enerL_16 ); - enerL = L_shl( enerL, 6 ); /*Q6 */ -#ifdef BASOP_NOGLOB - tmp1 = i_mult_sat( 3, WB_fenv[0] ); /*Q3 */ -#else - tmp1 = i_mult( 3, WB_fenv[0] ); /*Q3 */ -#endif + enerL = L_shl( enerL, 6 ); /*Q6 */ + tmp1 = i_mult_sat( 3, WB_fenv[0] ); /*Q3 */ L_tmp = L_mult0( tmp1, WB_fenv[0] ); /*Q6 */ test(); @@ -303,13 +255,9 @@ Word16 WB_BWE_gain_pred_fx( enerL_64 = mult_r( 4096, enerL_16 ); /* 1/64 in Q18 ->Q3 */ exp = norm_s( WB_fenv[0] ); - tmp = div_s( shl( 1, sub( 14, exp ) ), WB_fenv[0] ); /*Q(29-exp-3) */ - L_tmp = L_mult( enerL_64, tmp ); /*Q(30-exp) */ -#ifdef BASOP_NOGLOB + tmp = div_s( shl( 1, sub( 14, exp ) ), WB_fenv[0] ); /*Q(29-exp-3) */ + L_tmp = L_mult( enerL_64, tmp ); /*Q(30-exp) */ tmp = round_fx_sat( L_shl_sat( L_tmp, sub( exp, 2 ) ) ); /*Q12 */ -#else - tmp = round_fx( L_shl( L_tmp, sub( exp, 2 ) ) ); /*Q12 */ -#endif tmp = s_min( tmp, 16384 /*4 in Q12*/ ); L_tmp = L_shr( L_mult0( tmp, WB_fenv[0] ), 12 ); /*Q3 */ WB_fenv[0] = extract_l( L_tmp ); /*Q3 */ @@ -343,12 +291,8 @@ Word16 WB_BWE_gain_pred_fx( tmp = s_min( s_max( tmp1, 16 /* 0.125 in Q7 */ ), 256 /* 1 in Q7 */ ); /*Q7 */ L_tmp = L_shr( L_mult0( WB_fenv[0], tmp ), 7 ); /*Q3 */ /*WB_fenv[0] = saturate(L_tmp); //Q3 */ -#ifdef BASOP_NOGLOB - WB_fenv[0] = round_fx_sat( L_shl_sat( L_tmp, 16 ) ); /*Q3 */ + WB_fenv[0] = round_fx_sat( L_shl_sat( L_tmp, 16 ) ); /*Q3 */ move16(); -#else - WB_fenv[0] = round_fx( L_shl( L_tmp, 16 ) ); /*Q3 */ -#endif } test(); IF( GT_32( last_core_brate, ACELP_8k00 ) && GT_16( WB_fenv[0], last_wb_bwe_ener ) ) @@ -454,11 +398,7 @@ static void calc_norm_envelop_lf_fx( tmp = add( lookback, n_freq ); FOR( n_lag = 0; n_lag < tmp; n_lag++ ) { -#ifdef BASOP_NOGLOB L_tmp = L_add_sat( L_tmp, L_abs( SWB_signal[n_lag] ) ); -#else - L_tmp = L_add( L_tmp, L_abs( SWB_signal[n_lag] ) ); -#endif } envelope[env_index] = L_tmp; move32(); @@ -471,11 +411,7 @@ static void calc_norm_envelop_lf_fx( Word32 L_tmp = L_deposit_l( 1 ); FOR( n_lag = 0; n_lag < n_lag_now; n_lag++ ) { -#ifdef BASOP_NOGLOB L_tmp = L_add_sat( L_tmp, L_abs( SWB_signal[n_freq - lookback + n_lag] ) ); -#else - L_tmp = L_add( L_tmp, L_abs( SWB_signal[n_freq - lookback + n_lag] ) ); -#endif } envelope[env_index] = L_tmp; @@ -649,30 +585,16 @@ Word32 calc_tilt_bwe_fx( /* o : Tilt in Q24 /* Divide Frame Length by 32 */ FOR( j = shr( N, 5 ); j > 0; j-- ) { -#ifdef BASOP_NOGLOB /* Critical Overflow and all those below*/ tmp1 = mult_ro( *ptr++, 8192 /*0.25 in Q15 */, &Overflow ); /* Divide by 4 */ -#else - tmp1 = mult_r( *ptr++, 8192 /*0.25 in Q15 */ ); /* Divide by 4 */ -#endif L_ener = L_mult0( tmp1, tmp1 ); /* With the shift by 4 and the L_mult0, no overflow possible for 32 samples */ FOR( i = 1; i < 32; i++ ) { -#ifdef BASOP_NOGLOB /* Critical Overflow */ tmp1 = mult_ro( *ptr++, 8192 /*0.25 in Q15 */, &Overflow ); /* Divide by 4 */ L_ener = L_mac0_o( L_ener, tmp1, tmp1, &Overflow ); -#else - tmp1 = mult_r( *ptr++, 8192 ); /* Divide by 4 */ - L_ener = L_mac0( L_ener, tmp1, tmp1 ); -#endif } -#ifdef BASOP_NOGLOB /* Critical Overflow */ L_ener = L_shr_o( L_ener, exp2, &Overflow ); L_temp = L_add_o( L_ener_tot, L_ener, &Overflow ); -#else - L_ener = L_shr( L_ener, exp2 ); - L_temp = L_add( L_ener_tot, L_ener ); -#endif IF( Overflow != 0 ) { L_ener_tot = L_shr( L_ener_tot, 1 ); @@ -682,27 +604,14 @@ Word32 calc_tilt_bwe_fx( /* o : Tilt in Q24 Overflow = 0; move16(); } -#ifdef BASOP_NOGLOB /* Critical Overflow */ L_ener_tot = L_add_o( L_ener_tot, L_ener, &Overflow ); -#else - L_ener_tot = L_add( L_ener_tot, L_ener ); -#endif } -#ifdef BASOP_NOGLOB L_ener = L_deposit_l( abs_s( sub_o( sp[1], sp[0], &Overflow ) ) ); -#else - L_ener = L_deposit_l( abs_s( sub( sp[1], sp[0] ) ) ); -#endif FOR( i = 2; i < N; i++ ) { /* Eq to (sp[i] - sp[i-1]) * (sp[i-1] - sp[i-2]) < 0 */ -#ifdef BASOP_NOGLOB tmp1 = sub_o( sp[i], sp[i - 1], &Overflow ); tmp2 = sub_o( sp[i - 1], sp[i - 2], &Overflow ); -#else - tmp1 = sub( sp[i], sp[i - 1] ); - tmp2 = sub( sp[i - 1], sp[i - 2] ); -#endif tmp2 = mult( tmp1, tmp2 ); tmp1 = abs_s( tmp1 ); /* to Get either 0 or -1 in 'tmp2' */ @@ -725,20 +634,12 @@ Word32 calc_tilt_bwe_fx( /* o : Tilt in Q24 /* *tilt_flt = (float)(r1/sqrt(r0)); */ exp2 = norm_l( L_ener ); -#ifdef BASOP_NOGLOB L_temp = Mult_32_16( L_temp, round_fx_sat( L_shl_sat( L_ener, exp2 ) ) ); -#else - L_temp = Mult_32_16( L_temp, round_fx( L_shl( L_ener, exp2 ) ) ); -#endif exp2 = sub( exp2, tmp1 ); exp2 = add( exp2, exp_sp ); /* Put in Q24 */ -#ifdef BASOP_NOGLOB L_temp = L_shr_sat( L_temp, sub( exp2, 24 ) ); -#else - L_temp = L_shr( L_temp, sub( exp2, 24 ) ); -#endif BASOP_SATURATE_WARNING_ON_EVS return L_temp; @@ -1397,20 +1298,12 @@ void SWB_BWE_decoding_fx( EnergyL = L_deposit_l( 0 ); FOR( n_freq = 224 + st_offset; n_freq < swb_bwe_trans_subband[0] + st_offset; n_freq++ ) { -#ifdef BASOP_NOGLOB fenvL = L_mac0_sat( fenvL, core_dec_freq[n_freq], core_dec_freq[n_freq] ); /*2*Q_syn */ -#else - fenvL = L_mac0( fenvL, core_dec_freq[n_freq], core_dec_freq[n_freq] ); /*2*Q_syn */ -#endif } FOR( n_freq = 16; n_freq < L_FRAME; n_freq++ ) { -#ifdef BASOP_NOGLOB EnergyL = L_mac0_sat( EnergyL, core_dec_freq[n_freq], core_dec_freq[n_freq] ); /*2*Q_syn */ -#else - EnergyL = L_mac0( EnergyL, core_dec_freq[n_freq], core_dec_freq[n_freq] ); /*2*Q_syn */ -#endif } fenvL_16 = 0; @@ -1425,17 +1318,9 @@ void SWB_BWE_decoding_fx( L_tmp = L_deposit_h( tmp ); L_tmp = Isqrt_lc( L_tmp, &exp ); -#ifdef BASOP_NOGLOB fenvL_16 = round_fx_sat( L_shl_sat( L_tmp, sub( exp, 12 ) ) ); /* Q3 */ -#else - fenvL_16 = round_fx( L_shl( L_tmp, sub( exp, 12 ) ) ); /* Q3 */ -#endif } -#ifdef BASOP_NOGLOB IF( GT_16( fenvL_16, shl_sat( SWB_fenv[0], 5 ) ) ) -#else - IF( GT_16( fenvL_16, shl( SWB_fenv[0], 5 ) ) ) -#endif { fenvL_16 = shl( SWB_fenv[0], 2 ); move16(); @@ -1453,11 +1338,7 @@ void SWB_BWE_decoding_fx( L_tmp = L_deposit_h( tmp ); L_tmp = Isqrt_lc( L_tmp, &exp ); -#ifdef BASOP_NOGLOB EnergyL_16 = round_fx_sat( L_shl_sat( L_tmp, sub( exp, 12 ) ) ); /* Q3 */ -#else - EnergyL_16 = round_fx( L_shl( L_tmp, sub( exp, 12 ) ) ); /* Q3 */ -#endif } calc_normal_length_fx( ACELP_CORE, core_dec_freq, mode, extl, &L_swb_norm, prev_L_swb_norm, Q_syn ); @@ -1509,13 +1390,8 @@ void SWB_BWE_decoding_fx( tmp = add( swb_bwe_trans_subband[n_band + 1], st_offset ); FOR( n_freq = add( swb_bwe_trans_subband[n_band], st_offset ); n_freq < tmp; n_freq++ ) { -#ifdef BASOP_NOGLOB L_tmp = L_mult_sat( SWB_signal[n_freq], SWB_signal[n_freq] ); /*Q31 */ energy = L_add_sat( energy, L_shr( L_tmp, 6 ) ); /*Q25 */ -#else - L_tmp = L_mult( SWB_signal[n_freq], SWB_signal[n_freq] ); /*Q31 */ - energy = L_add( energy, L_shr( L_tmp, 6 ) ); /*Q25 */ -#endif } IF( energy == 0 ) @@ -1581,11 +1457,7 @@ void SWB_BWE_decoding_fx( tmp = div_s( shl( 1, sub( 14, exp ) ), SWB_FENV ); /*Q(29-exp) */ L_tmp = Mult_32_16( L_energy, tmp ); /*Q(1+29-exp+1)->Q(15-exp) */ -#ifdef BASOP_NOGLOB Energy_16 = round_fx_sat( L_shl_sat( L_tmp, add( exp, 4 ) ) ); /* Q3 */ -#else - Energy_16 = round_fx( L_shl( L_tmp, add( exp, 4 ) ) ); /*Q3 */ -#endif test(); IF( NE_16( last_extl, SWB_BWE ) && NE_16( last_extl, FB_BWE ) ) @@ -1659,13 +1531,8 @@ void SWB_BWE_decoding_fx( Copy( &core_dec_freq[112], &SWB_signal[368 + st_offset], 128 ); Copy( &core_dec_freq[176], &SWB_signal[496 + st_offset], 64 ); -#ifdef BASOP_NOGLOB tmp1 = add_sat( abs_s( SWB_signal[368 + st_offset] ), abs_s( SWB_signal[369 + st_offset] ) ); /*Q_syn */ tmp2 = add_sat( abs_s( SWB_signal[365 + st_offset] ), abs_s( SWB_signal[366 + st_offset] ) ); /*Q_syn */ -#else - tmp1 = add( abs_s( SWB_signal[368 + st_offset] ), abs_s( SWB_signal[369 + st_offset] ) ); /*Q_syn */ - tmp2 = add( abs_s( SWB_signal[365 + st_offset] ), abs_s( SWB_signal[366 + st_offset] ) ); /*Q_syn */ -#endif pit1 = &SWB_signal[368 + st_offset]; move16(); @@ -1679,32 +1546,20 @@ void SWB_BWE_decoding_fx( *pit1 = mult_r( *pit1, tmp3 ); move16(); /*Q_syn */ pit1++; -#ifdef BASOP_NOGLOB tmp3 = add_sat( tmp3, 3277 /* 0.1 in Q15*/ ); /*Q15 */ -#else - tmp3 = add( tmp3, 3277 /* 0.1 in Q15*/ ); /*Q15 */ -#endif } } ELSE IF( LT_16( tmp2, tmp1 ) ) { exp = norm_s( tmp1 ); - tmp = div_s( shl( 1, sub( 14, exp ) ), tmp1 ); /*Q(29-exp) */ -#ifdef BASOP_NOGLOB + tmp = div_s( shl( 1, sub( 14, exp ) ), tmp1 ); /*Q(29-exp) */ tmp3 = round_fx_sat( L_shl_sat( L_mult( tmp2, tmp ), add( exp, 2 ) ) ); /*Q15 */ -#else - tmp3 = round_fx( L_shl( L_mult( tmp2, tmp ), add( exp, 2 ) ) ); /*Q15 */ -#endif WHILE( LT_16( tmp3, 32767 ) ) { *pit1 = mult_r( *pit1, tmp3 ); move16(); /*Q_syn */ pit1++; -#ifdef BASOP_NOGLOB tmp3 = add_sat( tmp3, 3277 /* 0.1 in Q15*/ ); /*Q15 */ -#else - tmp3 = add( tmp3, 3277 ); /*Q15 */ -#endif } } @@ -1715,23 +1570,14 @@ void SWB_BWE_decoding_fx( /*20480 = 5 in Q12 */ FOR( tmp3 = 20480; tmp3 > 4096; tmp3 -= 2048 ) { -#ifdef BASOP_NOGLOB *pit1 = round_fx_sat( L_shl_sat( L_mult( *pit1, tmp3 ), 3 ) ); /*Q_syn */ -#else - *pit1 = round_fx( L_shl( L_mult( *pit1, tmp3 ), 3 ) ); /*Q_syn */ -#endif move16(); pit1--; } } -#ifdef BASOP_NOGLOB tmp1 = add_sat( abs_s( SWB_signal[496 + st_offset] ), abs_s( SWB_signal[497 + st_offset] ) ); /*Q_syn */ tmp2 = add_sat( add_sat( abs_s( SWB_signal[492 + st_offset] ), abs_s( SWB_signal[493 + st_offset] ) ), add_sat( abs_s( SWB_signal[494 + st_offset] ), abs_s( SWB_signal[495 + st_offset] ) ) ); -#else - tmp1 = add( abs_s( SWB_signal[496 + st_offset] ), abs_s( SWB_signal[497 + st_offset] ) ); /*Q_syn */ - tmp2 = add( add( abs_s( SWB_signal[492 + st_offset] ), abs_s( SWB_signal[493 + st_offset] ) ), add( abs_s( SWB_signal[494 + st_offset] ), abs_s( SWB_signal[495 + st_offset] ) ) ); -#endif pit1 = &SWB_signal[496 + st_offset]; test(); @@ -1744,32 +1590,20 @@ void SWB_BWE_decoding_fx( *pit1 = mult_r( *pit1, tmp3 ); move16(); /*Q_syn */ pit1++; -#ifdef BASOP_NOGLOB tmp3 = add_sat( tmp3, 3277 /* 0.1 in Q15 */ ); /*Q15 */ -#else - tmp3 = add( tmp3, 3277 /* 0.1 in Q15 */ ); /*Q15 */ -#endif } } ELSE IF( LT_16( tmp2, tmp1 ) ) { exp = norm_s( tmp1 ); - tmp = div_s( shl( 1, sub( 14, exp ) ), tmp1 ); /*Q(29-exp) */ -#ifdef BASOP_NOGLOB + tmp = div_s( shl( 1, sub( 14, exp ) ), tmp1 ); /*Q(29-exp) */ tmp3 = round_fx_sat( L_shl_sat( L_mult( tmp2, tmp ), add( exp, 2 ) ) ); /*Q15 */ -#else - tmp3 = round_fx( L_shl( L_mult( tmp2, tmp ), add( exp, 2 ) ) ); /*Q15 */ -#endif WHILE( LT_16( tmp3, 32767 ) ) { *pit1 = mult_r( *pit1, tmp3 ); move16(); /*Q_syn */ pit1++; -#ifdef BASOP_NOGLOB tmp3 = add_sat( tmp3, 3277 /* 0.1 in Q15 */ ); /*Q15 */ -#else - tmp3 = add( tmp3, 3277 /* 0.1 in Q15 */ ); /*Q15 */ -#endif } } pit1 = &SWB_signal[495 + st_offset]; @@ -1967,11 +1801,7 @@ FOR( n_band = 0; n_band < SWB_FENV; n_band += L ) } } -#ifdef BASOP_NOGLOB IF( GT_16( *prev_Energy, add_sat( Energy_16, shr( Energy_16, 2 ) ) ) && Energy_16 > 0 ) -#else -IF( GT_16( *prev_Energy, add( Energy_16, shr( Energy_16, 2 ) ) ) && Energy_16 > 0 ) -#endif { weight = shr( div_s( Energy_16, *prev_Energy ), 1 ); /*Q15 */ } @@ -2005,11 +1835,7 @@ tmp2 = add( add( swb_bwe_subband[0], 8 ), st_offset ); FOR( n_freq = add( swb_bwe_subband[0], st_offset ); n_freq < tmp2; n_freq++ ) { L_tmp1 = Mult_32_16( SWB_signal_32[n_freq], factor ); -#ifdef BASOP_NOGLOB SWB_signal_32[n_freq] = L_shl_sat( L_tmp1, tmp - 1 ); -#else - SWB_signal_32[n_freq] = L_shl( L_tmp1, tmp - 1 ); -#endif move32(); /*15+Qsyn */ factor = add( factor, factor1 ); /*Q3 */ } @@ -2040,17 +1866,9 @@ FOR( n_band = 0; n_band < 12; n_band++ ) FOR( ; n_freq < tmp2; n_freq++ ) { L_tmp1 = Mult_32_16( SWB_signal_32[n_freq], factor ); -#ifdef BASOP_NOGLOB SWB_signal_32[n_freq] = L_shl_sat( L_tmp1, tmp - 1 ); -#else - SWB_signal_32[n_freq] = L_shl( L_tmp1, tmp - 1 ); -#endif - move32(); /*15+Qsyn */ -#ifdef BASOP_NOGLOB + move32(); /*15+Qsyn */ factor = add_sat( factor, factor1 ); /*Q1 */ -#else - factor = add( factor, factor1 ); /*Q1 */ -#endif } } L_tmp = L_mult( weight, prev_SWB_fenv[13] ); /*Q17 */ @@ -2063,11 +1881,7 @@ tmp2 = add( swb_bwe_sm_subband[13], st_offset ); FOR( ; n_freq < tmp2; n_freq++ ) { L_tmp1 = Mult_32_16( SWB_signal_32[n_freq], factor ); -#ifdef BASOP_NOGLOB SWB_signal_32[n_freq] = L_shl_sat( L_tmp1, 13 ); -#else - SWB_signal_32[n_freq] = L_shl( L_tmp1, 13 ); -#endif move32(); /*15+Qsyn */ factor = add( factor, factor1 ); /*Q1 */ } @@ -2081,11 +1895,7 @@ FOR( n_band = 13; n_band < SWB_FENV; n_band++ ) FOR( ; n_freq < tmp2; n_freq++ ) { L_tmp1 = Mult_32_16( SWB_signal_32[n_freq], factor ); -#ifdef BASOP_NOGLOB SWB_signal_32[n_freq] = L_shl_sat( L_tmp1, 13 ); -#else - SWB_signal_32[n_freq] = L_shl( L_tmp1, 13 ); -#endif move32(); /*15+Qsyn */ } } @@ -2148,11 +1958,7 @@ void time_envelop_shaping_fx( Energy = L_deposit_l( 0 ); FOR( j = 0; j < L / 4; j++ ) { -#ifdef BASOP_NOGLOB Energy = L_mac0_sat( Energy, *pit, *pit ); /*(2*Q_synth) */ -#else - Energy = L_mac0( Energy, *pit, *pit ); /*(2*Q_synth) */ -#endif pit++; } Energy = Mult_32_16( Energy, inv_L ); /*Q(29-exp_L-15) -> Q(-exp_L+14+2*Q_synth) */ @@ -2175,11 +1981,7 @@ void time_envelop_shaping_fx( } test(); -#ifdef BASOP_NOGLOB IF( LT_32( SWB_tenv[i], 65536 /* 2 in Q15 */ ) && LT_32( Energy, L_shl_sat( SWB_tenv[i], sub( 16, exp ) ) ) ) -#else - IF( LT_32( SWB_tenv[i], 65536 /* 2 in Q15 */ ) && LT_32( Energy, L_shl( SWB_tenv[i], sub( 16, exp ) ) ) ) -#endif { *Q_synth = add( *Q_synth, 3 ); move16(); @@ -2204,11 +2006,90 @@ void time_envelop_shaping_fx( FOR( j = 0; j < L / 4; j++ ) { -#ifdef BASOP_NOGLOB *pit = round_fx_sat( L_shl_sat( L_mult( tmp, *pit ), sub( exp, 1 ) ) ); /*Q(13-exp+1)->Q(14-exp)->Qsyn-3 */ -#else - *pit = round_fx( L_shl( L_mult( tmp, *pit ), sub( exp, 1 ) ) ); /*Q(13-exp+1)->Q(14-exp)->Qsyn-3 */ -#endif + move16(); + pit++; + } + } + } + + return; +} + +void time_envelop_shaping_ivas_fx( + Word16 werr[], /* i/o: SHB synthesis Q_synth*/ + Word32 SWB_tenv[], /* i/o: frequency envelope Q15*/ + const Word16 L, /* i : frame length */ + Word16 *Q_synth ) +{ + Word16 *pit; + Word32 Energy; + Word16 i, j; + Word16 tmp_ener, Energy_16; + Word64 Energy_64; + Word16 exp_L, exp, frac, tmp, inv_L, w_tmp, Energy_Q; + Word32 L_tmp; + + pit = werr; + exp_L = norm_s( L ); + inv_L = div_s( shl( 1, sub( 14, exp_L ) ), L ); /*Q(29-exp_L) */ + FOR( i = 0; i < SWB_TENV; i++ ) + { + Energy_64 = L_deposit_l( 0 ); + FOR( j = 0; j < L / 4; j++ ) + { + Energy_64 = W_mac0_16_16( Energy_64, *pit, *pit ); /*(2*Q_synth) */ + pit++; + } + w_tmp = W_norm( Energy_64 ); + Energy_64 = W_shl( Energy_64, w_tmp ); + Energy = W_extract_h( Energy_64 ); /*2*Q_synth + w_tmp -32*/ + Energy_Q = sub( add( shl( ( *Q_synth ), 1 ), w_tmp ), 32 ); + Energy = Mult_32_16( Energy, inv_L ); /*Q(29-exp_L-15) -> Q(-exp_L+14+2*Q_synth+w_tmp-32) */ + Energy_16 = 0; + move16(); + /*exp = 31-(-exp_L+14 +(2*(*Q_synth)+w_tmp-32)); */ + exp = sub( 17, sub( Energy_Q, exp_L ) ); + + IF( Energy != 0 ) + { + exp = norm_l( Energy ); + frac = extract_h( L_shl( Energy, exp ) ); + /*exp = sub(exp, 30-(-exp_L+14-2+(2*(*Q_synth)+w_tmp-32))); */ + exp = sub( exp, sub( 30, add( sub( Energy_Q, exp_L ), 14 - 2 ) ) ); + + tmp = div_s( 16384, frac ); + L_tmp = L_deposit_h( tmp ); + Energy = Isqrt_lc( L_tmp, &exp ); /*Q(31-exp) */ + Energy_16 = round_fx( L_shl( Energy, sub( exp, 15 ) ) ); /*Q0 */ + } + + test(); + IF( LT_32( SWB_tenv[i], 65536 /* 2 in Q15 */ ) && LT_32( Energy, L_shl_sat( SWB_tenv[i], sub( 16, exp ) ) ) ) + { + *Q_synth = add( *Q_synth, 3 ); + move16(); + } + ELSE + { + pit -= shr( L, 2 ); + tmp_ener = 0; + move16(); + exp = 0; + move16(); + + IF( Energy_16 != 0 ) + { + exp = norm_s( Energy_16 ); + tmp_ener = div_s( shl( 1, sub( 14, exp ) ), Energy_16 ); /*Q(29-exp) */ + } + + L_tmp = Mult_32_16( SWB_tenv[i], tmp_ener ); /*Q(29-exp) */ + tmp = round_fx( L_tmp ); /*Q(13-exp) */ + + FOR( j = 0; j < L / 4; j++ ) + { + *pit = round_fx_sat( L_shl_sat( L_mult( tmp, *pit ), sub( exp, 1 ) ) ); /*Q(13-exp+1)->Q(14-exp)->Qsyn-3 */ move16(); pit++; } @@ -2265,11 +2146,7 @@ void time_reduce_pre_echo_fx( L_tmp = L_deposit_l( 0 ); FOR( j = 0; j < L; j++ ) { -#ifdef BASOP_NOGLOB L_tmp = L_mac0_sat( L_tmp, synth[Len + j], synth[Len + j] ); /*2*Q_syn */ -#else - L_tmp = L_mac0( L_tmp, synth[Len + j], synth[Len + j] ); /*2*Q_syn */ -#endif } energyL[i] = Mult_32_16( L_shr( L_tmp, sub( 14, exp_L ) ), inv_L ); move32(); /*Q(2*Q_syn +29-exp_L-15 - (14-exp_L) ) -> Q(2*Q_syn) */ @@ -2309,11 +2186,7 @@ void time_reduce_pre_echo_fx( j = i_mult( L, pos ); FOR( i = 0; i < j; i++ ) { -#ifdef BASOP_NOGLOB energy = L_mac0_sat( energy, error[i], error[i] ); /*Q(2*Q_synth) */ -#else - energy = L_mac0( energy, error[i], error[i] ); /*Q(2*Q_synth) */ -#endif } exp_j = norm_s( j ); @@ -2354,22 +2227,14 @@ void time_reduce_pre_echo_fx( tmp_exp = add( 1, exp ); FOR( i = 0; i < j; i++ ) { -#ifdef BASOP_NOGLOB error[i] = round_fx_sat( L_shl_sat( Mult_32_16( L_tmp, error[i] ), tmp_exp ) ); /*Q(30-exp+1-16)->Q(15-exp)->Q_synth */ -#else - error[i] = round_fx( L_shl( Mult_32_16( L_tmp, error[i] ), tmp_exp ) ); /*Q(30-exp+1-16)->Q(15-exp)->Q_synth */ -#endif move16(); } energy = L_deposit_l( 0 ); FOR( i = j; i < ( j + L ); i++ ) { -#ifdef BASOP_NOGLOB energy = L_mac0_sat( energy, error[i], error[i] ); /*(2*Q_synth) */ -#else - energy = L_mac0( energy, error[i], error[i] ); /*(2*Q_synth) */ -#endif } energy = Mult_32_16( energy, inv_L ); /*Q(29-exp_L+1-16) -> Q(-exp_L+14) */ @@ -2404,15 +2269,11 @@ void time_reduce_pre_echo_fx( move16(); FOR( i = 0; i < L; i++ ) { - tmpi = round_fx( L_shl( L_mult( i, inv_L ), add( 1, exp_L ) ) ); /*Q15 */ - L_tmp = L_sub( L_tmp1, Ltmp_ener ); /*Q(30-exp) */ - L_tmp = Mult_32_16( L_tmp, tmpi ); /*Q(30-exp) */ - L_tmp = L_add( Ltmp_ener, L_tmp ); /*Q(30-exp) */ -#ifdef BASOP_NOGLOB + tmpi = round_fx( L_shl( L_mult( i, inv_L ), add( 1, exp_L ) ) ); /*Q15 */ + L_tmp = L_sub( L_tmp1, Ltmp_ener ); /*Q(30-exp) */ + L_tmp = Mult_32_16( L_tmp, tmpi ); /*Q(30-exp) */ + L_tmp = L_add( Ltmp_ener, L_tmp ); /*Q(30-exp) */ tmp = round_fx_sat( L_shl_sat( Mult_32_16( L_tmp, *pit ), add( 1, exp ) ) ); /*Q0 */ -#else - tmp = round_fx( L_shl( Mult_32_16( L_tmp, *pit ), add( 1, exp ) ) ); /*Q0 */ -#endif *pit++ = tmp; move16(); } @@ -2481,11 +2342,7 @@ void calc_normal_length_fx_32( peak = mag; move16(); } -#ifdef BASOP_NOGLOB mean = L_add_sat( mean, mag ); -#else - mean = L_add( mean, mag ); -#endif pit++; } @@ -2575,11 +2432,7 @@ void calc_norm_envelop_fx_32( move16(); FOR( n_lag = 0; n_lag < n_lag_now; n_lag++ ) { -#ifdef BASOP_NOGLOB envelope_fx[env_index] = L_add_sat( envelope_fx[env_index], L_abs( SWB_signal_fx[n_freq + n_lag] ) ); -#else - envelope_fx[env_index] = L_add( envelope_fx[env_index], L_abs( SWB_signal_fx[n_freq + n_lag] ) ); -#endif move32(); } env_index = add( env_index, 1 ); @@ -2687,12 +2540,8 @@ void hq_generic_decoding_fx( #endif tmp = div_s( 16384, frac ); /*15 + 14 - (cs+exp-16) */ exp = sub( add( cs, exp ), 30 ); - L_tmp = Isqrt_lc( L_deposit_h( tmp ), &exp ); /*Q31 - exp */ -#ifdef BASOP_NOGLOB + L_tmp = Isqrt_lc( L_deposit_h( tmp ), &exp ); /*Q31 - exp */ fenvL_fx = round_fx_sat( L_shl_sat( L_tmp, sub( exp, 14 ) ) ); /*Q1 */ -#else - fenvL_fx = round_fx( L_shl( L_tmp, sub( exp, 14 ) ) ); /*Q1 */ -#endif } calc_normal_length_fx_32( HQ_CORE, coeff_out1_fx, HQ_GEN_SWB, -1, &L_swb_norm, prev_L_swb_norm ); @@ -2993,12 +2842,564 @@ void hq_generic_decoding_fx( exp2 = sub( norm_l( L_tmp2 ), 1 ); tmp1_fx = extract_h( L_shl( L_tmp1, exp1 ) ); tmp2_fx = extract_h( L_shl( L_tmp2, exp2 ) ); - tmp3_fx = div_s( tmp2_fx, tmp1_fx ); /*15 + exp2 + 15 - (exp1 + 15) */ -#ifdef BASOP_NOGLOB + tmp3_fx = div_s( tmp2_fx, tmp1_fx ); /*15 + exp2 + 15 - (exp1 + 15) */ tmp3_fx = shr_sat( tmp3_fx, add( 5, sub( exp2, exp1 ) ) ); /*10 */ + if ( LT_16( tmp3_fx, 307 /* 0.3 in Q10*/ ) ) + { + tmp3_fx = 307; /* 0.3 in Q10*/ + move16(); + } + FOR( ; tmp3_fx < 1024; tmp3_fx += 102 ) + { + L_tmp = L_shl( Mult_32_16( *pit1_fx, tmp3_fx ), 5 ); /*15 + 5 + 10 -15 */ + *pit1_fx++ = L_tmp; + move32(); + } + + pit1_fx = &coeff_out_fx[HQ_GENERIC_HIGH2 - 1 + hq_generic_offset]; + + exp1 = sub( norm_l( L_tmp1 ), 1 ); + exp2 = norm_l( L_tmp2 ); + tmp1_fx = extract_h( L_shl( L_tmp1, exp1 ) ); + tmp2_fx = extract_h( L_shl( L_tmp2, exp2 ) ); + tmp3_fx = div_s( tmp1_fx, tmp2_fx ); /*15 + exp2 + 15 - (exp1 + 15) */ + tmp3_fx = shr( tmp3_fx, add( 5, sub( exp1, exp2 ) ) ); /*10 */ + tmp3_fx = shr( tmp3_fx, 1 ); + tmp4_fx = mult_r( tmp3_fx, 1638 /* 0.05 in Q15 */ ); + WHILE( tmp3_fx > 1024 /* 1 in Q10*/ ) + { +#ifdef EVS_FUNC_MODIFIED + L_tmp1 = L_shl( Mult_32_16( *pit1_fx, tmp3_fx ), 5 ); /*15 + 5 + 10 -15 */ #else - tmp3_fx = shr( tmp3_fx, add( 5, sub( exp2, exp1 ) ) ); /*10 */ + L_tmp1 = Mult_32_16( L_shl( *pit1_fx, 5 ), tmp3_fx ); /*15 + 5 + 10 -15 */ #endif + *pit1_fx-- = L_tmp1; + move32(); + tmp3_fx = sub( tmp3_fx, tmp4_fx ); + } + } + + + wfenv_fx = hq_generic_fenv_fx[0]; + move16(); /*1 */ + i = 0; + move16(); + tmp2 = add( add( swb_bwe_subband[0], hq_generic_offset ), 8 ); + FOR( n_freq = add( swb_bwe_subband[0], hq_generic_offset ); n_freq < tmp2; n_freq++ ) + { + factor_fx = shl( i, 12 ); /*15 */ + L_tmp1 = L_mult( sub( 32767, factor_fx ), fenvL_fx ); /*17 */ + L_tmp2 = L_mult( factor_fx, wfenv_fx ); /*17 */ + L_tmp1 = L_add( L_tmp1, L_tmp2 ); /*17 */ + + cs = norm_l( L_tmp1 ); + tmp = extract_h( L_shl( L_tmp1, cs ) ); /*17 + cs - 16 */ + L_tmp = Mult_32_16( coeff_out_fx[n_freq], tmp ); /*12 + 15 + 17 + cs - 16 - 15 */ + coeff_out_fx[n_freq] = L_shr( L_tmp, add( 1, cs ) ); + move32(); /*12 */ + i++; + move16(); + } + + k = sub( nenv, 2 ); + FOR( n_band = 0; n_band < k; n_band++ ) + { + wfenv_fx = hq_generic_fenv_fx[n_band + 1]; + move16(); /*1 */ + + tmp2 = swb_bwe_sm_subband[n_band + 1] + hq_generic_offset; + FOR( i = 0; n_freq < tmp2; i++ ) + { + L_tmp1 = L_mult( sub( wfenv_fx, hq_generic_fenv_fx[n_band] ), smooth_factor_fx[n_band] ); /*17 */ + L_tmp1 = Mult_32_16( L_tmp1, shl( i, 10 ) ); /*17 + 10 - 15 */ + L_tmp1 = L_add( L_tmp1, L_shl( hq_generic_fenv_fx[n_band], 11 ) ); /*12 */ + + cs = norm_l( L_tmp1 ); + tmp = extract_h( L_shl( L_tmp1, cs ) ); /*12 + cs - 16 */ + L_tmp = Mult_32_16( coeff_out_fx[n_freq], tmp ); /*12 + 15 + 12 + cs - 16 - 15 */ + coeff_out_fx[n_freq] = L_shl( L_tmp, sub( 4, cs ) ); + move32(); /*12 */ + n_freq++; + } + } + + wfenv_fx = hq_generic_fenv_fx[nenv - 1]; + move16(); /*1 */ + tmp2 = add( swb_bwe_sm_subband[nenv - 1], hq_generic_offset ); + FOR( i = 0; n_freq < tmp2; i++ ) + { + L_tmp1 = L_mult( sub( wfenv_fx, hq_generic_fenv_fx[nenv - 2] ), smooth_factor_fx[nenv - 2] ); /*17 */ + L_tmp1 = Mult_32_16( L_tmp1, shl( i, 10 ) ); /*17 + 10 - 15 */ + L_tmp1 = L_add( L_tmp1, L_shl( hq_generic_fenv_fx[nenv - 2], 11 ) ); /*12 */ + + cs = norm_l( L_tmp1 ); + tmp = extract_h( L_shl( L_tmp1, cs ) ); /*12 + cs - 16 */ + L_tmp = Mult_32_16( coeff_out_fx[n_freq], tmp ); /*12 + 15 + 12 + cs - 16 - 15 */ + coeff_out_fx[n_freq] = L_shl( L_tmp, sub( 4, cs ) ); + move32(); /*12 */ + n_freq++; + } + + IF( EQ_16( HQ_mode, HQ_GEN_SWB ) ) + { + FOR( n_band = sub( nenv, 1 ); n_band < nenv; ++n_band ) + { + wfenv_fx = hq_generic_fenv_fx[n_band]; + move16(); /*1 */ + tmp2 = add( swb_bwe_subband[n_band + 1], hq_generic_offset ); + FOR( ; n_freq < tmp2; n_freq++ ) + { + L_tmp = Mult_32_16( coeff_out_fx[n_freq], wfenv_fx ); /*15 + 12 + 1 - 15 */ + coeff_out_fx[n_freq] = L_shr( L_tmp, 1 ); + move32(); /*12 */ + } + } + } + ELSE + { + test(); + IF( GT_16( sub( hq_generic_fenv_fx[nenv - 1], hq_generic_fenv_fx[nenv] ), 30 ) || LT_16( hq_generic_fenv_fx[nenv], 10 ) ) + { + wfenv_fx = hq_generic_fenv_fx[nenv - 1]; + move16(); /*1 */ + FOR( i = 0; n_freq < fb_bwe_subband[0]; i++ ) + { + L_tmp = Mult_32_16( coeff_out_fx[n_freq], wfenv_fx ); /*15 + 12 + 1 - 15 */ + coeff_out_fx[n_freq] = L_shr( L_tmp, 1 ); + move32(); /*12 */ + n_freq++; + } + + FOR( n_band = 0; n_band < DIM_FB; n_band++ ) + { + wfenv_fx = hq_generic_fenv_fx[n_band + nenv]; + move16(); /*1 */ + tmp2 = fb_bwe_subband[n_band + 1]; + FOR( i = 0; n_freq < tmp2; i++ ) + { + L_tmp = Mult_32_16( coeff_out_fx[n_freq], wfenv_fx ); /*15 + 12 + 1 - 15 */ + coeff_out_fx[n_freq] = L_shr( L_tmp, 1 ); + move32(); /*12 */ + n_freq++; + } + } + } + ELSE + { + FOR( n_band = 0; n_band < DIM_FB; n_band++ ) + { + wfenv_fx = hq_generic_fenv_fx[n_band + nenv - 1]; + move16(); /*1 */ + + FOR( i = 0; n_freq < fb_bwe_sm_subband[n_band]; i++ ) + { + L_tmp1 = L_mult( sub( wfenv_fx, hq_generic_fenv_fx[n_band + nenv] ), fb_smooth_factor_fx[n_band] ); /*17 */ + L_tmp1 = Mult_32_16( L_tmp1, shl( i, 9 ) ); /*17 + 9 - 15 */ + L_tmp1 = L_add( L_tmp1, L_shl( hq_generic_fenv_fx[n_band + nenv], 10 ) ); /*11 */ + + cs = norm_l( L_tmp1 ); + tmp = extract_h( L_shl( L_tmp1, cs ) ); /*11 + cs - 16 */ + L_tmp = Mult_32_16( coeff_out_fx[n_freq], tmp ); /*12 + 15 + 11 + cs - 16 - 15 */ + coeff_out_fx[n_freq] = L_shl( L_tmp, sub( 5, cs ) ); + move32(); /*12 */ + n_freq = add( n_freq, 1 ); + } + } + + wfenv_fx = hq_generic_fenv_fx[tenv - 1]; + move16(); /*1 */ + + FOR( ; n_freq < fb_bwe_subband[DIM_FB]; n_freq++ ) + { + L_tmp = Mult_32_16( coeff_out_fx[n_freq], wfenv_fx ); /*15 + 12 + 1 - 15 */ + coeff_out_fx[n_freq] = L_shr( L_tmp, 1 ); + move32(); /*12 */ + } + } + } + + return; +} + +void hq_generic_decoding_ivas_fx( + const Word16 HQ_mode, /* i : HQ mode : Q0 */ + Word32 *coeff_out1_fx, /* i/o: BWE input & temporary buffer : Q12 */ + const Word16 *hq_generic_fenv_fx, /* i : SWB frequency envelopes : Q1 */ + Word32 *coeff_out_fx, /* o : SWB signal in MDCT domain : Q12 */ + const Word16 hq_generic_offset, /* i : frequency offset for representing hq generci : Q0 */ + Word16 *prev_L_swb_norm, /* i/o: last normalize length : Q0 */ + const Word16 hq_generic_exc_clas, /* i : bwe excitation class " Q0 */ + const Word16 *R ) +{ + Word16 i, n_freq, n_band, L_swb_norm; + Word16 k; + Word16 nenv; + Word16 tenv; + + Word16 exp, exp1, exp2, frac, tmp, tmp2, cs; + Word32 L_tmp, L_tmp1, L_tmp2, max_coeff_fx; + Word16 fenvL_fx, wfenv_fx, factor_fx; + Word32 *pit1_fx; + Word16 tmp1_fx, tmp2_fx, tmp3_fx, tmp4_fx; + Word32 energy_fx; + + Word32 envelope_fx[L_FRAME16k]; + Word32 mean_vector_fx[20]; + Word16 rn_weight0_fx; + Word16 s; + Word16 blen, nband_lf, sfidx, efidx; + Word16 bwe_seed; + Word16 signum[L_FRAME16k]; + + nenv = sub( SWB_FENV, 2 ); + if ( LE_16( hq_generic_offset, HQ_GENERIC_FOFFSET_24K4 ) ) + { + nenv = SWB_FENV; + move16(); + } + + tenv = nenv; + move16(); + if ( EQ_16( HQ_mode, HQ_GEN_FB ) ) + { + tenv = add( nenv, DIM_FB ); + } + + max_coeff_fx = 0; + move16(); + tmp = add( swb_bwe_subband[0], hq_generic_offset ); + FOR( n_freq = add( HQ_GENERIC_ST_FREQ, hq_generic_offset ); n_freq < tmp; n_freq++ ) + { + max_coeff_fx = L_max( max_coeff_fx, L_abs( coeff_out1_fx[n_freq] ) ); + } + cs = norm_l( max_coeff_fx ); + + L_tmp = 0; + move16(); + tmp2 = add( swb_bwe_subband[0], hq_generic_offset ); + FOR( n_freq = add( HQ_GENERIC_ST_FREQ, hq_generic_offset ); n_freq < tmp2; n_freq++ ) + { + tmp = extract_h( L_shl( coeff_out1_fx[n_freq], cs ) ); /*12 + cs - 16 */ + L_tmp1 = L_mult0( tmp, tmp ); /*2*(cs-2) */ + L_tmp = L_add( L_tmp, L_shr( L_tmp1, 5 ) ); /*2*(cs-2) - 5 */ + } + cs = sub( shl( cs, 1 ), 9 ); + fenvL_fx = 0; + move16(); + IF( L_tmp != 0 ) + { + exp = norm_l( L_tmp ); +#ifdef EVS_FUNC_MODIFIED + frac = round_fx_sat( L_shl( L_tmp, exp ) ); /*cs+exp-16 */ +#else + frac = round_fx( L_shl( L_tmp, exp ) ); /*cs+exp-16 */ +#endif + tmp = div_s( 16384, frac ); /*15 + 14 - (cs+exp-16) */ + exp = sub( add( cs, exp ), 30 ); + L_tmp = Isqrt_lc( L_deposit_h( tmp ), &exp ); /*Q31 - exp */ + fenvL_fx = round_fx_sat( L_shl_sat( L_tmp, sub( exp, 14 ) ) ); /*Q1 */ + } + + calc_normal_length_fx_32( HQ_CORE, coeff_out1_fx, HQ_GEN_SWB, -1, &L_swb_norm, prev_L_swb_norm ); + + calc_norm_envelop_lf_fx( coeff_out1_fx, envelope_fx, &L_swb_norm, HQ_mode, hq_generic_offset, &sfidx, &efidx ); + + blen = 16; + move16(); + + IF( EQ_16( hq_generic_exc_clas, HQ_GENERIC_EXC0 ) ) + { + rn_weight0_fx = 819; + move16(); /* 0.8 Q10 */ + } + ELSE IF( EQ_16( hq_generic_exc_clas, HQ_GENERIC_EXC1 ) ) + { + rn_weight0_fx = 51; + move16(); /* 0.05 Q10*/ + } + ELSE + { + rn_weight0_fx = 205; + move16(); /* 0.02 Q10 */ + } + + tmp = sub( efidx, sfidx ); + IF( tmp == 0 ) + { + nband_lf = 0; + move16(); + } + ELSE + { + exp = norm_s( tmp ); + nband_lf = shl( tmp, sub( exp, 1 ) ); + exp1 = norm_s( blen ); + tmp = shl( blen, exp1 ); + nband_lf = shr( div_s( nband_lf, tmp ), add( sub( 14, exp1 ), exp ) ); /* 15 + exp-1 - exp1, Q0*/ + } + + FOR( n_freq = sfidx; n_freq < efidx; n_freq++ ) + { + IF( coeff_out1_fx[n_freq] < 0 ) + { + signum[n_freq] = -1; + move16(); + coeff_out1_fx[n_freq] = L_negate( coeff_out1_fx[n_freq] ); + move32(); + } + ELSE + { + signum[n_freq] = 1; + move16(); + } + } + + /* applying whitening */ + FOR( n_freq = sfidx; n_freq < efidx; n_freq++ ) + { + exp = norm_l( coeff_out1_fx[n_freq] ) - 1; + exp1 = norm_l( envelope_fx[n_freq] ); + + L_tmp = L_shl( coeff_out1_fx[n_freq], exp ); + L_tmp1 = L_shl( envelope_fx[n_freq], exp1 ); + + logic16(); + coeff_out1_fx[n_freq] = Div_32( L_tmp, extract_h( L_tmp1 ), extract_l( L_shr( L_tmp1, 1 ) ) & 0x00007fff ); + move32(); /*31 + exp1 - exp2*/ + + exp = add( 31, sub( exp, exp1 ) ); + coeff_out1_fx[n_freq] = L_shl( coeff_out1_fx[n_freq], sub( 20, exp ) ); + move32(); /*Q12->Q20*/ + } + + /* mean vector generation for controlling dynamic range */ + FOR( k = 0; k < nband_lf; ++k ) + { + energy_fx = 1; + move16(); + + tmp = add( i_mult2( add( k, 1 ), blen ), sfidx ); + FOR( i = add( i_mult2( k, blen ), sfidx ); i < tmp; ++i ) + { + energy_fx = L_add( energy_fx, coeff_out1_fx[i] ); + } + exp = sub( norm_l( energy_fx ), 1 ); + L_tmp = L_shl( energy_fx, exp ); + exp1 = norm_l( L_and( blen, 0x00007fff ) ); + L_tmp1 = L_shl( blen, exp1 ); + logic16(); + mean_vector_fx[k] = Div_32( L_tmp, extract_h( L_tmp1 ), extract_l( L_shr( L_tmp1, 1 ) ) & 0x00007fff ); + move32(); /*31 + 20 + exp1 - exp2*/ + exp = add( 51, sub( exp, exp1 ) ); + mean_vector_fx[k] = L_shl( mean_vector_fx[k], sub( 20, exp ) ); + move32(); /*Q12->Q20*/ + } + + /* dynamics control */ + FOR( k = 0; k < nband_lf; ++k ) + { + tmp = add( i_mult2( add( k, 1 ), blen ), sfidx ); + FOR( i = add( i_mult2( k, blen ), sfidx ); i < tmp; ++i ) + { + L_tmp = L_sub( coeff_out1_fx[i], mean_vector_fx[k] ); + exp = norm_l( L_tmp ); + L_tmp = L_shl( L_tmp, exp ); /* exp+12*/ + exp1 = norm_l( rn_weight0_fx ); + L_tmp1 = L_shl( rn_weight0_fx, exp1 ); /* exp1+10*/ + L_tmp = L_mult( extract_h( L_tmp ), extract_h( L_tmp1 ) ); + L_tmp = L_shr( L_tmp, add( exp, sub( exp1, 21 ) ) ); /* Q20*/ + coeff_out1_fx[i] = L_sub( coeff_out1_fx[i], L_tmp ); + move32(); + } + } + + IF( EQ_16( hq_generic_exc_clas, HQ_GENERIC_EXC0 ) ) + { + bwe_seed = add( add( shl( R[0], 3 ), shl( R[1], 2 ) ), add( shl( R[2], 1 ), R[3] ) ); + + FOR( n_freq = sfidx; n_freq < efidx; n_freq++ ) + { + IF( signum[n_freq] < 0 ) + { + coeff_out1_fx[n_freq] = L_negate( coeff_out1_fx[n_freq] ); + move32(); + } + + IF( Random( &bwe_seed ) < 0 ) + { + coeff_out1_fx[n_freq] = L_negate( coeff_out1_fx[n_freq] ); + move32(); + } + } + } + ELSE + { + FOR( n_freq = sfidx; n_freq < efidx; n_freq++ ) + { + IF( signum[n_freq] < 0 ) + { + coeff_out1_fx[n_freq] = L_negate( coeff_out1_fx[n_freq] ); + move32(); + } + } + } + + /* normalizing modified low frequency spectrum */ + FOR( k = 0; k < nband_lf; ++k ) + { + energy_fx = 1; + move16(); + tmp = add( i_mult2( add( k, 1 ), blen ), sfidx ); + FOR( i = add( ( i_mult2( k, blen ) ), sfidx ); i < tmp; ++i ) + { + exp = norm_l( coeff_out1_fx[i] ); + L_tmp1 = L_shl( coeff_out1_fx[i], exp ); /* exp + 12*/ + + L_tmp = Mult_32_32( L_tmp1, L_tmp1 ); + L_tmp = L_shr( L_tmp, sub( i_mult2( 2, exp ), 11 ) ); /*Q20 */ + energy_fx = L_add( energy_fx, L_tmp ); + } + + exp = norm_l( energy_fx ); + L_tmp = L_shl( energy_fx, sub( exp, 1 ) ); + exp1 = norm_s( blen ); + L_tmp1 = L_shl( (Word32) blen, add( exp1, 16 ) ); + + L_tmp = Div_32( L_tmp, extract_h( L_tmp1 ), extract_l( L_shr( L_tmp1, 1 ) ) & 0x00007fff ); + exp = sub( add( 34, exp ), exp1 ); + L_tmp = L_shr( L_tmp, sub( exp, 31 ) ); + exp = 31; + move16(); + + exp = sub( 31, exp ); + IF( exp & 0x1 ) + { + L_tmp = L_shr( L_tmp, 1 ); + exp = add( exp, 1 ); + } + L_tmp = Sqrt_l( L_tmp, &exp1 ); + exp = add( 31, sub( shr( exp1, 1 ), shr( exp, 1 ) ) ); + energy_fx = L_shl( L_tmp, sub( 31, exp ) ); /*Q31*/ + + tmp = add( i_mult2( add( k, 1 ), blen ), sfidx ); + FOR( i = add( ( i_mult2( k, blen ) ), sfidx ); i < tmp; ++i ) + { + IF( NE_32( L_abs( coeff_out1_fx[i] ), coeff_out1_fx[i] ) ) + { + s = -1; + move16(); + coeff_out1_fx[i] = L_abs( coeff_out1_fx[i] ); + move32(); + } + ELSE + { + s = 0; + move16(); + } + exp = norm_l( coeff_out1_fx[i] ); + L_tmp = L_shl( coeff_out1_fx[i], sub( exp, 1 ) ); + exp1 = norm_l( energy_fx ); + L_tmp1 = L_shl( (Word32) energy_fx, exp1 ); + logic16(); + L_tmp = Div_32( L_tmp, extract_h( L_tmp1 ), extract_l( L_shr( L_tmp1, 1 ) ) & 0x00007fff ); + exp = add( sub( 19, exp1 ), exp ); + coeff_out1_fx[i] = L_shl( L_tmp, add( sub( 12, exp ), 15 ) ); + move32(); /* Q12 -> Q27 */ + IF( s ) + { + coeff_out1_fx[i] = L_negate( coeff_out1_fx[i] ); + move32(); + } + } + } + + Copy32( &coeff_out1_fx[HQ_GENERIC_OFFSET], &coeff_out_fx[HQ_GENERIC_HIGH0 + hq_generic_offset], HQ_GENERIC_LEN0 ); + Copy32( &coeff_out1_fx[HQ_GENERIC_OFFSET], &coeff_out_fx[HQ_GENERIC_HIGH1 + hq_generic_offset], HQ_GENERIC_LEN0 ); + + IF( LE_16( hq_generic_offset, HQ_GENERIC_FOFFSET_24K4 ) ) + { + Copy32( &coeff_out1_fx[HQ_GENERIC_LOW0], &coeff_out_fx[HQ_GENERIC_HIGH2 + hq_generic_offset], HQ_GENERIC_END_FREQ - HQ_GENERIC_HIGH2 ); + } + + IF( EQ_16( HQ_mode, HQ_GEN_FB ) ) + { + IF( LE_16( hq_generic_offset, HQ_GENERIC_FOFFSET_24K4 ) ) + { + Copy32( &coeff_out1_fx[HQ_GENERIC_LOW0 + HQ_GENERIC_END_FREQ - HQ_GENERIC_HIGH2], &coeff_out_fx[fb_bwe_subband[0]], 160 ); + } + ELSE + { + Copy32( &coeff_out1_fx[HQ_GENERIC_OFFSET + HQ_GENERIC_LEN0], &coeff_out_fx[fb_bwe_subband[0]], 160 ); + } + } + + + L_tmp1 = L_deposit_l( 0 ); + L_tmp2 = L_deposit_l( 0 ); + FOR( i = 0; i < 5; ++i ) + { + L_tmp1 = L_add( L_tmp1, L_shr( L_abs( coeff_out_fx[HQ_GENERIC_HIGH1 + hq_generic_offset + i] ), 3 ) ); // adding guard bits + L_tmp2 = L_add( L_tmp2, L_shr( L_abs( coeff_out_fx[HQ_GENERIC_HIGH1 - 2 + hq_generic_offset - i] ), 3 ) ); // adding guard bits + } + + pit1_fx = &coeff_out_fx[HQ_GENERIC_HIGH1 + hq_generic_offset]; + L_tmp1 = L_max( L_tmp1, 1 ); + L_tmp2 = L_max( L_tmp2, 1 ); + exp1 = norm_l( L_tmp1 ); + exp2 = sub( norm_l( L_tmp2 ), 1 ); + tmp1_fx = extract_h( L_shl( L_tmp1, exp1 ) ); + tmp2_fx = extract_h( L_shl( L_tmp2, exp2 ) ); + tmp3_fx = div_s( tmp2_fx, tmp1_fx ); /*15 + exp2 + 15 - (exp1 + 15) */ + tmp3_fx = shr( tmp3_fx, add( 5, sub( exp2, exp1 ) ) ); /*10 */ + + if ( LT_16( tmp3_fx, 307 /*0.3 in Q10 */ ) ) + { + tmp3_fx = 307 /*0.3 in Q10 */; + move16(); + } + FOR( ; tmp3_fx < 1024; tmp3_fx += 102 ) + { + *pit1_fx = Mult_32_16( *pit1_fx, shl( tmp3_fx, 5 ) ); + move32(); /*15 + 5 + 10 -15 */ + pit1_fx++; + } + + pit1_fx = &coeff_out_fx[HQ_GENERIC_HIGH1 - 1 + hq_generic_offset]; + + exp1 = sub( norm_l( L_tmp1 ), 1 ); + exp2 = norm_l( L_tmp2 ); + tmp1_fx = extract_h( L_shl( L_tmp1, exp1 ) ); + tmp2_fx = extract_h( L_shl( L_tmp2, exp2 ) ); + tmp3_fx = div_s( tmp1_fx, tmp2_fx ); /*15 + exp2 + 15 - (exp1 + 15) */ + tmp3_fx = shr( tmp3_fx, add( 5, sub( exp1, exp2 ) ) ); /*10 */ + + IF( GT_16( tmp3_fx, 5120 ) ) + { + FOR( tmp3_fx = 5120; tmp3_fx > 1024; tmp3_fx -= 512 ) + { + /* Adding saturation suggested as fix for issue #957 */ + L_tmp1 = L_shl_sat( Mult_32_16( *pit1_fx, tmp3_fx ), 5 ); /*15 + 5 + 10 -15 */ + *pit1_fx-- = L_tmp1; + move32(); + } + } + + IF( LE_16( hq_generic_offset, HQ_GENERIC_FOFFSET_24K4 ) ) + { + L_tmp1 = L_add( L_abs( coeff_out_fx[HQ_GENERIC_HIGH2 + hq_generic_offset] ), L_abs( coeff_out_fx[HQ_GENERIC_HIGH2 + 1 + hq_generic_offset] ) ); + L_tmp2 = L_add( L_abs( coeff_out_fx[HQ_GENERIC_HIGH2 - 4 + hq_generic_offset] ), L_add( L_abs( coeff_out_fx[HQ_GENERIC_HIGH2 - 3 + hq_generic_offset] ), + L_add( L_abs( coeff_out_fx[HQ_GENERIC_HIGH2 - 2 + hq_generic_offset] ), L_abs( coeff_out_fx[HQ_GENERIC_HIGH2 - 1 + hq_generic_offset] ) ) ) ); + + pit1_fx = &coeff_out_fx[HQ_GENERIC_HIGH2 + hq_generic_offset]; + + L_tmp1 = L_max( L_tmp1, 1 ); + L_tmp2 = L_max( L_tmp2, 1 ); + exp1 = norm_l( L_tmp1 ); + exp2 = sub( norm_l( L_tmp2 ), 1 ); + tmp1_fx = extract_h( L_shl( L_tmp1, exp1 ) ); + tmp2_fx = extract_h( L_shl( L_tmp2, exp2 ) ); + tmp3_fx = div_s( tmp2_fx, tmp1_fx ); /*15 + exp2 + 15 - (exp1 + 15) */ + tmp3_fx = shr_sat( tmp3_fx, add( 5, sub( exp2, exp1 ) ) ); /*10 */ if ( LT_16( tmp3_fx, 307 /* 0.3 in Q10*/ ) ) { tmp3_fx = 307; /* 0.3 in Q10*/ diff --git a/lib_com/swb_bwe_com_lr_fx.c b/lib_com/swb_bwe_com_lr_fx.c index 0535cb1c8398bf0ba28e93651dae605b447cbe7e..d0b8d010022f45d3a388d47b8e799c5d288b7983 100644 --- a/lib_com/swb_bwe_com_lr_fx.c +++ b/lib_com/swb_bwe_com_lr_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other @@ -208,7 +208,7 @@ Word16 har_est_fx( Word16 blk_end_LEN; Word16 *p_blk_peak_pos, *pm1_blk_peak_pos; - Word16 *p_diff_peak_pos, *pm1_diff_peak_pos; + Word16 *pm1_diff_peak_pos; Word16 blk_peak_max_idx, blk_peak_pos_max_diff, diff_peak_pos_te[30]; Word16 thr1, thr2; @@ -387,8 +387,6 @@ Word16 har_est_fx( blk_peak_max_idx = 0; move16(); - - p_diff_peak_pos = &diff_peak_pos[1]; pm1_diff_peak_pos = &diff_peak_pos[1 - 1]; FOR( i = 1; i < j; i++ ) { @@ -410,7 +408,6 @@ Word16 har_est_fx( temp = add( temp, 1 ); - p_diff_peak_pos++; pm1_diff_peak_pos++; } blk_peak_pos_max_diff = diff_peak_pos[blk_peak_max_idx]; @@ -989,11 +986,7 @@ void SpectrumSmoothing_fx( IF( GT_32( L_max_val[i], 0x1L ) ) { exp_normd = norm_l( L_max_val[i] ); -#ifdef BASOP_NOGLOB max_val_norm_fx = div_s( 0x2800, round_fx_o( L_shl_o( L_max_val[i], exp_normd, &Overflow ), &Overflow ) ); /* Q10-(Qs+exp_normd-16) */ -#else - max_val_norm_fx = div_s( 0x2800, round_fx( L_shl( L_max_val[i], exp_normd ) ) ); /* Q10-(Qs+exp_normd-16) */ -#endif Qmax_val_norm[i] = sub( 10 - 12 + 16 + 15, exp_normd ); move16(); /* 10 - (12+exp_normd-16) +15 */ ; @@ -1019,20 +1012,12 @@ void SpectrumSmoothing_fx( { IF( L_inBuf_pss[j] >= 0 ) { -#ifdef BASOP_NOGLOB outBuf_pss_fx[j] = round_fx_o( L_shl_o( Mpy_32_16_r( L_shl_o( L_inBuf_pss[j], exp_norm, &Overflow ), max_val_norm_fx ), sub( exp_shift, exp_norm ), &Overflow ), &Overflow ); -#else - outBuf_pss_fx[j] = round_fx( L_shl( Mpy_32_16_r( L_shl( L_inBuf_pss[j], exp_norm ), max_val_norm_fx ), sub( exp_shift, exp_norm ) ) ); -#endif move32(); } ELSE { -#ifdef BASOP_NOGLOB outBuf_pss_fx[j] = negate( round_fx_o( L_shl_o( Mpy_32_16_r( L_shl_o( L_abs( L_inBuf_pss[j] ), exp_norm, &Overflow ), max_val_norm_fx ), sub( exp_shift, exp_norm ), &Overflow ), &Overflow ) ); -#else - outBuf_pss_fx[j] = negate( round_fx( L_shl( Mpy_32_16_r( L_shl( L_abs( L_inBuf_pss[j] ), exp_norm ), max_val_norm_fx ), sub( exp_shift, exp_norm ) ) ) ); -#endif move16(); } } @@ -2330,11 +2315,7 @@ void ton_ene_est_fx( exp_pow = sub( 14, temp_hi_fx ); L_band_energy_Linear[i] = Pow2( 14, temp_lo_fx ); move32(); /* Qexp_pow */ -#ifdef BASOP_NOGLOB L_band_energy_Linear[i] = L_shl_sat( L_band_energy_Linear[i], sub( *QbeL, exp_pow ) ); -#else - L_band_energy_Linear[i] = L_shl( L_band_energy_Linear[i], sub( *QbeL, exp_pow ) ); -#endif move32(); /* Div Part */ E_r_fx = 0x7fff; @@ -2357,11 +2338,7 @@ void ton_ene_est_fx( move16(); /* 0.06=15729(Q18) */ exp_shift = sub( 18, QE_r ); -#ifdef BASOP_NOGLOB E_r_shift_fx = shl_o( E_r_fx, exp_shift, &Overflow ); -#else - E_r_shift_fx = shl( E_r_fx, exp_shift ); -#endif IF( LT_16( E_r_shift_fx, 15729 ) ) /* E_r < 0.06 */ { /* avg_pe[k] = (float) sqrt(pow(2.0f,band_energy[i])/band_width[i]); */ @@ -2403,11 +2380,7 @@ void ton_ene_est_fx( L_temp = Mult_32_16( L_temp, E_r_fx ); /* 0.12f: 257698038 (Q31) */ -#ifdef BASOP_NOGLOB if ( GE_32( L_shl_o( L_temp, sub( 31, add( add( shl( Qavg_pe[k], 1 ), QE_r ), 1 - 15 ) ), &Overflow ), 257698038 ) ) -#else - if ( GE_32( L_shl( L_temp, sub( 31, add( add( shl( Qavg_pe[k], 1 ), QE_r ), 1 - 15 ) ) ), 257698038 ) ) -#endif { ni_gain_fx[k] = mult_r( 1638, ni_gain_fx[k] ); /* 0.05 : 1638(Q15) */ move16(); @@ -2433,11 +2406,7 @@ void ton_ene_est_fx( L_E = sum2_fx( &xSynth_har_fx[sub( band_start[i], fLenLow )], band_width[i] ); QE = add( shl( QxSynth_sft, 1 ), 1 ); -#ifdef BASOP_NOGLOB L_E = L_shl_sat( L_E, sub( *QbeL, QE ) ); -#else - L_E = L_shl( L_E, sub( *QbeL, QE ) ); -#endif QE = *QbeL; move16(); } @@ -2647,11 +2616,7 @@ void Gettonl_scalfact_fx( exp_pow = sub( 14, temp_hi_fx ); L_band_energy_Linear[band_pos_fx] = Pow2( 14, temp_lo_fx ); move32(); /* Qexp_pow */ -#ifdef BASOP_NOGLOB L_band_energy_Linear[band_pos_fx] = L_shl_sat( L_band_energy_Linear[band_pos_fx], sub( QbeL, exp_pow ) ); -#else - L_band_energy_Linear[band_pos_fx] = L_shl( L_band_energy_Linear[band_pos_fx], sub( QbeL, exp_pow ) ); -#endif move32(); /* Div Part */ exp_normd = norm_l( L_be_tonal[band_pos_fx] ); @@ -2659,11 +2624,7 @@ void Gettonl_scalfact_fx( exp_normn = norm_l( L_band_energy_Linear[band_pos_fx] ); temp_fx = div_l( L_shl( L_be_tonal[band_pos_fx], exp_normd ), extract_h( L_shl( L_band_energy_Linear[band_pos_fx], exp_normn ) ) ); /* QbeL+exp_normd-(QbeL+exp_normn-16)-1 */ sqrt_32n_16_fx( L_deposit_h( temp_fx ), add( sub( exp_normd, exp_normn ), 31 ), &temp_fx, &Qtemp ); -#ifdef BASOP_NOGLOB enrd_r_fx = extract_h( L_shl_sat( L_mult( enrd_r_fx, temp_fx ), sub( 15, Qtemp ) ) ); -#else - enrd_r_fx = extract_h( L_shl( L_mult( enrd_r_fx, temp_fx ), sub( 15, Qtemp ) ) ); -#endif enrd_r_fx = sub( enrd_r_fx, step_fx ); } ELSE @@ -3274,120 +3235,105 @@ void noiseinj_hf_fx( move32(); IF( p2a_flags_fx[k] == 0 ) { - FOR( i = band_start_fx[k]; i <= band_end_fx[k]; i++ ) - { - IF( LE_32( L_abs( L_xSynth_har[i - fLenLow_fx] ), L_th_g[k - ( BANDS_fx - NB_SWB_SUBBANDS )] ) ) - { - *p_L_En = L_mac( *p_L_En, xSynth_har_fx[i - fLenLow_fx], xSynth_har_fx[i - fLenLow_fx] ); - move32(); - } - ELSE - { - map_pulse_t_fx[i] = 1; - move16(); - } - } -#ifdef BASOP_NOGLOB - *p_L_En = L_shl_sat( *p_L_En, sub( QbeL, QE ) ); -#else - *p_L_En = L_shl( *p_L_En, sub( QbeL, QE ) ); -#endif + FOR( i = band_start_fx[k]; i <= band_end_fx[k]; i++ ){ + IF( LE_32( L_abs( L_xSynth_har[i - fLenLow_fx] ), L_th_g[k - ( BANDS_fx - NB_SWB_SUBBANDS )] ) ){ + *p_L_En = L_mac( *p_L_En, xSynth_har_fx[i - fLenLow_fx], xSynth_har_fx[i - fLenLow_fx] ); move32(); - /**p_L_En = (float)sqrt(*p_En);*/ - sqrt_32n_16_fx( *p_L_En, QbeL, p_sqrt_En_fx, &Qtemp ); -#ifdef BASOP_NOGLOB - *p_sqrt_En_fx = shl_o( *p_sqrt_En_fx, sub( QsEn, Qtemp ), &Overflow ); /* -> Q2 */ - move16(); -#else - *p_sqrt_En_fx = shl( *p_sqrt_En_fx, sub( QsEn, Qtemp ) ); /* -> Q2 */ + } + ELSE + { + map_pulse_t_fx[i] = 1; move16(); -#endif } - p_L_En++; - p_sqrt_En_fx++; } + *p_L_En = L_shl_sat( *p_L_En, sub( QbeL, QE ) ); + move32(); + /**p_L_En = (float)sqrt(*p_En);*/ + sqrt_32n_16_fx( *p_L_En, QbeL, p_sqrt_En_fx, &Qtemp ); + *p_sqrt_En_fx = shl_o( *p_sqrt_En_fx, sub( QsEn, Qtemp ), &Overflow ); /* -> Q2 */ + move16(); +} +p_L_En++; +p_sqrt_En_fx++; +} - p_sqrt_En_fx = sqrt_En_fx; - p_Enn_sm_sb_fx = Enn_sm_sb_fx; - p_prev_En_sb_fx = prev_En_sb_fx; - FOR( k = BANDS_fx - NB_SWB_SUBBANDS; k < BANDS_fx; k++ ) +p_sqrt_En_fx = sqrt_En_fx; +p_Enn_sm_sb_fx = Enn_sm_sb_fx; +p_prev_En_sb_fx = prev_En_sb_fx; +FOR( k = BANDS_fx - NB_SWB_SUBBANDS; k < BANDS_fx; k++ ) +{ + *p_Enn_sm_sb_fx = prev_En_sb_fx[k - ( BANDS_fx - NB_SWB_SUBBANDS )]; + move16(); /* QsEn */ + IF( p2a_flags_fx[k] == 0 ) { - *p_Enn_sm_sb_fx = prev_En_sb_fx[k - ( BANDS_fx - NB_SWB_SUBBANDS )]; - move16(); /* QsEn */ - IF( p2a_flags_fx[k] == 0 ) + L_temp = Mult_32_16( L_band_energy[k], 26214 ); /* 0.8: 26214(Q15) */ + temp_fx = round_fx( L_shl( L_temp, sub( QsEn, sub( Qbe, 16 ) ) ) ); + IF( LT_16( *p_prev_En_sb_fx, temp_fx ) ) { - L_temp = Mult_32_16( L_band_energy[k], 26214 ); /* 0.8: 26214(Q15) */ - temp_fx = round_fx( L_shl( L_temp, sub( QsEn, sub( Qbe, 16 ) ) ) ); - IF( LT_16( *p_prev_En_sb_fx, temp_fx ) ) - { - /**p_Enn_sm_sb = (0.15f*(*p_En)) + (0.85f*prev_En_sb[k-(BANDS-NB_SWB_SUBBANDS)]);*/ - /* 0.15: 4915.2(Q15) 0.85: 27852.80(Q15) */ - *p_Enn_sm_sb_fx = round_fx( L_mac( L_mult( *p_sqrt_En_fx, 4915 ), *p_prev_En_sb_fx, 27853 ) ); - } - ELSE - { - /**p_Enn_sm_sb = (0.8f*(*p_En)) + (0.2f*prev_En_sb[k-(BANDS-NB_SWB_SUBBANDS)]);*/ - /* 0.8: 26214.4(Q15) 0.2:6553.6(Q15) */ - *p_Enn_sm_sb_fx = round_fx( L_mac( L_mult( *p_sqrt_En_fx, 26214 ), *p_prev_En_sb_fx, 6554 ) ); - } - move16(); + /**p_Enn_sm_sb = (0.15f*(*p_En)) + (0.85f*prev_En_sb[k-(BANDS-NB_SWB_SUBBANDS)]);*/ + /* 0.15: 4915.2(Q15) 0.85: 27852.80(Q15) */ + *p_Enn_sm_sb_fx = round_fx( L_mac( L_mult( *p_sqrt_En_fx, 4915 ), *p_prev_En_sb_fx, 27853 ) ); } - - p_Enn_sm_sb_fx++; - p_sqrt_En_fx++; - p_prev_En_sb_fx++; + ELSE + { + /**p_Enn_sm_sb = (0.8f*(*p_En)) + (0.2f*prev_En_sb[k-(BANDS-NB_SWB_SUBBANDS)]);*/ + /* 0.8: 26214.4(Q15) 0.2:6553.6(Q15) */ + *p_Enn_sm_sb_fx = round_fx( L_mac( L_mult( *p_sqrt_En_fx, 26214 ), *p_prev_En_sb_fx, 6554 ) ); + } + move16(); } - p_sqrt_En_fx = sqrt_En_fx; - p_Enn_sm_sb_fx = Enn_sm_sb_fx; - p_prev_En_sb_fx = prev_En_sb_fx; - map_pulse_fx[fLenLow_fx] = ( map_pulse_t_fx[fLenLow_fx] | map_pulse_t_fx[fLenLow_fx + 1] ); + p_Enn_sm_sb_fx++; + p_sqrt_En_fx++; + p_prev_En_sb_fx++; +} + +p_sqrt_En_fx = sqrt_En_fx; +p_Enn_sm_sb_fx = Enn_sm_sb_fx; +p_prev_En_sb_fx = prev_En_sb_fx; +map_pulse_fx[fLenLow_fx] = ( map_pulse_t_fx[fLenLow_fx] | map_pulse_t_fx[fLenLow_fx + 1] ); +logic16(); +move16(); +FOR( i = fLenLow_fx + 1; i < band_end_fx[BANDS_fx - 1]; i++ ) +{ + map_pulse_fx[i] = ( map_pulse_t_fx[i - 1] | map_pulse_t_fx[i] | map_pulse_t_fx[i + 1] ); logic16(); - move16(); - FOR( i = fLenLow_fx + 1; i < band_end_fx[BANDS_fx - 1]; i++ ) - { - map_pulse_fx[i] = ( map_pulse_t_fx[i - 1] | map_pulse_t_fx[i] | map_pulse_t_fx[i + 1] ); - logic16(); - logic16(); - move16(); - } - map_pulse_fx[i] = ( map_pulse_t_fx[i - 1] | map_pulse_t_fx[i] ); logic16(); move16(); +} +map_pulse_fx[i] = ( map_pulse_t_fx[i - 1] | map_pulse_t_fx[i] ); +logic16(); +move16(); - FOR( k = BANDS_fx - NB_SWB_SUBBANDS; k < BANDS_fx; k++ ) +FOR( k = BANDS_fx - NB_SWB_SUBBANDS; k < BANDS_fx; k++ ) +{ + test(); + IF( p2a_flags_fx[k] == 0 && *p_sqrt_En_fx != 0x0 ) { - test(); - IF( p2a_flags_fx[k] == 0 && *p_sqrt_En_fx != 0x0 ) - { - /*ni_scale = sqrt((*p_Enn_sm_sb)/(*p_En));*/ - /* Div Part */ - exp_normn = norm_s( *p_Enn_sm_sb_fx ); - exp_normn = sub( exp_normn, 1 ); - exp_normd = norm_s( *p_sqrt_En_fx ); - div_fx = div_s( shl( *p_Enn_sm_sb_fx, exp_normn ), shl( *p_sqrt_En_fx, exp_normd ) ); - Qdiv = add( sub( exp_normn, exp_normd ), 15 ); - - /* SQRT Part */ - sqrt_32n_16_fx( L_deposit_h( div_fx ), add( Qdiv, 16 ), &ni_scale_fx, &Qtemp ); -#ifdef BASOP_NOGLOB - ni_scale_fx = shl_o( ni_scale_fx, sub( 14, Qtemp ), &Overflow ); -#else - ni_scale_fx = shl( ni_scale_fx, sub( 14, Qtemp ) ); -#endif - ni_scale_fx = s_min( 20408, ni_scale_fx ); /* 1.25=20408.0(Q14) */ - - ni_scale_fx = s_max( 12288, ni_scale_fx ); /* 0.75=12288.0(Q14) */ - - ni_scale_fx = mult_r( ni_scale_fx, 26214 ); /* 0.8=26214.4(Q15) -> Q14 */ - FOR( i = band_start_fx[k]; i <= band_end_fx[k]; i++ ){ - IF( LE_32( L_abs( L_xSynth_har[i - fLenLow_fx] ), L_th_g[k - ( BANDS_fx - NB_SWB_SUBBANDS )] ) ){ - IF( map_pulse_fx[i] == 0 ){ - L_xSynth_har[i - fLenLow_fx] = L_shl( Mult_32_16( L_xSynth_har[i - fLenLow_fx], ni_scale_fx ), 1 ); /* Q12+Q14-15-1 = Q12 */ - move32(); - } + /*ni_scale = sqrt((*p_Enn_sm_sb)/(*p_En));*/ + /* Div Part */ + exp_normn = norm_s( *p_Enn_sm_sb_fx ); + exp_normn = sub( exp_normn, 1 ); + exp_normd = norm_s( *p_sqrt_En_fx ); + div_fx = div_s( shl( *p_Enn_sm_sb_fx, exp_normn ), shl( *p_sqrt_En_fx, exp_normd ) ); + Qdiv = add( sub( exp_normn, exp_normd ), 15 ); + + /* SQRT Part */ + sqrt_32n_16_fx( L_deposit_h( div_fx ), add( Qdiv, 16 ), &ni_scale_fx, &Qtemp ); + ni_scale_fx = shl_o( ni_scale_fx, sub( 14, Qtemp ), &Overflow ); + ni_scale_fx = s_min( 20408, ni_scale_fx ); /* 1.25=20408.0(Q14) */ + + ni_scale_fx = s_max( 12288, ni_scale_fx ); /* 0.75=12288.0(Q14) */ + + ni_scale_fx = mult_r( ni_scale_fx, 26214 ); /* 0.8=26214.4(Q15) -> Q14 */ + FOR( i = band_start_fx[k]; i <= band_end_fx[k]; i++ ){ + IF( LE_32( L_abs( L_xSynth_har[i - fLenLow_fx] ), L_th_g[k - ( BANDS_fx - NB_SWB_SUBBANDS )] ) ){ + IF( map_pulse_fx[i] == 0 ){ + L_xSynth_har[i - fLenLow_fx] = L_shl( Mult_32_16( L_xSynth_har[i - fLenLow_fx], ni_scale_fx ), 1 ); /* Q12+Q14-15-1 = Q12 */ + move32(); } } +} *p_prev_En_sb_fx = *p_Enn_sm_sb_fx; move16(); } diff --git a/lib_com/swb_tbe_com.c b/lib_com/swb_tbe_com.c index 9b20512a24e17ca91b7c39668a07e128894cf01f..7905c7145b985c6cf56ef687f1c2d7600d03f363 100644 --- a/lib_com/swb_tbe_com.c +++ b/lib_com/swb_tbe_com.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other @@ -38,11 +38,9 @@ #include "options.h" #include #include "cnst.h" -#include "prot.h" #include "prot_fx.h" #include "rom_com.h" #include "wmc_auto.h" -#include "ivas_prot.h" #include @@ -69,7 +67,45 @@ void GenSHBSynth_fx_32( Word32 speech_buf_32k[L_FRAME32k]; Word16 i; +#ifdef FIX_881_HILBERT_FILTER + Word16 shift = 0; + Word32 maxm32, input_synspeech_temp[L_FRAME16k]; + move16(); + + /* find the maximum value and derive the shift to improve precision of the Hilber filter */ + maxm32 = L_deposit_l( 0 ); + FOR( i = 0; i < L_FRAME16k; i++ ) + { + maxm32 = L_max( maxm32, L_abs( input_synspeech[i] ) ); + } + + FOR( i = 0; i < 2 * ALLPASSSECTIONS_STEEP; i++ ) + { + maxm32 = L_max( maxm32, L_abs( state_lsyn_filt_shb_local[i] ) ); + } + + FOR( i = 0; i < HILBERT_MEM_SIZE; i++ ) + { + maxm32 = L_max( maxm32, L_abs( Hilbert_Mem[i] ) ); + } + + IF( maxm32 != 0 ) + { + shift = sub( norm_l( maxm32 ), 3 ); + + Copy_Scale_sig32( input_synspeech, input_synspeech_temp, L_FRAME16k, shift ); + Scale_sig32( state_lsyn_filt_shb_local, 2 * ALLPASSSECTIONS_STEEP, shift ); + Scale_sig32( Hilbert_Mem, HILBERT_MEM_SIZE, shift ); + } + ELSE + { + Copy32( input_synspeech, input_synspeech_temp, L_FRAME16k ); + } + + Interpolate_allpass_steep_32( input_synspeech_temp, state_lsyn_filt_shb_local, L_FRAME16k, speech_buf_32k ); +#else Interpolate_allpass_steep_32( input_synspeech, state_lsyn_filt_shb_local, L_FRAME16k, speech_buf_32k ); +#endif IF( EQ_16( L_frame, L_FRAME ) ) { @@ -92,6 +128,15 @@ void GenSHBSynth_fx_32( } } +#ifdef FIX_881_HILBERT_FILTER + IF( maxm32 != 0 ) + { + Scale_sig32( shb_syn_speech_32k, L_FRAME32k, negate( shift ) ); + Scale_sig32( state_lsyn_filt_shb_local, 2 * ALLPASSSECTIONS_STEEP, negate( shift ) ); + Scale_sig32( Hilbert_Mem, HILBERT_MEM_SIZE, negate( shift ) ); + } +#endif + return; } void ScaleShapedSHB_32( diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index 494dbebd5d0262f5d437ec2f3787954d8d4ae2bf..7e9471c45b04a77a33f67679e751f60168fc5a05 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -7,7 +7,6 @@ #include "options.h" #include "cnst.h" /* Common constants */ #include "rom_com.h" /* Static table prototypes */ -#include "prot.h" #include "prot_fx.h" #include "basop_util.h" #include "ivas_prot_fx.h" @@ -810,6 +809,65 @@ void Calc_rc0_h( } } +void Calc_rc0_h_ivas_enc_fx( + Word16 *h, /* i : impulse response of composed filter */ + Word16 *rc0 /* o : 1st parcor */ +) +{ + Word32 L_acc; + Word16 *ptrs; + Word16 acf0, acf1; + Word16 temp, sh_acf, tmp2; + Word16 i; + + /* computation of the autocorrelation function acf */ + L_acc = L_mult( h[0], h[0] ); + FOR( i = 1; i < LONG_H_ST; i++ ) + { + tmp2 = shr( h[i], 2 ); + L_acc = L_mac( L_acc, tmp2, tmp2 ); + } + sh_acf = norm_l( L_acc ); + L_acc = L_shl( L_acc, sh_acf ); + acf0 = extract_h( L_acc ); + + ptrs = h; + + temp = *ptrs++; + move16(); + L_acc = L_mult( temp, *ptrs ); + FOR( i = 1; i < LONG_H_ST - 1; i++ ) + { + temp = shr( *ptrs++, 2 ); + move16(); + L_acc = L_mac( L_acc, temp, shr( *ptrs, 2 ) ); + } + L_acc = L_shl( L_acc, sh_acf ); + acf1 = extract_h( L_acc ); + + /* Compute 1st parcor */ + IF( acf0 == 0 ) + { + *rc0 = 0; + move16(); + return; + } + + IF( LT_16( acf0, abs_s( acf1 ) ) ) + { + *rc0 = 0; + move16(); + return; + } + *rc0 = div_s( abs_s( acf1 ), acf0 ); + move16(); + IF( acf1 > 0 ) + { + *rc0 = negate( *rc0 ); + move16(); + } +} + static void Calc_st_filt_tbe( Word16 *apond2, /* i : coefficients of numerator */ Word16 *apond1, /* i : coefficients of denominator */ @@ -868,7 +926,7 @@ static void Calc_st_filt_tbe_ivas_enc_fx( /* compute i.r. of composed filter apond2 / apond1 */ syn_filt_fx( temp, apond1, LPC_SHB_ORDER, apond2, h, LONG_H_ST, mem_zero, 0 ); /* compute 1st parcor */ - Calc_rc0_h( h, parcor0 ); + Calc_rc0_h_ivas_enc_fx( h, parcor0 ); /* compute g0 */ L_g0 = L_mult0( 1, abs_s( h[0] ) ); @@ -982,7 +1040,11 @@ static void filt_mu_fx( FOR( n = 0; n < SubFrameLength; n++ ) { temp = mult_r( mu, ( *ptrs++ ) ); +#ifdef FIX_ISSUE_1155 + temp = add_sat( temp, *ptrs ); /*Q12 */ +#else temp = add( temp, *ptrs ); /*Q12 */ +#endif sig_out[n] = shl_o( mult_r( ga, temp ), 1, &Overflow ); move16(); /*Q12 */ } @@ -1082,13 +1144,8 @@ static void scale_st_swb( temp = mult_r( agc_fac_para_fx, gain_fx ); /*15 +14 -15 =14 */ gain_fx = add( temp, g0_fx ); /* in Q14 */ L_temp = L_mult( gain_fx, sig_out_fx[i] ); /*14 + Q_bwe_exc-1 +1 = 14 + Q_bwe_exc */ -#ifdef BASOP_NOGLOB - L_temp = L_shl_sat( L_temp, 1 ); /*14 + Q_bwe_exc +1 */ - sig_out_fx[i] = round_fx_sat( L_temp ); /*Q_bwe_exc +15 -16 = Q_bwe_exc-1 */ -#else - L_temp = L_shl( L_temp, 1 ); /*14 + Q_bwe_exc +1 */ - sig_out_fx[i] = round_fx( L_temp ); /*Q_bwe_exc +15 -16 = Q_bwe_exc-1 */ -#endif + L_temp = L_shl_sat( L_temp, 1 ); /*14 + Q_bwe_exc +1 */ + sig_out_fx[i] = round_fx_sat( L_temp ); /*Q_bwe_exc +15 -16 = Q_bwe_exc-1 */ move16(); } *gain_prec_fx = gain_fx; @@ -1355,7 +1412,7 @@ void flip_spectrum_and_decimby4_fx( /* CALLED FROM : */ /*==========================================================================*/ -void ivas_GenShapedWBExcitation_fx( +void GenShapedWBExcitation_ivas_fx( Word16 *excSHB, /* o : synthesized shaped shb exctiation Q_bwe_exc*/ const Word16 *lpc_shb, /* i : lpc coefficients Q12*/ Word16 *exc4kWhtnd, /* o : whitened synthesized shb excitation Q_bwe_exc*/ @@ -1487,35 +1544,22 @@ void ivas_GenShapedWBExcitation_fx( n1 = norm_s( max_val ); FOR( i = 0; i < L_FRAME16k / 4; i++ ) { -#ifdef BASOP_NOGLOB excTmp2_frac[i] = shl_o( excTmp2[i], n1, &Overflow ); // Q_bwe_exc + n1 -#else - excTmp2_frac[i] = shl( excTmp2[i], n1 ); -#endif - move16(); /* Q14 */ + move16(); /* Q14 */ } n1 = sub( sub( 14, n1 ), Q_bwe_exc ); pow1 = 1; move32(); FOR( i = 0; i < L_FRAME16k / 4; i++ ) { -#ifdef BASOP_NOGLOB L_tmp = L_mult_o( excTmp2_frac[i], excTmp2_frac[i], &Overflow ); /* Q29 */ pow1 = L_add_o( pow1, L_shr( L_tmp, 10 ), &Overflow ); /* Q22 */ -#else - L_tmp = L_mult( excTmp2_frac[i], excTmp2_frac[i] ); /* Q29 */ - pow1 = L_add( pow1, L_shr( L_tmp, 7 ) ); /* Q22 */ -#endif } } FOR( i = 0; i < L_FRAME16k / 4; i++ ) { -#ifdef BASOP_NOGLOB excNoisyEnv[i] = L_add_o( *mem_csfilt, L_mult_o( csfilt_num2[0], excTmp2[i], &Overflow ), &Overflow ); -#else - excNoisyEnv[i] = L_add( *mem_csfilt, L_mult( csfilt_num2[0], excTmp2[i] ) ); -#endif move32(); /* Q_bwe_exc+16 */ *mem_csfilt = Mult_32_16( excNoisyEnv[i], neg_csfilt_den2[1] ); move32(); /* Q_bwe_exc+16 */ @@ -1545,11 +1589,7 @@ void ivas_GenShapedWBExcitation_fx( n2 = norm_l( Lmax ); FOR( i = 0; i < L_FRAME16k / 4; i++ ) { -#ifdef BASOP_NOGLOB exc4k_frac[i] = extract_h( L_shl_o( exc4k_32[i], n2, &Overflow ) ); /* Q(14-n2) */ -#else - exc4k_frac[i] = extract_h( L_shl( exc4k_32[i], n2 ) ); /* Q(14-n2) */ -#endif move16(); } n2 = 30 - n2 - ( Q_bwe_exc + 6 ); @@ -1557,13 +1597,8 @@ void ivas_GenShapedWBExcitation_fx( move32(); FOR( i = 0; i < L_FRAME16k / 4; i++ ) { -#ifdef BASOP_NOGLOB L_tmp = L_mult_o( exc4k_frac[i], exc4k_frac[i], &Overflow ); /* Q29 */ pow22 = L_add_o( pow22, L_shr( L_tmp, 10 ), &Overflow ); /* Q22 */ -#else - L_tmp = L_mult( exc4k_frac[i], exc4k_frac[i] ); /* Q29 */ - pow22 = L_add( pow22, L_shr( L_tmp, 7 ) ); /* Q22 */ -#endif } } @@ -1572,19 +1607,11 @@ void ivas_GenShapedWBExcitation_fx( IF( EQ_16( coder_type, UNVOICED ) || ( igf_flag != 0 && LT_16( avg_voice_fac, 6654 /* 0.2 in Q15 */ ) ) ) { L_tmp = root_a_over_b_fx( pow1, sub( 19, shl( n1, 1 ) ), pow22, sub( 19, shl( n2, 1 ) ), &exp ); -#ifdef BASOP_NOGLOB scale = round_fx_o( L_shl_o( L_tmp, exp, &Overflow ), &Overflow ); /*Q15 */ -#else - scale = round_fx( L_shl( L_tmp, exp ) ); /*Q15 */ -#endif sc = sub( add( n2, Q_bwe_exc ), 14 ); FOR( i = 0; i < L_FRAME16k / 4; i++ ) { -#ifdef BASOP_NOGLOB exc4kWhtnd[i] = round_fx_o( L_shl_o( L_mult_o( exc4k_frac[i], scale, &Overflow ), sc, &Overflow ), &Overflow ); /* Q_bwe_exc+n2-10+16+ Q_bwe_exc + n2 -14 -16 = //Q_bwe_exc */ -#else - exc4kWhtnd[i] = round_fx( L_shl( L_mult( exc4k_frac[i], scale ), sc ) ); /* Q_bwe_exc+n2-10+16+ Q_bwe_exc + n2 -14 -16 = //Q_bwe_exc */ -#endif move16(); } } @@ -1600,13 +1627,7 @@ void ivas_GenShapedWBExcitation_fx( { /*tmp_vfac = 2*voice_factors[i]; tmp_vfac = min(1, tmp_vfac);*/ -#ifdef BASOP_NOGLOB tmp_vfac = shl_o( voice_factors[i], 1, &Overflow ); -#else - BASOP_SATURATE_WARNING_OFF_EVS - tmp_vfac = shl( voice_factors[i], 1 ); - BASOP_SATURATE_WARNING_ON_EVS -#endif } ELSE { @@ -1615,29 +1636,15 @@ void ivas_GenShapedWBExcitation_fx( } Ltemp1 = root_a_fx( L_deposit_h( tmp_vfac ), 31, &exp ); -#ifdef BASOP_NOGLOB temp1 = round_fx_o( L_shl_o( Ltemp1, exp, &Overflow ), &Overflow ); /* Q15 */ -#else - temp1 = round_fx( L_shl( Ltemp1, exp ) ); /* Q15 */ -#endif - L_tmp = Mult_32_16( pow1, sub( 32767, tmp_vfac ) ); /* Q22*/ + L_tmp = Mult_32_16( pow1, sub( 32767, tmp_vfac ) ); /* Q22*/ Ltemp2 = root_a_over_b_fx( L_tmp, sub( 19, shl( n1, 1 ) ), pow22, sub( 19, shl( n2, 1 ) ), &exp ); -#ifdef BASOP_NOGLOB temp2 = round_fx_o( L_shl_o( Ltemp2, exp, &Overflow ), &Overflow ); /* Q15 */ -#else - temp2 = round_fx( L_shl( Ltemp2, exp ) ); /* Q15 */ -#endif FOR( j = 0; j < L_FRAME16k / 16; j++ ) { -#ifdef BASOP_NOGLOB L_tmp = L_mult_o( temp1, exc4kWhtnd[k], &Overflow ); /* Q(16+Q_bwe_exc) */ L_tmp = L_add_o( L_tmp, L_shl_o( L_mult_o( temp2, exc4k_frac[k], &Overflow ), sc, &Overflow ), &Overflow ); /* Q(16+Q_bwe_exc) */ exc4kWhtnd[k] = round_fx_o( L_tmp, &Overflow ); /* Q_bwe_exc */ -#else - L_tmp = L_mult( temp1, exc4kWhtnd[k] ); /* Q(16+Q_bwe_exc) */ - L_tmp = L_add( L_tmp, L_shl( L_mult( temp2, exc4k_frac[k] ), sc ) ); /* Q(16+Q_bwe_exc) */ - exc4kWhtnd[k] = round_fx( L_tmp ); /* Q_bwe_exc */ -#endif move16(); k++; } @@ -1784,11 +1791,7 @@ void GenShapedWBExcitation_fx( n1 = norm_s( max_val ); FOR( i = 0; i < L_FRAME16k / 4; i++ ) { -#ifdef BASOP_NOGLOB excTmp2_frac[i] = shl_o( excTmp2[i], n1, &Overflow ); -#else - excTmp2_frac[i] = shl( excTmp2[i], n1 ); -#endif move16(); /* Q14 */ } n1 = sub( sub( 14, n1 ), Q_bwe_exc ); @@ -1796,23 +1799,14 @@ void GenShapedWBExcitation_fx( move32(); FOR( i = 0; i < L_FRAME16k / 4; i++ ) { -#ifdef BASOP_NOGLOB L_tmp = L_mult_o( excTmp2_frac[i], excTmp2_frac[i], &Overflow ); /* Q29 */ pow1 = L_add_o( pow1, L_shr( L_tmp, 7 ), &Overflow ); /* Q22 */ -#else - L_tmp = L_mult( excTmp2_frac[i], excTmp2_frac[i] ); /* Q29 */ - pow1 = L_add( pow1, L_shr( L_tmp, 7 ) ); /* Q22 */ -#endif } } FOR( i = 0; i < L_FRAME16k / 4; i++ ) { -#ifdef BASOP_NOGLOB excNoisyEnv[i] = L_add_o( *mem_csfilt, L_mult_o( csfilt_num2[0], excTmp2[i], &Overflow ), &Overflow ); -#else - excNoisyEnv[i] = L_add( *mem_csfilt, L_mult( csfilt_num2[0], excTmp2[i] ) ); -#endif move32(); /* Q_bwe_exc+16 */ *mem_csfilt = Mpy_32_16_1( excNoisyEnv[i], neg_csfilt_den2[1] ); move32(); /* Q_bwe_exc+16 */ @@ -1843,11 +1837,7 @@ void GenShapedWBExcitation_fx( n2 = norm_l( Lmax ); FOR( i = 0; i < L_FRAME16k / 4; i++ ) { -#ifdef BASOP_NOGLOB exc4k_frac[i] = extract_h( L_shl_o( exc4k_32[i], n2, &Overflow ) ); /* Q(14-n2) */ -#else - exc4k_frac[i] = extract_h( L_shl( exc4k_32[i], n2 ) ); /* Q(14-n2) */ -#endif move16(); } n2 = sub( sub( 30, n2 ), add( Q_bwe_exc, 6 ) ); @@ -1855,13 +1845,8 @@ void GenShapedWBExcitation_fx( move32(); FOR( i = 0; i < L_FRAME16k / 4; i++ ) { -#ifdef BASOP_NOGLOB L_tmp = L_mult_o( exc4k_frac[i], exc4k_frac[i], &Overflow ); /* Q29 */ pow22 = L_add_o( pow22, L_shr( L_tmp, 7 ), &Overflow ); /* Q22 */ -#else - L_tmp = L_mult( exc4k_frac[i], exc4k_frac[i] ); /* Q29 */ - pow22 = L_add( pow22, L_shr( L_tmp, 7 ) ); /* Q22 */ -#endif } } @@ -1870,19 +1855,11 @@ void GenShapedWBExcitation_fx( IF( EQ_16( coder_type, UNVOICED ) || ( igf_flag != 0 && LT_16( avg_voice_fac, 6654 /*0.2 in Q15 */ ) ) ) { L_tmp = root_a_over_b_fx( pow1, sub( 22, shl( n1, 1 ) ), pow22, sub( 22, shl( n2, 1 ) ), &exp ); -#ifdef BASOP_NOGLOB scale = round_fx_o( L_shl_o( L_tmp, exp, &Overflow ), &Overflow ); /*Q15 */ -#else - scale = round_fx( L_shl( L_tmp, exp ) ); /*Q15 */ -#endif sc = sub( add( n2, Q_bwe_exc ), 14 ); FOR( i = 0; i < L_FRAME16k / 4; i++ ) { -#ifdef BASOP_NOGLOB exc4kWhtnd[i] = round_fx_o( L_shl_o( L_mult_o( exc4k_frac[i], scale, &Overflow ), sc, &Overflow ), &Overflow ); /* Q_bwe_exc+n2-10+16+ Q_bwe_exc + n2 -14 -16 = //Q_bwe_exc */ -#else - exc4kWhtnd[i] = round_fx( L_shl( L_mult( exc4k_frac[i], scale ), sc ) ); /* Q_bwe_exc+n2-10+16+ Q_bwe_exc + n2 -14 -16 = //Q_bwe_exc */ -#endif move16(); } } @@ -1899,13 +1876,7 @@ void GenShapedWBExcitation_fx( { /*tmp_vfac = 2*voice_factors[i]; tmp_vfac = min(1, tmp_vfac);*/ -#ifdef BASOP_NOGLOB tmp_vfac = shl_o( voice_factors[i], 1, &Overflow ); -#else - BASOP_SATURATE_WARNING_OFF_EVS - tmp_vfac = shl( voice_factors[i], 1 ); - BASOP_SATURATE_WARNING_ON_EVS -#endif } ELSE { @@ -1914,29 +1885,15 @@ void GenShapedWBExcitation_fx( } Ltemp1 = root_a_fx( L_deposit_h( tmp_vfac ), 31, &exp ); -#ifdef BASOP_NOGLOB temp1 = round_fx_o( L_shl_o( Ltemp1, exp, &Overflow ), &Overflow ); /* Q15 */ -#else - temp1 = round_fx( L_shl( Ltemp1, exp ) ); /* Q15 */ -#endif - L_tmp = Mpy_32_16_1( pow1, sub( 32767, tmp_vfac ) ); /* Q22*/ + L_tmp = Mpy_32_16_1( pow1, sub( 32767, tmp_vfac ) ); /* Q22*/ Ltemp2 = root_a_over_b_fx( L_tmp, sub( 22, shl( n1, 1 ) ), pow22, sub( 22, shl( n2, 1 ) ), &exp ); -#ifdef BASOP_NOGLOB temp2 = round_fx_o( L_shl_o( Ltemp2, exp, &Overflow ), &Overflow ); /* Q15 */ -#else - temp2 = round_fx( L_shl( Ltemp2, exp ) ); /* Q15 */ -#endif FOR( j = 0; j < L_FRAME16k / 16; j++ ) { -#ifdef BASOP_NOGLOB L_tmp = L_mult_o( temp1, exc4kWhtnd[k], &Overflow ); /* Q(16+Q_bwe_exc) */ L_tmp = L_add_o( L_tmp, L_shl_o( L_mult_o( temp2, exc4k_frac[k], &Overflow ), sc, &Overflow ), &Overflow ); /* Q(16+Q_bwe_exc) */ exc4kWhtnd[k] = round_fx_o( L_tmp, &Overflow ); /* Q_bwe_exc */ -#else - L_tmp = L_mult( temp1, exc4kWhtnd[k] ); /* Q(16+Q_bwe_exc) */ - L_tmp = L_add( L_tmp, L_shl( L_mult( temp2, exc4k_frac[k] ), sc ) ); /* Q(16+Q_bwe_exc) */ - exc4kWhtnd[k] = round_fx( L_tmp ); /* Q_bwe_exc */ -#endif move16(); k = add( k, 1 ); } @@ -1950,7 +1907,6 @@ void GenShapedWBExcitation_fx( return; } - /*-------------------------------------------------------------------* * GenWBSynth() * @@ -2277,11 +2233,7 @@ void GenShapedSHBExcitation_fx( /* Estimate pow1 associated with Low band nonlinear extended excitation */ /* pow1=0.00001f */ tmp = sub( shl( *Q_bwe_exc, 1 ), 31 ); -#ifdef BASOP_NOGLOB pow1 = L_shl_sat( 21475l /*0.00001f Q31*/, tmp ); /* 0.00001f in 2*(Q_bwe_exc) */ -#else - pow1 = L_shl( 21475l /*0.00001f Q31*/, tmp ); /* 0.00001f in 2*(Q_bwe_exc) */ -#endif FOR( k = 0; k < L_FRAME16k; k++ ) { /*excTmp2[k ] = (float)(fabs(exc16kWhtnd[k]));*/ @@ -2289,11 +2241,7 @@ void GenShapedSHBExcitation_fx( move16(); /* pow1 += exc16kWhtnd[k] * exc16kWhtnd[k]; */ -#ifdef BASOP_NOGLOB pow1 = L_mac0_sat( pow1, exc16kWhtnd[k], exc16kWhtnd[k] ); /* 2*Q_bwe_exc */ -#else - pow1 = L_mac0( pow1, exc16kWhtnd[k], exc16kWhtnd[k] ); /* 2*Q_bwe_exc */ -#endif } Q_pow1 = shl( *Q_bwe_exc, 1 ); @@ -2455,11 +2403,7 @@ void GenShapedSHBExcitation_fx( tmp = add( *Q_bwe_exc, 1 ); FOR( k = 0; k < L_FRAME16k; k++ ) { -#ifdef BASOP_NOGLOB L_tmp4 = L_shl_sat( L_deposit_l( White_exc16k[k] ), tmp ); -#else - L_tmp4 = L_shl( L_deposit_l( White_exc16k[k] ), tmp ); -#endif if ( excNoisyEnv[k] != 0 ) { L_tmp4 = L_mult( excNoisyEnv[k], White_exc16k[k] ); /* (Q_bwe_exc) +5 +1*/ @@ -2491,11 +2435,7 @@ void GenShapedSHBExcitation_fx( /* i: White_exc16k in Q6 */ /* o: White_exc16k in (Q_bwe_exc-NOISE_QADJ) */ /* pow22 += White_exc16k[k] * White_exc16k[k]; */ -#ifdef BASOP_NOGLOB pow22 = L_mac0_sat( pow22, White_exc16k[k], White_exc16k[k] ); /* 2*(Q_bwe_exc-NOISE_QADJ)*/ -#else - pow22 = L_mac0( pow22, White_exc16k[k], White_exc16k[k] ); /* 2*(Q_bwe_exc-NOISE_QADJ)*/ -#endif } /*Q_pow22 = sub( shl(*Q_bwe_exc,1), 18 );*/ Q_pow22 = shl( sub( *Q_bwe_exc, NOISE_QADJ ), 1 ); @@ -2716,11 +2656,7 @@ void GenShapedSHBExcitation_fx( #endif { L_tmp = root_a_over_b_fx( pow1, Q_pow1, pow22, Q_pow22, &exp ); -#ifdef BASOP_NOGLOB scale = round_fx_sat( L_shl_sat( L_tmp, exp ) ); /*Q15 */ -#else - scale = round_fx( L_shl( L_tmp, exp ) ); /*Q15 */ -#endif FOR( k = 0; k < L_FRAME16k; k++ ) { /* White_exc16k: (Q_bwe_exc-NOISE_QADJ), scale: Q15 */ @@ -2768,11 +2704,7 @@ void GenShapedSHBExcitation_fx( temp = sub( MAX_16, temp ); tempQ31 = Mult_32_16( pow1, temp ); L_tmp = root_a_over_b_fx( tempQ31, Q_pow1, pow22, Q_pow22, &exp ); -#ifdef BASOP_NOGLOB temp2 = round_fx_sat( L_shl_sat( L_tmp, exp ) ); /* Q15 whiteEnvShapedExc scale factor */ -#else - temp2 = round_fx( L_shl( L_tmp, exp ) ); /* Q15 whiteEnvShapedExc scale factor */ -#endif } ELSE { @@ -2791,24 +2723,15 @@ void GenShapedSHBExcitation_fx( temp = sub( MAX_16, vf_tmp ); tempQ31 = Mult_32_16( pow1, temp ); L_tmp = root_a_over_b_fx( tempQ31, Q_pow1, pow22, Q_pow22, &exp ); -#ifdef BASOP_NOGLOB temp2 = round_fx_sat( L_shl_sat( L_tmp, exp ) ); /* Q15 whiteEnvShapedExc scale factor */ -#else - temp2 = round_fx( L_shl( L_tmp, exp ) ); /* Q15 whiteEnvShapedExc scale factor */ -#endif } FOR( j = 0; j < lSubFr; j++ ) { /*exc16kWhtnd[k+j] = temp1 * exc16kWhtnd[k+j] + temp2 * White_exc16k[k+j]; */ L_tmp = L_mult( temp2, White_exc16k[k + j] ); /* 16+(Q_bwe_exc-NOISE_QADJ)*/ -#ifdef BASOP_NOGLOB - L_tmp = L_shl_sat( L_tmp, NOISE_QADJ ); /* 16+(Q_bwe_exc) */ + L_tmp = L_shl_sat( L_tmp, NOISE_QADJ ); /* 16+(Q_bwe_exc) */ exc16kWhtnd[k + j] = mac_r_sat( L_tmp, temp1, exc16kWhtnd[k + j] ); -#else - L_tmp = L_shl( L_tmp, NOISE_QADJ ); /* 16+(Q_bwe_exc) */ - exc16kWhtnd[k + j] = mac_r( L_tmp, temp1, exc16kWhtnd[k + j] ); -#endif move16(); /* Q_bwe_exc */ } @@ -2955,7 +2878,7 @@ void GenShapedSHBExcitation_fx( void GenShapedSHBExcitation_ivas_enc_fx( Word16 *excSHB, /* o : synthesized shaped shb excitation Q_bwe_exc*/ const Word16 *lpc_shb, /* i : lpc coefficients Q12*/ - Word16 *White_exc16k_FB, /* o : white excitation for the Fullband extension Q_bwe_exc */ + Word16 *White_exc16k_FB, /* o : white excitation for the Fullband extension Q_bwe_exc_fb */ Word32 *mem_csfilt, /* i/o: memory */ Word16 *mem_genSHBexc_filt_down_shb, /* i/o: memory */ Word16 *state_lpc_syn, /* i/o: memory */ @@ -2977,21 +2900,24 @@ void GenShapedSHBExcitation_ivas_enc_fx( Word16 *Q_bwe_exc, Word16 *Q_bwe_exc_fb, const Word16 Q_shb, - Word16 n_mem2, /* i : n_mem2 scale factor to adjust 24.4/32kbps memories */ - Word16 prev_Q_bwe_syn, /* i : st_fx->prev_Q_bwe_syn */ - const Word32 bitrate, /* i : bitrate */ - const Word16 prev_bfi, /* i : previous frame was concealed */ - const Word16 element_mode, /* i : element mode */ - const Word16 flag_ACELP16k, /* i : ACELP@16kHz flag */ - Word16 *nlExc16k, /* i/o: NL exc for IC-BWE */ - Word16 *mixExc16k, /* i/o: exc spreading for IC-BWE */ - const Word32 extl_brate, /* i : extension layer bitarte */ - const Word16 MSFlag, /* i : Multi Source flag */ - Word16 EnvSHBres_4k[], /* i/o: TD envelope of the SHB residual signal */ - Word32 *prev_pow_exc16kWhtnd, /* i/o: power of the LB excitation signal in the previous frame */ - Word16 *prev_mix_factor, /* i/o: mixing factor in the previous frame */ - Word16 *Env_error, /* o : error in SHB residual envelope modelling Q0 */ - Word16 Env_error_part[] /* o : per-segment error in SHB residual envelope modelling Q0 */ + Word16 n_mem2, /* i : n_mem2 scale factor to adjust 24.4/32kbps memories */ + Word16 prev_Q_bwe_syn, /* i : st_fx->prev_Q_bwe_syn */ + const Word32 bitrate, + const Word16 prev_bfi, + const Word16 element_mode, /* i : element mode */ + const Word16 flag_ACELP16k, /* i : ACELP@16kHz flag */ + Word16 *nlExc16k, /* i/o: NL exc for IC-BWE */ + Word16 *nlExc16k_e, /* i/o: exp of nlExc16k */ + Word16 *mixExc16k, /* i/o: exc spreading for IC-BWE */ + Word16 *mixExc16k_e, /* i/o: exp of mixExc16k_fx */ + const Word32 extl_brate, /* i : extension layer bitarte */ + const Word16 MSFlag, /* i : Multi Source flag */ + Word16 EnvSHBres_4k[], /* i/o: TD envelope of the SHB residual signal */ + Word16 Q_EnvSHBres_4k, + Word32 *prev_pow_exc16kWhtnd, /* i/o: power of the LB excitation signal in the previous frame */ + Word16 *prev_mix_factor, /* i/o: mixing factor in the previous frame */ + Word16 *Env_error, /* o : error in SHB residual envelope modelling*/ + Word16 Env_error_part[] /* o : per-segment error in SHB residual envelope modelling */ ) { Word16 i, j, k; @@ -3007,6 +2933,7 @@ void GenShapedSHBExcitation_ivas_enc_fx( Word16 excTmp2[L_FRAME16k]; Word16 *White_exc16k; + Word16 Q_White_exc16k; Word16 excNoisyEnv[L_FRAME16k]; Word16 csfilt_num2[1] = { 6554 }; /*0.2 in Q15 */ move16(); @@ -3034,15 +2961,8 @@ void GenShapedSHBExcitation_ivas_enc_fx( Word16 White_exc16k_FB_temp[L_FRAME16k]; Word32 White_exc16k_32[L_FRAME16k]; Word16 White_exc16k_tmp[L_FRAME16k]; - Word16 Q_temp; Word16 prev_Q_bwe_exc_fb; - Word16 chk1, chk2; - chk1 = 0; - chk2 = 0; - move16(); - move16(); -#if 1 // def ADD_IVAS_TBE_CODE Word16 alpha, step, mem_csfilt_left, mem_csfilt_right, excNoisyEnvLeft[L_FRAME16k], excNoisyEnvRight[L_FRAME16k]; Word16 cbsize; Word16 mix_factor, old_fact, new_fact, fact, old_scale, new_scale, step_scale; @@ -3057,7 +2977,7 @@ void GenShapedSHBExcitation_ivas_enc_fx( mix_factor = 0; /* Q15 */ move16(); -#endif + set16_fx( zero_mem, 0, LPC_SHB_ORDER ); set16_fx( wht_fil_mem, 0, LPC_WHTN_ORDER ); FOR( i = 0; i < L_FRAME32k; i = i + 2 ) @@ -3089,11 +3009,7 @@ void GenShapedSHBExcitation_ivas_enc_fx( /* i: exc16k in Q_bwe_exc */ /* o: exc16kWhtnd in Q_bwe_exc */ -#if 1 // def ADD_IVAS_TBE_CODE IF( GE_32( extl_brate, SWB_TBE_2k8 ) ) -#else - IF( GE_32( bitrate, ACELP_24k40 ) ) -#endif { temp2 = 0; move16(); @@ -3114,33 +3030,21 @@ void GenShapedSHBExcitation_ivas_enc_fx( /* Estimate pow1 associated with Low band nonlinear extended excitation */ /* pow1=0.00001f */ tmp = sub( shl( *Q_bwe_exc, 1 ), 31 ); -#ifdef BASOP_NOGLOB - pow1 = L_shl_sat( 21475l /*0.00001f Q31*/, tmp ); /* 0.00001f in 2*(Q_bwe_exc) */ -#else - pow1 = L_shl( 21475l /*0.00001f Q31*/, tmp ); /* 0.00001f in 2*(Q_bwe_exc) */ -#endif + W_tmp = W_shl( 21475 /*0.00001f Q31*/, tmp ); /* 0.00001f in 2*(Q_bwe_exc) */ FOR( k = 0; k < L_FRAME16k; k++ ) { /*excTmp2[k ] = (float)(fabs(exc16kWhtnd[k]));*/ excTmp2[k] = abs_s( exc16kWhtnd[k] ); move16(); - chk1 = s_or( chk1, exc16kWhtnd[k] ); /* pow1 += exc16kWhtnd[k] * exc16kWhtnd[k]; */ -#ifdef BASOP_NOGLOB - pow1 = L_mac0_sat( pow1, exc16kWhtnd[k], exc16kWhtnd[k] ); /* 2*Q_bwe_exc */ -#else - pow1 = L_mac0( pow1, exc16kWhtnd[k], exc16kWhtnd[k] ); /* 2*Q_bwe_exc */ -#endif + W_tmp = W_mac_16_16( W_tmp, exc16kWhtnd[k], exc16kWhtnd[k] ); // 2*Q_bwe_exc+1 } - Q_pow1 = shl( *Q_bwe_exc, 1 ); + exp = W_norm( W_tmp ); + pow1 = W_extract_h( W_shl( W_tmp, exp ) ); // 2*Q_bwe_exc+1+exp-32 = // tmp+exp + Q_pow1 = add( tmp, exp ); - test(); -#if 1 // ADD_IVAS_TBE_CODE IF( flag_ACELP16k == 0 ) -#else - IF( ( LE_32( bitrate, ACELP_13k20 ) ) && ( GE_32( bitrate, ACELP_7k20 ) ) ) -#endif { /* varEnvShape = mean_fx(voice_factors, 4); */ /* unroll the loop */ @@ -3186,12 +3090,8 @@ void GenShapedSHBExcitation_ivas_enc_fx( test(); test(); test(); -#if 1 // def ADD_IVAS_TBE_CODE test(); IF( EQ_16( element_mode, EVS_MONO ) && *mem_csfilt == 0 && ( ( EQ_32( bitrate, ACELP_9k60 ) ) || ( EQ_32( bitrate, ACELP_16k40 ) ) || ( EQ_32( bitrate, ACELP_24k40 ) ) ) ) -#else - IF( *mem_csfilt == 0 && ( ( EQ_32( bitrate, ACELP_9k60 ) ) || ( EQ_32( bitrate, ACELP_16k40 ) ) || ( EQ_32( bitrate, ACELP_24k40 ) ) ) ) -#endif { /* pre-init smoothing filter to avoid energy drop outs */ L_tmp = L_mult( excTmp2[0], 1638 ); @@ -3218,7 +3118,7 @@ void GenShapedSHBExcitation_ivas_enc_fx( *mem_csfilt = Mult_32_16( L_tmp, varEnvShape ); move32(); } -#if 1 // def ADD_IVAS_TBE_CODE + IF( MSFlag > 0 ) { // varEnvShape = 0.995f; @@ -3232,7 +3132,6 @@ void GenShapedSHBExcitation_ivas_enc_fx( } White_exc16k = exc16k; - move16(); Word16 Q_excTmp2 = add( getScaleFactor16( excTmp2, L_FRAME16k ), *Q_bwe_exc ); IF( *mem_csfilt ) { @@ -3278,7 +3177,6 @@ void GenShapedSHBExcitation_ivas_enc_fx( } } ELSE -#endif { /* Track the low band envelope */ L_tmp = L_shl( *mem_csfilt, sub( Q_excTmp2, *Q_bwe_exc ) ); @@ -3304,19 +3202,19 @@ void GenShapedSHBExcitation_ivas_enc_fx( *mem_csfilt = L_shr( L_tmp, sub( Q_excTmp2, *Q_bwe_exc ) ); move32(); } -#if 1 // def ADD_IVAS_TBE_CODE + test(); IF( EQ_32( extl_brate, SWB_TBE_1k10 ) || EQ_32( extl_brate, SWB_TBE_1k75 ) ) { /* generate gaussian (white) excitation */ FOR( k = 0; k < L_FRAME16k; k++ ) { - White_exc16k[k] = own_random( &bwe_seed[0] ); + White_exc16k[k] = own_random( &bwe_seed[0] ); // Q0 move16(); } /* normalize the amplitude of the gaussian excitation to that of the LB exc. */ - Word32 pow22_inv = POW_EXC16k_WHTND_FX_INV_SQRT; + Word32 pow22_inv = POW_EXC16k_WHTND_FX_INV_SQRT; // Q31 move32(); move32(); pow22 = POW_EXC16k_WHTND_FX; @@ -3332,27 +3230,19 @@ void GenShapedSHBExcitation_ivas_enc_fx( // v_multc_fixed_16_16(White_exc16k, round_fx(temp_pow), White_exc16k, L_FRAME16k); L_tmp = 0; move32(); + Q_White_exc16k = add( getScaleFactor16( White_exc16k, L_FRAME16k ), norm_l( temp_pow ) ); FOR( k = 0; k < L_FRAME16k; k++ ) { - White_exc16k_32[k] = Mpy_32_16_1( temp_pow, White_exc16k[k] ); + White_exc16k_32[k] = Mpy_32_16_1( temp_pow, White_exc16k[k] ); // Q31 + Q0 - Q15 = Q16 move32(); - White_exc16k[k] = round_fx( L_shl( White_exc16k_32[k], sub( *Q_bwe_exc, NOISE_QADJ ) ) ); // Q_bwe_exc - NOISE_QADJ + White_exc16k[k] = round_fx( L_shl( White_exc16k_32[k], Q_White_exc16k ) ); // Q16 + Q_White_exc16k - Q16 = Q_White_exc16k move16(); L_tmp = L_max( L_tmp, L_abs( White_exc16k_32[k] ) ); } - Q_temp = norm_l( L_tmp ); - IF( L_tmp == 0 ) - { - Q_temp = 31; - move16(); - } } ELSE -#endif { /* create a random excitation - Reuse exc16k memory */ - White_exc16k = exc16k; - move16(); create_random_vector_fx( White_exc16k, L_FRAME, bwe_seed ); // Q5 create_random_vector_fx( White_exc16k + L_FRAME, L_FRAME16k - L_FRAME, bwe_seed ); // Q5 @@ -3365,50 +3255,38 @@ void GenShapedSHBExcitation_ivas_enc_fx( move32(); L_tmp = L_max( L_tmp, L_abs( White_exc16k_32[k] ) ); } - Q_temp = norm_l( L_tmp ); - IF( L_tmp == 0 ) - { - Q_temp = 31; - move16(); - } /*Copy_Scale_sig( White_exc16k, White_exc16k, L_FRAME16k, sub(NOISE_QFAC, 5) );)*/ /* White_exc16k in Q6 */ /* calculate pow22 */ /* pow22=0.00001f */ tmp = sub( shl( sub( *Q_bwe_exc, NOISE_QADJ ), 1 ), 31 ); - pow22 = L_shl( 21475l /*0.00001f Q31*/, tmp ); /* 0.00001f in 2*(*Q_bwe_exc-NOISE_QADJ) */ + W_tmp = W_shl( 21475l /*0.00001f Q31*/, tmp ); /* 0.00001f in 2*(*Q_bwe_exc-NOISE_QADJ) */ + Q_White_exc16k = getScaleFactor32( White_exc16k_32, L_FRAME16k ); FOR( k = 0; k < L_FRAME16k; k++ ) { /* White_exc16k[k] *= excNoisyEnv[k]; */ - White_exc16k[k] = mult_r( excNoisyEnv[k], shl( White_exc16k[k], 1 ) ); // Q_excTmp2 + 5 + 1 - 15 ==> Q_excTmp2 - 9 + White_exc16k[k] = extract_h( L_shl( White_exc16k_32[k], Q_White_exc16k ) ); // Q_excTmp2 + 6 + Q_White_exc16k - 16 ==> Q_excTmp2 + Q_White_exc16k - 10 move16(); - chk2 = s_or( chk2, White_exc16k[k] ); /* i: excNoisyEnv in (Q_excTmp2) */ /* i: White_exc16k in Q6 */ /* o: White_exc16k in (Q_bwe_exc-NOISE_QADJ) */ + /* pow22 += White_exc16k[k] * White_exc16k[k]; */ -#ifdef BASOP_NOGLOB - pow22 = L_mac0_sat( pow22, White_exc16k[k], White_exc16k[k] ); /* 2*(Q_excTmp2-NOISE_QADJ)*/ -#else - pow22 = L_mac0( pow22, White_exc16k[k], White_exc16k[k] ); /* 2*(Q_bwe_exc-NOISE_QADJ)*/ -#endif + W_tmp = W_mac0_16_16( W_tmp, White_exc16k[k], White_exc16k[k] ); /* 2*(Q_excTmp2 + Q_White_exc16k - 10)*/ } - /*Q_pow22 = sub( shl(*Q_bwe_exc,1), 18 );*/ - Q_pow22 = shl( sub( Q_excTmp2, NOISE_QADJ ), 1 ); - Scale_sig( White_exc16k, L_FRAME16k, sub( *Q_bwe_exc, Q_excTmp2 ) ); + Q_pow22 = W_norm( W_tmp ); + pow22 = W_extract_h( W_shl( W_tmp, Q_pow22 ) ); // 2*(Q_excTmp2 + Q_White_exc16k - 10)+Q_pow22-32 + Q_pow22 = sub( add( Q_pow22, shl( sub( add( Q_White_exc16k, Q_excTmp2 ), 10 ), 1 ) ), 32 ); + Q_White_exc16k = add( Q_White_exc16k, sub( Q_excTmp2, 10 ) ); } -#if 1 // def ADD_IVAS_TBE_CODE flag_plosive = 0; move16(); test(); test(); test(); IF( GE_32( extl_brate, SWB_TBE_2k8 ) || EQ_32( extl_brate, SWB_TBE_1k10 ) || EQ_32( extl_brate, SWB_TBE_1k75 ) ) -#else - IF( GE_32( bitrate, ACELP_24k40 ) ) -#endif { IF( EQ_16( *vf_ind, 20 ) ) /* encoder side */ { @@ -3418,7 +3296,7 @@ void GenShapedSHBExcitation_ivas_enc_fx( { FOR( k = 0; k < L_FRAME16k; k++ ) { - White_exc16k_tmp[k] = round_fx( L_shl( White_exc16k_32[k], *Q_bwe_exc ) ); + White_exc16k_tmp[k] = shl( White_exc16k[k], sub( *Q_bwe_exc, Q_White_exc16k ) ); move16(); } @@ -3444,8 +3322,8 @@ void GenShapedSHBExcitation_ivas_enc_fx( move32(); temp1 = add( shl( *Q_bwe_exc, 1 ), 1 ); - temp2 = add( add( Q_shb, *Q_bwe_exc ), 1 ); - temp3 = add( shl( Q_shb, 1 ), 1 ); + temp2 = add( add( Q_EnvSHBres_4k, *Q_bwe_exc ), 1 ); + temp3 = add( shl( Q_EnvSHBres_4k, 1 ), 1 ); FOR( i = 0; i < NUM_SHB_SUBGAINS; i++ ) { // c0_part[i] = sum2_f( &EnvExc16kWhtnd_4k[i * L_FRAME4k / NUM_SHB_SUBGAINS], L_FRAME4k / NUM_SHB_SUBGAINS ); @@ -3577,6 +3455,9 @@ void GenShapedSHBExcitation_ivas_enc_fx( { // g = 1.0f; g = MAX16B; /* Q15 */ + move16(); + g_e = 0; + move16(); } // else if ( g < shl( delta, ( 15 - g_e ) - 14 ) ) ELSE IF( BASOP_Util_Cmp_Mant32Exp( g, add( 16, g_e ), delta, 17 ) < 0 ) @@ -3584,8 +3465,12 @@ void GenShapedSHBExcitation_ivas_enc_fx( /* prevent low gains to be quantized to 0 as this is reserved for plosives */ // g = delta; g = shl( delta, 1 ); /* Q15 */ + g_e = 0; + move16(); } + g = shl_sat( g, g_e ); /* Q15 */ + *vf_ind = usquant_fx( g, &mix_factor, 0, delta, cbsize ); move16(); } @@ -3620,7 +3505,7 @@ void GenShapedSHBExcitation_ivas_enc_fx( #endif { Estimate_mix_factors_fx( shb_res, Q_shb, exc16kWhtnd, *Q_bwe_exc, White_exc16k, - ( *Q_bwe_exc - NOISE_QADJ ), pow1, Q_pow1, pow22, Q_pow22, voiceFacEst, vf_ind ); + Q_White_exc16k, pow1, Q_pow1, pow22, Q_pow22, voiceFacEst, vf_ind ); tmp = voiceFacEst[0]; tmp2 = MAX_16; move16(); @@ -3635,7 +3520,6 @@ void GenShapedSHBExcitation_ivas_enc_fx( ELSE /* decoder side */ { test(); -#if 1 // def ADD_IVAS_TBE_CODE IF( EQ_32( extl_brate, SWB_TBE_1k10 ) || EQ_32( extl_brate, SWB_TBE_1k75 ) ) { IF( *vf_ind == 0 ) @@ -3653,7 +3537,6 @@ void GenShapedSHBExcitation_ivas_enc_fx( } } ELSE -#endif { /* *vf_ind is an integer scale by 0.125f*/ tmp = shl( *vf_ind, ( 15 - 3 ) ); @@ -3666,10 +3549,9 @@ void GenShapedSHBExcitation_ivas_enc_fx( } } } -#if 1 // def ADD_IVAS_TBE_CODE + test(); IF( NE_32( extl_brate, SWB_TBE_1k10 ) && NE_32( extl_brate, SWB_TBE_1k75 ) ) -#endif { voice_factors[0] = mult_r( voice_factors[0], tmp2 ); move16(); @@ -3683,130 +3565,124 @@ void GenShapedSHBExcitation_ivas_enc_fx( move16(); } } -#if 1 // def ADD_IVAS_TBE_CODE + test(); IF( GE_16( element_mode, IVAS_CPE_DFT ) && nlExc16k != NULL ) { /* save buffers for IC-BWE */ // mvr2r(exc16kWhtnd, nlExc16k, L_FRAME16k); - Copy( exc16kWhtnd, nlExc16k, L_FRAME16k ); + Copy( exc16kWhtnd, nlExc16k, L_FRAME16k ); // Q_bwe_exc + *nlExc16k_e = sub( 15, *Q_bwe_exc ); + move16(); + // v_multc(White_exc16k, (float)sqrt(pow1 / pow22), mixExc16k, L_FRAME16k); - /*Word16 temp_fac = divide3232(L_shr(pow1, Q_pow1), pow22); - Word16 temp_fac_exp = 0; - temp_fac = Sqrt16(temp_fac, &temp_fac_exp);*/ L_tmp = root_a_over_b_fx( pow1, Q_pow1, pow22, Q_pow22, &exp ); - Word16 temp_fac = round_fx_sat( L_shl_sat( L_tmp, exp ) ); // Q15 - // v_multc_fixed_16_16(White_exc16k,shr(temp_fac, temp_fac_exp) , mixExc16k, L_FRAME16k); + Word16 temp_fac = round_fx_sat( L_tmp ); // Q15-exp + FOR( k = 0; k < L_FRAME16k; k++ ) { - mixExc16k[k] = mult_r( White_exc16k[k], temp_fac ); + mixExc16k[k] = mult_r( White_exc16k[k], temp_fac ); // Q_White_exc16k+15-exp-15 = Q_White_exc16k-exp move16(); } + *mixExc16k_e = sub( 15, sub( Q_White_exc16k, exp ) ); + move16(); } -#endif - tmp = sub( Q_temp, 3 ); - FOR( k = 0; k < L_FRAME16k; k++ ) - { - White_exc16k_FB[k] = White_exc16k[k]; /* Q_bwe_exc-NOISE_QADJ */ - } + Copy( White_exc16k, White_exc16k_FB, L_FRAME16k ); // Q_White_exc16k prev_Q_bwe_exc_fb = *Q_bwe_exc_fb; + *Q_bwe_exc_fb = Q_White_exc16k; move16(); - *Q_bwe_exc_fb = sub( *Q_bwe_exc, NOISE_QADJ ); move16(); - deemph_fx( White_exc16k, PREEMPH_FAC, L_FRAME16k, tbe_demph ); - /* i/o: White_exc16k (Q_bwe_exc-NOISE_QADJ) */ - /* i: tbe_demph (Q_bwe_exc-NOISE_QADJ) */ -#if 1 // def ADD_IVAS_TBE_CODE + Word16 tbe_demph_fx = shl_sat( *tbe_demph, sub( Q_White_exc16k, *Q_bwe_exc ) ); // Q_White_exc16k + + deemph_fx( White_exc16k, PREEMPH_FAC, L_FRAME16k, &tbe_demph_fx ); + /* i/o: White_exc16k (Q_White_exc16k) */ + /* i: tbe_demph_fx (Q_White_exc16k) */ + *tbe_demph = shr_sat( tbe_demph_fx, sub( Q_White_exc16k, *Q_bwe_exc ) ); + move16(); + test(); IF( EQ_32( extl_brate, SWB_TBE_1k10 ) || EQ_32( extl_brate, SWB_TBE_1k75 ) ) { IF( !flag_plosive ) /* use only LB excitation in case of plosives */ { /* re-scale gaussian excitation at the beginning to gradually move from old energy to new energy */ - // old_scale = (float)sqrt(*prev_pow_exc16kWhtnd / pow1); - // old_scale = divide3232(*prev_pow_exc16kWhtnd, pow1); // exp = Q15 - (Q_pow1) - // Word16 old_scale_exp = Q15 - (Q_pow1); - // old_scale = Sqrt16(old_scale, &old_scale_exp); - // old_scale = shl(old_scale, old_scale_exp); //Q15 - L_tmp = root_a_over_b_fx( *prev_pow_exc16kWhtnd, 0, pow1, Q_pow1, &exp ); - old_scale = round_fx_sat( L_shl_sat( L_tmp, exp ) ); // Q15 + /* old_scale = (float) sqrt( *prev_pow_exc16kWhtnd / pow1 ); */ + old_scale = round_fx_sat( root_a_over_b_fx( *prev_pow_exc16kWhtnd, 0, pow1, Q_pow1, &exp ) ); // exp + old_scale = shl( old_scale, s_min( 0, exp ) ); // limit Q factor to 15 + exp = s_max( 0, exp ); + // new_scale = 1.0f; - new_scale = 32767; - move16(); + new_scale = shr( 32767, exp ); // exp + // step_scale = (new_scale - old_scale) / (L_FRAME16k / 2); - step_scale = mult_r( sub( new_scale, old_scale ), 205 ); - scale = old_scale; + step_scale = mult_r( sub( new_scale, old_scale ), 205 ); // exp + scale = old_scale; // exp move16(); + /* interpolate between the old and the new value of the mixing factor */ - old_fact = *prev_mix_factor; + old_fact = *prev_mix_factor; // Q15 + new_fact = mix_factor; // Q15 move16(); - new_fact = mix_factor; move16(); + // step = (new_fact - old_fact) / (L_FRAME16k / 2); - step = mult_r( sub( new_fact, old_fact ), 205 ); - fact = old_fact; + step = mult_r( sub( new_fact, old_fact ), 205 ); // Q15 + fact = old_fact; // Q15 move16(); + + shift = add( exp, sub( *Q_bwe_exc, Q_White_exc16k ) ); + /* mixing of LB and gaussian excitation in the first half of the frame */ FOR( k = 0; k < L_FRAME16k / 2; k++ ) { - // exc16kWhtnd[k] = (float)fact * (White_exc16k[k] * scale) + (float)(1 - fact) * exc16kWhtnd[k]; - // exc16kWhtnd[k] = add(mult_r(fact, mult(shl(White_exc16k[k], *Q_bwe_exc), scale)), mult_r(sub(32767, fact), exc16kWhtnd[k])); - L_tmp = L_add( L_shl( L_mult( fact, mult_r( White_exc16k[k], scale ) ), NOISE_QADJ ), - L_mult( sub( 32767, fact ), exc16kWhtnd[k] ) ); // Q_bwe_exc - exc16kWhtnd[k] = round_fx( L_tmp ); + /* exc16kWhtnd[k] = (float)fact * (White_exc16k[k] * scale) + (float)(1 - fact) * exc16kWhtnd[k]; */ + L_tmp = L_shl_sat( L_mult( fact, mult_r( White_exc16k[k], scale ) ), shift ); // Q_bwe_exc+16 + exc16kWhtnd[k] = mac_r_sat( L_tmp, sub( 32767, fact ), exc16kWhtnd[k] ); // Q_bwe_exc move16(); - fact = add_sat( fact, step ); - scale = add_sat( scale, step_scale ); + + fact = add_sat( fact, step ); // Q15 + scale = add_sat( scale, step_scale ); // exp } + shift = sub( *Q_bwe_exc, Q_White_exc16k ); /* mixing of LB and gaussian excitation in the second half of the frame */ FOR( ; k < L_FRAME16k; k++ ) { // exc16kWhtnd[k] = (float)new_fact * White_exc16k[k] + (float)(1 - new_fact) * exc16kWhtnd[k]; - // exc16kWhtnd[k] = add(mult_r(new_fact, shl(White_exc16k[k], *Q_bwe_exc)), mult_r(sub(32767, new_fact), exc16kWhtnd[k])); - L_tmp = L_add( L_shl( L_mult( new_fact, White_exc16k[k] ), NOISE_QADJ ), - mult_r( sub( 32767, new_fact ), exc16kWhtnd[k] ) ); // Q_bwe_exc - exc16kWhtnd[k] = round_fx( L_tmp ); + L_tmp = L_shl_sat( L_mult( new_fact, White_exc16k[k] ), shift ); // Q_bwe_exc+16 + exc16kWhtnd[k] = mac_r( L_tmp, sub( 32767, new_fact ), exc16kWhtnd[k] ); // Q_bwe_exc move16(); } } // preemph(exc16kWhtnd, PREEMPH_FAC, L_FRAME16k, tbe_premph); - PREEMPH_FX( exc16kWhtnd, PREEMPH_FAC, L_FRAME16k, tbe_premph ); + PREEMPH_FX( exc16kWhtnd, PREEMPH_FAC, L_FRAME16k, tbe_premph ); // Q_bwe_exc } ELSE -#endif { -#if 1 // def ADD_IVAS_TBE_CODE test(); IF( EQ_16( coder_type, UNVOICED ) || EQ_16( MSFlag, 1 ) ) -#else - IF( EQ_16( coder_type, UNVOICED ) ) -#endif { - L_tmp = root_a_over_b_fx( pow1, Q_pow1, pow22, Q_pow22, &exp ); + scale = 0; + move16(); + test(); - if ( chk1 == 0 && chk2 == 0 ) + IF( pow1 != 0 && pow22 != 0 ) { - L_tmp = 0; - move32(); + L_tmp = root_a_over_b_fx( pow1, Q_pow1, pow22, Q_pow22, &exp ); + scale = round_fx_sat( L_shl_sat( L_tmp, exp ) ); /*Q15 */ } -#ifdef BASOP_NOGLOB - scale = round_fx_sat( L_shl_sat( L_tmp, exp ) ); /*Q15 */ -#else - scale = round_fx( L_shl( L_tmp, exp ) ); /*Q15 */ -#endif + FOR( k = 0; k < L_FRAME16k; k++ ) { - /* White_exc16k: (Q_bwe_exc-NOISE_QADJ), scale: Q15 */ - L_tmp = L_mult( White_exc16k[k], scale ); - /* L_tmp: (Q_bwe_exc-NOISE_QADJ) + 15 + 1 */ - exc16kWhtnd[k] = round_fx_sat( L_shl_sat( L_tmp, NOISE_QADJ ) ); + exc16kWhtnd[k] = mult_r_sat( White_exc16k[k], scale ); // Q_White_exc16k move16(); - /* exc16kWhtnd: Q_bwe_exc */ } - PREEMPH_FX( exc16kWhtnd, PREEMPH_FAC, L_FRAME16k, tbe_premph ); + + Scale_sig( exc16kWhtnd, L_FRAME16k, sub( *Q_bwe_exc, Q_White_exc16k ) ); // Q_bwe_exc + + PREEMPH_FX( exc16kWhtnd, PREEMPH_FAC, L_FRAME16k, tbe_premph ); // Q_bwe_exc /* i/o: exc16kWhtnd (Q_bwe_exc) */ /* i/o: tbe_premph (Q_bwe_exc) */ } @@ -3846,11 +3722,7 @@ void GenShapedSHBExcitation_ivas_enc_fx( temp = sub( MAX_16, temp ); tempQ31 = Mult_32_16( pow1, temp ); L_tmp = root_a_over_b_fx( tempQ31, Q_pow1, pow22, Q_pow22, &exp ); -#ifdef BASOP_NOGLOB temp2 = round_fx_sat( L_shl_sat( L_tmp, exp ) ); /* Q15 whiteEnvShapedExc scale factor */ -#else - temp2 = round_fx( L_shl( L_tmp, exp ) ); /* Q15 whiteEnvShapedExc scale factor */ -#endif } ELSE { @@ -3869,26 +3741,16 @@ void GenShapedSHBExcitation_ivas_enc_fx( temp = sub( MAX_16, vf_tmp ); tempQ31 = Mult_32_16( pow1, temp ); L_tmp = root_a_over_b_fx( tempQ31, Q_pow1, pow22, Q_pow22, &exp ); -#ifdef BASOP_NOGLOB temp2 = round_fx_sat( L_shl_sat( L_tmp, exp ) ); /* Q15 whiteEnvShapedExc scale factor */ -#else - temp2 = round_fx( L_shl( L_tmp, exp ) ); /* Q15 whiteEnvShapedExc scale factor */ -#endif } + shift = sub( *Q_bwe_exc, Q_White_exc16k ); FOR( j = 0; j < lSubFr; j++ ) { /*exc16kWhtnd[k+j] = temp1 * exc16kWhtnd[k+j] + temp2 * White_exc16k[k+j]; */ - L_tmp = L_mult( temp2, White_exc16k[k + j] ); /* 16+(Q_bwe_exc-NOISE_QADJ)*/ -#ifdef BASOP_NOGLOB - L_tmp = L_shl_sat( L_tmp, NOISE_QADJ ); /* 16+(Q_bwe_exc) */ - exc16kWhtnd[k + j] = mac_r_sat( L_tmp, temp1, exc16kWhtnd[k + j] ); -#else - L_tmp = L_shl( L_tmp, NOISE_QADJ ); /* 16+(Q_bwe_exc) */ - exc16kWhtnd[k + j] = mac_r( L_tmp, temp1, exc16kWhtnd[k + j] ); -#endif + L_tmp = L_shl_sat( L_mult( temp2, White_exc16k[k + j] ), shift ); // 16+(Q_bwe_exc) + exc16kWhtnd[k + j] = mac_r_sat( L_tmp, temp1, exc16kWhtnd[k + j] ); // Q_bwe_exc move16(); - /* Q_bwe_exc */ } k = add( k, lSubFr ); @@ -3903,18 +3765,14 @@ void GenShapedSHBExcitation_ivas_enc_fx( temp = div_s( temp, temp2 ); /* Q15 */ temp = mult_r( PREEMPH_FAC, temp ); - PREEMPH_FX( &exc16kWhtnd[i * lSubFr], temp, lSubFr, tbe_premph ); + PREEMPH_FX( &exc16kWhtnd[i * lSubFr], temp, lSubFr, tbe_premph ); // Q_bwe_exc /* exc16kWhtnd: Q_bwe_exc; tbe_premph: Q_bwe_exc*/ } } } -#if 1 // def ADD_IVAS_TBE_CODE IF( LT_32( extl_brate, SWB_TBE_2k8 ) ) -#else - IF( LT_32( bitrate, ACELP_24k40 ) ) -#endif { syn_filt_fx( 0, lpc_shb, LPC_SHB_ORDER, exc16kWhtnd, excSHB, L_FRAME16k, state_lpc_syn, 1 ); /* i: exc16kWhtnd in Q_bwe_exc */ @@ -4025,8 +3883,8 @@ void GenShapedSHBExcitation_ivas_enc_fx( Scale_sig( fb_state_lpc_syn, LPC_SHB_ORDER, tmp ); Scale_sig( fb_tbe_demph, 1, tmp ); syn_filt_fx( 0, lpc_shb, LPC_SHB_ORDER, White_exc16k_FB, White_exc16k_FB_temp, L_FRAME16k, fb_state_lpc_syn, 1 ); - /* i: White_exc16k_FB in (14-n2) */ - /* o: White_exc16k_FB_temp in (14-n2) */ + /* i: White_exc16k_FB in (Q_bwe_exc_fb) */ + /* o: White_exc16k_FB_temp in (Q_bwe_exc_fb) */ FOR( i = 0; i < 10; i++ ) { @@ -4048,10 +3906,11 @@ void GenShapedSHBExcitation_ivas_enc_fx( set16_fx( White_exc16k_FB, 0, L_FRAME16k ); } -#if 1 // def ADD_IVAS_TBE_CODE *prev_pow_exc16kWhtnd = L_shr_sat( pow1, Q_pow1 ); // power goes above MAX_32 *prev_mix_factor = mix_factor; -#endif + move32(); + move16(); + return; } @@ -4217,11 +4076,7 @@ void GenShapedSHBExcitation_ivas_dec_fx( /* Estimate pow1 associated with Low band nonlinear extended excitation */ /* pow1=0.00001f */ tmp = sub( shl( *Q_bwe_exc, 1 ), 31 ); -#ifdef BASOP_NOGLOB pow1 = L_shl_sat( 21475l /*0.00001f Q31*/, tmp ); /* 0.00001f in 2*(Q_bwe_exc) */ -#else - pow1 = L_shl( 21475l /*0.00001f Q31*/, tmp ); /* 0.00001f in 2*(Q_bwe_exc) */ -#endif FOR( k = 0; k < L_FRAME16k; k++ ) { /*excTmp2[k ] = (float)(fabs(exc16kWhtnd[k]));*/ @@ -4230,11 +4085,7 @@ void GenShapedSHBExcitation_ivas_dec_fx( chk1 = s_or( chk1, exc16kWhtnd[k] ); /* pow1 += exc16kWhtnd[k] * exc16kWhtnd[k]; */ -#ifdef BASOP_NOGLOB pow1 = L_mac0_sat( pow1, exc16kWhtnd[k], exc16kWhtnd[k] ); /* 2*Q_bwe_exc */ -#else - pow1 = L_mac0( pow1, exc16kWhtnd[k], exc16kWhtnd[k] ); /* 2*Q_bwe_exc */ -#endif } Q_pow1 = shl( *Q_bwe_exc, 1 ); @@ -4491,11 +4342,7 @@ void GenShapedSHBExcitation_ivas_dec_fx( /* i: White_exc16k in Q6 */ /* o: White_exc16k in (Q_bwe_exc-NOISE_QADJ) */ /* pow22 += White_exc16k[k] * White_exc16k[k]; */ -#ifdef BASOP_NOGLOB pow22 = L_mac0_sat( pow22, White_exc16k[k], White_exc16k[k] ); /* 2*(Q_excTmp2-NOISE_QADJ)*/ -#else - pow22 = L_mac0( pow22, White_exc16k[k], White_exc16k[k] ); /* 2*(Q_bwe_exc-NOISE_QADJ)*/ -#endif } /*Q_pow22 = sub( shl(*Q_bwe_exc,1), 18 );*/ Q_pow22 = shl( sub( Q_excTmp2, NOISE_QADJ ), 1 ); @@ -4895,11 +4742,7 @@ void GenShapedSHBExcitation_ivas_dec_fx( L_tmp = 0; move32(); } -#ifdef BASOP_NOGLOB scale = round_fx_sat( L_shl_sat( L_tmp, exp ) ); /*Q15 */ -#else - scale = round_fx( L_shl( L_tmp, exp ) ); /*Q15 */ -#endif FOR( k = 0; k < L_FRAME16k; k++ ) { /* White_exc16k: (Q_bwe_exc-NOISE_QADJ), scale: Q15 */ @@ -4949,11 +4792,7 @@ void GenShapedSHBExcitation_ivas_dec_fx( temp = sub( MAX_16, temp ); tempQ31 = Mult_32_16( pow1, temp ); L_tmp = root_a_over_b_fx( tempQ31, Q_pow1, pow22, Q_pow22, &exp ); -#ifdef BASOP_NOGLOB temp2 = round_fx_sat( L_shl_sat( L_tmp, exp ) ); /* Q15 whiteEnvShapedExc scale factor */ -#else - temp2 = round_fx( L_shl( L_tmp, exp ) ); /* Q15 whiteEnvShapedExc scale factor */ -#endif } ELSE { @@ -4972,24 +4811,15 @@ void GenShapedSHBExcitation_ivas_dec_fx( temp = sub( MAX_16, vf_tmp ); tempQ31 = Mult_32_16( pow1, temp ); L_tmp = root_a_over_b_fx( tempQ31, Q_pow1, pow22, Q_pow22, &exp ); -#ifdef BASOP_NOGLOB temp2 = round_fx_sat( L_shl_sat( L_tmp, exp ) ); /* Q15 whiteEnvShapedExc scale factor */ -#else - temp2 = round_fx( L_shl( L_tmp, exp ) ); /* Q15 whiteEnvShapedExc scale factor */ -#endif } FOR( j = 0; j < lSubFr; j++ ) { /*exc16kWhtnd[k+j] = temp1 * exc16kWhtnd[k+j] + temp2 * White_exc16k[k+j]; */ L_tmp = L_mult( temp2, White_exc16k[k + j] ); /* 16+(Q_bwe_exc-NOISE_QADJ)*/ -#ifdef BASOP_NOGLOB - L_tmp = L_shl_sat( L_tmp, NOISE_QADJ ); /* 16+(Q_bwe_exc) */ + L_tmp = L_shl_sat( L_tmp, NOISE_QADJ ); /* 16+(Q_bwe_exc) */ exc16kWhtnd[k + j] = mac_r_sat( L_tmp, temp1, exc16kWhtnd[k + j] ); -#else - L_tmp = L_shl( L_tmp, NOISE_QADJ ); /* 16+(Q_bwe_exc) */ - exc16kWhtnd[k + j] = mac_r( L_tmp, temp1, exc16kWhtnd[k + j] ); -#endif move16(); /* Q_bwe_exc */ } @@ -5675,42 +5505,27 @@ void ScaleShapedWB_fx( FOR( i = 0; i < l_shb_lahead; i++ ) { /* mod_syn in (16+Q_bwe_exc), frame_gain in Q18 */ - L_tmp = Mult_32_32( mod_syn[i], frame_gain ); /* L_tmp in (Q_bwe_exc+3) */ -#ifdef BASOP_NOGLOB + L_tmp = Mult_32_32( mod_syn[i], frame_gain ); /* L_tmp in (Q_bwe_exc+3) */ synSHB[i] = round_fx_sat( L_shl_sat( Mult_32_16( L_tmp, win[i] ), shift ) ); /* Qx */ move16(); synSHB[i] = add_sat( synSHB[i], overlap[i] ); move16(); /* Qx */ synSHB[i + l_shb_lahead] = round_fx_sat( L_shl_sat( L_tmp, shift ) ); /* Qx */ move16(); -#else - synSHB[i] = round_fx( L_shl( Mult_32_16( L_tmp, win[i] ), shift ) ); /* Qx */ - synSHB[i] = add( synSHB[i], overlap[i] ); - move16(); /* Qx */ - synSHB[i + l_shb_lahead] = round_fx( L_shl( L_tmp, shift ) ); /* Qx */ -#endif } FOR( ; i < l_frame; i++ ) { - L_tmp = Mult_32_32( mod_syn[i], frame_gain ); /* L_tmp in (Q_bwe_exc+3) */ -#ifdef BASOP_NOGLOB + L_tmp = Mult_32_32( mod_syn[i], frame_gain ); /* L_tmp in (Q_bwe_exc+3) */ synSHB[i] = round_fx_sat( L_shl_sat( L_tmp, shift ) ); /* Qx; */ -#else - synSHB[i] = round_fx( L_shl( L_tmp, shift ) ); /* Qx; */ -#endif move16(); } l_frame_tmp = add( l_frame, l_shb_lahead ); FOR( ; i < l_frame_tmp; i++ ) { - L_tmp = Mult_32_32( mod_syn[i], frame_gain ); /* (Q_bwe_exc+3) */ -#ifdef BASOP_NOGLOB + L_tmp = Mult_32_32( mod_syn[i], frame_gain ); /* (Q_bwe_exc+3) */ overlap[i - l_frame] = round_fx_sat( L_shl_sat( Mult_32_16( L_tmp, win[l_frame + l_shb_lahead - 1 - i] ), shift ) ); /* Qx */ -#else - overlap[i - l_frame] = round_fx( L_shl( Mult_32_16( L_tmp, win[l_frame + l_shb_lahead - 1 - i] ), shift ) ); /* Qx */ -#endif move16(); } @@ -5740,12 +5555,8 @@ static Word32 non_linearity_scaled_copy( { FOR( i = 0; i < j; i++ ) { -#ifdef BASOP_NOGLOB L_tmp = L_mult_sat( input[i], input[i] ); /* 2*Q_inp+1 */ -#else - L_tmp = L_mult( input[i], input[i] ); /* 2*Q_inp+1 */ -#endif - L_tmp = Mult_32_32( L_tmp, prev_scale ); /* 2*Q_inp */ + L_tmp = Mult_32_32( L_tmp, prev_scale ); /* 2*Q_inp */ output[i] = L_tmp; move32(); @@ -5754,12 +5565,8 @@ static Word32 non_linearity_scaled_copy( } FOR( ; i < length; i++ ) { -#ifdef BASOP_NOGLOB L_tmp = L_mult_sat( input[i], input[i] ); /* 2*Q_inp+1 */ -#else - L_tmp = L_mult( input[i], input[i] ); /* 2*Q_inp+1 */ -#endif - L_tmp = Mult_32_32( L_tmp, prev_scale ); /* 2*Q_inp */ + L_tmp = Mult_32_32( L_tmp, prev_scale ); /* 2*Q_inp */ output[i] = L_tmp; move32(); } @@ -5768,12 +5575,8 @@ static Word32 non_linearity_scaled_copy( { FOR( i = 0; i < j; i++ ) { -#ifdef BASOP_NOGLOB L_tmp = L_mult_sat( input[i], input[i] ); /* 2*Q_inp+1 */ -#else - L_tmp = L_mult( input[i], input[i] ); /* 2*Q_inp+1 */ -#endif - L_tmp = Mult_32_32( L_tmp, prev_scale ); /* 2*Q_inp */ + L_tmp = Mult_32_32( L_tmp, prev_scale ); /* 2*Q_inp */ if ( input[i] < 0 ) { @@ -5788,11 +5591,7 @@ static Word32 non_linearity_scaled_copy( FOR( ; i < length; i++ ) { -#ifdef BASOP_NOGLOB L_tmp = L_mult_sat( input[i], input[i] ); /* 2*Q_inp+1 */ -#else /* BASOP_NOGLOB */ - L_tmp = L_mult( input[i], input[i] ); /* 2*Q_inp+1 */ -#endif /* BASOP_NOGLOB */ L_tmp = Mult_32_32( L_tmp, prev_scale ); /* 2*Q_inp */ if ( input[i] < 0 ) @@ -5894,11 +5693,7 @@ static Word32 non_linearity_scaled_copy_ivas( FOR( ; i < length; i++ ) { -#ifdef BASOP_NOGLOB L_tmp = L_mult_sat( input[i], input[i] ); /* 2*Q_inp+1 */ -#else /* BASOP_NOGLOB */ - L_tmp = L_mult( input[i], input[i] ); /* 2*Q_inp+1 */ -#endif /* BASOP_NOGLOB */ L_tmp = Mult_32_32( L_tmp, prev_scale ); /* 2*Q_inp */ test(); test(); @@ -6075,20 +5870,12 @@ void non_linearity_fx( tmp = div_s( shl( 1, sub( 14, exp ) ), j ); /* Q(29-exp) */ /* (log2(scale / prev_scale))/length */ -#ifdef BASOP_NOGLOB L_tmp = L_shl_o( Mult_32_16( L_tmp, tmp ), sub( exp, 14 ), &Overflow ); /* Q(16+29-exp+1-16+exp-14)->Q16 */ -#else - L_tmp = L_shl( Mult_32_16( L_tmp, tmp ), sub( exp, 14 ) ); /* Q(16+29-exp+1-16+exp-14)->Q16 */ -#endif frac = L_Extract_lc( L_tmp, &exp ); /* Extract exponent of L_tmp */ tmp = extract_l( Pow2( 14, frac ) ); -#ifdef BASOP_NOGLOB scale_step = shl_o( tmp, exp, &Overflow ); /* Q14 */ -#else - scale_step = shl( tmp, exp ); /* Q14 */ -#endif } } @@ -6111,12 +5898,8 @@ void non_linearity_fx( IF( GT_16( max_val, shl( 1, Q_inp ) ) ) { exp = norm_s( max_val ); - tmp = div_s( shl( 1, sub( 14, exp ) ), max_val ); /* Q(29-exp-Q_inp) */ -#ifdef BASOP_NOGLOB + tmp = div_s( shl( 1, sub( 14, exp ) ), max_val ); /* Q(29-exp-Q_inp) */ scale = L_shl_o( L_mult( 21955 /* 0.67 in Q15 */, tmp ), add( exp, sub( Q_inp, 14 ) ), &Overflow ); /* Q31 */ -#else - scale = L_shl( L_mult( 21955, tmp ), add( exp, sub( Q_inp, 14 ) ) ); /* Q31 */ -#endif } ELSE { @@ -6165,20 +5948,12 @@ void non_linearity_fx( tmp = div_s( shl( 1, sub( 14, exp ) ), tmp ); /* Q(29-exp) */ /* (log2(scale / prev_scale))/length */ -#ifdef BASOP_NOGLOB L_tmp = L_shl_o( Mult_32_16( L_tmp, tmp ), sub( exp, 14 ), &Overflow ); /*Q(16+29-exp+1-16+exp-14)->Q16 */ -#else - L_tmp = L_shl( Mult_32_16( L_tmp, tmp ), sub( exp, 14 ) ); /*Q(16+29-exp+1-16+exp-14)->Q16 */ -#endif frac = L_Extract_lc( L_tmp, &exp ); /* Extract exponent of L_tmp */ tmp = extract_l( Pow2( 14, frac ) ); -#ifdef BASOP_NOGLOB scale_step = shl_o( tmp, exp, &Overflow ); /*Q14 */ -#else - scale_step = shl( tmp, exp ); /*Q14 */ -#endif } } @@ -6347,20 +6122,12 @@ void non_linearity_ivas_fx( tmp = div_s( shl( 1, sub( 14, exp ) ), j ); /* Q(29-exp) */ /* (log2(scale / prev_scale))/length */ -#ifdef BASOP_NOGLOB L_tmp = L_shl_o( Mult_32_16( L_tmp, tmp ), sub( exp, 14 ), &Overflow ); /* Q(16+29-exp+1-16+exp-14)->Q16 */ -#else - L_tmp = L_shl( Mult_32_16( L_tmp, tmp ), sub( exp, 14 ) ); /* Q(16+29-exp+1-16+exp-14)->Q16 */ -#endif frac = L_Extract_lc( L_tmp, &exp ); /* Extract exponent of L_tmp */ tmp = extract_l( Pow2( 14, frac ) ); -#ifdef BASOP_NOGLOB scale_step = shl_o( tmp, exp, &Overflow ); /* Q14 */ -#else - scale_step = shl( tmp, exp ); /* Q14 */ -#endif } } @@ -6383,12 +6150,8 @@ void non_linearity_ivas_fx( IF( GT_16( max_val, shl( 1, Q_inp ) ) ) { exp = norm_s( max_val ); - tmp = div_s( shl( 1, sub( 14, exp ) ), max_val ); /* Q(29-exp-Q_inp) */ -#ifdef BASOP_NOGLOB + tmp = div_s( shl( 1, sub( 14, exp ) ), max_val ); /* Q(29-exp-Q_inp) */ scale = L_shl_o( L_mult( 21955, tmp ), add( exp, sub( Q_inp, 14 ) ), &Overflow ); /* Q31 */ -#else - scale = L_shl( L_mult( 21955, tmp ), add( exp, sub( Q_inp, 14 ) ) ); /* Q31 */ -#endif } ELSE { @@ -6437,20 +6200,12 @@ void non_linearity_ivas_fx( tmp = div_s( shl( 1, sub( 14, exp ) ), tmp ); /* Q(29-exp) */ /* (log2(scale / prev_scale))/length */ -#ifdef BASOP_NOGLOB L_tmp = L_shl_o( Mult_32_16( L_tmp, tmp ), sub( exp, 14 ), &Overflow ); /*Q(16+29-exp+1-16+exp-14)->Q16 */ -#else - L_tmp = L_shl( Mult_32_16( L_tmp, tmp ), sub( exp, 14 ) ); /*Q(16+29-exp+1-16+exp-14)->Q16 */ -#endif frac = L_Extract_lc( L_tmp, &exp ); /* Extract exponent of L_tmp */ tmp = extract_l( Pow2( 14, frac ) ); -#ifdef BASOP_NOGLOB scale_step = shl_o( tmp, exp, &Overflow ); /*Q14 */ -#else - scale_step = shl( tmp, exp ); /*Q14 */ -#endif } } @@ -6728,7 +6483,6 @@ void elliptic_bpf_48k_generic_fx( FOR( i = 0; i < 4; i++ ) { memory_fx0[0][i] = extract_l( memory_fx2[0][i] ); -#ifdef BASOP_NOGLOB memory_fx[0][i] = shl_sat( memory_fx0[0][i], sub( *Q_input_fx, memory_fx_Q[0] ) ); memory2_fx[1][i] = L_shl_sat( memory_fx2[1][i], sub( add( *Q_input_fx, 11 ), memory_fx_Q[1] ) ); memory2_fx[2][i] = L_shl_sat( memory_fx2[2][i], sub( add( *Q_input_fx, 6 ), memory_fx_Q[2] ) ); @@ -6738,91 +6492,52 @@ void elliptic_bpf_48k_generic_fx( move32(); move32(); move32(); -#else - memory_fx[0][i] = shl( memory_fx0[0][i], sub( *Q_input_fx, memory_fx_Q[0] ) ); - memory2_fx[1][i] = L_shl( memory_fx2[1][i], sub( add( *Q_input_fx, 11 ), memory_fx_Q[1] ) ); - memory2_fx[2][i] = L_shl( memory_fx2[2][i], sub( add( *Q_input_fx, 6 ), memory_fx_Q[2] ) ); - memory2_fx[3][i] = L_shl( memory_fx2[3][i], sub( add( *Q_input_fx, 1 ), memory_fx_Q[3] ) ); -#endif } - L_tmpX = L_shr( L_mult( memory_fx[0][0], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( memory_fx[0][1], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( memory_fx[0][2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( memory_fx[0][3], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ -#ifdef BASOP_NOGLOB + L_tmpX = L_shr( L_mult( memory_fx[0][0], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( memory_fx[0][1], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( memory_fx[0][2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( memory_fx[0][3], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][3], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][1], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ L_tmp[0] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][0], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ move32(); -#else - L_tmpX = L_sub( L_tmpX, L_shl( Mult_32_16( memory2_fx[1][3], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub( L_tmpX, L_shl( Mult_32_16( memory2_fx[1][2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub( L_tmpX, L_shl( Mult_32_16( memory2_fx[1][1], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmp[0] = L_sub( L_tmpX, L_shl( Mult_32_16( memory2_fx[1][0], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - move32(); -#endif - L_tmpX = L_shr( L_mult( memory_fx[0][1], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( memory_fx[0][2], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( memory_fx[0][3], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[1], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ -#ifdef BASOP_NOGLOB + L_tmpX = L_shr( L_mult( memory_fx[0][1], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( memory_fx[0][2], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( memory_fx[0][3], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[1], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][3], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][2], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ L_tmp[1] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][1], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ move32(); -#else - L_tmpX = L_sub( L_tmpX, L_shl( Mult_32_16( L_tmp[0], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub( L_tmpX, L_shl( Mult_32_16( memory2_fx[1][3], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub( L_tmpX, L_shl( Mult_32_16( memory2_fx[1][2], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmp[1] = L_sub( L_tmpX, L_shl( Mult_32_16( memory2_fx[1][1], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - move32(); -#endif - L_tmpX = L_shr( L_mult( memory_fx[0][2], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( memory_fx[0][3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[2], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ -#ifdef BASOP_NOGLOB + L_tmpX = L_shr( L_mult( memory_fx[0][2], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( memory_fx[0][3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[2], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ L_tmp[2] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][2], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ move32(); -#else - L_tmpX = L_sub( L_tmpX, L_shl( Mult_32_16( L_tmp[1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub( L_tmpX, L_shl( Mult_32_16( L_tmp[0], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub( L_tmpX, L_shl( Mult_32_16( memory2_fx[1][3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmp[2] = L_sub( L_tmpX, L_shl( Mult_32_16( memory2_fx[1][2], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - move32(); -#endif - L_tmpX = L_shr( L_mult( memory_fx[0][3], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[1], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[2], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[3], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ -#ifdef BASOP_NOGLOB + L_tmpX = L_shr( L_mult( memory_fx[0][3], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[0], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[1], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[2], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ + L_tmpX = L_add( L_shr( L_mult( input_fx[3], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[2], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[1], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[0], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ L_tmp[3] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[1][3], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ move32(); -#else - L_tmpX = L_sub( L_tmpX, L_shl( Mult_32_16( L_tmp[2], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub( L_tmpX, L_shl( Mult_32_16( L_tmp[1], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_sub( L_tmpX, L_shl( Mult_32_16( L_tmp[0], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmp[3] = L_sub( L_tmpX, L_shl( Mult_32_16( memory2_fx[1][3], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - move32(); -#endif FOR( i = 4; i < L_FRAME48k; i++ ) { -#ifdef BASOP_NOGLOB L_tmpX = L_shr( L_mult( input_fx[i - 4], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ @@ -6833,18 +6548,6 @@ void elliptic_bpf_48k_generic_fx( L_tmpX = L_add_sat( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ L_tmp[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ move32(); -#else - L_tmpX = L_shr( L_mult( input_fx [[i - 4]], full_band_bpf_fx[0][4] ), 3 ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[i - 3], full_band_bpf_fx[0][3] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub( L_tmpX, L_shl( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[3][1] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[i - 2], full_band_bpf_fx[0][2] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub( L_tmpX, L_shl( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[3][2] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[i - 1], full_band_bpf_fx[0][1] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmpX = L_sub( L_tmpX, L_shl( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[3][3] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - L_tmpX = L_add( L_shr( L_mult( input_fx[i], full_band_bpf_fx[0][0] ), 3 ), L_tmpX ); /*Q_input_fx + 13 + 1 - 3*/ - L_tmp[i] = L_sub( L_tmpX, L_shl( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[3][4] ), 2 ) ); /*Q_input_fx + 11 + 13 -15 +2*/ - move32(); -#endif } memory_fx2[0][0] = input_fx[L_FRAME48k - 4]; @@ -6856,89 +6559,52 @@ void elliptic_bpf_48k_generic_fx( move32(); move32(); move32(); - L_tmpX = L_shr( Mult_32_16( memory2_fx[1][0], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_add( L_shr( Mult_32_16( memory2_fx[1][1], full_band_bpf_fx[1][3] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_add( L_shr( Mult_32_16( memory2_fx[1][2], full_band_bpf_fx[1][2] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_add( L_shr( Mult_32_16( memory2_fx[1][3], full_band_bpf_fx[1][1] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[0], full_band_bpf_fx[1][0] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ -#ifdef BASOP_NOGLOB + L_tmpX = L_shr( Mult_32_16( memory2_fx[1][0], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_add( L_shr( Mult_32_16( memory2_fx[1][1], full_band_bpf_fx[1][3] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_add( L_shr( Mult_32_16( memory2_fx[1][2], full_band_bpf_fx[1][2] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_add( L_shr( Mult_32_16( memory2_fx[1][3], full_band_bpf_fx[1][1] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[0], full_band_bpf_fx[1][0] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[2][3], full_band_bpf_fx[4][1] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[2][2], full_band_bpf_fx[4][2] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2*/ L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[2][1], full_band_bpf_fx[4][3] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2*/ L_tmp2[0] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[2][0], full_band_bpf_fx[4][4] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2*/ move32(); L_tmpMax = L_abs( L_tmp2[0] ); -#else - L_tmpX = L_sub( L_tmpX, L_shl( Mult_32_16( memory2_fx[2][3], full_band_bpf_fx[4][1] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - L_tmpX = L_sub( L_tmpX, L_shl( Mult_32_16( memory2_fx[2][2], full_band_bpf_fx[4][2] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2*/ - L_tmpX = L_sub( L_tmpX, L_shl( Mult_32_16( memory2_fx[2][1], full_band_bpf_fx[4][3] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2*/ - L_tmp2[0] = L_sub( L_tmpX, L_shl( Mult_32_16( memory2_fx[2][0], full_band_bpf_fx[4][4] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2*/ - move32(); - L_tmpMax = L_abs( L_tmp2[0] ); -#endif - L_tmpX = L_shr( Mult_32_16( memory2_fx[1][1], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_add( L_shr( Mult_32_16( memory2_fx[1][2], full_band_bpf_fx[1][3] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_add( L_shr( Mult_32_16( memory2_fx[1][3], full_band_bpf_fx[1][2] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[0], full_band_bpf_fx[1][1] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[1], full_band_bpf_fx[1][0] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ -#ifdef BASOP_NOGLOB + L_tmpX = L_shr( Mult_32_16( memory2_fx[1][1], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_add( L_shr( Mult_32_16( memory2_fx[1][2], full_band_bpf_fx[1][3] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_add( L_shr( Mult_32_16( memory2_fx[1][3], full_band_bpf_fx[1][2] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[0], full_band_bpf_fx[1][1] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[1], full_band_bpf_fx[1][0] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[0], full_band_bpf_fx[4][1] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[2][3], full_band_bpf_fx[4][2] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[2][2], full_band_bpf_fx[4][3] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ L_tmp2[1] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[2][1], full_band_bpf_fx[4][4] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ move32(); L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[1] ) ); -#else - L_tmpX = L_sub( L_tmpX, L_shl( Mult_32_16( L_tmp2[0], full_band_bpf_fx[4][1] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - L_tmpX = L_sub( L_tmpX, L_shl( Mult_32_16( memory2_fx[2][3], full_band_bpf_fx[4][2] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - L_tmpX = L_sub( L_tmpX, L_shl( Mult_32_16( memory2_fx[2][2], full_band_bpf_fx[4][3] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - L_tmp2[1] = L_sub( L_tmpX, L_shl( Mult_32_16( memory2_fx[2][1], full_band_bpf_fx[4][4] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - move32(); - L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[1] ) ); -#endif - L_tmpX = L_shr( Mult_32_16( memory2_fx[1][2], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_add( L_shr( Mult_32_16( memory2_fx[1][3], full_band_bpf_fx[1][3] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[0], full_band_bpf_fx[1][2] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[1], full_band_bpf_fx[1][1] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[2], full_band_bpf_fx[1][0] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ -#ifdef BASOP_NOGLOB + L_tmpX = L_shr( Mult_32_16( memory2_fx[1][2], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_add( L_shr( Mult_32_16( memory2_fx[1][3], full_band_bpf_fx[1][3] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[0], full_band_bpf_fx[1][2] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[1], full_band_bpf_fx[1][1] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[2], full_band_bpf_fx[1][0] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[1], full_band_bpf_fx[4][1] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[0], full_band_bpf_fx[4][2] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[2][3], full_band_bpf_fx[4][3] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ L_tmp2[2] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[2][2], full_band_bpf_fx[4][4] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ move32(); L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[2] ) ); -#else - L_tmpX = L_sub( L_tmpX, L_shl( Mult_32_16( L_tmp2[1], full_band_bpf_fx[4][1] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - L_tmpX = L_sub( L_tmpX, L_shl( Mult_32_16( L_tmp2[0], full_band_bpf_fx[4][2] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - L_tmpX = L_sub( L_tmpX, L_shl( Mult_32_16( memory2_fx[2][3], full_band_bpf_fx[4][3] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - L_tmp2[2] = L_sub( L_tmpX, L_shl( Mult_32_16( memory2_fx[2][2], full_band_bpf_fx[4][4] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - move32(); - L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[2] ) ); -#endif - L_tmpX = L_shr( Mult_32_16( memory2_fx[1][3], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[0], full_band_bpf_fx[1][3] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[1], full_band_bpf_fx[1][2] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[2], full_band_bpf_fx[1][1] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[3], full_band_bpf_fx[1][0] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ -#ifdef BASOP_NOGLOB + L_tmpX = L_shr( Mult_32_16( memory2_fx[1][3], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[0], full_band_bpf_fx[1][3] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[1], full_band_bpf_fx[1][2] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[2], full_band_bpf_fx[1][1] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ + L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[3], full_band_bpf_fx[1][0] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[2], full_band_bpf_fx[4][1] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[1], full_band_bpf_fx[4][2] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[0], full_band_bpf_fx[4][3] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ L_tmp2[3] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( memory2_fx[2][3], full_band_bpf_fx[4][4] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ /*14 + Q_input_fx - shift_flag*/ move32(); L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[3] ) ); -#else - L_tmpX = L_sub( L_tmpX, L_shl( Mult_32_16( L_tmp2[2], full_band_bpf_fx[4][1] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - L_tmpX = L_sub( L_tmpX, L_shl( Mult_32_16( L_tmp2[1], full_band_bpf_fx[4][2] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - L_tmpX = L_sub( L_tmpX, L_shl( Mult_32_16( L_tmp2[0], full_band_bpf_fx[4][3] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - L_tmp2[3] = L_sub( L_tmpX, L_shl( Mult_32_16( memory2_fx[2][3], full_band_bpf_fx[4][4] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ /*14 + Q_input_fx - shift_flag*/ - move32(); - L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[3] ) ); -#endif FOR( i = 4; i < L_FRAME48k; i++ ) { -#ifdef BASOP_NOGLOB L_tmpX = L_shr( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[1][3] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ L_tmpX = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[i - 1], full_band_bpf_fx[4][1] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ @@ -6949,18 +6615,6 @@ void elliptic_bpf_48k_generic_fx( L_tmpX = L_add_sat( L_shr( Mult_32_16( L_tmp[i], full_band_bpf_fx[1][0] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ L_tmp2[i] = L_sub_sat( L_tmpX, L_shl_sat( Mult_32_16( L_tmp2[i - 4], full_band_bpf_fx[4][4] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ move32(); -#else - L_tmpX = L_shr( Mult_32_16( L_tmp[i - 4], full_band_bpf_fx[1][4] ), 3 ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[i - 3], full_band_bpf_fx[1][3] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_sub( L_tmpX, L_shl( Mult_32_16( L_tmp2[i - 1], full_band_bpf_fx[4][1] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[i - 2], full_band_bpf_fx[1][2] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_sub( L_tmpX, L_shl( Mult_32_16( L_tmp2[i - 2], full_band_bpf_fx[4][2] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[i - 1], full_band_bpf_fx[1][1] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmpX = L_sub( L_tmpX, L_shl( Mult_32_16( L_tmp2[i - 3], full_band_bpf_fx[4][3] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - L_tmpX = L_add( L_shr( Mult_32_16( L_tmp[i], full_band_bpf_fx[1][0] ), 3 ), L_tmpX ); /*Q_input_fx + 11 + 13 - 15 -3*/ - L_tmp2[i] = L_sub( L_tmpX, L_shl( Mult_32_16( L_tmp2[i - 4], full_band_bpf_fx[4][4] ), 2 ) ); /*Q_input_fx + 6 +13 -15 +2 */ - move32(); -#endif L_tmpMax = L_max( L_tmpMax, L_abs( L_tmp2[i] ) ); } @@ -6979,18 +6633,12 @@ void elliptic_bpf_48k_generic_fx( move32(); FOR( j = 0; j < 4; j++ ) { -#ifdef BASOP_NOGLOB memory2_fx_2[j] = L_shl_sat( memory_fx2[2][j], sub( add( add( *Q_input_fx, 6 ), Q_temp ), memory_fx_Q[2] ) ); memory2_fx_3[j] = L_shl_sat( memory_fx2[3][j], sub( add( add( *Q_input_fx, 1 ), Q_temp ), memory_fx_Q[3] ) ); -#else - memory2_fx_2[j] = L_shl( memory_fx2[2][j], sub( add( add( *Q_input_fx, 6 ), Q_temp ), memory_fx_Q[2] ) ); - memory2_fx_3[j] = L_shl( memory_fx2[3][j], sub( add( add( *Q_input_fx, 1 ), Q_temp ), memory_fx_Q[3] ) ); -#endif move32(); move32(); move32(); } -#ifdef BASOP_NOGLOB L_tmpX = L_shr( Mult_32_16( memory2_fx_2[0], full_band_bpf_fx[2][4] ), 3 ); /* *Q_input_fx+6 +Q_temp +13 -15 -3 */ L_tmpX = L_add_sat( L_shr( Mult_32_16( memory2_fx_2[1], full_band_bpf_fx[2][3] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ L_tmpX = L_add_sat( L_shr( Mult_32_16( memory2_fx_2[2], full_band_bpf_fx[2][2] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ @@ -7056,73 +6704,6 @@ void elliptic_bpf_48k_generic_fx( move32(); L_tmpMax = L_max( L_tmpMax, L_abs( L_output[i] ) ); } -#else - L_tmpX = L_shr( Mult_32_16( memory2_fx_2[0], full_band_bpf_fx[2][4] ), 3 ); /* *Q_input_fx+6 +Q_temp +13 -15 -3 */ - L_tmpX = L_add( L_shr( Mult_32_16( memory2_fx_2[1], full_band_bpf_fx[2][3] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ - L_tmpX = L_add( L_shr( Mult_32_16( memory2_fx_2[2], full_band_bpf_fx[2][2] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ - L_tmpX = L_add( L_shr( Mult_32_16( memory2_fx_2[3], full_band_bpf_fx[2][1] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ - L_tmpX = L_add( L_shr( Mult_32_16( L_tmp2[0], full_band_bpf_fx[2][0] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ - L_tmpX = L_sub( L_tmpX, L_shl( Mult_32_16( memory2_fx_3[3], full_band_bpf_fx[5][1] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2 */ - L_tmpX = L_sub( L_tmpX, L_shl( Mult_32_16( memory2_fx_3[2], full_band_bpf_fx[5][2] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2 */ - L_tmpX = L_sub( L_tmpX, L_shl( Mult_32_16( memory2_fx_3[1], full_band_bpf_fx[5][3] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2 */ - L_output[0] = L_sub( L_tmpX, L_shl( Mult_32_16( memory2_fx_3[0], full_band_bpf_fx[5][4] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2 */ - move32(); - L_tmpMax = L_abs( L_output[0] ); - - L_tmpX = L_shr( Mult_32_16( memory2_fx_2[1], full_band_bpf_fx[2][4] ), 3 ); /*Q_input_fx + 6 +Q_temp +13 -15 -3 */ - L_tmpX = L_add( L_shr( Mult_32_16( memory2_fx_2[2], full_band_bpf_fx[2][3] ), 3 ), L_tmpX ); /*Q_input_fx +Q_temp+ 6 +13 -15 -3*/ - L_tmpX = L_add( L_shr( Mult_32_16( memory2_fx_2[3], full_band_bpf_fx[2][2] ), 3 ), L_tmpX ); /*Q_input_fx +Q_temp+ 6 +13 -15 -3*/ - L_tmpX = L_add( L_shr( Mult_32_16( L_tmp2[0], full_band_bpf_fx[2][1] ), 3 ), L_tmpX ); /*Q_input_fx +Q_temp+ 6 +13 -15 -3*/ - L_tmpX = L_add( L_shr( Mult_32_16( L_tmp2[1], full_band_bpf_fx[2][0] ), 3 ), L_tmpX ); /*Q_input_fx+Q_temp + 6 +13 -15 -3*/ - L_tmpX = L_sub( L_tmpX, L_shl( Mult_32_16( L_output[0], full_band_bpf_fx[5][1] ), 2 ) ); /*Q_input_fx + 1 +13 -15 + 2+Q_temp*/ - L_tmpX = L_sub( L_tmpX, L_shl( Mult_32_16( memory2_fx_3[3], full_band_bpf_fx[5][2] ), 2 ) ); /*Q_input_fx + 1 +13 -15 + 2+Q_temp*/ - L_tmpX = L_sub( L_tmpX, L_shl( Mult_32_16( memory2_fx_3[2], full_band_bpf_fx[5][3] ), 2 ) ); /*Q_input_fx + 1 +13 -15 + 2+Q_temp*/ - L_output[1] = L_sub( L_tmpX, L_shl( Mult_32_16( memory2_fx_3[1], full_band_bpf_fx[5][4] ), 2 ) ); /*Q_input_fx + 1 +13 -15 + 2+Q_temp*/ - move32(); - L_tmpMax = L_max( L_tmpMax, L_abs( L_output[1] ) ); - - L_tmpX = L_shr( Mult_32_16( memory2_fx_2[2], full_band_bpf_fx[2][4] ), 3 ); /*Q_input_fx + 6 +Q_temp+13 -15 -3 */ - L_tmpX = L_add( L_shr( Mult_32_16( memory2_fx_2[3], full_band_bpf_fx[2][3] ), 3 ), L_tmpX ); /*Q_input_fx +Q_temp+ 6 +13 -15 -3*/ - L_tmpX = L_add( L_shr( Mult_32_16( L_tmp2[0], full_band_bpf_fx[2][2] ), 3 ), L_tmpX ); /*Q_input_fx +Q_temp+ 6 +13 -15 -3*/ - L_tmpX = L_add( L_shr( Mult_32_16( L_tmp2[1], full_band_bpf_fx[2][1] ), 3 ), L_tmpX ); /*Q_input_fx +Q_temp + 6 +13 -15 -3*/ - L_tmpX = L_add( L_shr( Mult_32_16( L_tmp2[2], full_band_bpf_fx[2][0] ), 3 ), L_tmpX ); /*Q_input_fx +Q_temp + 6 +13 -15 -3*/ - L_tmpX = L_sub( L_tmpX, L_shl( Mult_32_16( L_output[1], full_band_bpf_fx[5][1] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ - L_tmpX = L_sub( L_tmpX, L_shl( Mult_32_16( L_output[0], full_band_bpf_fx[5][2] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ - L_tmpX = L_sub( L_tmpX, L_shl( Mult_32_16( memory2_fx_3[3], full_band_bpf_fx[5][3] ), 2 ) ); /*Q_input_fx + 1+Q_temp +13 -15 + 2*/ - L_output[2] = L_sub( L_tmpX, L_shl( Mult_32_16( memory2_fx_3[2], full_band_bpf_fx[5][4] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ - move32(); - L_tmpMax = L_max( L_tmpMax, L_abs( L_output[2] ) ); - - L_tmpX = L_shr( Mult_32_16( memory2_fx_2[3], full_band_bpf_fx[2][4] ), 3 ); /*Q_input_fx + 6 +Q_temp +13 -15 -3 */ - L_tmpX = L_add( L_shr( Mult_32_16( L_tmp2[0], full_band_bpf_fx[2][3] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ - L_tmpX = L_add( L_shr( Mult_32_16( L_tmp2[1], full_band_bpf_fx[2][2] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ - L_tmpX = L_add( L_shr( Mult_32_16( L_tmp2[2], full_band_bpf_fx[2][1] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ - L_tmpX = L_add( L_shr( Mult_32_16( L_tmp2[3], full_band_bpf_fx[2][0] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ - L_tmpX = L_sub( L_tmpX, L_shl( Mult_32_16( L_output[2], full_band_bpf_fx[5][1] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ - L_tmpX = L_sub( L_tmpX, L_shl( Mult_32_16( L_output[1], full_band_bpf_fx[5][2] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ - L_tmpX = L_sub( L_tmpX, L_shl( Mult_32_16( L_output[0], full_band_bpf_fx[5][3] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ - L_output[3] = L_sub( L_tmpX, L_shl( Mult_32_16( memory2_fx_3[3], full_band_bpf_fx[5][4] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ - move32(); - L_tmpMax = L_max( L_tmpMax, L_abs( L_output[3] ) ); - - FOR( i = 4; i < L_FRAME48k; i++ ) - { - L_tmpX = L_shr( Mult_32_16( L_tmp2[i - 4], full_band_bpf_fx[2][4] ), 3 ); /*Q_input_fx + 6 +Q_temp+13 -15 -3 */ - L_tmpX = L_add( L_shr( Mult_32_16( L_tmp2[i - 3], full_band_bpf_fx[2][3] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp +13 -15 -3*/ - L_tmpX = L_sub( L_tmpX, L_shl( Mult_32_16( L_output[i - 1], full_band_bpf_fx[5][1] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ - - L_tmpX = L_add( L_shr( Mult_32_16( L_tmp2[i - 2], full_band_bpf_fx[2][2] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp+13 -15 -3*/ - L_tmpX = L_sub( L_tmpX, L_shl( Mult_32_16( L_output[i - 2], full_band_bpf_fx[5][2] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ - - L_tmpX = L_add( L_shr( Mult_32_16( L_tmp2[i - 1], full_band_bpf_fx[2][1] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp +13 -15 -3*/ - L_tmpX = L_sub( L_tmpX, L_shl( Mult_32_16( L_output[i - 3], full_band_bpf_fx[5][3] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ - - L_tmpX = L_add( L_shr( Mult_32_16( L_tmp2[i], full_band_bpf_fx[2][0] ), 3 ), L_tmpX ); /*Q_input_fx + 6 +Q_temp +13 -15 -3*/ - L_output[i] = L_sub( L_tmpX, L_shl( Mult_32_16( L_output[i - 4], full_band_bpf_fx[5][4] ), 2 ) ); /*Q_input_fx + 1 +Q_temp+13 -15 + 2*/ - move32(); - L_tmpMax = L_max( L_tmpMax, L_abs( L_output[i] ) ); - } -#endif memory_fx2[2][0] = L_tmp2[L_FRAME48k - 4]; memory_fx2[2][1] = L_tmp2[L_FRAME48k - 3]; memory_fx2[2][2] = L_tmp2[L_FRAME48k - 2]; @@ -7268,21 +6849,13 @@ void synthesise_fb_high_band_fx( L_tmp = Mult_32_16( ratio2, tmp[i] ); /* Q(16-exp+exp_tmp-15 = 1-exp+exp_tmp) */ IF( L_tmp < 0 ) { -#ifdef BASOP_NOGLOB output[i] = negate( extract_h( L_shl_sat( L_negate( L_tmp ), tmp3 ) ) ); /*Qout*/ move16(); -#else - output[i] = negate( extract_h( L_shl( L_negate( L_tmp ), tmp3 ) ) ); /*Qout*/ -#endif } ELSE { -#ifdef BASOP_NOGLOB output[i] = extract_h( L_shl_sat( L_tmp, tmp3 ) ); /*Qout*/ move16(); -#else - output[i] = extract_h( L_shl( L_tmp, tmp3 ) ); /*Qout*/ -#endif } } return; @@ -7351,20 +6924,12 @@ void Estimate_mix_factors_fx( shb_res_local[i] = round_fx( L_tmp2 ); move16(); /* temp_numer1[i] = sub(shb_res_local[i], WN_exc_local[i]); */ -#ifdef BASOP_NOGLOB temp_numer1[i] = round_fx_sat( L_sub_sat( L_shl_sat( L_tmp2, sc2 ), L_shl_sat( L_tmp1, sc1 ) ) ); -#else - temp_numer1[i] = round_fx( L_sub( L_shl( L_tmp2, sc2 ), L_shl( L_tmp1, sc1 ) ) ); -#endif move16(); /* (Q_bwe_exc) */ /* temp_numer2[i] = sub(exc16kWhtnd[i], WN_exc_local[i]); */ -#ifdef BASOP_NOGLOB temp_numer2[i] = sub_sat( exc16kWhtnd[i], round_fx_sat( L_shl_sat( L_tmp1, sc1 ) ) ); -#else - temp_numer2[i] = sub( exc16kWhtnd[i], round_fx( L_shl( L_tmp1, sc1 ) ) ); -#endif move16(); /* (Q_bwe_exc) */ } @@ -7384,11 +6949,7 @@ void Estimate_mix_factors_fx( expa = sub( 30, expa ); expb = norm_l( temp_p1_p2 ); -#ifdef BASOP_NOGLOB fracb = round_fx_o( L_shl_o( temp_p1_p2, expb, &Overflow ), &Overflow ); -#else - fracb = round_fx( L_shl( temp_p1_p2, expb ) ); -#endif expb = sub( 30, expb ); num_flag = 0; @@ -7415,11 +6976,7 @@ void Estimate_mix_factors_fx( tmp = div_s( fracb, fraca ); exp1 = sub( expb, expa ); -#ifdef BASOP_NOGLOB tmp = shl_sat( tmp, exp1 ); -#else - tmp = shl( tmp, exp1 ); -#endif if ( NE_16( num_flag, den_flag ) ) { tmp = negate( tmp ); @@ -7590,11 +7147,7 @@ void prep_tbe_exc_fx( tmp = MAX_16; move16(); -#ifdef BASOP_NOGLOB pitch = shl_o( add( shl_o( T0, 2, &Overflow ), T0_frac ), 5, &Overflow ); /* Q7 */ -#else /* BASOP_NOGLOB */ - pitch = shl( add( shl( T0, 2 ), T0_frac ), 5 ); /* Q7 */ -#endif /* BASOP_NOGLOB */ test(); test(); @@ -7621,29 +7174,15 @@ void prep_tbe_exc_fx( #endif IF( EQ_16( L_frame_fx, L_FRAME ) ) { - interp_code_5over2_fx( code_fx, tmp_code_fx, L_subfr ); /* code: Q9, tmp_code: Q9 */ -#ifdef BASOP_NOGLOB + interp_code_5over2_fx( code_fx, tmp_code_fx, L_subfr ); /* code: Q9, tmp_code: Q9 */ gain_code16 = round_fx_o( L_shl_o( gain_code_fx, Q_exc, &Overflow ), &Overflow ); /*Q_exc */ -#else - gain_code16 = round_fx( L_shl( gain_code_fx, Q_exc ) ); /*Q_exc */ -#endif FOR( i = 0; i < L_subfr * HIBND_ACB_L_FAC; i++ ) { - L_tmp = L_mult( gain_code16, tmp_code_fx[i] ); /* Q9 + Q_exc + 1*/ -#ifdef BASOP_NOGLOB + L_tmp = L_mult( gain_code16, tmp_code_fx[i] ); /* Q9 + Q_exc + 1*/ L_tmp = L_shl_sat( L_tmp, 5 ); /* Q9 + Q_exc + Q6*/ L_tmp = L_mac_sat( L_tmp, gain_pit_fx, bwe_exc_fx[i + i_subfr_fx * HIBND_ACB_L_FAC] ); /*Q15+Q_exc */ -#else - L_tmp = L_shl( L_tmp, 5 ); /* Q9 + Q_exc + Q6*/ - L_tmp = L_mac( L_tmp, gain_pit_fx, bwe_exc_fx[i + i_subfr_fx * HIBND_ACB_L_FAC] ); /*Q15+Q_exc */ -#endif -#ifdef BASOP_NOGLOB - L_tmp = L_shl_o( L_tmp, 1, &Overflow ); /*16+Q_exc */ /* saturation can occur here */ - bwe_exc_fx[i + i_subfr_fx * HIBND_ACB_L_FAC] = round_fx_o( L_tmp, &Overflow ); /*Q_exc */ -#else /* BASOP_NOGLOB */ - L_tmp = L_shl( L_tmp, 1 ); /*16+Q_exc */ /* saturation can occur here */ - bwe_exc_fx[i + i_subfr_fx * HIBND_ACB_L_FAC] = round_fx( L_tmp ); /*Q_exc */ -#endif /* BASOP_NOGLOB */ + L_tmp = L_shl_o( L_tmp, 1, &Overflow ); /*16+Q_exc */ /* saturation can occur here */ + bwe_exc_fx[i + i_subfr_fx * HIBND_ACB_L_FAC] = round_fx_o( L_tmp, &Overflow ); /*Q_exc */ move16(); } } @@ -7657,18 +7196,11 @@ void prep_tbe_exc_fx( Ltemp1 = Mult_32_16( gain_code_fx, code_fx[i] ); /* Q16 + Q9 + 1 - 16 = Q10 */ Ltemp2 = L_mult( gain_preQ_fx, code_preQ_fx[i] ); /*Q2 * Q10 -> Q12 */ -#ifdef BASOP_NOGLOB Ltemp1 = L_shl_o( Ltemp1, add( Q_exc, 6 ) /*Q_exc+16-19*/, &Overflow ); /*Q_exc+16 */ Ltemp2 = L_shl_o( Ltemp2, add( Q_exc, 4 ) /*Q_exc+16-13*/, &Overflow ); /*Q_exc+16 */ tmp_code_preInt_fx[i] = round_fx_o( L_add_o( Ltemp1, Ltemp2, &Overflow ), &Overflow ); /* Q_exc */ move16(); -#else /* BASOP_NOGLOB */ - Ltemp1 = L_shl( Ltemp1, Q_exc + 6 /*Q_exc+16-19*/ ); /*Q_exc+16 */ - Ltemp2 = L_shl( Ltemp2, Q_exc + 4 /*Q_exc+16-13*/ ); /*Q_exc+16 */ - - tmp_code_preInt_fx[i] = round_fx( L_add( Ltemp1, Ltemp2 ) ); /* Q_exc */ -#endif /* BASOP_NOGLOB */ } } ELSE @@ -7676,31 +7208,20 @@ void prep_tbe_exc_fx( FOR( i = 0; i < L_subfr; i++ ) { /*code in the encoder is Q9 and there is no <<1 with Mult_32_16 Q16 * Q9 -> Q9 */ - Ltemp1 = Mult_32_16( gain_code_fx, code_fx[i] ); /* Q16 + Q9 + 1 - 16 = Q10 */ -#ifdef BASOP_NOGLOB + Ltemp1 = Mult_32_16( gain_code_fx, code_fx[i] ); /* Q16 + Q9 + 1 - 16 = Q10 */ Ltemp1 = L_shl_o( Ltemp1, add( Q_exc, 6 ) /*Q_exc+16-19*/, &Overflow ); /*Q_exc+16 */ tmp_code_preInt_fx[i] = round_fx_o( Ltemp1, &Overflow ); /* Q_exc */ move16(); -#else - Ltemp1 = L_shl( Ltemp1, Q_exc + 6 /*Q_exc+16-19*/ ); /*Q_exc+16 */ - tmp_code_preInt_fx[i] = round_fx( Ltemp1 ); /* Q_exc */ -#endif } } interp_code_4over2_fx( tmp_code_preInt_fx, tmp_code_fx, L_subfr ); /* o: tmp_code in Q_exc */ FOR( i = 0; i < L_subfr * 2; i++ ) { - L_tmp = L_mult( gain_pit_fx, bwe_exc_fx[i + i_subfr_fx * 2] ); /*Q14+Q_exc+1 */ -#ifdef BASOP_NOGLOB + L_tmp = L_mult( gain_pit_fx, bwe_exc_fx[i + i_subfr_fx * 2] ); /*Q14+Q_exc+1 */ tmp = round_fx_o( L_shl_o( L_tmp, 1 /* (Q_exc+16)-(14+Q_exc+1)*/, &Overflow ), &Overflow ); /* tmp in Q_exc */ bwe_exc_fx[i + i_subfr_fx * 2] = add_o( tmp, tmp_code_fx[i], &Overflow ); /*Q_exc */ move16(); -#else /* BASOP_NOGLOB */ - tmp = round_fx( L_shl( L_tmp, 1 /* (Q_exc+16)-(14+Q_exc+1)*/ ) ); /* tmp in Q_exc */ - bwe_exc_fx[i + i_subfr_fx * 2] = add( tmp, tmp_code_fx[i] ); /*Q_exc */ - move16(); -#endif } } @@ -7792,11 +7313,7 @@ void prep_tbe_exc_ivas_fx( tmp = MAX_16; move16(); -#ifdef BASOP_NOGLOB pitch = shl_o( add( shl_o( T0, 2, &Overflow ), T0_frac ), 5, &Overflow ); /* Q7 */ -#else /* BASOP_NOGLOB */ - pitch = shl( add( shl( T0, 2 ), T0_frac ), 5 ); /* Q7 */ -#endif /* BASOP_NOGLOB */ test(); test(); @@ -7826,37 +7343,22 @@ void prep_tbe_exc_ivas_fx( #endif IF( EQ_16( L_frame_fx, L_FRAME ) ) { - interp_code_5over2_fx( code_fx, tmp_code_fx, L_subfr ); /* code: Q9, tmp_code: Q9 */ -#ifdef BASOP_NOGLOB + interp_code_5over2_fx( code_fx, tmp_code_fx, L_subfr ); /* code: Q9, tmp_code: Q9 */ gain_code16 = round_fx_o( L_shl_o( gain_code_fx, Q_exc, &Overflow ), &Overflow ); /*Q_exc */ -#else - gain_code16 = round_fx( L_shl( gain_code_fx, Q_exc ) ); /*Q_exc */ -#endif FOR( i = 0; i < L_subfr * HIBND_ACB_L_FAC; i++ ) { - L_tmp = L_mult( gain_code16, tmp_code_fx[i] ); /* Q9 + Q_exc + 1*/ - L_tmp = L_shl( L_tmp, 5 ); /* Q9 + Q_exc + Q6*/ -#ifdef BASOP_NOGLOB + L_tmp = L_mult( gain_code16, tmp_code_fx[i] ); /* Q9 + Q_exc + 1*/ + L_tmp = L_shl( L_tmp, 5 ); /* Q9 + Q_exc + Q6*/ L_tmp = L_mac_o( L_tmp, gain_pit_fx, bwe_exc_fx[i + i_subfr_fx * HIBND_ACB_L_FAC], &Overflow ); /*Q15+Q_exc */ L_tmp = L_shl_o( L_tmp, 1, &Overflow ); /*16+Q_exc */ /* saturation can occur here */ bwe_exc_fx[i + i_subfr_fx * HIBND_ACB_L_FAC] = round_fx_o( L_tmp, &Overflow ); /*Q_exc */ -#else /* BASOP_NOGLOB */ - L_tmp = L_mac( L_tmp, gain_pit_fx, bwe_exc_fx[i + i_subfr_fx * HIBND_ACB_L_FAC] ); /*Q15+Q_exc */ - L_tmp = L_shl( L_tmp, 1 ); /*16+Q_exc */ /* saturation can occur here */ - bwe_exc_fx[i + i_subfr_fx * HIBND_ACB_L_FAC] = round_fx( L_tmp ); /*Q_exc */ -#endif /* BASOP_NOGLOB */ move16(); } } ELSE { - Word16 shift = 8; + Word16 shift = 4; move16(); - if ( element_mode == EVS_MONO ) - { - shift = 4; - move16(); - } IF( gain_preQ_fx != 0 ) { FOR( i = 0; i < L_subfr; i++ ) @@ -7865,17 +7367,10 @@ void prep_tbe_exc_ivas_fx( Ltemp1 = Mult_32_16( gain_code_fx, code_fx[i] ); /* Q16 + Q9 + 1 - 16 = Q10 */ Ltemp2 = L_mult( gain_preQ_fx, code_preQ_fx[i] ); /*Q2 * Q10 -> Q12 */ -#ifdef BASOP_NOGLOB Ltemp1 = L_shl_o( Ltemp1, add( Q_exc, 6 ) /*Q_exc+16-19*/, &Overflow ); /*Q_exc+16 */ Ltemp2 = L_shl_o( Ltemp2, add( Q_exc, shift ) /*Q_exc+ 2 + 6 (or) 10 - 13*/, &Overflow ); /*Q_exc+16 */ tmp_code_preInt_fx[i] = round_fx_o( L_add_o( Ltemp1, Ltemp2, &Overflow ), &Overflow ); /* Q_exc */ -#else /* BASOP_NOGLOB */ - Ltemp1 = L_shl( Ltemp1, Q_exc + 6 /*Q_exc+16-19*/ ); /*Q_exc+16 */ - Ltemp2 = L_shl( Ltemp2, Q_exc + 4 /*Q_exc+16-13*/ ); /*Q_exc+16 */ - - tmp_code_preInt_fx[i] = round_fx( L_add( Ltemp1, Ltemp2 ) ); /* Q_exc */ -#endif /* BASOP_NOGLOB */ move16(); } } @@ -7884,14 +7379,9 @@ void prep_tbe_exc_ivas_fx( FOR( i = 0; i < L_subfr; i++ ) { /*code in the encoder is Q9 and there is no <<1 with Mult_32_16 Q16 * Q9 -> Q9 */ - Ltemp1 = Mult_32_16( gain_code_fx, code_fx[i] ); /* Q16 + Q9 + 1 - 16 = Q10 */ -#ifdef BASOP_NOGLOB + Ltemp1 = Mult_32_16( gain_code_fx, code_fx[i] ); /* Q16 + Q9 + 1 - 16 = Q10 */ Ltemp1 = L_shl_o( Ltemp1, add( Q_exc, 6 ) /*Q_exc+16-19*/, &Overflow ); /*Q_exc+16 */ tmp_code_preInt_fx[i] = round_fx_o( Ltemp1, &Overflow ); /* Q_exc */ -#else - Ltemp1 = L_shl( Ltemp1, Q_exc + 6 /*Q_exc+16-19*/ ); /*Q_exc+16 */ - tmp_code_preInt_fx[i] = round_fx( Ltemp1 ); /* Q_exc */ -#endif move16(); } } @@ -7899,16 +7389,10 @@ void prep_tbe_exc_ivas_fx( interp_code_4over2_fx( tmp_code_preInt_fx, tmp_code_fx, L_subfr ); /* o: tmp_code in Q_exc */ FOR( i = 0; i < shl( L_subfr, 1 ); i++ ) { - L_tmp = L_mult( gain_pit_fx, bwe_exc_fx[i + shl( i_subfr_fx, 1 )] ); /*Q14+Q_exc+1 */ -#ifdef BASOP_NOGLOB + L_tmp = L_mult( gain_pit_fx, bwe_exc_fx[i + shl( i_subfr_fx, 1 )] ); /*Q14+Q_exc+1 */ tmp = round_fx_o( L_shl_o( L_tmp, 1 /* (Q_exc+16)-(14+Q_exc+1)*/, &Overflow ), &Overflow ); /* tmp in Q_exc */ bwe_exc_fx[i + shl( i_subfr_fx, 1 )] = add_o( tmp, tmp_code_fx[i], &Overflow ); /*Q_exc */ move16(); -#else /* BASOP_NOGLOB */ - tmp = round_fx( L_shl( L_tmp, 1 /* (Q_exc+16)-(14+Q_exc+1)*/ ) ); /* tmp in Q_exc */ - bwe_exc_fx[i + i_subfr_fx * 2] = add( tmp, tmp_code_fx[i] ); /*Q_exc */ - move16(); -#endif } } @@ -7971,11 +7455,7 @@ Word16 swb_formant_fac_fx( /* o : Formant filter strength /* formant_fac = 1.0f - 0.5f*formant_fac */ tmp = mult_r( 16384, formant_fac ); /* 0.5 in Q15 */ -#ifdef BASOP_NOGLOB formant_fac = shl_o( sub( 4096 /* 1 in Q12 */, tmp ), 3, &Overflow ); -#else - formant_fac = shl( sub( 4096, tmp ), 3 ); -#endif return formant_fac; /*Q15 */ } diff --git a/lib_com/syn_filt_fx.c b/lib_com/syn_filt_fx.c index 082ccb4c85e44f7bd5bb9fc5550641489e1aa183..968cc8359120850e8eb2596ae92a9464a0694200 100644 --- a/lib_com/syn_filt_fx.c +++ b/lib_com/syn_filt_fx.c @@ -14,13 +14,8 @@ static Word32 syn_kern_2( Word32 L_tmp, const Word16 a[], const Word16 y[] ) #ifdef BASOP_NOGLOB_DECLARE_LOCAL Flag Overflow = 0; #endif -#ifdef BASOP_NOGLOB L_tmp = L_msu_o( L_tmp, y[-1], a[1], &Overflow ); return L_msu_o( L_tmp, y[-2], a[2], &Overflow ); -#else - L_tmp = L_msu( L_tmp, y[-1], a[1] ); - return L_msu( L_tmp, y[-2], a[2] ); -#endif } static Word32 syn_kern_4( Word32 L_tmp, const Word16 a[], const Word16 y[] ) @@ -135,33 +130,19 @@ void syn_filt_s_lc_fx( /* Stop at i to Avoid Mults with Zeros */ FOR( j = 1; j <= i; j++ ) { -#ifdef BASOP_NOGLOB L_tmp = L_msu_sat( L_tmp, y[-j], a[j] ); -#else - L_tmp = L_msu( L_tmp, y[-j], a[j] ); -#endif } -#ifdef BASOP_NOGLOB L_tmp = L_shl_sat( L_tmp, q ); *y++ = round_fx_sat( L_tmp ); -#else - L_tmp = L_shl( L_tmp, q ); - *y++ = round_fx( L_tmp ); -#endif move16(); } FOR( ; i < lg; i++ ) { L_tmp = syn_kern_16( L_mult( *x++, a0 ), a, y ); -#ifdef BASOP_NOGLOB L_tmp = L_shl_sat( L_tmp, q ); *y++ = round_fx_sat( L_tmp ); -#else - L_tmp = L_shl( L_tmp, q ); - *y++ = round_fx( L_tmp ); -#endif move16(); } } @@ -204,22 +185,17 @@ void syn_filt_fx( { Word16 i, j; Word16 buf[L_FRAME48k + L_FRAME48k / 2 + TCXLTP_LTP_ORDER]; /* temporary synthesis buffer */ - Word16 s, *yy; + Word16 *yy; + Word32 s; Word16 q; -#ifdef BASOP_NOGLOB Flag Overflow = 0; move16(); -#endif Word16 a0; yy = &buf[0]; q = add( norm_s( a[0] ), 1 ); -#ifdef BASOP_NOGLOB a0 = shr_o( a[0], shift, &Overflow ); /* input / 2^shift */ -#else - a0 = shr( a[0], shift ); /* input / 2^shift */ -#endif /*------------------------------------------------------------------* * copy initial filter states into synthesis buffer and do synthesis @@ -237,23 +213,16 @@ void syn_filt_fx( FOR( i = 0; i < l; i++ ) { -#ifdef BASOP_NOGLOB - s = mult_r( shl_o( a0, q, &Overflow ), x[i] ); -#else - s = mult_r( shl( a0, q ), x[i] ); -#endif + s = L_mult( a0, x[i] ); FOR( j = 1; j <= m; j++ ) { -#ifdef BASOP_NOGLOB - s = msu_ro( L_deposit_h( s ), shl_o( a[j], q, &Overflow ), yy[i - j], &Overflow ); -#else - s = msu_r( L_deposit_h( s ), shl( a[j], q ), yy[i - j] ); -#endif + s = L_msu_sat( s, shr( a[j], shift ), yy[i - j] ); } - yy[i] = s; + s = L_shl_sat( s, q ); + yy[i] = extract_h( s ); move16(); - y[i] = s; + y[i] = extract_h( s ); move16(); } @@ -274,6 +243,80 @@ void syn_filt_fx( } +void syn_filt_fx32( + const Word16 a_e, /* i : exp of LP coeffs Q0 */ + const Word32 a[], /* i : LP filter coefficients Q12 */ + const Word16 m, /* i : order of LP filter Q0 */ + const Word32 x[], /* i : input signal Qx */ + const Word16 x_e, /* i : input signal Qx */ + Word32 y[], /* o : output signal Qx */ + Word16 *y_e, /* o : output signal Qx */ + const Word16 l, /* i : size of filtering Q0 */ + Word32 mem[], /* i/o: initial filter states Qx */ + Word16 *mem_e, /* i/o: initial filter states Qx */ + const Word16 update_m /* i : update memory flag Q0 : 0 --> no memory update */ + ) /* 1 --> update of memory */ +{ + Word16 i, j; + Word64 buf[L_FRAME48k + L_FRAME48k / 2 + TCXLTP_LTP_ORDER]; /* temporary synthesis buffer */ + Word64 s, *yy; + + yy = &buf[0]; + + /*------------------------------------------------------------------* + * copy initial filter states into synthesis buffer and do synthesis + *------------------------------------------------------------------*/ + + FOR( i = 0; i < m; i++ ) + { + *yy++ = W_deposit32_l( mem[i] ); + move32(); + } + + /*-----------------------------------------------------------------------* + * Do the filtering + *-----------------------------------------------------------------------*/ + Word64 max_val = 1; + FOR( i = 0; i < l; i++ ) + { + s = W_deposit32_l( x[i] ); + FOR( j = 1; j <= m; j++ ) + { + s = W_sub( s, W_mult0_32_32( a[j], W_extract_l( W_shr( yy[i - j], sub( 31, a_e ) ) ) ) ); + } + + yy[i] = s; + move32(); + if ( GT_64( W_abs( s ), max_val ) ) + { + max_val = W_abs( s ); + } + } + + Word16 norm = W_norm( max_val ); + + FOR( i = 0; i < l; i++ ) + { + y[i] = W_extract_l( W_shr( yy[i], sub( 32, norm ) ) ); + } + *y_e = sub( 31, add( sub( 31, x_e ), sub( norm, 32 ) ) ); + /*------------------------------------------------------------------* + * Update memory if required + *------------------------------------------------------------------*/ + + IF( update_m ) + { + FOR( i = 0; i < m; i++ ) + { + mem[i] = W_extract_l( W_shr( yy[l - m + i], sub( 32, norm ) ) ); + } + *mem_e = sub( 31, add( sub( 31, x_e ), sub( norm, 32 ) ) ); + } + + return; +} + + /* * E_UTIL_synthesis * @@ -330,23 +373,14 @@ void E_UTIL_synthesis( const Word16 shift, const Word16 a[], const Word16 x[], W *-----------------------------------------------------------------------*/ mem += m; /*move16();*/ -#ifdef BASOP_NOGLOB a0 = shr_o( a[0], shift, &Overflow ); /* input / 2^shift */ -#else - a0 = shr( a[0], shift ); /* input / 2^shift */ -#endif /*-----------------------------------------------------------------------* * Do the filtering *-----------------------------------------------------------------------*/ /* Filtering Only from Input + Memory */ L_tmp = syn_kern( L_mult( a0, *x++ ), a, mem ); -#ifdef BASOP_NOGLOB L_tmp = L_shl_o( L_tmp, q, &Overflow ); *y++ = round_fx_o( L_tmp, &Overflow ); -#else - L_tmp = L_shl( L_tmp, q ); - *y++ = round_fx( L_tmp ); -#endif move16(); /* Filtering from Input + Mix of Memory & Output Signal Past */ @@ -356,28 +390,15 @@ void E_UTIL_synthesis( const Word16 shift, const Word16 a[], const Word16 x[], W /* Process Output Signal Past */ FOR( j = 1; j <= i; j++ ) { -#ifdef BASOP_NOGLOB L_tmp = L_msu_o( L_tmp, a[j], y[-j], &Overflow ); -#else - L_tmp = L_msu( L_tmp, a[j], y[-j] ); -#endif } /* Process Memory */ FOR( ; j <= m; j++ ) { -#ifdef BASOP_NOGLOB L_tmp = L_msu_sat( L_tmp, a[j], mem[i - j] ); -#else - L_tmp = L_msu( L_tmp, a[j], mem[i - j] ); -#endif } -#ifdef BASOP_NOGLOB L_tmp = L_shl_o( L_tmp, q, &Overflow ); *y++ = round_fx_o( L_tmp, &Overflow ); -#else - L_tmp = L_shl( L_tmp, q ); - *y++ = round_fx( L_tmp ); -#endif move16(); } @@ -385,13 +406,8 @@ void E_UTIL_synthesis( const Word16 shift, const Word16 a[], const Word16 x[], W FOR( ; i < lg; i++ ) { L_tmp = syn_kern( L_mult( a0, *x++ ), a, y ); -#ifdef BASOP_NOGLOB L_tmp = L_shl_o( L_tmp, q, &Overflow ); *y++ = round_fx_o( L_tmp, &Overflow ); -#else /* BASOP_NOGLOB */ - L_tmp = L_shl( L_tmp, q ); - *y++ = round_fx( L_tmp ); -#endif move16(); } @@ -623,25 +639,7 @@ void synth_mem_updt2( { lerp( old_exc + L_EXC_MEM - last_L_frame, old_exc + L_EXC_MEM - L_frame, L_frame, last_L_frame ); } -#ifdef ADD_LRTD - IF( EQ_16( dec, DEC_IVAS ) ) - { - IF( EQ_16( L_frame, L_FRAME16k ) ) - { - /* find scaling factor */ - PME() - en1 = 1.25f * sum2_f( mem_syn2, M ); - en2 = sum2_f( mem_syn_r + L_SYN_MEM - M, M ); - loc_rat = sqrtf( en2 ) / ( sqrtf( en1 ) + 0.01f ); - /* scale synthesis filter memory */ - FOR( i = 0; i < M; i++ ) - { - mem_syn_r[L_SYN_MEM - M + i] *= loc_rat; - } - } - } -#endif /*Resamp memory*/ /*Size of LPC syn memory*/ /* 1.25/20.0 = 1.0/16.0 -> shift 4 to the right. */ diff --git a/lib_com/tcq_position_arith_fx.c b/lib_com/tcq_position_arith_fx.c index 581ef7395240953b989c8d5f246e8390e08aa09e..0466dc133ffdcfacc31ed63696c9eda864027398 100644 --- a/lib_com/tcq_position_arith_fx.c +++ b/lib_com/tcq_position_arith_fx.c @@ -942,14 +942,9 @@ Word32 GetISCScale_fx( tmp16 = extract_l( t32 ); } } -#ifdef BASOP_NOGLOB tmp32 = L_shl_sat( tmp32, sub( 1, SafeExp ) ); /* *2 */ tmp32 = L_sub_sat( L_shl_sat( L_mult0( g_fx, tmp16 ), sub( Qsxy, exp ) ), tmp32 ); /*Qsxy */ -#else - tmp32 = L_shl( tmp32, 1 - SafeExp ); /* *2 */ - tmp32 = L_sub( L_shl( L_mult0( g_fx, tmp16 ), sub( Qsxy, exp ) ), tmp32 ); /*Qsxy */ -#endif - dist_fx[i] = Mult_32_16( tmp32, g_fx ); /*Qsxy + exp - 15 */ + dist_fx[i] = Mult_32_16( tmp32, g_fx ); /*Qsxy + exp - 15 */ move32(); exp_dist[i] = add( sub( Qsxy, 15 ), exp ); move16(); @@ -1988,7 +1983,11 @@ Word32 encode_magnitude_tcq_fx( move16(); bits_fx = L_deposit_l( 0 ); +#ifdef IVAS_ISSUE_1188_EVS_CRASH + tcq_bits_fx = L_sub( table_logcum_fx[npulses], L_add( table_logcum_fx[nzpos], table_logcum_fx[npulses - ( nzpos - 1 )] ) ); +#else tcq_bits_fx = L_sub( table_logcum_fx[npulses], L_add( table_logcum_fx[nzpos], table_logcum_fx[npulses - nzpos - 1] ) ); +#endif *est_frame_bits_fx = L_add( *est_frame_bits_fx, tcq_bits_fx ); move32(); @@ -2471,7 +2470,11 @@ void decode_mangitude_tcq_fx( move16(); bits_fx = L_deposit_l( 0 ); +#ifdef IVAS_ISSUE_1188_EVS_CRASH + tcq_bits_fx = L_sub( table_logcum_fx[npulses], L_add( table_logcum_fx[nzpos], table_logcum_fx[npulses - ( nzpos - 1 )] ) ); +#else tcq_bits_fx = L_sub( table_logcum_fx[npulses], L_add( table_logcum_fx[nzpos], table_logcum_fx[npulses - nzpos - 1] ) ); +#endif IF( EQ_16( nzpos, npulses ) ) { diff --git a/lib_com/tcx_ltp_fx.c b/lib_com/tcx_ltp_fx.c index a42272f0b7a5806dbaaf6febb9e62d4544b2891a..9d7cb9254a7f93061a7183406fb65853e8559889 100644 --- a/lib_com/tcx_ltp_fx.c +++ b/lib_com/tcx_ltp_fx.c @@ -44,12 +44,8 @@ void tcx_ltp_get_lpc( if ( L_tmp > 0 ) r = L_shr( r, 2 ); - tmp = shl( x[j], s ); /* Qx + s */ -#ifdef BASOP_NOGLOB + tmp = shl( x[j], s ); /* Qx + s */ r = L_mac0_sat( r, tmp, tmp ); /* Q30 */ -#else - r = L_mac0( r, tmp, tmp ); -#endif } r = L_max( r, L_shl( 100, shl( s, 1 ) ) ); /* Q30 */ r = Mpy_32_16_1( r, 16386 /*1.0001f Q14*/ ); /* Q29 */ @@ -249,25 +245,15 @@ static void tcx_ltp_get_zir( move16(); FOR( i = 0; i < L; i++ ) { -#ifdef BASOP_NOGLOB s = L_mac_sat( L_mac_sat( s, w0[k], x0[i] ), w1[k], x1[-i] ); /* Qx */ s2 = L_mac_sat( L_mac_sat( s2, v0[k], y0[i] ), v1[k], y1[-i] ); /* Qx */ -#else - s = L_mac( L_mac( s, w0[k], x0[i] ), w1[k], x1[-i] ); - s2 = L_mac( L_mac( s2, v0[k], y0[i] ), v1[k], y1[-i] ); -#endif k = k + pitres; } /* s2 *= ALPHA; buf[j] = ( synth[j] - gain * s2 ) - ( synth_ltp[j] - gain * s ); */ -#ifdef BASOP_NOGLOB i = sub_sat( round_fx_sat( s ), mult_r_sat( round_fx_sat( s2 ), ALPHA ) ); buf[j] = add_sat( sub_sat( synth[j], synth_ltp[j] ), mult_r_sat( gain, i ) ); /* Qx */ -#else - i = sub( round_fx( s ), mult_r( round_fx( s2 ), ALPHA ) ); - buf[j] = add( sub( synth[j], synth_ltp[j] ), mult_r( gain, i ) ); -#endif move16(); x0++; @@ -422,17 +408,10 @@ void predict_signal( FOR( j = 0; j < L_subfr; j++ ) { -#ifdef BASOP_NOGLOB s = L_mult_o( win[0], x0[0], &Overflow ); /* Qx + 16 */ s = L_mac_o( s, win[1], x0[1], &Overflow ); /* Qx + 16 */ s = L_mac_o( s, win[2], x0[2], &Overflow ); /* Qx + 16 */ excO[j] = mac_ro( s, win[3], x0[3], &Overflow ); /* Qx + 16 */ -#else - s = L_mult( win[0], x0[0] ); - s = L_mac( s, win[1], x0[1] ); - s = L_mac( s, win[2], x0[2] ); - excO[j] = mac_r( s, win[3], x0[3] ); -#endif move16(); x0++; @@ -512,13 +491,8 @@ static void tcx_ltp_synth_filter( move16(); FOR( i = 0; i < L; i++ ) { -#ifdef BASOP_NOGLOB s = L_mac_sat( L_mac_sat( s, w0[k], x0[i] ), w1[k], x1[-i] ); /* Qx */ s2 = L_mac_sat( L_mac_sat( s2, v0[k], y0[i] ), v1[k], y1[-i] ); /* Qx */ -#else - s = L_mac( L_mac( s, w0[k], x0[i] ), w1[k], x1[-i] ); - s2 = L_mac( L_mac( s2, v0[k], y0[i] ), v1[k], y1[-i] ); -#endif k = k + pitch_res; } @@ -526,39 +500,24 @@ static void tcx_ltp_synth_filter( normal: synth_ltp[j] = synth[j] - gain * s2 + gain * s; zir: synth_ltp[j] = synth[j] - gain * s2 + gain * s - zir[j]; fade-in/out: synth_ltp[j] = synth[j] - alpha * gain * s2 + alpha * gain * s; */ -#ifdef BASOP_NOGLOB i = sub_sat( round_fx_sat( s ), mult_r_sat( round_fx_sat( s2 ), ALPHA ) ); /* Qx */ -#else - i = sub( round_fx( s ), mult_r( round_fx( s2 ), ALPHA ) ); -#endif - k = mult_r( gain, i ); /* Qx */ + k = mult_r( gain, i ); /* Qx */ if ( fade != 0 ) k = mult_r( k, alpha ); /* Qx */ -#ifdef BASOP_NOGLOB k = add_sat( synth[j], k ); /* Qx */ if ( zir != NULL ) { k = sub_sat( k, zir[j] ); /* Qx */ } -#else - k = add( synth[j], k ); - if ( zir != NULL ) - k = sub( k, zir[j] ); -#endif synth_ltp[j] = k; /* Qx */ move16(); BASOP_SATURATE_WARNING_OFF_EVS; -#ifdef BASOP_NOGLOB if ( fade != 0 ) { alpha = add_sat( alpha, step ); } -#else - if ( fade != 0 ) - alpha = add( alpha, step ); -#endif BASOP_SATURATE_WARNING_ON_EVS; x0++; @@ -646,13 +605,8 @@ static void tcx_ltp_synth_filter32( move16(); FOR( i = 0; i < L; i++ ) { -#ifdef BASOP_NOGLOB s = Madd_32_16_r( Madd_32_16_r( s, x0[i], w0[k] ), x1[-i], w1[k] ); /* Qx */ s2 = Madd_32_16_r( Madd_32_16_r( s2, y0[i], v0[k] ), y1[-i], v1[k] ); /* Qx */ -#else - s = L_mac( L_mac( s, w0[k], x0[i] ), w1[k], x1[-i] ); - s2 = L_mac( L_mac( s2, v0[k], y0[i] ), v1[k], y1[-i] ); -#endif k = k + pitch_res; } @@ -660,39 +614,24 @@ static void tcx_ltp_synth_filter32( normal: synth_ltp[j] = synth[j] - gain * s2 + gain * s; zir: synth_ltp[j] = synth[j] - gain * s2 + gain * s - zir[j]; fade-in/out: synth_ltp[j] = synth[j] - alpha * gain * s2 + alpha * gain * s; */ -#ifdef BASOP_NOGLOB L_tmp = L_sub_sat( s, Mpy_32_16_r( s2, ALPHA ) ); /* Qx */ -#else - i = sub( round_fx( s ), mult_r( round_fx( s2 ), ALPHA ) ); -#endif - L_tmp2 = Mpy_32_16_r( L_tmp, gain ); /* Qx */ + L_tmp2 = Mpy_32_16_r( L_tmp, gain ); /* Qx */ IF( fade != 0 ) - L_tmp2 = Mpy_32_16_r( L_tmp2, alpha ); /* Qx */ -#ifdef BASOP_NOGLOB + L_tmp2 = Mpy_32_16_r( L_tmp2, alpha ); /* Qx */ L_tmp2 = L_add_sat( synth[j], L_tmp2 ); /* Qx */ if ( zir != NULL ) { L_tmp2 = L_sub_sat( L_tmp2, zir[j] ); /* Qx */ } -#else - L_tmp2 = add( synth[j], L_tmp2 ); - if ( zir != NULL ) - L_tmp2 = sub( L_tmp2, zir[j] ); -#endif synth_ltp[j] = L_tmp2; /* Qx */ move16(); BASOP_SATURATE_WARNING_OFF_EVS; -#ifdef BASOP_NOGLOB if ( fade != 0 ) { alpha = add_sat( alpha, step ); } -#else - if ( fade != 0 ) - alpha = add( alpha, step ); -#endif BASOP_SATURATE_WARNING_ON_EVS; x0++; @@ -1343,7 +1282,7 @@ void tcx_ltp_post( filtIdx = 0; /* just to avoid comilation warnings */ move16(); - tcx_buf_len = NS2SA( st->output_Fs, TCXLTP_DELAY_NS ); /* Q0 */ + tcx_buf_len = NS2SA_FX2( st->output_Fs, TCXLTP_DELAY_NS ); /* Q0 */ SideInfoOnly = 0; move16(); if ( GE_32( total_brate, HQ_96k ) ) diff --git a/lib_com/tcx_mdct_fx.c b/lib_com/tcx_mdct_fx.c index 26e7e234569154959b5b3f628448f7a1184a7269..1fc57871d4b4a6ab7096c28bc6dda728ee5cbd39 100644 --- a/lib_com/tcx_mdct_fx.c +++ b/lib_com/tcx_mdct_fx.c @@ -128,11 +128,7 @@ void TCX_MDCT( } FOR( i = 0; i < l / 2; i++ ) { -#ifdef BASOP_NOGLOB y[m / 2 + r / 2 + m / 2 + i] = L_msu_o( L_mult( x[i], factor ), x[l - 1 - i], factor, &Overflow ); /* exp(y_e) */ -#else /* BASOP_NOGLOB */ - y[m / 2 + r / 2 + m / 2 + i] = L_msu( L_mult( x[i], factor ), x[l - 1 - i], factor ); -#endif /* BASOP_NOGLOB */ move32(); } FOR( i = 0; i < m / 2; i++ ) @@ -142,11 +138,7 @@ void TCX_MDCT( } FOR( i = 0; i < r / 2; i++ ) { -#ifdef BASOP_NOGLOB y[m / 2 + r / 2 - 1 - m / 2 - i] = L_mac_o( L_mult( x[l + m + i], neg_factor ), x[l + m + r - 1 - i], neg_factor, &Overflow ); /* exp(y_e) */ -#else /* BASOP_NOGLOB */ - y[m / 2 + r / 2 - 1 - m / 2 - i] = L_mac( L_mult( x[l + m + i], neg_factor ), x[l + m + r - 1 - i], neg_factor ); -#endif /* BASOP_NOGLOB */ move32(); } @@ -194,11 +186,7 @@ void TCX_MDST( } FOR( i = 0; i < l / 2; i++ ) { -#ifdef BASOP_NOGLOB y[m / 2 + r / 2 + m / 2 + i] = L_msu_o( L_mult( x[i], neg_factor ), x[l - 1 - i], factor, &Overflow ); /* exp(y_e) */ -#else /* BASOP_NOGLOB */ - y[m / 2 + r / 2 + m / 2 + i] = L_msu( L_mult( x[i], neg_factor ), x[l - 1 - i], factor ); -#endif move32(); } FOR( i = 0; i < m / 2; i++ ) @@ -208,11 +196,7 @@ void TCX_MDST( } FOR( i = 0; i < r / 2; i++ ) { -#ifdef BASOP_NOGLOB y[m / 2 + r / 2 - 1 - m / 2 - i] = L_mac_sat( L_mult( x[l + m + i], neg_factor ), x[l + m + r - 1 - i], factor ); /* exp(y_e) */ -#else - y[m / 2 + r / 2 - 1 - m / 2 - i] = L_mac( L_mult( x[l + m + i], neg_factor ), x[l + m + r - 1 - i], factor ); -#endif move32(); } @@ -262,22 +246,14 @@ void TCX_MDCT_Inverse( FOR( i = 0; i < R2; i++ ) { -#ifdef BASOP_NOGLOB y[l + m + R2 + i] = round_fx_sat( L_shl_sat( Mpy_32_16_1( tmp_buf[L2 + i], negfac ), s ) ); /* fold out right end of DCT exp(fac_e)*/ -#else - y[l + m + R2 + i] = round_fx( L_shl( Mpy_32_16_1( tmp_buf[L2 + i], negfac ), s ) ); /* fold out right end of DCT */ -#endif move16(); } FOR( i = 0; i < L2; i++ ) { -#ifdef BASOP_NOGLOB y[i] = round_fx_sat( L_shl_sat( Mpy_32_16_1( tmp_buf[L2 + m + R2 + i], fac ), s ) ); /* negate, fold out left end of DCT exp(fac_e)*/ -#else - y[i] = round_fx( L_shl( Mpy_32_16_1( tmp_buf[L2 + m + R2 + i], fac ), s ) ); /* negate, fold out left end of DCT */ -#endif move16(); } @@ -285,13 +261,8 @@ void TCX_MDCT_Inverse( { Word16 f; -#ifdef BASOP_NOGLOB f = round_fx_sat( L_shl_sat( Mpy_32_16_1( tmp_buf[L2 + i], negfac ), s ) ); y[L2 + i] = round_fx_sat( L_shl_sat( Mpy_32_16_1( tmp_buf[l + m + R2 - 1 - i], negfac ), s ) ); /* time-reverse mid of DCT exp(fac_e)*/ -#else - f = round_fx( L_shl( Mpy_32_16_1( tmp_buf[L2 + i], negfac ), s ) ); - y[L2 + i] = round_fx( L_shl( Mpy_32_16_1( tmp_buf[l + m + R2 - 1 - i], negfac ), s ) ); /* time-reverse mid of DCT */ -#endif move16(); y[l + m + R2 - 1 - i] = f; move16(); diff --git a/lib_com/tcx_mdct_window.c b/lib_com/tcx_mdct_window.c index 110a1160d9fb2cb12d38d71d218fccfe27979ef4..44ce806f73305390709b042c43728ab19ae3aab0 100644 --- a/lib_com/tcx_mdct_window.c +++ b/lib_com/tcx_mdct_window.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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,7 +39,6 @@ #include "options.h" #include #include "cnst.h" -#include "prot.h" #include "prot_fx.h" #include "rom_com.h" #include "wmc_auto.h" diff --git a/lib_com/tcx_utils_fx.c b/lib_com/tcx_utils_fx.c index 64b7defc94efdaa59c549a80bf9b6c86b9d255e1..c5ff95e04e68c7904a93ddc7444440333131cded 100644 --- a/lib_com/tcx_utils_fx.c +++ b/lib_com/tcx_utils_fx.c @@ -9,7 +9,6 @@ #include "rom_com.h" #include "rom_basop_util.h" #include "basop_util.h" -#include "prot.h" #define inv_int InvIntTable @@ -348,11 +347,7 @@ void tcx_windowing_synthesis_current_frame( } ELSE { -#ifdef BASOP_NOGLOB lerp( acelp_zir, tmp_buf, acelp_zir_len, idiv1616U( shl_sat( acelp_zir_len, LD_FSCALE_DENOM ), fullbandScale ) ); -#else - lerp( acelp_zir, tmp_buf, acelp_zir_len, idiv1616U( shl( acelp_zir_len, LD_FSCALE_DENOM ), fullbandScale ) ); -#endif acelp_zir = tmp_buf; /*Qx*/ } @@ -387,17 +382,10 @@ void tcx_windowing_synthesis_current_frame( tmp2 = mult_r( signal[i + overlap - acelp_mem_len], window_trans[i].v.im ); /*Qx*/ /*Time TDAC: 1)forward part of ACELP*/ -#ifdef BASOP_NOGLOB tmp2 = add_sat( tmp2, mult_r( old_syn[acelp_zir_len - tmp + i], mult_r( window_trans[i].v.re, window_trans[i].v.re ) ) ); /*Qx*/ /*Time TDAC: 1)reward part of ACELP*/ tmp2 = add_sat( tmp2, mult_r( old_syn[acelp_zir_len - i - 1], mult_r( window_trans[i].v.im, window_trans[i].v.re ) ) ); /*Qx*/ -#else - tmp2 = add( tmp2, mult_r( old_syn[acelp_zir_len - tmp + i], mult_r( window_trans[i].v.re, window_trans[i].v.re ) ) ); - - /*Time TDAC: 1)reward part of ACELP*/ - tmp2 = add( tmp2, mult_r( old_syn[acelp_zir_len - i - 1], mult_r( window_trans[i].v.im, window_trans[i].v.re ) ) ); -#endif move16(); signal[i + overlap - acelp_mem_len] = tmp2; /*Qx*/ } @@ -408,17 +396,9 @@ void tcx_windowing_synthesis_current_frame( tmp2 = mult_r( signal[i + overlap - acelp_mem_len], window_trans[tmp - 1 - i].v.re ); /*Qx*/ /*Time TDAC: 1)forward part of ACELP*/ -#ifdef BASOP_NOGLOB tmp2 = add_sat( tmp2, mult_r( old_syn[acelp_zir_len - tmp + i], mult_r( window_trans[tmp - 1 - i].v.im, window_trans[tmp - 1 - i].v.im ) ) ); /*Qx*/ -#else - tmp2 = add( tmp2, mult_r( old_syn[acelp_zir_len - tmp + i], mult_r( window_trans[tmp - 1 - i].v.im, window_trans[tmp - 1 - i].v.im ) ) ); -#endif /*Time TDAC: 1)reward part of ACELP*/ -#ifdef BASOP_NOGLOB tmp2 = add_sat( tmp2, mult_r( old_syn[acelp_zir_len - i - 1], mult_r( window_trans[tmp - 1 - i].v.re, window_trans[tmp - 1 - i].v.im ) ) ); /*Qx*/ -#else - tmp2 = add( tmp2, mult_r( old_syn[acelp_zir_len - i - 1], mult_r( window_trans[tmp - 1 - i].v.re, window_trans[tmp - 1 - i].v.im ) ) ); -#endif move16(); signal[i + overlap - acelp_mem_len] = tmp2; /*Qx*/ } @@ -426,11 +406,7 @@ void tcx_windowing_synthesis_current_frame( FOR( i = 0; i < M; i++ ) { move16(); -#ifdef BASOP_NOGLOB signal[overlap + acelp_mem_len - M + i] = sub_sat( signal[overlap + acelp_mem_len - M + i], old_syn[acelp_zir_len - M + i] ); /*Qx*/ -#else - signal[overlap + acelp_mem_len - M + i] = sub( signal[overlap + acelp_mem_len - M + i], old_syn[acelp_zir_len - M + i] ); -#endif } } /* ZIR at the end of the ACELP frame */ @@ -484,11 +460,7 @@ void tcx_windowing_synthesis_current_frame( { /*remove reconstructed ZIR and add ACELP ZIR*/ move16(); -#ifdef BASOP_NOGLOB signal[i + overlap + acelp_mem_len] = sub_sat( signal[i + overlap + acelp_mem_len], mult_r_sat( acelp_zir[i], div_s( sub_sat( acelp_zir_len, i ), acelp_zir_len ) ) ); /*Qx*/ -#else - signal[i + overlap + acelp_mem_len] = sub( signal[i + overlap + acelp_mem_len], mult_r( acelp_zir[i], div_s( sub( acelp_zir_len, i ), acelp_zir_len ) ) ); -#endif } } /* Rectangular window (past-frame is TCX) */ @@ -1072,7 +1044,7 @@ void mdct_shaping( FOR( l = 0; l < k; l++ ) { - *x = L_shl( Mpy_32_16_r( *x, *gains ), *gains_exp ); /*Qx*/ + *x = L_shl_o( Mpy_32_16_r( *x, *gains ), *gains_exp, &Overflow ); /*Qx*/ move32(); x++; } @@ -1091,11 +1063,7 @@ void mdct_shaping( gains_exp = pgainsexp; FOR( i = 0; i < FDNS_NPTS; i++ ) { -#ifdef BASOP_NOGLOB *x = L_shl_o( Mpy_32_16_r( *x, *gains ), *gains_exp, &Overflow ); /*Qx*/ -#else - *x = L_shl( Mpy_32_16_r( *x, *gains ), *gains_exp ); -#endif move32(); x += k; gains++; @@ -1470,12 +1438,8 @@ void PsychAdaptLowFreqDeemph( L_tmp = BASOP_Util_Log2( L_tmp ); /* Q25 */ L_tmp = L_shr( L_tmp, 7 ); /* 0.0078125f = 1.f/(1<<7) */ L_tmp = BASOP_Util_InvLog2( L_tmp ); /* Q31 */ -#ifdef BASOP_NOGLOB - tmp = round_fx_o( L_tmp, &Overflow ); /* Q15 */ -#else /* BASOP_NOGLOB */ - tmp = round_fx( L_tmp ); /* Q15 */ -#endif - fac = tmp; /* Q15 */ + tmp = round_fx_o( L_tmp, &Overflow ); /* Q15 */ + fac = tmp; /* Q15 */ move16(); /* gradual lowering of lowest 32 bins; DC is lowered by (max_val/tmp)^1/4 */ @@ -1710,11 +1674,7 @@ void tcx_noise_filling( tmp32 = BASOP_Util_Log2( L_deposit_h( s_max( 0x3000, tiltCompFactor ) ) ); /* 6Q25 */ tmp32 = L_shr( Mpy_32_16_1( tmp32, tmp1 ), 6 ); /*Q25*/ BASOP_SATURATE_WARNING_OFF_EVS; -#ifdef BASOP_NOGLOB tilt_factor = round_fx_sat( BASOP_Util_InvLog2( tmp32 ) ); /*Q15*/ -#else - tilt_factor = round_fx( BASOP_Util_InvLog2( tmp32 ) ); -#endif BASOP_SATURATE_WARNING_ON_EVS; /* find last nonzero line below iFirstLine, use it as start offset */ @@ -1856,11 +1816,7 @@ void tcx_noise_filling_with_shift( tmp32 = BASOP_Util_Log2( L_deposit_h( s_max( 0x3000, tiltCompFactor ) ) ); /* 6Q25 */ tmp32 = L_shr( Mpy_32_16_1( tmp32, tmp1 ), 6 ); /*Q25*/ BASOP_SATURATE_WARNING_OFF_EVS; -#ifdef BASOP_NOGLOB tilt_factor = round_fx_sat( BASOP_Util_InvLog2( tmp32 ) ); /*Q15*/ -#else - tilt_factor = round_fx( BASOP_Util_InvLog2( tmp32 ) ); -#endif BASOP_SATURATE_WARNING_ON_EVS; /* find last nonzero line below iFirstLine, use it as start offset */ @@ -2173,11 +2129,7 @@ void tcx_get_gain( ener = L_shl( ener, tmp ); /*Q31 - ener_e + tmp*/ ener_e = sub( ener_e, tmp ); -#ifdef BASOP_NOGLOB tmp = div_s( abs_s( round_fx_o( corr, &Overflow ) ), round_fx_o( ener, &Overflow ) ); /*Q15 - (corr_e - ener_e)*/ -#else - tmp = div_s( abs_s( round_fx( corr ) ), round_fx( ener ) ); -#endif if ( corr < 0 ) tmp = negate( tmp ); diff --git a/lib_com/tec_com.c b/lib_com/tec_com.c index c51a2cd02a77f6fe48b61088f16bf245fcc97304..0a37504df957bc577c8fc9eed3c64c0b4fa17de3 100644 --- a/lib_com/tec_com.c +++ b/lib_com/tec_com.c @@ -317,11 +317,7 @@ static void calcHiTempEnv_Fx( FOR( k = lowSubband; k < highSubband; k++ ) { -#ifdef BASOP_NOGLOB nrg = L_add_sat( nrg, L_shr( pCldfbPow[timeIndex][k], s1 ) ); /*Q31 - s1*/ -#else - nrg = L_add( nrg, L_shr( pCldfbPow[timeIndex][k], s1 ) ); -#endif } diff --git a/lib_com/tns_base.c b/lib_com/tns_base.c index 039c7a04226d8e6604b56a5fe41aecfef2d2fee1..101bc1df8b6552407c352786dc2e08dd79ec5ec0 100644 --- a/lib_com/tns_base.c +++ b/lib_com/tns_base.c @@ -12,7 +12,6 @@ #include "rom_com.h" #include "prot_fx.h" #include "basop_util.h" -#include "prot.h" /*---------------------------------------------------------------------------- * Local constants @@ -496,11 +495,7 @@ Word16 ITF_Detect_fx( /* Check threshold HLM_MIN_NRG */ BASOP_SATURATE_WARNING_OFF_EVS; -#ifdef BASOP_NOGLOB tmp32 = L_sub( L_shl_o( L_tmp, sub( shift, sub( 24, Q ) ), &Overflow ), 4194304l /*HLM_MIN_NRG Q7*/ ); /*Q7*/ -#else /* BASOP_NOGLOB */ - tmp32 = L_sub( L_shl( L_tmp, sub( shift, 24 - Q ) ), 4194304l /*HLM_MIN_NRG Q7*/ ); -#endif BASOP_SATURATE_WARNING_ON_EVS; /* get pre-shift for autocorrelation */ @@ -531,11 +526,7 @@ Word16 ITF_Detect_fx( L_tmp = L_shl( L_tmp, sub( shift, tmp ) ); /* shift L_tmp to that exponent */ /* calc factor (with 2 bits headroom for sum of 3 subdivisions) */ -#ifdef BASOP_NOGLOB facs[iSubdivisions] = div_s( 0x2000, round_fx_sat( L_tmp ) ); /* L_tmp is >= 0x2000000 Q15*/ -#else - facs[iSubdivisions] = div_s( 0x2000, round_fx( L_tmp ) ); /* L_tmp is >= 0x2000000 */ -#endif move16(); } } @@ -610,6 +601,145 @@ Word16 ITF_Detect_fx( return 1; } + +Word16 ITF_Detect_ivas_fx( + const Word32 pSpectrum[], /*Q*/ + const Word16 startLine, /*Q0*/ + const Word16 stopLine, /*Q0*/ + const Word16 maxOrder, /*Q0*/ + Word16 *A, /*Q_A*/ + Word16 *Q_A, + Word16 *predictionGain, /*Q7*/ + Word16 *curr_order, /*Q0*/ + Word16 Q ) +{ + Word32 norms[MAX_SUBDIVISIONS]; + Word16 num_subdivisions, i, length; + Word16 iStartLine, iEndLine, spectrumLength; + Word32 rxx[ITF_MAX_FILTER_ORDER + 1]; + Word16 q_rxx[ITF_MAX_FILTER_ORDER + 1]; + Word32 temp_spectrum[640]; + const Word16 *pWindow; + const Word32 *ptr_spectrum1, *ptr_spectrum2; + Word16 iSubdivisions, lag; + Word16 headroom, guard_bits, shift, q_min; + Word64 sum; + Word16 fac, q_fac, exp, q_temp; + Word32 temp; + + IF( maxOrder <= 0 ) + { + return 0; + } + pWindow = tnsAcfWindow_fx; + set_zero_fx( norms, MAX_SUBDIVISIONS ); + set_zero_fx( rxx, ITF_MAX_FILTER_ORDER + 1 ); /* This initialization is required */ + set16_fx( q_rxx, Q31, ITF_MAX_FILTER_ORDER + 1 ); /* This initialization is required */ + + spectrumLength = sub( stopLine, startLine ); + num_subdivisions = 0; + move16(); + + /* Calculate norms for each spectrum part */ + FOR( iSubdivisions = 0; iSubdivisions < MAX_SUBDIVISIONS; iSubdivisions++ ) + { + /* iStartLine = startLine + ( stopLine - startLine ) * iSubdivisions / nSubdivisions; */ + iStartLine = add( startLine, mult( imult1616( spectrumLength, iSubdivisions ), 10923 /* 1/MAX_SUBDIVISIONS in Q15 */ ) ); /*Q0*/ + /* iEndLine = startLine + ( stopLine - startLine ) * ( iSubdivisions + 1 ) / nSubdivisions; */ + iEndLine = add( startLine, mult( imult1616( spectrumLength, add( iSubdivisions, 1 ) ), 10923 /* 1/MAX_SUBDIVISIONS in Q15 */ ) ); /*Q0*/ + + + /* Variable initialization */ + /* norms[iSubdivisions] = sum2_f(pSpectrum + iStartLine - IGF_START_MN, iEndLine - iStartLine); */ + + ptr_spectrum1 = pSpectrum + sub( iStartLine, IGF_START_MN ); + length = sub( iEndLine, iStartLine ); + headroom = L_norm_arr( ptr_spectrum1, length ); + guard_bits = find_guarded_bits_fx( length ); + shift = sub( headroom, guard_bits ); + + Copy_Scale_sig32( ptr_spectrum1, temp_spectrum, length, shift ); // Q -> Q+shift + + sum = 0; + move64(); + FOR( i = 0; i < length; i++ ) + { + sum = W_mac_32_32( sum, temp_spectrum[i], temp_spectrum[i] ); // 2(Q+shift)+1 + } + + IF( LE_64( sum, W_shl( 32768 * 2 /* HLM_MIN_NRG in Q1 */, shl( add( Q, shift ), 1 ) ) ) ) + { + BREAK; + } + + /* fac = 1.0f / norms[iSubdivisions]; */ + exp = W_norm( sum ); + sum = W_shl( sum, exp ); // 2(Q+shift)+1+exp + fac = div_s( ONE_IN_Q14, extract_h( W_extract_h( sum ) ) ); // 15+14-(2(Q+shift)+1+exp-48) = 76-(2(Q+shift)+exp) + q_fac = sub( 76, add( shl( add( Q, shift ), 1 ), exp ) ); + pWindow = tnsAcfWindow_fx; + + /* For additional loop condition */ + /* Variable initialization */ + /*for ( lag = 1; lag <= maxOrder; lag++ ) + { + rxx[lag] += fac * ( *pWindow ) * dotp( pSpectrum + iStartLine - IGF_START_MN, pSpectrum + iStartLine - IGF_START_MN + lag, iEndLine - iStartLine - lag ); + pWindow++; + }*/ + + ptr_spectrum1 = temp_spectrum; // pSpectrum + iStartLine - IGF_START_MN; + FOR( lag = 1; lag <= maxOrder; lag++ ) + { + /* dotp( pSpectrum + iStartLine - IGF_START_MN, pSpectrum + iStartLine - IGF_START_MN + lag, iEndLine - iStartLine - lag ) */ + ptr_spectrum2 = temp_spectrum + lag; // pSpectrum + iStartLine - IGF_START_MN + lag; + + sum = 0; + move64(); + FOR( i = 0; i < iEndLine - iStartLine - lag; i++ ) + { + sum = W_mac_32_32( sum, ptr_spectrum1[i], ptr_spectrum2[i] ); // 2(Q+shift)+1 + } + exp = W_norm( sum ); + sum = W_shl( sum, exp ); // 2(Q+shift)+1+exp + temp = Mpy_32_32( L_mult0( fac, *pWindow ), W_extract_h( sum ) ); // (q_fac+15)+(2(Q+shift)+1+exp-32)-31 = q_fac+2(Q+shift)+exp-47 + q_temp = sub( add( q_fac, add( shl( add( Q, shift ), 1 ), exp ) ), 47 ); + + /* rxx[lag] += fac * (*pWindow) * dotp(pSpectrum + iStartLine - IGF_START_MN, pSpectrum + iStartLine - IGF_START_MN + lag, iEndLine - iStartLine - lag); */ + q_min = sub( s_min( q_temp, q_rxx[lag] ), 1 ); + rxx[lag] = L_add( L_shl( rxx[lag], sub( q_min, q_rxx[lag] ) ), L_shl( temp, sub( q_min, q_temp ) ) ); + q_rxx[lag] = q_min; + move32(); + move16(); + + pWindow++; + } + + num_subdivisions = add( num_subdivisions, 1 ); + } + + minimum_s( q_rxx + 1, ITF_MAX_FILTER_ORDER, &q_min ); + q_min = s_min( Q29, q_min ); + + FOR( i = 1; i < ITF_MAX_FILTER_ORDER; i++ ) + { + rxx[i] = L_shl( rxx[i], sub( q_min, q_rxx[i] ) ); + move32(); + } + + IF( EQ_16( iSubdivisions, MAX_SUBDIVISIONS ) ) /* meaning there is no subdivision with low energy */ + { + rxx[0] = L_shl( MAX_SUBDIVISIONS, q_min ); + move32(); + + /* Limit the maximum order to spectrum length/4 */ + ITF_GetFilterParameters_fx( rxx, s_min( maxOrder, shr( spectrumLength, 2 ) ), A, Q_A, predictionGain ); + + *curr_order = maxOrder; /*Q0*/ + move16(); + } + + return 1; +} /* Helper functions for Hufmann table coding */ @@ -1071,6 +1201,10 @@ void ResetTnsData( STnsData *pTnsData ) move16(); pTnsFilter->predictionGain = ONE_IN_Q7; /*Q7*/ move16(); + pTnsFilter->predictionGain32 = ONE_IN_Q23; /*Q23*/ + move32(); + pTnsFilter->predictionGain_e = PRED_GAIN_E; + move16(); pTnsFilter->avgSqrCoef = 0; move16(); pTnsFilter->filterType = TNS_FILTER_OFF; /*Q0*/ diff --git a/lib_com/tools.c b/lib_com/tools.c index f757239f38f38da77ad373ff14f22007e7b9a2e7..e4ccd9955ff0ec12a935b289f98e151da54c2be2 100644 --- a/lib_com/tools.c +++ b/lib_com/tools.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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,7 +37,6 @@ #include #include "options.h" #include -#include "prot.h" #include "prot_fx.h" #include "wmc_auto.h" @@ -136,23 +135,6 @@ int16_t sum_s( return tmp; } -/*! r: sum of all vector elements */ -int32_t sum_l( - const int32_t *vec, /* i : input vector */ - const int16_t lvec /* i : length of input vector */ -) -{ - int16_t i; - int32_t tmpL; - - tmpL = 0; - for ( i = 0; i < lvec; i++ ) - { - tmpL += vec[i]; - } - - return tmpL; -} /*! r: sum of all vector elements */ Word32 sum_l_fx( const Word32 *vec, /* i : input vector */ @@ -171,23 +153,6 @@ Word32 sum_l_fx( return tmpL; } -/*! r: sum of all vector elements */ -float sum_f( - const float *vec, /* i : input vector */ - const int16_t lvec /* i : length of input vector */ -) -{ - int16_t i; - float tmp; - - tmp = 0.0f; - for ( i = 0; i < lvec; i++ ) - { - tmp += vec[i]; - } - - return tmp; -} /*---------------------------------------------------------------------- * sum2_f() @@ -228,22 +193,6 @@ Word32 sum2_f_16_gb_fx( return tmp; } -float sum2_f( - const float *vec, /* i : input vector */ - const int16_t lvec /* i : length of input vector */ -) -{ - int16_t i; - float tmp; - - tmp = 0.0f; - for ( i = 0; i < lvec; i++ ) - { - tmp += vec[i] * vec[i]; - } - - return tmp; -} Word32 sum2_16_exp_fx( const Word16 *vec, /* i : input vector Q(15 - exp) */ @@ -281,13 +230,18 @@ Word32 sum2_32_exp_fx( Word16 gb /* i : guard bits */ ) { - Word16 i, s; + Word16 i, s, norm; Word64 W_tmp; W_tmp = 0; Word64 var_a = 0; move64(); move64(); + + norm = L_norm_arr( vec, lvec ); + + gb = sub( gb, norm ); + FOR( i = 0; i < lvec; i++ ) { var_a = W_mult0_32_32( vec[i], vec[i] ); // 2x @@ -527,101 +481,6 @@ void mvs2s( return; } -uint32_t mvr2s( - const float x[], /* i : input vector */ - int16_t y[], /* o : output vector */ - const int16_t n /* i : vector size */ -) -{ - int16_t i; - float temp; - uint32_t noClipping = 0; - - if ( n <= 0 ) - { - /* cannot transfer vectors with size 0 */ - return 0; - } - - if ( (void *) y <= (const void *) x ) - { - for ( i = 0; i < n; i++ ) - { - temp = x[i]; - temp = (float) floor( temp + 0.5f ); - - if ( temp > MAX16B_FLT ) - { - temp = MAX16B_FLT; - noClipping++; - } - else if ( temp < MIN16B_FLT ) - { - temp = MIN16B_FLT; - noClipping++; - } - - y[i] = (int16_t) temp; - } - } - else - { - for ( i = n - 1; i >= 0; i-- ) - { - temp = x[i]; - temp = (float) floor( temp + 0.5f ); - - if ( temp > MAX16B_FLT ) - { - temp = MAX16B_FLT; - noClipping++; - } - else if ( temp < MIN16B_FLT ) - { - temp = MIN16B_FLT; - noClipping++; - } - - y[i] = (int16_t) temp; - } - } - - return noClipping; -} - -void mvs2r( - const int16_t x[], /* i : input vector */ - float y[], /* o : output vector */ - const int16_t n /* i : vector size */ -) -{ - int16_t i; - - if ( n <= 0 ) - { - /* cannot transfer vectors with size 0 */ - return; - } - - if ( (void *) y < (const void *) x ) - { - for ( i = 0; i < n; i++ ) - { - y[i] = (float) x[i]; - } - } - else - { - for ( i = n - 1; i >= 0; i-- ) - { - y[i] = (float) x[i]; - } - } - - return; -} - - void mvl2l( const int32_t x[], /* i : input vector */ int32_t y[], /* o : output vector */ @@ -654,44 +513,6 @@ void mvl2l( return; } - -/*---------------------------------------------------------------------* - * maximum() - * - * Find index and value of the maximum in a vector - *---------------------------------------------------------------------*/ - -/*! r: index of the maximum value in the input vector */ -int16_t maximum( - const float *vec, /* i : input vector */ - const int16_t lvec, /* i : length of input vector */ - float *max_val /* o : maximum value in the input vector */ -) -{ - int16_t j, ind; - float tmp; - - ind = 0; - tmp = vec[0]; - - for ( j = 1; j < lvec; j++ ) - { - if ( vec[j] > tmp ) - { - ind = j; - tmp = vec[j]; - } - } - - if ( max_val != NULL ) - { - *max_val = tmp; - } - - return ind; -} - - /*! r: index of the maximum value in the input vector */ Word16 maximum_s( const Word16 *vec, /* i : input vector */ @@ -761,42 +582,6 @@ Word16 maximum_l( return ind; } -/*---------------------------------------------------------------------* - * maximumAbs() - * - * Find index and value of the maximum in a vector - *---------------------------------------------------------------------*/ - -/*! r: index of the maximum value in the input vector */ -int16_t maximumAbs( - const float *vec, /* i : input vector */ - const int16_t lvec, /* i : length of input vector */ - float *max_val /* o : maximum value in the input vector */ -) -{ - int16_t j, ind; - float tmp; - - ind = 0; - tmp = (float) fabs( vec[0] ); - - for ( j = 1; j < lvec; j++ ) - { - if ( (float) fabs( vec[j] ) > tmp ) - { - ind = j; - tmp = (float) fabs( vec[j] ); - } - } - - if ( max_val != NULL ) - { - *max_val = tmp; - } - - return ind; -} - /*! r: index of the maximum value in the input vector */ Word16 maximumAbs_l( const Word32 *vec, /* i : input vector */ @@ -830,42 +615,6 @@ Word16 maximumAbs_l( return ind; } -/*---------------------------------------------------------------------* - * minimum() - * - * Find index of a minimum in a vector - *---------------------------------------------------------------------*/ - -/*! r: index of the minimum value in the input vector */ -int16_t minimum( - const float *vec, /* i : input vector */ - const int16_t lvec, /* i : length of input vector */ - float *min_val /* o : minimum value in the input vector */ -) -{ - int16_t j, ind; - float tmp; - - ind = 0; - tmp = vec[0]; - - for ( j = 1; j < lvec; j++ ) - { - if ( vec[j] < tmp ) - { - ind = j; - tmp = vec[j]; - } - } - - if ( min_val != NULL ) - { - *min_val = tmp; - } - - return ind; -} - /*-------------------------------------------------------------------* * minimum_s() * @@ -983,59 +732,6 @@ Word16 minimum_l( return ind; } -/*---------------------------------------------------------------------* - * emaximum() - * - * Find index of a maximum energy in a vector - *---------------------------------------------------------------------*/ - -/*! r: return index with max energy value in vector */ -int16_t emaximum( - const float *vec, /* i : input vector */ - const int16_t lvec, /* i : length of input vector */ - float *ener_max /* o : maximum energy value */ -) -{ - int16_t j, ind; - float temp; - - *ener_max = 0.0f; - ind = 0; - - for ( j = 0; j < lvec; j++ ) - { - temp = vec[j] * vec[j]; - - if ( temp > *ener_max ) - { - ind = j; - *ener_max = temp; - } - } - - return ind; -} - - -/*---------------------------------------------------------------------* - * mean() - * - * Find the mean of the vector - *---------------------------------------------------------------------*/ - -/*! r: mean of vector */ -float mean( - const float *vec, /* i : input vector */ - const int16_t lvec /* i : length of input vector */ -) -{ - float tmp; - - tmp = sum_f( vec, lvec ) / (float) lvec; - - return tmp; -} - /*---------------------------------------------------------------------* * dotp() * @@ -1163,114 +859,6 @@ float inv_sqrt( return (float) ( 1.0 / sqrt( x ) ); } - -/*-------------------------------------------------------------------* - * conv() - * - * Convolution between vectors x[] and h[] written to y[] - * All vectors are of length L. Only the first L samples of the - * convolution are considered. - *-------------------------------------------------------------------*/ - -void conv( - const float x[], /* i : input vector */ - const float h[], /* i : impulse response (or second input vector) */ - float y[], /* o : output vetor (result of convolution) */ - const int16_t L /* i : vector size */ -) -{ - float temp; - int16_t i, n; - for ( n = 0; n < L; n++ ) - { - temp = x[0] * h[n]; - for ( i = 1; i <= n; i++ ) - { - temp += x[i] * h[n - i]; - } - y[n] = temp; - } - - return; -} - -/*-------------------------------------------------------------------* - * fir() - * - * FIR filtering of vector x[] with filter having impulse response h[] - * written to y[] - * The input vector has length L and the FIR filter has an order of K, i.e. - * K+1 coefficients. The memory of the input signal is provided in the vector mem[] - * which has K values - * The maximum length of the input signal is L_FRAME32k and the maximum order - * of the FIR filter is L_FILT_MAX - *-------------------------------------------------------------------*/ - -void fir( - const float x[], /* i : input vector */ - const float h[], /* i : impulse response of the FIR filter */ - float y[], /* o : output vector (result of filtering) */ - float mem[], /* i/o: memory of the input signal (L samples) */ - const int16_t L, /* i : input vector size */ - const int16_t K, /* i : order of the FIR filter (K+1 coefs.) */ - const int16_t upd /* i : 1 = update the memory, 0 = not */ -) -{ - float buf_in[L_FRAME48k + 60], buf_out[L_FRAME48k], s; - int16_t i, j; - - /* prepare the input buffer (copy and update memory) */ - mvr2r( mem, buf_in, K ); - mvr2r( x, buf_in + K, L ); - - if ( upd ) - { - mvr2r( buf_in + L, mem, K ); - } - - /* do the filtering */ - for ( i = 0; i < L; i++ ) - { - s = buf_in[K + i] * h[0]; - - for ( j = 1; j <= K; j++ ) - { - s += h[j] * buf_in[K + i - j]; - } - - buf_out[i] = s; - } - - /* copy to the output buffer */ - mvr2r( buf_out, y, L ); - - return; -} - -/*-------------------------------------------------------------------* - * v_add() - * - * Addition of two vectors sample by sample - *-------------------------------------------------------------------*/ - -void v_add( - const float x1[], /* i : Input vector 1 */ - const float x2[], /* i : Input vector 2 */ - float y[], /* o : Output vector that contains vector 1 + vector 2 */ - const int16_t N /* i : Vector length */ -) -{ - int16_t i; - - for ( i = 0; i < N; i++ ) - { - y[i] = x1[i] + x2[i]; - } - - return; -} - - /*-------------------------------------------------------------------* * v_add_w64() * @@ -1346,55 +934,9 @@ void v_sub_fixed( } /*-------------------------------------------------------------------* - * v_mult() + * v_multc_fixed() * - * Multiplication of two vectors - *-------------------------------------------------------------------*/ - -void v_mult( - const float x1[], /* i : Input vector 1 */ - const float x2[], /* i : Input vector 2 */ - float y[], /* o : Output vector that contains vector 1 .* vector 2 */ - const int16_t N /* i : Vector length */ -) -{ - int16_t i; - - for ( i = 0; i < N; i++ ) - { - y[i] = x1[i] * x2[i]; - } - - return; -} - -/*-------------------------------------------------------------------* - * v_multc() - * - * Multiplication of vector by constant - *-------------------------------------------------------------------*/ - -void v_multc( - const float x[], /* i : Input vector */ - const float c, /* i : Constant */ - float y[], /* o : Output vector that contains c*x */ - const int16_t N /* i : Vector length */ -) -{ - int16_t i; - - for ( i = 0; i < N; i++ ) - { - y[i] = c * x[i]; - } - - return; -} - -/*-------------------------------------------------------------------* - * v_multc_fixed() - * - * Multiplication of vector by constant + * Multiplication of vector by constant *-------------------------------------------------------------------*/ void v_multc_fixed( @@ -1451,102 +993,6 @@ void v_multc_fixed_16_16( return; } -/*-------------------------------------------------------------------* - * squant() - * - * Scalar quantizer according to MMSE criterion (nearest neighbour in Euclidean space) - * - * Searches a given codebook to find the nearest neighbour in Euclidean space. - * Index of the winning codeword and the winning codeword itself are returned. - *-------------------------------------------------------------------*/ - -/*! r: index of the winning codeword */ -int16_t squant( - const float x, /* i : scalar value to quantize */ - float *xq, /* o : quantized value */ - const float cb[], /* i : codebook */ - const int16_t cbsize /* i : codebook size */ -) -{ - float dist, mindist, tmp; - int16_t c, idx; - - idx = 0; - mindist = 1e16f; - - for ( c = 0; c < cbsize; c++ ) - { - dist = 0.0f; - tmp = x - cb[c]; - dist += tmp * tmp; - if ( dist < mindist ) - { - mindist = dist; - idx = c; - } - } - - *xq = cb[idx]; - - return idx; -} - -/*! r: index of the winning codeword */ -int16_t squant_int( - uint8_t x, /* i : scalar value to quantize */ - uint8_t *xq, /* o : quantized value */ - const uint8_t *cb, /* i : codebook */ - const int16_t cbsize /* i : codebook size */ -) -{ - int16_t i, idx; - float mindist, d; - - idx = 0; - mindist = 10000000.0f; - for ( i = 0; i < cbsize; i++ ) - { - d = (float) ( x - cb[i] ) * ( x - cb[i] ); - if ( d < mindist ) - { - mindist = d; - idx = i; - } - } - *xq = cb[idx]; - - return idx; -} - - -/*-------------------------------------------------------------------* - * usquant() - * - * Uniform scalar quantizer according to MMSE criterion - * (nearest neighbour in Euclidean space) - * - * Applies quantization based on scale and round operations. - * Index of the winning codeword and the winning codeword itself are returned. - *-------------------------------------------------------------------*/ - -/*! r: index of the winning codeword */ -int16_t usquant( - const float x, /* i : scalar value to quantize */ - float *xq, /* o : quantized value */ - const float qlow, /* i : lowest codebook entry (index 0) */ - const float delta, /* i : quantization step */ - const int16_t cbsize /* i : codebook size */ -) -{ - int16_t idx; - - idx = (int16_t) max( 0.f, min( cbsize - 1, ( ( x - qlow ) / delta + 0.5f ) ) ); - *xq = idx * delta + qlow; - - return idx; -} - - /*-------------------------------------------------------------------* * usdequant() * @@ -1568,219 +1014,6 @@ float usdequant( return ( g ); } - -/*-------------------------------------------------------------------* - * vquant() - * - * Vector quantizer according to MMSE criterion (nearest neighbour in Euclidean space) - * - * Searches a given codebook to find the nearest neighbour in Euclidean space. - * Index of the winning codevector and the winning vector itself are returned. - *-------------------------------------------------------------------*/ - -/*! r: index of the winning codevector */ -int16_t vquant( - float x[], /* i : vector to quantize */ - const float x_mean[], /* i : vector mean to subtract (0 if none) */ - float xq[], /* o : quantized vector */ - const float cb[], /* i : codebook */ - const int16_t dim, /* i : dimension of codebook vectors */ - const int16_t cbsize /* i : codebook size */ -) -{ - float dist, mindist, tmp; - int16_t c, d, idx, j; - - idx = 0; - mindist = 1e16f; - - if ( x_mean != 0 ) - { - for ( d = 0; d < dim; d++ ) - { - x[d] -= x_mean[d]; - } - } - - j = 0; - for ( c = 0; c < cbsize; c++ ) - { - dist = 0.0f; - for ( d = 0; d < dim; d++ ) - { - tmp = x[d] - cb[j++]; - dist += tmp * tmp; - } - - if ( dist < mindist ) - { - mindist = dist; - idx = c; - } - } - - if ( xq == 0 ) - { - return idx; - } - - j = idx * dim; - for ( d = 0; d < dim; d++ ) - { - xq[d] = cb[j++]; - } - - if ( x_mean != 0 ) - { - for ( d = 0; d < dim; d++ ) - { - xq[d] += x_mean[d]; - } - } - - return idx; -} - -/*-------------------------------------------------------------------* - * w_vquant() - * - * Vector quantizer according to MMSE criterion (nearest neighbour in Euclidean space) - * - * Searches a given codebook to find the nearest neighbour in Euclidean space. - * Weights are put on the error for each vector element. - * Index of the winning codevector and the winning vector itself are returned. - *-------------------------------------------------------------------*/ - -/*! r: index of the winning codevector */ -int16_t w_vquant( - float x[], /* i : vector to quantize */ - const float x_mean[], /* i : vector mean to subtract (0 if none) */ - const int16_t weights[], /* i : error weights */ - float xq[], /* o : quantized vector */ - const float cb[], /* i : codebook */ - const int16_t dim, /* i : dimension of codebook vectors */ - const int16_t cbsize, /* i : codebook size */ - const int16_t rev_vect /* i : reverse codebook vectors */ -) -{ - float dist, mindist, tmp; - int16_t c, d, idx, j, k; - - idx = 0; - mindist = 1e16f; - - if ( x_mean != 0 ) - { - for ( d = 0; d < dim; d++ ) - { - x[d] -= x_mean[d]; - } - } - - j = 0; - if ( rev_vect ) - { - k = dim - 1; - for ( c = 0; c < cbsize; c++ ) - { - dist = 0.0f; - - for ( d = k; d >= 0; d-- ) - { - tmp = x[d] - cb[j++]; - dist += weights[d] * ( tmp * tmp ); - } - - if ( dist < mindist ) - { - mindist = dist; - idx = c; - } - } - - if ( xq == 0 ) - { - return idx; - } - - j = idx * dim; - for ( d = k; d >= 0; d-- ) - { - xq[d] = cb[j++]; - } - } - else - { - for ( c = 0; c < cbsize; c++ ) - { - dist = 0.0f; - - for ( d = 0; d < dim; d++ ) - { - tmp = x[d] - cb[j++]; - dist += weights[d] * ( tmp * tmp ); - } - - if ( dist < mindist ) - { - mindist = dist; - idx = c; - } - } - - if ( xq == 0 ) - { - return idx; - } - - j = idx * dim; - for ( d = 0; d < dim; d++ ) - { - xq[d] = cb[j++]; - } - } - - if ( x_mean != 0 ) - { - for ( d = 0; d < dim; d++ ) - { - xq[d] += x_mean[d]; - } - } - - return idx; -} - - -/*----------------------------------------------------------------------------------* - * v_sort() - * - * Sorting of vectors. This is very fast with almost ordered vectors. - *----------------------------------------------------------------------------------*/ - -void v_sort_float( - float *r, /* i/o: Vector to be sorted in place */ - const int16_t lo, /* i : Low limit of sorting range */ - const int16_t up /* I : High limit of sorting range */ -) -{ - int16_t i, j; - float tempr; - - for ( i = up - 1; i >= lo; i-- ) - { - tempr = r[i]; - for ( j = i + 1; j <= up && ( tempr > r[j] ); j++ ) - { - r[j - 1] = r[j]; - } - - r[j - 1] = tempr; - } - - return; -} - void sort( UWord16 *x, /* i/o: Vector to be sorted */ UWord16 len /* i/o: vector length */ @@ -1805,430 +1038,3 @@ void sort( return; } - -/*---------------------------------------------------------------------* - * var() - * - * Calculate the variance of a vector - *---------------------------------------------------------------------*/ - -/*! r: variance of vector */ -float var( - const float *x, /* i : input vector */ - const int16_t len /* i : length of inputvector */ -) -{ - float m; - float v; - int16_t i; - - m = mean( x, len ); - - v = 0.0f; - for ( i = 0; i < len; i++ ) - { - v += ( x[i] - m ) * ( x[i] - m ); - } - v /= len; - - return v; -} - - -/*---------------------------------------------------------------------* - * std_dev() - * - * Calculate the standard deviation of a vector - *---------------------------------------------------------------------*/ - -/*! r: standard deviation */ -float std_dev( - const float *x, /* i : input vector */ - const int16_t len /* i : length of the input vector */ -) -{ - int16_t i; - float std; - - std = 1e-16f; - for ( i = 0; i < len; i++ ) - { - std += x[i] * x[i]; - } - - std = (float) sqrt( std / len ); - - return std; -} - - -/*---------------------------------------------------------------------* - * dot_product_mat() - * - * Calculates dot product of type x'*A*x, where x is column vector of size m, - * and A is square matrix of size m*m - *---------------------------------------------------------------------*/ - -/*! r: the dot product x'*A*x */ -float dot_product_mat( - const float *x, /* i : vector x */ - const float *A, /* i : matrix A */ - const int16_t m /* i : vector & matrix size */ -) -{ - int16_t i, j; - float suma, tmp_sum; - const float *pt_x, *pt_A; - - pt_A = A; - suma = 0; - - for ( i = 0; i < m; i++ ) - { - tmp_sum = 0; - pt_x = x; - for ( j = 0; j < m; j++ ) - { - tmp_sum += *pt_x++ * *pt_A++; - } - - suma += x[i] * tmp_sum; - } - - return suma; -} - - -/*--------------------------------------------------------------------------------* - * polezero_filter() - * - * Y(Z)=X(Z)(b[0]+b[1]z^(-1)+..+b[L]z^(-L))/(a[0]+a[1]z^(-1)+..+a[M]z^(-M)) - * mem[n]=x[n]+cp[0]mem[n-1]+..+cp[M-1]mem[n-M], where cp[i]=-a[i+1]/a[0] - * y[n]=cz[0]mem[n]+cz[1]mem[n-1]+..+cz[L]mem[n-L], where cz[i]=b[i]/a[0] - * mem={mem[n-K] mem[n-K+1] . . . . mem[n-2] mem[n-1]}, where K=max(L,M) - * - * a[0] must be equal to 1.0f! - *---------------------------------------------------------------------------------*/ - -void polezero_filter( - const float *in, /* i : input vector */ - float *out, /* o : output vector */ - const int16_t N, /* i : input vector size */ - const float *b, /* i : numerator coefficients */ - const float *a, /* i : denominator coefficients */ - const int16_t order, /* i : filter order */ - float *mem /* i/o: filter memory */ -) -{ - int16_t i, j, k; - - - for ( i = 0; i < order; i++ ) - { - out[i] = in[i] * b[0]; - for ( j = 0; j < i; j++ ) - { - out[i] += in[i - 1 - j] * b[j + 1] - out[i - 1 - j] * a[j + 1]; - } - - for ( k = order - 1; j < order; j++, k-- ) - { - out[i] += mem[k] * b[j + 1] - mem[k + order] * a[j + 1]; - } - } - - for ( ; i < N; i++ ) - { - out[i] = in[i] * b[0]; - for ( j = 0; j < order; j++ ) - { - out[i] += in[i - 1 - j] * b[j + 1] - out[i - 1 - j] * a[j + 1]; - } - } - - for ( i = 0; i < order; i++ ) - { - mem[i] = in[N - order + i]; - mem[i + order] = out[N - order + i]; - } - - return; -} - -#define WMC_TOOL_SKIP -static float fleft_shift( float input, const int16_t shift ) -{ - return ( input * (float) pow( 2.0, (double) shift ) ); -} - -static float fright_shift( float input, const int16_t shift ) -{ - return ( input * (float) pow( 0.5, (double) shift ) ); -} -#undef WMC_TOOL_SKIP - - -/*--------------------------------------------------------------------------------* - * root_a() - * - * Implements a quadratic approximation to sqrt(a) - * Firstly, a is normalized to lie between 0.25 & 1.0 - * by shifting the input left or right by an even number of - * shifts. Even shifts represent powers of 4 which, after - * the sqrt, can easily be converted to powers of 2 and are - * easily dealt with. - * At the heart of the algorithm is a quadratic - * approximation of the curve sqrt(a) for 0.25 <= a <= 1.0. - * Sqrt(a) approx = 0.27 + 1.0127 * a - 0.2864 * a^2 - * - *---------------------------------------------------------------------------------*/ - -float root_a( - float a ) -{ - int16_t shift_a; - float mod_a; - float approx; - - if ( a <= 0.0f ) - { - return 0.0; - } - -#define WMC_TOOL_SKIP - /* This next piece of code implements a "norm" function */ - /* and returns the shift needed to scale "a" to have a */ - /* 1 in the (MSB-1) position. This is equivalent to */ - /* giving a value between 0.5 & 1.0. */ - mod_a = a; - - shift_a = 0; - while ( mod_a > 1.0 ) - { - mod_a /= 2.0; - shift_a--; - } - - while ( mod_a < 0.5 ) - { - mod_a *= 2.0; - shift_a++; - } -#undef WMC_TOOL_SKIP - - shift_a &= 0xfffe; - mod_a = fleft_shift( a, shift_a ); - - approx = 0.27f + 1.0127f * mod_a - 0.2864f * mod_a * mod_a; - - approx = fright_shift( approx, ( shift_a >> 1 ) ); - - return ( approx ); -} - -/*--------------------------------------------------------------------------------* - * root_a_over_b() - * - * Implements an approximation to sqrt(a/b) - * Firstly a & b are normalized to lie between 0.25 & 1.0 - * by shifting the inputs left or right by an even number - * of shifts. - * Even shifts represent powers of 4 which, after the sqrt, - * become powers of 2 and are easily dealt with. - * At the heart of the algorithm is an approximation of the - * curve sqrt(a/b) for 0.25 <= a <= 1.0 & 0.25 <= b <= 1.0. - * Given the value of b, the 2nd order coefficients p0, p1 - * & p2 can be determined so that... - * Sqrt(a/b) approx = p0 + p1 * a + p2 * a^2 - * where p0 approx = 0.7176 - 0.8815 * b + 0.4429 * b^2 - * p1 approx = 2.6908 - 3.3056 * b + 1.6608 * b^2 - * p2 approx = -0.7609 + 0.9346 * b - 0.4695 * b^2 - * - *---------------------------------------------------------------------------------*/ - -float root_a_over_b( - float a, - float b ) -{ - int16_t shift_a, shift_b, shift; - float mod_a, mod_b; - float p2 = -0.7609f; - float p1 = 2.6908f; - float p0 = 0.7176f; - float b_sqr; - float approx; - - if ( ( a <= 0.0f ) || ( b <= 0.0f ) ) - { - return 0.0; - } -#define WMC_TOOL_SKIP - if ( isinf( a ) ) -#undef WMC_TOOL_SKIP - { - return FLT_MAX; - } -#define WMC_TOOL_SKIP - if ( isinf( b ) ) -#undef WMC_TOOL_SKIP - { - return 0.f; - } - - a += 0x00000001; - b += 0x00000001; - -#define WMC_TOOL_SKIP - /* This next piece of code implements a "norm" function */ - /* and returns the shift needed to scale "a" to have a */ - /* 1 in the (MSB-1) position. This is equivalent to */ - /* giving a value between 0.5 & 1.0. */ - mod_a = a; - - shift_a = 0; - while ( mod_a > 1.0 ) - { - mod_a /= 2.0; - shift_a--; - } - - while ( mod_a < 0.5 ) - { - mod_a *= 2.0; - shift_a++; - } -#undef WMC_TOOL_SKIP - - shift_a &= 0xfffe; - mod_a = fleft_shift( a, shift_a ); - -#define WMC_TOOL_SKIP - /* This next piece of code implements a "norm" function */ - /* and returns the shift needed to scale "b" to have a */ - /* 1 in the (MSB-1) position. This is equivalent to */ - /* giving a value between 0.5 & 1.0. */ - mod_b = b; - - shift_b = 0; - while ( mod_b > 1.0 ) - { - mod_b /= 2.0; - shift_b--; - } - - while ( mod_b < 0.5 ) - { - mod_b *= 2.0; - shift_b++; - } -#undef WMC_TOOL_SKIP - - shift_b &= 0xfffe; - mod_b = fleft_shift( b, shift_b ); - - shift = ( shift_b - shift_a ) >> 1; - - b_sqr = mod_b * mod_b; - - p2 += 0.9346f * mod_b + -0.4695f * b_sqr; - p1 += -3.3056f * mod_b + 1.6608f * b_sqr; - p0 += -0.8815f * mod_b + 0.4429f * b_sqr; - - approx = p0 + p1 * mod_a + p2 * mod_a * mod_a; - - approx = fleft_shift( approx, shift ); - - return ( approx ); -} - -/*--------------------------------------------------------------------------------* - * rint_new() - * - * Round to the nearest integer with mid-point exception - *---------------------------------------------------------------------------------*/ - -double rint_new( - double x ) -{ - int16_t a; - - /* middle value point test */ - if ( ceil( x + 0.5 ) == floor( x + 0.5 ) ) - { - a = (int16_t) ceil( x ); - - if ( a % 2 == 0 ) - { - return ceil( x ); - } - else - { - return floor( x ); - } - } - else - { - return floor( x + 0.5 ); - } -} - - -/*-------------------------------------------------------------------* - * anint() - * - * Round to the nearest integer. - *-------------------------------------------------------------------*/ - -double anint( - double x ) -{ - return ( x ) >= 0 ? (int32_t) ( ( x ) + 0.5 ) : (int32_t) ( (x) -0.5 ); -} - -/*-------------------------------------------------------------------* - * is_numeric_float() - * - * Returns 0 for all NaN and Inf values defined according to IEEE 754 - * floating point number's definition. Returns 1 for numeric values. - *-------------------------------------------------------------------*/ - -int16_t is_numeric_float( - float x ) -{ -#ifndef BASOP_NOGLOB - union float_int -#else /* BASOP_NOGLOB */ - union float_int -#endif /* BASOP_NOGLOB */ - { - float float_val; - int32_t int_val; - } float_int; - - float_int.float_val = x; - - return ( ( float_int.int_val & 0x7f800000 ) != 0x7f800000 ); -} - -/*-------------------------------------------------------------------* - * delay_signal_float() - * - * Delay buffer by defined number of samples - *-------------------------------------------------------------------*/ - -void delay_signal_float( - float x[], /* i/o: signal to be delayed */ - const int16_t len, /* i : length of the input signal */ - float mem[], /* i/o: synchronization memory */ - const int16_t delay /* i : delay in samples */ -) -{ - float tmp_buffer[L_FRAME48k]; - - mvr2r( mem, tmp_buffer, delay ); - mvr2r( x + len - delay, mem, delay ); - mvr2r( x, x + delay, len - delay ); - mvr2r( tmp_buffer, x, delay ); - - return; -} diff --git a/lib_com/tools_fx.c b/lib_com/tools_fx.c index 62766e3b76035193c8732501a0eefa8e9ff0fc87..6f46fdfa3c3ecce8ba76d364ee0eb226a49c2b90 100644 --- a/lib_com/tools_fx.c +++ b/lib_com/tools_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other @@ -50,7 +50,6 @@ #include "basop32.h" #include "wmc_auto.h" #include "prot_fx_enc.h" -#include "prot.h" #include "ivas_prot_fx.h" #define INV_BANDS10 3277 /* 1/10 in Q15 */ @@ -242,26 +241,6 @@ void fix2f_16( Word16 *var_fix, float *var_flt, Word32 expo ) #undef WMC_TOOL_SKIP -int16_t norm_ul( uint32_t UL_var1 ) -{ - int16_t var_out; - - if ( UL_var1 == 0 ) - { - var_out = 0; - } - else - { - for ( var_out = 0; UL_var1 < (uint32_t) 0x80000000U; var_out++ ) - { - UL_var1 <<= 1; - } - } - BASOP_CHECK(); - - return ( var_out ); -} - /*-------------------------------------------------------------------* * usdequant_fx() * @@ -279,13 +258,9 @@ Word16 usdequant_fx( /* Qx*/ Word32 L_tmp; /*g = idx * delta + qlow;*/ - L_tmp = L_deposit_l( qlow ); /*Qx */ - L_tmp = L_mac( L_tmp, idx, delta ); /*Qx */ -#ifdef BASOP_NOGLOB + L_tmp = L_deposit_l( qlow ); /*Qx */ + L_tmp = L_mac( L_tmp, idx, delta ); /*Qx */ g = round_fx_sat( L_shl_sat( L_tmp, 16 ) ); /*Qx */ -#else - g = round_fx( L_shl( L_tmp, 16 ) ); /*Qx */ -#endif return ( g ); } @@ -316,26 +291,17 @@ Word16 usquant_fx( /* o: index of the winning codeword */ /* idx = (short)( (x - qlow)/delta + 0.5f); */ exp = norm_s( delta ); - tmp = div_s( shl( 1, sub( 14, exp ) ), delta ); /*Q(29-exp-(Qx-1))->Q(30-exp-Qx) */ -#ifdef BASOP_NOGLOB + tmp = div_s( shl( 1, sub( 14, exp ) ), delta ); /*Q(29-exp-(Qx-1))->Q(30-exp-Qx) */ L_tmp = L_mult( sub_o( x, qlow, &Overflow ), tmp ); /*Q(31-exp) */ idx = extract_l( L_shr_r( L_add( L_tmp, shl_o( 1, sub( 30, exp ), &Overflow ) ), sub( 31, exp ) ) ); /*Q0 */ -#else /* BASOP_NOGLOB */ - L_tmp = L_mult( sub( x, qlow ), tmp ); /*Q(31-exp) */ - idx = extract_l( L_shr_r( L_add( L_tmp, shl( 1, sub( 30, exp ) ) ), sub( 31, exp ) ) ); /*Q0 */ -#endif /* BASOP_NOGLOB */ idx = s_min( idx, sub( cbsize, 1 ) ); idx = s_max( idx, 0 ); /* *xq = idx*delta + qlow; */ - L_tmp = L_deposit_l( qlow ); /*Qx */ - L_tmp = L_mac( L_tmp, idx, delta ); /*Qx */ -#ifdef BASOP_NOGLOB + L_tmp = L_deposit_l( qlow ); /*Qx */ + L_tmp = L_mac( L_tmp, idx, delta ); /*Qx */ *xq = round_fx_o( L_shl_o( L_tmp, 16, &Overflow ), &Overflow ); /*Qx */ -#else - *xq = round_fx( L_shl( L_tmp, 16 ) ); /*Qx */ -#endif return idx; } /*-------------------------------------------------------------------* @@ -408,16 +374,30 @@ Word32 sum2_fx( /* o : sum of all squared vector elements L_tmp = L_deposit_l( 0 ); FOR( i = 0; i < lvec; i++ ) { -#ifdef BASOP_NOGLOB L_tmp = L_mac_o( L_tmp, vec[i], vec[i], &Overflow ); /*Q(2x+1) */ -#else /* BASOP_NOGLOB */ - L_tmp = L_mac( L_tmp, vec[i], vec[i] ); /*Q(2x+1) */ -#endif /* BASOP_NOGLOB */ } return L_tmp; } +Word64 sum2_fx_no_sat( /* o : sum of all squared vector elements Q(2*Qx)*/ + const Word16 *vec, /* i : input vector Qx*/ + const Word16 lvec /* i : length of input vector */ +) +{ + Word16 i; + Word64 sum; + + sum = 0; + move64(); + FOR( i = 0; i < lvec; i++ ) + { + sum = W_mac0_16_16( sum, vec[i], vec[i] ); // 2*Qx + } + + return sum; +} + Word32 sum_32_fx( const Word32 *vec, /* i : input vector */ const Word16 lvec, /* i : length of input vector */ @@ -456,11 +436,7 @@ Word32 sum2_fx_mod( /* o : sum of all squared vector element L_tmp = L_deposit_l( 0 ); FOR( i = 0; i < lvec; i++ ) { -#ifdef BASOP_NOGLOB L_tmp = L_add_o( L_tmp, L_shr( L_mult_o( vec[i], vec[i], &Overflow ), 9 ), &Overflow ); -#else - L_tmp = L_add( L_tmp, L_shr( L_mult( vec[i], vec[i] ), 9 ) ); -#endif } return L_tmp; @@ -762,11 +738,7 @@ void Copy_Scale_sig( } FOR( i = 0; i < lg; i++ ) { -#ifdef BASOP_NOGLOB y[i] = shl_o( x[i], exp0, &Overflow ); -#else - y[i] = shl( x[i], exp0 ); -#endif move16(); /* saturation can occur here */ } } @@ -775,7 +747,7 @@ void Copy_Scale_sig( * * Up/down scale a 16 bits vector x and move it into y *-------------------------------------------------------------------*/ -void Copy_Scale_sig_16_32( +void Copy_Scale_sig_16_32_DEPREC( const Word16 x[], /* i : signal to scale input Qx */ Word32 y[], /* o : scaled signal output Qx */ const Word16 lg, /* i : size of x[] Q0 */ @@ -804,20 +776,22 @@ void Copy_Scale_sig_16_32( /*Should not happen */ FOR( i = 0; i < lg; i++ ) { -#ifdef BASOP_NOGLOB y[i] = L_deposit_l( shl_o( x[i], exp0, &Overflow ) ); -#else - y[i] = L_deposit_l( shl( x[i], exp0 ) ); -#endif move32(); } return; } -#ifdef BASOP_NOGLOB - tmp = shl_o( 1, exp0, &Overflow ); +#ifdef FIX_ISSUE_1237 +#ifdef DEBUGGING + if ( exp0 >= 16 ) + { + printf( "Issue in Copy_Scale_sig_16_32_DEPREC\n" ); + } #else - tmp = shl( 1, exp0 ); + assert( exp0 < 16 ); +#endif #endif + tmp = shl_o( 1, exp0, &Overflow ); FOR( i = 0; i < lg; i++ ) { y[i] = L_mult0( x[i], tmp ); @@ -854,20 +828,12 @@ void Copy_Scale_sig_16_32_no_sat( /*Should not happen */ FOR( i = 0; i < lg; i++ ) { -#ifdef BASOP_NOGLOB y[i] = L_deposit_l( shl_o( x[i], exp0, &Overflow ) ); -#else - y[i] = L_deposit_l( shl( x[i], exp0 ) ); -#endif move32(); } return; } -#ifdef BASOP_NOGLOB L_tmp = L_shl_o( 1, exp0 - 1, &Overflow ); -#else - tmp = shl( 1, exp0 ); -#endif FOR( i = 0; i < lg; i++ ) { // y[i] = L_mult0(x[i], L_tmp); @@ -895,11 +861,7 @@ void Copy_Scale_sig_32_16( { FOR( i = 0; i < lg; i++ ) { -#ifdef BASOP_NOGLOB y[i] = round_fx_o( L_shl_o( x[i], tmp, &Overflow ), &Overflow ); -#else - y[i] = round_fx( L_shl( x[i], tmp ) ); -#endif move16(); } } @@ -907,11 +869,7 @@ void Copy_Scale_sig_32_16( { FOR( i = 0; i < lg; i++ ) { -#ifdef BASOP_NOGLOB y[i] = round_fx_o( x[i], &Overflow ); -#else - y[i] = round_fx( x[i] ); -#endif move16(); } } @@ -933,14 +891,14 @@ void Scale_sig32( Flag Overflow = 0; move32(); #endif + IF( 0 == exp0 ) + { + return; + } FOR( i = 0; i < lg; i++ ) { -#ifdef BASOP_NOGLOB x[i] = L_shl_o( x[i], exp0, &Overflow ); -#else - x[i] = L_shl( x[i], exp0 ); -#endif move32(); /* saturation can occur here */ } } @@ -990,37 +948,45 @@ void Scale_sig( { FOR( i = 0; i < lg; i++ ) { -#ifdef BASOP_NOGLOB x[i] = shl_sat( x[i], exp0 ); -#else /* BASOP_NOGLOB */ - x[i] = shl( x[i], exp0 ); -#endif /* BASOP_NOGLOB */ move16(); /* saturation can occur here */ } return; } IF( exp0 < 0 ) { -#ifdef BASOP_NOGLOB tmp = shl_sat( -32768, exp0 ); /* we use negative to correctly represent 1.0 */ -#else - BASOP_SATURATE_WARNING_OFF_EVS - tmp = shl( -32768, exp0 ); /* we use negative to correctly represent 1.0 */ - BASOP_SATURATE_WARNING_ON_EVS -#endif FOR( i = 0; i < lg; i++ ) { -#ifdef BASOP_NOGLOB x[i] = msu_r_sat( 0, x[i], tmp ); -#else - x[i] = msu_r( 0, x[i], tmp ); -#endif move16(); /* msu instead of mac because factor is negative */ } return; } } +/*-------------------------------------------------------------------* + * scale_sig + * Up/down scale a 16 bits vector + *-------------------------------------------------------------------*/ +void scale_sig( + Word16 x[], /* i/o: signal to scale Qx */ + const Word16 lg, /* i : size of x[] Q0 */ + const Word16 exp0 /* i : exponent: x = round(x << exp) Qx exp */ +) +{ + Word16 i; + + IF( exp0 != 0 ) + { + FOR( i = 0; i < lg; i++ ) + { + x[i] = shl( x[i], exp0 ); + move16(); + } + } +} + /*---------------------------------------------------------------------* * mean() * @@ -1086,11 +1052,7 @@ void Vr_add( FOR( i = 0; i < Len; i++ ) { -#ifdef BASOP_NOGLOB out[i] = add_sat( in1[i], in2[i] ); -#else /* BASOP_NOGLOB */ - out[i] = add( in1[i], in2[i] ); -#endif /* BASOP_NOGLOB */ move16(); } } @@ -1212,6 +1174,37 @@ Word16 maximum_fx( /* o : index of the maximum value in t return ind; } +Word16 maximum_exp_fx( /* o : index of the maximum value in the input vector */ + const Word16 *vec_fx, /* i : input vector */ + const Word16 *exp_vec, /* i : exponents of input vector */ + const Word16 lvec_fx /* i : length of input vector */ +) +{ + Word16 j, ind; + Word16 tmp, exp; + ind = 0; + move16(); + tmp = vec_fx[0]; + move16(); + exp = exp_vec[0]; + move16(); + + FOR( j = 1; j < lvec_fx; j++ ) + { + IF( LT_16( tmp, shr_sat( vec_fx[j], sub( exp, exp_vec[j] ) ) ) ) + { + ind = j; + move16(); + tmp = vec_fx[j]; + move16(); + exp = exp_vec[j]; + move16(); + } + } + + return ind; +} + /*---------------------------------------------------------------------* * maximum_abs_16_fx() * @@ -1499,12 +1492,8 @@ Word32 var_fx_32( /* o: variance of vector Q v = L_deposit_l( 0 ); FOR( i = 0; i < len; i++ ) { - tmp = sub( x[i], m ); /*Qx */ -#ifdef BASOP_NOGLOB + tmp = sub( x[i], m ); /*Qx */ v = L_mac0_sat( v, tmp, tmp ); /*(Qx+Qx) */ -#else /* BASOP_NOGLOB */ - v = L_mac0( v, tmp, tmp ); /*(Qx+Qx) */ -#endif /* BASOP_NOGLOB */ } L_tmp = Mult_32_16( v, inv_len ); /*Q(14-exp+Qx+Qx) */ v = L_shl( L_tmp, add( exp, sub( 2, Qx ) ) ); /*Qx+16 */ @@ -1545,11 +1534,7 @@ Word32 var_fx_32in_32out( /* o: variance of vector * convolution are considered. *-------------------------------------------------------------------*/ -#ifdef BASOP_NOGLOB /*Critical overflow */ Flag conv_fx( -#else -void conv_fx( -#endif const Word16 x[], /* i : input vector Q_new*/ const Word16 h[], /* i : impulse response (or second input vector) Q(15)*/ Word16 y[], /* o : output vetor (result of convolution) 12 bits*/ @@ -1570,22 +1555,12 @@ void conv_fx( L_sum = L_mult( x[0], h[n] ); FOR( i = 1; i < n; i++ ) { -#ifdef BASOP_NOGLOB L_sum = L_mac_o( L_sum, x[i], h[n - i], &Overflow ); -#else - L_sum = L_mac( L_sum, x[i], h[n - i] ); -#endif } -#ifdef BASOP_NOGLOB y[n] = mac_ro( L_sum, x[i], h[0], &Overflow ); -#else - y[n] = mac_r( L_sum, x[i], h[0] ); -#endif move16(); } -#ifdef BASOP_NOGLOB return Overflow; -#endif } /*-------------------------------------------------------------------* @@ -1595,11 +1570,7 @@ void conv_fx( * All vectors are of length L. Only the first L samples of the * convolution are considered. *-------------------------------------------------------------------*/ -#ifdef BASOP_NOGLOB /*Critical overflow */ Flag conv_fx_32( -#else -void conv_fx_32( -#endif const Word16 x[], /* i : input vector Q_new*/ const Word16 h[], /* i : impulse response (or second input vector) Q(15)*/ Word32 y[], /* o : output vetor (result of convolution) 12 bits*/ @@ -1622,9 +1593,7 @@ void conv_fx_32( y[n] = L_mac_o( L_sum, x[i], h[0], &Overflow ); move32(); } -#ifdef BASOP_NOGLOB return Overflow; -#endif } Word16 var_fx( /* o: variance of vector Qx*/ const Word16 *x, /* i: input vector Qx*/ @@ -1653,20 +1622,11 @@ Word16 var_fx( /* o: variance of vector Qx*/ v = L_deposit_l( 0 ); FOR( i = 0; i < len; i++ ) { -#ifdef BASOP_NOGLOB tmp = sub_sat( x[i], m ); /*Qx */ v = L_mac0_sat( v, tmp, tmp ); /*(Qx+Qx) */ -#else - tmp = sub( x[i], m ); /*Qx */ - v = L_mac0( v, tmp, tmp ); /*(Qx+Qx) */ -#endif } - L_tmp = Mult_32_16( v, inv_len ); /*Q(14-exp+Qx+Qx) */ -#ifdef BASOP_NOGLOB + L_tmp = Mult_32_16( v, inv_len ); /*Q(14-exp+Qx+Qx) */ v_16 = round_fx_sat( L_shl_sat( L_tmp, add( exp, sub( 2, Qx ) ) ) ); /*Qx */ -#else /* BASOP_NOGLOB */ - v_16 = round_fx( L_shl( L_tmp, add( exp, sub( 2, Qx ) ) ) ); /*Qx */ -#endif /* BASOP_NOGLOB */ return v_16; } @@ -1758,11 +1718,7 @@ void Vr_subt( FOR( i = 0; i < N; i++ ) { -#ifdef BASOP_NOGLOB y[i] = sub_sat( x1[i], x2[i] ); -#else /* BASOP_NOGLOB */ - y[i] = sub( x1[i], x2[i] ); -#endif /* BASOP_NOGLOB */ move16(); } } @@ -1957,7 +1913,6 @@ Word16 w_vquant_fx( { dist = L_deposit_l( 0 ); -#ifdef BASOP_NOGLOB tmp = sub_o( x[3], shr( cb[j++], Qx ), &Overflow ); if ( weights[3] != 0 ) { @@ -1978,28 +1933,6 @@ Word16 w_vquant_fx( { dist = L_mac0_o( dist, tmp, tmp, &Overflow ); } -#else - tmp = sub( x[3], shr( cb[j++], Qx ) ); - if ( weights[3] != 0 ) - { - dist = L_mac0( dist, tmp, tmp ); - } - tmp = sub( x[2], shr( cb[j++], Qx ) ); - if ( weights[2] != 0 ) - { - dist = L_mac0( dist, tmp, tmp ); - } - tmp = sub( x[1], shr( cb[j++], Qx ) ); - if ( weights[1] != 0 ) - { - dist = L_mac0( dist, tmp, tmp ); - } - tmp = sub( x[0], shr( cb[j++], Qx ) ); - if ( weights[0] != 0 ) - { - dist = L_mac0( dist, tmp, tmp ); - } -#endif if ( LT_32( dist, minDist ) ) { idx = c; @@ -2029,7 +1962,6 @@ Word16 w_vquant_fx( { dist = L_deposit_l( 0 ); -#ifdef BASOP_NOGLOB tmp = sub_o( x[0], shr( cb[j++], Qx ), &Overflow ); if ( weights[0] != 0 ) { @@ -2050,28 +1982,6 @@ Word16 w_vquant_fx( { dist = L_mac0_o( dist, tmp, tmp, &Overflow ); } -#else - tmp = sub( x[0], shr( cb[j++], Qx ) ); - if ( weights[0] != 0 ) - { - dist = L_mac0( dist, tmp, tmp ); - } - tmp = sub( x[1], shr( cb[j++], Qx ) ); - if ( weights[1] != 0 ) - { - dist = L_mac0( dist, tmp, tmp ); - } - tmp = sub( x[2], shr( cb[j++], Qx ) ); - if ( weights[2] != 0 ) - { - dist = L_mac0( dist, tmp, tmp ); - } - tmp = sub( x[3], shr( cb[j++], Qx ) ); - if ( weights[3] != 0 ) - { - dist = L_mac0( dist, tmp, tmp ); - } -#endif if ( LT_32( dist, minDist ) ) { idx = c; @@ -2130,11 +2040,7 @@ Word16 emaximum_fx( /* o : return index with max energy valu emax = L_max( emax, L_tmp ); } -#ifdef BASOP_NOGLOB *ener_max = L_shr_sat( emax, add( Qvec, Qvec ) ); -#else /* BASOP_NOGLOB */ - *ener_max = L_shr( emax, add( Qvec, Qvec ) ); -#endif /* BASOP_NOGLOB */ move32(); return ind; @@ -2171,11 +2077,7 @@ Word16 emaximum_32fx( /* o : return index with max energy va } } -#ifdef BASOP_NOGLOB *ener_max = W_extract_l( W_shr( emax, add( Qvec, Qvec ) ) ); -#else /* BASOP_NOGLOB */ - *ener_max = L_shr( emax, add( Qvec, Qvec ) ); -#endif /* BASOP_NOGLOB */ move32(); return ind; @@ -2219,11 +2121,7 @@ Word32 sum32_fx( /* o : sum of all vector elements tmp = L_deposit_l( 0 ); FOR( i = 0; i < lvec; i++ ) { -#ifdef BASOP_NOGLOB tmp = L_add_sat( tmp, vec[i] ); /*Qx */ -#else /* BASOP_NOGLOB */ - tmp = L_add( tmp, vec[i] ); /*Qx */ -#endif /* BASOP_NOGLOB */ } return tmp; @@ -2239,11 +2137,7 @@ Word16 sum16_fx( /* o : sum of all vector elements move16(); FOR( i = 0; i < lvec; i++ ) { -#ifdef BASOP_NOGLOB tmp = add_sat( tmp, vec[i] ); /*Qx */ -#else - tmp = add( tmp, vec[i] ); /*Qx */ -#endif } return tmp; @@ -2486,30 +2380,17 @@ void pz_filter_sp_fx( Lacc = L_deposit_h( x[i] ); /* Lacc in Q(16+Qn)*/ Lacc = L_shl( Lacc, s ); /* Lacc=x[i] in Q(16+Qn-2Qa+1)*/ FOR( j = PDR - 1; j >= 0; j-- ) -#ifdef BASOP_NOGLOB Lacc = L_msu_sat( Lacc, buf[j], a[j + 1] ); /*Q(16+Qn-2Qa+1)*/ -#else - Lacc = L_msu( Lacc, buf[j], a[j + 1] ); /*Q(16+Qn-2Qa+1)*/ -#endif Lacc = L_shr( Lacc, 1 ); -#ifdef BASOP_NOGLOB Ltemp1 = L_add_sat( L_shl_sat( Lacc, Qa ), 0x08000 ); -#else - Ltemp1 = L_add( L_shl( Lacc, Qa ), 0x08000 ); -#endif s_mem = extract_h( Ltemp1 ); Lacc = L_deposit_l( 0 ); FOR( j = PNR - 1; j >= 0; j-- ) -#ifdef BASOP_NOGLOB Lacc = L_mac_sat( Lacc, buf[j], b[j + 1] ); Lacc = L_mac_sat( Lacc, s_mem, b[0] ); -#else - Lacc = L_mac( Lacc, buf[j], b[j + 1] ); - Lacc = L_mac( Lacc, s_mem, b[0] ); -#endif /* Lacc in Q(1+Qc+Qn-Qa)*/ FOR( j = s_max( PDR, PNR ) - 1; j > 0; j-- ) @@ -2521,12 +2402,8 @@ void pz_filter_sp_fx( buf[0] = s_mem; move16(); -#ifdef BASOP_NOGLOB Ltemp1 = L_add_sat( L_shr_sat( Lacc, s ), 0x08000 ); /* Ltemp1 in Qc+Qa+Qn=Q(Qn) */ -#else - Ltemp1 = L_add( L_shr( Lacc, s ), 0x08000 ); /* Ltemp1 in Qc+Qa+Qn=Q(Qn) */ -#endif - y[i] = extract_h( Ltemp1 ); /* y[i] in Qn */ + y[i] = extract_h( Ltemp1 ); /* y[i] in Qn */ move16(); } } @@ -2584,27 +2461,15 @@ Word32 root_a_over_b_fx( } exp_num = norm_l( b ); -#ifdef BASOP_NOGLOB num = round_fx_o( L_shl_o( b, exp_num, &Overflow ), &Overflow ); -#else - num = round_fx( L_shl( b, exp_num ) ); -#endif exp_num = sub( sub( 30, exp_num ), Q_b ); exp_den = norm_l( a ); -#ifdef BASOP_NOGLOB den = round_fx_o( L_shl_o( a, exp_den, &Overflow ), &Overflow ); -#else /* BASOP_NOGLOB */ - den = round_fx( L_shl( a, exp_den ) ); -#endif /* BASOP_NOGLOB */ exp_den = sub( sub( 30, exp_den ), Q_a ); scale = shr( sub( den, num ), 15 ); -#ifdef BASOP_NOGLOB num = shl_o( num, scale, &Overflow ); -#else - num = shl( num, scale ); -#endif exp_num = sub( exp_num, scale ); tmp = div_s( num, den ); @@ -2619,6 +2484,109 @@ Word32 root_a_over_b_fx( return L_tmp; } +Word32 root_a_over_b_ivas_fx( + Word32 a, /* Q(Q_a) */ + Word16 Q_a, + Word32 b, /* Q(Q_b) */ + Word16 Q_b, + Word16 *q_out ) +{ + Word16 shift_a, shift_b, shift; + Word32 mod_a, mod_b, one_in_Q_a, one_in_Q_b, half_in_Q_a, half_in_Q_b; + Word32 a_sqr, b_sqr, p0, p1, p2, approx; + Word16 exp; + + test(); + IF( ( a <= 0 ) || ( b <= 0 ) ) + { + *q_out = 0; + move16(); + return 0; + } + + one_in_Q_a = L_shl( 1, Q_a ); // 1.0f in Q_a + one_in_Q_b = L_shl( 1, Q_b ); // 1.0f in Q_b + half_in_Q_a = L_shr( one_in_Q_a, 1 ); // 0.5f in Q_a + half_in_Q_b = L_shr( one_in_Q_b, 1 ); // 0.5f in Q_b + + a = L_add( a, one_in_Q_a ); + b = L_add( b, one_in_Q_b ); + + /* This next piece of code implements a "norm" function */ + /* and returns the shift needed to scale "a" to have a */ + /* 1 in the (MSB-1) position. This is equivalent to */ + /* giving a value between 0.5 & 1.0. */ + + mod_a = a; + move32(); + + shift_a = 0; + move16(); + WHILE( GT_32( mod_a, one_in_Q_a ) ) + { + mod_a = L_shr( mod_a, 1 ); + shift_a = sub( shift_a, 1 ); + } + + WHILE( LT_32( mod_a, half_in_Q_a ) ) + { + mod_a = L_shl( mod_a, 1 ); + shift_a = add( shift_a, 1 ); + } + + shift_a = s_and( shift_a, -2 ); + mod_a = L_shl( a, shift_a ); // Q_a + + /* This next piece of code implements a "norm" function */ + /* and returns the shift needed to scale "b" to have a */ + /* 1 in the (MSB-1) position. This is equivalent to */ + /* giving a value between 0.5 & 1.0. */ + mod_b = b; + move32(); + + shift_b = 0; + move16(); + WHILE( GT_32( mod_b, one_in_Q_b ) ) + { + mod_b = L_shr( mod_b, 1 ); + shift_b = sub( shift_b, 1 ); + } + + WHILE( LT_32( mod_b, half_in_Q_b ) ) + { + mod_b = L_shl( mod_b, 1 ); + shift_b = add( shift_b, 1 ); + } + + shift_b = s_and( shift_b, -2 ); + mod_b = L_shl( b, shift_b ); // Q_b + + shift = shr( sub( shift_b, shift_a ), 1 ); + + a_sqr = W_extract_h( W_shl( W_mult0_32_32( mod_a, mod_a ), sub( 32, Q_a ) ) ); // Q_a + b_sqr = W_extract_h( W_shl( W_mult0_32_32( mod_b, mod_b ), sub( 32, Q_b ) ) ); // Q_b + + p2 = L_shl( -408505077 /* -0.7609f in Q29 */, sub( Q_b, 31 ) ); // Qb-2 + p1 = L_shl( 1444612250 /* 2.6908f in Q29 */, sub( Q_b, 31 ) ); // Qb-2 + p0 = L_shl( 385258566 /* 0.7176f in Q29 */, sub( Q_b, 31 ) ); // Qb-2 + + p2 = Madd_32_32( Madd_32_32( p2, 501759554 /* 0.9346f in Q29*/, mod_b ), -252060893 /* -0.4695f in Q29 */, b_sqr ); // Q_b-2 + p1 = Madd_32_32( Madd_32_32( p1, -1774680487 /* -3.3056f in Q29 */, mod_b ), 891635211 /* 1.6608f in Q29 */, b_sqr ); // Q_b-2 + p0 = Madd_32_32( Madd_32_32( p0, -473251709 /* -0.8815f in Q29 */, mod_b ), 237780127 /* 0.4429f in Q29 */, b_sqr ); // Q_b-2 + + /* approx = p0 + p1 * mod_a + p2 * mod_a * mod_a; */ + approx = Madd_32_32( Mpy_32_32( p1, mod_a ), p2, a_sqr ); // Q_a+Q_b-33 + approx = L_add( approx, L_shl( p0, sub( Q_a, 31 ) ) ); // Q_a+Q_b-33 + + exp = sub( norm_l( approx ), 1 ); + approx = L_shl( approx, exp ); // // Q_a+Q_b-33+exp + + *q_out = sub( add( sub( add( Q_a, Q_b ), 33 ), exp ), shift ); + move16(); + + return approx; +} + /*===================================================================*/ /* FUNCTION : fir_fx () */ /*-------------------------------------------------------------------*/ @@ -2672,7 +2640,6 @@ void fir_fx( const Word16 x[], /* i : input vector /* do the filtering */ FOR( i = 0; i < L; i++ ) { -#ifdef BASOP_NOGLOB s = L_mult_o( buf_in[K + i], h[0], &Overflow ); FOR( j = 1; j <= K; j++ ) @@ -2681,16 +2648,6 @@ void fir_fx( const Word16 x[], /* i : input vector } s = L_shl_o( s, shift, &Overflow ); y[i] = round_fx_o( s, &Overflow ); /*Qx */ -#else - s = L_mult( buf_in[K + i], h[0] ); - - FOR( j = 1; j <= K; j++ ) - { - s = L_mac( s, h[j], buf_in[K + i - j] ); - } - s = L_shl( s, shift ); - y[i] = round_fx( s ); /*Qx */ -#endif move16(); } } @@ -2838,18 +2795,10 @@ Word16 squant_fx( /* o: index of the winning codeword */ FOR( c = 0; c < cbsize; c++ ) { L_dist = L_deposit_l( 0 ); -#ifdef BASOP_NOGLOB tmp = sub_o( x, cb[c], &Overflow ); -#else /* BASOP_NOGLOB */ - tmp = sub( x, cb[c] ); -#endif /* BASOP_NOGLOB */ /*dist += tmp*tmp; */ -#ifdef BASOP_NOGLOB L_dist = L_mac_o( L_dist, tmp, tmp, &Overflow ); -#else /* BASOP_NOGLOB */ - L_dist = L_mac( L_dist, tmp, tmp ); -#endif /* BASOP_NOGLOB */ if ( LT_32( L_dist, L_mindist ) ) { @@ -2950,11 +2899,7 @@ void pz_filter_dp_fx( FOR( j = PDR - 1; j >= 0; j-- ) Lacc = Msub_32_16( Lacc, buf[j], a[j + 1] ); /*Q(16+Qn-2Qa+1)*/ -#ifdef BASOP_NOGLOB s_mem = L_shl_sat( Lacc, sub( Qa, 1 ) ); /*Qn-Qa+16=Qn+Qc*/ -#else - s_mem = L_shl( Lacc, sub( Qa, 1 ) ); /*Qn-Qa+16=Qn+Qc*/ -#endif Lacc = L_deposit_l( 0 ); FOR( j = PNR - 1; j >= 0; j-- ) Lacc = Madd_32_16( Lacc, buf[j], b[j + 1] ); @@ -2970,12 +2915,8 @@ void pz_filter_dp_fx( buf[0] = s_mem; move16(); -#ifdef BASOP_NOGLOB Ltemp1 = L_shr_sat( Lacc, s ); /* Ltemp1 in Qc+Qa+Qn=Q(16+Qn) */ -#else - Ltemp1 = L_shr( Lacc, s ); /* Ltemp1 in Qc+Qa+Qn=Q(16+Qn) */ -#endif - y[i] = extract_h( Ltemp1 ); /* y[i] in Qn */ + y[i] = extract_h( Ltemp1 ); /* y[i] in Qn */ move16(); } } @@ -3012,20 +2953,12 @@ void Copy_Scale_sig32( { FOR( i = 0; i < lg; i++ ) { -#ifdef BASOP_NOGLOB y[i] = L_shl_o( x[i], tmp, &Overflow ); -#else - y[i] = L_shl( x[i], tmp ); -#endif move16(); } return; } -#ifdef BASOP_NOGLOB L_tmp = L_shl_o( 1, exp0 - 1, &Overflow ); -#else - tmp = shl( 1, exp0 ); -#endif FOR( i = 0; i < lg; i++ ) { y[i] = W_extract_l( W_mult_32_32( L_tmp, x[i] ) ); @@ -3052,11 +2985,7 @@ void Copy_Scale_sig32_16( { FOR( i = 0; i < len; i++ ) { -#ifdef BASOP_NOGLOB *dst++ = round_fx_sat( *src++ ); -#else - *dst++ = round_fx( *src++ ); -#endif move16(); } return; @@ -3064,15 +2993,9 @@ void Copy_Scale_sig32_16( FOR( i = 0; i < len; i++ ) { -#ifdef BASOP_NOGLOB L_temp = L_shl_sat( *src++, exp0 ); *dst++ = round_fx_sat( L_temp ); -#else - L_temp = L_shl( *src++, exp0 ); - - *dst++ = round_fx( L_temp ); -#endif move16(); } } @@ -3222,11 +3145,7 @@ void add_vec_fx( { FOR( i = 0; i < N; i++ ) { -#ifdef BASOP_NOGLOB y[i] = add_o( x1[i], shr_ro( x2[i], Qyx2, &Overflow ), &Overflow ); -#else - y[i] = add( x1[i], shr_r( x2[i], Qyx2 ) ); -#endif move16(); } } @@ -3234,11 +3153,7 @@ void add_vec_fx( { FOR( i = 0; i < N; i++ ) { -#ifdef BASOP_NOGLOB y[i] = add_o( shr_ro( x1[i], Qyx1, &Overflow ), shr_ro( x2[i], Qyx2, &Overflow ), &Overflow ); -#else - y[i] = add( shr_r( x1[i], Qyx1 ), shr_r( x2[i], Qyx2 ) ); -#endif move16(); } } @@ -3365,39 +3280,21 @@ Word32 Calc_Energy_Autoscaled( /* o: Result (Energy) FOR( i = 0; i < j; i++ ) { /* divide by 2 so energy will be divided by 4 */ -#ifdef BASOP_NOGLOB /* Critical Overflow and all those below*/ temp = mult_ro( *signal++, 16384, &Overflow ); L_Energy = L_mac0_o( L_Energy, temp, temp, &Overflow ); -#else - temp = mult_r( *signal++, 16384 ); - L_Energy = L_mac0( L_Energy, temp, temp ); -#endif } FOR( i = j; i < len; i += 8 ) /* Process 8 Samples at a time */ { /* divide by 2 so energy will be divided by 4 */ -#ifdef BASOP_NOGLOB /* Critical Overflow */ temp = mult_ro( *signal++, 16384, &Overflow ); -#else - temp = mult_r( *signal++, 16384 ); -#endif L_temp = L_mult0( temp, temp ); FOR( j = 1; j < 8; j++ ) { -#ifdef BASOP_NOGLOB /* Critical Overflow */ temp = mult_ro( *signal++, 16384, &Overflow ); L_temp = L_mac0_o( L_temp, temp, temp, &Overflow ); -#else - temp = mult_r( *signal++, 16384 ); - L_temp = L_mac0( L_temp, temp, temp ); -#endif } -#ifdef BASOP_NOGLOB /* Critical Overflow */ L_temp = L_shr_o( L_temp, temp2, &Overflow ); -#else - L_temp = L_shr( L_temp, temp2 ); -#endif /* Here we try the addition just to check if we can sum the energy of the small (8 Iterations) loop with the total energy calculated so far without an overflow. @@ -3405,11 +3302,7 @@ Word32 Calc_Energy_Autoscaled( /* o: Result (Energy) energies are div by 2. Otherwise, nothing is done. After the 'IF', the sum is done again and will always be without an overflow. */ -#ifdef BASOP_NOGLOB /* Critical Overflow */ L_add_o( L_Energy, L_temp, &Overflow ); -#else - L_add( L_Energy, L_temp ); -#endif IF( Overflow != 0 ) { L_Energy = L_shr( L_Energy, 1 ); @@ -3418,11 +3311,7 @@ Word32 Calc_Energy_Autoscaled( /* o: Result (Energy) Overflow = 0; move16(); } -#ifdef BASOP_NOGLOB /* Critical Overflow */ L_Energy = L_add_o( L_Energy, L_temp, &Overflow ); -#else - L_Energy = L_add( L_Energy, L_temp ); -#endif } /* Calc Final Exponent (sub 2 because of the mult_r by 16384 that already divs the ener by 4) */ temp2 = sub( sub( shl( signal_exp, 1 ), temp2 ), 2 ); @@ -3494,11 +3383,7 @@ Word32 Sqrt_Ratio32( /* o: Result in Q31 exp2 = add( exp2, temp ); /* Prepare for Inverse */ -#ifdef BASOP_NOGLOB temp = round_fx_sat( L_val1 ); -#else - temp = round_fx( L_val1 ); -#endif temp = div_s( 16384, temp ); /* Mult Now */ L_val2 = Mult_32_16( L_val2, temp ); @@ -3796,17 +3681,10 @@ void Acelp_dec_total_exc( FOR( i = 0; i < L_subfr; i++ ) { -#ifdef BASOP_NOGLOB L_tmp = L_shl_sat( L_mult( gain_pit_fx, exc_fx[i + i_subfr] ), 1 ); /*Q16+Q_exc*/ exc2_fx[i + i_subfr] = round_fx_sat( L_tmp ); /*Q_exc*/ L_tmp = L_add_sat( L_tmp, L_shl_sat( L_mult( gain_code16, code_fx[i] ), 6 ) ); /*Q16+Q_exc*/ exc_fx[i + i_subfr] = round_fx_sat( L_tmp ); /*Q_exc*/ -#else - L_tmp = L_shl( L_mult( gain_pit_fx, exc_fx[i + i_subfr] ), 1 ); /*Q16+Q_exc*/ - exc2_fx[i + i_subfr] = round_fx( L_tmp ); /*Q_exc*/ - L_tmp = L_add( L_tmp, L_shl( L_mult( gain_code16, code_fx[i] ), 6 ) ); /*Q16+Q_exc*/ - exc_fx[i + i_subfr] = round_fx( L_tmp ); /*Q_exc*/ -#endif move16(); move16(); } @@ -4000,20 +3878,12 @@ Word16 dot_prod_satcontr( const Word16 *x, const Word16 *y, Word16 qx, Word16 qy { Overflow = 0; move16(); -#ifdef BASOP_NOGLOB /* Critical Overflow and all those below*/ L_tmp = L_shl_o( 1, s_max( sub( add( add( qx, qy ), 7 ), shift ), 0 ), &Overflow ); -#else /* BASOP_NOGLOB */ - L_tmp = L_shl( 1, s_max( sub( add( add( qx, qy ), 7 ), shift ), 0 ) ); -#endif /* BASOP_NOGLOB */ pt1 = tmp_tab_x; pt2 = tmp_tab_y; FOR( i = 0; i < len; i++ ) { -#ifdef BASOP_NOGLOB L_tmp = L_mac0_o( L_tmp, *pt1++, *pt2++, &Overflow ); /*Q(qx+qy-shift) */ -#else /* BASOP_NOGLOB */ - L_tmp = L_mac0( L_tmp, *pt1++, *pt2++ ); /*Q(qx+qy-shift) */ -#endif } IF( Overflow != 0 ) @@ -4461,10 +4331,11 @@ UWord32 mvl2s_r( IF( (void *) y <= (const void *) x ) { + Word32 tempd = L_shl( 1, sub( q_x, 1 ) ); FOR( i = 0; i < n; i++ ) { - temp = L_shr( x[i], sub( q_x, 1 ) ); - temp = L_shr( L_add( temp, 1 ), 1 ); + temp = L_add( x[i], tempd ); + temp = L_shr( temp, q_x ); IF( GT_32( temp, MAX16B ) ) { @@ -4485,10 +4356,11 @@ UWord32 mvl2s_r( } ELSE { + Word32 tempd = L_shl( 1, sub( q_x, 1 ) ); FOR( i = n - 1; i >= 0; i-- ) { - temp = L_shr( x[i], sub( q_x, 1 ) ); - temp = L_shr( L_add( temp, 1 ), 1 ); + temp = L_add( x[i], tempd ); + temp = L_shr( temp, q_x ); IF( GT_32( temp, MAX16B ) ) { diff --git a/lib_com/trans_inv_fx.c b/lib_com/trans_inv_fx.c index cc562c8999d960dc77257c30b538430068a4d1c3..0033e2c9e5d37a44f7ca4989d041c25881c5d0af 100644 --- a/lib_com/trans_inv_fx.c +++ b/lib_com/trans_inv_fx.c @@ -84,7 +84,9 @@ void preecho_sb_fx( UWord16 tmp_u16; Word32 mean_prev_hb_fx_loc, mean_prev_nc_fx_loc, mean_prev_fx_loc; /* */ Word16 q16p1, qmemp1, qtmp; - +#ifdef OPT_STEREO_32KBPS_V1 + Word16 shift_q = sub( 15, q_sig32 ); +#endif /* OPT_STEREO_32KBPS_V1 */ q16p1 = add( q_sig16, 1 ); qmemp1 = q16p1; @@ -93,11 +95,7 @@ void preecho_sb_fx( { mean_prev_fx_loc = L_add( *mean_prev_fx, 0 ); -#ifdef BASOP_NOGLOB mean_prev_hb_fx_loc = L_shl_sat( *mean_prev_hb_fx, shl( q_sig16, 1 ) ); /*Q0 to q_sig16*/ -#else - mean_prev_hb_fx_loc = L_shl( *mean_prev_hb_fx, shl( q_sig16, 1 ) ); /*Q0 to q_sig16*/ -#endif mean_prev_nc_fx_loc = L_add( *mean_prev_nc_fx, 0 ); framelength_m1 = sub( framelength, 1 ); nb_flag = 0; @@ -141,26 +139,33 @@ void preecho_sb_fx( /* len3xLp20 = framelength/2-(short)((float)framelength*N_ZERO_MDCT/FRAME_SIZE_MS); in float*/ fxptr1 = imdct_mem_fx; +#ifdef OPT_STEREO_32KBPS_V1 + FOR( i = 0; i < len3xLp20; i++ ) + { + *fxptr1++ = negate( extract_h( L_shl_sat( wtda_audio_fx[len3xLp20 - 1 - i], shift_q ) ) ); /*Q-1*/ + move16(); /*convert to Word16 Q-1 with saturation (saturation not a problem here) */ + } + FOR( i = 0; i < framelength >> 1; i++ ) + { + *fxptr1++ = negate( extract_h( L_shl_sat( wtda_audio_fx[i], shift_q ) ) ); /*Q-1*/ + move16(); /*convert to Word16 Q-1 with saturation (saturation not a problem here) */ + } +#else /* OPT_STEREO_32KBPS_V1 */ fx32ptr1 = wtda_audio_fx + len3xLp20 - 1; /*q_sig32*/ FOR( i = 0; i < len3xLp20; i++ ) { -#ifdef BASOP_NOGLOB *fxptr1++ = negate( extract_h( L_shl_sat( *fx32ptr1--, sub( 15, q_sig32 ) ) ) ); /*Q-1*/ -#else - *fxptr1++ = negate( extract_h( L_shl( *fx32ptr1--, 15 - q_sig32 ) ) ); -#endif - move16(); /*convert to Word16 Q-1 with saturation (saturation not a problem here) */ + move16(); /*convert to Word16 Q-1 with saturation (saturation not a problem here) */ } FOR( i = 0; i < L_shr( framelength, 1 ); i++ ) { -#ifdef BASOP_NOGLOB *fxptr1++ = negate( extract_h( L_shl_sat( wtda_audio_fx[i], sub( 15, q_sig32 ) ) ) ); /*Q-1*/ -#else - *fxptr1++ = negate( extract_h( L_shl( wtda_audio_fx[i], 15 - q_sig32 ) ) ); -#endif - move16(); /*convert to Word16 Q-1 with saturation (saturation not a problem here) */ + move16(); /*convert to Word16 Q-1 with saturation (saturation not a problem here) */ } +#endif /* OPT_STEREO_32KBPS_V1 */ + qmemp1 = 0; /*already in q-1*/ + move16(); subframelength = shr( framelength, LOG2_NUMSF ); /*Q0*/ subsubframelength = shr( subframelength, log2_num_subsubframes ); /*Q0*/ @@ -195,13 +200,9 @@ void preecho_sb_fx( fxptr3 = rec_sig_fx + 1; /*q_sig16*/ fxptr4 = rec_sig_fx + 2; /*q_sig16*/ -#ifdef BASOP_NOGLOB tmp_fxL1 = L_mult( shl_sat( *memfilt_lb_fx, q_sig16 ), 8192 ); /* *memfilt_lb_fx in q0 */ -#else - tmp_fxL1 = L_mult( shl( *memfilt_lb_fx, q_sig16 ), 8192 ); /* *memfilt_lb_fx in q0 */ -#endif - tmp_fxL1 = L_mac( tmp_fxL1, *fxptr3, 8192 /*Q15*/ ); /*Q16*/ - *fxptr1 = mac_r( tmp_fxL1, *fxptr2, 16384 /*Q15*/ ); /*Q0*/ + tmp_fxL1 = L_mac( tmp_fxL1, *fxptr3, 8192 /*Q15*/ ); /*Q16*/ + *fxptr1 = mac_r( tmp_fxL1, *fxptr2, 16384 /*Q15*/ ); /*Q0*/ move16(); fxptr1++; @@ -234,12 +235,8 @@ void preecho_sb_fx( } fxptr2--; -#ifdef BASOP_NOGLOB *memfilt_lb_fx = shr_sat( *fxptr2, q_sig16 ); /*Q0*/ -#else - *memfilt_lb_fx = shr( *fxptr2, q_sig16 ); -#endif - move16(); /* *memfilt_lb_fx in q0 */ + move16(); /* *memfilt_lb_fx in q0 */ /* energy of low bands 8 present and 1 future sub-frames */ sptr1 = zcr; /*Q0*/ @@ -258,16 +255,9 @@ void preecho_sb_fx( FOR( j = 0; j < NUMSF; j++ ) /* 8 present subframes */ { tmp_fx2 = sub( j, 1 ); -#ifdef BASOP_NOGLOB tmp_fx1 = shr_sat( *fxptr2, q16p1 ); /*q-1 to avoisd saturation in energy*/ tmp_fxL1 = L_mac0_sat( 25, tmp_fx1, tmp_fx1 ); /*2*(Q-1)*/ tmp_fxL2 = L_mac0_sat( 100, *fxptr3, *fxptr3 ); /*2*(q_sig16)*/ -#else - tmp_fx1 = shr( *fxptr2, q16p1 ); /*q-1 to avoisd saturation in energy*/ - tmp_fxL1 = L_mac0( 25, tmp_fx1, tmp_fx1 ); - - tmp_fxL2 = L_mac0( 100, *fxptr3, *fxptr3 ); -#endif sptr2_loc = 0; move16(); @@ -287,15 +277,9 @@ void preecho_sb_fx( *fx32ptr6 = tmp_fxL1; /*2*(Q-1)*/ move32(); } -#ifdef BASOP_NOGLOB tmp_fx1 = shr_sat( *fxptr2, q16p1 ); /*q-1 to avoisd saturation in energy*/ tmp_fxL1 = L_mac0_sat( tmp_fxL1, tmp_fx1, tmp_fx1 ); /*2*(Q-1)*/ tmp_fxL2 = L_mac0_sat( tmp_fxL2, *fxptr3, *fxptr3 ); /*2*(q_sig16)*/ -#else - tmp_fx1 = shr( *fxptr2, q16p1 ); /*q-1 to avoisd saturation in energy*/ - tmp_fxL1 = L_mac0( tmp_fxL1, tmp_fx1, tmp_fx1 ); - tmp_fxL2 = L_mac0( tmp_fxL2, *fxptr3, *fxptr3 ); -#endif cntnzcr = add( cntnzcr, 1 ); IF( L_mult0( *fxptr2, *( fxptr2 - 1 ) ) <= 0 ) { @@ -357,11 +341,7 @@ void preecho_sb_fx( move32(); if ( LT_32( *fx32ptr5, L_shr( *fx32ptr1, 1 ) ) ) { -#ifdef BASOP_NOGLOB tmp_fxL1 = L_shl_sat( L_sub_sat( *fx32ptr1, *fx32ptr5 ), 1 ); /*2*(Q-1)*/ -#else - tmp_fxL1 = L_shl( L_sub( *fx32ptr1, *fx32ptr5 ), 1 ); -#endif } *fx32ptr5 = tmp_fxL1; /*2*(Q-1)*/ move32(); @@ -383,12 +363,8 @@ void preecho_sb_fx( tmp_fx3 = sub( len3xLp20, 1 ); FOR( i = 1; i < len3xLp20; i++ ) { - tmp_fx1 = shr( *fxptr2, qmemp1 ); /*q-1 to avoisd saturation in energy*/ -#ifdef BASOP_NOGLOB + tmp_fx1 = shr( *fxptr2, qmemp1 ); /*q-1 to avoisd saturation in energy*/ tmp_fxL1 = L_mac0_sat( tmp_fxL1, tmp_fx1, tmp_fx1 ); /*2*(Q-1)*/ -#else - tmp_fxL1 = L_mac0( tmp_fxL1, tmp_fx1, tmp_fx1 ); -#endif if ( *fxptr2 * *( fxptr2 - 1 ) <= 0 ) { sptr1_loc = add( sptr1_loc, 1 ); @@ -411,31 +387,19 @@ void preecho_sb_fx( FOR( j = 1; j < tmp_fx3; j++ ) /* tmp_fx3 still contains subframelength*1.2-1 */ { - tmp_fxL1 = L_mult( *fxptr2, -8192 /*Q15*/ ); /*q_sig16+Q16*/ -#ifdef BASOP_NOGLOB + tmp_fxL1 = L_mult( *fxptr2, -8192 /*Q15*/ ); /*q_sig16+Q16*/ tmp_fxL1 = L_mac_sat( tmp_fxL1, *fxptr4, -8192 ); /*q_sig16+Q16*/ tmp_fx1 = mac_r_sat( tmp_fxL1, *fxptr3, 16384 /*Q15*/ ); /*q_sig16*/ tmp_fxL2 = L_mac0_sat( tmp_fxL2, tmp_fx1, tmp_fx1 ); /*2*(q_sig16)*/ -#else - tmp_fxL1 = L_mac( tmp_fxL1, *fxptr4, -8192 ); - tmp_fx1 = mac_r( tmp_fxL1, *fxptr3, 16384 ); - - tmp_fxL2 = L_mac0( tmp_fxL2, tmp_fx1, tmp_fx1 ); -#endif fxptr2++; fxptr3++; fxptr4++; } - tmp_fxL1 = L_mult( *fxptr2, -8192 /*Q15*/ ); /*q_sig16+Q16*/ -#ifdef BASOP_NOGLOB + tmp_fxL1 = L_mult( *fxptr2, -8192 /*Q15*/ ); /*q_sig16+Q16*/ tmp_fx1 = mac_r_sat( tmp_fxL1, *fxptr3, 16384 /*Q15*/ ); /*q_sig16*/ es_mdct_hb_fx[NUMSF] = L_mac0_sat( tmp_fxL2, tmp_fx1, tmp_fx1 ); /*2*(q_sig16)*/ -#else - tmp_fx1 = mac_r( tmp_fxL1, *fxptr3, 16384 ); - es_mdct_hb_fx[NUMSF] = L_mac0( tmp_fxL2, tmp_fx1, tmp_fx1 ); -#endif move32(); max_es_hb_fx = L_add( es_mdct_hb_fx[0], 0 ); /* for memorising the max energy */ @@ -444,6 +408,17 @@ void preecho_sb_fx( move16(); FOR( i = 1; i <= NUMSF; i++ ) { +#ifdef OPT_STEREO_32KBPS_V1 + max_es_hb_fx = L_max( max_es_hb_fx, es_mdct_hb_fx[i] ); /* max energy low band, 8 present and 1 future subframes */ + + max_es_fx = L_max( max_es_fx, es_mdct_fx[i] ); /* max energy low band, 8 present and 1 future subframes */ + + if ( GE_32( es_mdct_fx[i], max_es_fx ) ) /* '=' to handle the first window*/ + { + maxind = i; + move16(); + } +#else /* OPT_STEREO_32KBPS_V1 */ IF( GE_32( es_mdct_hb_fx[i], max_es_hb_fx ) ) /* '=' to handle the first window*/ { max_es_hb_fx = L_add( es_mdct_hb_fx[i], 0 ); /* max energy low band, 8 present and 1 future subframes */ @@ -455,6 +430,7 @@ void preecho_sb_fx( maxind = i; move16(); } +#endif /* OPT_STEREO_32KBPS_V1 */ } cnt2 = cnt5 = 0; @@ -467,11 +443,7 @@ void preecho_sb_fx( move16(); } -#ifdef BASOP_NOGLOB if ( LT_32( max_es_fx, L_shl_sat( mean_prev_fx_loc, 2 ) ) ) /*OK if saturated*/ -#else - if ( LT_32( max_es_fx, L_shl( mean_prev_fx_loc, 2 ) ) ) /*OK if saturated*/ -#endif { maxind = 0; move16(); @@ -708,12 +680,8 @@ void preecho_sb_fx( FOR( i = 0; i < subsubframelength; i++ ) { - tmp_fx1 = shr( *ptr_fx, qtmp ); /* q-1, to have same shift as es_mdct_.. */ -#ifdef BASOP_NOGLOB + tmp_fx1 = shr( *ptr_fx, qtmp ); /* q-1, to have same shift as es_mdct_.. */ tmp_fxL1 = L_mac0_sat( tmp_fxL1, tmp_fx1, tmp_fx1 ); /*2*(Q-1)*/ -#else - tmp_fxL1 = L_mac0( tmp_fxL1, tmp_fx1, tmp_fx1 ); -#endif ptr_fx++; } if ( GT_32( tmp_fxL1, max_plus_es_mdct_fx ) ) @@ -721,12 +689,8 @@ void preecho_sb_fx( max_plus_es_mdct_fx = L_add( tmp_fxL1, 0 ); } -#ifdef BASOP_NOGLOB sum_plus_es_fx = L_add_sat( sum_plus_es_fx, L_shl_sat( tmp_fxL1, 2 ) ); /*2*(Q-1)*/ -#else - sum_plus_es_fx = L_add( sum_plus_es_fx, L_shl( tmp_fxL1, 2 ) ); -#endif - *fx32ptr1 = tmp_fxL1; /*2*(Q-1)*/ + *fx32ptr1 = tmp_fxL1; /*2*(Q-1)*/ fx32ptr1++; Mpy_32_16_ss( sum_plus_es_fx, inv_jp2[j], fx32ptr4, &tmp_u16 ); /* 410 for 1/80*/ if ( LT_32( *fx32ptr4, maxcrit_fx ) ) @@ -899,11 +863,7 @@ void preecho_sb_fx( fxptr1 = preechogain_fx + tmp_fx2; /*Q15*/ FOR( j = 0; j < smooth_len; j++ ) { -#ifdef BASOP_NOGLOB *fxptr1 = add_sat( *fxptr1, tmp_fx1 ); /*Q15*/ -#else - *fxptr1 = add( *fxptr1, tmp_fx1 ); -#endif move16(); tmp_fx1 = add( tmp_fx1, tmp_fx3 ); /*Q15*/ fxptr1++; @@ -941,20 +901,12 @@ void preecho_sb_fx( { savehalfe_fx = L_add( mean_prev_nc_fx_loc, 0 ); /*2*(Q-1)*/ } -#ifdef BASOP_NOGLOB mean_prev_nc_fx_loc = L_add_sat( mean_prev_nc_fx_loc, es_mdct_fx[i] ); /*2*(Q-1)*/ -#else - mean_prev_nc_fx_loc = L_add( mean_prev_nc_fx_loc, es_mdct_fx[i] ); -#endif } if ( LT_32( savehalfe_fx, L_shr( mean_prev_nc_fx_loc, 1 ) ) ) { -#ifdef BASOP_NOGLOB mean_prev_nc_fx_loc = L_shl_sat( L_sub_sat( mean_prev_nc_fx_loc, savehalfe_fx ), 1 ); /*2*(Q-1)*/ -#else - mean_prev_nc_fx_loc = L_shl( L_sub( mean_prev_nc_fx_loc, savehalfe_fx ), 1 ); -#endif } mean_prev_nc_fx_loc = L_shr( mean_prev_nc_fx_loc, 3 ); /* >> LOG2_NUMSF in fixpoint 2*(Q-1)*/ @@ -994,13 +946,8 @@ void preecho_sb_fx( mean_prev_hb_fx_loc = L_shl( tmp_fxL1, 1 ); /*2*(q_sig16)*/ } -#ifdef BASOP_NOGLOB last2_fx = L_shr( L_add_sat( es_mdct_fx[NUMSF_M1], es_mdct_fx[NUMSF_M2] ), 1 ); /*q_sig16*/ last2_hb_fx = L_shr( L_add_sat( es_mdct_hb_fx[NUMSF_M1], es_mdct_hb_fx[NUMSF_M2] ), 1 ); /*q_sig16*/ -#else - last2_fx = L_shr( L_add( es_mdct_fx[NUMSF_M1], es_mdct_fx[NUMSF_M2] ), 1 ); - last2_hb_fx = L_shr( L_add( es_mdct_hb_fx[NUMSF_M1], es_mdct_hb_fx[NUMSF_M2] ), 1 ); -#endif if ( GT_32( last2_fx, mean_prev_fx_loc ) ) { mean_prev_fx_loc = L_add( last2_fx, 0 ); @@ -1012,13 +959,9 @@ void preecho_sb_fx( } *mean_prev_fx = mean_prev_fx_loc; /*2*(Q-1)*/ move32(); -#ifdef BASOP_NOGLOB *mean_prev_hb_fx = L_shr_sat( mean_prev_hb_fx_loc, shl_sat( q_sig16, 1 ) ); /*Q0*/ -#else - *mean_prev_hb_fx = L_shr( mean_prev_hb_fx_loc, shl( q_sig16, 1 ) ); -#endif - move32(); /*save in Q0*/ - *mean_prev_nc_fx = mean_prev_nc_fx_loc; /*2*(Q-1)*/ + move32(); /*save in Q0*/ + *mean_prev_nc_fx = mean_prev_nc_fx_loc; /*2*(Q-1)*/ move32(); } diff --git a/lib_com/typedef.h b/lib_com/typedef.h index 3d86229dd6e90e93261e44def4b6235c67ba4dab..4dfd372240e39b54d0b84092257a09a144a85a8e 100644 --- a/lib_com/typedef.h +++ b/lib_com/typedef.h @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other @@ -134,6 +134,8 @@ typedef float Float32; typedef unsigned short int UNS_Word16; /* 16 bit "register" (sw*) */ +typedef int Counter; + #ifndef TYPEDEF_INITIALIZED #error types in typedef.h not initialized #endif diff --git a/lib_com/weight_a_fx.c b/lib_com/weight_a_fx.c index 78297923648004976ea8e1110f24d853272c04af..7bea66ea0b0f2194210a0a06fdcc932f7660841c 100644 --- a/lib_com/weight_a_fx.c +++ b/lib_com/weight_a_fx.c @@ -122,11 +122,7 @@ void weight_a_fx( move16(); FOR( i = 1; i < m; i++ ) { -#ifdef BASOP_NOGLOB ap[i] = round_fx_o( L_shl( L_mult0( a[i], fac ), shift ), &Overflow ); /* Q11 + shift */ -#else /* BASOP_NOGLOB */ - ap[i] = round_fx( L_shl( L_mult0( a[i], fac ), shift ) ); -#endif move16(); fac = mult_r( fac, gamma ); /* Q15 */ } diff --git a/lib_com/wi_fx.c b/lib_com/wi_fx.c index 19788dc0af989d21ec12d29937e457a4e4050c7c..7df4cb3f04098dfa42ec0d36e8885daab0e2326c 100644 --- a/lib_com/wi_fx.c +++ b/lib_com/wi_fx.c @@ -320,13 +320,8 @@ static Word16 DTFS_alignment_weight_fx( FOR( k = 0; k <= HalfLag; k++ ) { -#ifdef BASOP_NOGLOB ab1[k] = round_fx_o( L_mac0_o( L_mult0( X1.a_fx[k], X2.a_fx[k] ), X1.b_fx[k], X2.b_fx[k], &Overflow ), &Overflow ); /* Q(-15) */ ab2[k] = round_fx_o( L_msu0_o( L_mult0( X1.a_fx[k], X2.b_fx[k] ), X1.b_fx[k], X2.a_fx[k], &Overflow ), &Overflow ); /* Q(-15) */ -#else - ab1[k] = round_fx( L_mac0( L_mult0( X1.a_fx[k], X2.a_fx[k] ), X1.b_fx[k], X2.b_fx[k] ) ); /* Q(-15) */ - ab2[k] = round_fx( L_msu0( L_mult0( X1.a_fx[k], X2.b_fx[k] ), X1.b_fx[k], X2.a_fx[k] ) ); /* Q(-15) */ -#endif move16(); move16(); } @@ -349,13 +344,8 @@ static Word16 DTFS_alignment_weight_fx( FOR( k = 0; k <= HalfLag; k++ ) { -#ifdef BASOP_NOGLOB corr_fx = L_mac0_o( corr_fx, ab1[k], cos_table[s_and( temp, 511 )], &Overflow ); corr_fx = L_mac0_o( corr_fx, ab2[k], cos_table[s_and( add( temp, 128 ), 511 )], &Overflow ); -#else - corr_fx = L_mac0( corr_fx, ab1[k], cos_table[s_and( temp, 511 )] ); - corr_fx = L_mac0( corr_fx, ab2[k], cos_table[s_and( add( temp, 128 ), 511 )] ); -#endif move32(); move32(); temp = add( temp, temp1 ); @@ -368,28 +358,15 @@ static Word16 DTFS_alignment_weight_fx( move16(); } -#ifdef BASOP_NOGLOB temp1 = round_fx_o( (Word32) L_shl_o( corr_fx, Qcorr, &Overflow ), &Overflow ); /* Q(Qcorr-16) */ wcorr_fx = L_mult_o( temp1, shl_o( temp, 2, &Overflow ), &Overflow ); /* Q(Qcorr-16+13+2+1)=Q(Qcorr) */ -#else - temp1 = round_fx( (Word32) L_shl( corr_fx, Qcorr ) ); /* Q(Qcorr-16) */ - wcorr_fx = L_mult( temp1, shl( temp, 2 ) ); /* Q(Qcorr-16+13+2+1)=Q(Qcorr) */ -#endif IF( GE_16( Qmaxcorr, Qcorr ) ) { -#ifdef BASOP_NOGLOB diff_corr = L_sub_o( wcorr_fx, L_shl_o( maxcorr_fx, sub( Qcorr, Qmaxcorr ), &Overflow ), &Overflow ); /* Qcorr */ -#else - diff_corr = L_sub( wcorr_fx, L_shl( maxcorr_fx, sub( Qcorr, Qmaxcorr ) ) ); /* Qcorr */ -#endif } ELSE { -#ifdef BASOP_NOGLOB diff_corr = L_sub_o( L_shl_o( wcorr_fx, sub( Qmaxcorr, Qcorr ), &Overflow ), maxcorr_fx, &Overflow ); /* Qmaxcorr */ -#else - diff_corr = L_sub( L_shl( wcorr_fx, sub( Qmaxcorr, Qcorr ) ), maxcorr_fx ); /* Qmaxcorr */ -#endif } IF( diff_corr > 0 ) @@ -448,18 +425,10 @@ Word16 DTFS_alignment_full_fx( /* Calculating the expected alignment shift */ Eshift = mult_r( ph_offset_fx, shl( X2_DTFS_fx.lag_fx, 7 ) ); /* confirmed I<2 by smv12.org, Q7 */ find_rem( (Word16) L_FRAME, shr( add( X2_DTFS_fx.lag_fx, X1_DTFS_fx.lag_fx ), 1 ), &temp ); -#ifdef BASOP_NOGLOB temp = add_sat( shl( temp, 7 ), Eshift ); /* Q7 */ -#else - temp = add( shl( temp, 7 ), Eshift ); /* Q7 */ -#endif IF( temp < 0 ) { -#ifdef BASOP_NOGLOB temp = add_sat( temp, shl_sat( X1_DTFS_fx.lag_fx, 7 ) ); /* Q7 */ -#else - temp = add( temp, shl( X1_DTFS_fx.lag_fx, 7 ) ); /* Q7 */ -#endif } find_rem( temp, shl( X1_DTFS_fx.lag_fx, 7 ), &Eshift ); /* Q7 */ Eshift = shl( shr( Eshift, 7 ), 1 ); /* Q1 but integer */ @@ -484,13 +453,8 @@ Word16 DTFS_alignment_full_fx( FOR( k = 0; k <= HalfLag; k++ ) { -#ifdef BASOP_NOGLOB ab1[k] = round_fx_o( L_mac_o( L_mult_o( X1_DTFS_fx.a_fx[k], X2_DTFS_fx.a_fx[k], &Overflow ), X1_DTFS_fx.b_fx[k], X2_DTFS_fx.b_fx[k], &Overflow ), &Overflow ); /* Q(-15); */ ab2[k] = round_fx_o( L_msu_o( L_mult_o( X1_DTFS_fx.b_fx[k], X2_DTFS_fx.a_fx[k], &Overflow ), X1_DTFS_fx.a_fx[k], X2_DTFS_fx.b_fx[k], &Overflow ), &Overflow ); /* Q(-15); */ -#else - ab1[k] = round_fx( L_mac( L_mult( X1_DTFS_fx.a_fx[k], X2_DTFS_fx.a_fx[k] ), X1_DTFS_fx.b_fx[k], X2_DTFS_fx.b_fx[k] ) ); /* Q(-15); */ - ab2[k] = round_fx( L_msu( L_mult( X1_DTFS_fx.b_fx[k], X2_DTFS_fx.a_fx[k] ), X1_DTFS_fx.a_fx[k], X2_DTFS_fx.b_fx[k] ) ); /* Q(-15); */ -#endif } IF( FR_flag == 0 ) { @@ -520,15 +484,9 @@ Word16 DTFS_alignment_full_fx( temp1 = add( n, shl( X2_DTFS_fx.lag_fx, 1 ) ); /* add lag_fx in Q1to make positive */ FOR( k = 0; k <= HalfLag; k++ ) { -#ifdef BASOP_NOGLOB corr_fx = L_mac_o( corr_fx, ab1[k], C_fx[( 2 * temp ) % ( 4 * X2_DTFS_fx.lag_fx )], &Overflow ); corr_fx = L_mac_o( corr_fx, ab2[k], S_fx[( 2 * temp ) % ( 4 * X2_DTFS_fx.lag_fx )], &Overflow ); temp = add_o( temp, temp1, &Overflow ); -#else - corr_fx = L_mac( corr_fx, ab1[k], C_fx[( 2 * temp ) % ( 4 * X2_DTFS_fx.lag_fx )] ); - corr_fx = L_mac( corr_fx, ab2[k], S_fx[( 2 * temp ) % ( 4 * X2_DTFS_fx.lag_fx )] ); - temp = add( temp, temp1 ); -#endif } IF( GT_32( corr_fx, maxcorr_fx ) ) @@ -648,15 +606,9 @@ void Q2phaseShift_fx( FOR( k = 0; k <= HalfLag; k++ ) { temp = X_fx->a_fx[k]; -#ifdef BASOP_NOGLOB X_fx->a_fx[k] = round_fx_o( L_msu_o( L_mult_o( temp, C_fx[temp2 % ( 4 * Lag )], &Overflow ), X_fx->b_fx[k], S_fx[temp2 % ( 4 * Lag )], &Overflow ), &Overflow ); /* X.Q */ X_fx->b_fx[k] = round_fx_o( L_mac_o( L_mult_o( X_fx->b_fx[k], C_fx[temp2 % ( 4 * Lag )], &Overflow ), temp, S_fx[temp2 % ( 4 * Lag )], &Overflow ), &Overflow ); temp2 = L_add_o( temp2, (Word32) ph, &Overflow ); -#else - X_fx->a_fx[k] = round_fx( L_msu( L_mult( temp, C_fx[temp2 % ( 4 * Lag )] ), X_fx->b_fx[k], S_fx[temp2 % ( 4 * Lag )] ) ); /* X.Q */ - X_fx->b_fx[k] = round_fx( L_mac( L_mult( X_fx->b_fx[k], C_fx[temp2 % ( 4 * Lag )] ), temp, S_fx[temp2 % ( 4 * Lag )] ) ); - temp2 = L_add( temp2, (Word32) ph ); -#endif move16(); move16(); } @@ -668,15 +620,9 @@ void Q2phaseShift_fx( FOR( k = 0; k <= HalfLag; k++ ) { temp = X_fx->a_fx[k]; -#ifdef BASOP_NOGLOB X_fx->a_fx[k] = round_fx_o( L_mac_o( L_mult_o( temp, C_fx[temp2 % ( 4 * Lag )], &Overflow ), X_fx->b_fx[k], S_fx[temp2 % ( 4 * Lag )], &Overflow ), &Overflow ); /* X.Q */ X_fx->b_fx[k] = round_fx_o( L_msu_o( L_mult_o( X_fx->b_fx[k], C_fx[temp2 % ( 4 * Lag )], &Overflow ), temp, S_fx[temp2 % ( 4 * Lag )], &Overflow ), &Overflow ); temp2 = add_o( (Word16) temp2, negate( ph ), &Overflow ); -#else - X_fx->a_fx[k] = round_fx( L_mac( L_mult( temp, C_fx[temp2 % ( 4 * Lag )] ), X_fx->b_fx[k], S_fx[temp2 % ( 4 * Lag )] ) ); /* X.Q */ - X_fx->b_fx[k] = round_fx( L_msu( L_mult( X_fx->b_fx[k], C_fx[temp2 % ( 4 * Lag )] ), temp, S_fx[temp2 % ( 4 * Lag )] ) ); - temp2 = add( (Word16) temp2, negate( ph ) ); -#endif move16(); move16(); } @@ -819,25 +765,15 @@ void DTFS_to_fs_fx( move16(); exp = norm_s( X_fx->lag_fx ); - tmp = div_s( shl( 1, sub( 14, exp ) ), X_fx->lag_fx ); /* Q29-exp */ -#ifdef BASOP_NOGLOB + tmp = div_s( shl( 1, sub( 14, exp ) ), X_fx->lag_fx ); /* Q29-exp */ L_tmp1 = L_mult_o( 12800, tmp, &Overflow ); /* Q(30-exp) */ diff_fx = extract_h( L_shl_o( L_tmp1, sub( exp, 14 ), &Overflow ) ); /* Q0 */ -#else - L_tmp1 = L_mult( 12800, tmp ); /* Q(30-exp) */ - diff_fx = extract_h( L_shl( L_tmp1, sub( exp, 14 ) ) ); /* Q0 */ -#endif exp = norm_s( diff_fx ); - tmp = div_s( shl( 1, sub( 14, exp ) ), diff_fx ); /* Q29-exp */ -#ifdef BASOP_NOGLOB + tmp = div_s( shl( 1, sub( 14, exp ) ), diff_fx ); /* Q29-exp */ L_tmp1 = L_mult_o( X_fx->upper_cut_off_freq_fx, tmp, &Overflow ); /* Q(30-exp) */ nH_band = extract_h( L_shl_o( L_tmp1, sub( exp, 14 ), &Overflow ) ); /* Q0 */ -#else - L_tmp1 = L_mult( X_fx->upper_cut_off_freq_fx, tmp ); /* Q(30-exp) */ - nH_band = extract_h( L_shl( L_tmp1, sub( exp, 14 ) ) ); /* Q0 */ -#endif - nH_4kHz = mult( 10240, ( X_fx->lag_fx ) ); /* 4000/12800 in Q15 */ + nH_4kHz = mult( 10240, ( X_fx->lag_fx ) ); /* 4000/12800 in Q15 */ if ( GE_16( sub( X_fx->upper_cut_off_freq_fx, shr( (Word16) L_mult( diff_fx, nH_band ), 1 ) ), diff_fx ) ) { @@ -860,13 +796,8 @@ void DTFS_to_fs_fx( exp = norm_s( N ); tmp = div_s( shl( 1, ( sub( 14, exp ) ) ), N ); -#ifdef BASOP_NOGLOB L_tmp = L_shl_o( tmp, add( exp, 6 ), &Overflow ); inv_lag = round_fx_o( L_tmp, &Overflow ); -#else - L_tmp = L_shl( tmp, add( exp, 6 ) ); - inv_lag = round_fx( L_tmp ); -#endif Lx0 = L_deposit_h( x[0] ); Labmax = L_deposit_l( 0 ); FOR( k = 1; k <= nH; k++ ) @@ -880,13 +811,8 @@ void DTFS_to_fs_fx( move16(); FOR( n = 1; n < N; n++ ) { -#ifdef BASOP_NOGLOB L_a = L_mac0_o( L_a, x[n], C_fx[( 4 * sum ) % ( 4 * N )], &Overflow ); /* Q16 of x[n]*cos(sum) */ L_b = L_mac0_o( L_b, x[n], S_fx[( 4 * sum ) % ( 4 * N )], &Overflow ); /* Q16 of x[n]*sin(sum) */ -#else - L_a = L_mac0( L_a, x[n], C_fx[( 4 * sum ) % ( 4 * N )] ); /* Q16 of x[n]*cos(sum) */ - L_b = L_mac0( L_b, x[n], S_fx[( 4 * sum ) % ( 4 * N )] ); /* Q16 of x[n]*sin(sum) */ -#endif sum = add( sum, temp ); } La[k] = L_shr( L_a, 6 ); /* Q8 of a[k]*2.0 */ @@ -923,22 +849,13 @@ void DTFS_to_fs_fx( temp_neg = negate( temp ); FOR( n = 0; n < N - 1; n += 2 ) { -#ifdef BASOP_NOGLOB L_a = L_mac_o( L_a, x[n], temp, &Overflow ); /* Q1 */ L_a = L_mac_o( L_a, x[n + 1], temp_neg, &Overflow ); -#else - L_a = L_mac( L_a, x[n], temp ); /* Q1 */ - L_a = L_mac( L_a, x[n + 1], temp_neg ); -#endif /*temp= negate(temp); */ } if ( s_and( N, 1 ) ) /*if N is odd we need to calculate last */ { -#ifdef BASOP_NOGLOB L_a = L_mac_o( L_a, x[n], temp, &Overflow ); /* Q1 */ -#else - L_a = L_mac( L_a, x[n], temp ); /* Q1 */ -#endif } La[k] = L_shl( L_a, 7 ); @@ -965,7 +882,6 @@ void DTFS_to_fs_fx( FOR( k = 1; k <= nH; k++ ) { -#ifdef BASOP_NOGLOB X_fx->a_fx[k] = round_fx_o( L_shl_o( La[k], temp, &Overflow ), &Overflow ); /* Q(8+temp-16)=Q(temp-8) */ move16(); X_fx->a_fx[k] = mult_ro( X_fx->a_fx[k], inv_lag, &Overflow ); @@ -974,28 +890,13 @@ void DTFS_to_fs_fx( move16(); X_fx->b_fx[k] = mult_ro( X_fx->b_fx[k], inv_lag, &Overflow ); move16(); /* Q(temp-8+19+1-16)=Q(temp-4) of b[k]*2.0/N */ -#else - X_fx->a_fx[k] = round_fx( L_shl( La[k], temp ) ); /* Q(8+temp-16)=Q(temp-8) */ - move16(); - X_fx->a_fx[k] = mult_r( X_fx->a_fx[k], inv_lag ); - move16(); /* Q(temp-8+19+1-16)=Q(temp-4) of a[k]*2.0/N */ - X_fx->b_fx[k] = round_fx( L_shl( Lb[k], temp ) ); /* Q(8+temp-16)=Q(temp-8) */ - move16(); - X_fx->b_fx[k] = mult_r( X_fx->b_fx[k], inv_lag ); - move16(); /* Q(temp-8+19+1-16)=Q(temp-4) of b[k]*2.0/N */ -#endif } /* IF ( N%2 == 0 ) */ IF( s_and( N, 1 ) == 0 ) { -#ifdef BASOP_NOGLOB X_fx->a_fx[k] = round_fx_o( L_shl_o( La[k], temp, &Overflow ), &Overflow ); /* Q(8+temp-16)=Q(temp-8) */ X_fx->a_fx[k] = mult_ro( X_fx->a_fx[k], inv_lag, &Overflow ); -#else - X_fx->a_fx[k] = round_fx( L_shl( La[k], temp ) ); /* Q(8+temp-16)=Q(temp-8) */ - X_fx->a_fx[k] = mult_r( X_fx->a_fx[k], inv_lag ); -#endif move16(); move16(); /* Q(temp-8+19+1-16)=Q(temp-4) of a[k]*1.0/N */ X_fx->b_fx[k] = 0; @@ -1249,11 +1150,7 @@ static void DTFS_transform_fx( m = L_add( 1000 * LL - OSLENGTH / 2, add( l1, j ) ) % LL; /* use circular addressing */ tmptmp3_40_fx = L_add( tmptmp3_40_fx, Mult_32_16( x_r_fx[m], sinc_fx[k][j] ) ); } -#ifdef BASOP_NOGLOB out_fx[i] = round_fx_sat( L_shl_sat( tmptmp3_40_fx, 2 ) ); -#else - out_fx[i] = round_fx( L_shl( tmptmp3_40_fx, 2 ) ); -#endif move16(); } @@ -1320,17 +1217,11 @@ void DTFS_zeroFilter_fx( FOR( n = 0; n < N; n++ ) { -#ifdef BASOP_NOGLOB sum1_fx = L_mac_o( sum1_fx, LPC[n], C_fx[( 4 * temp2 ) % ( 4 * X_fx->lag_fx )], &Overflow ); /* Q(12+15+1) */ sum2_fx = L_mac_o( sum2_fx, LPC[n], S_fx[( 4 * temp2 ) % ( 4 * X_fx->lag_fx )], &Overflow ); -#else - sum1_fx = L_mac( sum1_fx, LPC[n], C_fx[i_mult( 4, temp2 ) % i_mult( 4, X_fx->lag_fx )] ); /* Q(12+15+1) */ - sum2_fx = L_mac( sum2_fx, LPC[n], S_fx[i_mult( 4, temp2 ) % i_mult( 4, X_fx->lag_fx )] ); -#endif temp2 = add( temp2, temp ); } -#ifdef BASOP_NOGLOB temp1 = round_fx_o( sum1_fx, &Overflow ); /* Q(12+15+1-16)=Q(12) */ temp2 = round_fx_o( sum2_fx, &Overflow ); /* Q(12) */ @@ -1339,16 +1230,6 @@ void DTFS_zeroFilter_fx( L_temp1 = L_msu_o( L_temp1, temp2, X_fx->b_fx[k], &Overflow ); /* Q(12+Q+1) */ L_temp2 = L_mult_o( temp1, X_fx->b_fx[k], &Overflow ); L_temp2 = L_mac_o( L_temp2, temp2, X_fx->a_fx[k], &Overflow ); /* Q(12+Q+1) */ -#else - temp1 = round_fx( sum1_fx ); /* Q(12+15+1-16)=Q(12) */ - temp2 = round_fx( sum2_fx ); /* Q(12) */ - - /* Calculate the circular convolution */ - L_temp1 = L_mult( temp1, X_fx->a_fx[k] ); - L_temp1 = L_msu( L_temp1, temp2, X_fx->b_fx[k] ); /* Q(12+Q+1) */ - L_temp2 = L_mult( temp1, X_fx->b_fx[k] ); - L_temp2 = L_mac( L_temp2, temp2, X_fx->a_fx[k] ); /* Q(12+Q+1) */ -#endif /* normalization */ na = norm_l( L_temp1 ); if ( L_temp1 == 0 ) @@ -1368,13 +1249,8 @@ void DTFS_zeroFilter_fx( nb = na; move16(); } -#ifdef BASOP_NOGLOB X_fx->a_fx[k] = round_fx_o( (Word32) L_shl_o( L_temp1, nb, &Overflow ), &Overflow ); /* Q(13+Q+nb-16)=Q(Q+nb-3) */ X_fx->b_fx[k] = round_fx_o( (Word32) L_shl_o( L_temp2, nb, &Overflow ), &Overflow ); /* Q(Q+nb-3) */ -#else - X_fx->a_fx[k] = round_fx( (Word32) L_shl( L_temp1, nb ) ); /* Q(13+Q+nb-16)=Q(Q+nb-3) */ - X_fx->b_fx[k] = round_fx( (Word32) L_shl( L_temp2, nb ) ); /* Q(Q+nb-3) */ -#endif move32(); move32(); @@ -1390,17 +1266,10 @@ void DTFS_zeroFilter_fx( /* bring to the same Q */ FOR( k = 0; k <= HalfLag; k++ ) { -#ifdef BASOP_NOGLOB X_fx->a_fx[k] = shl_o( X_fx->a_fx[k], sub( Qmin, Qab[k] ), &Overflow ); move16(); /* Q(Q+Qab[k]+Qmin-Qab[k]=Q(Q+Qmin) */ X_fx->b_fx[k] = shl_o( X_fx->b_fx[k], sub( Qmin, Qab[k] ), &Overflow ); move16(); /* Q(Q+Qmin) */ -#else - X_fx->a_fx[k] = shl( X_fx->a_fx[k], sub( Qmin, Qab[k] ) ); - move16(); /* Q(Q+Qab[k]+Qmin-Qab[k]=Q(Q+Qmin) */ - X_fx->b_fx[k] = shl( X_fx->b_fx[k], sub( Qmin, Qab[k] ) ); - move16(); /* Q(Q+Qmin) */ -#endif } X_fx->Q = add( X_fx->Q, Qmin ); @@ -1657,23 +1526,14 @@ Word32 DTFS_getEngy_fx( temp_b_fx = X_fx->b_fx[k]; move16(); -#ifdef BASOP_NOGLOB en_fx = L_mac0_o( en_fx, temp_a_fx, temp_a_fx, &Overflow ); en_fx = L_mac0_o( en_fx, temp_b_fx, temp_b_fx, &Overflow ); -#else - en_fx = L_mac0( en_fx, temp_a_fx, temp_a_fx ); - en_fx = L_mac0( en_fx, temp_b_fx, temp_b_fx ); -#endif } en_fx = L_shr( en_fx, 1 ); temp_a_fx = X_fx->a_fx[0]; move16(); -#ifdef BASOP_NOGLOB en_fx = L_mac0_o( en_fx, temp_a_fx, temp_a_fx, &Overflow ); -#else - en_fx = L_mac0( en_fx, temp_a_fx, temp_a_fx ); -#endif /* IF (X_fx->lag_fx%2 == 0) */ IF( s_and( X_fx->lag_fx, 1 ) == 0 ) { @@ -1682,13 +1542,8 @@ Word32 DTFS_getEngy_fx( temp_b_fx = X_fx->b_fx[k]; move16(); -#ifdef BASOP_NOGLOB en_fx = L_mac0_o( en_fx, temp_a_fx, temp_a_fx, &Overflow ); en_fx = L_mac0_o( en_fx, temp_b_fx, temp_b_fx, &Overflow ); -#else - en_fx = L_mac0( en_fx, temp_a_fx, temp_a_fx ); - en_fx = L_mac0( en_fx, temp_b_fx, temp_b_fx ); -#endif } return en_fx; /* 2*X1.Q+1=Q13 */ @@ -1727,30 +1582,16 @@ Word32 DTFS_getEngy_P2A_fx( HalfLag_fx = s_min( HalfLag_fx, X_fx->nH_fx ); FOR( k = 1; k <= HalfLag_fx; k++ ) { -#ifdef BASOP_NOGLOB en_fx = L_mac0_o( en_fx, X_fx->a_fx[k], X_fx->a_fx[k], &Overflow ); en_fx = L_mac0_o( en_fx, X_fx->b_fx[k], X_fx->b_fx[k], &Overflow ); -#else - en_fx = L_mac0( en_fx, X_fx->a_fx[k], X_fx->a_fx[k] ); - en_fx = L_mac0( en_fx, X_fx->b_fx[k], X_fx->b_fx[k] ); -#endif } en_fx = L_shr( en_fx, 1 ); -#ifdef BASOP_NOGLOB en_fx = L_mac0_o( en_fx, X_fx->a_fx[0], X_fx->a_fx[0], &Overflow ); -#else - en_fx = L_mac0( en_fx, X_fx->a_fx[0], X_fx->a_fx[0] ); -#endif /* IF (X_fx->lag_fx%2 == 0) */ IF( s_and( X_fx->lag_fx, 1 ) == 0 ) { -#ifdef BASOP_NOGLOB en_fx = L_mac0_o( en_fx, X_fx->a_fx[k], X_fx->a_fx[k], &Overflow ); en_fx = L_mac0_o( en_fx, X_fx->b_fx[k], X_fx->b_fx[k], &Overflow ); -#else - en_fx = L_mac0( en_fx, X_fx->a_fx[k], X_fx->a_fx[k] ); - en_fx = L_mac0( en_fx, X_fx->b_fx[k], X_fx->b_fx[k] ); -#endif } return en_fx; /* 2*X1.Q */ @@ -1810,11 +1651,7 @@ static Word32 DTFS_setEngy_fx( expb = norm_l( en1_fx ); -#ifdef BASOP_NOGLOB fracb = round_fx_sat( L_shl_sat( en1_fx, expb ) ); -#else - fracb = round_fx( L_shl( en1_fx, expb ) ); -#endif expb = sub( 30, add( expb, shl( X_DTFS_FX->Q, 1 ) ) ); @@ -1891,13 +1728,9 @@ void DTFS_car2pol_fx( FOR( k = 1; k <= HalfLag_fx; k++ ) { - Lacc_fx = L_mult( X_fx->a_fx[k], X_fx->a_fx[k] ); /* a[k]^2, 2Q+1 */ -#ifdef BASOP_NOGLOB + Lacc_fx = L_mult( X_fx->a_fx[k], X_fx->a_fx[k] ); /* a[k]^2, 2Q+1 */ Lacc_fx = L_mac_o( Lacc_fx, X_fx->b_fx[k], X_fx->b_fx[k], &Overflow ); /* a[k]^2+b[k]^2, 2Q+1 */ -#else - Lacc_fx = L_mac( Lacc_fx, X_fx->b_fx[k], X_fx->b_fx[k] ); /* a[k]^2+b[k]^2, 2Q+1 */ -#endif - Lacc_fx = L_shr( Lacc_fx, 3 ); /* Lacc=(a[k]^2+b[k]^2)/4, 2Q */ + Lacc_fx = L_shr( Lacc_fx, 3 ); /* Lacc=(a[k]^2+b[k]^2)/4, 2Q */ IF( Lacc_fx ) { @@ -2019,11 +1852,7 @@ Word32 DTFS_setEngyHarm_fx( Lacc = L_deposit_l( 0 ); FOR( k = f_low_fx + 1; k <= HalfLag_fx; k++ ) { -#ifdef BASOP_NOGLOB Lacc = L_mac0_o( Lacc, X_fx->a_fx[k], X_fx->a_fx[k], &Overflow ); /* 2*X1.Q */ -#else - Lacc = L_mac0( Lacc, X_fx->a_fx[k], X_fx->a_fx[k] ); /* 2*X1.Q */ -#endif Lacc_max = L_max( Lacc_max, Lacc ); count = add( count, 1 ); @@ -2038,13 +1867,8 @@ Word32 DTFS_setEngyHarm_fx( Lacc = L_deposit_l( 0 ); FOR( k = f_low_fx + 1; k <= HalfLag_fx; k++ ) { -#ifdef BASOP_NOGLOB L_tmp = L_mult_o( X_fx->a_fx[k], X_fx->a_fx[k], &Overflow ); Lacc = L_add_o( Lacc, L_shr( L_tmp, expp ), &Overflow ); /* 2*X1.Q-expp */ -#else - L_tmp = L_mult( X_fx->a_fx[k], X_fx->a_fx[k] ); - Lacc = L_add( Lacc, L_shr( L_tmp, expp ) ); /* 2*X1.Q-expp */ -#endif count = add( count, 1 ); } } @@ -2057,11 +1881,7 @@ Word32 DTFS_setEngyHarm_fx( exp = norm_s( count ); tmp = div_s( shl( 1, sub( 14, exp ) ), count ); /* 29 - exp */ -#ifdef BASOP_NOGLOB en1_fx = L_shl_o( Mult_32_16( Lacc, tmp ), sub( exp, 14 ), &Overflow ); -#else - en1_fx = L_shl( Mult_32_16( Lacc, tmp ), sub( exp, 14 ) ); -#endif test(); IF( en1_fx > 0 && en2_fx > 0 ) { @@ -2072,11 +1892,7 @@ Word32 DTFS_setEngyHarm_fx( expb = norm_l( en1_fx ); -#ifdef BASOP_NOGLOB fracb = round_fx_o( L_shl_o( en1_fx, expb, &Overflow ), &Overflow ); -#else - fracb = round_fx( L_shl( en1_fx, expb ) ); -#endif IF( GE_32( Lacc_max, 2147483647 /*1.Q31*/ ) ) { expb = sub( 30, add( expb, sub( shl( X_fx->Q, 1 ), expp ) ) ); @@ -2114,11 +1930,7 @@ Word32 DTFS_setEngyHarm_fx( { /*L_temp_fx =(Word32)Mpy_32_16(extract_h(factor_fx),extract_l(factor_fx), X_fx->a_fx[k]); move32(); */ /* Q(temp+X1.Q-15) */ L_temp_fx = Mult_32_16( factor_fx, X_fx->a_fx[k] ); /* Q(temp+X1.Q-15) */ -#ifdef BASOP_NOGLOB - X_fx->a_fx[k] = round_fx_o( L_temp_fx, &Overflow ); /* Q(temp+X1.Q-15-16)=Q(temp+X1.Q-31); */ -#else - X_fx->a_fx[k] = round_fx( L_temp_fx ); /* Q(temp+X1.Q-15-16)=Q(temp+X1.Q-31); */ -#endif + X_fx->a_fx[k] = round_fx_o( L_temp_fx, &Overflow ); /* Q(temp+X1.Q-15-16)=Q(temp+X1.Q-31); */ move16(); } @@ -2254,11 +2066,7 @@ static void cubicPhase_fx( Ltemp3 = L_sub( Ltemp3, L_shl( Ltemp1, 1 ) ); /* Ltemp3=N*c1-2*Ltemp1, Q20 */ -#ifdef BASOP_NOGLOB IF( GE_32( L_abs( Ltemp3 ), L_shl_o( Ltemp2, 8, &Overflow ) ) ) -#else - IF( GE_32( L_abs( Ltemp3 ), L_shl( Ltemp2, 8 ) ) ) -#endif { Lacc = L_add( MIN_32, 0 ); if ( Ltemp3 > 0 ) @@ -2271,11 +2079,7 @@ static void cubicPhase_fx( ELSE { expa = norm_l( Ltemp3 ); -#ifdef BASOP_NOGLOB fraca = extract_h( L_shl_o( Ltemp3, expa, &Overflow ) ); -#else - fraca = extract_h( L_shl( Ltemp3, expa ) ); -#endif expa = sub( 30, add( expa, 20 ) ); if ( fraca < 0 ) { @@ -2284,11 +2088,7 @@ static void cubicPhase_fx( } expb = norm_l( Ltemp2 ); -#ifdef BASOP_NOGLOB fracb = extract_h( L_shl_o( Ltemp2, expb, &Overflow ) ); -#else - fracb = extract_h( L_shl( Ltemp2, expb ) ); -#endif expb = sub( 30, expb ); if ( fracb < 0 ) { @@ -2305,11 +2105,7 @@ static void cubicPhase_fx( fracb = negate( fracb ); } scale = shr( sub( fracb, fraca ), 15 ); -#ifdef BASOP_NOGLOB fraca = shl_o( fraca, scale, &Overflow ); -#else - fraca = shl( fraca, scale ); -#endif expa = sub( expa, scale ); tmp = div_s( fraca, fracb ); /* 15-exp */ @@ -2325,13 +2121,8 @@ static void cubicPhase_fx( tmp = negate( tmp ); } -#ifdef BASOP_NOGLOB Lacc = L_shl_o( tmp, add( exp, 34 ), &Overflow ); Lacc = L_add_o( Lacc, 0x08000, &Overflow ); -#else - Lacc = L_shl( tmp, add( exp, 34 ) ); - Lacc = L_add( Lacc, 0x08000 ); -#endif c0 = extract_h( Lacc ); /* c0 in Q33 */ } @@ -2457,11 +2248,7 @@ static void cubicPhase_fx( Ltemp3 = L_add( Ltemp3, 1 ); } -#ifdef BASOP_NOGLOB Ltemp3 = L_shl_o( Mult_32_16( L_shl_o( Ltemp3, 7, &Overflow ), c0 ), 2, &Overflow ); /* Ltemp3=c0*n^3, Q27 */ -#else - Ltemp3 = L_shl( Mult_32_16( L_shl( Ltemp3, 7 ), c0 ), 2 ); /* Ltemp3=c0*n^3, Q27 */ -#endif Ltemp2 = L_shl( Mult_32_16( N2, c1 ), 1 ); /* Ltemp2 = (Word32)L_mult_su(c1,(UNS_Word16)n2); : Ltemp2=c1*n^2, Q27 */ Ltemp1 = L_shl( L_mult( c2, n ), 7 ); /* Ltemp1=c2*n, Q27 */ @@ -2587,12 +2374,8 @@ void DTFS_to_erb_fx( FOR( i = 0; i < num_erb_fx; i++ ) { -#ifdef BASOP_NOGLOB out_fx[i] = round_fx_o( L_shl_o( sum_a_fx[i], n, &Overflow ), &Overflow ); /* Q13 */ move16(); -#else - out_fx[i] = round_fx( L_shl( sum_a_fx[i], n ) ); /* Q13 */ -#endif IF( GT_16( count[i], 1 ) ) { IF( sum_a_fx[i] < 0 ) @@ -2619,14 +2402,8 @@ void DTFS_to_erb_fx( tmp = div_s( fracb, fraca ); exp = sub( expb, expa ); -#ifdef BASOP_NOGLOB L_tmp = L_shl_sat( tmp, add( exp, 14 ) ); out_fx[i] = round_fx_sat( L_tmp ); -#else - L_tmp = L_shl( tmp, add( exp, 14 ) ); - - out_fx[i] = round_fx( L_tmp ); -#endif move16(); } } @@ -2754,29 +2531,17 @@ void erb_slot_fx( } FOR( j = 0; j < num_erb_fx; j++ ) { -#ifdef BASOP_NOGLOB mfreq_fx[j] = round_fx_o( L_shl_o( mf_fx[j], 11, &Overflow ), &Overflow ); /* Q15 */ -#else - mfreq_fx[j] = round_fx( L_shl( mf_fx[j], 11 ) ); /* Q15 */ -#endif move16(); IF( GT_16( out_fx[j], 1 ) ) { expb = norm_l( mf_fx[j] ); -#ifdef BASOP_NOGLOB fracb = round_fx_o( L_shl_o( mf_fx[j], expb, &Overflow ), &Overflow ); -#else - fracb = round_fx( L_shl( mf_fx[j], expb ) ); -#endif expb = sub( 30, add( expb, 20 ) ); expa = norm_l( out_fx[j] ); -#ifdef BASOP_NOGLOB fraca = extract_h( L_shl_o( out_fx[j], expa, &Overflow ) ); -#else - fraca = extract_h( L_shl( out_fx[j], expa ) ); -#endif expa = sub( 30, expa ); scale = shr( sub( fraca, fracb ), 15 ); @@ -2785,16 +2550,10 @@ void erb_slot_fx( tmp = div_s( fracb, fraca ); exp = sub( expb, expa ); -#ifdef BASOP_NOGLOB L_tmp = L_shl_o( tmp, add( exp, 16 ), &Overflow ); mfreq_fx[j] = round_fx_o( L_tmp, &Overflow ); move16(); -#else - L_tmp = L_shl( tmp, add( exp, 16 ) ); - - mfreq_fx[j] = round_fx( L_tmp ); -#endif } } return; @@ -2933,11 +2692,7 @@ void DTFS_erb_inv_fx( d2h = 31; move16(); } -#ifdef BASOP_NOGLOB X_fx->a_fx[i] = round_fx_o( L_shl_o( Ltemp_fx, d2h, &Overflow ), &Overflow ); /* Q(28-n+d2h) */ -#else - X_fx->a_fx[i] = round_fx( L_shl( Ltemp_fx, d2h ) ); /* Q(28-n+d2h) */ -#endif move16(); q[i] = add( sub( 28, n ), d2h ); move16(); @@ -3481,11 +3236,7 @@ Word16 ppp_extract_pitch_period_fx( spike = i; move16(); } -#ifdef BASOP_NOGLOB en1 = L_mac0_sat( en1, ptr[i], ptr[i] ); /* Q0 */ -#else - en1 = L_mac0( en1, ptr[i], ptr[i] ); /* Q0 */ -#endif } IF( ptr[spike] > 0 ) @@ -3618,11 +3369,7 @@ Word16 ppp_extract_pitch_period_fx( Lacc = L_deposit_l( 0 ); FOR( i = 0; i < l; i++ ) { -#ifdef BASOP_NOGLOB Lacc = L_mac0_sat( Lacc, out[i], out[i] ); /* Q0 */ -#else - Lacc = L_mac0( Lacc, out[i], out[i] ); /* Q0 */ -#endif } @@ -3636,11 +3383,7 @@ Word16 ppp_extract_pitch_period_fx( expb = norm_l( Lacc ); -#ifdef BASOP_NOGLOB fracb = round_fx_sat( L_shl_sat( Lacc, expb ) ); -#else - fracb = round_fx( L_shl( Lacc, expb ) ); -#endif expb = sub( 30, add( expb, Qres ) ); scale1 = shr( sub( fraca, fracb ), 15 ); @@ -3700,11 +3443,7 @@ void DTFS_peaktoaverage_fx( DTFS_STRUCTURE X_fx, Word32 *pos_fx, Word16 *Qpos, W FOR( i = 0; i < 256; i++ ) { -#ifdef BASOP_NOGLOB L_temp = L_mult_sat( time_fx[i], time_fx[i] ); /* Q(1) */ -#else - L_temp = L_mult( time_fx[i], time_fx[i] ); /* Q(1) */ -#endif IF( time_fx[i] >= 0 ) { if ( GT_32( L_temp, maxPosEn_fx ) ) @@ -3742,29 +3481,17 @@ void DTFS_peaktoaverage_fx( DTFS_STRUCTURE X_fx, Word32 *pos_fx, Word16 *Qpos, W ELSE { expa = norm_l( maxPosEn_fx ); -#ifdef BASOP_NOGLOB fraca = extract_h( L_shl_o( maxPosEn_fx, expa, &Overflow ) ); -#else - fraca = extract_h( L_shl( maxPosEn_fx, expa ) ); -#endif expa = sub( 30, add( expa, 1 ) ); expb = norm_l( L_sum ); -#ifdef BASOP_NOGLOB fracb = round_fx_o( L_shl_o( L_sum, expb, &Overflow ), &Overflow ); -#else - fracb = round_fx( L_shl( L_sum, expb ) ); -#endif expb = sub( 30, add( expb, shl( X_fx.Q, 1 ) ) ); scale = shr( sub( fraca, fracb ), 15 ); -#ifdef BASOP_NOGLOB fracb = shl_o( fracb, scale, &Overflow ); -#else - fracb = shl( fracb, scale ); -#endif expb = sub( expb, scale ); tmp = div_s( fracb, fraca ); @@ -3788,29 +3515,17 @@ void DTFS_peaktoaverage_fx( DTFS_STRUCTURE X_fx, Word32 *pos_fx, Word16 *Qpos, W { expa = norm_l( maxNegEn_fx ); -#ifdef BASOP_NOGLOB fraca = extract_h( L_shl_o( maxNegEn_fx, expa, &Overflow ) ); -#else - fraca = extract_h( L_shl( maxNegEn_fx, expa ) ); -#endif expa = sub( Q29, expa ); // 30 - expa - 1; expb = norm_l( L_sum ); -#ifdef BASOP_NOGLOB fracb = round_fx_o( L_shl_o( L_sum, expb, &Overflow ), &Overflow ); -#else - fracb = round_fx( L_shl( L_sum, expb ) ); -#endif expb = sub( 30, add( expb, shl( X_fx.Q, 1 ) ) ); scale = shr( sub( fraca, fracb ), 15 ); -#ifdef BASOP_NOGLOB fracb = shl_o( fracb, scale, &Overflow ); -#else - fracb = shl( fracb, scale ); -#endif expb = sub( expb, scale ); tmp = div_s( fracb, fraca ); @@ -4109,7 +3824,6 @@ static void c_fft_wi_fx( Word16 *farray_ptr_fx, Word16 size, Word16 stage, Word1 tmp1 = round_fx( ftmp_real_fx ); tmp2 = round_fx( ftmp_imag_fx ); -#ifdef BASOP_NOGLOB *( farray_ptr_fx + kj ) = sub_sat( *( farray_ptr_fx + k ), tmp1 ); move16(); *( farray_ptr_fx + kj + 1 ) = sub_sat( *( farray_ptr_fx + k + 1 ), tmp2 ); @@ -4118,16 +3832,6 @@ static void c_fft_wi_fx( Word16 *farray_ptr_fx, Word16 size, Word16 stage, Word1 move16(); *( farray_ptr_fx + k + 1 ) = add_sat( *( farray_ptr_fx + k + 1 ), tmp2 ); move16(); -#else - *( farray_ptr_fx + kj ) = sub( *( farray_ptr_fx + k ), tmp1 ); - move16(); - *( farray_ptr_fx + kj + 1 ) = sub( *( farray_ptr_fx + k + 1 ), tmp2 ); - move16(); - *( farray_ptr_fx + k ) = add( *( farray_ptr_fx + k ), tmp1 ); - move16(); - *( farray_ptr_fx + k + 1 ) = add( *( farray_ptr_fx + k + 1 ), tmp2 ); - move16(); -#endif } } } @@ -4314,13 +4018,8 @@ void copy_phase_fx( DTFS_STRUCTURE *X1_fx, DTFS_STRUCTURE X2_fx, DTFS_STRUCTURE FOR( k = 1; k <= HalfLag; k++ ) { -#ifdef BASOP_NOGLOB Lacc_fx = L_mult_o( X1_fx->a_fx[k], X1_fx->a_fx[k], &Overflow ); Lacc_fx = L_mac_o( Lacc_fx, X1_fx->b_fx[k], X1_fx->b_fx[k], &Overflow ); /* 2*Q+1 */ -#else - Lacc_fx = L_mult( X1_fx->a_fx[k], X1_fx->a_fx[k] ); - Lacc_fx = L_mac( Lacc_fx, X1_fx->b_fx[k], X1_fx->b_fx[k] ); /* 2*Q+1 */ -#endif exp = norm_l( Lacc_fx ); tmp = extract_h( L_shl( Lacc_fx, exp ) ); @@ -4361,7 +4060,6 @@ void copy_phase_fx( DTFS_STRUCTURE *X1_fx, DTFS_STRUCTURE X2_fx, DTFS_STRUCTURE d1h = extract_h( Ltemp_fx ); d1l = extract_l( Ltemp_fx ); -#ifdef BASOP_NOGLOB Ltemp_fx = L_mult0( X1_fx->b_fx[k], d1l ); Ltemp_fx = L_add_o( L_shr( Ltemp_fx, 15 ), L_mult_o( X1_fx->b_fx[k], d1h, &Overflow ), &Overflow ); /* sin(w) in Q(q+16+Q-15) */ sn = round_fx_o( L_shl_o( Ltemp_fx, sub( 30, add( q, X1_fx->Q ) ), &Overflow ), &Overflow ); /* Q15 */ @@ -4373,19 +4071,6 @@ void copy_phase_fx( DTFS_STRUCTURE *X1_fx, DTFS_STRUCTURE X2_fx, DTFS_STRUCTURE cn = round_fx_o( L_shl_o( Ltemp_fx, sub( 30, add( q, X1_fx->Q ) ), &Overflow ), &Overflow ); /* Q15 */ retX_fx->a_fx[k] = mult_ro( X2_fx.a_fx[k], cn, &Overflow ); /* X2_fx.Q */ move16(); -#else - Ltemp_fx = L_mult0( X1_fx->b_fx[k], d1l ); - Ltemp_fx = L_add( L_shr( Ltemp_fx, 15 ), L_mult( X1_fx->b_fx[k], d1h ) ); /* sin(w) in Q(q+16+Q-15) */ - sn = round_fx( L_shl( Ltemp_fx, sub( 30, add( q, X1_fx->Q ) ) ) ); /* Q15 */ - retX_fx->b_fx[k] = mult_r( X2_fx.a_fx[k], sn ); /* X2_fx.Q */ - move16(); - - Ltemp_fx = L_mult0( X1_fx->a_fx[k], d1l ); - Ltemp_fx = L_add( L_shr( Ltemp_fx, 15 ), L_mult( X1_fx->a_fx[k], d1h ) ); /* cos(w) in Q(q+Q+1) */ - cn = round_fx( L_shl( Ltemp_fx, sub( 30, add( q, X1_fx->Q ) ) ) ); /* Q15 */ - retX_fx->a_fx[k] = mult_r( X2_fx.a_fx[k], cn ); /* X2_fx.Q */ - move16(); -#endif } k = sub( k, 1 ); @@ -4476,12 +4161,8 @@ Word32 getSpEngyFromResAmp_fx( DTFS_STRUCTURE *X_fx, Word16 lband, Word16 hband, FOR( i = 0; i < M + 1; i++ ) { /* Compute Re */ -#ifdef BASOP_NOGLOB Lacc = L_mac_o( Lacc, curr_lpc[i], cos_tab[n % M_fx], &Overflow ); /* Q28 */ -#else - Lacc = L_mac( Lacc, curr_lpc[i], cos_tab[n % M_fx] ); /* Q28 */ -#endif - n = add( n, k4 ); /* n=4*i*k */ + n = add( n, k4 ); /* n=4*i*k */ } Re = L_shr( Lacc, 1 ); /* Q27 */ @@ -4491,21 +4172,13 @@ Word32 getSpEngyFromResAmp_fx( DTFS_STRUCTURE *X_fx, Word16 lband, Word16 hband, FOR( i = 0; i < M + 1; i++ ) { /* Compute Im */ -#ifdef BASOP_NOGLOB Lacc = L_msu_o( Lacc, curr_lpc[i], sin_tab[n % M_fx], &Overflow ); /* Q28 */ -#else - Lacc = L_msu( Lacc, curr_lpc[i], sin_tab[n % M_fx] ); /* Q28 */ -#endif - n = add( n, k4 ); /* n=4*i*k */ + n = add( n, k4 ); /* n=4*i*k */ } - Im = L_shr( Lacc, 1 ); /* Q27 */ - /* Lacc=L_add(L_mult_ll(Re,Re),(Word32)L_mult_ll(Im,Im)); : Lacc=Re^2+Im^2 in Q23 */ -#ifdef BASOP_NOGLOB + Im = L_shr( Lacc, 1 ); /* Q27 */ + /* Lacc=L_add(L_mult_ll(Re,Re),(Word32)L_mult_ll(Im,Im)); : Lacc=Re^2+Im^2 in Q23 */ Lacc = L_add_o( Mult_32_32( Re, Re ), Mult_32_32( Im, Im ), &Overflow ); /* Lacc=Re^2+Im^2 in Q23 */ -#else - Lacc = L_add( Mult_32_32( Re, Re ), Mult_32_32( Im, Im ) ); /* Lacc=Re^2+Im^2 in Q23 */ -#endif - Ltemp = L_mult0( X_fx->a_fx[k], X_fx->a_fx[k] ); /* 2*a[k]^2 in 2Q */ + Ltemp = L_mult0( X_fx->a_fx[k], X_fx->a_fx[k] ); /* 2*a[k]^2 in 2Q */ /* Ltemp=(Word32)L_sat32_40(divide_dp(Ltemp,Lacc,-19,1)); : Ltemp in Q(2Q-13) */ if ( Lacc < 0 ) @@ -4531,11 +4204,7 @@ Word32 getSpEngyFromResAmp_fx( DTFS_STRUCTURE *X_fx, Word16 lband, Word16 hband, tmp = div_s( fracb, fraca ); /* 15-exp */ exp = sub( expb, expa ); -#ifdef BASOP_NOGLOB Ltemp = L_shl_o( tmp, sub( add( shl( X_fx->Q, 1 ), exp ), 27 ), &Overflow ); -#else - Ltemp = L_shl( tmp, sub( add( shl( X_fx->Q, 1 ), exp ), 27 ) ); -#endif } ELSE { @@ -4601,41 +4270,21 @@ void DTFS_poleFilter_fx( DTFS_STRUCTURE *X_fx, Word16 *LPC, Word16 N, Word16 *S_ sum2_fx = L_deposit_l( 0 ); FOR( n = 0; n < N; n++ ) { -#ifdef BASOP_NOGLOB sum1_fx = L_mac_o( sum1_fx, LPC[n], C_fx[shl( temp2, 2 ) % shl( X_fx->lag_fx, 2 )], &Overflow ); /* Q(12+15+1) */ sum2_fx = L_mac_o( sum2_fx, LPC[n], S_fx[shl( temp2, 2 ) % shl( X_fx->lag_fx, 2 )], &Overflow ); /* Q(12+15+1) */ -#else - sum1_fx = L_mac( sum1_fx, LPC[n], C_fx[( 4 * temp2 ) % ( 4 * X_fx->lag_fx )] ); /* Q(12+15+1) */ - sum2_fx = L_mac( sum2_fx, LPC[n], S_fx[( 4 * temp2 ) % ( 4 * X_fx->lag_fx )] ); /* Q(12+15+1) */ -#endif temp2 = add( temp2, k ); } -#ifdef BASOP_NOGLOB temp1 = round_fx_o( sum1_fx, &Overflow ); /* Q(12+15+1-16)=Q(12) */ temp2 = round_fx_o( sum2_fx, &Overflow ); /* Q(12) */ /* Calculate the circular convolution */ sum = L_mac_o( L_mult_o( temp1, temp1, &Overflow ), temp2, temp2, &Overflow ); /* Q(12+12+1)=Q(25) */ -#else - temp1 = round_fx( sum1_fx ); /* Q(12+15+1-16)=Q(12) */ - temp2 = round_fx( sum2_fx ); /* Q(12) */ - /* Calculate the circular convolution */ - sum = L_mac( L_mult( temp1, temp1 ), temp2, temp2 ); /* Q(12+12+1)=Q(25) */ -#endif L_temp1 = L_mult( temp1, X_fx->a_fx[k] ); -#ifdef BASOP_NOGLOB L_temp1 = L_mac_o( L_temp1, temp2, X_fx->b_fx[k], &Overflow ); /* Q(12+Q+1)=Q(13+Q) */ -#else - L_temp1 = L_mac( L_temp1, temp2, X_fx->b_fx[k] ); /* Q(12+Q+1)=Q(13+Q) */ -#endif L_temp2 = L_mult( temp1, X_fx->b_fx[k] ); -#ifdef BASOP_NOGLOB L_temp2 = L_msu_o( L_temp2, temp2, X_fx->a_fx[k], &Overflow ); /* Q(12+Q+1)=Q(13+Q) */ -#else - L_temp2 = L_msu( L_temp2, temp2, X_fx->a_fx[k] ); /* Q(12+Q+1)=Q(13+Q) */ -#endif IF( sum ) { exp = norm_l( sum ); @@ -4750,13 +4399,8 @@ void poleFilter_setup_fx( const Word16 *LPC, Word16 N, DTFS_STRUCTURE X_fx, Word sum2_fx = L_deposit_l( 0 ); FOR( n = 0; n < N; n++ ) { -#ifdef BASOP_NOGLOB sum1_fx = L_mac_o( sum1_fx, LPC[n], C_fx[( 4 * temp2 ) % ( 4 * X_fx.lag_fx )], &Overflow ); /* Q(12+15+1) */ sum2_fx = L_mac_o( sum2_fx, LPC[n], S_fx[( 4 * temp2 ) % ( 4 * X_fx.lag_fx )], &Overflow ); /* Q(12+15+1) */ -#else - sum1_fx = L_mac( sum1_fx, LPC[n], C_fx[( 4 * temp2 ) % ( 4 * X_fx.lag_fx )] ); /* Q(12+15+1) */ - sum2_fx = L_mac( sum2_fx, LPC[n], S_fx[( 4 * temp2 ) % ( 4 * X_fx.lag_fx )] ); /* Q(12+15+1) */ -#endif temp2 = add( temp2, k ); } diff --git a/lib_com/window_fx.c b/lib_com/window_fx.c index 2b3c50ac6749ca1a74fed4bd80ad51a09e5f3d76..a1ff625b08f2328fac98ec8066afed188f7e453d 100644 --- a/lib_com/window_fx.c +++ b/lib_com/window_fx.c @@ -46,13 +46,8 @@ void ham_cos_window( { /* fh_f[i] = 0.54f - 0.46f * (Float32)cos(cc); */ BASOP_SATURATE_WARNING_OFF_EVS -#ifdef BASOP_NOGLOB fh[i] = sub_o( P54_0Q15, mult_r( getCosWord16( round_fx_o( L_shl_o( cc, 9, &Overflow ), &Overflow ) ), P92_0Q15 ), &Overflow ); /*0Q15*/ move16(); -#else - fh[i] = sub( P54_0Q15, mult_r( getCosWord16( round_fx( L_shl( cc, 9 ) ) ), P92_0Q15 ) ); /*0Q15*/ - move16(); -#endif BASOP_SATURATE_WARNING_ON_EVS cc = L_add( cc, cte ); /*0Q15*/ } @@ -68,13 +63,8 @@ void ham_cos_window( FOR( i = n1; i < n1 + n2; i++ ) { /* fh_f[i] = (Float32)cos(cc); */ -#ifdef BASOP_NOGLOB fh[i] = shl_o( getCosWord16( round_fx( L_shl( cc, 10 ) ) ), 1, &Overflow ); /*0Q15*/ move16(); -#else - fh[i] = shl( getCosWord16( round_fx( L_shl( cc, 10 ) ) ), 1 ); /*0Q15*/ - move16(); -#endif cc = L_add( cc, cte ); } BASOP_SATURATE_WARNING_ON_EVS diff --git a/lib_com/window_ola_fx.c b/lib_com/window_ola_fx.c index 40763be995bdd9a8d5664f33fcc19c2409891084..2948e725ecdb0ca7d1add2a05b91500c4b2b8aaa 100644 --- a/lib_com/window_ola_fx.c +++ b/lib_com/window_ola_fx.c @@ -27,16 +27,12 @@ void sinq_fx( L_tmp = Mult_32_16( L_tmp, 5461 ); /*Q31; division by 6 */ tmp2 = round_fx( L_tmp ); /*Q15 */ x[1] = sub( tmp1, tmp2 ); - move16(); /* sin(x) approximated by (x-x^3/3!); Q15 */ -#ifdef BASOP_NOGLOB + move16(); /* sin(x) approximated by (x-x^3/3!); Q15 */ tmp1 = add_sat( shl_sat( tmp, 1 ), phi ); /*Q15 */ -#else - tmp1 = add( shl( tmp, 1 ), phi ); /*Q15 */ -#endif - L_tmp = L_mult( tmp1, tmp1 ); /*Q31 */ - L_tmp = Mult_32_16( L_tmp, tmp1 ); /*Q31 */ - L_tmp = Mult_32_16( L_tmp, 5461 ); /*Q31; division by 6 */ - tmp2 = round_fx( L_tmp ); /*Q15 */ + L_tmp = L_mult( tmp1, tmp1 ); /*Q31 */ + L_tmp = Mult_32_16( L_tmp, tmp1 ); /*Q31 */ + L_tmp = Mult_32_16( L_tmp, 5461 ); /*Q31; division by 6 */ + tmp2 = round_fx( L_tmp ); /*Q15 */ x[2] = sub( tmp1, tmp2 ); move16(); /* sin(x) approximated by (x-x^3/3!); Q15 */ @@ -62,13 +58,8 @@ void sinq_fx( L_tmp = Mult_32_32( A32, tmp_old ); /*Q30 */ L_tmp = L_sub( L_tmp, L_shr( tmp_old_old, 1 ) ); /*Q30 */ tmp_old_old = L_add( tmp_old, 0 ); /*Q31 */ -#ifdef BASOP_NOGLOB - tmp_old = L_shl_sat( L_tmp, 1 ); /*Q31 */ - x[i] = round_fx_sat( tmp_old ); /*Q15 */ -#else - tmp_old = L_shl( L_tmp, 1 ); /*Q31 */ - x[i] = round_fx( tmp_old ); /*Q15 */ -#endif + tmp_old = L_shl_sat( L_tmp, 1 ); /*Q31 */ + x[i] = round_fx_sat( tmp_old ); /*Q15 */ move16(); } @@ -328,11 +319,7 @@ void window_ola_fx( p4 = OldauOut + n; FOR( i = 0; i < temp; i++ ) { -#ifdef BASOP_NOGLOB *p1 = add_sat( mult( *p1, *p2 ), shl_sat( mult( *p4, *p3 ), 5 ) ); /*auOut[i]*SS2[i]+ OldauOut[i+n]*(SS2[L-n-i-1])/(wret2[i]+0.01f);;*/ -#else - *p1 = add( mult( *p1, *p2 ), shl( mult( *p4, *p3 ), 5 ) ); /*auOut[i]*SS2[i]+ OldauOut[i+n]*(SS2[L-n-i-1])/(wret2[i]+0.01f);;*/ -#endif move16(); p1++; p2++; @@ -359,15 +346,9 @@ void window_ola_fx( temp_len = sub( shr( L, 1 ), n ); FOR( i = 0; i < temp_len; i += 2 ) { -#ifdef BASOP_NOGLOB *p1++ = round_fx_sat( L_add_sat( L_shl_sat( Mult_32_16( *pa++, *p3 ), 1 ), L_deposit_h( *p4++ ) ) ); /* (( Qin + Q15 -15)+1 + ( Qin - 15 + 16))-1 */ p3 -= decimate; *p1++ = round_fx_sat( L_add_sat( L_shl_sat( Mult_32_16( *pa++, *p5-- ), 1 ), L_deposit_h( *p4++ ) ) ); /* (( Qin + Q15 -15)+1 + ( Qin - 15 + 16))-1 */ -#else - *p1++ = round_fx( L_add( L_shl( Mult_32_16( *pa++, *p3 ), 1 ), L_deposit_h( *p4++ ) ) ); /* (( Qin + Q15 -15)+1 + ( Qin - 15 + 16))-1 */ - p3 -= decimate; - *p1++ = round_fx( L_add( L_shl( Mult_32_16( *pa++, *p5-- ), 1 ), L_deposit_h( *p4++ ) ) ); /* (( Qin + Q15 -15)+1 + ( Qin - 15 + 16))-1 */ -#endif move16(); /* paout[i] = ImdctOut[L/2 + i] * win_right[(2*L_FRAME16k-(n16+(i-n)/2))*decimate-1-decay-windecay48]+OldauOut[i]; paout[i+1] = ImdctOut[L/2 + i +1] * win_int_right[2*L_FRAME16k-(n16+(i-n)/2)-1-windecay16]+OldauOut[i+1];*/ @@ -380,13 +361,8 @@ void window_ola_fx( temp_len = sub( shr( L, 1 ), n ); FOR( i = 0; i < temp_len; i += 2 ) { -#ifdef BASOP_NOGLOB *p1++ = round_fx_sat( L_sub_sat( L_deposit_h( *p4++ ), L_shl_sat( Mult_32_16( *pa--, *p5-- ), 1 ) ) ); /* (( Qin + Q15 -15)+1 + ( Qin - 15 + 16))-1 */ *p1++ = round_fx_sat( L_sub_sat( L_deposit_h( *p4++ ), L_shl_sat( Mult_32_16( *pa--, *p3 ), 1 ) ) ); /* (( Qin + Q15 -15)+1 + ( Qin - 15 + 16))-1 */ -#else - *p1++ = round_fx( L_sub( L_deposit_h( *p4++ ), L_shl( Mult_32_16( *pa--, *p5-- ), 1 ) ) ); /* (( Qin + Q15 -15)+1 + ( Qin - 15 + 16))-1 */ - *p1++ = round_fx( L_sub( L_deposit_h( *p4++ ), L_shl( Mult_32_16( *pa--, *p3 ), 1 ) ) ); /* (( Qin + Q15 -15)+1 + ( Qin - 15 + 16))-1 */ -#endif move16(); p3 -= decimate; /* paout[L/2 + i ] = -ImdctOut[L - 1 - i] * win_int_right[(3*L_FRAME16k/2-1-i/2)-windecay16]+OldauOut[i+L/2]; @@ -450,11 +426,7 @@ void window_ola_fx( temp_len = sub( shr( L, 1 ), n ); FOR( i = 0; i < temp_len; i++ ) { -#ifdef BASOP_NOGLOB *p1++ = round_fx_sat( L_add_sat( L_shl( Mult_32_16( *pa++, *p3 ), 1 ), L_deposit_h( *p4++ ) ) ); /* (( Qin + Q15 -15)+1 + ( Qin - 15 + 16))-1 */ -#else - *p1++ = round_fx( L_add( L_shl( Mult_32_16( *pa++, *p3 ), 1 ), L_deposit_h( *p4++ ) ) ); /* (( Qin + Q15 -15)+1 + ( Qin - 15 + 16))-1 */ -#endif move16(); p3 -= decimate; /*paout[i] = ImdctOut[L/2 + i] * win_right[(2*L-i)*decimate-1-decay-windecay48]+OldauOut[i];*/ @@ -466,11 +438,7 @@ void window_ola_fx( temp_len = sub( shr( L, 1 ), n ); FOR( i = 0; i < temp_len; i++ ) { -#ifdef BASOP_NOGLOB *p1++ = round_fx_sat( L_sub_sat( L_deposit_h( *p4++ ), L_shl_sat( Mult_32_16( *pa--, *p3 ), 1 ) ) ); /* (( Qin + Q15 -15)+1 + ( Qin - 15 + 16))-1 */ -#else - *p1++ = round_fx( L_sub( L_deposit_h( *p4++ ), L_shl( Mult_32_16( *pa--, *p3 ), 1 ) ) ); /* (( Qin + Q15 -15)+1 + ( Qin - 15 + 16))-1 */ -#endif move16(); p3 -= decimate; /* paout[L/2 + i] = -ImdctOut[L - 1 - i] * win_right[(3*L/2-1-i)*decimate+decay-windecay48]+OldauOut[i+L/2]; */ @@ -865,13 +833,13 @@ void core_switching_OLA_fx( IF( ( output_frame - L_FRAME16k ) == 0 ) /* no resampling */ { - Copy( mem_over_hp + 2, tmp_buf_switch + i_mult2( SWITCH_GAP_LENGTH_8k, delta ), NS2SA( output_Fs, DELAY_CLDFB_NS ) ); + Copy( mem_over_hp + 2, tmp_buf_switch + i_mult2( SWITCH_GAP_LENGTH_8k, delta ), NS2SA_FX2( output_Fs, DELAY_CLDFB_NS ) ); } ELSE { IF( ( output_frame - L_FRAME8k ) == 0 ) /* not done yet */ { - Copy( synth_subfr_out + SWITCH_GAP_LENGTH_8k, tmp_buf_switch + SWITCH_GAP_LENGTH_8k, NS2SA( output_Fs, DELAY_CLDFB_NS ) ); /* copy subframe to tmp buffer */ + Copy( synth_subfr_out + SWITCH_GAP_LENGTH_8k, tmp_buf_switch + SWITCH_GAP_LENGTH_8k, NS2SA_FX2( output_Fs, DELAY_CLDFB_NS ) ); /* copy subframe to tmp buffer */ } ELSE { @@ -930,15 +898,9 @@ void core_switching_OLA_fx( temp_len = i_mult2( ( R2_16 >> 2 ), delta ); FOR( i = 0; i < temp_len; i += 2 ) { -#ifdef BASOP_NOGLOB *pt = shl_sat( mult_r_sat( *pt, *pt5 ), 1 ); move16(); /* // Q14* Q15 + shl ==> Q15 */ *pt2 = shl_sat( mult_r_sat( *pt2, *pt4 ), 1 ); -#else - *pt = shl( mult_r( *pt, *pt5 ), 1 ); - move16(); /* // Q14* Q15 + shl ==> Q15 */ - *pt2 = shl( mult_r( *pt2, *pt4 ), 1 ); -#endif move16(); /*/= win[(3*L_FRAME16k/2-1-i/2)*decimate+decay-L_FRAME48k*14/20]; */ pt += 2; pt2 += 2; @@ -954,11 +916,7 @@ void core_switching_OLA_fx( temp_len = i_mult2( ( R2_16 >> 2 ), delta ); FOR( i = 0; i < temp_len; i++ ) { -#ifdef BASOP_NOGLOB *pt = shl_sat( mult_r_sat( *pt, *pt5 ), 1 ); -#else - *pt = shl( mult_r( *pt, *pt5 ), 1 ); -#endif move16(); /* /= win[(3*output_frame/2-1-i)*decimate+decay-L_FRAME48k*14/20]; */ pt++; pt5 -= decimate; @@ -992,7 +950,7 @@ void core_switching_OLA_fx( pt = synth; pt2 = tmp_buf_switch; - tmp = NS2SA( output_Fs, DELAY_CLDFB_NS ); + tmp = NS2SA_FX2( output_Fs, DELAY_CLDFB_NS ); move16(); pt3 = synth_subfr_bwe; @@ -1007,11 +965,7 @@ void core_switching_OLA_fx( temp_len = sub( L, tmp ); FOR( i = 0; i < temp_len; i++ ) { -#ifdef BASOP_NOGLOB *pt = add_sat( add_sat( *pt, *pt2++ ), *pt3++ ); -#else - *pt = add( add( *pt, *pt2++ ), *pt3++ ); -#endif move16(); pt++; } diff --git a/lib_com/wtda.c b/lib_com/wtda.c index 6bce31db96a7307ceb822a71a80d809f1a3cbea0..3fb40813816c7b4462bdcc3ec82b8df2314fb845 100644 --- a/lib_com/wtda.c +++ b/lib_com/wtda.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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,11 +37,10 @@ #include #include "options.h" #include "cnst.h" -#include "prot.h" +#include "prot_fx.h" #include "rom_com.h" #include #include "wmc_auto.h" -#include "prot_fx.h" void wtda_fx32( diff --git a/lib_com/wtda_fx.c b/lib_com/wtda_fx.c index 5f35a3c299fc9aff890d85c361be94182f978ff5..e060984dff14eb316ed1d965e06830487eb1624b 100644 --- a/lib_com/wtda_fx.c +++ b/lib_com/wtda_fx.c @@ -572,7 +572,7 @@ void wtda_ivas_fx( void wtda_ext_fx( const Word16 *new_audio, /* i : input audio (Q_in) */ - Word16 *wtda_audio, /* o : windowed audio (Q_in) */ + Word16 *wtda_audio, /* o : windowed audio (Q_in - 1) */ const Word16 left_mode, /* i : window overlap of previous frame (0: full, 2: none, or 3: half) */ const Word16 right_mode, /* i : window overlap of current frame (0: full, 2: none, or 3: half) */ const Word16 L, /* i : length */ @@ -628,10 +628,10 @@ void wtda_ext_fx( FOR( i = 0; i < L / 2 - n; i += 2 ) { wtda_audio[i] = round_fx( L_mac0( L_mult0( negate( allsig_r[L / 2 - i - 1] ), win_int_right[3 * L_FRAME16k / 2 - i / 2 - 1 - windecay16] ), - allsig_r[L / 2 + i], win_int_right[3 * L_FRAME16k / 2 + i / 2 - windecay16] ) ); // q_in + allsig_r[L / 2 + i], win_int_right[3 * L_FRAME16k / 2 + i / 2 - windecay16] ) ); // q_in - 1 move16(); wtda_audio[i + 1] = round_fx( L_mac0( L_mult0( negate( allsig_r[L / 2 - ( i + 1 ) - 1] ), win_right[( 3 * L_FRAME16k / 2 - i / 2 - 1 ) * decimate + decay - windecay48] ), - allsig_r[L / 2 + i + 1], win_right[( 3 * L_FRAME16k / 2 + 1 + i / 2 ) * decimate - decay - 1 - windecay48] ) ); // q_in + allsig_r[L / 2 + i + 1], win_right[( 3 * L_FRAME16k / 2 + 1 + i / 2 ) * decimate - decay - 1 - windecay48] ) ); // q_in - 1 move16(); } } @@ -640,19 +640,19 @@ void wtda_ext_fx( FOR( i = 0; i < L / 2 - n; i += 2 ) { wtda_audio[i] = round_fx( L_msu0( L_mult0( negate( allsig_r[L / 2 - i - 1] ), win_int_right[3 * L_FRAME16k / 2 - i / 2 - 1 - windecay16] ), - allsig_r[L / 2 + i], win_int_right[3 * L_FRAME16k / 2 + i / 2 - windecay16] ) ); // q_in + allsig_r[L / 2 + i], win_int_right[3 * L_FRAME16k / 2 + i / 2 - windecay16] ) ); // q_in - 1 move16(); wtda_audio[i + 1] = round_fx( L_msu0( L_mult0( negate( allsig_r[L / 2 - ( i + 1 ) - 1] ), win_right[( 3 * L_FRAME16k / 2 - i / 2 - 1 ) * decimate + decay - windecay48] ), - allsig_r[L / 2 + i + 1], win_right[( 3 * L_FRAME16k / 2 + 1 + i / 2 ) * decimate - decay - 1 - windecay48] ) ); // q_in + allsig_r[L / 2 + i + 1], win_right[( 3 * L_FRAME16k / 2 + 1 + i / 2 ) * decimate - decay - 1 - windecay48] ) ); // q_in - 1 move16(); } } FOR( i = L / 2 - n; i < L / 2; i += 2 ) { - wtda_audio[i] = shr( negate( allsig_r[L / 2 - i - 1] ), 1 ); // q_in + wtda_audio[i] = shr( negate( allsig_r[L / 2 - i - 1] ), 1 ); // q_in - 1 move16(); - wtda_audio[i + 1] = shr( negate( allsig_r[L / 2 - ( i + 1 ) - 1] ), 1 ); // q_in + wtda_audio[i + 1] = shr( negate( allsig_r[L / 2 - ( i + 1 ) - 1] ), 1 ); // q_in - 1 move16(); } @@ -661,20 +661,20 @@ void wtda_ext_fx( FOR( i = 0; i < n; i += 2 ) { wtda_audio[i + L / 2] = round_fx( L_msu0( L_mult0( negate( allsig_l[i] ), win_left[( i / 2 ) * decimate + decay] ), - new_audio[n - i - 1], MAX16B ) ); // q_in + new_audio[n - i - 1], MAX16B ) ); // q_in - 1 move16(); wtda_audio[i + L / 2 + 1] = round_fx( L_msu0( L_mult0( negate( allsig_l[i + 1] ), win_int_left[i / 2] ), - new_audio[n - ( i + 1 ) - 1], MAX16B ) ); // q_in + new_audio[n - ( i + 1 ) - 1], MAX16B ) ); // q_in - 1 move16(); } FOR( i = n; i < L / 2; i += 2 ) { wtda_audio[i + L / 2] = round_fx( L_msu0( L_mult0( negate( allsig_l[i] ), win_left[( i / 2 ) * decimate + decay] ), - allsig_l[L - i - 1], win_left[( L / 2 - i / 2 ) * decimate - 1 - decay] ) ); // q_in + allsig_l[L - i - 1], win_left[( L / 2 - i / 2 ) * decimate - 1 - decay] ) ); // q_in - 1 move16(); wtda_audio[i + L / 2 + 1] = round_fx( L_msu0( L_mult0( negate( allsig_l[i + 1] ), win_int_left[i / 2] ), - allsig_l[L - ( i + 1 ) - 1], win_int_left[L / 2 - i / 2 - 1] ) ); // q_in + allsig_l[L - ( i + 1 ) - 1], win_int_left[L / 2 - i / 2 - 1] ) ); // q_in - 1 move16(); } } @@ -683,20 +683,20 @@ void wtda_ext_fx( FOR( i = 0; i < n; i += 2 ) { wtda_audio[i + L / 2] = round_fx( L_msu0( L_mult0( allsig_l[i], win_left[( i / 2 ) * decimate + decay] ), - new_audio[n - i - 1], MAX16B ) ); // q_in + new_audio[n - i - 1], MAX16B ) ); // q_in - 1 move16(); wtda_audio[i + L / 2 + 1] = round_fx( L_msu0( L_mult0( allsig_l[i + 1], win_int_left[i / 2] ), - new_audio[n - ( i + 1 ) - 1], MAX16B ) ); // q_in + new_audio[n - ( i + 1 ) - 1], MAX16B ) ); // q_in - 1 move16(); } FOR( i = n; i < L / 2; i += 2 ) { wtda_audio[i + L / 2] = round_fx( L_msu0( L_mult0( allsig_l[i], win_left[( i / 2 ) * decimate + decay] ), - allsig_l[L - i - 1], win_left[( L / 2 - i / 2 ) * decimate - 1 - decay] ) ); // q_in + allsig_l[L - i - 1], win_left[( L / 2 - i / 2 ) * decimate - 1 - decay] ) ); // q_in - 1 move16(); wtda_audio[i + L / 2 + 1] = round_fx( L_msu0( L_mult0( allsig_l[i + 1], win_int_left[i / 2] ), - allsig_l[L - ( i + 1 ) - 1], win_int_left[L / 2 - i / 2 - 1] ) ); // q_in + allsig_l[L - ( i + 1 ) - 1], win_int_left[L / 2 - i / 2 - 1] ) ); // q_in - 1 move16(); } } @@ -708,7 +708,7 @@ void wtda_ext_fx( FOR( i = 0; i < L / 2 - n; i++ ) { wtda_audio[i] = round_fx( L_mac0( L_mult0( negate( allsig_r[L / 2 - i - 1] ), win_right[3 * L / 2 * decimate - ( i + 1 ) * decimate + decay - windecay48] ), - allsig_r[L / 2 + i], win_right[3 * L / 2 * decimate - 1 + ( i + 1 ) * decimate - decay - windecay48] ) ); // q_in + allsig_r[L / 2 + i], win_right[3 * L / 2 * decimate - 1 + ( i + 1 ) * decimate - decay - windecay48] ) ); // q_in - 1 move16(); } } @@ -717,14 +717,14 @@ void wtda_ext_fx( FOR( i = 0; i < L / 2 - n; i++ ) { wtda_audio[i] = round_fx( L_msu0( L_mult0( negate( allsig_r[L / 2 - i - 1] ), win_right[3 * L / 2 * decimate - ( i + 1 ) * decimate + decay - windecay48] ), - allsig_r[L / 2 + i], win_right[3 * L / 2 * decimate - 1 + ( i + 1 ) * decimate - decay - windecay48] ) ); // q_in + allsig_r[L / 2 + i], win_right[3 * L / 2 * decimate - 1 + ( i + 1 ) * decimate - decay - windecay48] ) ); // q_in - 1 move16(); } } FOR( i = L / 2 - n; i < L / 2; i++ ) { - wtda_audio[i] = shr( negate( allsig_r[L / 2 - i - 1] ), 1 ); // q_in + wtda_audio[i] = shr( negate( allsig_r[L / 2 - i - 1] ), 1 ); // q_in - 1 move16(); } @@ -733,14 +733,14 @@ void wtda_ext_fx( FOR( i = 0; i < n; i++ ) { wtda_audio[i + L / 2] = round_fx( L_msu0( L_mult0( negate( allsig_l[i] ), win_left[i * decimate + decay] ), - new_audio[n - i - 1], MAX16B ) ); // q_in + new_audio[n - i - 1], MAX16B ) ); // q_in - 1 move16(); } FOR( i = n; i < L / 2; i++ ) { wtda_audio[i + L / 2] = round_fx( L_msu0( L_mult0( negate( allsig_l[i] ), win_left[i * decimate + decay] ), - allsig_l[L - i - 1], win_left[L * decimate - i * decimate - 1 - decay] ) ); // q_in + allsig_l[L - i - 1], win_left[L * decimate - i * decimate - 1 - decay] ) ); // q_in - 1 move16(); } } @@ -749,14 +749,14 @@ void wtda_ext_fx( FOR( i = 0; i < n; i++ ) { wtda_audio[i + L / 2] = round_fx( L_msu0( L_mult0( allsig_l[i], win_left[i * decimate + decay] ), - new_audio[n - i - 1], MAX16B ) ); // q_in + new_audio[n - i - 1], MAX16B ) ); // q_in - 1 move16(); } FOR( i = n; i < L / 2; i++ ) { wtda_audio[i + L / 2] = round_fx( L_msu0( L_mult0( allsig_l[i], win_left[i * decimate + decay] ), - allsig_l[L - i - 1], win_left[L * decimate - i * decimate - 1 - decay] ) ); // q_in + allsig_l[L - i - 1], win_left[L * decimate - i * decimate - 1 - decay] ) ); // q_in - 1 move16(); } } diff --git a/lib_debug/debug.c b/lib_debug/debug.c index f1cfa928ab136ad2fb2817655dae23025cf79eed..aafc1b66332ef261ec444a0c2ca4cd269cb1a325 100644 --- a/lib_debug/debug.c +++ b/lib_debug/debug.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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,6 +39,7 @@ #include "options.h" #ifdef DEBUGGING #include "debug.h" +#include #ifdef DEBUG_MODE_INFO #ifdef DEBUG_MODE_INFO_TWEAK #include @@ -363,6 +364,13 @@ int16_t dbgread( { index = in_count; in_fileptr[index] = fopen( filename, "rb" ); +#ifdef DEBUG_FORCE_DIR + if ( in_fileptr[index] == NULL ) + { + /* file does not exist or could not be opened -> just return */ + return -1; + } +#endif in_filename[index] = malloc( sizeof( char ) * ( strlen( filename ) + 1 ) ); strcpy( in_filename[index], filename ); in_count++; @@ -751,7 +759,7 @@ int16_t tweakdbgfolder( const char *filename, char *filename_mod, int16_t *textm #endif -#ifdef DEBUG_MODE_INFO +#ifdef DEBUGGING /*-------------------------------------------------------------------* * fname() * @@ -771,10 +779,21 @@ char *fname( const int16_t id, const int16_t enc_dec ) { - char idd[5] = ".idX"; - idd[3] = (char) ( id + '0' ); + char idd[6]; + + assert( id < 100 ); + sprintf( idd, ".id%d", id ); strcpy( tmp_fname, dir ); +#ifdef DEBUG_FORCE_DIR + size_t len; + len = strlen( tmp_fname ); + if (tmp_fname[len - 1] != '/' && tmp_fname[len - 1] != '\\' ) + { + /* add trailing '/' slash */ + strcat( tmp_fname, "/" ); + } +#endif strcat( tmp_fname, file ); if ( enc_dec == DEC ) diff --git a/lib_debug/debug.h b/lib_debug/debug.h index e88def922b0992a0ba765942089cb59a8d4a76c6..c79ff60465cf7fc043aff2930846e853c02edde2 100644 --- a/lib_debug/debug.h +++ b/lib_debug/debug.h @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other @@ -60,12 +60,16 @@ extern int16_t debug_level; #define DEBUG_LINE( level ) if ( 0 ) #endif -#ifdef DEBUG_MODE_INFO +#ifdef DEBUGGING extern char tmp_fname[]; extern char debug_dir[6]; char *fname( char *dir, char *file, const int16_t n, const int16_t id, const int16_t enc_dec ); #endif +#ifdef DEBUG_FORCE_DIR +#define FORCE_DIR_MAX_LENGTH 255 /* maximum length of the directory for modes/parameters enforcement */ +#endif + /*------------------------------------------------------------------------------------------* * Read/write I/O tool *------------------------------------------------------------------------------------------*/ diff --git a/lib_debug/sba_debug.c b/lib_debug/sba_debug.c index a85bc7be02b5fa643dd1905a3cbea48b030f60ff..c05ae96ef6279111db026a5dadff58fa2ce72045 100644 --- a/lib_debug/sba_debug.c +++ b/lib_debug/sba_debug.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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_debug/sba_debug.h b/lib_debug/sba_debug.h index 60f74401d56816137be28e5723c06c938ee63576..2be427d524e82f92deec2ab9e8c0964374474dab 100644 --- a/lib_debug/sba_debug.h +++ b/lib_debug/sba_debug.h @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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_debug/snr.c b/lib_debug/snr.c index bd8af44e820ea26b29e3baf59dfdc8fc2d0c0cc2..cf15a2907b50dec0580121c2773f91191c8b4afc 100644 --- a/lib_debug/snr.c +++ b/lib_debug/snr.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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_debug/wmc_auto.c b/lib_debug/wmc_auto.c index 731b01e1c14b7e8cad2fd4b922010941855b5224..d357c03dd7d09ed3721a2fd735b48c26978e6fec 100644 --- a/lib_debug/wmc_auto.c +++ b/lib_debug/wmc_auto.c @@ -2499,11 +2499,11 @@ long DeltaWeightedOperation( unsigned int CounterId ) void Reset_BASOP_WMOPS_counter( unsigned int counterId ) { int i; - long *ptr; + unsigned int *ptr; /* reset the current BASOP operation counter */ - ptr = (long *) &multiCounter[counterId]; - for ( i = 0; i < (int) ( sizeof( multiCounter[counterId] ) / sizeof( long ) ); i++ ) + ptr = (unsigned int *) &multiCounter[counterId]; + for ( i = 0; i < (int) (sizeof(BASIC_OP) / sizeof(unsigned int)); i++ ) { *ptr++ = 0; } @@ -2513,4 +2513,4 @@ void Reset_BASOP_WMOPS_counter( unsigned int counterId ) return; } -#endif \ No newline at end of file +#endif diff --git a/lib_debug/wmc_auto.h b/lib_debug/wmc_auto.h index 59bbc5bbf72f54a9ab64216be94d3c5f4ce57800..64e2c751a9261c0e8e02c147f194047f61b83786 100644 --- a/lib_debug/wmc_auto.h +++ b/lib_debug/wmc_auto.h @@ -34,7 +34,7 @@ #define ENH_64_BIT_OPERATOR #define ENH_U_32_BIT_OPERATOR #define COMPLEX_OPERATOR -#define CONTROL_CODE_OPS /* enable control code operators such as LT_16, GT_16, ... */ +#define CONTROL_CODE_OPS /* enable control code operators such as LT_16, GT_16, ... */ #define WMOPS_DISABLE_FCN_CALL_PENALIZATION /* do not count the complexity of function calls */ #ifdef WMOPS @@ -123,7 +123,7 @@ void update_mem( void ); ops_cnt += ( _MULT_C * ( x ) ); \ inst_cnt[_MULT] += ( x ); \ } -#define MAC( x ) \ +#define MAC_C( x ) \ { \ ops_cnt += ( _MAC_C * ( x ) ); \ inst_cnt[_MAC] += ( x ); \ @@ -258,7 +258,7 @@ void update_mem( void ); { \ ops_cnt += ( 2 * _TRANS_C * ( x ) ); \ inst_cnt[_TRANS] += ( x ); \ - } + } #else @@ -273,7 +273,7 @@ extern int cntr_push_pop; #define ADD( x ) #define ABS( x ) #define MULT( x ) -#define MAC( x ) +#define MAC_C( x ) #define MOVE( x ) #define STORE( x ) #define LOGIC( x ) @@ -335,29 +335,29 @@ extern int cntr_push_pop; #endif /* Define all Macros without '{' & '}' (None of these should be called externally!) */ -#define ABS_( x ) OP_COUNT_( _ABS, ( x ) ) -#define ADD_( x ) OP_COUNT_( _ADD, ( x ) ) -#define MULT_( x ) OP_COUNT_( _MULT, ( x ) ) -#define MAC_( x ) OP_COUNT_( _MAC, ( x ) ) -#define MOVE_( x ) OP_COUNT_( _MOVE, ( x ) ) -#define STORE_( x ) OP_COUNT_( _STORE, ( x ) ) -#define LOGIC_( x ) OP_COUNT_( _LOGIC, ( x ) ) -#define SHIFT_( x ) OP_COUNT_( _SHIFT, ( x ) ) -#define BRANCH_( x ) OP_COUNT_( _BRANCH, ( x ) ) -#define DIV_( x ) OP_COUNT_( _DIV, ( x ) ) -#define SQRT_( x ) OP_COUNT_( _SQRT, ( x ) ) -#define TRANS_( x ) OP_COUNT_( _TRANS, ( x ) ) +#define ABS_( x ) OP_COUNT_( _ABS, ( x ) ) +#define ADD_( x ) OP_COUNT_( _ADD, ( x ) ) +#define MULT_( x ) OP_COUNT_( _MULT, ( x ) ) +#define MAC_( x ) OP_COUNT_( _MAC, ( x ) ) +#define MOVE_( x ) OP_COUNT_( _MOVE, ( x ) ) +#define STORE_( x ) OP_COUNT_( _STORE, ( x ) ) +#define LOGIC_( x ) OP_COUNT_( _LOGIC, ( x ) ) +#define SHIFT_( x ) OP_COUNT_( _SHIFT, ( x ) ) +#define BRANCH_( x ) OP_COUNT_( _BRANCH, ( x ) ) +#define DIV_( x ) OP_COUNT_( _DIV, ( x ) ) +#define SQRT_( x ) OP_COUNT_( _SQRT, ( x ) ) +#define TRANS_( x ) OP_COUNT_( _TRANS, ( x ) ) #define POWER_( x ) TRANS_( x ) #define LOG_( x ) TRANS_( x ) -#define LOOP_( x ) OP_COUNT_( _LOOP, ( x ) ) -#define INDIRECT_( x ) OP_COUNT_( _INDIRECT, ( x ) ) -#define PTR_INIT_( x ) OP_COUNT_( _PTR_INIT, ( x ) ) +#define LOOP_( x ) OP_COUNT_( _LOOP, ( x ) ) +#define INDIRECT_( x ) OP_COUNT_( _INDIRECT, ( x ) ) +#define PTR_INIT_( x ) OP_COUNT_( _PTR_INIT, ( x ) ) #ifdef WMOPS_DISABLE_FCN_CALL_PENALIZATION -#define FUNC_( x ) ( x ) +#define FUNC_( x ) ( x ) #else -#define FUNC_( x ) ( OP_COUNT_( _MOVE, ( x ) ), OP_COUNT_( _FUNC, 1 ) ) +#define FUNC_( x ) ( OP_COUNT_( _MOVE, ( x ) ), OP_COUNT_( _FUNC, 1 ) ) #endif -#define MISC_( x ) ABS_( x ) +#define MISC_( x ) ABS_( x ) /* Math Operations */ #define abs_ OP_COUNT_WRAPPER1_( ABS_( 1 ), abs ) @@ -401,8 +401,8 @@ extern int cntr_push_pop; #define frexp_ OP_COUNT_WRAPPER1_( MISC_( 2 ), frexp ) #define frexpf_ OP_COUNT_WRAPPER1_( MISC_( 2 ), frexpf ) -/* the macros below are instrumented versions of user-defined macros that might be used in the source code - representing some well-known and recognized mathematical operations (that are not defined in math.h) +/* the macros below are instrumented versions of user-defined macros that might be used in the source code + representing some well-known and recognized mathematical operations (that are not defined in math.h) Note: the 'wmc_flag_=wmc_flag_' is used to avoid warning: left-hand operand of comma expression has no effect with gcc */ #define min_( a, b ) OP_COUNT_WRAPPER1_( MISC_( 1 ), min( ( a ), ( b ) ) ) @@ -928,7 +928,7 @@ typedef struct unsigned int Madd_32_32_r; /* Complexity Weight of 1 */ unsigned int Msub_32_32; /* Complexity Weight of 1 */ unsigned int Msub_32_32_r; /* Complexity Weight of 1 */ -#endif /* #ifdef ENH_32_BIT_OPERATOR */ +#endif /* #ifdef ENH_32_BIT_OPERATOR */ #ifdef ENH_U_32_BIT_OPERATOR unsigned int UL_addNs; /* Complexity Weight of 1 */ @@ -938,7 +938,7 @@ typedef struct unsigned int Mpy_32_16_uu; /* Complexity Weight of 2 */ unsigned int norm_ul_float; /* Complexity Weight of 1 */ unsigned int UL_deposit_l; /* Complexity Weight of 1 */ -#endif /* #ifdef ENH_U_32_BIT_OPERATOR */ +#endif /* #ifdef ENH_U_32_BIT_OPERATOR */ #ifdef CONTROL_CODE_OPS unsigned int LT_16; /* Complexity Weight of 1 */ @@ -1095,7 +1095,9 @@ void incrIf( const char *func_name ); #ifndef WMOPS #define ELSE else #else /* ifndef WMOPS */ -#define ELSE else if ( incrElse( __func__ ), 0 ); else +#define ELSE \ + else if ( incrElse( __func__ ), 0 ); \ + else void incrElse( const char *func_name ); #endif /* ifndef WMOPS */ diff --git a/lib_dec/ACcontextMapping_dec.c b/lib_dec/ACcontextMapping_dec.c deleted file mode 100644 index cf5b4a9b7daa4d9139d1be45f8dec3f96ad4dd39..0000000000000000000000000000000000000000 --- a/lib_dec/ACcontextMapping_dec.c +++ /dev/null @@ -1,45 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include "cnst.h" -#include "rom_com.h" -#include "ivas_rom_com.h" -#include "prot.h" -#include "wmc_auto.h" -#include "ivas_prot.h" /* Range coder header file */ -#include diff --git a/lib_dec/ACcontextMapping_dec_fx.c b/lib_dec/ACcontextMapping_dec_fx.c index 34e74a06f9ae9d5f1838d46efb8007cec71a00d8..22e9fff0114f1f5c0d3b5057744a446f95a0a0bb 100644 --- a/lib_dec/ACcontextMapping_dec_fx.c +++ b/lib_dec/ACcontextMapping_dec_fx.c @@ -12,7 +12,6 @@ #include "prot_fx.h" #include "ivas_prot_fx.h" -#include "ivas_prot.h" #include "ivas_rom_com.h" /*-------------------------------------------------------------------* * ACcontextMapping_decode2_no_mem_s17_LC() diff --git a/lib_dec/FEC.c b/lib_dec/FEC.c deleted file mode 100644 index fc669bf26e5d7f47a17d6e62ec8ebfb50941216e..0000000000000000000000000000000000000000 --- a/lib_dec/FEC.c +++ /dev/null @@ -1,54 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include -#include "cnst.h" -#include "rom_com.h" -#include "rom_dec.h" -#include "prot.h" -#include "wmc_auto.h" - - -#define WMC_TOOL_SKIP -/*-------------------------------------------------------------------* - * pulseRes_preCalc() - * - * calculates some conditions for Pulse resynchronization to take place - *-------------------------------------------------------------------*/ - -#undef WMC_TOOL_SKIP diff --git a/lib_dec/FEC_HQ_core.c b/lib_dec/FEC_HQ_core.c deleted file mode 100644 index 794f6dab36c75867d5d0cb3e0b91766f37586557..0000000000000000000000000000000000000000 --- a/lib_dec/FEC_HQ_core.c +++ /dev/null @@ -1,136 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include -#include "cnst.h" -#include "rom_dec.h" -#include "rom_com.h" -#include "prot.h" -#include "wmc_auto.h" -#include "prot_fx.h" - - -void save_synthesis_hq_fec_fx( - Decoder_State *st, /* i/o: decoder state structure */ - const Word32 output_fx[], /* i : decoded synthesis */ - const Word16 output_frame, /* i : decoded synthesis */ - CPE_DEC_HANDLE hCPE /* i : CPE decoder structure */ -) -{ - Word16 post_hq_delay; - - SWITCH( st->element_mode ) - { - case EVS_MONO: - post_hq_delay = NS2SA_FX2( st->output_Fs, POST_HQ_DELAY_NS ); - BREAK; - case IVAS_SCE: - post_hq_delay = NS2SA_FX2( st->output_Fs, DELAY_CLDFB_NS ); - BREAK; - case IVAS_CPE_DFT: - test(); - IF( EQ_16( hCPE->nchan_out, 1 ) && hCPE->hStereoDft->hConfig->res_cod_mode == STEREO_DFT_RES_COD_OFF ) - { - post_hq_delay = NS2SA_FX2( st->output_Fs, DELAY_CLDFB_NS ); - } - ELSE - { - post_hq_delay = 0; - move16(); - } - BREAK; - default: - post_hq_delay = 0; - move16(); - BREAK; - } - - test(); - test(); - test(); - test(); - test(); - IF( ( EQ_16( st->codec_mode, MODE1 ) && st->hTcxDec != NULL ) && ( ( ( st->core == ACELP_CORE ) && !( EQ_16( st->bfi, 1 ) && EQ_16( st->con_tcx, 1 ) ) ) || EQ_16( st->core, HQ_CORE ) ) ) - { - Copy( st->hTcxDec->synth_history_fx + output_frame, st->hTcxDec->synth_history_fx, add( sub( output_frame, post_hq_delay ), NS2SA_FX2( st->output_Fs, PH_ECU_MEM_NS ) ) ); - FOR( Word16 i = 0; i < output_frame; i++ ) - { - st->hTcxDec->old_synthFB_fx[( ( i + output_frame ) - post_hq_delay )] = extract_h( L_shl_sat( output_fx[i], 16 ) ); // Q16 - move16(); - } - - IF( st->element_mode == EVS_MONO ) - { - /* reset the remaining buffer, which is read in TCX concealment the necessary samples to fill - this buffer are not available for all cases, the impact on the output is limited */ - - set16_fx( st->hTcxDec->old_synthFB_fx + sub( shl( output_frame, 1 ), post_hq_delay ), 0, post_hq_delay ); - IF( GE_16( output_frame, L_FRAME16k ) ) - { - Copy( st->prev_synth_buffer_fx, st->hTcxDec->old_synthFB_fx + sub( shl( output_frame, 1 ), NS2SA_FX2( st->output_Fs, DELAY_BWE_TOTAL_NS ) ), NS2SA_FX2( st->output_Fs, DELAY_BWE_TOTAL_NS - DELAY_CLDFB_NS ) ); - } - ELSE - { - Copy( st->hHQ_core->old_out_fx + NS2SA_FX2( st->output_Fs, N_ZERO_MDCT_NS ), st->hTcxDec->old_synthFB_fx + shl( output_frame, 1 ), NS2SA_FX2( st->output_Fs, PH_ECU_LOOKAHEAD_NS ) ); - } - - IF( st->core != ACELP_CORE ) - { - IF( GE_16( output_frame, L_FRAME16k ) ) - { - Copy( st->delay_buf_out_fx, st->hTcxDec->old_synthFB_fx + sub( shl( output_frame, 1 ), NS2SA_FX2( st->output_Fs, DELAY_CLDFB_NS ) ), NS2SA_FX2( st->output_Fs, DELAY_CLDFB_NS ) ); - Copy( st->hHQ_core->old_out_fx + NS2SA_FX2( st->output_Fs, N_ZERO_MDCT_NS ), st->hTcxDec->old_synthFB_fx + shl( output_frame, 1 ), NS2SA_FX2( st->output_Fs, PH_ECU_LOOKAHEAD_NS ) ); - } - ELSE - { - Copy( st->delay_buf_out_fx, st->hTcxDec->old_synthFB_fx + sub( shl( output_frame, 1 ), NS2SA_FX2( st->output_Fs, DELAY_BWE_TOTAL_NS ) ), NS2SA_FX2( st->output_Fs, DELAY_CLDFB_NS ) ); - Copy( st->hHQ_core->old_out_fx + NS2SA_FX2( st->output_Fs, N_ZERO_MDCT_NS ), st->hTcxDec->old_synthFB_fx + sub( shl( output_frame, 1 ), NS2SA_FX2( st->output_Fs, DELAY_BWE_TOTAL_NS - DELAY_CLDFB_NS ) ), NS2SA_FX2( st->output_Fs, PH_ECU_LOOKAHEAD_NS ) ); - } - } - } - ELSE - { - IF( st->core != ACELP_CORE ) - { - Copy( st->delay_buf_out_fx, st->hTcxDec->old_synthFB_fx + sub( shl( output_frame, 1 ), post_hq_delay ), post_hq_delay ); - Copy( st->hHQ_core->old_out_fx + NS2SA_FX2( st->output_Fs, N_ZERO_MDCT_NS ), st->hTcxDec->old_synthFB_fx + shl( output_frame, 1 ), NS2SA_FX2( st->output_Fs, PH_ECU_LOOKAHEAD_NS ) ); - } - } - } - return; -} diff --git a/lib_dec/FEC_HQ_core_fx.c b/lib_dec/FEC_HQ_core_fx.c index 01002b56b665bd15f18fc5908b93b9006a00dff5..09bc652be8b7cfbb370f18938ca0ac32632bcb56 100644 --- a/lib_dec/FEC_HQ_core_fx.c +++ b/lib_dec/FEC_HQ_core_fx.c @@ -78,13 +78,8 @@ static void Regression_Anal_fx( { b_p_fx[0] = L_add( b_p_fx[0], L_shr( values_fx[i], 2 ) ); /*10 */ move32(); -#ifdef BASOP_NOGLOB b_p_fx[1] = L_add( b_p_fx[1], Mult_32_16( values_fx[i], shl_o( sub( num_pgf, i ), 13, &Overflow ) ) ); /*10 */ move32(); -#else - b_p_fx[1] = L_add( b_p_fx[1], Mult_32_16( values_fx[i], shl( sub( num_pgf, i ), 13 ) ) ); /*10 */ - move32(); -#endif } tmp = sub( i_mult( aindex_fx[0], aindex_fx[2] ), i_mult( aindex_fx[1], aindex_fx[1] ) ); @@ -378,11 +373,7 @@ void HQ_FEC_processing_fx( exp2 = norm_l( norm_values_fx[0] ); tmp_fx = div_s( extract_h( L_shl( norm_p_fx[i], exp1 ) ), extract_h( L_shl( norm_values_fx[0], exp2 ) ) ); /*15 + (5 + exp1 - 16) - (12 + exp2 - 16)*/ -#ifdef BASOP_NOGLOB - tmp_fx = shl_sat( tmp_fx, add( 6, sub( exp2, exp1 ) ) ); /*14*/ -#else - tmp_fx = shl( tmp_fx, add( 6, sub( exp2, exp1 ) ) ); /*14*/ -#endif + tmp_fx = shl_sat( tmp_fx, add( 6, sub( exp2, exp1 ) ) ); /*14*/ if ( GT_16( tmp_fx, 16384 ) ) { tmp_fx = 16384; @@ -391,14 +382,9 @@ void HQ_FEC_processing_fx( FOR( j = 0; j < Num_bands_p[i]; j++ ) { -#ifdef BASOP_NOGLOB hHQ_nbfec->Norm_gain_fx[k] = shl_o( tmp_fx, 1, &Overflow ); move16(); k = add( k, 1 ); -#else - hHQ_nbfec->Norm_gain_fx[k++] = shl( tmp_fx, 1 ); - move16(); -#endif } } ELSE @@ -532,12 +518,8 @@ void ivas_HQ_FEC_Mem_update_fx( L_tmp = L_add( L_tmp, L_shr( normq_fx[k], 3 ) ); /*11*/ k = add( k, 1 ); } -#ifdef BASOP_NOGLOB tmp_fx = shl_o( inv_tbl_fx[Num_bands_p[i]], 1, &Overflow ); /*16*/ -#else - tmp_fx = shl( inv_tbl_fx[Num_bands_p[i]], 1 ); /*16*/ -#endif - norm_values_fx[0] = Mult_32_16( L_tmp, tmp_fx ); /*11 + 16 - 15*/ + norm_values_fx[0] = Mult_32_16( L_tmp, tmp_fx ); /*11 + 16 - 15*/ move32(); tmp_energy_fx = L_add( tmp_energy_fx, L_shr( L_tmp, 3 ) ); /*8*/ } @@ -656,11 +638,7 @@ void ivas_HQ_FEC_Mem_update_fx( exp2 = norm_l( hHQ_nbfec->ynrm_values_fx[i][0] ); tmp_fx = div_s( extract_h( L_shl( en_high_fx[i], exp1 ) ), extract_h( L_shl( hHQ_nbfec->ynrm_values_fx[i][0], exp2 ) ) ); exp = add( 15, sub( exp1, exp2 ) ); -#ifdef BASOP_NOGLOB *mean_en_high_fx = add_o( *mean_en_high_fx, shr_o( tmp_fx, sub( exp, 5 ), &Overflow ), &Overflow ); -#else - *mean_en_high_fx = add( *mean_en_high_fx, shr( tmp_fx, sub( exp, 5 ) ) ); -#endif move16(); } *mean_en_high_fx = mult( *mean_en_high_fx, inv_tbl_fx[sub( num_Sb, k )] ); @@ -829,12 +807,8 @@ void HQ_FEC_Mem_update_fx( L_tmp = L_add( L_tmp, L_shr( normq_fx[k], 3 ) ); /*11*/ k = add( k, 1 ); } -#ifdef BASOP_NOGLOB tmp_fx = shl_o( inv_tbl_fx[Num_bands_p[i]], 1, &Overflow ); /*16*/ -#else - tmp_fx = shl( inv_tbl_fx[Num_bands_p[i]], 1 ); /*16*/ -#endif - norm_values_fx[0] = Mult_32_16( L_tmp, tmp_fx ); /*11 + 16 - 15*/ + norm_values_fx[0] = Mult_32_16( L_tmp, tmp_fx ); /*11 + 16 - 15*/ move32(); tmp_energy_fx = L_add( tmp_energy_fx, L_shr( L_tmp, 3 ) ); /*8*/ } @@ -857,12 +831,8 @@ void HQ_FEC_Mem_update_fx( move16(); /*15*/ L_tmp = Mult_32_16( tmp_energy_fx, tmp_fx ); /*8 + 15 - 15*/ -#ifdef BASOP_NOGLOB hHQ_nbfec->energy_MA_Curr_fx[1] = extract_h( L_shl_sat( L_tmp, 16 - 8 ) ); move16(); -#else - hHQ_nbfec->energy_MA_Curr_fx[1] = extract_h( L_shl( L_tmp, 16 - 8 ) ); -#endif /* Moving Average */ hHQ_nbfec->energy_MA_Curr_fx[0] = s_max( 1, add( mult_r( 26214, hHQ_nbfec->energy_MA_Curr_fx[0] ), mult_r( 6554, hHQ_nbfec->energy_MA_Curr_fx[1] ) ) ); move16(); @@ -958,11 +928,7 @@ void HQ_FEC_Mem_update_fx( exp2 = norm_l( hHQ_nbfec->ynrm_values_fx[i][0] ); tmp_fx = div_s( extract_h( L_shl( en_high_fx[i], exp1 ) ), extract_h( L_shl( hHQ_nbfec->ynrm_values_fx[i][0], exp2 ) ) ); exp = add( 15, sub( exp1, exp2 ) ); -#ifdef BASOP_NOGLOB *mean_en_high_fx = add_o( *mean_en_high_fx, shr_o( tmp_fx, sub( exp, 5 ), &Overflow ), &Overflow ); -#else - *mean_en_high_fx = add( *mean_en_high_fx, shr( tmp_fx, sub( exp, 5 ) ) ); -#endif move16(); } *mean_en_high_fx = mult( *mean_en_high_fx, inv_tbl_fx[sub( num_Sb, k )] ); @@ -1049,13 +1015,8 @@ static Word16 find_best_delay_fx( accB_fx = L_deposit_l( 0 ); FOR( i = 0; i < lin; i += delta ) { -#ifdef BASOP_NOGLOB accA_fx = L_add_sat( accA_fx, L_shr( L_mult_sat( mu_o_fx[d1 + i], mu_o_fx[d1 + i] ), 2 ) ); accB_fx = L_add_sat( accB_fx, L_shr( L_mult_sat( mu_o_fx[d1 + i], in_fx[i] ), 2 ) ); -#else - accA_fx = L_add( accA_fx, L_shr( L_mult( mu_o_fx[d1 + i], mu_o_fx[d1 + i] ), 2 ) ); - accB_fx = L_add( accB_fx, L_shr( L_mult( mu_o_fx[d1 + i], in_fx[i] ), 2 ) ); -#endif } Rxy_fx[k] = accB_fx; @@ -1107,12 +1068,8 @@ static Word16 find_best_delay_fx( exp2 = norm_l( min_corr_fx ); L_tmp1 = L_shl( min_sq_cross_fx, exp1 ); L_tmp2 = L_shl( min_corr_fx, exp2 ); - tmp = div_s( extract_h( L_tmp1 ), extract_h( L_tmp2 ) ); /*15 + exp1 - exp2 */ -#ifdef BASOP_NOGLOB + tmp = div_s( extract_h( L_tmp1 ), extract_h( L_tmp2 ) ); /*15 + exp1 - exp2 */ tmp = shl_o( tmp, sub( exp2, add( exp1, 1 ) ), &Overflow ); /*14 */ -#else - tmp = shl( tmp, sub( exp2, add( exp1, 1 ) ) ); /*14 */ -#endif } *false_flag = 0; @@ -1306,11 +1263,7 @@ static Word16 FEC_phase_matching_fx( tmp = shl( tmp, sub( sub( exp2, exp1 ), 1 ) ); /*14*/ FOR( i = N_ZERO_NB; i < L * 2; i++ ) { -#ifdef BASOP_NOGLOB ImdctOutWin_fx[i] = shl_sat( mult( ImdctOutWin_fx[i], tmp ), 1 ); -#else - ImdctOutWin_fx[i] = shl( mult( ImdctOutWin_fx[i], tmp ), 1 ); -#endif move16(); } } @@ -1582,11 +1535,7 @@ static void Repetition_smoothing_nextgood_fx( /*mvr2r(&ImdctOutWin[L], OldauOut, L);*/ FOR( i = 0; i < L; i++ ) { -#ifdef BASOP_NOGLOB auOut_fx[i] = add_sat( ImdctOutWin_fx[N_ZERO_NB + i], OldauOut_fx[i] ); // Q0 -#else - auOut_fx[i] = add( ImdctOutWin_fx[N_ZERO_NB + i], OldauOut_fx[i] ); -#endif move16(); } Copy( &ImdctOutWin_fx[L], OldauOut_fx, L ); @@ -1678,11 +1627,7 @@ static void common_overlapping_fx( FOR( i = 0; i < end1; i++ ) { /*auOut_fx[i] = L_add(ImdctOutWin_fx[i+7*L/20], OldauOut_fx[i+offset1]);*/ -#ifdef BASOP_NOGLOB auOut_fx[i] = add_sat( ImdctOutWin_fx[i + N_ZERO_NB], OldauOut_fx[i + offset1] ); -#else - auOut_fx[i] = add( ImdctOutWin_fx[i + N_ZERO_NB], OldauOut_fx[i + offset1] ); -#endif move16(); } FOR( i = start2; i < end2; i++ ) @@ -2016,6 +1961,98 @@ static void Next_good_after_burst_erasures_fx( return; } + +void save_synthesis_hq_fec_fx( + Decoder_State *st, /* i/o: decoder state structure */ + const Word32 output_fx[], /* i : decoded synthesis */ + const Word16 output_frame, /* i : decoded synthesis */ + CPE_DEC_HANDLE hCPE /* i : CPE decoder structure */ +) +{ + Word16 post_hq_delay; + + SWITCH( st->element_mode ) + { + case EVS_MONO: + post_hq_delay = NS2SA_FX2( st->output_Fs, POST_HQ_DELAY_NS ); + BREAK; + case IVAS_SCE: + post_hq_delay = NS2SA_FX2( st->output_Fs, DELAY_CLDFB_NS ); + BREAK; + case IVAS_CPE_DFT: + test(); + IF( EQ_16( hCPE->nchan_out, 1 ) && hCPE->hStereoDft->hConfig->res_cod_mode == STEREO_DFT_RES_COD_OFF ) + { + post_hq_delay = NS2SA_FX2( st->output_Fs, DELAY_CLDFB_NS ); + } + ELSE + { + post_hq_delay = 0; + move16(); + } + BREAK; + default: + post_hq_delay = 0; + move16(); + BREAK; + } + + test(); + test(); + test(); + test(); + test(); + IF( ( EQ_16( st->codec_mode, MODE1 ) && st->hTcxDec != NULL ) && ( ( ( st->core == ACELP_CORE ) && !( EQ_16( st->bfi, 1 ) && EQ_16( st->con_tcx, 1 ) ) ) || EQ_16( st->core, HQ_CORE ) ) ) + { + Copy( st->hTcxDec->synth_history_fx + output_frame, st->hTcxDec->synth_history_fx, add( sub( output_frame, post_hq_delay ), NS2SA_FX2( st->output_Fs, PH_ECU_MEM_NS ) ) ); + FOR( Word16 i = 0; i < output_frame; i++ ) + { + st->hTcxDec->old_synthFB_fx[( ( i + output_frame ) - post_hq_delay )] = extract_h( L_shl_sat( output_fx[i], 16 ) ); // Q16 + move16(); + } + + IF( st->element_mode == EVS_MONO ) + { + /* reset the remaining buffer, which is read in TCX concealment the necessary samples to fill + this buffer are not available for all cases, the impact on the output is limited */ + + set16_fx( st->hTcxDec->old_synthFB_fx + sub( shl( output_frame, 1 ), post_hq_delay ), 0, post_hq_delay ); + IF( GE_16( output_frame, L_FRAME16k ) ) + { + Copy( st->prev_synth_buffer_fx, st->hTcxDec->old_synthFB_fx + sub( shl( output_frame, 1 ), NS2SA_FX2( st->output_Fs, DELAY_BWE_TOTAL_NS ) ), NS2SA_FX2( st->output_Fs, DELAY_BWE_TOTAL_NS - DELAY_CLDFB_NS ) ); + } + ELSE + { + Copy( st->hHQ_core->old_out_fx + NS2SA_FX2( st->output_Fs, N_ZERO_MDCT_NS ), st->hTcxDec->old_synthFB_fx + shl( output_frame, 1 ), NS2SA_FX2( st->output_Fs, PH_ECU_LOOKAHEAD_NS ) ); + } + + IF( st->core != ACELP_CORE ) + { + IF( GE_16( output_frame, L_FRAME16k ) ) + { + Copy( st->delay_buf_out_fx, st->hTcxDec->old_synthFB_fx + sub( shl( output_frame, 1 ), NS2SA_FX2( st->output_Fs, DELAY_CLDFB_NS ) ), NS2SA_FX2( st->output_Fs, DELAY_CLDFB_NS ) ); + Copy( st->hHQ_core->old_out_fx + NS2SA_FX2( st->output_Fs, N_ZERO_MDCT_NS ), st->hTcxDec->old_synthFB_fx + shl( output_frame, 1 ), NS2SA_FX2( st->output_Fs, PH_ECU_LOOKAHEAD_NS ) ); + } + ELSE + { + Copy( st->delay_buf_out_fx, st->hTcxDec->old_synthFB_fx + sub( shl( output_frame, 1 ), NS2SA_FX2( st->output_Fs, DELAY_BWE_TOTAL_NS ) ), NS2SA_FX2( st->output_Fs, DELAY_CLDFB_NS ) ); + Copy( st->hHQ_core->old_out_fx + NS2SA_FX2( st->output_Fs, N_ZERO_MDCT_NS ), st->hTcxDec->old_synthFB_fx + sub( shl( output_frame, 1 ), NS2SA_FX2( st->output_Fs, DELAY_BWE_TOTAL_NS - DELAY_CLDFB_NS ) ), NS2SA_FX2( st->output_Fs, PH_ECU_LOOKAHEAD_NS ) ); + } + } + } + ELSE + { + IF( st->core != ACELP_CORE ) + { + Copy( st->delay_buf_out_fx, st->hTcxDec->old_synthFB_fx + sub( shl( output_frame, 1 ), post_hq_delay ), post_hq_delay ); + Copy( st->hHQ_core->old_out_fx + NS2SA_FX2( st->output_Fs, N_ZERO_MDCT_NS ), st->hTcxDec->old_synthFB_fx + shl( output_frame, 1 ), NS2SA_FX2( st->output_Fs, PH_ECU_LOOKAHEAD_NS ) ); + } + } + } + return; +} + + #ifdef ADD_IVAS_HQ_CODE_FEC /*-------------------------------------------------------------------------- * save_synthesis_hq_fec() diff --git a/lib_dec/FEC_HQ_phase_ecu.c b/lib_dec/FEC_HQ_phase_ecu.c deleted file mode 100644 index 2df90bf117b7384825a00d5521e06605170c3e63..0000000000000000000000000000000000000000 --- a/lib_dec/FEC_HQ_phase_ecu.c +++ /dev/null @@ -1,44 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include -#include "rom_dec.h" -#include "rom_com.h" -#include "cnst.h" -#include "prot.h" -#include "wmc_auto.h" diff --git a/lib_dec/FEC_HQ_phase_ecu_fx.c b/lib_dec/FEC_HQ_phase_ecu_fx.c index f31f20af5e6b633270f0244618bbc1ed75055802..34d01d7fe0ea41b37e77e9096bfc0ebedb3f5128 100644 --- a/lib_dec/FEC_HQ_phase_ecu_fx.c +++ b/lib_dec/FEC_HQ_phase_ecu_fx.c @@ -491,23 +491,15 @@ static void trans_ana_fx( tr_dec[k] = 0; move16(); Mpy_32_16_ss( *pGrPowLeft, THRESH_TR_LIN_BY2_FX, &acc, &lsb ); /* To facilitate fixed-point implementation, divide threshold by 2. */ -#ifdef BASOP_NOGLOB - acc = L_or( L_shl_sat( acc, 16 ), L_and( 0xffffL, lsb ) ); /* Equivalent to concatenate acc and lsb, and then down shift by 16 bits. */ -#else - acc = L_or( L_shl( acc, 16 ), L_and( 0xffffL, lsb ) ); /* Equivalent to concatenate acc and lsb, and then down shift by 16 bits. */ -#endif - if ( GT_32( *pGrPowRight, acc ) ) /* gr_pow_right > thres_tr_lin*gr_pow_left */ + acc = L_or( L_shl_sat( acc, 16 ), L_and( 0xffffL, lsb ) ); /* Equivalent to concatenate acc and lsb, and then down shift by 16 bits. */ + if ( GT_32( *pGrPowRight, acc ) ) /* gr_pow_right > thres_tr_lin*gr_pow_left */ { tr_dec[k] = 1; move16(); } Mpy_32_16_ss( *pGrPowRight, THRESH_TR_LIN_BY2_FX, &acc, &lsb ); -#ifdef BASOP_NOGLOB acc = L_or( L_shl_sat( acc, 16 ), L_and( 0xffffL, lsb ) ); /* Equivalent to concatenate acc and lsb, and then down shift by 16 bits. */ -#else - acc = L_or( L_shl( acc, 16 ), L_and( 0xffffL, lsb ) ); /* Equivalent to concatenate acc and lsb, and then down shift by 16 bits. */ -#endif - if ( GT_32( *pGrPowLeft, acc ) ) /* gr_pow_left > thres_tr_lin*gr_pow_right */ + if ( GT_32( *pGrPowLeft, acc ) ) /* gr_pow_left > thres_tr_lin*gr_pow_right */ { tr_dec[k] = 1; move16(); @@ -1274,13 +1266,9 @@ static Word16 imax_fx( /* o: The location, relative to the } /* Although the output of ratio() is in Q14, adding the missing factor of 2 (See above) * in the denominator, the output is now considered to be in Q15. */ - man = ratio( numer, denom, &expo ); /* The mantissa is considered in Q15 */ -#ifdef BASOP_NOGLOB + man = ratio( numer, denom, &expo ); /* The mantissa is considered in Q15 */ posi = shr_o( man, expo, &Overflow ); /* in Q15 (Due to saturation, it is automatically bound inside [-1.0,1.0].) */ -#else - posi = shr( man, expo ); /* in Q15 (Due to saturation, it is automatically bound inside [-1.0,1.0].) */ -#endif - if ( sign < 0 ) /* Restore the sign. */ + if ( sign < 0 ) /* Restore the sign. */ { posi = negate( posi ); } @@ -1602,7 +1590,11 @@ static void ivas_spec_ana_fx( test(); IF( n > 0 && *pPlocs == 0 ) /* Very 1st peak position possible to have a peak at 0/DC index position. */ { - Copy_Scale_sig_16_32( &xfp[*pPlocs], xfp_32, 3, Q16 ); // Q + 16 +#ifdef FIX_ISSUE_1237 + Copy_Scale_sig_16_32_no_sat( &xfp[*pPlocs], xfp_32, 3, Q15 ); // Q + 15 +#else + Copy_Scale_sig_16_32_DEPREC( &xfp[*pPlocs], xfp_32, 3, Q16 ); // Q + 16 +#endif acc = L_deposit_h( *pPlocs ); // Q16 *pPlocsi++ = L_add( acc, L_shl( imax_pos_fx( xfp_32 ) /* Q15 */, 1 ) ); // Q16 move32(); @@ -1613,7 +1605,11 @@ static void ivas_spec_ana_fx( test(); IF( n > 0 && EQ_16( *pPlocs, 1 ) ) /* Also 2nd peak position uses DC which makes jacobsen unsuitable. */ { - Copy_Scale_sig_16_32( &xfp[*pPlocs - 1], xfp_32, 3, Q16 ); // Q + 16 +#ifdef FIX_ISSUE_1237 + Copy_Scale_sig_16_32_no_sat( &xfp[*pPlocs - 1], xfp_32, 3, Q15 ); // Q + 15 +#else + Copy_Scale_sig_16_32_DEPREC( &xfp[*pPlocs - 1], xfp_32, 3, Q16 ); // Q + 16 +#endif acc = L_deposit_h( sub( *pPlocs, 1 ) ); // Q16 *pPlocsi++ = L_add( acc, L_shl( imax_pos_fx( xfp_32 ) /* Q15 */, 1 ) ); // Q16 move32(); @@ -1659,7 +1655,11 @@ static void ivas_spec_ana_fx( IF( EQ_16( currPlocs, ( sub( Lprot2_1, DELTA_CORR_F0_INT ) ) ) ) /* Also 2nd last peak position uses fs/2 which makes jacobsen less suitable. */ { - Copy_Scale_sig_16_32( &xfp[currPlocs - 1], xfp_32, 3, Q16 ); // Q + 16 +#ifdef FIX_ISSUE_1237 + Copy_Scale_sig_16_32_no_sat( &xfp[currPlocs - 1], xfp_32, 3, Q15 ); // Q + 15 +#else + Copy_Scale_sig_16_32_DEPREC( &xfp[currPlocs - 1], xfp_32, 3, Q16 ); // Q + 16 +#endif acc = L_deposit_h( sub( currPlocs, 1 ) ); // Q16 *pPlocsi++ = L_add( acc, L_shl( imax_pos_fx( xfp_32 ) /* Q15 */, 1 ) ); // Q16 move32(); @@ -1673,7 +1673,11 @@ static void ivas_spec_ana_fx( * whould point */ IF( n > 0 ) /* fs/2 which makes special case . */ { - Copy_Scale_sig_16_32( &xfp[currPlocs - 2], xfp_32, 3, Q16 ); // Q + 16 +#ifdef FIX_ISSUE_1237 + Copy_Scale_sig_16_32_no_sat( &xfp[currPlocs - 2], xfp_32, 3, Q15 ); // Q + 15 +#else + Copy_Scale_sig_16_32_DEPREC( &xfp[currPlocs - 2], xfp_32, 3, Q16 ); // Q + 16 +#endif acc = L_deposit_h( sub( currPlocs, 2 ) ); // Q16 *pPlocsi++ = L_add( acc, L_shl( imax_pos_fx( xfp_32 ) /* Q15 */, 1 ) ); // Q16 move32(); @@ -1884,11 +1888,7 @@ static void spec_ana_fx( man = mult_r( man, FEC_HQ_ECU_ROOT2 ); /* FEC_HQ_ECU_ROOT2 is sqrt(2) in Q14 */ expoBy2 = sub( expoBy2, 1 ); } -#ifdef BASOP_NOGLOB *pXfp++ = shr_sat( man, expoBy2 ); -#else - *pXfp++ = shr( man, expoBy2 ); -#endif move16(); /* Denormalize the mantissa back to Q0. */ } } @@ -2156,7 +2156,7 @@ static void ivas_subst_spec_fx( ELSE { // tmp = NS2SA(output_frame*50,PH_ECU_ALDO_OLP2_NS-PH_ECU_LOOKAHEAD_NS); - tmp = NS2SA_FX2( output_frame * 50, PH_ECU_ALDO_OLP2_NS ); + tmp = NS2SA_FX2( L_mult0( output_frame, 50 ), PH_ECU_ALDO_OLP2_NS ); move16(); tmp = sub( tmp, ph_ecu_lookahead ); tmp = add( tmp, sub( Lecu, shr( sub( Lecu, Lprot ), 1 ) ) ); @@ -2559,7 +2559,7 @@ static void subst_spec_fx( } ELSE { - tmp = NS2SA( output_frame * 50, PH_ECU_ALDO_OLP2_NS - PH_ECU_LOOKAHEAD_NS ); + tmp = NS2SA_FX2( L_mult0( output_frame, 50 ), PH_ECU_ALDO_OLP2_NS - PH_ECU_LOOKAHEAD_NS ); move16(); tmp = add( tmp, sub( Lecu, shr( sub( Lecu, Lprot ), 1 ) ) ); tmp = sub( tmp, shr( output_frame, 1 ) ); @@ -2786,13 +2786,8 @@ static void subst_spec_fx( IF( EQ_16( element_mode, EVS_MONO ) ) #endif { -#ifdef BASOP_NOGLOB tmp = sub_sat( mult_r( re, cos_F ), mult_r( im, sin_F ) ); im = add_sat( mult_r( re, sin_F ), mult_r( im, cos_F ) ); -#else - tmp = sub( mult_r( re, cos_F ), mult_r( im, sin_F ) ); - im = add( mult_r( re, sin_F ), mult_r( im, cos_F ) ); -#endif } #ifdef IVAS_FEC_ECU_TO_COMPLETE ELSE @@ -2925,9 +2920,9 @@ static void ivas_rec_wtda_fx( Word16 copy_len; Word16 ola_len; - copy_len = NS2SA( output_frame * FRAMES_PER_SEC, ( 2 * FRAME_SIZE_NS - L_PROT_NS ) / 2 ); /* prototype fill on each side of xsubst to fill MDCT Frame */ + copy_len = NS2SA_FX2( L_mult0( output_frame, FRAMES_PER_SEC ), ( 2 * FRAME_SIZE_NS - L_PROT_NS ) / 2 ); /* prototype fill on each side of xsubst to fill MDCT Frame */ move16(); - ola_len = NS2SA( output_frame * FRAMES_PER_SEC, N_ZERO_MDCT_NS - ( 2 * FRAME_SIZE_NS - L_PROT_NS ) / 2 ); /* remaining lengt of LA_ZEROS to overlap add decoded with xsubst */ + ola_len = NS2SA_FX2( L_mult0( output_frame, FRAMES_PER_SEC ), N_ZERO_MDCT_NS - ( 2 * FRAME_SIZE_NS - L_PROT_NS ) / 2 ); /* remaining lengt of LA_ZEROS to overlap add decoded with xsubst */ move16(); xf_len = 26; @@ -2985,7 +2980,7 @@ static void ivas_rec_wtda_fx( } /* extract reconstructed frame with aldo window */ - timesh = sub( NS2SA( output_frame * FRAMES_PER_SEC, N_ZERO_MDCT_NS ), shr( sub( shl( output_frame, 1 ), Lprot ), 1 ) ); + timesh = sub( NS2SA_FX2( L_mult0( output_frame, FRAMES_PER_SEC ), N_ZERO_MDCT_NS ), shr( sub( shl( output_frame, 1 ), Lprot ), 1 ) ); set16_fx( xsubst_, 0, add( sub( shl( output_frame, 1 ), Lprot ), timesh ) ); Copy( X, xsubst_ + add( sub( shl( output_frame, 1 ), Lprot ), timesh ), sub( Lprot, timesh ) ); @@ -2993,9 +2988,9 @@ static void ivas_rec_wtda_fx( /* Copy and OLA look ahead zero part of MDCT window from decoded signal */ IF( element_mode != EVS_MONO ) { - Copy( old_dec, xsubst_ + NS2SA( output_frame * FRAMES_PER_SEC, N_ZERO_MDCT_NS ), copy_len ); /* also need to scale to Q0 ?? */ + Copy( old_dec, xsubst_ + NS2SA_FX2( L_mult0( output_frame, FRAMES_PER_SEC ), N_ZERO_MDCT_NS ), copy_len ); /* also need to scale to Q0 ?? */ pOld = old_dec + copy_len; - pNew = xsubst_ + add( copy_len, NS2SA( output_frame * FRAMES_PER_SEC, N_ZERO_MDCT_NS ) ); + pNew = xsubst_ + add( copy_len, NS2SA_FX2( L_mult0( output_frame, FRAMES_PER_SEC ), N_ZERO_MDCT_NS ) ); tmp = div_s( 1, shl( ola_len, 1 ) ); // Q15 tmp = round_fx( L_shl( L_mult( tmp, EVS_PI_FX ), 2 ) ); // Q15 sinq_fx( tmp, 0, ola_len, xfwin ); @@ -3322,11 +3317,7 @@ static Word32 mult_32_32_q( const Word32 a, const Word32 b, const Word16 q ) #endif Mpy_32_32_ss( a, b, &hi, &lo ); -#ifdef BASOP_NOGLOB return L_or( L_shl_o( hi, sub( 32 - 1, q ), &Overflow ), L_lshr( (Word32) lo, add( q, 1 ) ) ); -#else - return L_or( L_shl( hi, 32 - q - 1 ), L_lshr( lo, q + 1 ) ); -#endif } static void fir_dwn_fx( @@ -3360,19 +3351,11 @@ static void fir_dwn_fx( FOR( j = 1; j <= i; j++ ) { -#ifdef BASOP_NOGLOB s = L_mac0_sat( s, *ptr_h++, *ptr_x-- ); // Q(h_Q) + Q(x_q) -#else - s = L_mac0( s, *ptr_h++, *ptr_x-- ); -#endif } -#ifdef BASOP_NOGLOB *ptr_y++ = extract_h( L_shl_sat( s, centering ) ); move16(); -#else - *ptr_y++ = extract_h( L_shl( s, centering ) ); -#endif } FOR( i = K; i < L; i += decimation ) { @@ -3383,19 +3366,11 @@ static void fir_dwn_fx( FOR( j = 1; j <= K; j++ ) { -#ifdef BASOP_NOGLOB s = L_mac0_sat( s, *ptr_h++, *ptr_x-- ); // Q(h_Q) + Q(x_q) -#else - s = L_mac0( s, *ptr_h++, *ptr_x-- ); -#endif } -#ifdef BASOP_NOGLOB *ptr_y++ = extract_h( L_shl_sat( s, centering ) ); move16(); -#else - *ptr_y++ = extract_h( L_shl( s, centering ) ); -#endif } tmp = add( L, Kdiv2 ); FOR( i = i; i < tmp; i += decimation ) @@ -3408,19 +3383,11 @@ static void fir_dwn_fx( FOR( j = i - L + 1; j <= K; j++ ) { -#ifdef BASOP_NOGLOB s = L_mac0_sat( s, *ptr_h++, *ptr_x-- ); -#else - s = L_mac0( s, *ptr_h++, *ptr_x-- ); -#endif } -#ifdef BASOP_NOGLOB *ptr_y++ = extract_h( L_shl_sat( s, centering ) ); move16(); -#else - *ptr_y++ = extract_h( L_shl( s, centering ) ); -#endif } return; @@ -3896,20 +3863,11 @@ static void sin_cos_est_fx( Word32 phi, Word16 *cosfreq, Word16 *sinfreq ) tmp = L_shl( Mult_32_16( delta, cosb ), 1 ); /*Q31 */ sinv = L_add( L_deposit_h( sinb ), tmp ); tmp = L_shl( Mult_32_16( delta, sinb ), 1 ); /*Q31 */ -#ifdef BASOP_NOGLOB cosv = L_sub_sat( L_deposit_h( cosb ), tmp ); -#else - cosv = L_sub( L_deposit_h( cosb ), tmp ); -#endif -#ifdef BASOP_NOGLOB *sinfreq = round_fx_sat( sinv ); move16(); *cosfreq = round_fx_sat( cosv ); move16(); -#else - *sinfreq = round_fx( sinv ); - *cosfreq = round_fx( cosv ); -#endif return; } @@ -3963,11 +3921,7 @@ static Word16 abs_iter_fx( Word16 re /*Qx*/, Word16 im /*Qx*/, Word16 N ) i = s_min( sub( i, 1 ), 9 ); tmp = abs_s( re ); /*A = round_fx(L_shr(L_mult(tmp, cor[i]), exp)); //this can be ommited, if we don't need the exact abs value */ -#ifdef BASOP_NOGLOB A = shr_sat( tmp, exp ); -#else - A = shr( tmp, exp ); -#endif return A; } /*-------------------------------------------------------------------------- @@ -4039,13 +3993,8 @@ static void ivas_fec_ecu_dft_fx( { tmp_short = extract_l( L_shr( Tmp, 15 ) ); tmp = extract_l( L_msu( Tmp, tmp_short, 16384 ) ); -#ifdef BASOP_NOGLOB L_tmp = L_mult( sub_sat( target[tmp_short + 1], target[tmp_short] ), tmp ); /*Qin+16 */ Tfr16[i] = add_sat( target[tmp_short], round_fx_sat( L_tmp ) ); -#else - L_tmp = L_mult( sub( target[tmp_short + 1], target[tmp_short] ), tmp ); /*Qin+16 */ - Tfr16[i] = add( target[tmp_short], round_fx( L_tmp ) ); -#endif move16(); /*Qin */ Tmp = L_add( Tmp, fac ); } @@ -4056,7 +4005,11 @@ static void ivas_fec_ecu_dft_fx( tmp = Exp16Array( *Nfft, Tfr16 ); *exp = add( tmp, add( 2, norm_s( *Nfft ) ) ); move16(); - Copy_Scale_sig_16_32( Tfr16, Tfr32, *Nfft, *exp ); /*Qin+exp; */ +#ifdef FIX_ISSUE_1237 + Copy_Scale_sig_16_32_no_sat( Tfr16, Tfr32, *Nfft, *exp ); /*Qin+exp; */ +#else + Copy_Scale_sig_16_32_DEPREC( Tfr16, Tfr32, *Nfft, *exp ); /*Qin+exp; */ +#endif *exp = s_min( *exp, 15 ); DoRTFTn_fx( Tfr32, Tfi32, *Nfft ); @@ -4160,13 +4113,8 @@ static void fec_ecu_dft_fx( { tmp_short = extract_l( L_shr( Tmp, 15 ) ); tmp = extract_l( L_msu( Tmp, tmp_short, 16384 ) ); -#ifdef BASOP_NOGLOB L_tmp = L_mult( sub_sat( target[tmp_short + 1], target[tmp_short] ), tmp ); /*Qin+16 */ Tfr16[i] = add_sat( target[tmp_short], round_fx_sat( L_tmp ) ); -#else - L_tmp = L_mult( sub( target[tmp_short + 1], target[tmp_short] ), tmp ); /*Qin+16 */ - Tfr16[i] = add( target[tmp_short], round_fx( L_tmp ) ); -#endif move16(); /*Qin */ Tmp = L_add( Tmp, fac ); } @@ -4177,7 +4125,20 @@ static void fec_ecu_dft_fx( tmp = Exp16Array( *Nfft, Tfr16 ); *exp = add( tmp, add( 2, norm_s( *Nfft ) ) ); move16(); - Copy_Scale_sig_16_32( Tfr16, Tfr32, *Nfft, *exp ); /*Qin+exp; */ +#ifdef FIX_ISSUE_1237 + { +#ifdef FIX_ISSUE_1237_KEEP_EVS_BE + Word16 loctmp = *exp; + move16(); + loctmp = s_min( 15, loctmp ); + Copy_Scale_sig_16_32_DEPREC( Tfr16, Tfr32, *Nfft, loctmp ); /*Qin+exp; */ /*Even with limiting loctmp, if Copy_Scale_sig_16_32_no_sat() is used, can lead to 1 difference */ +#else + Copy_Scale_sig_16_32_no_sat( Tfr16, Tfr32, *Nfft, *exp ); /*Qin+exp; */ +#endif + } +#else + Copy_Scale_sig_16_32_DEPREC( Tfr16, Tfr32, *Nfft, *exp ); /*Qin+exp; */ +#endif DoRTFTn_fx( Tfr32, Tfi32, *Nfft ); N_LP = shr( *Nfft, 1 ); @@ -4235,11 +4196,7 @@ static void singenerator_fx( ptr = xx; -#ifdef BASOP_NOGLOB *ptr = L_add_sat( *ptr, L_C0 ); -#else - *ptr = L_add( *ptr, L_C0 ); -#endif move32(); ptr++; @@ -4250,11 +4207,7 @@ static void singenerator_fx( L_C1 = L_msu( L_C1, S0, sinfreq ); /*Qin+16 */ L_S1 = L_mult( C0, sinfreq ); S1 = mac_r( L_S1, S0, cosfreq ); -#ifdef BASOP_NOGLOB *ptr = L_add_sat( *ptr, L_C1 ); -#else - *ptr = L_add( *ptr, L_C1 ); -#endif move32(); /*Qin+16 */ ptr++; @@ -4263,11 +4216,7 @@ static void singenerator_fx( L_C0 = L_msu( L_C0, S1, sinfreq ); L_S0 = L_mult( C1, sinfreq ); S0 = mac_r( L_S0, S1, cosfreq ); -#ifdef BASOP_NOGLOB *ptr = L_add_sat( *ptr, L_C0 ); -#else - *ptr = L_add( *ptr, L_C0 ); -#endif move32(); ptr++; } @@ -4276,11 +4225,7 @@ static void singenerator_fx( S0 = extract_h( L_S0 ); L_C1 = L_mult( C0, cosfreq ); L_C1 = L_msu( L_C1, S0, sinfreq ); -#ifdef BASOP_NOGLOB *ptr = L_add_sat( *ptr, L_C1 ); -#else - *ptr = L_add( *ptr, L_C1 ); -#endif move32(); ptr++; @@ -4574,11 +4519,7 @@ static void ivas_fec_noise_filling_fx( move16(); FOR( k = 0; k < tmp_fx; k++ ) { -#ifdef BASOP_NOGLOB ( *pt1++ ) = sub_sat( ( *pt2++ ), ( *pt3++ ) ); -#else - ( *pt1++ ) = sub( ( *pt2++ ), ( *pt3++ ) ); -#endif move16(); } @@ -4625,14 +4566,9 @@ static void ivas_fec_noise_filling_fx( tmp_fx = s_min( Rnd_N_noise, flag ); FOR( i = 0; i < tmp_fx; i++ ) { - L_tmp = L_mult( ( *pt1++ ), ( *pt3++ ) ); /*Qsynth+16 */ -#ifdef BASOP_NOGLOB + L_tmp = L_mult( ( *pt1++ ), ( *pt3++ ) ); /*Qsynth+16 */ L_tmp = L_mac_sat( L_tmp, ( *pt2++ ), ( *pt4-- ) ); /*Qsynth+16 */ *pt5 = add_sat( *pt5, round_fx_sat( L_tmp ) ); -#else - L_tmp = L_mac( L_tmp, ( *pt2++ ), ( *pt4-- ) ); /*Qsynth+16 */ - *pt5 = add( *pt5, round_fx( L_tmp ) ); -#endif move16(); /*Qsynth */ pt5++; } @@ -4647,7 +4583,7 @@ static void ivas_fec_noise_filling_fx( } ELSE { - kk = NS2SA( L * FRAMES_PER_SEC, N_ZERO_MDCT_NS ); + kk = NS2SA_FX2( L_mult0( L, FRAMES_PER_SEC ), N_ZERO_MDCT_NS ); p_mdct_ola = old_out + kk; } @@ -4659,11 +4595,11 @@ static void ivas_fec_noise_filling_fx( { L_tmp = L_mult( *sinq_tab, *sinq_tab ); /*Q30 */ sinq_tab++; - q2 = round_fx( L_sub( 2147483647, L_tmp ) ); /*Q15 */ - q1 = round_fx( L_tmp ); /*Q15 */ - L_tmp = L_mult( ( *pt1 ), q1 ); /*Qsynth+16 */ - L_tmp = L_mac( L_tmp, shr( *pt6++, Q_old_out ), q2 ); /*Qsynth+16 */ - ( *pt1++ ) = round_fx( L_tmp ); /*Qsynth */ + q2 = round_fx( L_sub( 2147483647, L_tmp ) ); /*Q15 */ + q1 = round_fx( L_tmp ); /*Q15 */ + L_tmp = L_mult( ( *pt1 ), q1 ); /*Qsynth+16 */ + L_tmp = L_add( L_tmp, L_shr( Mpy_32_16_1( L_deposit_h( *pt6++ ), q2 ), Q_old_out ) ); /*Qsynth+16 */ + ( *pt1++ ) = round_fx( L_tmp ); /*Qsynth */ move16(); } @@ -4748,11 +4684,7 @@ static void fec_noise_filling_fx( move16(); FOR( k = 0; k < tmp_fx; k++ ) { -#ifdef BASOP_NOGLOB ( *pt1++ ) = sub_sat( ( *pt2++ ), ( *pt3++ ) ); -#else - ( *pt1++ ) = sub( ( *pt2++ ), ( *pt3++ ) ); -#endif move16(); } @@ -4787,12 +4719,8 @@ static void fec_noise_filling_fx( Rnd_N_noise = extract_h( L_mult( N_noise, tmp_fx ) ); /*Q0 */ - tmp_fx = div_s( 1, Rnd_N_noise ); /*Q15 */ -#ifdef BASOP_NOGLOB + tmp_fx = div_s( 1, Rnd_N_noise ); /*Q15 */ tmp_fx = round_fx_sat( L_shl_sat( L_mult( tmp_fx, 25736 ), 2 ) ); /*Q15 */ -#else - tmp_fx = round_fx( L_shl( L_mult( tmp_fx, 25736 ), 2 ) ); /*Q15 */ -#endif #ifdef IVAS_FEC_ECU_TO_COMPLETE if ( element_mode == EVS_MONO ) { @@ -4815,14 +4743,9 @@ static void fec_noise_filling_fx( tmp_fx = s_min( Rnd_N_noise, flag ); FOR( i = 0; i < tmp_fx; i++ ) { - L_tmp = L_mult( ( *pt1++ ), ( *pt3++ ) ); /*Qsynth+16 */ -#ifdef BASOP_NOGLOB + L_tmp = L_mult( ( *pt1++ ), ( *pt3++ ) ); /*Qsynth+16 */ L_tmp = L_mac_sat( L_tmp, ( *pt2++ ), ( *pt4-- ) ); /*Qsynth+16 */ *pt5 = add_sat( *pt5, round_fx_sat( L_tmp ) ); -#else - L_tmp = L_mac( L_tmp, ( *pt2++ ), ( *pt4-- ) ); /*Qsynth+16 */ - *pt5 = add( *pt5, round_fx( L_tmp ) ); -#endif move16(); /*Qsynth */ pt5++; } @@ -5016,7 +4939,7 @@ static void ivas_hq_phase_ecu_fx( IF( element_mode == EVS_MONO ) { - ph_ecu_lookahead = NS2SA( output_frame * FRAMES_PER_SEC, PH_ECU_LOOKAHEAD_NS ); + ph_ecu_lookahead = NS2SA_FX2( L_mult0( output_frame, FRAMES_PER_SEC ), PH_ECU_LOOKAHEAD_NS ); move16(); } ELSE @@ -5095,7 +5018,7 @@ static void ivas_hq_phase_ecu_fx( alpha, beta, *beta_mute, Xavg, element_mode, ph_ecu_lookahead, noise_fac ); /* reconstructed frame in tda domain */ - old_dec = prevsynth + sub( shl( output_frame, 1 ), NS2SA( output_frame * FRAMES_PER_SEC, N_ZERO_MDCT_NS ) ); + old_dec = prevsynth + sub( shl( output_frame, 1 ), NS2SA_FX2( L_mult0( output_frame, FRAMES_PER_SEC ), N_ZERO_MDCT_NS ) ); ivas_rec_frame_fx( X, ecu_rec, output_frame, *Q_spec, old_dec, element_mode, num_p, plocs ); *last_fec = 0; @@ -5300,11 +5223,11 @@ void ivas_hq_ecu_fx( move16(); IF( EQ_16( st_fx->element_mode, EVS_MONO ) ) { - fec_alg_input = prevsynth + NS2SA( output_frame * FRAMES_PER_SEC, ACELP_LOOK_NS / 2 - PH_ECU_LOOKAHEAD_NS ); + fec_alg_input = prevsynth + NS2SA_FX2( L_mult0( output_frame, FRAMES_PER_SEC ), ACELP_LOOK_NS / 2 - PH_ECU_LOOKAHEAD_NS ); } ELSE { - fec_alg_input = prevsynth - NS2SA( output_frame * FRAMES_PER_SEC, PH_ECU_LOOKAHEAD_NS ); + fec_alg_input = prevsynth - NS2SA_FX2( L_mult0( output_frame, FRAMES_PER_SEC ), PH_ECU_LOOKAHEAD_NS ); } /* init (values ar changed after) */ @@ -5363,7 +5286,7 @@ void ivas_hq_ecu_fx( } ELSE { - ivas_hq_phase_ecu_fx( prevsynth - NS2SA( output_frame * FRAMES_PER_SEC, PH_ECU_LOOKAHEAD_NS ), ecu_rec, time_offs, X_sav, Q_spec, num_p, plocs, plocsi, + ivas_hq_phase_ecu_fx( prevsynth - NS2SA_FX2( L_mult0( output_frame, FRAMES_PER_SEC ), PH_ECU_LOOKAHEAD_NS ), ecu_rec, time_offs, X_sav, Q_spec, num_p, plocs, plocsi, env_stab, last_fec, ph_ecu_active, prev_bfi, old_is_transient, mag_chg_1st, Xavg, beta_mute, st_fx->bwidth, output_frame, corr, st_fx->element_mode ); @@ -5431,7 +5354,7 @@ void hq_ecu_fx( #ifdef IVAS_FEC_ECU_TO_COMPLETE fec_ecu_pitch_fx( fec_alg_input, prevsynth_LP, output_frame, &N, &corr, &decimatefactor, ph_ecu_HqVoicing ); #else - fec_ecu_pitch_fx( prevsynth + NS2SA( output_frame * 50, ACELP_LOOK_NS / 2 - PH_ECU_LOOKAHEAD_NS ), prevsynth_LP, output_frame, &N, &corr, &decimatefactor, ph_ecu_HqVoicing ); + fec_ecu_pitch_fx( prevsynth + NS2SA_FX2( L_mult0( output_frame, 50 ), ACELP_LOOK_NS / 2 - PH_ECU_LOOKAHEAD_NS ), prevsynth_LP, output_frame, &N, &corr, &decimatefactor, ph_ecu_HqVoicing ); #endif } ELSE @@ -5486,7 +5409,7 @@ void hq_ecu_fx( ( LT_32( st_fx->total_brate, 48000 ) && ( ( ph_ecu_HqVoicing || GT_16( corr, 27853 ) ) && !prev_bfi && ( !old_is_transient[0] || old_is_transient[1] ) ) ) ) { - fec_alg_fx( prevsynth + NS2SA( output_frame * 50, ACELP_LOOK_NS / 2 - PH_ECU_LOOKAHEAD_NS ), prevsynth_LP, &st_fx->hHQ_core->ni_seed_forfec, ecu_rec, output_frame, N, decimatefactor, ph_ecu_HqVoicing, gapsynth ); + fec_alg_fx( prevsynth + NS2SA_FX2( L_mult0( output_frame, 50 ), ACELP_LOOK_NS / 2 - PH_ECU_LOOKAHEAD_NS ), prevsynth_LP, &st_fx->hHQ_core->ni_seed_forfec, ecu_rec, output_frame, N, decimatefactor, ph_ecu_HqVoicing, gapsynth ); *last_fec = 1; move16(); *ph_ecu_active = 0; @@ -5623,11 +5546,7 @@ static void windowing_ROM_optimized( FOR( i = 0; i < quarterLen; i++ ) { acc = L_deposit_h( FEC_HQ_WIN_A0 ); -#ifdef BASOP_NOGLOB hamm = mac_r_sat( acc, *pSine, FEC_HQ_WIN_A1 ); -#else - hamm = mac_r( acc, *pSine, FEC_HQ_WIN_A1 ); -#endif *pY++ = mult_r( hamm, *pX++ ); move16(); pSine += downSamples; /* Increment address counter */ @@ -5643,13 +5562,9 @@ static void windowing_ROM_optimized( /* 1st half of the right half of the Hamming window. */ FOR( i = 0; i < quarterLen; i++ ) { - pSine -= downSamples; /* Decrement address counter */ - acc = L_deposit_h( FEC_HQ_WIN_A0 ); // Q31 -#ifdef BASOP_NOGLOB + pSine -= downSamples; /* Decrement address counter */ + acc = L_deposit_h( FEC_HQ_WIN_A0 ); // Q31 hamm = mac_r_sat( acc, *pSine, FEC_HQ_WIN_A1 ); // Q15 -#else - hamm = mac_r( acc, *pSine, FEC_HQ_WIN_A1 ); -#endif *pY++ = mult_r( hamm, *pX++ ); move16(); } diff --git a/lib_dec/FEC_adapt_codebook.c b/lib_dec/FEC_adapt_codebook.c deleted file mode 100644 index b2dcc556003357d6e4441122ad670cfdd7bde413..0000000000000000000000000000000000000000 --- a/lib_dec/FEC_adapt_codebook.c +++ /dev/null @@ -1,51 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include -#include "cnst.h" -#include "rom_dec.h" -#include "prot.h" -#include "wmc_auto.h" - -/*------------------------------------------------------------------------- - * FEC_synchro_exc() - * - * Perform resynchronisation of the last glottal pulse in voiced frame lost - *------------------------------------------------------------------------*/ - -/*! r: do_WI flag */ diff --git a/lib_dec/FEC_clas_estim.c b/lib_dec/FEC_clas_estim.c deleted file mode 100644 index 4d461a0dc573e8a1290d05b7acaa24ebcbe52f21..0000000000000000000000000000000000000000 --- a/lib_dec/FEC_clas_estim.c +++ /dev/null @@ -1,44 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include "cnst.h" -#include -#include "options.h" -#include -#include "prot.h" -#include "rom_com.h" -#include "stat_dec.h" -#include "wmc_auto.h" diff --git a/lib_dec/FEC_clas_estim_fx.c b/lib_dec/FEC_clas_estim_fx.c index 4c268186d8851b3a0f05a69385a6160f8f787bc0..e56a77be12f49bf6522a1b129d91eaa0edbe4bb9 100644 --- a/lib_dec/FEC_clas_estim_fx.c +++ b/lib_dec/FEC_clas_estim_fx.c @@ -82,7 +82,7 @@ void FEC_clas_estim_fx( Word16 bfi, /* i : bad frame indicator */ /*B*/ Word32 last_core_brate, /* i : bitrate of previous frame */ - const int16_t FEC_mode /* i : ACELP FEC mode */ + const Word16 FEC_mode /* i : ACELP FEC mode */ ) { Word16 i, j, pos; @@ -285,11 +285,7 @@ void FEC_clas_estim_fx( Corre( &pt1[pos], &pt1[pos - T0], T0, &cor_max[0] ); -#ifdef BASOP_NOGLOB T0 = mult_r_sat( add_sat( pitch[2], pitch[3] ), 256 ); -#else - T0 = mult_r( add( pitch[2], pitch[3] ), 256 ); -#endif pos_limit = sub( L_frame, L_SUBFR ); j = s_min( 1, s_max( 0, sub( pos, pos_limit ) ) ); Ltmp = L_deposit_l( cor_max[0] ); @@ -334,11 +330,7 @@ void FEC_clas_estim_fx( test(); IF( EQ_16( codec_mode, MODE1 ) || !( NE_16( LTP_Gain, -32768 /*-1.f Q15*/ ) && EQ_16( mode, CLASSIFIER_TCX ) ) ) { -#ifdef BASOP_NOGLOB pc = shr( abs_s( sub( add_sat( pitch[3], sub( pitch[2], pitch[1] ) ), pitch[0] ) ), 6 ); -#else - pc = shr( abs_s( sub( add( pitch[3], sub( pitch[2], pitch[1] ) ), pitch[0] ) ), 6 ); -#endif IF( EQ_16( L_frame, L_FRAME16k ) ) { @@ -359,13 +351,8 @@ void FEC_clas_estim_fx( { pt1++; pt2++; -#ifdef BASOP_NOGLOB Ltmp = L_mac0_sat( Ltmp, *pt1, *pt1 ); Ltmp1 = L_mac0_sat( Ltmp1, *pt1, *pt2 ); -#else - Ltmp = L_mac0( Ltmp, *pt1, *pt1 ); - Ltmp1 = L_mac0( Ltmp1, *pt1, *pt2 ); -#endif } tilt = 0; move16(); @@ -383,21 +370,13 @@ void FEC_clas_estim_fx( tmp_x = extract_h( L_shl( Ltmp, exp2 ) ); exp2 = sub( 31 - 1 + 3, exp2 ); BASOP_SATURATE_WARNING_OFF_EVS -#ifdef BASOP_NOGLOB tmpS = shr( sub_sat( tmp_x, tmp_y ), 16 ); /* if tmp_x >= tmp_y tmpS = 0, -1 otherwise */ -#else - tmpS = shr( sub( tmp_x, tmp_y ), 16 ); /* if tmp_x >= tmp_y tmpS = 0, -1 otherwise */ -#endif BASOP_SATURATE_WARNING_ON_EVS tmp_y = shl( tmp_y, tmpS ); exp1 = sub( exp1, tmpS ); tilt = div_s( tmp_y, tmp_x ); -#ifdef BASOP_NOGLOB tilt = shl_sat( tilt, sub( exp1, exp2 ) ); /* saturate to 1.0 */ -#else - tilt = shl( tilt, sub( exp1, exp2 ) ); /* saturate to 1.0 */ -#endif tilt = i_mult2( tilt, tmp16 ); } @@ -420,11 +399,7 @@ void FEC_clas_estim_fx( zcn = extract_h( L_shl( L_mac( C_ZC_FX, K_ZC_FX, zc_frame ), 4 ) ); /* Q4 -> Q8*/ BASOP_SATURATE_WARNING_OFF_EVS -#ifdef BASOP_NOGLOB tmp16 = sub_sat( LTP_Gain, -32768 /*-1.f Q15*/ ); -#else - tmp16 = sub( LTP_Gain, -32768 /*-1.f Q15*/ ); -#endif BASOP_SATURATE_WARNING_ON_EVS test(); test(); @@ -446,11 +421,7 @@ void FEC_clas_estim_fx( Ltmp = L_mac( Ltmp, pcn, UNS6 ); Ltmp = L_mac( Ltmp, enern, UNS6 ); BASOP_SATURATE_WARNING_OFF_EVS -#ifdef BASOP_NOGLOB fmerit1 = round_fx_sat( L_shl_sat( Ltmp, 15 - 8 ) ); /*Q15 can saturate to 1.0 */ -#else - fmerit1 = round_fx( L_shl( Ltmp, 15 - 8 ) ); /*Q15 can saturate to 1.0 */ -#endif BASOP_SATURATE_WARNING_ON_EVS test(); IF( EQ_16( codec_mode, MODE2 ) && narrowBand != 0 ) @@ -938,11 +909,7 @@ static void Corre( /* keep Q15 normalized result */ cor = extract_h( Dot_product12( x, y, l, &cor_exp ) ); -#ifdef BASOP_NOGLOB den = add_sat( extract_h( Dot_product12( y, y, l, &den_exp ) ), 1 ); -#else - den = add( extract_h( Dot_product12( y, y, l, &den_exp ) ), 1 ); -#endif den2 = extract_h( Dot_product12( x, x, l, &den2_exp ) ); /* keep Q31 normalized result */ @@ -953,10 +920,6 @@ static void Corre( tmp = Isqrt_lc( tmp, &tmp_exp ); /* keep Q15 result */ -#ifdef BASOP_NOGLOB gain[0] = shl_sat( mult_r( cor, extract_h( tmp ) ), add( cor_exp, tmp_exp ) ); -#else - gain[0] = shl( mult_r( cor, extract_h( tmp ) ), add( cor_exp, tmp_exp ) ); -#endif move16(); } diff --git a/lib_dec/FEC_fx.c b/lib_dec/FEC_fx.c index c0976e68a0764e9ed958564472fa481fdd8de8ba..35bb254af835011d3ec461752e47c43ee3c7b2f3 100644 --- a/lib_dec/FEC_fx.c +++ b/lib_dec/FEC_fx.c @@ -126,11 +126,7 @@ void FEC_exc_estim_fx( gainCNG = round_fx( L_shl( L_tmp, sub( exp, 12 ) ) ); /* In Q3 */ } -#ifdef BASOP_NOGLOB tmp1 = shl_o( st_fx->lp_gainc_fx, 1, &Overflow ); -#else - tmp1 = shl( st_fx->lp_gainc_fx, 1 ); -#endif gainCNG = s_min( gainCNG, tmp1 ); set16_fx( exc_dct_in, 0, L_FRAME16k ); @@ -191,15 +187,9 @@ void FEC_exc_estim_fx( { test(); test(); -#ifdef BASOP_NOGLOB IF( ( LT_16( round_fx( L_shl( st_fx->old_pitch_buf_fx[2 * NB_SUBFR - 1], 6 ) ), shl_o( mult( 29491, st_fx->bfi_pitch_fx ), 1, &Overflow ) ) && GT_16( round_fx( L_shl( st_fx->old_pitch_buf_fx[2 * NB_SUBFR - 1], 6 ) ), mult( 19661, st_fx->bfi_pitch_fx ) ) ) || /* last pitch coherent with the past */ GE_16( st_fx->upd_cnt, MAX_UPD_CNT ) ) /* or last update too far in the past */ -#else - IF( ( LT_16( round_fx( L_shl( st_fx->old_pitch_buf_fx[2 * NB_SUBFR - 1], 6 ) ), shl( mult( 29491, st_fx->bfi_pitch_fx ), 1 ) ) && - GT_16( round_fx( L_shl( st_fx->old_pitch_buf_fx[2 * NB_SUBFR - 1], 6 ) ), mult( 19661, st_fx->bfi_pitch_fx ) ) ) || /* last pitch coherent with the past */ - GE_16( st_fx->upd_cnt, MAX_UPD_CNT ) ) /* or last update too far in the past */ -#endif { /* take the pitch value of last subframe of the previous frame */ *tmp_tc = round_fx( L_shl( st_fx->old_pitch_buf_fx[2 * NB_SUBFR - 1], 6 ) ); @@ -210,15 +200,9 @@ void FEC_exc_estim_fx( { test(); test(); -#ifdef BASOP_NOGLOB IF( ( LT_16( round_fx( L_shl( st_fx->old_pitch_buf_fx[2 * NB_SUBFR16k - 1], 6 ) ), shl_o( mult( 29491, st_fx->bfi_pitch_fx ), 1, &Overflow ) ) && GT_16( round_fx( L_shl( st_fx->old_pitch_buf_fx[2 * NB_SUBFR16k - 1], 6 ) ), mult( 19661, st_fx->bfi_pitch_fx ) ) ) || /* last pitch coherent with the past */ GE_16( st_fx->upd_cnt, MAX_UPD_CNT ) ) /* or last update too far in the past */ -#else - IF( ( LT_16( round_fx( L_shl( st_fx->old_pitch_buf_fx[2 * NB_SUBFR16k - 1], 6 ) ), shl( mult( 29491, st_fx->bfi_pitch_fx ), 1 ) ) && - GT_16( round_fx( L_shl( st_fx->old_pitch_buf_fx[2 * NB_SUBFR16k - 1], 6 ) ), mult( 19661, st_fx->bfi_pitch_fx ) ) ) || /* last pitch coherent with the past */ - GE_16( st_fx->upd_cnt, MAX_UPD_CNT ) ) /* or last update too far in the past */ -#endif { /* take the pitch value of last subframe of the previous frame */ *tmp_tc = round_fx( L_shl( st_fx->old_pitch_buf_fx[2 * NB_SUBFR16k - 1], 6 ) ); @@ -312,11 +296,7 @@ void FEC_exc_estim_fx( IF( LE_16( st_fx->nbLostCmpt, 1 ) ) { /* if stable, do not decrease the energy, pitch_gain = 0 */ -#ifdef BASOP_NOGLOB alpha = mac_ro( ( 1L << 16 ) * 2 * _ALPHA_U_FX, st_fx->stab_fac_fx, 32768 - 2 * _ALPHA_U_FX, &Overflow ); /*st_fx->stab_fac_fx in Q15*/ -#else - alpha = mac_r( ( 1L << 16 ) * 2 * _ALPHA_U_FX, st_fx->stab_fac_fx, 32768 - 2 * _ALPHA_U_FX ); /*st_fx->stab_fac_fx in Q15*/ -#endif } ELSE IF( EQ_16( st_fx->nbLostCmpt, 2 ) ) { @@ -365,11 +345,7 @@ void FEC_exc_estim_fx( L_tmp = L_deposit_h( tmp ); L_tmp = Isqrt_lc( L_tmp, &exp ); -#ifdef BASOP_NOGLOB gain = extract_h( L_shl_o( L_tmp, exp, &Overflow ) ); -#else - gain = extract_h( L_shl( L_tmp, exp ) ); -#endif gain = s_min( gain, 32113 ); /*0.98 */ gain = s_max( gain, 27853 ); /*0.85 */ @@ -528,7 +504,11 @@ void FEC_exc_estim_fx( test(); test(); test(); +#ifdef NONBE_FIX_GSC_BSTR + IF( EQ_16( st_fx->last_coder_type, AUDIO ) || ( EQ_16( st_fx->last_good, INACTIVE_CLAS ) && st_fx->inactive_coder_type_flag && !st_fx->Opt_AMR_WB ) ) +#else IF( EQ_16( st_fx->last_coder_type, AUDIO ) || ( EQ_16( st_fx->last_good, INACTIVE_CLAS ) && LE_32( st_fx->total_brate, MAX_GSC_INACTIVE_BRATE ) && !st_fx->Opt_AMR_WB ) ) +#endif { st_fx->GSC_noisy_speech = st_fx->Last_GSC_noisy_speech_flag; move16(); @@ -658,11 +638,7 @@ void FEC_exc_estim_fx( /* non-causal ringing of the FIR filter */ /**pt_exc++ *= (gain_inov * gain);*/ L_tmp = L_mult( tmp, *pt_exc ); /* Q_exc+18 * Q-3 -> Q_exc+16 */ -#ifdef BASOP_NOGLOB *pt_exc++ = round_fx_sat( L_shl_sat( L_tmp, exp ) ); -#else - *pt_exc++ = round_fx( L_shl( L_tmp, exp ) ); -#endif move16(); } @@ -671,11 +647,7 @@ void FEC_exc_estim_fx( /* the inner part of the FIR filter */ /* *pt_exc++ *= (gain_inov * gain); */ L_tmp = L_mult( tmp, *pt_exc ); -#ifdef BASOP_NOGLOB *pt_exc++ = round_fx_sat( L_shl_sat( L_tmp, exp ) ); -#else - *pt_exc++ = round_fx( L_shl( L_tmp, exp ) ); -#endif move16(); /* gain -= step; */ L_tmp2 = L_sub( L_tmp2, L_step ); @@ -686,11 +658,7 @@ void FEC_exc_estim_fx( { /* *pt_exc++ *= (gain_inov * gain) */ L_tmp = L_mult( tmp, *pt_exc ); -#ifdef BASOP_NOGLOB *pt_exc++ = round_fx_sat( L_shl_sat( L_tmp, exp ) ); -#else - *pt_exc++ = round_fx( L_shl( L_tmp, exp ) ); -#endif move16(); } } @@ -702,7 +670,11 @@ void FEC_exc_estim_fx( test(); test(); test(); +#ifdef NONBE_FIX_GSC_BSTR + IF( EQ_16( st_fx->last_coder_type, AUDIO ) || ( EQ_16( st_fx->last_good, INACTIVE_CLAS ) && st_fx->inactive_coder_type_flag && !st_fx->Opt_AMR_WB ) ) +#else IF( ( EQ_16( st_fx->last_coder_type, AUDIO ) || EQ_16( st_fx->last_good, INACTIVE_CLAS ) ) && LE_32( st_fx->total_brate, MAX_GSC_INACTIVE_BRATE ) && !st_fx->Opt_AMR_WB ) +#endif { /* For GSC - the excitation is already computed */ Copy( exc, exc2, st_fx->L_frame ); @@ -726,17 +698,9 @@ void FEC_exc_estim_fx( L_tmp = L_mult( hp_filt[0], pt_exc[0] ); FOR( j = 1; j < MODE1_L_FIR_FER; j++ ) { -#ifdef BASOP_NOGLOB L_tmp = L_mac_sat( L_tmp, hp_filt[j], pt_exc[j] ); -#else - L_tmp = L_mac( L_tmp, hp_filt[j], pt_exc[j] ); -#endif } -#ifdef BASOP_NOGLOB exc2[i] = msu_r_sat( L_tmp, -32768, exc[i] ); -#else - exc2[i] = msu_r( L_tmp, -32768, exc[i] ); -#endif move16(); pt_exc++; } @@ -812,11 +776,7 @@ static void pulseRes_preCalc( Word16 *cond1, Word16 *cond2, Word32 *cond3, Word1 tmp_frame = sub( 32767 /*1.f Q15*/, tmp_frame ); /*Q15*/ BASOP_SATURATE_WARNING_OFF_EVS /*To calc Q15 threshold, overflow may happen - do negation and compare with negated value to check also highest possible value*/ -#ifdef BASOP_NOGLOB tmp_pit = shl_o( negate( tmp_pit ), tmp_pit_e, &Overflow ); -#else - tmp_pit = shl( negate( tmp_pit ), tmp_pit_e ); -#endif BASOP_SATURATE_WARNING_ON_EVS *cond1 = sub( tmp_pit, negate( tmp_frame ) ); move16(); @@ -829,11 +789,7 @@ static void pulseRes_preCalc( Word16 *cond1, Word16 *cond2, Word32 *cond3, Word1 tmp_pit2 = L_mult( Tc, 4915 /*0.15f Q15*/ ); /*Q16*/ BASOP_SATURATE_WARNING_OFF_EVS /*To calc Q15 threshold, overflow may happen - do negation and compare with negated value to check also highest possible value*/ -#ifdef BASOP_NOGLOB tmp_pit2 = L_shl_sat( L_negate( tmp_pit2 ), sub( 15 - 16, tmp_pit_e ) ); -#else - tmp_pit2 = L_shl( L_negate( tmp_pit2 ), sub( 15 - 16, tmp_pit_e ) ); -#endif BASOP_SATURATE_WARNING_ON_EVS *cond3 = L_sub( L_mult0( -1, tmp_pit ), tmp_pit2 ); move32(); diff --git a/lib_dec/FEC_lsf_estim.c b/lib_dec/FEC_lsf_estim.c deleted file mode 100644 index 1fa0758f744aa77ba4adf437deef92afb4795fe1..0000000000000000000000000000000000000000 --- a/lib_dec/FEC_lsf_estim.c +++ /dev/null @@ -1,49 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include "cnst.h" -#include "rom_com.h" -#include "prot.h" -#include "wmc_auto.h" - -/*-------------------------------------------------------------------* - * FEC_lsf2lsp_interp_flt() - * - * - LSP calculation - * - A(z) calculation - *-------------------------------------------------------------------*/ diff --git a/lib_dec/FEC_pitch_estim.c b/lib_dec/FEC_pitch_estim.c deleted file mode 100644 index 1b9ed9484bba69c85ffac45d65729be6b855b40b..0000000000000000000000000000000000000000 --- a/lib_dec/FEC_pitch_estim.c +++ /dev/null @@ -1,42 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - - -#include -#include "options.h" -#include "cnst.h" -#include "prot.h" -#include "wmc_auto.h" diff --git a/lib_dec/FEC_pitch_estim_fx.c b/lib_dec/FEC_pitch_estim_fx.c index 45304a94cebb2fae2cf31d7140947e525b4d0f1f..b7ad94f8931293ef25288170d9be242c4e0fabc8 100644 --- a/lib_dec/FEC_pitch_estim_fx.c +++ b/lib_dec/FEC_pitch_estim_fx.c @@ -59,11 +59,7 @@ void FEC_pitch_estim_fx( tmp3 = shl_sat( tmp2, 1 ); /*Q6 (1.4f * old_pitch_buf[2*NB_SUBFR-1])*/ tmp16k1 = round_fx( L_shl( Mpy_32_16_1( old_pitch_buf[2 * NB_SUBFR16k - 1], 22938 ), 6 ) ); /*Q6 0.7f * old_pitch_buf[2*NB_SUBFR16k-1]*/ -#ifdef BASOP_NOGLOB - tmp16k2 = shl_sat( tmp16k1, 1 ); /*Q6 1.4f * old_pitch_buf[2*NB_SUBFR16k-1]*/ -#else - tmp16k2 = shl( tmp16k1, 1 ); /*Q6 1.4f * old_pitch_buf[2*NB_SUBFR16k-1]*/ -#endif + tmp16k2 = shl_sat( tmp16k1, 1 ); /*Q6 1.4f * old_pitch_buf[2*NB_SUBFR16k-1]*/ test(); test(); diff --git a/lib_dec/FEC_scale_syn.c b/lib_dec/FEC_scale_syn.c deleted file mode 100644 index 7d23dd6f703552ed5f1af9f2941cf4dee9763f27..0000000000000000000000000000000000000000 --- a/lib_dec/FEC_scale_syn.c +++ /dev/null @@ -1,42 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include -#include "cnst.h" -#include "prot.h" -#include "wmc_auto.h" diff --git a/lib_dec/FEC_scale_syn_fx.c b/lib_dec/FEC_scale_syn_fx.c index f8f3d834688235c542a60f170d5df435a4672f13..d664aa9fbb2ea39a35ea23477c0ec2e3517e40c9 100644 --- a/lib_dec/FEC_scale_syn_fx.c +++ b/lib_dec/FEC_scale_syn_fx.c @@ -188,11 +188,7 @@ void FEC_scale_syn_fx( { /* gain2 = (float)sqrt( enr_old / enr2 );*/ L_tmp = Sqrt_Ratio32( L_enr_old, 0, L_enr2, 0, &exp2 ); -#ifdef BASOP_NOGLOB gain2 = round_fx_sat( L_shl_sat( L_tmp, sub( exp2, 1 ) ) ); /* in Q14 */ -#else - gain2 = round_fx( L_shl( L_tmp, sub( exp2, 1 ) ) ); /* in Q14 */ -#endif /*if( gain2 > 1.0f )gain2 = 1.0f;*/ gain2 = s_min( gain2, 16384 ); @@ -205,11 +201,7 @@ void FEC_scale_syn_fx( /*gain1 = (float)sqrt( enr_old / enr1 );*/ L_tmp = Sqrt_Ratio32( L_enr_old, 0, L_enr1, 0, &exp2 ); -#ifdef BASOP_NOGLOB gain1 = round_fx_sat( L_shl_sat( L_tmp, sub( exp2, 1 ) ) ); /* in Q14 */ -#else - gain1 = round_fx( L_shl( L_tmp, sub( exp2, 1 ) ) ); /* in Q14 */ -#endif /*if( gain1 > 1.0f )gain1 = 1.0f;*/ gain1 = s_min( gain1, 16384 ); /*Q14*/ @@ -229,11 +221,7 @@ void FEC_scale_syn_fx( /*rr0 = dotp( h1, h1, L_FRAME/2-1 ) + 0.1f;*/ /*rr1 = dotp( h1, h1+1, L_FRAME/2-1 );*/ /*tilt = rr1 / rr0;*/ -#ifdef BASOP_NOGLOB tilt = extract_h( L_shl_sat( get_gain( h1 + 1, h1, L_FRAME / 2 - 1 ), 15 ) ); /*Q15*/ -#else - tilt = extract_h( L_shl( get_gain( h1 + 1, h1, L_FRAME / 2 - 1 ), 15 ) ); -#endif pitch_dist = 0; move16(); L_mean_pitch = L_mult( pitch[0], 8192 /*1.0f in Q13*/ ); /*Q14*/ @@ -259,11 +247,7 @@ void FEC_scale_syn_fx( ( ( prev_bfi ) || ( ( EQ_16( coder_type, GENERIC ) ) && ( EQ_16( LSF_Q_prediction, AUTO_REGRESSIVE ) ) ) ) ) { /*if( enr_q > scaling * enr_old ){enr_q = scaling * enr_old;}*/ -#ifdef BASOP_NOGLOB L_enr_q = L_min( L_enr_q, L_shl_sat( Mult_32_16( L_enr_old, scaling ), 1 ) ); /* scaling in Q14*/ -#else - L_enr_q = L_min( L_enr_q, L_shl( Mult_32_16( L_enr_old, scaling ), 1 ) ); /* scaling in Q14*/ -#endif } ELSE { @@ -279,11 +263,7 @@ void FEC_scale_syn_fx( ener_max = L_max( ener_max, L_enr_old ); /*if( enr_q > scaling * ener_max ){enr_q = scaling * ener_max;}*/ -#ifdef BASOP_NOGLOB L_enr_q = L_min( L_enr_q, L_shl_sat( Mult_32_16( ener_max, scaling ), 1 ) ); /* scaling in Q14*/ -#else - L_enr_q = L_min( L_enr_q, L_shl( Mult_32_16( ener_max, scaling ), 1 ) ); /* scaling in Q14*/ -#endif } } /*gain2 = (float)sqrt( enr_q / enr2 );*/ @@ -320,11 +300,7 @@ void FEC_scale_syn_fx( /*gain1 = (float)sqrt( enr_old / enr1 );*/ L_tmp = Sqrt_Ratio32( L_enr_old, 0, L_enr1, 0, &exp2 ); -#ifdef BASOP_NOGLOB gain1 = round_fx_sat( L_shl_sat( L_tmp, sub( exp2, 1 ) ) ); /* in Q14 */ -#else - gain1 = round_fx( L_shl( L_tmp, sub( exp2, 1 ) ) ); /* in Q14 */ -#endif /*if( gain1 > 1.2f )gain1 = 1.2f;*/ /* prevent clipping */ @@ -358,11 +334,7 @@ void FEC_scale_syn_fx( exc[i] = mac_r( L_mult( exc[i], gain1 ), exc[i], gain1 ); move16(); /*exc2[i] *= gain1;*/ -#ifdef BASOP_NOGLOB exc2[i] = mac_r_sat( L_mult( exc2[i], gain1 ), exc2[i], gain1 ); -#else - exc2[i] = mac_r( L_mult( exc2[i], gain1 ), exc2[i], gain1 ); -#endif move16(); } /* smoothing is done in excitation domain, so redo synthesis */ @@ -390,11 +362,7 @@ void FEC_scale_syn_fx( /*rr0 = dotp( h1, h1, L_FRAME/2-1 ) + 0.1f;*/ /*rr1 = dotp( h1, h1+1, L_FRAME/2-1 );*/ /*tilt = rr1 / rr0;*/ -#ifdef BASOP_NOGLOB tilt = extract_h( L_shl_sat( get_gain( h1 + 1, h1, L_FRAME / 2 - 1 ), 15 ) ); /*Q15*/ -#else - tilt = extract_h( L_shl( get_gain( h1 + 1, h1, L_FRAME / 2 - 1 ), 15 ) ); -#endif test(); test(); test(); @@ -409,21 +377,13 @@ void FEC_scale_syn_fx( ( ( ( clas == UNVOICED_CLAS ) ) || ( EQ_16( clas, INACTIVE_CLAS ) ) ) ) ) /* unvoiced classification */ { /*if( enr_q > scaling * enr_old )enr_q = scaling * enr_old;*/ -#ifdef BASOP_NOGLOB L_enr_q = L_min( L_enr_q, L_shl_sat( Mult_32_16( L_enr_old, scaling ), 1 ) ); /* scaling in Q14*/ -#else - L_enr_q = L_min( L_enr_q, L_shl( Mult_32_16( L_enr_old, scaling ), 1 ) ); /* scaling in Q14*/ -#endif } ELSE IF( GE_16( last_good, VOICED_TRANSITION ) && LT_16( last_good, INACTIVE_CLAS ) && GE_16( clas, VOICED_TRANSITION ) && LT_16( clas, INACTIVE_CLAS ) ) { /* Voiced-voiced recovery */ test(); -#ifdef BASOP_NOGLOB IF( *old_enr_LP != 0 && GT_16( enr_LP, shl_sat( *old_enr_LP, 1 ) ) ) -#else - IF( *old_enr_LP != 0 && GT_16( enr_LP, shl( *old_enr_LP, 1 ) ) ) -#endif { /* enr_q /= enr_LP */ exp = norm_l( L_enr_q ); @@ -508,11 +468,7 @@ void FEC_scale_syn_fx( L_tmp = L_deposit_h( tmp ); L_tmp = Isqrt_lc( L_tmp, &exp2 ); -#ifdef BASOP_NOGLOB gain2 = round_fx_sat( L_shl_sat( L_tmp, sub( exp2, 1 ) ) ); /* in Q14 */ -#else - gain2 = round_fx( L_shl( L_tmp, sub( exp2, 1 ) ) ); /* in Q14 */ -#endif /*-----------------------------------------------------------------* * Clipping of the smoothing gain at the frame end *-----------------------------------------------------------------*/ @@ -573,11 +529,7 @@ void FEC_scale_syn_fx( L_tmp = L_deposit_h( tmp ); L_tmp = Isqrt_lc( L_tmp, &exp2 ); -#ifdef BASOP_NOGLOB gain1 = round_fx_sat( L_shl_sat( L_tmp, sub( exp2, 1 ) ) ); /* in Q14 */ -#else - gain1 = round_fx( L_shl( L_tmp, sub( exp2, 1 ) ) ); /* in Q14 */ -#endif /* exp2 is always <= 1 */ gain1 = s_min( gain1, 19661 /*1.2F in Q14*/ ); @@ -609,15 +561,9 @@ void FEC_scale_syn_fx( FOR( i = 0; i < L_frame; i++ ) { gain1 = mac_r( L_tmp, gain1, AGC_FX ); /* in Q14 */ -#ifdef BASOP_NOGLOB exc[i] = mac_r_sat( L_mult_sat( exc[i], gain1 ), exc[i], gain1 ); move16(); exc2[i] = mac_r_sat( L_mult_sat( exc2[i], gain1 ), exc2[i], gain1 ); -#else - exc[i] = mac_r( L_mult( exc[i], gain1 ), exc[i], gain1 ); - move16(); - exc2[i] = mac_r( L_mult( exc2[i], gain1 ), exc2[i], gain1 ); -#endif move16(); } @@ -815,11 +761,7 @@ void FEC_scale_syn_ivas_fx( { /* gain2 = (float)sqrt( enr_old / enr2 );*/ L_tmp = Sqrt_Ratio32( L_enr_old, 0, L_enr2, 0, &exp2 ); -#ifdef BASOP_NOGLOB gain2 = round_fx_sat( L_shl_sat( L_tmp, sub( exp2, 1 ) ) ); /* in Q14 */ -#else - gain2 = round_fx( L_shl( L_tmp, sub( exp2, 1 ) ) ); /* in Q14 */ -#endif /*if( gain2 > 1.0f )gain2 = 1.0f;*/ gain2 = s_min( gain2, 16384 /*1.0f in Q14*/ ); /*Q14*/ @@ -832,11 +774,7 @@ void FEC_scale_syn_ivas_fx( /*gain1 = (float)sqrt( enr_old / enr1 );*/ L_tmp = Sqrt_Ratio32( L_enr_old, 0, L_enr1, 0, &exp2 ); -#ifdef BASOP_NOGLOB gain1 = round_fx_sat( L_shl_sat( L_tmp, sub( exp2, 1 ) ) ); /* in Q14 */ -#else - gain1 = round_fx( L_shl( L_tmp, sub( exp2, 1 ) ) ); /* in Q14 */ -#endif /*if( gain1 > 1.0f )gain1 = 1.0f;*/ gain1 = s_min( gain1, 16384 /*1.0f in Q14*/ ); /*Q14*/ @@ -856,11 +794,7 @@ void FEC_scale_syn_ivas_fx( /*rr0 = dotp( h1, h1, L_FRAME/2-1 ) + 0.1f;*/ /*rr1 = dotp( h1, h1+1, L_FRAME/2-1 );*/ /*tilt = rr1 / rr0;*/ -#ifdef BASOP_NOGLOB tilt = extract_h( L_shl_sat( get_gain( h1 + 1, h1, L_FRAME / 2 - 1 ), 15 ) ); /*Q15*/ -#else - tilt = extract_h( L_shl( get_gain( h1 + 1, h1, L_FRAME / 2 - 1 ), 15 ) ); -#endif pitch_dist = 0; move16(); L_mean_pitch = L_mult( pitch[0], 8192 ); /*Q14*/ @@ -886,11 +820,7 @@ void FEC_scale_syn_ivas_fx( ( ( prev_bfi ) || ( ( EQ_16( coder_type, GENERIC ) ) && ( EQ_16( LSF_Q_prediction, AUTO_REGRESSIVE ) ) ) ) ) { /*if( enr_q > scaling * enr_old ){enr_q = scaling * enr_old;}*/ -#ifdef BASOP_NOGLOB L_enr_q = L_min( L_enr_q, L_shl_sat( Mult_32_16( L_enr_old, scaling ), 1 ) ); /* scaling in Q14*/ -#else - L_enr_q = L_min( L_enr_q, L_shl( Mult_32_16( L_enr_old, scaling ), 1 ) ); /* scaling in Q14*/ -#endif } ELSE { @@ -906,11 +836,7 @@ void FEC_scale_syn_ivas_fx( ener_max = L_max( ener_max, L_enr_old ); /*if( enr_q > scaling * ener_max ){enr_q = scaling * ener_max;}*/ -#ifdef BASOP_NOGLOB L_enr_q = L_min( L_enr_q, L_shl_sat( Mult_32_16( ener_max, scaling ), 1 ) ); /* scaling in Q14*/ -#else - L_enr_q = L_min( L_enr_q, L_shl( Mult_32_16( ener_max, scaling ), 1 ) ); /* scaling in Q14*/ -#endif } } /*gain2 = (float)sqrt( enr_q / enr2 );*/ @@ -947,11 +873,7 @@ void FEC_scale_syn_ivas_fx( /*gain1 = (float)sqrt( enr_old / enr1 );*/ L_tmp = Sqrt_Ratio32( L_enr_old, 0, L_enr1, 0, &exp2 ); -#ifdef BASOP_NOGLOB gain1 = round_fx_sat( L_shl_sat( L_tmp, sub( exp2, 1 ) ) ); /* in Q14 */ -#else - gain1 = round_fx( L_shl( L_tmp, sub( exp2, 1 ) ) ); /* in Q14 */ -#endif /*if( gain1 > 1.2f )gain1 = 1.2f;*/ /* prevent clipping */ @@ -985,11 +907,7 @@ void FEC_scale_syn_ivas_fx( exc[i] = mac_r( L_mult( exc[i], gain1 ), exc[i], gain1 ); move16(); /*exc2[i] *= gain1;*/ -#ifdef BASOP_NOGLOB exc2[i] = mac_r_sat( L_mult( exc2[i], gain1 ), exc2[i], gain1 ); -#else - exc2[i] = mac_r( L_mult( exc2[i], gain1 ), exc2[i], gain1 ); -#endif move16(); } /* smoothing is done in excitation domain, so redo synthesis */ @@ -1017,11 +935,7 @@ void FEC_scale_syn_ivas_fx( /*rr0 = dotp( h1, h1, L_FRAME/2-1 ) + 0.1f;*/ /*rr1 = dotp( h1, h1+1, L_FRAME/2-1 );*/ /*tilt = rr1 / rr0;*/ -#ifdef BASOP_NOGLOB tilt = extract_h( L_shl_sat( get_gain( h1 + 1, h1, L_FRAME / 2 - 1 ), 15 ) ); /*Q15*/ -#else - tilt = extract_h( L_shl( get_gain( h1 + 1, h1, L_FRAME / 2 - 1 ), 15 ) ); -#endif test(); test(); test(); @@ -1036,21 +950,13 @@ void FEC_scale_syn_ivas_fx( ( ( ( clas == UNVOICED_CLAS ) ) || ( EQ_16( clas, INACTIVE_CLAS ) ) ) ) ) /* unvoiced classification */ { /*if( enr_q > scaling * enr_old )enr_q = scaling * enr_old;*/ -#ifdef BASOP_NOGLOB L_enr_q = L_min( L_enr_q, L_shl_sat( Mult_32_16( L_enr_old, scaling ), 1 ) ); /* scaling in Q14*/ -#else - L_enr_q = L_min( L_enr_q, L_shl( Mult_32_16( L_enr_old, scaling ), 1 ) ); /* scaling in Q14*/ -#endif } ELSE IF( GE_16( last_good, VOICED_TRANSITION ) && LT_16( last_good, INACTIVE_CLAS ) && GE_16( clas, VOICED_TRANSITION ) && LT_16( clas, INACTIVE_CLAS ) ) { /* Voiced-voiced recovery */ test(); -#ifdef BASOP_NOGLOB IF( *old_enr_LP != 0 && GT_16( enr_LP, shl_sat( *old_enr_LP, 1 ) ) ) -#else - IF( *old_enr_LP != 0 && GT_16( enr_LP, shl( *old_enr_LP, 1 ) ) ) -#endif { /* enr_q /= enr_LP */ exp = norm_l( L_enr_q ); @@ -1135,11 +1041,7 @@ void FEC_scale_syn_ivas_fx( L_tmp = L_deposit_h( tmp ); L_tmp = Isqrt_lc( L_tmp, &exp2 ); -#ifdef BASOP_NOGLOB gain2 = round_fx_sat( L_shl_sat( L_tmp, sub( exp2, 1 ) ) ); /* in Q14 */ -#else - gain2 = round_fx( L_shl( L_tmp, sub( exp2, 1 ) ) ); /* in Q14 */ -#endif /*-----------------------------------------------------------------* * Clipping of the smoothing gain at the frame end *-----------------------------------------------------------------*/ @@ -1200,11 +1102,7 @@ void FEC_scale_syn_ivas_fx( L_tmp = L_deposit_h( tmp ); L_tmp = Isqrt_lc( L_tmp, &exp2 ); -#ifdef BASOP_NOGLOB gain1 = round_fx_sat( L_shl_sat( L_tmp, sub( exp2, 1 ) ) ); /* in Q14 */ -#else - gain1 = round_fx( L_shl( L_tmp, sub( exp2, 1 ) ) ); /* in Q14 */ -#endif /* exp2 is always <= 1 */ gain1 = s_min( gain1, 19661 /*1.2f in Q14*/ ); /*Q14*/ @@ -1236,15 +1134,9 @@ void FEC_scale_syn_ivas_fx( FOR( i = 0; i < L_frame; i++ ) { gain1 = mac_r( L_tmp, gain1, AGC_FX ); /* in Q14 */ -#ifdef BASOP_NOGLOB exc[i] = mac_r_sat( L_mult_sat( exc[i], gain1 ), exc[i], gain1 ); move16(); exc2[i] = mac_r_sat( L_mult_sat( exc2[i], gain1 ), exc2[i], gain1 ); -#else - exc[i] = mac_r( L_mult( exc[i], gain1 ), exc[i], gain1 ); - move16(); - exc2[i] = mac_r( L_mult( exc2[i], gain1 ), exc2[i], gain1 ); -#endif move16(); } diff --git a/lib_dec/LD_music_post_filter.c b/lib_dec/LD_music_post_filter.c deleted file mode 100644 index b2b69cc4506ca9cbac64eb5e1b85bb3920c05818..0000000000000000000000000000000000000000 --- a/lib_dec/LD_music_post_filter.c +++ /dev/null @@ -1,44 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include -#include "cnst.h" -#include "rom_com.h" -#include "prot.h" -#include "prot_fx.h" -#include "wmc_auto.h" diff --git a/lib_dec/LD_music_post_filter_fx.c b/lib_dec/LD_music_post_filter_fx.c index 04252087049f01e5d53724775d022d625c1d856c..5b48ab47225f7355d8f46111c86dd939b2fc7461 100644 --- a/lib_dec/LD_music_post_filter_fx.c +++ b/lib_dec/LD_music_post_filter_fx.c @@ -186,11 +186,7 @@ void LD_music_post_filter_fx( FOR( k = j; k < mfreq_bindiv_LD[i] + j; k++ ) { /*m_ave += lf_E[k];*/ -#ifdef BASOP_NOGLOB Ltmp = L_add_o( lf_E[k], Ltmp, &Overflow ); /*2*Qdct+10*/ -#else - Ltmp = L_add( lf_E[k], Ltmp ); -#endif max_val = L_max( max_val, lf_E[k] ); } Ltmp_max = L_max( Ltmp_max, max_val ); /*2*Qdct+10*/ @@ -364,27 +360,19 @@ void LD_music_post_filter_fx( FOR( ; i < BIN_2KHZ; i++ ) { - tmp16 = s_min( max_ovf_2k, hMusicPF->filt_lfE_fx[i] ); /*Q12*/ - tmp16 = s_max( min_g_2k, tmp16 ); /*Q12*/ - /*DCT_buf[i] *= ftmp;*/ -#ifdef BASOP_NOGLOB + tmp16 = s_min( max_ovf_2k, hMusicPF->filt_lfE_fx[i] ); /*Q12*/ + tmp16 = s_max( min_g_2k, tmp16 ); /*Q12*/ + /*DCT_buf[i] *= ftmp;*/ dtc_out[i] = round_fx_sat( L_shl_sat( L_mult( dtc_out[i], tmp16 ), 3 ) ); /*Q15*/ -#else - dtc_out[i] = round_fx( L_shl( L_mult( dtc_out[i], tmp16 ), 3 ) ); -#endif move16(); } FOR( ; i < BIN_4KHZ; i++ ) { - tmp16 = s_min( max_ovf_4k, hMusicPF->filt_lfE_fx[i] ); /*Q12*/ - tmp16 = s_max( min_g_4k, tmp16 ); /*Q12*/ - /*DCT_buf[i] *= ftmp;*/ -#ifdef BASOP_NOGLOB + tmp16 = s_min( max_ovf_4k, hMusicPF->filt_lfE_fx[i] ); /*Q12*/ + tmp16 = s_max( min_g_4k, tmp16 ); /*Q12*/ + /*DCT_buf[i] *= ftmp;*/ dtc_out[i] = round_fx_sat( L_shl_sat( L_mult_sat( dtc_out[i], tmp16 ), 3 ) ); /*Q15*/ -#else - dtc_out[i] = round_fx( L_shl( L_mult( dtc_out[i], tmp16 ), 3 ) ); -#endif move16(); } @@ -394,14 +382,10 @@ void LD_music_post_filter_fx( /* Do not modify HF when coded with GSC at LR, because the spectrum is just noise */ FOR( ; i < DCT_L_POST; i++ ) { - tmp16 = s_min( max_ovf_6k, hMusicPF->filt_lfE_fx[i] ); /*Q12*/ - tmp16 = s_max( min_g_6k, tmp16 ); /*Q12*/ - /*DCT_buf[i] *= ftmp;*/ -#ifdef BASOP_NOGLOB + tmp16 = s_min( max_ovf_6k, hMusicPF->filt_lfE_fx[i] ); /*Q12*/ + tmp16 = s_max( min_g_6k, tmp16 ); /*Q12*/ + /*DCT_buf[i] *= ftmp;*/ dtc_out[i] = round_fx_sat( L_shl_sat( L_mult_sat( dtc_out[i], tmp16 ), 3 ) ); /*Q15*/ -#else - dtc_out[i] = round_fx( L_shl( L_mult( dtc_out[i], tmp16 ), 3 ) ); -#endif move16(); } } @@ -411,13 +395,9 @@ void LD_music_post_filter_fx( /* When unsure on content type only slight clean-up allowed, no overshoot allowed */ FOR( ; i < DCT_L_POST; i++ ) { - tmp16 = s_min( 4096 /*1.0f in Q12*/, hMusicPF->filt_lfE_fx[i] ); /*Q12*/ - /*DCT_buf[i] *= ftmp;*/ -#ifdef BASOP_NOGLOB + tmp16 = s_min( 4096 /*1.0f in Q12*/, hMusicPF->filt_lfE_fx[i] ); /*Q12*/ + /*DCT_buf[i] *= ftmp;*/ dtc_out[i] = round_fx_sat( L_shl_sat( L_mult_sat( dtc_out[i], tmp16 ), 3 ) ); /*Q15*/ -#else - dtc_out[i] = round_fx( L_shl( L_mult( dtc_out[i], tmp16 ), 3 ) ); -#endif move16(); } } @@ -543,11 +523,7 @@ static void spectrum_mod_dct_fx( IF( music_flag != 0 ) /* prevent subtraction on clean speech */ { -#ifdef BASOP_NOGLOB IF( LE_32( maxNoise, L_shl_o( 10, scaling, &Overflow ) ) ) -#else - IF( LE_32( maxNoise, L_shl( 10, scaling ) ) ) -#endif { minE = 18432 / 2; /*Q14*/ move16(); @@ -623,21 +599,12 @@ static void spectrum_mod_dct_fx( Ltmp = L_mult( tmpN, m_binE ); /*2*Qdct+e_binE+9*/ e_binE = sub( add( e_tmp, e_binE ), 15 ); -#ifdef BASOP_NOGLOB Ltmp = L_shr_o( Ltmp, e_binE, &Overflow ); /*2*Qdct+9*/ Lgain = L_add_o( Ltmp, Lshift, &Overflow ); /*Saturation can occure here result in Q30*/ -#else - Ltmp = L_shr( Ltmp, e_binE ); - Lgain = L_add( Ltmp, Lshift ); /*Saturation can occure here result in Q30*/ -#endif } Lpt2++; -#ifdef BASOP_NOGLOB gain = round_fx_o( Lgain, &Overflow ); /*gain in Q30-16 = Q14*/ -#else - gain = round_fx( Lgain ); /*gain in Q30-16 = Q14*/ -#endif /*if (gain < minE)gain = minE;*/ gain = s_max( gain, minE ); /*Q14*/ /*if (gain > 1.0f+MAX_GN)gain = 1.0f+MAX_GN;*/ @@ -661,14 +628,10 @@ static void spectrum_mod_dct_fx( alpha = shl( sub( 16384 /*Q14*/, sqrt_gain ), 1 ); /*Q15*/ /**pt_gbin = gain + alpha * *pt_gbin;*/ - Ltmp = L_mult( gain, 32767 /*Q15*/ ); /*Q30*/ - *pt_gbin = round_fx( L_mac( Ltmp, alpha, *pt_gbin ) ); /*Q14*/ - /**pt++ *= *pt_gbin;*/ -#ifdef BASOP_NOGLOB + Ltmp = L_mult( gain, 32767 /*Q15*/ ); /*Q30*/ + *pt_gbin = round_fx( L_mac( Ltmp, alpha, *pt_gbin ) ); /*Q14*/ + /**pt++ *= *pt_gbin;*/ *pt = round_fx_sat( L_shl_sat( L_mult( *pt, *pt_gbin ), 1 ) ); /*Qdct*/ -#else - *pt = round_fx( L_shl( L_mult( *pt, *pt_gbin ), 1 ) ); -#endif move16(); move16(); pt++; @@ -774,11 +737,7 @@ static void find_enr_dct_fx( { /* energy */ /**ptE = *ptR * *ptR; */ -#ifdef BASOP_NOGLOB Ltmp = L_mult_sat( *ptR, *ptR ); /*2*Qdct+1*/ -#else - Ltmp = L_mult( *ptR, *ptR ); -#endif /* normalization */ /**ptE *= 1.0f / (DCT_L_POST);*/ Ltmp = Mult_32_16( Ltmp, 26214 ); /*26214 = 1.0/640 ->Q15+9 --> 2*Q_dct + 10*/ @@ -787,11 +746,7 @@ static void find_enr_dct_fx( move32(); /*band[i] += *ptE++;*/ -#ifdef BASOP_NOGLOB Ltmp1 = L_add_sat( Ltmp, Ltmp1 ); /*2*Q_dct + 10*/ -#else - Ltmp1 = L_add( Ltmp, Ltmp1 ); -#endif ptE++; ptR++; @@ -812,11 +767,7 @@ static void find_enr_dct_fx( FOR( i = min_band; i <= NB_LIMIT_BAND; i++ ) { /* total channel energy */ -#ifdef BASOP_NOGLOB Ltmp = L_add_sat( band[i], Ltmp ); /* 2*Q_dct + 10*/ -#else - Ltmp = L_add( band[i], Ltmp ); -#endif } *Etot = Ltmp; /* 2*Q_dct + 10*/ @@ -965,11 +916,7 @@ static Word16 norm_lfe( exp3 = sub( exp2, 12 + 16 - 3 ); /* if exp2 < 31, means that tmp >= 1.0 */ /* Need to shl by 3 to take into account the 3 multiplications */ } -#ifdef BASOP_NOGLOB tmp16 = shl_o( tmp16, exp3, &Overflow ); /* Result in Q12 */ -#else - tmp16 = shl( tmp16, exp3 ); /* Result in Q12 */ -#endif return tmp16; } diff --git a/lib_dec/TonalComponentDetection.c b/lib_dec/TonalComponentDetection.c deleted file mode 100644 index 040d4569daf24e167a6e355e26da5e8284ea5779..0000000000000000000000000000000000000000 --- a/lib_dec/TonalComponentDetection.c +++ /dev/null @@ -1,47 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#define _USE_MATH_DEFINES - -#include -#include -#include "options.h" -#include -#include "prot.h" -#include "cnst.h" -#include "stat_com.h" -#include "wmc_auto.h" -#include "ivas_prot.h" diff --git a/lib_dec/TonalComponentDetection_fx.c b/lib_dec/TonalComponentDetection_fx.c index b555eff8e7ae98691f576fd38dc9927c192562e8..ca7bec1408a10c55203b4a1990f6a7cc95bb71c8 100644 --- a/lib_dec/TonalComponentDetection_fx.c +++ b/lib_dec/TonalComponentDetection_fx.c @@ -20,12 +20,15 @@ static void calcPseudoSpec( const Word32 *mdctSpec, const Word16 mdctSpec_exp, const Word16 nSamples, Word16 floorPowerSpectrum, Word32 *powerSpec, Word16 *powerSpec_exp ); static void getEnvelope( const Word16 nSamples, const Word32 *powerSpec, Word16 F0, Word32 *envelope, Word32 *smoothedSpectrum ); static void GetF0( Word16 const nSamples, Word16 const nSamplesCore, Word32 const *const powerSpectrum, Word32 const pitchLag, Word16 *const pOrigF0, Word16 *const pF0 ); +static void ivas_GetF0_fx( Word16 const nSamples, Word16 const nSamplesCore, Word32 const *const powerSpectrum, Word32 const pitchLag, Word16 *const pOrigF0, Word16 *const pF0 ); static void findStrongestHarmonics( const Word16 nSamples, const Word32 *powerSpectrum, const Word16 F0, const Word16 nTotalHarmonics, Word16 *pHarmonicIndexes, Word16 *pnHarmonics ); static void CorrectF0( const Word16 *pHarmonicIndexes, const Word16 nHarmonics, Word16 *pF0 ); +static void ivas_CorrectF0_fx( const Word16 *pHarmonicIndexes, const Word16 nHarmonics, Word16 *pF0 ); static void findCandidates( const Word16 nSamples, const Word32 *MDCTSpectrum, const Word16 MDCTSpectrum_exp, Word16 *thresholdModificationNew, Word16 floorPowerSpectrum ); static void modifyThreshold( Word16 i, Word16 F0, Word16 threshold, Word16 *thresholdModification ); static void modifyThresholds( Word16 F0, Word16 origF0, Word16 *thresholdModification ); static void RefineThresholdsUsingPitch( const Word16 nSamples, const Word16 nSamplesCore, const Word32 powerSpectrum[], const Word32 lastPitchLag, const Word32 currentPitchLag, Word16 *pF0, Word16 *thresholdModification ); +static void ivas_RefineThresholdsUsingPitch_fx( const Word16 nSamples, const Word16 nSamplesCore, const Word32 powerSpectrum[], const Word32 lastPitchLag, const Word32 currentPitchLag, Word16 *pF0, Word16 *thresholdModification ); static void findTonalComponents( Word16 *indexOfTonalPeak, Word16 *lowerIndex, Word16 *upperIndex, Word16 *numIndexes, Word16 nSamples, const Word32 *powerSpectrum, Word16 F0, Word16 *thresholdModification, Word16 element_mode ); /*-------------------------------------------------------------------* @@ -121,7 +124,7 @@ void ivas_DetectTonalComponents_fx( findCandidates( nSamples, pScaledMdctSpectrum, lastMDCTSpect_exp, thresholdModification, floorPowerSpectrum ); /* Refine peak candidates using the pitch information */ - RefineThresholdsUsingPitch( nSamples, nSamplesCore, secondLastPowerSpectrum, lastPitchLag, currentPitchLag, &F0, thresholdModification ); + ivas_RefineThresholdsUsingPitch_fx( nSamples, nSamplesCore, secondLastPowerSpectrum, lastPitchLag, currentPitchLag, &F0, thresholdModification ); /* Find peaks in the second last frame */ findTonalComponents( indexOfTonalPeak, lowerIndex, upperIndex, pNumIndexes, nSamples, secondLastPowerSpectrum, F0, thresholdModification, element_mode ); @@ -491,11 +494,7 @@ static void getEnvelope( /* No need for PTR_INIT for powerSpec[i+n2] as we continue from the previous loop */ FOR( i = 0; i < n1; i++ ) { -#ifdef BASOP_NOGLOB - sum = L_add_sat( sum, powerSpec[i + n2] ); /*powerSpec_exp*/ -#else - sum = L_add( sum, powerSpec[i + n2] ); -#endif + sum = L_add_sat( sum, powerSpec[i + n2] ); /*powerSpec_exp*/ tmp = Mpy_32_16_1( sum /*Q31,powerSpec_exp*/, level /*Q12*/ ); /*Q28,powerSpec_exp*/ envelope[i] /*Q28,powerSpec_exp*/ = Mpy_32_16_1( tmp /*Q28,powerSpec_exp*/, InvIntTable[i + nSecondHalfFilterLength] /*Q15*/ ); move32(); @@ -504,12 +503,8 @@ static void getEnvelope( inv_len = mult_r( level, InvIntTable[nFilterLength] ); /*Q12*/ FOR( i = n1; i < nSamples - n2; i++ ) { -#ifdef BASOP_NOGLOB sum = L_add_sat( sum, L_sub( powerSpec[i + n2], powerSpec[i - n1] ) ); /*powerSpec_exp*/ -#else - sum = L_add( sum, L_sub( powerSpec[i + n2], powerSpec[i - n1] ) ); -#endif - envelope[i] = Mpy_32_16_1( sum, inv_len ); /*Q28*/ + envelope[i] = Mpy_32_16_1( sum, inv_len ); /*Q28*/ move32(); } @@ -593,6 +588,65 @@ static void GetF0( return; } +static void ivas_GetF0_fx( + Word16 /*short*/ const nSamples, /*i - Q0 */ + Word16 /*short*/ const nSamplesCore, /*i - Q0 */ + Word32 /*int*/ const *const powerSpectrum, + /*i - Qx */ /*is justed handed over and given back*/ + Word32 /*int*/ const pitchLag, /*i - Q16*/ + Word16 /*short*/ *const pOrigF0, /*o - Q10*/ + Word16 /*short*/ *const pF0 ) /*o - Q10*/ +{ + Word16 /*short*/ tmpPitchLag; + Word16 /*short*/ rgiStrongHarmonics[MAX_PEAKS_FROM_PITCH]; /*Q0*/ + Word16 /*short*/ nTotalHarmonics, nStrongHarmonics; + Word16 tmp; + + + assert( LAST_HARMONIC_POS_TO_CHECK <= nSamplesCore ); + + /* Use only F0 >= 100 Hz */ + test(); + IF( ( pitchLag > 0 ) && ( LE_16( round_fx( pitchLag ), shr( nSamplesCore, 1 ) ) ) ) + { + + tmpPitchLag /*"halfPitchLag" in FLC - read as Q5 for comparison to halfpitchlag Q4*/ + = round_fx( L_shl( pitchLag, 4 ) ); /*no division by 2, will be done in following division - + furthermore, do a leftshift before rounding, to preserve more accuracy - + will be accommodated also in following division*/ + + /**pF0 = nSamplesCore/tmpPitchLag;*/ + BASOP_Util_Divide_MantExp( nSamplesCore, 0, tmpPitchLag, -( 1 /*division by 2*/ + 4 /*accommodate accuracy-prevention-leftshift*/ ), pF0, &tmp ); /*pF0 is Q15*/ + move16(); + *pF0 = shr_sat( *pF0, sub( 5, tmp ) ); /*Q10 without scalingfactor*/ + move16(); + *pOrigF0 = *pF0; /*Q10*/ + move16(); + tmp = 2 * LAST_HARMONIC_POS_TO_CHECK; + if ( LT_16( nSamples, 2 * LAST_HARMONIC_POS_TO_CHECK ) ) + { + move16(); + tmp = nSamples; + } + BASOP_Util_Divide_MantExp( tmp, 15, *pF0, 5, &nTotalHarmonics, &tmp ); + nTotalHarmonics = shl( nTotalHarmonics, sub( tmp, 15 ) ); + + + /* Get in rgiStrongHarmonics all i for which i*F0 are the strongest harmonics */ + findStrongestHarmonics( nSamples, powerSpectrum, *pF0, nTotalHarmonics, rgiStrongHarmonics, &nStrongHarmonics ); + + ivas_CorrectF0_fx( rgiStrongHarmonics, nStrongHarmonics, pF0 ); + } + ELSE + { + move16(); + move16(); + *pF0 = 0; + *pOrigF0 = 0; + } + return; +} + static void findStrongestHarmonics( const Word16 nSamples, @@ -833,6 +887,159 @@ static void CorrectF0( return; } +static void ivas_CorrectF0_fx( + const Word16 /*short*/ *pHarmonicIndexes, /*I - Q0 */ + const Word16 /*short*/ nHarmonics, /*I - Q0 */ + Word16 /*short*/ *pF0 ) /*I/O - Q10 range: {0}, [4..18) */ +{ + Word16 /*short*/ i; + Word16 /*short*/ F0; + Word16 /*short*/ diff[MAX_PEAKS_FROM_PITCH - 1], sortedDiff[MAX_PEAKS_FROM_PITCH - 1]; /*Q0*/ + Word16 /*short*/ iMostCommonDiff, nMostCommonDiff, nSameDiff, iMult; /*Q0*/ + + Word16 tmp; + + FOR( i = 0; i < MAX_PEAKS_FROM_PITCH - 1; i++ ) + { + diff[i] = 0; + sortedDiff[i] = 0; + move16(); + move16(); + } + + F0 = *pF0; /*Q10*/ + + test(); + IF( F0 > 0 && nHarmonics != 0 ) + { + tmp = sub( nHarmonics, 1 ); + FOR( i = 0; i < tmp; i++ ) + { + diff[i] = sub( pHarmonicIndexes[i + 1], pHarmonicIndexes[i] ); /*Q0*/ + move16(); + sortedDiff[i] = diff[i]; /*Q0*/ + move16(); + } + sort_fx( sortedDiff, 0, sub( nHarmonics, 1 + 1 ) ); + iMostCommonDiff = sortedDiff[0]; /*Q0*/ + move16(); + nSameDiff = 1; + move16(); + i = 1; + move16(); + IF( EQ_16( imult1616( sortedDiff[0], pHarmonicIndexes[0] ), 1 ) ) + { + /* Find how many distances between peaks have length 1 */ + FOR( ; i < tmp; i++ ) + { + if ( EQ_16( sortedDiff[i], 1 ) ) + { + nSameDiff = add( nSameDiff, 1 ); + } + } + } + nMostCommonDiff = nSameDiff; /*Q0*/ + move16(); + + /* If there are at least 3 distances between peaks with length 1 and if the 1st harmonic is in pHarmonicIndexes then keep the original F0 */ + /* Otherwise find the most common distance between peaks */ + IF( LT_16( nSameDiff, 3 ) ) + { + /* Find the most common difference */ + FOR( i = nSameDiff; i < tmp; i++ ) + { + IF( EQ_16( sortedDiff[i], sortedDiff[i - 1] ) ) + { + nSameDiff = add( nSameDiff, 1 ); + } + ELSE + { + IF( GT_16( nSameDiff, nMostCommonDiff ) ) + { + nMostCommonDiff = nSameDiff; /*Q0*/ + move16(); + iMostCommonDiff = sortedDiff[i - 1]; /*Q0*/ + move16(); + } + ELSE + { + test(); + IF( EQ_16( nSameDiff, nMostCommonDiff ) && GT_16( abs_s( sub( iMostCommonDiff, pHarmonicIndexes[0] ) ), abs_s( sub( sortedDiff[i - 1], pHarmonicIndexes[0] ) ) ) ) + { + nMostCommonDiff = nSameDiff; /*Q0*/ + move16(); + iMostCommonDiff = sortedDiff[i - 1]; /*Q0*/ + move16(); + } + } + nSameDiff = 1; + move16(); + } + } + IF( GT_16( nSameDiff, nMostCommonDiff ) ) + { + nMostCommonDiff = nSameDiff; /*Q0*/ + move16(); + iMostCommonDiff = sortedDiff[nHarmonics - 2]; /*Q0*/ + move16(); + } + } + + /* If there are enough peaks at the same distance */ + IF( GE_16( nMostCommonDiff, MAX_PEAKS_FROM_PITCH / 2 ) ) + { + iMult = 1; + move16(); + FOR( i = 0; i < tmp; i++ ) + { + IF( EQ_16( diff[i], iMostCommonDiff ) ) + { + iMult = pHarmonicIndexes[i]; /*Q0*/ + move16(); + BREAK; + } + /* for rare cases of octave mismatch or missing harmonics */ + test(); + test(); + IF( GT_16( sub( nHarmonics, 2 ), i ) && ( EQ_16( diff[i], diff[i + 1] ) ) && ( EQ_16( add( diff[i], diff[i + 1] ), iMostCommonDiff ) ) ) + { + iMult = pHarmonicIndexes[i]; /*Q0*/ + move16(); + BREAK; + } + } + + /* If the real F0 is much higher than the original F0 from the pitch */ + + IF( LE_16( iMult, 3 ) ) + { + /* Use iMostCommonDiff, because the lowest pHarmonicIndexes[i] (which is equal to iMult) may not correspond to the new F0, but to it's multiple */ + F0 = round_fx_sat( L_shl_sat( L_mult( iMostCommonDiff /*Q0*/, F0 /*Q10*/ ), 15 ) ); /*Q10*/ + } + ELSE + { + F0 = 0; + move16(); + } + } + /* Otherwise if there are at least 3 distances between peaks with length 1 and if the 1st harmonic is in pHarmonicIndexes then keep the original F0 */ + /* Otherwise don't use F0 */ + ELSE + { + test(); + if ( ( GT_16( iMostCommonDiff, 1 ) ) || ( LT_16( nMostCommonDiff, 3 ) ) ) + { + /* Not enough peaks at the same distance => don't use the pitch. */ + F0 = 0; + move16(); + } + } + *pF0 = F0; + move16(); + } + return; +} + static void modifyThreshold( Word16 /*short*/ i, /*I - Q0 */ Word16 /*short*/ F0, /*I - Q10*/ @@ -1073,6 +1280,45 @@ static void RefineThresholdsUsingPitch( return; } +static void ivas_RefineThresholdsUsingPitch_fx( + const Word16 nSamples, + const Word16 nSamplesCore, + const Word32 powerSpectrum[], /*Qx*/ + const Word32 lastPitchLag, /*Qx*/ + const Word32 currentPitchLag, /*Qx*/ + Word16 *pF0, /*Q10*/ + Word16 *thresholdModification /*Q10*/ +) +{ + Word16 pitchIsStable; + Word16 origF0; + Word32 L_tmp; + + /*pitchIsStable = (fabs(lastPitchLag-currentPitchLag) < 0.25f);*/ + pitchIsStable = 0; + move16(); + L_tmp = L_abs( L_sub( lastPitchLag, currentPitchLag ) ); + if ( LT_32( L_tmp, 16384l /*0.25f Q16*/ ) ) + { + pitchIsStable = 1; + move16(); + } + + IF( pitchIsStable ) + { + ivas_GetF0_fx( nSamples, + nSamplesCore, + powerSpectrum, lastPitchLag, &origF0, pF0 ); + + modifyThresholds( *pF0, origF0, thresholdModification ); + } + ELSE + { + *pF0 = 0; + move16(); + } + return; +} static void findTonalComponents( Word16 *indexOfTonalPeak, /* OUT Q0*/ Word16 *lowerIndex, /* OUT Q0*/ diff --git a/lib_dec/acelp_core_dec.c b/lib_dec/acelp_core_dec.c deleted file mode 100644 index 5350d6dbccc02b25f54c41761456798faa12ca11..0000000000000000000000000000000000000000 --- a/lib_dec/acelp_core_dec.c +++ /dev/null @@ -1,49 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - - -#include -#include -#include -#include "options.h" -#include "cnst.h" -#include "rom_com.h" -#include "prot.h" -#include "prot_fx.h" -#include "ivas_cnst.h" -#include "ivas_prot.h" -#include "ivas_rom_com.h" -#include "wmc_auto.h" diff --git a/lib_dec/acelp_core_dec_fx.c b/lib_dec/acelp_core_dec_fx.c index a41a0c813ebf50cb2a41d9fa92dcc0e33e414b91..daec97ba8206f454b6049a03a05d68d9bf2b9949 100644 --- a/lib_dec/acelp_core_dec_fx.c +++ b/lib_dec/acelp_core_dec_fx.c @@ -107,9 +107,6 @@ ivas_error acelp_core_dec_fx( Word16 uc_two_stage_flag, dec; Word16 nb_bits, indice; Word16 tdm_lp_reuse_flag, tdm_low_rate_mode, tdm_Pitch_reuse_flag; -#ifdef ADD_LRTD - Word16 *p_tdm_Pri_pitch_buf; -#endif MUSIC_POSTFILT_HANDLE hMusicPF; BPF_DEC_HANDLE hBPF; TD_BWE_DEC_HANDLE hBWE_TD; @@ -146,66 +143,6 @@ ivas_error acelp_core_dec_fx( return error; } - -#ifdef IVAS_CODE - output_frame = (int16_t) ( st->output_Fs / FRAMES_PER_SEC ); - - /*----------------------------------------------------------------* - * stereo SID and CNG frames processing - *----------------------------------------------------------------*/ - - if ( st->core_brate <= SID_2k40 && st->element_mode == IVAS_CPE_DFT && nchan_out == 2 ) - { - if ( st->cng_type == FD_CNG ) - { - configureFdCngDec_fx( st->hFdCngDec, st->bwidth, ACELP_14k25, st->L_frame, st->last_L_frame, st->element_mode ); - - /* Only run parameter decoding in SID frames */ - if ( st->core_brate == SID_2k40 ) - { - FdCng_decodeSID_fx( st ); - } - - for ( i = 0; i < NPART; i++ ) - { - st->hFdCngDec->hFdCngCom->sidNoiseEstLp[i] = STEREO_DFT_FD_FILT * st->hFdCngDec->hFdCngCom->sidNoiseEstLp[i] + ( 1 - STEREO_DFT_FD_FILT ) * st->hFdCngDec->hFdCngCom->sidNoiseEst[i]; - } - -#ifdef IVAS_CODE_CNG_FIX185_PLC_FADEOUT - ApplyFdCng_fx( NULL, NULL, NULL, NULL, st, 0, 0 ); -#else - ApplyFdCng_fx( NULL, NULL, NULL, NULL, st, 0, 0 ); -#endif - } - else - { - configureFdCngDec_fx( st->hFdCngDec, st->bwidth, ACELP_14k25, st->L_frame, st->last_L_frame, st->element_mode ); - - /* decode CNG parameters */ - CNG_dec( st, last_element_mode, Aq, lsp_new, lsf_new, &allow_cn_step, sid_bw, q_env ); - - /* comfort noise generation */ - CNG_exc( st->core_brate, st->L_frame, &st->hTdCngDec->Enew, &st->hTdCngDec->cng_seed, NULL, NULL, &st->lp_ener, st->last_core_brate, &st->first_CNG, &( st->hTdCngDec->cng_ener_seed ), NULL, allow_cn_step, &st->hTdCngDec->last_allow_cn_step, st->hTdCngDec->num_ho, q_env, st->hTdCngDec->lp_env, st->hTdCngDec->old_env, st->hTdCngDec->exc_mem, st->hTdCngDec->exc_mem1, sid_bw, &st->hTdCngDec->cng_ener_seed1, NULL, st->Opt_AMR_WB, st->element_mode ); - - mvr2r( Aq, st->Aq_cng, M + 1 ); - - /* update old LSP and LSF vector */ - mvr2r( lsf_new, st->lsf_old, M ); - mvr2r( lsp_new, st->lsp_old, M ); - } - - set_f( output, 0, output_frame ); /* output and synth are not used in DFT domain CNG generation and the decoder output is unaffected if they are left uninitalized */ - set_f( synth, 0, output_frame ); /* They are however read in a few places which causes errors in the valgrind tests. Simplest solution from a code perspective was to set them to zero. */ - - /* CN generation done in DFT domain */ - wmops_sub_end(); - return error; - } - - /*----------------------------------------------------------------* - * Active frames processing - *----------------------------------------------------------------*/ -#endif FOR( i = 0; i < CLDFB_NO_COL_MAX; i++ ) { set32_fx( realBufferTmp[i], 0, CLDFB_NO_CHANNELS_MAX ); @@ -268,13 +205,7 @@ ivas_error acelp_core_dec_fx( move32(); } } -#ifdef IVAS_CODE - if ( st->hFdCngDec != NULL && ( st->element_mode == IVAS_CPE_DFT || st->element_mode == IVAS_CPE_TD ) && ( st->last_core_brate == SID_2k40 || st->last_core_brate == FRAME_NO_DATA ) ) - { - set_zero( st->hFdCngDec->hFdCngCom->olapBufferSynth2, FFTLEN ); - set_zero( hStereoCng->olapBufferSynth22, FFTLEN ); - } -#endif + st_fx->clas_dec = st_fx->last_good; move16(); enr_q_fx = 0; @@ -359,9 +290,6 @@ ivas_error acelp_core_dec_fx( tdm_lp_reuse_flag = hStereoTD->tdm_lp_reuse_flag; tdm_low_rate_mode = hStereoTD->tdm_low_rate_mode; tdm_Pitch_reuse_flag = hStereoTD->tdm_Pitch_reuse_flag; -#ifdef ADD_LRTD - p_tdm_Pri_pitch_buf = hStereoTD->tdm_Pri_pitch_buf; -#endif move16(); move16(); move16(); @@ -380,9 +308,6 @@ ivas_error acelp_core_dec_fx( move16(); } tdm_Pitch_reuse_flag = 0; -#ifdef ADD_LRTD - p_tdm_Pri_pitch_buf = NULL; -#endif move16(); } /*----------------------------------------------------------------* @@ -422,7 +347,7 @@ ivas_error acelp_core_dec_fx( Copy( GEWB_Ave_fx, st_fx->mem_AR_fx, M ); // Qlog2(2.56) } set16_fx( st_fx->mem_MA_fx, 0, M ); -#if 1 // def IVAS_CODE + dec = DEC; move16(); IF( NE_16( st_fx->element_mode, EVS_MONO ) ) @@ -433,9 +358,7 @@ ivas_error acelp_core_dec_fx( /* update synthesis filter memories */ synth_mem_updt2( st_fx->L_frame, st_fx->last_L_frame, st_fx->old_exc_fx, st_fx->mem_syn_r, st_fx->mem_syn2_fx, NULL, dec ); -#else - synth_mem_updt2( st_fx->L_frame, st_fx->last_L_frame, st_fx->old_exc_fx, st_fx->mem_syn_r, st_fx->mem_syn2_fx, NULL, DEC ); -#endif + Copy( st_fx->old_exc_fx, old_exc_fx, L_EXC_MEM_DEC ); // Q_exc Copy_Scale_sig( st_fx->mem_syn2_fx, st_fx->mem_syn1_fx, M, sub( -1, st_fx->Q_syn ) ); /*Q-1*/ @@ -600,7 +523,7 @@ ivas_error acelp_core_dec_fx( { tc_subfr_fx = tc_classif_fx( st_fx, st_fx->L_frame ); } -#if 1 // def IVAS_CODE + /*----------------------------------------------------------------* * Decoding of GSC IVAS mode *----------------------------------------------------------------*/ @@ -620,7 +543,7 @@ ivas_error acelp_core_dec_fx( move16(); } } -#endif + /*----------------------------------------------------------------* * Decoding of inactive CNG frames *----------------------------------------------------------------*/ @@ -632,22 +555,13 @@ ivas_error acelp_core_dec_fx( { CNG_dec_fx( st_fx, st_fx->last_element_mode, Aq_fx, lsp_new_fx, lsf_new_fx, &allow_cn_step_fx, sid_bw, q_env ); -#ifdef IVAS_CODE - local_element_mode = st_fx->element_mode; - move16(); - IF( ( EQ_16( nchan_out, 1 ) && EQ_16( st_fx->element_mode, IVAS_CPE_DFT ) ) || EQ_16( st_fx->masa_sid_format, 1 ) ) - { - local_element_mode = IVAS_SCE; /* For DFT Stereo mono decoding, run CNG_exc as in SCE */ - move16(); - } -#endif + /* comfort noise generation */ CNG_exc_fx( st_fx->core_brate, st_fx->L_frame, &st_fx->hTdCngDec->Enew_fx, &st_fx->hTdCngDec->cng_seed, exc_fx, exc2_fx, &st_fx->lp_ener_fx, st_fx->last_core_brate, &st_fx->first_CNG, &( st_fx->hTdCngDec->cng_ener_seed ), bwe_exc_fx, allow_cn_step_fx, &st_fx->hTdCngDec->last_allow_cn_step, st_fx->prev_Q_exc, st_fx->Q_exc, st_fx->hTdCngDec->num_ho, q_env, st_fx->hTdCngDec->lp_env_fx, st_fx->hTdCngDec->old_env_fx, st_fx->hTdCngDec->exc_mem_fx, st_fx->hTdCngDec->exc_mem1_fx, sid_bw, &st_fx->hTdCngDec->cng_ener_seed1, exc3_fx, st_fx->Opt_AMR_WB, st_fx->element_mode ); -#if 1 // def IVAS_CODE + Copy( Aq_fx, st_fx->Aq_cng, M + 1 ); // Q12 -#endif } ELSE { @@ -658,32 +572,7 @@ ivas_error acelp_core_dec_fx( *sid_bw = 0; move16(); } -#ifdef IVAS_CODE - if ( st->element_mode == IVAS_CPE_DFT ) - { - assert( nchan_out == 1 ); - for ( i = 0; i < NPART; i++ ) - { - st->hFdCngDec->hFdCngCom->sidNoiseEstLp[i] = STEREO_DFT_FD_FILT * st->hFdCngDec->hFdCngCom->sidNoiseEstLp[i] + ( 1 - STEREO_DFT_FD_FILT ) * st->hFdCngDec->hFdCngCom->sidNoiseEst[i]; - } -#ifdef IVAS_CODE_CNG_FIX185_PLC_FADEOUT - ApplyFdCng_fx( syn, 0, NULL, realBuffer, imagBuffer, NULL, st, 0, ( st->coder_type == AUDIO && !st->GSC_noisy_speech ) ); -#else - ApplyFdCng_fx( syn, realBuffer, imagBuffer, st, 0, ( st->coder_type == AUDIO && !st->GSC_noisy_speech ) ); -#endif - } - if ( !read_sid_info ) - { - float noise_lvl_highest; - - noise_lvl_highest = st->hFdCngDec->hFdCngCom->cngNoiseLevel[st->hFdCngDec->hFdCngCom->stopFFTbin - st->hFdCngDec->hFdCngCom->startBand - 1]; - for ( int16_t b = st->hFdCngDec->hFdCngCom->stopFFTbin - st->hFdCngDec->hFdCngCom->startBand; b < st->hFdCngDec->hFdCngCom->stopBand; b++ ) - { - st->hFdCngDec->hFdCngCom->cngNoiseLevel[b] = noise_lvl_highest; - } - } -#endif generate_comfort_noise_dec_fx( NULL, NULL, NULL, st_fx, &( st_fx->Q_exc ), 2, -1 ); FdCng_exc( st_fx->hFdCngDec->hFdCngCom, &st_fx->CNG_mode, st_fx->L_frame, st_fx->lsp_old_fx, st_fx->first_CNG, st_fx->lspCNG_fx, Aq_fx, lsp_new_fx, lsf_new_fx, exc_fx, exc2_fx, bwe_exc_fx ); @@ -777,14 +666,21 @@ ivas_error acelp_core_dec_fx( move16(); } +#ifdef NONBE_FIX_GSC_BSTR + config_acelp1( DEC, st_fx->total_brate, st_fx->core_brate, st_fx->core, st_fx->extl_orig, st_fx->extl_brate_orig, st_fx->L_frame, st_fx->GSC_noisy_speech, &( st_fx->acelp_cfg ), st_fx->next_bit_pos, st_fx->coder_type, st_fx->inactive_coder_type_flag, tc_subfr_tmp, 1, &nb_bits, unbits, st_fx->element_mode, &uc_two_stage_flag, tdm_lp_reuse_flag, tdm_low_rate_mode, st_fx->idchan, st_fx->active_cnt, tdm_Pitch_reuse_flag, st_fx->tdm_LRTD_flag, st_fx->GSC_IVAS_mode ); +#else config_acelp1( DEC, st_fx->total_brate, st_fx->core_brate, st_fx->core, st_fx->extl_orig, st_fx->extl_brate_orig, st_fx->L_frame, st_fx->GSC_noisy_speech, &( st_fx->acelp_cfg ), st_fx->next_bit_pos, st_fx->coder_type, tc_subfr_tmp, 1, &nb_bits, unbits, st_fx->element_mode, &uc_two_stage_flag, tdm_lp_reuse_flag, tdm_low_rate_mode, st_fx->idchan, st_fx->active_cnt, tdm_Pitch_reuse_flag, st_fx->tdm_LRTD_flag, st_fx->GSC_IVAS_mode ); - +#endif test(); test(); IF( EQ_16( st_fx->coder_type, TRANSITION ) && LT_16( tc_subfr_fx, L_SUBFR ) && EQ_16( st_fx->L_frame, L_FRAME ) ) { +#ifdef NONBE_FIX_GSC_BSTR + config_acelp1( DEC, st_fx->total_brate, st_fx->core_brate, st_fx->core, st_fx->extl_orig, st_fx->extl_brate_orig, st_fx->L_frame, -1, &( st_fx->acelp_cfg ), st_fx->next_bit_pos, TRANSITION, -1, tc_subfr_fx, 2, &nb_bits, unbits, st_fx->element_mode, &uc_two_stage_flag, tdm_lp_reuse_flag, tdm_low_rate_mode, st_fx->idchan, st_fx->active_cnt, tdm_Pitch_reuse_flag, st_fx->tdm_LRTD_flag, st_fx->GSC_IVAS_mode ); +#else config_acelp1( DEC, st_fx->total_brate, st_fx->core_brate, st_fx->core, st_fx->extl_orig, st_fx->extl_brate_orig, st_fx->L_frame, -1, &( st_fx->acelp_cfg ), st_fx->next_bit_pos, st_fx->coder_type, tc_subfr_fx, 2, &nb_bits, unbits, st_fx->element_mode, &uc_two_stage_flag, tdm_lp_reuse_flag, tdm_low_rate_mode, st_fx->idchan, st_fx->active_cnt, tdm_Pitch_reuse_flag, st_fx->tdm_LRTD_flag, st_fx->GSC_IVAS_mode ); +#endif } } @@ -811,10 +707,6 @@ ivas_error acelp_core_dec_fx( move16(); st_fx->last_nq_preQ = 0; move16(); -#ifdef IVAS_CODE - st_fx->last_code_preq = 0; - move16(); -#endif } st_fx->use_acelp_preq = 0; @@ -823,86 +715,10 @@ ivas_error acelp_core_dec_fx( /*-----------------------------------------------------------------* * LSF de-quantization and interpolation *-----------------------------------------------------------------*/ -#ifdef ADD_LRTD - if ( !tdm_lp_reuse_flag ) -#endif - { - lsf_dec_fx( st_fx, tc_subfr_fx, Aq_fx, &LSF_Q_prediction, lsf_new_fx, lsp_new_fx, lsp_mid_fx, tdm_low_rate_mode, - tdm_lsfQ_PCh ); - } -#ifdef ADD_LRTD - else - { - const float *pt_interp_2; -#ifdef LSF_RE_USE_SECONDARY_CHANNEL - if ( st->active_cnt != 1 ) - { - int16_t beta_index; - - beta_index = get_next_indice( st, TDM_IC_LSF_PRED_BITS ); - tdm_SCh_lsf_reuse( DEC, st->element_brate, lsf_new, lsp_new, tdm_lsfQ_PCh, NULL, &beta_index ); - } - else - { - mvr2r( tdm_lspQ_PCh, lsp_new, M ); - mvr2r( tdm_lsfQ_PCh, lsf_new, M ); - } -#else - mvr2r( tdm_lspQ_PCh, lsp_new, M ); - mvr2r( tdm_lsfQ_PCh, lsf_new, M ); -#endif - if ( st->rate_switching_reset ) - { - /* extrapolation in case of unstable LSF convert */ - mvr2r( lsp_new, st->lsp_old, M ); - mvr2r( lsf_new, st->lsf_old, M ); - } - - pt_interp_2 = interpol_frac_12k8; - if ( tdm_low_rate_mode == 1 && st->coder_type > UNVOICED ) - { - pt_interp_2 = interpol_frac2; - } - - if ( st->active_cnt == 1 ) - { - mvr2r( lsp_new, st->lsp_old, M ); - lsp2lsf( lsp_new, st->lsf_old, M, st->sr_core ); - } - /* LSP interpolation and conversion of LSPs to A(z) */ - int_lsp( st->L_frame, st->lsp_old, lsp_new, Aq, M, pt_interp_2, 0 ); - /* Check LSF stability (distance between old LSFs and current LSFs) */ - st->stab_fac = lsf_stab( lsf_new, st->lsf_old, 0, st->L_frame ); - } + lsf_dec_fx( st_fx, tc_subfr_fx, Aq_fx, &LSF_Q_prediction, lsf_new_fx, lsp_new_fx, lsp_mid_fx, tdm_low_rate_mode, + tdm_lsfQ_PCh ); - if ( st->last_core == HQ_CORE && st->element_mode > EVS_MONO ) - { - /* Prepare ACB memory from last HQ frame */ - old_exc_s = st->old_exc + L_EXC_MEM_DEC - st->L_frame; - tmpF = *old_exc_s; - st->mem_deemph = old_exc_s[st->L_frame - 1]; - preemph( old_exc_s, st->preemph_fac, L_FRAME16k, &tmpF ); - mvr2r( old_exc_s + st->L_frame - M, st->mem_syn2, M ); - residu( Aq, M, old_exc_s, old_exc + L_EXC_MEM_DEC - st->L_frame, st->L_frame ); - } - if ( st->last_core != ACELP_CORE && st->element_mode > EVS_MONO ) - { - /* Prepare ACB memory of old_bwe_exc */ -#ifdef CR_FIX_639_HQ_ACELP_TRANSITION - if ( st->L_frame == L_FRAME ) - { - lerp( old_exc, old_bwe_exc, L_EXC_MEM_DEC * HIBND_ACB_L_FAC, L_EXC_MEM_DEC ); - } - else - { - lerp( old_exc, old_bwe_exc, L_EXC_MEM_DEC * 2, L_EXC_MEM_DEC ); - } -#else - lerp( old_exc, old_bwe_exc, L_EXC_MEM_DEC * HIBND_ACB_L_FAC, L_EXC_MEM_DEC ); -#endif - } -#endif /*-----------------------------------------------------------------* * FEC - first good frame after lost frame(s) (possibility to correct the ACB) *-----------------------------------------------------------------*/ @@ -972,27 +788,7 @@ ivas_error acelp_core_dec_fx( test(); test(); -#ifdef ADD_LRTD - IF( tdm_low_rate_mode ) /* tdm stereo low rate mode */ - { - IF( LE_16( st_fx->coder_type, UNVOICED ) ) - { - tdm_low_rate_dec( st_fx, dct_exc_tmp, &tmp_noise, pitch_buf, voice_factors, exc, exc2, bwe_exc, lsf_new ); - } - ELSE /* GENERIC */ - { - decod_gen_2sbfr( st_fx, sharpFlag, Aq, pitch_buf, voice_factors, exc, exc2, bwe_exc, gain_buf, tdm_Pitch_reuse_flag, p_tdm_Pri_pitch_buf ); - - IF( EQ_16( st_fx->element_mode, IVAS_CPE_TD ) ) - { - tmp_noise = st_fx->lp_gainc_fx; - move16(); - } - } - } - else -#endif - IF( EQ_16( st_fx->nelp_mode_dec, 1 ) ) + IF( EQ_16( st_fx->nelp_mode_dec, 1 ) ) { /* SC-VBR - NELP frames */ Scale_sig( exc_fx - L_EXC_MEM, L_EXC_MEM, negate( st_fx->Q_exc ) ); // Q0 @@ -1005,7 +801,7 @@ ivas_error acelp_core_dec_fx( ELSE IF( EQ_16( st_fx->coder_type, UNVOICED ) ) { /* UNVOICED frames */ - decod_unvoiced_fx( st_fx, Aq_fx, st_fx->coder_type, &tmp_noise_fx, pitch_buf_fx, voice_factors, exc_fx, exc2_fx, bwe_exc_fx, gain_buf ); + decod_unvoiced_fx( st_fx, st_fx->coder_type, &tmp_noise_fx, pitch_buf_fx, voice_factors, exc_fx, exc2_fx, bwe_exc_fx, gain_buf ); } ELSE IF( EQ_16( st_fx->ppp_mode_dec, 1 ) ) { @@ -1026,12 +822,7 @@ ivas_error acelp_core_dec_fx( } ELSE IF( EQ_16( st_fx->coder_type, AUDIO ) || ( ( st_fx->coder_type == INACTIVE ) && LE_32( st_fx->core_brate, MAX_GSC_INACTIVE_BRATE ) ) ) { - decod_audio_fx( st_fx, dct_exc_tmp, Aq_fx, pitch_buf_fx, voice_factors, exc_fx, exc2_fx, bwe_exc_fx, lsf_new_fx, gain_buf -#ifdef ADD_LRTD - , - tdm_lp_reuse_flag, tdm_low_rate_mode, tdm_Pitch_reuse_flag, p_tdm_Pri_pitch_buf -#endif - ); + decod_audio_fx( st_fx, dct_exc_tmp, Aq_fx, pitch_buf_fx, voice_factors, exc_fx, exc2_fx, bwe_exc_fx, lsf_new_fx, gain_buf ); tmp_noise_fx = shr_r( st_fx->lp_gainc_fx, 3 ); /*Q0*/ } ELSE @@ -1512,103 +1303,8 @@ ivas_error acelp_core_dec_fx( #endif } /* CNA: Generate additional comfort noise to mask potential coding artefacts */ - -#ifdef IVAS_CODE - if ( !st->cna_dirac_flag ) - { - /* CNA: Generate additional comfort noise to mask potential coding artefacts */ - if ( st->flag_cna && !( st->coder_type == AUDIO && !( st->element_mode > EVS_MONO && st->GSC_noisy_speech ) ) ) - { - if ( st->element_mode == IVAS_CPE_TD && nchan_out == 2 ) - { - if ( hStereoCng->flag_cna_fade ) - { - generate_stereo_masking_noise( syn, st, hStereoTD, flag_sec_CNA, 1, hStereoCng, nchan_out ); - hStereoCng->flag_cna_fade = 0; - } - else - { - if ( st->element_mode != last_element_mode && st->idchan == 0 ) - { - /* Clear memory for secondary channel CNA */ - set_f( hStereoCng->olapBufferSynth22, 0.0f, st->hFdCngDec->hFdCngCom->frameSize / 2 ); - } - - generate_stereo_masking_noise( syn, st, hStereoTD, flag_sec_CNA, 0, hStereoCng, nchan_out ); - } - } - else if ( st->element_mode != IVAS_CPE_DFT ) - { - if ( st->idchan == 0 ) - { - if ( st->element_mode != last_element_mode ) - { - set_f( st->hFdCngDec->hFdCngCom->olapBufferSynth2, 0.0f, st->hFdCngDec->hFdCngCom->fftlen ); - } - generate_masking_noise_fx( syn, st->hFdCngDec->hFdCngCom, st->hFdCngDec->hFdCngCom->frameSize, 0, 0, 0, st->element_mode, hStereoCng, nchan_out ); - } - } - } - else if ( st->flag_cna && st->coder_type == AUDIO && ( ( st->last_core == ACELP_CORE && !( st->last_coder_type == AUDIO && !( st->element_mode > EVS_MONO && st->Last_GSC_noisy_speech_flag ) ) ) || st->last_core == TCX_20_CORE ) ) - { - if ( st->element_mode == IVAS_CPE_TD && nchan_out == 2 ) - { - generate_stereo_masking_noise( syn, st, hStereoTD, flag_sec_CNA, 1, hStereoCng, nchan_out ); - hStereoCng->flag_cna_fade = 1; - } - else - { - v_multc( st->hFdCngDec->hFdCngCom->olapBufferSynth2 + 5 * st->hFdCngDec->hFdCngCom->frameSize / 4, (float) ( st->hFdCngDec->hFdCngCom->fftlen / 2 ), temp_buf, st->hFdCngDec->hFdCngCom->frameSize / 2 ); - v_add( temp_buf, syn, syn, st->hFdCngDec->hFdCngCom->frameSize / 2 ); - } - } - else - { - if ( hStereoCng != NULL ) - { - hStereoCng->flag_cna_fade = 1; - hStereoCng->enableSecCNA = 0; - } - } - - if ( st->element_mode == IVAS_CPE_TD ) - { - /*Noise estimate*/ - if ( st->idchan == 0 && ( nchan_out == 2 || ( st->core_brate != FRAME_NO_DATA && st->core_brate != SID_2k40 ) ) ) - { -#ifdef IVAS_CODE_CNG_FIX185_PLC_FADEOUT - ApplyFdCng_fx( syn, st_fx->Q_syn, realBuffer, imagBuffer, NULL, st, 0, ( st->coder_type == AUDIO && !st->GSC_noisy_speech ) ); -#else - ApplyFdCng_fx( syn, st_fx->Q_syn, realBuffer, imagBuffer, NULL, st, 0, ( st->coder_type == AUDIO && !st->GSC_noisy_speech ) ); -#endif - } - } - } -#endif } -#ifdef IVAS_CODE - if ( !st->cna_dirac_flag ) - { - if ( st->flag_cna == 0 && st->L_frame == L_FRAME16k && st->last_flag_cna == 1 && ( ( st->last_core == ACELP_CORE && !( st->last_coder_type == AUDIO && !( st->element_mode > EVS_MONO && st->Last_GSC_noisy_speech_flag ) ) ) || st->last_core == AMR_WB_CORE ) ) - { - v_multc( st->hFdCngDec->hFdCngCom->olapBufferSynth2 + 5 * st->L_frame / 4, 256.f, temp_buf, st->L_frame / 2 ); - v_add( temp_buf, syn, syn, st->L_frame / 2 ); - } - - if ( st->flag_cna == 0 || ( st->coder_type == AUDIO && !( st->element_mode > EVS_MONO && st->GSC_noisy_speech ) ) ) - { - if ( st->idchan == 0 ) - { - set_f( st->hFdCngDec->hFdCngCom->olapBufferSynth2, 0.f, st->hFdCngDec->hFdCngCom->fftlen ); - } - if ( hStereoCng != NULL && st->idchan == 0 ) - { - set_f( hStereoCng->olapBufferSynth22, 0.f, st->hFdCngDec->hFdCngCom->fftlen ); - } - } - } -#else test(); test(); test(); @@ -1625,9 +1321,7 @@ ivas_error acelp_core_dec_fx( move16(); } } -#endif -#ifndef IVAS_CODE test(); test(); test(); @@ -1647,7 +1341,6 @@ ivas_error acelp_core_dec_fx( { set16_fx( st_fx->hFdCngDec->hFdCngCom->olapBufferSynth2, 0, st_fx->hFdCngDec->hFdCngCom->fftlen ); } -#endif } /*----------------------------------------------------------------* @@ -1669,10 +1362,7 @@ ivas_error acelp_core_dec_fx( move16(); } } -#ifdef ADD_LRTD - /* analyze pitch coherence for bass post-filter */ - bpf_pitch_coherence( st, pitch_buf ); -#endif + test(); IF( !( EQ_16( st_fx->element_mode, IVAS_CPE_MDCT ) && st_fx->bpf_off ) ) { @@ -1695,20 +1385,6 @@ ivas_error acelp_core_dec_fx( test(); IF( NE_16( st_fx->element_mode, IVAS_CPE_DFT ) || use_cldfb_for_dft ) { -#ifdef IVAS_CODE - float realBufferSave[CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX]; - float imagBufferSave[CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX]; - float *pRealSave[CLDFB_NO_COL_MAX], *pImagSave[CLDFB_NO_COL_MAX]; - for ( i = 0; i < CLDFB_NO_COL_MAX; i++ ) - { - pRealSave[i] = realBufferSave[i]; - pImagSave[i] = imagBufferSave[i]; - } - if ( st->p_bpf_noise_buf ) - { - mvr2r( bpf_error_signal, st->p_bpf_noise_buf, st->L_frame ); - } -#endif /* analysis of the synthesis at internal sampling rate */ cldfbAnalysisFiltering( st_fx->cldfbAna, realBuffer, imagBuffer, &scaleFactor, syn_fx, negate( st_fx->Q_syn ), CLDFB_NO_COL_MAX, workBuffer ); @@ -1769,40 +1445,6 @@ ivas_error acelp_core_dec_fx( /* synthesis of the combined signal */ st_fx->Q_syn2 = st_fx->Q_syn; move16(); -#ifdef IVAS_CODE - if ( save_hb_synth != NULL ) - { - /* save and then zero-out lowband */ - for ( int16_t j = 0; j < CLDFB_NO_CHANNELS_MAX; j++ ) - { - for ( i = 0; i < CLDFB_NO_COL_MAX; i++ ) - { - realBufferSave[i][j] = realBuffer[i][j]; - imagBufferSave[i][j] = imagBuffer[i][j]; - if ( j < st->hFdCngDec->hFdCngCom->numCoreBands && i < st->hFdCngDec->hFdCngCom->numSlots ) - { - realBuffer[i][j] = 0.0f; - imagBuffer[i][j] = 0.0f; - } - } - } - - cldfbSynthesis( realBuffer, imagBuffer, save_hb_synth, -1, st->cldfbSynHB ); - - /* restore lowband */ - for ( int16_t j = 0; j < CLDFB_NO_CHANNELS_MAX; j++ ) - { - for ( i = 0; i < CLDFB_NO_COL_MAX; i++ ) - { - realBuffer[i][j] = realBufferSave[i][j]; - imagBuffer[i][j] = imagBufferSave[i][j]; - } - } - - cldfbSynthesis( pRealSave, pImagSave, synth, -1, st->cldfbSyn ); - } - else -#endif { cldfbSynthesisFiltering( st_fx->cldfbSyn, realBuffer, imagBuffer, &scaleFactor, synth_out, negate( st_fx->Q_syn2 ), CLDFB_NO_COL_MAX, workBuffer ); } @@ -1814,34 +1456,7 @@ ivas_error acelp_core_dec_fx( /* save synthesis - needed in case of core switching */ Copy( synth_out, st_fx->previoussynth_fx, output_frame ); } -#ifdef IVAS_CODE - ELSE - { - int16_t nSamples = NS2SA( st->L_frame * FRAMES_PER_SEC, FRAME_SIZE_NS /*DELAY_CLDFB_NS*/ ); /* IVAS-64: optimization is likely possible here (don't resample the whole frame) */ - - /* analysis of the synthesis at internal sampling rate - needed for DFT stereo -> TD stereo switching */ - cldfbAnalysis( syn + st->L_frame - nSamples, realBuffer, imagBuffer, nSamples, st->cldfbAna ); - - /* analysis and add the BPF error signal - needed for DFT stereo -> TD stereo switching */ - addBassPostFilter( bpf_error_signal + st->L_frame - nSamples, st->bpf_off ? 0 : nSamples, realBuffer, imagBuffer, st->cldfbBPF ); - - /* synthesis of the combined signal - needed for DFT stereo -> TD stereo switching */ - cldfbSynthesis( realBuffer, imagBuffer, synth /*dummy*/, NS2SA( st->output_Fs, FRAME_SIZE_NS /*DELAY_CLDFB_NS*/ ), st->cldfbSyn ); - - if ( st->p_bpf_noise_buf ) - { - mvr2r( bpf_error_signal, st->p_bpf_noise_buf, st->L_frame ); - } - - set_f( synth, 0.0f, output_frame ); - } - /* Copy output signal */ - if ( st->element_mode > EVS_MONO ) - { - mvr2r( syn, output, st->L_frame ); - } -#endif /*-----------------------------------------------------------------* * Bandwidth extension 6kHz-7kHz *-----------------------------------------------------------------*/ diff --git a/lib_dec/acelp_core_dec_ivas_fx.c b/lib_dec/acelp_core_dec_ivas_fx.c index 49b3297836a70ff42e2b69e68ed4471fea852703..7826546236b7c3baffb643a9adb11e38181509d0 100644 --- a/lib_dec/acelp_core_dec_ivas_fx.c +++ b/lib_dec/acelp_core_dec_ivas_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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,10 +39,8 @@ #include "options.h" #include "cnst.h" #include "rom_com.h" -#include "prot.h" #include "prot_fx.h" #include "ivas_cnst.h" -#include "ivas_prot.h" #include "ivas_rom_com.h" #include "wmc_auto.h" #include "ivas_prot_fx.h" @@ -180,7 +178,19 @@ ivas_error acelp_core_dec_ivas_fx( IF( EQ_32( st->core_brate, SID_2k40 ) ) { FdCng_decodeSID_ivas_fx( st ); +#ifdef FIX_ISSUE_1218 + Word16 n1, n2; + n1 = L_norm_arr( st->hFdCngDec->hFdCngCom->sidNoiseEst, NPART ); + n2 = L_norm_arr( st->hFdCngDec->hFdCngCom->sidNoiseEstLp, NPART ); + + Word16 common_e = s_max( sub( old_NoiseEstExp, n2 ), sub( st->hFdCngDec->hFdCngCom->sidNoiseEstExp, n1 ) ); + scale_sig32( st->hFdCngDec->hFdCngCom->sidNoiseEst, NPART, sub( st->hFdCngDec->hFdCngCom->sidNoiseEstExp, common_e ) ); + scale_sig32( st->hFdCngDec->hFdCngCom->sidNoiseEstLp, NPART, sub( old_NoiseEstExp, common_e ) ); + st->hFdCngDec->hFdCngCom->sidNoiseEstExp = common_e; + move16(); +#else rescale_fdCngDec( st->hFdCngDec, sub( old_NoiseEstExp, st->hFdCngDec->hFdCngCom->sidNoiseEstExp ) ); +#endif } FOR( i = 0; i < NPART; i++ ) { @@ -611,7 +621,11 @@ ivas_error acelp_core_dec_ivas_fx( { test(); test(); +#ifdef FIX_1189_GSC_IVAS_OMASA + IF( EQ_16( st->coder_type, AUDIO ) || ( EQ_16( st->coder_type, INACTIVE ) && EQ_16( st->inactive_coder_type_flag, 1 ) ) ) +#else IF( EQ_16( st->coder_type, AUDIO ) || ( st->coder_type == INACTIVE && LE_32( st->total_brate, MAX_GSC_INACTIVE_BRATE ) ) ) +#endif { st->GSC_IVAS_mode = get_next_indice_fx( st, 2 ); move16(); @@ -732,7 +746,11 @@ ivas_error acelp_core_dec_ivas_fx( IF( st->hMusicPF && st->hGSCDec ) { Rescale_exc( st->hMusicPF->dct_post_old_exc_fx, exc_fx, bwe_exc_fx, st->hGSCDec->last_exc_dct_in_fx, st->L_frame, +#ifdef FIX_ISSUE_1291 + L_FRAME32k, 0, &( st->Q_exc ), st->Q_subfr, NULL, 0, INACTIVE ); +#else imult1616( st->L_frame, HIBND_ACB_L_FAC ), 0, &( st->Q_exc ), st->Q_subfr, NULL, 0, INACTIVE ); +#endif } IF( st->hPFstat != NULL ) { @@ -783,10 +801,14 @@ ivas_error acelp_core_dec_ivas_fx( Copy( syn1_fx + st->L_frame - L_SYN_MEM_CLAS_ESTIM, st->mem_syn_clas_estim_fx, L_SYN_MEM_CLAS_ESTIM ); /* save and delay synthesis to be used by SWB BWE */ - Copy_Scale_sig( syn1_fx, temp_buf_fx, st->L_frame, sub( -1, st->Q_syn ) ); // Q_syn + Copy_Scale_sig( syn1_fx, temp_buf_fx, st->L_frame, sub( -1, st->Q_syn ) ); // Q_syn -> Q(-1) IF( st->hBWE_FD != NULL ) { +#ifdef FIX_ISSUE_1290 + save_old_syn_fx( st->L_frame, temp_buf_fx, old_syn_12k8_16k_fx, st->hBWE_FD->old_syn_12k8_16k_fx, st->preemph_fac, &st->hBWE_FD->mem_deemph_old_syn_fx ); +#else save_old_syn_fx( st->L_frame, syn1_fx, old_syn_12k8_16k_fx, st->hBWE_FD->old_syn_12k8_16k_fx, st->preemph_fac, &st->hBWE_FD->mem_deemph_old_syn_fx ); +#endif } } @@ -826,12 +848,21 @@ ivas_error acelp_core_dec_ivas_fx( move16(); } +#ifdef NONBE_FIX_GSC_BSTR + config_acelp1_IVAS( DEC, st->total_brate, st->core_brate, st->core, st->extl_orig, st->extl_brate_orig, st->L_frame, st->GSC_noisy_speech, &( st->acelp_cfg ), st->next_bit_pos, st->coder_type, st->inactive_coder_type_flag, tc_subfr_tmp, 1, &nb_bits, unbits, st->element_mode, &uc_two_stage_flag, tdm_lp_reuse_flag, tdm_low_rate_mode, st->idchan, st->active_cnt, tdm_Pitch_reuse_flag, st->tdm_LRTD_flag, st->GSC_IVAS_mode ); +#else config_acelp1_IVAS( DEC, st->total_brate, st->core_brate, st->core, st->extl_orig, st->extl_brate_orig, st->L_frame, st->GSC_noisy_speech, &( st->acelp_cfg ), st->next_bit_pos, st->coder_type, tc_subfr_tmp, 1, &nb_bits, unbits, st->element_mode, &uc_two_stage_flag, tdm_lp_reuse_flag, tdm_low_rate_mode, st->idchan, st->active_cnt, tdm_Pitch_reuse_flag, st->tdm_LRTD_flag, st->GSC_IVAS_mode ); +#endif + test(); test(); IF( EQ_16( st->coder_type, TRANSITION ) && LT_16( tc_subfr, L_SUBFR ) && EQ_16( st->L_frame, L_FRAME ) ) { +#ifdef NONBE_FIX_GSC_BSTR + config_acelp1_IVAS( DEC, st->total_brate, st->core_brate, st->core, st->extl_orig, st->extl_brate_orig, st->L_frame, -1, &( st->acelp_cfg ), st->next_bit_pos, TRANSITION, -1, tc_subfr, 2, &nb_bits, unbits, st->element_mode, &uc_two_stage_flag, tdm_lp_reuse_flag, tdm_low_rate_mode, st->idchan, st->active_cnt, tdm_Pitch_reuse_flag, st->tdm_LRTD_flag, st->GSC_IVAS_mode ); +#else config_acelp1_IVAS( DEC, st->total_brate, st->core_brate, st->core, st->extl_orig, st->extl_brate_orig, st->L_frame, -1, &( st->acelp_cfg ), st->next_bit_pos, st->coder_type, tc_subfr, 2, &nb_bits, unbits, st->element_mode, &uc_two_stage_flag, tdm_lp_reuse_flag, tdm_low_rate_mode, st->idchan, st->active_cnt, tdm_Pitch_reuse_flag, st->tdm_LRTD_flag, st->GSC_IVAS_mode ); +#endif } } @@ -1067,12 +1098,8 @@ ivas_error acelp_core_dec_ivas_fx( ELSE IF( EQ_16( st->coder_type, AUDIO ) || ( ( st->coder_type == INACTIVE ) && st->inactive_coder_type_flag ) ) { /* AUDIO and INACTIVE frames (coded by GSC technology) */ - decod_audio_ivas_fx( st, dct_exc_tmp_fx, Aq_fx, pitch_buf_fx, voice_factors_fx, exc_fx, exc2_fx, bwe_exc_fx, lsf_new_fx, gain_buf_fx -#if 1 // def ADD_LRTD - , - tdm_lp_reuse_flag, tdm_low_rate_mode, tdm_Pitch_reuse_flag, p_tdm_Pri_pitch_buf_fx -#endif - ); + decod_audio_ivas_fx( st, dct_exc_tmp_fx, Aq_fx, pitch_buf_fx, voice_factors_fx, exc_fx, exc2_fx, bwe_exc_fx, lsf_new_fx, gain_buf_fx, + tdm_lp_reuse_flag, tdm_low_rate_mode, tdm_Pitch_reuse_flag, p_tdm_Pri_pitch_buf_fx ); tmp_noise_fx = shr_r( st->lp_gainc_fx, 3 ); /*Q0*/ } ELSE @@ -1102,7 +1129,11 @@ ivas_error acelp_core_dec_ivas_fx( * Apply energy matching when switching to inactive frames *-----------------------------------------------------------------*/ +#ifdef NONBE_FIX_GSC_BSTR + Inac_switch_ematch_ivas_fx( exc2_fx, dct_exc_tmp_fx, st->hGSCDec->lt_ener_per_band_fx, st->coder_type, st->inactive_coder_type_flag, st->L_frame, st->Q_exc, st->bfi, st->last_core, st->last_codec_mode, tdm_low_rate_mode, st->element_mode ); +#else Inac_switch_ematch_ivas_fx( exc2_fx, dct_exc_tmp_fx, st->hGSCDec->lt_ener_per_band_fx, st->coder_type, st->L_frame, st->total_brate, st->Q_exc, st->bfi, st->last_core, st->last_codec_mode, tdm_low_rate_mode, st->element_mode ); +#endif /*------------------------------------------------------------* * Decode information and modify the excitation signal of stationary unvoiced frames @@ -1218,7 +1249,7 @@ ivas_error acelp_core_dec_ivas_fx( *------------------------------------------------------------*/ - Copy_Scale_sig( pitch_buf_fx, pitch_buf_tmp, NB_SUBFR16k, -Q6 ); // Q0 + Copy_Scale_sig( pitch_buf_fx, pitch_buf_tmp, st->nb_subfr, -Q6 ); // Q0 FEC_scale_syn_ivas_fx( st->L_frame, &update_flg, st->clas_dec, st->last_good, psyn_fx, pitch_buf_tmp, st->enr_old_fx, enr_q_fx, st->coder_type, LSF_Q_prediction, &st->scaling_flag, &st->lp_ener_FEC_av, &st->lp_ener_FEC_max, st->bfi, st->total_brate, st->prev_bfi, st->last_core_brate, exc_fx, exc2_fx, Aq_fx, &st->old_enr_LP, mem_tmp_fx, st->mem_syn2_fx, st->Q_exc, st->Q_syn, avoid_lpc_burst_on_recovery, 0 ); @@ -1309,7 +1340,11 @@ ivas_error acelp_core_dec_ivas_fx( } /* Apply energy matching when switching to inactive frames */ +#ifdef NONBE_FIX_GSC_BSTR + Inac_switch_ematch_ivas_fx( exc2_fx, dct_exc_tmp_fx, st->hGSCDec->lt_ener_per_band_fx, st->coder_type, st->inactive_coder_type_flag, st->L_frame, st->Q_exc, st->bfi, st->last_core, st->last_codec_mode, tdm_low_rate_mode, st->element_mode ); +#else Inac_switch_ematch_ivas_fx( exc2_fx, dct_exc_tmp_fx, st->hGSCDec->lt_ener_per_band_fx, st->coder_type, st->L_frame, st->total_brate, st->Q_exc, st->bfi, st->last_core, st->last_codec_mode, tdm_low_rate_mode, st->element_mode ); +#endif /* update past excitation signals for LD music post-filter */ IF( st->hMusicPF != NULL ) @@ -1372,7 +1407,7 @@ ivas_error acelp_core_dec_ivas_fx( test(); IF( EQ_32( st->total_brate, ACELP_7k20 ) || EQ_32( st->total_brate, ACELP_8k00 ) ) { - Copy_Scale_sig( pitch_buf_fx, pitch_buf_tmp, NB_SUBFR16k, -Q6 ); // Q0 + Copy_Scale_sig( pitch_buf_fx, pitch_buf_tmp, st->nb_subfr, -Q6 ); // Q0 FEC_scale_syn_ivas_fx( st->L_frame, &update_flg, st->clas_dec, st->last_good, psyn_fx, pitch_buf_tmp, st->enr_old_fx, enr_q_fx, st->coder_type, LSF_Q_prediction, &st->scaling_flag, &st->lp_ener_FEC_av, &st->lp_ener_FEC_max, st->bfi, st->total_brate, st->prev_bfi, st->last_core_brate, @@ -1409,7 +1444,7 @@ ivas_error acelp_core_dec_ivas_fx( test(); IF( st->last_bwidth == NB && st->hPFstat != NULL ) { - Copy( pitch_buf_fx, pitch_buf_tmp, NB_SUBFR16k ); + Copy_Scale_sig( pitch_buf_fx, pitch_buf_tmp, st->nb_subfr, -Q6 ); // Q0 IF( st->bwidth == NB ) { st->hPFstat->on = 1; @@ -1731,12 +1766,12 @@ ivas_error acelp_core_dec_ivas_fx( pImagSave_fx[i] = imagBufferSave_fx[i]; } #ifndef MSAN_FIX - Copy_Scale_sig_16_32( bpf_error_signal_16fx, bpf_error_signal_fx, st->L_frame, -1 ); // Q_syn-1 + Copy_Scale_sig_16_32_DEPREC( bpf_error_signal_16fx, bpf_error_signal_fx, st->L_frame, -1 ); // Q_syn-1 #endif IF( st->p_bpf_noise_buf_32 ) { #ifdef MSAN_FIX - Copy_Scale_sig_16_32( bpf_error_signal_16fx, bpf_error_signal_fx, st->L_frame, -1 ); // Q_syn-1 + Copy_Scale_sig_16_32_DEPREC( bpf_error_signal_16fx, bpf_error_signal_fx, st->L_frame, -1 ); // Q_syn-1 #endif Copy32( bpf_error_signal_fx, st->p_bpf_noise_buf_32, st->L_frame ); Scale_sig32( st->p_bpf_noise_buf_32, st->L_frame, sub( Q11, sub( st->Q_syn, 1 ) ) ); // Q11 @@ -1768,9 +1803,13 @@ ivas_error acelp_core_dec_ivas_fx( q_bpf_error_signal = Q6; move16(); #ifdef MSAN_FIX - Copy_Scale_sig_16_32( bpf_error_signal_16fx, tmp_bpf_error_signal_fx, st->L_frame, sub( q_bpf_error_signal, st->Q_syn ) ); // Q6 +#ifdef FIX_ISSUE_1237 + Copy_Scale_sig_16_32_no_sat( bpf_error_signal_16fx, tmp_bpf_error_signal_fx, st->L_frame, sub( q_bpf_error_signal, st->Q_syn ) ); // Q6 +#else + Copy_Scale_sig_16_32_DEPREC( bpf_error_signal_16fx, tmp_bpf_error_signal_fx, st->L_frame, sub( q_bpf_error_signal, st->Q_syn ) ); // Q6 +#endif #else - Copy_Scale_sig_16_32( bpf_error_signal_16fx, tmp_bpf_error_signal_fx, L_FRAME16k, q_bpf_error_signal - st->Q_syn ); // Q6 + Copy_Scale_sig_16_32_DEPREC( bpf_error_signal_16fx, tmp_bpf_error_signal_fx, L_FRAME16k, q_bpf_error_signal - st->Q_syn ); // Q6 #endif FOR( i = 0; i < CLDFB_NO_COL_MAX; i++ ) { @@ -1863,10 +1902,16 @@ ivas_error acelp_core_dec_ivas_fx( scale_sig32( realBuffer_fx[i], CLDFB_NO_CHANNELS_MAX, Q_real ); // Q_real scale_sig32( imagBuffer_fx[i], CLDFB_NO_CHANNELS_MAX, Q_imag ); // Q_imag } - scale_sig32_r( st->cldfbSynHB->cldfb_state_fx, st->cldfbSynHB->p_filter_length, sub( sub( Q_real, 1 ), Q10 ) ); // (Q_real-1) +#ifdef OPT_STEREO_32KBPS_V1 + scale_sig32( st->cldfbSynHB->cldfb_state_fx, st->cldfbSynHB->p_filter_length, sub( Q_real, Q11 ) ); // Q10 - > (Q_real-1) +#else /* OPT_STEREO_32KBPS_V1 */ + scale_sig32_r( st->cldfbSynHB->cldfb_state_fx, st->cldfbSynHB->p_filter_length, sub( sub( Q_real, 1 ), Q10 ) ); // (Q_real-1) +#endif /* OPT_STEREO_32KBPS_V1 */ st->cldfbSynHB->Q_cldfb_state = sub( Q_real, 1 ); move16(); +#ifndef MSAN_FIX Scale_sig32( save_hb_synth_fx, L_FRAME48k, sub( Q_real, 1 ) ); // Q_real-1 +#endif FOR( j = 0; j < CLDFB_NO_CHANNELS_MAX; j++ ) { @@ -1942,7 +1987,11 @@ ivas_error acelp_core_dec_ivas_fx( scale_sig32( realBuffer_fx[i], CLDFB_NO_CHANNELS_MAX, Q_real ); // Q_real scale_sig32( imagBuffer_fx[i], CLDFB_NO_CHANNELS_MAX, Q_real ); // Q_real } - scale_sig32_r( st->cldfbSyn->cldfb_state_fx, st->cldfbSyn->p_filter_length, sub( sub( Q_real, 1 ), Q10 ) ); //(Q_real - 1) +#ifdef OPT_STEREO_32KBPS_V1 + scale_sig32( st->cldfbSyn->cldfb_state_fx, st->cldfbSyn->p_filter_length, sub( Q_real, Q11 ) ); // Q10 - > (Q_real-1) +#else /* OPT_STEREO_32KBPS_V1 */ + scale_sig32_r( st->cldfbSyn->cldfb_state_fx, st->cldfbSyn->p_filter_length, sub( sub( Q_real, 1 ), Q10 ) ); //(Q_real - 1) +#endif /* OPT_STEREO_32KBPS_V1 */ st->cldfbSyn->Q_cldfb_state = sub( Q_real, 1 ); move16(); #ifndef MSAN_FIX @@ -1995,7 +2044,11 @@ ivas_error acelp_core_dec_ivas_fx( // Get Q-factor q_bpf_error_signal = Q6; move16(); - Copy_Scale_sig_16_32( bpf_error_signal_16fx, tmp_bpf_error_signal_fx, L_FRAME16k, sub( q_bpf_error_signal, st->Q_syn ) ); // Q6 +#ifdef FIX_ISSUE_1237 + Copy_Scale_sig_16_32_no_sat( bpf_error_signal_16fx, tmp_bpf_error_signal_fx, L_FRAME16k, sub( q_bpf_error_signal, st->Q_syn ) ); // Q6 +#else + Copy_Scale_sig_16_32_DEPREC( bpf_error_signal_16fx, tmp_bpf_error_signal_fx, L_FRAME16k, sub( q_bpf_error_signal, st->Q_syn ) ); // Q6 +#endif FOR( i = 0; i < CLDFB_NO_COL_MAX; i++ ) { Scale_sig32( realBuffer_fx[i], CLDFB_NO_CHANNELS_MAX, -Q7 ); // Q0 @@ -2045,12 +2098,16 @@ ivas_error acelp_core_dec_ivas_fx( scale_sig32( realBuffer_fx[i], CLDFB_NO_CHANNELS_MAX, Q_real ); // Q_real scale_sig32( imagBuffer_fx[i], CLDFB_NO_CHANNELS_MAX, Q_real ); // Q_real } - scale_sig32_r( st->cldfbSyn->cldfb_state_fx, st->cldfbSyn->p_filter_length, sub( sub( Q_real, 1 ), Q10 ) ); //(Q_real - 1) +#ifdef OPT_STEREO_32KBPS_V1 + scale_sig32( st->cldfbSyn->cldfb_state_fx, st->cldfbSyn->p_filter_length, sub( Q_real, Q11 ) ); // Q10 - > (Q_real-1) +#else /* OPT_STEREO_32KBPS_V1 */ + scale_sig32_r( st->cldfbSyn->cldfb_state_fx, st->cldfbSyn->p_filter_length, sub( sub( Q_real, 1 ), Q10 ) ); //(Q_real - 1) +#endif /* OPT_STEREO_32KBPS_V1 */ #ifndef MSAN_FIX Scale_sig32( synth_fx, L_FRAME48k, Q_real - 1 ); #endif - cldfbSynthesis_ivas_fx( realBuffer_fx, imagBuffer_fx, synth_fx /*dummy*/, NS2SA( st->output_Fs, FRAME_SIZE_NS /*DELAY_CLDFB_NS*/ ), st->cldfbSyn ); + cldfbSynthesis_ivas_fx( realBuffer_fx, imagBuffer_fx, synth_fx /*dummy*/, NS2SA_FX2( st->output_Fs, FRAME_SIZE_NS /*DELAY_CLDFB_NS*/ ), st->cldfbSyn ); #ifdef MSAN_FIX Scale_sig32( synth_fx, output_frame, negate( sub( Q_real, 1 ) ) ); // Q0 @@ -2062,7 +2119,7 @@ ivas_error acelp_core_dec_ivas_fx( move16(); IF( st->p_bpf_noise_buf_32 ) { - Copy_Scale_sig_16_32( bpf_error_signal_16fx, bpf_error_signal_fx, st->L_frame, -1 ); // Q_syn-1 + Copy_Scale_sig_16_32_DEPREC( bpf_error_signal_16fx, bpf_error_signal_fx, st->L_frame, -1 ); // Q_syn-1 Copy32( bpf_error_signal_fx, st->p_bpf_noise_buf_32, st->L_frame ); Scale_sig32( st->p_bpf_noise_buf_32, st->L_frame, sub( Q11, sub( st->Q_syn, 1 ) ) ); // Q11 @@ -2108,9 +2165,9 @@ ivas_error acelp_core_dec_ivas_fx( psyn_fx, synth_fx16, st->Q_exc, st->Q_syn2, st->hBWE_zero->delay_syn_hf_fx, &st->hBWE_zero->memExp1, st->hBWE_zero->mem_hp_interp_fx, st->extl, st->CNG_mode ); #ifdef MSAN_FIX - Copy_Scale_sig_16_32( synth_fx16, synth_fx, output_frame, 0 ); + Copy_Scale_sig_16_32_DEPREC( synth_fx16, synth_fx, output_frame, 0 ); #else - Copy_Scale_sig_16_32( synth_fx16, synth_fx, L_FRAME48k, 0 ); + Copy_Scale_sig_16_32_DEPREC( synth_fx16, synth_fx, L_FRAME48k, 0 ); #endif } ELSE @@ -2153,7 +2210,11 @@ ivas_error acelp_core_dec_ivas_fx( test(); IF( !st->ppp_mode_dec && ( st->idchan == 0 || NE_16( st->element_mode, IVAS_CPE_TD ) || ( EQ_16( st->idchan, 1 ) && EQ_16( st->element_mode, IVAS_CPE_TD ) && st->tdm_LRTD_flag ) ) ) { - Copy_Scale_sig_16_32( st->hBWE_TD->old_bwe_exc_extended_fx, bwe_exc_extended_fx, NL_BUFF_OFFSET, ( sub( shl( st->Q_exc, 1 ), sub( st->prev_Q_bwe_exc, 16 ) ) ) ); // prev_Q_bwe_exc +#ifdef FIX_ISSUE_1237 + Copy_Scale_sig_16_32_no_sat( st->hBWE_TD->old_bwe_exc_extended_fx, bwe_exc_extended_fx, NL_BUFF_OFFSET, ( sub( shl( st->Q_exc, 1 ), sub( st->prev_Q_bwe_exc, 16 ) ) ) ); // prev_Q_bwe_exc +#else + Copy_Scale_sig_16_32_DEPREC( st->hBWE_TD->old_bwe_exc_extended_fx, bwe_exc_extended_fx, NL_BUFF_OFFSET, ( sub( shl( st->Q_exc, 1 ), sub( st->prev_Q_bwe_exc, 16 ) ) ) ); // prev_Q_bwe_exc +#endif non_linearity_ivas_fx( bwe_exc_fx, bwe_exc_extended_fx + NL_BUFF_OFFSET, L_FRAME32k, &st->hBWE_TD->bwe_non_lin_prev_scale_fx, st->Q_exc, st->coder_type, voice_factors_fx, st->L_frame ); Copy_Scale_sig_32_16( bwe_exc_extended_fx + L_FRAME32k, st->hBWE_TD->old_bwe_exc_extended_fx, NL_BUFF_OFFSET, negate( sub( shl( st->Q_exc, 1 ), sub( st->prev_Q_bwe_exc, 16 ) ) ) ); // prev_Q_bwe_exc } diff --git a/lib_dec/acelp_core_switch_dec.c b/lib_dec/acelp_core_switch_dec.c deleted file mode 100644 index fd4f3cb7c53af6bc1a4a149c6db6799b8f39655e..0000000000000000000000000000000000000000 --- a/lib_dec/acelp_core_switch_dec.c +++ /dev/null @@ -1,42 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include "cnst.h" -#include "rom_com.h" -#include "prot.h" -#include "wmc_auto.h" diff --git a/lib_dec/acelp_core_switch_dec_fx.c b/lib_dec/acelp_core_switch_dec_fx.c index 8224a74eb5ada3306a55839662d9a103e8038ea7..b2cc593b3d8f632ccaf1b29930f9abff5622399c 100644 --- a/lib_dec/acelp_core_switch_dec_fx.c +++ b/lib_dec/acelp_core_switch_dec_fx.c @@ -7,7 +7,6 @@ #include "cnst.h" /* Common constants */ #include "rom_com.h" /* Static table prototypes */ #include "prot_fx.h" /* Function prototypes */ -#include "prot.h" /* Function prototypes */ /*---------------------------------------------------------------------* * Local function prototypes *---------------------------------------------------------------------*/ @@ -128,7 +127,13 @@ ivas_error acelp_core_switch_dec_fx( /*----------------------------------------------------------------* * Excitation decoding *----------------------------------------------------------------*/ + +#ifdef NONBE_FIX_GSC_BSTR + config_acelp1( DEC, st_fx->total_brate, cbrate, st_fx->core, -1, -1, st_fx->last_L_frame, -1, &( st_fx->acelp_cfg ), st_fx->next_bit_pos, GENERIC, st_fx->inactive_coder_type_flag, -1, -1, &decode_bwe /* dummy */, &i, st_fx->element_mode, &i /*dummy*/, 0, 0, st_fx->idchan, st_fx->active_cnt, 0, 0, 0 ); +#else config_acelp1( DEC, st_fx->total_brate, cbrate, st_fx->core, -1, -1, st_fx->last_L_frame, -1, &( st_fx->acelp_cfg ), st_fx->next_bit_pos, GENERIC, -1, -1, &decode_bwe /* dummy */, &i, st_fx->element_mode, &i /*dummy*/, 0, 0, st_fx->idchan, st_fx->active_cnt, 0, 0, 0 ); +#endif + decod_gen_voic_core_switch_fx( st_fx, L_frame_for_cs, 0, Aq, exc, cbrate, &st_fx->Q_exc ); /*----------------------------------------------------------------* @@ -236,7 +241,7 @@ ivas_error acelp_core_switch_dec_fx( *Q_syn = 0; move16(); - Copy_Scale_sig( synth_intFreq + sub( NS2SA( i_mult( L_frame_for_cs, 50 ), ( SWITCH_GAP_LENGTH_NS - DELAY_CLDFB_NS ) ), 2 ), mem_synth, add( NS2SA( i_mult( L_frame_for_cs, 50 ), DELAY_CLDFB_NS ), 2 ), negate( st_fx->Q_syn ) ); /* Copy mem with Q0 */ + Copy_Scale_sig( synth_intFreq + sub( NS2SA_FX2( i_mult( L_frame_for_cs, 50 ), ( SWITCH_GAP_LENGTH_NS - DELAY_CLDFB_NS ) ), 2 ), mem_synth, add( NS2SA_FX2( i_mult( L_frame_for_cs, 50 ), DELAY_CLDFB_NS ), 2 ), negate( st_fx->Q_syn ) ); /* Copy mem with Q0 */ /*----------------------------------------------------------------* * BWE decoding @@ -332,12 +337,8 @@ ivas_error acelp_core_switch_dec_fx( pt2 = &hb_synth_tmp[tmp]; FOR( i = 0; i < gapsize; i++ ) { -#ifdef BASOP_NOGLOB *pt1++ = round_fx_sat( L_shl_sat( L_mult_sat( ( *pt2++ ), gain ), 2 ) ); move16(); -#else - *pt1++ = round_fx( L_shl( L_mult( ( *pt2++ ), gain ), 2 ) ); -#endif } } ELSE @@ -820,7 +821,11 @@ ivas_error acelp_core_switch_dec_bfi_ivas_fx( *----------------------------------------------------------------*/ /* CLDFB analysis of the synthesis at internal sampling rate */ Qtmp = sub( 11, st_fx->Q_syn ); - Copy_Scale_sig_16_32( syn, syn32, L_FRAME16k, Qtmp ); // Q(11) +#ifdef FIX_ISSUE_1237 + Copy_Scale_sig_16_32_no_sat( syn, syn32, L_FRAME16k, Qtmp ); // Q(11) +#else + Copy_Scale_sig_16_32_DEPREC( syn, syn32, L_FRAME16k, Qtmp ); // Q(11) +#endif IF( NE_32( ( error = cldfb_save_memory_ivas_fx( st_fx->cldfbAna ) ), IVAS_ERR_OK ) ) { return error; @@ -840,9 +845,8 @@ ivas_error acelp_core_switch_dec_bfi_ivas_fx( Scale_sig32( st_fx->cldfbSyn->cldfb_state_fx, st_fx->cldfbSyn->cldfb_state_length, 1 ); // Q_cldfb_state+1 st_fx->cldfbSyn->Q_cldfb_state = add( st_fx->cldfbSyn->Q_cldfb_state, 1 ); move16(); - Copy_Scale_sig_16_32( synth_out, synth32, L_FRAME48k, 5 ); /*11-5-1*/ + Copy_Scale_sig_16_32_DEPREC( synth_out, synth32, L_FRAME48k, 5 ); /*11-5-1*/ - // cldfbSynthesis_ivas_fx(realBuffer, imagBuffer, synth_out, (int16_t)(st_fx->output_Fs * 0.01f), st_fx->cldfbSyn); cldfbSynthesis_ivas_fx( realBuffer, imagBuffer, synth32, extract_l( Mpy_32_16_1( st_fx->output_Fs, 328 ) ), st_fx->cldfbSyn ); Scale_sig32( st_fx->cldfbSyn->cldfb_state_fx, st_fx->cldfbSyn->cldfb_state_length, -1 ); // Q_cldfb_state-1 st_fx->cldfbSyn->Q_cldfb_state = sub( st_fx->cldfbSyn->Q_cldfb_state, 1 ); @@ -973,11 +977,7 @@ static void decod_gen_voic_core_switch_fx( IF( st_fx->prev_bfi ) { /*gain_code = min(gain_code, 0.5f*gain_code+0.5f*st->lp_gainc);*/ -#ifdef BASOP_NOGLOB gain_code16 = s_min( gain_code16, mac_r( L_mult( 16384, gain_code16 ), shl_o( 16384 >> 3, st_fx->Q_exc, &Overflow ), st_fx->lp_gainc_fx ) ); /* st_fx->lp_gainc_fx in Q3 >>3 to bring it to Q0 as gain_code16 */ -#else - gain_code16 = s_min( gain_code16, mac_r( L_mult( 16384, gain_code16 ), shl( 16384 >> 3, st_fx->Q_exc ), st_fx->lp_gainc_fx ) ); /* st_fx->lp_gainc_fx in Q3 >>3 to bring it to Q0 as gain_code16 */ -#endif } FOR( i = 0; i < L_SUBFR; i++ ) diff --git a/lib_dec/amr_wb_dec.c b/lib_dec/amr_wb_dec.c deleted file mode 100644 index d441f6ead49ddcb3a6a1ffab0962633db8157cd0..0000000000000000000000000000000000000000 --- a/lib_dec/amr_wb_dec.c +++ /dev/null @@ -1,43 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include -#include "cnst.h" -#include "rom_com.h" -#include "prot.h" -#include "wmc_auto.h" diff --git a/lib_dec/amr_wb_dec_fx.c b/lib_dec/amr_wb_dec_fx.c index 72ceb6cd3155a6e56df40e72df0c3a6a323f7ded..d45655903fb6f8f427e3d28ea4f7e91cbd2be7a2 100644 --- a/lib_dec/amr_wb_dec_fx.c +++ b/lib_dec/amr_wb_dec_fx.c @@ -1046,11 +1046,7 @@ ivas_error amr_wb_dec_fx( FOR( i = 0; i < tmps; i++ ) { -#ifdef BASOP_NOGLOB synth_out_fx[( i + delay_comp )] = msu_r_sat( L_mult( synth_out_fx[( i + delay_comp )], alpha ), hHQ_core->old_out_fx[( i + nz )], add( alpha, -32768 ) ); -#else - synth_out_fx[i + delay_comp] = msu_r( L_mult( synth_out_fx[i + delay_comp], alpha ), hHQ_core->old_out_fx[i + nz], add( alpha, -32768 ) ); -#endif move16(); alpha = add( alpha, step ); } diff --git a/lib_dec/ari_dec.c b/lib_dec/ari_dec.c deleted file mode 100644 index 8dedcea1e57bfd2eef330c0a2ca1e074f37abb0e..0000000000000000000000000000000000000000 --- a/lib_dec/ari_dec.c +++ /dev/null @@ -1,338 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include -#include "options.h" -#include "cnst.h" -#include "prot.h" -#include "prot_fx.h" -#include "stat_com.h" -#include "basop_util.h" -#include "wmc_auto.h" - - -/*--------------------------------------------------------------- - * Ari decode 14 bits routines - -------------------------------------------------------------*/ - -/*--------------------------------------------------------------- - * ari_start_decoding_14bits_ivas() - * - * Start ArCo decoding - *-------------------------------------------------------------*/ - - -Word16 ari_start_decoding_14bits_prm_ivas_fx( - const Word16 *ptr, - Word16 bp, - Tastat *s ) -{ - Word32 val; - Word16 i; - const Word16 *p; - - val = 0; - move32(); - p = ptr + bp; - - FOR( i = 0; i < cbitsnew; i++ ) - { - val = L_or( L_shl( val, 1 ), *( p + i ) ); - } - s->low = 0; - move32(); - s->high = ari_q4new; - move32(); - s->value = val; - move32(); - - return add( bp, i ); -} - - -Word16 ari_decode_14bits_pow_ivas( - Word16 *ptr, - Word16 bp, - Word16 bits, - Word16 *res, - Tastat *s, - UWord16 base ) -{ - UWord16 symbol; - Word32 low, high; - UWord32 range, value, cum; - Word16 pows[12]; /* "base" to the power of 2, 4, 8,... 2^12 */ - Word16 lowlim, highlim, testval; - Word16 k; - - highlim = 0; - low = s->low; - high = L_add( s->high, 1 ); - value = s->value; - lowlim = 0; - symbol = 0; - move16(); - move32(); - move32(); - move16(); - move16(); - - range = (UWord32) W_sub( high, low ); - move32(); - - /* the value read from bitstream */ - assert( value >= (UWord32) low ); - cum = (UWord32) W_add( W_shl( ( W_sub( value, low ) ), stat_bitsnew ), ( 1 << stat_bitsnew ) - 1 ); - move32(); - - /* search for the interval where "cum" fits */ - IF( GT_64( W_mult0_32_32( L_shr( base, 1 ), range ), cum ) ) /* below pow-1 */ - { - pows[0] = testval = base; - move16(); - move16(); - /* increase exponent until it is smaller than "cum" */ - FOR( k = 1; k < 12; k++ ) - { - highlim = testval; - move16(); - pows[k] = mult_r( pows[k - 1], pows[k - 1] ); - move16(); - testval = mult_r( pows[k], base ); - IF( LE_64( W_mult0_32_32( shr( testval, 1 ), range ), cum ) ) /* found! big range is [lowlim,testval], (now narrow it down) */ - { - lowlim = testval; - move16(); - k = sub( k, 1 ); - symbol = (UWord16) L_shl( 1, k ); - BREAK; - } - } - assert( k < 12 ); /* maximum 2^10-1*/ - /* narrow the range down */ - FOR( k--; k > 0; k-- ) - { - testval = mult_r( highlim, pows[k] ); - IF( LE_64( W_mult0_32_32( shr( testval, 1 ), range ), cum ) ) - { - lowlim = testval; - move16(); - symbol = (UWord16) L_sub( symbol, L_shl( 1, sub( k, 1 ) ) ); - } - ELSE - { - highlim = testval; - move16(); - } - } - highlim = shr( highlim, 1 ); - lowlim = shr( lowlim, 1 ); - } - ELSE /* trivial case, above pow-1, that is, first symbol */ - { - symbol = 0; - lowlim = extract_l( L_shr( base, 1 ) ); - highlim = 16384; - move16(); - move16(); - } - - - high = L_add( low, mul_sbc_14bits( range, highlim ) ); - - low = L_add( low, mul_sbc_14bits( range, lowlim ) ); - - /*ptr init for ptr*/ - FOR( ; bp < bits; ) - { - IF( GT_32( high, ari_q2new ) ) - { - IF( GE_32( low, ari_q2new ) ) - { - value = (UWord32) W_sub( value, ari_q2new ); - low = L_sub( low, ari_q2new ); - high = L_sub( high, ari_q2new ); - } - ELSE - { - test(); - IF( GE_32( low, ari_q1new ) && LE_32( high, ari_q3new ) ) - { - value = (UWord32) W_sub( value, ari_q1new ); - low = L_sub( low, ari_q1new ); - high = L_sub( high, ari_q1new ); - } - ELSE - { - BREAK; - } - } - } - low = L_add( low, low ); - high = L_add( high, high ); - - assert( abs( ptr[bp] ) <= 1 && "AC expects reading binary values!!!" ); - - value = (UWord32) ( W_shl( value, 1 ) | ptr[bp++] ); - } - - test(); - test(); - test(); - IF( !( NE_16( bp, bits ) || !( EQ_32( s->low, low ) && ( EQ_32( s->high, high ) ) && ( EQ_64( s->value, value ) ) ) ) ) - { - /* This should not happen except of bit errors. */ - s->high = s->low = 0; - move32(); - move32(); - *res = 0; - move16(); - return -1; - } - - s->low = low; - s->high = L_sub( high, 1 ); - s->value = value; - move32(); - move32(); - move32(); - - *res = symbol; - move16(); - return bp; -} - -Word16 ari_decode_14bits_sign_ivas( - Word16 *ptr, - Word16 bp, - Word16 bits, - Word16 *res, - Tastat *s ) -{ - Word16 symbol; - Word32 low, high; - UWord32 range, value, cum; - - low = s->low; - high = L_add( s->high, 1 ); - value = s->value; - move32(); - move32(); - - range = (UWord32) W_sub( high, low ); - - IF( LT_16( bp, bits ) ) - { - assert( value >= (UWord32) low ); - cum = (UWord32) W_add( W_shl( ( W_sub( value, low ) ), stat_bitsnew ), ( 1 << stat_bitsnew ) - 1 ); - IF( GT_64( W_shl( range, 13 ), cum ) ) - { - symbol = 2; - move16(); - high = L_add( low, W_extract_l( W_shr( range, 1 ) ) ); - } - ELSE - { - symbol = 1; - move16(); - low = L_add( low, W_extract_l( W_shr( range, 1 ) ) ); - } - - /*ptr init for ptr*/ - FOR( ; bp < bits; ) - { - IF( GT_32( high, ari_q2new ) ) - { - IF( GE_32( low, ari_q2new ) ) - { - value = (UWord32) W_sub( value, ari_q2new ); - low = L_sub( low, ari_q2new ); - high = L_sub( high, ari_q2new ); - } - ELSE - { - test(); - IF( GE_32( low, ari_q1new ) && LE_32( high, ari_q3new ) ) - { - value = (UWord32) W_sub( value, ari_q1new ); - low = L_sub( low, ari_q1new ); - high = L_sub( high, ari_q1new ); - } - ELSE - { - BREAK; - } - } - } - low = L_add( low, low ); - high = L_add( high, high ); - - assert( abs( ptr[bp] ) <= 1 && "AC expects reading binary values!!!" ); - - value = (UWord32) ( W_shl( value, 1 ) | ptr[bp++] ); - } - } - ELSE - { - cum = (UWord32) W_sub( value, low ); - range = (UWord32) W_shr( range, 1 ); - IF( GT_64( range, cum ) ) - { - symbol = 2; - move16(); - high = L_add( low, range ); - } - ELSE - { - symbol = 1; - move16(); - low = L_add( low, range ); - } - } - - s->low = low; - s->high = L_sub( high, 1 ); - s->value = value; - move32(); - move32(); - move32(); - - *res = symbol; - move16(); - - return bp; -} diff --git a/lib_dec/ari_dec_fx.c b/lib_dec/ari_dec_fx.c index 3681568f28f46665132a75fefe5aa2ec05ac5bca..3aabbdaa58cbcdda0a7c83d962eb9297c8a8608f 100644 --- a/lib_dec/ari_dec_fx.c +++ b/lib_dec/ari_dec_fx.c @@ -551,3 +551,291 @@ Word16 ari_decode_14bits_sign_fx( Word16 *ptr, Word16 bp, Word16 bits, Word16 *r { return ari_decode_14bits_notbl_fx( ptr, bp, bits, res, s, 0, ari_lookup_sign_fx ); } + +/*--------------------------------------------------------------- + * ari_start_decoding_14bits_ivas() + * + * Start ArCo decoding + *-------------------------------------------------------------*/ + + +Word16 ari_start_decoding_14bits_prm_ivas_fx( + const Word16 *ptr, + Word16 bp, + Tastat *s ) +{ + Word32 val; + Word16 i; + const Word16 *p; + + val = 0; + move32(); + p = ptr + bp; + + FOR( i = 0; i < cbitsnew; i++ ) + { + val = L_or( L_shl( val, 1 ), *( p + i ) ); + } + s->low = 0; + move32(); + s->high = ari_q4new; + move32(); + s->value = val; + move32(); + + return add( bp, i ); +} + + +Word16 ari_decode_14bits_pow_ivas( + Word16 *ptr, + Word16 bp, + Word16 bits, + Word16 *res, + Tastat *s, + UWord16 base ) +{ + UWord16 symbol; + Word32 low, high; + UWord32 range, value, cum; + Word16 pows[12]; /* "base" to the power of 2, 4, 8,... 2^12 */ + Word16 lowlim, highlim, testval; + Word16 k; + + highlim = 0; + low = s->low; + high = L_add( s->high, 1 ); + value = s->value; + lowlim = 0; + symbol = 0; + move16(); + move32(); + move32(); + move16(); + move16(); + + range = (UWord32) W_sub( high, low ); + move32(); + + /* the value read from bitstream */ + assert( value >= (UWord32) low ); + cum = (UWord32) W_add( W_shl( ( W_sub( value, low ) ), stat_bitsnew ), ( 1 << stat_bitsnew ) - 1 ); + move32(); + + /* search for the interval where "cum" fits */ + IF( GT_64( W_mult0_32_32( L_shr( base, 1 ), range ), cum ) ) /* below pow-1 */ + { + pows[0] = testval = base; + move16(); + move16(); + /* increase exponent until it is smaller than "cum" */ + FOR( k = 1; k < 12; k++ ) + { + highlim = testval; + move16(); + pows[k] = mult_r( pows[k - 1], pows[k - 1] ); + move16(); + testval = mult_r( pows[k], base ); + IF( LE_64( W_mult0_32_32( shr( testval, 1 ), range ), cum ) ) /* found! big range is [lowlim,testval], (now narrow it down) */ + { + lowlim = testval; + move16(); + k = sub( k, 1 ); + symbol = (UWord16) L_shl( 1, k ); + BREAK; + } + } + assert( k < 12 ); /* maximum 2^10-1*/ + /* narrow the range down */ + FOR( k--; k > 0; k-- ) + { + testval = mult_r( highlim, pows[k] ); + IF( LE_64( W_mult0_32_32( shr( testval, 1 ), range ), cum ) ) + { + lowlim = testval; + move16(); + symbol = (UWord16) L_sub( symbol, L_shl( 1, sub( k, 1 ) ) ); + } + ELSE + { + highlim = testval; + move16(); + } + } + highlim = shr( highlim, 1 ); + lowlim = shr( lowlim, 1 ); + } + ELSE /* trivial case, above pow-1, that is, first symbol */ + { + symbol = 0; + lowlim = extract_l( L_shr( base, 1 ) ); + highlim = 16384; + move16(); + move16(); + } + + + high = L_add( low, mul_sbc_14bits( range, highlim ) ); + + low = L_add( low, mul_sbc_14bits( range, lowlim ) ); + + /*ptr init for ptr*/ + FOR( ; bp < bits; ) + { + IF( GT_32( high, ari_q2new ) ) + { + IF( GE_32( low, ari_q2new ) ) + { + value = (UWord32) W_sub( value, ari_q2new ); + low = L_sub( low, ari_q2new ); + high = L_sub( high, ari_q2new ); + } + ELSE + { + test(); + IF( GE_32( low, ari_q1new ) && LE_32( high, ari_q3new ) ) + { + value = (UWord32) W_sub( value, ari_q1new ); + low = L_sub( low, ari_q1new ); + high = L_sub( high, ari_q1new ); + } + ELSE + { + BREAK; + } + } + } + low = L_add( low, low ); + high = L_add( high, high ); + + assert( abs( ptr[bp] ) <= 1 && "AC expects reading binary values!!!" ); + + value = (UWord32) ( W_shl( value, 1 ) | ptr[bp++] ); + } + + test(); + test(); + test(); + IF( !( NE_16( bp, bits ) || !( EQ_32( s->low, low ) && ( EQ_32( s->high, high ) ) && ( EQ_64( s->value, value ) ) ) ) ) + { + /* This should not happen except of bit errors. */ + s->high = s->low = 0; + move32(); + move32(); + *res = 0; + move16(); + return -1; + } + + s->low = low; + s->high = L_sub( high, 1 ); + s->value = value; + move32(); + move32(); + move32(); + + *res = symbol; + move16(); + return bp; +} + +Word16 ari_decode_14bits_sign_ivas( + Word16 *ptr, + Word16 bp, + Word16 bits, + Word16 *res, + Tastat *s ) +{ + Word16 symbol; + Word32 low, high; + UWord32 range, value, cum; + + low = s->low; + high = L_add( s->high, 1 ); + value = s->value; + move32(); + move32(); + + range = (UWord32) W_sub( high, low ); + + IF( LT_16( bp, bits ) ) + { + assert( value >= (UWord32) low ); + cum = (UWord32) W_add( W_shl( ( W_sub( value, low ) ), stat_bitsnew ), ( 1 << stat_bitsnew ) - 1 ); + IF( GT_64( W_shl( range, 13 ), cum ) ) + { + symbol = 2; + move16(); + high = L_add( low, W_extract_l( W_shr( range, 1 ) ) ); + } + ELSE + { + symbol = 1; + move16(); + low = L_add( low, W_extract_l( W_shr( range, 1 ) ) ); + } + + /*ptr init for ptr*/ + FOR( ; bp < bits; ) + { + IF( GT_32( high, ari_q2new ) ) + { + IF( GE_32( low, ari_q2new ) ) + { + value = (UWord32) W_sub( value, ari_q2new ); + low = L_sub( low, ari_q2new ); + high = L_sub( high, ari_q2new ); + } + ELSE + { + test(); + IF( GE_32( low, ari_q1new ) && LE_32( high, ari_q3new ) ) + { + value = (UWord32) W_sub( value, ari_q1new ); + low = L_sub( low, ari_q1new ); + high = L_sub( high, ari_q1new ); + } + ELSE + { + BREAK; + } + } + } + low = L_add( low, low ); + high = L_add( high, high ); + + assert( abs( ptr[bp] ) <= 1 && "AC expects reading binary values!!!" ); + + value = (UWord32) ( W_shl( value, 1 ) | ptr[bp++] ); + } + } + ELSE + { + cum = (UWord32) W_sub( value, low ); + range = (UWord32) W_shr( range, 1 ); + IF( GT_64( range, cum ) ) + { + symbol = 2; + move16(); + high = L_add( low, range ); + } + ELSE + { + symbol = 1; + move16(); + low = L_add( low, range ); + } + } + + s->low = low; + s->high = L_sub( high, 1 ); + s->value = value; + move32(); + move32(); + move32(); + + *res = symbol; + move16(); + + return bp; +} diff --git a/lib_dec/ari_hm_dec.c b/lib_dec/ari_hm_dec.c index f290ca9fbebd7a101484a3e805253924c07a84ef..ef4fb62d5579e0f89500a76227fbe459a7f1719e 100644 --- a/lib_dec/ari_hm_dec.c +++ b/lib_dec/ari_hm_dec.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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,10 +40,9 @@ #include "cnst.h" #include "stl.h" #include "basop_util.h" -#include "prot.h" +#include "prot_fx.h" #include "rom_com.h" #include "wmc_auto.h" -#include "prot_fx.h" Word16 DecodeIndex_fx( diff --git a/lib_dec/arith_coder_dec.c b/lib_dec/arith_coder_dec.c deleted file mode 100644 index a9579d5d212f073c932b6e60606d507285763ecb..0000000000000000000000000000000000000000 --- a/lib_dec/arith_coder_dec.c +++ /dev/null @@ -1,250 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include -#include "options.h" -#include "cnst.h" -#include "prot.h" -#include "rom_com.h" -#include "basop_util.h" -#include "basop_proto_func.h" -#include "wmc_auto.h" -#include "prot_fx.h" - -/*-------------------------------------------------------* - * tcx_arith_decode() - * - * - *-------------------------------------------------------*/ - -/*! r: number of bits consumed */ - -static Word16 tcx_arith_decode_ivas_fx( - const Word16 L_frame, /* i : number of spectral lines */ - const Word16 envelope[], /* i : scaled envelope (Q15-envelope_e) */ - Word16 envelope_e, /* i : scaled envelope exponent (Q0) */ - const Word16 target_bits, /* i : target bit budget */ - Word16 prm[], /* i : bitstream parameters */ - Word32 q_spectrum[], /* o : scalar quantized spectrum (Q31-q_spectrum_e) */ - Word16 *q_spectrum_e /* o : spectrum exponent */ -) -{ - Word16 bp, k, q; - Word16 s; - Tastat as; - UWord16 exp_k; - Word16 tmp; - - bp = ari_start_decoding_14bits_prm_ivas_fx( prm, 0, &as ); - - tmp = sub( envelope_e, 1 ); - - FOR( k = 0; k < L_frame; k++ ) - { - IF( EQ_16( envelope[k], 0 ) ) /* safety check in case of bit errors */ - { - set32_fx( q_spectrum, 0, L_frame ); - return -1; - } - ELSE - { - exp_k = expfp_evs_fx( negate( envelope[k] ), tmp ); - } - - /* decode line magnitude */ - bp = ari_decode_14bits_pow_ivas( prm, bp, target_bits, &q, &as, exp_k ); - - IF( q ) - { - /* line is non-zero, decode sign */ - bp = ari_decode_14bits_sign_ivas( prm, bp, target_bits, &s, &as ); - q_spectrum[k] = L_mult( q, sub( 3, shl( s, 1 ) ) ); - move32(); - q_spectrum[k] = L_shl( q_spectrum[k], 30 - SPEC_EXP_DEC ); // Q(31-20) - move32(); - } - ELSE - { - /* line is zero, no sign needed */ - q_spectrum[k] = 0; - move32(); - } - - IF( LE_32( as.high, as.low ) ) - { - if ( LT_16( bp, target_bits ) ) /* safety check in case of bit errors */ - { - bp = -1; - move16(); - } - BREAK; /* no bits left, so exit loop */ - } - } - *q_spectrum_e = SPEC_EXP_DEC; - move16(); - - set32_fx( q_spectrum + k, 0, sub( L_frame, k ) ); - - return bp; -} - -/*-------------------------------------------------------* - * tcx_arith_decode_envelope() - * - * - *-------------------------------------------------------*/ - -void tcx_arith_decode_envelope_ivas_fx( - Decoder_State *st, /* i/o: coder state */ - Word32 q_spectrum[], /* o : quantised MDCT coefficients Q(31-q_spectrum_e) */ - Word16 *q_spectrum_e, /* o : MDCT exponent */ - const Word16 L_frame, /* i : frame or MDCT length */ - Word16 L_spec, /* i : length w/o BW limitation */ - const Word16 A_ind[], /* i : quantised LPC coefficients */ - const Word16 target_bits, /* i : number of available bits */ - Word16 prm[], /* i : bitstream parameters */ - const Word16 use_hm, /* i : use HM in current frame? */ - const Word16 prm_hm[], /* i : HM parameter area */ - Word16 tcxltp_pitch, /* i : TCX LTP pitch in FD, -1 if n/a*/ - Word16 *arith_bits, /* o : bits used for ari. coding */ - Word16 *signaling_bits, /* o : bits used for signaling */ - const Word16 low_complexity /* i : low-complexity flag */ -) -{ - Word32 env[N_MAX_ARI]; /* unscaled envelope (Q16) */ - Word16 *envelope; /* scaled envelope (Q15-e) */ - Word16 envelope_e; - Word16 L_spec_core; - TCX_CONFIG_HANDLE hTcxCfg; - TCX_DEC_HANDLE hTcxDec; - Word16 gamma_w, gamma_uw; - Word16 hm_bits; - - test(); - test(); - test(); - test(); - test(); - test(); - test(); - IF( GT_16( L_spec, N_MAX_ARI ) || ( ( st->element_mode == EVS_MONO ) && GT_16( target_bits, ( ACELP_13k20 / FRAMES_PER_SEC ) ) ) || - ( EQ_16( st->element_mode, IVAS_SCE ) && ( GT_16( st->bits_frame_nominal, ( LPC_SHAPED_ARI_MAX_RATE / FRAMES_PER_SEC ) ) ) ) || - ( GT_16( st->element_mode, IVAS_SCE ) && ( GT_16( st->bits_frame_nominal, ( LPC_SHAPED_ARI_MAX_RATE_CPE / FRAMES_PER_SEC ) ) ) ) || - ( target_bits <= 0 ) ) - { - /* this could happen in case of bit errors */ - st->BER_detect = 1; - move16(); - L_spec = N_MAX_ARI; - move16(); - *signaling_bits = 0; - move16(); - *arith_bits = 0; - move16(); - set32_fx( q_spectrum, 0, L_frame ); - - return; - } - - hTcxCfg = st->hTcxCfg; - hTcxDec = st->hTcxDec; - *signaling_bits = 0; - move16(); - - assert( hTcxDec->enableTcxLpc ); - gamma_w = MAX16B; - move16(); - gamma_uw = st->inv_gamma; - move16(); - -#define WMC_TOOL_SKIP - tcx_arith_render_envelope_ivas_fx( A_ind, L_frame, L_spec, hTcxCfg->preemph_fac, gamma_w, gamma_uw, env ); -#undef WMC_TOOL_SKIP - - IF( use_hm != 0 ) - { - IF( prm_hm[0] != 0 ) - { - tcx_hm_decode( L_spec, env, target_bits, st->coder_type, prm_hm, tcxltp_pitch, &hm_bits ); - - IF( hm_bits < 0 ) - { - st->BER_detect = 1; - move16(); - *signaling_bits = 0; - move16(); - *arith_bits = 0; - move16(); - set32_fx( q_spectrum, 0, L_frame ); - - return; - } - } - ELSE - { - hm_bits = 1; - move16(); - } - *signaling_bits = add( *signaling_bits, hm_bits ); - move16(); - } - - L_spec_core = L_spec; - move16(); - IF( st->igf ) - { - L_spec_core = s_min( L_spec_core, st->hIGFDec->infoIGFStartLine ); - } - - envelope = (Word16 *) env; - tcx_arith_scale_envelope( L_spec, L_spec_core, env, target_bits, low_complexity, envelope, &envelope_e ); - - *arith_bits = tcx_arith_decode_ivas_fx( L_spec, envelope, envelope_e, target_bits, prm, q_spectrum, q_spectrum_e ); - move16(); - - /* safety check in case of bit errors */ - IF( *arith_bits < 0 ) - { - st->BER_detect = 1; - move16(); - set32_fx( q_spectrum, 0, L_frame ); - } - - set32_fx( q_spectrum + L_spec, 0, sub( L_frame, L_spec ) ); - - return; -} diff --git a/lib_dec/arith_coder_dec_fx.c b/lib_dec/arith_coder_dec_fx.c index 68736867d887d10af7e0c4f1e6e26110e50c1e62..60a59c4da469f113f7195179ed0521d2c343bc2d 100644 --- a/lib_dec/arith_coder_dec_fx.c +++ b/lib_dec/arith_coder_dec_fx.c @@ -8,6 +8,8 @@ #include "cnst.h" #include "rom_com.h" #include "prot_fx.h" +#include "basop_util.h" +#include "basop_proto_func.h" /* Returns: number of bits consumed */ static Word16 tcx_arith_decode_fx( @@ -61,11 +63,7 @@ static Word16 tcx_arith_decode_fx( { bp = ari_decode_14bits_sign_fx( prm, bp, target_bits, &s, &as ); -#ifdef BASOP_NOGLOB L_tmp = L_macNs_co( L_tmp, q, k, &Carry, &Overflow ); -#else - L_tmp = L_macNs( L_tmp, q, k ); -#endif Q = L_mult( q, negate( shl( 1, sub( 30, SPEC_EXP_DEC ) ) ) ); IF( EQ_16( s, 0 ) ) @@ -217,3 +215,207 @@ void tcx_arith_decode_envelope_fx( set32_fx( q_spectrum + L_spec, 0, sub( L_frame, L_spec ) ); } + +/*-------------------------------------------------------* + * tcx_arith_decode() + * + * + *-------------------------------------------------------*/ + +/*! r: number of bits consumed */ + +static Word16 tcx_arith_decode_ivas_fx( + const Word16 L_frame, /* i : number of spectral lines */ + const Word16 envelope[], /* i : scaled envelope (Q15-envelope_e) */ + Word16 envelope_e, /* i : scaled envelope exponent (Q0) */ + const Word16 target_bits, /* i : target bit budget */ + Word16 prm[], /* i : bitstream parameters */ + Word32 q_spectrum[], /* o : scalar quantized spectrum (Q31-q_spectrum_e) */ + Word16 *q_spectrum_e /* o : spectrum exponent */ +) +{ + Word16 bp, k, q; + Word16 s; + Tastat as; + UWord16 exp_k; + Word16 tmp; + + bp = ari_start_decoding_14bits_prm_ivas_fx( prm, 0, &as ); + + tmp = sub( envelope_e, 1 ); + + FOR( k = 0; k < L_frame; k++ ) + { + IF( EQ_16( envelope[k], 0 ) ) /* safety check in case of bit errors */ + { + set32_fx( q_spectrum, 0, L_frame ); + return -1; + } + ELSE + { + exp_k = expfp_evs_fx( negate( envelope[k] ), tmp ); + } + + /* decode line magnitude */ + bp = ari_decode_14bits_pow_ivas( prm, bp, target_bits, &q, &as, exp_k ); + + IF( q ) + { + /* line is non-zero, decode sign */ + bp = ari_decode_14bits_sign_ivas( prm, bp, target_bits, &s, &as ); + q_spectrum[k] = L_mult( q, sub( 3, shl( s, 1 ) ) ); + move32(); + q_spectrum[k] = L_shl( q_spectrum[k], 30 - SPEC_EXP_DEC ); // Q(31-20) + move32(); + } + ELSE + { + /* line is zero, no sign needed */ + q_spectrum[k] = 0; + move32(); + } + + IF( LE_32( as.high, as.low ) ) + { + if ( LT_16( bp, target_bits ) ) /* safety check in case of bit errors */ + { + bp = -1; + move16(); + } + BREAK; /* no bits left, so exit loop */ + } + } + *q_spectrum_e = SPEC_EXP_DEC; + move16(); + + set32_fx( q_spectrum + k, 0, sub( L_frame, k ) ); + + return bp; +} + +/*-------------------------------------------------------* + * tcx_arith_decode_envelope() + * + * + *-------------------------------------------------------*/ + +void tcx_arith_decode_envelope_ivas_fx( + Decoder_State *st, /* i/o: coder state */ + Word32 q_spectrum[], /* o : quantised MDCT coefficients Q(31-q_spectrum_e) */ + Word16 *q_spectrum_e, /* o : MDCT exponent */ + const Word16 L_frame, /* i : frame or MDCT length */ + Word16 L_spec, /* i : length w/o BW limitation */ + const Word16 A_ind[], /* i : quantised LPC coefficients */ + const Word16 target_bits, /* i : number of available bits */ + Word16 prm[], /* i : bitstream parameters */ + const Word16 use_hm, /* i : use HM in current frame? */ + const Word16 prm_hm[], /* i : HM parameter area */ + Word16 tcxltp_pitch, /* i : TCX LTP pitch in FD, -1 if n/a*/ + Word16 *arith_bits, /* o : bits used for ari. coding */ + Word16 *signaling_bits, /* o : bits used for signaling */ + const Word16 low_complexity /* i : low-complexity flag */ +) +{ + Word32 env[N_MAX_ARI]; /* unscaled envelope (Q16) */ + Word16 *envelope; /* scaled envelope (Q15-e) */ + Word16 envelope_e; + Word16 L_spec_core; + TCX_CONFIG_HANDLE hTcxCfg; + TCX_DEC_HANDLE hTcxDec; + Word16 gamma_w, gamma_uw; + Word16 hm_bits; + + test(); + test(); + test(); + test(); + test(); + test(); + test(); + IF( GT_16( L_spec, N_MAX_ARI ) || ( ( st->element_mode == EVS_MONO ) && GT_16( target_bits, ( ACELP_13k20 / FRAMES_PER_SEC ) ) ) || + ( EQ_16( st->element_mode, IVAS_SCE ) && ( GT_16( st->bits_frame_nominal, ( LPC_SHAPED_ARI_MAX_RATE / FRAMES_PER_SEC ) ) ) ) || + ( GT_16( st->element_mode, IVAS_SCE ) && ( GT_16( st->bits_frame_nominal, ( LPC_SHAPED_ARI_MAX_RATE_CPE / FRAMES_PER_SEC ) ) ) ) || + ( target_bits <= 0 ) ) + { + /* this could happen in case of bit errors */ + st->BER_detect = 1; + move16(); + L_spec = N_MAX_ARI; + move16(); + *signaling_bits = 0; + move16(); + *arith_bits = 0; + move16(); + set32_fx( q_spectrum, 0, L_frame ); + + return; + } + + hTcxCfg = st->hTcxCfg; + hTcxDec = st->hTcxDec; + *signaling_bits = 0; + move16(); + + assert( hTcxDec->enableTcxLpc ); + gamma_w = MAX16B; + move16(); + gamma_uw = st->inv_gamma; + move16(); + +#define WMC_TOOL_SKIP + tcx_arith_render_envelope_ivas_fx( A_ind, L_frame, L_spec, hTcxCfg->preemph_fac, gamma_w, gamma_uw, env ); +#undef WMC_TOOL_SKIP + + IF( use_hm != 0 ) + { + IF( prm_hm[0] != 0 ) + { + tcx_hm_decode( L_spec, env, target_bits, st->coder_type, prm_hm, tcxltp_pitch, &hm_bits ); + + IF( hm_bits < 0 ) + { + st->BER_detect = 1; + move16(); + *signaling_bits = 0; + move16(); + *arith_bits = 0; + move16(); + set32_fx( q_spectrum, 0, L_frame ); + + return; + } + } + ELSE + { + hm_bits = 1; + move16(); + } + *signaling_bits = add( *signaling_bits, hm_bits ); + move16(); + } + + L_spec_core = L_spec; + move16(); + IF( st->igf ) + { + L_spec_core = s_min( L_spec_core, st->hIGFDec->infoIGFStartLine ); + } + + envelope = (Word16 *) env; + tcx_arith_scale_envelope( L_spec, L_spec_core, env, target_bits, low_complexity, envelope, &envelope_e ); + + *arith_bits = tcx_arith_decode_ivas_fx( L_spec, envelope, envelope_e, target_bits, prm, q_spectrum, q_spectrum_e ); + move16(); + + /* safety check in case of bit errors */ + IF( *arith_bits < 0 ) + { + st->BER_detect = 1; + move16(); + set32_fx( q_spectrum, 0, L_frame ); + } + + set32_fx( q_spectrum + L_spec, 0, sub( L_frame, L_spec ) ); + + return; +} diff --git a/lib_dec/avq_dec.c b/lib_dec/avq_dec.c deleted file mode 100644 index 27bb2c3245453c4ea715bf395c5e448974151ac4..0000000000000000000000000000000000000000 --- a/lib_dec/avq_dec.c +++ /dev/null @@ -1,42 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include "prot.h" -#include "cnst.h" -#include "wmc_auto.h" -#include diff --git a/lib_dec/avq_dec_fx.c b/lib_dec/avq_dec_fx.c index a13678a97124b2c8af8361358a98b4035db7c57a..a8ba2bfc3612253b30e153d2cb22f863afe3d4a4 100644 --- a/lib_dec/avq_dec_fx.c +++ b/lib_dec/avq_dec_fx.c @@ -7,7 +7,6 @@ #include "options.h" /* Compilation switches */ #include "cnst.h" /* Common constants */ #include "rom_com.h" /* Static table prototypes */ -#include "prot.h" /* Function prototypes */ #include "prot_fx.h" /* Function prototypes */ /*-------------------------------------------------------------------* @@ -184,7 +183,7 @@ void AVQ_demuxdec_fx( move16(); FOR( j = i; j < Nsv - 1; j++ ) { - if ( ( nq[svOrder[j]] == 0 ) ) + if ( nq[svOrder[j]] == 0 ) { nullVec = add( nullVec, 1 ); } @@ -271,12 +270,7 @@ void AVQ_demuxdec_fx( /*Compute AVQ code book number from unused Bits */ tmp = (Word16) ( sub( bits, add( add( shl( add( unusedbitsFlag, unused_bits_idx ), 2 ), unusedbitsFlag ), unused_bits_idx ) ) ); nq_est = idiv1616( tmp, 5 ); - IF( ( ( tmp % 5 ) == 0 ) ) - { - nq_est = nq_est; - move16(); - } - ELSE + IF( ( ( tmp % 5 ) != 0 ) ) { nq_est = add( nq_est, 1 ); } diff --git a/lib_dec/bass_psfilter.c b/lib_dec/bass_psfilter.c deleted file mode 100644 index a33149fffd514053b3f9107efd778fc3887489e6..0000000000000000000000000000000000000000 --- a/lib_dec/bass_psfilter.c +++ /dev/null @@ -1,317 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include -#include "prot.h" -#include "prot_fx.h" -#include "ivas_prot.h" -#include "cnst.h" -#include "stat_dec.h" -#include "rom_com.h" -#include -#include "wmc_auto.h" -#include "ivas_prot_fx.h" - -/*---------------------------------------------------------------------* - * Local constants - *---------------------------------------------------------------------*/ - - -#define NBPSF_L_EXTRA 120 -#define BPF_STOP_STOPBAND_16 16 -#define K_PC_DEC_FX -1170 /* -0.0357f in Q15 */ -#define K_PC_DEC_FX32 -76665166 /* -0.0357f in Q31 */ -#define C_PC_DEC_FX 6583 /*in Q8*/ - -/*---------------------------------------------------------------------* - * Local function prototypes - *---------------------------------------------------------------------*/ - -/*---------------------------------------------------------------------* - * bass_psfilter() - * - * Perform low-frequency postfiltering - *---------------------------------------------------------------------*/ - -/*---------------------------------------------------------------------* - * Pit_track() - * - * Perform pitch tracking and test pitch/2 to avoid continuous pitch doubling - *---------------------------------------------------------------------*/ - -/*! r: Pitch */ - - -/*---------------------------------------------------------------------* - * addBassPostFilter() - * - * Add BPF component in cldfb domain - *---------------------------------------------------------------------*/ - - -void addBassPostFilter_ivas_fx( - const Word32 *harm_timeIn_fx, // Qx - const Word16 samplesToProcess, - Word32 **rAnalysis_fx, // Qx - 5 - Word32 **iAnalysis_fx, // Qx - 5 - HANDLE_CLDFB_FILTER_BANK cldfb ) -{ - Word32 *tmp_R_fx[CLDFB_NO_COL_MAX]; - Word32 *tmp_I_fx[CLDFB_NO_COL_MAX]; - Word32 cldfbBufferReal_fx[CLDFB_NO_COL_MAX][20]; - Word32 cldfbBufferImag_fx[CLDFB_NO_COL_MAX][20]; - Word16 i, b; - Word16 maxBand; - const Word32 *weights_fx; - Word16 nCol = cldfb->no_col; - move16(); - Word16 nColToProcess = nCol; - move16(); - Word16 nChan = cldfb->no_channels; - move16(); - IF( GT_16( samplesToProcess, -1 ) ) - { - nColToProcess = idiv1616( sub( add( samplesToProcess, cldfb->no_channels ), 1 ), cldfb->no_channels ); - move16(); - } - - assert( nCol == 16 ); - - weights_fx = bpf_weights_16_ivas_fx_32; - - IF( GT_16( nChan, BPF_STOP_STOPBAND_16 ) ) - { - maxBand = BPF_STOP_STOPBAND_16; - move16(); - } - ELSE - { - maxBand = nChan; - move16(); - } - - FOR( i = 0; i < nColToProcess; i++ ) - { - tmp_R_fx[i] = cldfbBufferReal_fx[i]; - tmp_I_fx[i] = cldfbBufferImag_fx[i]; - } - - cldfbAnalysis_ivas_fx( harm_timeIn_fx, tmp_R_fx, tmp_I_fx, samplesToProcess, cldfb ); - - /* now do the subtraction */ - FOR( i = 0; i < nColToProcess; i++ ) - { - /* loop over low frequency bands */ - FOR( b = 0; b < maxBand; b++ ) - { - rAnalysis_fx[i][b] = Msub_32_32( rAnalysis_fx[i][b], tmp_R_fx[i][b], weights_fx[b] ); // Qx - 6 - move32(); - iAnalysis_fx[i][b] = Msub_32_32( iAnalysis_fx[i][b], tmp_I_fx[i][b], weights_fx[b] ); // Qx - 6 - move32(); - } - } - - return; -} - - -/*---------------------------------------------------------------------* - * res_bpf_adapt_ivas_fx() - * - * Analyze BPF output and decide if it should be applied on DFT stereo - * residual signal - *---------------------------------------------------------------------*/ - -/*! r: Decision to enable or disable BPF on DFT stereo residual */ -Word16 res_bpf_adapt_ivas_fx( - STEREO_DFT_DEC_DATA_HANDLE hStereoDft, /* i/o: DFT stereo decoder handle */ - const Word32 *bpf_error_signal_8k, /* i : BPF modification signal */ - Word32 res_buf[STEREO_DFT_N_8k], /* i : residual buffer Q12 */ - Word16 q_res ) -{ - Word32 error_nrg; - Word32 tmp; - Word32 res_hb_nrg; - Word16 bpf_error_ratio; - Word16 res_bpf_flag; - Word16 i; - Word16 i_start; - Word16 i_end; - Word16 bw_inv; - Word64 W_tmp; - - IF( EQ_16( hStereoDft->res_cod_band_max, 6 ) ) - { - i_start = 39; - move16(); - i_end = 64; - move16(); - bw_inv = 1311; - move16(); /* 1/(64 - 39) in Q15 */ - } - ELSE - { - i_start = 28; - move16(); - i_end = 40; - move16(); - bw_inv = 2720; - move16(); /* 1/(40 - 28) in Q15*/ - } - - /* Measure energy of high frequency band in MDCT domain */ - res_hb_nrg = L_deposit_l( 0 ); - W_tmp = W_deposit32_l( 0 ); - FOR( i = i_start; i < i_end; i++ ) - { - W_tmp = W_add_nosat( W_tmp, W_mult0_32_32( res_buf[i], res_buf[i] ) ); - } - - res_hb_nrg = W_extract_l( W_shr( W_tmp, shl( q_res, 1 ) ) ); // Q0 - res_hb_nrg = Mpy_32_16_1( res_hb_nrg, bw_inv ); // Q0 - res_hb_nrg = L_add( Mpy_32_16_1( res_hb_nrg, STEREO_DFT_BPF_ADAPT_ALPHA_FX ), Mpy_32_16_1( hStereoDft->res_hb_nrg_mem_fx, sub( MAX_16, STEREO_DFT_BPF_ADAPT_ALPHA_FX ) ) ); - hStereoDft->res_hb_nrg_mem_fx = res_hb_nrg; - move32(); - - /* Measure energy of discontinuities at subframe boundaries */ - error_nrg = 0; - move32(); - FOR( i = 0; i < L_FRAME8k; i += STEREO_DFT_L_SUBFR_8k ) - { - tmp = L_sub( bpf_error_signal_8k[i], hStereoDft->bpf_error_signal_last_fx ); - error_nrg = Madd_32_32( error_nrg, tmp, tmp ); - hStereoDft->bpf_error_signal_last_fx = bpf_error_signal_8k[( i + ( STEREO_DFT_L_SUBFR_8k - 1 ) )]; - move32(); - } - error_nrg = L_shl( error_nrg, 1 ); // Q0 - error_nrg = Mpy_32_16_1( error_nrg, 6553 /* 0.2f in Q15 */ ); /* Division by 5 for average value */ - /* Form decision variable and apply limit */ - IF( LT_32( ( L_shr( error_nrg, 1 ) ), res_hb_nrg ) ) - { - Word16 temp; - bpf_error_ratio = BASOP_Util_Divide3232_Scale( error_nrg, res_hb_nrg, &temp ); - bpf_error_ratio = shl( bpf_error_ratio, sub( 13, sub( 15, temp ) ) ); - } - ELSE - { - bpf_error_ratio = ONE_IN_Q14; // Q13 - move16(); - } - bpf_error_ratio = add( mult( STEREO_DFT_BPF_ADAPT_BETA_FX, bpf_error_ratio ), mult( ( MAX_16 - STEREO_DFT_BPF_ADAPT_BETA_FX ), hStereoDft->bpf_error_ratio_mem_fx ) ); - hStereoDft->bpf_error_ratio_mem_fx = bpf_error_ratio; - move16(); - - res_bpf_flag = (Word16) LT_16( bpf_error_ratio, ONE_IN_Q13 ); - move16(); - - return res_bpf_flag; -} - -void bpf_pitch_coherence_ivas_fx( - Decoder_State *st, /* i/o: decoder state structure */ - const Word32 pitch_buf[] /* i : pitch for every subfr [0,1,2,3] Q20 */ -) -{ - Word16 nb_subfr; - Word32 pc, pcn1, pcn2, pcn3; - Word32 scaled_inv_L_frame; // Q8 + Q23 - - SWITCH( st->L_frame ) - { - case 80: - scaled_inv_L_frame = 26843545; // 1/80 in Q31 - move32(); - BREAK; - case 160: - scaled_inv_L_frame = 13421773; // 1/160 in Q31 - move32(); - BREAK; - case 256: - scaled_inv_L_frame = 8388608; // 1/256 in Q31 - move32(); - BREAK; - case 320: - scaled_inv_L_frame = 6710886; // 1/320 in Q31 - move32(); - BREAK; - case 512: - scaled_inv_L_frame = 4194304; // 1/512 in Q31 - move32(); - BREAK; - case 640: - scaled_inv_L_frame = 3355443; // 1/640 in Q31 - move32(); - BREAK; - case 960: - scaled_inv_L_frame = 2236962; // 1/80 in Q31 - move32(); - BREAK; - default: - scaled_inv_L_frame = 0; - move32(); - } - - nb_subfr = shr( st->L_frame, 6 ); - test(); - IF( GT_16( st->clas_dec, UNVOICED_CLAS ) && ( st->element_mode != EVS_MONO ) ) - { - pc = L_abs( L_sub( L_add( st->old_pitch_buf_fx[nb_subfr + 3], st->old_pitch_buf_fx[nb_subfr + 2] ), L_add( st->old_pitch_buf_fx[nb_subfr], st->old_pitch_buf_fx[nb_subfr + 1] ) ) ); - pc = Mpy_32_32( pc, scaled_inv_L_frame ); - pcn1 = L_add( Mpy_32_32( pc, K_PC_DEC_FX32 ), C_PC_DEC_FX ); - pcn1 = L_max( L_min( pcn1, 4096 ), 0 ); // 4096 = 1 in Q12 - - pc = L_abs( L_sub( L_add( pitch_buf[nb_subfr - 1], pitch_buf[nb_subfr - 2] ), L_add( pitch_buf[1], pitch_buf[0] ) ) ); - pc = Mpy_32_32( pc, scaled_inv_L_frame ); - pcn2 = L_add( Mpy_32_32( pc, K_PC_DEC_FX32 ), C_PC_DEC_FX ); - pcn2 = L_max( L_min( pcn2, 4096 ), 0 ); // 4096 = 1 in Q12 - - pc = L_abs( L_sub( L_add( st->old_pitch_buf_fx[nb_subfr + 3], st->old_pitch_buf_fx[nb_subfr + 2] ), L_add( pitch_buf[1], pitch_buf[0] ) ) ); - pc = Mpy_32_32( pc, scaled_inv_L_frame ); - pcn3 = L_add( Mpy_32_32( pc, K_PC_DEC_FX32 ), C_PC_DEC_FX ); - pcn3 = L_max( L_min( pcn3, 4096 ), 0 ); // 4096 = 1 in Q12 - - IF( LT_32( L_add( pcn1, L_add( pcn2, pcn3 ) ), 10240 /*2.5f in Q12*/ ) ) - { - st->hBPF->psf_att_fx = 13107; //.4 in Q15 - move16(); /*Q15*/ - set16_fx( &st->hBPF->Track_on_hist[L_TRACK_HIST - nb_subfr], 1, nb_subfr ); - } - } - - return; -} diff --git a/lib_dec/bass_psfilter_fx.c b/lib_dec/bass_psfilter_fx.c index 0f290fc8f5dd770c37bab21d27fd2440614ed8ce..75cabf160042c12159d477ea02f447c97ef37456 100644 --- a/lib_dec/bass_psfilter_fx.c +++ b/lib_dec/bass_psfilter_fx.c @@ -4,11 +4,12 @@ #include #include -#include "options.h" /* Compilation switches */ -#include "prot_fx.h" /* Function prototypes */ -#include "cnst.h" /* Common constants */ -#include "rom_com.h" /* Static table prototypes */ -#include "rom_dec.h" /* Static table prototypes */ +#include "options.h" /* Compilation switches */ +#include "prot_fx.h" /* Function prototypes */ +#include "ivas_prot_fx.h" /* Function prototypes */ +#include "cnst.h" /* Common constants */ +#include "rom_com.h" /* Static table prototypes */ +#include "rom_dec.h" /* Static table prototypes */ #include "basop_util.h" /*---------------------------------------------------------------------* @@ -17,6 +18,9 @@ #define NBPSF_L_EXTRA 120 #define BPF_STOP_STOPBAND_16 16 +#define K_PC_DEC_FX -1170 /* -0.0357f in Q15 */ +#define K_PC_DEC_FX32 -76665166 /* -0.0357f in Q31 */ +#define C_PC_DEC_FX 6583 /*in Q8*/ /*---------------------------------------------------------------------* * Local function prototypes @@ -192,12 +196,8 @@ void bass_psfilter_fx( } tmp = sum16_fx( hBPF->Track_on_hist, L_TRACK_HIST ); -#ifdef BASOP_NOGLOB TrackOnR = round_fx_sat( L_shl_sat( L_mult0( tmp, 3277 ), 16 ) ); /*Q15 */ -#else - TrackOnR = round_fx( L_shl( L_mult0( tmp, 3277 ), 16 ) ); /*Q15 */ -#endif - vibratR = sum16_fx( hBPF->vibrato_hist, L_TRACK_HIST ); /*Q0 */ + vibratR = sum16_fx( hBPF->vibrato_hist, L_TRACK_HIST ); /*Q0 */ alp_tmp = sub( 32767, TrackOnR ); /*Q15 */ @@ -328,21 +328,13 @@ void bass_psfilter_fx( because it is a signed sum. */ FOR( j = 0; j < subfr_len; j += 2 ) { - Lcorr0 = L_mult0( syn_fx[j], syn2_fx[j] ); /* Q31 */ - Lener0 = L_mult0( syn2_fx[j], syn2_fx[j] ); /* Q31 */ -#ifdef BASOP_NOGLOB + Lcorr0 = L_mult0( syn_fx[j], syn2_fx[j] ); /* Q31 */ + Lener0 = L_mult0( syn2_fx[j], syn2_fx[j] ); /* Q31 */ Lcorr0 = L_mac0_sat( Lcorr0, syn_fx[j + 1], syn2_fx[j + 1] ); /* Q31 */ Lener0 = L_mac0_sat( Lener0, syn2_fx[j + 1], syn2_fx[j + 1] ); /* Q31 */ Lcorr = L_add_sat( Lcorr, L_shr( Lcorr0, 4 ) ); Lener = L_add_sat( Lener, L_shr( Lener0, 4 ) ); -#else - Lcorr0 = L_mac0( Lcorr0, syn_fx[j + 1], syn2_fx[j + 1] ); - Lener0 = L_mac0( Lener0, syn2_fx[j + 1], syn2_fx[j + 1] ); - - Lcorr = L_add( Lcorr, L_shr( Lcorr0, 4 ) ); - Lener = L_add( Lener, L_shr( Lener0, 4 ) ); -#endif /* this loop is not efficient but it provide a respectable precision while avoiding overflow. */ } @@ -354,24 +346,16 @@ void bass_psfilter_fx( Ltmp = L_abs( Lcorr ); exp = norm_l( Ltmp ); -#ifdef BASOP_NOGLOB tmp = round_fx_sat( L_shl_sat( Ltmp, exp ) ); -#else - tmp = round_fx( L_shl( Ltmp, exp ) ); -#endif exp2 = norm_l( Lener ); -#ifdef BASOP_NOGLOB tmp2 = round_fx_sat( L_shl( Lener, exp2 ) ); -#else - tmp2 = round_fx( L_shl( Lener, exp2 ) ); -#endif if ( GT_16( tmp, tmp2 ) ) { exp = sub( exp, 1 ); } exp2 = sub( exp, exp2 ); /* exponent num - exponent denom */ /* gain = corr / ener */ - gain = div_s( round_fx( L_shl( Ltmp, exp ) ), tmp2 ); + gain = div_s( round_fx_sat( L_shl( Ltmp, exp ) ), tmp2 ); if ( Lcorr < 0 ) { gain = sub( 0, gain ); @@ -381,11 +365,7 @@ void bass_psfilter_fx( FOR( i = 0; i < subfr_len; i++ ) { /* err[i] = syn_fx[i] - gain*syn2_fx[i] */ -#ifdef BASOP_NOGLOB err[i] = msu_r_sat( L_shr_sat( L_mult0( gain, syn2_fx[i] ), exp2 ), syn_fx[i], 16384 ); /* Q15 */ -#else - err[i] = msu_r( L_shr( L_mult0( gain, syn2_fx[i] ), exp2 ), syn_fx[i], 16384 ); -#endif move16(); /* the sign is inverted but it is not important because we calculate energy with 'err[i]' x 'err[i]' @@ -404,28 +384,16 @@ void bass_psfilter_fx( tmp2 = sub( tmp2, 1 + 4 ); /* substract 1 because 'Lener' is divided by two */ tmp2 = add( tmp2, Q_syn2x ); tmp2 = s_max( 0, s_min( 30, tmp2 ) ); -#ifdef BASOP_NOGLOB Lener = L_add_sat( Lener, Pow2( tmp2, exp2 ) ); -#else - Lener = L_add( Lener, Pow2( tmp2, exp2 ) ); -#endif exp2 = norm_l( Lener ); -#ifdef BASOP_NOGLOB tmp2 = round_fx_sat( L_shl( Lener, exp2 ) ); -#else - tmp2 = round_fx( L_shl( Lener, exp2 ) ); -#endif if ( GT_16( tmp, tmp2 ) ) { exp = sub( exp, 1 ); } - exp2 = sub( exp, exp2 ); /* exponent num - exponent denom */ - /* alpha = corr / ener */ -#ifdef BASOP_NOGLOB + exp2 = sub( exp, exp2 ); /* exponent num - exponent denom */ + /* alpha = corr / ener */ alpha = shr_sat( div_s( round_fx_sat( L_shl_sat( Ltmp, exp ) ), tmp2 ), exp2 ); /*Q15 */ -#else - alpha = shr( div_s( round_fx( L_shl( Ltmp, exp ) ), tmp2 ), exp2 ); /*Q15 */ -#endif if ( Lcorr < 0 ) { alpha = sub( 0, alpha ); @@ -471,13 +439,8 @@ void bass_psfilter_fx( FOR( i = 0; i < subfr_len; i++ ) { /*syn2_fx[i] = alpha*(syn_fx[i]-syn2_fx[i]); */ -#ifdef BASOP_NOGLOB tmp = sub_sat( syn_fx[i], syn2_fx[i] ); syn2_fx[i] = mult_sat( alpha, shl_sat( tmp, 1 ) ); -#else - tmp = sub( syn_fx[i], syn2_fx[i] ); - syn2_fx[i] = mult( alpha, shl( tmp, 1 ) ); -#endif move16(); /*Q_syn2 */ } @@ -490,11 +453,7 @@ void bass_psfilter_fx( This sum is divided by 4 */ FOR( i = 0; i < subfr_len; i++ ) { -#ifdef BASOP_NOGLOB Lener = L_mac0_sat( Lener, err[i], err[i] ); /* Q31 */ -#else - Lener = L_mac0( Lener, err[i], err[i] ); -#endif } exp2 = -1 - 2; move16(); @@ -506,11 +465,7 @@ void bass_psfilter_fx( FOR( i = 0; i < shr( subfr_len, 1 ); i++ ) { Lener0 = L_mult0( sigPtr[i], sigPtr[i] ); /* Q31 */ -#ifdef BASOP_NOGLOB Lener = L_add( Lener, L_shr( L_mac0_sat( Lener0, err[i], err[i] ), 5 ) ); -#else - Lener = L_add( Lener, L_shr( L_mac0( Lener0, err[i], err[i] ), 5 ) ); -#endif } exp2 = sub( exp2, 5 ); } @@ -563,21 +518,13 @@ void bass_psfilter_fx( sigPtr1 = syn2_fx + 1; FOR( j = 0; j < subfr_len; j += 2 ) { - Lcorr0 = L_mult0( syn_fx[j], syn2_fx[j] ); /* Q31 */ - Lener0 = L_mult0( syn2_fx[j], syn2_fx[j] ); /* Q31 */ -#ifdef BASOP_NOGLOB + Lcorr0 = L_mult0( syn_fx[j], syn2_fx[j] ); /* Q31 */ + Lener0 = L_mult0( syn2_fx[j], syn2_fx[j] ); /* Q31 */ Lcorr0 = L_mac0_sat( Lcorr0, sigPtr[j], sigPtr1[j] ); /* Q31 */ Lener0 = L_mac0_sat( Lener0, sigPtr1[j], sigPtr1[j] ); /* Q31 */ Lcorr = L_add_sat( Lcorr, L_shr( Lcorr0, 4 ) ); Lener = L_add_sat( Lener, L_shr( Lener0, 4 ) ); -#else - Lcorr0 = L_mac0( Lcorr0, sigPtr[j], sigPtr1[j] ); - Lener0 = L_mac0( Lener0, sigPtr1[j], sigPtr1[j] ); - - Lcorr = L_add( Lcorr, L_shr( Lcorr0, 4 ) ); - Lener = L_add( Lener, L_shr( Lener0, 4 ) ); -#endif /* this loop is not efficient but it provide a respectable precision while avoiding overflow. */ } @@ -589,15 +536,9 @@ void bass_psfilter_fx( Ltmp = L_abs( Lcorr ); exp = norm_l( Ltmp ); -#ifdef BASOP_NOGLOB tmp = round_fx_sat( L_shl_sat( Ltmp, exp ) ); exp2 = norm_l( Lener ); tmp2 = round_fx_sat( L_shl_sat( Lener, exp2 ) ); -#else - tmp = round_fx( L_shl( Ltmp, exp ) ); - exp2 = norm_l( Lener ); - tmp2 = round_fx( L_shl( Lener, exp2 ) ); -#endif if ( GT_16( tmp, tmp2 ) ) { exp = sub( exp, 1 ); @@ -633,17 +574,9 @@ void bass_psfilter_fx( tmp2 = sub( tmp2, 1 + 4 ); /* substract 1 because 'Lener' is divided by two */ tmp2 = add( tmp2, Q_syn2x ); tmp2 = s_max( 0, s_min( 30, tmp2 ) ); -#ifdef BASOP_NOGLOB Lener = L_add_sat( Lener, Pow2( tmp2, exp2 ) ); -#else - Lener = L_add( Lener, Pow2( tmp2, exp2 ) ); -#endif exp2 = norm_l( Lener ); -#ifdef BASOP_NOGLOB tmp2 = round_fx_sat( L_shl( Lener, exp2 ) ); -#else - tmp2 = round_fx( L_shl( Lener, exp2 ) ); -#endif if ( GT_16( tmp, tmp2 ) ) { exp = sub( exp, 1 ); @@ -675,11 +608,7 @@ void bass_psfilter_fx( This sum is divided by 4 */ FOR( i = 0; i < subfr_len; i++ ) { -#ifdef BASOP_NOGLOB Lener = L_mac0_sat( Lener, err[i], err[i] ); /* Q31 */ -#else - Lener = L_mac0( Lener, err[i], err[i] ); -#endif } exp2 = -1 - 2; move16(); @@ -691,11 +620,7 @@ void bass_psfilter_fx( FOR( i = 0; i < subfr_len / 2; i++ ) { Lener0 = L_mult0( sigPtr[i], sigPtr[i] ); /* Q31 */ -#ifdef BASOP_NOGLOB Lener = L_add_sat( Lener, L_shr( L_mac0_sat( Lener0, err[i], err[i] ), 5 ) ); -#else - Lener = L_add( Lener, L_shr( L_mac0( Lener0, err[i], err[i] ), 5 ) ); -#endif } exp2 = sub( exp2, 5 ); } @@ -798,15 +723,9 @@ static Word16 Pit_track_fx( /* o : Pitch */ Lcorr0 = L_mult0( *v1++, *v2++ ); /* Q31 */ FOR( i = 1; i < ( ( L_HALFR16k + NBPSF_L_EXTRA ) / 14 ); i++ ) { -#ifdef BASOP_NOGLOB Lener0 = L_mac0_sat( Lener0, *v1, *v1 ); /* Q31 */ Ltmp0 = L_mac0_sat( Ltmp0, *v2, *v2 ); /* Q31 */ Lcorr0 = L_mac0_sat( Lcorr0, *v1++, *v2++ ); /* Q31 */ -#else - Lener0 = L_mac0( Lener0, *v1, *v1 ); - Ltmp0 = L_mac0( Ltmp0, *v2, *v2 ); - Lcorr0 = L_mac0( Lcorr0, *v1++, *v2++ ); -#endif } BASOP_SATURATE_WARNING_ON_EVS test(); @@ -846,11 +765,7 @@ static Word16 Pit_track_fx( /* o : Pitch */ exp1 = norm_l( Lener ); exp2 = norm_l( Ltmp ); /* Multiply the Most Significant 16 bits */ -#ifdef BASOP_NOGLOB Ltmp = L_mult0( round_fx_sat( L_shl_sat( Lener, exp1 ) ), round_fx_sat( L_shl_sat( Ltmp, exp2 ) ) ); /* Q31 */ -#else - Ltmp = L_mult0( round_fx( L_shl( Lener, exp1 ) ), round_fx( L_shl( Ltmp, exp2 ) ) ); -#endif exp1 = add( exp1, exp2 ); /* Correct if Odd # of Shifts */ exp2 = s_and( exp1, 1 ); @@ -868,11 +783,7 @@ static Word16 Pit_track_fx( /* o : Pitch */ exp1 = sub( exp1, exp2 ); Ltmp = Mpy_32_16_1( Lcorr, round_fx( Ltmp ) ); /* Go to Q31 */ -#ifdef BASOP_NOGLOB Ltmp = L_shl_sat( Ltmp, exp1 ); -#else - Ltmp = L_shl( Ltmp, exp1 ); -#endif /* cn = normalized correlation of pitch/2 */ if ( GT_32( Ltmp, 2040109466L ) ) /* 0.95f in Q31 */ { @@ -982,6 +893,246 @@ void addBassPostFilter_fx( return; } +/*---------------------------------------------------------------------* + * addBassPostFilter() + * + * Add BPF component in cldfb domain + *---------------------------------------------------------------------*/ + + +void addBassPostFilter_ivas_fx( + const Word32 *harm_timeIn_fx, // Qx + const Word16 samplesToProcess, + Word32 **rAnalysis_fx, // Qx - 5 + Word32 **iAnalysis_fx, // Qx - 5 + HANDLE_CLDFB_FILTER_BANK cldfb ) +{ + Word32 *tmp_R_fx[CLDFB_NO_COL_MAX]; + Word32 *tmp_I_fx[CLDFB_NO_COL_MAX]; + Word32 cldfbBufferReal_fx[CLDFB_NO_COL_MAX][20]; + Word32 cldfbBufferImag_fx[CLDFB_NO_COL_MAX][20]; + Word16 i, b; + Word16 maxBand; + const Word32 *weights_fx; + Word16 nCol = cldfb->no_col; + move16(); + Word16 nColToProcess = nCol; + move16(); + Word16 nChan = cldfb->no_channels; + move16(); + IF( GT_16( samplesToProcess, -1 ) ) + { + nColToProcess = idiv1616( sub( add( samplesToProcess, cldfb->no_channels ), 1 ), cldfb->no_channels ); + move16(); + } + + assert( nCol == 16 ); + + weights_fx = bpf_weights_16_ivas_fx_32; + + IF( GT_16( nChan, BPF_STOP_STOPBAND_16 ) ) + { + maxBand = BPF_STOP_STOPBAND_16; + move16(); + } + ELSE + { + maxBand = nChan; + move16(); + } + + FOR( i = 0; i < nColToProcess; i++ ) + { + tmp_R_fx[i] = cldfbBufferReal_fx[i]; + tmp_I_fx[i] = cldfbBufferImag_fx[i]; + } + + cldfbAnalysis_ivas_fx( harm_timeIn_fx, tmp_R_fx, tmp_I_fx, samplesToProcess, cldfb ); + + /* now do the subtraction */ + FOR( i = 0; i < nColToProcess; i++ ) + { + /* loop over low frequency bands */ + FOR( b = 0; b < maxBand; b++ ) + { + rAnalysis_fx[i][b] = Msub_32_32( rAnalysis_fx[i][b], tmp_R_fx[i][b], weights_fx[b] ); // Qx - 6 + move32(); + iAnalysis_fx[i][b] = Msub_32_32( iAnalysis_fx[i][b], tmp_I_fx[i][b], weights_fx[b] ); // Qx - 6 + move32(); + } + } + + return; +} + + +/*---------------------------------------------------------------------* + * res_bpf_adapt_ivas_fx() + * + * Analyze BPF output and decide if it should be applied on DFT stereo + * residual signal + *---------------------------------------------------------------------*/ + +/*! r: Decision to enable or disable BPF on DFT stereo residual */ +Word16 res_bpf_adapt_ivas_fx( + STEREO_DFT_DEC_DATA_HANDLE hStereoDft, /* i/o: DFT stereo decoder handle */ + const Word32 *bpf_error_signal_8k, /* i : BPF modification signal */ + Word32 res_buf[STEREO_DFT_N_8k], /* i : residual buffer Q12 */ + Word16 q_res ) +{ + Word32 error_nrg; + Word32 tmp; + Word32 res_hb_nrg; + Word16 bpf_error_ratio; + Word16 res_bpf_flag; + Word16 i; + Word16 i_start; + Word16 i_end; + Word16 bw_inv; + Word64 W_tmp; + + IF( EQ_16( hStereoDft->res_cod_band_max, 6 ) ) + { + i_start = 39; + move16(); + i_end = 64; + move16(); + bw_inv = 1311; + move16(); /* 1/(64 - 39) in Q15 */ + } + ELSE + { + i_start = 28; + move16(); + i_end = 40; + move16(); + bw_inv = 2720; + move16(); /* 1/(40 - 28) in Q15*/ + } + + /* Measure energy of high frequency band in MDCT domain */ + res_hb_nrg = L_deposit_l( 0 ); + W_tmp = W_deposit32_l( 0 ); + FOR( i = i_start; i < i_end; i++ ) + { + W_tmp = W_add_nosat( W_tmp, W_mult0_32_32( res_buf[i], res_buf[i] ) ); + } + + res_hb_nrg = W_extract_l( W_shr( W_tmp, shl( q_res, 1 ) ) ); // Q0 + res_hb_nrg = Mpy_32_16_1( res_hb_nrg, bw_inv ); // Q0 + res_hb_nrg = L_add( Mpy_32_16_1( res_hb_nrg, STEREO_DFT_BPF_ADAPT_ALPHA_FX ), Mpy_32_16_1( hStereoDft->res_hb_nrg_mem_fx, sub( MAX_16, STEREO_DFT_BPF_ADAPT_ALPHA_FX ) ) ); + hStereoDft->res_hb_nrg_mem_fx = res_hb_nrg; + move32(); + + /* Measure energy of discontinuities at subframe boundaries */ + error_nrg = 0; + move32(); + FOR( i = 0; i < L_FRAME8k; i += STEREO_DFT_L_SUBFR_8k ) + { + tmp = L_sub( bpf_error_signal_8k[i], hStereoDft->bpf_error_signal_last_fx ); + error_nrg = Madd_32_32( error_nrg, tmp, tmp ); + hStereoDft->bpf_error_signal_last_fx = bpf_error_signal_8k[( i + ( STEREO_DFT_L_SUBFR_8k - 1 ) )]; + move32(); + } + error_nrg = L_shl( error_nrg, 1 ); // Q0 + error_nrg = Mpy_32_16_1( error_nrg, 6553 /* 0.2f in Q15 */ ); /* Division by 5 for average value */ + /* Form decision variable and apply limit */ + IF( LT_32( ( L_shr( error_nrg, 1 ) ), res_hb_nrg ) ) + { + Word16 temp; + bpf_error_ratio = BASOP_Util_Divide3232_Scale( error_nrg, res_hb_nrg, &temp ); + bpf_error_ratio = shl( bpf_error_ratio, sub( 13, sub( 15, temp ) ) ); + } + ELSE + { + bpf_error_ratio = ONE_IN_Q14; // Q13 + move16(); + } + bpf_error_ratio = add( mult( STEREO_DFT_BPF_ADAPT_BETA_FX, bpf_error_ratio ), mult( ( MAX_16 - STEREO_DFT_BPF_ADAPT_BETA_FX ), hStereoDft->bpf_error_ratio_mem_fx ) ); + hStereoDft->bpf_error_ratio_mem_fx = bpf_error_ratio; + move16(); + + res_bpf_flag = (Word16) LT_16( bpf_error_ratio, ONE_IN_Q13 ); + move16(); + + return res_bpf_flag; +} + +void bpf_pitch_coherence_ivas_fx( + Decoder_State *st, /* i/o: decoder state structure */ + const Word32 pitch_buf[] /* i : pitch for every subfr [0,1,2,3] Q20 */ +) +{ + Word16 nb_subfr; + Word32 pc, pcn1, pcn2, pcn3; + Word32 scaled_inv_L_frame; // Q8 + Q23 + + SWITCH( st->L_frame ) + { + case 80: + scaled_inv_L_frame = 26843545; // 1/80 in Q31 + move32(); + BREAK; + case 160: + scaled_inv_L_frame = 13421773; // 1/160 in Q31 + move32(); + BREAK; + case 256: + scaled_inv_L_frame = 8388608; // 1/256 in Q31 + move32(); + BREAK; + case 320: + scaled_inv_L_frame = 6710886; // 1/320 in Q31 + move32(); + BREAK; + case 512: + scaled_inv_L_frame = 4194304; // 1/512 in Q31 + move32(); + BREAK; + case 640: + scaled_inv_L_frame = 3355443; // 1/640 in Q31 + move32(); + BREAK; + case 960: + scaled_inv_L_frame = 2236962; // 1/80 in Q31 + move32(); + BREAK; + default: + scaled_inv_L_frame = 0; + move32(); + } + + nb_subfr = shr( st->L_frame, 6 ); + test(); + IF( GT_16( st->clas_dec, UNVOICED_CLAS ) && ( st->element_mode != EVS_MONO ) ) + { + pc = L_abs( L_sub( L_add( st->old_pitch_buf_fx[nb_subfr + 3], st->old_pitch_buf_fx[nb_subfr + 2] ), L_add( st->old_pitch_buf_fx[nb_subfr], st->old_pitch_buf_fx[nb_subfr + 1] ) ) ); + pc = Mpy_32_32( pc, scaled_inv_L_frame ); + pcn1 = L_add( Mpy_32_32( pc, K_PC_DEC_FX32 ), C_PC_DEC_FX ); + pcn1 = L_max( L_min( pcn1, 4096 ), 0 ); // 4096 = 1 in Q12 + + pc = L_abs( L_sub( L_add( pitch_buf[nb_subfr - 1], pitch_buf[nb_subfr - 2] ), L_add( pitch_buf[1], pitch_buf[0] ) ) ); + pc = Mpy_32_32( pc, scaled_inv_L_frame ); + pcn2 = L_add( Mpy_32_32( pc, K_PC_DEC_FX32 ), C_PC_DEC_FX ); + pcn2 = L_max( L_min( pcn2, 4096 ), 0 ); // 4096 = 1 in Q12 + + pc = L_abs( L_sub( L_add( st->old_pitch_buf_fx[nb_subfr + 3], st->old_pitch_buf_fx[nb_subfr + 2] ), L_add( pitch_buf[1], pitch_buf[0] ) ) ); + pc = Mpy_32_32( pc, scaled_inv_L_frame ); + pcn3 = L_add( Mpy_32_32( pc, K_PC_DEC_FX32 ), C_PC_DEC_FX ); + pcn3 = L_max( L_min( pcn3, 4096 ), 0 ); // 4096 = 1 in Q12 + + IF( LT_32( L_add( pcn1, L_add( pcn2, pcn3 ) ), 10240 /*2.5f in Q12*/ ) ) + { + st->hBPF->psf_att_fx = 13107; //.4 in Q15 + move16(); /*Q15*/ + set16_fx( &st->hBPF->Track_on_hist[L_TRACK_HIST - nb_subfr], 1, nb_subfr ); + } + } + + return; +} + + #ifdef ADD_BPF_ADAPT /*---------------------------------------------------------------------* * res_bpf_adapt() diff --git a/lib_dec/cng_dec.c b/lib_dec/cng_dec.c deleted file mode 100644 index 515dd295af034fe7645af8028d29af3c3cb69e33..0000000000000000000000000000000000000000 --- a/lib_dec/cng_dec.c +++ /dev/null @@ -1,47 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include -#include "ivas_cnst.h" -#include "prot.h" -#include "rom_com.h" -#include "wmc_auto.h" - -/*---------------------------------------------------------------------* - * Local function prototypes - *---------------------------------------------------------------------*/ diff --git a/lib_dec/cng_dec_fx.c b/lib_dec/cng_dec_fx.c index 1ca8f8ac3e10d50b7a0038defbcbcc27f9196aba..ab349773ee6e3948dc03edf782479bb9e57ce3c5 100644 --- a/lib_dec/cng_dec_fx.c +++ b/lib_dec/cng_dec_fx.c @@ -6,7 +6,6 @@ #include "options.h" /* Compilation switches */ #include "cnst.h" #include "rom_com.h" -#include "prot.h" #include "prot_fx.h" #include "ivas_cnst.h" @@ -524,11 +523,7 @@ void CNG_dec_fx( FOR( i = 0; i < M; i++ ) { dev = abs_s( sub( lsp_tmp[i], lsp_new[i] ) ); /*Q15*/ -#ifdef BASOP_NOGLOB - dist = add_o( dist, dev, &Overflow ); /*Q15*/ -#else - dist = add( dist, dev ); /*Q15*/ -#endif + dist = add_o( dist, dev, &Overflow ); /*Q15*/ if ( GT_16( dev, max_dev ) ) { max_dev = dev; @@ -562,31 +557,19 @@ void CNG_dec_fx( FOR( j = 0; j < m1; j++ ) { /* env[i] += tmp_env[j*NUM_ENV_CNG+i];*/ -#ifdef BASOP_NOGLOB L_tmp = L_add_sat( L_tmp, tmp_env[j * NUM_ENV_CNG + i] ); -#else - L_tmp = L_add( L_tmp, tmp_env[j * NUM_ENV_CNG + i] ); -#endif } /* env[i] /= (float)m1; */ /* env[i] = env[i] - 2*st_fx->lp_ener_fx; */ IF( EQ_16( m1, 1 ) ) { -#ifdef BASOP_NOGLOB L_tmp = L_sub_sat( L_tmp, L_add_sat( st_fx->lp_ener_fx, st_fx->lp_ener_fx ) ); /* Q6 */ -#else - L_tmp = L_sub( L_tmp, L_add( st_fx->lp_ener_fx, st_fx->lp_ener_fx ) ); -#endif } ELSE { tmp1 = div_s( 1, m1 ); - L_tmp = Mult_32_16( L_tmp, tmp1 ); /* Q6 */ -#ifdef BASOP_NOGLOB + L_tmp = Mult_32_16( L_tmp, tmp1 ); /* Q6 */ L_tmp = L_sub_sat( L_tmp, L_add_sat( st_fx->lp_ener_fx, st_fx->lp_ener_fx ) ); /* Q6 */ -#else - L_tmp = L_sub( L_tmp, L_add( st_fx->lp_ener_fx, st_fx->lp_ener_fx ) ); -#endif } env[i] = L_tmp; /* Q6 */ move32(); @@ -606,11 +589,7 @@ void CNG_dec_fx( { /* Update hangover memory during CNG */ test(); -#ifdef BASOP_NOGLOB IF( ( *allow_cn_step == 0 ) && LT_32( hTdCngDec->Enew_fx, L_add_sat( st_fx->lp_ener_fx, L_shr( st_fx->lp_ener_fx, 1 ) ) ) ) -#else - IF( *allow_cn_step == 0 && LT_32( hTdCngDec->Enew_fx, L_add( st_fx->lp_ener_fx, L_shr( st_fx->lp_ener_fx, 1 ) ) ) ) -#endif { /* update the pointer to circular buffer of old LSP vectors */ hTdCngDec->ho_hist_ptr++; @@ -634,11 +613,7 @@ void CNG_dec_fx( exp = norm_l( hTdCngDec->Enew_fx ); L_tmp = L_shl( hTdCngDec->Enew_fx, exp ); /*Q(exp+6)*/ L_tmp = Mult_32_16( L_tmp, shl( st_fx->L_frame, 5 ) ); /*Q(exp+6+5-15=exp-4)*/ -#ifdef BASOP_NOGLOB - L_tmp = L_shr_sat( L_tmp, sub( exp, 10 ) ); /*Q6*/ -#else - L_tmp = L_shr( L_tmp, sub( exp, 10 ) ); /*Q6*/ -#endif + L_tmp = L_shr_sat( L_tmp, sub( exp, 10 ) ); /*Q6*/ exp = norm_l( L_tmp ); fra = Log2_norm_lc( L_shl( L_tmp, exp ) ); exp = sub( sub( 30, exp ), 6 ); @@ -1219,11 +1194,7 @@ void CNG_dec_ivas_fx( FOR( i = 0; i < M; i++ ) { dev = abs_s( sub( lsp_tmp[i], lsp_new[i] ) ); /*Q15*/ -#ifdef BASOP_NOGLOB - dist = add_o( dist, dev, &Overflow ); /*Q15*/ -#else - dist = add( dist, dev ); /*Q15*/ -#endif + dist = add_o( dist, dev, &Overflow ); /*Q15*/ if ( GT_16( dev, max_dev ) ) { max_dev = dev; @@ -1257,31 +1228,19 @@ void CNG_dec_ivas_fx( FOR( j = 0; j < m1; j++ ) { /* env[i] += tmp_env[j*NUM_ENV_CNG+i];*/ -#ifdef BASOP_NOGLOB L_tmp = L_add_sat( L_tmp, tmp_env[j * NUM_ENV_CNG + i] ); -#else - L_tmp = L_add( L_tmp, tmp_env[j * NUM_ENV_CNG + i] ); -#endif } /* env[i] /= (float)m1; */ /* env[i] = env[i] - 2*st_fx->lp_ener_fx; */ IF( EQ_16( m1, 1 ) ) { -#ifdef BASOP_NOGLOB L_tmp = L_sub_sat( L_tmp, L_add_sat( st_fx->lp_ener_fx, st_fx->lp_ener_fx ) ); /* Q6 */ -#else - L_tmp = L_sub( L_tmp, L_add( st_fx->lp_ener_fx, st_fx->lp_ener_fx ) ); -#endif } ELSE { tmp1 = div_s( 1, m1 ); - L_tmp = Mult_32_16( L_tmp, tmp1 ); /* Q6 */ -#ifdef BASOP_NOGLOB + L_tmp = Mult_32_16( L_tmp, tmp1 ); /* Q6 */ L_tmp = L_sub_sat( L_tmp, L_add_sat( st_fx->lp_ener_fx, st_fx->lp_ener_fx ) ); /* Q6 */ -#else - L_tmp = L_sub( L_tmp, L_add( st_fx->lp_ener_fx, st_fx->lp_ener_fx ) ); -#endif } env[i] = L_tmp; /* Q6 */ move32(); @@ -1301,11 +1260,7 @@ void CNG_dec_ivas_fx( { /* Update hangover memory during CNG */ test(); -#ifdef BASOP_NOGLOB IF( ( *allow_cn_step == 0 ) && LT_32( hTdCngDec->Enew_fx, L_add_sat( st_fx->lp_ener_fx, L_shr( st_fx->lp_ener_fx, 1 ) ) ) ) -#else - IF( *allow_cn_step == 0 && LT_32( hTdCngDec->Enew_fx, L_add( st_fx->lp_ener_fx, L_shr( st_fx->lp_ener_fx, 1 ) ) ) ) -#endif { /* update the pointer to circular buffer of old LSP vectors */ hTdCngDec->ho_hist_ptr++; @@ -1329,11 +1284,7 @@ void CNG_dec_ivas_fx( exp = norm_l( hTdCngDec->Enew_fx ); L_tmp = L_shl( hTdCngDec->Enew_fx, exp ); /*Q(exp+6)*/ L_tmp = Mult_32_16( L_tmp, shl( st_fx->L_frame, 5 ) ); /*Q(exp+6+5-15=exp-4)*/ -#ifdef BASOP_NOGLOB - L_tmp = L_shr_sat( L_tmp, sub( exp, 10 ) ); /*Q6*/ -#else - L_tmp = L_shr( L_tmp, sub( exp, 10 ) ); /*Q6*/ -#endif + L_tmp = L_shr_sat( L_tmp, sub( exp, 10 ) ); /*Q6*/ exp = norm_l( L_tmp ); fra = Log2_norm_lc( L_shl( L_tmp, exp ) ); exp = sub( sub( 30, exp ), 6 ); @@ -1561,12 +1512,6 @@ static void shb_CNG_decod_fx( } ELSE { -#ifdef IVAS_CODE_CNG - /* de-quantization of SHB CNG parameters */ To be verified - L_tmp = L_mult( idx_ener_fx, 17615 ); /*Q13*/ - st_fx->last_shb_cng_ener_fx = extract_l( L_shr( L_sub( L_tmp, 147962 ), 5 ) ); /*Q8 */ - move16(); -#endif } } } @@ -1575,11 +1520,7 @@ static void shb_CNG_decod_fx( interp_fx = s_min( st_fx->shb_dtx_count_fx, 32 ); -#ifdef BASOP_NOGLOB interp_fx = shl_sat( interp_fx, 10 ); /*Q15*/ -#else - interp_fx = shl( interp_fx, 10 ); /*Q15*/ -#endif FOR( i = 0; i < LPC_SHB_ORDER; i++ ) { tmp2 = mult( interp_fx, st_fx->lsp_shb_prev_fx[i] ); /*Q14*/ @@ -1601,9 +1542,6 @@ static void shb_CNG_decod_fx( Copy_Scale_sig( shb_lpcCNG_fx, shb_lpcCNG_fx, LPC_SHB_ORDER + 1, sub( norm_s( shb_lpcCNG_fx[0] ), 2 ) ); /* Q12 */ -#ifdef IVAS_CODE_CNG - // mvr2r(shb_lpcCNG, st->hTdCngDec->shb_lpcCNG, LPC_SHB_ORDER + 1); -#endif /* SHB energy estimation */ wb_ener_fx = L_deposit_l( 1 ); /*Q1 */ FOR( i = 0; i < L_FRAME32k; i++ ) @@ -1708,12 +1646,8 @@ static void shb_CNG_decod_fx( move16(); /*Q8 */ IF( st_fx->trans_cnt_fx > 0 ) { - i = extract_l( L_mult0( st_fx->trans_cnt_fx, 17 ) ); /*Q0 */ -#ifdef BASOP_NOGLOB + i = extract_l( L_mult0( st_fx->trans_cnt_fx, 17 ) ); /*Q0 */ ener_fx = add_sat( st_fx->shb_cng_ener_fx, mult( sin_table256_fx[i], sub_sat( st_fx->last_shb_ener_fx, st_fx->shb_cng_ener_fx ) ) ); /*Q8 */ -#else - ener_fx = add( st_fx->shb_cng_ener_fx, mult( sin_table256_fx[i], sub( st_fx->last_shb_ener_fx, st_fx->shb_cng_ener_fx ) ) ); /*Q8 */ -#endif st_fx->trans_cnt_fx = sub( st_fx->trans_cnt_fx, 1 ); move16(); } @@ -1728,11 +1662,7 @@ static void shb_CNG_decod_fx( move32(); } fra = L_Extract_lc( L_tmp, &exp ); -#ifdef BASOP_NOGLOB L_tmp = L_shl_sat( Pow2( exp, fra ), 5 ); /*Q5 */ -#else - L_tmp = L_shl( Pow2( exp, fra ), 5 ); /*Q5 */ -#endif L_tmp = L_shr( L_tmp, 10 ); if ( !L_tmp ) { @@ -1755,9 +1685,7 @@ static void shb_CNG_decod_fx( L_tmp = L_deposit_h( tmp ); /*Q31 */ tmp = sub( add( 5, exp ), add( q, exp1 ) ); L_gain_fx = Isqrt_lc( L_tmp, &tmp ); /*Q31-Qtmp */ -#ifdef IVAS_CODE_CNG - st->hTdCngDec->shb_cng_gain = ener_fx; -#endif + FOR( i = 0; i < L_FRAME16k; i++ ) { shb_syn16k_fx[i] = extract_l( L_shr( Mpy_32_16_1( L_gain_fx, excSHB_fx[i] ), sub( 5, tmp ) ) ); /*Q3 = 31-Qtmp-8-15-5+Qtmp */ @@ -1786,11 +1714,8 @@ static void shb_CNG_decod_fx( { interpolate_3_over_2_allpass_fx( shb_synth_fx, L_FRAME32k, shb_synth_fx, st_fx->interpol_3_2_cng_dec_fx, allpass_poles_3_ov_2 ); } -#ifdef IVAS_CODE_CNG - ResetSHBbuffer_Dec( st->hBWE_TD, st->extl ); -#else + ResetSHBbuffer_Dec_fx( st_fx ); -#endif return; } @@ -1858,11 +1783,7 @@ static void shb_CNG_decod_ivas_fx( /* SHB spectrum estimation */ interp_fx = s_min( st->hTdCngDec->shb_dtx_count, 32 ); -#ifdef BASOP_NOGLOB interp_fx = shl_sat( interp_fx, 10 ); /*Q15*/ -#else - interp_fx = shl( interp_fx, 10 ); /*Q15*/ -#endif FOR( i = 0; i < LPC_SHB_ORDER; i++ ) { @@ -2101,20 +2022,6 @@ void td_cng_dec_init_fx( move16(); hTdCngDec->last_allow_cn_step = 0; move16(); -#ifdef IVAS_CODE_CNG - // mvr2r(st->lsp_old, st->lspCNG, M); - // hTdCngDec->shb_cng_ener = -6.02f; - IF( st->element_mode != EVS_MONO ) - { - // set_f(hTdCngDec->shb_lpcCNG, 0.0f, LPC_SHB_ORDER + 1); - // hTdCngDec->shb_lpcCNG[0] = 1.0f; - // hTdCngDec->shb_cng_gain = -82.0; /* a dB value approximately corresponding to shb index 0(used as index -15) */ - } - // hTdCngDec->wb_cng_ener = -6.02f; - // hTdCngDec->last_wb_cng_ener = -6.02f; - // hTdCngDec->last_shb_cng_ener = -6.02f; - // hTdCngDec->swb_cng_seed = RANDOM_INITSEED; -#endif hTdCngDec->ho_hist_ptr = -1; move16(); hTdCngDec->ho_sid_bw = L_deposit_l( 0 ); @@ -2145,26 +2052,6 @@ void td_cng_dec_init_fx( set16_fx( hTdCngDec->exc_mem_fx, 0, 24 ); set16_fx( hTdCngDec->exc_mem1_fx, 0, 30 ); set32_fx( hTdCngDec->old_env_fx, 0, NUM_ENV_CNG ); -#ifdef IVAS_CODE_CNG - // st->CNG_mode = -1; - // for (i = 0; i < LPC_SHB_ORDER; i++) - //{ - // IF (st->element_mode != EVS_MONO) - // { - // hTdCngDec->lsp_shb_prev[i] = 0.5f * ((float)(i + 1)) / ((float)(LPC_SHB_ORDER + 1)); - // } - // else - // { - // hTdCngDec->lsp_shb_prev[i] = 0.5f * ((float)i) / ((float)LPC_SHB_ORDER); - // } - // hTdCngDec->lsp_shb_prev_prev[i] = hTdCngDec->lsp_shb_prev[i]; - // } - - // hTdCngDec->shb_dtx_count = 0; - // hTdCngDec->trans_cnt = 0; - // hTdCngDec->last_shb_ener = 0.001f; - // set_f(hTdCngDec->interpol_3_2_cng_dec, 0.0f, INTERP_3_2_MEM_LEN); -#endif hTdCngDec->burst_cnt = 0; move16(); diff --git a/lib_dec/core_dec_init_fx.c b/lib_dec/core_dec_init_fx.c index c0a83460a51adaf9b87906158817144fc14a3ff0..dd268fe083ed61cdf5e23233a66d88a24d2148ae 100644 --- a/lib_dec/core_dec_init_fx.c +++ b/lib_dec/core_dec_init_fx.c @@ -7,7 +7,6 @@ #include #include #include "options.h" -#include "prot.h" #include "prot_fx.h" #include "basop_util.h" #include "rom_com.h" @@ -1287,7 +1286,7 @@ void open_decoder_LPD_ivas_fx( move16(); st->output_frame_fx = st->hTcxDec->L_frameTCX; /* Q0 */ move16(); - if ( ( st->ini_frame == 0 ) ) + if ( st->ini_frame == 0 ) { st->L_frameTCX_past = st->hTcxDec->L_frameTCX; move16(); @@ -1360,7 +1359,7 @@ void open_decoder_LPD_ivas_fx( } } - if ( ( st->ini_frame == 0 ) ) + if ( st->ini_frame == 0 ) { st->pit_res_max_past = st->pit_res_max; move16(); @@ -2191,3 +2190,28 @@ void open_decoder_LPD_ivas_fx( return; } + +/*-----------------------------------------------------------------------* + * reset_tcx_overl_buf() + * + * Reset TCX core overlap buffers + *-----------------------------------------------------------------------*/ + +void reset_tcx_overl_buf_fx( + TCX_DEC_HANDLE hTcxDec /* i/o: TCX decoder handle */ +) +{ + set16_fx( hTcxDec->old_syn_Overl, 0, L_FRAME32k / 2 ); /*HQ-CORE(bfi)->TCX don't need it*/ + hTcxDec->Q_old_syn_Overl = 0; + move16(); + set16_fx( hTcxDec->syn_Overl_TDAC, 0, L_FRAME32k / 2 ); /*HQ-CORE(bfi)->TCX don't need it*/ + hTcxDec->Q_syn_Overl_TDAC = 0; + move16(); + set16_fx( hTcxDec->syn_Overl, 0, L_FRAME32k / 2 ); /*HQ-CORE(bfi)->TCX don't need it*/ + hTcxDec->Q_syn_Overl = 0; + move16(); + set16_fx( hTcxDec->syn_Overl_TDACFB, 0, L_FRAME_MAX / 2 ); /*HQ-CORE(bfi)->TCX don't need it*/ + hTcxDec->Q_syn_Overl_TDACFB = 0; + move16(); + return; +} diff --git a/lib_dec/core_dec_reconf.c b/lib_dec/core_dec_reconf.c deleted file mode 100644 index f8f6d6a6fbe971408dea336364c639a89c470215..0000000000000000000000000000000000000000 --- a/lib_dec/core_dec_reconf.c +++ /dev/null @@ -1,43 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include "prot.h" -#include "rom_com.h" -#include "rom_dec.h" -#include "wmc_auto.h" -#include "prot_fx.h" diff --git a/lib_dec/core_dec_switch.c b/lib_dec/core_dec_switch.c deleted file mode 100644 index 9fb0cf7882be3549e115080f0f158540d6808548..0000000000000000000000000000000000000000 --- a/lib_dec/core_dec_switch.c +++ /dev/null @@ -1,48 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include -#include "options.h" -#include "prot.h" -#include "rom_com.h" -#include "wmc_auto.h" - -/*-------------------------------------------------------------* - * mode_switch_decoder_LPD() - * - * - *-------------------------------------------------------------*/ diff --git a/lib_dec/core_dec_switch_fx.c b/lib_dec/core_dec_switch_fx.c index c7d2c526574e7a61c710be168e72836de7c5b81b..2fd3f1d2ec32c0b8b0308378c73062f344bbfe71 100644 --- a/lib_dec/core_dec_switch_fx.c +++ b/lib_dec/core_dec_switch_fx.c @@ -8,7 +8,6 @@ #include "basop_util.h" #include "prot_fx.h" #include "rom_com.h" -#include "prot.h" void mode_switch_decoder_LPD_fx( Decoder_State *st, /* i/o: decoder state structure */ diff --git a/lib_dec/core_switching_dec.c b/lib_dec/core_switching_dec.c deleted file mode 100644 index 323deae0ac32506e8208d09fcd45eb92f04fa50b..0000000000000000000000000000000000000000 --- a/lib_dec/core_switching_dec.c +++ /dev/null @@ -1,1072 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include -#include "cnst.h" -#include "rom_com.h" -#include "prot.h" -#include "prot_fx.h" -#include "ivas_cnst.h" -#include "wmc_auto.h" - -#include "ivas_prot_fx.h" -#include "debug.h" -/*---------------------------------------------------------------------* - * Local prototypes - *---------------------------------------------------------------------*/ - - -/*---------------------------------------------------------------------* - * core_switching_pre_dec() - * - * Preprocessing/preparation for ACELP/HQ core switching - *---------------------------------------------------------------------*/ -ivas_error core_switching_pre_dec_ivas_fx( - Decoder_State *st, /* i/o: decoder state structure */ - const Word16 output_frame, /* i : frame length */ - const Word32 last_core_brate_st0, /* i : channel 0 last core bitrate */ - const Word16 nchan_out, /* i : number of output channels */ - const Word16 last_element_mode, /* i : last_element_mode */ - const Word32 last_element_brate, /* i : last element bitrate */ - Word16 Q_old_synthFB, - Word16 *Q_olapBufferSynth, - Word16 *Q_olapBufferSynth2 ) -{ - Word32 tmp_fx; /*Q-12*/ - Word16 i, oldLenClasBuff, newLenClasBuff; - ivas_error error; - Word16 exp = 25; - move16(); - error = IVAS_ERR_OK; - move32(); - - /* Codec mode switching */ - test(); - test(); - test(); - IF( EQ_16( st->last_codec_mode, MODE2 ) || ( ( EQ_16( st->last_core, TCX_20_CORE ) || EQ_16( st->last_core, TCX_10_CORE ) ) && ( st->element_mode > EVS_MONO ) ) ) - { - st->mem_deemph_fx = st->syn[M]; - move16(); - set16_fx( st->agc_mem_fx, 0, 2 ); - Scale_sig( &( st->mem_deemph_fx ), 1, st->Q_syn ); /* Brings mem_deemph to Qsyn */ - - Copy_Scale_sig( st->mem_syn2_fx, st->mem_syn1_fx, M, sub( -1, st->Q_syn ) ); /*Q-1*/ - - st->bpf_off = 1; - move16(); - IF( st->hPFstat != NULL ) - { - Scale_sig( st->hPFstat->mem_pf_in, L_SUBFR, st->Q_syn ); /* Post_filter mem ,Q_syn*/ - Scale_sig( st->hPFstat->mem_res2, DECMEM_RES2, st->Q_syn ); /* NB post_filter mem , Q_syn*/ - Scale_sig( st->hPFstat->mem_stp, L_SUBFR, st->Q_syn ); /* Post_filter mem ,Q_syn*/ - set16_fx( st->hBPF->pst_old_syn_fx, 0, NBPSF_PIT_MAX ); /* BPF mem*/ - } - IF( st->hBPF != NULL ) - { - st->hBPF->pst_lp_ener_fx = round_fx( L_shl( Mpy_32_16_1( st->lp_error_ener, 0x6054 ), 2 + 8 ) ); /* convert from 15Q16, log2 -> 7Q8 10*log10 */ - st->hBPF->pst_mem_deemp_err_fx = 0; - move16(); - move16(); - } - st->psf_lp_noise_fx = round_fx( L_shl( st->lp_noise, 1 ) ); // Q(23+1-16)->Q8 - move16(); - - /* reset old HB synthesis buffer */ - IF( EQ_16( st->last_L_frame, L_FRAME ) ) - { - st->old_bwe_delay = NS2SA( st->output_Fs, MAX_DELAY_TBE_NS - DELAY_SWB_TBE_12k8_NS ); - } - ELSE - { - st->old_bwe_delay = NS2SA( st->output_Fs, MAX_DELAY_TBE_NS - DELAY_SWB_TBE_16k_NS ); - } - move16(); - set16_fx( st->hb_prev_synth_buffer_fx, 0, NS2SA( 48000, DELAY_BWE_TOTAL_NS ) ); - - test(); - IF( st->hBWE_TD != NULL && ( st->last_core != ACELP_CORE ) ) - { -#ifdef MSAN_FIX - st->hBWE_TD->prev_hb_synth_fx_exp = 31; - move16(); -#endif // MSAN_FIX - /* reset BWE memories */ - set16_fx( st->hBWE_TD->old_bwe_exc_fx, 0, PIT16k_MAX * 2 ); - st->hBWE_TD->bwe_non_lin_prev_scale_fx = 0; - move32(); - } - - /* reset upd_cnt */ - st->upd_cnt = MAX_UPD_CNT; - move16(); - - st->igf = 0; - move16(); - - test(); - IF( GT_32( st->output_Fs, 16000 ) && st->hBWE_zero != NULL ) - { - hf_synth_reset_fx( st->hBWE_zero ); -#ifdef MSAN_FIX - set16_fx( st->hBWE_zero->mem_hp400_fx, 0, 6 ); -#endif - } - - IF( st->hBWE_FD != NULL ) - { - set16_fx( st->hBWE_FD->old_syn_12k8_16k_fx, 0, NS2SA( 16000, DELAY_FD_BWE_ENC_NS ) ); - } - - IF( st->hHQ_core != NULL ) - { - set32_fx( st->hHQ_core->prev_env_fx, 0, SFM_N_WB ); - set32_fx( st->hHQ_core->prev_normq_fx, 0, SFM_N_WB ); - - set32_fx( st->hHQ_core->last_ni_gain_fx, 0, BANDS_MAX ); - set16_fx( st->hHQ_core->last_env_fx, 0, BANDS_MAX ); - - st->hHQ_core->last_max_pos_pulse = 0; - move16(); - - IF( GT_32( st->output_Fs, 16000 ) ) - { - set32_fx( st->hHQ_core->prev_coeff_out_fx, 0, L_HQ_WB_BWE ); - } - - /* pre-echo */ - st->hHQ_core->pastpre = 0; - move16(); - } - - /* reset the GSC pre echo energy threshold in case of switching */ - if ( st->hGSCDec != NULL ) - { - st->hGSCDec->Last_frame_ener_fx = MAX_32; - move32(); - } - - test(); - IF( EQ_16( st->last_core, TCX_20_CORE ) || EQ_16( st->last_core, TCX_10_CORE ) ) - { - IF( st->element_mode == EVS_MONO ) - { - st->last_core = HQ_CORE; - move16(); - - Copy32( st->hTcxDec->FBTCXdelayBuf_32, st->prev_synth_buffer32_fx, NS2SA( st->output_Fs, DELAY_BWE_TOTAL_NS - DELAY_CLDFB_NS ) ); - // Copy_Scale_sig_32_16( st->hTcxDec->FBTCXdelayBuf_32, st->prev_synth_buffer_fx, NS2SA( st->output_Fs, DELAY_BWE_TOTAL_NS - DELAY_CLDFB_NS ), -11 ); //Q11 -> Q0 - } - - IF( st->hHQ_core != NULL ) - { - set32_fx( st->hHQ_core->last_ni_gain_fx, 0, BANDS_MAX ); - set16_fx( st->hHQ_core->last_env_fx, 0, BANDS_MAX ); - st->hHQ_core->last_max_pos_pulse = 0; - move16(); - - set16_fx( st->hHQ_core->prev_SWB_peak_pos, 0, SPT_SHORTEN_SBNUM ); - st->hHQ_core->prev_frm_hfe2 = 0; - st->hHQ_core->prev_stab_hfe2 = 0; - move16(); - move16(); - } - } - - IF( st->prev_bfi != 0 ) - { - Word16 delay_comp; - - /*switch off Hq Voicing as it was not updated in MODE2*/ - IF( st->hHQ_core != NULL ) - { - st->hHQ_core->oldHqVoicing = 0; - st->hHQ_core->HqVoicing = 0; - move16(); - move16(); - } - - delay_comp = NS2SA( st->output_Fs, DELAY_CLDFB_NS ); - /*TODO To be tested:control not entering the block*/ - test(); - test(); - IF( !st->last_con_tcx && ( st->last_core_bfi == ACELP_CORE ) && EQ_16( st->core, HQ_CORE ) ) - { - /*TODO None of the test dtreams are entering this block,hence enabled assert(0)*/ - assert( 0 ); - Word32 *realBuffer_fx[CLDFB_NO_COL_MAX_SWITCH], *imagBuffer_fx[CLDFB_NO_COL_MAX_SWITCH]; - Word32 realBufferTmp_fx[CLDFB_NO_COL_MAX_SWITCH][CLDFB_NO_CHANNELS_MAX], imagBufferTmp_fx[CLDFB_NO_COL_MAX_SWITCH][CLDFB_NO_CHANNELS_MAX]; - Word32 syn_Overl_fx[320]; - Word32 fer_samples_fx[960]; - Copy_Scale_sig_16_32( st->hTcxDec->syn_Overl, syn_Overl_fx, 320, 15 ); - Copy_Scale_sig_16_32( st->hHQ_core->fer_samples_fx, fer_samples_fx, 960, 15 ); - - - FOR( i = 0; i < CLDFB_NO_COL_MAX_SWITCH; i++ ) - { - set32_fx( realBufferTmp_fx[i], 0, CLDFB_NO_CHANNELS_MAX ); - set32_fx( imagBufferTmp_fx[i], 0, CLDFB_NO_CHANNELS_MAX ); - realBuffer_fx[i] = realBufferTmp_fx[i]; - imagBuffer_fx[i] = imagBufferTmp_fx[i]; - } - - /* CLDFB analysis of the synthesis at internal sampling rate */ - IF( NE_32( ( error = cldfb_save_memory_ivas_fx( st->cldfbAna ) ), IVAS_ERR_OK ) ) - { - return error; - } - - cldfbAnalysis_ivas_fx( syn_Overl_fx, realBuffer_fx, imagBuffer_fx, delay_comp, st->cldfbAna ); - cldfb_restore_memory_ivas_fx( st->cldfbAna ); /*Assuming Q10*/ - - /* CLDFB synthesis of the combined signal */ - IF( NE_32( ( error = cldfb_save_memory_ivas_fx( st->cldfbSyn ) ), IVAS_ERR_OK ) ) - { - return error; - } - - cldfbSynthesis_ivas_fx( realBuffer_fx, imagBuffer_fx, fer_samples_fx, delay_comp, st->cldfbSyn ); - cldfb_restore_memory_ivas_fx( st->cldfbSyn ); - Copy_Scale_sig_32_16( syn_Overl_fx, st->hTcxDec->syn_Overl, 320, 15 ); - Copy_Scale_sig_32_16( fer_samples_fx, st->hHQ_core->fer_samples_fx, 960, 9 ); - } - - test(); - test(); - IF( !st->last_con_tcx && ( st->last_core_bfi == ACELP_CORE ) && EQ_16( st->core, HQ_CORE ) ) - { - lerp( st->hTcxDec->syn_Overl, st->hHQ_core->fer_samples_fx + delay_comp, shr( output_frame, 1 ), shr( st->last_L_frame, 1 ) ); - /*Set to zero the remaining part*/ - set16_fx( st->hHQ_core->fer_samples_fx + delay_comp + output_frame / 2, 0, sub( shr( output_frame, 1 ), delay_comp ) ); - } - } - - st->use_acelp_preq = 0; - st->reset_mem_AR = 0; - move16(); - move16(); - } - - /*FEC*/ - IF( LE_16( st->L_frame, L_FRAME16k ) ) - { - test(); - IF( LE_16( st->last_L_frame, L_FRAME16k ) && NE_16( st->core, HQ_CORE ) ) - { - IF( NE_16( st->L_frame, st->last_L_frame ) ) - { - IF( GT_16( st->L_frame, st->last_L_frame ) ) - { - oldLenClasBuff = mult_r( L_SYN_MEM_CLAS_ESTIM, div_s( st->last_L_frame, st->L_frame ) ); - newLenClasBuff = L_SYN_MEM_CLAS_ESTIM; - move16(); - } - ELSE - { - oldLenClasBuff = L_SYN_MEM_CLAS_ESTIM; - move16(); - newLenClasBuff = mult_r( L_SYN_MEM_CLAS_ESTIM, div_s( st->L_frame, st->last_L_frame ) ); - } - lerp( &st->mem_syn_clas_estim_fx[L_SYN_MEM_CLAS_ESTIM - oldLenClasBuff], &st->mem_syn_clas_estim_fx[L_SYN_MEM_CLAS_ESTIM - newLenClasBuff], newLenClasBuff, oldLenClasBuff ); - } - } - ELSE - { - set16_fx( st->mem_syn_clas_estim_fx, 0, L_SYN_MEM_CLAS_ESTIM ); - } - } - - /* Here we only handle cases where last_ppp and last_nelp not updated when coming from CodecB or other cores - within ACELP_CORE if switching from another bitarate to vbr, last_ppp and last_nelp is always updated in the previous frame */ - test(); - test(); - IF( ( st->core == ACELP_CORE ) && ( ( st->last_core != ACELP_CORE ) || EQ_16( st->last_codec_mode, MODE2 ) ) ) - { - st->last_ppp_mode_dec = 0; - st->last_nelp_mode_dec = 0; - move16(); - move16(); - } - - /* Handle state reset of stat_noise_uv_mod memory */ - test(); - test(); - test(); - IF( ( st->core == ACELP_CORE ) && ( ( st->last_core != ACELP_CORE ) || EQ_16( st->last_codec_mode, MODE2 ) || LE_32( st->last_total_brate, PPP_NELP_2k80 ) ) ) - { - st->act_count = 3; - st->uv_count = 0; - move16(); - move16(); - } - - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - IF( ( ( ( st->core == ACELP_CORE ) || EQ_16( st->core, AMR_WB_CORE ) ) && EQ_16( st->last_core, HQ_CORE ) ) || ( ( EQ_16( st->element_mode, IVAS_CPE_DFT ) || EQ_16( st->element_mode, IVAS_CPE_TD ) || ( EQ_16( st->element_mode, IVAS_CPE_MDCT ) && EQ_16( last_element_mode, IVAS_CPE_DFT ) ) ) && EQ_16( nchan_out, 2 ) && - NE_32( st->core_brate, SID_2k40 ) && ( st->core_brate != FRAME_NO_DATA ) && ( ( last_core_brate_st0 == FRAME_NO_DATA ) || EQ_32( last_core_brate_st0, SID_2k40 ) ) ) ) - { - test(); - if ( EQ_16( st->element_mode, IVAS_CPE_DFT ) || EQ_16( st->element_mode, IVAS_CPE_TD ) ) - { - st->hPFstat->reset = 1; - move16(); - } - - IF( EQ_16( st->L_frame, L_FRAME16k ) ) - { - Copy( TRWB2_Ave_fx, st->lsf_old_fx, M ); /* init of LSP */ - Copy( TRWB2_Ave_fx, st->lsfoldbfi1_fx, M ); - Copy( TRWB2_Ave_fx, st->lsfoldbfi0_fx, M ); - Copy( TRWB2_Ave_fx, st->lsf_adaptive_mean_fx, M ); - lsf2lsp_fx( st->lsf_old_fx, st->lsp_old_fx, M, INT_FS_16k ); - } - ELSE - { - Copy( TRWB_Ave_fx, st->lsf_old_fx, M ); /* init of LSP */ - Copy( TRWB_Ave_fx, st->lsfoldbfi1_fx, M ); - Copy( TRWB_Ave_fx, st->lsfoldbfi0_fx, M ); - Copy( TRWB_Ave_fx, st->lsf_adaptive_mean_fx, M ); - lsf2lsp_fx( st->lsf_old_fx, st->lsp_old_fx, M, INT_FS_12k8 ); - } - - test(); - test(); - test(); - test(); - test(); - test(); - IF( ( EQ_16( st->element_mode, IVAS_CPE_DFT ) || EQ_16( st->element_mode, IVAS_CPE_TD ) ) && EQ_16( nchan_out, 2 ) && GT_32( st->core_brate, SID_2k40 ) && ( ( last_core_brate_st0 == FRAME_NO_DATA ) || EQ_32( last_core_brate_st0, SID_2k40 ) ) && st->hTcxDec != NULL ) - { - /* Last frame was Stereo CNG and the synthesis memory is outdated -- reset */ - set16_fx( st->hTcxDec->old_syn_Overl, 0, L_FRAME32k / 2 ); - set16_fx( st->hFdCngDec->hFdCngCom->olapBufferAna_fx, 0, FFTLEN ); - set16_fx( st->agc_mem_fx, 0, 2 ); - } - st->mem_deemph_fx = 0; - move16(); - IF( !st->last_con_tcx ) - { - set16_fx( st->mem_syn2_fx, 0, M ); - } - set16_fx( st->mem_syn1_fx, 0, M ); - if ( st->hBWE_TD != NULL ) - { - st->hBWE_TD->bwe_non_lin_prev_scale_fx = 0; - move32(); - } - - /* Reset ACELP parameters */ - set16_fx( st->mem_MA_fx, 0, M ); - - IF( EQ_32( st->sr_core, INT_FS_16k ) ) - { - Copy( GEWB2_Ave_fx, st->mem_AR_fx, M ); - } - ELSE - { - Copy( GEWB_Ave_fx, st->mem_AR_fx, M ); - } - - st->tilt_code_fx = 0; - st->gc_threshold_fx = 0; - st->dm_fx.prev_gain_code = 0; - st->dm_fx.prev_state = 0; - move16(); - move32(); - move32(); - move16(); - set16_fx( st->dm_fx.prev_gain_pit, 0, 6 ); - - st->last_coder_type = GENERIC; - move16(); - - fer_energy_fx( output_frame, UNVOICED_CLAS, st->previoussynth_fx_32, 0, -1, &st->enr_old_fx, 1 ); /*Q-0*/ - st->lp_gainp_fx = 0; - move16(); - st->lp_gainc_fx = extract_h( Sqrt32( st->lp_ener_fx, &exp ) ); /*Q=15-exp*/ - move16(); - st->lp_gainc_fx = shr( st->lp_gainc_fx, sub( 12, exp ) ); /*Q3*/ - move16(); - - st->last_voice_factor_fx = 0; - st->Last_GSC_noisy_speech_flag = 0; - move16(); - move16(); - - /* reset CLDFB memories */ - cldfb_reset_memory_fx( st->cldfbAna ); - cldfb_reset_memory_fx( st->cldfbBPF ); - cldfb_reset_memory_fx( st->cldfbSyn ); - - /* reset TBE memories */ - test(); - test(); - IF( !st->last_con_tcx && !( ( EQ_16( st->last_core, HQ_CORE ) ) && ( st->element_mode > EVS_MONO ) ) ) - { - set16_fx( st->old_exc_fx, 0, L_EXC_MEM_DEC ); - } - ELSE IF( LT_16( st->L_frame, L_FRAME16k ) ) - { - /* resample from 16kHz to 12.8kHZ */ - synth_mem_updt2( st->L_frame, L_FRAME16k, st->old_exc_fx, st->mem_syn_r, st->mem_syn2_fx, NULL, DEC ); - } - - IF( st->hBWE_TD != NULL ) - { - set16_fx( st->hBWE_TD->old_bwe_exc_fx, 0, PIT16k_MAX * 2 ); - } - - test(); - IF( GT_32( st->output_Fs, 16000 ) && st->hBWE_zero != NULL ) - { - hf_synth_reset_fx( st->hBWE_zero ); -#ifdef MSAN_FIX - set16_fx( st->hBWE_zero->mem_hp400_fx, 0, 6 ); -#endif - } - - IF( st->hBWE_FD != NULL ) - { - set16_fx( st->hBWE_FD->old_syn_12k8_16k_fx, 0, NS2SA( 16000, DELAY_FD_BWE_ENC_NS ) ); - } - } - - test(); - test(); - test(); - IF( ( ( st->core == ACELP_CORE ) || EQ_16( st->core, AMR_WB_CORE ) ) && ( EQ_16( st->last_core, TCX_20_CORE ) || EQ_16( st->last_core, TCX_10_CORE ) ) ) - { - IF( st->hBWE_TD != NULL ) - { - st->hBWE_TD->bwe_non_lin_prev_scale_fx = 0; - move32(); - set16_fx( st->hBWE_TD->old_bwe_exc_fx, 0, PIT16k_MAX * 2 ); - } - - st->tilt_code_fx = 0; - st->gc_threshold_fx = 0; - st->dm_fx.prev_gain_code = 0; - st->dm_fx.prev_state = 0; - move16(); - move32(); - move32(); - move16(); - set16_fx( st->dm_fx.prev_gain_pit, 0, 6 ); - st->last_coder_type = GENERIC; - move16(); - fer_energy_fx( output_frame, UNVOICED_CLAS, st->previoussynth_fx_32, 0, -1, &st->enr_old_fx, 1 ); /*Q-0*/ - - st->lp_gainp_fx = 0; - move16(); - st->lp_gainc_fx = extract_h( Sqrt32( st->lp_ener_fx, &exp ) ); /*Q=15-exp*/ - move16(); - st->lp_gainc_fx = shr( st->lp_gainc_fx, sub( 12, exp ) ); /*Q3*/ - move16(); - - st->last_voice_factor_fx = 0; - st->Last_GSC_noisy_speech_flag = 0; - move16(); - move16(); - - test(); - IF( GT_32( st->output_Fs, 16000 ) && st->hBWE_zero != NULL ) - { - hf_synth_reset_fx( st->hBWE_zero ); -#ifdef MSAN_FIX - set16_fx( st->hBWE_zero->mem_hp400_fx, 0, 6 ); -#endif - } - - IF( st->hBWE_FD != NULL ) - { - set16_fx( st->hBWE_FD->old_syn_12k8_16k_fx, 0, NS2SA( 16000, DELAY_FD_BWE_ENC_NS ) ); - } - - test(); - test(); - test(); - IF( EQ_16( nchan_out, 1 ) && EQ_16( st->element_mode, IVAS_CPE_DFT ) && LE_32( st->element_brate, IVAS_24k4 ) && GT_32( last_element_brate, IVAS_24k4 ) ) - { - /* update cldbf state with previous frame TCX synthesis when going from a bitrate with residual coding to a bitrate without it */ - Word16 offset; - offset = sub( st->cldfbAna->p_filter_length, st->cldfbAna->no_channels ); - Word32 *old_synthFB_fx; - IF( ( old_synthFB_fx = (Word32 *) malloc( st->hTcxDec->old_synth_lenFB * sizeof( Word32 ) ) ) == NULL ) - { - return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Cannot allocate memory for old_synth_lenFB (32 bit) \n" ) ); - } - Copy_Scale_sig_16_32( st->hTcxDec->old_synthFB_fx, old_synthFB_fx, st->hTcxDec->old_synth_lenFB, sub( Q10, Q_old_synthFB ) ); // Q10 - Copy32( old_synthFB_fx + st->hTcxDec->old_synth_lenFB - offset, st->cldfbAna->cldfb_state_fx, offset ); - st->cldfbAna->Q_cldfb_state = Q10; - move16(); - IF( old_synthFB_fx ) - free( old_synthFB_fx ); - } - } - - test(); - test(); - test(); - test(); - IF( EQ_16( st->core, HQ_CORE ) && ( ( st->last_core == ACELP_CORE ) || EQ_16( st->last_core, AMR_WB_CORE ) || ( ( ( st->element_mode != EVS_MONO ) ) && ( NE_16( st->last_core, HQ_CORE ) ) ) ) ) - { - set32_fx( st->hHQ_core->prev_env_fx, 0, SFM_N_WB ); - set32_fx( st->hHQ_core->prev_normq_fx, 0, SFM_N_WB ); - - set32_fx( st->hHQ_core->last_ni_gain_fx, 0, BANDS_MAX ); - set16_fx( st->hHQ_core->last_env_fx, 0, BANDS_MAX ); - st->hHQ_core->last_max_pos_pulse = 0; - move16(); - - set16_fx( st->hHQ_core->prev_SWB_peak_pos, 0, SPT_SHORTEN_SBNUM ); - st->hHQ_core->prev_frm_hfe2 = 0; - st->hHQ_core->prev_stab_hfe2 = 0; - move16(); - move16(); - IF( GT_32( st->output_Fs, 16000 ) ) - { - set32_fx( st->hHQ_core->prev_coeff_out_fx, 0, L_HQ_WB_BWE ); - } - - IF( st->element_mode != EVS_MONO ) - { - /* Estimate mem_env_delta to reinit env_stab */ - tmp_fx = L_max( 0, L_add( ENV_STAB_EST1_FX, L_add( Mult_32_16( st->stab_fac_smooth_lt_fx, ENV_STAB_EST2_FX ), Mult_32_16( st->log_energy_diff_lt_fx, ENV_STAB_EST3_FX ) ) ) ); /*Q12*/ - - st->hHQ_core->mem_env_delta = extract_l( L_min( MAX16B, tmp_fx ) ); /* Convert to Q12 and handle saturation */ - move16(); - test(); - IF( NE_16( st->last_core, TCX_20_CORE ) && NE_16( st->last_core, TCX_10_CORE ) ) - { - set16_fx( st->hHQ_core->old_out_fx, 0, output_frame ); - set32_fx( st->hHQ_core->old_outLB_fx, 0, L_FRAME16k ); - set16_fx( st->hHQ_core->old_out_LB_fx, 0, L_FRAME16k ); - } - - st->hHQ_core->no_att_hangover = 0; - move16(); - st->hHQ_core->energy_lt_fx = 2457600; /*300.0f Q13*/ - move32(); - set16_fx( st->hHQ_core->old_is_transient, 0, 3 ); - set16_fx( st->hHQ_core->prev_noise_level_fx, 0, 2 ); - st->hHQ_core->prev_R = 0; - move16(); - set16_fx( st->hHQ_core->mem_norm + 1, 39, SFM_N_ENV_STAB - 1 ); - st->hHQ_core->prev_hqswb_clas = HQ_NORMAL; - st->hHQ_core->prev_ni_ratio_fx = 16384; /*Q15*/ - move16(); - move16(); - set16_fx( st->hHQ_core->prev_En_sb_fx, 0, NB_SWB_SUBBANDS ); - } - ELSE - { - set16_fx( st->hHQ_core->old_out_fx, 0, output_frame ); - set32_fx( st->hHQ_core->old_outLB_fx, 0, L_FRAME16k ); - } - } - - /* handle switching cases where preecho_sb was not called in the last frame (memory not up to date) */ - IF( st->hHQ_core != NULL ) - { - st->hHQ_core->pastpre = sub( st->hHQ_core->pastpre, 1 ); - move16(); - IF( st->hHQ_core->pastpre < 0 ) - { - reset_preecho_dec_fx( st->hHQ_core ); - } - } - test(); - IF( st->core_brate == FRAME_NO_DATA ) - { - st->VAD = 0; - st->m_frame_type = ZERO_FRAME; - } - ELSE IF( EQ_32( st->core_brate, SID_2k40 ) || EQ_32( st->core_brate, SID_1k75 ) ) - { - st->VAD = 0; - st->m_frame_type = SID_FRAME; - } - ELSE - { - st->VAD = 1; - st->m_frame_type = ACTIVE_FRAME; - } - - move16(); - move16(); - /*switch on CNA on active frames*/ - IF( ( st->element_mode == EVS_MONO ) ) /* for IVAS modes, st->flag_cna is set earlier */ - { - test(); - test(); - test(); - test(); - test(); - test(); - IF( st->VAD && ( ( NE_16( st->core, AMR_WB_CORE ) && LE_32( st->total_brate, CNA_MAX_BRATE ) ) || ( EQ_16( st->core, AMR_WB_CORE ) && LE_32( st->total_brate, ACELP_8k85 ) ) ) ) - { - st->flag_cna = 1; - move16(); - } - ELSE IF( st->VAD || ( EQ_16( st->cng_type, FD_CNG ) && EQ_16( st->L_frame, L_FRAME16k ) ) ) - { - st->flag_cna = 0; - move16(); - } - } - - if ( EQ_16( st->core, AMR_WB_CORE ) ) - { - st->cng_type = LP_CNG; - move16(); - } - - /* Reconfigure CNG */ - test(); - test(); - test(); - test(); - IF( st->hFdCngDec && ( NE_16( st->last_L_frame, st->L_frame ) || NE_16( st->hFdCngDec->hFdCngCom->frameSize, st->L_frame ) || ( st->ini_frame == 0 ) || NE_16( st->bwidth, st->last_bwidth ) ) ) - { - /* || st->last_core == AMR_WB_CORE || st->last_codec_mode == MODE2)){*/ - IF( NE_16( st->core, AMR_WB_CORE ) ) - { - test(); - IF( EQ_16( st->rf_flag, 1 ) && EQ_32( st->total_brate, ACELP_13k20 ) ) - { - configureFdCngDec_ivas_fx( st->hFdCngDec, st->bwidth, ACELP_9k60, st->L_frame, st->last_L_frame, st->element_mode ); - } - ELSE - { - configureFdCngDec_ivas_fx( st->hFdCngDec, st->bwidth, st->total_brate, st->L_frame, st->last_L_frame, st->element_mode ); - } - } - ELSE - { - configureFdCngDec_ivas_fx( st->hFdCngDec, WB, ACELP_8k00, st->L_frame, st->last_L_frame, st->element_mode ); - - if ( st->VAD ) - { - st->hFdCngDec->hFdCngCom->CngBitrate = st->total_brate; - move32(); - } - } - test(); - test(); - IF( NE_16( st->last_L_frame, st->L_frame ) && LE_16( st->L_frame, L_FRAME16k ) && LE_16( st->last_L_frame, L_FRAME16k ) ) - { - test(); - IF( EQ_16( st->element_mode, IVAS_CPE_DFT ) || EQ_16( st->element_mode, IVAS_CPE_TD ) ) - { - lerp( st->hFdCngDec->hFdCngCom->olapBufferAna_fx + st->last_L_frame, st->hFdCngDec->hFdCngCom->olapBufferAna_fx + st->L_frame, st->L_frame, st->last_L_frame ); - } - - L_lerp_fx( st->hFdCngDec->hFdCngCom->olapBufferSynth2_fx, st->hFdCngDec->hFdCngCom->olapBufferSynth2_fx, shl( st->L_frame, 1 ), shl( st->last_L_frame, 1 ), Q_olapBufferSynth2 ); - - test(); - IF( LE_32( st->total_brate, SID_2k40 ) && LE_32( st->last_total_brate, SID_2k40 ) ) - { - L_lerp_fx( st->hFdCngDec->hFdCngCom->olapBufferSynth_fx, st->hFdCngDec->hFdCngCom->olapBufferSynth_fx, shl( st->L_frame, 1 ), shl( st->last_L_frame, 1 ), Q_olapBufferSynth ); - - IF( EQ_16( st->L_frame, L_FRAME ) ) - { - FOR( i = 0; i < ( st->L_frame * 2 ); i++ ) - { - st->hFdCngDec->hFdCngCom->olapBufferSynth_fx[i] = Mult_32_16( st->hFdCngDec->hFdCngCom->olapBufferSynth_fx[i], (Word16) 20480 /* 0.6250f in Q15 */ ); - move32(); - } - } - ELSE - { - FOR( i = 0; i < ( st->L_frame * 2 ); i++ ) - { - st->hFdCngDec->hFdCngCom->olapBufferSynth_fx[i] = Mult_32_16( L_shl( st->hFdCngDec->hFdCngCom->olapBufferSynth_fx[i], 1 ), (Word16) 26214 /* 1.6f in Q14 */ ); - move32(); - } - } - } - } - } - - return error; -} -/*---------------------------------------------------------------------* - * core_switching_hq_prepare_dec() - * - * Preprocessing in the first HQ frame after ACELP frame - * Modify bit allocation for HQ core by removing ACELP subframe budget - *---------------------------------------------------------------------*/ - -/*---------------------------------------------------------------------* - * bandwidth_switching_detect() - * - * Classification for band-width switching - *---------------------------------------------------------------------*/ - -void bandwidth_switching_detect_ivas_fx( - Decoder_State *st_fx /* i/o: encoder state structure */ -) -{ - test(); - test(); - IF( ( EQ_16( st_fx->element_mode, IVAS_CPE_TD ) && EQ_16( st_fx->idchan, 1 ) ) || EQ_16( st_fx->element_mode, IVAS_CPE_MDCT ) ) - { - /* there is no BWE in TD stereo secondary channel and in MDCT stereo, IGF is part of the core decoding -> no BW switching -> reset BWS counters */ - st_fx->prev_bws_cnt = 0; - st_fx->bws_cnt = 0; - st_fx->bws_cnt1 = 0; - move16(); - move16(); - move16(); - - return; - } - /* update band-width switching counter */ - test(); - test(); - test(); - test(); - IF( GE_16( st_fx->bws_cnt1, N_NS2W_FRAMES ) ) - { - st_fx->bws_cnt1 = 0; - move16(); - } - ELSE IF( GT_32( st_fx->total_brate, ACELP_9k60 ) && LT_32( st_fx->last_core_brate, ACELP_9k60 ) && EQ_16( st_fx->bwidth, SWB ) && EQ_16( st_fx->last_bwidth, WB ) && ( st_fx->last_low_rate_mode == 0 ) ) - { - st_fx->bws_cnt1 = add( st_fx->bws_cnt1, 1 ); - move16(); - } - ELSE IF( st_fx->bws_cnt1 > 0 ) - { - IF( LT_16( st_fx->bwidth, st_fx->last_bwidth ) ) - { - st_fx->bws_cnt = sub( shl( sub( N_NS2W_FRAMES, st_fx->bws_cnt1 ), 1 ), 1 ); - move16(); - } - ELSE - { - st_fx->bws_cnt = 0; - move16(); - } - - IF( LT_16( st_fx->bwidth, st_fx->last_bwidth ) ) - { - st_fx->bws_cnt1 = 0; - move16(); - } - ELSE - { - IF( EQ_16( st_fx->bwidth, SWB ) ) - { - st_fx->bws_cnt1 = add( st_fx->bws_cnt1, 1 ); - move16(); - } - ELSE - { - st_fx->bws_cnt1 = 0; - move16(); - } - } - } - - /* update band-width switching counter */ - test(); - test(); - test(); - IF( GE_16( st_fx->bws_cnt, N_WS2N_FRAMES ) ) - { - st_fx->bws_cnt = 0; - move16(); - } - ELSE IF( LT_32( st_fx->total_brate, ACELP_9k60 ) && GT_32( st_fx->last_core_brate, ACELP_9k60 ) && LT_16( st_fx->bwidth, st_fx->last_bwidth ) && EQ_16( st_fx->bwidth, WB ) ) - { - st_fx->bws_cnt = add( st_fx->bws_cnt, 1 ); - move16(); - } - ELSE IF( st_fx->bws_cnt > 0 ) - { - IF( GT_16( st_fx->bwidth, st_fx->last_bwidth ) ) - { - st_fx->bws_cnt1 = shr( sub( N_WS2N_FRAMES, st_fx->bws_cnt ), 1 ); - move16(); - } - ELSE - { - st_fx->bws_cnt1 = 0; - move16(); - } - - IF( GT_16( st_fx->bwidth, st_fx->last_bwidth ) ) - { - st_fx->bws_cnt = 0; - move16(); - } - ELSE - { - IF( EQ_16( st_fx->bwidth, WB ) ) - { - st_fx->bws_cnt = add( st_fx->bws_cnt, 1 ); - move16(); - } - ELSE - { - st_fx->bws_cnt = 0; - move16(); - } - } - } - - return; -} - - -/*---------------------------------------------------------------------* - * bw_switching_pre_proc() - * - * Band-width switching pre-processing - *---------------------------------------------------------------------*/ -void ivas_bw_switching_pre_proc_fx( - Decoder_State *st, /* i/o: decoder state structure */ - const Word32 last_element_brate, /* i : last element bitrate */ - const Word16 nchan_out /* i : number of output channels */, - Word32 *old_syn_12k8_16k_fx, - Word16 Q, - Word16 Q_audio ) -{ - Word16 i; - Word32 syn_dct_fx[L_FRAME]; - - - Flag Overflow = 0; - move32(); - - IF( st->element_mode > EVS_MONO ) - { - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - IF( ( st->core == ACELP_CORE ) && !( EQ_16( st->bfi, 1 ) && EQ_16( st->con_tcx, 1 ) ) && st->hBWE_FD != NULL && !( LE_32( st->core_brate, SID_2k40 ) && EQ_16( st->element_mode, IVAS_CPE_DFT ) && EQ_16( nchan_out, 2 ) ) && !( EQ_16( st->element_mode, IVAS_CPE_MDCT ) && EQ_16( nchan_out, 1 ) && EQ_16( st->idchan, 1 ) && LE_32( last_element_brate, IVAS_SID_5k2 ) ) ) - { - /* Calculate tilt of the ACELP core synthesis - needed in SWB BWE decoding */ - Word16 old_syn_12k8_16k_tmp_16fx[L_FRAME16k]; - Copy_Scale_sig_32_16( old_syn_12k8_16k_fx, old_syn_12k8_16k_tmp_16fx, st->L_frame, sub( -1, Q ) ); - st->tilt_wb_fx = round_fx_sat( L_shl_sat( calc_tilt_bwe_fx( old_syn_12k8_16k_tmp_16fx, -1, st->L_frame ), sub( Q, 8 ) ) ); // Q24+(Q-8) - 16 - move16(); - } - - return; - } - - - test(); - test(); - IF( ( st->core == ACELP_CORE ) && !( EQ_16( st->bfi, 1 ) && EQ_16( st->con_tcx, 1 ) ) ) - { - /*----------------------------------------------------------------------* - * Calculate tilt of the ACELP core synthesis - *----------------------------------------------------------------------*/ - - st->tilt_wb_fx = ivas_calc_tilt_bwe_fx( old_syn_12k8_16k_fx, Q, st->L_frame ); - move16(); - /*-------------------------------------------------------------------------------* - * Calculate frequency energy of 0~3.2kHz and 3.2~6.4kHz the ACELP core synthesis - *-------------------------------------------------------------------------------*/ - edct_fx( old_syn_12k8_16k_fx, syn_dct_fx, L_FRAME, &Q ); - Word64 W_tmp = 0; - move64(); - Word32 tmp; - Word16 shift; - FOR( i = 0; i < L_FRAME / 2; i++ ) - { - W_tmp = W_add( W_tmp, W_shr( W_mult0_32_32( syn_dct_fx[i], syn_dct_fx[i] ), Q ) ); - } - shift = W_norm( W_tmp ); - W_tmp = W_shl( W_tmp, shift ); - tmp = W_extract_h( W_tmp ); - tmp = L_shr( tmp, 8 ); - - tmp = getSqrtWord32( tmp ); - st->enerLL_fx = tmp; - move32(); - st->enerLL_fx_Q = shr( sub( add( Q, shift ), 32 ), 1 ); - move16(); - W_tmp = 0; - move64(); - FOR( ; i < L_FRAME; i++ ) - { - W_tmp = W_add( W_tmp, W_shr( W_mult0_32_32( syn_dct_fx[i], syn_dct_fx[i] ), Q ) ); - } - shift = W_norm( W_tmp ); - W_tmp = W_shl( W_tmp, shift ); - tmp = W_extract_h( W_tmp ); // Q = Q + shift - 32 - tmp = L_shr( tmp, 7 ); // divide by 128 - tmp = getSqrtWord32( tmp ); - st->enerLH_fx = tmp; - move32(); - st->enerLH_fx_Q = shr( sub( add( Q, shift ), 32 ), 1 ); - move16(); - } - ELSE - { - IF( st->hHQ_core->old_is_transient[0] ) - { - Word32 tmp, L_tmp = 0; - move32(); - FOR( i = 0; i < 32; i++ ) - { - L_tmp = L_mac0_o( L_tmp, st->t_audio_q_fx[i], st->t_audio_q_fx[i], &Overflow ); - } - tmp = L_shr( L_tmp, 5 ); // divide by 32 - tmp = getSqrtWord32( tmp ); - st->enerLL_fx = tmp; - move32(); - st->enerLL_fx_Q = Q_audio; - move16(); - - L_tmp = 0; - move32(); - FOR( ; i < 64; i++ ) - { - L_tmp = L_mac0_o( L_tmp, st->t_audio_q_fx[i], st->t_audio_q_fx[i], &Overflow ); - } - - tmp = L_shr( L_tmp, 5 ); // divide by 32 - tmp = getSqrtWord32( tmp ); - st->enerLH_fx = tmp; - move32(); - st->enerLH_fx_Q = Q_audio; - move16(); - } - ELSE - { - Word32 tmp, L_tmp = 0; - move32(); - FOR( i = 0; i < L_FRAME / 2; i++ ) - { - L_tmp = L_mac0_o( L_tmp, st->t_audio_q_fx[i], st->t_audio_q_fx[i], &Overflow ); - } - tmp = L_shr( L_tmp, 5 ); // divide by 32 - tmp = getSqrtWord32( tmp ); - st->enerLL_fx = tmp; - move32(); - st->enerLL_fx_Q = Q_audio; - move16(); - - L_tmp = 0; - move32(); - FOR( ; i < L_FRAME; i++ ) - { - L_tmp = L_mac0_o( L_tmp, st->t_audio_q_fx[i], st->t_audio_q_fx[i], &Overflow ); - } - tmp = L_shr( L_tmp, 5 ); // divide by 32 - tmp = getSqrtWord32( tmp ); - st->enerLL_fx = tmp; - move32(); - st->enerLL_fx_Q = Q_audio; - move16(); - } - } - - test(); - test(); - test(); - test(); - test(); - test(); - test(); - IF( EQ_16( st->last_bwidth, 0 ) && LE_16( st->extl, SWB_CNG ) ) - { - - st->prev_ener_shb_fx = 0; - move16(); - IF( st->hBWE_FD != NULL ) - { - set16_fx( st->prev_SWB_fenv_fx, 0, SWB_FENV ); - } - } - ELSE IF( ( ( ( st->core == ACELP_CORE ) && ( EQ_16( st->last_core, HQ_CORE ) || EQ_16( st->last_core, TCX_10_CORE ) || EQ_16( st->last_core, TCX_20_CORE ) ) ) || ( EQ_16( st->core, st->last_core ) && NE_16( st->extl, st->last_extl ) ) ) && GE_16( st->last_bwidth, SWB ) ) - { - st->attenu_fx = 3277; // 0.1f in Q15 - move16(); - } - - test(); - test(); - test(); - test(); - test(); - if ( EQ_16( st->last_core, HQ_CORE ) || ( ( st->last_core == ACELP_CORE ) && !( EQ_16( st->last_extl, WB_TBE ) || EQ_16( st->last_extl, SWB_TBE ) || EQ_16( st->last_extl, FB_TBE ) ) && GT_32( st->core_brate, ACELP_8k00 ) ) ) - { - st->prev_fractive = 0; - move16(); - } - - return; -} -/*---------------------------------------------------------------------* - * core_switch_lb_upsamp() - * - * Resample HQ/TCX-LB to the output sampling rate (8/16/32/48 kHz) - *---------------------------------------------------------------------*/ - - -/*---------------------------------------------------------------------* - * smoothTransitionDtxToTcx() - * - * apply smoothing to the transition part for inactive to active transitions in DTX - *---------------------------------------------------------------------*/ - -#define TRANSITION_SMOOTHING_LEN_16k 15 -#define TRANSITION_SMOOTHING_LEN_32k 31 -#define TRANSITION_SMOOTHING_LEN_48k 47 diff --git a/lib_dec/core_switching_dec_fx.c b/lib_dec/core_switching_dec_fx.c index bd7d53bc66a32206b5d4f9104111c346526e6289..0f361e658628093c61be18cd92a839371e0d868b 100644 --- a/lib_dec/core_switching_dec_fx.c +++ b/lib_dec/core_switching_dec_fx.c @@ -16,10 +16,6 @@ * * *---------------------------------------------------------------------*/ -#ifdef IVAS_CODE_SWITCHING -static void core_switch_lb_upsamp( Decoder_State *st, float *output ); -static void smoothTransitionDtxToTcx( float synth[], const int16_t output_frame, const int16_t delay_comp ); -#endif static void smoothTransitionDtxToTcx_fx( Word16 synth[], const Word16 output_frame, const Word16 delay_comp ); static void core_switch_lb_upsamp_fx( Decoder_State *st, Word32 *output ); @@ -189,30 +185,11 @@ void bw_switching_pre_proc_fx( Flag Overflow = 0; move32(); #endif -#ifdef IVAS_CODE_SWITCHING + IF( st_fx->element_mode > EVS_MONO ) { - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - IF( EQ_16( st_fx->core, ACELP_CORE ) && !( EQ_16( st_fx->bfi, 1 ) && EQ_16( st_fx->con_tcx, 1 ) ) && - st_fx->hBWE_FD != NULL && !( LE_16( st_fx->core_brate, SID_2k40 ) && EQ_16( st_fx->element_mode, IVAS_CPE_DFT ) && EQ_16( nchan_out, 2 ) ) && - !( EQ_16( st_fx->element_mode, IVAS_CPE_MDCT ) && EQ_16( nchan_out, 1 ) && EQ_16( st_fx->idchan, 1 ) && LE_16( last_element_brate, IVAS_SID_4k4 ) ) ) - { - /* Calculate tilt of the ACELP core synthesis - needed in SWB BWE decoding */ - calc_tilt_bwe( old_syn_12k8_16k, &st->tilt_wb, st->L_frame ); - } - - return; } -#endif + test(); test(); IF( EQ_16( st_fx->core, ACELP_CORE ) && !( EQ_16( st_fx->bfi, 1 ) && EQ_16( st_fx->con_tcx, 1 ) ) ) @@ -221,12 +198,8 @@ void bw_switching_pre_proc_fx( * Calculate tilt of the ACELP core synthesis *----------------------------------------------------------------------*/ -#ifdef BASOP_NOGLOB st_fx->tilt_wb_fx = round_fx_o( L_shl_o( calc_tilt_bwe_fx( old_syn_12k8_16k_fx, -1, st_fx->L_frame ), 3, &Overflow ), &Overflow ); /* Q11 */ move16(); -#else - st_fx->tilt_wb_fx = round_fx( L_shl( calc_tilt_bwe_fx( old_syn_12k8_16k_fx, -1, st_fx->L_frame ), 3 ) ); -#endif /*-------------------------------------------------------------------------------* * Calculate frequency energy of 0~3.2kHz and 3.2~6.4kHz the ACELP core synthesis *-------------------------------------------------------------------------------*/ @@ -236,11 +209,7 @@ void bw_switching_pre_proc_fx( L_tmp = L_deposit_l( 0 ); FOR( i = 0; i < L_FRAME / 2; i++ ) { -#ifdef BASOP_NOGLOB L_tmp = L_mac0_o( L_tmp, syn_dct_fx[i], syn_dct_fx[i], &Overflow ); /* (2 * Q_syn2) */ -#else - L_tmp = L_mac0( L_tmp, syn_dct_fx[i], syn_dct_fx[i] ); -#endif } L_tmp = L_shr( L_tmp, 7 ); /* 2 * Q_syn2 */ st_fx->enerLL_fx = Calc_freq_ener_fx( L_tmp, shl( st_fx->Q_syn2, 1 ) ); /* Q_syn2 */ @@ -248,11 +217,7 @@ void bw_switching_pre_proc_fx( L_tmp = L_deposit_l( 0 ); FOR( ; i < L_FRAME; i++ ) { -#ifdef BASOP_NOGLOB L_tmp = L_mac0_o( L_tmp, syn_dct_fx[i], syn_dct_fx[i], &Overflow ); -#else - L_tmp = L_mac0( L_tmp, syn_dct_fx[i], syn_dct_fx[i] ); -#endif } L_tmp = L_shr( L_tmp, 7 ); /* 2 * Q_syn2 */ st_fx->enerLH_fx = Calc_freq_ener_fx( L_tmp, shl( st_fx->Q_syn2, 1 ) ); /* Q_syn2 */ @@ -265,11 +230,7 @@ void bw_switching_pre_proc_fx( L_tmp = L_deposit_l( 0 ); FOR( i = 0; i < 32; i++ ) { -#ifdef BASOP_NOGLOB L_tmp = L_mac0_o( L_tmp, st_fx->t_audio_q_fx[i], st_fx->t_audio_q_fx[i], &Overflow ); /* 2 * Q_syn2 */ -#else - L_tmp = L_mac0( L_tmp, st_fx->t_audio_q_fx[i], st_fx->t_audio_q_fx[i] ); -#endif } L_tmp = L_shr( L_tmp, 5 ); /* 2 * Q_syn2 */ st_fx->enerLL_fx = Calc_freq_ener_fx( L_tmp, shl( st_fx->Q_syn2, 1 ) ); /* Q_syn2 */ @@ -277,11 +238,7 @@ void bw_switching_pre_proc_fx( L_tmp = L_deposit_l( 0 ); FOR( ; i < 64; i++ ) { -#ifdef BASOP_NOGLOB L_tmp = L_mac0_o( L_tmp, st_fx->t_audio_q_fx[i], st_fx->t_audio_q_fx[i], &Overflow ); /* 2 * Q_syn2 */ -#else - L_tmp = L_mac0( L_tmp, st_fx->t_audio_q_fx[i], st_fx->t_audio_q_fx[i] ); -#endif } L_tmp = L_shr( L_tmp, 5 ); /* 2 * Q_syn2 */ st_fx->enerLH_fx = Calc_freq_ener_fx( L_tmp, shl( st_fx->Q_syn2, 1 ) ); /* Q_syn2 */ @@ -292,11 +249,7 @@ void bw_switching_pre_proc_fx( L_tmp = L_deposit_l( 0 ); FOR( i = 0; i < L_FRAME / 2; i++ ) { -#ifdef BASOP_NOGLOB L_tmp = L_mac0_o( L_tmp, st_fx->t_audio_q_fx[i], st_fx->t_audio_q_fx[i], &Overflow ); /* 2 * Q_syn2 */ -#else - L_tmp = L_mac0( L_tmp, st_fx->t_audio_q_fx[i], st_fx->t_audio_q_fx[i] ); -#endif } L_tmp = L_shr( L_tmp, 7 ); /* 2 * Q_syn2 */ st_fx->enerLL_fx = Calc_freq_ener_fx( L_tmp, shl( st_fx->Q_syn2, 1 ) ); /* Q_syn2 */ @@ -304,11 +257,7 @@ void bw_switching_pre_proc_fx( L_tmp = L_deposit_l( 0 ); FOR( ; i < L_FRAME; i++ ) { -#ifdef BASOP_NOGLOB L_tmp = L_mac0_o( L_tmp, st_fx->t_audio_q_fx[i], st_fx->t_audio_q_fx[i], &Overflow ); /* 2 * Q_syn2 */ -#else - L_tmp = L_mac0( L_tmp, st_fx->t_audio_q_fx[i], st_fx->t_audio_q_fx[i] ); -#endif } L_tmp = L_shr( L_tmp, 7 ); /* 2 * Q_syn2 */ st_fx->enerLH_fx = Calc_freq_ener_fx( L_tmp, shl( st_fx->Q_syn2, 1 ) ); /* Q_syn2 */ @@ -349,149 +298,7 @@ void bw_switching_pre_proc_fx( return; } -#ifdef IVAS_CODE_SWITCHING - - -/*---------------------------------------------------------------------* - * core_switch_lb_upsamp() - * - * Resample HQ/TCX-LB to the output sampling rate (8/16/32/48 kHz) - *---------------------------------------------------------------------*/ - -static void core_switch_lb_upsamp( - Decoder_State *st, /* i/o: Decoder state */ - float *output /* i/o: LB synth/upsampled LB synth */ -) -{ - int16_t i; - float *realBuffer[CLDFB_OVRLP_MIN_SLOTS], *imagBuffer[CLDFB_OVRLP_MIN_SLOTS]; - float realBufferTmp[CLDFB_OVRLP_MIN_SLOTS][CLDFB_NO_CHANNELS_MAX]; - float imagBufferTmp[CLDFB_OVRLP_MIN_SLOTS][CLDFB_NO_CHANNELS_MAX]; - - /* open CLDFB buffer up to CLDFB_NO_CHANNELS_MAX bands for 48kHz */ - for ( i = 0; i < CLDFB_OVRLP_MIN_SLOTS; i++ ) - { - set_f( realBufferTmp[i], 0, CLDFB_NO_CHANNELS_MAX ); - set_f( imagBufferTmp[i], 0, CLDFB_NO_CHANNELS_MAX ); - realBuffer[i] = realBufferTmp[i]; - imagBuffer[i] = imagBufferTmp[i]; - } - - /* check if the CLDFB works on the right sample rate */ - if ( ( st->cldfbAna->no_channels * st->cldfbAna->no_col ) != st->L_frame ) - { - resampleCldfb( st->cldfbAna, st->L_frame * FRAMES_PER_SEC ); - - if ( st->cldfbBPF != NULL && st->L_frame <= L_FRAME16k ) - { - resampleCldfb( st->cldfbBPF, st->L_frame * FRAMES_PER_SEC ); - } - - if ( st->ini_frame > 0 ) - { - st->cldfbSyn->bandsToZero = st->cldfbSyn->no_channels - st->cldfbAna->no_channels; - } - } - - /* analysis of the synthesis at internal sampling rate */ - cldfbAnalysis( output, realBuffer, imagBuffer, CLDFB_OVRLP_MIN_SLOTS * st->cldfbAna->no_channels, st->cldfbAna ); - - /* analysis and add the BPF error signal */ - if ( st->p_bpf_noise_buf ) - { - addBassPostFilter( st->p_bpf_noise_buf, st->bpf_off ? 0 : CLDFB_OVRLP_MIN_SLOTS * st->cldfbBPF->no_channels, realBuffer, imagBuffer, st->cldfbBPF ); - } - - /* set output mask for upsampling */ - if ( st->bwidth == NB ) - { - /* set NB mask for upsampling */ - st->cldfbSyn->bandsToZero = st->cldfbSyn->no_channels - 10; - } - else if ( st->cldfbSyn->bandsToZero != st->cldfbSyn->no_channels - st->cldfbAna->no_channels ) - { - /* in case of BW switching, re-init to default */ - st->cldfbSyn->bandsToZero = st->cldfbSyn->no_channels - st->cldfbAna->no_channels; - } - - /* synthesis of the combined signal */ - cldfbSynthesis( realBuffer, imagBuffer, output, CLDFB_OVRLP_MIN_SLOTS * st->cldfbSyn->no_channels, st->cldfbSyn ); - - /* save synthesis - needed in case of core switching */ - if ( st->hTcxDec != NULL ) - { - mvr2r( output, st->previoussynth, st->hTcxDec->L_frameTCX ); - } - - return; -} - -/*---------------------------------------------------------------------* - * smoothTransitionMdctStereoDtx() - * - * apply smoothing to the transition part for MDCT-Stereo DTX - *---------------------------------------------------------------------*/ - -#define TRANSITION_SMOOTHING_LEN_16k 15 -#define TRANSITION_SMOOTHING_LEN_32k 31 -#define TRANSITION_SMOOTHING_LEN_48k 47 - -static void smoothTransitionMdctStereoDtx( - float synth[], /* i/o: synthesis */ - const int16_t output_frame, /* i : output frame length */ - const int16_t delay_comp /* i : delay compensation in samples */ -) -{ - int16_t i, filter_len; - float w, mem, step, fade_in; - float smoothing_input_buffer[2 * NS2SA( 48000, DELAY_CLDFB_NS ) + TRANSITION_SMOOTHING_LEN_48k]; - float smoothing_out_buffer[2 * NS2SA( 48000, DELAY_CLDFB_NS ) + TRANSITION_SMOOTHING_LEN_48k]; - - filter_len = TRANSITION_SMOOTHING_LEN_16k; - if ( output_frame == L_FRAME32k ) - { - filter_len = TRANSITION_SMOOTHING_LEN_32k; - } - else if ( output_frame == L_FRAME48k ) - { - filter_len = TRANSITION_SMOOTHING_LEN_48k; - } - - /* prepare buffer */ - for ( i = 0; i < filter_len / 2; i++ ) - { - smoothing_input_buffer[i] = synth[0]; - } - mvr2r( synth, smoothing_input_buffer + filter_len / 2, 2 * delay_comp + filter_len / 2 ); - - /* apply Mean filter */ - w = 1.f / filter_len; - mem = sum_f( smoothing_input_buffer, filter_len ); - for ( i = 0; i < 2 * delay_comp; i++ ) - { - smoothing_out_buffer[i] = w * mem; - mem = mem - smoothing_input_buffer[i] + smoothing_input_buffer[i + filter_len]; - } - - /* apply fades around transition */ - step = 1.f / delay_comp; - fade_in = 0.f; - for ( i = 0; i < delay_comp; i++ ) - { - synth[i] = smoothing_out_buffer[i] * fade_in + synth[i] * ( 1 - fade_in ); - fade_in += step; - } - - fade_in = 0.f; - for ( ; i < 2 * delay_comp; i++ ) - { - synth[i] = synth[i] * fade_in + smoothing_out_buffer[i] * ( 1 - fade_in ); - fade_in += step; - } - return; -} -#endif /*---------------------------------------------------------------------* * core_switching_pre_dec_fx() * @@ -766,13 +573,7 @@ ivas_error core_switching_pre_dec_fx( test(); test(); - IF( ( ( EQ_16( st_fx->core, ACELP_CORE ) || EQ_16( st_fx->core, AMR_WB_CORE ) ) && EQ_16( st_fx->last_core, HQ_CORE ) ) - //#ifdef IVAS_CODE_SWITCHING - // || ((EQ_16(st_fx->element_mode, IVAS_CPE_DFT) || EQ_16(st_fx->element_mode, IVAS_CPE_TD) || - // (EQ_16(st_fx->element_mode, IVAS_CPE_MDCT) && last_element_mode == IVAS_CPE_DFT)) && EQ_16(nchan_out,2) && - // NE_16(st_fx->core_brate, SID_2k40) && NE_16(st_fx->core_brate, FRAME_NO_DATA) && (EQ_16(last_core_brate_st0, FRAME_NO_DATA) || EQ_16(last_core_brate_st0, SID_2k40))) - //#endif - ) + IF( ( ( EQ_16( st_fx->core, ACELP_CORE ) || EQ_16( st_fx->core, AMR_WB_CORE ) ) && EQ_16( st_fx->last_core, HQ_CORE ) ) ) { test(); IF( EQ_16( st_fx->element_mode, IVAS_CPE_DFT ) || EQ_16( st_fx->element_mode, IVAS_CPE_TD ) ) @@ -798,14 +599,7 @@ ivas_error core_switching_pre_dec_fx( lsf2lsp_fx( st_fx->lsf_old_fx, st_fx->lsp_old_fx, M, INT_FS_FX ); } -#ifdef IVAS_CODE_SWITCHING - if ( ( st->element_mode == IVAS_CPE_DFT || st->element_mode == IVAS_CPE_TD ) && nchan_out == 2 && st->core_brate > SID_2k40 && ( last_core_brate_st0 == FRAME_NO_DATA || last_core_brate_st0 == SID_2k40 ) && st->hTcxDec != NULL ) - { - /* Last frame was Stereo CNG and the synthesis memory is outdated -- reset */ - set_f( st->hTcxDec->old_syn_Overl, 0.0f, L_FRAME32k / 2 ); - set_f( st->hFdCngDec->hFdCngCom->olapBufferAna, 0.0f, FFTLEN ); - } -#endif + set16_fx( st_fx->agc_mem_fx, 0, 2 ); st_fx->mem_deemph_fx = 0; move16(); @@ -904,47 +698,7 @@ ivas_error core_switching_pre_dec_fx( set16_fx( hBWE_FD->old_syn_12k8_16k_fx, 0, NS2SA_FX2( 16000, DELAY_FD_BWE_ENC_NS ) ); } } -#ifdef IVAS_CODE_SWITCHING - if ( ( st->core == ACELP_CORE || st->core == AMR_WB_CORE ) && ( st->last_core == TCX_20_CORE || st->last_core == TCX_10_CORE ) ) - { - if ( st->hBWE_TD != NULL ) - { - st->hBWE_TD->bwe_non_lin_prev_scale = 0.0f; - set_f( st->hBWE_TD->old_bwe_exc, 0, PIT16k_MAX * 2 ); - } - - st->tilt_code = 0.0f; - st->gc_threshold = 0.0f; - set_f( st->dispMem, 0, 8 ); - - st->last_coder_type = GENERIC; - fer_energy( output_frame, UNVOICED_CLAS, st->previoussynth, -1, &st->enr_old, 1 ); - st->lp_gainp = 0.0f; - st->lp_gainc = (float) sqrt( st->lp_ener ); - - st->last_voice_factor = 0; - st->Last_GSC_noisy_speech_flag = 0; - - if ( st->output_Fs >= 16000 && st->hBWE_zero != NULL ) - { - hf_synth_reset( st->hBWE_zero ); - } - - if ( st->hBWE_FD != NULL ) - { - set_f( st->hBWE_FD->old_syn_12k8_16k, 0, NS2SA( 16000, DELAY_FD_BWE_ENC_NS ) ); - } - - if ( nchan_out == 1 && st->element_mode == IVAS_CPE_DFT && st->element_brate <= IVAS_24k4 && last_element_brate > IVAS_24k4 ) - { - /* update cldbf state with previous frame TCX synthesis when going from a bitrate with residual coding to a bitrate without it */ - int16_t offset; - offset = st->cldfbAna->p_filter_length - st->cldfbAna->no_channels; - mvr2r( st->hTcxDec->old_synthFB + st->hTcxDec->old_synth_lenFB - offset, st->cldfbAna->cldfb_state, offset ); - } - } -#endif test(); test(); test(); @@ -969,40 +723,16 @@ ivas_error core_switching_pre_dec_fx( { set32_fx( hHQ_core->prev_coeff_out_fx, 0, L_HQ_WB_BWE ); } -#ifdef IVAS_CODE_SWITCHING - if ( st->element_mode != EVS_MONO ) - { - /* Estimate mem_env_delta to reinit env_stab */ - tmp = max( 0, ENV_STAB_EST1 + ( ENV_STAB_EST2 * st->stab_fac_smooth_lt ) + ( ENV_STAB_EST3 * st->log_energy_diff_lt ) ); - st->hHQ_core->mem_env_delta = (int16_t) min( MAX16B, (int32_t) ( tmp * ( 1 << 12 ) ) ); /* Convert to Q12 and handle saturation */ - if ( st->last_core != TCX_20_CORE && st->last_core != TCX_10_CORE ) - { - set_f( st->hHQ_core->old_out, 0, output_frame ); - set_f( st->hHQ_core->old_outLB, 0, L_FRAME16k ); - } - - st->hHQ_core->no_att_hangover = 0; - st->hHQ_core->energy_lt = 300.0f; - - set_s( st->hHQ_core->old_is_transient, 0, 3 ); - set_f( st->hHQ_core->prev_noise_level, 0.0f, 2 ); - st->hHQ_core->prev_R = 0; - set_s( st->hHQ_core->mem_norm + 1, 39, SFM_N_ENV_STAB - 1 ); - st->hHQ_core->prev_hqswb_clas = HQ_NORMAL; - st->hHQ_core->prev_ni_ratio = 0.5f; - set_f( st->hHQ_core->prev_En_sb, 0.0f, NB_SWB_SUBBANDS ); + if ( st_fx->element_mode != EVS_MONO ) + { } else -#endif { set16_fx( hHQ_core->old_out_fx, 0, output_frame ); hHQ_core->Q_old_wtda_LB = 15; hHQ_core->Q_old_wtda = 15; move16(); -#ifdef IVAS_CODE_SWITCHING - set_f( st->hHQ_core->old_outLB, 0, L_FRAME16k ); -#endif } } @@ -1109,12 +839,10 @@ ivas_error core_switching_pre_dec_fx( IF( NE_16( st_fx->last_L_frame, st_fx->L_frame ) && LE_16( st_fx->L_frame, L_FRAME16k ) && LE_16( st_fx->last_L_frame, L_FRAME16k ) ) { test(); -#ifdef IVAS_CODE_SWITCHING IF( EQ_16( st_fx->element_mode, IVAS_CPE_DFT ) || EQ_16( st_fx->element_mode, IVAS_CPE_TD ) ) { - lerp( st_fx->hFdCngDec->hFdCngCom->olapBufferAna + st_fx->last_L_frame, st_fx->hFdCngDec->hFdCngCom->olapBufferAna + st_fx->L_frame, st_fx->L_frame, st_fx->last_L_frame ); } -#endif + lerp( st_fx->hFdCngDec->hFdCngCom->olapBufferSynth2, st_fx->hFdCngDec->hFdCngCom->olapBufferSynth2, shl( st_fx->L_frame, 1 ), shl( st_fx->last_L_frame, 1 ) ); test(); IF( LE_32( st_fx->total_brate, SID_2k40 ) && LE_32( st_fx->last_total_brate, SID_2k40 ) ) @@ -1150,22 +878,12 @@ ivas_error core_switching_pre_dec_fx( *---------------------------------------------------------------------*/ ivas_error core_switching_post_dec_fx( - Decoder_State *st_fx, /* i/o: decoder state structure */ - Word16 *synth, /* i/o: output synthesis Qsynth*/ -#ifdef IVAS_CODE_SWITCHING - float *output, /* i/o: LB synth/upsampled LB synth */ - float output_mem[], /* i : OLA memory from last TCX/HQ frame */ - const IVAS_FORMAT ivas_format, /* i : IVAS format */ - const Word16 use_cldfb_for_dft, /* i : flag to use of CLDFB for DFT Stereo */ -#endif + Decoder_State *st_fx, /* i/o: decoder state structure */ + Word16 *synth, /* i/o: output synthesis Qsynth*/ const Word16 output_frame, /* i : frame length Q0*/ const Word16 core_switching_flag, /* i : ACELP->HQ switching flag Q0*/ -#ifdef IVAS_CODE_SWITCHING - const Word16 sba_dirac_stereo_flag, /* i : signal stereo output for SBA DirAC */ - const Word16 nchan_out, /* i : number of output channels */ -#endif - const Word16 last_element_mode, /* i : element mode of previous frame Q0*/ - Word16 *Qsynth /* i/o: Scaling of ACELP exit (Q_syn2-1) or HQ exit (Qsynth); changes after this function */ + const Word16 last_element_mode, /* i : element mode of previous frame Q0*/ + Word16 *Qsynth /* i/o: Scaling of ACELP exit (Q_syn2-1) or HQ exit (Qsynth); changes after this function */ ) { Word16 i, delay_comp, delta; @@ -1180,9 +898,6 @@ ivas_error core_switching_post_dec_fx( HQ_DEC_HANDLE hHQ_core; ivas_error error; -#ifdef IVAS_CODE_SWITCHING - int16_t offset; -#endif #ifdef REMOVE_IVAS_UNUSED_PARAMETERS_WARNING (void) ( last_element_mode ); #endif @@ -1192,8 +907,6 @@ ivas_error core_switching_post_dec_fx( error = IVAS_ERR_OK; move32(); - // PMT("core_switching_post_dec_fx : Only handles has been converted, code needs to be entirely reviewed ") - /* Rescale synthesis in Q0 to avoid multiple rescaling after */ tmp = Find_Max_Norm16( synth, output_frame ); Scale_sig( synth, output_frame, tmp ); @@ -1301,12 +1014,8 @@ ivas_error core_switching_post_dec_fx( FOR( i = 0; i < shift; i++ ) { - L_tmp = L_mult( ( *ptmp1 ), tmpF ); /*Qsynth + 16*/ -#ifdef BASOP_NOGLOB + L_tmp = L_mult( ( *ptmp1 ), tmpF ); /*Qsynth + 16*/ *ptmp1 = round_fx_sat( L_mac_sat( L_tmp, add_sat( sub( 24576, tmpF ), 8192 ), ( *ptmp2 ) ) ); /*Qsynth*/ -#else - *ptmp1 = round_fx( L_mac( L_tmp, add( sub( 24576, tmpF ), 8192 ), ( *ptmp2 ) ) ); /*Qsynth*/ -#endif ptmp1++; ptmp2++; tmpF = add( tmpF, tmp ); @@ -1325,12 +1034,8 @@ ivas_error core_switching_post_dec_fx( ptmp2 = hHQ_core->fer_samples_fx; FOR( i = 0; i < shift; i++ ) { - L_tmp = L_mult( ( *ptmp1 ), tmpF ); /*Qsynth + 16*/ -#ifdef BASOP_NOGLOB + L_tmp = L_mult( ( *ptmp1 ), tmpF ); /*Qsynth + 16*/ *ptmp1 = round_fx_sat( L_mac_sat( L_tmp, add_sat( sub( 24576, tmpF ), 8192 ), ( *ptmp2 ) ) ); /*Qsynth*/ -#else - *ptmp1 = round_fx( L_mac( L_tmp, add( sub( 24576, tmpF ), 8192 ), ( *ptmp2 ) ) ); /*Qsynth*/ -#endif move16(); tmpF = add( tmpF, tmp ); ptmp1++; @@ -1585,7 +1290,7 @@ ivas_error core_switching_post_dec_ivas_fx( FD_BWE_DEC_HANDLE hBWE_FD; HQ_DEC_HANDLE hHQ_core; ivas_error error; - int16_t offset; + Word16 offset; L_tmp = 0; move32(); @@ -1596,8 +1301,6 @@ ivas_error core_switching_post_dec_ivas_fx( error = IVAS_ERR_OK; move32(); - // PMT("core_switching_post_dec_fx : Only handles has been converted, code needs to be entirely reviewed ") - /* Rescale synthesis in Q0 to avoid multiple rescaling after */ tmp = Find_Max_Norm16( synth, output_frame ); Scale_sig( synth, output_frame, tmp ); /* Qsynth + tmp */ @@ -1753,12 +1456,8 @@ ivas_error core_switching_post_dec_ivas_fx( FOR( i = 0; i < shift; i++ ) { - L_tmp = L_mult( ( *ptmp1 ), tmpF ); /*Qsynth + 16*/ -#ifdef BASOP_NOGLOB + L_tmp = L_mult( ( *ptmp1 ), tmpF ); /*Qsynth + 16*/ *ptmp1 = round_fx_sat( L_mac_sat( L_tmp, add_sat( sub( 24576, tmpF ), 8192 ), ( *ptmp2 ) ) ); /*Qsynth*/ -#else - *ptmp1 = round_fx( L_mac( L_tmp, add( sub( 24576, tmpF ), 8192 ), ( *ptmp2 ) ) ); /*Qsynth*/ -#endif ptmp1++; ptmp2++; tmpF = add( tmpF, tmp ); @@ -1777,12 +1476,8 @@ ivas_error core_switching_post_dec_ivas_fx( ptmp2 = hHQ_core->fer_samples_fx; FOR( i = 0; i < shift; i++ ) { - L_tmp = L_mult( ( *ptmp1 ), tmpF ); /*Qsynth + 16*/ -#ifdef BASOP_NOGLOB + L_tmp = L_mult( ( *ptmp1 ), tmpF ); /*Qsynth + 16*/ *ptmp1 = round_fx_sat( L_mac_sat( L_tmp, add_sat( sub( 24576, tmpF ), 8192 ), ( *ptmp2 ) ) ); /*Qsynth*/ -#else - *ptmp1 = round_fx( L_mac( L_tmp, add( sub( 24576, tmpF ), 8192 ), ( *ptmp2 ) ) ); /*Qsynth*/ -#endif move16(); tmpF = add( tmpF, tmp ); ptmp1++; @@ -1809,7 +1504,7 @@ ivas_error core_switching_post_dec_ivas_fx( Copy_Scale_sig( st_fx->previoussynth_fx, synth, delay_comp, *Qsynth ); /* Qsynth */ /* Overlap between TCX-LB and TCX-FB*/ - Word16 tmpDelta = NS2SA( st_fx->output_Fs, DELAY_BWE_TOTAL_NS ); + Word16 tmpDelta = NS2SA_FX2( st_fx->output_Fs, DELAY_BWE_TOTAL_NS ); Word32 L_tmp2; FOR( i = 0; i < tmpDelta; i++ ) { @@ -1968,7 +1663,7 @@ ivas_error core_switching_post_dec_ivas_fx( } IF( output_mem_fx != NULL ) { - Scale_sig( output_mem_fx, NS2SA( st_fx->output_Fs, STEREO_DFT32MS_OVL_NS ), Qtmp ); /* Qtmp */ + Scale_sig( output_mem_fx, NS2SA_FX2( st_fx->output_Fs, STEREO_DFT32MS_OVL_NS ), Qtmp ); /* Qtmp */ } *Qsynth = Qtmp; move16(); @@ -2479,3 +2174,1012 @@ static void smoothTransitionDtxToTcx_fx( return; } + + +/*---------------------------------------------------------------------* + * core_switching_pre_dec() + * + * Preprocessing/preparation for ACELP/HQ core switching + *---------------------------------------------------------------------*/ +ivas_error core_switching_pre_dec_ivas_fx( + Decoder_State *st, /* i/o: decoder state structure */ + const Word16 output_frame, /* i : frame length */ + const Word32 last_core_brate_st0, /* i : channel 0 last core bitrate */ + const Word16 nchan_out, /* i : number of output channels */ + const Word16 last_element_mode, /* i : last_element_mode */ + const Word32 last_element_brate, /* i : last element bitrate */ + Word16 Q_old_synthFB, + Word16 *Q_olapBufferSynth, + Word16 *Q_olapBufferSynth2 ) +{ + Word32 tmp_fx; /*Q-12*/ + Word16 i, oldLenClasBuff, newLenClasBuff; + ivas_error error; + Word16 exp = 25; + move16(); + error = IVAS_ERR_OK; + move32(); + + /* Codec mode switching */ + test(); + test(); + test(); + IF( EQ_16( st->last_codec_mode, MODE2 ) || ( ( EQ_16( st->last_core, TCX_20_CORE ) || EQ_16( st->last_core, TCX_10_CORE ) ) && ( st->element_mode > EVS_MONO ) ) ) + { + st->mem_deemph_fx = st->syn[M]; + move16(); + set16_fx( st->agc_mem_fx, 0, 2 ); + Scale_sig( &( st->mem_deemph_fx ), 1, st->Q_syn ); /* Brings mem_deemph to Qsyn */ + + Copy_Scale_sig( st->mem_syn2_fx, st->mem_syn1_fx, M, sub( -1, st->Q_syn ) ); /*Q-1*/ + + st->bpf_off = 1; + move16(); + IF( st->hPFstat != NULL ) + { + Scale_sig( st->hPFstat->mem_pf_in, L_SUBFR, st->Q_syn ); /* Post_filter mem ,Q_syn*/ + Scale_sig( st->hPFstat->mem_res2, DECMEM_RES2, st->Q_syn ); /* NB post_filter mem , Q_syn*/ + Scale_sig( st->hPFstat->mem_stp, L_SUBFR, st->Q_syn ); /* Post_filter mem ,Q_syn*/ + set16_fx( st->hBPF->pst_old_syn_fx, 0, NBPSF_PIT_MAX ); /* BPF mem*/ + } + IF( st->hBPF != NULL ) + { + st->hBPF->pst_lp_ener_fx = round_fx( L_shl( Mpy_32_16_1( st->lp_error_ener, 0x6054 ), 2 + 8 ) ); /* convert from 15Q16, log2 -> 7Q8 10*log10 */ + st->hBPF->pst_mem_deemp_err_fx = 0; + move16(); + move16(); + } + st->psf_lp_noise_fx = round_fx( L_shl( st->lp_noise, 1 ) ); // Q(23+1-16)->Q8 + move16(); + + /* reset old HB synthesis buffer */ + IF( EQ_16( st->last_L_frame, L_FRAME ) ) + { + st->old_bwe_delay = NS2SA( st->output_Fs, MAX_DELAY_TBE_NS - DELAY_SWB_TBE_12k8_NS ); + } + ELSE + { + st->old_bwe_delay = NS2SA( st->output_Fs, MAX_DELAY_TBE_NS - DELAY_SWB_TBE_16k_NS ); + } + move16(); + set16_fx( st->hb_prev_synth_buffer_fx, 0, NS2SA( 48000, DELAY_BWE_TOTAL_NS ) ); + + test(); + IF( st->hBWE_TD != NULL && ( st->last_core != ACELP_CORE ) ) + { +#ifdef MSAN_FIX + st->hBWE_TD->prev_hb_synth_fx_exp = 31; + move16(); +#endif // MSAN_FIX + /* reset BWE memories */ + set16_fx( st->hBWE_TD->old_bwe_exc_fx, 0, PIT16k_MAX * 2 ); + st->hBWE_TD->bwe_non_lin_prev_scale_fx = 0; + move32(); + } + + /* reset upd_cnt */ + st->upd_cnt = MAX_UPD_CNT; + move16(); + + st->igf = 0; + move16(); + + test(); + IF( GT_32( st->output_Fs, 16000 ) && st->hBWE_zero != NULL ) + { + hf_synth_reset_fx( st->hBWE_zero ); +#ifdef MSAN_FIX + set16_fx( st->hBWE_zero->mem_hp400_fx, 0, 6 ); +#endif + } + + IF( st->hBWE_FD != NULL ) + { + set16_fx( st->hBWE_FD->old_syn_12k8_16k_fx, 0, NS2SA( 16000, DELAY_FD_BWE_ENC_NS ) ); + } + + IF( st->hHQ_core != NULL ) + { + set32_fx( st->hHQ_core->prev_env_fx, 0, SFM_N_WB ); + set32_fx( st->hHQ_core->prev_normq_fx, 0, SFM_N_WB ); + + set32_fx( st->hHQ_core->last_ni_gain_fx, 0, BANDS_MAX ); + set16_fx( st->hHQ_core->last_env_fx, 0, BANDS_MAX ); + + st->hHQ_core->last_max_pos_pulse = 0; + move16(); + + IF( GT_32( st->output_Fs, 16000 ) ) + { + set32_fx( st->hHQ_core->prev_coeff_out_fx, 0, L_HQ_WB_BWE ); + } + + /* pre-echo */ + st->hHQ_core->pastpre = 0; + move16(); + } + + /* reset the GSC pre echo energy threshold in case of switching */ + if ( st->hGSCDec != NULL ) + { + st->hGSCDec->Last_frame_ener_fx = MAX_32; + move32(); + } + + test(); + IF( EQ_16( st->last_core, TCX_20_CORE ) || EQ_16( st->last_core, TCX_10_CORE ) ) + { + IF( st->element_mode == EVS_MONO ) + { + st->last_core = HQ_CORE; + move16(); + + Copy32( st->hTcxDec->FBTCXdelayBuf_32, st->prev_synth_buffer32_fx, NS2SA( st->output_Fs, DELAY_BWE_TOTAL_NS - DELAY_CLDFB_NS ) ); + // Copy_Scale_sig_32_16( st->hTcxDec->FBTCXdelayBuf_32, st->prev_synth_buffer_fx, NS2SA( st->output_Fs, DELAY_BWE_TOTAL_NS - DELAY_CLDFB_NS ), -11 ); //Q11 -> Q0 + } + + IF( st->hHQ_core != NULL ) + { + set32_fx( st->hHQ_core->last_ni_gain_fx, 0, BANDS_MAX ); + set16_fx( st->hHQ_core->last_env_fx, 0, BANDS_MAX ); + st->hHQ_core->last_max_pos_pulse = 0; + move16(); + + set16_fx( st->hHQ_core->prev_SWB_peak_pos, 0, SPT_SHORTEN_SBNUM ); + st->hHQ_core->prev_frm_hfe2 = 0; + st->hHQ_core->prev_stab_hfe2 = 0; + move16(); + move16(); + } + } + + IF( st->prev_bfi != 0 ) + { + Word16 delay_comp; + + /*switch off Hq Voicing as it was not updated in MODE2*/ + IF( st->hHQ_core != NULL ) + { + st->hHQ_core->oldHqVoicing = 0; + st->hHQ_core->HqVoicing = 0; + move16(); + move16(); + } + + delay_comp = NS2SA( st->output_Fs, DELAY_CLDFB_NS ); + /*TODO To be tested:control not entering the block*/ + test(); + test(); + IF( !st->last_con_tcx && ( st->last_core_bfi == ACELP_CORE ) && EQ_16( st->core, HQ_CORE ) ) + { + /*TODO None of the test dtreams are entering this block,hence enabled assert(0)*/ + assert( 0 ); + Word32 *realBuffer_fx[CLDFB_NO_COL_MAX_SWITCH], *imagBuffer_fx[CLDFB_NO_COL_MAX_SWITCH]; + Word32 realBufferTmp_fx[CLDFB_NO_COL_MAX_SWITCH][CLDFB_NO_CHANNELS_MAX], imagBufferTmp_fx[CLDFB_NO_COL_MAX_SWITCH][CLDFB_NO_CHANNELS_MAX]; + Word32 syn_Overl_fx[320]; + Word32 fer_samples_fx[960]; + Copy_Scale_sig_16_32_DEPREC( st->hTcxDec->syn_Overl, syn_Overl_fx, 320, 15 ); + Copy_Scale_sig_16_32_DEPREC( st->hHQ_core->fer_samples_fx, fer_samples_fx, 960, 15 ); + + + FOR( i = 0; i < CLDFB_NO_COL_MAX_SWITCH; i++ ) + { + set32_fx( realBufferTmp_fx[i], 0, CLDFB_NO_CHANNELS_MAX ); + set32_fx( imagBufferTmp_fx[i], 0, CLDFB_NO_CHANNELS_MAX ); + realBuffer_fx[i] = realBufferTmp_fx[i]; + imagBuffer_fx[i] = imagBufferTmp_fx[i]; + } + + /* CLDFB analysis of the synthesis at internal sampling rate */ + IF( NE_32( ( error = cldfb_save_memory_ivas_fx( st->cldfbAna ) ), IVAS_ERR_OK ) ) + { + return error; + } + + cldfbAnalysis_ivas_fx( syn_Overl_fx, realBuffer_fx, imagBuffer_fx, delay_comp, st->cldfbAna ); + cldfb_restore_memory_ivas_fx( st->cldfbAna ); /*Assuming Q10*/ + + /* CLDFB synthesis of the combined signal */ + IF( NE_32( ( error = cldfb_save_memory_ivas_fx( st->cldfbSyn ) ), IVAS_ERR_OK ) ) + { + return error; + } + + cldfbSynthesis_ivas_fx( realBuffer_fx, imagBuffer_fx, fer_samples_fx, delay_comp, st->cldfbSyn ); + cldfb_restore_memory_ivas_fx( st->cldfbSyn ); + Copy_Scale_sig_32_16( syn_Overl_fx, st->hTcxDec->syn_Overl, 320, 15 ); + Copy_Scale_sig_32_16( fer_samples_fx, st->hHQ_core->fer_samples_fx, 960, 9 ); + } + + test(); + test(); + IF( !st->last_con_tcx && ( st->last_core_bfi == ACELP_CORE ) && EQ_16( st->core, HQ_CORE ) ) + { + lerp( st->hTcxDec->syn_Overl, st->hHQ_core->fer_samples_fx + delay_comp, shr( output_frame, 1 ), shr( st->last_L_frame, 1 ) ); + /*Set to zero the remaining part*/ + set16_fx( st->hHQ_core->fer_samples_fx + delay_comp + output_frame / 2, 0, sub( shr( output_frame, 1 ), delay_comp ) ); + } + } + + st->use_acelp_preq = 0; + st->reset_mem_AR = 0; + move16(); + move16(); + } + + /*FEC*/ + IF( LE_16( st->L_frame, L_FRAME16k ) ) + { + test(); + IF( LE_16( st->last_L_frame, L_FRAME16k ) && NE_16( st->core, HQ_CORE ) ) + { + IF( NE_16( st->L_frame, st->last_L_frame ) ) + { + IF( GT_16( st->L_frame, st->last_L_frame ) ) + { + oldLenClasBuff = mult_r( L_SYN_MEM_CLAS_ESTIM, div_s( st->last_L_frame, st->L_frame ) ); + newLenClasBuff = L_SYN_MEM_CLAS_ESTIM; + move16(); + } + ELSE + { + oldLenClasBuff = L_SYN_MEM_CLAS_ESTIM; + move16(); + newLenClasBuff = mult_r( L_SYN_MEM_CLAS_ESTIM, div_s( st->L_frame, st->last_L_frame ) ); + } + lerp( &st->mem_syn_clas_estim_fx[L_SYN_MEM_CLAS_ESTIM - oldLenClasBuff], &st->mem_syn_clas_estim_fx[L_SYN_MEM_CLAS_ESTIM - newLenClasBuff], newLenClasBuff, oldLenClasBuff ); + } + } + ELSE + { + set16_fx( st->mem_syn_clas_estim_fx, 0, L_SYN_MEM_CLAS_ESTIM ); + } + } + + /* Here we only handle cases where last_ppp and last_nelp not updated when coming from CodecB or other cores + within ACELP_CORE if switching from another bitarate to vbr, last_ppp and last_nelp is always updated in the previous frame */ + test(); + test(); + IF( ( st->core == ACELP_CORE ) && ( ( st->last_core != ACELP_CORE ) || EQ_16( st->last_codec_mode, MODE2 ) ) ) + { + st->last_ppp_mode_dec = 0; + st->last_nelp_mode_dec = 0; + move16(); + move16(); + } + + /* Handle state reset of stat_noise_uv_mod memory */ + test(); + test(); + test(); + IF( ( st->core == ACELP_CORE ) && ( ( st->last_core != ACELP_CORE ) || EQ_16( st->last_codec_mode, MODE2 ) || LE_32( st->last_total_brate, PPP_NELP_2k80 ) ) ) + { + st->act_count = 3; + st->uv_count = 0; + move16(); + move16(); + } + + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + IF( ( ( ( st->core == ACELP_CORE ) || EQ_16( st->core, AMR_WB_CORE ) ) && EQ_16( st->last_core, HQ_CORE ) ) || ( ( EQ_16( st->element_mode, IVAS_CPE_DFT ) || EQ_16( st->element_mode, IVAS_CPE_TD ) || ( EQ_16( st->element_mode, IVAS_CPE_MDCT ) && EQ_16( last_element_mode, IVAS_CPE_DFT ) ) ) && EQ_16( nchan_out, 2 ) && + NE_32( st->core_brate, SID_2k40 ) && ( st->core_brate != FRAME_NO_DATA ) && ( ( last_core_brate_st0 == FRAME_NO_DATA ) || EQ_32( last_core_brate_st0, SID_2k40 ) ) ) ) + { + test(); + if ( EQ_16( st->element_mode, IVAS_CPE_DFT ) || EQ_16( st->element_mode, IVAS_CPE_TD ) ) + { + st->hPFstat->reset = 1; + move16(); + } + + IF( EQ_16( st->L_frame, L_FRAME16k ) ) + { + Copy( TRWB2_Ave_fx, st->lsf_old_fx, M ); /* init of LSP */ + Copy( TRWB2_Ave_fx, st->lsfoldbfi1_fx, M ); + Copy( TRWB2_Ave_fx, st->lsfoldbfi0_fx, M ); + Copy( TRWB2_Ave_fx, st->lsf_adaptive_mean_fx, M ); + lsf2lsp_fx( st->lsf_old_fx, st->lsp_old_fx, M, INT_FS_16k ); + } + ELSE + { + Copy( TRWB_Ave_fx, st->lsf_old_fx, M ); /* init of LSP */ + Copy( TRWB_Ave_fx, st->lsfoldbfi1_fx, M ); + Copy( TRWB_Ave_fx, st->lsfoldbfi0_fx, M ); + Copy( TRWB_Ave_fx, st->lsf_adaptive_mean_fx, M ); + lsf2lsp_fx( st->lsf_old_fx, st->lsp_old_fx, M, INT_FS_12k8 ); + } + + test(); + test(); + test(); + test(); + test(); + test(); + IF( ( EQ_16( st->element_mode, IVAS_CPE_DFT ) || EQ_16( st->element_mode, IVAS_CPE_TD ) ) && EQ_16( nchan_out, 2 ) && GT_32( st->core_brate, SID_2k40 ) && ( ( last_core_brate_st0 == FRAME_NO_DATA ) || EQ_32( last_core_brate_st0, SID_2k40 ) ) && st->hTcxDec != NULL ) + { + /* Last frame was Stereo CNG and the synthesis memory is outdated -- reset */ + set16_fx( st->hTcxDec->old_syn_Overl, 0, L_FRAME32k / 2 ); + set16_fx( st->hFdCngDec->hFdCngCom->olapBufferAna_fx, 0, FFTLEN ); + set16_fx( st->agc_mem_fx, 0, 2 ); + } + st->mem_deemph_fx = 0; + move16(); + IF( !st->last_con_tcx ) + { + set16_fx( st->mem_syn2_fx, 0, M ); + } + set16_fx( st->mem_syn1_fx, 0, M ); + if ( st->hBWE_TD != NULL ) + { + st->hBWE_TD->bwe_non_lin_prev_scale_fx = 0; + move32(); + } + + /* Reset ACELP parameters */ + set16_fx( st->mem_MA_fx, 0, M ); + + IF( EQ_32( st->sr_core, INT_FS_16k ) ) + { + Copy( GEWB2_Ave_fx, st->mem_AR_fx, M ); + } + ELSE + { + Copy( GEWB_Ave_fx, st->mem_AR_fx, M ); + } + + st->tilt_code_fx = 0; + st->gc_threshold_fx = 0; + st->dm_fx.prev_gain_code = 0; + st->dm_fx.prev_state = 0; + move16(); + move32(); + move32(); + move16(); + set16_fx( st->dm_fx.prev_gain_pit, 0, 6 ); + + st->last_coder_type = GENERIC; + move16(); + + fer_energy_fx( output_frame, UNVOICED_CLAS, st->previoussynth_fx_32, 0, -1, &st->enr_old_fx, 1 ); /*Q-0*/ + st->lp_gainp_fx = 0; + move16(); + st->lp_gainc_fx = extract_h( Sqrt32( st->lp_ener_fx, &exp ) ); /*Q=15-exp*/ + move16(); + st->lp_gainc_fx = shr( st->lp_gainc_fx, sub( 12, exp ) ); /*Q3*/ + move16(); + + st->last_voice_factor_fx = 0; + st->Last_GSC_noisy_speech_flag = 0; + move16(); + move16(); + + /* reset CLDFB memories */ + cldfb_reset_memory_fx( st->cldfbAna ); + cldfb_reset_memory_fx( st->cldfbBPF ); + cldfb_reset_memory_fx( st->cldfbSyn ); + + /* reset TBE memories */ + test(); + test(); + IF( !st->last_con_tcx && !( ( EQ_16( st->last_core, HQ_CORE ) ) && ( st->element_mode > EVS_MONO ) ) ) + { + set16_fx( st->old_exc_fx, 0, L_EXC_MEM_DEC ); + } + ELSE IF( LT_16( st->L_frame, L_FRAME16k ) ) + { + /* resample from 16kHz to 12.8kHZ */ + synth_mem_updt2( st->L_frame, L_FRAME16k, st->old_exc_fx, st->mem_syn_r, st->mem_syn2_fx, NULL, DEC ); + } + + IF( st->hBWE_TD != NULL ) + { + set16_fx( st->hBWE_TD->old_bwe_exc_fx, 0, PIT16k_MAX * 2 ); + } + + test(); + IF( GT_32( st->output_Fs, 16000 ) && st->hBWE_zero != NULL ) + { + hf_synth_reset_fx( st->hBWE_zero ); +#ifdef MSAN_FIX + set16_fx( st->hBWE_zero->mem_hp400_fx, 0, 6 ); +#endif + } + + IF( st->hBWE_FD != NULL ) + { + set16_fx( st->hBWE_FD->old_syn_12k8_16k_fx, 0, NS2SA( 16000, DELAY_FD_BWE_ENC_NS ) ); + } + } + + test(); + test(); + test(); + IF( ( ( st->core == ACELP_CORE ) || EQ_16( st->core, AMR_WB_CORE ) ) && ( EQ_16( st->last_core, TCX_20_CORE ) || EQ_16( st->last_core, TCX_10_CORE ) ) ) + { + IF( st->hBWE_TD != NULL ) + { + st->hBWE_TD->bwe_non_lin_prev_scale_fx = 0; + move32(); + set16_fx( st->hBWE_TD->old_bwe_exc_fx, 0, PIT16k_MAX * 2 ); + } + + st->tilt_code_fx = 0; + st->gc_threshold_fx = 0; + st->dm_fx.prev_gain_code = 0; + st->dm_fx.prev_state = 0; + move16(); + move32(); + move32(); + move16(); + set16_fx( st->dm_fx.prev_gain_pit, 0, 6 ); + st->last_coder_type = GENERIC; + move16(); + fer_energy_fx( output_frame, UNVOICED_CLAS, st->previoussynth_fx_32, 0, -1, &st->enr_old_fx, 1 ); /*Q-0*/ + + st->lp_gainp_fx = 0; + move16(); + st->lp_gainc_fx = extract_h( Sqrt32( st->lp_ener_fx, &exp ) ); /*Q=15-exp*/ + move16(); + st->lp_gainc_fx = shr( st->lp_gainc_fx, sub( 12, exp ) ); /*Q3*/ + move16(); + + st->last_voice_factor_fx = 0; + st->Last_GSC_noisy_speech_flag = 0; + move16(); + move16(); + + test(); + IF( GT_32( st->output_Fs, 16000 ) && st->hBWE_zero != NULL ) + { + hf_synth_reset_fx( st->hBWE_zero ); +#ifdef MSAN_FIX + set16_fx( st->hBWE_zero->mem_hp400_fx, 0, 6 ); +#endif + } + + IF( st->hBWE_FD != NULL ) + { + set16_fx( st->hBWE_FD->old_syn_12k8_16k_fx, 0, NS2SA( 16000, DELAY_FD_BWE_ENC_NS ) ); + } + + test(); + test(); + test(); + IF( EQ_16( nchan_out, 1 ) && EQ_16( st->element_mode, IVAS_CPE_DFT ) && LE_32( st->element_brate, IVAS_24k4 ) && GT_32( last_element_brate, IVAS_24k4 ) ) + { + /* update cldbf state with previous frame TCX synthesis when going from a bitrate with residual coding to a bitrate without it */ + Word16 offset; + offset = sub( st->cldfbAna->p_filter_length, st->cldfbAna->no_channels ); + Word32 *old_synthFB_fx; + IF( ( old_synthFB_fx = (Word32 *) malloc( st->hTcxDec->old_synth_lenFB * sizeof( Word32 ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Cannot allocate memory for old_synth_lenFB (32 bit) \n" ) ); + } +#ifdef FIX_ISSUE_1237 + Copy_Scale_sig_16_32_no_sat( st->hTcxDec->old_synthFB_fx, old_synthFB_fx, st->hTcxDec->old_synth_lenFB, sub( Q10, Q_old_synthFB ) ); // Q10 +#else + Copy_Scale_sig_16_32_DEPREC( st->hTcxDec->old_synthFB_fx, old_synthFB_fx, st->hTcxDec->old_synth_lenFB, sub( Q10, Q_old_synthFB ) ); // Q10 +#endif + Copy32( old_synthFB_fx + st->hTcxDec->old_synth_lenFB - offset, st->cldfbAna->cldfb_state_fx, offset ); + st->cldfbAna->Q_cldfb_state = Q10; + move16(); + IF( old_synthFB_fx ) + free( old_synthFB_fx ); + } + } + + test(); + test(); + test(); + test(); + IF( EQ_16( st->core, HQ_CORE ) && ( ( st->last_core == ACELP_CORE ) || EQ_16( st->last_core, AMR_WB_CORE ) || ( ( ( st->element_mode != EVS_MONO ) ) && ( NE_16( st->last_core, HQ_CORE ) ) ) ) ) + { + set32_fx( st->hHQ_core->prev_env_fx, 0, SFM_N_WB ); + set32_fx( st->hHQ_core->prev_normq_fx, 0, SFM_N_WB ); + + set32_fx( st->hHQ_core->last_ni_gain_fx, 0, BANDS_MAX ); + set16_fx( st->hHQ_core->last_env_fx, 0, BANDS_MAX ); + st->hHQ_core->last_max_pos_pulse = 0; + move16(); + + set16_fx( st->hHQ_core->prev_SWB_peak_pos, 0, SPT_SHORTEN_SBNUM ); + st->hHQ_core->prev_frm_hfe2 = 0; + st->hHQ_core->prev_stab_hfe2 = 0; + move16(); + move16(); + IF( GT_32( st->output_Fs, 16000 ) ) + { + set32_fx( st->hHQ_core->prev_coeff_out_fx, 0, L_HQ_WB_BWE ); + } + + IF( st->element_mode != EVS_MONO ) + { + /* Estimate mem_env_delta to reinit env_stab */ + tmp_fx = L_max( 0, L_add( ENV_STAB_EST1_FX, L_add( Mult_32_16( st->stab_fac_smooth_lt_fx, ENV_STAB_EST2_FX ), Mult_32_16( st->log_energy_diff_lt_fx, ENV_STAB_EST3_FX ) ) ) ); /*Q12*/ + + st->hHQ_core->mem_env_delta = extract_l( L_min( MAX16B, tmp_fx ) ); /* Convert to Q12 and handle saturation */ + move16(); + test(); + IF( NE_16( st->last_core, TCX_20_CORE ) && NE_16( st->last_core, TCX_10_CORE ) ) + { + set16_fx( st->hHQ_core->old_out_fx, 0, output_frame ); + set32_fx( st->hHQ_core->old_outLB_fx, 0, L_FRAME16k ); + set16_fx( st->hHQ_core->old_out_LB_fx, 0, L_FRAME16k ); + } + + st->hHQ_core->no_att_hangover = 0; + move16(); + st->hHQ_core->energy_lt_fx = 2457600; /*300.0f Q13*/ + move32(); + set16_fx( st->hHQ_core->old_is_transient, 0, 3 ); + set16_fx( st->hHQ_core->prev_noise_level_fx, 0, 2 ); + st->hHQ_core->prev_R = 0; + move16(); + set16_fx( st->hHQ_core->mem_norm + 1, 39, SFM_N_ENV_STAB - 1 ); + st->hHQ_core->prev_hqswb_clas = HQ_NORMAL; + st->hHQ_core->prev_ni_ratio_fx = 16384; /*Q15*/ + move16(); + move16(); + set16_fx( st->hHQ_core->prev_En_sb_fx, 0, NB_SWB_SUBBANDS ); + } + ELSE + { + set16_fx( st->hHQ_core->old_out_fx, 0, output_frame ); + set32_fx( st->hHQ_core->old_outLB_fx, 0, L_FRAME16k ); + } + } + + /* handle switching cases where preecho_sb was not called in the last frame (memory not up to date) */ + IF( st->hHQ_core != NULL ) + { + st->hHQ_core->pastpre = sub( st->hHQ_core->pastpre, 1 ); + move16(); + IF( st->hHQ_core->pastpre < 0 ) + { + reset_preecho_dec_fx( st->hHQ_core ); + } + } + test(); + IF( st->core_brate == FRAME_NO_DATA ) + { + st->VAD = 0; + st->m_frame_type = ZERO_FRAME; + } + ELSE IF( EQ_32( st->core_brate, SID_2k40 ) || EQ_32( st->core_brate, SID_1k75 ) ) + { + st->VAD = 0; + st->m_frame_type = SID_FRAME; + } + ELSE + { + st->VAD = 1; + st->m_frame_type = ACTIVE_FRAME; + } + + move16(); + move16(); + /*switch on CNA on active frames*/ + IF( ( st->element_mode == EVS_MONO ) ) /* for IVAS modes, st->flag_cna is set earlier */ + { + test(); + test(); + test(); + test(); + test(); + test(); + IF( st->VAD && ( ( NE_16( st->core, AMR_WB_CORE ) && LE_32( st->total_brate, CNA_MAX_BRATE ) ) || ( EQ_16( st->core, AMR_WB_CORE ) && LE_32( st->total_brate, ACELP_8k85 ) ) ) ) + { + st->flag_cna = 1; + move16(); + } + ELSE IF( st->VAD || ( EQ_16( st->cng_type, FD_CNG ) && EQ_16( st->L_frame, L_FRAME16k ) ) ) + { + st->flag_cna = 0; + move16(); + } + } + + if ( EQ_16( st->core, AMR_WB_CORE ) ) + { + st->cng_type = LP_CNG; + move16(); + } + + /* Reconfigure CNG */ + test(); + test(); + test(); + test(); + IF( st->hFdCngDec && ( NE_16( st->last_L_frame, st->L_frame ) || NE_16( st->hFdCngDec->hFdCngCom->frameSize, st->L_frame ) || ( st->ini_frame == 0 ) || NE_16( st->bwidth, st->last_bwidth ) ) ) + { + /* || st->last_core == AMR_WB_CORE || st->last_codec_mode == MODE2)){*/ + IF( NE_16( st->core, AMR_WB_CORE ) ) + { + test(); + IF( EQ_16( st->rf_flag, 1 ) && EQ_32( st->total_brate, ACELP_13k20 ) ) + { + configureFdCngDec_ivas_fx( st->hFdCngDec, st->bwidth, ACELP_9k60, st->L_frame, st->last_L_frame, st->element_mode ); + } + ELSE + { + configureFdCngDec_ivas_fx( st->hFdCngDec, st->bwidth, st->total_brate, st->L_frame, st->last_L_frame, st->element_mode ); + } + } + ELSE + { + configureFdCngDec_ivas_fx( st->hFdCngDec, WB, ACELP_8k00, st->L_frame, st->last_L_frame, st->element_mode ); + + if ( st->VAD ) + { + st->hFdCngDec->hFdCngCom->CngBitrate = st->total_brate; + move32(); + } + } + test(); + test(); + IF( NE_16( st->last_L_frame, st->L_frame ) && LE_16( st->L_frame, L_FRAME16k ) && LE_16( st->last_L_frame, L_FRAME16k ) ) + { + test(); + IF( EQ_16( st->element_mode, IVAS_CPE_DFT ) || EQ_16( st->element_mode, IVAS_CPE_TD ) ) + { + lerp( st->hFdCngDec->hFdCngCom->olapBufferAna_fx + st->last_L_frame, st->hFdCngDec->hFdCngCom->olapBufferAna_fx + st->L_frame, st->L_frame, st->last_L_frame ); + } + + L_lerp_fx( st->hFdCngDec->hFdCngCom->olapBufferSynth2_fx, st->hFdCngDec->hFdCngCom->olapBufferSynth2_fx, shl( st->L_frame, 1 ), shl( st->last_L_frame, 1 ), Q_olapBufferSynth2 ); + + test(); + IF( LE_32( st->total_brate, SID_2k40 ) && LE_32( st->last_total_brate, SID_2k40 ) ) + { + L_lerp_fx( st->hFdCngDec->hFdCngCom->olapBufferSynth_fx, st->hFdCngDec->hFdCngCom->olapBufferSynth_fx, shl( st->L_frame, 1 ), shl( st->last_L_frame, 1 ), Q_olapBufferSynth ); + + IF( EQ_16( st->L_frame, L_FRAME ) ) + { + FOR( i = 0; i < ( st->L_frame * 2 ); i++ ) + { + st->hFdCngDec->hFdCngCom->olapBufferSynth_fx[i] = Mult_32_16( st->hFdCngDec->hFdCngCom->olapBufferSynth_fx[i], (Word16) 20480 /* 0.6250f in Q15 */ ); + move32(); + } + } + ELSE + { + FOR( i = 0; i < ( st->L_frame * 2 ); i++ ) + { + st->hFdCngDec->hFdCngCom->olapBufferSynth_fx[i] = Mult_32_16( L_shl( st->hFdCngDec->hFdCngCom->olapBufferSynth_fx[i], 1 ), (Word16) 26214 /* 1.6f in Q14 */ ); + move32(); + } + } + } + } + } + + return error; +} +/*---------------------------------------------------------------------* + * core_switching_hq_prepare_dec() + * + * Preprocessing in the first HQ frame after ACELP frame + * Modify bit allocation for HQ core by removing ACELP subframe budget + *---------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------* + * bandwidth_switching_detect() + * + * Classification for band-width switching + *---------------------------------------------------------------------*/ + +void bandwidth_switching_detect_ivas_fx( + Decoder_State *st_fx /* i/o: encoder state structure */ +) +{ + test(); + test(); + IF( ( EQ_16( st_fx->element_mode, IVAS_CPE_TD ) && EQ_16( st_fx->idchan, 1 ) ) || EQ_16( st_fx->element_mode, IVAS_CPE_MDCT ) ) + { + /* there is no BWE in TD stereo secondary channel and in MDCT stereo, IGF is part of the core decoding -> no BW switching -> reset BWS counters */ + st_fx->prev_bws_cnt = 0; + st_fx->bws_cnt = 0; + st_fx->bws_cnt1 = 0; + move16(); + move16(); + move16(); + + return; + } + /* update band-width switching counter */ + test(); + test(); + test(); + test(); + IF( GE_16( st_fx->bws_cnt1, N_NS2W_FRAMES ) ) + { + st_fx->bws_cnt1 = 0; + move16(); + } + ELSE IF( GT_32( st_fx->total_brate, ACELP_9k60 ) && LT_32( st_fx->last_core_brate, ACELP_9k60 ) && EQ_16( st_fx->bwidth, SWB ) && EQ_16( st_fx->last_bwidth, WB ) && ( st_fx->last_low_rate_mode == 0 ) ) + { + st_fx->bws_cnt1 = add( st_fx->bws_cnt1, 1 ); + move16(); + } + ELSE IF( st_fx->bws_cnt1 > 0 ) + { + IF( LT_16( st_fx->bwidth, st_fx->last_bwidth ) ) + { + st_fx->bws_cnt = sub( shl( sub( N_NS2W_FRAMES, st_fx->bws_cnt1 ), 1 ), 1 ); + move16(); + } + ELSE + { + st_fx->bws_cnt = 0; + move16(); + } + + IF( LT_16( st_fx->bwidth, st_fx->last_bwidth ) ) + { + st_fx->bws_cnt1 = 0; + move16(); + } + ELSE + { + IF( EQ_16( st_fx->bwidth, SWB ) ) + { + st_fx->bws_cnt1 = add( st_fx->bws_cnt1, 1 ); + move16(); + } + ELSE + { + st_fx->bws_cnt1 = 0; + move16(); + } + } + } + + /* update band-width switching counter */ + test(); + test(); + test(); + IF( GE_16( st_fx->bws_cnt, N_WS2N_FRAMES ) ) + { + st_fx->bws_cnt = 0; + move16(); + } + ELSE IF( LT_32( st_fx->total_brate, ACELP_9k60 ) && GT_32( st_fx->last_core_brate, ACELP_9k60 ) && LT_16( st_fx->bwidth, st_fx->last_bwidth ) && EQ_16( st_fx->bwidth, WB ) ) + { + st_fx->bws_cnt = add( st_fx->bws_cnt, 1 ); + move16(); + } + ELSE IF( st_fx->bws_cnt > 0 ) + { + IF( GT_16( st_fx->bwidth, st_fx->last_bwidth ) ) + { + st_fx->bws_cnt1 = shr( sub( N_WS2N_FRAMES, st_fx->bws_cnt ), 1 ); + move16(); + } + ELSE + { + st_fx->bws_cnt1 = 0; + move16(); + } + + IF( GT_16( st_fx->bwidth, st_fx->last_bwidth ) ) + { + st_fx->bws_cnt = 0; + move16(); + } + ELSE + { + IF( EQ_16( st_fx->bwidth, WB ) ) + { + st_fx->bws_cnt = add( st_fx->bws_cnt, 1 ); + move16(); + } + ELSE + { + st_fx->bws_cnt = 0; + move16(); + } + } + } + + return; +} + + +/*---------------------------------------------------------------------* + * bw_switching_pre_proc() + * + * Band-width switching pre-processing + *---------------------------------------------------------------------*/ +void ivas_bw_switching_pre_proc_fx( + Decoder_State *st, /* i/o: decoder state structure */ + const Word32 last_element_brate, /* i : last element bitrate */ + const Word16 nchan_out /* i : number of output channels */, + Word32 *old_syn_12k8_16k_fx, + Word16 Q, + Word16 Q_audio ) +{ + Word16 i; + Word32 syn_dct_fx[L_FRAME]; + + + Flag Overflow = 0; + move32(); + + IF( st->element_mode > EVS_MONO ) + { + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + IF( ( st->core == ACELP_CORE ) && !( EQ_16( st->bfi, 1 ) && EQ_16( st->con_tcx, 1 ) ) && st->hBWE_FD != NULL && !( LE_32( st->core_brate, SID_2k40 ) && EQ_16( st->element_mode, IVAS_CPE_DFT ) && EQ_16( nchan_out, 2 ) ) && !( EQ_16( st->element_mode, IVAS_CPE_MDCT ) && EQ_16( nchan_out, 1 ) && EQ_16( st->idchan, 1 ) && LE_32( last_element_brate, IVAS_SID_5k2 ) ) ) + { + /* Calculate tilt of the ACELP core synthesis - needed in SWB BWE decoding */ + Word16 old_syn_12k8_16k_tmp_16fx[L_FRAME16k]; + Copy_Scale_sig_32_16( old_syn_12k8_16k_fx, old_syn_12k8_16k_tmp_16fx, st->L_frame, sub( -1, Q ) ); + st->tilt_wb_fx = round_fx_sat( L_shl_sat( calc_tilt_bwe_fx( old_syn_12k8_16k_tmp_16fx, -1, st->L_frame ), sub( Q, 8 ) ) ); // Q24+(Q-8) - 16 + move16(); + } + + return; + } + + + test(); + test(); + IF( ( st->core == ACELP_CORE ) && !( EQ_16( st->bfi, 1 ) && EQ_16( st->con_tcx, 1 ) ) ) + { + /*----------------------------------------------------------------------* + * Calculate tilt of the ACELP core synthesis + *----------------------------------------------------------------------*/ + + st->tilt_wb_fx = ivas_calc_tilt_bwe_fx( old_syn_12k8_16k_fx, Q, st->L_frame ); + move16(); + /*-------------------------------------------------------------------------------* + * Calculate frequency energy of 0~3.2kHz and 3.2~6.4kHz the ACELP core synthesis + *-------------------------------------------------------------------------------*/ + edct_fx( old_syn_12k8_16k_fx, syn_dct_fx, L_FRAME, &Q ); + Word64 W_tmp = 0; + move64(); + Word32 tmp; + Word16 shift; + FOR( i = 0; i < L_FRAME / 2; i++ ) + { + W_tmp = W_add( W_tmp, W_shr( W_mult0_32_32( syn_dct_fx[i], syn_dct_fx[i] ), Q ) ); + } + shift = W_norm( W_tmp ); + W_tmp = W_shl( W_tmp, shift ); + tmp = W_extract_h( W_tmp ); + tmp = L_shr( tmp, 8 ); + + tmp = getSqrtWord32( tmp ); + st->enerLL_fx = tmp; + move32(); + st->enerLL_fx_Q = shr( sub( add( Q, shift ), 32 ), 1 ); + move16(); + W_tmp = 0; + move64(); + FOR( ; i < L_FRAME; i++ ) + { + W_tmp = W_add( W_tmp, W_shr( W_mult0_32_32( syn_dct_fx[i], syn_dct_fx[i] ), Q ) ); + } + shift = W_norm( W_tmp ); + W_tmp = W_shl( W_tmp, shift ); + tmp = W_extract_h( W_tmp ); // Q = Q + shift - 32 + tmp = L_shr( tmp, 7 ); // divide by 128 + tmp = getSqrtWord32( tmp ); + st->enerLH_fx = tmp; + move32(); + st->enerLH_fx_Q = shr( sub( add( Q, shift ), 32 ), 1 ); + move16(); + } + ELSE + { + IF( st->hHQ_core->old_is_transient[0] ) + { + Word32 tmp, L_tmp = 0; + move32(); + FOR( i = 0; i < 32; i++ ) + { + L_tmp = L_mac0_o( L_tmp, st->t_audio_q_fx[i], st->t_audio_q_fx[i], &Overflow ); + } + tmp = L_shr( L_tmp, 5 ); // divide by 32 + tmp = getSqrtWord32( tmp ); + st->enerLL_fx = tmp; + move32(); + st->enerLL_fx_Q = Q_audio; + move16(); + + L_tmp = 0; + move32(); + FOR( ; i < 64; i++ ) + { + L_tmp = L_mac0_o( L_tmp, st->t_audio_q_fx[i], st->t_audio_q_fx[i], &Overflow ); + } + + tmp = L_shr( L_tmp, 5 ); // divide by 32 + tmp = getSqrtWord32( tmp ); + st->enerLH_fx = tmp; + move32(); + st->enerLH_fx_Q = Q_audio; + move16(); + } + ELSE + { + Word32 tmp, L_tmp = 0; + move32(); + FOR( i = 0; i < L_FRAME / 2; i++ ) + { + L_tmp = L_mac0_o( L_tmp, st->t_audio_q_fx[i], st->t_audio_q_fx[i], &Overflow ); + } + tmp = L_shr( L_tmp, 5 ); // divide by 32 + tmp = getSqrtWord32( tmp ); + st->enerLL_fx = tmp; + move32(); + st->enerLL_fx_Q = Q_audio; + move16(); + + L_tmp = 0; + move32(); + FOR( ; i < L_FRAME; i++ ) + { + L_tmp = L_mac0_o( L_tmp, st->t_audio_q_fx[i], st->t_audio_q_fx[i], &Overflow ); + } + tmp = L_shr( L_tmp, 5 ); // divide by 32 + tmp = getSqrtWord32( tmp ); + st->enerLL_fx = tmp; + move32(); + st->enerLL_fx_Q = Q_audio; + move16(); + } + } + + test(); + test(); + test(); + test(); + test(); + test(); + test(); + IF( EQ_16( st->last_bwidth, 0 ) && LE_16( st->extl, SWB_CNG ) ) + { + + st->prev_ener_shb_fx = 0; + move16(); + IF( st->hBWE_FD != NULL ) + { + set16_fx( st->prev_SWB_fenv_fx, 0, SWB_FENV ); + } + } + ELSE IF( ( ( ( st->core == ACELP_CORE ) && ( EQ_16( st->last_core, HQ_CORE ) || EQ_16( st->last_core, TCX_10_CORE ) || EQ_16( st->last_core, TCX_20_CORE ) ) ) || ( EQ_16( st->core, st->last_core ) && NE_16( st->extl, st->last_extl ) ) ) && GE_16( st->last_bwidth, SWB ) ) + { + st->attenu_fx = 3277; // 0.1f in Q15 + move16(); + } + + test(); + test(); + test(); + test(); + test(); + if ( EQ_16( st->last_core, HQ_CORE ) || ( ( st->last_core == ACELP_CORE ) && !( EQ_16( st->last_extl, WB_TBE ) || EQ_16( st->last_extl, SWB_TBE ) || EQ_16( st->last_extl, FB_TBE ) ) && GT_32( st->core_brate, ACELP_8k00 ) ) ) + { + st->prev_fractive = 0; + move16(); + } + + return; +} diff --git a/lib_dec/d_gain2p.c b/lib_dec/d_gain2p.c deleted file mode 100644 index bcdeaa0415b3291cebf3e4463a6e123980ab180f..0000000000000000000000000000000000000000 --- a/lib_dec/d_gain2p.c +++ /dev/null @@ -1,43 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include -#include "prot.h" -#include "cnst.h" -#include "rom_com.h" -#include "wmc_auto.h" diff --git a/lib_dec/d_gain2p_fx.c b/lib_dec/d_gain2p_fx.c index 3af3affc3e792c8ee82c453d53181a0e24574b24..4d1c101c05441b731f8d866b3d1b8e5cc92c40e3 100644 --- a/lib_dec/d_gain2p_fx.c +++ b/lib_dec/d_gain2p_fx.c @@ -43,11 +43,7 @@ static Word32 calc_gain_code_fx( Word16 g_code, Word16 gcode0, Word16 exp_gcode0 L_tmp = L_mult( g_code, gcode0 ); /* Q11*Q15 -> Q27 */ exp_gcode0 = add( exp_gcode0, -11 ); -#ifdef BASOP_NOGLOB L_tmp = L_shl_sat( L_tmp, exp_gcode0 ); /* Q27 -> Q16 */ -#else - L_tmp = L_shl( L_tmp, exp_gcode0 ); /* Q27 -> Q16 */ -#endif return L_tmp; } @@ -81,11 +77,7 @@ static void Mode2_gain_dec_mless_fx( /**gain_inov = 1.0f / (float)sqrt( ( dot_product( code, code, lcode ) + 0.01f ) / lcode);*/ L_tmp = calc_gain_inov( code, lcode, &L_tmp1, &exp_L_tmp1 ); -#ifdef BASOP_NOGLOB *gain_inov = round_fx_sat( L_shl_sat( L_tmp, 15 - 3 ) ); /* gain_inov in Q12 */ -#else - *gain_inov = round_fx( L_shl( L_tmp, 15 - 3 ) ); /* gain_inov in Q12 */ -#endif move16(); /*-----------------------------------------------------------------* * Select the gains quantization table @@ -203,11 +195,7 @@ static void gain_dec_uv_fx( move16(); *past_gcode = L_tmp; move32(); -#ifdef BASOP_NOGLOB L_tmp = L_shl_sat( Mpy_32_16_1( L_tmp, *gain_inov ), 3 ); /* Q16*Q12 -> Q13 -> Q16 */ -#else - L_tmp = L_shl( Mpy_32_16_1( L_tmp, *gain_inov ), 3 ); /* Q16*Q12 -> Q13 -> Q16 */ -#endif *gain_code = L_tmp; move32(); @@ -269,11 +257,7 @@ static void gain_dec_gacelp_uv_fx( /* g_code2 = pred_nrg_frame * norm_code2; */ L_tmp = Mpy_32_16_1( pred_nrg_frame, norm_code2 ); /* 18Q13 */ i = norm_l( L_tmp ); -#ifdef BASOP_NOGLOB g_code2 = round_fx_sat( L_shl_sat( L_tmp, i ) ); -#else - g_code2 = round_fx( L_shl( L_tmp, i ) ); -#endif exp_gcode2 = sub( 18, i ); /*-----------------------------------------------------------------* @@ -313,11 +297,7 @@ static void gain_dec_gacelp_uv_fx( *past_gcode = L_shl( L_tmp1, sub( exp_L_tmp1, 15 ) ); /* Q16 */ move32(); -#ifdef BASOP_NOGLOB *gain_code = L_shl_sat( Mpy_32_16_1( *past_gcode, *gain_inov ), 3 ); -#else - *gain_code = L_shl( Mpy_32_16_1( *past_gcode, *gain_inov ), 3 ); -#endif move32(); diff --git a/lib_dec/dec2t32.c b/lib_dec/dec2t32.c deleted file mode 100644 index 6b94be229c8053da69de10ebf2fa0cba4eb9830b..0000000000000000000000000000000000000000 --- a/lib_dec/dec2t32.c +++ /dev/null @@ -1,55 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include "cnst.h" -#include "prot.h" -#include "wmc_auto.h" - -/*----------------------------------------------------------------------------------* - * dec_acelp_2t32() - * - * 12 bits algebraic codebook decoder. - * 2 track x 32 positions per track = 64 samples. - * - * 12 bits --> 2 pulses in a frame of 64 samples. - * - * All pulses can have two (2) possible amplitudes: +1 or -1. - * Each pulse can have 32 possible positions. - * - * See cod2t32.c for more details of the algebraic code. - *----------------------------------------------------------------------------------*/ diff --git a/lib_dec/dec4t64.c b/lib_dec/dec4t64.c deleted file mode 100644 index e931b0a6816a8af39857cb89c8b4839671fe8de6..0000000000000000000000000000000000000000 --- a/lib_dec/dec4t64.c +++ /dev/null @@ -1,43 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include "cnst.h" -#include "prot.h" -#include "ivas_prot.h" -#include "rom_com.h" -#include "wmc_auto.h" diff --git a/lib_dec/dec4t64_fx.c b/lib_dec/dec4t64_fx.c index 58f9048c4c69194c0874af32fad1343b5a9bde92..ee6ef65a6ce3aa2b91e1020f51ad5f12405baa84 100644 --- a/lib_dec/dec4t64_fx.c +++ b/lib_dec/dec4t64_fx.c @@ -793,242 +793,7 @@ void D_ACELP_decode_43bit_fx( UWord16 idxs[], Word16 code[], Word16 *pulsestrack return; } -#ifdef IVAS_CODE_FCB -/*-------------------------------------------------------* - * dec_1p_N1() - * - * Decode 1 pulse with N+1 bits - *-------------------------------------------------------*/ - -static void dec_1p_N1_L_subfr( - const int32_t index, /* i : quantization index */ - const int16_t nb_pos, /* i : number of positions */ - const int16_t N, /* i : nb. of bits */ - int16_t pos[] /* o : pulse position */ -) -{ - int16_t i, pos1; - int32_t mask; - - mask = ( ( 1 << N ) - 1 ); - pos1 = (int16_t) ( index & mask ); - i = (int16_t) ( index >> N ) & 1; - - if ( i == 1 ) - { - pos1 += nb_pos; - } - - pos[0] = pos1; - - return; -} - -/*-------------------------------------------------------* - * add_pulses() - * - * Add decoded pulses to the codeword - *-------------------------------------------------------*/ - -static void add_pulses_L_subfr( - const int16_t nb_pos, /* i : number of positions */ - const int16_t pos[], /* i : pulse position */ - const int16_t nb_pulse, /* i : nb. of pulses */ - const int16_t track, /* i : no. of the tracks */ - float code[] /* i/o: decoded codevector */ -) -{ - int16_t i, k; - - for ( k = 0; k < nb_pulse; k++ ) - { - i = ( ( pos[k] & ( nb_pos - 1 ) ) * NB_TRACK_FCB_4T ) + track; - if ( ( pos[k] & nb_pos ) == 0 ) - { - code[i] += 1.0f; - } - else - { - code[i] -= 1.0f; - } - } - - return; -} - -/*----------------------------------------------------------------------------------* - * dec_acelp_fast() - * - * fast algebraic codebook decoder - *----------------------------------------------------------------------------------*/ - -void dec_acelp_fast( - Decoder_State *st, /* i/o: decoder state structure */ - const int16_t cdk_index, /* i : codebook index */ - float code[], /* o : algebraic (fixed) codebook excitation */ - const int16_t L_subfr /* i : subframe length */ -) -{ - int16_t k, pos[7], skip_track; - int32_t L_index; - PulseConfig config; - - skip_track = -1; - set_f( code, 0.0f, L_subfr ); - - if ( L_subfr == L_SUBFR ) - { - config = PulseConfTable[cdk_index]; - - if ( cdk_index == 2 ) - { - dec_acelp_2t32( st, code ); - } - else if ( config.nb_pulse == 2 ) - { - /* 10 bits, 2 pulses, 4 tracks 1010 (used only even tracks) */ - for ( k = 0; k < NB_TRACK_FCB_4T - 1; k += 2 ) - { - L_index = get_next_indice( st, 5 ); - dec_1p_N1( L_index, 4, 0, pos ); - add_pulses( pos, 1, k, code ); - } - } - else if ( config.nb_pulse == 3 ) - { - if ( config.codetrackpos == TRACKPOS_FIXED_FIRST ) - { - /* 15 bits, 3 pulses, 4 tracks 1110 fixed track to first ? */ - for ( k = 0; k < NB_TRACK_FCB_4T - 1; k++ ) - { - L_index = get_next_indice( st, 5 ); - dec_1p_N1( L_index, 4, 0, pos ); - add_pulses( pos, 1, k, code ); - } - } - else if ( config.codetrackpos == TRACKPOS_FREE_THREE ) - { - /* 17 bits, 3 pulses, 4 tracks (used all tracks) - 1110, 1101, 1011, 0111 */ - skip_track = get_next_indice( st, 2 ); - for ( k = 0; k < NB_TRACK_FCB_4T; k++ ) - { - if ( k != skip_track ) - { - L_index = get_next_indice( st, 5 ); - dec_1p_N1( L_index, 4, 0, pos ); - add_pulses( pos, 1, k, code ); - } - } - } - } - else - { - if ( config.bits == 20 ) - { - skip_track = -1; - } - else if ( config.codetrackpos == TRACKPOS_FIXED_FIRST ) - { - skip_track = 0; - } - else if ( config.codetrackpos == TRACKPOS_FREE_ONE ) - { - skip_track = get_next_indice( st, 2 ); - } - - for ( k = 0; k < NB_TRACK_FCB_4T; k++ ) - { - if ( k == skip_track ) - { - L_index = get_next_indice( st, 9 ); - dec_2p_2N1( L_index, 4, 0, pos ); - add_pulses( pos, 2, k, code ); - } - else - { - L_index = get_next_indice( st, 5 ); - dec_1p_N1( L_index, 4, 0, pos ); - add_pulses( pos, 1, k, code ); - } - } - } - } - else /* L_subfr == 2*L_SUBFR */ - { - config.bits = cdk_index; - - if ( cdk_index == 14 ) - { - /* 14 bits, 2 pulses, 2 tracks: 11 (used all tracks) */ - int16_t index, i0, i1; - - index = get_next_indice( st, 14 ); - - i0 = ( ( index >> 7 ) & ( NB_POS_FCB_2T_128 - 1 ) ) * NB_TRACK_FCB_2T; - i1 = ( ( index & ( NB_POS_FCB_2T_128 - 1 ) ) * NB_TRACK_FCB_2T ) + 1; - - code[i0] = -1.0f; - if ( ( index & 0x2000 ) == 0 ) - { - code[i0] = 1.0f; - } - - code[i1] = -1.0f; - if ( ( index & 0x40 ) == 0 ) - { - code[i1] = 1.0f; - } - } - else if ( cdk_index == 12 ) - { - /* 12 bits, 2 pulses, 4 tracks: 1010 (used only even tracks) */ - for ( k = 0; k < NB_TRACK_FCB_4T - 1; k += 2 ) - { - L_index = get_next_indice( st, 6 ); - dec_1p_N1_L_subfr( L_index, NB_POS_FCB_4T_128, 5, pos ); - add_pulses_L_subfr( NB_POS_FCB_4T_128, pos, 1, k, code ); - } - } - else if ( cdk_index == 18 ) - { - /* 18 bits, 3 pulses, 4 tracks: 1110 (used first three tracks) */ - for ( k = 0; k < NB_TRACK_FCB_4T - 1; k++ ) - { - L_index = get_next_indice( st, 6 ); - dec_1p_N1_L_subfr( L_index, NB_POS_FCB_4T_128, 5, pos ); - add_pulses_L_subfr( NB_POS_FCB_4T_128, pos, 1, k, code ); - } - } - else if ( cdk_index == 20 ) - { - /* 20 bits, 3 pulses, 4 tracks (used all tracks): 1110, 1101, 1011, 0111 */ - skip_track = get_next_indice( st, 2 ); - for ( k = 0; k < NB_TRACK_FCB_4T; k++ ) - { - if ( k != skip_track ) - { - L_index = get_next_indice( st, 6 ); - dec_1p_N1_L_subfr( L_index, NB_POS_FCB_4T_128, 5, pos ); - add_pulses_L_subfr( NB_POS_FCB_4T_128, pos, 1, k, code ); - } - } - } - else if ( cdk_index == 24 ) - { - /* 24 bits, 4 pulses, 4 tracks: 1111 */ - for ( k = 0; k < NB_TRACK_FCB_4T; k++ ) - { - L_index = get_next_indice( st, 6 ); - dec_1p_N1_L_subfr( L_index, NB_POS_FCB_4T_128, 5, pos ); - add_pulses_L_subfr( NB_POS_FCB_4T_128, pos, 1, k, code ); - } - } - } - - return; -} -#endif /*-------------------------------------------------------* * dec_1p_N1() diff --git a/lib_dec/dec_LPD.c b/lib_dec/dec_LPD.c deleted file mode 100644 index 9af4fa20ed52472eebe81f066ec3f3d89807e31d..0000000000000000000000000000000000000000 --- a/lib_dec/dec_LPD.c +++ /dev/null @@ -1,54 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include -#include "options.h" -#include -#include "prot.h" -#include "rom_com.h" -#include "cnst.h" -#include "basop_proto_func.h" -#include "stat_com.h" -#include "wmc_auto.h" -#include "prot_fx.h" - - -/*-------------------------------------------------------------------* - * decoder_LPD() - * - * Core decoder MODE2 - *--------------------------------------------------------------------*/ diff --git a/lib_dec/dec_LPD_fx.c b/lib_dec/dec_LPD_fx.c index 9c2e014b4f5848aeaabee3343f09e6198aab4b0f..f3443349a1a542e0ff66f85b2ba1650107e1c2f8 100644 --- a/lib_dec/dec_LPD_fx.c +++ b/lib_dec/dec_LPD_fx.c @@ -448,7 +448,7 @@ void decoder_LPD_fx( IF( st->enablePlcWaveadjust ) { - if ( ( st->core == ACELP_CORE ) ) + if ( st->core == ACELP_CORE ) { st->tonality_flag = 0; move16(); diff --git a/lib_dec/dec_ace.c b/lib_dec/dec_ace.c deleted file mode 100644 index da306d76e7c9cb3b04b81593815e8dd94e8ae62a..0000000000000000000000000000000000000000 --- a/lib_dec/dec_ace.c +++ /dev/null @@ -1,42 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include "prot.h" -#include -#include "rom_com.h" -#include "wmc_auto.h" diff --git a/lib_dec/dec_ace_fx.c b/lib_dec/dec_ace_fx.c index df518a39549fff9de4220971f06d99556c8a9ec9..e327d4cfb958cacf783da1add249812e3336ceab 100644 --- a/lib_dec/dec_ace_fx.c +++ b/lib_dec/dec_ace_fx.c @@ -508,27 +508,15 @@ void decoder_acelp_fx( Ltmp = Mpy_32_16_1( gain_code2, code2[i] ); Ltmp = L_shl( Ltmp, add( 5, st->Q_exc ) ); Ltmp = L_mac( Ltmp, gain_pit, exc[i + i_subfr] ); -#ifdef BASOP_NOGLOB exc2[( i + i_subfr )] = round_fx_sat( L_shl_sat( Ltmp, 1 ) ); -#else - exc2[i + i_subfr] = round_fx( L_shl( Ltmp, 1 ) ); -#endif move16(); Ltmp2 = Mpy_32_16_1( gain_code, code[i] ); Ltmp2 = L_shl( Ltmp2, add( 5, st->Q_exc ) ); Ltmp = L_add( Ltmp, Ltmp2 ); BASOP_SATURATE_WARNING_OFF_EVS -#ifdef BASOP_NOGLOB Ltmp = L_shl_sat( Ltmp, 1 ); /* saturation can occur here */ -#else - Ltmp = L_shl( Ltmp, 1 ); /* saturation can occur here */ -#endif BASOP_SATURATE_WARNING_ON_EVS -#ifdef BASOP_NOGLOB exc[( i + i_subfr )] = round_fx_sat( Ltmp ); -#else - exc[i + i_subfr] = round_fx( Ltmp ); -#endif move16(); } tmp2 = L_SUBFR; @@ -641,12 +629,8 @@ void decoder_acelp_fx( Ltmp = Dot_productSq16HQ( 0, h1, L_SUBFR, &st->last_gain_syn_deemph_e ); st->last_gain_syn_deemph_e = add( st->last_gain_syn_deemph_e, 10 /*scaling of h1[0] and E_UTIL_synthesis * 2*/ ); move16(); -#ifdef BASOP_NOGLOB st->last_gain_syn_deemph = round_fx_sat( Sqrt32( Ltmp, &st->last_gain_syn_deemph_e ) ); // Q(15-last_gain_syn_deemph_e - (16)) move16(); -#else - st->last_gain_syn_deemph = round_fx( Sqrt32( Ltmp, &st->last_gain_syn_deemph_e ) ); -#endif /* Do the classification */ { diff --git a/lib_dec/dec_acelp.c b/lib_dec/dec_acelp.c deleted file mode 100644 index 7cae6239199739a71ac8690e9e1aa700d90078a5..0000000000000000000000000000000000000000 --- a/lib_dec/dec_acelp.c +++ /dev/null @@ -1,46 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include -#include "options.h" -#include "prot.h" -#include "rom_com.h" -#include "wmc_auto.h" - -/*---------------------------------------------------------------------* - * Local function prototypes - *---------------------------------------------------------------------*/ diff --git a/lib_dec/dec_acelp_tcx_main.c b/lib_dec/dec_acelp_tcx_main.c deleted file mode 100644 index 4e5d4e3aef0ff50eb31871d3c5105c3010d00f71..0000000000000000000000000000000000000000 --- a/lib_dec/dec_acelp_tcx_main.c +++ /dev/null @@ -1,43 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "prot.h" -#include "rom_com.h" -#include -#include "options.h" -#include "stat_dec.h" -#include "wmc_auto.h" diff --git a/lib_dec/dec_acelp_tcx_main_fx.c b/lib_dec/dec_acelp_tcx_main_fx.c index 7edd2354961721af2eb1ee3be18067cd3f76704f..04a41ed46c9a3ca1b4f0110d3eb3b60872886ffa 100644 --- a/lib_dec/dec_acelp_tcx_main_fx.c +++ b/lib_dec/dec_acelp_tcx_main_fx.c @@ -10,12 +10,7 @@ #include "stat_com.h" #include "prot_fx.h" #include "basop_util.h" -static void decode_frame_type_fx( Decoder_State *st -#ifdef IVAS_CODE_CNG - , - STEREO_CNG_DEC_HANDLE hStereoCng -#endif -) +static void decode_frame_type_fx( Decoder_State *st ) { Word32 L_tmp; Word16 num_bits; @@ -259,9 +254,7 @@ static void decode_frame_type_fx( Decoder_State *st IF( EQ_16( st->m_frame_type, SID_FRAME ) && NE_16( st->hFdCngDec->hFdCngCom->frame_type_previous, ACTIVE_FRAME ) ) { lerp( st->hFdCngDec->hFdCngCom->olapBufferSynth, st->hFdCngDec->hFdCngCom->olapBufferSynth, st->L_frame * 2, st->last_L_frame * 2 ); -#ifdef IVAS_CODE_CNG - lerp( hStereoCng->olapBufferSynth22, hStereoCng->olapBufferSynth22, st->L_frame * 2, st->last_L_frame * 2 ); -#endif + IF( EQ_16( st->L_frame, L_FRAME ) ) { FOR( n = 0; n < shl( st->L_frame, 1 ); n++ ) @@ -311,10 +304,6 @@ Word16 dec_acelp_tcx_frame_fx( Word32 bwe_exc_extended[], /* i/o: bandwidth extended excitation Q0 */ Word16 *voice_factors, /* o : voicing factors Q15 */ Word16 pitch_buf[] /* o : floating pitch for each subframe Q6 */ -#ifdef IVAS_CODE_CNG - , - STEREO_CNG_DEC_HANDLE hStereoCng /* i : stereo CNG handle */ -#endif ) { Word16 num_bits; @@ -366,12 +355,7 @@ Word16 dec_acelp_tcx_frame_fx( Word32 total_brate = st->last_total_brate; move32(); - decode_frame_type_fx( st -#ifdef IVAS_CODE_CNG - , - hStereoCng -#endif - ); + decode_frame_type_fx( st ); st->force_lpd_reset = 0; move16(); diff --git a/lib_dec/dec_amr_wb.c b/lib_dec/dec_amr_wb.c deleted file mode 100644 index 0874e988a748d4239c1a70f82e2ed8c1c0494117..0000000000000000000000000000000000000000 --- a/lib_dec/dec_amr_wb.c +++ /dev/null @@ -1,48 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include "cnst.h" -#include "rom_com.h" -#include "prot.h" -#include "wmc_auto.h" - -/*---------------------------------------------------------------------* - * decod_amr_wb() - * - * Decode excitation signal in AMR-WB IO mode - *---------------------------------------------------------------------*/ diff --git a/lib_dec/dec_amr_wb_fx.c b/lib_dec/dec_amr_wb_fx.c index baea98a2c0883f936ad95cb0290a90234fdcadf6..415b4584e53c884068ce8f194e63305bc2ed8dd9 100644 --- a/lib_dec/dec_amr_wb_fx.c +++ b/lib_dec/dec_amr_wb_fx.c @@ -71,12 +71,8 @@ void decod_amr_wb_fx( * Decode pitch lag *----------------------------------------------------------------------*/ - *pt_pitch_fx = pit_decode_fx( st_fx, st_fx->core_brate, 1, L_FRAME, i_subfr, -1, &pitch_limit_flag, &T0, &T0_frac, &T0_min, &T0_max, L_SUBFR -#ifdef ADD_LRTD - , - 0, NULL -#endif - ); + *pt_pitch_fx = pit_decode_fx( st_fx, st_fx->core_brate, 1, L_FRAME, i_subfr, -1, &pitch_limit_flag, &T0, &T0_frac, &T0_min, &T0_max, L_SUBFR ); + /*--------------------------------------------------------------* * Find the adaptive codebook vector *--------------------------------------------------------------*/ diff --git a/lib_dec/dec_gen_voic.c b/lib_dec/dec_gen_voic.c deleted file mode 100644 index fd4f3cb7c53af6bc1a4a149c6db6799b8f39655e..0000000000000000000000000000000000000000 --- a/lib_dec/dec_gen_voic.c +++ /dev/null @@ -1,42 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include "cnst.h" -#include "rom_com.h" -#include "prot.h" -#include "wmc_auto.h" diff --git a/lib_dec/dec_gen_voic_fx.c b/lib_dec/dec_gen_voic_fx.c index 1cfff9b84f68904f57bd8e5d3122d5fcec91af38..bdfac224f45b0efbfee46ebfe92a8acf010a9f0f 100644 --- a/lib_dec/dec_gen_voic_fx.c +++ b/lib_dec/dec_gen_voic_fx.c @@ -263,30 +263,17 @@ ivas_error decod_gen_voic_fx( Ltmp1 = L_shl_sat( Ltmp1, tmp1_fx ); /* Q16 + Q_exc */ /* Compute exc2 */ -#ifdef BASOP_NOGLOB L_tmp = L_shl_sat( L_mult( gain_pit_fx, exc_fx[i + i_subfr_fx] ), 1 ); // Q_exc+Q14+1+1 exc2_fx[i + i_subfr_fx] = round_fx_sat( L_add_sat( L_tmp, Ltmp1 ) ); // Q_exc -#else - L_tmp = L_shl( L_mult( gain_pit_fx, exc_fx[i + i_subfr_fx] ), 1 ); - exc2_fx[i + i_subfr_fx] = round_fx( L_add( L_tmp, Ltmp1 ) ); -#endif move16(); /* gain_pit in Q14 */ - L_tmp = L_mult( gain_code16, code_fx[i] ); // Q_exc+Q9+1 -#ifdef BASOP_NOGLOB + L_tmp = L_mult( gain_code16, code_fx[i] ); // Q_exc+Q9+1 L_tmp = L_shl_sat( L_tmp, 5 ); // Q_exc+Q9+1+5 L_tmp = L_mac_sat( L_tmp, exc_fx[i + i_subfr_fx], gain_pit_fx ); // Q_exc+Q15 +1 L_tmp = L_shl_sat( L_tmp, 1 ); /* saturation can occur here */ exc_fx[i + i_subfr_fx] = round_fx_sat( L_add_sat( L_tmp, Ltmp1 ) ); // Q_exc move16(); -#else - L_tmp = L_shl( L_tmp, 5 ); - L_tmp = L_mac( L_tmp, exc_fx[i + i_subfr_fx], gain_pit_fx ); - L_tmp = L_shl( L_tmp, 1 ); /* saturation can occur here */ - - exc_fx[i + i_subfr_fx] = round_fx( L_add( L_tmp, Ltmp1 ) ); -#endif } } ELSE @@ -349,13 +336,8 @@ ivas_error decod_gen_voic_fx( prev_spch_nrg = L_deposit_l( 1 ); FOR( i = 0; i < rint_bfi_pitch; i++ ) { -#ifdef BASOP_NOGLOB prev_res_nrg = L_mac0_sat( prev_res_nrg, *p_exc, *p_exc ); /* 2*st_fx->prev_Q_exc_fr */ prev_spch_nrg = L_mac0_sat( prev_spch_nrg, *p_syn, *p_syn ); /* 2*st_fx->prev_Q_syn_fr */ -#else - prev_res_nrg = L_mac0( prev_res_nrg, *p_exc, *p_exc ); /* 2*st_fx->prev_Q_exc_fr */ - prev_spch_nrg = L_mac0( prev_spch_nrg, *p_syn, *p_syn ); /* 2*st_fx->prev_Q_syn_fr */ -#endif p_exc++; p_syn++; } @@ -375,13 +357,8 @@ ivas_error decod_gen_voic_fx( curr_spch_nrg = L_deposit_l( 1 ); FOR( i = 0; i < rint_pitch; i++ ) { -#ifdef BASOP_NOGLOB curr_res_nrg = L_mac0_sat( curr_res_nrg, *p_exc, *p_exc ); /* 2*st_fx->Q_exc */ curr_spch_nrg = L_mac0_sat( curr_spch_nrg, *p_syn, *p_syn ); /* 2*st_fx->Q_syn */ -#else - curr_res_nrg = L_mac0( curr_res_nrg, *p_exc, *p_exc ); /* 2*st_fx->Q_exc */ - curr_spch_nrg = L_mac0( curr_spch_nrg, *p_syn, *p_syn ); /* 2*st_fx->Q_syn */ -#endif p_exc++; p_syn++; } @@ -394,11 +371,7 @@ ivas_error decod_gen_voic_fx( expa = sub( 30, add( expa, ( shl( st_fx->prev_Q_exc_fr, 1 ) ) ) ); expb = norm_l( curr_res_nrg ); -#ifdef BASOP_NOGLOB fracb = round_fx_sat( L_shl_sat( curr_res_nrg, expb ) ); /* 2*st_fx->Q_exc +expb+1 -16*/ -#else - fracb = round_fx( L_shl( curr_res_nrg, expb ) ); -#endif expb = sub( 30, add( expb, shl( st_fx->Q_exc, 1 ) ) ); scale = shr( sub( fraca, fracb ), 15 ); @@ -425,11 +398,7 @@ ivas_error decod_gen_voic_fx( expa = sub( 30, add( expa, shl( st_fx->prev_Q_syn_fr, 1 ) ) ); expb = norm_l( curr_spch_nrg ); -#ifdef BASOP_NOGLOB fracb = round_fx_sat( L_shl_sat( curr_spch_nrg, expb ) ); /* 2*st_fx->Q_syn +expb-16 */ -#else - fracb = round_fx( L_shl( curr_spch_nrg, expb ) ); -#endif expb = sub( 30, add( expb, shl( st_fx->Q_syn, 1 ) ) ); scale = shr( sub( fraca, fracb ), 15 ); @@ -452,19 +421,11 @@ ivas_error decod_gen_voic_fx( test(); test(); test(); -#ifdef BASOP_NOGLOB IF( GT_16( shl_ro( enratio, sub( 15, Qenratio ), &Overflow ), 8192 ) && /*compare with 0.25 in Q15*/ LT_16( shl_ro( enratio, sub( 10, Qenratio ), &Overflow ), 15360 ) && /*compare with 15.0 in Q10*/ GT_16( shl_ro( sp_enratio, sub( 15, Qsp_enratio ), &Overflow ), 4915 ) && /*compare with 0.15 in Q15*/ LT_16( st_fx->bfi_pitch_fx, 9600 ) && /*Q6*/ LT_16( pitch_buf_fx[NB_SUBFR16k - 1], 9600 ) ) /*Q6*/ -#else - IF( GT_16( shl_r( enratio, 15 - Qenratio ), 8192 ) && /*compare with 0.25 in Q15*/ - LT_16( shl_r( enratio, 10 - Qenratio ), 15360 ) && /*compare with 15.0 in Q10*/ - GT_16( shl_r( sp_enratio, 15 - Qsp_enratio ), 4915 ) && /*compare with 0.15 in Q15*/ - st_fx->bfi_pitch_fx < 9600 && /*Q6*/ - pitch_buf_fx[sub( NB_SUBFR16k, 1 )] < 9600 ) /*Q6*/ -#endif { IF( NE_32( ( error = DTFS_new_fx( &PREVP ) ), IVAS_ERR_OK ) ) { @@ -732,7 +693,11 @@ ivas_error decod_gen_voic_ivas_fx( * Transform domain contribution decoding *-----------------------------------------------------------------*/ test(); +#ifdef NONBE_FIX_GSC_BSTR + IF( !st_fx->inactive_coder_type_flag && st_fx->coder_type == INACTIVE ) +#else IF( GE_32( st_fx->total_brate, MAX_GSC_INACTIVE_BRATE ) && ( st_fx->coder_type == INACTIVE ) ) +#endif { transf_cdbk_dec_fx( st_fx, harm_flag_acelp, i_subfr_fx, Es_pred_fx, gain_code_fx, &gain_preQ_fx, &norm_gain_preQ_fx, code_preQ_fx, unbits ); } @@ -794,37 +759,20 @@ ivas_error decod_gen_voic_ivas_fx( Word32 Ltmp1; /* Contribution from AVQ layer */ Ltmp1 = L_mult( gain_preQ_fx, code_preQ_fx[i] ); /* Q2 + Q6 -> Q9*/ -#ifdef BASOP_NOGLOB - Ltmp1 = L_shl_sat( Ltmp1, tmp1_fx ); /* Q16 + Q_exc */ -#else - Ltmp1 = L_shl( Ltmp1, tmp1_fx ); /* Q16 + Q_exc */ -#endif + Ltmp1 = L_shl_sat( Ltmp1, tmp1_fx ); /* Q16 + Q_exc */ /* Compute exc2 */ -#ifdef BASOP_NOGLOB L_tmp = L_shl_sat( L_mult( gain_pit_fx, exc_fx[i + i_subfr_fx] ), 1 ); exc2_fx[i + i_subfr_fx] = round_fx_sat( L_add_sat( L_tmp, Ltmp1 ) ); // Q_exc -#else - L_tmp = L_shl( L_mult( gain_pit_fx, exc_fx[i + i_subfr_fx] ), 1 ); - exc2_fx[i + i_subfr_fx] = round_fx( L_add( L_tmp, Ltmp1 ) ); -#endif move16(); /* gain_pit in Q14 */ - L_tmp = L_mult( gain_code16, code_fx[i] ); // Q_exc+Q9+1 -#ifdef BASOP_NOGLOB + L_tmp = L_mult( gain_code16, code_fx[i] ); // Q_exc+Q9+1 L_tmp = L_shl_sat( L_tmp, 5 ); // Q_exc+Q9+1+5 L_tmp = L_mac_sat( L_tmp, exc_fx[i + i_subfr_fx], gain_pit_fx ); // Q_exc+16 L_tmp = L_shl_sat( L_tmp, 1 ); /* saturation can occur here */ exc_fx[i + i_subfr_fx] = round_fx_sat( L_add_sat( L_tmp, Ltmp1 ) ); // Q_exc move16(); -#else - L_tmp = L_shl( L_tmp, 5 ); - L_tmp = L_mac( L_tmp, exc_fx[i + i_subfr_fx], gain_pit_fx ); - L_tmp = L_shl( L_tmp, 1 ); /* saturation can occur here */ - - exc_fx[i + i_subfr_fx] = round_fx( L_add( L_tmp, Ltmp1 ) ); -#endif } } ELSE @@ -894,13 +842,8 @@ ivas_error decod_gen_voic_ivas_fx( move32(); FOR( i = 0; i < rint_bfi_pitch; i++ ) { -#ifdef BASOP_NOGLOB prev_res_nrg = L_mac0_sat( prev_res_nrg, *p_exc, *p_exc ); /* 2*st_fx->prev_Q_exc_fr */ prev_spch_nrg = L_mac0_sat( prev_spch_nrg, *p_syn, *p_syn ); /* 2*st_fx->prev_Q_syn_fr */ -#else - prev_res_nrg = L_mac0( prev_res_nrg, *p_exc, *p_exc ); /* 2*st_fx->prev_Q_exc_fr */ - prev_spch_nrg = L_mac0( prev_spch_nrg, *p_syn, *p_syn ); /* 2*st_fx->prev_Q_syn_fr */ -#endif p_exc++; p_syn++; } @@ -986,19 +929,11 @@ ivas_error decod_gen_voic_ivas_fx( test(); test(); test(); -#ifdef BASOP_NOGLOB IF( GT_16( shl_ro( enratio, sub( 15, Qenratio ), &Overflow ), 8192 ) && /*compare with 0.25 in Q15*/ LT_16( shl_ro( enratio, sub( 10, Qenratio ), &Overflow ), 15360 ) && /*compare with 15.0 in Q10*/ GT_16( shl_ro( sp_enratio, sub( 15, Qsp_enratio ), &Overflow ), 4915 ) && /*compare with 0.15 in Q15*/ LT_16( st_fx->bfi_pitch_fx, 9600 ) && /*Q6*/ LT_16( pitch_buf_fx[( NB_SUBFR16k - 1 )], 9600 ) ) /*Q6*/ -#else - IF( GT_16( shl_r( enratio, 15 - Qenratio ), 8192 ) && /*compare with 0.25 in Q15*/ - LT_16( shl_r( enratio, 10 - Qenratio ), 15360 ) && /*compare with 15.0 in Q10*/ - GT_16( shl_r( sp_enratio, 15 - Qsp_enratio ), 4915 ) && /*compare with 0.15 in Q15*/ - st_fx->bfi_pitch_fx < 9600 && /*Q6*/ - pitch_buf_fx[sub( NB_SUBFR16k, 1 )] < 9600 ) /*Q6*/ -#endif { IF( NE_32( ( error = DTFS_new_fx( &PREVP ) ), IVAS_ERR_OK ) ) { diff --git a/lib_dec/dec_higher_acelp.c b/lib_dec/dec_higher_acelp.c deleted file mode 100644 index 2a9bb28cb10ce6aa83cbcd6a71f6cd31fadf4659..0000000000000000000000000000000000000000 --- a/lib_dec/dec_higher_acelp.c +++ /dev/null @@ -1,50 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include -#include "cnst.h" -#include "prot.h" -#include "rom_com.h" -#include "wmc_auto.h" -#include "prot_fx.h" - -/*-----------------------------------------------------------------* - * transf_cdbk_dec() - * - * Transform domain contribution decoding - *-----------------------------------------------------------------*/ diff --git a/lib_dec/dec_higher_acelp_fx.c b/lib_dec/dec_higher_acelp_fx.c index 49789732cb37758d0b8c36fa349732df765fb49c..aff7e56564e134e0492ba56f92bed3e6882af87b 100644 --- a/lib_dec/dec_higher_acelp_fx.c +++ b/lib_dec/dec_higher_acelp_fx.c @@ -8,7 +8,6 @@ #include "prot_fx.h" /* Function prototypes */ #include "rom_com.h" /* Static table prototypes */ -#define IVAS_CODE #define IVAS_CODE_AVQ /*-----------------------------------------------------------------* * transf_cdbk_dec() @@ -36,7 +35,6 @@ void transf_cdbk_dec_fx( Flag Overflow = 0; move32(); #endif -#ifdef IVAS_CODE Word16 avq_bit_sFlag; Word16 trgtSvPos; Word16 Nsv; @@ -50,7 +48,7 @@ void transf_cdbk_dec_fx( move16(); avq_bit_sFlag = 1; } -#endif + /*--------------------------------------------------------------* * Set bit-allocation *--------------------------------------------------------------*/ @@ -83,13 +81,8 @@ void transf_cdbk_dec_fx( } L_tmp = Mult_32_16( gain_code, gain16 ); /* Q16 * Q12 - 15 -> Q13*/ -#ifdef BASOP_NOGLOB - L_tmp = L_shl_sat( L_tmp, 5 ); /* Q13 -> Q18*/ - *gain_preQ = round_fx_sat( L_tmp ); /* Q2*/ -#else - L_tmp = L_shl( L_tmp, 5 ); /* Q13 -> Q18*/ - *gain_preQ = round_fx( L_tmp ); /* Q2*/ -#endif + L_tmp = L_shl_sat( L_tmp, 5 ); /* Q13 -> Q18*/ + *gain_preQ = round_fx_sat( L_tmp ); /* Q2*/ move16(); } ELSE @@ -117,7 +110,7 @@ void transf_cdbk_dec_fx( *gain_preQ = round_fx( L_tmp ); /* Q2*/ move16(); } -#ifdef IVAS_CODE + trgtSvPos = sub( Nsv, 1 ); test(); test(); @@ -131,7 +124,7 @@ void transf_cdbk_dec_fx( move16(); move16(); } -#endif + /*--------------------------------------------------------------* * Demultiplex and decode subvectors from bit-stream *--------------------------------------------------------------*/ @@ -154,11 +147,7 @@ void transf_cdbk_dec_fx( #endif FOR( i = 0; i < L_SUBFR; i++ ) { -#ifdef BASOP_NOGLOB code_preQ[i] = shl_o( code_preQ[i], q_Code_preQ, &Overflow ); -#else - code_preQ[i] = shl( code_preQ[i], q_Code_preQ ); -#endif move16(); /* code_preQ in Q6*/ } diff --git a/lib_dec/dec_nelp.c b/lib_dec/dec_nelp.c deleted file mode 100644 index e7a8ca967132cf8896fc4a231dbaf74eed596840..0000000000000000000000000000000000000000 --- a/lib_dec/dec_nelp.c +++ /dev/null @@ -1,41 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include "cnst.h" -#include "prot.h" -#include "wmc_auto.h" diff --git a/lib_dec/dec_pit_exc.c b/lib_dec/dec_pit_exc.c deleted file mode 100644 index e5ee5c0c04b0adc8423be1951998a54e6ca01b6d..0000000000000000000000000000000000000000 --- a/lib_dec/dec_pit_exc.c +++ /dev/null @@ -1,48 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include "cnst.h" -#include "rom_com.h" -#include "prot.h" -#include "wmc_auto.h" - -/*-------------------------------------------------------------------* - * dec_pit_exc() - * - * Decode pitch-only contribution (used by the GSC technology) - *-------------------------------------------------------------------*/ diff --git a/lib_dec/dec_pit_exc_fx.c b/lib_dec/dec_pit_exc_fx.c index f3bb07aef0387a63838dd1ed88806984ee88d6e0..746b668198d4c2d0a3ff030739b0d40d82b23952 100644 --- a/lib_dec/dec_pit_exc_fx.c +++ b/lib_dec/dec_pit_exc_fx.c @@ -41,11 +41,6 @@ void dec_pit_exc_fx( const Word16 nb_subfr_fx /* i : Number of subframe considered */ , Word16 *gain_buf /*Q14*/ -#ifdef ADD_LRTD - , - const Word16 tdm_Pitch_reuse_flag, /* i : primary channel pitch reuse flag */ - const Word16 tdm_Pri_pitch_buf[] /* i : primary channel pitch buffer */ -#endif ) { Word16 T0_fx, T0_frac_fx, T0_min_fx, T0_max_fx; /* integer pitch variables */ @@ -179,12 +174,7 @@ void dec_pit_exc_fx( /*----------------------------------------------------------------------* * Decode pitch lag *----------------------------------------------------------------------*/ - *pt_pitch_fx = pit_decode_fx( st_fx, Pitch_BR_fx, 0, st_fx->L_frame, i_subfr_fx, Pitch_CT_fx, &pitch_limit_flag, &T0_fx, &T0_frac_fx, &T0_min_fx, &T0_max_fx, L_subfr_fx -#ifdef ADD_LRTD - , - tdm_Pitch_reuse_flag, tdm_Pri_pitch_buf -#endif - ); + *pt_pitch_fx = pit_decode_fx( st_fx, Pitch_BR_fx, 0, st_fx->L_frame, i_subfr_fx, Pitch_CT_fx, &pitch_limit_flag, &T0_fx, &T0_frac_fx, &T0_min_fx, &T0_max_fx, L_subfr_fx ); move16(); /*--------------------------------------------------------------* @@ -207,12 +197,7 @@ void dec_pit_exc_fx( gain_dec_mless_fx( st_fx, st_fx->L_frame, LOCAL_CT, i_subfr_fx, -1, code_fx, Es_pred_fx, &gain_pit_fx, &gain_code_fx, &gain_inov_fx, &norm_gain_code_fx ); - st_fx->tilt_code_fx = est_tilt_fx( exc_fx + i_subfr_fx, gain_pit_fx, code_fx, gain_code_fx, &voice_fac_fx, 0 -#ifdef ADD_LRTD - , - L_subfr_fx -#endif - ); + st_fx->tilt_code_fx = est_tilt_fx( exc_fx + i_subfr_fx, gain_pit_fx, code_fx, gain_code_fx, &voice_fac_fx, 0 ); move16(); } ELSE IF( EQ_16( use_fcb, 2 ) ) /* IVAS only */ @@ -225,12 +210,7 @@ void dec_pit_exc_fx( gain_dec_lbr_fx( st_fx, GENERIC, i_subfr_fx, code_fx, &gain_pit_fx, &gain_code_fx, &gain_inov_fx, &norm_gain_code_fx, gc_mem, gp_mem, L_subfr_fx ); - st_fx->tilt_code_fx = est_tilt_fx( exc_fx + i_subfr_fx, gain_pit_fx, code_fx, gain_code_fx, &voice_fac_fx, 0 -#ifdef ADD_LRTD - , - L_subfr_fx -#endif - ); + st_fx->tilt_code_fx = est_tilt_fx( exc_fx + i_subfr_fx, gain_pit_fx, code_fx, gain_code_fx, &voice_fac_fx, 0 ); move16(); } ELSE @@ -258,11 +238,7 @@ void dec_pit_exc_fx( gain_pit_fx = st_fx->lp_gainp_fx; move16(); } -#ifdef BASOP_NOGLOB gain_code_fx = L_mult0( s_max( sub( 32767, shl_o( gain_pit_fx, 1, &Overflow ) ), 16384 ), st_fx->lp_gainc_fx ); /* Use gain pitch and past gain code as an indicator to help finding the best scaling value. gain_code_fx used a temp var*/ -#else - gain_code_fx = L_mult0( s_max( sub( 32767, shl( gain_pit_fx, 1 ) ), 16384 ), st_fx->lp_gainc_fx ); /* Use gain pitch and past gain code as an indicator to help finding the best scaling value. gain_code_fx used a temp var*/ -#endif } /*----------------------------------------------------------------------* @@ -284,13 +260,8 @@ void dec_pit_exc_fx( { FOR( i = 0; i < L_subfr_fx; i++ ) { -#ifdef BASOP_NOGLOB L_tmp = L_shl_sat( L_mult( gain_pit_fx, exc_fx[i + i_subfr_fx] ), 1 ); /*Q16+Q_exc*/ exc_fx[i + i_subfr_fx] = round_fx_sat( L_tmp ); /*Q_exc*/ -#else - L_tmp = L_shl( L_mult( gain_pit_fx, exc_fx[i + i_subfr_fx] ), 1 ); /*Q16+Q_exc*/ - exc_fx[i + i_subfr_fx] = round_fx( L_tmp ); /*Q_exc*/ -#endif move16(); } } @@ -301,11 +272,7 @@ void dec_pit_exc_fx( FOR( i = 0; i < L_subfr_fx; i++ ) { L_tmp = L_mult( gain_pitx2, exc_fx[i + i_subfr_fx] ); /*Q16+Q_exc*/ -#ifdef BASOP_NOGLOB - exc_fx[i + i_subfr_fx] = round_fx_sat( L_tmp ); /*Q_exc*/ -#else - exc_fx[i + i_subfr_fx] = round_fx( L_tmp ); /*Q_exc*/ -#endif + exc_fx[i + i_subfr_fx] = round_fx_sat( L_tmp ); /*Q_exc*/ move16(); } } @@ -470,22 +437,18 @@ void dec_pit_exc_fx( /* _ None */ /*==========================================================================*/ void dec_pit_exc_ivas_fx( - Decoder_State *st_fx, /* i/o: decoder static memory */ - const Word16 *Aq_fx, /* i : LP filter coefficient */ - const Word16 coder_type, /* i : coding type */ - const Word16 Es_pred_fx, /* i : predicted scaled innov. energy */ - Word16 *pitch_buf_fx, /* o : Word16 pitch values for each subframe */ - Word16 *code_fx, /* o : innovation */ - Word16 *exc_fx, /* i/o: adapt. excitation exc */ - Word16 *bwe_exc_fx, /* o : excitation for SWB TBE */ - const Word16 nb_subfr_fx /* i : Number of subframe considered */ - , - Word16 *gain_buf /*Q14*/ -#if 1 // def ADD_LRTD - , + Decoder_State *st_fx, /* i/o: decoder static memory */ + const Word16 *Aq_fx, /* i : LP filter coefficient */ + const Word16 coder_type, /* i : coding type */ + const Word16 Es_pred_fx, /* i : predicted scaled innov. energy */ + Word16 *pitch_buf_fx, /* o : Word16 pitch values for each subframe */ + Word16 *code_fx, /* o : innovation */ + Word16 *exc_fx, /* i/o: adapt. excitation exc */ + Word16 *bwe_exc_fx, /* o : excitation for SWB TBE */ + const Word16 nb_subfr_fx, /* i : Number of subframe considered */ + Word16 *gain_buf, /*Q14*/ const Word16 tdm_Pitch_reuse_flag, /* i : primary channel pitch reuse flag */ const Word16 tdm_Pri_pitch_buf[] /* i : primary channel pitch buffer */ -#endif ) { Word16 T0_fx, T0_frac_fx, T0_min_fx, T0_max_fx; /* integer pitch variables */ @@ -604,9 +567,11 @@ void dec_pit_exc_ivas_fx( set16_fx( st_fx->acelp_cfg.pitch_bits, 9, 4 ); set16_fx( st_fx->acelp_cfg.fixed_cdk_index, 14, 5 ); } + /*------------------------------------------------------------------* * ACELP subframe loop *------------------------------------------------------------------*/ + p_Aq_fx = Aq_fx; /* pointer to interpolated LPC parameters */ pt_pitch_fx = pitch_buf_fx; /* pointer to the pitch buffer */ pt_gain = gain_buf; /* pointer to the gain buffer */ @@ -615,12 +580,8 @@ void dec_pit_exc_ivas_fx( /*----------------------------------------------------------------------* * Decode pitch lag *----------------------------------------------------------------------*/ - *pt_pitch_fx = pit_decode_ivas_fx( st_fx, Pitch_BR_fx, 0, st_fx->L_frame, i_subfr_fx, Pitch_CT_fx, &pitch_limit_flag, &T0_fx, &T0_frac_fx, &T0_min_fx, &T0_max_fx, L_subfr_fx -#if 1 // def ADD_LRTD - , - tdm_Pitch_reuse_flag, tdm_Pri_pitch_buf -#endif - ); + + *pt_pitch_fx = pit_decode_ivas_fx( st_fx, Pitch_BR_fx, 0, st_fx->L_frame, i_subfr_fx, Pitch_CT_fx, &pitch_limit_flag, &T0_fx, &T0_frac_fx, &T0_min_fx, &T0_max_fx, L_subfr_fx, tdm_Pitch_reuse_flag, tdm_Pri_pitch_buf ); move16(); /*--------------------------------------------------------------* @@ -636,6 +597,7 @@ void dec_pit_exc_ivas_fx( IF( EQ_16( use_fcb, 1 ) ) { inov_decode_fx( st_fx, Local_BR_fx, 0, st_fx->L_frame, 1, i_subfr_fx, p_Aq_fx, st_fx->tilt_code_fx, *pt_pitch_fx, code_fx, L_subfr_fx ); + /*--------------------------------------------------------------* * Gain decoding * Estimate spectrum tilt and voicing @@ -643,18 +605,14 @@ void dec_pit_exc_ivas_fx( gain_dec_mless_fx( st_fx, st_fx->L_frame, LOCAL_CT, i_subfr_fx, -1, code_fx, Es_pred_fx, &gain_pit_fx, &gain_code_fx, &gain_inov_fx, &norm_gain_code_fx ); - st_fx->tilt_code_fx = est_tilt_ivas_fx( exc_fx + i_subfr_fx, gain_pit_fx, code_fx, gain_code_fx, &voice_fac_fx, 0 -#if 1 // def ADD_LRTD - , - L_subfr_fx, 0 -#endif - ); + st_fx->tilt_code_fx = est_tilt_ivas_fx( exc_fx + i_subfr_fx, gain_pit_fx, code_fx, gain_code_fx, &voice_fac_fx, 0, L_subfr_fx, 0 ); move16(); } ELSE IF( EQ_16( use_fcb, 2 ) ) /* IVAS only */ { /*inov_decode_fx(st_fx, Local_BR_fx, 0, st_fx->L_frame, 1, i_subfr_fx, p_Aq_fx, st_fx->tilt_code_fx, *pt_pitch_fx, code_fx, L_subfr_fx);*/ inov_decode_fx( st_fx, st_fx->core_brate, 0, st_fx->L_frame, 0, i_subfr_fx, p_Aq_fx, st_fx->tilt_code_fx, *pt_pitch_fx, code_fx, L_subfr_fx ); + /*--------------------------------------------------------------* * Gain decoding * Estimate spectrum tilt and voicing @@ -662,12 +620,7 @@ void dec_pit_exc_ivas_fx( gain_dec_lbr_ivas_fx( st_fx, GENERIC, i_subfr_fx, code_fx, &gain_pit_fx, &gain_code_fx, &gain_inov_fx, &norm_gain_code_fx, gc_mem, gp_mem, L_subfr_fx ); - st_fx->tilt_code_fx = est_tilt_ivas_fx( exc_fx + i_subfr_fx, gain_pit_fx, code_fx, gain_code_fx, &voice_fac_fx, 0 -#if 1 // def ADD_LRTD - , - L_subfr_fx, 0 -#endif - ); + st_fx->tilt_code_fx = est_tilt_ivas_fx( exc_fx + i_subfr_fx, gain_pit_fx, code_fx, gain_code_fx, &voice_fac_fx, 0, L_subfr_fx, 0 ); move16(); } ELSE @@ -694,11 +647,7 @@ void dec_pit_exc_ivas_fx( gain_pit_fx = st_fx->lp_gainp_fx; move16(); } -#ifdef BASOP_NOGLOB gain_code_fx = L_mult0( s_max( sub( 32767, shl_o( gain_pit_fx, 1, &Overflow ) ), 16384 /*0.5.Q15*/ ), st_fx->lp_gainc_fx ); /* Use gain pitch and past gain code as an indicator to help finding the best scaling value. gain_code_fx used a temp var*/ -#else - gain_code_fx = L_mult0( s_max( sub( 32767, shl( gain_pit_fx, 1 ) ), 16384 ), st_fx->lp_gainc_fx ); /* Use gain pitch and past gain code as an indicator to help finding the best scaling value. gain_code_fx used a temp var*/ -#endif } /*----------------------------------------------------------------------* diff --git a/lib_dec/dec_post.c b/lib_dec/dec_post.c deleted file mode 100644 index 10836b7799b2982d308f8c9647c4e2f58329a7e5..0000000000000000000000000000000000000000 --- a/lib_dec/dec_post.c +++ /dev/null @@ -1,159 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include -#include "cnst.h" -#include "rom_com.h" -#include "prot.h" -#include "wmc_auto.h" - -/*---------------------------------------------------------------------* - * Local constants - *---------------------------------------------------------------------*/ - -#define FORMAT_POST_FILT_G1 0.75f /*0.75f*/ /*denominator 0.9,0.75,0.15,0.9*/ - - -/*-------------------------------------------------------------------------- - * Local function prototypes - *--------------------------------------------------------------------------*/ - - -/*--------------------------------------------------------------------------* - * Function Init_post_filter_ivas() - * - * Post-filter initialization - *--------------------------------------------------------------------------*/ - -/*-------------------------------------------------------------------------- - * nb_post_filt_ivas() - * - * Main routine to perform post filtering of NB signals - *--------------------------------------------------------------------------*/ - -/*-------------------------------------------------------------------------- - * formant_post_filt_ivas: - * - * WB and SWB formant post-filtering - *--------------------------------------------------------------------------*/ - -/*---------------------------------------------------------------------------- - * Dec_postfilt() - * - * Adaptive postfilter main function - * Short-term postfilter : - * Hst(z) = Hst0(z) Hst1(z) - * Hst0(z) = 1/g0 A(gamma2)(z) / A(gamma1)(z) - * if {hi} = i.r. filter A(gamma2)/A(gamma1) (truncated) - * g0 = SUM(|hi|) if > 1 - * g0 = 1. else - * Hst1(z) = 1/(1 - |mu|) (1 + mu z-1) - * with mu = k1 * gamma3 - * k1 = 1st parcor calculated on {hi} - * gamma3 = gamma3_minus if k1<0, gamma3_plus if k1>0 - * Long-term postfilter : - * harmonic postfilter : H0(z) = gl * (1 + b * z-p) - * b = gamma_g * gain_ltp - * gl = 1 / 1 + b - * computation of delay p on A(gamma2)(z) s(z) - * sub optimal search - * 1. search around 1st subframe delay (3 integer values) - * 2. search around best integer with fract. delays (1/8) - *----------------------------------------------------------------------------*/ - -/*---------------------------------------------------------------------------- - * Dec_formant_postfilt - * - * Post - adaptive postfilter main function - * Short term postfilter : - * Hst(z) = Hst0(z) Hst1(z) - * Hst0(z) = 1/g0 A(gamma2)(z) / A(gamma1)(z) - * if {hi} = i.r. filter A(gamma2)/A(gamma1) (truncated) - * g0 = SUM(|hi|) if > 1 - * g0 = 1. else - * Hst1(z) = 1/(1 - |mu|) (1 + mu z-1) - * with mu = k1 * gamma3 - * k1 = 1st parcor calculated on {hi} - * gamma3 = gamma3_minus if k1<0, gamma3_plus if k1>0 - *----------------------------------------------------------------------------*/ - -/*---------------------------------------------------------------------------- - * pst_ltp() - * - * Perform harmonic postfilter - *----------------------------------------------------------------------------*/ - - -/*---------------------------------------------------------------------------- - * search_del() - * - * Computes best (shortest) integer LTP delay + fine search - *---------------------------------------------------------------------------*/ - - -/*---------------------------------------------------------------------------- - * filt_plt() - * - * Perform long term postfilter - *----------------------------------------------------------------------------*/ - - -/*---------------------------------------------------------------------------- - * compute_ltp_l() - * - * compute delayed signal, num & den of gain for fractional delay - * with long interpolation filter - *----------------------------------------------------------------------------*/ - - -/*---------------------------------------------------------------------------- - * select_ltp() - * - * selects best of (gain1, gain2) - * with gain1 = num1 * 2** sh_num1 / den1 * 2** sh_den1 - * and gain2 = num2 * 2** sh_num2 / den2 * 2** sh_den2 - *----------------------------------------------------------------------------*/ - -/*! r: 1 = 1st gain, 2 = 2nd gain */ - - -/*------------------------------------------------------------------------------------ - * modify_pst_param() - * - * Modify gamma1 and gamma2 values in function of the long-term noise level - *-----------------------------------------------------------------------------------*/ diff --git a/lib_dec/dec_post_fx.c b/lib_dec/dec_post_fx.c index 27abd7b2d416e2e029a0e6aa18e187431164b579..a4f618a3fd751dec1eeea852d8e26230a86f39c8 100644 --- a/lib_dec/dec_post_fx.c +++ b/lib_dec/dec_post_fx.c @@ -86,7 +86,7 @@ void nb_post_filt_fx( const Word16 tmp_noise, /* i : noise energy Q0 */ Word16 *Synth, /* i : 12k8 synthesis Qsyn */ const Word16 *Aq, /* i : LP filter coefficient Q12 */ - const Word16 *Pitch_buf, /* i : Fractionnal subframe pitch buffer Q6 */ + const Word16 *Pitch_buf, /* i : Fractionnal subframe pitch buffer Q0 */ const Word16 coder_type, /* i : coder_type */ const Word16 BER_detect, /* i : BER detect flag */ const Word16 disable_hpf /* i : flag to diabled HPF */ @@ -142,7 +142,7 @@ void nb_post_filt_fx( move16(); FOR( i = 0; i < L_frame; i += L_SUBFR ) { - T0_first = Pitch_buf[j]; // Q6 + T0_first = Pitch_buf[j]; // Q0 move16(); Dec_postfilt_fx( hPFstat, T0_first, &Pf_in[i], p_Aq, &Synth[i], Post_G1, Post_G2, Gain_factor, disable_hpf ); @@ -179,7 +179,7 @@ void nb_post_filt_fx( *----------------------------------------------------------------------------*/ static void Dec_postfilt_fx( PFSTAT_HANDLE hPFstat, /* i : core decoder parameters */ - const Word16 t0, /* i : pitch delay given by coder Q6 */ + const Word16 t0, /* i : pitch delay given by coder Q0 */ const Word16 *signal_ptr, /* i : input signal (pointer to current subframe Q0 */ const Word16 *coeff, /* i : LPC coefficients for current subframe Q12 */ Word16 *sig_out, /* o : postfiltered output Q15*/ @@ -703,11 +703,7 @@ static void modify_pst_param_fx( test(); IF( NE_16( coder_type, INACTIVE ) && LT_16( lp_noise, LP_NOISE_THR_FX ) ) { -#ifdef BASOP_NOGLOB lp_noiseQ12 = shl_o( lp_noise, 4, &Overflow ); /* to go from Q8 to Q12 */ -#else - lp_noiseQ12 = shl( lp_noise, 4 ); /* to go from Q8 to Q12 */ -#endif /* ftmp = lp_noise*BG1_FX + CG1_FX */ tmp = mac_r( CG1_FX * 65536L, lp_noiseQ12, BG1_FX * 8 ); /* x8 to go from Q12 to Q15 */ @@ -753,7 +749,7 @@ static void modify_pst_param_fx( * Perform harmonic postfilter *----------------------------------------------------------------------------*/ static void pst_ltp_fx( - Word16 t0, /* i : pitch delay given by coder Q6 */ + Word16 t0, /* i : pitch delay given by coder Q0 */ Word16 *ptr_sig_in, /* i : postfilter i filter (residu2) Qx */ Word16 *ptr_sig_pst0, /* o : harmonic postfilter o Qx */ Word16 gain_factor /* i : Gain Factor (Q15) */ @@ -846,11 +842,7 @@ static void pst_ltp_fx( FOR( i = 0; i < L_SUBFR; i++ ) { /* nb_sh_sig may be >0, <0 or =0 */ -#ifdef BASOP_NOGLOB ptr_y_up[i] = shl_sat( ptr_y_up[i], nb_sh_sig ); -#else - ptr_y_up[i] = shl( ptr_y_up[i], nb_sh_sig ); -#endif move16(); } } @@ -884,11 +876,7 @@ static void pst_ltp_fx( /* decrease gain in noisy condition */ /* gain_plt += (1.0f-gain_plt) * gain_factor */ /* gain_plt = gain_plt + gain_factor - gain_plt*gain_factor */ -#ifdef BASOP_NOGLOB gain_plt = msu_ro( L_msu( L_deposit_h( gain_plt ), gain_plt, gain_factor ), -32768, gain_factor, &Overflow ); // Q15 -#else - gain_plt = msu_r( L_msu( L_deposit_h( gain_plt ), gain_plt, gain_factor ), -32768, gain_factor ); -#endif /** filtering by H0(z) = harmonic filter **/ filt_plt_fx( ptr_sig_in, ptr_y_up, ptr_sig_pst0, gain_plt ); @@ -944,11 +932,7 @@ static void search_del_fx( L_acc = L_mult( ptr_sig_in[0], ptr_sig_in[0] ); FOR( i = 1; i < L_SUBFR; i++ ) { -#ifdef BASOP_NOGLOB L_acc = L_mac_sat( L_acc, ptr_sig_in[i], ptr_sig_in[i] ); -#else - L_acc = L_mac( L_acc, ptr_sig_in[i], ptr_sig_in[i] ); -#endif } IF( L_acc == 0 ) { @@ -985,20 +969,12 @@ static void search_del_fx( L_acc = L_mult( ptr_sig_in[0], ptr_sig_past[0] ); FOR( n = 1; n < L_SUBFR; n++ ) { -#ifdef BASOP_NOGLOB L_acc = L_mac_sat( L_acc, ptr_sig_in[n], ptr_sig_past[n] ); -#else - L_acc = L_mac( L_acc, ptr_sig_in[n], ptr_sig_past[n] ); -#endif } L_acc = L_max( L_acc, 0 ); -#ifdef BASOP_NOGLOB L_temp = L_sub_sat( L_acc, L_num_int ); -#else - L_temp = L_sub( L_acc, L_num_int ); -#endif if ( L_temp > 0L ) { i_max = (Word16) i; @@ -1032,11 +1008,7 @@ static void search_del_fx( { temp = *ptr_sig_past++; move16(); -#ifdef BASOP_NOGLOB L_acc = L_mac_sat( L_acc, temp, temp ); -#else - L_acc = L_mac( L_acc, temp, temp ); -#endif } IF( L_acc == 0L ) { @@ -1094,30 +1066,18 @@ static void search_del_fx( L_acc = L_mult( ptr_y_up[1], ptr_y_up[1] ); FOR( n = 2; n < L_SUBFR; n++ ) { -#ifdef BASOP_NOGLOB L_acc = L_mac_sat( L_acc, ptr_y_up[n], ptr_y_up[n] ); -#else - L_acc = L_mac( L_acc, ptr_y_up[n], ptr_y_up[n] ); -#endif } L_temp0 = L_acc; /* sets to 'L_acc' in 1 clock (saved for den1) */ move32(); /* den0 */ -#ifdef BASOP_NOGLOB L_acc = L_mac_sat( L_acc, ptr_y_up[0], ptr_y_up[0] ); -#else - L_acc = L_mac( L_acc, ptr_y_up[0], ptr_y_up[0] ); -#endif *ptr_L_den0 = L_acc; move32(); /* den1 */ -#ifdef BASOP_NOGLOB L_acc = L_mac_sat( L_temp0, ptr_y_up[L_SUBFR], ptr_y_up[L_SUBFR] ); -#else - L_acc = L_mac( L_temp0, ptr_y_up[L_SUBFR], ptr_y_up[L_SUBFR] ); -#endif *ptr_L_den1 = L_acc; move32(); @@ -1208,11 +1168,7 @@ static void search_del_fx( L_acc = L_mult( ptr_sig_in[0], ptr_y_up[0] ); FOR( n = 1; n < L_SUBFR; n++ ) { -#ifdef BASOP_NOGLOB L_acc = L_mac_sat( L_acc, ptr_sig_in[n], ptr_y_up[n] ); -#else - L_acc = L_mac( L_acc, ptr_sig_in[n], ptr_y_up[n] ); -#endif } L_acc = L_shr( L_acc, sh_num ); /* sh_num > 0 */ L_acc = L_max( 0, L_acc ); @@ -1245,11 +1201,7 @@ static void search_del_fx( L_acc = L_mult( ptr_sig_in[0], ptr_y_up[0] ); FOR( n = 1; n < L_SUBFR; n++ ) { -#ifdef BASOP_NOGLOB L_acc = L_mac_sat( L_acc, ptr_sig_in[n], ptr_y_up[n] ); -#else - L_acc = L_mac( L_acc, ptr_sig_in[n], ptr_y_up[n] ); -#endif } L_acc = L_shr( L_acc, sh_num ); /* sh_num > 0 */ L_acc = L_max( 0, L_acc ); @@ -1461,11 +1413,7 @@ static void compute_ltp_l_fx( L_acc = L_mult( y_up[0], y_up[0] ); FOR( n = 1; n < L_SUBFR; n++ ) { -#ifdef BASOP_NOGLOB L_acc = L_mac_sat( L_acc, y_up[n], y_up[n] ); -#else - L_acc = L_mac( L_acc, y_up[n], y_up[n] ); -#endif } temp = sub( 16, norm_l( L_acc ) ); temp = s_max( temp, 0 ); @@ -1701,11 +1649,7 @@ void Filt_mu_fx( temp = sub( 1, abs_s( mu ) ); BASOP_SATURATE_WARNING_OFF_EVS; -#ifdef BASOP_NOGLOB mu2 = add_o( 32767, temp, &Overflow ); /* Q15 (1 - |mu|) */ -#else - mu2 = add( 32767, temp ); /* 2**15 (1 - |mu|) */ -#endif BASOP_SATURATE_WARNING_ON_EVS; ga = div_s( fact, mu2 ); /* Q(sh_fact) / (1 - |mu|) */ @@ -1719,19 +1663,11 @@ void Filt_mu_fx( L_temp = L_mac( L_acc, 16384, *ptrs ); /* sig_in(n) * 2**15 */ L_temp = Madd_32_16( L_fact, L_temp, ga ); -#ifdef BASOP_NOGLOB L_temp = L_shr_sat( L_temp, sh_fact ); /* mult. temp x ga */ -#else - L_temp = L_shr( L_temp, sh_fact ); /* mult. temp x ga */ -#endif BASOP_SATURATE_WARNING_OFF_EVS; /*sig_out[n] = saturate(L_temp); move16();*/ -#ifdef BASOP_NOGLOB sig_out[n] = round_fx_sat( L_temp ); move16(); -#else - sig_out[n] = round_fx( L_temp ); -#endif BASOP_SATURATE_WARNING_ON_EVS; } @@ -1807,11 +1743,7 @@ void Filt_mu_ivas_fx( temp = sub( 1, abs_s( mu ) ); BASOP_SATURATE_WARNING_OFF_EVS; -#ifdef BASOP_NOGLOB mu2 = add_o( 32767, temp, &Overflow ); /* Q15 (1 - |mu|) */ -#else - mu2 = add( 32767, temp ); /* 2**15 (1 - |mu|) */ -#endif BASOP_SATURATE_WARNING_ON_EVS; ga = div_s( fact, mu2 ); /* Q(sh_fact) / (1 - |mu|) */ @@ -1829,11 +1761,7 @@ void Filt_mu_ivas_fx( BASOP_SATURATE_WARNING_OFF_EVS; /*sig_out[n] = saturate(L_temp); move16();*/ -#ifdef BASOP_NOGLOB sig_out[n] = round_fx_sat( L_temp ); -#else - sig_out[n] = round_fx( L_temp ); -#endif BASOP_SATURATE_WARNING_ON_EVS; } @@ -1917,11 +1845,7 @@ void scale_st_fx( } /* L_gain_in/L_gain_out in Q14 */ /* overflows if L_gain_in > 2 * L_gain_out */ -#ifdef BASOP_NOGLOB - g0 = shr_sat( g0, sh_g0 ); /* sh_g0 may be >0, <0, or =0 */ -#else - g0 = shr( g0, sh_g0 ); /* sh_g0 may be >0, <0, or =0 */ -#endif + g0 = shr_sat( g0, sh_g0 ); /* sh_g0 may be >0, <0, or =0 */ g0 = mult_r( g0, AGC_FAC1_FX ); /* L_gain_in/L_gain_out * AGC_FAC1_FX */ } @@ -1934,13 +1858,8 @@ void scale_st_fx( temp = mult_r( AGC_FAC_FX, gain ); gain = add( temp, g0 ); /* in Q14 */ L_temp = L_mult( gain, sig_out[i] ); -#ifdef BASOP_NOGLOB L_temp = L_shl_sat( L_temp, 1 ); sig_out[i] = round_fx_sat( L_temp ); -#else - L_temp = L_shl( L_temp, 1 ); - sig_out[i] = round_fx( L_temp ); -#endif move16(); } *gain_prec = gain; @@ -1975,15 +1894,9 @@ void blend_subfr2_fx( move16(); FOR( i = 0; i < L_SUBFR / 2; i++ ) { -#ifdef BASOP_NOGLOB sigOut[i] = mac_ro( L_mult_o( fac1, sigIn1[i], &Overflow ), fac2, sigIn2[i], &Overflow ); // Qx fac1 = sub_o( fac1, step, &Overflow ); fac2 = add_o( fac2, step, &Overflow ); -#else - sigOut[i] = mac_r( L_mult( fac1, sigIn1[i] ), fac2, sigIn2[i] ); - fac1 = sub( fac1, step ); - fac2 = add( fac2, step ); -#endif move16(); } diff --git a/lib_dec/dec_ppp.c b/lib_dec/dec_ppp.c deleted file mode 100644 index e7a8ca967132cf8896fc4a231dbaf74eed596840..0000000000000000000000000000000000000000 --- a/lib_dec/dec_ppp.c +++ /dev/null @@ -1,41 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include "cnst.h" -#include "prot.h" -#include "wmc_auto.h" diff --git a/lib_dec/dec_prm.c b/lib_dec/dec_prm.c deleted file mode 100644 index 33c62a67a09e57e3f54e7cd49aace17014132f00..0000000000000000000000000000000000000000 --- a/lib_dec/dec_prm.c +++ /dev/null @@ -1,328 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include -#include "options.h" -#include "cnst.h" -#include "rom_com.h" -#include "prot.h" -#include "wmc_auto.h" -#include "prot_fx.h" - -/*-------------------------------------------------------------------* - * getTCXMode_ivas() - * - * get TCX mode - *--------------------------------------------------------------------*/ -void getTCXMode_ivas_fx( - Decoder_State *st, /* i/o: decoder memory state */ - Decoder_State *st0, /* i : bitstream */ - const Word16 MCT_flag /* i : hMCT handle allocated (1) or not (0) */ -) -{ - UWord16 ind; - - IF( st->tcxonly ) - { - /* get core */ - ind = get_next_indice_fx( st0, 1 ); /* Store decoder memory of last_core */ - st->core = add( ind, TCX_20_CORE ); - move16(); - /* get class */ - ind = get_next_indice_fx( st0, 2 ); - - st->clas_dec = ONSET; - move16(); - IF( ind == 0 ) - { - st->clas_dec = UNVOICED_CLAS; - move16(); - } - ELSE IF( EQ_16( ind, 1 ) ) - { - IF( GE_16( st->last_good, VOICED_TRANSITION ) ) - { - st->clas_dec = VOICED_TRANSITION; - move16(); - } - ELSE - { - st->clas_dec = UNVOICED_TRANSITION; - move16(); - } - } - ELSE IF( EQ_16( ind, 2 ) ) - { - st->clas_dec = VOICED_CLAS; - move16(); - } - - st->coder_type = INACTIVE; - move16(); - test(); - IF( EQ_16( st->element_mode, IVAS_CPE_MDCT ) && !MCT_flag ) - { - st->VAD = get_next_indice_fx( st0, 1 ); - move16(); - } - ELSE - { - st->VAD = 0; - move16(); - } - } - ELSE - { - IF( EQ_16( st->mdct_sw, MODE1 ) ) - { - /* 2 bits instead of 3 as TCX is already signaled */ - st->core = TCX_20_CORE; - move16(); - st->hTcxCfg->coder_type = get_next_indice_fx( st0, 2 ); - move16(); - st->coder_type = st->hTcxCfg->coder_type; - move16(); - } - ELSE - { - IF( EQ_16( st->mdct_sw_enable, MODE2 ) ) - { - IF( get_next_indice_1_fx( st0 ) ) - { - ind = get_next_indice_fx( st0, 3 ); - assert( !( ind & 4 ) || !"HQ_CORE encountered in dec_prm_ivas" ); - st->core = TCX_20_CORE; - move16(); - st->hTcxCfg->coder_type = ind; - move16(); - st->coder_type = st->hTcxCfg->coder_type; - move16(); - } - ELSE /* ACELP */ - { - st->core = ACELP_CORE; - move16(); - st->coder_type = get_next_indice_fx( st0, 2 ); - move16(); - } - } - ELSE - { - IF( EQ_16( st->rf_flag, 1 ) ) - { - IF( !st->use_partial_copy ) - { - ind = get_next_indice_fx( st0, 1 ); - IF( ind == 0 ) - { - st->core = ACELP_CORE; - move16(); - } - ELSE - { - st->core = TCX_20_CORE; - move16(); - st->hTcxCfg->coder_type = st->coder_type; - move16(); - } - } - } - ELSE - { - ind = get_next_indice_fx( st, 3 ); - IF( LT_16( ind, ACELP_MODE_MAX ) ) - { - st->core = ACELP_CORE; - move16(); - st->coder_type = ind; - move16(); - } - ELSE - { - st->core = TCX_20_CORE; - move16(); - st->hTcxCfg->coder_type = sub( ind, ACELP_MODE_MAX ); - move16(); - st->coder_type = st->hTcxCfg->coder_type; - move16(); - } - } - } - } - - IF( EQ_16( st->element_mode, EVS_MONO ) ) - { - test(); - IF( st->igf && EQ_16( st->core, ACELP_CORE ) ) - { - st->bits_frame_core = sub( st->bits_frame_core, get_tbe_bits_fx( st->total_brate, st->bwidth, st->rf_flag ) ); - move16(); - } - - IF( st->rf_flag ) - { - st->bits_frame_core = sub( st->bits_frame_core, add( st->rf_target_bits, 1 ) ); /* +1 as flag-bit not considered in rf_target_bits */ - move16(); - } - } - - /* Inactive frame detection on non-DTX mode */ - IF( EQ_16( st->coder_type, INACTIVE ) ) - { - st->VAD = 0; - move16(); - } - ELSE - { - st->VAD = 1; - move16(); - } - } - - /*Core extended mode mapping for correct PLC classification*/ - st->core_ext_mode = st->coder_type; - move16(); - if ( EQ_16( st->coder_type, INACTIVE ) ) - { - st->core_ext_mode = UNVOICED; - move16(); - } - - return; -} - -/*-------------------------------------------------------------------* - * getTCXWindowing_ivas() - * - * get TCX transform type for each subframe - *--------------------------------------------------------------------*/ -void getTCXWindowing_ivas_fx( - const Word16 core, /* i : current core */ - const Word16 last_core, /* i : last frame core */ - const Word16 element_mode, /* i : element mode */ - TCX_CONFIG_HANDLE hTcxCfg, /* i/o: TCX configuration handle */ - Decoder_State *st0 /* i : bitstream */ -) -{ - Word16 overlap_code; - - /* Set the last overlap mode based on the previous and current frame type and coded overlap mode */ - test(); - test(); - test(); - IF( EQ_16( last_core, ACELP_CORE ) || EQ_16( last_core, AMR_WB_CORE ) ) - { - hTcxCfg->tcx_last_overlap_mode = TRANSITION_OVERLAP; - move16(); - } - ELSE IF( EQ_16( core, TCX_10_CORE ) && EQ_16( hTcxCfg->tcx_curr_overlap_mode, ALDO_WINDOW ) ) - { - hTcxCfg->tcx_last_overlap_mode = FULL_OVERLAP; - move16(); - } - ELSE IF( NE_16( core, TCX_10_CORE ) && EQ_16( hTcxCfg->tcx_curr_overlap_mode, FULL_OVERLAP ) ) - { - hTcxCfg->tcx_last_overlap_mode = ALDO_WINDOW; - move16(); - } - ELSE - { - hTcxCfg->tcx_last_overlap_mode = hTcxCfg->tcx_curr_overlap_mode; - move16(); - } - - /* Set the current overlap mode based on the current frame type and coded overlap mode */ - hTcxCfg->tcx_curr_overlap_mode = ALDO_WINDOW; - move16(); - - IF( NE_16( core, ACELP_CORE ) ) - { - overlap_code = 0; - move16(); - IF( get_next_indice_fx( st0, 1 ) ) - { - overlap_code = add( 2, get_next_indice_fx( st0, 1 ) ); - } - - assert( MIN_OVERLAP == 2 && HALF_OVERLAP == 3 ); - hTcxCfg->tcx_curr_overlap_mode = overlap_code; - move16(); - /*TCX10 : always symmetric windows*/ - test(); - test(); - test(); - IF( EQ_16( core, TCX_20_CORE ) && ( overlap_code == 0 ) && NE_16( last_core, ACELP_CORE ) && NE_16( last_core, AMR_WB_CORE ) ) - { - hTcxCfg->tcx_curr_overlap_mode = ALDO_WINDOW; - move16(); - } - } - - test(); - IF( NE_16( element_mode, EVS_MONO ) && EQ_16( core, TCX_10_CORE ) ) - { - /* also read last overlap */ - overlap_code = 0; - move16(); - - IF( get_next_indice_fx( st0, 1 ) ) - { - overlap_code = add( 2, get_next_indice_fx( st0, 1 ) ); - } - - hTcxCfg->tcx_last_overlap_mode = overlap_code; - move16(); - } - - return; -} - -/*-------------------------------------------------------------------* - * getLPCparam_ivas() - * - * get LPC parameters - *--------------------------------------------------------------------*/ - - -/*-----------------------------------------------------------------* - * Function dec_prm_ivas() * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * - * - * SQ is used for TCX modes - * - * decode parameters according to selected mode * - *-----------------------------------------------------------------*/ diff --git a/lib_dec/dec_prm_fx.c b/lib_dec/dec_prm_fx.c index 73edd3b3b3c98d0a0018f9e206153a54254a3ec3..3d277807d2fed95764ba8e3c4992662fd26eac4b 100644 --- a/lib_dec/dec_prm_fx.c +++ b/lib_dec/dec_prm_fx.c @@ -1742,3 +1742,272 @@ void dec_prm_fx( return; } + + +/*-------------------------------------------------------------------* + * getTCXMode_ivas() + * + * get TCX mode + *--------------------------------------------------------------------*/ +void getTCXMode_ivas_fx( + Decoder_State *st, /* i/o: decoder memory state */ + Decoder_State *st0, /* i : bitstream */ + const Word16 MCT_flag /* i : hMCT handle allocated (1) or not (0) */ +) +{ + UWord16 ind; + + IF( st->tcxonly ) + { + /* get core */ + ind = get_next_indice_fx( st0, 1 ); /* Store decoder memory of last_core */ + st->core = add( ind, TCX_20_CORE ); + move16(); + /* get class */ + ind = get_next_indice_fx( st0, 2 ); + + st->clas_dec = ONSET; + move16(); + IF( ind == 0 ) + { + st->clas_dec = UNVOICED_CLAS; + move16(); + } + ELSE IF( EQ_16( ind, 1 ) ) + { + IF( GE_16( st->last_good, VOICED_TRANSITION ) ) + { + st->clas_dec = VOICED_TRANSITION; + move16(); + } + ELSE + { + st->clas_dec = UNVOICED_TRANSITION; + move16(); + } + } + ELSE IF( EQ_16( ind, 2 ) ) + { + st->clas_dec = VOICED_CLAS; + move16(); + } + + st->coder_type = INACTIVE; + move16(); + test(); + IF( EQ_16( st->element_mode, IVAS_CPE_MDCT ) && !MCT_flag ) + { + st->VAD = get_next_indice_fx( st0, 1 ); + move16(); + } + ELSE + { + st->VAD = 0; + move16(); + } + } + ELSE + { + IF( EQ_16( st->mdct_sw, MODE1 ) ) + { + /* 2 bits instead of 3 as TCX is already signaled */ + st->core = TCX_20_CORE; + move16(); + st->hTcxCfg->coder_type = get_next_indice_fx( st0, 2 ); + move16(); + st->coder_type = st->hTcxCfg->coder_type; + move16(); + } + ELSE + { + IF( EQ_16( st->mdct_sw_enable, MODE2 ) ) + { + IF( get_next_indice_1_fx( st0 ) ) + { + ind = get_next_indice_fx( st0, 3 ); + assert( !( ind & 4 ) || !"HQ_CORE encountered in dec_prm_ivas" ); + st->core = TCX_20_CORE; + move16(); + st->hTcxCfg->coder_type = ind; + move16(); + st->coder_type = st->hTcxCfg->coder_type; + move16(); + } + ELSE /* ACELP */ + { + st->core = ACELP_CORE; + move16(); + st->coder_type = get_next_indice_fx( st0, 2 ); + move16(); + } + } + ELSE + { + IF( EQ_16( st->rf_flag, 1 ) ) + { + IF( !st->use_partial_copy ) + { + ind = get_next_indice_fx( st0, 1 ); + IF( ind == 0 ) + { + st->core = ACELP_CORE; + move16(); + } + ELSE + { + st->core = TCX_20_CORE; + move16(); + st->hTcxCfg->coder_type = st->coder_type; + move16(); + } + } + } + ELSE + { + ind = get_next_indice_fx( st, 3 ); + IF( LT_16( ind, ACELP_MODE_MAX ) ) + { + st->core = ACELP_CORE; + move16(); + st->coder_type = ind; + move16(); + } + ELSE + { + st->core = TCX_20_CORE; + move16(); + st->hTcxCfg->coder_type = sub( ind, ACELP_MODE_MAX ); + move16(); + st->coder_type = st->hTcxCfg->coder_type; + move16(); + } + } + } + } + + IF( EQ_16( st->element_mode, EVS_MONO ) ) + { + test(); + IF( st->igf && EQ_16( st->core, ACELP_CORE ) ) + { + st->bits_frame_core = sub( st->bits_frame_core, get_tbe_bits_fx( st->total_brate, st->bwidth, st->rf_flag ) ); + move16(); + } + + IF( st->rf_flag ) + { + st->bits_frame_core = sub( st->bits_frame_core, add( st->rf_target_bits, 1 ) ); /* +1 as flag-bit not considered in rf_target_bits */ + move16(); + } + } + + /* Inactive frame detection on non-DTX mode */ + IF( EQ_16( st->coder_type, INACTIVE ) ) + { + st->VAD = 0; + move16(); + } + ELSE + { + st->VAD = 1; + move16(); + } + } + + /*Core extended mode mapping for correct PLC classification*/ + st->core_ext_mode = st->coder_type; + move16(); + if ( EQ_16( st->coder_type, INACTIVE ) ) + { + st->core_ext_mode = UNVOICED; + move16(); + } + + return; +} + +/*-------------------------------------------------------------------* + * getTCXWindowing_ivas() + * + * get TCX transform type for each subframe + *--------------------------------------------------------------------*/ +void getTCXWindowing_ivas_fx( + const Word16 core, /* i : current core */ + const Word16 last_core, /* i : last frame core */ + const Word16 element_mode, /* i : element mode */ + TCX_CONFIG_HANDLE hTcxCfg, /* i/o: TCX configuration handle */ + Decoder_State *st0 /* i : bitstream */ +) +{ + Word16 overlap_code; + + /* Set the last overlap mode based on the previous and current frame type and coded overlap mode */ + test(); + test(); + test(); + IF( EQ_16( last_core, ACELP_CORE ) || EQ_16( last_core, AMR_WB_CORE ) ) + { + hTcxCfg->tcx_last_overlap_mode = TRANSITION_OVERLAP; + move16(); + } + ELSE IF( EQ_16( core, TCX_10_CORE ) && EQ_16( hTcxCfg->tcx_curr_overlap_mode, ALDO_WINDOW ) ) + { + hTcxCfg->tcx_last_overlap_mode = FULL_OVERLAP; + move16(); + } + ELSE IF( NE_16( core, TCX_10_CORE ) && EQ_16( hTcxCfg->tcx_curr_overlap_mode, FULL_OVERLAP ) ) + { + hTcxCfg->tcx_last_overlap_mode = ALDO_WINDOW; + move16(); + } + ELSE + { + hTcxCfg->tcx_last_overlap_mode = hTcxCfg->tcx_curr_overlap_mode; + move16(); + } + + /* Set the current overlap mode based on the current frame type and coded overlap mode */ + hTcxCfg->tcx_curr_overlap_mode = ALDO_WINDOW; + move16(); + + IF( NE_16( core, ACELP_CORE ) ) + { + overlap_code = 0; + move16(); + IF( get_next_indice_fx( st0, 1 ) ) + { + overlap_code = add( 2, get_next_indice_fx( st0, 1 ) ); + } + + assert( MIN_OVERLAP == 2 && HALF_OVERLAP == 3 ); + hTcxCfg->tcx_curr_overlap_mode = overlap_code; + move16(); + /*TCX10 : always symmetric windows*/ + test(); + test(); + test(); + IF( EQ_16( core, TCX_20_CORE ) && ( overlap_code == 0 ) && NE_16( last_core, ACELP_CORE ) && NE_16( last_core, AMR_WB_CORE ) ) + { + hTcxCfg->tcx_curr_overlap_mode = ALDO_WINDOW; + move16(); + } + } + + test(); + IF( NE_16( element_mode, EVS_MONO ) && EQ_16( core, TCX_10_CORE ) ) + { + /* also read last overlap */ + overlap_code = 0; + move16(); + + IF( get_next_indice_fx( st0, 1 ) ) + { + overlap_code = add( 2, get_next_indice_fx( st0, 1 ) ); + } + + hTcxCfg->tcx_last_overlap_mode = overlap_code; + move16(); + } + + return; +} diff --git a/lib_dec/dec_tcx.c b/lib_dec/dec_tcx.c deleted file mode 100644 index ae0474f3d987d452a00f59905bd09924038a8e21..0000000000000000000000000000000000000000 --- a/lib_dec/dec_tcx.c +++ /dev/null @@ -1,497 +0,0 @@ - -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "prot.h" -#include "ivas_prot.h" -#include "prot_fx.h" -#include -#include "options.h" -#include -#include "stat_com.h" -#include "cnst.h" -#include "wmc_auto.h" -#include "ivas_rom_com.h" -#include "ivas_prot_fx.h" -#include "debug.h" - -/*-------------------------------------------------------------------* - * decoder_tcx_post() - * - * - *-------------------------------------------------------------------*/ - - -/*-------------------------------------------------------------------* - * decoder_tcx_tns() - * - * TCX: TNS application - *-------------------------------------------------------------------*/ - -void decoder_tcx_tns_fx( - Decoder_State *st, /* i/o: coder memory state */ - const Word16 L_frame_glob, /* i : frame length */ - const Word16 L_spec, - const Word16 L_frame, - const Word16 L_frameTCX, - Word32 x_fx[N_MAX], // Qx - const Word16 fUseTns, /* i : flag that is set if TNS data is present */ - STnsData *tnsData, - const Word16 bfi, /* i : Bad frame indicator */ - const Word16 frame_cnt, /* i : frame counter in the super frame */ - const Word16 whitenedDomain, - Word16 *length ) -{ - Word16 index, isTCX5, L, tmp; - TCX_CONFIG_HANDLE hTcxCfg = st->hTcxCfg; - - index = hTcxCfg->tcx_last_overlap_mode; /* backup last TCX overlap mode */ - move16(); - - isTCX5 = 0; - move16(); - L = L_frameTCX; - move16(); - tmp = L; - move16(); - - test(); - IF( EQ_16( L_frame, shr( st->L_frame, 1 ) ) && NE_16( st->tcxonly, 0 ) ) - { - test(); - test(); - IF( NE_16( frame_cnt, 0 ) && EQ_16( bfi, 0 ) && NE_16( st->last_core, ACELP_CORE ) ) - { - /* fix sub-window overlap */ - hTcxCfg->tcx_last_overlap_mode = hTcxCfg->tcx_curr_overlap_mode; - move16(); - } - - test(); - test(); - test(); - IF( ( NE_16( hTcxCfg->fIsTNSAllowed, 0 ) && NE_16( fUseTns, 0 ) && NE_16( bfi, 1 ) ) || GT_16( L_spec, L_frameTCX ) ) - { - L = L_spec; - move16(); - tmp = L; - move16(); - } - - test(); - test(); - test(); - test(); - test(); - test(); - test(); - IF( ( EQ_16( bfi, 0 ) && ( NE_16( hTcxCfg->tcx_last_overlap_mode, FULL_OVERLAP ) || - ( EQ_16( hTcxCfg->tcx_curr_overlap_mode, FULL_OVERLAP ) && EQ_16( frame_cnt, 0 ) && EQ_16( index, 0 ) ) ) ) || - ( NE_16( bfi, 0 ) && ( NE_16( hTcxCfg->tcx_last_overlap_mode, FULL_OVERLAP ) && - NE_16( hTcxCfg->tcx_curr_overlap_mode, FULL_OVERLAP ) ) ) ) - { - isTCX5 = 1; - move16(); - - tcx5SpectrumDeinterleaving_fx( shr( L, 1 ), x_fx ); - } - } - - /*-----------------------------------------------------------* - * Temporal Noise Shaping Synthesis * - *-----------------------------------------------------------*/ - - - test(); - test(); - test(); - IF( NE_16( hTcxCfg->fIsTNSAllowed, 0 ) && NE_16( fUseTns, 0 ) && NE_16( bfi, 1 ) && EQ_16( tnsData->tnsOnWhitenedSpectra, whitenedDomain ) ) - { - /* Apply TNS to get the reconstructed signal */ - SetTnsConfig( hTcxCfg, L_frame_glob == st->L_frame, ( st->last_core == ACELP_CORE ) && ( frame_cnt == 0 ) ); - - test(); - test(); - IF( EQ_16( L_frame, shr( st->L_frame, 1 ) ) && NE_16( st->tcxonly, 0 ) && NE_16( isTCX5, 0 ) ) - { - tcx5TnsGrouping_fx( shr( L, 1 ), shr( hTcxCfg->tnsConfig[0][0].iFilterBorders[0], 1 ), x_fx ); - } - - ApplyTnsFilter( hTcxCfg->pCurrentTnsConfig, tnsData, x_fx, 0 ); - - test(); - test(); - IF( EQ_16( L_frame, shr( st->L_frame, 1 ) ) && NE_16( st->tcxonly, 0 ) && NE_16( isTCX5, 0 ) ) - { - test(); - IF( EQ_16( st->element_mode, EVS_MONO ) || LT_16( L_spec, L_frameTCX ) ) /* todo: this is temporary to maintain EVS BE, this is a bug and should be fixed also for EVS (see issue 13) */ - { - tcx5TnsUngrouping_fx( shr( L_frameTCX, 1 ), shr( hTcxCfg->tnsConfig[0][0].iFilterBorders[0], 1 ), x_fx, DEC ); - tmp = L_frameTCX; - move16(); - } - ELSE - { - tcx5TnsUngrouping_fx( shr( L, 1 ), shr( hTcxCfg->tnsConfig[0][0].iFilterBorders[0], 1 ), x_fx, DEC ); - } - } - } - test(); - IF( NE_16( whitenedDomain, 0 ) && NE_16( isTCX5, 0 ) ) - { - tcx5SpectrumInterleaving_fx( shr( L, 1 ), x_fx ); - } - - /* restore index */ - test(); - test(); - test(); - test(); - IF( EQ_16( L_frame, shr( st->L_frame, 1 ) ) && NE_16( st->tcxonly, 0 ) && NE_16( frame_cnt, 0 ) && EQ_16( bfi, 0 ) && NE_16( st->last_core, ACELP_CORE ) ) - { - /* restore sub-window overlap */ - hTcxCfg->tcx_last_overlap_mode = index; - move16(); - } - - if ( length != NULL ) - { - *length = tmp; - move16(); - } - - return; -} - - -void decoder_tcx_imdct_fx( - Decoder_State *st, /* i/o: coder memory state */ - const Word16 L_frame_glob, /* i : frame length */ - const Word16 L_frameTCX_glob, - const Word16 L_spec, - const Word16 tcx_offset, - const Word16 tcx_offsetFB, - const Word16 L_frame, - const Word16 L_frameTCX, - const Word16 left_rect, - Word32 x_fx[N_MAX], // Q(11) - Word16 q_x, - Word16 xn_buf_fx[], // Q(-2) - Word16 q_win, - const UWord16 kernelType, /* i : TCX transform kernel type */ - const Word16 fUseTns, /* i : flag that is set if TNS data is present */ - Word16 synth_fx[], // Q(-2) /* i/o: synth[-M..L_frame] */ - Word16 synthFB_fx[], // Q(-2) - const Word16 bfi, /* i : Bad frame indicator */ - const Word16 frame_cnt, /* i : frame counter in the super frame */ - const Word16 sba_dirac_stereo_flag /* i : signal stereo output for SBA DirAC */ -) -{ - Word16 j, L, overlap, curr_order, startLine, endLine, isTCX5; - Word16 overlapFB; - Word32 x_tmp_fx[L_FRAME_PLUS]; - Word32 xn_bufFB_fx[L_MDCT_OVLP_MAX + L_FRAME_PLUS + L_MDCT_OVLP_MAX] = { 0 }; - Word16 xn_bufFB_fx_16[L_MDCT_OVLP_MAX + L_FRAME_PLUS + L_MDCT_OVLP_MAX]; - Word16 acelp_zir_fx[L_FRAME_MAX / 2]; - Word32 x_itf_fx[N_MAX_TCX - IGF_START_MN]; - Word16 index, proc = 0; - TCX_LTP_DEC_HANDLE hTcxLtpDec = st->hTcxLtpDec; - TCX_DEC_HANDLE hTcxDec = st->hTcxDec; - TCX_CONFIG_HANDLE hTcxCfg = st->hTcxCfg; - Word16 predictionGain_fx; - Word16 A_itf_fx[ITF_MAX_FILTER_ORDER + 1]; // q_a_itf - Word16 q_a_itf = 15; - Word16 x_e = sub( 31, q_x ); - move16(); - - /*-----------------------------------------------------------------* - * Initializations - *-----------------------------------------------------------------*/ - - /* Init lengths */ - overlap = hTcxCfg->tcx_mdct_window_length; - move16(); - overlapFB = hTcxCfg->tcx_mdct_window_lengthFB; - move16(); - - index = hTcxCfg->tcx_last_overlap_mode; /* backup last TCX overlap mode */ - move16(); - test(); - test(); - test(); - test(); - IF( EQ_16( L_frame, shr( st->L_frame, 1 ) ) && ( st->tcxonly != 0 ) && ( frame_cnt != 0 ) && ( bfi == 0 ) && ( st->last_core != ACELP_CORE ) ) - { - /* fix sub-window overlap */ - hTcxCfg->tcx_last_overlap_mode = hTcxCfg->tcx_curr_overlap_mode; - move16(); - } - - IF( st->igf != 0 ) - { - proc = st->hIGFDec->flatteningTrigger; - move16(); - - test(); - IF( proc && fUseTns != 0 ) - { - proc = 0; - move16(); - } - - IF( proc ) - { - - startLine = st->hIGFDec->infoIGFStartLine; - move16(); - endLine = st->hIGFDec->infoIGFStopLine; - move16(); - curr_order = 0; - move16(); - predictionGain_fx = 0; - move16(); - L = L_frameTCX; - move16(); - isTCX5 = 0; - move16(); - - /* interleave again for ITF */ - test(); - IF( EQ_16( L_frame, shr( st->L_frame, 1 ) ) && st->tcxonly ) - { - test(); - test(); - test(); - IF( ( hTcxCfg->fIsTNSAllowed && ( fUseTns != 0 ) && NE_16( bfi, 1 ) ) || GT_16( L_spec, L_frameTCX ) ) - { - L = L_spec; - move16(); - } - - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - IF( ( ( bfi == 0 ) && ( ( hTcxCfg->tcx_last_overlap_mode != FULL_OVERLAP ) || - ( ( hTcxCfg->tcx_curr_overlap_mode == FULL_OVERLAP ) && ( frame_cnt == 0 ) && ( index == 0 ) ) ) ) || - ( ( bfi != 0 ) && ( ( hTcxCfg->tcx_last_overlap_mode != FULL_OVERLAP ) && - ( hTcxCfg->tcx_curr_overlap_mode != FULL_OVERLAP ) ) ) ) - { - isTCX5 = 1; - move16(); - - tcx5SpectrumInterleaving_fx( shr( L, 1 ), x_fx ); - } - } - - FOR( j = startLine; j < endLine; j++ ) - { - IF( EQ_16( st->hIGFDec->flag_sparse[j - IGF_START_MN], 2 ) ) - { - x_itf_fx[j - IGF_START_MN] = x_fx[j]; // q_x - move32(); - x_fx[j] = st->hIGFDec->virtualSpec_fx[j - IGF_START_MN]; - move32(); - } - } - - ITF_Detect_fx( x_fx + IGF_START_MN, startLine, endLine, 8 /*maxOrder*/, A_itf_fx, &q_a_itf, &predictionGain_fx, &curr_order, shl( x_e, 1 ) ); - - ITF_Apply_fx( x_fx, startLine, endLine, A_itf_fx, q_a_itf, curr_order ); - - FOR( j = startLine; j < endLine; j++ ) - { - IF( EQ_16( st->hIGFDec->flag_sparse[j - IGF_START_MN], 2 ) ) - { - x_fx[j] = x_itf_fx[j - IGF_START_MN]; // q_x - move32(); - } - } - - /* deinterleave */ - IF( NE_16( isTCX5, 0 ) ) - { - tcx5SpectrumDeinterleaving_fx( shr( L, 1 ), x_fx ); - } - } - } - - /*-----------------------------------------------------------* - * Prepare OLA buffer after waveadjustment. * - * Compute inverse MDCT of x[]. * - *-----------------------------------------------------------*/ - - - IF( EQ_16( st->element_mode, IVAS_CPE_MDCT ) ) - { - set32_fx( x_tmp_fx, 0, L_FRAME_PLUS ); - Copy32( x_fx, x_tmp_fx, s_min( L_FRAME48k, s_max( L_spec, s_max( L_frame, L_frameTCX ) ) ) ); // q_x - Copy32( x_fx, xn_bufFB_fx, s_min( L_FRAME48k, s_max( L_spec, s_max( L_frame, L_frameTCX ) ) ) ); // q_x - } - ELSE IF( ( st->element_mode == EVS_MONO ) ) - { - Copy32( x_fx, xn_bufFB_fx, s_max( L_spec, s_max( L_frame, L_frameTCX ) ) ); // q_x - } - ELSE - { - Copy32( x_fx, x_tmp_fx, s_max( L_spec, s_max( L_frame, L_frameTCX ) ) ); // q_x - Copy32( x_fx, xn_bufFB_fx, s_max( L_spec, s_max( L_frame, L_frameTCX ) ) ); // q_x - } - - IF( ( st->igf != 0 ) ) - { - set32_fx( xn_bufFB_fx + st->hIGFDec->infoIGFStartLine, 0, L_frameTCX - st->hIGFDec->infoIGFStartLine ); - } - - test(); - IF( NE_16( st->element_mode, IVAS_CPE_DFT ) && !sba_dirac_stereo_flag ) - { - - IMDCT_ivas_fx( xn_bufFB_fx, q_x, hTcxDec->syn_Overl, hTcxDec->syn_Overl_TDAC, xn_buf_fx, hTcxCfg->tcx_aldo_window_1, hTcxCfg->tcx_aldo_window_1_trunc, hTcxCfg->tcx_aldo_window_2, - hTcxCfg->tcx_mdct_window_half, hTcxCfg->tcx_mdct_window_minimum, hTcxCfg->tcx_mdct_window_trans, hTcxCfg->tcx_mdct_window_half_length, hTcxCfg->tcx_mdct_window_min_length, index, - kernelType, left_rect, tcx_offset, overlap, L_frame, L_frameTCX, shr( s_max( L_frameTCX, L_spec ), 1 ), L_frame_glob, frame_cnt, bfi, st->hHQ_core->old_out_LB_fx, 0, st, 0, acelp_zir_fx, q_win ); - } - - /* Generate additional comfort noise to mask potential coding artefacts */ - test(); - test(); - test(); - IF( ( st->flag_cna != 0 ) && NE_16( st->element_mode, IVAS_CPE_TD ) && NE_16( st->element_mode, IVAS_CPE_DFT ) && ( st->cna_dirac_flag == 0 ) ) - { - generate_masking_noise_mdct_ivas_fx( x_fx, &x_e, st->hFdCngDec->hFdCngCom ); - FOR( Word16 ind = 0; ind < L_frame; ind++ ) - { - x_fx[ind] = L_shr( x_fx[ind], sub( 31, add( x_e, q_x ) ) ); // q_x - } - } - - test(); - IF( EQ_16( st->element_mode, IVAS_CPE_DFT ) || ( sba_dirac_stereo_flag != 0 ) ) - { - Copy32( x_fx, xn_bufFB_fx, s_max( L_spec, s_max( L_frame, L_frameTCX ) ) ); // q_x - - IMDCT_ivas_fx( xn_bufFB_fx, q_x, hTcxDec->syn_Overl, hTcxDec->syn_Overl_TDAC, xn_buf_fx, hTcxCfg->tcx_aldo_window_1, hTcxCfg->tcx_aldo_window_1_trunc, hTcxCfg->tcx_aldo_window_2, hTcxCfg->tcx_mdct_window_half, hTcxCfg->tcx_mdct_window_minimum, hTcxCfg->tcx_mdct_window_trans, hTcxCfg->tcx_mdct_window_half_length, hTcxCfg->tcx_mdct_window_min_length, index, - kernelType, left_rect, tcx_offset, overlap, L_frame, L_frameTCX, shr( s_max( L_frameTCX, L_spec ), 1 ), L_frame_glob, frame_cnt, bfi, st->hHQ_core->old_out_LB_fx, 0, st, 0, acelp_zir_fx, q_win ); - } - - FOR( Word16 ind = 0; ind < L_MDCT_OVLP_MAX + L_FRAME_PLUS + L_MDCT_OVLP_MAX; ind++ ) - { - xn_bufFB_fx_16[ind] = extract_l( L_shr( xn_bufFB_fx[ind], sub( q_x, q_win ) ) ); // q_x - move16(); - } - IF( st->element_mode != EVS_MONO ) - { - IMDCT_ivas_fx( x_tmp_fx, q_x, hTcxDec->syn_OverlFB, hTcxDec->syn_Overl_TDACFB, xn_bufFB_fx_16, hTcxCfg->tcx_aldo_window_1_FB, hTcxCfg->tcx_aldo_window_1_FB_trunc, hTcxCfg->tcx_aldo_window_2_FB, - hTcxCfg->tcx_mdct_window_halfFB, hTcxCfg->tcx_mdct_window_minimumFB, hTcxCfg->tcx_mdct_window_transFB, hTcxCfg->tcx_mdct_window_half_lengthFB, hTcxCfg->tcx_mdct_window_min_lengthFB, index, - kernelType, left_rect, tcx_offsetFB, overlapFB, L_frameTCX, L_frameTCX, max( L_frameTCX, L_spec ) >> 1, L_frameTCX_glob, frame_cnt, bfi, st->hHQ_core->old_out_fx, 1, st, FSCALE_DENOM * L_frameTCX_glob / L_frame_glob, acelp_zir_fx, q_win ); - } - ELSE - { - - IMDCT_ivas_fx( x_fx, q_x, hTcxDec->syn_OverlFB, hTcxDec->syn_Overl_TDACFB, xn_bufFB_fx_16, hTcxCfg->tcx_aldo_window_1_FB, hTcxCfg->tcx_aldo_window_1_FB_trunc, hTcxCfg->tcx_aldo_window_2_FB, hTcxCfg->tcx_mdct_window_halfFB, hTcxCfg->tcx_mdct_window_minimumFB, hTcxCfg->tcx_mdct_window_transFB, hTcxCfg->tcx_mdct_window_half_lengthFB, hTcxCfg->tcx_mdct_window_min_lengthFB, index, - kernelType, left_rect, tcx_offsetFB, overlapFB, L_frameTCX, L_frameTCX, shr( s_max( L_frameTCX, L_spec ), 1 ), L_frameTCX_glob, frame_cnt, bfi, st->hHQ_core->old_out_fx, 1, st, FSCALE_DENOM * L_frameTCX_glob / L_frame_glob, acelp_zir_fx, q_win ); - } - FOR( Word16 ind = 0; ind < L_MDCT_OVLP_MAX + L_FRAME_PLUS + L_MDCT_OVLP_MAX; ind++ ) - { - xn_bufFB_fx[ind] = L_shl( xn_bufFB_fx_16[ind], sub( q_x, q_win ) ); // Q_x - } - - IF( ( bfi == 0 ) ) - { - Word16 res_m, res_e = 0; - move16(); - st->second_last_tns_active = st->last_tns_active; - move16(); - st->last_tns_active = hTcxCfg->fIsTNSAllowed & fUseTns; - move16(); - hTcxDec->tcxltp_third_last_pitch = hTcxDec->tcxltp_second_last_pitch; - move32(); - hTcxDec->tcxltp_second_last_pitch = st->old_fpitch; - move32(); - res_m = BASOP_Util_Divide1616_Scale( hTcxLtpDec->tcxltp_pitch_fr, st->pit_res_max, &res_e ); - st->old_fpitch = L_add( L_shl( hTcxLtpDec->tcxltp_pitch_int, 16 ), L_shl( res_m, add( res_e, 1 ) ) ); - - IF( EQ_16( st->element_mode, IVAS_CPE_MDCT ) ) - { - res_m = BASOP_Util_Divide1616_Scale( L_frame_glob, L_FRAME, &res_e ); - st->old_fpitch = L_shl( Mpy_32_16_1( st->old_fpitch, res_m ), res_e ); - } - - IF( GT_16( st->element_mode, EVS_MONO ) ) - { - res_m = BASOP_Util_Divide1616_Scale( L_frameTCX_glob, L_frame_glob, &res_e ); - st->old_fpitchFB = L_shl( Mpy_32_16_1( st->old_fpitch, res_m ), res_e ); - } - ELSE - { - res_m = BASOP_Util_Divide1616_Scale( L_frameTCX, L_frame, &res_e ); - st->old_fpitchFB = L_shl( Mpy_32_16_1( st->old_fpitch, res_m ), res_e ); - } - } - - /* Update old_syn_overl */ - IF( hTcxCfg->last_aldo == 0 ) - { - Copy( xn_buf_fx + L_frame, hTcxDec->syn_Overl, overlap ); // Q(-2) - FOR( Word16 ind = 0; ind < overlapFB; ind++ ) - { - hTcxDec->syn_OverlFB[ind] = (Word16) L_shr( xn_bufFB_fx[( ind + L_frameTCX )], sub( q_x, q_win ) ); // q_x - } - } - - /* Output */ - Copy( xn_buf_fx + sub( shr( overlap, 1 ), tcx_offset ), synth_fx, L_frame_glob ); // Q(-2) - FOR( Word16 ind = 0; ind < L_frameTCX_glob; ind++ ) - { - synthFB_fx[ind] = (Word16) L_shr( xn_bufFB_fx[( ind + ( ( overlapFB >> 1 ) - tcx_offsetFB ) )], sub( q_x, q_win ) ); // q_x - } - - - return; -} - -/*-------------------------------------------------------------------* - * init_tcx_info() - * - * Initialize lengths for TCX processing, update IGF subframe info - *-------------------------------------------------------------------*/ diff --git a/lib_dec/dec_tcx_fx.c b/lib_dec/dec_tcx_fx.c index 20f7d297d739e3030ff5c8bdb468b1b7c12a6097..d1ed7ad8c90fcdc38719cf2e07f0c5ba0fad4cef 100644 --- a/lib_dec/dec_tcx_fx.c +++ b/lib_dec/dec_tcx_fx.c @@ -9,9 +9,7 @@ #include "basop_util.h" #include "stl.h" #include "options.h" -#include "prot.h" #include "math.h" -#include "ivas_prot.h" #include "ivas_prot_fx.h" #include "rom_com.h" #include "ivas_rom_com.h" @@ -434,11 +432,7 @@ void decoder_tcx_fx( gain_tcx_e = add( extract_l( L_shr( tmp32, 25 ) ), 1 ); /* get exponent */ gain_tcx = round_fx( BASOP_Util_InvLog2( L_or( tmp32, (Word32) 0xFE000000 ) ) ); -#ifdef BASOP_NOGLOB tmp1 = mult_r( shl_sat( L_spec, 5 ), 26214 /*128.f/NORM_MDCT_FACTOR Q15*/ ); -#else - tmp1 = mult_r( shl( L_spec, 5 ), 26214 /*128.f/NORM_MDCT_FACTOR Q15*/ ); -#endif s = 15 - 5 - 7; move16(); IF( GE_16( L_spec, 1024 ) ) /*reduce precision for avoiding overflow*/ @@ -553,11 +547,7 @@ void decoder_tcx_fx( st->last_gain_syn_deemph_e = add( st->last_gain_syn_deemph_e, 10 /*scaling of h1[0] and E_UTIL_synthesis * 2*/ ); move16(); tmp32 = Sqrt32( tmp32, &st->last_gain_syn_deemph_e ); -#ifdef BASOP_NOGLOB st->last_gain_syn_deemph = round_fx_o( tmp32, &Overflow ); -#else - st->last_gain_syn_deemph = round_fx( tmp32 ); -#endif move16(); /*for avoiding compiler warnings*/ hTcxDec->gainHelper = 32768 / 2; @@ -575,11 +565,7 @@ void decoder_tcx_fx( /* gainCompensate = st->last_gain_syn_deemph/(float)sqrt(dot_product( h1, h1, L_SUBFR)); */ tmp32 = Dot_productSq16HQ( 0, h1, L_SUBFR, &gainCompensate_e ) /*Q15, gainCompensate_e*/; gainCompensate_e = add( gainCompensate_e, 10 /*scaling of h1[0] and E_UTIL:synthesis*/ ); -#ifdef BASOP_NOGLOB gainCompensate = round_fx_sat( Sqrt32( tmp32, &gainCompensate_e ) ) /*Q15, gainCompensate_e*/; -#else - gainCompensate = round_fx( Sqrt32( tmp32, &gainCompensate_e ) ) /*Q15, gainCompensate_e*/; -#endif BASOP_Util_Divide_MantExp( st->last_gain_syn_deemph, st->last_gain_syn_deemph_e, gainCompensate, @@ -752,11 +738,7 @@ void decoder_tcx_fx( tmp32 = L_deposit_l( 0 ); FOR( i = 0; i < L_spec; i++ ) { -#ifdef BASOP_NOGLOB tmp32 = L_macNs_co( tmp32, abs_s( prm_sqQ[i] ), i, &Carry, &Overflow ); -#else - tmp32 = L_macNs( tmp32, abs_s( prm_sqQ[i] ), i ); -#endif } nf_seed = extract_l( tmp32 ); } @@ -876,11 +858,7 @@ void decoder_tcx_fx( BASOP_Util_Divide_MantExp( extract_h( E_2ndlast ), exp2, extract_h( E_last ), exp1, &tmp1, &tmp2 ); tmp1 = shr( tmp1, 2 ); /*Q13*/ -#ifdef BASOP_NOGLOB tmp1 = shl_sat( tmp1, tmp2 ); -#else - tmp1 = shl( tmp1, tmp2 ); -#endif /* replace higher energy TCX5 frame by lower one to avoid energy fluctuation */ IF( GT_16( tmp1, 16384 /*2 in Q13*/ ) ) { @@ -1345,11 +1323,7 @@ void decoder_tcx_post_fx( Decoder_State *st_fx, FOR( i = 0; i < hTcxDec->L_frameTCX; i++ ) { tmp32 = L_shl( tmp32_1 /*Q28*/, -( 28 - 15 ) ); /*16Q15*/ -#ifdef BASOP_NOGLOB synthFB[i] = round_fx_sat( L_shl_sat( Mpy_32_16_1( tmp32, synthFB[i] ), 16 ) ); -#else - synthFB[i] = round_fx( L_shl( Mpy_32_16_1( tmp32, synthFB[i] ), 16 ) ); -#endif move16(); tmp32_1 = L_sub( tmp32_1, tmp32_2 ); } @@ -1383,11 +1357,7 @@ void decoder_tcx_post_fx( Decoder_State *st_fx, } tmp32 = Mpy_32_16_1( tmp32, getInvFrameLen( hTcxDec->L_frameTCX ) ); tmp2 = norm_l( tmp32 ); -#ifdef BASOP_NOGLOB tmp1 = round_fx_o( L_shl( tmp32, tmp2 ), &Overflow ); -#else - tmp1 = round_fx( L_shl( tmp32, tmp2 ) ); -#endif s = sub( sub( sub( 1, shl( s, 1 ) ), 6 /*table lookup for inverse framelength*/ ), tmp2 ); tmp1 = Sqrt16( tmp1, &s ); move16(); @@ -1480,71 +1450,36 @@ void decoder_tcx_post_fx( Decoder_State *st_fx, &tmp1 ); tmp2 = BASOP_Util_Add_MantExp( hTcxDec->conceal_eof_gain, 15 - 14, negate( tmp1 ), tmp2, &tmp1 ); -#ifdef BASOP_NOGLOB step = L_shl_o( L_mult( tmp1, getInvFrameLen( st_fx->L_frame ) ), sub( tmp2, 6 /*scaling from table lookup*/ + 1 /*go to Q30*/ ), &Overflow ); /*Q30*/ -#else - step = L_shl( L_mult( tmp1, getInvFrameLen( st_fx->L_frame ) ), sub( tmp2, 6 /*scaling from table lookup*/ + 1 /*go to Q30*/ ) ); /*Q30*/ -#endif { Word32 stepFB; UWord32 dmy; conceal_eof_gainFB = L_deposit_h( hTcxDec->conceal_eof_gain ); /*Q30*/ Mpy_32_32_ss( step, L_shl( L_mult0( st_fx->L_frame, getInvFrameLen( hTcxDec->L_frameTCX ) ), 8 ), &stepFB, &dmy ); -#ifdef BASOP_NOGLOB stepFB = L_shl_o( stepFB, 3 - 1, &Overflow ); /*Q30*/ -#else - stepFB = L_shl( stepFB, 3 - 1 ); /*Q30*/ -#endif FOR( i = 0; i < hTcxDec->L_frameTCX; i++ ) { -#ifdef BASOP_NOGLOB synthFB[i] = round_fx_sat( L_shl_sat( Mpy_32_16_1( conceal_eof_gainFB, synthFB[i] ), 1 ) ); -#else - synthFB[i] = round_fx( L_shl( Mpy_32_16_1( conceal_eof_gainFB, synthFB[i] ), 1 ) ); -#endif move16(); -#ifdef BASOP_NOGLOB conceal_eof_gainFB = L_sub_o( conceal_eof_gainFB, stepFB, &Overflow ); -#else - conceal_eof_gainFB = L_sub( conceal_eof_gainFB, stepFB ); -#endif } } conceal_eof_gain32 = L_deposit_h( hTcxDec->conceal_eof_gain ); /*Q30*/ FOR( i = 0; i < st_fx->L_frame; i++ ) { -#ifdef BASOP_NOGLOB xn_buf[i] = round_fx_sat( L_shl_sat( Mpy_32_16_1( conceal_eof_gain32 /*Q30*/, xn_buf[i] ), 1 ) ); -#else - xn_buf[i] = round_fx( L_shl( Mpy_32_16_1( conceal_eof_gain32 /*Q30*/, xn_buf[i] ), 1 ) ); -#endif move16(); -#ifdef BASOP_NOGLOB conceal_eof_gain32 = L_sub_o( conceal_eof_gain32, step, &Overflow ); -#else - conceal_eof_gain32 = L_sub( conceal_eof_gain32, step ); -#endif } -#ifdef BASOP_NOGLOB hTcxDec->conceal_eof_gain = round_fx_o( conceal_eof_gain32, &Overflow ); /*Q14*/ move16(); -#else - hTcxDec->conceal_eof_gain = round_fx( conceal_eof_gain32 ); /*Q14*/ - move16(); -#endif /* run lpc gain compensation not for waveform adjustment */ test(); IF( 0 == st_fx->enablePlcWaveadjust || EQ_16( st_fx->plcInfo.concealment_method, TCX_TONAL ) ) { -#ifdef BASOP_NOGLOB st_fx->plcInfo.recovery_gain = extract_h( L_shl_o( Mpy_32_16_1( conceal_eof_gainFB, st_fx->last_concealed_gain_syn_deemph ), st_fx->last_concealed_gain_syn_deemph_e, &Overflow ) ); /*Q30->Q14*/ -#else - st_fx->plcInfo.recovery_gain = extract_h( L_shl( Mpy_32_16_1( conceal_eof_gainFB, - st_fx->last_concealed_gain_syn_deemph ), - st_fx->last_concealed_gain_syn_deemph_e ) ); /*Q30->Q14*/ -#endif move16(); } ELSE @@ -1553,14 +1488,7 @@ void decoder_tcx_post_fx( Decoder_State *st_fx, move16(); } st_fx->plcInfo.step_concealgain_fx = -#ifdef BASOP_NOGLOB round_fx_sat( L_shl_sat( L_mult0( round_fx_sat( step ), round_fx_sat( L_shl_sat( L_mult0( st_fx->L_frame, getInvFrameLen( hTcxDec->L_frameTCX ) ), 8 ) ) ), 3 ) ); /*Q15*/ -#else - round_fx( L_shl( L_mult0( - round_fx( step ), - round_fx( L_shl( L_mult0( st_fx->L_frame, getInvFrameLen( hTcxDec->L_frameTCX ) ), 8 ) ) ), - 3 ) ); /*Q15*/ -#endif move16(); } @@ -1584,11 +1512,7 @@ void decoder_tcx_post_fx( Decoder_State *st_fx, move32(); Copy32( &st_fx->old_pitch_buf_fx[st_fx->nb_subfr + 2], &st_fx->old_pitch_buf_fx[2], st_fx->nb_subfr ); set32_fx( &st_fx->old_pitch_buf_fx[st_fx->nb_subfr + 2], st_fx->old_fpitch, st_fx->nb_subfr ); -#ifdef BASOP_NOGLOB /*TBV st_fx->old_fpitch seems to have an odd value for this bitstream stv48n1_dtx_sw_164_1280_48kHz.f06.COD at frame 10 */ st_fx->bfi_pitch_fx = shl_sat( round_fx( st_fx->old_fpitch ), 6 ); -#else - st_fx->bfi_pitch_fx = shl( round_fx( st_fx->old_fpitch ), 6 ); -#endif move16(); st_fx->bfi_pitch_frame = st_fx->L_frame; move16(); @@ -1678,12 +1602,8 @@ void decoder_tcx_post_ivas_fx( Decoder_State *st_fx, FOR( i = 0; i < hTcxDec->L_frameTCX; i++ ) { - tmp32 = L_shl( tmp32_1 /*Q28*/, -( 28 - 15 ) ); /*16Q15*/ -#ifdef BASOP_NOGLOB + tmp32 = L_shl( tmp32_1 /*Q28*/, -( 28 - 15 ) ); /*16Q15*/ synthFB[i] = round_fx_sat( L_shl_sat( Mpy_32_16_1( tmp32, synthFB[i] ), 16 ) ); // Q_syn -#else - synthFB[i] = round_fx( L_shl( Mpy_32_16_1( tmp32, synthFB[i] ), 16 ) ); -#endif move16(); tmp32_1 = L_sub( tmp32_1, tmp32_2 ); } @@ -1716,11 +1636,7 @@ void decoder_tcx_post_ivas_fx( Decoder_State *st_fx, } tmp32 = Mpy_32_16_1( tmp32, getInvFrameLen( hTcxDec->L_frameTCX ) ); tmp2 = norm_l( tmp32 ); -#ifdef BASOP_NOGLOB tmp1 = round_fx_o( L_shl( tmp32, tmp2 ), &Overflow ); -#else - tmp1 = round_fx( L_shl( tmp32, tmp2 ) ); -#endif // s = sub(sub(sub(1, shl(s, 1)), 6/*table lookup for inverse framelength*/), tmp2); s = sub( 25, add( shl( add( Q_syn, s ), 1 ), tmp2 ) ); tmp1 = Sqrt16( tmp1, &s ); @@ -1891,15 +1807,9 @@ void decoder_tcx_post_ivas_fx( Decoder_State *st_fx, test(); IF( 0 == st_fx->enablePlcWaveadjust || EQ_16( st_fx->plcInfo.concealment_method, TCX_TONAL ) ) { -#ifdef BASOP_NOGLOB st_fx->plcInfo.recovery_gain = extract_h( L_shl_o( Mpy_32_16_1( conceal_eof_gainFB, st_fx->last_concealed_gain_syn_deemph ), st_fx->last_concealed_gain_syn_deemph_e, &Overflow ) ); /*Q30->Q14*/ -#else - st_fx->plcInfo.recovery_gain = extract_h( L_shl( Mpy_32_16_1( conceal_eof_gainFB, - st_fx->last_concealed_gain_syn_deemph ), - st_fx->last_concealed_gain_syn_deemph_e ) ); /*Q30->Q14*/ -#endif move16(); } ELSE @@ -1908,14 +1818,7 @@ void decoder_tcx_post_ivas_fx( Decoder_State *st_fx, move16(); } st_fx->plcInfo.step_concealgain_fx = -#ifdef BASOP_NOGLOB round_fx_sat( L_shl_sat( L_mult0( round_fx_sat( L_shr_sat( step, sub( 1, step_e ) ) ), round_fx_sat( L_shl_sat( L_mult0( st_fx->L_frame, getInvFrameLen( hTcxDec->L_frameTCX ) ), 8 ) ) ), 4 ) ); /*Q15*/ -#else - round_fx( L_shl( L_mult0( - round_fx( L_shr( step, sub( 1, step_e ) ), - round_fx( L_shl( L_mult0( st_fx->L_frame, getInvFrameLen( hTcxDec->L_frameTCX ) ), 8 ) ) ), - 4 ) ); /*Q15*/ -#endif move16(); } @@ -1939,11 +1842,7 @@ void decoder_tcx_post_ivas_fx( Decoder_State *st_fx, move32(); Copy32( &st_fx->old_pitch_buf_fx[st_fx->nb_subfr + 2], &st_fx->old_pitch_buf_fx[2], st_fx->nb_subfr ); set32_fx( &st_fx->old_pitch_buf_fx[st_fx->nb_subfr + 2], st_fx->old_fpitch, st_fx->nb_subfr ); -#ifdef BASOP_NOGLOB /*TBV st_fx->old_fpitch seems to have an odd value for this bitstream stv48n1_dtx_sw_164_1280_48kHz.f06.COD at frame 10 */ st_fx->bfi_pitch_fx = shl_sat( round_fx( st_fx->old_fpitch ), 6 ); -#else - st_fx->bfi_pitch_fx = shl( round_fx( st_fx->old_fpitch ), 6 ); -#endif st_fx->bfi_pitch_frame = st_fx->L_frame; move16(); @@ -1980,7 +1879,6 @@ static Word32 CalculateAbsEnergy_fx( /* o : normalized resul move32(); L_c = 0; move32(); -#ifdef BASOP_NOGLOB /* Critical Overflow/Carry */ L_sum = L_macNs_co( L_off, 0, 0, &Carry, &Overflow ); IF( L_sum > 0 ) { @@ -1990,31 +1888,16 @@ static Word32 CalculateAbsEnergy_fx( /* o : normalized resul { L_c = L_msuNs_co( L_c, 0, 0, &Carry, &Overflow ); } -#else - L_sum = L_macNs( L_off, 0, 0 ); - if ( L_sum > 0 ) - L_c = L_macNs( L_c, 0, 0 ); - if ( L_sum < 0 ) - L_c = L_msuNs( L_c, 0, 0 ); -#endif FOR( i = 0; i < lg; i += 2 ) { Carry = 0; move32(); BASOP_SATURATE_WARNING_OFF_EVS /*multiplication of -32768 * -32768 throws an overflow, but is not critical*/ -#ifdef BASOP_NOGLOB /* Critical Overflow/Carry */ L_sum = L_macNs_co( L_sum, x[i], x[i], &Carry, &Overflow ); -#else - L_sum = L_macNs( L_sum, x[i], x[i] ); -#endif BASOP_SATURATE_WARNING_ON_EVS Overflow = 0; /* to avoid useless warning in L_macNs calling L_mult */ move32(); -#ifdef BASOP_NOGLOB /* Critical Overflow/Carry */ L_c = L_macNs_co( L_c, 0, 0, &Carry, &Overflow ); -#else - L_c = L_macNs( L_c, 0, 0 ); -#endif } L_sum = norm_llQ31( L_c, L_sum, exp ); return L_sum; @@ -2371,11 +2254,7 @@ void IMDCT_fx( Word32 *x, Word16 x_e, Word16 *old_syn_overl, Word16 *syn_Overl_T { FOR( i = 0; i < L_frame; i++ ) { -#ifdef BASOP_NOGLOB xn_buf[i] = shr_sat( xn_buf[i], Q ); -#else - xn_buf[i] = shr( xn_buf[i], Q ); -#endif move16(); } } @@ -2467,11 +2346,7 @@ void IMDCT_fx( Word32 *x, Word16 x_e, Word16 *old_syn_overl, Word16 *syn_Overl_T tmp1 = sub( overlap, tcx_mdct_window_min_length ); FOR( i = 0; i < tmp1; i++ ) { -#ifdef BASOP_NOGLOB xn_buf[i + tmp4] = shl_sat( add_sat( xn_buf[i + tmp4], shr_sat( old_out[i + nz], tmp2 ) ), TCX_IMDCT_HEADROOM ); -#else - xn_buf[i + tmp4] = shl( add( xn_buf[i + tmp4], shr( old_out[i + nz], tmp2 ) ), TCX_IMDCT_HEADROOM ); -#endif move16(); } @@ -2480,31 +2355,19 @@ void IMDCT_fx( Word32 *x, Word16 x_e, Word16 *old_syn_overl, Word16 *syn_Overl_T FOR( ; i < tmp1; i++ ) { tmp3 = mult_r( shr( old_out[i + nz], tmp2 ), tcx_mdct_window_minimum[i - overlap + tcx_mdct_window_min_length].v.re ); -#ifdef BASOP_NOGLOB xn_buf[i + tmp4] = shl_sat( add_sat( xn_buf[i + tmp4], tmp3 ), TCX_IMDCT_HEADROOM ); -#else - xn_buf[i + tmp4] = shl( add( xn_buf[i + tmp4], tmp3 ), TCX_IMDCT_HEADROOM ); -#endif move16(); } FOR( ; i < overlap; i++ ) { tmp3 = mult_r( shr( old_out[i + nz], tmp2 ), tcx_mdct_window_minimum[overlap - 1 - i].v.im ); -#ifdef BASOP_NOGLOB xn_buf[i + tmp4] = shl_sat( add_sat( xn_buf[i + tmp4], tmp3 ), TCX_IMDCT_HEADROOM ); -#else - xn_buf[i + tmp4] = shl( add( xn_buf[i + tmp4], tmp3 ), TCX_IMDCT_HEADROOM ); -#endif move16(); } FOR( i = add( i, tmp4 ); i < L_frame; i++ ) { -#ifdef BASOP_NOGLOB xn_buf[i] = shl_sat( xn_buf[i], TCX_IMDCT_HEADROOM ); -#else - xn_buf[i] = shl( xn_buf[i], TCX_IMDCT_HEADROOM ); -#endif move16(); } } @@ -2535,43 +2398,26 @@ void IMDCT_fx( Word32 *x, Word16 x_e, Word16 *old_syn_overl, Word16 *syn_Overl_T tmp3 = shr( tcx_mdct_window_half_length, 1 ); FOR( i = 0; i < tmp1; i++ ) { -#ifdef BASOP_NOGLOB xn_buf[i] = shl_sat( xn_buf[i], TCX_IMDCT_HEADROOM ); -#else - xn_buf[i] = shl( xn_buf[i], TCX_IMDCT_HEADROOM ); -#endif move16(); } FOR( i = 0; i < tmp3; i++ ) { -#ifdef BASOP_NOGLOB tmp2 = add_sat( xn_buf[i + tmp1], mult_r( old_syn_overl[i], tcx_mdct_window_half[i].v.re ) ); xn_buf[i + tmp1] = shl_sat( tmp2, TCX_IMDCT_HEADROOM ); -#else - tmp2 = add( xn_buf[i + tmp1], mult_r( old_syn_overl[i], tcx_mdct_window_half[i].v.re ) ); - xn_buf[i + tmp1] = shl( tmp2, TCX_IMDCT_HEADROOM ); -#endif move16(); } FOR( ; i < tcx_mdct_window_half_length; i++ ) { tmp2 = add( xn_buf[i + tmp1], mult_r( old_syn_overl[i], tcx_mdct_window_half[tcx_mdct_window_half_length - 1 - i].v.im ) ); -#ifdef BASOP_NOGLOB xn_buf[i + tmp1] = shl_sat( tmp2, TCX_IMDCT_HEADROOM ); -#else - xn_buf[i + tmp1] = shl( tmp2, TCX_IMDCT_HEADROOM ); -#endif move16(); } IF( LT_16( add( i, tmp1 ), L_frame ) ) { FOR( i = add( i, tmp1 ); i < L_frame; i++ ) { -#ifdef BASOP_NOGLOB xn_buf[i] = shl_sat( xn_buf[i], TCX_IMDCT_HEADROOM ); -#else - xn_buf[i] = shl( xn_buf[i], TCX_IMDCT_HEADROOM ); -#endif move16(); } } @@ -2581,11 +2427,7 @@ void IMDCT_fx( Word32 *x, Word16 x_e, Word16 *old_syn_overl, Word16 *syn_Overl_T FOR( i = 0; i < overlap; i++ ) { -#ifdef BASOP_NOGLOB xn_buf[i] = shl_sat( add_sat( xn_buf[i], old_syn_overl[i] ), TCX_IMDCT_HEADROOM ); -#else - xn_buf[i] = shl( add( xn_buf[i], old_syn_overl[i] ), TCX_IMDCT_HEADROOM ); -#endif move16(); } @@ -2593,11 +2435,7 @@ void IMDCT_fx( Word32 *x, Word16 x_e, Word16 *old_syn_overl, Word16 *syn_Overl_T { FOR( ; i < L_frame; i++ ) { -#ifdef BASOP_NOGLOB xn_buf[i] = shl_sat( xn_buf[i], TCX_IMDCT_HEADROOM ); -#else - xn_buf[i] = shl( xn_buf[i], TCX_IMDCT_HEADROOM ); -#endif move16(); } } @@ -2607,22 +2445,14 @@ void IMDCT_fx( Word32 *x, Word16 x_e, Word16 *old_syn_overl, Word16 *syn_Overl_T tmp1 = shr( overlap, 1 ); FOR( i = 0; i < tmp1; i++ ) { -#ifdef BASOP_NOGLOB xn_buf[i] = shl_sat( xn_buf[i], TCX_IMDCT_HEADROOM ); -#else - xn_buf[i] = shl( xn_buf[i], TCX_IMDCT_HEADROOM ); -#endif move16(); } tmpP16 = xn_buf + tmp1; FOR( i = 0; i < overlap; i++ ) { -#ifdef BASOP_NOGLOB tmpP16[i] = shl_sat( add( tmpP16[i], old_syn_overl[i] ), TCX_IMDCT_HEADROOM ); -#else - tmpP16[i] = shl( add( tmpP16[i], old_syn_overl[i] ), TCX_IMDCT_HEADROOM ); -#endif move16(); } @@ -2630,11 +2460,7 @@ void IMDCT_fx( Word32 *x, Word16 x_e, Word16 *old_syn_overl, Word16 *syn_Overl_T { FOR( i = add( i, tmp1 ); i < L_frame; i++ ) { -#ifdef BASOP_NOGLOB xn_buf[i] = shl_sat( xn_buf[i], TCX_IMDCT_HEADROOM ); -#else - xn_buf[i] = shl( xn_buf[i], TCX_IMDCT_HEADROOM ); -#endif move16(); } } @@ -2652,11 +2478,7 @@ void IMDCT_fx( Word32 *x, Word16 x_e, Word16 *old_syn_overl, Word16 *syn_Overl_T BASOP_SATURATE_WARNING_OFF_EVS; FOR( i = 0; i < L_frame; i++ ) { -#ifdef BASOP_NOGLOB xn_buf[i] = shl_sat( xn_buf[i], TCX_IMDCT_HEADROOM ); -#else - xn_buf[i] = shl( xn_buf[i], TCX_IMDCT_HEADROOM ); -#endif move16(); } BASOP_SATURATE_WARNING_ON_EVS; @@ -2722,25 +2544,15 @@ void IMDCT_fx( Word32 *x, Word16 x_e, Word16 *old_syn_overl, Word16 *syn_Overl_T tmp3 = shr( tcx_mdct_window_half_length, 1 ); FOR( i = 0; i < tmp3; i++ ) { -#ifdef BASOP_NOGLOB xn_buf[i + tmp1] = mult_r_sat( xn_buf[i + tmp1], tcx_mdct_window_half[i].v.im ); xn_buf[i + tmp1] = add_sat( xn_buf[i + tmp1], mult_r_sat( hTcxDec->syn_OverlFB[i], mult_r_sat( tcx_mdct_window_half[i].v.re, tcx_mdct_window_half[i].v.re ) ) ); -#else - xn_buf[i + tmp1] = mult_r( xn_buf[i + tmp1], tcx_mdct_window_half[i].v.im ); - xn_buf[i + tmp1] = add( xn_buf[i + tmp1], mult_r( hTcxDec->syn_OverlFB[i], mult_r( tcx_mdct_window_half[i].v.re, tcx_mdct_window_half[i].v.re ) ) ); -#endif move16(); move16(); } FOR( ; i < tcx_mdct_window_half_length; i++ ) { -#ifdef BASOP_NOGLOB xn_buf[i + tmp1] = mult_r_sat( xn_buf[i + tmp1], tcx_mdct_window_half[( ( tcx_mdct_window_half_length - 1 ) - i )].v.re ); xn_buf[i + tmp1] = add_sat( xn_buf[i + tmp1], mult_r_sat( hTcxDec->syn_OverlFB[i], mult_r_sat( tcx_mdct_window_half[( ( tcx_mdct_window_half_length - 1 ) - i )].v.im, tcx_mdct_window_half[tcx_mdct_window_half_length - 1 - i].v.im ) ) ); -#else - xn_buf[i + tmp1] = mult_r( xn_buf[i + tmp1], tcx_mdct_window_half[tcx_mdct_window_half_length - 1 - i].v.re ); - xn_buf[i + tmp1] = add( xn_buf[i + tmp1], mult_r( hTcxDec->syn_OverlFB[i], mult_r( tcx_mdct_window_half[tcx_mdct_window_half_length - 1 - i].v.im, tcx_mdct_window_half[tcx_mdct_window_half_length - 1 - i].v.im ) ) ); -#endif move16(); move16(); } @@ -2751,25 +2563,15 @@ void IMDCT_fx( Word32 *x, Word16 x_e, Word16 *old_syn_overl, Word16 *syn_Overl_T tmp3 = shr( tcx_mdct_window_half_length, 1 ); FOR( i = 0; i < tmp3; i++ ) { -#ifdef BASOP_NOGLOB xn_buf[i + tmp1] = mult_r_sat( xn_buf[i + tmp1], tcx_mdct_window_half[i].v.im ); xn_buf[i + tmp1] = add_sat( xn_buf[i + tmp1], mult_r_sat( hTcxDec->syn_Overl[i], mult_r_sat( tcx_mdct_window_half[i].v.re, tcx_mdct_window_half[i].v.re ) ) ); -#else - xn_buf[i + tmp1] = mult_r( xn_buf[i + tmp1], tcx_mdct_window_half[i].v.im ); - xn_buf[i + tmp1] = add( xn_buf[i + tmp1], mult_r( hTcxDec->syn_Overl[i], mult_r( tcx_mdct_window_half[i].v.re, tcx_mdct_window_half[i].v.re ) ) ); -#endif move16(); move16(); } FOR( ; i < tcx_mdct_window_half_length; i++ ) { -#ifdef BASOP_NOGLOB xn_buf[i + tmp1] = mult_r_sat( xn_buf[i + tmp1], tcx_mdct_window_half[tcx_mdct_window_half_length - 1 - i].v.re ); xn_buf[i + tmp1] = add_sat( xn_buf[i + tmp1], mult_r_sat( hTcxDec->syn_Overl[i], mult_r_sat( tcx_mdct_window_half[tcx_mdct_window_half_length - 1 - i].v.im, tcx_mdct_window_half[tcx_mdct_window_half_length - 1 - i].v.im ) ) ); -#else - xn_buf[i + tmp1] = mult_r( xn_buf[i + tmp1], tcx_mdct_window_half[tcx_mdct_window_half_length - 1 - i].v.re ); - xn_buf[i + tmp1] = add( xn_buf[i + tmp1], mult_r( hTcxDec->syn_Overl[i], mult_r( tcx_mdct_window_half[tcx_mdct_window_half_length - 1 - i].v.im, tcx_mdct_window_half[tcx_mdct_window_half_length - 1 - i].v.im ) ) ); -#endif move16(); move16(); } @@ -3203,11 +3005,7 @@ void IMDCT_ivas_fx( { FOR( i = 0; i < sub( overlap, tcx_mdct_window_min_length ); i++ ) { -#ifdef BASOP_NOGLOB xn_buf_fx[( i + ( ( overlap / 2 ) - tcx_offset ) )] = add_sat( xn_buf_fx[( i + ( ( overlap / 2 ) - tcx_offset ) )], old_out_fx[( i + nz )] ); // Q(-2) -#else - xn_buf_fx[( i + ( ( overlap / 2 ) - tcx_offset ) )] = add( xn_buf_fx[( i + ( ( overlap / 2 ) - tcx_offset ) )], old_out_fx[( i + nz )] ); -#endif move16(); } @@ -3220,30 +3018,17 @@ void IMDCT_ivas_fx( // tested FOR( ; i < overlap; i++ ) /* perfectly reconstructing ALDO shortening */ { -#ifdef BASOP_NOGLOB xn_buf_fx[( ( i + ( overlap / 2 ) ) - tcx_offset )] = add_sat( xn_buf_fx[( ( i + ( overlap / 2 ) ) - tcx_offset )], old_out_fx[( i + nz )] ); // Q(-2) -#else - xn_buf_fx[( ( i + ( overlap / 2 ) ) - tcx_offset )] = add( xn_buf_fx[( ( i + ( overlap / 2 ) ) - tcx_offset )], old_out_fx[( i + nz )] ); // Q(-2) - -#endif move16(); } FOR( i = 0; i < ( tcx_mdct_window_min_length / 2 ); i++ ) { -#ifdef BASOP_NOGLOB xn_buf_fx[( ( ( i + ( overlap / 2 ) ) - tcx_offset ) + overlap )] = add_sat( xn_buf_fx[( ( ( i + ( overlap / 2 ) ) - tcx_offset ) + overlap )], mult_r( old_out_fx[( ( i + nz ) + overlap )], tcx_mdct_window_minimum_fx[i].v.re ) ); // Q(-2) -#else - xn_buf_fx[( ( ( i + ( overlap / 2 ) ) - tcx_offset ) + overlap )] = add( xn_buf_fx[( ( ( i + ( overlap / 2 ) ) - tcx_offset ) + overlap )], mult_r( old_out_fx[( ( i + nz ) + overlap )], tcx_mdct_window_minimum_fx[i].v.re ) ); -#endif move16(); } FOR( ; i < tcx_mdct_window_min_length; i++ ) { -#ifdef BASOP_NOGLOB xn_buf_fx[( ( ( i + ( overlap / 2 ) ) - tcx_offset ) + overlap )] = add_sat( xn_buf_fx[( ( ( i + ( overlap / 2 ) ) - tcx_offset ) + overlap )], mult_r( old_out_fx[( ( i + nz ) + overlap )], tcx_mdct_window_minimum_fx[( tcx_mdct_window_min_length - ( 1 + i ) )].v.im ) ); // Q(-2) -#else - xn_buf_fx[( ( ( i + ( overlap / 2 ) ) - tcx_offset ) + overlap )] = add( xn_buf_fx[( ( ( i + ( overlap / 2 ) ) - tcx_offset ) + overlap )], mult_r( old_out_fx[( ( i + nz ) + overlap )], tcx_mdct_window_minimum_fx[( tcx_mdct_window_min_length - ( 1 + i ) )].v.im ) ); -#endif move16(); } } @@ -3251,20 +3036,12 @@ void IMDCT_ivas_fx( { FOR( ; i < ( overlap - ( tcx_mdct_window_min_length / 2 ) ); i++ ) { -#ifdef BASOP_NOGLOB xn_buf_fx[( ( i + ( overlap / 2 ) ) - tcx_offset )] = add_sat( xn_buf_fx[( ( i + ( overlap / 2 ) ) - tcx_offset )], mult_r( old_out_fx[( i + nz )], tcx_mdct_window_minimum_fx[( ( tcx_mdct_window_min_length - overlap ) + i )].v.re ) ); // Q(-2) -#else - xn_buf_fx[( ( i + ( overlap / 2 ) ) - tcx_offset )] = add( xn_buf_fx[( ( i + ( overlap / 2 ) ) - tcx_offset )], mult_r( old_out_fx[( i + nz )], tcx_mdct_window_minimum_fx[( ( tcx_mdct_window_min_length - overlap ) + i )].v.re ) ); -#endif move16(); } FOR( ; i < overlap; i++ ) { -#ifdef BASOP_NOGLOB xn_buf_fx[( i + ( ( overlap / 2 ) - tcx_offset ) )] = add_sat( xn_buf_fx[( ( i + ( overlap / 2 ) ) - tcx_offset )], mult_r( old_out_fx[( i + nz )], tcx_mdct_window_minimum_fx[( overlap - ( 1 + i ) )].v.im ) ); // Q(-2) -#else - xn_buf_fx[( i + ( ( overlap / 2 ) - tcx_offset ) )] = add( xn_buf_fx[( ( i + ( overlap / 2 ) ) - tcx_offset )], mult_r( old_out_fx[( i + nz )], tcx_mdct_window_minimum_fx[( overlap - ( 1 + i ) )].v.im ) ); -#endif move16(); } } @@ -3277,21 +3054,12 @@ void IMDCT_ivas_fx( { FOR( i = 0; i < ( tcx_mdct_window_half_length / 2 ); i++ ) { -#ifdef BASOP_NOGLOB xn_buf_fx[( ( i + ( overlap / 2 ) ) - tcx_offset )] = add_sat( xn_buf_fx[( ( i + ( overlap / 2 ) ) - tcx_offset )], mult_r( old_syn_overl_fx[i], tcx_mdct_window_half_fx[i].v.re ) ); // Q(-2) -#else - xn_buf_fx[( ( i + ( overlap / 2 ) ) - tcx_offset )] = add( xn_buf_fx[( ( i + ( overlap / 2 ) ) - tcx_offset )], mult_r( old_syn_overl_fx[i], tcx_mdct_window_half_fx[i].v.re ) ); - -#endif move16(); } FOR( ; i < tcx_mdct_window_half_length; i++ ) { -#ifdef BASOP_NOGLOB xn_buf_fx[( ( i + ( overlap / 2 ) ) - tcx_offset )] = add_sat( xn_buf_fx[( ( i + ( overlap / 2 ) ) - tcx_offset )], mult_r( old_syn_overl_fx[i], tcx_mdct_window_half_fx[( tcx_mdct_window_half_length - ( 1 + i ) )].v.im ) ); // Q(-2) -#else - xn_buf_fx[( ( i + ( overlap / 2 ) ) - tcx_offset )] = add( xn_buf_fx[( ( i + ( overlap / 2 ) ) - tcx_offset )], mult_r( old_syn_overl_fx[i], tcx_mdct_window_half_fx[( tcx_mdct_window_half_length - ( 1 + i ) )].v.im ) ); -#endif move16(); } } @@ -3307,11 +3075,7 @@ void IMDCT_ivas_fx( { FOR( i = 0; i < overlap; i++ ) { -#ifdef BASOP_NOGLOB xn_buf_fx[( i + ( overlap / 2 ) )] = add_sat( xn_buf_fx[( i + ( overlap / 2 ) )], old_syn_overl_fx[i] ); // Q(-2) -#else - xn_buf_fx[( i + ( overlap / 2 ) )] = add( xn_buf_fx[( i + ( overlap / 2 ) )], old_syn_overl_fx[i] ); -#endif move16(); } } @@ -3387,22 +3151,14 @@ void IMDCT_ivas_fx( FOR( i = 0; i < ( tcx_mdct_window_half_length / 2 ); i++ ) { xn_buf_fx[( ( i + ( overlap / 2 ) ) - tcx_offset )] = mult_r( xn_buf_fx[( ( i + ( overlap / 2 ) ) - tcx_offset )], tcx_mdct_window_half_fx[i].v.im ); -#ifdef BASOP_NOGLOB xn_buf_fx[( ( i + ( overlap / 2 ) ) - tcx_offset )] = add_sat( xn_buf_fx[( ( i + ( overlap / 2 ) ) - tcx_offset )], mult_r( mult_r( hTcxDec->syn_Overl[i], tcx_mdct_window_half_fx[i].v.re ), tcx_mdct_window_half_fx[i].v.re ) ); // Q(-2) -#else - xn_buf_fx[( ( i + ( overlap / 2 ) ) - tcx_offset )] = add( xn_buf_fx[( ( i + ( overlap / 2 ) ) - tcx_offset )], mult_r( mult_r( hTcxDec->syn_Overl[i], tcx_mdct_window_half_fx[i].v.re ), tcx_mdct_window_half_fx[i].v.re ) ); -#endif move16(); move16(); } FOR( ; i < tcx_mdct_window_half_length; i++ ) { xn_buf_fx[( ( i + ( overlap / 2 ) ) - tcx_offset )] = mult_r( xn_buf_fx[( ( i + ( overlap / 2 ) ) - tcx_offset )], tcx_mdct_window_half_fx[( tcx_mdct_window_half_length - ( 1 + i ) )].v.re ); -#ifdef BASOP_NOGLOB xn_buf_fx[( ( i + ( overlap / 2 ) ) - tcx_offset )] = add_sat( xn_buf_fx[( ( i + ( overlap / 2 ) ) - tcx_offset )], mult_r( mult_r( hTcxDec->syn_Overl[i], tcx_mdct_window_half_fx[( tcx_mdct_window_half_length - ( 1 + i ) )].v.im ), tcx_mdct_window_half_fx[( tcx_mdct_window_half_length - ( 1 + i ) )].v.im ) ); // Q(-2) -#else - xn_buf_fx[( ( i + ( overlap / 2 ) ) - tcx_offset )] = add( xn_buf_fx[( ( i + ( overlap / 2 ) ) - tcx_offset )], mult_r( mult_r( hTcxDec->syn_Overl[i], tcx_mdct_window_half_fx[( tcx_mdct_window_half_length - ( 1 + i ) )].v.im ), tcx_mdct_window_half_fx[( tcx_mdct_window_half_length - ( 1 + i ) )].v.im ) ); -#endif move16(); move16(); } @@ -4050,11 +3806,7 @@ void decoder_tcx_invQ_fx( FOR( i = 0; i < noiseFillingSize; ++i ) { tmp32 = L_shr( x[i], sub( 31, *x_e ) ); -#ifdef BASOP_NOGLOB - *nf_seed = add_o( *nf_seed, (Word16) abs( tmp32 ) * i * 2, &Overflow ); -#else - *nf_seed = add( *nf_seed, (Word16) abs( tmp32 ) * i * 2 ); -#endif + *nf_seed = add_o( *nf_seed, extract_l( L_shl( i_mult( (Word16) L_abs( tmp32 ), i ), 1 ) ), &Overflow ); // abs( tmp32 ) * i * 2 move16(); } } @@ -4122,7 +3874,8 @@ void decoder_tcx_invQ_fx( test(); IF( !st->tcxonly || ( hTcxCfg->resq && hTcxDec->tcx_lpc_shaped_ari ) ) { - FOR( i = 0; i < max( L_spec, L_frameTCX ); i++ ) + Word16 len = s_max( L_spec, L_frameTCX ); + FOR( i = 0; i < len; i++ ) { xn_buf[i] = ONE_IN_Q14; move16(); @@ -4149,11 +3902,7 @@ void decoder_tcx_invQ_fx( move16(); move16(); -#ifdef BASOP_NOGLOB tmp1 = mult_r( shl_sat( L_spec, 5 ), 26214 /*128.f/NORM_MDCT_FACTOR Q15*/ ); -#else - tmp1 = mult_r( shl( L_spec, 5 ), 26214 /*128.f/NORM_MDCT_FACTOR Q15*/ ); -#endif s = 15 - 5 - 7; move16(); IF( GE_16( L_spec, 1024 ) ) /*reduce precision for avoiding overflow*/ @@ -4297,11 +4046,7 @@ void decoder_tcx_invQ_fx( st->last_gain_syn_deemph_e = add( st->last_gain_syn_deemph_e, 10 /*scaling of h1[0] and E_UTIL_synthesis * 2*/ ); move16(); tmp32 = Sqrt32( tmp32, &st->last_gain_syn_deemph_e ); -#ifdef BASOP_NOGLOB st->last_gain_syn_deemph = round_fx_o( tmp32, &Overflow ); // Q15 -#else - last_gain_syn_deemph_fx = round_fx( tmp32 ); -#endif move16(); } @@ -4594,11 +4339,7 @@ void decoder_tcx_noisefilling_fx( tmp32 = L_deposit_l( 0 ); FOR( i = 0; i < L_spec; i++ ) { -#ifdef BASOP_NOGLOB tmp32 = L_macNs_co( tmp32, abs_s( prm_sqQ[i] ), i, &Carry, &Overflow ); -#else - tmp32 = L_macNs( tmp32, abs_s( prm_sqQ[i] ), i ); -#endif } nf_seed = extract_l( tmp32 ); } @@ -4749,11 +4490,7 @@ void decoder_tcx_noisefilling_fx( tmp1 = BASOP_Util_Divide3232_Scale( W_extract_h( E_2ndlast ), W_extract_h( E_last ), &tmp2 ); tmp2 = add( tmp2, sub( exp2, exp1 ) ); -#ifdef BASOP_NOGLOB tmp1 = shl_sat( tmp1, sub( tmp2, 2 ) ); -#else - tmp1 = shl( tmp1, tmp2 ); -#endif /* replace higher energy TCX5 frame by lower one to avoid energy fluctuation */ IF( st->element_mode > EVS_MONO ) @@ -5118,3 +4855,449 @@ void decoder_tcx_noiseshaping_igf_fx( return; } + + +/*-------------------------------------------------------------------* + * decoder_tcx_tns() + * + * TCX: TNS application + *-------------------------------------------------------------------*/ + +void decoder_tcx_tns_fx( + Decoder_State *st, /* i/o: coder memory state */ + const Word16 L_frame_glob, /* i : frame length */ + const Word16 L_spec, + const Word16 L_frame, + const Word16 L_frameTCX, + Word32 x_fx[N_MAX], // Qx + const Word16 fUseTns, /* i : flag that is set if TNS data is present */ + STnsData *tnsData, + const Word16 bfi, /* i : Bad frame indicator */ + const Word16 frame_cnt, /* i : frame counter in the super frame */ + const Word16 whitenedDomain, + Word16 *length ) +{ + Word16 index, isTCX5, L, tmp; + TCX_CONFIG_HANDLE hTcxCfg = st->hTcxCfg; + + index = hTcxCfg->tcx_last_overlap_mode; /* backup last TCX overlap mode */ + move16(); + + isTCX5 = 0; + move16(); + L = L_frameTCX; + move16(); + tmp = L; + move16(); + + test(); + IF( EQ_16( L_frame, shr( st->L_frame, 1 ) ) && st->tcxonly != 0 ) + { + test(); + test(); + IF( frame_cnt != 0 && bfi == 0 && st->last_core != ACELP_CORE ) + { + /* fix sub-window overlap */ + hTcxCfg->tcx_last_overlap_mode = hTcxCfg->tcx_curr_overlap_mode; + move16(); + } + + test(); + test(); + test(); + IF( ( NE_16( hTcxCfg->fIsTNSAllowed, 0 ) && NE_16( fUseTns, 0 ) && NE_16( bfi, 1 ) ) || GT_16( L_spec, L_frameTCX ) ) + { + L = L_spec; + move16(); + tmp = L; + move16(); + } + + test(); + test(); + test(); + test(); + test(); + test(); + test(); + IF( ( EQ_16( bfi, 0 ) && ( NE_16( hTcxCfg->tcx_last_overlap_mode, FULL_OVERLAP ) || + ( EQ_16( hTcxCfg->tcx_curr_overlap_mode, FULL_OVERLAP ) && EQ_16( frame_cnt, 0 ) && EQ_16( index, 0 ) ) ) ) || + ( NE_16( bfi, 0 ) && ( NE_16( hTcxCfg->tcx_last_overlap_mode, FULL_OVERLAP ) && + NE_16( hTcxCfg->tcx_curr_overlap_mode, FULL_OVERLAP ) ) ) ) + { + isTCX5 = 1; + move16(); + + tcx5SpectrumDeinterleaving_fx( shr( L, 1 ), x_fx ); + } + } + + /*-----------------------------------------------------------* + * Temporal Noise Shaping Synthesis * + *-----------------------------------------------------------*/ + + + test(); + test(); + test(); + IF( NE_16( hTcxCfg->fIsTNSAllowed, 0 ) && fUseTns != 0 && NE_16( bfi, 1 ) && EQ_16( tnsData->tnsOnWhitenedSpectra, whitenedDomain ) ) + { + /* Apply TNS to get the reconstructed signal */ + SetTnsConfig( hTcxCfg, L_frame_glob == st->L_frame, ( st->last_core == ACELP_CORE ) && ( frame_cnt == 0 ) ); + + test(); + test(); + IF( EQ_16( L_frame, shr( st->L_frame, 1 ) ) && st->tcxonly != 0 && isTCX5 != 0 ) + { + tcx5TnsGrouping_fx( shr( L, 1 ), shr( hTcxCfg->tnsConfig[0][0].iFilterBorders[0], 1 ), x_fx ); + } + + ApplyTnsFilter( hTcxCfg->pCurrentTnsConfig, tnsData, x_fx, 0 ); + + test(); + test(); + IF( EQ_16( L_frame, shr( st->L_frame, 1 ) ) && st->tcxonly != 0 && isTCX5 != 0 ) + { + test(); + IF( st->element_mode == EVS_MONO || LT_16( L_spec, L_frameTCX ) ) /* todo: this is temporary to maintain EVS BE, this is a bug and should be fixed also for EVS (see issue 13) */ + { + tcx5TnsUngrouping_fx( shr( L_frameTCX, 1 ), shr( hTcxCfg->tnsConfig[0][0].iFilterBorders[0], 1 ), x_fx, DEC ); + tmp = L_frameTCX; + move16(); + } + ELSE + { + tcx5TnsUngrouping_fx( shr( L, 1 ), shr( hTcxCfg->tnsConfig[0][0].iFilterBorders[0], 1 ), x_fx, DEC ); + } + } + } + test(); + IF( NE_16( whitenedDomain, 0 ) && NE_16( isTCX5, 0 ) ) + { + tcx5SpectrumInterleaving_fx( shr( L, 1 ), x_fx ); + } + + /* restore index */ + test(); + test(); + test(); + test(); + IF( EQ_16( L_frame, shr( st->L_frame, 1 ) ) && NE_16( st->tcxonly, 0 ) && NE_16( frame_cnt, 0 ) && EQ_16( bfi, 0 ) && NE_16( st->last_core, ACELP_CORE ) ) + { + /* restore sub-window overlap */ + hTcxCfg->tcx_last_overlap_mode = index; + move16(); + } + + if ( length != NULL ) + { + *length = tmp; + move16(); + } + + return; +} + + +void decoder_tcx_imdct_fx( + Decoder_State *st, /* i/o: coder memory state */ + const Word16 L_frame_glob, /* i : frame length */ + const Word16 L_frameTCX_glob, + const Word16 L_spec, + const Word16 tcx_offset, + const Word16 tcx_offsetFB, + const Word16 L_frame, + const Word16 L_frameTCX, + const Word16 left_rect, + Word32 x_fx[N_MAX], // Q(11) + Word16 q_x, + Word16 xn_buf_fx[], // Q(-2) + Word16 q_win, + const UWord16 kernelType, /* i : TCX transform kernel type */ + const Word16 fUseTns, /* i : flag that is set if TNS data is present */ + Word16 synth_fx[], // Q(-2) /* i/o: synth[-M..L_frame] */ + Word16 synthFB_fx[], // Q(-2) + const Word16 bfi, /* i : Bad frame indicator */ + const Word16 frame_cnt, /* i : frame counter in the super frame */ + const Word16 sba_dirac_stereo_flag /* i : signal stereo output for SBA DirAC */ +) +{ + Word16 j, L, overlap, curr_order, startLine, endLine, isTCX5; + Word16 overlapFB; + Word32 x_tmp_fx[L_FRAME_PLUS]; + Word32 xn_bufFB_fx[L_MDCT_OVLP_MAX + L_FRAME_PLUS + L_MDCT_OVLP_MAX] = { 0 }; + Word16 xn_bufFB_fx_16[L_MDCT_OVLP_MAX + L_FRAME_PLUS + L_MDCT_OVLP_MAX]; + Word16 acelp_zir_fx[L_FRAME_MAX / 2]; + Word32 x_itf_fx[N_MAX_TCX - IGF_START_MN]; + Word16 index, proc = 0; + TCX_LTP_DEC_HANDLE hTcxLtpDec = st->hTcxLtpDec; + TCX_DEC_HANDLE hTcxDec = st->hTcxDec; + TCX_CONFIG_HANDLE hTcxCfg = st->hTcxCfg; + Word16 predictionGain_fx; + Word16 A_itf_fx[ITF_MAX_FILTER_ORDER + 1]; // q_a_itf + Word16 q_a_itf = 15; + Word16 x_e = sub( 31, q_x ); + move16(); + Word16 shift_q = sub( q_x, q_win ); + + /*-----------------------------------------------------------------* + * Initializations + *-----------------------------------------------------------------*/ + + /* Init lengths */ + overlap = hTcxCfg->tcx_mdct_window_length; + move16(); + overlapFB = hTcxCfg->tcx_mdct_window_lengthFB; + move16(); + + index = hTcxCfg->tcx_last_overlap_mode; /* backup last TCX overlap mode */ + move16(); + test(); + test(); + test(); + test(); + IF( EQ_16( L_frame, shr( st->L_frame, 1 ) ) && ( st->tcxonly != 0 ) && ( frame_cnt != 0 ) && ( bfi == 0 ) && ( st->last_core != ACELP_CORE ) ) + { + /* fix sub-window overlap */ + hTcxCfg->tcx_last_overlap_mode = hTcxCfg->tcx_curr_overlap_mode; + move16(); + } + + IF( st->igf != 0 ) + { + proc = st->hIGFDec->flatteningTrigger; + move16(); + + test(); + IF( proc && fUseTns != 0 ) + { + proc = 0; + move16(); + } + + IF( proc ) + { + + startLine = st->hIGFDec->infoIGFStartLine; + move16(); + endLine = st->hIGFDec->infoIGFStopLine; + move16(); + curr_order = 0; + move16(); + predictionGain_fx = 0; + move16(); + L = L_frameTCX; + move16(); + isTCX5 = 0; + move16(); + + /* interleave again for ITF */ + test(); + IF( EQ_16( L_frame, shr( st->L_frame, 1 ) ) && st->tcxonly ) + { + test(); + test(); + test(); + IF( ( hTcxCfg->fIsTNSAllowed && ( fUseTns != 0 ) && NE_16( bfi, 1 ) ) || GT_16( L_spec, L_frameTCX ) ) + { + L = L_spec; + move16(); + } + + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + IF( ( ( bfi == 0 ) && ( ( hTcxCfg->tcx_last_overlap_mode != FULL_OVERLAP ) || + ( ( hTcxCfg->tcx_curr_overlap_mode == FULL_OVERLAP ) && ( frame_cnt == 0 ) && ( index == 0 ) ) ) ) || + ( ( bfi != 0 ) && ( ( hTcxCfg->tcx_last_overlap_mode != FULL_OVERLAP ) && + ( hTcxCfg->tcx_curr_overlap_mode != FULL_OVERLAP ) ) ) ) + { + isTCX5 = 1; + move16(); + + tcx5SpectrumInterleaving_fx( shr( L, 1 ), x_fx ); + } + } + + FOR( j = startLine; j < endLine; j++ ) + { + IF( EQ_16( st->hIGFDec->flag_sparse[j - IGF_START_MN], 2 ) ) + { + x_itf_fx[j - IGF_START_MN] = x_fx[j]; // q_x + move32(); + x_fx[j] = st->hIGFDec->virtualSpec_fx[j - IGF_START_MN]; + move32(); + } + } + + ITF_Detect_fx( x_fx + IGF_START_MN, startLine, endLine, 8 /*maxOrder*/, A_itf_fx, &q_a_itf, &predictionGain_fx, &curr_order, shl( x_e, 1 ) ); + + ITF_Apply_fx( x_fx, startLine, endLine, A_itf_fx, q_a_itf, curr_order ); + + FOR( j = startLine; j < endLine; j++ ) + { + IF( EQ_16( st->hIGFDec->flag_sparse[j - IGF_START_MN], 2 ) ) + { + x_fx[j] = x_itf_fx[j - IGF_START_MN]; // q_x + move32(); + } + } + + /* deinterleave */ + IF( NE_16( isTCX5, 0 ) ) + { + tcx5SpectrumDeinterleaving_fx( shr( L, 1 ), x_fx ); + } + } + } + + /*-----------------------------------------------------------* + * Prepare OLA buffer after waveadjustment. * + * Compute inverse MDCT of x[]. * + *-----------------------------------------------------------*/ + + + IF( EQ_16( st->element_mode, IVAS_CPE_MDCT ) ) + { + Word16 copy_len = s_min( L_FRAME48k, s_max( L_spec, s_max( L_frame, L_frameTCX ) ) ); + set32_fx( x_tmp_fx, 0, L_FRAME_PLUS ); + Copy32( x_fx, x_tmp_fx, copy_len ); // q_x + Copy32( x_fx, xn_bufFB_fx, copy_len ); // q_x + } + ELSE IF( ( st->element_mode == EVS_MONO ) ) + { + Copy32( x_fx, xn_bufFB_fx, s_max( L_spec, s_max( L_frame, L_frameTCX ) ) ); // q_x + } + ELSE + { + Word16 copy_len = s_max( L_spec, s_max( L_frame, L_frameTCX ) ); + Copy32( x_fx, x_tmp_fx, copy_len ); // q_x + Copy32( x_fx, xn_bufFB_fx, copy_len ); // q_x + } + + IF( ( st->igf != 0 ) ) + { + set32_fx( xn_bufFB_fx + st->hIGFDec->infoIGFStartLine, 0, L_frameTCX - st->hIGFDec->infoIGFStartLine ); + } + + test(); + IF( NE_16( st->element_mode, IVAS_CPE_DFT ) && !sba_dirac_stereo_flag ) + { + + IMDCT_ivas_fx( xn_bufFB_fx, q_x, hTcxDec->syn_Overl, hTcxDec->syn_Overl_TDAC, xn_buf_fx, hTcxCfg->tcx_aldo_window_1, hTcxCfg->tcx_aldo_window_1_trunc, hTcxCfg->tcx_aldo_window_2, + hTcxCfg->tcx_mdct_window_half, hTcxCfg->tcx_mdct_window_minimum, hTcxCfg->tcx_mdct_window_trans, hTcxCfg->tcx_mdct_window_half_length, hTcxCfg->tcx_mdct_window_min_length, index, + kernelType, left_rect, tcx_offset, overlap, L_frame, L_frameTCX, shr( s_max( L_frameTCX, L_spec ), 1 ), L_frame_glob, frame_cnt, bfi, st->hHQ_core->old_out_LB_fx, 0, st, 0, acelp_zir_fx, q_win ); + } + + /* Generate additional comfort noise to mask potential coding artefacts */ + test(); + test(); + test(); + IF( ( st->flag_cna != 0 ) && NE_16( st->element_mode, IVAS_CPE_TD ) && NE_16( st->element_mode, IVAS_CPE_DFT ) && ( st->cna_dirac_flag == 0 ) ) + { + generate_masking_noise_mdct_ivas_fx( x_fx, &x_e, st->hFdCngDec->hFdCngCom ); + FOR( Word16 ind = 0; ind < L_frame; ind++ ) + { + x_fx[ind] = L_shr( x_fx[ind], sub( 31, add( x_e, q_x ) ) ); // q_x + } + } + + test(); + IF( EQ_16( st->element_mode, IVAS_CPE_DFT ) || ( sba_dirac_stereo_flag != 0 ) ) + { + Copy32( x_fx, xn_bufFB_fx, s_max( L_spec, s_max( L_frame, L_frameTCX ) ) ); // q_x + + IMDCT_ivas_fx( xn_bufFB_fx, q_x, hTcxDec->syn_Overl, hTcxDec->syn_Overl_TDAC, xn_buf_fx, hTcxCfg->tcx_aldo_window_1, hTcxCfg->tcx_aldo_window_1_trunc, hTcxCfg->tcx_aldo_window_2, hTcxCfg->tcx_mdct_window_half, hTcxCfg->tcx_mdct_window_minimum, hTcxCfg->tcx_mdct_window_trans, hTcxCfg->tcx_mdct_window_half_length, hTcxCfg->tcx_mdct_window_min_length, index, + kernelType, left_rect, tcx_offset, overlap, L_frame, L_frameTCX, shr( s_max( L_frameTCX, L_spec ), 1 ), L_frame_glob, frame_cnt, bfi, st->hHQ_core->old_out_LB_fx, 0, st, 0, acelp_zir_fx, q_win ); + } + + FOR( Word16 ind = 0; ind < L_MDCT_OVLP_MAX + L_FRAME_PLUS + L_MDCT_OVLP_MAX; ind++ ) + { + xn_bufFB_fx_16[ind] = extract_l( L_shr( xn_bufFB_fx[ind], shift_q ) ); // q_x + move16(); + } + + Word16 ratio_e; + Word16 ratio = BASOP_Util_Divide1616_Scale( L_frameTCX_glob, L_frame_glob, &ratio_e ); // Q = 15-ratio_e. * FSCALE_DENOM is (1 << 9) + ratio = shr( ratio, sub( 6, ratio_e ) ); + + IF( st->element_mode != EVS_MONO ) + { + IMDCT_ivas_fx( x_tmp_fx, q_x, hTcxDec->syn_OverlFB, hTcxDec->syn_Overl_TDACFB, xn_bufFB_fx_16, hTcxCfg->tcx_aldo_window_1_FB, hTcxCfg->tcx_aldo_window_1_FB_trunc, hTcxCfg->tcx_aldo_window_2_FB, + hTcxCfg->tcx_mdct_window_halfFB, hTcxCfg->tcx_mdct_window_minimumFB, hTcxCfg->tcx_mdct_window_transFB, hTcxCfg->tcx_mdct_window_half_lengthFB, hTcxCfg->tcx_mdct_window_min_lengthFB, index, + kernelType, left_rect, tcx_offsetFB, overlapFB, L_frameTCX, L_frameTCX, shr( s_max( L_frameTCX, L_spec ), 1 ), L_frameTCX_glob, frame_cnt, bfi, st->hHQ_core->old_out_fx, 1, st, ratio, acelp_zir_fx, q_win ); + } + ELSE + { + + IMDCT_ivas_fx( x_fx, q_x, hTcxDec->syn_OverlFB, hTcxDec->syn_Overl_TDACFB, xn_bufFB_fx_16, hTcxCfg->tcx_aldo_window_1_FB, hTcxCfg->tcx_aldo_window_1_FB_trunc, hTcxCfg->tcx_aldo_window_2_FB, hTcxCfg->tcx_mdct_window_halfFB, hTcxCfg->tcx_mdct_window_minimumFB, hTcxCfg->tcx_mdct_window_transFB, hTcxCfg->tcx_mdct_window_half_lengthFB, hTcxCfg->tcx_mdct_window_min_lengthFB, index, + kernelType, left_rect, tcx_offsetFB, overlapFB, L_frameTCX, L_frameTCX, shr( s_max( L_frameTCX, L_spec ), 1 ), L_frameTCX_glob, frame_cnt, bfi, st->hHQ_core->old_out_fx, 1, st, ratio, acelp_zir_fx, q_win ); + } + FOR( Word16 ind = 0; ind < L_MDCT_OVLP_MAX + L_FRAME_PLUS + L_MDCT_OVLP_MAX; ind++ ) + { + xn_bufFB_fx[ind] = L_shl( L_deposit_l( xn_bufFB_fx_16[ind] ), shift_q ); // Q_x + } + + IF( ( bfi == 0 ) ) + { + Word16 res_m, res_e = 0; + move16(); + st->second_last_tns_active = st->last_tns_active; + move16(); + st->last_tns_active = hTcxCfg->fIsTNSAllowed & fUseTns; + move16(); + hTcxDec->tcxltp_third_last_pitch = hTcxDec->tcxltp_second_last_pitch; + move32(); + hTcxDec->tcxltp_second_last_pitch = st->old_fpitch; + move32(); + res_m = BASOP_Util_Divide1616_Scale( hTcxLtpDec->tcxltp_pitch_fr, st->pit_res_max, &res_e ); + st->old_fpitch = L_add( L_shl( hTcxLtpDec->tcxltp_pitch_int, 16 ), L_shl( res_m, add( res_e, 1 ) ) ); + + IF( EQ_16( st->element_mode, IVAS_CPE_MDCT ) ) + { + // Using sat as a single instruction shifts and extracts + st->old_fpitch = W_shl_sat_l( W_mult0_32_32( st->old_fpitch, L_frame_glob ), -8 ); // Divide by 256 ==> SHR by 8 + move32(); + } + + IF( GT_16( st->element_mode, EVS_MONO ) ) + { + res_m = BASOP_Util_Divide1616_Scale( L_frameTCX_glob, L_frame_glob, &res_e ); + st->old_fpitchFB = L_shl( Mpy_32_16_1( st->old_fpitch, res_m ), res_e ); + move32(); + } + ELSE + { + res_m = BASOP_Util_Divide1616_Scale( L_frameTCX, L_frame, &res_e ); + st->old_fpitchFB = L_shl( Mpy_32_16_1( st->old_fpitch, res_m ), res_e ); + move32(); + } + } + + /* Update old_syn_overl */ + IF( hTcxCfg->last_aldo == 0 ) + { + Copy( xn_buf_fx + L_frame, hTcxDec->syn_Overl, overlap ); // Q(-2) + FOR( Word16 ind = 0; ind < overlapFB; ind++ ) + { + hTcxDec->syn_OverlFB[ind] = extract_l( L_shr( xn_bufFB_fx[( ind + L_frameTCX )], shift_q ) ); // q_x + } + } + + /* Output */ + Copy( xn_buf_fx + sub( shr( overlap, 1 ), tcx_offset ), synth_fx, L_frame_glob ); // Q(-2) + FOR( Word16 ind = 0; ind < L_frameTCX_glob; ind++ ) + { + synthFB_fx[ind] = extract_l( L_shr( xn_bufFB_fx[( ind + ( ( overlapFB >> 1 ) - tcx_offsetFB ) )], shift_q ) ); // q_x + } + + + return; +} diff --git a/lib_dec/dec_tran.c b/lib_dec/dec_tran.c deleted file mode 100644 index 88f93c73337a55edba9c3770c1f9dbcd7280b9d7..0000000000000000000000000000000000000000 --- a/lib_dec/dec_tran.c +++ /dev/null @@ -1,47 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include "cnst.h" -#include "prot.h" -#include "wmc_auto.h" - -/*-------------------------------------------------------------------* - * decod_tran() - * - * Decode transition (TC) frames - *-------------------------------------------------------------------*/ diff --git a/lib_dec/dec_tran_fx.c b/lib_dec/dec_tran_fx.c index d21109dce767cb8d9a39949efdea4901b90e628d..e886fd33770a60b034c992b92348e9fdc33bb9e6 100644 --- a/lib_dec/dec_tran_fx.c +++ b/lib_dec/dec_tran_fx.c @@ -234,21 +234,12 @@ void decod_tran_fx( FOR( i = 0; i < L_SUBFR; i++ ) { L_tmp = L_mult( gain_preQ_fx, code_preQ_fx[i] ); /* Q2 + Q10 -> Q13*/ -#ifdef BASOP_NOGLOB - L_tmp = L_shl_sat( L_tmp, tmp1_fx ); /* Q16 + Q_exc */ + L_tmp = L_shl_sat( L_tmp, tmp1_fx ); /* Q16 + Q_exc */ tmp_fx = round_fx_sat( L_tmp ); exc2_fx[i + i_subfr] = add_sat( exc2_fx[i + i_subfr], tmp_fx ); move16(); exc_fx[i + i_subfr] = add_sat( exc_fx[i + i_subfr], tmp_fx ); move16(); -#else - L_tmp = L_shl( L_tmp, tmp1_fx ); /* Q16 + Q_exc */ - tmp_fx = round_fx( L_tmp ); - exc2_fx[i + i_subfr] = add( exc2_fx[i + i_subfr], tmp_fx ); - move16(); - exc_fx[i + i_subfr] = add( exc_fx[i + i_subfr], tmp_fx ); - move16(); -#endif } } diff --git a/lib_dec/dec_uv.c b/lib_dec/dec_uv.c deleted file mode 100644 index e748899a9667996f0776eb65127752b66796a660..0000000000000000000000000000000000000000 --- a/lib_dec/dec_uv.c +++ /dev/null @@ -1,40 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include "prot.h" -#include "wmc_auto.h" diff --git a/lib_dec/dec_uv_fx.c b/lib_dec/dec_uv_fx.c index 352738d5f524a16ecebeaf947766054f147f5475..bbec94d94f903d1116d84751f4a0c9e43223c012 100644 --- a/lib_dec/dec_uv_fx.c +++ b/lib_dec/dec_uv_fx.c @@ -27,7 +27,6 @@ static void gain_dec_gacelp_uv_fx( void decod_unvoiced_fx( Decoder_State *st_fx, /* i/o: decoder static memory */ - const Word16 *Aq_fx, /* Q12 i : LP filter coefficient */ const Word16 coder_type, /* Q0 i : coding type */ Word16 *tmp_noise_fx, /* Q0 o : long term temporary noise energy */ Word16 *pitch_buf_fx, /* Q6 o : floating pitch values for each subframe*/ @@ -44,7 +43,6 @@ void decod_unvoiced_fx( Word16 voice_fac_fx; /* Voicing factor */ Word16 code_fx[L_SUBFR]; /* algebraic codevector */ Word16 i_subfr_fx; - const Word16 *p_Aq_fx; Word16 *pt_pitch_fx; gain_pit_fx = 0; @@ -57,7 +55,6 @@ void decod_unvoiced_fx( CNG_reset_dec_fx( st_fx, pitch_buf_fx, voice_factors_fx ); } - p_Aq_fx = Aq_fx; move16(); /*Q12*/ /* pointer to interpolated LPC parameters */ pt_pitch_fx = pitch_buf_fx; move16(); /* pointer to the pitch buffer */ @@ -92,7 +89,6 @@ void decod_unvoiced_fx( interp_code_5over2_fx( &exc_fx[i_subfr_fx], &bwe_exc_fx[( ( i_subfr_fx * 2 * HIBND_ACB_L_FAC ) >> 1 )], L_SUBFR ); - p_Aq_fx += ( M + 1 ); pt_pitch_fx++; st_fx->tilt_code_dec_fx[tmp_idx] = st_fx->tilt_code_fx; move16(); @@ -114,17 +110,17 @@ void decod_unvoiced_fx( *-------------------------------------------------------------------*/ void decod_unvoiced_ivas_fx( - Decoder_State *st_fx, /* i/o: decoder static memory */ - const Word16 *Aq_fx, /* Q12 i : LP filter coefficient */ - const Word16 Es_pred_fx, /* i : predicted scaled innov. energy */ - const int16_t uc_two_stage_flag, /* i : flag indicating two-stage UC */ - const Word16 coder_type, /* Q0 i : coding type */ - Word16 *tmp_noise_fx, /* Q0 o : long term temporary noise energy */ - Word16 *pitch_buf_fx, /* Q6 o : floating pitch values for each subframe*/ - Word16 *voice_factors_fx, /* Q15 o : voicing factors */ - Word16 *exc_fx, /* Q_X o : adapt. excitation exc */ - Word16 *exc2_fx, /* Q_X o : adapt. excitation/total exc */ - Word16 *bwe_exc_fx, /* Q_X i/o: excitation for SWB TBE */ + Decoder_State *st_fx, /* i/o: decoder static memory */ + const Word16 *Aq_fx, /* Q12 i : LP filter coefficient */ + const Word16 Es_pred_fx, /* i : predicted scaled innov. energy */ + const Word16 uc_two_stage_flag, /* i : flag indicating two-stage UC */ + const Word16 coder_type, /* Q0 i : coding type */ + Word16 *tmp_noise_fx, /* Q0 o : long term temporary noise energy */ + Word16 *pitch_buf_fx, /* Q6 o : floating pitch values for each subframe*/ + Word16 *voice_factors_fx, /* Q15 o : voicing factors */ + Word16 *exc_fx, /* Q_X o : adapt. excitation exc */ + Word16 *exc2_fx, /* Q_X o : adapt. excitation/total exc */ + Word16 *bwe_exc_fx, /* Q_X i/o: excitation for SWB TBE */ Word16 *gain_buf ) { Word16 gain_pit_fx; /* Quantized pitch gain */ @@ -255,9 +251,9 @@ void decod_unvoiced_ivas_fx( Word16 tmp_idx; tmp_idx = 0; move16(); - if ( i_subfr_fx != 0 ) + IF( i_subfr_fx != 0 ) { - idiv1616( i_subfr_fx, L_SUBFR ); + tmp_idx = idiv1616( i_subfr_fx, L_SUBFR ); } voice_factors_fx[tmp_idx] = 0; move16(); @@ -372,11 +368,7 @@ static void gain_dec_gacelp_uv_fx( *past_gcode = L_shl( L_tmp1, sub( exp_L_tmp1, 15 ) ); /* Q16 */ move32(); -#ifdef BASOP_NOGLOB *gain_code = L_shl_sat( Mpy_32_16_1( *past_gcode, *gain_inov ), 3 ); -#else - *gain_code = L_shl( Mpy_32_16_1( *past_gcode, *gain_inov ), 3 ); -#endif move32(); diff --git a/lib_dec/decision_matrix_dec.c b/lib_dec/decision_matrix_dec.c deleted file mode 100644 index a96d130cb7b5bdcee22cb5dcb02c029006dee9e8..0000000000000000000000000000000000000000 --- a/lib_dec/decision_matrix_dec.c +++ /dev/null @@ -1,50 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include "stat_dec.h" -#include "rom_com.h" -#include "prot.h" -#include "wmc_auto.h" - -/*-----------------------------------------------------------------* - * decision_matrix_dec() - * - * ACELP/HQ core selection - * Read ACELP signaling bits from the bitstream - * Set extension layers - *-----------------------------------------------------------------*/ diff --git a/lib_dec/decision_matrix_dec_fx.c b/lib_dec/decision_matrix_dec_fx.c index 9c0020223150cbb48adcfa4f6497e23fbe600359..f9833e80a85cc38309828ee2b6f2d0764df82741 100644 --- a/lib_dec/decision_matrix_dec_fx.c +++ b/lib_dec/decision_matrix_dec_fx.c @@ -681,12 +681,12 @@ void decision_matrix_dec_fx( st->nb_subfr = NB_SUBFR16k; move16(); } -#if 1 // def ADD_IVAS_BWE 0> NEEDED for IO with conf_acelp1 + st->extl_orig = st->extl; move16(); st->extl_brate_orig = st->extl_brate; move32(); -#endif + test(); IF( EQ_32( st->output_Fs, 8000 ) ) { @@ -713,5 +713,20 @@ void decision_matrix_dec_fx( move16(); } +#ifdef NONBE_FIX_GSC_BSTR + /*-----------------------------------------------------------------* + * set inactive coder_type flag in ACELP core + *-----------------------------------------------------------------*/ + + st->inactive_coder_type_flag = 0; /* AVQ by default */ + move16(); + + if ( LE_32( st->total_brate, MAX_GSC_INACTIVE_BRATE ) ) + { + st->inactive_coder_type_flag = 1; /* GSC */ + move16(); + } + +#endif return; } diff --git a/lib_dec/dlpc_avq.c b/lib_dec/dlpc_avq.c deleted file mode 100644 index 3514dda88db2f9cf14dc1f1e4ef2e3a51656e03a..0000000000000000000000000000000000000000 --- a/lib_dec/dlpc_avq.c +++ /dev/null @@ -1,47 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include "prot.h" -#include "ivas_prot.h" -#include "wmc_auto.h" - -/*------------------------------------------------------------------* - * dlpc_avq() - * - * Variable bitrate multiple LPC un-quantizer - *------------------------------------------------------------------*/ diff --git a/lib_dec/dlpc_stoch.c b/lib_dec/dlpc_stoch.c deleted file mode 100644 index c1956b8d903ffc59fcb8895a07ecbe363d6ce954..0000000000000000000000000000000000000000 --- a/lib_dec/dlpc_stoch.c +++ /dev/null @@ -1,49 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include -#include "options.h" -#include "prot.h" -#include "rom_com.h" -#include "basop_proto_func.h" -#include "wmc_auto.h" - -/*------------------------------------------------------------------* - * lpc_unquantize() - * - * - *------------------------------------------------------------------*/ diff --git a/lib_dec/er_dec_acelp.c b/lib_dec/er_dec_acelp.c deleted file mode 100644 index 68731d8f1702d45c4fc58916c47fef083afa1903..0000000000000000000000000000000000000000 --- a/lib_dec/er_dec_acelp.c +++ /dev/null @@ -1,42 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include -#include "options.h" -#include -#include "prot.h" -#include "wmc_auto.h" diff --git a/lib_dec/er_dec_acelp_fx.c b/lib_dec/er_dec_acelp_fx.c index f61e782e342baee1480fbf6b0e2eefa0f8aadfb9..e30553d388e32c0a53b2b903aa763b120af22ab0 100644 --- a/lib_dec/er_dec_acelp_fx.c +++ b/lib_dec/er_dec_acelp_fx.c @@ -202,11 +202,7 @@ void con_acelp_fx( Tc = round_fx( tmp_tc ); /* Q0 */ BASOP_SATURATE_WARNING_OFF_EVS /*if this ever saturates, it doesn't matter*/ -#ifdef BASOP_NOGLOB tmp = sub( shl_sat( abs_s( sub( T0, Tc ) ), 6 ), mult( 19661 /*0.15f Q17*/, shl_sat( Tc, 4 ) ) /*Q6*/ ); -#else - tmp = sub( shl( abs_s( sub( T0, Tc ) ), 6 ), mult( 19661 /*0.15f Q17*/, shl( Tc, 4 ) ) /*Q6*/ ); -#endif BASOP_SATURATE_WARNING_ON_EVS test(); test(); @@ -419,11 +415,7 @@ void con_acelp_fx( FOR( ; i < l; i++ ) { BASOP_SATURATE_WARNING_OFF_EVS -#ifdef BASOP_NOGLOB exc[i] = mult_r( exc[i], shl_sat( gain, 1 ) ); /*overflow is first iteration because gain may be 1 after shift*/ /*Qf_exc*/ -#else - exc[i] = mult_r( exc[i], shl( gain, 1 ) ); /*overflow is first iteration because gain may be 1 after shift*/ /*Qf_exc*/ -#endif BASOP_SATURATE_WARNING_ON_EVS move16(); gain = sub( gain, step ); @@ -434,11 +426,7 @@ void con_acelp_fx( FOR( ; i < l; i++ ) { BASOP_SATURATE_WARNING_OFF_EVS -#ifdef BASOP_NOGLOB exc[i] = mult_r( exc[i], shl_sat( gain, 1 ) ); /*overflow is first iteration because gain may become 1 due to shift*/ /*Qf_exc*/ -#else - exc[i] = mult_r( exc[i], shl( gain, 1 ) ); /*overflow is first iteration because gain may become 1 due to shift*/ /*Qf_exc*/ -#endif BASOP_SATURATE_WARNING_ON_EVS move16(); gain = sub( gain, step ); @@ -458,7 +446,7 @@ void con_acelp_fx( ELSE { /* No harmonic part */ - assert( (int) ( sizeof( buf ) / sizeof( buf[0] ) ) - M - L_EXC_MEM_DEC >= st->L_frame + st->L_frame / 2 ); + assert( (Word32) ( sizeof( buf ) / sizeof( buf[0] ) ) - M - L_EXC_MEM_DEC >= st->L_frame + st->L_frame / 2 ); set16_fx( &exc[0], 0, add( st->L_frame, shr( st->L_frame, 1 ) ) ); FOR( i = 0; i < st->nb_subfr; i++ ) @@ -541,24 +529,12 @@ void con_acelp_fx( gain_32 = st->Mode2_lp_gainc; /*15Q16 */ /* start-of-the-frame gain */ move32(); -#ifdef BASOP_NOGLOB ftmp = round_fx_sat( L_shl_sat( gain_32, 1 ) ); /*Q0*/ -#else - ftmp = round_fx( L_shl( gain_32, 1 ) ); /*Q0*/ -#endif BASOP_SATURATE_WARNING_OFF_EVS -#ifdef BASOP_NOGLOB tmp_16 = sub( shl_sat( gainCNG, sub( gainCNG_e, 5 /*Q5*/ ) ), ftmp ); /*Q0*/ -#else - tmp_16 = sub( shl( gainCNG, sub( gainCNG_e, 5 /*Q5*/ ) ), ftmp ); -#endif /*in case of overflow:*/ test(); -#ifdef BASOP_NOGLOB if ( ( EQ_16( shl_sat( ftmp, sub( gainCNG_e, 1 ) ), MAXVAL_WORD16 ) ) && EQ_16( gainCNG, MAXVAL_WORD16 ) ) -#else - if ( ( EQ_16( shl( ftmp, sub( gainCNG_e, 1 ) ), MAXVAL_WORD16 ) ) && EQ_16( gainCNG, MAXVAL_WORD16 ) ) -#endif { tmp_16 = 1; move16(); @@ -670,24 +646,15 @@ void con_acelp_fx( /* non-causal ringing of the FIR filter */ /* gain_16 = gain_32 = gain_inov * gain */ - gain_32 = Mpy_32_16_1( gain_32, gain_inov ); /* 15Q16 * Q15 * 2^s_gain_inov */ -#ifdef BASOP_NOGLOB + gain_32 = Mpy_32_16_1( gain_32, gain_inov ); /* 15Q16 * Q15 * 2^s_gain_inov */ gain_32 = L_shl_sat( gain_32, add( 15, s_gain_inov ) ); /* Q31 */ gain_16 = round_fx_sat( gain_32 ); /* Q15 */ -#else - gain_32 = L_shl( gain_32, add( 15, s_gain_inov ) ); /* Q31 */ - gain_16 = round_fx( gain_32 ); /* Q15 */ -#endif /* step_32 = gain_inov * step */ step_32 = Mpy_32_16_1( step_32, gain_inov ); /* 15Q16 * Q15 * 2^s_gain_inov */ step_32 = L_shl( step_32, add( 15, s_gain_inov ) ); /* Q31 */ -#ifdef BASOP_NOGLOB g_e = norm_s( round_fx_sat( L_shl_sat( Mpy_32_16_1( st->Mode2_lp_gainc, gain_inov ), add( 15, s_gain_inov ) ) ) ); /* norm_s for gain*gain_inov at the end of the following loops */ -#else - g_e = norm_s( round_fx( L_shl( Mpy_32_16_1( st->Mode2_lp_gainc, gain_inov ), add( 15, s_gain_inov ) ) ) ); /* norm_s for gain*gain_inov at the end of the following loops */ -#endif g_e = s_min( norm_s( gain_16 ), g_e ); gain_16 = shl( gain_16, g_e ); /*Q15 + g_e*/ gain_32 = L_shl( gain_32, g_e ); /*Q31 + g_e*/ @@ -826,13 +793,8 @@ void con_acelp_fx( /* i_subfr / L_SUBFR */ tmp_16 = shr( i_subfr, Q6 ); g = mult_r( st->last_gain_syn_deemph, gain_lpc[tmp_16] ); /* Q15 - gain_lpc_e[tmp_16] */ -#ifdef BASOP_NOGLOB g_e = add_sat( st->last_gain_syn_deemph_e, gain_lpc_e[tmp_16] ); g = shl_sat( g, g_e ); /* Q15 */ -#else - g_e = add( st->last_gain_syn_deemph_e, gain_lpc_e[tmp_16] ); - g = shl( g, g_e ); -#endif FOR( i = 0; i < L_SUBFR; i++ ) { @@ -917,11 +879,7 @@ void con_acelp_fx( tmp_16 = shr( i_subfr, Q6 ); g = mult_r( st->last_gain_syn_deemph, gain_lpc[tmp_16] ); /* Q15 - gain_lpc_e[tmp_16] */ g_e = add( st->last_gain_syn_deemph_e, gain_lpc_e[tmp_16] ); -#ifdef BASOP_NOGLOB g = shl_sat( g, g_e ); /*Q15*/ -#else - g = shl( g, g_e ); -#endif FOR( i = 0; i < L_SUBFR; i++ ) { /* exc[i_subfr + i] *= st->last_gain_syn_deemph*gain_lpc[j]; */ @@ -990,11 +948,7 @@ void con_acelp_fx( { FOR( i = 0; i < st->L_frame; i++ ) { -#ifdef BASOP_NOGLOB syn[i] = add_sat( syn[i], syn_unv[i] ); /*Qf_syn*/ -#else - syn[i] = add( syn[i], syn_unv[i] ); -#endif move16(); } } @@ -1048,11 +1002,7 @@ void con_acelp_fx( /*updating enr_old parameters*/ frame_ener_fx( st->L_frame, st->last_good, syn, round_fx( tmp_tc ), &( st->enr_old_fx ), 1, 0, 0, 0 ); -#ifdef BASOP_NOGLOB st->enr_old_fx = L_shl_sat( st->enr_old_fx, shl( negate( Qf_syn ), 1 ) ); /*Q0*/ -#else - st->enr_old_fx = L_shl( st->enr_old_fx, shl( negate( Qf_syn ), 1 ) ); -#endif move32(); /* update ACELP synthesis memory */ Copy( mem_syn, st->mem_syn2_fx, M ); /*Qf_syn*/ @@ -1187,11 +1137,7 @@ static void memsynPrecission_fx( Word16 nbLostCmpt, Word16 *mem_syn /*Qx*/, Word { /*saturation doesn't matter*/ BASOP_SATURATE_WARNING_OFF_EVS -#ifdef BASOP_NOGLOB tmp = add_sat( tmp, abs_s( mem_syn[i] ) ); -#else - tmp = add( tmp, abs_s( mem_syn[i] ) ); -#endif BASOP_SATURATE_WARNING_ON_EVS } /*if there is energy in scale_syn, then increase precision*/ diff --git a/lib_dec/er_dec_tcx.c b/lib_dec/er_dec_tcx.c deleted file mode 100644 index 2d8fdd56a26863aa278c3049828685d97e31264f..0000000000000000000000000000000000000000 --- a/lib_dec/er_dec_tcx.c +++ /dev/null @@ -1,45 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include "cnst.h" -#include "ivas_cnst.h" -#include -#include -#include "options.h" -#include -#include "prot.h" -#include "rom_dec.h" -#include "wmc_auto.h" diff --git a/lib_dec/er_dec_tcx_fx.c b/lib_dec/er_dec_tcx_fx.c index 352c46ad63048ce8e6c30f33b38de9e964391e24..5cc06dabf285301cae74d550d27f09128f1954d1 100644 --- a/lib_dec/er_dec_tcx_fx.c +++ b/lib_dec/er_dec_tcx_fx.c @@ -36,34 +36,18 @@ static void calcGainc_fx( Word16 *exc, Word16 Q_exc, Word32 old_fpitch /*Q16*/, tmp16 = round_fx( old_fpitch ); /*Q0*/ tmp_loop = shl( L_subfr, 1 ); BASOP_SATURATE_WARNING_OFF_EVS -#ifdef BASOP_NOGLOB tmp16_2 = round_fx_o( L_shl_o( lp_gainp, 2, &Overflow ), &Overflow ); /*Q31->Q15, no severe saturation, because st->lp_gainp here is [0,1]*/ -#else - tmp16_2 = round_fx( L_shl( lp_gainp, 2 ) ); /*Q31->Q15, no severe saturation, because st->lp_gainp here is [0,1]*/ -#endif BASOP_SATURATE_WARNING_ON_EVS FOR( i = 0; i < tmp_loop; i++ ) { /*st->lp_gainc += ( exc[i-2*L_subfr] - st->Mode2_lp_gainp * exc[i-2*L_subfr-(int)(st->old_fpitch+0.5f)] ) * ( exc[i-2*L_subfr] - st->Mode2_lp_gainp * exc[i-2*L_subfr-(int)(st->old_fpitch+0.5f)] );*/ -#ifdef BASOP_NOGLOB tmp16_3 = sub_o( exc[( i - ( L_subfr * 2 ) )] /*Q1*/, mult_r( tmp16_2 /*Q15*/, exc[( ( i - ( L_subfr * 2 ) ) - tmp16 )] /*Q1*/ ) /*Q1*/, &Overflow ); -#else - tmp16_3 = sub( exc[sub( i, shl( L_subfr, 1 ) )] /*Q1*/, mult_r( tmp16_2 /*Q15*/, exc[sub( sub( i, shl( L_subfr, 1 ) ), tmp16 )] /*Q1*/ ) /*Q1*/ ); -#endif -#ifdef BASOP_NOGLOB L_acc = L_macNs_co( L_acc, tmp16_3, tmp16_3, &Carry, &Overflow ); /*Q3*/ -#else - L_acc = L_macNs( L_acc, tmp16_3, tmp16_3 ); /*Q3*/ -#endif Overflow = 0; move16(); -#ifdef BASOP_NOGLOB L_c = L_macNs_co( L_c, 0, 0, &Carry, &Overflow ); /*Accumulate Carrys Q-1*/ -#else - L_c = L_macNs( L_c, 0, 0 ); /*Accumulate Carrys*/ -#endif Carry = 0; move16(); } @@ -105,18 +89,10 @@ static void calcGainc2_fx( Word16 *exc, Word16 Q_exc, Word16 L_subfr /*Q0*/, Wor FOR( i = 0; i < cnt; i++ ) { /* *gainc += ( exc[i-2*L_subfr] ) * ( exc[i-2*L_subfr]); */ -#ifdef BASOP_NOGLOB /* Critical Carry/Overflow */ L_acc = L_macNs_co( L_acc, exc[( i - ( L_subfr * 2 ) )] /*Q1*/, exc[( i - ( L_subfr * 2 ) )] /*Q1*/, &Carry, &Overflow ); /*Q3*/ -#else - L_acc = L_macNs( L_acc, exc[sub( i, shl( L_subfr, 1 ) )] /*Q1*/, exc[sub( i, shl( L_subfr, 1 ) )] /*Q1*/ ); /*Q3*/ -#endif Overflow = 0; move16(); -#ifdef BASOP_NOGLOB /* Critical Carry/Overflow */ L_c = L_macNs_co( L_c, 0, 0, &Carry, &Overflow ); /* Accumulate Carrys Q-1*/ -#else - L_c = L_macNs( L_c, 0, 0 ); /* Accumulate Carrys */ -#endif Carry = 0; move16(); } @@ -401,7 +377,6 @@ void con_tcx_fx( { FOR( i = 0; i < Tc; i++ ) { -#ifdef BASOP_NOGLOB *pt_exc++ = mac_r_sat( L_mac_sat( L_mac_sat( L_mac_sat( L_mac_sat( L_mac_sat( L_mac_sat( L_mac_sat( L_mac_sat( L_mac_sat( L_mult( 174 /* 0.0053f Q15*/, pt1_exc[-5] ), 0 /* 0.0000f Q15*/, pt1_exc[-4] ), @@ -414,20 +389,6 @@ void con_tcx_fx( -1442 /*-0.0440f Q15*/, pt1_exc[3] ), 0 /* 0.0000f Q15*/, pt1_exc[4] ), 174 /* 0.0053f Q15*/, pt1_exc[5] ); /*Q_exc*/ -#else - *pt_exc++ = mac_r( L_mac( L_mac( L_mac( L_mac( L_mac( L_mac( L_mac( L_mac( L_mac( - L_mult( 174 /* 0.0053f Q15*/, pt1_exc[-5] ), - 0 /* 0.0000f Q15*/, pt1_exc[-4] ), - -1442 /*-0.0440f Q15*/, pt1_exc[-3] ), - 0 /* 0.0000f Q15*/, pt1_exc[-2] ), - 8641 /* 0.2637f Q15*/, pt1_exc[-1] ), - 18022 /* 0.5500f Q15*/, pt1_exc[0] ), - 8641 /* 0.2637f Q15*/, pt1_exc[1] ), - 0 /* 0.0000f Q15*/, pt1_exc[2] ), - -1442 /*-0.0440f Q15*/, pt1_exc[3] ), - 0 /* 0.0000f Q15*/, pt1_exc[4] ), - 174 /* 0.0053f Q15*/, pt1_exc[5] ); -#endif move16(); pt1_exc++; } @@ -436,7 +397,6 @@ void con_tcx_fx( { FOR( i = 0; i < Tc; i++ ) { -#ifdef BASOP_NOGLOB *pt_exc++ = mac_r_sat( L_mac_sat( L_mac_sat( L_mac_sat( L_mac_sat( L_mac_sat( L_mac_sat( L_mac_sat( L_mac_sat( L_mac_sat( L_mult( -174 /*-0.0053f Q15*/, pt1_exc[-5] ), -121 /*-0.0037f Q15*/, pt1_exc[-4] ), @@ -449,20 +409,6 @@ void con_tcx_fx( -459 /*-0.0140f Q15*/, pt1_exc[3] ), -121 /*-0.0037f Q15*/, pt1_exc[4] ), -174 /*-0.0053f Q15*/, pt1_exc[5] ); /*Q_exc*/ -#else - *pt_exc++ = mac_r( L_mac( L_mac( L_mac( L_mac( L_mac( L_mac( L_mac( L_mac( L_mac( - L_mult( -174 /*-0.0053f Q15*/, pt1_exc[-5] ), - -121 /*-0.0037f Q15*/, pt1_exc[-4] ), - -459 /*-0.0140f Q15*/, pt1_exc[-3] ), - 590 /* 0.0180f Q15*/, pt1_exc[-2] ), - 8743 /* 0.2668f Q15*/, pt1_exc[-1] ), - 16355 /* 0.4991f Q15*/, pt1_exc[0] ), - 8743 /* 0.2668f Q15*/, pt1_exc[1] ), - 590 /* 0.0180f Q15*/, pt1_exc[2] ), - -459 /*-0.0140f Q15*/, pt1_exc[3] ), - -121 /*-0.0037f Q15*/, pt1_exc[4] ), - -174 /*-0.0053f Q15*/, pt1_exc[5] ); -#endif move16(); pt1_exc++; } @@ -563,11 +509,7 @@ void con_tcx_fx( } ELSE { -#ifdef BASOP_NOGLOB st->cummulative_damping = shl_sat( mult_r_sat( st->cummulative_damping /*Q15*/, alpha /*Q14*/ ), 1 ) /*Q15*/; -#else - st->cummulative_damping = shl( mult_r( st->cummulative_damping /*Q15*/, alpha /*Q14*/ ), 1 ) /*Q15*/; -#endif move16(); } @@ -595,15 +537,9 @@ void con_tcx_fx( tmp_loop = shr( imult1616( L_frame, 3 ), 1 ); FOR( i = offset; i < tmp_loop; i++ ) { -#ifdef BASOP_NOGLOB exc[i] = mult_r( exc[i], round_fx_sat( gain32 ) ) /*Q1*/; move16(); gain32 = L_sub_sat( gain32, step32 ); /*Q31*/ -#else - exc[i] = mult_r( exc[i], round_fx( gain32 ) ) /*Q1*/; - move16(); - gain32 = L_sub( gain32, step32 ); -#endif } /* update old exc without random part */ @@ -783,7 +719,7 @@ void con_tcx_fx( #else tmp16 = 32767; move16(); - gainSynthDeemph = getLevelSynDeemph_fx( &( tmp16 ), A_local, M, shr( L_frame, 2 ), st->preemph_fac, 1, &gainSynthDeemph_e ); /*Q5*/ + gainSynthDeemph = getLevelSynDeemph_fx( &( tmp16 ), A_local, M, shr( L_frame, 2 ), st->preemph_fac, 1, &gainSynthDeemph_e ); /*Q5*/ #endif IF( st->tcxonly != 0 ) { @@ -821,11 +757,7 @@ void con_tcx_fx( { gain32 = Mpy_32_16_1( gain32, 22938 /*0.7f Q15*/ ); /*Q16*/ } -#ifdef BASOP_NOGLOB /* Critical Overflow */ L_tmp = L_shl_sat( gain32, 1 ); /*Q16*/ -#else - L_tmp = L_shl( gain32, 1 ); -#endif IF( GT_32( L_shl( L_deposit_h( gainCNG ), sub( gainCNG_e, 31 - 16 ) /*Q16*/ ), L_tmp ) ) { gainCNG_e = sub( 15 + 1, norm_l( L_tmp ) ); @@ -872,11 +804,7 @@ void con_tcx_fx( tmp_e = norm_l( L_tmp ); L_tmp = L_shl( L_tmp, tmp_e ); gain_inov_e = add( sub( gain_inov_e, tmp_e ), 31 - 29 ); /*->Q31*/ -#ifdef BASOP_NOGLOB /* Critical Overflow */ gain_inov = round_fx_sat( L_tmp ); /*Q15,gain_inov_e*/ -#else - gain_inov = round_fx( L_tmp ); /*Q15,gain_inov_e*/ -#endif } st->Mode2_lp_gainp = L_shr( L_deposit_h( alpha /*Q14*/ ) /*Q14+16*/, 1 ); /*Q29*/ @@ -925,13 +853,8 @@ void con_tcx_fx( tmp16 = add( L_frame, shr( L_frame, 1 ) ); FOR( i = 0; i < tmp16; i++ ) { -#ifdef BASOP_NOGLOB exc[i] = add_sat( exc[i], shl_sat( noise[i + ( L_FIR_FER2 / 2 )], add( Q_exc, noise_e ) ) ); /*Q1*/ move16(); -#else - exc[i] = add( exc[i], shl( noise[i + ( L_FIR_FER2 / 2 )], add( Q_exc, noise_e ) ) ); /*Q1*/ - move16(); -#endif } } ELSE @@ -978,11 +901,7 @@ void con_tcx_fx( Copy_Scale_sig( buf, mem_syn, M, exp_scale ); /*Q: tmp16*/ -#ifdef BASOP_NOGLOB tmp_deemph = shl_sat( tmp_deemph, Q_syn ); /*Q_syn*/ -#else - tmp_deemph = shl( tmp_deemph, Q_syn ); -#endif st->Q_syn = Q_syn; move16(); @@ -1080,11 +999,7 @@ void con_tcx_fx( lerp( syn, st->hWIDec->old_syn2_fx, L_EXC_MEM, L_frame ); } -#ifdef BASOP_NOGLOB st->bfi_pitch_fx /*Q6*/ = round_fx_sat( L_shl_sat( pitch_buf[( st->nb_subfr - 1 )] /*15Q16*/, 6 /*Q6*/ ) ); -#else - st->bfi_pitch_fx /*Q6*/ = round_fx( L_shl( pitch_buf[sub( st->nb_subfr, 1 )] /*15Q16*/, 6 /*Q6*/ ) ); -#endif move16(); st->bfi_pitch_frame = st->L_frame; move16(); @@ -1108,21 +1023,13 @@ void con_tcx_fx( FOR( i = 0; i < W2; i++ ) { -#ifdef BASOP_NOGLOB hTcxDec->syn_Overl_TDACFB[i] = add_sat( buf[i], buf[( ( W1 - 1 ) - i )] ); /*hTcxDec->Q_syn_Overl_TDACFB*/ -#else - hTcxDec->syn_Overl_TDACFB[i] = add( buf[i], buf[sub( sub( W1, 1 ), i )] ); -#endif move16(); } FOR( i = 0; i < W2; i++ ) { -#ifdef BASOP_NOGLOB hTcxDec->syn_Overl_TDACFB[( W2 + i )] = add_sat( buf[( W2 + i )], buf[( ( ( W1 - 1 ) - W2 ) - i )] ); /*hTcxDec->Q_syn_Overl_TDACFB*/ -#else - hTcxDec->syn_Overl_TDACFB[add( W2, i )] = add( buf[add( W2, i )], buf[sub( sub( sub( W1, 1 ), W2 ), i )] ); -#endif move16(); } @@ -1261,7 +1168,7 @@ void con_tcx_ivas_fx( /* apply pre-emphasis to the signal */ mem = synth[( -( ( ( L_frame / 2 ) + hTcxDec->pit_max_TCX ) + M + M ) - 1 )]; /*Q0*/ move16(); - Q_exc = E_UTIL_f_preemph3_ivas_fx( &( synth[-add( add( shr( L_frame, 1 ), hTcxDec->pit_max_TCX ), 2 * M )] ), st->preemph_fac, add( add( shr( L_frame, 1 ), hTcxDec->pit_max_TCX ), shl( M, 1 ) ), &mem, 1 ); + Q_exc = E_UTIL_f_preemph3_ivas_fx( &( synth[-( ( ( L_frame / 2 ) + hTcxDec->pit_max_TCX ) + 2 * M )] ), st->preemph_fac, add( add( shr( L_frame, 1 ), hTcxDec->pit_max_TCX ), shl( M, 1 ) ), &mem, 1 ); st->Mode2_lp_gainc = L_deposit_l( 0 ); st->Mode2_lp_gainp = get_gain2( synth - shl( L_subfr, 1 ), synth - add( shl( L_subfr, 1 ), Tc ), shl( L_subfr, 1 ) ); @@ -1547,11 +1454,7 @@ void con_tcx_ivas_fx( } ELSE { -#ifdef BASOP_NOGLOB st->cummulative_damping = shl_sat( mult_r_sat( st->cummulative_damping /*Q15*/, alpha /*Q14*/ ), 1 ) /*Q15*/; -#else - st->cummulative_damping = shl( mult_r( st->cummulative_damping /*Q15*/, alpha /*Q14*/ ), 1 ) /*Q15*/; -#endif move16(); } @@ -1579,15 +1482,9 @@ void con_tcx_ivas_fx( tmp_loop = shr( imult1616( L_frame, 3 ), 1 ); FOR( i = offset; i < tmp_loop; i++ ) { -#ifdef BASOP_NOGLOB exc[i] = mult_r( exc[i], round_fx_sat( gain32 ) ) /*Q1*/; move16(); gain32 = L_sub_sat( gain32, step32 ); /*Q31*/ -#else - exc[i] = mult_r( exc[i], round_fx( gain32 ) ) /*Q1*/; - move16(); - gain32 = L_sub( gain32, step32 ); -#endif } /* update old exc without random part */ @@ -1930,13 +1827,8 @@ void con_tcx_ivas_fx( tmp16 = add( L_frame, shr( L_frame, 1 ) ); FOR( i = 0; i < tmp16; i++ ) { -#ifdef BASOP_NOGLOB exc[i] = add_sat( exc[i], shl_sat( noise[i + ( L_FIR_FER2 / 2 )], add( Q_exc, noise_e ) ) ); /*Q1*/ move16(); -#else - exc[i] = add( exc[i], shl( noise[i + ( L_FIR_FER2 / 2 )], add( Q_exc, noise_e ) ) ); /*Q1*/ - move16(); -#endif } } ELSE @@ -1984,11 +1876,7 @@ void con_tcx_ivas_fx( Copy_Scale_sig( buf, mem_syn, M, exp_scale ); /* Q: tmp16 */ -#ifdef BASOP_NOGLOB tmp_deemph = shl_sat( tmp_deemph, Q_syn ); -#else - tmp_deemph = shl( tmp_deemph, Q_syn ); -#endif st->Q_syn = Q_syn; move16(); @@ -2092,11 +1980,7 @@ void con_tcx_ivas_fx( lerp( syn, st->hWIDec->old_syn2_fx, L_EXC_MEM, L_frame ); } -#ifdef BASOP_NOGLOB st->bfi_pitch_fx /*Q6*/ = round_fx_sat( L_shl_sat( pitch_buf[sub( st->nb_subfr, 1 )] /*15Q16*/, 6 /*Q6*/ ) ); -#else - st->bfi_pitch_fx /*Q6*/ = round_fx( L_shl( pitch_buf[sub( st->nb_subfr, 1 )] /*15Q16*/, 6 /*Q6*/ ) ); -#endif move16(); st->bfi_pitch_frame = st->L_frame; move16(); diff --git a/lib_dec/er_scale_syn.c b/lib_dec/er_scale_syn.c deleted file mode 100644 index a45d9a0bdf5a0577866c41abe0db7147f5179e46..0000000000000000000000000000000000000000 --- a/lib_dec/er_scale_syn.c +++ /dev/null @@ -1,49 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include -#include "prot.h" -#include "cnst.h" -#include "wmc_auto.h" - - -/*----------------------------------------------------------------------------------* - * Damping_fact_flt() - * - * Estimate damping factor - *----------------------------------------------------------------------------------*/ diff --git a/lib_dec/er_scale_syn_fx.c b/lib_dec/er_scale_syn_fx.c index 6061ac0992ffde683144b2a39520f16980ee3147..35ad826486d758fbbaa190df3afa1374320fc238 100644 --- a/lib_dec/er_scale_syn_fx.c +++ b/lib_dec/er_scale_syn_fx.c @@ -97,14 +97,10 @@ Word16 Damping_fact_fx( /* o : damping factor move16(); gain32 = Sqrt32( lp_tmp, &s_gainp ); /*Q31-s_gainp*/ -#ifdef BASOP_NOGLOB gain = round_fx_o( L_shl_o( gain32, s_gainp, &Overflow ), &Overflow ); /* Q15*/ -#else - gain = round_fx( L_shl( gain32, s_gainp ) ); /* Q15*/ -#endif - gain = s_min( gain, 32113 /*0.98f Q15*/ ); /*Q15*/ - gain = s_max( gain, 27853 /*0.85f Q15*/ ); /*Q15*/ - alpha = mult_r( alpha, gain ); /*Q14*/ + gain = s_min( gain, 32113 /*0.98f Q15*/ ); /*Q15*/ + gain = s_max( gain, 27853 /*0.85f Q15*/ ); /*Q15*/ + alpha = mult_r( alpha, gain ); /*Q14*/ } ELSE IF( EQ_16( nbLostCmpt, 2 ) ) { diff --git a/lib_dec/er_sync_exc.c b/lib_dec/er_sync_exc.c deleted file mode 100644 index 8b2b54876ffbc5c1d7401614037c840599902f59..0000000000000000000000000000000000000000 --- a/lib_dec/er_sync_exc.c +++ /dev/null @@ -1,43 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include -#include "options.h" -#include -#include "prot.h" -#include "cnst.h" -#include "wmc_auto.h" diff --git a/lib_dec/er_sync_exc_fx.c b/lib_dec/er_sync_exc_fx.c index 19ae2edcccf2d48656a9fd4354652ef664519607..48be80d43cecd12d70b57d6f2d4d8a47c93cbe3a 100644 --- a/lib_dec/er_sync_exc_fx.c +++ b/lib_dec/er_sync_exc_fx.c @@ -52,28 +52,16 @@ static Word16 GetMinimumPosition_fx( move16(); FOR( i = 0; i < cnt; i++ ) { - tmp16 = shr( x[i], tmp_e ); /*Qx*/ -#ifdef BASOP_NOGLOB + tmp16 = shr( x[i], tmp_e ); /*Qx*/ energy = L_msu_sat( energy_old, tmp16, tmp16 ); /*2Qx+1*/ -#else - energy = L_msu( energy_old, tmp16, tmp16 ); -#endif - tmp16 = shr( x[( i + filterLength )], tmp_e ); /*Qx*/ - BASOP_SATURATE_WARNING_OFF_EVS /*Saturation will be handled*/ -#ifdef BASOP_NOGLOB + tmp16 = shr( x[( i + filterLength )], tmp_e ); /*Qx*/ + BASOP_SATURATE_WARNING_OFF_EVS /*Saturation will be handled*/ energy = L_mac_sat( energy, tmp16, tmp16 ); /*2Qx+1*/ -#else - energy = L_mac( energy, tmp16, tmp16 ); -#endif BASOP_SATURATE_WARNING_ON_EVS /*if (energy == MAXVAL_WORD32)*/ - BASOP_SATURATE_WARNING_OFF_EVS /*saturates if energy < 0*/ -#ifdef BASOP_NOGLOB + BASOP_SATURATE_WARNING_OFF_EVS /*saturates if energy < 0*/ tmptest = L_sub_o( energy, MAXVAL_WORD32, &Overflow ); /*Q31*/ -#else - tmptest = L_sub( energy, MAXVAL_WORD32 ); -#endif BASOP_SATURATE_WARNING_ON_EVS IF( tmptest == 0 ) { @@ -307,11 +295,7 @@ void PulseResynchronization_fx( tmp3_e = tmp2_e; move16(); tmp32_a = L_negate( tmp32_a ); -#ifdef BASOP_NOGLOB tmp32_a = L_add( L_shl_o( 1, sub( 31, tmp3_e ), &Overflow ), tmp32_a ); /*Q31,tmp3_e*/ /*tmp32_a= 1.0f-pitchStart*freqStart*/ -#else - tmp32_a = L_add( L_shl( 1, sub( 31, tmp3_e ) ), tmp32_a ); /*Q31,tmp3_e*/ /*tmp32_a= 1.0f-pitchStart*freqStart*/ -#endif tmp2_e = norm_s( nFrameLength ); tmp16_a = shl( nFrameLength, tmp2_e ); /*Q0+tmp2_e*/ tmp32_a = Mpy_32_16_1( tmp32_a /*Q31,tmp3_e*/, tmp16_a /*Q0,-tmp2_e*/ ); /*Q16,tmp3_e-tmp2_e*/ /*tmp32_a= nFrameLength*(1.0f-pitchStart*freqStart)*/ @@ -376,12 +360,8 @@ void PulseResynchronization_fx( fractionalLeft = lshr( extract_l( tmp32_a ), 1 ); /*Q15*/ tmp_e = sub( 15, norm_l( tmp32 ) ); cycleDelta_e = add( cycleDelta_e, tmp_e ); - tmp32 = L_shr( tmp32, sub( tmp_e, 15 ) ); /*Q31 frac, cycleDelta_e*/ -#ifdef BASOP_NOGLOB + tmp32 = L_shr( tmp32, sub( tmp_e, 15 ) ); /*Q31 frac, cycleDelta_e*/ cycleDelta = round_fx_o( tmp32, &Overflow ); /*Q15, cycleDelta_e*/ -#else - cycleDelta = round_fx( tmp32 ); /*Q15, cycleDelta_e*/ -#endif if ( cycleDelta == 0 ) { cycleDelta_e = 0; diff --git a/lib_dec/er_util.c b/lib_dec/er_util.c deleted file mode 100644 index 88c1af13fe655e9dd67bcd92af230f8c869c8bbc..0000000000000000000000000000000000000000 --- a/lib_dec/er_util.c +++ /dev/null @@ -1,43 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include -#include "prot.h" -#include "cnst.h" -#include "stat_com.h" -#include "wmc_auto.h" diff --git a/lib_dec/er_util_fx.c b/lib_dec/er_util_fx.c index 7452e9bf69e7c92528e70eaec8adf7f46574d194..8c94ecf987e1152e94d8c19b63da37c8bdaee5cf 100644 --- a/lib_dec/er_util_fx.c +++ b/lib_dec/er_util_fx.c @@ -53,11 +53,7 @@ void minimumStatistics_fx( BASOP_SATURATE_WARNING_OFF_EVS -#ifdef BASOP_NOGLOB IF( LT_16( shl_o( currentFrameLevel, currentFrameLevel_e, &Overflow ), PLC_MIN_CNG_LEV ) ) -#else - IF( LT_16( shl( currentFrameLevel, currentFrameLevel_e ), PLC_MIN_CNG_LEV ) ) -#endif { BASOP_SATURATE_WARNING_ON_EVS currentFrameLevel = PLC_MIN_CNG_LEV; /*Q15*/ @@ -271,11 +267,7 @@ Word16 getLevelSynDeemph_fx( /*10Q5*/ *Exp = sub( 10, s16 ); /*Set exponent in order to transform returnvalue to Q15*/ move16(); -#ifdef BASOP_NOGLOB return round_fx_sat( levelSynDeemph ); /*Q15*/ -#else - return round_fx( levelSynDeemph ); /*Q15*/ -#endif } /* BASOP version: up to date with rev 7422 */ diff --git a/lib_dec/evs_dec.c b/lib_dec/evs_dec.c deleted file mode 100644 index d441f6ead49ddcb3a6a1ffab0962633db8157cd0..0000000000000000000000000000000000000000 --- a/lib_dec/evs_dec.c +++ /dev/null @@ -1,43 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include -#include "cnst.h" -#include "rom_com.h" -#include "prot.h" -#include "wmc_auto.h" diff --git a/lib_dec/evs_dec_fx.c b/lib_dec/evs_dec_fx.c index 5e027e6526be1198ea66f6415065115823a4768f..f20ff77f30367e0dc15e2f7936f0d46892a4a014 100644 --- a/lib_dec/evs_dec_fx.c +++ b/lib_dec/evs_dec_fx.c @@ -36,11 +36,7 @@ ivas_error evs_dec_fx( Word16 exp, fra; Word16 tmp_buffer_fx[L_FRAME48k]; Word16 tmp16, tmp16_2; -#ifdef IVAS_CODE - Word16 synth_fx[L_FRAME48k]; -#else Word16 synth_fx[L_FRAME48k + HQ_DELTA_MAX * HQ_DELAY_COMP]; -#endif Word16 fb_exc_fx[L_FRAME16k]; Word16 pitch_buf_fx[NB_SUBFR16k] = { 0 }; Word16 Q_fb_exc; @@ -163,20 +159,12 @@ ivas_error evs_dec_fx( /* st_fx->old_out_fx, st_fx->L_frameTCX); */ FOR( i = 0; i < hTcxDec->L_frameTCX; i++ ) { -#ifdef BASOP_NOGLOB hHQ_core->old_out_fx[i] = shl_sat( mult_r( hHQ_core->old_out_fx[i], st_fx->plcInfo.recovery_gain ), 1 ); /*hHQ_core->exp_old_out*/ -#else - hHQ_core->old_out_fx[i] = shl( mult_r( hHQ_core->old_out_fx[i], st_fx->plcInfo.recovery_gain ), 1 ); -#endif move16(); } FOR( i = 0; i < st_fx->L_frame; i++ ) { -#ifdef BASOP_NOGLOB hHQ_core->old_out_LB_fx[i] = shl_sat( mult_r( hHQ_core->old_out_LB_fx[i], st_fx->plcInfo.recovery_gain ), 1 ); /*hHQ_core->exp_old_out*/ -#else - hHQ_core->old_out_LB_fx[i] = shl( mult_r( hHQ_core->old_out_LB_fx[i], st_fx->plcInfo.recovery_gain ), 1 ); -#endif move16(); } /* attenuate PLC buffers, if no aldo window @@ -192,11 +180,7 @@ ivas_error evs_dec_fx( tmp1 = extract_l( L_shr_r( f, s ) ); /*Q14 - s*/ FOR( i = 0; i < st_fx->hTcxCfg->tcx_mdct_window_lengthFB; i++ ) { -#ifdef BASOP_NOGLOB hTcxDec->syn_OverlFB[i] = shl_sat( mult_sat( tmp1, hTcxDec->syn_OverlFB[i] ), add( s, 1 ) ); /*hTcxDec->Q_syn_Overl*/ -#else - hTcxDec->syn_OverlFB[i] = shl( mult( tmp1, hTcxDec->syn_OverlFB[i] ), add( s, 1 ) ); -#endif move16(); } s = norm_l( f ); @@ -204,11 +188,7 @@ ivas_error evs_dec_fx( tmp1 = extract_l( L_shr_r( f, s ) ); /*Q14 - s*/ FOR( i = 0; i < st_fx->hTcxCfg->tcx_mdct_window_length; i++ ) { -#ifdef BASOP_NOGLOB hTcxDec->syn_Overl[i] = shl_sat( mult_sat( tmp1, hTcxDec->syn_Overl[i] ), s ); /*hTcxDec->Q_syn_Overl*/ -#else - hTcxDec->syn_Overl[i] = shl( mult( tmp1, hTcxDec->syn_Overl[i] ), s ); -#endif move16(); } } @@ -349,7 +329,7 @@ ivas_error evs_dec_fx( /*---------------------------------------------------------------------* * Preprocessing (preparing) for ACELP/HQ core switching *---------------------------------------------------------------------*/ - // PMT("core_switching_pre_dec_fx missign args") + IF( ( error = core_switching_pre_dec_fx( st_fx, output_frame ) ) != IVAS_ERR_OK ) { return error; @@ -362,7 +342,6 @@ ivas_error evs_dec_fx( IF( EQ_16( st_fx->core, ACELP_CORE ) ) { /* ACELP core decoder */ - IF( ( error = acelp_core_dec_fx( st_fx, NULL, synth_fx, NULL, bwe_exc_extended_fx, voice_factors_fx, old_syn_12k8_16k_fx, sharpFlag, pitch_buf_fx, &unbits, &sid_bw, NULL, NULL, NULL, 0, EVS_MONO, 0, 0, 1, NULL, 1 ) ) != IVAS_ERR_OK ) { return error; @@ -372,25 +351,16 @@ ivas_error evs_dec_fx( } ELSE { - // PMT("HQ core missing args") - hq_core_dec_fx( st_fx, synth_fx, &Q_synth, output_frame, hq_core_type, core_switching_flag ); Qpostd = Q_synth; move16(); } + /*---------------------------------------------------------------------* * Postprocessing for ACELP/HQ core switching *---------------------------------------------------------------------*/ - if ( ( error = core_switching_post_dec_fx( st_fx, synth_fx, -#ifdef IVAS_CODE_SWITCHING - output, output_mem[], IVAS_FORMAT ivas_format, use_cldfb_for_dft, -#endif - output_frame, core_switching_flag, -#ifdef IVAS_CODE_SWITCHING - sba_dirac_stereo_flag, nchan_out, -#endif - st_fx->last_element_mode, &Qpostd ) ) != IVAS_ERR_OK ) + if ( ( error = core_switching_post_dec_fx( st_fx, synth_fx, output_frame, core_switching_flag, st_fx->last_element_mode, &Qpostd ) ) != IVAS_ERR_OK ) { return error; } @@ -398,7 +368,6 @@ ivas_error evs_dec_fx( * Pre-processing for bandwidth switching *---------------------------------------------------------------------*/ - /// PMT("bw_switching_pre_proc_fx missing args") bw_switching_pre_proc_fx( old_syn_12k8_16k_fx, st_fx ); /*---------------------------------------------------------------------* @@ -414,15 +383,7 @@ ivas_error evs_dec_fx( ELSE IF( EQ_16( st_fx->extl, WB_BWE ) && st_fx->bws_cnt == 0 ) { /* WB BWE decoder */ - hb_synth_fx_exp = wb_bwe_dec_fx( -#ifdef ADD_IVAS_BWE - NULL, -#endif - synth_fx, hb_synth_fx, -#ifdef ADD_IVAS_BWE - 0, -#endif - output_frame, voice_factors_fx, pitch_buf_fx, st_fx, &Qpostd ); /*Q0*/ + hb_synth_fx_exp = wb_bwe_dec_fx( synth_fx, hb_synth_fx, output_frame, voice_factors_fx, pitch_buf_fx, st_fx, &Qpostd ); /*Q0*/ } /*---------------------------------------------------------------------* @@ -465,15 +426,7 @@ ivas_error evs_dec_fx( ( GE_32( st_fx->output_Fs, 32000 ) && EQ_16( st_fx->core, ACELP_CORE ) && GT_16( st_fx->bwidth, NB ) && st_fx->bws_cnt > 0 && !st_fx->ppp_mode_dec && !( EQ_16( st_fx->nelp_mode_dec, 1 ) && EQ_16( st_fx->bfi, 1 ) ) ) ) { /* SWB BWE decoder */ - hb_synth_fx_exp = swb_bwe_dec_fx( -#ifdef ADD_IVAS_BWE - NULL, -#endif - st_fx, synth_fx, hb_synth_fx, -#ifdef ADD_IVAS_BWE - 0, -#endif - output_frame, &Qpostd ); /*Q0*/ + hb_synth_fx_exp = swb_bwe_dec_fx( st_fx, synth_fx, hb_synth_fx, output_frame, &Qpostd ); /*Q0*/ } ELSE IF( EQ_16( st_fx->extl, SWB_BWE_HIGHRATE ) || EQ_16( st_fx->extl, FB_BWE_HIGHRATE ) ) { @@ -504,11 +457,7 @@ ivas_error evs_dec_fx( /*hb_synth[i] *= (i*tmp);*/ hb_synth_fx[i] = mult_r( hb_synth_fx[i], tmp16_2 ); /*hb_synth_fx_exp*/ move16(); -#ifdef BASOP_NOGLOB tmp16_2 = add_o( tmp16_2, tmp16, &Overflow ); -#else - tmp16_2 = add( tmp16_2, tmp16 ); -#endif } } @@ -757,11 +706,7 @@ ivas_error evs_dec_fx( fra = Log2_norm_lc( L_shl( L_tmp, exp ) ); exp = sub( sub( 30, shl( hb_synth_fx_exp, 1 ) ), exp ); L_tmp = Mpy_32_16( exp, fra, LG10 ); -#ifdef BASOP_NOGLOB st_fx->last_shb_ener_fx = round_fx_sat( L_shl_sat( L_tmp, 10 ) ); /*Q8*/ -#else - st_fx->last_shb_ener_fx = round_fx( L_shl( L_tmp, 10 ) ); /*Q8*/ -#endif } } hBWE_TD->prev_hb_synth_fx_exp = hb_synth_fx_exp; @@ -943,7 +888,7 @@ ivas_error evs_dec_fx( IF( ( EQ_16( st_fx->bwidth, SWB ) || EQ_16( st_fx->bwidth, FB ) ) && ( ( EQ_16( st_fx->last_extl, SWB_TBE ) || EQ_16( st_fx->last_extl, FB_TBE ) ) && EQ_16( st_fx->last_codec_mode, MODE2 ) ) ) { - GenTransition_fx( hBWE_TD->syn_overlap_fx, hBWE_TD->old_tbe_synth_fx, 2 * NS2SA( st_fx->output_Fs, DELAY_BWE_TOTAL_NS ), hb_synth_fx, + GenTransition_fx( hBWE_TD->syn_overlap_fx, hBWE_TD->old_tbe_synth_fx, shl( NS2SA_FX2( st_fx->output_Fs, DELAY_BWE_TOTAL_NS ), 1 ), hb_synth_fx, hBWE_TD->genSHBsynth_Hilbert_Mem_fx, hBWE_TD->genSHBsynth_state_lsyn_filt_shb_local_fx, hBWE_TD->mem_resamp_HB_32k_fx, &( hBWE_TD->syn_dm_phase ), st_fx->output_Fs, hBWE_TD->int_3_over_2_tbemem_dec_fx, st_fx->rf_flag, st_fx->total_brate ); @@ -953,7 +898,7 @@ ivas_error evs_dec_fx( } ELSE IF( EQ_16( st_fx->bwidth, WB ) && EQ_16( st_fx->last_extl, WB_TBE ) ) { - GenTransition_WB_fx( hBWE_TD->syn_overlap_fx, hBWE_TD->old_tbe_synth_fx, st_fx->prev_Qx, 2 * NS2SA( st_fx->output_Fs, DELAY_BWE_TOTAL_NS ), hb_synth_fx, + GenTransition_WB_fx( hBWE_TD->syn_overlap_fx, hBWE_TD->old_tbe_synth_fx, st_fx->prev_Qx, shl( NS2SA_FX2( st_fx->output_Fs, DELAY_BWE_TOTAL_NS ), 1 ), hb_synth_fx, hBWE_TD->state_lsyn_filt_shb_fx, hBWE_TD->state_lsyn_filt_dwn_shb_fx, st_fx->output_Fs, hBWE_TD->mem_resamp_HB_fx ); hb_synth_fx_exp = st_fx->prev_Qx; @@ -1044,11 +989,7 @@ ivas_error evs_dec_fx( { FOR( i = 0; i < st_fx->L_frame / 2; i++ ) { -#ifdef BASOP_NOGLOB output_sp[i] = add_sat( output_sp[i], st_fx->hFdCngDec->hFdCngCom->olapBufferSynth2[i + 5 * st_fx->L_frame / 4] ); /*Q0*/ -#else - output_sp[i] = add( output_sp[i], st_fx->hFdCngDec->hFdCngCom->olapBufferSynth2[i + 5 * st_fx->L_frame / 4] ); -#endif move16(); } } @@ -1218,11 +1159,7 @@ ivas_error evs_dec_fx( FOR( i = 0; i < tmps; i++ ) { -#ifdef BASOP_NOGLOB output_sp[i + delay_comp] = msu_r_sat( L_mult_sat( output_sp[i + delay_comp], alpha ), shr( hHQ_core->old_out_fx[i + nz], timeIn_e ), add( alpha, -32768 ) ); /*timeIn_e*/ -#else - output_sp[i + delay_comp] = msu_r( L_mult( output_sp[i + delay_comp], alpha ), shr( hHQ_core->old_out_fx[i + nz], timeIn_e ), add( alpha, -32768 ) ); -#endif move16(); alpha = add( alpha, step ); } @@ -1345,11 +1282,7 @@ ivas_error evs_dec_fx( FOR( i = 0; i < tmps; i++ ) { -#ifdef BASOP_NOGLOB output_sp[i + tmps] = msu_r_sat( L_mult_sat( shr( pcmbufFB[i], timeIn_e ), alpha ), output_sp[i + tmps], add( alpha, -32768 ) ); /*Q0*/ -#else - output_sp[i + tmps] = msu_r( L_mult( shr( pcmbufFB[i], timeIn_e ), alpha ), output_sp[i + tmps], add( alpha, -32768 ) ); -#endif move16(); alpha = add( alpha, step ); } @@ -1363,12 +1296,12 @@ ivas_error evs_dec_fx( { IF( EQ_32( st_fx->output_Fs, 8000 ) ) { - Copy( hTcxDec->FBTCXdelayBuf, st_fx->delay_buf_out_fx, NS2SA( st_fx->output_Fs, DELAY_CLDFB_NS ) ); /*st_fx->q_prev_synth_buffer_fx*/ + Copy( hTcxDec->FBTCXdelayBuf, st_fx->delay_buf_out_fx, NS2SA_FX2( st_fx->output_Fs, DELAY_CLDFB_NS ) ); /*st_fx->q_prev_synth_buffer_fx*/ } ELSE { - Copy( hTcxDec->FBTCXdelayBuf, st_fx->prev_synth_buffer_fx, NS2SA( st_fx->output_Fs, DELAY_BWE_TOTAL_NS - DELAY_CLDFB_NS ) ); /*st_fx->Qprev_synth_buffer_fx*/ - Copy( hTcxDec->FBTCXdelayBuf + NS2SA( st_fx->output_Fs, DELAY_BWE_TOTAL_NS - DELAY_CLDFB_NS ), st_fx->delay_buf_out_fx, NS2SA( st_fx->output_Fs, DELAY_CLDFB_NS ) ); /*Q0*/ + Copy( hTcxDec->FBTCXdelayBuf, st_fx->prev_synth_buffer_fx, NS2SA_FX2( st_fx->output_Fs, DELAY_BWE_TOTAL_NS - DELAY_CLDFB_NS ) ); /*st_fx->Qprev_synth_buffer_fx*/ + Copy( hTcxDec->FBTCXdelayBuf + NS2SA_FX2( st_fx->output_Fs, DELAY_BWE_TOTAL_NS - DELAY_CLDFB_NS ), st_fx->delay_buf_out_fx, NS2SA_FX2( st_fx->output_Fs, DELAY_CLDFB_NS ) ); /*Q0*/ } } } @@ -1387,17 +1320,9 @@ ivas_error evs_dec_fx( FOR( i = delta; i < tmps; i++ ) { -#ifdef BASOP_NOGLOB output_sp[i] = msu_r_sat( L_mult( output_sp[i], alpha ), shr_sat( hTcxDec->FBTCXdelayBuf[i], timeIn_e ), add( alpha, -32768 ) ); /*Q0*/ -#else - output_sp[i] = msu_r( L_mult( output_sp[i], alpha ), shr( hTcxDec->FBTCXdelayBuf[i], timeIn_e ), add( alpha, -32768 ) ); -#endif move16(); -#ifdef BASOP_NOGLOB alpha = add_sat( alpha, step ); -#else - alpha = add( alpha, step ); -#endif } } @@ -1406,7 +1331,7 @@ ivas_error evs_dec_fx( Scale_sig( output_sp, output_frame, timeIn_e ); /*timeIn_e*/ - tcx_ltp_post( st_fx, hTcxLtpDec, st_fx->core, output_frame /*hTcxDec->L_frameTCX*/, NS2SA_FX2( st_fx->output_Fs, ACELP_LOOK_NS ) + tmps, + tcx_ltp_post( st_fx, hTcxLtpDec, st_fx->core, output_frame /*hTcxDec->L_frameTCX*/, add( NS2SA_FX2( st_fx->output_Fs, ACELP_LOOK_NS ), tmps ), output_sp, hTcxDec->FBTCXdelayBuf ); Copy( output_sp, synth_fx, output_frame ); /*timeIn_e*/ @@ -1416,7 +1341,7 @@ ivas_error evs_dec_fx( /*----------------------------------------------------------------* * Save synthesis for HQ FEC *----------------------------------------------------------------*/ - // PMT("The code below could be move to save_synthesis_hq_fec") + post_hq_delay = NS2SA_FX2( st_fx->output_Fs, POST_HQ_DELAY_NS ); IF( EQ_16( st_fx->codec_mode, MODE1 ) ) { @@ -1441,8 +1366,8 @@ ivas_error evs_dec_fx( ELSE { - Copy_Scale_sig( synth_fx + output_frame, hTcxDec->old_synthFB_fx + sub( shl( output_frame, 1 ), NS2SA_FX2( st_fx->output_Fs, DELAY_BWE_TOTAL_NS ) ), NS2SA_FX2( st_fx->output_Fs, DELAY_CLDFB_NS ), negate( Qpostd ) ); /*Q0*/ - Copy_Scale_sig( hHQ_core->old_out_fx + NS2SA_FX2( st_fx->output_Fs, N_ZERO_MDCT_NS ), hTcxDec->old_synthFB_fx + shl( output_frame, 1 ) - NS2SA_FX2( st_fx->output_Fs, DELAY_BWE_TOTAL_NS - DELAY_CLDFB_NS ), NS2SA_FX2( st_fx->output_Fs, PH_ECU_LOOKAHEAD_NS ), negate( hHQ_core->Q_old_wtda ) ); /*Q0*/ + Copy_Scale_sig( synth_fx + output_frame, hTcxDec->old_synthFB_fx + sub( shl( output_frame, 1 ), NS2SA_FX2( st_fx->output_Fs, DELAY_BWE_TOTAL_NS ) ), NS2SA_FX2( st_fx->output_Fs, DELAY_CLDFB_NS ), negate( Qpostd ) ); /*Q0*/ + Copy_Scale_sig( hHQ_core->old_out_fx + NS2SA_FX2( st_fx->output_Fs, N_ZERO_MDCT_NS ), hTcxDec->old_synthFB_fx + sub( shl( output_frame, 1 ), NS2SA_FX2( st_fx->output_Fs, DELAY_BWE_TOTAL_NS - DELAY_CLDFB_NS ) ), NS2SA_FX2( st_fx->output_Fs, PH_ECU_LOOKAHEAD_NS ), negate( hHQ_core->Q_old_wtda ) ); /*Q0*/ } } } diff --git a/lib_dec/fd_cng_dec.c b/lib_dec/fd_cng_dec.c deleted file mode 100644 index ea716c8670066173ec98d3213e4fdada2bf2d310..0000000000000000000000000000000000000000 --- a/lib_dec/fd_cng_dec.c +++ /dev/null @@ -1,1386 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include -#include "options.h" -#include -#include "prot.h" -#include "ivas_prot.h" -#include "rom_com.h" -#include "wmc_auto.h" -#include "ivas_prot.h" -#include "ivas_rom_dec.h" -#include "ivas_rom_com_fx.h" -#include "prot_fx.h" -#include "ivas_prot_fx.h" -#include "basop_util.h" -#include "rom_basop_util.h" - -/*------------------------------------------------------------------- - * Local constants - *-------------------------------------------------------------------*/ - -#define DELTA_MASKING_NOISE_Q15 0 -#define CNA_ACT_DN_LARGE_PARTITION 50 /* index of the first larger partition */ -#define FIRST_CNA_NOISE_UPD_FRAMES 5 /* minimum number of CN initialization frames */ -#define LOG_10_BASE_2 1783446566 /* Q29 */ -#define GAIN_Q_OFFSET_IVAS_FX 45 -#define LOG_10_BASE_2_BY_10_Q31 713378606 -#define TWO_BY_THREE_Q31 1431655765 -#define ONE_BY_FRAMES_PER_SEC_Q15 656 -#define NB_LAST_BAND_SCALE_Q31 1717986918 -#define SWB_13k2_LAST_BAND_SCALE_Q31 1717986918 - -/*------------------------------------------------------------------- - * Local fucntions declarations - *-------------------------------------------------------------------*/ - -/*------------------------------------------------------------------- - * createFdCngDec() - * - * Create an instance of type FD_CNG - *-------------------------------------------------------------------*/ - - -/*------------------------------------------------------------------- - * initFdCngDec() - * - * Initialize an instance of type FD_CNG - *-------------------------------------------------------------------*/ -void configureFdCngDec_ivas_fx( - HANDLE_FD_CNG_DEC hFdCngDec, /* i/o: Contains the variables related to the FD-based CNG process */ - const Word16 bwidth, /*Q0*/ - const Word32 total_brate, /*Q0*/ - const Word16 L_frame, /*Q0*/ - const Word16 last_L_frame, /*Q0*/ - const Word16 element_mode /*Q0*/ ) -{ - Word16 j, stopBandFR; - HANDLE_FD_CNG_COM hsCom = hFdCngDec->hFdCngCom; - - hsCom->CngBandwidth = bwidth; /*Q0*/ - move16(); - if ( EQ_16( hsCom->CngBandwidth, FB ) ) - { - hsCom->CngBandwidth = SWB; - move16(); - } - test(); - IF( NE_32( total_brate, FRAME_NO_DATA ) && NE_32( total_brate, SID_2k40 ) ) - { - hsCom->CngBitrate = total_brate; /*Q0*/ - move32(); - } - ELSE IF( EQ_32( hsCom->CngBitrate, -1 ) ) - { - /* set minimum active CBR bitrate IF CngBitrate is uninitialized */ - IF( element_mode > EVS_MONO ) - { - hsCom->CngBitrate = IVAS_13k2; - move32(); - } - ELSE - { - hsCom->CngBitrate = ACELP_7k20; - move32(); - } - } - - /* FD-CNG config for MDCT-Stereo is always the same (since for > 48 kbps only) */ - /* This may need adjustment in the future IF 2TC DTX for some mode uses MDCT-Stereo DTX for lower bitrates too */ - if ( EQ_16( element_mode, IVAS_CPE_MDCT ) ) - { - hsCom->CngBitrate = IVAS_48k; - move32(); - } - hsCom->numSlots = 16; - move32(); - - /* NB configuration */ - IF( EQ_16( bwidth, NB ) ) - { - hsCom->FdCngSetup = FdCngSetup_nb; - hsCom->numCoreBands = 16; - move16(); - hsCom->regularStopBand = 16; - move16(); - } - - /* WB configuration */ - ELSE IF( EQ_16( bwidth, WB ) ) - { - /* FFT 6.4kHz, no CLDFB */ - test(); - test(); - IF( LE_32( hsCom->CngBitrate, ACELP_8k00 ) && EQ_16( L_frame, L_FRAME ) ) - { - hsCom->FdCngSetup = FdCngSetup_wb1; - hsCom->numCoreBands = 16; - move16(); - hsCom->regularStopBand = 16; - move16(); - } - /* FFT 6.4kHz, CLDFB 8.0kHz */ - ELSE IF( LE_32( hsCom->CngBitrate, ACELP_13k20 ) || EQ_16( L_frame, L_FRAME ) ) - { - hsCom->FdCngSetup = FdCngSetup_wb2; - hsCom->numCoreBands = 16; - move16(); - hsCom->regularStopBand = 20; - move16(); - IF( EQ_16( L_frame, L_FRAME16k ) ) - { - hsCom->FdCngSetup = FdCngSetup_wb2; - hsCom->numCoreBands = 20; - move16(); - hsCom->regularStopBand = 20; - move16(); - hsCom->FdCngSetup.fftlen = 640; - move16(); - hsCom->FdCngSetup.stopFFTbin = 256; - move16(); - } - } - /* FFT 8.0kHz, no CLDFB */ - ELSE - { - hsCom->FdCngSetup = FdCngSetup_wb3; - hsCom->numCoreBands = 20; - move16(); - hsCom->regularStopBand = 20; - move16(); - } - } - - /* SWB/FB configuration */ - ELSE - { - /* FFT 6.4kHz, CLDFB 14kHz */ - IF( EQ_16( L_frame, L_FRAME ) ) - { - hsCom->FdCngSetup = FdCngSetup_swb1; - hsCom->numCoreBands = 16; - move16(); - hsCom->regularStopBand = 35; - move16(); - } - /* FFT 8.0kHz, CLDFB 16kHz */ - ELSE - { - hsCom->FdCngSetup = FdCngSetup_swb2; - hsCom->numCoreBands = 20; - move16(); - hsCom->regularStopBand = 40; - move16(); - test(); - if ( EQ_16( last_L_frame, L_FRAME ) && EQ_16( element_mode, IVAS_CPE_DFT ) ) - { - hsCom->regularStopBand = 35; - move16(); - } - } - } - - - hsCom->fftlen = hsCom->FdCngSetup.fftlen; - move16(); - hsCom->stopFFTbin = hsCom->FdCngSetup.stopFFTbin; - move16(); - - /* Configure the SID quantizer and the Comfort Noise Generator */ - - hsCom->startBand = 2; - move16(); - hsCom->stopBand = add( hsCom->FdCngSetup.sidPartitions[( hsCom->FdCngSetup.numPartitions - 1 )], 1 ); /*Q0*/ - initPartitions( hsCom->FdCngSetup.sidPartitions, hsCom->FdCngSetup.numPartitions, hsCom->startBand, hsCom->stopBand, hsCom->part, &hsCom->npart, hsCom->midband, hsCom->psize, hsCom->psize_norm, &hsCom->psize_norm_exp, hsCom->psize_inv, 0 ); - - IF( EQ_16( hsCom->stopFFTbin, 160 ) ) - { - hsCom->nFFTpart = 17; - move16(); - } - ELSE IF( EQ_16( hsCom->stopFFTbin, 256 ) ) - { - hsCom->nFFTpart = 20; - move16(); - } - ELSE - { - hsCom->nFFTpart = 21; - move16(); - } - hsCom->nCLDFBpart = sub( hsCom->npart, hsCom->nFFTpart ); /*Q0*/ - move16(); - FOR( j = 0; j < hsCom->nCLDFBpart; j++ ) - { - hsCom->CLDFBpart[j] = sub( hsCom->part[( j + hsCom->nFFTpart )], sub( hsCom->stopFFTbin, hsCom->startBand ) ); /*Q0*/ - move16(); - hsCom->CLDFBpsize_inv[j] = hsCom->psize_inv[( j + hsCom->nFFTpart )]; - move16(); - } - - stopBandFR = 40; //(Word16)floor(1000.f /*Hz*/ / 25.f /*Hz/Bin*/); - move16(); - if ( GT_16( stopBandFR, hsCom->stopFFTbin ) ) - { - stopBandFR = hsCom->stopFFTbin; /*Q0*/ - move16(); - } - - initPartitions( hsCom->FdCngSetup.shapingPartitions, hsCom->FdCngSetup.numShapingPartitions, hsCom->startBand, hsCom->stopFFTbin, hFdCngDec->part_shaping, &hFdCngDec->npart_shaping, hFdCngDec->midband_shaping, hFdCngDec->psize_shaping, hFdCngDec->psize_shaping_norm, &hFdCngDec->psize_shaping_norm_exp, hFdCngDec->psize_inv_shaping, stopBandFR ); - - hFdCngDec->nFFTpart_shaping = hFdCngDec->npart_shaping; /*Q0*/ - move16(); - - BASOP_getTables( &hsCom->olapWinAna, NULL, NULL, shr( hsCom->fftlen, 1 ) ); - BASOP_getTables( &hsCom->olapWinSyn, NULL, NULL, shr( hsCom->fftlen, 2 ) ); - - SWITCH( hsCom->fftlen ) - { - case 512: - hsCom->olapWinAna_fx = olapWinAna512_fx; /*Q30*/ - hsCom->fftSineTab_fx = NULL; - hsCom->olapWinSyn_fx = olapWinSyn256_fx; /*Q15*/ - hsCom->fftlenShift = 8; - move16(); - hsCom->fftlenFac = 32767 /*1.0 Q15*/; - move16(); - BREAK; - case 640: - hsCom->olapWinAna_fx = olapWinAna640_fx; /*Q30*/ - hsCom->fftSineTab_fx = fftSineTab640_fx; /*Q15*/ - hsCom->olapWinSyn_fx = olapWinSyn320_fx; /*Q15*/ - hsCom->fftlenShift = 9; - move16(); - hsCom->fftlenFac = 20480 /*0.625 Q15*/; - move16(); - BREAK; - default: - assert( !"Unsupported FFT length for FD-based CNG" ); - BREAK; - } - BASOP_getTables( &hsCom->olapWinAna, NULL, NULL, shr( hsCom->fftlen, 1 ) ); - BASOP_getTables( &hsCom->olapWinSyn, NULL, NULL, shr( hsCom->fftlen, 2 ) ); - hsCom->frameSize = shr( hsCom->fftlen, 1 ); - - return; -} - -/*------------------------------------------------------------------- - * deleteFdCngDec() - * - * Delete the instance of type FD_CNG - *-------------------------------------------------------------------*/ - - -/*------------------------------------------------------------------- - * ApplyFdCng() - * - * Apply the CLDFB-based CNG at the decoder - *-------------------------------------------------------------------*/ - -/*------------------------------------------------------------------- - * FdCng_decodeSID() - * - * Decode the FD-CNG bitstream - *-------------------------------------------------------------------*/ - - -/*------------------------------------------------------------------- - * FdCng_decodeSID_ivas_fx() - * - * Decode the FD-CNG bitstream - *-------------------------------------------------------------------*/ - -void FdCng_decodeSID_ivas_fx( - Decoder_State *st /* i/o: decoder state structure */ -) -{ - Word16 N; - Word32 *sidNoiseEst; - Word32 gain; - Word16 i, index; - Word32 v[32]; - Word16 indices[32]; - HANDLE_FD_CNG_COM hFdCngCom; - Word32 *invTrfMatrix_fx; - Word32 tmpRAM_fx[FDCNG_VQ_MAX_LEN][FDCNG_VQ_DCT_MAXTRUNC]; - Word16 tmp16; - - IF( st->element_mode == EVS_MONO ) - { - tmp16 = GAIN_Q_OFFSET_EVS_FX_Q0; - move16(); - } - ELSE - { - tmp16 = GAIN_Q_OFFSET_IVAS_FX_Q0; - move16(); - } - - const Word16 gain_q_offset = tmp16; /* Q0 */ - move16(); - - invTrfMatrix_fx = (Word32 *) tmpRAM_fx; /*Q31*/ - - hFdCngCom = ( st->hFdCngDec )->hFdCngCom; - - sidNoiseEst = hFdCngCom->sidNoiseEst; /*Q16*/ - - N = hFdCngCom->npart; /*Q0*/ - move16(); - gain = 0; - move32(); - hFdCngCom->sid_frame_counter = add( hFdCngCom->sid_frame_counter, 1 ); - move16(); - - /* Read bitstream */ - FOR( i = 0; i < FD_CNG_stages_37bits; i++ ) - { - indices[i] = get_next_indice_fx( st, bits_37bits[i] ); /*Q0*/ - move16(); - } - - index = get_next_indice_fx( st, 7 ); - - /* MSVQ decoder */ - - IF( st->element_mode != EVS_MONO ) - { - create_IDCT_N_Matrix_fx( invTrfMatrix_fx, FDCNG_VQ_MAX_LEN, FDCNG_VQ_DCT_MAXTRUNC, FDCNG_VQ_MAX_LEN * FDCNG_VQ_DCT_MAXTRUNC ); - msvq_dec_fx( ivas_cdk_37bits_fx, NULL, NULL, FD_CNG_stages_37bits, N, FD_CNG_maxN_37bits, indices, 1, invTrfMatrix_fx, v, NULL, 7 ); - } - ELSE - { /* Legacy EVS_MONO MSVQ tables */ - msvq_dec_fx( cdk_37bits, NULL, NULL, FD_CNG_stages_37bits, N, FD_CNG_maxN_37bits, indices, 0, NULL, v, NULL, 7 ); - } - - - /* Decode gain */ - // gain = ((float)index - gain_q_offset) / 1.5f; - gain = L_mult0( sub( index, gain_q_offset ), 21845 ); // Q15 - - /* Apply gain and undo log */ - Word16 res_exp[NPART]; - Word16 max_res_exp = 0; - move16(); - FOR( i = 0; i < N; i++ ) - { - sidNoiseEst[i] = BASOP_util_Pow2( Mpy_32_32( L_add( v[i], gain ), LOG_10_BASE_2_BY_10_Q31 ), Q16, &res_exp[i] ); /*Q31 - res_exp[i]*/ - move32(); - if ( LT_16( max_res_exp, res_exp[i] ) ) - { - max_res_exp = res_exp[i]; - move16(); - } - } - - FOR( i = 0; i < N; i++ ) - { - sidNoiseEst[i] = L_shr( sidNoiseEst[i], sub( max_res_exp, res_exp[i] ) ); /*Q31 - max_res_exp*/ - move32(); - } - - hFdCngCom->sidNoiseEstExp = max_res_exp; - move16(); - - /* NB last band energy compensation */ - - IF( hFdCngCom->CngBandwidth == NB ) - { - sidNoiseEst[( N - 1 )] = Mpy_32_16_1( sidNoiseEst[( N - 1 )], NB_LAST_BAND_SCALE ); /*Q31 - max_res_exp*/ - move32(); - } - - test(); - IF( EQ_16( hFdCngCom->CngBandwidth, SWB ) && LE_32( hFdCngCom->CngBitrate, ACELP_13k20 ) ) - { - sidNoiseEst[( N - 1 )] = Mpy_32_16_1( sidNoiseEst[( N - 1 )], SWB_13k2_LAST_BAND_SCALE ); /*Q31 - max_res_exp*/ - move32(); - } - - scalebands( sidNoiseEst, hFdCngCom->part, hFdCngCom->npart, hFdCngCom->midband, hFdCngCom->nFFTpart, sub( hFdCngCom->stopBand, hFdCngCom->startBand ), hFdCngCom->cngNoiseLevel, 1 ); - hFdCngCom->cngNoiseLevelExp = hFdCngCom->sidNoiseEstExp; - move16(); - - lpc_from_spectrum( hFdCngCom, hFdCngCom->startBand, hFdCngCom->stopFFTbin, st->preemph_fac ); - - return; -} - -/*------------------------------------------------------------------- - * noisy_speech_detection() - * - * - *-------------------------------------------------------------------*/ - -/*------------------------------------------------------------------- - * generate_comfort_noise_dec() - * - * Generate the comfort noise based on the target noise level - *-------------------------------------------------------------------*/ - -/*------------------------------------------------------------------- - * generate_masking_noise() - * - * Generate additional comfort noise (kind of noise filling) - *-------------------------------------------------------------------*/ - -/*------------------------------------------------------------------- - * generate_masking_noise_ivas_fx() - * - * Generate additional comfort noise (kind of noise filling) - *-------------------------------------------------------------------*/ - -void generate_masking_noise_ivas_fx( - Word32 *timeDomainBuffer, /* i/o: time-domain signal Q31 - *exp_out*/ - Word16 *exp_out, /* o : time-domain signal exp */ - HANDLE_FD_CNG_COM hFdCngCom, /* i/o: FD_CNG structure containing all buffers and variables */ - const Word16 length, /* i : frame size Q0*/ - const Word16 core, /* i : core Q0*/ - const Word16 return_noise, /* i : noise is returned instead of added Q0*/ - const Word16 secondary, /* i : flag to indicate secondary noise generation Q0*/ - const Word16 element_mode, /* i : element mode Q0*/ - STEREO_CNG_DEC_HANDLE hStereoCng, /* i : stereo CNG handle */ - const Word16 nchan_out /* i : number of output channels Q0*/ -) -{ - Word32 *cngNoiseLevel_fx = hFdCngCom->cngNoiseLevel; - Word32 *ptr_level_fx = cngNoiseLevel_fx; - Word32 *fftBuffer_fx = hFdCngCom->fftBuffer; - Word16 i; - Word32 maskingNoise_fx[L_FRAME16k]; - Word32 *ptr_r_fx; - Word32 *ptr_i_fx; - Word16 startBand; - Word16 *seed = &( hFdCngCom->seed ); - Word32 scale_fx; - Word16 shift; - scale_fx = 0x40000000; // 1.0 in Q30 - move32(); - startBand = hFdCngCom->startBand; /*Q0*/ - move16(); - shift = getScaleFactor32( hFdCngCom->cngNoiseLevel, FFTCLDFBLEN ); - if ( LT_16( sub( hFdCngCom->cngNoiseLevelExp, shift ), 4 ) ) - { - shift = sub( hFdCngCom->cngNoiseLevelExp, 4 ); /*Q0*/ - } - scale_sig32( hFdCngCom->cngNoiseLevel, FFTCLDFBLEN, shift ); /*hFdCngCom->cngNoiseLevelExp*/ - hFdCngCom->cngNoiseLevelExp = sub( hFdCngCom->cngNoiseLevelExp, shift ); - move16(); - - /* skip noise generating if level is very low, to avoid problems with possibly running into denormals */ - *exp_out = Q15; - move16(); - IF( GT_16( hFdCngCom->likelihood_noisy_speech, DELTA_MASKING_NOISE_Q15 ) ) - { - IF( NE_16( core, AMR_WB_CORE ) ) - { - /* Compute additional CN level */ - FOR( i = 0; i < SIZE_SCALE_TABLE_CN; i++ ) - { - test(); - test(); - if ( EQ_16( hFdCngCom->CngBandwidth, scaleTable_cn_only[i].bwmode ) && - GE_32( hFdCngCom->CngBitrate, scaleTable_cn_only[i].bitrateFrom ) && - LT_32( hFdCngCom->CngBitrate, scaleTable_cn_only[i].bitrateTo ) ) - { - BREAK; - } - } - - scale_fx = L_deposit_h( scaleTable_cn_only[i].scale_ivas ); /* Q30 */ - } - ELSE - { - /* Compute additional CN level */ - FOR( i = 0; i < SIZE_SCALE_TABLE_CN_AMRWB; i++ ) - { - if ( GE_32( hFdCngCom->CngBitrate, scaleTable_cn_only_amrwbio[i][0] ) ) - { - BREAK; - } - } - - IF( LT_16( i, SIZE_SCALE_TABLE_CN_AMRWB ) ) - { - scale_fx = L_deposit_h( scaleTable_cn_only_amrwbio[i][1] ); /* Q30 */ - } - ELSE - { - scale_fx = 0; - move32(); - } - } - - /* Exclude clean speech */ - scale_fx = Mpy_32_16_1( scale_fx, hFdCngCom->likelihood_noisy_speech ); // Q30 - - /* Generate Gaussian random noise in real and imaginary parts of the FFT bins - Amplitudes are adjusted to the estimated noise level cngNoiseLevel_flt in each bin */ - IF( startBand == 0 ) - { - rand_gauss_fx( &fftBuffer_fx[0], seed, *exp_out ); // Q15 - ptr_r_fx = fftBuffer_fx + 2; /*Q31 - hFdCngCom->fftBuffer_exp*/ - Word16 exp1; - exp1 = add( hFdCngCom->cngNoiseLevelExp, 1 ); - Word32 mpy1; - mpy1 = Sqrt32( Mpy_32_32( scale_fx, *ptr_level_fx ), &exp1 ); /*Q31 - exp1*/ - mpy1 = L_shl( mpy1, exp1 ); // Q31 - fftBuffer_fx[0] = Mpy_32_32( fftBuffer_fx[0], mpy1 ); /* DC component in FFT */ // Q = Q15 - ptr_level_fx++; - } - ELSE - { - fftBuffer_fx[0] = 0; - move32(); - set32_fx( fftBuffer_fx + 2, 0, shl( sub( startBand, 1 ), 1 ) ); - ptr_r_fx = fftBuffer_fx + shl( startBand, 1 ); /*Q31 - hFdCngCom->fftBuffer_exp*/ - } - ptr_i_fx = ptr_r_fx + 1; - FOR( ; ptr_level_fx < cngNoiseLevel_fx + hFdCngCom->stopFFTbin - startBand; ptr_level_fx++ ) - { - /* Real part in FFT bins */ - rand_gauss_fx( ptr_r_fx, seed, *exp_out ); // Q15 - Word16 exp2; - exp2 = add( hFdCngCom->cngNoiseLevelExp, 1 ); - Word32 mpy2; - mpy2 = Sqrt32( L_shr( Mpy_32_32( scale_fx, *ptr_level_fx ), 1 ), &exp2 ); /*Q31 - exp2*/ - ( *ptr_r_fx ) = L_shl( Mpy_32_32( *ptr_r_fx, mpy2 ), exp2 ); // Q = Q15 - move32(); - ptr_r_fx += 2; - - /* Imaginary part in FFT bins */ - rand_gauss_fx( ptr_i_fx, seed, *exp_out ); // Q15 - ( *ptr_i_fx ) = L_shl( Mpy_32_32( *ptr_i_fx, mpy2 ), exp2 ); // Q = Q15 - ptr_i_fx += 2; - } - - /* Remaining FFT bins are set to zero */ - set32_fx( fftBuffer_fx + shl( hFdCngCom->stopFFTbin, 1 ), 0, sub( hFdCngCom->fftlen, shl( hFdCngCom->stopFFTbin, 1 ) ) ); - /* Nyquist frequency is discarded */ - fftBuffer_fx[1] = 0; - move32(); - } - ELSE - { - /* very low level case - update random seeds and reset FFT buffer; don't fully skip SynthesisSTFT_flt(), because of the buffer updates done there... */ - generate_masking_noise_update_seed_fx( hFdCngCom ); - - set32_fx( fftBuffer_fx, 0, hFdCngCom->fftlen ); - } - - /* Perform STFT synthesis */ - IF( secondary ) - { - SynthesisSTFT_fx( fftBuffer_fx, maskingNoise_fx, hStereoCng->olapBufferSynth22_32fx, hFdCngCom->olapWinSyn_fx, 0, hFdCngCom, element_mode, nchan_out ); - } - ELSE - { - SynthesisSTFT_fx( fftBuffer_fx, maskingNoise_fx, hFdCngCom->olapBufferSynth2_fx, hFdCngCom->olapWinSyn_fx, 0, hFdCngCom, element_mode, nchan_out ); - } - *exp_out = sub( *exp_out, Q9 ); - move16(); - - /* Add some comfort noise on top of decoded signal */ - IF( return_noise ) - { - Copy32( maskingNoise_fx, timeDomainBuffer, s_min( hFdCngCom->frameSize, length ) ); /*Q31 - *exp_out*/ - } - ELSE - { - v_add_fixed( maskingNoise_fx, timeDomainBuffer, timeDomainBuffer, s_min( hFdCngCom->frameSize, length ), 0 ); /*Q31 - *exp_out*/ - } - - return; -} - -/*------------------------------------------------------------------- - * generate_masking_noise_update_seed() - * - * Update seed for scenarios where generate_masking_noise() is - * not called based on signal statistics - *-------------------------------------------------------------------*/ - - -/*------------------------------------------------------------------- - * generate_stereo_masking_noise_fx() - * - * Generate additional comfort noise (kind of noise filling) - *-------------------------------------------------------------------*/ - -void generate_stereo_masking_noise_fx( - Word16 *syn, /* i/o: time-domain signal Q_syn*/ - Word16 Q_syn, - Decoder_State *st, /* i/o: decoder state structure */ - STEREO_TD_DEC_DATA_HANDLE hStereoTD, /* i : TD stereo structure */ - const Word16 flag_sec_CNA, /* i : CNA flag for secondary channel Q0*/ - const Word16 fadeOut, /* i : only fade out of previous state Q0*/ - STEREO_CNG_DEC_HANDLE hStereoCng, /* i : Stereo CNG handle */ - const Word16 nchan_out /* i : number of output channels Q0*/ -) -{ - HANDLE_FD_CNG_COM hFdCngCom; - Word32 gamma_fx, scale_fx /*, SP_ratio_fx needs to be integrated*/; - Word32 Np_fx[L_FRAME16k]; - Word32 Ns_fx[L_FRAME16k]; - Word32 N1_fx[L_FRAME16k]; - Word32 N2_fx[L_FRAME16k]; - Word16 N1_fx_exp, N2_fx_exp; - Word16 i; - - IF( st->idchan == 0 ) - { - hFdCngCom = st->hFdCngDec->hFdCngCom; - Copy_Scale_sig_16_32( hStereoCng->olapBufferSynth22_fx, Ns_fx, shr( hFdCngCom->frameSize, 1 ), sub( Q6, st->Q_syn ) ); /*Q6*/ - Copy32( hFdCngCom->olapBufferSynth2_fx, Np_fx, shr( hFdCngCom->frameSize, 1 ) ); /*st->Q_syn*/ - - set32_fx( &Np_fx[( hFdCngCom->frameSize / 2 )], 0, shr( hFdCngCom->frameSize, 1 ) ); - set32_fx( &Ns_fx[( hFdCngCom->frameSize / 2 )], 0, shr( hFdCngCom->frameSize, 1 ) ); - - IF( !fadeOut ) - { - Copy_Scale_sig_16_32( hStereoCng->olapBufferSynth22_fx, hStereoCng->olapBufferSynth22_32fx, hFdCngCom->fftlen, sub( Q15, st->Q_syn ) ); /*Q15*/ - - generate_masking_noise_ivas_fx( N1_fx, &N1_fx_exp, hFdCngCom, hFdCngCom->frameSize, 0, 1, 0, st->element_mode, hStereoCng, nchan_out ); // N1_fx Q6 - /* Generate masking noise for secondary channel */ - IF( flag_sec_CNA ) - { - generate_masking_noise_ivas_fx( N2_fx, &N2_fx_exp, hFdCngCom, hFdCngCom->frameSize, 0, 1, 1, st->element_mode, hStereoCng, nchan_out ); // N2_fx Q6 - gamma_fx = L_shr( Mpy_32_32( hStereoCng->c_PS_LT_fx, hStereoCng->c_PS_LT_fx ), 1 ); /*Q30*/ - scale_fx = ONE_IN_Q30; - move32(); - IF( LT_32( gamma_fx, 966367642 /* 0.9 in Q30 */ ) ) - { - Word16 exp_gamma; - exp_gamma = 0; - move16(); - Word16 divisor1; - divisor1 = Inv16( (Word16) L_shr( L_sub( ONE_IN_Q30, gamma_fx ), Q15 ), &exp_gamma ); // Q15-exp_gamma - gamma_fx = L_shl( Mpy_32_16_1( gamma_fx, divisor1 ), exp_gamma ); // Q30 - Word16 exp_gamma1, exp_gamma2, exp_gamma3; - exp_gamma1 = Q1; - exp_gamma2 = Q1; - exp_gamma3 = Q1; - move16(); - move16(); - move16(); - gamma_fx = Sqrt32( L_add( gamma_fx, ONE_IN_Q30 ), &exp_gamma1 ); /*Q31 - exp_gamma1*/ - Word32 temp; - temp = Sqrt32( gamma_fx, &exp_gamma2 ); // Q31-exp_gamma1 - gamma_fx = L_sub( gamma_fx, L_shl( temp, sub( exp_gamma2, exp_gamma1 ) ) ); // Q31-exp_gamma1 - gamma_fx = L_shl( gamma_fx, sub( exp_gamma1, Q1 ) ); // Q30 - Word32 divisor2; - divisor2 = Sqrt32( L_add( ONE_IN_Q30, L_shl( Mpy_32_32( gamma_fx, gamma_fx ), Q1 ) ), &exp_gamma3 ); // Q31 - exp_gamma3 - scale_fx = L_shl( divide3232( ONE_IN_Q30, divisor2 ), add( Q15, exp_gamma3 ) ); // Q30 - } - ELSE - { - gamma_fx = 0; - move16(); - } - - FOR( i = 0; i < 2 * hFdCngCom->frameSize / 4; i++ ) - { - Np_fx[i] = L_add( Np_fx[i], - Mpy_32_32( scale_fx, L_shl( L_add( N1_fx[i], Mpy_32_32( gamma_fx, L_shl( N2_fx[i], Q1 ) ) ), Q1 ) ) ); // Q6 - move32(); - Word32 add2; - add2 = Mpy_32_32( scale_fx, L_shl( L_sub( N1_fx[i], Mpy_32_32( gamma_fx, L_shl( N2_fx[i], Q1 ) ) ), Q1 ) ); // Q6 - if ( hStereoCng->c_PS_LT_fx < 0 ) - { - add2 = L_negate( add2 ); /*Q6*/ - } - Ns_fx[i] = L_add( Ns_fx[i], add2 ); /*Q6*/ - move32(); - } - FOR( ; i < hFdCngCom->frameSize; i++ ) - { - Np_fx[i] = Mpy_32_32( scale_fx, L_shl( L_add( N1_fx[i], Mpy_32_32( gamma_fx, L_shl( N2_fx[i], Q1 ) ) ), Q1 ) ); // Q6 - move32(); - Ns_fx[i] = Mpy_32_32( scale_fx, L_shl( L_sub( N1_fx[i], Mpy_32_32( gamma_fx, L_shl( N2_fx[i], Q1 ) ) ), Q1 ) ); // Q6 - move32(); - IF( hStereoCng->c_PS_LT_fx < 0 ) - { - Ns_fx[i] = L_negate( Ns_fx[i] ); - move32(); - } - } - /* Below code to be converted */ - Word32 scale_fx_tmp = Mpy_32_32( scale_fx, L_shl( shr( hFdCngCom->fftlen, 1 ), Q22 ) ); // Q21 - FOR( i = 0; i < shr( hFdCngCom->frameSize, 1 ); i++ ) - { - hFdCngCom->olapBufferSynth2[i] = (Word16) L_shr( Mpy_32_32( scale_fx_tmp, - L_add( L_shr( hFdCngCom->olapBufferSynth2[( i + ( 5 * ( hFdCngCom->frameSize / 4 ) ) )], Q15 ), - Mpy_32_16_1( gamma_fx, hStereoCng->olapBufferSynth22_fx[( i + ( 5 * ( hFdCngCom->frameSize / 4 ) ) )] ) ) ), - Q14 ); // Q_olap - move16(); - hStereoCng->olapBufferSynth22_fx[i] = (Word16) L_shr( Mpy_32_32( scale_fx_tmp, - L_sub( L_shr( hFdCngCom->olapBufferSynth2[( i + ( 5 * ( hFdCngCom->frameSize / 4 ) ) )], Q15 ), - Mpy_32_16_1( gamma_fx, hStereoCng->olapBufferSynth22_fx[( i + ( 5 * ( hFdCngCom->frameSize / 4 ) ) )] ) ) ), - Q14 ); // Q_olap - move16(); - } - } - ELSE - { - FOR( i = 0; i < shr( hFdCngCom->frameSize, 1 ); i++ ) - { - Np_fx[i] = L_add( Np_fx[i], N1_fx[i] ); // Q6 - move32(); - } - Copy32( &N1_fx[( hFdCngCom->frameSize / 2 )], &Np_fx[( hFdCngCom->frameSize / 2 )], shr( hFdCngCom->frameSize, 1 ) ); /*Q6*/ - scale_fx = L_shl( shr( hFdCngCom->fftlen, 1 ), Q22 ); // Q21 - FOR( i = 0; i < hFdCngCom->frameSize; i++ ) - { - hFdCngCom->olapBufferSynth2[i] = (Word16) L_shr( Mpy_32_16_1( scale_fx, hFdCngCom->olapBufferSynth2[( i + ( 5 * ( hFdCngCom->frameSize / 4 ) ) )] ), Q6 ); // Q_olap - move16(); - } - } - - Copy_Scale_sig_32_16( hStereoCng->olapBufferSynth22_32fx, hStereoCng->olapBufferSynth22_fx, hFdCngCom->fftlen, sub( st->Q_syn, 15 ) ); /*st->Q_syn*/ - } - ELSE - { - set16_fx( hFdCngCom->olapBufferSynth2, 0, shr( hFdCngCom->frameSize, 1 ) ); - set16_fx( hStereoCng->olapBufferSynth22_fx, 0, shr( hFdCngCom->frameSize, 1 ) ); - } - IF( flag_sec_CNA ) - { - Copy_Scale_sig_32_16( Ns_fx, hStereoCng->maskingNoiseS_fx, hFdCngCom->frameSize, 0 ); // Q6 - hStereoCng->enableSecCNA = 1; - move16(); - } - ELSE - { - set16_fx( hStereoCng->olapBufferSynth22_fx, 0, hFdCngCom->frameSize ); - } - - /* add masking noise */ - FOR( i = 0; i < hFdCngCom->frameSize; i++ ) - { - syn[i] = add( syn[i], (Word16) L_shr( Np_fx[i], sub( Q16 + Q6, Q_syn ) ) ); // Q_syn - move16(); - } - } - ELSE IF( hStereoCng->enableSecCNA ) - { - Word16 SP_ratio_fx; - SP_ratio_fx = extract_h( hStereoTD->SP_ratio_LT_fx ); /* Use long-term SP ratio based on L/R synthesis Q15*/ - Word16 prevSP_ratio_fx; - prevSP_ratio_fx = hStereoTD->prevSP_ratio_fx; /* Use long-term SP ratio based on L/R synthesis Q15*/ - move16(); - /* scale and add masking noise */ - FOR( i = 0; i < shr( *hStereoCng->frameSize, 2 ); i++ ) - { - Word16 s; - Word16 scale_fx_tmp; - scale_fx_tmp = BASOP_Util_Divide3216_Scale( L_add( L_mult0( prevSP_ratio_fx, sub( shr( *hStereoCng->frameSize, 2 ), i ) ), L_mult0( SP_ratio_fx, i ) ), shr( *hStereoCng->frameSize, 2 ), &s ); // Q15 - scale_fx_tmp = shl( scale_fx_tmp, s ); - syn[i] = add( syn[i], mult( scale_fx_tmp, shr( hStereoCng->maskingNoiseS_fx[i], sub( Q6, Q_syn ) ) ) ); /*Q_syn*/ - move16(); - } - FOR( ; i < *hStereoCng->frameSize / 2; i++ ) - { - syn[i] = add( syn[i], mult( SP_ratio_fx, shr( hStereoCng->maskingNoiseS_fx[i], sub( Q6, Q_syn ) ) ) ); /*Q_syn*/ - move16(); - } - FOR( ; i < *hStereoCng->frameSize; i++ ) - { - syn[i] = add( syn[i], mult( SP_ratio_fx, shr( hStereoCng->maskingNoiseS_fx[i], sub( Q6, Q_syn ) ) ) ); /*Q_syn*/ - move16(); - } - hStereoTD->prevSP_ratio_fx = extract_h( hStereoTD->SP_ratio_LT_fx ); /*Q15*/ - move16(); - } - - return; -} -void generate_masking_noise_lb_dirac_fx( - HANDLE_FD_CNG_COM hFdCngCom, /* i/o: FD_CNG structure containing all buffers and variables */ - Word32 *tdBuffer, /* i/o: time-domain signal, if NULL no LB-CNA Q11*/ - const Word16 nCldfbTs, /* i : number of CLDFB slots that will be rendered Q0*/ - const Word16 cna_flag /* i : CNA flag for LB and HB Q0*/ -) -{ - Word16 i; - Word32 *cngNoiseLevel = hFdCngCom->cngNoiseLevel; /*hFdCngCom->cngNoiseLevelExp*/ - Word32 *fftBuffer = hFdCngCom->fftBuffer; /*hFdCngCom->fftBuffer_exp*/ - Word32 *ptr_r; - Word32 *ptr_i; - Word32 *ptr_level; - Word16 *seed = &( hFdCngCom->seed ); - Word32 scale; - Word16 n_samples_out, n_samples_start, n_samples_out_loop; - - push_wmops( "fd_cng_dirac" ); - - /* Init */ - scale = 0; - move32(); - n_samples_out = i_mult( shr( hFdCngCom->frameSize, 4 ), nCldfbTs ); - n_samples_start = 0; - move16(); - Word16 exp_out = Q11; - move16(); - /*LB CLDFB - CNA from STFT*/ - IF( cna_flag ) - { - /* skip noise generating if level is very low, to avoid problems with possibly running into denormals */ - IF( GT_16( hFdCngCom->likelihood_noisy_speech, DELTA_MASKING_NOISE_Q15 ) ) - { - /* Compute additional CN level */ - FOR( i = 0; i < 15; i++ ) - { - test(); - test(); - if ( ( EQ_16( hFdCngCom->CngBandwidth, scaleTable_cn_dirac[i].bwmode ) ) && - GE_32( hFdCngCom->CngBitrate, scaleTable_cn_dirac[i].bitrateFrom ) && - LT_32( hFdCngCom->CngBitrate, scaleTable_cn_dirac[i].bitrateTo ) ) - { - BREAK; - } - } - - scale = L_deposit_h( scaleTable_cn_dirac[i].scale_ivas ); /* Q30 */ - scale = Mpy_32_16_1( scale, hFdCngCom->likelihood_noisy_speech ); /* Q30 */ - } - } - - /* LB CLDFB - CNA from STFT: CNA applied only in channel 0*/ - test(); - IF( cna_flag && tdBuffer != NULL ) - { - WHILE( n_samples_out > 0 ) - { - n_samples_out_loop = s_min( hFdCngCom->frameSize, n_samples_out ); - IF( scale != 0 ) - { - /*Generate LF comfort noise only at first slot, for the whole frame*/ - ptr_level = cngNoiseLevel; /*hFdCngCom->cngNoiseLevelExp*/ - - /* Generate Gaussian random noise in real and imaginary parts of the FFT bins - Amplitudes are adjusted to the estimated noise level cngNoiseLevel_flt in each bin */ - IF( EQ_16( hFdCngCom->startBand, 0 ) ) - { - rand_gauss_fx( &fftBuffer[0], seed, exp_out ); - ptr_r = fftBuffer + 2; /*hFdCngCom->fftBuffer_exp*/ - - Word16 exp2 = sub( 31, hFdCngCom->cngNoiseLevelExp ); - Word32 sqr = Sqrt32( L_shr( Mpy_32_32( scale, *ptr_level ), 1 ), &exp2 ); /* DC component in FFT Q31 - exp2*/ - sqr = L_shl( sqr, exp2 ); /*Q31*/ - fftBuffer[0] = Mpy_32_32( fftBuffer[0], sqr ); /* DC component in FFT Q31 - hFdCngCom->fftBuffer_exp*/ - move32(); - ptr_level++; - } - ELSE - { - fftBuffer[0] = 0; - move32(); - set32_fx( fftBuffer + 2, 0, shl( sub( hFdCngCom->startBand, 1 ), 1 ) ); - ptr_r = fftBuffer + shl( hFdCngCom->startBand, 1 ); /*hFdCngCom->fftBuffer_exp*/ - } - ptr_i = ptr_r + 1; /*hFdCngCom->fftBuffer_exp*/ - - FOR( ; ptr_level < cngNoiseLevel + sub( hFdCngCom->stopFFTbin, hFdCngCom->startBand ); ptr_level++ ) - { - rand_gauss_fx( ptr_r, seed, exp_out ); - Word16 exp2 = hFdCngCom->cngNoiseLevelExp; - Word32 mpy2 = Sqrt32( Mpy_32_32( scale, *ptr_level ), &exp2 ); /*Q31 - exp2*/ - ( *ptr_r ) = L_shl( Mpy_32_32( *ptr_r, mpy2 ), exp2 ); /*Q31 - hFdCngCom->fftBuffer_exp*/ - move32(); - ptr_r += 2; - - /* Imaginary part in FFT bins */ - rand_gauss_fx( ptr_i, seed, exp_out ); - ( *ptr_i ) = L_shl( Mpy_32_32( *ptr_i, mpy2 ), exp2 ); /*Q31 - hFdCngCom->fftBuffer_exp*/ - move32(); - ptr_i += 2; - } - /* Remaining FFT bins are set to zero */ - set32_fx( fftBuffer + shl( hFdCngCom->stopFFTbin, 1 ), 0, sub( hFdCngCom->fftlen, shl( hFdCngCom->stopFFTbin, 1 ) ) ); - /* Nyquist frequency is discarded */ - fftBuffer[1] = 0; - move32(); - - /* Perform STFT synthesis */ - SynthesisSTFT_dirac_fx( fftBuffer, tdBuffer + n_samples_start, hFdCngCom->olapBufferSynth2_fx, hFdCngCom->olapWinSyn_fx, n_samples_out_loop, hFdCngCom ); - scale_sig32( tdBuffer + n_samples_start, n_samples_out_loop, Q9 ); // Q2 -> Q11 - } - - ELSE - { - /* very low level case - update random seeds */ - generate_masking_noise_update_seed_fx( hFdCngCom ); - - set32_fx( fftBuffer, 0, hFdCngCom->fftlen ); - /* Perform STFT synthesis */ - SynthesisSTFT_dirac_fx( fftBuffer, tdBuffer + n_samples_start, hFdCngCom->olapBufferSynth2_fx, hFdCngCom->olapWinSyn_fx, n_samples_out_loop, hFdCngCom ); - } - hFdCngCom->fftBuffer_exp = 31 - 11; - move16(); - n_samples_out = sub( n_samples_out, hFdCngCom->frameSize ); - n_samples_start = add( n_samples_start, hFdCngCom->frameSize ); - } - } - - pop_wmops(); - - return; -} -void generate_masking_noise_dirac_ivas_fx( - HANDLE_FD_CNG_COM hFdCngCom, /* i/o: FD_CNG structure containing all buffers and variables */ - HANDLE_CLDFB_FILTER_BANK h_cldfb, /* i : filterbank state */ - Word32 *tdBuffer_fx, /* i/o: time-domain signal, if NULL no LB-CNA q_input*/ - Word32 *Cldfb_RealBuffer_fx, /* o : CLDFD real buffer q_cldfb*/ - Word32 *Cldfb_ImagBuffer_fx, /* o : CLDFD imaginary buffer q_cldfb*/ - const Word16 slot_index, /* i : CLDFB slot index Q0*/ - const Word16 cna_flag, /* i : CNA flag for LB and HB Q0*/ - const Word16 fd_cng_flag, /* i : FD-CNG flag for HB Q0*/ - Word16 q_input, - Word16 *q_cldfb ) -{ - Word16 i; - Word32 *ptr_level_fx; - Word16 *seed = &( hFdCngCom->seed ); - Word32 scale_fx; - Word16 q_scale, q_shift, q_ptr_level; - - push_wmops( "fd_cng_dirac" ); - - /* Init */ - scale_fx = 0; - move32(); - - /* Resample CLDFB memories if necessary*/ - IF( NE_16( i_mult( h_cldfb->no_channels, h_cldfb->no_col ), hFdCngCom->frameSize ) ) - { - resampleCldfb_ivas_fx( h_cldfb, hFdCngCom->frameSize * FRAMES_PER_SEC ); - } - - set32_fx( Cldfb_RealBuffer_fx, 0, CLDFB_NO_CHANNELS_MAX ); - set32_fx( Cldfb_ImagBuffer_fx, 0, CLDFB_NO_CHANNELS_MAX ); - - /*LB CLDFB - CNA from STFT*/ - IF( cna_flag != 0 ) - { - /* skip noise generating if level is very low, to avoid problems with possibly running into denormals */ - IF( hFdCngCom->likelihood_noisy_speech > 0 ) - { - /* Compute additional CN level */ - FOR( i = 0; i < 15; i++ ) - { - test(); - test(); - if ( ( EQ_16( hFdCngCom->CngBandwidth, scaleTable_cn_dirac[i].bwmode ) ) && - ( GE_32( hFdCngCom->CngBitrate, scaleTable_cn_dirac[i].bitrateFrom ) ) && - ( LT_32( hFdCngCom->CngBitrate, scaleTable_cn_dirac[i].bitrateTo ) ) ) - { - BREAK; - } - } - - scale_fx = L_shr( L_deposit_h( scaleTable_cn_dirac[i].scale_ivas ), Q3 ); /* Q27 */ - scale_fx = Mpy_32_16_1( scale_fx, hFdCngCom->likelihood_noisy_speech ); - } - } - /* LB CLDFB - CNA from STFT: CNA applied only in channel 0*/ - IF( cna_flag && tdBuffer_fx != NULL ) - { - *q_cldfb = q_input; - move16(); - IF( scale_fx != 0 ) - { - /* LF CLDFB*/ - cldfbAnalysis_ts_fx_fixed_q( &( tdBuffer_fx[( hFdCngCom->numCoreBands * slot_index )] ), Cldfb_RealBuffer_fx, Cldfb_ImagBuffer_fx, hFdCngCom->numCoreBands, h_cldfb, q_cldfb ); - } - ELSE - { - /* LB ana CLDFB*/ - cldfbAnalysis_ts_fx_fixed_q( &( tdBuffer_fx[( hFdCngCom->numCoreBands * slot_index )] ), Cldfb_RealBuffer_fx, Cldfb_ImagBuffer_fx, hFdCngCom->numCoreBands, h_cldfb, q_cldfb ); - } - } - - /*HF CLDFB - CNA and/or FD-CNG*/ - if ( fd_cng_flag ) - { - scale_fx = L_add( scale_fx, ONE_IN_Q27 ); // 1 in Q27 - } - IF( scale_fx != 0 ) - { - q_scale = 27; - move16(); - q_shift = norm_l( scale_fx ); - scale_fx = L_shl( scale_fx, q_shift ); /*q_scale+q_shift*/ - q_scale = add( q_scale, q_shift ); - scale_fx = Mpy_32_32( scale_fx, Mpy_32_16_1( L_mult( h_cldfb->scale, h_cldfb->scale ), CLDFB_SCALING ) ); // Q = q_scale + 2 * Q8 - 34 - q_scale = sub( add( q_scale, 2 * Q8 ), 31 ); - ptr_level_fx = hFdCngCom->cngNoiseLevel + sub( hFdCngCom->stopFFTbin, hFdCngCom->startBand ); /*Q31 - hFdCngCom->cngNoiseLevelExp*/ - q_ptr_level = sub( 31, hFdCngCom->cngNoiseLevelExp ); - - FOR( i = hFdCngCom->numCoreBands; i < hFdCngCom->regularStopBand; i++ ) - { - Word32 num; - Word16 exp, q_num; - q_shift = norm_l( scale_fx ); - scale_fx = L_shl( scale_fx, q_shift ); /*q_scale+q_shift*/ - q_scale = add( q_scale, q_shift ); - num = Mpy_32_32( scale_fx, *ptr_level_fx ); /*q_num*/ - q_num = sub( add( q_scale, q_ptr_level ), 31 ); - exp = sub( 31, q_num ); - num = Sqrt32( num, &exp ); /*Q31 - exp*/ - /* Real part in CLDFB band */ - rand_gauss_fx( &Cldfb_RealBuffer_fx[i], seed, *q_cldfb ); - Cldfb_RealBuffer_fx[i] = L_shl( Mpy_32_32( Cldfb_RealBuffer_fx[i], num ), exp ); - move32(); - /* Imaginary part in CLDFB band */ - rand_gauss_fx( &Cldfb_ImagBuffer_fx[i], seed, *q_cldfb ); - Cldfb_ImagBuffer_fx[i] = L_shl( Mpy_32_32( Cldfb_ImagBuffer_fx[i], num ), exp ); - move32(); - - ptr_level_fx++; - } - } - - pop_wmops(); - - return; -} - - -/*------------------------------------------------------------------- - * FdCngDecodeMDCTStereoSID() - * - * Decode FD-Cng parameters for CNG in MDCT-Stereo mode from the bitstream - * - *-------------------------------------------------------------------*/ - -void FdCngDecodeMDCTStereoSID_fx( - CPE_DEC_HANDLE hCPE /* i/o: CPE decoder state structure */ -) -{ - DEC_CORE_HANDLE sts[CPE_CHANNELS]; - HANDLE_FD_CNG_COM hFdCngCom; - Word32 *ms_ptr_fx[CPE_CHANNELS]; - Word32 *lr_ptr_fx[CPE_CHANNELS]; - Word32 logNoiseEst_fx[CPE_CHANNELS][NPART]; - Word32 gain_fx[CPE_CHANNELS]; - Word16 indices[FD_CNG_stages_37bits]; - Word16 N, i, ch, p, stages; - Word16 is_out_ms; - Word32 *invTrfMatrix_fx; - Word32 tmpRAM_fx[FDCNG_VQ_MAX_LEN][FDCNG_VQ_DCT_MAXTRUNC]; - Word16 shift, exp_diff, max_exp_idx; - Word16 exp_arr[NPART]; - Word32 tmp32, tmp32_arr[NPART]; - - invTrfMatrix_fx = (Word32 *) tmpRAM_fx; - create_IDCT_N_Matrix_fx( invTrfMatrix_fx, FDCNG_VQ_MAX_LEN, FDCNG_VQ_DCT_MAXTRUNC, FDCNG_VQ_MAX_LEN * FDCNG_VQ_DCT_MAXTRUNC ); // Q31 - - is_out_ms = 0; - move16(); - if ( hCPE->hCoreCoder[0]->cng_sba_flag ) - { - is_out_ms = 1; - move16(); - } - - N = 0; /* to avoid compilation warning */ - move16(); - - FOR( ch = 0; ch < CPE_CHANNELS; ch++ ) - { - sts[ch] = hCPE->hCoreCoder[ch]; - ms_ptr_fx[ch] = &logNoiseEst_fx[ch][0]; /*Q20*/ - lr_ptr_fx[ch] = &sts[ch]->hFdCngDec->hFdCngCom->sidNoiseEst[0]; /*Q18*/ - } - - /* decode noise shapes and gains */ - FOR( ch = 0; ch < CPE_CHANNELS; ch++ ) - { - sts[ch] = hCPE->hCoreCoder[ch]; - hFdCngCom = ( sts[ch]->hFdCngDec )->hFdCngCom; - N = hFdCngCom->npart; - move16(); - hFdCngCom->sid_frame_counter = add( hFdCngCom->sid_frame_counter, 1 ); /*Q0*/ - move16(); - - IF( ch ) - { - stages = FD_CNG_JOINT_stages_25bits; - move16(); - } - ELSE - { - stages = FD_CNG_stages_37bits; - move16(); - } - - /* read bitstream */ - FOR( i = 0; i < stages; i++ ) - { - indices[i] = get_next_indice_fx( sts[ch], bits_37bits[i] ); /*Q0*/ - move16(); - } - { - gain_fx[ch] = Mpy_32_32( L_shl( L_sub( get_next_indice_fx( sts[ch], 7 ), GAIN_Q_OFFSET_IVAS_FX ), Q20 ), TWO_BY_THREE_Q31 /* 2/3 in Q31 */ ); // Q20 - move32(); - } - - /* MSVQ decoder */ - shift = find_guarded_bits_fx( N ); - msvq_dec_fx( ivas_cdk_37bits_fx, NULL, NULL, stages, N, FD_CNG_maxN_37bits, indices, 1, invTrfMatrix_fx, ms_ptr_fx[ch], NULL, 7 ); // Q20 - shift - - Scale_sig32( ms_ptr_fx[ch], N, shift ); // Q20 - } - - dtx_read_padding_bits_fx( sts[1], mult( sub( IVAS_SID_5k2, 4400 ), ONE_BY_FRAMES_PER_SEC_Q15 ) ); - - IF( sts[0]->hFdCngDec->hFdCngCom->no_side_flag ) - { - set32_fx( ms_ptr_fx[1], 0, NPART ); - } - - IF( EQ_16( is_out_ms, 0 ) ) - { - inverseMS_fx( N, ms_ptr_fx[0], ms_ptr_fx[1], ONE_IN_Q31 ); - } - - FOR( ch = 0; ch < CPE_CHANNELS; ch++ ) - { - max_exp_idx = 0; - move16(); - hFdCngCom = sts[ch]->hFdCngDec->hFdCngCom; - FOR( p = 0; p < N; p++ ) - { - tmp32 = L_add( ms_ptr_fx[ch][p], gain_fx[ch] ); // Q20 - tmp32_arr[p] = BASOP_util_Pow2( Mpy_32_32( tmp32, LOG_10_BASE_2_BY_10_Q31 ), Q11, &exp_arr[p] ); /*Q31 - exp_arr[p]*/ - move32(); - if ( LT_16( exp_arr[max_exp_idx], exp_arr[p] ) ) - { - max_exp_idx = p; /*Q0*/ - move16(); - } - } - - // Bringing in same exponent - FOR( p = 0; p < N; p++ ) - { - lr_ptr_fx[ch][p] = L_shl( tmp32_arr[p], sub( exp_arr[p], exp_arr[max_exp_idx] ) ); /*Q31 - exp_arr[max_exp_idx]*/ - move32(); - } - - hFdCngCom->sidNoiseEstExp = exp_arr[max_exp_idx]; - move16(); - - scalebands( hFdCngCom->sidNoiseEst, hFdCngCom->part, hFdCngCom->npart, hFdCngCom->midband, hFdCngCom->nFFTpart, sub( hFdCngCom->stopBand, hFdCngCom->startBand ), hFdCngCom->cngNoiseLevel, 1 ); - - hFdCngCom->cngNoiseLevelExp = hFdCngCom->sidNoiseEstExp; - move16(); - - lpc_from_spectrum( hFdCngCom, hFdCngCom->startBand, hFdCngCom->stopFFTbin, sts[ch]->preemph_fac ); - } - - test(); - IF( EQ_16( hCPE->nchan_out, 1 ) && LE_32( hCPE->last_element_brate, IVAS_SID_5k2 ) ) - { - /* create proper M noise shape in channel zero after gains have been applied */ - exp_diff = sub( sts[0]->hFdCngDec->hFdCngCom->sidNoiseEstExp, sts[1]->hFdCngDec->hFdCngCom->sidNoiseEstExp ); - move16(); - FOR( p = 0; p < N; p++ ) - { - IF( GT_16( exp_diff, 0 ) ) - { - sts[0]->hFdCngDec->hFdCngCom->sidNoiseEst[p] = L_add( L_shr( sts[0]->hFdCngDec->hFdCngCom->sidNoiseEst[p], 1 ), L_shr( sts[1]->hFdCngDec->hFdCngCom->sidNoiseEst[p], add( exp_diff, 1 ) ) ); /*Q18*/ - move32(); - } - ELSE - { - sts[0]->hFdCngDec->hFdCngCom->sidNoiseEst[p] = L_add( L_shr( sts[0]->hFdCngDec->hFdCngCom->sidNoiseEst[p], sub( 1, exp_diff ) ), L_shr( sts[1]->hFdCngDec->hFdCngCom->sidNoiseEst[p], 1 ) ); /*Q18*/ - move32(); - } - } - IF( LT_16( exp_diff, 0 ) ) - { - sts[0]->hFdCngDec->hFdCngCom->sidNoiseEstExp = add( sts[0]->hFdCngDec->hFdCngCom->sidNoiseEstExp, negate( exp_diff ) ); - move16(); - } - } - - return; -} - - -/*------------------------------------------------------------------- - * FdCngDecodeDiracMDCTStereoSID_fx() - * - * Decode FD-CNG parameters for CNG in 2TC DirAC mode from the bitstream - *-------------------------------------------------------------------*/ - -void FdCngDecodeDiracMDCTStereoSID_fx( - CPE_DEC_HANDLE hCPE /* i/o: CPE decoder state structure */ -) -{ - DEC_CORE_HANDLE sts[CPE_CHANNELS]; - HANDLE_FD_CNG_COM hFdCngCom; - Word32 *ms_ptr_fx[CPE_CHANNELS]; - Word32 *lr_ptr_fx[CPE_CHANNELS]; - Word32 logNoiseEst_fx[CPE_CHANNELS][NPART]; - Word32 gain_fx[CPE_CHANNELS]; - Word16 indices[FD_CNG_stages_37bits]; - Word16 N, i, ch, p; - Word32 *invTrfMatrix_fx; - Word32 tmpRAM_fx[FDCNG_VQ_MAX_LEN][FDCNG_VQ_DCT_MAXTRUNC]; - Word16 shift, exp_diff, max_exp_idx; - Word16 exp_arr[NPART]; - Word32 tmp32, tmp32_arr[NPART]; - - invTrfMatrix_fx = (Word32 *) tmpRAM_fx; /* dynamically filled */ - create_IDCT_N_Matrix_fx( invTrfMatrix_fx, FDCNG_VQ_MAX_LEN, FDCNG_VQ_DCT_MAXTRUNC, FDCNG_VQ_MAX_LEN * FDCNG_VQ_DCT_MAXTRUNC ); // Q31 - - FOR( ch = 0; ch < CPE_CHANNELS; ch++ ) - { - sts[ch] = hCPE->hCoreCoder[ch]; - ms_ptr_fx[ch] = &logNoiseEst_fx[ch][0]; /*Q20*/ - lr_ptr_fx[ch] = &sts[ch]->hFdCngDec->hFdCngCom->sidNoiseEst[0]; /*Q20*/ - ( sts[ch]->hFdCngDec )->hFdCngCom->sid_frame_counter++; /*Q18*/ - } - - /* decode noise shapes and gains */ - hFdCngCom = ( sts[0]->hFdCngDec )->hFdCngCom; - N = hFdCngCom->npart; /*Q0*/ - move16(); - - /* read bitstream */ - FOR( i = 0; i < FD_CNG_stages_37bits; i++ ) - { - indices[i] = get_next_indice_fx( sts[0], bits_37bits[i] ); /*Q0*/ - move16(); - } - gain_fx[0] = Mpy_32_32( L_shl( L_sub( get_next_indice_fx( sts[0], 7 ), GAIN_Q_OFFSET_IVAS_FX ), Q20 ), TWO_BY_THREE_Q31 /* 2/3 in Q31 */ ); // Q20 - move32(); - - gain_fx[1] = gain_fx[0]; /*Q20*/ - move32(); - - /* MSVQ decoder */ - shift = find_guarded_bits_fx( N ); - msvq_dec_fx( ivas_cdk_37bits_fx, NULL, NULL, FD_CNG_stages_37bits, N, FD_CNG_maxN_37bits, indices, 1, invTrfMatrix_fx, ms_ptr_fx[0], NULL, 7 ); // Q20 - shift - - Scale_sig32( ms_ptr_fx[0], N, shift ); // Q20 - - Copy32( ms_ptr_fx[0], ms_ptr_fx[1], N ); /*Q20*/ - - FOR( ch = 0; ch < CPE_CHANNELS; ch++ ) - { - max_exp_idx = 0; - move16(); - hFdCngCom = sts[ch]->hFdCngDec->hFdCngCom; - - FOR( p = 0; p < N; p++ ) - { - tmp32 = L_add( ms_ptr_fx[ch][p], gain_fx[ch] ); // Q20 - tmp32_arr[p] = BASOP_util_Pow2( Mpy_32_32( tmp32, LOG_10_BASE_2_BY_10_Q31 ), Q11, &exp_arr[p] ); /*Q31 - exp_arr[p]*/ - move32(); - if ( LT_16( exp_arr[max_exp_idx], exp_arr[p] ) ) - { - max_exp_idx = p; /*Q0*/ - move16(); - } - } - - // Bringing in same exponent - FOR( p = 0; p < N; p++ ) - { - lr_ptr_fx[ch][p] = L_shl( tmp32_arr[p], sub( exp_arr[p], exp_arr[max_exp_idx] ) ); /*Q20*/ - move32(); - } - - hFdCngCom->sidNoiseEstExp = exp_arr[max_exp_idx]; /*Q0*/ - move16(); - - /* NB last band energy compensation */ - test(); - IF( hFdCngCom->CngBandwidth == NB ) - { - lr_ptr_fx[ch][( N - 1 )] = Mpy_32_32( lr_ptr_fx[ch][( N - 1 )], NB_LAST_BAND_SCALE_Q31 ); /*Q20*/ - move32(); - } - ELSE IF( EQ_16( hFdCngCom->CngBandwidth, SWB ) && LE_32( hFdCngCom->CngBitrate, ACELP_13k20 ) ) - { - lr_ptr_fx[ch][( N - 1 )] = Mpy_32_32( lr_ptr_fx[ch][( N - 1 )], SWB_13k2_LAST_BAND_SCALE_Q31 ); /*Q20*/ - move32(); - } - - scalebands( hFdCngCom->sidNoiseEst, hFdCngCom->part, hFdCngCom->npart, hFdCngCom->midband, hFdCngCom->nFFTpart, sub( hFdCngCom->stopBand, hFdCngCom->startBand ), hFdCngCom->cngNoiseLevel, 1 ); - - hFdCngCom->cngNoiseLevelExp = hFdCngCom->sidNoiseEstExp; - move16(); - - lpc_from_spectrum( hFdCngCom, hFdCngCom->startBand, hFdCngCom->stopFFTbin, sts[ch]->preemph_fac ); - } - sts[0]->hFdCngDec->hFdCngCom->coherence_fx = 0; - move16(); - sts[1]->hFdCngDec->hFdCngCom->coherence_fx = 0; - move16(); - - IF( EQ_16( hCPE->nchan_out, 1 ) ) - { - /* create proper M noise shape in channel zero after gains have been applied */ - exp_diff = sub( sts[0]->hFdCngDec->hFdCngCom->sidNoiseEstExp, sts[1]->hFdCngDec->hFdCngCom->sidNoiseEstExp ); - FOR( p = 0; p < N; p++ ) - { - IF( exp_diff > 0 ) - { - sts[0]->hFdCngDec->hFdCngCom->sidNoiseEst[p] = L_add( L_shr( sts[0]->hFdCngDec->hFdCngCom->sidNoiseEst[p], 1 ), L_shr( sts[1]->hFdCngDec->hFdCngCom->sidNoiseEst[p], add( exp_diff, 1 ) ) ); /*Q18*/ - move32(); - } - ELSE - { - sts[0]->hFdCngDec->hFdCngCom->sidNoiseEst[p] = L_add( L_shr( sts[0]->hFdCngDec->hFdCngCom->sidNoiseEst[p], sub( 1, exp_diff ) ), L_shr( sts[1]->hFdCngDec->hFdCngCom->sidNoiseEst[p], 1 ) ); /*Q18*/ - move32(); - } - } - IF( exp_diff < 0 ) - { - sts[0]->hFdCngDec->hFdCngCom->sidNoiseEstExp = add( sts[0]->hFdCngDec->hFdCngCom->sidNoiseEstExp, negate( exp_diff ) ); - move16(); - } - } - - return; -} diff --git a/lib_dec/fd_cng_dec_fx.c b/lib_dec/fd_cng_dec_fx.c index 2bb2a39ec3184f06b3bda44d11079d0c3afa0ebf..c509d5d1028b46af70fc21b31ddc1953b2e8fd10 100644 --- a/lib_dec/fd_cng_dec_fx.c +++ b/lib_dec/fd_cng_dec_fx.c @@ -20,10 +20,18 @@ #endif -#define CNA_ACT_DN_LARGE_PARTITION 50 /* index of the first larger partition */ -#define ST_PERIODOG_FACT_Q15 29491 /* 0.9 in Q15, short-term filter factor for periodogram */ -#define CNA_ACT_DN_FACT_Q15 22938 /* 0.7 in Q15, downward updating factor for CNA during active frames */ -#define FIRST_CNA_NOISE_UPD_FRAMES 5 /* minimum number of CN initialization frames */ +#define CNA_ACT_DN_LARGE_PARTITION 50 /* index of the first larger partition */ +#define ST_PERIODOG_FACT_Q15 29491 /* 0.9 in Q15, short-term filter factor for periodogram */ +#define CNA_ACT_DN_FACT_Q15 22938 /* 0.7 in Q15, downward updating factor for CNA during active frames */ +#define FIRST_CNA_NOISE_UPD_FRAMES 5 /* minimum number of CN initialization frames */ +#define DELTA_MASKING_NOISE_Q15 0 +#define LOG_10_BASE_2 1783446566 /* Q29 */ +#define GAIN_Q_OFFSET_IVAS_FX 45 +#define LOG_10_BASE_2_BY_10_Q31 713378606 +#define TWO_BY_THREE_Q31 1431655765 +#define ONE_BY_FRAMES_PER_SEC_Q15 656 +#define NB_LAST_BAND_SCALE_Q31 1717986918 +#define SWB_13k2_LAST_BAND_SCALE_Q31 1717986918 /******************************** * External tables * @@ -271,30 +279,6 @@ void initFdCngDec_fx( hFdCngDec->smoothed_psd_exp = 0; move16(); -#ifdef IVAS_CODE_CNG - set_f( hFdCngDec->hFdCngCom->sidNoiseEstLp, 0.0f, NPART ); - - set_f( hFdCngDec->smoothed_psd, 0.0f, L_FRAME16k ); - set_f( hFdCngDec->msPeriodog_ST, 0.0f, NPART_SHAPING ); - - hFdCngDec->ms_last_inactive_bwidth = NB; - hFdCngDec->ms_cnt_bw_up = 0; - - hFdCngDec->cna_LR_LT = 0.5f; - hFdCngDec->cna_ILD_LT = 0.0f; - hFdCngDec->first_cna_noise_updated = 0; - hFdCngDec->first_cna_noise_update_cnt = 0; - hFdCngDec->cna_nbands = 6; - mvs2s( cna_init_bands, hFdCngDec->cna_band_limits, MAX_CNA_NBANDS + 1 ); - hFdCngDec->cna_act_fact = 1.0f; - hFdCngDec->cna_rescale_fact = 0.0f; - hFdCngDec->cna_seed = 5687; - set_zero( hFdCngDec->cna_cm, STEREO_DFT_BAND_MAX ); - set_zero( hFdCngDec->cna_g_state, STEREO_DFT_BAND_MAX ); - - st->CNG_mode = -1; - mvr2r( st->lsp_old, st->lspCNG, M ); -#endif return; } /* @@ -825,11 +809,7 @@ Word16 ApplyFdCng_fx( Carry = 0; move16(); -#ifdef BASOP_NOGLOB L_tmp = L_add_co( L_tmp, *( cngNoiseLevel + j ), &Carry, &Overflow ); /*Q31*/ -#else - L_tmp = L_add_c( L_tmp, *( cngNoiseLevel + j ) ); -#endif Overflow = 0; move16(); @@ -839,11 +819,7 @@ Word16 ApplyFdCng_fx( } IF( *( cngNoiseLevel + j ) >= 0 ) { -#ifdef BASOP_NOGLOB L_c = L_macNs_co( L_c, 0, 0, &Carry, &Overflow ); /*Q-1*/ -#else - L_c = L_macNs( L_c, 0, 0 ); -#endif } } L_tmp = norm_llQ31( L_c, L_tmp, &L_tmp_exp ); /*Q31 - L_tmp_exp*/ @@ -855,11 +831,7 @@ Word16 ApplyFdCng_fx( L_tmp_exp = add( L_tmp_exp, -7 ); /*->Q16, L_tmp_exp */ L_tmp_exp = add( L_tmp_exp, 31 - 16 ); /*->Q31, L_tmp_exp*/ -#ifdef BASOP_NOGLOB st->cngTDLevel = round_fx_sat( Sqrt32( L_tmp, &L_tmp_exp ) ); /*Q15 - L_tmp_exp*/ -#else - st->cngTDLevel = round_fx( Sqrt32( L_tmp, &L_tmp_exp ) ); -#endif st->cngTDLevel_e = L_tmp_exp; move16(); } @@ -885,11 +857,7 @@ Word16 ApplyFdCng_fx( L_tmp_exp = add( *cngNoiseLevel_exp, 16 ); test(); test(); -#ifdef BASOP_NOGLOB IF( EQ_16( concealWholeFrame, 1 ) && EQ_16( st->nbLostCmpt, 1 ) && ( GT_32( L_shl_o( L_tmp, L_tmp_exp, &Overflow ), 21474836 ) /*0.01f Q31*/ ) ) -#else - IF( EQ_16( concealWholeFrame, 1 ) && EQ_16( st->nbLostCmpt, 1 ) && ( L_shl( L_tmp, L_tmp_exp ) > 21474836 /*0.01f Q31*/ ) ) -#endif { /* update isf cng estimate for concealment. Do that during concealment, in order to avoid addition clean channel complexity*/ #ifndef IVAS_CODE_CNG_FIX185_PLC_FADEOUT @@ -991,7 +959,6 @@ Word16 ApplyFdCng_fx( Carry = 0; move16(); -#ifdef BASOP_NOGLOB /* Critical Carry/Overflow */ L_tmp = L_add_co( L_tmp, *( cngNoiseLevel + j ), &Carry, &Overflow ); /*Q31*/ Overflow = 0; move16(); @@ -1004,19 +971,6 @@ Word16 ApplyFdCng_fx( { L_c = L_macNs_co( L_c, 0, 0, &Carry, &Overflow ); /*Q-1*/ } -#else - L_tmp = L_add_c( L_tmp, *( cngNoiseLevel + j ) ); - Overflow = 0; - - if ( *( cngNoiseLevel + j ) < 0 ) - { - L_c = L_msuNs( L_c, 0, 0 ); - } - if ( *( cngNoiseLevel + j ) >= 0 ) - { - L_c = L_macNs( L_c, 0, 0 ); - } -#endif } L_tmp = norm_llQ31( L_c, L_tmp, &L_tmp_exp ); /*Q31 - L_tmp_exp*/ L_tmp_exp = sub( add( L_tmp_exp, *cngNoiseLevel_exp ), 1 ); @@ -1027,12 +981,8 @@ Word16 ApplyFdCng_fx( L_tmp_exp = add( L_tmp_exp, -7 ); /*->Q16, L_tmp_exp */ L_tmp_exp = add( L_tmp_exp, 31 - 16 ); /*->Q31, L_tmp_exp*/ -#ifdef BASOP_NOGLOB /* Critical Carry/Overflow */ - st->cngTDLevel = round_fx_o( Sqrt32( L_tmp, &L_tmp_exp ), &Overflow ); /*Q15 - L_tmp_exp*/ + st->cngTDLevel = round_fx_o( Sqrt32( L_tmp, &L_tmp_exp ), &Overflow ); /*Q15 - L_tmp_exp*/ move16(); -#else - st->cngTDLevel = round_fx( Sqrt32( L_tmp, &L_tmp_exp ) ); -#endif st->cngTDLevel_e = L_tmp_exp; move16(); #endif @@ -1058,12 +1008,6 @@ Word16 ApplyFdCng_fx( hFdCngCom->psize_inv, hFdCngDec->partNoiseShape, &hFdCngDec->partNoiseShape_exp ); -#ifdef IVAS_CODE_CNG - IF( EQ_16( st->element_mode, IVAS_CPE_DFT ) ) - { - Copy( hFdCngDec->hFdCngCom->sidNoiseEst, hFdCngDec->hFdCngCom->sidNoiseEstLp, NPART ); - } -#endif } IF( EQ_16( st->m_frame_type, SID_FRAME ) ) @@ -1080,11 +1024,8 @@ Word16 ApplyFdCng_fx( { if ( EQ_16( st->element_mode, IVAS_CPE_DFT ) ) { -#ifdef IVAS_CODE_CNG - sidNoiseEst = hFdCngCom->sidNoiseEstLp; - move16(); -#endif } + /* Interpolate the CLDFB band levels from the SID (partition) levels */ IF( GT_16( hFdCngCom->regularStopBand, hFdCngCom->numCoreBands ) ) { @@ -1162,24 +1103,7 @@ Word16 ApplyFdCng_fx( move16(); } } -#ifdef IVAS_CODE_CNG - else if ( st->element_mode == IVAS_CPE_DFT ) - { - if ( !( hFdCngCom->msFrCnt_init_counter < hFdCngCom->msFrCnt_init_thresh ) ) - { - sidNoiseEst = hFdCngCom->sidNoiseEstLp; - j = 0; - for ( k = 0; k < hFdCngCom->nFFTpart; k++ ) - { - factor = ( sidNoiseEst[k] + DELTA ) / ( hFdCngDec->partNoiseShape[k] + DELTA ); - for ( ; j <= hFdCngCom->part[k]; j++ ) - { - cngNoiseLevel[j] = hFdCngDec->bandNoiseShape[j] * factor; - } - } - } - } -#endif + IF( EQ_16( st->codec_mode, MODE2 ) ) { /* Generate comfort noise during SID or zero frames */ @@ -1434,11 +1358,7 @@ Word16 ApplyFdCng_ivas_fx( Carry = 0; move16(); -#ifdef BASOP_NOGLOB L_tmp = L_add_co( L_tmp, *( cngNoiseLevel + j ), &Carry, &Overflow ); /*Q31*/ -#else - L_tmp = L_add_c( L_tmp, *( cngNoiseLevel + j ) ); -#endif Overflow = 0; move16(); @@ -1448,11 +1368,7 @@ Word16 ApplyFdCng_ivas_fx( } IF( *( cngNoiseLevel + j ) >= 0 ) { -#ifdef BASOP_NOGLOB L_c = L_macNs_co( L_c, 0, 0, &Carry, &Overflow ); /*Q-1*/ -#else - L_c = L_macNs( L_c, 0, 0 ); -#endif } } L_tmp = norm_llQ31( L_c, L_tmp, &L_tmp_exp ); /*Q31 - L_tmp_exp*/ @@ -1464,11 +1380,7 @@ Word16 ApplyFdCng_ivas_fx( L_tmp_exp = add( L_tmp_exp, -7 ); /*->Q16, L_tmp_exp */ L_tmp_exp = add( L_tmp_exp, 31 - 16 ); /*->Q31, L_tmp_exp*/ -#ifdef BASOP_NOGLOB st->hTcxDec->conCngLevelBackgroundTrace = round_fx_sat( Sqrt32( L_tmp, &L_tmp_exp ) ); /*Q15 - L_tmp_exp*/ -#else - st->hTcxDec->conCngLevelBackgroundTrace = round_fx( Sqrt32( L_tmp, &L_tmp_exp ) ); -#endif move16(); L_tmp_exp = add( L_tmp_exp, 1 ); st->hTcxDec->conCngLevelBackgroundTrace_e = L_tmp_exp; @@ -1485,11 +1397,7 @@ Word16 ApplyFdCng_ivas_fx( Carry = 0; move16(); -#ifdef BASOP_NOGLOB L_tmp = L_add_co( L_tmp, *( cngNoiseLevel + j ), &Carry, &Overflow ); /*Q31 - L_tmp_exp*/ -#else - L_tmp = L_add_c( L_tmp, *( cngNoiseLevel + j ) ); -#endif Overflow = 0; move16(); @@ -1499,11 +1407,7 @@ Word16 ApplyFdCng_ivas_fx( } IF( *( cngNoiseLevel + j ) >= 0 ) { -#ifdef BASOP_NOGLOB L_c = L_macNs_co( L_c, 0, 0, &Carry, &Overflow ); /*Q-1*/ -#else - L_c = L_macNs( L_c, 0, 0 ); -#endif } } L_tmp = norm_llQ31( L_c, L_tmp, &L_tmp_exp ); /*Q31 - L_tmp_exp*/ @@ -1515,13 +1419,8 @@ Word16 ApplyFdCng_ivas_fx( L_tmp_exp = add( L_tmp_exp, -7 ); /*->Q16, L_tmp_exp */ L_tmp_exp = add( L_tmp_exp, 31 - 16 ); /*->Q31, L_tmp_exp*/ -#ifdef BASOP_NOGLOB st->hTcxDec->conCngLevelBackgroundTrace = round_fx_sat( Sqrt32( L_tmp, &L_tmp_exp ) ); /*Q15 - L_tmp_exp*/ move16(); -#else - st->hTcxDec->conCngLevelBackgroundTrace = round_fx( Sqrt32( L_tmp, &L_tmp_exp ) ); - st->hTcxDec->CngLevelBackgroundTrace_bfi_fx = ( Sqrt32( L_tmp, &L_tmp_exp ) ); -#endif st->hTcxDec->conCngLevelBackgroundTrace_e = L_tmp_exp; move16(); } @@ -1534,11 +1433,7 @@ Word16 ApplyFdCng_ivas_fx( Carry = 0; move16(); -#ifdef BASOP_NOGLOB L_tmp = L_add_co( L_tmp, *( cngNoiseLevel + j ), &Carry, &Overflow ); /*Q31 - L_tmp_exp*/ -#else - L_tmp = L_add_c( L_tmp, *( cngNoiseLevel + j ) ); -#endif Overflow = 0; move16(); @@ -1548,11 +1443,7 @@ Word16 ApplyFdCng_ivas_fx( } IF( *( cngNoiseLevel + j ) >= 0 ) { -#ifdef BASOP_NOGLOB L_c = L_macNs_co( L_c, 0, 0, &Carry, &Overflow ); /*Q-1*/ -#else - L_c = L_macNs( L_c, 0, 0 ); -#endif } } L_tmp = norm_llQ31( L_c, L_tmp, &L_tmp_exp ); /*Q31 - L_tmp_exp*/ @@ -1564,11 +1455,7 @@ Word16 ApplyFdCng_ivas_fx( L_tmp_exp = add( L_tmp_exp, -7 ); /*->Q16, L_tmp_exp */ L_tmp_exp = add( L_tmp_exp, 31 - 16 ); /*->Q31, L_tmp_exp*/ -#ifdef BASOP_NOGLOB st->cngTDLevel = round_fx_sat( Sqrt32( L_tmp, &L_tmp_exp ) ); /*Q15 - L_tmp_exp*/ -#else - st->cngTDLevel = round_fx( Sqrt32( L_tmp, &L_tmp_exp ) ); -#endif move16(); st->cngTDLevel_e = L_tmp_exp; move16(); @@ -1601,11 +1488,7 @@ Word16 ApplyFdCng_ivas_fx( } L_tmp_exp = 0; move16(); -#ifdef BASOP_NOGLOB IF( GT_32( L_shl_o( L_tmp, L_tmp_exp, &Overflow ), 21474836 ) /*0.01f Q31*/ ) -#else - IF( L_shl( L_tmp, L_tmp_exp ) > 21474836 /*0.01f Q31*/ ) -#endif { test(); test(); @@ -1665,7 +1548,6 @@ Word16 ApplyFdCng_ivas_fx( Carry = 0; move16(); -#ifdef BASOP_NOGLOB /* Critical Carry/Overflow */ L_tmp = L_add_co( L_tmp, *( cngNoiseLevel + j ), &Carry, &Overflow ); /*Q31 - L_tmp_exp*/ Overflow = 0; move16(); @@ -1678,19 +1560,6 @@ Word16 ApplyFdCng_ivas_fx( { L_c = L_macNs_co( L_c, 0, 0, &Carry, &Overflow ); /*Q-1*/ } -#else - L_tmp = L_add_c( L_tmp, *( cngNoiseLevel + j ) ); - Overflow = 0; - - if ( *( cngNoiseLevel + j ) < 0 ) - { - L_c = L_msuNs( L_c, 0, 0 ); - } - if ( *( cngNoiseLevel + j ) >= 0 ) - { - L_c = L_macNs( L_c, 0, 0 ); - } -#endif } L_tmp = norm_llQ31( L_c, L_tmp, &L_tmp_exp ); /*Q31 - L_tmp_exp*/ L_tmp_exp = sub( add( L_tmp_exp, *cngNoiseLevel_exp ), 1 ); @@ -1701,11 +1570,7 @@ Word16 ApplyFdCng_ivas_fx( L_tmp_exp = add( L_tmp_exp, -7 ); /*->Q16, L_tmp_exp */ L_tmp_exp = add( L_tmp_exp, 31 - 16 ); /*->Q31, L_tmp_exp*/ -#ifdef BASOP_NOGLOB /* Critical Carry/Overflow */ st->cngTDLevel = round_fx_o( Sqrt32( L_tmp, &L_tmp_exp ), &Overflow ); /*Q15 - L_tmp_exp*/ -#else - st->cngTDLevel = round_fx( Sqrt32( L_tmp, &L_tmp_exp ) ); -#endif move16(); st->cngTDLevel_e = L_tmp_exp; move16(); @@ -1900,7 +1765,12 @@ Word16 ApplyFdCng_ivas_fx( { FOR( ; j <= hFdCngCom->part[k]; j++ ) { +#ifdef FIX_ISSUE_1218 + /* NOTE: saturation is added here as part of issue 1218 fix. after rescaling the fdcng noise estimation buffers, due to slight precision loss, values may slightly overflow */ + cngNoiseLevel[j] = L_shl_sat( cngNoiseLevel[j], s ); /*Q31 - hFdCngDec->bandNoiseShape_exp + s*/ +#else cngNoiseLevel[j] = L_shl( cngNoiseLevel[j], s ); /*Q31 - hFdCngDec->bandNoiseShape_exp + s*/ +#endif move32(); } } @@ -1946,15 +1816,6 @@ void perform_noise_estimation_dec_fx( float *power_spectrum, #endif HANDLE_FD_CNG_DEC hFdCngDec /* i/o: FD_CNG structure containing all buffers and variables */ -#ifdef IVAS_CODE_CNG - , - const int16_t element_mode, /* i : element mode */ - const int16_t bwidth, /* i : audio bandwidth */ - const int16_t L_frame, /* i : frame length at internal Fs */ - const int16_t last_L_frame, /* i : frame length of the last frame at internal Fs */ - const int32_t last_core_brate, /* i : previous frame core bitrate */ - const int16_t VAD /* i : VAD flag in the decoder */ -#endif ) { Word16 i, tmp_r, tmp_i, fac, fftBuffer_exp; @@ -1963,10 +1824,6 @@ void perform_noise_estimation_dec_fx( Word16 *part, *psize_inv, *psize_norm; Word32 tmp, *fftBuffer, *periodog, *ptr_per, *ptr_r, *ptr_i; -#ifdef IVAS_CODE_CNG - PMT( "lots of code related to IVAS needs to be done " ) -#endif - /* pointer initialization */ periodog = hFdCngDec->hFdCngCom->periodog; /*Q31 - hFdCngDec->hFdCngCom->periodog_exp*/ @@ -1999,238 +1856,7 @@ void perform_noise_estimation_dec_fx( AnalysisSTFT( timeDomainInput, Q, fftBuffer, &fftBuffer_exp, hFdCngDec->hFdCngCom ); #endif fftBuffer_exp = add( fftBuffer_exp, WORD16_BITS - 1 ); -#ifdef IVAS_CODE_CNG - if ( element_mode == IVAS_CPE_TD || element_mode == IVAS_CPE_DFT ) - { - /* Calculate periodogram (squared magnitude in each FFT bin) */ - if ( startBand == 0 ) - { - ( *ptr_per ) = fftBuffer[0] * fftBuffer[0]; - ptr_per++; - ptr_r = fftBuffer + 2; - } - else - { - ptr_r = fftBuffer + 2 * startBand; - } - - ptr_i = ptr_r + 1; - - for ( ; ptr_per < periodog + stopFFTbin - startBand; ptr_per++ ) - { - ( *ptr_per ) = ( *ptr_r ) * ( *ptr_r ) + ( *ptr_i ) * ( *ptr_i ); - ptr_r += 2; - ptr_i += 2; - } - - /* Rescale to get energy/sample: it should be 2*(1/N)*(2/N), parseval relation with 1/N,*2 for nrg computed till Nyquist only, 2/N as windowed samples correspond to half a frame*/ - v_multc( periodog, 4.f / (float) ( hFdCngDec->hFdCngCom->fftlen * hFdCngDec->hFdCngCom->fftlen ), periodog, stopFFTbin - startBand ); - - /* Combine bins of power spectrum into partitions */ - i = 0; - for ( p = 0; p < npart; p++ ) - { - - /* calculate mean over all bins in power partition */ - temp = 0; - for ( ; i <= part[p]; i++ ) - { - temp += periodog[i]; - } - msPeriodog[p] = temp * psize_inv[p]; - } - - /* compensate for the loss of variance - don't do when first noise update is not completed yet due to risk of msPeriodog[p] < 0 */ - if ( hFdCngDec->first_cna_noise_updated ) - { - i = 0; - for ( p = 0; p < npart; p++ ) - { - /* calculate variance over all bins in power partition */ - temp = 0; - for ( ; i <= part[p]; i++ ) - { - delta = periodog[i] - msPeriodog[p]; - temp += delta * delta; - } - temp *= psize_inv[p]; - - /* compensate for the loss of variance */ - msPeriodog[p] = (float) ( msPeriodog[p] + sqrt( temp ) * rand_gauss( &ftemp, &hFdCngDec->cna_seed ) ); - - if ( msPeriodog[p] < 1e-5f ) - { - msPeriodog[p] = 1e-5f; - } - } - } - - /* calculate total energy (short-term and long-term) */ - enr_tot = sum_f( msPeriodog, npart ) + EPSILON; - enr_tot0 = sum_f( msNoiseEst, npart ) + EPSILON; - - /* update short-term periodogram on larger partitions */ - for ( p = CNA_ACT_DN_LARGE_PARTITION; p < npart; p++ ) - { - if ( L_frame != last_L_frame || last_core_brate <= SID_2k40 ) - { - /* core Fs has changed or last frame was SID/NO_DATA -> re-initialize short-term periodogram */ - hFdCngDec->msPeriodog_ST[p] = msPeriodog[p]; - } - else - { - hFdCngDec->msPeriodog_ST[p] = (float) ( ST_PERIODOG_FACT * hFdCngDec->msPeriodog_ST[p] + ( 1 - ST_PERIODOG_FACT ) * msPeriodog[p] ); - } - } - - /* core Fs has changed -> partitions have changed -> re-calculate long-term periodogram */ - /* part L_FRAME16k L_FRAME */ - /* ... */ - /* [55] 146 146 */ - /* [56] 174 160 */ - /* [57] 210 174 */ - /* [58] 254 190 */ - /* [59] 306 210 */ - /* [60] 317 230 */ - /* [61] 253 */ - - if ( last_L_frame == L_FRAME16k && L_frame == L_FRAME ) - { - msNoiseEst[61] = msNoiseEst[58]; - msNoiseEst[60] = min( msNoiseEst[58], msNoiseEst[57] ); - msNoiseEst[59] = msNoiseEst[57]; - msNoiseEst[58] = msNoiseEst[56]; - msNoiseEst[57] = msNoiseEst[56]; - msNoiseEst[56] = min( msNoiseEst[56], msNoiseEst[55] ); - } - else if ( last_L_frame == L_FRAME && L_frame == L_FRAME16k ) - { - msNoiseEst[56] = min( msNoiseEst[56], msNoiseEst[57] ); - msNoiseEst[57] = min( msNoiseEst[58], msNoiseEst[59] ); - msNoiseEst[58] = min( msNoiseEst[60], msNoiseEst[61] ); - msNoiseEst[59] = 0.0f; - msNoiseEst[60] = 0.0f; - msNoiseEst[61] = 0.0f; - - hFdCngDec->ms_cnt_bw_up = FIRST_CNA_NOISE_UPD_FRAMES; - } - - /* Smooth with IIR filter */ - if ( !hFdCngDec->first_cna_noise_updated ) - { - if ( !VAD ) - { - /* background noise update with moving average */ - alpha = 1.0f / ( hFdCngDec->first_cna_noise_update_cnt + 1 ); - for ( p = 0; p < npart; p++ ) - { - msNoiseEst[p] = ( 1 - alpha ) * msNoiseEst[p] + alpha * msPeriodog[p]; - } - - /* check, if we reached the required number of first CNA noise update frames */ - if ( hFdCngDec->first_cna_noise_update_cnt < FIRST_CNA_NOISE_UPD_FRAMES - 1 ) - { - hFdCngDec->first_cna_noise_update_cnt++; - } - else - { - hFdCngDec->first_cna_noise_updated = 1; - if ( hFdCngDec->hFdCngCom->msFrCnt_init_counter == 0 ) - { - hFdCngDec->hFdCngCom->msFrCnt_init_counter = 1; - } - } - } - else - { - hFdCngDec->first_cna_noise_update_cnt = 0; - } - } - else - { - hFdCngDec->hFdCngCom->msFrCnt_init_counter = 1; - if ( VAD ) - { - /* no updates during active frames except for significant energy drops */ - enr_ratio = enr_tot / enr_tot0; - if ( enr_ratio < 0.5f ) - { - /* total energy significantly decreases during active frames -> downward update */ - wght = lin_interp( enr_ratio, 0.0f, 0.8f, 0.5f, 0.95f, 1 ); - for ( p = 0; p < npart; p++ ) - { - if ( msPeriodog[p] < msNoiseEst[p] ) - { - msNoiseEst[p] = wght * msNoiseEst[p] + ( 1 - wght ) * msPeriodog[p]; - } - } - } - else - { - /* energy significantly decreases in one of the larger partitions during active frames -> downward update */ - for ( p = CNA_ACT_DN_LARGE_PARTITION; p < npart; p++ ) - { - if ( hFdCngDec->msPeriodog_ST[p] < msNoiseEst[p] ) - { - msNoiseEst[p] = (float) ( CNA_ACT_DN_FACT * msNoiseEst[p] + ( 1 - CNA_ACT_DN_FACT ) * hFdCngDec->msPeriodog_ST[p] ); - } - } - } - } - else - { - - if ( bwidth >= WB && hFdCngDec->ms_last_inactive_bwidth == NB ) - { - /* bandwidth increased -> set counter for fast initilization */ - hFdCngDec->ms_cnt_bw_up = FIRST_CNA_NOISE_UPD_FRAMES; - } - hFdCngDec->ms_last_inactive_bwidth = bwidth; - /* update background noise during inactive frames */ - ptr_per = msNoiseEst; - for ( p = 0; p < npart; p++ ) - { - enr = msPeriodog[p]; - alpha = 0.95f; - /* bandwidth increased -> do fast re-initilization */ - if ( hFdCngDec->ms_cnt_bw_up > 0 && p > 55 ) - { - alpha = 1.0f / ( hFdCngDec->ms_cnt_bw_up + 1 ); - } - else if ( enr < *ptr_per && part[p] == 1 ) - { - /* faster downward update for single-bin partitions */ - alpha = 0.8f; - } - else if ( enr > 2.0f * ( *ptr_per ) ) - { - /* prevent abrupt upward updates */ - enr = 2.0f * ( *ptr_per ); - } - - /* IIR smoothing */ - *ptr_per *= alpha; - *ptr_per += ( 1 - alpha ) * enr; - ptr_per++; - } - - if ( hFdCngDec->ms_cnt_bw_up > 0 ) - { - hFdCngDec->ms_cnt_bw_up--; - } - } - } - mvr2r( msNoiseEst, hFdCngDec->msPsd, npart ); - - /* Expand partitions into bins of power spectrum */ - scalebands( msNoiseEst, part, nFFTpart, hFdCngDec->midband_shaping, nFFTpart, stopFFTbin - startBand, hFdCngDec->bandNoiseShape, 1 ); - - mvr2r( hFdCngDec->bandNoiseShape, &hFdCngDec->smoothed_psd[startBand], stopFFTbin - startBand ); - set_zero( &hFdCngDec->smoothed_psd[stopFFTbin], L_FRAME16k - stopFFTbin ); - } - else -#endif { #ifdef IVAS_CODE_CNG_FIX185_PLC_FADEOUT if ( element_mode == IVAS_CPE_MDCT && power_spectrum != NULL ) @@ -2382,12 +2008,7 @@ void perform_noise_estimation_dec_fx( hFdCngDec->msNewMinFlag, hFdCngDec->msPeriodogBuf, &( hFdCngDec->msPeriodogBufPtr ), - hFdCngDec->hFdCngCom -#ifdef IVAS_CODE_CNG - , - DEC, element_mode -#endif - ); + hFdCngDec->hFdCngCom ); /* Expand MS outputs */ expand_range( hFdCngDec->msLogNoiseEst, hFdCngDec->msNoiseEst, &hFdCngDec->msNoiseEst_exp, npart ); @@ -2427,10 +2048,6 @@ void perform_noise_estimation_dec_ivas_fx( Word16 q_shift; Word32 max_l; Word16 norm_shift; -#ifdef IVAS_CODE_CNG - PMT( "lots of code related to IVAS needs to be done " ) -#endif - /* pointer initialization */ periodog = hFdCngDec->hFdCngCom->periodog; /*Q31 - hFdCngDec->hFdCngCom->periodog_exp*/ @@ -2783,10 +2400,9 @@ void perform_noise_estimation_dec_ivas_fx( } ELSE { - Word16 tmp = s_max( sub( hFdCngDec->msPeriodog_exp, getScaleFactor32( msPeriodog, npart ) ), sub( hFdCngDec->msNoiseEst_exp, getScaleFactor32( &msNoiseEst[npart], sub( NPART_SHAPING, npart ) ) ) ); - Copy_Scale_sig32( msPeriodog, msNoiseEst, npart, sub( hFdCngDec->msPeriodog_exp, tmp ) ); /*Q31 - tmp*/ - scale_sig32( &msNoiseEst[npart], sub( NPART_SHAPING, npart ), sub( hFdCngDec->msNoiseEst_exp, tmp ) ); /*Q31 - tmp*/ - hFdCngDec->msNoiseEst_exp = tmp; + Copy32( msPeriodog, msNoiseEst, npart ); + scale_sig32( &msNoiseEst[npart], sub( NPART_SHAPING, npart ), sub( hFdCngDec->msNoiseEst_exp, hFdCngDec->msPeriodog_exp ) ); + hFdCngDec->msNoiseEst_exp = hFdCngDec->msPeriodog_exp; move16(); } @@ -3710,9 +3326,9 @@ void generate_comfort_noise_dec_fx( IF( st->hTcxCfg->last_aldo != 0 ) { - FOR( i = 0; i < sub( hFdCngCom->frameSize, NS2SA( st->sr_core, N_ZERO_MDCT_NS ) ); i++ ) + FOR( i = 0; i < hFdCngCom->frameSize - NS2SA( st->sr_core, N_ZERO_MDCT_NS ); i++ ) { - timeDomainOutput[i] = add( timeDomainOutput[i], shr_r( st->hHQ_core->old_out_LB_fx[i + NS2SA( st->sr_core, N_ZERO_MDCT_NS )], st->hHQ_core->Q_old_wtda_LB ) ); /*st->q_old_outLB_fx*/ + timeDomainOutput[i] = add( timeDomainOutput[i], shr_r( st->hHQ_core->old_out_LB_fx[i + NS2SA_FX2( st->sr_core, N_ZERO_MDCT_NS )], st->hHQ_core->Q_old_wtda_LB ) ); /*st->q_old_outLB_fx*/ move16(); } } @@ -3812,11 +3428,7 @@ void generate_comfort_noise_dec_fx( s = sub( 15 - NOISE_HEADROOM, noiseExp ); FOR( i = 0; i < N; i++ ) { -#ifdef BASOP_NOGLOB noise[i] = shr_sat( mult( noise[i], gain16 ), s ); /*Q15 - noiseExp*/ -#else - noise[i] = shr( mult( noise[i], gain16 ), s ); -#endif move16(); } @@ -3825,11 +3437,7 @@ void generate_comfort_noise_dec_fx( s = sub( 15 - NOISE_HEADROOM, ( sub( 15, Q_syn ) ) ); FOR( i = 0; i < lpcorder; i++ ) { -#ifdef BASOP_NOGLOB old_syn_pe_tmp[i] = shr_sat( old_syn_pe[i], s ); /*Q0*/ -#else - old_syn_pe_tmp[i] = shr( old_syn_pe[i], s ); -#endif move16(); } @@ -4257,9 +3865,9 @@ void generate_comfort_noise_dec_ivas_fx( IF( st->hTcxCfg->last_aldo != 0 ) { - FOR( i = 0; i < sub( hFdCngCom->frameSize, NS2SA( st->sr_core, N_ZERO_MDCT_NS ) ); i++ ) + FOR( i = 0; i < hFdCngCom->frameSize - NS2SA( st->sr_core, N_ZERO_MDCT_NS ); i++ ) { - timeDomainOutput[i] = add( timeDomainOutput[i], shr_r( st->hHQ_core->old_out_LB_fx[i + NS2SA( st->sr_core, N_ZERO_MDCT_NS )], st->hHQ_core->Q_old_wtda_LB ) ); /*st->q_old_outLB_fx*/ + timeDomainOutput[i] = add( timeDomainOutput[i], shr_r( st->hHQ_core->old_out_LB_fx[i + NS2SA_FX2( st->sr_core, N_ZERO_MDCT_NS )], st->hHQ_core->Q_old_wtda_LB ) ); /*st->q_old_outLB_fx*/ move16(); } } @@ -4359,11 +3967,7 @@ void generate_comfort_noise_dec_ivas_fx( s = sub( 15 - NOISE_HEADROOM, noiseExp ); FOR( i = 0; i < N; i++ ) { -#ifdef BASOP_NOGLOB noise[i] = shr_sat( mult( noise[i], gain16 ), s ); /*Q15 - noiseExp*/ -#else - noise[i] = shr( mult( noise[i], gain16 ), s ); -#endif move16(); } @@ -4372,11 +3976,7 @@ void generate_comfort_noise_dec_ivas_fx( s = sub( 15 - NOISE_HEADROOM, ( sub( 15, Q_syn ) ) ); FOR( i = 0; i < lpcorder; i++ ) { -#ifdef BASOP_NOGLOB old_syn_pe_tmp[i] = shr_sat( old_syn_pe[i], s ); /*Q0*/ -#else - old_syn_pe_tmp[i] = shr( old_syn_pe[i], s ); -#endif move16(); } @@ -4798,11 +4398,7 @@ void generate_masking_noise_fx( { FOR( i = 0; i < hFdCngCom->frameSize; i++ ) { -#ifdef BASOP_NOGLOB timeDomainBuffer[i] = add_sat( timeDomainBuffer[i], shr_r_sat( maskingNoise[i], -Q ) ); /*Q0*/ -#else - timeDomainBuffer[i] = add( timeDomainBuffer[i], shr_r( maskingNoise[i], -Q ) ); -#endif move16(); } } @@ -5134,318 +4730,969 @@ void generate_masking_noise_mdct_ivas_fx( return; } -#ifdef IVAS_CODE_CNG /*------------------------------------------------------------------- - * generate_stereo_masking_noise() + * initFdCngDec() * - * Generate additional comfort noise (kind of noise filling) + * Initialize an instance of type FD_CNG *-------------------------------------------------------------------*/ - -void generate_stereo_masking_noise( - float *syn, /* i/o: time-domain signal */ - Decoder_State *st, /* i/o: decoder state structure */ - STEREO_TD_DEC_DATA_HANDLE hStereoTD, /* i : TD stereo structure */ - const int16_t flag_sec_CNA, /* i : CNA flag for secondary channel */ - const int16_t fadeOut, /* i : only fade out of previous state */ - STEREO_CNG_DEC_HANDLE hStereoCng, /* i : Stereo CNG handle */ - const int16_t nchan_out /* i : number of output channels */ -) +void configureFdCngDec_ivas_fx( + HANDLE_FD_CNG_DEC hFdCngDec, /* i/o: Contains the variables related to the FD-based CNG process */ + const Word16 bwidth, /*Q0*/ + const Word32 total_brate, /*Q0*/ + const Word16 L_frame, /*Q0*/ + const Word16 last_L_frame, /*Q0*/ + const Word16 element_mode /*Q0*/ ) { - HANDLE_FD_CNG_COM hFdCngCom; - float gamma, scale, SP_ratio; - float Np[L_FRAME16k]; - float Ns[L_FRAME16k]; - float N1[L_FRAME16k]; - float N2[L_FRAME16k]; - int16_t i; - - if ( st->idchan == 0 ) - { - hFdCngCom = st->hFdCngDec->hFdCngCom; - mvr2r( hFdCngCom->olapBufferSynth2, Np, hFdCngCom->frameSize / 2 ); - mvr2r( hStereoCng->olapBufferSynth22, Ns, hFdCngCom->frameSize / 2 ); - set_f( &Np[hFdCngCom->frameSize / 2], 0.0f, hFdCngCom->frameSize / 2 ); - set_f( &Ns[hFdCngCom->frameSize / 2], 0.0f, hFdCngCom->frameSize / 2 ); + Word16 j, stopBandFR; + HANDLE_FD_CNG_COM hsCom = hFdCngDec->hFdCngCom; + + hsCom->CngBandwidth = bwidth; /*Q0*/ + move16(); + if ( EQ_16( hsCom->CngBandwidth, FB ) ) + { + hsCom->CngBandwidth = SWB; + move16(); + } + test(); + IF( NE_32( total_brate, FRAME_NO_DATA ) && NE_32( total_brate, SID_2k40 ) ) + { + hsCom->CngBitrate = total_brate; /*Q0*/ + move32(); + } + ELSE IF( EQ_32( hsCom->CngBitrate, -1 ) ) + { + /* set minimum active CBR bitrate IF CngBitrate is uninitialized */ + IF( element_mode > EVS_MONO ) + { + hsCom->CngBitrate = IVAS_13k2; + move32(); + } + ELSE + { + hsCom->CngBitrate = ACELP_7k20; + move32(); + } + } + + /* FD-CNG config for MDCT-Stereo is always the same (since for > 48 kbps only) */ + /* This may need adjustment in the future IF 2TC DTX for some mode uses MDCT-Stereo DTX for lower bitrates too */ + if ( EQ_16( element_mode, IVAS_CPE_MDCT ) ) + { + hsCom->CngBitrate = IVAS_48k; + move32(); + } + hsCom->numSlots = 16; + move32(); + + /* NB configuration */ + IF( EQ_16( bwidth, NB ) ) + { + hsCom->FdCngSetup = FdCngSetup_nb; + hsCom->numCoreBands = 16; + move16(); + hsCom->regularStopBand = 16; + move16(); + } + + /* WB configuration */ + ELSE IF( EQ_16( bwidth, WB ) ) + { + /* FFT 6.4kHz, no CLDFB */ + test(); + test(); + IF( LE_32( hsCom->CngBitrate, ACELP_8k00 ) && EQ_16( L_frame, L_FRAME ) ) + { + hsCom->FdCngSetup = FdCngSetup_wb1; + hsCom->numCoreBands = 16; + move16(); + hsCom->regularStopBand = 16; + move16(); + } + /* FFT 6.4kHz, CLDFB 8.0kHz */ + ELSE IF( LE_32( hsCom->CngBitrate, ACELP_13k20 ) || EQ_16( L_frame, L_FRAME ) ) + { + hsCom->FdCngSetup = FdCngSetup_wb2; + hsCom->numCoreBands = 16; + move16(); + hsCom->regularStopBand = 20; + move16(); + IF( EQ_16( L_frame, L_FRAME16k ) ) + { + hsCom->FdCngSetup = FdCngSetup_wb2; + hsCom->numCoreBands = 20; + move16(); + hsCom->regularStopBand = 20; + move16(); + hsCom->FdCngSetup.fftlen = 640; + move16(); + hsCom->FdCngSetup.stopFFTbin = 256; + move16(); + } + } + /* FFT 8.0kHz, no CLDFB */ + ELSE + { + hsCom->FdCngSetup = FdCngSetup_wb3; + hsCom->numCoreBands = 20; + move16(); + hsCom->regularStopBand = 20; + move16(); + } + } + + /* SWB/FB configuration */ + ELSE + { + /* FFT 6.4kHz, CLDFB 14kHz */ + IF( EQ_16( L_frame, L_FRAME ) ) + { + hsCom->FdCngSetup = FdCngSetup_swb1; + hsCom->numCoreBands = 16; + move16(); + hsCom->regularStopBand = 35; + move16(); + } + /* FFT 8.0kHz, CLDFB 16kHz */ + ELSE + { + hsCom->FdCngSetup = FdCngSetup_swb2; + hsCom->numCoreBands = 20; + move16(); + hsCom->regularStopBand = 40; + move16(); + test(); + if ( EQ_16( last_L_frame, L_FRAME ) && EQ_16( element_mode, IVAS_CPE_DFT ) ) + { + hsCom->regularStopBand = 35; + move16(); + } + } + } + + + hsCom->fftlen = hsCom->FdCngSetup.fftlen; + move16(); + hsCom->stopFFTbin = hsCom->FdCngSetup.stopFFTbin; + move16(); + + /* Configure the SID quantizer and the Comfort Noise Generator */ + + hsCom->startBand = 2; + move16(); + hsCom->stopBand = add( hsCom->FdCngSetup.sidPartitions[( hsCom->FdCngSetup.numPartitions - 1 )], 1 ); /*Q0*/ + initPartitions( hsCom->FdCngSetup.sidPartitions, hsCom->FdCngSetup.numPartitions, hsCom->startBand, hsCom->stopBand, hsCom->part, &hsCom->npart, hsCom->midband, hsCom->psize, hsCom->psize_norm, &hsCom->psize_norm_exp, hsCom->psize_inv, 0 ); + + IF( EQ_16( hsCom->stopFFTbin, 160 ) ) + { + hsCom->nFFTpart = 17; + move16(); + } + ELSE IF( EQ_16( hsCom->stopFFTbin, 256 ) ) + { + hsCom->nFFTpart = 20; + move16(); + } + ELSE + { + hsCom->nFFTpart = 21; + move16(); + } + hsCom->nCLDFBpart = sub( hsCom->npart, hsCom->nFFTpart ); /*Q0*/ + move16(); + FOR( j = 0; j < hsCom->nCLDFBpart; j++ ) + { + hsCom->CLDFBpart[j] = sub( hsCom->part[( j + hsCom->nFFTpart )], sub( hsCom->stopFFTbin, hsCom->startBand ) ); /*Q0*/ + move16(); + hsCom->CLDFBpsize_inv[j] = hsCom->psize_inv[( j + hsCom->nFFTpart )]; + move16(); + } + + stopBandFR = 40; //(Word16)floor(1000.f /*Hz*/ / 25.f /*Hz/Bin*/); + move16(); + if ( GT_16( stopBandFR, hsCom->stopFFTbin ) ) + { + stopBandFR = hsCom->stopFFTbin; /*Q0*/ + move16(); + } + + initPartitions( hsCom->FdCngSetup.shapingPartitions, hsCom->FdCngSetup.numShapingPartitions, hsCom->startBand, hsCom->stopFFTbin, hFdCngDec->part_shaping, &hFdCngDec->npart_shaping, hFdCngDec->midband_shaping, hFdCngDec->psize_shaping, hFdCngDec->psize_shaping_norm, &hFdCngDec->psize_shaping_norm_exp, hFdCngDec->psize_inv_shaping, stopBandFR ); + + hFdCngDec->nFFTpart_shaping = hFdCngDec->npart_shaping; /*Q0*/ + move16(); + + BASOP_getTables( &hsCom->olapWinAna, NULL, NULL, shr( hsCom->fftlen, 1 ) ); + BASOP_getTables( &hsCom->olapWinSyn, NULL, NULL, shr( hsCom->fftlen, 2 ) ); + + SWITCH( hsCom->fftlen ) + { + case 512: + hsCom->olapWinAna_fx = olapWinAna512_fx; /*Q30*/ + hsCom->fftSineTab_fx = NULL; + hsCom->olapWinSyn_fx = olapWinSyn256_fx; /*Q15*/ + hsCom->fftlenShift = 8; + move16(); + hsCom->fftlenFac = 32767 /*1.0 Q15*/; + move16(); + BREAK; + case 640: + hsCom->olapWinAna_fx = olapWinAna640_fx; /*Q30*/ + hsCom->fftSineTab_fx = fftSineTab640_fx; /*Q15*/ + hsCom->olapWinSyn_fx = olapWinSyn320_fx; /*Q15*/ + hsCom->fftlenShift = 9; + move16(); + hsCom->fftlenFac = 20480 /*0.625 Q15*/; + move16(); + BREAK; + default: + assert( !"Unsupported FFT length for FD-based CNG" ); + BREAK; + } + BASOP_getTables( &hsCom->olapWinAna, NULL, NULL, shr( hsCom->fftlen, 1 ) ); + BASOP_getTables( &hsCom->olapWinSyn, NULL, NULL, shr( hsCom->fftlen, 2 ) ); + hsCom->frameSize = shr( hsCom->fftlen, 1 ); + + return; +} + +/*------------------------------------------------------------------- + * FdCng_decodeSID_ivas_fx() + * + * Decode the FD-CNG bitstream + *-------------------------------------------------------------------*/ + +void FdCng_decodeSID_ivas_fx( + Decoder_State *st /* i/o: decoder state structure */ +) +{ + Word16 N; + Word32 *sidNoiseEst; + Word32 gain; + Word16 i, index; + Word32 v[32]; + Word16 indices[32]; + HANDLE_FD_CNG_COM hFdCngCom; + Word32 *invTrfMatrix_fx; + Word32 tmpRAM_fx[FDCNG_VQ_MAX_LEN][FDCNG_VQ_DCT_MAXTRUNC]; + Word16 tmp16; + + IF( st->element_mode == EVS_MONO ) + { + tmp16 = GAIN_Q_OFFSET_EVS_FX_Q0; + move16(); + } + ELSE + { + tmp16 = GAIN_Q_OFFSET_IVAS_FX_Q0; + move16(); + } + + const Word16 gain_q_offset = tmp16; /* Q0 */ + move16(); + + invTrfMatrix_fx = (Word32 *) tmpRAM_fx; /*Q31*/ + + hFdCngCom = ( st->hFdCngDec )->hFdCngCom; + + sidNoiseEst = hFdCngCom->sidNoiseEst; /*Q16*/ + + N = hFdCngCom->npart; /*Q0*/ + move16(); + gain = 0; + move32(); + hFdCngCom->sid_frame_counter = add( hFdCngCom->sid_frame_counter, 1 ); + move16(); + + /* Read bitstream */ + FOR( i = 0; i < FD_CNG_stages_37bits; i++ ) + { + indices[i] = get_next_indice_fx( st, bits_37bits[i] ); /*Q0*/ + move16(); + } + + index = get_next_indice_fx( st, 7 ); + + /* MSVQ decoder */ + + IF( st->element_mode != EVS_MONO ) + { + create_IDCT_N_Matrix_fx( invTrfMatrix_fx, FDCNG_VQ_MAX_LEN, FDCNG_VQ_DCT_MAXTRUNC, FDCNG_VQ_MAX_LEN * FDCNG_VQ_DCT_MAXTRUNC ); + msvq_dec_fx( ivas_cdk_37bits_fx, NULL, NULL, FD_CNG_stages_37bits, N, FD_CNG_maxN_37bits, indices, 1, invTrfMatrix_fx, v, NULL, 7 ); + } + ELSE + { /* Legacy EVS_MONO MSVQ tables */ + msvq_dec_fx( cdk_37bits, NULL, NULL, FD_CNG_stages_37bits, N, FD_CNG_maxN_37bits, indices, 0, NULL, v, NULL, 7 ); + } + + + /* Decode gain */ + // gain = ((float)index - gain_q_offset) / 1.5f; + gain = L_mult0( sub( index, gain_q_offset ), 21845 ); // Q15 + + /* Apply gain and undo log */ + Word16 res_exp[NPART]; + Word16 max_res_exp = 0; + move16(); + FOR( i = 0; i < N; i++ ) + { + sidNoiseEst[i] = BASOP_util_Pow2( Mpy_32_32( L_add( v[i], gain ), LOG_10_BASE_2_BY_10_Q31 ), Q16, &res_exp[i] ); /*Q31 - res_exp[i]*/ + move32(); + if ( LT_16( max_res_exp, res_exp[i] ) ) + { + max_res_exp = res_exp[i]; + move16(); + } + } + + FOR( i = 0; i < N; i++ ) + { + sidNoiseEst[i] = L_shr( sidNoiseEst[i], sub( max_res_exp, res_exp[i] ) ); /*Q31 - max_res_exp*/ + move32(); + } + + hFdCngCom->sidNoiseEstExp = max_res_exp; + move16(); + + /* NB last band energy compensation */ + + IF( hFdCngCom->CngBandwidth == NB ) + { + sidNoiseEst[( N - 1 )] = Mpy_32_16_1( sidNoiseEst[( N - 1 )], NB_LAST_BAND_SCALE ); /*Q31 - max_res_exp*/ + move32(); + } + + test(); + IF( EQ_16( hFdCngCom->CngBandwidth, SWB ) && LE_32( hFdCngCom->CngBitrate, ACELP_13k20 ) ) + { + sidNoiseEst[( N - 1 )] = Mpy_32_16_1( sidNoiseEst[( N - 1 )], SWB_13k2_LAST_BAND_SCALE ); /*Q31 - max_res_exp*/ + move32(); + } + + scalebands( sidNoiseEst, hFdCngCom->part, hFdCngCom->npart, hFdCngCom->midband, hFdCngCom->nFFTpart, sub( hFdCngCom->stopBand, hFdCngCom->startBand ), hFdCngCom->cngNoiseLevel, 1 ); + hFdCngCom->cngNoiseLevelExp = hFdCngCom->sidNoiseEstExp; + move16(); + + lpc_from_spectrum( hFdCngCom, hFdCngCom->startBand, hFdCngCom->stopFFTbin, st->preemph_fac ); + + return; +} + +/*------------------------------------------------------------------- + * generate_masking_noise_ivas_fx() + * + * Generate additional comfort noise (kind of noise filling) + *-------------------------------------------------------------------*/ + +void generate_masking_noise_ivas_fx( + Word32 *timeDomainBuffer, /* i/o: time-domain signal Q31 - *exp_out*/ + Word16 *exp_out, /* o : time-domain signal exp */ + HANDLE_FD_CNG_COM hFdCngCom, /* i/o: FD_CNG structure containing all buffers and variables */ + const Word16 length, /* i : frame size Q0*/ + const Word16 core, /* i : core Q0*/ + const Word16 return_noise, /* i : noise is returned instead of added Q0*/ + const Word16 secondary, /* i : flag to indicate secondary noise generation Q0*/ + const Word16 element_mode, /* i : element mode Q0*/ + STEREO_CNG_DEC_HANDLE hStereoCng, /* i : stereo CNG handle */ + const Word16 nchan_out /* i : number of output channels Q0*/ +) +{ + Word32 *cngNoiseLevel_fx = hFdCngCom->cngNoiseLevel; + Word32 *ptr_level_fx = cngNoiseLevel_fx; + Word32 *fftBuffer_fx = hFdCngCom->fftBuffer; + Word16 i; + Word32 maskingNoise_fx[L_FRAME16k]; + Word32 *ptr_r_fx; + Word32 *ptr_i_fx; + Word16 startBand; + Word16 *seed = &( hFdCngCom->seed ); + Word32 scale_fx; + Word16 shift; + scale_fx = 0x40000000; // 1.0 in Q30 + move32(); + startBand = hFdCngCom->startBand; /*Q0*/ + move16(); + shift = getScaleFactor32( hFdCngCom->cngNoiseLevel, FFTCLDFBLEN ); + if ( LT_16( sub( hFdCngCom->cngNoiseLevelExp, shift ), 4 ) ) + { + shift = sub( hFdCngCom->cngNoiseLevelExp, 4 ); /*Q0*/ + } + scale_sig32( hFdCngCom->cngNoiseLevel, FFTCLDFBLEN, shift ); /*hFdCngCom->cngNoiseLevelExp*/ + hFdCngCom->cngNoiseLevelExp = sub( hFdCngCom->cngNoiseLevelExp, shift ); + move16(); + + /* skip noise generating if level is very low, to avoid problems with possibly running into denormals */ + *exp_out = Q15; + move16(); + IF( GT_16( hFdCngCom->likelihood_noisy_speech, DELTA_MASKING_NOISE_Q15 ) ) + { + IF( NE_16( core, AMR_WB_CORE ) ) + { + /* Compute additional CN level */ + FOR( i = 0; i < SIZE_SCALE_TABLE_CN; i++ ) + { + test(); + test(); + if ( EQ_16( hFdCngCom->CngBandwidth, scaleTable_cn_only[i].bwmode ) && + GE_32( hFdCngCom->CngBitrate, scaleTable_cn_only[i].bitrateFrom ) && + LT_32( hFdCngCom->CngBitrate, scaleTable_cn_only[i].bitrateTo ) ) + { + BREAK; + } + } + + scale_fx = L_deposit_h( scaleTable_cn_only[i].scale_ivas ); /* Q30 */ + } + ELSE + { + /* Compute additional CN level */ + FOR( i = 0; i < SIZE_SCALE_TABLE_CN_AMRWB; i++ ) + { + if ( GE_32( hFdCngCom->CngBitrate, scaleTable_cn_only_amrwbio[i][0] ) ) + { + BREAK; + } + } + + IF( LT_16( i, SIZE_SCALE_TABLE_CN_AMRWB ) ) + { + scale_fx = L_deposit_h( scaleTable_cn_only_amrwbio[i][1] ); /* Q30 */ + } + ELSE + { + scale_fx = 0; + move32(); + } + } + + /* Exclude clean speech */ + scale_fx = Mpy_32_16_1( scale_fx, hFdCngCom->likelihood_noisy_speech ); // Q30 + + /* Generate Gaussian random noise in real and imaginary parts of the FFT bins + Amplitudes are adjusted to the estimated noise level cngNoiseLevel_flt in each bin */ + IF( startBand == 0 ) + { + rand_gauss_fx( &fftBuffer_fx[0], seed, *exp_out ); // Q15 + ptr_r_fx = fftBuffer_fx + 2; /*Q31 - hFdCngCom->fftBuffer_exp*/ + Word16 exp1; + exp1 = add( hFdCngCom->cngNoiseLevelExp, 1 ); + Word32 mpy1; + mpy1 = Sqrt32( Mpy_32_32( scale_fx, *ptr_level_fx ), &exp1 ); /*Q31 - exp1*/ + mpy1 = L_shl( mpy1, exp1 ); // Q31 + fftBuffer_fx[0] = Mpy_32_32( fftBuffer_fx[0], mpy1 ); /* DC component in FFT */ // Q = Q15 + ptr_level_fx++; + } + ELSE + { + fftBuffer_fx[0] = 0; + move32(); + set32_fx( fftBuffer_fx + 2, 0, shl( sub( startBand, 1 ), 1 ) ); + ptr_r_fx = fftBuffer_fx + shl( startBand, 1 ); /*Q31 - hFdCngCom->fftBuffer_exp*/ + } + ptr_i_fx = ptr_r_fx + 1; + FOR( ; ptr_level_fx < cngNoiseLevel_fx + hFdCngCom->stopFFTbin - startBand; ptr_level_fx++ ) + { + /* Real part in FFT bins */ + rand_gauss_fx( ptr_r_fx, seed, *exp_out ); // Q15 + Word16 exp2; + exp2 = add( hFdCngCom->cngNoiseLevelExp, 1 ); + Word32 mpy2; + mpy2 = Sqrt32( L_shr( Mpy_32_32( scale_fx, *ptr_level_fx ), 1 ), &exp2 ); /*Q31 - exp2*/ + ( *ptr_r_fx ) = L_shl( Mpy_32_32( *ptr_r_fx, mpy2 ), exp2 ); // Q = Q15 + move32(); + ptr_r_fx += 2; + + /* Imaginary part in FFT bins */ + rand_gauss_fx( ptr_i_fx, seed, *exp_out ); // Q15 + ( *ptr_i_fx ) = L_shl( Mpy_32_32( *ptr_i_fx, mpy2 ), exp2 ); // Q = Q15 + ptr_i_fx += 2; + } + + /* Remaining FFT bins are set to zero */ + set32_fx( fftBuffer_fx + shl( hFdCngCom->stopFFTbin, 1 ), 0, sub( hFdCngCom->fftlen, shl( hFdCngCom->stopFFTbin, 1 ) ) ); + /* Nyquist frequency is discarded */ + fftBuffer_fx[1] = 0; + move32(); + } + ELSE + { + /* very low level case - update random seeds and reset FFT buffer; don't fully skip SynthesisSTFT_flt(), because of the buffer updates done there... */ + generate_masking_noise_update_seed_fx( hFdCngCom ); + + set32_fx( fftBuffer_fx, 0, hFdCngCom->fftlen ); + } + + /* Perform STFT synthesis */ + IF( secondary ) + { + SynthesisSTFT_fx( fftBuffer_fx, maskingNoise_fx, hStereoCng->olapBufferSynth22_32fx, hFdCngCom->olapWinSyn_fx, 0, hFdCngCom, element_mode, nchan_out ); + } + ELSE + { + SynthesisSTFT_fx( fftBuffer_fx, maskingNoise_fx, hFdCngCom->olapBufferSynth2_fx, hFdCngCom->olapWinSyn_fx, 0, hFdCngCom, element_mode, nchan_out ); + } + *exp_out = sub( *exp_out, Q9 ); + move16(); + + /* Add some comfort noise on top of decoded signal */ + IF( return_noise ) + { + Copy32( maskingNoise_fx, timeDomainBuffer, s_min( hFdCngCom->frameSize, length ) ); /*Q31 - *exp_out*/ + } + ELSE + { + v_add_fixed( maskingNoise_fx, timeDomainBuffer, timeDomainBuffer, s_min( hFdCngCom->frameSize, length ), 0 ); /*Q31 - *exp_out*/ + } + + return; +} + +/*------------------------------------------------------------------- + * generate_stereo_masking_noise_fx() + * + * Generate additional comfort noise (kind of noise filling) + *-------------------------------------------------------------------*/ + +void generate_stereo_masking_noise_fx( + Word16 *syn, /* i/o: time-domain signal Q_syn*/ + Word16 Q_syn, + Decoder_State *st, /* i/o: decoder state structure */ + STEREO_TD_DEC_DATA_HANDLE hStereoTD, /* i : TD stereo structure */ + const Word16 flag_sec_CNA, /* i : CNA flag for secondary channel Q0*/ + const Word16 fadeOut, /* i : only fade out of previous state Q0*/ + STEREO_CNG_DEC_HANDLE hStereoCng, /* i : Stereo CNG handle */ + const Word16 nchan_out /* i : number of output channels Q0*/ +) +{ + HANDLE_FD_CNG_COM hFdCngCom; + Word32 gamma_fx, scale_fx /*, SP_ratio_fx needs to be integrated*/; + Word32 Np_fx[L_FRAME16k]; + Word32 Ns_fx[L_FRAME16k]; + Word32 N1_fx[L_FRAME16k]; + Word32 N2_fx[L_FRAME16k]; + Word16 N1_fx_exp, N2_fx_exp; + Word16 i; + + IF( st->idchan == 0 ) + { + hFdCngCom = st->hFdCngDec->hFdCngCom; +#ifdef FIX_ISSUE_1237 + Copy_Scale_sig_16_32_no_sat( hStereoCng->olapBufferSynth22_fx, Ns_fx, shr( hFdCngCom->frameSize, 1 ), sub( Q6, st->Q_syn ) ); /*Q6*/ +#else + Copy_Scale_sig_16_32_DEPREC( hStereoCng->olapBufferSynth22_fx, Ns_fx, shr( hFdCngCom->frameSize, 1 ), sub( Q6, st->Q_syn ) ); /*Q6*/ +#endif + Copy32( hFdCngCom->olapBufferSynth2_fx, Np_fx, shr( hFdCngCom->frameSize, 1 ) ); /*st->Q_syn*/ - if ( !fadeOut ) + set32_fx( &Np_fx[( hFdCngCom->frameSize / 2 )], 0, shr( hFdCngCom->frameSize, 1 ) ); + set32_fx( &Ns_fx[( hFdCngCom->frameSize / 2 )], 0, shr( hFdCngCom->frameSize, 1 ) ); + + IF( !fadeOut ) { - generate_masking_noise_fx( N1, hFdCngCom, hFdCngCom->frameSize, 0, 1, 0, st->element_mode, hStereoCng, nchan_out ); +#ifdef FIX_ISSUE_1237 + Copy_Scale_sig_16_32_no_sat( hStereoCng->olapBufferSynth22_fx, hStereoCng->olapBufferSynth22_32fx, hFdCngCom->fftlen, sub( Q15, st->Q_syn ) ); /*Q15*/ +#else + Copy_Scale_sig_16_32_DEPREC( hStereoCng->olapBufferSynth22_fx, hStereoCng->olapBufferSynth22_32fx, hFdCngCom->fftlen, sub( Q15, st->Q_syn ) ); /*Q15*/ +#endif + generate_masking_noise_ivas_fx( N1_fx, &N1_fx_exp, hFdCngCom, hFdCngCom->frameSize, 0, 1, 0, st->element_mode, hStereoCng, nchan_out ); // N1_fx Q6 /* Generate masking noise for secondary channel */ - if ( flag_sec_CNA ) + IF( flag_sec_CNA ) { - generate_masking_noise_fx( N2, hFdCngCom, hFdCngCom->frameSize, 0, 1, 1, st->element_mode, hStereoCng, nchan_out ); - gamma = hStereoCng->c_PS_LT * hStereoCng->c_PS_LT; - scale = 1.0f; - if ( gamma < 0.9f ) + generate_masking_noise_ivas_fx( N2_fx, &N2_fx_exp, hFdCngCom, hFdCngCom->frameSize, 0, 1, 1, st->element_mode, hStereoCng, nchan_out ); // N2_fx Q6 + gamma_fx = L_shr( Mpy_32_32( hStereoCng->c_PS_LT_fx, hStereoCng->c_PS_LT_fx ), 1 ); /*Q30*/ + scale_fx = ONE_IN_Q30; + move32(); + IF( LT_32( gamma_fx, 966367642 /* 0.9 in Q30 */ ) ) { - gamma = gamma / ( 1 - gamma ); - gamma = (float) sqrt( gamma + 1 ) - (float) sqrt( gamma ); - scale = 1.0f / (float) sqrt( 1 + gamma * gamma ); + Word16 exp_gamma; + exp_gamma = 0; + move16(); + Word16 divisor1; + divisor1 = Inv16( (Word16) L_shr( L_sub( ONE_IN_Q30, gamma_fx ), Q15 ), &exp_gamma ); // Q15-exp_gamma + gamma_fx = L_shl( Mpy_32_16_1( gamma_fx, divisor1 ), exp_gamma ); // Q30 + Word16 exp_gamma1, exp_gamma2, exp_gamma3; + exp_gamma1 = Q1; + exp_gamma2 = Q1; + exp_gamma3 = Q1; + move16(); + move16(); + move16(); + gamma_fx = Sqrt32( L_add( gamma_fx, ONE_IN_Q30 ), &exp_gamma1 ); /*Q31 - exp_gamma1*/ + Word32 temp; + temp = Sqrt32( gamma_fx, &exp_gamma2 ); // Q31-exp_gamma1 + gamma_fx = L_sub( gamma_fx, L_shl( temp, sub( exp_gamma2, exp_gamma1 ) ) ); // Q31-exp_gamma1 + gamma_fx = L_shl( gamma_fx, sub( exp_gamma1, Q1 ) ); // Q30 + Word32 divisor2; + divisor2 = Sqrt32( L_add( ONE_IN_Q30, L_shl( Mpy_32_32( gamma_fx, gamma_fx ), Q1 ) ), &exp_gamma3 ); // Q31 - exp_gamma3 + scale_fx = L_shl( divide3232( ONE_IN_Q30, divisor2 ), add( Q15, exp_gamma3 ) ); // Q30 } - else + ELSE { - gamma = 0.0f; + gamma_fx = 0; + move16(); } - for ( i = 0; i < 2 * hFdCngCom->frameSize / 4; i++ ) + FOR( i = 0; i < 2 * hFdCngCom->frameSize / 4; i++ ) { - Np[i] += scale * ( N1[i] + gamma * N2[i] ); - Ns[i] += scale * sign( hStereoCng->c_PS_LT ) * ( N1[i] - gamma * N2[i] ); + Np_fx[i] = L_add( Np_fx[i], + Mpy_32_32( scale_fx, L_shl( L_add( N1_fx[i], Mpy_32_32( gamma_fx, L_shl( N2_fx[i], Q1 ) ) ), Q1 ) ) ); // Q6 + move32(); + Word32 add2; + add2 = Mpy_32_32( scale_fx, L_shl( L_sub( N1_fx[i], Mpy_32_32( gamma_fx, L_shl( N2_fx[i], Q1 ) ) ), Q1 ) ); // Q6 + if ( hStereoCng->c_PS_LT_fx < 0 ) + { + add2 = L_negate( add2 ); /*Q6*/ + } + Ns_fx[i] = L_add( Ns_fx[i], add2 ); /*Q6*/ + move32(); } - for ( ; i < hFdCngCom->frameSize; i++ ) + FOR( ; i < hFdCngCom->frameSize; i++ ) { - Np[i] = scale * ( N1[i] + gamma * N2[i] ); - Ns[i] = scale * sign( hStereoCng->c_PS_LT ) * ( N1[i] - gamma * N2[i] ); + Np_fx[i] = Mpy_32_32( scale_fx, L_shl( L_add( N1_fx[i], Mpy_32_32( gamma_fx, L_shl( N2_fx[i], Q1 ) ) ), Q1 ) ); // Q6 + move32(); + Ns_fx[i] = Mpy_32_32( scale_fx, L_shl( L_sub( N1_fx[i], Mpy_32_32( gamma_fx, L_shl( N2_fx[i], Q1 ) ) ), Q1 ) ); // Q6 + move32(); + IF( hStereoCng->c_PS_LT_fx < 0 ) + { + Ns_fx[i] = L_negate( Ns_fx[i] ); + move32(); + } } - scale *= (float) ( hFdCngCom->fftlen / 2 ); - for ( i = 0; i < hFdCngCom->frameSize / 2; i++ ) + /* Below code to be converted */ + Word32 scale_fx_tmp = Mpy_32_32( scale_fx, L_shl( shr( hFdCngCom->fftlen, 1 ), Q22 ) ); // Q21 + FOR( i = 0; i < shr( hFdCngCom->frameSize, 1 ); i++ ) { - hFdCngCom->olapBufferSynth2[i] = scale * ( hFdCngCom->olapBufferSynth2[i + 5 * hFdCngCom->frameSize / 4] + gamma * hStereoCng->olapBufferSynth22[i + 5 * hFdCngCom->frameSize / 4] ); - hStereoCng->olapBufferSynth22[i] = sign( hStereoCng->c_PS_LT ) * scale * ( hFdCngCom->olapBufferSynth2[i + 5 * hFdCngCom->frameSize / 4] - gamma * hStereoCng->olapBufferSynth22[i + 5 * hFdCngCom->frameSize / 4] ); + hFdCngCom->olapBufferSynth2[i] = (Word16) L_shr( Mpy_32_32( scale_fx_tmp, + L_add( L_shr( hFdCngCom->olapBufferSynth2[( i + ( 5 * ( hFdCngCom->frameSize / 4 ) ) )], Q15 ), + Mpy_32_16_1( gamma_fx, hStereoCng->olapBufferSynth22_fx[( i + ( 5 * ( hFdCngCom->frameSize / 4 ) ) )] ) ) ), + Q14 ); // Q_olap + move16(); + hStereoCng->olapBufferSynth22_fx[i] = (Word16) L_shr( Mpy_32_32( scale_fx_tmp, + L_sub( L_shr( hFdCngCom->olapBufferSynth2[( i + ( 5 * ( hFdCngCom->frameSize / 4 ) ) )], Q15 ), + Mpy_32_16_1( gamma_fx, hStereoCng->olapBufferSynth22_fx[( i + ( 5 * ( hFdCngCom->frameSize / 4 ) ) )] ) ) ), + Q14 ); // Q_olap + move16(); } } - else + ELSE { - for ( i = 0; i < hFdCngCom->frameSize / 2; i++ ) + FOR( i = 0; i < shr( hFdCngCom->frameSize, 1 ); i++ ) { - Np[i] += N1[i]; + Np_fx[i] = L_add( Np_fx[i], N1_fx[i] ); // Q6 + move32(); } - mvr2r( &N1[hFdCngCom->frameSize / 2], &Np[hFdCngCom->frameSize / 2], hFdCngCom->frameSize / 2 ); - scale = (float) ( hFdCngCom->fftlen / 2 ); - for ( i = 0; i < hFdCngCom->frameSize; i++ ) + Copy32( &N1_fx[( hFdCngCom->frameSize / 2 )], &Np_fx[( hFdCngCom->frameSize / 2 )], shr( hFdCngCom->frameSize, 1 ) ); /*Q6*/ + scale_fx = L_shl( shr( hFdCngCom->fftlen, 1 ), Q22 ); // Q21 + FOR( i = 0; i < hFdCngCom->frameSize; i++ ) { - hFdCngCom->olapBufferSynth2[i] = scale * hFdCngCom->olapBufferSynth2[i + 5 * hFdCngCom->frameSize / 4]; + hFdCngCom->olapBufferSynth2[i] = (Word16) L_shr( Mpy_32_16_1( scale_fx, hFdCngCom->olapBufferSynth2[( i + ( 5 * ( hFdCngCom->frameSize / 4 ) ) )] ), Q6 ); // Q_olap + move16(); } } + + Copy_Scale_sig_32_16( hStereoCng->olapBufferSynth22_32fx, hStereoCng->olapBufferSynth22_fx, hFdCngCom->fftlen, sub( st->Q_syn, 15 ) ); /*st->Q_syn*/ } - else + ELSE { - set_f( hFdCngCom->olapBufferSynth2, 0.0f, hFdCngCom->frameSize / 2 ); - set_f( hStereoCng->olapBufferSynth22, 0.0f, hFdCngCom->frameSize / 2 ); + set16_fx( hFdCngCom->olapBufferSynth2, 0, shr( hFdCngCom->frameSize, 1 ) ); + set16_fx( hStereoCng->olapBufferSynth22_fx, 0, shr( hFdCngCom->frameSize, 1 ) ); } - if ( flag_sec_CNA ) + IF( flag_sec_CNA ) { - mvr2r( Ns, hStereoCng->maskingNoiseS, hFdCngCom->frameSize ); + Copy_Scale_sig_32_16( Ns_fx, hStereoCng->maskingNoiseS_fx, hFdCngCom->frameSize, 0 ); // Q6 hStereoCng->enableSecCNA = 1; + move16(); } - else + ELSE { - set_f( hStereoCng->olapBufferSynth22, 0.0f, hFdCngCom->frameSize ); + set16_fx( hStereoCng->olapBufferSynth22_fx, 0, hFdCngCom->frameSize ); } /* add masking noise */ - v_add( Np, syn, syn, hFdCngCom->frameSize ); + FOR( i = 0; i < hFdCngCom->frameSize; i++ ) + { + syn[i] = add( syn[i], (Word16) L_shr( Np_fx[i], sub( Q16 + Q6, Q_syn ) ) ); // Q_syn + move16(); + } } - else if ( hStereoCng->enableSecCNA ) + ELSE IF( hStereoCng->enableSecCNA ) { - SP_ratio = hStereoTD->SP_ratio_LT; /* Use long-term SP ratio based on L/R synthesis */ + Word16 SP_ratio_fx; + SP_ratio_fx = extract_h( hStereoTD->SP_ratio_LT_fx ); /* Use long-term SP ratio based on L/R synthesis Q15*/ + Word16 prevSP_ratio_fx; + prevSP_ratio_fx = hStereoTD->prevSP_ratio_fx; /* Use long-term SP ratio based on L/R synthesis Q15*/ + move16(); /* scale and add masking noise */ - for ( i = 0; i < *hStereoCng->frameSize / 4; i++ ) + FOR( i = 0; i < shr( *hStereoCng->frameSize, 2 ); i++ ) { - scale = ( ( hStereoTD->prevSP_ratio * ( *hStereoCng->frameSize / 4 - (float) i ) + SP_ratio * (float) i ) / ( *hStereoCng->frameSize / 4 ) ); - syn[i] += scale * hStereoCng->maskingNoiseS[i]; + Word16 s; + Word16 scale_fx_tmp; + scale_fx_tmp = BASOP_Util_Divide3216_Scale( L_add( L_mult0( prevSP_ratio_fx, sub( shr( *hStereoCng->frameSize, 2 ), i ) ), L_mult0( SP_ratio_fx, i ) ), shr( *hStereoCng->frameSize, 2 ), &s ); // Q15 + scale_fx_tmp = shl( scale_fx_tmp, s ); + syn[i] = add( syn[i], mult( scale_fx_tmp, shr( hStereoCng->maskingNoiseS_fx[i], sub( Q6, Q_syn ) ) ) ); /*Q_syn*/ + move16(); } - for ( ; i < *hStereoCng->frameSize / 2; i++ ) + FOR( ; i < *hStereoCng->frameSize / 2; i++ ) { - syn[i] += SP_ratio * hStereoCng->maskingNoiseS[i]; + syn[i] = add( syn[i], mult( SP_ratio_fx, shr( hStereoCng->maskingNoiseS_fx[i], sub( Q6, Q_syn ) ) ) ); /*Q_syn*/ + move16(); } - for ( ; i < *hStereoCng->frameSize; i++ ) + FOR( ; i < *hStereoCng->frameSize; i++ ) { - syn[i] += SP_ratio * hStereoCng->maskingNoiseS[i]; + syn[i] = add( syn[i], mult( SP_ratio_fx, shr( hStereoCng->maskingNoiseS_fx[i], sub( Q6, Q_syn ) ) ) ); /*Q_syn*/ + move16(); } - hStereoTD->prevSP_ratio = SP_ratio; + hStereoTD->prevSP_ratio_fx = extract_h( hStereoTD->SP_ratio_LT_fx ); /*Q15*/ + move16(); } return; } - -/*------------------------------------------------------------------- - * generate_masking_noise_hf_cldfb() - * - * Generate additional comfort noise (kind of noise filling) - *-------------------------------------------------------------------*/ - -void generate_masking_noise_dirac( - HANDLE_FD_CNG_COM hFdCngCom, /* i/o: FD_CNG structure containing all buffers and variables */ - HANDLE_CLDFB_FILTER_BANK h_cldfb, /* i : filterbank state */ - float *tdBuffer, /* i/o: time-domain signal, if NULL no LB-CNA */ - float *Cldfb_RealBuffer, /* o : CLDFD real buffer */ - float *Cldfb_ImagBuffer, /* o : CLDFD imaginary buffer */ - const int16_t slot_index, /* i : CLDFB slot index */ - const int16_t cna_flag, /* i : CNA flag for LB and HB */ - const int16_t fd_cng_flag /* i : FD-CNG flag for HB */ +void generate_masking_noise_lb_dirac_fx( + HANDLE_FD_CNG_COM hFdCngCom, /* i/o: FD_CNG structure containing all buffers and variables */ + Word32 *tdBuffer, /* i/o: time-domain signal, if NULL no LB-CNA Q11*/ + const Word16 nCldfbTs, /* i : number of CLDFB slots that will be rendered Q0*/ + const Word16 cna_flag /* i : CNA flag for LB and HB Q0*/ ) { - int16_t i; - float *cngNoiseLevel = hFdCngCom->cngNoiseLevel; - float *fftBuffer = hFdCngCom->fftBuffer; - float *ptr_r; - float *ptr_i; - float *ptr_level; - int16_t *seed = &( hFdCngCom->seed ); - float scale; + Word16 i; + Word32 *cngNoiseLevel = hFdCngCom->cngNoiseLevel; /*hFdCngCom->cngNoiseLevelExp*/ + Word32 *fftBuffer = hFdCngCom->fftBuffer; /*hFdCngCom->fftBuffer_exp*/ + Word32 *ptr_r; + Word32 *ptr_i; + Word32 *ptr_level; + Word16 *seed = &( hFdCngCom->seed ); + Word32 scale; + Word16 n_samples_out, n_samples_start, n_samples_out_loop; - wmops_sub_start( "fd_cng_dirac" ); + push_wmops( "fd_cng_dirac" ); /* Init */ - scale = 0.f; - - /* Resample CLDFB memories if necessary*/ - if ( ( h_cldfb->no_channels * h_cldfb->no_col ) != hFdCngCom->frameSize ) - { - resampleCldfb( h_cldfb, hFdCngCom->frameSize * FRAMES_PER_SEC ); - } - - set_zero( Cldfb_RealBuffer, CLDFB_NO_CHANNELS_MAX ); - set_zero( Cldfb_ImagBuffer, CLDFB_NO_CHANNELS_MAX ); - + scale = 0; + move32(); + n_samples_out = i_mult( shr( hFdCngCom->frameSize, 4 ), nCldfbTs ); + n_samples_start = 0; + move16(); + Word16 exp_out = Q11; + move16(); /*LB CLDFB - CNA from STFT*/ -#ifdef DEBUG_MODE_DIRAC - { - int16_t tmp_s; - tmp_s = (int16_t) ( 32768.f * 0.5f * hFdCngCom->likelihood_noisy_speech * cna_flag + 0.5f ); - dbgwrite( &tmp_s, sizeof( int16_t ), 1, hFdCngCom->frameSize / 16, "./res/ivas_dirac_likelihood_noisy.pcm" ); - } -#endif - if ( cna_flag ) + IF( cna_flag ) { /* skip noise generating if level is very low, to avoid problems with possibly running into denormals */ - if ( hFdCngCom->likelihood_noisy_speech > DELTA_MASKING_NOISE ) + IF( GT_16( hFdCngCom->likelihood_noisy_speech, DELTA_MASKING_NOISE_Q15 ) ) { /* Compute additional CN level */ - for ( i = 0; i < 15; i++ ) + FOR( i = 0; i < 15; i++ ) { - if ( ( hFdCngCom->CngBandwidth == scaleTable_cn_dirac[i].bwmode ) && - ( hFdCngCom->CngBitrate >= scaleTable_cn_dirac[i].bitrateFrom ) && - ( hFdCngCom->CngBitrate < scaleTable_cn_dirac[i].bitrateTo ) ) + test(); + test(); + if ( ( EQ_16( hFdCngCom->CngBandwidth, scaleTable_cn_dirac[i].bwmode ) ) && + GE_32( hFdCngCom->CngBitrate, scaleTable_cn_dirac[i].bitrateFrom ) && + LT_32( hFdCngCom->CngBitrate, scaleTable_cn_dirac[i].bitrateTo ) ) { - break; + BREAK; } } - scale = (float) pow( 10.f, -scaleTable_cn_dirac[i].scale / 10.f ) - 1.f; - scale *= hFdCngCom->likelihood_noisy_speech; + scale = L_deposit_h( scaleTable_cn_dirac[i].scale_ivas ); /* Q30 */ + scale = Mpy_32_16_1( scale, hFdCngCom->likelihood_noisy_speech ); /* Q30 */ } } /* LB CLDFB - CNA from STFT: CNA applied only in channel 0*/ - if ( cna_flag && tdBuffer != NULL ) + test(); + IF( cna_flag && tdBuffer != NULL ) { - if ( scale != 0 ) + WHILE( n_samples_out > 0 ) { - /*Generate LF comfort noise only at first slot, for the whole frame*/ - if ( slot_index == 0 ) + n_samples_out_loop = s_min( hFdCngCom->frameSize, n_samples_out ); + IF( scale != 0 ) { - ptr_level = cngNoiseLevel; + /*Generate LF comfort noise only at first slot, for the whole frame*/ + ptr_level = cngNoiseLevel; /*hFdCngCom->cngNoiseLevelExp*/ /* Generate Gaussian random noise in real and imaginary parts of the FFT bins - Amplitudes are adjusted to the estimated noise level cngNoiseLevel in each bin */ - if ( hFdCngCom->startBand == 0 ) + Amplitudes are adjusted to the estimated noise level cngNoiseLevel_flt in each bin */ + IF( EQ_16( hFdCngCom->startBand, 0 ) ) { - rand_gauss( &fftBuffer[0], seed ); - ptr_r = fftBuffer + 2; - fftBuffer[0] *= (float) sqrt( scale * *ptr_level ); /* DC component in FFT */ + rand_gauss_fx( &fftBuffer[0], seed, exp_out ); + ptr_r = fftBuffer + 2; /*hFdCngCom->fftBuffer_exp*/ + + Word16 exp2 = sub( 31, hFdCngCom->cngNoiseLevelExp ); + Word32 sqr = Sqrt32( L_shr( Mpy_32_32( scale, *ptr_level ), 1 ), &exp2 ); /* DC component in FFT Q31 - exp2*/ + sqr = L_shl( sqr, exp2 ); /*Q31*/ + fftBuffer[0] = Mpy_32_32( fftBuffer[0], sqr ); /* DC component in FFT Q31 - hFdCngCom->fftBuffer_exp*/ + move32(); ptr_level++; } - else + ELSE { - fftBuffer[0] = 0.f; - set_f( fftBuffer + 2, 0.0f, 2 * ( hFdCngCom->startBand - 1 ) ); - ptr_r = fftBuffer + 2 * hFdCngCom->startBand; + fftBuffer[0] = 0; + move32(); + set32_fx( fftBuffer + 2, 0, shl( sub( hFdCngCom->startBand, 1 ), 1 ) ); + ptr_r = fftBuffer + shl( hFdCngCom->startBand, 1 ); /*hFdCngCom->fftBuffer_exp*/ } - ptr_i = ptr_r + 1; + ptr_i = ptr_r + 1; /*hFdCngCom->fftBuffer_exp*/ - for ( ; ptr_level < cngNoiseLevel + hFdCngCom->stopFFTbin - hFdCngCom->startBand; ptr_level++ ) + FOR( ; ptr_level < cngNoiseLevel + sub( hFdCngCom->stopFFTbin, hFdCngCom->startBand ); ptr_level++ ) { - /* Real part in FFT bins */ - rand_gauss( ptr_r, seed ); - ( *ptr_r ) *= (float) sqrt( ( scale * *ptr_level ) * 0.5f ); + rand_gauss_fx( ptr_r, seed, exp_out ); + Word16 exp2 = hFdCngCom->cngNoiseLevelExp; + Word32 mpy2 = Sqrt32( Mpy_32_32( scale, *ptr_level ), &exp2 ); /*Q31 - exp2*/ + ( *ptr_r ) = L_shl( Mpy_32_32( *ptr_r, mpy2 ), exp2 ); /*Q31 - hFdCngCom->fftBuffer_exp*/ + move32(); ptr_r += 2; + /* Imaginary part in FFT bins */ - rand_gauss( ptr_i, seed ); - ( *ptr_i ) *= (float) sqrt( ( scale * *ptr_level ) * 0.5f ); + rand_gauss_fx( ptr_i, seed, exp_out ); + ( *ptr_i ) = L_shl( Mpy_32_32( *ptr_i, mpy2 ), exp2 ); /*Q31 - hFdCngCom->fftBuffer_exp*/ + move32(); ptr_i += 2; } - /* Remaining FFT bins are set to zero */ - set_f( fftBuffer + 2 * hFdCngCom->stopFFTbin, 0.0f, hFdCngCom->fftlen - 2 * hFdCngCom->stopFFTbin ); + set32_fx( fftBuffer + shl( hFdCngCom->stopFFTbin, 1 ), 0, sub( hFdCngCom->fftlen, shl( hFdCngCom->stopFFTbin, 1 ) ) ); /* Nyquist frequency is discarded */ - fftBuffer[1] = 0.f; + fftBuffer[1] = 0; + move32(); /* Perform STFT synthesis */ - SynthesisSTFT( fftBuffer, tdBuffer, hFdCngCom->olapBufferSynth2, hFdCngCom->olapWinSyn, 0, hFdCngCom, X, Y, -1, -1 ); - -#ifdef DEBUG_MODE_DIRAC - { - int16_t tmp[1000]; - - for ( i = 0; i < hFdCngCom->frameSize; i++ ) - { - tmp[i] = (int16_t) ( tdBuffer[i] + 0.5f ); - } - dbgwrite( tmp, sizeof( int16_t ), hFdCngCom->frameSize, 1, "./res/ivas_dirac_cna_fft.pcm" ); - } -#endif + SynthesisSTFT_dirac_fx( fftBuffer, tdBuffer + n_samples_start, hFdCngCom->olapBufferSynth2_fx, hFdCngCom->olapWinSyn_fx, n_samples_out_loop, hFdCngCom ); + scale_sig32( tdBuffer + n_samples_start, n_samples_out_loop, Q9 ); // Q2 -> Q11 } - /* LF CLDFB*/ - cldfbAnalysis_ts( &( tdBuffer[hFdCngCom->numCoreBands * slot_index] ), Cldfb_RealBuffer, Cldfb_ImagBuffer, hFdCngCom->numCoreBands, h_cldfb ); - } - else - { - if ( slot_index == 0 ) + ELSE { /* very low level case - update random seeds */ generate_masking_noise_update_seed_fx( hFdCngCom ); - set_f( fftBuffer, 0.f, hFdCngCom->fftlen ); - + set32_fx( fftBuffer, 0, hFdCngCom->fftlen ); /* Perform STFT synthesis */ - SynthesisSTFT( fftBuffer, tdBuffer, hFdCngCom->olapBufferSynth2, hFdCngCom->olapWinSyn, 0, hFdCngCom, X, Y, -1, -1 ); + SynthesisSTFT_dirac_fx( fftBuffer, tdBuffer + n_samples_start, hFdCngCom->olapBufferSynth2_fx, hFdCngCom->olapWinSyn_fx, n_samples_out_loop, hFdCngCom ); + } + hFdCngCom->fftBuffer_exp = 31 - 11; + move16(); + n_samples_out = sub( n_samples_out, hFdCngCom->frameSize ); + n_samples_start = add( n_samples_start, hFdCngCom->frameSize ); + } + } -#ifdef DEBUG_MODE_DIRAC - { - int16_t tmp[1000]; + pop_wmops(); - for ( i = 0; i < hFdCngCom->frameSize; i++ ) - { - tmp[i] = (int16_t) ( tdBuffer[i] + 0.5f ); - } - dbgwrite( tmp, sizeof( int16_t ), hFdCngCom->frameSize, 1, "./res/ivas_dirac_cna_fft.pcm" ); + return; +} +void generate_masking_noise_dirac_ivas_fx( + HANDLE_FD_CNG_COM hFdCngCom, /* i/o: FD_CNG structure containing all buffers and variables */ + HANDLE_CLDFB_FILTER_BANK h_cldfb, /* i : filterbank state */ + Word32 *tdBuffer_fx, /* i/o: time-domain signal, if NULL no LB-CNA q_input*/ + Word32 *Cldfb_RealBuffer_fx, /* o : CLDFD real buffer q_cldfb*/ + Word32 *Cldfb_ImagBuffer_fx, /* o : CLDFD imaginary buffer q_cldfb*/ + const Word16 slot_index, /* i : CLDFB slot index Q0*/ + const Word16 cna_flag, /* i : CNA flag for LB and HB Q0*/ + const Word16 fd_cng_flag, /* i : FD-CNG flag for HB Q0*/ + Word16 q_input, + Word16 *q_cldfb ) +{ + Word16 i; + Word32 *ptr_level_fx; + Word16 *seed = &( hFdCngCom->seed ); + Word32 scale_fx; + Word16 q_scale, q_shift, q_ptr_level; + + push_wmops( "fd_cng_dirac" ); + + /* Init */ + scale_fx = 0; + move32(); + + /* Resample CLDFB memories if necessary*/ + IF( NE_16( i_mult( h_cldfb->no_channels, h_cldfb->no_col ), hFdCngCom->frameSize ) ) + { + resampleCldfb_ivas_fx( h_cldfb, hFdCngCom->frameSize * FRAMES_PER_SEC ); + } + + set32_fx( Cldfb_RealBuffer_fx, 0, CLDFB_NO_CHANNELS_MAX ); + set32_fx( Cldfb_ImagBuffer_fx, 0, CLDFB_NO_CHANNELS_MAX ); + + /*LB CLDFB - CNA from STFT*/ + IF( cna_flag != 0 ) + { + /* skip noise generating if level is very low, to avoid problems with possibly running into denormals */ + IF( hFdCngCom->likelihood_noisy_speech > 0 ) + { + /* Compute additional CN level */ + FOR( i = 0; i < 15; i++ ) + { + test(); + test(); + if ( ( EQ_16( hFdCngCom->CngBandwidth, scaleTable_cn_dirac[i].bwmode ) ) && + ( GE_32( hFdCngCom->CngBitrate, scaleTable_cn_dirac[i].bitrateFrom ) ) && + ( LT_32( hFdCngCom->CngBitrate, scaleTable_cn_dirac[i].bitrateTo ) ) ) + { + BREAK; } -#endif } + scale_fx = L_shr( L_deposit_h( scaleTable_cn_dirac[i].scale_ivas ), Q3 ); /* Q27 */ + scale_fx = Mpy_32_16_1( scale_fx, hFdCngCom->likelihood_noisy_speech ); + } + } + /* LB CLDFB - CNA from STFT: CNA applied only in channel 0*/ + IF( cna_flag && tdBuffer_fx != NULL ) + { + *q_cldfb = q_input; + move16(); + IF( scale_fx != 0 ) + { + /* LF CLDFB*/ + cldfbAnalysis_ts_fx_fixed_q( &( tdBuffer_fx[( hFdCngCom->numCoreBands * slot_index )] ), Cldfb_RealBuffer_fx, Cldfb_ImagBuffer_fx, hFdCngCom->numCoreBands, h_cldfb, q_cldfb ); + } + ELSE + { /* LB ana CLDFB*/ - cldfbAnalysis_ts( &( tdBuffer[hFdCngCom->numCoreBands * slot_index] ), Cldfb_RealBuffer, Cldfb_ImagBuffer, hFdCngCom->numCoreBands, h_cldfb ); + cldfbAnalysis_ts_fx_fixed_q( &( tdBuffer_fx[( hFdCngCom->numCoreBands * slot_index )] ), Cldfb_RealBuffer_fx, Cldfb_ImagBuffer_fx, hFdCngCom->numCoreBands, h_cldfb, q_cldfb ); } } /*HF CLDFB - CNA and/or FD-CNG*/ if ( fd_cng_flag ) { - scale += 1.f; + scale_fx = L_add( scale_fx, ONE_IN_Q27 ); // 1 in Q27 } - if ( scale != 0 ) + IF( scale_fx != 0 ) { - scale *= CLDFB_SCALING_FLT * ( h_cldfb->scale * h_cldfb->scale * 8.f ); - ptr_level = hFdCngCom->cngNoiseLevel + hFdCngCom->stopFFTbin - hFdCngCom->startBand; - - for ( i = hFdCngCom->numCoreBands; i < hFdCngCom->regularStopBand; i++ ) + q_scale = 27; + move16(); + q_shift = norm_l( scale_fx ); + scale_fx = L_shl( scale_fx, q_shift ); /*q_scale+q_shift*/ + q_scale = add( q_scale, q_shift ); + scale_fx = Mpy_32_32( scale_fx, Mpy_32_16_1( L_mult( h_cldfb->scale, h_cldfb->scale ), CLDFB_SCALING ) ); // Q = q_scale + 2 * Q8 - 34 + q_scale = sub( add( q_scale, 2 * Q8 ), 31 ); + ptr_level_fx = hFdCngCom->cngNoiseLevel + sub( hFdCngCom->stopFFTbin, hFdCngCom->startBand ); /*Q31 - hFdCngCom->cngNoiseLevelExp*/ + q_ptr_level = sub( 31, hFdCngCom->cngNoiseLevelExp ); + + FOR( i = hFdCngCom->numCoreBands; i < hFdCngCom->regularStopBand; i++ ) { + Word32 num; + Word16 exp, q_num; + q_shift = norm_l( scale_fx ); + scale_fx = L_shl( scale_fx, q_shift ); /*q_scale+q_shift*/ + q_scale = add( q_scale, q_shift ); + num = Mpy_32_32( scale_fx, *ptr_level_fx ); /*q_num*/ + q_num = sub( add( q_scale, q_ptr_level ), 31 ); + exp = sub( 31, q_num ); + num = Sqrt32( num, &exp ); /*Q31 - exp*/ /* Real part in CLDFB band */ - rand_gauss( &Cldfb_RealBuffer[i], seed ); - Cldfb_RealBuffer[i] *= (float) sqrt( ( scale * *ptr_level ) * 0.5f ); + rand_gauss_fx( &Cldfb_RealBuffer_fx[i], seed, *q_cldfb ); + Cldfb_RealBuffer_fx[i] = L_shl( Mpy_32_32( Cldfb_RealBuffer_fx[i], num ), exp ); + move32(); /* Imaginary part in CLDFB band */ - rand_gauss( &Cldfb_ImagBuffer[i], seed ); - Cldfb_ImagBuffer[i] *= (float) sqrt( ( scale * *ptr_level ) * 0.5f ); + rand_gauss_fx( &Cldfb_ImagBuffer_fx[i], seed, *q_cldfb ); + Cldfb_ImagBuffer_fx[i] = L_shl( Mpy_32_32( Cldfb_ImagBuffer_fx[i], num ), exp ); + move32(); - ptr_level++; + ptr_level_fx++; } } - wmops_sub_end(); + pop_wmops(); return; } @@ -5458,94 +5705,155 @@ void generate_masking_noise_dirac( * *-------------------------------------------------------------------*/ -void FdCngDecodeMDCTStereoSID( +void FdCngDecodeMDCTStereoSID_fx( CPE_DEC_HANDLE hCPE /* i/o: CPE decoder state structure */ ) { DEC_CORE_HANDLE sts[CPE_CHANNELS]; HANDLE_FD_CNG_COM hFdCngCom; - float *ms_ptr[CPE_CHANNELS]; - float *lr_ptr[CPE_CHANNELS]; - float logNoiseEst[CPE_CHANNELS][NPART]; - float gain[CPE_CHANNELS]; - int16_t indices[FD_CNG_stages_37bits]; - int16_t N, i, ch, p, stages; - int16_t is_out_ms; + Word32 *ms_ptr_fx[CPE_CHANNELS]; + Word32 *lr_ptr_fx[CPE_CHANNELS]; + Word32 logNoiseEst_fx[CPE_CHANNELS][NPART]; + Word32 gain_fx[CPE_CHANNELS]; + Word16 indices[FD_CNG_stages_37bits]; + Word16 N, i, ch, p, stages; + Word16 is_out_ms; + Word32 *invTrfMatrix_fx; + Word32 tmpRAM_fx[FDCNG_VQ_MAX_LEN][FDCNG_VQ_DCT_MAXTRUNC]; + Word16 shift, exp_diff, max_exp_idx; + Word16 exp_arr[NPART]; + Word32 tmp32, tmp32_arr[NPART]; + + invTrfMatrix_fx = (Word32 *) tmpRAM_fx; + create_IDCT_N_Matrix_fx( invTrfMatrix_fx, FDCNG_VQ_MAX_LEN, FDCNG_VQ_DCT_MAXTRUNC, FDCNG_VQ_MAX_LEN * FDCNG_VQ_DCT_MAXTRUNC ); // Q31 is_out_ms = 0; + move16(); if ( hCPE->hCoreCoder[0]->cng_sba_flag ) { is_out_ms = 1; + move16(); } N = 0; /* to avoid compilation warning */ + move16(); - for ( ch = 0; ch < CPE_CHANNELS; ch++ ) + FOR( ch = 0; ch < CPE_CHANNELS; ch++ ) { sts[ch] = hCPE->hCoreCoder[ch]; - ms_ptr[ch] = &logNoiseEst[ch][0]; - lr_ptr[ch] = &sts[ch]->hFdCngDec->hFdCngCom->sidNoiseEst[0]; + ms_ptr_fx[ch] = &logNoiseEst_fx[ch][0]; /*Q20*/ + lr_ptr_fx[ch] = &sts[ch]->hFdCngDec->hFdCngCom->sidNoiseEst[0]; /*Q18*/ } /* decode noise shapes and gains */ - for ( ch = 0; ch < CPE_CHANNELS; ch++ ) + FOR( ch = 0; ch < CPE_CHANNELS; ch++ ) { sts[ch] = hCPE->hCoreCoder[ch]; hFdCngCom = ( sts[ch]->hFdCngDec )->hFdCngCom; N = hFdCngCom->npart; - hFdCngCom->sid_frame_counter++; + move16(); + hFdCngCom->sid_frame_counter = add( hFdCngCom->sid_frame_counter, 1 ); /*Q0*/ + move16(); - if ( ch ) + IF( ch ) { stages = FD_CNG_JOINT_stages_25bits; + move16(); } - else + ELSE { stages = FD_CNG_stages_37bits; + move16(); } /* read bitstream */ - for ( i = 0; i < stages; i++ ) + FOR( i = 0; i < stages; i++ ) { - indices[i] = get_next_indice( sts[ch], bits_37bits[i] ); + indices[i] = get_next_indice_fx( sts[ch], bits_37bits[i] ); /*Q0*/ + move16(); } { - gain[ch] = ( (float) get_next_indice( sts[ch], 7 ) - GAIN_Q_OFFSET_IVAS ) / 1.5f; + gain_fx[ch] = Mpy_32_32( L_shl( L_sub( get_next_indice_fx( sts[ch], 7 ), GAIN_Q_OFFSET_IVAS_FX ), Q20 ), TWO_BY_THREE_Q31 /* 2/3 in Q31 */ ); // Q20 + move32(); } /* MSVQ decoder */ - msvq_dec( cdk_37bits_ivas, NULL, NULL, stages, N, FD_CNG_maxN_37bits, indices, ms_ptr[ch], NULL ); + shift = find_guarded_bits_fx( N ); + msvq_dec_fx( ivas_cdk_37bits_fx, NULL, NULL, stages, N, FD_CNG_maxN_37bits, indices, 1, invTrfMatrix_fx, ms_ptr_fx[ch], NULL, 7 ); // Q20 - shift + + Scale_sig32( ms_ptr_fx[ch], N, shift ); // Q20 } - if ( sts[0]->hFdCngDec->hFdCngCom->no_side_flag ) + dtx_read_padding_bits_fx( sts[1], mult( sub( IVAS_SID_5k2, 4400 ), ONE_BY_FRAMES_PER_SEC_Q15 ) ); + + IF( sts[0]->hFdCngDec->hFdCngCom->no_side_flag ) { - set_zero( ms_ptr[1], NPART ); + set32_fx( ms_ptr_fx[1], 0, NPART ); } - if ( is_out_ms == 0 ) + IF( EQ_16( is_out_ms, 0 ) ) { - inverseMS( N, ms_ptr[0], ms_ptr[1], 1.f ); + inverseMS_fx( N, ms_ptr_fx[0], ms_ptr_fx[1], ONE_IN_Q31 ); } - for ( ch = 0; ch < CPE_CHANNELS; ch++ ) + FOR( ch = 0; ch < CPE_CHANNELS; ch++ ) { + max_exp_idx = 0; + move16(); hFdCngCom = sts[ch]->hFdCngDec->hFdCngCom; - for ( p = 0; p < N; p++ ) + FOR( p = 0; p < N; p++ ) { - lr_ptr[ch][p] = powf( 10.f, ( ms_ptr[ch][p] + gain[ch] ) / 10.f ); + tmp32 = L_add( ms_ptr_fx[ch][p], gain_fx[ch] ); // Q20 + tmp32_arr[p] = BASOP_util_Pow2( Mpy_32_32( tmp32, LOG_10_BASE_2_BY_10_Q31 ), Q11, &exp_arr[p] ); /*Q31 - exp_arr[p]*/ + move32(); + if ( LT_16( exp_arr[max_exp_idx], exp_arr[p] ) ) + { + max_exp_idx = p; /*Q0*/ + move16(); + } + } + + // Bringing in same exponent + FOR( p = 0; p < N; p++ ) + { + lr_ptr_fx[ch][p] = L_shl( tmp32_arr[p], sub( exp_arr[p], exp_arr[max_exp_idx] ) ); /*Q31 - exp_arr[max_exp_idx]*/ + move32(); } - scalebands( hFdCngCom->sidNoiseEst, hFdCngCom->part, hFdCngCom->npart, hFdCngCom->midband, hFdCngCom->nFFTpart, hFdCngCom->stopBand - hFdCngCom->startBand, hFdCngCom->cngNoiseLevel, 1 ); + hFdCngCom->sidNoiseEstExp = exp_arr[max_exp_idx]; + move16(); + + scalebands( hFdCngCom->sidNoiseEst, hFdCngCom->part, hFdCngCom->npart, hFdCngCom->midband, hFdCngCom->nFFTpart, sub( hFdCngCom->stopBand, hFdCngCom->startBand ), hFdCngCom->cngNoiseLevel, 1 ); + + hFdCngCom->cngNoiseLevelExp = hFdCngCom->sidNoiseEstExp; + move16(); lpc_from_spectrum( hFdCngCom, hFdCngCom->startBand, hFdCngCom->stopFFTbin, sts[ch]->preemph_fac ); } - if ( hCPE->nchan_out == 1 && hCPE->last_element_brate <= IVAS_SID_4k4 ) + test(); + IF( EQ_16( hCPE->nchan_out, 1 ) && LE_32( hCPE->last_element_brate, IVAS_SID_5k2 ) ) { /* create proper M noise shape in channel zero after gains have been applied */ - for ( p = 0; p < N; p++ ) + exp_diff = sub( sts[0]->hFdCngDec->hFdCngCom->sidNoiseEstExp, sts[1]->hFdCngDec->hFdCngCom->sidNoiseEstExp ); + move16(); + FOR( p = 0; p < N; p++ ) + { + IF( GT_16( exp_diff, 0 ) ) + { + sts[0]->hFdCngDec->hFdCngCom->sidNoiseEst[p] = L_add( L_shr( sts[0]->hFdCngDec->hFdCngCom->sidNoiseEst[p], 1 ), L_shr( sts[1]->hFdCngDec->hFdCngCom->sidNoiseEst[p], add( exp_diff, 1 ) ) ); /*Q18*/ + move32(); + } + ELSE + { + sts[0]->hFdCngDec->hFdCngCom->sidNoiseEst[p] = L_add( L_shr( sts[0]->hFdCngDec->hFdCngCom->sidNoiseEst[p], sub( 1, exp_diff ) ), L_shr( sts[1]->hFdCngDec->hFdCngCom->sidNoiseEst[p], 1 ) ); /*Q18*/ + move32(); + } + } + IF( LT_16( exp_diff, 0 ) ) { - sts[0]->hFdCngDec->hFdCngCom->sidNoiseEst[p] = 0.5f * ( sts[0]->hFdCngDec->hFdCngCom->sidNoiseEst[p] + sts[1]->hFdCngDec->hFdCngCom->sidNoiseEst[p] ); + sts[0]->hFdCngDec->hFdCngCom->sidNoiseEstExp = add( sts[0]->hFdCngDec->hFdCngCom->sidNoiseEstExp, negate( exp_diff ) ); + move16(); } } @@ -5554,86 +5862,141 @@ void FdCngDecodeMDCTStereoSID( /*------------------------------------------------------------------- - * FdCngDecodeDiracMDCTStereoSID() + * FdCngDecodeDiracMDCTStereoSID_fx() * - * Decode FD-Cng parameters for CNG in 2TC DirAC mode from the bitstream + * Decode FD-CNG parameters for CNG in 2TC DirAC mode from the bitstream *-------------------------------------------------------------------*/ -void FdCngDecodeDiracMDCTStereoSID( +void FdCngDecodeDiracMDCTStereoSID_fx( CPE_DEC_HANDLE hCPE /* i/o: CPE decoder state structure */ ) { DEC_CORE_HANDLE sts[CPE_CHANNELS]; HANDLE_FD_CNG_COM hFdCngCom; - float *ms_ptr[CPE_CHANNELS]; - float *lr_ptr[CPE_CHANNELS]; - float logNoiseEst[CPE_CHANNELS][NPART]; - float gain[CPE_CHANNELS]; - int16_t indices[FD_CNG_stages_37bits]; - int16_t N, i, ch, p; - - for ( ch = 0; ch < CPE_CHANNELS; ch++ ) + Word32 *ms_ptr_fx[CPE_CHANNELS]; + Word32 *lr_ptr_fx[CPE_CHANNELS]; + Word32 logNoiseEst_fx[CPE_CHANNELS][NPART]; + Word32 gain_fx[CPE_CHANNELS]; + Word16 indices[FD_CNG_stages_37bits]; + Word16 N, i, ch, p; + Word32 *invTrfMatrix_fx; + Word32 tmpRAM_fx[FDCNG_VQ_MAX_LEN][FDCNG_VQ_DCT_MAXTRUNC]; + Word16 shift, exp_diff, max_exp_idx; + Word16 exp_arr[NPART]; + Word32 tmp32, tmp32_arr[NPART]; + + invTrfMatrix_fx = (Word32 *) tmpRAM_fx; /* dynamically filled */ + create_IDCT_N_Matrix_fx( invTrfMatrix_fx, FDCNG_VQ_MAX_LEN, FDCNG_VQ_DCT_MAXTRUNC, FDCNG_VQ_MAX_LEN * FDCNG_VQ_DCT_MAXTRUNC ); // Q31 + + FOR( ch = 0; ch < CPE_CHANNELS; ch++ ) { sts[ch] = hCPE->hCoreCoder[ch]; - ms_ptr[ch] = &logNoiseEst[ch][0]; - lr_ptr[ch] = &sts[ch]->hFdCngDec->hFdCngCom->sidNoiseEst[0]; - ( sts[ch]->hFdCngDec )->hFdCngCom->sid_frame_counter++; + ms_ptr_fx[ch] = &logNoiseEst_fx[ch][0]; /*Q20*/ + lr_ptr_fx[ch] = &sts[ch]->hFdCngDec->hFdCngCom->sidNoiseEst[0]; /*Q20*/ + ( sts[ch]->hFdCngDec )->hFdCngCom->sid_frame_counter++; /*Q18*/ } /* decode noise shapes and gains */ hFdCngCom = ( sts[0]->hFdCngDec )->hFdCngCom; - N = hFdCngCom->npart; + N = hFdCngCom->npart; /*Q0*/ + move16(); /* read bitstream */ - for ( i = 0; i < FD_CNG_stages_37bits; i++ ) + FOR( i = 0; i < FD_CNG_stages_37bits; i++ ) { - indices[i] = get_next_indice( sts[0], bits_37bits[i] ); + indices[i] = get_next_indice_fx( sts[0], bits_37bits[i] ); /*Q0*/ + move16(); } - gain[0] = ( (float) get_next_indice( sts[0], 7 ) - GAIN_Q_OFFSET_IVAS ) / 1.5f; - gain[1] = gain[0]; + gain_fx[0] = Mpy_32_32( L_shl( L_sub( get_next_indice_fx( sts[0], 7 ), GAIN_Q_OFFSET_IVAS_FX ), Q20 ), TWO_BY_THREE_Q31 /* 2/3 in Q31 */ ); // Q20 + move32(); + + gain_fx[1] = gain_fx[0]; /*Q20*/ + move32(); /* MSVQ decoder */ - msvq_dec( cdk_37bits_ivas, NULL, NULL, FD_CNG_stages_37bits, N, FD_CNG_maxN_37bits, indices, ms_ptr[0], NULL ); - mvr2r( ms_ptr[0], ms_ptr[1], N ); + shift = find_guarded_bits_fx( N ); + msvq_dec_fx( ivas_cdk_37bits_fx, NULL, NULL, FD_CNG_stages_37bits, N, FD_CNG_maxN_37bits, indices, 1, invTrfMatrix_fx, ms_ptr_fx[0], NULL, 7 ); // Q20 - shift + + Scale_sig32( ms_ptr_fx[0], N, shift ); // Q20 - /*inverseMS( N, ms_ptr[0], ms_ptr[1], 1.f );*/ + Copy32( ms_ptr_fx[0], ms_ptr_fx[1], N ); /*Q20*/ - for ( ch = 0; ch < CPE_CHANNELS; ch++ ) + FOR( ch = 0; ch < CPE_CHANNELS; ch++ ) { + max_exp_idx = 0; + move16(); hFdCngCom = sts[ch]->hFdCngDec->hFdCngCom; - for ( p = 0; p < N; p++ ) + + FOR( p = 0; p < N; p++ ) + { + tmp32 = L_add( ms_ptr_fx[ch][p], gain_fx[ch] ); // Q20 + tmp32_arr[p] = BASOP_util_Pow2( Mpy_32_32( tmp32, LOG_10_BASE_2_BY_10_Q31 ), Q11, &exp_arr[p] ); /*Q31 - exp_arr[p]*/ + move32(); + if ( LT_16( exp_arr[max_exp_idx], exp_arr[p] ) ) + { + max_exp_idx = p; /*Q0*/ + move16(); + } + } + + // Bringing in same exponent + FOR( p = 0; p < N; p++ ) { - lr_ptr[ch][p] = powf( 10.f, ( ms_ptr[ch][p] + gain[ch] ) / 10.f ); + lr_ptr_fx[ch][p] = L_shl( tmp32_arr[p], sub( exp_arr[p], exp_arr[max_exp_idx] ) ); /*Q20*/ + move32(); } + hFdCngCom->sidNoiseEstExp = exp_arr[max_exp_idx]; /*Q0*/ + move16(); + /* NB last band energy compensation */ - if ( hFdCngCom->CngBandwidth == NB ) + test(); + IF( hFdCngCom->CngBandwidth == NB ) { - lr_ptr[ch][N - 1] *= NB_LAST_BAND_SCALE; + lr_ptr_fx[ch][( N - 1 )] = Mpy_32_32( lr_ptr_fx[ch][( N - 1 )], NB_LAST_BAND_SCALE_Q31 ); /*Q20*/ + move32(); } - else if ( hFdCngCom->CngBandwidth == SWB && hFdCngCom->CngBitrate <= ACELP_13k20 ) + ELSE IF( EQ_16( hFdCngCom->CngBandwidth, SWB ) && LE_32( hFdCngCom->CngBitrate, ACELP_13k20 ) ) { - lr_ptr[ch][N - 1] *= SWB_13k2_LAST_BAND_SCALE; + lr_ptr_fx[ch][( N - 1 )] = Mpy_32_32( lr_ptr_fx[ch][( N - 1 )], SWB_13k2_LAST_BAND_SCALE_Q31 ); /*Q20*/ + move32(); } - scalebands( hFdCngCom->sidNoiseEst, hFdCngCom->part, hFdCngCom->npart, hFdCngCom->midband, hFdCngCom->nFFTpart, hFdCngCom->stopBand - hFdCngCom->startBand, hFdCngCom->cngNoiseLevel, 1 ); + scalebands( hFdCngCom->sidNoiseEst, hFdCngCom->part, hFdCngCom->npart, hFdCngCom->midband, hFdCngCom->nFFTpart, sub( hFdCngCom->stopBand, hFdCngCom->startBand ), hFdCngCom->cngNoiseLevel, 1 ); + + hFdCngCom->cngNoiseLevelExp = hFdCngCom->sidNoiseEstExp; + move16(); lpc_from_spectrum( hFdCngCom, hFdCngCom->startBand, hFdCngCom->stopFFTbin, sts[ch]->preemph_fac ); } - sts[0]->hFdCngDec->hFdCngCom->coherence = 0.0f; - sts[1]->hFdCngDec->hFdCngCom->coherence = 0.0f; + sts[0]->hFdCngDec->hFdCngCom->coherence_fx = 0; + move16(); + sts[1]->hFdCngDec->hFdCngCom->coherence_fx = 0; + move16(); - if ( hCPE->nchan_out == 1 ) + IF( EQ_16( hCPE->nchan_out, 1 ) ) { /* create proper M noise shape in channel zero after gains have been applied */ - for ( p = 0; p < N; p++ ) + exp_diff = sub( sts[0]->hFdCngDec->hFdCngCom->sidNoiseEstExp, sts[1]->hFdCngDec->hFdCngCom->sidNoiseEstExp ); + FOR( p = 0; p < N; p++ ) + { + IF( exp_diff > 0 ) + { + sts[0]->hFdCngDec->hFdCngCom->sidNoiseEst[p] = L_add( L_shr( sts[0]->hFdCngDec->hFdCngCom->sidNoiseEst[p], 1 ), L_shr( sts[1]->hFdCngDec->hFdCngCom->sidNoiseEst[p], add( exp_diff, 1 ) ) ); /*Q18*/ + move32(); + } + ELSE + { + sts[0]->hFdCngDec->hFdCngCom->sidNoiseEst[p] = L_add( L_shr( sts[0]->hFdCngDec->hFdCngCom->sidNoiseEst[p], sub( 1, exp_diff ) ), L_shr( sts[1]->hFdCngDec->hFdCngCom->sidNoiseEst[p], 1 ) ); /*Q18*/ + move32(); + } + } + IF( exp_diff < 0 ) { - sts[0]->hFdCngDec->hFdCngCom->sidNoiseEst[p] = 0.5f * ( sts[0]->hFdCngDec->hFdCngCom->sidNoiseEst[p] + sts[1]->hFdCngDec->hFdCngCom->sidNoiseEst[p] ); + sts[0]->hFdCngDec->hFdCngCom->sidNoiseEstExp = add( sts[0]->hFdCngDec->hFdCngCom->sidNoiseEstExp, negate( exp_diff ) ); + move16(); } - sts[0]->hFdCngDec->hFdCngCom->coherence = 0.0f; - sts[1]->hFdCngDec->hFdCngCom->coherence = 0.0f; } return; } -#endif diff --git a/lib_dec/gain_dec.c b/lib_dec/gain_dec.c deleted file mode 100644 index d441f6ead49ddcb3a6a1ffab0962633db8157cd0..0000000000000000000000000000000000000000 --- a/lib_dec/gain_dec.c +++ /dev/null @@ -1,43 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include -#include "cnst.h" -#include "rom_com.h" -#include "prot.h" -#include "wmc_auto.h" diff --git a/lib_dec/gain_dec_fx.c b/lib_dec/gain_dec_fx.c index 210fae39e36c330676b8d77c97dbf67bb36fed0b..5e17122311bc97e7495aa9840fa7036d069b3c24 100644 --- a/lib_dec/gain_dec_fx.c +++ b/lib_dec/gain_dec_fx.c @@ -169,11 +169,7 @@ void gain_dec_tc_fx( IF( GT_16( nBits, 3 ) ) { wgain_code = gain_dequant_fx( index, G_CODE_MIN_TC_Q15, G_CODE_MAX_TC_Q0, nBits, &expg ); -#ifdef BASOP_NOGLOB wgain_code = shl_sat( wgain_code, add( expg, 13 ) ); /* wgain_code in Q13*/ -#else - wgain_code = shl( wgain_code, add( expg, 13 ) ); /* wgain_code in Q13*/ -#endif } ELSE /* nBits == 3 */ { @@ -186,12 +182,8 @@ void gain_dec_tc_fx( *-----------------------------------------------------------------*/ /* *gain_code *= gcode0;*/ - L_tmp = L_mult( wgain_code, gcode0_fx ); /* Q13*Q0 -> Q14 */ -#ifdef BASOP_NOGLOB + L_tmp = L_mult( wgain_code, gcode0_fx ); /* Q13*Q0 -> Q14 */ *gain_code_fx = L_shl_sat( L_tmp, add( exp_gcode0, 2 ) ); /*Q16*/ -#else - *gain_code_fx = L_shl( L_tmp, add( exp_gcode0, 2 ) ); -#endif move32(); /**norm_gain_code = *gain_code / *gain_inov;*/ @@ -461,12 +453,8 @@ void gain_dec_mless_fx( gain_code16 = gain_dequant_fx( index, G_CODE_MIN_TC192_Q15, G_CODE_MAX_TC192_Q0, shr( add( nBits, 1 ), 1 ), &expg ); /**gain_code *= gcode0;*/ - L_tmp = L_mult( gain_code16, gcode0_fx ); /*Q0*Q0 -> Q1*/ -#ifdef BASOP_NOGLOB + L_tmp = L_mult( gain_code16, gcode0_fx ); /*Q0*Q0 -> Q1*/ *gain_code_fx = L_shl_sat( L_tmp, add( add( expg, exp_gcode0 ), 15 ) ); /*Q16*/ -#else - *gain_code_fx = L_shl( L_tmp, add( add( expg, exp_gcode0 ), 15 ) ); -#endif move32(); } ELSE @@ -517,22 +505,34 @@ void gain_dec_mless_fx( L_tmp = Dot_product12( code_fx, code_fx, L_SUBFR, &expg ); /*Q31 - expg*/ expg = sub( expg, 18 + 6 ); /* exp: -18 (code in Q9), -6 (/L_SUBFR) */ - expg2 = expg; - move16(); - L_tmp1 = L_tmp; /* sets to 'L_tmp' in 1 clock */ - move32(); - L_tmp = Isqrt_lc( L_tmp, &expg ); /*Q31 - expg*/ - - *gain_inov_fx = extract_h( L_shl( L_tmp, sub( expg, 3 ) ) ); /* gain_inov in Q12 */ - move16(); - - /*Ei = 10 * (float)log10( Ecode );*/ - e_tmp = norm_l( L_tmp1 ); - f_tmp = Log2_norm_lc( L_shl( L_tmp1, e_tmp ) ); /*Q15*/ - e_tmp = sub( expg2, add( 1, e_tmp ) ); - L_tmp1 = Mpy_32_16( e_tmp, f_tmp, 12330 ); /* Q13 */ /* 10*log10(2) in Q12*/ - Ei_fx = round_fx( L_shl( L_tmp1, 11 ) ); /* Q8 */ + // To avoid crash in case code value is 0 + IF( EQ_16( BASOP_Util_Cmp_Mant32Exp( L_tmp, expg, 21474836, 0 ), -1 ) ) + { + // setting values to avoid extra computation + *gain_inov_fx = 32767; /*8(max value gain_inov can hold) in Q12*/ + Ei_fx = -9743; /* -38 in Q8*/ + move16(); + move16(); + } + ELSE + { + expg2 = expg; + move16(); + L_tmp1 = L_tmp; /* sets to 'L_tmp' in 1 clock */ + move32(); + L_tmp = Isqrt_lc( L_tmp, &expg ); /*Q31 - expg*/ + + *gain_inov_fx = extract_h( L_shl( L_tmp, sub( expg, 3 ) ) ); /* gain_inov in Q12 */ + move16(); + + /*Ei = 10 * (float)log10( Ecode );*/ + e_tmp = norm_l( L_tmp1 ); + f_tmp = Log2_norm_lc( L_shl( L_tmp1, e_tmp ) ); /*Q15*/ + e_tmp = sub( expg2, add( 1, e_tmp ) ); + L_tmp1 = Mpy_32_16( e_tmp, f_tmp, 12330 ); /* Q13 */ /* 10*log10(2) in Q12*/ + Ei_fx = round_fx( L_shl( L_tmp1, 11 ) ); /* Q8 */ + } /*-----------------------------------------------------------------* * calculate the predicted gain code *-----------------------------------------------------------------*/ @@ -560,11 +560,7 @@ void gain_dec_mless_fx( /**gain_code = qua_table[index * 2 + 1] * gcode0;*/ L_tmp = L_mult( qua_table_fx[( ( index * 2 ) + 1 )], gcode0_fx ); /* Q9*Q0 -> Q10 */ -#ifdef BASOP_NOGLOB - *gain_code_fx = L_shl_sat( L_tmp, add( exp_gcode0, 6 ) ); /*Q16*/ -#else - *gain_code_fx = L_shl( L_tmp, add( exp_gcode0, 6 ) ); -#endif + *gain_code_fx = L_shl_sat( L_tmp, add( exp_gcode0, 6 ) ); /*Q16*/ move32(); } @@ -731,11 +727,7 @@ void gain_dec_lbr_fx( move16(); L_tmp = L_mult( cdbk_fx[( ( index * 2 ) + 1 )], gcode0_fx ); /* Q9*Q0 -> Q10 */ -#ifdef BASOP_NOGLOB - *gain_code_fx = L_shl_sat( L_tmp, add( exp_gcode0, 6 ) ); /* Q10 -> Q16*/ -#else - *gain_code_fx = L_shl( L_tmp, add( exp_gcode0, 6 ) ); -#endif + *gain_code_fx = L_shl_sat( L_tmp, add( exp_gcode0, 6 ) ); /* Q10 -> Q16*/ move16(); gc_mem[0] = *gain_code_fx; /*Q16*/ @@ -805,11 +797,7 @@ void gain_dec_lbr_fx( move16(); L_tmp = L_mult( cdbk_fx[( ( index * 2 ) + 1 )], gcode0_fx ); /* Q9*Q0 -> Q10 */ -#ifdef BASOP_NOGLOB - *gain_code_fx = L_shl_sat( L_tmp, add( exp_gcode0, 6 ) ); /*Q16*/ -#else - *gain_code_fx = L_shl( L_tmp, add( exp_gcode0, 6 ) ); -#endif + *gain_code_fx = L_shl_sat( L_tmp, add( exp_gcode0, 6 ) ); /*Q16*/ move16(); gc_mem[1] = *gain_code_fx; /*Q16*/ @@ -883,11 +871,7 @@ void gain_dec_lbr_fx( move16(); L_tmp = L_mult( cdbk_fx[( ( index * 2 ) + 1 )], gcode0_fx ); /* Q9*Q0 -> Q10 */ -#ifdef BASOP_NOGLOB - *gain_code_fx = L_shl_sat( L_tmp, add( exp_gcode0, 6 ) ); /* Q10 -> Q16*/ -#else - *gain_code_fx = L_shl( L_tmp, add( exp_gcode0, 6 ) ); /* Q10 -> Q16*/ -#endif + *gain_code_fx = L_shl_sat( L_tmp, add( exp_gcode0, 6 ) ); /* Q10 -> Q16*/ move32(); gc_mem[2] = *gain_code_fx; /*Q16*/ move32(); @@ -971,11 +955,7 @@ void gain_dec_lbr_fx( move16(); L_tmp = L_mult( cdbk_fx[( ( index * 2 ) + 1 )], gcode0_fx ); /* Q9*Q0 -> Q10 */ -#ifdef BASOP_NOGLOB - *gain_code_fx = L_shl_sat( L_tmp, add( exp_gcode0, 6 ) ); /*Q16*/ -#else - *gain_code_fx = L_shl( L_tmp, add( exp_gcode0, 6 ) ); -#endif + *gain_code_fx = L_shl_sat( L_tmp, add( exp_gcode0, 6 ) ); /*Q16*/ move32(); } @@ -1117,11 +1097,7 @@ void gain_dec_lbr_ivas_fx( move16(); L_tmp = L_mult( cdbk_fx[( ( index * 2 ) + 1 )], gcode0_fx ); /* Q9*Q0 -> Q10 */ -#ifdef BASOP_NOGLOB - *gain_code_fx = L_shl_sat( L_tmp, add( exp_gcode0, 6 ) ); /*Q16*/ -#else - *gain_code_fx = L_shl( L_tmp, add( exp_gcode0, 6 ) ); -#endif + *gain_code_fx = L_shl_sat( L_tmp, add( exp_gcode0, 6 ) ); /*Q16*/ move16(); gc_mem[0] = *gain_code_fx; /*Q16*/ @@ -1191,11 +1167,7 @@ void gain_dec_lbr_ivas_fx( move16(); L_tmp = L_mult( cdbk_fx[( ( index * 2 ) + 1 )], gcode0_fx ); /* Q9*Q0 -> Q10 */ -#ifdef BASOP_NOGLOB - *gain_code_fx = L_shl_sat( L_tmp, add( exp_gcode0, 6 ) ); /*Q16*/ -#else - *gain_code_fx = L_shl( L_tmp, add( exp_gcode0, 6 ) ); -#endif + *gain_code_fx = L_shl_sat( L_tmp, add( exp_gcode0, 6 ) ); /*Q16*/ move16(); gc_mem[1] = *gain_code_fx; /*Q16*/ @@ -1269,11 +1241,7 @@ void gain_dec_lbr_ivas_fx( move16(); L_tmp = L_mult( cdbk_fx[( ( index * 2 ) + 1 )], gcode0_fx ); /* Q9*Q0 -> Q10 */ -#ifdef BASOP_NOGLOB - *gain_code_fx = L_shl_sat( L_tmp, add( exp_gcode0, 6 ) ); /* Q10 -> Q16*/ -#else - *gain_code_fx = L_shl( L_tmp, add( exp_gcode0, 6 ) ); /* Q10 -> Q16*/ -#endif + *gain_code_fx = L_shl_sat( L_tmp, add( exp_gcode0, 6 ) ); /* Q10 -> Q16*/ move32(); gc_mem[2] = *gain_code_fx; /*Q16*/ move32(); @@ -1356,11 +1324,7 @@ void gain_dec_lbr_ivas_fx( move16(); L_tmp = L_mult( cdbk_fx[( ( index * 2 ) + 1 )], gcode0_fx ); /* Q9*Q0 -> Q10 */ -#ifdef BASOP_NOGLOB - *gain_code_fx = L_shl_sat( L_tmp, add( exp_gcode0, 6 ) ); /*Q16*/ -#else - *gain_code_fx = L_shl( L_tmp, add( exp_gcode0, 6 ) ); -#endif + *gain_code_fx = L_shl_sat( L_tmp, add( exp_gcode0, 6 ) ); /*Q16*/ move32(); } @@ -1414,11 +1378,7 @@ void lp_gain_updt_fx( { Word16 tmp; -#ifdef BASOP_NOGLOB tmp = extract_h( L_shl_sat( norm_gain_code, 3 ) ); /*(16+3)-16 -> Q3*/ -#else - tmp = extract_h( L_shl( norm_gain_code, 3 ) ); /*(16+3)-16 -> Q3*/ -#endif IF( EQ_16( L_frame, L_FRAME ) ) { IF( EQ_16( i_subfr, 0 ) ) @@ -1446,11 +1406,7 @@ void lp_gain_updt_fx( { *lp_gainp = add( *lp_gainp, mult( 13107, gain_pit ) ); move16(); /*Q14 (0.4 in Q15 = 13107)*/ -#ifdef BASOP_NOGLOB *lp_gainc = mac_r_sat( L_deposit_h( *lp_gainc ), 13107, tmp ); -#else - *lp_gainc = mac_r( L_deposit_h( *lp_gainc ), 13107, tmp ); -#endif move16(); /*Q3*/ } } @@ -1488,11 +1444,7 @@ void lp_gain_updt_fx( { *lp_gainp = add( *lp_gainp, mult( 10923, gain_pit ) ); move16(); /*Q14 (5.0/15.0 in Q15 = 10923)*/ -#ifdef BASOP_NOGLOB *lp_gainc = mac_r_sat( L_deposit_h( *lp_gainc ), 10923, tmp ); -#else - *lp_gainc = mac_r( L_deposit_h( *lp_gainc ), 10923, tmp ); -#endif move16(); /*Q3*/ } } @@ -1538,11 +1490,7 @@ void lp_gain_updt_ivas_fx( { Word16 tmp; -#ifdef BASOP_NOGLOB tmp = extract_h( L_shl_sat( norm_gain_code, 3 ) ); /*(16+3)-16 -> Q3*/ -#else - tmp = extract_h( L_shl( norm_gain_code, 3 ) ); /*(16+3)-16 -> Q3*/ -#endif /* To handle extremely low values */ test(); if ( norm_gain_code != 0 && tmp == 0 ) @@ -1578,11 +1526,7 @@ void lp_gain_updt_ivas_fx( { *lp_gainp = add( *lp_gainp, mult( 13107, gain_pit ) ); move16(); /*Q14 (0.4 in Q15 = 13107)*/ -#ifdef BASOP_NOGLOB *lp_gainc = mac_r_sat( L_deposit_h( *lp_gainc ), 13107, tmp ); -#else - *lp_gainc = mac_r( L_deposit_h( *lp_gainc ), 13107, tmp ); -#endif move16(); /*Q3*/ } } @@ -1620,11 +1564,7 @@ void lp_gain_updt_ivas_fx( { *lp_gainp = add( *lp_gainp, mult( 10923, gain_pit ) ); move16(); /*Q14 (5.0/15.0 in Q15 = 10923)*/ -#ifdef BASOP_NOGLOB *lp_gainc = mac_r_sat( L_deposit_h( *lp_gainc ), 10923, tmp ); -#else - *lp_gainc = mac_r( L_deposit_h( *lp_gainc ), 10923, tmp ); -#endif move16(); /*Q3*/ } } @@ -1691,24 +1631,14 @@ Word32 gain_dec_gaus_fx( /* o : quantized codebook expg = add( expg, 16 - 30 ); /* output of Pow2() will be */ /* Normalized, set result in Q16 */ gain = round_fx( L_gain ); -#ifdef BASOP_NOGLOB L_gain = L_shl_sat( L_gain, expg ); /* In Q16*/ -#else - L_gain = L_shl( L_gain, expg ); /* In Q16*/ -#endif /* *norm_gain_code = gain / *inv_gain_inov;*/ expi = norm_s( inv_gain_inov ); tmp_igi = shl( inv_gain_inov, expi ); L_tmp = div_s( shr( gain, 1 ), tmp_igi ); -#ifdef BASOP_NOGLOB L_tmp = L_shl_sat( L_tmp, add( 1, expi ) ); *L_norm_gain_code = L_shl_sat( L_tmp, add( expg, 13 ) ); /* Q16 */ move32(); -#else - L_tmp = L_shl( L_tmp, add( 1, expi ) ); - *L_norm_gain_code = L_shl( L_tmp, add( expg, 13 ) ); /* Q16 */ - move32(); -#endif return L_gain; } @@ -1805,11 +1735,7 @@ void gain_dec_SQ_fx( /**gain_code *= gcode0;*/ L_tmp = L_mult( tmp16, gcode0 ); /* Q0*Q0 -> Q1*/ /**gain_code = L_shl(L_tmp,add(expg,15)); Q16*/ -#ifdef BASOP_NOGLOB *gain_code = L_shl_sat( L_tmp, add( add( expg, exp_gcode0 ), 15 ) ); /*Q16*/ -#else - *gain_code = L_shl( L_tmp, add( add( expg, exp_gcode0 ), 15 ) ); -#endif move32(); /**norm_gain_code = *gain_code / *gain_inov;*/ @@ -1934,11 +1860,7 @@ void gain_dec_amr_wb_fx( /* adjust gain according to energy of code */ L_tmp = Mult_32_16( *gain_code, *gain_inov ); -#ifdef BASOP_NOGLOB *gain_code = L_shl_o( L_tmp, 3, &Overflow ); /* gcode_inov in Q12*/ -#else - *gain_code = L_shl( L_tmp, 3 ); -#endif move32(); /*-----------------------------------------------------------------* diff --git a/lib_dec/gaus_dec.c b/lib_dec/gaus_dec.c deleted file mode 100644 index d441f6ead49ddcb3a6a1ffab0962633db8157cd0..0000000000000000000000000000000000000000 --- a/lib_dec/gaus_dec.c +++ /dev/null @@ -1,43 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include -#include "cnst.h" -#include "rom_com.h" -#include "prot.h" -#include "wmc_auto.h" diff --git a/lib_dec/gs_dec.c b/lib_dec/gs_dec.c deleted file mode 100644 index 79457ca5d89f27400733b171424935cf844532dd..0000000000000000000000000000000000000000 --- a/lib_dec/gs_dec.c +++ /dev/null @@ -1,50 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include -#include "options.h" -#include "cnst.h" -#include "rom_com.h" -#include "prot.h" -#include "ivas_prot.h" -#include "wmc_auto.h" - -/*-------------------------------------------------------------------* - * decod_audio() - * - * Decode audio (AC) frames - *-------------------------------------------------------------------*/ diff --git a/lib_dec/gs_dec_amr_wb.c b/lib_dec/gs_dec_amr_wb.c deleted file mode 100644 index d441f6ead49ddcb3a6a1ffab0962633db8157cd0..0000000000000000000000000000000000000000 --- a/lib_dec/gs_dec_amr_wb.c +++ /dev/null @@ -1,43 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include -#include "cnst.h" -#include "rom_com.h" -#include "prot.h" -#include "wmc_auto.h" diff --git a/lib_dec/gs_dec_amr_wb_fx.c b/lib_dec/gs_dec_amr_wb_fx.c index a4aef88dd698f73733008dd01196d465b25b9c76..65e9eaa87c777a89fa575441dfc820f571d521d5 100644 --- a/lib_dec/gs_dec_amr_wb_fx.c +++ b/lib_dec/gs_dec_amr_wb_fx.c @@ -111,11 +111,7 @@ static void Ener_per_band_fx( IF( L_temp != 0 ) /* avoid executing sqrt of 0 (because a div_s is used to invert and then call inv_sqrt) */ { L_temp2 = Sqrt_Ratio32( L_temp, exp, 1, 0, &i ); -#ifdef BASOP_NOGLOB L_temp2 = L_shr_sat( L_temp2, sub( 15 - ENER_FX_Q_GUARD, i ) ); /* Q16 */ -#else - L_temp2 = L_shr( L_temp2, sub( 15 - ENER_FX_Q_GUARD, i ) ); -#endif } y_gain4_fx[j] = L_temp2; /* Q16 */ move32(); @@ -155,12 +151,8 @@ static void Apply_gain_fx( { EndBin = add( CurBin, crit_bins[i_band] ); /* Q0 */ y_gain_exp = norm_l( L_Ener_per_bd_yQ[i_band] ); - exp3 = norm_l( L_Ener_per_bd_iQ[i_band] ); /* use 'exp3' as temporary exponent of 'L_Ener_per_bd_iQ[]' */ -#ifdef BASOP_NOGLOB + exp3 = norm_l( L_Ener_per_bd_iQ[i_band] ); /* use 'exp3' as temporary exponent of 'L_Ener_per_bd_iQ[]' */ y_gain_fx = round_fx_sat( Div_flt32_flt32( L_shl_sat( L_Ener_per_bd_iQ[i_band], exp3 ), exp3, L_shl_sat( L_Ener_per_bd_yQ[i_band], y_gain_exp ), y_gain_exp, &y_gain_exp ) ); /* y_gain_exp - 31 + Q_out */ -#else - y_gain_fx = round_fx( Div_flt32_flt32( L_shl( L_Ener_per_bd_iQ[i_band], exp3 ), exp3, L_shl( L_Ener_per_bd_yQ[i_band], y_gain_exp ), y_gain_exp, &y_gain_exp ) ); -#endif y_gain_exp = add( sub( y_gain_exp, 31 ), Q_out ); exp3 = sub( y_gain_exp, 16 - 1 ); @@ -204,11 +196,7 @@ static void normalize_spec_fx( temp = Invert16( abs_s( fy_norm_fx[idx] ), &exp ); /* Q15 + exp */ L_temp = L_mult( temp, fac_up_fx ); /* Q15 + exp + Q8 + 1 */ exp = sub( 15, exp ); -#ifdef BASOP_NOGLOB L_temp = L_shl_sat( L_temp, exp ); /* Q24 + Q_out */ -#else - L_temp = L_shl( L_temp, exp ); -#endif FOR( j = 0; j < L_frame; j++ ) { fy_norm_fx[j] = round_fx( Mult_32_16( L_temp, fy_norm_fx[j] ) ); /* Q_out */ @@ -264,11 +252,7 @@ static void gs_dec_amr_wb_fx( move16(); FOR( i = 0; i < CRIT_NOIS_BAND; i++ ) { -#ifdef BASOP_NOGLOB temp = s_max( round_fx_sat( Ener_per_bd_iQ_fx[i] ), temp ); /* Q0 */ -#else - temp = s_max( round_fx( Ener_per_bd_iQ_fx[i] ), temp ); -#endif } test(); @@ -487,11 +471,7 @@ void improv_amr_wb_gs_fx( FOR( i = 0; i < NB_SUBFR; i++ ) { -#ifdef BASOP_NOGLOB enr_LP_new = Enr_1_Az_fx_o( Aq_fx + imult1616( i, ( M + 1 ) ), L_SUBFR, &Overflow ); /* Q3 */ -#else - enr_LP_new = Enr_1_Az_fx( Aq_fx + i * ( M + 1 ), L_SUBFR ); -#endif test(); IF( GT_16( shr( enr_LP_new, 7 ), enr_LP_old ) || Overflow ) { diff --git a/lib_dec/gs_dec_fx.c b/lib_dec/gs_dec_fx.c index bbf06741957530167cd6f9a2c69a92ac3991c050..6c63377fd4798954750060a7477bcf5bf9ad161e 100644 --- a/lib_dec/gs_dec_fx.c +++ b/lib_dec/gs_dec_fx.c @@ -6,7 +6,6 @@ #include "options.h" #include "cnst.h" #include "rom_com.h" -#include "prot.h" #include "prot_fx.h" #include "ivas_cnst.h" /*=========================================================================*/ @@ -75,12 +74,7 @@ void decod_audio_fx( /* decode GSC SWB speech flag */ test(); -#if !defined ADD_LRTD IF( st_fx->coder_type != INACTIVE && GE_32( st_fx->total_brate, ACELP_13k20 ) ) -#else - if ( st_fx->GSC_IVAS_mode >= 1 || ( st_fx->coder_type != INACTIVE && ( ( st_fx->element_mode == EVS_MONO && st_fx->total_brate >= ACELP_13k20 ) || - ( st_fx->element_mode > EVS_MONO && st_fx->total_brate > MIN_BRATE_GSC_NOISY_FLAG && st_fx->bwidth >= SWB && !st_fx->flag_ACELP16k ) ) ) ) -#endif { st_fx->GSC_noisy_speech = (Word16) get_next_indice_fx( st_fx, 1 ); /* Q0 */ move16(); @@ -96,22 +90,19 @@ void decod_audio_fx( st_fx->GSC_noisy_speech = 0; /* Q0 */ move16(); } + /* set bit-allocation */ -#ifdef ADD_LRTD - config_acelp1( DEC, st_fx->total_brate, st_fx->core_brate, st_fx->core, st_fx->extl_orig, st_fx->extl_brate_orig, st_fx->L_frame, st_fx->GSC_noisy_speech, &( st_fx->acelp_cfg ), st_fx->next_bit_pos, st_fx->coder_type, -1, 1, &nbits, NULL, st_fx->element_mode, &nbits /*dummy*/, tdm_lp_reuse_flag, tdm_low_rate_mode, st_fx->idchan, st_fx->active_cnt, tdm_Pitch_reuse_flag, st_fx->tdm_LRTD_flag, st_fx->GSC_IVAS_mode ); +#ifdef NONBE_FIX_GSC_BSTR + config_acelp1( DEC, st_fx->total_brate, st_fx->core_brate, st_fx->core, st_fx->extl_orig, st_fx->extl_brate_orig, st_fx->L_frame, st_fx->GSC_noisy_speech, &( st_fx->acelp_cfg ), st_fx->next_bit_pos, st_fx->coder_type, st_fx->inactive_coder_type_flag, -1, 1, &nbits, NULL, st_fx->element_mode, &nbits /*dummy*/, 0, 0, st_fx->idchan, st_fx->active_cnt, 0, st_fx->tdm_LRTD_flag, st_fx->GSC_IVAS_mode ); #else config_acelp1( DEC, st_fx->total_brate, st_fx->core_brate, st_fx->core, st_fx->extl_orig, st_fx->extl_brate_orig, st_fx->L_frame, st_fx->GSC_noisy_speech, &( st_fx->acelp_cfg ), st_fx->next_bit_pos, st_fx->coder_type, -1, 1, &nbits, NULL, st_fx->element_mode, &nbits /*dummy*/, 0, 0, st_fx->idchan, st_fx->active_cnt, 0, st_fx->tdm_LRTD_flag, st_fx->GSC_IVAS_mode ); #endif + /*---------------------------------------------------------------* * Decode energy dynamics *---------------------------------------------------------------*/ -#if defined ADD_LRTD - test(); - test(); - IF( st_fx->GSC_IVAS_mode >= 1 || ( EQ_16( st_fx->GSC_noisy_speech, 1 ) && st_fx->GSC_IVAS_mode == 0 ) ) -#else + IF( EQ_16( st_fx->GSC_noisy_speech, 1 ) ) -#endif { nb_subfr = NB_SUBFR; /* Q0 */ move16(); @@ -119,25 +110,6 @@ void decod_audio_fx( move16(); hGSCDec->noise_lev = NOISE_LEVEL_SP3; /* Q0 */ move16(); -#ifdef ADD_LRTD - if ( st_fx->GSC_IVAS_mode >= 1 ) - { - if ( st_fx->core_brate < GSC_L_RATE_STG && st_fx->GSC_IVAS_mode < 3 ) - { - nb_subfr = 2; - } - hGSCDec->noise_lev = NOISE_LEVEL_SP2; - - if ( st_fx->GSC_IVAS_mode == 3 ) /* Music like */ - { - hGSCDec->noise_lev = NOISE_LEVEL_SP0; - } - else if ( st_fx->GSC_noisy_speech == 0 ) /* speech like but not noisy */ - { - hGSCDec->noise_lev = NOISE_LEVEL_SP3; - } - } -#endif } ELSE { @@ -155,54 +127,30 @@ void decod_audio_fx( /*---------------------------------------------------------------* * Decode number of subframes *---------------------------------------------------------------*/ -#ifdef ADD_LRTD - if ( st_fx->L_frame == L_FRAME16k && ( st_fx->core_brate <= ACELP_13k20 || st_fx->coder_type == INACTIVE ) ) - { - hGSCDec->cor_strong_limit = 0; - nb_subfr = 1; - } - else -#endif + + + hGSCDec->cor_strong_limit = 1; /* Q0 */ + move16(); + nb_subfr = SWNB_SUBFR; + move16(); + + IF( GE_32( st_fx->core_brate, ACELP_9k60 ) ) { - hGSCDec->cor_strong_limit = 1; /* Q0 */ + nbits = 1; move16(); - nb_subfr = SWNB_SUBFR; + nb_frame_flg = (Word16) get_next_indice_fx( st_fx, nbits ); /* Q0 */ move16(); - IF( GE_32( st_fx->core_brate, ACELP_9k60 ) ) + IF( s_and( nb_frame_flg, 0x1 ) == 0 ) { - nbits = 1; + nb_subfr = 2 * SWNB_SUBFR; /* Q0 */ move16(); -#ifdef ADD_LRTD - if ( st_fx->L_frame == L_FRAME16k && st_fx->core_brate >= MIN_RATE_4SBFR ) - { - nbits = 2; - } -#endif - nb_frame_flg = (Word16) get_next_indice_fx( st_fx, nbits ); /* Q0 */ + hGSCDec->cor_strong_limit = 0; move16(); - - IF( s_and( nb_frame_flg, 0x1 ) == 0 ) - { - nb_subfr = 2 * SWNB_SUBFR; /* Q0 */ - move16(); - hGSCDec->cor_strong_limit = 0; - move16(); - } -#ifdef ADD_LRTD - else if ( st_fx->L_frame == L_FRAME16k && st_fx->core_brate >= MIN_RATE_4SBFR ) - { - nb_subfr = 2 * SWNB_SUBFR; /* cor_strong already set to 1 */ - } - - if ( ( nb_frame_flg >> 1 ) == 1 ) - { - nb_subfr *= 2; - } -#endif } } } + /*---------------------------------------------------------------* * Decode the last band where the adaptive (pitch) contribution is significant *---------------------------------------------------------------*/ @@ -272,13 +220,7 @@ void decod_audio_fx( * Decode adaptive (pitch) excitation contribution *---------------------------------------------------------------*/ test(); -#ifdef ADD_LRTD - if ( !( st_fx->GSC_IVAS_mode > 0 && st_fx->L_frame / nb_subfr == 2 * L_SUBFR && st_fx->GSC_IVAS_mode < 3 ) && - ( ( st_fx->core_brate >= MIN_RATE_FCB || st_fx->GSC_noisy_speech ) && - ( ( nb_subfr == NB_SUBFR && st_fx->L_frame == L_FRAME ) || ( nb_subfr == NB_SUBFR16k && st_fx->L_frame == L_FRAME16k ) ) ) ) -#else IF( EQ_16( st_fx->GSC_noisy_speech, 1 ) && EQ_16( nb_subfr, NB_SUBFR ) ) -#endif { Word16 indice; nbits = Es_pred_bits_tbl[BIT_ALLOC_IDX_fx( st_fx->core_brate, GENERIC, -1, -1 )]; /* Q0 */ @@ -293,11 +235,9 @@ void decod_audio_fx( Es_pred_dec_fx( &Es_pred, indice, nbits, 0 ); } -#ifdef ADD_LRTD - dec_pit_exc_fx( st_fx, Aq, coder_type, Es_pred, pitch_buf, code, exc, bwe_exc, nb_subfr, gain_buf, tdm_Pitch_reuse_flag, tdm_Pri_pitch_buf ); -#else + dec_pit_exc_fx( st_fx, Aq, st_fx->coder_type, Es_pred, pitch_buf, code, exc, bwe_exc, nb_subfr, gain_buf ); -#endif + IF( LT_32( st_fx->core_brate, ACELP_9k60 ) ) { minimum_fx( pitch_buf, shr( st_fx->L_frame, 6 ), &low_pit ); @@ -429,39 +369,19 @@ void decod_audio_fx( tmp_nb_bits_tot = st_fx->next_bit_pos; /* Q0 */ move16(); -#ifdef IVAS_CODE - if ( st_fx->extl_brate_fx_orig > 0 ) -#else + if ( st_fx->extl_brate > 0 ) -#endif { /* subtract 1 bit for TBE/BWE BWE flag (bit counted in extl_brate) */ tmp_nb_bits_tot = sub( tmp_nb_bits_tot, 1 ); /* Q0 */ } - - test(); -#if defined ADD_LRTD - test(); - if ( EQ_16( st_fx->coder_type, INACTIVE ) && LE_32( st_fx->core_brate, ACELP_9k60 ) && st_fx->idchan == 0 ) -#else test(); if ( st_fx->coder_type == INACTIVE && LE_32( st_fx->core_brate, ACELP_9k60 ) ) -#endif { tmp_nb_bits_tot = add( tmp_nb_bits_tot, 5 ); /* Q0 */ } -#ifdef ADD_LRTD - IF( EQ_16( st_fx->idchan, 1 ) ) - { - tmp_nb_bits_tot = add( tmp_nb_bits_tot, TDM_SIGNAL_BITS_READ_FROM_THE_END_OF_BS ); - IF( EQ_16( st_fx->tdm_LRTD_flag, 1 ) ) - { - tmp_nb_bits_tot = sub( tmp_nb_bits_tot, STEREO_BITS_TCA ); - } - } -#endif gsc_dec_fx( st_fx, dct_epit, pit_band_idx, Diff_len, tmp_nb_bits_tot, nb_subfr, st_fx->coder_type, &last_bin, lsf_new, exc_wo_nf, st_fx->Q_exc ); /*--------------------------------------------------------------------------------------* * iDCT transform @@ -600,22 +520,21 @@ void decod_audio_ivas_fx( st_fx->GSC_noisy_speech = 0; move16(); } + /* set bit-allocation */ -#if 1 // def ADD_LRTD - config_acelp1_IVAS( DEC, st_fx->total_brate, st_fx->core_brate, st_fx->core, st_fx->extl_orig, st_fx->extl_brate_orig, st_fx->L_frame, st_fx->GSC_noisy_speech, &( st_fx->acelp_cfg ), st_fx->next_bit_pos, st_fx->coder_type, -1, 1, &nbits, NULL, st_fx->element_mode, &nbits /*dummy*/, tdm_lp_reuse_flag, tdm_low_rate_mode, st_fx->idchan, st_fx->active_cnt, tdm_Pitch_reuse_flag, st_fx->tdm_LRTD_flag, st_fx->GSC_IVAS_mode ); +#ifdef NONBE_FIX_GSC_BSTR + config_acelp1_IVAS( DEC, st_fx->total_brate, st_fx->core_brate, st_fx->core, st_fx->extl_orig, st_fx->extl_brate_orig, st_fx->L_frame, st_fx->GSC_noisy_speech, &( st_fx->acelp_cfg ), st_fx->next_bit_pos, st_fx->coder_type, st_fx->inactive_coder_type_flag, -1, 1, &nbits, NULL, st_fx->element_mode, &nbits /*dummy*/, tdm_lp_reuse_flag, tdm_low_rate_mode, st_fx->idchan, st_fx->active_cnt, tdm_Pitch_reuse_flag, st_fx->tdm_LRTD_flag, st_fx->GSC_IVAS_mode ); #else - config_acelp1( DEC, st_fx->total_brate, st_fx->core_brate, st_fx->core, st_fx->extl_orig, st_fx->extl_brate_orig, st_fx->L_frame, st_fx->GSC_noisy_speech, &( st_fx->acelp_cfg ), st_fx->next_bit_pos, st_fx->coder_type, -1, 1, &nbits, NULL, st_fx->element_mode, &nbits /*dummy*/, 0, 0, st_fx->idchan, st_fx->active_cnt, 0, st_fx->tdm_LRTD_flag, st_fx->GSC_IVAS_mode ); + config_acelp1_IVAS( DEC, st_fx->total_brate, st_fx->core_brate, st_fx->core, st_fx->extl_orig, st_fx->extl_brate_orig, st_fx->L_frame, st_fx->GSC_noisy_speech, &( st_fx->acelp_cfg ), st_fx->next_bit_pos, st_fx->coder_type, -1, 1, &nbits, NULL, st_fx->element_mode, &nbits /*dummy*/, tdm_lp_reuse_flag, tdm_low_rate_mode, st_fx->idchan, st_fx->active_cnt, tdm_Pitch_reuse_flag, st_fx->tdm_LRTD_flag, st_fx->GSC_IVAS_mode ); #endif + /*---------------------------------------------------------------* * Decode energy dynamics *---------------------------------------------------------------*/ -#if 1 // defined ADD_LRTD + test(); test(); IF( GE_16( st_fx->GSC_IVAS_mode, 1 ) || ( EQ_16( st_fx->GSC_noisy_speech, 1 ) && st_fx->GSC_IVAS_mode == 0 ) ) -#else - IF( EQ_16( st_fx->GSC_noisy_speech, 1 ) ) -#endif { nb_subfr = NB_SUBFR; /* Q0 */ move16(); @@ -623,7 +542,7 @@ void decod_audio_ivas_fx( move16(); hGSCDec->noise_lev = NOISE_LEVEL_SP3; /* Q0 */ move16(); -#if 1 // def ADD_LRTD + IF( GE_16( st_fx->GSC_IVAS_mode, 1 ) ) { test(); @@ -646,7 +565,6 @@ void decod_audio_ivas_fx( move16(); } } -#endif } ELSE { @@ -664,7 +582,7 @@ void decod_audio_ivas_fx( /*---------------------------------------------------------------* * Decode number of subframes *---------------------------------------------------------------*/ -#if 1 // def ADD_LRTD + test(); test(); IF( EQ_16( st_fx->L_frame, L_FRAME16k ) && ( LE_32( st_fx->core_brate, ACELP_13k20 ) || st_fx->coder_type == INACTIVE ) ) @@ -675,7 +593,6 @@ void decod_audio_ivas_fx( move16(); } ELSE -#endif { hGSCDec->cor_strong_limit = 1; /* Q0 */ move16(); @@ -686,14 +603,14 @@ void decod_audio_ivas_fx( { nbits = 1; /* Q0 */ move16(); -#if 1 // def ADD_LRTD + test(); if ( EQ_16( st_fx->L_frame, L_FRAME16k ) && GE_32( st_fx->core_brate, MIN_RATE_4SBFR ) ) { nbits = 2; /* Q0 */ move16(); } -#endif + nb_frame_flg = (Word16) get_next_indice_fx( st_fx, nbits ); /* Q0 */ move16(); @@ -705,7 +622,6 @@ void decod_audio_ivas_fx( hGSCDec->cor_strong_limit = 0; move16(); } -#if 1 // def ADD_LRTD ELSE IF( EQ_16( st_fx->L_frame, L_FRAME16k ) && GE_32( st_fx->core_brate, MIN_RATE_4SBFR ) ) { nb_subfr = 2 * SWNB_SUBFR; /* cor_strong already set to 1 */ @@ -716,18 +632,17 @@ void decod_audio_ivas_fx( { nb_subfr = shl( nb_subfr, 1 ); /* Q0 */ } -#endif } } } -#if 1 + test(); if ( EQ_16( st_fx->L_frame, L_FRAME16k ) && EQ_16( nb_subfr, NB_SUBFR ) ) { nb_subfr = NB_SUBFR16k; /* Q0 */ move16(); } -#endif + /*---------------------------------------------------------------* * Decode the last band where the adaptive (pitch) contribution is significant *---------------------------------------------------------------*/ @@ -786,7 +701,6 @@ void decod_audio_ivas_fx( hGSCDec->Last_GSC_pit_band_idx = pit_band_idx; /* Q0 */ move16(); - /*--------------------------------------------------------------------------------------* * Decode adaptive (pitch) excitation contribution * Reset unvaluable part of the adaptive (pitch) excitation contribution @@ -797,7 +711,6 @@ void decod_audio_ivas_fx( * Decode adaptive (pitch) excitation contribution *---------------------------------------------------------------*/ test(); -#if 1 // def ADD_LRTD test(); test(); test(); @@ -808,9 +721,6 @@ void decod_audio_ivas_fx( IF( !( ( st_fx->GSC_IVAS_mode > 0 ) && EQ_16( idiv1616( st_fx->L_frame, nb_subfr ), 2 * L_SUBFR ) && LT_16( st_fx->GSC_IVAS_mode, 3 ) ) && ( ( GE_32( st_fx->core_brate, MIN_RATE_FCB ) || st_fx->GSC_noisy_speech ) && ( ( EQ_16( nb_subfr, NB_SUBFR ) && EQ_16( st_fx->L_frame, L_FRAME ) ) || ( EQ_16( nb_subfr, NB_SUBFR16k ) && EQ_16( st_fx->L_frame, L_FRAME16k ) ) ) ) ) -#else - IF( EQ_16( st_fx->GSC_noisy_speech, 1 ) && EQ_16( nb_subfr, NB_SUBFR ) ) -#endif { Word16 indice; nbits = Es_pred_bits_tbl[BIT_ALLOC_IDX_fx( st_fx->core_brate, GENERIC, -1, -1 )]; /* Q0 */ @@ -825,11 +735,9 @@ void decod_audio_ivas_fx( Es_pred_dec_fx( &Es_pred, indice, nbits, 0 ); } -#if 1 // def ADD_LRTD + dec_pit_exc_ivas_fx( st_fx, Aq, st_fx->coder_type, Es_pred, pitch_buf, code, exc, bwe_exc, nb_subfr, gain_buf, tdm_Pitch_reuse_flag, tdm_Pri_pitch_buf ); -#else - dec_pit_exc_fx( st_fx, Aq, st_fx->coder_type, Es_pred, pitch_buf, code, exc, bwe_exc, nb_subfr, gain_buf ); -#endif + IF( LT_32( st_fx->core_brate, ACELP_9k60 ) ) { minimum_fx( pitch_buf, shr( st_fx->L_frame, 6 ), &low_pit ); @@ -961,29 +869,20 @@ void decod_audio_ivas_fx( tmp_nb_bits_tot = st_fx->next_bit_pos; /* Q0 */ move16(); -#if 1 // def IVAS_CODE + if ( st_fx->extl_brate_orig > 0 ) -#else - if ( st_fx->extl_brate > 0 ) -#endif { /* subtract 1 bit for TBE/BWE BWE flag (bit counted in extl_brate) */ tmp_nb_bits_tot = sub( tmp_nb_bits_tot, 1 ); /* Q0 */ } - test(); -#if 1 // defined ADD_LRTD test(); if ( st_fx->coder_type == INACTIVE && LE_32( st_fx->core_brate, ACELP_9k60 ) && st_fx->idchan == 0 ) -#else - if ( EQ_16( st_fx->coder_type, INACTIVE ) && LE_32( st_fx->core_brate, ACELP_9k60 ) ) -#endif { tmp_nb_bits_tot = add( tmp_nb_bits_tot, 5 ); /* Q0 */ } -#if 1 // ydef ADD_LRTD IF( EQ_16( st_fx->idchan, 1 ) ) { tmp_nb_bits_tot = add( tmp_nb_bits_tot, TDM_SIGNAL_BITS_READ_FROM_THE_END_OF_BS ); /* Q0 */ @@ -992,7 +891,7 @@ void decod_audio_ivas_fx( tmp_nb_bits_tot = sub( tmp_nb_bits_tot, STEREO_BITS_TCA ); /* Q0 */ } } -#endif + Word16 Q_exc_old = st_fx->Q_exc; move16(); gsc_dec_ivas_fx( st_fx, dct_epit, pit_band_idx, Diff_len, tmp_nb_bits_tot, nb_subfr, st_fx->coder_type, &last_bin, lsf_new, exc_wo_nf, &st_fx->Q_exc ); @@ -1089,7 +988,6 @@ void gsc_dec_fx( Word16 Q_exc ) { Word16 i, j, bit, nb_subbands, pvq_len; -#if 1 // def ADD_LRTD Word16 bitallocation_band[MBANDS_GN_BITALLOC16k]; Word16 bitallocation_exc[2]; Word16 Ener_per_bd_iQ[MBANDS_GN_BITALLOC16k]; @@ -1097,15 +995,6 @@ void gsc_dec_fx( Word16 exc_diffQ[L_FRAME16k]; Word16 bits_per_bands[MBANDS_GN_BITALLOC16k]; Word16 concat_out[L_FRAME16k]; -#else - Word16 bitallocation_band[MBANDS_GN]; - Word16 bitallocation_exc[2]; - Word16 Ener_per_bd_iQ[MBANDS_GN]; - Word16 max_ener_band[MBANDS_GN]; - Word16 exc_diffQ[L_FRAME]; - Word16 bits_per_bands[MBANDS_GN]; - Word16 concat_out[L_FRAME]; -#endif Word16 inpulses_fx[NB_SFM]; Word16 imaxpulse_fx[NB_SFM]; Word16 mean_gain; @@ -1129,22 +1018,7 @@ void gsc_dec_fx( *--------------------------------------------------------------------------------------*/ bit = bits_used; move16(); -#ifdef ADD_LRTD - test(); - test(); - test(); - test(); - IF( EQ_16( coder_type, INACTIVE ) && ( EQ_16( st_fx->tdm_LRTD_flag, 1 ) || EQ_16( st_fx->element_mode, IVAS_SCE ) ) && LE_32( st_fx->core_brate, GSC_LRES_GAINQ_LIMIT ) ) - { - bit = add( bit, GSC_LRES_NB_NITS ); - } - IF( EQ_16( st_fx->L_frame, L_FRAME16k ) ) - { - Mbands_gn = MBANDS_GN16k; - move16(); - } -#endif set16_fx( exc_diffQ, 0, st_fx->L_frame ); /*--------------------------------------------------------------------------------------* @@ -1168,33 +1042,8 @@ void gsc_dec_fx( } ELSE { - -#ifdef ADD_LRTD - i = 0; - move16(); - While( LT_16( i, SIZE_BRATE_INTERMED_TBL ) ) - { - IF( LQ_32( st_fx->core_brate, brate_intermed_tbl[i] ) ) - { - break; - } - i = add( i, 1 ); - } - - test(); - test(); - test(); - test(); - IF( GT_16( st_fx->element_mode, EVS_MONO ) > &&EQ_16( coder_type, AUDIO ) && - LE_32( st_fx->core_brate, STEREO_GSC_BIT_RATE_ALLOC ) && EQ_32( brate_intermed_tbl[i], ACELP_9k60 ) ) /* Bit allocation is mapped to 8 kb/s instead of 9.6 kb/s in this case */ - { - i--; - } - mean_gain = gsc_gaindec_fx( st_fx, Ener_per_bd_iQ, brate_intermed_tbl[i], hGSCDec->old_y_gain_fx, coder_type, st_fx->bwidth ); - -#else mean_gain = gsc_gaindec_fx( st_fx, Ener_per_bd_iQ, st_fx->core_brate, hGSCDec->old_y_gain_fx, coder_type, st_fx->bwidth ); /* Q12 */ -#endif + st_fx->lp_gainc_fx = mult_r( 640, mean_gain ); /*10 in Q6 x Q12 -> lp_gainc in Q3 */ move16(); } @@ -1220,10 +1069,7 @@ void gsc_dec_fx( * reduce spectral dynamic * save spectrum *--------------------------------------------------------------------------------------*/ -#ifdef ADD_LRTD - max_eq = 32767; - move16(); -#endif + test(); IF( EQ_16( st_fx->last_good, INACTIVE_CLAS ) || EQ_16( st_fx->Last_GSC_noisy_speech_flag, 1 ) ) { @@ -1254,12 +1100,6 @@ void gsc_dec_fx( max_ener_band, bits_per_bands, &nb_subbands, NULL, NULL, &pvq_len, coder_type, st_fx->bwidth, st_fx->GSC_noisy_speech, st_fx->L_frame, st_fx->element_mode, st_fx->GSC_IVAS_mode ); -#ifdef ADD_LRTD - if ( bit == 0 ) - { - set16_fx( concact_out, 0, L_FRAME16k ); - } -#endif { pvq_core_dec_fx( st_fx, gsc_sfm_start, gsc_sfm_end, gsc_sfm_size, concat_out, &Q_tmp, bit, nb_subbands, bits_per_bands, NULL, inpulses_fx, imaxpulse_fx, ACELP_CORE ); Scale_sig( concat_out, gsc_sfm_end[nb_subbands - 1], sub( Q_PVQ_OUT, Q_tmp ) ); /* Q_PVQ_OUT */ @@ -1267,17 +1107,6 @@ void gsc_dec_fx( seed_init = 0; move16(); -#ifdef ADD_LRTD - max_eq = 0.0f; - max_eq_val = 1.0f; - - if ( ( ( st_fx->core_brate < ACELP_7k20 && st_fx->GSC_noisy_speech == 1 ) || st_fx->core_brate < 6000 ) && coder_type <= UNVOICED ) - { - j = emaximum( concat_out, nb_subbands * 16, &max_eq ); - max_eq = (float) ( max_eq_val / ( fabs( concat_out[j] ) + 0.01f ) ); - max_eq = min( max_eq_val, max_eq ); - } -#endif /* Reorder Q bands */ FOR( j = 0; j < nb_subbands; j++ ) { @@ -1334,34 +1163,8 @@ void gsc_dec_fx( * Find x pulses between 1.6-3.2kHz to code in the spectrum of the residual signal * Gain is based on the inter-correlation gain between the pulses found and residual signal *--------------------------------------------------------------------------------------*/ -#ifdef ADD_LRTD - test(); - test(); - test(); - test(); - test(); - test(); - IF( GE_16( st_fx->GSC_IVAS_mode, 1 ) && EQ_16( st_fx->GSC_noisy_speech, 1 ) ) - { - FOR( i = 64; i < st_fx->L_frame; i++ ) - { - PMT( "GSC FIX point to be done here" ) - exc_diffQ[i] *= max_eq; - } - } - ELSE IF( ( ( LT_32( st_fx->core_brate, ACELP_7k20 ) && EQ_16( st_fx->GSC_noisy_speech, 1 ) ) || LT_32( st_fx->core_brate, 6000 ) ) && LE_16( st_fx->coder_type, UNVOICED ) ) - { - FOR( i = 0; i < L_FRAME; i++ ) - { - PMT( "GSC FIX point to be done here" ) - exc_diffQ[i] *= max_eq; - } - } - else -#endif - { - freq_dnw_scaling_fx( hGSCDec->cor_strong_limit, st_fx->coder_type, hGSCDec->noise_lev, st_fx->core_brate, exc_diffQ, Qexc_diffQ, st_fx->L_frame ); - } + + freq_dnw_scaling_fx( hGSCDec->cor_strong_limit, st_fx->coder_type, hGSCDec->noise_lev, st_fx->core_brate, exc_diffQ, Qexc_diffQ, st_fx->L_frame ); } /*--------------------------------------------------------------------------------------* @@ -1416,7 +1219,6 @@ void gsc_dec_ivas_fx( Word16 *Q_exc ) { Word16 i, j, bit, nb_subbands, pvq_len; -#if 1 // def ADD_LRTD Word16 bitallocation_band[MBANDS_GN_BITALLOC16k]; Word16 bitallocation_exc[2]; Word16 Ener_per_bd_iQ[MBANDS_GN_BITALLOC16k]; @@ -1425,19 +1227,10 @@ void gsc_dec_ivas_fx( Word16 bits_per_bands[MBANDS_GN_BITALLOC16k]; Word16 concat_out[L_FRAME16k]; Word16 max_eq, max_eq_val; -#else - Word16 bitallocation_band[MBANDS_GN]; - Word16 bitallocation_exc[2]; - Word16 Ener_per_bd_iQ[MBANDS_GN]; - Word16 max_ener_band[MBANDS_GN]; - Word16 exc_diffQ[L_FRAME]; - Word16 bits_per_bands[MBANDS_GN]; - Word16 concat_out[L_FRAME]; -#endif Word16 inpulses_fx[NB_SFM]; Word16 imaxpulse_fx[NB_SFM]; Word16 mean_gain; - Word16 Mbands_gn = 16; + Word16 Mbands_gn = MBANDS_GN; Word16 Qexc_diffQ = Q_PVQ_OUT; Word32 L_tmp; Word16 Q_tmp; @@ -1445,8 +1238,8 @@ void gsc_dec_ivas_fx( GSC_DEC_HANDLE hGSCDec; hGSCDec = st_fx->hGSCDec; - move16(); // for Mbands_gn - move16(); // for Qexc_diffQ + move16(); /* for Mbands_gn */ + move16(); /* for Qexc_diffQ */ set16_fx( inpulses_fx, 0, NB_SFM ); set16_fx( imaxpulse_fx, 0, NB_SFM ); @@ -1455,7 +1248,7 @@ void gsc_dec_ivas_fx( *--------------------------------------------------------------------------------------*/ bit = bits_used; move16(); -#if 1 // def ADD_LRTD + test(); test(); test(); @@ -1469,7 +1262,7 @@ void gsc_dec_ivas_fx( Mbands_gn = MBANDS_GN16k; /* Q0 */ move16(); } -#endif + set16_fx( exc_diffQ, 0, st_fx->L_frame ); /*--------------------------------------------------------------------------------------* @@ -1493,8 +1286,6 @@ void gsc_dec_ivas_fx( } ELSE { - -#if 1 // def ADD_LRTD i = 0; move16(); WHILE( LT_16( i, SIZE_BRATE_INTERMED_TBL ) ) @@ -1516,9 +1307,6 @@ void gsc_dec_ivas_fx( } mean_gain = gsc_gaindec_ivas_fx( st_fx, Ener_per_bd_iQ, brate_intermed_tbl[i], hGSCDec->old_y_gain_fx, coder_type, st_fx->bwidth ); /* Q3 */ -#else - mean_gain = gsc_gaindec_fx( st_fx, Ener_per_bd_iQ, st_fx->core_brate, hGSCDec->old_y_gain_fx, coder_type, st_fx->bwidth ); -#endif st_fx->lp_gainc_fx = mult_r( 640, mean_gain ); /*10 in Q6 x Q12 -> lp_gainc in Q3 */ move16(); } @@ -1544,17 +1332,17 @@ void gsc_dec_ivas_fx( * reduce spectral dynamic * save spectrum *--------------------------------------------------------------------------------------*/ -#if 1 // def ADD_LRTD + max_eq = 32767; move16(); -#endif + test(); IF( EQ_16( st_fx->last_good, INACTIVE_CLAS ) || EQ_16( st_fx->Last_GSC_noisy_speech_flag, 1 ) ) { FOR( i = 0; i < st_fx->L_frame; i++ ) { L_tmp = L_shr( L_mult( Random( &hGSCDec->seed_tcx ), 26214 ), 5 ); /*Q10*/ - L_tmp = L_mac( L_tmp, hGSCDec->Last_GSC_spectrum_fx[i], 6554 ); /* Q10 */ + L_tmp = L_mac( L_tmp, hGSCDec->Last_GSC_spectrum_fx[i], 6554 ); /*Q10*/ hGSCDec->Last_GSC_spectrum_fx[i] = round_fx( L_tmp ); /*Q10*/ move16(); } @@ -1578,20 +1366,24 @@ void gsc_dec_ivas_fx( max_ener_band, bits_per_bands, &nb_subbands, NULL, NULL, &pvq_len, coder_type, st_fx->bwidth, st_fx->GSC_noisy_speech, st_fx->L_frame, st_fx->element_mode, st_fx->GSC_IVAS_mode ); -#if 1 // def ADD_LRTD IF( bit == 0 ) { set16_fx( concat_out, 0, L_FRAME16k ); } -#endif + + pvq_core_dec_fx( st_fx, gsc_sfm_start, gsc_sfm_end, gsc_sfm_size, concat_out, &Q_tmp, bit, nb_subbands, bits_per_bands, NULL, inpulses_fx, imaxpulse_fx, ACELP_CORE ); +#ifdef MSAN_FIX + IF( nb_subbands > 0 ) { - pvq_core_dec_fx( st_fx, gsc_sfm_start, gsc_sfm_end, gsc_sfm_size, concat_out, &Q_tmp, bit, nb_subbands, bits_per_bands, NULL, inpulses_fx, imaxpulse_fx, ACELP_CORE ); Scale_sig( concat_out, gsc_sfm_end[nb_subbands - 1], sub( Q_PVQ_OUT, Q_tmp ) ); /* Q_PVQ_OUT */ } +#else + Scale_sig( concat_out, gsc_sfm_end[nb_subbands - 1], sub( Q_PVQ_OUT, Q_tmp ) ); /* Q_PVQ_OUT */ +#endif + seed_init = 0; move16(); -#if 1 // def ADD_LRTD max_eq = 0; move16(); max_eq_val = 32767; /* 1.0f in Q15 */ @@ -1603,7 +1395,6 @@ void gsc_dec_ivas_fx( IF( ( ( LT_32( st_fx->core_brate, ACELP_7k20 ) && EQ_16( st_fx->GSC_noisy_speech, 1 ) ) || LT_32( st_fx->core_brate, 6000 ) ) && LE_16( coder_type, UNVOICED ) ) { j = maximum_fx( concat_out, imult1616( nb_subbands, 16 ), &max_eq ); - // max_eq = max_eq_val / (abs_s(concat_out[j]) + 328 /*0.01f*/ ); Word16 temp_max_eq = add( abs_s( concat_out[j] ), 10 ) /*0.01f in Q10*/; if ( LE_16( temp_max_eq, ONE_IN_Q10 ) ) { @@ -1618,7 +1409,7 @@ void gsc_dec_ivas_fx( max_eq = shl( max_eq, exp ); /* Q15 */ } } -#endif + /* Reorder Q bands */ FOR( j = 0; j < nb_subbands; j++ ) { @@ -1678,7 +1469,7 @@ void gsc_dec_ivas_fx( * Find x pulses between 1.6-3.2kHz to code in the spectrum of the residual signal * Gain is based on the inter-correlation gain between the pulses found and residual signal *--------------------------------------------------------------------------------------*/ -#if 1 // def ADD_LRTD + test(); test(); test(); @@ -1687,8 +1478,6 @@ void gsc_dec_ivas_fx( { FOR( i = 64; i < st_fx->L_frame; i++ ) { - // PMT("GSC FIX point to be done here") - // exc_diffQ[i] *= max_eq; exc_diffQ[i] = mult_r( exc_diffQ[i], max_eq ); /* Q_PVQ_OUT */ move16(); } @@ -1697,14 +1486,11 @@ void gsc_dec_ivas_fx( { FOR( i = 0; i < L_FRAME; i++ ) { - // PMT("GSC FIX point to be done here") - // exc_diffQ[i] *= max_eq; exc_diffQ[i] = mult_r( exc_diffQ[i], max_eq ); /* Q_PVQ_OUT */ move16(); } } ELSE -#endif { freq_dnw_scaling_fx( hGSCDec->cor_strong_limit, st_fx->coder_type, hGSCDec->noise_lev, st_fx->core_brate, exc_diffQ, Qexc_diffQ, st_fx->L_frame ); } @@ -1745,17 +1531,11 @@ void GSC_dec_init( move16(); move16(); -#ifdef ADD_LRTD - set16_fx( hGSCDec->Last_GSC_spectrum_fx, 0, L_FRAME16k ); - set16_fx( hGSCDec->last_exc_dct_in_fx, 0, L_FRAME16k ); - set16_fx( hGSCDec->lt_ener_per_band_fx, 4096, MBANDS_GN_BITALLOC16k ); - set16_fx( hGSCDec->old_y_gain_fx, 0, MBANDS_GN_BITALLOC16k ); -#else set16_fx( hGSCDec->Last_GSC_spectrum_fx, 0, L_FRAME ); set16_fx( hGSCDec->last_exc_dct_in_fx, 0, L_FRAME ); set16_fx( hGSCDec->old_y_gain_fx, 0, MBANDS_GN ); set16_fx( hGSCDec->lt_ener_per_band_fx, 4096, MBANDS_GN ); /*Q12*/ -#endif + hGSCDec->last_ener_fx = 0; move16(); set16_fx( hGSCDec->last_bitallocation_band, 0, 6 ); diff --git a/lib_dec/hdecnrm.c b/lib_dec/hdecnrm.c deleted file mode 100644 index 56e7b45fee58bbf657962368390a21ea3df5f681..0000000000000000000000000000000000000000 --- a/lib_dec/hdecnrm.c +++ /dev/null @@ -1,85 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include "cnst.h" -#include "prot.h" -#include "rom_com.h" -#include "rom_dec.h" -#include "wmc_auto.h" - - -/*--------------------------------------------------------------------------*/ -/* Function decode_huff_context() */ -/* */ -/* Context based Huffman decoding for indices of quantized norms */ -/*--------------------------------------------------------------------------*/ - - -/*--------------------------------------------------------------------------*/ -/* Function hdecnrm() */ -/* */ -/* Huffman decoding for indices of quantized norms */ -/*--------------------------------------------------------------------------*/ - - -/*-------------------------------------------------------------------------- - * huff_dec() - * - * Huffman decoding - *--------------------------------------------------------------------------*/ - - -/*-------------------------------------------------------------------------- - * hdecnrm_context() - * - * Huffman decoding for indices of quantized norms - *--------------------------------------------------------------------------*/ - - -/*-------------------------------------------------------------------------- - * hdecnrm_resize() - * - * - *--------------------------------------------------------------------------*/ - - -/*-------------------------------------------------------------------------- - * hdecnrm_trans() - * - * Huffman decoding for indices of quantized norms - *--------------------------------------------------------------------------*/ diff --git a/lib_dec/hf_synth.c b/lib_dec/hf_synth.c deleted file mode 100644 index 8070239de50819efd37d9572e70571081767b81a..0000000000000000000000000000000000000000 --- a/lib_dec/hf_synth.c +++ /dev/null @@ -1,112 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include -#include "cnst.h" -#include "prot.h" -#include "rom_com.h" -#include "wmc_auto.h" -#include "prot_fx.h" -#include "basop32.h" - -/*---------------------------------------------------------------------* - * Local function prototypes - *---------------------------------------------------------------------*/ - - -/*-----------------------------------------------------------------------------------* - * hf_synthesis_amr_wb() - * - * HF noise synthesis - * - Generate HF noise between 6 and 8 kHz, mix it with signal obtained by linear resampling. - * - Set energy of high band - *-----------------------------------------------------------------------------------*/ - - -/*-----------------------------------------------------------------------------------* - * EnhanceClass() - * - * - *-----------------------------------------------------------------------------------*/ - - -/*-----------------------------------------------------------------------------------* - * envelope() - * - * - *-----------------------------------------------------------------------------------*/ - - -/*---------------------------------------------------------------------* - * AdaptiveStartBand() - * - * adaptively select the start band of bandwidth extension - *---------------------------------------------------------------------*/ - - -/*-----------------------------------------------------------------------* - * hp400_12k8() - * - * 2nd order Cheb2 high pass filter with cut off frequency at 400 Hz. - * Optimized for fixed-point to get the following frequency response: - * - * frequency : 0Hz 100Hz 200Hz 300Hz 400Hz 630Hz 1.5kHz 3kHz - * dB loss : -infdB -30dB -20dB -10dB -3dB +6dB +1dB 0dB - * - * Algorithm : - * - * y[i] = b[0]*x[i] + b[1]*x[i-1] + b[2]*x[i-2] - * + a[1]*y[i-1] + a[2]*y[i-2]; - * - * short b[3] = {3660, -7320, 3660}; in Q12 - * short a[3] = {4096, 7320, -3540}; in Q12 - * - * float b[3] = {0.893554687, -1.787109375, 0.893554687}; - * float a[3] = {1.000000000, 1.787109375, -0.864257812}; - *-----------------------------------------------------------------------*/ - - -/*-------------------------------------------------------------------* - * filt_6k_7k() - * - * 15th order band pass 6kHz to 7kHz FIR filter - * - * frequency :4kHz 5kHz 5.5kHz 6kHz 6.5kHz 7kHz 7.5kHz 8kHz - * dB loss : -60dB -45dB -13dB -3dB 0dB -3dB -13dB -45dB - * (gain = 4.0) - *-------------------------------------------------------------------*/ diff --git a/lib_dec/hf_synth_fx.c b/lib_dec/hf_synth_fx.c index e931ae229eafdbb14229cc16da6c2620fa4ba92e..ee7a7eca61bb4ef92182e732a772ae6b5c787f0f 100644 --- a/lib_dec/hf_synth_fx.c +++ b/lib_dec/hf_synth_fx.c @@ -7,7 +7,6 @@ #include "prot_fx.h" /* Function prototypes */ #include "rom_com.h" /* Static table prototypes */ #include "basop32.h" -#include "prot.h" /*---------------------------------------------------------------------* * Local constants @@ -209,11 +208,7 @@ static void hf_synthesis_fx( L_tmp = L_mac( 1L, synth[0], synth[0] ); /* 2*(Q_syn-3)+1 */ FOR( i = 1; i < L_SUBFR; i++ ) { -#ifdef BASOP_NOGLOB L_tmp = L_mac_sat( L_tmp, synth[i], synth[i] ); /* 2*(Q_syn-3)+1 */ -#else - L_tmp = L_mac( L_tmp, synth[i], synth[i] ); -#endif } tmp = norm_l( L_tmp ); ener = extract_h( L_shl( L_tmp, tmp ) ); /* ener = r[0] */ @@ -222,11 +217,7 @@ static void hf_synthesis_fx( L_tmp = L_mac( 1L, synth[1], synth[0] ); /* 2*(Q_syn-3)+1 */ FOR( i = 2; i < L_SUBFR; i++ ) { -#ifdef BASOP_NOGLOB L_tmp = L_mac_sat( L_tmp, synth[i], synth[i - 1] ); /* 2*(Q_syn-3)+1 */ -#else - L_tmp = L_mac( L_tmp, synth[i], synth[i - 1] ); -#endif } tmp = extract_h( L_shl( L_tmp, tmp ) ); /* tmp = r[1] */ /*tmp in Q = 2*(Q_syn-3)+1 = Q-5 when Q_syn=0 */ @@ -245,21 +236,13 @@ static void hf_synthesis_fx( *-----------------------------------------------------------------*/ /* tmp = 1.0 - fac */ -#ifdef BASOP_NOGLOB tmp = add_o( 1, sub( 32767 /* 1 in Q15 */, tmp ), &Overflow ); -#else - tmp = add( 1, sub( 32767, tmp ) ); -#endif test(); if ( core_brate == FRAME_NO_DATA || EQ_32( core_brate, SID_2k40 ) ) { /* emphasize HF noise in CNG */ /*fac *= 2.0f;*/ -#ifdef BASOP_NOGLOB tmp = add_o( tmp, tmp, &Overflow ); /* Q15 */ -#else - tmp = add( tmp, tmp ); -#endif } tmp = s_max( tmp, 3277 ); /* 0.1 in Q15 */ @@ -380,19 +363,11 @@ static void filt_6k_7k_scale_fx( move32(); FOR( j = 0; j < 31; j++ ) { -#ifdef BASOP_NOGLOB L_tmp = L_mac_o( L_tmp, x[i + j], fir_6k_7k_fx[j], &Overflow ); /* Q16 */ -#else - L_tmp = L_mac( L_tmp, x[i + j], fir_6k_7k_fx[j] ); -#endif } -#ifdef BASOP_NOGLOB signal[i] = round_fx_o( L_tmp, &Overflow ); /* Q0 */ move16(); -#else - signal[i] = round_fx( L_tmp ); -#endif } Copy( x + lg, mem, L_FIR - 1 ); /* Qx - 2 */ } @@ -630,12 +605,8 @@ void hf_synth_amr_wb_fx( fmerit_w = shr( fmerit_w, 1 ); /* Q14 */ } -#ifdef BASOP_NOGLOB L_tmp = L_mult( fmerit_w, add_sat( 16384, voice_fac ) ); /* Q14 */ -#else - L_tmp = L_mult( fmerit_w, add( 16384, voice_fac ) ); -#endif - fmerit_w = extract_l( L_shr( L_tmp, 15 ) ); /*Q14 */ + fmerit_w = extract_l( L_shr( L_tmp, 15 ) ); /*Q14 */ /**fmerit_w_sm = add(mult_r(*fmerit_w_sm, 29491), mult_r(fmerit_w, 3277)); //Q14 */ hAmrwb_IO->fmerit_w_sm_fx = round_fx( L_mac( L_mult( hAmrwb_IO->fmerit_w_sm_fx, 29491 ), fmerit_w, 3277 ) ); /*Q14 */ move16(); @@ -702,7 +673,7 @@ void hf_synth_amr_wb_fx( q_tmp = Exp16Array( L_FRAME, exc ); qdct = sub( q_tmp, 1 ); - Copy_Scale_sig_16_32( exc, exc32, L_FRAME, qdct ); /* Qexc + qdct */ + Copy_Scale_sig_16_32_DEPREC( exc, exc32, L_FRAME, qdct ); /* Qexc + qdct */ qdct = add( qdct, Q_exc ); edct_fx( exc32, dct_exc32, L_FRAME, &qdct ); @@ -775,11 +746,7 @@ void hf_synth_amr_wb_fx( pt4 = &dct_hb[240]; FOR( j = 0; j < fn; j++ ) { -#ifdef BASOP_NOGLOB tmp = add_sat( tmp, shr( *pt4++, 2 ) ); /*qdct-2 */ -#else - tmp = add( tmp, shr( *pt4++, 2 ) ); /*qdct-2 */ -#endif } *pt1 = round_fx( L_shl( L_mult( tmp, tmp1 ), 2 ) ); /*qdct */ move16(); @@ -802,11 +769,7 @@ void hf_synth_amr_wb_fx( pt4 = &dct_hb[fb + 240]; FOR( j = fb; j < fn; j++ ) { -#ifdef BASOP_NOGLOB tmp = add_sat( tmp, shr( *pt4++, 2 ) ); /*qdct-2 */ -#else - tmp = add( tmp, shr( *pt4++, 2 ) ); /*qdct-2 */ -#endif } *pt1 = mult_r( tmp, 8738 ); move16(); /* 8738 = 1/15 in Q17 qdct */ @@ -814,11 +777,7 @@ void hf_synth_amr_wb_fx( move16(); IF( *pt2 > 0 ) { -#ifdef BASOP_NOGLOB L_tmp = L_mac0_sat( L_tmp, shr( *pt2, 1 ), shr( *pt2, 1 ) ); /*2*qdct-2 */ -#else - L_tmp = L_mac0( L_tmp, shr( *pt2, 1 ), shr( *pt2, 1 ) ); -#endif } pt1++; pt2++; @@ -834,11 +793,7 @@ void hf_synth_amr_wb_fx( pt4 = &dct_hb[fb + 240]; FOR( j = fb; j < L_SUBFR16k; j++ ) { -#ifdef BASOP_NOGLOB tmp = add_sat( tmp, shr( *pt4++, 2 ) ); /*qdct-2 */ -#else - tmp = add( tmp, shr( *pt4++, 2 ) ); /*qdct-2 */ -#endif } *pt1 = round_fx( L_shl( L_mult( tmp, tmp1 ), 2 ) ); /*qdct */ move16(); @@ -846,11 +801,7 @@ void hf_synth_amr_wb_fx( move16(); IF( *pt2 > 0 ) { -#ifdef BASOP_NOGLOB L_tmp = L_mac0_sat( L_tmp, shr( *pt2, 1 ), shr( *pt2, 1 ) ); /*2*qdct-2 */ -#else - L_tmp = L_mac0( L_tmp, shr( *pt2, 1 ), shr( *pt2, 1 ) ); /*2*qdct-2 */ -#endif } pt1++; pt2++; @@ -878,15 +829,10 @@ void hf_synth_amr_wb_fx( *pt1 = mult_r( *pt1, g ); /*qdct */ move16(); } -#ifdef BASOP_NOGLOB *pt2 = round_fx_sat( L_shl_sat( L_mult( *pt2, inv_g ), 3 ) ); /*qdct */ move16(); *pt3 = add_sat( *pt1, *pt2 ); move16(); -#else - *pt2 = round_fx( L_shl( L_mult( *pt2, inv_g ), 3 ) ); /*qdct */ - *pt3 = add( *pt1, *pt2 ); -#endif *pt3 = extract_l( L_mult0( *pt3, *pt4 ) ); /*qdct */ move16(); pt1++; @@ -900,11 +846,7 @@ void hf_synth_amr_wb_fx( L_tmp = L_mult( ener, scale ); /*30-q1+q2 */ q2 = sub( q1, q2 ); /*30-q2 */ scale = round_fx( Isqrt( L_shl( L_tmp, sub( q2, 24 ) ) ) ); /*Q12 */ -#ifdef BASOP_NOGLOB - scale = round_fx_sat( L_shl_sat( L_mult( scale, gamma ), 4 ) ); /*Q15 */ -#else - scale = round_fx( L_shl( L_mult( scale, gamma ), 4 ) ); /*Q15 */ -#endif + scale = round_fx_sat( L_shl_sat( L_mult( scale, gamma ), 4 ) ); /*Q15 */ } ELSE { @@ -1017,7 +959,7 @@ void hf_synth_amr_wb_fx( q_tmp = Exp16Array( L_FRAME16k, dct_hb ); qhf = sub( q_tmp, 1 ); - Copy_Scale_sig_16_32( dct_hb, dct_hb32, L_FRAME16k, qhf ); /* qhf + qdct */ + Copy_Scale_sig_16_32_DEPREC( dct_hb, dct_hb32, L_FRAME16k, qhf ); /* qhf + qdct */ qhf = add( qhf, qdct ); edct_fx( dct_hb32, exc16k32, L_FRAME16k, &qhf ); q_tmp = Exp32Array( L_FRAME16k, exc16k32 ); @@ -1041,40 +983,24 @@ void hf_synth_amr_wb_fx( shift = norm_l( L_tmp ); L_tmp = L_shl( L_tmp, shift ); /*Q(q3+shift); */ q3 = add( q3, shift ); -#ifdef BASOP_NOGLOB scale = round_fx_sat( L_tmp ); /*Q(q3-16); */ -#else - scale = round_fx( L_tmp ); /*Q(q3-16); */ -#endif q3 = sub( q3, 16 ); scale = div_s( shl( 1, 14 ), scale ); /*Q(29-q3) */ L_tmp = L_mult( scale, ener ); /*Q(29-q3+q1+1) */ shift = norm_l( L_tmp ); - L_tmp = L_shl( L_tmp, shift ); /*Q(29-q3+q1+1+shift) */ -#ifdef BASOP_NOGLOB - scale = round_fx_sat( L_tmp ); /*Q(29-q3+q1+1+shift-16) */ -#else - scale = round_fx( L_tmp ); /*Q(29-q3+q1+1+shift-16) */ -#endif + L_tmp = L_shl( L_tmp, shift ); /*Q(29-q3+q1+1+shift) */ + scale = round_fx_sat( L_tmp ); /*Q(29-q3+q1+1+shift-16) */ L_tmp = L_mult( scale, e_subfr2 ); /*Q(29-q3+q1+1+shift-16+q4+1)=Q(15+q1-q3+q4+shift) */ q3 = sub( 15, q3 ); q3 = add( q3, q1 ); q3 = add( q3, shift ); q3 = add( q3, q4 ); -#ifdef BASOP_NOGLOB scale = round_fx_sat( Isqrt( L_shl_sat( L_tmp, sub( 6, q3 ) ) ) ); /*Q12 */ -#else - scale = round_fx( Isqrt( L_shl( L_tmp, sub( 6, q3 ) ) ) ); /*Q12 */ -#endif pt6 += L_SUBFR; FOR( j = 0; j < L_SUBFR16k; j++ ) { -#ifdef BASOP_NOGLOB *pt2 = round_fx_sat( L_shl_sat( L_mult( *pt2, scale ), 2 ) ); /*qhf-1 */ move16(); -#else - *pt2 = round_fx( L_shl( L_mult( *pt2, scale ), 2 ) ); /*qhf-1 */ -#endif pt2++; } } @@ -1141,14 +1067,10 @@ static void hf_synthesis_amr_wb_fx( ener = extract_h( L_tmp ); /*Q(q1+q3); */ q1 = add( q1, q3 ); - scale = div_s( shl( 1, 14 ), ener ); /*Q(29-q1) */ - L_tmp = L_mult( tmp, scale ); /*30-q1+q2 */ - q2 = sub( q1, q2 ); /*30-q2 */ -#ifdef BASOP_NOGLOB + scale = div_s( shl( 1, 14 ), ener ); /*Q(29-q1) */ + L_tmp = L_mult( tmp, scale ); /*30-q1+q2 */ + q2 = sub( q1, q2 ); /*30-q2 */ scale = round_fx_sat( Isqrt( L_shl_sat( L_tmp, sub( q2, 24 ) ) ) ); /*Q12 */ -#else - scale = round_fx( Isqrt( L_shl( L_tmp, sub( q2, 24 ) ) ) ); /*Q12 */ -#endif pt1 = exc16k; pt2 = exc2385; FOR( i = 0; i < L_SUBFR16k; i++ ) @@ -1177,14 +1099,10 @@ static void hf_synthesis_amr_wb_fx( ener = extract_h( L_tmp ); /*Q(q1+q3); */ q1 = add( q1, q3 ); - scale = div_s( shl( 1, 14 ), ener ); /*Q(29-q1) */ - L_tmp = L_mult( tmp, scale ); /*30-q1+q2 */ - q2 = sub( q1, q2 ); /*30-q2 */ -#ifdef BASOP_NOGLOB + scale = div_s( shl( 1, 14 ), ener ); /*Q(29-q1) */ + L_tmp = L_mult( tmp, scale ); /*30-q1+q2 */ + q2 = sub( q1, q2 ); /*30-q2 */ scale = round_fx_sat( Isqrt( L_shl_sat( L_tmp, sub( q2, 24 ) ) ) ); /*Q12 */ -#else - scale = round_fx( Isqrt( L_shl( L_tmp, sub( q2, 24 ) ) ) ); /*Q12 */ -#endif flag = negate( s_and( til, -0x8000 ) ); if ( GT_16( scale, 4096 /* 1.0f in Q12 */ ) ) { @@ -1287,9 +1205,7 @@ static Word16 EnhanceClass_fx( Word16 unvoicing_tmp_fx; Word16 tmp, tmp1; Word32 L_tmp; -#ifdef BASOP_NOGLOB Flag Overflow; -#endif /* Decide (*unvoicing_flag) to allow BWE enhancement when qq>pp */ @@ -1327,21 +1243,13 @@ static Word16 EnhanceClass_fx( move16(); } -#ifdef BASOP_NOGLOB if ( GT_16( sub_o( *unvoicing_fx, *unvoicing_sm_fx, &Overflow ), 3277 /* 0.1 in Q15 */ ) ) -#else - if ( GT_16( sub( *unvoicing_fx, *unvoicing_sm_fx ), 3277 ) ) -#endif { *unvoicing_flag = 1; move16(); } -#ifdef BASOP_NOGLOB if ( LT_16( sub_o( *unvoicing_fx, *unvoicing_sm_fx, &Overflow ), 1638 /* 0.05 in Q15 */ ) ) -#else - if ( LT_16( sub( *unvoicing_fx, *unvoicing_sm_fx ), 1638 ) ) -#endif { *unvoicing_flag = 0; move16(); @@ -1437,11 +1345,7 @@ static void envelope_fx( pt3 = exp_tab_q_fx; /* Q14 */ FOR( i = 0; i <= M; i++ ) { -#ifdef BASOP_NOGLOB L_tmp = L_mac_sat( L_tmp, *pt2++, *pt3++ ); /* Q27 */ -#else - L_tmp = L_mac( L_tmp, *pt2++, *pt3++ ); -#endif } q2 = norm_l( L_tmp ); L_tmp = L_shl( L_tmp, q2 ); /*Q(27+q2)*/ @@ -1452,11 +1356,7 @@ static void envelope_fx( pt3 = exp_tab_q_fx + 33; /* Q14 */ FOR( i = 0; i <= M; i++ ) { -#ifdef BASOP_NOGLOB L_tmp = L_mac_sat( L_tmp, *pt2++, *pt3-- ); /* Q14 */ -#else - L_tmp = L_mac( L_tmp, *pt2++, *pt3-- ); -#endif } q3 = norm_l( L_tmp ); shift = sub( q2, q3 ); @@ -1474,19 +1374,11 @@ static void envelope_fx( ry = round_fx( L_shr( L_tmp, 1 ) ); /*Q(10+q2)*/ L_tmp = L_mult( px, px ); - L_tmp = L_mac( L_tmp, py, py ); /*Q(21+2*q1)*/ -#ifdef BASOP_NOGLOB + L_tmp = L_mac( L_tmp, py, py ); /*Q(21+2*q1)*/ pp = round_fx_sat( Isqrt( L_shr( L_tmp, add( 11, shl( q1, 1 ) ) ) ) ); /*Q10*/ -#else - pp = round_fx( Isqrt( L_shr( L_tmp, add( 11, shl( q1, 1 ) ) ) ) ); /*Q10*/ -#endif L_tmp = L_mult( rx, rx ); - L_tmp = L_mac( L_tmp, ry, ry ); /*Q(21+2*q1)*/ -#ifdef BASOP_NOGLOB + L_tmp = L_mac( L_tmp, ry, ry ); /*Q(21+2*q1)*/ rr = round_fx_sat( Isqrt( L_shr( L_tmp, add( 11, shl( q2, 1 ) ) ) ) ); /*Q10*/ -#else - rr = round_fx( Isqrt( L_shr( L_tmp, add( 11, shl( q2, 1 ) ) ) ) ); /*Q10*/ -#endif Copy( Aq, As, 3 ); IF( EQ_16( shr( As[2], 1 ), -2048 /* -1.0f in Q11 */ ) ) { @@ -1517,11 +1409,7 @@ static void envelope_fx( L_tmp = L_mult( As[1], tmp ); /*Q(42-q1) */ q1 = sub( q1, 14 ); -#ifdef BASOP_NOGLOB k1 = round_fx_sat( L_shl_sat( L_tmp, q1 ) ); /*Q12 */ -#else - k1 = round_fx( L_shl( L_tmp, q1 ) ); /*Q12 */ -#endif k2 = As[2]; move16(); /*Q12 */ if ( GT_16( k2, 2458 /* 0.6f in Q12 */ ) ) @@ -1599,11 +1487,7 @@ static void envelope_fx( { IF( GT_16( rr, ( hAmrwb_IO->prev_r_fx ) ) ) { -#ifdef BASOP_NOGLOB rr = shr( add_sat( rr, ( hAmrwb_IO->prev_r_fx ) ), 1 ); -#else - rr = shr( add( rr, ( hAmrwb_IO->prev_r_fx ) ), 1 ); -#endif } hAmrwb_IO->prev_r_fx = rr; @@ -1617,14 +1501,10 @@ static void envelope_fx( rr = round_fx( L_shl( L_tmp, 3 ) ); /*Q10*/ L_tmp = L_mult( tilt, sub( 26214 /* 1.6f in Q14 */, shr( voice_factor, 1 ) ) ); /*Q28*/ L_tmp = L_max( L_tmp, 268435456 /* 1 in Q28 */ ); - L_tmp = Mult_32_16( L_tmp, qq ); /*Q23*/ -#ifdef BASOP_NOGLOB + L_tmp = Mult_32_16( L_tmp, qq ); /*Q23*/ qq = round_fx_sat( L_shl_sat( L_tmp, 3 ) ); /*Q10*/ -#else - qq = round_fx( L_shl( L_tmp, 3 ) ); /*Q10*/ -#endif - rr = s_min( rr, qq ); /* Q10 */ - rr = s_max( rr, pp ); /* Q10 */ + rr = s_min( rr, qq ); /* Q10 */ + rr = s_max( rr, pp ); /* Q10 */ } ELSE { @@ -1637,11 +1517,7 @@ static void envelope_fx( alpha = round_fx( L_shl( L_tmp, 9 ) ); /*Q14*/ L_tmp = L_mult( alpha, ( hAmrwb_IO->prev_r_fx ) ); /*Q25*/ L_tmp = L_mac( L_tmp, tmp, rr ); /*Q25*/ -#ifdef BASOP_NOGLOB - rr = round_fx_sat( L_shl_sat( L_tmp, 1 ) ); /*Q10*/ -#else - rr = round_fx( L_shl( L_tmp, 1 ) ); /*Q10*/ -#endif + rr = round_fx_sat( L_shl_sat( L_tmp, 1 ) ); /*Q10*/ } hAmrwb_IO->prev_r_fx = rr; @@ -1671,12 +1547,8 @@ static void envelope_fx( tmp = div_s( shl( 1, sub( 14, q1 ) ), pp ); /*Q(29-q1-10) */ L_tmp = L_mult( rr, tmp ); /*Q(30-q1-10+10) */ -#ifdef BASOP_NOGLOB *sub_gain = s_min( 20480 /* 5.0f in Q12 */, round_fx_sat( L_shl_sat( L_tmp, sub( q1, 2 ) ) ) ); /*Q12 */ move16(); -#else - *sub_gain = s_min( 20480, round_fx( L_shl( L_tmp, sub( q1, 2 ) ) ) ); /*Q12 */ -#endif return; } diff --git a/lib_dec/hq_classifier_dec.c b/lib_dec/hq_classifier_dec.c deleted file mode 100644 index 0fe8682daace6673130ca2ca05de2a188e8e2ae0..0000000000000000000000000000000000000000 --- a/lib_dec/hq_classifier_dec.c +++ /dev/null @@ -1,42 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include "cnst.h" -#include "prot.h" -#include "rom_com.h" -#include "wmc_auto.h" diff --git a/lib_dec/hq_conf_fec.c b/lib_dec/hq_conf_fec.c deleted file mode 100644 index fd4f3cb7c53af6bc1a4a149c6db6799b8f39655e..0000000000000000000000000000000000000000 --- a/lib_dec/hq_conf_fec.c +++ /dev/null @@ -1,42 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include "cnst.h" -#include "rom_com.h" -#include "prot.h" -#include "wmc_auto.h" diff --git a/lib_dec/hq_core_dec.c b/lib_dec/hq_core_dec.c deleted file mode 100644 index 5a1f34a11a5ce940017243e9d78dcc4c048d33dc..0000000000000000000000000000000000000000 --- a/lib_dec/hq_core_dec.c +++ /dev/null @@ -1,56 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include -#include "cnst.h" -#include "prot.h" -#include "rom_com.h" -#include "wmc_auto.h" -#include "ivas_prot.h" - -/*-------------------------------------------------------------------------- - * hq_core_dec() - * - * HQ core decoder - *--------------------------------------------------------------------------*/ - -/*-------------------------------------------------------------------* - * hq_core_dec_init() - * - * Initialize HQ core state structure - *-------------------------------------------------------------------*/ diff --git a/lib_dec/hq_core_dec_fx.c b/lib_dec/hq_core_dec_fx.c index daa8804d7c15f77ac5b20c688896fa0a611d4fe4..86cf9784aa1eb3346aa7c52a16d78f7e2808f40e 100644 --- a/lib_dec/hq_core_dec_fx.c +++ b/lib_dec/hq_core_dec_fx.c @@ -6,7 +6,6 @@ #include "cnst.h" /* Common constants */ #include "prot_fx.h" /* Function prototypes */ #include "rom_com.h" /* Static table prototypes */ -#include "prot.h" #include "ivas_prot_fx.h" /*-------------------------------------------------------------------------- * hq_core_dec() @@ -257,11 +256,7 @@ void hq_core_dec_fx( { /*t_audio_q[i] *= ener_match;*/ Mpy_32_16_ss( t_audio_q[i], ener_match, &L_tmp, &lsb ); /*12+13-15=10 */ -#ifdef BASOP_NOGLOB t_audio_q[i] = L_add_sat( L_shl_sat( L_tmp, 2 ), L_shr( lsb, 14 ) ); -#else - t_audio_q[i] = L_add( L_shl( L_tmp, 2 ), lshr( lsb, 14 ) ); -#endif move16(); /* Q12 */ } } @@ -497,13 +492,8 @@ void hq_core_dec_fx( test(); IF( !st_fx->bfi && st_fx->prev_bfi && GE_32( st_fx->last_total_brate, HQ_48k ) && EQ_16( st_fx->last_codec_mode, MODE2 ) && ( EQ_16( st_fx->last_core_bfi, TCX_20_CORE ) || EQ_16( st_fx->last_core_bfi, TCX_10_CORE ) ) && st_fx->plcInfo.concealment_method == TCX_NONTONAL && LT_32( st_fx->plcInfo.nbLostCmpt, 4 ) ) { -#ifdef BASOP_NOGLOB st_fx->plcInfo.recovery_gain = shl_sat( st_fx->plcInfo.recovery_gain, *Q_synth ); /* Q14 + Q_synth */ move16(); -#else - st_fx->plcInfo.recovery_gain = shl( st_fx->plcInfo.recovery_gain, *Q_synth ); - move16(); -#endif IF( st_fx->tonalMDCTconceal.q_lastPcmOut != 0 ) { Scale_sig( st_fx->tonalMDCTconceal.secondLastPcmOut, shr( st_fx->plcInfo.FrameSize, 1 ), negate( st_fx->tonalMDCTconceal.q_lastPcmOut ) ); @@ -649,6 +639,9 @@ void ivas_hq_core_dec_fx( set16_fx( gapsynth_fx, 0, L_FRAME48k ); set16_fx( num_bands_p, 0, MAX_SB_NB ); set16_fx( ynrm, 39, NB_SFM ); /* Initialize to the smallest value */ +#ifdef MSAN_FIX + set16_fx( wtda_audio_16, 0, 2 * L_FRAME48k ); +#endif mean_en_high_fx = 0; move16(); Q_audio = 12; @@ -856,11 +849,7 @@ void ivas_hq_core_dec_fx( { /*t_audio_q[i] *= ener_match;*/ Mpy_32_16_ss( t_audio_q[i], ener_match, &L_tmp, &lsb ); /*12+13-15=10 */ -#ifdef BASOP_NOGLOB t_audio_q[i] = L_add_sat( L_shl_sat( L_tmp, 2 ), lshr( (Word16) lsb, 14 ) ); -#else - t_audio_q[i] = L_add( L_shl( L_tmp, 2 ), lshr( (Word16) lsb, 14 ) ); -#endif move16(); /* Q12 */ } } @@ -998,7 +987,7 @@ void ivas_hq_core_dec_fx( Copy( wtda_audio_16 + sub( shr( overlapFB, 1 ), tcx_offsetFB ), synth, L_frameTCX_glob ); /* q_wtda */ - Copy_Scale_sig_16_32( wtda_audio_16, wtda_audio, 2 * L_FRAME48k, 12 ); /* q_wtda + 12 */ + Copy_Scale_sig_16_32_DEPREC( wtda_audio_16, wtda_audio, 2 * L_FRAME48k, 12 ); /* q_wtda + 12 */ IF( !core_switching_flag ) { st_fx->last_core = ACELP_CORE; /* Restore last core Q0*/ @@ -1135,11 +1124,7 @@ void ivas_hq_core_dec_fx( test(); IF( !st_fx->bfi && st_fx->prev_bfi && GE_32( st_fx->last_total_brate, HQ_48k ) && EQ_16( st_fx->last_codec_mode, MODE2 ) && ( EQ_16( st_fx->last_core_bfi, TCX_20_CORE ) || EQ_16( st_fx->last_core_bfi, TCX_10_CORE ) ) && EQ_16( st_fx->plcInfo.concealment_method, TCX_NONTONAL ) && LT_32( st_fx->plcInfo.nbLostCmpt, 4 ) ) { -#ifdef BASOP_NOGLOB st_fx->plcInfo.recovery_gain = shl_sat( st_fx->plcInfo.recovery_gain, *Q_synth ); /* Q15 */ -#else - st_fx->plcInfo.recovery_gain = shl( st_fx->plcInfo.recovery_gain, *Q_synth ); -#endif move16(); IF( st_fx->tonalMDCTconceal.q_lastPcmOut != 0 ) { diff --git a/lib_dec/hq_env_dec.c b/lib_dec/hq_env_dec.c deleted file mode 100644 index fc894ba6cc3b0f6891e5522d7bdaa893786ada84..0000000000000000000000000000000000000000 --- a/lib_dec/hq_env_dec.c +++ /dev/null @@ -1,41 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include "prot.h" -#include "rom_com.h" -#include "wmc_auto.h" diff --git a/lib_dec/hq_hr_dec.c b/lib_dec/hq_hr_dec.c deleted file mode 100644 index fd4f3cb7c53af6bc1a4a149c6db6799b8f39655e..0000000000000000000000000000000000000000 --- a/lib_dec/hq_hr_dec.c +++ /dev/null @@ -1,42 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include "cnst.h" -#include "rom_com.h" -#include "prot.h" -#include "wmc_auto.h" diff --git a/lib_dec/hq_hr_dec_fx.c b/lib_dec/hq_hr_dec_fx.c index 02d58f7bf5144d98500f963dd14725df4b0e8c2c..f96b8f59787008b5a1eb5bee0f584f417e4563c6 100644 --- a/lib_dec/hq_hr_dec_fx.c +++ b/lib_dec/hq_hr_dec_fx.c @@ -90,11 +90,7 @@ void hq_pred_hb_bws_fx( L_tmp = L_deposit_l( 0 ); FOR( i = 25; i < SFM_N_HARM; i++ ) { -#ifdef BASOP_NOGLOB L_tmp = L_add_sat( L_tmp, dicn_fx[ynrm[i]] ); /*Q14*/ -#else - L_tmp = L_add( L_tmp, dicn_fx[ynrm[i]] ); /*Q14*/ -#endif } L_tmp = L_min( 8191, L_shr( L_tmp, 13 ) ); /* Q1 */ st_fx->prev_ener_shb_fx = extract_l( L_tmp ); /*Q1*/ diff --git a/lib_dec/hq_lr_dec.c b/lib_dec/hq_lr_dec.c deleted file mode 100644 index dd5876ea913249de73802cee8febd5a24948ed99..0000000000000000000000000000000000000000 --- a/lib_dec/hq_lr_dec.c +++ /dev/null @@ -1,105 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include -#include "cnst.h" -#include "rom_com.h" -#include "rom_dec.h" -#include "prot.h" -#include "stl.h" -#include "basop_util.h" -#include "wmc_auto.h" - -/*--------------------------------------------------------------------------* - * Local function prototypes - *--------------------------------------------------------------------------*/ - - -/*-------------------------------------------------------------------* - * hq_lr_dec() - * - * HQ low rate decoding routine - *-------------------------------------------------------------------*/ - -/*------------------------------------------------------------------------------------ - * small_symbol_dec_tran() - * - * Huffman decoding of differential energies - *--------------------------------------------------------------------------------------*/ - - -/*-------------------------------------------------------------------------- - * small_symbol_dec() - * - * Huffman decoding of differential energies (MSB and LSB) - *--------------------------------------------------------------------------*/ - - -/*-------------------------------------------------------------------------- - * large_symbol_dec() - * - * - *--------------------------------------------------------------------------*/ - - -/*--------------------------------------------------------------------------* - * band_energy_dequant() - * - * - *--------------------------------------------------------------------------*/ - - -/*--------------------------------------------------------------------------* - * p2a_threshold_dequant() - * - * - *--------------------------------------------------------------------------*/ - - -/*--------------------------------------------------------------------------* - * mdct_spectrum_fine_gain_dec() - * - * - *--------------------------------------------------------------------------*/ - - -/*--------------------------------------------------------------------------* - * spt_shorten_domain_set_dec() - * - * update the shorten band information based on p2a analysis - *--------------------------------------------------------------------------*/ diff --git a/lib_dec/hq_lr_dec_fx.c b/lib_dec/hq_lr_dec_fx.c index cf7aee8f013f179c82c0fb4c6c948b84d71981fb..61c1d0938eef3222ee6e0366fbdcb2f284aa9f85 100644 --- a/lib_dec/hq_lr_dec_fx.c +++ b/lib_dec/hq_lr_dec_fx.c @@ -343,12 +343,8 @@ void hq_lr_dec_fx( frac1 = L_Extract_lc( L_tmp, &exp ); /* Extract exponent of L_tmp */ L_tmp = Pow2( 30, frac1 ); exp = sub( exp, 30 ); -#ifdef BASOP_NOGLOB Ep_fx[i] = L_shl_sat( L_tmp, s_max( sub( exp, 6 ), -31 ) ); /* Q -6 */ move32(); -#else - Ep_fx[i] = L_shl( L_tmp, s_max( sub( exp, 6 ), -31 ) ); /* Q -6 */ -#endif } FOR( i = 0; i < bands_fx; i++ ) @@ -428,21 +424,12 @@ void hq_lr_dec_fx( { IF( GE_16( i, lowband ) ) { -#ifdef BASOP_NOGLOB Ep_vari_fx = L_add_sat( Ep_vari_fx, L_abs( L_sub_sat( Ep_tmp_fx[i], Ep_tmp_fx[i - 1] ) ) ); /*Q15 */ Ep_avrg_fx = L_add_sat( Ep_avrg_fx, Ep_tmp_fx[i] ); /*Q15 */ -#else - Ep_vari_fx = L_add( Ep_vari_fx, L_abs( L_sub( Ep_tmp_fx[i], Ep_tmp_fx[i - 1] ) ) ); /*Q15 */ - Ep_avrg_fx = L_add( Ep_avrg_fx, Ep_tmp_fx[i] ); /*Q15 */ -#endif } ELSE { -#ifdef BASOP_NOGLOB Ep_avrgL_fx = L_add_sat( Ep_avrgL_fx, Ep_tmp_fx[i] ); /*Q15 */ -#else - Ep_avrgL_fx = L_add( Ep_avrgL_fx, Ep_tmp_fx[i] ); /*Q15 */ -#endif if ( GT_32( Ep_tmp_fx[i], Ep_peak_fx ) ) { Ep_peak_fx = L_add( Ep_tmp_fx[i], 0 ); /*Q15 */ @@ -515,16 +502,11 @@ void hq_lr_dec_fx( IF( EQ_16( last_bitalloc_max_band[j++], 1 ) ) { L_tmp = Mult_32_16( Ep_tmp_fx[i], sub( bands_fx, lowband ) ); /*Q(13+0-15 = -2) */ -#ifdef BASOP_NOGLOB tmp = Calc_inv( L_shl_sat( L_tmp, 14 ), &exp ); L_tmp = L_shl_sat( Mult_32_16( Ep_avrg_fx, tmp ), sub( 14, exp ) ); /*Q(13+exp-15 +14-exp+2 = 14) */ -#else - tmp = Calc_inv( L_shl( L_tmp, 14 ), &exp ); - L_tmp = L_shl( Mult_32_16( Ep_avrg_fx, tmp ), sub( 14, exp ) ); /*Q(13+exp-15 +14-exp+2 = 14) */ -#endif - L_tmp = L_max( L_tmp, 16384 ); /*14 */ - tmp = extract_l( L_min( L_tmp, beta_fx ) ); /*14 */ - alpha_fx = shl( mult( alpha_fx, tmp ), 1 ); /*14+14-15 +1=14 */ + L_tmp = L_max( L_tmp, 16384 ); /*14 */ + tmp = extract_l( L_min( L_tmp, beta_fx ) ); /*14 */ + alpha_fx = shl( mult( alpha_fx, tmp ), 1 ); /*14+14-15 +1=14 */ } ELSE { @@ -563,11 +545,7 @@ void hq_lr_dec_fx( { IF( GE_16( i, lowband ) ) { -#ifdef BASOP_NOGLOB Ep_avrg_fx = L_add_sat( Ep_avrg_fx, Ep_tmp_fx[i] ); /*Q15 */ -#else - Ep_avrg_fx = L_add( Ep_avrg_fx, Ep_tmp_fx[i] ); /*Q15 */ -#endif } ELSE { @@ -614,11 +592,7 @@ void hq_lr_dec_fx( } FOR( i = 0; i < bands_fx; i++ ) { -#ifdef BASOP_NOGLOB Ep_tmp_fx[i] = L_shl_sat( Ep_tmp_fx[i], 2 ); /* Q15 */ -#else - Ep_tmp_fx[i] = L_shl( Ep_tmp_fx[i], 2 ); -#endif move32(); } IF( EQ_32( st_fx->core_brate, ACELP_13k20 ) ) @@ -649,30 +623,17 @@ void hq_lr_dec_fx( test(); IF( GE_16( i, lowband ) && add( sub( i, bands_fx ), p2a_bands_fx ) < 0 ) { -#ifdef BASOP_NOGLOB Ep_vari_fx = L_add_sat( Ep_vari_fx, L_abs( L_sub( Ep_tmp_fx[i], Ep_tmp_fx[i - 1] ) ) ); /*Q15 */ Ep_avrg_fx = L_add_sat( Ep_avrg_fx, Ep_tmp_fx[i] ); /*Q15 */ -#else - Ep_vari_fx = L_add( Ep_vari_fx, L_abs( L_sub( Ep_tmp_fx[i], Ep_tmp_fx[i - 1] ) ) ); /*Q15 */ - Ep_avrg_fx = L_add( Ep_avrg_fx, Ep_tmp_fx[i] ); /*Q15 */ -#endif } IF( GE_16( i, highband ) ) { -#ifdef BASOP_NOGLOB enerH_fx = L_add_sat( enerH_fx, L_shl_sat( Ep_fx[i], 2 ) ); /*Q0 */ -#else - enerH_fx = L_add( enerH_fx, L_shl( Ep_fx[i], 2 ) ); /*Q0 */ -#endif } ELSE IF( GE_16( i, lowband ) ) { -#ifdef BASOP_NOGLOB enerL_fx = L_add_sat( enerL_fx, L_shl_sat( Ep_fx[i], 2 ) ); /*Q0 */ -#else - enerL_fx = L_add( enerL_fx, L_shl( Ep_fx[i], 2 ) ); /*Q0 */ -#endif } } @@ -693,11 +654,7 @@ void hq_lr_dec_fx( tmp = sub( bands_fx, p2a_bands_fx ); tmp = sub( tmp, lowband ); /*Q0 */ -#ifdef BASOP_NOGLOB tmp1 = extract_h( L_shl_sat( Ep_avrg_fx, 1 ) ); /*Q0 */ -#else - tmp1 = extract_h( L_shl( Ep_avrg_fx, 1 ) ); /*Q0 */ -#endif IF( tmp1 != 0 ) { exp = norm_s( tmp1 ); @@ -738,11 +695,7 @@ void hq_lr_dec_fx( { tmp = sub( tmp, lowband ); L_tmp = Mult_32_16( Ep_tmp_fx[i], tmp ); /*Q(15+0-15 = 0) */ -#ifdef BASOP_NOGLOB tmp = Calc_inv( L_shl_sat( L_tmp, 16 ), &exp ); -#else - tmp = Calc_inv( L_shl( L_tmp, 16 ), &exp ); -#endif L_tmp = Mult_32_16( Ep_avrg_fx, tmp ); /*Q(15+exp-15 = exp) */ L_tmp = L_shl( L_tmp, sub( 14, exp ) ); /*Q14 */ tmp = extract_l( L_min( L_max( L_tmp, 16384 ), 20480 ) ); /*Q14 */ @@ -753,11 +706,7 @@ void hq_lr_dec_fx( { tmp = sub( tmp, lowband ); -#ifdef BASOP_NOGLOB tmp1 = extract_h( L_shl_sat( Ep_avrg_fx, 1 ) ); /*Q0 */ -#else - tmp1 = extract_h( L_shl( Ep_avrg_fx, 1 ) ); /*Q0 */ -#endif IF( tmp1 != 0 ) { exp = norm_s( tmp1 ); @@ -794,19 +743,11 @@ void hq_lr_dec_fx( { IF( GE_16( i, lowband ) ) { -#ifdef BASOP_NOGLOB Ep_avrg_fx = L_add_sat( Ep_avrg_fx, Ep_tmp_fx[i] ); /*Q15 */ -#else - Ep_avrg_fx = L_add( Ep_avrg_fx, Ep_tmp_fx[i] ); /*Q15 */ -#endif } ELSE { -#ifdef BASOP_NOGLOB Ep_avrgL_fx = L_add_sat( Ep_avrgL_fx, Ep_tmp_fx[i] ); /*Q15 */ -#else - Ep_avrgL_fx = L_add( Ep_avrgL_fx, Ep_tmp_fx[i] ); /*Q15 */ -#endif if ( GT_32( Ep_tmp_fx[i], Ep_peak_fx ) ) { Ep_peak_fx = L_add( Ep_tmp_fx[i], 0 ); /*Q15 */ @@ -831,11 +772,7 @@ void hq_lr_dec_fx( move16(); FOR( i = 0; i < lowband; i++ ) { -#ifdef BASOP_NOGLOB tmp = Calc_inv( L_shl_sat( Ep_avrgL_fx, 1 ), &exp ); -#else - tmp = Calc_inv( L_shl( Ep_avrgL_fx, 1 ), &exp ); -#endif L_tmp = Mult_32_16( Ep_peak_fx, tmp ); /*Q(15+exp-15 = exp) */ L_tmp = Mult_32_16( L_tmp, lowband ); /*Q(exp+0-15 = exp-15) */ L_tmp = L_shl( L_tmp, sub( 28, exp ) ); /*Q14 0.5 */ diff --git a/lib_dec/igf_dec.c b/lib_dec/igf_dec.c deleted file mode 100644 index 785dc6a86aa92a9e5f4c80c8884724a2fabd3d76..0000000000000000000000000000000000000000 --- a/lib_dec/igf_dec.c +++ /dev/null @@ -1,141 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include -#include "options.h" -#include -#include "prot.h" -#include "cnst.h" -#include "stat_dec.h" -#include "ivas_prot.h" -#include "wmc_auto.h" -#include "prot_fx.h" - - -/*-------------------------------------------------------------------* - * IGF_replaceTCXNoise_1_flr() - * - * measures TCX noise - *-------------------------------------------------------------------*/ - -/*! r: number of noise bands */ - - -/*-------------------------------------------------------------------* - * IGF_replaceTCXNoise_2_flt() - * - * replaces TCX noise - *-------------------------------------------------------------------*/ - - -/*-------------------------------------------------------------------* - * IGF_replaceTCXNoise_2_new_flt() - * - * - *-------------------------------------------------------------------*/ - - -/*-------------------------------------------------------------------* - * IGF_decode_whitening_level_flt() - * - * reads whitening levels - *-------------------------------------------------------------------*/ - - -/*-------------------------------------------------------------------* - * IGF_getMDCTSquare_flt() - * - * square the MDCT spectrum - *-------------------------------------------------------------------*/ - - -/*-------------------------------------------------------------------* - * IGF_calcSfbEnergy_flt() - * - * calculate energy per SFB - *-------------------------------------------------------------------*/ - - -/*-------------------------------------------------------------------* - * IGF_setLinesToZero_flt() - * - * set power spectrum values to zero, needed for energy calculation - *-------------------------------------------------------------------*/ - - -/*-------------------------------------------------------------------* - * IGF_RefineGrid_flt() - * - * refines the IGF grid - *-------------------------------------------------------------------*/ - - -/*-------------------------------------------------------------------* - * IGFDecReadData_flt() - * - * reads whitening information from the bitstream - *-------------------------------------------------------------------*/ - - -/*-------------------------------------------------------------------* - * IGFDecUpdateInfo_flt() - * - * updates the start/stop frequency of IGF according to igfGridIdx - *-------------------------------------------------------------------*/ - - -/*-------------------------------------------------------------------* - * IGFDecStoreTCX10SubFrameData_flt() - * - * store the IGF bitstream information for TCX10 subframes - *-------------------------------------------------------------------*/ - -/*-------------------------------------------------------------------* - * IGFDecRestoreTCX10SubFrameData_flt() - * - * restore the IGF bitstream information for TCX10 subframes - *-------------------------------------------------------------------*/ -/*-----------------------------------------------------------------------* - * init_igf_dec_flt() - * - * Initialize IGF decoder parameters - *-----------------------------------------------------------------------*/ -/*-----------------------------------------------------------------------* - * get_igf_startline_flt() - * - * - *-----------------------------------------------------------------------*/ diff --git a/lib_dec/igf_dec_fx.c b/lib_dec/igf_dec_fx.c index 7dd389164151197fe8c9a61d8fabb161354d5419..c1b0ce93ab4157604fb5bcec23e3bd22ae2fc463 100644 --- a/lib_dec/igf_dec_fx.c +++ b/lib_dec/igf_dec_fx.c @@ -8,10 +8,8 @@ #include #include "options.h" #include "stl.h" -#include "prot.h" -#include "ivas_prot.h" -#include "ivas_prot_fx.h" #include "prot_fx.h" +#include "ivas_prot_fx.h" #include "cnst.h" #include "stat_dec.h" #include "basop_util.h" @@ -1570,16 +1568,10 @@ static void IGF_appl( IGF_DEC_PRIVATE_DATA_HANDLE hPrivateData, /**< in { Carry = 0; move16(); -#ifdef BASOP_NOGLOB /* Critical Carry/Overflow*/ L_tmp = L_add_co( L_tmp, energyTmp[tb], &Carry, &Overflow ); // Q31 - dE_e Overflow = 0; move16(); L_c = L_macNs_co( L_c, 0, 0, &Carry, &Overflow ); -#else - L_tmp = L_add_c( L_tmp, energyTmp[tb] ); - Overflow = 0; - L_c = L_macNs( L_c, 0, 0 ); -#endif } L_tmp = norm_llQ31( L_c, L_tmp, &shift ); // Q31 /* float: dE = (float)sqrt(dE / 24.f); basop: */ @@ -1679,13 +1671,8 @@ static void IGF_appl( IGF_DEC_PRIVATE_DATA_HANDLE hPrivateData, /**< in /* Build a threshold and compare with L_tmp. Build negated threshold and compare with negated L_tmp to cover also fullscale L_tmp case */ BASOP_SATURATE_WARNING_OFF_EVS -#ifdef BASOP_NOGLOB L_tmp2 = L_shl_sat( L_negate( Mpy_32_16_1( sNlocal, 33 /*0.001f Q15*/ ) ), sub( sNlocal_e, L_tmp_e ) ); L_tmp2 = L_sub_sat( L_tmp2, L_negate( L_tmp ) ); -#else - L_tmp2 = L_shl( L_negate( Mpy_32_16_1( sNlocal, 33 /*0.001f Q15*/ ) ), sub( sNlocal_e, L_tmp_e ) ); - L_tmp2 = L_sub( L_tmp2, L_negate( L_tmp ) ); -#endif BASOP_SATURATE_WARNING_ON_EVS IF( L_tmp2 < 0 ) @@ -1697,13 +1684,8 @@ static void IGF_appl( IGF_DEC_PRIVATE_DATA_HANDLE hPrivateData, /**< in /* calc square root of L_tmp and store result in dN */ L_tmp = Sqrt32( L_tmp, &L_tmp_e ); -#ifdef BASOP_NOGLOB dN[sfb] = round_fx_sat( L_tmp ); move16(); -#else - dN[sfb] = round_fx( L_tmp ); - move16(); -#endif dN_e[sfb] = L_tmp_e; move16(); dN[sfb + 1] = dN[sfb]; @@ -1759,13 +1741,8 @@ static void IGF_appl( IGF_DEC_PRIVATE_DATA_HANDLE hPrivateData, /**< in /* Build a threshold and compare with L_tmp. Build negated threshold and compare with negated L_tmp to cover also fullscale L_tmp case */ BASOP_SATURATE_WARNING_OFF_EVS -#ifdef BASOP_NOGLOB L_tmp2 = L_shl_sat( L_negate( Mpy_32_16_1( sNlocal, 33 /*0.001f Q15*/ ) ), sub( sNlocal_e, L_tmp_e ) ); L_tmp2 = L_sub_sat( L_tmp2, L_negate( L_tmp ) ); -#else - L_tmp2 = L_shl( L_negate( Mpy_32_16_1( sNlocal, 33 /*0.001f Q15*/ ) ), sub( sNlocal_e, L_tmp_e ) ); - L_tmp2 = L_sub( L_tmp2, L_negate( L_tmp ) ); -#endif BASOP_SATURATE_WARNING_ON_EVS IF( L_tmp2 < 0 ) @@ -1904,12 +1881,8 @@ static void IGF_appl( IGF_DEC_PRIVATE_DATA_HANDLE hPrivateData, /**< in sum = shl( sum, shift ); /* exponent of sum: sub(15, shift) */ /* divide E by sum */ -#ifdef BASOP_NOGLOB /* Critical Carry/Overflow*/ tmp = div_s( shr( round_fx_o( E, &Overflow ), 1 ), sum ); /* shift E 1 bit to the right in order to make it smaller than sum */ -#else - tmp = div_s( shr( round_fx( E ), 1 ), sum ); /* shift E 1 bit to the right in order to make it smaller than sum */ -#endif - tmp_e = sub( add( E_e, 1 ), sub( 15, shift ) ); /* 15Q0 | sum is 15Q0 */ + tmp_e = sub( add( E_e, 1 ), sub( 15, shift ) ); /* 15Q0 | sum is 15Q0 */ /* multiply the result by the hopsize */ L_tmp = L_mult( tmp, hopsize ); @@ -2040,12 +2013,8 @@ static void IGF_appl( IGF_DEC_PRIVATE_DATA_HANDLE hPrivateData, /**< in move16(); /* gain[sfb] = min(gain[sfb], 12.f); */ - BASOP_SATURATE_WARNING_OFF_EVS /* threshold, may overflow */ -#ifdef BASOP_NOGLOB + BASOP_SATURATE_WARNING_OFF_EVS /* threshold, may overflow */ tmp = shl_sat( gain[sfb], sub( gain_e[sfb], 15 - 5 ) ); /* 10Q5 | tmp is in 10Q5 */ -#else - tmp = shl( gain[sfb], sub( gain_e[sfb], 15 - 5 ) ); /* 10Q5 | tmp is in 10Q5 */ -#endif BASOP_SATURATE_WARNING_ON_EVS IF( tmp > 384 ) /* 10Q5 | 384 = 12 in 10Q5 */ @@ -2288,15 +2257,9 @@ static void IGF_appl_ivas( IGF_DEC_PRIVATE_DATA_HANDLE hPrivateData, /**< in { Carry = 0; move16(); -#ifdef BASOP_NOGLOB /* Critical Carry/Overflow*/ L_tmp = L_add_co( L_tmp, energyTmp[tb], &Carry, &Overflow ); // Q31 - dE_e Overflow = 0; L_c = L_macNs_co( L_c, 0, 0, &Carry, &Overflow ); -#else - L_tmp = L_add_c( L_tmp, energyTmp[tb] ); - Overflow = 0; - L_c = L_macNs( L_c, 0, 0 ); -#endif } L_tmp = norm_llQ31( L_c, L_tmp, &shift ); // Q31 /* float: dE = (float)sqrt(dE / 24.f); basop: */ @@ -2399,13 +2362,8 @@ static void IGF_appl_ivas( IGF_DEC_PRIVATE_DATA_HANDLE hPrivateData, /**< in /* Build a threshold and compare with L_tmp. Build negated threshold and compare with negated L_tmp to cover also fullscale L_tmp case */ BASOP_SATURATE_WARNING_OFF_EVS -#ifdef BASOP_NOGLOB L_tmp2 = L_shl_sat( L_negate( Mpy_32_16_1( sNlocal, 33 /*0.001f Q15*/ ) ), sub( sNlocal_e, L_tmp_e ) ); L_tmp2 = L_sub_sat( L_tmp2, L_negate( L_tmp ) ); -#else - L_tmp2 = L_shl( L_negate( Mpy_32_16_1( sNlocal, 33 /*0.001f Q15*/ ) ), sub( sNlocal_e, L_tmp_e ) ); - L_tmp2 = L_sub( L_tmp2, L_negate( L_tmp ) ); -#endif BASOP_SATURATE_WARNING_ON_EVS IF( L_tmp2 < 0 ) @@ -2610,12 +2568,8 @@ static void IGF_appl_ivas( IGF_DEC_PRIVATE_DATA_HANDLE hPrivateData, /**< in sum = shl( sum, shift ); /* exponent of sum: sub(15, shift) */ /* divide E by sum */ -#ifdef BASOP_NOGLOB /* Critical Carry/Overflow*/ tmp = div_s( shr( round_fx_o( E, &Overflow ), 1 ), sum ); /* shift E 1 bit to the right in order to make it smaller than sum */ -#else - tmp = div_s( shr( round_fx( E ), 1 ), sum ); /* shift E 1 bit to the right in order to make it smaller than sum */ -#endif - tmp_e = sub( add( E_e, 1 ), sub( 15, shift ) ); /* 15Q0 | sum is 15Q0 */ + tmp_e = sub( add( E_e, 1 ), sub( 15, shift ) ); /* 15Q0 | sum is 15Q0 */ /* multiply the result by the hopsize */ L_tmp = L_mult( tmp, hopsize ); @@ -2702,12 +2656,8 @@ static void IGF_appl_ivas( IGF_DEC_PRIVATE_DATA_HANDLE hPrivateData, /**< in move16(); /* gain[sfb] = min(gain[sfb], 12.f); */ - BASOP_SATURATE_WARNING_OFF_EVS /* threshold, may overflow */ -#ifdef BASOP_NOGLOB + BASOP_SATURATE_WARNING_OFF_EVS /* threshold, may overflow */ tmp = shl_sat( gain[sfb], sub( gain_e[sfb], 15 - 5 ) ); /* 10Q5 | tmp is in 10Q5 */ -#else - tmp = shl( gain[sfb], sub( gain_e[sfb], 15 - 5 ) ); /* 10Q5 | tmp is in 10Q5 */ -#endif BASOP_SATURATE_WARNING_ON_EVS IF( tmp > 384 ) /* 10Q5 | 384 = 12 in 10Q5 */ @@ -2952,19 +2902,22 @@ static void IGF_getWhiteSpectralData_ivas( Word16 guard_bits = add( find_guarded_bits_fx( add( i_mult( 2, level ), 1 ) ), 1 ) / 2; s_l = sub( s_l, guard_bits ); + Word16 quo = BASOP_Util_Divide3216_Scale( ONE_IN_Q30, add( shl( level, 1 ), 1 ), &tmp_e ); + tmp_e = add( tmp_e, 1 ); + + ak_e = add( tmp_e, sub( shl( sub( in_e, s_l ), 1 ), 15 ) ); // tmp_e + 2 * (in_e - s_l) - 15 FOR( i = start; i < stop - level; i++ ) { ak = 0; move32(); - ak_e = 0; move32(); FOR( j = i - level; j < i + level + 1; j++ ) { tmp_16 = extract_h( L_shl( in[j], s_l ) ); // e: in_e - s_l ak = L_mac( ak, tmp_16, tmp_16 ); // e: 2 * (in_e - s_l) } - ak = L_deposit_h( BASOP_Util_Divide3216_Scale( ak, add( shl( level, 1 ), 1 ), &tmp_e ) ); - ak_e = add( tmp_e, sub( shl( sub( in_e, s_l ), 1 ), 15 ) ); // tmp_e + 2 * (in_e - s_l) - 15 + ak = Mult_32_16( ak, quo ); // add( shl( level, 1 ), 1 ), &tmp_e ) ); + n = sub( 30, add( norm_l( ak ), sub( 31, ak_e ) ) ); n = shr( n, 1 ); @@ -2977,9 +2930,7 @@ static void IGF_getWhiteSpectralData_ivas( FOR( ; i < stop; i++ ) { ak = 0; - ak_e = 0; move32(); - move16(); FOR( j = i - level; j < stop; j++ ) { @@ -3036,11 +2987,7 @@ static void IGF_RefineGrid( H_IGF_GRID hGrid /**< in move16(); tmp = add( tmp, 1 ); delta = sub( hGrid->swb_offset[sfb + 1], hGrid->swb_offset[sfb] ); -#ifdef BASOP_NOGLOB /* TBV for 16 kHz, 9.6kbps dtx condition, hGrid->swb_offset[sfb+1] points to an uninit value */ delta = mac_r( 0x00195000, 29491 /*0.45f Q16*/, shl_o( delta, 5, &Overflow ) ); -#else - delta = mac_r( 0x00195000, 29491 /*0.45f Q16*/, shl( delta, 5 ) ); -#endif a[tmp] = add( hGrid->swb_offset[sfb], shr( delta, 6 ) ); move16(); IF( s_and( a[tmp], 1 ) != 0 ) @@ -3088,11 +3035,7 @@ static void IGF_RefineGrid_ivas_fx( H_IGF_GRID hGrid /**< in/out: | IGF grid han move16(); tmp = add( tmp, 1 ); delta = sub( hGrid->swb_offset[sfb + 1], hGrid->swb_offset[sfb] ); -#ifdef BASOP_NOGLOB /* TBV for 16 kHz, 9.6kbps dtx condition, hGrid->swb_offset[sfb+1] points to an uninit value */ delta = mac_r( 0x00195000, 29491 /*0.45f Q16*/, shl_o( delta, 5, &Overflow ) ); -#else - delta = mac_r( 0x00195000, 29491 /*0.45f Q16*/, shl( delta, 5 ) ); -#endif a[tmp] = add( hGrid->swb_offset[sfb], shr( delta, 6 ) ); move16(); // Rounding off delta values >=t+0.5 to t+1 diff --git a/lib_dec/igf_scf_dec.c b/lib_dec/igf_scf_dec.c deleted file mode 100644 index 1c0985cf485291788276d8ca67d81b5170d79d54..0000000000000000000000000000000000000000 --- a/lib_dec/igf_scf_dec.c +++ /dev/null @@ -1,41 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include "prot.h" -#include "stat_dec.h" -#include "wmc_auto.h" diff --git a/lib_dec/init_dec_fx.c b/lib_dec/init_dec_fx.c index d709ff5fcfcc2a11824bc4c07aa47688b3e0f6ec..bd8a2cbd3095c210f6ffa49344a60f66b826c58c 100644 --- a/lib_dec/init_dec_fx.c +++ b/lib_dec/init_dec_fx.c @@ -8,7 +8,6 @@ #include "rom_com.h" /* Static table prototypes */ #include "stl.h" /* required for wmc_tool */ #include "basop_util.h" -#include "prot.h" #include "ivas_prot_fx.h" /*----------------------------------------------------------------------* @@ -20,10 +19,6 @@ ivas_error init_decoder_fx( Decoder_State *st_fx, /* o: Decoder static variables structure */ const Word16 idchan /* i : channel ID */ -#ifdef IVAS_CODE - , - const MC_MODE mc_mode /* i : MC mode */ -#endif ) { Word16 i; @@ -493,8 +488,8 @@ ivas_error init_decoder_fx( set16_fx( st_fx->hTcxDec->FBTCXdelayBuf, 0, 111 ); - st_fx->hTcxDec->old_synthFB_fx = st_fx->hTcxDec->synth_history_fx + NS2SA( st_fx->output_Fs, PH_ECU_MEM_NS ); - st_fx->hTcxDec->prev_good_synth_fx = st_fx->hTcxDec->old_synthFB_fx + NS2SA( st_fx->output_Fs, PH_ECU_LOOKAHEAD_NS ); + st_fx->hTcxDec->old_synthFB_fx = st_fx->hTcxDec->synth_history_fx + NS2SA_FX2( st_fx->output_Fs, PH_ECU_MEM_NS ); + st_fx->hTcxDec->prev_good_synth_fx = st_fx->hTcxDec->old_synthFB_fx + NS2SA_FX2( st_fx->output_Fs, PH_ECU_LOOKAHEAD_NS ); } ELSE { @@ -536,11 +531,7 @@ ivas_error init_decoder_fx( return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for TD BWE\n" ) ); } - td_bwe_dec_init_fx( st_fx, st_fx->hBWE_TD, -#ifdef ADD_IVAS_BWE - st_fx->extl, -#endif - st_fx->output_Fs ); + td_bwe_dec_init_fx( st_fx, st_fx->hBWE_TD, st_fx->output_Fs ); #ifdef MSAN_FIX st_fx->hBWE_TD->prev_hb_synth_fx_exp = 31; @@ -778,11 +769,7 @@ ivas_error init_decoder_fx( resampleCldfb( st_fx->cldfbBPF, newCldfbBands, st_fx->L_frame, 1 ); test(); -#ifdef IVAS_CODE - IF( ( EQ_16( st_fx->element_mode, IVAS_CPE_MDCT ) || idchan == 0 ) && NE_16( mc_mode, MC_MODE_MCT ) && NE_16( mc_mode, MC_MODE_PARAMUPMIX ) ) // TBV Fixed point missing -#else IF( ( EQ_16( st_fx->element_mode, IVAS_CPE_MDCT ) || idchan == 0 ) /*&& mc_mode != MC_MODE_MCT && mc_mode != MC_MODE_PARAMUPMIX*/ ) -#endif { /* Create FD_CNG instance */ @@ -1460,13 +1447,13 @@ ivas_error init_decoder_ivas_fx( IF( ( idchan == 0 && NE_16( st_fx->element_mode, IVAS_CPE_MDCT ) ) || EQ_16( st_fx->element_mode, IVAS_CPE_TD ) ) { /* open analysis for max. SR 48kHz */ - IF( NE_32( ( error = openCldfb_ivas_fx( &st_fx->cldfbAna, CLDFB_ANALYSIS, 48000, CLDFB_PROTOTYPE_1_25MS ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &st_fx->cldfbAna, CLDFB_ANALYSIS, 48000, CLDFB_PROTOTYPE_1_25MS, DEC ) ), IVAS_ERR_OK ) ) { return error; } /* open analysis BPF for max. SR 16kHz */ - IF( NE_32( ( error = openCldfb_ivas_fx( &st_fx->cldfbBPF, CLDFB_ANALYSIS, 16000, CLDFB_PROTOTYPE_1_25MS ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &st_fx->cldfbBPF, CLDFB_ANALYSIS, 16000, CLDFB_PROTOTYPE_1_25MS, DEC ) ), IVAS_ERR_OK ) ) { return error; } @@ -1478,7 +1465,7 @@ ivas_error init_decoder_ivas_fx( } /* open synthesis for output SR */ - IF( NE_32( ( error = openCldfb_ivas_fx( &st_fx->cldfbSyn, CLDFB_SYNTHESIS, st_fx->output_Fs, CLDFB_PROTOTYPE_1_25MS ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &st_fx->cldfbSyn, CLDFB_SYNTHESIS, st_fx->output_Fs, CLDFB_PROTOTYPE_1_25MS, DEC ) ), IVAS_ERR_OK ) ) { return error; } @@ -1822,3 +1809,18 @@ void destroy_cldfb_decoder_fx( return; } + +void destroy_cldfb_decoder_ivas_fx( + Decoder_State *st /* o : Decoder static variables structure */ +) +{ + /* CLDFB BPF & resampling tools */ + deleteCldfb_ivas_fx( &st->cldfbAna ); /* delete analysis at max. sampling rate 48kHz */ + deleteCldfb_ivas_fx( &st->cldfbBPF ); /* delete analysis BPF at max. internal sampling rate 16kHz */ + deleteCldfb_ivas_fx( &st->cldfbSyn ); /* delete synthesis at output sampling rate */ + deleteCldfb_ivas_fx( &st->cldfbSynHB ); + + deleteFdCngDec_fx( &st->hFdCngDec ); + + return; +} diff --git a/lib_dec/inov_dec.c b/lib_dec/inov_dec.c deleted file mode 100644 index 84f371717219c8610d04500e82c61a8cc6a0eca3..0000000000000000000000000000000000000000 --- a/lib_dec/inov_dec.c +++ /dev/null @@ -1,50 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include "cnst.h" -#include "prot.h" -#include "prot_fx.h" -#include "ivas_prot.h" -#include "rom_com.h" -#include "wmc_auto.h" - -/*----------------------------------------------------------------------* - * inov_decode() - * - * Decode the algebraic innovation and do pitch sharpening - *----------------------------------------------------------------------*/ diff --git a/lib_dec/inov_dec_fx.c b/lib_dec/inov_dec_fx.c index ef65c4fcd20fd8f3af216ccf3b7ff5df989c275b..1ab1efe8fa8c587a2494997818d9694b6cc63a71 100644 --- a/lib_dec/inov_dec_fx.c +++ b/lib_dec/inov_dec_fx.c @@ -113,7 +113,7 @@ void inov_decode_fx( move16(); bitcnt = s_and( ACELP_FIXED_CDK_BITS( st_fx->acelp_cfg.fixed_cdk_index[i_subfr / L_SUBFR] ), 15 ); // Q0 move16(); - // PMT("CONDITION above is missing -> idchan") + FOR( i = 0; i < wordcnt; i++ ) { indexing_indices[i] = extract_l( get_next_indice_fx( st_fx, 16 ) ); // Q0 @@ -298,7 +298,7 @@ void inov_decode_ivas_fx( move16(); bitcnt = s_and( ACELP_FIXED_CDK_BITS( st_fx->acelp_cfg.fixed_cdk_index[i_subfr / L_SUBFR] ), 15 ); // Q0 move16(); - // PMT("CONDITION above is missing -> idchan") + FOR( i = 0; i < wordcnt; i++ ) { indexing_indices[i] = get_next_indice_fx( st_fx, 16 ); // Q0 diff --git a/lib_dec/ivas_agc_dec.c b/lib_dec/ivas_agc_dec.c deleted file mode 100644 index 3bfbcee10de7b95c27905f12c5ab83b103a45f84..0000000000000000000000000000000000000000 --- a/lib_dec/ivas_agc_dec.c +++ /dev/null @@ -1,37 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -#include -#include -#include -#include "options.h" -#include "wmc_auto.h" diff --git a/lib_dec/ivas_agc_dec_fx.c b/lib_dec/ivas_agc_dec_fx.c index 8996f087d79a860e574d6b23a6fa30623b42bb68..a196a1abdd8a157e472fdcf21913f8367fd42e63 100644 --- a/lib_dec/ivas_agc_dec_fx.c +++ b/lib_dec/ivas_agc_dec_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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,9 +34,7 @@ #include #include #include "options.h" -#include "prot.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "ivas_prot_fx.h" #include "rom_com.h" #include "wmc_auto.h" diff --git a/lib_dec/ivas_binRenderer_internal.c b/lib_dec/ivas_binRenderer_internal_fx.c similarity index 67% rename from lib_dec/ivas_binRenderer_internal.c rename to lib_dec/ivas_binRenderer_internal_fx.c index 36246f73923c7b643e2709a7b7fc6faa71ace490..ca63053ba9befe4669d10c600d508c6a8e80651f 100644 --- a/lib_dec/ivas_binRenderer_internal.c +++ b/lib_dec/ivas_binRenderer_internal_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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,8 @@ #include #include "options.h" #include -#include "prot.h" -#include "ivas_prot.h" -#include "ivas_prot_rend.h" +#include "prot_fx.h" +#include "ivas_prot_rend_fx.h" #include "cnst.h" #include "ivas_cnst.h" #include "ivas_rom_rend.h" @@ -43,7 +42,6 @@ #include "ivas_rom_com.h" #include "ivas_rom_binauralRenderer.h" #include "wmc_auto.h" -#include "prot_fx.h" #include "ivas_prot_fx.h" #include "ivas_rom_com_fx.h" #include "debug.h" @@ -63,21 +61,52 @@ static void ivas_binRenderer_filterModule_fx( Word32 CLDFB_real[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* i : real part of LS signals Q_curr*/ Word32 CLDFB_imag[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* i : imag part of LS signals Q_curr*/ const Word16 numTimeSlots, /* i : number of time slots to process */ - BINAURAL_RENDERER_HANDLE hBinRenderer, /* i/o: fastconv binaural renderer handle */ +#ifdef SPLIT_REND_WITH_HEAD_ROT + BINAURAL_RENDERER_HANDLE hBinRenderer, /* i/o: fastconv binaural renderer handle */ + const Word16 pos_idx, /* i : pose index */ +#else + BINAURAL_RENDERER_HANDLE hBinRenderer, /* i/o: fastconv binaural renderer handle */ +#endif Word16 Q_curr ) { Word16 bandIdx, k, chIdx, tapIdx; Word32 *filterStatesLeftRealPtr_fx, *filterStatesLeftImagPtr_fx; +#ifdef OPT_BASOP_ADD_v1 + Word16 Q_filterStates; +#else /* OPT_BASOP_ADD_v1 */ Word16 *Q_filterStates; +#endif /* OPT_BASOP_ADD_v1 */ const Word32 *filterTapsLeftRealPtr_fx, *filterTapsLeftImagPtr_fx, *filterTapsRightRealPtr_fx, *filterTapsRightImagPtr_fx; + Word16 shift_q; +#ifdef SPLIT_REND_WITH_HEAD_ROT +#ifdef OPT_BASOP_ADD_v1 + Q_filterStates = hBinRenderer->hBinRenConvModule->Q_filterStates[pos_idx]; + move16(); +#endif /* OPT_BASOP_ADD_v1 */ +#else +#ifdef OPT_BASOP_ADD_v1 + Q_filterStates = hBinRenderer->hBinRenConvModule->Q_filterStatesLeft; + move16(); +#endif /* OPT_BASOP_ADD_v1 */ +#endif FOR( bandIdx = 0; bandIdx < hBinRenderer->conv_band; bandIdx++ ) { FOR( chIdx = 0; chIdx < hBinRenderer->nInChannels; chIdx++ ) { +#ifdef SPLIT_REND_WITH_HEAD_ROT + filterStatesLeftRealPtr_fx = (Word32 *) &( hBinRenderer->hBinRenConvModule->filterStatesLeftReal_fx[pos_idx][bandIdx][chIdx][0] ); + filterStatesLeftImagPtr_fx = (Word32 *) &( hBinRenderer->hBinRenConvModule->filterStatesLeftImag_fx[pos_idx][bandIdx][chIdx][0] ); +#ifndef OPT_BASOP_ADD_v1 + Q_filterStates = (Word16 *) &( hBinRenderer->hBinRenConvModule->Q_filterStatesLeft[pos_idx][bandIdx][chIdx][0] ); +#endif +#else filterStatesLeftRealPtr_fx = (Word32 *) &( hBinRenderer->hBinRenConvModule->filterStatesLeftReal_fx[bandIdx][chIdx][0] ); filterStatesLeftImagPtr_fx = (Word32 *) &( hBinRenderer->hBinRenConvModule->filterStatesLeftImag_fx[bandIdx][chIdx][0] ); +#ifndef OPT_BASOP_ADD_v1 Q_filterStates = (Word16 *) &( hBinRenderer->hBinRenConvModule->Q_filterStatesLeft[bandIdx][chIdx][0] ); +#endif /* OPT_BASOP_ADD_v1 */ +#endif /* SPLIT_REND_WITH_HEAD_ROT */ filterTapsLeftRealPtr_fx = hBinRenderer->hBinRenConvModule->filterTapsLeftReal_fx[bandIdx][chIdx]; // Q29 filterTapsLeftImagPtr_fx = hBinRenderer->hBinRenConvModule->filterTapsLeftImag_fx[bandIdx][chIdx]; // Q29 @@ -87,11 +116,6 @@ static void ivas_binRenderer_filterModule_fx( FOR( k = 0; k < numTimeSlots; k++ ) { Word64 outRealLeft_fx = 0, outRealRight_fx = 0, outImagLeft_fx = 0, outImagRight_fx = 0; - Word64 W_sub1 = 0, W_add1 = 0, W_sub2 = 0, W_add2 = 0; - move64(); - move64(); - move64(); - move64(); move64(); move64(); move64(); @@ -104,64 +128,91 @@ static void ivas_binRenderer_filterModule_fx( filterStatesLeftImagPtr_fx[tapIdx] = filterStatesLeftImagPtr_fx[tapIdx - 1]; move32(); - W_sub1 = W_sub( W_mult0_32_32( filterStatesLeftRealPtr_fx[tapIdx], filterTapsLeftRealPtr_fx[tapIdx] ), - W_mult0_32_32( filterStatesLeftImagPtr_fx[tapIdx], filterTapsLeftImagPtr_fx[tapIdx] ) ); // Q29 + Q_filterStates[tapIdx - 1] - W_add1 = W_add( W_mult0_32_32( filterStatesLeftRealPtr_fx[tapIdx], filterTapsLeftImagPtr_fx[tapIdx] ), - W_mult0_32_32( filterStatesLeftImagPtr_fx[tapIdx], filterTapsLeftRealPtr_fx[tapIdx] ) ); // Q29 + Q_filterStates[tapIdx - 1] - W_sub2 = W_sub( W_mult0_32_32( filterStatesLeftRealPtr_fx[tapIdx], filterTapsRightRealPtr_fx[tapIdx] ), - W_mult0_32_32( filterStatesLeftImagPtr_fx[tapIdx], filterTapsRightImagPtr_fx[tapIdx] ) ); // Q29 + Q_filterStates[tapIdx - 1] - W_add2 = W_add( W_mult0_32_32( filterStatesLeftRealPtr_fx[tapIdx], filterTapsRightImagPtr_fx[tapIdx] ), - W_mult0_32_32( filterStatesLeftImagPtr_fx[tapIdx], filterTapsRightRealPtr_fx[tapIdx] ) ); // Q29 + Q_filterStates[tapIdx - 1] +#ifndef OPT_BASOP_ADD_v1 + shift_q = sub( Q_filterStates[tapIdx], Q_filterStates[tapIdx - 1] ); + outRealLeft_fx = W_shr( outRealLeft_fx, shift_q ); + outImagLeft_fx = W_shr( outImagLeft_fx, shift_q ); + outRealRight_fx = W_shr( outRealRight_fx, shift_q ); + outImagRight_fx = W_shr( outImagRight_fx, shift_q ); +#endif /* OPT_BASOP_ADD_v1 */ + + outRealLeft_fx = W_mac_32_32( outRealLeft_fx, filterStatesLeftRealPtr_fx[tapIdx], filterTapsLeftRealPtr_fx[tapIdx] ); // Q30 + Q_filterStates + outRealLeft_fx = W_mac_32_32( outRealLeft_fx, L_negate( filterStatesLeftImagPtr_fx[tapIdx] ), filterTapsLeftImagPtr_fx[tapIdx] ); // Q30 + Q_filterStates + + outImagLeft_fx = W_mac_32_32( outImagLeft_fx, filterStatesLeftRealPtr_fx[tapIdx], filterTapsLeftImagPtr_fx[tapIdx] ); // Q30 + Q_filterStates + outImagLeft_fx = W_mac_32_32( outImagLeft_fx, filterStatesLeftImagPtr_fx[tapIdx], filterTapsLeftRealPtr_fx[tapIdx] ); // Q30 + Q_filterStates - outRealLeft_fx = W_shr( outRealLeft_fx, sub( Q_filterStates[tapIdx], Q_filterStates[tapIdx - 1] ) ); - outImagLeft_fx = W_shr( outImagLeft_fx, sub( Q_filterStates[tapIdx], Q_filterStates[tapIdx - 1] ) ); - outRealRight_fx = W_shr( outRealRight_fx, sub( Q_filterStates[tapIdx], Q_filterStates[tapIdx - 1] ) ); - outImagRight_fx = W_shr( outImagRight_fx, sub( Q_filterStates[tapIdx], Q_filterStates[tapIdx - 1] ) ); + outRealRight_fx = W_mac_32_32( outRealRight_fx, filterStatesLeftRealPtr_fx[tapIdx], filterTapsRightRealPtr_fx[tapIdx] ); // Q30 + Q_filterStates + outRealRight_fx = W_mac_32_32( outRealRight_fx, L_negate( filterStatesLeftImagPtr_fx[tapIdx] ), filterTapsRightImagPtr_fx[tapIdx] ); // Q30 + Q_filterStates + outImagRight_fx = W_mac_32_32( outImagRight_fx, filterStatesLeftRealPtr_fx[tapIdx], filterTapsRightImagPtr_fx[tapIdx] ); // Q30 + Q_filterStates + outImagRight_fx = W_mac_32_32( outImagRight_fx, filterStatesLeftImagPtr_fx[tapIdx], filterTapsRightRealPtr_fx[tapIdx] ); // Q30 + Q_filterStates +#ifndef OPT_BASOP_ADD_v1 Q_filterStates[tapIdx] = Q_filterStates[tapIdx - 1]; move16(); +#endif /* OPT_BASOP_ADD_v1 */ + } - /* Left Real and Imag */ - outRealLeft_fx = W_add( outRealLeft_fx, W_sub1 ); // Q29 + Q_filterStates[1] - outImagLeft_fx = W_add( outImagLeft_fx, W_add1 ); // Q29 + Q_filterStates[1] +#ifdef OPT_BASOP_ADD_v1 + shift_q = add( sub( Q_filterStates, Q_curr ), 1 ); +#else /* OPT_BASOP_ADD_v1 */ + shift_q = add( sub( Q_filterStates[1], Q_curr ), 1 ); +#endif /* OPT_BASOP_ADD_v1 */ - /* Right Real and Imag*/ - outRealRight_fx = W_add( outRealRight_fx, W_sub2 ); // Q29 + Q_filterStates[1] - outImagRight_fx = W_add( outImagRight_fx, W_add2 ); // Q29 + Q_filterStates[1] +#ifdef OPT_BASOP_ADD_v1 + IF( shift_q != 0 ) + { +#endif /* OPT_BASOP_ADD_v1 */ + outRealLeft_fx = W_shr( outRealLeft_fx, shift_q ); // Q_curr + outImagLeft_fx = W_shr( outImagLeft_fx, shift_q ); // Q_curr + outRealRight_fx = W_shr( outRealRight_fx, shift_q ); // Q_curr + outImagRight_fx = W_shr( outImagRight_fx, shift_q ); // Q_curr +#ifdef OPT_BASOP_ADD_v1 +#ifdef SPLIT_REND_WITH_HEAD_ROT + hBinRenderer->hBinRenConvModule->Q_filterStates[pos_idx] = Q_curr; +#else + hBinRenderer->hBinRenConvModule->Q_filterStatesLeft = Q_curr; +#endif + move16(); } +#endif /* OPT_BASOP_ADD_v1 */ filterStatesLeftRealPtr_fx[0] = CLDFB_real[chIdx][k][bandIdx]; move32(); filterStatesLeftImagPtr_fx[0] = CLDFB_imag[chIdx][k][bandIdx]; move32(); +#ifndef OPT_BASOP_ADD_v1 Q_filterStates[0] = Q_curr; move16(); +#endif /* OPT_BASOP_ADD_v1 */ /* Left Real and Imag */ // Q29 + Q_curr - out_Conv_CLDFB_real[0][k][bandIdx] = W_add( out_Conv_CLDFB_real[0][k][bandIdx], - W_add( W_shr( outRealLeft_fx, sub( Q_filterStates[1], Q_curr ) ), - W_sub( W_mult0_32_32( filterStatesLeftRealPtr_fx[0], filterTapsLeftRealPtr_fx[0] ), - W_mult0_32_32( filterStatesLeftImagPtr_fx[0], filterTapsLeftImagPtr_fx[0] ) ) ) ); // Q29 + Word32 temp1 = L_shr( filterStatesLeftRealPtr_fx[0], 1 ); + Word32 temp2 = L_shr( filterStatesLeftImagPtr_fx[0], 1 ); + + + outRealLeft_fx = W_mac_32_32( outRealLeft_fx, temp1, filterTapsLeftRealPtr_fx[0] ); + outRealLeft_fx = W_mac_32_32( outRealLeft_fx, L_negate( temp2 ), filterTapsLeftImagPtr_fx[0] ); + out_Conv_CLDFB_real[0][k][bandIdx] = W_add( out_Conv_CLDFB_real[0][k][bandIdx], outRealLeft_fx ); // Q29 move64(); - out_Conv_CLDFB_imag[0][k][bandIdx] = W_add( out_Conv_CLDFB_imag[0][k][bandIdx], - W_add( W_shr( outImagLeft_fx, sub( Q_filterStates[1], Q_curr ) ), - W_add( W_mult0_32_32( filterStatesLeftRealPtr_fx[0], filterTapsLeftImagPtr_fx[0] ), - W_mult0_32_32( filterStatesLeftImagPtr_fx[0], filterTapsLeftRealPtr_fx[0] ) ) ) ); // Q29 + + outImagLeft_fx = W_mac_32_32( outImagLeft_fx, temp1, filterTapsLeftImagPtr_fx[0] ); + outImagLeft_fx = W_mac_32_32( outImagLeft_fx, temp2, filterTapsLeftRealPtr_fx[0] ); + out_Conv_CLDFB_imag[0][k][bandIdx] = W_add( out_Conv_CLDFB_imag[0][k][bandIdx], outImagLeft_fx ); // Q29 move64(); /* Right Real and Imag */ - out_Conv_CLDFB_real[1][k][bandIdx] = W_add( out_Conv_CLDFB_real[1][k][bandIdx], - W_add( W_shr( outRealRight_fx, sub( Q_filterStates[1], Q_curr ) ), - W_sub( W_mult0_32_32( filterStatesLeftRealPtr_fx[0], filterTapsRightRealPtr_fx[0] ), - W_mult0_32_32( filterStatesLeftImagPtr_fx[0], filterTapsRightImagPtr_fx[0] ) ) ) ); // Q29 + outRealRight_fx = W_mac_32_32( outRealRight_fx, temp1, filterTapsRightRealPtr_fx[0] ); + outRealRight_fx = W_mac_32_32( outRealRight_fx, L_negate( temp2 ), filterTapsRightImagPtr_fx[0] ); + out_Conv_CLDFB_real[1][k][bandIdx] = W_add( out_Conv_CLDFB_real[1][k][bandIdx], outRealRight_fx ); // Q29 move64(); - out_Conv_CLDFB_imag[1][k][bandIdx] = W_add( out_Conv_CLDFB_imag[1][k][bandIdx], - W_add( W_shr( outImagRight_fx, sub( Q_filterStates[1], Q_curr ) ), - W_add( W_mult0_32_32( filterStatesLeftRealPtr_fx[0], filterTapsRightImagPtr_fx[0] ), - W_mult0_32_32( filterStatesLeftImagPtr_fx[0], filterTapsRightRealPtr_fx[0] ) ) ) ); // Q29 + + outImagRight_fx = W_mac_32_32( outImagRight_fx, temp1, filterTapsRightImagPtr_fx[0] ); + outImagRight_fx = W_mac_32_32( outImagRight_fx, temp2, filterTapsRightRealPtr_fx[0] ); + out_Conv_CLDFB_imag[1][k][bandIdx] = W_add( out_Conv_CLDFB_imag[1][k][bandIdx], outImagRight_fx ); // Q29 move64(); } } @@ -180,9 +231,18 @@ static ivas_error ivas_binRenderer_convModuleOpen( const Word16 renderer_type, const Word16 isLoudspeaker, const AUDIO_CONFIG input_config, - const HRTFS_FASTCONV_HANDLE hHrtf ) +#ifdef SPLIT_REND_WITH_HEAD_ROT + const HRTFS_FASTCONV_HANDLE hHrtf, + const Word16 num_poses +#else + const HRTFS_FASTCONV_HANDLE hHrtf +#endif +) { Word16 bandIdx, chIdx; +#ifdef SPLIT_REND_WITH_HEAD_ROT + Word16 pos_idx; +#endif BINRENDERER_CONV_MODULE_HANDLE_FX hBinRenConvModule; @@ -308,7 +368,90 @@ static ivas_error ivas_binRenderer_convModuleOpen( } } +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( ( hBinRenConvModule->filterStatesLeftReal_fx = (Word32 ****) malloc( num_poses * sizeof( Word32 *** ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) ); + } + + if ( ( hBinRenConvModule->filterStatesLeftImag_fx = (Word32 ****) malloc( num_poses * sizeof( Word32 *** ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) ); + } + +#ifdef OPT_BASOP_ADD_v1 + IF( ( hBinRenConvModule->Q_filterStates = (Word16 *) malloc( num_poses * sizeof( Word16 ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) ); + } +#else + IF( ( hBinRenConvModule->Q_filterStatesLeft = (Word16 ****) malloc( num_poses * sizeof( Word16 *** ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) ); + } +#endif /* OPT_BASOP_ADD_v1 */ + + for ( pos_idx = 0; pos_idx < num_poses; pos_idx++ ) + { + if ( ( hBinRenConvModule->filterStatesLeftReal_fx[pos_idx] = (Word32 ***) malloc( hBinRenderer->conv_band * sizeof( Word32 ** ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) ); + } + if ( ( hBinRenConvModule->filterStatesLeftImag_fx[pos_idx] = (Word32 ***) malloc( hBinRenderer->conv_band * sizeof( Word32 ** ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) ); + } + +#ifndef OPT_BASOP_ADD_v1 + IF( ( hBinRenConvModule->Q_filterStatesLeft[pos_idx] = (Word16 ***) malloc( hBinRenderer->conv_band * sizeof( Word16 ** ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) ); + } +#endif /* OPT_BASOP_ADD_v1 */ + + for ( bandIdx = 0; bandIdx < hBinRenderer->conv_band; bandIdx++ ) + { + if ( ( hBinRenConvModule->filterStatesLeftReal_fx[pos_idx][bandIdx] = (Word32 **) malloc( hBinRenderer->nInChannels * sizeof( Word32 * ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) ); + } + + if ( ( hBinRenConvModule->filterStatesLeftImag_fx[pos_idx][bandIdx] = (Word32 **) malloc( hBinRenderer->nInChannels * sizeof( Word32 * ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) ); + } + +#ifndef OPT_BASOP_ADD_v1 + IF( ( hBinRenConvModule->Q_filterStatesLeft[pos_idx][bandIdx] = (Word16 **) malloc( hBinRenderer->nInChannels * sizeof( Word16 * ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) ); + } +#endif /* OPT_BASOP_ADD_v1 */ + + for ( chIdx = 0; chIdx < hBinRenderer->nInChannels; chIdx++ ) + { + if ( ( hBinRenConvModule->filterStatesLeftReal_fx[pos_idx][bandIdx][chIdx] = (Word32 *) malloc( hBinRenConvModule->numTapsArray[bandIdx] * sizeof( Word32 ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) ); + } + + if ( ( hBinRenConvModule->filterStatesLeftImag_fx[pos_idx][bandIdx][chIdx] = (Word32 *) malloc( hBinRenConvModule->numTapsArray[bandIdx] * sizeof( Word32 ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) ); + } + +#ifndef OPT_BASOP_ADD_v1 + IF( ( hBinRenConvModule->Q_filterStatesLeft[pos_idx][bandIdx][chIdx] = (Word16 *) malloc( hBinRenConvModule->numTapsArray[bandIdx] * sizeof( Word16 ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) ); + } +#endif /* OPT_BASOP_ADD_v1 */ + } + } + } + +#else IF( ( hBinRenConvModule->filterStatesLeftReal_fx = (Word32 ***) malloc( hBinRenderer->conv_band * sizeof( Word32 ** ) ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) ); @@ -319,10 +462,12 @@ static ivas_error ivas_binRenderer_convModuleOpen( return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) ); } +#ifndef OPT_BASOP_ADD_v1 IF( ( hBinRenConvModule->Q_filterStatesLeft = (Word16 ***) malloc( hBinRenderer->conv_band * sizeof( Word16 ** ) ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) ); } +#endif /* OPT_BASOP_ADD_v1 */ FOR( bandIdx = 0; bandIdx < hBinRenderer->conv_band; bandIdx++ ) { @@ -336,10 +481,12 @@ static ivas_error ivas_binRenderer_convModuleOpen( return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) ); } +#ifndef OPT_BASOP_ADD_v1 IF( ( hBinRenConvModule->Q_filterStatesLeft[bandIdx] = (Word16 **) malloc( hBinRenderer->nInChannels * sizeof( Word16 * ) ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) ); } +#endif /* OPT_BASOP_ADD_v1 */ FOR( chIdx = 0; chIdx < hBinRenderer->nInChannels; chIdx++ ) { @@ -353,12 +500,15 @@ static ivas_error ivas_binRenderer_convModuleOpen( return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) ); } +#ifndef OPT_BASOP_ADD_v1 IF( ( hBinRenConvModule->Q_filterStatesLeft[bandIdx][chIdx] = (Word16 *) malloc( hBinRenConvModule->numTapsArray[bandIdx] * sizeof( Word16 ) ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) ); } +#endif /* OPT_BASOP_ADD_v1 */ } } +#endif /* set memories */ FOR( bandIdx = 0; bandIdx < hBinRenderer->conv_band; bandIdx++ ) { @@ -399,9 +549,16 @@ static ivas_error ivas_binRenderer_convModuleOpen( IF( EQ_16( renderer_type, RENDERER_BINAURAL_FASTCONV_ROOM ) ) { /* set the memories to zero */ +#ifndef SPLIT_REND_WITH_HEAD_ROT set32_fx( hBinRenConvModule->filterStatesLeftReal_fx[bandIdx][chIdx], 0, hBinRenConvModule->numTapsArray[bandIdx] ); set32_fx( hBinRenConvModule->filterStatesLeftImag_fx[bandIdx][chIdx], 0, hBinRenConvModule->numTapsArray[bandIdx] ); +#ifdef OPT_BASOP_ADD_v1 + hBinRenConvModule->Q_filterStatesLeft = 31; + move16(); +#else /* OPT_BASOP_ADD_v1 */ set16_fx( hBinRenConvModule->Q_filterStatesLeft[bandIdx][chIdx], 31, hBinRenConvModule->numTapsArray[bandIdx] ); +#endif /* OPT_BASOP_ADD_v1 */ +#endif /* !SPLIT_REND_WITH_HEAD_ROT */ IF( isLoudspeaker ) { hBinRenConvModule->filterTapsLeftReal_fx[bandIdx][chIdx] = hHrtf->leftBRIRReal_fx[bandIdx][tmp]; @@ -412,10 +569,17 @@ static ivas_error ivas_binRenderer_convModuleOpen( } ELSE { +#ifndef SPLIT_REND_WITH_HEAD_ROT /* set the memories to zero */ set32_fx( hBinRenConvModule->filterStatesLeftReal_fx[bandIdx][chIdx], 0, hBinRenConvModule->numTaps ); set32_fx( hBinRenConvModule->filterStatesLeftImag_fx[bandIdx][chIdx], 0, hBinRenConvModule->numTaps ); +#ifdef OPT_BASOP_ADD_v1 + hBinRenConvModule->Q_filterStatesLeft = 31; + move16(); +#else /* OPT_BASOP_ADD_v1 */ set16_fx( hBinRenConvModule->Q_filterStatesLeft[bandIdx][chIdx], 31, hBinRenConvModule->numTaps ); +#endif /* OPT_BASOP_ADD_v1 */ +#endif /* SPLIT_REND_WITH_HEAD_ROT */ IF( isLoudspeaker ) { hBinRenConvModule->filterTapsLeftReal_fx[bandIdx][chIdx] = hHrtf->leftHRIRReal_fx[bandIdx][tmp]; @@ -458,6 +622,52 @@ static ivas_error ivas_binRenderer_convModuleOpen( } } +#ifdef SPLIT_REND_WITH_HEAD_ROT + IF( EQ_16( renderer_type, RENDERER_BINAURAL_FASTCONV_ROOM ) ) + { + for ( pos_idx = 0; pos_idx < num_poses; pos_idx++ ) + { +#ifdef OPT_BASOP_ADD_v1 + hBinRenConvModule->Q_filterStates[pos_idx] = 31; + move16(); +#endif + for ( bandIdx = 0; bandIdx < hBinRenderer->conv_band; bandIdx++ ) + { + for ( chIdx = 0; chIdx < hBinRenderer->nInChannels; chIdx++ ) + { + /* set the memories to zero */ + set32_fx( hBinRenConvModule->filterStatesLeftReal_fx[pos_idx][bandIdx][chIdx], 0, hBinRenConvModule->numTapsArray[bandIdx] ); + set32_fx( hBinRenConvModule->filterStatesLeftImag_fx[pos_idx][bandIdx][chIdx], 0, hBinRenConvModule->numTapsArray[bandIdx] ); +#ifndef OPT_BASOP_ADD_v1 + set16_fx( hBinRenConvModule->Q_filterStatesLeft[pos_idx][bandIdx][chIdx], 31, hBinRenConvModule->numTapsArray[bandIdx] ); +#endif /* OPT_BASOP_ADD_v1 */ + } + } + } + } + ELSE + { + for ( pos_idx = 0; pos_idx < num_poses; pos_idx++ ) + { +#ifdef OPT_BASOP_ADD_v1 + hBinRenConvModule->Q_filterStates[pos_idx] = 31; + move16(); +#endif + for ( bandIdx = 0; bandIdx < hBinRenderer->conv_band; bandIdx++ ) + { + for ( chIdx = 0; chIdx < hBinRenderer->nInChannels; chIdx++ ) + { + /* set the memories to zero */ + set32_fx( hBinRenConvModule->filterStatesLeftReal_fx[pos_idx][bandIdx][chIdx], 0, hBinRenConvModule->numTaps ); + set32_fx( hBinRenConvModule->filterStatesLeftImag_fx[pos_idx][bandIdx][chIdx], 0, hBinRenConvModule->numTaps ); +#ifndef OPT_BASOP_ADD_v1 + set16_fx( hBinRenConvModule->Q_filterStatesLeft[pos_idx][bandIdx][chIdx], 31, hBinRenConvModule->numTaps ); +#endif /* OPT_BASOP_ADD_v1 */ + } + } + } + } +#endif hBinRenderer->hBinRenConvModule = hBinRenConvModule; @@ -544,25 +754,27 @@ static ivas_error ivas_alloc_pppMem_fx( return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for HRTF memory" ); } - FOR( i = 0; i < dim1; i++ ){ - IF( ( localMem[i] = (Word32 **) malloc( dim2 * sizeof( Word32 * ) ) ) == NULL ){ - return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for HRTF memory" ); -} -IF( allocate_init_flag == 0 ) -{ - FOR( j = 0; j < dim2; j++ ) + for ( i = 0; i < dim1; i++ ) { - IF( ( localMem[i][j] = (Word32 *) malloc( dim3 * sizeof( Word32 ) ) ) == NULL ) + IF( ( localMem[i] = (Word32 **) malloc( dim2 * sizeof( Word32 * ) ) ) == NULL ) { return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for HRTF memory" ); } + IF( allocate_init_flag == 0 ) + { + FOR( j = 0; j < dim2; j++ ) + { + IF( ( localMem[i][j] = (Word32 *) malloc( dim3 * sizeof( Word32 ) ) ) == NULL ) + { + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for HRTF memory" ); + } + } + } } -} -} -*pppMem = localMem; + *pppMem = localMem; -return IVAS_ERR_OK; + return IVAS_ERR_OK; } /*-------------------------------------------------------------------------* @@ -1009,6 +1221,112 @@ static void ivas_binaural_obtain_DMX_fx( return; } + +#ifdef SPLIT_REND_WITH_HEAD_ROT +/*------------------------------------------------------------------------- + * ivas_rend_openCldfbRend() + * + * Allocate and initialize CLDFB fast conv renderer handle + *------------------------------------------------------------------------*/ + +ivas_error ivas_rend_openCldfbRend( + CLDFB_REND_WRAPPER *pCldfbRend, + const AUDIO_CONFIG inConfig, + const AUDIO_CONFIG outConfig, + const MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, + const Word32 output_Fs ) +{ + BINAURAL_RENDERER_HANDLE hBinRenderer; + Word16 convBand; + ivas_error error; + + error = IVAS_ERR_OK; + + /*-----------------------------------------------------------------* + * prepare library opening + *-----------------------------------------------------------------*/ + + if ( ( hBinRenderer = (BINAURAL_RENDERER_HANDLE) malloc( sizeof( BINAURAL_RENDERER ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Binaural Renderer\n" ) ); + } + + if ( ( hBinRenderer->hInputSetup = (IVAS_OUTPUT_SETUP_HANDLE) malloc( sizeof( IVAS_OUTPUT_SETUP ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for output setup Binaural Renderer\n" ) ); + } + + hBinRenderer->rotInCldfb = 1; + hBinRenderer->ivas_format = SBA_FORMAT; + + hBinRenderer->max_band = extract_l( Mpy_32_32( Mpy_32_32( BINAURAL_MAXBANDS_Q25, L_shl( output_Fs, Q6 ) ), ONE_BY_48000_Q31 ) ); + move16(); + + convBand = hBinRenderer->max_band; + move16(); + + hBinRenderer->timeSlots = MAX_PARAM_SPATIAL_SUBFRAMES; /* Corresponds to 5 msec sound to motion latency */ + move16(); + + IF( GT_16( convBand, BINAURAL_CONVBANDS ) ) + { + hBinRenderer->conv_band = BINAURAL_CONVBANDS; + move16(); + } + ELSE + { + hBinRenderer->conv_band = convBand; + move16(); + } + + hBinRenderer->hInputSetup->is_loudspeaker_setup = 0; + hBinRenderer->hInputSetup->output_config = inConfig; + IF( ( error = getAudioConfigNumChannels( inConfig, &hBinRenderer->hInputSetup->nchan_out_woLFE ) ) != IVAS_ERR_OK ) + { + return error; + } + + IF( EQ_32( outConfig, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) || EQ_32( outConfig, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ) + { + hBinRenderer->numPoses = pMultiBinPoseData->num_poses; + move16(); + } + ELSE + { + hBinRenderer->numPoses = 1; + move16(); + } + + /*LFE rendering switched off by default*/ + hBinRenderer->render_lfe = 0; + move16(); + + + /* Load HRTF tables */ + IF( NE_32( ( error = ivas_binaural_hrtf_open_fx( &pCldfbRend->hHrtfFastConv, hBinRenderer->hInputSetup->output_config, RENDERER_BINAURAL_FASTCONV ) ), IVAS_ERR_OK ) ) + { + return error; + } + + /* Allocate memories and buffers needed for convolutional module in CICP19 */ + IF( NE_32( ( error = ivas_binRenderer_convModuleOpen( hBinRenderer, RENDERER_BINAURAL_FASTCONV, hBinRenderer->hInputSetup->is_loudspeaker_setup, inConfig, pCldfbRend->hHrtfFastConv, hBinRenderer->numPoses ) ), IVAS_ERR_OK ) ) + { + return error; + } + + pCldfbRend->binaural_latency_ns = (Word32) ( pCldfbRend->hHrtfFastConv->FASTCONV_HOA3_latency_s_fx * 1000000000 ); + move32(); + hBinRenderer->hReverb = NULL; + move32(); + hBinRenderer->hEFAPdata = NULL; + move32(); + pCldfbRend->hCldfbRend = hBinRenderer; + move32(); + + return error; +} +#endif + /*------------------------------------------------------------------------- * ivas_binRenderer_open() * @@ -1046,6 +1364,18 @@ ivas_error ivas_binRenderer_open_fx( move16(); } +#ifdef SPLIT_REND_WITH_HEAD_ROT + IF( EQ_32( st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) || EQ_32( st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ) + { + hBinRenderer->numPoses = st_ivas->hSplitBinRend->splitrend.multiBinPoseData.num_poses; + move16(); + } + else + { + hBinRenderer->numPoses = 1; + move16(); + } +#endif /* Declare some common variables needed for renderer */ /* Which format used for binaural rendering (needed for late reverb) ? MC or SBA */ @@ -1102,11 +1432,17 @@ ivas_error ivas_binRenderer_open_fx( IVAS_OUTPUT_SETUP out_setup; /* Allocate memories and buffers needed for convolutional module in CICP19 */ +#ifdef SPLIT_REND_WITH_HEAD_ROT + IF( NE_32( ( error = ivas_binRenderer_convModuleOpen( hBinRenderer, st_ivas->renderer_type, 1, IVAS_AUDIO_CONFIG_7_1_4, st_ivas->hHrtfFastConv, hBinRenderer->numPoses ) ), IVAS_ERR_OK ) ) + { + return error; + } +#else IF( NE_32( ( error = ivas_binRenderer_convModuleOpen( hBinRenderer, st_ivas->renderer_type, 1, IVAS_AUDIO_CONFIG_7_1_4, st_ivas->hHrtfFastConv ) ), IVAS_ERR_OK ) ) { return error; } - +#endif ivas_output_init( &out_setup, IVAS_AUDIO_CONFIG_7_1_4 ); IF( st_ivas->hoa_dec_mtx == NULL ) @@ -1124,10 +1460,17 @@ ivas_error ivas_binRenderer_open_fx( ELSE { /* Allocate memories and buffers needed for convolutional module */ +#ifdef SPLIT_REND_WITH_HEAD_ROT + IF( NE_32( ( error = ivas_binRenderer_convModuleOpen( hBinRenderer, st_ivas->renderer_type, st_ivas->hIntSetup.is_loudspeaker_setup, st_ivas->hIntSetup.output_config, st_ivas->hHrtfFastConv, hBinRenderer->numPoses ) ), IVAS_ERR_OK ) ) + { + return error; + } +#else IF( NE_32( ( error = ivas_binRenderer_convModuleOpen( hBinRenderer, st_ivas->renderer_type, st_ivas->hIntSetup.is_loudspeaker_setup, st_ivas->hIntSetup.output_config, st_ivas->hHrtfFastConv ) ), IVAS_ERR_OK ) ) { return error; } +#endif IF( EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_FASTCONV ) ) { @@ -1229,10 +1572,18 @@ ivas_error ivas_binRenderer_open_fx( * Close convolution module handle of fastconv binaural renderer *------------------------------------------------------------------------*/ static void ivas_binRenderer_convModuleClose_fx( +#ifdef SPLIT_REND_WITH_HEAD_ROT + BINAURAL_RENDERER_HANDLE *hBinRenderer, /* i/o: fastconv binaural renderer handle */ + const Word16 num_poses /* i : number of poses */ +#else BINAURAL_RENDERER_HANDLE *hBinRenderer /* i/o: fastconv binaural renderer handle */ +#endif ) { Word16 bandIdx, chIdx; +#ifdef SPLIT_REND_WITH_HEAD_ROT + Word16 posIdx; +#endif BINRENDERER_CONV_MODULE_HANDLE_FX hBinRenConvModule; @@ -1270,6 +1621,48 @@ static void ivas_binRenderer_convModuleClose_fx( free( hBinRenConvModule->filterTapsRightImag_fx ); hBinRenConvModule->filterTapsRightImag_fx = NULL; +#ifdef SPLIT_REND_WITH_HEAD_ROT + FOR( posIdx = 0; posIdx < num_poses; posIdx++ ) + { + FOR( bandIdx = 0; bandIdx < ( *hBinRenderer )->conv_band; bandIdx++ ) + { + FOR( chIdx = 0; chIdx < ( *hBinRenderer )->nInChannels; chIdx++ ) + { + free( hBinRenConvModule->filterStatesLeftReal_fx[posIdx][bandIdx][chIdx] ); + hBinRenConvModule->filterStatesLeftReal_fx[posIdx][bandIdx][chIdx] = NULL; + + free( hBinRenConvModule->filterStatesLeftImag_fx[posIdx][bandIdx][chIdx] ); + hBinRenConvModule->filterStatesLeftImag_fx[posIdx][bandIdx][chIdx] = NULL; +#ifndef OPT_BASOP_ADD_v1 + + free( hBinRenConvModule->Q_filterStatesLeft[posIdx][bandIdx][chIdx] ); + hBinRenConvModule->Q_filterStatesLeft[posIdx][bandIdx][chIdx] = NULL; +#endif /* OPT_BASOP_ADD_v1 */ + } + + free( hBinRenConvModule->filterStatesLeftReal_fx[posIdx][bandIdx] ); + hBinRenConvModule->filterStatesLeftReal_fx[posIdx][bandIdx] = NULL; + + free( hBinRenConvModule->filterStatesLeftImag_fx[posIdx][bandIdx] ); + hBinRenConvModule->filterStatesLeftImag_fx[posIdx][bandIdx] = NULL; +#ifndef OPT_BASOP_ADD_v1 + + free( hBinRenConvModule->Q_filterStatesLeft[posIdx][bandIdx] ); + hBinRenConvModule->Q_filterStatesLeft[posIdx][bandIdx] = NULL; +#endif /* OPT_BASOP_ADD_v1 */ + } + free( hBinRenConvModule->filterStatesLeftReal_fx[posIdx] ); + hBinRenConvModule->filterStatesLeftReal_fx[posIdx] = NULL; + + free( hBinRenConvModule->filterStatesLeftImag_fx[posIdx] ); + hBinRenConvModule->filterStatesLeftImag_fx[posIdx] = NULL; +#ifndef OPT_BASOP_ADD_v1 + + free( hBinRenConvModule->Q_filterStatesLeft[posIdx] ); + hBinRenConvModule->Q_filterStatesLeft[posIdx] = NULL; +#endif /* OPT_BASOP_ADD_v1 */ + } +#else FOR( bandIdx = 0; bandIdx < ( *hBinRenderer )->conv_band; bandIdx++ ) { FOR( chIdx = 0; chIdx < ( *hBinRenderer )->nInChannels; chIdx++ ) @@ -1280,8 +1673,10 @@ static void ivas_binRenderer_convModuleClose_fx( free( hBinRenConvModule->filterStatesLeftImag_fx[bandIdx][chIdx] ); hBinRenConvModule->filterStatesLeftImag_fx[bandIdx][chIdx] = NULL; +#ifndef OPT_BASOP_ADD_v1 free( hBinRenConvModule->Q_filterStatesLeft[bandIdx][chIdx] ); hBinRenConvModule->Q_filterStatesLeft[bandIdx][chIdx] = NULL; +#endif /* OPT_BASOP_ADD_v1 */ } free( hBinRenConvModule->filterStatesLeftReal_fx[bandIdx] ); @@ -1290,18 +1685,22 @@ static void ivas_binRenderer_convModuleClose_fx( free( hBinRenConvModule->filterStatesLeftImag_fx[bandIdx] ); hBinRenConvModule->filterStatesLeftImag_fx[bandIdx] = NULL; +#ifndef OPT_BASOP_ADD_v1 free( hBinRenConvModule->Q_filterStatesLeft[bandIdx] ); hBinRenConvModule->Q_filterStatesLeft[bandIdx] = NULL; +#endif /* OPT_BASOP_ADD_v1 */ } - +#endif free( hBinRenConvModule->filterStatesLeftReal_fx ); hBinRenConvModule->filterStatesLeftReal_fx = NULL; free( hBinRenConvModule->filterStatesLeftImag_fx ); hBinRenConvModule->filterStatesLeftImag_fx = NULL; +#ifndef OPT_BASOP_ADD_v1 free( hBinRenConvModule->Q_filterStatesLeft ); hBinRenConvModule->Q_filterStatesLeft = NULL; +#endif /* OPT_BASOP_ADD_v1 */ free( ( *hBinRenderer )->hBinRenConvModule ); ( *hBinRenderer )->hBinRenConvModule = NULL; @@ -1326,7 +1725,11 @@ void ivas_binRenderer_close_fx( IF( ( *hBinRenderer )->hBinRenConvModule != NULL ) { +#ifdef SPLIT_REND_WITH_HEAD_ROT + ivas_binRenderer_convModuleClose_fx( hBinRenderer, ( *hBinRenderer )->numPoses ); +#else ivas_binRenderer_convModuleClose_fx( hBinRenderer ); +#endif } IF( ( *hBinRenderer )->hReverb != NULL ) @@ -1434,7 +1837,8 @@ void ivas_binaural_add_LFE_fx( Word32 *output_fx[] /* o : synthesized core-coder transport channels/DirAC output Q11*/ ) { - Word16 render_lfe, idx_lfe, gain_fx; + Word16 render_lfe, idx_lfe, gain_fx, idx; + Word32 lfe_tc[L_FRAME48k]; IF( st_ivas->hBinRenderer != NULL ) { @@ -1471,15 +1875,15 @@ void ivas_binaural_add_LFE_fx( } FOR( idx_lfe = 0; idx_lfe < st_ivas->hIntSetup.num_lfe; idx_lfe++ ) { - v_multc_fixed_16( input_fx[st_ivas->hIntSetup.index_lfe[idx_lfe]], gain_fx, input_fx[st_ivas->hIntSetup.index_lfe[idx_lfe]], output_frame ); // q_input_fx - 1 + v_multc_fixed_16( input_fx[st_ivas->hIntSetup.index_lfe[idx_lfe]], gain_fx, lfe_tc, output_frame ); // q_input_fx - 1 /* copy LFE to left and right channels */ - FOR( int idx = 0; idx < output_frame; idx++ ) + FOR( idx = 0; idx < output_frame; idx++ ) { - input_fx[st_ivas->hIntSetup.index_lfe[idx_lfe]][idx] = L_shl_sat( input_fx[st_ivas->hIntSetup.index_lfe[idx_lfe]][idx], 1 ); // saturating to keep same q + lfe_tc[idx] = L_shl_sat( lfe_tc[idx], 1 ); // saturating to keep same q move32(); - output_fx[0][idx] = L_add_sat( output_fx[0][idx], input_fx[st_ivas->hIntSetup.index_lfe[idx_lfe]][idx] ); + output_fx[0][idx] = L_add_sat( output_fx[0][idx], lfe_tc[idx] ); move32(); - output_fx[1][idx] = L_add_sat( output_fx[1][idx], input_fx[st_ivas->hIntSetup.index_lfe[idx_lfe]][idx] ); + output_fx[1][idx] = L_add_sat( output_fx[1][idx], lfe_tc[idx] ); move32(); } } @@ -1489,30 +1893,80 @@ void ivas_binaural_add_LFE_fx( } /*------------------------------------------------------------------------- - * ivas_binRenderer() + * ivas_binRenderer_fx() * * Fastconv binaural renderer main function *-------------------------------------------------------------------------*/ void ivas_binRenderer_fx( - BINAURAL_RENDERER_HANDLE hBinRenderer, /* i/o: binaural renderer handle */ - COMBINED_ORIENTATION_HANDLE hCombinedOrientationData, /* i : combined head and external orientation handle*/ - const Word16 numTimeSlots, /* i : number of time slots to render */ + BINAURAL_RENDERER_HANDLE hBinRenderer, /* i/o: binaural renderer handle */ +#ifdef SPLIT_REND_WITH_HEAD_ROT + const MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, +#endif + COMBINED_ORIENTATION_HANDLE hCombinedOrientationData, /* i : combined head and external orientation handle*/ + const Word16 numTimeSlots, /* i : number of time slots to render */ +#ifdef SPLIT_REND_WITH_HEAD_ROT + Word32 Cldfb_RealBuffer_Binaural_fx[][BINAURAL_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* o : Rotated Binaural signals */ + Word32 Cldfb_ImagBuffer_Binaural_fx[][BINAURAL_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* o : Rotated Binaural signals */ +#else Word32 Cldfb_RealBuffer_Binaural_fx[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* o : Binaural signals Q_in*/ Word32 Cldfb_ImagBuffer_Binaural_fx[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* o : Binaural signals Q_in*/ - Word32 RealBuffer_fx[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* i : LS signals Q_in*/ - Word32 ImagBuffer_fx[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* i : LS signals Q_in*/ - Word16 *Q_in /* i : LS signals exp */ +#endif + Word32 RealBuffer_fx[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* i : LS signals Q_in*/ + Word32 ImagBuffer_fx[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* i : LS signals Q_in*/ + Word16 *Q_in /* i : LS signals exp */ ) { Word16 chIdx, i, j, k; +#ifdef SPLIT_REND_WITH_HEAD_ROT + Word16 pos_idx, num_poses; + Word32 RealBuffer_local[MAX_OUTPUT_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX]; + Word32 ImagBuffer_local[MAX_OUTPUT_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX]; +#endif + // to be checked: feasibility with 32 bit buffers Word64 Cldfb_RealBuffer_Binaural_64fx[BINAURAL_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX]; Word64 Cldfb_ImagBuffer_Binaural_64fx[BINAURAL_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX]; + push_wmops( "fastconv_binaural_rendering" ); +#ifdef SPLIT_REND_WITH_HEAD_ROT + num_poses = hBinRenderer->numPoses; +#endif + /* Compute Convolution */ /* memory reset for the binaural output */ + +#ifdef SPLIT_REND_WITH_HEAD_ROT + FOR( pos_idx = 0; pos_idx < num_poses; pos_idx++ ) + { + FOR( chIdx = 0; chIdx < BINAURAL_CHANNELS; chIdx++ ) + { + FOR( k = 0; k < numTimeSlots; k++ ) + { + set32_fx( Cldfb_RealBuffer_Binaural_fx[pos_idx][chIdx][k], 0, CLDFB_NO_CHANNELS_MAX ); + set32_fx( Cldfb_ImagBuffer_Binaural_fx[pos_idx][chIdx][k], 0, CLDFB_NO_CHANNELS_MAX ); + } + } + } + FOR( chIdx = 0; chIdx < BINAURAL_CHANNELS; chIdx++ ) + { + FOR( k = 0; k < numTimeSlots; k++ ) + { + set64_fx( Cldfb_RealBuffer_Binaural_64fx[chIdx][k], 0, CLDFB_NO_CHANNELS_MAX ); + set64_fx( Cldfb_ImagBuffer_Binaural_64fx[chIdx][k], 0, CLDFB_NO_CHANNELS_MAX ); + } + } + + FOR( chIdx = 0; chIdx < hBinRenderer->hInputSetup->nchan_out_woLFE; chIdx++ ) + { + FOR( k = 0; k < numTimeSlots; k++ ) + { + Copy32( RealBuffer_fx[chIdx][k], RealBuffer_local[chIdx][k], CLDFB_NO_CHANNELS_MAX ); + Copy32( ImagBuffer_fx[chIdx][k], ImagBuffer_local[chIdx][k], CLDFB_NO_CHANNELS_MAX ); + } + } +#else FOR( chIdx = 0; chIdx < BINAURAL_CHANNELS; chIdx++ ) { FOR( k = 0; k < numTimeSlots; k++ ) @@ -1523,6 +1977,7 @@ void ivas_binRenderer_fx( set64_fx( Cldfb_ImagBuffer_Binaural_64fx[chIdx][k], 0, CLDFB_NO_CHANNELS_MAX ); } } +#endif /* Head rotation in HOA3 or CICPx */ test(); @@ -1560,7 +2015,12 @@ void ivas_binRenderer_fx( ivas_sba2mc_cldfb_fixed( *( hBinRenderer->hInputSetup ), RealBuffer_fx, ImagBuffer_fx, hBinRenderer->nInChannels, hBinRenderer->conv_band, numTimeSlots, hBinRenderer->hoa_dec_mtx ); } + +#ifdef SPLIT_REND_WITH_HEAD_ROT + ivas_binRenderer_filterModule_fx( Cldfb_RealBuffer_Binaural_64fx, Cldfb_ImagBuffer_Binaural_64fx, RealBuffer_fx, ImagBuffer_fx, numTimeSlots, hBinRenderer, 0, *Q_in ); +#else ivas_binRenderer_filterModule_fx( Cldfb_RealBuffer_Binaural_64fx, Cldfb_ImagBuffer_Binaural_64fx, RealBuffer_fx, ImagBuffer_fx, numTimeSlots, hBinRenderer, *Q_in ); +#endif FOR( i = 0; i < BINAURAL_CHANNELS; i++ ) { @@ -1568,13 +2028,114 @@ void ivas_binRenderer_fx( { FOR( k = 0; k < CLDFB_NO_CHANNELS_MAX; k++ ) { +#ifdef SPLIT_REND_WITH_HEAD_ROT + Cldfb_RealBuffer_Binaural_fx[0][i][j][k] = W_extract_l( W_shr( Cldfb_RealBuffer_Binaural_64fx[i][j][k], 29 ) ); //(*Q_in + 29) - 29 + move32(); + Cldfb_ImagBuffer_Binaural_fx[0][i][j][k] = W_extract_l( W_shr( Cldfb_ImagBuffer_Binaural_64fx[i][j][k], 29 ) ); //(*Q_in + 29) - 29 + move32(); +#else Cldfb_RealBuffer_Binaural_fx[i][j][k] = W_extract_l( W_shr( Cldfb_RealBuffer_Binaural_64fx[i][j][k], 29 ) ); //(*Q_in + 29) - 29 move32(); Cldfb_ImagBuffer_Binaural_fx[i][j][k] = W_extract_l( W_shr( Cldfb_ImagBuffer_Binaural_64fx[i][j][k], 29 ) ); //(*Q_in + 29) - 29 move32(); +#endif } } } + +#ifdef SPLIT_REND_WITH_HEAD_ROT + IF( pMultiBinPoseData != NULL ) + { + IF( GT_16( pMultiBinPoseData->num_poses, 1 ) ) + { + IVAS_QUATERNION Quaternions_abs, Quaternions_ref, Quaternions_ref2; + Word32 Rmat_local[3][3]; + Word16 q_fact_orig, extra_shift = 0; + + IF( hCombinedOrientationData && hBinRenderer->rotInCldfb ) + { + Quaternions_ref = hCombinedOrientationData->Quaternions[0]; + q_fact_orig = Quaternions_ref.q_fact; + + modify_Quat_q_fx( &Quaternions_ref, &Quaternions_ref, Q22 ); + + Quaternions_ref2.w_fx = L_negate( 12582912 ); // Q22 + IF( EQ_16( hCombinedOrientationData->shd_rot_max_order, 0 ) ) + { + /*HOA signal already rotated by DirAC*/ + Quaternions_ref2.x_fx = 0; + Quaternions_ref2.y_fx = 0; + Quaternions_ref2.z_fx = 0; + extra_shift = 1; + } + ELSE + { + /*euler*/ + Quat2EulerDegree_fx( Quaternions_ref, &Quaternions_ref2.z_fx, &Quaternions_ref2.y_fx, &Quaternions_ref2.x_fx ); /*order in Quat2Euler seems to be reversed ?*/ + } + + FOR( pos_idx = 1; pos_idx < pMultiBinPoseData->num_poses; pos_idx++ ) + { + FOR( chIdx = 0; chIdx < hBinRenderer->hInputSetup->nchan_out_woLFE; chIdx++ ) + { + FOR( k = 0; k < numTimeSlots; k++ ) + { + Copy32( RealBuffer_local[chIdx][k], RealBuffer_fx[chIdx][k], CLDFB_NO_CHANNELS_MAX ); + Copy32( ImagBuffer_local[chIdx][k], ImagBuffer_fx[chIdx][k], CLDFB_NO_CHANNELS_MAX ); + } + } + + Quaternions_abs.x_fx = L_add( Quaternions_ref2.x_fx, pMultiBinPoseData->relative_head_poses_fx[pos_idx][0] ); + Quaternions_abs.y_fx = L_add( Quaternions_ref2.y_fx, pMultiBinPoseData->relative_head_poses_fx[pos_idx][1] ); + Quaternions_abs.z_fx = L_add( Quaternions_ref2.z_fx, pMultiBinPoseData->relative_head_poses_fx[pos_idx][2] ); + Quaternions_abs.w_fx = L_negate( 12582912 ); // Q22 + + Euler2Quat_fx( deg2rad_fx( Quaternions_abs.x_fx ), deg2rad_fx( Quaternions_abs.y_fx ), deg2rad_fx( Quaternions_abs.z_fx ), &Quaternions_abs ); + + modify_Quat_q_fx( &Quaternions_abs, &Quaternions_abs, q_fact_orig ); + + QuatToRotMat_fx( Quaternions_abs, Rmat_local ); + + modify_Rmat_q_fx( Rmat_local, Rmat_local, sub( shl( q_fact_orig, 1 ), 32 ), Q30 ); + + if ( hBinRenderer->hInputSetup->is_loudspeaker_setup ) + { + rotateFrame_sd_cldfb_fixed( Rmat_local, RealBuffer_fx, ImagBuffer_fx, hBinRenderer->hInputSetup, hBinRenderer->hEFAPdata, numTimeSlots, hBinRenderer->conv_band ); + } + else + { + rotateFrame_shd_cldfb( RealBuffer_fx, ImagBuffer_fx, Rmat_local, hBinRenderer->hInputSetup->nchan_out_woLFE, numTimeSlots, 3 ); + } + + FOR( chIdx = 0; chIdx < BINAURAL_CHANNELS; chIdx++ ) + { + FOR( k = 0; k < numTimeSlots; k++ ) + { + set64_fx( Cldfb_RealBuffer_Binaural_64fx[chIdx][k], 0, CLDFB_NO_CHANNELS_MAX ); + set64_fx( Cldfb_ImagBuffer_Binaural_64fx[chIdx][k], 0, CLDFB_NO_CHANNELS_MAX ); + } + } + ivas_binRenderer_filterModule_fx( Cldfb_RealBuffer_Binaural_64fx, Cldfb_ImagBuffer_Binaural_64fx, RealBuffer_fx, ImagBuffer_fx, numTimeSlots, hBinRenderer, pos_idx, *Q_in ); + + FOR( i = 0; i < BINAURAL_CHANNELS; i++ ) + { + FOR( j = 0; j < MAX_PARAM_SPATIAL_SUBFRAMES; j++ ) + { + FOR( k = 0; k < CLDFB_NO_CHANNELS_MAX; k++ ) + { + Cldfb_RealBuffer_Binaural_fx[pos_idx][i][j][k] = W_extract_l( W_shr( Cldfb_RealBuffer_Binaural_64fx[i][j][k], 29 - extra_shift ) ); //(*Q_in + 29) - 29 + move32(); + Cldfb_ImagBuffer_Binaural_fx[pos_idx][i][j][k] = W_extract_l( W_shr( Cldfb_ImagBuffer_Binaural_64fx[i][j][k], 29 - extra_shift ) ); //(*Q_in + 29) - 29 + move32(); + } + } + } + } + } + } + } +#endif + /* Obtain the binaural dmx and compute the reverb */ IF( hBinRenderer->hReverb != NULL ) { @@ -1615,12 +2176,104 @@ void ivas_binRenderer_fx( { FOR( k = 0; k < numTimeSlots; k++ ) { +#ifdef SPLIT_REND_WITH_HEAD_ROT + for ( pos_idx = 0; pos_idx < num_poses; pos_idx++ ) + { + /* Combine first and second parts to generate binaural output signal with room effect */ + v_add_32( Cldfb_RealBuffer_Binaural_fx[pos_idx][chIdx][k], reverbRe_fx[chIdx][k], Cldfb_RealBuffer_Binaural_fx[pos_idx][chIdx][k], hBinRenderer->conv_band ); // Q_in + v_add_32( Cldfb_ImagBuffer_Binaural_fx[pos_idx][chIdx][k], reverbIm_fx[chIdx][k], Cldfb_ImagBuffer_Binaural_fx[pos_idx][chIdx][k], hBinRenderer->conv_band ); // Q_in + } +#else /* Combine first and second parts to generate binaural output signal with room effect */ v_add_32( Cldfb_RealBuffer_Binaural_fx[chIdx][k], reverbRe_fx[chIdx][k], Cldfb_RealBuffer_Binaural_fx[chIdx][k], hBinRenderer->conv_band ); // Q_in v_add_32( Cldfb_ImagBuffer_Binaural_fx[chIdx][k], reverbIm_fx[chIdx][k], Cldfb_ImagBuffer_Binaural_fx[chIdx][k], hBinRenderer->conv_band ); // Q_in +#endif } } } pop_wmops(); return; } + +#ifdef SPLIT_REND_WITH_HEAD_ROT +/*------------------------------------------------------------------------- + * ivas_rend_CldfbMultiBinRendProcess() + * + * + *-------------------------------------------------------------------------*/ + +void ivas_rend_CldfbMultiBinRendProcess( + const BINAURAL_RENDERER_HANDLE hCldfbRend, + const COMBINED_ORIENTATION_HANDLE *pCombinedOrientationData, + const MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, + Word32 Cldfb_In_Real[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + Word32 Cldfb_In_Imag[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + Word32 Cldfb_Out_Real[MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], /* o : Binaural signals */ + Word32 Cldfb_Out_Imag[MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + const Word16 low_res_pre_rend_rot, + const Word16 num_subframes, + const Word16 Q_in /* i : LS signals exp */ +) +{ + int16_t slot_idx, ch_idx, idx, pose_idx, i, j; + int16_t sf_idx; + Word32 Cldfb_RealBuffer_sfIn[MAX_INPUT_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX]; + Word32 Cldfb_ImagBuffer_sfIn[MAX_INPUT_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX]; + Word32 Cldfb_RealBuffer_Binaural[MAX_HEAD_ROT_POSES][BINAURAL_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX]; + Word32 Cldfb_ImagBuffer_Binaural[MAX_HEAD_ROT_POSES][BINAURAL_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX]; + Word16 Q_in_orig; + + FOR( sf_idx = 0; sf_idx < num_subframes; sf_idx++ ) + { + Q_in_orig = Q_in; + move16(); + FOR( slot_idx = 0; slot_idx < MAX_PARAM_SPATIAL_SUBFRAMES; slot_idx++ ) + { + idx = sf_idx * MAX_PARAM_SPATIAL_SUBFRAMES + slot_idx; + FOR( ch_idx = 0; ch_idx < hCldfbRend->nInChannels; ch_idx++ ) + { + Copy32( &Cldfb_In_Real[ch_idx][idx][0], &Cldfb_RealBuffer_sfIn[ch_idx][slot_idx][0], hCldfbRend->max_band ); + Copy32( &Cldfb_In_Imag[ch_idx][idx][0], &Cldfb_ImagBuffer_sfIn[ch_idx][slot_idx][0], hCldfbRend->max_band ); + } + } + + IF( ( *pCombinedOrientationData ) != NULL ) + { + IF( ( low_res_pre_rend_rot ) && ( EQ_32( pMultiBinPoseData->poseCorrectionMode, ISAR_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB ) ) ) + { + Copy_Quat_fx( &( *pCombinedOrientationData )->Quaternions[0], &( *pCombinedOrientationData )->Quaternions[sf_idx] ); + + FOR( i = 0; i < 3; i++ ) + { + FOR( j = 0; j < 3; j++ ) + { + ( *pCombinedOrientationData )->Rmat_fx[sf_idx][i][j] = ( *pCombinedOrientationData )->Rmat_fx[0][i][j]; + move32(); + } + } + } + ( *pCombinedOrientationData )->shd_rot_max_order = -1; + move16(); + } + + ivas_binRenderer_fx( hCldfbRend, pMultiBinPoseData, *pCombinedOrientationData, MAX_PARAM_SPATIAL_SUBFRAMES, Cldfb_RealBuffer_Binaural, Cldfb_ImagBuffer_Binaural, Cldfb_RealBuffer_sfIn, Cldfb_ImagBuffer_sfIn, &Q_in_orig ); + + FOR( pose_idx = 0; pose_idx < hCldfbRend->numPoses; pose_idx++ ) + { + FOR( slot_idx = 0; slot_idx < MAX_PARAM_SPATIAL_SUBFRAMES; slot_idx++ ) + { + idx = sf_idx * MAX_PARAM_SPATIAL_SUBFRAMES + slot_idx; + FOR( ch_idx = 0; ch_idx < BINAURAL_CHANNELS; ch_idx++ ) + { + Copy32( &Cldfb_RealBuffer_Binaural[pose_idx][ch_idx][slot_idx][0], &Cldfb_Out_Real[( pose_idx * BINAURAL_CHANNELS ) + ch_idx][idx][0], hCldfbRend->max_band ); + Copy32( &Cldfb_ImagBuffer_Binaural[pose_idx][ch_idx][slot_idx][0], &Cldfb_Out_Imag[( pose_idx * BINAURAL_CHANNELS ) + ch_idx][idx][0], hCldfbRend->max_band ); + Scale_sig32( &Cldfb_Out_Real[( pose_idx * BINAURAL_CHANNELS ) + ch_idx][idx][0], hCldfbRend->max_band, sub( Q_in, Q_in_orig ) ); // Q_in_orig + Scale_sig32( &Cldfb_Out_Imag[( pose_idx * BINAURAL_CHANNELS ) + ch_idx][idx][0], hCldfbRend->max_band, sub( Q_in, Q_in_orig ) ); // Q_in_orig + } + } + } + } + + return; +} +#endif diff --git a/lib_dec/ivas_core_dec.c b/lib_dec/ivas_core_dec_fx.c similarity index 86% rename from lib_dec/ivas_core_dec.c rename to lib_dec/ivas_core_dec_fx.c index e7708a747520a7675af7f515f362ec4a001d0c8f..7b4e5f267f708713deb5f978ae2764fb9592097d 100644 --- a/lib_dec/ivas_core_dec.c +++ b/lib_dec/ivas_core_dec_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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,12 +36,10 @@ #include #include "cnst.h" #include "rom_com.h" -#include "prot.h" -#include "ivas_prot.h" +#include "prot_fx.h" #include "ivas_prot_fx.h" #include "ivas_rom_com.h" #include "wmc_auto.h" -#include "prot_fx.h" #include "ivas_prot_fx.h" @@ -120,9 +118,7 @@ ivas_error ivas_core_dec_fx( Word16 tdm_lsfQ_PCh_fx[M], tdm_lspQ_PCh_fx[M]; Word32 conceal_eof_gain32; -#ifdef BASOP_NOGLOB Flag Overflow; -#endif error = IVAS_ERR_OK; move32(); @@ -355,7 +351,11 @@ ivas_error ivas_core_dec_fx( Word16 ovl, fade_len; IF( NE_16( sts[0]->L_frame, sts[0]->last_L_frame ) ) { - Copy_Scale_sig_16_32( sts[0]->hHQ_core->old_out_LB_fx, sts[0]->hHQ_core->old_outLB_fx, L_FRAME32k, sub( Q11, sts[0]->hHQ_core->Q_old_wtda_LB ) ); // Q11 +#ifdef FIX_ISSUE_1237 + Copy_Scale_sig_16_32_no_sat( sts[0]->hHQ_core->old_out_LB_fx, sts[0]->hHQ_core->old_outLB_fx, L_FRAME32k, sub( Q11, sts[0]->hHQ_core->Q_old_wtda_LB ) ); // Q11 +#else + Copy_Scale_sig_16_32_DEPREC( sts[0]->hHQ_core->old_out_LB_fx, sts[0]->hHQ_core->old_outLB_fx, L_FRAME32k, sub( Q11, sts[0]->hHQ_core->Q_old_wtda_LB ) ); // Q11 +#endif L_lerp_fx_q11( sts[0]->hHQ_core->old_outLB_fx, sts[0]->hHQ_core->old_outLB_fx, sts[0]->L_frame, sts[0]->last_L_frame ); Copy_Scale_sig_32_16( sts[0]->hHQ_core->old_outLB_fx, sts[0]->hHQ_core->old_out_LB_fx, L_FRAME32k, sub( sts[0]->hHQ_core->Q_old_wtda_LB, Q11 ) ); // Q_old_wtda_LB } @@ -474,7 +474,7 @@ ivas_error ivas_core_dec_fx( move16(); move16(); - Copy_Scale_sig_16_32( st->previoussynth_fx, st->previoussynth_fx_32, L_FRAME48k, 0 ); // Q0 + Copy_Scale_sig_16_32_DEPREC( st->previoussynth_fx, st->previoussynth_fx_32, L_FRAME48k, 0 ); // Q0 IF( NE_32( ( error = core_switching_pre_dec_ivas_fx( st, output_frame, sts[0]->last_core_brate, nchan_out, last_element_mode, last_element_brate, st->Q_syn, &Q_olapBufferSynth, &Q_olapBufferSynth2 ) ), IVAS_ERR_OK ) ) { @@ -548,9 +548,12 @@ ivas_error ivas_core_dec_fx( return error; } } - - Copy_Scale_sig_16_32( output_16_fx[n], output_32_fx[n], L_FRAME48k, sub( Q11, st->Q_syn2 ) ); // Q_syn2->Q11 - Scale_sig( output_16_fx[n], L_FRAME48k, negate( st->Q_syn2 ) ); // Q0 +#ifdef FIX_ISSUE_1237 + Copy_Scale_sig_16_32_no_sat( output_16_fx[n], output_32_fx[n], L_FRAME48k, sub( Q11, st->Q_syn2 ) ); // Q_syn2->Q11 +#else + Copy_Scale_sig_16_32_DEPREC( output_16_fx[n], output_32_fx[n], L_FRAME48k, sub( Q11, st->Q_syn2 ) ); // Q_syn2->Q11 +#endif + Scale_sig( output_16_fx[n], L_FRAME48k, negate( st->Q_syn2 ) ); // Q0 IF( st->cldfbAna ) { scale_sig32( st->cldfbAna->cldfb_state_fx, st->cldfbAna->cldfb_size, Q10 - Q11 ); /* 9 * (Word16)(st->L_frame * FRAMES_PER_SEC * INV_CLDFB_BANDWIDTH + 0.5f) , Q10 */ @@ -569,17 +572,19 @@ ivas_error ivas_core_dec_fx( st->cldfbSyn->Q_cldfb_state = Q11; move16(); } +#ifndef FIX_ISSUE_1279 /* the update of prev_Q_syn is already done inside rescale_mem( ) */ st->prev_Q_syn = st->Q_syn; +#endif move16(); IF( save_hb_synth_32_fx ) { - Copy_Scale_sig_16_32( save_hb_synth_16_fx, save_hb_synth_32_fx, output_frame, Q11 ); // Q11 + Copy_Scale_sig_16_32_DEPREC( save_hb_synth_16_fx, save_hb_synth_32_fx, output_frame, Q11 ); // Q11 hSCE->q_save_hb_synth_fx = Q11; move16(); } - Copy_Scale_sig_16_32( old_syn_12k8_16k_fx_16, old_syn_12k8_16k_fx[n], L_FRAME16k, Q11 - ( -Q1 ) ); // Q(11 - (-1)) + Copy_Scale_sig_16_32_DEPREC( old_syn_12k8_16k_fx_16, old_syn_12k8_16k_fx[n], L_FRAME16k, Q11 - ( -Q1 ) ); // Q(11 - (-1)) } Copy_Scale_sig_32_16( st->previoussynth_fx_32, st->previoussynth_fx, L_FRAME48k, 0 ); // Q0 @@ -636,7 +641,7 @@ ivas_error ivas_core_dec_fx( stereo_tcx_core_dec_fx( st, frameMode[n], output_16_fx[n], synth_16_fx[n], pitch_buf_fx[n], sba_dirac_stereo_flag, hStereoTD, last_element_mode, flag_sec_CNA, hStereoCng, nchan_out, ivas_format ); st->hHQ_core->Q_old_wtda_LB = st->hHQ_core->Q_old_wtda; move16(); - Copy_Scale_sig_16_32( output_16_fx[n], output_32_fx[n], L_FRAME48k, Q11 ); // Q11 + Copy_Scale_sig_16_32_DEPREC( output_16_fx[n], output_32_fx[n], L_FRAME48k, Q11 ); // Q11 IF( st->hTcxDec ) { @@ -663,7 +668,7 @@ ivas_error ivas_core_dec_fx( ivas_hq_core_dec_fx( st, synth_16_fx[n], &Q_synth, output_frame, NORMAL_HQ_CORE, core_switching_flag[n], output_16_fx[n], &Q_output ); - Copy_Scale_sig_16_32( output_16_fx[n], output_32_fx[n], L_FRAME48k, sub( Q11, Q_output ) ); // Q11 + Copy_Scale_sig_16_32_DEPREC( output_16_fx[n], output_32_fx[n], L_FRAME48k, sub( Q11, Q_output ) ); // Q11 #ifdef MSAN_FIX Scale_sig( synth_16_fx[n], output_frame, negate( Q_synth ) ); // Q0 #else @@ -683,8 +688,11 @@ ivas_error ivas_core_dec_fx( td_stereo_param_updt_fx( st->lsp_old_fx, st->lsf_old_fx, st->old_pitch_buf_16_fx + st->nb_subfr, tdm_lspQ_PCh_fx, tdm_lsfQ_PCh_fx, hStereoTD->tdm_Pri_pitch_buf_fx, st->flag_ACELP16k, hStereoTD->tdm_use_IAWB_Ave_lpc ); - - Copy_Scale_sig_16_32( hCPE->hCoreCoder[0]->old_pitch_buf_16_fx, hCPE->hCoreCoder[0]->old_pitch_buf_fx, add( imult1616( 2, NB_SUBFR16k ), 2 ), Q10 ); // Q16 +#ifdef FIX_ISSUE_1237 + Copy_Scale_sig_16_32_no_sat( hCPE->hCoreCoder[0]->old_pitch_buf_16_fx, hCPE->hCoreCoder[0]->old_pitch_buf_fx, add( imult1616( 2, NB_SUBFR16k ), 2 ), Q10 ); // Q16 +#else + Copy_Scale_sig_16_32_DEPREC( hCPE->hCoreCoder[0]->old_pitch_buf_16_fx, hCPE->hCoreCoder[0]->old_pitch_buf_fx, add( imult1616( 2, NB_SUBFR16k ), 2 ), Q10 ); // Q16 +#endif } } /* n_channels loop */ @@ -772,6 +780,7 @@ ivas_error ivas_core_dec_fx( /* for inactive frames with mono output, copy and (if necessary) downmix buffers */ ELSE IF( EQ_16( hCPE->nchan_out, 1 ) ) { + Word16 shift1, shift2; sts[0] = hCPE->hCoreCoder[0]; sts[1] = hCPE->hCoreCoder[1]; @@ -790,6 +799,15 @@ ivas_error ivas_core_dec_fx( move16(); sts[1]->hHQ_core->Q_old_wtda = sub( 15, sts[1]->hHQ_core->exp_old_out ); move16(); + + shift1 = norm_arr( sts[0]->hHQ_core->old_out_fx, L_FRAME48k ); + shift2 = norm_arr( sts[1]->hHQ_core->old_out_fx, L_FRAME48k ); + scale_sig( sts[0]->hHQ_core->old_out_fx, L_FRAME48k, shift1 ); + scale_sig( sts[1]->hHQ_core->old_out_fx, L_FRAME48k, shift2 ); + sts[0]->hHQ_core->Q_old_wtda = add( sts[0]->hHQ_core->Q_old_wtda, shift1 ); + sts[1]->hHQ_core->Q_old_wtda = add( sts[1]->hHQ_core->Q_old_wtda, shift2 ); + move16(); + move16(); } } @@ -915,11 +933,19 @@ ivas_error ivas_core_dec_fx( /* Memories Re-Scaling */ IF( st->hBWE_TD != NULL ) { - Copy_Scale_sig_16_32( st->hBWE_TD->syn_overlap_fx, st->hBWE_TD->syn_overlap_fx_32, L_SHB_LAHEAD, sub( Q11, st->prev_Q_bwe_syn2 ) ); // Q11 - Copy_Scale_sig_16_32( st->hBWE_TD->old_tbe_synth_fx, st->hBWE_TD->old_tbe_synth_fx_32, L_SHB_TRANSITION_LENGTH, sub( Q11, st->prev_Qx ) ); // Q11 - Copy_Scale_sig_16_32( st->hBWE_TD->state_lsyn_filt_dwn_shb_fx, st->hBWE_TD->state_lsyn_filt_dwn_shb_fx_32, ALLPASSSECTIONS_STEEP * 2, sub( Q11, st->prev_Qx ) ); // Q11 - Copy_Scale_sig_16_32( st->hBWE_TD->state_lsyn_filt_shb_fx, st->hBWE_TD->state_lsyn_filt_shb_fx_32, ALLPASSSECTIONS_STEEP * 2, sub( Q11, st->prev_Qx ) ); // Q11 - Copy_Scale_sig_16_32( st->hBWE_TD->mem_resamp_HB_fx, st->hBWE_TD->mem_resamp_HB_fx_32, INTERP_3_1_MEM_LEN, sub( Q11, st->prev_Qx ) ); // Q11 +#ifdef FIX_ISSUE_1237 + Copy_Scale_sig_16_32_no_sat( st->hBWE_TD->syn_overlap_fx, st->hBWE_TD->syn_overlap_fx_32, L_SHB_LAHEAD, sub( Q11, st->prev_Q_bwe_syn2 ) ); // Q11 + Copy_Scale_sig_16_32_no_sat( st->hBWE_TD->old_tbe_synth_fx, st->hBWE_TD->old_tbe_synth_fx_32, L_SHB_TRANSITION_LENGTH, sub( Q11, st->prev_Qx ) ); // Q11 + Copy_Scale_sig_16_32_no_sat( st->hBWE_TD->state_lsyn_filt_dwn_shb_fx, st->hBWE_TD->state_lsyn_filt_dwn_shb_fx_32, ALLPASSSECTIONS_STEEP * 2, sub( Q11, st->prev_Qx ) ); // Q11 + Copy_Scale_sig_16_32_no_sat( st->hBWE_TD->state_lsyn_filt_shb_fx, st->hBWE_TD->state_lsyn_filt_shb_fx_32, ALLPASSSECTIONS_STEEP * 2, sub( Q11, st->prev_Qx ) ); // Q11 + Copy_Scale_sig_16_32_no_sat( st->hBWE_TD->mem_resamp_HB_fx, st->hBWE_TD->mem_resamp_HB_fx_32, INTERP_3_1_MEM_LEN, sub( Q11, st->prev_Qx ) ); // Q11 +#else + Copy_Scale_sig_16_32_DEPREC( st->hBWE_TD->syn_overlap_fx, st->hBWE_TD->syn_overlap_fx_32, L_SHB_LAHEAD, sub( Q11, st->prev_Q_bwe_syn2 ) ); // Q11 + Copy_Scale_sig_16_32_DEPREC( st->hBWE_TD->old_tbe_synth_fx, st->hBWE_TD->old_tbe_synth_fx_32, L_SHB_TRANSITION_LENGTH, sub( Q11, st->prev_Qx ) ); // Q11 + Copy_Scale_sig_16_32_DEPREC( st->hBWE_TD->state_lsyn_filt_dwn_shb_fx, st->hBWE_TD->state_lsyn_filt_dwn_shb_fx_32, ALLPASSSECTIONS_STEEP * 2, sub( Q11, st->prev_Qx ) ); // Q11 + Copy_Scale_sig_16_32_DEPREC( st->hBWE_TD->state_lsyn_filt_shb_fx, st->hBWE_TD->state_lsyn_filt_shb_fx_32, ALLPASSSECTIONS_STEEP * 2, sub( Q11, st->prev_Qx ) ); // Q11 + Copy_Scale_sig_16_32_DEPREC( st->hBWE_TD->mem_resamp_HB_fx, st->hBWE_TD->mem_resamp_HB_fx_32, INTERP_3_1_MEM_LEN, sub( Q11, st->prev_Qx ) ); // Q11 +#endif Copy( st->hBWE_TD->mem_resamp_HB_fx, st->hBWE_TD->state_32and48k_WB_upsample_fx, ( 2 * ALLPASSSECTIONS_STEEP ) ); } /*---------------------------------------------------------------------* @@ -932,7 +958,11 @@ ivas_error ivas_core_dec_fx( test(); IF( sba_dirac_stereo_flag && NE_16( st->element_mode, IVAS_CPE_MDCT ) && !( EQ_32( st->core_brate, SID_2k40 ) && EQ_16( st->cng_type, FD_CNG ) ) ) { - Copy_Scale_sig_16_32( synth_16_fx[n], hSCE->save_synth_fx, output_frame, sub( hSCE->q_save_synth_fx, Q_synth ) ); // q_save_synth_fx +#ifdef FIX_ISSUE_1237 + Copy_Scale_sig_16_32_no_sat( synth_16_fx[n], hSCE->save_synth_fx, output_frame, sub( hSCE->q_save_synth_fx, Q_synth ) ); // q_save_synth_fx +#else + Copy_Scale_sig_16_32_DEPREC( synth_16_fx[n], hSCE->save_synth_fx, output_frame, sub( hSCE->q_save_synth_fx, Q_synth ) ); // q_save_synth_fx +#endif } IVAS_FORMAT ivas_format; @@ -967,7 +997,11 @@ ivas_error ivas_core_dec_fx( test(); IF( sba_dirac_stereo_flag && hSCE && EQ_32( st->core_brate, SID_2k40 ) && EQ_16( st->cng_type, FD_CNG ) ) { - Copy_Scale_sig_16_32( synth_16_fx[n], hSCE->save_synth_fx, output_frame, sub( hSCE->q_save_synth_fx, Q_synth ) ); // q_save_synth_fx +#ifdef FIX_ISSUE_1237 + Copy_Scale_sig_16_32_no_sat( synth_16_fx[n], hSCE->save_synth_fx, output_frame, sub( hSCE->q_save_synth_fx, Q_synth ) ); // q_save_synth_fx +#else + Copy_Scale_sig_16_32_DEPREC( synth_16_fx[n], hSCE->save_synth_fx, output_frame, sub( hSCE->q_save_synth_fx, Q_synth ) ); // q_save_synth_fx +#endif } /* if we transition from inactive to active coding in MDCT-Stereo DTX and the output format is mono DMX, we need to sync the upsampled buffer between channels here */ @@ -989,11 +1023,15 @@ ivas_error ivas_core_dec_fx( IF( st->hHQ_core == NULL ) { - Copy_Scale_sig_16_32( st->delay_buf_out_fx, st->delay_buf_out32_fx, ( HQ_DELTA_MAX * HQ_DELAY_COMP ), Q11 ); // Q11 + Copy_Scale_sig_16_32_DEPREC( st->delay_buf_out_fx, st->delay_buf_out32_fx, ( HQ_DELTA_MAX * HQ_DELAY_COMP ), Q11 ); // Q11 } ELSE { - Copy_Scale_sig_16_32( st->delay_buf_out_fx, st->delay_buf_out32_fx, ( HQ_DELTA_MAX * HQ_DELAY_COMP ), sub( Q11, st->hHQ_core->Q_old_postdec ) ); // Q11 +#ifdef FIX_ISSUE_1237 + Copy_Scale_sig_16_32_no_sat( st->delay_buf_out_fx, st->delay_buf_out32_fx, ( HQ_DELTA_MAX * HQ_DELAY_COMP ), sub( Q11, st->hHQ_core->Q_old_postdec ) ); // Q11 +#else + Copy_Scale_sig_16_32_DEPREC( st->delay_buf_out_fx, st->delay_buf_out32_fx, ( HQ_DELTA_MAX * HQ_DELAY_COMP ), sub( Q11, st->hHQ_core->Q_old_postdec ) ); // Q11 +#endif } Scale_sig32( output_32_fx[n], L_FRAME48k, ( Q11 - Q4 ) ); // Q11 @@ -1085,17 +1123,31 @@ ivas_error ivas_core_dec_fx( } /* Memories Re-Scaling */ - Copy_Scale_sig_16_32( hb_synth_16_fx[n], hb_synth_32_fx[n], L_FRAME48k, sub( Q11, Q_hb_synth_fx ) ); // Q11 - Copy_Scale_sig_16_32( output_16_fx[n], output_32_fx[n], L_FRAME48k, sub( Q11, Q_input ) ); // Q11 - Copy_Scale_sig_16_32( synth_16_fx[n], synth_32_fx[n], L_FRAME48k, sub( Q11, Q_synth_fx ) ); // Q11 +#ifdef FIX_ISSUE_1237 + Copy_Scale_sig_16_32_no_sat( hb_synth_16_fx[n], hb_synth_32_fx[n], L_FRAME48k, sub( Q11, Q_hb_synth_fx ) ); // Q11 + Copy_Scale_sig_16_32_no_sat( output_16_fx[n], output_32_fx[n], L_FRAME48k, sub( Q11, Q_input ) ); // Q11 // Q_input can get value <= -5 + Copy_Scale_sig_16_32_no_sat( synth_16_fx[n], synth_32_fx[n], L_FRAME48k, sub( Q11, Q_synth_fx ) ); // Q11 +#else + Copy_Scale_sig_16_32_DEPREC( hb_synth_16_fx[n], hb_synth_32_fx[n], L_FRAME48k, sub( Q11, Q_hb_synth_fx ) ); // Q11 + Copy_Scale_sig_16_32_DEPREC( output_16_fx[n], output_32_fx[n], L_FRAME48k, sub( Q11, Q_input ) ); // Q11 + Copy_Scale_sig_16_32_DEPREC( synth_16_fx[n], synth_32_fx[n], L_FRAME48k, sub( Q11, Q_synth_fx ) ); // Q11 +#endif IF( hBWE_FD != NULL ) { - Copy_Scale_sig_16_32( hBWE_FD->L_old_wtda_swb_fx, hBWE_FD->L_old_wtda_swb_fx32, L_FRAME48k, sub( Q11, hBWE_FD->old_wtda_swb_fx_exp ) ); // Q11 +#ifdef FIX_ISSUE_1237 + Copy_Scale_sig_16_32_no_sat( hBWE_FD->L_old_wtda_swb_fx, hBWE_FD->L_old_wtda_swb_fx32, L_FRAME48k, sub( Q11, hBWE_FD->old_wtda_swb_fx_exp ) ); // Q11 +#else + Copy_Scale_sig_16_32_DEPREC( hBWE_FD->L_old_wtda_swb_fx, hBWE_FD->L_old_wtda_swb_fx32, L_FRAME48k, sub( Q11, hBWE_FD->old_wtda_swb_fx_exp ) ); // Q11 +#endif } IF( st->hBWE_TD != NULL ) { - Copy_Scale_sig_16_32( st->hBWE_TD->old_tbe_synth_fx, st->hBWE_TD->old_tbe_synth_fx_32, L_SHB_TRANSITION_LENGTH, sub( Q11, st->prev_Qx ) ); // Q11 +#ifdef FIX_ISSUE_1237 + Copy_Scale_sig_16_32_no_sat( st->hBWE_TD->old_tbe_synth_fx, st->hBWE_TD->old_tbe_synth_fx_32, L_SHB_TRANSITION_LENGTH, sub( Q11, st->prev_Qx ) ); // Q11 +#else + Copy_Scale_sig_16_32_DEPREC( st->hBWE_TD->old_tbe_synth_fx, st->hBWE_TD->old_tbe_synth_fx_32, L_SHB_TRANSITION_LENGTH, sub( Q11, st->prev_Qx ) ); // Q11 +#endif } /*---------------------------------------------------------------------* @@ -1175,11 +1227,7 @@ ivas_error ivas_core_dec_fx( { hb_synth_32_fx[n][i] = Mpy_32_16_1( hb_synth_32_fx[n][i], tmp16_2 ); /* Q11 */ move32(); -#ifdef BASOP_NOGLOB tmp16_2 = add_o( tmp16_2, tmp16, &Overflow ); /* Q15 */ -#else - tmp16_2 = add( tmp16_2, tmp16 ); -#endif } } @@ -1213,7 +1261,7 @@ ivas_error ivas_core_dec_fx( test(); IF( st->core_brate == FRAME_NO_DATA || EQ_32( st->core_brate, SID_2k40 ) ) { - Copy_Scale_sig_16_32( hb_synth_16_fx[n], hb_synth_32_fx[n], L_FRAME48k, ( Q11 ) ); // Q11 + Copy_Scale_sig_16_32_DEPREC( hb_synth_16_fx[n], hb_synth_32_fx[n], L_FRAME48k, ( Q11 ) ); // Q11 } Scale_sig( st->hBWE_TD->state_lpc_syn_fx, LPC_SHB_ORDER, negate( sub( Q8, st->prev_Q_bwe_syn ) ) ); // Q0 @@ -1399,7 +1447,7 @@ ivas_error ivas_core_dec_fx( /* Delay hb_synth */ Word32 hb_prev_synth_buffer_fx_32[111]; - Copy_Scale_sig_16_32( st->hb_prev_synth_buffer_fx, hb_prev_synth_buffer_fx_32, 111, 11 ); // Q11 + Copy_Scale_sig_16_32_DEPREC( st->hb_prev_synth_buffer_fx, hb_prev_synth_buffer_fx_32, 111, 11 ); // Q11 delay_signal_fx( hb_synth_32_fx[n], output_frame, hb_prev_synth_buffer_fx_32, tmps ); Copy_Scale_sig_32_16( hb_prev_synth_buffer_fx_32, st->hb_prev_synth_buffer_fx, 111, -( 11 ) ); // Q0 } @@ -1484,8 +1532,14 @@ ivas_error ivas_core_dec_fx( { IF( hCPE->hCoreCoder[ch_ind]->hHQ_core != NULL ) { - Copy_Scale_sig_16_32( hCPE->hCoreCoder[ch_ind]->hHQ_core->old_out_LB_fx, hCPE->hCoreCoder[ch_ind]->hHQ_core->old_outLB_fx, L_FRAME32k, sub( Q11, hCPE->hCoreCoder[ch_ind]->hHQ_core->Q_old_wtda_LB ) ); // Q11 - Copy_Scale_sig_16_32( hCPE->hCoreCoder[ch_ind]->hHQ_core->old_out_fx, hCPE->hCoreCoder[ch_ind]->hHQ_core->oldOut_fx, L_FRAME48k, sub( Q11, hCPE->hCoreCoder[ch_ind]->hHQ_core->Q_old_wtda ) ); // Q11 +#ifdef FIX_ISSUE_1237 + Copy_Scale_sig_16_32_no_sat( hCPE->hCoreCoder[ch_ind]->hHQ_core->old_out_LB_fx, hCPE->hCoreCoder[ch_ind]->hHQ_core->old_outLB_fx, L_FRAME32k, sub( Q11, hCPE->hCoreCoder[ch_ind]->hHQ_core->Q_old_wtda_LB ) ); // Q11 + Copy_Scale_sig_16_32_no_sat( hCPE->hCoreCoder[ch_ind]->hHQ_core->old_out_fx, hCPE->hCoreCoder[ch_ind]->hHQ_core->oldOut_fx, L_FRAME48k, sub( Q11, hCPE->hCoreCoder[ch_ind]->hHQ_core->Q_old_wtda ) ); // Q11 + +#else + Copy_Scale_sig_16_32_DEPREC( hCPE->hCoreCoder[ch_ind]->hHQ_core->old_out_LB_fx, hCPE->hCoreCoder[ch_ind]->hHQ_core->old_outLB_fx, L_FRAME32k, sub( Q11, hCPE->hCoreCoder[ch_ind]->hHQ_core->Q_old_wtda_LB ) ); // Q11 + Copy_Scale_sig_16_32_DEPREC( hCPE->hCoreCoder[ch_ind]->hHQ_core->old_out_fx, hCPE->hCoreCoder[ch_ind]->hHQ_core->oldOut_fx, L_FRAME48k, sub( Q11, hCPE->hCoreCoder[ch_ind]->hHQ_core->Q_old_wtda ) ); // Q11 +#endif } } } @@ -1496,8 +1550,13 @@ ivas_error ivas_core_dec_fx( { IF( hSCE->hCoreCoder[0]->hHQ_core != NULL ) { - Copy_Scale_sig_16_32( hSCE->hCoreCoder[0]->hHQ_core->old_out_LB_fx, hSCE->hCoreCoder[0]->hHQ_core->old_outLB_fx, L_FRAME32k, sub( Q11, hSCE->hCoreCoder[0]->hHQ_core->Q_old_wtda_LB ) ); // Q11 - Copy_Scale_sig_16_32( hSCE->hCoreCoder[0]->hHQ_core->old_out_fx, hSCE->hCoreCoder[0]->hHQ_core->oldOut_fx, L_FRAME48k, sub( Q11, hSCE->hCoreCoder[0]->hHQ_core->Q_old_wtda ) ); // Q11 +#ifdef FIX_ISSUE_1237 + Copy_Scale_sig_16_32_no_sat( hSCE->hCoreCoder[0]->hHQ_core->old_out_LB_fx, hSCE->hCoreCoder[0]->hHQ_core->old_outLB_fx, L_FRAME32k, sub( Q11, hSCE->hCoreCoder[0]->hHQ_core->Q_old_wtda_LB ) ); // Q11 + Copy_Scale_sig_16_32_no_sat( hSCE->hCoreCoder[0]->hHQ_core->old_out_fx, hSCE->hCoreCoder[0]->hHQ_core->oldOut_fx, L_FRAME48k, sub( Q11, hSCE->hCoreCoder[0]->hHQ_core->Q_old_wtda ) ); // Q11 +#else + Copy_Scale_sig_16_32_DEPREC( hSCE->hCoreCoder[0]->hHQ_core->old_out_LB_fx, hSCE->hCoreCoder[0]->hHQ_core->old_outLB_fx, L_FRAME32k, sub( Q11, hSCE->hCoreCoder[0]->hHQ_core->Q_old_wtda_LB ) ); // Q11 + Copy_Scale_sig_16_32_DEPREC( hSCE->hCoreCoder[0]->hHQ_core->old_out_fx, hSCE->hCoreCoder[0]->hHQ_core->oldOut_fx, L_FRAME48k, sub( Q11, hSCE->hCoreCoder[0]->hHQ_core->Q_old_wtda ) ); // Q11 +#endif } } } @@ -1578,15 +1637,15 @@ ivas_error ivas_core_dec_fx( move16(); move16(); - Copy_Scale_sig32_16( st->prev_synth_buffer32_fx, st->prev_synth_buffer_fx, NS2SA_FX2( 48000, DELAY_BWE_TOTAL_NS - DELAY_CLDFB_NS ), -( Q11 ) ); // Q0 + Copy_Scale_sig32_16( st->prev_synth_buffer32_fx, st->prev_synth_buffer_fx, NS2SA( 48000, DELAY_BWE_TOTAL_NS - DELAY_CLDFB_NS ), -( Q11 ) ); // Q0 st->q_prev_synth_buffer_fx = 0; move16(); exp_ouput = Find_Max_Norm32( output_32_fx[n], output_frame ); exp_ouput = add( exp_ouput, Q11 ); - exp_prev_synth_buffer = Find_Max_Norm16( st->prev_synth_buffer_fx, NS2SA_FX2( 48000, DELAY_BWE_TOTAL_NS - DELAY_CLDFB_NS ) ); + exp_prev_synth_buffer = Find_Max_Norm16( st->prev_synth_buffer_fx, NS2SA( 48000, DELAY_BWE_TOTAL_NS - DELAY_CLDFB_NS ) ); exp_prev_synth_buffer = add( exp_prev_synth_buffer, st->q_prev_synth_buffer_fx ); - exp_old_out = Find_Max_Norm16( st->hHQ_core->old_out_fx + NS2SA_FX2( st->output_Fs, N_ZERO_MDCT_NS ), sub( add( NS2SA_FX2( st->output_Fs, N_ZERO_MDCT_NS ), NS2SA_FX2( st->output_Fs, PH_ECU_LOOKAHEAD_NS ) ), NS2SA( st->output_Fs, N_ZERO_MDCT_NS ) ) ); + exp_old_out = Find_Max_Norm16( st->hHQ_core->old_out_fx + NS2SA_FX2( st->output_Fs, N_ZERO_MDCT_NS ), sub( add( NS2SA_FX2( st->output_Fs, N_ZERO_MDCT_NS ), NS2SA_FX2( st->output_Fs, PH_ECU_LOOKAHEAD_NS ) ), NS2SA_FX2( st->output_Fs, N_ZERO_MDCT_NS ) ) ); exp_delay_buf_out = Find_Max_Norm16( st->delay_buf_out_fx, NS2SA_FX2( st->output_Fs, DELAY_CLDFB_NS ) ); exp_synth_history = Find_Max_Norm16( st->hTcxDec->synth_history_fx + output_frame, sub( add( sub( imult1616( 2, output_frame ), NS2SA_FX2( st->output_Fs, DELAY_CLDFB_NS ) ), NS2SA_FX2( st->output_Fs, PH_ECU_MEM_NS ) ), output_frame ) ); exp_max = s_min( exp_synth_history, exp_ouput ); @@ -1599,7 +1658,7 @@ ivas_error ivas_core_dec_fx( Scale_sig32( output_fx_loc, output_frame, sub( exp_max, Q11 ) ); // Q(31-exp_max) Scale_sig( st->delay_buf_out_fx, NS2SA_FX2( st->output_Fs, DELAY_CLDFB_NS ), exp_max ); // exp_max Scale_sig( st->hHQ_core->old_out_fx + NS2SA_FX2( st->output_Fs, N_ZERO_MDCT_NS ), sub( NS2SA_FX2( st->output_Fs, PH_ECU_LOOKAHEAD_NS ), NS2SA_FX2( st->output_Fs, N_ZERO_MDCT_NS ) ), exp_max ); // Q(31-exp_max) - Scale_sig( st->prev_synth_buffer_fx, NS2SA_FX2( 48000, L_sub( DELAY_BWE_TOTAL_NS, DELAY_CLDFB_NS ) ), sub( exp_max, st->q_prev_synth_buffer_fx ) ); // Q(exp_max - prev_synth_buffer_fx) + Scale_sig( st->prev_synth_buffer_fx, NS2SA_FX2( 48000, DELAY_BWE_TOTAL_NS - DELAY_CLDFB_NS ), sub( exp_max, st->q_prev_synth_buffer_fx ) ); // Q(exp_max - prev_synth_buffer_fx) Scale_sig( st->hTcxDec->synth_history_fx + output_frame, sub( add( sub( imult1616( 2, output_frame ), NS2SA_FX2( st->output_Fs, DELAY_CLDFB_NS ) ), NS2SA_FX2( st->output_Fs, PH_ECU_MEM_NS ) ), output_frame ), sub( exp_max, 0 ) ); // Q(31-exp_max) st->q_prev_synth_buffer_fx = sub( exp_max, st->q_prev_synth_buffer_fx ); diff --git a/lib_dec/ivas_corecoder_dec_reconfig.c b/lib_dec/ivas_corecoder_dec_reconfig_fx.c similarity index 99% rename from lib_dec/ivas_corecoder_dec_reconfig.c rename to lib_dec/ivas_corecoder_dec_reconfig_fx.c index 56a45ddb077dba581ccda198ec360212e4632772..8333f146f594a61de657bee9e9b066119b14e694 100644 --- a/lib_dec/ivas_corecoder_dec_reconfig.c +++ b/lib_dec/ivas_corecoder_dec_reconfig_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other @@ -32,10 +32,8 @@ #include "options.h" #include "ivas_cnst.h" -#include "ivas_prot.h" #include "ivas_prot_fx.h" #include "prot_fx.h" -#include "prot.h" #include #include "wmc_auto.h" @@ -604,7 +602,7 @@ ivas_error ivas_cldfb_dec_reconfig_fx( /* create additional CLDFB synthesis instances */ FOR( i = numCldfbAnalyses_old; i < numCldfbAnalyses; i++ ) { - IF( NE_32( ( error = openCldfb_ivas_fx( &( st_ivas->cldfbAnaDec[i] ), CLDFB_ANALYSIS, hDecoderConfig->output_Fs, CLDFB_PROTOTYPE_5_00MS ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &( st_ivas->cldfbAnaDec[i] ), CLDFB_ANALYSIS, hDecoderConfig->output_Fs, CLDFB_PROTOTYPE_5_00MS, DEC ) ), IVAS_ERR_OK ) ) { return error; } @@ -624,7 +622,7 @@ ivas_error ivas_cldfb_dec_reconfig_fx( /* create additional CLDFB synthesis instances */ FOR( i = numCldfbSyntheses_old; i < numCldfbSyntheses; i++ ) { - IF( NE_32( ( error = openCldfb_ivas_fx( &( st_ivas->cldfbSynDec[i] ), CLDFB_SYNTHESIS, hDecoderConfig->output_Fs, CLDFB_PROTOTYPE_5_00MS ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &( st_ivas->cldfbSynDec[i] ), CLDFB_SYNTHESIS, hDecoderConfig->output_Fs, CLDFB_PROTOTYPE_5_00MS, DEC ) ), IVAS_ERR_OK ) ) { return error; } diff --git a/lib_dec/ivas_cpe_dec.c b/lib_dec/ivas_cpe_dec.c deleted file mode 100644 index bc61a3baa666ffbc8bee8db1abaadc283878cd21..0000000000000000000000000000000000000000 --- a/lib_dec/ivas_cpe_dec.c +++ /dev/null @@ -1,69 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -#include -#include -#include "options.h" -#include "cnst.h" -#include "ivas_cnst.h" -#include "rom_com.h" -#include "prot.h" -#include "ivas_prot.h" -#include "prot_fx.h" -#include "ivas_rom_com.h" -#include "wmc_auto.h" -#include - - -/*--------------------------------------------------------------------------* - * Local function prototypes - *--------------------------------------------------------------------------*/ - - -/*--------------------------------------------------------------------------* - * ivas_cpe_dec() - * - * Channel Pair Element (CPE) decoding routine - *--------------------------------------------------------------------------*/ - -/*------------------------------------------------------------------------- - * read_stereo_mode_and_bwidth() - * - * Read stereo technology info & audio bandwidth - *-------------------------------------------------------------------------*/ - - -/*------------------------------------------------------------------------- - * stereo_mode_combined_format_dec() - * - * Set stereo format in a combined format - *-------------------------------------------------------------------------*/ diff --git a/lib_dec/ivas_cpe_dec_fx.c b/lib_dec/ivas_cpe_dec_fx.c index d8ebe8d4b1f8bd7e306eb97b2c9e7ffab2cc82fb..9e934cc888f116b241496c89510ac9ef449123d1 100644 --- a/lib_dec/ivas_cpe_dec_fx.c +++ b/lib_dec/ivas_cpe_dec_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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,10 +36,8 @@ #include "cnst.h" #include "ivas_cnst.h" #include "rom_com.h" -#include "prot.h" -#include "ivas_prot.h" -#include "ivas_prot_fx.h" #include "prot_fx.h" +#include "ivas_prot_fx.h" #include "ivas_rom_com.h" #include "wmc_auto.h" #include @@ -126,14 +124,22 @@ ivas_error ivas_cpe_dec_fx( test(); IF( hCPE->hCoreCoder[ind1] && hCPE->hCoreCoder[ind1]->hHQ_core ) { - Copy_Scale_sig_16_32( hCPE->hCoreCoder[ind1]->hHQ_core->old_out_fx, hCPE->hCoreCoder[ind1]->hHQ_core->oldOut_fx, L_FRAME48k, sub( Q11, hCPE->hCoreCoder[ind1]->hHQ_core->Q_old_wtda ) ); // Q11 +#ifdef FIX_ISSUE_1237 + Copy_Scale_sig_16_32_no_sat( hCPE->hCoreCoder[ind1]->hHQ_core->old_out_fx, hCPE->hCoreCoder[ind1]->hHQ_core->oldOut_fx, L_FRAME48k, sub( Q11, hCPE->hCoreCoder[ind1]->hHQ_core->Q_old_wtda ) ); // Q11 +#else + Copy_Scale_sig_16_32_DEPREC( hCPE->hCoreCoder[ind1]->hHQ_core->old_out_fx, hCPE->hCoreCoder[ind1]->hHQ_core->oldOut_fx, L_FRAME48k, sub( Q11, hCPE->hCoreCoder[ind1]->hHQ_core->Q_old_wtda ) ); // Q11 +#endif } } FOR( Word16 ind1 = 0; ind1 < 2; ind1++ ) { IF( hCPE->hCoreCoder[ind1]->hHQ_core ) { - Copy_Scale_sig_16_32( hCPE->hCoreCoder[ind1]->hHQ_core->old_out_LB_fx, hCPE->hCoreCoder[ind1]->hHQ_core->old_outLB_fx, L_FRAME32k, sub( Q11, hCPE->hCoreCoder[ind1]->hHQ_core->Q_old_wtda_LB ) ); // Q11 +#ifdef FIX_ISSUE_1237 + Copy_Scale_sig_16_32_no_sat( hCPE->hCoreCoder[ind1]->hHQ_core->old_out_LB_fx, hCPE->hCoreCoder[ind1]->hHQ_core->old_outLB_fx, L_FRAME32k, sub( Q11, hCPE->hCoreCoder[ind1]->hHQ_core->Q_old_wtda_LB ) ); // Q11 +#else + Copy_Scale_sig_16_32_DEPREC( hCPE->hCoreCoder[ind1]->hHQ_core->old_out_LB_fx, hCPE->hCoreCoder[ind1]->hHQ_core->old_outLB_fx, L_FRAME32k, sub( Q11, hCPE->hCoreCoder[ind1]->hHQ_core->Q_old_wtda_LB ) ); // Q11 +#endif hCPE->hCoreCoder[ind1]->hHQ_core->q_old_outLB_fx = Q11; move16(); } @@ -680,7 +686,7 @@ ivas_error ivas_cpe_dec_fx( stereo_dft_dec_res_fx( hCPE, res_buf_fx, q_res_buf, output[1] ); - Copy_Scale_sig_16_32( hCPE->hCoreCoder[0]->old_pitch_buf_16_fx, hCPE->hCoreCoder[0]->old_pitch_buf_fx, ( ( 2 * NB_SUBFR16k ) + 2 ), 10 ); // Q6->Q16 + Copy_Scale_sig_16_32_DEPREC( hCPE->hCoreCoder[0]->old_pitch_buf_16_fx, hCPE->hCoreCoder[0]->old_pitch_buf_fx, ( ( 2 * NB_SUBFR16k ) + 2 ), 10 ); // Q6->Q16 Scale_sig32( output[1], L_FRAME8k, ( Q11 - Q15 ) ); // Q15 -> Q11 diff --git a/lib_dec/ivas_dec.c b/lib_dec/ivas_dec.c deleted file mode 100644 index 70d0a21a7c77e1f8eee6f84506b56355b8b88c2b..0000000000000000000000000000000000000000 --- a/lib_dec/ivas_dec.c +++ /dev/null @@ -1,49 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -#include -#include "options.h" -#include "cnst.h" -#include "ivas_cnst.h" -#include "rom_com.h" -#include "prot.h" -#include "ivas_prot.h" -#include "ivas_prot_rend.h" -#include "ivas_rom_com.h" -#include "wmc_auto.h" - - -/*--------------------------------------------------------------------------* - * ivas_dec() - * - * Principal IVAS decoder routine - *--------------------------------------------------------------------------*/ diff --git a/lib_dec/ivas_decision_matrix_dec.c b/lib_dec/ivas_decision_matrix_dec_fx.c similarity index 99% rename from lib_dec/ivas_decision_matrix_dec.c rename to lib_dec/ivas_decision_matrix_dec_fx.c index 6196d31fbe3bd9bcff5e3b21bca81b4527df4c2f..717bb3b93512bdd8818088c6a585e9a2376d71b6 100644 --- a/lib_dec/ivas_decision_matrix_dec.c +++ b/lib_dec/ivas_decision_matrix_dec_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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,12 +34,10 @@ #include "options.h" #include "stat_dec.h" #include "rom_com.h" -#include "ivas_prot.h" -#include "prot.h" +#include "prot_fx.h" #include "ivas_cnst.h" #include "wmc_auto.h" #include "ivas_prot_fx.h" -#include "prot_fx.h" /*-----------------------------------------------------------------* * ivas_decision_matrix_dec() diff --git a/lib_dec/ivas_dirac_dec.c b/lib_dec/ivas_dirac_dec_fx.c similarity index 95% rename from lib_dec/ivas_dirac_dec.c rename to lib_dec/ivas_dirac_dec_fx.c index 95cca12a098cc772bf24cc54c6a5b604e95565e5..70271c725da18c44befb55a5fd57a5276ad46b43 100644 --- a/lib_dec/ivas_dirac_dec.c +++ b/lib_dec/ivas_dirac_dec_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other @@ -35,15 +35,13 @@ #include "options.h" #include #include "cnst.h" -#include "prot.h" -#include "ivas_prot.h" -#include "ivas_prot_rend.h" +#include "prot_fx.h" +#include "ivas_prot_rend_fx.h" #include "ivas_cnst.h" #include "ivas_rom_com.h" #include "ivas_rom_dec.h" #include "ivas_rom_rend.h" #include "wmc_auto.h" -#include "prot_fx.h" /* Function prototypes */ #include "ivas_rom_com_fx.h" #include "ivas_prot_fx.h" @@ -980,6 +978,9 @@ ivas_error ivas_dirac_dec_config_fx( Word16 need_parambin; Word16 dec_param_estim_old; Word16 dec_param_estim_new; +#ifdef SPLIT_REND_WITH_HEAD_ROT + Word16 num_poses, pos_idx; +#endif error = IVAS_ERR_OK; move32(); @@ -1010,6 +1011,16 @@ ivas_error ivas_dirac_dec_config_fx( move16(); } +#ifdef SPLIT_REND_WITH_HEAD_ROT + num_poses = 1; + move16(); + IF( EQ_16( st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) || EQ_16( st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ) + { + num_poses = st_ivas->hSplitBinRend->splitrend.multiBinPoseData.num_poses; + move16(); + } +#endif + sparfoa_flag = 0; move16(); test(); @@ -1056,7 +1067,11 @@ ivas_error ivas_dirac_dec_config_fx( IF( !need_parambin ) { +#ifdef SPLIT_REND_WITH_HEAD_ROT + ivas_dirac_dec_close_binaural_data( st_ivas->hDiracDecBin ); +#else ivas_dirac_dec_close_binaural_data( &st_ivas->hDiracDecBin ); +#endif } need_dirac_rend = 0; @@ -1129,7 +1144,11 @@ ivas_error ivas_dirac_dec_config_fx( } } +#ifdef SPLIT_REND_WITH_HEAD_ROT + IF( st_ivas->hDiracDecBin[0] == NULL ) +#else IF( st_ivas->hDiracDecBin == NULL ) +#endif { IF( NE_32( ( error = ivas_dirac_dec_init_binaural_data_fx( st_ivas, st_ivas->hHrtfParambin ) ), IVAS_ERR_OK ) ) { @@ -1141,34 +1160,75 @@ ivas_error ivas_dirac_dec_config_fx( /* This is required to keep BE in rate switching. This probably means that 1TC and 2TC MASA perform differently. */ test(); test(); +#ifdef SPLIT_REND_WITH_HEAD_ROT + IF( st_ivas->hDiracDecBin[0]->h_freq_domain_decorr_ap_params != NULL && !( EQ_32( st_ivas->ivas_format, MASA_FORMAT ) && st_ivas->nSCE > 0 ) ) +#else IF( st_ivas->hDiracDecBin->h_freq_domain_decorr_ap_params != NULL && !( EQ_32( st_ivas->ivas_format, MASA_FORMAT ) && st_ivas->nSCE > 0 ) ) +#endif { +#ifdef SPLIT_REND_WITH_HEAD_ROT + ivas_dirac_dec_decorr_close_fx( &st_ivas->hDiracDecBin[0]->h_freq_domain_decorr_ap_params, &st_ivas->hDiracDecBin[0]->h_freq_domain_decorr_ap_state ); // done +#else ivas_dirac_dec_decorr_close_fx( &st_ivas->hDiracDecBin->h_freq_domain_decorr_ap_params, &st_ivas->hDiracDecBin->h_freq_domain_decorr_ap_state ); // done +#endif } +#ifdef SPLIT_REND_WITH_HEAD_ROT + IF( NE_32( ( error = ivas_td_decorr_reconfig_dec( st_ivas->ivas_format, st_ivas->hDecoderConfig->ivas_total_brate, st_ivas->nchan_transport, st_ivas->hDecoderConfig->output_Fs, &( st_ivas->hDiracDecBin[0]->hTdDecorr ), &( st_ivas->hDiracDecBin[0]->useTdDecorr ) ) ), IVAS_ERR_OK ) ) +#else IF( NE_32( ( error = ivas_td_decorr_reconfig_dec( st_ivas->ivas_format, st_ivas->hDecoderConfig->ivas_total_brate, st_ivas->nchan_transport, st_ivas->hDecoderConfig->output_Fs, &( st_ivas->hDiracDecBin->hTdDecorr ), &( st_ivas->hDiracDecBin->useTdDecorr ) ) ), IVAS_ERR_OK ) ) +#endif { return error; } +#ifdef SPLIT_REND_WITH_HEAD_ROT + /* copy td-decorr flag to split renderer side rendereres */ + FOR( pos_idx = 1; pos_idx < num_poses; pos_idx++ ) + { + st_ivas->hDiracDecBin[pos_idx]->useTdDecorr = st_ivas->hDiracDecBin[0]->useTdDecorr; + } + IF( !st_ivas->hDiracDecBin[0]->useTdDecorr ) +#else IF( !st_ivas->hDiracDecBin->useTdDecorr ) +#endif { +#ifdef SPLIT_REND_WITH_HEAD_ROT + IF( st_ivas->hDiracDecBin[0]->h_freq_domain_decorr_ap_params == NULL ) +#else IF( st_ivas->hDiracDecBin->h_freq_domain_decorr_ap_params == NULL ) +#endif { Word16 frequency_axis_fx[CLDFB_NO_CHANNELS_MAX]; ivas_dirac_dec_get_frequency_axis_fx( frequency_axis_fx, st_ivas->hDecoderConfig->output_Fs, st_ivas->hSpatParamRendCom->num_freq_bands ); - +#ifdef SPLIT_REND_WITH_HEAD_ROT + IF( NE_32( ( error = ivas_dirac_dec_decorr_open_fx( &( st_ivas->hDiracDecBin[0]->h_freq_domain_decorr_ap_params ), &( st_ivas->hDiracDecBin[0]->h_freq_domain_decorr_ap_state ), st_ivas->hSpatParamRendCom->num_freq_bands, BINAURAL_CHANNELS, BINAURAL_CHANNELS, + DIRAC_SYNTHESIS_PSD_LS, frequency_axis_fx, BINAURAL_CHANNELS, st_ivas->hDecoderConfig->output_Fs ) ), + IVAS_ERR_OK ) ) + { + return error; + } +#else IF( NE_32( ( error = ivas_dirac_dec_decorr_open_fx( &( st_ivas->hDiracDecBin->h_freq_domain_decorr_ap_params ), &( st_ivas->hDiracDecBin->h_freq_domain_decorr_ap_state ), st_ivas->hSpatParamRendCom->num_freq_bands, BINAURAL_CHANNELS, BINAURAL_CHANNELS, DIRAC_SYNTHESIS_PSD_LS, frequency_axis_fx, BINAURAL_CHANNELS, st_ivas->hDecoderConfig->output_Fs ) ), IVAS_ERR_OK ) ) { return error; } +#endif } } +#ifdef SPLIT_REND_WITH_HEAD_ROT + FOR( pos_idx = 0; pos_idx < num_poses; pos_idx++ ) + { + st_ivas->hDiracDecBin[pos_idx]->reqularizationFactor_fx = configure_reqularization_factor_fx( st_ivas->ivas_format, st_ivas->hDecoderConfig->ivas_total_brate ); + move16(); + } +#else st_ivas->hDiracDecBin->reqularizationFactor_fx = configure_reqularization_factor_fx( st_ivas->ivas_format, st_ivas->hDecoderConfig->ivas_total_brate ); move16(); +#endif } } } @@ -2093,7 +2153,7 @@ void ivas_dirac_dec_render_fx( output_f_local_fx[ch] = output_f_local_buff_fx[ch]; set_zero_fx( output_f_local_fx[ch], nSamplesAsked ); } - slot_size = NS2SA( st_ivas->hDecoderConfig->output_Fs, CLDFB_SLOT_NS ); // cL + slot_size = NS2SA_FX2( st_ivas->hDecoderConfig->output_Fs, CLDFB_SLOT_NS ); // cL /* loop for synthesis, assume we always have to render in multiples of 5ms subframes with spills */ @@ -2185,8 +2245,13 @@ void ivas_dirac_dec_render_sf_fx( /*CLDFB: last output channels reserved to LFT for CICPx*/ Word32 Cldfb_RealBuffer_fx[MAX_OUTPUT_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX]; Word32 Cldfb_ImagBuffer_fx[MAX_OUTPUT_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX]; +#ifdef SPLIT_REND_WITH_HEAD_ROT + Word32 Cldfb_RealBuffer_Binaural_fx[MAX_HEAD_ROT_POSES][BINAURAL_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX]; + Word32 Cldfb_ImagBuffer_Binaural_fx[MAX_HEAD_ROT_POSES][BINAURAL_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX]; +#else Word32 Cldfb_RealBuffer_Binaural_fx[BINAURAL_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX]; Word32 Cldfb_ImagBuffer_Binaural_fx[BINAURAL_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX]; +#endif Word16 index = 0, num_freq_bands = 0; move16(); move16(); @@ -2206,18 +2271,20 @@ void ivas_dirac_dec_render_sf_fx( Word32 Cldfb_RealBuffer_Temp_fx[2][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX]; Word32 Cldfb_ImagBuffer_Temp_fx[2][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX]; Word16 cldfb_buf_q; - Word16 offset, buff_len; + Word16 offset = 0, buff_len = 0; + move16(); + move16(); Word16 q_cldfb, q_temp_cldfb = 0; move16(); Word16 proto_length = 0; move16(); - Word16 q_proto_direct_buffer[CLDFB_SLOTS_PER_SUBFRAME]; - Word16 q_proto_diffuse_buffer[CLDFB_SLOTS_PER_SUBFRAME]; + Word16 q_proto_direct_buffer[CLDFB_SLOTS_PER_SUBFRAME + 1]; + Word16 q_proto_diffuse_buffer[CLDFB_SLOTS_PER_SUBFRAME + 1]; Word16 size, size_ho; DIRAC_DEC_STACK_MEM DirAC_mem; Word32 *p_onset_filter_fx = NULL; - uint16_t coherence_flag; + UWord16 coherence_flag; SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom; Word16 scale = 0; move16(); @@ -2260,8 +2327,8 @@ void ivas_dirac_dec_render_sf_fx( } q_cldfb = Q11; move16(); - set16_fx( q_proto_direct_buffer, hDirACRend->h_output_synthesis_psd_state.proto_direct_buffer_f_q, CLDFB_SLOTS_PER_SUBFRAME ); - set16_fx( q_proto_diffuse_buffer, hDirACRend->h_output_synthesis_psd_state.proto_diffuse_buffer_f_q, CLDFB_SLOTS_PER_SUBFRAME ); + set16_fx( q_proto_direct_buffer, hDirACRend->h_output_synthesis_psd_state.proto_direct_buffer_f_q, CLDFB_SLOTS_PER_SUBFRAME + 1 ); + set16_fx( q_proto_diffuse_buffer, hDirACRend->h_output_synthesis_psd_state.proto_diffuse_buffer_f_q, CLDFB_SLOTS_PER_SUBFRAME + 1 ); set_zero_fx( surCohRatio_fx, CLDFB_NO_CHANNELS_MAX ); IF( EQ_16( hDirACRend->synthesisConf, DIRAC_SYNTHESIS_MONO ) ) @@ -3254,22 +3321,21 @@ void ivas_dirac_dec_render_sf_fx( } } - minimum_s( q_proto_direct_buffer, hSpatParamRendCom->subframe_nbslots[subframe_idx], &hDirACRend->h_output_synthesis_psd_state.proto_direct_buffer_f_q ); + minimum_s( q_proto_direct_buffer, add( hSpatParamRendCom->subframe_nbslots[subframe_idx], 1 ), &hDirACRend->h_output_synthesis_psd_state.proto_direct_buffer_f_q ); IF( EQ_16( hDirACRend->synthesisConf, DIRAC_SYNTHESIS_GAIN_SHD ) ) { - minimum_s( q_proto_diffuse_buffer, hSpatParamRendCom->subframe_nbslots[subframe_idx], &hDirACRend->h_output_synthesis_psd_state.proto_diffuse_buffer_f_q ); + minimum_s( q_proto_diffuse_buffer, add( hSpatParamRendCom->subframe_nbslots[subframe_idx], 1 ), &hDirACRend->h_output_synthesis_psd_state.proto_diffuse_buffer_f_q ); } FOR( slot_idx = 0; slot_idx < hSpatParamRendCom->subframe_nbslots[subframe_idx]; slot_idx++ ) { IF( EQ_16( hDirACRend->synthesisConf, DIRAC_SYNTHESIS_GAIN_SHD ) ) { - offset = i_mult( i_mult( slot_idx, 2 ), i_mult( hSpatParamRendCom->num_freq_bands, nchan_transport ) ); - buff_len = i_mult( 2, i_mult( nchan_transport, hSpatParamRendCom->num_freq_bands ) ); - scale_sig32( hDirACRend->h_output_synthesis_psd_state.proto_direct_buffer_f_fx + offset, buff_len, sub( hDirACRend->h_output_synthesis_psd_state.proto_direct_buffer_f_q, q_proto_direct_buffer[slot_idx] ) ); // proto_direct_buffer_f_q - offset = i_mult( i_mult( slot_idx, 2 ), i_mult( hSpatParamRendCom->num_freq_bands, hDirACRend->num_outputs_diff ) ); buff_len = i_mult( 2, i_mult( hDirACRend->num_outputs_diff, hSpatParamRendCom->num_freq_bands ) ); scale_sig32( hDirACRend->h_output_synthesis_psd_state.proto_diffuse_buffer_f_fx + offset, buff_len, sub( hDirACRend->h_output_synthesis_psd_state.proto_diffuse_buffer_f_q, q_proto_diffuse_buffer[slot_idx] ) ); // proto_diffuse_buffer_f_q + offset = i_mult( i_mult( slot_idx, 2 ), i_mult( hSpatParamRendCom->num_freq_bands, nchan_transport ) ); + buff_len = i_mult( 2, i_mult( nchan_transport, hSpatParamRendCom->num_freq_bands ) ); + scale_sig32( hDirACRend->h_output_synthesis_psd_state.proto_direct_buffer_f_fx + offset, buff_len, sub( hDirACRend->h_output_synthesis_psd_state.proto_direct_buffer_f_q, q_proto_direct_buffer[slot_idx] ) ); // proto_direct_buffer_f_q } ELSE IF( EQ_16( hDirACRend->synthesisConf, DIRAC_SYNTHESIS_MONO ) ) { @@ -3309,10 +3375,18 @@ void ivas_dirac_dec_render_sf_fx( BREAK; } } - q_proto_direct_buffer[slot_idx] = hDirACRend->h_output_synthesis_psd_state.proto_direct_buffer_f_q; - move16(); } - + test(); + IF( EQ_16( slot_idx, hSpatParamRendCom->subframe_nbslots[subframe_idx] ) && sub( hDirACRend->h_output_synthesis_psd_state.proto_direct_buffer_f_len, add( offset, buff_len ) ) > 0 ) + { + scale_sig32( hDirACRend->h_output_synthesis_psd_state.proto_direct_buffer_f_fx + add( offset, buff_len ), sub( hDirACRend->h_output_synthesis_psd_state.proto_direct_buffer_f_len, add( offset, buff_len ) ), sub( hDirACRend->h_output_synthesis_psd_state.proto_direct_buffer_f_q, q_proto_direct_buffer[slot_idx] ) ); // proto_direct_buffer_f_q + offset = i_mult( i_mult( sub( slot_idx, 1 ), 2 ), i_mult( hSpatParamRendCom->num_freq_bands, hDirACRend->num_outputs_diff ) ); + buff_len = i_mult( 2, i_mult( hDirACRend->num_outputs_diff, hSpatParamRendCom->num_freq_bands ) ); + IF( EQ_16( hDirACRend->synthesisConf, DIRAC_SYNTHESIS_GAIN_SHD ) && sub( hDirACRend->h_output_synthesis_psd_state.proto_diffuse_buffer_f_len, add( offset, buff_len ) ) > 0 ) + { + scale_sig32( hDirACRend->h_output_synthesis_psd_state.proto_diffuse_buffer_f_fx + add( offset, buff_len ), sub( hDirACRend->h_output_synthesis_psd_state.proto_diffuse_buffer_f_len, add( offset, buff_len ) ), sub( hDirACRend->h_output_synthesis_psd_state.proto_diffuse_buffer_f_q, q_proto_diffuse_buffer[slot_idx] ) ); // proto_direct_buffer_f_q + } + } ivas_dirac_dec_output_synthesis_get_interpolator_fx( &hDirACRend->h_output_synthesis_psd_params, hSpatParamRendCom->subframe_nbslots[subframe_idx] ); size = i_mult( hDirACRend->num_outputs_dir, hSpatParamRendCom->num_freq_bands ); @@ -3712,14 +3786,60 @@ void ivas_dirac_dec_render_sf_fx( input_q = Q6; move16(); +#ifdef SPLIT_REND_WITH_HEAD_ROT + IF( EQ_16( st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) || EQ_16( st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ) + { + IF( st_ivas->hSplitBinRend->hCldfbDataOut != NULL ) + { + FOR( slot_idx = 0; slot_idx < hSpatParamRendCom->subframe_nbslots[subframe_idx]; slot_idx++ ) + { + FOR( ch = 0; ch < st_ivas->hBinRenderer->nInChannels; ch++ ) + { + Copy32( Cldfb_RealBuffer_fx[ch][slot_idx], st_ivas->hSplitBinRend->hCldfbDataOut->Cldfb_RealBuffer_fx[ch][add( slot_idx_start, slot_idx )], hSpatParamRendCom->num_freq_bands ); + Copy32( Cldfb_ImagBuffer_fx[ch][slot_idx], st_ivas->hSplitBinRend->hCldfbDataOut->Cldfb_ImagBuffer_fx[ch][add( slot_idx_start, slot_idx )], hSpatParamRendCom->num_freq_bands ); + } + } + st_ivas->hSplitBinRend->hCldfbDataOut->config = st_ivas->hIntSetup.output_config; + move16(); + } + } +#endif + ivas_binRenderer_fx( st_ivas->hBinRenderer, +#ifdef SPLIT_REND_WITH_HEAD_ROT + ( st_ivas->hSplitBinRend == NULL ) ? NULL : &st_ivas->hSplitBinRend->splitrend.multiBinPoseData, +#endif st_ivas->hCombinedOrientationData, hSpatParamRendCom->subframe_nbslots[subframe_idx], Cldfb_RealBuffer_Binaural_fx, Cldfb_ImagBuffer_Binaural_fx, Cldfb_RealBuffer_fx, Cldfb_ImagBuffer_fx, &input_q ); - +#ifndef SPLIT_REND_WITH_HEAD_ROT Scale_sig32( Cldfb_RealBuffer_Binaural_fx[0][0], i_mult( BINAURAL_CHANNELS, i_mult( MAX_PARAM_SPATIAL_SUBFRAMES, CLDFB_NO_CHANNELS_MAX ) ), sub( Q6, input_q ) ); // Q6 Scale_sig32( Cldfb_ImagBuffer_Binaural_fx[0][0], i_mult( BINAURAL_CHANNELS, i_mult( MAX_PARAM_SPATIAL_SUBFRAMES, CLDFB_NO_CHANNELS_MAX ) ), sub( Q6, input_q ) ); // Q6 +#else + Word16 pos_idx; + FOR( pos_idx = 0; pos_idx < st_ivas->hBinRenderer->numPoses; pos_idx++ ) + { + Scale_sig32( &Cldfb_RealBuffer_Binaural_fx[pos_idx][0][0][0], i_mult( BINAURAL_CHANNELS, i_mult( MAX_PARAM_SPATIAL_SUBFRAMES, CLDFB_NO_CHANNELS_MAX ) ), sub( Q6, input_q ) ); // Q6 + Scale_sig32( &Cldfb_ImagBuffer_Binaural_fx[pos_idx][0][0][0], i_mult( BINAURAL_CHANNELS, i_mult( MAX_PARAM_SPATIAL_SUBFRAMES, CLDFB_NO_CHANNELS_MAX ) ), sub( Q6, input_q ) ); // Q6 + } +#endif +#ifdef SPLIT_REND_WITH_HEAD_ROT + IF( EQ_16( st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) || EQ_16( st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ) + { + FOR( pos_idx = 0; pos_idx < st_ivas->hBinRenderer->numPoses; pos_idx++ ) + { + FOR( slot_idx = 0; slot_idx < hSpatParamRendCom->subframe_nbslots[subframe_idx]; slot_idx++ ) + { + FOR( ch = 0; ch < st_ivas->hDecoderConfig->nchan_out; ch++ ) + { + Copy32( Cldfb_RealBuffer_Binaural_fx[pos_idx][ch][slot_idx], st_ivas->hSplitBinRend->hMultiBinCldfbData->Cldfb_RealBuffer_Binaural_fx[add( i_mult( pos_idx, BINAURAL_CHANNELS ), ch )][add( slot_idx_start, slot_idx )], hSpatParamRendCom->num_freq_bands ); // Q6 + Copy32( Cldfb_ImagBuffer_Binaural_fx[pos_idx][ch][slot_idx], st_ivas->hSplitBinRend->hMultiBinCldfbData->Cldfb_ImagBuffer_Binaural_fx[add( i_mult( pos_idx, BINAURAL_CHANNELS ), ch )][add( slot_idx_start, slot_idx )], hSpatParamRendCom->num_freq_bands ); // Q6 + } + } + } + } +#endif /* Inverse CLDFB*/ FOR( ch = 0; ch < st_ivas->hDecoderConfig->nchan_out; ch++ ) @@ -3730,10 +3850,17 @@ void ivas_dirac_dec_render_sf_fx( Word32 *ImagBuffer_fx[MAX_PARAM_SPATIAL_SUBFRAMES]; FOR( i = 0; i < hSpatParamRendCom->subframe_nbslots[subframe_idx]; i++ ) { +#ifdef SPLIT_REND_WITH_HEAD_ROT + RealBuffer_fx[i] = Cldfb_RealBuffer_Binaural_fx[0][ch][i]; + move32(); + ImagBuffer_fx[i] = Cldfb_ImagBuffer_Binaural_fx[0][ch][i]; + move32(); +#else RealBuffer_fx[i] = Cldfb_RealBuffer_Binaural_fx[ch][i]; move32(); ImagBuffer_fx[i] = Cldfb_ImagBuffer_Binaural_fx[ch][i]; move32(); +#endif } scale_sig32( st_ivas->cldfbSynDec[ch]->cldfb_state_fx, st_ivas->cldfbSynDec[ch]->p_filter_length, sub( ( Q6 - 1 ), st_ivas->cldfbSynDec[ch]->Q_cldfb_state ) ); // Q6-1 diff --git a/lib_dec/ivas_dirac_output_synthesis_cov.c b/lib_dec/ivas_dirac_output_synthesis_cov_fx.c similarity index 91% rename from lib_dec/ivas_dirac_output_synthesis_cov.c rename to lib_dec/ivas_dirac_output_synthesis_cov_fx.c index 5aa649ecda5e1fe8388321724dac753b47b0d351..b247fd6531c63eec9e3d7291599349bc28feed98 100644 --- a/lib_dec/ivas_dirac_output_synthesis_cov.c +++ b/lib_dec/ivas_dirac_output_synthesis_cov_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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,15 +40,13 @@ #include "cnst.h" #include "rom_enc.h" #include "rom_com.h" -#include "prot.h" -#include "ivas_prot.h" +#include "prot_fx.h" #include "ivas_stat_dec.h" #include "ivas_cnst.h" #include "ivas_rom_com.h" #include "ivas_rom_dec.h" #include "wmc_auto.h" #include "rom_dec.h" -#include "prot_fx.h" #include "ivas_prot_fx.h" @@ -410,8 +408,6 @@ void ivas_dirac_dec_output_synthesis_cov_param_mc_collect_slot_fx( const Word16 nchan_in /* i : number of input channels */ ) { - Word16 cx_init_e; - Word16 cx_init_imag_e; Word16 band_idx, ch_idx; Word16 brange[2]; Word32 real_in_buffer_fx[PARAM_MC_MAX_BANDS_IN_PARAMETER_BAND * MAX_TRANSPORT_CHANNELS]; @@ -421,10 +417,9 @@ void ivas_dirac_dec_output_synthesis_cov_param_mc_collect_slot_fx( Word32 real_buffer_fx[PARAM_MC_MAX_TRANSPORT_CHANS * PARAM_MC_MAX_TRANSPORT_CHANS]; Word32 imag_buffer_fx[PARAM_MC_MAX_TRANSPORT_CHANS * PARAM_MC_MAX_TRANSPORT_CHANS]; Word16 output_e; - Word16 i, j, tmp1, tmp2, tmp1_e, tmp2_e, shift_imag, shift_real; - Word32 L_tmp; + Word16 tmp1_e, tmp2_e, shift_imag, shift_real; Word16 band, num_bands; - + Word16 cx_fx_norm, cx_imag_fx_norm; /* estimate input covariance */ /* Already stack here instead of in the process_subframe */ @@ -451,8 +446,11 @@ void ivas_dirac_dec_output_synthesis_cov_param_mc_collect_slot_fx( move16(); imag_in_e = ImagBuffer_e; move16(); - shift_real = sub( L_norm_arr( real_in_buffer_fx, imult1616( num_bands, nchan_in ) ), find_guarded_bits_fx( add( num_bands, 1 ) ) ); - shift_imag = sub( L_norm_arr( imag_in_buffer_fx, imult1616( num_bands, nchan_in ) ), find_guarded_bits_fx( add( num_bands, 1 ) ) ); + + Word16 buf_len = imult1616( num_bands, nchan_in ); + + shift_real = sub( L_norm_arr( real_in_buffer_fx, buf_len ), find_guarded_bits_fx( add( num_bands, 1 ) ) ); + shift_imag = sub( L_norm_arr( imag_in_buffer_fx, buf_len ), find_guarded_bits_fx( add( num_bands, 1 ) ) ); real_in_e = sub( real_in_e, shift_real ); imag_in_e = sub( imag_in_e, shift_imag ); @@ -460,50 +458,23 @@ void ivas_dirac_dec_output_synthesis_cov_param_mc_collect_slot_fx( output_e = s_max( real_in_e, imag_in_e ); - FOR( i = 0; i < num_bands * nchan_in; ++i ) - { - real_in_buffer_fx[i] = L_shr( real_in_buffer_fx[i], sub( output_e, RealBuffer_e ) ); // Q(31-output_e) - move32(); - imag_in_buffer_fx[i] = L_shr( imag_in_buffer_fx[i], sub( output_e, ImagBuffer_e ) ); // Q(31-output_e) - move32(); - } + scale_sig32( real_in_buffer_fx, buf_len, sub( RealBuffer_e, output_e ) ); + scale_sig32( imag_in_buffer_fx, buf_len, sub( ImagBuffer_e, output_e ) ); cmplx_matrix_square_fx( real_in_buffer_fx, imag_in_buffer_fx, num_bands, nchan_in, real_buffer_fx, imag_buffer_fx, output_e, &output_e ); v_add_fixed_me( cx_fx, *cx_e, real_buffer_fx, output_e, cx_fx, &tmp1_e, imult1616( nchan_in, nchan_in ), 1 ); v_add_fixed_me( cx_imag_fx, *cx_imag_e, imag_buffer_fx, output_e, cx_imag_fx, &tmp2_e, imult1616( nchan_in, nchan_in ), 1 ); - cx_init_e = tmp1_e; - move16(); - cx_init_imag_e = tmp2_e; - move16(); - // normalizing both the matrices to a common exponent for a better precision - tmp1 = 0; - move16(); - tmp2 = 0; - move16(); + cx_fx_norm = L_norm_arr( cx_fx, PARAM_MC_MAX_TRANSPORT_CHANS * PARAM_MC_MAX_TRANSPORT_CHANS ); + cx_imag_fx_norm = L_norm_arr( cx_imag_fx, PARAM_MC_MAX_TRANSPORT_CHANS * PARAM_MC_MAX_TRANSPORT_CHANS ); - FOR( j = 0; j < PARAM_MC_MAX_TRANSPORT_CHANS * PARAM_MC_MAX_TRANSPORT_CHANS; j++ ) - { - L_tmp = BASOP_Util_Add_Mant32Exp( cx_fx[j], cx_init_e, 0, 0, &tmp1_e ); - L_tmp = BASOP_Util_Add_Mant32Exp( cx_imag_fx[j], cx_init_imag_e, 0, 0, &tmp2_e ); - tmp1 = s_max( tmp1, tmp1_e ); - tmp2 = s_max( tmp2, tmp2_e ); - } - - FOR( j = 0; j < PARAM_MC_MAX_TRANSPORT_CHANS * PARAM_MC_MAX_TRANSPORT_CHANS; j++ ) - { - L_tmp = BASOP_Util_Add_Mant32Exp( cx_fx[j], cx_init_e, 0, 0, &tmp1_e ); - cx_fx[j] = L_shr( L_tmp, sub( tmp1, tmp1_e ) ); // Q(31-tmp1) - move32(); - L_tmp = BASOP_Util_Add_Mant32Exp( cx_imag_fx[j], cx_init_imag_e, 0, 0, &tmp2_e ); - cx_imag_fx[j] = L_shr( L_tmp, sub( tmp2, tmp2_e ) ); // Q(31-tmp2) - move32(); - } + scale_sig32( cx_fx, PARAM_MC_MAX_TRANSPORT_CHANS * PARAM_MC_MAX_TRANSPORT_CHANS, cx_fx_norm ); + scale_sig32( cx_imag_fx, PARAM_MC_MAX_TRANSPORT_CHANS * PARAM_MC_MAX_TRANSPORT_CHANS, cx_imag_fx_norm ); - *cx_e = tmp1; + *cx_e = sub( tmp1_e, cx_fx_norm ); move16(); - *cx_imag_e = tmp2; + *cx_imag_e = sub( tmp2_e, cx_imag_fx_norm ); move16(); return; @@ -752,7 +723,11 @@ Word16 computeMixingMatrices_fx( Word32 G_hat_fx[MAX_OUTPUT_CHANNELS]; Word16 G_hat_buff_e[MAX_OUTPUT_CHANNELS]; +#ifdef OPT_BASOP_ADD_v1 + Word16 mat_mult_buffer2_e, mat_mult_buffer3_e; +#else /* OPT_BASOP_ADD_v1 */ Word16 mat_mult_buffer1_e, mat_mult_buffer2_e, mat_mult_buffer3_e; +#endif /* OPT_BASOP_ADD_v1 */ Word32 mat_mult_buffer3_fx[MAX_OUTPUT_CHANNELS * MAX_OUTPUT_CHANNELS]; @@ -802,7 +777,9 @@ Word16 computeMixingMatrices_fx( mat2svdMat_fx( Cy_fx, svd_in_buffer_fx, lengthCy, lengthCy, 0 ); svd_fx( svd_in_buffer_fx, Cy_fx_e, svd_u_buffer_fx, svd_s_buffer_fx, svd_v_buffer_fx, svd_s_buffer_e, lengthCy, lengthCy ); - +#ifdef OPT_BASOP_ADD_v1 + Word16 max_e = -32; +#endif /* OPT_BASOP_ADD_v1 */ /* Computing Ky */ FOR( i = 0; i < lengthCy; ++i ) { @@ -815,8 +792,20 @@ Word16 computeMixingMatrices_fx( move32(); Ky_fx_e[i + ( j * lengthCy )] = tmp_e; move16(); +#ifdef OPT_BASOP_ADD_v1 + max_e = s_max( max_e, tmp_e ); +#endif /* OPT_BASOP_ADD_v1 */ } } +#ifdef OPT_BASOP_ADD_v1 + FOR( i = 0; i < lengthCy * lengthCy; ++i ) + { + Ky_fx[i] = L_shr( Ky_fx[i], sub( max_e, Ky_fx_e[i] ) ); + move32(); + Ky_fx_e[i] = max_e; + move16(); + } +#endif /* OPT_BASOP_ADD_v1 */ /*-----------------------------------------------------------------* * Decomposition of Cx @@ -827,7 +816,9 @@ Word16 computeMixingMatrices_fx( mat2svdMat_fx( Cx_fx, svd_in_buffer_fx, lengthCx, lengthCx, 0 ); svd_fx( svd_in_buffer_fx, Cx_fx_e, svd_u_buffer_fx, svd_s_buffer_fx, svd_v_buffer_fx, svd_s_buffer_e, lengthCx, lengthCx ); - +#ifdef OPT_BASOP_ADD_v1 + max_e = -32; +#endif /* OPT_BASOP_ADD_v1 */ FOR( i = 0; i < lengthCx; ++i ) { FOR( j = 0; j < lengthCx; ++j ) @@ -839,9 +830,20 @@ Word16 computeMixingMatrices_fx( move32(); Kx_fx_e[( i + ( j * lengthCx ) )] = tmp_e; move16(); +#ifdef OPT_BASOP_ADD_v1 + max_e = s_max( max_e, tmp_e ); +#endif /* OPT_BASOP_ADD_v1 */ } } - +#ifdef OPT_BASOP_ADD_v1 + FOR( i = 0; i < lengthCx * lengthCx; ++i ) + { + Kx_fx[i] = L_shr( Kx_fx[i], sub( max_e, Kx_fx_e[i] ) ); + move32(); + Kx_fx_e[i] = max_e; + move16(); + } +#endif /* OPT_BASOP_ADD_v1 */ FOR( i = 0; i < lengthCx; ++i ) { @@ -965,14 +967,25 @@ Word16 computeMixingMatrices_fx( /* Computing the input matrix Kx'*Q'*G_hat'*Ky */ +#ifdef OPT_BASOP_ADD_v1 + Word16 mat_mult_buffer1_fx_e; +#else /* OPT_BASOP_ADD_v1 */ Word16 mat_mult_buffer1_fx_e[MAX_OUTPUT_CHANNELS * MAX_OUTPUT_CHANNELS]; Word16 Q_e_arr[PARAM_MC_MAX_TRANSPORT_CHANS * MAX_CICP_CHANNELS]; set16_fx( Q_e_arr, Q_e, PARAM_MC_MAX_TRANSPORT_CHANS * MAX_CICP_CHANNELS ); matrix_product_mant_exp( Kx_fx, Kx_fx_e, lengthCx, lengthCx, 1, Q_fx, Q_e_arr, lengthCy, lengthCx, 1, mat_mult_buffer1_fx, mat_mult_buffer1_fx_e ); +#endif /* OPT_BASOP_ADD_v1 */ Word16 mat_mult_buffer2_fx_e[MAX_OUTPUT_CHANNELS * MAX_OUTPUT_CHANNELS]; +#ifdef OPT_BASOP_ADD_v1 + matrix_product_mant_exp_fx( Kx_fx, Kx_fx_e[0], lengthCx, lengthCx, 1, Q_fx, Q_e, lengthCy, lengthCx, 1, mat_mult_buffer1_fx, &mat_mult_buffer1_fx_e ); + + matrix_diag_product_fx_2( mat_mult_buffer1_fx, mat_mult_buffer1_fx_e, lengthCx, lengthCy, 0, G_hat_fx, G_hat_buff_e, lengthCy, mat_mult_buffer2_fx, mat_mult_buffer2_fx_e ); + + matrix_product_mant_exp_fx( mat_mult_buffer2_fx, mat_mult_buffer2_fx_e[0], lengthCx, lengthCy, 0, Ky_fx, Ky_fx_e[0], lengthCy, lengthCy, 0, mat_mult_buffer1_fx, &mat_mult_buffer1_fx_e ); +#else /* OPT_BASOP_ADD_v1 */ matrix_diag_product_fx_1( mat_mult_buffer1_fx, mat_mult_buffer1_fx_e, lengthCx, lengthCy, 0, G_hat_fx, G_hat_buff_e, lengthCy, mat_mult_buffer2_fx, mat_mult_buffer2_fx_e ); matrix_product_mant_exp( mat_mult_buffer2_fx, mat_mult_buffer2_fx_e, lengthCx, lengthCy, 0, Ky_fx, Ky_fx_e, lengthCy, lengthCy, 0, mat_mult_buffer1_fx, mat_mult_buffer1_fx_e ); @@ -996,6 +1009,7 @@ Word16 computeMixingMatrices_fx( mat_mult_buffer1_e = exp; move16(); +#endif /* OPT_BASOP_ADD_v1 */ IF( LT_16( lengthCx, lengthCy ) ) { @@ -1004,7 +1018,11 @@ Word16 computeMixingMatrices_fx( move16(); nC = lengthCx; move16(); +#ifdef OPT_BASOP_ADD_v1 + svd_fx( svd_in_buffer_fx, mat_mult_buffer1_fx_e, svd_v_buffer_fx, svd_s_buffer_fx, svd_u_buffer_fx, svd_s_buffer_e, nL, nC ); +#else /* OPT_BASOP_ADD_v1 */ svd_fx( svd_in_buffer_fx, mat_mult_buffer1_e, svd_v_buffer_fx, svd_s_buffer_fx, svd_u_buffer_fx, svd_s_buffer_e, nL, nC ); +#endif /* OPT_BASOP_ADD_v1 */ } ELSE { @@ -1013,7 +1031,11 @@ Word16 computeMixingMatrices_fx( move16(); nC = lengthCy; move16(); +#ifdef OPT_BASOP_ADD_v1 + svd_fx( svd_in_buffer_fx, mat_mult_buffer1_fx_e, svd_u_buffer_fx, svd_s_buffer_fx, svd_v_buffer_fx, svd_s_buffer_e, nL, nC ); +#else /* OPT_BASOP_ADD_v1 */ svd_fx( svd_in_buffer_fx, mat_mult_buffer1_e, svd_u_buffer_fx, svd_s_buffer_fx, svd_v_buffer_fx, svd_s_buffer_e, nL, nC ); +#endif /* OPT_BASOP_ADD_v1 */ } /* Actually Processing P */ @@ -1024,25 +1046,46 @@ Word16 computeMixingMatrices_fx( svdMat2mat_fx( svd_v_buffer_fx, mat_mult_buffer1_fx, lengthCy, lengthCx ); svdMat2mat_fx( svd_u_buffer_fx, mat_mult_buffer2_fx, lengthCx, lengthCx ); +#ifdef OPT_BASOP_ADD_v1 + mat_mult_buffer1_fx_e = 0; +#else /* OPT_BASOP_ADD_v1 */ mat_mult_buffer1_e = 0; +#endif /* OPT_BASOP_ADD_v1 */ move16(); mat_mult_buffer2_e = 0; move16(); +#ifdef OPT_BASOP_ADD_v1 + matrix_product_mant_exp_fx( mat_mult_buffer1_fx, mat_mult_buffer1_fx_e, lengthCy, lengthCx, 0, + mat_mult_buffer2_fx, mat_mult_buffer2_e, lengthCx, lengthCx, 1, + mat_mult_buffer3_fx, &mat_mult_buffer3_e ); +#else /* OPT_BASOP_ADD_v1 */ matrix_product_mant_exp_fx( mat_mult_buffer1_fx, mat_mult_buffer1_e, lengthCy, lengthCx, 0, mat_mult_buffer2_fx, mat_mult_buffer2_e, lengthCx, lengthCx, 1, mat_mult_buffer3_fx, &mat_mult_buffer3_e ); +#endif /* OPT_BASOP_ADD_v1 */ /************************ Formulate M **********************/ +#ifdef OPT_BASOP_ADD_v1 + matrix_product_mant_exp_fx( Ky_fx, Ky_fx_e[0], lengthCy, lengthCy, 0, mat_mult_buffer3_fx, mat_mult_buffer3_e, lengthCy, lengthCx, 0, mat_mult_buffer1_fx, &mat_mult_buffer1_fx_e ); +#else /* OPT_BASOP_ADD_v1 */ Word16 mat_mult_buffer3_fx_e[MAX_OUTPUT_CHANNELS * MAX_OUTPUT_CHANNELS]; set16_fx( mat_mult_buffer3_fx_e, mat_mult_buffer3_e, MAX_OUTPUT_CHANNELS * MAX_OUTPUT_CHANNELS ); matrix_product_mant_exp( Ky_fx, Ky_fx_e, lengthCy, lengthCy, 0, mat_mult_buffer3_fx, mat_mult_buffer3_fx_e, lengthCy, lengthCx, 0, mat_mult_buffer1_fx, mat_mult_buffer1_fx_e ); +#endif /* OPT_BASOP_ADD_v1 */ Word16 mixing_matrix_fx_e[MAX_CICP_CHANNELS * PARAM_MC_MAX_TRANSPORT_CHANS]; +#ifdef OPT_BASOP_ADD_v1 + Word16 mat_mult_buffer1_fx_e1[MAX_OUTPUT_CHANNELS * MAX_OUTPUT_CHANNELS]; + set16_fx( mat_mult_buffer1_fx_e1, mat_mult_buffer1_fx_e, MAX_OUTPUT_CHANNELS * MAX_OUTPUT_CHANNELS ); + + matrix_product_mant_exp( mat_mult_buffer1_fx, mat_mult_buffer1_fx_e1, lengthCy, lengthCx, 0, Kx_reg_inv_fx, Kx_reg_inv_e, lengthCx, lengthCx, 0, mixing_matrix_fx, mixing_matrix_fx_e ); +#else /* OPT_BASOP_ADD_v1 */ matrix_product_mant_exp( mat_mult_buffer1_fx, mat_mult_buffer1_fx_e, lengthCy, lengthCx, 0, Kx_reg_inv_fx, Kx_reg_inv_e, lengthCx, lengthCx, 0, mixing_matrix_fx, mixing_matrix_fx_e ); +#endif /* OPT_BASOP_ADD_v1 */ /*-----------------------------------------------------------------* * Formulate Cr @@ -1053,9 +1096,15 @@ Word16 computeMixingMatrices_fx( Word16 Cx_e_arr[PARAM_MC_MAX_TRANSPORT_CHANS * PARAM_MC_MAX_TRANSPORT_CHANS]; set16_fx( Cx_e_arr, Cx_fx_e, PARAM_MC_MAX_TRANSPORT_CHANS * PARAM_MC_MAX_TRANSPORT_CHANS ); +#ifdef OPT_BASOP_ADD_v1 + matrix_product_mant_exp( mixing_matrix_fx, mixing_matrix_fx_e, lengthCy, lengthCx, 0, Cx_fx, Cx_e_arr, lengthCx, lengthCx, 0, mat_mult_buffer1_fx, mat_mult_buffer1_fx_e1 ); + + matrix_product_mant_exp( mat_mult_buffer1_fx, mat_mult_buffer1_fx_e1, lengthCy, lengthCx, 0, mixing_matrix_fx, mixing_matrix_fx_e, lengthCy, lengthCx, 1, mat_mult_buffer2_fx, mat_mult_buffer2_fx_e ); +#else /* OPT_BASOP_ADD_v1 */ matrix_product_mant_exp( mixing_matrix_fx, mixing_matrix_fx_e, lengthCy, lengthCx, 0, Cx_fx, Cx_e_arr, lengthCx, lengthCx, 0, mat_mult_buffer1_fx, mat_mult_buffer1_fx_e ); matrix_product_mant_exp( mat_mult_buffer1_fx, mat_mult_buffer1_fx_e, lengthCy, lengthCx, 0, mixing_matrix_fx, mixing_matrix_fx_e, lengthCy, lengthCx, 1, mat_mult_buffer2_fx, mat_mult_buffer2_fx_e ); +#endif /* OPT_BASOP_ADD_v1 */ exp = mixing_matrix_fx_e[0]; move16(); @@ -1094,7 +1143,11 @@ Word16 computeMixingMatrices_fx( } /* Avoid Meaningless negative main diagonal elements */ +#ifdef OPT_BASOP_ADD_v1 + IF( Cr_fx[i + ( i * lengthCy )] < 0 ) +#else /* OPT_BASOP_ADD_v1 */ IF( BASOP_Util_Cmp_Mant32Exp( Cr_fx[i + ( i * lengthCy )], exp, 0, 0 ) < 0 ) +#endif /* OPT_BASOP_ADD_v1 */ { Cr_fx[i + ( i * lengthCy )] = 0; move32(); @@ -1156,7 +1209,11 @@ Word16 computeMixingMatrices_fx( { /* Avoid correction for very small energies, main diagonal elements of Cy_tilde_p may be negative */ +#ifdef OPT_BASOP_ADD_v1 + IF( Cy_tilde_p_fx[i + ( i * lengthCy )] < 0 ) +#else /* OPT_BASOP_ADD_v1 */ IF( BASOP_Util_Cmp_Mant32Exp( Cy_tilde_p_fx[i + ( i * lengthCy )], mat_mult_buffer2_e, 0, 0 ) < 0 ) +#endif /* OPT_BASOP_ADD_v1 */ { adj_fx_p[i] = 1073741824; // 1.0f in Q30 move32(); @@ -1175,7 +1232,12 @@ Word16 computeMixingMatrices_fx( move16(); } +#ifdef OPT_BASOP_ADD_v1 + Word32 temp = W_shl_sat_l( W_deposit32_l( 4 ), sub( 31, adj_e[i] ) ); + IF( GT_32( adj_fx_p[i], temp ) ) +#else /* OPT_BASOP_ADD_v1 */ IF( BASOP_Util_Cmp_Mant32Exp( adj_fx_p[i], adj_e[i], 1073741824, 3 ) > 0 ) +#endif /* OPT_BASOP_ADD_v1 */ { adj_fx_p[i] = 1073741824; // 1.0f in Q30 move32(); @@ -1308,6 +1370,9 @@ Word16 computeMixingMatricesResidual_fx( svd_fx( svd_in_buffer_fx, Cy_fx_e, svd_u_buffer_fx, svd_s_buffer_fx, svd_v_buffer_fx, svd_s_buffer_e, lengthCy, lengthCy ); /* Computing Ky */ +#ifdef OPT_BASOP_ADD_v1 + Word16 max_e = -32; +#endif /* OPT_BASOP_ADD_v1 */ FOR( i = 0; i < lengthCy; ++i ) { FOR( j = 0; j < lengthCy; ++j ) @@ -1319,9 +1384,22 @@ Word16 computeMixingMatricesResidual_fx( move32(); Ky_fx_e[i + j * lengthCy] = tmp_e; move16(); +#ifdef OPT_BASOP_ADD_v1 + max_e = s_max( max_e, tmp_e ); +#endif /* OPT_BASOP_ADD_v1 */ } } +#ifdef OPT_BASOP_ADD_v1 + FOR( i = 0; i < lengthCy * lengthCy; ++i ) + { + Ky_fx[i] = L_shr( Ky_fx[i], sub( max_e, Ky_fx_e[i] ) ); + move32(); + Ky_fx_e[i] = max_e; + move16(); + } +#endif /* OPT_BASOP_ADD_v1 */ + /*-----------------------------------------------------------------* * Decomposition of Cx *-----------------------------------------------------------------*/ @@ -1332,7 +1410,9 @@ Word16 computeMixingMatricesResidual_fx( * square root of the diagonal of Cx */ /* Computing Kx */ - +#ifdef OPT_BASOP_ADD_v1 + max_e = -32; +#endif /* OPT_BASOP_ADD_v1 */ FOR( i = 0; i < lengthCx; ++i ) { exp = Cx_e; @@ -1341,24 +1421,46 @@ Word16 computeMixingMatricesResidual_fx( move32(); Kx_fx_e[i] = exp; move16(); +#ifdef OPT_BASOP_ADD_v1 + max_e = s_max( max_e, exp ); +#endif /* OPT_BASOP_ADD_v1 */ } +#ifdef OPT_BASOP_ADD_v1 + FOR( i = 0; i < lengthCx; ++i ) + { + Kx_fx[i] = L_shr( Kx_fx[i], sub( max_e, Kx_fx_e[i] ) ); + move32(); + Kx_fx_e[i] = max_e; + move16(); + } +#endif /* OPT_BASOP_ADD_v1 */ + /*-----------------------------------------------------------------* * Regularization of Sx *-----------------------------------------------------------------*/ limit_fx = Kx_fx[0]; move32(); +#ifndef OPT_BASOP_ADD_v1 limit_e = Kx_fx_e[0]; move16(); +#endif /* OPT_BASOP_ADD_v1 */ + FOR( i = 1; i < lengthCx; i++ ) { +#ifdef OPT_BASOP_ADD_v1 + IF( GT_32( Kx_fx[i], limit_fx ) ) +#else /* OPT_BASOP_ADD_v1 */ IF( BASOP_Util_Cmp_Mant32Exp( Kx_fx[i], Kx_fx_e[i], limit_fx, limit_e ) > 0 ) +#endif /* OPT_BASOP_ADD_v1 */ { limit_fx = Kx_fx[i]; move32(); +#ifndef OPT_BASOP_ADD_v1 limit_e = Kx_fx_e[i]; move16(); +#endif /* OPT_BASOP_ADD_v1 */ } } @@ -1366,7 +1468,11 @@ Word16 computeMixingMatricesResidual_fx( L_tmp = L_add( L_tmp, EPSILLON_FX ); limit_fx = L_tmp; move16(); +#ifdef OPT_BASOP_ADD_v1 + limit_e = add( Kx_fx_e[0], reg_Sx_e ); +#else /* OPT_BASOP_ADD_v1 */ limit_e = add( limit_e, reg_Sx_e ); +#endif /* OPT_BASOP_ADD_v1 */ FOR( i = 0; i < lengthCx; ++i ) { @@ -1515,10 +1621,16 @@ Word16 computeMixingMatricesResidual_fx( * Formulate M *-----------------------------------------------------------------*/ + +#ifdef OPT_BASOP_ADD_v1 + matrix_product_mant_exp_fx( Ky_fx, Ky_fx_e[0], lengthCy, lengthCy, 0, mat_mult_buffer3_fx, mat_mult_buffer3_e, lengthCy, lengthCx, 0, mat_mult_buffer1_fx, mat_mult_buffer1_buff_e ); + set16_fx( mat_mult_buffer1_buff_e, mat_mult_buffer1_buff_e[0], MAX_OUTPUT_CHANNELS * MAX_OUTPUT_CHANNELS ); +#else /* OPT_BASOP_ADD_v1 */ Word16 mat_mult_buffer3_fx_e[MAX_OUTPUT_CHANNELS * MAX_OUTPUT_CHANNELS]; set16_fx( mat_mult_buffer3_fx_e, mat_mult_buffer3_e, MAX_OUTPUT_CHANNELS * MAX_OUTPUT_CHANNELS ); matrix_product_mant_exp( Ky_fx, Ky_fx_e, lengthCy, lengthCy, 0, mat_mult_buffer3_fx, mat_mult_buffer3_fx_e, lengthCy, lengthCx, 0, mat_mult_buffer1_fx, mat_mult_buffer1_buff_e ); +#endif /* OPT_BASOP_ADD_v1 */ Word16 mixing_matrix_fx_e[MAX_CICP_CHANNELS * MAX_CICP_CHANNELS]; @@ -1603,7 +1715,12 @@ Word16 computeMixingMatricesResidual_fx( move32(); adj_buff_e[i] = scale; move16(); +#ifdef OPT_BASOP_ADD_v1 + Word32 temp = W_shl_sat_l( W_deposit32_l( 4 ), sub( 31, scale ) ); + IF( GT_32( adj_fx_p[i], temp ) ) // 1073741824 -> 1.0f in Q30 +#else /* OPT_BASOP_ADD_v1 */ IF( BASOP_Util_Cmp_Mant32Exp( adj_fx_p[i], scale, 1073741824, 3 ) > 0 ) // 1073741824 -> 1.0f in Q30 +#endif /* OPT_BASOP_ADD_v1 */ { adj_fx_p[i] = 1073741824; // 1.0f in Q30 move32(); @@ -1998,7 +2115,12 @@ Word16 computeMixingMatricesISM_fx( } } +#ifdef OPT_BASOP_ADD_v1 + Word32 temp = W_shl_sat_l( W_deposit32_l( 4 ), sub( 31, temp_e[i] ) ); + IF( GT_32( adj_fx[i], temp ) ) +#else /* OPT_BASOP_ADD_v1 */ IF( BASOP_Util_Cmp_Mant32Exp( adj_fx[i], temp_e[i], MAX_32, 2 ) > 0 ) +#endif /* OPT_BASOP_ADD_v1 */ { adj_fx[i] = MAX_32; move32(); diff --git a/lib_dec/ivas_entropy_decoder.c b/lib_dec/ivas_entropy_decoder_fx.c similarity index 99% rename from lib_dec/ivas_entropy_decoder.c rename to lib_dec/ivas_entropy_decoder_fx.c index 5f64c1123903689419f91074f9b266d38ac6d501..f8bf3c0910563b96492446ff76aa581507552b77 100644 --- a/lib_dec/ivas_entropy_decoder.c +++ b/lib_dec/ivas_entropy_decoder_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other @@ -32,13 +32,11 @@ #include #include "options.h" -#include "prot.h" -#include "ivas_prot.h" +#include "prot_fx.h" #include "ivas_cnst.h" #include "ivas_rom_com.h" #include #include "wmc_auto.h" -#include "prot_fx.h" #include "ivas_prot_fx.h" diff --git a/lib_dec/ivas_init_dec.c b/lib_dec/ivas_init_dec.c index 35844b5e53d3dd214665bfcf932501ccb765daaf..cef1e45e90c3543a8c2dc0f49359959eb5b6c919 100644 --- a/lib_dec/ivas_init_dec.c +++ b/lib_dec/ivas_init_dec.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other @@ -35,15 +35,18 @@ #include #include "options.h" #include "ivas_cnst.h" -#include "ivas_prot.h" -#include "ivas_prot_rend.h" +#include "ivas_prot_rend_fx.h" #include "rom_com.h" #include "ivas_rom_com.h" #include "ivas_stat_enc.h" -#include "prot.h" -#include "wmc_auto.h" #include "prot_fx.h" +#include "wmc_auto.h" #include "ivas_prot_fx.h" +#ifdef SPLIT_REND_WITH_HEAD_ROT +#include "lib_isar_pre_rend.h" +#include "isar_prot.h" +#include "isar_stat.h" +#endif /*-------------------------------------------------------------------* @@ -55,6 +58,215 @@ static ivas_error ivas_read_format( Decoder_Struct *st_ivas, Word16 *num_bits_re static ivas_error doSanityChecks_IVAS( Decoder_Struct *st_ivas ); +#ifdef SPLIT_REND_WITH_HEAD_ROT +static ivas_error ivas_dec_reconfig_split_rend( Decoder_Struct *st_ivas ); + + +/*-------------------------------------------------------------------* + * ivas_dec_reconfig_split_rend() + * + * IVAS decoder split rend reconfig + *-------------------------------------------------------------------*/ + +static ivas_error ivas_dec_reconfig_split_rend( + Decoder_Struct *st_ivas /* i : IVAS decoder structure */ +) +{ + ivas_error error; + Word16 cldfb_in_flag, num_ch, ch, isCldfbNeeded, i, pcm_out_flag; + SPLIT_REND_WRAPPER *hSplitRendWrapper; + + hSplitRendWrapper = &st_ivas->hSplitBinRend->splitrend; + move16(); + pcm_out_flag = ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ? 1 : 0; + move16(); + cldfb_in_flag = 0; + move16(); + + IF( EQ_16( st_ivas->renderer_type, RENDERER_BINAURAL_FASTCONV ) || + EQ_16( st_ivas->renderer_type, RENDERER_BINAURAL_FASTCONV_ROOM ) || + EQ_16( st_ivas->renderer_type, RENDERER_BINAURAL_PARAMETRIC ) || + EQ_16( st_ivas->renderer_type, RENDERER_BINAURAL_PARAMETRIC_ROOM ) ) + { + cldfb_in_flag = 1; + move16(); + } + + ISAR_PRE_REND_GetMultiBinPoseData( &st_ivas->hRenderConfig->split_rend_config, &hSplitRendWrapper->multiBinPoseData, ( st_ivas->hHeadTrackData != NULL ) ? st_ivas->hHeadTrackData->sr_pose_pred_axis : DEFAULT_AXIS ); + + isCldfbNeeded = 0; + move16(); + + IF( ( EQ_16( st_ivas->renderer_type, RENDERER_BINAURAL_FASTCONV ) && EQ_16( st_ivas->ivas_format, SBA_ISM_FORMAT ) ) || + ( EQ_16( st_ivas->renderer_type, RENDERER_BINAURAL_PARAMETRIC ) && EQ_16( st_ivas->ivas_format, MASA_ISM_FORMAT ) && EQ_16( st_ivas->ism_mode, ISM_MASA_MODE_DISC ) ) ) + { + cldfb_in_flag = 0; + move16(); + } + + IF( NE_16( st_ivas->renderer_type, RENDERER_DISABLE ) ) + { + IF( EQ_16( cldfb_in_flag, 0 ) ) + { + isCldfbNeeded = 1; + move16(); + } + ELSE IF( EQ_16( st_ivas->hRenderConfig->split_rend_config.codec, ISAR_SPLIT_REND_CODEC_LC3PLUS ) && cldfb_in_flag ) + { + isCldfbNeeded = 1; + move16(); + } + ELSE IF( pcm_out_flag && cldfb_in_flag ) + { + isCldfbNeeded = 1; + move16(); + } + } + ELSE IF( st_ivas->hDecoderConfig->Opt_non_diegetic_pan ) + { + isCldfbNeeded = 1; + move16(); + } + + IF( EQ_16( isCldfbNeeded, 1 ) && hSplitRendWrapper->hCldfbHandles == NULL ) + { + IF( ( hSplitRendWrapper->hCldfbHandles = (CLDFB_HANDLES_WRAPPER_HANDLE) malloc( sizeof( CLDFB_HANDLES_WRAPPER ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for CLDFB handles\n" ) ); + } + + num_ch = i_mult( MAX_HEAD_ROT_POSES, BINAURAL_CHANNELS ); + move16(); + FOR( ch = 0; ch < num_ch; ch++ ) + { + hSplitRendWrapper->hCldfbHandles->cldfbAna[ch] = NULL; + move16(); + } + + num_ch = i_mult( hSplitRendWrapper->multiBinPoseData.num_poses, BINAURAL_CHANNELS ); + move16(); + + FOR( ch = 0; ch < num_ch; ch++ ) + { + IF( ( error = openCldfb_ivas_fx( &( hSplitRendWrapper->hCldfbHandles->cldfbAna[ch] ), CLDFB_ANALYSIS, st_ivas->hDecoderConfig->output_Fs, CLDFB_PROTOTYPE_5_00MS, DEC ) ) != IVAS_ERR_OK ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not open CLDFB handles\n" ) ); + } + } + + FOR( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) + { + if ( ( error = openCldfb_ivas_fx( &( hSplitRendWrapper->hCldfbHandles->cldfbSyn[ch] ), CLDFB_SYNTHESIS, st_ivas->hDecoderConfig->output_Fs, CLDFB_PROTOTYPE_5_00MS, DEC ) ) != IVAS_ERR_OK ) + { + return error; + } + } + } + ELSE IF( EQ_16( isCldfbNeeded, 0 ) && hSplitRendWrapper->hCldfbHandles != NULL ) + { + num_ch = i_mult( MAX_HEAD_ROT_POSES, BINAURAL_CHANNELS ); + move16(); + FOR( ch = 0; ch < num_ch; ch++ ) + { + IF( hSplitRendWrapper->hCldfbHandles->cldfbAna[ch] != NULL ) + { + deleteCldfb_ivas_fx( &hSplitRendWrapper->hCldfbHandles->cldfbAna[ch] ); + hSplitRendWrapper->hCldfbHandles->cldfbAna[ch] = NULL; + move32(); + } + } + + FOR( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) + { + IF( hSplitRendWrapper->hCldfbHandles->cldfbSyn[ch] != NULL ) + { + deleteCldfb_ivas_fx( &hSplitRendWrapper->hCldfbHandles->cldfbSyn[ch] ); + hSplitRendWrapper->hCldfbHandles->cldfbSyn[ch] = NULL; + move32(); + } + } + + free( hSplitRendWrapper->hCldfbHandles ); + hSplitRendWrapper->hCldfbHandles = NULL; + move32(); + } + + IF( ( NE_16( st_ivas->renderer_type, RENDERER_BINAURAL_OBJECTS_TD ) ) && + ( NE_16( st_ivas->renderer_type, RENDERER_BINAURAL_FASTCONV ) || NE_16( st_ivas->ivas_format, SBA_ISM_FORMAT ) ) && + !( EQ_16( st_ivas->renderer_type, RENDERER_BINAURAL_PARAMETRIC ) && EQ_16( st_ivas->ivas_format, MASA_ISM_FORMAT ) && EQ_16( st_ivas->ism_mode, ISM_MASA_MODE_DISC ) ) ) /* td-rend not needed? */ + { + FOR( i = 0; i < MAX_HEAD_ROT_POSES - 1; ++i ) + { + IF( st_ivas->hTdRendHandles[i] != NULL ) + { + st_ivas->hTdRendHandles[i]->HrFiltSet_p = NULL; + move32(); + ivas_td_binaural_close_fx( &st_ivas->hTdRendHandles[i] ); + } + } + } + + return IVAS_ERR_OK; +} + + +/*-------------------------------------------------------------------* + * ivas_dec_init_split_rend() + * + * IVAS decoder split rend init + *-------------------------------------------------------------------*/ + +static ivas_error ivas_dec_init_split_rend( + Decoder_Struct *st_ivas /* i : IVAS decoder structure */ +) +{ + ivas_error error; + Word16 cldfb_in_flag, pcm_out_flag; + Word16 mixed_td_cldfb_flag; + + pcm_out_flag = ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ? 1 : 0; + cldfb_in_flag = 0; + move16(); + + IF( EQ_16( st_ivas->renderer_type, RENDERER_BINAURAL_FASTCONV ) || + EQ_16( st_ivas->renderer_type, RENDERER_BINAURAL_FASTCONV_ROOM ) || + EQ_16( st_ivas->renderer_type, RENDERER_BINAURAL_PARAMETRIC ) || + EQ_16( st_ivas->renderer_type, RENDERER_BINAURAL_PARAMETRIC_ROOM ) ) + { + cldfb_in_flag = 1; + move16(); + } + + ISAR_PRE_REND_GetMultiBinPoseData( &st_ivas->hRenderConfig->split_rend_config, &st_ivas->hSplitBinRend->splitrend.multiBinPoseData, ( st_ivas->hHeadTrackData != NULL ) ? st_ivas->hHeadTrackData->sr_pose_pred_axis : DEFAULT_AXIS ); + + IF( EQ_16( cldfb_in_flag, 1 ) && ( EQ_16( st_ivas->hSplitBinRend->splitrend.multiBinPoseData.poseCorrectionMode, ISAR_SPLIT_REND_POSE_CORRECTION_MODE_NONE ) ) ) + { + IF( ( st_ivas->hSplitBinRend->hCldfbDataOut = (ISAR_DEC_SPLIT_REND_CLDFB_OUT_DATA_HANDLE) malloc( sizeof( ISAR_DEC_SPLIT_REND_CLDFB_OUT_DATA ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for cldfb data out buffer\n" ) ); + } + } + + mixed_td_cldfb_flag = 0; + move16(); + IF( ( EQ_16( st_ivas->renderer_type, RENDERER_BINAURAL_FASTCONV ) && EQ_16( st_ivas->ivas_format, SBA_ISM_FORMAT ) ) || + ( EQ_16( st_ivas->renderer_type, RENDERER_BINAURAL_PARAMETRIC ) && EQ_16( st_ivas->ivas_format, MASA_ISM_FORMAT ) && EQ_16( st_ivas->ism_mode, ISM_MASA_MODE_DISC ) ) ) + { + mixed_td_cldfb_flag = 1; + move16(); + } + +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + error = ISAR_PRE_REND_open( &st_ivas->hSplitBinRend->splitrend, &st_ivas->hRenderConfig->split_rend_config, st_ivas->hDecoderConfig->output_Fs, cldfb_in_flag, pcm_out_flag, st_ivas->hDecoderConfig->render_framesize, mixed_td_cldfb_flag ); + move16(); +#else + error = ISAR_PRE_REND_open( &st_ivas->hSplitBinRend->splitrend, &st_ivas->hRenderConfig->split_rend_config, st_ivas->hDecoderConfig->output_Fs, cldfb_in_flag, pcm_out_flag, (int16_t) st_ivas->hDecoderConfig->render_framesize, mixed_td_cldfb_flag ); + move16(); +#endif + return error; +} +#endif + /*-------------------------------------------------------------------* * ivas_dec_setup() * @@ -524,6 +736,20 @@ ivas_error ivas_dec_setup( } +#ifdef SPLIT_REND_WITH_HEAD_ROT + /*-----------------------------------------------------------------* + * reconfig split rendering as renderer might change after bitrate switching + *-----------------------------------------------------------------*/ + + IF( EQ_16( st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) || EQ_16( st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ) + { + if ( ( error = ivas_dec_reconfig_split_rend( st_ivas ) ) != IVAS_ERR_OK ) + { + return error; + } + } +#endif + /*----------------------------------------------------------------* * Reset bitstream pointers *----------------------------------------------------------------*/ @@ -958,7 +1184,12 @@ ivas_error ivas_init_decoder_front( *--------------------------------------------------------------------*/ test(); test(); +#ifdef SPLIT_REND_WITH_HEAD_ROT + IF( EQ_16( st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_BINAURAL ) || EQ_16( st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR ) || EQ_16( st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) || EQ_16( st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) || EQ_16( st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) || + ( EQ_16( st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_STEREO ) && st_ivas->hDecoderConfig->Opt_non_diegetic_pan ) ) +#else IF( EQ_16( st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_BINAURAL ) || EQ_16( st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR ) || EQ_16( st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) ) +#endif { IF( NE_32( ( error = ivas_render_config_open( &( st_ivas->hRenderConfig ) ) ), IVAS_ERR_OK ) ) { @@ -1133,6 +1364,20 @@ ivas_error ivas_init_decoder_fx( } } +#ifdef SPLIT_REND_WITH_HEAD_ROT + /*-----------------------------------------------------------------* + * Initialize binuaral split rendering + *-----------------------------------------------------------------*/ + + IF( st_ivas->hSplitBinRend != NULL && ( EQ_16( st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) || EQ_16( st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) || + ( EQ_16( st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_STEREO ) && st_ivas->hDecoderConfig->Opt_non_diegetic_pan && EQ_16( st_ivas->hRenderConfig->split_rend_config.dof, 0 ) ) ) ) + { + IF( ( error = ivas_dec_init_split_rend( st_ivas ) ) != IVAS_ERR_OK ) + { + return error; + } + } +#endif /*-----------------------------------------------------------------* * Allocate and initialize SCE/CPE and other handles @@ -2034,7 +2279,7 @@ ivas_error ivas_init_decoder_fx( } } - granularity = NS2SA( st_ivas->hDecoderConfig->output_Fs, FRAME_SIZE_NS / MAX_PARAM_SPATIAL_SUBFRAMES ); + granularity = NS2SA_FX2( st_ivas->hDecoderConfig->output_Fs, FRAME_SIZE_NS / MAX_PARAM_SPATIAL_SUBFRAMES ); n_channels_transport_jbm = ivas_jbm_dec_get_num_tc_channels_fx( st_ivas ); @@ -2071,9 +2316,15 @@ ivas_error ivas_init_decoder_fx( } } +#ifdef SPLIT_REND_WITH_HEAD_ROT + IF( NE_32( ( error = ivas_rend_openCrend( &( st_ivas->hCrendWrapper ), st_ivas->intern_config, st_ivas->hDecoderConfig->output_config, + st_ivas->hRenderConfig, st_ivas->hSetOfHRTF, st_ivas->hDecoderConfig->output_Fs, ( st_ivas->hSplitBinRend == NULL ) ? 1 : st_ivas->hSplitBinRend->splitrend.multiBinPoseData.num_poses ) ), + IVAS_ERR_OK ) ) +#else IF( NE_32( ( error = ivas_rend_openCrend( &( st_ivas->hCrendWrapper ), st_ivas->intern_config, st_ivas->hDecoderConfig->output_config, st_ivas->hRenderConfig, st_ivas->hSetOfHRTF, st_ivas->hDecoderConfig->output_Fs ) ), IVAS_ERR_OK ) ) +#endif { return error; } @@ -2237,6 +2488,9 @@ ivas_error ivas_init_decoder_fx( { IF( st_ivas->hBinRenderer->render_lfe ) { +#ifdef SPLIT_REND_WITH_HEAD_ROT + IF( NE_16( st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) && NE_16( st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ) +#endif { /* Account for filterbank delay */ binauralization_delay_ns = L_add( binauralization_delay_ns, IVAS_FB_DEC_DELAY_NS ); @@ -2266,7 +2520,7 @@ ivas_error ivas_init_decoder_fx( FOR( i = 0; i < numCldfbAnalyses; i++ ) { - IF( NE_32( ( error = openCldfb_ivas_fx( &( st_ivas->cldfbAnaDec[i] ), CLDFB_ANALYSIS, output_Fs, CLDFB_PROTOTYPE_5_00MS ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &( st_ivas->cldfbAnaDec[i] ), CLDFB_ANALYSIS, output_Fs, CLDFB_PROTOTYPE_5_00MS, DEC ) ), IVAS_ERR_OK ) ) { return error; } @@ -2278,7 +2532,7 @@ ivas_error ivas_init_decoder_fx( FOR( i = 0; i < numCldfbSyntheses; i++ ) { - IF( NE_32( ( error = openCldfb_ivas_fx( &( st_ivas->cldfbSynDec[i] ), CLDFB_SYNTHESIS, output_Fs, CLDFB_PROTOTYPE_5_00MS ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &( st_ivas->cldfbSynDec[i] ), CLDFB_SYNTHESIS, output_Fs, CLDFB_PROTOTYPE_5_00MS, DEC ) ), IVAS_ERR_OK ) ) { return error; } @@ -2333,7 +2587,7 @@ ivas_error ivas_init_decoder_fx( /* no module has yet open the TC buffer, open a default one */ n_channels_transport_jbm = ivas_jbm_dec_get_num_tc_channels_fx( st_ivas ); - IF( NE_32( ( error = ivas_jbm_dec_tc_buffer_open_fx( st_ivas, ivas_jbm_dec_get_tc_buffer_mode( st_ivas ), n_channels_transport_jbm, n_channels_transport_jbm, n_channels_transport_jbm, NS2SA( st_ivas->hDecoderConfig->output_Fs, CLDFB_SLOT_NS ) ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = ivas_jbm_dec_tc_buffer_open_fx( st_ivas, ivas_jbm_dec_get_tc_buffer_mode( st_ivas ), n_channels_transport_jbm, n_channels_transport_jbm, n_channels_transport_jbm, NS2SA_FX2( st_ivas->hDecoderConfig->output_Fs, CLDFB_SLOT_NS ) ) ), IVAS_ERR_OK ) ) { return error; } @@ -2586,7 +2840,14 @@ void ivas_initialize_handles_dec( /* rendering handles */ st_ivas->hBinRenderer = NULL; +#ifdef SPLIT_REND_WITH_HEAD_ROT + for ( i = 0; i < MAX_HEAD_ROT_POSES; i++ ) + { + st_ivas->hDiracDecBin[i] = NULL; + } +#else st_ivas->hDiracDecBin = NULL; +#endif st_ivas->hDirACRend = NULL; st_ivas->hSpatParamRendCom = NULL; st_ivas->hLsSetUpConversion = NULL; @@ -2611,7 +2872,13 @@ void ivas_initialize_handles_dec( st_ivas->hExtOrientationData = NULL; st_ivas->hCombinedOrientationData = NULL; - +#ifdef SPLIT_REND_WITH_HEAD_ROT + st_ivas->hSplitBinRend = NULL; + for ( i = 0; i < MAX_HEAD_ROT_POSES - 1; ++i ) + { + st_ivas->hTdRendHandles[i] = NULL; + } +#endif /* JBM handles */ st_ivas->hTcBuffer = NULL; st_ivas->hJbmMetadata = NULL; @@ -2748,12 +3015,31 @@ void ivas_destroy_dec_fx( /* Fastconv binaural renderer handle */ ivas_binRenderer_close_fx( &st_ivas->hBinRenderer ); +#ifdef SPLIT_REND_WITH_HEAD_ROT + /* TD binaural renderer handles */ + for ( i = 0; i < MAX_HEAD_ROT_POSES - 1; ++i ) + { + if ( st_ivas->hTdRendHandles[i] != NULL ) + { + st_ivas->hTdRendHandles[i]->HrFiltSet_p = NULL; + ivas_td_binaural_close_fx( &st_ivas->hTdRendHandles[i] ); + } + } +#endif + /* Parametric binaural renderer handle */ +#ifdef SPLIT_REND_WITH_HEAD_ROT + ivas_dirac_dec_close_binaural_data( st_ivas->hDiracDecBin ); +#else ivas_dirac_dec_close_binaural_data( &st_ivas->hDiracDecBin ); +#endif /* Crend handle */ - +#ifdef SPLIT_REND_WITH_HEAD_ROT + ivas_rend_closeCrend( &( st_ivas->hCrendWrapper ), ( st_ivas->hSplitBinRend == NULL ) ? 1 : st_ivas->hSplitBinRend->splitrend.multiBinPoseData.num_poses ); +#else ivas_rend_closeCrend( &( st_ivas->hCrendWrapper ) ); +#endif /* Reverb handle */ ivas_reverb_close( &st_ivas->hReverb ); @@ -2919,7 +3205,12 @@ void ivas_init_dec_get_num_cldfb_instances( move16(); } } + +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( st_ivas->hDiracDecBin[0]->useTdDecorr ) +#else IF( st_ivas->hDiracDecBin->useTdDecorr ) +#endif { *numCldfbAnalyses = add( *numCldfbAnalyses, 2 ); move16(); @@ -3206,12 +3497,22 @@ static ivas_error doSanityChecks_IVAS( } } +#ifdef SPLIT_REND_WITH_HEAD_ROT + IF( ( EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) || EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ) && NE_32( output_Fs, 48000 ) ) + { + return IVAS_ERROR( IVAS_ERR_INVALID_SAMPLING_RATE, "Error: Only 48kHz output sampling rate is supported for split rendering." ); + } +#endif IF( st_ivas->hDecoderConfig->Opt_Headrotation ) { test(); test(); +#ifdef SPLIT_REND_WITH_HEAD_ROT + IF( !( EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL ) || EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR ) || EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) || EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) || EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ) ) +#else IF( !( EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL ) || EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR ) || EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) ) ) +#endif { return IVAS_ERROR( IVAS_ERR_HEAD_ROTATION_NOT_SUPPORTED, "Wrong set-up: Head-rotation not supported in this configuration" ); } diff --git a/lib_dec/ivas_init_dec_fx.c b/lib_dec/ivas_init_dec_fx.c index b0dbe97b4234bd4e2f96ab6440d0e36bd4f2cc10..47b17aa966f20831df65941e63265300acfcccb8 100644 --- a/lib_dec/ivas_init_dec_fx.c +++ b/lib_dec/ivas_init_dec_fx.c @@ -60,7 +60,11 @@ void ivas_init_dec_get_num_cldfb_instances_ivas_fx( move16(); } } +#ifdef SPLIT_REND_WITH_HEAD_ROT + IF( st_ivas->hDiracDecBin[0]->useTdDecorr ) +#else IF( st_ivas->hDiracDecBin->useTdDecorr ) +#endif { *numCldfbAnalyses = add( *numCldfbAnalyses, 2 ); move16(); diff --git a/lib_dec/ivas_ism_dec.c b/lib_dec/ivas_ism_dec_fx.c similarity index 92% rename from lib_dec/ivas_ism_dec.c rename to lib_dec/ivas_ism_dec_fx.c index a5f7f7b06ff1223ef66e62eb8d8786967a715773..18c6953f282aaab2cb794776bdea986e0c5aafe9 100644 --- a/lib_dec/ivas_ism_dec.c +++ b/lib_dec/ivas_ism_dec_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other @@ -32,13 +32,11 @@ #include #include "options.h" -#include "prot.h" -#include "ivas_prot.h" +#include "prot_fx.h" #include "ivas_prot_fx.h" -#include "ivas_prot_rend.h" +#include "ivas_prot_rend_fx.h" #include "wmc_auto.h" #include "ivas_prot_fx.h" -#include "prot_fx.h" /*-------------------------------------------------------------------------* @@ -198,10 +196,18 @@ static ivas_error ivas_ism_bitrate_switching_dec_fx( ivas_param_ism_dec_close_fx( &( st_ivas->hParamIsmDec ), &( st_ivas->hSpatParamRendCom ), st_ivas->hDecoderConfig->output_config ); test(); +#ifdef SPLIT_REND_WITH_HEAD_ROT + IF( EQ_32( st_ivas->hOutSetup.output_config, IVAS_AUDIO_CONFIG_BINAURAL ) || EQ_32( st_ivas->hOutSetup.output_config, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) || EQ_32( st_ivas->hOutSetup.output_config, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) || EQ_32( st_ivas->hOutSetup.output_config, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ) +#else IF( EQ_32( st_ivas->hOutSetup.output_config, IVAS_AUDIO_CONFIG_BINAURAL ) || EQ_32( st_ivas->hOutSetup.output_config, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) ) +#endif { /* close the parametric binaural renderer */ +#ifdef SPLIT_REND_WITH_HEAD_ROT + ivas_dirac_dec_close_binaural_data( st_ivas->hDiracDecBin ); +#else ivas_dirac_dec_close_binaural_data( &st_ivas->hDiracDecBin ); +#endif /* Open the TD Binaural renderer */ test(); IF( st_ivas->hHrtfTD == NULL || st_ivas->hBinRendererTd == NULL ) @@ -234,13 +240,24 @@ static ivas_error ivas_ism_bitrate_switching_dec_fx( IF( EQ_32( st_ivas->hOutSetup.output_config, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR ) ) { /* close the parametric binaural renderer */ +#ifdef SPLIT_REND_WITH_HEAD_ROT + ivas_dirac_dec_close_binaural_data( st_ivas->hDiracDecBin ); +#else ivas_dirac_dec_close_binaural_data( &st_ivas->hDiracDecBin ); +#endif /* Open Crend Binaural renderer */ +#ifdef SPLIT_REND_WITH_HEAD_ROT + IF( NE_32( ( error = ivas_rend_openCrend( &( st_ivas->hCrendWrapper ), st_ivas->intern_config, st_ivas->hOutSetup.output_config, st_ivas->hRenderConfig, st_ivas->hSetOfHRTF, st_ivas->hDecoderConfig->output_Fs, ( st_ivas->hSplitBinRend == NULL ) ? 1 : st_ivas->hSplitBinRend->splitrend.multiBinPoseData.num_poses ) ), IVAS_ERR_OK ) ) + { + return error; + } +#else IF( NE_32( ( error = ivas_rend_openCrend( &( st_ivas->hCrendWrapper ), st_ivas->intern_config, st_ivas->hOutSetup.output_config, st_ivas->hRenderConfig, st_ivas->hSetOfHRTF, st_ivas->hDecoderConfig->output_Fs ) ), IVAS_ERR_OK ) ) { return error; } +#endif st_ivas->binaural_latency_ns = st_ivas->hCrendWrapper->binaural_latency_ns; move32(); @@ -258,7 +275,11 @@ static ivas_error ivas_ism_bitrate_switching_dec_fx( } test(); +#ifdef SPLIT_REND_WITH_HEAD_ROT + IF( EQ_32( st_ivas->hOutSetup.output_config, IVAS_AUDIO_CONFIG_BINAURAL ) || EQ_32( st_ivas->hOutSetup.output_config, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) || EQ_32( st_ivas->hOutSetup.output_config, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) || EQ_32( st_ivas->hOutSetup.output_config, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ) +#else IF( EQ_32( st_ivas->hOutSetup.output_config, IVAS_AUDIO_CONFIG_BINAURAL ) || EQ_32( st_ivas->hOutSetup.output_config, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) ) +#endif { /* open the parametric binaural renderer */ IF( NE_32( ( error = ivas_dirac_dec_binaural_copy_hrtfs_fx( &st_ivas->hHrtfParambin ) ), IVAS_ERR_OK ) ) @@ -303,7 +324,11 @@ static ivas_error ivas_ism_bitrate_switching_dec_fx( } /* close the crend binaural renderer */ +#ifdef SPLIT_REND_WITH_HEAD_ROT + ivas_rend_closeCrend( &( st_ivas->hCrendWrapper ), ( st_ivas->hSplitBinRend == NULL ) ? 1 : st_ivas->hSplitBinRend->splitrend.multiBinPoseData.num_poses ); +#else ivas_rend_closeCrend( &( st_ivas->hCrendWrapper ) ); +#endif } } diff --git a/lib_dec/ivas_ism_dtx_dec.c b/lib_dec/ivas_ism_dtx_dec_fx.c similarity index 98% rename from lib_dec/ivas_ism_dtx_dec.c rename to lib_dec/ivas_ism_dtx_dec_fx.c index 106653e485a1d7113d94722008e767aa97bc248f..0f023a7efd080f499328b709895092c92b8c95fc 100644 --- a/lib_dec/ivas_ism_dtx_dec.c +++ b/lib_dec/ivas_ism_dtx_dec_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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,12 +33,10 @@ #include #include #include "options.h" -#include "ivas_prot.h" #include "ivas_prot_fx.h" -#include "prot.h" +#include "prot_fx.h" #include "wmc_auto.h" -#include "prot_fx.h" /*-------------------------------------------------------------------* * ivas_ism_dtx_dec_fx() diff --git a/lib_dec/ivas_ism_metadata_dec.c b/lib_dec/ivas_ism_metadata_dec_fx.c similarity index 99% rename from lib_dec/ivas_ism_metadata_dec.c rename to lib_dec/ivas_ism_metadata_dec_fx.c index ae33f2794101fa1416ca967ccf0fdf0aadae23e5..3288903ab8f43b3b9cb00c03a44abb6b904cfbcc 100644 --- a/lib_dec/ivas_ism_metadata_dec.c +++ b/lib_dec/ivas_ism_metadata_dec_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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,11 +33,9 @@ #include #include "options.h" #include "ivas_cnst.h" -#include "ivas_prot.h" #include "ivas_prot_fx.h" #include "ivas_rom_com.h" #include "ivas_rom_com_fx.h" -#include "prot.h" #include "prot_fx.h" #include "ivas_stat_enc.h" #include diff --git a/lib_dec/ivas_ism_param_dec.c b/lib_dec/ivas_ism_param_dec_fx.c similarity index 95% rename from lib_dec/ivas_ism_param_dec.c rename to lib_dec/ivas_ism_param_dec_fx.c index 9514e5e2a13cf92647264eae718bfc698d9789ff..9ef1c192cb09c5ce14212e137f68b91d3459d91f 100644 --- a/lib_dec/ivas_ism_param_dec.c +++ b/lib_dec/ivas_ism_param_dec_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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,15 +34,13 @@ #include #include #include "options.h" -#include "ivas_prot.h" -#include "ivas_prot_rend.h" -#include "prot.h" +#include "ivas_prot_rend_fx.h" +#include "prot_fx.h" #include "rom_com.h" #include "ivas_rom_com.h" #include "ivas_rom_dec.h" #include "wmc_auto.h" #include "ivas_prot_fx.h" -#include "prot_fx.h" #include "debug.h" #include "ivas_rom_com_fx.h" @@ -176,26 +174,16 @@ static void ivas_param_ism_collect_slot_fx( Word32 *Cldfb_ImagBuffer_in_fx, /*Q(31-exp_imag)*/ Word16 exp_imag, const Word16 ch, - Word32 ref_power_fx[], /*Q(31-exp_ref_power)*/ - Word16 *exp_ref_power, Word32 cx_diag_fx[][PARAM_ISM_MAX_DMX], /*Q(31-exp_cx_diag)*/ - Word16 *exp_cx_diag ) + Word16 exp_cx_diag[][PARAM_ISM_MAX_DMX] ) { Word16 band_idx, bin_idx; Word16 brange[2]; Word32 tmp_fx; Word16 exp_tmp; - Word16 i, j; /* loop over parameter bands to collect transport channel energies */ - Word16 exp_ref_power_buf[CLDFB_NO_CHANNELS_MAX]; - Word16 exp_cx_diag_buf[CLDFB_NO_CHANNELS_MAX][PARAM_ISM_MAX_DMX]; - set16_fx( exp_ref_power_buf, *exp_ref_power, CLDFB_NO_CHANNELS_MAX ); - FOR( i = 0; i < CLDFB_NO_CHANNELS_MAX; i++ ) - { - set16_fx( exp_cx_diag_buf[i], *exp_cx_diag, PARAM_ISM_MAX_DMX ); - } FOR( band_idx = 0; band_idx < hParamIsmDec->hParamIsm->nbands; band_idx++ ) { brange[0] = hParamIsmDec->hParamIsm->band_grouping[band_idx]; @@ -213,53 +201,18 @@ static void ivas_param_ism_collect_slot_fx( tmp_fx = BASOP_Util_Add_Mant32Exp( tmp_fx, exp_tmp, var1, add( exp_real, exp_real ), &exp_tmp ); tmp_fx = BASOP_Util_Add_Mant32Exp( tmp_fx, exp_tmp, var2, add( exp_imag, exp_imag ), &exp_tmp ); - Word16 exp_cx_diag_new = 0, exp_ref_power_new = 0; + Word16 exp_cx_diag_new; move16(); move16(); - cx_diag_fx[bin_idx][ch] = BASOP_Util_Add_Mant32Exp( cx_diag_fx[bin_idx][ch], exp_cx_diag_buf[bin_idx][ch], tmp_fx, exp_tmp, &exp_cx_diag_new ); - move32(); - ref_power_fx[bin_idx] = BASOP_Util_Add_Mant32Exp( ref_power_fx[bin_idx], exp_ref_power_buf[bin_idx], tmp_fx, exp_tmp, &exp_ref_power_new ); + cx_diag_fx[bin_idx][ch] = BASOP_Util_Add_Mant32Exp( cx_diag_fx[bin_idx][ch], exp_cx_diag[bin_idx][ch], tmp_fx, exp_tmp, &exp_cx_diag_new ); move32(); - exp_cx_diag_buf[bin_idx][ch] = exp_cx_diag_new; - move16(); - exp_ref_power_buf[bin_idx] = exp_ref_power_new; + exp_cx_diag[bin_idx][ch] = exp_cx_diag_new; move16(); } } - - /*make common exponent*/ - Word16 max_exp_cx_diag = exp_cx_diag_buf[0][0], max_exp_ref_power = exp_ref_power_buf[0]; - move16(); - move16(); - FOR( i = 0; i < CLDFB_NO_CHANNELS_MAX; i++ ) - { - FOR( j = 0; j < PARAM_ISM_MAX_DMX; j++ ) - { - max_exp_cx_diag = s_max( max_exp_cx_diag, exp_cx_diag_buf[i][j] ); - } - max_exp_ref_power = s_max( max_exp_ref_power, exp_ref_power_buf[i] ); - } - - FOR( i = 0; i < CLDFB_NO_CHANNELS_MAX; i++ ) - { - FOR( j = 0; j < PARAM_ISM_MAX_DMX; j++ ) - { - cx_diag_fx[i][j] = L_shr_r( cx_diag_fx[i][j], sub( max_exp_cx_diag, exp_cx_diag_buf[i][j] ) ); // Q(31-max_exp_cx_diag) - move32(); - } - ref_power_fx[i] = L_shr_r( ref_power_fx[i], sub( max_exp_ref_power, exp_ref_power_buf[i] ) ); // Q(31-max_exp_ref_power) - move16(); - } - - *exp_cx_diag = max_exp_cx_diag; - move16(); - *exp_ref_power = max_exp_ref_power; - move16(); - return; } - static void ivas_param_ism_compute_mixing_matrix_fx( const Word16 nchan_ism, /* i : number of ISM channels */ PARAM_ISM_DEC_HANDLE hParamIsmDec, /* i/o: decoder ParamISM handle */ @@ -268,9 +221,7 @@ static void ivas_param_ism_compute_mixing_matrix_fx( const Word16 nchan_transport, const Word16 nchan_out_woLFE, Word32 cx_diag_fx[][PARAM_ISM_MAX_DMX], /*Q(31-cx_diag_e)*/ - Word16 cx_diag_e, - Word32 ref_power_fx[], /*Q(31-ref_power_e)*/ - Word16 ref_power_e, + Word16 cx_diag_e[][PARAM_ISM_MAX_DMX], Word32 mixing_matrix_fx[CLDFB_NO_CHANNELS_MAX][PARAM_ISM_MAX_CHAN * PARAM_ISM_MAX_DMX], /*Q(31-mixing_matrix_e)*/ Word16 mixing_matrix_e[CLDFB_NO_CHANNELS_MAX] ) { @@ -343,6 +294,27 @@ static void ivas_param_ism_compute_mixing_matrix_fx( set32_fx( cy_diag_fx, 0, nchan_out_woLFE ); set16_fx( cy_diag_e_arr, 0, nchan_out_woLFE ); + + /* equal cx diag exponents, compute ref power from cx_diag*/ + Word16 max_exp_cx_diag; + Word32 cx_diag_eq_exp_fx[PARAM_ISM_MAX_DMX]; + Word32 ref_power_fx; + Word16 ref_power_e, ref_power_e_new; + ref_power_fx = cx_diag_fx[bin_idx][0]; + ref_power_e = cx_diag_e[bin_idx][0]; + + FOR( i = 1; i < PARAM_ISM_MAX_DMX; i++ ) + { + ref_power_fx = BASOP_Util_Add_Mant32Exp( ref_power_fx, ref_power_e, cx_diag_fx[bin_idx][i], cx_diag_e[bin_idx][i], &ref_power_e_new ); + ref_power_e = ref_power_e_new; + } + max_exp_cx_diag = ref_power_e; + FOR( i = 0; i < PARAM_ISM_MAX_DMX; i++ ) + { + cx_diag_eq_exp_fx[i] = L_shr_r( cx_diag_fx[bin_idx][i], sub( max_exp_cx_diag, cx_diag_e[bin_idx][i] ) ); // Q(31-max_exp_cx_diag) + } + + FOR( w = 0; w < num_wave; w++ ) { test(); @@ -352,24 +324,25 @@ static void ivas_param_ism_compute_mixing_matrix_fx( SWITCH( nchan_ism ) { case 2: - direct_power_fx[w] = L_shr_r( ref_power_fx[bin_idx], 1 ); + direct_power_fx[w] = L_shr_r( ref_power_fx, 1 ); move32(); BREAK; case 3: - direct_power_fx[w] = Mpy_32_16_1( ref_power_fx[bin_idx], 10923 ); // 10923 = 1/3f in Q15 + direct_power_fx[w] = Mpy_32_16_1( ref_power_fx, 10923 ); // 10923 = 1/3f in Q15 move32(); BREAK; case 4: - direct_power_fx[w] = L_shr_r( ref_power_fx[bin_idx], 2 ); + direct_power_fx[w] = L_shr_r( ref_power_fx, 2 ); move32(); BREAK; } } ELSE { - direct_power_fx[w] = Mpy_32_16_1( ref_power_fx[bin_idx], hParamIsmDec->power_ratios_fx[band_idx][0][w] ); // Q(31-ref_power_e) + direct_power_fx[w] = Mpy_32_16_1( ref_power_fx, hParamIsmDec->power_ratios_fx[band_idx][0][w] ); // Q(31-ref_power_e[bin_idx]) move32(); } + // direct_power_e = ref_power_e[bin_idx]; direct_power_e = ref_power_e; move16(); IF( direct_power_fx[w] != 0 ) @@ -410,7 +383,7 @@ static void ivas_param_ism_compute_mixing_matrix_fx( } /* Compute mixing matrix */ - computeMixingMatricesISM_fx( nchan_transport, num_wave, nchan_out_woLFE, response_matrix_fx, response_matrix_e, direct_power_fx, direct_power_e, cx_diag_fx[bin_idx], cx_diag_e, cy_diag_fx, cy_diag_e, proto_matrix_fx, 1, + computeMixingMatricesISM_fx( nchan_transport, num_wave, nchan_out_woLFE, response_matrix_fx, response_matrix_e, direct_power_fx, direct_power_e, cx_diag_eq_exp_fx, max_exp_cx_diag, cy_diag_fx, cy_diag_e, proto_matrix_fx, 1, PARAM_MC_REG_SX_FX, PARAM_MC_REG_GHAT_FX, mixing_matrix_fx[bin_idx], &mixing_matrix_e[bin_idx] ); } } @@ -556,7 +529,11 @@ static ivas_error ivas_param_ism_rendering_init_fx( test(); test(); test(); +#ifdef SPLIT_REND_WITH_HEAD_ROT + IF( !( EQ_32( output_config, IVAS_AUDIO_CONFIG_EXTERNAL ) || EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL ) || EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR ) || EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) || EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) || EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ) ) +#else IF( !( EQ_32( output_config, IVAS_AUDIO_CONFIG_EXTERNAL ) || EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL ) || EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR ) || EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) ) ) +#endif { /* computation of proto matrix */ ivas_ism_get_proto_matrix_fx( hOutSetup, nchan_transport, hParamIsmRendering->proto_matrix_fx ); @@ -733,8 +710,13 @@ ivas_error ivas_param_ism_dec_open_fx( test(); test(); test(); +#ifdef SPLIT_REND_WITH_HEAD_ROT + IF( !( EQ_32( output_config, IVAS_AUDIO_CONFIG_EXTERNAL ) || EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL ) || EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR ) || EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) || + EQ_32( output_config, IVAS_AUDIO_CONFIG_MONO ) || EQ_32( output_config, IVAS_AUDIO_CONFIG_STEREO ) || EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) || EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ) ) +#else IF( !( EQ_32( output_config, IVAS_AUDIO_CONFIG_EXTERNAL ) || EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL ) || EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR ) || EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) || EQ_32( output_config, IVAS_AUDIO_CONFIG_MONO ) || EQ_32( output_config, IVAS_AUDIO_CONFIG_STEREO ) ) ) +#endif { /* Initialize efap handle */ IF( NE_32( ( error = efap_init_data_fx( &( st_ivas->hEFAPdata ), hOutSetup.ls_azimuth_fx, hOutSetup.ls_elevation_fx, hOutSetup.nchan_out_woLFE, EFAP_MODE_EFAP ) ), IVAS_ERR_OK ) ) @@ -757,7 +739,11 @@ ivas_error ivas_param_ism_dec_open_fx( test(); test(); +#ifdef SPLIT_REND_WITH_HEAD_ROT + IF( EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL ) || EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR ) || EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) || EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) || EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ) +#else IF( EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL ) || EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR ) || EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) ) +#endif { IF( NE_32( ( error = ivas_dirac_allocate_parameters_fx( hSpatParamRendCom, 1 ) ), IVAS_ERR_OK ) ) { @@ -822,7 +808,6 @@ ivas_error ivas_param_ism_dec_open_fx( IF( st_ivas->hTcBuffer == NULL ) { - move16(); // NS2SA IF( NE_32( ( error = ivas_jbm_dec_tc_buffer_open_fx( st_ivas, TC_BUFFER_MODE_RENDERER, nchan_transport, nchan_transport, nchan_full, NS2SA_FX2( st_ivas->hDecoderConfig->output_Fs, CLDFB_SLOT_NS ) ) ), IVAS_ERR_OK ) ) { @@ -1070,14 +1055,14 @@ void ivas_param_ism_dec_digest_tc_fx( Word32 *transport_channels[], /* i : synthesized core-coder transport channels/DirAC output q_tc_in*/ Word16 q_tc_in ) { - Word16 exp_ref_power = 31, exp_cx_diag = 31; Word16 exp_real_tmp = 0, exp_imag_tmp = 0; move16(); move16(); move16(); move16(); - Word32 ref_power_fx[CLDFB_NO_CHANNELS_MAX]; Word32 cx_diag_fx[CLDFB_NO_CHANNELS_MAX][PARAM_ISM_MAX_DMX]; + Word16 exp_cx_diag[CLDFB_NO_CHANNELS_MAX][PARAM_ISM_MAX_DMX]; + Word16 q_tc = q_tc_in; move16(); Word16 ch, nchan_transport, nchan_out, nchan_out_woLFE, i; @@ -1132,15 +1117,8 @@ void ivas_param_ism_dec_digest_tc_fx( ivas_dirac_dec_set_md_map_fx( st_ivas, nCldfbSlots ); /* set buffers to zero */ - FOR( bin_idx = 0; bin_idx < CLDFB_NO_CHANNELS_MAX; bin_idx++ ) - { - set_zero_fx( cx_diag_fx[bin_idx], PARAM_ISM_MAX_DMX ); - } - exp_cx_diag = 0; - move16(); - set_zero_fx( ref_power_fx, CLDFB_NO_CHANNELS_MAX ); - exp_ref_power = 0; - move16(); + set_zero_fx( &cx_diag_fx[0][0], CLDFB_NO_CHANNELS_MAX * PARAM_ISM_MAX_DMX ); + set16_zero_fx( &exp_cx_diag[0][0], CLDFB_NO_CHANNELS_MAX * PARAM_ISM_MAX_DMX ); /* Frame-level Processing */ /* De-quantization */ @@ -1269,7 +1247,7 @@ void ivas_param_ism_dec_digest_tc_fx( &hParamIsmDec->hParamIsmRendering->Cldfb_ImagBuffer_tc_fx[current_idx], exp_imag_tmp, ch, - ref_power_fx, &exp_ref_power, cx_diag_fx, &exp_cx_diag ); + cx_diag_fx, exp_cx_diag ); exp_real_tmp = add( exp_real_tmp, scale_factor_real ); exp_imag_tmp = add( exp_imag_tmp, scale_factor_imag ); @@ -1284,7 +1262,7 @@ void ivas_param_ism_dec_digest_tc_fx( } /* Compute mixing matrix */ - ivas_param_ism_compute_mixing_matrix_fx( st_ivas->nchan_ism, hParamIsmDec, st_ivas->hISMDTX, direct_response_fx, nchan_transport, nchan_out_woLFE, cx_diag_fx, exp_cx_diag, ref_power_fx, exp_ref_power, + ivas_param_ism_compute_mixing_matrix_fx( st_ivas->nchan_ism, hParamIsmDec, st_ivas->hISMDTX, direct_response_fx, nchan_transport, nchan_out_woLFE, cx_diag_fx, exp_cx_diag, hParamIsmDec->hParamIsmRendering->mixing_matrix_lin_fx, hParamIsmDec->hParamIsmRendering->exp_mixing_matrix_lin_fx ); pop_wmops(); @@ -1462,9 +1440,9 @@ void ivas_ism_param_dec_tc_gain_ajust_fx( static void ivas_ism_param_dec_render_sf_fx( Decoder_Struct *st_ivas, IVAS_OUTPUT_SETUP hSetup, - const int16_t nchan_transport, - const int16_t nchan_out, - const int16_t nchan_out_woLFE, + const Word16 nchan_transport, + const Word16 nchan_out, + const Word16 nchan_out_woLFE, Word32 *output_f_fx[], /*Q_output*/ Word16 Q_output[] ) { diff --git a/lib_dec/ivas_ism_renderer.c b/lib_dec/ivas_ism_renderer_fx.c similarity index 99% rename from lib_dec/ivas_ism_renderer.c rename to lib_dec/ivas_ism_renderer_fx.c index 2f2a0fda5803520e91a86e0b83971fff898a8256..2535eb6ee7e6349606f9e415bdbdbfc1c6bb668f 100644 --- a/lib_dec/ivas_ism_renderer.c +++ b/lib_dec/ivas_ism_renderer_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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,11 +33,9 @@ #include #include "options.h" #include "ivas_cnst.h" -#include "prot.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "ivas_prot_fx.h" -#include "ivas_prot_rend.h" +#include "ivas_prot_rend_fx.h" #include "ivas_stat_com.h" #include "ivas_rom_com.h" #include "rom_com.h" diff --git a/lib_dec/ivas_jbm_dec.c b/lib_dec/ivas_jbm_dec_fx.c similarity index 94% rename from lib_dec/ivas_jbm_dec.c rename to lib_dec/ivas_jbm_dec_fx.c index 70b4c2699ac3b62fad565949ee9df30656cb6f24..f265975d506ce14ca1ffecf94f43459000a90a60 100644 --- a/lib_dec/ivas_jbm_dec.c +++ b/lib_dec/ivas_jbm_dec_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other @@ -35,10 +35,9 @@ #include "cnst.h" #include "ivas_cnst.h" #include "rom_com.h" -#include "prot.h" -#include "ivas_prot.h" +#include "prot_fx.h" #include "ivas_prot_fx.h" -#include "ivas_prot_rend.h" +#include "ivas_prot_rend_fx.h" #include "ivas_rom_com.h" #include #include "wmc_auto.h" @@ -46,7 +45,6 @@ #ifdef DEBUGGING #include "debug.h" #endif -#include "prot_fx.h" /*-----------------------------------------------------------------------* @@ -84,7 +82,7 @@ ivas_error ivas_jbm_dec_tc_fx( Word32 *data_fx /*Q11*/ ) { - Word16 n, output_frame, nchan_out, i; + Word16 n, output_frame, nchan_out, i, ii; Decoder_State *st; /* used for bitstream handling */ Word32 *p_output_fx[MAX_TRANSPORT_CHANNELS]; /* buffer for output synthesis */ Word16 nchan_remapped; @@ -431,13 +429,18 @@ ivas_error ivas_jbm_dec_tc_fx( scale_sig32( hCPE->input_mem_BPF_fx[0], STEREO_DFT32MS_OVL_16k, sub( hCPE->hStereoDft->q_dft, Q11 ) ); // q_dft FOR( i = 0; i < CPE_CHANNELS; ++i ) { - scale_sig32( hCPE->input_mem_LB_fx[i], STEREO_DFT32MS_OVL_16k, sub( hCPE->hStereoDft->q_dft, Q11 ) ); // q_dft - scale_sig32( hCPE->input_mem_fx[i], NS2SA( hCPE->hCoreCoder[0]->output_Fs, STEREO_DFT32MS_OVL_NS ), sub( hCPE->hStereoDft->q_dft, Q11 ) ); // q_dft + scale_sig32( hCPE->input_mem_LB_fx[i], STEREO_DFT32MS_OVL_16k, sub( hCPE->hStereoDft->q_dft, Q11 ) ); // q_dft + scale_sig32( hCPE->input_mem_fx[i], NS2SA_FX2( hCPE->hCoreCoder[0]->output_Fs, STEREO_DFT32MS_OVL_NS ), sub( hCPE->hStereoDft->q_dft, Q11 ) ); // q_dft } IF( hCPE->hCoreCoder[0] != NULL ) { - Copy_Scale_sig_16_32( hCPE->hCoreCoder[0]->hHQ_core->old_out_LB_fx, hCPE->hCoreCoder[0]->hHQ_core->old_outLB_fx, L_FRAME32k, q - hCPE->hCoreCoder[0]->hHQ_core->Q_old_wtda_LB ); // q - Copy_Scale_sig_16_32( hCPE->hCoreCoder[0]->hHQ_core->old_out_fx, hCPE->hCoreCoder[0]->hHQ_core->oldOut_fx, L_FRAME48k, q - hCPE->hCoreCoder[0]->hHQ_core->Q_old_wtda ); // q +#ifdef FIX_ISSUE_1237 + Copy_Scale_sig_16_32_no_sat( hCPE->hCoreCoder[0]->hHQ_core->old_out_LB_fx, hCPE->hCoreCoder[0]->hHQ_core->old_outLB_fx, L_FRAME32k, q - hCPE->hCoreCoder[0]->hHQ_core->Q_old_wtda_LB ); // q + Copy_Scale_sig_16_32_no_sat( hCPE->hCoreCoder[0]->hHQ_core->old_out_fx, hCPE->hCoreCoder[0]->hHQ_core->oldOut_fx, L_FRAME48k, q - hCPE->hCoreCoder[0]->hHQ_core->Q_old_wtda ); // q +#else + Copy_Scale_sig_16_32_DEPREC( hCPE->hCoreCoder[0]->hHQ_core->old_out_LB_fx, hCPE->hCoreCoder[0]->hHQ_core->old_outLB_fx, L_FRAME32k, q - hCPE->hCoreCoder[0]->hHQ_core->Q_old_wtda_LB ); // q + Copy_Scale_sig_16_32_DEPREC( hCPE->hCoreCoder[0]->hHQ_core->old_out_fx, hCPE->hCoreCoder[0]->hHQ_core->oldOut_fx, L_FRAME48k, q - hCPE->hCoreCoder[0]->hHQ_core->Q_old_wtda ); // q +#endif hCPE->hCoreCoder[0]->hHQ_core->q_old_outLB_fx = q; move16(); } @@ -508,16 +511,16 @@ ivas_error ivas_jbm_dec_tc_fx( hSCE->q_save_synth_fx = hCPE->hStereoDft->q_dft; move16(); } - FOR( Word16 ii = 0; ii < CPE_CHANNELS; ii++ ) + FOR( ii = 0; ii < CPE_CHANNELS; ii++ ) { scale_sig32( hCPE->output_mem_fx[ii], NS2SA_FX2( st_ivas->hDecoderConfig->output_Fs, STEREO_DFT32MS_OVL_NS ), sub( hCPE->hStereoDft->q_dft, Q11 ) ); // q_dft hCPE->q_output_mem_fx[ii] = hCPE->hStereoDft->q_dft; move16(); } #ifdef MSAN_FIX - FOR( Word16 ii = 0; ii < CPE_CHANNELS; ii++ ) + FOR( ii = 0; ii < CPE_CHANNELS; ii++ ) { - Scale_sig32( &hCPE->prev_synth_fx[ii][0], NS2SA_FX2( st_ivas->hDecoderConfig->output_Fs, IVAS_DEC_DELAY_NS - STEREO_DFT32MS_OVL_NS ), hCPE->q_prev_synth_fx - 11 ); // q_prev_synth_fx + Scale_sig32( &hCPE->prev_synth_fx[ii][0], NS2SA_FX2( st_ivas->hDecoderConfig->output_Fs, IVAS_DEC_DELAY_NS - STEREO_DFT32MS_OVL_NS ), sub( hCPE->q_prev_synth_fx, Q11 ) ); // q_prev_synth_fx } #else Scale_sig32( &hCPE->prev_synth_fx[0][0], sizeof( hCPE->prev_synth_fx ) / sizeof( hCPE->prev_synth_fx[0][0] ), hCPE->q_prev_synth_fx - 11 ); @@ -530,9 +533,9 @@ ivas_error ivas_jbm_dec_tc_fx( Scale_sig32( p_output_fx[i], L_FRAME48k, negate( s ) ); } #ifdef MSAN_FIX - FOR( int ii = 0; ii < CPE_CHANNELS; ii++ ) + FOR( ii = 0; ii < CPE_CHANNELS; ii++ ) { - Scale_sig32( &hCPE->prev_synth_fx[ii][0], NS2SA_FX2( st_ivas->hDecoderConfig->output_Fs, IVAS_DEC_DELAY_NS - STEREO_DFT32MS_OVL_NS ), sub( 11, hCPE->q_prev_synth_fx ) ); // Q11 + Scale_sig32( &hCPE->prev_synth_fx[ii][0], NS2SA_FX2( st_ivas->hDecoderConfig->output_Fs, IVAS_DEC_DELAY_NS - STEREO_DFT32MS_OVL_NS ), sub( Q11, hCPE->q_prev_synth_fx ) ); // Q11 } #else Scale_sig32( &hCPE->prev_synth_fx[0][0], sizeof( hCPE->prev_synth_fx ) / sizeof( hCPE->prev_synth_fx[0][0] ), 11 - hCPE->q_prev_synth_fx ); @@ -601,7 +604,7 @@ ivas_error ivas_jbm_dec_tc_fx( } } #else - scale_sig32( hCPE->hStereoDft->buff_LBTCX_mem_fx, NS2SA( 16000, STEREO_DFT32MS_OVL_NS ), sub( Q11, hCPE->hStereoDft->q_dft ) ); // Q11 + scale_sig32( hCPE->hStereoDft->buff_LBTCX_mem_fx, NS2SA( 16000, STEREO_DFT32MS_OVL_NS ), sub( Q11, hCPE->hStereoDft->q_dft ) ); // Q11 #endif scale_sig32( hCPE->hStereoDft->ap_delay_mem_fx, NS2SA_FX2( 16000, DELAY_BWE_TOTAL_NS ), sub( Q11, hCPE->hStereoDft->q_ap_fade_mem_fx ) ); // Q11 hCPE->hStereoDft->q_ap_fade_mem_fx = Q11; @@ -610,7 +613,7 @@ ivas_error ivas_jbm_dec_tc_fx( st_ivas->hSpar->hMdDec->Q_mixer_mat = 30; move16(); - FOR( Word16 ii = 0; ii < CPE_CHANNELS; ii++ ) + FOR( ii = 0; ii < CPE_CHANNELS; ii++ ) { scale_sig32( hCPE->output_mem_fx[ii], NS2SA_FX2( st_ivas->hDecoderConfig->output_Fs, STEREO_DFT32MS_OVL_NS ), sub( Q11, hCPE->hStereoDft->q_dft ) ); // Q11 hCPE->q_output_mem_fx[ii] = Q11; @@ -963,13 +966,18 @@ ivas_error ivas_jbm_dec_tc_fx( scale_sig32( hCPE->input_mem_BPF_fx[0], STEREO_DFT32MS_OVL_16k, sub( hCPE->hStereoDft->q_dft, Q11 ) ); FOR( i = 0; i < CPE_CHANNELS; ++i ) { - scale_sig32( hCPE->input_mem_LB_fx[i], STEREO_DFT32MS_OVL_16k, sub( hCPE->hStereoDft->q_dft, Q11 ) ); // q_dft - scale_sig32( hCPE->input_mem_fx[i], NS2SA( hCPE->hCoreCoder[0]->output_Fs, STEREO_DFT32MS_OVL_NS ), sub( hCPE->hStereoDft->q_dft, Q11 ) ); // q_dft + scale_sig32( hCPE->input_mem_LB_fx[i], STEREO_DFT32MS_OVL_16k, sub( hCPE->hStereoDft->q_dft, Q11 ) ); // q_dft + scale_sig32( hCPE->input_mem_fx[i], NS2SA_FX2( hCPE->hCoreCoder[0]->output_Fs, STEREO_DFT32MS_OVL_NS ), sub( hCPE->hStereoDft->q_dft, Q11 ) ); // q_dft } IF( hCPE->hCoreCoder[0] != NULL ) { - Copy_Scale_sig_16_32( hCPE->hCoreCoder[0]->hHQ_core->old_out_LB_fx, hCPE->hCoreCoder[0]->hHQ_core->old_outLB_fx, L_FRAME32k, sub( q, hCPE->hCoreCoder[0]->hHQ_core->Q_old_wtda_LB ) ); // q - Copy_Scale_sig_16_32( hCPE->hCoreCoder[0]->hHQ_core->old_out_fx, hCPE->hCoreCoder[0]->hHQ_core->oldOut_fx, L_FRAME48k, sub( q, hCPE->hCoreCoder[0]->hHQ_core->Q_old_wtda ) ); // q +#ifdef FIX_ISSUE_1237 + Copy_Scale_sig_16_32_no_sat( hCPE->hCoreCoder[0]->hHQ_core->old_out_LB_fx, hCPE->hCoreCoder[0]->hHQ_core->old_outLB_fx, L_FRAME32k, sub( q, hCPE->hCoreCoder[0]->hHQ_core->Q_old_wtda_LB ) ); // q + Copy_Scale_sig_16_32_no_sat( hCPE->hCoreCoder[0]->hHQ_core->old_out_fx, hCPE->hCoreCoder[0]->hHQ_core->oldOut_fx, L_FRAME48k, sub( q, hCPE->hCoreCoder[0]->hHQ_core->Q_old_wtda ) ); // q +#else + Copy_Scale_sig_16_32_DEPREC( hCPE->hCoreCoder[0]->hHQ_core->old_out_LB_fx, hCPE->hCoreCoder[0]->hHQ_core->old_outLB_fx, L_FRAME32k, sub( q, hCPE->hCoreCoder[0]->hHQ_core->Q_old_wtda_LB ) ); // q + Copy_Scale_sig_16_32_DEPREC( hCPE->hCoreCoder[0]->hHQ_core->old_out_fx, hCPE->hCoreCoder[0]->hHQ_core->oldOut_fx, L_FRAME48k, sub( q, hCPE->hCoreCoder[0]->hHQ_core->Q_old_wtda ) ); // q +#endif hCPE->hCoreCoder[0]->hHQ_core->q_old_outLB_fx = q; move16(); } @@ -990,7 +998,7 @@ ivas_error ivas_jbm_dec_tc_fx( hSCE->q_save_synth_fx = hCPE->hStereoDft->q_dft; move16(); } - FOR( Word16 ii = 0; ii < CPE_CHANNELS; ii++ ) + FOR( ii = 0; ii < CPE_CHANNELS; ii++ ) { scale_sig32( hCPE->output_mem_fx[ii], NS2SA_FX2( st_ivas->hDecoderConfig->output_Fs, STEREO_DFT32MS_OVL_NS ), sub( hCPE->hStereoDft->q_dft, Q11 ) ); // q_dft hCPE->q_output_mem_fx[ii] = hCPE->hStereoDft->q_dft; @@ -998,7 +1006,7 @@ ivas_error ivas_jbm_dec_tc_fx( } #ifdef MSAN_FIX FOR( i = 0; i < CPE_CHANNELS; i++ ) - Scale_sig32( hCPE->prev_synth_fx[i], NS2SA_FX2( output_Fs, IVAS_DEC_DELAY_NS - STEREO_DFT32MS_OVL_NS ), sub( hCPE->q_prev_synth_fx, 11 ) ); // q_prev_synth_fx + Scale_sig32( hCPE->prev_synth_fx[i], NS2SA_FX2( output_Fs, IVAS_DEC_DELAY_NS - STEREO_DFT32MS_OVL_NS ), sub( hCPE->q_prev_synth_fx, Q11 ) ); // q_prev_synth_fx #else Scale_sig32( &hCPE->prev_synth_fx[0][0], sizeof( hCPE->prev_synth_fx ) / sizeof( hCPE->prev_synth_fx[0][0] ), hCPE->q_prev_synth_fx - 11 ); #endif @@ -1018,8 +1026,8 @@ ivas_error ivas_jbm_dec_tc_fx( scale_sig32( hCPE->input_mem_BPF_fx[0], STEREO_DFT32MS_OVL_16k, sub( Q11, hCPE->hStereoDft->q_dft ) ); // Q11 FOR( i = 0; i < CPE_CHANNELS; ++i ) { - scale_sig32( hCPE->input_mem_LB_fx[i], STEREO_DFT32MS_OVL_16k, sub( Q11, hCPE->hStereoDft->q_dft ) ); // Q11 - scale_sig32( hCPE->input_mem_fx[i], NS2SA( hCPE->hCoreCoder[0]->output_Fs, STEREO_DFT32MS_OVL_NS ), sub( Q11, hCPE->hStereoDft->q_dft ) ); // Q11 + scale_sig32( hCPE->input_mem_LB_fx[i], STEREO_DFT32MS_OVL_16k, sub( Q11, hCPE->hStereoDft->q_dft ) ); // Q11 + scale_sig32( hCPE->input_mem_fx[i], NS2SA_FX2( hCPE->hCoreCoder[0]->output_Fs, STEREO_DFT32MS_OVL_NS ), sub( Q11, hCPE->hStereoDft->q_dft ) ); // Q11 } IF( hCPE->hCoreCoder[0] != NULL ) @@ -1036,7 +1044,7 @@ ivas_error ivas_jbm_dec_tc_fx( move16(); } - FOR( Word16 ii = 0; ii < CPE_CHANNELS; ii++ ) + FOR( ii = 0; ii < CPE_CHANNELS; ii++ ) { scale_sig32( hCPE->output_mem_fx[ii], NS2SA_FX2( st_ivas->hDecoderConfig->output_Fs, STEREO_DFT32MS_OVL_NS ), sub( Q11, hCPE->hStereoDft->q_dft ) ); // Q11 hCPE->q_output_mem_fx[ii] = Q11; @@ -1417,14 +1425,19 @@ ivas_error ivas_jbm_dec_tc_fx( scale_sig32( hCPE->input_mem_BPF_fx[0], STEREO_DFT32MS_OVL_16k, sub( hCPE->hStereoDft->q_dft, Q11 ) ); FOR( i = 0; i < CPE_CHANNELS; ++i ) { - scale_sig32( hCPE->input_mem_LB_fx[i], STEREO_DFT32MS_OVL_16k, sub( hCPE->hStereoDft->q_dft, Q11 ) ); // q_dft - scale_sig32( hCPE->input_mem_fx[i], NS2SA( hCPE->hCoreCoder[0]->output_Fs, STEREO_DFT32MS_OVL_NS ), sub( hCPE->hStereoDft->q_dft, Q11 ) ); // q_dft + scale_sig32( hCPE->input_mem_LB_fx[i], STEREO_DFT32MS_OVL_16k, sub( hCPE->hStereoDft->q_dft, Q11 ) ); // q_dft + scale_sig32( hCPE->input_mem_fx[i], NS2SA_FX2( hCPE->hCoreCoder[0]->output_Fs, STEREO_DFT32MS_OVL_NS ), sub( hCPE->hStereoDft->q_dft, Q11 ) ); // q_dft } IF( hCPE->hCoreCoder[0] != NULL ) { - Copy_Scale_sig_16_32( hCPE->hCoreCoder[0]->hHQ_core->old_out_LB_fx, hCPE->hCoreCoder[0]->hHQ_core->old_outLB_fx, L_FRAME32k, q - hCPE->hCoreCoder[0]->hHQ_core->Q_old_wtda_LB ); // q - Copy_Scale_sig_16_32( hCPE->hCoreCoder[0]->hHQ_core->old_out_fx, hCPE->hCoreCoder[0]->hHQ_core->oldOut_fx, L_FRAME48k, q - hCPE->hCoreCoder[0]->hHQ_core->Q_old_wtda ); // q +#ifdef FIX_ISSUE_1237 + Copy_Scale_sig_16_32_no_sat( hCPE->hCoreCoder[0]->hHQ_core->old_out_LB_fx, hCPE->hCoreCoder[0]->hHQ_core->old_outLB_fx, L_FRAME32k, q - hCPE->hCoreCoder[0]->hHQ_core->Q_old_wtda_LB ); // q + Copy_Scale_sig_16_32_no_sat( hCPE->hCoreCoder[0]->hHQ_core->old_out_fx, hCPE->hCoreCoder[0]->hHQ_core->oldOut_fx, L_FRAME48k, q - hCPE->hCoreCoder[0]->hHQ_core->Q_old_wtda ); // q +#else + Copy_Scale_sig_16_32_DEPREC( hCPE->hCoreCoder[0]->hHQ_core->old_out_LB_fx, hCPE->hCoreCoder[0]->hHQ_core->old_outLB_fx, L_FRAME32k, q - hCPE->hCoreCoder[0]->hHQ_core->Q_old_wtda_LB ); // q + Copy_Scale_sig_16_32_DEPREC( hCPE->hCoreCoder[0]->hHQ_core->old_out_fx, hCPE->hCoreCoder[0]->hHQ_core->oldOut_fx, L_FRAME48k, q - hCPE->hCoreCoder[0]->hHQ_core->Q_old_wtda ); // q +#endif hCPE->hCoreCoder[0]->hHQ_core->q_old_outLB_fx = q; move16(); } @@ -1450,7 +1463,7 @@ ivas_error ivas_jbm_dec_tc_fx( hSCE->q_save_synth_fx = hCPE->hStereoDft->q_dft; move16(); } - FOR( Word16 ii = 0; ii < CPE_CHANNELS; ii++ ) + FOR( ii = 0; ii < CPE_CHANNELS; ii++ ) { scale_sig32( hCPE->output_mem_fx[ii], NS2SA_FX2( st_ivas->hDecoderConfig->output_Fs, STEREO_DFT32MS_OVL_NS ), sub( hCPE->hStereoDft->q_dft, hCPE->q_output_mem_fx[ii] ) ); // q_dft hCPE->q_output_mem_fx[ii] = hCPE->hStereoDft->q_dft; @@ -1458,7 +1471,7 @@ ivas_error ivas_jbm_dec_tc_fx( } #ifdef MSAN_FIX FOR( i = 0; i < CPE_CHANNELS; i++ ) - Scale_sig32( hCPE->prev_synth_fx[i], NS2SA_FX2( output_Fs, IVAS_DEC_DELAY_NS - STEREO_DFT32MS_OVL_NS ), sub( hCPE->q_prev_synth_fx, 11 ) ); // q_prev_synth_fx + Scale_sig32( hCPE->prev_synth_fx[i], NS2SA_FX2( output_Fs, IVAS_DEC_DELAY_NS - STEREO_DFT32MS_OVL_NS ), sub( hCPE->q_prev_synth_fx, Q11 ) ); // q_prev_synth_fx #else Scale_sig32( &hCPE->prev_synth_fx[0][0], sizeof( hCPE->prev_synth_fx ) / sizeof( hCPE->prev_synth_fx[0][0] ), hCPE->q_prev_synth_fx - 11 ); #endif @@ -1469,7 +1482,7 @@ ivas_error ivas_jbm_dec_tc_fx( } #ifdef MSAN_FIX FOR( i = 0; i < CPE_CHANNELS; i++ ) - Scale_sig32( hCPE->prev_synth_fx[i], NS2SA_FX2( output_Fs, IVAS_DEC_DELAY_NS - STEREO_DFT32MS_OVL_NS ), sub( 11, hCPE->q_prev_synth_fx ) ); // Q11 + Scale_sig32( hCPE->prev_synth_fx[i], NS2SA_FX2( output_Fs, IVAS_DEC_DELAY_NS - STEREO_DFT32MS_OVL_NS ), sub( Q11, hCPE->q_prev_synth_fx ) ); // Q11 #else Scale_sig32( &hCPE->prev_synth_fx[0][0], sizeof( hCPE->prev_synth_fx ) / sizeof( hCPE->prev_synth_fx[0][0] ), 11 - hCPE->q_prev_synth_fx ); #endif // MSAN_FIX @@ -1495,7 +1508,7 @@ ivas_error ivas_jbm_dec_tc_fx( } IF( st_ivas->hSpar != NULL ) { - FOR( Word16 ii = 0; ii < CPE_CHANNELS; ii++ ) + FOR( ii = 0; ii < CPE_CHANNELS; ii++ ) { scale_sig32( hCPE->output_mem_fx[ii], NS2SA_FX2( st_ivas->hDecoderConfig->output_Fs, STEREO_DFT32MS_OVL_NS ), sub( Q11, hCPE->hStereoDft->q_dft ) ); // Q11 hCPE->q_output_mem_fx[ii] = Q11; @@ -1687,12 +1700,23 @@ void ivas_jbm_dec_feed_tc_to_renderer_fx( test(); test(); /* delay the objects here for all renderers where it is needed */ +#ifdef SPLIT_REND_WITH_HEAD_ROT + IF( + ( + EQ_16( st_ivas->renderer_type, RENDERER_BINAURAL_FASTCONV ) || + EQ_16( st_ivas->renderer_type, RENDERER_BINAURAL_FASTCONV_ROOM ) || + EQ_16( st_ivas->renderer_type, RENDERER_OSBA_AMBI ) || + EQ_16( st_ivas->renderer_type, RENDERER_OSBA_LS ) || + EQ_16( st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_EXTERNAL ) ) && + ( NE_32( st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) && NE_32( st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ) ) +#else IF( EQ_16( st_ivas->renderer_type, RENDERER_BINAURAL_FASTCONV ) || EQ_16( st_ivas->renderer_type, RENDERER_BINAURAL_FASTCONV_ROOM ) || EQ_16( st_ivas->renderer_type, RENDERER_OSBA_AMBI ) || EQ_16( st_ivas->renderer_type, RENDERER_OSBA_LS ) || EQ_16( st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_EXTERNAL ) ) +#endif { FOR( n = 0; n < st_ivas->nchan_ism; n++ ) { @@ -1773,7 +1797,7 @@ void ivas_jbm_dec_feed_tc_to_renderer_fx( } ELSE IF( EQ_16( st_ivas->mc_mode, MC_MODE_PARAMUPMIX ) ) { - ivas_mc_paramupmix_dec_digest_tc( st_ivas, (uint8_t) n_render_timeslots, st_ivas->hTcBuffer->n_samples_available ); + ivas_mc_paramupmix_dec_digest_tc( st_ivas, (UWord8) n_render_timeslots, st_ivas->hTcBuffer->n_samples_available ); } ELSE IF( EQ_16( st_ivas->mc_mode, MC_MODE_PARAMMC ) ) { @@ -1868,10 +1892,13 @@ ivas_error ivas_jbm_dec_render_fx( ivas_error error; Word32 *p_output_fx[MAX_OUTPUT_CHANNELS + MAX_NUM_OBJECTS]; Word32 *p_tc_fx[MAX_TRANSPORT_CHANNELS + MAX_NUM_OBJECTS]; - Word16 subframe_len, gd_bits, exp, nchan_in, i, j; + Word16 subframe_len, gd_bits, exp, nchan_in, i, j, ch; const Word16 output_q_factor = Q11; move16(); SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom; +#ifdef SPLIT_REND_WITH_HEAD_ROT + Word16 nchan_out_syn_output; +#endif push_wmops( "ivas_dec_render" ); /*----------------------------------------------------------------* @@ -2064,6 +2091,26 @@ ivas_error ivas_jbm_dec_render_fx( #endif } +#ifdef SPLIT_REND_WITH_HEAD_ROT + /* Binaural rendering */ + IF( EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_OBJECTS_TD ) ) + { + IF( EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) || EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ) + { + IF( ( error = ivas_td_binaural_renderer_sf_splitBinaural( st_ivas, p_output_fx, *nSamplesRendered ) ) != IVAS_ERR_OK ) + { + return error; + } + } + ELSE + { + IF( NE_32( ( error = ivas_td_binaural_renderer_sf_fx( st_ivas, p_output_fx, *nSamplesRendered ) ), IVAS_ERR_OK ) ) + { + return error; + } + } + } +#else /* Binaural rendering */ IF( EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_OBJECTS_TD ) ) { @@ -2072,6 +2119,7 @@ ivas_error ivas_jbm_dec_render_fx( return error; } } +#endif ELSE IF( EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_MIXER_CONV_ROOM ) ) { st_ivas->hCrendWrapper->p_io_qfactor = &st_ivas->hCrendWrapper->io_qfactor; @@ -2090,10 +2138,19 @@ ivas_error ivas_jbm_dec_render_fx( { scale_sig32( p_output_fx[i], *nSamplesRendered, negate( sub( 11, *st_ivas->hCrendWrapper->p_io_qfactor ) ) ); // Q11 } + +#if defined SPLIT_REND_WITH_HEAD_ROT + IF( NE_32( ( error = ivas_rend_crendProcessSubframe( st_ivas->hCrendWrapper, IVAS_AUDIO_CONFIG_7_1_4, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR, st_ivas->hDecoderConfig, NULL, NULL, NULL, st_ivas->hTcBuffer, p_output_fx, p_output_fx, *nSamplesRendered, output_Fs, 0 ) ), IVAS_ERR_OK ) ) + { + return error; + } +#else IF( NE_32( ( error = ivas_rend_crendProcessSubframe( st_ivas->hCrendWrapper, IVAS_AUDIO_CONFIG_7_1_4, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR, st_ivas->hDecoderConfig, NULL, NULL, NULL, st_ivas->hTcBuffer, p_output_fx, p_output_fx, *nSamplesRendered, output_Fs ) ), IVAS_ERR_OK ) ) { return error; } +#endif + FOR( i = 0; i < nchan_out; i++ ) { scale_sig32( p_output_fx[i], *nSamplesRendered, sub( 11, *st_ivas->hCrendWrapper->p_io_qfactor ) ); // Q11 @@ -2314,14 +2371,40 @@ ivas_error ivas_jbm_dec_render_fx( scale_sig32( p_tc_fx[i], *nSamplesRendered, negate( sub( Q11, *st_ivas->hCrendWrapper->p_io_qfactor ) ) ); // Q11 } } + +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) || EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ) + { + if ( ( error = ivas_rend_crendProcessSubframesSplitBin( st_ivas->hCrendWrapper, st_ivas->intern_config, st_ivas->hOutSetup.output_config, ( st_ivas->hSplitBinRend == NULL ) ? NULL : &st_ivas->hSplitBinRend->splitrend.multiBinPoseData, st_ivas->hDecoderConfig, st_ivas->hCombinedOrientationData, + &st_ivas->hIntSetup, st_ivas->hEFAPdata, st_ivas->hTcBuffer, crendInPlaceRotation ? p_output_fx : p_tc_fx, p_output_fx, *nSamplesRendered, output_Fs ) ) != IVAS_ERR_OK ) + { + return error; + } + } + else + { +#endif + +#if defined SPLIT_REND_WITH_HEAD_ROT + IF( NE_32( ( error = ivas_rend_crendProcessSubframe( st_ivas->hCrendWrapper, st_ivas->intern_config, st_ivas->hOutSetup.output_config, st_ivas->hDecoderConfig, st_ivas->hCombinedOrientationData, + &st_ivas->hIntSetup, st_ivas->hEFAPdata, st_ivas->hTcBuffer, crendInPlaceRotation ? p_output_fx : p_tc_fx, p_output_fx, *nSamplesRendered, output_Fs, 0 ) ), + IVAS_ERR_OK ) ) + { + return error; + } +#else IF( NE_32( ( error = ivas_rend_crendProcessSubframe( st_ivas->hCrendWrapper, st_ivas->intern_config, st_ivas->hOutSetup.output_config, st_ivas->hDecoderConfig, st_ivas->hCombinedOrientationData, &st_ivas->hIntSetup, st_ivas->hEFAPdata, st_ivas->hTcBuffer, crendInPlaceRotation ? p_output_fx : p_tc_fx, p_output_fx, *nSamplesRendered, output_Fs ) ), IVAS_ERR_OK ) ) { return error; } +#endif - ivas_binaural_add_LFE_fx( st_ivas, *nSamplesRendered, p_tc_fx, p_output_fx ); + ivas_binaural_add_LFE_fx( st_ivas, *nSamplesRendered, p_tc_fx, p_output_fx ); +#ifdef SPLIT_REND_WITH_HEAD_ROT + } +#endif FOR( i = 0; i < nchan_in; i++ ) { @@ -2345,12 +2428,26 @@ ivas_error ivas_jbm_dec_render_fx( } ELSE IF( EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_OBJECTS_TD ) ) { - IF( NE_32( ( error = ivas_td_binaural_renderer_sf_fx( st_ivas, p_output_fx, *nSamplesRendered ) ), IVAS_ERR_OK ) ) +#ifdef SPLIT_REND_WITH_HEAD_ROT + IF( EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) || EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ) { - return error; + IF( NE_32( ( error = ivas_td_binaural_renderer_sf_splitBinaural( st_ivas, p_output_fx, *nSamplesRendered ) ), IVAS_ERR_OK ) ) + { + return error; + } } + else + { +#endif + IF( NE_32( ( error = ivas_td_binaural_renderer_sf_fx( st_ivas, p_output_fx, *nSamplesRendered ) ), IVAS_ERR_OK ) ) + { + return error; + } - ivas_binaural_add_LFE_fx( st_ivas, *nSamplesRendered, p_tc_fx, p_output_fx ); + ivas_binaural_add_LFE_fx( st_ivas, *nSamplesRendered, p_tc_fx, p_output_fx ); +#ifdef SPLIT_REND_WITH_HEAD_ROT + } +#endif } } ELSE IF( EQ_32( st_ivas->mc_mode, MC_MODE_PARAMUPMIX ) ) @@ -2362,7 +2459,13 @@ ivas_error ivas_jbm_dec_render_fx( /* Rendering */ IF( ( EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_FASTCONV ) || EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_FASTCONV_ROOM ) ) && !st_ivas->hDecoderConfig->Opt_Headrotation ) { - ivas_binaural_add_LFE_fx( st_ivas, *nSamplesRendered, p_output_fx, p_output_fx ); +#ifdef SPLIT_REND_WITH_HEAD_ROT + /*handled in CLDFB domain already*/ + IF( NE_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) && NE_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ) +#endif + { + ivas_binaural_add_LFE_fx( st_ivas, *nSamplesRendered, p_output_fx, p_output_fx ); + } } ELSE IF( EQ_32( st_ivas->renderer_type, RENDERER_MC ) ) { @@ -2434,7 +2537,7 @@ ivas_error ivas_jbm_dec_render_fx( move16(); } /* CLDFB synthesis */ - FOR( Word16 ch = 0; ch < nchan_out_cldfb; ch++ ) + FOR( ch = 0; ch < nchan_out_cldfb; ch++ ) { IF( st_ivas->cldfbSynDec[ch] ) { @@ -2462,7 +2565,7 @@ ivas_error ivas_jbm_dec_render_fx( ivas_param_mc_dec_render_fx( st_ivas, nSamplesAskedLocal, nSamplesRendered, nSamplesAvailableNext, p_output_fx, channel_active_fx ); - FOR( int ch = 0; ch < nchan_out_cldfb; ch++ ) + FOR( ch = 0; ch < nchan_out_cldfb; ch++ ) { IF( st_ivas->cldfbSynDec[ch] ) { @@ -2578,6 +2681,19 @@ ivas_error ivas_jbm_dec_render_fx( move16(); } +#ifdef SPLIT_REND_WITH_HEAD_ROT + IF( EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) || EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ) + { + FOR( i = 0; i < st_ivas->hSplitBinRend->splitrend.multiBinPoseData.num_poses * BINAURAL_CHANNELS; i++ ) + { + Copy32( p_output_fx[i], st_ivas->hSplitBinRend->hMultiBinCldfbData->output_fx[i], *nSamplesRendered ); + } + } + nchan_out_syn_output = nchan_out; + move16(); + + IF( st_ivas->hDecoderConfig->Opt_Limiter ) +#endif { IF( NE_32( st_ivas->ivas_format, MONO_FORMAT ) ) { @@ -2587,7 +2703,11 @@ ivas_error ivas_jbm_dec_render_fx( } } +#ifdef SPLIT_REND_WITH_HEAD_ROT + ivas_syn_output_fx( p_output_fx, output_q_factor, *nSamplesRendered, nchan_out_syn_output, data ); +#else ivas_syn_output_fx( p_output_fx, output_q_factor, *nSamplesRendered, nchan_out, data ); +#endif *nSamplesAvailableNext = st_ivas->hTcBuffer->n_samples_available; move16(); @@ -2713,12 +2833,21 @@ ivas_error ivas_jbm_dec_flush_renderer_fx( st_ivas->hCrendWrapper->p_io_qfactor = &st_ivas->hCrendWrapper->io_qfactor; *st_ivas->hCrendWrapper->p_io_qfactor = 11; move16(); +#if defined SPLIT_REND_WITH_HEAD_ROT + IF( NE_32( ( error = ivas_rend_crendProcessSubframe( st_ivas->hCrendWrapper, IVAS_AUDIO_CONFIG_7_1_4, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR, st_ivas->hDecoderConfig, NULL, + NULL, NULL, st_ivas->hTcBuffer, p_output_fx, p_output_fx, hTcBuffer->n_samples_granularity, st_ivas->hDecoderConfig->output_Fs, 0 ) ), + IVAS_ERR_OK ) ) + { + return error; + } +#else IF( NE_32( ( error = ivas_rend_crendProcessSubframe( st_ivas->hCrendWrapper, IVAS_AUDIO_CONFIG_7_1_4, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR, st_ivas->hDecoderConfig, NULL, NULL, NULL, st_ivas->hTcBuffer, p_output_fx, p_output_fx, hTcBuffer->n_samples_granularity, st_ivas->hDecoderConfig->output_Fs ) ), IVAS_ERR_OK ) ) { return error; } +#endif } } ELSE @@ -2745,12 +2874,22 @@ ivas_error ivas_jbm_dec_flush_renderer_fx( } *st_ivas->hCrendWrapper->p_io_qfactor = 11; move16(); + +#if defined SPLIT_REND_WITH_HEAD_ROT + IF( NE_32( ( error = ivas_rend_crendProcessSubframe( st_ivas->hCrendWrapper, intern_config_old, st_ivas->hOutSetup.output_config, st_ivas->hDecoderConfig, st_ivas->hCombinedOrientationData, + hIntSetupOld, st_ivas->hEFAPdata, st_ivas->hTcBuffer, hTcBuffer->tc_fx, p_output_fx, hTcBuffer->n_samples_granularity, st_ivas->hDecoderConfig->output_Fs, 0 ) ), + IVAS_ERR_OK ) ) + { + return error; + } +#else IF( NE_32( ( error = ivas_rend_crendProcessSubframe( st_ivas->hCrendWrapper, intern_config_old, st_ivas->hOutSetup.output_config, st_ivas->hDecoderConfig, st_ivas->hCombinedOrientationData, hIntSetupOld, st_ivas->hEFAPdata, st_ivas->hTcBuffer, hTcBuffer->tc_fx, p_output_fx, hTcBuffer->n_samples_granularity, st_ivas->hDecoderConfig->output_Fs ) ), IVAS_ERR_OK ) ) { return error; } +#endif ivas_binaural_add_LFE_fx( st_ivas, hTcBuffer->n_samples_granularity, st_ivas->hTcBuffer->tc_fx, p_output_fx ); } @@ -2866,6 +3005,9 @@ ivas_error ivas_jbm_dec_flush_renderer_fx( *nSamplesRendered = n_samples_to_render; move16(); /* Only write out the valid data*/ +#ifdef SPLIT_REND_WITH_HEAD_ROT + IF( st_ivas->hDecoderConfig->Opt_Limiter ) +#endif { IF( NE_16( st_ivas->ivas_format, MONO_FORMAT ) ) { diff --git a/lib_dec/ivas_lfe_dec.c b/lib_dec/ivas_lfe_dec.c deleted file mode 100644 index a9ed90a8a2e7d5ac3f567208cbc2824c329d03cf..0000000000000000000000000000000000000000 --- a/lib_dec/ivas_lfe_dec.c +++ /dev/null @@ -1,36 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -#include -#include -#include "options.h" -#include "wmc_auto.h" diff --git a/lib_dec/ivas_lfe_dec_fx.c b/lib_dec/ivas_lfe_dec_fx.c index ec58c45c0c4c5ec6446c90e2f07a7231407decb9..672d3fbe67ca2a80b1518e99a30d2e3bca85c9a4 100644 --- a/lib_dec/ivas_lfe_dec_fx.c +++ b/lib_dec/ivas_lfe_dec_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other @@ -32,9 +32,7 @@ #include #include "options.h" -#include "prot.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "ivas_prot_fx.h" #include "ivas_rom_com.h" #include "rom_com.h" diff --git a/lib_dec/ivas_lfe_plc_fx.c b/lib_dec/ivas_lfe_plc_fx.c index 6e3969255e36c9094dcd4f8ec13cd7217c4b0308..d98603d2a567052962051810bce287bbb9e3cedb 100644 --- a/lib_dec/ivas_lfe_plc_fx.c +++ b/lib_dec/ivas_lfe_plc_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other @@ -32,9 +32,7 @@ #include #include "options.h" -#include "prot.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "ivas_rom_com.h" #include #include "wmc_auto.h" @@ -389,7 +387,7 @@ static Word16 lfeplc_lev_dur_fx( s = W_extract_h( W_shl( s_fx, exp1 ) ); s_q_fx = sub( add( s_q_fx, exp1 ), 32 ); - rc_fx[i - 1] = L_shr( BASOP_Util_Divide3232_Scale_cadence( -s, err_fx, &temp_q2 ), 1 ); + rc_fx[i - 1] = L_shr( BASOP_Util_Divide3232_Scale_cadence( L_negate( s ), err_fx, &temp_q2 ), 1 ); move32(); rc_q_fx[i - 1] = sub( add( sub( s_q_fx, err_q_fx ), sub( 31, temp_q2 ) ), 1 ); move16(); @@ -397,7 +395,7 @@ static Word16 lfeplc_lev_dur_fx( IF( LT_16( rc_q_fx[i - 1], 31 ) ) { - IF( GT_32( abs( rc_fx[i - 1] ), L_shr( 2146302532, sub( 31, rc_q_fx[i - 1] ) ) ) ) // 2146302532 = 0.99945f in Q31 + IF( GT_32( L_abs( rc_fx[i - 1] ), L_shr( 2146302532, sub( 31, rc_q_fx[i - 1] ) ) ) ) // 2146302532 = 0.99945f in Q31 { return 1; } @@ -414,7 +412,7 @@ static Word16 lfeplc_lev_dur_fx( } ELSE { - IF( GT_32( abs( L_shr( rc_fx[i - 1], sub( rc_q_fx[i - 1], 31 ) ) ), 2146302532 ) ) // 2146302532 = 0.00045f in Q31 + IF( GT_32( L_abs( L_shr( rc_fx[i - 1], sub( rc_q_fx[i - 1], 31 ) ) ), 2146302532 ) ) // 2146302532 = 0.00045f in Q31 { return 1; } @@ -466,7 +464,7 @@ static Word16 d_a2rc_fx( move32(); km_q_fx = ff_q_fx[m]; move16(); - IF( GE_64( W_shr( abs( km_fx ), sub( ff_q_fx[m], Q30 ) ), W_deposit32_l( ONE_IN_Q30 ) ) ) + IF( GE_64( W_shr( L_abs( km_fx ), sub( ff_q_fx[m], Q30 ) ), W_deposit32_l( ONE_IN_Q30 ) ) ) { FOR( j = 0; j < lpcorder; j++ ) { @@ -827,7 +825,7 @@ static Word32 find_max_delta_fx( IF( !stable ) { - temp = abs( eps_fx ); + temp = L_abs( eps_fx ); IF( GT_32( L_shr( temp, sub( eps_q_fx, 31 ) ), EPS_STOP_Q31 ) ) { exp1 = norm_l( -temp ); @@ -837,12 +835,12 @@ static Word32 find_max_delta_fx( } ELSE { - eps_fx = L_negate( abs( eps_fx ) ); + eps_fx = L_negate( L_abs( eps_fx ) ); } } ELSE { - temp = abs( eps_fx ); + temp = L_abs( eps_fx ); if ( LT_32( L_shr( temp, sub( eps_q_fx, 31 ) ), EPS_STOP_Q31 ) ) { BREAK; @@ -1027,7 +1025,7 @@ void ivas_lfe_tdplc_fx( } } - Copy_Scale_sig_16_32( rec_frame_us_16_fx, rec_frame_us_fx, LFE_PLC_RECLEN_48K, 10 ); // Q10 = rec_frame_q + 5 + Copy_Scale_sig_16_32_DEPREC( rec_frame_us_16_fx, rec_frame_us_fx, LFE_PLC_RECLEN_48K, 10 ); // Q10 = rec_frame_q + 5 FOR( i = 0; i < 2; i++ ) { diff --git a/lib_dec/ivas_ls_custom_dec.c b/lib_dec/ivas_ls_custom_dec_fx.c similarity index 98% rename from lib_dec/ivas_ls_custom_dec.c rename to lib_dec/ivas_ls_custom_dec_fx.c index 25badc6082b4ce6a85737cdd54b2cb96bc7559e0..5ad390f9a66786ed847e1f78cc278c1fa165826c 100644 --- a/lib_dec/ivas_ls_custom_dec.c +++ b/lib_dec/ivas_ls_custom_dec_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other @@ -31,11 +31,9 @@ *******************************************************************************************************/ #include #include "options.h" -#include "ivas_prot.h" -#include "prot.h" +#include "prot_fx.h" #include "wmc_auto.h" #include "ivas_prot_fx.h" -#include "prot_fx.h" /*-----------------------------------------------------------------------* diff --git a/lib_dec/ivas_masa_dec.c b/lib_dec/ivas_masa_dec_fx.c similarity index 97% rename from lib_dec/ivas_masa_dec.c rename to lib_dec/ivas_masa_dec_fx.c index 19ee1e68a54f1ed10ef9e29e25eb9526d2b433cf..23653c53b91395bc70c561e636fd1506971bb40a 100644 --- a/lib_dec/ivas_masa_dec.c +++ b/lib_dec/ivas_masa_dec_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other @@ -35,12 +35,10 @@ #include #include "options.h" #include "ivas_cnst.h" -#include "ivas_prot.h" -#include "ivas_prot_rend.h" +#include "ivas_prot_rend_fx.h" #include "rom_com.h" #include "ivas_rom_com.h" #include "ivas_stat_dec.h" -#include "prot.h" #include "prot_fx.h" #include "wmc_auto.h" #include "ivas_prot_fx.h" @@ -836,7 +834,7 @@ ivas_error ivas_masa_dec_open_fx( nchan_to_allocate = add( nchan_to_allocate, 1 ); } - IF( ( error = ivas_jbm_dec_tc_buffer_open_fx( st_ivas, buffer_mode, nchan_transport, nchan_to_allocate, nchan_to_allocate, NS2SA( st_ivas->hDecoderConfig->output_Fs, CLDFB_SLOT_NS ) ) ) != IVAS_ERR_OK ) + IF( ( error = ivas_jbm_dec_tc_buffer_open_fx( st_ivas, buffer_mode, nchan_transport, nchan_to_allocate, nchan_to_allocate, NS2SA_FX2( st_ivas->hDecoderConfig->output_Fs, CLDFB_SLOT_NS ) ) ) != IVAS_ERR_OK ) { return error; } @@ -1581,6 +1579,9 @@ ivas_error ivas_masa_dec_reconfigure_fx( Word16 numCldfbAnalyses_old, numCldfbSyntheses_old; ivas_error error; Word32 ism_total_brate; +#ifdef SPLIT_REND_WITH_HEAD_ROT + Word16 pos_idx; +#endif error = IVAS_ERR_OK; move16(); @@ -1611,8 +1612,13 @@ ivas_error ivas_masa_dec_reconfigure_fx( test(); test(); test(); +#ifdef SPLIT_REND_WITH_HEAD_ROT + IF( ( EQ_32( st_ivas->renderer_type, RENDERER_DIRAC ) && st_ivas->hDirACRend == NULL ) || + ( ( EQ_32( st_ivas->renderer_type, RENDERER_STEREO_PARAMETRIC ) || EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_PARAMETRIC ) || EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_PARAMETRIC_ROOM ) ) && st_ivas->hDiracDecBin[0] == NULL ) ) +#else IF( ( EQ_32( st_ivas->renderer_type, RENDERER_DIRAC ) && st_ivas->hDirACRend == NULL ) || ( ( EQ_32( st_ivas->renderer_type, RENDERER_STEREO_PARAMETRIC ) || EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_PARAMETRIC ) || EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_PARAMETRIC_ROOM ) ) && st_ivas->hDiracDecBin == NULL ) ) +#endif { /* init a new DirAC dec */ if ( ( error = ivas_dirac_dec_config_fx( st_ivas, DIRAC_OPEN ) ) != IVAS_ERR_OK ) @@ -1625,7 +1631,11 @@ ivas_error ivas_masa_dec_reconfigure_fx( IF( st_ivas->hDirAC != NULL ) { /* close all unnecessary parametric decoding and rendering */ +#ifdef SPLIT_REND_WITH_HEAD_ROT + ivas_dirac_dec_close_binaural_data( st_ivas->hDiracDecBin ); +#else ivas_dirac_dec_close_binaural_data( &st_ivas->hDiracDecBin ); +#endif ivas_dirac_rend_close_fx( &( st_ivas->hDirACRend ) ); ivas_spat_hSpatParamRendCom_close_fx( &( st_ivas->hSpatParamRendCom ) ); ivas_dirac_dec_close_fx( &( st_ivas->hDirAC ) ); @@ -1676,7 +1686,11 @@ ivas_error ivas_masa_dec_reconfigure_fx( test(); test(); test(); +#ifdef SPLIT_REND_WITH_HEAD_ROT + IF( ( EQ_32( st_ivas->renderer_type, RENDERER_STEREO_PARAMETRIC ) || EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_PARAMETRIC ) || EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_PARAMETRIC_ROOM ) ) && st_ivas->hDiracDecBin[0] != NULL ) +#else IF( ( EQ_32( st_ivas->renderer_type, RENDERER_STEREO_PARAMETRIC ) || EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_PARAMETRIC ) || EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_PARAMETRIC_ROOM ) ) && st_ivas->hDiracDecBin != NULL ) +#endif { if ( NE_32( ( error = ivas_dirac_dec_config_fx( st_ivas, DIRAC_RECONFIGURE ) ), IVAS_ERR_OK ) ) { @@ -1732,7 +1746,11 @@ ivas_error ivas_masa_dec_reconfigure_fx( test(); test(); test(); +#ifdef SPLIT_REND_WITH_HEAD_ROT + IF( ( EQ_32( st_ivas->renderer_type, RENDERER_DIRAC ) && st_ivas->hDirACRend != NULL ) || ( ( EQ_32( st_ivas->renderer_type, RENDERER_STEREO_PARAMETRIC ) || EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_PARAMETRIC ) || EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_PARAMETRIC_ROOM ) ) && st_ivas->hDiracDecBin[0] != NULL ) ) +#else IF( ( EQ_32( st_ivas->renderer_type, RENDERER_DIRAC ) && st_ivas->hDirACRend != NULL ) || ( ( EQ_32( st_ivas->renderer_type, RENDERER_STEREO_PARAMETRIC ) || EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_PARAMETRIC ) || EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_PARAMETRIC_ROOM ) ) && st_ivas->hDiracDecBin != NULL ) ) +#endif { if ( NE_32( ( error = ivas_dirac_dec_config_fx( st_ivas, DIRAC_RECONFIGURE ) ), IVAS_ERR_OK ) ) { @@ -1750,7 +1768,11 @@ ivas_error ivas_masa_dec_reconfigure_fx( test(); test(); test(); +#ifdef SPLIT_REND_WITH_HEAD_ROT + IF( ( EQ_32( st_ivas->renderer_type, RENDERER_DIRAC ) && st_ivas->hDirACRend != NULL ) || ( ( EQ_32( st_ivas->renderer_type, RENDERER_STEREO_PARAMETRIC ) || EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_PARAMETRIC ) || EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_PARAMETRIC_ROOM ) ) && st_ivas->hDiracDecBin[0] != NULL ) ) +#else IF( ( EQ_32( st_ivas->renderer_type, RENDERER_DIRAC ) && st_ivas->hDirACRend != NULL ) || ( ( EQ_32( st_ivas->renderer_type, RENDERER_STEREO_PARAMETRIC ) || EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_PARAMETRIC ) || EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_PARAMETRIC_ROOM ) ) && st_ivas->hDiracDecBin != NULL ) ) +#endif { if ( ( error = ivas_dirac_dec_config_fx( st_ivas, DIRAC_RECONFIGURE ) ) != IVAS_ERR_OK ) { @@ -1760,12 +1782,24 @@ ivas_error ivas_masa_dec_reconfigure_fx( } } +#ifdef SPLIT_REND_WITH_HEAD_ROT + FOR( pos_idx = 0; pos_idx < MAX_HEAD_ROT_POSES; pos_idx++ ) + { + IF( st_ivas->hDiracDecBin[pos_idx] != NULL ) + { + /* regularization factor is bitrate-dependent */ + st_ivas->hDiracDecBin[pos_idx]->reqularizationFactor_fx = configure_reqularization_factor_fx( st_ivas->ivas_format, st_ivas->hDecoderConfig->ivas_total_brate ); + move16(); + } + } +#else IF( st_ivas->hDiracDecBin != NULL ) { /* regularization factor is bitrate-dependent */ st_ivas->hDiracDecBin->reqularizationFactor_fx = configure_reqularization_factor_fx( st_ivas->ivas_format, st_ivas->hDecoderConfig->ivas_total_brate ); move16(); } +#endif test(); IF( EQ_32( st_ivas->ivas_format, MASA_FORMAT ) && EQ_32( st_ivas->last_ivas_format, MASA_FORMAT ) ) /* note: switching within OMASA is handled in ivas_omasa_dec_config() */ @@ -1773,9 +1807,17 @@ ivas_error ivas_masa_dec_reconfigure_fx( /*-----------------------------------------------------------------* * TD Decorrelator *-----------------------------------------------------------------*/ +#ifdef SPLIT_REND_WITH_HEAD_ROT + IF( st_ivas->hDiracDecBin[0] != NULL ) +#else IF( st_ivas->hDiracDecBin != NULL ) +#endif { +#ifdef SPLIT_REND_WITH_HEAD_ROT + IF( NE_32( ( error = ivas_td_decorr_reconfig_dec( st_ivas->ivas_format, st_ivas->hDecoderConfig->ivas_total_brate, st_ivas->nchan_transport, st_ivas->hDecoderConfig->output_Fs, &( st_ivas->hDiracDecBin[0]->hTdDecorr ), &( st_ivas->hDiracDecBin[0]->useTdDecorr ) ) ), IVAS_ERR_OK ) ) +#else IF( NE_32( ( error = ivas_td_decorr_reconfig_dec( st_ivas->ivas_format, st_ivas->hDecoderConfig->ivas_total_brate, st_ivas->nchan_transport, st_ivas->hDecoderConfig->output_Fs, &( st_ivas->hDiracDecBin->hTdDecorr ), &( st_ivas->hDiracDecBin->useTdDecorr ) ) ), IVAS_ERR_OK ) ) +#endif { return error; } @@ -2012,7 +2054,11 @@ void ivas_spar_param_to_masa_param_mapping_fx( move16(); hSpatParamRendCom->numSimultaneousDirections = 1; move16(); +#ifdef SPLIT_REND_WITH_HEAD_ROT + hDiffuseDist = st_ivas->hDiracDecBin[0]->hDiffuseDist; +#else hDiffuseDist = st_ivas->hDiracDecBin->hDiffuseDist; +#endif nchan_transport = st_ivas->nchan_transport; move16(); band_grouping = hDirAC->band_grouping; @@ -2326,15 +2372,11 @@ void ivas_spar_param_to_masa_param_mapping_fx( move16(); res_q = 0; move16(); - IF( E_fx > 0 ) - { - E_fx = E_fx; - } - ELSE + IF( E_fx <= 0 ) { E_fx = 1; + move32(); } - move32(); ratio_float_fx = BASOP_Util_Divide3232_Scale( I_fx, E_fx, &res_q ); res_q = sub( res_q, sub( num_q, denom_q ) ); ratio_fx = L_shl_sat( ratio_float_fx, add( Q15, res_q ) ); // Q(15 + res_q) diff --git a/lib_dec/ivas_mc_param_dec.c b/lib_dec/ivas_mc_param_dec.c deleted file mode 100644 index e3d8bf0c034ff19afd08dd299334be9c128ad9f5..0000000000000000000000000000000000000000 --- a/lib_dec/ivas_mc_param_dec.c +++ /dev/null @@ -1,3790 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -#include -#include "options.h" -#include -#include "cnst.h" -#include "rom_enc.h" -#include "rom_com.h" -#include "prot.h" -#include "ivas_prot.h" -#include "ivas_prot_rend.h" -#include "ivas_cnst.h" -#include "ivas_rom_com.h" -#include "ivas_rom_dec.h" -#include "math.h" -#include "wmc_auto.h" -#include "rom_dec.h" -#include "prot_fx.h" -#include "ivas_prot_fx.h" - -#define INV_EPSILON_MANT 214748365 - -/*-----------------------------------------------------------------------* - * Local constants - *-----------------------------------------------------------------------*/ - -#define PARAM_MC_LOCAL_SZ_LFE_MAP 5 - -/*-----------------------------------------------------------------------* - * Local typedefs - *-----------------------------------------------------------------------*/ - -typedef struct parameter_band_mapping_struct -{ - Word16 n_source_bands[20]; - Word16 source_band_idx[20][4]; - Word16 source_band_factor_fx[20][4]; /*Q15*/ - -} PARAM_MC_PARAMETER_BAND_MAPPING; - -/*-----------------------------------------------------------------------* - * Local function prototypes - *-----------------------------------------------------------------------*/ - -static void ivas_param_mc_dec_init_fx( PARAM_MC_DEC_HANDLE hParamMC, const Word16 nchan_in, const Word16 nchan_out ); - -static void ivas_param_mc_dec_copy_diffuse_proto( PARAM_MC_DEC_HANDLE hParamMC, Word32 Cldfb_buffer_real_fx[MAX_CICP_CHANNELS][PARAM_MC_MAX_NSLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX], Word32 Cldfb_buffer_imag_fx[MAX_CICP_CHANNELS][PARAM_MC_MAX_NSLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX], const Word16 nY, const Word16 slot_idx ); -static Word16 ivas_param_mc_range_decoder_LC_fx( UWord16 *bit_buffer, Word16 *x, Word16 *BER_detect, const Word16 sz_seq, const Word16 sz_alphabet, const UWord16 *cft, const UWord16 *sft, const Word16 tot_shift, const Word16 nbbits ); - - -static void ivas_param_mc_get_mixing_matrices_fx( - PARAM_MC_DEC_HANDLE hParamMC, /* i : Parametric MC handle */ - IVAS_OUTPUT_SETUP *hSynthesisOutputSetup, - Word32 Cx_in_fixed[PARAM_MC_MAX_TRANSPORT_CHANS * PARAM_MC_MAX_TRANSPORT_CHANS], /* i : input covariance for all parameter bands */ - Word16 Cx_in_e, - const Word16 param_band_idx, - Word32 *mixing_matrix_fx[], - Word16 *mixing_matrix_e, - Word32 *mixing_matrix_res_fx[], - Word16 *mixing_matrix_res_e, - const Word16 nY_intern, /* i : number of channels in the transported format */ - const PARAM_MC_SYNTHESIS_CONF synth_config, /* i : Parametric MC synthesis config */ - const Word16 nX, /* i : number of transport channels */ - const Word16 nY_cov /* i : number of covariance synthesis output channels */ -); - -static Word16 ivas_param_mc_uniform_decoder_fx( Word16 *seq, const Word16 sz_seq, const Word16 *alphabet, const Word16 N, UWord16 bit_buffer[PARAM_MC_MAX_BITS] ); -static void ivas_param_mc_dec_compute_interpolator_fx( const UWord16 bAttackPresent, const UWord16 attackPos, const UWord16 interp_length, Word16 *interpolator ); - -static void param_mc_set_num_synth_bands( const Word32 output_Fs, PARAM_MC_DEC_HANDLE hParamMC ); - -static void ivas_param_mc_get_param_band_mapping( const Word16 n_target_bands, const Word16 *target_band_grouping, const Word16 n_source_bands, const Word16 *source_band_grouping, PARAM_MC_PARAMETER_BAND_MAPPING *parameter_band_mapping ); - - -static void ivas_param_mc_bs_decode_parameter_values_fx( UWord16 bit_buffer[], Word16 *bit_pos, const Word16 max_bits, Word16 *BER_detect, HANDLE_IVAS_PARAM_MC_METADATA hMetadataPMC, HANDLE_PARAM_MC_PARAMETER_CODING_INFO hParamCodingInfo, const Word16 map_size_wo_lfe, const Word16 map_size, const Word16 num_lfe_bands, const Word16 band_step, const Word16 num_param_bands, Word16 *value_buffer ); -static void ivas_param_mc_dequantize_cov_fx( PARAM_MC_DEC_HANDLE hParamMC, Word16 *ild_q_fx, Word16 *icc_q_fx, const Word16 param_band_index, const Word16 nY_cov, const PARAM_MC_SYNTHESIS_CONF synth_conf, const Word16 nY_int, const Word16 nX, Word32 *Cx_state_fx, Word16 Cx_state_e, Word32 *Cproto_fx, Word16 Cproto_e, Word32 *Cy_state_fx, Word16 *Cy_state_e ); -static ivas_error param_mc_get_diff_proto_info_fx( const Word32 *proto_mtx, const UWord16 nchan_transport, const UWord16 nchan_out_cov, PARAM_MC_DIFF_PROTO_INFO *p_diff_proto_info, Word16 Q_proto_mtx ); -static void param_mc_update_mixing_matrices_fx( PARAM_MC_DEC_HANDLE hParamMC, Word32 *mixing_matrix[], Word16 *mixing_matrix_fx, Word32 *mixing_matrix_res[], Word16 *mixing_matrix_res_exp, const UWord16 nX, const UWord16 nY ); - - -static void param_mc_protoSignalComputation_fx( Word32 *RealBuffer_fx, Word32 *ImagBuffer_fx, Word32 *proto_frame_f_fx, const PARAM_MC_DIFF_PROTO_INFO *diff_proto_info, const int16_t num_freq_bands /*, Word16 RealBuffer_fx_e, Word16 ImagBuffer_fx_e, Word16 *common_e*/ ); - -/*------------------------------------------------------------------------- - * ivas_param_mc_dec_open() - * - * Open Parametric MC decoder handle - *-------------------------------------------------------------------------*/ - -ivas_error ivas_param_mc_dec_open_fx( - Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */ -) -{ - Word16 k, nchan_transport; - PARAM_MC_DEC_HANDLE hParamMC; - Word16 nchan_out_transport; - Word16 nchan_out_cov; - Word32 proto_matrix_fx[MAX_CICP_CHANNELS * PARAM_MC_MAX_TRANSPORT_CHANS]; - Word32 proto_mtx_norm_fx; - Word16 frequency_axis_fx[CLDFB_NO_CHANNELS_MAX]; - Word16 max_param_band_residual; - UWord16 config_index; - MC_LS_SETUP mc_ls_setup; - AUDIO_CONFIG output_config; - Word32 output_Fs, ivas_total_brate; - ivas_error error; - - error = IVAS_ERR_OK; - move32(); - - /*-----------------------------------------------------------------* - * prepare library opening - *-----------------------------------------------------------------*/ - - IF( ( hParamMC = (PARAM_MC_DEC_HANDLE) malloc( sizeof( PARAM_MC_DEC_DATA ) ) ) == NULL ) - { - return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Parametric MC\n" ) ); - } - - IF( ( hParamMC->hMetadataPMC = (HANDLE_IVAS_PARAM_MC_METADATA) malloc( sizeof( IVAS_PARAM_MC_METADATA ) ) ) == NULL ) - { - return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Parametric MC metadata \n" ) ); - } - - output_Fs = st_ivas->hDecoderConfig->output_Fs; - move32(); - output_config = st_ivas->hDecoderConfig->output_config; - move32(); - ivas_total_brate = st_ivas->hDecoderConfig->ivas_total_brate; - move32(); - mc_ls_setup = ivas_mc_map_output_config_to_mc_ls_setup_fx( st_ivas->transport_config ); - nchan_out_transport = add( st_ivas->hTransSetup.nchan_out_woLFE, st_ivas->hTransSetup.num_lfe ); - hParamMC->hoa_encoder_fx = NULL; - - /* determine the synthesis config */ - test(); - test(); - test(); - test(); - test(); - IF( EQ_32( st_ivas->renderer_type, RENDERER_SBA_LINEAR_ENC ) || EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_FASTCONV ) || EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_FASTCONV_ROOM ) || EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_OBJECTS_TD ) || EQ_32( st_ivas->transport_config, output_config ) ) - { - hParamMC->synthesis_conf = PARAM_MC_SYNTH_DIRECT; - move32(); - } - ELSE IF( EQ_32( output_config, IVAS_AUDIO_CONFIG_MONO ) || EQ_32( output_config, IVAS_AUDIO_CONFIG_STEREO ) ) - { - hParamMC->synthesis_conf = PARAM_MC_SYNTH_MONO_STEREO; - move32(); - } - ELSE IF( NE_32( st_ivas->transport_config, output_config ) ) - { - test(); - test(); - IF( ( NE_32( output_config, IVAS_AUDIO_CONFIG_LS_CUSTOM ) && GT_16( nchan_out_transport, audioCfg2channels( output_config ) ) ) || ( EQ_32( output_config, IVAS_AUDIO_CONFIG_LS_CUSTOM ) && GT_16( nchan_out_transport, st_ivas->hOutSetup.nchan_out_woLFE ) ) ) - { - hParamMC->synthesis_conf = PARAM_MC_SYNTH_LS_CONV_COV; - move32(); - /* need to reset the intern config */ - st_ivas->intern_config = output_config; - move32(); - ivas_output_init( &( st_ivas->hIntSetup ), st_ivas->intern_config ); - IF( EQ_32( output_config, IVAS_AUDIO_CONFIG_LS_CUSTOM ) ) - { - st_ivas->hIntSetup.nchan_out_woLFE = st_ivas->hLsSetupCustom->num_spk; - move32(); - st_ivas->hIntSetup.ls_azimuth_fx = st_ivas->hLsSetupCustom->ls_azimuth_fx; // Q22 - st_ivas->hIntSetup.ls_elevation_fx = st_ivas->hLsSetupCustom->ls_elevation_fx; // Q22 - } - } - ELSE - { - hParamMC->synthesis_conf = PARAM_MC_SYNTH_LS_CONV_CLDFB; - move32(); - } - } - - hParamMC->ls_conv_dmx_matrix_fx = NULL; - - test(); - IF( EQ_32( hParamMC->synthesis_conf, PARAM_MC_SYNTH_LS_CONV_COV ) || EQ_32( hParamMC->synthesis_conf, PARAM_MC_SYNTH_MONO_STEREO ) ) - { - nchan_out_cov = add( st_ivas->hOutSetup.nchan_out_woLFE, st_ivas->hOutSetup.num_lfe ); - } - ELSE - { - nchan_out_cov = nchan_out_transport; - move16(); - } - - st_ivas->nchan_transport = ivas_param_mc_getNumTransportChannels_fx( ivas_total_brate, mc_ls_setup ); - move16(); - config_index = ivas_param_mc_get_configuration_index_fx( mc_ls_setup, ivas_total_brate ); - nchan_transport = st_ivas->nchan_transport; - move16(); - - SWITCH( nchan_transport ) - { - case 4: - case 3: - st_ivas->nCPE = 2; - move16(); - st_ivas->nSCE = 0; - move16(); - st_ivas->element_mode_init = IVAS_CPE_MDCT; - move16(); - BREAK; - case 2: - st_ivas->nCPE = 1; - move16(); - st_ivas->nSCE = 0; - move16(); - st_ivas->element_mode_init = IVAS_CPE_MDCT; - move16(); - - BREAK; - } - - /*-----------------------------------------------------------------* - * set input parameters - *-----------------------------------------------------------------*/ - - // hParamMC->slot_size = (int16_t) ( output_Fs / FRAMES_PER_SEC ) / CLDFB_NO_COL_MAX; - Word16 temp_e; - Word16 temp = BASOP_Util_Divide3232_Scale( output_Fs, FRAMES_PER_SEC, &temp_e ); - temp = shr( temp, sub( 15, temp_e ) ); // Going back to Q0 - temp = BASOP_Util_Divide1616_Scale( temp, CLDFB_NO_COL_MAX, &temp_e ); - temp = shr( temp, sub( 15, temp_e ) ); // Going back to Q0 - hParamMC->slot_size = temp; - move16(); - set16_fx( hParamMC->subframe_nbslots, 0, MAX_JBM_SUBFRAMES_5MS ); - set16_fx( hParamMC->subframe_nbslots, PARAM_MC_MAX_NSLOTS_IN_SUBFRAME, DEFAULT_JBM_SUBFRAMES_5MS ); - hParamMC->nb_subframes = DEFAULT_JBM_SUBFRAMES_5MS; - move16(); - - // hParamMC->num_freq_bands = (int16_t)(output_Fs * INV_CLDFB_BANDWIDTH + 0.5f); - hParamMC->num_freq_bands = extract_l( Mpy_32_32_r( output_Fs, INV_CLDFB_BANDWIDTH_Q31 ) ); - move16(); - hParamMC->max_band_energy_compensation = hParamMC->num_freq_bands; - move16(); - ivas_param_mc_metadata_open_fx( mc_ls_setup, ivas_total_brate, hParamMC->hMetadataPMC ); - - /* init arrays for quantized parameters */ - - IF( ( hParamMC->icc_q_fx = (Word16 *) malloc( hParamMC->hMetadataPMC->num_parameter_bands * hParamMC->hMetadataPMC->icc_mapping_conf->icc_map_size_lfe * sizeof( Word16 ) ) ) == NULL ) - { - return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Parametric MC\n" ) ); - } - IF( ( hParamMC->icld_q_fx = (Word16 *) malloc( hParamMC->hMetadataPMC->num_parameter_bands * hParamMC->hMetadataPMC->ild_mapping_conf->ild_map_size_lfe * sizeof( Word16 ) ) ) == NULL ) - { - return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Parametric MC\n" ) ); - } - set16_fx( hParamMC->icld_q_fx, PARAM_MC_DEFAULT_MIN_ILD_FX, imult1616( hParamMC->hMetadataPMC->num_parameter_bands, hParamMC->hMetadataPMC->ild_mapping_conf->ild_map_size_lfe ) ); // Q8 - set16_fx( hParamMC->icc_q_fx, 0, imult1616( hParamMC->hMetadataPMC->num_parameter_bands, hParamMC->hMetadataPMC->icc_mapping_conf->icc_map_size_lfe ) ); // Q15 - - param_mc_set_num_synth_bands( output_Fs, hParamMC ); - - /* Band Grouping */ - IF( EQ_16( hParamMC->hMetadataPMC->num_parameter_bands, 20 ) ) - { - Copy( param_mc_band_grouping_20, hParamMC->band_grouping, 20 + 1 ); - } - ELSE IF( EQ_16( hParamMC->hMetadataPMC->num_parameter_bands, 14 ) ) - { - Copy( param_mc_band_grouping_14, hParamMC->band_grouping, 14 + 1 ); - } - ELSE IF( EQ_16( hParamMC->hMetadataPMC->num_parameter_bands, 10 ) ) - { - Copy( param_mc_band_grouping_10, hParamMC->band_grouping, 10 + 1 ); - } - ELSE - { - assert( 0 && "nbands must be 20, 14, or 10!" ); - } - - /* set max parameter band for abs cov */ - k = 0; - move16(); - WHILE( LE_16( hParamMC->band_grouping[k], PARAM_MC_MAX_BAND_ABS_COV_DEC ) ) - { - hParamMC->max_param_band_abs_cov = k; - move16(); - k = add( k, 1 ); - } - - /*-----------------------------------------------------------------* - * open sub-modules - *-----------------------------------------------------------------*/ - - /* prototype signal computation */ - - test(); - test(); - IF( EQ_32( hParamMC->synthesis_conf, PARAM_MC_SYNTH_LS_CONV_CLDFB ) || EQ_32( hParamMC->synthesis_conf, PARAM_MC_SYNTH_LS_CONV_COV ) || EQ_32( hParamMC->synthesis_conf, PARAM_MC_SYNTH_MONO_STEREO ) ) - { - IF( NE_32( ( error = ivas_ls_setup_conversion_open_fx( st_ivas ) ), IVAS_ERR_OK ) ) - { - return error; - } - - /* convert the ls conv dmx matrix into column order matrix format (nchan_out_cldfb x nchan_out) */ - test(); - IF( EQ_32( hParamMC->synthesis_conf, PARAM_MC_SYNTH_LS_CONV_COV ) || EQ_32( hParamMC->synthesis_conf, PARAM_MC_SYNTH_MONO_STEREO ) ) - { - IF( ( hParamMC->ls_conv_dmx_matrix_fx = (Word32 *) malloc( nchan_out_transport * nchan_out_cov * sizeof( Word32 ) ) ) == NULL ) - { - return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Parametric MC\n" ) ); - } - - FOR( k = 0; k < nchan_out_transport; k++ ) - { - Copy32( st_ivas->hLsSetUpConversion->dmxMtx_fx[k], &hParamMC->ls_conv_dmx_matrix_fx[k * nchan_out_cov], nchan_out_cov ); /*Q30*/ - } - - /* convert ParamMC parameter bands to SFB */ - IF( EQ_32( hParamMC->synthesis_conf, PARAM_MC_SYNTH_MONO_STEREO ) ) - { - st_ivas->hLsSetUpConversion->sfbCnt = hParamMC->num_param_bands_synth; - move16(); - FOR( k = 0; k <= hParamMC->num_param_bands_synth; k++ ) - { - st_ivas->hLsSetUpConversion->sfbOffset[k] = imult1616( PARAM_MC_BAND_TO_MDCT_BAND_RATIO, hParamMC->band_grouping[k] ); - move16(); - } - } - ELSE - { - /* close the ls conversion handle immediately, it was only needed to get the DMX matrix in case of DMX in the covariance domain */ - ivas_ls_setup_conversion_close_fx( &st_ivas->hLsSetUpConversion ); - } - } - } - IF( ( hParamMC->proto_matrix_int_fx = (Word32 *) malloc( nchan_out_transport * nchan_transport * sizeof( Word32 ) ) ) == NULL ) - { - return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Parametric MC\n" ) ); - } - Copy32( ivas_param_mc_conf[config_index].dmx_fac_fx, hParamMC->proto_matrix_int_fx, imult1616( nchan_transport, nchan_out_transport ) ); /*Q31*/ - - hParamMC->proto_matrix_int_len = imult1616( nchan_out_transport, nchan_transport ); - move16(); - - test(); - IF( EQ_32( hParamMC->synthesis_conf, PARAM_MC_SYNTH_LS_CONV_COV ) || EQ_32( hParamMC->synthesis_conf, PARAM_MC_SYNTH_MONO_STEREO ) ) - { - Scale_sig32( hParamMC->ls_conv_dmx_matrix_fx, imult1616( nchan_out_transport, nchan_out_cov ), -4 ); /*Q.26*/ - matrix_product_fx( hParamMC->ls_conv_dmx_matrix_fx, nchan_out_cov, nchan_out_transport, 0, ivas_param_mc_conf[config_index].dmx_fac_fx, nchan_out_transport, nchan_transport, 0, proto_matrix_fx ); /*Q.26*/ - Scale_sig32( hParamMC->ls_conv_dmx_matrix_fx, imult1616( nchan_out_transport, nchan_out_cov ), 4 ); /*Q.26*/ - IF( EQ_32( hParamMC->synthesis_conf, PARAM_MC_SYNTH_MONO_STEREO ) ) - { - proto_mtx_norm_fx = ONE_IN_Q26; /*Q26*/ - move32(); - FOR( k = 0; k < nchan_transport * nchan_out_cov; k++ ) - { - proto_mtx_norm_fx = L_max( L_abs( proto_mtx_norm_fx ), L_abs( proto_matrix_fx[k] ) ); /*Q.26*/ - } - proto_mtx_norm_fx = divide3232( ONE_IN_Q26, proto_mtx_norm_fx ); /*Q15*/ - - /* transfer flattened proto_matrix to 2D in hLsSetupConversion->dmxMtx */ - FOR( k = 0; k < nchan_transport; k++ ) - { - FOR( Word16 i = 0; i < nchan_out_cov; i++ ) - { - st_ivas->hLsSetUpConversion->dmxMtx_fx[k][i] = L_shl( Mult_32_16( proto_matrix_fx[k * nchan_out_cov + i], extract_l( proto_mtx_norm_fx ) ), 4 ); /*Q.30*/ - move32(); - } - } - } - } - ELSE - { - Copy32( ivas_param_mc_conf[config_index].dmx_fac_fx, proto_matrix_fx, imult1616( nchan_out_transport, nchan_transport ) ); /*Q.31*/ - Scale_sig32( proto_matrix_fx, imult1616( nchan_out_transport, nchan_transport ), -5 ); /*Scaling down to 26*/ - } - - IF( EQ_32( hParamMC->synthesis_conf, PARAM_MC_SYNTH_MONO_STEREO ) ) - { - hParamMC->num_outputs_diff = 0; - move16(); - hParamMC->diff_proto_info = NULL; - hParamMC->h_output_synthesis_params.use_onset_filters = 0; - move16(); - hParamMC->max_band_decorr = 0; - move16(); - hParamMC->h_freq_domain_decorr_ap_params = NULL; - hParamMC->h_freq_domain_decorr_ap_state = NULL; - } - ELSE - { - hParamMC->num_outputs_diff = nchan_out_cov; - move16(); - IF( ( hParamMC->diff_proto_info = (PARAM_MC_DIFF_PROTO_INFO *) malloc( sizeof( PARAM_MC_DIFF_PROTO_INFO ) ) ) == NULL ) - { - return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Parametric MC\n" ) ); - } - - IF( NE_32( ( error = param_mc_get_diff_proto_info_fx( proto_matrix_fx, nchan_transport, nchan_out_cov, hParamMC->diff_proto_info, Q26 ) ), IVAS_ERR_OK ) ) - { - return error; - } - - /* decorrelation */ - hParamMC->h_freq_domain_decorr_ap_params = NULL; - hParamMC->h_freq_domain_decorr_ap_state = NULL; - - ivas_dirac_dec_get_frequency_axis_fx( frequency_axis_fx, output_Fs, hParamMC->num_freq_bands ); // Q0 - - IF( NE_32( ( error = ivas_dirac_dec_decorr_open_fx( &( hParamMC->h_freq_domain_decorr_ap_params ), &( hParamMC->h_freq_domain_decorr_ap_state ), hParamMC->num_freq_bands, hParamMC->num_outputs_diff, - hParamMC->diff_proto_info->num_protos_diff, DIRAC_SYNTHESIS_COV_MC_LS, frequency_axis_fx, nchan_transport, output_Fs ) ), - IVAS_ERR_OK ) ) - { - return error; - } - - hParamMC->h_output_synthesis_params.use_onset_filters = 0; - move16(); - hParamMC->max_band_decorr = hParamMC->h_freq_domain_decorr_ap_params->max_band_decorr; - move16(); - } - hParamMC->max_band_energy_compensation = hParamMC->band_grouping[hParamMC->hMetadataPMC->nbands_coded]; - move16(); - max_param_band_residual = 0; - move16(); - - FOR( k = hParamMC->hMetadataPMC->num_parameter_bands; k >= 0; k-- ) - { - IF( LE_16( hParamMC->band_grouping[k], hParamMC->max_band_decorr ) ) - { - max_param_band_residual = k; - move16(); - assert( hParamMC->band_grouping[k] == hParamMC->max_band_decorr ); - break; - } - } - - /* output synthesis */ - IF( NE_32( ( error = ivas_dirac_dec_output_synthesis_cov_open_fx( &( hParamMC->h_output_synthesis_params ), &( hParamMC->h_output_synthesis_cov_state ), hParamMC->max_band_decorr, PARAM_MC_MAX_NSLOTS, hParamMC->hMetadataPMC->num_parameter_bands, max_param_band_residual, nchan_transport, nchan_out_cov, proto_matrix_fx ) ), IVAS_ERR_OK ) ) - { - return error; - } - - ivas_param_mc_dec_compute_interpolator_fx( 0, 0, DEFAULT_JBM_CLDFB_TIMESLOTS, hParamMC->h_output_synthesis_params.interpolator_fx ); - - /* Head or external rotation */ - test(); - test(); - test(); - IF( ( EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_FASTCONV ) || EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_FASTCONV_ROOM ) ) && ( st_ivas->hDecoderConfig->Opt_Headrotation || st_ivas->hDecoderConfig->Opt_ExternalOrientation ) ) - { - IF( ( hParamMC->hoa_encoder_fx = (Word32 *) malloc( st_ivas->hTransSetup.nchan_out_woLFE * MAX_INTERN_CHANNELS * sizeof( Word32 ) ) ) == NULL ) - { - return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Parametric MC\n" ) ); - } - compute_hoa_encoder_mtx_fx( st_ivas->hTransSetup.ls_azimuth_fx, st_ivas->hTransSetup.ls_elevation_fx, hParamMC->hoa_encoder_fx, st_ivas->hTransSetup.nchan_out_woLFE, HEAD_ROTATION_HOA_ORDER ); - } - - /*-----------------------------------------------------------------* - * memory allocation - *-----------------------------------------------------------------*/ - - IF( hParamMC->max_band_decorr > 0 ) - { - IF( ( hParamMC->proto_frame_f_fx = (Word32 *) malloc( 2 * hParamMC->diff_proto_info->num_protos_diff * hParamMC->num_freq_bands * sizeof( Word32 ) ) ) == NULL ) - { - return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Parametric MC\n" ) ); - } - IF( ( hParamMC->proto_frame_dec_f_fx = (Word32 *) malloc( 2 * nchan_out_cov * hParamMC->num_freq_bands * sizeof( Word32 ) ) ) == NULL ) - { - return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Parametric MC\n" ) ); - } - } - ELSE - { - hParamMC->proto_frame_f_fx = NULL; - hParamMC->proto_frame_dec_f_fx = NULL; - } - - ivas_param_mc_dec_init_fx( hParamMC, nchan_transport, nchan_out_cov ); - - IF( NE_32( hParamMC->synthesis_conf, PARAM_MC_SYNTH_MONO_STEREO ) ) - { - Word16 n_cldfb_slots; - - n_cldfb_slots = DEFAULT_JBM_CLDFB_TIMESLOTS; - move16(); - IF( st_ivas->hDecoderConfig->Opt_tsm ) - { - n_cldfb_slots = MAX_JBM_CLDFB_TIMESLOTS; - move16(); - } - - Word16 cldfb_buf_size = imult1616( imult1616( n_cldfb_slots, nchan_transport ), hParamMC->num_freq_bands ); - IF( ( hParamMC->Cldfb_RealBuffer_tc_fx = (Word32 *) malloc( cldfb_buf_size * sizeof( Word32 ) ) ) == NULL ) - { - return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Parametric MC JBM\n" ) ); - } - set32_fx( hParamMC->Cldfb_RealBuffer_tc_fx, 0, cldfb_buf_size ); - IF( ( hParamMC->Cldfb_ImagBuffer_tc_fx = (Word32 *) malloc( cldfb_buf_size * sizeof( Word32 ) ) ) == NULL ) - { - return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Parametric MC JBM\n" ) ); - } - set32_fx( hParamMC->Cldfb_ImagBuffer_tc_fx, 0, cldfb_buf_size ); - - hParamMC->sz = imult1616( imult1616( n_cldfb_slots, nchan_transport ), hParamMC->num_freq_bands ); - move16(); - - IF( st_ivas->hTcBuffer == NULL ) - { - IF( NE_32( ( error = ivas_jbm_dec_tc_buffer_open_fx( st_ivas, TC_BUFFER_MODE_RENDERER, nchan_transport, nchan_transport, 0, NS2SA( st_ivas->hDecoderConfig->output_Fs, CLDFB_SLOT_NS ) ) ), IVAS_ERR_OK ) ) - { - return error; - } - } - } - ELSE - { - hParamMC->Cldfb_RealBuffer_tc_fx = NULL; - hParamMC->Cldfb_ImagBuffer_tc_fx = NULL; - } - - hParamMC->subframes_rendered = 0; - move16(); - hParamMC->slots_rendered = 0; - move16(); - - st_ivas->hParamMC = hParamMC; - return error; -} - - -/*------------------------------------------------------------------------- - * ivas_param_mc_get_param_band_mapping() - * - * - *-------------------------------------------------------------------------*/ - -static void ivas_param_mc_get_param_band_mapping( - const Word16 n_target_bands, - const Word16 *target_band_grouping, - const Word16 n_source_bands, - const Word16 *source_band_grouping, - PARAM_MC_PARAMETER_BAND_MAPPING *parameter_band_mapping ) -{ - Word16 target_band_idx; - Word16 source_band_idx = 0; - move16(); - Word16 source_band_cnt_total; - - FOR( target_band_idx = 0; target_band_idx < n_target_bands; target_band_idx++ ) - { - Word16 upper = target_band_grouping[target_band_idx + 1]; - Word16 lower = target_band_grouping[target_band_idx]; - Word16 source_band_in_target_band_cnt = 0; - Word16 norm_fac_fx = 32767; // 1.Q15 - source_band_cnt_total = 0; - move16(); - move16(); - move16(); - - FOR( source_band_idx = 0; source_band_idx < n_source_bands; source_band_idx++ ) - { - /* find lowest corresponding source band*/ - test(); - IF( LE_16( source_band_grouping[source_band_idx], lower ) && GE_16( source_band_grouping[source_band_idx + 1], lower ) ) - { - DO - { - Word16 source_bands_in_target_band = sub( s_min( source_band_grouping[source_band_idx + 1], upper ), s_max( source_band_grouping[source_band_idx], lower ) ); - IF( source_bands_in_target_band ) - { - source_band_cnt_total = add( source_band_cnt_total, source_bands_in_target_band ); - parameter_band_mapping->source_band_idx[target_band_idx][source_band_in_target_band_cnt] = source_band_idx; - parameter_band_mapping->source_band_factor_fx[target_band_idx][source_band_in_target_band_cnt++] = shl( source_bands_in_target_band, 10 ); /*Q10*/ - move16(); - move16(); - } - source_band_idx++; - } - WHILE( LE_16( source_band_grouping[source_band_idx], upper ) && LT_16( source_band_idx, n_source_bands ) ); - BREAK; - } - } - norm_fac_fx = div_s( 1, source_band_cnt_total ); /*Q15*/ - FOR( source_band_idx = 0; source_band_idx < source_band_in_target_band_cnt; source_band_idx++ ) - { - parameter_band_mapping->source_band_factor_fx[target_band_idx][source_band_idx] = shl_sat( mult( parameter_band_mapping->source_band_factor_fx[target_band_idx][source_band_idx], norm_fac_fx ) /*Q10*/, 5 ); /*Q15*/ - move16(); - } - parameter_band_mapping->n_source_bands[target_band_idx] = source_band_in_target_band_cnt; - move16(); - } - return; -} - - -/*------------------------------------------------------------------------- - * ivas_param_mc_dec_reconfig() - * - * Reconfiguration of ParamMC decoder - *-------------------------------------------------------------------------*/ - -ivas_error ivas_param_mc_dec_reconfig_fx( - Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */ -) -{ - Word16 k, nchan_transport; - PARAM_MC_DEC_HANDLE hParamMC; - Word16 nchan_out_transport; - Word16 nchan_out_cov; - Word32 proto_matrix_fx[MAX_CICP_CHANNELS * PARAM_MC_MAX_TRANSPORT_CHANS]; - Word32 proto_mtx_norm_fx; - Word16 max_param_band_residual; - UWord16 config_index; - MC_LS_SETUP mc_ls_setup; - Word32 output_Fs, ivas_total_brate; - ivas_error error; - Word16 nchan_transport_old; - Word16 num_param_bands_old; - PARAM_MC_PARAMETER_BAND_MAPPING parameter_band_mapping; - Word16 band_grouping_old[20 + 1]; - - hParamMC = st_ivas->hParamMC; - error = IVAS_ERR_OK; - move32(); - /* save important config information from the previous state */ - nchan_transport_old = st_ivas->nchan_transport; - move32(); - num_param_bands_old = hParamMC->hMetadataPMC->num_parameter_bands; - move32(); - - /*-----------------------------------------------------------------* - * prepare library opening - *-----------------------------------------------------------------*/ - - output_Fs = st_ivas->hDecoderConfig->output_Fs; - move32(); - ivas_total_brate = st_ivas->hDecoderConfig->ivas_total_brate; - move32(); - mc_ls_setup = ivas_mc_map_output_config_to_mc_ls_setup_fx( st_ivas->transport_config ); - nchan_out_transport = add( st_ivas->hTransSetup.nchan_out_woLFE, st_ivas->hTransSetup.num_lfe ); - - test(); - IF( EQ_16( hParamMC->synthesis_conf, PARAM_MC_SYNTH_LS_CONV_COV ) || EQ_16( hParamMC->synthesis_conf, PARAM_MC_SYNTH_MONO_STEREO ) ) - { - nchan_out_cov = add( st_ivas->hOutSetup.nchan_out_woLFE, st_ivas->hOutSetup.num_lfe ); - } - ELSE - { - nchan_out_cov = nchan_out_transport; - move16(); - } - - st_ivas->nchan_transport = ivas_param_mc_getNumTransportChannels_fx( ivas_total_brate, mc_ls_setup ); - move16(); - config_index = ivas_param_mc_get_configuration_index_fx( mc_ls_setup, ivas_total_brate ); - nchan_transport = st_ivas->nchan_transport; - move16(); - - SWITCH( nchan_transport ) - { - case 4: - case 3: - st_ivas->nCPE = 2; - move16(); - st_ivas->nSCE = 0; - move16(); - st_ivas->element_mode_init = IVAS_CPE_MDCT; - move16(); - BREAK; - case 2: - st_ivas->nCPE = 1; - move16(); - st_ivas->nSCE = 0; - move16(); - st_ivas->element_mode_init = IVAS_CPE_MDCT; - move16(); - - BREAK; - } - - /*-----------------------------------------------------------------* - * set input parameters - *-----------------------------------------------------------------*/ - hParamMC->num_freq_bands = shr( add( (Word16) Mpy_32_32( output_Fs, INV_CLDFB_BANDWIDTH_Q31 << 1 ), 1 ), 1 ); // Q0 - move16(); - hParamMC->max_band_energy_compensation = hParamMC->num_freq_bands; - move16(); - - Copy( hParamMC->band_grouping, band_grouping_old, add( hParamMC->hMetadataPMC->num_parameter_bands, 1 ) ); - ivas_param_mc_metadata_open_fx( mc_ls_setup, ivas_total_brate, hParamMC->hMetadataPMC ); - /* Band Grouping */ - IF( EQ_16( hParamMC->hMetadataPMC->num_parameter_bands, 20 ) ) - { - Copy( param_mc_band_grouping_20, hParamMC->band_grouping, 20 + 1 ); - } - ELSE IF( EQ_16( hParamMC->hMetadataPMC->num_parameter_bands, 14 ) ) - { - Copy( param_mc_band_grouping_14, hParamMC->band_grouping, 14 + 1 ); - } - ELSE IF( EQ_16( hParamMC->hMetadataPMC->num_parameter_bands, 10 ) ) - { - Copy( param_mc_band_grouping_10, hParamMC->band_grouping, 10 + 1 ); - } - ELSE - { - assert( 0 && "nbands must be 20, 14, or 10!" ); - } - - ivas_param_mc_get_param_band_mapping( hParamMC->hMetadataPMC->num_parameter_bands, hParamMC->band_grouping, num_param_bands_old, band_grouping_old, ¶meter_band_mapping ); - - test(); - IF( NE_16( nchan_transport_old, nchan_transport ) || NE_16( num_param_bands_old, hParamMC->hMetadataPMC->num_parameter_bands ) ) - { - Word16 *ild_q_old_fx = hParamMC->icld_q_fx; // Q8 - Word16 *icc_q_old_fx = hParamMC->icc_q_fx; // Q15 - - IF( ( hParamMC->icc_q_fx = (Word16 *) malloc( hParamMC->hMetadataPMC->num_parameter_bands * hParamMC->hMetadataPMC->icc_mapping_conf->icc_map_size_lfe * sizeof( Word16 ) ) ) == NULL ) - { - return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Parametric MC\n" ) ); - } - IF( ( hParamMC->icld_q_fx = (Word16 *) malloc( hParamMC->hMetadataPMC->num_parameter_bands * hParamMC->hMetadataPMC->ild_mapping_conf->ild_map_size_lfe * sizeof( Word16 ) ) ) == NULL ) - { - return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Parametric MC\n" ) ); - } - set16_fx( hParamMC->icld_q_fx, PARAM_MC_DEFAULT_MIN_ILD_FX, hParamMC->hMetadataPMC->num_parameter_bands * hParamMC->hMetadataPMC->ild_mapping_conf->ild_map_size_lfe ); /*Q8*/ - set16_fx( hParamMC->icc_q_fx, 0, hParamMC->hMetadataPMC->num_parameter_bands * hParamMC->hMetadataPMC->icc_mapping_conf->icc_map_size_lfe ); /*Q15*/ - - /* map old to new parameter banding, only for same number of TCs, needs some more thought for a changing number of TCs */ - test(); - IF( NE_16( num_param_bands_old, hParamMC->hMetadataPMC->num_parameter_bands ) && EQ_16( nchan_transport_old, nchan_transport ) ) - { - Word16 new_param_band_idx, param_idx, source_param_idx; - Word16 num_param_lfe; - Word16 *p_icc_new_fx = hParamMC->icc_q_fx; // Q15 - Word16 *p_ild_new_fx = hParamMC->icld_q_fx; // Q8 - Word16 p_ild_new_e = 23; - move16(); - Word16 p_ild_new_tmp; - - /* ICC */ - num_param_lfe = hParamMC->hMetadataPMC->icc_mapping_conf->icc_map_size_lfe; - move16(); - FOR( new_param_band_idx = 0; new_param_band_idx < hParamMC->hMetadataPMC->num_parameter_bands; new_param_band_idx++ ) - { - FOR( param_idx = 0; param_idx < num_param_lfe; param_idx++ ) - { - *p_icc_new_fx = 0; - move16(); - FOR( source_param_idx = 0; source_param_idx < parameter_band_mapping.n_source_bands[new_param_band_idx]; source_param_idx++ ) - { - *p_icc_new_fx = add( *p_icc_new_fx, mult( icc_q_old_fx[parameter_band_mapping.source_band_idx[new_param_band_idx][source_param_idx] * num_param_lfe + param_idx], parameter_band_mapping.source_band_factor_fx[new_param_band_idx][source_param_idx] ) ); /*Q15*/ - move16(); - } - p_icc_new_fx++; - } - } - - /* ILD */ - num_param_lfe = hParamMC->hMetadataPMC->ild_mapping_conf->ild_map_size_lfe; - move16(); - FOR( new_param_band_idx = 0; new_param_band_idx < hParamMC->hMetadataPMC->num_parameter_bands; new_param_band_idx++ ) - { - FOR( param_idx = 0; param_idx < num_param_lfe; param_idx++ ) - { - *p_ild_new_fx = 0; - move16(); - FOR( source_param_idx = 0; source_param_idx < parameter_band_mapping.n_source_bands[new_param_band_idx]; source_param_idx++ ) - { - p_ild_new_tmp = extract_h( BASOP_util_Pow2( L_mult0( 10885 /*log2(10)/10*2^15*/, ild_q_old_fx[parameter_band_mapping.source_band_idx[new_param_band_idx][source_param_idx] * num_param_lfe + param_idx] ), 8, &p_ild_new_e ) ); // 31 - p_ild_new_e - 16 - *p_ild_new_fx = add( *p_ild_new_fx, mult( p_ild_new_tmp, parameter_band_mapping.source_band_factor_fx[new_param_band_idx][source_param_idx] ) ); - move16(); - } - *p_ild_new_fx = extract_l( L_shr( Mpy_32_16_1( L_add( BASOP_Util_Log2( *p_ild_new_fx ), L_add( 16 << Q25, L_shl( p_ild_new_e, 25 ) ) ), 24660 /*3.Q13*/ ), 15 ) ); // Q8 - move16(); - p_ild_new_fx++; - } - } - } - free( ild_q_old_fx ); - free( icc_q_old_fx ); - } - - param_mc_set_num_synth_bands( output_Fs, hParamMC ); - - /* set max parameter band for abs cov */ - k = 0; - move16(); - WHILE( LE_16( hParamMC->band_grouping[k], PARAM_MC_MAX_BAND_ABS_COV_DEC ) ) - { - hParamMC->max_param_band_abs_cov = k; - move16(); - k = add( k, 1 ); - } - - /*-----------------------------------------------------------------* - * open sub-modules - *-----------------------------------------------------------------*/ - - /* prototype signal computation */ - - IF( EQ_16( hParamMC->synthesis_conf, PARAM_MC_SYNTH_MONO_STEREO ) ) - { - IF( NE_16( nchan_transport_old, nchan_transport ) ) - { - IF( st_ivas->hLsSetUpConversion != NULL ) - { - ivas_ls_setup_conversion_close_fx( &st_ivas->hLsSetUpConversion ); - } - - IF( NE_32( ( error = ivas_ls_setup_conversion_open_fx( st_ivas ) ), IVAS_ERR_OK ) ) - { - return error; - } - - /* convert the ls conv dmx matrix into column order matrix format (nchan_out_cldfb x nchan_out) */ - free( hParamMC->ls_conv_dmx_matrix_fx ); - - IF( ( hParamMC->ls_conv_dmx_matrix_fx = (Word32 *) malloc( nchan_out_transport * nchan_out_cov * sizeof( Word32 ) ) ) == NULL ) - { - return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Parametric MC\n" ) ); - } - FOR( k = 0; k < nchan_out_transport; k++ ) - { - Copy32( st_ivas->hLsSetUpConversion->dmxMtx_fx[k], &hParamMC->ls_conv_dmx_matrix_fx[k * nchan_out_cov], nchan_out_cov ); - } - } - /* convert ParamMC parameter bands to SFB */ - - st_ivas->hLsSetUpConversion->sfbCnt = hParamMC->num_param_bands_synth; - move16(); - FOR( k = 0; k <= hParamMC->num_param_bands_synth; k++ ) - { - st_ivas->hLsSetUpConversion->sfbOffset[k] = imult1616( PARAM_MC_BAND_TO_MDCT_BAND_RATIO, hParamMC->band_grouping[k] ); - move16(); - } - FOR( ; k < MAX_SFB + 2; k++ ) - { - st_ivas->hLsSetUpConversion->sfbOffset[k] = 0; - move16(); - } - } - - IF( NE_16( nchan_transport_old, nchan_transport ) ) - { - free( hParamMC->proto_matrix_int_fx ); - IF( ( hParamMC->proto_matrix_int_fx = (Word32 *) malloc( nchan_out_transport * nchan_transport * sizeof( Word32 ) ) ) == NULL ) - { - return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Parametric MC\n" ) ); - } - hParamMC->proto_matrix_int_len = imult1616( nchan_out_transport, nchan_transport ); - move16(); - Copy32( ivas_param_mc_conf[config_index].dmx_fac_fx, hParamMC->proto_matrix_int_fx, hParamMC->proto_matrix_int_len ); /*Q31*/ - } - - test(); - IF( EQ_16( hParamMC->synthesis_conf, PARAM_MC_SYNTH_LS_CONV_COV ) || EQ_16( hParamMC->synthesis_conf, PARAM_MC_SYNTH_MONO_STEREO ) ) - { - Scale_sig32( hParamMC->ls_conv_dmx_matrix_fx, imult1616( nchan_out_transport, nchan_out_cov ), -4 ); // Q30 -> Q26 - matrix_product_fx( hParamMC->ls_conv_dmx_matrix_fx, nchan_out_cov, nchan_out_transport, 0, - ivas_param_mc_conf[config_index].dmx_fac_fx, nchan_out_transport, nchan_transport, 0, - proto_matrix_fx /*Q26*/ ); - Scale_sig32( hParamMC->ls_conv_dmx_matrix_fx, imult1616( nchan_out_transport, nchan_out_cov ), 4 ); // Q26 -> Q30 - - IF( EQ_16( hParamMC->synthesis_conf, PARAM_MC_SYNTH_MONO_STEREO ) ) - { - proto_mtx_norm_fx = ONE_IN_Q26; // Q26 - move32(); - FOR( k = 0; k < nchan_transport * nchan_out_cov; k++ ) - { - proto_mtx_norm_fx = L_max( L_abs( proto_mtx_norm_fx ), L_abs( proto_matrix_fx[k] ) ); // Q26 - } - proto_mtx_norm_fx = divide3232( ONE_IN_Q26, proto_mtx_norm_fx ); /*Q15*/ - - /* transfer flattened proto_matrix to 2D in hLsSetupConversion->dmxMtx */ - FOR( k = 0; k < nchan_transport; k++ ) - { - FOR( Word16 i = 0; i < nchan_out_cov; i++ ) - { - st_ivas->hLsSetUpConversion->dmxMtx_fx[k][i] = L_shl( Mpy_32_16_1( proto_matrix_fx[k * nchan_out_cov + i], (Word16) proto_mtx_norm_fx ), 4 ); // Q26 -> Q30 - move32(); - } - } - } - } - ELSE - { - Copy32( ivas_param_mc_conf[config_index].dmx_fac_fx, proto_matrix_fx, imult1616( nchan_out_transport, nchan_transport ) ); // proto_matrix_fx -> Q31 - Scale_sig32( proto_matrix_fx, imult1616( nchan_out_transport, nchan_transport ), -5 ); // proto_matrix_fx -> Q26 - } - - test(); - IF( NE_16( nchan_transport_old, nchan_transport ) && NE_16( hParamMC->synthesis_conf, PARAM_MC_SYNTH_MONO_STEREO ) ) - { - Word16 i; - Word16 len; - - /* close decorrelator */ - ivas_dirac_dec_decorr_close_fx( &hParamMC->h_freq_domain_decorr_ap_params, &hParamMC->h_freq_domain_decorr_ap_state ); - - /* deallocate diffuse prototype info */ - IF( hParamMC->diff_proto_info ) - { - FOR( i = 0; i < hParamMC->diff_proto_info->num_protos_diff; i++ ) - { - free( hParamMC->diff_proto_info->source_chan_idx[i] ); - hParamMC->diff_proto_info->source_chan_idx[i] = NULL; - - free( hParamMC->diff_proto_info->proto_fac_fx[i] ); - hParamMC->diff_proto_info->proto_fac_fx[i] = NULL; - } - - free( hParamMC->diff_proto_info->source_chan_idx ); - hParamMC->diff_proto_info->source_chan_idx = NULL; - - free( hParamMC->diff_proto_info->proto_fac_fx ); - hParamMC->diff_proto_info->proto_fac_fx = NULL; - - free( hParamMC->diff_proto_info->proto_index_diff ); - hParamMC->diff_proto_info->proto_index_diff = NULL; - - free( hParamMC->diff_proto_info->num_source_chan_diff ); - hParamMC->diff_proto_info->num_source_chan_diff = NULL; - - free( hParamMC->diff_proto_info ); - hParamMC->diff_proto_info = NULL; - } - - hParamMC->num_outputs_diff = nchan_out_cov; - move16(); - IF( ( hParamMC->diff_proto_info = (PARAM_MC_DIFF_PROTO_INFO *) malloc( sizeof( PARAM_MC_DIFF_PROTO_INFO ) ) ) == NULL ) - { - return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Parametric MC\n" ) ); - } - IF( ( param_mc_get_diff_proto_info_fx( proto_matrix_fx, nchan_transport, nchan_out_cov, hParamMC->diff_proto_info, Q26 ) ) != IVAS_ERR_OK ) - { - return error; - } - - /* decorrelation */ - hParamMC->h_freq_domain_decorr_ap_params = NULL; - hParamMC->h_freq_domain_decorr_ap_state = NULL; - - Word16 frequency_axis_fx[CLDFB_NO_CHANNELS_MAX]; - ivas_dirac_dec_get_frequency_axis_fx( frequency_axis_fx, output_Fs, hParamMC->num_freq_bands ); // Q0 - - IF( NE_32( ( error = ivas_dirac_dec_decorr_open_fx( &( hParamMC->h_freq_domain_decorr_ap_params ), &( hParamMC->h_freq_domain_decorr_ap_state ), hParamMC->num_freq_bands, hParamMC->num_outputs_diff, - hParamMC->diff_proto_info->num_protos_diff, DIRAC_SYNTHESIS_COV_MC_LS, frequency_axis_fx, nchan_transport, output_Fs ) ), - IVAS_ERR_OK ) ) - { - return error; - } - hParamMC->h_output_synthesis_params.use_onset_filters = 0; - move16(); - hParamMC->max_band_decorr = hParamMC->h_freq_domain_decorr_ap_params->max_band_decorr; - move16(); - /* init decorrelation */ - IF( hParamMC->max_band_decorr > 0 ) - { - - len = imult1616( hParamMC->diff_proto_info->num_protos_diff, hParamMC->h_freq_domain_decorr_ap_params->h_onset_detection_power_params.max_band_decorr ); - - /* init onsetDetectionPower */ - set_zero_fx( hParamMC->h_freq_domain_decorr_ap_state->h_onset_detection_power_state.onset_detector_1_fx, len ); - set_zero_fx( hParamMC->h_freq_domain_decorr_ap_state->h_onset_detection_power_state.onset_detector_2_fx, len ); - hParamMC->h_freq_domain_decorr_ap_state->h_onset_detection_power_state.q_onset_detector = Q31; - move16(); - } - } - hParamMC->max_band_energy_compensation = hParamMC->band_grouping[hParamMC->hMetadataPMC->nbands_coded]; - move16(); - max_param_band_residual = 0; - move16(); - - FOR( k = hParamMC->hMetadataPMC->num_parameter_bands; k >= 0; k-- ) - { - IF( LE_16( hParamMC->band_grouping[k], hParamMC->max_band_decorr ) ) - { - max_param_band_residual = k; - move16(); - assert( hParamMC->band_grouping[k] == hParamMC->max_band_decorr ); - BREAK; - } - } - - test(); - IF( NE_16( nchan_transport_old, nchan_transport ) || NE_16( num_param_bands_old, hParamMC->hMetadataPMC->num_parameter_bands ) ) - { - DIRAC_OUTPUT_SYNTHESIS_COV_STATE cov_state_old = hParamMC->h_output_synthesis_cov_state; - DIRAC_OUTPUT_SYNTHESIS_PARAMS params_old = hParamMC->h_output_synthesis_params; - - Word32 tmp_buf_fx[MAX_CICP_CHANNELS * MAX_CICP_CHANNELS]; - - set_zero_fx( tmp_buf_fx, MAX_CICP_CHANNELS * MAX_CICP_CHANNELS ); - - /* output synthesis */ - IF( NE_32( ( error = ivas_dirac_dec_output_synthesis_cov_open_fx( &( hParamMC->h_output_synthesis_params ), &( hParamMC->h_output_synthesis_cov_state ), hParamMC->max_band_decorr, PARAM_MC_MAX_NSLOTS, - hParamMC->hMetadataPMC->num_parameter_bands, max_param_band_residual, nchan_transport, nchan_out_cov, proto_matrix_fx ) ), - IVAS_ERR_OK ) ) - { - return error; - } - - ivas_param_mc_dec_compute_interpolator_fx( 0, 0, DEFAULT_JBM_CLDFB_TIMESLOTS, hParamMC->h_output_synthesis_params.interpolator_fx ); - - ivas_dirac_dec_output_synthesis_cov_init_fx( &( hParamMC->h_output_synthesis_cov_state ), nchan_transport, nchan_out_cov, hParamMC->hMetadataPMC->num_parameter_bands, max_param_band_residual ); - - /* map old to new parameter banding, only for same number of TCs, needs some more thought for changing number of TCs */ - test(); - IF( NE_16( num_param_bands_old, hParamMC->hMetadataPMC->num_parameter_bands ) && EQ_16( nchan_transport_old, nchan_transport ) ) - { - Word16 new_param_band_idx, source_param_idx; - - FOR( new_param_band_idx = 0; new_param_band_idx < hParamMC->hMetadataPMC->num_parameter_bands; new_param_band_idx++ ) - { - FOR( source_param_idx = 0; source_param_idx < parameter_band_mapping.n_source_bands[new_param_band_idx]; source_param_idx++ ) - { - /* Cx */ - v_multc_fixed_16( cov_state_old.cx_old_fx[parameter_band_mapping.source_band_idx[new_param_band_idx][source_param_idx]], parameter_band_mapping.source_band_factor_fx[new_param_band_idx][source_param_idx], tmp_buf_fx, imult1616( nchan_transport_old, nchan_transport_old ) ); // Q(31 - cov_state_old.cx_old_e) - v_add_fixed_me( tmp_buf_fx, cov_state_old.cx_old_e[parameter_band_mapping.source_band_idx[new_param_band_idx][source_param_idx]], hParamMC->h_output_synthesis_cov_state.cx_old_fx[new_param_band_idx], hParamMC->h_output_synthesis_cov_state.cx_old_e[new_param_band_idx], hParamMC->h_output_synthesis_cov_state.cx_old_fx[new_param_band_idx], &hParamMC->h_output_synthesis_cov_state.cx_old_e[new_param_band_idx], imult1616( nchan_transport_old, nchan_transport_old ), 0 ); // Q(31 - hParamMC->h_output_synthesis_cov_state.cx_old_e[new_param_band_idx]) - /* Cy */ - v_multc_fixed_16( cov_state_old.cy_old_fx[parameter_band_mapping.source_band_idx[new_param_band_idx][source_param_idx]], parameter_band_mapping.source_band_factor_fx[new_param_band_idx][source_param_idx], tmp_buf_fx, imult1616( nchan_out_cov, nchan_out_cov ) ); // Q(31 - cov_state_old.cy_old_e) - v_add_fixed_me( tmp_buf_fx, cov_state_old.cy_old_e[parameter_band_mapping.source_band_idx[new_param_band_idx][source_param_idx]], hParamMC->h_output_synthesis_cov_state.cy_old_fx[new_param_band_idx], hParamMC->h_output_synthesis_cov_state.cy_old_e[new_param_band_idx], hParamMC->h_output_synthesis_cov_state.cy_old_fx[new_param_band_idx], &hParamMC->h_output_synthesis_cov_state.cy_old_e[new_param_band_idx], imult1616( nchan_out_cov, nchan_out_cov ), 0 ); // Q(31 - hParamMC->h_output_synthesis_cov_state.cy_old_e[new_param_band_idx]) - /* mixing matrix*/ - v_multc_fixed_16( cov_state_old.mixing_matrix_old_fx[parameter_band_mapping.source_band_idx[new_param_band_idx][source_param_idx]], parameter_band_mapping.source_band_factor_fx[new_param_band_idx][source_param_idx], tmp_buf_fx, imult1616( nchan_transport_old, nchan_out_cov ) ); // Q(31 - mixing_matrix_old_exp) - v_add_fixed_me( tmp_buf_fx, cov_state_old.mixing_matrix_old_exp[parameter_band_mapping.source_band_idx[new_param_band_idx][source_param_idx]], hParamMC->h_output_synthesis_cov_state.mixing_matrix_old_fx[new_param_band_idx], hParamMC->h_output_synthesis_cov_state.mixing_matrix_old_exp[new_param_band_idx], hParamMC->h_output_synthesis_cov_state.mixing_matrix_old_fx[new_param_band_idx], &hParamMC->h_output_synthesis_cov_state.mixing_matrix_old_exp[new_param_band_idx], imult1616( nchan_transport_old, nchan_out_cov ), 0 ); // Q(31 - hParamMC->h_output_synthesis_cov_state.mixing_matrix_old_exp[new_param_band_idx]) - } - } - FOR( new_param_band_idx = 0; new_param_band_idx < max_param_band_residual; new_param_band_idx++ ) - { - FOR( source_param_idx = 0; source_param_idx < parameter_band_mapping.n_source_bands[new_param_band_idx]; source_param_idx++ ) - { - /* residual mixing matrix*/ - v_multc_fixed_16( cov_state_old.mixing_matrix_res_old_fx[parameter_band_mapping.source_band_idx[new_param_band_idx][source_param_idx]], parameter_band_mapping.source_band_factor_fx[new_param_band_idx][source_param_idx], tmp_buf_fx, imult1616( nchan_out_cov, nchan_out_cov ) ); // Q(31 - mixing_matrix_res_old_exp) - v_add_fixed_me( tmp_buf_fx, cov_state_old.mixing_matrix_res_old_exp[parameter_band_mapping.source_band_idx[new_param_band_idx][source_param_idx]], hParamMC->h_output_synthesis_cov_state.mixing_matrix_res_old_fx[new_param_band_idx], hParamMC->h_output_synthesis_cov_state.mixing_matrix_res_old_exp[new_param_band_idx], hParamMC->h_output_synthesis_cov_state.mixing_matrix_res_old_fx[new_param_band_idx], &hParamMC->h_output_synthesis_cov_state.mixing_matrix_res_old_exp[new_param_band_idx], imult1616( nchan_out_cov, nchan_out_cov ), 0 ); // Q(hParamMC->h_output_synthesis_cov_state.mixing_matrix_res_old_exp[new_param_band_idx]) - } - } - } - ivas_dirac_dec_output_synthesis_cov_close_fx( ¶ms_old, &cov_state_old ); - } - - /*-----------------------------------------------------------------* - * memory allocation - *-----------------------------------------------------------------*/ - - test(); - IF( ( hParamMC->max_band_decorr > 0 ) && NE_16( nchan_transport_old, nchan_transport ) ) - { - free( hParamMC->proto_frame_f_fx ); - IF( ( hParamMC->proto_frame_f_fx = (Word32 *) malloc( 2 * hParamMC->diff_proto_info->num_protos_diff * hParamMC->num_freq_bands * sizeof( Word32 ) ) ) == NULL ) - { - return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Parametric MC\n" ) ); - } - set_zero_fx( hParamMC->proto_frame_f_fx, shl( imult1616( hParamMC->diff_proto_info->num_protos_diff, hParamMC->num_freq_bands ), 1 ) ); - } - - - IF( NE_16( nchan_transport_old, nchan_transport ) ) - { - IF( NE_16( hParamMC->synthesis_conf, PARAM_MC_SYNTH_MONO_STEREO ) ) - { - Word16 n_cldfb_slots; - IF( hParamMC->Cldfb_RealBuffer_tc_fx != NULL ) - { - free( hParamMC->Cldfb_RealBuffer_tc_fx ); - hParamMC->Cldfb_RealBuffer_tc_fx = NULL; // Q12 - } - IF( hParamMC->Cldfb_ImagBuffer_tc_fx != NULL ) - { - free( hParamMC->Cldfb_ImagBuffer_tc_fx ); - hParamMC->Cldfb_ImagBuffer_tc_fx = NULL; // Q12 - } - - n_cldfb_slots = DEFAULT_JBM_CLDFB_TIMESLOTS; - move16(); - IF( st_ivas->hDecoderConfig->Opt_tsm ) - { - n_cldfb_slots = MAX_JBM_CLDFB_TIMESLOTS; - move16(); - } - Word16 cldfb_size = imult1616( imult1616( n_cldfb_slots, nchan_transport ), hParamMC->num_freq_bands ); - IF( ( hParamMC->Cldfb_RealBuffer_tc_fx = (Word32 *) malloc( cldfb_size * sizeof( Word32 ) ) ) == NULL ) - { - return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Parametric MC JBM\n" ) ); - } - set_zero_fx( hParamMC->Cldfb_RealBuffer_tc_fx, cldfb_size ); - - IF( ( hParamMC->Cldfb_ImagBuffer_tc_fx = (Word32 *) malloc( cldfb_size * sizeof( Word32 ) ) ) == NULL ) - { - return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Parametric MC JBM\n" ) ); - } - set_zero_fx( hParamMC->Cldfb_ImagBuffer_tc_fx, cldfb_size ); - } - ELSE - { - IF( hParamMC->Cldfb_RealBuffer_tc_fx != NULL ) - { - free( hParamMC->Cldfb_RealBuffer_tc_fx ); - hParamMC->Cldfb_RealBuffer_tc_fx = NULL; - } - IF( hParamMC->Cldfb_ImagBuffer_tc_fx != NULL ) - { - free( hParamMC->Cldfb_ImagBuffer_tc_fx ); - hParamMC->Cldfb_ImagBuffer_tc_fx = NULL; - } - } - } - return error; -} - - -/*------------------------------------------------------------------------- - * param_mc_get_num_cldfb_syntheses() - * - * calculate the necessary number of CLDFB synthesis instances - *------------------------------------------------------------------------*/ - -/*! r: number of cldfb synthesis instances */ -Word16 param_mc_get_num_cldfb_syntheses_fx( - Decoder_Struct *st_ivas /* i : Parametric MC handle */ -) -{ - Word16 num_cldfb_syntheses; - - num_cldfb_syntheses = 0; - move16(); - - /* sanity check*/ - IF( st_ivas->hParamMC == NULL ) - { - assert( 0 && "ParamMC handle does not exist!\n" ); - } - - test(); - IF( EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_FASTCONV ) || EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_FASTCONV_ROOM ) ) - { - num_cldfb_syntheses = 2; - move16(); - } - ELSE IF( EQ_32( st_ivas->renderer_type, RENDERER_SBA_LINEAR_ENC ) ) - { - num_cldfb_syntheses = add( st_ivas->hTransSetup.nchan_out_woLFE, st_ivas->hTransSetup.num_lfe ); - } - ELSE IF( EQ_32( st_ivas->renderer_type, RENDERER_MC_PARAMMC ) ) - { - num_cldfb_syntheses = add( st_ivas->hOutSetup.nchan_out_woLFE, st_ivas->hOutSetup.num_lfe ); - } - - return num_cldfb_syntheses; -} - - -/*------------------------------------------------------------------------- - * ivas_param_mc_dec_close() - * - * Close Parametric MC memories - *------------------------------------------------------------------------*/ - -void ivas_param_mc_dec_close_fx( - PARAM_MC_DEC_HANDLE *hParamMC_out /* i/o: Parametric MC decoder handle */ -) -{ - UWord16 i; - PARAM_MC_DEC_HANDLE hParamMC; - - IF( hParamMC_out == NULL || *hParamMC_out == NULL ) - { - return; - } - - hParamMC = *hParamMC_out; - - /* close sub-modules */ - ivas_dirac_dec_output_synthesis_cov_close_fx( &hParamMC->h_output_synthesis_params, &hParamMC->h_output_synthesis_cov_state ); - - IF( hParamMC->h_freq_domain_decorr_ap_params != NULL || hParamMC->h_freq_domain_decorr_ap_state != NULL ) - { - ivas_dirac_dec_decorr_close_fx( &hParamMC->h_freq_domain_decorr_ap_params, &hParamMC->h_freq_domain_decorr_ap_state ); - } - - /* parameter decoding */ - IF( hParamMC->hMetadataPMC != NULL ) - { - free( hParamMC->hMetadataPMC ); - hParamMC->hMetadataPMC = NULL; - } - IF( hParamMC->icc_q_fx != NULL ) - { - free( hParamMC->icc_q_fx ); - hParamMC->icc_q_fx = NULL; // Q15 - } - - IF( hParamMC->icld_q_fx != NULL ) - { - free( hParamMC->icld_q_fx ); - hParamMC->icld_q_fx = NULL; // Q8 - } - /* diffuse prototype info */ - IF( hParamMC->diff_proto_info ) - { - FOR( i = 0; i < hParamMC->diff_proto_info->num_protos_diff; i++ ) - { - free( hParamMC->diff_proto_info->source_chan_idx[i] ); - hParamMC->diff_proto_info->source_chan_idx[i] = NULL; - - free( hParamMC->diff_proto_info->proto_fac_fx[i] ); - hParamMC->diff_proto_info->proto_fac_fx[i] = NULL; - } - - free( hParamMC->diff_proto_info->source_chan_idx ); - hParamMC->diff_proto_info->source_chan_idx = NULL; - - free( hParamMC->diff_proto_info->proto_fac_fx ); - hParamMC->diff_proto_info->proto_fac_fx = NULL; - - free( hParamMC->diff_proto_info->proto_index_diff ); - hParamMC->diff_proto_info->proto_index_diff = NULL; - - free( hParamMC->diff_proto_info->num_source_chan_diff ); - hParamMC->diff_proto_info->num_source_chan_diff = NULL; - - free( hParamMC->diff_proto_info ); - hParamMC->diff_proto_info = NULL; - } - /* States */ - /* free prototype signal buffers */ - IF( hParamMC->proto_frame_f_fx != NULL ) - { - free( hParamMC->proto_frame_f_fx ); - hParamMC->proto_frame_f_fx = NULL; - } - - IF( hParamMC->proto_frame_dec_f_fx != NULL ) - { - free( hParamMC->proto_frame_dec_f_fx ); - hParamMC->proto_frame_dec_f_fx = NULL; - } - - IF( hParamMC->ls_conv_dmx_matrix_fx != NULL ) - { - free( hParamMC->ls_conv_dmx_matrix_fx ); - hParamMC->ls_conv_dmx_matrix_fx = NULL; - } - - IF( hParamMC->proto_matrix_int_fx != NULL ) - { - free( hParamMC->proto_matrix_int_fx ); - hParamMC->proto_matrix_int_fx = NULL; - } - - IF( hParamMC->hoa_encoder_fx != NULL ) - { - free( hParamMC->hoa_encoder_fx ); - hParamMC->hoa_encoder_fx = NULL; - } - IF( hParamMC->Cldfb_RealBuffer_tc_fx != NULL ) - { - free( hParamMC->Cldfb_RealBuffer_tc_fx ); - hParamMC->Cldfb_RealBuffer_tc_fx = NULL; - } - IF( hParamMC->Cldfb_ImagBuffer_tc_fx != NULL ) - { - free( hParamMC->Cldfb_ImagBuffer_tc_fx ); - hParamMC->Cldfb_ImagBuffer_tc_fx = NULL; - } - - free( *hParamMC_out ); - *hParamMC_out = NULL; - - return; -} - - -/*------------------------------------------------------------------------- - * ivas_param_mc_dec_read_BS() - * - * Read the Parametric MC metadata - *------------------------------------------------------------------------*/ - -void ivas_param_mc_dec_read_BS_fx( - const Word32 ivas_total_brate, /* i : IVAS total bitrate */ - Decoder_State *st, /* i/o: decoder state structure */ - PARAM_MC_DEC_HANDLE hParamMC, /* i/o: decoder ParamMC handle */ - Word16 *nb_bits /* o : number of bits written */ -) -{ - Word16 param_frame_idx; - Word16 band_step; - UWord16 bit_buffer[PARAM_MC_MAX_BITS]; - Word16 bits_to_copy; - Word16 bit_pos; - Word16 num_lfe_bands; - Word16 num_param_bands; - Word16 metadata_bit_pos; - Word16 i, j, k; - Word16 icc_map_size; - Word16 icc_map_size_wo_lfe; - Word16 ild_map_size; - Word16 ild_map_size_wo_lfe; - HANDLE_IVAS_PARAM_MC_METADATA hMetadataPMC; - - push_wmops( "param_mc_read_bs" ); - - /* Inits */ - *nb_bits = 0; - move16(); - hMetadataPMC = hParamMC->hMetadataPMC; - icc_map_size = hMetadataPMC->icc_mapping_conf->icc_map_size_lfe; - move16(); - icc_map_size_wo_lfe = hMetadataPMC->icc_mapping_conf->icc_map_size_wo_lfe; - move16(); - ild_map_size = hMetadataPMC->ild_mapping_conf->ild_map_size_lfe; - move16(); - ild_map_size_wo_lfe = hMetadataPMC->ild_mapping_conf->ild_map_size_wo_lfe; - move16(); - - IF( !st->bfi ) - { - /*metadata_bit_pos = extract_l(ivas_total_brate / FRAMES_PER_SEC - 1); - bits_to_copy = s_min(extract_l(ivas_total_brate / FRAMES_PER_SEC), PARAM_MC_MAX_BITS);*/ - Word16 temp = extract_l( Mpy_32_32_r( ivas_total_brate, ONE_BY_FRAMES_PER_SEC_Q31 ) ); - metadata_bit_pos = sub( temp, 1 ); - bits_to_copy = s_min( temp, PARAM_MC_MAX_BITS ); - - /* copy and reverse metadata */ - FOR( bit_pos = 0; bit_pos < bits_to_copy; bit_pos++ ) - { - bit_buffer[bit_pos] = st->bit_stream[metadata_bit_pos]; - move16(); - metadata_bit_pos = sub( metadata_bit_pos, 1 ); - move16(); - } - - bit_pos = 0; - move16(); - - /* read reserved bit */ - hMetadataPMC->lfe_on = bit_buffer[bit_pos++]; - move16(); - - /* get coded bwidth */ - { - Word16 pos; - Word16 bw = 0; - move16(); - FOR( pos = 0; pos < 2; pos++ ) - { - bw = add( bw, extract_l( L_shl( bit_buffer[bit_pos++], pos ) ) ); - } - hMetadataPMC->coded_bwidth = bw; - move16(); - } - - /* set tables if coded band width differs from last frame */ - IF( NE_16( hMetadataPMC->coded_bwidth, hMetadataPMC->last_coded_bwidth ) ) - { - ivas_param_mc_set_coded_bands_fx( hMetadataPMC ); - param_mc_set_num_synth_bands( st->output_Fs, hParamMC ); - hParamMC->max_band_energy_compensation = hParamMC->band_grouping[hParamMC->num_param_bands_synth]; - move16(); - } - - param_frame_idx = bit_buffer[bit_pos++]; - move16(); - hMetadataPMC->param_frame_idx = param_frame_idx; - move16(); - num_param_bands = hMetadataPMC->nbands_in_param_frame[param_frame_idx]; - move16(); - - hMetadataPMC->bAttackPresent = bit_buffer[bit_pos++]; - move16(); - hMetadataPMC->attackIndex = 0; - move16(); - band_step = 1; - move16(); - num_lfe_bands = 0; - move16(); - - IF( hMetadataPMC->bAttackPresent ) - { - FOR( i = 2; i >= 0; i-- ) - { - hMetadataPMC->attackIndex = add( hMetadataPMC->attackIndex, extract_l( L_shl( bit_buffer[bit_pos++], i ) ) ); - } - - band_step = PARAM_MC_TRANSIENT_BAND_STEP; - move16(); - - /*num_lfe_bands = add(PARAM_MC_MAX_BAND_LFE / band_step, (PARAM_MC_MAX_BAND_LFE % band_step) ? 1 : 0); - num_param_bands = add(hMetadataPMC->nbands_coded / band_step, ((hMetadataPMC->nbands_coded % band_step) ? 1 : 0));*/ - Word16 temp_e; - temp = BASOP_Util_Divide3232_Scale( PARAM_MC_MAX_BAND_LFE, band_step, &temp_e ); - temp = shr( temp, sub( 15, temp_e ) ); - Word16 temp1; - IF( PARAM_MC_MAX_BAND_LFE % band_step ) - { - temp1 = 1; - } - ELSE - { - temp1 = 0; - } - move16(); - num_lfe_bands = add( temp, temp1 ); - - temp = BASOP_Util_Divide3232_Scale( hMetadataPMC->nbands_coded, band_step, &temp_e ); - temp = shr( temp, sub( 15, temp_e ) ); - Word16 temp2; - IF( hMetadataPMC->nbands_coded % band_step ) - { - temp2 = 1; - } - ELSE - { - temp2 = 0; - } - move16(); - num_param_bands = add( temp, temp2 ); - } - ELSE - { - FOR( j = 0; j < PARAM_MC_MAX_BAND_LFE; j += band_step ) - { - IF( EQ_16( param_frame_idx, hMetadataPMC->coding_band_mapping[j] ) ) - { - /* LFE ICC is always the last ICC in coding band 0 */ - num_lfe_bands = add( num_lfe_bands, 1 ); - move16(); - } - } - } - - IF( !hMetadataPMC->lfe_on ) - { - num_lfe_bands = 0; - move16(); - } - - ivas_param_mc_bs_decode_parameter_values_fx( bit_buffer, &bit_pos, bits_to_copy, &st->BER_detect, hMetadataPMC, &hMetadataPMC->icc_coding, - icc_map_size_wo_lfe, icc_map_size, num_lfe_bands, band_step, num_param_bands, hParamMC->icc_q_fx ); - - IF( !st->BER_detect ) - { - ivas_param_mc_bs_decode_parameter_values_fx( bit_buffer, &bit_pos, bits_to_copy, &st->BER_detect, hMetadataPMC, &hMetadataPMC->ild_coding, - ild_map_size_wo_lfe, ild_map_size, num_lfe_bands, band_step, num_param_bands, hParamMC->icld_q_fx ); - } - /* set LFE ILD and ICC to zero above PARAM_MC_MAX_BAND_LFE for attack frames */ - IF( hMetadataPMC->bAttackPresent ) - { - FOR( k = PARAM_MC_MAX_BAND_LFE; k < imult1616( band_step, num_lfe_bands ); k++ ) - { - hParamMC->icc_q_fx[L_sub( L_mult0( add( k, 1 ), icc_map_size ), 1 )] = 32767; /* 1.0f in Q15 */ - move16(); - hParamMC->icld_q_fx[L_sub( L_mult0( add( k, 1 ), ild_map_size ), 1 )] = PARAM_MC_DEFAULT_MIN_ILD_FX; /* -92.0f in Q8 */ - move16(); - } - } - - *nb_bits = bit_pos; - move16(); - - } /* if ( !st->bfi ) */ - - IF( st->bfi ) - { - /* for PLC, use the saved ILDs and ICCs from the past and set the transient flag and transient position to zero */ - hMetadataPMC->bAttackPresent = 0; - move16(); - hMetadataPMC->attackIndex = 0; - move16(); - } - - pop_wmops(); - - return; -} - - -/*------------------------------------------------------------------------- - * ivas_param_mc_dec_digest_tc() - * - * - *------------------------------------------------------------------------*/ - -void ivas_param_mc_dec_digest_tc_fx( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */ - const uint8_t nCldfbSlots, /* i : number of CLFBS slots in the transport channels */ - Word32 *transport_channels_f_fx[], - Word16 transport_f_e ) -{ - PARAM_MC_DEC_HANDLE hParamMC; - Word16 i, ch; - Word16 is_next_band, skip_next_band; - Word16 slot_idx, param_band_idx; - Word16 nchan_transport, nchan_out_transport, nchan_out_cldfb; - Word16 nchan_out_cov; - /*CLDFB*/ - /* format converter */ - Word16 channel_active[MAX_OUTPUT_CHANNELS]; - IVAS_OUTPUT_SETUP *hSynthesisOutputSetup; - - hParamMC = st_ivas->hParamMC; - assert( hParamMC ); - Word32 *pCx, *pCx_imag; - Word32 cx_fx[PARAM_MC_MAX_TRANSPORT_CHANS * PARAM_MC_MAX_TRANSPORT_CHANS]; // Q(31 - cx_e) - Word32 cx_imag_fx[PARAM_MC_MAX_TRANSPORT_CHANS * PARAM_MC_MAX_TRANSPORT_CHANS]; // Q(31 - cx_imag_e) - Word32 cx_next_band_fx[PARAM_MC_MAX_TRANSPORT_CHANS * PARAM_MC_MAX_TRANSPORT_CHANS]; // Q(31 - cx_next_band_e) - Word32 cx_imag_next_band_fx[PARAM_MC_MAX_TRANSPORT_CHANS * PARAM_MC_MAX_TRANSPORT_CHANS]; // Q(31 - cx_imag_next_band_e) - - Word16 cx_buff_e[2][PARAM_MC_MAX_TRANSPORT_CHANS * PARAM_MC_MAX_TRANSPORT_CHANS]; - Word16 cx_e; - Word16 cx_imag_e, tmp_e; - Word16 cx_imag_next_band_e, cx_next_band_e; - Word16 qout = 0; - move16(); - - Word32 real_part_fx, imag_part_fx, L_tmp1, L_tmp2; - - Word16 max_e; - - push_wmops( "param_mc_dec_digest_tc" ); - - set16_fx( channel_active, 0, MAX_CICP_CHANNELS ); - nchan_transport = st_ivas->nchan_transport; - move16(); - nchan_out_transport = add( st_ivas->hTransSetup.nchan_out_woLFE, st_ivas->hTransSetup.num_lfe ); - - test(); - test(); - IF( EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_FASTCONV ) || EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_FASTCONV_ROOM ) ) - { - nchan_out_cldfb = BINAURAL_CHANNELS; - move16(); - set16_fx( channel_active, 1, nchan_out_cldfb ); - nchan_out_cov = add( st_ivas->hTransSetup.nchan_out_woLFE, st_ivas->hTransSetup.num_lfe ); - hSynthesisOutputSetup = &st_ivas->hTransSetup; - } - ELSE IF( EQ_32( hParamMC->synthesis_conf, PARAM_MC_SYNTH_LS_CONV_CLDFB ) ) - { - nchan_out_cov = nchan_out_transport; - move16(); - nchan_out_cldfb = add( st_ivas->hOutSetup.nchan_out_woLFE, st_ivas->hOutSetup.num_lfe ); - hSynthesisOutputSetup = &st_ivas->hTransSetup; - } - ELSE IF( EQ_32( hParamMC->synthesis_conf, PARAM_MC_SYNTH_LS_CONV_COV ) || EQ_32( hParamMC->synthesis_conf, PARAM_MC_SYNTH_MONO_STEREO ) ) - { - nchan_out_cov = add( st_ivas->hOutSetup.nchan_out_woLFE, st_ivas->hOutSetup.num_lfe ); - nchan_out_cldfb = nchan_out_cov; - move16(); - set16_fx( channel_active, 1, nchan_out_cov ); - hSynthesisOutputSetup = &st_ivas->hOutSetup; - } - ELSE - { - nchan_out_cov = nchan_out_transport; - move16(); - nchan_out_cldfb = nchan_out_transport; - move16(); - set16_fx( channel_active, 1, nchan_out_cov ); - hSynthesisOutputSetup = &st_ivas->hTransSetup; - } - - /* adapt transient position */ - IF( hParamMC->hMetadataPMC->bAttackPresent ) - { - hParamMC->hMetadataPMC->attackIndex = s_max( 0, add( hParamMC->hMetadataPMC->attackIndex, shr( sub( nCldfbSlots, DEFAULT_JBM_CLDFB_TIMESLOTS ), 1 ) ) ); - move16(); - } - /* adapt subframes */ - hParamMC->num_slots = nCldfbSlots; - move16(); - hParamMC->slots_rendered = 0; - move16(); - hParamMC->subframes_rendered = 0; - move16(); - ivas_jbm_dec_get_adapted_subframes( nCldfbSlots, hParamMC->subframe_nbslots, &hParamMC->nb_subframes ); - st_ivas->hTcBuffer->nb_subframes = hParamMC->nb_subframes; - move16(); - Copy( hParamMC->subframe_nbslots, st_ivas->hTcBuffer->subframe_nbslots, hParamMC->nb_subframes ); - - ivas_param_mc_dec_compute_interpolator_fx( hParamMC->hMetadataPMC->bAttackPresent, hParamMC->hMetadataPMC->attackIndex, nCldfbSlots, hParamMC->h_output_synthesis_params.interpolator_fx ); - - /* loop over two bands at a time */ - FOR( param_band_idx = 0; param_band_idx < hParamMC->num_param_bands_synth; param_band_idx += 2 ) - { - /* don't process next band if it exceeds the limit */ - skip_next_band = ( ( param_band_idx + 1 ) == hParamMC->num_param_bands_synth ) ? 1 : 0; - - set_zero_fx( cx_fx, PARAM_MC_MAX_TRANSPORT_CHANS * PARAM_MC_MAX_TRANSPORT_CHANS ); - set_zero_fx( cx_imag_fx, PARAM_MC_MAX_TRANSPORT_CHANS * PARAM_MC_MAX_TRANSPORT_CHANS ); - set_zero_fx( cx_next_band_fx, PARAM_MC_MAX_TRANSPORT_CHANS * PARAM_MC_MAX_TRANSPORT_CHANS ); - set_zero_fx( cx_imag_next_band_fx, PARAM_MC_MAX_TRANSPORT_CHANS * PARAM_MC_MAX_TRANSPORT_CHANS ); - - cx_e = 0; - move16(); - cx_imag_e = 0; - move16(); - cx_next_band_e = 0; - move16(); - cx_imag_next_band_e = 0; - move16(); - /* slot loop for gathering the input data */ - FOR( slot_idx = 0; slot_idx < nCldfbSlots; slot_idx++ ) - { - IF( st_ivas->hDecoderConfig->Opt_tsm ) - { - IF( param_band_idx == 0 ) /* only run cldfbAna once */ - { - Word32 RealBuffer_fx[CLDFB_NO_CHANNELS_MAX]; - Word32 ImagBuffer_fx[CLDFB_NO_CHANNELS_MAX]; - - /* CLDFB Analysis*/ - FOR( ch = 0; ch < nchan_transport; ch++ ) - { - qout = transport_f_e; - move16(); - cldfbAnalysis_ts_fx_fixed_q( &( transport_channels_f_fx[ch][hParamMC->num_freq_bands * slot_idx] ), RealBuffer_fx, ImagBuffer_fx, hParamMC->num_freq_bands, st_ivas->cldfbAnaDec[ch], &qout ); - - Copy32( RealBuffer_fx, &hParamMC->Cldfb_RealBuffer_tc_fx[slot_idx * hParamMC->num_freq_bands * nchan_transport + ch * hParamMC->num_freq_bands], hParamMC->num_freq_bands ); - Copy32( ImagBuffer_fx, &hParamMC->Cldfb_ImagBuffer_tc_fx[slot_idx * hParamMC->num_freq_bands * nchan_transport + ch * hParamMC->num_freq_bands], hParamMC->num_freq_bands ); - } - - hParamMC->Cldfb_ImagBuffer_tc_e = qout; - move16(); - } - } - IF( GE_16( slot_idx, shl( hParamMC->hMetadataPMC->attackIndex, 1 ) ) ) - { - FOR( is_next_band = 0; is_next_band < 2; is_next_band++ ) - { - test(); - IF( is_next_band && skip_next_band ) - { - continue; - } - IF( is_next_band ) - { - ivas_dirac_dec_output_synthesis_cov_param_mc_collect_slot_fx( &hParamMC->Cldfb_RealBuffer_tc_fx[slot_idx * hParamMC->num_freq_bands * nchan_transport], - /*hParamMC->Cldfb_RealBuffer_tc_e*/ Q31 - Q6, - &hParamMC->Cldfb_ImagBuffer_tc_fx[slot_idx * hParamMC->num_freq_bands * nchan_transport], - /*hParamMC->Cldfb_ImagBuffer_tc_e*/ Q31 - Q6, - cx_next_band_fx, - &cx_next_band_e, - cx_imag_next_band_fx, - &cx_imag_next_band_e, - hParamMC, - add( param_band_idx, is_next_band ), - nchan_transport ); - } - ELSE - { - ivas_dirac_dec_output_synthesis_cov_param_mc_collect_slot_fx( &hParamMC->Cldfb_RealBuffer_tc_fx[slot_idx * hParamMC->num_freq_bands * nchan_transport], - /*hParamMC->Cldfb_RealBuffer_tc_e*/ Q31 - Q6, - &hParamMC->Cldfb_ImagBuffer_tc_fx[slot_idx * hParamMC->num_freq_bands * nchan_transport], - /*hParamMC->Cldfb_ImagBuffer_tc_e*/ Q31 - Q6, - cx_fx, - &cx_e, - cx_imag_fx, - &cx_imag_e, - hParamMC, - add( param_band_idx, is_next_band ), - nchan_transport ); - } - } - } - } - - Word16 tmp_cx_e, tmp_cx_imag_e; - /* map from complex input covariance to real values */ - FOR( is_next_band = 0; is_next_band < 2; is_next_band++ ) - { - test(); - IF( is_next_band && skip_next_band ) - { - continue; - } - /* Cx for transport channels */ - IF( is_next_band ) - { - pCx = &cx_next_band_fx[0]; - pCx_imag = &cx_imag_next_band_fx[0]; - tmp_cx_e = cx_next_band_e; - tmp_cx_imag_e = cx_imag_next_band_e; - } - ELSE - { - pCx = &cx_fx[0]; - pCx_imag = &cx_imag_fx[0]; - tmp_cx_e = cx_e; - tmp_cx_imag_e = cx_imag_e; - } - - FOR( i = 0; i < nchan_transport * nchan_transport; i++ ) - { - real_part_fx = pCx[i]; // Q(31 - cx_buff_e) - imag_part_fx = pCx_imag[i]; - move32(); - move32(); - cx_buff_e[is_next_band][i] = tmp_cx_e; - move16(); - /* (a-ib)(c+id) = ac + bd + i(ad-bc) */ - IF( LT_16( param_band_idx, hParamMC->max_param_band_abs_cov ) ) - { - L_tmp1 = Mpy_32_32( real_part_fx, real_part_fx ); - L_tmp2 = Mpy_32_32( imag_part_fx, imag_part_fx ); - L_tmp1 = BASOP_Util_Add_Mant32Exp( L_tmp1, add( tmp_cx_e, tmp_cx_e ), L_tmp2, add( tmp_cx_imag_e, tmp_cx_imag_e ), &tmp_e ); - pCx[i] = Sqrt32( L_tmp1, &tmp_e ); - move32(); - cx_buff_e[is_next_band][i] = tmp_e; - move16(); - } - ELSE - { - pCx[i] = real_part_fx; - move32(); - cx_buff_e[is_next_band][i] = tmp_cx_e; - move16(); - } - } - } - - max_e = cx_buff_e[0][0]; - move16(); - - /* Cx for transport channels */ - FOR( is_next_band = 0; is_next_band < 2; is_next_band++ ) - { - FOR( i = 0; i < imult1616( nchan_transport, nchan_transport ); i++ ) - { - - IF( LT_16( max_e, cx_buff_e[is_next_band][i] ) ) - { - max_e = cx_buff_e[is_next_band][i]; - } - } - } - /* Cx for transport channels */ - FOR( is_next_band = 0; is_next_band < 2; is_next_band++ ) - { - FOR( i = 0; i < imult1616( nchan_transport, nchan_transport ); i++ ) - { - if ( is_next_band == 0 ) - { - cx_fx[i] = L_shr( cx_fx[i], sub( max_e, cx_buff_e[is_next_band][i] ) ); - } - else - { - cx_next_band_fx[i] = L_shr( cx_next_band_fx[i], sub( max_e, cx_buff_e[is_next_band][i] ) ); - } - move32(); - } - } - cx_e = max_e; - move16(); - - - /* we have to do it similar to the encoder in case of attacks (i.e. accumulate two bands) to ensure correct DMX of the target covariance*/ - - test(); - test(); - IF( hParamMC->hMetadataPMC->bAttackPresent && ( EQ_32( hParamMC->synthesis_conf, PARAM_MC_SYNTH_LS_CONV_COV ) || EQ_32( hParamMC->synthesis_conf, PARAM_MC_SYNTH_MONO_STEREO ) ) ) - { - v_add_fx( cx_fx, cx_next_band_fx, cx_fx, imult1616( nchan_transport, nchan_transport ) ); - Copy32( cx_fx, cx_next_band_fx, imult1616( nchan_transport, nchan_transport ) ); - } - - FOR( is_next_band = 0; is_next_band < 2; is_next_band++ ) - { - test(); - IF( is_next_band && skip_next_band ) - { - continue; - } - - IF( NE_32( hParamMC->synthesis_conf, PARAM_MC_SYNTH_MONO_STEREO ) ) - { - IF( is_next_band ) - { - - ivas_param_mc_get_mixing_matrices_fx( hParamMC, hSynthesisOutputSetup, cx_next_band_fx, cx_e, add( param_band_idx, is_next_band ), hParamMC->h_output_synthesis_cov_state.mixing_matrix_fx, hParamMC->h_output_synthesis_cov_state.mixing_matrix_exp, hParamMC->h_output_synthesis_cov_state.mixing_matrix_res_fx, hParamMC->h_output_synthesis_cov_state.mixing_matrix_res_exp, nchan_out_transport, hParamMC->synthesis_conf, nchan_transport, nchan_out_cov ); - } - ELSE - { - - ivas_param_mc_get_mixing_matrices_fx( hParamMC, hSynthesisOutputSetup, cx_fx, cx_e, add( param_band_idx, is_next_band ), hParamMC->h_output_synthesis_cov_state.mixing_matrix_fx, hParamMC->h_output_synthesis_cov_state.mixing_matrix_exp, hParamMC->h_output_synthesis_cov_state.mixing_matrix_res_fx, hParamMC->h_output_synthesis_cov_state.mixing_matrix_res_exp, nchan_out_transport, hParamMC->synthesis_conf, nchan_transport, nchan_out_cov ); - } - } - } - } - pop_wmops(); - - return; -} - - -/*------------------------------------------------------------------------- - * ivas_param_mc_dec() - * - * Parametric MC decoding process - *------------------------------------------------------------------------*/ - -void ivas_param_mc_dec_render_fx( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */ - const UWord16 nSamplesAsked, /* i : number of CLDFB slots requested */ - UWord16 *nSamplesRendered, /* o : number of CLDFB slots rendered */ - UWord16 *nSamplesAvailableNext, /* o : number of CLDFB slots still to render */ - Word32 *output_f_fx[], /* o : rendered time signal Q11*/ - Word16 channel_active_fx[MAX_OUTPUT_CHANNELS] ) -{ - PARAM_MC_DEC_HANDLE hParamMC; - Word16 i, ch; - Word16 subframe_idx; - Word16 slot_idx, slot_idx_start, slot_idx_start_cldfb_synth, first_sf, last_sf, slots_to_render; - Word16 nchan_transport, nchan_out_transport, nchan_out_cldfb; - Word16 nchan_out_cov; - - /*CLDFB*/ - Word32 Cldfb_RealBuffer_fx[MAX_INTERN_CHANNELS][PARAM_MC_MAX_NSLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX]; - Word32 Cldfb_ImagBuffer_fx[MAX_INTERN_CHANNELS][PARAM_MC_MAX_NSLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX]; - Word32 Cldfb_RealBuffer_Binaural_fx[BINAURAL_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX]; - Word32 Cldfb_ImagBuffer_Binaural_fx[BINAURAL_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX]; - Word32 *p_output_f_fx[MAX_OUTPUT_CHANNELS]; - FOR( i = 0; i < MAX_OUTPUT_CHANNELS; i++ ) - { - p_output_f_fx[i] = output_f_fx[i]; // Q11 - } - /*Decorrelator*/ - Word32 onset_filter_fx[MAX_CICP_CHANNELS * CLDFB_NO_CHANNELS_MAX]; // Q31 - - /* format converter */ - Word16 channel_active[MAX_OUTPUT_CHANNELS]; - UWord16 nband_synth; -#ifndef MSAN_FIX - UWord16 nchan_out_init, nbands_to_zero; -#endif - UWord32 output_Fs; - Word16 tmp_q = 0; - move16(); - - hParamMC = st_ivas->hParamMC; - assert( hParamMC ); - - push_wmops( "param_mc_dec_render" ); - - set16_fx( channel_active, 0, MAX_CICP_CHANNELS ); - nchan_transport = st_ivas->nchan_transport; - move16(); - nchan_out_transport = add( st_ivas->hTransSetup.nchan_out_woLFE, st_ivas->hTransSetup.num_lfe ); -#ifndef MSAN_FIX - nchan_out_init = nchan_out_transport; - move16(); -#endif - output_Fs = st_ivas->hDecoderConfig->output_Fs; - move32(); - - test(); - test(); - IF( EQ_16( st_ivas->renderer_type, RENDERER_BINAURAL_FASTCONV ) || EQ_16( st_ivas->renderer_type, RENDERER_BINAURAL_FASTCONV_ROOM ) ) - { - nchan_out_cldfb = BINAURAL_CHANNELS; - set16_fx( channel_active, 1, nchan_out_cldfb ); -#ifndef MSAN_FIX - IF( st_ivas->hCombinedOrientationData ) - { - nchan_out_init = MAX_INTERN_CHANNELS; - } -#endif - nchan_out_cov = add( st_ivas->hTransSetup.nchan_out_woLFE, st_ivas->hTransSetup.num_lfe ); - } - ELSE IF( EQ_16( hParamMC->synthesis_conf, PARAM_MC_SYNTH_LS_CONV_CLDFB ) ) - { - nchan_out_cov = nchan_out_transport; - move16(); - nchan_out_cldfb = add( st_ivas->hOutSetup.nchan_out_woLFE, st_ivas->hOutSetup.num_lfe ); - } - ELSE IF( EQ_16( hParamMC->synthesis_conf, PARAM_MC_SYNTH_LS_CONV_COV ) || EQ_16( hParamMC->synthesis_conf, PARAM_MC_SYNTH_MONO_STEREO ) ) - { - nchan_out_cov = add( st_ivas->hOutSetup.nchan_out_woLFE, st_ivas->hOutSetup.num_lfe ); - nchan_out_cldfb = nchan_out_cov; - move16(); - set16_fx( channel_active, 1, nchan_out_cov ); - } - ELSE - { - nchan_out_cov = nchan_out_transport; - move16(); - nchan_out_cldfb = nchan_out_transport; - move16(); - set16_fx( channel_active, 1, nchan_out_cov ); - } - - /* set everything to zero that will not be decoded */ - nband_synth = hParamMC->band_grouping[hParamMC->num_param_bands_synth]; - move16(); -#ifdef MSAN_FIX - FOR( ch = 0; ch < MAX_OUTPUT_CHANNELS; ch++ ) -#else - FOR( ch = 0; ch < nchan_out_init; ch++ ) -#endif - { - FOR( slot_idx = 0; slot_idx < JBM_CLDFB_SLOTS_IN_SUBFRAME; slot_idx++ ) - { -#ifdef MSAN_FIX - set32_fx( &( Cldfb_RealBuffer_fx[ch][slot_idx][0] ), 0, CLDFB_NO_CHANNELS_MAX ); - set32_fx( &( Cldfb_ImagBuffer_fx[ch][slot_idx][0] ), 0, CLDFB_NO_CHANNELS_MAX ); -#else - set32_fx( &( Cldfb_RealBuffer_fx[ch][slot_idx][nband_synth] ), 0, nbands_to_zero ); - set32_fx( &( Cldfb_ImagBuffer_fx[ch][slot_idx][nband_synth] ), 0, nbands_to_zero ); -#endif - } - } - - /* loop FOR synthesis, assume we always have to render in multiples of 5ms subframes with spills */ - /*slots_to_render = min(sub(hParamMC->num_slots, hParamMC->slots_rendered), nSamplesAsked / NS2SA(output_Fs, CLDFB_SLOT_NS)); - *nSamplesRendered = slots_to_render * NS2SA(output_Fs, CLDFB_SLOT_NS);*/ - Word16 temp_e; - Word16 temp = BASOP_Util_Divide1616_Scale( nSamplesAsked, NS2SA( output_Fs, CLDFB_SLOT_NS ), &temp_e ); - temp = shr( temp, sub( 15, temp_e ) ); - slots_to_render = s_min( sub( hParamMC->num_slots, hParamMC->slots_rendered ), temp ); - *nSamplesRendered = imult1616( slots_to_render, NS2SA( output_Fs, CLDFB_SLOT_NS ) ); - move16(); - Word16 j, k; - first_sf = hParamMC->subframes_rendered; - move16(); - last_sf = first_sf; - move16(); - WHILE( slots_to_render > 0 ) - { - slots_to_render = sub( slots_to_render, hParamMC->subframe_nbslots[last_sf] ); - last_sf = add( last_sf, 1 ); - } - IF( EQ_16( st_ivas->renderer_type, RENDERER_SBA_LINEAR_ENC ) ) - { - FOR( subframe_idx = first_sf; subframe_idx < last_sf; subframe_idx++ ) - { - slots_to_render = add( slots_to_render, hParamMC->subframe_nbslots[subframe_idx] ); - } - } - slot_idx_start = hParamMC->slots_rendered; - move16(); - slot_idx_start_cldfb_synth = 0; - move16(); - -#ifndef FIX_1009_OPT_PARAMMC_RENDER - Flag is_zero = 1; - move32(); -#endif - FOR( j = 0; j < st_ivas->hParamMC->hMetadataPMC->nbands_coded; j++ ) - { -#ifndef FIX_1009_OPT_PARAMMC_RENDER - is_zero = 1; - move16(); - FOR( i = 0; i < hParamMC->h_output_synthesis_cov_state.mixing_matrix_len; i++ ) - { - IF( hParamMC->h_output_synthesis_cov_state.mixing_matrix_fx[j][i] != 0 ) - { - is_zero = 0; - move16(); - } - } - IF( is_zero ) - { - hParamMC->h_output_synthesis_cov_state.mixing_matrix_exp[j] = 0; - move16(); - } - is_zero = 1; - move16(); -#else - Flag is_zero = is_zero_arr( hParamMC->h_output_synthesis_cov_state.mixing_matrix_fx[j], hParamMC->h_output_synthesis_cov_state.mixing_matrix_len ); - { - if ( is_zero != 0 ) - { - hParamMC->h_output_synthesis_cov_state.mixing_matrix_exp[j] = 0; - move16(); - } - } -#endif - IF( LT_16( st_ivas->hParamMC->band_grouping[j], st_ivas->hParamMC->h_output_synthesis_params.max_band_decorr ) ) - { -#ifndef FIX_1009_OPT_PARAMMC_RENDER - FOR( i = 0; i < hParamMC->h_output_synthesis_cov_state.mixing_matrix_res_len; i++ ) - { - IF( NE_32( hParamMC->h_output_synthesis_cov_state.mixing_matrix_res_fx[j][i], 0 ) ) - { - is_zero = 0; - move16(); - } - } - IF( is_zero ) -#else - is_zero = is_zero_arr( hParamMC->h_output_synthesis_cov_state.mixing_matrix_res_fx[j], hParamMC->h_output_synthesis_cov_state.mixing_matrix_res_len ); - if ( is_zero != 0 ) -#endif - { - hParamMC->h_output_synthesis_cov_state.mixing_matrix_res_exp[j] = 0; - move16(); - } - } - } - FOR( subframe_idx = first_sf; subframe_idx < last_sf; subframe_idx++ ) - { - FOR( slot_idx = 0; slot_idx < hParamMC->subframe_nbslots[subframe_idx]; ( slot_idx++, hParamMC->slots_rendered++ ) ) - { - IF( hParamMC->max_band_decorr > 0 ) - { - /*-----------------------------------------------------------------* - * protoype signal computation - *-----------------------------------------------------------------*/ - param_mc_protoSignalComputation_fx( &hParamMC->Cldfb_RealBuffer_tc_fx[hParamMC->slots_rendered * nchan_transport * hParamMC->num_freq_bands], - &hParamMC->Cldfb_ImagBuffer_tc_fx[hParamMC->slots_rendered * nchan_transport * hParamMC->num_freq_bands], - hParamMC->proto_frame_f_fx, hParamMC->diff_proto_info, - hParamMC->num_freq_bands ); - Scale_sig32( hParamMC->proto_frame_f_fx, shl( imult1616( hParamMC->diff_proto_info->num_protos_diff, hParamMC->num_freq_bands ), 1 ), Q11 - Q5 ); - /*-----------------------------------------------------------------* - * frequency domain decorrelation - *-----------------------------------------------------------------*/ - /* decorrelate prototype frame */ - - ivas_dirac_dec_decorr_process_fx( hParamMC->num_freq_bands, - hParamMC->num_outputs_diff, - hParamMC->diff_proto_info->num_protos_diff, - DIRAC_SYNTHESIS_COV_MC_LS, - nchan_transport, - hParamMC->proto_frame_f_fx, - 11, - hParamMC->diff_proto_info->num_protos_diff, - hParamMC->diff_proto_info->proto_index_diff, - hParamMC->proto_frame_dec_f_fx, // output - &tmp_q, - onset_filter_fx, - hParamMC->h_freq_domain_decorr_ap_params, - hParamMC->h_freq_domain_decorr_ap_state ); - - /* copy decorrelated frame directly to output CLDFB buffer, acts also as intermediate */ - /* memory FOR the decorrelated signal */ - ivas_param_mc_dec_copy_diffuse_proto( hParamMC, Cldfb_RealBuffer_fx, Cldfb_ImagBuffer_fx, nchan_out_cov, slot_idx ); // Returns Cldfb buffers in Q11(tmp_q) - - FOR( k = 0; k < nchan_out_cov; k++ ) - { - FOR( Word16 l = 0; l < hParamMC->h_output_synthesis_params.max_band_decorr; l++ ) - { - Cldfb_RealBuffer_fx[k][slot_idx][l] = L_shl( Cldfb_RealBuffer_fx[k][slot_idx][l], sub( 6, tmp_q ) ); // Q11(tmp_q) -> Q6 - move32(); - Cldfb_ImagBuffer_fx[k][slot_idx][l] = L_shl( Cldfb_ImagBuffer_fx[k][slot_idx][l], sub( 6, tmp_q ) ); // Q11(tmp_q) -> Q6 - move32(); - } - } - } - - /*-----------------------------------------------------------------* - * output synthesis - *-----------------------------------------------------------------*/ - ivas_dirac_dec_output_synthesis_cov_param_mc_synthesise_slot_fx( - &hParamMC->Cldfb_RealBuffer_tc_fx[hParamMC->slots_rendered * nchan_transport * hParamMC->num_freq_bands], - &hParamMC->Cldfb_ImagBuffer_tc_fx[hParamMC->slots_rendered * nchan_transport * hParamMC->num_freq_bands], Cldfb_RealBuffer_fx, Cldfb_ImagBuffer_fx, hParamMC->h_output_synthesis_cov_state.mixing_matrix_fx, hParamMC->h_output_synthesis_cov_state.mixing_matrix_exp, hParamMC->h_output_synthesis_cov_state.mixing_matrix_res_fx, hParamMC->h_output_synthesis_cov_state.mixing_matrix_res_exp, slot_idx, add( slot_idx, slot_idx_start ), - nchan_transport, nchan_out_cov, hParamMC ); - - test(); - IF( ( EQ_16( st_ivas->renderer_type, RENDERER_BINAURAL_FASTCONV ) || EQ_16( st_ivas->renderer_type, RENDERER_BINAURAL_FASTCONV_ROOM ) ) ) - { - test(); - IF( st_ivas->hCombinedOrientationData && EQ_16( st_ivas->renderer_type, RENDERER_BINAURAL_FASTCONV ) ) - { - Word16 Q_Cldfb_ImagBuffer, Q_Cldfb_RealBuffer; - Q_Cldfb_ImagBuffer = Q6 - 5; /*max value =MAX_INTERN_CHANNELS(=16)*Cldfb_ImagBuffer_fx*/ - move16(); - Q_Cldfb_RealBuffer = Q6 - 5; - move16(); - FOR( i = 0; i < MAX_OUTPUT_CHANNELS; i++ ) - { - FOR( j = 0; j < MAX_PARAM_SPATIAL_SUBFRAMES; j++ ) - { - Scale_sig32( Cldfb_RealBuffer_fx[i][j], CLDFB_NO_CHANNELS_MAX, sub( Q_Cldfb_ImagBuffer, Q6 ) ); // Q1 - Scale_sig32( Cldfb_ImagBuffer_fx[i][j], CLDFB_NO_CHANNELS_MAX, sub( Q_Cldfb_RealBuffer, Q6 ) ); // Q1 - } - } - ivas_param_mc_mc2sba_cldfb_fx( st_ivas->hTransSetup, hParamMC->hoa_encoder_fx, slot_idx, Cldfb_RealBuffer_fx, Cldfb_ImagBuffer_fx, nband_synth, GAIN_LFE_FX ); - FOR( i = 0; i < MAX_OUTPUT_CHANNELS; i++ ) - { - FOR( j = 0; j < MAX_PARAM_SPATIAL_SUBFRAMES; j++ ) - { - Scale_sig32( Cldfb_RealBuffer_fx[i][j], CLDFB_NO_CHANNELS_MAX, sub( Q6, Q_Cldfb_ImagBuffer ) ); // Q6 - Scale_sig32( Cldfb_ImagBuffer_fx[i][j], CLDFB_NO_CHANNELS_MAX, sub( Q6, Q_Cldfb_RealBuffer ) ); // Q6 - } - } - } - ELSE - { - /* remove LFE */ - UWord16 idx_out; - UWord16 idx_lfe; - IVAS_OUTPUT_SETUP hLsSetup; - - hLsSetup = st_ivas->hTransSetup; - /* If LFE should be rendered, add it to other channels before removing */ - IF( st_ivas->hBinRenderer->render_lfe ) - { - Word16 tmp_exp = 0; - move16(); - Word16 tmp = BASOP_Util_Divide1616_Scale( GAIN_LFE_FX, hLsSetup.nchan_out_woLFE, &tmp_exp ); - tmp_exp = add( tmp_exp, ( 1 - 15 ) ); - FOR( idx_lfe = 0; idx_lfe < hLsSetup.num_lfe; idx_lfe++ ) - { - /* Copy just the first band of LFE*/ - v_multc_fixed_16( Cldfb_RealBuffer_fx[hLsSetup.index_lfe[idx_lfe]][slot_idx], tmp, Cldfb_RealBuffer_fx[hLsSetup.index_lfe[idx_lfe]][slot_idx], 1 ); - v_multc_fixed_16( Cldfb_ImagBuffer_fx[hLsSetup.index_lfe[idx_lfe]][slot_idx], tmp, Cldfb_ImagBuffer_fx[hLsSetup.index_lfe[idx_lfe]][slot_idx], 1 ); - - Scale_sig32( Cldfb_RealBuffer_fx[hLsSetup.index_lfe[idx_lfe]][slot_idx], 1, tmp_exp ); - Scale_sig32( Cldfb_ImagBuffer_fx[hLsSetup.index_lfe[idx_lfe]][slot_idx], 1, tmp_exp ); - FOR( ch = 0; ch < ( hLsSetup.nchan_out_woLFE + hLsSetup.num_lfe ); ch++ ) - { - IF( hLsSetup.index_lfe[idx_lfe] != ch ) - { - v_add_fixed( Cldfb_RealBuffer_fx[ch][slot_idx], Cldfb_RealBuffer_fx[hLsSetup.index_lfe[idx_lfe]][slot_idx], Cldfb_RealBuffer_fx[ch][slot_idx], 1, 0 ); - v_add_fixed( Cldfb_ImagBuffer_fx[ch][slot_idx], Cldfb_ImagBuffer_fx[hLsSetup.index_lfe[idx_lfe]][slot_idx], Cldfb_ImagBuffer_fx[ch][slot_idx], 1, 0 ); - } - } - } - } - - idx_out = 0; - move16(); - idx_lfe = 0; - move16(); - - FOR( ch = 0; ch < ( hLsSetup.nchan_out_woLFE + hLsSetup.num_lfe ); ch++ ) - { - test(); - IF( ( hLsSetup.num_lfe > 0 ) && EQ_16( hLsSetup.index_lfe[idx_lfe], ch ) ) - { - IF( LT_16( idx_lfe, ( sub( hLsSetup.num_lfe, 1 ) ) ) ) - { - idx_lfe = add( idx_lfe, 1 ); - } - } - ELSE IF( NE_16( ch, idx_out ) ) - { - Copy32( Cldfb_RealBuffer_fx[ch][slot_idx], Cldfb_RealBuffer_fx[idx_out][slot_idx], nband_synth ); - Copy32( Cldfb_ImagBuffer_fx[ch][slot_idx], Cldfb_ImagBuffer_fx[idx_out][slot_idx], nband_synth ); - idx_out = add( idx_out, 1 ); - } - ELSE - { - idx_out = add( idx_out, 1 ); - } - } - } - } - } - - test(); - IF( EQ_16( st_ivas->renderer_type, RENDERER_BINAURAL_FASTCONV ) || EQ_16( st_ivas->renderer_type, RENDERER_BINAURAL_FASTCONV_ROOM ) ) - { - Word16 input_q = 6; - move16(); - /* Implement binaural rendering */ - ivas_binRenderer_fx( st_ivas->hBinRenderer, - st_ivas->hCombinedOrientationData, - hParamMC->subframe_nbslots[subframe_idx], - Cldfb_RealBuffer_Binaural_fx, Cldfb_ImagBuffer_Binaural_fx, - Cldfb_RealBuffer_fx, - Cldfb_ImagBuffer_fx, &input_q ); - - FOR( i = 0; i < MAX_OUTPUT_CHANNELS; i++ ) - { - FOR( j = 0; j < MAX_PARAM_SPATIAL_SUBFRAMES; j++ ) - { - FOR( k = 0; k < CLDFB_NO_CHANNELS_MAX; k++ ) - { - Cldfb_RealBuffer_fx[i][j][k] = L_shl( Cldfb_RealBuffer_fx[i][j][k], sub( Q6, input_q ) ); // Q6 - Cldfb_ImagBuffer_fx[i][j][k] = L_shl( Cldfb_ImagBuffer_fx[i][j][k], sub( Q6, input_q ) ); // Q6 - } - } - } - - FOR( Word16 idx1 = 0; idx1 < BINAURAL_CHANNELS; idx1++ ) - { - FOR( Word16 idx2 = 0; idx2 < hParamMC->subframe_nbslots[subframe_idx]; idx2++ ) - { - Scale_sig32( Cldfb_RealBuffer_Binaural_fx[idx1][idx2], CLDFB_NO_CHANNELS_MAX, sub( Q6, input_q ) ); // Q6 - Scale_sig32( Cldfb_ImagBuffer_Binaural_fx[idx1][idx2], CLDFB_NO_CHANNELS_MAX, sub( Q6, input_q ) ); // Q6 - } - } - /* update combined orientation access index */ - ivas_combined_orientation_update_index( st_ivas->hCombinedOrientationData, hParamMC->num_freq_bands * hParamMC->subframe_nbslots[subframe_idx] ); - } - ELSE IF( EQ_16( hParamMC->synthesis_conf, PARAM_MC_SYNTH_LS_CONV_CLDFB ) ) - { - /* format conversion*/ - ivas_lssetupconversion_process_param_mc_fx( st_ivas, hParamMC->subframe_nbslots[subframe_idx], Cldfb_RealBuffer_fx, Cldfb_ImagBuffer_fx, channel_active ); - } - - - /* CLDFB synthesis */ - FOR( ch = 0; ch < nchan_out_cldfb; ch++ ) - { - Word32 *RealBuffer_fx[16]; - Word32 *ImagBuffer_fx[16]; - - IF( channel_active[ch] ) - { - /* open CLDFB buffer up to CLDFB_NO_CHANNELS_MAX bands FOR 48kHz */ - FOR( i = 0; i < hParamMC->subframe_nbslots[subframe_idx]; i++ ) - { - IF( EQ_16( st_ivas->renderer_type, RENDERER_BINAURAL_FASTCONV ) || EQ_16( st_ivas->renderer_type, RENDERER_BINAURAL_FASTCONV_ROOM ) ) - { - RealBuffer_fx[i] = Cldfb_RealBuffer_Binaural_fx[ch][i]; // Q6 - ImagBuffer_fx[i] = Cldfb_ImagBuffer_Binaural_fx[ch][i]; // Q6 - } - ELSE - { - RealBuffer_fx[i] = Cldfb_RealBuffer_fx[ch][i]; // Q6 - ImagBuffer_fx[i] = Cldfb_ImagBuffer_fx[ch][i]; // Q6 - } - } - - Word16 len = add( imult1616( slot_idx_start_cldfb_synth, hParamMC->num_freq_bands ), imult1616( hParamMC->num_freq_bands, hParamMC->subframe_nbslots[subframe_idx] ) ); - scale_sig32( output_f_fx[ch], len, 5 - 11 ); - cldfbSynthesis_ivas_fx( RealBuffer_fx, ImagBuffer_fx, &( output_f_fx[ch][slot_idx_start_cldfb_synth * hParamMC->num_freq_bands] ), - imult1616( hParamMC->num_freq_bands, hParamMC->subframe_nbslots[subframe_idx] ), st_ivas->cldfbSynDec[ch] ); - - scale_sig32( output_f_fx[ch], len, 11 - 5 ); // Q11 - } - ELSE - { - set32_fx( &( output_f_fx[ch][slot_idx_start_cldfb_synth * hParamMC->num_freq_bands] ), 0, imult1616( hParamMC->num_freq_bands, hParamMC->subframe_nbslots[subframe_idx] ) ); - } - } - slot_idx_start = add( slot_idx_start, hParamMC->subframe_nbslots[subframe_idx] ); - slot_idx_start_cldfb_synth = add( slot_idx_start_cldfb_synth, hParamMC->subframe_nbslots[subframe_idx] ); - } - IF( EQ_16( st_ivas->renderer_type, RENDERER_SBA_LINEAR_ENC ) ) - { - ivas_mc2sba_fx( st_ivas->hIntSetup, p_output_f_fx, p_output_f_fx, *nSamplesRendered, st_ivas->hOutSetup.ambisonics_order, 0 ); - } - - /* update */ - - IF( EQ_16( hParamMC->slots_rendered, hParamMC->num_slots ) ) - { - hParamMC->hMetadataPMC->last_coded_bwidth = hParamMC->hMetadataPMC->coded_bwidth; - move16(); - param_mc_update_mixing_matrices_fx( hParamMC, hParamMC->h_output_synthesis_cov_state.mixing_matrix_fx, hParamMC->h_output_synthesis_cov_state.mixing_matrix_exp, hParamMC->h_output_synthesis_cov_state.mixing_matrix_res_fx, hParamMC->h_output_synthesis_cov_state.mixing_matrix_res_exp, nchan_transport, nchan_out_cov ); - } - - - hParamMC->subframes_rendered = last_sf; - move16(); - *nSamplesAvailableNext = imult1616( sub( hParamMC->num_slots, hParamMC->slots_rendered ), NS2SA( output_Fs, CLDFB_SLOT_NS ) ); - move16(); - - FOR( i = 0; i < MAX_OUTPUT_CHANNELS; i++ ) - { - channel_active_fx[i] = channel_active[i]; - move16(); - } - pop_wmops(); - - return; -} - -/*------------------------------------------------------------------------- - * param_mc_dec_init() - * - * Parametric MC decoding initialization - *------------------------------------------------------------------------*/ - -static void ivas_param_mc_dec_init_fx( - PARAM_MC_DEC_HANDLE hParamMC, /* i/o: decoder DirAC handle */ - const Word16 nchan_transport, /* i : number of input (transport) channels */ - const Word16 nchan_cov ) /* i : number of cov synthesis channels */ -{ - Word16 k; - UWord16 max_param_band_residual; - Word16 len; - - /*-----------------------------------------------------------------* - * init sub-modules - *-----------------------------------------------------------------*/ - - /* decorrelation */ - IF( hParamMC->max_band_decorr > 0 ) - { - len = imult1616( hParamMC->diff_proto_info->num_protos_diff, hParamMC->h_freq_domain_decorr_ap_params->h_onset_detection_power_params.max_band_decorr ); - - /* init onsetDetectionPower */ - set_zero_fx( hParamMC->h_freq_domain_decorr_ap_state->h_onset_detection_power_state.onset_detector_1_fx, len ); - set_zero_fx( hParamMC->h_freq_domain_decorr_ap_state->h_onset_detection_power_state.onset_detector_2_fx, len ); - hParamMC->h_freq_domain_decorr_ap_state->h_onset_detection_power_state.q_onset_detector = Q31; - move16(); - } - - max_param_band_residual = 0; - move16(); - - /* output synthesis */ - FOR( k = hParamMC->hMetadataPMC->num_parameter_bands; k >= 0; k-- ) - { - IF( LE_16( hParamMC->band_grouping[k], hParamMC->max_band_decorr ) ) - { - max_param_band_residual = k; - move16(); - BREAK; - } - } - - ivas_dirac_dec_output_synthesis_cov_init_fx( &( hParamMC->h_output_synthesis_cov_state ), nchan_transport, nchan_cov, hParamMC->hMetadataPMC->num_parameter_bands, max_param_band_residual ); - - /*-----------------------------------------------------------------* - * init proto frames - *-----------------------------------------------------------------*/ - - IF( hParamMC->max_band_decorr > 0 ) - { - set_zero_fx( hParamMC->proto_frame_f_fx, shl( imult1616( hParamMC->diff_proto_info->num_protos_diff, hParamMC->num_freq_bands ), 1 ) ); - set32_fx( hParamMC->proto_frame_dec_f_fx, 0, shl( imult1616( nchan_cov, hParamMC->num_freq_bands ), 1 ) ); - } - - return; -} - - -/*------------------------------------------------------------------------- - * Local functions - *-------------------------------------------------------------------------*/ - - -/*------------------------------------------------------------------------- - * ivas_param_mc_dec_compute_diffuse_proto() - * - * Compute prototypes for decorrelation - *------------------------------------------------------------------------*/ - -static void param_mc_protoSignalComputation_fx( - Word32 *RealBuffer_fx, /* i : CLDFB samples of the transport channels (real part) */ - Word32 *ImagBuffer_fx, /* i : CLDFB samples of the transport channels (imaginary part) */ - Word32 *proto_frame_f_fx, /* o : interleaved complex prototype CLDFB samples */ - const PARAM_MC_DIFF_PROTO_INFO *diff_proto_info, /* i : prototype generation information */ - const int16_t num_freq_bands /* i : number of frequency bands for the prototypes */ -) -{ - Word16 band; - Word16 proto_ch_idx, source_ch_cnt; - - Word32 *p_proto_frame_fx; - Word32 *p_real_buffer_fx; // Q12 - Word32 *p_imag_buffer_fx; // Q12 - - set32_fx( proto_frame_f_fx, 0, shl( imult1616( num_freq_bands, diff_proto_info->num_protos_diff ), 1 ) ); - - - FOR( proto_ch_idx = 0; proto_ch_idx < diff_proto_info->num_protos_diff; proto_ch_idx++ ) - { - Word16 num_source_ch = diff_proto_info->num_source_chan_diff[proto_ch_idx]; - move16(); - - FOR( source_ch_cnt = 0; source_ch_cnt < num_source_ch; source_ch_cnt++ ) - { - - Word32 fac_fx = diff_proto_info->proto_fac_fx[proto_ch_idx][source_ch_cnt]; - move32(); - - Word16 source_ch_idx = diff_proto_info->source_chan_idx[proto_ch_idx][source_ch_cnt]; - move16(); - - p_proto_frame_fx = &proto_frame_f_fx[shl( imult1616( proto_ch_idx, num_freq_bands ), 1 )]; - p_real_buffer_fx = &RealBuffer_fx[imult1616( source_ch_idx, num_freq_bands )]; - p_imag_buffer_fx = &ImagBuffer_fx[imult1616( source_ch_idx, num_freq_bands )]; - - FOR( band = 0; band < num_freq_bands; band++ ) - { - - Word32 tmp_x = Mpy_32_32( fac_fx, ( *( p_real_buffer_fx++ ) ) ); // Q(30 + 6 - 31) :: Q5 - - *( p_proto_frame_fx ) = L_add( *( p_proto_frame_fx ), tmp_x ); - move32(); - p_proto_frame_fx++; - - tmp_x = Mpy_32_32( fac_fx, ( *( p_imag_buffer_fx++ ) ) ); // Q(30 + 6 - 31) :: Q5 - - *( p_proto_frame_fx ) = L_add( *( p_proto_frame_fx ), tmp_x ); - move32(); - p_proto_frame_fx++; - } - } - } - - return; -} - -/*------------------------------------------------------------------------- - * ivas_param_mc_dec_compute_diffuse_proto() - * - * Transfer decorrelated signals back from the decorrelator buffer to - * the buffers used in the final synthesis - *------------------------------------------------------------------------*/ - -static void ivas_param_mc_dec_copy_diffuse_proto( - PARAM_MC_DEC_HANDLE hParamMC, /* i : Parametric MC handle */ - Word32 Cldfb_buffer_real_fx[MAX_CICP_CHANNELS][PARAM_MC_MAX_NSLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX], /* o : CLDFB buffer used in the final synthesis (real part) */ - Word32 Cldfb_buffer_imag_fx[MAX_CICP_CHANNELS][PARAM_MC_MAX_NSLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX], /* o : CLDFB buffer used in the final synthesis (imaginary part) */ - const Word16 nY, /* i : number of decorrelated channels */ - const Word16 slot_idx /* i : current time slot index */ -) -{ - Word16 k, l; - Word16 num_freq_bands, num_freq_bands_diff; - Word32 *p_proto_diff_fx; - num_freq_bands = hParamMC->num_freq_bands; - move16(); - num_freq_bands_diff = hParamMC->h_output_synthesis_params.max_band_decorr; - move16(); - - FOR( k = 0; k < nY; k++ ) - { - p_proto_diff_fx = hParamMC->proto_frame_dec_f_fx + imult1616( shl( k, 1 ), num_freq_bands ); // Q11 - - FOR( l = 0; l < num_freq_bands_diff; l++ ) - { - Cldfb_buffer_real_fx[k][slot_idx][l] = *( p_proto_diff_fx++ ); // Q11 - move32(); - Cldfb_buffer_imag_fx[k][slot_idx][l] = *( p_proto_diff_fx++ ); // Q11 - move32(); - } - } - - return; -} - -/*------------------------------------------------------------------------- - * ivas_param_mc_bin2dec() - * - * decode a number of bits to an integer - *------------------------------------------------------------------------*/ -/* r : decoded integer */ -static Word16 ivas_param_mc_bin2dec_fx( - UWord16 bits[PARAM_MC_MAX_BITS], /* i : bit buffer */ - const Word16 N /* i : number of bits to decode */ -) -{ - Word16 i; - Word16 out; - - assert( N <= 16 ); - out = 0; - move16(); - FOR( i = 0; i < N; i++ ) - { - out = add( out, shl( bits[i], sub( sub( N, 1 ), i ) ) ); - } - - return out; -} - -/*------------------------------------------------------------------------- - * ivas_param_mc_uniform_decoder() - * - * decode a uniformily coded sequence of float values - *------------------------------------------------------------------------*/ -static Word16 ivas_param_mc_uniform_decoder_fx( - Word16 *seq, /* o : decoded sequence of float values hParamCodingInfo -> Q-quant*/ - const Word16 sz_seq, /* i : number of values to decode */ - const Word16 *alphabet, /* i : codebook hParamCodingInfo -> Q-quant*/ - const Word16 N, /* i : number of bits per coded index */ - UWord16 bit_buffer[PARAM_MC_MAX_BITS] /* i : bit buffer to decode */ -) -{ - Word16 i; - Word16 idx; - Word16 n_bits; - - n_bits = 0; - move16(); - assert( N * sz_seq < PARAM_MC_MAX_BITS ); - - FOR( i = 0; i < sz_seq; ++i ) - { - idx = ivas_param_mc_bin2dec_fx( &bit_buffer[i * N], N ); - seq[i] = alphabet[idx]; - move16(); - } - - n_bits = imult1616( N, sz_seq ); - - return n_bits; -} - - -/*------------------------------------------------------------------------- - * ivas_param_mc_range_decoder_LC() - * - * decode a sequency of inidices coded with a range coder - *------------------------------------------------------------------------*/ -static Word16 ivas_param_mc_range_decoder_LC_fx( - UWord16 *bit_buffer, /* i : bit buffer to read from */ - Word16 *x, /* o : decoded indices */ - Word16 *BER_detect, /* o : flag for indicating a bit error */ - const Word16 sz_seq, /* i : size of the sequence to be decoded */ - const Word16 sz_alphabet, /* i : size of the alphabet */ - const UWord16 *cft, /* i : cumulative frequency table */ - const UWord16 *sft, /* i : symbol frequency table */ - const Word16 tot_shift, /* i : total frequency as a power of 2 */ - const Word16 nbbits /* i : maximum bit budget */ -) -{ - RangeUniDecState rc_st_dec; /* State of the range decoder */ - Word16 cur_bit_pos; - Word16 k; - Word16 r; - - /* Start Decoding */ - /* Initialize range decoder */ - cur_bit_pos = 0; - move16(); - rc_uni_dec_init_fx( &rc_st_dec, bit_buffer, sub( nbbits, 32 ) ); /* (nbbits + 30) entries are read by the decoder */ - - /* Main Loop through the indices */ - FOR( k = 0; k < sz_seq; k++ ) - { - r = rc_uni_dec_read_symbol_fastS_fx( &rc_st_dec, cft, sft, sz_alphabet, tot_shift ); /*Alphabet size = 17 (2^4 = 16 MSB symbols + 1 ESC symbol) */ - /* r is the symbol read, the possible values are {0,1,....alphabet_size - 1} */ - - /* Update bitstream pointer */ - cur_bit_pos = rc_uni_dec_virtual_finish_fx( &rc_st_dec ); - - /* Confirm that there is no overflow */ - IF( GT_16( cur_bit_pos, nbbits ) ) - { - *BER_detect = s_or( *BER_detect, 1 ); - move16(); - } - - x[k] = r; - move16(); - } - - /* We don't need to finish because virtual_finish() already does the same */ - /*st->next_bit_pos = rc_uni_dec_finish(&rc_st_dec);*/ - - /* Check for bitstream errors */ - IF( rc_st_dec.bit_error_detected != 0 ) - { - *BER_detect = s_or( *BER_detect, 1 ); - move16(); - } - - return cur_bit_pos; -} - -/*------------------------------------------------------------------------- - * param_mc_compute_interpolator() - * - * compute the interpolator used in the final synthesis - *------------------------------------------------------------------------*/ - -static void ivas_param_mc_dec_compute_interpolator_fx( - const UWord16 bAttackPresent, /* i : flag indicating if we have a transient in the current frame */ - const UWord16 attackPos, /* i : position of the transient */ - const UWord16 interp_length, /* i : number of interpolation values to be calculated */ - Word16 *interpolator /* o : interpolator */ -) -{ - Word16 idx; - - IF( bAttackPresent ) - { - FOR( idx = 0; idx < attackPos * 2; idx++ ) - { - interpolator[idx] = 0; - move16(); - } - FOR( ; idx < interp_length; idx++ ) - { - interpolator[idx] = 32767; /* 1.0f Q15 */ - move16(); - } - } - ELSE - { - ivas_jbm_dec_get_adapted_linear_interpolator_fx( DEFAULT_JBM_CLDFB_TIMESLOTS, interp_length, interpolator ); - } - - return; -} - - -/*------------------------------------------------------------------------- - * remove_lfe_from_cy() - * - * remove all LFE related values from a covariance matrix - *------------------------------------------------------------------------*/ - -static void remove_lfe_from_cy_fx( - const Word16 nY, /* i : dimension of the covariance matrix */ - Word16 lfe_indices[PARAM_MC_LOCAL_SZ_LFE_MAP], /* i : LFE index */ - Word16 num_lfe, /* i : number of LFEs */ - Word32 *cy, /* i : covariance matrix */ - Word32 *cy_woLFE /* o : covariance matrix with LFE removed */ -) -{ - Word16 ch_idx1, ch_idx2; - Word16 lfe_idx1, lfe_idx2; - Word32 *ptrCy; - Word32 *ptrCy_out; - - ptrCy = cy; - ptrCy_out = cy_woLFE; - - FOR( lfe_idx1 = 0; lfe_idx1 < num_lfe + 1; lfe_idx1++ ) - { - FOR( ch_idx1 = lfe_indices[lfe_idx1] + 1; ch_idx1 < lfe_indices[lfe_idx1 + 1]; ch_idx1++ ) - { - FOR( lfe_idx2 = 0; lfe_idx2 < num_lfe + 1; lfe_idx2++ ) - { - FOR( ch_idx2 = lfe_indices[lfe_idx2] + 1; ch_idx2 < lfe_indices[lfe_idx2 + 1]; ch_idx2++ ) - { - *( ptrCy_out++ ) = *( ptrCy++ ); - move32(); - } - ptrCy++; - } - ptrCy--; - } - ptrCy += nY; - } - - return; -} - - -/*------------------------------------------------------------------------- - * ivas_param_mc_get_mixing_matrices() - * - * calculate the direct and residual mixing matrices - * using the covariance method - *------------------------------------------------------------------------*/ - -static void ivas_param_mc_get_mixing_matrices_fx( - PARAM_MC_DEC_HANDLE hParamMC, /* i : Parametric MC handle */ - IVAS_OUTPUT_SETUP *hSynthesisOutputSetup, - Word32 Cx_in_fixed[PARAM_MC_MAX_TRANSPORT_CHANS * PARAM_MC_MAX_TRANSPORT_CHANS], /* i : input covariance for all parameter bands Q(31 - Cx_in_e)*/ - Word16 Cx_in_e, - const Word16 param_band_idx, /* i : parameter band index */ - Word32 *mixing_matrix_fx[], // Q(31 - mixing_matrix_e) - Word16 *mixing_matrix_e, - Word32 *mixing_matrix_res_fx[], // Q(31 - mixing_matrix_res_e) - Word16 *mixing_matrix_res_e, - const Word16 nY_intern, /* i : number of channels in the transported format */ - const PARAM_MC_SYNTHESIS_CONF synth_config, /* i : Parametric MC synthesis config */ - const Word16 nX, /* i : number of transport channels */ - const Word16 nY_cov /* i : number of covariance synthesis output channels */ -) -{ - Word16 matSize = MAX_OUTPUT_CHANNELS * MAX_OUTPUT_CHANNELS; - Word16 nY_band; - Word16 num_lfe_bands; - Word16 brange[2]; - uint16_t i; - Word16 ch_idx1, ch_idx2, lfe_idx1, lfe_idx2; - Word16 remove_lfe; - Word16 lfe_indices[PARAM_MC_LOCAL_SZ_LFE_MAP]; - - Word32 Cx_fx[PARAM_MC_MAX_TRANSPORT_CHANS * PARAM_MC_MAX_TRANSPORT_CHANS]; - Word32 Cy_fx[MAX_CICP_CHANNELS * MAX_CICP_CHANNELS]; - - Word32 Cy_full_fx[MAX_CICP_CHANNELS * MAX_CICP_CHANNELS]; - - Word32 Cr_fx[MAX_CICP_CHANNELS * MAX_CICP_CHANNELS]; // Q(31 - Cr_e) - Word16 Cr_e; - Word32 Cy_diag_fx[MAX_OUTPUT_CHANNELS]; // Q(31 - Cy_diag_buff_e) - Word16 Cy_diag_buff_e[MAX_OUTPUT_CHANNELS]; - Word32 mixing_matrix_local_fx[MAX_CICP_CHANNELS * PARAM_MC_MAX_TRANSPORT_CHANS]; // Q(31 - mixing_matrix_local_e) - Word16 Cy_diag_e = 0, mixing_matrix_local_e = 0; - Word32 Cproto_fx[MAX_CICP_CHANNELS * MAX_CICP_CHANNELS]; // Q(31 - Cproto_e) - Word16 Cproto_e; - Word32 *proto_matrix_ptr_fx; // Q(31 - proto_matrix_ptr_e) - Word32 *Cx_state_fx; // Q(31 - Cx_state_e) - Word32 *Cx_old_state_fx; - Word32 Cy_state_fx[MAX_CICP_CHANNELS * MAX_CICP_CHANNELS]; // Q(31 - Cy_state_e) - Word32 *Cy_old_state_fx; - Word16 Cx_state_e; - Word16 Cy_state_e; - Word32 mixing_matrix_res_local_fx[MAX_CICP_CHANNELS * MAX_CICP_CHANNELS]; // Q(31 - mixing_matrix_res_local_e) - Word16 mixing_matrix_res_local_e; - Word32 L_tmp; - Word16 tmp_e, tmp; - - Word16 proto_matrix_e = hParamMC->h_output_synthesis_params.proto_matrix_e; - move16(); - Word32 proto_matrix_noLFE_fx[PARAM_MC_MAX_TRANSPORT_CHANS * MAX_CICP_CHANNELS]; // Q(31 - proto_matrix_noLFE_e) - - Word32 mat_mult_buffer1_fx[MAX_CICP_CHANNELS * MAX_CICP_CHANNELS]; // Q(31 - mat_mult_buffer1_e) - - Word32 Cproto_diag_fx[MAX_CICP_CHANNELS]; // Q(31 - Cproto_diag_e) - Word16 mat_mult_buffer1_e, proto_matrix_ptr_e, Cproto_diag_e; - - Word32 *ptrMM_fx; - Word32 *ptrMM_out_fx; - - Word16 Cy_e, Cx_e; - Word16 Cy_full_e; - Word16 new_e = 0; - move16(); - - set_zero_fx( Cproto_fx, MAX_CICP_CHANNELS * MAX_CICP_CHANNELS ); - set_zero_fx( mat_mult_buffer1_fx, MAX_CICP_CHANNELS * MAX_CICP_CHANNELS ); - set_zero_fx( proto_matrix_noLFE_fx, PARAM_MC_MAX_TRANSPORT_CHANS * MAX_CICP_CHANNELS ); - set_zero_fx( mixing_matrix_local_fx, MAX_CICP_CHANNELS * PARAM_MC_MAX_TRANSPORT_CHANS ); -#ifdef MSAN_FIX - set_zero_fx( mixing_matrix_res_local_fx, MAX_CICP_CHANNELS * MAX_CICP_CHANNELS ); -#endif - Word16 proto_matrix_noLFE_e = 0; - move16(); - - Word32 Cx_in_fx[PARAM_MC_MAX_TRANSPORT_CHANS * PARAM_MC_MAX_TRANSPORT_CHANS]; - - Copy32( Cx_in_fixed, Cx_in_fx, PARAM_MC_MAX_TRANSPORT_CHANS * PARAM_MC_MAX_TRANSPORT_CHANS ); - - nY_band = nY_cov; - move16(); - num_lfe_bands = 0; - move16(); - remove_lfe = 0; - move16(); - - set16_fx( lfe_indices, -1, PARAM_MC_LOCAL_SZ_LFE_MAP ); - IF( hSynthesisOutputSetup->num_lfe ) - { - Word32 *proto_matrix_ptr_in_fx; - FOR( lfe_idx1 = 0; lfe_idx1 < hSynthesisOutputSetup->num_lfe; lfe_idx1++ ) - { - lfe_indices[lfe_idx1 + 1] = hSynthesisOutputSetup->index_lfe[lfe_idx1]; - move16(); - } - lfe_indices[hSynthesisOutputSetup->num_lfe + 1] = nY_cov; - move16(); - proto_matrix_ptr_fx = &proto_matrix_noLFE_fx[0]; - proto_matrix_ptr_in_fx = &hParamMC->h_output_synthesis_params.proto_matrix_fx[0]; - proto_matrix_noLFE_e = proto_matrix_e; - move16(); - - set_zero_fx( proto_matrix_noLFE_fx, PARAM_MC_MAX_TRANSPORT_CHANS * MAX_CICP_CHANNELS ); - - FOR( ch_idx1 = 0; ch_idx1 < nX; ch_idx1++ ) - { - FOR( lfe_idx1 = 0; lfe_idx1 < hSynthesisOutputSetup->num_lfe + 1; lfe_idx1++ ) - { - FOR( ch_idx2 = lfe_indices[lfe_idx1] + 1; ch_idx2 < lfe_indices[lfe_idx1 + 1]; ch_idx2++ ) - { - *( proto_matrix_ptr_fx++ ) = *( proto_matrix_ptr_in_fx++ ); - move32(); - } - proto_matrix_ptr_in_fx++; - } - proto_matrix_ptr_in_fx--; - } - - proto_matrix_ptr_e = proto_matrix_e; - move16(); - } - - if ( hParamMC->hMetadataPMC->lfe_on ) - { - num_lfe_bands = PARAM_MC_MAX_BAND_LFE; - move16(); - } - IF( hSynthesisOutputSetup->num_lfe > 0 && param_band_idx >= num_lfe_bands ) - { - remove_lfe = 1; - move16(); - nY_band = sub( nY_cov, hSynthesisOutputSetup->num_lfe ); - proto_matrix_ptr_fx = proto_matrix_noLFE_fx; - proto_matrix_ptr_e = proto_matrix_noLFE_e; - move16(); - } - ELSE - { - proto_matrix_ptr_fx = hParamMC->h_output_synthesis_params.proto_matrix_fx; - proto_matrix_ptr_e = hParamMC->h_output_synthesis_params.proto_matrix_e; - move16(); - } - - brange[0] = hParamMC->band_grouping[param_band_idx]; - move16(); - brange[1] = hParamMC->band_grouping[param_band_idx + 1]; - move16(); - - Cx_state_fx = Cx_in_fx; - Cx_old_state_fx = hParamMC->h_output_synthesis_cov_state.cx_old_fx[param_band_idx]; - Cy_old_state_fx = hParamMC->h_output_synthesis_cov_state.cy_old_fx[param_band_idx]; - - - /* Getting mixing mtx */ - /* estimate target cov from input cov and proto_matrix */ - - Cx_state_e = Cx_in_e; - move16(); - matrix_product_fx( hParamMC->proto_matrix_int_fx, nY_intern, nX, 0, Cx_state_fx, nX, nX, 0, mat_mult_buffer1_fx ); - mat_mult_buffer1_e = add( hParamMC->proto_matrix_int_e, Cx_in_e ); - - matrix_product_fx( mat_mult_buffer1_fx, nY_intern, nX, 0, hParamMC->proto_matrix_int_fx, nY_intern, nX, 1, Cproto_fx ); - Cproto_e = add( mat_mult_buffer1_e, hParamMC->proto_matrix_int_e ); - - FOR( ch_idx1 = 0; ch_idx1 < nY_intern; ch_idx1++ ) - { - IF( BASOP_Util_Cmp_Mant32Exp( Cproto_fx[ch_idx1 + ( ch_idx1 * nY_intern )], Cproto_e, 0, 0 ) < 0 ) - { - Cproto_fx[ch_idx1 + ( ch_idx1 * nY_intern )] = 0; - move32(); - } - } - - set_zero_fx( Cy_state_fx, matSize ); - Cy_state_e = 0; - move16(); - - ivas_param_mc_dequantize_cov_fx( hParamMC, - hParamMC->icld_q_fx + L_mult0( param_band_idx, hParamMC->hMetadataPMC->ild_mapping_conf->ild_map_size_lfe ), - hParamMC->icc_q_fx + L_mult0( param_band_idx, hParamMC->hMetadataPMC->icc_mapping_conf->icc_map_size_lfe ), - param_band_idx, nY_cov, - synth_config, - nY_intern, - nX, Cx_state_fx, Cx_state_e, Cproto_fx, Cproto_e, Cy_state_fx, &Cy_state_e ); - - // dbgwrite2_txt(Cy_state_fx,nY_intern*nY_intern,"../cy_state_fx.txt"); - - /* Smoothing: Sum over two buffers */ - IF( hParamMC->hMetadataPMC->bAttackPresent ) - { - /* no smoothing on attacks */ - Copy32( Cx_state_fx, Cx_fx, imult1616( nX, nX ) ); - Copy32( Cy_state_fx, Cy_full_fx, imult1616( nY_cov, nY_cov ) ); - Cy_full_e = Cy_state_e; - move16(); - Cx_e = Cx_state_e; - move16(); - } - ELSE - { - /* smoothing gains are now identical to one, simply add up */ - // v_add( Cy_state, Cy_old_state, Cy_full, nY_cov * nY_cov ); - - v_add_fixed_me( Cx_state_fx, Cx_state_e, Cx_old_state_fx, hParamMC->h_output_synthesis_cov_state.cx_old_e[param_band_idx], Cx_fx, &Cx_e, imult1616( nX, nX ), 1 ); - v_add_fixed_me( Cy_state_fx, Cy_state_e, Cy_old_state_fx, hParamMC->h_output_synthesis_cov_state.cy_old_e[param_band_idx], Cy_full_fx, &Cy_full_e, imult1616( nY_cov, nY_cov ), 1 ); - } - - Copy32( Cx_state_fx, Cx_old_state_fx, imult1616( nX, nX ) ); - - Copy32( Cy_state_fx, Cy_old_state_fx, imult1616( nY_cov, nY_cov ) ); - - hParamMC->h_output_synthesis_cov_state.cx_old_e[param_band_idx] = Cx_state_e; - move16(); - hParamMC->h_output_synthesis_cov_state.cy_old_e[param_band_idx] = Cy_state_e; - move16(); - - FOR( i = 0; i < nX * nX; i++ ) - { - if ( Cx_old_state_fx[i] != 0 ) - { - new_e = hParamMC->h_output_synthesis_cov_state.cx_old_e[param_band_idx]; - move16(); - BREAK; - } - } - - hParamMC->h_output_synthesis_cov_state.cx_old_e[param_band_idx] = new_e; - move16(); - - new_e = 0; - move16(); - - FOR( i = 0; i < nY_cov * nY_cov; i++ ) - { - if ( Cy_old_state_fx[i] != 0 ) - { - new_e = hParamMC->h_output_synthesis_cov_state.cy_old_e[param_band_idx]; - move16(); - BREAK; - } - } - - hParamMC->h_output_synthesis_cov_state.cy_old_e[param_band_idx] = new_e; - move16(); - - /* remove LFE IF necessary */ - IF( remove_lfe ) - { - - Cy_e = Cy_full_e; - remove_lfe_from_cy_fx( nY_cov, lfe_indices, hSynthesisOutputSetup->num_lfe, Cy_full_fx, Cy_fx ); - } - ELSE - { - Copy32( Cy_full_fx, Cy_fx, imult1616( nY_band, nY_band ) ); - Cy_e = Cy_full_e; - move16(); - } - - matrix_product_fx( proto_matrix_ptr_fx, nY_band, nX, 0, Cx_fx, nX, nX, 0, mat_mult_buffer1_fx ); - mat_mult_buffer1_e = add( proto_matrix_ptr_e, Cx_e ); - - matrix_product_diag_fx( mat_mult_buffer1_fx, mat_mult_buffer1_e, nY_band, nX, 0, proto_matrix_ptr_fx, proto_matrix_ptr_e, nY_band, nX, 1, Cproto_diag_fx, &Cproto_diag_e ); - - /* make sure we have no negative entries in Cproto_diag due to rounding errors */ - - FOR( ch_idx1 = 0; ch_idx1 < nY_band; ch_idx1++ ) - { - if ( BASOP_Util_Cmp_Mant32Exp( Cproto_diag_fx[ch_idx1], Cproto_diag_e, 0, 0 ) < 0 ) - { - Cproto_diag_fx[ch_idx1] = 0; - move16(); - } - } - - - /* Computing the mixing matrices */ - - /* bands with decorr */ - IF( LT_16( brange[0], hParamMC->h_output_synthesis_params.max_band_decorr ) ) - { - computeMixingMatrices_fx( nX, nY_band, Cx_fx, Cx_e, Cy_fx, Cy_e, proto_matrix_ptr_fx, proto_matrix_ptr_e, 0, PARAM_MC_REG_SX_FX, 0, PARAM_MC_REG_GHAT_FX, 0, mixing_matrix_local_fx, &mixing_matrix_local_e, Cr_fx, &Cr_e ); - /* Compute mixing matrix FOR residual */ - computeMixingMatricesResidual_fx( nY_band, Cproto_diag_fx, Cproto_diag_e, Cr_fx, Cr_e, PARAM_MC_REG_SX_FX, 0, PARAM_MC_REG_GHAT_FX, 0, mixing_matrix_res_local_fx, &mixing_matrix_res_local_e ); - - IF( NE_16( mixing_matrix_res_local_e, mixing_matrix_local_e ) ) - { - tmp = getScaleFactor32( mixing_matrix_local_fx, MAX_CICP_CHANNELS * PARAM_MC_MAX_TRANSPORT_CHANS ); - scale_sig32( mixing_matrix_local_fx, MAX_CICP_CHANNELS * PARAM_MC_MAX_TRANSPORT_CHANS, tmp ); - mixing_matrix_local_e = sub( mixing_matrix_local_e, tmp ); - - tmp = getScaleFactor32( mixing_matrix_res_local_fx, MAX_CICP_CHANNELS * MAX_CICP_CHANNELS ); - scale_sig32( mixing_matrix_res_local_fx, MAX_CICP_CHANNELS * MAX_CICP_CHANNELS, tmp ); - mixing_matrix_res_local_e = sub( mixing_matrix_res_local_e, tmp ); - - scale_sig32( mixing_matrix_local_fx, MAX_CICP_CHANNELS * PARAM_MC_MAX_TRANSPORT_CHANS, sub( mixing_matrix_local_e, s_max( mixing_matrix_local_e, mixing_matrix_res_local_e ) ) ); - scale_sig32( mixing_matrix_res_local_fx, MAX_CICP_CHANNELS * MAX_CICP_CHANNELS, sub( mixing_matrix_res_local_e, s_max( mixing_matrix_local_e, mixing_matrix_res_local_e ) ) ); - - mixing_matrix_res_local_e = mixing_matrix_local_e = s_max( mixing_matrix_local_e, mixing_matrix_res_local_e ); - move16(); - } - IF( remove_lfe ) - { - set_zero_fx( mixing_matrix_res_fx[param_band_idx], imult1616( nY_cov, nY_cov ) ); - - ptrMM_fx = mixing_matrix_res_local_fx; - ptrMM_out_fx = mixing_matrix_res_fx[param_band_idx]; - FOR( lfe_idx1 = 0; lfe_idx1 < hSynthesisOutputSetup->num_lfe + 1; lfe_idx1++ ) - { - FOR( ch_idx1 = lfe_indices[lfe_idx1] + 1; ch_idx1 < lfe_indices[lfe_idx1 + 1]; ch_idx1++ ) - { - FOR( lfe_idx2 = 0; lfe_idx2 < hSynthesisOutputSetup->num_lfe + 1; lfe_idx2++ ) - { - FOR( ch_idx2 = lfe_indices[lfe_idx2] + 1; ch_idx2 < lfe_indices[lfe_idx2 + 1]; ch_idx2++ ) - { - *( ptrMM_out_fx++ ) = *( ptrMM_fx++ ); - move32(); - } - ptrMM_out_fx++; - } - ptrMM_out_fx--; - } - ptrMM_out_fx += nY_cov; - } - mixing_matrix_res_e[param_band_idx] = mixing_matrix_res_local_e; - move16(); - } - ELSE - { - Copy32( mixing_matrix_res_local_fx, mixing_matrix_res_fx[param_band_idx], imult1616( nY_cov, nY_cov ) ); - mixing_matrix_res_e[param_band_idx] = mixing_matrix_res_local_e; - move16(); - } - } - ELSE IF( brange[0] < hParamMC->max_band_energy_compensation ) - { - /* Compute mixing matrices (energy compensation only) */ - computeMixingMatrices_fx( nX, nY_band, Cx_fx, Cx_e, Cy_fx, Cy_e, proto_matrix_ptr_fx, proto_matrix_ptr_e, 1, PARAM_MC_REG_SX_FX, 0, PARAM_MC_REG_GHAT_FX, 0, mixing_matrix_local_fx, &mixing_matrix_local_e, Cr_fx, &Cr_e ); - } - ELSE - { - /*IF neither decorrelation nor energy compensation is applied*/ - FOR( i = 0; i < nY_band; i++ ) - { - tmp = BASOP_Util_Divide3232_Scale( Cy_fx[i], L_add( Cproto_diag_fx[i], EPSILON_FX ), &tmp_e ); - tmp_e = add( Cy_diag_e, Cproto_diag_e ); - L_tmp = Sqrt32( L_deposit_h( tmp ), &tmp_e ); - Cy_diag_fx[i] = L_tmp; - move32(); - Cy_diag_buff_e[i] = tmp_e; - move16(); - } - - - Cy_diag_e = Cy_diag_buff_e[0]; - move16(); - - FOR( i = 1; i < nY_band; i++ ) - { - if ( LT_16( Cy_diag_e, Cy_diag_buff_e[i] ) ) - { - Cy_diag_e = Cy_diag_buff_e[i]; - move16(); - } - } - - FOR( i = 0; i < nY_band; i++ ) - { - Cy_diag_fx[i] = L_shr( Cy_diag_fx[i], sub( Cy_diag_e, Cy_diag_buff_e[i] ) ); - move32(); - } - - diag_matrix_product_fx( Cy_diag_fx, Cy_diag_e, nY_band, proto_matrix_ptr_fx, proto_matrix_ptr_e, nY_band, nX, 0, mixing_matrix_local_fx, &mixing_matrix_local_e ); - } - - IF( remove_lfe ) - { - set_zero_fx( mixing_matrix_fx[param_band_idx], imult1616( nX, nY_cov ) ); - ptrMM_fx = mixing_matrix_local_fx; - ptrMM_out_fx = mixing_matrix_fx[param_band_idx]; - FOR( ch_idx1 = 0; ch_idx1 < nX; ch_idx1++ ) - { - FOR( lfe_idx1 = 0; lfe_idx1 < hSynthesisOutputSetup->num_lfe + 1; lfe_idx1++ ) - { - FOR( ch_idx2 = lfe_indices[lfe_idx1] + 1; ch_idx2 < lfe_indices[lfe_idx1 + 1]; ch_idx2++ ) - { - *( ptrMM_out_fx++ ) = *( ptrMM_fx++ ); - move32(); - } - ptrMM_out_fx++; - } - ptrMM_out_fx--; - } - - mixing_matrix_e[param_band_idx] = mixing_matrix_local_e; - move16(); - } - ELSE - { - Copy32( mixing_matrix_local_fx, mixing_matrix_fx[param_band_idx], imult1616( nY_cov, nX ) ); - mixing_matrix_e[param_band_idx] = mixing_matrix_local_e; - move16(); - } - - return; -} - - -/*------------------------------------------------------------------------- - * ivas_param_mc_get_mono_stereo_mixing_matrices() - * - * calculate the direct and residual mixing matrices - * for mono and stereo output - *------------------------------------------------------------------------*/ - - -/*------------------------------------------------------------------------- - * param_mc_update_mixing_matrices() - * - * update mixing matrix buffers - *------------------------------------------------------------------------*/ - -static void param_mc_update_mixing_matrices_fx( - PARAM_MC_DEC_HANDLE hParamMC, /* i/o: Parametric MC handle */ - Word32 *mixing_matrix[], /* i : direct mixing matrices for the frame just processed */ - Word16 *mixing_matrix_exp, - Word32 *mixing_matrix_res[], /* i : residual mixing matrices for the frame just processed */ - Word16 *mixing_matrix_res_exp, - const UWord16 nX, /* i : number of transport channels */ - const UWord16 nY ) /* i : number of synthesis channels */ -{ - UWord16 param_band_idx; - - FOR( param_band_idx = 0; param_band_idx < hParamMC->hMetadataPMC->nbands_coded; param_band_idx++ ) - { - Word16 brange[2]; - - brange[0] = hParamMC->band_grouping[param_band_idx]; - move16(); - brange[1] = hParamMC->band_grouping[param_band_idx + 1]; - move16(); - - Copy32( mixing_matrix[param_band_idx], hParamMC->h_output_synthesis_cov_state.mixing_matrix_old_fx[param_band_idx], imult1616( nX, nY ) ); - hParamMC->h_output_synthesis_cov_state.mixing_matrix_old_exp[param_band_idx] = mixing_matrix_exp[param_band_idx]; - move16(); - - IF( LT_16( brange[0], hParamMC->h_output_synthesis_params.max_band_decorr ) ) - { - Copy32( mixing_matrix_res[param_band_idx], hParamMC->h_output_synthesis_cov_state.mixing_matrix_res_old_fx[param_band_idx], imult1616( nY, nY ) ); - hParamMC->h_output_synthesis_cov_state.mixing_matrix_res_old_exp[param_band_idx] = mixing_matrix_res_exp[param_band_idx]; - move16(); - } - } - - return; -} - - -/*------------------------------------------------------------------------- - * ivas_param_mc_dequantize_cov() - * - * generate the target covariance matrix - *------------------------------------------------------------------------*/ - - -/*------------------------------------------------------------------------- - * ivas_param_mc_dequantize_cov_fx() - * - * generate the target covariance matrix - *------------------------------------------------------------------------*/ - -static void ivas_param_mc_dequantize_cov_fx( - PARAM_MC_DEC_HANDLE hParamMC, /* i : Parametric MC handle */ - Word16 *ild_q_fx, /* i : sequence of dequantized ILD values Q8 */ - Word16 *icc_q_fx, /* i : sequence of dequantized ICC values Q15*/ - const Word16 param_band_index, /* i : current parameter band */ - const Word16 nY_cov, /* i : number of output channels in the covariance synthesis */ - const PARAM_MC_SYNTHESIS_CONF synth_conf, /* i : Parametric MC synthesis configuration */ - const Word16 nY_int, /* i : number of channels in the transported format */ - const Word16 nX, /* i : number of transport channels */ - Word32 *Cx_state_fx, /* i : transport channel covariance matrix */ - Word16 Cx_state_e, /* i : exponent for transport channel covariance matrix */ - Word32 *Cproto_fx, /* i : prototype matrix */ - Word16 Cproto_e, /* i : exponent for prototype matrix */ - Word32 *Cy_state_fx, /* o : target covariance matrix */ - Word16 *Cy_state_e /* o : exponent for target covariance matrix */ -) -{ - Word16 Cy_buf_e[MAX_OUTPUT_CHANNELS * MAX_OUTPUT_CHANNELS]; - Word16 Cp_buf_e[MAX_OUTPUT_CHANNELS * MAX_OUTPUT_CHANNELS]; - - Word32 Nrqq_fx[MAX_OUTPUT_CHANNELS]; // Q(31 - Nrqq_e) - Word16 Nrqq_e[MAX_OUTPUT_CHANNELS]; - Word32 a_fx[MAX_OUTPUT_CHANNELS]; // Q(31 - a_e) - Word16 a_e[MAX_OUTPUT_CHANNELS]; - Word16 k; - Word16 l; - Word32 *Cyp_fx; // Q(31 - Cyp_e) - Word16 *Cyp_e; - Word32 ap_fx; // Q(31 - ap_e) - Word16 ap_e; - Word32 L_tmp; - Word16 tmp, tmp_e; - const PARAM_MC_ILD_MAPPING *h_ild_mapping; - Word32 Cy_state_int_fx[MAX_OUTPUT_CHANNELS * MAX_OUTPUT_CHANNELS]; - Word16 Cy_state_int_e[MAX_OUTPUT_CHANNELS * MAX_OUTPUT_CHANNELS]; - - set16_fx( Cp_buf_e, Cproto_e, MAX_OUTPUT_CHANNELS * MAX_OUTPUT_CHANNELS ); - set32_fx( Nrqq_fx, 0, MAX_OUTPUT_CHANNELS ); - set16_fx( Nrqq_e, 0, MAX_OUTPUT_CHANNELS ); - h_ild_mapping = hParamMC->hMetadataPMC->ild_mapping_conf; - - /*get back Nrg*/ - tmp = 0; - move16(); - - FOR( k = 0; k < nY_int; k++ ) - { - Word32 ref_ener_fx = 0; // Q(31 - ref_ener_e) - move32(); - Word16 ref_ener_e = 0; - move16(); - Word16 ref_channel_cnt; - Word16 ref_channel_idx; - - FOR( ref_channel_cnt = 0; ref_channel_cnt < h_ild_mapping->num_ref_channels[k]; ref_channel_cnt++ ) - { - ref_channel_idx = h_ild_mapping->ref_channel_idx[k][ref_channel_cnt]; - move16(); - ref_ener_fx = BASOP_Util_Add_Mant32Exp( Cx_state_fx[ref_channel_idx + ( ref_channel_idx * nX )], Cx_state_e, ref_ener_fx, ref_ener_e, &ref_ener_e ); - move32(); - } - - L_tmp = Mpy_32_16_1( 713378626, ild_q_fx[k] ); /*Q24 : L_tmp Q31 for log2(10)/10 -> 713378626 */ - L_tmp = BASOP_util_Pow2( L_tmp, 31 - 24, &tmp_e ); /*powf( 10.0f, ild_q_fx[k] / 10.0f )*/ - L_tmp = Mpy_32_32( L_tmp, Mpy_32_16_1( ref_ener_fx, hParamMC->hMetadataPMC->ild_factors_fx[k] ) ); - - Nrqq_fx[h_ild_mapping->ild_index[k]] = L_tmp; - move32(); - Nrqq_e[h_ild_mapping->ild_index[k]] = add( tmp_e, ref_ener_e ); - move16(); - } - - /* estimate ICCs from estimated Cproto */ - - FOR( k = 0; k < nY_int; k++ ) - { - // a_fx[k] = 1.f / ( sqrtf( Cproto_fx[k + nY_int * k] ) + EPSILON ); - tmp_e = Cp_buf_e[k + ( nY_int * k )]; - move16(); - - IF( Cproto_fx[k + ( nY_int * k )] != 0 ) - { - L_tmp = ISqrt32( Cproto_fx[k + ( nY_int * k )], &tmp_e ); - } - ELSE - { - L_tmp = INV_EPSILON_MANT; - move32(); - tmp_e = 15; - move16(); - } - a_fx[k] = L_tmp; - move32(); - a_e[k] = tmp_e; - move16(); - - FOR( l = 0; l < nY_int; l++ ) - { - Cy_state_int_fx[( k * nY_int ) + l] = Mpy_32_32( Cproto_fx[( k * nY_int ) + l], a_fx[k] ); - move32(); - Cy_state_int_e[( k * nY_int ) + l] = add( Cp_buf_e[( k * nY_int ) + l], a_e[k] ); - move16(); - } - } - - FOR( k = 0; k < nY_int; k++ ) - { - Cyp_fx = Cy_state_int_fx + k; - Cyp_e = Cy_state_int_e + k; - ap_fx = a_fx[k]; - move32(); - ap_e = a_e[k]; - move16(); - - FOR( l = 0; l < nY_int; l++ ) - { - ( *Cyp_fx ) = Mpy_32_32( *Cyp_fx, ap_fx ); - move32(); - *Cyp_e = add( *Cyp_e, ap_e ); - move16(); - - Cyp_fx += nY_int; - Cyp_e += nY_int; - } - } - - /*normalizing the Cy_state_int_fx to a common exponent*/ - - /* replace some estimated ICCs with transmitted values */ - FOR( k = 0; k < hParamMC->hMetadataPMC->icc_mapping_conf->icc_map_size_lfe; k++ ) - { - Cy_state_int_fx[hParamMC->hMetadataPMC->icc_mapping_conf->icc_mapping[k][0] + ( nY_int * hParamMC->hMetadataPMC->icc_mapping_conf->icc_mapping[k][1] )] = L_shr( L_deposit_h( icc_q_fx[k] ), tmp ); - move32(); - Cy_state_int_e[hParamMC->hMetadataPMC->icc_mapping_conf->icc_mapping[k][0] + ( nY_int * hParamMC->hMetadataPMC->icc_mapping_conf->icc_mapping[k][1] )] = tmp; - move16(); - Cy_state_int_fx[hParamMC->hMetadataPMC->icc_mapping_conf->icc_mapping[k][1] + ( nY_int * hParamMC->hMetadataPMC->icc_mapping_conf->icc_mapping[k][0] )] = L_shr( L_deposit_h( icc_q_fx[k] ), tmp ); - move32(); - Cy_state_int_e[hParamMC->hMetadataPMC->icc_mapping_conf->icc_mapping[k][1] + ( nY_int * hParamMC->hMetadataPMC->icc_mapping_conf->icc_mapping[k][0] )] = tmp; - move16(); - } - - test(); - IF( GE_16( param_band_index, PARAM_MC_MAX_BAND_LFE ) || ( hParamMC->hMetadataPMC->lfe_on == 0 ) ) - { - FOR( k = 0; k < nY_int; k++ ) - { - Cy_state_int_fx[k + ( 3 * nY_int )] = ONE_IN_Q31; - move32(); - Cy_state_int_e[k + ( 3 * nY_int )] = 0; - move16(); - Cy_state_int_fx[3 + ( k * nY_int )] = ONE_IN_Q31; - move32(); - Cy_state_int_e[3 + ( k * nY_int )] = 0; - move16(); - } - Nrqq_fx[3] = 0; - move32(); - } - - /* Generate back Covariance Mtx */ - FOR( k = 0; k < nY_int; k++ ) - { - tmp_e = Nrqq_e[k]; - move16(); - a_fx[k] = Sqrt32( Nrqq_fx[k], &tmp_e ); - move32(); - a_e[k] = tmp_e; - move16(); - - /* v_multc( Cy_state_int_fx + k * nY_int, a_fx[k], Cy_state_int_fx + k * nY_int, nY_int ) */ - FOR( l = 0; l < nY_int; l++ ) - { - Cy_state_int_fx[( k * nY_int ) + l] = Mpy_32_32( Cy_state_int_fx[( k * nY_int ) + l], a_fx[k] ); - move32(); - Cy_state_int_e[( k * nY_int ) + l] = add( Cy_state_int_e[( k * nY_int ) + l], a_e[k] ); - move16(); - } - } - - FOR( k = 0; k < nY_int; k++ ) - { - Cyp_fx = Cy_state_int_fx + k; - Cyp_e = Cy_state_int_e + k; - ap_fx = a_fx[k]; - move32(); - ap_e = a_e[k]; - move16(); - - FOR( l = 0; l < nY_int; l++ ) - { - ( *Cyp_fx ) = Mpy_32_32( *Cyp_fx, ap_fx ); - move32(); - ( *Cyp_e ) = add( *Cyp_e, ap_e ); - move16(); - - Cyp_fx += nY_int; - Cyp_e += nY_int; - } - } - - IF( EQ_32( synth_conf, PARAM_MC_SYNTH_LS_CONV_COV ) ) - { - /* Cy = dmx*Cy*dmx' */ - Word32 mat_mult_buffer1_fx[MAX_CICP_CHANNELS * MAX_CICP_CHANNELS]; // Q(31 - mat_mult_buffer1_e) - Word16 mat_mult_buffer1_e[MAX_CICP_CHANNELS * MAX_CICP_CHANNELS]; - Word32 target_ch_ener_fx[MAX_CICP_CHANNELS]; // Q(31 - target_ch_ener_e) - Word16 target_ch_ener_e[MAX_CICP_CHANNELS]; - Word32 dmx_ch_ener_fx[MAX_CICP_CHANNELS]; - - Word16 ls_conv_dmx_matrix_e[MAX_CICP_CHANNELS * MAX_CICP_CHANNELS]; - - set32_fx( target_ch_ener_fx, 0, MAX_CICP_CHANNELS ); - set16_fx( target_ch_ener_e, 0, MAX_CICP_CHANNELS ); - set32_fx( dmx_ch_ener_fx, 0, MAX_CICP_CHANNELS ); - set16_fx( ls_conv_dmx_matrix_e, 1, MAX_OUTPUT_CHANNELS * MAX_OUTPUT_CHANNELS ); - - matrix_product_mant_exp( hParamMC->ls_conv_dmx_matrix_fx, ls_conv_dmx_matrix_e, nY_cov, nY_int, 0, - Cy_state_int_fx, Cy_state_int_e, nY_int, nY_int, 0, - mat_mult_buffer1_fx, mat_mult_buffer1_e ); - - matrix_product_mant_exp( mat_mult_buffer1_fx, mat_mult_buffer1_e, nY_cov, nY_int, 0, - hParamMC->ls_conv_dmx_matrix_fx, ls_conv_dmx_matrix_e, nY_cov, nY_int, 1, - Cy_state_fx, Cy_buf_e ); - - FOR( k = 0; k < nY_cov; k++ ) - { - FOR( l = 0; l < nY_int; l++ ) - { - L_tmp = Mpy_32_32( hParamMC->ls_conv_dmx_matrix_fx[k + ( l * nY_cov )], Nrqq_fx[l] ); - tmp_e = add( ls_conv_dmx_matrix_e[k + ( l + nY_cov )], Nrqq_e[l] ); - L_tmp = BASOP_Util_Add_Mant32Exp( target_ch_ener_fx[k], target_ch_ener_e[k], L_tmp, tmp_e, &tmp_e ); - target_ch_ener_fx[k] = L_tmp; - move32(); - target_ch_ener_e[k] = tmp_e; - move16(); - } - - dmx_ch_ener_fx[k] = Cy_state_fx[k + ( nY_cov * k )]; - move32(); - - IF( dmx_ch_ener_fx[k] < 0 ) - { - Cy_state_fx[k + ( nY_cov * k )] = L_negate( Cy_state_fx[k + ( nY_cov * k )] ); - move32(); - dmx_ch_ener_fx[k] = L_negate( dmx_ch_ener_fx[k] ); - move32(); - } - - IF( extract_h( dmx_ch_ener_fx[k] ) == 0 ) - { - target_ch_ener_fx[k] = 0; - move32(); - target_ch_ener_e[k] = 0; - move16(); - } - ELSE - { - BASOP_Util_Divide_MantExp( extract_h( target_ch_ener_fx[k] ), target_ch_ener_e[k], extract_h( dmx_ch_ener_fx[k] ), Cy_buf_e[k + ( nY_cov * k )], &tmp, &tmp_e ); - tmp = Sqrt16( tmp, &tmp_e ); - target_ch_ener_fx[k] = L_deposit_h( tmp ); - move32(); - target_ch_ener_e[k] = tmp_e; - move16(); - } - - FOR( l = 0; l < nY_cov; l++ ) - { - Cy_state_fx[( k * nY_cov ) + l] = Mpy_32_32( target_ch_ener_fx[k], Cy_state_fx[( k * nY_cov ) + l] ); - move32(); - Cy_buf_e[( k * nY_cov ) + l] = add( target_ch_ener_e[k], Cy_buf_e[( k * nY_cov ) + l] ); - move16(); - } - - Cyp_fx = Cy_state_fx + k; - Cyp_e = Cy_buf_e + k; - ap_fx = target_ch_ener_fx[k]; - move32(); - ap_e = target_ch_ener_e[k]; - move16(); - FOR( l = 0; l < nY_cov; l++ ) - { - ( *Cyp_fx ) = Mpy_32_32( *Cyp_fx, ap_fx ); - move32(); - *Cyp_e = add( *Cyp_e, ap_e ); - move16(); - - Cyp_fx += nY_cov; - Cyp_e += nY_cov; - } - } - } - ELSE - { - Copy32( Cy_state_int_fx, Cy_state_fx, imult1616( nY_int, nY_int ) ); - Copy( Cy_state_int_e, Cy_buf_e, imult1616( nY_int, nY_int ) ); - } - - /*normalize output matrix to a common exponent*/ - tmp = 0; - FOR( k = 0; k < nY_int * nY_int; k++ ) - { - Cy_state_fx[k] = BASOP_Util_Add_Mant32Exp( Cy_state_fx[k], Cy_buf_e[k], 0, 0, &Cy_buf_e[k] ); - move32(); - tmp = s_max( tmp, Cy_buf_e[k] ); - } - FOR( k = 0; k < nY_int * nY_int; k++ ) - { - L_tmp = L_shr( Cy_state_fx[k], sub( tmp, Cy_buf_e[k] ) ); - Cy_state_fx[k] = L_tmp; - move32(); - } - *Cy_state_e = tmp; - move16(); - - return; -} - -/*-------------------------------------------------------------------------* - * param_mc_set_num_synth_bands() - * - * set the number of frequency bands to be synthesized - *-------------------------------------------------------------------------*/ - -static void param_mc_set_num_synth_bands( - const Word32 output_Fs, /* i : output sampling frequency */ - PARAM_MC_DEC_HANDLE hParamMC /* i/o: Parametric MC handle */ -) -{ - UWord16 max_param_band_synth; - const Word16 *param_mc_bands_coded; - - SWITCH( hParamMC->hMetadataPMC->num_parameter_bands ) - { - case 20: - param_mc_bands_coded = param_mc_bands_coded_20; - BREAK; - case 10: - param_mc_bands_coded = param_mc_bands_coded_10; - BREAK; - case 14: - default: - param_mc_bands_coded = param_mc_bands_coded_14; - BREAK; - } - move16(); - SWITCH( output_Fs ) - { - case 8000: - max_param_band_synth = (UWord16) param_mc_bands_coded[NB]; - BREAK; - case 16000: - max_param_band_synth = (UWord16) param_mc_bands_coded[WB]; - BREAK; - case 32000: - max_param_band_synth = (UWord16) param_mc_bands_coded[SWB]; - BREAK; - case 48000: - default: - max_param_band_synth = (UWord16) param_mc_bands_coded[FB]; - BREAK; - } - move16(); - hParamMC->num_param_bands_synth = s_min( hParamMC->hMetadataPMC->nbands_coded, max_param_band_synth ); - move16(); - - return; -} - - -/*-------------------------------------------------------------------------* - * param_mc_get_diff_proto_info() - * - * calculated the diffuse prototype information - *-------------------------------------------------------------------------*/ - - -static ivas_error param_mc_get_diff_proto_info_fx( - const Word32 *proto_mtx, /* i : protoype matrix for the synthesis */ - const UWord16 nchan_transport, /* i : number of transport channels */ - const UWord16 nchan_out_cov, /* i : number if output channels of the covariance synthesis */ - PARAM_MC_DIFF_PROTO_INFO *p_diff_proto_info, /* o : generated diffuse prototype info */ - Word16 Q_proto_mtx ) -{ - Word32 proto_fac_fx[MAX_CICP_CHANNELS * PARAM_MC_MAX_TRANSPORT_CHANS]; - UWord16 cur_out_ch; - UWord16 cur_diff_proto; - UWord16 cur_transport_ch; - UWord16 max_num_src_chan; - - /* Initializations */ - max_num_src_chan = 0; - move16(); - - set_zero_fx( proto_fac_fx, MAX_CICP_CHANNELS * PARAM_MC_MAX_TRANSPORT_CHANS ); - IF( ( p_diff_proto_info->proto_index_diff = (Word16 *) malloc( nchan_out_cov * sizeof( Word16 ) ) ) == NULL ) - { - return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Parametric MC\n" ) ); - } - set16_fx( p_diff_proto_info->proto_index_diff, 0, nchan_out_cov ); - - IF( ( p_diff_proto_info->num_source_chan_diff = (Word16 *) malloc( nchan_out_cov * sizeof( Word16 ) ) ) == NULL ) - { - return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Parametric MC\n" ) ); - } - set16_fx( p_diff_proto_info->num_source_chan_diff, 0, nchan_out_cov ); - - /* we have at least one prototype, copy the first one */ - p_diff_proto_info->num_protos_diff = 1; - move16(); - - mvr2r_inc_fixed( proto_mtx, nchan_out_cov, proto_fac_fx, nchan_out_cov, nchan_transport ); - p_diff_proto_info->proto_index_diff[0] = 0; - move16(); - - /* search for distinct prototypes */ - FOR( cur_out_ch = 1; cur_out_ch < nchan_out_cov; cur_out_ch++ ) - { - UWord16 found = 0; - move16(); - - FOR( cur_diff_proto = 0; cur_diff_proto < p_diff_proto_info->num_protos_diff; cur_diff_proto++ ) - { - Word32 diff_fx = 0; - move32(); - Word32 *proto_fac_ptr_fx = proto_fac_fx + cur_diff_proto; - const Word32 *proto_mtx_ptr = proto_mtx + cur_out_ch; - FOR( cur_transport_ch = 0; cur_transport_ch < nchan_transport; cur_transport_ch++ ) - { - diff_fx = L_add( diff_fx, L_abs( L_sub( *proto_fac_ptr_fx, *proto_mtx_ptr ) ) ); - proto_fac_ptr_fx += nchan_out_cov; - proto_mtx_ptr += nchan_out_cov; - } - - /* we already have this prototype, save the index */ - IF( LT_64( W_mult0_32_32( diff_fx, 10 ), L_shl_sat( 1, Q_proto_mtx ) ) ) - { - found = 1; - move16(); - p_diff_proto_info->proto_index_diff[cur_out_ch] = cur_diff_proto; - move16(); - BREAK; - } - } - - /* new distinct prototype, add it */ - IF( found == 0 ) - { - const Word32 *proto_mtx_ptr = proto_mtx + cur_out_ch; - Word16 cur_num_src_chan; - - cur_num_src_chan = 0; - move16(); - FOR( cur_transport_ch = 0; cur_transport_ch < nchan_transport; cur_transport_ch++ ) - { - if ( GT_32( *proto_mtx_ptr, 0 /*EPSILON*/ ) ) - { - cur_num_src_chan = add( cur_num_src_chan, 1 ); - } - proto_mtx_ptr += nchan_out_cov; - } - - mvr2r_inc_fixed( proto_mtx + cur_out_ch, nchan_out_cov, proto_fac_fx + p_diff_proto_info->num_protos_diff, nchan_out_cov, nchan_transport ); - - p_diff_proto_info->proto_index_diff[cur_out_ch] = p_diff_proto_info->num_protos_diff; - move16(); - p_diff_proto_info->num_protos_diff = add( p_diff_proto_info->num_protos_diff, 1 ); - move16(); - max_num_src_chan = s_max( max_num_src_chan, cur_num_src_chan ); - } - } - - /* set up the prototype info struct */ - IF( ( p_diff_proto_info->source_chan_idx = (Word16 **) malloc( p_diff_proto_info->num_protos_diff * sizeof( Word16 * ) ) ) == NULL ) - { - return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Parametric MC\n" ) ); - } - - IF( ( p_diff_proto_info->proto_fac_fx = (Word32 **) malloc( p_diff_proto_info->num_protos_diff * sizeof( Word32 * ) ) ) == NULL ) - { - return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Parametric MC\n" ) ); - } - FOR( cur_diff_proto = 0; cur_diff_proto < p_diff_proto_info->num_protos_diff; cur_diff_proto++ ) - { - Word32 *proto_fac_ptr; - - IF( ( p_diff_proto_info->source_chan_idx[cur_diff_proto] = (Word16 *) malloc( max_num_src_chan * sizeof( Word16 ) ) ) == NULL ) - { - return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Parametric MC\n" ) ); - } - - IF( ( p_diff_proto_info->proto_fac_fx[cur_diff_proto] = (Word32 *) malloc( max_num_src_chan * sizeof( Word32 ) ) ) == NULL ) - { - return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Parametric MC\n" ) ); - } - - proto_fac_ptr = proto_fac_fx + cur_diff_proto; - FOR( cur_transport_ch = 0; cur_transport_ch < nchan_transport; cur_transport_ch++ ) - { - IF( GT_32( *proto_fac_ptr, EPSILON_FX_SMALL ) ) - { - p_diff_proto_info->source_chan_idx[cur_diff_proto][p_diff_proto_info->num_source_chan_diff[cur_diff_proto]] = cur_transport_ch; - move16(); - p_diff_proto_info->proto_fac_fx[cur_diff_proto][p_diff_proto_info->num_source_chan_diff[cur_diff_proto]] = L_shl( *proto_fac_ptr, 4 ); // (proto_fac_fx)Q26 + 4 = Q30 - move16(); - p_diff_proto_info->num_source_chan_diff[cur_diff_proto] = add( p_diff_proto_info->num_source_chan_diff[cur_diff_proto], 1 ); - move16(); - } - proto_fac_ptr += nchan_out_cov; - } - } - return IVAS_ERR_OK; -} - - -/*-------------------------------------------------------------------------* - * ivas_param_mc_bs_decode_parameter_values() - * - * reads and decodes a sequence of Parametric MC parameters from the bitstream - *-------------------------------------------------------------------------*/ - -static void ivas_param_mc_bs_decode_parameter_values_fx( - UWord16 bit_buffer[], /* i : bitstream buffer */ - Word16 *bit_pos, /* i/o: current bitstream buffer position */ - const Word16 max_bits, /* i : maximum available bits in the buffer */ - Word16 *BER_detect, /* i/o: bit error detection flag */ - HANDLE_IVAS_PARAM_MC_METADATA hMetadataPMC, /* i : Parametric MC metadata information */ - HANDLE_PARAM_MC_PARAMETER_CODING_INFO hParamCodingInfo, /* i : Parametric MC parameter quantization and coding tables */ - const Word16 map_size_wo_lfe, /* i : number of parameters per band (w/o LFEs) */ - const Word16 map_size, /* i : number of parameters per band (total) */ - const Word16 num_lfe_bands, /* i : number of parameter bands with coded LFE */ - const Word16 band_step, /* i : parameter band step */ - const Word16 num_param_bands, /* i : number of parameter bands to decode */ - Word16 *value_buffer /* o : output buffer for decoded parameter values hParamCodingInfo -> Q-quant*/ -) -{ - Word16 range_coding; - Word16 sz_seq; - Word16 delta_coding; - Word16 delta_idx[PARAM_MC_MAX_PARAMETER_BANDS * PARAM_MC_MAX_VAL_MAP_SIZE]; - Word16 idx[PARAM_MC_MAX_PARAMETER_BANDS * PARAM_MC_MAX_VAL_MAP_SIZE]; - Word16 idx_prev; - Word16 idx_offset; - Word16 sz_alphabet; - Word16 i, j, k; - Word16 dequant_seq_fx[PARAM_MC_MAX_PARAMETER_BANDS * PARAM_MC_MAX_VAL_MAP_SIZE]; - Word16 dequant_ordered_fx[PARAM_MC_MAX_PARAMETER_BANDS * PARAM_MC_MAX_VAL_MAP_SIZE]; - Word16 n_lfe_idx; - - range_coding = bit_buffer[*bit_pos]; - move16(); - *bit_pos = add( *bit_pos, 1 ); - move16(); - - /* Decoding the sequence */ - n_lfe_idx = sub( map_size, map_size_wo_lfe ); - sz_seq = add( imult1616( num_param_bands, map_size_wo_lfe ), imult1616( num_lfe_bands, n_lfe_idx ) ); - - set16_fx( idx, 0, PARAM_MC_MAX_PARAMETER_BANDS * PARAM_MC_MAX_VAL_MAP_SIZE ); - set16_fx( dequant_ordered_fx, 0, PARAM_MC_MAX_PARAMETER_BANDS * PARAM_MC_MAX_VAL_MAP_SIZE ); - set16_fx( dequant_seq_fx, 0, PARAM_MC_MAX_PARAMETER_BANDS * PARAM_MC_MAX_VAL_MAP_SIZE ); - IF( range_coding ) - { - delta_coding = bit_buffer[*bit_pos]; - move16(); - *bit_pos = add( *bit_pos, 1 ); - move16(); - - IF( delta_coding ) - { - idx_prev = sub( add( shr( hParamCodingInfo->quantizer_size, 1 ), hParamCodingInfo->quantizer_size % 2 ), 1 ); - sz_alphabet = sub( shl( hParamCodingInfo->quantizer_size, 1 ), 1 ); - idx_offset = sub( hParamCodingInfo->quantizer_size, 1 ); - - /* read range coded delta ICC indices */ - *bit_pos = add( *bit_pos, ivas_param_mc_range_decoder_LC_fx( &bit_buffer[*bit_pos], delta_idx, BER_detect, sz_seq, sz_alphabet, - hParamCodingInfo->cum_freq_delta, hParamCodingInfo->sym_freq_delta, PARAM_MC_RANGE_CODER_TOT_SHIFT, sub( max_bits, *bit_pos ) ) ); - move16(); - - /* delta index to absolute index */ - FOR( j = 0; j < sz_seq; j++ ) - { - idx[j] = add( idx_prev, sub( delta_idx[j], idx_offset ) ); - idx_prev = idx[j]; - move16(); - } - } - ELSE - { - /* read range coded absolute ICC indices */ - sz_alphabet = hParamCodingInfo->quantizer_size; - move16(); - *bit_pos = add( *bit_pos, ivas_param_mc_range_decoder_LC_fx( &bit_buffer[*bit_pos], idx, BER_detect, sz_seq, sz_alphabet, - hParamCodingInfo->cum_freq, hParamCodingInfo->sym_freq, PARAM_MC_RANGE_CODER_TOT_SHIFT, sub( max_bits, *bit_pos ) ) ); - move16(); - } - - /* dequantize */ - FOR( j = 0; j < sz_seq; j++ ) - { - dequant_seq_fx[j] = hParamCodingInfo->quantizer_fx[idx[j]]; // hParamCodingInfo -> Q-quant - move16(); - } - } - ELSE - { - set16_fx( dequant_seq_fx, 0, PARAM_MC_MAX_PARAMETER_BANDS * PARAM_MC_MAX_VAL_MAP_SIZE ); - /* read uniformly coded ICCs */ - *bit_pos = add( *bit_pos, ivas_param_mc_uniform_decoder_fx( dequant_seq_fx, sz_seq, hParamCodingInfo->quantizer_fx, hParamCodingInfo->uni_bits, &bit_buffer[*bit_pos] ) ); - move16(); - } - - /* reorder from sequential to parameter-band-wise */ - k = 0; - FOR( j = 0; j < map_size_wo_lfe; ++j ) - { - FOR( i = 0; i < num_param_bands; ++i ) - { - dequant_ordered_fx[j + ( i * map_size )] = dequant_seq_fx[k]; // hParamCodingInfo -> Q-quant - move16(); - k = add( k, 1 ); - } - } - - FOR( i = 0; i < num_lfe_bands; i++ ) - { - FOR( j = 0; j < n_lfe_idx; j++ ) - { - dequant_ordered_fx[map_size - n_lfe_idx + j + i * map_size] = dequant_seq_fx[k]; // hParamCodingInfo -> Q-quant - move16(); - k = add( k, 1 ); - } - } - - IF( !( *BER_detect ) ) - { - j = 0; - FOR( k = 0; k < hMetadataPMC->nbands_coded; k += band_step ) - { - test(); - IF( hMetadataPMC->bAttackPresent || EQ_16( hMetadataPMC->param_frame_idx, hMetadataPMC->coding_band_mapping[k] ) ) - { - Copy( dequant_ordered_fx + imult1616( j, map_size ), value_buffer + imult1616( k, map_size ), map_size ); // hParamCodingInfo -> Q-quant - j++; - } - IF( hMetadataPMC->bAttackPresent && k + 1 < hMetadataPMC->nbands_coded ) - { - Copy( value_buffer + imult1616( k, map_size ), value_buffer + imult1616( add( k, 1 ), map_size ), map_size ); - } - } - } - - return; -} diff --git a/lib_dec/ivas_mc_param_dec_fx.c b/lib_dec/ivas_mc_param_dec_fx.c index 0d9ee27107cedfdf97ef477e77d8c0882d2917ca..a065a0b029d6b04ca7f77d89308fb1d79ff09f6f 100644 --- a/lib_dec/ivas_mc_param_dec_fx.c +++ b/lib_dec/ivas_mc_param_dec_fx.c @@ -1,5 +1,3860 @@ +/****************************************************************************************************** + + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository. All Rights Reserved. + + This software is protected by copyright law and by international treaties. + The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository retain full ownership rights in their respective contributions in + the software. This notice grants no license of any kind, including but not limited to patent + license, nor is any license granted by implication, estoppel or otherwise. + + Contributors are required to enter into the IVAS codec Public Collaboration agreement before making + contributions. + + This software is provided "AS IS", without any express or implied warranties. The software is in the + development stage. It is intended exclusively for experts who have experience with such software and + solely for the purpose of inspection. All implied warranties of non-infringement, merchantability + and fitness for a particular purpose are hereby disclaimed and excluded. + + Any dispute, controversy or claim arising under or in relation to providing this software shall be + submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in + accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and + the United Nations Convention on Contracts on the International Sales of Goods. + +*******************************************************************************************************/ + +#include +#include "options.h" +#include +#include "cnst.h" +#include "rom_enc.h" +#include "rom_com.h" +#include "prot_fx.h" +#include "ivas_prot_rend_fx.h" +#include "ivas_cnst.h" +#include "ivas_rom_com.h" +#include "ivas_rom_dec.h" +#include "math.h" +#include "wmc_auto.h" +#include "rom_dec.h" #include "ivas_prot_fx.h" +#define INV_EPSILON_MANT 214748365 + +/*-----------------------------------------------------------------------* + * Local constants + *-----------------------------------------------------------------------*/ + +#define PARAM_MC_LOCAL_SZ_LFE_MAP 5 + +/*-----------------------------------------------------------------------* + * Local typedefs + *-----------------------------------------------------------------------*/ + +typedef struct parameter_band_mapping_struct +{ + Word16 n_source_bands[20]; + Word16 source_band_idx[20][4]; + Word16 source_band_factor_fx[20][4]; /*Q15*/ + +} PARAM_MC_PARAMETER_BAND_MAPPING; + +/*-----------------------------------------------------------------------* + * Local function prototypes + *-----------------------------------------------------------------------*/ + +static void ivas_param_mc_dec_init_fx( PARAM_MC_DEC_HANDLE hParamMC, const Word16 nchan_in, const Word16 nchan_out ); + +static void ivas_param_mc_dec_copy_diffuse_proto( PARAM_MC_DEC_HANDLE hParamMC, Word32 Cldfb_buffer_real_fx[MAX_CICP_CHANNELS][PARAM_MC_MAX_NSLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX], Word32 Cldfb_buffer_imag_fx[MAX_CICP_CHANNELS][PARAM_MC_MAX_NSLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX], const Word16 nY, const Word16 slot_idx ); +static Word16 ivas_param_mc_range_decoder_LC_fx( UWord16 *bit_buffer, Word16 *x, Word16 *BER_detect, const Word16 sz_seq, const Word16 sz_alphabet, const UWord16 *cft, const UWord16 *sft, const Word16 tot_shift, const Word16 nbbits ); + + +static void ivas_param_mc_get_mixing_matrices_fx( + PARAM_MC_DEC_HANDLE hParamMC, /* i : Parametric MC handle */ + IVAS_OUTPUT_SETUP *hSynthesisOutputSetup, + Word32 Cx_in_fixed[PARAM_MC_MAX_TRANSPORT_CHANS * PARAM_MC_MAX_TRANSPORT_CHANS], /* i : input covariance for all parameter bands */ + Word16 Cx_in_e, + const Word16 param_band_idx, + Word32 *mixing_matrix_fx[], + Word16 *mixing_matrix_e, + Word32 *mixing_matrix_res_fx[], + Word16 *mixing_matrix_res_e, + const Word16 nY_intern, /* i : number of channels in the transported format */ + const PARAM_MC_SYNTHESIS_CONF synth_config, /* i : Parametric MC synthesis config */ + const Word16 nX, /* i : number of transport channels */ + const Word16 nY_cov /* i : number of covariance synthesis output channels */ +); + +static Word16 ivas_param_mc_uniform_decoder_fx( Word16 *seq, const Word16 sz_seq, const Word16 *alphabet, const Word16 N, UWord16 bit_buffer[PARAM_MC_MAX_BITS] ); +static void ivas_param_mc_dec_compute_interpolator_fx( const UWord16 bAttackPresent, const UWord16 attackPos, const UWord16 interp_length, Word16 *interpolator ); + +static void param_mc_set_num_synth_bands( const Word32 output_Fs, PARAM_MC_DEC_HANDLE hParamMC ); + +static void ivas_param_mc_get_param_band_mapping( const Word16 n_target_bands, const Word16 *target_band_grouping, const Word16 n_source_bands, const Word16 *source_band_grouping, PARAM_MC_PARAMETER_BAND_MAPPING *parameter_band_mapping ); + + +static void ivas_param_mc_bs_decode_parameter_values_fx( UWord16 bit_buffer[], Word16 *bit_pos, const Word16 max_bits, Word16 *BER_detect, HANDLE_IVAS_PARAM_MC_METADATA hMetadataPMC, HANDLE_PARAM_MC_PARAMETER_CODING_INFO hParamCodingInfo, const Word16 map_size_wo_lfe, const Word16 map_size, const Word16 num_lfe_bands, const Word16 band_step, const Word16 num_param_bands, Word16 *value_buffer ); +static void ivas_param_mc_dequantize_cov_fx( PARAM_MC_DEC_HANDLE hParamMC, Word16 *ild_q_fx, Word16 *icc_q_fx, const Word16 param_band_index, const Word16 nY_cov, const PARAM_MC_SYNTHESIS_CONF synth_conf, const Word16 nY_int, const Word16 nX, Word32 *Cx_state_fx, Word16 Cx_state_e, Word32 *Cproto_fx, Word16 Cproto_e, Word32 *Cy_state_fx, Word16 *Cy_state_e ); +static ivas_error param_mc_get_diff_proto_info_fx( const Word32 *proto_mtx, const UWord16 nchan_transport, const UWord16 nchan_out_cov, PARAM_MC_DIFF_PROTO_INFO *p_diff_proto_info, Word16 Q_proto_mtx ); +static void param_mc_update_mixing_matrices_fx( PARAM_MC_DEC_HANDLE hParamMC, Word32 *mixing_matrix[], Word16 *mixing_matrix_fx, Word32 *mixing_matrix_res[], Word16 *mixing_matrix_res_exp, const UWord16 nX, const UWord16 nY ); + + +static void param_mc_protoSignalComputation_fx( Word32 *RealBuffer_fx, Word32 *ImagBuffer_fx, Word32 *proto_frame_f_fx, const PARAM_MC_DIFF_PROTO_INFO *diff_proto_info, const Word16 num_freq_bands /*, Word16 RealBuffer_fx_e, Word16 ImagBuffer_fx_e, Word16 *common_e*/ ); + +/*------------------------------------------------------------------------- + * ivas_param_mc_dec_open() + * + * Open Parametric MC decoder handle + *-------------------------------------------------------------------------*/ + +ivas_error ivas_param_mc_dec_open_fx( + Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */ +) +{ + Word16 k, nchan_transport; + PARAM_MC_DEC_HANDLE hParamMC; + Word16 nchan_out_transport; + Word16 nchan_out_cov; + Word32 proto_matrix_fx[MAX_CICP_CHANNELS * PARAM_MC_MAX_TRANSPORT_CHANS]; + Word32 proto_mtx_norm_fx; + Word16 frequency_axis_fx[CLDFB_NO_CHANNELS_MAX]; + Word16 max_param_band_residual; + UWord16 config_index; + MC_LS_SETUP mc_ls_setup; + AUDIO_CONFIG output_config; + Word32 output_Fs, ivas_total_brate; + ivas_error error; + + error = IVAS_ERR_OK; + move32(); + + /*-----------------------------------------------------------------* + * prepare library opening + *-----------------------------------------------------------------*/ + + IF( ( hParamMC = (PARAM_MC_DEC_HANDLE) malloc( sizeof( PARAM_MC_DEC_DATA ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Parametric MC\n" ) ); + } + + IF( ( hParamMC->hMetadataPMC = (HANDLE_IVAS_PARAM_MC_METADATA) malloc( sizeof( IVAS_PARAM_MC_METADATA ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Parametric MC metadata \n" ) ); + } + + output_Fs = st_ivas->hDecoderConfig->output_Fs; + move32(); + output_config = st_ivas->hDecoderConfig->output_config; + move32(); + ivas_total_brate = st_ivas->hDecoderConfig->ivas_total_brate; + move32(); + mc_ls_setup = ivas_mc_map_output_config_to_mc_ls_setup_fx( st_ivas->transport_config ); + nchan_out_transport = add( st_ivas->hTransSetup.nchan_out_woLFE, st_ivas->hTransSetup.num_lfe ); + hParamMC->hoa_encoder_fx = NULL; + + /* determine the synthesis config */ + test(); + test(); + test(); + test(); + test(); + IF( EQ_32( st_ivas->renderer_type, RENDERER_SBA_LINEAR_ENC ) || EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_FASTCONV ) || EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_FASTCONV_ROOM ) || EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_OBJECTS_TD ) || EQ_32( st_ivas->transport_config, output_config ) ) + { + hParamMC->synthesis_conf = PARAM_MC_SYNTH_DIRECT; + move32(); + } + ELSE IF( EQ_32( output_config, IVAS_AUDIO_CONFIG_MONO ) || EQ_32( output_config, IVAS_AUDIO_CONFIG_STEREO ) ) + { + hParamMC->synthesis_conf = PARAM_MC_SYNTH_MONO_STEREO; + move32(); + } + ELSE IF( NE_32( st_ivas->transport_config, output_config ) ) + { + test(); + test(); + IF( ( NE_32( output_config, IVAS_AUDIO_CONFIG_LS_CUSTOM ) && GT_16( nchan_out_transport, audioCfg2channels( output_config ) ) ) || ( EQ_32( output_config, IVAS_AUDIO_CONFIG_LS_CUSTOM ) && GT_16( nchan_out_transport, st_ivas->hOutSetup.nchan_out_woLFE ) ) ) + { + hParamMC->synthesis_conf = PARAM_MC_SYNTH_LS_CONV_COV; + move32(); + /* need to reset the intern config */ + st_ivas->intern_config = output_config; + move32(); + ivas_output_init( &( st_ivas->hIntSetup ), st_ivas->intern_config ); + IF( EQ_32( output_config, IVAS_AUDIO_CONFIG_LS_CUSTOM ) ) + { + st_ivas->hIntSetup.nchan_out_woLFE = st_ivas->hLsSetupCustom->num_spk; + move32(); + st_ivas->hIntSetup.ls_azimuth_fx = st_ivas->hLsSetupCustom->ls_azimuth_fx; // Q22 + st_ivas->hIntSetup.ls_elevation_fx = st_ivas->hLsSetupCustom->ls_elevation_fx; // Q22 + } + } + ELSE + { + hParamMC->synthesis_conf = PARAM_MC_SYNTH_LS_CONV_CLDFB; + move32(); + } + } + + hParamMC->ls_conv_dmx_matrix_fx = NULL; + + test(); + IF( EQ_32( hParamMC->synthesis_conf, PARAM_MC_SYNTH_LS_CONV_COV ) || EQ_32( hParamMC->synthesis_conf, PARAM_MC_SYNTH_MONO_STEREO ) ) + { + nchan_out_cov = add( st_ivas->hOutSetup.nchan_out_woLFE, st_ivas->hOutSetup.num_lfe ); + } + ELSE + { + nchan_out_cov = nchan_out_transport; + move16(); + } + + st_ivas->nchan_transport = ivas_param_mc_getNumTransportChannels_fx( ivas_total_brate, mc_ls_setup ); + move16(); + config_index = ivas_param_mc_get_configuration_index_fx( mc_ls_setup, ivas_total_brate ); + nchan_transport = st_ivas->nchan_transport; + move16(); + + SWITCH( nchan_transport ) + { + case 4: + case 3: + st_ivas->nCPE = 2; + move16(); + st_ivas->nSCE = 0; + move16(); + st_ivas->element_mode_init = IVAS_CPE_MDCT; + move16(); + BREAK; + case 2: + st_ivas->nCPE = 1; + move16(); + st_ivas->nSCE = 0; + move16(); + st_ivas->element_mode_init = IVAS_CPE_MDCT; + move16(); + + BREAK; + } + + /*-----------------------------------------------------------------* + * set input parameters + *-----------------------------------------------------------------*/ + + // hParamMC->slot_size = (int16_t) ( output_Fs / FRAMES_PER_SEC ) / CLDFB_NO_COL_MAX; + Word16 temp_e; + Word16 temp = BASOP_Util_Divide3232_Scale( output_Fs, FRAMES_PER_SEC, &temp_e ); + temp = shr( temp, sub( 15, temp_e ) ); // Going back to Q0 + temp = BASOP_Util_Divide1616_Scale( temp, CLDFB_NO_COL_MAX, &temp_e ); + temp = shr( temp, sub( 15, temp_e ) ); // Going back to Q0 + hParamMC->slot_size = temp; + move16(); + set16_fx( hParamMC->subframe_nbslots, 0, MAX_JBM_SUBFRAMES_5MS ); + set16_fx( hParamMC->subframe_nbslots, PARAM_MC_MAX_NSLOTS_IN_SUBFRAME, DEFAULT_JBM_SUBFRAMES_5MS ); + hParamMC->nb_subframes = DEFAULT_JBM_SUBFRAMES_5MS; + move16(); + + // hParamMC->num_freq_bands = (int16_t)(output_Fs * INV_CLDFB_BANDWIDTH + 0.5f); + hParamMC->num_freq_bands = extract_l( Mpy_32_32_r( output_Fs, INV_CLDFB_BANDWIDTH_Q31 ) ); + move16(); + hParamMC->max_band_energy_compensation = hParamMC->num_freq_bands; + move16(); + ivas_param_mc_metadata_open_fx( mc_ls_setup, ivas_total_brate, hParamMC->hMetadataPMC ); + + /* init arrays for quantized parameters */ + + IF( ( hParamMC->icc_q_fx = (Word16 *) malloc( hParamMC->hMetadataPMC->num_parameter_bands * hParamMC->hMetadataPMC->icc_mapping_conf->icc_map_size_lfe * sizeof( Word16 ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Parametric MC\n" ) ); + } + IF( ( hParamMC->icld_q_fx = (Word16 *) malloc( hParamMC->hMetadataPMC->num_parameter_bands * hParamMC->hMetadataPMC->ild_mapping_conf->ild_map_size_lfe * sizeof( Word16 ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Parametric MC\n" ) ); + } + set16_fx( hParamMC->icld_q_fx, PARAM_MC_DEFAULT_MIN_ILD_FX, imult1616( hParamMC->hMetadataPMC->num_parameter_bands, hParamMC->hMetadataPMC->ild_mapping_conf->ild_map_size_lfe ) ); // Q8 + set16_fx( hParamMC->icc_q_fx, 0, imult1616( hParamMC->hMetadataPMC->num_parameter_bands, hParamMC->hMetadataPMC->icc_mapping_conf->icc_map_size_lfe ) ); // Q15 + + param_mc_set_num_synth_bands( output_Fs, hParamMC ); + + /* Band Grouping */ + IF( EQ_16( hParamMC->hMetadataPMC->num_parameter_bands, 20 ) ) + { + Copy( param_mc_band_grouping_20, hParamMC->band_grouping, 20 + 1 ); + } + ELSE IF( EQ_16( hParamMC->hMetadataPMC->num_parameter_bands, 14 ) ) + { + Copy( param_mc_band_grouping_14, hParamMC->band_grouping, 14 + 1 ); + } + ELSE IF( EQ_16( hParamMC->hMetadataPMC->num_parameter_bands, 10 ) ) + { + Copy( param_mc_band_grouping_10, hParamMC->band_grouping, 10 + 1 ); + } + ELSE + { + assert( 0 && "nbands must be 20, 14, or 10!" ); + } + + /* set max parameter band for abs cov */ + k = 0; + move16(); + WHILE( LE_16( hParamMC->band_grouping[k], PARAM_MC_MAX_BAND_ABS_COV_DEC ) ) + { + hParamMC->max_param_band_abs_cov = k; + move16(); + k = add( k, 1 ); + } + + /*-----------------------------------------------------------------* + * open sub-modules + *-----------------------------------------------------------------*/ + + /* prototype signal computation */ + + test(); + test(); + IF( EQ_32( hParamMC->synthesis_conf, PARAM_MC_SYNTH_LS_CONV_CLDFB ) || EQ_32( hParamMC->synthesis_conf, PARAM_MC_SYNTH_LS_CONV_COV ) || EQ_32( hParamMC->synthesis_conf, PARAM_MC_SYNTH_MONO_STEREO ) ) + { + IF( NE_32( ( error = ivas_ls_setup_conversion_open_fx( st_ivas ) ), IVAS_ERR_OK ) ) + { + return error; + } + + /* convert the ls conv dmx matrix into column order matrix format (nchan_out_cldfb x nchan_out) */ + test(); + IF( EQ_32( hParamMC->synthesis_conf, PARAM_MC_SYNTH_LS_CONV_COV ) || EQ_32( hParamMC->synthesis_conf, PARAM_MC_SYNTH_MONO_STEREO ) ) + { + IF( ( hParamMC->ls_conv_dmx_matrix_fx = (Word32 *) malloc( nchan_out_transport * nchan_out_cov * sizeof( Word32 ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Parametric MC\n" ) ); + } + + FOR( k = 0; k < nchan_out_transport; k++ ) + { + Copy32( st_ivas->hLsSetUpConversion->dmxMtx_fx[k], &hParamMC->ls_conv_dmx_matrix_fx[k * nchan_out_cov], nchan_out_cov ); /*Q30*/ + } + + /* convert ParamMC parameter bands to SFB */ + IF( EQ_32( hParamMC->synthesis_conf, PARAM_MC_SYNTH_MONO_STEREO ) ) + { + st_ivas->hLsSetUpConversion->sfbCnt = hParamMC->num_param_bands_synth; + move16(); + FOR( k = 0; k <= hParamMC->num_param_bands_synth; k++ ) + { + st_ivas->hLsSetUpConversion->sfbOffset[k] = imult1616( PARAM_MC_BAND_TO_MDCT_BAND_RATIO, hParamMC->band_grouping[k] ); + move16(); + } + } + ELSE + { + /* close the ls conversion handle immediately, it was only needed to get the DMX matrix in case of DMX in the covariance domain */ + ivas_ls_setup_conversion_close_fx( &st_ivas->hLsSetUpConversion ); + } + } + } + IF( ( hParamMC->proto_matrix_int_fx = (Word32 *) malloc( nchan_out_transport * nchan_transport * sizeof( Word32 ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Parametric MC\n" ) ); + } + Copy32( ivas_param_mc_conf[config_index].dmx_fac_fx, hParamMC->proto_matrix_int_fx, imult1616( nchan_transport, nchan_out_transport ) ); /*Q31*/ + + hParamMC->proto_matrix_int_len = imult1616( nchan_out_transport, nchan_transport ); + move16(); + + test(); + IF( EQ_32( hParamMC->synthesis_conf, PARAM_MC_SYNTH_LS_CONV_COV ) || EQ_32( hParamMC->synthesis_conf, PARAM_MC_SYNTH_MONO_STEREO ) ) + { + Scale_sig32( hParamMC->ls_conv_dmx_matrix_fx, imult1616( nchan_out_transport, nchan_out_cov ), -4 ); /*Q.26*/ + matrix_product_fx( hParamMC->ls_conv_dmx_matrix_fx, nchan_out_cov, nchan_out_transport, 0, ivas_param_mc_conf[config_index].dmx_fac_fx, nchan_out_transport, nchan_transport, 0, proto_matrix_fx ); /*Q.26*/ + Scale_sig32( hParamMC->ls_conv_dmx_matrix_fx, imult1616( nchan_out_transport, nchan_out_cov ), 4 ); /*Q.26*/ + IF( EQ_32( hParamMC->synthesis_conf, PARAM_MC_SYNTH_MONO_STEREO ) ) + { + proto_mtx_norm_fx = ONE_IN_Q26; /*Q26*/ + move32(); + FOR( k = 0; k < nchan_transport * nchan_out_cov; k++ ) + { + proto_mtx_norm_fx = L_max( L_abs( proto_mtx_norm_fx ), L_abs( proto_matrix_fx[k] ) ); /*Q.26*/ + } + proto_mtx_norm_fx = divide3232( ONE_IN_Q26, proto_mtx_norm_fx ); /*Q15*/ + + /* transfer flattened proto_matrix to 2D in hLsSetupConversion->dmxMtx */ + FOR( k = 0; k < nchan_transport; k++ ) + { + FOR( Word16 i = 0; i < nchan_out_cov; i++ ) + { + st_ivas->hLsSetUpConversion->dmxMtx_fx[k][i] = L_shl( Mult_32_16( proto_matrix_fx[k * nchan_out_cov + i], extract_l( proto_mtx_norm_fx ) ), 4 ); /*Q.30*/ + move32(); + } + } + } + } + ELSE + { + Copy32( ivas_param_mc_conf[config_index].dmx_fac_fx, proto_matrix_fx, imult1616( nchan_out_transport, nchan_transport ) ); /*Q.31*/ + Scale_sig32( proto_matrix_fx, imult1616( nchan_out_transport, nchan_transport ), -5 ); /*Scaling down to 26*/ + } + + IF( EQ_32( hParamMC->synthesis_conf, PARAM_MC_SYNTH_MONO_STEREO ) ) + { + hParamMC->num_outputs_diff = 0; + move16(); + hParamMC->diff_proto_info = NULL; + hParamMC->h_output_synthesis_params.use_onset_filters = 0; + move16(); + hParamMC->max_band_decorr = 0; + move16(); + hParamMC->h_freq_domain_decorr_ap_params = NULL; + hParamMC->h_freq_domain_decorr_ap_state = NULL; + } + ELSE + { + hParamMC->num_outputs_diff = nchan_out_cov; + move16(); + IF( ( hParamMC->diff_proto_info = (PARAM_MC_DIFF_PROTO_INFO *) malloc( sizeof( PARAM_MC_DIFF_PROTO_INFO ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Parametric MC\n" ) ); + } + + IF( NE_32( ( error = param_mc_get_diff_proto_info_fx( proto_matrix_fx, nchan_transport, nchan_out_cov, hParamMC->diff_proto_info, Q26 ) ), IVAS_ERR_OK ) ) + { + return error; + } + + /* decorrelation */ + hParamMC->h_freq_domain_decorr_ap_params = NULL; + hParamMC->h_freq_domain_decorr_ap_state = NULL; + + ivas_dirac_dec_get_frequency_axis_fx( frequency_axis_fx, output_Fs, hParamMC->num_freq_bands ); // Q0 + + IF( NE_32( ( error = ivas_dirac_dec_decorr_open_fx( &( hParamMC->h_freq_domain_decorr_ap_params ), &( hParamMC->h_freq_domain_decorr_ap_state ), hParamMC->num_freq_bands, hParamMC->num_outputs_diff, + hParamMC->diff_proto_info->num_protos_diff, DIRAC_SYNTHESIS_COV_MC_LS, frequency_axis_fx, nchan_transport, output_Fs ) ), + IVAS_ERR_OK ) ) + { + return error; + } + + hParamMC->h_output_synthesis_params.use_onset_filters = 0; + move16(); + hParamMC->max_band_decorr = hParamMC->h_freq_domain_decorr_ap_params->max_band_decorr; + move16(); + } + hParamMC->max_band_energy_compensation = hParamMC->band_grouping[hParamMC->hMetadataPMC->nbands_coded]; + move16(); + max_param_band_residual = 0; + move16(); + + FOR( k = hParamMC->hMetadataPMC->num_parameter_bands; k >= 0; k-- ) + { + IF( LE_16( hParamMC->band_grouping[k], hParamMC->max_band_decorr ) ) + { + max_param_band_residual = k; + move16(); + assert( hParamMC->band_grouping[k] == hParamMC->max_band_decorr ); + break; + } + } + + /* output synthesis */ + IF( NE_32( ( error = ivas_dirac_dec_output_synthesis_cov_open_fx( &( hParamMC->h_output_synthesis_params ), &( hParamMC->h_output_synthesis_cov_state ), hParamMC->max_band_decorr, PARAM_MC_MAX_NSLOTS, hParamMC->hMetadataPMC->num_parameter_bands, max_param_band_residual, nchan_transport, nchan_out_cov, proto_matrix_fx ) ), IVAS_ERR_OK ) ) + { + return error; + } + + ivas_param_mc_dec_compute_interpolator_fx( 0, 0, DEFAULT_JBM_CLDFB_TIMESLOTS, hParamMC->h_output_synthesis_params.interpolator_fx ); + + /* Head or external rotation */ + test(); + test(); + test(); + IF( ( EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_FASTCONV ) || EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_FASTCONV_ROOM ) ) && ( st_ivas->hDecoderConfig->Opt_Headrotation || st_ivas->hDecoderConfig->Opt_ExternalOrientation ) ) + { + IF( ( hParamMC->hoa_encoder_fx = (Word32 *) malloc( st_ivas->hTransSetup.nchan_out_woLFE * MAX_INTERN_CHANNELS * sizeof( Word32 ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Parametric MC\n" ) ); + } + compute_hoa_encoder_mtx_fx( st_ivas->hTransSetup.ls_azimuth_fx, st_ivas->hTransSetup.ls_elevation_fx, hParamMC->hoa_encoder_fx, st_ivas->hTransSetup.nchan_out_woLFE, HEAD_ROTATION_HOA_ORDER ); + } + + /*-----------------------------------------------------------------* + * memory allocation + *-----------------------------------------------------------------*/ + + IF( hParamMC->max_band_decorr > 0 ) + { + IF( ( hParamMC->proto_frame_f_fx = (Word32 *) malloc( 2 * hParamMC->diff_proto_info->num_protos_diff * hParamMC->num_freq_bands * sizeof( Word32 ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Parametric MC\n" ) ); + } + IF( ( hParamMC->proto_frame_dec_f_fx = (Word32 *) malloc( 2 * nchan_out_cov * hParamMC->num_freq_bands * sizeof( Word32 ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Parametric MC\n" ) ); + } + } + ELSE + { + hParamMC->proto_frame_f_fx = NULL; + hParamMC->proto_frame_dec_f_fx = NULL; + } + + ivas_param_mc_dec_init_fx( hParamMC, nchan_transport, nchan_out_cov ); + + IF( NE_32( hParamMC->synthesis_conf, PARAM_MC_SYNTH_MONO_STEREO ) ) + { + Word16 n_cldfb_slots; + + n_cldfb_slots = DEFAULT_JBM_CLDFB_TIMESLOTS; + move16(); + IF( st_ivas->hDecoderConfig->Opt_tsm ) + { + n_cldfb_slots = MAX_JBM_CLDFB_TIMESLOTS; + move16(); + } + + Word16 cldfb_buf_size = imult1616( imult1616( n_cldfb_slots, nchan_transport ), hParamMC->num_freq_bands ); + IF( ( hParamMC->Cldfb_RealBuffer_tc_fx = (Word32 *) malloc( cldfb_buf_size * sizeof( Word32 ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Parametric MC JBM\n" ) ); + } + set32_fx( hParamMC->Cldfb_RealBuffer_tc_fx, 0, cldfb_buf_size ); + IF( ( hParamMC->Cldfb_ImagBuffer_tc_fx = (Word32 *) malloc( cldfb_buf_size * sizeof( Word32 ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Parametric MC JBM\n" ) ); + } + set32_fx( hParamMC->Cldfb_ImagBuffer_tc_fx, 0, cldfb_buf_size ); + + hParamMC->sz = imult1616( imult1616( n_cldfb_slots, nchan_transport ), hParamMC->num_freq_bands ); + move16(); + + IF( st_ivas->hTcBuffer == NULL ) + { + IF( NE_32( ( error = ivas_jbm_dec_tc_buffer_open_fx( st_ivas, TC_BUFFER_MODE_RENDERER, nchan_transport, nchan_transport, 0, NS2SA_FX2( st_ivas->hDecoderConfig->output_Fs, CLDFB_SLOT_NS ) ) ), IVAS_ERR_OK ) ) + { + return error; + } + } + } + ELSE + { + hParamMC->Cldfb_RealBuffer_tc_fx = NULL; + hParamMC->Cldfb_ImagBuffer_tc_fx = NULL; + } + + hParamMC->subframes_rendered = 0; + move16(); + hParamMC->slots_rendered = 0; + move16(); + + st_ivas->hParamMC = hParamMC; + return error; +} + + +/*------------------------------------------------------------------------- + * ivas_param_mc_get_param_band_mapping() + * + * + *-------------------------------------------------------------------------*/ + +static void ivas_param_mc_get_param_band_mapping( + const Word16 n_target_bands, + const Word16 *target_band_grouping, + const Word16 n_source_bands, + const Word16 *source_band_grouping, + PARAM_MC_PARAMETER_BAND_MAPPING *parameter_band_mapping ) +{ + Word16 target_band_idx; + Word16 source_band_idx = 0; + move16(); + Word16 source_band_cnt_total; + + FOR( target_band_idx = 0; target_band_idx < n_target_bands; target_band_idx++ ) + { + Word16 upper = target_band_grouping[target_band_idx + 1]; + Word16 lower = target_band_grouping[target_band_idx]; + Word16 source_band_in_target_band_cnt = 0; + Word16 norm_fac_fx = 32767; // 1.Q15 + source_band_cnt_total = 0; + move16(); + move16(); + move16(); + + FOR( source_band_idx = 0; source_band_idx < n_source_bands; source_band_idx++ ) + { + /* find lowest corresponding source band*/ + test(); + IF( LE_16( source_band_grouping[source_band_idx], lower ) && GE_16( source_band_grouping[source_band_idx + 1], lower ) ) + { + DO + { + Word16 source_bands_in_target_band = sub( s_min( source_band_grouping[source_band_idx + 1], upper ), s_max( source_band_grouping[source_band_idx], lower ) ); + IF( source_bands_in_target_band ) + { + source_band_cnt_total = add( source_band_cnt_total, source_bands_in_target_band ); + parameter_band_mapping->source_band_idx[target_band_idx][source_band_in_target_band_cnt] = source_band_idx; + parameter_band_mapping->source_band_factor_fx[target_band_idx][source_band_in_target_band_cnt++] = shl( source_bands_in_target_band, 10 ); /*Q10*/ + move16(); + move16(); + } + source_band_idx++; + } + WHILE( LE_16( source_band_grouping[source_band_idx], upper ) && LT_16( source_band_idx, n_source_bands ) ); + BREAK; + } + } + norm_fac_fx = div_s( 1, source_band_cnt_total ); /*Q15*/ + FOR( source_band_idx = 0; source_band_idx < source_band_in_target_band_cnt; source_band_idx++ ) + { + parameter_band_mapping->source_band_factor_fx[target_band_idx][source_band_idx] = shl_sat( mult( parameter_band_mapping->source_band_factor_fx[target_band_idx][source_band_idx], norm_fac_fx ) /*Q10*/, 5 ); /*Q15*/ + move16(); + } + parameter_band_mapping->n_source_bands[target_band_idx] = source_band_in_target_band_cnt; + move16(); + } + return; +} + + +/*------------------------------------------------------------------------- + * ivas_param_mc_dec_reconfig() + * + * Reconfiguration of ParamMC decoder + *-------------------------------------------------------------------------*/ + +ivas_error ivas_param_mc_dec_reconfig_fx( + Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */ +) +{ + Word16 k, nchan_transport; + PARAM_MC_DEC_HANDLE hParamMC; + Word16 nchan_out_transport; + Word16 nchan_out_cov; + Word32 proto_matrix_fx[MAX_CICP_CHANNELS * PARAM_MC_MAX_TRANSPORT_CHANS]; + Word32 proto_mtx_norm_fx; + Word16 max_param_band_residual; + UWord16 config_index; + MC_LS_SETUP mc_ls_setup; + Word32 output_Fs, ivas_total_brate; + ivas_error error; + Word16 nchan_transport_old; + Word16 num_param_bands_old; + PARAM_MC_PARAMETER_BAND_MAPPING parameter_band_mapping; + Word16 band_grouping_old[20 + 1]; + + hParamMC = st_ivas->hParamMC; + error = IVAS_ERR_OK; + move32(); + /* save important config information from the previous state */ + nchan_transport_old = st_ivas->nchan_transport; + move32(); + num_param_bands_old = hParamMC->hMetadataPMC->num_parameter_bands; + move32(); + + /*-----------------------------------------------------------------* + * prepare library opening + *-----------------------------------------------------------------*/ + + output_Fs = st_ivas->hDecoderConfig->output_Fs; + move32(); + ivas_total_brate = st_ivas->hDecoderConfig->ivas_total_brate; + move32(); + mc_ls_setup = ivas_mc_map_output_config_to_mc_ls_setup_fx( st_ivas->transport_config ); + nchan_out_transport = add( st_ivas->hTransSetup.nchan_out_woLFE, st_ivas->hTransSetup.num_lfe ); + + test(); + IF( EQ_16( hParamMC->synthesis_conf, PARAM_MC_SYNTH_LS_CONV_COV ) || EQ_16( hParamMC->synthesis_conf, PARAM_MC_SYNTH_MONO_STEREO ) ) + { + nchan_out_cov = add( st_ivas->hOutSetup.nchan_out_woLFE, st_ivas->hOutSetup.num_lfe ); + } + ELSE + { + nchan_out_cov = nchan_out_transport; + move16(); + } + + st_ivas->nchan_transport = ivas_param_mc_getNumTransportChannels_fx( ivas_total_brate, mc_ls_setup ); + move16(); + config_index = ivas_param_mc_get_configuration_index_fx( mc_ls_setup, ivas_total_brate ); + nchan_transport = st_ivas->nchan_transport; + move16(); + + SWITCH( nchan_transport ) + { + case 4: + case 3: + st_ivas->nCPE = 2; + move16(); + st_ivas->nSCE = 0; + move16(); + st_ivas->element_mode_init = IVAS_CPE_MDCT; + move16(); + BREAK; + case 2: + st_ivas->nCPE = 1; + move16(); + st_ivas->nSCE = 0; + move16(); + st_ivas->element_mode_init = IVAS_CPE_MDCT; + move16(); + + BREAK; + } + + /*-----------------------------------------------------------------* + * set input parameters + *-----------------------------------------------------------------*/ + hParamMC->num_freq_bands = shr( add( (Word16) Mpy_32_32( output_Fs, INV_CLDFB_BANDWIDTH_Q31 << 1 ), 1 ), 1 ); // Q0 + move16(); + hParamMC->max_band_energy_compensation = hParamMC->num_freq_bands; + move16(); + + Copy( hParamMC->band_grouping, band_grouping_old, add( hParamMC->hMetadataPMC->num_parameter_bands, 1 ) ); + ivas_param_mc_metadata_open_fx( mc_ls_setup, ivas_total_brate, hParamMC->hMetadataPMC ); + /* Band Grouping */ + IF( EQ_16( hParamMC->hMetadataPMC->num_parameter_bands, 20 ) ) + { + Copy( param_mc_band_grouping_20, hParamMC->band_grouping, 20 + 1 ); + } + ELSE IF( EQ_16( hParamMC->hMetadataPMC->num_parameter_bands, 14 ) ) + { + Copy( param_mc_band_grouping_14, hParamMC->band_grouping, 14 + 1 ); + } + ELSE IF( EQ_16( hParamMC->hMetadataPMC->num_parameter_bands, 10 ) ) + { + Copy( param_mc_band_grouping_10, hParamMC->band_grouping, 10 + 1 ); + } + ELSE + { + assert( 0 && "nbands must be 20, 14, or 10!" ); + } + + ivas_param_mc_get_param_band_mapping( hParamMC->hMetadataPMC->num_parameter_bands, hParamMC->band_grouping, num_param_bands_old, band_grouping_old, ¶meter_band_mapping ); + + test(); + IF( NE_16( nchan_transport_old, nchan_transport ) || NE_16( num_param_bands_old, hParamMC->hMetadataPMC->num_parameter_bands ) ) + { + Word16 *ild_q_old_fx = hParamMC->icld_q_fx; // Q8 + Word16 *icc_q_old_fx = hParamMC->icc_q_fx; // Q15 + + IF( ( hParamMC->icc_q_fx = (Word16 *) malloc( hParamMC->hMetadataPMC->num_parameter_bands * hParamMC->hMetadataPMC->icc_mapping_conf->icc_map_size_lfe * sizeof( Word16 ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Parametric MC\n" ) ); + } + IF( ( hParamMC->icld_q_fx = (Word16 *) malloc( hParamMC->hMetadataPMC->num_parameter_bands * hParamMC->hMetadataPMC->ild_mapping_conf->ild_map_size_lfe * sizeof( Word16 ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Parametric MC\n" ) ); + } + set16_fx( hParamMC->icld_q_fx, PARAM_MC_DEFAULT_MIN_ILD_FX, hParamMC->hMetadataPMC->num_parameter_bands * hParamMC->hMetadataPMC->ild_mapping_conf->ild_map_size_lfe ); /*Q8*/ + set16_fx( hParamMC->icc_q_fx, 0, hParamMC->hMetadataPMC->num_parameter_bands * hParamMC->hMetadataPMC->icc_mapping_conf->icc_map_size_lfe ); /*Q15*/ + + /* map old to new parameter banding, only for same number of TCs, needs some more thought for a changing number of TCs */ + test(); + IF( NE_16( num_param_bands_old, hParamMC->hMetadataPMC->num_parameter_bands ) && EQ_16( nchan_transport_old, nchan_transport ) ) + { + Word16 new_param_band_idx, param_idx, source_param_idx; + Word16 num_param_lfe; + Word16 *p_icc_new_fx = hParamMC->icc_q_fx; // Q15 + Word16 *p_ild_new_fx = hParamMC->icld_q_fx; // Q8 + Word16 p_ild_new_e = 23; + move16(); + Word16 p_ild_new_tmp; + + /* ICC */ + num_param_lfe = hParamMC->hMetadataPMC->icc_mapping_conf->icc_map_size_lfe; + move16(); + FOR( new_param_band_idx = 0; new_param_band_idx < hParamMC->hMetadataPMC->num_parameter_bands; new_param_band_idx++ ) + { + FOR( param_idx = 0; param_idx < num_param_lfe; param_idx++ ) + { + *p_icc_new_fx = 0; + move16(); + FOR( source_param_idx = 0; source_param_idx < parameter_band_mapping.n_source_bands[new_param_band_idx]; source_param_idx++ ) + { + *p_icc_new_fx = add( *p_icc_new_fx, mult( icc_q_old_fx[parameter_band_mapping.source_band_idx[new_param_band_idx][source_param_idx] * num_param_lfe + param_idx], parameter_band_mapping.source_band_factor_fx[new_param_band_idx][source_param_idx] ) ); /*Q15*/ + move16(); + } + p_icc_new_fx++; + } + } + + /* ILD */ + num_param_lfe = hParamMC->hMetadataPMC->ild_mapping_conf->ild_map_size_lfe; + move16(); + FOR( new_param_band_idx = 0; new_param_band_idx < hParamMC->hMetadataPMC->num_parameter_bands; new_param_band_idx++ ) + { + FOR( param_idx = 0; param_idx < num_param_lfe; param_idx++ ) + { + *p_ild_new_fx = 0; + move16(); + FOR( source_param_idx = 0; source_param_idx < parameter_band_mapping.n_source_bands[new_param_band_idx]; source_param_idx++ ) + { + p_ild_new_tmp = extract_h( BASOP_util_Pow2( L_mult0( 10885 /*log2(10)/10*2^15*/, ild_q_old_fx[parameter_band_mapping.source_band_idx[new_param_band_idx][source_param_idx] * num_param_lfe + param_idx] ), 8, &p_ild_new_e ) ); // 31 - p_ild_new_e - 16 + *p_ild_new_fx = add( *p_ild_new_fx, mult( p_ild_new_tmp, parameter_band_mapping.source_band_factor_fx[new_param_band_idx][source_param_idx] ) ); + move16(); + } + *p_ild_new_fx = extract_l( L_shr( Mpy_32_16_1( L_add( BASOP_Util_Log2( *p_ild_new_fx ), L_add( 16 << Q25, L_shl( p_ild_new_e, 25 ) ) ), 24660 /*3.Q13*/ ), 15 ) ); // Q8 + move16(); + p_ild_new_fx++; + } + } + } + free( ild_q_old_fx ); + free( icc_q_old_fx ); + } + + param_mc_set_num_synth_bands( output_Fs, hParamMC ); + + /* set max parameter band for abs cov */ + k = 0; + move16(); + WHILE( LE_16( hParamMC->band_grouping[k], PARAM_MC_MAX_BAND_ABS_COV_DEC ) ) + { + hParamMC->max_param_band_abs_cov = k; + move16(); + k = add( k, 1 ); + } + + /*-----------------------------------------------------------------* + * open sub-modules + *-----------------------------------------------------------------*/ + + /* prototype signal computation */ + + IF( EQ_16( hParamMC->synthesis_conf, PARAM_MC_SYNTH_MONO_STEREO ) ) + { + IF( NE_16( nchan_transport_old, nchan_transport ) ) + { + IF( st_ivas->hLsSetUpConversion != NULL ) + { + ivas_ls_setup_conversion_close_fx( &st_ivas->hLsSetUpConversion ); + } + + IF( NE_32( ( error = ivas_ls_setup_conversion_open_fx( st_ivas ) ), IVAS_ERR_OK ) ) + { + return error; + } + + /* convert the ls conv dmx matrix into column order matrix format (nchan_out_cldfb x nchan_out) */ + free( hParamMC->ls_conv_dmx_matrix_fx ); + + IF( ( hParamMC->ls_conv_dmx_matrix_fx = (Word32 *) malloc( nchan_out_transport * nchan_out_cov * sizeof( Word32 ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Parametric MC\n" ) ); + } + FOR( k = 0; k < nchan_out_transport; k++ ) + { + Copy32( st_ivas->hLsSetUpConversion->dmxMtx_fx[k], &hParamMC->ls_conv_dmx_matrix_fx[k * nchan_out_cov], nchan_out_cov ); + } + } + /* convert ParamMC parameter bands to SFB */ + + st_ivas->hLsSetUpConversion->sfbCnt = hParamMC->num_param_bands_synth; + move16(); + FOR( k = 0; k <= hParamMC->num_param_bands_synth; k++ ) + { + st_ivas->hLsSetUpConversion->sfbOffset[k] = imult1616( PARAM_MC_BAND_TO_MDCT_BAND_RATIO, hParamMC->band_grouping[k] ); + move16(); + } + FOR( ; k < MAX_SFB + 2; k++ ) + { + st_ivas->hLsSetUpConversion->sfbOffset[k] = 0; + move16(); + } + } + + IF( NE_16( nchan_transport_old, nchan_transport ) ) + { + free( hParamMC->proto_matrix_int_fx ); + IF( ( hParamMC->proto_matrix_int_fx = (Word32 *) malloc( nchan_out_transport * nchan_transport * sizeof( Word32 ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Parametric MC\n" ) ); + } + hParamMC->proto_matrix_int_len = imult1616( nchan_out_transport, nchan_transport ); + move16(); + Copy32( ivas_param_mc_conf[config_index].dmx_fac_fx, hParamMC->proto_matrix_int_fx, hParamMC->proto_matrix_int_len ); /*Q31*/ + } + + test(); + IF( EQ_16( hParamMC->synthesis_conf, PARAM_MC_SYNTH_LS_CONV_COV ) || EQ_16( hParamMC->synthesis_conf, PARAM_MC_SYNTH_MONO_STEREO ) ) + { + Scale_sig32( hParamMC->ls_conv_dmx_matrix_fx, imult1616( nchan_out_transport, nchan_out_cov ), -4 ); // Q30 -> Q26 + matrix_product_fx( hParamMC->ls_conv_dmx_matrix_fx, nchan_out_cov, nchan_out_transport, 0, + ivas_param_mc_conf[config_index].dmx_fac_fx, nchan_out_transport, nchan_transport, 0, + proto_matrix_fx /*Q26*/ ); + Scale_sig32( hParamMC->ls_conv_dmx_matrix_fx, imult1616( nchan_out_transport, nchan_out_cov ), 4 ); // Q26 -> Q30 + + IF( EQ_16( hParamMC->synthesis_conf, PARAM_MC_SYNTH_MONO_STEREO ) ) + { + proto_mtx_norm_fx = ONE_IN_Q26; // Q26 + move32(); + FOR( k = 0; k < nchan_transport * nchan_out_cov; k++ ) + { + proto_mtx_norm_fx = L_max( L_abs( proto_mtx_norm_fx ), L_abs( proto_matrix_fx[k] ) ); // Q26 + } + proto_mtx_norm_fx = divide3232( ONE_IN_Q26, proto_mtx_norm_fx ); /*Q15*/ + + /* transfer flattened proto_matrix to 2D in hLsSetupConversion->dmxMtx */ + FOR( k = 0; k < nchan_transport; k++ ) + { + FOR( Word16 i = 0; i < nchan_out_cov; i++ ) + { + st_ivas->hLsSetUpConversion->dmxMtx_fx[k][i] = L_shl( Mpy_32_16_1( proto_matrix_fx[k * nchan_out_cov + i], (Word16) proto_mtx_norm_fx ), 4 ); // Q26 -> Q30 + move32(); + } + } + } + } + ELSE + { + Copy32( ivas_param_mc_conf[config_index].dmx_fac_fx, proto_matrix_fx, imult1616( nchan_out_transport, nchan_transport ) ); // proto_matrix_fx -> Q31 + Scale_sig32( proto_matrix_fx, imult1616( nchan_out_transport, nchan_transport ), -5 ); // proto_matrix_fx -> Q26 + } + + test(); + IF( NE_16( nchan_transport_old, nchan_transport ) && NE_16( hParamMC->synthesis_conf, PARAM_MC_SYNTH_MONO_STEREO ) ) + { + Word16 i; + Word16 len; + + /* close decorrelator */ + ivas_dirac_dec_decorr_close_fx( &hParamMC->h_freq_domain_decorr_ap_params, &hParamMC->h_freq_domain_decorr_ap_state ); + + /* deallocate diffuse prototype info */ + IF( hParamMC->diff_proto_info ) + { + FOR( i = 0; i < hParamMC->diff_proto_info->num_protos_diff; i++ ) + { + free( hParamMC->diff_proto_info->source_chan_idx[i] ); + hParamMC->diff_proto_info->source_chan_idx[i] = NULL; + + free( hParamMC->diff_proto_info->proto_fac_fx[i] ); + hParamMC->diff_proto_info->proto_fac_fx[i] = NULL; + } + + free( hParamMC->diff_proto_info->source_chan_idx ); + hParamMC->diff_proto_info->source_chan_idx = NULL; + + free( hParamMC->diff_proto_info->proto_fac_fx ); + hParamMC->diff_proto_info->proto_fac_fx = NULL; + + free( hParamMC->diff_proto_info->proto_index_diff ); + hParamMC->diff_proto_info->proto_index_diff = NULL; + + free( hParamMC->diff_proto_info->num_source_chan_diff ); + hParamMC->diff_proto_info->num_source_chan_diff = NULL; + + free( hParamMC->diff_proto_info ); + hParamMC->diff_proto_info = NULL; + } + + hParamMC->num_outputs_diff = nchan_out_cov; + move16(); + IF( ( hParamMC->diff_proto_info = (PARAM_MC_DIFF_PROTO_INFO *) malloc( sizeof( PARAM_MC_DIFF_PROTO_INFO ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Parametric MC\n" ) ); + } + IF( ( param_mc_get_diff_proto_info_fx( proto_matrix_fx, nchan_transport, nchan_out_cov, hParamMC->diff_proto_info, Q26 ) ) != IVAS_ERR_OK ) + { + return error; + } + + /* decorrelation */ + hParamMC->h_freq_domain_decorr_ap_params = NULL; + hParamMC->h_freq_domain_decorr_ap_state = NULL; + + Word16 frequency_axis_fx[CLDFB_NO_CHANNELS_MAX]; + ivas_dirac_dec_get_frequency_axis_fx( frequency_axis_fx, output_Fs, hParamMC->num_freq_bands ); // Q0 + + IF( NE_32( ( error = ivas_dirac_dec_decorr_open_fx( &( hParamMC->h_freq_domain_decorr_ap_params ), &( hParamMC->h_freq_domain_decorr_ap_state ), hParamMC->num_freq_bands, hParamMC->num_outputs_diff, + hParamMC->diff_proto_info->num_protos_diff, DIRAC_SYNTHESIS_COV_MC_LS, frequency_axis_fx, nchan_transport, output_Fs ) ), + IVAS_ERR_OK ) ) + { + return error; + } + hParamMC->h_output_synthesis_params.use_onset_filters = 0; + move16(); + hParamMC->max_band_decorr = hParamMC->h_freq_domain_decorr_ap_params->max_band_decorr; + move16(); + /* init decorrelation */ + IF( hParamMC->max_band_decorr > 0 ) + { + + len = imult1616( hParamMC->diff_proto_info->num_protos_diff, hParamMC->h_freq_domain_decorr_ap_params->h_onset_detection_power_params.max_band_decorr ); + + /* init onsetDetectionPower */ + set_zero_fx( hParamMC->h_freq_domain_decorr_ap_state->h_onset_detection_power_state.onset_detector_1_fx, len ); + set_zero_fx( hParamMC->h_freq_domain_decorr_ap_state->h_onset_detection_power_state.onset_detector_2_fx, len ); + hParamMC->h_freq_domain_decorr_ap_state->h_onset_detection_power_state.q_onset_detector = Q31; + move16(); + } + } + hParamMC->max_band_energy_compensation = hParamMC->band_grouping[hParamMC->hMetadataPMC->nbands_coded]; + move16(); + max_param_band_residual = 0; + move16(); + + FOR( k = hParamMC->hMetadataPMC->num_parameter_bands; k >= 0; k-- ) + { + IF( LE_16( hParamMC->band_grouping[k], hParamMC->max_band_decorr ) ) + { + max_param_band_residual = k; + move16(); + assert( hParamMC->band_grouping[k] == hParamMC->max_band_decorr ); + BREAK; + } + } + + test(); + IF( NE_16( nchan_transport_old, nchan_transport ) || NE_16( num_param_bands_old, hParamMC->hMetadataPMC->num_parameter_bands ) ) + { + DIRAC_OUTPUT_SYNTHESIS_COV_STATE cov_state_old = hParamMC->h_output_synthesis_cov_state; + DIRAC_OUTPUT_SYNTHESIS_PARAMS params_old = hParamMC->h_output_synthesis_params; + + Word32 tmp_buf_fx[MAX_CICP_CHANNELS * MAX_CICP_CHANNELS]; + + set_zero_fx( tmp_buf_fx, MAX_CICP_CHANNELS * MAX_CICP_CHANNELS ); + + /* output synthesis */ + IF( NE_32( ( error = ivas_dirac_dec_output_synthesis_cov_open_fx( &( hParamMC->h_output_synthesis_params ), &( hParamMC->h_output_synthesis_cov_state ), hParamMC->max_band_decorr, PARAM_MC_MAX_NSLOTS, + hParamMC->hMetadataPMC->num_parameter_bands, max_param_band_residual, nchan_transport, nchan_out_cov, proto_matrix_fx ) ), + IVAS_ERR_OK ) ) + { + return error; + } + + ivas_param_mc_dec_compute_interpolator_fx( 0, 0, DEFAULT_JBM_CLDFB_TIMESLOTS, hParamMC->h_output_synthesis_params.interpolator_fx ); + + ivas_dirac_dec_output_synthesis_cov_init_fx( &( hParamMC->h_output_synthesis_cov_state ), nchan_transport, nchan_out_cov, hParamMC->hMetadataPMC->num_parameter_bands, max_param_band_residual ); + + /* map old to new parameter banding, only for same number of TCs, needs some more thought for changing number of TCs */ + test(); + IF( NE_16( num_param_bands_old, hParamMC->hMetadataPMC->num_parameter_bands ) && EQ_16( nchan_transport_old, nchan_transport ) ) + { + Word16 new_param_band_idx, source_param_idx; + + FOR( new_param_band_idx = 0; new_param_band_idx < hParamMC->hMetadataPMC->num_parameter_bands; new_param_band_idx++ ) + { + FOR( source_param_idx = 0; source_param_idx < parameter_band_mapping.n_source_bands[new_param_band_idx]; source_param_idx++ ) + { + /* Cx */ + v_multc_fixed_16( cov_state_old.cx_old_fx[parameter_band_mapping.source_band_idx[new_param_band_idx][source_param_idx]], parameter_band_mapping.source_band_factor_fx[new_param_band_idx][source_param_idx], tmp_buf_fx, imult1616( nchan_transport_old, nchan_transport_old ) ); // Q(31 - cov_state_old.cx_old_e) + v_add_fixed_me( tmp_buf_fx, cov_state_old.cx_old_e[parameter_band_mapping.source_band_idx[new_param_band_idx][source_param_idx]], hParamMC->h_output_synthesis_cov_state.cx_old_fx[new_param_band_idx], hParamMC->h_output_synthesis_cov_state.cx_old_e[new_param_band_idx], hParamMC->h_output_synthesis_cov_state.cx_old_fx[new_param_band_idx], &hParamMC->h_output_synthesis_cov_state.cx_old_e[new_param_band_idx], imult1616( nchan_transport_old, nchan_transport_old ), 0 ); // Q(31 - hParamMC->h_output_synthesis_cov_state.cx_old_e[new_param_band_idx]) + /* Cy */ + v_multc_fixed_16( cov_state_old.cy_old_fx[parameter_band_mapping.source_band_idx[new_param_band_idx][source_param_idx]], parameter_band_mapping.source_band_factor_fx[new_param_band_idx][source_param_idx], tmp_buf_fx, imult1616( nchan_out_cov, nchan_out_cov ) ); // Q(31 - cov_state_old.cy_old_e) + v_add_fixed_me( tmp_buf_fx, cov_state_old.cy_old_e[parameter_band_mapping.source_band_idx[new_param_band_idx][source_param_idx]], hParamMC->h_output_synthesis_cov_state.cy_old_fx[new_param_band_idx], hParamMC->h_output_synthesis_cov_state.cy_old_e[new_param_band_idx], hParamMC->h_output_synthesis_cov_state.cy_old_fx[new_param_band_idx], &hParamMC->h_output_synthesis_cov_state.cy_old_e[new_param_band_idx], imult1616( nchan_out_cov, nchan_out_cov ), 0 ); // Q(31 - hParamMC->h_output_synthesis_cov_state.cy_old_e[new_param_band_idx]) + /* mixing matrix*/ + v_multc_fixed_16( cov_state_old.mixing_matrix_old_fx[parameter_band_mapping.source_band_idx[new_param_band_idx][source_param_idx]], parameter_band_mapping.source_band_factor_fx[new_param_band_idx][source_param_idx], tmp_buf_fx, imult1616( nchan_transport_old, nchan_out_cov ) ); // Q(31 - mixing_matrix_old_exp) + v_add_fixed_me( tmp_buf_fx, cov_state_old.mixing_matrix_old_exp[parameter_band_mapping.source_band_idx[new_param_band_idx][source_param_idx]], hParamMC->h_output_synthesis_cov_state.mixing_matrix_old_fx[new_param_band_idx], hParamMC->h_output_synthesis_cov_state.mixing_matrix_old_exp[new_param_band_idx], hParamMC->h_output_synthesis_cov_state.mixing_matrix_old_fx[new_param_band_idx], &hParamMC->h_output_synthesis_cov_state.mixing_matrix_old_exp[new_param_band_idx], imult1616( nchan_transport_old, nchan_out_cov ), 0 ); // Q(31 - hParamMC->h_output_synthesis_cov_state.mixing_matrix_old_exp[new_param_band_idx]) + } + } + FOR( new_param_band_idx = 0; new_param_band_idx < max_param_band_residual; new_param_band_idx++ ) + { + FOR( source_param_idx = 0; source_param_idx < parameter_band_mapping.n_source_bands[new_param_band_idx]; source_param_idx++ ) + { + /* residual mixing matrix*/ + v_multc_fixed_16( cov_state_old.mixing_matrix_res_old_fx[parameter_band_mapping.source_band_idx[new_param_band_idx][source_param_idx]], parameter_band_mapping.source_band_factor_fx[new_param_band_idx][source_param_idx], tmp_buf_fx, imult1616( nchan_out_cov, nchan_out_cov ) ); // Q(31 - mixing_matrix_res_old_exp) + v_add_fixed_me( tmp_buf_fx, cov_state_old.mixing_matrix_res_old_exp[parameter_band_mapping.source_band_idx[new_param_band_idx][source_param_idx]], hParamMC->h_output_synthesis_cov_state.mixing_matrix_res_old_fx[new_param_band_idx], hParamMC->h_output_synthesis_cov_state.mixing_matrix_res_old_exp[new_param_band_idx], hParamMC->h_output_synthesis_cov_state.mixing_matrix_res_old_fx[new_param_band_idx], &hParamMC->h_output_synthesis_cov_state.mixing_matrix_res_old_exp[new_param_band_idx], imult1616( nchan_out_cov, nchan_out_cov ), 0 ); // Q(hParamMC->h_output_synthesis_cov_state.mixing_matrix_res_old_exp[new_param_band_idx]) + } + } + } + ivas_dirac_dec_output_synthesis_cov_close_fx( ¶ms_old, &cov_state_old ); + } + + /*-----------------------------------------------------------------* + * memory allocation + *-----------------------------------------------------------------*/ + + test(); + IF( ( hParamMC->max_band_decorr > 0 ) && NE_16( nchan_transport_old, nchan_transport ) ) + { + free( hParamMC->proto_frame_f_fx ); + IF( ( hParamMC->proto_frame_f_fx = (Word32 *) malloc( 2 * hParamMC->diff_proto_info->num_protos_diff * hParamMC->num_freq_bands * sizeof( Word32 ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Parametric MC\n" ) ); + } + set_zero_fx( hParamMC->proto_frame_f_fx, shl( imult1616( hParamMC->diff_proto_info->num_protos_diff, hParamMC->num_freq_bands ), 1 ) ); + } + + + IF( NE_16( nchan_transport_old, nchan_transport ) ) + { + IF( NE_16( hParamMC->synthesis_conf, PARAM_MC_SYNTH_MONO_STEREO ) ) + { + Word16 n_cldfb_slots; + IF( hParamMC->Cldfb_RealBuffer_tc_fx != NULL ) + { + free( hParamMC->Cldfb_RealBuffer_tc_fx ); + hParamMC->Cldfb_RealBuffer_tc_fx = NULL; // Q12 + } + IF( hParamMC->Cldfb_ImagBuffer_tc_fx != NULL ) + { + free( hParamMC->Cldfb_ImagBuffer_tc_fx ); + hParamMC->Cldfb_ImagBuffer_tc_fx = NULL; // Q12 + } + + n_cldfb_slots = DEFAULT_JBM_CLDFB_TIMESLOTS; + move16(); + IF( st_ivas->hDecoderConfig->Opt_tsm ) + { + n_cldfb_slots = MAX_JBM_CLDFB_TIMESLOTS; + move16(); + } + Word16 cldfb_size = imult1616( imult1616( n_cldfb_slots, nchan_transport ), hParamMC->num_freq_bands ); + IF( ( hParamMC->Cldfb_RealBuffer_tc_fx = (Word32 *) malloc( cldfb_size * sizeof( Word32 ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Parametric MC JBM\n" ) ); + } + set_zero_fx( hParamMC->Cldfb_RealBuffer_tc_fx, cldfb_size ); + + IF( ( hParamMC->Cldfb_ImagBuffer_tc_fx = (Word32 *) malloc( cldfb_size * sizeof( Word32 ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Parametric MC JBM\n" ) ); + } + set_zero_fx( hParamMC->Cldfb_ImagBuffer_tc_fx, cldfb_size ); + } + ELSE + { + IF( hParamMC->Cldfb_RealBuffer_tc_fx != NULL ) + { + free( hParamMC->Cldfb_RealBuffer_tc_fx ); + hParamMC->Cldfb_RealBuffer_tc_fx = NULL; + } + IF( hParamMC->Cldfb_ImagBuffer_tc_fx != NULL ) + { + free( hParamMC->Cldfb_ImagBuffer_tc_fx ); + hParamMC->Cldfb_ImagBuffer_tc_fx = NULL; + } + } + } + return error; +} + + +/*------------------------------------------------------------------------- + * param_mc_get_num_cldfb_syntheses() + * + * calculate the necessary number of CLDFB synthesis instances + *------------------------------------------------------------------------*/ + +/*! r: number of cldfb synthesis instances */ +Word16 param_mc_get_num_cldfb_syntheses_fx( + Decoder_Struct *st_ivas /* i : Parametric MC handle */ +) +{ + Word16 num_cldfb_syntheses; + + num_cldfb_syntheses = 0; + move16(); + + /* sanity check*/ + IF( st_ivas->hParamMC == NULL ) + { + assert( 0 && "ParamMC handle does not exist!\n" ); + } + + test(); + IF( EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_FASTCONV ) || EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_FASTCONV_ROOM ) ) + { + num_cldfb_syntheses = 2; + move16(); + } + ELSE IF( EQ_32( st_ivas->renderer_type, RENDERER_SBA_LINEAR_ENC ) ) + { + num_cldfb_syntheses = add( st_ivas->hTransSetup.nchan_out_woLFE, st_ivas->hTransSetup.num_lfe ); + } + ELSE IF( EQ_32( st_ivas->renderer_type, RENDERER_MC_PARAMMC ) ) + { + num_cldfb_syntheses = add( st_ivas->hOutSetup.nchan_out_woLFE, st_ivas->hOutSetup.num_lfe ); + } + + return num_cldfb_syntheses; +} + + +/*------------------------------------------------------------------------- + * ivas_param_mc_dec_close() + * + * Close Parametric MC memories + *------------------------------------------------------------------------*/ + +void ivas_param_mc_dec_close_fx( + PARAM_MC_DEC_HANDLE *hParamMC_out /* i/o: Parametric MC decoder handle */ +) +{ + UWord16 i; + PARAM_MC_DEC_HANDLE hParamMC; + + IF( hParamMC_out == NULL || *hParamMC_out == NULL ) + { + return; + } + + hParamMC = *hParamMC_out; + + /* close sub-modules */ + ivas_dirac_dec_output_synthesis_cov_close_fx( &hParamMC->h_output_synthesis_params, &hParamMC->h_output_synthesis_cov_state ); + + IF( hParamMC->h_freq_domain_decorr_ap_params != NULL || hParamMC->h_freq_domain_decorr_ap_state != NULL ) + { + ivas_dirac_dec_decorr_close_fx( &hParamMC->h_freq_domain_decorr_ap_params, &hParamMC->h_freq_domain_decorr_ap_state ); + } + + /* parameter decoding */ + IF( hParamMC->hMetadataPMC != NULL ) + { + free( hParamMC->hMetadataPMC ); + hParamMC->hMetadataPMC = NULL; + } + IF( hParamMC->icc_q_fx != NULL ) + { + free( hParamMC->icc_q_fx ); + hParamMC->icc_q_fx = NULL; // Q15 + } + + IF( hParamMC->icld_q_fx != NULL ) + { + free( hParamMC->icld_q_fx ); + hParamMC->icld_q_fx = NULL; // Q8 + } + /* diffuse prototype info */ + IF( hParamMC->diff_proto_info ) + { + FOR( i = 0; i < hParamMC->diff_proto_info->num_protos_diff; i++ ) + { + free( hParamMC->diff_proto_info->source_chan_idx[i] ); + hParamMC->diff_proto_info->source_chan_idx[i] = NULL; + + free( hParamMC->diff_proto_info->proto_fac_fx[i] ); + hParamMC->diff_proto_info->proto_fac_fx[i] = NULL; + } + + free( hParamMC->diff_proto_info->source_chan_idx ); + hParamMC->diff_proto_info->source_chan_idx = NULL; + + free( hParamMC->diff_proto_info->proto_fac_fx ); + hParamMC->diff_proto_info->proto_fac_fx = NULL; + + free( hParamMC->diff_proto_info->proto_index_diff ); + hParamMC->diff_proto_info->proto_index_diff = NULL; + + free( hParamMC->diff_proto_info->num_source_chan_diff ); + hParamMC->diff_proto_info->num_source_chan_diff = NULL; + + free( hParamMC->diff_proto_info ); + hParamMC->diff_proto_info = NULL; + } + /* States */ + /* free prototype signal buffers */ + IF( hParamMC->proto_frame_f_fx != NULL ) + { + free( hParamMC->proto_frame_f_fx ); + hParamMC->proto_frame_f_fx = NULL; + } + + IF( hParamMC->proto_frame_dec_f_fx != NULL ) + { + free( hParamMC->proto_frame_dec_f_fx ); + hParamMC->proto_frame_dec_f_fx = NULL; + } + + IF( hParamMC->ls_conv_dmx_matrix_fx != NULL ) + { + free( hParamMC->ls_conv_dmx_matrix_fx ); + hParamMC->ls_conv_dmx_matrix_fx = NULL; + } + + IF( hParamMC->proto_matrix_int_fx != NULL ) + { + free( hParamMC->proto_matrix_int_fx ); + hParamMC->proto_matrix_int_fx = NULL; + } + + IF( hParamMC->hoa_encoder_fx != NULL ) + { + free( hParamMC->hoa_encoder_fx ); + hParamMC->hoa_encoder_fx = NULL; + } + IF( hParamMC->Cldfb_RealBuffer_tc_fx != NULL ) + { + free( hParamMC->Cldfb_RealBuffer_tc_fx ); + hParamMC->Cldfb_RealBuffer_tc_fx = NULL; + } + IF( hParamMC->Cldfb_ImagBuffer_tc_fx != NULL ) + { + free( hParamMC->Cldfb_ImagBuffer_tc_fx ); + hParamMC->Cldfb_ImagBuffer_tc_fx = NULL; + } + + free( *hParamMC_out ); + *hParamMC_out = NULL; + + return; +} + + +/*------------------------------------------------------------------------- + * ivas_param_mc_dec_read_BS() + * + * Read the Parametric MC metadata + *------------------------------------------------------------------------*/ + +void ivas_param_mc_dec_read_BS_fx( + const Word32 ivas_total_brate, /* i : IVAS total bitrate */ + Decoder_State *st, /* i/o: decoder state structure */ + PARAM_MC_DEC_HANDLE hParamMC, /* i/o: decoder ParamMC handle */ + Word16 *nb_bits /* o : number of bits written */ +) +{ + Word16 param_frame_idx; + Word16 band_step; + UWord16 bit_buffer[PARAM_MC_MAX_BITS]; + Word16 bits_to_copy; + Word16 bit_pos; + Word16 num_lfe_bands; + Word16 num_param_bands; + Word16 metadata_bit_pos; + Word16 i, j, k; + Word16 icc_map_size; + Word16 icc_map_size_wo_lfe; + Word16 ild_map_size; + Word16 ild_map_size_wo_lfe; + HANDLE_IVAS_PARAM_MC_METADATA hMetadataPMC; + + push_wmops( "param_mc_read_bs" ); + + /* Inits */ + *nb_bits = 0; + move16(); + hMetadataPMC = hParamMC->hMetadataPMC; + icc_map_size = hMetadataPMC->icc_mapping_conf->icc_map_size_lfe; + move16(); + icc_map_size_wo_lfe = hMetadataPMC->icc_mapping_conf->icc_map_size_wo_lfe; + move16(); + ild_map_size = hMetadataPMC->ild_mapping_conf->ild_map_size_lfe; + move16(); + ild_map_size_wo_lfe = hMetadataPMC->ild_mapping_conf->ild_map_size_wo_lfe; + move16(); + + IF( !st->bfi ) + { + /*metadata_bit_pos = extract_l(ivas_total_brate / FRAMES_PER_SEC - 1); + bits_to_copy = s_min(extract_l(ivas_total_brate / FRAMES_PER_SEC), PARAM_MC_MAX_BITS);*/ + Word16 temp = extract_l( Mpy_32_32_r( ivas_total_brate, ONE_BY_FRAMES_PER_SEC_Q31 ) ); + metadata_bit_pos = sub( temp, 1 ); + bits_to_copy = s_min( temp, PARAM_MC_MAX_BITS ); + + /* copy and reverse metadata */ + FOR( bit_pos = 0; bit_pos < bits_to_copy; bit_pos++ ) + { + bit_buffer[bit_pos] = st->bit_stream[metadata_bit_pos]; + move16(); + metadata_bit_pos = sub( metadata_bit_pos, 1 ); + move16(); + } + + bit_pos = 0; + move16(); + + /* read reserved bit */ + hMetadataPMC->lfe_on = bit_buffer[bit_pos++]; + move16(); + + /* get coded bwidth */ + { + Word16 pos; + Word16 bw = 0; + move16(); + FOR( pos = 0; pos < 2; pos++ ) + { + bw = add( bw, extract_l( L_shl( bit_buffer[bit_pos++], pos ) ) ); + } + hMetadataPMC->coded_bwidth = bw; + move16(); + } + + /* set tables if coded band width differs from last frame */ + IF( NE_16( hMetadataPMC->coded_bwidth, hMetadataPMC->last_coded_bwidth ) ) + { + ivas_param_mc_set_coded_bands_fx( hMetadataPMC ); + param_mc_set_num_synth_bands( st->output_Fs, hParamMC ); + hParamMC->max_band_energy_compensation = hParamMC->band_grouping[hParamMC->num_param_bands_synth]; + move16(); + } + + param_frame_idx = bit_buffer[bit_pos++]; + move16(); + hMetadataPMC->param_frame_idx = param_frame_idx; + move16(); + num_param_bands = hMetadataPMC->nbands_in_param_frame[param_frame_idx]; + move16(); + + hMetadataPMC->bAttackPresent = bit_buffer[bit_pos++]; + move16(); + hMetadataPMC->attackIndex = 0; + move16(); + band_step = 1; + move16(); + num_lfe_bands = 0; + move16(); + + IF( hMetadataPMC->bAttackPresent ) + { + FOR( i = 2; i >= 0; i-- ) + { + hMetadataPMC->attackIndex = add( hMetadataPMC->attackIndex, extract_l( L_shl( bit_buffer[bit_pos++], i ) ) ); + } + + band_step = PARAM_MC_TRANSIENT_BAND_STEP; + move16(); + + /*num_lfe_bands = add(PARAM_MC_MAX_BAND_LFE / band_step, (PARAM_MC_MAX_BAND_LFE % band_step) ? 1 : 0); + num_param_bands = add(hMetadataPMC->nbands_coded / band_step, ((hMetadataPMC->nbands_coded % band_step) ? 1 : 0));*/ + Word16 temp_e; + temp = BASOP_Util_Divide3232_Scale( PARAM_MC_MAX_BAND_LFE, band_step, &temp_e ); + temp = shr( temp, sub( 15, temp_e ) ); + Word16 temp1; + IF( PARAM_MC_MAX_BAND_LFE % band_step ) + { + temp1 = 1; + } + ELSE + { + temp1 = 0; + } + move16(); + num_lfe_bands = add( temp, temp1 ); + + temp = BASOP_Util_Divide3232_Scale( hMetadataPMC->nbands_coded, band_step, &temp_e ); + temp = shr( temp, sub( 15, temp_e ) ); + Word16 temp2; + IF( hMetadataPMC->nbands_coded % band_step ) + { + temp2 = 1; + } + ELSE + { + temp2 = 0; + } + move16(); + num_param_bands = add( temp, temp2 ); + } + ELSE + { + FOR( j = 0; j < PARAM_MC_MAX_BAND_LFE; j += band_step ) + { + IF( EQ_16( param_frame_idx, hMetadataPMC->coding_band_mapping[j] ) ) + { + /* LFE ICC is always the last ICC in coding band 0 */ + num_lfe_bands = add( num_lfe_bands, 1 ); + move16(); + } + } + } + + IF( !hMetadataPMC->lfe_on ) + { + num_lfe_bands = 0; + move16(); + } + + ivas_param_mc_bs_decode_parameter_values_fx( bit_buffer, &bit_pos, bits_to_copy, &st->BER_detect, hMetadataPMC, &hMetadataPMC->icc_coding, + icc_map_size_wo_lfe, icc_map_size, num_lfe_bands, band_step, num_param_bands, hParamMC->icc_q_fx ); + + IF( !st->BER_detect ) + { + ivas_param_mc_bs_decode_parameter_values_fx( bit_buffer, &bit_pos, bits_to_copy, &st->BER_detect, hMetadataPMC, &hMetadataPMC->ild_coding, + ild_map_size_wo_lfe, ild_map_size, num_lfe_bands, band_step, num_param_bands, hParamMC->icld_q_fx ); + } + /* set LFE ILD and ICC to zero above PARAM_MC_MAX_BAND_LFE for attack frames */ + IF( hMetadataPMC->bAttackPresent ) + { + FOR( k = PARAM_MC_MAX_BAND_LFE; k < imult1616( band_step, num_lfe_bands ); k++ ) + { + hParamMC->icc_q_fx[L_sub( L_mult0( add( k, 1 ), icc_map_size ), 1 )] = 32767; /* 1.0f in Q15 */ + move16(); + hParamMC->icld_q_fx[L_sub( L_mult0( add( k, 1 ), ild_map_size ), 1 )] = PARAM_MC_DEFAULT_MIN_ILD_FX; /* -92.0f in Q8 */ + move16(); + } + } + + *nb_bits = bit_pos; + move16(); + + } /* if ( !st->bfi ) */ + + IF( st->bfi ) + { + /* for PLC, use the saved ILDs and ICCs from the past and set the transient flag and transient position to zero */ + hMetadataPMC->bAttackPresent = 0; + move16(); + hMetadataPMC->attackIndex = 0; + move16(); + } + + pop_wmops(); + + return; +} + + +/*------------------------------------------------------------------------- + * ivas_param_mc_dec_digest_tc() + * + * + *------------------------------------------------------------------------*/ + +void ivas_param_mc_dec_digest_tc_fx( + Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */ + const UWord8 nCldfbSlots, /* i : number of CLFBS slots in the transport channels */ + Word32 *transport_channels_f_fx[], + Word16 transport_f_e ) +{ + PARAM_MC_DEC_HANDLE hParamMC; + Word16 i, ch; + Word16 is_next_band, skip_next_band; + Word16 slot_idx, param_band_idx; + Word16 nchan_transport, nchan_out_transport, nchan_out_cldfb; + Word16 nchan_out_cov; + /*CLDFB*/ + /* format converter */ + Word16 channel_active[MAX_OUTPUT_CHANNELS]; + IVAS_OUTPUT_SETUP *hSynthesisOutputSetup; + + hParamMC = st_ivas->hParamMC; + assert( hParamMC ); + Word32 *pCx, *pCx_imag; + Word32 cx_fx[PARAM_MC_MAX_TRANSPORT_CHANS * PARAM_MC_MAX_TRANSPORT_CHANS]; // Q(31 - cx_e) + Word32 cx_imag_fx[PARAM_MC_MAX_TRANSPORT_CHANS * PARAM_MC_MAX_TRANSPORT_CHANS]; // Q(31 - cx_imag_e) + Word32 cx_next_band_fx[PARAM_MC_MAX_TRANSPORT_CHANS * PARAM_MC_MAX_TRANSPORT_CHANS]; // Q(31 - cx_next_band_e) + Word32 cx_imag_next_band_fx[PARAM_MC_MAX_TRANSPORT_CHANS * PARAM_MC_MAX_TRANSPORT_CHANS]; // Q(31 - cx_imag_next_band_e) + + Word16 cx_buff_e[2][PARAM_MC_MAX_TRANSPORT_CHANS * PARAM_MC_MAX_TRANSPORT_CHANS]; + Word16 cx_e; + Word16 cx_imag_e, tmp_e; + Word16 cx_imag_next_band_e, cx_next_band_e; + Word16 qout = 0; + move16(); + + Word32 real_part_fx, imag_part_fx, L_tmp1, L_tmp2; + + Word16 max_e; + + push_wmops( "param_mc_dec_digest_tc" ); + + set16_fx( channel_active, 0, MAX_CICP_CHANNELS ); + nchan_transport = st_ivas->nchan_transport; + move16(); + nchan_out_transport = add( st_ivas->hTransSetup.nchan_out_woLFE, st_ivas->hTransSetup.num_lfe ); + + test(); + test(); + IF( EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_FASTCONV ) || EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_FASTCONV_ROOM ) ) + { + nchan_out_cldfb = BINAURAL_CHANNELS; + move16(); + set16_fx( channel_active, 1, nchan_out_cldfb ); + nchan_out_cov = add( st_ivas->hTransSetup.nchan_out_woLFE, st_ivas->hTransSetup.num_lfe ); + hSynthesisOutputSetup = &st_ivas->hTransSetup; + } + ELSE IF( EQ_32( hParamMC->synthesis_conf, PARAM_MC_SYNTH_LS_CONV_CLDFB ) ) + { + nchan_out_cov = nchan_out_transport; + move16(); + nchan_out_cldfb = add( st_ivas->hOutSetup.nchan_out_woLFE, st_ivas->hOutSetup.num_lfe ); + hSynthesisOutputSetup = &st_ivas->hTransSetup; + } + ELSE IF( EQ_32( hParamMC->synthesis_conf, PARAM_MC_SYNTH_LS_CONV_COV ) || EQ_32( hParamMC->synthesis_conf, PARAM_MC_SYNTH_MONO_STEREO ) ) + { + nchan_out_cov = add( st_ivas->hOutSetup.nchan_out_woLFE, st_ivas->hOutSetup.num_lfe ); + nchan_out_cldfb = nchan_out_cov; + move16(); + set16_fx( channel_active, 1, nchan_out_cov ); + hSynthesisOutputSetup = &st_ivas->hOutSetup; + } + ELSE + { + nchan_out_cov = nchan_out_transport; + move16(); + nchan_out_cldfb = nchan_out_transport; + move16(); + set16_fx( channel_active, 1, nchan_out_cov ); + hSynthesisOutputSetup = &st_ivas->hTransSetup; + } + + /* adapt transient position */ + IF( hParamMC->hMetadataPMC->bAttackPresent ) + { + hParamMC->hMetadataPMC->attackIndex = s_max( 0, add( hParamMC->hMetadataPMC->attackIndex, shr( sub( nCldfbSlots, DEFAULT_JBM_CLDFB_TIMESLOTS ), 1 ) ) ); + move16(); + } + /* adapt subframes */ + hParamMC->num_slots = nCldfbSlots; + move16(); + hParamMC->slots_rendered = 0; + move16(); + hParamMC->subframes_rendered = 0; + move16(); + ivas_jbm_dec_get_adapted_subframes( nCldfbSlots, hParamMC->subframe_nbslots, &hParamMC->nb_subframes ); + st_ivas->hTcBuffer->nb_subframes = hParamMC->nb_subframes; + move16(); + Copy( hParamMC->subframe_nbslots, st_ivas->hTcBuffer->subframe_nbslots, hParamMC->nb_subframes ); + + ivas_param_mc_dec_compute_interpolator_fx( hParamMC->hMetadataPMC->bAttackPresent, hParamMC->hMetadataPMC->attackIndex, nCldfbSlots, hParamMC->h_output_synthesis_params.interpolator_fx ); + + /* loop over two bands at a time */ + FOR( param_band_idx = 0; param_band_idx < hParamMC->num_param_bands_synth; param_band_idx += 2 ) + { + /* don't process next band if it exceeds the limit */ + skip_next_band = ( ( param_band_idx + 1 ) == hParamMC->num_param_bands_synth ) ? 1 : 0; + + set_zero_fx( cx_fx, PARAM_MC_MAX_TRANSPORT_CHANS * PARAM_MC_MAX_TRANSPORT_CHANS ); + set_zero_fx( cx_imag_fx, PARAM_MC_MAX_TRANSPORT_CHANS * PARAM_MC_MAX_TRANSPORT_CHANS ); + set_zero_fx( cx_next_band_fx, PARAM_MC_MAX_TRANSPORT_CHANS * PARAM_MC_MAX_TRANSPORT_CHANS ); + set_zero_fx( cx_imag_next_band_fx, PARAM_MC_MAX_TRANSPORT_CHANS * PARAM_MC_MAX_TRANSPORT_CHANS ); + + cx_e = 0; + move16(); + cx_imag_e = 0; + move16(); + cx_next_band_e = 0; + move16(); + cx_imag_next_band_e = 0; + move16(); + /* slot loop for gathering the input data */ + FOR( slot_idx = 0; slot_idx < nCldfbSlots; slot_idx++ ) + { + IF( st_ivas->hDecoderConfig->Opt_tsm ) + { + IF( param_band_idx == 0 ) /* only run cldfbAna once */ + { + Word32 RealBuffer_fx[CLDFB_NO_CHANNELS_MAX]; + Word32 ImagBuffer_fx[CLDFB_NO_CHANNELS_MAX]; + + /* CLDFB Analysis*/ + FOR( ch = 0; ch < nchan_transport; ch++ ) + { + qout = transport_f_e; + move16(); + cldfbAnalysis_ts_fx_fixed_q( &( transport_channels_f_fx[ch][hParamMC->num_freq_bands * slot_idx] ), RealBuffer_fx, ImagBuffer_fx, hParamMC->num_freq_bands, st_ivas->cldfbAnaDec[ch], &qout ); + + Copy32( RealBuffer_fx, &hParamMC->Cldfb_RealBuffer_tc_fx[slot_idx * hParamMC->num_freq_bands * nchan_transport + ch * hParamMC->num_freq_bands], hParamMC->num_freq_bands ); + Copy32( ImagBuffer_fx, &hParamMC->Cldfb_ImagBuffer_tc_fx[slot_idx * hParamMC->num_freq_bands * nchan_transport + ch * hParamMC->num_freq_bands], hParamMC->num_freq_bands ); + } + + hParamMC->Cldfb_ImagBuffer_tc_e = qout; + move16(); + } + } + IF( GE_16( slot_idx, shl( hParamMC->hMetadataPMC->attackIndex, 1 ) ) ) + { + FOR( is_next_band = 0; is_next_band < 2; is_next_band++ ) + { + test(); + IF( is_next_band && skip_next_band ) + { + CONTINUE; + } + IF( is_next_band ) + { + ivas_dirac_dec_output_synthesis_cov_param_mc_collect_slot_fx( &hParamMC->Cldfb_RealBuffer_tc_fx[slot_idx * hParamMC->num_freq_bands * nchan_transport], + /*hParamMC->Cldfb_RealBuffer_tc_e*/ Q31 - Q6, + &hParamMC->Cldfb_ImagBuffer_tc_fx[slot_idx * hParamMC->num_freq_bands * nchan_transport], + /*hParamMC->Cldfb_ImagBuffer_tc_e*/ Q31 - Q6, + cx_next_band_fx, + &cx_next_band_e, + cx_imag_next_band_fx, + &cx_imag_next_band_e, + hParamMC, + add( param_band_idx, is_next_band ), + nchan_transport ); + } + ELSE + { + ivas_dirac_dec_output_synthesis_cov_param_mc_collect_slot_fx( &hParamMC->Cldfb_RealBuffer_tc_fx[slot_idx * hParamMC->num_freq_bands * nchan_transport], + /*hParamMC->Cldfb_RealBuffer_tc_e*/ Q31 - Q6, + &hParamMC->Cldfb_ImagBuffer_tc_fx[slot_idx * hParamMC->num_freq_bands * nchan_transport], + /*hParamMC->Cldfb_ImagBuffer_tc_e*/ Q31 - Q6, + cx_fx, + &cx_e, + cx_imag_fx, + &cx_imag_e, + hParamMC, + add( param_band_idx, is_next_band ), + nchan_transport ); + } + } + } + } + + Word16 tmp_cx_e, tmp_cx_imag_e; + /* map from complex input covariance to real values */ + FOR( is_next_band = 0; is_next_band < 2; is_next_band++ ) + { + test(); + IF( is_next_band && skip_next_band ) + { + CONTINUE; + } + /* Cx for transport channels */ + IF( is_next_band ) + { + pCx = &cx_next_band_fx[0]; + pCx_imag = &cx_imag_next_band_fx[0]; + tmp_cx_e = cx_next_band_e; + tmp_cx_imag_e = cx_imag_next_band_e; + } + ELSE + { + pCx = &cx_fx[0]; + pCx_imag = &cx_imag_fx[0]; + tmp_cx_e = cx_e; + tmp_cx_imag_e = cx_imag_e; + } + + FOR( i = 0; i < nchan_transport * nchan_transport; i++ ) + { + real_part_fx = pCx[i]; // Q(31 - cx_buff_e) + imag_part_fx = pCx_imag[i]; + move32(); + move32(); + cx_buff_e[is_next_band][i] = tmp_cx_e; + move16(); + /* (a-ib)(c+id) = ac + bd + i(ad-bc) */ + IF( LT_16( param_band_idx, hParamMC->max_param_band_abs_cov ) ) + { + L_tmp1 = Mpy_32_32( real_part_fx, real_part_fx ); + L_tmp2 = Mpy_32_32( imag_part_fx, imag_part_fx ); + L_tmp1 = BASOP_Util_Add_Mant32Exp( L_tmp1, add( tmp_cx_e, tmp_cx_e ), L_tmp2, add( tmp_cx_imag_e, tmp_cx_imag_e ), &tmp_e ); + pCx[i] = Sqrt32( L_tmp1, &tmp_e ); + move32(); + cx_buff_e[is_next_band][i] = tmp_e; + move16(); + } + ELSE + { + pCx[i] = real_part_fx; + move32(); + cx_buff_e[is_next_band][i] = tmp_cx_e; + move16(); + } + } + } + + max_e = cx_buff_e[0][0]; + move16(); + + /* Cx for transport channels */ + FOR( is_next_band = 0; is_next_band < 2; is_next_band++ ) + { + FOR( i = 0; i < imult1616( nchan_transport, nchan_transport ); i++ ) + { + + IF( LT_16( max_e, cx_buff_e[is_next_band][i] ) ) + { + max_e = cx_buff_e[is_next_band][i]; + } + } + } + /* Cx for transport channels */ + FOR( is_next_band = 0; is_next_band < 2; is_next_band++ ) + { + FOR( i = 0; i < imult1616( nchan_transport, nchan_transport ); i++ ) + { + if ( is_next_band == 0 ) + { + cx_fx[i] = L_shr( cx_fx[i], sub( max_e, cx_buff_e[is_next_band][i] ) ); + } + else + { + cx_next_band_fx[i] = L_shr( cx_next_band_fx[i], sub( max_e, cx_buff_e[is_next_band][i] ) ); + } + move32(); + } + } + cx_e = max_e; + move16(); + + + /* we have to do it similar to the encoder in case of attacks (i.e. accumulate two bands) to ensure correct DMX of the target covariance*/ + + test(); + test(); + IF( hParamMC->hMetadataPMC->bAttackPresent && ( EQ_32( hParamMC->synthesis_conf, PARAM_MC_SYNTH_LS_CONV_COV ) || EQ_32( hParamMC->synthesis_conf, PARAM_MC_SYNTH_MONO_STEREO ) ) ) + { + v_add_fx( cx_fx, cx_next_band_fx, cx_fx, imult1616( nchan_transport, nchan_transport ) ); + Copy32( cx_fx, cx_next_band_fx, imult1616( nchan_transport, nchan_transport ) ); + } + + FOR( is_next_band = 0; is_next_band < 2; is_next_band++ ) + { + test(); + IF( is_next_band && skip_next_band ) + { + CONTINUE; + } + + IF( NE_32( hParamMC->synthesis_conf, PARAM_MC_SYNTH_MONO_STEREO ) ) + { + IF( is_next_band ) + { + + ivas_param_mc_get_mixing_matrices_fx( hParamMC, hSynthesisOutputSetup, cx_next_band_fx, cx_e, add( param_band_idx, is_next_band ), hParamMC->h_output_synthesis_cov_state.mixing_matrix_fx, hParamMC->h_output_synthesis_cov_state.mixing_matrix_exp, hParamMC->h_output_synthesis_cov_state.mixing_matrix_res_fx, hParamMC->h_output_synthesis_cov_state.mixing_matrix_res_exp, nchan_out_transport, hParamMC->synthesis_conf, nchan_transport, nchan_out_cov ); + } + ELSE + { + + ivas_param_mc_get_mixing_matrices_fx( hParamMC, hSynthesisOutputSetup, cx_fx, cx_e, add( param_band_idx, is_next_band ), hParamMC->h_output_synthesis_cov_state.mixing_matrix_fx, hParamMC->h_output_synthesis_cov_state.mixing_matrix_exp, hParamMC->h_output_synthesis_cov_state.mixing_matrix_res_fx, hParamMC->h_output_synthesis_cov_state.mixing_matrix_res_exp, nchan_out_transport, hParamMC->synthesis_conf, nchan_transport, nchan_out_cov ); + } + } + } + } + pop_wmops(); + + return; +} + + +/*------------------------------------------------------------------------- + * ivas_param_mc_dec() + * + * Parametric MC decoding process + *------------------------------------------------------------------------*/ + +void ivas_param_mc_dec_render_fx( + Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */ + const UWord16 nSamplesAsked, /* i : number of CLDFB slots requested */ + UWord16 *nSamplesRendered, /* o : number of CLDFB slots rendered */ + UWord16 *nSamplesAvailableNext, /* o : number of CLDFB slots still to render */ + Word32 *output_f_fx[], /* o : rendered time signal Q11*/ + Word16 channel_active_fx[MAX_OUTPUT_CHANNELS] ) +{ + PARAM_MC_DEC_HANDLE hParamMC; + Word16 i, ch; + Word16 subframe_idx; + Word16 slot_idx, slot_idx_start, slot_idx_start_cldfb_synth, first_sf, last_sf, slots_to_render; + Word16 nchan_transport, nchan_out_transport, nchan_out_cldfb; + Word16 nchan_out_cov; + + /*CLDFB*/ + Word32 Cldfb_RealBuffer_fx[MAX_INTERN_CHANNELS][PARAM_MC_MAX_NSLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX]; + Word32 Cldfb_ImagBuffer_fx[MAX_INTERN_CHANNELS][PARAM_MC_MAX_NSLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX]; +#ifdef SPLIT_REND_WITH_HEAD_ROT + Word32 Cldfb_RealBuffer_Binaural_fx[MAX_HEAD_ROT_POSES][BINAURAL_CHANNELS][PARAM_MC_MAX_NSLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX]; + Word32 Cldfb_ImagBuffer_Binaural_fx[MAX_HEAD_ROT_POSES][BINAURAL_CHANNELS][PARAM_MC_MAX_NSLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX]; +#else + Word32 Cldfb_RealBuffer_Binaural_fx[BINAURAL_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX]; + Word32 Cldfb_ImagBuffer_Binaural_fx[BINAURAL_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX]; +#endif + Word32 *p_output_f_fx[MAX_OUTPUT_CHANNELS]; + FOR( i = 0; i < MAX_OUTPUT_CHANNELS; i++ ) + { + p_output_f_fx[i] = output_f_fx[i]; // Q11 + } + /*Decorrelator*/ + Word32 onset_filter_fx[MAX_CICP_CHANNELS * CLDFB_NO_CHANNELS_MAX]; // Q31 + + /* format converter */ + Word16 channel_active[MAX_OUTPUT_CHANNELS]; + UWord16 nband_synth; +#ifndef MSAN_FIX + UWord16 nchan_out_init, nbands_to_zero; +#endif + UWord32 output_Fs; + Word16 tmp_q = 0; + move16(); + + hParamMC = st_ivas->hParamMC; + assert( hParamMC ); + + push_wmops( "param_mc_dec_render" ); + + set16_fx( channel_active, 0, MAX_CICP_CHANNELS ); + nchan_transport = st_ivas->nchan_transport; + move16(); + nchan_out_transport = add( st_ivas->hTransSetup.nchan_out_woLFE, st_ivas->hTransSetup.num_lfe ); +#ifndef MSAN_FIX + nchan_out_init = nchan_out_transport; + move16(); +#endif + output_Fs = st_ivas->hDecoderConfig->output_Fs; + move32(); + + test(); + test(); + IF( EQ_16( st_ivas->renderer_type, RENDERER_BINAURAL_FASTCONV ) || EQ_16( st_ivas->renderer_type, RENDERER_BINAURAL_FASTCONV_ROOM ) ) + { + nchan_out_cldfb = BINAURAL_CHANNELS; + set16_fx( channel_active, 1, nchan_out_cldfb ); +#ifndef MSAN_FIX + IF( st_ivas->hCombinedOrientationData ) + { + nchan_out_init = MAX_INTERN_CHANNELS; + } +#endif + nchan_out_cov = add( st_ivas->hTransSetup.nchan_out_woLFE, st_ivas->hTransSetup.num_lfe ); + } + ELSE IF( EQ_16( hParamMC->synthesis_conf, PARAM_MC_SYNTH_LS_CONV_CLDFB ) ) + { + nchan_out_cov = nchan_out_transport; + move16(); + nchan_out_cldfb = add( st_ivas->hOutSetup.nchan_out_woLFE, st_ivas->hOutSetup.num_lfe ); + } + ELSE IF( EQ_16( hParamMC->synthesis_conf, PARAM_MC_SYNTH_LS_CONV_COV ) || EQ_16( hParamMC->synthesis_conf, PARAM_MC_SYNTH_MONO_STEREO ) ) + { + nchan_out_cov = add( st_ivas->hOutSetup.nchan_out_woLFE, st_ivas->hOutSetup.num_lfe ); + nchan_out_cldfb = nchan_out_cov; + move16(); + set16_fx( channel_active, 1, nchan_out_cov ); + } + ELSE + { + nchan_out_cov = nchan_out_transport; + move16(); + nchan_out_cldfb = nchan_out_transport; + move16(); + set16_fx( channel_active, 1, nchan_out_cov ); + } + + /* set everything to zero that will not be decoded */ + nband_synth = hParamMC->band_grouping[hParamMC->num_param_bands_synth]; + move16(); +#ifdef MSAN_FIX + FOR( ch = 0; ch < MAX_OUTPUT_CHANNELS; ch++ ) +#else + FOR( ch = 0; ch < nchan_out_init; ch++ ) +#endif + { + FOR( slot_idx = 0; slot_idx < JBM_CLDFB_SLOTS_IN_SUBFRAME; slot_idx++ ) + { +#ifdef MSAN_FIX + set32_fx( &( Cldfb_RealBuffer_fx[ch][slot_idx][0] ), 0, CLDFB_NO_CHANNELS_MAX ); + set32_fx( &( Cldfb_ImagBuffer_fx[ch][slot_idx][0] ), 0, CLDFB_NO_CHANNELS_MAX ); +#else + set32_fx( &( Cldfb_RealBuffer_fx[ch][slot_idx][nband_synth] ), 0, nbands_to_zero ); + set32_fx( &( Cldfb_ImagBuffer_fx[ch][slot_idx][nband_synth] ), 0, nbands_to_zero ); +#endif + } + } + + /* loop FOR synthesis, assume we always have to render in multiples of 5ms subframes with spills */ + /*slots_to_render = min(sub(hParamMC->num_slots, hParamMC->slots_rendered), nSamplesAsked / NS2SA(output_Fs, CLDFB_SLOT_NS)); + *nSamplesRendered = slots_to_render * NS2SA(output_Fs, CLDFB_SLOT_NS);*/ + Word16 temp_e; + Word16 temp = BASOP_Util_Divide1616_Scale( nSamplesAsked, NS2SA_FX2( output_Fs, CLDFB_SLOT_NS ), &temp_e ); + temp = shr( temp, sub( 15, temp_e ) ); + slots_to_render = s_min( sub( hParamMC->num_slots, hParamMC->slots_rendered ), temp ); + *nSamplesRendered = imult1616( slots_to_render, NS2SA_FX2( output_Fs, CLDFB_SLOT_NS ) ); + move16(); + Word16 j, k; + first_sf = hParamMC->subframes_rendered; + move16(); + last_sf = first_sf; + move16(); + WHILE( slots_to_render > 0 ) + { + slots_to_render = sub( slots_to_render, hParamMC->subframe_nbslots[last_sf] ); + last_sf = add( last_sf, 1 ); + } + IF( EQ_16( st_ivas->renderer_type, RENDERER_SBA_LINEAR_ENC ) ) + { + FOR( subframe_idx = first_sf; subframe_idx < last_sf; subframe_idx++ ) + { + slots_to_render = add( slots_to_render, hParamMC->subframe_nbslots[subframe_idx] ); + } + } + slot_idx_start = hParamMC->slots_rendered; + move16(); + slot_idx_start_cldfb_synth = 0; + move16(); + +#ifndef FIX_1009_OPT_PARAMMC_RENDER + Flag is_zero = 1; + move32(); +#endif + FOR( j = 0; j < st_ivas->hParamMC->hMetadataPMC->nbands_coded; j++ ) + { +#ifndef FIX_1009_OPT_PARAMMC_RENDER + is_zero = 1; + move16(); + FOR( i = 0; i < hParamMC->h_output_synthesis_cov_state.mixing_matrix_len; i++ ) + { + IF( hParamMC->h_output_synthesis_cov_state.mixing_matrix_fx[j][i] != 0 ) + { + is_zero = 0; + move16(); + } + } + IF( is_zero ) + { + hParamMC->h_output_synthesis_cov_state.mixing_matrix_exp[j] = 0; + move16(); + } + is_zero = 1; + move16(); +#else + Flag is_zero = is_zero_arr( hParamMC->h_output_synthesis_cov_state.mixing_matrix_fx[j], hParamMC->h_output_synthesis_cov_state.mixing_matrix_len ); + { + if ( is_zero != 0 ) + { + hParamMC->h_output_synthesis_cov_state.mixing_matrix_exp[j] = 0; + move16(); + } + } +#endif + IF( LT_16( st_ivas->hParamMC->band_grouping[j], st_ivas->hParamMC->h_output_synthesis_params.max_band_decorr ) ) + { +#ifndef FIX_1009_OPT_PARAMMC_RENDER + FOR( i = 0; i < hParamMC->h_output_synthesis_cov_state.mixing_matrix_res_len; i++ ) + { + IF( NE_32( hParamMC->h_output_synthesis_cov_state.mixing_matrix_res_fx[j][i], 0 ) ) + { + is_zero = 0; + move16(); + } + } + IF( is_zero ) +#else + is_zero = is_zero_arr( hParamMC->h_output_synthesis_cov_state.mixing_matrix_res_fx[j], hParamMC->h_output_synthesis_cov_state.mixing_matrix_res_len ); + if ( is_zero != 0 ) +#endif + { + hParamMC->h_output_synthesis_cov_state.mixing_matrix_res_exp[j] = 0; + move16(); + } + } + } + FOR( subframe_idx = first_sf; subframe_idx < last_sf; subframe_idx++ ) + { + FOR( slot_idx = 0; slot_idx < hParamMC->subframe_nbslots[subframe_idx]; ( slot_idx++, hParamMC->slots_rendered++ ) ) + { + IF( hParamMC->max_band_decorr > 0 ) + { + /*-----------------------------------------------------------------* + * protoype signal computation + *-----------------------------------------------------------------*/ + param_mc_protoSignalComputation_fx( &hParamMC->Cldfb_RealBuffer_tc_fx[hParamMC->slots_rendered * nchan_transport * hParamMC->num_freq_bands], + &hParamMC->Cldfb_ImagBuffer_tc_fx[hParamMC->slots_rendered * nchan_transport * hParamMC->num_freq_bands], + hParamMC->proto_frame_f_fx, hParamMC->diff_proto_info, + hParamMC->num_freq_bands ); + /*-----------------------------------------------------------------* + * frequency domain decorrelation + *-----------------------------------------------------------------*/ + /* decorrelate prototype frame */ + + ivas_dirac_dec_decorr_process_fx( hParamMC->num_freq_bands, + hParamMC->num_outputs_diff, + hParamMC->diff_proto_info->num_protos_diff, + DIRAC_SYNTHESIS_COV_MC_LS, + nchan_transport, + hParamMC->proto_frame_f_fx, + Q5, + hParamMC->diff_proto_info->num_protos_diff, + hParamMC->diff_proto_info->proto_index_diff, + hParamMC->proto_frame_dec_f_fx, // output + &tmp_q, + onset_filter_fx, + hParamMC->h_freq_domain_decorr_ap_params, + hParamMC->h_freq_domain_decorr_ap_state ); + + /* copy decorrelated frame directly to output CLDFB buffer, acts also as intermediate */ + /* memory FOR the decorrelated signal */ + ivas_param_mc_dec_copy_diffuse_proto( hParamMC, Cldfb_RealBuffer_fx, Cldfb_ImagBuffer_fx, nchan_out_cov, slot_idx ); // Returns Cldfb buffers in Q11(tmp_q) + + FOR( k = 0; k < nchan_out_cov; k++ ) + { + FOR( Word16 l = 0; l < hParamMC->h_output_synthesis_params.max_band_decorr; l++ ) + { + Cldfb_RealBuffer_fx[k][slot_idx][l] = L_shl( Cldfb_RealBuffer_fx[k][slot_idx][l], sub( 6, tmp_q ) ); // Q11(tmp_q) -> Q6 + move32(); + Cldfb_ImagBuffer_fx[k][slot_idx][l] = L_shl( Cldfb_ImagBuffer_fx[k][slot_idx][l], sub( 6, tmp_q ) ); // Q11(tmp_q) -> Q6 + move32(); + } + } + } + + /*-----------------------------------------------------------------* + * output synthesis + *-----------------------------------------------------------------*/ + ivas_dirac_dec_output_synthesis_cov_param_mc_synthesise_slot_fx( + &hParamMC->Cldfb_RealBuffer_tc_fx[hParamMC->slots_rendered * nchan_transport * hParamMC->num_freq_bands], + &hParamMC->Cldfb_ImagBuffer_tc_fx[hParamMC->slots_rendered * nchan_transport * hParamMC->num_freq_bands], Cldfb_RealBuffer_fx, Cldfb_ImagBuffer_fx, hParamMC->h_output_synthesis_cov_state.mixing_matrix_fx, hParamMC->h_output_synthesis_cov_state.mixing_matrix_exp, hParamMC->h_output_synthesis_cov_state.mixing_matrix_res_fx, hParamMC->h_output_synthesis_cov_state.mixing_matrix_res_exp, slot_idx, add( slot_idx, slot_idx_start ), + nchan_transport, nchan_out_cov, hParamMC ); + + test(); + IF( ( EQ_16( st_ivas->renderer_type, RENDERER_BINAURAL_FASTCONV ) || EQ_16( st_ivas->renderer_type, RENDERER_BINAURAL_FASTCONV_ROOM ) ) ) + { + test(); + IF( st_ivas->hCombinedOrientationData && EQ_16( st_ivas->renderer_type, RENDERER_BINAURAL_FASTCONV ) ) + { + Word16 Q_Cldfb_ImagBuffer, Q_Cldfb_RealBuffer; + Q_Cldfb_ImagBuffer = Q6 - 5; /*max value =MAX_INTERN_CHANNELS(=16)*Cldfb_ImagBuffer_fx*/ + move16(); + Q_Cldfb_RealBuffer = Q6 - 5; + move16(); + FOR( i = 0; i < MAX_OUTPUT_CHANNELS; i++ ) + { + FOR( j = 0; j < MAX_PARAM_SPATIAL_SUBFRAMES; j++ ) + { + Scale_sig32( Cldfb_RealBuffer_fx[i][j], CLDFB_NO_CHANNELS_MAX, sub( Q_Cldfb_ImagBuffer, Q6 ) ); // Q1 + Scale_sig32( Cldfb_ImagBuffer_fx[i][j], CLDFB_NO_CHANNELS_MAX, sub( Q_Cldfb_RealBuffer, Q6 ) ); // Q1 + } + } + ivas_param_mc_mc2sba_cldfb_fx( st_ivas->hTransSetup, hParamMC->hoa_encoder_fx, slot_idx, Cldfb_RealBuffer_fx, Cldfb_ImagBuffer_fx, nband_synth, GAIN_LFE_FX ); + FOR( i = 0; i < MAX_OUTPUT_CHANNELS; i++ ) + { + FOR( j = 0; j < MAX_PARAM_SPATIAL_SUBFRAMES; j++ ) + { + Scale_sig32( Cldfb_RealBuffer_fx[i][j], CLDFB_NO_CHANNELS_MAX, sub( Q6, Q_Cldfb_ImagBuffer ) ); // Q6 + Scale_sig32( Cldfb_ImagBuffer_fx[i][j], CLDFB_NO_CHANNELS_MAX, sub( Q6, Q_Cldfb_RealBuffer ) ); // Q6 + } + } + } + ELSE + { + /* remove LFE */ + UWord16 idx_out; + UWord16 idx_lfe; + IVAS_OUTPUT_SETUP hLsSetup; + + hLsSetup = st_ivas->hTransSetup; + /* If LFE should be rendered, add it to other channels before removing */ + IF( st_ivas->hBinRenderer->render_lfe ) + { + Word16 tmp_exp = 0; + move16(); + Word16 tmp = BASOP_Util_Divide1616_Scale( GAIN_LFE_FX, hLsSetup.nchan_out_woLFE, &tmp_exp ); + tmp_exp = add( tmp_exp, ( 1 - 15 ) ); + FOR( idx_lfe = 0; idx_lfe < hLsSetup.num_lfe; idx_lfe++ ) + { + /* Copy just the first band of LFE*/ + v_multc_fixed_16( Cldfb_RealBuffer_fx[hLsSetup.index_lfe[idx_lfe]][slot_idx], tmp, Cldfb_RealBuffer_fx[hLsSetup.index_lfe[idx_lfe]][slot_idx], 1 ); + v_multc_fixed_16( Cldfb_ImagBuffer_fx[hLsSetup.index_lfe[idx_lfe]][slot_idx], tmp, Cldfb_ImagBuffer_fx[hLsSetup.index_lfe[idx_lfe]][slot_idx], 1 ); + + Scale_sig32( Cldfb_RealBuffer_fx[hLsSetup.index_lfe[idx_lfe]][slot_idx], 1, tmp_exp ); + Scale_sig32( Cldfb_ImagBuffer_fx[hLsSetup.index_lfe[idx_lfe]][slot_idx], 1, tmp_exp ); + FOR( ch = 0; ch < ( hLsSetup.nchan_out_woLFE + hLsSetup.num_lfe ); ch++ ) + { + IF( hLsSetup.index_lfe[idx_lfe] != ch ) + { + v_add_fixed( Cldfb_RealBuffer_fx[ch][slot_idx], Cldfb_RealBuffer_fx[hLsSetup.index_lfe[idx_lfe]][slot_idx], Cldfb_RealBuffer_fx[ch][slot_idx], 1, 0 ); + v_add_fixed( Cldfb_ImagBuffer_fx[ch][slot_idx], Cldfb_ImagBuffer_fx[hLsSetup.index_lfe[idx_lfe]][slot_idx], Cldfb_ImagBuffer_fx[ch][slot_idx], 1, 0 ); + } + } + } + } + + idx_out = 0; + move16(); + idx_lfe = 0; + move16(); + + FOR( ch = 0; ch < ( hLsSetup.nchan_out_woLFE + hLsSetup.num_lfe ); ch++ ) + { + test(); + IF( ( hLsSetup.num_lfe > 0 ) && EQ_16( hLsSetup.index_lfe[idx_lfe], ch ) ) + { + IF( LT_16( idx_lfe, ( sub( hLsSetup.num_lfe, 1 ) ) ) ) + { + idx_lfe = add( idx_lfe, 1 ); + } + } + ELSE IF( NE_16( ch, idx_out ) ) + { + Copy32( Cldfb_RealBuffer_fx[ch][slot_idx], Cldfb_RealBuffer_fx[idx_out][slot_idx], nband_synth ); + Copy32( Cldfb_ImagBuffer_fx[ch][slot_idx], Cldfb_ImagBuffer_fx[idx_out][slot_idx], nband_synth ); + idx_out = add( idx_out, 1 ); + } + ELSE + { + idx_out = add( idx_out, 1 ); + } + } + } + } + } + + test(); + IF( EQ_16( st_ivas->renderer_type, RENDERER_BINAURAL_FASTCONV ) || EQ_16( st_ivas->renderer_type, RENDERER_BINAURAL_FASTCONV_ROOM ) ) + { + Word16 input_q = 6; + move16(); + +#ifdef SPLIT_REND_WITH_HEAD_ROT + IF( EQ_16( st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) || EQ_16( st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ) + { + IF( st_ivas->hSplitBinRend->hCldfbDataOut != NULL ) + { + FOR( slot_idx = 0; slot_idx < MAX_PARAM_SPATIAL_SUBFRAMES; slot_idx++ ) + { + FOR( ch = 0; ch < ( st_ivas->hIntSetup.nchan_out_woLFE + st_ivas->hIntSetup.num_lfe ); ch++ ) + { + Copy32( Cldfb_RealBuffer_fx[ch][slot_idx], st_ivas->hSplitBinRend->hCldfbDataOut->Cldfb_RealBuffer_fx[ch][add( slot_idx_start, slot_idx )], hParamMC->num_freq_bands ); + Copy32( Cldfb_ImagBuffer_fx[ch][slot_idx], st_ivas->hSplitBinRend->hCldfbDataOut->Cldfb_ImagBuffer_fx[ch][add( slot_idx_start, slot_idx )], hParamMC->num_freq_bands ); + } + } + st_ivas->hSplitBinRend->hCldfbDataOut->config = st_ivas->hIntSetup.output_config; + move16(); + } + } +#endif + + /* Implement binaural rendering */ + ivas_binRenderer_fx( st_ivas->hBinRenderer, +#ifdef SPLIT_REND_WITH_HEAD_ROT + ( st_ivas->hSplitBinRend == NULL ) ? NULL : &st_ivas->hSplitBinRend->splitrend.multiBinPoseData, +#endif + st_ivas->hCombinedOrientationData, + hParamMC->subframe_nbslots[subframe_idx], + Cldfb_RealBuffer_Binaural_fx, Cldfb_ImagBuffer_Binaural_fx, + Cldfb_RealBuffer_fx, + Cldfb_ImagBuffer_fx, &input_q ); + + FOR( i = 0; i < MAX_OUTPUT_CHANNELS; i++ ) + { + FOR( j = 0; j < MAX_PARAM_SPATIAL_SUBFRAMES; j++ ) + { + FOR( k = 0; k < CLDFB_NO_CHANNELS_MAX; k++ ) + { + Cldfb_RealBuffer_fx[i][j][k] = L_shl( Cldfb_RealBuffer_fx[i][j][k], sub( Q6, input_q ) ); // Q6 + Cldfb_ImagBuffer_fx[i][j][k] = L_shl( Cldfb_ImagBuffer_fx[i][j][k], sub( Q6, input_q ) ); // Q6 + } + } + } + +#ifdef SPLIT_REND_WITH_HEAD_ROT + int16_t pos_idx; + FOR( pos_idx = 0; pos_idx < st_ivas->hBinRenderer->numPoses; pos_idx++ ) + { + FOR( Word16 idx1 = 0; idx1 < BINAURAL_CHANNELS; idx1++ ) + { + FOR( Word16 idx2 = 0; idx2 < hParamMC->subframe_nbslots[subframe_idx]; idx2++ ) + { + Scale_sig32( Cldfb_RealBuffer_Binaural_fx[pos_idx][idx1][idx2], CLDFB_NO_CHANNELS_MAX, sub( Q6, input_q ) ); // Q6 + Scale_sig32( Cldfb_ImagBuffer_Binaural_fx[pos_idx][idx1][idx2], CLDFB_NO_CHANNELS_MAX, sub( Q6, input_q ) ); // Q6 + } + } + } +#else + FOR( Word16 idx1 = 0; idx1 < BINAURAL_CHANNELS; idx1++ ) + { + FOR( Word16 idx2 = 0; idx2 < hParamMC->subframe_nbslots[subframe_idx]; idx2++ ) + { + Scale_sig32( Cldfb_RealBuffer_Binaural_fx[idx1][idx2], CLDFB_NO_CHANNELS_MAX, sub( Q6, input_q ) ); // Q6 + Scale_sig32( Cldfb_ImagBuffer_Binaural_fx[idx1][idx2], CLDFB_NO_CHANNELS_MAX, sub( Q6, input_q ) ); // Q6 + } + } +#endif + +#ifdef SPLIT_REND_WITH_HEAD_ROT + IF( EQ_16( st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) || EQ_16( st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ) + { + FOR( pos_idx = 0; pos_idx < st_ivas->hBinRenderer->numPoses; pos_idx++ ) + { + FOR( slot_idx = 0; slot_idx < hParamMC->subframe_nbslots[subframe_idx]; slot_idx++ ) + { + FOR( ch = 0; ch < nchan_out_cldfb; ch++ ) + { + Copy32( Cldfb_RealBuffer_Binaural_fx[pos_idx][ch][slot_idx], st_ivas->hSplitBinRend->hMultiBinCldfbData->Cldfb_RealBuffer_Binaural_fx[add( i_mult( pos_idx, BINAURAL_CHANNELS ), ch )][add( slot_idx_start, slot_idx )], hParamMC->num_freq_bands ); + Copy32( Cldfb_ImagBuffer_Binaural_fx[pos_idx][ch][slot_idx], st_ivas->hSplitBinRend->hMultiBinCldfbData->Cldfb_ImagBuffer_Binaural_fx[add( i_mult( pos_idx, BINAURAL_CHANNELS ), ch )][add( slot_idx_start, slot_idx )], hParamMC->num_freq_bands ); + } + } + } + } +#endif + /* update combined orientation access index */ + ivas_combined_orientation_update_index( st_ivas->hCombinedOrientationData, hParamMC->num_freq_bands * hParamMC->subframe_nbslots[subframe_idx] ); + } + ELSE IF( EQ_16( hParamMC->synthesis_conf, PARAM_MC_SYNTH_LS_CONV_CLDFB ) ) + { + /* format conversion*/ + ivas_lssetupconversion_process_param_mc_fx( st_ivas, hParamMC->subframe_nbslots[subframe_idx], Cldfb_RealBuffer_fx, Cldfb_ImagBuffer_fx, channel_active ); + } + + + /* CLDFB synthesis */ + FOR( ch = 0; ch < nchan_out_cldfb; ch++ ) + { + Word32 *RealBuffer_fx[16]; + Word32 *ImagBuffer_fx[16]; + + IF( channel_active[ch] ) + { + /* open CLDFB buffer up to CLDFB_NO_CHANNELS_MAX bands FOR 48kHz */ + FOR( i = 0; i < hParamMC->subframe_nbslots[subframe_idx]; i++ ) + { + IF( EQ_16( st_ivas->renderer_type, RENDERER_BINAURAL_FASTCONV ) || EQ_16( st_ivas->renderer_type, RENDERER_BINAURAL_FASTCONV_ROOM ) ) + { +#ifdef SPLIT_REND_WITH_HEAD_ROT + RealBuffer_fx[i] = Cldfb_RealBuffer_Binaural_fx[0][ch][i]; // Q6 + ImagBuffer_fx[i] = Cldfb_ImagBuffer_Binaural_fx[0][ch][i]; // Q6 +#else + RealBuffer_fx[i] = Cldfb_RealBuffer_Binaural_fx[ch][i]; // Q6 + ImagBuffer_fx[i] = Cldfb_ImagBuffer_Binaural_fx[ch][i]; // Q6 +#endif + } + ELSE + { + RealBuffer_fx[i] = Cldfb_RealBuffer_fx[ch][i]; // Q6 + ImagBuffer_fx[i] = Cldfb_ImagBuffer_fx[ch][i]; // Q6 + } + } + + Word16 len = add( imult1616( slot_idx_start_cldfb_synth, hParamMC->num_freq_bands ), imult1616( hParamMC->num_freq_bands, hParamMC->subframe_nbslots[subframe_idx] ) ); + scale_sig32( output_f_fx[ch], len, 5 - 11 ); + cldfbSynthesis_ivas_fx( RealBuffer_fx, ImagBuffer_fx, &( output_f_fx[ch][slot_idx_start_cldfb_synth * hParamMC->num_freq_bands] ), + imult1616( hParamMC->num_freq_bands, hParamMC->subframe_nbslots[subframe_idx] ), st_ivas->cldfbSynDec[ch] ); + + scale_sig32( output_f_fx[ch], len, 11 - 5 ); // Q11 + } + ELSE + { + set32_fx( &( output_f_fx[ch][slot_idx_start_cldfb_synth * hParamMC->num_freq_bands] ), 0, imult1616( hParamMC->num_freq_bands, hParamMC->subframe_nbslots[subframe_idx] ) ); + } + } + slot_idx_start = add( slot_idx_start, hParamMC->subframe_nbslots[subframe_idx] ); + slot_idx_start_cldfb_synth = add( slot_idx_start_cldfb_synth, hParamMC->subframe_nbslots[subframe_idx] ); + } + IF( EQ_16( st_ivas->renderer_type, RENDERER_SBA_LINEAR_ENC ) ) + { + ivas_mc2sba_fx( st_ivas->hIntSetup, p_output_f_fx, p_output_f_fx, *nSamplesRendered, st_ivas->hOutSetup.ambisonics_order, 0 ); + } + + /* update */ + + IF( EQ_16( hParamMC->slots_rendered, hParamMC->num_slots ) ) + { + hParamMC->hMetadataPMC->last_coded_bwidth = hParamMC->hMetadataPMC->coded_bwidth; + move16(); + param_mc_update_mixing_matrices_fx( hParamMC, hParamMC->h_output_synthesis_cov_state.mixing_matrix_fx, hParamMC->h_output_synthesis_cov_state.mixing_matrix_exp, hParamMC->h_output_synthesis_cov_state.mixing_matrix_res_fx, hParamMC->h_output_synthesis_cov_state.mixing_matrix_res_exp, nchan_transport, nchan_out_cov ); + } + + + hParamMC->subframes_rendered = last_sf; + move16(); + *nSamplesAvailableNext = imult1616( sub( hParamMC->num_slots, hParamMC->slots_rendered ), NS2SA_FX2( output_Fs, CLDFB_SLOT_NS ) ); + move16(); + + FOR( i = 0; i < MAX_OUTPUT_CHANNELS; i++ ) + { + channel_active_fx[i] = channel_active[i]; + move16(); + } + pop_wmops(); + + return; +} + +/*------------------------------------------------------------------------- + * param_mc_dec_init() + * + * Parametric MC decoding initialization + *------------------------------------------------------------------------*/ + +static void ivas_param_mc_dec_init_fx( + PARAM_MC_DEC_HANDLE hParamMC, /* i/o: decoder DirAC handle */ + const Word16 nchan_transport, /* i : number of input (transport) channels */ + const Word16 nchan_cov ) /* i : number of cov synthesis channels */ +{ + Word16 k; + UWord16 max_param_band_residual; + Word16 len; + + /*-----------------------------------------------------------------* + * init sub-modules + *-----------------------------------------------------------------*/ + + /* decorrelation */ + IF( hParamMC->max_band_decorr > 0 ) + { + len = imult1616( hParamMC->diff_proto_info->num_protos_diff, hParamMC->h_freq_domain_decorr_ap_params->h_onset_detection_power_params.max_band_decorr ); + + /* init onsetDetectionPower */ + set_zero_fx( hParamMC->h_freq_domain_decorr_ap_state->h_onset_detection_power_state.onset_detector_1_fx, len ); + set_zero_fx( hParamMC->h_freq_domain_decorr_ap_state->h_onset_detection_power_state.onset_detector_2_fx, len ); + hParamMC->h_freq_domain_decorr_ap_state->h_onset_detection_power_state.q_onset_detector = Q31; + move16(); + } + + max_param_band_residual = 0; + move16(); + + /* output synthesis */ + FOR( k = hParamMC->hMetadataPMC->num_parameter_bands; k >= 0; k-- ) + { + IF( LE_16( hParamMC->band_grouping[k], hParamMC->max_band_decorr ) ) + { + max_param_band_residual = k; + move16(); + BREAK; + } + } + + ivas_dirac_dec_output_synthesis_cov_init_fx( &( hParamMC->h_output_synthesis_cov_state ), nchan_transport, nchan_cov, hParamMC->hMetadataPMC->num_parameter_bands, max_param_band_residual ); + + /*-----------------------------------------------------------------* + * init proto frames + *-----------------------------------------------------------------*/ + + IF( hParamMC->max_band_decorr > 0 ) + { + set_zero_fx( hParamMC->proto_frame_f_fx, shl( imult1616( hParamMC->diff_proto_info->num_protos_diff, hParamMC->num_freq_bands ), 1 ) ); + set32_fx( hParamMC->proto_frame_dec_f_fx, 0, shl( imult1616( nchan_cov, hParamMC->num_freq_bands ), 1 ) ); + } + + return; +} + + +/*------------------------------------------------------------------------- + * Local functions + *-------------------------------------------------------------------------*/ + + +/*------------------------------------------------------------------------- + * ivas_param_mc_dec_compute_diffuse_proto() + * + * Compute prototypes for decorrelation + *------------------------------------------------------------------------*/ + +static void param_mc_protoSignalComputation_fx( + Word32 *RealBuffer_fx, /* i : CLDFB samples of the transport channels (real part) */ + Word32 *ImagBuffer_fx, /* i : CLDFB samples of the transport channels (imaginary part) */ + Word32 *proto_frame_f_fx, /* o : interleaved complex prototype CLDFB samples */ + const PARAM_MC_DIFF_PROTO_INFO *diff_proto_info, /* i : prototype generation information */ + const Word16 num_freq_bands /* i : number of frequency bands for the prototypes */ +) +{ + Word16 band; + Word16 proto_ch_idx, source_ch_cnt; + + Word32 *p_proto_frame_fx; + Word32 *p_real_buffer_fx; // Q12 + Word32 *p_imag_buffer_fx; // Q12 + + set32_fx( proto_frame_f_fx, 0, shl( imult1616( num_freq_bands, diff_proto_info->num_protos_diff ), 1 ) ); + + + FOR( proto_ch_idx = 0; proto_ch_idx < diff_proto_info->num_protos_diff; proto_ch_idx++ ) + { + Word16 num_source_ch = diff_proto_info->num_source_chan_diff[proto_ch_idx]; + move16(); + + FOR( source_ch_cnt = 0; source_ch_cnt < num_source_ch; source_ch_cnt++ ) + { + + Word32 fac_fx = diff_proto_info->proto_fac_fx[proto_ch_idx][source_ch_cnt]; + move32(); + + Word16 source_ch_idx = diff_proto_info->source_chan_idx[proto_ch_idx][source_ch_cnt]; + move16(); + + p_proto_frame_fx = &proto_frame_f_fx[shl( imult1616( proto_ch_idx, num_freq_bands ), 1 )]; + p_real_buffer_fx = &RealBuffer_fx[imult1616( source_ch_idx, num_freq_bands )]; + p_imag_buffer_fx = &ImagBuffer_fx[imult1616( source_ch_idx, num_freq_bands )]; + + FOR( band = 0; band < num_freq_bands; band++ ) + { + + Word32 tmp_x = Mpy_32_32( fac_fx, ( *( p_real_buffer_fx++ ) ) ); // Q(30 + 6 - 31) :: Q5 + + *( p_proto_frame_fx ) = L_add( *( p_proto_frame_fx ), tmp_x ); + move32(); + p_proto_frame_fx++; + + tmp_x = Mpy_32_32( fac_fx, ( *( p_imag_buffer_fx++ ) ) ); // Q(30 + 6 - 31) :: Q5 + + *( p_proto_frame_fx ) = L_add( *( p_proto_frame_fx ), tmp_x ); + move32(); + p_proto_frame_fx++; + } + } + } + + return; +} + +/*------------------------------------------------------------------------- + * ivas_param_mc_dec_compute_diffuse_proto() + * + * Transfer decorrelated signals back from the decorrelator buffer to + * the buffers used in the final synthesis + *------------------------------------------------------------------------*/ + +static void ivas_param_mc_dec_copy_diffuse_proto( + PARAM_MC_DEC_HANDLE hParamMC, /* i : Parametric MC handle */ + Word32 Cldfb_buffer_real_fx[MAX_CICP_CHANNELS][PARAM_MC_MAX_NSLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX], /* o : CLDFB buffer used in the final synthesis (real part) */ + Word32 Cldfb_buffer_imag_fx[MAX_CICP_CHANNELS][PARAM_MC_MAX_NSLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX], /* o : CLDFB buffer used in the final synthesis (imaginary part) */ + const Word16 nY, /* i : number of decorrelated channels */ + const Word16 slot_idx /* i : current time slot index */ +) +{ + Word16 k, l; + Word16 num_freq_bands, num_freq_bands_diff; + Word32 *p_proto_diff_fx; + num_freq_bands = hParamMC->num_freq_bands; + move16(); + num_freq_bands_diff = hParamMC->h_output_synthesis_params.max_band_decorr; + move16(); + + FOR( k = 0; k < nY; k++ ) + { + p_proto_diff_fx = hParamMC->proto_frame_dec_f_fx + imult1616( shl( k, 1 ), num_freq_bands ); // Q11 + + FOR( l = 0; l < num_freq_bands_diff; l++ ) + { + Cldfb_buffer_real_fx[k][slot_idx][l] = *( p_proto_diff_fx++ ); // Q11 + move32(); + Cldfb_buffer_imag_fx[k][slot_idx][l] = *( p_proto_diff_fx++ ); // Q11 + move32(); + } + } + + return; +} + +/*------------------------------------------------------------------------- + * ivas_param_mc_bin2dec() + * + * decode a number of bits to an integer + *------------------------------------------------------------------------*/ +/* r : decoded integer */ +static Word16 ivas_param_mc_bin2dec_fx( + UWord16 bits[PARAM_MC_MAX_BITS], /* i : bit buffer */ + const Word16 N /* i : number of bits to decode */ +) +{ + Word16 i; + Word16 out; + + assert( N <= 16 ); + out = 0; + move16(); + FOR( i = 0; i < N; i++ ) + { + out = add( out, shl( bits[i], sub( sub( N, 1 ), i ) ) ); + } + + return out; +} + +/*------------------------------------------------------------------------- + * ivas_param_mc_uniform_decoder() + * + * decode a uniformily coded sequence of float values + *------------------------------------------------------------------------*/ +static Word16 ivas_param_mc_uniform_decoder_fx( + Word16 *seq, /* o : decoded sequence of float values hParamCodingInfo -> Q-quant*/ + const Word16 sz_seq, /* i : number of values to decode */ + const Word16 *alphabet, /* i : codebook hParamCodingInfo -> Q-quant*/ + const Word16 N, /* i : number of bits per coded index */ + UWord16 bit_buffer[PARAM_MC_MAX_BITS] /* i : bit buffer to decode */ +) +{ + Word16 i; + Word16 idx; + Word16 n_bits; + + n_bits = 0; + move16(); + assert( N * sz_seq < PARAM_MC_MAX_BITS ); + + FOR( i = 0; i < sz_seq; ++i ) + { + idx = ivas_param_mc_bin2dec_fx( &bit_buffer[i * N], N ); + seq[i] = alphabet[idx]; + move16(); + } + + n_bits = imult1616( N, sz_seq ); + + return n_bits; +} + + +/*------------------------------------------------------------------------- + * ivas_param_mc_range_decoder_LC() + * + * decode a sequency of inidices coded with a range coder + *------------------------------------------------------------------------*/ +static Word16 ivas_param_mc_range_decoder_LC_fx( + UWord16 *bit_buffer, /* i : bit buffer to read from */ + Word16 *x, /* o : decoded indices */ + Word16 *BER_detect, /* o : flag for indicating a bit error */ + const Word16 sz_seq, /* i : size of the sequence to be decoded */ + const Word16 sz_alphabet, /* i : size of the alphabet */ + const UWord16 *cft, /* i : cumulative frequency table */ + const UWord16 *sft, /* i : symbol frequency table */ + const Word16 tot_shift, /* i : total frequency as a power of 2 */ + const Word16 nbbits /* i : maximum bit budget */ +) +{ + RangeUniDecState rc_st_dec; /* State of the range decoder */ + Word16 cur_bit_pos; + Word16 k; + Word16 r; + + /* Start Decoding */ + /* Initialize range decoder */ + cur_bit_pos = 0; + move16(); + rc_uni_dec_init_fx( &rc_st_dec, bit_buffer, sub( nbbits, 32 ) ); /* (nbbits + 30) entries are read by the decoder */ + + /* Main Loop through the indices */ + FOR( k = 0; k < sz_seq; k++ ) + { + r = rc_uni_dec_read_symbol_fastS_fx( &rc_st_dec, cft, sft, sz_alphabet, tot_shift ); /*Alphabet size = 17 (2^4 = 16 MSB symbols + 1 ESC symbol) */ + /* r is the symbol read, the possible values are {0,1,....alphabet_size - 1} */ + + /* Update bitstream pointer */ + cur_bit_pos = rc_uni_dec_virtual_finish_fx( &rc_st_dec ); + + /* Confirm that there is no overflow */ + IF( GT_16( cur_bit_pos, nbbits ) ) + { + *BER_detect = s_or( *BER_detect, 1 ); + move16(); + } + + x[k] = r; + move16(); + } + + /* We don't need to finish because virtual_finish() already does the same */ + /*st->next_bit_pos = rc_uni_dec_finish(&rc_st_dec);*/ + + /* Check for bitstream errors */ + IF( rc_st_dec.bit_error_detected != 0 ) + { + *BER_detect = s_or( *BER_detect, 1 ); + move16(); + } + + return cur_bit_pos; +} + +/*------------------------------------------------------------------------- + * param_mc_compute_interpolator() + * + * compute the interpolator used in the final synthesis + *------------------------------------------------------------------------*/ + +static void ivas_param_mc_dec_compute_interpolator_fx( + const UWord16 bAttackPresent, /* i : flag indicating if we have a transient in the current frame */ + const UWord16 attackPos, /* i : position of the transient */ + const UWord16 interp_length, /* i : number of interpolation values to be calculated */ + Word16 *interpolator /* o : interpolator */ +) +{ + Word16 idx; + + IF( bAttackPresent ) + { + FOR( idx = 0; idx < attackPos * 2; idx++ ) + { + interpolator[idx] = 0; + move16(); + } + FOR( ; idx < interp_length; idx++ ) + { + interpolator[idx] = 32767; /* 1.0f Q15 */ + move16(); + } + } + ELSE + { + ivas_jbm_dec_get_adapted_linear_interpolator_fx( DEFAULT_JBM_CLDFB_TIMESLOTS, interp_length, interpolator ); + } + + return; +} + + +/*------------------------------------------------------------------------- + * remove_lfe_from_cy() + * + * remove all LFE related values from a covariance matrix + *------------------------------------------------------------------------*/ + +static void remove_lfe_from_cy_fx( + const Word16 nY, /* i : dimension of the covariance matrix */ + Word16 lfe_indices[PARAM_MC_LOCAL_SZ_LFE_MAP], /* i : LFE index */ + Word16 num_lfe, /* i : number of LFEs */ + Word32 *cy, /* i : covariance matrix */ + Word32 *cy_woLFE /* o : covariance matrix with LFE removed */ +) +{ + Word16 ch_idx1, ch_idx2; + Word16 lfe_idx1, lfe_idx2; + Word32 *ptrCy; + Word32 *ptrCy_out; + + ptrCy = cy; + ptrCy_out = cy_woLFE; + + FOR( lfe_idx1 = 0; lfe_idx1 < num_lfe + 1; lfe_idx1++ ) + { + FOR( ch_idx1 = lfe_indices[lfe_idx1] + 1; ch_idx1 < lfe_indices[lfe_idx1 + 1]; ch_idx1++ ) + { + FOR( lfe_idx2 = 0; lfe_idx2 < num_lfe + 1; lfe_idx2++ ) + { + FOR( ch_idx2 = lfe_indices[lfe_idx2] + 1; ch_idx2 < lfe_indices[lfe_idx2 + 1]; ch_idx2++ ) + { + *( ptrCy_out++ ) = *( ptrCy++ ); + move32(); + } + ptrCy++; + } + ptrCy--; + } + ptrCy += nY; + } + + return; +} + + +/*------------------------------------------------------------------------- + * ivas_param_mc_get_mixing_matrices() + * + * calculate the direct and residual mixing matrices + * using the covariance method + *------------------------------------------------------------------------*/ + +static void ivas_param_mc_get_mixing_matrices_fx( + PARAM_MC_DEC_HANDLE hParamMC, /* i : Parametric MC handle */ + IVAS_OUTPUT_SETUP *hSynthesisOutputSetup, + Word32 Cx_in_fixed[PARAM_MC_MAX_TRANSPORT_CHANS * PARAM_MC_MAX_TRANSPORT_CHANS], /* i : input covariance for all parameter bands Q(31 - Cx_in_e)*/ + Word16 Cx_in_e, + const Word16 param_band_idx, /* i : parameter band index */ + Word32 *mixing_matrix_fx[], // Q(31 - mixing_matrix_e) + Word16 *mixing_matrix_e, + Word32 *mixing_matrix_res_fx[], // Q(31 - mixing_matrix_res_e) + Word16 *mixing_matrix_res_e, + const Word16 nY_intern, /* i : number of channels in the transported format */ + const PARAM_MC_SYNTHESIS_CONF synth_config, /* i : Parametric MC synthesis config */ + const Word16 nX, /* i : number of transport channels */ + const Word16 nY_cov /* i : number of covariance synthesis output channels */ +) +{ + Word16 matSize = MAX_OUTPUT_CHANNELS * MAX_OUTPUT_CHANNELS; + Word16 nY_band; + Word16 num_lfe_bands; + Word16 brange[2]; + UWord16 i; + Word16 ch_idx1, ch_idx2, lfe_idx1, lfe_idx2; + Word16 remove_lfe; + Word16 lfe_indices[PARAM_MC_LOCAL_SZ_LFE_MAP]; + + Word32 Cx_fx[PARAM_MC_MAX_TRANSPORT_CHANS * PARAM_MC_MAX_TRANSPORT_CHANS]; + Word32 Cy_fx[MAX_CICP_CHANNELS * MAX_CICP_CHANNELS]; + + Word32 Cy_full_fx[MAX_CICP_CHANNELS * MAX_CICP_CHANNELS]; + + Word32 Cr_fx[MAX_CICP_CHANNELS * MAX_CICP_CHANNELS]; // Q(31 - Cr_e) + Word16 Cr_e; + Word32 Cy_diag_fx[MAX_OUTPUT_CHANNELS]; // Q(31 - Cy_diag_buff_e) + Word16 Cy_diag_buff_e[MAX_OUTPUT_CHANNELS]; + Word32 mixing_matrix_local_fx[MAX_CICP_CHANNELS * PARAM_MC_MAX_TRANSPORT_CHANS]; // Q(31 - mixing_matrix_local_e) + Word16 Cy_diag_e = 0, mixing_matrix_local_e = 0; + Word32 Cproto_fx[MAX_CICP_CHANNELS * MAX_CICP_CHANNELS]; // Q(31 - Cproto_e) + Word16 Cproto_e; + Word32 *proto_matrix_ptr_fx; // Q(31 - proto_matrix_ptr_e) + Word32 *Cx_state_fx; // Q(31 - Cx_state_e) + Word32 *Cx_old_state_fx; + Word32 Cy_state_fx[MAX_CICP_CHANNELS * MAX_CICP_CHANNELS]; // Q(31 - Cy_state_e) + Word32 *Cy_old_state_fx; + Word16 Cx_state_e; + Word16 Cy_state_e; + Word32 mixing_matrix_res_local_fx[MAX_CICP_CHANNELS * MAX_CICP_CHANNELS]; // Q(31 - mixing_matrix_res_local_e) + Word16 mixing_matrix_res_local_e; + Word32 L_tmp; + Word16 tmp_e, tmp; + + Word16 proto_matrix_e = hParamMC->h_output_synthesis_params.proto_matrix_e; + move16(); + Word32 proto_matrix_noLFE_fx[PARAM_MC_MAX_TRANSPORT_CHANS * MAX_CICP_CHANNELS]; // Q(31 - proto_matrix_noLFE_e) + + Word32 mat_mult_buffer1_fx[MAX_CICP_CHANNELS * MAX_CICP_CHANNELS]; // Q(31 - mat_mult_buffer1_e) + + Word32 Cproto_diag_fx[MAX_CICP_CHANNELS]; // Q(31 - Cproto_diag_e) + Word16 mat_mult_buffer1_e, proto_matrix_ptr_e, Cproto_diag_e; + + Word32 *ptrMM_fx; + Word32 *ptrMM_out_fx; + + Word16 Cy_e, Cx_e; + Word16 Cy_full_e; + Word16 new_e = 0; + move16(); + + set_zero_fx( Cproto_fx, MAX_CICP_CHANNELS * MAX_CICP_CHANNELS ); + set_zero_fx( mat_mult_buffer1_fx, MAX_CICP_CHANNELS * MAX_CICP_CHANNELS ); + set_zero_fx( proto_matrix_noLFE_fx, PARAM_MC_MAX_TRANSPORT_CHANS * MAX_CICP_CHANNELS ); + set_zero_fx( mixing_matrix_local_fx, MAX_CICP_CHANNELS * PARAM_MC_MAX_TRANSPORT_CHANS ); +#ifdef MSAN_FIX + set_zero_fx( mixing_matrix_res_local_fx, MAX_CICP_CHANNELS * MAX_CICP_CHANNELS ); +#endif + Word16 proto_matrix_noLFE_e = 0; + move16(); + + Word32 Cx_in_fx[PARAM_MC_MAX_TRANSPORT_CHANS * PARAM_MC_MAX_TRANSPORT_CHANS]; + + Copy32( Cx_in_fixed, Cx_in_fx, PARAM_MC_MAX_TRANSPORT_CHANS * PARAM_MC_MAX_TRANSPORT_CHANS ); + + nY_band = nY_cov; + move16(); + num_lfe_bands = 0; + move16(); + remove_lfe = 0; + move16(); + + set16_fx( lfe_indices, -1, PARAM_MC_LOCAL_SZ_LFE_MAP ); + IF( hSynthesisOutputSetup->num_lfe ) + { + Word32 *proto_matrix_ptr_in_fx; + FOR( lfe_idx1 = 0; lfe_idx1 < hSynthesisOutputSetup->num_lfe; lfe_idx1++ ) + { + lfe_indices[lfe_idx1 + 1] = hSynthesisOutputSetup->index_lfe[lfe_idx1]; + move16(); + } + lfe_indices[hSynthesisOutputSetup->num_lfe + 1] = nY_cov; + move16(); + proto_matrix_ptr_fx = &proto_matrix_noLFE_fx[0]; + proto_matrix_ptr_in_fx = &hParamMC->h_output_synthesis_params.proto_matrix_fx[0]; + proto_matrix_noLFE_e = proto_matrix_e; + move16(); + + set_zero_fx( proto_matrix_noLFE_fx, PARAM_MC_MAX_TRANSPORT_CHANS * MAX_CICP_CHANNELS ); + + FOR( ch_idx1 = 0; ch_idx1 < nX; ch_idx1++ ) + { + FOR( lfe_idx1 = 0; lfe_idx1 < hSynthesisOutputSetup->num_lfe + 1; lfe_idx1++ ) + { + FOR( ch_idx2 = lfe_indices[lfe_idx1] + 1; ch_idx2 < lfe_indices[lfe_idx1 + 1]; ch_idx2++ ) + { + *( proto_matrix_ptr_fx++ ) = *( proto_matrix_ptr_in_fx++ ); + move32(); + } + proto_matrix_ptr_in_fx++; + } + proto_matrix_ptr_in_fx--; + } + + proto_matrix_ptr_e = proto_matrix_e; + move16(); + } + + if ( hParamMC->hMetadataPMC->lfe_on ) + { + num_lfe_bands = PARAM_MC_MAX_BAND_LFE; + move16(); + } + IF( hSynthesisOutputSetup->num_lfe > 0 && param_band_idx >= num_lfe_bands ) + { + remove_lfe = 1; + move16(); + nY_band = sub( nY_cov, hSynthesisOutputSetup->num_lfe ); + proto_matrix_ptr_fx = proto_matrix_noLFE_fx; + proto_matrix_ptr_e = proto_matrix_noLFE_e; + move16(); + } + ELSE + { + proto_matrix_ptr_fx = hParamMC->h_output_synthesis_params.proto_matrix_fx; + proto_matrix_ptr_e = hParamMC->h_output_synthesis_params.proto_matrix_e; + move16(); + } + + brange[0] = hParamMC->band_grouping[param_band_idx]; + move16(); + brange[1] = hParamMC->band_grouping[param_band_idx + 1]; + move16(); + + Cx_state_fx = Cx_in_fx; + Cx_old_state_fx = hParamMC->h_output_synthesis_cov_state.cx_old_fx[param_band_idx]; + Cy_old_state_fx = hParamMC->h_output_synthesis_cov_state.cy_old_fx[param_band_idx]; + + + /* Getting mixing mtx */ + /* estimate target cov from input cov and proto_matrix */ + + Cx_state_e = Cx_in_e; + move16(); + matrix_product_fx( hParamMC->proto_matrix_int_fx, nY_intern, nX, 0, Cx_state_fx, nX, nX, 0, mat_mult_buffer1_fx ); + mat_mult_buffer1_e = add( hParamMC->proto_matrix_int_e, Cx_in_e ); + + matrix_product_fx( mat_mult_buffer1_fx, nY_intern, nX, 0, hParamMC->proto_matrix_int_fx, nY_intern, nX, 1, Cproto_fx ); + Cproto_e = add( mat_mult_buffer1_e, hParamMC->proto_matrix_int_e ); + + FOR( ch_idx1 = 0; ch_idx1 < nY_intern; ch_idx1++ ) + { + IF( BASOP_Util_Cmp_Mant32Exp( Cproto_fx[ch_idx1 + ( ch_idx1 * nY_intern )], Cproto_e, 0, 0 ) < 0 ) + { + Cproto_fx[ch_idx1 + ( ch_idx1 * nY_intern )] = 0; + move32(); + } + } + + set_zero_fx( Cy_state_fx, matSize ); + Cy_state_e = 0; + move16(); + + ivas_param_mc_dequantize_cov_fx( hParamMC, + hParamMC->icld_q_fx + L_mult0( param_band_idx, hParamMC->hMetadataPMC->ild_mapping_conf->ild_map_size_lfe ), + hParamMC->icc_q_fx + L_mult0( param_band_idx, hParamMC->hMetadataPMC->icc_mapping_conf->icc_map_size_lfe ), + param_band_idx, nY_cov, + synth_config, + nY_intern, + nX, Cx_state_fx, Cx_state_e, Cproto_fx, Cproto_e, Cy_state_fx, &Cy_state_e ); + + // dbgwrite2_txt(Cy_state_fx,nY_intern*nY_intern,"../cy_state_fx.txt"); + + /* Smoothing: Sum over two buffers */ + IF( hParamMC->hMetadataPMC->bAttackPresent ) + { + /* no smoothing on attacks */ + Copy32( Cx_state_fx, Cx_fx, imult1616( nX, nX ) ); + Copy32( Cy_state_fx, Cy_full_fx, imult1616( nY_cov, nY_cov ) ); + Cy_full_e = Cy_state_e; + move16(); + Cx_e = Cx_state_e; + move16(); + } + ELSE + { + /* smoothing gains are now identical to one, simply add up */ + // v_add( Cy_state, Cy_old_state, Cy_full, nY_cov * nY_cov ); + + v_add_fixed_me( Cx_state_fx, Cx_state_e, Cx_old_state_fx, hParamMC->h_output_synthesis_cov_state.cx_old_e[param_band_idx], Cx_fx, &Cx_e, imult1616( nX, nX ), 1 ); + v_add_fixed_me( Cy_state_fx, Cy_state_e, Cy_old_state_fx, hParamMC->h_output_synthesis_cov_state.cy_old_e[param_band_idx], Cy_full_fx, &Cy_full_e, imult1616( nY_cov, nY_cov ), 1 ); + } + + Copy32( Cx_state_fx, Cx_old_state_fx, imult1616( nX, nX ) ); + + Copy32( Cy_state_fx, Cy_old_state_fx, imult1616( nY_cov, nY_cov ) ); + + hParamMC->h_output_synthesis_cov_state.cx_old_e[param_band_idx] = Cx_state_e; + move16(); + hParamMC->h_output_synthesis_cov_state.cy_old_e[param_band_idx] = Cy_state_e; + move16(); + + FOR( i = 0; i < nX * nX; i++ ) + { + if ( Cx_old_state_fx[i] != 0 ) + { + new_e = hParamMC->h_output_synthesis_cov_state.cx_old_e[param_band_idx]; + move16(); + BREAK; + } + } + + hParamMC->h_output_synthesis_cov_state.cx_old_e[param_band_idx] = new_e; + move16(); + + new_e = 0; + move16(); + + FOR( i = 0; i < nY_cov * nY_cov; i++ ) + { + if ( Cy_old_state_fx[i] != 0 ) + { + new_e = hParamMC->h_output_synthesis_cov_state.cy_old_e[param_band_idx]; + move16(); + BREAK; + } + } + + hParamMC->h_output_synthesis_cov_state.cy_old_e[param_band_idx] = new_e; + move16(); + + /* remove LFE IF necessary */ + IF( remove_lfe ) + { + + Cy_e = Cy_full_e; + remove_lfe_from_cy_fx( nY_cov, lfe_indices, hSynthesisOutputSetup->num_lfe, Cy_full_fx, Cy_fx ); + } + ELSE + { + Copy32( Cy_full_fx, Cy_fx, imult1616( nY_band, nY_band ) ); + Cy_e = Cy_full_e; + move16(); + } + + matrix_product_fx( proto_matrix_ptr_fx, nY_band, nX, 0, Cx_fx, nX, nX, 0, mat_mult_buffer1_fx ); + mat_mult_buffer1_e = add( proto_matrix_ptr_e, Cx_e ); + + matrix_product_diag_fx( mat_mult_buffer1_fx, mat_mult_buffer1_e, nY_band, nX, 0, proto_matrix_ptr_fx, proto_matrix_ptr_e, nY_band, nX, 1, Cproto_diag_fx, &Cproto_diag_e ); + + /* make sure we have no negative entries in Cproto_diag due to rounding errors */ + + FOR( ch_idx1 = 0; ch_idx1 < nY_band; ch_idx1++ ) + { +#ifdef OPT_BASOP_ADD_v1 + if ( Cproto_diag_fx[ch_idx1] < 0 ) +#else /* OPT_BASOP_ADD_v1 */ + if ( BASOP_Util_Cmp_Mant32Exp( Cproto_diag_fx[ch_idx1], Cproto_diag_e, 0, 0 ) < 0 ) +#endif /* OPT_BASOP_ADD_v1 */ + { + Cproto_diag_fx[ch_idx1] = 0; + move16(); + } + } + + + /* Computing the mixing matrices */ + + /* bands with decorr */ + IF( LT_16( brange[0], hParamMC->h_output_synthesis_params.max_band_decorr ) ) + { + computeMixingMatrices_fx( nX, nY_band, Cx_fx, Cx_e, Cy_fx, Cy_e, proto_matrix_ptr_fx, proto_matrix_ptr_e, 0, PARAM_MC_REG_SX_FX, 0, PARAM_MC_REG_GHAT_FX, 0, mixing_matrix_local_fx, &mixing_matrix_local_e, Cr_fx, &Cr_e ); + /* Compute mixing matrix FOR residual */ + computeMixingMatricesResidual_fx( nY_band, Cproto_diag_fx, Cproto_diag_e, Cr_fx, Cr_e, PARAM_MC_REG_SX_FX, 0, PARAM_MC_REG_GHAT_FX, 0, mixing_matrix_res_local_fx, &mixing_matrix_res_local_e ); + + IF( NE_16( mixing_matrix_res_local_e, mixing_matrix_local_e ) ) + { + tmp = getScaleFactor32( mixing_matrix_local_fx, MAX_CICP_CHANNELS * PARAM_MC_MAX_TRANSPORT_CHANS ); + scale_sig32( mixing_matrix_local_fx, MAX_CICP_CHANNELS * PARAM_MC_MAX_TRANSPORT_CHANS, tmp ); + mixing_matrix_local_e = sub( mixing_matrix_local_e, tmp ); + + tmp = getScaleFactor32( mixing_matrix_res_local_fx, MAX_CICP_CHANNELS * MAX_CICP_CHANNELS ); + scale_sig32( mixing_matrix_res_local_fx, MAX_CICP_CHANNELS * MAX_CICP_CHANNELS, tmp ); + mixing_matrix_res_local_e = sub( mixing_matrix_res_local_e, tmp ); + + scale_sig32( mixing_matrix_local_fx, MAX_CICP_CHANNELS * PARAM_MC_MAX_TRANSPORT_CHANS, sub( mixing_matrix_local_e, s_max( mixing_matrix_local_e, mixing_matrix_res_local_e ) ) ); + scale_sig32( mixing_matrix_res_local_fx, MAX_CICP_CHANNELS * MAX_CICP_CHANNELS, sub( mixing_matrix_res_local_e, s_max( mixing_matrix_local_e, mixing_matrix_res_local_e ) ) ); + + mixing_matrix_res_local_e = mixing_matrix_local_e = s_max( mixing_matrix_local_e, mixing_matrix_res_local_e ); + move16(); + } + IF( remove_lfe ) + { + set_zero_fx( mixing_matrix_res_fx[param_band_idx], imult1616( nY_cov, nY_cov ) ); + + ptrMM_fx = mixing_matrix_res_local_fx; + ptrMM_out_fx = mixing_matrix_res_fx[param_band_idx]; + FOR( lfe_idx1 = 0; lfe_idx1 < hSynthesisOutputSetup->num_lfe + 1; lfe_idx1++ ) + { + FOR( ch_idx1 = lfe_indices[lfe_idx1] + 1; ch_idx1 < lfe_indices[lfe_idx1 + 1]; ch_idx1++ ) + { + FOR( lfe_idx2 = 0; lfe_idx2 < hSynthesisOutputSetup->num_lfe + 1; lfe_idx2++ ) + { + FOR( ch_idx2 = lfe_indices[lfe_idx2] + 1; ch_idx2 < lfe_indices[lfe_idx2 + 1]; ch_idx2++ ) + { + *( ptrMM_out_fx++ ) = *( ptrMM_fx++ ); + move32(); + } + ptrMM_out_fx++; + } + ptrMM_out_fx--; + } + ptrMM_out_fx += nY_cov; + } + mixing_matrix_res_e[param_band_idx] = mixing_matrix_res_local_e; + move16(); + } + ELSE + { + Copy32( mixing_matrix_res_local_fx, mixing_matrix_res_fx[param_band_idx], imult1616( nY_cov, nY_cov ) ); + mixing_matrix_res_e[param_band_idx] = mixing_matrix_res_local_e; + move16(); + } + } + ELSE IF( brange[0] < hParamMC->max_band_energy_compensation ) + { + /* Compute mixing matrices (energy compensation only) */ + computeMixingMatrices_fx( nX, nY_band, Cx_fx, Cx_e, Cy_fx, Cy_e, proto_matrix_ptr_fx, proto_matrix_ptr_e, 1, PARAM_MC_REG_SX_FX, 0, PARAM_MC_REG_GHAT_FX, 0, mixing_matrix_local_fx, &mixing_matrix_local_e, Cr_fx, &Cr_e ); + } + ELSE + { + /*IF neither decorrelation nor energy compensation is applied*/ + FOR( i = 0; i < nY_band; i++ ) + { + tmp = BASOP_Util_Divide3232_Scale( Cy_fx[i], L_add( Cproto_diag_fx[i], EPSILON_FX ), &tmp_e ); + tmp_e = add( Cy_diag_e, Cproto_diag_e ); + L_tmp = Sqrt32( L_deposit_h( tmp ), &tmp_e ); + Cy_diag_fx[i] = L_tmp; + move32(); + Cy_diag_buff_e[i] = tmp_e; + move16(); + } + + + Cy_diag_e = Cy_diag_buff_e[0]; + move16(); + + FOR( i = 1; i < nY_band; i++ ) + { + if ( LT_16( Cy_diag_e, Cy_diag_buff_e[i] ) ) + { + Cy_diag_e = Cy_diag_buff_e[i]; + move16(); + } + } + + FOR( i = 0; i < nY_band; i++ ) + { + Cy_diag_fx[i] = L_shr( Cy_diag_fx[i], sub( Cy_diag_e, Cy_diag_buff_e[i] ) ); + move32(); + } + + diag_matrix_product_fx( Cy_diag_fx, Cy_diag_e, nY_band, proto_matrix_ptr_fx, proto_matrix_ptr_e, nY_band, nX, 0, mixing_matrix_local_fx, &mixing_matrix_local_e ); + } + + IF( remove_lfe ) + { + set_zero_fx( mixing_matrix_fx[param_band_idx], imult1616( nX, nY_cov ) ); + ptrMM_fx = mixing_matrix_local_fx; + ptrMM_out_fx = mixing_matrix_fx[param_band_idx]; + FOR( ch_idx1 = 0; ch_idx1 < nX; ch_idx1++ ) + { + FOR( lfe_idx1 = 0; lfe_idx1 < hSynthesisOutputSetup->num_lfe + 1; lfe_idx1++ ) + { + FOR( ch_idx2 = lfe_indices[lfe_idx1] + 1; ch_idx2 < lfe_indices[lfe_idx1 + 1]; ch_idx2++ ) + { + *( ptrMM_out_fx++ ) = *( ptrMM_fx++ ); + move32(); + } + ptrMM_out_fx++; + } + ptrMM_out_fx--; + } + + mixing_matrix_e[param_band_idx] = mixing_matrix_local_e; + move16(); + } + ELSE + { + Copy32( mixing_matrix_local_fx, mixing_matrix_fx[param_band_idx], imult1616( nY_cov, nX ) ); + mixing_matrix_e[param_band_idx] = mixing_matrix_local_e; + move16(); + } + + return; +} + + +/*------------------------------------------------------------------------- + * ivas_param_mc_get_mono_stereo_mixing_matrices() + * + * calculate the direct and residual mixing matrices + * for mono and stereo output + *------------------------------------------------------------------------*/ + + +/*------------------------------------------------------------------------- + * param_mc_update_mixing_matrices() + * + * update mixing matrix buffers + *------------------------------------------------------------------------*/ + +static void param_mc_update_mixing_matrices_fx( + PARAM_MC_DEC_HANDLE hParamMC, /* i/o: Parametric MC handle */ + Word32 *mixing_matrix[], /* i : direct mixing matrices for the frame just processed */ + Word16 *mixing_matrix_exp, + Word32 *mixing_matrix_res[], /* i : residual mixing matrices for the frame just processed */ + Word16 *mixing_matrix_res_exp, + const UWord16 nX, /* i : number of transport channels */ + const UWord16 nY ) /* i : number of synthesis channels */ +{ + UWord16 param_band_idx; + + FOR( param_band_idx = 0; param_band_idx < hParamMC->hMetadataPMC->nbands_coded; param_band_idx++ ) + { + Word16 brange[2]; + + brange[0] = hParamMC->band_grouping[param_band_idx]; + move16(); + brange[1] = hParamMC->band_grouping[param_band_idx + 1]; + move16(); + + Copy32( mixing_matrix[param_band_idx], hParamMC->h_output_synthesis_cov_state.mixing_matrix_old_fx[param_band_idx], imult1616( nX, nY ) ); + hParamMC->h_output_synthesis_cov_state.mixing_matrix_old_exp[param_band_idx] = mixing_matrix_exp[param_band_idx]; + move16(); + + IF( LT_16( brange[0], hParamMC->h_output_synthesis_params.max_band_decorr ) ) + { + Copy32( mixing_matrix_res[param_band_idx], hParamMC->h_output_synthesis_cov_state.mixing_matrix_res_old_fx[param_band_idx], imult1616( nY, nY ) ); + hParamMC->h_output_synthesis_cov_state.mixing_matrix_res_old_exp[param_band_idx] = mixing_matrix_res_exp[param_band_idx]; + move16(); + } + } + + return; +} + + +/*------------------------------------------------------------------------- + * ivas_param_mc_dequantize_cov() + * + * generate the target covariance matrix + *------------------------------------------------------------------------*/ + + +/*------------------------------------------------------------------------- + * ivas_param_mc_dequantize_cov_fx() + * + * generate the target covariance matrix + *------------------------------------------------------------------------*/ + +static void ivas_param_mc_dequantize_cov_fx( + PARAM_MC_DEC_HANDLE hParamMC, /* i : Parametric MC handle */ + Word16 *ild_q_fx, /* i : sequence of dequantized ILD values Q8 */ + Word16 *icc_q_fx, /* i : sequence of dequantized ICC values Q15*/ + const Word16 param_band_index, /* i : current parameter band */ + const Word16 nY_cov, /* i : number of output channels in the covariance synthesis */ + const PARAM_MC_SYNTHESIS_CONF synth_conf, /* i : Parametric MC synthesis configuration */ + const Word16 nY_int, /* i : number of channels in the transported format */ + const Word16 nX, /* i : number of transport channels */ + Word32 *Cx_state_fx, /* i : transport channel covariance matrix */ + Word16 Cx_state_e, /* i : exponent for transport channel covariance matrix */ + Word32 *Cproto_fx, /* i : prototype matrix */ + Word16 Cproto_e, /* i : exponent for prototype matrix */ + Word32 *Cy_state_fx, /* o : target covariance matrix */ + Word16 *Cy_state_e /* o : exponent for target covariance matrix */ +) +{ + Word16 Cy_buf_e[MAX_OUTPUT_CHANNELS * MAX_OUTPUT_CHANNELS]; + Word16 Cp_buf_e[MAX_OUTPUT_CHANNELS * MAX_OUTPUT_CHANNELS]; + + Word32 Nrqq_fx[MAX_OUTPUT_CHANNELS]; // Q(31 - Nrqq_e) + Word16 Nrqq_e[MAX_OUTPUT_CHANNELS]; + Word32 a_fx[MAX_OUTPUT_CHANNELS]; // Q(31 - a_e) + Word16 a_e[MAX_OUTPUT_CHANNELS]; + Word16 k; + Word16 l; + Word32 *Cyp_fx; // Q(31 - Cyp_e) + Word16 *Cyp_e; + Word32 ap_fx; // Q(31 - ap_e) + Word16 ap_e; + Word32 L_tmp; + Word16 tmp, tmp_e; + const PARAM_MC_ILD_MAPPING *h_ild_mapping; + Word32 Cy_state_int_fx[MAX_OUTPUT_CHANNELS * MAX_OUTPUT_CHANNELS]; + Word16 Cy_state_int_e[MAX_OUTPUT_CHANNELS * MAX_OUTPUT_CHANNELS]; + + set16_fx( Cp_buf_e, Cproto_e, MAX_OUTPUT_CHANNELS * MAX_OUTPUT_CHANNELS ); + set32_fx( Nrqq_fx, 0, MAX_OUTPUT_CHANNELS ); + set16_fx( Nrqq_e, 0, MAX_OUTPUT_CHANNELS ); + h_ild_mapping = hParamMC->hMetadataPMC->ild_mapping_conf; + + /*get back Nrg*/ + tmp = 0; + move16(); + + FOR( k = 0; k < nY_int; k++ ) + { + Word32 ref_ener_fx = 0; // Q(31 - ref_ener_e) + move32(); + Word16 ref_ener_e = 0; + move16(); + Word16 ref_channel_cnt; + Word16 ref_channel_idx; + + FOR( ref_channel_cnt = 0; ref_channel_cnt < h_ild_mapping->num_ref_channels[k]; ref_channel_cnt++ ) + { + ref_channel_idx = h_ild_mapping->ref_channel_idx[k][ref_channel_cnt]; + move16(); + ref_ener_fx = BASOP_Util_Add_Mant32Exp( Cx_state_fx[ref_channel_idx + ( ref_channel_idx * nX )], Cx_state_e, ref_ener_fx, ref_ener_e, &ref_ener_e ); + move32(); + } + + L_tmp = Mpy_32_16_1( 713378626, ild_q_fx[k] ); /*Q24 : L_tmp Q31 for log2(10)/10 -> 713378626 */ + L_tmp = BASOP_util_Pow2( L_tmp, 31 - 24, &tmp_e ); /*powf( 10.0f, ild_q_fx[k] / 10.0f )*/ + L_tmp = Mpy_32_32( L_tmp, Mpy_32_16_1( ref_ener_fx, hParamMC->hMetadataPMC->ild_factors_fx[k] ) ); + + Nrqq_fx[h_ild_mapping->ild_index[k]] = L_tmp; + move32(); + Nrqq_e[h_ild_mapping->ild_index[k]] = add( tmp_e, ref_ener_e ); + move16(); + } + + /* estimate ICCs from estimated Cproto */ + + FOR( k = 0; k < nY_int; k++ ) + { + // a_fx[k] = 1.f / ( sqrtf( Cproto_fx[k + nY_int * k] ) + EPSILON ); + tmp_e = Cp_buf_e[k + ( nY_int * k )]; + move16(); + + IF( Cproto_fx[k + ( nY_int * k )] != 0 ) + { + L_tmp = ISqrt32( Cproto_fx[k + ( nY_int * k )], &tmp_e ); + } + ELSE + { + L_tmp = INV_EPSILON_MANT; + move32(); + tmp_e = 15; + move16(); + } + a_fx[k] = L_tmp; + move32(); + a_e[k] = tmp_e; + move16(); + + FOR( l = 0; l < nY_int; l++ ) + { + Cy_state_int_fx[( k * nY_int ) + l] = Mpy_32_32( Cproto_fx[( k * nY_int ) + l], a_fx[k] ); + move32(); + Cy_state_int_e[( k * nY_int ) + l] = add( Cp_buf_e[( k * nY_int ) + l], a_e[k] ); + move16(); + } + } + + FOR( k = 0; k < nY_int; k++ ) + { + Cyp_fx = Cy_state_int_fx + k; + Cyp_e = Cy_state_int_e + k; + ap_fx = a_fx[k]; + move32(); + ap_e = a_e[k]; + move16(); + + FOR( l = 0; l < nY_int; l++ ) + { + ( *Cyp_fx ) = Mpy_32_32( *Cyp_fx, ap_fx ); + move32(); + *Cyp_e = add( *Cyp_e, ap_e ); + move16(); + + Cyp_fx += nY_int; + Cyp_e += nY_int; + } + } + + /*normalizing the Cy_state_int_fx to a common exponent*/ + + /* replace some estimated ICCs with transmitted values */ + FOR( k = 0; k < hParamMC->hMetadataPMC->icc_mapping_conf->icc_map_size_lfe; k++ ) + { + Cy_state_int_fx[hParamMC->hMetadataPMC->icc_mapping_conf->icc_mapping[k][0] + ( nY_int * hParamMC->hMetadataPMC->icc_mapping_conf->icc_mapping[k][1] )] = L_shr( L_deposit_h( icc_q_fx[k] ), tmp ); + move32(); + Cy_state_int_e[hParamMC->hMetadataPMC->icc_mapping_conf->icc_mapping[k][0] + ( nY_int * hParamMC->hMetadataPMC->icc_mapping_conf->icc_mapping[k][1] )] = tmp; + move16(); + Cy_state_int_fx[hParamMC->hMetadataPMC->icc_mapping_conf->icc_mapping[k][1] + ( nY_int * hParamMC->hMetadataPMC->icc_mapping_conf->icc_mapping[k][0] )] = L_shr( L_deposit_h( icc_q_fx[k] ), tmp ); + move32(); + Cy_state_int_e[hParamMC->hMetadataPMC->icc_mapping_conf->icc_mapping[k][1] + ( nY_int * hParamMC->hMetadataPMC->icc_mapping_conf->icc_mapping[k][0] )] = tmp; + move16(); + } + + test(); + IF( GE_16( param_band_index, PARAM_MC_MAX_BAND_LFE ) || ( hParamMC->hMetadataPMC->lfe_on == 0 ) ) + { + FOR( k = 0; k < nY_int; k++ ) + { + Cy_state_int_fx[k + ( 3 * nY_int )] = ONE_IN_Q31; + move32(); + Cy_state_int_e[k + ( 3 * nY_int )] = 0; + move16(); + Cy_state_int_fx[3 + ( k * nY_int )] = ONE_IN_Q31; + move32(); + Cy_state_int_e[3 + ( k * nY_int )] = 0; + move16(); + } + Nrqq_fx[3] = 0; + move32(); + } + + /* Generate back Covariance Mtx */ + FOR( k = 0; k < nY_int; k++ ) + { + tmp_e = Nrqq_e[k]; + move16(); + a_fx[k] = Sqrt32( Nrqq_fx[k], &tmp_e ); + move32(); + a_e[k] = tmp_e; + move16(); + + /* v_multc( Cy_state_int_fx + k * nY_int, a_fx[k], Cy_state_int_fx + k * nY_int, nY_int ) */ + FOR( l = 0; l < nY_int; l++ ) + { + Cy_state_int_fx[( k * nY_int ) + l] = Mpy_32_32( Cy_state_int_fx[( k * nY_int ) + l], a_fx[k] ); + move32(); + Cy_state_int_e[( k * nY_int ) + l] = add( Cy_state_int_e[( k * nY_int ) + l], a_e[k] ); + move16(); + } + } + + FOR( k = 0; k < nY_int; k++ ) + { + Cyp_fx = Cy_state_int_fx + k; + Cyp_e = Cy_state_int_e + k; + ap_fx = a_fx[k]; + move32(); + ap_e = a_e[k]; + move16(); + + FOR( l = 0; l < nY_int; l++ ) + { + ( *Cyp_fx ) = Mpy_32_32( *Cyp_fx, ap_fx ); + move32(); + ( *Cyp_e ) = add( *Cyp_e, ap_e ); + move16(); + + Cyp_fx += nY_int; + Cyp_e += nY_int; + } + } + + IF( EQ_32( synth_conf, PARAM_MC_SYNTH_LS_CONV_COV ) ) + { + /* Cy = dmx*Cy*dmx' */ + Word32 mat_mult_buffer1_fx[MAX_CICP_CHANNELS * MAX_CICP_CHANNELS]; // Q(31 - mat_mult_buffer1_e) + Word16 mat_mult_buffer1_e[MAX_CICP_CHANNELS * MAX_CICP_CHANNELS]; + Word32 target_ch_ener_fx[MAX_CICP_CHANNELS]; // Q(31 - target_ch_ener_e) + Word16 target_ch_ener_e[MAX_CICP_CHANNELS]; + Word32 dmx_ch_ener_fx[MAX_CICP_CHANNELS]; + + Word16 ls_conv_dmx_matrix_e[MAX_CICP_CHANNELS * MAX_CICP_CHANNELS]; + + set32_fx( target_ch_ener_fx, 0, MAX_CICP_CHANNELS ); + set16_fx( target_ch_ener_e, 0, MAX_CICP_CHANNELS ); + set32_fx( dmx_ch_ener_fx, 0, MAX_CICP_CHANNELS ); + set16_fx( ls_conv_dmx_matrix_e, 1, MAX_OUTPUT_CHANNELS * MAX_OUTPUT_CHANNELS ); + + matrix_product_mant_exp( hParamMC->ls_conv_dmx_matrix_fx, ls_conv_dmx_matrix_e, nY_cov, nY_int, 0, + Cy_state_int_fx, Cy_state_int_e, nY_int, nY_int, 0, + mat_mult_buffer1_fx, mat_mult_buffer1_e ); + + matrix_product_mant_exp( mat_mult_buffer1_fx, mat_mult_buffer1_e, nY_cov, nY_int, 0, + hParamMC->ls_conv_dmx_matrix_fx, ls_conv_dmx_matrix_e, nY_cov, nY_int, 1, + Cy_state_fx, Cy_buf_e ); + + FOR( k = 0; k < nY_cov; k++ ) + { + FOR( l = 0; l < nY_int; l++ ) + { + L_tmp = Mpy_32_32( hParamMC->ls_conv_dmx_matrix_fx[k + ( l * nY_cov )], Nrqq_fx[l] ); + tmp_e = add( ls_conv_dmx_matrix_e[k + ( l + nY_cov )], Nrqq_e[l] ); + L_tmp = BASOP_Util_Add_Mant32Exp( target_ch_ener_fx[k], target_ch_ener_e[k], L_tmp, tmp_e, &tmp_e ); + target_ch_ener_fx[k] = L_tmp; + move32(); + target_ch_ener_e[k] = tmp_e; + move16(); + } + + dmx_ch_ener_fx[k] = Cy_state_fx[k + ( nY_cov * k )]; + move32(); + + IF( dmx_ch_ener_fx[k] < 0 ) + { + Cy_state_fx[k + ( nY_cov * k )] = L_negate( Cy_state_fx[k + ( nY_cov * k )] ); + move32(); + dmx_ch_ener_fx[k] = L_negate( dmx_ch_ener_fx[k] ); + move32(); + } + + IF( extract_h( dmx_ch_ener_fx[k] ) == 0 ) + { + target_ch_ener_fx[k] = 0; + move32(); + target_ch_ener_e[k] = 0; + move16(); + } + ELSE + { + BASOP_Util_Divide_MantExp( extract_h( target_ch_ener_fx[k] ), target_ch_ener_e[k], extract_h( dmx_ch_ener_fx[k] ), Cy_buf_e[k + ( nY_cov * k )], &tmp, &tmp_e ); + tmp = Sqrt16( tmp, &tmp_e ); + target_ch_ener_fx[k] = L_deposit_h( tmp ); + move32(); + target_ch_ener_e[k] = tmp_e; + move16(); + } + + FOR( l = 0; l < nY_cov; l++ ) + { + Cy_state_fx[( k * nY_cov ) + l] = Mpy_32_32( target_ch_ener_fx[k], Cy_state_fx[( k * nY_cov ) + l] ); + move32(); + Cy_buf_e[( k * nY_cov ) + l] = add( target_ch_ener_e[k], Cy_buf_e[( k * nY_cov ) + l] ); + move16(); + } + + Cyp_fx = Cy_state_fx + k; + Cyp_e = Cy_buf_e + k; + ap_fx = target_ch_ener_fx[k]; + move32(); + ap_e = target_ch_ener_e[k]; + move16(); + FOR( l = 0; l < nY_cov; l++ ) + { + ( *Cyp_fx ) = Mpy_32_32( *Cyp_fx, ap_fx ); + move32(); + *Cyp_e = add( *Cyp_e, ap_e ); + move16(); + + Cyp_fx += nY_cov; + Cyp_e += nY_cov; + } + } + } + ELSE + { + Copy32( Cy_state_int_fx, Cy_state_fx, imult1616( nY_int, nY_int ) ); + Copy( Cy_state_int_e, Cy_buf_e, imult1616( nY_int, nY_int ) ); + } + + /*normalize output matrix to a common exponent*/ + tmp = 0; + FOR( k = 0; k < nY_int * nY_int; k++ ) + { + Cy_state_fx[k] = BASOP_Util_Add_Mant32Exp( Cy_state_fx[k], Cy_buf_e[k], 0, 0, &Cy_buf_e[k] ); + move32(); + tmp = s_max( tmp, Cy_buf_e[k] ); + } + FOR( k = 0; k < nY_int * nY_int; k++ ) + { + L_tmp = L_shr( Cy_state_fx[k], sub( tmp, Cy_buf_e[k] ) ); + Cy_state_fx[k] = L_tmp; + move32(); + } + *Cy_state_e = tmp; + move16(); + + return; +} + +/*-------------------------------------------------------------------------* + * param_mc_set_num_synth_bands() + * + * set the number of frequency bands to be synthesized + *-------------------------------------------------------------------------*/ + +static void param_mc_set_num_synth_bands( + const Word32 output_Fs, /* i : output sampling frequency */ + PARAM_MC_DEC_HANDLE hParamMC /* i/o: Parametric MC handle */ +) +{ + UWord16 max_param_band_synth; + const Word16 *param_mc_bands_coded; + + SWITCH( hParamMC->hMetadataPMC->num_parameter_bands ) + { + case 20: + param_mc_bands_coded = param_mc_bands_coded_20; + BREAK; + case 10: + param_mc_bands_coded = param_mc_bands_coded_10; + BREAK; + case 14: + default: + param_mc_bands_coded = param_mc_bands_coded_14; + BREAK; + } + move16(); + SWITCH( output_Fs ) + { + case 8000: + max_param_band_synth = (UWord16) param_mc_bands_coded[NB]; + BREAK; + case 16000: + max_param_band_synth = (UWord16) param_mc_bands_coded[WB]; + BREAK; + case 32000: + max_param_band_synth = (UWord16) param_mc_bands_coded[SWB]; + BREAK; + case 48000: + default: + max_param_band_synth = (UWord16) param_mc_bands_coded[FB]; + BREAK; + } + move16(); + hParamMC->num_param_bands_synth = s_min( hParamMC->hMetadataPMC->nbands_coded, max_param_band_synth ); + move16(); + + return; +} + + +/*-------------------------------------------------------------------------* + * param_mc_get_diff_proto_info() + * + * calculated the diffuse prototype information + *-------------------------------------------------------------------------*/ + + +static ivas_error param_mc_get_diff_proto_info_fx( + const Word32 *proto_mtx, /* i : protoype matrix for the synthesis */ + const UWord16 nchan_transport, /* i : number of transport channels */ + const UWord16 nchan_out_cov, /* i : number if output channels of the covariance synthesis */ + PARAM_MC_DIFF_PROTO_INFO *p_diff_proto_info, /* o : generated diffuse prototype info */ + Word16 Q_proto_mtx ) +{ + Word32 proto_fac_fx[MAX_CICP_CHANNELS * PARAM_MC_MAX_TRANSPORT_CHANS]; + UWord16 cur_out_ch; + UWord16 cur_diff_proto; + UWord16 cur_transport_ch; + UWord16 max_num_src_chan; + + /* Initializations */ + max_num_src_chan = 0; + move16(); + + set_zero_fx( proto_fac_fx, MAX_CICP_CHANNELS * PARAM_MC_MAX_TRANSPORT_CHANS ); + IF( ( p_diff_proto_info->proto_index_diff = (Word16 *) malloc( nchan_out_cov * sizeof( Word16 ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Parametric MC\n" ) ); + } + set16_fx( p_diff_proto_info->proto_index_diff, 0, nchan_out_cov ); + + IF( ( p_diff_proto_info->num_source_chan_diff = (Word16 *) malloc( nchan_out_cov * sizeof( Word16 ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Parametric MC\n" ) ); + } + set16_fx( p_diff_proto_info->num_source_chan_diff, 0, nchan_out_cov ); + + /* we have at least one prototype, copy the first one */ + p_diff_proto_info->num_protos_diff = 1; + move16(); + + mvr2r_inc_fixed( proto_mtx, nchan_out_cov, proto_fac_fx, nchan_out_cov, nchan_transport ); + p_diff_proto_info->proto_index_diff[0] = 0; + move16(); + + /* search for distinct prototypes */ + FOR( cur_out_ch = 1; cur_out_ch < nchan_out_cov; cur_out_ch++ ) + { + UWord16 found = 0; + move16(); + + FOR( cur_diff_proto = 0; cur_diff_proto < p_diff_proto_info->num_protos_diff; cur_diff_proto++ ) + { + Word32 diff_fx = 0; + move32(); + Word32 *proto_fac_ptr_fx = proto_fac_fx + cur_diff_proto; + const Word32 *proto_mtx_ptr = proto_mtx + cur_out_ch; + FOR( cur_transport_ch = 0; cur_transport_ch < nchan_transport; cur_transport_ch++ ) + { + diff_fx = L_add( diff_fx, L_abs( L_sub( *proto_fac_ptr_fx, *proto_mtx_ptr ) ) ); + proto_fac_ptr_fx += nchan_out_cov; + proto_mtx_ptr += nchan_out_cov; + } + + /* we already have this prototype, save the index */ + IF( LT_64( W_mult0_32_32( diff_fx, 10 ), L_shl_sat( 1, Q_proto_mtx ) ) ) + { + found = 1; + move16(); + p_diff_proto_info->proto_index_diff[cur_out_ch] = cur_diff_proto; + move16(); + BREAK; + } + } + + /* new distinct prototype, add it */ + IF( found == 0 ) + { + const Word32 *proto_mtx_ptr = proto_mtx + cur_out_ch; + Word16 cur_num_src_chan; + + cur_num_src_chan = 0; + move16(); + FOR( cur_transport_ch = 0; cur_transport_ch < nchan_transport; cur_transport_ch++ ) + { + if ( GT_32( *proto_mtx_ptr, 0 /*EPSILON*/ ) ) + { + cur_num_src_chan = add( cur_num_src_chan, 1 ); + } + proto_mtx_ptr += nchan_out_cov; + } + + mvr2r_inc_fixed( proto_mtx + cur_out_ch, nchan_out_cov, proto_fac_fx + p_diff_proto_info->num_protos_diff, nchan_out_cov, nchan_transport ); + + p_diff_proto_info->proto_index_diff[cur_out_ch] = p_diff_proto_info->num_protos_diff; + move16(); + p_diff_proto_info->num_protos_diff = add( p_diff_proto_info->num_protos_diff, 1 ); + move16(); + max_num_src_chan = s_max( max_num_src_chan, cur_num_src_chan ); + } + } + + /* set up the prototype info struct */ + IF( ( p_diff_proto_info->source_chan_idx = (Word16 **) malloc( p_diff_proto_info->num_protos_diff * sizeof( Word16 * ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Parametric MC\n" ) ); + } + + IF( ( p_diff_proto_info->proto_fac_fx = (Word32 **) malloc( p_diff_proto_info->num_protos_diff * sizeof( Word32 * ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Parametric MC\n" ) ); + } + FOR( cur_diff_proto = 0; cur_diff_proto < p_diff_proto_info->num_protos_diff; cur_diff_proto++ ) + { + Word32 *proto_fac_ptr; + + IF( ( p_diff_proto_info->source_chan_idx[cur_diff_proto] = (Word16 *) malloc( max_num_src_chan * sizeof( Word16 ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Parametric MC\n" ) ); + } + + IF( ( p_diff_proto_info->proto_fac_fx[cur_diff_proto] = (Word32 *) malloc( max_num_src_chan * sizeof( Word32 ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Parametric MC\n" ) ); + } + + proto_fac_ptr = proto_fac_fx + cur_diff_proto; + FOR( cur_transport_ch = 0; cur_transport_ch < nchan_transport; cur_transport_ch++ ) + { + IF( GT_32( *proto_fac_ptr, EPSILON_FX_SMALL ) ) + { + p_diff_proto_info->source_chan_idx[cur_diff_proto][p_diff_proto_info->num_source_chan_diff[cur_diff_proto]] = cur_transport_ch; + move16(); + p_diff_proto_info->proto_fac_fx[cur_diff_proto][p_diff_proto_info->num_source_chan_diff[cur_diff_proto]] = L_shl( *proto_fac_ptr, 4 ); // (proto_fac_fx)Q26 + 4 = Q30 + move16(); + p_diff_proto_info->num_source_chan_diff[cur_diff_proto] = add( p_diff_proto_info->num_source_chan_diff[cur_diff_proto], 1 ); + move16(); + } + proto_fac_ptr += nchan_out_cov; + } + } + return IVAS_ERR_OK; +} + + +/*-------------------------------------------------------------------------* + * ivas_param_mc_bs_decode_parameter_values() + * + * reads and decodes a sequence of Parametric MC parameters from the bitstream + *-------------------------------------------------------------------------*/ + +static void ivas_param_mc_bs_decode_parameter_values_fx( + UWord16 bit_buffer[], /* i : bitstream buffer */ + Word16 *bit_pos, /* i/o: current bitstream buffer position */ + const Word16 max_bits, /* i : maximum available bits in the buffer */ + Word16 *BER_detect, /* i/o: bit error detection flag */ + HANDLE_IVAS_PARAM_MC_METADATA hMetadataPMC, /* i : Parametric MC metadata information */ + HANDLE_PARAM_MC_PARAMETER_CODING_INFO hParamCodingInfo, /* i : Parametric MC parameter quantization and coding tables */ + const Word16 map_size_wo_lfe, /* i : number of parameters per band (w/o LFEs) */ + const Word16 map_size, /* i : number of parameters per band (total) */ + const Word16 num_lfe_bands, /* i : number of parameter bands with coded LFE */ + const Word16 band_step, /* i : parameter band step */ + const Word16 num_param_bands, /* i : number of parameter bands to decode */ + Word16 *value_buffer /* o : output buffer for decoded parameter values hParamCodingInfo -> Q-quant*/ +) +{ + Word16 range_coding; + Word16 sz_seq; + Word16 delta_coding; + Word16 delta_idx[PARAM_MC_MAX_PARAMETER_BANDS * PARAM_MC_MAX_VAL_MAP_SIZE]; + Word16 idx[PARAM_MC_MAX_PARAMETER_BANDS * PARAM_MC_MAX_VAL_MAP_SIZE]; + Word16 idx_prev; + Word16 idx_offset; + Word16 sz_alphabet; + Word16 i, j, k; + Word16 dequant_seq_fx[PARAM_MC_MAX_PARAMETER_BANDS * PARAM_MC_MAX_VAL_MAP_SIZE]; + Word16 dequant_ordered_fx[PARAM_MC_MAX_PARAMETER_BANDS * PARAM_MC_MAX_VAL_MAP_SIZE]; + Word16 n_lfe_idx; + + range_coding = bit_buffer[*bit_pos]; + move16(); + *bit_pos = add( *bit_pos, 1 ); + move16(); + + /* Decoding the sequence */ + n_lfe_idx = sub( map_size, map_size_wo_lfe ); + sz_seq = add( imult1616( num_param_bands, map_size_wo_lfe ), imult1616( num_lfe_bands, n_lfe_idx ) ); + + set16_fx( idx, 0, PARAM_MC_MAX_PARAMETER_BANDS * PARAM_MC_MAX_VAL_MAP_SIZE ); + set16_fx( dequant_ordered_fx, 0, PARAM_MC_MAX_PARAMETER_BANDS * PARAM_MC_MAX_VAL_MAP_SIZE ); + set16_fx( dequant_seq_fx, 0, PARAM_MC_MAX_PARAMETER_BANDS * PARAM_MC_MAX_VAL_MAP_SIZE ); + IF( range_coding ) + { + delta_coding = bit_buffer[*bit_pos]; + move16(); + *bit_pos = add( *bit_pos, 1 ); + move16(); + + IF( delta_coding ) + { + idx_prev = sub( add( shr( hParamCodingInfo->quantizer_size, 1 ), hParamCodingInfo->quantizer_size % 2 ), 1 ); + sz_alphabet = sub( shl( hParamCodingInfo->quantizer_size, 1 ), 1 ); + idx_offset = sub( hParamCodingInfo->quantizer_size, 1 ); + + /* read range coded delta ICC indices */ + *bit_pos = add( *bit_pos, ivas_param_mc_range_decoder_LC_fx( &bit_buffer[*bit_pos], delta_idx, BER_detect, sz_seq, sz_alphabet, + hParamCodingInfo->cum_freq_delta, hParamCodingInfo->sym_freq_delta, PARAM_MC_RANGE_CODER_TOT_SHIFT, sub( max_bits, *bit_pos ) ) ); + move16(); + + /* delta index to absolute index */ + FOR( j = 0; j < sz_seq; j++ ) + { + idx[j] = add( idx_prev, sub( delta_idx[j], idx_offset ) ); + idx_prev = idx[j]; + move16(); + } + } + ELSE + { + /* read range coded absolute ICC indices */ + sz_alphabet = hParamCodingInfo->quantizer_size; + move16(); + *bit_pos = add( *bit_pos, ivas_param_mc_range_decoder_LC_fx( &bit_buffer[*bit_pos], idx, BER_detect, sz_seq, sz_alphabet, + hParamCodingInfo->cum_freq, hParamCodingInfo->sym_freq, PARAM_MC_RANGE_CODER_TOT_SHIFT, sub( max_bits, *bit_pos ) ) ); + move16(); + } + + /* dequantize */ + FOR( j = 0; j < sz_seq; j++ ) + { + dequant_seq_fx[j] = hParamCodingInfo->quantizer_fx[idx[j]]; // hParamCodingInfo -> Q-quant + move16(); + } + } + ELSE + { + set16_fx( dequant_seq_fx, 0, PARAM_MC_MAX_PARAMETER_BANDS * PARAM_MC_MAX_VAL_MAP_SIZE ); + /* read uniformly coded ICCs */ + *bit_pos = add( *bit_pos, ivas_param_mc_uniform_decoder_fx( dequant_seq_fx, sz_seq, hParamCodingInfo->quantizer_fx, hParamCodingInfo->uni_bits, &bit_buffer[*bit_pos] ) ); + move16(); + } + + /* reorder from sequential to parameter-band-wise */ + k = 0; + FOR( j = 0; j < map_size_wo_lfe; ++j ) + { + FOR( i = 0; i < num_param_bands; ++i ) + { + dequant_ordered_fx[j + ( i * map_size )] = dequant_seq_fx[k]; // hParamCodingInfo -> Q-quant + move16(); + k = add( k, 1 ); + } + } + + FOR( i = 0; i < num_lfe_bands; i++ ) + { + FOR( j = 0; j < n_lfe_idx; j++ ) + { + dequant_ordered_fx[map_size - n_lfe_idx + j + i * map_size] = dequant_seq_fx[k]; // hParamCodingInfo -> Q-quant + move16(); + k = add( k, 1 ); + } + } + + IF( !( *BER_detect ) ) + { + j = 0; + FOR( k = 0; k < hMetadataPMC->nbands_coded; k += band_step ) + { + test(); + IF( hMetadataPMC->bAttackPresent || EQ_16( hMetadataPMC->param_frame_idx, hMetadataPMC->coding_band_mapping[k] ) ) + { + Copy( dequant_ordered_fx + imult1616( j, map_size ), value_buffer + imult1616( k, map_size ), map_size ); // hParamCodingInfo -> Q-quant + j++; + } + IF( hMetadataPMC->bAttackPresent && k + 1 < hMetadataPMC->nbands_coded ) + { + Copy( value_buffer + imult1616( k, map_size ), value_buffer + imult1616( add( k, 1 ), map_size ), map_size ); + } + } + } + + return; +} + Word16 param_mc_get_num_cldfb_syntheses_ivas_fx( Decoder_Struct *st_ivas /* i : Parametric MC handle */ ) diff --git a/lib_dec/ivas_mc_paramupmix_dec.c b/lib_dec/ivas_mc_paramupmix_dec_fx.c similarity index 91% rename from lib_dec/ivas_mc_paramupmix_dec.c rename to lib_dec/ivas_mc_paramupmix_dec_fx.c index c1bf455a5f60063f955fff29a969e716e2b9aba9..3b7bfd3e2864e04ebd9e8a9170733e07fd1a27fa 100644 --- a/lib_dec/ivas_mc_paramupmix_dec.c +++ b/lib_dec/ivas_mc_paramupmix_dec_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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,11 +34,9 @@ #include #include "options.h" #include "cnst.h" -#include "prot.h" #include "prot_fx.h" #include "ivas_prot_fx.h" -#include "ivas_prot.h" -#include "ivas_prot_rend.h" +#include "ivas_prot_rend_fx.h" #include "ivas_cnst.h" #include "rom_com.h" #include "ivas_rom_com.h" @@ -133,7 +131,8 @@ void ivas_mc_paramupmix_dec_read_BS( nb_bits_read_orig = 0; move16(); last_bit_pos = sub( last_bit_pos, nb_bits_read_orig ); /* reverse the bitstream for easier reading of indices */ - FOR( i = 0; i < min( MAX_BITS_METADATA, last_bit_pos ); i++ ) + Word16 len = s_min( MAX_BITS_METADATA, last_bit_pos ); + FOR( i = 0; i < len; i++ ) { bstr_meta[i] = st_ivas->bit_stream[last_bit_pos - i]; move16(); @@ -270,7 +269,8 @@ void ivas_mc_paramupmix_dec_render( ivas_mc_paramupmix_dec_sf( st_ivas, output_local_fx ); - FOR( ch = 0; ch < min( MAX_OUTPUT_CHANNELS, ivas_get_nchan_buffers_dec( st_ivas, -1, -1 ) ); ch++ ) + Word16 num_ch = s_min( MAX_OUTPUT_CHANNELS, ivas_get_nchan_buffers_dec( st_ivas, -1, -1 ) ); + FOR( ch = 0; ch < num_ch; ch++ ) { output_local_fx[ch] += n_samples_sf; } @@ -418,7 +418,7 @@ ivas_error ivas_mc_paramupmix_dec_open( move16(); } - IF( NE_32( ( error = ivas_jbm_dec_tc_buffer_open_fx( st_ivas, buffer_mode, nchan_tc, nchan_to_allocate, nchan_to_allocate, NS2SA( st_ivas->hDecoderConfig->output_Fs, CLDFB_SLOT_NS ) ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = ivas_jbm_dec_tc_buffer_open_fx( st_ivas, buffer_mode, nchan_tc, nchan_to_allocate, nchan_to_allocate, NS2SA_FX2( st_ivas->hDecoderConfig->output_Fs, CLDFB_SLOT_NS ) ) ), IVAS_ERR_OK ) ) { return error; } @@ -723,13 +723,24 @@ static void ivas_mc_paramupmix_dec_sf( Word32 Cldfb_RealBuffer_subfr_fx[MAX_INTERN_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX]; Word32 Cldfb_ImagBuffer_subfr_fx[MAX_INTERN_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX]; #endif // MSAN_FIX + +#ifdef SPLIT_REND_WITH_HEAD_ROT + Word32 Cldfb_RealBuffer_Binaural_fx[MAX_HEAD_ROT_POSES][BINAURAL_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX]; + Word32 Cldfb_ImagBuffer_Binaural_fx[MAX_HEAD_ROT_POSES][BINAURAL_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX]; + int16_t slot_index_start; +#else Word32 Cldfb_RealBuffer_Binaural_fx[BINAURAL_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX]; Word32 Cldfb_ImagBuffer_Binaural_fx[BINAURAL_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX]; +#endif hMCParamUpmix = st_ivas->hMCParamUpmix; assert( hMCParamUpmix ); push_wmops( "ivas_mc_paramupmix_dec_sf" ); +#ifdef SPLIT_REND_WITH_HEAD_ROT + slot_index_start = st_ivas->hTcBuffer->slots_rendered; +#endif + FOR( i = 0; i < MC_PARAMUPMIX_COMBINATIONS; i++ ) { pPcm_temp_fx[2 * i] = output_fx[i + 4]; /* un-decorrelated Q11*/ @@ -844,14 +855,53 @@ static void ivas_mc_paramupmix_dec_sf( Word16 input_q = 6; move16(); + +#ifdef SPLIT_REND_WITH_HEAD_ROT + /*LFE handling for split rendering cases*/ + IF( EQ_16( st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) || EQ_16( st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ) + { + IF( st_ivas->hSplitBinRend->hCldfbDataOut != NULL ) + { + FOR( slot_idx = 0; slot_idx < st_ivas->hTcBuffer->subframe_nbslots[st_ivas->hTcBuffer->subframes_rendered]; slot_idx++ ) + { + FOR( ch = 0; ch < ( st_ivas->hIntSetup.nchan_out_woLFE + st_ivas->hIntSetup.num_lfe ); ch++ ) + { + Copy32( Cldfb_RealBuffer_subfr_fx[ch][slot_idx], st_ivas->hSplitBinRend->hCldfbDataOut->Cldfb_RealBuffer_fx[ch][add( slot_index_start, slot_idx )], maxBand ); + Copy32( Cldfb_ImagBuffer_subfr_fx[ch][slot_idx], st_ivas->hSplitBinRend->hCldfbDataOut->Cldfb_ImagBuffer_fx[ch][add( slot_index_start, slot_idx )], maxBand ); + } + } + + st_ivas->hSplitBinRend->hCldfbDataOut->config = st_ivas->hIntSetup.output_config; + move16(); + } + } +#endif + /* Implement binaural rendering */ ivas_binRenderer_fx( st_ivas->hBinRenderer, +#ifdef SPLIT_REND_WITH_HEAD_ROT + ( st_ivas->hSplitBinRend == NULL ) ? NULL : &st_ivas->hSplitBinRend->splitrend.multiBinPoseData, +#endif st_ivas->hCombinedOrientationData, st_ivas->hTcBuffer->subframe_nbslots[subframeIdx], Cldfb_RealBuffer_Binaural_fx, Cldfb_ImagBuffer_Binaural_fx, Cldfb_RealBuffer_subfr_fx, Cldfb_ImagBuffer_subfr_fx, &input_q ); +#ifdef SPLIT_REND_WITH_HEAD_ROT + int16_t pos_idx; + FOR( pos_idx = 0; pos_idx < st_ivas->hBinRenderer->numPoses; pos_idx++ ) + { + FOR( Word16 idx1 = 0; idx1 < BINAURAL_CHANNELS; idx1++ ) + { + FOR( Word16 idx2 = 0; idx2 < MAX_PARAM_SPATIAL_SUBFRAMES; idx2++ ) + { + Scale_sig32( Cldfb_RealBuffer_Binaural_fx[pos_idx][idx1][idx2], CLDFB_NO_CHANNELS_MAX, sub( 6, input_q ) ); // Q6 + Scale_sig32( Cldfb_ImagBuffer_Binaural_fx[pos_idx][idx1][idx2], CLDFB_NO_CHANNELS_MAX, sub( 6, input_q ) ); // Q6 + } + } + } +#else FOR( Word16 idx1 = 0; idx1 < BINAURAL_CHANNELS; idx1++ ) { FOR( Word16 idx2 = 0; idx2 < MAX_PARAM_SPATIAL_SUBFRAMES; idx2++ ) @@ -860,6 +910,25 @@ static void ivas_mc_paramupmix_dec_sf( Scale_sig32( Cldfb_ImagBuffer_Binaural_fx[idx1][idx2], CLDFB_NO_CHANNELS_MAX, sub( 6, input_q ) ); // Q6 } } +#endif + +#ifdef SPLIT_REND_WITH_HEAD_ROT + IF( EQ_16( st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) || EQ_16( st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ) + { + FOR( pos_idx = 0; pos_idx < st_ivas->hBinRenderer->numPoses; pos_idx++ ) + { + FOR( slot_idx = 0; slot_idx < st_ivas->hTcBuffer->subframe_nbslots[subframeIdx]; slot_idx++ ) + { + FOR( ch = 0; ch < st_ivas->hDecoderConfig->nchan_out; ch++ ) + { + Copy32( Cldfb_RealBuffer_Binaural_fx[pos_idx][ch][slot_idx], st_ivas->hSplitBinRend->hMultiBinCldfbData->Cldfb_RealBuffer_Binaural_fx[add( i_mult( pos_idx, BINAURAL_CHANNELS ), ch )][add( slot_index_start, slot_idx )], maxBand ); + Copy32( Cldfb_ImagBuffer_Binaural_fx[pos_idx][ch][slot_idx], st_ivas->hSplitBinRend->hMultiBinCldfbData->Cldfb_ImagBuffer_Binaural_fx[add( i_mult( pos_idx, BINAURAL_CHANNELS ), ch )][add( slot_index_start, slot_idx )], maxBand ); + } + } + } + } +#endif + /* Implement CLDFB synthesis */ FOR( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) { @@ -868,8 +937,13 @@ static void ivas_mc_paramupmix_dec_sf( FOR( slot_idx = 0; slot_idx < st_ivas->hTcBuffer->subframe_nbslots[subframeIdx]; slot_idx++ ) { +#ifdef SPLIT_REND_WITH_HEAD_ROT + RealBuffer_fx[slot_idx] = Cldfb_RealBuffer_Binaural_fx[0][ch][slot_idx]; // Q6 + ImagBuffer_fx[slot_idx] = Cldfb_ImagBuffer_Binaural_fx[0][ch][slot_idx]; // Q6 +#else RealBuffer_fx[slot_idx] = Cldfb_RealBuffer_Binaural_fx[ch][slot_idx]; // Q6 ImagBuffer_fx[slot_idx] = Cldfb_ImagBuffer_Binaural_fx[ch][slot_idx]; // Q6 +#endif } scale_sig32( st_ivas->cldfbSynDec[ch]->cldfb_state_fx, st_ivas->cldfbSynDec[ch]->cldfb_size, Q5 - Q11 ); // Q11 -> Q5 st_ivas->cldfbSynDec[ch]->Q_cldfb_state = Q5; diff --git a/lib_dec/ivas_mcmasa_dec.c b/lib_dec/ivas_mcmasa_dec_fx.c similarity index 97% rename from lib_dec/ivas_mcmasa_dec.c rename to lib_dec/ivas_mcmasa_dec_fx.c index 3f5f1d098dbd6de796b595fa37ae5f0c1bf553f1..d12b190c640728b55825a1a5a4b948591e481b70 100644 --- a/lib_dec/ivas_mcmasa_dec.c +++ b/lib_dec/ivas_mcmasa_dec_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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,8 @@ #include "options.h" #include #include "ivas_cnst.h" -#include "ivas_prot.h" -#include "ivas_prot_rend.h" -#include "prot.h" +#include "ivas_prot_rend_fx.h" +#include "prot_fx.h" #include "wmc_auto.h" #include "ivas_prot_fx.h" diff --git a/lib_dec/ivas_mct_core_dec.c b/lib_dec/ivas_mct_core_dec_fx.c similarity index 96% rename from lib_dec/ivas_mct_core_dec.c rename to lib_dec/ivas_mct_core_dec_fx.c index 7c4c3743c3a0ebea5f91e9d9722861601c0d0d00..b42eb534b34af52b78b359306728ea7fd919f4a3 100644 --- a/lib_dec/ivas_mct_core_dec.c +++ b/lib_dec/ivas_mct_core_dec_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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,16 +33,14 @@ #include #include #include "options.h" -#include "prot.h" +#include "prot_fx.h" #include "rom_com.h" #include "wmc_auto.h" #include "cnst.h" #include "basop_proto_func.h" #include "stat_com.h" -#include "ivas_prot.h" #include "ivas_stat_dec.h" #include "ivas_stat_com.h" -#include "prot_fx.h" #include "ivas_prot_fx.h" /*-----------------------------------------------------------------* @@ -90,9 +88,9 @@ void ivas_mct_side_bits_fx( FOR( ch = 0; ch < nChannels; ch++ ) { st = sts[ch]; - if ( EQ_32( st->mct_chan_mode, MCT_CHAN_MODE_IGNORE ) ) + IF( EQ_32( st->mct_chan_mode, MCT_CHAN_MODE_IGNORE ) ) { - continue; + CONTINUE; } mdct_read_IGF_bits_fx( st, st0 ); @@ -233,7 +231,7 @@ void ivas_mct_core_dec( { IF( EQ_32( sts[ch]->mct_chan_mode, MCT_CHAN_MODE_IGNORE ) ) { - continue; + CONTINUE; } i = add( i, 1 ); } @@ -260,15 +258,15 @@ void ivas_mct_core_dec( { st = sts[ch]; - if ( EQ_32( sts[ch]->mct_chan_mode, MCT_CHAN_MODE_IGNORE ) ) /*indicates LFE */ + IF( EQ_32( sts[ch]->mct_chan_mode, MCT_CHAN_MODE_IGNORE ) ) /*indicates LFE */ { - continue; + CONTINUE; } test(); - if ( bfi && EQ_16( st->core, ACELP_CORE ) ) /*no igf processing needed*/ + IF( bfi && EQ_16( st->core, ACELP_CORE ) ) /*no igf processing needed*/ { - continue; + CONTINUE; } IF( EQ_16( st->core, TCX_10_CORE ) ) diff --git a/lib_dec/ivas_mct_dec.c b/lib_dec/ivas_mct_dec_fx.c similarity index 91% rename from lib_dec/ivas_mct_dec.c rename to lib_dec/ivas_mct_dec_fx.c index f3afead8fe1b8c7a8c86783f0c498986ebff91c5..31fbdadd86663c61f0529cbb1cfed7716bd5288d 100644 --- a/lib_dec/ivas_mct_dec.c +++ b/lib_dec/ivas_mct_dec_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other @@ -38,9 +38,7 @@ #include "ivas_cnst.h" #include "rom_com.h" #include "prot_fx.h" -#include "prot.h" -#include "ivas_prot.h" -#include "ivas_prot_rend.h" +#include "ivas_prot_rend_fx.h" #include "ivas_rom_com.h" #include "wmc_auto.h" #include "ivas_prot_fx.h" @@ -86,6 +84,10 @@ ivas_error ivas_mct_dec_fx( set16_fx( x_len[0], 0, NB_DIV ); set16_fx( x_len[1], 0, NB_DIV ); Decoder_State **sts; +#ifdef NONBE_FIX_1087_OOB_SBA_DTX_RS + Word32 *p_output_orig_fx[2]; + Word32 synth_32_fx[CPE_CHANNELS][L_FRAME_PLUS]; +#endif Word16 synth_fx[CPE_CHANNELS][L_FRAME_PLUS]; //(Q_synth) Word32 ivas_total_brate; ivas_error error; @@ -162,6 +164,18 @@ ivas_error ivas_mct_dec_fx( /* MCT side bits decoder */ ivas_mct_side_bits_fx( hMCT, st_ivas->hCPE, nCPE, st_ivas->hCPE[0]->hCoreCoder[0], st_ivas->bfi, st_ivas->hCPE[0]->hCoreCoder[0]->bit_stream, ivas_total_brate, nb_bits_metadata ); +#ifdef NONBE_FIX_1087_OOB_SBA_DTX_RS + /* in case of switching from an SID frame (with ACELP core) to MCT, buffer of L_FRAME_PLUS samples is needed -> use synth[] as a temporary buffer */ + IF( st_ivas->hCPE[0]->hCoreCoder[0]->last_core == ACELP_CORE ) + { + FOR( n = 0; n < CPE_CHANNELS; n++ ) + { + p_output_orig_fx[n] = output_fx[n]; + output_fx[n] = synth_32_fx[n]; + } + } +#endif + FOR( cpe_id = 0; cpe_id < nCPE; cpe_id++ ) { st_ivas->hCPE[cpe_id]->hCoreCoder[0]->BER_detect = s_or( st_ivas->hCPE[cpe_id]->hCoreCoder[0]->BER_detect, st_ivas->BER_detect ); @@ -250,9 +264,9 @@ ivas_error ivas_mct_dec_fx( FOR( n = 0; n < CPE_CHANNELS; n++ ) { - Copy_Scale_sig_16_32( Aq_fx[cpe_id][n], Aq_fx_32[cpe_id][n], 102, Q16 - Q12 ); // Q16 - x_fx[n][0] = output_fx[n + ( cpe_id * CPE_CHANNELS )]; // Q11 - x_fx[n][1] = output_fx[n + ( cpe_id * CPE_CHANNELS )] + ( L_FRAME48k / 2 ); // Q11 + Copy_Scale_sig_16_32_DEPREC( Aq_fx[cpe_id][n], Aq_fx_32[cpe_id][n], 102, Q16 - Q12 ); // Q16 + x_fx[n][0] = output_fx[n + ( cpe_id * CPE_CHANNELS )]; // Q11 + x_fx[n][1] = output_fx[n + ( cpe_id * CPE_CHANNELS )] + ( L_FRAME48k / 2 ); // Q11 x_e[n][0] = 20; move16(); move16(); @@ -334,10 +348,13 @@ ivas_error ivas_mct_dec_fx( x_fx[n][0] = output_fx[n + ( cpe_id * CPE_CHANNELS )]; // Q11 x_fx[n][1] = output_fx[n + ( cpe_id * CPE_CHANNELS )] + ( L_FRAME48k / 2 ); // Q11 } - - Copy_Scale_sig_16_32( hCPE->hCoreCoder[0]->old_Aq_12_8_fx, hCPE->hCoreCoder[0]->old_Aq_12_8_fx_32, add( M, 1 ), sub( 28, norm_s( sub( hCPE->hCoreCoder[0]->old_Aq_12_8_fx[0], 1 ) ) ) ); - Copy_Scale_sig_16_32( hCPE->hCoreCoder[1]->old_Aq_12_8_fx, hCPE->hCoreCoder[1]->old_Aq_12_8_fx_32, add( M, 1 ), sub( 28, norm_s( sub( hCPE->hCoreCoder[1]->old_Aq_12_8_fx[0], 1 ) ) ) ); - +#ifdef FIX_ISSUE_1237 + Copy_Scale_sig_16_32_no_sat( hCPE->hCoreCoder[0]->old_Aq_12_8_fx, hCPE->hCoreCoder[0]->old_Aq_12_8_fx_32, add( M, 1 ), sub( 28, sub( 15, norm_s( sub( hCPE->hCoreCoder[0]->old_Aq_12_8_fx[0], 1 ) ) ) ) ); + Copy_Scale_sig_16_32_no_sat( hCPE->hCoreCoder[1]->old_Aq_12_8_fx, hCPE->hCoreCoder[1]->old_Aq_12_8_fx_32, add( M, 1 ), sub( 28, sub( 15, norm_s( sub( hCPE->hCoreCoder[1]->old_Aq_12_8_fx[0], 1 ) ) ) ) ); +#else + Copy_Scale_sig_16_32_DEPREC( hCPE->hCoreCoder[0]->old_Aq_12_8_fx, hCPE->hCoreCoder[0]->old_Aq_12_8_fx_32, add( M, 1 ), sub( 28, norm_s( sub( hCPE->hCoreCoder[0]->old_Aq_12_8_fx[0], 1 ) ) ) ); + Copy_Scale_sig_16_32_DEPREC( hCPE->hCoreCoder[1]->old_Aq_12_8_fx, hCPE->hCoreCoder[1]->old_Aq_12_8_fx_32, add( M, 1 ), sub( 28, norm_s( sub( hCPE->hCoreCoder[1]->old_Aq_12_8_fx[0], 1 ) ) ) ); +#endif ivas_mdct_core_reconstruct_fx( hCPE, x_fx, synth_fx, fUseTns[cpe_id], 1, q_output, e_sig ); Word16 hdrm, sh; @@ -368,6 +385,18 @@ ivas_error ivas_mct_dec_fx( } } +#ifdef NONBE_FIX_1087_OOB_SBA_DTX_RS + /* set pointers back */ + test(); + IF( cpe_id == 0 && st_ivas->hCPE[0]->hCoreCoder[0]->last_core == ACELP_CORE ) + { + FOR( n = 0; n < CPE_CHANNELS; n++ ) + { + output_fx[n] = p_output_orig_fx[n]; + } + } + +#endif /*----------------------------------------------------------------* * CoreCoder Post-processing and updates @@ -380,9 +409,13 @@ ivas_error ivas_mct_dec_fx( test(); IF( ( st_ivas->sba_dirac_stereo_flag != 0 ) && ( NE_16( st_ivas->ivas_format, SBA_ISM_FORMAT ) || GE_16( cpe_id, sub( nCPE, 2 ) ) ) ) { - - Copy_Scale_sig_16_32( synth_fx[n], synth_fx_32[n], L_FRAME48k, sub( Q11, ( sub( 15, e_sig[n] ) ) ) ); // Q11 - Copy_Scale_sig_16_32( hCPE->hCoreCoder[n]->hHQ_core->old_out_fx, hCPE->hCoreCoder[n]->hHQ_core->oldOut_fx, output_frame, sub( Q11, hCPE->hCoreCoder[n]->hHQ_core->Q_old_wtda ) ); +#ifdef FIX_ISSUE_1237 + Copy_Scale_sig_16_32_no_sat( synth_fx[n], synth_fx_32[n], L_FRAME48k, sub( Q11, ( sub( 15, e_sig[n] ) ) ) ); // Q11 + Copy_Scale_sig_16_32_no_sat( hCPE->hCoreCoder[n]->hHQ_core->old_out_fx, hCPE->hCoreCoder[n]->hHQ_core->oldOut_fx, output_frame, sub( Q11, hCPE->hCoreCoder[n]->hHQ_core->Q_old_wtda ) ); +#else + Copy_Scale_sig_16_32_DEPREC( synth_fx[n], synth_fx_32[n], L_FRAME48k, sub( Q11, ( sub( 15, e_sig[n] ) ) ) ); // Q11 + Copy_Scale_sig_16_32_DEPREC( hCPE->hCoreCoder[n]->hHQ_core->old_out_fx, hCPE->hCoreCoder[n]->hHQ_core->oldOut_fx, output_frame, sub( Q11, hCPE->hCoreCoder[n]->hHQ_core->Q_old_wtda ) ); +#endif ivas_post_proc_fx( NULL, hCPE, n, synth_fx_32[n], NULL, output_frame, 1, Q11 ); #ifdef MSAN_FIX Copy_Scale_sig_32_16( synth_fx_32[n], synth_fx[n], output_frame, sub( sub( 15, e_sig[n] ), Q11 ) ); // Q0 @@ -395,11 +428,11 @@ ivas_error ivas_mct_dec_fx( Word16 output_mem_fx[L_FRAME48k]; IF( hCPE->output_mem_fx[1] != NULL ) { - Copy_Scale_sig_32_16( hCPE->output_mem_fx[1], output_mem_fx, NS2SA( sts[n]->output_Fs, 3125000 ), -Q11 ); + Copy_Scale_sig_32_16( hCPE->output_mem_fx[1], output_mem_fx, NS2SA_FX2( sts[n]->output_Fs, 3125000 ), -Q11 ); } ELSE { - set16_fx( output_mem_fx, 0, NS2SA( sts[n]->output_Fs, 3125000 ) ); + set16_fx( output_mem_fx, 0, NS2SA_FX2( sts[n]->output_Fs, 3125000 ) ); } Word16 Q_synth = sub( 15, e_sig[n] ); @@ -419,14 +452,16 @@ ivas_error ivas_mct_dec_fx( { return error; } - - Copy_Scale_sig_16_32( synth_fx[n], output_fx[( cpe_id * CPE_CHANNELS ) + n], output_frame, sub( Q11, Q_synth ) ); // Q11 - +#ifdef FIX_ISSUE_1237 + Copy_Scale_sig_16_32_no_sat( synth_fx[n], output_fx[( cpe_id * CPE_CHANNELS ) + n], output_frame, sub( Q11, Q_synth ) ); // Q11 +#else + Copy_Scale_sig_16_32_DEPREC( synth_fx[n], output_fx[( cpe_id * CPE_CHANNELS ) + n], output_frame, sub( Q11, Q_synth ) ); // Q11 +#endif /* Save synthesis for HQ FEC */ Word32 output_fx_[L_FRAME48k]; - Copy32( output_fx[( cpe_id * CPE_CHANNELS ) + n], output_fx_, L_FRAME48k ); // Q11 - Scale_sig32( output_fx_, L_FRAME48k, Q16 - Q11 ); // Q11 -> Q16 - Copy_Scale_sig32_16( sts[n]->prev_synth_buffer32_fx, sts[n]->prev_synth_buffer_fx, NS2SA( 48000, DELAY_BWE_TOTAL_NS - DELAY_CLDFB_NS ), -11 ); // Q11 -> Q0 + Copy32( output_fx[( cpe_id * CPE_CHANNELS ) + n], output_fx_, L_FRAME48k ); // Q11 + Scale_sig32( output_fx_, L_FRAME48k, Q16 - Q11 ); // Q11 -> Q16 + Copy_Scale_sig32_16( sts[n]->prev_synth_buffer32_fx, sts[n]->prev_synth_buffer_fx, NS2SA( 48000, DELAY_BWE_TOTAL_NS - DELAY_CLDFB_NS ), -Q11 ); // Q11 -> Q0 sts[n]->q_prev_synth_buffer_fx = 0; move16(); @@ -441,7 +476,11 @@ ivas_error ivas_mct_dec_fx( { IF( hCPE->hCoreCoder[n] ) { - Copy_Scale_sig_16_32( hCPE->hCoreCoder[n]->delay_buf_out_fx, hCPE->hCoreCoder[n]->delay_buf_out32_fx, HQ_DELTA_MAX * HQ_DELAY_COMP, Q11 ); // Q0 -> Q11 +#ifdef FIX_ISSUE_1237 + Copy_Scale_sig_16_32_no_sat( hCPE->hCoreCoder[n]->delay_buf_out_fx, hCPE->hCoreCoder[n]->delay_buf_out32_fx, HQ_DELTA_MAX * HQ_DELAY_COMP, Q11 ); // Q0 -> Q11 +#else + Copy_Scale_sig_16_32_DEPREC( hCPE->hCoreCoder[n]->delay_buf_out_fx, hCPE->hCoreCoder[n]->delay_buf_out32_fx, HQ_DELTA_MAX * HQ_DELAY_COMP, Q11 ); // Q0 -> Q11 +#endif } } @@ -1455,7 +1494,11 @@ static ivas_error ivas_mc_dec_reconfig_fx( test(); test(); test(); +#ifdef SPLIT_REND_WITH_HEAD_ROT + IF( EQ_16( output_config, IVAS_AUDIO_CONFIG_BINAURAL ) || EQ_16( output_config, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR ) || EQ_16( output_config, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) || EQ_16( output_config, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) || EQ_16( output_config, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ) +#else IF( EQ_16( output_config, IVAS_AUDIO_CONFIG_BINAURAL ) || EQ_16( output_config, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR ) || EQ_16( output_config, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) ) +#endif { /* remove unneeded binaural renderers */ test(); @@ -1470,10 +1513,17 @@ static ivas_error ivas_mc_dec_reconfig_fx( test(); test(); test(); +#ifdef SPLIT_REND_WITH_HEAD_ROT + IF( ( st_ivas->hCrendWrapper != NULL ) && ( st_ivas->hCrendWrapper->hCrend[0] != NULL ) && ( NE_16( st_ivas->renderer_type, RENDERER_BINAURAL_MIXER_CONV ) && NE_16( st_ivas->renderer_type, RENDERER_BINAURAL_MIXER_CONV_ROOM ) && ( NE_16( st_ivas->renderer_type, RENDERER_BINAURAL_OBJECTS_TD ) || NE_16( st_ivas->hIntSetup.output_config, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) ) ) ) +#else IF( ( st_ivas->hCrendWrapper != NULL ) && ( st_ivas->hCrendWrapper->hCrend != NULL ) && ( NE_16( st_ivas->renderer_type, RENDERER_BINAURAL_MIXER_CONV ) && NE_16( st_ivas->renderer_type, RENDERER_BINAURAL_MIXER_CONV_ROOM ) && ( NE_16( st_ivas->renderer_type, RENDERER_BINAURAL_OBJECTS_TD ) || NE_16( st_ivas->hIntSetup.output_config, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) ) ) ) +#endif { - +#ifdef SPLIT_REND_WITH_HEAD_ROT + ivas_rend_closeCrend( &( st_ivas->hCrendWrapper ), ( st_ivas->hSplitBinRend == NULL ) ? 1 : st_ivas->hSplitBinRend->splitrend.multiBinPoseData.num_poses ); +#else ivas_rend_closeCrend( &( st_ivas->hCrendWrapper ) ); +#endif } test(); @@ -1486,13 +1536,21 @@ static ivas_error ivas_mc_dec_reconfig_fx( } } +#ifdef SPLIT_REND_WITH_HEAD_ROT + IF( st_ivas->hDiracDecBin[0] != NULL ) +#else IF( st_ivas->hDiracDecBin != NULL ) +#endif { test(); test(); IF( NE_16( st_ivas->renderer_type, RENDERER_BINAURAL_PARAMETRIC ) && NE_16( st_ivas->renderer_type, RENDERER_BINAURAL_PARAMETRIC_ROOM ) && NE_16( st_ivas->renderer_type, RENDERER_STEREO_PARAMETRIC ) ) { +#ifdef SPLIT_REND_WITH_HEAD_ROT + ivas_dirac_dec_close_binaural_data( st_ivas->hDiracDecBin ); +#else ivas_dirac_dec_close_binaural_data( &st_ivas->hDiracDecBin ); +#endif } } @@ -1517,22 +1575,39 @@ static ivas_error ivas_mc_dec_reconfig_fx( } IF( EQ_16( st_ivas->hIntSetup.output_config, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) ) { +#ifdef SPLIT_REND_WITH_HEAD_ROT + IF( ( error = ivas_rend_initCrendWrapper( &st_ivas->hCrendWrapper, 1 ) ) != IVAS_ERR_OK ) +#else IF( ( error = ivas_rend_initCrendWrapper( &st_ivas->hCrendWrapper ) ) != IVAS_ERR_OK ) +#endif { return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Crend Wrapper\n" ); } +#ifdef SPLIT_REND_WITH_HEAD_ROT + st_ivas->hCrendWrapper->hCrend[0] = NULL; + st_ivas->hCrendWrapper->hHrtfCrend = NULL; + IF( ( st_ivas->hCrendWrapper->hCrend[0] = (CREND_HANDLE) malloc( sizeof( CREND_DATA ) ) ) == NULL ) + { + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Crend\n" ); + } +#else st_ivas->hCrendWrapper->hCrend = NULL; st_ivas->hCrendWrapper->hHrtfCrend = NULL; IF( ( st_ivas->hCrendWrapper->hCrend = (CREND_HANDLE) malloc( sizeof( CREND_DATA ) ) ) == NULL ) { return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Crend\n" ); } +#endif } } ELSE IF( st_ivas->hCrendWrapper == NULL && ( EQ_16( st_ivas->renderer_type, RENDERER_BINAURAL_MIXER_CONV ) || EQ_16( st_ivas->renderer_type, RENDERER_BINAURAL_MIXER_CONV_ROOM ) ) ) { +#ifdef SPLIT_REND_WITH_HEAD_ROT + IF( ( error = ivas_rend_openCrend( &( st_ivas->hCrendWrapper ), st_ivas->intern_config, st_ivas->hDecoderConfig->output_config, st_ivas->hRenderConfig, st_ivas->hSetOfHRTF, st_ivas->hDecoderConfig->output_Fs, ( st_ivas->hSplitBinRend == NULL ) ? 1 : st_ivas->hSplitBinRend->splitrend.multiBinPoseData.num_poses ) ) != IVAS_ERR_OK ) +#else IF( ( error = ivas_rend_openCrend( &( st_ivas->hCrendWrapper ), st_ivas->intern_config, st_ivas->hDecoderConfig->output_config, st_ivas->hRenderConfig, st_ivas->hSetOfHRTF, st_ivas->hDecoderConfig->output_Fs ) ) != IVAS_ERR_OK ) +#endif { return error; } diff --git a/lib_dec/ivas_mct_dec_mct.c b/lib_dec/ivas_mct_dec_mct.c deleted file mode 100644 index 7ba41f344beb919d85c23047e4aaf70d31e29bd9..0000000000000000000000000000000000000000 --- a/lib_dec/ivas_mct_dec_mct.c +++ /dev/null @@ -1,41 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -#include -#include "options.h" -#include "ivas_cnst.h" -#include "ivas_prot.h" -#include "prot.h" -#include "wmc_auto.h" -#include -#include "stat_enc.h" -#include "ivas_prot_fx.h" diff --git a/lib_dec/ivas_mct_dec_mct_fx.c b/lib_dec/ivas_mct_dec_mct_fx_fx.c similarity index 99% rename from lib_dec/ivas_mct_dec_mct_fx.c rename to lib_dec/ivas_mct_dec_mct_fx_fx.c index 3ed0998d1642fd8e96aca435a0dfe720550df64f..c275820fbcf25cb352d72c029c7965843fa29090 100644 --- a/lib_dec/ivas_mct_dec_mct_fx.c +++ b/lib_dec/ivas_mct_dec_mct_fx_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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,12 +33,10 @@ #include #include "options.h" #include "ivas_cnst.h" -#include "ivas_prot.h" -#include "prot.h" +#include "prot_fx.h" #include "wmc_auto.h" #include #include "stat_enc.h" -#include "prot_fx.h" #include "ivas_prot_fx.h" /*----------------------------------------------------------* diff --git a/lib_dec/ivas_mdct_core_dec.c b/lib_dec/ivas_mdct_core_dec_fx.c similarity index 96% rename from lib_dec/ivas_mdct_core_dec.c rename to lib_dec/ivas_mdct_core_dec_fx.c index b80bff932e923b09a077d4bad722d61314b63c07..151ba7d1eafa6fc83452492bcae937152ed6127e 100644 --- a/lib_dec/ivas_mdct_core_dec.c +++ b/lib_dec/ivas_mdct_core_dec_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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,18 +33,16 @@ #include #include #include "options.h" -#include "prot.h" +#include "prot_fx.h" #include "rom_com.h" #include "ivas_rom_com.h" #include "wmc_auto.h" #include "cnst.h" #include "basop_proto_func.h" #include "stat_com.h" -#include "ivas_prot.h" #include "ivas_stat_dec.h" #include "ivas_stat_com.h" #include -#include "prot_fx.h" #include "ivas_prot_fx.h" @@ -731,11 +729,16 @@ void ivas_mdct_core_invQ_fx( common_exp = s_max( sts[0]->hTonalMDCTConc->lastBlockData.spectralData_exp, sts[1]->hTonalMDCTConc->lastBlockData.spectralData_exp ); #ifdef MSAN_FIX - Copy_Scale_sig_16_32( sts[0]->hTonalMDCTConc->lastBlockData.spectralData, spectralData_tmp[0], L_frameTCX[0], sub( 15, sub( common_exp, sts[0]->hTonalMDCTConc->lastBlockData.spectralData_exp ) ) ); // 30 - spectral_exp1 - Copy_Scale_sig_16_32( sts[1]->hTonalMDCTConc->lastBlockData.spectralData, spectralData_tmp[1], L_frameTCX[1], sub( 15, sub( common_exp, sts[1]->hTonalMDCTConc->lastBlockData.spectralData_exp ) ) ); // 30 - spectral_exp2 +#ifdef FIX_ISSUE_1237 + Copy_Scale_sig_16_32_no_sat( sts[0]->hTonalMDCTConc->lastBlockData.spectralData, spectralData_tmp[0], L_frameTCX[0], sub( 15, sub( common_exp, sts[0]->hTonalMDCTConc->lastBlockData.spectralData_exp ) ) ); // 30 - spectral_exp1 + Copy_Scale_sig_16_32_no_sat( sts[1]->hTonalMDCTConc->lastBlockData.spectralData, spectralData_tmp[1], L_frameTCX[1], sub( 15, sub( common_exp, sts[1]->hTonalMDCTConc->lastBlockData.spectralData_exp ) ) ); // 30 - spectral_exp2 +#else + Copy_Scale_sig_16_32_DEPREC( sts[0]->hTonalMDCTConc->lastBlockData.spectralData, spectralData_tmp[0], L_frameTCX[0], sub( 15, sub( common_exp, sts[0]->hTonalMDCTConc->lastBlockData.spectralData_exp ) ) ); // 30 - spectral_exp1 + Copy_Scale_sig_16_32_DEPREC( sts[1]->hTonalMDCTConc->lastBlockData.spectralData, spectralData_tmp[1], L_frameTCX[1], sub( 15, sub( common_exp, sts[1]->hTonalMDCTConc->lastBlockData.spectralData_exp ) ) ); // 30 - spectral_exp2 +#endif #else - Copy_Scale_sig_16_32( sts[0]->hTonalMDCTConc->lastBlockData.spectralData, spectralData_tmp[0], L_FRAME_MAX, 15 - ( common_exp - sts[0]->hTonalMDCTConc->lastBlockData.spectralData_exp ) ); // 30 - spectral_exp1 - Copy_Scale_sig_16_32( sts[1]->hTonalMDCTConc->lastBlockData.spectralData, spectralData_tmp[1], L_FRAME_MAX, 15 - ( common_exp - sts[1]->hTonalMDCTConc->lastBlockData.spectralData_exp ) ); // 30 - spectral_exp2 + Copy_Scale_sig_16_32_DEPREC( sts[0]->hTonalMDCTConc->lastBlockData.spectralData, spectralData_tmp[0], L_FRAME_MAX, 15 - ( common_exp - sts[0]->hTonalMDCTConc->lastBlockData.spectralData_exp ) ); // 30 - spectral_exp1 + Copy_Scale_sig_16_32_DEPREC( sts[1]->hTonalMDCTConc->lastBlockData.spectralData, spectralData_tmp[1], L_FRAME_MAX, 15 - ( common_exp - sts[1]->hTonalMDCTConc->lastBlockData.spectralData_exp ) ); // 30 - spectral_exp2 #endif // MSAN_FIX sts[0]->hTonalMDCTConc->lastBlockData.spectralData_exp = sts[1]->hTonalMDCTConc->lastBlockData.spectralData_exp = common_exp; @@ -1278,11 +1281,6 @@ void ivas_mdct_core_reconstruct_fx( ELSE /*ACELP core for ACELP-PLC */ { assert( EQ_16( st->bfi, 1 ) ); - - Scale_sig( synth_buf_fx, add( add( st->hTcxDec->old_synth_len, L_FRAME_PLUS ), M ), sub( -2, q_syn ) ); // Q0 - Scale_sig( synth_bufFB_fx, add( add( st->hTcxDec->old_synth_lenFB, L_FRAME_PLUS ), M ), sub( -2, q_syn ) ); // Q0 - q_syn = -2; - move16(); /* PLC: [TCX: TD PLC] */ IF( MCT_flag != 0 ) { @@ -1312,11 +1310,11 @@ void ivas_mdct_core_reconstruct_fx( IF( ( EQ_16( st->nbLostCmpt, 1 ) ) || ( st->hTcxDec->tcxConceal_recalc_exc != 0 ) ) { - Scale_sig( synthFB_fx - add( add( shr( st->hTcxDec->L_frameTCX, 1 ), st->hTcxDec->pit_max_TCX ), 2 * M ), add( add( shr( st->hTcxDec->L_frameTCX, 1 ), st->hTcxDec->pit_max_TCX ), 2 * M ), sub( q_syn, sub( st->Q_exc, 1 ) ) ); // 2 * q_syn - (st->Q_exc - 1) + Scale_sig( synthFB_fx - add( add( shr( st->hTcxDec->L_frameTCX, 1 ), st->hTcxDec->pit_max_TCX ), 2 * M ), sub( add( add( shr( st->hTcxDec->L_frameTCX, 1 ), st->hTcxDec->pit_max_TCX ), 2 * M ), 1 ), sub( q_syn, sub( st->Q_exc, 1 ) ) ); // 2 * q_syn - (st->Q_exc - 1) } ELSE { - Scale_sig( synthFB_fx - st->hTcxDec->L_frameTCX, st->hTcxDec->L_frameTCX, sub( q_syn, sub( st->Q_exc, 1 ) ) ); // 2 * q_syn - (st->Q_exc - 1) + Scale_sig( synthFB_fx - st->hTcxDec->L_frameTCX, sub( st->hTcxDec->L_frameTCX, 1 ), sub( q_syn, sub( st->Q_exc, 1 ) ) ); // 2 * q_syn - (st->Q_exc - 1) } lerp( synthFB_fx, synth_fx, st->L_frame, st->hTcxDec->L_frameTCX ); @@ -1356,7 +1354,7 @@ void ivas_mdct_core_reconstruct_fx( /* Update */ Copy( synth_buf_fx + st->L_frame, st->hTcxDec->old_synth, st->hTcxDec->old_synth_len ); - Copy( st->hTcxDec->old_synthFB_fx + st->hTcxDec->L_frameTCX - NS2SA( st->output_Fs, PH_ECU_MEM_NS ), st->hTcxDec->synth_history_fx, NS2SA( st->output_Fs, PH_ECU_MEM_NS ) ); + Copy( st->hTcxDec->old_synthFB_fx + st->hTcxDec->L_frameTCX - NS2SA_FX2( st->output_Fs, PH_ECU_MEM_NS ), st->hTcxDec->synth_history_fx, NS2SA_FX2( st->output_Fs, PH_ECU_MEM_NS ) ); Copy( synth_bufFB_fx + st->hTcxDec->L_frameTCX, st->hTcxDec->old_synthFB_fx, st->hTcxDec->old_synth_lenFB ); st->hTcxDec->q_old_synth = q_syn; st->hTcxDec->q_synth_history_fx = st->hTcxDec->q_old_synth; @@ -1366,7 +1364,7 @@ void ivas_mdct_core_reconstruct_fx( IF( st->hHQ_core != NULL ) { - Copy( st->hHQ_core->old_out_fx + NS2SA( st->output_Fs, N_ZERO_MDCT_NS ), st->hTcxDec->old_synthFB_fx + st->hTcxDec->old_synth_lenFB, NS2SA( st->output_Fs, PH_ECU_LOOKAHEAD_NS ) ); + Copy( st->hHQ_core->old_out_fx + NS2SA_FX2( st->output_Fs, N_ZERO_MDCT_NS ), st->hTcxDec->old_synthFB_fx + st->hTcxDec->old_synth_lenFB, NS2SA_FX2( st->output_Fs, PH_ECU_LOOKAHEAD_NS ) ); } Copy( st->lsp_q_cng, st->old_lsp_q_cng, M ); @@ -1399,8 +1397,11 @@ void ivas_mdct_core_reconstruct_fx( move16(); st->last_coder_type = st->coder_type; move16(); - - Copy_Scale_sig_16_32( x_fx_16, x_fx[ch][0], st->L_frame, sub( q_x, q_syn ) ); // q_syn -> Q_x +#ifdef FIX_ISSUE_1237 + Copy_Scale_sig_16_32_no_sat( x_fx_16, x_fx[ch][0], st->L_frame, sub( q_x, q_syn ) ); // q_syn -> Q_x +#else + Copy_Scale_sig_16_32_DEPREC( x_fx_16, x_fx[ch][0], st->L_frame, sub( q_x, q_syn ) ); // q_syn -> Q_x +#endif } IF( GT_16( e_sig[0], e_sig[1] ) ) @@ -1504,6 +1505,9 @@ void ivas_mdct_core_tns_ns_fx( move16(); set32_fx( xn_buf_fx, 0, L_MDCT_OVLP_MAX + L_FRAME_PLUS + L_MDCT_OVLP_MAX ); +#ifdef MSAN_FIX + set32_fx( sns_int_scf_fx, 0, FDNS_NPTS ); +#endif /* TNS, ITF, IMDCT and updates */ @@ -1545,7 +1549,7 @@ void ivas_mdct_core_tns_ns_fx( } /* nothing to do for missing LFE */ - continue; + CONTINUE; } FOR( k = 0; k < nSubframes[ch]; k++ ) diff --git a/lib_dec/ivas_mono_dmx_renderer.c b/lib_dec/ivas_mono_dmx_renderer_fx.c similarity index 99% rename from lib_dec/ivas_mono_dmx_renderer.c rename to lib_dec/ivas_mono_dmx_renderer_fx.c index 6ef61560148a498f11f6552809071fe80a292d56..2eb8d84dfe6a1d93e468243d1a11353fed12e82e 100644 --- a/lib_dec/ivas_mono_dmx_renderer.c +++ b/lib_dec/ivas_mono_dmx_renderer_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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,9 +34,7 @@ #include "options.h" #include #include "cnst.h" -#include "prot.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "ivas_prot_fx.h" #include "ivas_cnst.h" #include "ivas_rom_com.h" diff --git a/lib_dec/ivas_objectRenderer_internal.c b/lib_dec/ivas_objectRenderer_internal_fx.c similarity index 67% rename from lib_dec/ivas_objectRenderer_internal.c rename to lib_dec/ivas_objectRenderer_internal_fx.c index 256ce8f96bb845a1b711fe3cd2e8b1e3ea420d05..9a836574ab7c1cacdb3466dc65b70e99c31869e9 100644 --- a/lib_dec/ivas_objectRenderer_internal.c +++ b/lib_dec/ivas_objectRenderer_internal_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other @@ -32,14 +32,12 @@ #include #include "options.h" -#include "prot.h" -#include "ivas_prot.h" -#include "ivas_prot_rend.h" +#include "prot_fx.h" +#include "ivas_prot_rend_fx.h" #include #include "ivas_rom_com.h" #include "wmc_auto.h" #include "ivas_prot_fx.h" -#include "prot_fx.h" #include "debug.h" @@ -342,3 +340,159 @@ ivas_error ivas_td_binaural_renderer_sf_fx( return IVAS_ERR_OK; } + +#ifdef SPLIT_REND_WITH_HEAD_ROT +/*---------------------------------------------------------------------* + * ivas_td_binaural_renderer_sf_splitBinaural() + * + * Render to multiple binaural pairs based on relative head positions for split rendering. + *---------------------------------------------------------------------*/ + +ivas_error ivas_td_binaural_renderer_sf_splitBinaural( + Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ + Word32 *output[], /* i/o: SCE channels / Binaural synthesis */ + const Word16 nSamplesRendered /* i : number of samples to render */ +) +{ + Word16 i; + Word16 pos_idx; + IVAS_QUATERNION originalHeadRot[MAX_PARAM_SPATIAL_SUBFRAMES]; + MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData; + BINAURAL_TD_OBJECT_RENDERER_HANDLE origTdRendHandle; + ivas_error error; + Word16 original_subframes_rendered; + Word16 original_slots_rendered; + Word32 *p_bin_output[BINAURAL_CHANNELS]; + Word32 output_local[MAX_OUTPUT_CHANNELS][L_FRAME48k]; + Word16 q_fact_orig[MAX_PARAM_SPATIAL_SUBFRAMES]; + + Word16 SrcInd[MAX_NUM_TDREND_CHANNELS]; + + pMultiBinPoseData = &st_ivas->hSplitBinRend->splitrend.multiBinPoseData; + move32(); + + /* If not yet allocated, open additional instances of TD renderer */ + FOR( i = 0; i < pMultiBinPoseData->num_poses - 1; ++i ) + { + IF( st_ivas->hTdRendHandles[i] != NULL ) + { + continue; + } + + IF( ( error = ivas_td_binaural_open_unwrap_fx( &st_ivas->hHrtfTD, + st_ivas->hDecoderConfig->output_Fs, + st_ivas->nchan_transport, + st_ivas->ivas_format, + st_ivas->transport_config, + st_ivas->hRenderConfig->directivity_fx, + st_ivas->hTransSetup, + &st_ivas->hTdRendHandles[i], + &st_ivas->binaural_latency_ns, + SrcInd ) ) != IVAS_ERR_OK ) + { + return error; + } + } + + /* Save current head positions */ + FOR( i = 0; i < st_ivas->hCombinedOrientationData->num_subframes; ++i ) + { + originalHeadRot[i] = st_ivas->hCombinedOrientationData->Quaternions[i]; + q_fact_orig[i] = originalHeadRot[i].q_fact; + } + + original_subframes_rendered = st_ivas->hTcBuffer->subframes_rendered; + move16(); + original_slots_rendered = st_ivas->hTcBuffer->slots_rendered; + move16(); + origTdRendHandle = st_ivas->hBinRendererTd; + move32(); + + FOR( i = 0; i < st_ivas->hCombinedOrientationData->num_subframes; ++i ) + { + modify_Quat_q_fx( &originalHeadRot[i], &originalHeadRot[i], Q22 ); + } + + FOR( pos_idx = 0; pos_idx < pMultiBinPoseData->num_poses; pos_idx++ ) + { + /* Update head positions */ + IF( NE_16( pos_idx, 0 ) ) + { + COMBINED_ORIENTATION_HANDLE pCombinedOrientationData = st_ivas->hCombinedOrientationData; + FOR( i = 0; i < st_ivas->hCombinedOrientationData->num_subframes; ++i ) + { + pCombinedOrientationData->Quaternions[i].w_fx = L_negate( 12582912 ); // Q22 + /*euler*/ + Quat2EulerDegree_fx( originalHeadRot[i], + &pCombinedOrientationData->Quaternions[i].z_fx, + &pCombinedOrientationData->Quaternions[i].y_fx, + &pCombinedOrientationData->Quaternions[i].x_fx ); + pCombinedOrientationData->Quaternions[i].x_fx = L_add( pCombinedOrientationData->Quaternions[i].x_fx, pMultiBinPoseData->relative_head_poses_fx[pos_idx][0] ); + pCombinedOrientationData->Quaternions[i].y_fx = L_add( pCombinedOrientationData->Quaternions[i].y_fx, pMultiBinPoseData->relative_head_poses_fx[pos_idx][1] ); + pCombinedOrientationData->Quaternions[i].z_fx = L_add( pCombinedOrientationData->Quaternions[i].z_fx, pMultiBinPoseData->relative_head_poses_fx[pos_idx][2] ); + + Euler2Quat_fx( deg2rad_fx( pCombinedOrientationData->Quaternions[i].x_fx ), + deg2rad_fx( pCombinedOrientationData->Quaternions[i].y_fx ), + deg2rad_fx( pCombinedOrientationData->Quaternions[i].z_fx ), &pCombinedOrientationData->Quaternions[i] ); + + modify_Quat_q_fx( &pCombinedOrientationData->Quaternions[i], &pCombinedOrientationData->Quaternions[i], q_fact_orig[i] ); + } + } + + /* set output channels */ + FOR( i = 0; i < BINAURAL_CHANNELS; i++ ) + { + p_bin_output[i] = output_local[add( i_mult( pos_idx, BINAURAL_CHANNELS ), i )]; + move32(); + } + st_ivas->hTcBuffer->subframes_rendered = original_subframes_rendered; + move16(); + st_ivas->hTcBuffer->slots_rendered = original_slots_rendered; + move16(); + + /* update combined orientation access index */ + ivas_combined_orientation_set_to_start_index( st_ivas->hCombinedOrientationData ); + + /* Render */ + IF( NE_16( pos_idx, 0 ) ) + { + st_ivas->hBinRendererTd = st_ivas->hTdRendHandles[sub( pos_idx, 1 )]; + move32(); + } + + IF( ( error = ivas_td_binaural_renderer_sf_fx( st_ivas, p_bin_output, nSamplesRendered ) ) != IVAS_ERR_OK ) + { + return error; + } + + IF( EQ_16( st_ivas->ivas_format, MC_FORMAT ) ) + { + Word32 *p_tc[MAX_TRANSPORT_CHANNELS]; + FOR( i = 0; i < st_ivas->nchan_transport; i++ ) + { + p_tc[i] = st_ivas->hTcBuffer->tc_fx[i] + st_ivas->hTcBuffer->n_samples_rendered; + } + ivas_binaural_add_LFE_fx( st_ivas, nSamplesRendered, p_tc, p_bin_output ); + } + } + + FOR( i = 0; i < i_mult( pMultiBinPoseData->num_poses, BINAURAL_CHANNELS ); i++ ) + { + Copy32( output_local[i], output[i], nSamplesRendered ); + } + + /* Restore original head rotation */ + FOR( i = 0; i < st_ivas->hCombinedOrientationData->num_subframes; ++i ) + { + modify_Quat_q_fx( &originalHeadRot[i], &originalHeadRot[i], q_fact_orig[i] ); + st_ivas->hCombinedOrientationData->Quaternions[i] = originalHeadRot[i]; + move32(); + } + + /* restore original td renderer handle */ + st_ivas->hBinRendererTd = origTdRendHandle; + move32(); + + return IVAS_ERR_OK; +} +#endif diff --git a/lib_dec/ivas_omasa_dec.c b/lib_dec/ivas_omasa_dec_fx.c similarity index 87% rename from lib_dec/ivas_omasa_dec.c rename to lib_dec/ivas_omasa_dec_fx.c index 50921761651bd8e790087ebe28274583bcce4826..2393ea51d096ff0da5db9e567d1307f426a1afb0 100644 --- a/lib_dec/ivas_omasa_dec.c +++ b/lib_dec/ivas_omasa_dec_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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,14 +33,12 @@ #include "options.h" #include #include "ivas_cnst.h" -#include "ivas_prot.h" #include "ivas_prot_fx.h" -#include "prot.h" -#include "ivas_prot_rend.h" +#include "prot_fx.h" +#include "ivas_prot_rend_fx.h" #include "ivas_rom_com.h" #include "wmc_auto.h" #include "ivas_prot_fx.h" -#include "prot_fx.h" /*------------------------------------------------------------------------- @@ -422,10 +420,17 @@ ivas_error ivas_omasa_dec_config_fx( * TD Decorrelator *-----------------------------------------------------------------*/ +#ifdef SPLIT_REND_WITH_HEAD_ROT + IF( st_ivas->hDiracDecBin[0] != NULL ) +#else IF( st_ivas->hDiracDecBin != NULL ) +#endif { +#ifdef SPLIT_REND_WITH_HEAD_ROT + IF( NE_32( ( error = ivas_td_decorr_reconfig_dec( st_ivas->ivas_format, st_ivas->hDecoderConfig->ivas_total_brate, st_ivas->nchan_transport, st_ivas->hDecoderConfig->output_Fs, &( st_ivas->hDiracDecBin[0]->hTdDecorr ), &( st_ivas->hDiracDecBin[0]->useTdDecorr ) ) ), IVAS_ERR_OK ) ) +#else IF( NE_32( ( error = ivas_td_decorr_reconfig_dec( st_ivas->ivas_format, st_ivas->hDecoderConfig->ivas_total_brate, st_ivas->nchan_transport, st_ivas->hDecoderConfig->output_Fs, &( st_ivas->hDiracDecBin->hTdDecorr ), &( st_ivas->hDiracDecBin->useTdDecorr ) ) ), IVAS_ERR_OK ) ) - +#endif { return error; } @@ -761,6 +766,12 @@ ivas_error ivas_omasa_dirac_td_binaural_jbm_fx( Word32 *p_sepobj_fx[MAX_NUM_OBJECTS]; // Q11 Word32 data_separated_objects_fx[MAX_NUM_OBJECTS][L_FRAME48k]; move16(); +#ifdef SPLIT_REND_WITH_HEAD_ROT + Word16 slot_idx_start; + + slot_idx_start = st_ivas->hSpatParamRendCom->slots_rendered; + move16(); +#endif FOR( n = 0; n < MAX_NUM_OBJECTS; n++ ) { @@ -788,15 +799,72 @@ ivas_error ivas_omasa_dirac_td_binaural_jbm_fx( /* reset combined orientation access index before calling the td renderer */ ivas_combined_orientation_set_to_start_index( st_ivas->hCombinedOrientationData ); - IF( NE_32( ( error = ivas_td_binaural_renderer_sf_fx( st_ivas, p_sepobj_fx, *nSamplesRendered ) ), IVAS_ERR_OK ) ) +#ifdef SPLIT_REND_WITH_HEAD_ROT + IF( EQ_16( st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) || EQ_16( st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ) { - return error; - } + Word16 slot_idx, num_cldfb_bands, nchan_transport_orig, cldfb_slots; + Word32 Cldfb_RealBuffer[CLDFB_NO_CHANNELS_MAX]; + Word32 Cldfb_ImagBuffer[CLDFB_NO_CHANNELS_MAX]; + Word32 *p_rend_obj[MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS]; /* [8 * 2] */ + Word16 q_cldfb, q_in = 11; + move16(); + + FOR( n = 0; n < i_mult( st_ivas->hSplitBinRend->splitrend.multiBinPoseData.num_poses, BINAURAL_CHANNELS ); n++ ) + { + p_rend_obj[n] = &output_fx[n][0]; + move32(); + } + + num_cldfb_bands = st_ivas->hSplitBinRend->splitrend.hCldfbHandles->cldfbAna[0]->no_channels; + move16(); + nchan_transport_orig = st_ivas->nchan_transport; + move16(); + st_ivas->nchan_transport = st_ivas->nchan_ism; + move16(); - FOR( n = 0; n < BINAURAL_CHANNELS; n++ ) + IF( ( error = ivas_td_binaural_renderer_sf_splitBinaural( st_ivas, p_rend_obj, *nSamplesRendered ) ) != IVAS_ERR_OK ) /* objects are read from st_ivas->hTcBuffer->tc[2..(1+n_isms)] */ + { + return error; + } + st_ivas->nchan_transport = nchan_transport_orig; + move16(); + cldfb_slots = *nSamplesRendered / num_cldfb_bands; + + FOR( n = 0; n < i_mult( st_ivas->hSplitBinRend->splitrend.multiBinPoseData.num_poses, BINAURAL_CHANNELS ); ++n ) + { + q_cldfb = q_in; + Scale_sig32( st_ivas->hSplitBinRend->splitrend.hCldfbHandles->cldfbAna[n]->cldfb_state_fx, + sub( st_ivas->hSplitBinRend->splitrend.hCldfbHandles->cldfbAna[n]->p_filter_length, st_ivas->hSplitBinRend->splitrend.hCldfbHandles->cldfbAna[n]->no_channels ), + sub( q_cldfb, st_ivas->hSplitBinRend->splitrend.hCldfbHandles->cldfbAna[n]->Q_cldfb_state ) ); + st_ivas->hSplitBinRend->splitrend.hCldfbHandles->cldfbAna[n]->Q_cldfb_state = q_cldfb; + FOR( slot_idx = 0; slot_idx < cldfb_slots; slot_idx++ ) + { + q_cldfb = q_in; + cldfbAnalysis_ts_fx_fixed_q( &( p_rend_obj[n][num_cldfb_bands * slot_idx] ), Cldfb_RealBuffer, Cldfb_ImagBuffer, num_cldfb_bands, st_ivas->hSplitBinRend->splitrend.hCldfbHandles->cldfbAna[n], &q_cldfb ); + + Scale_sig32( Cldfb_RealBuffer, num_cldfb_bands, sub( Q6, q_cldfb ) ); + Scale_sig32( Cldfb_ImagBuffer, num_cldfb_bands, sub( Q6, q_cldfb ) ); + /* note: this intentionally differs from OSBA by: no scaling by 0.5 */ + v_add_fx( st_ivas->hSplitBinRend->hMultiBinCldfbData->Cldfb_RealBuffer_Binaural_fx[n][slot_idx_start + slot_idx], Cldfb_RealBuffer, st_ivas->hSplitBinRend->hMultiBinCldfbData->Cldfb_RealBuffer_Binaural_fx[n][slot_idx_start + slot_idx], num_cldfb_bands ); + v_add_fx( st_ivas->hSplitBinRend->hMultiBinCldfbData->Cldfb_ImagBuffer_Binaural_fx[n][slot_idx_start + slot_idx], Cldfb_ImagBuffer, st_ivas->hSplitBinRend->hMultiBinCldfbData->Cldfb_ImagBuffer_Binaural_fx[n][slot_idx_start + slot_idx], num_cldfb_bands ); + } + } + } + else { - v_add_fx( output_fx[n], p_sepobj_fx[n], output_fx[n], *nSamplesRendered ); +#endif + IF( NE_32( ( error = ivas_td_binaural_renderer_sf_fx( st_ivas, p_sepobj_fx, *nSamplesRendered ) ), IVAS_ERR_OK ) ) + { + return error; + } + + FOR( n = 0; n < BINAURAL_CHANNELS; n++ ) + { + v_add_fx( output_fx[n], p_sepobj_fx[n], output_fx[n], *nSamplesRendered ); + } +#ifdef SPLIT_REND_WITH_HEAD_ROT } +#endif return IVAS_ERR_OK; } diff --git a/lib_dec/ivas_osba_dec.c b/lib_dec/ivas_osba_dec_fx.c similarity index 70% rename from lib_dec/ivas_osba_dec.c rename to lib_dec/ivas_osba_dec_fx.c index f9d14c995b01d9b822957779f70aa566c90dc42a..f2d096caf30f958830e0f4cefecea8efda91fcdb 100644 --- a/lib_dec/ivas_osba_dec.c +++ b/lib_dec/ivas_osba_dec_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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,13 +33,11 @@ #include "options.h" #include #include "ivas_cnst.h" -#include "ivas_prot.h" -#include "prot.h" -#include "ivas_prot_rend.h" +#include "prot_fx.h" +#include "ivas_prot_rend_fx.h" #include "ivas_rom_com.h" #include "wmc_auto.h" #include "ivas_prot_fx.h" -#include "prot_fx.h" /*-------------------------------------------------------------------* @@ -140,6 +138,12 @@ ivas_error ivas_osba_dirac_td_binaural_jbm_fx( Word32 output_separated_objects_fx[BINAURAL_CHANNELS][L_FRAME48k]; // VE2SB: TBV Word32 *p_sepobj_fx[BINAURAL_CHANNELS]; Word16 channel_offset; +#ifdef SPLIT_REND_WITH_HEAD_ROT + Word16 slot_idx_start; + + slot_idx_start = st_ivas->hSpatParamRendCom->slots_rendered; + move16(); +#endif FOR( n = 0; n < BINAURAL_CHANNELS; n++ ) { @@ -154,20 +158,79 @@ ivas_error ivas_osba_dirac_td_binaural_jbm_fx( return error; } - IF( NE_32( ( error = ivas_td_binaural_renderer_sf_fx( st_ivas, p_sepobj_fx, *nSamplesRendered ) ), IVAS_ERR_OK ) ) +#ifdef SPLIT_REND_WITH_HEAD_ROT + IF( EQ_16( st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) || EQ_16( st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ) { - return error; - } + Word16 slot_idx, num_cldfb_bands, b, nchan_transport_orig; + Word16 cldfb_slots; + Word32 Cldfb_RealBuffer[CLDFB_NO_CHANNELS_MAX]; + Word32 Cldfb_ImagBuffer[CLDFB_NO_CHANNELS_MAX]; + Word16 q_cldfb, q_in = 11; + move16(); + + num_cldfb_bands = st_ivas->hSplitBinRend->splitrend.hCldfbHandles->cldfbAna[0]->no_channels; + move16(); + nchan_transport_orig = st_ivas->nchan_transport; + move16(); + st_ivas->nchan_transport = st_ivas->nchan_ism; + move16(); + IF( ( error = ivas_td_binaural_renderer_sf_splitBinaural( st_ivas, output_fx, *nSamplesRendered ) ) != IVAS_ERR_OK ) + { + return error; + } + st_ivas->nchan_transport = nchan_transport_orig; + move16(); + cldfb_slots = *nSamplesRendered / num_cldfb_bands; - FOR( n = 0; n < BINAURAL_CHANNELS; n++ ) + FOR( n = 0; n < i_mult( st_ivas->hSplitBinRend->splitrend.multiBinPoseData.num_poses, BINAURAL_CHANNELS ); ++n ) + { + q_cldfb = q_in; + Scale_sig32( st_ivas->hSplitBinRend->splitrend.hCldfbHandles->cldfbAna[n]->cldfb_state_fx, + sub( st_ivas->hSplitBinRend->splitrend.hCldfbHandles->cldfbAna[n]->p_filter_length, st_ivas->hSplitBinRend->splitrend.hCldfbHandles->cldfbAna[n]->no_channels ), + sub( q_cldfb, st_ivas->hSplitBinRend->splitrend.hCldfbHandles->cldfbAna[n]->Q_cldfb_state ) ); + st_ivas->hSplitBinRend->splitrend.hCldfbHandles->cldfbAna[n]->Q_cldfb_state = q_cldfb; + FOR( slot_idx = 0; slot_idx < cldfb_slots; slot_idx++ ) + { + q_cldfb = q_in; + cldfbAnalysis_ts_fx_fixed_q( &( output_fx[n][num_cldfb_bands * slot_idx] ), Cldfb_RealBuffer, Cldfb_ImagBuffer, num_cldfb_bands, st_ivas->hSplitBinRend->splitrend.hCldfbHandles->cldfbAna[n], &q_cldfb ); + + Scale_sig32( Cldfb_RealBuffer, num_cldfb_bands, sub( Q6, q_cldfb ) ); + Scale_sig32( Cldfb_ImagBuffer, num_cldfb_bands, sub( Q6, q_cldfb ) ); + FOR( b = 0; b < num_cldfb_bands; b++ ) + { + st_ivas->hSplitBinRend->hMultiBinCldfbData->Cldfb_RealBuffer_Binaural_fx[n][slot_idx_start + slot_idx][b] = + L_add( L_shr( st_ivas->hSplitBinRend->hMultiBinCldfbData->Cldfb_RealBuffer_Binaural_fx[n][add( slot_idx_start, slot_idx )][b], 1 ), + L_shr( Cldfb_RealBuffer[b], 1 ) ); + move32(); + + st_ivas->hSplitBinRend->hMultiBinCldfbData->Cldfb_ImagBuffer_Binaural_fx[n][slot_idx_start + slot_idx][b] = + L_add( L_shr( st_ivas->hSplitBinRend->hMultiBinCldfbData->Cldfb_ImagBuffer_Binaural_fx[n][add( slot_idx_start, slot_idx )][b], 1 ), + L_shr( Cldfb_ImagBuffer[b], 1 ) ); + move32(); + } + } + } + } + else { - Word16 i; - FOR( i = 0; i < nSamplesAsked; i++ ) +#endif + IF( NE_32( ( error = ivas_td_binaural_renderer_sf_fx( st_ivas, p_sepobj_fx, *nSamplesRendered ) ), IVAS_ERR_OK ) ) + { + return error; + } + + FOR( n = 0; n < BINAURAL_CHANNELS; n++ ) { - output_fx[n][i] = L_add( L_shr( output_fx[channel_offset + n][i], 1 ), L_shr( p_sepobj_fx[n][i], 1 ) ); - move32(); + Word16 i; + FOR( i = 0; i < nSamplesAsked; i++ ) + { + output_fx[n][i] = L_add( L_shr( output_fx[channel_offset + n][i], 1 ), L_shr( p_sepobj_fx[n][i], 1 ) ); + move32(); + } } +#ifdef SPLIT_REND_WITH_HEAD_ROT } +#endif return IVAS_ERR_OK; } diff --git a/lib_dec/ivas_out_setup_conversion.c b/lib_dec/ivas_out_setup_conversion_fx.c similarity index 99% rename from lib_dec/ivas_out_setup_conversion.c rename to lib_dec/ivas_out_setup_conversion_fx.c index 59a560f3318c21af5da8ad9b7f2a3d90fb84e8c7..c7bf0655d9ea765be0f1310a09229b8f553203a0 100644 --- a/lib_dec/ivas_out_setup_conversion.c +++ b/lib_dec/ivas_out_setup_conversion_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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,13 +34,11 @@ #include "options.h" #include #include -#include "prot.h" -#include "ivas_prot.h" -#include "ivas_prot_rend.h" +#include "prot_fx.h" +#include "ivas_prot_rend_fx.h" #include "ivas_rom_com.h" #include "ivas_rom_rend.h" #include "wmc_auto.h" -#include "prot_fx.h" #include "ivas_prot_fx.h" #include "debug.h" diff --git a/lib_dec/ivas_output_config.c b/lib_dec/ivas_output_config_fx.c similarity index 91% rename from lib_dec/ivas_output_config.c rename to lib_dec/ivas_output_config_fx.c index 64995d8a0ac9975fc5847f762be5bac13d8ed472..c98a9514e805c562381b02b911cabe68665652c4 100644 --- a/lib_dec/ivas_output_config.c +++ b/lib_dec/ivas_output_config_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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,7 +33,6 @@ #include #include "options.h" #include "ivas_cnst.h" -#include "ivas_prot.h" #include "ivas_stat_dec.h" #include "wmc_auto.h" #include "ivas_prot_fx.h" @@ -81,7 +80,11 @@ void ivas_renderer_select( test(); test(); test(); +#ifdef SPLIT_REND_WITH_HEAD_ROT + IF( EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL ) || EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR ) || EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) || EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) || EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ) +#else IF( EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL ) || EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR ) || EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) ) +#endif { test(); test(); @@ -92,7 +95,11 @@ void ivas_renderer_select( { IF( EQ_32( st_ivas->ism_mode, ISM_MODE_PARAM ) ) { +#ifdef SPLIT_REND_WITH_HEAD_ROT + IF( EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL ) || EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) || EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ) +#else IF( EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL ) ) +#endif { *renderer_type = RENDERER_BINAURAL_PARAMETRIC; move16(); @@ -106,7 +113,11 @@ void ivas_renderer_select( ELSE /* ISM_MODE_DISC */ { test(); +#ifdef SPLIT_REND_WITH_HEAD_ROT + IF( EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL ) || EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) || EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) || EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ) +#else IF( EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL ) || EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) ) +#endif { *renderer_type = RENDERER_BINAURAL_OBJECTS_TD; move16(); @@ -126,8 +137,11 @@ void ivas_renderer_select( { *internal_config = output_config; move16(); - +#ifdef SPLIT_REND_WITH_HEAD_ROT + IF( EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL ) || EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) || EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ) +#else IF( EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL ) ) +#endif { *renderer_type = RENDERER_BINAURAL_PARAMETRIC; move16(); @@ -144,7 +158,11 @@ void ivas_renderer_select( move16(); test(); +#ifdef SPLIT_REND_WITH_HEAD_ROT + IF( EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL ) || EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) || EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) || EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ) +#else IF( EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL ) || EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) ) +#endif { *renderer_type = RENDERER_BINAURAL_FASTCONV; move16(); @@ -199,7 +217,11 @@ void ivas_renderer_select( *internal_config = output_config; move16(); +#ifdef SPLIT_REND_WITH_HEAD_ROT + IF( EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL ) || EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) || EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ) +#else IF( EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL ) ) +#endif { *renderer_type = RENDERER_BINAURAL_PARAMETRIC; move16(); @@ -215,7 +237,11 @@ void ivas_renderer_select( *internal_config = transport_config; move16(); test(); +#ifdef SPLIT_REND_WITH_HEAD_ROT + IF( EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL ) || EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) || EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) || EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ) +#else IF( EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL ) || EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) ) +#endif { test(); test(); diff --git a/lib_dec/ivas_pca_dec.c b/lib_dec/ivas_pca_dec.c deleted file mode 100644 index 9e3fbe939c4338e66d95957265d671b0fe345df0..0000000000000000000000000000000000000000 --- a/lib_dec/ivas_pca_dec.c +++ /dev/null @@ -1,44 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -#include -#include "options.h" -#include "prot.h" -#include "ivas_prot.h" -#include -#include "ivas_cnst.h" -#include "wmc_auto.h" - - -/*-----------------------------------------------------------------------* - * Local function definitions - *-----------------------------------------------------------------------*/ diff --git a/lib_dec/ivas_pca_dec_fx.c b/lib_dec/ivas_pca_dec_fx.c index 1700c25277779bb3ff25bb9da451510e2bc491ac..98611ab7cbcf9af52799eb55c91a6353ee726624 100644 --- a/lib_dec/ivas_pca_dec_fx.c +++ b/lib_dec/ivas_pca_dec_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2023 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other @@ -32,12 +32,10 @@ #include #include "options.h" -#include "prot.h" -#include "ivas_prot.h" +#include "prot_fx.h" #include #include "ivas_cnst.h" #include "wmc_auto.h" -#include "prot_fx.h" #include "math.h" #include "ivas_prot_fx.h" diff --git a/lib_dec/ivas_post_proc.c b/lib_dec/ivas_post_proc_fx.c similarity index 93% rename from lib_dec/ivas_post_proc.c rename to lib_dec/ivas_post_proc_fx.c index ce361c8944e774d6b7cb85ae67db39b31de58a8d..9357394a5741ee2b152504f8db29d408374c4801 100644 --- a/lib_dec/ivas_post_proc.c +++ b/lib_dec/ivas_post_proc_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other @@ -35,9 +35,7 @@ #include "options.h" #include "cnst.h" #include "rom_com.h" -#include "prot.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "ivas_prot_fx.h" #include "ivas_cnst.h" #include "wmc_auto.h" @@ -159,7 +157,7 @@ void ivas_post_proc_fx( ELSE { /*Use channel 0 side info.*/ - tcx_ltp_post32( sts[0], hTcxLtpDec, TCX_20_CORE, output_frame, NS2SA( output_Fs, STEREO_DFT32MS_OVL_NS ), output[k], hCPE->output_mem_fx[k], output_q ); + tcx_ltp_post32( sts[0], hTcxLtpDec, TCX_20_CORE, output_frame, NS2SA_FX2( output_Fs, STEREO_DFT32MS_OVL_NS ), output[k], hCPE->output_mem_fx[k], output_q ); } } } @@ -268,7 +266,7 @@ void stereo_dft_dec_core_switching_fx( IF( ( ( ( st->last_core != ACELP_CORE ) || ( EQ_16( st->prev_bfi, 1 ) && EQ_16( st->last_core, ACELP_CORE ) && EQ_16( st->last_con_tcx, 1 ) ) ) && NE_16( st->last_core, AMR_WB_CORE ) ) || ( sba_dirac_stereo_dtx_flag && EQ_16( st->cng_type, FD_CNG ) ) ) /* TCX / HQ-CORE -> TCX / HQ-CORE */ { /* In case of a TCX to ACELP switch next frame */ - Copy32( &output_fx[st->L_frame - NS2SA_FX2( L_mult0( st->L_frame, FRAMES_PER_SEC ), STEREO_DFT32MS_OVL_NS )], hCPE->hStereoDft->buff_LBTCX_mem_fx, NS2SA_FX2( L_mult0( st->L_frame, FRAMES_PER_SEC ), STEREO_DFT32MS_OVL_NS ) ); /*q*/ + Copy32( &output_fx[st->L_frame - NS2SA( ( st->L_frame * FRAMES_PER_SEC ), STEREO_DFT32MS_OVL_NS )], hCPE->hStereoDft->buff_LBTCX_mem_fx, NS2SA_FX2( L_mult0( st->L_frame, FRAMES_PER_SEC ), STEREO_DFT32MS_OVL_NS ) ); /*q*/ /* BPF */ test(); @@ -296,7 +294,11 @@ void stereo_dft_dec_core_switching_fx( { Word16 mem_len = NS2SA_FX2( L_mult0( L_frameTCX, FRAMES_PER_SEC ), STEREO_DFT32MS_OVL_NS ); /*Q0*/ move16(); +#ifdef MSAN_FIX + Word32 mem_len_inv = mem_len_inv_tbl[( mem_len / 25 ) - 1]; +#else Word32 mem_len_inv = mem_len_inv_tbl[( mem_len / 25 )]; +#endif move32(); Word16 qmem_len = norm_l( mem_len ); Word32 mem_len_fx = L_shl( mem_len, qmem_len ); @@ -311,8 +313,8 @@ void stereo_dft_dec_core_switching_fx( /* Update FB input buff with hb synth FOR last delay_tdbwe sampled */ FOR( i = 0; i < delay_tdbwe; i++ ) { - hCPE->input_mem_fx[0][( ( NS2SA_FX2( L_mult0( L_frameTCX, FRAMES_PER_SEC ), STEREO_DFT32MS_OVL_NS ) - delay_tdbwe ) + i )] = - L_add( hCPE->input_mem_fx[0][NS2SA_FX2( L_add( L_sub( L_mult0( L_frameTCX, FRAMES_PER_SEC ), STEREO_DFT32MS_OVL_NS ), delay_tdbwe ), i )], hb_synth_fx[i] ); /*Q11*/ + hCPE->input_mem_fx[0][( ( NS2SA( L_frameTCX * FRAMES_PER_SEC, STEREO_DFT32MS_OVL_NS ) - delay_tdbwe ) + i )] = + L_add( hCPE->input_mem_fx[0][NS2SA( ( ( L_frameTCX * FRAMES_PER_SEC ) - STEREO_DFT32MS_OVL_NS ) + delay_tdbwe, i )], hb_synth_fx[i] ); /*Q11*/ move32(); } } @@ -321,7 +323,7 @@ void stereo_dft_dec_core_switching_fx( /* Update FB input buff with hb synth FOR last delay_tdbwe sampled */ FOR( i = 0; i < delay_tdbwe; i++ ) { - hCPE->input_mem_fx[0][( ( NS2SA_FX2( L_mult0( L_frameTCX, FRAMES_PER_SEC ), STEREO_DFT32MS_OVL_NS ) - delay_tdbwe ) + i )] = hb_synth_fx[i]; /*Q11*/ + hCPE->input_mem_fx[0][( ( NS2SA_FX2( L_frameTCX * FRAMES_PER_SEC, STEREO_DFT32MS_OVL_NS ) - delay_tdbwe ) + i )] = hb_synth_fx[i]; /*Q11*/ move32(); } } @@ -364,7 +366,7 @@ void stereo_dft_dec_core_switching_fx( /* In case of TCX frames, output LB TCX is zeroed out until the end but in case of an TCX->ACELP switch, this memory is needed, hence it is backed up */ /* Unlike the case when DFT32MS is disabled, there is only 1 DFT analysis window, hence in the TCX frame we don't want to do a DFT analysis FOR LB TCX but in a potential ACELP frame, we want the memories of the LB TCX FOR the last OLA samples so that HB analysis can be skipped */ - Copy32( &output_fx[st->L_frame - NS2SA_FX2( L_mult0( st->L_frame, FRAMES_PER_SEC ), STEREO_DFT32MS_OVL_NS )], hCPE->hStereoDft->buff_LBTCX_mem_fx, NS2SA_FX2( L_mult0( st->L_frame, FRAMES_PER_SEC ), STEREO_DFT32MS_OVL_NS ) ); /*q*/ + Copy32( &output_fx[st->L_frame - NS2SA_FX2( st->L_frame * FRAMES_PER_SEC, STEREO_DFT32MS_OVL_NS )], hCPE->hStereoDft->buff_LBTCX_mem_fx, NS2SA_FX2( L_mult0( st->L_frame, FRAMES_PER_SEC ), STEREO_DFT32MS_OVL_NS ) ); /*q*/ /*zero the rest FOR avoiding adding contribution except the last samples which are not considered in DFT analysis (potentially used in next ACELP frame)*/ IF( GT_32( st->last_core_brate, SID_2k40 ) ) @@ -414,8 +416,8 @@ void stereo_dft_dec_core_switching_fx( delay_comp = NS2SA_FX2( st->output_Fs, DELAY_CLDFB_NS ); /*Q0*/ move16(); - Copy32( &st->hHQ_core->oldOut_fx[( nZeros - ( delay_comp + NS2SA_FX2( L_mult0( output_frame, FRAMES_PER_SEC ), STEREO_DFT32MS_OVL_NS ) ) )], hCPE->input_mem_fx[0], NS2SA_FX2( L_mult0( output_frame, FRAMES_PER_SEC ), STEREO_DFT32MS_OVL_NS ) ); /*Q11*/ - Copy32( synth_fx, synth_tmp_fx, output_frame ); /*q*/ + Copy32( &st->hHQ_core->oldOut_fx[nZeros - ( delay_comp + NS2SA( output_frame * FRAMES_PER_SEC, STEREO_DFT32MS_OVL_NS ) )], hCPE->input_mem_fx[0], NS2SA_FX2( L_mult0( output_frame, FRAMES_PER_SEC ), STEREO_DFT32MS_OVL_NS ) ); /*Q11*/ + Copy32( synth_fx, synth_tmp_fx, output_frame ); /*q*/ Word16 mem_len; mem_len = NS2SA_FX2( L_mult0( st->L_frame, FRAMES_PER_SEC ), STEREO_DFT32MS_OVL_NS ); /*Q0*/ @@ -458,11 +460,11 @@ void stereo_dft_dec_core_switching_fx( Word32 delay_dft_dec_lb_inv = (Word32) ( calc_inv / delay_dft_dec_lb ); FOR( i = 0; i < delay_dft_dec_lb; i++ ) { - hCPE->input_mem_LB_fx[0][( ( NS2SA_FX2( L_mult0( st->L_frame, FRAMES_PER_SEC ), STEREO_DFT32MS_OVL_NS ) - delay_dft_dec_lb ) + i )] = - Mpy_32_32( hCPE->input_mem_LB_fx[0][( ( NS2SA_FX2( L_mult0( st->L_frame, FRAMES_PER_SEC ), STEREO_DFT32MS_OVL_NS ) - delay_dft_dec_lb ) + i )], L_shl( i, qdelay_dft_dec_lb ) ); /*Q11 + qdelay_dft_dec_lb -31*/ + hCPE->input_mem_LB_fx[0][( ( NS2SA( st->L_frame * FRAMES_PER_SEC, STEREO_DFT32MS_OVL_NS ) - delay_dft_dec_lb ) + i )] = + Mpy_32_32( hCPE->input_mem_LB_fx[0][( NS2SA( st->L_frame * FRAMES_PER_SEC, STEREO_DFT32MS_OVL_NS ) - delay_dft_dec_lb ) + i], L_shl( i, qdelay_dft_dec_lb ) ); /*Q11 + qdelay_dft_dec_lb -31*/ move32(); - hCPE->input_mem_LB_fx[0][( ( NS2SA_FX2( L_mult0( st->L_frame, FRAMES_PER_SEC ), STEREO_DFT32MS_OVL_NS ) - delay_dft_dec_lb ) + i )] = - L_shl( Mpy_32_32( hCPE->input_mem_LB_fx[0][( ( NS2SA_FX2( L_mult0( st->L_frame, FRAMES_PER_SEC ), STEREO_DFT32MS_OVL_NS ) - delay_dft_dec_lb ) + i )], delay_dft_dec_lb_inv ), sub( Q31, qdelay_dft_dec_lb ) ); /*Q11*/ + hCPE->input_mem_LB_fx[0][( ( NS2SA( st->L_frame * FRAMES_PER_SEC, STEREO_DFT32MS_OVL_NS ) - delay_dft_dec_lb ) + i )] = + L_shl( Mpy_32_32( hCPE->input_mem_LB_fx[0][( ( NS2SA( st->L_frame * FRAMES_PER_SEC, STEREO_DFT32MS_OVL_NS ) - delay_dft_dec_lb ) + i )], delay_dft_dec_lb_inv ), sub( Q31, qdelay_dft_dec_lb ) ); /*Q11*/ move32(); } stereo_dft_dec_analyze_fx( hCPE, output_fx, DFT_fx, 0, st->L_frame, output_frame, DFT_STEREO_DEC_ANA_LB, 0, 0, q, q_DFT ); diff --git a/lib_dec/ivas_qmetadata_dec.c b/lib_dec/ivas_qmetadata_dec_fx.c similarity index 99% rename from lib_dec/ivas_qmetadata_dec.c rename to lib_dec/ivas_qmetadata_dec_fx.c index 434fc958df433872148cbcdbefe70e1a152112c0..c78c51c52aae3a7351ac604da7fea2a00521c962 100644 --- a/lib_dec/ivas_qmetadata_dec.c +++ b/lib_dec/ivas_qmetadata_dec_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other @@ -35,13 +35,11 @@ #include "options.h" #include #include "ivas_cnst.h" -#include "ivas_prot.h" #include "ivas_rom_com.h" #include "ivas_rom_dec.h" #include "wmc_auto.h" -#include "prot.h" - #include "prot_fx.h" + #include "ivas_prot_fx.h" #include "ivas_rom_com_fx.h" @@ -3258,7 +3256,8 @@ static Word16 read_truncGR_azimuth_fx( move16(); IF( LE_16( allowed_bits, add( no_subframes, 1 ) ) ) { - FOR( i = 0; i < min( allowed_bits, no_subframes ); i++ ) + Word16 len = s_min( allowed_bits, no_subframes ); + FOR( i = 0; i < len; i++ ) { IF( bitstream[( *pbit_pos )--] == 0 ) { diff --git a/lib_dec/ivas_qspherical_dec.c b/lib_dec/ivas_qspherical_dec_fx.c similarity index 97% rename from lib_dec/ivas_qspherical_dec.c rename to lib_dec/ivas_qspherical_dec_fx.c index 446c64b6cd63c9277311d1ee9a80a9448ea56c8e..f6ac39a99f081d7fc2a3d63802bb9983abe5bc7c 100644 --- a/lib_dec/ivas_qspherical_dec.c +++ b/lib_dec/ivas_qspherical_dec_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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,11 +33,10 @@ #include #include "options.h" #include "ivas_cnst.h" -#include "ivas_prot.h" #include "ivas_rom_com.h" #include "ivas_stat_dec.h" #include "wmc_auto.h" -#include "prot.h" +#include "prot_fx.h" #include "ivas_rom_com_fx.h" #include "ivas_prot_fx.h" diff --git a/lib_dec/ivas_range_uni_dec.c b/lib_dec/ivas_range_uni_dec_fx.c similarity index 99% rename from lib_dec/ivas_range_uni_dec.c rename to lib_dec/ivas_range_uni_dec_fx.c index 3da244dd875ca003fc9ffdfedf8c716b23b3241f..9a49680e874a2d665b7ba37e3e0c2c47334cc18a 100644 --- a/lib_dec/ivas_range_uni_dec.c +++ b/lib_dec/ivas_range_uni_dec_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other @@ -31,17 +31,15 @@ *******************************************************************************************************/ #include -#include "ivas_prot.h" #include "ivas_cnst.h" #include "ivas_stat_dec.h" #include "cnst.h" #include "rom_com.h" #include #include "options.h" -#include "prot.h" +#include "prot_fx.h" #include "wmc_auto.h" #include "ivas_prot_fx.h" -#include "prot_fx.h" /* diff --git a/lib_dec/ivas_rom_dec.c b/lib_dec/ivas_rom_dec.c index e7324617670fe378a713259a12a88020f3c34604..6f75230c9510b987af703f417b2b20e655e107f7 100644 --- a/lib_dec/ivas_rom_dec.c +++ b/lib_dec/ivas_rom_dec.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other @@ -100,7 +100,7 @@ const Word32 dft_ap_gains_fx[5][3] = { 644245094, -644245120, 1073741824 } }; -const int16_t dft_ap_delays[3][3] = +const Word16 dft_ap_delays[3][3] = { { 2, 47, 61}, {29, 41, 73}, @@ -196,7 +196,7 @@ const Word16 dft_win_8k_fx[70] = * stereo CNA tables *------------------------------------------------------------------------*/ -const int16_t cna_init_bands[CNA_INIT_NBANDS + 1] = +const Word16 cna_init_bands[CNA_INIT_NBANDS + 1] = { 1, 4, 14, 33, 67, 171, 320 }; @@ -235,7 +235,7 @@ const Word16 min_smooth_gains2_fx[SBA_DIRAC_STEREO_NUM_BANDS] = /* all the "probability" tables for the actual AC are in the reversed cumulative counts table format; for example, given the counts table [c0 | c1 | c2 | c3] with c0 + c1 + c2 + c3 = 2 ^ 14, the reversed cumulative counts table is [2 ^ 14 | 2 ^ 14 - c0 | 2 ^ 14 - c0 - c1 | 2 ^ 14 - c0 - c1 - c2 | 2 ^ 14 - c0 - c1 - c2 - c3] */ -const uint16_t cum_freq_ECSQ_tab_param[ECSQ_CONFIG_COUNT][1 + ECSQ_PARAM_COUNT] = +const UWord16 cum_freq_ECSQ_tab_param[ECSQ_CONFIG_COUNT][1 + ECSQ_PARAM_COUNT] = { {0,1024,2048,3072,4096,5120,6144,7168,8192,9216,10240,11264,12288,13312,14336,15360,16384 }, {0,9294,16019,16213,16311,16346,16363,16371,16375,16377,16378,16379,16380,16381,16382,16383,16384 }, @@ -246,7 +246,7 @@ const uint16_t cum_freq_ECSQ_tab_param[ECSQ_CONFIG_COUNT][1 + ECSQ_PARAM_COUNT] {0,5836,14448,15610,16267,16343,16374,16375,16376,16377,16378,16379,16380,16381,16382,16383,16384 } }; -const uint16_t sym_freq_ECSQ_tab_param[ECSQ_CONFIG_COUNT][ECSQ_PARAM_COUNT] = +const UWord16 sym_freq_ECSQ_tab_param[ECSQ_CONFIG_COUNT][ECSQ_PARAM_COUNT] = { {1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024 }, {9294,6725,194,98,35,17,8,4,2,1,1,1,1,1,1,1 }, @@ -257,7 +257,7 @@ const uint16_t sym_freq_ECSQ_tab_param[ECSQ_CONFIG_COUNT][ECSQ_PARAM_COUNT] = {5836,8612,1162,657,76,31,1,1,1,1,1,1,1,1,1,1 } }; -const uint16_t cum_freq_ECSQ_tab_vals[ECSQ_PARAM_COUNT - 1][1 + ECSQ_TAB_VALS_SIZE] = +const UWord16 cum_freq_ECSQ_tab_vals[ECSQ_PARAM_COUNT - 1][1 + ECSQ_TAB_VALS_SIZE] = { {0,6445,12725,15035,15885,16198,16313,16355,16370,16376,16378,16379,16380,16381,16382,16383,16384 }, {0,3624,8645,11690,13537,14657,15336,15748,15998,16150,16242,16298,16332,16352,16364,16372,16384 }, @@ -276,7 +276,7 @@ const uint16_t cum_freq_ECSQ_tab_vals[ECSQ_PARAM_COUNT - 1][1 + ECSQ_TAB_VALS_SI {0,3623,6446,8644,10356,11689,12727,13536,14166,14657,15039,15337,15569,15749,15890,15999,16384 }, }; -const uint16_t sym_freq_ECSQ_tab_vals[ECSQ_PARAM_COUNT - 1][ECSQ_TAB_VALS_SIZE] = +const UWord16 sym_freq_ECSQ_tab_vals[ECSQ_PARAM_COUNT - 1][ECSQ_TAB_VALS_SIZE] = { {6445,6280,2310,850,313,115,42,15,6,2,1,1,1,1,1,1 }, {3624,5021,3045,1847,1120,679,412,250,152,92,56,34,20,12,8,12 }, @@ -295,59 +295,59 @@ const uint16_t sym_freq_ECSQ_tab_vals[ECSQ_PARAM_COUNT - 1][ECSQ_TAB_VALS_SIZE] {3623,2823,2198,1712,1333,1038,809,630,491,382,298,232,180,141,109,385 }, }; -const uint16_t cum_freq_ECSQ_tab_abs_1bit[1 + 2] = +const UWord16 cum_freq_ECSQ_tab_abs_1bit[1 + 2] = { 0, 5462, 16384 }; /* table for uniform coding of absolute values in {0, +-1, +-2, +-3} */ -const uint16_t cum_freq_ECSQ_tab_abs_2bit[1 + 4] = +const UWord16 cum_freq_ECSQ_tab_abs_2bit[1 + 4] = { 0, 2338, 7020, 11702, 16384 }; /* table for uniform coding of absolute values in {0, +-1, ..., +-7} */ -const uint16_t cum_freq_ECSQ_tab_abs_3bit[1 + 8] = +const UWord16 cum_freq_ECSQ_tab_abs_3bit[1 + 8] = { 0, 1096, 3280, 5464, 7648, 9832, 12016, 14200, 16384 }; /* table for uniform coding of absolute values in {0, +-1, ..., +-15} */ -const uint16_t cum_freq_ECSQ_tab_abs_4bit[1 + 16] = +const UWord16 cum_freq_ECSQ_tab_abs_4bit[1 + 16] = { 0, 514, 1572, 2630, 3688, 4746, 5804, 6862, 7920, 8978, 10036, 11094, 12152, 13210, 14268, 15326, 16384 }; -const uint16_t sym_freq_ECSQ_tab_abs_1bit[2] = +const UWord16 sym_freq_ECSQ_tab_abs_1bit[2] = { 5462, 10922 }; /* table for uniform coding of absolute values in {0, +-1, +-2, +-3} */ -const uint16_t sym_freq_ECSQ_tab_abs_2bit[4] = +const UWord16 sym_freq_ECSQ_tab_abs_2bit[4] = { 2338, 4682, 4682, 4682 }; /* table for uniform coding of absolute values in {0, +-1, ..., +-7} */ -const uint16_t sym_freq_ECSQ_tab_abs_3bit[8] = +const UWord16 sym_freq_ECSQ_tab_abs_3bit[8] = { 1096, 2184, 2184, 2184, 2184, 2184, 2184, 2184 }; /* table for uniform coding of absolute values in {0, +-1, ..., +-15} */ -const uint16_t sym_freq_ECSQ_tab_abs_4bit[16] = +const UWord16 sym_freq_ECSQ_tab_abs_4bit[16] = { 514, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058 }; /* array of tables for uniform coding of absolute values */ -const uint16_t * const cum_freq_ECSQ_tab_abs_lsbs[1 + 4] = +const UWord16 * const cum_freq_ECSQ_tab_abs_lsbs[1 + 4] = { NULL, cum_freq_ECSQ_tab_abs_1bit, cum_freq_ECSQ_tab_abs_2bit, cum_freq_ECSQ_tab_abs_3bit, cum_freq_ECSQ_tab_abs_4bit }; -const uint16_t * const sym_freq_ECSQ_tab_abs_lsbs[1 + 4] = +const UWord16 * const sym_freq_ECSQ_tab_abs_lsbs[1 + 4] = { NULL, sym_freq_ECSQ_tab_abs_1bit, sym_freq_ECSQ_tab_abs_2bit, sym_freq_ECSQ_tab_abs_3bit, sym_freq_ECSQ_tab_abs_4bit }; @@ -391,7 +391,7 @@ const Word32 dmxmtx_table_fx[BINAURAL_CHANNELS][11] = *-----------------------------------------------------------------------*/ /* Alpha Fine Huffman table df0 */ -static const int16_t huff_nodes_first_band_alpha[32][2] = +static const Word16 huff_nodes_first_band_alpha[32][2] = { { -17, 1 }, { 3, 2 }, @@ -428,7 +428,7 @@ static const int16_t huff_nodes_first_band_alpha[32][2] = }; /* Alpha Fine Huffman table df */ -static const int16_t huff_nodes_alpha_1D_DF[64][2] = +static const Word16 huff_nodes_alpha_1D_DF[64][2] = { { -33, 1 }, { 3, 2 }, @@ -497,7 +497,7 @@ static const int16_t huff_nodes_alpha_1D_DF[64][2] = }; /* Alpha Fine Huffman table dt */ -static const int16_t huff_nodes_alpha_1D_DT[64][2] = +static const Word16 huff_nodes_alpha_1D_DT[64][2] = { { -33, 1 }, { -34, 2 }, @@ -566,19 +566,19 @@ static const int16_t huff_nodes_alpha_1D_DT[64][2] = }; /* Beta Fine Huffman table df0 */ -static const int16_t huff_nodes_first_band_beta[8][2] = +static const Word16 huff_nodes_first_band_beta[8][2] = { { -1, 1 }, { -2, 2 }, { -3, 3 }, { -4, 4 }, { -5, 5 }, { -6, 6 }, { -7, 7 }, { -8, -9 } }; /* Beta Fine Huffman table df */ -static const int16_t huff_nodes_beta_1D_DF[16][2] = +static const Word16 huff_nodes_beta_1D_DF[16][2] = { { -9, 1 }, { -10, 2 }, { -8, 3 }, { -11, 4 }, { -7, 5 }, { 7, 6 }, { -6, -12 }, { 9, 8 }, { -5, -13 }, { 11, 10 }, { -4, -14 }, { -15, 12 }, { -3, 13 }, { -16, 14 }, { -2, 15 }, { -1, -17 } }; /* Beta Fine Huffman table dt */ -static const int16_t huff_nodes_beta_1D_DT[16][2] = +static const Word16 huff_nodes_beta_1D_DT[16][2] = { { -9, 1 }, { -10, 2 }, { -8, 3 }, { -11, 4 }, { -7, 5 }, { 7, 6 }, { -6, -12 }, { -13, 8 }, { -5, 9 }, { -14, 10 }, { -4, 11 }, { -15, 12 }, { -3, 13 }, { -16, 14 }, { -2, 15 }, { -1, -17 } }; diff --git a/lib_dec/ivas_rom_dec.h b/lib_dec/ivas_rom_dec.h index e79c50856f2c926367dcd465e39efa88220f3b8e..84c1a94a07d72577dc9dcafdef45974da14bc540 100644 --- a/lib_dec/ivas_rom_dec.h +++ b/lib_dec/ivas_rom_dec.h @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other @@ -53,7 +53,7 @@ extern const Word16 dft_alpha_s2_b2_fx[STEREO_DFT_BAND_MAX]; extern const Word32 dft_bpf_weights_fx[]; extern const Word32 dft_ap_gains_fx[5][3]; -extern const int16_t dft_ap_delays[3][3]; +extern const Word16 dft_ap_delays[3][3]; extern const Word16 dft_win232ms_8k_fx[75]; extern const Word16 dft_win232ms_12k8_fx[120]; extern const Word16 dft_win232ms_16k_fx[150]; @@ -62,7 +62,7 @@ extern const Word16 dft_win232ms_48k_fx[450]; extern const Word16 dft_res_pred_weights_fx[][STEREO_DFT_BAND_MAX]; extern const Word16 dft_win_8k_fx[70]; -extern const int16_t cna_init_bands[CNA_INIT_NBANDS + 1]; +extern const Word16 cna_init_bands[CNA_INIT_NBANDS + 1]; extern const Word16 min_smooth_gains1_fx[SBA_DIRAC_STEREO_NUM_BANDS]; @@ -74,12 +74,12 @@ extern const Word16 max_smooth_gains2_fx[SBA_DIRAC_STEREO_NUM_BANDS]; * ECLVQ Stereo ROM tables *----------------------------------------------------------------------------------*/ -extern const uint16_t cum_freq_ECSQ_tab_param[ECSQ_CONFIG_COUNT][1 + ECSQ_PARAM_COUNT]; -extern const uint16_t sym_freq_ECSQ_tab_param[ECSQ_CONFIG_COUNT][ECSQ_PARAM_COUNT]; -extern const uint16_t cum_freq_ECSQ_tab_vals[ECSQ_PARAM_COUNT - 1][1 + ECSQ_TAB_VALS_SIZE]; -extern const uint16_t sym_freq_ECSQ_tab_vals[ECSQ_PARAM_COUNT - 1][ECSQ_TAB_VALS_SIZE]; -extern const uint16_t *const cum_freq_ECSQ_tab_abs_lsbs[1 + 4]; -extern const uint16_t *const sym_freq_ECSQ_tab_abs_lsbs[1 + 4]; +extern const UWord16 cum_freq_ECSQ_tab_param[ECSQ_CONFIG_COUNT][1 + ECSQ_PARAM_COUNT]; +extern const UWord16 sym_freq_ECSQ_tab_param[ECSQ_CONFIG_COUNT][ECSQ_PARAM_COUNT]; +extern const UWord16 cum_freq_ECSQ_tab_vals[ECSQ_PARAM_COUNT - 1][1 + ECSQ_TAB_VALS_SIZE]; +extern const UWord16 sym_freq_ECSQ_tab_vals[ECSQ_PARAM_COUNT - 1][ECSQ_TAB_VALS_SIZE]; +extern const UWord16 *const cum_freq_ECSQ_tab_abs_lsbs[1 + 4]; +extern const UWord16 *const sym_freq_ECSQ_tab_abs_lsbs[1 + 4]; /*----------------------------------------------------------------------------------* diff --git a/lib_dec/ivas_sba_dec.c b/lib_dec/ivas_sba_dec_fx.c similarity index 93% rename from lib_dec/ivas_sba_dec.c rename to lib_dec/ivas_sba_dec_fx.c index e27bc063809994fe3b4b035f7e2632c97890831d..2d96ce81ac502883998637832a96744ff270be1c 100644 --- a/lib_dec/ivas_sba_dec.c +++ b/lib_dec/ivas_sba_dec_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other @@ -35,16 +35,14 @@ #include "options.h" #include "cnst.h" #include "ivas_cnst.h" -#include "prot.h" -#include "ivas_prot.h" -#include "ivas_prot_rend.h" +#include "prot_fx.h" +#include "ivas_prot_rend_fx.h" #include "rom_com.h" #include "ivas_rom_com.h" #include "ivas_rom_dec.h" #include #include "wmc_auto.h" #include "ivas_prot_fx.h" -#include "prot_fx.h" /*-------------------------------------------------------------------* * ivas_sba_set_cna_cng_flag() * @@ -185,7 +183,11 @@ ivas_error ivas_sba_dec_reconfigure_fx( test(); test(); test(); +#ifdef SPLIT_REND_WITH_HEAD_ROT + IF( EQ_16( st_ivas->ivas_format, SBA_ISM_FORMAT ) && ( EQ_16( st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_BINAURAL ) || EQ_16( st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR ) || EQ_16( st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) || EQ_16( st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) || EQ_16( st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ) ) +#else IF( EQ_16( st_ivas->ivas_format, SBA_ISM_FORMAT ) && ( EQ_16( st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_BINAURAL ) || EQ_16( st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR ) || EQ_16( st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) ) ) +#endif { RENDERER_TYPE renderer_type_new; Word16 sba_order_internal; @@ -196,7 +198,11 @@ ivas_error ivas_sba_dec_reconfigure_fx( /* copy the logic from ivas_renderer_select(), because calling this function has too many side effects that would affect the flushing */ IF( LE_16( ivas_get_sba_num_TCs_fx( ivas_total_brate, sba_order_internal ), 2 ) ) { +#ifdef SPLIT_REND_WITH_HEAD_ROT + IF( EQ_16( st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_BINAURAL ) || EQ_16( st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) || EQ_16( st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ) +#else IF( EQ_16( st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_BINAURAL ) ) +#endif { renderer_type_new = RENDERER_BINAURAL_PARAMETRIC; move16(); @@ -210,7 +216,11 @@ ivas_error ivas_sba_dec_reconfigure_fx( ELSE { test(); +#ifdef SPLIT_REND_WITH_HEAD_ROT + IF( EQ_16( st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_BINAURAL ) || EQ_16( st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) || EQ_16( st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) || EQ_16( st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ) +#else IF( EQ_16( st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_BINAURAL ) || EQ_16( st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) ) +#endif { renderer_type_new = RENDERER_BINAURAL_FASTCONV; move16(); @@ -223,7 +233,7 @@ ivas_error ivas_sba_dec_reconfigure_fx( } /* determine new granularity */ - granularity_new = NS2SA( st_ivas->hDecoderConfig->output_Fs, CLDFB_SLOT_NS ); /*Q0*/ + granularity_new = NS2SA_FX2( st_ivas->hDecoderConfig->output_Fs, CLDFB_SLOT_NS ); /*Q0*/ move16(); /* this will change anyway only with binaural */ @@ -351,7 +361,12 @@ ivas_error ivas_sba_dec_reconfigure_fx( test(); test(); test(); +#ifdef NONBE_FIX_708_OSBA_BR_SWITCHING_CRASH + test(); + IF( hSpar->hPCA == NULL && EQ_32( st_ivas->hDecoderConfig->ivas_total_brate, PCA_BRATE ) && EQ_16( st_ivas->sba_order, 1 ) && ( EQ_32( st_ivas->ivas_format, SBA_FORMAT ) || EQ_32( st_ivas->ivas_format, SBA_ISM_FORMAT ) ) ) +#else IF( hSpar->hPCA == NULL && EQ_32( st_ivas->hDecoderConfig->ivas_total_brate, PCA_BRATE ) && EQ_16( st_ivas->sba_order, 1 ) && EQ_32( st_ivas->ivas_format, SBA_FORMAT ) ) +#endif { IF( ( hSpar->hPCA = (PCA_DEC_STATE *) malloc( sizeof( PCA_DEC_STATE ) ) ) == NULL ) { @@ -628,6 +643,15 @@ ivas_error ivas_sba_dec_reconfigure_fx( * TD Decorrelator *-----------------------------------------------------------------*/ +#ifdef SPLIT_REND_WITH_HEAD_ROT + IF( st_ivas->hDiracDecBin[0] != NULL ) + { + IF( NE_32( ( error = ivas_td_decorr_reconfig_dec( st_ivas->ivas_format, st_ivas->hDecoderConfig->ivas_total_brate, st_ivas->nchan_transport, st_ivas->hDecoderConfig->output_Fs, &( st_ivas->hDiracDecBin[0]->hTdDecorr ), &( st_ivas->hDiracDecBin[0]->useTdDecorr ) ) ), IVAS_ERR_OK ) ) + { + return error; + } + } +#else IF( st_ivas->hDiracDecBin != NULL ) { IF( NE_32( ( error = ivas_td_decorr_reconfig_dec( st_ivas->ivas_format, st_ivas->hDecoderConfig->ivas_total_brate, st_ivas->nchan_transport, st_ivas->hDecoderConfig->output_Fs, &( st_ivas->hDiracDecBin->hTdDecorr ), &( st_ivas->hDiracDecBin->useTdDecorr ) ) ), IVAS_ERR_OK ) ) @@ -635,6 +659,7 @@ ivas_error ivas_sba_dec_reconfigure_fx( return error; } } +#endif /*-----------------------------------------------------------------* * CLDFB instances @@ -784,7 +809,11 @@ void ivas_sba_dec_digest_tc_fx( ivas_spar_dec_digest_tc_fx( st_ivas, st_ivas->nchan_transport, nCldfbSlots, nSamplesForRendering ); } test(); +#ifdef SPLIT_REND_WITH_HEAD_ROT + IF( st_ivas->hDiracDecBin[0] != NULL && st_ivas->hDiracDecBin[0]->useTdDecorr ) +#else IF( st_ivas->hDiracDecBin != NULL && ( st_ivas->hDiracDecBin->useTdDecorr ) ) +#endif { Word16 nSamplesLeftForTD, default_frame; Word32 *decorr_signal[BINAURAL_CHANNELS]; @@ -807,9 +836,17 @@ void ivas_sba_dec_digest_tc_fx( { Word16 nSamplesToDecorr = s_min( nSamplesLeftForTD, default_frame ); /*Q0*/ +#ifdef SPLIT_REND_WITH_HEAD_ROT + IF( st_ivas->hDiracDecBin[0]->hTdDecorr ) +#else IF( st_ivas->hDiracDecBin->hTdDecorr ) +#endif { +#ifdef SPLIT_REND_WITH_HEAD_ROT + ivas_td_decorr_process_fx( st_ivas->hDiracDecBin[0]->hTdDecorr, p_tc, decorr_signal, nSamplesToDecorr ); +#else ivas_td_decorr_process_fx( st_ivas->hDiracDecBin->hTdDecorr, p_tc, decorr_signal, nSamplesToDecorr ); +#endif } FOR( ch_idx = 0; ch_idx < BINAURAL_CHANNELS; ch_idx++ ) diff --git a/lib_dec/ivas_sba_dirac_stereo_dec.c b/lib_dec/ivas_sba_dirac_stereo_dec.c deleted file mode 100644 index 15a652bc12b8ff52235e2fd1b3b991bf91e0ce54..0000000000000000000000000000000000000000 --- a/lib_dec/ivas_sba_dirac_stereo_dec.c +++ /dev/null @@ -1,43 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -#include -#include -#include "options.h" -#include "cnst.h" -#include "ivas_cnst.h" -#include "prot.h" -#include "ivas_prot.h" -#include "ivas_prot_fx.h" -#include "ivas_rom_com.h" -#include "ivas_rom_dec.h" -#include "wmc_auto.h" diff --git a/lib_dec/ivas_sba_dirac_stereo_dec_fx.c b/lib_dec/ivas_sba_dirac_stereo_dec_fx.c index 216888fbe0a87dbe439801dfacb57441400b2bad..892751057e4b82ace13ceefa493e74810b398411 100644 --- a/lib_dec/ivas_sba_dirac_stereo_dec_fx.c +++ b/lib_dec/ivas_sba_dirac_stereo_dec_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other @@ -35,7 +35,6 @@ #include "cnst.h" #include "ivas_cnst.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "ivas_prot_fx.h" #include "rom_com.h" #include "ivas_rom_com.h" @@ -277,6 +276,8 @@ static Word16 get_panning_tangent_gain( lim_r = sub( idx, 1 ); /*Q0*/ } } + assert( "should not be reached, added to avoid issues with WMC tool instrumentation" ); + return 0; /* should not be reached, added to avoid issues with WMC tool instrumentation */ } static Word16 get_panning( @@ -1241,6 +1242,13 @@ void ivas_sba_dirac_stereo_dec_fx( CPE_DEC_HANDLE hCPE; STEREO_DFT_DEC_DATA_HANDLE hStereoDft; +#ifdef MSAN_FIX + FOR( Word16 i = 0; i < CPE_CHANNELS; i++ ) + { + set32_fx( DFT[i], 0, STEREO_DFT_BUF_MAX ); + } +#endif + hSCE = st_ivas->hSCE[0]; hCPE = st_ivas->hCPE[0]; hStereoDft = hCPE->hStereoDft; @@ -1286,7 +1294,7 @@ void ivas_sba_dirac_stereo_dec_fx( sba_mono_flag = (Word16) EQ_16( st_ivas->hDecoderConfig->nchan_out, 1 ); move16(); - memOffset = NS2SA( L_mult0( output_frame, FRAMES_PER_SEC ), IVAS_DEC_DELAY_NS - DELAY_BWE_TOTAL_NS ); + memOffset = NS2SA_FX2( L_mult0( output_frame, FRAMES_PER_SEC ), IVAS_DEC_DELAY_NS - DELAY_BWE_TOTAL_NS ); move16(); ivas_sba_dirac_stereo_config( hStereoDft->hConfig ); diff --git a/lib_dec/ivas_sba_rendering_internal.c b/lib_dec/ivas_sba_rendering_internal_fx.c similarity index 99% rename from lib_dec/ivas_sba_rendering_internal.c rename to lib_dec/ivas_sba_rendering_internal_fx.c index 7cc1ebbb64f5aa976d04064211d12818c4f40b21..bbe63e965c4dd80be1cedec78bd8365bdd4b3a92 100644 --- a/lib_dec/ivas_sba_rendering_internal.c +++ b/lib_dec/ivas_sba_rendering_internal_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other @@ -32,15 +32,13 @@ #include #include "options.h" -#include "prot.h" -#include "ivas_prot.h" -#include "ivas_prot_rend.h" +#include "prot_fx.h" +#include "ivas_prot_rend_fx.h" #include "ivas_stat_dec.h" #include "ivas_cnst.h" #include #include "wmc_auto.h" #include "ivas_prot_fx.h" -#include "prot_fx.h" #ifdef DEBUGGING #include "debug.h" #endif @@ -321,7 +319,7 @@ Word16 ivas_sba_remapTCs_fx( Copy32( sba_data_fx[2], sba_data_fx[3], output_frame ); /*Q11*/ } } - IF( GT_16( st_ivas->nchan_transport, 3 ) ) + IF( GE_16( st_ivas->nchan_transport, 3 ) ) { Word16 i = 0; move16(); diff --git a/lib_dec/ivas_sce_dec.c b/lib_dec/ivas_sce_dec.c deleted file mode 100644 index 0bee68afb331e2885b43ca4c13a5210986ee82d1..0000000000000000000000000000000000000000 --- a/lib_dec/ivas_sce_dec.c +++ /dev/null @@ -1,43 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -#include -#include -#include "options.h" -#include "cnst.h" -#include "ivas_cnst.h" -#include "rom_com.h" -#include "prot.h" -#include "prot_fx.h" -#include "ivas_prot.h" -#include "ivas_rom_com.h" -#include "wmc_auto.h" diff --git a/lib_dec/ivas_sce_dec_fx.c b/lib_dec/ivas_sce_dec_fx.c index 6c22b3a987ecbca7d83fc600b3be810cbf5bf1b6..12549f49df29761496430c1f1416ec92f1023225 100644 --- a/lib_dec/ivas_sce_dec_fx.c +++ b/lib_dec/ivas_sce_dec_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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,9 +36,7 @@ #include "cnst.h" #include "ivas_cnst.h" #include "rom_com.h" -#include "prot.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "ivas_prot_fx.h" #include "ivas_rom_com.h" #include "wmc_auto.h" @@ -440,7 +438,7 @@ ivas_error create_sce_dec( IF( EQ_16( (Word16) st_ivas->ivas_format, SBA_FORMAT ) && ( EQ_16( (Word16) st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_STEREO ) || ( EQ_16( (Word16) st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_MONO ) && EQ_16( st_ivas->nchan_transport, 1 ) ) ) ) { - IF( NE_32( ( error = openCldfb_ivas_fx( &st->cldfbSynHB, CLDFB_SYNTHESIS, st->output_Fs, CLDFB_PROTOTYPE_1_25MS ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &st->cldfbSynHB, CLDFB_SYNTHESIS, st->output_Fs, CLDFB_PROTOTYPE_1_25MS, DEC ) ), IVAS_ERR_OK ) ) { return error; } diff --git a/lib_dec/ivas_sns_dec.c b/lib_dec/ivas_sns_dec.c deleted file mode 100644 index 7823d2f7c8616a2abf5a3732c190876a6f32cb4b..0000000000000000000000000000000000000000 --- a/lib_dec/ivas_sns_dec.c +++ /dev/null @@ -1,41 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -#include -#include "options.h" -#include "prot.h" -#include "ivas_prot.h" -#include "rom_com.h" -#include "ivas_rom_com.h" -#include "ivas_cnst.h" -#include -#include "wmc_auto.h" diff --git a/lib_dec/ivas_sns_dec_fx.c b/lib_dec/ivas_sns_dec_fx.c index 0451aad08b7a14b047d1f6f290fcbffca0f8f7e4..3bc6d337e9d57924af5fffa7957ceac12ecb2d4d 100644 --- a/lib_dec/ivas_sns_dec_fx.c +++ b/lib_dec/ivas_sns_dec_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten FORschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other @@ -32,14 +32,12 @@ #include #include "options.h" -#include "prot.h" -#include "ivas_prot.h" +#include "prot_fx.h" #include "rom_com.h" #include "ivas_rom_com.h" #include "ivas_cnst.h" #include #include "wmc_auto.h" -#include "prot_fx.h" #include "ivas_rom_com_fx.h" #include "ivas_prot_fx.h" @@ -374,7 +372,7 @@ void dequantize_sns_fx( IF( zero_side_flag[k] ) { set32_fx( snsQ_fx, 0, M ); - continue; + CONTINUE; } nStages = SNS_MSVQ_NSTAGES_SIDE; diff --git a/lib_dec/ivas_spar_decoder.c b/lib_dec/ivas_spar_decoder_fx.c similarity index 90% rename from lib_dec/ivas_spar_decoder.c rename to lib_dec/ivas_spar_decoder_fx.c index fdace42d822ae5e85b084285873d70df63bad336..172251104e9e07d286f144c2d185d8c3bef64da1 100644 --- a/lib_dec/ivas_spar_decoder.c +++ b/lib_dec/ivas_spar_decoder_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other @@ -35,17 +35,15 @@ #include #include "options.h" #include "ivas_stat_dec.h" -#include "prot.h" +#include "prot_fx.h" #include "string.h" -#include "ivas_prot.h" -#include "ivas_prot_rend.h" +#include "ivas_prot_rend_fx.h" #include "rom_com.h" #include "ivas_rom_com.h" #include "ivas_rom_dec.h" #include "ivas_stat_com.h" #include "stat_com.h" #include "wmc_auto.h" -#include "prot_fx.h" #include "ivas_prot_fx.h" #ifdef DEBUGGING #include "debug.h" @@ -1160,6 +1158,10 @@ void ivas_spar_get_parameters_fx( split_band = SPAR_DIRAC_SPLIT_START_BAND; move16(); +#ifdef FIX_1101_IVAS_SPAR_DEC_UPMIXER_SF_USE_MADD_ADD_WEIGHTS + Word16 add_weight_fx = sub( MAX_WORD16, weight_fx ); + Word16 add_weight_20ms_fx = sub( MAX_WORD16, weight_20ms_fx ); +#endif FOR( spar_band = 0; spar_band < num_spar_bands; spar_band++ ) { FOR( out_ch = 0; out_ch < num_ch_out; out_ch++ ) @@ -1174,9 +1176,13 @@ void ivas_spar_get_parameters_fx( { IF( GT_16( hSpar->i_subframe, 3 ) ) { - +#ifndef FIX_1101_IVAS_SPAR_DEC_UPMIXER_SF_USE_MADD_ADD_WEIGHTS par_mat_fx[out_ch][in_ch][spar_band] = L_add_sat( Mpy_32_16_1( hSpar->hMdDec->mixer_mat_prev_fx[ts0][out_ch][in_ch][spar_band], sub( MAX_WORD16, weight_fx ) ), Mpy_32_16_1( hSpar->hMdDec->mixer_mat_prev_fx[ts1][out_ch][in_ch][spar_band], weight_fx ) ); /*hSpar->hMdDec->Q_mixer_mat*/ +#else + par_mat_fx[out_ch][in_ch][spar_band] = Madd_32_16( Mpy_32_16_1( hSpar->hMdDec->mixer_mat_prev_fx[ts1][out_ch][in_ch][spar_band], weight_fx ), + hSpar->hMdDec->mixer_mat_prev_fx[ts0][out_ch][in_ch][spar_band], add_weight_fx ); +#endif move32(); } ELSE @@ -1193,7 +1199,12 @@ void ivas_spar_get_parameters_fx( /* 20ms Transport channel reconstruction with matching encoder/decoder processing */ Word16 prev_idx = SPAR_DIRAC_SPLIT_START_BAND < IVAS_MAX_NUM_BANDS ? 1 : 0; /* if SPAR_DIRAC_SPLIT_START_BAND == IVAS_MAX_NUM_BANDS, then the sub-frame mixer_mat delay line is not active */ move16(); +#ifndef FIX_1101_IVAS_SPAR_DEC_UPMIXER_SF_USE_MADD_ADD_WEIGHTS par_mat_fx[out_ch][in_ch][spar_band] = L_add_sat( Mpy_32_16_1( hSpar->hMdDec->mixer_mat_prev_fx[prev_idx][out_ch][in_ch][spar_band], sub( MAX_WORD16, weight_20ms_fx ) ), Mpy_32_16_1( hSpar->hMdDec->mixer_mat_fx[out_ch][in_ch][spar_band], weight_20ms_fx ) ); /*hSpar->hMdDec->Q_mixer_mat*/ +#else + par_mat_fx[out_ch][in_ch][spar_band] = Madd_32_16( Mpy_32_16_1( hSpar->hMdDec->mixer_mat_prev_fx[prev_idx][out_ch][in_ch][spar_band], add_weight_20ms_fx ), + hSpar->hMdDec->mixer_mat_fx[out_ch][in_ch][spar_band], weight_20ms_fx ); /*hSpar->hMdDec->Q_mixer_mat*/ +#endif move32(); } } @@ -1353,10 +1364,17 @@ static void ivas_spar_calc_smooth_facs_fx( smooth_long_avg_fx[b] = L_add( smooth_long_avg_fx[b], smooth_buf_fx[b][i] ); // Q0 move32(); } +#ifndef FIX_1101_IVAS_SPAR_DEC_UPMIXER_SF_HQ_CONSTANTS smooth_short_avg_fx[b] = Mpy_32_16_1( smooth_short_avg_fx[b], 5461 /*(1/6 in Q15)*/ ); // Q0 move32(); smooth_long_avg_fx[b] = Mpy_32_16_1( smooth_long_avg_fx[b], 1639 /*(1/20 in Q15)*/ ); // Q0 move32(); +#else + smooth_short_avg_fx[b] = Mpy_32_32( smooth_short_avg_fx[b], 357913941 /*(1/6 in Q31)*/ ); // Q0 + move32(); + smooth_long_avg_fx[b] = Mpy_32_32( smooth_long_avg_fx[b], 107374182 /*(1/20 in Q31)*/ ); // Q0 + move32(); +#endif /* calculate smoothing factor based on energy averages */ /* reduce factor for higher short-term energy */ @@ -1687,8 +1705,9 @@ void ivas_spar_dec_upmixer_sf_fx( SPAR_DEC_HANDLE hSpar; Word16 num_md_sub_frames; Word16 q1 = 30; + Word16 prod; move16(); - push_wmops( "ivas_spar_dec_upmixer_sf" ); + push_wmops( "ivas_spar_dec_upmixer_sf_fx" ); hSpar = st_ivas->hSpar; hDecoderConfig = st_ivas->hDecoderConfig; nchan_transport = hSpar->hMdDec->spar_md_cfg.nchan_transport; /*Q0*/ @@ -1706,6 +1725,8 @@ void ivas_spar_dec_upmixer_sf_fx( slot_idx_start = hSpar->slots_rendered; /*Q0*/ move16(); + prod = i_mult( slot_idx_start, slot_size ); + test(); IF( EQ_32( st_ivas->ivas_format, SBA_ISM_FORMAT ) && EQ_32( st_ivas->ism_mode, ISM_SBA_MODE_DISC ) ) { @@ -1716,7 +1737,7 @@ void ivas_spar_dec_upmixer_sf_fx( FOR( i = 0; i < nchan_internal; i++ ) { - p_tc_fx[i] = st_ivas->hTcBuffer->tc_fx[( i + nchan_ism )] + i_mult( slot_idx_start, slot_size ); /*Q11*/ + p_tc_fx[i] = st_ivas->hTcBuffer->tc_fx[( i + nchan_ism )] + prod; /*Q11*/ } test(); @@ -1725,7 +1746,7 @@ void ivas_spar_dec_upmixer_sf_fx( { FOR( i = 0; i < nchan_ism; i++ ) { - p_tc_fx[( i + nchan_internal )] = st_ivas->hTcBuffer->tc_fx[i] + i_mult( slot_idx_start, slot_size ); /*Q11*/ + p_tc_fx[( i + nchan_internal )] = st_ivas->hTcBuffer->tc_fx[i] + prod; /*Q11*/ } } } @@ -1733,7 +1754,7 @@ void ivas_spar_dec_upmixer_sf_fx( { FOR( i = 0; i < nchan_internal; i++ ) { - p_tc_fx[i] = st_ivas->hTcBuffer->tc_fx[i] + i_mult( slot_idx_start, slot_size ); /*Q11*/ + p_tc_fx[i] = st_ivas->hTcBuffer->tc_fx[i] + prod; /*Q11*/ } } @@ -1843,6 +1864,9 @@ void ivas_spar_dec_upmixer_sf_fx( ivas_spar_calc_smooth_facs_fx( cldfb_in_ts_re_fx[0], cldfb_in_ts_im_fx[0], q_cldfb, num_spar_bands, hSpar->subframe_nbslots[hSpar->subframes_rendered], hSpar->subframes_rendered == 0, &hSpar->hFbMixer->pFb->fb_bin_to_band, hSpar->hMdDec->smooth_fac_fx, hSpar->hMdDec->smooth_buf_fx ); } +#ifdef FIX_1101_IVAS_SPAR_DEC_UPMIXER_SF_USE_UNIQUE_SHL + Word16 sh_l = sub( 31, q1 ); +#endif FOR( ts = 0; ts < hSpar->subframe_nbslots[hSpar->subframes_rendered]; ts++ ) { md_idx = hSpar->render_to_md_map[( ts + slot_idx_start )]; /*Q0*/ @@ -1870,7 +1894,7 @@ void ivas_spar_dec_upmixer_sf_fx( } } } - +#ifndef FIX_1101_IVAS_SPAR_DEC_UPMIXER_SF_SPLIT_LOOPS FOR( cldfb_band = 0; cldfb_band < num_cldfb_bands; cldfb_band++ ) { Word32 out_re_fx[IVAS_SPAR_MAX_CH]; @@ -1897,14 +1921,14 @@ void ivas_spar_dec_upmixer_sf_fx( } ELSE { - cldfb_par_fx = 0; - move32(); + Word64 acc = 0; + move64(); FOR( spar_band = bin2band->p_spar_start_bands[cldfb_band]; spar_band < num_spar_bands; spar_band++ ) { /* accumulate contributions from all SPAR bands */ - Word16 tmp = extract_l( L_shr( bin2band->pp_cldfb_weights_per_spar_band_fx[cldfb_band][spar_band], 7 ) ); /*Q15*/ - cldfb_par_fx = L_add_sat( cldfb_par_fx, Mpy_32_16_1( mixer_mat_fx[out_ch][in_ch][spar_band], tmp ) ); /*q1*/ + acc = W_mac_32_32( acc, mixer_mat_fx[out_ch][in_ch][spar_band], bin2band->pp_cldfb_weights_per_spar_band_fx[cldfb_band][spar_band] ); // q1+ Q23 } + cldfb_par_fx = W_shl_sat_l( acc, -23 ); // q1 } out_re_fx[out_ch] = Madd_32_32( out_re_fx[out_ch], cldfb_in_ts_re_fx[in_ch][ts][cldfb_band], cldfb_par_fx ); /*q1-25*/ @@ -1918,13 +1942,116 @@ void ivas_spar_dec_upmixer_sf_fx( /*update CLDFB data with the parameter-modified data*/ FOR( out_ch = 0; out_ch < numch_out; out_ch++ ) { +#ifndef FIX_1101_IVAS_SPAR_DEC_UPMIXER_SF_USE_UNIQUE_SHL + cldfb_in_ts_re_fx[out_ch][ts][cldfb_band] = L_shl( out_re_fx[out_ch], sub( 31, q1 ) ); /*Q=6*/ + move32(); + cldfb_in_ts_im_fx[out_ch][ts][cldfb_band] = L_shl( out_im_fx[out_ch], sub( 31, q1 ) ); /*Q=6*/ + move32(); +#else + cldfb_in_ts_re_fx[out_ch][ts][cldfb_band] = L_shl( out_re_fx[out_ch], sh_l ); /*Q=6*/ + move32(); + cldfb_in_ts_im_fx[out_ch][ts][cldfb_band] = L_shl( out_im_fx[out_ch], sh_l ); /*Q=6*/ + move32(); +#endif + } + } +#else /* FIX_1101_IVAS_SPAR_DEC_UPMIXER_SF_SPLIT_LOOPS */ + /* Note: This version splits the cldfb band loop into 2 loops, removing some inner-loop IF_statements */ + Word16 min_cldf_band = s_min( CLDFB_PAR_WEIGHT_START_BAND, num_cldfb_bands ); + Word32 out_re_fx[IVAS_SPAR_MAX_CH]; + Word32 out_im_fx[IVAS_SPAR_MAX_CH]; + Word32 cldfb_par_fx; /*q1*/ + ivas_fb_bin_to_band_data_t *bin2band = &hSpar->hFbMixer->pFb->fb_bin_to_band; + + /* First loop from cldfb_band=0 till min_cldf_band (CLDFB_PAR_WEIGHT_START_BAND) */ + FOR( cldfb_band = 0; cldfb_band < min_cldf_band; cldfb_band++ ) + { + spar_band = bin2band->p_cldfb_map_to_spar_band[cldfb_band]; /*Q0*/ + move16(); + FOR( out_ch = 0; out_ch < numch_out; out_ch++ ) + { + out_re_fx[out_ch] = 0; + move32(); + out_im_fx[out_ch] = 0; + move32(); + FOR( in_ch = 0; in_ch < numch_in; in_ch++ ) + { + IF( b_skip_mat[out_ch][in_ch] == 0 ) + { + cldfb_par_fx = mixer_mat_fx[out_ch][in_ch][spar_band]; /*q1*/ + move32(); + out_re_fx[out_ch] = Madd_32_32( out_re_fx[out_ch], cldfb_in_ts_re_fx[in_ch][ts][cldfb_band], cldfb_par_fx ); /*q1-25*/ + move32(); + out_im_fx[out_ch] = Madd_32_32( out_im_fx[out_ch], cldfb_in_ts_im_fx[in_ch][ts][cldfb_band], cldfb_par_fx ); /*q1-25*/ + move32(); + } + } + } + /*update CLDFB data with the parameter-modified data*/ + FOR( out_ch = 0; out_ch < numch_out; out_ch++ ) + { +#ifndef FIX_1101_IVAS_SPAR_DEC_UPMIXER_SF_USE_UNIQUE_SHL cldfb_in_ts_re_fx[out_ch][ts][cldfb_band] = L_shl( out_re_fx[out_ch], sub( 31, q1 ) ); /*Q=6*/ move32(); cldfb_in_ts_im_fx[out_ch][ts][cldfb_band] = L_shl( out_im_fx[out_ch], sub( 31, q1 ) ); /*Q=6*/ move32(); +#else + cldfb_in_ts_re_fx[out_ch][ts][cldfb_band] = L_shl( out_re_fx[out_ch], sh_l ); /*Q=6*/ + move32(); + cldfb_in_ts_im_fx[out_ch][ts][cldfb_band] = L_shl( out_im_fx[out_ch], sh_l ); /*Q=6*/ + move32(); +#endif } } + + /* Second loop from min_cldf_band (CLDFB_PAR_WEIGHT_START_BAND) till num_cldfb_bands */ + FOR( ; cldfb_band < num_cldfb_bands; cldfb_band++ ) + { + FOR( out_ch = 0; out_ch < numch_out; out_ch++ ) + { + Word32 Out_re_fx = L_add( 0, 0 ); + Word32 Out_im_fx = L_add( 0, 0 ); + FOR( in_ch = 0; in_ch < numch_in; in_ch++ ) + { + IF( b_skip_mat[out_ch][in_ch] == 0 ) + { + Word64 acc = 0; + move64(); + + cldfb_par_fx = 0; + move32(); + FOR( spar_band = bin2band->p_spar_start_bands[cldfb_band]; spar_band < num_spar_bands; spar_band++ ) + { + /* accumulate contributions from all SPAR bands */ + acc = W_mac_32_32( acc, mixer_mat_fx[out_ch][in_ch][spar_band], bin2band->pp_cldfb_weights_per_spar_band_fx[cldfb_band][spar_band] ); // q1+ Q23 + } + cldfb_par_fx = W_shl_sat_l( acc, -23 ); // q1 + Out_re_fx = Madd_32_32( Out_re_fx, cldfb_in_ts_re_fx[in_ch][ts][cldfb_band], cldfb_par_fx ); /*q1-25*/ + Out_im_fx = Madd_32_32( Out_im_fx, cldfb_in_ts_im_fx[in_ch][ts][cldfb_band], cldfb_par_fx ); /*q1-25*/ + } + } + out_re_fx[out_ch] = Out_re_fx; + out_im_fx[out_ch] = Out_im_fx; + } + + /*update CLDFB data with the parameter-modified data*/ + FOR( out_ch = 0; out_ch < numch_out; out_ch++ ) + { +#ifndef FIX_1101_IVAS_SPAR_DEC_UPMIXER_SF_USE_UNIQUE_SHL + cldfb_in_ts_re_fx[out_ch][ts][cldfb_band] = L_shl( out_re_fx[out_ch], sub( 31, q1 ) ); /*Q=6*/ + move32(); + cldfb_in_ts_im_fx[out_ch][ts][cldfb_band] = L_shl( out_im_fx[out_ch], sub( 31, q1 ) ); /*Q=6*/ + move32(); +#else + cldfb_in_ts_re_fx[out_ch][ts][cldfb_band] = L_shl( out_re_fx[out_ch], sh_l ); /*Q=6*/ + move32(); + cldfb_in_ts_im_fx[out_ch][ts][cldfb_band] = L_shl( out_im_fx[out_ch], sh_l ); /*Q=6*/ + move32(); +#endif + } + } +#endif /* FIX_1101_IVAS_SPAR_DEC_UPMIXER_SF_SPLIT_LOOPS */ test(); IF( ( EQ_16( ( add( add( slot_idx_start, ts ), 1 ) ), hSpar->num_slots ) ) || ( NE_16( ( shr( md_idx, 2 ) /* md_idx / JBM_CLDFB_SLOTS_IN_SUBFRAME */ ), ( hSpar->render_to_md_map[( ( slot_idx_start + ts ) + 1 )] / JBM_CLDFB_SLOTS_IN_SUBFRAME /*It's value is 4*/ ) ) ) ) { @@ -1999,8 +2126,13 @@ void ivas_spar_dec_upmixer_sf_fx( test(); test(); test(); +#ifdef SPLIT_REND_WITH_HEAD_ROT + IF( ( EQ_32( hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_FOA ) || !( EQ_32( st_ivas->hOutSetup.output_config, IVAS_AUDIO_CONFIG_BINAURAL ) || EQ_32( st_ivas->hOutSetup.output_config, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR ) || EQ_32( st_ivas->hOutSetup.output_config, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) || EQ_32( st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) || EQ_32( st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ) ) && + !( EQ_32( st_ivas->ivas_format, SBA_ISM_FORMAT ) && EQ_32( st_ivas->ism_mode, ISM_SBA_MODE_DISC ) && EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_FASTCONV_ROOM ) ) ) +#else IF( ( EQ_32( hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_FOA ) || !( EQ_32( st_ivas->hOutSetup.output_config, IVAS_AUDIO_CONFIG_BINAURAL ) || EQ_32( st_ivas->hOutSetup.output_config, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR ) || EQ_32( st_ivas->hOutSetup.output_config, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) ) ) && !( EQ_32( st_ivas->ivas_format, SBA_ISM_FORMAT ) && EQ_32( st_ivas->ism_mode, ISM_SBA_MODE_DISC ) && EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_FASTCONV_ROOM ) ) ) +#endif { Scale_sig32( st_ivas->cldfbSynDec[idx_in]->cldfb_state_fx, st_ivas->cldfbSynDec[idx_in]->p_filter_length, -6 ); /*st_ivas->cldfbSynDec[idx_in]->Q_cldfb_state-6*/ st_ivas->cldfbSynDec[idx_in]->Q_cldfb_state = sub( st_ivas->cldfbSynDec[idx_in]->Q_cldfb_state, 6 ); diff --git a/lib_dec/ivas_spar_md_dec.c b/lib_dec/ivas_spar_md_dec_fx.c similarity index 99% rename from lib_dec/ivas_spar_md_dec.c rename to lib_dec/ivas_spar_md_dec_fx.c index c33c5da630e365fdd3971deec0be2392dd53f249..7f487a75c272279cbc0ab168f8116743069db676 100644 --- a/lib_dec/ivas_spar_md_dec.c +++ b/lib_dec/ivas_spar_md_dec_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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,13 +33,11 @@ #include #include "options.h" #include "math.h" -#include "prot.h" -#include "ivas_prot.h" +#include "prot_fx.h" #include "ivas_rom_com.h" #include #include "wmc_auto.h" #include "ivas_stat_dec.h" -#include "prot_fx.h" #include "ivas_prot_fx.h" #include "ivas_rom_com_fx.h" @@ -50,11 +48,11 @@ #define IVAS_DEFAULT_DTX_CNG_RAMP ( 8 ) /* PLC constants */ -static const int16_t ivas_spar_dec_plc_num_frames_keep = 9; -// static const int16_t ivas_spar_dec_plc_num_frames_fade_out = 9; -static const int16_t ivas_spar_dec_plc_per_frame_ramp_down_gain_dB = 3; -static const int16_t ivas_spar_dec_plc_max_num_frames_ramp_down = 33; -static const int16_t ivas_spar_dec_plc_spatial_target[IVAS_SPAR_MAX_CH] = { 1, 0, 0, 0, 0, 0, 0, 0 }; +static const Word16 ivas_spar_dec_plc_num_frames_keep = 9; +// static const Word16 ivas_spar_dec_plc_num_frames_fade_out = 9; +static const Word16 ivas_spar_dec_plc_per_frame_ramp_down_gain_dB = 3; +static const Word16 ivas_spar_dec_plc_max_num_frames_ramp_down = 33; +static const Word16 ivas_spar_dec_plc_spatial_target[IVAS_SPAR_MAX_CH] = { 1, 0, 0, 0, 0, 0, 0, 0 }; /*------------------------------------------------------------------------------------------* @@ -937,9 +935,10 @@ Word16 ivas_spar_chk_zero_coefs_fx( ndm = hMdDec->spar_md_cfg.num_dmx_chans_per_band[0]; /*Q0*/ move16(); - FOR( b = 0; b < min( hMdDec->spar_md.num_bands, SPAR_DIRAC_SPLIT_START_BAND ); b++ ) + Word16 min_bands = s_min( hMdDec->spar_md.num_bands, SPAR_DIRAC_SPLIT_START_BAND ); + FOR( b = 0; b < min_bands; b++ ) { - FOR( j = 0; j < sub( add( ndm, ndec ), 1 ); j++ ) + FOR( j = 0; j < ( ( ndm + ndec ) - 1 ); j++ ) { if ( hMdDec->spar_md.band_coeffs[b].pred_re_fx[j] != 0 ) { @@ -949,7 +948,7 @@ Word16 ivas_spar_chk_zero_coefs_fx( } FOR( j = 0; j < ndec; j++ ) { - FOR( k = 0; k < sub( ndm, 1 ); k++ ) + FOR( k = 0; k < ( ndm - 1 ); k++ ) { if ( hMdDec->spar_md.band_coeffs[b].C_re_fx[j][k] != 0 ) { diff --git a/lib_dec/ivas_stat_dec.h b/lib_dec/ivas_stat_dec.h index cf01ce54fcb68678e8891aec18b491652f22bd0d..f893c4b31e4edf1b9a8c9c0b84f06541f5f1f555 100644 --- a/lib_dec/ivas_stat_dec.h +++ b/lib_dec/ivas_stat_dec.h @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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,6 +40,7 @@ #include "stat_dec.h" #include "ivas_stat_com.h" #include "ivas_stat_rend.h" +#include "isar_stat.h" /*----------------------------------------------------------------------------------* @@ -49,14 +50,14 @@ /* State of the range decoder */ typedef struct { - uint32_t rc_low; - uint32_t rc_range; + UWord32 rc_low; + UWord32 rc_range; - uint16_t *bit_buffer; - int16_t bit_count; - int16_t max_allowable_bit_count; + UWord16 *bit_buffer; + Word16 bit_count; + Word16 max_allowable_bit_count; - int16_t bit_error_detected; + Word16 bit_error_detected; } RangeUniDecState; @@ -78,11 +79,11 @@ typedef struct stereo_dft_dec_data_struct STEREO_DFT_CONFIG_DATA_HANDLE hConfig; /*Sizes*/ - int16_t N; /* Size of DFT hop size */ - int16_t NFFT; /* Size of DFT */ + Word16 N; /* Size of DFT hop size */ + Word16 NFFT; /* Size of DFT */ /*FFT*/ - int16_t dft_trigo_step; + Word16 dft_trigo_step; const Word16 *dft_trigo_fx; /* Q15 */ const Word16 *dft_trigo_12k8_fx; /* Q15 */ @@ -90,13 +91,13 @@ typedef struct stereo_dft_dec_data_struct const Word16 *dft_trigo_8k_fx; /* Q15 */ - int16_t dft32ms_ovl; /* Overlap size */ + Word16 dft32ms_ovl; /* Overlap size */ const Word16 *win32ms_fx; /* DFT window */ /* Q15 */ const Word16 *win32ms_12k8_fx; /* DFT window */ /* Q15 */ const Word16 *win32ms_16k_fx; /* DFT window */ /* Q15 */ const Word16 *win32ms_8k_fx; /* DFT window */ /* Q15 */ - int16_t dft32ms_ovl2; /* Overlap2 size */ + Word16 dft32ms_ovl2; /* Overlap2 size */ const Word16 *win232ms_fx; /* DFT window */ /* Q15 */ const Word16 *win232ms_12k8_fx; /* DFT window */ /* Q15 */ const Word16 *win232ms_16k_fx; /* DFT window */ /* Q15 */ @@ -105,31 +106,31 @@ typedef struct stereo_dft_dec_data_struct /*Bands*/ - int16_t band_res[STEREO_DFT_DEC_DFT_NB]; - int16_t band_limits[STEREO_DFT_BAND_MAX + 1]; - int16_t nbands; + Word16 band_res[STEREO_DFT_DEC_DFT_NB]; + Word16 band_limits[STEREO_DFT_BAND_MAX + 1]; + Word16 nbands; /*Configuration*/ - int16_t prm_res[STEREO_DFT_DEC_DFT_NB]; + Word16 prm_res[STEREO_DFT_DEC_DFT_NB]; /*Stereo parameters*/ Word32 side_gain_fx[STEREO_DFT_DEC_DFT_NB * STEREO_DFT_BAND_MAX]; /* Q31 */ - int16_t side_gain_flag_1; - int16_t side_gain_flag_2; - int16_t side_gain_index_previous[STEREO_DFT_BAND_MAX]; - int16_t side_gain_index[STEREO_DFT_BAND_MAX]; + Word16 side_gain_flag_1; + Word16 side_gain_flag_2; + Word16 side_gain_index_previous[STEREO_DFT_BAND_MAX]; + Word16 side_gain_index[STEREO_DFT_BAND_MAX]; Word32 gipd_fx[STEREO_DFT_DEC_DFT_NB]; /* Q27 */ - int16_t no_ipd_flag; /* flag to indicate when no IPD gets used */ + Word16 no_ipd_flag; /* flag to indicate when no IPD gets used */ - int16_t itd_xfade_counter; - int32_t last_active_element_brate; - int16_t ipd_xfade_counter; + Word16 itd_xfade_counter; + Word32 last_active_element_brate; + Word16 ipd_xfade_counter; /*residual prediction*/ - int16_t res_pred_mode[STEREO_DFT_DEC_DFT_NB]; /* residual prediction mode: 0(off), 1(stereo filling only), 2(enhanced stereo filling) */ - Word32 itd_fx[STEREO_DFT_DEC_DFT_NB]; /* Q15 */ + Word16 res_pred_mode[STEREO_DFT_DEC_DFT_NB]; /* residual prediction mode: 0(off), 1(stereo filling only), 2(enhanced stereo filling) */ + Word32 itd_fx[STEREO_DFT_DEC_DFT_NB]; /* Q15 */ Word32 itd_xfade_step_fx; /* Q15 */ Word32 itd_xfade_target_fx; /* Q15 */ @@ -139,19 +140,19 @@ typedef struct stereo_dft_dec_data_struct Word32 ipd_xfade_step_fx; /* Q27 */ Word32 ipd_xfade_prev_fx; /* Q27 */ Word32 res_pred_gain_fx[STEREO_DFT_DEC_DFT_NB * STEREO_DFT_BAND_MAX]; /* prediction gain for the residual HFs */ /* Q31 */ - int16_t res_pred_band_min; /* Band min for prediction of residual */ - int16_t past_DMX_pos; - int16_t res_pred_flag_0; - int16_t res_pred_flag_1; - int16_t res_pred_index_previous[STEREO_DFT_BAND_MAX]; + Word16 res_pred_band_min; /* Band min for prediction of residual */ + Word16 past_DMX_pos; + Word16 res_pred_flag_0; + Word16 res_pred_flag_1; + Word16 res_pred_index_previous[STEREO_DFT_BAND_MAX]; - int16_t reverb_flag; - int16_t nbands_respred; + Word16 reverb_flag; + Word16 nbands_respred; /*residual coding*/ - int16_t res_cod_mode[STEREO_DFT_DEC_DFT_NB]; /* mode from 0 (off) to 3 */ - int16_t res_cod_band_max; /* Band max for coding of residual */ - int16_t res_cod_line_max; + Word16 res_cod_mode[STEREO_DFT_DEC_DFT_NB]; /* mode from 0 (off) to 3 */ + Word16 res_cod_band_max; /* Band max for coding of residual */ + Word16 res_cod_line_max; Word32 DFT_past_DMX_fx[STEREO_DFT_PAST_MAX][STEREO_DFT32MS_N_32k]; /* Past DMX for residual prediction */ /* Q(q_DFT_past_DMX_fx) */ Word32 past_res_pred_gain_fx[STEREO_DFT_PAST_MAX][STEREO_DFT_BAND_MAX]; /* Q31 */ Word32 res_gains_ind_fx[2][2 * STEREO_DFT_BAND_MAX]; /* Q26 */ @@ -171,9 +172,9 @@ typedef struct stereo_dft_dec_data_struct BPF_DEC_HANDLE hBpf; TCX_LTP_DEC_HANDLE hTcxLtpDec; - int16_t trans; - int16_t attackPresent; - int16_t wasTransient; + Word16 trans; + Word16 attackPresent; + Word16 wasTransient; basic_allpass_t ap1, ap2, ap3; @@ -188,9 +189,9 @@ typedef struct stereo_dft_dec_data_struct Word32 ap_fade_mem_fx[STEREO_DFT_ALLPASS_FADELEN_16k]; /* Q(q_ap_fade_mem_fx) */ Word16 q_ap_fade_mem_fx; - int16_t ap_wasTransient; - int16_t core_hist[STEREO_DFT_CORE_HIST_MAX]; - int16_t hb_stefi_delay; + Word16 ap_wasTransient; + Word16 core_hist[STEREO_DFT_CORE_HIST_MAX]; + Word16 hb_stefi_delay; Word32 smooth_dmx_nrg_fx[STEREO_DFT_BAND_MAX]; /* Q(q_smoothed_nrg) */ Word32 smooth_res_nrg_fx[STEREO_DFT_BAND_MAX]; /* Q(q_smoothed_nrg) */ Word32 td_gain_fx[STEREO_DFT_CORE_HIST_MAX]; /* Q(q_td_gain) */ @@ -206,16 +207,16 @@ typedef struct stereo_dft_dec_data_struct /* stereo DTX */ Word16 g_state_fx[STEREO_DFT_BAND_MAX]; /* Q15 */ - int16_t frame_sid_nodata; - int16_t frame_nodata; - int16_t frame_sid; + Word16 frame_sid_nodata; + Word16 frame_nodata; + Word16 frame_sid; Word16 scale_fx; /* Q15 */ /* PLC on residual signal */ - int16_t time_offs; - int16_t sg_mem_corrupt; - int16_t recovery_flg; + Word16 time_offs; + Word16 sg_mem_corrupt; + Word16 recovery_flg; /* PLC on residual signal */ Word32 sg_mean_fx; /* Q31 */ @@ -228,7 +229,7 @@ typedef struct stereo_dft_dec_data_struct Word16 q_hb_nrg_subr; Word16 q_res_mem; - int16_t first_frame; + Word16 first_frame; Word32 mixer_mat_smooth_fx[2][4][2 * IVAS_MAX_NUM_BANDS]; /* Q31 */ Word32 g_L_prev_fx; /* Q31 */ Word32 g_R_prev_fx; /* Q31 */ @@ -257,26 +258,26 @@ typedef struct stereo_dec_cng { Word16 cm_fx[STEREO_DFT_BAND_MAX]; /* cm */ /* Q15 */ Word16 coh_fx[STEREO_DFT_BAND_MAX + 1]; /* coherence */ /* Q15 */ - int16_t first_SID; /* first SID indicator */ - int16_t first_SID_after_TD; /* first SID after TD-stereo indicator */ - int16_t prev_sid_nodata; /* previous frame SID/FRAME_NO_DATA indicator */ - int16_t last_tdm_idx; /* last tdm index */ + Word16 first_SID; /* first SID indicator */ + Word16 first_SID_after_TD; /* first SID after TD-stereo indicator */ + Word16 prev_sid_nodata; /* previous frame SID/FRAME_NO_DATA indicator */ + Word16 last_tdm_idx; /* last tdm index */ Word32 c_LR_LT_fx; /* left right cross correlation */ /* Q31 */ - int16_t active_frame_counter; /* counter for active frames */ - int16_t xfade_frame_counter; /* xfade counter */ - int16_t xfade_length; /* number of frames to perform xfade */ - int16_t nr_dft_frames; /* dft frame counter */ - int16_t nr_corr_frames; /* correlation frame counter */ - int16_t nr_sid_frames; /* SID frame counter */ - int16_t last_act_element_mode; /* Element mode of last active frame */ + Word16 active_frame_counter; /* counter for active frames */ + Word16 xfade_frame_counter; /* xfade counter */ + Word16 xfade_length; /* number of frames to perform xfade */ + Word16 nr_dft_frames; /* dft frame counter */ + Word16 nr_corr_frames; /* correlation frame counter */ + Word16 nr_sid_frames; /* SID frame counter */ + Word16 last_act_element_mode; /* Element mode of last active frame */ Word16 olapBufferSynth22_fx[FFTLEN]; /* overlap buffer for secondary channel CNA */ Word32 olapBufferSynth22_32fx[FFTLEN]; /* overlap buffer for secondary channel CNA */ - int16_t flag_cna_fade; /* flag enabling CNA fade out */ + Word16 flag_cna_fade; /* flag enabling CNA fade out */ Word16 maskingNoiseS_fx[L_FRAME16k]; /* masking noise (CNA) for secondary channel */ - int16_t enableSecCNA; /* flag enabling secondary channel CNA */ + Word16 enableSecCNA; /* flag enabling secondary channel CNA */ Word16 c_PS_LT_fx; /* long term cross-correlation between primary and secondary channel */ // Assumed Q15 for initialization. Can be modified later if reqd. - const int16_t *frameSize; /* Frame size in samples */ - const int16_t *fftlen; /* FFT length used for the decomposition */ + const Word16 *frameSize; /* Frame size in samples */ + const Word16 *fftlen; /* FFT length used for the decomposition */ } STEREO_CNG_DEC, *STEREO_CNG_DEC_HANDLE; @@ -287,18 +288,18 @@ typedef struct stereo_dec_cng typedef struct stereo_td_dec_data_structure { - int16_t tdm_last_ratio_idx; /* last TDM ratio index */ - int16_t tdm_last_SM_flag; /* last channel combination scheme flag */ - int16_t tdm_prev_last_SM_flag; /* channel combination scheme flag before last frame */ - int16_t tdm_SM_flag; /* current channel combination scheme flag */ - int16_t tdm_use_IAWB_Ave_lpc; /* Flag to indicate the usage of mean inactive LP coefficients */ - - int16_t tdm_lp_reuse_flag; /* Flag that indicate if it is possible to reuse the LP coefficient from the primary channel or not */ - int16_t tdm_low_rate_mode; /* secondary channel low rate mode flag */ + Word16 tdm_last_ratio_idx; /* last TDM ratio index */ + Word16 tdm_last_SM_flag; /* last channel combination scheme flag */ + Word16 tdm_prev_last_SM_flag; /* channel combination scheme flag before last frame */ + Word16 tdm_SM_flag; /* current channel combination scheme flag */ + Word16 tdm_use_IAWB_Ave_lpc; /* Flag to indicate the usage of mean inactive LP coefficients */ + + Word16 tdm_lp_reuse_flag; /* Flag that indicate if it is possible to reuse the LP coefficient from the primary channel or not */ + Word16 tdm_low_rate_mode; /* secondary channel low rate mode flag */ Word16 tdm_Pri_pitch_buf_fx[NB_SUBFR]; - int16_t tdm_Pitch_reuse_flag; - int16_t tdm_LRTD_flag; - int16_t flag_skip_DMX; /* flag that indicates whether the TD downmixing is skipped */ + Word16 tdm_Pitch_reuse_flag; + Word16 tdm_LRTD_flag; + Word16 flag_skip_DMX; /* flag that indicates whether the TD downmixing is skipped */ Word32 TCX_old_syn_Overl_fx[L_FRAME16k / 2]; /* past ovrl buffer for possible switching from TD stereo ACELP to MDCT stereo TCX frame */ /* Q11 */ Word16 prevSP_ratio_fx; /* previous SP ratio */ @@ -320,24 +321,24 @@ typedef struct stereo_mdct_dec_data_structure STEREO_MDCT_BAND_PARAMETERS stbParamsTCX20afterACELP; /* stereo frequency band parameters for transition frame */ /* only intraframe */ - int16_t mdct_stereo_mode[2]; /* mdct stereo mode: LR, MS, band-wise MS */ - int16_t global_ild[2]; /* Quantized ILD for the whole spectrum */ - int16_t split_ratio; /* Ratio of bitrate (1 to 7), split_ratio = 8 * 1st chn bitrate / (1st + 2nd chn bitrate) */ + Word16 mdct_stereo_mode[2]; /* mdct stereo mode: LR, MS, band-wise MS */ + Word16 global_ild[2]; /* Quantized ILD for the whole spectrum */ + Word16 split_ratio; /* Ratio of bitrate (1 to 7), split_ratio = 8 * 1st chn bitrate / (1st + 2nd chn bitrate) */ - int16_t IGFStereoMode[2]; /* MDCT stereo mode for IGF */ + Word16 IGFStereoMode[2]; /* MDCT stereo mode for IGF */ - int16_t use_itd; - int16_t itd_mode; /*0/1*/ - Word32 itd_fx; /* Q15 */ + Word16 use_itd; + Word16 itd_mode; /*0/1*/ + Word32 itd_fx; /* Q15 */ - int16_t reverse_dmx; + Word16 reverse_dmx; Word32 smooth_ratio_fx; /* Q26 */ - int16_t prev_ms_mask[NB_DIV][MAX_SFB]; + Word16 prev_ms_mask[NB_DIV][MAX_SFB]; Word16 lastCoh_fx; /* Q14 */ - int16_t noise_seeds_channels[CPE_CHANNELS]; - int16_t noise_seed_common; - int16_t isSBAStereoMode; + Word16 noise_seeds_channels[CPE_CHANNELS]; + Word16 noise_seed_common; + Word16 isSBAStereoMode; } STEREO_MDCT_DEC_DATA, *STEREO_MDCT_DEC_DATA_HANDLE; @@ -348,18 +349,18 @@ typedef struct stereo_mdct_dec_data_structure typedef struct stereo_tca_dec_data_structure { - int16_t refChanIndx; /* reference channel index in current frame */ - int16_t prevRefChanIndx; /* reference channel index in previous frame */ - int16_t indx_ica_NCShift; /* ICA target channel inter-channel corrstats */ - int16_t indx_ica_gD; /* ICA target gain */ + Word16 refChanIndx; /* reference channel index in current frame */ + Word16 prevRefChanIndx; /* reference channel index in previous frame */ + Word16 indx_ica_NCShift; /* ICA target channel inter-channel corrstats */ + Word16 indx_ica_gD; /* ICA target gain */ Word32 targetGain_fx; /* gain norm applied on target (or right) channel in current frame */ // Q29 Word32 prevTargetGain_fx; /* gain norm applied on target (or right) channel in previous frame */ // Q29 - int16_t corrLagStats; /* corr lag stats in current frame */ - int16_t prevCorrLagStats; /* corr lag stats in previous frame */ + Word16 corrLagStats; /* corr lag stats in current frame */ + Word16 prevCorrLagStats; /* corr lag stats in previous frame */ - int16_t interp_dec_prevNCShift; /* NC Shift in previous frame */ - int16_t interp_dec_switch_to_zero_diff; /* switch flag for interpolation */ + Word16 interp_dec_prevNCShift; /* NC Shift in previous frame */ + Word16 interp_dec_switch_to_zero_diff; /* switch flag for interpolation */ Word32 memChanL_fx[L_DEC_MEM_LEN_ICA]; /* left channel input to correct at the cross-over for Fixed */ @@ -428,10 +429,10 @@ typedef struct stereo_icbwe_dec_data_structure typedef struct { - int16_t dtx_flag; - int16_t sce_id_dtx; + Word16 dtx_flag; + Word16 sce_id_dtx; - int16_t ism_dtx_hangover_cnt; /* hangover counter for ISM DTX decoder */ + Word16 ism_dtx_hangover_cnt; /* hangover counter for ISM DTX decoder */ } ISM_DTX_DATA_DEC; @@ -478,9 +479,9 @@ typedef struct ivas_dirac_dec_data_structure { DIRAC_CONFIG_DATA_HANDLE hConfig; - int16_t band_grouping[IVAS_MAX_NUM_BANDS + 1]; - int16_t dithering_seed; - int16_t spar_to_dirac_write_idx; + Word16 band_grouping[IVAS_MAX_NUM_BANDS + 1]; + Word16 dithering_seed; + Word16 spar_to_dirac_write_idx; IVAS_FB_MIXER_HANDLE hFbMdft; @@ -521,10 +522,10 @@ typedef struct dirac_output_synthesis_cov_state_structure typedef struct ivas_param_mc_diff_proto_info_structure { - int16_t num_protos_diff; - int16_t *proto_index_diff; - int16_t *num_source_chan_diff; - int16_t **source_chan_idx; + Word16 num_protos_diff; + Word16 *proto_index_diff; + Word16 *num_source_chan_diff; + Word16 **source_chan_idx; Word32 **proto_fac_fx; } PARAM_MC_DIFF_PROTO_INFO; @@ -532,42 +533,42 @@ typedef struct ivas_param_mc_diff_proto_info_structure typedef struct ivas_param_mc_dec_data_structure { - int16_t slot_size; + Word16 slot_size; Word32 *Cldfb_RealBuffer_tc_fx; // Q12 Word16 Cldfb_RealBuffer_tc_e; Word32 *Cldfb_ImagBuffer_tc_fx; // Q12 Word16 Cldfb_ImagBuffer_tc_e; Word16 sz; - int16_t subframe_nbslots[MAX_JBM_SUBFRAMES_5MS]; - int16_t nb_subframes; - int16_t subframes_rendered; - int16_t slots_rendered; - int16_t num_slots; - int16_t num_freq_bands; - int16_t num_param_bands_synth; + Word16 subframe_nbslots[MAX_JBM_SUBFRAMES_5MS]; + Word16 nb_subframes; + Word16 subframes_rendered; + Word16 slots_rendered; + Word16 num_slots; + Word16 num_freq_bands; + Word16 num_param_bands_synth; - int16_t band_grouping[PARAM_MC_MAX_PARAMETER_BANDS + 1]; + Word16 band_grouping[PARAM_MC_MAX_PARAMETER_BANDS + 1]; /*Decoder parameters */ /*Prototypes*/ - int16_t num_outputs_diff; + Word16 num_outputs_diff; PARAM_MC_DIFF_PROTO_INFO *diff_proto_info; PARAM_MC_SYNTHESIS_CONF synthesis_conf; /*Options*/ /* Decorrelator options */ - int16_t max_band_decorr; + Word16 max_band_decorr; /*Decoder states=memories*/ Word32 *proto_frame_f_fx; /* Q11 */ Word32 *proto_frame_dec_f_fx; /* Q11 */ DIRAC_OUTPUT_SYNTHESIS_COV_STATE h_output_synthesis_cov_state; DIRAC_OUTPUT_SYNTHESIS_PARAMS h_output_synthesis_params; - int16_t max_band_energy_compensation; + Word16 max_band_energy_compensation; HANDLE_IVAS_PARAM_MC_METADATA hMetadataPMC; Word16 *icc_q_fx; /* ICC parameters*/ /* Q15 */ Word16 *icld_q_fx; /* Q8 */ - int16_t max_param_band_abs_cov; + Word16 max_param_band_abs_cov; Word16 q_proto_frame_f; Word32 *ls_conv_dmx_matrix_fx; /* Q30 */ Word32 *proto_matrix_int_fx; @@ -588,12 +589,12 @@ typedef struct ivas_param_mc_dec_data_structure typedef struct ivas_mc_paramupmix_dec_data_structure { - int16_t num_freq_bands; + Word16 num_freq_bands; ivas_td_decorr_state_t *hTdDecorr[MC_PARAMUPMIX_COMBINATIONS]; - int32_t alpha_quant[MC_PARAMUPMIX_COMBINATIONS][IVAS_MAX_NUM_BANDS]; - int32_t beta_quant[MC_PARAMUPMIX_COMBINATIONS][IVAS_MAX_NUM_BANDS]; - int16_t first_frame; - int16_t free_param_interpolator; + Word32 alpha_quant[MC_PARAMUPMIX_COMBINATIONS][IVAS_MAX_NUM_BANDS]; + Word32 beta_quant[MC_PARAMUPMIX_COMBINATIONS][IVAS_MAX_NUM_BANDS]; + Word16 first_frame; + Word16 free_param_interpolator; Word32 alphas_fx[MC_PARAMUPMIX_COMBINATIONS][IVAS_MAX_NUM_BANDS]; // Q28 @@ -627,30 +628,30 @@ typedef struct ivas_spar_md_dec_state_t ivas_spar_dec_matrices_t spar_coeffs; ivas_spar_dec_matrices_t spar_coeffs_prev; ivas_spar_dec_matrices_t spar_coeffs_tar; - int16_t dtx_md_smoothing_cntr; - int16_t valid_bands[IVAS_MAX_NUM_BANDS]; - int16_t base_band_age[IVAS_MAX_NUM_BANDS]; - int16_t spar_plc_num_lost_frames; - int16_t num_decorr; - int16_t td_decorr_flag; - int16_t spar_plc_enable_fadeout_flag; + Word16 dtx_md_smoothing_cntr; + Word16 valid_bands[IVAS_MAX_NUM_BANDS]; + Word16 base_band_age[IVAS_MAX_NUM_BANDS]; + Word16 spar_plc_num_lost_frames; + Word16 num_decorr; + Word16 td_decorr_flag; + Word16 spar_plc_enable_fadeout_flag; Word32 ***mixer_mat_fx; /* Q(Q_mixer_mat) */ Word32 mixer_mat_prev_fx[MAX_PARAM_SPATIAL_SUBFRAMES + 1][IVAS_MAX_FB_MIXER_OUT_CH][IVAS_MAX_SPAR_FB_MIXER_IN_CH][IVAS_MAX_NUM_BANDS]; /* Q(Q_mixer_mat) */ Word16 Q_mixer_mat; ivas_spar_md_com_cfg spar_md_cfg; ivas_arith_coeffs_t arith_coeffs; ivas_huff_coeffs_t huff_coeffs; - int16_t table_idx; - int16_t dtx_vad; - int16_t spar_hoa_md_flag; - int16_t spar_hoa_dirac2spar_md_flag; - int16_t HOA_md_ind[IVAS_SPAR_MAX_CH]; + Word16 table_idx; + Word16 dtx_vad; + Word16 spar_hoa_md_flag; + Word16 spar_hoa_dirac2spar_md_flag; + Word16 HOA_md_ind[IVAS_SPAR_MAX_CH]; Word32 smooth_buf_fx[IVAS_MAX_NUM_BANDS][2 * SBA_DIRAC_NRG_SMOOTH_LONG + 1]; /* Q0 */ Word16 smooth_fac_fx[IVAS_MAX_NUM_BANDS]; /* Q15 */ Word32 mixer_mat_prev2_fx[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH][IVAS_MAX_NUM_BANDS]; /* Q(Q_mixer_mat) */ - int16_t first_valid_frame; + Word16 first_valid_frame; ivas_band_coeffs_t *band_coeffs_prev; - int16_t base_band_coeffs_age[IVAS_MAX_NUM_BANDS]; + Word16 base_band_coeffs_age[IVAS_MAX_NUM_BANDS]; } ivas_spar_md_dec_state_t; @@ -676,11 +677,11 @@ typedef struct { Word16 prev_ql_fx[IVAS_PCA_INTERP]; Word16 prev_qr_fx[IVAS_PCA_INTERP]; - int16_t prev_pca_bypass; + Word16 prev_pca_bypass; Word16 mem_eigVec_interp_fx[IVAS_PCA_LEN_INTERP_EIG_DEC]; /* parser output: */ - int16_t pca_bypass; - int32_t index[2]; + Word16 pca_bypass; + Word32 index[2]; } PCA_DEC_STATE; @@ -690,20 +691,20 @@ typedef struct ivas_spar_dec_lib_t ivas_td_decorr_state_t *hTdDecorr; ivas_spar_md_dec_state_t *hMdDec; IVAS_FB_MIXER_HANDLE hFbMixer; - int16_t AGC_flag; + Word16 AGC_flag; ivas_agc_dec_state_t *hAgcDec; PCA_DEC_STATE *hPCA; - int16_t dirac_to_spar_md_bands[DIRAC_MAX_NBANDS]; - int16_t enc_param_start_band; - int32_t core_nominal_brate; /* Nominal bitrate for core coding */ - int16_t i_subframe; - - int16_t subframe_nbslots[MAX_JBM_SUBFRAMES_5MS]; - int16_t render_to_md_map[MAX_JBM_CLDFB_TIMESLOTS]; - int16_t nb_subframes; - int16_t subframes_rendered; - int16_t slots_rendered; - int16_t num_slots; + Word16 dirac_to_spar_md_bands[DIRAC_MAX_NBANDS]; + Word16 enc_param_start_band; + Word32 core_nominal_brate; /* Nominal bitrate for core coding */ + Word16 i_subframe; + + Word16 subframe_nbslots[MAX_JBM_SUBFRAMES_5MS]; + Word16 render_to_md_map[MAX_JBM_CLDFB_TIMESLOTS]; + Word16 nb_subframes; + Word16 subframes_rendered; + Word16 slots_rendered; + Word16 num_slots; } SPAR_DEC_DATA, *SPAR_DEC_HANDLE; @@ -712,8 +713,8 @@ typedef struct ivas_spar_dec_lib_t typedef struct ivas_osba_data { Word32 **delayBuffer_fx; - int16_t delayBuffer_size; - int16_t delayBuffer_nchan; + Word16 delayBuffer_size; + Word16 delayBuffer_nchan; } SBA_ISM_DATA, *SBA_ISM_DATA_HANDLE; @@ -724,9 +725,9 @@ typedef struct ivas_osba_data typedef struct sce_dec_data_structure { - int16_t sce_id; /* SCE # identifier */ - int32_t element_brate; /* SCE total bitrate in bps */ - int32_t last_element_brate; /* SCE last total bitrate in bps */ + Word16 sce_id; /* SCE # identifier */ + Word32 element_brate; /* SCE total bitrate in bps */ + Word32 last_element_brate; /* SCE last total bitrate in bps */ /* core coder handle */ DEC_CORE_HANDLE hCoreCoder[1]; @@ -747,15 +748,15 @@ typedef struct sce_dec_data_structure typedef struct cpe_dec_data_structure { - int16_t cpe_id; /* CPE # identifier */ - int32_t element_brate; /* CPE element total bitrate in bps */ - int32_t last_element_brate; /* last CPE element total bitrate in bps */ + Word16 cpe_id; /* CPE # identifier */ + Word32 element_brate; /* CPE element total bitrate in bps */ + Word32 last_element_brate; /* last CPE element total bitrate in bps */ - int16_t element_mode; /* element mode, in CPE it can be IVAS_CPE_DFT, IVAS_CPE_TD or IVAS_CPE_MDCT */ - int16_t last_element_mode; /* last element mode */ + Word16 element_mode; /* element mode, in CPE it can be IVAS_CPE_DFT, IVAS_CPE_TD or IVAS_CPE_MDCT */ + Word16 last_element_mode; /* last element mode */ - int16_t stereo_switching_counter; - int16_t NbFrameMod; + Word16 stereo_switching_counter; + Word16 NbFrameMod; /* core coder handle */ DEC_CORE_HANDLE hCoreCoder[CPE_CHANNELS]; @@ -768,7 +769,7 @@ typedef struct cpe_dec_data_structure STEREO_ICBWE_DEC_HANDLE hStereoICBWE; /* Stereo inter-channel BWE data handle */ STEREO_CNG_DEC_HANDLE hStereoCng; /* Stereo CNG data structure */ - int16_t nchan_out; /* number of output channels (1: mono dmx, 2: default stereo) */ + Word16 nchan_out; /* number of output channels (1: mono dmx, 2: default stereo) */ /* DFT stereo I/O channel buffer memories that need to be updated for TD->DFT stereo switching */ @@ -792,7 +793,7 @@ typedef struct cpe_dec_data_structure /* buffers used for fading between MDCT and DFT Stereo */ - int32_t brate_surplus; /* bitrate surplus for bitrate adaptation in combined format coding */ + Word32 brate_surplus; /* bitrate surplus for bitrate adaptation in combined format coding */ } CPE_DEC_DATA, *CPE_DEC_HANDLE; @@ -803,8 +804,8 @@ typedef struct cpe_dec_data_structure typedef struct mct_dec_block_data_struct { - int16_t ch1, ch2; - int16_t mask[2][MAX_SFB]; + Word16 ch1, ch2; + Word16 mask[2][MAX_SFB]; STEREO_MDCT_DEC_DATA_HANDLE hStereoMdct; /* MDCT stereo data handle */ } MCT_DEC_BLOCK_DATA, *MCT_DEC_BLOCK_DATA_HANDLE; @@ -812,14 +813,14 @@ typedef struct mct_dec_block_data_struct typedef struct mct_dec_data_structure { - int16_t nchan_out_woLFE; /* number of active channels within multi-channel configuration */ - int16_t currBlockDataCnt; - int16_t bitsChannelPairIndex; /* bits needed to code channel pair index, depends on number of active channels */ + Word16 nchan_out_woLFE; /* number of active channels within multi-channel configuration */ + Word16 currBlockDataCnt; + Word16 bitsChannelPairIndex; /* bits needed to code channel pair index, depends on number of active channels */ MCT_DEC_BLOCK_DATA_HANDLE hBlockData[MCT_MAX_BLOCKS]; - int16_t chBitRatios[MCT_MAX_CHANNELS]; - int16_t lowE_ch[MCT_MAX_CHANNELS]; /* note: pointer to local parameter */ - uint16_t mc_global_ild[MCT_MAX_CHANNELS]; /* note: pointer to local parameter */ + Word16 chBitRatios[MCT_MAX_CHANNELS]; + Word16 lowE_ch[MCT_MAX_CHANNELS]; /* note: pointer to local parameter */ + UWord16 mc_global_ild[MCT_MAX_CHANNELS]; /* note: pointer to local parameter */ } MCT_DEC_DATA, *MCT_DEC_HANDLE; @@ -859,6 +860,7 @@ typedef struct renderer_struct } ISM_RENDERER_DATA, *ISM_RENDERER_HANDLE; +#ifndef SPLIT_REND_WITH_HEAD_ROT /* Fastconv binaural data structure */ typedef struct ivas_binaural_rendering_struct { @@ -866,12 +868,12 @@ typedef struct ivas_binaural_rendering_struct IVAS_OUTPUT_SETUP_HANDLE hInputSetup; /* pointer to input spatial format for binaural renderer*/ EFAP_HANDLE hEFAPdata; /* EFAP structure*/ Word32 *hoa_dec_mtx; /* pointer to HOA decoder mtx */ /*Q29*/ - int8_t rotInCldfb; /* Flag to enable rotation within bin Renderer in CLDFB*/ - int16_t max_band; /* band upto which rendering is performed */ - int16_t conv_band; /* band upto which convolution in cldfb domain is performed */ - int16_t timeSlots; /* number of time slots of binaural renderer */ - int16_t nInChannels; /* number input channels */ - int8_t render_lfe; /* Flag to render LFE in binaural rendering*/ + Word8 rotInCldfb; /* Flag to enable rotation within bin Renderer in CLDFB*/ + Word16 max_band; /* band upto which rendering is performed */ + Word16 conv_band; /* band upto which convolution in cldfb domain is performed */ + Word16 timeSlots; /* number of time slots of binaural renderer */ + Word16 nInChannels; /* number input channels */ + Word8 render_lfe; /* Flag to render LFE in binaural rendering*/ IVAS_FORMAT ivas_format; /* format; corresponds to st_ivas->ivas_format, unless the signal gets transormed to a different domain for rendering */ /* Convolution module structure */ @@ -882,8 +884,41 @@ typedef struct ivas_binaural_rendering_struct REVERB_STRUCT_HANDLE hReverb; } BINAURAL_RENDERER, *BINAURAL_RENDERER_HANDLE; +#endif +#ifdef SPLIT_REND_WITH_HEAD_ROT +/*----------------------------------------------------------------------------------* + * IVAS decoder specific ISAR wrapper structures + *----------------------------------------------------------------------------------*/ + +typedef struct +{ + Word32 Cldfb_RealBuffer_Binaural_fx[MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX]; + Word32 Cldfb_ImagBuffer_Binaural_fx[MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX]; + Word32 output_fx[BINAURAL_CHANNELS * MAX_HEAD_ROT_POSES][L_FRAME48k]; + +} ISAR_DEC_SPLIT_REND_MULTI_BIN_CLDFB_DATA, *ISAR_DEC_SPLIT_REND_MULTI_BIN_CLDFB_DATA_HANDLE; + +typedef struct +{ + Word32 Cldfb_RealBuffer_fx[MAX_OUTPUT_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX]; + Word32 Cldfb_ImagBuffer_fx[MAX_OUTPUT_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX]; + IVAS_AUDIO_CONFIG config; + +} ISAR_DEC_SPLIT_REND_CLDFB_OUT_DATA, *ISAR_DEC_SPLIT_REND_CLDFB_OUT_DATA_HANDLE; + +typedef struct +{ + ISAR_DEC_SPLIT_REND_MULTI_BIN_CLDFB_DATA_HANDLE hMultiBinCldfbData; /*scratch buffer for frame by frame processing*/ + ISAR_SPLIT_REND_BITS_HANDLE hSplitRendBits; /*scratch buffer for frame by frame processing*/ + SPLIT_REND_WRAPPER splitrend; + ISAR_DEC_SPLIT_REND_CLDFB_OUT_DATA_HANDLE hCldfbDataOut; /*buffer to store cldfb data before binauralization*/ + Word16 numTdSamplesPerChannelCached; + +} ISAR_DEC_SPLIT_REND_WRAPPER, *ISAR_DEC_SPLIT_REND_WRAPPER_HANDLE; +#endif + /*----------------------------------------------------------------------------------* * MASA decoder structures *----------------------------------------------------------------------------------*/ @@ -892,18 +927,18 @@ typedef struct ivas_masa_decoder_ext_out_meta_struct { MASA_DECRIPTIVE_META descriptiveMeta; - uint16_t directionIndex[MASA_MAXIMUM_DIRECTIONS][MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS]; - uint8_t directToTotalRatio[MASA_MAXIMUM_DIRECTIONS][MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS]; - uint8_t spreadCoherence[MASA_MAXIMUM_DIRECTIONS][MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS]; + UWord16 directionIndex[MASA_MAXIMUM_DIRECTIONS][MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS]; + UWord8 directToTotalRatio[MASA_MAXIMUM_DIRECTIONS][MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS]; + UWord8 spreadCoherence[MASA_MAXIMUM_DIRECTIONS][MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS]; - uint8_t surroundCoherence[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS]; - uint8_t diffuseToTotalRatio[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS]; + UWord8 surroundCoherence[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS]; + UWord8 diffuseToTotalRatio[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS]; } MASA_DECODER_EXT_OUT_META; typedef struct ivas_masa_decoder_data_struct { - int16_t band_mapping[MASA_FREQUENCY_BANDS + 1]; + Word16 band_mapping[MASA_FREQUENCY_BANDS + 1]; SPHERICAL_GRID_DATA *sph_grid16; MASA_DECODER_EXT_OUT_META *extOutMeta; @@ -922,32 +957,32 @@ typedef struct ivas_masa_decoder_struct /* Data structure for MASA_ISM rendering */ typedef struct ivas_masa_ism_data_structure { - int16_t azimuth_ism[MAX_NUM_OBJECTS][MAX_PARAM_SPATIAL_SUBFRAMES + DELAY_MASA_PARAM_DEC_SFR]; - int16_t elevation_ism[MAX_NUM_OBJECTS][MAX_PARAM_SPATIAL_SUBFRAMES + DELAY_MASA_PARAM_DEC_SFR]; + Word16 azimuth_ism[MAX_NUM_OBJECTS][MAX_PARAM_SPATIAL_SUBFRAMES + DELAY_MASA_PARAM_DEC_SFR]; + Word16 elevation_ism[MAX_NUM_OBJECTS][MAX_PARAM_SPATIAL_SUBFRAMES + DELAY_MASA_PARAM_DEC_SFR]; Word32 energy_ratio_ism_fx[MAX_NUM_OBJECTS][MAX_PARAM_SPATIAL_SUBFRAMES + DELAY_MASA_PARAM_DEC_SFR][CLDFB_NO_CHANNELS_MAX]; /* Q30 */ Word32 masa_to_total_energy_ratio_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS]; /* Q30 */ - int16_t azimuth_ism_edited[MAX_NUM_OBJECTS]; - int16_t elevation_ism_edited[MAX_NUM_OBJECTS]; - uint8_t ism_is_edited[MAX_NUM_OBJECTS]; + Word16 azimuth_ism_edited[MAX_NUM_OBJECTS]; + Word16 elevation_ism_edited[MAX_NUM_OBJECTS]; + UWord8 ism_is_edited[MAX_NUM_OBJECTS]; - int16_t idx_separated_ism; - int16_t azimuth_separated_ism[MAX_PARAM_SPATIAL_SUBFRAMES + DELAY_MASA_PARAM_DEC_SFR]; - int16_t elevation_separated_ism[MAX_PARAM_SPATIAL_SUBFRAMES + DELAY_MASA_PARAM_DEC_SFR]; + Word16 idx_separated_ism; + Word16 azimuth_separated_ism[MAX_PARAM_SPATIAL_SUBFRAMES + DELAY_MASA_PARAM_DEC_SFR]; + Word16 elevation_separated_ism[MAX_PARAM_SPATIAL_SUBFRAMES + DELAY_MASA_PARAM_DEC_SFR]; Word32 q_azimuth_old_fx[MAX_NUM_OBJECTS]; /* Q22 */ Word32 q_elevation_old_fx[MAX_NUM_OBJECTS]; /* Q22 */ Word16 ismPreprocMatrix_fx[2][2][CLDFB_NO_CHANNELS_MAX]; /* Q15 */ - uint8_t objectsMoved; + UWord8 objectsMoved; Word32 eneMoveIIR_fx[2][CLDFB_NO_CHANNELS_MAX]; /*Q-22*/ Word32 enePreserveIIR_fx[2][CLDFB_NO_CHANNELS_MAX]; /*Q-22*/ Word32 preprocEneTarget_fx[CLDFB_NO_CHANNELS_MAX]; /*Q-19*/ Word32 preprocEneRealized_fx[CLDFB_NO_CHANNELS_MAX]; /*Q-19*/ Word32 **delayBuffer_fx; /* Q11 */ - int16_t delayBuffer_size; - int16_t delayBuffer_nchan; + Word16 delayBuffer_size; + Word16 delayBuffer_nchan; } MASA_ISM_DATA, *MASA_ISM_DATA_HANDLE; @@ -965,41 +1000,41 @@ typedef struct decoder_tc_buffer_structure Word16 no_channels; /*Stores no of channels in tc_fx with values*/ #endif Word16 q_tc_fx; - TC_BUFFER_MODE tc_buffer_mode; /* mode of the buffer (no buffering, render buffering, out buffering) */ - int16_t nchan_transport_jbm; /* number of TCs after TC decoding */ - int16_t nchan_transport_internal; /* total number of TC buffer channels, can include e.g. TD decorr data */ - int16_t nchan_buffer_full; /* number of channels to be fully buffered */ - int16_t n_samples_available; /* samples still available for rendering in the current frame */ - int16_t n_samples_buffered; /* full number of samples in the buffer (including spill to next frame) */ - int16_t n_samples_rendered; /* samples already rendered in the current frame */ - int16_t n_samples_granularity; /* render granularity */ - int16_t n_samples_flushed; - int16_t subframe_nbslots[MAX_JBM_SUBFRAMES_5MS]; - int16_t nb_subframes; - int16_t subframes_rendered; - int16_t slots_rendered; - int16_t num_slots; - int16_t n_samples_discard; /* number of samples to discard from the beginning of the output */ + TC_BUFFER_MODE tc_buffer_mode; /* mode of the buffer (no buffering, render buffering, out buffering) */ + Word16 nchan_transport_jbm; /* number of TCs after TC decoding */ + Word16 nchan_transport_internal; /* total number of TC buffer channels, can include e.g. TD decorr data */ + Word16 nchan_buffer_full; /* number of channels to be fully buffered */ + Word16 n_samples_available; /* samples still available for rendering in the current frame */ + Word16 n_samples_buffered; /* full number of samples in the buffer (including spill to next frame) */ + Word16 n_samples_rendered; /* samples already rendered in the current frame */ + Word16 n_samples_granularity; /* render granularity */ + Word16 n_samples_flushed; + Word16 subframe_nbslots[MAX_JBM_SUBFRAMES_5MS]; + Word16 nb_subframes; + Word16 subframes_rendered; + Word16 slots_rendered; + Word16 num_slots; + Word16 n_samples_discard; /* number of samples to discard from the beginning of the output */ } DECODER_TC_BUFFER, *DECODER_TC_BUFFER_HANDLE; typedef struct jbm_metadata_structure { - int16_t sf_write_idx; - int16_t sf_md_buffer_length; + Word16 sf_write_idx; + Word16 sf_md_buffer_length; - uint16_t directionIndexBuffer[MASA_MAXIMUM_DIRECTIONS][MAX_PARAM_SPATIAL_SUBFRAMES * MASA_JBM_RINGBUFFER_FRAMES][MASA_FREQUENCY_BANDS]; - uint8_t directToTotalRatioBuffer[MASA_MAXIMUM_DIRECTIONS][MAX_PARAM_SPATIAL_SUBFRAMES * MASA_JBM_RINGBUFFER_FRAMES][MASA_FREQUENCY_BANDS]; - uint8_t spreadCoherenceBuffer[MASA_MAXIMUM_DIRECTIONS][MAX_PARAM_SPATIAL_SUBFRAMES * MASA_JBM_RINGBUFFER_FRAMES][MASA_FREQUENCY_BANDS]; - uint8_t surroundCoherenceBuffer[MAX_PARAM_SPATIAL_SUBFRAMES * MASA_JBM_RINGBUFFER_FRAMES][MASA_FREQUENCY_BANDS]; - uint8_t diffuseToTotalRatioBuffer[MAX_PARAM_SPATIAL_SUBFRAMES * MASA_JBM_RINGBUFFER_FRAMES][MASA_FREQUENCY_BANDS]; - uint8_t numberOfDirections[MAX_PARAM_SPATIAL_SUBFRAMES * MASA_JBM_RINGBUFFER_FRAMES]; /* Descriptive metadata, value is 0 or 1 */ + UWord16 directionIndexBuffer[MASA_MAXIMUM_DIRECTIONS][MAX_PARAM_SPATIAL_SUBFRAMES * MASA_JBM_RINGBUFFER_FRAMES][MASA_FREQUENCY_BANDS]; + UWord8 directToTotalRatioBuffer[MASA_MAXIMUM_DIRECTIONS][MAX_PARAM_SPATIAL_SUBFRAMES * MASA_JBM_RINGBUFFER_FRAMES][MASA_FREQUENCY_BANDS]; + UWord8 spreadCoherenceBuffer[MASA_MAXIMUM_DIRECTIONS][MAX_PARAM_SPATIAL_SUBFRAMES * MASA_JBM_RINGBUFFER_FRAMES][MASA_FREQUENCY_BANDS]; + UWord8 surroundCoherenceBuffer[MAX_PARAM_SPATIAL_SUBFRAMES * MASA_JBM_RINGBUFFER_FRAMES][MASA_FREQUENCY_BANDS]; + UWord8 diffuseToTotalRatioBuffer[MAX_PARAM_SPATIAL_SUBFRAMES * MASA_JBM_RINGBUFFER_FRAMES][MASA_FREQUENCY_BANDS]; + UWord8 numberOfDirections[MAX_PARAM_SPATIAL_SUBFRAMES * MASA_JBM_RINGBUFFER_FRAMES]; /* Descriptive metadata, value is 0 or 1 */ - int16_t slot_read_idx; - int16_t slot_write_idx; - int16_t slot_md_buffer_length; + Word16 slot_read_idx; + Word16 slot_write_idx; + Word16 slot_md_buffer_length; - int16_t sf_to_slot_map[MAX_JBM_SUBFRAMES_5MS * JBM_CLDFB_SLOTS_IN_SUBFRAME * MASA_JBM_RINGBUFFER_FRAMES]; + Word16 sf_to_slot_map[MAX_JBM_SUBFRAMES_5MS * JBM_CLDFB_SLOTS_IN_SUBFRAME * MASA_JBM_RINGBUFFER_FRAMES]; } JBM_METADATA, *JBM_METADATA_HANDLE; @@ -1010,26 +1045,28 @@ typedef struct jbm_metadata_structure typedef struct decoder_config_structure { - int32_t ivas_total_brate; /* IVAS total bitrate in bps */ - int32_t last_ivas_total_brate; /* last IVAS total bitrate in bps */ - int32_t output_Fs; /* output signal sampling frequency in Hz */ - int16_t nchan_out; /* number of output audio channels */ + Word32 ivas_total_brate; /* IVAS total bitrate in bps */ + Word32 last_ivas_total_brate; /* last IVAS total bitrate in bps */ + Word32 output_Fs; /* output signal sampling frequency in Hz */ + Word16 nchan_out; /* number of output audio channels */ AUDIO_CONFIG output_config; /* output audio configuration */ - int16_t Opt_LsCustom; /* indicates whether loudspeaker custom setup is used */ - int16_t Opt_HRTF_binary; /* indicates whether HRTF binary file is used */ - int16_t Opt_Headrotation; /* indicates whether head-rotation is used */ - int16_t Opt_RendConfigCustom; /* indicates whether Renderer configuration custom setup is used */ + Word16 Opt_LsCustom; /* indicates whether loudspeaker custom setup is used */ + Word16 Opt_HRTF_binary; /* indicates whether HRTF binary file is used */ + Word16 Opt_Headrotation; /* indicates whether head-rotation is used */ + Word16 Opt_RendConfigCustom; /* indicates whether Renderer configuration custom setup is used */ IVAS_HEAD_ORIENT_TRK_T orientation_tracking; /* indicates orientation tracking type */ - int16_t Opt_non_diegetic_pan; /* indicates diegetic or not */ + Word16 Opt_non_diegetic_pan; /* indicates diegetic or not */ Word16 non_diegetic_pan_gain_fx; /* non diegetic panning gain*/ /* Q15 */ - int16_t Opt_AMR_WB; /* flag indicating AMR-WB IO mode */ - int16_t Opt_ExternalOrientation; /* indiates whether external orientations are used */ - int16_t Opt_dpid_on; /* indicates whether Directivity pattern option is used */ - int16_t Opt_aeid_on; /* indicates whether Acoustic environment option is used */ - int16_t Opt_tsm; /* indicates whether time scaling modification is activated */ + Word16 Opt_AMR_WB; /* flag indicating AMR-WB IO mode */ + Word16 Opt_ExternalOrientation; /* indiates whether external orientations are used */ + Word16 Opt_dpid_on; /* indicates whether Directivity pattern option is used */ + Word16 Opt_aeid_on; /* indicates whether Acoustic environment option is used */ + Word16 Opt_tsm; /* indicates whether time scaling modification is activated */ IVAS_RENDER_FRAMESIZE render_framesize; - int16_t Opt_delay_comp; /* flag indicating delay compensation active */ - + Word16 Opt_delay_comp; /* flag indicating delay compensation active */ +#ifdef SPLIT_REND_WITH_HEAD_ROT + int16_t Opt_Limiter; +#endif } DECODER_CONFIG, *DECODER_CONFIG_HANDLE; @@ -1047,8 +1084,8 @@ typedef struct Decoder_Struct IVAS_FORMAT ivas_format; /* IVAS format */ IVAS_FORMAT last_ivas_format; /* last frame IVAS format */ - int16_t sid_format; /* IVAS format indicator from SID frame */ - int16_t nchan_transport; /* number of transport channels */ + Word16 sid_format; /* IVAS format indicator from SID frame */ + Word16 nchan_transport; /* number of transport channels */ IVAS_OUTPUT_SETUP hOutSetup; /* output setup structure */ AUDIO_CONFIG intern_config; /* internal audio configuration */ IVAS_OUTPUT_SETUP hIntSetup; /* internal setup structure */ @@ -1056,24 +1093,24 @@ typedef struct Decoder_Struct AUDIO_CONFIG transport_config; /* transport audio configuration */ IVAS_OUTPUT_SETUP hTransSetup; /* transport setup structure */ - int16_t element_mode_init; /* element mode used at initialization */ - int16_t codec_mode; /* Mode 1 or 2 */ - int16_t ini_frame; /* initialization frames counter */ - int16_t ini_active_frame; /* initialization active frames counter */ + Word16 element_mode_init; /* element mode used at initialization */ + Word16 codec_mode; /* Mode 1 or 2 */ + Word16 ini_frame; /* initialization frames counter */ + Word16 ini_active_frame; /* initialization active frames counter */ - int16_t bfi; /* FEC - bad frame indicator */ - int16_t BER_detect; /* BER detect flag */ - int16_t num_bits; /* BER detect flag */ + Word16 bfi; /* FEC - bad frame indicator */ + Word16 BER_detect; /* BER detect flag */ + Word16 num_bits; /* BER detect flag */ - uint16_t *bit_stream; /* Pointer to bitstream buffer */ - int16_t writeFECoffset; /* parameter for debugging JBM stuff */ + UWord16 *bit_stream; /* Pointer to bitstream buffer */ + Word16 writeFECoffset; /* parameter for debugging JBM stuff */ IVAS_LIMITER_HANDLE hLimiter; /* Limiter handle */ /* core-decoder modules */ - int16_t nSCE; /* number of total SCEs */ - int16_t nCPE; /* number of total CPEs */ - int16_t nCPE_old; /* number of total CPEs available in the last frame before bitrate switching */ + Word16 nSCE; /* number of total SCEs */ + Word16 nCPE; /* number of total CPEs */ + Word16 nCPE_old; /* number of total CPEs available in the last frame before bitrate switching */ SCE_DEC_HANDLE hSCE[MAX_SCE]; /* SCE handles */ CPE_DEC_HANDLE hCPE[MCT_MAX_BLOCKS]; /* CPE handles */ @@ -1092,12 +1129,12 @@ typedef struct Decoder_Struct LFE_DEC_HANDLE hLFE; /* LFE handle */ ISM_MODE ism_mode; /* ISM format mode */ - int16_t nchan_ism; /* number of ISM channels */ + Word16 nchan_ism; /* number of ISM channels */ MC_MODE mc_mode; /* MC format mode */ - int16_t sba_order; /* Ambisonic (SBA) order */ - int16_t sba_planar; /* Ambisonic (SBA) planar flag */ - int16_t sba_analysis_order; /* Ambisonic (SBA) order used for analysis and coding */ - int16_t sba_dirac_stereo_flag; /* flag indicating stereo output for SBA DirAC modes with 1 TC */ + Word16 sba_order; /* Ambisonic (SBA) order */ + Word16 sba_planar; /* Ambisonic (SBA) planar flag */ + Word16 sba_analysis_order; /* Ambisonic (SBA) order used for analysis and coding */ + Word16 sba_dirac_stereo_flag; /* flag indicating stereo output for SBA DirAC modes with 1 TC */ /* rendering modules */ RENDERER_TYPE renderer_type; /* renderer type */ @@ -1106,7 +1143,11 @@ typedef struct Decoder_Struct BINAURAL_RENDERER_HANDLE hBinRenderer; /* fastconv binaural renderer handle */ BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd; /* Time domain binaural object renderer handle */ TDREND_HRFILT_FiltSet_t *hHrtfTD; /* pointer to HRTF data for TD renderer */ +#ifdef SPLIT_REND_WITH_HEAD_ROT + DIRAC_DEC_BIN_HANDLE hDiracDecBin[MAX_HEAD_ROT_POSES]; /* parametric binaural renderer handle */ +#else DIRAC_DEC_BIN_HANDLE hDiracDecBin; /* parametric binaural renderer handle */ +#endif LSSETUP_CONVERSION_HANDLE hLsSetUpConversion; /* MC LS configuration convertion handle */ EFAP_HANDLE hEFAPdata; /* EFAP structure */ VBAP_HANDLE hVBAPdata; /* VBAP structure */ @@ -1120,7 +1161,7 @@ typedef struct Decoder_Struct Word32 *hoa_dec_mtx; /* Pointer to decoder matrix for SBA */ HEAD_TRACK_DATA_HANDLE hHeadTrackData; /* Head tracking data structure */ RENDER_CONFIG_DATA *hRenderConfig; /* Renderer config pointer */ - int32_t binaural_latency_ns; /* Binauralization latency in ns */ + Word32 binaural_latency_ns; /* Binauralization latency in ns */ EXTERNAL_ORIENTATION_HANDLE hExtOrientationData; /* External orientation data structure */ COMBINED_ORIENTATION_HANDLE hCombinedOrientationData; /* Combined external and head orientation data structure */ DIRAC_REND_HANDLE hDirACRend; /* DirAC renderer handle */ @@ -1128,16 +1169,20 @@ typedef struct Decoder_Struct MASA_ISM_DATA_HANDLE hMasaIsmData; /* OMASA rendering handle */ SBA_ISM_DATA_HANDLE hSbaIsmData; /* OSBA rendering handle */ - int16_t flag_omasa_brate; + Word16 flag_omasa_brate; +#ifdef SPLIT_REND_WITH_HEAD_ROT + ISAR_DEC_SPLIT_REND_WRAPPER_HANDLE hSplitBinRend; /* ISAR split binaural rendering handle */ + BINAURAL_TD_OBJECT_RENDERER_HANDLE hTdRendHandles[MAX_HEAD_ROT_POSES - 1]; +#endif /* JBM module */ DECODER_TC_BUFFER_HANDLE hTcBuffer; /* JBM structure */ JBM_METADATA_HANDLE hJbmMetadata; /* Structure for metadata buffering in JBM */ - int32_t last_active_ivas_total_brate; - int16_t ism_extmeta_active; /* Extended metadata active in decoder */ - int16_t ism_extmeta_cnt; /* Change frame counter for extended metadata */ + Word32 last_active_ivas_total_brate; + Word16 ism_extmeta_active; /* Extended metadata active in decoder */ + Word16 ism_extmeta_cnt; /* Change frame counter for extended metadata */ Word32 **mem_hp20_out_fx; Word32 *p_output_fx[MAX_OUTPUT_CHANNELS + MAX_NUM_OBJECTS]; /* Word32-output audio buffers */ Word16 p_out_len;/*Stores the total no of channels for which memory is allocated to p_output_fx*/ diff --git a/lib_dec/ivas_stereo_adapt_GR_dec.c b/lib_dec/ivas_stereo_adapt_GR_dec_fx.c similarity index 99% rename from lib_dec/ivas_stereo_adapt_GR_dec.c rename to lib_dec/ivas_stereo_adapt_GR_dec_fx.c index fbaa98534e6baf399a929bf42bfa9700c361b9a0..2bade4786e8c8fde9f33e95ff0cbdeaaedc95ffb 100644 --- a/lib_dec/ivas_stereo_adapt_GR_dec.c +++ b/lib_dec/ivas_stereo_adapt_GR_dec_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other @@ -32,12 +32,10 @@ #include #include "options.h" -#include "prot.h" +#include "prot_fx.h" #include "wmc_auto.h" -#include "ivas_prot.h" #include "ivas_rom_com.h" #include "rom_dec.h" -#include "prot_fx.h" #include "ivas_prot_fx.h" /*---------------------------------------------------------------------* diff --git a/lib_dec/ivas_stereo_cng_dec.c b/lib_dec/ivas_stereo_cng_dec.c index f8d6f6086edf0308a7d11134905dfccbc6700c5b..223860db0f18067279a25906c3832a1673cdbac2 100644 --- a/lib_dec/ivas_stereo_cng_dec.c +++ b/lib_dec/ivas_stereo_cng_dec.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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,13 +34,11 @@ #include "options.h" #include #include "cnst.h" -#include "prot.h" -#include "ivas_prot.h" +#include "prot_fx.h" #include "ivas_cnst.h" #include "ivas_rom_com.h" #include "wmc_auto.h" #include "ivas_prot_fx.h" -#include "prot_fx.h" #include "ivas_rom_com_fx.h" /*------------------------------------------------------------------- @@ -357,7 +355,7 @@ static void stereo_dft_generate_comfort_noise_fx( { /* Transform shb LP spectrum */ set32_fx( shb_shape, 0, L_FRAME16k ); - Copy_Scale_sig_16_32( st->hTdCngDec->shb_lpcCNG_fx, shb_shape, LPC_SHB_ORDER + 1, Q15 ); // Q30 + Copy_Scale_sig_16_32_DEPREC( st->hTdCngDec->shb_lpcCNG_fx, shb_shape, LPC_SHB_ORDER + 1, Q15 ); // Q30 IF( NE_16( st->L_frame, L_FRAME16k ) ) { @@ -586,7 +584,8 @@ static void stereo_dft_generate_comfort_noise_fx( ptr_r = DFT[chan] + add( hFdCngCom->stopFFTbin, i_mult( k, STEREO_DFT32MS_N_MAX ) ); /* q_dft */ ptr_i = ptr_r + 1; - FOR( i = 0; i < ( min( output_frame, hFdCngCom->regularStopBand * 16 ) - hFdCngCom->stopFFTbin ) / 2; i++ ) + Word16 len = shr( ( sub( s_min( output_frame, i_mult( hFdCngCom->regularStopBand, 16 ) ), hFdCngCom->stopFFTbin ) ), 1 ); + FOR( i = 0; i < len; i++ ) { /* Real part in FFT bins */ rand_gauss_fx( ptr_r, &st->hTdCngDec->cng_seed, q_dft ); @@ -623,7 +622,8 @@ static void stereo_dft_generate_comfort_noise_fx( ptr_r = DFT[chan] + add( hFdCngCom->stopFFTbin, i_mult( k, STEREO_DFT32MS_N_MAX ) ); /* q_dft */ ptr_i = ptr_r + 1; - FOR( i = 0; i < ( min( output_frame, hFdCngCom->regularStopBand * 16 ) - hFdCngCom->stopFFTbin ) / 2; i++ ) + tmp = shr( sub( s_min( output_frame, i_mult( hFdCngCom->regularStopBand, 16 ) ), hFdCngCom->stopFFTbin ), 1 ); + FOR( i = 0; i < tmp; i++ ) { ( *ptr_r ) = L_shl( Mpy_32_32( ( *ptr_r ), tmp32_1 ), q_shift ); /* q_dft + q_shift */ move32(); @@ -683,7 +683,12 @@ static void stereo_dft_generate_comfort_noise_fx( factor = L_min( L_add( L_shl( hStereoDft->scale_fx, sub( 16, q_div ) ), W_extract_l( W_mult0_32_32( Mpy_32_16_1( L_sub( factor, L_shl( hStereoDft->scale_fx, sub( 16, q_div ) ) ), ONE_BY_MAX_K ), hStereoCng->xfade_frame_counter ) ) ), factor ); /* q_div */ FOR( ; j <= hFdCngCom->part[k]; j++ ) { +#ifdef FIX_ISSUE_1218 + /* NOTE: saturation is added here as part of issue 1218 fix. After rescaling the fdcng noise estimation buffers, due to slight precision loss, values may slightly overflow */ + hFdCngCom->cngNoiseLevel[j] = L_shl_sat( Mpy_32_32( st->hFdCngDec->bandNoiseShape[j], factor ), q_div ); /* exp(st->hFdCngDec->bandNoiseShape_exp) */ +#else hFdCngCom->cngNoiseLevel[j] = L_shl( Mpy_32_32( st->hFdCngDec->bandNoiseShape[j], factor ), q_div ); /* exp(st->hFdCngDec->bandNoiseShape_exp) */ +#endif move32(); } } @@ -1445,7 +1450,11 @@ void stereo_cna_update_params_fx( { IF( EQ_16( hCPE->nchan_out, 1 ) ) { +#ifdef OPT_STEREO_32KBPS_V1 + c_LR_fx = MAX_32; +#else /* OPT_STEREO_32KBPS_V1 */ c_LR_fx = MAX_WORD16; +#endif /* OPT_STEREO_32KBPS_V1 */ move32(); c_ILD_fx = 0; move32(); @@ -1507,8 +1516,12 @@ void stereo_cna_update_params_fx( dotLR_fx = Mpy_32_32( W_extract_l( dotLR_fx ), energy_xy_fx ); /* dotLR_fx_q + ((31 - temp_res_q) - 31)) */ dotLR_fx_q = add( dotLR_fx_q, sub( sub( 31, temp_res_q ), 31 ) ); dotLR_fx = W_deposit32_l( L_shl_sat( W_extract_l( dotLR_fx ), sub( 31, dotLR_fx_q ) ) ); /* Q31 */ - /* estimate L/R correlation factor and ILD in time domain */ + /* estimate L/R correlation factor and ILD in time domain */ +#ifdef OPT_STEREO_32KBPS_V1 + c_LR_fx = W_extract_l( dotLR_fx ); /* Q31 */ +#else /* OPT_STEREO_32KBPS_V1 */ c_LR_fx = extract_h( W_extract_l( dotLR_fx ) ); /* Q15 */ +#endif /* OPT_STEREO_32KBPS_V1 */ temp_res_q = 0; move16(); @@ -1547,15 +1560,24 @@ void stereo_cna_update_params_fx( /* update of long-term ILD and LR correlation factors for stereo CNA */ IF( !hFdCngDec->first_cna_noise_updated ) { +#ifdef OPT_STEREO_32KBPS_V1 + hFdCngDec->cna_LR_LT_fx = extract_h( c_LR_fx ); +#else /* OPT_STEREO_32KBPS_V1 */ hFdCngDec->cna_LR_LT_fx = extract_l( c_LR_fx ); +#endif /* OPT_STEREO_32KBPS_V1 */ move16(); hFdCngDec->cna_ILD_LT_fx = extract_l( c_ILD_fx ); move16(); } ELSE { +#ifdef OPT_STEREO_32KBPS_V1 + hFdCngDec->cna_LR_LT_fx = extract_h( L_add_sat( Mpy_32_16_1( STEREO_CNA_LR_CORR_LT_FILT_FX, hFdCngDec->cna_LR_LT_fx ), + Mpy_32_32( ONE_IN_Q31 - STEREO_CNA_LR_CORR_LT_FILT_FX, c_LR_fx ) ) ); /* Q31 */ +#else /* OPT_STEREO_32KBPS_V1 */ hFdCngDec->cna_LR_LT_fx = extract_h( L_add_sat( Mpy_32_16_1( STEREO_CNA_LR_CORR_LT_FILT_FX, hFdCngDec->cna_LR_LT_fx ), Mpy_32_16_1( L_sub( ONE_IN_Q31, STEREO_CNA_LR_CORR_LT_FILT_FX ), extract_l( c_LR_fx ) ) ) ); /* Q31 */ +#endif /* OPT_STEREO_32KBPS_V1 */ move16(); hFdCngDec->cna_ILD_LT_fx = extract_h( L_add_sat( Mpy_32_16_1( STEREO_CNA_ILD_LT_FILT_FX, hFdCngDec->cna_ILD_LT_fx ), diff --git a/lib_dec/ivas_stereo_dft_dec.c b/lib_dec/ivas_stereo_dft_dec.c index 94234a1e12b14523fc1485106a6683a6181f05b4..f0fd1978b2e03862de5a38a572aff48efa0c3002 100644 --- a/lib_dec/ivas_stereo_dft_dec.c +++ b/lib_dec/ivas_stereo_dft_dec.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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 "cnst.h" #include "rom_com.h" #include "rom_dec.h" -#include "prot.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "ivas_cnst.h" #include "ivas_rom_com.h" #include "ivas_rom_com_fx.h" @@ -289,7 +287,7 @@ void stereo_dft_dec_analyze_fx( move16(); /* Offset FOR the time buffers */ - assert( ( delay >= -NS2SA_FX2( ( input_frame * FRAMES_PER_SEC ), STEREO_DFT_DELAY_DEC_BWE_NS + STEREO_DFT_OVL_NS / 2 ) ) && ( delay <= NS2SA_FX2( ( input_frame * FRAMES_PER_SEC ), STEREO_DFT_OVL_NS ) ) ); + assert( ( delay >= -NS2SA( input_frame * FRAMES_PER_SEC, STEREO_DFT_DELAY_DEC_BWE_NS + STEREO_DFT_OVL_NS / 2 ) ) && ( delay <= NS2SA( input_frame * FRAMES_PER_SEC, STEREO_DFT_OVL_NS ) ) ); mem_size = add( delay_dec, delay ); /* Update buffers */ diff --git a/lib_dec/ivas_stereo_dft_dec_dmx.c b/lib_dec/ivas_stereo_dft_dec_dmx_fx.c similarity index 98% rename from lib_dec/ivas_stereo_dft_dec_dmx.c rename to lib_dec/ivas_stereo_dft_dec_dmx_fx.c index e97ba23de18a04f2fae1f611dc632222ccc802a5..e82005965b6a452c7d327e89d07b42b082048c7b 100644 --- a/lib_dec/ivas_stereo_dft_dec_dmx.c +++ b/lib_dec/ivas_stereo_dft_dec_dmx_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other @@ -35,15 +35,13 @@ #include "options.h" #include #include "cnst.h" -#include "prot.h" -#include "ivas_prot.h" +#include "prot_fx.h" #include "ivas_cnst.h" #include "ivas_rom_com.h" #include "ivas_rom_dec.h" #include "rom_com.h" #include "wmc_auto.h" #include "ivas_prot_fx.h" -#include "prot_fx.h" /*------------------------------------------------------------------------- @@ -61,8 +59,8 @@ void stereo_dft_dmx_out_reset_fx( hStereoDftDmx->prevTargetGain_fx = ONE_IN_Q29; /* Q29 */ move32(); - set32_fx( hStereoDftDmx->memOutHB_fx, 0, NS2SA_FX2( 48000, STEREO_DFT32MS_OVL_NS ) ); - set32_fx( hStereoDftDmx->memTransitionHB_fx, 0, NS2SA_FX2( 48000, STEREO_DFT32MS_OVL_NS ) ); + set32_fx( hStereoDftDmx->memOutHB_fx, 0, NS2SA( 48000, STEREO_DFT32MS_OVL_NS ) ); + set32_fx( hStereoDftDmx->memTransitionHB_fx, 0, NS2SA( 48000, STEREO_DFT32MS_OVL_NS ) ); return; } diff --git a/lib_dec/ivas_stereo_dft_dec_fx.c b/lib_dec/ivas_stereo_dft_dec_fx.c index 3ee0f8e8c7a041648d0ade0266b758032e78a0d1..3d9e58ad1adda592d13fac5b3dc29d89aaa45fab 100644 --- a/lib_dec/ivas_stereo_dft_dec_fx.c +++ b/lib_dec/ivas_stereo_dft_dec_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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 "cnst.h" #include "rom_com.h" #include "rom_dec.h" -#include "prot.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "ivas_prot_fx.h" #include "ivas_cnst.h" #include "ivas_rom_com.h" @@ -99,7 +97,7 @@ void stereo_dft_dec_reset_fx( Word16 i; Word16 j, b; #ifdef MSAN_FIX - set_zero_fx( hStereoDft->buff_LBTCX_mem_fx, NS2SA_FX2( 16000, STEREO_DFT32MS_OVL_NS ) ); + set_zero_fx( hStereoDft->buff_LBTCX_mem_fx, NS2SA( 16000, STEREO_DFT32MS_OVL_NS ) ); #endif /*Configuration*/ @@ -124,13 +122,25 @@ void stereo_dft_dec_reset_fx( set16_fx( hStereoDft->res_pred_index_previous, 0, STEREO_DFT_BAND_MAX ); +#ifdef MSAN_FIX + FOR( i = 0; i < STEREO_DFT_BAND_MAX * 2; i++ ) + { + hStereoDft->res_gains_ind_fx[0][i] = 1006632960; /* 15.0f in Q26 */ + move32(); + } +#else FOR( i = 0; i < STEREO_DFT_BAND_MAX; i++ ) { hStereoDft->res_gains_ind_fx[0][i] = 1006632960; /* 15.0f in Q26 */ move32(); } +#endif +#ifdef MSAN_FIX + set32_fx( hStereoDft->res_gains_ind_fx[1], 0, STEREO_DFT_BAND_MAX * 2 ); +#else set32_fx( hStereoDft->res_gains_ind_fx[1], 0, STEREO_DFT_BAND_MAX ); +#endif /*residual coding*/ set16_fx( hStereoDft->res_cod_mode, hStereoDft->hConfig->res_cod_mode, STEREO_DFT_DEC_DFT_NB ); @@ -248,7 +258,21 @@ void stereo_dft_dec_reset_fx( move16(); hStereoDft->ipd_xfade_prev_fx = 0; move32(); - + hStereoDft->frame_sid_nodata = 0; + move16(); +#ifdef MSAN_FIX + FOR( b = 0; b < 2 * IVAS_MAX_NUM_BANDS; b++ ) + { + FOR( i = 0; i < 2; i++ ) + { + FOR( j = 0; j < 4; j++ ) + { + hStereoDft->mixer_mat_smooth_fx[i][j][b] = 0; + move32(); + } + } + } +#else FOR( b = 0; b < hStereoDft->nbands; b++ ) { FOR( i = 0; i < 2; i++ ) @@ -260,6 +284,7 @@ void stereo_dft_dec_reset_fx( } } } +#endif hStereoDft->first_frame = 1; move16(); hStereoDft->g_L_prev_fx = 0; @@ -1334,7 +1359,7 @@ void stereo_dft_dec_res_fx( set32_fx( hCPE->hStereoDft->res_cod_mem_fx, 0, STEREO_DFT_OVL_8k ); hCPE->hStereoDft->q_res_cod_mem_fx = Q16; move16(); - set32_fx( hCPE->input_mem_fx[1], 0, NS2SA_FX2( 8000, STEREO_DFT32MS_OVL_NS ) ); + set32_fx( hCPE->input_mem_fx[1], 0, NS2SA( 8000, STEREO_DFT32MS_OVL_NS ) ); set16_fx( hCPE->hStereoDft->hBpf->pst_old_syn_fx, 0, STEREO_DFT_NBPSF_PIT_MAX_8k ); hCPE->hStereoDft->hBpf->pst_mem_deemp_err_fx = 0; move16(); @@ -1343,23 +1368,23 @@ void stereo_dft_dec_res_fx( /*Inverse MDCT*/ TCX_MDCT_Inverse( res_buf, q_res, win, STEREO_DFT_OVL_8k, L_FRAME8k - STEREO_DFT_OVL_8k, STEREO_DFT_OVL_8k, IVAS_CPE_DFT ); + scale_sig( win, L_FRAME8k + STEREO_DFT_OVL_8k, -1 ); + + Word16 q_shift = sub( hCPE->hStereoDft->q_res_cod_mem_fx, Q16 ); IF( !prev_bfi ) { /*OLA*/ /*overlapping parts*/ - Word16 q_shift = sub( hCPE->hStereoDft->q_res_cod_mem_fx, Q16 ); + FOR( i = 0; i < STEREO_DFT_OVL_8k; i++ ) { - win[i] = extract_h( L_add( hCPE->hStereoDft->res_cod_mem_fx[i], L_shl( L_mult( win[i], hCPE->hStereoDft->win_8k_fx[i] ), q_shift ) ) ); /* q_res_cod_mem_fx */ + win[i] = extract_h( L_add( L_shr( hCPE->hStereoDft->res_cod_mem_fx[i], 1 ), L_shl( L_mult( win[i], hCPE->hStereoDft->win_8k_fx[i] ), q_shift ) ) ); /* q_res_cod_mem_fx -17 (q_shift -1)*/ move16(); - hCPE->hStereoDft->res_cod_mem_fx[i] = L_mult( win[L_FRAME8k + i], hCPE->hStereoDft->win_8k_fx[STEREO_DFT_OVL_8k - 1 - i] ); /* q_res_cod_mem_fx */ + hCPE->hStereoDft->res_cod_mem_fx[i] = L_shl( L_mult( win[L_FRAME8k + i], hCPE->hStereoDft->win_8k_fx[STEREO_DFT_OVL_8k - 1 - i] ), 1 ); /* -1 +15 +1 +1 */ move32(); } - IF( q_shift != 0 ) - { - v_shr_16( &win[STEREO_DFT_OVL_8k], negate( q_shift ), &win[STEREO_DFT_OVL_8k], L_FRAME8k ); - } - hCPE->hStereoDft->q_res_cod_mem_fx = Q16; + + move16(); } ELSE @@ -1371,24 +1396,31 @@ void stereo_dft_dec_res_fx( move16(); FOR( i = 0; i < STEREO_DFT_OVL_8k; i++ ) { - win[i] = extract_h( Madd_32_16( Mpy_32_16_1( hCPE->hStereoDft->res_cod_mem_fx[i], sub( MAX_16, mult( fac, fac ) ) ), - L_mult( hCPE->hStereoDft->win_8k_fx[i], win[i] ), - sub( MAX_16, mult( sub( MAX_16, fac ), sub( MAX_16, fac ) ) ) ) ); /* Q0 */ + win[i] = extract_h( Madd_32_16( Mpy_32_16_1( L_shr( hCPE->hStereoDft->res_cod_mem_fx[i], 1 ), sub( MAX_16, mult( fac, fac ) ) ), + L_shl( L_mult( hCPE->hStereoDft->win_8k_fx[i], win[i] ), q_shift ), + sub( MAX_16, mult( sub( MAX_16, fac ), sub( MAX_16, fac ) ) ) ) ); /* Q(q_shift -1) */ move16(); - hCPE->hStereoDft->res_cod_mem_fx[i] = L_mult( win[L_FRAME8k + i], hCPE->hStereoDft->win_8k_fx[STEREO_DFT_OVL_8k - 1 - i] ); /* Q16 */ + hCPE->hStereoDft->res_cod_mem_fx[i] = L_shl( L_mult( win[L_FRAME8k + i], hCPE->hStereoDft->win_8k_fx[STEREO_DFT_OVL_8k - 1 - i] ), 1 ); /* Q16 */ move32(); fac = add( fac, step ); } } - Copy( win, out_16, L_FRAME8k ); /* Q0 */ + IF( q_shift != 0 ) + { + v_shr_16( &win[STEREO_DFT_OVL_8k], negate( q_shift ), &win[STEREO_DFT_OVL_8k], L_FRAME8k ); + } + + hCPE->hStereoDft->q_res_cod_mem_fx = Q16; + + Copy( win, out_16, L_FRAME8k ); /* Q(q_shift -1 ) */ IF( hCPE->hCoreCoder[0]->core == ACELP_CORE ) { /* bass post-filter */ bass_psfilter_fx( hCPE->hStereoDft->hBpf, hCPE->hCoreCoder[0]->Opt_AMR_WB, out_16, L_FRAME8k, hCPE->hCoreCoder[0]->old_pitch_buf_16_fx + ( L_FRAME8k / STEREO_DFT_L_SUBFR_8k ), hCPE->hCoreCoder[0]->bpf_off, - hCPE->hCoreCoder[0]->stab_fac_fx, &hCPE->hStereoDft->stab_fac_smooth_res_fx, hCPE->hCoreCoder[0]->last_coder_type, 0, bpf_error_signal_8k_16 ); - Copy_Scale_sig_16_32( bpf_error_signal_8k_16, bpf_error_signal_8k, L_FRAME8k, Q15 ); /* Q15 */ + hCPE->hCoreCoder[0]->stab_fac_fx, &hCPE->hStereoDft->stab_fac_smooth_res_fx, hCPE->hCoreCoder[0]->last_coder_type, sub( q_shift, 1 ), bpf_error_signal_8k_16 ); + Copy_Scale_sig_16_32_DEPREC( bpf_error_signal_8k_16, bpf_error_signal_8k, L_FRAME8k, Q15 ); /* Q15 */ res_bpf_flag = res_bpf_adapt_ivas_fx( hCPE->hStereoDft, bpf_error_signal_8k, res_buf, q_res ); IF( prev_bfi ) @@ -1404,7 +1436,11 @@ void stereo_dft_dec_res_fx( move32(); } } - Copy_Scale_sig_16_32( out_16, output, L_FRAME8k, 16 ); /* Q16 */ +#ifdef FIX_ISSUE_1237 + Copy_Scale_sig_16_32_no_sat( out_16, output, L_FRAME8k, sub( 15, sub( q_shift, 1 ) ) ); /* Q15 */ +#else + Copy_Scale_sig_16_32_DEPREC( out_16, output, L_FRAME8k, 16 ); /* Q16 */ +#endif IF( res_bpf_flag ) { v_sub_32( output, bpf_error_signal_8k, output, L_FRAME8k ); @@ -1415,12 +1451,20 @@ void stereo_dft_dec_res_fx( set16_fx( hCPE->hStereoDft->hBpf->pst_old_syn_fx, 0, STEREO_DFT_NBPSF_PIT_MAX_8k ); hCPE->hStereoDft->hBpf->pst_mem_deemp_err_fx = 0; move16(); - Copy_Scale_sig_16_32( out_16, output, L_FRAME8k, 16 ); /* Q16 */ +#ifdef FIX_ISSUE_1237 + Copy_Scale_sig_16_32_no_sat( out_16, output, L_FRAME8k, sub( 15, sub( q_shift, 1 ) ) ); /* Q15 */ +#else + Copy_Scale_sig_16_32_DEPREC( out_16, output, L_FRAME8k, 16 ); /* Q16 */ +#endif } ELSE { /* This step is needed to ensure output is properly populated with scaled values in all cases*/ - Copy_Scale_sig_16_32( out_16, output, L_FRAME8k, 16 ); /* Q16 */ +#ifdef FIX_ISSUE_1237 + Copy_Scale_sig_16_32_no_sat( out_16, output, L_FRAME8k, sub( 15, sub( q_shift, 1 ) ) ); /* Q15 */ +#else + Copy_Scale_sig_16_32_DEPREC( out_16, output, L_FRAME8k, 16 ); /* Q16 */ +#endif } return; @@ -1481,8 +1525,11 @@ void stereo_dft_dec_fx( HANDLE_FD_CNG_COM hFdCngCom = hFdCngDec->hFdCngCom; Word16 *cna_seed = &( hFdCngCom->seed ); Word32 DFT_W, DFT_Y; +#ifndef OPT_STEREO_32KBPS_V1 Word16 q_samp_ratio = Q15; move16(); +#endif /* OPT_STEREO_32KBPS_V1 */ + Word16 len; output_frame = (Word16) Mpy_32_32( L_add( st0->output_Fs, FRAMES_PER_SEC_BY_2 ), ONE_BY_FRAMES_PER_SEC_Q31 ); /* Q0 */ @@ -1490,8 +1537,12 @@ void stereo_dft_dec_fx( * Initialization *-----------------------------------------------------------------*/ +#ifdef OPT_STEREO_32KBPS_V1 + samp_ratio = divide3232( st0->sr_core, st0->output_Fs ); // Q15 +#else /* OPT_STEREO_32KBPS_V1 */ samp_ratio = (Word16) BASOP_Util_Divide3232_Scale( st0->sr_core, st0->output_Fs, &q_samp_ratio ); samp_ratio = shr( samp_ratio, sub( Q15 - Q12, q_samp_ratio ) ); +#endif /* OPT_STEREO_32KBPS_V1 */ stop = shr( STEREO_DFT32MS_N_32k, 1 ); @@ -1847,7 +1898,8 @@ void stereo_dft_dec_fx( DFT_R[2 * i + 1] = L_sub( DFT_W, DFT_Y ); /* qDFT */ move32(); } - FOR( i = hStereoDft->band_limits[b]; i < min( stop, hStereoDft->band_limits[b + 1] ); i++ ) + len = s_min( stop, hStereoDft->band_limits[b + 1] ); + FOR( i = hStereoDft->band_limits[b]; i < len; i++ ) { DFT_W = Madd_32_32( Mpy_32_32( hStereoDft->mixer_mat_smooth_fx[0][0][b + k * IVAS_MAX_NUM_BANDS], pDFT_DMX[2 * i] ), L_add( hStereoDft->mixer_mat_smooth_fx[0][1][b + k * IVAS_MAX_NUM_BANDS], @@ -1954,7 +2006,8 @@ void stereo_dft_dec_fx( } ELSE { - FOR( i = hStereoDft->band_limits[b]; i < min( stop, hStereoDft->band_limits[b + 1] ); i++ ) + len = s_min( stop, hStereoDft->band_limits[b + 1] ); + FOR( i = hStereoDft->band_limits[b]; i < len; i++ ) { tmp = L_add( Madd_32_16( pDFT_RES[2 * i], pDFT_DMX[2 * i], g ), DFT_PRED_RES[2 * i] ); /* qDFT */ @@ -2064,10 +2117,17 @@ void stereo_dft_dec_fx( /*Nyquist Freq.*/ IF( EQ_16( hStereoDft->band_limits[b], shr( hStereoDft->NFFT, 1 ) ) ) { +#ifdef OPT_STEREO_32KBPS_V1 + DFT_L[1] = Madd_32_16( pDFT_DMX[1], pDFT_DMX[1], g ); /* qDFT */ + move32(); + DFT_R[1] = Msub_32_16( pDFT_DMX[1], pDFT_DMX[1], g ); /* qDFT */ + move32(); +#else /* OPT_STEREO_32KBPS_V1 */ DFT_L[1] = L_add( pDFT_DMX[1], Mpy_32_16_1( pDFT_DMX[1], g ) ); /* qDFT */ move32(); DFT_R[1] = L_sub( pDFT_DMX[1], Mpy_32_16_1( pDFT_DMX[1], g ) ); /* qDFT */ move32(); +#endif /* OPT_STEREO_32KBPS_V1 */ DFT_L[1] = Mpy_32_16_1( DFT_L[1], INV_SQRT2_FX_Q15 ); /* qDFT */ move32(); DFT_R[1] = Mpy_32_16_1( DFT_R[1], INV_SQRT2_FX_Q15 ); /* qDFT */ @@ -2168,8 +2228,8 @@ void stereo_dft_dec_fx( gamma = 0; move16(); } - - FOR( i = max( hFdCngDec->cna_band_limits[b], ( hFdCngCom->startBand / 2 ) ); i < min( hFdCngDec->cna_band_limits[b + 1], ( L_FRAME16k ) >> 1 ); i++ ) + len = s_min( hFdCngDec->cna_band_limits[b + 1], ( L_FRAME16k ) >> 1 ); + FOR( i = s_max( hFdCngDec->cna_band_limits[b], ( hFdCngCom->startBand >> 1 ) ); i < len; i++ ) // i < min( hFdCngDec->cna_band_limits[b + 1], ( L_FRAME16k ) >> 1 ); { Word32 l_tmp; lev1 = *ptr_per++; @@ -2200,27 +2260,52 @@ void stereo_dft_dec_fx( q_cna_level = sub( Q31, add( q_cna_level, Q16 ) ); /* generate comfort noise from gaussian noise and add to the decoded DFT spectrum */ +#ifdef OPT_STEREO_32KBPS_V1 + Word16 shift = sub( q_cna_level, hStereoDft->q_dft ); +#endif /* OPT_STEREO_32KBPS_V1 */ N1 = L_shl( Mpy_32_16_1( scale_fact, rand_gauss_fix( &ftmp, cna_seed ) ), Q2 ); /* q_cna_level */ N2 = L_shl( Mpy_32_16_1( scale_fact, rand_gauss_fix( &ftmp, cna_seed ) ), Q2 ); /* q_cna_level */ - l_tmp = L_add( Madd_32_16( N1, N1, g ), Mpy_32_16_1( N2, gamma ) ); /* q_cna_level */ - l_tmp = L_shr( l_tmp, sub( q_cna_level, hStereoDft->q_dft ) ); /* q_dft */ - DFT_L[2 * i] = L_add( DFT_L[2 * i], l_tmp ); /* q_dft */ +#ifdef OPT_STEREO_32KBPS_V1 + l_tmp = Madd_32_16( Madd_32_16( N1, N1, g ), N2, gamma ); /* q_cna_level */ + l_tmp = L_shr( l_tmp, shift ); /* q_dft */ +#else /* OPT_STEREO_32KBPS_V1 */ + l_tmp = L_add( Madd_32_16( N1, N1, g ), Mpy_32_16_1( N2, gamma ) ); /* q_cna_level */ + l_tmp = L_shr( l_tmp, sub( q_cna_level, hStereoDft->q_dft ) ); /* q_dft */ +#endif /* OPT_STEREO_32KBPS_V1 */ + DFT_L[2 * i] = L_add( DFT_L[2 * i], l_tmp ); /* q_dft */ move32(); +#ifdef OPT_STEREO_32KBPS_V1 + l_tmp = Msub_32_16( Msub_32_16( N1, N1, g ), N2, gamma ); /* q_cna_level */ + l_tmp = L_shr( l_tmp, shift ); /* q_dft */ + DFT_R[2 * i] = L_add( DFT_R[2 * i], l_tmp ); /* q_dft */ +#else /* OPT_STEREO_32KBPS_V1 */ l_tmp = L_sub( Msub_32_16( N1, N1, g ), Mpy_32_16_1( N2, gamma ) ); /* q_cna_level */ l_tmp = L_shr( l_tmp, sub( q_cna_level, hStereoDft->q_dft ) ); /* q_dft */ DFT_R[2 * i] = L_add( DFT_R[2 * i], l_tmp ); /* q_dft */ +#endif /* OPT_STEREO_32KBPS_V1 */ move32(); N1 = L_shl( Mpy_32_16_1( scale_fact, rand_gauss_fix( &ftmp, cna_seed ) ), Q2 ); /* q_cna_level */ N2 = L_shl( Mpy_32_16_1( scale_fact, rand_gauss_fix( &ftmp, cna_seed ) ), Q2 ); /* q_cna_level */ - l_tmp = L_add( Madd_32_16( N1, N1, g ), Mpy_32_16_1( N2, gamma ) ); /* q_cna_level */ - l_tmp = L_shr( l_tmp, sub( q_cna_level, hStereoDft->q_dft ) ); /* q_dft */ - DFT_L[2 * i + 1] = L_add( DFT_L[2 * i + 1], l_tmp ); /* q_dft */ +#ifdef OPT_STEREO_32KBPS_V1 + l_tmp = Madd_32_16( Madd_32_16( N1, N1, g ), N2, gamma ); /* q_cna_level */ + l_tmp = L_shr( l_tmp, shift ); /* q_dft */ + DFT_L[2 * i + 1] = L_add( DFT_L[2 * i + 1], l_tmp ); /* q_dft */ + move32(); + l_tmp = Msub_32_16( Msub_32_16( N1, N1, g ), N2, gamma ); /* q_cna_level */ + l_tmp = L_shr( l_tmp, shift ); /* q_dft */ + DFT_R[2 * i + 1] = L_add( DFT_R[2 * i + 1], l_tmp ); /* q_dft */ + move32(); +#else /* OPT_STEREO_32KBPS_V1 */ + l_tmp = L_add( Madd_32_16( N1, N1, g ), Mpy_32_16_1( N2, gamma ) ); /* q_cna_level */ + l_tmp = L_shr( l_tmp, sub( q_cna_level, hStereoDft->q_dft ) ); /* q_dft */ + DFT_L[2 * i + 1] = L_add( DFT_L[2 * i + 1], l_tmp ); /* q_dft */ move32(); l_tmp = L_sub( Msub_32_16( N1, N1, g ), Mpy_32_16_1( N2, gamma ) ); /* q_cna_level */ l_tmp = L_shr( l_tmp, sub( q_cna_level, hStereoDft->q_dft ) ); /* q_dft */ DFT_R[2 * i + 1] = L_add( DFT_R[2 * i + 1], l_tmp ); /* q_dft */ move32(); +#endif /* OPT_STEREO_32KBPS_V1 */ } } @@ -2308,8 +2393,12 @@ static void stereo_dft_compute_td_stefi_params_fx( return; } +#ifdef OPT_STEREO_32KBPS_V1 + bin0 = round_fx( L_mult0( hStereoDft->NFFT, samp_ratio ) ); +#else /* OPT_STEREO_32KBPS_V1 */ bin0 = extract_l( L_shr_r( Mpy_32_16_1( (Word32) hStereoDft->NFFT, samp_ratio ), 1 ) ); /* Q0 */ bin0 = shl( bin0, Q3 ); +#endif /* OPT_STEREO_32KBPS_V1 */ bin0 = s_min( bin0, hStereoDft->band_limits[hStereoDft->nbands] ); /* Q0 */ b = hStereoDft->nbands; /* Q0 */ move16(); @@ -2474,14 +2563,18 @@ static void stereo_dft_dequantize_ipd_fx( *-------------------------------------------------------------------------*/ void stereo_dft_generate_res_pred_fx( STEREO_DFT_DEC_DATA_HANDLE hStereoDft, /* i/o: decoder DFT stereo handle */ - const Word16 samp_ratio, /* i : sampling ratio Q13*/ - Word32 *pDFT_DMX, /* i : downmix signal qDFT*/ - Word32 *DFT_PRED_RES, /* o : residual prediction signal qDFT*/ - Word32 *pPredGain, /* i : residual prediction gains Q31*/ - const Word16 k, /* i : subframe index Q0*/ - Word32 *ap_filt_DMX, /* i : enhanced stereo filling signal qDFT*/ - Word16 *stop, /* o : last FD stereo filling bin Q0*/ - const Word16 bfi /* i : BFI flag Q0*/ +#ifdef OPT_STEREO_32KBPS_V1 + const Word16 samp_ratio, /* i : sampling ratio Q15*/ +#else /* OPT_STEREO_32KBPS_V1 */ + const Word16 samp_ratio, /* i : sampling ratio Q13*/ +#endif /* OPT_STEREO_32KBPS_V1 */ + Word32 *pDFT_DMX, /* i : downmix signal qDFT*/ + Word32 *DFT_PRED_RES, /* o : residual prediction signal qDFT*/ + Word32 *pPredGain, /* i : residual prediction gains Q31*/ + const Word16 k, /* i : subframe index Q0*/ + Word32 *ap_filt_DMX, /* i : enhanced stereo filling signal qDFT*/ + Word16 *stop, /* o : last FD stereo filling bin Q0*/ + const Word16 bfi /* i : BFI flag Q0*/ ) { /* general variables */ @@ -2491,7 +2584,10 @@ void stereo_dft_generate_res_pred_fx( Word16 lb_stefi_start_band; /* variables for enhanced stereo filling */ - Word16 norm_fac, q_norm_fac, lim_norm_fac; + Word16 norm_fac, q_norm_fac; +#ifndef OPT_STEREO_32KBPS_V1 + Word16 lim_norm_fac; +#endif /* OPT_STEREO_32KBPS_V1 */ Word16 q_sqrt; Word16 alpha; // gain_limit; @@ -2505,8 +2601,13 @@ void stereo_dft_generate_res_pred_fx( Word32 pred_gain_avg; Word32 g2; Word16 nbands_respred; +#ifdef OPT_STEREO_32KBPS_V1 + Word16 q_new, diff; +#else /* OPT_STEREO_32KBPS_V1 */ q_norm_fac = 0; move16(); +#endif /* OPT_STEREO_32KBPS_V1 */ + Word16 len; push_wmops( "gen_respred" ); /* smoothing and limiting parameters */ @@ -2528,8 +2629,12 @@ void stereo_dft_generate_res_pred_fx( /* In ACELP mode the downmix signal is not available in bandwidth extension area. * * Therefore, the downmix energy in the corresponding subbands is estimated. */ +#ifdef OPT_STEREO_32KBPS_V1 + bin0 = round_fx( L_mult0( hStereoDft->NFFT, samp_ratio ) ); +#else /* OPT_STEREO_32KBPS_V1 */ bin0 = (Word16) ( L_shr( L_add( L_mult0( hStereoDft->NFFT, samp_ratio ), ONE_IN_Q12 ), Q12 + 1 ) ); /* Q0 */ move16(); +#endif /* OPT_STEREO_32KBPS_V1 */ bin0 = s_min( bin0, hStereoDft->band_limits[hStereoDft->nbands] ); /* Q0 */ b = hStereoDft->nbands; move16(); @@ -2571,39 +2676,81 @@ void stereo_dft_generate_res_pred_fx( move64(); /* calculate band energies (low band only in case of ACELP) */ - FOR( i = hStereoDft->band_limits[b]; i < min( hStereoDft->band_limits[b + 1], bin0 ); i++ ) + len = s_min( hStereoDft->band_limits[b + 1], bin0 ); + FOR( i = hStereoDft->band_limits[b]; i < len; i++ ) { +#ifdef OPT_STEREO_32KBPS_V1 + dmx_nrg_64bit = W_mac_32_32( W_mac_32_32( dmx_nrg_64bit, pDFT_DMX[2 * i], pDFT_DMX[2 * i] ), + pDFT_DMX[2 * i + 1], pDFT_DMX[2 * i + 1] ); /* 2 * q_dft + 1 */ + rev_nrg_64bit = W_mac_32_32( W_mac_32_32( rev_nrg_64bit, ap_filt_DMX[2 * i], ap_filt_DMX[2 * i] ), + ap_filt_DMX[2 * i + 1], ap_filt_DMX[2 * i + 1] ); /* 2 * q_dft + 1 */ +#else /* OPT_STEREO_32KBPS_V1 */ dmx_nrg_64bit = W_add( dmx_nrg_64bit, W_add( W_mult0_32_32( pDFT_DMX[2 * i], pDFT_DMX[2 * i] ), W_mult0_32_32( pDFT_DMX[2 * i + 1], pDFT_DMX[2 * i + 1] ) ) ); /* 2 * q_dft */ rev_nrg_64bit = W_add( rev_nrg_64bit, W_add( W_mult0_32_32( ap_filt_DMX[2 * i], ap_filt_DMX[2 * i] ), W_mult0_32_32( ap_filt_DMX[2 * i + 1], ap_filt_DMX[2 * i + 1] ) ) ); /* 2 * q_dft */ +#endif /* OPT_STEREO_32KBPS_V1 */ } + +#ifdef OPT_STEREO_32KBPS_V1 + q_new = add( shl( hStereoDft->q_dft, 1 ), 1 ); + q_shift = W_norm( dmx_nrg_64bit ); + dmx_nrg = W_shl_sat_l( dmx_nrg_64bit, sub( q_shift, 32 ) ); // 2 * hStereoDft->q_dft + 1 - (q_shift - 32) + dmx_nrg_q = add( q_new, sub( q_shift, 32 ) ); + q_shift = W_norm( rev_nrg_64bit ); + rev_nrg = W_shl_sat_l( rev_nrg_64bit, sub( q_shift, 32 ) ); // 2 * hStereoDft->q_dft + 1 - (q_shift - 32) + rev_nrg_q = add( q_new, sub( q_shift, 32 ) ); + move16(); +#else /* OPT_STEREO_32KBPS_V1 */ q_shift = W_norm( dmx_nrg_64bit ); dmx_nrg = W_extract_l( W_shl( dmx_nrg_64bit, sub( q_shift, 32 ) ) ); // 2 * hStereoDft->q_dft + (q_shift - 32) dmx_nrg_q = add( imult1616( 2, hStereoDft->q_dft ), sub( q_shift, 32 ) ); q_shift = W_norm( rev_nrg_64bit ); rev_nrg = W_extract_l( W_shl( rev_nrg_64bit, sub( q_shift, 32 ) ) ); // 2 * hStereoDft->q_dft + (q_shift - 32) rev_nrg_q = add( imult1616( 2, hStereoDft->q_dft ), sub( q_shift, 32 ) ); +#endif /* OPT_STEREO_32KBPS_V1 */ /* Reach a common Q for dmx_nrg and rev_nrg */ q_com = s_min( dmx_nrg_q, rev_nrg_q ); dmx_nrg = L_shl( dmx_nrg, sub( q_com, dmx_nrg_q ) ); /* q_com */ rev_nrg = L_shl( rev_nrg, sub( q_com, rev_nrg_q ) ); /* q_com */ + +#ifdef OPT_STEREO_32KBPS_V1 + diff = sub( hStereoDft->q_smoothed_nrg, q_com ); + IF( diff < 0 ) +#else /* OPT_STEREO_32KBPS_V1 */ IF( LT_16( hStereoDft->q_smoothed_nrg, q_com ) ) +#endif /* OPT_STEREO_32KBPS_V1 */ { +#ifdef OPT_STEREO_32KBPS_V1 + rev_nrg = L_shl( rev_nrg, shl( diff, 1 ) ); + dmx_nrg = L_shl( dmx_nrg, shl( diff, 1 ) ); +#else /* OPT_STEREO_32KBPS_V1 */ rev_nrg = L_shr( rev_nrg, shl( sub( q_com, hStereoDft->q_smoothed_nrg ), 1 ) ); dmx_nrg = L_shr( dmx_nrg, shl( sub( q_com, hStereoDft->q_smoothed_nrg ), 1 ) ); +#endif /* OPT_STEREO_32KBPS_V1 */ q_com = hStereoDft->q_smoothed_nrg; move16(); } +#ifdef OPT_STEREO_32KBPS_V1 + ELSE +#else /* OPT_STEREO_32KBPS_V1 */ ELSE IF( GT_16( hStereoDft->q_smoothed_nrg, q_com ) ) +#endif /* OPT_STEREO_32KBPS_V1 */ { +#ifdef OPT_STEREO_32KBPS_V1 + hStereoDft->smooth_res_nrg_fx[b] = L_shr( hStereoDft->smooth_res_nrg_fx[b], shl( diff, 1 ) ); /* hStereoDft->q_smoothed_nrg */ + move32(); + hStereoDft->smooth_dmx_nrg_fx[b] = L_shr( hStereoDft->smooth_dmx_nrg_fx[b], shl( diff, 1 ) ); /* hStereoDft->q_smoothed_nrg */ + move32(); +#else /* OPT_STEREO_32KBPS_V1 */ hStereoDft->smooth_res_nrg_fx[b] = L_shr( hStereoDft->smooth_res_nrg_fx[b], shl( sub( hStereoDft->q_smoothed_nrg, q_com ), 1 ) ); /* hStereoDft->q_smoothed_nrg */ move32(); hStereoDft->smooth_dmx_nrg_fx[b] = L_shr( hStereoDft->smooth_dmx_nrg_fx[b], shl( sub( hStereoDft->q_smoothed_nrg, q_com ), 1 ) ); /* hStereoDft->q_smoothed_nrg */ move32(); +#endif /* OPT_STEREO_32KBPS_V1 */ q_smoothed_nrg_local[b] = q_com; move16(); } @@ -2613,9 +2760,38 @@ void stereo_dft_generate_res_pred_fx( hStereoDft->smooth_dmx_nrg_fx[b] = Madd_32_16( Mpy_32_16_1( hStereoDft->smooth_dmx_nrg_fx[b], alpha ), dmx_nrg, sub( (Word16) ( 0x7FFF ), alpha ) ); /* hStereoDft->q_smoothed_nrg */ move32(); +#ifdef OPT_STEREO_32KBPS_V1 + // Compute norm_fac in Q14 + norm_fac = MAX_16; + move16(); +#endif /* OPT_STEREO_32KBPS_V1 */ /* normalization factor */ IF( hStereoDft->smooth_res_nrg_fx[b] != 0 ) { +#ifdef OPT_STEREO_32KBPS_V1 + norm_fac = 0; + move16(); + IF( hStereoDft->smooth_dmx_nrg_fx[b] != 0 ) + { + Word16 quo, quo_e; + Word32 prod; + + norm_fac = BASOP_Util_Divide3232_Scale( hStereoDft->smooth_dmx_nrg_fx[b], hStereoDft->smooth_res_nrg_fx[b], &q_norm_fac ); /* q_norm_fac */ + norm_fac = Sqrt16( norm_fac, &q_norm_fac ); + + quo = BASOP_Util_Divide1616_Scale( 32767, norm_fac, &quo_e ); /* q_norm_fac */ + quo_e = sub( quo_e, q_norm_fac ); + quo = shl_sat( quo, sub( quo_e, 1 ) ); // Q14 + quo = s_max( 13107 /*0.8 in Q14 */, quo ); + quo = s_min( quo, 20480 /* 1.25 in Q14*/ ); + + prod = L_mult( norm_fac, quo ); // exp:q_norm_fac+1 + // Bring to Q30 + prod = L_shl_sat( prod, q_norm_fac ); + + norm_fac = extract_h( prod ); + } +#else /* OPT_STEREO_32KBPS_V1 */ norm_fac = BASOP_Util_Divide3232_Scale( hStereoDft->smooth_dmx_nrg_fx[b], hStereoDft->smooth_res_nrg_fx[b], &q_norm_fac ); /* q_norm_fac */ norm_fac = Sqrt16( norm_fac, &q_norm_fac ); IF( norm_fac != 0 ) @@ -2671,7 +2847,9 @@ void stereo_dft_generate_res_pred_fx( } } } +#endif /* OPT_STEREO_32KBPS_V1 */ } +#ifndef OPT_STEREO_32KBPS_V1 ELSE { norm_fac = MAX_16; @@ -2679,13 +2857,22 @@ void stereo_dft_generate_res_pred_fx( q_norm_fac = Q1; move16(); } +#endif /* OPT_STEREO_32KBPS_V1 */ - FOR( i = hStereoDft->band_limits[b]; i < min( hStereoDft->band_limits[b + 1], bin0 ); i++ ) + len = s_min( hStereoDft->band_limits[b + 1], bin0 ); + FOR( i = hStereoDft->band_limits[b]; i < len; i++ ) { +#ifdef OPT_STEREO_32KBPS_V1 + DFT_PRED_RES[2 * i] = L_shl( Mpy_32_32( Mpy_32_16_1( pPredGain[b], norm_fac ), ap_filt_DMX[2 * i] ), 1 ); /* q_dft */ + move32(); + DFT_PRED_RES[2 * i + 1] = L_shl( Mpy_32_32( Mpy_32_16_1( pPredGain[b], norm_fac ), ap_filt_DMX[2 * i + 1] ), 1 ); /* q_dft */ + move32(); +#else /* OPT_STEREO_32KBPS_V1 */ DFT_PRED_RES[2 * i] = L_shl( Mpy_32_32( Mpy_32_16_1( pPredGain[b], norm_fac ), ap_filt_DMX[2 * i] ), q_norm_fac ); /* q_dft */ move32(); DFT_PRED_RES[2 * i + 1] = L_shl( Mpy_32_32( Mpy_32_16_1( pPredGain[b], norm_fac ), ap_filt_DMX[2 * i + 1] ), q_norm_fac ); /* q_dft */ move32(); +#endif /* OPT_STEREO_32KBPS_V1 */ } } @@ -2795,7 +2982,8 @@ void stereo_dft_generate_res_pred_fx( move32(); dmx_nrg = EPSILON_FIX; move32(); - FOR( i = hStereoDft->band_limits[b]; i < min( bin0, hStereoDft->band_limits[b + 1] ); i++ ) + len = s_min( bin0, hStereoDft->band_limits[b + 1] ); + FOR( i = hStereoDft->band_limits[b]; i < len; i++ ) { dmx_nrg = Madd_32_32( Madd_32_32( dmx_nrg, pDFT_DMX[2 * i], pDFT_DMX[2 * i] ), pDFT_DMX[2 * i + 1], pDFT_DMX[2 * i + 1] ); /* 2 * q_dft - 31 */ @@ -2836,8 +3024,8 @@ void stereo_dft_generate_res_pred_fx( q_sqrt = 0; move16(); } - - FOR( i = hStereoDft->band_limits[b]; i < min( bin0, hStereoDft->band_limits[b + 1] ); i++ ) + len = s_min( bin0, hStereoDft->band_limits[b + 1] ); + FOR( i = hStereoDft->band_limits[b]; i < len; i++ ) { DFT_PRED_RES[2 * i] = L_shl( Mpy_32_32( g2, DFT_PRED_RES[2 * i] ), q_sqrt ); /* q_dft */ move32(); @@ -2894,7 +3082,8 @@ void stereo_dft_generate_res_pred_fx( // past_dmx_nrg = EPSILON_FIX; past_dmx_nrg = 0; move32(); - FOR( i = bin0; i < min( ( hStereoDft->NFFT / 2 ), ( STEREO_DFT32MS_N_32k / 2 ) ); i++ ) + len = s_min( shr( hStereoDft->NFFT, 1 ), ( STEREO_DFT32MS_N_32k >> 1 ) ); + FOR( i = bin0; i < len; i++ ) // i < min( ( hStereoDft->NFFT / 2 ), ( hStereoDft->NFFT / 2 ) ) { past_dmx_nrg = L_add( past_dmx_nrg, Madd_32_32( Mpy_32_32( hStereoDft->DFT_past_DMX_fx[d_short_ind][2 * i], hStereoDft->DFT_past_DMX_fx[d_short_ind][2 * i] ), hStereoDft->DFT_past_DMX_fx[d_short_ind][2 * i + 1], hStereoDft->DFT_past_DMX_fx[d_short_ind][2 * i + 1] ) ); /* 2 * hStereoDft->q_DFT_past_DMX_fx[d_short_ind] - 31 */ } @@ -2955,7 +3144,8 @@ void stereo_dft_generate_res_pred_fx( } q_shift = sub( hStereoDft->q_dft, hStereoDft->q_DFT_past_DMX_fx[d_short_ind] ); move16(); - FOR( i = max( hStereoDft->band_limits[b], bin0 ); i < min( hStereoDft->band_limits[b + 1], STEREO_DFT32MS_N_32k / 2 ); i++ ) + len = s_min( hStereoDft->band_limits[b + 1], STEREO_DFT32MS_N_32k >> 1 ); + FOR( i = s_max( hStereoDft->band_limits[b], bin0 ); i < len; i++ ) // i < min( hStereoDft->band_limits[b + 1], STEREO_DFT32MS_N_32k / 2 ) { DFT_PRED_RES[2 * i] = L_shl( Mpy_32_32( g2, hStereoDft->DFT_past_DMX_fx[d_short_ind][2 * i] ), q_shift ); /* q_dft */ move32(); @@ -3069,7 +3259,8 @@ void stereo_dft_generate_res_pred_fx( move32(); dmx_nrg = EPSILON_FIX; move32(); - FOR( i = max( hStereoDft->band_limits[b], bin0 ); i < min( hStereoDft->band_limits[b + 1], STEREO_DFT32MS_N_32k / 2 ); i++ ) + len = s_min( hStereoDft->band_limits[b + 1], STEREO_DFT32MS_N_32k >> 1 ); + FOR( i = s_max( hStereoDft->band_limits[b], bin0 ); i < len; i++ ) // i < min( hStereoDft->band_limits[b + 1], STEREO_DFT32MS_N_32k / 2 ) { dmx_nrg = L_add( dmx_nrg, L_shr( Madd_32_32( Mpy_32_32( pDFT_DMX[2 * i], pDFT_DMX[2 * i] ), pDFT_DMX[2 * i + 1], pDFT_DMX[2 * i + 1] ), 1 ) ); /* 2 * q_dft - 31 - 1 */ @@ -3095,8 +3286,8 @@ void stereo_dft_generate_res_pred_fx( g2 = L_min( Mpy_32_16_1( pred_gain_avg, STEREO_DFT_STEFFI_GAIN_AMP_FX ), Madd_32_16( Mpy_32_16_1( pred_gain_avg, sub( (Word16) ( 0x7FFF ), STEREO_DFT_STEFFI_GAIN_REST_AMT_FX ) ), g2, STEREO_DFT_STEFFI_GAIN_REST_AMT_FX ) ); /* Q31 */ - - FOR( i = max( hStereoDft->band_limits[b], bin0 ); i < min( hStereoDft->band_limits[b + 1], STEREO_DFT32MS_N_32k / 2 ); i++ ) + len = s_min( hStereoDft->band_limits[b + 1], STEREO_DFT32MS_N_32k >> 1 ); + FOR( i = s_max( hStereoDft->band_limits[b], bin0 ); i < len; i++ ) // i < min( hStereoDft->band_limits[b + 1], STEREO_DFT32MS_N_32k / 2 ) { DFT_PRED_RES[2 * i] = Mpy_32_32( g2, DFT_PRED_RES[2 * i] ); /* Q31 */ move32(); diff --git a/lib_dec/ivas_stereo_dft_plc.c b/lib_dec/ivas_stereo_dft_plc.c deleted file mode 100644 index 3988b275ab72e96c190c47bfb82a17d72f87812a..0000000000000000000000000000000000000000 --- a/lib_dec/ivas_stereo_dft_plc.c +++ /dev/null @@ -1,40 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -#include -#include "options.h" -#include "cnst.h" -#include "prot.h" -#include "ivas_cnst.h" -#include "ivas_prot.h" -#include "math.h" -#include "wmc_auto.h" diff --git a/lib_dec/ivas_stereo_dft_plc_fx.c b/lib_dec/ivas_stereo_dft_plc_fx.c index ded3b48f450be00dc719a5359a488c15a96afc74..90d9c58235bda9d978657307b0547a9e1c8abda4 100644 --- a/lib_dec/ivas_stereo_dft_plc_fx.c +++ b/lib_dec/ivas_stereo_dft_plc_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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,8 @@ #include #include "options.h" #include "cnst.h" -#include "prot.h" #include "prot_fx.h" #include "ivas_cnst.h" -#include "ivas_prot.h" #include "ivas_prot_fx.h" #include "math.h" #include "wmc_auto.h" diff --git a/lib_dec/ivas_stereo_eclvq_dec.c b/lib_dec/ivas_stereo_eclvq_dec_fx.c similarity index 98% rename from lib_dec/ivas_stereo_eclvq_dec.c rename to lib_dec/ivas_stereo_eclvq_dec_fx.c index c74649d9087f7beef67e4203ea79cb1718302929..dfa411145fc3ce2930203029047d821a1d37e45d 100644 --- a/lib_dec/ivas_stereo_eclvq_dec.c +++ b/lib_dec/ivas_stereo_eclvq_dec_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other @@ -32,12 +32,11 @@ #include #include "options.h" -#include "ivas_prot.h" #include "ivas_cnst.h" #include "ivas_rom_com.h" #include "ivas_rom_dec.h" #include -#include "prot.h" +#include "prot_fx.h" #include "wmc_auto.h" #include "ivas_prot_fx.h" diff --git a/lib_dec/ivas_stereo_esf_dec.c b/lib_dec/ivas_stereo_esf_dec_fx.c similarity index 98% rename from lib_dec/ivas_stereo_esf_dec.c rename to lib_dec/ivas_stereo_esf_dec_fx.c index e5252804402b411549f6169046b1b81851da3179..d4219f1e60464e7dbaf87c7effb4c814e18bc0ae 100644 --- a/lib_dec/ivas_stereo_esf_dec.c +++ b/lib_dec/ivas_stereo_esf_dec_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other @@ -32,7 +32,6 @@ #include #include "options.h" -#include "ivas_prot.h" #include "ivas_prot_fx.h" #include "ivas_stat_dec.h" #include "ivas_cnst.h" diff --git a/lib_dec/ivas_stereo_ica_dec.c b/lib_dec/ivas_stereo_ica_dec_fx.c similarity index 97% rename from lib_dec/ivas_stereo_ica_dec.c rename to lib_dec/ivas_stereo_ica_dec_fx.c index a28afdad9386436838774d62669350813caf43a0..694aad0b4a921922562c30f727dfa570e52d3dc2 100644 --- a/lib_dec/ivas_stereo_ica_dec.c +++ b/lib_dec/ivas_stereo_ica_dec_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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,12 +36,10 @@ #include #include "cnst.h" #include "ivas_cnst.h" -#include "prot.h" -#include "ivas_prot.h" +#include "prot_fx.h" #include "wmc_auto.h" #include "rom_com.h" #include "ivas_rom_com.h" -#include "prot_fx.h" #include "ivas_prot_fx.h" #include "basop32.h" #include "ivas_stat_dec.h" @@ -126,7 +124,7 @@ void stereo_tca_dec_fx( dsFactor = BASOP_Util_Divide3232_Scale( output_Fs, 8000, &exp_ds ); dsFactor = shr( dsFactor, sub( 15, exp_ds ) ); /* Q0 */ - tempMax = NS2SA( output_Fs, L_NCSHIFT_NS ); /* Q0 */ + tempMax = NS2SA_FX2( output_Fs, L_NCSHIFT_NS ); /* Q0 */ hStereoTCA->corrLagStats = s_min( hStereoTCA->indx_ica_NCShift * dsFactor, tempMax ); /* Q0 */ bothChannelShift = 0; @@ -343,14 +341,14 @@ void stereo_tca_scale_R_channel_fx( return; } /* Scale the Right channel with the gain */ - l_ica_ovl = NS2SA( output_Fs, STEREO_L_TCA_OVLP_NS ); /* Q0 */ + l_ica_ovl = NS2SA_FX2( output_Fs, STEREO_L_TCA_OVLP_NS ); /* Q0 */ move16(); test(); IF( EQ_16( hCPE->nchan_out, 1 ) ) { /* in mono DMX, the scaling is done before synchro_synthesis() */ - flat_old = NS2SA( output_Fs, ACELP_LOOK_NS + IVAS_DEC_DELAY_NS - DELAY_CLDFB_NS ); /* Q0 */ + flat_old = NS2SA_FX2( output_Fs, ACELP_LOOK_NS + IVAS_DEC_DELAY_NS - DELAY_CLDFB_NS ); /* Q0 */ move16(); test(); @@ -365,18 +363,18 @@ void stereo_tca_scale_R_channel_fx( hCPE->hStereoDftDmx->targetGain_fx = ONE_IN_Q29; /* Q29 */ move32(); - flat_old = NS2SA( output_Fs, IVAS_DEC_DELAY_NS ); /* Q0 */ + flat_old = NS2SA_FX2( output_Fs, IVAS_DEC_DELAY_NS ); /* Q0 */ move16(); } } ELSE IF( EQ_16( hCPE->last_element_mode, IVAS_CPE_TD ) && EQ_16( hCPE->element_mode, IVAS_CPE_DFT ) ) { - flat_old = NS2SA( output_Fs, IVAS_DEC_DELAY_NS ); /* Q0 */ + flat_old = NS2SA_FX2( output_Fs, IVAS_DEC_DELAY_NS ); /* Q0 */ move16(); } ELSE { - flat_old = NS2SA( output_Fs, ACELP_LOOK_NS + IVAS_DEC_DELAY_NS ); /* Q0 */ + flat_old = NS2SA_FX2( output_Fs, ACELP_LOOK_NS + IVAS_DEC_DELAY_NS ); /* Q0 */ move16(); } diff --git a/lib_dec/ivas_stereo_icbwe_dec.c b/lib_dec/ivas_stereo_icbwe_dec_fx.c similarity index 98% rename from lib_dec/ivas_stereo_icbwe_dec.c rename to lib_dec/ivas_stereo_icbwe_dec_fx.c index 8b8887c9c09a44a09b6fc11ceeab4c190811c18e..3b32072f300c229e5c36211909bff0bb84024d22 100644 --- a/lib_dec/ivas_stereo_icbwe_dec.c +++ b/lib_dec/ivas_stereo_icbwe_dec_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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,9 +36,7 @@ #include #include "cnst.h" #include "ivas_cnst.h" -#include "prot.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "ivas_prot_fx.h" #include "wmc_auto.h" #include "rom_com.h" @@ -339,7 +337,7 @@ void stereo_icBWE_dec_fx( move32(); alpha_fx = add_sat( alpha_fx, winSlope_fx ); /* Q15 */ } - FOR( ; i < NS2SA( st->output_Fs, FRAME_SIZE_NS ); i++ ) + FOR( ; i < NS2SA_FX2( st->output_Fs, FRAME_SIZE_NS ); i++ ) { synthRef_fx[i] = Mpy_32_16_1( synthRef_fx[i], icbweM2Ref_fx ); // Qsyth - 1 move32(); @@ -766,7 +764,7 @@ void stereo_icBWE_dec_fx( alpha_fx = add( alpha_fx, winSlope_fx ); /* Q15 */ } } - FOR( ; i < NS2SA( st->output_Fs, FRAME_SIZE_NS ); i++ ) + FOR( ; i < NS2SA_FX2( st->output_Fs, FRAME_SIZE_NS ); i++ ) { synthRef_fx[i] = Mpy_32_16_1( synthRef_fx[i], icbweM2Ref_fx ); /* Qsyn - 1 */ move32(); @@ -933,7 +931,7 @@ void stereo_icBWE_dec_fx( } } - FOR( ; i < NS2SA( st->output_Fs, FRAME_SIZE_NS ); i++ ) + FOR( ; i < NS2SA_FX2( st->output_Fs, FRAME_SIZE_NS ); i++ ) { synthRef_fx[i] = Mpy_32_16_1( synthRef_fx[i], icbweM2Ref_fx ); /* Qsyn - 1 */ move32(); @@ -1015,7 +1013,7 @@ void stereo_icBWE_decproc_fx( output_Fs = hCPE->hCoreCoder[0]->output_Fs; /* Q0 */ move32(); - memOffset = NS2SA( output_Fs, IVAS_DEC_DELAY_NS - DELAY_BWE_TOTAL_NS ); /* Q0 */ + memOffset = NS2SA_FX2( output_Fs, IVAS_DEC_DELAY_NS - DELAY_BWE_TOTAL_NS ); /* Q0 */ /* LRTD stereo mode - 2xBWEs used */ test(); @@ -1070,8 +1068,8 @@ void stereo_icBWE_decproc_fx( set32_fx( hStereoICBWE->memOutHB_fx[0], 0, memOffset ); set32_fx( hStereoICBWE->memOutHB_fx[1], 0, memOffset ); - set32_fx( hStereoICBWE->memTransitionHB_fx[0], 0, NS2SA( output_Fs, STEREO_DFT32MS_OVL_NS ) ); - set32_fx( hStereoICBWE->memTransitionHB_fx[1], 0, NS2SA( output_Fs, STEREO_DFT32MS_OVL_NS ) ); + set32_fx( hStereoICBWE->memTransitionHB_fx[0], 0, NS2SA_FX2( output_Fs, STEREO_DFT32MS_OVL_NS ) ); + set32_fx( hStereoICBWE->memTransitionHB_fx[1], 0, NS2SA_FX2( output_Fs, STEREO_DFT32MS_OVL_NS ) ); } test(); @@ -1123,13 +1121,13 @@ void stereo_icBWE_decproc_fx( Copy32( outputHB[refChanIndx_bwe], temp0_fx + memOffset, sub( output_frame, memOffset ) ); /* Q11 */ Copy32( outputHB[!refChanIndx_bwe], temp1_fx + memOffset, sub( output_frame, memOffset ) ); /* Q11 */ - decoderDelay = NS2SA( output_Fs, IVAS_DEC_DELAY_NS ); /* Q0 */ + decoderDelay = NS2SA_FX2( output_Fs, IVAS_DEC_DELAY_NS ); /* Q0 */ test(); IF( last_core != ACELP_CORE && EQ_16( hCPE->element_mode, IVAS_CPE_DFT ) ) { /* hb_synth of mid band is faded out in the 1.25 ms prior to DFT analysis and the icbwe is faded in time domain */ - icbweOLASize = NS2SA( output_Fs, STEREO_DFT_DELAY_DEC_BWE_NS ); /* Q0 */ + icbweOLASize = NS2SA_FX2( output_Fs, STEREO_DFT_DELAY_DEC_BWE_NS ); /* Q0 */ FOR( i = 0; i < decoderDelay; i++ ) { @@ -1286,15 +1284,15 @@ void stereo_icBWE_decproc_fx( ELSE { /* This is generated in the ACELP frame and windowed. This process is akin to GenTransition for IC-BWE */ - v_add_32( output[0], hStereoICBWE->memTransitionHB_fx[hStereoICBWE->prev_refChanIndx_bwe], output[0], NS2SA( output_Fs, STEREO_DFT32MS_OVL_NS ) ); - v_add_32( output[1], hStereoICBWE->memTransitionHB_fx[!hStereoICBWE->prev_refChanIndx_bwe], output[1], NS2SA( output_Fs, STEREO_DFT32MS_OVL_NS ) ); + v_add_32( output[0], hStereoICBWE->memTransitionHB_fx[hStereoICBWE->prev_refChanIndx_bwe], output[0], NS2SA_FX2( output_Fs, STEREO_DFT32MS_OVL_NS ) ); + v_add_32( output[1], hStereoICBWE->memTransitionHB_fx[!hStereoICBWE->prev_refChanIndx_bwe], output[1], NS2SA_FX2( output_Fs, STEREO_DFT32MS_OVL_NS ) ); } set32_fx( hStereoICBWE->memOutHB_fx[0], 0, memOffset ); set32_fx( hStereoICBWE->memOutHB_fx[1], 0, memOffset ); - set32_fx( hStereoICBWE->memTransitionHB_fx[0], 0, NS2SA( output_Fs, STEREO_DFT32MS_OVL_NS ) ); - set32_fx( hStereoICBWE->memTransitionHB_fx[1], 0, NS2SA( output_Fs, STEREO_DFT32MS_OVL_NS ) ); + set32_fx( hStereoICBWE->memTransitionHB_fx[0], 0, NS2SA_FX2( output_Fs, STEREO_DFT32MS_OVL_NS ) ); + set32_fx( hStereoICBWE->memTransitionHB_fx[1], 0, NS2SA_FX2( output_Fs, STEREO_DFT32MS_OVL_NS ) ); } } } @@ -1304,13 +1302,13 @@ void stereo_icBWE_decproc_fx( } ELSE IF( EQ_16( hCPE->element_mode, IVAS_CPE_MDCT ) && EQ_16( hCPE->last_element_mode, IVAS_CPE_DFT ) && EQ_16( last_core, ACELP_CORE ) ) { - Word16 delay_tdbwe = NS2SA( output_Fs, DELAY_BWE_TOTAL_NS ); + Word16 delay_tdbwe = NS2SA_FX2( output_Fs, DELAY_BWE_TOTAL_NS ); FOR( n = 0; n < hCPE->nchan_out; n++ ) { FOR( i = 0; i < delay_tdbwe; i++ ) { - output[n][NS2SA( output_Fs, STEREO_DFT32MS_OVL_NS ) - delay_tdbwe + i] = L_add_sat( output[n][NS2SA( output_Fs, STEREO_DFT32MS_OVL_NS ) - delay_tdbwe + i], outputHB[0][i] ); + output[n][NS2SA_FX2( output_Fs, STEREO_DFT32MS_OVL_NS ) - delay_tdbwe + i] = L_add_sat( output[n][NS2SA_FX2( output_Fs, STEREO_DFT32MS_OVL_NS ) - delay_tdbwe + i], outputHB[0][i] ); move32(); } } diff --git a/lib_dec/ivas_stereo_mdct_core_dec.c b/lib_dec/ivas_stereo_mdct_core_dec.c deleted file mode 100644 index 233dcc22521cad85b355f588b8bd4c85411feefd..0000000000000000000000000000000000000000 --- a/lib_dec/ivas_stereo_mdct_core_dec.c +++ /dev/null @@ -1,42 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -#include -#include -#include "options.h" -#include -#include "prot.h" -#include "cnst.h" -#include "stat_com.h" -#include "ivas_prot.h" -#include "ivas_stat_dec.h" -#include "wmc_auto.h" diff --git a/lib_dec/ivas_stereo_mdct_core_dec_fx.c b/lib_dec/ivas_stereo_mdct_core_dec_fx.c index 79b88b88c159b8abd89d124905291c75ed722512..a6b350d3301a38c47499587c69b988d1fa1b3abf 100644 --- a/lib_dec/ivas_stereo_mdct_core_dec_fx.c +++ b/lib_dec/ivas_stereo_mdct_core_dec_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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,13 +34,11 @@ #include #include "options.h" #include -#include "prot.h" +#include "prot_fx.h" #include "cnst.h" #include "stat_com.h" -#include "ivas_prot.h" #include "ivas_stat_dec.h" #include "wmc_auto.h" -#include "prot_fx.h" #include "ivas_prot_fx.h" @@ -403,7 +401,7 @@ void stereo_mdct_core_dec_fx( FOR( ch = 0; ch < CPE_CHANNELS; ch++ ) { - Copy_Scale_sig_16_32( Aq_fx[ch], Aq_fx_32[ch], ( NB_SUBFR16k + 1 ) * ( M + 1 ), sub( Q16, Q12 ) ); /* Q16 */ + Copy_Scale_sig_16_32_DEPREC( Aq_fx[ch], Aq_fx_32[ch], ( NB_SUBFR16k + 1 ) * ( M + 1 ), sub( Q16, Q12 ) ); /* Q16 */ } /*--------------------------------------------------------------------------------* @@ -542,10 +540,13 @@ void stereo_mdct_core_dec_fx( move16(); } } - - Copy_Scale_sig_16_32( hCPE->hCoreCoder[0]->old_Aq_12_8_fx, hCPE->hCoreCoder[0]->old_Aq_12_8_fx_32, M + 1, ( 28 - norm_s( hCPE->hCoreCoder[0]->old_Aq_12_8_fx[0] - 1 ) ) ); /* Q28 */ - Copy_Scale_sig_16_32( hCPE->hCoreCoder[1]->old_Aq_12_8_fx, hCPE->hCoreCoder[1]->old_Aq_12_8_fx_32, M + 1, ( 28 - norm_s( hCPE->hCoreCoder[1]->old_Aq_12_8_fx[0] - 1 ) ) ); /* Q28 */ - +#ifdef FIX_ISSUE_1237 + Copy_Scale_sig_16_32_no_sat( hCPE->hCoreCoder[0]->old_Aq_12_8_fx, hCPE->hCoreCoder[0]->old_Aq_12_8_fx_32, M + 1, sub( 28, sub( 15, norm_s( sub( hCPE->hCoreCoder[0]->old_Aq_12_8_fx[0], 1 ) ) ) ) ); /* Q28 */ + Copy_Scale_sig_16_32_no_sat( hCPE->hCoreCoder[1]->old_Aq_12_8_fx, hCPE->hCoreCoder[1]->old_Aq_12_8_fx_32, M + 1, sub( 28, sub( 15, norm_s( sub( hCPE->hCoreCoder[1]->old_Aq_12_8_fx[0], 1 ) ) ) ) ); /* Q28 */ +#else + Copy_Scale_sig_16_32_DEPREC( hCPE->hCoreCoder[0]->old_Aq_12_8_fx, hCPE->hCoreCoder[0]->old_Aq_12_8_fx_32, M + 1, ( 28 - norm_s( hCPE->hCoreCoder[0]->old_Aq_12_8_fx[0] - 1 ) ) ); /* Q28 */ + Copy_Scale_sig_16_32_DEPREC( hCPE->hCoreCoder[1]->old_Aq_12_8_fx, hCPE->hCoreCoder[1]->old_Aq_12_8_fx_32, M + 1, ( 28 - norm_s( hCPE->hCoreCoder[1]->old_Aq_12_8_fx[0] - 1 ) ) ); /* Q28 */ +#endif ivas_mdct_core_reconstruct_fx( hCPE, x_fx, signal_outFB_tmp_fx, fUseTns, 0, Q11, e_sigFB ); Copy32( signal_out_tmp_fx[0], signal_out_fx[0], L_FRAME48k ); /* Q11 */ @@ -987,7 +988,7 @@ static void run_min_stats_fx( { Word16 ch, will_estimate_noise_on_channel[CPE_CHANNELS], save_VAD[CPE_CHANNELS]; Word32 power_spec[L_FRAME16k]; - Word16 power_spec_e = 0; + Word16 power_spec_q = 0; move16(); Word32 *spec_in; Word16 spec_e; @@ -1043,25 +1044,27 @@ static void run_min_stats_fx( IF( ( EQ_16( will_estimate_noise_on_channel[0], will_estimate_noise_on_channel[1] ) ) || EQ_16( ch, 0 ) ) { Word16 tmp16 = getScaleFactor32( spec_in, L_FRAME16k ); - + Word64 spec_power; Word32 power_spec_scale_fac; /* calculate power spectrum from MDCT coefficients and estimated MDST coeffs */ power_spec_scale_fac = 20792; // 1.f / ( L_FRAME16k * L_FRAME16k ) in Q31 move32(); - power_spec[0] = Mpy_32_32( W_extract_h( W_shl( W_mult_32_32( spec_in[0], spec_in[0] ), sub( tmp16, 4 ) ) ), power_spec_scale_fac ); /* 2 * (Q31 - x_e) + tmp16 - Q4 - Q31 */ + spec_power = W_shl( W_mult_32_32( spec_in[0], spec_in[0] ), shl( tmp16, 1 ) ); + power_spec[0] = W_extract_l( W_shr( W_mult_32_32( W_extract_h( spec_power ), power_spec_scale_fac ), 16 ) ); /* 2 * (Q31 - x_e + tmp16) + 1 - Q16 */ move32(); - power_spec[L_FRAME16k - 1] = Mpy_32_32( W_extract_h( W_shl( W_mult_32_32( spec_in[L_FRAME16k - 1], spec_in[L_FRAME16k - 1] ), sub( tmp16, 4 ) ) ), power_spec_scale_fac ); /* 2 * (Q31 - x_e) + tmp16 - Q4 - Q31 */ + spec_power = W_shl( W_mult_32_32( spec_in[L_FRAME16k - 1], spec_in[L_FRAME16k - 1] ), shl( tmp16, 1 ) ); + power_spec[L_FRAME16k - 1] = W_extract_l( W_shr( W_mult_32_32( W_extract_h( spec_power ), power_spec_scale_fac ), 16 ) ); /* 2 * (Q31 - x_e + tmp16) + 1 - Q16 */ move32(); FOR( Word16 i = 1; i < L_FRAME16k - 1; i++ ) { Word32 mdst; mdst = L_sub( spec_in[i + 1], spec_in[i - 1] ); /* Q31 - x_e */ - - power_spec[i] = Mpy_32_32( L_add( W_extract_h( W_shl( W_mult_32_32( spec_in[i], spec_in[i] ), sub( tmp16, 4 ) ) ), W_extract_h( W_shl( W_mult_32_32( mdst, mdst ), sub( tmp16, 4 ) ) ) ), power_spec_scale_fac ); /* 2 * (Q31 - x_e) + tmp16 - Q4 - Q31*/ + spec_power = W_shl( W_add( W_mult_32_32( spec_in[i], spec_in[i] ), W_mult_32_32( mdst, mdst ) ), shl( tmp16, 1 ) ); + power_spec[i] = W_extract_l( W_shr( W_mult_32_32( W_extract_h( spec_power ), power_spec_scale_fac ), 16 ) ); /* 2 * (Q31 - x_e + tmp16) + 1 - Q16 */ move32(); } - power_spec_e = sub( add( 4, shl( spec_e, 1 ) ), tmp16 ); + power_spec_q = add( shl( add( sub( 31, spec_e ), tmp16 ), 1 ), 1 - 16 ); } } @@ -1091,7 +1094,7 @@ static void run_min_stats_fx( { arr_tmp = power_spec; } - ApplyFdCng_ivas_fx( NULL, 0, arr_tmp, sub( 31, power_spec_e ), NULL, NULL, NULL, st, st->bfi, 0 ); + ApplyFdCng_ivas_fx( NULL, 0, arr_tmp, power_spec_q, NULL, NULL, NULL, st, st->bfi, 0 ); /*=================================================*/ } diff --git a/lib_dec/ivas_stereo_mdct_stereo_dec.c b/lib_dec/ivas_stereo_mdct_stereo_dec_fx.c similarity index 96% rename from lib_dec/ivas_stereo_mdct_stereo_dec.c rename to lib_dec/ivas_stereo_mdct_stereo_dec_fx.c index 6d4fc967ea10795e9a872894a1396557a3c0e7f7..5b1378a894fead3f6efabcef3e7746132dccad56 100644 --- a/lib_dec/ivas_stereo_mdct_stereo_dec.c +++ b/lib_dec/ivas_stereo_mdct_stereo_dec_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other @@ -35,11 +35,9 @@ #include #include "options.h" #include "ivas_cnst.h" -#include "ivas_prot.h" -#include "prot.h" +#include "prot_fx.h" #include "rom_com.h" #include "wmc_auto.h" -#include "prot_fx.h" #include "ivas_prot_fx.h" @@ -603,7 +601,7 @@ ivas_error initMdctStereoDtxData_fx( IF( st->cldfbAna == NULL ) { /* open analysis for max. sampling rate 48kHz */ - IF( NE_32( ( error = openCldfb_ivas_fx( &st->cldfbAna, CLDFB_ANALYSIS, 48000, CLDFB_PROTOTYPE_1_25MS ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &st->cldfbAna, CLDFB_ANALYSIS, 48000, CLDFB_PROTOTYPE_1_25MS, DEC ) ), IVAS_ERR_OK ) ) { return error; } @@ -612,7 +610,7 @@ ivas_error initMdctStereoDtxData_fx( IF( st->cldfbBPF == NULL ) { /* open analysis BPF for max. internal sampling rate 16kHz */ - IF( NE_32( ( error = openCldfb_ivas_fx( &st->cldfbBPF, CLDFB_ANALYSIS, 16000, CLDFB_PROTOTYPE_1_25MS ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &st->cldfbBPF, CLDFB_ANALYSIS, 16000, CLDFB_PROTOTYPE_1_25MS, DEC ) ), IVAS_ERR_OK ) ) { return error; } @@ -720,20 +718,7 @@ static void update_exp( } return; } -static Word16 norm_arr( - Word16 *arr, - Word32 size /* Q0 */ -) -{ - Word16 q = 15; - move16(); - FOR( Word32 i = 0; i < size; i++ ) - IF( arr[i] != 0 ) - { - q = s_min( q, norm_s( arr[i] ) ); - } - return q; -} + void updateBuffersForDmxMdctStereo_fx( CPE_DEC_HANDLE hCPE, /* i/o: CPE handle */ const Word16 output_frame, /* i : output frame length Q0*/ @@ -919,9 +904,13 @@ void updateBuffersForDmxMdctStereo_fx( move16(); sts[0]->hTcxLtpDec->exp_tcxltp_mem_out = add( sts[0]->hTcxLtpDec->exp_tcxltp_mem_out, 1 ); move16(); - - Copy_Scale_sig_16_32( &sts[0]->hTcxLtpDec->tcxltp_mem_in[0], &sts[0]->hTcxLtpDec->tcxltp_mem_in_32[0], TCXLTP_MAX_DELAY, sub( 11, sub( 15, sts[0]->hTcxLtpDec->exp_tcxltp_mem_in ) ) ); // Q11 - Copy_Scale_sig_16_32( &sts[0]->hTcxLtpDec->tcxltp_mem_out[0], &sts[0]->hTcxLtpDec->tcxltp_mem_out_32[0], TCXLTP_MAX_DELAY, sub( 11, sub( 15, sts[0]->hTcxLtpDec->exp_tcxltp_mem_out ) ) ); // Q11 +#ifdef FIX_ISSUE_1237 + Copy_Scale_sig_16_32_no_sat( &sts[0]->hTcxLtpDec->tcxltp_mem_in[0], &sts[0]->hTcxLtpDec->tcxltp_mem_in_32[0], TCXLTP_MAX_DELAY, sub( 11, sub( 15, sts[0]->hTcxLtpDec->exp_tcxltp_mem_in ) ) ); // Q11 + Copy_Scale_sig_16_32_no_sat( &sts[0]->hTcxLtpDec->tcxltp_mem_out[0], &sts[0]->hTcxLtpDec->tcxltp_mem_out_32[0], TCXLTP_MAX_DELAY, sub( 11, sub( 15, sts[0]->hTcxLtpDec->exp_tcxltp_mem_out ) ) ); // Q11 +#else + Copy_Scale_sig_16_32_DEPREC( &sts[0]->hTcxLtpDec->tcxltp_mem_in[0], &sts[0]->hTcxLtpDec->tcxltp_mem_in_32[0], TCXLTP_MAX_DELAY, sub( 11, sub( 15, sts[0]->hTcxLtpDec->exp_tcxltp_mem_in ) ) ); // Q11 + Copy_Scale_sig_16_32_DEPREC( &sts[0]->hTcxLtpDec->tcxltp_mem_out[0], &sts[0]->hTcxLtpDec->tcxltp_mem_out_32[0], TCXLTP_MAX_DELAY, sub( 11, sub( 15, sts[0]->hTcxLtpDec->exp_tcxltp_mem_out ) ) ); // Q11 +#endif } return; @@ -956,7 +945,7 @@ void applyDmxMdctStereo_fx( test(); IF( LE_32( hCPE->last_element_brate, IVAS_SID_5k2 ) ) { - crossfade_len = NS2SA( hCPE->hCoreCoder[0]->output_Fs, IVAS_DEC_DELAY_NS - DELAY_CLDFB_NS ); + crossfade_len = NS2SA_FX2( hCPE->hCoreCoder[0]->output_Fs, IVAS_DEC_DELAY_NS - DELAY_CLDFB_NS ); move16(); SWITCH( hCPE->hCoreCoder[0]->output_Fs ) { @@ -1003,7 +992,7 @@ void applyDmxMdctStereo_fx( } ELSE IF( EQ_16( hCPE->last_element_mode, IVAS_CPE_DFT ) && LE_32( hCPE->last_element_brate, IVAS_32k ) ) { - crossfade_len = NS2SA( hCPE->hCoreCoder[0]->output_Fs, DELAY_CLDFB_NS ); /* Q0 */ + crossfade_len = NS2SA_FX2( hCPE->hCoreCoder[0]->output_Fs, DELAY_CLDFB_NS ); /* Q0 */ move16(); SWITCH( hCPE->hCoreCoder[0]->output_Fs ) { diff --git a/lib_dec/ivas_stereo_switching_dec.c b/lib_dec/ivas_stereo_switching_dec_fx.c similarity index 96% rename from lib_dec/ivas_stereo_switching_dec.c rename to lib_dec/ivas_stereo_switching_dec_fx.c index 5d5b38d4dfdc1cb85b342be846f66093d087bf84..c70e606ac7c54298dc672c03b3e7b91dedadc02b 100644 --- a/lib_dec/ivas_stereo_switching_dec.c +++ b/lib_dec/ivas_stereo_switching_dec_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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,15 +34,13 @@ #include "options.h" #include "cnst.h" #include "rom_com.h" -#include "prot.h" -#include "ivas_prot.h" +#include "prot_fx.h" #include "ivas_prot_fx.h" #include "ivas_rom_com.h" #include "assert.h" #include "wmc_auto.h" #include #include "ivas_prot_fx.h" -#include "prot_fx.h" #include "ivas_rom_com_fx.h" /*-------------------------------------------------------------------* @@ -207,7 +205,7 @@ static ivas_error allocate_CoreCoder_fx( IF( st->cldfbAna == NULL ) { /* open analysis for max. sampling rate 48kHz */ - IF( NE_32( ( error = openCldfb_ivas_fx( &st->cldfbAna, CLDFB_ANALYSIS, 48000, CLDFB_PROTOTYPE_1_25MS ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &st->cldfbAna, CLDFB_ANALYSIS, 48000, CLDFB_PROTOTYPE_1_25MS, DEC ) ), IVAS_ERR_OK ) ) { return error; } @@ -216,7 +214,7 @@ static ivas_error allocate_CoreCoder_fx( IF( st->cldfbBPF == NULL ) { /* open analysis BPF for max. internal sampling rate 16kHz */ - IF( NE_32( ( error = openCldfb_ivas_fx( &st->cldfbBPF, CLDFB_ANALYSIS, 16000, CLDFB_PROTOTYPE_1_25MS ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &st->cldfbBPF, CLDFB_ANALYSIS, 16000, CLDFB_PROTOTYPE_1_25MS, DEC ) ), IVAS_ERR_OK ) ) { return error; } @@ -415,7 +413,7 @@ ivas_error stereo_memory_dec_fx( IF( hCPE->hCoreCoder[0]->last_core != ACELP_CORE ) { - Copy32( hCPE->hStereoDft->buff_LBTCX_mem_fx, hCPE->input_mem_LB_fx[0], NS2SA( i_mult( hCPE->hCoreCoder[0]->last_L_frame, FRAMES_PER_SEC ), STEREO_DFT32MS_OVL_NS ) ); /* Q11 */ + Copy32( hCPE->hStereoDft->buff_LBTCX_mem_fx, hCPE->input_mem_LB_fx[0], NS2SA_FX2( i_mult( hCPE->hCoreCoder[0]->last_L_frame, FRAMES_PER_SEC ), STEREO_DFT32MS_OVL_NS ) ); /* Q11 */ } } @@ -470,7 +468,7 @@ ivas_error stereo_memory_dec_fx( } /* memory update - needed in TD stereo, TCX/HQ frame -> DFT stereo, ACELP frame switching */ - Copy32( hCPE->input_mem_LB_fx[0], hCPE->hStereoDft->buff_LBTCX_mem_fx, NS2SA( s_min( i_mult( hCPE->hCoreCoder[0]->last_L_frame, FRAMES_PER_SEC ), 16000 ), STEREO_DFT32MS_OVL_NS ) ); /* Q11 */ + Copy32( hCPE->input_mem_LB_fx[0], hCPE->hStereoDft->buff_LBTCX_mem_fx, NS2SA_FX2( s_min( i_mult( hCPE->hCoreCoder[0]->last_L_frame, FRAMES_PER_SEC ), 16000 ), STEREO_DFT32MS_OVL_NS ) ); /* Q11 */ /* allocate ICBWE structure */ IF( hCPE->hStereoICBWE == NULL ) @@ -503,7 +501,7 @@ ivas_error stereo_memory_dec_fx( return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DTX/TD CNG\n" ) ); } - td_cng_dec_init_fx( st ); + td_cng_dec_init_ivas_fx( st ); } } @@ -754,7 +752,7 @@ ivas_error stereo_memory_dec_fx( IF( st->cldfbAna == NULL ) { - IF( NE_32( ( error = openCldfb_ivas_fx( &st->cldfbAna, CLDFB_ANALYSIS, 48000, CLDFB_PROTOTYPE_1_25MS ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &st->cldfbAna, CLDFB_ANALYSIS, 48000, CLDFB_PROTOTYPE_1_25MS, DEC ) ), IVAS_ERR_OK ) ) { return error; } @@ -763,7 +761,7 @@ ivas_error stereo_memory_dec_fx( IF( st->cldfbBPF == NULL ) { /* open analysis BPF for max. internal sampling rate 16kHz */ - IF( NE_32( ( error = openCldfb_ivas_fx( &st->cldfbBPF, CLDFB_ANALYSIS, 16000, CLDFB_PROTOTYPE_1_25MS ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &st->cldfbBPF, CLDFB_ANALYSIS, 16000, CLDFB_PROTOTYPE_1_25MS, DEC ) ), IVAS_ERR_OK ) ) { return error; } @@ -1034,11 +1032,11 @@ ivas_error stereo_memory_dec_fx( IF( hCPE->prev_synth_chs_fx[1] == NULL ) { st = hCPE->hCoreCoder[1]; - IF( ( hCPE->prev_synth_chs_fx[1] = (Word32 *) malloc( sizeof( Word32 ) * NS2SA( st->output_Fs, FRAME_SIZE_NS ) ) ) == NULL ) + IF( ( hCPE->prev_synth_chs_fx[1] = (Word32 *) malloc( sizeof( Word32 ) * NS2SA_FX2( st->output_Fs, FRAME_SIZE_NS ) ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DFT stereo memory\n" ) ); } - set32_fx( hCPE->prev_synth_chs_fx[1], 0, NS2SA( st->output_Fs, FRAME_SIZE_NS ) ); + set32_fx( hCPE->prev_synth_chs_fx[1], 0, NS2SA_FX2( st->output_Fs, FRAME_SIZE_NS ) ); } IF( hCPE->hStereoICBWE == NULL && EQ_16( hCPE->element_mode, IVAS_CPE_DFT ) ) @@ -1102,7 +1100,7 @@ ivas_error stereo_memory_dec_fx( { IF( hCPE->hCoreCoder[i]->cldfbSyn == NULL ) /* could be NULL when we had the MCT LFE channel */ { - IF( NE_32( ( error = openCldfb_ivas_fx( &hCPE->hCoreCoder[i]->cldfbSyn, CLDFB_SYNTHESIS, hCPE->hCoreCoder[i]->output_Fs, CLDFB_PROTOTYPE_1_25MS ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &hCPE->hCoreCoder[i]->cldfbSyn, CLDFB_SYNTHESIS, hCPE->hCoreCoder[i]->output_Fs, CLDFB_PROTOTYPE_1_25MS, DEC ) ), IVAS_ERR_OK ) ) { return error; } @@ -2079,7 +2077,7 @@ void stereo_td2dft_update_fx( ) { Word16 ovl, ovl_TCX, dft32ms_ovl, hq_delay_comp; - Word16 ns, nsLB; + Word16 ns, nsLB, i; Word16 old_out_len, old_outLB_len; Decoder_State **sts; @@ -2143,7 +2141,7 @@ void stereo_td2dft_update_fx( /* TCX synthesis (it was already delayed in TD stereo in core_switching_post_dec()) */ IF( sts[n]->hTcxDec != NULL ) { - ovl_TCX = NS2SA_FX2( sts[n]->hTcxDec->L_frameTCX * FRAMES_PER_SEC, STEREO_DFT32MS_OVL_NS ); /* Q0 */ + ovl_TCX = NS2SA_FX2( L_mult0( sts[n]->hTcxDec->L_frameTCX, FRAMES_PER_SEC ), STEREO_DFT32MS_OVL_NS ); /* Q0 */ move16(); Copy32( synth_fx + sts[n]->hTcxDec->L_frameTCX + hq_delay_comp - ovl_TCX, hCPE->input_mem_fx[n], sub( ovl_TCX, hq_delay_comp ) ); /* Q11 */ Copy32( sts[n]->delay_buf_out32_fx, hCPE->input_mem_fx[n] + ovl_TCX - hq_delay_comp, hq_delay_comp ); /* Q11 */ @@ -2161,7 +2159,7 @@ void stereo_td2dft_update_fx( /* TCX synthesis (it was already delayed in TD stereo in core_switching_post_dec()) */ IF( sts[n]->hTcxDec != NULL ) { - ovl_TCX = NS2SA_FX2( sts[n]->hTcxDec->L_frameTCX * FRAMES_PER_SEC, STEREO_DFT32MS_OVL_NS ); /* Q0 */ + ovl_TCX = NS2SA_FX2( L_mult0( sts[n]->hTcxDec->L_frameTCX, FRAMES_PER_SEC ), STEREO_DFT32MS_OVL_NS ); /* Q0 */ move16(); Copy32( synth_fx + add( sts[n]->hTcxDec->L_frameTCX, sub( hq_delay_comp, ovl_TCX ) ), hCPE->input_mem_fx[n], sub( ovl_TCX, hq_delay_comp ) ); /* Q11 */ Copy32( sts[n]->delay_buf_out32_fx, hCPE->input_mem_fx[n] + sub( ovl_TCX, hq_delay_comp ), hq_delay_comp ); /* Q11 */ @@ -2182,9 +2180,9 @@ void stereo_td2dft_update_fx( v_add_fx( sts[0]->hHQ_core->old_outLB_fx + nsLB, sts[1]->hHQ_core->old_outLB_fx + nsLB, hCPE->old_outLB_mdct_fx, old_outLB_len ); L_lerp_fx_q11( hCPE->old_outLB_mdct_fx, hCPE->old_outLB_mdct_fx, STEREO_MDCT2DFT_FADE_LEN_48k, old_outLB_len ); #ifndef MSAN_FIX - for ( int i = 0; i < STEREO_MDCT2DFT_FADE_LEN_48k; i++ ) + for ( i = 0; i < STEREO_MDCT2DFT_FADE_LEN_48k; i++ ) #else - FOR( Word32 i = 0; i < old_outLB_len; i++ ) + FOR( i = 0; i < old_outLB_len; i++ ) #endif { hCPE->old_outLB_mdct_fx[i] = L_shr( hCPE->old_outLB_mdct_fx[i], 1 ); /* Q11 */ @@ -2194,7 +2192,7 @@ void stereo_td2dft_update_fx( #ifndef MSAN_FIX for ( int i = 0; i < STEREO_MDCT2DFT_FADE_LEN_48k; i++ ) #else - FOR( Word32 i = 0; i < old_out_len; i++ ) + FOR( i = 0; i < old_out_len; i++ ) #endif { hCPE->old_out_mdct_fx[i] = L_shr( hCPE->old_out_mdct_fx[i], 1 ); /* q_old_out_mdct */ @@ -2343,15 +2341,20 @@ static Word32 ncross_corr_self_fx( { Word64 c_c_fx; Word32 c_c_fx_return; + Word64 energy_x_fx, energy_y_fx; +#ifndef OPT_STEREO_32KBPS_V1 Word16 c_c_fx_q; - Word64 energy_xy_fx, energy_x_fx, energy_y_fx; + Word64 energy_xy_fx; +#endif /* OPT_STEREO_32KBPS_V1 */ UWord16 j; Word32 *signal_a_fx, *signal_b_fx; Word32 temp_x, temp_y; Word16 headroom_left_x, headroom_left_y; +#ifndef OPT_STEREO_32KBPS_V1 Word16 x_inv_q, y_inv_q; Word16 x_q, y_q; Word16 res_q; +#endif /* OPT_STEREO_32KBPS_V1 */ c_c_fx = 0; move64(); energy_x_fx = 0; @@ -2362,13 +2365,43 @@ static Word32 ncross_corr_self_fx( signal_b_fx = &signal_fx[y]; /* Q11 */ FOR( j = 0; j < corr_len; j += subsampling ) { +#ifdef OPT_STEREO_32KBPS_V1 + c_c_fx = W_mac_32_32( c_c_fx, signal_a_fx[j], signal_b_fx[j] ); /* 2 * Q11 + 1*/ + energy_x_fx = W_mac_32_32( energy_x_fx, signal_a_fx[j], signal_a_fx[j] ); /* 2 * Q11+ 1 */ + energy_y_fx = W_mac_32_32( energy_y_fx, signal_b_fx[j], signal_b_fx[j] ); /* 2 * Q11+ 1 */ +#else /* OPT_STEREO_32KBPS_V1 */ c_c_fx = W_add( c_c_fx, W_mult0_32_32( ( signal_a_fx[j] ), ( signal_b_fx[j] ) ) ); /* 2 * Q11 */ energy_x_fx = W_add( energy_x_fx, W_mult0_32_32( ( signal_a_fx[j] ), ( signal_a_fx[j] ) ) ); /* 2 * Q11 */ energy_y_fx = W_add( energy_y_fx, W_mult0_32_32( ( signal_b_fx[j] ), ( signal_b_fx[j] ) ) ); /* 2 * Q11 */ +#endif /* OPT_STEREO_32KBPS_V1 */ } headroom_left_x = W_norm( energy_x_fx ); headroom_left_y = W_norm( energy_y_fx ); +#ifdef OPT_STEREO_32KBPS_V1 + temp_x = W_extract_h( W_shl( energy_x_fx, headroom_left_x ) ); // Q23 + headroom_left_x -32 + temp_y = W_extract_h( W_shl( energy_y_fx, headroom_left_y ) ); // Q23 + headroom_left_y -32 + Word64 prod = W_mult0_32_32( temp_x, temp_y ); // Q(headroom_left_x + headroom_left_y - 18) + Word16 q_prod = W_norm( prod ); + Word32 energy = W_extract_h( W_shl( prod, q_prod ) ); // Q(headroom_left_x + headroom_left_y + q_prod - 18) - 32 + q_prod = sub( 81, add( add( headroom_left_x, headroom_left_y ), q_prod ) ); + energy = Sqrt32( energy, &q_prod ); + + IF( LT_32( energy, L_shl_sat( 1, sub( 31, q_prod ) ) ) ) + { + c_c_fx_return = W_shl_sat_l( c_c_fx, 31 - ( 2 * OUTPUT_Q + 1 ) ); // Q31 + } + ELSE + { + // Maximize c_c_fx + Word16 q_cc = W_norm( c_c_fx ); + Word32 num = W_extract_h( W_shl( c_c_fx, q_cc ) ); // Q(23 + q_cc - 32) -> e(40 - q_cc) + Word16 quo_e; + num = BASOP_Util_Divide3232_Scale_cadence( num, energy, &quo_e ); + quo_e = add( sub( sub( 40, q_cc ), q_prod ), quo_e ); + c_c_fx_return = L_shl_sat( num, quo_e ); // Q31 + } +#else /* OPT_STEREO_32KBPS_V1 */ IF( LT_16( headroom_left_x, 32 ) ) { energy_x_fx = W_shr( energy_x_fx, sub( 32, headroom_left_x ) ); /* 2 * Q11 - (32 -headroom_left_x) */ @@ -2440,6 +2473,7 @@ static Word32 ncross_corr_self_fx( c_c_fx_return = W_extract_l( c_c_fx ); /* Q31 */ move32(); +#endif /* OPT_STEREO_32KBPS_V1 */ return c_c_fx_return; } diff --git a/lib_dec/ivas_stereo_td_dec.c b/lib_dec/ivas_stereo_td_dec_fx.c similarity index 95% rename from lib_dec/ivas_stereo_td_dec.c rename to lib_dec/ivas_stereo_td_dec_fx.c index c53135f0a3b493fa021415330d0478b9d7dd4b4f..023c9a2e5e3a1fc4dd97ded44e0ac846508e84ed 100644 --- a/lib_dec/ivas_stereo_td_dec.c +++ b/lib_dec/ivas_stereo_td_dec_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other @@ -35,9 +35,7 @@ #include #include "cnst.h" #include "rom_com.h" -#include "prot.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "ivas_rom_com.h" #include "ivas_cnst.h" #include "wmc_auto.h" @@ -339,52 +337,13 @@ void tdm_configure_dec_fx( return; } -/*-------------------------------------------------------------------* - * Function tdm_downmix_plain() - * - * downmix Left+Right to Primary+Secondary channel - *-------------------------------------------------------------------*/ - -void tdm_upmix_plain( - float Left[], /* o : left channel */ - float Right[], /* o : right channel */ - const float PCh_2_L[], /* i : primary channel */ - const float SCh_2_R[], /* i : secondary channel */ - const float LR_ratio, /* i : mixing ratio */ - const float inv_den_LR_ratio, /* i : inverse mixing ration */ - const int16_t start_index, /* i : start index */ - const int16_t end_index, /* i : end index */ - const int16_t plus_minus_flag /* i : plus/minus flag */ -) -{ - int16_t i; - - if ( plus_minus_flag == 1 ) - { - for ( i = start_index; i < end_index; i++ ) - { - Left[i] = ( LR_ratio * ( PCh_2_L[i] - SCh_2_R[i] ) + SCh_2_R[i] ) * inv_den_LR_ratio; - Right[i] = ( -LR_ratio * ( PCh_2_L[i] + SCh_2_R[i] ) + PCh_2_L[i] ) * inv_den_LR_ratio; - } - } - else - { - for ( i = start_index; i < end_index; i++ ) - { - Left[i] = ( LR_ratio * ( PCh_2_L[i] + SCh_2_R[i] ) - SCh_2_R[i] ) * inv_den_LR_ratio; - Right[i] = ( LR_ratio * ( PCh_2_L[i] - SCh_2_R[i] ) - PCh_2_L[i] ) * inv_den_LR_ratio; - } - } - - return; -} void tdm_upmix_plain_fx( Word32 Left_fx[], /* o : left channel Qx*/ Word32 Right_fx[], /* o : right channel Qx*/ const Word32 PCh_2_L_fx[], /* i : primary channel Qx*/ const Word32 SCh_2_R_fx[], /* i : secondary channel Qx*/ const Word32 LR_ratio_fx, /* i : mixing ratio Q31*/ - const Word32 inv_den_LR_ratio_fx, /* i : inverse mixing ration Q31*/ + const Word32 inv_den_LR_ratio_fx, /* i : inverse mixing ration Q30*/ const Word16 start_index, /* i : start index Q0*/ const Word16 end_index, /* i : end index Q0*/ const Word16 plus_minus_flag /* i : plus/minus flag Q0*/ @@ -396,16 +355,37 @@ void tdm_upmix_plain_fx( { FOR( i = start_index; i < end_index; i++ ) { +#ifdef OPT_STEREO_32KBPS_V1 + Word32 temp_left = Madd_32_32( SCh_2_R_fx[i], L_sub( PCh_2_L_fx[i], SCh_2_R_fx[i] ), LR_ratio_fx ); /* Qx */ + Left_fx[i] = W_shl_sat_l( W_mult0_32_32( temp_left, inv_den_LR_ratio_fx ), -30 ); /* Qx */ + move32(); + Word32 temp_right = Msub_32_32( PCh_2_L_fx[i], L_add( PCh_2_L_fx[i], SCh_2_R_fx[i] ), LR_ratio_fx ); /* Qx */ + Right_fx[i] = W_shl_sat_l( W_mult0_32_32( temp_right, inv_den_LR_ratio_fx ), -30 ); /* Qx */ + move32(); +#else /* OPT_STEREO_32KBPS_V1 */ Word32 temp_left = L_add( Mpy_32_32( L_sub( PCh_2_L_fx[i], SCh_2_R_fx[i] ), LR_ratio_fx ), SCh_2_R_fx[i] ); /* Qx */ Left_fx[i] = L_shl_sat( Mpy_32_32( temp_left, inv_den_LR_ratio_fx ), 1 ); /* Qx + 1 */ move32(); Word32 temp_right = L_add( Mpy_32_32( L_add( PCh_2_L_fx[i], SCh_2_R_fx[i] ), L_negate( LR_ratio_fx ) ), PCh_2_L_fx[i] ); /* Qx */ Right_fx[i] = L_shl_sat( Mpy_32_32( temp_right, inv_den_LR_ratio_fx ), 1 ); /* Qx + 1 */ move32(); +#endif /* OPT_STEREO_32KBPS_V1 */ } } ELSE { +#ifdef OPT_STEREO_32KBPS_V1 + Word32 inv_den_LR_ratio_fx_neg = L_negate( inv_den_LR_ratio_fx ); + FOR( i = start_index; i < end_index; i++ ) + { + Word32 temp_left = Msub_32_32( SCh_2_R_fx[i], L_add( PCh_2_L_fx[i], SCh_2_R_fx[i] ), LR_ratio_fx ); /* Qx */ + Left_fx[i] = W_shl_sat_l( W_mult0_32_32( temp_left, inv_den_LR_ratio_fx_neg ), -30 ); /* Qx */ + move32(); + Word32 temp_right = Msub_32_32( PCh_2_L_fx[i], L_sub( PCh_2_L_fx[i], SCh_2_R_fx[i] ), LR_ratio_fx ); /* Qx */ + Right_fx[i] = W_shl_sat_l( W_mult0_32_32( temp_right, inv_den_LR_ratio_fx_neg ), -30 ); /* Qx */ + move32(); + } +#else /* OPT_STEREO_32KBPS_V1 */ FOR( i = start_index; i < end_index; i++ ) { Word32 temp_left = L_sub( Mpy_32_32( L_add( PCh_2_L_fx[i], SCh_2_R_fx[i] ), LR_ratio_fx ), SCh_2_R_fx[i] ); /* Qx */ @@ -415,6 +395,7 @@ void tdm_upmix_plain_fx( Right_fx[i] = L_shl_sat( Mpy_32_32( temp_right, inv_den_LR_ratio_fx ), 1 ); /* Qx + 1 */ move32(); } +#endif /* OPT_STEREO_32KBPS_V1 */ } return; @@ -680,17 +661,17 @@ void stereo_tdm_combine_fx( output_Fs = hCPE->hCoreCoder[0]->output_Fs; /* Q0 */ move32(); - tdm_n_OVA = NS2SA( output_Fs, TDM_L_NOVA_NS ); /* Q0 */ + tdm_n_OVA = NS2SA_FX2( output_Fs, TDM_L_NOVA_NS ); /* Q0 */ move16(); IF( flag_HB ) { - upmixing_delay = NS2SA( output_Fs, ACELP_LOOK_NS + DELAY_BWE_TOTAL_NS ); /* Q0 */ + upmixing_delay = NS2SA_FX2( output_Fs, ACELP_LOOK_NS + DELAY_BWE_TOTAL_NS ); /* Q0 */ move16(); } ELSE { - upmixing_delay = NS2SA( output_Fs, ACELP_LOOK_NS + DELAY_CLDFB_NS ); /* Q0 */ + upmixing_delay = NS2SA_FX2( output_Fs, ACELP_LOOK_NS + DELAY_CLDFB_NS ); /* Q0 */ move16(); } @@ -845,7 +826,7 @@ void stereo_tdm_combine_fx( } incr_fx = Mpy_32_32( L_sub( ONE_IN_Q29, fac_fx ), step ); /* Q29 */ - FOR( i = 0; i < NS2SA( output_Fs, ACELP_LOOK_NS ); i++ ) + FOR( i = 0; i < NS2SA_FX2( output_Fs, ACELP_LOOK_NS ); i++ ) { PCh_2_L_fx[i] = L_shl_sat( Mpy_32_32( PCh_2_L_fx[i], fac_fx ), 2 ); /* Qx */ move32(); diff --git a/lib_dec/ivas_svd_dec.c b/lib_dec/ivas_svd_dec_fx.c similarity index 71% rename from lib_dec/ivas_svd_dec.c rename to lib_dec/ivas_svd_dec_fx.c index 3b8a90a4c87bd969a3359b24a3ee577266a1b55e..1467687d8b49a576e6b28bbc4ac58a7ccdd2065d 100644 --- a/lib_dec/ivas_svd_dec.c +++ b/lib_dec/ivas_svd_dec_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other @@ -32,13 +32,11 @@ #include #include "options.h" -#include "prot.h" -#include "ivas_prot.h" +#include "prot_fx.h" #include "ivas_stat_dec.h" #include "ivas_cnst.h" #include #include "wmc_auto.h" -#include "prot_fx.h" #include "ivas_prot_fx.h" /*-----------------------------------------------------------------------* @@ -50,6 +48,7 @@ #define SVD_MINIMUM_VALUE_FX ( 2 ) /* minimum value */ #define SVD_ZERO_FLUSH_THRESHOLD_FX ( 0 ) #define CONVERGENCE_FACTOR_FX 214748 /* factor for SVD convergence (as per latest float code: 1.0e-04f) */ + /*-----------------------------------------------------------------------* * Local function prototypes *-----------------------------------------------------------------------*/ @@ -71,7 +70,11 @@ static void biDiagonalReductionLeft_fx( Word32 singularVectors[][MAX_OUTPUT_CHANNELS], /* exp(singularVectors_e) */ Word32 singularValues[MAX_OUTPUT_CHANNELS], /* exp(singularValues_e) */ Word32 secDiag[MAX_OUTPUT_CHANNELS], /* exp(secDiag_e) */ +#ifndef FIX_1010_OPT_SINGLE_RESCALE Word16 *singularVectors_e, +#else + Word16 singularVectors2_e[][MAX_OUTPUT_CHANNELS], +#endif Word16 singularValues_e[MAX_OUTPUT_CHANNELS], Word16 *secDiag_e, const Word16 nChannelsL, /* Q0 */ @@ -85,7 +88,11 @@ static void biDiagonalReductionLeft_fx( static void biDiagonalReductionRight_fx( Word32 singularVectors[][MAX_OUTPUT_CHANNELS], /* exp(singularVectors_e) */ Word32 secDiag[MAX_OUTPUT_CHANNELS], /* exp(secDiag_e) */ +#ifndef FIX_1010_OPT_SINGLE_RESCALE Word16 *singularVectors_e, +#else + Word16 singularVectors2_e[][MAX_OUTPUT_CHANNELS], +#endif Word16 *secDiag_e, const Word16 nChannelsL, /* Q0 */ const Word16 nChannelsC, /* Q0 */ @@ -98,7 +105,11 @@ static void biDiagonalReductionRight_fx( static void singularVectorsAccumulationLeft_fx( Word32 singularVectors_Left[][MAX_OUTPUT_CHANNELS], /* exp(singularVectors_e) as Input, Q31 as output */ Word32 singularValues[MAX_OUTPUT_CHANNELS], /* exp(singularValues_e) */ +#ifndef FIX_1010_OPT_SINGLE_RESCALE Word16 singularVectors_e, +#else + Word16 singularVectors_Left_e[][MAX_OUTPUT_CHANNELS], +#endif Word16 singularValues_e[MAX_OUTPUT_CHANNELS], const Word16 nChannelsL, /* Q0 */ const Word16 nChannelsC /* Q0 */ @@ -108,8 +119,16 @@ static void singularVectorsAccumulationRight_fx( Word32 singularVectors_Left[][MAX_OUTPUT_CHANNELS], /* singularVectors_e */ Word32 singularVectors_Right[][MAX_OUTPUT_CHANNELS], /* singularVectors_e */ Word32 secDiag[MAX_OUTPUT_CHANNELS], /* exp(secDiag_e) */ +#ifndef FIX_1010_OPT_SINGLE_RESCALE Word16 singularVectors_e, +#else + Word16 singularVectors_Left_e[][MAX_OUTPUT_CHANNELS], +#endif +#ifndef FIX_1010_OPT_SEC_SINGLE_RESCALE Word16 secDiag_e, +#else + Word16 *secDiag_e, +#endif const Word16 nChannelsC /* Q0 */ ); @@ -149,6 +168,18 @@ static void ApplyRotation_fx( const Word16 nChannels /* Q0 */ ); +#ifdef FIX_1010_OPT_GIVENS_INV +static void GivensRotation2_fx( + const Word32 x, /* exp(x_e) */ + const Word16 x_e, + const Word32 z, /* exp(z_e) */ + const Word16 z_e, + Word32 *result, + Word32 *resultInv, + Word16 *out_e, + Word16 *outInv_e ); +#endif + static Word32 GivensRotation_fx( const Word32 x, /* exp(x_e) */ const Word16 x_e, @@ -274,9 +305,12 @@ Word16 svd_fx( Word16 iCh, jCh; Word16 lengthSingularValues; Word16 errorMessage, condition; - // int16_t max_length = ((nChannelsL > nChannelsC) ? nChannelsL : nChannelsC); Word32 secDiag_fx[MAX_OUTPUT_CHANNELS]; +#ifndef FIX_1010_OPT_SEC_SINGLE_RESCALE Word16 secDiag_fx_e = 0; +#else + Word16 secDiag_fx_e[MAX_OUTPUT_CHANNELS]; +#endif move16(); Word32 eps_x_fx = 0, temp_fx; move16(); @@ -285,7 +319,11 @@ Word16 svd_fx( Word16 temp_fx_e; push_wmops( "svd_fx" ); + +#ifndef FIX_1010_OPT_SINGLE_RESCALE set32_fx( secDiag_fx, 0, MAX_OUTPUT_CHANNELS ); + set16_fx( singularValues_fx_e, 0, MAX_OUTPUT_CHANNELS ); +#endif /* Collecting Values */ FOR( iCh = 0; iCh < nChannelsL; iCh++ ) @@ -297,19 +335,23 @@ Word16 svd_fx( } } - set16_fx( singularValues_fx_e, 0, MAX_OUTPUT_CHANNELS ); - /* Householder reduction */ +#ifndef FIX_1010_OPT_SEC_SINGLE_RESCALE HouseholderReduction_fx( singularVectors_Left_fx, singularValues_fx, singularVectors_Right_fx, secDiag_fx, InputMatrix_e, singularValues_fx_e, &secDiag_fx_e, nChannelsL, nChannelsC, &eps_x_fx, &eps_x_fx_e ); - +#else + HouseholderReduction_fx( singularVectors_Left_fx, singularValues_fx, singularVectors_Right_fx, secDiag_fx, InputMatrix_e, singularValues_fx_e, secDiag_fx_e, nChannelsL, nChannelsC, &eps_x_fx, &eps_x_fx_e ); +#endif /* Set extremely small values to zero if needed */ // flushToZeroArray(singularValues, max_length); // flushToZeroMat(singularVectors_Left, nChannelsL, nChannelsL); // flushToZeroMat(singularVectors_Right, nChannelsC, nChannelsC); /* BidagonalDiagonalisation */ +#ifndef FIX_1010_OPT_SEC_SINGLE_RESCALE errorMessage = BidagonalDiagonalisation_fx( singularVectors_Left_fx, singularValues_fx, singularVectors_Right_fx, secDiag_fx, singularValues_fx_e, &secDiag_fx_e, nChannelsL, nChannelsC, eps_x_fx, eps_x_fx_e ); /* Q0 */ - +#else + errorMessage = BidagonalDiagonalisation_fx( singularVectors_Left_fx, singularValues_fx, singularVectors_Right_fx, secDiag_fx, singularValues_fx_e, secDiag_fx_e, nChannelsL, nChannelsC, eps_x_fx, eps_x_fx_e ); /* Q0 */ +#endif /* Sort the singular values descending order */ lengthSingularValues = s_min( nChannelsL, nChannelsC ); /* Q0 */ @@ -381,11 +423,15 @@ static Word16 BidagonalDiagonalisation_fx( Word32 singularVectors_Right_fx[][MAX_OUTPUT_CHANNELS], /* i/o: right singular vectors (V) singularValues_fx_e*/ Word32 secDiag_fx[MAX_OUTPUT_CHANNELS], /* i/o: secDiag_fx_e*/ Word16 singularValues_fx_e[MAX_OUTPUT_CHANNELS], /* i/o: singular values vector (S) */ - Word16 *secDiag_fx_e, /* i/o: */ - const Word16 nChannelsL, /* i : number of rows in the matrix to be decomposed Q0*/ - const Word16 nChannelsC, /* i : number of columns in the matrix to be decomposed Q0*/ - const Word32 eps_x, /* i : eps_x_e*/ - const Word16 eps_x_e /* i : */ +#ifndef FIX_1010_OPT_SEC_SINGLE_RESCALE + Word16 *secDiag_fx_e, /* i/o: */ +#else + Word16 *secDiag_new_e, /* i/o: */ +#endif + const Word16 nChannelsL, /* i : number of rows in the matrix to be decomposed Q0*/ + const Word16 nChannelsC, /* i : number of columns in the matrix to be decomposed Q0*/ + const Word32 eps_x, /* i : eps_x_e*/ + const Word16 eps_x_e /* i : */ ) { Word16 kCh, nCh, iCh, jCh, split; @@ -395,6 +441,9 @@ static Word16 BidagonalDiagonalisation_fx( move16(); move16(); Word16 temp_exp; +#ifdef FIX_1010_OPT_NORM_NOSAT + Word16 temp_exp2; +#endif Word32 g = 0; move16(); Word16 g_e = 0; @@ -402,9 +451,15 @@ static Word16 BidagonalDiagonalisation_fx( Word16 convergence, iteration, found_split; Word16 error = 0; move16(); - Word16 singularValues_new_e[MAX_OUTPUT_CHANNELS], secDiag_new_e[MAX_OUTPUT_CHANNELS]; - Copy( singularValues_fx_e, singularValues_new_e, MAX_OUTPUT_CHANNELS ); +#ifdef FIX_1010_OPT_GIVENS_INV + Word32 temp; +#endif + Word16 singularValues_new_e[MAX_OUTPUT_CHANNELS]; +#ifndef FIX_1010_OPT_SEC_SINGLE_RESCALE + Word16 secDiag_new_e[MAX_OUTPUT_CHANNELS]; set16_fx( secDiag_new_e, *secDiag_fx_e, MAX_OUTPUT_CHANNELS ); +#endif + Copy( singularValues_fx_e, singularValues_new_e, MAX_OUTPUT_CHANNELS ); FOR( iCh = nChannelsC - 1; iCh >= 0; iCh-- ) /* nChannelsC */ { @@ -472,24 +527,46 @@ static Word16 BidagonalDiagonalisation_fx( c = singularValues_fx[kCh]; /* exp(singularValues_new_e) */ c_e = singularValues_new_e[kCh]; - singularValues_fx[kCh] = GivensRotation_fx( g, g_e, singularValues_fx[kCh], singularValues_new_e[kCh], &singularValues_new_e[kCh] ); /* exp(singularValues_new_e) */ - c = BASOP_Util_Divide3232_Scale_cadence( c, maxWithSign_fx( singularValues_fx[kCh] ), &temp_exp ); /* exp(temp_exp + (c_e - singularValues_new_e)) */ +#ifdef FIX_1010_OPT_GIVENS_INV + GivensRotation2_fx( g, g_e, singularValues_fx[kCh], singularValues_new_e[kCh], &singularValues_fx[kCh], &temp, &singularValues_new_e[kCh], &temp_exp ); /* exp(singularValues_new_e) */ + c = Mpy_32_32( c, temp ); + c_e = add( c_e, temp_exp ); +#else + singularValues_fx[kCh] = GivensRotation_fx( g, g_e, singularValues_fx[kCh], singularValues_new_e[kCh], &singularValues_new_e[kCh] ); /* exp(singularValues_new_e) */ + c = BASOP_Util_Divide3232_Scale_cadence( c, maxWithSign_fx( singularValues_fx[kCh] ), &temp_exp ); /* exp(temp_exp + (c_e - singularValues_new_e)) */ c_e = add( temp_exp, sub( c_e, singularValues_new_e[kCh] ) ); +#endif +#ifndef FIX_1010_OPT_NORM_NOSAT IF( c_e > 0 ) { c = L_shl_sat( c, c_e ); // Q31 c_e = 0; move16(); } +#else + temp_exp2 = norm_l( c ); + c = L_shl( c, temp_exp2 ); + c_e = sub( c_e, temp_exp2 ); +#endif +#ifdef FIX_1010_OPT_GIVENS_INV + s = Mpy_32_32( -g, temp ); + s_e = add( g_e, temp_exp ); +#else s = BASOP_Util_Divide3232_Scale_cadence( -g, maxWithSign_fx( singularValues_fx[kCh] ), &temp_exp ); /* exp(temp_exp + (g_e - singularValues_new_e))*/ s_e = add( temp_exp, sub( g_e, singularValues_new_e[kCh] ) ); +#endif +#ifndef FIX_1010_OPT_NORM_NOSAT IF( s_e > 0 ) { s = L_shl_sat( s, s_e ); // Q31 s_e = 0; move16(); } - +#else + temp_exp2 = norm_l( s ); + s = L_shl( s, temp_exp2 ); + s_e = sub( s_e, temp_exp2 ); +#endif ApplyRotation_fx( singularVectors_Left_fx, c, c_e, s, s_e, 0, x11_e, 0, x12_e, &f1, &f1_e, &f2, &f2_e, kCh, split, nChannelsL ); /* nChannelsL */ } } @@ -540,6 +617,7 @@ static Word16 BidagonalDiagonalisation_fx( // rescaling block Copy( singularValues_new_e, singularValues_fx_e, MAX_OUTPUT_CHANNELS ); +#ifndef FIX_1010_OPT_SEC_SINGLE_RESCALE Word16 max_exp = -31; move16(); FOR( iCh = 0; iCh < nChannelsC; iCh++ ) @@ -556,6 +634,7 @@ static Word16 BidagonalDiagonalisation_fx( secDiag_fx[iCh] = L_shr_r( secDiag_fx[iCh], sub( *secDiag_fx_e, secDiag_new_e[iCh] ) ); /* exp(secDiag_fx_e) */ move32(); } +#endif return ( error ); } @@ -579,6 +658,13 @@ static void ApplyQRTransform_fx( const Word16 nChannelsC /* i : number of columns in the matrix to be decomposed Q0*/ ) { +#ifdef FIX_1010_OPT_GIVENS_INV + Word32 temp; + Word16 temp_e; +#endif +#ifdef FIX_1010_OPT_NORM_NOSAT + Word16 temp_norm_e; +#endif Word16 ch, split; Word32 d = 0, g = 0, r = 0, x_ii = 0, x_split = 0, x_kk = 0, mu = 0, aux = 0; move32(); @@ -681,25 +767,47 @@ static void ApplyQRTransform_fx( g = Mpy_32_32( c, secDiag[ch + 1] ); /* exp(c_e + secDiag_e) */ g_e = add( c_e, secDiag_e[ch + 1] ); +#ifdef FIX_1010_OPT_GIVENS_INV + GivensRotation2_fx( d, d_e, r, r_e, &secDiag[ch], &temp, &secDiag_e[ch], &temp_e ); /* exp(secDiag_e) */ + c = Mpy_32_32( d, temp ); + c_e = add( temp_e, d_e ); +#else secDiag[ch] = GivensRotation_fx( d, d_e, r, r_e, &secDiag_e[ch] ); /* exp(secDiag_e) */ move32(); c = BASOP_Util_Divide3232_Scale_cadence( d, maxWithSign_fx( secDiag[ch] ), &c_e ); /* exp(c_e + (d_e + secDiag_e)) */ c_e = add( c_e, sub( d_e, secDiag_e[ch] ) ); +#endif +#ifndef FIX_1010_OPT_NORM_NOSAT IF( c_e > 0 ) { c = L_shl_sat( c, c_e ); // Q31 c_e = 0; move16(); } +#else + temp_norm_e = norm_l( c ); + c = L_shl( c, temp_norm_e ); + c_e = sub( c_e, temp_norm_e ); +#endif +#ifdef FIX_1010_OPT_GIVENS_INV + s = Mpy_32_32( r, temp ); + s_e = add( r_e, temp_e ); +#else s = BASOP_Util_Divide3232_Scale_cadence( r, maxWithSign_fx( secDiag[ch] ), &s_e ); /* exp(s_e + (r_e - sec_Diag_e))*/ s_e = add( s_e, sub( r_e, secDiag_e[ch] ) ); +#endif +#ifndef FIX_1010_OPT_NORM_NOSAT IF( s_e > 0 ) { s = L_shl_sat( s, s_e ); // Q31 s_e = 0; move16(); } - +#else + temp_norm_e = norm_l( s ); + s = L_shl( s, temp_norm_e ); + s_e = sub( s_e, temp_norm_e ); +#endif r = Mpy_32_32( s, singularValues[ch + 1] ); /* exp(r_e + secDiag_e) */ r_e = add( s_e, singularValues_e[ch + 1] ); x_split = Mpy_32_32( c, singularValues[ch + 1] ); /* exp(c_e + secDiag_e) */ @@ -713,30 +821,48 @@ static void ApplyQRTransform_fx( // ApplyRotation(singularVectors_Right, c, s, x_ii, aux, &d, &g, ch + 1, ch, nChannelsC); ApplyRotation_fx( singularVectors_Right, c, c_e, s, s_e, x_ii, x_ii_e, aux, aux_e, &d, &d_e, &g, &g_e, ch + 1, ch, nChannelsC ); +#ifdef FIX_1010_OPT_GIVENS_INV + GivensRotation2_fx( d, d_e, r, r_e, &singularValues[ch], &aux, &singularValues_e[ch], &aux_e ); /* exp(singularValues_e) */ +#else singularValues[ch] = GivensRotation_fx( d, d_e, r, r_e, &singularValues_e[ch] ); /* exp(singularValues_e) */ move32(); - IF( GT_32( L_abs( singularValues[ch] ), Mpy_32_32( CONVERGENCE_FACTOR_FX, L_abs( singularValues[ch] ) ) ) ) +#endif + IF( singularValues[ch] != 0 ) { +#ifndef FIX_1010_OPT_GIVENS_INV aux = BASOP_Util_Divide3232_Scale_cadence( ONE_IN_Q30, singularValues[ch], &aux_e ); /* exp(aux_e + (1 - singularValues_e)) */ aux_e = add( aux_e, sub( 1, singularValues_e[ch] ) ); +#endif c = Mpy_32_32( d, aux ); /* exp(d_e + aux_e) */ c_e = add( d_e, aux_e ); +#ifndef FIX_1010_OPT_NORM_NOSAT IF( c_e > 0 ) { c = L_shl_sat( c, c_e ); // Q31 c_e = 0; move16(); } +#else + temp_norm_e = norm_l( c ); + c = L_shl( c, temp_norm_e ); + c_e = sub( c_e, temp_norm_e ); +#endif s = Mpy_32_32( r, aux ); /* exp(r_e + aux_e) */ s_e = add( r_e, aux_e ); +#ifndef FIX_1010_OPT_NORM_NOSAT IF( s_e > 0 ) { s = L_shl_sat( s, s_e ); // Q31 s_e = 0; move16(); } +#else + temp_norm_e = norm_l( s ); + s = L_shl( s, temp_norm_e ); + s_e = sub( s_e, temp_norm_e ); +#endif } // ApplyRotation(singularVectors_Left, c, s, g, x_split, &d, &x_ii, ch + 1, ch, nChannelsL); @@ -783,13 +909,56 @@ static void ApplyRotation_fx( ) { Word16 ch; - Word16 temp_exp; *d = BASOP_Util_Add_Mant32Exp( Mpy_32_32( c, x11 ), add( c_e, x11_e ), Mpy_32_32( s, x12 ), add( s_e, x12_e ), d_e ); /* exp(d_e) */ move32(); *g = BASOP_Util_Add_Mant32Exp( Mpy_32_32( c, x12 ), add( c_e, x12_e ), Mpy_32_32( L_negate( s ), x11 ), add( s_e, x11_e ), g_e ); /* exp(g_e) */ move32(); +#ifdef SVD_WMOPS_OPT + Word16 c_q = sub( 31, c_e ); + Word16 s_q = sub( 31, s_e ); + Word32 op1, op2; + Word16 op_e; + + // Bring c and s to same Q + IF( GT_16( c_q, s_q ) ) + { + op1 = L_shr( c, sub( c_q, s_q ) ); + op2 = s; + move32(); + op_e = s_q; + move16(); + } + ELSE + { + op1 = c; + move32(); + op2 = L_shr( s, sub( s_q, c_q ) ); + op_e = c_q; + move16(); + } + op_e = add( op_e, 1 ); // 64 bit mac -> +1 + + FOR( ch = 0; ch < nChannels; ch++ ) + { + x11 = singularVector[ch][currentIndex2]; + move32(); + x12 = singularVector[ch][currentIndex1]; + move32(); + + Word64 temp = W_mac_32_32( W_mult_32_32( op1, x11 ), op2, x12 ); // Q(singularVector) + op_e + temp = W_shr( temp, op_e ); // Q(singularVector) + singularVector[ch][currentIndex2] = W_sat_l( temp ); // Q(singularVector) + move32(); + + temp = W_mac_32_32( W_mult_32_32( op1, x12 ), L_negate( op2 ), x11 ); // Q(singularVector) + op_e + temp = W_shr( temp, op_e ); // Q(singularVector) + singularVector[ch][currentIndex1] = W_sat_l( temp ); // Q(singularVector) + move32(); + } +#else +#ifndef FIX_MINOR_SVD_WMOPS_MR1010X FOR( ch = 0; ch < nChannels; ch++ ) { x11 = singularVector[ch][currentIndex2]; @@ -805,6 +974,25 @@ static void ApplyRotation_fx( singularVector[ch][currentIndex1] = L_shl_sat( singularVector[ch][currentIndex1], temp_exp ); /* exp(temp_exp) */ move32(); } +#else + Word32 s_neg = L_negate( s ); + Word32 temp; + FOR( ch = 0; ch < nChannels; ch++ ) + { + x11 = singularVector[ch][currentIndex2]; + move32(); + x12 = singularVector[ch][currentIndex1]; + move32(); + temp = BASOP_Util_Add_Mant32Exp( Mpy_32_32( c, x11 ), c_e, Mpy_32_32( s, x12 ), s_e, &temp_exp ); /* exp(temp_exp) */ + singularVector[ch][currentIndex2] = L_shl_sat( temp, temp_exp ); /* exp(temp_exp) */ + move32(); + temp = BASOP_Util_Add_Mant32Exp( Mpy_32_32( c, x12 ), c_e, Mpy_32_32( s_neg, x11 ), s_e, &temp_exp ); /* exp(temp_exp) */ + singularVector[ch][currentIndex1] = L_shl_sat( temp, temp_exp ); /* exp(temp_exp) */ + move32(); + } + +#endif +#endif return; } @@ -836,14 +1024,36 @@ static void HouseholderReduction_fx( Word16 sig_x_fx_e = 0; move16(); +#ifdef FIX_1010_OPT_SINGLE_RESCALE + Word16 iCh, jCh; + Word16 singularVectors_Left_fx_e[MAX_OUTPUT_CHANNELS][MAX_OUTPUT_CHANNELS]; + FOR( jCh = 0; jCh < nChannelsL; jCh++ ) + { + FOR( iCh = 0; iCh < nChannelsC; iCh++ ) + { + singularVectors_Left_fx_e[jCh][iCh] = singularVectors_Left_e; + move16(); + } + } +#endif + /* Bidiagonal Reduction for every channel */ FOR( nCh = 0; nCh < nChannelsC; nCh++ ) /* nChannelsC */ { +#ifndef FIX_1010_OPT_SINGLE_RESCALE biDiagonalReductionLeft_fx( singularVectors_Left_fx, singularValues_fx, secDiag_fx, &singularVectors_Left_e, singularValues_fx_e, secDiag_fx_e, nChannelsL, nChannelsC, nCh, &sig_x_fx, &sig_x_fx_e, &g_fx ); biDiagonalReductionRight_fx( singularVectors_Left_fx, secDiag_fx, &singularVectors_Left_e, secDiag_fx_e, nChannelsL, nChannelsC, nCh, &sig_x_fx, &sig_x_fx_e, &g_fx ); +#else + biDiagonalReductionLeft_fx( singularVectors_Left_fx, singularValues_fx, secDiag_fx, singularVectors_Left_fx_e, singularValues_fx_e, secDiag_fx_e, nChannelsL, nChannelsC, nCh, &sig_x_fx, &sig_x_fx_e, &g_fx ); + biDiagonalReductionRight_fx( singularVectors_Left_fx, secDiag_fx, singularVectors_Left_fx_e, secDiag_fx_e, nChannelsL, nChannelsC, nCh, &sig_x_fx, &sig_x_fx_e, &g_fx ); +#endif Word16 L_temp_e; +#ifndef FIX_1010_OPT_SEC_SINGLE_RESCALE Word32 L_temp = BASOP_Util_Add_Mant32Exp( L_abs( singularValues_fx[nCh] ), singularValues_fx_e[nCh], L_abs( secDiag_fx[nCh] ), *secDiag_fx_e, &L_temp_e ); /* exp(L_temp_e) */ +#else + Word32 L_temp = BASOP_Util_Add_Mant32Exp( L_abs( singularValues_fx[nCh] ), singularValues_fx_e[nCh], L_abs( secDiag_fx[nCh] ), secDiag_fx_e[nCh], &L_temp_e ); /* exp(L_temp_e) */ +#endif IF( EQ_16( BASOP_Util_Cmp_Mant32Exp( L_temp, L_temp_e, *eps_x_fx, *eps_x_fx_e ), 1 ) ) { *eps_x_fx = L_temp; /* exp(L_temp_e) */ @@ -854,9 +1064,19 @@ static void HouseholderReduction_fx( } /* SingularVecotr Accumulation */ +#ifndef FIX_1010_OPT_SINGLE_RESCALE singularVectorsAccumulationRight_fx( singularVectors_Left_fx, singularVectors_Right_fx, secDiag_fx, singularVectors_Left_e, *secDiag_fx_e, nChannelsC ); - singularVectorsAccumulationLeft_fx( singularVectors_Left_fx, singularValues_fx, singularVectors_Left_e, singularValues_fx_e, nChannelsL, nChannelsC ); +#else +#ifndef FIX_1010_OPT_SEC_SINGLE_RESCALE + singularVectorsAccumulationRight_fx( singularVectors_Left_fx, singularVectors_Right_fx, secDiag_fx, singularVectors_Left_fx_e, *secDiag_fx_e, nChannelsC ); +#else + singularVectorsAccumulationRight_fx( singularVectors_Left_fx, singularVectors_Right_fx, secDiag_fx, singularVectors_Left_fx_e, secDiag_fx_e, nChannelsC ); +#endif + + + singularVectorsAccumulationLeft_fx( singularVectors_Left_fx, singularValues_fx, singularVectors_Left_fx_e, singularValues_fx_e, nChannelsL, nChannelsC ); +#endif return; } @@ -871,7 +1091,11 @@ static void biDiagonalReductionLeft_fx( Word32 singularVectors[][MAX_OUTPUT_CHANNELS], /* exp(singularVectors_e) */ Word32 singularValues[MAX_OUTPUT_CHANNELS], /* exp(singularValues_e) */ Word32 secDiag[MAX_OUTPUT_CHANNELS], /* exp(secDiag_e) */ +#ifndef FIX_1010_OPT_SINGLE_RESCALE Word16 *singularVectors_e, +#else + Word16 singularVectors2_e[][MAX_OUTPUT_CHANNELS], +#endif Word16 singularValues_e[MAX_OUTPUT_CHANNELS], Word16 *secDiag_e, const Word16 nChannelsL, /* Q0 */ @@ -885,17 +1109,20 @@ static void biDiagonalReductionLeft_fx( Word16 iCh, jCh, idx; Word32 norm_x, f, r; Word16 norm_x_e, f_e, r_e; - Word16 sing_exp[MAX_OUTPUT_CHANNELS]; - Word16 sing_exp2[MAX_OUTPUT_CHANNELS][MAX_OUTPUT_CHANNELS] = { 0 }; Word32 L_temp; Word16 L_temp_e; +#ifndef FIX_1010_OPT_SINGLE_RESCALE + Word16 sing_exp[MAX_OUTPUT_CHANNELS]; + Word16 sing_exp2[MAX_OUTPUT_CHANNELS][MAX_OUTPUT_CHANNELS] = { 0 }; FOR( jCh = 0; jCh < MAX_OUTPUT_CHANNELS; jCh++ ) { set16_fx( sing_exp2[jCh], *singularVectors_e, MAX_OUTPUT_CHANNELS ); } +#endif secDiag[currChannel] = Mpy_32_32( *sig_x, *g ); /* exp(sig_x_e) */ move32(); +#ifndef FIX_1010_OPT_SEC_SINGLE_RESCALE // rescaling block IF( GT_16( *sig_x_e, *secDiag_e ) ) { @@ -913,6 +1140,10 @@ ELSE IF( LT_16( *sig_x_e, *secDiag_e ) ) secDiag[currChannel] = L_shr_r( secDiag[currChannel], sub( *secDiag_e, *sig_x_e ) ); /* exp(secDiag_e) */ move32(); } +#else + secDiag_e[currChannel] = *sig_x_e; + move16(); +#endif /* Setting values to 0 */ ( *sig_x ) = 0; @@ -927,22 +1158,54 @@ IF( LT_16( currChannel, nChannelsL ) ) /* i <= m */ FOR( jCh = idx; jCh < nChannelsL; jCh++ ) /* nChannelsL */ { +#ifndef FIX_1010_OPT_SINGLE_RESCALE ( *sig_x ) = BASOP_Util_Add_Mant32Exp( *sig_x, *sig_x_e, L_abs( singularVectors[jCh][currChannel] ), *singularVectors_e, sig_x_e ); /* exp(sig_x_e) */ +#else + ( *sig_x ) = BASOP_Util_Add_Mant32Exp( *sig_x, *sig_x_e, L_abs( singularVectors[jCh][currChannel] ), singularVectors2_e[jCh][currChannel], sig_x_e ); /* exp(sig_x_e) */ +#endif } IF( ( *sig_x ) ) /*(fabsf(*sig_x) > EPSILON * fabsf(*sig_x)) { */ { +#ifdef FIX_1010_OPT_DIV + Word16 invVal_e; + Word32 invVal; + invVal = BASOP_Util_Divide3232_Scale_cadence( MAXVAL_WORD32, maxWithSign_fx( *sig_x ), &invVal_e ); +#endif norm_x = 0; move32(); norm_x_e = 0; move16(); FOR( jCh = idx; jCh < nChannelsL; jCh++ ) /* nChannelsL */ { +#ifndef FIX_1010_OPT_DIV +#ifndef FIX_1010_OPT_SINGLE_RESCALE singularVectors[jCh][currChannel] = BASOP_Util_Divide3232_Scale_cadence( singularVectors[jCh][currChannel], maxWithSign_fx( *sig_x ), &sing_exp[jCh] ); /* exp(sing_exp + (singularVectors_e - sig_x_e) */ move32(); sing_exp[jCh] = add( sing_exp[jCh], sub( *singularVectors_e, *sig_x_e ) ); move16(); norm_x = BASOP_Util_Add_Mant32Exp( norm_x, norm_x_e, Mpy_32_32( singularVectors[jCh][currChannel], singularVectors[jCh][currChannel] ), shl( sing_exp[jCh], 1 ), &norm_x_e ); /* exp(norm_x_e) */ +#else + singularVectors[jCh][currChannel] = BASOP_Util_Divide3232_Scale_cadence( singularVectors[jCh][currChannel], maxWithSign_fx( *sig_x ), &L_temp_e ); /* exp(sing_exp + (singularVectors_e - sig_x_e) */ + move32(); + singularVectors2_e[jCh][currChannel] = add( L_temp_e, sub( singularVectors2_e[jCh][currChannel], *sig_x_e ) ); + move16(); + norm_x = BASOP_Util_Add_Mant32Exp( norm_x, norm_x_e, Mpy_32_32( singularVectors[jCh][currChannel], singularVectors[jCh][currChannel] ), shl( singularVectors2_e[jCh][currChannel], 1 ), &norm_x_e ); /* exp(norm_x_e) */ +#endif +#else + Word16 temp_e = norm_l( singularVectors[jCh][currChannel] ); + singularVectors[jCh][currChannel] = Mpy_32_32( L_shl( singularVectors[jCh][currChannel], temp_e ), invVal ); /* exp(sing_exp + (singularVectors_e - sig_x_e) */ + move32(); +#ifndef FIX_1010_OPT_SINGLE_RESCALE + sing_exp[jCh] = sub( add( invVal_e, sub( *singularVectors_e, *sig_x_e ) ), temp_e ); + move16(); + norm_x = BASOP_Util_Add_Mant32Exp( norm_x, norm_x_e, Mpy_32_32( singularVectors[jCh][currChannel], singularVectors[jCh][currChannel] ), shl( sing_exp[jCh], 1 ), &norm_x_e ); /* exp(norm_x_e) */ +#else + singularVectors2_e[jCh][currChannel] = sub( add( invVal_e, sub( singularVectors2_e[jCh][currChannel], *sig_x_e ) ), temp_e ); + move16(); + norm_x = BASOP_Util_Add_Mant32Exp( norm_x, norm_x_e, Mpy_32_32( singularVectors[jCh][currChannel], singularVectors[jCh][currChannel] ), shl( singularVectors2_e[jCh][currChannel], 1 ), &norm_x_e ); /* exp(norm_x_e) */ +#endif +#endif } IF( GT_16( norm_x_e, 0 ) ) { @@ -955,7 +1218,8 @@ IF( LT_16( currChannel, nChannelsL ) ) /* i <= m */ move16(); L_temp = Sqrt32( norm_x, &L_temp_e ); L_temp = L_shl_r( L_temp, L_temp_e ); // Q31 - //( *g ) = L_negate( GE_32( singularVectors[currChannel][idx], 0 ) ? L_temp : L_negate( L_temp ) ); + //( *g ) = L_negate( GE_32( singularVectors[currChannel][idx], 0 ) ? L_temp : L_negate( L_temp ) ); +#ifndef FIX_MINOR_SVD_WMOPS_MR1010X IF( singularVectors[currChannel][idx] >= 0 ) { ( *g ) = L_negate( L_temp ); @@ -966,11 +1230,28 @@ IF( LT_16( currChannel, nChannelsL ) ) /* i <= m */ ( *g ) = L_negate( L_negate( L_temp ) ); move32(); } +#else + if ( singularVectors[currChannel][idx] >= 0 ) + { + L_temp = L_negate( L_temp ); + } + ( *g ) = L_temp; + move32(); +#endif +#ifndef FIX_1010_OPT_SINGLE_RESCALE r = BASOP_Util_Add_Mant32Exp( Mpy_32_32( ( *g ), singularVectors[currChannel][idx] ), sing_exp[currChannel], -norm_x, norm_x_e, &r_e ); /* exp(r_e) */ singularVectors[currChannel][idx] = BASOP_Util_Add_Mant32Exp( singularVectors[currChannel][idx], sing_exp[currChannel], -( *g ), 0, &sing_exp[currChannel] ); /* sing_exp */ +#else + r = BASOP_Util_Add_Mant32Exp( Mpy_32_32( ( *g ), singularVectors[currChannel][idx] ), singularVectors2_e[currChannel][idx], -norm_x, norm_x_e, &r_e ); /* exp(r_e) */ + singularVectors[currChannel][idx] = BASOP_Util_Add_Mant32Exp( singularVectors[currChannel][idx], singularVectors2_e[currChannel][idx], -( *g ), 0, &singularVectors2_e[currChannel][idx] ); /* sing_exp */ +#endif move32(); +#ifdef FIX_1010_OPT_DIV + invVal = BASOP_Util_Divide3232_Scale_cadence( MAXVAL_WORD32, maxWithSign_fx( r ), &invVal_e ); +#endif + FOR( iCh = currChannel + 1; iCh < nChannelsC; iCh++ ) /* nChannelsC */ { norm_x = 0; @@ -979,15 +1260,28 @@ IF( LT_16( currChannel, nChannelsL ) ) /* i <= m */ move16(); FOR( jCh = idx; jCh < nChannelsL; jCh++ ) /* nChannelsL */ { +#ifndef FIX_1010_OPT_SINGLE_RESCALE norm_x = BASOP_Util_Add_Mant32Exp( norm_x, norm_x_e, Mpy_32_32( singularVectors[jCh][currChannel], singularVectors[jCh][iCh] ), add( sing_exp[jCh], *singularVectors_e ), &norm_x_e ); /* exp(norm_x_e) */ +#else + norm_x = BASOP_Util_Add_Mant32Exp( norm_x, norm_x_e, Mpy_32_32( singularVectors[jCh][currChannel], singularVectors[jCh][iCh] ), add( singularVectors2_e[jCh][currChannel], singularVectors2_e[jCh][iCh] ), &norm_x_e ); /* exp(norm_x_e) */ +#endif } +#ifndef FIX_1010_OPT_DIV f = BASOP_Util_Divide3232_Scale_cadence( norm_x, maxWithSign_fx( r ), &f_e ); /* f_e + (norm_x_e - r_e) */ f_e = add( f_e, sub( norm_x_e, r_e ) ); +#else + f = Mpy_32_32( norm_x, invVal ); /* invVal_e + (norm_x_e - r_e) */ + f_e = add( invVal_e, sub( norm_x_e, r_e ) ); +#endif FOR( jCh = idx; jCh < nChannelsL; jCh++ ) /* nChannelsL */ { +#ifndef FIX_1010_OPT_SINGLE_RESCALE singularVectors[jCh][iCh] = BASOP_Util_Add_Mant32Exp( singularVectors[jCh][iCh], *singularVectors_e, Mpy_32_32( f, singularVectors[jCh][currChannel] ), add( f_e, sing_exp[jCh] ), &sing_exp2[jCh][iCh] ); /* exp( sing_exp2) */ +#else + singularVectors[jCh][iCh] = BASOP_Util_Add_Mant32Exp( singularVectors[jCh][iCh], singularVectors2_e[jCh][iCh], Mpy_32_32( f, singularVectors[jCh][currChannel] ), add( f_e, singularVectors2_e[jCh][currChannel] ), &singularVectors2_e[jCh][iCh] ); +#endif move32(); } } @@ -997,10 +1291,15 @@ IF( LT_16( currChannel, nChannelsL ) ) /* i <= m */ { singularVectors[jCh][currChannel] = Mpy_32_32( singularVectors[jCh][currChannel], ( *sig_x ) ); /* sing_exp + sig_x_e */ move32(); +#ifndef FIX_1010_OPT_SINGLE_RESCALE sing_exp2[jCh][currChannel] = add( sing_exp[jCh], *sig_x_e ); +#else + singularVectors2_e[jCh][currChannel] = add( singularVectors2_e[jCh][currChannel], *sig_x_e ); +#endif move16(); } +#ifndef FIX_1010_OPT_SINGLE_RESCALE // rescaling block Word16 exp_max = *singularVectors_e; move16(); @@ -1022,6 +1321,7 @@ IF( LT_16( currChannel, nChannelsL ) ) /* i <= m */ } *singularVectors_e = exp_max; move16(); +#endif } // rescaling block @@ -1042,9 +1342,17 @@ return; static void biDiagonalReductionRight_fx( Word32 singularVectors[][MAX_OUTPUT_CHANNELS], /* exp(singularVectors_e) */ - Word32 secDiag[MAX_OUTPUT_CHANNELS], /* exp(secDiag_e) */ + Word32 secDiag[MAX_OUTPUT_CHANNELS], /* exp(secDiag_exp[]) */ +#ifndef FIX_1010_OPT_SINGLE_RESCALE Word16 *singularVectors_e, +#else + Word16 singularVectors2_e[][MAX_OUTPUT_CHANNELS], +#endif +#ifndef FIX_1010_OPT_SEC_SINGLE_RESCALE Word16 *secDiag_e, +#else + Word16 *secDiag_exp, +#endif const Word16 nChannelsL, /* Q0 */ const Word16 nChannelsC, /* Q0 */ const Word16 currChannel, /* Q0 */ @@ -1056,16 +1364,22 @@ static void biDiagonalReductionRight_fx( Word16 iCh, jCh, idx; Word32 norm_x, r; Word16 norm_x_e, r_e; - Word16 sing_exp[MAX_OUTPUT_CHANNELS]; +#ifndef FIX_1010_OPT_SEC_SINGLE_RESCALE Word16 secDiag_exp[MAX_OUTPUT_CHANNELS]; - Word16 sing_exp2[MAX_OUTPUT_CHANNELS][MAX_OUTPUT_CHANNELS] = { 0 }; +#endif Word32 L_temp; Word16 L_temp_e; +#ifndef FIX_1010_OPT_SINGLE_RESCALE + Word16 sing_exp[MAX_OUTPUT_CHANNELS]; + Word16 sing_exp2[MAX_OUTPUT_CHANNELS][MAX_OUTPUT_CHANNELS] = { 0 }; FOR( jCh = 0; jCh < MAX_OUTPUT_CHANNELS; jCh++ ) { set16_fx( sing_exp2[jCh], *singularVectors_e, MAX_OUTPUT_CHANNELS ); } +#endif +#ifndef FIX_1010_OPT_SEC_SINGLE_RESCALE set16_fx( secDiag_exp, *secDiag_e, MAX_OUTPUT_CHANNELS ); +#endif /* Setting values to 0 */ ( *sig_x ) = 0; @@ -1079,7 +1393,11 @@ static void biDiagonalReductionRight_fx( FOR( jCh = idx; jCh < nChannelsC; jCh++ ) /* nChannelsC */ { +#ifndef FIX_1010_OPT_SINGLE_RESCALE ( *sig_x ) = BASOP_Util_Add_Mant32Exp( *sig_x, *sig_x_e, L_abs( singularVectors[currChannel][jCh] ), *singularVectors_e, sig_x_e ); /* exp(sig_x_e) */ +#else + ( *sig_x ) = BASOP_Util_Add_Mant32Exp( *sig_x, *sig_x_e, L_abs( singularVectors[currChannel][jCh] ), singularVectors2_e[currChannel][jCh], sig_x_e ); /* exp(sig_x_e) */ +#endif } IF( ( *sig_x ) ) /*(fabsf(*sig_x) > EPSILON * fabsf(*sig_x)) { */ @@ -1089,13 +1407,41 @@ static void biDiagonalReductionRight_fx( norm_x_e = 0; move16(); +#ifdef FIX_1010_OPT_DIV + Word16 invVal_e, temp_e; + Word32 invVal; + invVal = BASOP_Util_Divide3232_Scale_cadence( MAXVAL_WORD32, maxWithSign_fx( *sig_x ), &invVal_e ); +#endif FOR( jCh = idx; jCh < nChannelsC; jCh++ ) /*nChannelsC */ { +#ifndef FIX_1010_OPT_DIV +#ifndef FIX_1010_OPT_SINGLE_RESCALE singularVectors[currChannel][jCh] = BASOP_Util_Divide3232_Scale_cadence( singularVectors[currChannel][jCh], maxWithSign_fx( *sig_x ), &sing_exp[jCh] ); /* exp(sing_exp + (singularVectors_e - sig_x_e)) */ move32(); sing_exp[jCh] = add( sing_exp[jCh], sub( *singularVectors_e, *sig_x_e ) ); move16(); norm_x = BASOP_Util_Add_Mant32Exp( norm_x, norm_x_e, Mpy_32_32( singularVectors[currChannel][jCh], singularVectors[currChannel][jCh] ), shl( sing_exp[jCh], 1 ), &norm_x_e ); /* exp(norm_x_e) */ +#else + singularVectors[currChannel][jCh] = BASOP_Util_Divide3232_Scale_cadence( singularVectors[currChannel][jCh], maxWithSign_fx( *sig_x ), &L_temp_e ); /* exp(sing_exp + (singularVectors_e - sig_x_e)) */ + move32(); + singularVectors2_e[currChannel][jCh] = add( L_temp_e, sub( singularVectors2_e[currChannel][jCh], *sig_x_e ) ); + move16(); + norm_x = BASOP_Util_Add_Mant32Exp( norm_x, norm_x_e, Mpy_32_32( singularVectors[currChannel][jCh], singularVectors[currChannel][jCh] ), shl( singularVectors2_e[currChannel][jCh], 1 ), &norm_x_e ); /* exp(norm_x_e) */ +#endif +#else + temp_e = norm_l( singularVectors[currChannel][jCh] ); + singularVectors[currChannel][jCh] = Mpy_32_32( L_shl( singularVectors[currChannel][jCh], temp_e ), invVal ); /* exp(sing_exp + (singularVectors_e - sig_x_e) */ + move32(); +#ifndef FIX_1010_OPT_SINGLE_RESCALE + sing_exp[jCh] = add( sub( invVal_e, temp_e ), sub( *singularVectors_e, *sig_x_e ) ); + move16(); + norm_x = BASOP_Util_Add_Mant32Exp( norm_x, norm_x_e, Mpy_32_32( singularVectors[currChannel][jCh], singularVectors[currChannel][jCh] ), shl( sing_exp[jCh], 1 ), &norm_x_e ); /* exp(norm_x_e) */ +#else + singularVectors2_e[currChannel][jCh] = add( sub( invVal_e, temp_e ), sub( singularVectors2_e[currChannel][jCh], *sig_x_e ) ); + move16(); + norm_x = BASOP_Util_Add_Mant32Exp( norm_x, norm_x_e, Mpy_32_32( singularVectors[currChannel][jCh], singularVectors[currChannel][jCh] ), shl( singularVectors2_e[currChannel][jCh], 1 ), &norm_x_e ); /* exp(norm_x_e) */ +#endif +#endif } IF( GT_16( norm_x_e, 0 ) ) { @@ -1119,16 +1465,44 @@ static void biDiagonalReductionRight_fx( move32(); } +#ifndef FIX_1010_OPT_SINGLE_RESCALE r = BASOP_Util_Add_Mant32Exp( Mpy_32_32( ( *g ), singularVectors[currChannel][idx] ), sing_exp[idx], -norm_x, norm_x_e, &r_e ); /* exp(r_e) */ singularVectors[currChannel][idx] = BASOP_Util_Add_Mant32Exp( singularVectors[currChannel][idx], sing_exp[idx], -( *g ), 0, &sing_exp[idx] ); /* exp(sing_exp) */ +#else + r = BASOP_Util_Add_Mant32Exp( Mpy_32_32( ( *g ), singularVectors[currChannel][idx] ), singularVectors2_e[currChannel][idx], -norm_x, norm_x_e, &r_e ); /* exp(r_e) */ + singularVectors[currChannel][idx] = BASOP_Util_Add_Mant32Exp( singularVectors[currChannel][idx], singularVectors2_e[currChannel][idx], -( *g ), 0, &singularVectors2_e[currChannel][idx] ); /* exp(sing_exp) */ +#endif move32(); +#ifdef FIX_1010_OPT_DIV + invVal = BASOP_Util_Divide3232_Scale_cadence( MAXVAL_WORD32, maxWithSign_fx( r ), &invVal_e ); +#endif + FOR( jCh = idx; jCh < nChannelsC; jCh++ ) /* nChannelsC */ { +#ifndef FIX_1010_OPT_DIV +#ifndef FIX_1010_OPT_SINGLE_RESCALE secDiag[jCh] = BASOP_Util_Divide3232_Scale_cadence( singularVectors[currChannel][jCh], maxWithSign_fx( r ), &secDiag_exp[jCh] ); /* exp(secDiag_exp + (sing_exp - r_e) */ move32(); secDiag_exp[jCh] = add( secDiag_exp[jCh], sub( sing_exp[jCh], r_e ) ); move32(); +#else + secDiag[jCh] = BASOP_Util_Divide3232_Scale_cadence( singularVectors[currChannel][jCh], maxWithSign_fx( r ), &secDiag_exp[jCh] ); /* exp(secDiag_exp + (sing_exp - r_e) */ + move32(); + secDiag_exp[jCh] = add( secDiag_exp[jCh], sub( singularVectors2_e[currChannel][jCh], r_e ) ); + move32(); +#endif +#else + temp_e = norm_l( singularVectors[currChannel][jCh] ); + secDiag[jCh] = Mpy_32_32( L_shl( singularVectors[currChannel][jCh], temp_e ), invVal ); /* exp(sing_exp + (singularVectors_e - sig_x_e) */ + move32(); +#ifndef FIX_1010_OPT_SINGLE_RESCALE + secDiag_exp[jCh] = add( sub( invVal_e, temp_e ), sub( sing_exp[jCh], r_e ) ); +#else + secDiag_exp[jCh] = add( sub( invVal_e, temp_e ), sub( singularVectors2_e[currChannel][jCh], r_e ) ); +#endif + move16(); +#endif } FOR( iCh = currChannel + 1; iCh < nChannelsL; iCh++ ) /* nChannelsL */ @@ -1139,12 +1513,20 @@ static void biDiagonalReductionRight_fx( move16(); FOR( jCh = idx; jCh < nChannelsC; jCh++ ) /* nChannelsC */ { +#ifndef FIX_1010_OPT_SINGLE_RESCALE norm_x = BASOP_Util_Add_Mant32Exp( norm_x, norm_x_e, Mpy_32_32( singularVectors[iCh][jCh], singularVectors[currChannel][jCh] ), add( *singularVectors_e, sing_exp[jCh] ), &norm_x_e ); /* exp(norm_x_e) */ +#else + norm_x = BASOP_Util_Add_Mant32Exp( norm_x, norm_x_e, Mpy_32_32( singularVectors[iCh][jCh], singularVectors[currChannel][jCh] ), add( singularVectors2_e[iCh][jCh], singularVectors2_e[currChannel][jCh] ), &norm_x_e ); /* exp(norm_x_e) */ +#endif } FOR( jCh = idx; jCh < nChannelsC; jCh++ ) /* nChannelsC */ { +#ifndef FIX_1010_OPT_SINGLE_RESCALE singularVectors[iCh][jCh] = BASOP_Util_Add_Mant32Exp( singularVectors[iCh][jCh], *singularVectors_e, Mpy_32_32( norm_x, secDiag[jCh] ), add( norm_x_e, secDiag_exp[jCh] ), &sing_exp2[iCh][jCh] ); /* exp(sing_exp2) */ +#else + singularVectors[iCh][jCh] = BASOP_Util_Add_Mant32Exp( singularVectors[iCh][jCh], singularVectors2_e[iCh][jCh], Mpy_32_32( norm_x, secDiag[jCh] ), add( norm_x_e, secDiag_exp[jCh] ), &singularVectors2_e[iCh][jCh] ); /* exp(sing_exp2) */ +#endif move32(); } } @@ -1153,10 +1535,15 @@ static void biDiagonalReductionRight_fx( { singularVectors[currChannel][jCh] = Mpy_32_32( singularVectors[currChannel][jCh], ( *sig_x ) ); /* exp(sing_exp + sig_x_e) */ move32(); +#ifndef FIX_1010_OPT_SINGLE_RESCALE sing_exp2[currChannel][jCh] = add( sing_exp[jCh], *sig_x_e ); +#else + singularVectors2_e[currChannel][jCh] = add( singularVectors2_e[currChannel][jCh], *sig_x_e ); +#endif move16(); } +#ifndef FIX_1010_OPT_SEC_SINGLE_RESCALE /*rescaling block*/ Word16 exp_max = *secDiag_e; move16(); @@ -1169,8 +1556,12 @@ static void biDiagonalReductionRight_fx( secDiag[jCh] = L_shr_r( secDiag[jCh], sub( exp_max, secDiag_exp[jCh] ) ); /* exp(exp_max) */ move32(); } + *secDiag_e = exp_max; + move16(); +#endif +#ifndef FIX_1010_OPT_SINGLE_RESCALE exp_max = *singularVectors_e; move16(); FOR( iCh = 0; iCh < nChannelsL; iCh++ ) @@ -1191,6 +1582,7 @@ static void biDiagonalReductionRight_fx( } *singularVectors_e = exp_max; move16(); +#endif } } @@ -1204,9 +1596,13 @@ static void biDiagonalReductionRight_fx( *-------------------------------------------------------------------------*/ static void singularVectorsAccumulationLeft_fx( - Word32 singularVectors_Left[][MAX_OUTPUT_CHANNELS], /* exp(singularVectors_e) as Input, Q31 as output */ + Word32 singularVectors_Left[][MAX_OUTPUT_CHANNELS], /* input exp(singularVectors_Left_e), output Q31 */ Word32 singularValues[MAX_OUTPUT_CHANNELS], /* exp(singularValues_e) */ +#ifndef FIX_1010_OPT_SINGLE_RESCALE Word16 singularVectors_e, +#else + Word16 singularVectors_Left_e[][MAX_OUTPUT_CHANNELS], +#endif Word16 singularValues_e[MAX_OUTPUT_CHANNELS], const Word16 nChannelsL, /* Q0 */ const Word16 nChannelsC /* Q0 */ @@ -1216,11 +1612,13 @@ static void singularVectorsAccumulationLeft_fx( Word16 nChannels; Word32 norm_y, t_jj, t_ii; Word16 norm_y_e, t_jj_e, t_ii_e, temp_exp; +#ifndef FIX_1010_OPT_SINGLE_RESCALE Word16 sing_exp2[MAX_OUTPUT_CHANNELS][MAX_OUTPUT_CHANNELS] = { 0 }; FOR( nCh = 0; nCh < MAX_OUTPUT_CHANNELS; nCh++ ) { set16_fx( sing_exp2[nCh], singularVectors_e, MAX_OUTPUT_CHANNELS ); } +#endif /* Processing */ nChannels = s_min( nChannelsL, nChannelsC ); /* min(nChannelsL,ChannelsC) Q0*/ @@ -1240,25 +1638,58 @@ static void singularVectorsAccumulationLeft_fx( IF( t_ii ) /*if (fabsf(t_ii) > EPSILON *fabsf(t_ii)) {*/ { +#ifdef FIX_1010_OPT_DIV + t_ii = BASOP_Util_Divide3232_Scale_cadence( MAXVAL_WORD32, maxWithSign_fx( t_ii ), &temp_exp ); + t_ii_e = sub( temp_exp, t_ii_e ); +#else t_ii = BASOP_Util_Divide3232_Scale_cadence( ONE_IN_Q30, maxWithSign_fx( t_ii ), &temp_exp ); /* exp(1 + (temp_exp + tii_e)) */ t_ii_e = add( 1, sub( temp_exp, t_ii_e ) ); +#endif + Word16 tempe; + Word32 temp = BASOP_Util_Divide3232_Scale_cadence( t_ii, maxWithSign_fx( singularVectors_Left[nCh][nCh] ), &tempe ); + tempe = add( tempe, sub( t_ii_e, singularVectors_Left_e[nCh][nCh] ) ); // fprintf( fp, "%e\n", me2f( t_ii, t_ii_e ) ); FOR( iCh = nCh + 1; iCh < nChannelsC; iCh++ ) /* nChannelsC */ { - norm_y = 0; - move32(); - norm_y_e = 0; + Word64 acc = 0; + move64(); + Word64 prod[16]; + Word16 prod_e[16]; + Word16 max_e = -31; move16(); FOR( k = nCh + 1; k < nChannelsL; k++ ) /* nChannelsL */ { +#ifndef FIX_1010_OPT_SINGLE_RESCALE norm_y = BASOP_Util_Add_Mant32Exp( norm_y, norm_y_e, Mpy_32_32( singularVectors_Left[k][nCh], singularVectors_Left[k][iCh] ), add( sing_exp2[k][nCh], sing_exp2[k][iCh] ), &norm_y_e ); /* exp(norm_y_e) */ +#else + prod[k] = W_mult0_32_32( singularVectors_Left[k][nCh], singularVectors_Left[k][iCh] ); + prod_e[k] = add( singularVectors_Left_e[k][nCh], singularVectors_Left_e[k][iCh] ); + max_e = s_max( max_e, prod_e[k] ); +#endif } - t_jj = BASOP_Util_Divide3232_Scale_cadence( Mpy_32_32( t_ii, norm_y ), maxWithSign_fx( singularVectors_Left[nCh][nCh] ), &temp_exp ); // t_ii_e+norm_y_e-*singularVectors_e, - t_jj_e = add( temp_exp, sub( add( t_ii_e, norm_y_e ), sing_exp2[nCh][nCh] ) ); + FOR( k = nCh + 1; k < nChannelsL; k++ ) /* nChannelsL */ + { + acc = W_add( acc, W_shr( prod[k], sub( max_e, prod_e[k] ) ) ); + } + Word16 acc_e = W_norm( acc ); + acc = W_shl( acc, acc_e ); + + norm_y = W_extract_h( acc ); + norm_y_e = add( sub( max_e, acc_e ), 1 ); + t_jj = Mpy_32_32( temp, norm_y ); +#ifndef FIX_1010_OPT_SINGLE_RESCALE + t_jj_e = add( temp_exp, sub( add( t_ii_e, norm_y_e ), sing_exp2[nCh][nCh] ) ); +#else + t_jj_e = add( tempe, norm_y_e ); +#endif FOR( k = nCh; k < nChannelsL; k++ ) /* nChannelsL */ { +#ifndef FIX_1010_OPT_SINGLE_RESCALE singularVectors_Left[k][iCh] = BASOP_Util_Add_Mant32Exp( singularVectors_Left[k][iCh], sing_exp2[k][iCh], Mpy_32_32( t_jj, singularVectors_Left[k][nCh] ), add( t_jj_e, sing_exp2[k][nCh] ), &sing_exp2[k][iCh] ); /* exp(sing_exp2) */ +#else + singularVectors_Left[k][iCh] = BASOP_Util_Add_Mant32Exp( singularVectors_Left[k][iCh], singularVectors_Left_e[k][iCh], Mpy_32_32( t_jj, singularVectors_Left[k][nCh] ), add( t_jj_e, singularVectors_Left_e[k][nCh] ), &singularVectors_Left_e[k][iCh] ); /* exp(sing_exp2) */ +#endif move32(); } } @@ -1267,7 +1698,11 @@ static void singularVectorsAccumulationLeft_fx( { singularVectors_Left[iCh][nCh] = Mpy_32_32( singularVectors_Left[iCh][nCh], t_ii ); /* exp(sing_exp2 + t_ii_e) */ move32(); +#ifndef FIX_1010_OPT_SINGLE_RESCALE sing_exp2[iCh][nCh] = add( sing_exp2[iCh][nCh], t_ii_e ); +#else + singularVectors_Left_e[iCh][nCh] = add( singularVectors_Left_e[iCh][nCh], t_ii_e ); +#endif move16(); } } @@ -1279,8 +1714,11 @@ static void singularVectorsAccumulationLeft_fx( move32(); } } - +#ifndef FIX_1010_OPT_SINGLE_RESCALE singularVectors_Left[nCh][nCh] = BASOP_Util_Add_Mant32Exp( singularVectors_Left[nCh][nCh], sing_exp2[nCh][nCh], ONE_IN_Q30, 1, &sing_exp2[nCh][nCh] ); /* exp(sing_exp2) */ +#else + singularVectors_Left[nCh][nCh] = BASOP_Util_Add_Mant32Exp( singularVectors_Left[nCh][nCh], singularVectors_Left_e[nCh][nCh], ONE_IN_Q30, 1, &singularVectors_Left_e[nCh][nCh] ); /* exp(sing_exp2) */ +#endif move32(); } // fclose(fp); @@ -1288,7 +1726,11 @@ static void singularVectorsAccumulationLeft_fx( { FOR( iCh = 0; iCh < nChannelsC; iCh++ ) { +#ifndef FIX_1010_OPT_SINGLE_RESCALE singularVectors_Left[nCh][iCh] = L_shl_sat( singularVectors_Left[nCh][iCh], sing_exp2[nCh][iCh] ); /* Q31 */ +#else + singularVectors_Left[nCh][iCh] = L_shl_sat( singularVectors_Left[nCh][iCh], singularVectors_Left_e[nCh][iCh] ); /* Q31 */ +#endif move32(); } } @@ -1303,11 +1745,19 @@ static void singularVectorsAccumulationLeft_fx( *-------------------------------------------------------------------------*/ static void singularVectorsAccumulationRight_fx( - Word32 singularVectors_Left[][MAX_OUTPUT_CHANNELS], /* exp(singularVectors_e) */ - Word32 singularVectors_Right[][MAX_OUTPUT_CHANNELS], /* exp(singularVectors_e) */ + Word32 singularVectors_Left[][MAX_OUTPUT_CHANNELS], /* exp(singularVectors_Left_e) */ + Word32 singularVectors_Right[][MAX_OUTPUT_CHANNELS], /* input exp(singularVectors_Left_e), output Q31 */ Word32 secDiag[MAX_OUTPUT_CHANNELS], /* exp(secDiag_e) */ +#ifndef FIX_1010_OPT_SINGLE_RESCALE Word16 singularVectors_e, +#else + Word16 singularVectors_Left_e[][MAX_OUTPUT_CHANNELS], +#endif +#ifndef FIX_1010_OPT_SEC_SINGLE_RESCALE Word16 secDiag_e, +#else + Word16 *secDiag_e, +#endif const Word16 nChannelsC /* Q0 */ ) { @@ -1320,7 +1770,7 @@ static void singularVectorsAccumulationRight_fx( nChannels = nChannelsC; /* nChannelsC Q0*/ /* avoid compiler warning */ - t_ii = secDiag[nChannels - 1]; /* exp(secDiag_e) */ + t_ii = secDiag[nChannels - 1]; /* exp(secDiag_e[nChannels - 1]) */ move32(); FOR( nCh = nChannels - 1; nCh >= 0; nCh-- ) /* nChannelsC, min(nChannelsLmnChannelsC) otherwise */ @@ -1333,10 +1783,22 @@ static void singularVectorsAccumulationRight_fx( FOR( iCh = nCh + 1; iCh < nChannelsC; iCh++ ) /* nChannelsC*/ { +#ifdef FIX_1010_OPT_DIV + ratio_float = L_deposit_h( BASOP_Util_Divide3232_Scale( singularVectors_Left[nCh][iCh], maxWithSign_fx( singularVectors_Left[nCh][nCh + 1] ), &temp_exp1 ) ); /* exp(temp_exp1) */ + singularVectors_Right[iCh][nCh] = L_deposit_h( BASOP_Util_Divide3232_Scale( ratio_float, maxWithSign_fx( t_ii ), &sing_right_exp[iCh][nCh] ) ); /* exp(sing_right_exp + (temp_exp1 - secDiag_e) */ +#else ratio_float = BASOP_Util_Divide3232_Scale_cadence( singularVectors_Left[nCh][iCh], maxWithSign_fx( singularVectors_Left[nCh][nCh + 1] ), &temp_exp1 ); /* exp(temp_exp1) */ singularVectors_Right[iCh][nCh] = BASOP_Util_Divide3232_Scale_cadence( ratio_float, maxWithSign_fx( t_ii ), &sing_right_exp[iCh][nCh] ); /* exp(sing_right_exp + (temp_exp1 - secDiag_e) */ +#endif +#ifdef FIX_1010_OPT_SINGLE_RESCALE + temp_exp1 = add( temp_exp1, sub( singularVectors_Left_e[nCh][iCh], singularVectors_Left_e[nCh][nCh + 1] ) ); +#endif move32(); +#ifndef FIX_1010_OPT_SEC_SINGLE_RESCALE sing_right_exp[iCh][nCh] = add( sing_right_exp[iCh][nCh], sub( temp_exp1, secDiag_e ) ); +#else + sing_right_exp[iCh][nCh] = add( sing_right_exp[iCh][nCh], sub( temp_exp1, secDiag_e[nCh + 1] ) ); +#endif move16(); // singularVectors_Right[iCh][nCh] = L_shl_sat( singularVectors_Right[iCh][nCh], temp_exp2 ); } @@ -1350,7 +1812,11 @@ static void singularVectorsAccumulationRight_fx( FOR( k = nCh + 1; k < nChannelsC; k++ ) /* nChannelsC */ { +#ifndef FIX_1010_OPT_SINGLE_RESCALE norm_y = BASOP_Util_Add_Mant32Exp( norm_y, norm_y_e, Mpy_32_32( singularVectors_Left[nCh][k], singularVectors_Right[k][iCh] ), add( singularVectors_e, sing_right_exp[k][iCh] ), &norm_y_e ); /* exp(norm_y_e) */ +#else + norm_y = BASOP_Util_Add_Mant32Exp( norm_y, norm_y_e, Mpy_32_32( singularVectors_Left[nCh][k], singularVectors_Right[k][iCh] ), add( singularVectors_Left_e[nCh][k], sing_right_exp[k][iCh] ), &norm_y_e ); /* exp(norm_y_e) */ +#endif } FOR( k = nCh + 1; k < nChannelsC; k++ ) /* nChannelsC */ @@ -1374,7 +1840,7 @@ static void singularVectorsAccumulationRight_fx( } singularVectors_Right[nCh][nCh] = MAX_32; move32(); - t_ii = secDiag[nCh]; /* exp(secDiag_e) */ + t_ii = secDiag[nCh]; /* exp(secDiag_e[nCh]) */ move32(); } return; @@ -1386,6 +1852,31 @@ static void singularVectorsAccumulationRight_fx( * *-------------------------------------------------------------------------*/ + +#ifdef FIX_1010_OPT_GIVENS_INV +static void GivensRotation2_fx( + const Word32 x, /* exp(x_e) */ + const Word16 x_e, + const Word32 z, /* exp(z_e) */ + const Word16 z_e, + Word32 *result, + Word32 *resultInv, + Word16 *out_e, + Word16 *outInv_e ) +{ + Word32 r; + r = BASOP_Util_Add_Mant32Exp( Mpy_32_32( z, z ), shl( z_e, 1 ), Mpy_32_32( x, x ), shl( x_e, 1 ), out_e ); + r = L_max( r, 1 ); + *outInv_e = *out_e; + move16(); + *result = Sqrt32( r, out_e ); + move32(); + + *resultInv = ISqrt32( r, outInv_e ); + move32(); +} +#endif + static Word32 GivensRotation_fx( const Word32 x, /* exp(x_e) */ const Word16 x_e, @@ -1393,10 +1884,19 @@ static Word32 GivensRotation_fx( const Word16 z_e, Word16 *out_e ) { +#ifdef FIX_1010_OPT_GIVENS + Word32 r; +#else Word32 x_abs, z_abs; Word32 cotan, tan, r; Word16 temp_exp; Word32 L_temp; +#endif + +#ifdef FIX_1010_OPT_GIVENS + r = BASOP_Util_Add_Mant32Exp( Mpy_32_32( z, z ), shl( z_e, 1 ), Mpy_32_32( x, x ), shl( x_e, 1 ), out_e ); + r = Sqrt32( r, out_e ); +#else x_abs = L_abs( x ); z_abs = L_abs( z ); test(); @@ -1439,7 +1939,7 @@ static Word32 GivensRotation_fx( *out_e = add( z_e, temp_exp ); } } - +#endif return ( r ); } @@ -1453,6 +1953,7 @@ static Word32 maxWithSign_fx( const Word32 a /* Qx */ ) { +#ifndef FIX_MINOR_SVD_WMOPS_MR1010X IF( GT_32( L_abs( a ), SVD_MINIMUM_VALUE_FX ) ) { return a; @@ -1465,6 +1966,18 @@ static Word32 maxWithSign_fx( { return SVD_MINIMUM_VALUE_FX; } +#else + Word32 result; + IF( a >= 0 ) + { + result = L_max( a, SVD_MINIMUM_VALUE_FX ); + } + ELSE + { + result = L_min( a, -SVD_MINIMUM_VALUE_FX ); + } + return result; +#endif } /*------------------------------------------------------------------------- diff --git a/lib_dec/ivas_tcx_core_dec.c b/lib_dec/ivas_tcx_core_dec_fx.c similarity index 99% rename from lib_dec/ivas_tcx_core_dec.c rename to lib_dec/ivas_tcx_core_dec_fx.c index d3a3d7bc60a9141b2b105b634ca0958528f44a38..07eba9e6420b1fb940e78273467317b8d61ae136 100644 --- a/lib_dec/ivas_tcx_core_dec.c +++ b/lib_dec/ivas_tcx_core_dec_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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,14 +34,12 @@ #include #include "options.h" #include -#include "prot.h" +#include "prot_fx.h" #include "rom_com.h" #include "stat_dec.h" #include "wmc_auto.h" #include "basop_proto_func.h" #include "stat_com.h" -#include "ivas_prot.h" -#include "prot_fx.h" #include "ivas_prot_fx.h" /*-------------------------------------------------------------* diff --git a/lib_dec/ivas_td_low_rate_dec.c b/lib_dec/ivas_td_low_rate_dec_fx.c similarity index 95% rename from lib_dec/ivas_td_low_rate_dec.c rename to lib_dec/ivas_td_low_rate_dec_fx.c index 7df267b1d648efc5ceb1e6bc86247b0cc403ef35..98c1a6a79dd6fcd080752f1b40a09f483c7cf8da 100644 --- a/lib_dec/ivas_td_low_rate_dec.c +++ b/lib_dec/ivas_td_low_rate_dec_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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 "rom_com.h" #include "ivas_rom_com.h" #include "ivas_cnst.h" -#include "prot.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "wmc_auto.h" #include "ivas_prot_fx.h" void tdm_low_rate_dec_fx( @@ -139,8 +137,21 @@ void tdm_low_rate_dec_fx( edct_16fx( exc_wo_nf_fx, exc_wo_nf_fx, L_FRAME, find_guarded_bits_fx( L_FRAME ), IVAS_CPE_TD ); +#ifdef FIX_USAN_ISSUES + IF( bwe_exc != NULL ) + { + Rescale_exc( st->hMusicPF->dct_post_old_exc_fx, &exc[0], &bwe_exc[0], st->hGSCDec->last_exc_dct_in_fx, + L_FRAME, L_FRAME * HIBND_ACB_L_FAC, L_shl( st->lp_gainc_fx, 13 /* Q3 -> Q16*/ ), &( st->Q_exc ), st->Q_subfr, NULL, 0, st->coder_type ); + } + ELSE + { + Rescale_exc( st->hMusicPF->dct_post_old_exc_fx, &exc[0], NULL, st->hGSCDec->last_exc_dct_in_fx, + L_FRAME, L_FRAME * HIBND_ACB_L_FAC, L_shl( st->lp_gainc_fx, 13 /* Q3 -> Q16*/ ), &( st->Q_exc ), st->Q_subfr, NULL, 0, st->coder_type ); + } +#else Rescale_exc( st->hMusicPF->dct_post_old_exc_fx, &exc[0], &bwe_exc[0], st->hGSCDec->last_exc_dct_in_fx, L_FRAME, L_FRAME * HIBND_ACB_L_FAC, L_shl( st->lp_gainc_fx, 13 /* Q3 -> Q16*/ ), &( st->Q_exc ), st->Q_subfr, NULL, 0, st->coder_type ); +#endif /*----------------------------------------------------------------------* * Remove potential pre-echo in case an onset has been detected *----------------------------------------------------------------------*/ diff --git a/lib_dec/jbm_jb4_circularbuffer.c b/lib_dec/jbm_jb4_circularbuffer.c index bc12026c9520a90fc69c64e830efb4d89787fec1..f9d6d1ca148c39a2c2891ace4451261d119a2458 100644 --- a/lib_dec/jbm_jb4_circularbuffer.c +++ b/lib_dec/jbm_jb4_circularbuffer.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other @@ -38,7 +38,7 @@ #include #include "options.h" #include "string.h" -#include "prot.h" +#include "prot_fx.h" #include "wmc_auto.h" /* local includes */ #include "jbm_jb4_circularbuffer.h" diff --git a/lib_dec/jbm_jb4_circularbuffer.h b/lib_dec/jbm_jb4_circularbuffer.h index ec6a5c7becc4f0e347f2a7ee2ee3fe08b9c9badb..9e3102feba4dee6b3812f2aca4cdd5c6b7461c20 100644 --- a/lib_dec/jbm_jb4_circularbuffer.h +++ b/lib_dec/jbm_jb4_circularbuffer.h @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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,7 +37,7 @@ #ifndef JBM_JB4_CIRCULARBUFFER_H #define JBM_JB4_CIRCULARBUFFER_H JBM_JB4_CIRCULARBUFFER_H -#include "prot.h" +#include "prot_fx.h" #include "cnst.h" /** handle for circular buffer (FIFO) with fixed capacity */ diff --git a/lib_dec/jbm_jb4_inputbuffer.c b/lib_dec/jbm_jb4_inputbuffer.c index 27a1d6ff1f49c1e4cddba644eafe622c1f791692..5497a437126a701eccbc82e1aad6bf352a654f06 100644 --- a/lib_dec/jbm_jb4_inputbuffer.c +++ b/lib_dec/jbm_jb4_inputbuffer.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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,7 +39,7 @@ #include #include #include "options.h" -#include "prot.h" +#include "prot_fx.h" #include "string.h" #include "jbm_jb4_inputbuffer.h" #include "wmc_auto.h" diff --git a/lib_dec/jbm_jb4_inputbuffer.h b/lib_dec/jbm_jb4_inputbuffer.h index b9c9c5ef6e79e367822266096229c19d428468e0..769cccba68424358d328d32f01c540de96d5904d 100644 --- a/lib_dec/jbm_jb4_inputbuffer.h +++ b/lib_dec/jbm_jb4_inputbuffer.h @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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_dec/jbm_jb4_jmf.c b/lib_dec/jbm_jb4_jmf.c index 8e5215dae2b3aad8fa6fff643f5bbe8c79742c0f..5ab8242c75bbbd078d3fbc6ddc30ee102bf1b224 100644 --- a/lib_dec/jbm_jb4_jmf.c +++ b/lib_dec/jbm_jb4_jmf.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other @@ -42,7 +42,7 @@ #include #include #include "options.h" -#include "prot.h" +#include "prot_fx.h" #include "wmc_auto.h" /* local includes */ diff --git a/lib_dec/jbm_jb4_jmf.h b/lib_dec/jbm_jb4_jmf.h index b08f5502cfbacc72343c1ec4c3369becb5222e62..6b5a004348d06f61385b761e1fc1e454d84041c8 100644 --- a/lib_dec/jbm_jb4_jmf.h +++ b/lib_dec/jbm_jb4_jmf.h @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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_dec/jbm_jb4sb.c b/lib_dec/jbm_jb4sb.c index a19f8bfd7275aeef05bafa9b191a20b0868c4495..002b4bc109985558a4bf8769317309d597cb8aca 100644 --- a/lib_dec/jbm_jb4sb.c +++ b/lib_dec/jbm_jb4sb.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other @@ -48,7 +48,6 @@ #include "jbm_jb4_inputbuffer.h" #include "jbm_jb4_jmf.h" #include "jbm_jb4sb.h" -#include "prot.h" #include "prot_fx.h" #define WMC_TOOL_SKIP diff --git a/lib_dec/jbm_jb4sb.h b/lib_dec/jbm_jb4sb.h index 55565be4aaf9cbcce1936d748a37aeae180f3706..5b5ff16c5f2a19c2e06b74cf8bd1e456feeb8545 100644 --- a/lib_dec/jbm_jb4sb.h +++ b/lib_dec/jbm_jb4sb.h @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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,7 +67,7 @@ struct JB4_DATAUNIT Word16 qBit; /** the binary encoded access unit */ - uint8_t *data; + UWord8 *data; /** the size of the binary encoded access unit [bits] */ UWord16 dataSize; diff --git a/lib_dec/jbm_pcmdsp_apa.c b/lib_dec/jbm_pcmdsp_apa.c index 92aee035eb8f5e99de09856e6572b41d7ceabe8a..fc793dff01c72047684bc8a5db1fe53ab98f5644 100644 --- a/lib_dec/jbm_pcmdsp_apa.c +++ b/lib_dec/jbm_pcmdsp_apa.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other @@ -44,7 +44,7 @@ #include #include #include "options.h" -#include "prot.h" +#include "prot_fx.h" #include "wmc_auto.h" /* local headers */ #include "jbm_pcmdsp_apa.h" @@ -54,7 +54,6 @@ #include "rom_dec.h" -#include "prot_fx.h" #define INV_100_Q15 328 #define INV_400_Q15 82 #define INV_80_Q15 410 @@ -901,7 +900,7 @@ UWord8 apa_exec_ivas_fx( UWord32 statsResetThreshold, statsResetShift; Word16 Q_a_out; - Q_a_out = add( getScaleFactor32_copy( a_in, L_mult0( ps->num_channels, APA_BUF_PER_CHANNEL ) ), Q11 - Q16 ); + Q_a_out = add( getScaleFactor32_copy( a_in, L_mult0( ps->num_channels, APA_BUF_PER_CHANNEL ) ), Q11 - Q16 - Q1 ); statsResetThreshold = 1637; move32(); statsResetShift = 2; diff --git a/lib_dec/jbm_pcmdsp_apa.h b/lib_dec/jbm_pcmdsp_apa.h index 7acdf599cf5158690e64726af6ab091a7f4c891d..7955d0ea6e1b86aa6be7d6dcab90b331ef7c463f 100644 --- a/lib_dec/jbm_pcmdsp_apa.h +++ b/lib_dec/jbm_pcmdsp_apa.h @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other @@ -92,7 +92,7 @@ typedef struct apa_state_t *PCMDSP_APA_HANDLE; /*! Allocates memory for state struct and initializes elements. * @return 0 on success, 1 on failure */ ivas_error apa_init( apa_state_t **s, - const int32_t num_channels ); + const Word32 num_channels ); /*! Sets state variables to initial value. */ void apa_reset( apa_state_t *s ); @@ -106,7 +106,7 @@ void apa_reset( apa_state_t *s ); * @param[in] output_Fs sample rate [Hz] * @param[in] num_channels number of channels * @return 0 on success, 1 on failure */ -bool apa_set_rate( apa_state_t *ps, const int32_t output_Fs ); +bool apa_set_rate( apa_state_t *ps, const Word32 output_Fs ); /*! Set scaling. * The scale is given in % and will be valid until changed again. @@ -120,7 +120,7 @@ bool apa_set_renderer_residual_samples( apa_state_t *ps, UWord16 l_r_buf ); bool apa_set_evs_compat_mode( apa_state_t *ps, bool mode ); -uint8_t apa_reconfigure( apa_state_t *ps, uint16_t num_channels, uint16_t l_ts ); +UWord8 apa_reconfigure( apa_state_t *ps, UWord16 num_channels, UWord16 l_ts ); bool apa_set_complexity_options( apa_state_t *s, UWord16 wss, UWord16 css ); @@ -129,5 +129,5 @@ bool apa_set_quality( apa_state_t *s, Word32 quality, UWord16 qualityred, UWord1 bool apa_exit( apa_state_t **s ); UWord8 apa_exec_ivas_fx( apa_state_t *s, const Word32 a_in[], UWord16 l_in, UWord16 maxScaling, Word32 a_out[], UWord16 *l_out ); -uint8_t apa_exec_fx( apa_state_t *s, const Word16 a_in[], UWord16 l_in, UWord16 maxScaling, Word16 a_out[], UWord16 *l_out ); +UWord8 apa_exec_fx( apa_state_t *s, const Word16 a_in[], UWord16 l_in, UWord16 maxScaling, Word16 a_out[], UWord16 *l_out ); #endif /* JBM_PCMDSP_APA_H */ diff --git a/lib_dec/jbm_pcmdsp_fifo.c b/lib_dec/jbm_pcmdsp_fifo.c deleted file mode 100644 index 35a08b2de5c6d62f795c7da74b428dd579740388..0000000000000000000000000000000000000000 --- a/lib_dec/jbm_pcmdsp_fifo.c +++ /dev/null @@ -1,40 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -/*! @file jbm_pcmdsp_fifo.c Ringbuffer (FIFO) with fixed capacity for audio samples */ - -#include -#include "options.h" diff --git a/lib_dec/jbm_pcmdsp_fifo.h b/lib_dec/jbm_pcmdsp_fifo.h index 12b7f5b141af74256dddcc640eec36f06e5f57ef..1375c5713eba5c5cb67d29f43bfb546d59bc3527 100644 --- a/lib_dec/jbm_pcmdsp_fifo.h +++ b/lib_dec/jbm_pcmdsp_fifo.h @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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_dec/jbm_pcmdsp_similarityestimation.c b/lib_dec/jbm_pcmdsp_similarityestimation.c index b6eeaf0e1856fe28e137b3ae6a02871179854dca..cc13c0148d23a45b7a154bb93fc2ce91fa1ccc10 100644 --- a/lib_dec/jbm_pcmdsp_similarityestimation.c +++ b/lib_dec/jbm_pcmdsp_similarityestimation.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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_dec/jbm_pcmdsp_similarityestimation.h b/lib_dec/jbm_pcmdsp_similarityestimation.h index 123d0c3c1590adfb82cc47189362d74d27ed54b2..086f881814e1583db970c97716bb09955f988e32 100644 --- a/lib_dec/jbm_pcmdsp_similarityestimation.h +++ b/lib_dec/jbm_pcmdsp_similarityestimation.h @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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_dec/jbm_pcmdsp_window.c b/lib_dec/jbm_pcmdsp_window.c index ea15ab7a1f62ff8357cc4eae0284c88a7cd45632..eba40ec988241af9b0b4385df9b56e935053ab17 100644 --- a/lib_dec/jbm_pcmdsp_window.c +++ b/lib_dec/jbm_pcmdsp_window.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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_dec/jbm_pcmdsp_window.h b/lib_dec/jbm_pcmdsp_window.h index 9102e027fdd819941da2769ee5b017737f957389..1d193433e7b90f55d7a22902932a7bdaf19f17c2 100644 --- a/lib_dec/jbm_pcmdsp_window.h +++ b/lib_dec/jbm_pcmdsp_window.h @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other @@ -52,7 +52,7 @@ * <------> * n */ -void hannWindow( uint16_t n, float *w ); +void hannWindow( UWord16 n, float *w ); /** Overlap/Add of two signal with a given window. */ /** @param[in] fadeOut signal to fade out diff --git a/lib_dec/lead_deindexing.c b/lib_dec/lead_deindexing.c deleted file mode 100644 index dbe4a43e8d21c2682e0669da08da8c5369da002b..0000000000000000000000000000000000000000 --- a/lib_dec/lead_deindexing.c +++ /dev/null @@ -1,47 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include "cnst.h" -#include "prot.h" -#include "rom_com.h" -#include "rom_dec.h" -#include "wmc_auto.h" - -/*-------------------------------------------------------------------* - * Local function prototypes - *-------------------------------------------------------------------*/ diff --git a/lib_dec/lib_dec.c b/lib_dec/lib_dec.c deleted file mode 100644 index 8e228facb113dd5ca182532f116487e21d51ef8c..0000000000000000000000000000000000000000 --- a/lib_dec/lib_dec.c +++ /dev/null @@ -1,37 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -#include -#include -#include -#include "lib_dec.h" -#include "wmc_auto.h" diff --git a/lib_dec/lib_dec.h b/lib_dec/lib_dec.h index 28fbe71b965eed19a235fc4fafbec512d504dacb..999e15328b57e9f7ff485dacb6ac7610cc476840 100644 --- a/lib_dec/lib_dec.h +++ b/lib_dec/lib_dec.h @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other @@ -144,6 +144,46 @@ ivas_error IVAS_DEC_GetSamples( bool *needNewFrame /* o : indication that the decoder needs a new frame */ ); +#ifdef SPLIT_REND_WITH_HEAD_ROT +ivas_error IVAS_DEC_GetSplitBinauralBitstream( + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + Word16 *pcmBuf_out, /* o : output synthesis signal for BINAURAL_SPLIT_PCM */ + ISAR_SPLIT_REND_BITS_DATA *splitRendBits, /* o : output split rendering bits */ + Word16 *nOutSamples, /* o : number of samples per channel written to output buffer */ + bool *needNewFrame /* o : indication that the decoder needs a new frame */ +); + +/*! r: decoder error code */ +ivas_error IVAS_DEC_GetSplitRendBitstreamHeader( + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + ISAR_SPLIT_REND_CODEC *pCodec, /* o: pointer to codec setting */ + ISAR_SPLIT_REND_POSE_CORRECTION_MODE *poseCorrection, /* o: pointer to pose correction mode */ +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + Word16 *pIsar_frame_size_ms, /* o: pointer to isar frame size setting */ +#endif + Word16 *pCodec_frame_size_ms /* o: pointer to codec frame size setting */ +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + , + Word16 *pLc3plusHighRes /* o: pointer to LC3plus High-Res setting */ +#endif +); + +/*! r: decoder error code */ +ivas_error IVAS_DEC_GetCldfbSamples( + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + Word32 *out_real, /* o : buffer for decoded PCM real output in CLDFB domain */ + Word32 *out_imag, /* o : buffer for decoded PCM imag output in CLDFB domain */ + IVAS_AUDIO_CONFIG *audio_config, /* o : audio configuration */ + Word16 *nOutSamples /* o : number of samples per channel written to output buffer */ +); + +int16_t IVAS_DEC_is_split_rendering_enabled( + IVAS_DEC_HANDLE hIvasDec /* i: IVAS decoder handle */ +); +int16_t IVAS_DEC_is_split_rendering_coded_out( + IVAS_DEC_HANDLE hIvasDec /* i/o: IVAS decoder handle */ +); +#endif /*! r: error code */ ivas_error IVAS_DEC_GetObjectMetadata( @@ -165,7 +205,12 @@ ivas_error IVAS_DEC_FeedHeadTrackData( IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ IVAS_QUATERNION orientation, /* i : head-tracking data, listener orientation */ IVAS_VECTOR3 Pos, /* i : listener position */ - const Word16 subframe_idx /* i : subframe index */ +#ifdef SPLIT_REND_WITH_HEAD_ROT + const Word16 subframe_idx, /* i : subframe index */ + const ISAR_SPLIT_REND_ROT_AXIS rot_axis /* i : external control for rotation axis for split rendering */ +#else + const Word16 subframe_idx /* i : subframe index */ +#endif ); /*! r: error code */ @@ -242,6 +287,12 @@ ivas_error IVAS_DEC_EnableVoIP( const IVAS_DEC_INPUT_FORMAT inputFormat /* i : format of the input bitstream */ ); +#ifdef SPLIT_REND_WITH_HEAD_ROT +/*! r: error code */ +ivas_error IVAS_DEC_EnableSplitRendering( + IVAS_DEC_HANDLE hIvasDec /* i/o: IVAS decoder handle */ +); +#endif ivas_error IVAS_DEC_SetRenderFramesize( IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ diff --git a/lib_dec/lib_dec_fx.c b/lib_dec/lib_dec_fx.c index b63668b3874d3c812333b36f1af70fcba5691a06..561384c87e3c2fd7e408cefecfa6dfd9e57a7e46 100644 --- a/lib_dec/lib_dec_fx.c +++ b/lib_dec/lib_dec_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other @@ -35,15 +35,20 @@ #include #include #include "ivas_cnst.h" -#include "ivas_prot.h" -#include "ivas_prot_rend.h" -#include "prot.h" -#include "ivas_prot_fx.h" +#include "ivas_prot_rend_fx.h" #include "prot_fx.h" +#include "isar_prot.h" +#include "lib_isar_pre_rend.h" +#include "ivas_prot_fx.h" #include "jbm_jb4sb.h" #include "jbm_pcmdsp_apa.h" #include "jbm_pcmdsp_fifo.h" +#include +#include +#ifndef FIX_DISCLAIMER +#include +#endif #include "wmc_auto.h" #define INV_1000_Q31 2147484 /*1/1000 IN Q31*/ @@ -112,7 +117,11 @@ static ivas_error IVAS_DEC_RendererFeedTcSamples( IVAS_DEC_HANDLE hIvasDec, cons static ivas_error IVAS_DEC_GetRenderedSamples( IVAS_DEC_HANDLE hIvasDec, const UWord16 nSamplesForRendering, UWord16 *nSamplesRendered, UWord16 *nSamplesAvailableNext, Word16 *pcmBuf ); static ivas_error IVAS_DEC_GetBufferedNumberOfSamples( IVAS_DEC_HANDLE hIvasDec, Word16 *nSamplesBuffered ); static Word16 get_render_frame_size_ms( IVAS_RENDER_FRAMESIZE render_framesize ); - +#ifdef SPLIT_REND_WITH_HEAD_ROT +static ivas_error isar_set_split_rend_setup( ISAR_DEC_SPLIT_REND_WRAPPER *hSplitBinRend, const ISAR_SPLIT_REND_CONFIG_DATA *hSplitBinConfig, const COMBINED_ORIENTATION_HANDLE hCombinedOrientationData, ISAR_SPLIT_REND_BITS_DATA *splitRendBits ); +static ivas_error ivas_create_handle_isar( ISAR_DEC_SPLIT_REND_WRAPPER_HANDLE *hSplitBinRend_out ); +static void ivas_destroy_handle_isar( ISAR_DEC_SPLIT_REND_WRAPPER_HANDLE *hSplitBinRend_out ); +#endif /*---------------------------------------------------------------------* * IVAS_DEC_Open() @@ -270,6 +279,46 @@ ivas_error IVAS_DEC_Open( return IVAS_ERR_WRONG_PARAMS; } +#ifdef SPLIT_REND_WITH_HEAD_ROT +/*-------------------------------------------------------------------------* + * isar_set_split_rend_setup() + * + * Setup IVAS split rendering + *-------------------------------------------------------------------------*/ + +static ivas_error isar_set_split_rend_setup( + ISAR_DEC_SPLIT_REND_WRAPPER *hSplitBinRend, + const ISAR_SPLIT_REND_CONFIG_DATA *hSplitBinConfig, + const COMBINED_ORIENTATION_HANDLE hCombinedOrientationData, + ISAR_SPLIT_REND_BITS_DATA *splitRendBits /* o : output split rendering bits */ +) +{ + splitRendBits->bits_read = 0; + splitRendBits->bits_written = 0; + splitRendBits->buf_len = ISAR_MAX_SPLIT_REND_BITS_BUFFER_SIZE_IN_BYTES; + splitRendBits->codec = ISAR_SPLIT_REND_CODEC_DEFAULT; + splitRendBits->pose_correction = ISAR_SPLIT_REND_POSE_CORRECTION_MODE_NONE; + splitRendBits->codec_frame_size_ms = 0; +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + splitRendBits->isar_frame_size_ms = 0; + splitRendBits->lc3plus_highres = 0; +#endif + + if ( ( hSplitBinRend->hMultiBinCldfbData = (ISAR_DEC_SPLIT_REND_MULTI_BIN_CLDFB_DATA_HANDLE) malloc( sizeof( ISAR_DEC_SPLIT_REND_MULTI_BIN_CLDFB_DATA ) ) ) == NULL ) + { + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Cannot allocate memory for split rendering structure" ); + } + + ISAR_PRE_REND_GetMultiBinPoseData( hSplitBinConfig, &hSplitBinRend->splitrend.multiBinPoseData, ( hCombinedOrientationData != NULL ) ? hCombinedOrientationData->sr_pose_pred_axis : DEFAULT_AXIS ); + + if ( hCombinedOrientationData != NULL ) + { + isar_set_split_rend_ht_setup_fx( &hSplitBinRend->splitrend, hCombinedOrientationData->Quaternions, hCombinedOrientationData->Rmat_fx ); + } + + return IVAS_ERR_OK; +} +#endif /*---------------------------------------------------------------------* * init_decoder_config() @@ -292,6 +341,10 @@ static void init_decoder_config( hDecoderConfig->Opt_non_diegetic_pan = 0; hDecoderConfig->non_diegetic_pan_gain_fx = 0; // Q15 hDecoderConfig->Opt_tsm = 0; +#ifdef SPLIT_REND_WITH_HEAD_ROT + hDecoderConfig->Opt_Limiter = 1; + move16(); +#endif hDecoderConfig->Opt_delay_comp = 0; hDecoderConfig->Opt_ExternalOrientation = 0; hDecoderConfig->Opt_dpid_on = 0; @@ -338,6 +391,11 @@ void IVAS_DEC_Close( ( *phIvasDec )->hVoIP = NULL; } +#ifdef SPLIT_REND_WITH_HEAD_ROT + /* destroy Split binaural renderer (ISAR) handle */ + ivas_destroy_handle_isar( &( *phIvasDec )->st_ivas->hSplitBinRend ); +#endif + IF( ( *phIvasDec )->st_ivas ) { ivas_destroy_dec_fx( ( *phIvasDec )->st_ivas ); @@ -523,12 +581,31 @@ ivas_error IVAS_DEC_Configure( move16(); +#ifdef SPLIT_REND_WITH_HEAD_ROT + IF( EQ_32( hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) || EQ_32( hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ) + { + hDecoderConfig->Opt_Headrotation = TRUE; + move16(); + } +#endif + /* Set decoder parameters to initial values */ IF( NE_32( ( error = ivas_init_decoder_front( st_ivas ) ), IVAS_ERR_OK ) ) { return error; } +#ifdef SPLIT_REND_WITH_HEAD_ROT + /* create ISAR handle */ + IF( EQ_32( hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) || EQ_32( hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ) + { + IF( ( error = ivas_create_handle_isar( &st_ivas->hSplitBinRend ) ) != IVAS_ERR_OK ) + { + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Cannot allocate memory for ISAR handle" ); + } + } +#endif + if ( EQ_16( hIvasDec->mode, IVAS_DEC_MODE_EVS ) ) { hIvasDec->st_ivas->ivas_format = MONO_FORMAT; @@ -550,6 +627,43 @@ ivas_error IVAS_DEC_Configure( return error; } +#ifdef SPLIT_REND_WITH_HEAD_ROT +/*---------------------------------------------------------------------* + * IVAS_DEC_EnableSplitRendering( ) + * + * Intitialize Split rendering + *---------------------------------------------------------------------*/ + +ivas_error IVAS_DEC_EnableSplitRendering( + IVAS_DEC_HANDLE hIvasDec /* i/o: IVAS decoder handle */ +) +{ + DECODER_CONFIG_HANDLE hDecoderConfig; + ivas_error error; + + error = IVAS_ERR_OK; + move32(); + + + IF( hIvasDec == NULL || hIvasDec->st_ivas == NULL ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } + + hDecoderConfig = hIvasDec->st_ivas->hDecoderConfig; + move32(); + + hDecoderConfig->Opt_Headrotation = 1; + move16(); + hDecoderConfig->render_framesize = IVAS_RENDER_FRAMESIZE_20MS; + move32(); + + hDecoderConfig->Opt_Limiter = 0; + move16(); + + return error; +} +#endif /*---------------------------------------------------------------------* * get_render_framesize_ms( ) @@ -594,6 +708,16 @@ ivas_error IVAS_DEC_SetRenderFramesize( return IVAS_ERR_UNEXPECTED_NULL_POINTER; } + IF( hIvasDec->st_ivas->hExtOrientationData != NULL ) + { + hIvasDec->st_ivas->hExtOrientationData->num_subframes = (Word16) render_framesize; + } + IF( hIvasDec->st_ivas->hCombinedOrientationData != NULL ) + { + hIvasDec->st_ivas->hCombinedOrientationData->num_subframes = (Word16) render_framesize; + } + + hIvasDec->st_ivas->hDecoderConfig->render_framesize = render_framesize; move16(); @@ -920,7 +1044,7 @@ ivas_error IVAS_DEC_FeedFrame_Serial( } } - IF( NE_32( ( error = read_indices( hIvasDec->st_ivas, serial, num_bits, &hIvasDec->prev_ft_speech, &hIvasDec->CNG, bfi ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = read_indices_fx( hIvasDec->st_ivas, serial, num_bits, &hIvasDec->prev_ft_speech, &hIvasDec->CNG, bfi ) ), IVAS_ERR_OK ) ) { return error; } @@ -1001,6 +1125,21 @@ ivas_error IVAS_DEC_GetSamples( { return error; } + +#ifdef SPLIT_REND_WITH_HEAD_ROT + /*----------------------------------------------------------------* + * Binaural split rendering setup + *----------------------------------------------------------------*/ + + IF( EQ_32( hIvasDec->st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) || EQ_32( hIvasDec->st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ) + { + IF( hIvasDec->st_ivas->hCombinedOrientationData != NULL ) + { + isar_set_split_rend_ht_setup_fx( &hIvasDec->st_ivas->hSplitBinRend->splitrend, hIvasDec->st_ivas->hCombinedOrientationData->Quaternions, hIvasDec->st_ivas->hCombinedOrientationData->Rmat_fx ); + } + } +#endif + hIvasDec->updateOrientation = false; move16(); } @@ -1163,6 +1302,269 @@ return IVAS_ERR_OK; } +#ifdef SPLIT_REND_WITH_HEAD_ROT +/*---------------------------------------------------------------------* + * IVAS_DEC_GetSplitBinauralBitstream( ) + * + * + *---------------------------------------------------------------------*/ + +ivas_error +IVAS_DEC_GetSplitBinauralBitstream( + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + Word16 *pcmBuf_out, /* o : output synthesis signal for BINAURAL_SPLIT_PCM */ + ISAR_SPLIT_REND_BITS_DATA *splitRendBits, /* o : output split rendering bits */ + Word16 *nOutSamples, /* o : number of samples per channel written to output buffer */ + bool *needNewFrame /* o : indication that the decoder needs a new frame */ +) +{ + Decoder_Struct *st_ivas; + AUDIO_CONFIG output_config; + Word32 output_Fs; + Word32 *pOutput[BINAURAL_CHANNELS * MAX_HEAD_ROT_POSES]; + Word32 Cldfb_RealBuffer_Binaural[MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX]; + Word32 Cldfb_ImagBuffer_Binaural[MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX]; + FOR( Word32 i = 0; i < MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS; i++ ) + { + FOR( Word32 j = 0; j < CLDFB_NO_COL_MAX; j++ ) + { + FOR( Word32 k = 0; k < CLDFB_NO_CHANNELS_MAX; k++ ) + { + Cldfb_RealBuffer_Binaural[i][j][k] = 0; + Cldfb_ImagBuffer_Binaural[i][j][k] = 0; + move32(); + move32(); + } + } + } + Word16 numSamplesPerChannelToDecode; + Word16 i, j; + ivas_error error; + ISAR_DEC_SPLIT_REND_WRAPPER_HANDLE hSplitBinRend; + Word16 max_band; + Word16 pcm_out_flag; + Word16 td_input; + Word16 numPoses; + Word16 slots_rendered, slots_rendered_new; + Word16 ro_md_flag; + IVAS_QUATERNION Quaternion; + + error = IVAS_ERR_OK; + st_ivas = hIvasDec->st_ivas; + output_config = st_ivas->hDecoderConfig->output_config; + output_Fs = st_ivas->hDecoderConfig->output_Fs; + numSamplesPerChannelToDecode = (Word16) ( output_Fs / FRAMES_PER_SEC ); // TODO remove division + + *needNewFrame = false; + hSplitBinRend = st_ivas->hSplitBinRend; + + if ( ( error = isar_set_split_rend_setup( hSplitBinRend, &st_ivas->hRenderConfig->split_rend_config, st_ivas->hCombinedOrientationData, splitRendBits ) ) != IVAS_ERR_OK ) + { + return error; + } + FOR( i = 0; i < MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS; i++ ) + { + FOR( j = 0; j < CLDFB_NO_COL_MAX; j++ ) + { + set32_fx( hSplitBinRend->hMultiBinCldfbData->Cldfb_RealBuffer_Binaural_fx[i][j], 0, CLDFB_NO_CHANNELS_MAX ); + set32_fx( hSplitBinRend->hMultiBinCldfbData->Cldfb_ImagBuffer_Binaural_fx[i][j], 0, CLDFB_NO_CHANNELS_MAX ); + } + } + + numPoses = hSplitBinRend->splitrend.multiBinPoseData.num_poses; + move16(); + + IF( NE_32( st_ivas->hDecoderConfig->render_framesize, IVAS_RENDER_FRAMESIZE_20MS ) && + ( EQ_32( hIvasDec->st_ivas->hRenderConfig->split_rend_config.poseCorrectionMode, ISAR_SPLIT_REND_POSE_CORRECTION_MODE_NONE ) || + EQ_16( hIvasDec->st_ivas->hRenderConfig->split_rend_config.dof, 0 ) ) ) + { + numSamplesPerChannelToDecode = (Word16) ( output_Fs / FRAMES_PER_SEC ); // TODO remove division + numSamplesPerChannelToDecode = (Word16) ( numSamplesPerChannelToDecode / MAX_PARAM_SPATIAL_SUBFRAMES ); // TODO remove division + numSamplesPerChannelToDecode *= (Word16) st_ivas->hDecoderConfig->render_framesize; + move16(); + move16(); + } + + IF( EQ_16( IVAS_DEC_is_split_rendering_enabled( hIvasDec ), 0 ) ) + { + return IVAS_ERR_WRONG_PARAMS; + } + + IF( st_ivas->hTcBuffer == NULL || hIvasDec->hasBeenFedFrame ) + { + slots_rendered = 0; + } + ELSE + { + /* this is needed for OMASA-DISC, because the td-rend granularity is 240 samples at 48kHz, leading to wrong slot count. */ + IF( EQ_32( st_ivas->ivas_format, MASA_ISM_FORMAT ) && EQ_32( st_ivas->ism_mode, ISM_MASA_MODE_DISC ) ) + { + slots_rendered = st_ivas->hTcBuffer->n_samples_rendered / NS2SA( st_ivas->hDecoderConfig->output_Fs, CLDFB_SLOT_NS ); // TODO remove division + } + else + { + slots_rendered = st_ivas->hTcBuffer->n_samples_rendered / st_ivas->hTcBuffer->n_samples_granularity; + } + } + + + /* Decode and render */ + if ( ( error = IVAS_DEC_GetSamples( hIvasDec, numSamplesPerChannelToDecode, pcmBuf_out, nOutSamples, needNewFrame ) ) != IVAS_ERR_OK ) + { + return error; + } + + + FOR( i = 0; i < BINAURAL_CHANNELS * MAX_HEAD_ROT_POSES; ++i ) + { + pOutput[i] = hSplitBinRend->hMultiBinCldfbData->output_fx[i]; + move32(); + } + + IF( st_ivas->hTcBuffer == NULL ) + { + slots_rendered_new = 0; + move16(); + } + ELSE + { + /* this is needed for OMASA-DISC, because the td-rend granularity is 240 samples at 48kHz, leading to wrong slot count. */ + IF( EQ_32( st_ivas->ivas_format, MASA_ISM_FORMAT ) && EQ_32( st_ivas->ism_mode, ISM_MASA_MODE_DISC ) ) + { + slots_rendered_new = st_ivas->hTcBuffer->n_samples_rendered / NS2SA( st_ivas->hDecoderConfig->output_Fs, CLDFB_SLOT_NS ); // TODO remove division + } + ELSE + { + slots_rendered_new = st_ivas->hTcBuffer->n_samples_rendered / st_ivas->hTcBuffer->n_samples_granularity; // TODO remove division + } + } + + FOR( i = 0; i < i_mult( BINAURAL_CHANNELS, numPoses ); ++i ) + { + FOR( j = slots_rendered; j < slots_rendered_new; ++j ) + { + Copy32( hSplitBinRend->hMultiBinCldfbData->Cldfb_RealBuffer_Binaural_fx[i][j], Cldfb_RealBuffer_Binaural[i][j - slots_rendered], CLDFB_NO_CHANNELS_MAX ); + Copy32( hSplitBinRend->hMultiBinCldfbData->Cldfb_ImagBuffer_Binaural_fx[i][j], Cldfb_ImagBuffer_Binaural[i][j - slots_rendered], CLDFB_NO_CHANNELS_MAX ); + } + } + + max_band = (Word16) ( ( BINAURAL_MAXBANDS * output_Fs ) / 48000 ); // TODO remove division + move16(); + pcm_out_flag = ( output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ? 1 : 0; + td_input = st_ivas->renderer_type != RENDERER_BINAURAL_FASTCONV && st_ivas->renderer_type != RENDERER_BINAURAL_PARAMETRIC && st_ivas->renderer_type != RENDERER_BINAURAL_PARAMETRIC_ROOM && st_ivas->renderer_type != RENDERER_STEREO_PARAMETRIC; + + IF( st_ivas->hBinRendererTd != NULL ) + { + ro_md_flag = 1; + move16(); + } + ELSE + { + ro_md_flag = 0; + move16(); + } + + IF( st_ivas->hHeadTrackData != NULL ) + { + Quaternion = st_ivas->hHeadTrackData->Quaternions[0]; + } + ELSE + { + Quaternion.w_fx = -12582912; + Quaternion.x_fx = 0; + Quaternion.y_fx = 0; + Quaternion.z_fx = 0; + } + Word16 q1 = 31, q2 = 31, Q_buff; + Word16 Q_out[CLDFB_NO_COL_MAX]; + Q_out[0] = 31; + Word16 num_poses = hSplitBinRend->splitrend.multiBinPoseData.num_poses; + + for ( i = 0; i < i_mult( BINAURAL_CHANNELS, numPoses ); i++ ) + { + for ( j = 0; j < CLDFB_NO_COL_MAX; j++ ) + { + q1 = s_min( q1, L_norm_arr( Cldfb_RealBuffer_Binaural[i][j], CLDFB_NO_CHANNELS_MAX ) ); + q2 = s_min( q2, L_norm_arr( Cldfb_ImagBuffer_Binaural[i][j], CLDFB_NO_CHANNELS_MAX ) ); + } + } + Q_buff = s_min( q1, q2 ); + for ( i = 0; i < i_mult( BINAURAL_CHANNELS, numPoses ); i++ ) + { + for ( j = 0; j < CLDFB_NO_COL_MAX; j++ ) + { + scale_sig32( Cldfb_RealBuffer_Binaural[i][j], CLDFB_NO_CHANNELS_MAX, Q_buff ); + scale_sig32( Cldfb_ImagBuffer_Binaural[i][j], CLDFB_NO_CHANNELS_MAX, Q_buff ); + } + } + Q_buff = add( Q_buff, Q6 ); + + IF( NE_16( td_input, 0 ) ) + { + /*TD input*/ + /*if CLDFB handles have been allocated then assume valid multi binaural input in out[][] buffer and perform CLDFB analysis*/ + /* local float2fix, to be removed */ + num_poses = hSplitBinRend->splitrend.multiBinPoseData.num_poses; + + FOR( i = 0; i < num_poses * BINAURAL_CHANNELS; ++i ) + { + Q_out[0] = s_min( Q_out[0], L_norm_arr( pOutput[i], L_FRAME48k ) ); + } + + FOR( i = 0; i < num_poses * BINAURAL_CHANNELS; ++i ) + { + scale_sig32( pOutput[i], L_FRAME48k, Q_out[0] ); + } + Q_out[0] = add( Q_out[0], Q11 ); + Q_out[1] = Q_out[0]; + } + + if ( ( error = ISAR_PRE_REND_MultiBinToSplitBinaural( &hSplitBinRend->splitrend, + Quaternion, + st_ivas->hRenderConfig->split_rend_config.splitRendBitRate, + st_ivas->hRenderConfig->split_rend_config.codec, +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + st_ivas->hRenderConfig->split_rend_config.isar_frame_size_ms, +#endif + st_ivas->hRenderConfig->split_rend_config.codec_frame_size_ms, + splitRendBits, + Cldfb_RealBuffer_Binaural, + Cldfb_ImagBuffer_Binaural, + max_band, pOutput, 1, !td_input, pcm_out_flag, ro_md_flag, Q_buff, &Q_out[0] ) ) != IVAS_ERR_OK ) + + { + return error; + } + + + /* convert to int16 with limiting for BINAURAL_SPLIT_PCM */ + IF( pcm_out_flag ) + { + FOR( j = 0; j < BINAURAL_CHANNELS; j++ ) + { + scale_sig32( pOutput[j], numSamplesPerChannelToDecode, sub( Q11, Q_out[j] ) ); // Q11 + } + IF( EQ_32( st_ivas->hDecoderConfig->render_framesize, IVAS_RENDER_FRAMESIZE_5MS ) ) + { +#ifndef DISABLE_LIMITER + ivas_limiter_dec_fx( st_ivas->hLimiter, pOutput, st_ivas->hDecoderConfig->nchan_out, numSamplesPerChannelToDecode, st_ivas->BER_detect, Q11 ); +#endif + } + else + { + ivas_limiter_dec_fx( st_ivas->hLimiter, pOutput, st_ivas->hDecoderConfig->nchan_out, numSamplesPerChannelToDecode, st_ivas->BER_detect, Q11 ); + } + + ivas_syn_output_fx( pOutput, Q11, numSamplesPerChannelToDecode, st_ivas->hDecoderConfig->nchan_out, (int16_t *) pcmBuf_out ); + } + + free( st_ivas->hSplitBinRend->hMultiBinCldfbData ); + + return error; +} +#endif + + /*---------------------------------------------------------------------* * IVAS_DEC_Setup( ) * @@ -1831,7 +2233,12 @@ ivas_error IVAS_DEC_FeedHeadTrackData( IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ IVAS_QUATERNION orientation, /* i : head-tracking data, listener orientation */ IVAS_VECTOR3 Pos, /* i : listener position */ - const Word16 subframe_idx /* i : subframe index */ +#ifdef SPLIT_REND_WITH_HEAD_ROT + const Word16 subframe_idx, /* i : subframe index */ + const ISAR_SPLIT_REND_ROT_AXIS rot_axis /* i : external control for rotation axis for split rendering */ +#else + const Word16 subframe_idx /* i : subframe index */ +#endif ) { HEAD_TRACK_DATA_HANDLE hHeadTrackData; @@ -1852,10 +2259,19 @@ ivas_error IVAS_DEC_FeedHeadTrackData( /* Move head-tracking data to the decoder handle */ /* check for Euler angle signaling */ +#ifdef SPLIT_REND_WITH_HEAD_ROT + /* check for Euler angle signaling */ + IF( EQ_32( orientation.w_fx, L_negate( 12582912 ) ) && EQ_16( orientation.q_fact, Q22 ) ) + { + Euler2Quat_fx( deg2rad_fx( orientation.x_fx ), deg2rad_fx( orientation.y_fx ), deg2rad_fx( orientation.z_fx ), &orientation ); + modify_Quat_q_fx( &orientation, &orientation, Q29 ); + } +#else IF( EQ_32( orientation.w_fx, -1610612736 /* -3.0f in Q29 */ ) ) { Euler2Quat_fx( deg2rad_fx( orientation.x_fx ), deg2rad_fx( orientation.y_fx ), deg2rad_fx( orientation.z_fx ), &orientation ); } +#endif Word32 updateRate_fx = 1677721600; // value is 200 in Q23 move32(); @@ -1893,6 +2309,11 @@ ivas_error IVAS_DEC_FeedHeadTrackData( move32(); move16(); +#ifdef SPLIT_REND_WITH_HEAD_ROT + hHeadTrackData->sr_pose_pred_axis = rot_axis; + move32(); +#endif + hIvasDec->updateOrientation = true; move16(); @@ -2206,6 +2627,34 @@ static ivas_error copyRendererConfigStruct( Copy32( hRCin->roomAcoustics.pAcoustic_rt60_fx, hRCout->roomAcoustics.pAcoustic_rt60_fx, CLDFB_NO_CHANNELS_MAX ); // Q26 Copy32( hRCin->roomAcoustics.pAcoustic_dsr_fx, hRCout->roomAcoustics.pAcoustic_dsr_fx, CLDFB_NO_CHANNELS_MAX ); // Q30 Copy( hRCin->directivity_fx, hRCout->directivity_fx, 3 * MAX_NUM_OBJECTS ); + +#ifdef SPLIT_REND_WITH_HEAD_ROT + hRCout->split_rend_config.splitRendBitRate = SPLIT_REND_768k; + hRCout->split_rend_config.dof = 3; + hRCout->split_rend_config.hq_mode = 0; + hRCout->split_rend_config.codec_delay_ms = 0; +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + hRCout->split_rend_config.isar_frame_size_ms = 20; + move16(); +#endif + hRCout->split_rend_config.codec_frame_size_ms = 0; /* 0 means "use default for selected codec" */ + hRCout->split_rend_config.codec = ISAR_SPLIT_REND_CODEC_DEFAULT; + hRCout->split_rend_config.poseCorrectionMode = ISAR_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB; + hRCout->split_rend_config.rendererSelection = hRCin->split_rend_config.rendererSelection; +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + hRCout->split_rend_config.lc3plus_highres = hRCin->split_rend_config.lc3plus_highres; + move16(); +#endif + move32(); + move16(); + move16(); + move16(); + move16(); + move32(); + move32(); + move32(); +#endif + hRCout->roomAcoustics.use_er = hRCin->roomAcoustics.use_er; hRCout->roomAcoustics.lowComplexity = hRCin->roomAcoustics.lowComplexity; move16(); @@ -2270,6 +2719,9 @@ ivas_error IVAS_DEC_FeedRenderConfig( ) { RENDER_CONFIG_HANDLE hRenderConfig; +#ifdef SPLIT_REND_WITH_HEAD_ROT + ivas_error error; +#endif test(); test(); @@ -2308,6 +2760,21 @@ ivas_error IVAS_DEC_FeedRenderConfig( Copy( renderConfig.directivity_fx, hRenderConfig->directivity_fx, 3 * MAX_NUM_OBJECTS ); +#ifdef SPLIT_REND_WITH_HEAD_ROT + hRenderConfig->split_rend_config = renderConfig.split_rend_config; + + /* Overwrite any pose correction settings if 0 DOF (no pose correction) was selected */ + IF( hRenderConfig->split_rend_config.dof == 0 ) + { + hRenderConfig->split_rend_config.poseCorrectionMode = ISAR_SPLIT_REND_POSE_CORRECTION_MODE_NONE; + } + + IF( ( error = isar_split_rend_validate_config( &hRenderConfig->split_rend_config, ( hIvasDec->st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ? 1 : 0 ) ) != IVAS_ERR_OK ) + { + return error; + } +#endif + return IVAS_ERR_OK; } @@ -2362,8 +2829,13 @@ ivas_error IVAS_DEC_GetDelay( } move32(); +#ifdef SPLIT_REND_WITH_HEAD_ROT + nSamples[1] = NS2SA_FX2( hDecoderConfig->output_Fs, get_delay_fx( DEC, hDecoderConfig->output_Fs, st_ivas->ivas_format, st_ivas->cldfbAnaDec[0], hDecoderConfig->output_config ) ); + move16(); +#else nSamples[1] = NS2SA_FX2( hDecoderConfig->output_Fs, get_delay_fx( DEC, hDecoderConfig->output_Fs, st_ivas->ivas_format, st_ivas->cldfbAnaDec[0] ) ); move16(); +#endif nSamples[2] = extract_l( W_round64_L( W_mult0_32_32( L_shl( st_ivas->binaural_latency_ns, 1 ), out_fs_fx ) ) ); move16(); nSamples[0] = add( nSamples[1], nSamples[2] ); @@ -3058,7 +3530,7 @@ const char *IVAS_DEC_GetErrorMessage( return ivas_error_to_string( error ); } - +#ifndef FIX_DISCLAIMER /*---------------------------------------------------------------------* * get_channel_config() * @@ -3136,7 +3608,7 @@ static ivas_error get_channel_config( return IVAS_ERR_OK; } - +#endif /*---------------------------------------------------------------------* * printConfigInfo_dec( ) @@ -3260,7 +3732,11 @@ static ivas_error printConfigInfo_dec( test(); test(); +#ifdef SPLIT_REND_WITH_HEAD_ROT + IF( ( EQ_16( (Word16) output_config, IVAS_AUDIO_CONFIG_BINAURAL ) || EQ_16( (Word16) output_config, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR ) || EQ_16( (Word16) output_config, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) || EQ_16( (Word16) output_config, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) || EQ_16( (Word16) output_config, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ) ) +#else IF( ( EQ_16( (Word16) output_config, IVAS_AUDIO_CONFIG_BINAURAL ) || EQ_16( (Word16) output_config, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR ) || EQ_16( (Word16) output_config, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) ) ) +#endif { fprintf( stdout, "Render framesize: %dms\n", get_render_frame_size_ms( st_ivas->hDecoderConfig->render_framesize ) ); } @@ -3393,7 +3869,7 @@ static ivas_error evs_dec_main_fx( move32(); hCoreCoder[0]->output_frame_fx = extract_l( Mult_32_16( hCoreCoder[0]->output_Fs, 0x0290 /*Q0*/ ) ); // Q0 move16(); - mdct_switching_dec( hCoreCoder[0] ); + mdct_switching_dec_ivas_fx( hCoreCoder[0] ); FOR( ch = 0; ch < MAX_OUTPUT_CHANNELS_IN_DIEGETIC_PAN; ch++ ) { @@ -3653,3 +4129,217 @@ static ivas_error IVAS_DEC_VoIP_reconfigure( return IVAS_ERR_OK; } + + +#ifdef SPLIT_REND_WITH_HEAD_ROT +/*---------------------------------------------------------------------* + * IVAS_DEC_GetSplitRendBitstreamHeader() + * + * + *---------------------------------------------------------------------*/ + +ivas_error +IVAS_DEC_GetSplitRendBitstreamHeader( + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + ISAR_SPLIT_REND_CODEC *pCodec, /* o: pointer to codec setting */ + ISAR_SPLIT_REND_POSE_CORRECTION_MODE *poseCorrection, /* o: pointer to pose correction mode */ +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + Word16 *pIsar_frame_size_ms, /* o: pointer to isar frame size setting */ +#endif + Word16 *pCodec_frame_size_ms /* o: pointer to codec frame size setting */ +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + , + Word16 *pLc3plusHighRes +#endif +) +{ + if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } + + *pCodec = hIvasDec->st_ivas->hRenderConfig->split_rend_config.codec; + *pCodec_frame_size_ms = hIvasDec->st_ivas->hRenderConfig->split_rend_config.codec_frame_size_ms; + *poseCorrection = hIvasDec->st_ivas->hRenderConfig->split_rend_config.poseCorrectionMode; +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + *pIsar_frame_size_ms = hIvasDec->st_ivas->hRenderConfig->split_rend_config.isar_frame_size_ms; + *pLc3plusHighRes = hIvasDec->st_ivas->hRenderConfig->split_rend_config.lc3plus_highres; +#endif + return IVAS_ERR_OK; +} + + +/*---------------------------------------------------------------------* + * IVAS_DEC_GetCldfbSamples() + * + * API function to output CLDFB samples + *---------------------------------------------------------------------*/ + +ivas_error IVAS_DEC_GetCldfbSamples( + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + Word32 *out_real, /* o : buffer for decoded PCM real output in CLDFB domain */ + Word32 *out_imag, /* o : buffer for decoded PCM imag output in CLDFB domain */ + AUDIO_CONFIG *audio_config, /* o : audio configuration */ + Word16 *nOutSamples /* o : number of samples per channel written to output buffer */ +) +{ + ISAR_DEC_SPLIT_REND_WRAPPER_HANDLE hSplitBinRend; + Word16 ch, b, slot_idx, num_chs, maxBand, num_samples; + + IF( hIvasDec == NULL || hIvasDec->st_ivas == NULL || hIvasDec->st_ivas->hSplitBinRend == NULL ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } + + hSplitBinRend = hIvasDec->st_ivas->hSplitBinRend; + num_samples = 0; + + IF( hSplitBinRend->hCldfbDataOut != NULL ) + { + *audio_config = hSplitBinRend->hCldfbDataOut->config; + IF( hSplitBinRend->hCldfbDataOut->config != IVAS_AUDIO_CONFIG_INVALID ) + { + num_chs = audioCfg2channels( hSplitBinRend->hCldfbDataOut->config ); + maxBand = (int16_t) ( ( CLDFB_NO_CHANNELS_MAX * hIvasDec->st_ivas->hDecoderConfig->output_Fs ) / 48000 ); + + FOR( slot_idx = 0; slot_idx < CLDFB_NO_COL_MAX; slot_idx++ ) + { + FOR( b = 0; b < maxBand; b++ ) + { + FOR( ch = 0; ch < num_chs; ch++ ) + { + *out_real++ = hSplitBinRend->hCldfbDataOut->Cldfb_RealBuffer_fx[ch][slot_idx][b]; + *out_imag++ = hSplitBinRend->hCldfbDataOut->Cldfb_ImagBuffer_fx[ch][slot_idx][b]; + } + } + } + num_samples = CLDFB_NO_COL_MAX * maxBand; + } + } + ELSE + { + *audio_config = IVAS_AUDIO_CONFIG_INVALID; + } + + *nOutSamples = num_samples; + + return IVAS_ERR_OK; +} + + +/*-------------------------------------------------------------------* + * ivas_create_handle_isar() + * + * Initialize IVAS decoder split rend handle + *-------------------------------------------------------------------*/ + +static ivas_error ivas_create_handle_isar( + ISAR_DEC_SPLIT_REND_WRAPPER_HANDLE *hSplitBinRend_out /* o : ISAR split binaural rendering handle */ +) +{ + ISAR_DEC_SPLIT_REND_WRAPPER_HANDLE hSplitBinRend; + + if ( ( hSplitBinRend = (ISAR_DEC_SPLIT_REND_WRAPPER_HANDLE) malloc( sizeof( ISAR_DEC_SPLIT_REND_WRAPPER ) ) ) == NULL ) + { + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Cannot allocate memory for IVAS decoder handle" ); + } + + isar_init_split_rend_handles( &hSplitBinRend->splitrend ); + + hSplitBinRend->hMultiBinCldfbData = NULL; + hSplitBinRend->hCldfbDataOut = NULL; + hSplitBinRend->numTdSamplesPerChannelCached = 0; + + *hSplitBinRend_out = hSplitBinRend; + + return IVAS_ERR_OK; +} + + +/*-------------------------------------------------------------------* + * ivas_destroy_handle_isar() + * + * destroy IVAS decoder split rend handle + *-------------------------------------------------------------------*/ + +static void ivas_destroy_handle_isar( + ISAR_DEC_SPLIT_REND_WRAPPER_HANDLE *hSplitBinRend /* i/o: ISAR split binaural rendering handle */ +) +{ + IF( *hSplitBinRend != NULL ) + { + ISAR_PRE_REND_close( &( *hSplitBinRend )->splitrend, NULL ); + + IF( ( *hSplitBinRend )->hCldfbDataOut != NULL ) + { + free( ( *hSplitBinRend )->hCldfbDataOut ); + ( *hSplitBinRend )->hCldfbDataOut = NULL; + } + + free( *hSplitBinRend ); + *hSplitBinRend = NULL; + } + + return; +} + + +/*---------------------------------------------------------------------* + * IVAS_DEC_is_split_rendering_enabled() + * + * + *---------------------------------------------------------------------*/ + +int16_t IVAS_DEC_is_split_rendering_enabled( + IVAS_DEC_HANDLE hIvasDec /* i/o: IVAS decoder handle */ +) +{ + Decoder_Struct *st_ivas; + Word16 isSplitRend; + + IF( hIvasDec == NULL || hIvasDec->st_ivas == NULL ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } + st_ivas = hIvasDec->st_ivas; + isSplitRend = 0; + + IF( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM || + ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_STEREO && st_ivas->hDecoderConfig->Opt_non_diegetic_pan && st_ivas->hRenderConfig->split_rend_config.dof == 0 ) ) + { + isSplitRend = 1; + } + + return isSplitRend; +} + + +/*---------------------------------------------------------------------* + * IVAS_DEC_is_split_rendering_coded_out() + * + * + *---------------------------------------------------------------------*/ + +Word16 IVAS_DEC_is_split_rendering_coded_out( + IVAS_DEC_HANDLE hIvasDec /* i/o: IVAS decoder handle */ +) +{ + Decoder_Struct *st_ivas; + Word16 isSplitCoded; + + IF( hIvasDec == NULL || hIvasDec->st_ivas == NULL ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } + st_ivas = hIvasDec->st_ivas; + isSplitCoded = 0; + + IF( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || + ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_STEREO && st_ivas->hDecoderConfig->Opt_non_diegetic_pan && st_ivas->hRenderConfig->split_rend_config.dof == 0 ) ) + { + isSplitCoded = 1; + } + + return isSplitCoded; +} +#endif diff --git a/lib_dec/lp_exc_d.c b/lib_dec/lp_exc_d.c deleted file mode 100644 index e7a8ca967132cf8896fc4a231dbaf74eed596840..0000000000000000000000000000000000000000 --- a/lib_dec/lp_exc_d.c +++ /dev/null @@ -1,41 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include "cnst.h" -#include "prot.h" -#include "wmc_auto.h" diff --git a/lib_dec/lsf_dec.c b/lib_dec/lsf_dec.c deleted file mode 100644 index f963d7317917e3d87f50bd29ba50206654daa998..0000000000000000000000000000000000000000 --- a/lib_dec/lsf_dec.c +++ /dev/null @@ -1,58 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include "cnst.h" -#include "rom_com.h" -#include "prot.h" -#include "prot_fx.h" -#include "basop_proto_func.h" -#include "ivas_prot.h" -#include "ivas_rom_com.h" -#include "wmc_auto.h" - - -/*---------------------------------------------------------------------* - * Local function prototypes - *---------------------------------------------------------------------*/ - - -/*---------------------------------------------------------------------* - * lsf_dec() - * - * LSF decoder - *---------------------------------------------------------------------*/ diff --git a/lib_dec/lsf_dec_fx.c b/lib_dec/lsf_dec_fx.c index 50b5ec34131966f34314a4cf6e45dd344127e03a..21e8705f3aa64d7b7efcb4a8b7b929fbfe49a626 100644 --- a/lib_dec/lsf_dec_fx.c +++ b/lib_dec/lsf_dec_fx.c @@ -7,7 +7,6 @@ #include "cnst.h" /* Common constants */ #include "rom_com.h" /* Static table prototypes */ #include "prot_fx.h" /* Function prototypes */ -#include "ivas_prot.h" #include "ivas_prot_fx.h" /*-------------------------------------------------------------------* * Local functions @@ -195,7 +194,6 @@ void lsf_dec_fx( /* rightshift before *seed_acelp+param_lpc[i] to avoid overflows*/ st_fx->seed_acelp = extract_l( L_add( imult3216( 31821L /* Q0 */, add( shr( ( st_fx->seed_acelp ), 1 ), param_lpc[i] ) ), 13849L /* Q0 */ ) ); /* Q0 */ move16(); - // PMTE() /*IVAS_CODE to be completed */ } } IF( EQ_32( st_fx->core_brate, SID_2k40 ) ) @@ -449,7 +447,6 @@ void lsf_dec_ivas_fx( /* rightshift before *seed_acelp+param_lpc[i] to avoid overflows*/ st_fx->seed_acelp = extract_l( L_add( imult3216( 31821L /* Q0 */, add( shr( ( st_fx->seed_acelp ), 1 ), param_lpc[i] ) ), 13849L /* Q0 */ ) ); /* Q0 */ move16(); - // PMTE() /*IVAS_CODE to be completed */ } } IF( EQ_32( st_fx->core_brate, SID_2k40 ) ) @@ -664,12 +661,7 @@ void lsf_end_dec_fx( test(); test(); -#ifdef LSF_RE_USE_SECONDARY_CHANNEL - test(); - IF( ( EQ_16( coder_type_org, GENERIC ) ) && ( EQ_32( st->sr_core, INT_FS_16k ) ) && ( mode2_flag == 0 ) && ( st->idchan == 0 ) ) -#else IF( ( EQ_16( coder_type_org, GENERIC ) ) && ( EQ_32( st->sr_core, INT_FS_16k ) ) && ( mode2_flag == 0 ) ) -#endif { /* this bit is used only for primary channel or mono */ coder_type = (Word16) get_next_indice_fx( st, 1 ); /* Q0 */ diff --git a/lib_dec/lsf_msvq_ma_dec.c b/lib_dec/lsf_msvq_ma_dec.c deleted file mode 100644 index 313c2798e72af1d464783e1a91d5332b57966f1d..0000000000000000000000000000000000000000 --- a/lib_dec/lsf_msvq_ma_dec.c +++ /dev/null @@ -1,43 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include "cnst.h" -#include "prot.h" -#include "rom_com.h" -#include "basop_proto_func.h" -#include "wmc_auto.h" diff --git a/lib_dec/nelp_dec.c b/lib_dec/nelp_dec.c deleted file mode 100644 index 895fdaae2f764e88b23432ee1d3538c8b13f4715..0000000000000000000000000000000000000000 --- a/lib_dec/nelp_dec.c +++ /dev/null @@ -1,49 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include -#include "cnst.h" -#include "prot.h" -#include "rom_com.h" -#include "wmc_auto.h" - -/*-------------------------------------------------------------------* - * nelp_decoder() - * - * NELP decoder - *-------------------------------------------------------------------*/ diff --git a/lib_dec/nelp_dec_fx.c b/lib_dec/nelp_dec_fx.c index 9eb7ab2031758be2a889c082213e64889fde0498..c088dd82663b8faa30514363b931ccd27ba39001 100644 --- a/lib_dec/nelp_dec_fx.c +++ b/lib_dec/nelp_dec_fx.c @@ -336,11 +336,7 @@ void nelp_decoder_fx( E3 = L_deposit_l( 1 ); FOR( i = 0; i < L_FRAME; i++ ) { -#ifdef BASOP_NOGLOB E3 = L_mac0_sat( E3, ptr[i], ptr[i] ); /*2*Q_exc */ -#else - E3 = L_mac0( E3, ptr[i], ptr[i] ); /*2*Q_exc */ -#endif } @@ -391,11 +387,7 @@ void nelp_decoder_fx( E2 = L_deposit_l( 1 ); FOR( i = 0; i < L_FRAME; i++ ) { -#ifdef BASOP_NOGLOB E2 = L_mac0_sat( E2, ptr[i], ptr[i] ); /*2*Q_exc */ -#else - E2 = L_mac0( E2, ptr[i], ptr[i] ); /*2*Q_exc */ -#endif } exp_E3 = norm_l( E3 ); @@ -403,11 +395,7 @@ void nelp_decoder_fx( exp_E3 = sub( 30, add( exp_E3, 2 * ( *Q_exc ) ) ); exp_E2 = norm_l( E2 ); -#ifdef BASOP_NOGLOB frac_E2 = round_fx_sat( L_shl_sat( E2, exp_E2 ) ); -#else - frac_E2 = round_fx( L_shl( E2, exp_E2 ) ); -#endif exp_E2 = sub( 30, add( exp_E2, shl( ( *Q_exc ), 1 ) ) ); scale = shr( sub( frac_E3, frac_E2 ), 15 ); diff --git a/lib_dec/pit_dec.c b/lib_dec/pit_dec.c deleted file mode 100644 index 7d906b12ed9cb0216cb37fa9612a63684e9fe937..0000000000000000000000000000000000000000 --- a/lib_dec/pit_dec.c +++ /dev/null @@ -1,43 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include -#include "options.h" -#include "cnst.h" -#include "prot.h" -#include "rom_com.h" -#include "wmc_auto.h" diff --git a/lib_dec/pit_dec_fx.c b/lib_dec/pit_dec_fx.c index b72c2bae16296e0d49371ce46b16907438c3ba4f..1d3e9649793cb0578063ec2b5235a452812ffe1d 100644 --- a/lib_dec/pit_dec_fx.c +++ b/lib_dec/pit_dec_fx.c @@ -333,11 +333,6 @@ Word16 pit_decode_fx( /* o : floating pitch value Word16 *T0_min, /* i/o: delta search min for sf 2 & 4 */ Word16 *T0_max, /* i/o: delta search max for sf 2 & 4 */ const Word16 L_subfr /* i : subframe length */ -#ifdef ADD_LRTD - , - const Word16 tdm_Pitch_reuse_flag, /* i : primary channel pitch reuse flag */ - const Word16 tdm_Pri_pitch_buf[] /* i : primary channel pitch buffer */ -#endif ) { Word16 pitch; /*Q2*/ @@ -458,57 +453,6 @@ Word16 pit_decode_fx( /* o : floating pitch value pit_Q_dec_fx( 0, pitch_index, nBits, 4, pit_flag, *limit_flag, T0, T0_frac, T0_min, T0_max, &st_fx->BER_detect ); } -#ifdef ADD_LRTD - ELSE IF( EQ_16( st_fx->idchan, 1 ) && ( EQ_16( tdm_Pitch_reuse_flag, 1 ) || EQ_16( nBits, 4 ) ) ) - { - test(); - test(); - /*-------------------------------------------------------* - * Pitch decoding with reusing of primary channel information - *-------------------------------------------------------*/ - Word16 loc_T0, loc_frac, delta, pit_tmp1, pit_tmp2, isubfridx; - - delta = 4; - pit_flag = L_SUBFR; - move16(); - move16(); - isubfridx = shr( i_subfr, 6 ); - IF( EQ_16( L_subfr, 2 * L_SUBFR ) ) - { - move16(); - move16(); - pit_tmp1 = tdm_Pri_pitch_buf[isubfridx]; /*tdm_Pri_pitch_buf in Q6 ->pit_tmp1 and 2 in Q6 too */ - pit_tmp2 = tdm_Pri_pitch_buf[shr( add( i_subfr, 1 ), 6 )]; - /*loc_T0 = (int16_t)(0.5f * tdm_Pri_pitch_buf[i_subfr / L_SUBFR] + 0.5f * tdm_Pri_pitch_buf[(i_subfr + L_SUBFR) / L_SUBFR]);*/ - loc_T0 = mac_r( L_mult( 16384, pit_tmp1, 16384, pit_tmp2 ) ); - /*loc_frac = (int16_t)(((0.5f * tdm_Pri_pitch_buf[i_subfr / L_SUBFR] + 0.5f * tdm_Pri_pitch_buf[(i_subfr + L_SUBFR) / L_SUBFR]) - loc_T0) * 4.0f);*/ - } - ELSE - { - /*loc_T0 = (int16_t)tdm_Pri_pitch_buf[i_subfr / L_SUBFR];*/ - loc_T0 = tdm_Pri_pitch_buf[isubfridx]; /*Q6*/ - /*loc_frac = (int16_t)((tdm_Pri_pitch_buf[i_subfr / L_SUBFR] - loc_T0) * 4.0f);*/ - } - loc_frac = shr(sub(loc_T0, shl(shr(loc_T0, 6), 6)), 4)); /* Final result in Q 2*/ - loc_T0 = shr( loc_T0, 6 ); /*Q6 -> Q0*/ - - - limit_T0_fx( L_FRAME, delta, pit_flag, *limit_flag, loc_T0, loc_frac, T0_min, T0_max ); - - IF( nBits > 0 ) - { - pit_Q_dec_fx( 0, pitch_index, nBits, delta, pit_flag, *limit_flag, T0, T0_frac, T0_min, T0_max, &st_fx->BER_detect ); - } - ELSE - { - *T0 = loc_T0; - *T0_frac = loc_frac; - move16(); - move16(); - } - printf( "function not tested yet\n" ); - } -#endif ELSE { /*-------------------------------------------------------* diff --git a/lib_dec/pitch_extr.c b/lib_dec/pitch_extr.c deleted file mode 100644 index 53a6b154af24122c24d7aa40ca5c8b16c2a6265b..0000000000000000000000000000000000000000 --- a/lib_dec/pitch_extr.c +++ /dev/null @@ -1,45 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include - -#include -#include "options.h" -#include -#include "cnst.h" -#include "prot.h" -#include "basop_util.h" -#include "wmc_auto.h" diff --git a/lib_dec/pitch_extr_fx.c b/lib_dec/pitch_extr_fx.c index 6f5bcc535237e6140c40ed310ecf9c52870c3de2..73e9623f5da99fc082caae28ff4ce9c12a27bd20 100644 --- a/lib_dec/pitch_extr_fx.c +++ b/lib_dec/pitch_extr_fx.c @@ -157,9 +157,7 @@ void pitch_pred_linear_fit( { Word32 t1, t2, t3, t4, t5, t6, t7; Word16 e1, e2, e3, e4, e5, e6, e7; -#ifdef BASOP_NOGLOB Flag Overflow; -#endif t1 = L_mult0( pg[4], pg[3] ); /*Q24*/ /* t1 = pg[4]*pg[3] */ e1 = 7; move16(); @@ -182,12 +180,8 @@ void pitch_pred_linear_fit( t6 = BASOP_Util_Add_Mant32Exp( t3, e3, t4, e4, &e6 ); t7 = BASOP_Util_Add_Mant32Exp( t5, e5, t6, e6, &e7 ); /*Q31,e7*/ sum0_q = norm_l( t7 ); -#ifdef BASOP_NOGLOB sum0 = round_fx_o( L_shl( t7, sum0_q ), &Overflow ); /*Q15,e7-sum0_q*/ -#else - sum0 = round_fx( L_shl( t7, sum0_q ) ); /*Q15,e7-sum0_q*/ -#endif - sum0_q = add( 15, sub( sum0_q, e7 ) ); /* sum0 is now Qsum0_q*/ + sum0_q = add( 15, sub( sum0_q, e7 ) ); /* sum0 is now Qsum0_q*/ } pit = 0; diff --git a/lib_dec/post_dec.c b/lib_dec/post_dec.c deleted file mode 100644 index 3643a2810dea05d3a7a95c663eadd41f61e5b2f7..0000000000000000000000000000000000000000 --- a/lib_dec/post_dec.c +++ /dev/null @@ -1,59 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include -#include "prot.h" -#include "rom_com.h" -#include "wmc_auto.h" - -/*---------------------------------------------------------------------* - * Function prototypes - *---------------------------------------------------------------------*/ - - -/*---------------------------------------------------------------------* - * post_decoder_flt() - * - * Perform post-processing - *---------------------------------------------------------------------*/ - -/*---------------------------------------------------------------------* - * bass_pf_1sf_delay() - * - * Perform low-frequency postfiltering - *---------------------------------------------------------------------*/ diff --git a/lib_dec/post_dec_fx.c b/lib_dec/post_dec_fx.c index 8d3e03321b4d3b9082ba36fcb9cb2c138bcbb17a..d581f810a7dd724424e19f9651b0a5c4a11e930c 100644 --- a/lib_dec/post_dec_fx.c +++ b/lib_dec/post_dec_fx.c @@ -439,11 +439,7 @@ static void bass_pf_1sf_delay( /* gain = tmp/nrg; */ gain = BASOP_Util_Divide3232_Scale( tmp, nrg, &tmp16 ); BASOP_SATURATE_WARNING_OFF_EVS; -#ifdef BASOP_NOGLOB gain = shl_sat( gain, tmp16 ); /* Q15 */ -#else - gain = shl( gain, tmp16 ); /* Q15 */ -#endif BASOP_SATURATE_WARNING_ON_EVS; if ( gain < 0 ) @@ -471,20 +467,10 @@ static void bass_pf_1sf_delay( { tmp32 = L_msu0( 0, gain, syn[( i + i_subfr ) - T] ); tmp32 = L_msu0( tmp32, gain, syn[( i + i_subfr ) + T] ); -#ifdef BASOP_NOGLOB tmp16 = mac_r_sat( tmp32, gain, syn[i + i_subfr] ); /* Q0 */ -#else - tmp16 = mac_r( tmp32, gain, syn[i + i_subfr] ); /* Q0 */ -#endif lp_error = Mpy_32_16_1( lp_error, 29491 /*0.9f Q15*/ ); -#ifdef BASOP_NOGLOB lp_error = L_mac_sat( lp_error, tmp16, 0x1000 ); /* Q13 */ tmp16 = round_fx_sat( L_shl_sat( lp_error, s1 ) ); /* Q0+s1-3 */ -#else - lp_error = L_mac( lp_error, tmp16, 0x1000 ); /* Q13 */ - - tmp16 = round_fx( L_shl( lp_error, s1 ) ); /* Q0+s1-3 */ -#endif ener2_64 = W_mac0_16_16( ener2_64, tmp16, tmp16 ); /* Q0+(s1-3)*2 */ } ener2 = W_sat_l( ener2_64 ); @@ -498,7 +484,6 @@ static void bass_pf_1sf_delay( Word64 ener2_64 = W_deposit32_l( ener2 ); FOR( i = lg; i < l_subfr; i++ ) { -#ifdef BASOP_NOGLOB tmp32 = L_mult0( gain, syn[i + i_subfr] ); tmp32 = L_msu0_sat( tmp32, gain, syn[( i + i_subfr ) - T] ); /* Q0 */ tmp16 = round_fx_sat( tmp32 ); @@ -507,16 +492,6 @@ static void bass_pf_1sf_delay( lp_error = L_mac_sat( lp_error, tmp16, 0x1000 ); /* Q13 */ tmp16 = round_fx_sat( L_shl_sat( lp_error, s1 ) ); /* Q0+s1-3 */ -#else - tmp32 = L_mult0( gain, syn[i + i_subfr] ); - tmp32 = L_msu0( tmp32, gain, syn[i + i_subfr - T] ); /* Q0 */ - tmp16 = round_fx( tmp32 ); - - lp_error = Mpy_32_16_1( lp_error, 29491 /*0.9f Q15*/ ); - lp_error = L_mac( lp_error, tmp16, 0x1000 ); /* Q13 */ - - tmp16 = round_fx( L_shl( lp_error, s1 ) ); /* Q0+s1-3 */ -#endif ener2_64 = W_mac0_16_16( ener2_64, tmp16, tmp16 ); /* Q0+(s1-3)*2 */ } ener2 = W_sat_l( ener2_64 ); @@ -554,11 +529,7 @@ static void bass_pf_1sf_delay( tmp32 = L_deposit_l( 1 ); tmp16 = BASOP_Util_Divide3232_Scale( tmp, tmp32, &st ); BASOP_SATURATE_WARNING_OFF_EVS; -#ifdef BASOP_NOGLOB tmp16 = shl_sat( tmp16, sub( st, 2 ) ); /* Q15 */ -#else - tmp16 = shl( tmp16, sub( st, 2 ) ); /* Q15 */ -#endif if ( GT_16( tmp16, 16384 /*0.5f Q15*/ ) ) { @@ -584,16 +555,10 @@ static void bass_pf_1sf_delay( FOR( i = 0; i < lg; i++ ) { tmp32 = L_msu0( 0, tmp16, syn[( i + i_subfr ) - T] ); -#ifdef BASOP_NOGLOB tmp32 = L_msu0_sat( tmp32, tmp16, syn[( i + i_subfr ) + T] ); tmp32 = L_mac_sat( tmp32, tmp16, syn[i + i_subfr] ); bpf_noise_buf[i + i_subfr] = round_fx_sat( tmp32 ); /* Q0 */ move16(); -#else - tmp32 = L_msu0( tmp32, tmp16, syn[i + i_subfr + T] ); - tmp32 = L_mac( tmp32, tmp16, syn[i + i_subfr] ); - bpf_noise_buf[i + i_subfr] = round_fx( tmp32 ); /* Q0 */ -#endif } } @@ -602,14 +567,9 @@ static void bass_pf_1sf_delay( FOR( i = lg; i < l_subfr; i++ ) { tmp32 = L_mult0( tmp16, syn[i + i_subfr] ); -#ifdef BASOP_NOGLOB tmp32 = L_msu0_sat( tmp32, tmp16, syn[i + i_subfr - T] ); bpf_noise_buf[i + i_subfr] = round_fx_sat( tmp32 ); /* Q0 */ move16(); -#else - tmp32 = L_msu0( tmp32, tmp16, syn[i + i_subfr - T] ); - bpf_noise_buf[i + i_subfr] = round_fx( tmp32 ); /* Q0 */ -#endif } } } @@ -696,13 +656,8 @@ void cldfb_synth_set_bandsToZero( /* use 16-bit precision of real and imag buffers */ realQ1 = extract_l( L_shr( rAnalysis[k][i], sub( 31 + 3 - 15, scaleFactor.lb_scale ) ) ); /*31 - (15 + scaleFactor.lb_scale) + 3 )*/ imagQ1 = extract_l( L_shr( iAnalysis[k][i], sub( 31 + 3 - 15, scaleFactor.lb_scale ) ) ); /* Q(-3), headroom */ -#ifdef BASOP_NOGLOB nrgQ31 = L_mac0_o( nrgQ31, realQ1, realQ1, &Overflow ); nrgQ31 = L_mac0_o( nrgQ31, imagQ1, imagQ1, &Overflow ); /* keep in Q(-6) */ -#else - nrgQ31 = L_mac0( nrgQ31, realQ1, realQ1 ); - nrgQ31 = L_mac0( nrgQ31, imagQ1, imagQ1 ); /* keep in Q(-6) */ -#endif } nrg_band[i] = ( nrgQ31 ); move16(); diff --git a/lib_dec/ppp_dec.c b/lib_dec/ppp_dec.c deleted file mode 100644 index d1de09bc73bcde0f9193c0b1d468183cb122cda9..0000000000000000000000000000000000000000 --- a/lib_dec/ppp_dec.c +++ /dev/null @@ -1,43 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include -#include "cnst.h" -#include "prot.h" -#include "rom_com.h" -#include "wmc_auto.h" diff --git a/lib_dec/ppp_dec_fx.c b/lib_dec/ppp_dec_fx.c index 201d2cce6442081c47869f8514409c71720eef4a..00a333798ef26d9645b5c3a480cbe7c0dc267443 100644 --- a/lib_dec/ppp_dec_fx.c +++ b/lib_dec/ppp_dec_fx.c @@ -113,14 +113,9 @@ static void DTFS_dequant_cw_fx( /* Power Dequantization */ - tmp_fx = shl( POWER_IDX_fx, 1 ); /* tmp=2*POWER_IDX */ -#ifdef BASOP_NOGLOB + tmp_fx = shl( POWER_IDX_fx, 1 ); /* tmp=2*POWER_IDX */ *lastLgainD_fx = add_sat( *lastLgainD_fx, PowerCB_fx[tmp_fx] ); /* Q11 */ *lastHgainD_fx = add_sat( *lastHgainD_fx, PowerCB_fx[tmp_fx + 1] ); /* Q11 */ -#else - *lastLgainD_fx = add( *lastLgainD_fx, PowerCB_fx[tmp_fx] ); /* Q11 */ - *lastHgainD_fx = add( *lastHgainD_fx, PowerCB_fx[tmp_fx + 1] ); /* Q11 */ -#endif move16(); move16(); L_tmp = L_deposit_h( X_fx->lag_fx ); /* Q16 */ @@ -143,11 +138,7 @@ static void DTFS_dequant_cw_fx( frac = L_Extract_lc( L_tmp, &exp1 ); /* Extract exponent */ L_tmp = Pow2( 14, frac ); exp1 = sub( exp1, 14 ); -#ifdef BASOP_NOGLOB L_temp = L_shl_sat( L_tmp, add( exp1, 15 ) ); /* Q15 */ -#else - L_temp = L_shl( L_tmp, add( exp1, 15 ) ); /* Q15 */ -#endif L_tmp2 = L_temp; if ( GE_32( L_temp, 2147483647 ) ) { @@ -173,11 +164,7 @@ static void DTFS_dequant_cw_fx( frac = L_Extract_lc( L_tmp, &exp1 ); /* Extract exponent */ L_tmp = Pow2( 14, frac ); exp1 = sub( exp1, 14 ); -#ifdef BASOP_NOGLOB L_temp = L_shl_sat( L_tmp, exp1 + 15 ); /* Q15 */ -#else - L_temp = L_shl( L_tmp, exp1 + 15 ); /* Q15 */ -#endif L_tmp2 = L_temp; move32(); if ( GE_32( L_temp, 2147483647 ) ) diff --git a/lib_dec/pvq_core_dec.c b/lib_dec/pvq_core_dec.c deleted file mode 100644 index 936720d061915787d11511b5707d8c616feba14a..0000000000000000000000000000000000000000 --- a/lib_dec/pvq_core_dec.c +++ /dev/null @@ -1,44 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include -#include "cnst.h" -#include "rom_com.h" -#include "prot.h" -#include "stl.h" -#include "wmc_auto.h" diff --git a/lib_dec/pvq_core_dec_fx.c b/lib_dec/pvq_core_dec_fx.c index 6d3e24dadf3721f07adf9324312813d940d2d8ca..93da9c77a8a0ec9dc80d47a98cd2b5910c1b67e4 100644 --- a/lib_dec/pvq_core_dec_fx.c +++ b/lib_dec/pvq_core_dec_fx.c @@ -492,11 +492,7 @@ static void densitySymbolIndexDecode_fx( sym_freq = L_deposit_l( 1 ); angle = atan2_fx( SQRT_DIM_fx[opp_sz], SQRT_DIM_fx[near_sz] ); // Q13 -#ifdef BASOP_NOGLOB angle = shl_o( angle, 1, &Overflow ); -#else - angle = shl( angle, 1 ); -#endif angle = mult_r( angle, 20861 ); c = mult_r( density, angle ); density_c = sub( density, c ); diff --git a/lib_dec/pvq_decode.c b/lib_dec/pvq_decode.c deleted file mode 100644 index 8e752f0ac516550ba25f4c9dcce588dfd9e16b42..0000000000000000000000000000000000000000 --- a/lib_dec/pvq_decode.c +++ /dev/null @@ -1,42 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include -#include "prot.h" -#include "rom_com.h" -#include "wmc_auto.h" diff --git a/lib_dec/pvq_decode_fx.c b/lib_dec/pvq_decode_fx.c index 870ea25a900519019a0398f9fa36ef920748932f..649840f55ce2f942b1a2a5acfbfe16c21a456f4c 100644 --- a/lib_dec/pvq_decode_fx.c +++ b/lib_dec/pvq_decode_fx.c @@ -103,14 +103,9 @@ void pvq_decode_fx( Mpy_32_16_ss( L_isqrt, shl( y[i], shift_num ), &L_tmp, &u16_tmp ); /* Q31*Q(0+x) *2*/ Mpy_32_16_ss( L_tmp, neg_gain_norm, &L_tmp, &u16_tmp ); /* Q31*Q(0+x) *Q15 *2*/ -#ifdef BASOP_NOGLOB L_tmp = L_shr_o( L_tmp, shift_tot, &Overflow ); xq[i] = round_fx_o( L_tmp, &Overflow ); /* Q15 , array move */ move16(); -#else - L_tmp = L_shr( L_tmp, shift_tot ); - xq[i] = round_fx( L_tmp ); /* Q15 , array move */ -#endif } } diff --git a/lib_dec/range_dec.c b/lib_dec/range_dec.c deleted file mode 100644 index fd4f3cb7c53af6bc1a4a149c6db6799b8f39655e..0000000000000000000000000000000000000000 --- a/lib_dec/range_dec.c +++ /dev/null @@ -1,42 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include "cnst.h" -#include "rom_com.h" -#include "prot.h" -#include "wmc_auto.h" diff --git a/lib_dec/re8_dec.c b/lib_dec/re8_dec.c deleted file mode 100644 index e748899a9667996f0776eb65127752b66796a660..0000000000000000000000000000000000000000 --- a/lib_dec/re8_dec.c +++ /dev/null @@ -1,40 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include "prot.h" -#include "wmc_auto.h" diff --git a/lib_dec/rom_dec.c b/lib_dec/rom_dec.c index 787966f729af56f474673502dad9aecaff4fbaf1..3f5243286c21707d6fc854775d9f0830af13d6b6 100644 --- a/lib_dec/rom_dec.c +++ b/lib_dec/rom_dec.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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_dec/rom_dec.h b/lib_dec/rom_dec.h index f057b804a6080d3830eee5c671cab44a4453aa66..8c1021682a5494198dc376249596b674a7041475 100644 --- a/lib_dec/rom_dec.h +++ b/lib_dec/rom_dec.h @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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_dec/rst_dec.c b/lib_dec/rst_dec.c deleted file mode 100644 index 3b7436831d27db557be8e9ddea093277fe3a5564..0000000000000000000000000000000000000000 --- a/lib_dec/rst_dec.c +++ /dev/null @@ -1,49 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include -#include "cnst.h" -#include "rom_com.h" -#include "prot.h" -#include "wmc_auto.h" - -/*----------------------------------------------------------------------------------* - * CNG_reset_dec() - * - * Reset decoder static variables in case of CNG frame - *----------------------------------------------------------------------------------*/ diff --git a/lib_dec/rst_dec_fx.c b/lib_dec/rst_dec_fx.c index 339d828544de63bd55a07f2e493322c3469b012d..c226d8b9a68830300eec9c433d781875fde11569 100644 --- a/lib_dec/rst_dec_fx.c +++ b/lib_dec/rst_dec_fx.c @@ -61,11 +61,7 @@ void CNG_reset_dec_fx( L_tmp = L_deposit_h( tmp ); L_tmp = Isqrt_lc( L_tmp, &exp ); -#ifdef BASOP_NOGLOB st_fx->lp_gainc_fx = round_fx_sat( L_shl_sat( L_tmp, sub( exp, 12 ) ) ); /* In Q3 */ -#else - st_fx->lp_gainc_fx = round_fx( L_shl( L_tmp, sub( exp, 12 ) ) ); /* In Q3 */ -#endif move16(); } /* reset the pitch buffer in case of FRAME_NO_DATA or SID frames */ diff --git a/lib_dec/stat_dec.h b/lib_dec/stat_dec.h index 5c7f894b9023e647248b2175daa811f60a210092..530cd41d0fed9de98c364a56729a24119db8dc23 100644 --- a/lib_dec/stat_dec.h +++ b/lib_dec/stat_dec.h @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other @@ -529,32 +529,17 @@ typedef struct tcx_dec_structure typedef struct gsc_dec_structure { - Word16 seed_tcx; /* AC mode (GSC) - seed for noise fill */ - - Word16 cor_strong_limit; /* AC mode (GSC) - Indicator about high spectral correlation per band */ - // Word16 cor_strong_limit; /* AC mode (GSC) - Indicator about high spectral correlation per band */ - - Word16 old_y_gain_fx[MBANDS_GN16k]; /* AC mode (GSC) - AR mem for low rate gain quantization */ - - Word16 noise_lev; /* AC mode (GSC) - noise level */ - // Word16 noise_lev; /* AC mode (GSC) - noise level Q0*/ - + Word16 seed_tcx; /* AC mode (GSC) - seed for noise fill */ + Word16 cor_strong_limit; /* AC mode (GSC) - Indicator about high spectral correlation per band */ + Word16 old_y_gain_fx[MBANDS_GN16k]; /* AC mode (GSC) - AR mem for low rate gain quantization */ + Word16 noise_lev; /* AC mode (GSC) - noise level */ Word16 lt_ener_per_band_fx[MBANDS_GN16k]; /* Q12 */ - - Word32 Last_frame_ener_fx; /* AC mode (GSC) - last frame energy */ - - Word16 Last_GSC_spectrum_fx[L_FRAME16k]; /* AC mode (GSC) - Last good GSC spectrum */ - - Word16 Last_GSC_pit_band_idx; /* AC mode (GSC) - Last pitch band index */ - // Word16 Last_GSC_pit_band_idx; /* AC mode (GSC) - Last pitch band index Q0*/ - - Word16 last_exc_dct_in_fx[L_FRAME16k]; /* AC mode (GSC) - previous excitation */ - - Word16 last_ener_fx; /* AC mode (GSC) - previous energy */ - - Word16 last_bitallocation_band[6]; /* AC mode (GSC) - previous bit allocation of each band */ - // Word16 last_bitallocation_band[6]; /* AC mode (GSC) - previous bit allocation of each band */ - + Word32 Last_frame_ener_fx; /* AC mode (GSC) - last frame energy */ + Word16 Last_GSC_spectrum_fx[L_FRAME16k]; /* AC mode (GSC) - Last good GSC spectrum */ + Word16 Last_GSC_pit_band_idx; /* AC mode (GSC) - Last pitch band index */ + Word16 last_exc_dct_in_fx[L_FRAME16k]; /* AC mode (GSC) - previous excitation */ + Word16 last_ener_fx; /* AC mode (GSC) - previous energy */ + Word16 last_bitallocation_band[6]; /* AC mode (GSC) - previous bit allocation of each band */ } GSC_DEC_DATA, *GSC_DEC_HANDLE; @@ -566,10 +551,8 @@ typedef struct gsc_dec_structure typedef struct WI_dec_structure { Word16 old_exc2_fx[L_EXC_MEM]; /* FEC - old excitation2 used in fast recovery */ - Word16 old_syn2_fx[L_EXC_MEM]; /* FEC - old syn speech used in fast recovery */ - } WI_DEC_DATA, *WI_DEC_HANDLE; @@ -1258,12 +1241,6 @@ typedef struct amrwb_io_dec_structure } AMRWB_IO_DEC_DATA, *AMRWB_IO_DEC_HANDLE; -struct dispMem_fx -{ - Word16 prev_state; /*Q0 */ - Word32 prev_gain_code; /*Q16 */ - Word16 prev_gain_pit[6]; /*Q14 */ -}; /*----------------------------------------------------------------------------------* * diff --git a/lib_dec/stat_noise_uv_dec.c b/lib_dec/stat_noise_uv_dec.c deleted file mode 100644 index e748899a9667996f0776eb65127752b66796a660..0000000000000000000000000000000000000000 --- a/lib_dec/stat_noise_uv_dec.c +++ /dev/null @@ -1,40 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include "prot.h" -#include "wmc_auto.h" diff --git a/lib_dec/swb_bwe_dec.c b/lib_dec/swb_bwe_dec.c deleted file mode 100644 index 1dcc5c111603f6ac4fbb50eeb0838ddcfc83d865..0000000000000000000000000000000000000000 --- a/lib_dec/swb_bwe_dec.c +++ /dev/null @@ -1,680 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include -#include "cnst.h" -#include "prot.h" -#include "prot_fx.h" -#include "rom_com.h" -#include "basop_util.h" -#include "basop_proto_func.h" -#include "wmc_auto.h" - - -static Word16 para_pred_bws_fx( - Decoder_State *st_fx, /* i/o: decoder state structure */ - Word16 *signal_wb_fx, /* i : wideband frequency signal Q_syn */ - Word16 *SWB_fenv_fx, /* o : frequency-domain BWE envelope Q1 */ - Word16 Q_syn ) -{ - Word16 i, j, k; - Word16 mode; - Word16 tmp, tmp_den, tmp_num; - Word32 L_tmp, L_tmp_max; - Word16 exp; - Word16 *input_hi_fx; - Word32 *mea; - Word16 peak_fx, mag_fx; - Word32 mean_fx[7], peak_32_fx; - Word32 avrg1_fx, avrg2_fx, min_fx; - Word16 att_fx; - Word16 coder_type = st_fx->coder_type; - move16(); - - mode = NORMAL; - move16(); - - k = 0; - move16(); - input_hi_fx = &signal_wb_fx[SHARP_WIDTH]; /*Q_syn*/ - FOR( i = 0; i < 7; i++ ) - { - peak_fx = 0; - move16(); - mean_fx[i] = 0; - move16(); - FOR( j = 0; j < SHARP_WIDTH; j++ ) - { - mag_fx = abs_s( *input_hi_fx ); /*Q_syn*/ - peak_fx = s_max( peak_fx, mag_fx ); /*Q_syn*/ - mean_fx[i] = L_add( mean_fx[i], L_deposit_l( mag_fx ) ); /*Q_syn*/ - move32(); - input_hi_fx++; - } - - IF( LT_16( Q_syn, 11 ) ) - { - tmp = 1; - move16(); - } - ELSE - { - tmp = 0; - move16(); - if ( GT_16( shr( peak_fx, 3 ), shl( 1, Q_syn ) ) ) - { - tmp = 1; - move16(); - } - } - IF( tmp > 0 ) - { - L_tmp = L_msu0( Mult_32_16( L_shl( mean_fx[i], 10 ) /*Q_syn + 10*/, 18432 /*4.5f Q12*/ ), peak_fx /*Q_syn*/, 4544 /*35.5 (SHARP_WIDTH + 3.5f)Q7*/ ); - if ( L_tmp < 0 ) - { - k = add( k, 1 ); - } - } - } - - avrg1_fx = L_deposit_l( 0 ); - avrg2_fx = L_deposit_l( 0 ); - FOR( i = 1; i < 4; i++ ) - { - avrg1_fx = L_add( avrg1_fx, mean_fx[i] ); /*Q_syn*/ - avrg2_fx = L_add( avrg2_fx, mean_fx[i + 3] ); /*Q_syn*/ - } - avrg1_fx = Mult_32_16( avrg1_fx, 10923 /* 1/3 -> Q15 -> 10923 */ ); /*Q_syn + Q15 - 15*/ - avrg2_fx = Mult_32_16( avrg2_fx, 10923 /* 1/3 -> Q15 -> 10923 */ ); /*Q_syn + Q15 - 15*/ - - min_fx = L_add( 2147483647, 0 ); /*2^31 */ - peak_32_fx = L_deposit_l( 0 ); - FOR( i = 4; i < 7; i++ ) - { - IF( GT_32( mean_fx[i], L_shl( avrg2_fx, 1 ) ) ) - { - exp = norm_l( mean_fx[i] ); - IF( LT_16( exp, 16 ) ) - { - tmp_den = extract_l( L_shr( mean_fx[i], sub( 16, exp ) ) ); /*Qsyn - 16 + exp */ - tmp_num = extract_l( L_shr( avrg2_fx, sub( 15, exp ) ) ); /*Qsyn - 16 + exp */ - } - ELSE - { - tmp_den = extract_l( mean_fx[i] ); - tmp_num = extract_l( L_shl( avrg2_fx, 1 ) ); - } - - tmp_den = div_s( 1, tmp_den ); - - tmp = i_mult( tmp_num, tmp_den ); /*Q15 */ - - mean_fx[i] = Mult_32_16( mean_fx[i], tmp ); /*Q_syn + Q15 - 15*/ - move32(); - } - min_fx = L_min( min_fx, mean_fx[i] ); - peak_32_fx = L_max( peak_32_fx, mean_fx[i] ); - } - - IF( GT_16( st_fx->tilt_wb_fx, 16384 /*8 in Q11*/ ) ) - { - IF( GT_16( st_fx->tilt_wb_fx, 30720 /*15.0f in Q11*/ ) ) - { - min_fx = peak_32_fx; - move32(); - } - ELSE - { - tmp = extract_l( L_shr( L_mult0( st_fx->tilt_wb_fx, 17476 ), 14 ) ); /*Q15 */ - min_fx = Mult_32_16( peak_32_fx, tmp ); - } - } - - test(); - IF( peak_32_fx == 0 || min_fx == 0 ) - { - set16_fx( SWB_fenv_fx, 0, SWB_FENV ); - } - ELSE - { - exp = norm_l( peak_32_fx ); - IF( LT_16( exp, 16 ) ) - { - tmp_den = extract_l( L_shr( peak_32_fx, sub( 16, exp ) ) ); /*Qsyn - 16 + exp */ - tmp = div_s( 16384, tmp_den ); /*Q15+14 - (Qsyn - 16 + exp) */ - tmp_num = extract_l( L_shr( min_fx, sub( 16, exp ) ) ); /*Qsyn - 16 + exp */ - tmp = extract_l( L_shr( L_mult0( tmp_num, tmp ), 14 ) ); /*Q15 */ - } - ELSE - { - tmp_den = extract_l( peak_32_fx ); /*Qsyn */ - exp = norm_s( tmp_den ); - tmp = div_s( shl( 1, sub( 14, exp ) ), tmp_den ); /*Q 29-exp - Qsyn */ - tmp_num = extract_l( min_fx ); /*Qsyn */ - tmp = extract_l( L_shr( L_mult0( tmp_num, tmp ), sub( 14, exp ) ) ); /*Q15 */ - } - - j = 0; - move16(); - mea = &mean_fx[4]; - L_tmp_max = L_shl( 32767, add( Q_syn, 5 ) ); - FOR( i = 0; i < SWB_FENV; i++ ) - { - if ( EQ_16( j, 5 ) ) - { - mea++; - j = 0; - move16(); - } - j = add( j, 1 ); - L_tmp = L_min( Mult_32_16( *mea, tmp ), L_tmp_max ); - SWB_fenv_fx[i] = extract_l( L_shr( L_tmp, add( Q_syn, 5 ) ) ); - move16(); - } - } - - j = 0; - move16(); - FOR( i = SWB_FENV / 2; i < SWB_FENV; i++ ) - { - tmp = sub( 32767, i_mult( j, 2341 ) ); - SWB_fenv_fx[i] = mult_r( SWB_fenv_fx[i], tmp ); - move16(); - j = add( j, 1 ); - } - - IF( GT_32( avrg1_fx, L_shl( avrg2_fx, 3 ) ) ) - { - FOR( i = 0; i < SWB_FENV; i++ ) - { - SWB_fenv_fx[i] = shr( SWB_fenv_fx[i], 1 ); - move16(); - } - } - - test(); - test(); - test(); - test(); - test(); - IF( NE_16( st_fx->last_core, HQ_CORE ) && EQ_16( st_fx->last_codec_mode, MODE1 ) && - ( GT_32( st_fx->enerLH_fx, L_shr( st_fx->prev_enerLH_fx, 1 ) ) && LT_32( L_shr( st_fx->enerLH_fx, 1 ), st_fx->prev_enerLH_fx ) ) && - ( GT_32( st_fx->enerLL_fx, L_shr( st_fx->prev_enerLL_fx, 1 ) ) && LT_32( L_shr( st_fx->enerLL_fx, 1 ), st_fx->prev_enerLL_fx ) ) ) - { - FOR( i = 0; i < SWB_FENV; i++ ) - { - test(); - IF( NE_16( st_fx->prev_coder_type, coder_type ) && GT_16( mult_r( SWB_fenv_fx[i], 16384 /*1/2.0f in Q15*/ ), st_fx->prev_SWB_fenv_fx[i] ) ) - { - SWB_fenv_fx[i] = round_fx( L_mac( L_mult( SWB_fenv_fx[i], 3277 /*0.1f in Q15*/ ), st_fx->prev_SWB_fenv_fx[i], 29491 /*0.9f in Q15*/ ) ); - move16(); - } - ELSE - { - SWB_fenv_fx[i] = round_fx( L_mac( L_mult( SWB_fenv_fx[i], st_fx->attenu_fx ), st_fx->prev_SWB_fenv_fx[i], sub( 32767 /*1.0f in Q15*/, st_fx->attenu_fx ) ) ); - move16(); - } - } - - IF( LT_16( st_fx->attenu_fx, 29491 /*0.9f in Q15*/ ) ) - { - st_fx->attenu_fx = add( st_fx->attenu_fx, 1638 /*0.05f in Q15*/ ); - move16(); - } - } - ELSE - { - test(); - test(); - test(); - test(); - IF( NE_32( st_fx->core_brate, st_fx->last_core_brate ) || ( GT_32( st_fx->enerLH_fx, L_shr( st_fx->prev_enerLH_fx, 1 ) ) && LT_32( L_shr( st_fx->enerLH_fx, 1 ), st_fx->prev_enerLH_fx ) ) || - ( GT_32( st_fx->enerLL_fx, L_shr( st_fx->prev_enerLL_fx, 1 ) ) && LT_32( L_shr( st_fx->enerLL_fx, 1 ), st_fx->prev_enerLL_fx ) ) ) - { - FOR( i = 0; i < SWB_FENV; i++ ) - { - if ( GT_16( mult_r( SWB_fenv_fx[i], 16384 /*0.5f in Q15*/ ), st_fx->prev_SWB_fenv_fx[i] ) ) - { - SWB_fenv_fx[i] = st_fx->prev_SWB_fenv_fx[i]; - move16(); - } - } - } - - FOR( i = 0; i < SWB_FENV; i++ ) - { - SWB_fenv_fx[i] = round_fx( L_mac( L_mult( SWB_fenv_fx[i], 29491 /*0.9f in Q15*/ ), st_fx->prev_SWB_fenv_fx[i], 3277 /*0.1f in Q15*/ ) ); - move16(); - } - st_fx->attenu_fx = 3277; /*Q15*/ - move16(); - } - - if ( GT_16( k, 3 ) ) - { - mode = HARMONIC; - move16(); - } - - - att_fx = i_mult( sub( N_WS2N_FRAMES, st_fx->bws_cnt ), 819 ); /*15 */ - IF( EQ_16( st_fx->L_frame, L_FRAME16k ) ) - { - FOR( i = 0; i < 4; i++ ) - { - SWB_fenv_fx[i] = mult_r( SWB_fenv_fx[i], att_fx ); - move16(); /*Q1 */ - } - } - - FOR( i = 4; i < SWB_FENV; i++ ) - { - SWB_fenv_fx[i] = mult_r( SWB_fenv_fx[i], att_fx ); - move16(); /*Q1 */ - } - - return mode; -} - - -/*-------------------------------------------------------------------* - * WB_BWE_gain_deq() - * - * Decoding of WB parameters - *-------------------------------------------------------------------*/ - - -Word16 swb_bwe_dec_fx32( - Decoder_State *st_fx, /* i/o: decoder state structure */ - Word32 output_fx[], /* i : synthesis @internal Fs : Q11 */ - Word32 *synth_fx, /* i : ACELP core synthesis/final synthesis : Q11 */ - Word32 *hb_synth_fx, /* o : SHB synthesis/final synthesis : Q_syn_hb */ - Word16 use_cldfb_for_dft, /* i : flag to use of CLDFB for DFT Stereo */ - Word16 output_frame /* i : frame length */ -) -{ - Word16 L; - Word16 mode; - Word16 idxGain; - Word16 i, j, l_subfr; - Word16 fb_band_begin; - Word16 frica_flag = 0; - move16(); - Word16 ener_adjust_quan_fx; - Word16 fb_ener_adjust_fx = 0; - move16(); - Word16 scl, new_input_fx_exp, ysynth_frame_size; - Word16 Q_syn, Q_syn_hb, tmp, tmp2, q_tmp, Qsynth_fx16; - - Word16 ysynth_fx[L_FRAME48k]; - Word16 SWB_fenv_fx[SWB_FENV]; - Word16 SWB_tenv_fx[SWB_TENV]; - Word16 synth_fx16[L_FRAME48k]; - Word16 hb_synth_fx16[L_FRAME48k]; - - Word32 L_tmp; - Word32 yerror_fx[L_FRAME48k]; - Word32 ysynth_fx32[L_FRAME48k]; - Word32 SWB_tenv_tmp_fx[SWB_TENV]; - Word32 wtda_synth_fx[2 * L_FRAME48k]; - - FD_BWE_DEC_HANDLE hBWE_FD; - hBWE_FD = st_fx->hBWE_FD; - - /*---------------------------------------------------------------------* - * SWB BWE decoding - *---------------------------------------------------------------------*/ - test(); - IF( EQ_16( st_fx->element_mode, IVAS_CPE_DFT ) && !use_cldfb_for_dft ) - { - /* todo - wtda() does not support L_FRAME length; thus temporarily resample the signal */ - /* todo - delay output[] by 1.25ms ? */ - L_lerp_fx_q11( output_fx, ysynth_fx32, L_FRAME16k, st_fx->L_frame ); - - /* windowing of the ACELP core synthesis */ - wtda_fx32( ysynth_fx32, wtda_synth_fx, hBWE_FD->L_old_wtda_swb_fx32, ALDO_WINDOW, ALDO_WINDOW, /*st_fx->L_frame*/ L_FRAME16k ); - - /* DCT of the ACELP core synthesis */ - new_input_fx_exp = 11; - move16(); - direct_transform_fx( wtda_synth_fx, ysynth_fx32, 0, /*st_fx->L_frame*/ L_FRAME16k, &new_input_fx_exp, st_fx->element_mode ); - ysynth_frame_size = L_FRAME16k; - move16(); - } - ELSE - { - /* windowing of the ACELP core synthesis */ - wtda_fx32( synth_fx, wtda_synth_fx, hBWE_FD->L_old_wtda_swb_fx32, ALDO_WINDOW, ALDO_WINDOW, output_frame ); - - /* DCT of the ACELP core synthesis */ - new_input_fx_exp = 11; - move16(); - direct_transform_fx( wtda_synth_fx, ysynth_fx32, 0, output_frame, &new_input_fx_exp, st_fx->element_mode ); - ysynth_frame_size = output_frame; - move16(); - } - - /* Convert to 16 Bits (Calc Shift Required to Stay within MAX_Q_NEW_INPUT) */ - scl = sub( 16 + 11, new_input_fx_exp ); - /* Possible to Upscale? */ - IF( scl > 0 ) - { - /* Yes */ - /* Calc Room to Upscale */ - Q_syn = sub( Find_Max_Norm32( ysynth_fx32, ysynth_frame_size ), 3 ); - /* Stay within MAX_Q_NEW_INPUT */ - scl = s_min( Q_syn, scl ); - } - /*Don't upscale if already in 15 bits*/ - IF( GT_16( scl, 15 ) ) - { - FOR( i = 0; i < ysynth_frame_size; i++ ) - { - ysynth_fx[i] = extract_l( ysynth_fx32[i] ); - move16(); - } - Q_syn = new_input_fx_exp; - move16(); - } - ELSE - { - Copy_Scale_sig32_16( ysynth_fx32, ysynth_fx, ysynth_frame_size, scl ); - Q_syn = add( sub( new_input_fx_exp, 16 ), scl ); - } - - IF( !st_fx->bfi ) - { - IF( st_fx->bws_cnt > 0 ) - { - /* estimate parameters */ - mode = para_pred_bws_fx( st_fx, ysynth_fx, SWB_fenv_fx, Q_syn ); - } - ELSE - { - /* de-quantization */ - mode = swb_bwe_gain_deq_fx( st_fx, ACELP_CORE, SWB_tenv_fx, SWB_fenv_fx, 0, -1 ); - } - - L = SWB_FENV; - move16(); - if ( EQ_16( mode, TRANSIENT ) ) - { - L = SWB_FENV_TRANS; - move16(); - } - - L_tmp = 0; - move32(); - FOR( i = 0; i < L; i++ ) - { - L_tmp = L_add( L_tmp, L_deposit_l( SWB_fenv_fx[i] ) ); - } - q_tmp = norm_s( L ); - tmp = div_s( shl( 1, sub( 14, q_tmp ) ), L ); /*Q(29-q_tmp) */ - L_tmp = Mpy_32_16_1( L_tmp, tmp ); /*Q(1+29-q_tmp+1-16)->Q(15-q_tmp) */ - st_fx->prev_ener_shb_fx = round_fx( L_shl( L_tmp, add( q_tmp, 2 ) ) ); /*Q1 */ - move16(); - } - ELSE - { - /* SHB FEC */ - - IF( NE_16( hBWE_FD->prev_mode, TRANSIENT ) ) - { - mode = hBWE_FD->prev_mode; - move16(); - } - ELSE - { - mode = NORMAL; - move16(); - } - - Copy( st_fx->prev_SWB_fenv_fx, SWB_fenv_fx, SWB_FENV ); - } - - /* reconstruction of MDCT spectrum of the error signal */ - set32_fx( yerror_fx, 0, output_frame ); - - IF( EQ_16( st_fx->L_frame, L_FRAME16k ) ) - { - SWB_BWE_decoding_fx( ysynth_fx, SWB_fenv_fx, yerror_fx, L_FRAME32k - 80, mode, &frica_flag, &hBWE_FD->prev_Energy_fx, st_fx->prev_SWB_fenv_fx, &hBWE_FD->prev_L_swb_norm, st_fx->tilt_wb_fx, &hBWE_FD->Seed, 80, &hBWE_FD->prev_weight_fx, st_fx->extl, Q_syn, st_fx->last_extl ); - } - ELSE - { - SWB_BWE_decoding_fx( ysynth_fx, SWB_fenv_fx, yerror_fx, L_FRAME32k - 80, mode, &frica_flag, &hBWE_FD->prev_Energy_fx, st_fx->prev_SWB_fenv_fx, &hBWE_FD->prev_L_swb_norm, st_fx->tilt_wb_fx, &hBWE_FD->Seed, 6, &hBWE_FD->prev_weight_fx, st_fx->extl, Q_syn, st_fx->last_extl ); - } - - test(); - IF( EQ_16( hBWE_FD->prev_frica_flag, 1 ) && frica_flag == 0 ) - { - FOR( i = 0; i < L_SUBFR; i++ ) - { - tmp = sub( 32767, extract_l( L_mult0( i, 512 ) ) ); /*Q15 */ - hBWE_FD->mem_imdct_fx[i] = mult_r( hBWE_FD->mem_imdct_fx[i], tmp ); - move16(); - } - - FOR( ; i < output_frame; i++ ) - { - hBWE_FD->mem_imdct_fx[i] = 0; - move16(); - } - } - - /* decode information */ - IF( EQ_16( st_fx->extl, FB_BWE ) ) - { - IF( !st_fx->bfi ) - { - idxGain = (Word16) get_next_indice_fx( st_fx, NUM_BITS_FB_FRAMEGAIN ); - fb_ener_adjust_fx = usdequant_fx( idxGain, FB_GAIN_QLOW_FX, FB_GAIN_QDELTA_FX ); /*Q15 */ - } - ELSE IF( st_fx->bfi ) - { - fb_ener_adjust_fx = st_fx->prev_fb_ener_adjust_fx; - move16(); - } - - st_fx->prev_fb_ener_adjust_fx = fb_ener_adjust_fx; - move16(); - IF( EQ_16( mode, TRANSIENT ) ) - { - ener_adjust_quan_fx = shr( fb_ener_adjust_fx, 2 ); - } - ELSE - { - IF( SWB_fenv_fx[7] != 0 ) - { - tmp = div_s( 1, SWB_fenv_fx[7] ); - ener_adjust_quan_fx = s_min( shr( i_mult_sat( SWB_fenv_fx[13], tmp ), 2 ), 32767 ); - } - ELSE - { - ener_adjust_quan_fx = 0; - move16(); - } - } - - fb_band_begin = FB_BAND_BEGIN; - move16(); - if ( EQ_16( st_fx->L_frame, L_FRAME ) ) - { - fb_band_begin = FB_BAND_BEGIN_12k8; - move16(); - } - - j = 0; - move16(); - FOR( i = fb_band_begin; i < add( fb_band_begin, DE_OFFSET1 ); i++ ) - { - tmp = sub( 32767, i_mult( j, 1024 ) ); - tmp = mult_r( tmp, ener_adjust_quan_fx ); /*Q13*/ - - tmp2 = i_mult( j, 256 ); /*Q13*/ - tmp2 = mult_r( tmp2, fb_ener_adjust_fx ); /*Q13*/ - - tmp = add( tmp, tmp2 ); /*Q13*/ - yerror_fx[i] = L_shl( Mpy_32_16_1( yerror_fx[i - FB_BAND_WIDTH], tmp ), 2 ); /*15+Q_syn */ - move32(); - j = add( j, 1 ); - } - FOR( ; i < FB_BAND_END; i++ ) - { - yerror_fx[i] = Mpy_32_16_1( yerror_fx[i - FB_BAND_WIDTH], fb_ener_adjust_fx ); /*15+Q_syn */ - move32(); - } - } - - /* iDCT of the error signal */ - Q_syn_hb = add( Q_syn, 15 ); - Inverse_Transform( yerror_fx, &Q_syn_hb, wtda_synth_fx, 0, output_frame, -1, st_fx->element_mode ); - - /* inverse windowing of the error signal */ - window_ola_fx( wtda_synth_fx, hb_synth_fx16, &Q_syn_hb, hBWE_FD->mem_imdct_fx, &hBWE_FD->mem_imdct_exp_fx, output_frame, ALDO_WINDOW, ALDO_WINDOW, 0, 0, 0 ); - l_subfr = mult( output_frame, 8192 ); - - test(); - IF( EQ_16( mode, TRANSIENT ) ) - { - FOR( i = 0; i < SWB_TENV; i++ ) - { - SWB_tenv_tmp_fx[i] = L_mult0( SWB_tenv_fx[i] /*Q0*/, 26214 /*0.8f Q15*/ ); // Q15 - move32(); - } - - /* time envelope shaping when the current frame is TRANSIENT frame */ - time_envelop_shaping_fx( hb_synth_fx16, SWB_tenv_tmp_fx, output_frame, &Q_syn_hb ); - Q_syn_hb = sub( Q_syn_hb, 3 ); - - hBWE_FD->prev_td_energy_fx = SWB_tenv_fx[3]; - move16(); - } - ELSE IF( EQ_16( frica_flag, 1 ) && hBWE_FD->prev_frica_flag == 0 ) - { - Qsynth_fx16 = Find_Max_Norm32( synth_fx, output_frame ); - Qsynth_fx16 = sub( Qsynth_fx16, shr( add( sub( 15, norm_s( l_subfr ) ), 1 ), 1 ) ); - Copy_Scale_sig32_16( synth_fx, synth_fx16, output_frame, Qsynth_fx16 ); - Qsynth_fx16 = add( 11 - 16, Qsynth_fx16 ); - - /* IVAS_fmToDo: synth[] is @internal_Fs!!! */ - time_reduce_pre_echo_fx( synth_fx16, hb_synth_fx16, hBWE_FD->prev_td_energy_fx, l_subfr, Qsynth_fx16, Q_syn_hb ); - } - ELSE - { - tmp = i_mult2( 3, l_subfr ); - L_tmp = L_deposit_l( 0 ); - - FOR( i = 0; i < l_subfr; i++ ) - { - L_tmp = L_mac0_sat( L_tmp, hb_synth_fx16[add( tmp, i )], hb_synth_fx16[add( tmp, i )] ); /*(2*Q_syn_hb) */ - } - - L_tmp = Mult_32_16( L_tmp, div_s( 1, l_subfr ) ); /*(2*Q_syn_hb) */ - hBWE_FD->prev_td_energy_fx = 0; - move16(); - - IF( L_tmp != 0 ) - { - q_tmp = norm_l( L_tmp ); - tmp = extract_h( L_shl( L_tmp, q_tmp ) ); - q_tmp = sub( q_tmp, sub( 30, shl( Q_syn_hb, 1 ) ) ); - - tmp = div_s( 16384, tmp ); - L_tmp = L_deposit_h( tmp ); - L_tmp = Isqrt_lc( L_tmp, &q_tmp ); /*Q(31-exp) */ - hBWE_FD->prev_td_energy_fx = round_fx( L_shl( L_tmp, sub( q_tmp, 15 ) ) ); /*Q0 */ - move16(); - } - } - - test(); - IF( EQ_16( st_fx->element_mode, IVAS_CPE_DFT ) && !use_cldfb_for_dft ) - { - Qsynth_fx16 = add( 16 - 11, Q_syn_hb ); - Copy_Scale_sig32_16( synth_fx, synth_fx16, output_frame, Qsynth_fx16 ); - - /* add HB synth from hf_synth() */ - v_add_16( hb_synth_fx16, synth_fx16, hb_synth_fx16, output_frame ); - } - - hBWE_FD->prev_mode = mode; - move16(); - hBWE_FD->prev_frica_flag = frica_flag; - move16(); - - FOR( i = 0; i < output_frame; i++ ) - { - hb_synth_fx[i] = L_deposit_l( hb_synth_fx16[i] ); // Q_syn_hb - move32(); - } - - return Q_syn_hb; -} - - -void fd_bwe_dec_init_fx( - FD_BWE_DEC_HANDLE hBWE_FD /* i/o: FD BWE data handle */ -) -{ - set16_fx( hBWE_FD->L_old_wtda_swb_fx, 0, L_FRAME48k ); - set16_fx( hBWE_FD->old_syn_12k8_16k_fx, 0, NS2SA_FX2( 16000, DELAY_FD_BWE_ENC_NS ) ); - hBWE_FD->prev_mode = NORMAL; - move16(); - hBWE_FD->prev_Energy_fx = 0; - move16(); - hBWE_FD->prev_L_swb_norm = 8; - move16(); - hBWE_FD->Seed = 21211; - move16(); - hBWE_FD->prev_frica_flag = 0; - move16(); - set16_fx( hBWE_FD->mem_imdct_fx, 0, L_FRAME48k ); - hBWE_FD->prev_td_energy_fx = 0; - move16(); - hBWE_FD->prev_weight_fx = 0; - move16(); - hBWE_FD->prev_flag = 0; - move16(); - hBWE_FD->prev_Energy_wb_fx = 0; - move32(); - hBWE_FD->mem_deemph_old_syn_fx = 0; - move16(); - - return; -} diff --git a/lib_dec/swb_bwe_dec_fx.c b/lib_dec/swb_bwe_dec_fx.c index cd30df7c3fdb908afabc134c83b9814da2cfaabf..b91dcdf328f1d9151f6574777ff24e73d0324304 100644 --- a/lib_dec/swb_bwe_dec_fx.c +++ b/lib_dec/swb_bwe_dec_fx.c @@ -505,19 +505,12 @@ Word16 ivas_wb_bwe_dec_fx( /* o : } Word16 wb_bwe_dec_fx( -#ifdef ADD_IVAS_BWE - const Word16 output[], /* i : suntehsis @ internal Fs */ -#endif - Word16 *synth_fx, /* i/o: ACELP core synthesis/final synthesis Q0/Qpost */ - Word16 *hb_synth_fx, /* o : SHB synthesis/final synthesis Q_syn_hb */ -#ifdef ADD_IVAS_BWE - const Word16 use_cldfb_for_dft, /* i : flag to use of CLDFB for DFT Stereo */ -#endif + Word16 *synth_fx, /* i/o: ACELP core synthesis/final synthesis Q0/Qpost */ + Word16 *hb_synth_fx, /* o : SHB synthesis/final synthesis Q_syn_hb */ const Word16 output_frame, /* i : frame length */ Word16 *voice_factors_fx, /* i : voicing factors Q15 */ const Word16 pitch_buf_fx[], /* i : pitch buffer Q6 */ - Decoder_State *st_fx /* i/o: decoder state structure */ - , + Decoder_State *st_fx, /* i/o: decoder state structure */ Word16 *Qpost ) { Word16 mode; @@ -538,18 +531,7 @@ Word16 wb_bwe_dec_fx( new_input_fx_exp = *Qpost; move16(); -#ifdef ADD_IVAS_BWE - if ( st->element_mode == IVAS_CPE_DFT && !use_cldfb_for_dft ) - { - /* IVAS_fmToDo: wtda() does not support L_FRAME length; thus temporarily resample the signal */ - /* IVAS_fmToDo: delay output[] by 1.25ms ? */ - lerp( output, ysynth, L_FRAME16k, st->L_frame ); - wtda( ysynth, wtda_synth, hBWE_FD->old_wtda_swb, ALDO_WINDOW, ALDO_WINDOW, /*st->L_frame*/ L_FRAME16k ); - direct_transform( wtda_synth, ysynth, 0, /*st->L_frame*/ L_FRAME16k, st->element_mode ); - } - else -#endif { wtda_fx( synth_fx, &new_input_fx_exp, L_wtda_synth_fx, hBWE_FD->L_old_wtda_swb_fx, &hBWE_FD->old_wtda_swb_fx_exp, ALDO_WINDOW, ALDO_WINDOW, /* window overlap of current frame (0: full, 2: none, or 3: half) */ @@ -574,19 +556,11 @@ Word16 wb_bwe_dec_fx( Q_syn = add( sub( new_input_fx_exp, 16 ), scl ); IF( !st_fx->bfi ) { -#ifdef ADD_IVAS_BWE - IF( st_fx->extl_brate > 0 ) -#else IF( EQ_32( st_fx->total_brate, ACELP_13k20 ) ) -#endif { /* de-quantization */ mode = WB_BWE_gain_deq_fx( st_fx, WB_fenv_fx ); -#ifdef BASOP_NOGLOB st_fx->last_wb_bwe_ener_fx = mult_r( add_sat( WB_fenv_fx[0], WB_fenv_fx[1] ), 16384 ); // this would not saturate if written like : rounf_fx(L_mac(L_mult(WB_fenv_fx[0], 16384), WB_fenv_fx[1], 16384)) -#else - st_fx->last_wb_bwe_ener_fx = mult_r( add( WB_fenv_fx[0], WB_fenv_fx[1] ), 16384 ); -#endif move16(); } ELSE @@ -658,20 +632,15 @@ Word16 wb_bwe_dec_fx( window_ola_fx( t_audio32_tmp, hb_synth_fx, &Q_syn_hb, hBWE_FD->mem_imdct_fx, &hBWE_FD->mem_imdct_exp_fx, output_frame, ALDO_WINDOW, ALDO_WINDOW, 0, 0, 0 ); -#ifdef ADD_IVAS_BWE - test(); - IF( EQ_16( st_fx->element_mode, IVAS_CPE_DFT ) && !use_cldfb_for_dft ) - { - /* add HB synth from hf_synth() */ - v_add( hb_synth, synth, hb_synth, output_frame ); - } -#endif hBWE_FD->prev_mode = mode; move16(); st_fx->prev_Q_synth = Q_syn; move16(); + return Q_syn_hb; } + + /*-------------------------------------------------------------------* * swb_bwe_gain_deq() * @@ -737,13 +706,9 @@ Word16 swb_bwe_gain_deq_fx( /* o : BWE class /*tmp = indice[1]*DIM_TR2*/ tmp = shl( indice[1], 1 ); -#ifdef BASOP_NOGLOB quant_tmp[1] = add_sat( shr( add_sat( quant_tmp[0], quant_tmp[2] ), 1 ), Env_TR_Cdbk2_fx[tmp] ); /* To prevent an unnecessary saturation, it would be better to write the code as below, but might have an impact on EVS bit exactness */ /* quant_tmp[1] = add( extract_h( L_mac( L_mult( quant_tmp[0], 16384 ), quant_tmp[2], 16384 ) ), Env_TR_Cdbk2_fx[tmp] ); */ -#else - quant_tmp[1] = add( shr( add( quant_tmp[0], quant_tmp[2] ), 1 ), Env_TR_Cdbk2_fx[tmp] ); -#endif move16(); /*Q8 */ quant_tmp[3] = add( quant_tmp[2], Env_TR_Cdbk2_fx[tmp + 1] ); move16(); /*Q8 */ @@ -844,11 +809,7 @@ Word16 swb_bwe_gain_deq_fx( /* o : BWE class FOR( n_band = 0; n_band < 5; n_band++ ) { -#ifdef BASOP_NOGLOB SWB_fenv[n_band * 2 + 1] = add_sat( shr( add_sat( quant_tmp[n_band], quant_tmp[n_band + 1] ), 1 ), quant_tmp2[n_band + 1] ); -#else - SWB_fenv[add( shl( n_band, 1 ), 1 )] = add( shr( add( quant_tmp[n_band], quant_tmp[n_band + 1] ), 1 ), quant_tmp2[n_band + 1] ); -#endif move16(); /*Q8 */ } @@ -867,11 +828,7 @@ Word16 swb_bwe_gain_deq_fx( /* o : BWE class FOR( n_band = 0; n_band < DIM12 - 1; n_band++ ) { -#ifdef BASOP_NOGLOB SWB_fenv[n_band * 2 + 1] = add_sat( shr( add_sat( quant_tmp[n_band], quant_tmp[n_band + 1] ), 1 ), quant_tmp2[n_band] ); -#else - SWB_fenv[add( shl( n_band, 1 ), 1 )] = add( shr( add( quant_tmp[n_band], quant_tmp[n_band + 1] ), 1 ), quant_tmp2[n_band] ); -#endif move16(); /*Q8 */ } @@ -891,11 +848,7 @@ Word16 swb_bwe_gain_deq_fx( /* o : BWE class /* output of Pow2() will be: */ /* 16384 < Pow2() <= 32767 */ exp = sub( exp, 13 ); -#ifdef BASOP_NOGLOB SWB_fenv[n_band] = shl_sat( tmp, add( exp, 1 ) ); -#else - SWB_fenv[n_band] = shl( tmp, add( exp, 1 ) ); -#endif move16(); /*Q1 */ } @@ -930,18 +883,11 @@ Word16 swb_bwe_gain_deq_fx( /* o : BWE class * * SWB BWE decoder *-------------------------------------------------------------------*/ -Word16 swb_bwe_dec_fx( /*o :Q_syn_hb*/ -#ifdef ADD_IVAS_BWE - const Word16 output[], /* i : suntehsis @ internal Fs */ -#endif - Decoder_State *st_fx, /* i/o: decoder state structure */ - Word16 *synth_fx, /* i/o: ACELP core synthesis/final synthesis (might be rescaled inside wtda() ) Q0/Qpost */ - Word16 *hb_synth_fx, /* o : SHB synthesis/final synthesis Q_syn_hb */ -#ifdef ADD_IVAS_BWE - const Word16 use_cldfb_for_dft, /* i : flag to use of CLDFB for DFT Stereo */ -#endif - const Word16 output_frame /* i : frame length */ - , +Word16 swb_bwe_dec_fx( /*o :Q_syn_hb*/ + Decoder_State *st_fx, /* i/o: decoder state structure */ + Word16 *synth_fx, /* i/o: ACELP core synthesis/final synthesis (might be rescaled inside wtda() ) Q0/Qpost */ + Word16 *hb_synth_fx, /* o : SHB synthesis/final synthesis Q_syn_hb */ + const Word16 output_frame, /* i : frame length */ Word16 *Qpost ) { Word16 i, l_subfr; @@ -977,19 +923,7 @@ Word16 swb_bwe_dec_fx( /*o :Q_syn_hb*/ /* windowing of the ACELP core synthesis */ new_input_fx_exp = *Qpost; move16(); -#ifdef ADD_IVAS_BWE - if ( st->element_mode == IVAS_CPE_DFT && !use_cldfb_for_dft ) - { - /* IVAS_fmToDo: wtda() does not support L_FRAME length; thus temporarily resample the signal */ - /* IVAS_fmToDo: delay output[] by 1.25ms ? */ - lerp( output, ysynthIfx, L_FRAME16k, st_fx->L_frame ); - wtda_fx( ysynth_fx, &new_input_fx_exp, L_wtda_synth_fx, hBWE_FD->L_old_wtda_swb_fx, - &hBWE_FD->old_wtda_swb_fx_exp, ALDO_WINDOW, ALDO_WINDOW, /*st->L_frame*/ L_FRAME16k ); - direct_transform_fx( L_wtda_synth_fx, ysynth_32, 0, /*st->L_frame*/ L_FRAME16k, &new_input_fx_exp, st_fx->element_mode ); - } - else -#endif { wtda_fx( synth_fx, &new_input_fx_exp, L_wtda_synth_fx, hBWE_FD->L_old_wtda_swb_fx, &hBWE_FD->old_wtda_swb_fx_exp, @@ -1121,12 +1055,8 @@ Word16 swb_bwe_dec_fx( /*o :Q_syn_hb*/ IF( SWB_fenv_fx[7] != 0 ) { tmp = div_s( 1, SWB_fenv_fx[7] ); - move16(); /*Q14*/ -#ifdef BASOP_NOGLOB + move16(); /*Q14*/ ener_adjust_quan_fx = s_min( shr( i_mult_sat( SWB_fenv_fx[13], tmp ), 2 ), 32767 ); /*Q13*/ -#else - ener_adjust_quan_fx = s_min( shr( i_mult( SWB_fenv_fx[13], tmp ), 2 ), 32767 ); -#endif } ELSE { @@ -1136,12 +1066,7 @@ Word16 swb_bwe_dec_fx( /*o :Q_syn_hb*/ } fb_band_begin = FB_BAND_BEGIN; move16(); -#ifdef ADD_IVAS_BWE - IF( st_fx->L_frame == L_FRAME ) - { - fb_band_begin = FB_BAND_BEGIN_12k8; - } -#endif + FOR( i = fb_band_begin; i < add( fb_band_begin, DE_OFFSET1 ); i++ ) { tmp = sub( 32767, i_mult( j, 1024 ) ); @@ -1198,11 +1123,7 @@ Word16 swb_bwe_dec_fx( /*o :Q_syn_hb*/ L_tmp = L_deposit_l( 0 ); FOR( i = 0; i < l_subfr; i++ ) { -#ifdef BASOP_NOGLOB L_tmp = L_mac0_sat( L_tmp, hb_synth_fx[add( tmp, i )], hb_synth_fx[add( tmp, i )] ); /*(2*Q_syn_hb) */ -#else - L_tmp = L_mac0( L_tmp, hb_synth_fx[tmp + i], hb_synth_fx[tmp + i] ); /*(2*Q_syn_hb) */ -#endif } L_tmp = Mult_32_16( L_tmp, div_s( 1, l_subfr ) ); /*(2*Q_syn_hb) */ @@ -1221,14 +1142,7 @@ Word16 swb_bwe_dec_fx( /*o :Q_syn_hb*/ move16(); } } -#ifdef ADD_IVAS_BWE - test(); - IF( EQ_16( st_fx->element_mode, IVAS_CPE_DFT ) && !use_cldfb_for_dft ) - { - /* add HB synth from hf_synth() */ - v_add( hb_synth, synth, hb_synth, output_frame ); - } -#endif + hBWE_FD->prev_frica_flag = frica_flag; move16(); hBWE_FD->prev_mode = mode; @@ -1251,7 +1165,7 @@ void fd_bwe_dec_init( { hBWE_FD->old_wtda_wb_fx_exp = 0; move16(); - set16_fx( hBWE_FD->old_syn_12k8_16k_fx, 0, NS2SA_FX2( 16000, DELAY_FD_BWE_ENC_NS ) ); + set16_fx( hBWE_FD->old_syn_12k8_16k_fx, 0, NS2SA( 16000, DELAY_FD_BWE_ENC_NS ) ); set16_fx( hBWE_FD->L_old_wtda_swb_fx, 0, L_FRAME48k ); hBWE_FD->old_wtda_swb_fx_exp = 0; move16(); @@ -1294,3 +1208,371 @@ void fd_bwe_dec_init( return; } + +/*-------------------------------------------------------------------* + * WB_BWE_gain_deq() + * + * Decoding of WB parameters + *-------------------------------------------------------------------*/ + + +Word16 swb_bwe_dec_fx32( + Decoder_State *st_fx, /* i/o: decoder state structure */ + Word32 output_fx[], /* i : synthesis @internal Fs : Q11 */ + Word32 *synth_fx, /* i : ACELP core synthesis/final synthesis : Q11 */ + Word32 *hb_synth_fx, /* o : SHB synthesis/final synthesis : Q_syn_hb */ + Word16 use_cldfb_for_dft, /* i : flag to use of CLDFB for DFT Stereo */ + Word16 output_frame /* i : frame length */ +) +{ + Word16 L; + Word16 mode; + Word16 idxGain; + Word16 i, j, l_subfr; + Word16 fb_band_begin; + Word16 frica_flag = 0; + move16(); + Word16 ener_adjust_quan_fx; + Word16 fb_ener_adjust_fx = 0; + move16(); + Word16 scl, new_input_fx_exp, ysynth_frame_size; + Word16 Q_syn, Q_syn_hb, tmp, tmp2, q_tmp, Qsynth_fx16; + + Word16 ysynth_fx[L_FRAME48k]; + Word16 SWB_fenv_fx[SWB_FENV]; + Word16 SWB_tenv_fx[SWB_TENV]; + Word16 synth_fx16[L_FRAME48k]; + Word16 hb_synth_fx16[L_FRAME48k]; + + Word32 L_tmp; + Word32 yerror_fx[L_FRAME48k]; + Word32 ysynth_fx32[L_FRAME48k]; + Word32 SWB_tenv_tmp_fx[SWB_TENV]; + Word32 wtda_synth_fx[2 * L_FRAME48k]; + + FD_BWE_DEC_HANDLE hBWE_FD; + hBWE_FD = st_fx->hBWE_FD; + + /*---------------------------------------------------------------------* + * SWB BWE decoding + *---------------------------------------------------------------------*/ + test(); + IF( EQ_16( st_fx->element_mode, IVAS_CPE_DFT ) && !use_cldfb_for_dft ) + { + /* todo - wtda() does not support L_FRAME length; thus temporarily resample the signal */ + /* todo - delay output[] by 1.25ms ? */ + L_lerp_fx_q11( output_fx, ysynth_fx32, L_FRAME16k, st_fx->L_frame ); + + /* windowing of the ACELP core synthesis */ + wtda_fx32( ysynth_fx32, wtda_synth_fx, hBWE_FD->L_old_wtda_swb_fx32, ALDO_WINDOW, ALDO_WINDOW, /*st_fx->L_frame*/ L_FRAME16k ); + + /* DCT of the ACELP core synthesis */ + new_input_fx_exp = 11; + move16(); + direct_transform_fx( wtda_synth_fx, ysynth_fx32, 0, /*st_fx->L_frame*/ L_FRAME16k, &new_input_fx_exp, st_fx->element_mode ); + ysynth_frame_size = L_FRAME16k; + move16(); + } + ELSE + { + /* windowing of the ACELP core synthesis */ + wtda_fx32( synth_fx, wtda_synth_fx, hBWE_FD->L_old_wtda_swb_fx32, ALDO_WINDOW, ALDO_WINDOW, output_frame ); + + /* DCT of the ACELP core synthesis */ + new_input_fx_exp = 11; + move16(); + direct_transform_fx( wtda_synth_fx, ysynth_fx32, 0, output_frame, &new_input_fx_exp, st_fx->element_mode ); + ysynth_frame_size = output_frame; + move16(); + } + + /* Convert to 16 Bits (Calc Shift Required to Stay within MAX_Q_NEW_INPUT) */ + scl = sub( 16 + 11, new_input_fx_exp ); + /* Possible to Upscale? */ + IF( scl > 0 ) + { + /* Yes */ + /* Calc Room to Upscale */ + Q_syn = sub( Find_Max_Norm32( ysynth_fx32, ysynth_frame_size ), 3 ); + /* Stay within MAX_Q_NEW_INPUT */ + scl = s_min( Q_syn, scl ); + } + /*Don't upscale if already in 15 bits*/ + IF( GT_16( scl, 15 ) ) + { + FOR( i = 0; i < ysynth_frame_size; i++ ) + { + ysynth_fx[i] = extract_l( ysynth_fx32[i] ); + move16(); + } + Q_syn = new_input_fx_exp; + move16(); + } + ELSE + { + Copy_Scale_sig32_16( ysynth_fx32, ysynth_fx, ysynth_frame_size, scl ); + Q_syn = add( sub( new_input_fx_exp, 16 ), scl ); + } + + IF( !st_fx->bfi ) + { + IF( st_fx->bws_cnt > 0 ) + { + /* estimate parameters */ + mode = para_pred_bws_fx( st_fx, ysynth_fx, SWB_fenv_fx, Q_syn ); + } + ELSE + { + /* de-quantization */ + mode = swb_bwe_gain_deq_fx( st_fx, ACELP_CORE, SWB_tenv_fx, SWB_fenv_fx, 0, -1 ); + } + + L = SWB_FENV; + move16(); + if ( EQ_16( mode, TRANSIENT ) ) + { + L = SWB_FENV_TRANS; + move16(); + } + + L_tmp = 0; + move32(); + FOR( i = 0; i < L; i++ ) + { + L_tmp = L_add( L_tmp, L_deposit_l( SWB_fenv_fx[i] ) ); + } + q_tmp = norm_s( L ); + tmp = div_s( shl( 1, sub( 14, q_tmp ) ), L ); /*Q(29-q_tmp) */ + L_tmp = Mpy_32_16_1( L_tmp, tmp ); /*Q(1+29-q_tmp+1-16)->Q(15-q_tmp) */ + st_fx->prev_ener_shb_fx = round_fx( L_shl( L_tmp, add( q_tmp, 2 ) ) ); /*Q1 */ + move16(); + } + ELSE + { + /* SHB FEC */ + + IF( NE_16( hBWE_FD->prev_mode, TRANSIENT ) ) + { + mode = hBWE_FD->prev_mode; + move16(); + } + ELSE + { + mode = NORMAL; + move16(); + } + + Copy( st_fx->prev_SWB_fenv_fx, SWB_fenv_fx, SWB_FENV ); + } + + /* reconstruction of MDCT spectrum of the error signal */ + set32_fx( yerror_fx, 0, output_frame ); + + IF( EQ_16( st_fx->L_frame, L_FRAME16k ) ) + { + SWB_BWE_decoding_fx( ysynth_fx, SWB_fenv_fx, yerror_fx, L_FRAME32k - 80, mode, &frica_flag, &hBWE_FD->prev_Energy_fx, st_fx->prev_SWB_fenv_fx, &hBWE_FD->prev_L_swb_norm, st_fx->tilt_wb_fx, &hBWE_FD->Seed, 80, &hBWE_FD->prev_weight_fx, st_fx->extl, Q_syn, st_fx->last_extl ); + } + ELSE + { + SWB_BWE_decoding_fx( ysynth_fx, SWB_fenv_fx, yerror_fx, L_FRAME32k - 80, mode, &frica_flag, &hBWE_FD->prev_Energy_fx, st_fx->prev_SWB_fenv_fx, &hBWE_FD->prev_L_swb_norm, st_fx->tilt_wb_fx, &hBWE_FD->Seed, 6, &hBWE_FD->prev_weight_fx, st_fx->extl, Q_syn, st_fx->last_extl ); + } + + test(); + IF( EQ_16( hBWE_FD->prev_frica_flag, 1 ) && frica_flag == 0 ) + { + FOR( i = 0; i < L_SUBFR; i++ ) + { + tmp = sub( 32767, extract_l( L_mult0( i, 512 ) ) ); /*Q15 */ + hBWE_FD->mem_imdct_fx[i] = mult_r( hBWE_FD->mem_imdct_fx[i], tmp ); + move16(); + } + + FOR( ; i < output_frame; i++ ) + { + hBWE_FD->mem_imdct_fx[i] = 0; + move16(); + } + } + + /* decode information */ + IF( EQ_16( st_fx->extl, FB_BWE ) ) + { + IF( !st_fx->bfi ) + { + idxGain = (Word16) get_next_indice_fx( st_fx, NUM_BITS_FB_FRAMEGAIN ); + fb_ener_adjust_fx = usdequant_fx( idxGain, FB_GAIN_QLOW_FX, FB_GAIN_QDELTA_FX ); /*Q15 */ + } + ELSE IF( st_fx->bfi ) + { + fb_ener_adjust_fx = st_fx->prev_fb_ener_adjust_fx; + move16(); + } + + st_fx->prev_fb_ener_adjust_fx = fb_ener_adjust_fx; + move16(); + IF( EQ_16( mode, TRANSIENT ) ) + { + ener_adjust_quan_fx = shr( fb_ener_adjust_fx, 2 ); + } + ELSE + { + IF( SWB_fenv_fx[7] != 0 ) + { + tmp = div_s( 1, SWB_fenv_fx[7] ); + ener_adjust_quan_fx = s_min( shr( i_mult_sat( SWB_fenv_fx[13], tmp ), 2 ), 32767 ); + } + ELSE + { + ener_adjust_quan_fx = 0; + move16(); + } + } + + fb_band_begin = FB_BAND_BEGIN; + move16(); + if ( EQ_16( st_fx->L_frame, L_FRAME ) ) + { + fb_band_begin = FB_BAND_BEGIN_12k8; + move16(); + } + + j = 0; + move16(); + FOR( i = fb_band_begin; i < add( fb_band_begin, DE_OFFSET1 ); i++ ) + { + tmp = sub( 32767, i_mult( j, 1024 ) ); + tmp = mult_r( tmp, ener_adjust_quan_fx ); /*Q13*/ + + tmp2 = i_mult( j, 256 ); /*Q13*/ + tmp2 = mult_r( tmp2, fb_ener_adjust_fx ); /*Q13*/ + + tmp = add( tmp, tmp2 ); /*Q13*/ + yerror_fx[i] = L_shl( Mpy_32_16_1( yerror_fx[i - FB_BAND_WIDTH], tmp ), 2 ); /*15+Q_syn */ + move32(); + j = add( j, 1 ); + } + FOR( ; i < FB_BAND_END; i++ ) + { + yerror_fx[i] = Mpy_32_16_1( yerror_fx[i - FB_BAND_WIDTH], fb_ener_adjust_fx ); /*15+Q_syn */ + move32(); + } + } + + /* iDCT of the error signal */ + Q_syn_hb = add( Q_syn, 15 ); + Inverse_Transform( yerror_fx, &Q_syn_hb, wtda_synth_fx, 0, output_frame, -1, st_fx->element_mode ); + + /* inverse windowing of the error signal */ + window_ola_fx( wtda_synth_fx, hb_synth_fx16, &Q_syn_hb, hBWE_FD->mem_imdct_fx, &hBWE_FD->mem_imdct_exp_fx, output_frame, ALDO_WINDOW, ALDO_WINDOW, 0, 0, 0 ); + l_subfr = mult( output_frame, 8192 ); + + test(); + IF( EQ_16( mode, TRANSIENT ) ) + { + FOR( i = 0; i < SWB_TENV; i++ ) + { + SWB_tenv_tmp_fx[i] = L_mult0( SWB_tenv_fx[i] /*Q0*/, 26214 /*0.8f Q15*/ ); // Q15 + move32(); + } + + /* time envelope shaping when the current frame is TRANSIENT frame */ + time_envelop_shaping_ivas_fx( hb_synth_fx16, SWB_tenv_tmp_fx, output_frame, &Q_syn_hb ); + + Q_syn_hb = sub( Q_syn_hb, 3 ); + + hBWE_FD->prev_td_energy_fx = SWB_tenv_fx[3]; + move16(); + } + ELSE IF( EQ_16( frica_flag, 1 ) && hBWE_FD->prev_frica_flag == 0 ) + { + Qsynth_fx16 = Find_Max_Norm32( synth_fx, output_frame ); + Qsynth_fx16 = sub( Qsynth_fx16, shr( add( sub( 15, norm_s( l_subfr ) ), 1 ), 1 ) ); + Copy_Scale_sig32_16( synth_fx, synth_fx16, output_frame, Qsynth_fx16 ); + Qsynth_fx16 = add( 11 - 16, Qsynth_fx16 ); + + /* IVAS_fmToDo: synth[] is @internal_Fs!!! */ + time_reduce_pre_echo_fx( synth_fx16, hb_synth_fx16, hBWE_FD->prev_td_energy_fx, l_subfr, Qsynth_fx16, Q_syn_hb ); + } + ELSE + { + tmp = i_mult2( 3, l_subfr ); + L_tmp = L_deposit_l( 0 ); + + FOR( i = 0; i < l_subfr; i++ ) + { + L_tmp = L_mac0_sat( L_tmp, hb_synth_fx16[add( tmp, i )], hb_synth_fx16[add( tmp, i )] ); /*(2*Q_syn_hb) */ + } + + L_tmp = Mult_32_16( L_tmp, div_s( 1, l_subfr ) ); /*(2*Q_syn_hb) */ + hBWE_FD->prev_td_energy_fx = 0; + move16(); + + IF( L_tmp != 0 ) + { + q_tmp = norm_l( L_tmp ); + tmp = extract_h( L_shl( L_tmp, q_tmp ) ); + q_tmp = sub( q_tmp, sub( 30, shl( Q_syn_hb, 1 ) ) ); + + tmp = div_s( 16384, tmp ); + L_tmp = L_deposit_h( tmp ); + L_tmp = Isqrt_lc( L_tmp, &q_tmp ); /*Q(31-exp) */ + hBWE_FD->prev_td_energy_fx = round_fx( L_shl( L_tmp, sub( q_tmp, 15 ) ) ); /*Q0 */ + move16(); + } + } + + test(); + IF( EQ_16( st_fx->element_mode, IVAS_CPE_DFT ) && !use_cldfb_for_dft ) + { + Qsynth_fx16 = add( 16 - 11, Q_syn_hb ); + Copy_Scale_sig32_16( synth_fx, synth_fx16, output_frame, Qsynth_fx16 ); + + /* add HB synth from hf_synth() */ + v_add_16( hb_synth_fx16, synth_fx16, hb_synth_fx16, output_frame ); + } + + hBWE_FD->prev_mode = mode; + move16(); + hBWE_FD->prev_frica_flag = frica_flag; + move16(); + + FOR( i = 0; i < output_frame; i++ ) + { + hb_synth_fx[i] = L_deposit_l( hb_synth_fx16[i] ); // Q_syn_hb + move32(); + } + + return Q_syn_hb; +} + + +void fd_bwe_dec_init_fx( + FD_BWE_DEC_HANDLE hBWE_FD /* i/o: FD BWE data handle */ +) +{ + set16_fx( hBWE_FD->L_old_wtda_swb_fx, 0, L_FRAME48k ); + set16_fx( hBWE_FD->old_syn_12k8_16k_fx, 0, NS2SA_FX2( 16000, DELAY_FD_BWE_ENC_NS ) ); + hBWE_FD->prev_mode = NORMAL; + move16(); + hBWE_FD->prev_Energy_fx = 0; + move16(); + hBWE_FD->prev_L_swb_norm = 8; + move16(); + hBWE_FD->Seed = 21211; + move16(); + hBWE_FD->prev_frica_flag = 0; + move16(); + set16_fx( hBWE_FD->mem_imdct_fx, 0, L_FRAME48k ); + hBWE_FD->prev_td_energy_fx = 0; + move16(); + hBWE_FD->prev_weight_fx = 0; + move16(); + hBWE_FD->prev_flag = 0; + move16(); + hBWE_FD->prev_Energy_wb_fx = 0; + move32(); + hBWE_FD->mem_deemph_old_syn_fx = 0; + move16(); + + return; +} diff --git a/lib_dec/swb_bwe_dec_hr.c b/lib_dec/swb_bwe_dec_hr.c deleted file mode 100644 index e2be97ae4b8288ea63cc27a6bd828a9518e7aa43..0000000000000000000000000000000000000000 --- a/lib_dec/swb_bwe_dec_hr.c +++ /dev/null @@ -1,49 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include -#include "prot.h" -#include "rom_com.h" -#include "wmc_auto.h" -#include "prot_fx.h" - -/*-------------------------------------------------------------------* - * swb_bwe_dec_hr() - * - * HR SWB BWE decoder - *-------------------------------------------------------------------*/ diff --git a/lib_dec/swb_bwe_dec_hr_fx.c b/lib_dec/swb_bwe_dec_hr_fx.c index b5f8641dc0525f609a90b9f37735f19c16e5d82e..18867ce40bcd5d9ad0bb09e12c67b1212a9b31d0 100644 --- a/lib_dec/swb_bwe_dec_hr_fx.c +++ b/lib_dec/swb_bwe_dec_hr_fx.c @@ -185,13 +185,8 @@ static Word16 TD_Postprocess( /* o : gain in Q15 L_Energy = Sqrt_Ratio32( L_Energy, temp1, L_Energy2, temp2, &temp ); /* Put Back to Q31 (Let it saturate to 0.99999 in fx because we wanted to limit the gain to 1.0 anyways) */ -#ifdef BASOP_NOGLOB L_Energy = L_shl_sat( L_Energy, temp ); temp = round_fx_sat( L_Energy ); -#else - L_Energy = L_shl( L_Energy, temp ); - temp = round_fx( L_Energy ); -#endif test(); IF( EQ_16( last_extl, SWB_BWE ) || EQ_16( last_extl, FB_BWE ) ) @@ -229,15 +224,9 @@ static Word16 TD_Postprocess( /* o : gain in Q15 FOR( i = ind2; i < input_frame; i++ ) { -#ifdef BASOP_NOGLOB hb_synth_fx[i] = mult_r_sat( round_fx_sat( L_Energy ), hb_synth_fx[i] ); move16(); L_Energy = L_add_sat( L_Energy, L_Energy2 ); -#else - hb_synth_fx[i] = mult_r( round_fx( L_Energy ), hb_synth_fx[i] ); - move16(); - L_Energy = L_add( L_Energy, L_Energy2 ); -#endif } } } @@ -489,11 +478,7 @@ Word16 swb_bwe_dec_hr_fx( /* o : Exponent of SHB temp = div_s( 16384, frac ); L_temp = L_deposit_h( temp ); L_temp = Isqrt_lc( L_temp, &exp1 ); -#ifdef BASOP_NOGLOB gain_fx = extract_l( L_shl_sat( L_temp, sub( exp1, 2 ) ) ); /*Q(31-exp + (exp-3)) -> Q13*/ -#else - gain_fx = extract_l( L_shl( L_temp, sub( exp1, 2 ) ) ); /*Q(31-exp + (exp-3)) -> Q13*/ -#endif } env = 512; @@ -626,13 +611,8 @@ Word16 swb_bwe_dec_hr_fx( /* o : Exponent of SHB } /* apply noise-fill */ -#ifdef BASOP_NOGLOB swb_hr_noise_fill_fx( is_transient, NUM_TRANS_START_FREQ_COEF, NUM_TRANS_END_FREQ_COEF, round_fx_sat( L_shl_sat( L_tilt_wb, 3 ) ), /* Q(24+3-16) -> Q11 */ pitch, nq, Nsv, &hBWE_FD_HR->bwe_highrate_seed_fx, t_audio + temp, t_audio_exp ); -#else - swb_hr_noise_fill_fx( is_transient, NUM_TRANS_START_FREQ_COEF, NUM_TRANS_END_FREQ_COEF, round_fx( L_shl( L_tilt_wb, 3 ) ), /* Q(24+3-16) -> Q11 */ - pitch, nq, Nsv, &hBWE_FD_HR->bwe_highrate_seed_fx, t_audio + temp, t_audio_exp ); -#endif /* Go from Q't_audio_exp' on 16 Bits to 'Q_32_BITS' on 32 bits */ temp2 = i_mult2( WIDTH_BAND, Nsv ); ptr16 = &t_audio[temp]; @@ -925,11 +905,7 @@ Word16 swb_bwe_dec_hr_fx( /* o : Exponent of SHB move16(); FOR( i = 0; i < i_mult( Nsv, WIDTH_BAND ); i++ ) { -#ifdef BASOP_NOGLOB t_audio_tmp[i] = shl_sat( x_norm[i], t_audio_exp ); -#else - t_audio_tmp[i] = shl( x_norm[i], t_audio_exp ); -#endif move16(); } @@ -1054,11 +1030,7 @@ Word16 swb_bwe_dec_hr_fx( /* o : Exponent of SHB IF( LT_16( nBits, 200 ) ) { swb_hr_noise_fill_fx( is_transient, NUM_NONTRANS_START_FREQ_COEF, NUM_NONTRANS_END_FREQ_COEF, -#ifdef BASOP_NOGLOB round_fx_sat( L_shl_sat( L_tilt_wb, 3 ) ), /* Q(24+3-16) -> Q11 */ -#else - round_fx( L_shl( L_tilt_wb, 3 ) ), /* Q(24+3-16) -> Q11 */ -#endif pitch, nq, Nsv, &hBWE_FD_HR->bwe_highrate_seed_fx, t_audio + NUM_NONTRANS_START_FREQ_COEF, t_audio_exp ); } @@ -1185,11 +1157,7 @@ Word16 swb_bwe_dec_hr_fx( /* o : Exponent of SHB /* tmpF = max_env / min_env; */ temp = BASOP_Util_Divide1616_Scale( max_env, min_env, &temp2 ); test(); -#ifdef BASOP_NOGLOB IF( EQ_16( st_fx->extl, SWB_BWE_HIGHRATE ) || LT_16( temp, shl_sat( 18022, sub( 15 - 13, temp2 ) ) ) ) /* 2.2 in Q13 == 18022 */ -#else - IF( EQ_16( st_fx->extl, SWB_BWE_HIGHRATE ) || LT_16( temp, shl( 18022, sub( 15 - 13, temp2 ) ) ) ) /* 2.2 in Q13 == 18022 */ -#endif { /* (en_band_flt[3] - j*(en_band_flt[3]/WIDTH_BAND - en_noncoded_flt/WIDTH_BAND)) */ @@ -1281,11 +1249,7 @@ Word16 swb_bwe_dec_hr_fx( /* o : Exponent of SHB FOR( i = 0; i < temp2; i++ ) { L_temp = Mult_32_16( *ptr32, gain_fx ); -#ifdef BASOP_NOGLOB L_temp = L_shl_sat( L_temp, temp ); -#else - L_temp = L_shl( L_temp, temp ); -#endif *ptr32++ = L_temp; move32(); } diff --git a/lib_dec/swb_bwe_dec_lr.c b/lib_dec/swb_bwe_dec_lr.c deleted file mode 100644 index ff2af374eb0aeca1689c4e78b0fc985f8e8a0785..0000000000000000000000000000000000000000 --- a/lib_dec/swb_bwe_dec_lr.c +++ /dev/null @@ -1,51 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include -#include "cnst.h" -#include "prot.h" -#include "rom_com.h" -#include "stat_com.h" -#include "wmc_auto.h" - - -/*-------------------------------------------------------------------* - * DecodeSWBGenericParameters() - * - * Decoding of generic subband coding parameters - *-------------------------------------------------------------------*/ diff --git a/lib_dec/swb_tbe_dec.c b/lib_dec/swb_tbe_dec.c deleted file mode 100644 index 8c2387e53497fe35ad9061d5a68c03210e98c75d..0000000000000000000000000000000000000000 --- a/lib_dec/swb_tbe_dec.c +++ /dev/null @@ -1,2560 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include -#include "cnst.h" -#include "prot.h" -#include "prot_fx.h" -#include "rom_com.h" -#include "rom_dec.h" -#include "wmc_auto.h" -#include "ivas_prot.h" -#include "ivas_prot_fx.h" - -/*-----------------------------------------------------------------* - * Local function prototypes - *-----------------------------------------------------------------*/ - - -void find_max_mem_dec_m3( - Decoder_State *st, - Word16 *n_mem3 ); - -/*-------------------------------------------------------------------* - * ResetSHBbuffer_Dec() - * - * - *-------------------------------------------------------------------*/ - -static void calc_tilt_bwe_fx_loc( - const Word32 *sp_fx, /* i : input signal : Q11 */ - Word32 *tilt_fx, /* o : signal tilt : tilt_fx_q */ - Word16 *tilt_fx_q, /* o : signal tilt */ - const Word16 N /* i : signal length : Q0 */ -) -{ - Word16 i; - Word64 r0_fx, r1_fx; - - r0_fx = EPSILON_FX_SMALL; - move64(); - FOR( i = 0; i < N; i++ ) - { - r0_fx = W_add( r0_fx, W_shr( W_mult_32_32( sp_fx[i], sp_fx[i] ), 1 ) ); /*Q11*2 - 1*/ - } - r1_fx = W_deposit32_l( abs( L_sub( sp_fx[1], sp_fx[0] ) ) ); /*Q11*/ - FOR( i = 2; i < N; i++ ) - { - IF( W_mult_32_32( L_sub( sp_fx[i], sp_fx[i - 1] ) /*Q11*/, L_sub( sp_fx[i - 1], sp_fx[i - 2] ) /*Q11*/ ) /*Q11 * 2 - 1*/ < 0 ) - { - r1_fx = W_add( r1_fx, W_deposit32_l( abs( L_sub( sp_fx[i], sp_fx[i - 1] ) ) ) ); /*Q11*/ - } - } - Word16 headroom_left_r0 = W_norm( r0_fx ); - Word16 headroom_left_r1 = W_norm( r1_fx ); - Word16 r0_q = 0, r1_q = 0; - move16(); - move16(); - IF( LT_16( headroom_left_r0, 32 ) ) - { - r0_fx = W_shr( r0_fx, sub( 32, headroom_left_r0 ) ); - r0_q = sub( 31, sub( ( 2 * OUTPUT_Q ), sub( 32, headroom_left_r0 ) ) ); - } - ELSE - { - r0_q = 31 - ( 2 * OUTPUT_Q ); - move16(); - } - - IF( LT_16( headroom_left_r1, 32 ) ) - { - r1_fx = W_shr( r1_fx, sub( 32, headroom_left_r1 ) ); - r1_q = sub( OUTPUT_Q, sub( 32, headroom_left_r1 ) ); - } - ELSE - { - r1_q = OUTPUT_Q; - move16(); - } - Word32 temp_r0_inv = ISqrt32( W_extract_l( r0_fx ), &r0_q ); - Word32 res = Mpy_32_32( W_extract_l( r1_fx ), temp_r0_inv ); - // Word16 res_q = r1_q + ( r0_q < 0 ? ( 31 + ( -1 * r0_q ) ) : r0_q ) - 31; - Word16 res_q; - IF( r0_q < 0 ) - { - res_q = add( r1_q, sub( add( 31, -r0_q ), 31 ) ); - } - ELSE - { - res_q = add( r1_q, sub( r0_q, 31 ) ); - } - Word16 norm_res = norm_l( res ); - IF( norm_res > 0 ) - { - *tilt_fx = L_shl_sat( res, norm_res ); - move32(); - *tilt_fx_q = add( res_q, norm_res ); - move16(); - } - ELSE - { - *tilt_fx = res; - move32(); - *tilt_fx_q = res_q; - move16(); - } - return; -} - -/*-------------------------------------------------------------------* - * swb_tbe_dec() - * - * SWB TBE decoder, 6 - 14 kHz (or 7.5 - 15.5 kHz) band decoding module - *-------------------------------------------------------------------*/ -static void rescale_genSHB_mem_dec( - Decoder_State *st_fx, - Word16 sf /*Q0*/ -) -{ - Word16 i; - TD_BWE_DEC_HANDLE hBWE_TD; - hBWE_TD = st_fx->hBWE_TD; - - FOR( i = 0; i < NL_BUFF_OFFSET; i++ ) - { - hBWE_TD->old_bwe_exc_extended_fx[i] = shl( hBWE_TD->old_bwe_exc_extended_fx[i], sf ); - move16(); - } - - FOR( i = 0; i < 7; i++ ) - { - hBWE_TD->mem_genSHBexc_filt_down_shb_fx[i] = shl( hBWE_TD->mem_genSHBexc_filt_down_shb_fx[i], sf ); - move16(); - } - - /* -- Apply memory scaling for 13.2 and 16.4k bps using sf ----*/ - IF( LT_32( st_fx->total_brate, ACELP_24k40 ) ) - { - FOR( i = 0; i < LPC_SHB_ORDER; i++ ) - { - hBWE_TD->state_lpc_syn_fx[i] = shl_sat( hBWE_TD->state_lpc_syn_fx[i], sf ); - move16(); - } - - FOR( i = 0; i < L_SHB_LAHEAD; i++ ) - { - hBWE_TD->state_syn_shbexc_fx[i] = shl_sat( hBWE_TD->state_syn_shbexc_fx[i], sf ); - move16(); - } - } - - hBWE_TD->mem_csfilt_fx[0] = L_shl( hBWE_TD->mem_csfilt_fx[0], sf ); - move32(); - - hBWE_TD->tbe_demph_fx = shl_r( hBWE_TD->tbe_demph_fx, sf ); - move16(); - hBWE_TD->tbe_premph_fx = shl_r( hBWE_TD->tbe_premph_fx, sf ); - move16(); -} - -static void gradientGainShape( - Decoder_State *st_fx, - Word16 *GainShape_fx, /*Q15*/ - Word32 *GainFrame_fx /* Q18 */ ) -{ - Word16 i, j, tmp; - Word16 GainShapeTemp[NUM_SHB_SUBFR / 4]; - Word16 GainGrad0[3]; - Word16 GainGrad1[3]; - Word16 GainGradFEC[4]; - TD_BWE_DEC_HANDLE hBWE_TD; - hBWE_TD = st_fx->hBWE_TD; - - - /* the previous frame gainshape gradient and the gainshape gradient pattern for the current frame */ - FOR( j = 0; j < 3; j++ ) - { - GainGrad0[j] = sub( shr( st_fx->GainShape_Delay[j + 1], 1 ), shr( st_fx->GainShape_Delay[j], 1 ) ); - move16(); /* Q14 */ - GainGrad1[j] = sub( shr( st_fx->GainShape_Delay[j + 5], 1 ), shr( st_fx->GainShape_Delay[j + 4], 1 ) ); - move16(); /* Q14 */ - GainGradFEC[j + 1] = add( mult_r( GainGrad0[j], 13107 /*0.4f in Q15*/ ), mult_r( GainGrad1[j], 19660 /*0.6f in Q15*/ ) ); - move16(); /* Q14 */ - } - - /* gradient for the first gainshape */ - test(); - test(); - test(); - IF( ( ( GT_16( shr( GainGrad1[2], 1 ), GainGrad1[1] ) ) && ( GT_16( shr( GainGrad1[1], 1 ), GainGrad1[0] ) ) ) || - ( ( LT_16( shr( GainGrad1[2], 1 ), GainGrad1[1] ) ) && ( LT_16( shr( GainGrad1[1], 1 ), GainGrad1[0] ) ) ) ) - { - GainGradFEC[0] = add( mult_r( GainGrad1[1], 3277 /*0.1f in Q15*/ ), mult_r( GainGrad1[2], 29490 /*0.9f in Q15*/ ) ); - move16(); /* Q14 */ - } - ELSE - { - GainGradFEC[0] = add( mult_r( GainGrad1[0], 6553 /*0.2f in Q15*/ ), mult_r( GainGrad1[1], 9830 /*0.3f in Q15*/ ) ); - move16(); - GainGradFEC[0] = add( GainGradFEC[0], mult_r( GainGrad1[2], 16384 /*0.5f in Q15*/ ) ); - move16(); /* Q14 */ - } - - /* get the first gainshape template */ - test(); - test(); - IF( ( EQ_16( st_fx->prev_coder_type, UNVOICED ) || ( st_fx->last_good == UNVOICED_CLAS ) ) && ( GainGradFEC[0] > 0 ) ) - { - GainShapeTemp[0] = add( shr( st_fx->GainShape_Delay[7], 1 ), GainGradFEC[0] ); - move16(); - } - ELSE IF( GainGradFEC[0] > 0 ) - { - GainShapeTemp[0] = add( shr( st_fx->GainShape_Delay[7], 1 ), mult_r( GainGradFEC[0], 16384 /*0.5f in Q15*/ ) ); - move16(); /* Q14 */ - } - ELSE - { - GainShapeTemp[0] = shr( st_fx->GainShape_Delay[7], 1 ); - move16(); /* Q14 */ - } - - /*Get the second the third and the fourth gainshape template*/ - - tmp = shr( GainGrad1[2], 3 ); /* GainGrad1[2]/8 */ - tmp = mult_r( tmp, 26214 ); /* 0.8 in Q15 tmp*(8/10) */ - - test(); - IF( ( GT_16( tmp, GainGrad1[1] ) ) && ( GainGrad1[1] > 0 ) ) - { - FOR( i = 1; i < NUM_SHB_SUBFR / 4; i++ ) - { - GainShapeTemp[i] = add( GainShapeTemp[i - 1], mult_r( GainGradFEC[i], 26214 /*0.8f in Q15*/ ) ); - move16(); /* GainShapeTemp[i-1] + 0.8* GainShapeTemp[i] */ - GainShapeTemp[i] = s_max( GainShapeTemp[i], 328 /*0.01f Q15*/ ); - move16(); - } - } - ELSE - { - test(); - IF( ( GT_16( tmp, GainGrad1[1] ) ) && ( GainGrad1[1] < 0 ) ) - { - FOR( i = 1; i < NUM_SHB_SUBFR / 4; i++ ) - { - GainShapeTemp[i] = add( GainShapeTemp[i - 1], mult_r( GainGradFEC[i], 6553 /*0.2f in Q15*/ ) ); - move16(); /* GainShapeTemp[i-1] + 0.8* GainShapeTemp[i] */ - GainShapeTemp[i] = s_max( GainShapeTemp[i], 328 /*0.01f Q15*/ ); - move16(); /* Q14 */ - } - } - ELSE - { - FOR( i = 1; i < NUM_SHB_SUBFR / 4; i++ ) - { - GainShapeTemp[i] = add( GainShapeTemp[i - 1], GainGradFEC[i] ); - move16(); - GainShapeTemp[i] = s_max( GainShapeTemp[i], 328 /*0.01f Q15*/ ); - move16(); - } - } - } - - /* Get the gainshape and gain frame for the current frame*/ - test(); - test(); - test(); - IF( ( EQ_16( st_fx->prev_coder_type, UNVOICED ) || ( st_fx->last_good == UNVOICED_CLAS ) ) && EQ_16( st_fx->nbLostCmpt, 1 ) ) - { - FOR( i = 0; i < NUM_SHB_SUBFR / 4; i++ ) - { - FOR( j = 0; j < 4; j++ ) - { - tmp = mult_r( GainShapeTemp[i], 19660 /*0.6f Q15*/ ); /* GainShapeTemp[i]*0.6 */ - - IF( GT_16( 8192, tmp ) ) - { - GainShape_fx[i * 4 + j] = shl( tmp, 2 ); /*Q15*/ - move16(); /* (GainShapeTemp[i]*0.6)>>1 */ - } - ELSE - { - GainShape_fx[i * 4 + j] = 32767; /*Q15*/ - move16(); /* Clipping here to avoid the a huge change of the code due to gain shape change */ - } - } - } - hBWE_TD->GainAttn_fx = mult_r( hBWE_TD->GainAttn_fx, 31129 ); - move16(); - } - ELSE IF( EQ_16( st_fx->prev_coder_type, UNVOICED ) || ( st_fx->last_good == UNVOICED_CLAS ) ) - { - FOR( i = 0; i < NUM_SHB_SUBFR / 4; i++ ) - { - FOR( j = 0; j < 4; j++ ) - { - IF( LT_16( GainShapeTemp[i], 16384 ) ) - { - GainShape_fx[i * 4 + j] = shl( GainShapeTemp[i], 1 ); /*Q15*/ - move16(); - } - ELSE - { - GainShape_fx[i * 4 + j] = 32767; // 1.0f in Q15 - move16(); - } - } - } - hBWE_TD->GainAttn_fx = mult_r( hBWE_TD->GainAttn_fx, 31129 /*0.95f in Q15*/ ); /*Q15*/ - move16(); - } - ELSE IF( GT_16( st_fx->nbLostCmpt, 1 ) ) - { - FOR( i = 0; i < NUM_SHB_SUBFR / 4; i++ ) - { - FOR( j = 0; j < 4; j++ ) - { - GainShape_fx[i * 4 + j] = GainShapeTemp[i]; /*Q15*/ - move16(); - } - } - hBWE_TD->GainAttn_fx = mult_r( hBWE_TD->GainAttn_fx, 16384 /*0.5f in Q15*/ ); /*Q15*/ - move16(); - } - ELSE - { - FOR( i = 0; i < NUM_SHB_SUBFR / 4; i++ ) - { - FOR( j = 0; j < 4; j++ ) - { - IF( LT_16( GainShapeTemp[i], 16384 ) ) - { - GainShape_fx[i * 4 + j] = shl( GainShapeTemp[i], 1 ); /*Q15*/ - move16(); - } - ELSE - { - GainShape_fx[i * 4 + j] = 32767; /*Q15*/ - move16(); - } - } - } - hBWE_TD->GainAttn_fx = mult_r( hBWE_TD->GainAttn_fx, 27852 /*0.85f in Q15*/ ); /*Q15*/ - move16(); - } - - *GainFrame_fx = Mult_32_16( hBWE_TD->GainFrame_prevfrm_fx, hBWE_TD->GainAttn_fx ); /* Q18 */ - move32(); -} - -static void find_max_mem_dec( - Decoder_State *st_fx, - Word16 *n_mem, - Word16 *n_mem2, - Word16 *n_mem3 ) -{ - Word16 i; - Word16 n_mem_32; - Word16 max = 0; - move16(); - Word32 Lmax = 0; - move32(); - Word16 tempQ15, max2 = 0; - move16(); - Word16 max3; - Word32 tempQ32, Lmax3; - TD_BWE_DEC_HANDLE hBWE_TD; - hBWE_TD = st_fx->hBWE_TD; - - /* old BWE exc max */ - FOR( i = 0; i < NL_BUFF_OFFSET; i++ ) - { - tempQ15 = abs_s( hBWE_TD->old_bwe_exc_extended_fx[i] ); - max = s_max( max, tempQ15 ); - } - - /* decimate all-pass steep memory */ - FOR( i = 0; i < 7; i++ ) - { - tempQ15 = abs_s( hBWE_TD->mem_genSHBexc_filt_down_shb_fx[i] ); - max = s_max( max, tempQ15 ); - } - - /* -- keep norm of state_lpc_syn_fx, state_syn_shbexc_fx, - and mem_stp_swb_fx separately for 24.4 and 32kbps ----*/ - /* findMaxMem2() inside tbe com */ - FOR( i = 0; i < LPC_SHB_ORDER; i++ ) - { - tempQ15 = abs_s( hBWE_TD->state_lpc_syn_fx[i] ); - max2 = s_max( max2, tempQ15 ); - } - - /* findMaxMem2() inside tbe com */ - FOR( i = 0; i < L_SHB_LAHEAD; i++ ) - { - tempQ15 = abs_s( hBWE_TD->state_syn_shbexc_fx[i] ); - max2 = s_max( max2, tempQ15 ); - } - - /* findMaxMem2() inside tbe com */ - FOR( i = 0; i < LPC_SHB_ORDER; i++ ) - { - tempQ15 = abs_s( hBWE_TD->mem_stp_swb_fx[i] ); - max2 = s_max( max2, tempQ15 ); - } - - /* for total_brate > 16.4kbps, use n_mem2; else account for the max2 for n_mem calculation */ - *n_mem2 = norm_s( max2 ); - move16(); - if ( max2 == 0 ) - { - *n_mem2 = 15; - move16(); - } - - if ( LT_32( st_fx->total_brate, ACELP_24k40 ) ) - { - max = s_max( max, max2 ); - } - - /* de-emph and pre-emph memory */ - tempQ15 = abs_s( hBWE_TD->tbe_demph_fx ); - max = s_max( max, tempQ15 ); - - tempQ15 = abs_s( hBWE_TD->tbe_premph_fx ); - max = s_max( max, tempQ15 ); - - IF( EQ_16( st_fx->extl, FB_TBE ) ) - { - FOR( i = 0; i < LPC_SHB_ORDER; i++ ) - { - tempQ15 = abs_s( hBWE_TD->fb_state_lpc_syn_fx[i] ); - max = s_max( max, tempQ15 ); - } - /* FB de-emph memory */ - tempQ15 = abs_s( hBWE_TD->fb_tbe_demph_fx ); - max = s_max( max, tempQ15 ); - } - /* estimate the norm for 16-bit memories */ - *n_mem = norm_s( max ); - move16(); - if ( max == 0 ) - { - *n_mem = 15; - move16(); - } - - /* estimate the norm for 32-bit memories */ - Lmax = L_abs( hBWE_TD->mem_csfilt_fx[0] ); /* only element [0] is used in env. shaping */ - - n_mem_32 = norm_l( Lmax ); - if ( Lmax == 0 ) - { - n_mem_32 = 31; - move16(); - } - - tempQ15 = sub( s_min( *n_mem, n_mem_32 ), 1 ); - *n_mem = s_max( tempQ15, 0 ); - move16(); - - /* --------------------------------------------------------------*/ - /* Find headroom for synthesis stage associated with these memories: - 1. st_fx->syn_overlap_fx - 2. st_fx->genSHBsynth_state_lsyn_filt_shb_local - 3. st_fx->genSHBsynth_Hilbert_Mem_fx (32-bit) */ - max3 = 0; - move16(); - /* find max in prev overlapSyn */ - FOR( i = 0; i < L_SHB_LAHEAD; i++ ) - { - tempQ15 = abs_s( hBWE_TD->syn_overlap_fx[i] ); - max3 = s_max( max3, tempQ15 ); - } - /* find max in prev genSHBsynth_state_lsyn_filt_shb_local_fx */ - FOR( i = 0; i < 2 * ALLPASSSECTIONS_STEEP; i++ ) - { - tempQ15 = abs_s( hBWE_TD->genSHBsynth_state_lsyn_filt_shb_local_fx[i] ); - max3 = s_max( max3, tempQ15 ); - } - /* find max in prev int_3_over_2_tbemem_dec_fx */ - IF( EQ_32( st_fx->output_Fs, 48000 ) ) - { - FOR( i = 0; i < INTERP_3_2_MEM_LEN; i++ ) - { - tempQ15 = abs_s( hBWE_TD->int_3_over_2_tbemem_dec_fx[i] ); - max3 = s_max( max3, tempQ15 ); - } - } - IF( EQ_32( st_fx->output_Fs, 16000 ) ) - { - FOR( i = 0; i < ( 2 * ALLPASSSECTIONS_STEEP + 1 ); i++ ) - { - tempQ15 = abs_s( hBWE_TD->mem_resamp_HB_32k_fx[i] ); - max3 = s_max( max3, tempQ15 ); - } - } - /* estimate the norm for 16-bit memories */ - *n_mem3 = norm_s( max3 ); - move16(); - if ( max3 == 0 ) - { - *n_mem3 = 15; - move16(); - } - - Lmax3 = 0; - move32(); - IF( EQ_16( st_fx->L_frame, L_FRAME ) ) - { - /* find max in prev genSHBsynth_Hilbert_Mem_fx */ - FOR( i = 0; i < HILBERT_MEM_SIZE; i++ ) - { - tempQ32 = L_abs( hBWE_TD->genSHBsynth_Hilbert_Mem_fx[i] ); - Lmax3 = L_max( Lmax3, tempQ32 ); - } - } - - /* estimate the norm for 32-bit memories */ - n_mem_32 = norm_l( Lmax3 ); - if ( Lmax3 == 0 ) - { - n_mem_32 = 31; - move16(); - } - - tempQ15 = sub( s_min( *n_mem3, n_mem_32 ), 2 ); /* very important leave at least 2 bit head room - because of the Hilber transform and Q14 coeffs */ - *n_mem3 = s_max( tempQ15, 0 ); - move16(); - /* --------------------------------------------------------------*/ -} - -void find_max_mem_dec_m3( - Decoder_State *st, - Word16 *n_mem3 ) -{ - Word16 i; - // Word16 n_mem_32; - Word16 tempQ15; - Word16 max3; - // Word32 tempQ32, Lmax3; - TD_BWE_DEC_HANDLE hBWE_TD; - hBWE_TD = st->hBWE_TD; - - /* --------------------------------------------------------------*/ - /* Find headroom for synthesis stage associated with these memories: - 1. st->syn_overlap_fx*/ - max3 = 0; - move16(); - /* find max in prev overlapSyn */ - FOR( i = 0; i < L_SHB_LAHEAD; i++ ) - { - tempQ15 = abs_s( hBWE_TD->syn_overlap_fx[i] ); - max3 = s_max( max3, tempQ15 ); - } - /* find max in prev genSHBsynth_state_lsyn_filt_shb_local_fx */ - - /* estimate the norm for 16-bit memories */ - *n_mem3 = norm_s( max3 ); - move16(); - if ( max3 == 0 ) - { - *n_mem3 = 15; - move16(); - } -} - -/*-------------------------------------------------------------------* - * ivas_swb_tbe_dec_fx() - * - * SWB TBE decoder, 6 - 14 kHz (or 7.5 - 15.5 kHz) band decoding module - *-------------------------------------------------------------------*/ -void ivas_swb_tbe_dec_fx( - Decoder_State *st, /* i/o: decoder state structure */ - STEREO_ICBWE_DEC_HANDLE hStereoICBWE, /* i/o: IC-BWE state structure */ - const Word32 *bwe_exc_extended_fx, /* i : bandwidth extended excitation : Q_exc */ - Word16 Q_exc, - const Word16 voice_factors_fx[], /* i : voicing factors : Q15 */ - const Word32 old_syn_12k8_16k_fx[], /* i : low band synthesis : old_syn_fx */ - Word16 *White_exc16k_fx, /* o : shaped white excitation for the FB TBE : Q_white_exc*/ - Word32 *synth_fx, /* o : SHB synthesis/final synthesis : Qx */ - Word16 *pitch_buf_fx, /* i : Q6 */ - Word16 *Q_white_exc ) -{ - Word16 i, j, cnt, n; - Word16 stemp; - TD_BWE_DEC_HANDLE hBWE_TD; - Word32 shaped_shb_excitation_fx_32[L_FRAME16k + L_SHB_LAHEAD]; - Word16 bwe_exc_extended_16[L_FRAME32k + NL_BUFF_OFFSET]; - Word16 shaped_shb_excitation_fx[L_FRAME16k + L_SHB_LAHEAD]; - Word16 lsf_shb_fx[LPC_SHB_ORDER], lpc_shb_fx[LPC_SHB_ORDER + 1], GainShape_fx[NUM_SHB_SUBFR]; // Q12,Q12,Q15 - Word32 GainFrame_fx; // Q18 - Word32 error_fx[L_FRAME32k]; - Word16 ener_fx; - Word32 L_ener; - Word16 is_fractive; - Word32 prev_pow_fx, curr_pow_fx, Lscale; - Word16 scale_fx; - Word16 max_val, temp_fx, shaped_shb_excitation_frac[L_FRAME16k + L_SHB_LAHEAD]; - Word32 curr_frame_pow_fx; - Word16 curr_frame_pow_exp; - Word32 L_prev_ener_shb; - Word16 vf_modified_fx[NB_SUBFR16k]; - Word16 f_fx, inc_fx; - Word32 GainFrame_prevfrm_fx; - Word32 tilt_swb_fec_32_fx; - Word16 tilt_swb_fec_fx_q; - Word16 tilt_swb_fec_fx; - Word32 prev_ener_ratio_fx = 0; /* initialize just to avoid compiler warning */ - Word16 lsp_shb_1_fx[LPC_SHB_ORDER], lsp_shb_2_fx[LPC_SHB_ORDER], lsp_temp_fx[LPC_SHB_ORDER]; - Word16 lpc_shb_sf_fx[4 * ( LPC_SHB_ORDER + 1 )]; - const Word16 *ptr_lsp_interp_coef_fx; - Word32 shb_ener_sf_32; - Word16 shb_res_gshape_fx[NB_SUBFR16k]; - Word16 mixFactors_fx; - Word16 vind; - Word16 shb_res_dummy_fx[L_FRAME16k]; - Word16 shaped_shb_excitationTemp_fx[L_FRAME16k]; - Word32 ener_tmp_fx[NUM_SHB_SUBGAINS]; - Word16 GainShape_tmp_fx[NUM_SHB_SUBGAINS]; - Word16 pitch_fx; - Word16 l_subframe; - Word16 formant_fac_fx; - Word16 synth_scale_fx; - Word16 lsf_diff_fx[LPC_SHB_ORDER], w_fx[LPC_SHB_ORDER]; - Word16 refl_fx[M]; - Word16 tilt_para_fx; - Word16 *nlExc16k_fx, *mixExc16k_fx; - Word16 MSFlag; - Word16 feedback_fx; - Word16 GainShape_tilt_fx; - - // scaling - Word16 exp, tmp; - Word16 tmp1, tmp2; - Word16 mean_vf; - Word32 Lmax, L_tmp; - Word16 frac; - Word32 L_tmp1, L_tmp2; - Word16 Q_bwe_exc; - Word16 Q_bwe_exc_fb; - Word16 Q_shb; - Word16 n_mem, n_mem2, n_mem3, Qx, sc; - Word16 expa, expb; - Word16 fraca, fracb; - Word16 exp_ener, inv_ener; - - hBWE_TD = st->hBWE_TD; - - /* initializations */ - GainFrame_fx = 0; - move32(); - mixFactors_fx = 0; - move16(); - shb_ener_sf_32 = 0; - move32(); - set16_fx( shaped_shb_excitationTemp_fx, 0, L_FRAME16k ); - if ( st->hTdCngDec != NULL ) - { - st->hTdCngDec->shb_dtx_count = 0; - move16(); - } - is_fractive = 0; - move16(); - - IF( hStereoICBWE != NULL ) - { - nlExc16k_fx = hStereoICBWE->nlExc16k_fx; - mixExc16k_fx = hStereoICBWE->mixExc16k_fx; - MSFlag = hStereoICBWE->MSFlag; - move16(); - } - ELSE - { - nlExc16k_fx = NULL; - mixExc16k_fx = NULL; - MSFlag = 0; - move16(); - } - - /* find tilt */ - calc_tilt_bwe_fx_loc( old_syn_12k8_16k_fx, &tilt_swb_fec_32_fx, &tilt_swb_fec_fx_q, L_FRAME ); - tilt_swb_fec_fx = round_fx_sat( L_shl_sat( tilt_swb_fec_32_fx, sub( 11 + 16, tilt_swb_fec_fx_q ) ) ); - test(); - if ( st->bfi && st->clas_dec != UNVOICED_CLAS ) - { - tilt_swb_fec_fx = hBWE_TD->tilt_swb_fec_fx; - move16(); - } - - /* WB/SWB bandwidth switching */ - test(); - test(); - IF( ( GT_16( st->tilt_wb_fx, 10240 /*5 in Q11*/ ) && ( EQ_16( st->clas_dec, UNVOICED_CLAS ) ) ) || GT_16( st->tilt_wb_fx, 20480 /*10 in Q11*/ ) ) - { - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - IF( ( ( st->prev_fractive == 0 ) && - ( LT_32( st->prev_enerLH_fx, L_shl( st->enerLH_fx, 1 ) ) && GT_32( st->prev_enerLH_fx, L_shr( st->enerLH_fx, 1 ) ) && LT_32( st->prev_enerLL_fx, L_shl( st->enerLL_fx, 1 ) ) && GT_32( st->prev_enerLL_fx, L_shr( st->enerLL_fx, 1 ) ) ) ) || - ( EQ_16( st->prev_fractive, 1 ) && - GT_32( L_shr( st->prev_enerLH_fx, 2 ), Mult_32_16( st->enerLH_fx, 24576 ) ) ) /* 24576 in Q13*/ - || ( GT_32( L_shr( st->enerLL_fx, 1 ), Mult_32_16( st->enerLH_fx, 24576 ) ) && /*24576 = 1.5 in Q14*/ - LT_16( st->tilt_wb_fx, 20480 ) ) /* 20480 = 10 in Q11*/ - ) - { - is_fractive = 0; - } - ELSE - { - is_fractive = 1; - } - move16(); - } - - /* WB/SWB bandwidth switching */ - IF( st->bws_cnt > 0 ) - { - f_fx = 1489; /*1.0f / 22.0f in Q15*/ - move16(); - inc_fx = 1489; /*1.0f / 22.0f in Q15*/ - move16(); - - IF( EQ_16( is_fractive, 1 ) ) - { - Copy( lsf_tab_fx, hBWE_TD->lsp_prevfrm_fx, LPC_SHB_ORDER ); - } - ELSE - { - FOR( i = 0; i < LPC_SHB_ORDER; i++ ) - { - hBWE_TD->lsp_prevfrm_fx[i] = f_fx; /*Q15*/ - move16(); - f_fx = add( f_fx, inc_fx ); /*Q15*/ - } - } - test(); - test(); - test(); - test(); - test(); - test(); - test(); - IF( ( NE_16( st->last_extl, SWB_TBE ) && NE_16( st->last_extl, FB_TBE ) && !( ( L_sub( L_shr( st->prev_enerLH_fx, 1 ), st->enerLH_fx ) < 0 ) && L_sub( st->prev_enerLH_fx, ( L_shr( st->enerLH_fx, 1 ) > 0 ) ) ) ) || st->last_core != ACELP_CORE || ( ( st->last_core == ACELP_CORE ) && GT_32( abs( L_sub( st->last_core_brate, st->core_brate ) ), 3600 ) ) || EQ_16( s_xor( is_fractive, st->prev_fractive ), 1 ) ) - { - set16_fx( GainShape_fx, 11587, NUM_SHB_SUBFR ); /*0.3536f in Q15*/ - } - ELSE - { - if ( GT_16( hBWE_TD->prev_GainShape_fx, 11587 ) ) /*0.3536f in Q15*/ - { - hBWE_TD->prev_GainShape_fx = 11587; /*0.3536f in Q15*/ - move16(); - } - set16_fx( GainShape_fx, hBWE_TD->prev_GainShape_fx, NUM_SHB_SUBFR ); - } - - Copy( hBWE_TD->lsp_prevfrm_fx, lsf_shb_fx, LPC_SHB_ORDER ); - set16_fx( shb_res_gshape_fx, 3277 /*0.2f Q14*/, NB_SUBFR16k ); /* Q14 */ - } - ELSE - { - test(); - IF( NE_16( st->last_extl, SWB_TBE ) && NE_16( st->last_extl, FB_TBE ) ) - { - f_fx = 1489; /*Q15*/ - move16(); - inc_fx = 1489; /*Q15*/ - move16(); - FOR( i = 0; i < LPC_SHB_ORDER; i++ ) - { - hBWE_TD->lsp_prevfrm_fx[i] = f_fx; /*Q15*/ - move16(); - f_fx = add( f_fx, inc_fx ); - } - } - - IF( !st->bfi ) - { - IF( st->use_partial_copy ) - { - IF( NE_16( st->last_extl, SWB_TBE ) ) - { - hBWE_TD->GainFrame_prevfrm_fx = 0; - move32(); - f_fx = 1489 /*0.045454f Q15*/; - move16(); - inc_fx = 1489 /*0.045454f Q15*/; - move16(); - FOR( i = 0; i < LPC_SHB_ORDER; i++ ) - { - hBWE_TD->lsp_prevfrm_fx[i] = f_fx; /*Q15*/ - move16(); - f_fx = add( f_fx, inc_fx ); /*Q15*/ - } - } - Copy( hBWE_TD->lsp_prevfrm_fx, lsf_shb_fx, LPC_SHB_ORDER ); - set16_fx( GainShape_fx, RECIP_ROOT_EIGHT_FX, NUM_SHB_SUBFR ); - - IF( EQ_16( st->rf_frame_type, RF_NELP ) ) - { - /* Frame gain */ - - GainFrame_fx = L_mac( SHB_GAIN_QLOW_FX, st->rf_indx_tbeGainFr, SHB_GAIN_QDELTA_FX ); - L_tmp = Mult_32_16( GainFrame_fx, 27213 ); /*Q16*/ /* 3.321928 in Q13 */ - - frac = L_Extract_lc( L_tmp, &exp ); - L_tmp = Pow2( 30, frac ); - GainFrame_fx = L_shl( L_tmp, sub( exp, 12 ) ); /*Q18*/ - - test(); - test(); - test(); - test(); - test(); - test(); - IF( ( st->core == ACELP_CORE ) && ( st->last_core == ACELP_CORE ) && !st->prev_use_partial_copy && EQ_16( st->prev_coder_type, UNVOICED ) && NE_32( GainFrame_fx, hBWE_TD->GainFrame_prevfrm_fx ) && NE_16( st->next_coder_type, GENERIC ) && EQ_16( st->last_extl, SWB_TBE ) ) - { - GainFrame_fx = L_add( Mult_32_16( hBWE_TD->GainFrame_prevfrm_fx, 26214 /*0.8f in Q15*/ ), Mult_32_16( GainFrame_fx, 6553 /*0.2f in Q15*/ ) ); - } - } - ELSE - { - temp_fx = 0; - move16(); - /* Frame gain */ - SWITCH( st->rf_indx_tbeGainFr ) - { - case 0: - GainFrame_fx = 131072; /* 0.5f in Q18 */ - move32(); - if ( LE_32( hBWE_TD->GainFrame_prevfrm_fx, 327680l /*1.25 Q18*/ ) ) - { - temp_fx = 26214 /*0.8 Q15*/; - move16(); - } - BREAK; - case 1: - GainFrame_fx = 524288; /* 2.0f in Q18 */ - move32(); - test(); - if ( GT_32( hBWE_TD->GainFrame_prevfrm_fx, 327680l /*1.25 Q18*/ ) && LE_32( hBWE_TD->GainFrame_prevfrm_fx, 786432l /*3 Q18*/ ) ) - { - temp_fx = 26214 /*0.8 Q15*/; - move16(); - } - BREAK; - case 2: - GainFrame_fx = 1048576; /* 4.0f in Q18 */ - move32(); - test(); - if ( GT_32( hBWE_TD->GainFrame_prevfrm_fx, 786432l /*3 Q18*/ ) && LE_32( hBWE_TD->GainFrame_prevfrm_fx, 1572864l /*6 Q18*/ ) ) - { - temp_fx = 26214 /*0.8 Q15*/; - move16(); - } - BREAK; - case 3: - GainFrame_fx = 2097152; /* 8.0f in Q18 */ - move32(); - test(); - if ( GT_32( hBWE_TD->GainFrame_prevfrm_fx, 1572864l /*6 Q18*/ ) && LE_32( hBWE_TD->GainFrame_prevfrm_fx, 4194304l /*16Q18*/ ) ) - { - temp_fx = 26214 /*0.8 Q15*/; - move16(); - } - BREAK; - default: - fprintf( stderr, "RF SWB-TBE gain bits not supported." ); - } - - IF( EQ_16( st->last_extl, SWB_TBE ) ) - { - GainFrame_fx = L_add( Mult_32_16( hBWE_TD->GainFrame_prevfrm_fx, temp_fx ), Mult_32_16( GainFrame_fx, sub( 32767, temp_fx ) ) ); - /*Q18*/ - } - - IF( ( st->core == ACELP_CORE ) && ( st->last_core == ACELP_CORE ) ) - { - if ( !st->prev_use_partial_copy && EQ_16( st->last_coder_type, VOICED ) && EQ_16( st->rf_frame_type, RF_GENPRED ) && GT_32( GainFrame_fx, 2097152 /*8.0f in Q18*/ ) && LT_32( GainFrame_fx, 3059606 /*11.67f in Q18*/ ) ) - { - GainFrame_fx = Mult_32_16( GainFrame_fx, 9830 /*0.3f in Q15*/ ); // Q18 - } - } - } - } - ELSE - { - /* de-quantization */ - ivas_dequantizeSHBparams_fx_9_1( st, st->extl, st->extl_brate, lsf_shb_fx, GainShape_fx, &GainFrame_fx, &stemp, - &shb_ener_sf_32, shb_res_gshape_fx, &mixFactors_fx, &MSFlag ); - if ( hStereoICBWE != NULL ) - { - hStereoICBWE->MSFlag = MSFlag; - move16(); - } - } - } - ELSE - { - Copy( hBWE_TD->lsp_prevfrm_fx, lsf_shb_fx, LPC_SHB_ORDER ); - test(); - IF( EQ_16( st->codec_mode, MODE1 ) && ( st->element_mode == EVS_MONO ) ) - { - gradientGainShape( st, GainShape_fx, &GainFrame_fx ); - } - ELSE - { - FOR( i = 0; i < NUM_SHB_SUBFR / 4; i++ ) - { - FOR( j = 0; j < 4; j++ ) - { - GainShape_fx[i * 4 + j] = mult_r( st->cummulative_damping, st->GainShape_Delay[4 + i] ); - move16(); - } - } - IF( GT_16( tilt_swb_fec_fx, ( 8 << 11 ) ) ) /* tilt_swb_fec_fx in Q11 */ - { - IF( EQ_16( st->nbLostCmpt, 1 ) ) - { - GainFrame_fx = Mult_32_16( hBWE_TD->GainFrame_prevfrm_fx, 19661 /*0.6f Q15*/ ); - } - ELSE IF( EQ_16( st->nbLostCmpt, 2 ) ) - { - GainFrame_fx = Mult_32_16( hBWE_TD->GainFrame_prevfrm_fx, 11469 /*0.35f Q15*/ ); - } - ELSE - { - GainFrame_fx = Mult_32_16( hBWE_TD->GainFrame_prevfrm_fx, 6554 /*0.2f Q15*/ ); - } - GainFrame_fx = Mult_32_16( GainFrame_fx, st->cummulative_damping ); - } - ELSE - { - GainFrame_fx = hBWE_TD->GainFrame_prevfrm_fx; - move32(); /* gain locking */ - } - } - - IF( GE_32( st->extl_brate, SWB_TBE_2k8 ) ) - { - test(); - IF( EQ_16( st->codec_mode, MODE1 ) && ( st->element_mode == EVS_MONO ) ) - { - L_tmp = L_mult( extract_l( hBWE_TD->prev2_shb_ener_sf_fx ), extract_l( hBWE_TD->prev3_shb_ener_sf_fx ) ); /*Q1*/ - tmp = round_fx( root_a_fx( L_tmp, 1, &exp ) ); /* Q = 15-exp */ - tmp1 = extract_l( hBWE_TD->prev1_shb_ener_sf_fx ); /*Q0*/ - i = sub( norm_s( tmp1 ), 1 ); - tmp1 = shl( tmp1, i ); /* Qi */ - IF( tmp == 0 ) - { - tmp = 32767 /*1.0f Q15*/; - move16(); /*Q15*/ - } - ELSE - { - scale_fx = div_s( tmp1, tmp ); /* Q15 - Q(15-exp) + Qi = Qexp+i */ - scale_fx = s_max( scale_fx, 0 ); -#ifdef BASOP_NOGLOB - tmp = shl_sat( scale_fx, sub( sub( 15, exp ), i ) ); /*Q15*/ -#else - tmp = shl( scale, 15 - exp - i ); /*Q15*/ -#endif - } - scale_fx = mult_r( hBWE_TD->prev_res_shb_gshape_fx, tmp ); /* Q14 */ - test(); - IF( GT_32( L_shr( hBWE_TD->prev2_shb_ener_sf_fx, 1 ), hBWE_TD->prev1_shb_ener_sf_fx ) || - GT_32( L_shr( hBWE_TD->prev3_shb_ener_sf_fx, 1 ), hBWE_TD->prev2_shb_ener_sf_fx ) ) - { - shb_ener_sf_32 = Mult_32_16( hBWE_TD->prev1_shb_ener_sf_fx, scale_fx ); - - if ( GT_16( st->nbLostCmpt, 1 ) ) - { - shb_ener_sf_32 = L_shr( shb_ener_sf_32, 1 ); - } - } - ELSE - { - L_tmp = L_mult( scale_fx, scale_fx ); /* Q29 */ - shb_ener_sf_32 = L_shl( Mult_32_16( hBWE_TD->prev1_shb_ener_sf_fx, round_fx( L_tmp ) ), 2 ); - } - } - ELSE - { - test(); - IF( GT_32( L_shr( hBWE_TD->prev2_shb_ener_sf_fx, 1 ), hBWE_TD->prev1_shb_ener_sf_fx ) || - GT_32( L_shr( hBWE_TD->prev3_shb_ener_sf_fx, 1 ), hBWE_TD->prev2_shb_ener_sf_fx ) ) - { - shb_ener_sf_32 = L_shr( Mult_32_16( hBWE_TD->prev1_shb_ener_sf_fx, st->cummulative_damping ), 1 ); - } - ELSE - { - shb_ener_sf_32 = Mult_32_16( hBWE_TD->prev1_shb_ener_sf_fx, st->cummulative_damping ); - } - } - } - - shb_ener_sf_32 = L_max( shb_ener_sf_32, 1l /*1.0f Q0*/ ); - mixFactors_fx = hBWE_TD->prev_mixFactors_fx; - move16(); - - IF( EQ_16( st->codec_mode, MODE1 ) ) - { - set16_fx( shb_res_gshape_fx, 3277 /*0.2f Q14*/, 5 ); /* Q14 */ - } - ELSE - { - set16_fx( shb_res_gshape_fx, 16384 /*1.0f Q14*/, 5 ); /* Q14 */ - } - } - } - - /* get the gainshape delay */ - Copy( &st->GainShape_Delay[4], &st->GainShape_Delay[0], NUM_SHB_SUBFR / 4 ); - FOR( i = 0; i < NUM_SHB_SUBFR / 4; i++ ) - { - st->GainShape_Delay[i + 4] = GainShape_fx[i * 4]; /*Q15*/ - move16(); - } - - L_tmp = L_mult( voice_factors_fx[0], 8192 ); - L_tmp = L_mac( L_tmp, voice_factors_fx[1], 8192 ); - L_tmp = L_mac( L_tmp, voice_factors_fx[2], 8192 ); - mean_vf = mac_r( L_tmp, voice_factors_fx[3], 8192 ); - - Copy( voice_factors_fx, vf_modified_fx, NB_SUBFR16k ); - - test(); - IF( EQ_16( st->coder_type, VOICED ) || GT_16( mean_vf, 13107 /*0.4f Q15*/ ) ) - { - FOR( i = 1; i < NB_SUBFR; i++ ) - { - L_tmp = L_mult( voice_factors_fx[i], 26214 /*0.8f Q15*/ ); - vf_modified_fx[i] = mac_r( L_tmp, voice_factors_fx[i - 1], 6554 /*0.2f Q15*/ ); - move16(); - } - - IF( st->L_frame != L_FRAME ) - { - L_tmp = L_mult( voice_factors_fx[4], 26214 /*0.8f Q15*/ ); - vf_modified_fx[4] = mac_r( L_tmp, voice_factors_fx[3], 6554 /*0.2f Q15*/ ); - move16(); - } - } - - test(); - IF( st->use_partial_copy && st->nelp_mode_dec ) - { - set16_fx( vf_modified_fx, 0, NB_SUBFR16k ); - } - - /* SHB LSF from current frame; and convert to LSP for interpolation */ - E_LPC_lsf_lsp_conversion( lsf_shb_fx, lsp_shb_2_fx, LPC_SHB_ORDER ); - - test(); - IF( EQ_16( st->last_extl, SWB_TBE ) || EQ_16( st->last_extl, FB_TBE ) ) - { - /* SHB LSP values from prev. frame for interpolation */ - Copy( hBWE_TD->swb_lsp_prev_interp_fx, lsp_shb_1_fx, LPC_SHB_ORDER ); - } - ELSE - { - /* Use current frame's LSPs; in effect no interpolation */ - Copy( lsp_shb_2_fx, lsp_shb_1_fx, LPC_SHB_ORDER ); - } - - test(); - test(); - test(); - IF( ( st->bws_cnt == 0 ) && ( st->bws_cnt1 == 0 ) && ( st->prev_use_partial_copy == 0 ) && ( st->use_partial_copy == 0 ) ) - { - lsf_diff_fx[0] = 16384; - move16(); /*Q15*/ - lsf_diff_fx[LPC_SHB_ORDER - 1] = 16384; - move16(); /*Q15*/ - FOR( i = 1; i < LPC_SHB_ORDER - 1; i++ ) - { - lsf_diff_fx[i] = sub( lsf_shb_fx[i], lsf_shb_fx[i - 1] ); - move16(); - } - - a2rc_fx( hBWE_TD->cur_sub_Aq_fx + 1, refl_fx, M ); - tmp = add( 16384, shr( refl_fx[0], 1 ) ); /*Q14*/ - tmp1 = mult( 27425, tmp ); - tmp1 = mult( tmp1, tmp ); /*Q10*/ - tmp2 = shr( mult( 31715, tmp ), 2 ); /*Q10*/ - tilt_para_fx = add( sub( tmp1, tmp2 ), 1335 ); /*Q10*/ - - test(); - IF( NE_16( st->last_extl, SWB_TBE ) && NE_16( st->last_extl, FB_TBE ) ) - { - FOR( i = 1; i < LPC_SHB_ORDER - 1; i++ ) - { - hBWE_TD->prev_lsf_diff_fx[i - 1] = shr( lsf_diff_fx[i], 1 ); - move16(); - } - } - - IF( LE_32( st->extl_brate, FB_TBE_1k8 ) ) - { - test(); - test(); - test(); - test(); - test(); - IF( !( GT_16( hBWE_TD->prev_tilt_para_fx, 5120 ) && ( EQ_16( st->coder_type, TRANSITION ) || LT_16( tilt_para_fx, 1024 ) ) ) && - !( ( ( LT_16( hBWE_TD->prev_tilt_para_fx, 3072 ) && GE_16( st->prev_coder_type, VOICED ) ) ) && GT_16( tilt_para_fx, 5120 ) ) ) - { - FOR( i = 1; i < LPC_SHB_ORDER - 1; i++ ) - { - IF( LT_16( lsf_diff_fx[i], hBWE_TD->prev_lsf_diff_fx[i - 1] ) ) - { - tmp = mult( 26214, lsf_diff_fx[i] ); - - test(); - IF( ( hBWE_TD->prev_lsf_diff_fx[i - 1] <= 0 ) || ( tmp < 0 ) ) /* safety check in case of bit errors */ - { - st->BER_detect = 1; - move16(); - tmp = 0; - move16(); - } - ELSE - { - tmp = div_s( tmp, hBWE_TD->prev_lsf_diff_fx[i - 1] ); - } - - tmp = s_max( tmp, 16384 ); - w_fx[i] = s_min( tmp, 32767 ); - move16(); - } - ELSE - { - tmp = mult( 26214, hBWE_TD->prev_lsf_diff_fx[i - 1] ); - - test(); - IF( ( lsf_diff_fx[i] <= 0 ) || ( tmp < 0 ) ) /* safety check in case of bit errors */ - { - st->BER_detect = 1; - move16(); - tmp = 0; - move16(); - } - ELSE - { - tmp = div_s( tmp, lsf_diff_fx[i] ); - } - - tmp = s_max( tmp, 16384 ); - w_fx[i] = s_min( tmp, 32767 ); - move16(); - } - } - w_fx[0] = w_fx[1]; - move16(); - w_fx[LPC_SHB_ORDER - 1] = w_fx[LPC_SHB_ORDER - 2]; - move16(); - - FOR( i = 0; i < LPC_SHB_ORDER; i++ ) - { - tmp1 = mult( lsp_shb_1_fx[i], sub( 32767, w_fx[i] ) ); - tmp2 = mult( lsp_shb_2_fx[i], w_fx[i] ); - lsp_temp_fx[i] = add( tmp1, tmp2 ); - move16(); - } - } - ELSE - { - Copy( lsp_shb_2_fx, lsp_temp_fx, LPC_SHB_ORDER ); - } - - /* convert from lsp to lsf */ - lsp2lsf_fx( lsp_temp_fx, lsf_shb_fx, LPC_SHB_ORDER, 1 ); - } - - Copy( lsf_diff_fx + 1, hBWE_TD->prev_lsf_diff_fx, LPC_SHB_ORDER - 2 ); - hBWE_TD->prev_tilt_para_fx = tilt_para_fx; - move16(); - } - ELSE - { - Copy( lsp_shb_2_fx, lsp_temp_fx, LPC_SHB_ORDER ); - } - - IF( GE_32( st->extl_brate, SWB_TBE_2k8 ) ) - { - /* SHB LSP interpolation */ - ptr_lsp_interp_coef_fx = interpol_frac_shb; /*Q15*/ - FOR( j = 0; j < 4; j++ ) - { - FOR( i = 0; i < LPC_SHB_ORDER; i++ ) - { - L_tmp = L_mult( lsp_shb_1_fx[i], ( *ptr_lsp_interp_coef_fx ) ); - lsp_temp_fx[i] = mac_r( L_tmp, lsp_shb_2_fx[i], ( *( ptr_lsp_interp_coef_fx + 1 ) ) ); - move16(); - } - ptr_lsp_interp_coef_fx += 2; - - tmp = i_mult( j, ( LPC_SHB_ORDER + 1 ) ); - /* convert LSPs to LP coefficients */ - E_LPC_f_lsp_a_conversion( lsp_temp_fx, lpc_shb_sf_fx + tmp, LPC_SHB_ORDER ); -#ifndef FIX_1100_REMOVE_LPC_RESCALING - /* Bring the LPCs to Q12 */ - Copy_Scale_sig( lpc_shb_sf_fx + tmp, lpc_shb_sf_fx + tmp, LPC_SHB_ORDER + 1, sub( norm_s( lpc_shb_sf_fx[tmp] ), 2 ) ); - lpc_shb_sf_fx[i_mult( j, ( LPC_SHB_ORDER + 1 ) )] = ONE_IN_Q12; // recheck this - move16(); -#endif - } - } - - /* Save the SWB LSP values from current frame for interpolation */ - Copy( lsp_shb_2_fx, hBWE_TD->swb_lsp_prev_interp_fx, LPC_SHB_ORDER ); - - /* save the shb_ener and mixFactor values */ - hBWE_TD->prev3_shb_ener_sf_fx = hBWE_TD->prev2_shb_ener_sf_fx; - move32(); - hBWE_TD->prev2_shb_ener_sf_fx = hBWE_TD->prev1_shb_ener_sf_fx; - move32(); - hBWE_TD->prev1_shb_ener_sf_fx = shb_ener_sf_32; - move32(); - hBWE_TD->prev_res_shb_gshape_fx = shb_res_gshape_fx[4]; - move16(); - hBWE_TD->prev_mixFactors_fx = mixFactors_fx; - move16(); - - /* SWB CNG/DTX - update memories */ - IF( st->hTdCngDec != NULL ) - { - Copy( st->hTdCngDec->lsp_shb_prev_fx, st->hTdCngDec->lsp_shb_prev_prev_fx, LPC_SHB_ORDER ); - Copy( lsf_shb_fx, st->hTdCngDec->lsp_shb_prev_fx, LPC_SHB_ORDER ); - } - - /* convert LSPs back into LP coeffs */ - E_LPC_f_lsp_a_conversion( lsp_temp_fx, lpc_shb_fx, LPC_SHB_ORDER ); - Copy_Scale_sig( lpc_shb_fx, lpc_shb_fx, LPC_SHB_ORDER + 1, sub( norm_s( lpc_shb_fx[0] ), 2 ) ); /* Q12 */ - lpc_shb_fx[0] = ONE_IN_Q12; - move16(); - - test(); - IF( EQ_32( st->extl_brate, SWB_TBE_1k10 ) || EQ_32( st->extl_brate, SWB_TBE_1k75 ) ) - { - Word32 vind_temp = Mpy_32_32( L_shl( L_add( L_deposit_l( mixFactors_fx ), 1 ), 15 ), ( ( ( 1 << NUM_BITS_SHB_VF ) - 1 ) << 16 ) ); // check addition of 1 - vind = extract_l( L_shr( vind_temp, 15 ) ); /* 3 for mpy by 8.0f, -15 to bring it to Q0 */ /*mixFactors*7*/ - /* i: mixFactors_fx in Q15 */ - /* o: vind in Q0 */ - } - ELSE - { - vind = shl( mixFactors_fx, 3 - 15 ); /* 3 for mpy by 8.0f, -15 to bring it to Q0 */ /*mixFactors*8*/ - /* i: mixFactors_fx in Q15 */ - /* o: vind in Q0 */ - } - - /* Determine formant PF strength */ - formant_fac_fx = swb_formant_fac_fx( lpc_shb_fx[1], &hBWE_TD->tilt_mem_fx ); - /* i:lpc_shb_fx Q12, o:formant_fac_fx Q15 */ - IF( GT_32( st->total_brate, ACELP_32k ) ) - { - FOR( j = 0; j < 4; j++ ) - { - Copy( lpc_shb_fx, &lpc_shb_sf_fx[i_mult( j, ( LPC_SHB_ORDER + 1 ) )], LPC_SHB_ORDER + 1 ); - } - } - - /* From low band excitation, generate highband excitation */ - - /* -------- start of memory rescaling -------- */ - /* ----- calculate optimum Q_bwe_exc and rescale memories accordingly ----- */ - Lmax = 0; - move32(); - FOR( cnt = 0; cnt < L_FRAME32k; cnt++ ) - { - Lmax = L_max( Lmax, L_abs( bwe_exc_extended_fx[cnt] ) ); - } - Q_bwe_exc = norm_l( Lmax ); - if ( Lmax == 0 ) - { - Q_bwe_exc = 31; - move16(); - } - Q_bwe_exc = add( Q_bwe_exc, add( Q_exc, Q_exc ) ); - find_max_mem_dec( st, &n_mem, &n_mem2, &n_mem3 ); /* for >=24.4, use n_mem2 lpc_syn, shb_20sample, and mem_stp_swb_fx memory */ - - tmp = add( st->prev_Q_bwe_exc, n_mem ); - if ( GT_16( Q_bwe_exc, tmp ) ) - { - Q_bwe_exc = tmp; - move16(); - } - - /* rescale the memories if Q_bwe_exc is different from previous frame */ - sc = sub( Q_bwe_exc, st->prev_Q_bwe_exc ); - IF( sc != 0 ) - { - rescale_genSHB_mem_dec( st, sc ); - } - - /* rescale the bwe_exc_extended and bring it to 16-bit single precision with dynamic norm */ - sc = sub( Q_bwe_exc, add( Q_exc, Q_exc ) ); - - FOR( cnt = 0; cnt < L_FRAME32k; cnt++ ) - { -#ifdef BASOP_NOGLOB - bwe_exc_extended_16[cnt] = round_fx_sat( L_shl_sat( bwe_exc_extended_fx[cnt], sc ) ); -#else - bwe_exc_extended_16[cnt + NL_BUFF_OFFSET] = round_fx( L_shl( bwe_exc_extended[cnt], sc ) ); -#endif - move16(); - } - - /* state_syn_shbexc_fx is kept at (st_fx->prev_Q_bwe_syn) for 24.4/32kbps or is kept at Q_bwe_exc for 13.2/16.4kbps */ - - /* save the previous Q factor (32-bit) of the buffer */ - st->prev_Q_bwe_exc = Q_bwe_exc; - move16(); - - Q_bwe_exc = sub( Q_bwe_exc, 16 ); /* Q_bwe_exc reflecting the single precision dynamic norm-ed buffers from here */ - - /* -------- end of rescaling memories -------- */ - - Q_bwe_exc_fb = st->prev_Q_bwe_exc_fb; - move16(); - - Q_shb = 0; - move16(); - - Copy( hBWE_TD->state_syn_shbexc_fx, shaped_shb_excitation_fx, L_SHB_LAHEAD ); - GenShapedSHBExcitation_ivas_dec_fx( shaped_shb_excitation_fx + L_SHB_LAHEAD, lpc_shb_fx, White_exc16k_fx, - hBWE_TD->mem_csfilt_fx, hBWE_TD->mem_genSHBexc_filt_down_shb_fx, hBWE_TD->state_lpc_syn_fx, - st->coder_type, bwe_exc_extended_16, hBWE_TD->bwe_seed, vf_modified_fx, st->extl, - &( hBWE_TD->tbe_demph_fx ), &( hBWE_TD->tbe_premph_fx ), lpc_shb_sf_fx, shb_ener_sf_32, - shb_res_gshape_fx, shb_res_dummy_fx, &vind, formant_fac_fx, hBWE_TD->fb_state_lpc_syn_fx, - &( hBWE_TD->fb_tbe_demph_fx ), &Q_bwe_exc, &Q_bwe_exc_fb, Q_shb, n_mem2, st->prev_Q_bwe_syn, st->total_brate, st->prev_bfi, - st->element_mode, st->flag_ACELP16k, nlExc16k_fx, mixExc16k_fx, st->extl_brate, MSFlag, - NULL, &( hBWE_TD->prev_pow_exc16kWhtnd_fx32 ), &( hBWE_TD->prev_mix_factor_fx ), NULL, NULL ); - - *Q_white_exc = Q_bwe_exc_fb; - move16(); - IF( EQ_16( st->extl, FB_TBE ) ) - { - st->prev_Q_bwe_exc_fb = Q_bwe_exc_fb; - move16(); - } - ELSE - { - /*Indirectly a memory reset of FB memories for next frame such that rescaling of memories would lead to 0 due to such high prev. Q value. - 51 because of 31 + 20(shift of Q_bwe_exc_fb before de-emphasis)*/ - st->prev_Q_bwe_exc_fb = 51; - move16(); - } - - /* rescale the TBE post proc memory */ - FOR( i = 0; i < LPC_SHB_ORDER; i++ ) - { - hBWE_TD->mem_stp_swb_fx[i] = shl_sat( hBWE_TD->mem_stp_swb_fx[i], sub( Q_bwe_exc, st->prev_Q_bwe_syn ) ); - move16(); - } - /* fill-in missing SHB excitation */ - test(); - test(); - IF( ( EQ_16( st->element_mode, IVAS_CPE_TD ) || EQ_16( st->element_mode, IVAS_CPE_DFT ) ) && LE_32( st->last_core_brate, SID_2k40 ) ) - { - Copy( shaped_shb_excitation_fx + L_SHB_LAHEAD, shaped_shb_excitation_fx, L_SHB_LAHEAD ); - } - - IF( hStereoICBWE != NULL ) - { - Copy( shaped_shb_excitation_fx + L_SHB_LAHEAD, hStereoICBWE->shbSynthRef_fx, L_FRAME16k ); - } - - test(); - IF( NE_32( st->extl_brate, SWB_TBE_1k10 ) && NE_32( st->extl_brate, SWB_TBE_1k75 ) ) - { - FOR( i = 0; i < L_FRAME16k; i += L_SUBFR16k ) - { - /* TD BWE post-processing */ - PostShortTerm_ivas_dec_fx( &shaped_shb_excitation_fx[L_SHB_LAHEAD + i], lpc_shb_fx, &shaped_shb_excitationTemp_fx[i], hBWE_TD->mem_stp_swb_fx, - hBWE_TD->ptr_mem_stp_swb_fx, &( hBWE_TD->gain_prec_swb_fx ), hBWE_TD->mem_zero_swb_fx, formant_fac_fx ); - } - - Copy( shaped_shb_excitationTemp_fx, &shaped_shb_excitation_fx[L_SHB_LAHEAD], L_FRAME16k ); /* Q_bwe_exc */ - - tmp = sub( shl( Q_bwe_exc, 1 ), 31 + 16 ); -#ifdef BASOP_NOGLOB - prev_pow_fx = L_shl_sat( 1407374848l /*0.00001f Q47*/, tmp ); /* 2*(Q_bwe_exc) */ - curr_pow_fx = L_shl_sat( 1407374848l /*0.00001f Q47*/, tmp ); /* 2*(Q_bwe_exc) */ -#else - prev_pow_fx = L_shl( 1407374848l /*0.00001f Q47*/, tmp ); /* 2*(Q_bwe_exc) */ - curr_pow_fx = L_shl( 1407374848l /*0.00001f Q47*/, tmp ); /* 2*(Q_bwe_exc) */ -#endif - FOR( i = 0; i < L_SHB_LAHEAD + 10; i++ ) - { -#ifdef BASOP_NOGLOB - prev_pow_fx = L_mac0_sat( prev_pow_fx, shaped_shb_excitation_fx[i], shaped_shb_excitation_fx[i] ); /*2*Q_bwe_exc*/ - curr_pow_fx = L_mac0_sat( curr_pow_fx, shaped_shb_excitation_fx[i + L_SHB_LAHEAD + 10], shaped_shb_excitation_fx[i + L_SHB_LAHEAD + 10] ); /* 2*Q_bwe_exc */ -#else - prev_pow_fx = L_mac0( prev_pow_fx, shaped_shb_excitation_fx[i], shaped_shb_excitation_fx[i] ); /*2*Q_bwe_exc*/ - curr_pow_fx = L_mac0( curr_pow_fx, shaped_shb_excitation_fx[i + L_SHB_LAHEAD + 10], shaped_shb_excitation_fx[i + L_SHB_LAHEAD + 10] ); /* 2*Q_bwe_exc */ -#endif - } - - if ( GT_16( voice_factors_fx[0], 24576 /*0.75f Q15*/ ) ) - { - curr_pow_fx = L_shr( curr_pow_fx, 2 ); /* Q(2*Q_bwe_exc) */ - } - - Lscale = root_a_over_b_fx( curr_pow_fx, - shl( Q_bwe_exc, 1 ), - prev_pow_fx, - shl( Q_bwe_exc, 1 ), - &exp ); - - FOR( i = 0; i < L_SHB_LAHEAD; i++ ) - { - L_tmp = Mult_32_16( Lscale, shaped_shb_excitation_fx[i] ); /* Q_bwe_exc + (31-exp) - 15 */ - shaped_shb_excitation_fx[i] = round_fx_sat( L_shl_sat( L_tmp, exp ) ); /* Q_bwe_exc */ - move16(); - } - IF( exp < 0 ) - { - Lscale = L_shl( Lscale, exp ); - exp = 0; - move16(); - } - FOR( ; i < L_SHB_LAHEAD + 10; i++ ) - { -#ifdef BASOP_NOGLOB - temp_fx = i_mult_sat( sub( i, 19 ), 3277 /*0.1f Q15*/ ); /* Q15 */ - L_tmp1 = Mult_32_16( L_shl_sat( 1, sub( 31, exp ) ), temp_fx ); /* Q31-exp */ -#else - temp_fx = i_mult( sub( i, 19 ), 3277 /*0.1f Q15*/ ); /* Q15 */ - L_tmp1 = Mult_32_16( L_shl( 1, sub( 31, exp ) ), temp_fx ); /* Q31-exp */ -#endif - temp_fx = sub( 32767 /*1.0f Q15*/, temp_fx ); - Lscale = L_add( Mult_32_16( Lscale, temp_fx ), L_tmp1 ); - L_tmp = Mult_32_16( Lscale, shaped_shb_excitation_fx[i] ); /* Q_bwe_exc + (31-exp) - 15 */ - shaped_shb_excitation_fx[i] = round_fx_sat( L_shl_sat( L_tmp, exp ) ); /* Q_bwe_exc */ - move16(); - } - } - ELSE - { - /* reset the PF memories if the PF is not running */ - set16_fx( hBWE_TD->mem_stp_swb_fx, 0, LPC_SHB_ORDER ); - hBWE_TD->gain_prec_swb_fx = ONE_IN_Q14; - move16(); - set16_fx( hBWE_TD->mem_zero_swb_fx, 0, LPC_SHB_ORDER ); - } - - /* Update SHB excitation */ - Copy( shaped_shb_excitation_fx + L_FRAME16k, hBWE_TD->state_syn_shbexc_fx, L_SHB_LAHEAD ); /* Q_bwe_exc */ - l_subframe = L_FRAME16k / NUM_SHB_SUBGAINS; - move16(); - L_ener = EPSILON_FX_SMALL; - move32(); - - FOR( i = 0; i < NUM_SHB_SUBGAINS; i++ ) - { - L_tmp = 0; - move32(); - ener_tmp_fx[i] = EPSILON_FX_SMALL; - move32(); - - Word64 tmp64 = 0; - move64(); - FOR( j = 0; j < l_subframe; j++ ) - { - tmp64 = W_mac0_16_16( tmp64, shaped_shb_excitation_fx[add( i_mult( i, l_subframe ), j )], shaped_shb_excitation_fx[add( i_mult( i, l_subframe ), j )] ); /* 2*Q_bwe_exc */ - } - L_tmp = W_sat_l( tmp64 ); - - L_tmp = Mult_32_16( L_tmp, 410 /*0.0125 Q15*/ ); /* 2*Q_bwe_exc: ener_tmp_fx in (2*Q_bwe_exc) */ - IF( L_tmp != 0 ) - { - exp = norm_l( L_tmp ); - tmp = extract_h( L_shl( L_tmp, exp ) ); - exp = sub( exp, sub( 30, i_mult( 2, Q_bwe_exc ) ) ); - - tmp = div_s( 16384, tmp ); - L_tmp = L_deposit_h( tmp ); - L_tmp = Isqrt_lc( L_tmp, &exp ); -#ifdef BASOP_NOGLOB - ener_tmp_fx[i] = L_shl_sat( L_tmp, sub( add( exp, shl( Q_bwe_exc, 1 ) ), 31 ) ); /*2 * Q_bwe_exc: Q31 -exp +exp +2 * Q_bwe_exc -31 */ - move32(); - L_ener = L_add_sat( L_ener, L_shr( ener_tmp_fx[i], 2 ) ); /* 2*Q_bwe_exc */ -#else - ener_tmp_fx[i] = L_shl( L_tmp, sub( add( exp, shl( Q_bwe_exc, 1 ) ), 31 ) ); /*2 * Q_bwe_exc: Q31 -exp +exp +2 * Q_bwe_exc -31 */ - move32(); - L_ener = L_add( L_ener, L_shr( ener_tmp_fx[i], 2 ) ); /* 2*Q_bwe_exc */ -#endif - } - } -#ifdef BASOP_NOGLOB /* Saturation fix taken from EVS*/ - ener_fx = s_max( 1, round_fx_sat( L_shl_sat( L_ener, sub( 18, shl( Q_bwe_exc, 1 ) ) ) ) ); /* Q2: 2*Q_bwe_exc+18-2*Q_bwe_exc-16 */ -#else - ener_fx = s_max( 1, round_fx( L_shl( L_ener, sub( 18, shl( Q_bwe_exc, 1 ) ) ) ) ); /* Q2: 2*Q_bwe_exc+18-2*Q_bwe_exc-16 */ -#endif - /* WB/SWB bandwidth switching */ - IF( st->bws_cnt > 0 ) - { - IF( is_fractive == 0 ) - { - IF( GT_16( st->tilt_wb_fx, 2048 ) ) /*assuming st->tilt_wb_fx in Q11*/ - { - st->tilt_wb_fx = 2048; - move16(); - } - ELSE IF( LT_16( st->tilt_wb_fx, 1024 ) ) - { - st->tilt_wb_fx = 1024; - move16(); - } - test(); - if ( EQ_16( st->prev_fractive, 1 ) && GT_16( st->tilt_wb_fx, 1024 ) ) - { - st->tilt_wb_fx = 1024; - move16(); - } - } - ELSE - { - IF( GT_16( st->tilt_wb_fx, 8192 ) ) - { - IF( st->prev_fractive == 0 ) - { - st->tilt_wb_fx = 8192; - move16(); - } - ELSE - { - st->tilt_wb_fx = 16384; - move16(); - } - } - ELSE - { - st->tilt_wb_fx = shl( st->tilt_wb_fx, 2 ); - move16(); - } - } - - IF( ener_fx != 0 ) - { - L_tmp = L_shl( L_mult0( ener_fx, st->tilt_wb_fx ), sub( st->Q_syn2, 13 ) ); /* 2+11 +st->Q_syn2 -13 = st->Q_syn2*/ - exp_ener = norm_s( ener_fx ); - tmp = shl( ener_fx, exp_ener ); /*Q(2+exp)*/ - inv_ener = shr( div_s( 16384, tmp ), 1 ); /*Q(15+14-2-exp-1) = 26 - exp*/ - - test(); - IF( GT_32( L_tmp, st->enerLH_fx ) ) /*st->Q_syn2*/ - { -#ifdef BASOP_NOGLOB - st->tilt_wb_fx = extract_h( L_shr_sat( Mult_32_16( st->enerLH_fx, inv_ener ), sub( sub( st->Q_syn2, exp_ener ), 16 ) ) ); /*Q11*/ -#else - st->tilt_wb_fx = extract_h( L_shr( Mult_32_16( st->enerLH_fx, inv_ener ), sub( sub( st->Q_syn2, exp_ener ), 16 ) ) ); /*Q11*/ -#endif - move16(); - /*st->Q_syn2 -1 + 26- exp_ener -15 -(st->Q_syn2 -exp_ener -16 ) -16 +1 -1 = (11) *0.5*/ - } - ELSE IF( LT_32( L_tmp, Mult_32_16( st->enerLH_fx, 1638 ) ) && EQ_16( is_fractive, 1 ) ) - { -#ifdef BASOP_NOGLOB - st->tilt_wb_fx = extract_h( L_shr_sat( Mult_32_16( st->enerLH_fx, inv_ener ), sub( sub( st->Q_syn2, exp_ener ), 15 ) ) ); /*Q11*/ -#else - st->tilt_wb_fx = extract_h( L_shr( Mult_32_16( st->enerLH_fx, inv_ener ), sub( sub( st->Q_syn2, exp_ener ), 15 ) ) ); /*Q11*/ -#endif - move16(); - /*st->Q_syn2 -1 + 26- exp_ener -15 -(st->Q_syn2 -exp_ener -15 ) -16 = (11) 0.25*/ - } - L_tmp = L_mult0( st->prev_ener_shb_fx, inv_ener ); /*Q(1+15+14-3-exp_ener) = 27 -exp_ener*/ - GainFrame_prevfrm_fx = L_shr( L_tmp, sub( 9, exp_ener ) ); /*27 -exp_ener -(9-exp_ener )= Q18*/ - } - ELSE - { - GainFrame_prevfrm_fx = 0; - move32(); - } - - IF( EQ_16( is_fractive, 1 ) ) - { - GainFrame_fx = L_shl( L_deposit_l( st->tilt_wb_fx ), 10 ); - } - ELSE - { - GainFrame_fx = L_shl( L_deposit_l( st->tilt_wb_fx ), 8 ); - } - - test(); - IF( EQ_16( ( is_fractive & st->prev_fractive ), 1 ) && GT_32( GainFrame_fx, GainFrame_prevfrm_fx ) ) - { - GainFrame_fx = L_add( Mult_32_16( GainFrame_prevfrm_fx, 26214 ), Mult_32_16( GainFrame_fx, 6554 ) ); /* 18 +15 -15 = 18*/ - } - ELSE - { - test(); - test(); - test(); - test(); - IF( ( LT_32( L_shr( st->prev_enerLH_fx, 1 ), st->enerLH_fx ) && GT_32( st->prev_enerLH_fx, L_shr( st->enerLH_fx, 1 ) ) ) && ( LT_32( L_shr( st->prev_enerLL_fx, 1 ), st->enerLL_fx ) && GT_32( st->prev_enerLL_fx, L_shr( st->enerLL_fx, 1 ) ) ) && ( s_xor( is_fractive, st->prev_fractive ) == 0 ) ) - { - GainFrame_fx = L_add( L_shr( GainFrame_fx, 1 ), L_shr( GainFrame_prevfrm_fx, 1 ) ); - } - ELSE - { - test(); - IF( ( is_fractive == 0 ) && EQ_16( st->prev_fractive, 1 ) ) - { - L_tmp1 = L_shl( Mult_32_16( GainFrame_fx, 3277 ), 13 ); /* 31 */ - L_tmp = L_sub( 2147483647, L_tmp1 ); /* 31 */ - GainFrame_fx = L_add( Mult_32_32( GainFrame_fx, L_tmp ), Mult_32_32( GainFrame_prevfrm_fx, L_tmp1 ) ); /* 18 */ - } - ELSE - { - GainFrame_fx = L_add( L_shr( GainFrame_fx, 1 ), L_shr( L_min( GainFrame_prevfrm_fx, GainFrame_fx ), 1 ) ); /* 18 */ - } - } - } - - GainFrame_fx = Mult_32_16( GainFrame_fx, i_mult( sub( N_WS2N_FRAMES, st->bws_cnt ), 819 ) ); /*Q18*/ - } - ELSE - { - IF( st->bws_cnt1 > 0 ) - { - GainFrame_fx = Mult_32_16( GainFrame_fx, i_mult( st->bws_cnt1, 819 ) ); /*Q18*/ - } - IF( GE_16( st->nbLostCmpt, 1 ) ) - { - ener_fx = s_max( 1, ener_fx ); - exp_ener = norm_s( ener_fx ); - tmp = shl( ener_fx, exp_ener ); /*Q(2+exp)*/ - inv_ener = div_s( 16384, tmp ); /*Q(15+14-2-exp)*/ - prev_ener_ratio_fx = L_shr( L_mult0( st->prev_ener_shb_fx, inv_ener ), add( sub( 9, exp_ener ), 1 ) ); /*Q: 1+27-exp-9+exp-1 = 18 */ - } - - IF( EQ_16( st->nbLostCmpt, 1 ) ) - { - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - IF( ( st->clas_dec != UNVOICED_CLAS ) && NE_16( st->clas_dec, UNVOICED_TRANSITION ) && LT_16( hBWE_TD->tilt_swb_fec_fx, 16384 ) && - ( ( GT_32( st->enerLL_fx, L_shr( st->prev_enerLL_fx, 1 ) ) && LT_32( L_shr( st->enerLL_fx, 1 ), st->prev_enerLL_fx ) ) || ( GT_32( st->enerLH_fx, L_shr( st->prev_enerLH_fx, 1 ) ) && LT_32( L_shr( st->enerLH_fx, 1 ), st->prev_enerLH_fx ) ) ) ) - { - IF( GT_32( L_shr( prev_ener_ratio_fx, 2 ), GainFrame_fx ) ) /*18*/ - { - GainFrame_fx = L_add( Mult_32_16( prev_ener_ratio_fx, 13107 ), Mult_32_16( GainFrame_fx, 19661 ) ); /*18*/ - } - ELSE IF( GT_32( L_shr( prev_ener_ratio_fx, 1 ), GainFrame_fx ) ) - { - GainFrame_fx = L_add( Mult_32_16( prev_ener_ratio_fx, 26214 ), Mult_32_16( GainFrame_fx, 6554 ) ); - } - ELSE - { - GainFrame_fx = L_add( Mult_32_16( prev_ener_ratio_fx, 6554 ), Mult_32_16( GainFrame_fx, 26214 ) ); - } - - test(); - IF( GT_16( tilt_swb_fec_fx, hBWE_TD->tilt_swb_fec_fx ) && ( hBWE_TD->tilt_swb_fec_fx > 0 ) ) - { - exp = norm_s( hBWE_TD->tilt_swb_fec_fx ); - tmp = shl( hBWE_TD->tilt_swb_fec_fx, exp ); /*Q(11+exp)*/ - tmp = div_s( 16384, tmp ); /*Q(15+14-11-exp)*/ - tmp = extract_h( L_shl( L_mult0( tmp, st->tilt_wb_fx ), sub( exp, 1 ) ) ); /*18 -exp +11 + exp -1 -16 =12; */ - GainFrame_fx = L_shl( Mult_32_16( GainFrame_fx, s_min( tmp, 20480 ) ), 3 ); /*Q18 = 18 +12 -15 +3 */ - } - } - ELSE IF( ( ( st->clas_dec != UNVOICED_CLAS ) || GT_16( hBWE_TD->tilt_swb_fec_fx, 4096 ) ) && GT_32( L_shr( prev_ener_ratio_fx, 2 ), GainFrame_fx ) && - ( GT_32( st->enerLL_fx, L_shr( st->prev_enerLL_fx, 1 ) ) || GT_32( st->enerLH_fx, L_shr( st->prev_enerLH_fx, 1 ) ) ) ) - { - GainFrame_fx = L_add( Mult_32_16( prev_ener_ratio_fx, 6554 ), Mult_32_16( GainFrame_fx, 26214 ) ); - } - } - ELSE IF( GT_16( st->nbLostCmpt, 1 ) ) - { - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - IF( GT_32( L_shr( prev_ener_ratio_fx, 2 ), GainFrame_fx ) && ( ( EQ_16( st->codec_mode, MODE1 ) && GT_32( st->enerLL_fx, st->prev_enerLL_fx ) && GT_32( st->enerLH_fx, st->prev_enerLH_fx ) ) || EQ_16( st->codec_mode, MODE2 ) ) ) - { - test(); - IF( GT_16( tilt_swb_fec_fx, 20480 /*10.0f in Q11*/ ) && GT_16( hBWE_TD->tilt_swb_fec_fx, 20480 /*10.0f in Q11*/ ) ) - { - GainFrame_fx = L_min( L_add( Mult_32_16( prev_ener_ratio_fx, 26214 /*0.8f in Q15*/ ), Mult_32_16( GainFrame_fx, 6554 /*0.2f in Q15*/ ) ), L_shl( Mult_32_16( GainFrame_fx, 16384 /*4.0f in Q12*/ ), 3 ) ); /*Q18*/ - } - ELSE - { - GainFrame_fx = L_min( L_add( Mult_32_16( prev_ener_ratio_fx, 16384 ), Mult_32_16( GainFrame_fx, 16384 ) ), L_shl( Mult_32_16( GainFrame_fx, 16384 ), 3 ) ); /*Q18*/ - } - } - ELSE IF( GT_32( prev_ener_ratio_fx, GainFrame_fx ) && ( ( EQ_16( st->codec_mode, MODE1 ) && GT_32( st->enerLL_fx, st->prev_enerLL_fx ) && GT_32( st->enerLH_fx, st->prev_enerLH_fx ) ) || EQ_16( st->codec_mode, MODE2 ) ) ) - { - test(); - IF( GT_16( tilt_swb_fec_fx, 20480 ) && GT_16( hBWE_TD->tilt_swb_fec_fx, 20480 ) ) - { - GainFrame_fx = L_add( Mult_32_16( prev_ener_ratio_fx, 16384 /*0.5f in Q15*/ ), Mult_32_16( GainFrame_fx, 16384 /*0.5f in Q15*/ ) ); /* Q18 */ - } - ELSE - { - GainFrame_fx = L_add( Mult_32_16( prev_ener_ratio_fx, 6554 /*0.2f in Q15*/ ), Mult_32_16( GainFrame_fx, 26214 /*0.8f in Q15*/ ) ); /* Q18 */ - } - } - } - } - - st->prev_fractive = is_fractive; - move16(); - - /* Adjust the subframe and frame gain of the synthesized shb signal */ - /* Scale the shaped excitation */ - IF( EQ_16( st->L_frame, L_FRAME ) ) - { - L_tmp = L_mult( pitch_buf_fx[0], 8192 ); - FOR( i = 1; i < NB_SUBFR; i++ ) - { - L_tmp = L_mac( L_tmp, pitch_buf_fx[i], 8192 ); /* pitch_buf in Q6 x 0.25 in Q15 */ - } - pitch_fx = round_fx( L_tmp ); /* Q6 */ - } - ELSE - { - L_tmp = L_mult( pitch_buf_fx[0], 6554 ); - FOR( i = 1; i < NB_SUBFR16k; i++ ) - { - L_tmp = L_mac( L_tmp, pitch_buf_fx[i], 6554 ); /* pitch_buf in Q6 x 0.2 in Q15 */ - } - pitch_fx = round_fx( L_tmp ); /* Q6 */ - } - - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - IF( ( ( GE_32( st->extl_brate, SWB_TBE_2k8 ) && EQ_16( st->prev_coder_type, st->coder_type ) && NE_16( st->coder_type, UNVOICED ) ) || ( LT_32( st->extl_brate, SWB_TBE_2k8 ) && ( EQ_16( st->prev_coder_type, st->coder_type ) || ( EQ_16( st->prev_coder_type, VOICED ) && EQ_16( st->coder_type, GENERIC ) ) || ( EQ_16( st->prev_coder_type, GENERIC ) && EQ_16( st->coder_type, VOICED ) ) ) ) ) && GT_16( pitch_fx, 4480 /*70 in Q6*/ ) && LT_16( st->extl, FB_TBE ) && NE_32( st->extl_brate, SWB_TBE_1k10 ) && NE_32( st->extl_brate, SWB_TBE_1k75 ) ) - { - FOR( i = 0; i < NUM_SHB_SUBGAINS; i++ ) - { - GainShape_tmp_fx[i] = GainShape_fx[i * 4]; /* Q15 */ - move16(); - } - - FOR( i = 0; i < NUM_SHB_SUBGAINS; i++ ) - { - L_tmp1 = Mult_32_16( ener_tmp_fx[i], GainShape_tmp_fx[i] ); /* (2*Q_bwe_exc) */ - L_tmp2 = Mult_32_16( hBWE_TD->prev_ener_fx, hBWE_TD->prev_GainShape_fx ); /* (2*st->prev_ener_fx_Q) */ - tmp = sub( shl( Q_bwe_exc, 1 ), shl( st->prev_ener_fx_Q, 1 ) ); -#ifdef BASOP_NOGLOB - L_tmp2 = L_shl_sat( L_tmp2, tmp ); /* new Q = (2*Q_bwe_exc) */ -#else - L_tmp2 = L_shl( L_tmp2, tmp ); /* new Q = (2*Q_bwe_exc) */ -#endif - IF( GT_32( L_tmp1, L_tmp2 ) ) - { - L_tmp = L_tmp2; - move32(); - if ( L_tmp2 < 0 ) - { - L_tmp = L_negate( L_tmp2 ); - } - - expb = norm_l( L_tmp ); -#ifdef BASOP_NOGLOB - fracb = round_fx_sat( L_shl_sat( L_tmp, expb ) ); -#else - fracb = round_fx( L_shl( L_tmp, expb ) ); -#endif - expb = sub( 30, expb ); /* - (2*Q_bwe_exc_ext); */ - - expa = norm_l( ener_tmp_fx[i] ); - fraca = extract_h( L_shl( ener_tmp_fx[i], expa ) ); - expa = sub( 30, expa ); - - scale_fx = shr( sub( fraca, fracb ), 15 ); - fracb = shl( fracb, scale_fx ); - expb = sub( expb, scale_fx ); - - tmp = div_s( fracb, fraca ); - exp = sub( sub( expb, expa ), 1 ); - tmp = shl( tmp, exp ); - GainShape_tmp_fx[i] = add( tmp, shr( GainShape_tmp_fx[i], 1 ) ); /* Q15 */ - move16(); - } - - hBWE_TD->prev_ener_fx = ener_tmp_fx[i]; - move32(); - hBWE_TD->prev_GainShape_fx = GainShape_tmp_fx[i]; - move16(); - st->prev_ener_fx_Q = Q_bwe_exc; - move16(); - } - - FOR( i = 0; i < NUM_SHB_SUBFR; i++ ) - { - Word16 idx = 0; - move16(); - IF( i != 0 ) - { - idx = idiv1616( i_mult( i, NUM_SHB_SUBGAINS ), NUM_SHB_SUBFR ); - } - GainShape_fx[i] = GainShape_tmp_fx[idx]; - move16(); - } - } - ELSE - { - st->prev_ener_fx_Q = Q_bwe_exc; - move16(); - } - st->prev_Q_bwe_syn = Q_bwe_exc; - move16(); - - - /* Gain shape smoothing after quantization */ - test(); - IF( EQ_32( st->extl_brate, SWB_TBE_1k10 ) || EQ_32( st->extl_brate, SWB_TBE_1k75 ) ) - { - FOR( i = 0; i < NUM_SHB_SUBGAINS; i++ ) - { - GainShape_tmp_fx[i] = GainShape_fx[i * NUM_SHB_SUBGAINS]; - move16(); - } - - lls_interp_n_fx( GainShape_tmp_fx, NUM_SHB_SUBGAINS, &GainShape_tilt_fx, &temp_fx, 1 ); - - test(); - IF( GE_16( vind, 6 ) && LT_16( abs_s( GainShape_tilt_fx ), 3932 ) ) - { - feedback_fx = 9830; - move16(); - FOR( i = 0; i < NUM_SHB_SUBGAINS; i++ ) - { - GainShape_fx[i] = add_sat( mult( sub( 32767, feedback_fx ), GainShape_fx[i * NUM_SHB_SUBGAINS] ), mult( feedback_fx, GainShape_tmp_fx[i] ) ); - move16(); - } - - FOR( i = NUM_SHB_SUBFR - 1; i > 0; i-- ) - { - Word16 idx = 0; - move16(); - IF( i != 0 ) - { - idx = idiv1616( i_mult( i, NUM_SHB_SUBGAINS ), NUM_SHB_SUBFR ); - } - GainShape_fx[i] = GainShape_fx[idx]; - move16(); - } - } - } - - /* fil-in missing memory */ - test(); - test(); - IF( ( EQ_16( st->element_mode, IVAS_CPE_TD ) || EQ_16( st->element_mode, IVAS_CPE_DFT ) ) && LE_32( st->last_core_brate, SID_2k40 ) ) - { - FOR( i = 0; i < L_SHB_LAHEAD; i++ ) - { - Word16 intermediate = mult( shaped_shb_excitation_fx[i], subwin_shb_fx[L_SHB_LAHEAD - i] ); - Word32 intermediate_32 = Mpy_32_16_1( Mpy_32_16_1( GainFrame_fx, window_shb_fx[L_SHB_LAHEAD - 1 - i] ), intermediate ); - hBWE_TD->syn_overlap_fx[i] = round_fx( L_shl_sat( intermediate_32, sub( 16, ( add( Q_bwe_exc, 18 - 15 ) ) ) ) ); - move16(); - } - } - - Word16 n_mem3_new = 0; - move16(); - find_max_mem_dec_m3( st, &n_mem3_new ); - - ScaleShapedSHB_fx( SHB_OVERLAP_LEN, - shaped_shb_excitation_fx, /* i/o: Q_bwe_exc */ - hBWE_TD->syn_overlap_fx, - GainShape_fx, /* Q15 */ - GainFrame_fx, /* Q18 */ - window_shb_fx, - subwin_shb_fx, - &Q_bwe_exc, &Qx, n_mem3_new, st->prev_Q_bwe_syn2 ); - - IF( hStereoICBWE != NULL ) - { - Copy_Scale_sig_16_32( lpc_shb_fx, hStereoICBWE->lpSHBRef_fx, LPC_SHB_ORDER + 1, 0 ); - Copy( GainShape_fx, hStereoICBWE->gshapeRef_fx, NUM_SHB_SUBFR ); - hStereoICBWE->gFrameRef_fx = GainFrame_fx; - move32(); - - Copy( shaped_shb_excitation_fx, hStereoICBWE->shbSynthRef_fx, L_FRAME16k ); - } - - max_val = 0; - move16(); - FOR( i = 0; i < L_FRAME16k; i++ ) - { - max_val = s_max( max_val, abs_s( shaped_shb_excitation_fx[i] ) ); /* Q0 */ - } - IF( max_val == 0 ) - { - curr_frame_pow_fx = 0; - move32(); - n = 0; - move16(); - } - ELSE - { - n = norm_s( max_val ); - max_val = 0; - move16(); - FOR( i = 0; i < L_FRAME16k; i++ ) - { -#ifdef BASOP_NOGLOB - shaped_shb_excitation_frac[i] = shl_sat( shaped_shb_excitation_fx[i], n ); /*Q_bwe_exc+n*/ - move16(); -#else - shaped_shb_excitation_frac[i] = shl( shaped_shb_excitation_fx[i], n ); /*Q_bwe_exc+n*/ - move16(); -#endif - } - - curr_frame_pow_fx = 0; - move32(); - FOR( i = 0; i < L_FRAME16k; i++ ) - { - L_tmp = L_mult0( shaped_shb_excitation_frac[i], shaped_shb_excitation_frac[i] ); /*2*(Q_bwe_exc+n)*/ - curr_frame_pow_fx = L_add( curr_frame_pow_fx, L_shr( L_tmp, 9 ) ); /*2*(Q_bwe_exc+n)-9*/ - } - } - curr_frame_pow_exp = sub( shl( add( Q_bwe_exc, n ), 1 ), 9 ); - tmp = sub( st->prev_frame_pow_exp, curr_frame_pow_exp ); - IF( tmp > 0 ) /* shifting prev */ - { - IF( GT_16( tmp, 32 ) ) - { - st->prev_frame_pow_exp = add( curr_frame_pow_exp, 32 ); - move16(); - tmp = 32; - move16(); - } - hBWE_TD->prev_swb_bwe_frame_pow_fx = L_shr( hBWE_TD->prev_swb_bwe_frame_pow_fx, tmp ); - move32(); - st->prev_frame_pow_exp = curr_frame_pow_exp; - move16(); - } - ELSE /* shifting curr */ - { - IF( LT_16( tmp, -32 ) ) - { - curr_frame_pow_exp = sub( st->prev_frame_pow_exp, 32 ); - tmp = -32; - move16(); - } - curr_frame_pow_fx = L_shr( curr_frame_pow_fx, -tmp ); - curr_frame_pow_exp = st->prev_frame_pow_exp; - move16(); - } - test(); - test(); - IF( !st->bfi && ( st->prev_bfi || st->prev_use_partial_copy ) ) - { - test(); - test(); - IF( ( GT_32( L_shr( curr_frame_pow_fx, 1 ), hBWE_TD->prev_swb_bwe_frame_pow_fx ) ) && - ( GT_32( hBWE_TD->prev_swb_bwe_frame_pow_fx, L_tmp ) ) && EQ_16( st->prev_coder_type, UNVOICED ) ) - { - L_tmp = root_a_over_b_fx( hBWE_TD->prev_swb_bwe_frame_pow_fx, curr_frame_pow_exp, curr_frame_pow_fx, curr_frame_pow_exp, &exp ); - scale_fx = round_fx( L_shl( L_tmp, exp ) ); /*Q15*/ - - L_tmp = root_a_fx( L_tmp, sub( 31, exp ), &exp ); - L_tmp = root_a_fx( L_tmp, sub( 31, exp ), &exp ); - L_tmp = root_a_fx( L_tmp, sub( 31, exp ), &exp ); - temp_fx = round_fx( L_shl( L_tmp, exp ) ); /*Q15*/ - } - ELSE - { - scale_fx = temp_fx = 32767; - move16(); /*Q15*/ - move16(); /*Q15*/ - } - - FOR( j = 0; j < 8; j++ ) - { - GainShape_fx[2 * j] = mult_r( GainShape_fx[2 * j], scale_fx ); - move16(); - GainShape_fx[2 * j + 1] = mult_r( GainShape_fx[2 * j + 1], scale_fx ); - move16(); - FOR( i = 0; i < L_FRAME16k / 8; i++ ) - { - shaped_shb_excitation_fx[add( i, j * ( L_FRAME16k / 8 ) )] = mult_r( shaped_shb_excitation_fx[add( i, j * ( L_FRAME16k / 8 ) )], scale_fx ); - move16(); - } - - IF( temp_fx > 0 ) - { - /* scale_fx <= temp_fx, due to scale_fx = sqrt( st->prev_swb_bwe_frame_pow_fx/curr_frame_pow_fx ), temp_fx = sqrt( scale_fx, 1.f/8.f ) - and curr_frame_pow_fx > st->prev_swb_bwe_frame_pow_fx -> scale_fx <= 1.0, sqrt(scale_fx, 1.f/8.f) >= scale_fx */ - IF( LT_16( scale_fx, temp_fx ) ) - { - scale_fx = div_s( scale_fx, temp_fx ); - } - ELSE - { - scale_fx = 32767; - move16(); - } - } - ELSE - { - scale_fx = 0; - move16(); - } - } - } - - /* adjust the FEC frame energy */ - IF( st->bfi ) - { - scale_fx = temp_fx = 4096; - move16(); /*Q12*/ - move16(); - IF( EQ_16( st->nbLostCmpt, 1 ) ) - { - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - IF( GT_32( curr_frame_pow_fx, hBWE_TD->prev_swb_bwe_frame_pow_fx ) && - NE_16( st->prev_coder_type, UNVOICED ) && - ( st->last_good != UNVOICED_CLAS ) ) - { - L_tmp = root_a_over_b_fx( hBWE_TD->prev_swb_bwe_frame_pow_fx, curr_frame_pow_exp, curr_frame_pow_fx, curr_frame_pow_exp, &exp ); /*31 - exp*/ - scale_fx = round_fx( L_shl( L_tmp, sub( exp, 3 ) ) ); /*Q12*/ - L_tmp = root_a_fx( L_tmp, sub( 31, exp ), &exp ); - L_tmp = root_a_fx( L_tmp, sub( 31, exp ), &exp ); - L_tmp = root_a_fx( L_tmp, sub( 31, exp ), &exp ); - temp_fx = round_fx( L_shl( L_tmp, sub( exp, 3 ) ) ); /*Q12*/ - } - ELSE IF( LT_32( curr_frame_pow_fx, L_shr( hBWE_TD->prev_swb_bwe_frame_pow_fx, 1 ) ) && EQ_16( st->nbLostCmpt, 1 ) && - ( GT_32( st->enerLL_fx, L_shr( st->prev_enerLL_fx, 1 ) ) || GT_32( st->enerLH_fx, L_shr( st->prev_enerLH_fx, 1 ) ) ) && - ( EQ_16( st->prev_coder_type, UNVOICED ) || ( st->last_good == UNVOICED_CLAS ) || GT_16( hBWE_TD->tilt_swb_fec_fx, 10240 ) ) ) - { - L_tmp = root_a_over_b_fx( hBWE_TD->prev_swb_bwe_frame_pow_fx, curr_frame_pow_exp, curr_frame_pow_fx, curr_frame_pow_exp, &exp ); -#ifdef BASOP_NOGLOB - scale_fx = round_fx_sat( L_shl_sat( L_tmp, sub( exp, 3 ) ) ); /*Q12*/ -#else - scale_fx = round_fx( L_shl( L_tmp, sub( exp, 3 ) ) ); /*Q12*/ -#endif - L_tmp = root_a_fx( L_tmp, sub( 31, exp ), &exp ); - L_tmp = root_a_fx( L_tmp, sub( 31, exp ), &exp ); - L_tmp = root_a_fx( L_tmp, sub( 31, exp ), &exp ); - temp_fx = round_fx( L_shl( L_tmp, sub( exp, 3 ) ) ); /*Q12*/ - } - } - ELSE IF( GT_16( st->nbLostCmpt, 1 ) ) - { - test(); - test(); - test(); - test(); - test(); - IF( GT_32( curr_frame_pow_fx, hBWE_TD->prev_swb_bwe_frame_pow_fx ) ) - { - L_tmp = root_a_over_b_fx( hBWE_TD->prev_swb_bwe_frame_pow_fx, curr_frame_pow_exp, curr_frame_pow_fx, curr_frame_pow_exp, &exp ); - scale_fx = round_fx( L_shl( L_tmp, sub( exp, 3 ) ) ); /*Q12*/ - L_tmp = root_a_fx( L_tmp, sub( 31, exp ), &exp ); - L_tmp = root_a_fx( L_tmp, sub( 31, exp ), &exp ); - L_tmp = root_a_fx( L_tmp, sub( 31, exp ), &exp ); -#ifdef BASOP_NOGLOB - temp_fx = round_fx_sat( L_shl_sat( L_tmp, sub( exp, 3 ) ) ); /*Q12*/ -#else - temp_fx = round_fx( L_shl( L_tmp, sub( exp, 3 ) ) ); /*Q12*/ -#endif - } - ELSE IF( LT_32( curr_frame_pow_fx, L_shr( hBWE_TD->prev_swb_bwe_frame_pow_fx, 1 ) ) && - ( GT_32( st->enerLL_fx, L_shr( st->prev_enerLL_fx, 1 ) ) || GT_32( st->enerLH_fx, L_shr( st->prev_enerLH_fx, 1 ) ) ) && - ( EQ_16( st->prev_coder_type, UNVOICED ) || ( st->last_good == UNVOICED_CLAS ) || GT_16( hBWE_TD->tilt_swb_fec_fx, 10240 ) ) ) - { - L_tmp = root_a_over_b_fx( hBWE_TD->prev_swb_bwe_frame_pow_fx, curr_frame_pow_exp, curr_frame_pow_fx, curr_frame_pow_exp, &exp ); -#ifdef BASOP_NOGLOB - L_tmp = L_min( L_tmp, L_shl_sat( 2, sub( 31, exp ) ) ); /*31 - exp*/ -#else - L_tmp = L_min( L_tmp, L_shl( 2, ( 31 - exp ) ) ); /*31 - exp*/ -#endif - scale_fx = round_fx( L_shl( L_tmp, sub( exp, 3 ) ) ); /*Q12*/ - L_tmp = root_a_fx( L_tmp, sub( 31, exp ), &exp ); - L_tmp = root_a_fx( L_tmp, sub( 31, exp ), &exp ); - L_tmp = root_a_fx( L_tmp, sub( 31, exp ), &exp ); - temp_fx = round_fx( L_shl( L_tmp, sub( exp, 3 ) ) ); /*Q12*/ - } - } - - FOR( j = 0; j < 8; j++ ) - { -#ifdef BASOP_NOGLOB - GainShape_fx[2 * j] = shl_sat( mult_r( GainShape_fx[2 * j], scale_fx ), 3 ); -#else - GainShape_fx[2 * j] = shl( mult_r( GainShape_fx[2 * j], scale_fx ), 3 ); -#endif - move16(); /* 15 +12 +3-15 =15*/ -#ifdef BASOP_NOGLOB - GainShape_fx[add( 2 * j, 1 )] = shl_sat( mult_r( GainShape_fx[add( 2 * j, 1 )], scale_fx ), 3 ); -#else - GainShape_fx[2 * j + 1] = shl( mult_r( GainShape_fx[2 * j + 1], scale_fx ), 3 ); -#endif - move16(); - FOR( i = 0; i < 40; i++ ) - { - shaped_shb_excitation_fx[i + j * L_FRAME16k / 8] = shl( mult_r( shaped_shb_excitation_fx[i + j * L_FRAME16k / 8], scale_fx ), 3 ); - move16(); /* Q_bwe_exc +12+3 -15 =Q_bwe_exc*/ - } - - IF( temp_fx > 0 ) - { - IF( LT_16( scale_fx, temp_fx ) ) - { - scale_fx = shr( div_s( scale_fx, temp_fx ), 3 ); - } - ELSE - { - tmp1 = sub( norm_s( scale_fx ), 1 ); - tmp2 = norm_s( temp_fx ); - scale_fx = div_s( shl( scale_fx, tmp1 ), shl( temp_fx, tmp2 ) ); - scale_fx = shr( scale_fx, add( sub( tmp1, tmp2 ), 3 ) ); - } - } - ELSE - { - scale_fx = 0; - move16(); - } - } - } - - hBWE_TD->prev_swb_bwe_frame_pow_fx = curr_frame_pow_fx; - move32(); - st->prev_frame_pow_exp = curr_frame_pow_exp; - move16(); - - Word64 prev_ener_shb64 = 0; - move64(); - FOR( i = 0; i < L_FRAME16k; i++ ) - { - prev_ener_shb64 = W_mac0_16_16( prev_ener_shb64, shaped_shb_excitation_fx[i], shaped_shb_excitation_fx[i] ); /* Q0 */ - } - L_prev_ener_shb = W_sat_l( prev_ener_shb64 ); - - L_prev_ener_shb = Mult_32_16( L_prev_ener_shb, 26214 ); /* 2*Q_bwe_exc_mod+8; 26214=(1/L_FRAME16k) in Q23 */ - st->prev_ener_shb_fx = 0; - move16(); - IF( L_prev_ener_shb != 0 ) - { - exp = norm_l( L_prev_ener_shb ); - tmp = extract_h( L_shl( L_prev_ener_shb, exp ) ); - exp = sub( exp, sub( 30, ( add( i_mult( 2, Q_bwe_exc ), 8 ) ) ) ); - - tmp = div_s( 16384, tmp ); - L_tmp = L_deposit_h( tmp ); - L_tmp = Isqrt_lc( L_tmp, &exp ); -#ifdef BASOP_NOGLOB /* Saturation fix taken from EVS*/ - st->prev_ener_shb_fx = round_fx_sat( L_shl_sat( L_tmp, sub( exp, 14 ) ) ); /* Q1 */ -#else - st->prev_ener_shb_fx = round_fx( L_shl( L_tmp, sub( exp, 14 ) ) ); /* Q1 */ -#endif - move16(); - } - - IF( st->hBWE_FD != NULL ) - { - L_tmp = Mult_32_16( curr_frame_pow_fx, 26214 ); /* curr_frame_pow_exp+8; 26214=(1/L_FRAME16k) in Q23 */ - tmp = 0; - move16(); - IF( L_tmp != 0 ) - { - exp = norm_l( L_tmp ); - tmp = extract_h( L_shl( L_tmp, exp ) ); - exp = sub( exp, sub( 30, add( curr_frame_pow_exp, 8 ) ) ); - - tmp = div_s( 16384, tmp ); - L_tmp = L_deposit_h( tmp ); - L_tmp = Isqrt_lc( L_tmp, &exp ); -#ifdef BASOP_NOGLOB /* Saturation fix taken from EVS*/ - tmp = round_fx_sat( L_shl_sat( L_tmp, sub( exp, 14 ) ) ); /* Q1 */ -#else - tmp = round_fx( L_shl( L_tmp, sub( exp, 14 ) ) ); /* Q1 */ -#endif - } - set16_fx( st->prev_SWB_fenv_fx, tmp, SWB_FENV ); /* Q1 */ - } - - FOR( i = 0; i < L_FRAME16k; i++ ) - { - shaped_shb_excitation_fx_32[i] = L_shl( shaped_shb_excitation_fx[i], sub( Q11, Q_bwe_exc ) ); - move32(); - } - - /* generate 32kHz SHB synthesis from 12.8(16)kHz signal */ - GenSHBSynth_fx_32( shaped_shb_excitation_fx_32, error_fx, hBWE_TD->genSHBsynth_Hilbert_Mem_fx, hBWE_TD->genSHBsynth_state_lsyn_filt_shb_local_fx_32, st->L_frame, &( hBWE_TD->syn_dm_phase ) ); - Copy_Scale_sig_32_16( st->hBWE_TD->genSHBsynth_state_lsyn_filt_shb_local_fx_32, st->hBWE_TD->genSHBsynth_state_lsyn_filt_shb_local_fx, 2 * ALLPASSSECTIONS_STEEP, -( Q11 - Q_bwe_exc ) ); - Copy32( error_fx + L_FRAME32k - L_SHB_TRANSITION_LENGTH, hBWE_TD->old_tbe_synth_fx_32, L_SHB_TRANSITION_LENGTH ); - - /* resample SHB synthesis (if needed) and scale down */ - synth_scale_fx = 32767; - move16(); /* 1.0 in Q15 */ - if ( EQ_16( st->codec_mode, MODE1 ) ) - { - synth_scale_fx = 29491; - move16(); /* 0.9 in Q15 */ - } - - IF( EQ_32( st->output_Fs, 48000 ) ) - { - IF( EQ_16( st->extl, FB_TBE ) ) - { - tmp = norm_l( GainFrame_fx ); - if ( GainFrame_fx == 0 ) - { - tmp = 31; - move16(); - } - L_tmp = L_shl( GainFrame_fx, tmp ); /* 18 + tmp */ - - tmp1 = 0; - move16(); - FOR( i = 0; i < L_FRAME16k; i++ ) - { - Word16 idx = 0; - move16(); - IF( i != 0 ) - { - idx = idiv1616( i_mult( NUM_SHB_SUBFR, i ), L_FRAME16k ); - } - L_tmp1 = Mult_32_16( L_tmp, GainShape_fx[idx] ); /* Q : 18 + tmp +15 -15*/ - White_exc16k_fx[i] = round_fx( Mult_32_16( L_tmp1, White_exc16k_fx[i] ) ); /* 18 + tmp +*Q_white_exc -15 -16 */ - move16(); - tmp1 = s_max( tmp1, abs_s( White_exc16k_fx[i] ) ); - } - - *Q_white_exc = sub( add( *Q_white_exc, tmp ), 13 ); /* *Q_white_exc + 18 + tmp -15 -16 */ - move16(); - tmp = norm_s( tmp1 ); - if ( tmp1 == 0 ) - { - tmp = 15; - move16(); - } - - FOR( i = 0; i < L_FRAME16k; i++ ) - { - White_exc16k_fx[i] = shl( White_exc16k_fx[i], sub( tmp, 1 ) ); - move16(); - } - *Q_white_exc = sub( add( *Q_white_exc, tmp ), 1 ); - move16(); - } - - IF( NE_16( synth_scale_fx, 32767 ) ) /* 1.0 in Q15 */ - { - FOR( i = 0; i < L_FRAME32k; i++ ) - { - error_fx[i] = Mpy_32_16_1( error_fx[i], synth_scale_fx ); - move32(); - } - } - interpolate_3_over_2_allpass_32( error_fx, L_FRAME32k, synth_fx, hBWE_TD->int_3_over_2_tbemem_dec_fx_32 ); - } - ELSE IF( EQ_32( st->output_Fs, 32000 ) ) - { - IF( NE_16( synth_scale_fx, 32767 ) ) /* 1.0 in Q15 */ - { - FOR( i = 0; i < L_FRAME32k; i++ ) - { - synth_fx[i] = Mpy_32_16_1( error_fx[i], synth_scale_fx ); - move32(); /*Qx*/ - } - } - ELSE - { - Copy32( error_fx, synth_fx, L_FRAME32k ); - } - } - ELSE IF( EQ_32( st->output_Fs, 16000 ) ) - { - IF( NE_16( synth_scale_fx, 32767 ) ) /* 1.0 in Q15 */ - { - FOR( i = 0; i < L_FRAME32k; i++ ) - { - error_fx[i] = Mpy_32_16_1( error_fx[i], synth_scale_fx ); - move32(); - } - } - - Decimate_allpass_steep_fx32( error_fx, hBWE_TD->mem_resamp_HB_32k_fx_32, L_FRAME32k, synth_fx ); - } - - - /* Update previous frame parameters for FEC */ - Copy( lsf_shb_fx, hBWE_TD->lsp_prevfrm_fx, LPC_SHB_ORDER ); - IF( EQ_16( st->codec_mode, MODE1 ) ) - { - hBWE_TD->GainFrame_prevfrm_fx = GainFrame_fx; - move32(); /*Q18*/ - hBWE_TD->tilt_swb_fec_fx = tilt_swb_fec_fx; - move16(); - - if ( !st->bfi ) - { - hBWE_TD->GainAttn_fx = 32767; /*1.0f in Q15*/ - move16(); - } - } - ELSE - { - IF( !st->bfi ) - { - hBWE_TD->GainFrame_prevfrm_fx = GainFrame_fx; - move32(); /*Q18*/ - hBWE_TD->tilt_swb_fec_fx = tilt_swb_fec_fx; - move16(); - hBWE_TD->GainAttn_fx = 32767; /*1.0f in Q15*/ - move16(); - } - } - - hBWE_TD->prev_ener_fx = ener_tmp_fx[NUM_SHB_SUBGAINS - 1]; - move32(); - hBWE_TD->prev_GainShape_fx = GainShape_fx[NUM_SHB_SUBFR - 1]; - move16(); - st->prev_Q_bwe_syn2 = Q_bwe_exc; - move16(); - st->prev_Qx = Q_bwe_exc; - move16(); - - return; -} -/*-------------------------------------------------------------------* - * Dequant_lower_LSF() - * - * Dequantized the lower LSFs - *-------------------------------------------------------------------*/ - - -/*-------------------------------------------------------------------* - * Map_higher_LSF() - * - * Map the higher LSFs from the lower LSFs - *-------------------------------------------------------------------*/ - - -/*-------------------------------------------------------------------* - * Map_higher_LSF() - * - * Map the higher LSFs from the lower LSFs - *-------------------------------------------------------------------*/ - - -/*-------------------------------------------------------------------* - * dequantizeSHBparams() - * - * Dequantize super highband spectral envolope, temporal gains and frame gain - *-------------------------------------------------------------------*/ - - -void GenTransition_fixed( - TD_BWE_DEC_HANDLE hBWE_TD, /* i/o: TD BWE data handle */ - Word32 *outputHB_fx, /* o : synthesized HB transitions signal : Q11 */ - const Word32 output_Fs, /* i : output sampling rate : Q0 */ - const Word16 element_mode, /* i : element mode : Q0 */ - const Word16 L_frame, /* i : ACELP frame length : Q0 */ - const Word16 rf_flag, /* i : RF flag : Q0 */ - const Word32 total_brate, /* i : total bitrate : Q0 */ - const Word16 prev_Qx ) -{ - Word16 i, length; - - Word32 syn_overlap_32k_fx[2 * SHB_OVERLAP_LEN]; - - /* set targeted length of transition signal */ - length = i_mult( 2, NS2SA_FX2( output_Fs, DELAY_BWE_TOTAL_NS ) ); - - /* upsample overlap snippet */ - Interpolate_allpass_steep_32( hBWE_TD->syn_overlap_fx_32, hBWE_TD->genSHBsynth_state_lsyn_filt_shb_local_fx_32, SHB_OVERLAP_LEN, syn_overlap_32k_fx ); - - /* perFORm spectral flip and downmix with overlap snippet to match HB synth */ - test(); - test(); - test(); - test(); - IF( ( ( element_mode == EVS_MONO ) && ( rf_flag || EQ_32( total_brate, ACELP_9k60 ) ) ) || ( ( element_mode > EVS_MONO ) && EQ_16( L_frame, L_FRAME ) ) ) - { - flip_and_downmix_generic_fx_32( syn_overlap_32k_fx, syn_overlap_32k_fx, 2 * SHB_OVERLAP_LEN, hBWE_TD->genSHBsynth_Hilbert_Mem_fx, hBWE_TD->genSHBsynth_Hilbert_Mem_fx + HILBERT_ORDER1, hBWE_TD->genSHBsynth_Hilbert_Mem_fx + ( HILBERT_ORDER1 + 2 * HILBERT_ORDER2 ), &( hBWE_TD->syn_dm_phase ) ); - } - ELSE - { - FOR( i = 0; i < 2 * SHB_OVERLAP_LEN; i++ ) - { - IF( i % 2 == 0 ) - { - syn_overlap_32k_fx[i] = L_negate( syn_overlap_32k_fx[i] ); - } - ELSE - { - syn_overlap_32k_fx[i] = syn_overlap_32k_fx[i]; - } - move32(); - } - } - - /* cross fade of overlap snippet and mirrored HB synth from previous frame */ - FOR( i = 0; i < 2 * L_SHB_LAHEAD; i++ ) - { - outputHB_fx[i] = L_add_sat( Mpy_32_16_1( hBWE_TD->old_tbe_synth_fx_32[L_SHB_TRANSITION_LENGTH - 1 - i], window_shb_32k_fx[i] ), Mpy_32_16_1( syn_overlap_32k_fx[i], window_shb_32k_fx[2 * L_SHB_LAHEAD - 1 - i] ) ); - move32(); - } - - /* fill transition signal with mirrored HB synth from previous frame to fully fill delay alignment buffer gap */ - FOR( ; i < length; i++ ) - { - outputHB_fx[i] = L_shl( hBWE_TD->old_tbe_synth_fx[L_SHB_TRANSITION_LENGTH - 1 - i], sub( Q11, prev_Qx ) ); - move32(); - } - - IF( EQ_32( output_Fs, 48000 ) ) - { - interpolate_3_over_2_allpass_32( outputHB_fx, length, outputHB_fx, hBWE_TD->int_3_over_2_tbemem_dec_fx_32 ); - } - ELSE IF( EQ_32( output_Fs, 16000 ) ) - { - Decimate_allpass_steep_fx32( outputHB_fx, hBWE_TD->mem_resamp_HB_32k_fx_32, L_FRAME32k, outputHB_fx ); - } - - return; -} -void GenTransition_WB_fixed( - TD_BWE_DEC_HANDLE hBWE_TD, /* i/o: TD BWE data handle */ - Word32 *outputHB_fx, /* o : synthesized HB transitions signal : Q11 */ - const Word32 output_Fs /* i : output sampling rate */ -) -{ - Word16 i, length; - Word32 speech_buf_16k1_fx[SHB_OVERLAP_LEN], speech_buf_16k2_fx[2 * SHB_OVERLAP_LEN]; - Word32 upsampled_synth_fx[L_FRAME48k]; - - /* set targeted length of transition signal */ - length = i_mult( 2, NS2SA_FX2( output_Fs, DELAY_BWE_TOTAL_NS ) ); - - /* upsample overlap snippet */ - Interpolate_allpass_steep_32( hBWE_TD->syn_overlap_fx_32, hBWE_TD->state_lsyn_filt_shb_fx_32, SHB_OVERLAP_LEN / 2, speech_buf_16k1_fx ); - Interpolate_allpass_steep_32( speech_buf_16k1_fx, hBWE_TD->state_lsyn_filt_dwn_shb_fx_32, SHB_OVERLAP_LEN, speech_buf_16k2_fx ); - - /* perform spectral flip and downmix with overlap snippet to match HB synth */ - FOR( i = 0; i < SHB_OVERLAP_LEN; i++ ) - { - IF( i % 2 == 0 ) - { - speech_buf_16k2_fx[i] = L_negate( speech_buf_16k2_fx[i] ); - move32(); - } - ELSE - { - speech_buf_16k2_fx[i] = speech_buf_16k2_fx[i]; - move32(); - } - } - - /* cross fade of overlap snippet and mirrored HB synth from previous frame */ - FOR( i = 0; i < L_SHB_LAHEAD; i++ ) - { - outputHB_fx[i] = L_add( Mpy_32_16_1( hBWE_TD->old_tbe_synth_fx_32[L_SHB_TRANSITION_LENGTH - 1 - i], window_shb_fx[i] ), Mpy_32_16_1( speech_buf_16k2_fx[i], window_shb_fx[L_SHB_LAHEAD - 1 - i] ) ); - move32(); - outputHB_fx[i] = Mpy_32_16_1( outputHB_fx[i], 21299 ); - move32(); - } - - /* fill transition signal with mirrored HB synth from previous frame to fully fill delay alignment buffer gap */ - FOR( ; i < length; i++ ) - { - outputHB_fx[i] = hBWE_TD->old_tbe_synth_fx_32[L_SHB_TRANSITION_LENGTH - 1 - i]; - move32(); - outputHB_fx[i] = Mpy_32_16_1( outputHB_fx[i], 21299 ); - move32(); - } - - /* upsampling if necessary */ - IF( EQ_32( output_Fs, 32000 ) ) - { - Interpolate_allpass_steep_32( outputHB_fx, hBWE_TD->mem_resamp_HB_fx_32, L_FRAME16k, upsampled_synth_fx ); - Copy32( upsampled_synth_fx, outputHB_fx, L_FRAME32k ); - } - ELSE IF( EQ_32( output_Fs, 48000 ) ) - { - interpolate_3_over_1_allpass_32( outputHB_fx, L_FRAME16k, upsampled_synth_fx, hBWE_TD->mem_resamp_HB_fx_32 ); - Copy32( upsampled_synth_fx, outputHB_fx, L_FRAME48k ); - } - - return; -} - -/*-------------------------------------------------------------------* - * td_bwe_dec_init() - * - * Initialize TD BWE state structure at the decoder - *-------------------------------------------------------------------*/ diff --git a/lib_dec/swb_tbe_dec_fx.c b/lib_dec/swb_tbe_dec_fx.c index 54a8127c97ff8ac7c5152e7c96dfcff8a9d16136..cc9b681fba0ff907e5ca3a4cd863242a66e6bba6 100644 --- a/lib_dec/swb_tbe_dec_fx.c +++ b/lib_dec/swb_tbe_dec_fx.c @@ -31,6 +31,11 @@ Word16 dotp_loc( const Word16 n /* i : vector length */ ); +void find_max_mem_dec_m3( + Decoder_State *st, + Word16 *n_mem3 ); + + /* gain shape concealment code */ static void gradientGainShape( Decoder_State *st_fx, Word16 *GainShape, Word32 *GainFrame ); @@ -906,11 +911,7 @@ void ivas_wb_tbe_dec_fx( IF( st_fx->element_mode > EVS_MONO ) { tmp = sub( shl( sub( st_fx->prev_Q_bwe_exc, 16 ), 1 ), 31 + 16 ); -#ifdef BASOP_NOGLOB prev_pow = L_shl_sat( 1407374848l /*0.00001f Q47*/, tmp ); /*Q(2*(st_fx->prev_Q_bwe_exc-16))*/ -#else - prev_pow = L_shl( 1407374848l /*0.00001f Q47*/, tmp ); /*Q(2*(st_fx->prev_Q_bwe_exc-16))*/ -#endif } FOR( i = 0; i < L_SHB_LAHEAD / 4; i++ ) { @@ -930,7 +931,7 @@ void ivas_wb_tbe_dec_fx( Q_bwe_exc_ext = sub( Q_bwe_exc, 16 ); - ivas_GenShapedWBExcitation_fx( shaped_wb_excitation + L_SHB_LAHEAD / 4, lpc_wb, exc4kWhtnd, hBWE_TD->mem_csfilt_fx, + GenShapedWBExcitation_ivas_fx( shaped_wb_excitation + L_SHB_LAHEAD / 4, lpc_wb, exc4kWhtnd, hBWE_TD->mem_csfilt_fx, hBWE_TD->mem_genSHBexc_filt_down_shb_fx, hBWE_TD->mem_genSHBexc_filt_down_wb2_fx, hBWE_TD->mem_genSHBexc_filt_down_wb3_fx, hBWE_TD->state_lpc_syn_fx, coder_type, bwe_exc_extended_16, Q_bwe_exc_ext, hBWE_TD->bwe_seed, vf_modified, uv_flag, st_fx->igf ); @@ -940,19 +941,11 @@ void ivas_wb_tbe_dec_fx( IF( st_fx->element_mode > EVS_MONO ) { tmp = sub( shl( Q_bwe_exc_ext, 1 ), 31 + 16 ); -#ifdef BASOP_NOGLOB curr_pow = L_shl_sat( 1407374848l /*0.00001f Q47*/, tmp ); /*Q(2*(Q_bwe_exc_ext))*/ -#else - curr_pow = L_shl( 1407374848l /*0.00001f Q47*/, tmp ); /* 2*(Q_bwe_exc_ext) */ -#endif } FOR( i = 0; i < L_SHB_LAHEAD / 4; i++ ) { -#ifdef BASOP_NOGLOB curr_pow = L_mac0_sat( curr_pow, shaped_wb_excitation[i + L_SHB_LAHEAD / 4], shaped_wb_excitation[i + L_SHB_LAHEAD / 4] ); /* Q(2*Q_bwe_exc_ext) */ -#else - curr_pow = L_mac0( curr_pow, shaped_wb_excitation[i + L_SHB_LAHEAD / 4], shaped_wb_excitation[i + L_SHB_LAHEAD / 4] ); /* Q(2*Q_bwe_exc_ext) */ -#endif } if ( GT_16( voice_factors[0], 24576 ) ) @@ -965,12 +958,8 @@ void ivas_wb_tbe_dec_fx( FOR( i = 0; i < L_SHB_LAHEAD / 4 - 1; i++ ) { - L_tmp = Mult_32_16( Lscale, shaped_wb_excitation[i] ); /* Q(16-exp+Q_bwe_exc_ext) */ -#ifdef BASOP_NOGLOB + L_tmp = Mult_32_16( Lscale, shaped_wb_excitation[i] ); /* Q(16-exp+Q_bwe_exc_ext) */ shaped_wb_excitation[i] = round_fx_sat( L_shl_sat( L_tmp, exp ) ); /* Q_bwe_exc_ext */ -#else - shaped_wb_excitation[i] = round_fx( L_shl( L_tmp, exp ) ); /* Q_bwe_exc_ext */ -#endif move16(); } Lscale = root_a_fx( Lscale, sub( 31, exp ), &exp ); @@ -1007,26 +996,16 @@ void ivas_wb_tbe_dec_fx( n = norm_s( max ); FOR( i = 0; i < L_FRAME16k / 4; i++ ) { -#ifdef BASOP_NOGLOB shaped_wb_excitation_frac[i] = shl_o( shaped_wb_excitation[i], n, &Overflow ); /*Q14*/ move16(); -#else - shaped_wb_excitation_frac[i] = shl( shaped_wb_excitation[i], n ); /*Q14*/ - move16(); -#endif } n = sub( 14, n ); curr_frame_pow = 1; move32(); FOR( i = 0; i < L_FRAME16k / 4; i++ ) { -#ifdef BASOP_NOGLOB L_tmp = L_mult_o( shaped_wb_excitation_frac[i], shaped_wb_excitation_frac[i], &Overflow ); /*Q29*/ curr_frame_pow = L_add_o( curr_frame_pow, L_shr( L_tmp, 7 ), &Overflow ); /*Q22*/ -#else - L_tmp = L_mult( shaped_wb_excitation_frac[i], shaped_wb_excitation_frac[i] ); /*Q29*/ - curr_frame_pow = L_add( curr_frame_pow, L_shr( L_tmp, 7 ) ); /*Q22*/ -#endif } } curr_frame_pow_exp = add( n, n ); @@ -1216,19 +1195,11 @@ void ivas_wb_tbe_dec_fx( L_tmp = Mult_32_16( Lacc, 102 ); /* Q22 */ exp = norm_l( L_tmp ); -#ifdef BASOP_NOGLOB tmp = round_fx_o( L_shl_o( L_tmp, exp, &Overflow ), &Overflow ); -#else - tmp = round_fx( L_shl( L_tmp, exp ) ); -#endif exp = sub( add( exp, 22 ), 30 ); tmp = div_s( 16384, tmp ); - L_tmp = Isqrt_lc( L_deposit_h( tmp ), &exp ); /* Q(31-exp) */ -#ifdef BASOP_NOGLOB + L_tmp = Isqrt_lc( L_deposit_h( tmp ), &exp ); /* Q(31-exp) */ st_fx->last_wb_bwe_ener_fx = round_fx_sat( L_shl_sat( L_tmp, add( exp, sub( n, 12 ) ) ) ); /* Q3 */ -#else - st_fx->last_wb_bwe_ener_fx = round_fx( L_shl( L_tmp, add( exp, sub( n, 12 ) ) ) ); /* Q3 */ -#endif move16(); } @@ -1256,11 +1227,7 @@ void ivas_wb_tbe_dec_fx( { lsf_wb[i] = f; move16(); /*Q15*/ -#ifdef BASOP_NOGLOB f = add_sat( f, inc ); -#else - f = add( f, inc ); -#endif move16(); } GainFrame = 0; /* Q18 */ @@ -1582,19 +1549,11 @@ void wb_tbe_dec_fx( IF( st_fx->element_mode > EVS_MONO ) { tmp = sub( shl( sub( st_fx->prev_Q_bwe_exc, 16 ), 1 ), 31 + 16 ); -#ifdef BASOP_NOGLOB prev_pow = L_shl_sat( 1407374848l /*0.00001f Q47*/, tmp ); /*Q(2*(st_fx->prev_Q_bwe_exc-16))*/ -#else - prev_pow = L_shl( 1407374848l /*0.00001f Q47*/, tmp ); /*Q(2*(st_fx->prev_Q_bwe_exc-16))*/ -#endif } FOR( i = 0; i < L_SHB_LAHEAD / 4; i++ ) { -#ifdef BASOP_NOGLOB prev_pow = L_mac0_sat( prev_pow, hBWE_TD->state_syn_shbexc_fx[i], hBWE_TD->state_syn_shbexc_fx[i] ); /*Q(2*(st_fx->prev_Q_bwe_exc-16))*/ -#else - prev_pow = L_mac0( prev_pow, hBWE_TD->state_syn_shbexc_fx[i], hBWE_TD->state_syn_shbexc_fx[i] ); /*Q(2*(st_fx->prev_Q_bwe_exc-16))*/ -#endif } rescale_genWB_mem( st_fx, sub( Q_bwe_exc, st_fx->prev_Q_bwe_exc ) ); @@ -1603,11 +1562,7 @@ void wb_tbe_dec_fx( sc = sub( Q_bwe_exc, add( Q_exc, Q_exc ) ); FOR( cnt = 0; cnt < L_FRAME32k; cnt++ ) { -#ifdef BASOP_NOGLOB bwe_exc_extended_16[cnt + NL_BUFF_OFFSET] = round_fx_sat( L_shl_sat( bwe_exc_extended[cnt], sc ) ); -#else - bwe_exc_extended_16[cnt + NL_BUFF_OFFSET] = round_fx( L_shl( bwe_exc_extended[cnt], sc ) ); -#endif } Copy( bwe_exc_extended_16 + L_FRAME32k, hBWE_TD->old_bwe_exc_extended_fx, NL_BUFF_OFFSET ); @@ -1625,19 +1580,11 @@ void wb_tbe_dec_fx( IF( st_fx->element_mode > EVS_MONO ) { tmp = sub( shl( Q_bwe_exc_ext, 1 ), 31 + 16 ); -#ifdef BASOP_NOGLOB curr_pow = L_shl_sat( 1407374848l /*0.00001f Q47*/, tmp ); /*Q(2*(Q_bwe_exc_ext))*/ -#else - curr_pow = L_shl( 1407374848l /*0.00001f Q47*/, tmp ); /* 2*(Q_bwe_exc_ext) */ -#endif } FOR( i = 0; i < L_SHB_LAHEAD / 4; i++ ) { -#ifdef BASOP_NOGLOB curr_pow = L_mac0_sat( curr_pow, shaped_wb_excitation[i + L_SHB_LAHEAD / 4], shaped_wb_excitation[i + L_SHB_LAHEAD / 4] ); /* Q(2*Q_bwe_exc_ext) */ -#else - curr_pow = L_mac0( curr_pow, shaped_wb_excitation[i + L_SHB_LAHEAD / 4], shaped_wb_excitation[i + L_SHB_LAHEAD / 4] ); /* Q(2*Q_bwe_exc_ext) */ -#endif } if ( GT_16( voice_factors[0], 24576 ) ) @@ -1650,12 +1597,8 @@ void wb_tbe_dec_fx( FOR( i = 0; i < L_SHB_LAHEAD / 4 - 1; i++ ) { - L_tmp = Mult_32_16( Lscale, shaped_wb_excitation[i] ); /* Q(16-exp+Q_bwe_exc_ext) */ -#ifdef BASOP_NOGLOB + L_tmp = Mult_32_16( Lscale, shaped_wb_excitation[i] ); /* Q(16-exp+Q_bwe_exc_ext) */ shaped_wb_excitation[i] = round_fx_sat( L_shl_sat( L_tmp, exp ) ); /* Q_bwe_exc_ext */ -#else - shaped_wb_excitation[i] = round_fx( L_shl( L_tmp, exp ) ); /* Q_bwe_exc_ext */ -#endif move16(); } Lscale = root_a_fx( Lscale, sub( 31, exp ), &exp ); @@ -1691,26 +1634,16 @@ void wb_tbe_dec_fx( n = norm_s( max ); FOR( i = 0; i < L_FRAME16k / 4; i++ ) { -#ifdef BASOP_NOGLOB shaped_wb_excitation_frac[i] = shl_o( shaped_wb_excitation[i], n, &Overflow ); /*Q14*/ move16(); -#else - shaped_wb_excitation_frac[i] = shl( shaped_wb_excitation[i], n ); /*Q14*/ - move16(); -#endif } n = sub( 14, n ); curr_frame_pow = 1; move32(); FOR( i = 0; i < L_FRAME16k / 4; i++ ) { -#ifdef BASOP_NOGLOB L_tmp = L_mult_o( shaped_wb_excitation_frac[i], shaped_wb_excitation_frac[i], &Overflow ); /*Q29*/ curr_frame_pow = L_add_o( curr_frame_pow, L_shr( L_tmp, 7 ), &Overflow ); /*Q22*/ -#else - L_tmp = L_mult( shaped_wb_excitation_frac[i], shaped_wb_excitation_frac[i] ); /*Q29*/ - curr_frame_pow = L_add( curr_frame_pow, L_shr( L_tmp, 7 ) ); /*Q22*/ -#endif } } curr_frame_pow_exp = add( n, n ); @@ -1898,19 +1831,11 @@ void wb_tbe_dec_fx( L_tmp = Mult_32_16( Lacc, 102 ); /* Q22 */ exp = norm_l( L_tmp ); -#ifdef BASOP_NOGLOB tmp = round_fx_o( L_shl_o( L_tmp, exp, &Overflow ), &Overflow ); -#else - tmp = round_fx( L_shl( L_tmp, exp ) ); -#endif exp = sub( add( exp, 22 ), 30 ); tmp = div_s( 16384, tmp ); - L_tmp = Isqrt_lc( L_deposit_h( tmp ), &exp ); /* Q(31-exp) */ -#ifdef BASOP_NOGLOB + L_tmp = Isqrt_lc( L_deposit_h( tmp ), &exp ); /* Q(31-exp) */ st_fx->last_wb_bwe_ener_fx = round_fx_sat( L_shl_sat( L_tmp, add( exp, sub( n, 12 ) ) ) ); /* Q3 */ -#else - st_fx->last_wb_bwe_ener_fx = round_fx( L_shl( L_tmp, add( exp, n - 12 ) ) ); /* Q3 */ -#endif move16(); } @@ -1938,11 +1863,7 @@ void wb_tbe_dec_fx( { lsf_wb[i] = f; move16(); /*Q15*/ -#ifdef BASOP_NOGLOB f = add_sat( f, inc ); -#else - f = add( f, inc ); -#endif move16(); } GainFrame = 0; /* Q18 */ @@ -2101,11 +2022,7 @@ void swb_tbe_dec_fx( Q_shb = 0; /* high band target Q factor set to zero */ move16(); L_tmp = calc_tilt_bwe_fx( old_syn_12k8_16k, st_fx->Q_syn2, st_fx->L_frame ); -#ifdef BASOP_NOGLOB tilt_swb_fec = round_fx_sat( L_shl_sat( L_tmp, 3 ) ); -#else - tilt_swb_fec = round_fx( L_shl( L_tmp, 3 ) ); -#endif /* i: old_syn_12k8_16k in st_fx->Q_syn2 */ /* o: tilt_swb_fec in Q11 */ test(); @@ -2401,11 +2318,7 @@ void swb_tbe_dec_fx( scale = div_s( tmp1, tmp ); /* Q15 - Q(15-exp) + Qi = Qexp+i */ scale = s_max( scale, 0 ); /*scale = st->prev_res_shb_gshape * min(scale, 1.0f); */ -#ifdef BASOP_NOGLOB tmp = shl_sat( scale, sub( sub( 15, exp ), i ) ); /*Q15*/ -#else - tmp = shl( scale, 15 - exp - i ); /*Q15*/ -#endif } scale = mult_r( hBWE_TD->prev_res_shb_gshape_fx, tmp ); /* Q14 */ @@ -2738,11 +2651,7 @@ void swb_tbe_dec_fx( FOR( cnt = 0; cnt < L_FRAME32k; cnt++ ) { -#ifdef BASOP_NOGLOB bwe_exc_extended_16[cnt + NL_BUFF_OFFSET] = round_fx_sat( L_shl_sat( bwe_exc_extended[cnt], sc ) ); -#else - bwe_exc_extended_16[cnt + NL_BUFF_OFFSET] = round_fx( L_shl( bwe_exc_extended[cnt], sc ) ); -#endif } Copy( bwe_exc_extended_16 + L_FRAME32k, hBWE_TD->old_bwe_exc_extended_fx, NL_BUFF_OFFSET ); @@ -2805,22 +2714,12 @@ void swb_tbe_dec_fx( Copy( shaped_shb_excitationTemp, &shaped_shb_excitation[L_SHB_LAHEAD], L_FRAME16k ); /* Q_bwe_exc */ tmp = sub( shl( Q_bwe_exc, 1 ), 31 + 16 ); -#ifdef BASOP_NOGLOB prev_pow = L_shl_sat( 1407374848l /*0.00001f Q47*/, tmp ); /* 2*(Q_bwe_exc) */ curr_pow = L_shl_sat( 1407374848l /*0.00001f Q47*/, tmp ); /* 2*(Q_bwe_exc) */ -#else - prev_pow = L_shl( 1407374848l /*0.00001f Q47*/, tmp ); /* 2*(Q_bwe_exc) */ - curr_pow = L_shl( 1407374848l /*0.00001f Q47*/, tmp ); /* 2*(Q_bwe_exc) */ -#endif FOR( i = 0; i < L_SHB_LAHEAD + 10; i++ ) { -#ifdef BASOP_NOGLOB prev_pow = L_mac0_sat( prev_pow, shaped_shb_excitation[i], shaped_shb_excitation[i] ); /*2*Q_bwe_exc*/ curr_pow = L_mac0_sat( curr_pow, shaped_shb_excitation[i + L_SHB_LAHEAD + 10], shaped_shb_excitation[i + L_SHB_LAHEAD + 10] ); /* 2*Q_bwe_exc */ -#else - prev_pow = L_mac0( prev_pow, shaped_shb_excitation[i], shaped_shb_excitation[i] ); /*2*Q_bwe_exc*/ - curr_pow = L_mac0( curr_pow, shaped_shb_excitation[i + L_SHB_LAHEAD + 10], shaped_shb_excitation[i + L_SHB_LAHEAD + 10] ); /* 2*Q_bwe_exc */ -#endif } if ( GT_16( voice_factors[0], 24576 /*0.75f Q15*/ ) ) @@ -2848,13 +2747,8 @@ void swb_tbe_dec_fx( } FOR( ; i < L_SHB_LAHEAD + 10; i++ ) { -#ifdef BASOP_NOGLOB temp = i_mult_sat( sub( i, 19 ), 3277 /*0.1f Q15*/ ); /* Q15 */ L_tmp1 = Mult_32_16( L_shl_sat( 1, sub( 31, exp ) ), temp ); /* Q31-exp */ -#else - temp = i_mult( sub( i, 19 ), 3277 /*0.1f Q15*/ ); /* Q15 */ - L_tmp1 = Mult_32_16( L_shl( 1, sub( 31, exp ) ), temp ); /* Q31-exp */ -#endif temp = sub( 32767 /*1.0f Q15*/, temp ); Lscale = L_add( Mult_32_16( Lscale, temp ), L_tmp1 ); L_tmp = Mult_32_16( Lscale, shaped_shb_excitation[i] ); /* Q_bwe_exc + (31-exp) - 15 */ @@ -2894,22 +2788,12 @@ void swb_tbe_dec_fx( tmp = div_s( 16384, tmp ); L_tmp = L_deposit_h( tmp ); L_tmp = Isqrt_lc( L_tmp, &exp ); -#ifdef BASOP_NOGLOB ener_tmp[i] = L_shl_sat( L_tmp, sub( add( exp, shl( Q_bwe_exc, 1 ) ), 31 ) ); /*2 * Q_bwe_exc: Q31 -exp +exp +2 * Q_bwe_exc -31 */ move32(); L_ener = L_add_sat( L_ener, L_shr( ener_tmp[i], 2 ) ); /* 2*Q_bwe_exc */ -#else - ener_tmp[i] = L_shl( L_tmp, sub( add( exp, shl( Q_bwe_exc, 1 ) ), 31 ) ); /*2 * Q_bwe_exc: Q31 -exp +exp +2 * Q_bwe_exc -31 */ - move32(); - L_ener = L_add( L_ener, L_shr( ener_tmp[i], 2 ) ); /* 2*Q_bwe_exc */ -#endif } } -#ifdef BASOP_NOGLOB ener = s_max( 1, round_fx_sat( L_shl_sat( L_ener, sub( 19, shl( Q_bwe_exc, 1 ) ) ) ) ); /* Q3: 2*Q_bwe_exc+19-2*Q_bwe_exc-16 */ -#else - ener = s_max( 1, round_fx( L_shl( L_ener, sub( 19, shl( Q_bwe_exc, 1 ) ) ) ) ); /* Q3: 2*Q_bwe_exc+19-2*Q_bwe_exc-16 */ -#endif /* WB/SWB bandwidth switching */ IF( st_fx->bws_cnt > 0 ) { @@ -2972,30 +2856,18 @@ void swb_tbe_dec_fx( test(); IF( GT_32( L_tmp, st_fx->enerLH_fx ) ) /*st_fx->Q_syn2*/ { -#ifdef BASOP_NOGLOB st_fx->tilt_wb_fx = extract_h( L_shr_sat( Mult_32_16( st_fx->enerLH_fx, inv_ener ), sub( sub( st_fx->Q_syn2, exp_ener ), 16 ) ) ); /*Q11*/ -#else - st_fx->tilt_wb_fx = extract_h( L_shr( Mult_32_16( st_fx->enerLH_fx, inv_ener ), sub( sub( st_fx->Q_syn2, exp_ener ), 16 ) ) ); /*Q11*/ -#endif move16(); /*st_fx->Q_syn2 -1 + 26- exp_ener -15 -(st_fx->Q_syn2 -exp_ener -16 ) -16 +1 -1 = (11) *0.5*/ } ELSE IF( LT_32( L_tmp, Mult_32_16( st_fx->enerLH_fx, 1638 ) ) && EQ_16( is_fractive, 1 ) ) { -#ifdef BASOP_NOGLOB st_fx->tilt_wb_fx = extract_h( L_shr_sat( Mult_32_16( st_fx->enerLH_fx, inv_ener ), sub( sub( st_fx->Q_syn2, exp_ener ), 15 ) ) ); /*Q11*/ -#else - st_fx->tilt_wb_fx = extract_h( L_shr( Mult_32_16( st_fx->enerLH_fx, inv_ener ), sub( sub( st_fx->Q_syn2, exp_ener ), 15 ) ) ); /*Q11*/ -#endif move16(); /*st_fx->Q_syn2 -1 + 26- exp_ener -15 -(st_fx->Q_syn2 -exp_ener -15 ) -16 = (11) 0.25*/ } - L_tmp = L_mult0( st_fx->prev_ener_shb_fx, inv_ener ); /*Q(1+15+14-3-exp_ener) = 27 -exp_ener*/ -#ifdef BASOP_NOGLOB + L_tmp = L_mult0( st_fx->prev_ener_shb_fx, inv_ener ); /*Q(1+15+14-3-exp_ener) = 27 -exp_ener*/ GainFrame_prevfrm_fx = L_shr_sat( L_tmp, sub( 9, exp_ener ) ); /*27 -exp_ener -(9-exp_ener )= Q18*/ -#else - GainFrame_prevfrm_fx = L_shr( L_tmp, sub( 9, exp_ener ) ); /*27 -exp_ener -(9-exp_ener )= Q18*/ -#endif } ELSE { @@ -3055,13 +2927,9 @@ void swb_tbe_dec_fx( { ener = s_max( 1, ener ); exp_ener = norm_s( ener ); - tmp = shl( ener, exp_ener ); /*Q(3+exp)*/ - inv_ener = div_s( 16384, tmp ); /*Q(15+14-3-exp)*/ -#ifdef BASOP_NOGLOB + tmp = shl( ener, exp_ener ); /*Q(3+exp)*/ + inv_ener = div_s( 16384, tmp ); /*Q(15+14-3-exp)*/ prev_ener_ratio_fx = L_shr_sat( L_mult0( st_fx->prev_ener_shb_fx, inv_ener ), sub( 9, exp_ener ) ); /*Q: 1+26-exp-9+exp = 18 */ -#else - prev_ener_ratio_fx = L_shr( L_mult0( st_fx->prev_ener_shb_fx, inv_ener ), sub( 9, exp_ener ) ); /*Q: 1+26-exp-9+exp = 18 */ -#endif } IF( EQ_16( st_fx->nbLostCmpt, 1 ) ) @@ -3193,11 +3061,7 @@ void swb_tbe_dec_fx( L_tmp1 = Mult_32_16( ener_tmp[i], GainShape_tmp[i] ); /* (2*Q_bwe_exc) */ L_tmp2 = Mult_32_16( hBWE_TD->prev_ener_fx, hBWE_TD->prev_GainShape_fx ); /* (2*st_fx->prev_ener_fx_Q) */ tmp = sub( shl( Q_bwe_exc, 1 ), shl( st_fx->prev_ener_fx_Q, 1 ) ); -#ifdef BASOP_NOGLOB L_tmp2 = L_shl_sat( L_tmp2, tmp ); /* new Q = (2*Q_bwe_exc) */ -#else - L_tmp2 = L_shl( L_tmp2, tmp ); /* new Q = (2*Q_bwe_exc) */ -#endif IF( GT_32( L_tmp1, L_tmp2 ) ) { /*GainShape_tmp_fx[i] = 0.5f*(L_tmp2/ener_tmp_fx[i] + GainShape_tmp_fx[i]);*/ @@ -3210,11 +3074,7 @@ void swb_tbe_dec_fx( } expb = norm_l( L_tmp ); -#ifdef BASOP_NOGLOB fracb = round_fx_sat( L_shl_sat( L_tmp, expb ) ); -#else - fracb = round_fx( L_shl( L_tmp, expb ) ); -#endif expb = sub( 30, expb ); /* - (2*Q_bwe_exc_ext); */ expa = norm_l( ener_tmp[i] ); @@ -3299,13 +3159,8 @@ void swb_tbe_dec_fx( move16(); FOR( i = 0; i < L_FRAME16k; i++ ) { -#ifdef BASOP_NOGLOB shaped_shb_excitation_frac[i] = shl_sat( shaped_shb_excitation[i], n ); /*Q_bwe_exc+n*/ move16(); -#else - shaped_shb_excitation_frac[i] = shl( shaped_shb_excitation[i], n ); /*Q_bwe_exc+n*/ - move16(); -#endif } curr_frame_pow = 0; @@ -3436,11 +3291,7 @@ void swb_tbe_dec_fx( ( EQ_16( st_fx->prev_coder_type, UNVOICED ) || ( st_fx->last_good == UNVOICED_CLAS ) || GT_16( hBWE_TD->tilt_swb_fec_fx, 10240 ) ) ) { L_tmp = root_a_over_b_fx( hBWE_TD->prev_swb_bwe_frame_pow_fx, curr_frame_pow_exp, curr_frame_pow, curr_frame_pow_exp, &exp ); -#ifdef BASOP_NOGLOB scale = round_fx_sat( L_shl_sat( L_tmp, sub( exp, 3 ) ) ); /*Q12*/ -#else - scale = round_fx( L_shl( L_tmp, sub( exp, 3 ) ) ); /*Q12*/ -#endif L_tmp = root_a_fx( L_tmp, sub( 31, exp ), &exp ); L_tmp = root_a_fx( L_tmp, sub( 31, exp ), &exp ); L_tmp = root_a_fx( L_tmp, sub( 31, exp ), &exp ); @@ -3461,23 +3312,15 @@ void swb_tbe_dec_fx( L_tmp = root_a_fx( L_tmp, sub( 31, exp ), &exp ); L_tmp = root_a_fx( L_tmp, sub( 31, exp ), &exp ); L_tmp = root_a_fx( L_tmp, sub( 31, exp ), &exp ); -#ifdef BASOP_NOGLOB temp = round_fx_sat( L_shl_sat( L_tmp, sub( exp, 3 ) ) ); /*Q12*/ -#else - temp = round_fx( L_shl( L_tmp, sub( exp, 3 ) ) ); /*Q12*/ -#endif } ELSE IF( LT_32( curr_frame_pow, L_shr( hBWE_TD->prev_swb_bwe_frame_pow_fx, 1 ) ) && ( GT_32( st_fx->enerLL_fx, L_shr( st_fx->prev_enerLL_fx, 1 ) ) || GT_32( st_fx->enerLH_fx, L_shr( st_fx->prev_enerLH_fx, 1 ) ) ) && ( EQ_16( st_fx->prev_coder_type, UNVOICED ) || ( st_fx->last_good == UNVOICED_CLAS ) || GT_16( hBWE_TD->tilt_swb_fec_fx, 10240 ) ) ) { L_tmp = root_a_over_b_fx( hBWE_TD->prev_swb_bwe_frame_pow_fx, curr_frame_pow_exp, curr_frame_pow, curr_frame_pow_exp, &exp ); -#ifdef BASOP_NOGLOB L_tmp = L_min( L_tmp, L_shl_sat( 2, sub( 31, exp ) ) ); /*31 - exp*/ -#else - L_tmp = L_min( L_tmp, L_shl( 2, ( 31 - exp ) ) ); /*31 - exp*/ -#endif - scale = round_fx( L_shl( L_tmp, sub( exp, 3 ) ) ); /*Q12*/ + scale = round_fx( L_shl( L_tmp, sub( exp, 3 ) ) ); /*Q12*/ L_tmp = root_a_fx( L_tmp, sub( 31, exp ), &exp ); L_tmp = root_a_fx( L_tmp, sub( 31, exp ), &exp ); L_tmp = root_a_fx( L_tmp, sub( 31, exp ), &exp ); @@ -3486,25 +3329,13 @@ void swb_tbe_dec_fx( } FOR( j = 0; j < 8; j++ ) { -#ifdef BASOP_NOGLOB GainShape[2 * j] = shl_sat( mult_r( GainShape[2 * j], scale ), 3 ); -#else - GainShape[2 * j] = shl( mult_r( GainShape[2 * j], scale ), 3 ); -#endif move16(); /* 15 +12 +3-15 =15*/ -#ifdef BASOP_NOGLOB GainShape[add( 2 * j, 1 )] = shl_sat( mult_r( GainShape[add( 2 * j, 1 )], scale ), 3 ); -#else - GainShape[2 * j + 1] = shl( mult_r( GainShape[2 * j + 1], scale ), 3 ); -#endif move16(); FOR( i = 0; i < 40; i++ ) { -#ifdef BASOP_NOGLOB shaped_shb_excitation[add( i, j * 40 )] = shl_sat( mult_r( shaped_shb_excitation[add( i, j * 40 )], scale ), 3 ); -#else - shaped_shb_excitation[add( i, i_mult( j, 40 ) )] = shl( mult_r( shaped_shb_excitation[add( i, i_mult( j, 40 ) )], scale ), 3 ); -#endif move16(); /* Q_bwe_exc +12+3 -15 =Q_bwe_exc*/ } @@ -3561,11 +3392,7 @@ void swb_tbe_dec_fx( tmp = div_s( 16384, tmp ); L_tmp = L_deposit_h( tmp ); L_tmp = Isqrt_lc( L_tmp, &exp ); -#ifdef BASOP_NOGLOB st_fx->prev_ener_shb_fx = round_fx_sat( L_shl_sat( L_tmp, sub( exp, 14 ) ) ); /* Q1 */ -#else - st_fx->prev_ener_shb_fx = round_fx( L_shl( L_tmp, sub( exp, 14 ) ) ); /* Q1 */ -#endif move16(); } /* st->prev_SWB_fenv[i] = sqrt(curr_frame_pow/L_FRAME16k); */ @@ -3581,11 +3408,7 @@ void swb_tbe_dec_fx( tmp = div_s( 16384, tmp ); L_tmp = L_deposit_h( tmp ); L_tmp = Isqrt_lc( L_tmp, &exp ); -#ifdef BASOP_NOGLOB tmp = round_fx_sat( L_shl_sat( L_tmp, sub( exp, 14 ) ) ); /* Q1 */ -#else - tmp = round_fx( L_shl( L_tmp, sub( exp, 14 ) ) ); /* Q1 */ -#endif } set16_fx( st_fx->prev_SWB_fenv_fx, tmp, SWB_FENV ); /* Q1 */ @@ -3877,12 +3700,12 @@ static void gradientGainShape( IF( GT_16( 8192, tmp ) ) { - GainShape[add( i * 4, j )] = shl( tmp, 2 ); + GainShape[i * 4 + j] = shl( tmp, 2 ); move16(); /* (GainShapeTemp[i]*0.6)>>1 */ } ELSE { - GainShape[add( i * 4, j )] = 32767; + GainShape[i * 4 + j] = 32767; move16(); /* Clipping here to avoid the a huge change of the code due to gain shape change */ } } @@ -3898,12 +3721,12 @@ static void gradientGainShape( { IF( LT_16( GainShapeTemp[i], 16384 ) ) { - GainShape[add( i * 4, j )] = shl( GainShapeTemp[i], 1 ); + GainShape[i * 4 + j] = shl( GainShapeTemp[i], 1 ); move16(); } ELSE { - GainShape[add( i * 4, j )] = 32767; + GainShape[i * 4 + j] = 32767; move16(); } } @@ -3932,12 +3755,12 @@ static void gradientGainShape( { IF( LT_16( GainShapeTemp[i], 16384 ) ) { - GainShape[add( i * 4, j )] = shl( GainShapeTemp[i], 1 ); + GainShape[i * 4 + j] = shl( GainShapeTemp[i], 1 ); move16(); } ELSE { - GainShape[add( i * 4, j )] = 32767; + GainShape[i * 4 + j] = 32767; move16(); } } @@ -4859,11 +4682,7 @@ void fb_tbe_dec_fx( { i = (Word16) get_next_indice_fx( st, 4 ); } -#ifdef BASOP_NOGLOB ratio = shl_sat( 1, i ); -#else - ratio = shl( 1, i ); -#endif } ELSE IF( EQ_16( st->extl, FB_TBE ) && st->bfi ) { @@ -4879,11 +4698,7 @@ void fb_tbe_dec_fx( /* v_add_fx( hb_synth, fb_synth, hb_synth, L_FRAME48k );*/ FOR( i = 0; i < L_FRAME48k; i++ ) { -#ifdef BASOP_NOGLOB hb_synth[i] = add_sat( hb_synth[i], fb_synth[i] ); -#else - hb_synth[i] = add( hb_synth[i], fb_synth[i] ); -#endif move16(); } return; @@ -4925,11 +4740,7 @@ void fb_tbe_dec_ivas_fx( { i = (Word16) get_next_indice_fx( st, 4 ); } -#ifdef BASOP_NOGLOB ratio = shl_sat( 1, i ); -#else - ratio = shl( 1, i ); -#endif } ELSE IF( EQ_16( st->extl, FB_TBE ) && st->bfi ) { @@ -5424,10 +5235,7 @@ void td_bwe_dec_init_ivas_fx( void td_bwe_dec_init_fx( Decoder_State *st_fx, /* i/o: SHB decoder structure */ TD_BWE_DEC_HANDLE hBWE_TD, /* i/o: TD BWE data handle */ -#ifdef ADD_IVAS_BWE - const Word16 extl, /* i : BWE extension layer */ -#endif - const Word32 output_Fs /* i : output sampling rate */ + const Word32 output_Fs /* i : output sampling rate */ ) { Word16 i; @@ -5494,3 +5302,2019 @@ void td_bwe_dec_init_fx( return; } + +/*-------------------------------------------------------------------* + * ResetSHBbuffer_Dec() + * + * + *-------------------------------------------------------------------*/ + +static void calc_tilt_bwe_fx_loc( + const Word32 *sp_fx, /* i : input signal : Q11 */ + Word32 *tilt_fx, /* o : signal tilt : tilt_fx_q */ + Word16 *tilt_fx_q, /* o : signal tilt */ + const Word16 N /* i : signal length : Q0 */ +) +{ + Word16 i; + Word64 r0_fx, r1_fx; + + r0_fx = EPSILON_FX_SMALL; + move64(); + FOR( i = 0; i < N; i++ ) + { + r0_fx = W_add( r0_fx, W_shr( W_mult_32_32( sp_fx[i], sp_fx[i] ), 1 ) ); /*Q11*2 - 1*/ + } + r1_fx = W_deposit32_l( abs( L_sub( sp_fx[1], sp_fx[0] ) ) ); /*Q11*/ + FOR( i = 2; i < N; i++ ) + { + IF( W_mult_32_32( L_sub( sp_fx[i], sp_fx[i - 1] ) /*Q11*/, L_sub( sp_fx[i - 1], sp_fx[i - 2] ) /*Q11*/ ) /*Q11 * 2 - 1*/ < 0 ) + { + r1_fx = W_add( r1_fx, W_deposit32_l( abs( L_sub( sp_fx[i], sp_fx[i - 1] ) ) ) ); /*Q11*/ + } + } + Word16 headroom_left_r0 = W_norm( r0_fx ); + Word16 headroom_left_r1 = W_norm( r1_fx ); + Word16 r0_q = 0, r1_q = 0; + move16(); + move16(); + IF( LT_16( headroom_left_r0, 32 ) ) + { + r0_fx = W_shr( r0_fx, sub( 32, headroom_left_r0 ) ); + r0_q = sub( 31, sub( ( 2 * OUTPUT_Q ), sub( 32, headroom_left_r0 ) ) ); + } + ELSE + { + r0_q = 31 - ( 2 * OUTPUT_Q ); + move16(); + } + + IF( LT_16( headroom_left_r1, 32 ) ) + { + r1_fx = W_shr( r1_fx, sub( 32, headroom_left_r1 ) ); + r1_q = sub( OUTPUT_Q, sub( 32, headroom_left_r1 ) ); + } + ELSE + { + r1_q = OUTPUT_Q; + move16(); + } + Word32 temp_r0_inv = ISqrt32( W_extract_l( r0_fx ), &r0_q ); + Word32 res = Mpy_32_32( W_extract_l( r1_fx ), temp_r0_inv ); + // Word16 res_q = r1_q + ( r0_q < 0 ? ( 31 + ( -1 * r0_q ) ) : r0_q ) - 31; + Word16 res_q; + IF( r0_q < 0 ) + { + res_q = add( r1_q, sub( add( 31, -r0_q ), 31 ) ); + } + ELSE + { + res_q = add( r1_q, sub( r0_q, 31 ) ); + } + Word16 norm_res = norm_l( res ); + IF( norm_res > 0 ) + { + *tilt_fx = L_shl_sat( res, norm_res ); + move32(); + *tilt_fx_q = add( res_q, norm_res ); + move16(); + } + ELSE + { + *tilt_fx = res; + move32(); + *tilt_fx_q = res_q; + move16(); + } + return; +} + +/*-------------------------------------------------------------------* + * swb_tbe_dec() + * + * SWB TBE decoder, 6 - 14 kHz (or 7.5 - 15.5 kHz) band decoding module + *-------------------------------------------------------------------*/ +static void rescale_genSHB_mem_dec_ivas( + Decoder_State *st_fx, + Word16 sf /*Q0*/ +) +{ + Word16 i; + TD_BWE_DEC_HANDLE hBWE_TD; + hBWE_TD = st_fx->hBWE_TD; + + FOR( i = 0; i < NL_BUFF_OFFSET; i++ ) + { + hBWE_TD->old_bwe_exc_extended_fx[i] = shl( hBWE_TD->old_bwe_exc_extended_fx[i], sf ); + move16(); + } + + FOR( i = 0; i < 7; i++ ) + { + hBWE_TD->mem_genSHBexc_filt_down_shb_fx[i] = shl( hBWE_TD->mem_genSHBexc_filt_down_shb_fx[i], sf ); + move16(); + } + + /* -- Apply memory scaling for 13.2 and 16.4k bps using sf ----*/ + IF( LT_32( st_fx->total_brate, ACELP_24k40 ) ) + { + FOR( i = 0; i < LPC_SHB_ORDER; i++ ) + { + hBWE_TD->state_lpc_syn_fx[i] = shl_sat( hBWE_TD->state_lpc_syn_fx[i], sf ); + move16(); + } + + FOR( i = 0; i < L_SHB_LAHEAD; i++ ) + { + hBWE_TD->state_syn_shbexc_fx[i] = shl_sat( hBWE_TD->state_syn_shbexc_fx[i], sf ); + move16(); + } + } + + hBWE_TD->mem_csfilt_fx[0] = L_shl( hBWE_TD->mem_csfilt_fx[0], sf ); + move32(); + + hBWE_TD->tbe_demph_fx = shl_r( hBWE_TD->tbe_demph_fx, sf ); + move16(); + hBWE_TD->tbe_premph_fx = shl_r( hBWE_TD->tbe_premph_fx, sf ); + move16(); +} + +void find_max_mem_dec_m3( + Decoder_State *st, + Word16 *n_mem3 ) +{ + Word16 i; + // Word16 n_mem_32; + Word16 tempQ15; + Word16 max3; + // Word32 tempQ32, Lmax3; + TD_BWE_DEC_HANDLE hBWE_TD; + hBWE_TD = st->hBWE_TD; + + /* --------------------------------------------------------------*/ + /* Find headroom for synthesis stage associated with these memories: + 1. st->syn_overlap_fx*/ + max3 = 0; + move16(); + /* find max in prev overlapSyn */ + FOR( i = 0; i < L_SHB_LAHEAD; i++ ) + { + tempQ15 = abs_s( hBWE_TD->syn_overlap_fx[i] ); + max3 = s_max( max3, tempQ15 ); + } + /* find max in prev genSHBsynth_state_lsyn_filt_shb_local_fx */ + + /* estimate the norm for 16-bit memories */ + *n_mem3 = norm_s( max3 ); + move16(); + if ( max3 == 0 ) + { + *n_mem3 = 15; + move16(); + } +} + +/*-------------------------------------------------------------------* + * ivas_swb_tbe_dec_fx() + * + * SWB TBE decoder, 6 - 14 kHz (or 7.5 - 15.5 kHz) band decoding module + *-------------------------------------------------------------------*/ +void ivas_swb_tbe_dec_fx( + Decoder_State *st, /* i/o: decoder state structure */ + STEREO_ICBWE_DEC_HANDLE hStereoICBWE, /* i/o: IC-BWE state structure */ + const Word32 *bwe_exc_extended_fx, /* i : bandwidth extended excitation : Q_exc */ + Word16 Q_exc, + const Word16 voice_factors_fx[], /* i : voicing factors : Q15 */ + const Word32 old_syn_12k8_16k_fx[], /* i : low band synthesis : old_syn_fx */ + Word16 *White_exc16k_fx, /* o : shaped white excitation for the FB TBE : Q_white_exc*/ + Word32 *synth_fx, /* o : SHB synthesis/final synthesis : Qx */ + Word16 *pitch_buf_fx, /* i : Q6 */ + Word16 *Q_white_exc ) +{ + Word16 i, j, cnt, n; + Word16 stemp; + TD_BWE_DEC_HANDLE hBWE_TD; + Word32 shaped_shb_excitation_fx_32[L_FRAME16k + L_SHB_LAHEAD]; + Word16 bwe_exc_extended_16[L_FRAME32k + NL_BUFF_OFFSET]; + Word16 shaped_shb_excitation_fx[L_FRAME16k + L_SHB_LAHEAD]; + Word16 lsf_shb_fx[LPC_SHB_ORDER], lpc_shb_fx[LPC_SHB_ORDER + 1], GainShape_fx[NUM_SHB_SUBFR]; // Q12,Q12,Q15 + Word32 GainFrame_fx; // Q18 + Word32 error_fx[L_FRAME32k]; + Word16 ener_fx; + Word32 L_ener; + Word16 is_fractive; + Word32 prev_pow_fx, curr_pow_fx, Lscale; + Word16 scale_fx; + Word16 max_val, temp_fx, shaped_shb_excitation_frac[L_FRAME16k + L_SHB_LAHEAD]; + Word32 curr_frame_pow_fx; + Word16 curr_frame_pow_exp; + Word32 L_prev_ener_shb; + Word16 vf_modified_fx[NB_SUBFR16k]; + Word16 f_fx, inc_fx; + Word32 GainFrame_prevfrm_fx; + Word32 tilt_swb_fec_32_fx; + Word16 tilt_swb_fec_fx_q; + Word16 tilt_swb_fec_fx; + Word32 prev_ener_ratio_fx = 0; /* initialize just to avoid compiler warning */ + Word16 lsp_shb_1_fx[LPC_SHB_ORDER], lsp_shb_2_fx[LPC_SHB_ORDER], lsp_temp_fx[LPC_SHB_ORDER]; + Word16 lpc_shb_sf_fx[4 * ( LPC_SHB_ORDER + 1 )]; + const Word16 *ptr_lsp_interp_coef_fx; + Word32 shb_ener_sf_32; + Word16 shb_res_gshape_fx[NB_SUBFR16k]; + Word16 mixFactors_fx; + Word16 vind; + Word16 shb_res_dummy_fx[L_FRAME16k]; + Word16 shaped_shb_excitationTemp_fx[L_FRAME16k]; + Word32 ener_tmp_fx[NUM_SHB_SUBGAINS]; + Word16 GainShape_tmp_fx[NUM_SHB_SUBGAINS]; + Word16 pitch_fx; + Word16 l_subframe; + Word16 formant_fac_fx; + Word16 synth_scale_fx; + Word16 lsf_diff_fx[LPC_SHB_ORDER], w_fx[LPC_SHB_ORDER]; + Word16 refl_fx[M]; + Word16 tilt_para_fx; + Word16 *nlExc16k_fx, *mixExc16k_fx; + Word16 MSFlag; + Word16 feedback_fx; + Word16 GainShape_tilt_fx; + + // scaling + Word16 exp, tmp; + Word16 tmp1, tmp2; + Word16 mean_vf; + Word32 Lmax, L_tmp; + Word16 frac; + Word32 L_tmp1, L_tmp2; + Word16 Q_bwe_exc; + Word16 Q_bwe_exc_fb; + Word16 Q_shb; + Word16 n_mem, n_mem2, n_mem3, Qx, sc; + Word16 expa, expb; + Word16 fraca, fracb; + Word16 exp_ener, inv_ener; + + hBWE_TD = st->hBWE_TD; + + /* initializations */ + GainFrame_fx = 0; + move32(); + mixFactors_fx = 0; + move16(); + shb_ener_sf_32 = 0; + move32(); + set16_fx( shaped_shb_excitationTemp_fx, 0, L_FRAME16k ); + if ( st->hTdCngDec != NULL ) + { + st->hTdCngDec->shb_dtx_count = 0; + move16(); + } + is_fractive = 0; + move16(); + + IF( hStereoICBWE != NULL ) + { + nlExc16k_fx = hStereoICBWE->nlExc16k_fx; + mixExc16k_fx = hStereoICBWE->mixExc16k_fx; + MSFlag = hStereoICBWE->MSFlag; + move16(); + } + ELSE + { + nlExc16k_fx = NULL; + mixExc16k_fx = NULL; + MSFlag = 0; + move16(); + } + + /* find tilt */ + calc_tilt_bwe_fx_loc( old_syn_12k8_16k_fx, &tilt_swb_fec_32_fx, &tilt_swb_fec_fx_q, L_FRAME ); + tilt_swb_fec_fx = round_fx_sat( L_shl_sat( tilt_swb_fec_32_fx, sub( 11 + 16, tilt_swb_fec_fx_q ) ) ); + test(); + if ( st->bfi && st->clas_dec != UNVOICED_CLAS ) + { + tilt_swb_fec_fx = hBWE_TD->tilt_swb_fec_fx; + move16(); + } + + /* WB/SWB bandwidth switching */ + test(); + test(); + IF( ( GT_16( st->tilt_wb_fx, 10240 /*5 in Q11*/ ) && ( EQ_16( st->clas_dec, UNVOICED_CLAS ) ) ) || GT_16( st->tilt_wb_fx, 20480 /*10 in Q11*/ ) ) + { + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + IF( ( ( st->prev_fractive == 0 ) && + ( LT_32( st->prev_enerLH_fx, L_shl( st->enerLH_fx, 1 ) ) && GT_32( st->prev_enerLH_fx, L_shr( st->enerLH_fx, 1 ) ) && LT_32( st->prev_enerLL_fx, L_shl( st->enerLL_fx, 1 ) ) && GT_32( st->prev_enerLL_fx, L_shr( st->enerLL_fx, 1 ) ) ) ) || + ( EQ_16( st->prev_fractive, 1 ) && + GT_32( L_shr( st->prev_enerLH_fx, 2 ), Mult_32_16( st->enerLH_fx, 24576 ) ) ) /* 24576 in Q13*/ + || ( GT_32( L_shr( st->enerLL_fx, 1 ), Mult_32_16( st->enerLH_fx, 24576 ) ) && /*24576 = 1.5 in Q14*/ + LT_16( st->tilt_wb_fx, 20480 ) ) /* 20480 = 10 in Q11*/ + ) + { + is_fractive = 0; + } + ELSE + { + is_fractive = 1; + } + move16(); + } + + /* WB/SWB bandwidth switching */ + IF( st->bws_cnt > 0 ) + { + f_fx = 1489; /*1.0f / 22.0f in Q15*/ + move16(); + inc_fx = 1489; /*1.0f / 22.0f in Q15*/ + move16(); + + IF( EQ_16( is_fractive, 1 ) ) + { + Copy( lsf_tab_fx, hBWE_TD->lsp_prevfrm_fx, LPC_SHB_ORDER ); + } + ELSE + { + FOR( i = 0; i < LPC_SHB_ORDER; i++ ) + { + hBWE_TD->lsp_prevfrm_fx[i] = f_fx; /*Q15*/ + move16(); + f_fx = add( f_fx, inc_fx ); /*Q15*/ + } + } + test(); + test(); + test(); + test(); + test(); + test(); + test(); + IF( ( NE_16( st->last_extl, SWB_TBE ) && NE_16( st->last_extl, FB_TBE ) && !( ( L_sub( L_shr( st->prev_enerLH_fx, 1 ), st->enerLH_fx ) < 0 ) && L_sub( st->prev_enerLH_fx, ( L_shr( st->enerLH_fx, 1 ) > 0 ) ) ) ) || st->last_core != ACELP_CORE || ( ( st->last_core == ACELP_CORE ) && GT_32( abs( L_sub( st->last_core_brate, st->core_brate ) ), 3600 ) ) || EQ_16( s_xor( is_fractive, st->prev_fractive ), 1 ) ) + { + set16_fx( GainShape_fx, 11587, NUM_SHB_SUBFR ); /*0.3536f in Q15*/ + } + ELSE + { + if ( GT_16( hBWE_TD->prev_GainShape_fx, 11587 ) ) /*0.3536f in Q15*/ + { + hBWE_TD->prev_GainShape_fx = 11587; /*0.3536f in Q15*/ + move16(); + } + set16_fx( GainShape_fx, hBWE_TD->prev_GainShape_fx, NUM_SHB_SUBFR ); + } + + Copy( hBWE_TD->lsp_prevfrm_fx, lsf_shb_fx, LPC_SHB_ORDER ); + set16_fx( shb_res_gshape_fx, 3277 /*0.2f Q14*/, NB_SUBFR16k ); /* Q14 */ + } + ELSE + { + test(); + IF( NE_16( st->last_extl, SWB_TBE ) && NE_16( st->last_extl, FB_TBE ) ) + { + f_fx = 1489; /*Q15*/ + move16(); + inc_fx = 1489; /*Q15*/ + move16(); + FOR( i = 0; i < LPC_SHB_ORDER; i++ ) + { + hBWE_TD->lsp_prevfrm_fx[i] = f_fx; /*Q15*/ + move16(); + f_fx = add( f_fx, inc_fx ); + } + } + + IF( !st->bfi ) + { + IF( st->use_partial_copy ) + { + IF( NE_16( st->last_extl, SWB_TBE ) ) + { + hBWE_TD->GainFrame_prevfrm_fx = 0; + move32(); + f_fx = 1489 /*0.045454f Q15*/; + move16(); + inc_fx = 1489 /*0.045454f Q15*/; + move16(); + FOR( i = 0; i < LPC_SHB_ORDER; i++ ) + { + hBWE_TD->lsp_prevfrm_fx[i] = f_fx; /*Q15*/ + move16(); + f_fx = add( f_fx, inc_fx ); /*Q15*/ + } + } + Copy( hBWE_TD->lsp_prevfrm_fx, lsf_shb_fx, LPC_SHB_ORDER ); + set16_fx( GainShape_fx, RECIP_ROOT_EIGHT_FX, NUM_SHB_SUBFR ); + + IF( EQ_16( st->rf_frame_type, RF_NELP ) ) + { + /* Frame gain */ + + GainFrame_fx = L_mac( SHB_GAIN_QLOW_FX, st->rf_indx_tbeGainFr, SHB_GAIN_QDELTA_FX ); + L_tmp = Mult_32_16( GainFrame_fx, 27213 ); /*Q16*/ /* 3.321928 in Q13 */ + + frac = L_Extract_lc( L_tmp, &exp ); + L_tmp = Pow2( 30, frac ); + GainFrame_fx = L_shl( L_tmp, sub( exp, 12 ) ); /*Q18*/ + + test(); + test(); + test(); + test(); + test(); + test(); + IF( ( st->core == ACELP_CORE ) && ( st->last_core == ACELP_CORE ) && !st->prev_use_partial_copy && EQ_16( st->prev_coder_type, UNVOICED ) && NE_32( GainFrame_fx, hBWE_TD->GainFrame_prevfrm_fx ) && NE_16( st->next_coder_type, GENERIC ) && EQ_16( st->last_extl, SWB_TBE ) ) + { + GainFrame_fx = L_add( Mult_32_16( hBWE_TD->GainFrame_prevfrm_fx, 26214 /*0.8f in Q15*/ ), Mult_32_16( GainFrame_fx, 6553 /*0.2f in Q15*/ ) ); + } + } + ELSE + { + temp_fx = 0; + move16(); + /* Frame gain */ + SWITCH( st->rf_indx_tbeGainFr ) + { + case 0: + GainFrame_fx = 131072; /* 0.5f in Q18 */ + move32(); + if ( LE_32( hBWE_TD->GainFrame_prevfrm_fx, 327680l /*1.25 Q18*/ ) ) + { + temp_fx = 26214 /*0.8 Q15*/; + move16(); + } + BREAK; + case 1: + GainFrame_fx = 524288; /* 2.0f in Q18 */ + move32(); + test(); + if ( GT_32( hBWE_TD->GainFrame_prevfrm_fx, 327680l /*1.25 Q18*/ ) && LE_32( hBWE_TD->GainFrame_prevfrm_fx, 786432l /*3 Q18*/ ) ) + { + temp_fx = 26214 /*0.8 Q15*/; + move16(); + } + BREAK; + case 2: + GainFrame_fx = 1048576; /* 4.0f in Q18 */ + move32(); + test(); + if ( GT_32( hBWE_TD->GainFrame_prevfrm_fx, 786432l /*3 Q18*/ ) && LE_32( hBWE_TD->GainFrame_prevfrm_fx, 1572864l /*6 Q18*/ ) ) + { + temp_fx = 26214 /*0.8 Q15*/; + move16(); + } + BREAK; + case 3: + GainFrame_fx = 2097152; /* 8.0f in Q18 */ + move32(); + test(); + if ( GT_32( hBWE_TD->GainFrame_prevfrm_fx, 1572864l /*6 Q18*/ ) && LE_32( hBWE_TD->GainFrame_prevfrm_fx, 4194304l /*16Q18*/ ) ) + { + temp_fx = 26214 /*0.8 Q15*/; + move16(); + } + BREAK; + default: + fprintf( stderr, "RF SWB-TBE gain bits not supported." ); + } + + IF( EQ_16( st->last_extl, SWB_TBE ) ) + { + GainFrame_fx = L_add( Mult_32_16( hBWE_TD->GainFrame_prevfrm_fx, temp_fx ), Mult_32_16( GainFrame_fx, sub( 32767, temp_fx ) ) ); + /*Q18*/ + } + + IF( ( st->core == ACELP_CORE ) && ( st->last_core == ACELP_CORE ) ) + { + if ( !st->prev_use_partial_copy && EQ_16( st->last_coder_type, VOICED ) && EQ_16( st->rf_frame_type, RF_GENPRED ) && GT_32( GainFrame_fx, 2097152 /*8.0f in Q18*/ ) && LT_32( GainFrame_fx, 3059606 /*11.67f in Q18*/ ) ) + { + GainFrame_fx = Mult_32_16( GainFrame_fx, 9830 /*0.3f in Q15*/ ); // Q18 + } + } + } + } + ELSE + { + /* de-quantization */ + ivas_dequantizeSHBparams_fx_9_1( st, st->extl, st->extl_brate, lsf_shb_fx, GainShape_fx, &GainFrame_fx, &stemp, + &shb_ener_sf_32, shb_res_gshape_fx, &mixFactors_fx, &MSFlag ); + if ( hStereoICBWE != NULL ) + { + hStereoICBWE->MSFlag = MSFlag; + move16(); + } + } + } + ELSE + { + Copy( hBWE_TD->lsp_prevfrm_fx, lsf_shb_fx, LPC_SHB_ORDER ); + test(); + IF( EQ_16( st->codec_mode, MODE1 ) && ( st->element_mode == EVS_MONO ) ) + { + gradientGainShape( st, GainShape_fx, &GainFrame_fx ); + } + ELSE + { + FOR( i = 0; i < NUM_SHB_SUBFR / 4; i++ ) + { + FOR( j = 0; j < 4; j++ ) + { + GainShape_fx[i * 4 + j] = mult_r( st->cummulative_damping, st->GainShape_Delay[4 + i] ); + move16(); + } + } + IF( GT_16( tilt_swb_fec_fx, ( 8 << 11 ) ) ) /* tilt_swb_fec_fx in Q11 */ + { + IF( EQ_16( st->nbLostCmpt, 1 ) ) + { + GainFrame_fx = Mult_32_16( hBWE_TD->GainFrame_prevfrm_fx, 19661 /*0.6f Q15*/ ); + } + ELSE IF( EQ_16( st->nbLostCmpt, 2 ) ) + { + GainFrame_fx = Mult_32_16( hBWE_TD->GainFrame_prevfrm_fx, 11469 /*0.35f Q15*/ ); + } + ELSE + { + GainFrame_fx = Mult_32_16( hBWE_TD->GainFrame_prevfrm_fx, 6554 /*0.2f Q15*/ ); + } + GainFrame_fx = Mult_32_16( GainFrame_fx, st->cummulative_damping ); + } + ELSE + { + GainFrame_fx = hBWE_TD->GainFrame_prevfrm_fx; + move32(); /* gain locking */ + } + } + + IF( GE_32( st->extl_brate, SWB_TBE_2k8 ) ) + { + test(); + IF( EQ_16( st->codec_mode, MODE1 ) && ( st->element_mode == EVS_MONO ) ) + { + L_tmp = L_mult( extract_l( hBWE_TD->prev2_shb_ener_sf_fx ), extract_l( hBWE_TD->prev3_shb_ener_sf_fx ) ); /*Q1*/ + tmp = round_fx( root_a_fx( L_tmp, 1, &exp ) ); /* Q = 15-exp */ + tmp1 = extract_l( hBWE_TD->prev1_shb_ener_sf_fx ); /*Q0*/ + i = sub( norm_s( tmp1 ), 1 ); + tmp1 = shl( tmp1, i ); /* Qi */ + IF( tmp == 0 ) + { + tmp = 32767 /*1.0f Q15*/; + move16(); /*Q15*/ + } + ELSE + { + scale_fx = div_s( tmp1, tmp ); /* Q15 - Q(15-exp) + Qi = Qexp+i */ + scale_fx = s_max( scale_fx, 0 ); + tmp = shl_sat( scale_fx, sub( sub( 15, exp ), i ) ); /*Q15*/ + } + scale_fx = mult_r( hBWE_TD->prev_res_shb_gshape_fx, tmp ); /* Q14 */ + test(); + IF( GT_32( L_shr( hBWE_TD->prev2_shb_ener_sf_fx, 1 ), hBWE_TD->prev1_shb_ener_sf_fx ) || + GT_32( L_shr( hBWE_TD->prev3_shb_ener_sf_fx, 1 ), hBWE_TD->prev2_shb_ener_sf_fx ) ) + { + shb_ener_sf_32 = Mult_32_16( hBWE_TD->prev1_shb_ener_sf_fx, scale_fx ); + + if ( GT_16( st->nbLostCmpt, 1 ) ) + { + shb_ener_sf_32 = L_shr( shb_ener_sf_32, 1 ); + } + } + ELSE + { + L_tmp = L_mult( scale_fx, scale_fx ); /* Q29 */ + shb_ener_sf_32 = L_shl( Mult_32_16( hBWE_TD->prev1_shb_ener_sf_fx, round_fx( L_tmp ) ), 2 ); + } + } + ELSE + { + test(); + IF( GT_32( L_shr( hBWE_TD->prev2_shb_ener_sf_fx, 1 ), hBWE_TD->prev1_shb_ener_sf_fx ) || + GT_32( L_shr( hBWE_TD->prev3_shb_ener_sf_fx, 1 ), hBWE_TD->prev2_shb_ener_sf_fx ) ) + { + shb_ener_sf_32 = L_shr( Mult_32_16( hBWE_TD->prev1_shb_ener_sf_fx, st->cummulative_damping ), 1 ); + } + ELSE + { + shb_ener_sf_32 = Mult_32_16( hBWE_TD->prev1_shb_ener_sf_fx, st->cummulative_damping ); + } + } + } + + shb_ener_sf_32 = L_max( shb_ener_sf_32, 1l /*1.0f Q0*/ ); + mixFactors_fx = hBWE_TD->prev_mixFactors_fx; + move16(); + + IF( EQ_16( st->codec_mode, MODE1 ) ) + { + set16_fx( shb_res_gshape_fx, 3277 /*0.2f Q14*/, 5 ); /* Q14 */ + } + ELSE + { + set16_fx( shb_res_gshape_fx, 16384 /*1.0f Q14*/, 5 ); /* Q14 */ + } + } + } + + /* get the gainshape delay */ + Copy( &st->GainShape_Delay[4], &st->GainShape_Delay[0], NUM_SHB_SUBFR / 4 ); + FOR( i = 0; i < NUM_SHB_SUBFR / 4; i++ ) + { + st->GainShape_Delay[i + 4] = GainShape_fx[i * 4]; /*Q15*/ + move16(); + } + + L_tmp = L_mult( voice_factors_fx[0], 8192 ); + L_tmp = L_mac( L_tmp, voice_factors_fx[1], 8192 ); + L_tmp = L_mac( L_tmp, voice_factors_fx[2], 8192 ); + mean_vf = mac_r( L_tmp, voice_factors_fx[3], 8192 ); + + Copy( voice_factors_fx, vf_modified_fx, NB_SUBFR16k ); + + test(); + IF( EQ_16( st->coder_type, VOICED ) || GT_16( mean_vf, 13107 /*0.4f Q15*/ ) ) + { + FOR( i = 1; i < NB_SUBFR; i++ ) + { + L_tmp = L_mult( voice_factors_fx[i], 26214 /*0.8f Q15*/ ); + vf_modified_fx[i] = mac_r( L_tmp, voice_factors_fx[i - 1], 6554 /*0.2f Q15*/ ); + move16(); + } + + IF( st->L_frame != L_FRAME ) + { + L_tmp = L_mult( voice_factors_fx[4], 26214 /*0.8f Q15*/ ); + vf_modified_fx[4] = mac_r( L_tmp, voice_factors_fx[3], 6554 /*0.2f Q15*/ ); + move16(); + } + } + + test(); + IF( st->use_partial_copy && st->nelp_mode_dec ) + { + set16_fx( vf_modified_fx, 0, NB_SUBFR16k ); + } + + /* SHB LSF from current frame; and convert to LSP for interpolation */ + E_LPC_lsf_lsp_conversion( lsf_shb_fx, lsp_shb_2_fx, LPC_SHB_ORDER ); + + test(); + IF( EQ_16( st->last_extl, SWB_TBE ) || EQ_16( st->last_extl, FB_TBE ) ) + { + /* SHB LSP values from prev. frame for interpolation */ + Copy( hBWE_TD->swb_lsp_prev_interp_fx, lsp_shb_1_fx, LPC_SHB_ORDER ); + } + ELSE + { + /* Use current frame's LSPs; in effect no interpolation */ + Copy( lsp_shb_2_fx, lsp_shb_1_fx, LPC_SHB_ORDER ); + } + + test(); + test(); + test(); + IF( ( st->bws_cnt == 0 ) && ( st->bws_cnt1 == 0 ) && ( st->prev_use_partial_copy == 0 ) && ( st->use_partial_copy == 0 ) ) + { + lsf_diff_fx[0] = 16384; + move16(); /*Q15*/ + lsf_diff_fx[LPC_SHB_ORDER - 1] = 16384; + move16(); /*Q15*/ + FOR( i = 1; i < LPC_SHB_ORDER - 1; i++ ) + { + lsf_diff_fx[i] = sub( lsf_shb_fx[i], lsf_shb_fx[i - 1] ); + move16(); + } + + a2rc_fx( hBWE_TD->cur_sub_Aq_fx + 1, refl_fx, M ); + tmp = add( 16384, shr( refl_fx[0], 1 ) ); /*Q14*/ + tmp1 = mult( 27425, tmp ); + tmp1 = mult( tmp1, tmp ); /*Q10*/ + tmp2 = shr( mult( 31715, tmp ), 2 ); /*Q10*/ + tilt_para_fx = add( sub( tmp1, tmp2 ), 1335 ); /*Q10*/ + + test(); + IF( NE_16( st->last_extl, SWB_TBE ) && NE_16( st->last_extl, FB_TBE ) ) + { + FOR( i = 1; i < LPC_SHB_ORDER - 1; i++ ) + { + hBWE_TD->prev_lsf_diff_fx[i - 1] = shr( lsf_diff_fx[i], 1 ); + move16(); + } + } + + IF( LE_32( st->extl_brate, FB_TBE_1k8 ) ) + { + test(); + test(); + test(); + test(); + test(); + IF( !( GT_16( hBWE_TD->prev_tilt_para_fx, 5120 ) && ( EQ_16( st->coder_type, TRANSITION ) || LT_16( tilt_para_fx, 1024 ) ) ) && + !( ( ( LT_16( hBWE_TD->prev_tilt_para_fx, 3072 ) && GE_16( st->prev_coder_type, VOICED ) ) ) && GT_16( tilt_para_fx, 5120 ) ) ) + { + FOR( i = 1; i < LPC_SHB_ORDER - 1; i++ ) + { + IF( LT_16( lsf_diff_fx[i], hBWE_TD->prev_lsf_diff_fx[i - 1] ) ) + { + tmp = mult( 26214, lsf_diff_fx[i] ); + + test(); + IF( ( hBWE_TD->prev_lsf_diff_fx[i - 1] <= 0 ) || ( tmp < 0 ) ) /* safety check in case of bit errors */ + { + st->BER_detect = 1; + move16(); + tmp = 0; + move16(); + } + ELSE + { + tmp = div_s( tmp, hBWE_TD->prev_lsf_diff_fx[i - 1] ); + } + + tmp = s_max( tmp, 16384 ); + w_fx[i] = s_min( tmp, 32767 ); + move16(); + } + ELSE + { + tmp = mult( 26214, hBWE_TD->prev_lsf_diff_fx[i - 1] ); + + test(); + IF( ( lsf_diff_fx[i] <= 0 ) || ( tmp < 0 ) ) /* safety check in case of bit errors */ + { + st->BER_detect = 1; + move16(); + tmp = 0; + move16(); + } + ELSE + { + tmp = div_s( tmp, lsf_diff_fx[i] ); + } + + tmp = s_max( tmp, 16384 ); + w_fx[i] = s_min( tmp, 32767 ); + move16(); + } + } + w_fx[0] = w_fx[1]; + move16(); + w_fx[LPC_SHB_ORDER - 1] = w_fx[LPC_SHB_ORDER - 2]; + move16(); + + FOR( i = 0; i < LPC_SHB_ORDER; i++ ) + { + tmp1 = mult( lsp_shb_1_fx[i], sub( 32767, w_fx[i] ) ); + tmp2 = mult( lsp_shb_2_fx[i], w_fx[i] ); + lsp_temp_fx[i] = add( tmp1, tmp2 ); + move16(); + } + } + ELSE + { + Copy( lsp_shb_2_fx, lsp_temp_fx, LPC_SHB_ORDER ); + } + + /* convert from lsp to lsf */ + lsp2lsf_fx( lsp_temp_fx, lsf_shb_fx, LPC_SHB_ORDER, 1 ); + } + + Copy( lsf_diff_fx + 1, hBWE_TD->prev_lsf_diff_fx, LPC_SHB_ORDER - 2 ); + hBWE_TD->prev_tilt_para_fx = tilt_para_fx; + move16(); + } + ELSE + { + Copy( lsp_shb_2_fx, lsp_temp_fx, LPC_SHB_ORDER ); + } + + IF( GE_32( st->extl_brate, SWB_TBE_2k8 ) ) + { + /* SHB LSP interpolation */ + ptr_lsp_interp_coef_fx = interpol_frac_shb; /*Q15*/ + FOR( j = 0; j < 4; j++ ) + { + FOR( i = 0; i < LPC_SHB_ORDER; i++ ) + { + L_tmp = L_mult( lsp_shb_1_fx[i], ( *ptr_lsp_interp_coef_fx ) ); + lsp_temp_fx[i] = mac_r( L_tmp, lsp_shb_2_fx[i], ( *( ptr_lsp_interp_coef_fx + 1 ) ) ); + move16(); + } + ptr_lsp_interp_coef_fx += 2; + + tmp = i_mult( j, ( LPC_SHB_ORDER + 1 ) ); + /* convert LSPs to LP coefficients */ + E_LPC_f_lsp_a_conversion( lsp_temp_fx, lpc_shb_sf_fx + tmp, LPC_SHB_ORDER ); +#ifndef FIX_1100_REMOVE_LPC_RESCALING + /* Bring the LPCs to Q12 */ + Copy_Scale_sig( lpc_shb_sf_fx + tmp, lpc_shb_sf_fx + tmp, LPC_SHB_ORDER + 1, sub( norm_s( lpc_shb_sf_fx[tmp] ), 2 ) ); + lpc_shb_sf_fx[i_mult( j, ( LPC_SHB_ORDER + 1 ) )] = ONE_IN_Q12; // recheck this + move16(); +#endif + } + } + + /* Save the SWB LSP values from current frame for interpolation */ + Copy( lsp_shb_2_fx, hBWE_TD->swb_lsp_prev_interp_fx, LPC_SHB_ORDER ); + + /* save the shb_ener and mixFactor values */ + hBWE_TD->prev3_shb_ener_sf_fx = hBWE_TD->prev2_shb_ener_sf_fx; + move32(); + hBWE_TD->prev2_shb_ener_sf_fx = hBWE_TD->prev1_shb_ener_sf_fx; + move32(); + hBWE_TD->prev1_shb_ener_sf_fx = shb_ener_sf_32; + move32(); + hBWE_TD->prev_res_shb_gshape_fx = shb_res_gshape_fx[4]; + move16(); + hBWE_TD->prev_mixFactors_fx = mixFactors_fx; + move16(); + + /* SWB CNG/DTX - update memories */ + IF( st->hTdCngDec != NULL ) + { + Copy( st->hTdCngDec->lsp_shb_prev_fx, st->hTdCngDec->lsp_shb_prev_prev_fx, LPC_SHB_ORDER ); + Copy( lsf_shb_fx, st->hTdCngDec->lsp_shb_prev_fx, LPC_SHB_ORDER ); + } + + /* convert LSPs back into LP coeffs */ + E_LPC_f_lsp_a_conversion( lsp_temp_fx, lpc_shb_fx, LPC_SHB_ORDER ); + Copy_Scale_sig( lpc_shb_fx, lpc_shb_fx, LPC_SHB_ORDER + 1, sub( norm_s( lpc_shb_fx[0] ), 2 ) ); /* Q12 */ + lpc_shb_fx[0] = ONE_IN_Q12; + move16(); + + test(); + IF( EQ_32( st->extl_brate, SWB_TBE_1k10 ) || EQ_32( st->extl_brate, SWB_TBE_1k75 ) ) + { + Word32 vind_temp = Mpy_32_32( L_shl( L_add( L_deposit_l( mixFactors_fx ), 1 ), 15 ), ( ( ( 1 << NUM_BITS_SHB_VF ) - 1 ) << 16 ) ); // check addition of 1 + vind = extract_l( L_shr( vind_temp, 15 ) ); /* 3 for mpy by 8.0f, -15 to bring it to Q0 */ /*mixFactors*7*/ + /* i: mixFactors_fx in Q15 */ + /* o: vind in Q0 */ + } + ELSE + { + vind = shl( mixFactors_fx, 3 - 15 ); /* 3 for mpy by 8.0f, -15 to bring it to Q0 */ /*mixFactors*8*/ + /* i: mixFactors_fx in Q15 */ + /* o: vind in Q0 */ + } + + /* Determine formant PF strength */ + formant_fac_fx = swb_formant_fac_fx( lpc_shb_fx[1], &hBWE_TD->tilt_mem_fx ); + /* i:lpc_shb_fx Q12, o:formant_fac_fx Q15 */ + IF( GT_32( st->total_brate, ACELP_32k ) ) + { + FOR( j = 0; j < 4; j++ ) + { + Copy( lpc_shb_fx, &lpc_shb_sf_fx[i_mult( j, ( LPC_SHB_ORDER + 1 ) )], LPC_SHB_ORDER + 1 ); + } + } + + /* From low band excitation, generate highband excitation */ + + /* -------- start of memory rescaling -------- */ + /* ----- calculate optimum Q_bwe_exc and rescale memories accordingly ----- */ + Lmax = 0; + move32(); + FOR( cnt = 0; cnt < L_FRAME32k; cnt++ ) + { + Lmax = L_max( Lmax, L_abs( bwe_exc_extended_fx[cnt] ) ); + } + Q_bwe_exc = norm_l( Lmax ); + if ( Lmax == 0 ) + { + Q_bwe_exc = 31; + move16(); + } + Q_bwe_exc = add( Q_bwe_exc, add( Q_exc, Q_exc ) ); + find_max_mem_dec( st, &n_mem, &n_mem2, &n_mem3 ); /* for >=24.4, use n_mem2 lpc_syn, shb_20sample, and mem_stp_swb_fx memory */ + + tmp = add( st->prev_Q_bwe_exc, n_mem ); + if ( GT_16( Q_bwe_exc, tmp ) ) + { + Q_bwe_exc = tmp; + move16(); + } + + /* rescale the memories if Q_bwe_exc is different from previous frame */ + sc = sub( Q_bwe_exc, st->prev_Q_bwe_exc ); + IF( sc != 0 ) + { + rescale_genSHB_mem_dec_ivas( st, sc ); + } + + /* rescale the bwe_exc_extended and bring it to 16-bit single precision with dynamic norm */ + sc = sub( Q_bwe_exc, add( Q_exc, Q_exc ) ); + + FOR( cnt = 0; cnt < L_FRAME32k; cnt++ ) + { + bwe_exc_extended_16[cnt] = round_fx_sat( L_shl_sat( bwe_exc_extended_fx[cnt], sc ) ); + move16(); + } + + /* state_syn_shbexc_fx is kept at (st_fx->prev_Q_bwe_syn) for 24.4/32kbps or is kept at Q_bwe_exc for 13.2/16.4kbps */ + + /* save the previous Q factor (32-bit) of the buffer */ + st->prev_Q_bwe_exc = Q_bwe_exc; + move16(); + + Q_bwe_exc = sub( Q_bwe_exc, 16 ); /* Q_bwe_exc reflecting the single precision dynamic norm-ed buffers from here */ + + /* -------- end of rescaling memories -------- */ + + Q_bwe_exc_fb = st->prev_Q_bwe_exc_fb; + move16(); + + Q_shb = 0; + move16(); + + Copy( hBWE_TD->state_syn_shbexc_fx, shaped_shb_excitation_fx, L_SHB_LAHEAD ); + GenShapedSHBExcitation_ivas_dec_fx( shaped_shb_excitation_fx + L_SHB_LAHEAD, lpc_shb_fx, White_exc16k_fx, + hBWE_TD->mem_csfilt_fx, hBWE_TD->mem_genSHBexc_filt_down_shb_fx, hBWE_TD->state_lpc_syn_fx, + st->coder_type, bwe_exc_extended_16, hBWE_TD->bwe_seed, vf_modified_fx, st->extl, + &( hBWE_TD->tbe_demph_fx ), &( hBWE_TD->tbe_premph_fx ), lpc_shb_sf_fx, shb_ener_sf_32, + shb_res_gshape_fx, shb_res_dummy_fx, &vind, formant_fac_fx, hBWE_TD->fb_state_lpc_syn_fx, + &( hBWE_TD->fb_tbe_demph_fx ), &Q_bwe_exc, &Q_bwe_exc_fb, Q_shb, n_mem2, st->prev_Q_bwe_syn, st->total_brate, st->prev_bfi, + st->element_mode, st->flag_ACELP16k, nlExc16k_fx, mixExc16k_fx, st->extl_brate, MSFlag, + NULL, &( hBWE_TD->prev_pow_exc16kWhtnd_fx32 ), &( hBWE_TD->prev_mix_factor_fx ), NULL, NULL ); + + *Q_white_exc = Q_bwe_exc_fb; + move16(); + IF( EQ_16( st->extl, FB_TBE ) ) + { + st->prev_Q_bwe_exc_fb = Q_bwe_exc_fb; + move16(); + } + ELSE + { + /*Indirectly a memory reset of FB memories for next frame such that rescaling of memories would lead to 0 due to such high prev. Q value. + 51 because of 31 + 20(shift of Q_bwe_exc_fb before de-emphasis)*/ + st->prev_Q_bwe_exc_fb = 51; + move16(); + } + + /* rescale the TBE post proc memory */ + FOR( i = 0; i < LPC_SHB_ORDER; i++ ) + { + hBWE_TD->mem_stp_swb_fx[i] = shl_sat( hBWE_TD->mem_stp_swb_fx[i], sub( Q_bwe_exc, st->prev_Q_bwe_syn ) ); + move16(); + } + /* fill-in missing SHB excitation */ + test(); + test(); + IF( ( EQ_16( st->element_mode, IVAS_CPE_TD ) || EQ_16( st->element_mode, IVAS_CPE_DFT ) ) && LE_32( st->last_core_brate, SID_2k40 ) ) + { + Copy( shaped_shb_excitation_fx + L_SHB_LAHEAD, shaped_shb_excitation_fx, L_SHB_LAHEAD ); + } + + IF( hStereoICBWE != NULL ) + { + Copy( shaped_shb_excitation_fx + L_SHB_LAHEAD, hStereoICBWE->shbSynthRef_fx, L_FRAME16k ); + } + + test(); + IF( NE_32( st->extl_brate, SWB_TBE_1k10 ) && NE_32( st->extl_brate, SWB_TBE_1k75 ) ) + { + FOR( i = 0; i < L_FRAME16k; i += L_SUBFR16k ) + { + /* TD BWE post-processing */ + PostShortTerm_ivas_dec_fx( &shaped_shb_excitation_fx[L_SHB_LAHEAD + i], lpc_shb_fx, &shaped_shb_excitationTemp_fx[i], hBWE_TD->mem_stp_swb_fx, + hBWE_TD->ptr_mem_stp_swb_fx, &( hBWE_TD->gain_prec_swb_fx ), hBWE_TD->mem_zero_swb_fx, formant_fac_fx ); + } + + Copy( shaped_shb_excitationTemp_fx, &shaped_shb_excitation_fx[L_SHB_LAHEAD], L_FRAME16k ); /* Q_bwe_exc */ + + tmp = sub( shl( Q_bwe_exc, 1 ), 31 + 16 ); + prev_pow_fx = L_shl_sat( 1407374848l /*0.00001f Q47*/, tmp ); /* 2*(Q_bwe_exc) */ + curr_pow_fx = L_shl_sat( 1407374848l /*0.00001f Q47*/, tmp ); /* 2*(Q_bwe_exc) */ + FOR( i = 0; i < L_SHB_LAHEAD + 10; i++ ) + { + prev_pow_fx = L_mac0_sat( prev_pow_fx, shaped_shb_excitation_fx[i], shaped_shb_excitation_fx[i] ); /*2*Q_bwe_exc*/ + curr_pow_fx = L_mac0_sat( curr_pow_fx, shaped_shb_excitation_fx[i + L_SHB_LAHEAD + 10], shaped_shb_excitation_fx[i + L_SHB_LAHEAD + 10] ); /* 2*Q_bwe_exc */ + } + + if ( GT_16( voice_factors_fx[0], 24576 /*0.75f Q15*/ ) ) + { + curr_pow_fx = L_shr( curr_pow_fx, 2 ); /* Q(2*Q_bwe_exc) */ + } + + Lscale = root_a_over_b_fx( curr_pow_fx, + shl( Q_bwe_exc, 1 ), + prev_pow_fx, + shl( Q_bwe_exc, 1 ), + &exp ); + + FOR( i = 0; i < L_SHB_LAHEAD; i++ ) + { + L_tmp = Mult_32_16( Lscale, shaped_shb_excitation_fx[i] ); /* Q_bwe_exc + (31-exp) - 15 */ + shaped_shb_excitation_fx[i] = round_fx_sat( L_shl_sat( L_tmp, exp ) ); /* Q_bwe_exc */ + move16(); + } + IF( exp < 0 ) + { + Lscale = L_shl( Lscale, exp ); + exp = 0; + move16(); + } + FOR( ; i < L_SHB_LAHEAD + 10; i++ ) + { + temp_fx = i_mult_sat( sub( i, 19 ), 3277 /*0.1f Q15*/ ); /* Q15 */ + L_tmp1 = Mult_32_16( L_shl_sat( 1, sub( 31, exp ) ), temp_fx ); /* Q31-exp */ + temp_fx = sub( 32767 /*1.0f Q15*/, temp_fx ); + Lscale = L_add( Mult_32_16( Lscale, temp_fx ), L_tmp1 ); + L_tmp = Mult_32_16( Lscale, shaped_shb_excitation_fx[i] ); /* Q_bwe_exc + (31-exp) - 15 */ + shaped_shb_excitation_fx[i] = round_fx_sat( L_shl_sat( L_tmp, exp ) ); /* Q_bwe_exc */ + move16(); + } + } + ELSE + { + /* reset the PF memories if the PF is not running */ + set16_fx( hBWE_TD->mem_stp_swb_fx, 0, LPC_SHB_ORDER ); + hBWE_TD->gain_prec_swb_fx = ONE_IN_Q14; + move16(); + set16_fx( hBWE_TD->mem_zero_swb_fx, 0, LPC_SHB_ORDER ); + } + + /* Update SHB excitation */ + Copy( shaped_shb_excitation_fx + L_FRAME16k, hBWE_TD->state_syn_shbexc_fx, L_SHB_LAHEAD ); /* Q_bwe_exc */ + l_subframe = L_FRAME16k / NUM_SHB_SUBGAINS; + move16(); + L_ener = EPSILON_FX_SMALL; + move32(); + + FOR( i = 0; i < NUM_SHB_SUBGAINS; i++ ) + { + L_tmp = 0; + move32(); + ener_tmp_fx[i] = EPSILON_FX_SMALL; + move32(); + + Word64 tmp64 = 0; + move64(); + FOR( j = 0; j < l_subframe; j++ ) + { + tmp64 = W_mac0_16_16( tmp64, shaped_shb_excitation_fx[add( i_mult( i, l_subframe ), j )], shaped_shb_excitation_fx[add( i_mult( i, l_subframe ), j )] ); /* 2*Q_bwe_exc */ + } + L_tmp = W_sat_l( tmp64 ); + + L_tmp = Mult_32_16( L_tmp, 410 /*0.0125 Q15*/ ); /* 2*Q_bwe_exc: ener_tmp_fx in (2*Q_bwe_exc) */ + IF( L_tmp != 0 ) + { + exp = norm_l( L_tmp ); + tmp = extract_h( L_shl( L_tmp, exp ) ); + exp = sub( exp, sub( 30, i_mult( 2, Q_bwe_exc ) ) ); + + tmp = div_s( 16384, tmp ); + L_tmp = L_deposit_h( tmp ); + L_tmp = Isqrt_lc( L_tmp, &exp ); + ener_tmp_fx[i] = L_shl_sat( L_tmp, sub( add( exp, shl( Q_bwe_exc, 1 ) ), 31 ) ); /*2 * Q_bwe_exc: Q31 -exp +exp +2 * Q_bwe_exc -31 */ + move32(); + L_ener = L_add_sat( L_ener, L_shr( ener_tmp_fx[i], 2 ) ); /* 2*Q_bwe_exc */ + } + } + ener_fx = s_max( 1, round_fx_sat( L_shl_sat( L_ener, sub( 18, shl( Q_bwe_exc, 1 ) ) ) ) ); /* Q2: 2*Q_bwe_exc+18-2*Q_bwe_exc-16 */ + /* WB/SWB bandwidth switching */ + IF( st->bws_cnt > 0 ) + { + IF( is_fractive == 0 ) + { + IF( GT_16( st->tilt_wb_fx, 2048 ) ) /*assuming st->tilt_wb_fx in Q11*/ + { + st->tilt_wb_fx = 2048; + move16(); + } + ELSE IF( LT_16( st->tilt_wb_fx, 1024 ) ) + { + st->tilt_wb_fx = 1024; + move16(); + } + test(); + if ( EQ_16( st->prev_fractive, 1 ) && GT_16( st->tilt_wb_fx, 1024 ) ) + { + st->tilt_wb_fx = 1024; + move16(); + } + } + ELSE + { + IF( GT_16( st->tilt_wb_fx, 8192 ) ) + { + IF( st->prev_fractive == 0 ) + { + st->tilt_wb_fx = 8192; + move16(); + } + ELSE + { + st->tilt_wb_fx = 16384; + move16(); + } + } + ELSE + { + st->tilt_wb_fx = shl( st->tilt_wb_fx, 2 ); + move16(); + } + } + + IF( ener_fx != 0 ) + { + L_tmp = L_shl( L_mult0( ener_fx, st->tilt_wb_fx ), sub( st->Q_syn2, 13 ) ); /* 2+11 +st->Q_syn2 -13 = st->Q_syn2*/ + exp_ener = norm_s( ener_fx ); + tmp = shl( ener_fx, exp_ener ); /*Q(2+exp)*/ + inv_ener = shr( div_s( 16384, tmp ), 1 ); /*Q(15+14-2-exp-1) = 26 - exp*/ + + test(); + IF( GT_32( L_tmp, st->enerLH_fx ) ) /*st->Q_syn2*/ + { + st->tilt_wb_fx = extract_h( L_shr_sat( Mult_32_16( st->enerLH_fx, inv_ener ), sub( sub( st->Q_syn2, exp_ener ), 16 ) ) ); /*Q11*/ + move16(); + /*st->Q_syn2 -1 + 26- exp_ener -15 -(st->Q_syn2 -exp_ener -16 ) -16 +1 -1 = (11) *0.5*/ + } + ELSE IF( LT_32( L_tmp, Mult_32_16( st->enerLH_fx, 1638 ) ) && EQ_16( is_fractive, 1 ) ) + { + st->tilt_wb_fx = extract_h( L_shr_sat( Mult_32_16( st->enerLH_fx, inv_ener ), sub( sub( st->Q_syn2, exp_ener ), 15 ) ) ); /*Q11*/ + move16(); + /*st->Q_syn2 -1 + 26- exp_ener -15 -(st->Q_syn2 -exp_ener -15 ) -16 = (11) 0.25*/ + } + L_tmp = L_mult0( st->prev_ener_shb_fx, inv_ener ); /*Q(1+15+14-3-exp_ener) = 27 -exp_ener*/ + GainFrame_prevfrm_fx = L_shr( L_tmp, sub( 9, exp_ener ) ); /*27 -exp_ener -(9-exp_ener )= Q18*/ + } + ELSE + { + GainFrame_prevfrm_fx = 0; + move32(); + } + + IF( EQ_16( is_fractive, 1 ) ) + { + GainFrame_fx = L_shl( L_deposit_l( st->tilt_wb_fx ), 10 ); + } + ELSE + { + GainFrame_fx = L_shl( L_deposit_l( st->tilt_wb_fx ), 8 ); + } + + test(); + IF( EQ_16( ( is_fractive & st->prev_fractive ), 1 ) && GT_32( GainFrame_fx, GainFrame_prevfrm_fx ) ) + { + GainFrame_fx = L_add( Mult_32_16( GainFrame_prevfrm_fx, 26214 ), Mult_32_16( GainFrame_fx, 6554 ) ); /* 18 +15 -15 = 18*/ + } + ELSE + { + test(); + test(); + test(); + test(); + IF( ( LT_32( L_shr( st->prev_enerLH_fx, 1 ), st->enerLH_fx ) && GT_32( st->prev_enerLH_fx, L_shr( st->enerLH_fx, 1 ) ) ) && ( LT_32( L_shr( st->prev_enerLL_fx, 1 ), st->enerLL_fx ) && GT_32( st->prev_enerLL_fx, L_shr( st->enerLL_fx, 1 ) ) ) && ( s_xor( is_fractive, st->prev_fractive ) == 0 ) ) + { + GainFrame_fx = L_add( L_shr( GainFrame_fx, 1 ), L_shr( GainFrame_prevfrm_fx, 1 ) ); + } + ELSE + { + test(); + IF( ( is_fractive == 0 ) && EQ_16( st->prev_fractive, 1 ) ) + { + L_tmp1 = L_shl( Mult_32_16( GainFrame_fx, 3277 ), 13 ); /* 31 */ + L_tmp = L_sub( 2147483647, L_tmp1 ); /* 31 */ + GainFrame_fx = L_add( Mult_32_32( GainFrame_fx, L_tmp ), Mult_32_32( GainFrame_prevfrm_fx, L_tmp1 ) ); /* 18 */ + } + ELSE + { + GainFrame_fx = L_add( L_shr( GainFrame_fx, 1 ), L_shr( L_min( GainFrame_prevfrm_fx, GainFrame_fx ), 1 ) ); /* 18 */ + } + } + } + + GainFrame_fx = Mult_32_16( GainFrame_fx, i_mult( sub( N_WS2N_FRAMES, st->bws_cnt ), 819 ) ); /*Q18*/ + } + ELSE + { + IF( st->bws_cnt1 > 0 ) + { + GainFrame_fx = Mult_32_16( GainFrame_fx, i_mult( st->bws_cnt1, 819 ) ); /*Q18*/ + } + IF( GE_16( st->nbLostCmpt, 1 ) ) + { + ener_fx = s_max( 1, ener_fx ); + exp_ener = norm_s( ener_fx ); + tmp = shl( ener_fx, exp_ener ); /*Q(2+exp)*/ + inv_ener = div_s( 16384, tmp ); /*Q(15+14-2-exp)*/ + prev_ener_ratio_fx = L_shr( L_mult0( st->prev_ener_shb_fx, inv_ener ), add( sub( 9, exp_ener ), 1 ) ); /*Q: 1+27-exp-9+exp-1 = 18 */ + } + + IF( EQ_16( st->nbLostCmpt, 1 ) ) + { + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + IF( ( st->clas_dec != UNVOICED_CLAS ) && NE_16( st->clas_dec, UNVOICED_TRANSITION ) && LT_16( hBWE_TD->tilt_swb_fec_fx, 16384 ) && + ( ( GT_32( st->enerLL_fx, L_shr( st->prev_enerLL_fx, 1 ) ) && LT_32( L_shr( st->enerLL_fx, 1 ), st->prev_enerLL_fx ) ) || ( GT_32( st->enerLH_fx, L_shr( st->prev_enerLH_fx, 1 ) ) && LT_32( L_shr( st->enerLH_fx, 1 ), st->prev_enerLH_fx ) ) ) ) + { + IF( GT_32( L_shr( prev_ener_ratio_fx, 2 ), GainFrame_fx ) ) /*18*/ + { + GainFrame_fx = L_add( Mult_32_16( prev_ener_ratio_fx, 13107 ), Mult_32_16( GainFrame_fx, 19661 ) ); /*18*/ + } + ELSE IF( GT_32( L_shr( prev_ener_ratio_fx, 1 ), GainFrame_fx ) ) + { + GainFrame_fx = L_add( Mult_32_16( prev_ener_ratio_fx, 26214 ), Mult_32_16( GainFrame_fx, 6554 ) ); + } + ELSE + { + GainFrame_fx = L_add( Mult_32_16( prev_ener_ratio_fx, 6554 ), Mult_32_16( GainFrame_fx, 26214 ) ); + } + + test(); + IF( GT_16( tilt_swb_fec_fx, hBWE_TD->tilt_swb_fec_fx ) && ( hBWE_TD->tilt_swb_fec_fx > 0 ) ) + { + exp = norm_s( hBWE_TD->tilt_swb_fec_fx ); + tmp = shl( hBWE_TD->tilt_swb_fec_fx, exp ); /*Q(11+exp)*/ + tmp = div_s( 16384, tmp ); /*Q(15+14-11-exp)*/ + tmp = extract_h( L_shl( L_mult0( tmp, st->tilt_wb_fx ), sub( exp, 1 ) ) ); /*18 -exp +11 + exp -1 -16 =12; */ + GainFrame_fx = L_shl( Mult_32_16( GainFrame_fx, s_min( tmp, 20480 ) ), 3 ); /*Q18 = 18 +12 -15 +3 */ + } + } + ELSE IF( ( ( st->clas_dec != UNVOICED_CLAS ) || GT_16( hBWE_TD->tilt_swb_fec_fx, 4096 ) ) && GT_32( L_shr( prev_ener_ratio_fx, 2 ), GainFrame_fx ) && + ( GT_32( st->enerLL_fx, L_shr( st->prev_enerLL_fx, 1 ) ) || GT_32( st->enerLH_fx, L_shr( st->prev_enerLH_fx, 1 ) ) ) ) + { + GainFrame_fx = L_add( Mult_32_16( prev_ener_ratio_fx, 6554 ), Mult_32_16( GainFrame_fx, 26214 ) ); + } + } + ELSE IF( GT_16( st->nbLostCmpt, 1 ) ) + { + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + IF( GT_32( L_shr( prev_ener_ratio_fx, 2 ), GainFrame_fx ) && ( ( EQ_16( st->codec_mode, MODE1 ) && GT_32( st->enerLL_fx, st->prev_enerLL_fx ) && GT_32( st->enerLH_fx, st->prev_enerLH_fx ) ) || EQ_16( st->codec_mode, MODE2 ) ) ) + { + test(); + IF( GT_16( tilt_swb_fec_fx, 20480 /*10.0f in Q11*/ ) && GT_16( hBWE_TD->tilt_swb_fec_fx, 20480 /*10.0f in Q11*/ ) ) + { + GainFrame_fx = L_min( L_add( Mult_32_16( prev_ener_ratio_fx, 26214 /*0.8f in Q15*/ ), Mult_32_16( GainFrame_fx, 6554 /*0.2f in Q15*/ ) ), L_shl( Mult_32_16( GainFrame_fx, 16384 /*4.0f in Q12*/ ), 3 ) ); /*Q18*/ + } + ELSE + { + GainFrame_fx = L_min( L_add( Mult_32_16( prev_ener_ratio_fx, 16384 ), Mult_32_16( GainFrame_fx, 16384 ) ), L_shl( Mult_32_16( GainFrame_fx, 16384 ), 3 ) ); /*Q18*/ + } + } + ELSE IF( GT_32( prev_ener_ratio_fx, GainFrame_fx ) && ( ( EQ_16( st->codec_mode, MODE1 ) && GT_32( st->enerLL_fx, st->prev_enerLL_fx ) && GT_32( st->enerLH_fx, st->prev_enerLH_fx ) ) || EQ_16( st->codec_mode, MODE2 ) ) ) + { + test(); + IF( GT_16( tilt_swb_fec_fx, 20480 ) && GT_16( hBWE_TD->tilt_swb_fec_fx, 20480 ) ) + { + GainFrame_fx = L_add( Mult_32_16( prev_ener_ratio_fx, 16384 /*0.5f in Q15*/ ), Mult_32_16( GainFrame_fx, 16384 /*0.5f in Q15*/ ) ); /* Q18 */ + } + ELSE + { + GainFrame_fx = L_add( Mult_32_16( prev_ener_ratio_fx, 6554 /*0.2f in Q15*/ ), Mult_32_16( GainFrame_fx, 26214 /*0.8f in Q15*/ ) ); /* Q18 */ + } + } + } + } + + st->prev_fractive = is_fractive; + move16(); + + /* Adjust the subframe and frame gain of the synthesized shb signal */ + /* Scale the shaped excitation */ + IF( EQ_16( st->L_frame, L_FRAME ) ) + { + L_tmp = L_mult( pitch_buf_fx[0], 8192 ); + FOR( i = 1; i < NB_SUBFR; i++ ) + { + L_tmp = L_mac( L_tmp, pitch_buf_fx[i], 8192 ); /* pitch_buf in Q6 x 0.25 in Q15 */ + } + pitch_fx = round_fx( L_tmp ); /* Q6 */ + } + ELSE + { + L_tmp = L_mult( pitch_buf_fx[0], 6554 ); + FOR( i = 1; i < NB_SUBFR16k; i++ ) + { + L_tmp = L_mac( L_tmp, pitch_buf_fx[i], 6554 ); /* pitch_buf in Q6 x 0.2 in Q15 */ + } + pitch_fx = round_fx( L_tmp ); /* Q6 */ + } + + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + IF( ( ( GE_32( st->extl_brate, SWB_TBE_2k8 ) && EQ_16( st->prev_coder_type, st->coder_type ) && NE_16( st->coder_type, UNVOICED ) ) || ( LT_32( st->extl_brate, SWB_TBE_2k8 ) && ( EQ_16( st->prev_coder_type, st->coder_type ) || ( EQ_16( st->prev_coder_type, VOICED ) && EQ_16( st->coder_type, GENERIC ) ) || ( EQ_16( st->prev_coder_type, GENERIC ) && EQ_16( st->coder_type, VOICED ) ) ) ) ) && GT_16( pitch_fx, 4480 /*70 in Q6*/ ) && LT_16( st->extl, FB_TBE ) && NE_32( st->extl_brate, SWB_TBE_1k10 ) && NE_32( st->extl_brate, SWB_TBE_1k75 ) ) + { + FOR( i = 0; i < NUM_SHB_SUBGAINS; i++ ) + { + GainShape_tmp_fx[i] = GainShape_fx[i * 4]; /* Q15 */ + move16(); + } + + FOR( i = 0; i < NUM_SHB_SUBGAINS; i++ ) + { + L_tmp1 = Mult_32_16( ener_tmp_fx[i], GainShape_tmp_fx[i] ); /* (2*Q_bwe_exc) */ + L_tmp2 = Mult_32_16( hBWE_TD->prev_ener_fx, hBWE_TD->prev_GainShape_fx ); /* (2*st->prev_ener_fx_Q) */ + tmp = sub( shl( Q_bwe_exc, 1 ), shl( st->prev_ener_fx_Q, 1 ) ); + L_tmp2 = L_shl_sat( L_tmp2, tmp ); /* new Q = (2*Q_bwe_exc) */ + IF( GT_32( L_tmp1, L_tmp2 ) ) + { + L_tmp = L_tmp2; + move32(); + if ( L_tmp2 < 0 ) + { + L_tmp = L_negate( L_tmp2 ); + } + + expb = norm_l( L_tmp ); + fracb = round_fx_sat( L_shl_sat( L_tmp, expb ) ); + expb = sub( 30, expb ); /* - (2*Q_bwe_exc_ext); */ + + expa = norm_l( ener_tmp_fx[i] ); + fraca = extract_h( L_shl( ener_tmp_fx[i], expa ) ); + expa = sub( 30, expa ); + + scale_fx = shr( sub( fraca, fracb ), 15 ); + fracb = shl( fracb, scale_fx ); + expb = sub( expb, scale_fx ); + + tmp = div_s( fracb, fraca ); + exp = sub( sub( expb, expa ), 1 ); + tmp = shl( tmp, exp ); + GainShape_tmp_fx[i] = add( tmp, shr( GainShape_tmp_fx[i], 1 ) ); /* Q15 */ + move16(); + } + + hBWE_TD->prev_ener_fx = ener_tmp_fx[i]; + move32(); + hBWE_TD->prev_GainShape_fx = GainShape_tmp_fx[i]; + move16(); + st->prev_ener_fx_Q = Q_bwe_exc; + move16(); + } + + FOR( i = 0; i < NUM_SHB_SUBFR; i++ ) + { + Word16 idx = 0; + move16(); + IF( i != 0 ) + { + idx = idiv1616( i_mult( i, NUM_SHB_SUBGAINS ), NUM_SHB_SUBFR ); + } + GainShape_fx[i] = GainShape_tmp_fx[idx]; + move16(); + } + } + ELSE + { + st->prev_ener_fx_Q = Q_bwe_exc; + move16(); + } + st->prev_Q_bwe_syn = Q_bwe_exc; + move16(); + + + /* Gain shape smoothing after quantization */ + test(); + IF( EQ_32( st->extl_brate, SWB_TBE_1k10 ) || EQ_32( st->extl_brate, SWB_TBE_1k75 ) ) + { + FOR( i = 0; i < NUM_SHB_SUBGAINS; i++ ) + { + GainShape_tmp_fx[i] = GainShape_fx[i * NUM_SHB_SUBGAINS]; + move16(); + } + + lls_interp_n_fx( GainShape_tmp_fx, NUM_SHB_SUBGAINS, &GainShape_tilt_fx, &temp_fx, 1 ); + + test(); + IF( GE_16( vind, 6 ) && LT_16( abs_s( GainShape_tilt_fx ), 3932 ) ) + { + feedback_fx = 9830; + move16(); + FOR( i = 0; i < NUM_SHB_SUBGAINS; i++ ) + { + GainShape_fx[i] = add_sat( mult( sub( 32767, feedback_fx ), GainShape_fx[i * NUM_SHB_SUBGAINS] ), mult( feedback_fx, GainShape_tmp_fx[i] ) ); + move16(); + } + + FOR( i = NUM_SHB_SUBFR - 1; i > 0; i-- ) + { + Word16 idx = 0; + move16(); + IF( i != 0 ) + { + idx = idiv1616( i_mult( i, NUM_SHB_SUBGAINS ), NUM_SHB_SUBFR ); + } + GainShape_fx[i] = GainShape_fx[idx]; + move16(); + } + } + } + + /* fil-in missing memory */ + test(); + test(); + IF( ( EQ_16( st->element_mode, IVAS_CPE_TD ) || EQ_16( st->element_mode, IVAS_CPE_DFT ) ) && LE_32( st->last_core_brate, SID_2k40 ) ) + { + FOR( i = 0; i < L_SHB_LAHEAD; i++ ) + { + Word16 intermediate = mult( shaped_shb_excitation_fx[i], subwin_shb_fx[L_SHB_LAHEAD - i] ); + Word32 intermediate_32 = Mpy_32_16_1( Mpy_32_16_1( GainFrame_fx, window_shb_fx[L_SHB_LAHEAD - 1 - i] ), intermediate ); + hBWE_TD->syn_overlap_fx[i] = round_fx( L_shl_sat( intermediate_32, sub( 16, ( add( Q_bwe_exc, 18 - 15 ) ) ) ) ); + move16(); + } + } + + Word16 n_mem3_new = 0; + move16(); + find_max_mem_dec_m3( st, &n_mem3_new ); + + ScaleShapedSHB_fx( SHB_OVERLAP_LEN, + shaped_shb_excitation_fx, /* i/o: Q_bwe_exc */ + hBWE_TD->syn_overlap_fx, + GainShape_fx, /* Q15 */ + GainFrame_fx, /* Q18 */ + window_shb_fx, + subwin_shb_fx, + &Q_bwe_exc, &Qx, n_mem3_new, st->prev_Q_bwe_syn2 ); + + IF( hStereoICBWE != NULL ) + { + Copy_Scale_sig_16_32_DEPREC( lpc_shb_fx, hStereoICBWE->lpSHBRef_fx, LPC_SHB_ORDER + 1, 0 ); + Copy( GainShape_fx, hStereoICBWE->gshapeRef_fx, NUM_SHB_SUBFR ); + hStereoICBWE->gFrameRef_fx = GainFrame_fx; + move32(); + + Copy( shaped_shb_excitation_fx, hStereoICBWE->shbSynthRef_fx, L_FRAME16k ); + } + + max_val = 0; + move16(); + FOR( i = 0; i < L_FRAME16k; i++ ) + { + max_val = s_max( max_val, abs_s( shaped_shb_excitation_fx[i] ) ); /* Q0 */ + } + IF( max_val == 0 ) + { + curr_frame_pow_fx = 0; + move32(); + n = 0; + move16(); + } + ELSE + { + n = norm_s( max_val ); + max_val = 0; + move16(); + FOR( i = 0; i < L_FRAME16k; i++ ) + { + shaped_shb_excitation_frac[i] = shl_sat( shaped_shb_excitation_fx[i], n ); /*Q_bwe_exc+n*/ + move16(); + } + + curr_frame_pow_fx = 0; + move32(); + FOR( i = 0; i < L_FRAME16k; i++ ) + { + L_tmp = L_mult0( shaped_shb_excitation_frac[i], shaped_shb_excitation_frac[i] ); /*2*(Q_bwe_exc+n)*/ + curr_frame_pow_fx = L_add( curr_frame_pow_fx, L_shr( L_tmp, 9 ) ); /*2*(Q_bwe_exc+n)-9*/ + } + } + curr_frame_pow_exp = sub( shl( add( Q_bwe_exc, n ), 1 ), 9 ); + tmp = sub( st->prev_frame_pow_exp, curr_frame_pow_exp ); + IF( tmp > 0 ) /* shifting prev */ + { + IF( GT_16( tmp, 32 ) ) + { + st->prev_frame_pow_exp = add( curr_frame_pow_exp, 32 ); + move16(); + tmp = 32; + move16(); + } + hBWE_TD->prev_swb_bwe_frame_pow_fx = L_shr( hBWE_TD->prev_swb_bwe_frame_pow_fx, tmp ); + move32(); + st->prev_frame_pow_exp = curr_frame_pow_exp; + move16(); + } + ELSE /* shifting curr */ + { + IF( LT_16( tmp, -32 ) ) + { + curr_frame_pow_exp = sub( st->prev_frame_pow_exp, 32 ); + tmp = -32; + move16(); + } + curr_frame_pow_fx = L_shr( curr_frame_pow_fx, -tmp ); + curr_frame_pow_exp = st->prev_frame_pow_exp; + move16(); + } + test(); + test(); + IF( !st->bfi && ( st->prev_bfi || st->prev_use_partial_copy ) ) + { + test(); + test(); + IF( ( GT_32( L_shr( curr_frame_pow_fx, 1 ), hBWE_TD->prev_swb_bwe_frame_pow_fx ) ) && + ( GT_32( hBWE_TD->prev_swb_bwe_frame_pow_fx, L_tmp ) ) && EQ_16( st->prev_coder_type, UNVOICED ) ) + { + L_tmp = root_a_over_b_fx( hBWE_TD->prev_swb_bwe_frame_pow_fx, curr_frame_pow_exp, curr_frame_pow_fx, curr_frame_pow_exp, &exp ); + scale_fx = round_fx( L_shl( L_tmp, exp ) ); /*Q15*/ + + L_tmp = root_a_fx( L_tmp, sub( 31, exp ), &exp ); + L_tmp = root_a_fx( L_tmp, sub( 31, exp ), &exp ); + L_tmp = root_a_fx( L_tmp, sub( 31, exp ), &exp ); + temp_fx = round_fx( L_shl( L_tmp, exp ) ); /*Q15*/ + } + ELSE + { + scale_fx = temp_fx = 32767; + move16(); /*Q15*/ + move16(); /*Q15*/ + } + + FOR( j = 0; j < 8; j++ ) + { + GainShape_fx[2 * j] = mult_r( GainShape_fx[2 * j], scale_fx ); + move16(); + GainShape_fx[2 * j + 1] = mult_r( GainShape_fx[2 * j + 1], scale_fx ); + move16(); + FOR( i = 0; i < L_FRAME16k / 8; i++ ) + { + shaped_shb_excitation_fx[add( i, j * ( L_FRAME16k / 8 ) )] = mult_r( shaped_shb_excitation_fx[add( i, j * ( L_FRAME16k / 8 ) )], scale_fx ); + move16(); + } + + IF( temp_fx > 0 ) + { + /* scale_fx <= temp_fx, due to scale_fx = sqrt( st->prev_swb_bwe_frame_pow_fx/curr_frame_pow_fx ), temp_fx = sqrt( scale_fx, 1.f/8.f ) + and curr_frame_pow_fx > st->prev_swb_bwe_frame_pow_fx -> scale_fx <= 1.0, sqrt(scale_fx, 1.f/8.f) >= scale_fx */ + IF( LT_16( scale_fx, temp_fx ) ) + { + scale_fx = div_s( scale_fx, temp_fx ); + } + ELSE + { + scale_fx = 32767; + move16(); + } + } + ELSE + { + scale_fx = 0; + move16(); + } + } + } + + /* adjust the FEC frame energy */ + IF( st->bfi ) + { + scale_fx = temp_fx = 4096; + move16(); /*Q12*/ + move16(); + IF( EQ_16( st->nbLostCmpt, 1 ) ) + { + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + IF( GT_32( curr_frame_pow_fx, hBWE_TD->prev_swb_bwe_frame_pow_fx ) && + NE_16( st->prev_coder_type, UNVOICED ) && + ( st->last_good != UNVOICED_CLAS ) ) + { + L_tmp = root_a_over_b_fx( hBWE_TD->prev_swb_bwe_frame_pow_fx, curr_frame_pow_exp, curr_frame_pow_fx, curr_frame_pow_exp, &exp ); /*31 - exp*/ + scale_fx = round_fx( L_shl( L_tmp, sub( exp, 3 ) ) ); /*Q12*/ + L_tmp = root_a_fx( L_tmp, sub( 31, exp ), &exp ); + L_tmp = root_a_fx( L_tmp, sub( 31, exp ), &exp ); + L_tmp = root_a_fx( L_tmp, sub( 31, exp ), &exp ); + temp_fx = round_fx( L_shl( L_tmp, sub( exp, 3 ) ) ); /*Q12*/ + } + ELSE IF( LT_32( curr_frame_pow_fx, L_shr( hBWE_TD->prev_swb_bwe_frame_pow_fx, 1 ) ) && EQ_16( st->nbLostCmpt, 1 ) && + ( GT_32( st->enerLL_fx, L_shr( st->prev_enerLL_fx, 1 ) ) || GT_32( st->enerLH_fx, L_shr( st->prev_enerLH_fx, 1 ) ) ) && + ( EQ_16( st->prev_coder_type, UNVOICED ) || ( st->last_good == UNVOICED_CLAS ) || GT_16( hBWE_TD->tilt_swb_fec_fx, 10240 ) ) ) + { + L_tmp = root_a_over_b_fx( hBWE_TD->prev_swb_bwe_frame_pow_fx, curr_frame_pow_exp, curr_frame_pow_fx, curr_frame_pow_exp, &exp ); + scale_fx = round_fx_sat( L_shl_sat( L_tmp, sub( exp, 3 ) ) ); /*Q12*/ + L_tmp = root_a_fx( L_tmp, sub( 31, exp ), &exp ); + L_tmp = root_a_fx( L_tmp, sub( 31, exp ), &exp ); + L_tmp = root_a_fx( L_tmp, sub( 31, exp ), &exp ); + temp_fx = round_fx( L_shl( L_tmp, sub( exp, 3 ) ) ); /*Q12*/ + } + } + ELSE IF( GT_16( st->nbLostCmpt, 1 ) ) + { + test(); + test(); + test(); + test(); + test(); + IF( GT_32( curr_frame_pow_fx, hBWE_TD->prev_swb_bwe_frame_pow_fx ) ) + { + L_tmp = root_a_over_b_fx( hBWE_TD->prev_swb_bwe_frame_pow_fx, curr_frame_pow_exp, curr_frame_pow_fx, curr_frame_pow_exp, &exp ); + scale_fx = round_fx( L_shl( L_tmp, sub( exp, 3 ) ) ); /*Q12*/ + L_tmp = root_a_fx( L_tmp, sub( 31, exp ), &exp ); + L_tmp = root_a_fx( L_tmp, sub( 31, exp ), &exp ); + L_tmp = root_a_fx( L_tmp, sub( 31, exp ), &exp ); + temp_fx = round_fx_sat( L_shl_sat( L_tmp, sub( exp, 3 ) ) ); /*Q12*/ + } + ELSE IF( LT_32( curr_frame_pow_fx, L_shr( hBWE_TD->prev_swb_bwe_frame_pow_fx, 1 ) ) && + ( GT_32( st->enerLL_fx, L_shr( st->prev_enerLL_fx, 1 ) ) || GT_32( st->enerLH_fx, L_shr( st->prev_enerLH_fx, 1 ) ) ) && + ( EQ_16( st->prev_coder_type, UNVOICED ) || ( st->last_good == UNVOICED_CLAS ) || GT_16( hBWE_TD->tilt_swb_fec_fx, 10240 ) ) ) + { + L_tmp = root_a_over_b_fx( hBWE_TD->prev_swb_bwe_frame_pow_fx, curr_frame_pow_exp, curr_frame_pow_fx, curr_frame_pow_exp, &exp ); + L_tmp = L_min( L_tmp, L_shl_sat( 2, sub( 31, exp ) ) ); /*31 - exp*/ + scale_fx = round_fx( L_shl( L_tmp, sub( exp, 3 ) ) ); /*Q12*/ + L_tmp = root_a_fx( L_tmp, sub( 31, exp ), &exp ); + L_tmp = root_a_fx( L_tmp, sub( 31, exp ), &exp ); + L_tmp = root_a_fx( L_tmp, sub( 31, exp ), &exp ); + temp_fx = round_fx( L_shl( L_tmp, sub( exp, 3 ) ) ); /*Q12*/ + } + } + + FOR( j = 0; j < 8; j++ ) + { + GainShape_fx[2 * j] = shl_sat( mult_r( GainShape_fx[2 * j], scale_fx ), 3 ); + move16(); /* 15 +12 +3-15 =15*/ + GainShape_fx[add( 2 * j, 1 )] = shl_sat( mult_r( GainShape_fx[add( 2 * j, 1 )], scale_fx ), 3 ); + move16(); + FOR( i = 0; i < 40; i++ ) + { + shaped_shb_excitation_fx[i + j * L_FRAME16k / 8] = shl( mult_r( shaped_shb_excitation_fx[i + j * L_FRAME16k / 8], scale_fx ), 3 ); + move16(); /* Q_bwe_exc +12+3 -15 =Q_bwe_exc*/ + } + + IF( temp_fx > 0 ) + { + IF( LT_16( scale_fx, temp_fx ) ) + { + scale_fx = shr( div_s( scale_fx, temp_fx ), 3 ); + } + ELSE + { + tmp1 = sub( norm_s( scale_fx ), 1 ); + tmp2 = norm_s( temp_fx ); + scale_fx = div_s( shl( scale_fx, tmp1 ), shl( temp_fx, tmp2 ) ); + scale_fx = shr( scale_fx, add( sub( tmp1, tmp2 ), 3 ) ); + } + } + ELSE + { + scale_fx = 0; + move16(); + } + } + } + + hBWE_TD->prev_swb_bwe_frame_pow_fx = curr_frame_pow_fx; + move32(); + st->prev_frame_pow_exp = curr_frame_pow_exp; + move16(); + + Word64 prev_ener_shb64 = 0; + move64(); + FOR( i = 0; i < L_FRAME16k; i++ ) + { + prev_ener_shb64 = W_mac0_16_16( prev_ener_shb64, shaped_shb_excitation_fx[i], shaped_shb_excitation_fx[i] ); /* Q0 */ + } + L_prev_ener_shb = W_sat_l( prev_ener_shb64 ); + + L_prev_ener_shb = Mult_32_16( L_prev_ener_shb, 26214 ); /* 2*Q_bwe_exc_mod+8; 26214=(1/L_FRAME16k) in Q23 */ + st->prev_ener_shb_fx = 0; + move16(); + IF( L_prev_ener_shb != 0 ) + { + exp = norm_l( L_prev_ener_shb ); + tmp = extract_h( L_shl( L_prev_ener_shb, exp ) ); + exp = sub( exp, sub( 30, ( add( i_mult( 2, Q_bwe_exc ), 8 ) ) ) ); + + tmp = div_s( 16384, tmp ); + L_tmp = L_deposit_h( tmp ); + L_tmp = Isqrt_lc( L_tmp, &exp ); + st->prev_ener_shb_fx = round_fx_sat( L_shl_sat( L_tmp, sub( exp, 14 ) ) ); /* Q1 */ + move16(); + } + + IF( st->hBWE_FD != NULL ) + { + L_tmp = Mult_32_16( curr_frame_pow_fx, 26214 ); /* curr_frame_pow_exp+8; 26214=(1/L_FRAME16k) in Q23 */ + tmp = 0; + move16(); + IF( L_tmp != 0 ) + { + exp = norm_l( L_tmp ); + tmp = extract_h( L_shl( L_tmp, exp ) ); + exp = sub( exp, sub( 30, add( curr_frame_pow_exp, 8 ) ) ); + + tmp = div_s( 16384, tmp ); + L_tmp = L_deposit_h( tmp ); + L_tmp = Isqrt_lc( L_tmp, &exp ); + tmp = round_fx_sat( L_shl_sat( L_tmp, sub( exp, 14 ) ) ); /* Q1 */ + } + set16_fx( st->prev_SWB_fenv_fx, tmp, SWB_FENV ); /* Q1 */ + } + + FOR( i = 0; i < L_FRAME16k; i++ ) + { + shaped_shb_excitation_fx_32[i] = L_shl( shaped_shb_excitation_fx[i], sub( Q11, Q_bwe_exc ) ); + move32(); + } + + /* generate 32kHz SHB synthesis from 12.8(16)kHz signal */ + GenSHBSynth_fx_32( shaped_shb_excitation_fx_32, error_fx, hBWE_TD->genSHBsynth_Hilbert_Mem_fx, hBWE_TD->genSHBsynth_state_lsyn_filt_shb_local_fx_32, st->L_frame, &( hBWE_TD->syn_dm_phase ) ); + Copy_Scale_sig_32_16( st->hBWE_TD->genSHBsynth_state_lsyn_filt_shb_local_fx_32, st->hBWE_TD->genSHBsynth_state_lsyn_filt_shb_local_fx, 2 * ALLPASSSECTIONS_STEEP, -( Q11 - Q_bwe_exc ) ); + Copy32( error_fx + L_FRAME32k - L_SHB_TRANSITION_LENGTH, hBWE_TD->old_tbe_synth_fx_32, L_SHB_TRANSITION_LENGTH ); + + /* resample SHB synthesis (if needed) and scale down */ + synth_scale_fx = 32767; + move16(); /* 1.0 in Q15 */ + if ( EQ_16( st->codec_mode, MODE1 ) ) + { + synth_scale_fx = 29491; + move16(); /* 0.9 in Q15 */ + } + + IF( EQ_32( st->output_Fs, 48000 ) ) + { + IF( EQ_16( st->extl, FB_TBE ) ) + { + tmp = norm_l( GainFrame_fx ); + if ( GainFrame_fx == 0 ) + { + tmp = 31; + move16(); + } + L_tmp = L_shl( GainFrame_fx, tmp ); /* 18 + tmp */ + + tmp1 = 0; + move16(); + FOR( i = 0; i < L_FRAME16k; i++ ) + { + Word16 idx = 0; + move16(); + IF( i != 0 ) + { + idx = idiv1616( i_mult( NUM_SHB_SUBFR, i ), L_FRAME16k ); + } + L_tmp1 = Mult_32_16( L_tmp, GainShape_fx[idx] ); /* Q : 18 + tmp +15 -15*/ + White_exc16k_fx[i] = round_fx( Mult_32_16( L_tmp1, White_exc16k_fx[i] ) ); /* 18 + tmp +*Q_white_exc -15 -16 */ + move16(); + tmp1 = s_max( tmp1, abs_s( White_exc16k_fx[i] ) ); + } + + *Q_white_exc = sub( add( *Q_white_exc, tmp ), 13 ); /* *Q_white_exc + 18 + tmp -15 -16 */ + move16(); + tmp = norm_s( tmp1 ); + if ( tmp1 == 0 ) + { + tmp = 15; + move16(); + } + + FOR( i = 0; i < L_FRAME16k; i++ ) + { + White_exc16k_fx[i] = shl( White_exc16k_fx[i], sub( tmp, 1 ) ); + move16(); + } + *Q_white_exc = sub( add( *Q_white_exc, tmp ), 1 ); + move16(); + } + + IF( NE_16( synth_scale_fx, 32767 ) ) /* 1.0 in Q15 */ + { + FOR( i = 0; i < L_FRAME32k; i++ ) + { + error_fx[i] = Mpy_32_16_1( error_fx[i], synth_scale_fx ); + move32(); + } + } + interpolate_3_over_2_allpass_32( error_fx, L_FRAME32k, synth_fx, hBWE_TD->int_3_over_2_tbemem_dec_fx_32 ); + } + ELSE IF( EQ_32( st->output_Fs, 32000 ) ) + { + IF( NE_16( synth_scale_fx, 32767 ) ) /* 1.0 in Q15 */ + { + FOR( i = 0; i < L_FRAME32k; i++ ) + { + synth_fx[i] = Mpy_32_16_1( error_fx[i], synth_scale_fx ); + move32(); /*Qx*/ + } + } + ELSE + { + Copy32( error_fx, synth_fx, L_FRAME32k ); + } + } + ELSE IF( EQ_32( st->output_Fs, 16000 ) ) + { + IF( NE_16( synth_scale_fx, 32767 ) ) /* 1.0 in Q15 */ + { + FOR( i = 0; i < L_FRAME32k; i++ ) + { + error_fx[i] = Mpy_32_16_1( error_fx[i], synth_scale_fx ); + move32(); + } + } + + Decimate_allpass_steep_fx32( error_fx, hBWE_TD->mem_resamp_HB_32k_fx_32, L_FRAME32k, synth_fx ); + } + + + /* Update previous frame parameters for FEC */ + Copy( lsf_shb_fx, hBWE_TD->lsp_prevfrm_fx, LPC_SHB_ORDER ); + IF( EQ_16( st->codec_mode, MODE1 ) ) + { + hBWE_TD->GainFrame_prevfrm_fx = GainFrame_fx; + move32(); /*Q18*/ + hBWE_TD->tilt_swb_fec_fx = tilt_swb_fec_fx; + move16(); + + if ( !st->bfi ) + { + hBWE_TD->GainAttn_fx = 32767; /*1.0f in Q15*/ + move16(); + } + } + ELSE + { + IF( !st->bfi ) + { + hBWE_TD->GainFrame_prevfrm_fx = GainFrame_fx; + move32(); /*Q18*/ + hBWE_TD->tilt_swb_fec_fx = tilt_swb_fec_fx; + move16(); + hBWE_TD->GainAttn_fx = 32767; /*1.0f in Q15*/ + move16(); + } + } + + hBWE_TD->prev_ener_fx = ener_tmp_fx[NUM_SHB_SUBGAINS - 1]; + move32(); + hBWE_TD->prev_GainShape_fx = GainShape_fx[NUM_SHB_SUBFR - 1]; + move16(); + st->prev_Q_bwe_syn2 = Q_bwe_exc; + move16(); + st->prev_Qx = Q_bwe_exc; + move16(); + + return; +} + +void GenTransition_fixed( + TD_BWE_DEC_HANDLE hBWE_TD, /* i/o: TD BWE data handle */ + Word32 *outputHB_fx, /* o : synthesized HB transitions signal : Q11 */ + const Word32 output_Fs, /* i : output sampling rate : Q0 */ + const Word16 element_mode, /* i : element mode : Q0 */ + const Word16 L_frame, /* i : ACELP frame length : Q0 */ + const Word16 rf_flag, /* i : RF flag : Q0 */ + const Word32 total_brate, /* i : total bitrate : Q0 */ + const Word16 prev_Qx ) +{ + Word16 i, length; + + Word32 syn_overlap_32k_fx[2 * SHB_OVERLAP_LEN]; + + /* set targeted length of transition signal */ + length = i_mult( 2, NS2SA_FX2( output_Fs, DELAY_BWE_TOTAL_NS ) ); + + /* upsample overlap snippet */ + Interpolate_allpass_steep_32( hBWE_TD->syn_overlap_fx_32, hBWE_TD->genSHBsynth_state_lsyn_filt_shb_local_fx_32, SHB_OVERLAP_LEN, syn_overlap_32k_fx ); + + /* perFORm spectral flip and downmix with overlap snippet to match HB synth */ + test(); + test(); + test(); + test(); + IF( ( ( element_mode == EVS_MONO ) && ( rf_flag || EQ_32( total_brate, ACELP_9k60 ) ) ) || ( ( element_mode > EVS_MONO ) && EQ_16( L_frame, L_FRAME ) ) ) + { + flip_and_downmix_generic_fx_32( syn_overlap_32k_fx, syn_overlap_32k_fx, 2 * SHB_OVERLAP_LEN, hBWE_TD->genSHBsynth_Hilbert_Mem_fx, hBWE_TD->genSHBsynth_Hilbert_Mem_fx + HILBERT_ORDER1, hBWE_TD->genSHBsynth_Hilbert_Mem_fx + ( HILBERT_ORDER1 + 2 * HILBERT_ORDER2 ), &( hBWE_TD->syn_dm_phase ) ); + } + ELSE + { + FOR( i = 0; i < 2 * SHB_OVERLAP_LEN; i++ ) + { + IF( i % 2 == 0 ) + { + syn_overlap_32k_fx[i] = L_negate( syn_overlap_32k_fx[i] ); + } + ELSE + { + syn_overlap_32k_fx[i] = syn_overlap_32k_fx[i]; + } + move32(); + } + } + + /* cross fade of overlap snippet and mirrored HB synth from previous frame */ + FOR( i = 0; i < 2 * L_SHB_LAHEAD; i++ ) + { + outputHB_fx[i] = L_add_sat( Mpy_32_16_1( hBWE_TD->old_tbe_synth_fx_32[L_SHB_TRANSITION_LENGTH - 1 - i], window_shb_32k_fx[i] ), Mpy_32_16_1( syn_overlap_32k_fx[i], window_shb_32k_fx[2 * L_SHB_LAHEAD - 1 - i] ) ); + move32(); + } + + /* fill transition signal with mirrored HB synth from previous frame to fully fill delay alignment buffer gap */ + FOR( ; i < length; i++ ) + { + outputHB_fx[i] = L_shl( hBWE_TD->old_tbe_synth_fx[L_SHB_TRANSITION_LENGTH - 1 - i], sub( Q11, prev_Qx ) ); + move32(); + } + + IF( EQ_32( output_Fs, 48000 ) ) + { + interpolate_3_over_2_allpass_32( outputHB_fx, length, outputHB_fx, hBWE_TD->int_3_over_2_tbemem_dec_fx_32 ); + } + ELSE IF( EQ_32( output_Fs, 16000 ) ) + { + Decimate_allpass_steep_fx32( outputHB_fx, hBWE_TD->mem_resamp_HB_32k_fx_32, L_FRAME32k, outputHB_fx ); + } + + return; +} +void GenTransition_WB_fixed( + TD_BWE_DEC_HANDLE hBWE_TD, /* i/o: TD BWE data handle */ + Word32 *outputHB_fx, /* o : synthesized HB transitions signal : Q11 */ + const Word32 output_Fs /* i : output sampling rate */ +) +{ + Word16 i, length; + Word32 speech_buf_16k1_fx[SHB_OVERLAP_LEN], speech_buf_16k2_fx[2 * SHB_OVERLAP_LEN]; + Word32 upsampled_synth_fx[L_FRAME48k]; + + /* set targeted length of transition signal */ + length = i_mult( 2, NS2SA_FX2( output_Fs, DELAY_BWE_TOTAL_NS ) ); + + /* upsample overlap snippet */ + Interpolate_allpass_steep_32( hBWE_TD->syn_overlap_fx_32, hBWE_TD->state_lsyn_filt_shb_fx_32, SHB_OVERLAP_LEN / 2, speech_buf_16k1_fx ); + Interpolate_allpass_steep_32( speech_buf_16k1_fx, hBWE_TD->state_lsyn_filt_dwn_shb_fx_32, SHB_OVERLAP_LEN, speech_buf_16k2_fx ); + + /* perform spectral flip and downmix with overlap snippet to match HB synth */ + FOR( i = 0; i < SHB_OVERLAP_LEN; i++ ) + { + IF( i % 2 == 0 ) + { + speech_buf_16k2_fx[i] = L_negate( speech_buf_16k2_fx[i] ); + move32(); + } + ELSE + { + speech_buf_16k2_fx[i] = speech_buf_16k2_fx[i]; + move32(); + } + } + + /* cross fade of overlap snippet and mirrored HB synth from previous frame */ + FOR( i = 0; i < L_SHB_LAHEAD; i++ ) + { + outputHB_fx[i] = L_add( Mpy_32_16_1( hBWE_TD->old_tbe_synth_fx_32[L_SHB_TRANSITION_LENGTH - 1 - i], window_shb_fx[i] ), Mpy_32_16_1( speech_buf_16k2_fx[i], window_shb_fx[L_SHB_LAHEAD - 1 - i] ) ); + move32(); + outputHB_fx[i] = Mpy_32_16_1( outputHB_fx[i], 21299 ); + move32(); + } + + /* fill transition signal with mirrored HB synth from previous frame to fully fill delay alignment buffer gap */ + FOR( ; i < length; i++ ) + { + outputHB_fx[i] = hBWE_TD->old_tbe_synth_fx_32[L_SHB_TRANSITION_LENGTH - 1 - i]; + move32(); + outputHB_fx[i] = Mpy_32_16_1( outputHB_fx[i], 21299 ); + move32(); + } + + /* upsampling if necessary */ + IF( EQ_32( output_Fs, 32000 ) ) + { + Interpolate_allpass_steep_32( outputHB_fx, hBWE_TD->mem_resamp_HB_fx_32, L_FRAME16k, upsampled_synth_fx ); + Copy32( upsampled_synth_fx, outputHB_fx, L_FRAME32k ); + } + ELSE IF( EQ_32( output_Fs, 48000 ) ) + { + interpolate_3_over_1_allpass_32( outputHB_fx, L_FRAME16k, upsampled_synth_fx, hBWE_TD->mem_resamp_HB_fx_32 ); + Copy32( upsampled_synth_fx, outputHB_fx, L_FRAME48k ); + } + + return; +} diff --git a/lib_dec/syn_outp.c b/lib_dec/syn_outp.c deleted file mode 100644 index 96ac16dbadfe6ace2cb07d1ed022dbc673e7e97a..0000000000000000000000000000000000000000 --- a/lib_dec/syn_outp.c +++ /dev/null @@ -1,49 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include -#include "cnst.h" -#include "prot.h" -#include "wmc_auto.h" - -/*-------------------------------------------------------------------* - * syn_output() - * - * Output synthesis signal with compensation for saturation - * returns number of clipped samples - *-------------------------------------------------------------------*/ diff --git a/lib_dec/syn_outp_fx.c b/lib_dec/syn_outp_fx.c index 0d70524bedab22da24bf6cfda428734479423843..133ff17b44e2f40ac846c88353ebfb4d97092a56 100644 --- a/lib_dec/syn_outp_fx.c +++ b/lib_dec/syn_outp_fx.c @@ -40,11 +40,7 @@ void syn_output_fx( FOR( i = 0; i < output_frame; i++ ) { L_tmp = L_deposit_h( synth[i] ); -#ifdef BASOP_NOGLOB synth_out[i] = round_fx_sat( L_shr_sat( L_tmp, tmp ) ); -#else - synth_out[i] = round_fx( L_shr( L_tmp, tmp ) ); -#endif move16(); } } @@ -86,11 +82,7 @@ void unscale_AGC( max_val = s_max( max_val, abs_s( x[i] ) ); } BASOP_SATURATE_WARNING_OFF_EVS -#ifdef BASOP_NOGLOB tmp = shl_o( 30000, Qx, &Overflow ); /* saturation can occur here */ -#else - tmp = shl( 30000, Qx ); /* saturation can occurs here */ -#endif BASOP_SATURATE_WARNING_ON_EVS frame_fac = 0; move16(); diff --git a/lib_dec/tcq_core_dec.c b/lib_dec/tcq_core_dec.c deleted file mode 100644 index 403c5db5b04dcd5b2ea7a107b520257dc152e832..0000000000000000000000000000000000000000 --- a/lib_dec/tcq_core_dec.c +++ /dev/null @@ -1,44 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include "cnst.h" -#include "rom_com.h" -#include "prot.h" -#include "basop_util.h" -#include "basop_proto_func.h" -#include "wmc_auto.h" diff --git a/lib_dec/tcx_utils_dec.c b/lib_dec/tcx_utils_dec.c deleted file mode 100644 index efee08d61ff7a04b17812a2ec03793f68585587e..0000000000000000000000000000000000000000 --- a/lib_dec/tcx_utils_dec.c +++ /dev/null @@ -1,49 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include -#include "options.h" -#include "cnst.h" -#include "prot.h" -#include "rom_com.h" -#include "wmc_auto.h" - -/*--------------------------------------------------------------- - * tcx_decoder_memory_update_flt() - * - * - *--------------------------------------------------------------*/ diff --git a/lib_dec/tns_base_dec.c b/lib_dec/tns_base_dec.c deleted file mode 100644 index 68e2e313cbfcfa5ee46120f98faf3938b409a40d..0000000000000000000000000000000000000000 --- a/lib_dec/tns_base_dec.c +++ /dev/null @@ -1,43 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include "cnst.h" -#include "rom_com.h" -#include "prot.h" -#include "stat_com.h" -#include "wmc_auto.h" diff --git a/lib_dec/tonalMDCTconcealment.c b/lib_dec/tonalMDCTconcealment.c deleted file mode 100644 index c865dbe745ffc54da6b4c0908544a85ce25e5727..0000000000000000000000000000000000000000 --- a/lib_dec/tonalMDCTconcealment.c +++ /dev/null @@ -1,433 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#define _USE_MATH_DEFINES - -#include -#include -#include "options.h" -#include -#include "prot.h" -#include "ivas_prot.h" -#include "wmc_auto.h" -#include "ivas_prot_fx.h" -#include "prot_fx.h" - - -/*******************************************************/ -/*-------------- public functions -------------------- */ -/*******************************************************/ - -void TonalMdctConceal_create_concealment_noise_ivas_fx( - Word32 concealment_noise[L_FRAME48k], // Q31-concealment_noise_exp - Word16 *concealment_noise_exp, - CPE_DEC_HANDLE hCPE, - const Word16 L_frameTCX, // Q0 - const Word16 L_frame, // Q0 - const Word16 idchan, // Q0 - const Word16 subframe_idx, // Q0 - const Word16 core, // Q0 - const Word16 crossfade_gain, // Q15 - const TONALMDCTCONC_NOISE_GEN_MODE noise_gen_mode ) -{ - STEREO_MDCT_DEC_DATA_HANDLE hStereoMdct; - TonalMDCTConcealPtr hTonalMDCTConc; - Decoder_State *st; - HANDLE_FD_CNG_COM hFdCngCom; - Word16 *rnd_c, *rnd; - Word16 crossOverFreq, i, save_rnd_c, max_noise_line; - Word16 c, c_inv, inc; - Word32 noise_shape_buffer[L_FRAME48k]; - Word16 noise_shape_buffer_e[L_FRAME48k]; - Word16 start_idx, stop_idx, noise_shape_buffer_common_exp = MIN16B_FLT_FX, last_scf_e, temp_e; - move16(); - Word32 *cngNoiseLevelPtr; - Word32 last_scf; - - Word16 c_e, c_inv_e; - - push_wmops( "create_conc_noise" ); - - hStereoMdct = hCPE->hStereoMdct; - st = hCPE->hCoreCoder[idchan]; - hTonalMDCTConc = st->hTonalMDCTConc; - hFdCngCom = st->hFdCngDec->hFdCngCom; - rnd = &hStereoMdct->noise_seeds_channels[idchan]; - rnd_c = &hStereoMdct->noise_seed_common; - - /* determine start bin for IGF */ - IF( st->igf == 0 ) - { - IF( st->narrowBand == 0 ) - { - /* minimum needed for output with sampling rates lower then the - nominal sampling rate */ - crossOverFreq = s_min( L_frameTCX, L_frame ); - } - ELSE - { - crossOverFreq = L_frameTCX; - move16(); - } - } - ELSE - { - crossOverFreq = s_min( st->hIGFDec->infoIGFStartLine, L_frameTCX ); - } - - /* for tonal mdct concealment with tonal components above the crossover frequency, conditionally raise the frequency index until which noise is generated */ - max_noise_line = crossOverFreq; - move16(); - IF( st->tonal_mdct_plc_active ) - { - max_noise_line = s_max( max_noise_line, extract_l( L_add( hTonalMDCTConc->pTCI->upperIndex[hTonalMDCTConc->pTCI->numIndexes - 1], 1 ) ) ); - } - - /* first lost frame is handled separately */ - IF( !hTonalMDCTConc->lastBlockData.blockIsConcealed ) - { - *rnd = add( 1977, idchan ); // Q0 - move16(); - /* will be set twice when looping over two channels, but does not matter */ - *rnd_c = 1979; // Q0 - move16(); - } - - IF( GT_16( crossfade_gain, 32734 ) ) - /* Due to precision loss */ /* 0.999 in Q15*/ - { - /* In first frame, noise is weighted with zero anyway, we only need the random numbers for the sign scrambling */ - FOR( i = 0; i < max_noise_line; i++ ) - { - *rnd = own_random( rnd ); - move16(); - concealment_noise[i] = *rnd; // Q31-concealment_noise_exp - move32(); - } - *concealment_noise_exp = 31; - move16(); - pop_wmops(); - - return; - } - - save_rnd_c = *rnd_c; // Q0 - move16(); - - c_e = 1; - move16(); - c_inv_e = 1; - move16(); - - c = Sqrt16( hStereoMdct->lastCoh_fx, &c_e ); // Q1 = 15 - c_e - c_inv = Sqrt16( sub( ONE_IN_Q14, hStereoMdct->lastCoh_fx ), &c_inv_e ); // Q2 = 15 - c_inv_e - - IF( NE_16( c_e, c_inv_e ) ) - { - IF( LT_16( c_e, c_inv_e ) ) - { - c = shr( c, sub( c_inv_e, c_e ) ); // Q0 - c_e = c_inv_e; - move16(); - } - ELSE - { - c_inv = shr( c_inv, sub( c_e, c_inv_e ) ); // Q0 - } - } - - /* pre-compute the noise shape for later weighting of the noise spectra */ - cngNoiseLevelPtr = &hFdCngCom->cngNoiseLevel[0]; - last_scf_e = hFdCngCom->cngNoiseLevelExp; - move16(); - - IF( GT_16( st->core, TCX_20_CORE ) ) - { - inc = 2; - } - ELSE - { - inc = 1; - } - move16(); - start_idx = idiv1616( hFdCngCom->startBand, inc ); - stop_idx = idiv1616( hFdCngCom->stopFFTbin, inc ); - - FOR( i = 0; i < start_idx; i++ ) - { - noise_shape_buffer[i] = 0; - move32(); - noise_shape_buffer_e[i] = 0; - move16(); - } - FOR( ; i < stop_idx; ( i++, cngNoiseLevelPtr += inc ) ) - { - noise_shape_buffer_e[i] = hFdCngCom->cngNoiseLevelExp; - move16(); - noise_shape_buffer[i] = Sqrt32( *( cngNoiseLevelPtr ), &noise_shape_buffer_e[i] ); // Q31-noise_shape_buffer_e[i] - move32(); - noise_shape_buffer_common_exp = s_max( noise_shape_buffer_e[i], noise_shape_buffer_common_exp ); - } - - FOR( i = 0; i < stop_idx; i++ ) - { - IF( NE_16( noise_shape_buffer_common_exp, noise_shape_buffer_e[i] ) ) - { - - noise_shape_buffer[i] = L_shr( noise_shape_buffer[i], sub( noise_shape_buffer_common_exp, noise_shape_buffer_e[i] ) ); // Q31- (noise_shape_buffer_common_exp-noise_shape_buffer_e[i]) - move32(); - } - } - - last_scf = Sqrt32( *( cngNoiseLevelPtr - inc ), &last_scf_e ); // Q31-last_scf_e - - IF( LT_16( noise_shape_buffer_common_exp, last_scf_e ) ) - { - Scale_sig32( noise_shape_buffer, stop_idx, sub( noise_shape_buffer_common_exp, last_scf_e ) ); // Q31- (noise_shape_buffer_common_exp-last_scf_e) - - noise_shape_buffer_common_exp = last_scf_e; - move16(); - } - ELSE - { - last_scf = L_shl( last_scf, sub( last_scf_e, noise_shape_buffer_common_exp ) ); // Q31-(last_scf_e-noise_shape_buffer_common_exp) - } - - FOR( ; i < max_noise_line; i++ ) - { - noise_shape_buffer[i] = last_scf; // Q31 - noise_shape_buffer_common_exp - move32(); - } - - /* fill the noise vector */ - hTonalMDCTConc->curr_noise_nrg = MDCT_ST_PLC_FADEOUT_MIN_NOISE_NRG_Q31; // Q31 - move32(); - hTonalMDCTConc->curr_noise_nrg_exp = 0; - move16(); - *concealment_noise_exp = add( 16, add( noise_shape_buffer_common_exp, c_e ) ); - move16(); - temp_e = hTonalMDCTConc->curr_noise_nrg_exp; - move16(); - - test(); - test(); - test(); - test(); - IF( EQ_16( noise_gen_mode, EQUAL_CORES ) || ( ( EQ_16( noise_gen_mode, TCX20_IN_0_TCX10_IN_1 ) && EQ_16( idchan, 0 ) ) || ( EQ_16( noise_gen_mode, TCX10_IN_0_TCX20_IN_1 ) && EQ_16( idchan, 1 ) ) ) ) - { - /* current channel is TCX20 -> generate noise for "full-length" spectrum */ - - FOR( i = 0; i < max_noise_line; i++ ) - { - *rnd = own_random( rnd ); // Q0 - *rnd_c = own_random( rnd_c ); - - move16(); - move16(); - - concealment_noise[i] = Mpy_32_32( L_add( L_shr( L_mult( c_inv, *rnd ), 1 ), L_shr( L_mult( c, *rnd_c ), 1 ) ), noise_shape_buffer[i] ); // Q31 - *concealment_noise_exp - move32(); - IF( concealment_noise[i] != 0 ) - { - hTonalMDCTConc->curr_noise_nrg = BASOP_Util_Add_Mant32Exp( hTonalMDCTConc->curr_noise_nrg, hTonalMDCTConc->curr_noise_nrg_exp, Mpy_32_32( concealment_noise[i], concealment_noise[i] ), shl( *concealment_noise_exp, 1 ), &temp_e ); // Q31-temp_e - } - hTonalMDCTConc->curr_noise_nrg_exp = temp_e; - move16(); - } - } - ELSE /* ( ( noise_gen_mode == TCX10_IN_0_TCX20_IN_1 && idchan == 0 ) || ( noise_gen_mode == TCX20_IN_0_TCX10_IN_1 && idchan == 1 ) ) */ - { - /* current channel is TCX10 and the other is TCX20 -> generate noise for "half-length" spectrum, but "increment" mid seed twice, to have the same seed in mid as the other (TCX20) channel for next frame */ - FOR( i = 0; i < max_noise_line; i++ ) - { - *rnd = own_random( rnd ); // Q0 - *rnd_c = own_random( rnd_c ); // Q0 - move16(); - move16(); - - concealment_noise[i] = Mpy_32_32( L_add( L_shr( L_mult( c_inv, *rnd ), 1 ), L_shr( L_mult( c, *rnd_c ), 1 ) ), noise_shape_buffer[i] ); - move32(); - IF( concealment_noise[i] != 0 ) - { - hTonalMDCTConc->curr_noise_nrg = BASOP_Util_Add_Mant32Exp( hTonalMDCTConc->curr_noise_nrg, hTonalMDCTConc->curr_noise_nrg_exp, Mpy_32_32( concealment_noise[i], concealment_noise[i] ), shl( *concealment_noise_exp, 1 ), &temp_e ); // Q31-temp_e - } - hTonalMDCTConc->curr_noise_nrg_exp = temp_e; - move16(); - - *rnd_c = own_random( rnd_c ); - move16(); - } - } - - IF( st->tonal_mdct_plc_active ) - { - FOR( i = crossOverFreq; i < s_max( crossOverFreq, hTonalMDCTConc->pTCI->lowerIndex[hTonalMDCTConc->pTCI->numIndexes - 1] ); ++i ) - { - concealment_noise[i] = 0; - move32(); - } - } - - /* restore common seed - - after finishing the first channel - - after a first subframe if the current channel is TCX10 */ - - test(); - test(); - test(); - test(); - test(); - IF( ( EQ_16( idchan, 0 ) && ( EQ_16( core, TCX_20 ) || ( EQ_16( core, TCX_10 ) && EQ_16( subframe_idx, 1 ) ) ) ) || ( EQ_16( core, TCX_10 ) && EQ_16( subframe_idx, 0 ) ) ) - { - *rnd_c = save_rnd_c; - move16(); - } - - st->seed_tcx_plc = *rnd; - move16(); - - pop_wmops(); - - return; -} - - -void TonalMdctConceal_whiten_noise_shape_ivas_fx( - Decoder_State *st, - const Word16 L_frame, - const TONALMDCTCONC_NOISE_SHAPE_WHITENING_MODE whitening_mode ) -{ - Word16 inc, start_idx, stop_idx, i; - Word32 *noiseLevelPtr, *scfs_bg, *scfs_for_shaping; - Word16 noiseLevelPtr_exp; - HANDLE_FD_CNG_COM hFdCngCom; - Word32 whitenend_noise_shape[L_FRAME16k]; - Word16 q_wns; - Word32 scfs_int[FDNS_NPTS]; - const PsychoacousticParameters *psychParams; - - push_wmops( "apply_sns_on_noise_shape" ); - - scfs_bg = &st->hTonalMDCTConc->scaleFactorsBackground_fx[0]; - psychParams = st->hTonalMDCTConc->psychParams; - hFdCngCom = st->hFdCngDec->hFdCngCom; - - IF( EQ_32( whitening_mode, ON_FIRST_LOST_FRAME ) ) - { - IF( GT_16( st->core, TCX_20_CORE ) ) - { - inc = 2; - move16(); - } - ELSE - { - inc = 1; - move16(); - } - } - ELSE - { - IF( GT_16( st->last_core, TCX_20_CORE ) ) - { - inc = 2; - move16(); - } - ELSE - { - inc = 1; - move16(); - } - } - start_idx = shr( hFdCngCom->startBand, sub( inc, 1 ) ); - stop_idx = shr( L_frame, sub( inc, 1 ) ); - noiseLevelPtr = hFdCngCom->cngNoiseLevel; - noiseLevelPtr_exp = hFdCngCom->cngNoiseLevelExp; - move16(); - - set32_fx( whitenend_noise_shape, 0, start_idx ); - FOR( Word16 j = start_idx; j < stop_idx; j++ ) - { - whitenend_noise_shape[j] = L_shr( *noiseLevelPtr, 3 ); - move32(); - noiseLevelPtr += inc; - } - - IF( EQ_32( whitening_mode, ON_FIRST_LOST_FRAME ) ) - { - Word32 scf[SNS_NPTS]; - - sns_compute_scf_fx( whitenend_noise_shape, psychParams, L_frame, scf, sub( sub( 31, noiseLevelPtr_exp ), 3 ) ); - - sns_interpolate_scalefactors_fx( scfs_int, scf, ENC ); - sns_interpolate_scalefactors_fx( scfs_bg, scf, DEC ); - - scfs_for_shaping = &scfs_int[0]; // Q16 - } - ELSE /* whitening_mode == ON_FIRST_GOOD_FRAME */ - { - scfs_for_shaping = &scfs_bg[0]; // Q16 - } - - IF( sum32_sat( scfs_for_shaping, FDNS_NPTS ) > 0 ) - { - q_wns = sub( sub( 31, noiseLevelPtr_exp ), 3 ); - sns_shape_spectrum_fx( whitenend_noise_shape, &q_wns, psychParams, scfs_for_shaping, Q16, L_frame, NULL ); - - IF( GT_16( add( q_wns, 1 ), sub( 31, hFdCngCom->cngNoiseLevelExp ) ) ) - { - FOR( i = 0; i < sub( stop_idx, start_idx ); i++ ) - { - hFdCngCom->cngNoiseLevel[i] = L_shr( whitenend_noise_shape[start_idx + i], sub( add( q_wns, hFdCngCom->cngNoiseLevelExp ), 30 ) ); //(q_wns + 1) - move32(); - } - } - ELSE - { - Copy32( whitenend_noise_shape + start_idx, hFdCngCom->cngNoiseLevel, sub( stop_idx, start_idx ) ); - - scale_sig32( hFdCngCom->cngNoiseLevel + sub( stop_idx, start_idx ), sub( FFTCLDFBLEN, sub( stop_idx, start_idx ) ), sub( add( q_wns, hFdCngCom->cngNoiseLevelExp ), 30 ) ); - - hFdCngCom->cngNoiseLevelExp = sub( Q30, q_wns ); // Exponent = 31 - (q_wns + 1) - move16(); - } - } - ELSE - { - set32_fx( hFdCngCom->cngNoiseLevel, 0, sub( stop_idx, start_idx ) ); - } - - pop_wmops(); -} diff --git a/lib_dec/tonalMDCTconcealment_fx.c b/lib_dec/tonalMDCTconcealment_fx.c index 15ce08803e3f53618cab0aee33dc4fd515293403..36cadf6ffea2934dc2a7ebf63f9927240c33ba46 100644 --- a/lib_dec/tonalMDCTconcealment_fx.c +++ b/lib_dec/tonalMDCTconcealment_fx.c @@ -14,7 +14,6 @@ #include "cnst.h" #include "prot_fx.h" #include "stat_com.h" -#include "prot.h" #include "ivas_prot_fx.h" #define CROSSFADE_THRESHOLD ( 32762 ) // close to 1.0f in Q15 such that (x == 1.0f) is true @@ -885,11 +884,7 @@ static void ivas_CalcPowerSpecAndDetectTonalComponents_fx( powerSpectrum_exp = add( powerSpectrum_exp, 3 ); FOR( i = hTonalMDCTConc->nSamplesCore; i < nSamples; i++ ) { -#ifdef BASOP_NOGLOB powerSpectrum[i] = L_shl_sat( Mpy_32_16_1( powerSpectrum[i], invScaleFactors[nBands - 1] ), invScaleFactors_exp[nBands - 1] ); // Q(31 - powerSpectrum_exp) -#else - powerSpectrum[i] = L_shl( Mpy_32_16_1( powerSpectrum[i], invScaleFactors[nBands - 1] ), invScaleFactors_exp[nBands - 1] ); -#endif move32(); } @@ -900,11 +895,7 @@ static void ivas_CalcPowerSpecAndDetectTonalComponents_fx( /* 16 bits are now enough for storing the power spectrum */ FOR( i = 0; i < nSamples; i++ ) { -#ifdef BASOP_NOGLOB hTonalMDCTConc->secondLastPowerSpectrum[i] = round_fx_o( powerSpectrum[i], &Overflow ); // Q31 - powerSpectrum_exp -#else - hTonalMDCTConc->secondLastPowerSpectrum[i] = round_fx( powerSpectrum[i] ); -#endif move32(); } @@ -1031,22 +1022,14 @@ static void CalcPowerSpecAndDetectTonalComponents( #endif FOR( i = hTonalMDCTConc->nSamplesCore; i < nSamples; i++ ) { -#ifdef BASOP_NOGLOB powerSpectrum[i] = L_shl_sat( Mpy_32_16_1( powerSpectrum[i], invScaleFactors[FDNS_NPTS - 1] ), invScaleFactors_exp[FDNS_NPTS - 1] ); // powerSpectrum_exp+ 2*invScaleFactors_exp -15 -#else - powerSpectrum[i] = L_shl( Mpy_32_16_1( powerSpectrum[i], invScaleFactors[FDNS_NPTS - 1] ), invScaleFactors_exp[FDNS_NPTS - 1] ); -#endif move32(); } /* 16 bits are now enough for storing the power spectrum */ FOR( i = 0; i < nSamples; i++ ) { -#ifdef BASOP_NOGLOB hTonalMDCTConc->secondLastPowerSpectrum[i] = round_fx_o( powerSpectrum[i], &Overflow ); // Q31-powerSpectrum_exp -#else - hTonalMDCTConc->secondLastPowerSpectrum[i] = round_fx( powerSpectrum[i] ); -#endif move32(); } @@ -1318,7 +1301,7 @@ void TonalMDCTConceal_Detect_ivas_fx( #endif nSamples = hTonalMDCTConc->nNonZeroSamples; move16(); - Copy_Scale_sig_16_32( hTonalMDCTConc->secondLastPowerSpectrum, powerSpectrum, nSamples, Q15 ); + Copy_Scale_sig_16_32_DEPREC( hTonalMDCTConc->secondLastPowerSpectrum, powerSpectrum, nSamples, Q15 ); temp_power_spectrum_q = add( Q15, sub( 15, hTonalMDCTConc->secondLastPowerSpectrum_exp ) ); IF( psychParamsCurrent == NULL ) { @@ -1444,11 +1427,7 @@ void TonalMDCTConceal_InsertNoise_ivas_fx( inv_samples = Inv16( hTonalMDCTConc->lastBlockData.nSamples, &inv_exp ); // Q31-inv_exp tiltFactor = round_fx( BASOP_Util_fPow( L_max( L_tmp, L_deposit_h( tiltCompFactor ) ), 0, L_deposit_h( inv_samples ), inv_exp, &exp ) ); // Q15 - exp BASOP_SATURATE_WARNING_OFF_EVS /*next op may result in 32768*/ -#ifdef BASOP_NOGLOB - tiltFactor = shl_sat( tiltFactor, exp ); // Q15 -#else - tiltFactor = shl( tiltFactor, exp ); -#endif + tiltFactor = shl_sat( tiltFactor, exp ); // Q15 BASOP_SATURATE_WARNING_ON_EVS tilt = MAX16B; move16(); @@ -1521,11 +1500,7 @@ void TonalMDCTConceal_InsertNoise_ivas_fx( num = L_shr( num, 1 ); // Q31-exp -1 exp = add( exp, 1 ); } -#ifdef BASOP_NOGLOB tmp = div_l( num, round_fx_sat( den ) ); -#else - tmp = div_l( num, round_fx( den ) ); -#endif tmp = Sqrt16( tmp, &exp ); g = mult_r( g, tmp ); // exponent of g = exp @@ -2056,11 +2031,7 @@ ELSE tmp = round_fx( BASOP_Util_fPow( L_deposit_h( tiltFactor ), 0, L_deposit_h( extract_l( L_add( L_sub( hTonalMDCTConc->pTCI->upperIndex[hTonalMDCTConc->pTCI->numIndexes - 1], hTonalMDCTConc->pTCI->lowerIndex[hTonalMDCTConc->pTCI->numIndexes - 1] ), 1 ) ) ), 15, &exp ) ); BASOP_SATURATE_WARNING_OFF_EVS /*next op may result in 32768*/ -#ifdef BASOP_NOGLOB tmp = shl_sat( tmp, exp ); -#else - tmp = shl( tmp, exp ); -#endif BASOP_SATURATE_WARNING_ON_EVS tilt = mult_r( tilt, tmp ); @@ -2485,12 +2456,8 @@ void TonalMDCTConceal_InsertNoise( move16(); inv_samples = Inv16( hTonalMDCTConc->lastBlockData.nSamples, &inv_exp ); tiltFactor = round_fx( BASOP_Util_fPow( L_max( L_tmp, L_deposit_h( tiltCompFactor ) ), 0, L_deposit_h( inv_samples ), inv_exp, &exp ) ); - BASOP_SATURATE_WARNING_OFF_EVS /*next op may result in 32768*/ -#ifdef BASOP_NOGLOB + BASOP_SATURATE_WARNING_OFF_EVS /*next op may result in 32768*/ tiltFactor = shl_sat( tiltFactor, exp ); // Q15- 2*exp -#else - tiltFactor = shl( tiltFactor, exp ); -#endif BASOP_SATURATE_WARNING_ON_EVS tilt = 32767 /*1.0f Q15*/; @@ -2679,11 +2646,7 @@ void TonalMDCTConceal_InsertNoise( tmp = round_fx( BASOP_Util_fPow( L_deposit_h( tiltFactor ), 0, L_deposit_h( (UWord16) L_add( L_sub( hTonalMDCTConc->pTCI->upperIndex[hTonalMDCTConc->pTCI->numIndexes - 1], hTonalMDCTConc->pTCI->lowerIndex[hTonalMDCTConc->pTCI->numIndexes - 1] ), 1 ) ), 15, &exp ) ); BASOP_SATURATE_WARNING_OFF_EVS /*next op may result in 32768*/ -#ifdef BASOP_NOGLOB tmp = shl_sat( tmp, exp ); // Q15 - 2*exp -#else - tmp = shl( tmp, exp ); -#endif BASOP_SATURATE_WARNING_ON_EVS tilt = mult_r( tilt, tmp ); @@ -3236,6 +3199,397 @@ static void CalcPowerSpec( powerSpec[nSamples - 1] = L_shr( powerSpec[nSamples - 2], 1 ); move32(); } + + +/*******************************************************/ +/*-------------- public functions -------------------- */ +/*******************************************************/ + +void TonalMdctConceal_create_concealment_noise_ivas_fx( + Word32 concealment_noise[L_FRAME48k], // Q31-concealment_noise_exp + Word16 *concealment_noise_exp, + CPE_DEC_HANDLE hCPE, + const Word16 L_frameTCX, // Q0 + const Word16 L_frame, // Q0 + const Word16 idchan, // Q0 + const Word16 subframe_idx, // Q0 + const Word16 core, // Q0 + const Word16 crossfade_gain, // Q15 + const TONALMDCTCONC_NOISE_GEN_MODE noise_gen_mode ) +{ + STEREO_MDCT_DEC_DATA_HANDLE hStereoMdct; + TonalMDCTConcealPtr hTonalMDCTConc; + Decoder_State *st; + HANDLE_FD_CNG_COM hFdCngCom; + Word16 *rnd_c, *rnd; + Word16 crossOverFreq, i, save_rnd_c, max_noise_line; + Word16 c, c_inv, inc; + Word32 noise_shape_buffer[L_FRAME48k]; + Word16 noise_shape_buffer_e[L_FRAME48k]; + Word16 start_idx, stop_idx, noise_shape_buffer_common_exp = MIN16B_FLT_FX, last_scf_e, temp_e; + move16(); + Word32 *cngNoiseLevelPtr; + Word32 last_scf; + + Word16 c_e, c_inv_e; + + push_wmops( "create_conc_noise" ); + + hStereoMdct = hCPE->hStereoMdct; + st = hCPE->hCoreCoder[idchan]; + hTonalMDCTConc = st->hTonalMDCTConc; + hFdCngCom = st->hFdCngDec->hFdCngCom; + rnd = &hStereoMdct->noise_seeds_channels[idchan]; + rnd_c = &hStereoMdct->noise_seed_common; + + /* determine start bin for IGF */ + IF( st->igf == 0 ) + { + IF( st->narrowBand == 0 ) + { + /* minimum needed for output with sampling rates lower then the + nominal sampling rate */ + crossOverFreq = s_min( L_frameTCX, L_frame ); + } + ELSE + { + crossOverFreq = L_frameTCX; + move16(); + } + } + ELSE + { + crossOverFreq = s_min( st->hIGFDec->infoIGFStartLine, L_frameTCX ); + } + + /* for tonal mdct concealment with tonal components above the crossover frequency, conditionally raise the frequency index until which noise is generated */ + max_noise_line = crossOverFreq; + move16(); + IF( st->tonal_mdct_plc_active ) + { + max_noise_line = s_max( max_noise_line, extract_l( L_add( hTonalMDCTConc->pTCI->upperIndex[hTonalMDCTConc->pTCI->numIndexes - 1], 1 ) ) ); + } + + /* first lost frame is handled separately */ + IF( !hTonalMDCTConc->lastBlockData.blockIsConcealed ) + { + *rnd = add( 1977, idchan ); // Q0 + move16(); + /* will be set twice when looping over two channels, but does not matter */ + *rnd_c = 1979; // Q0 + move16(); + } + + IF( GT_16( crossfade_gain, 32734 ) ) + /* Due to precision loss */ /* 0.999 in Q15*/ + { + /* In first frame, noise is weighted with zero anyway, we only need the random numbers for the sign scrambling */ + FOR( i = 0; i < max_noise_line; i++ ) + { + *rnd = own_random( rnd ); + move16(); + concealment_noise[i] = *rnd; // Q31-concealment_noise_exp + move32(); + } + *concealment_noise_exp = 31; + move16(); + pop_wmops(); + + return; + } + + save_rnd_c = *rnd_c; // Q0 + move16(); + + c_e = 1; + move16(); + c_inv_e = 1; + move16(); + + c = Sqrt16( hStereoMdct->lastCoh_fx, &c_e ); // Q1 = 15 - c_e + c_inv = Sqrt16( sub( ONE_IN_Q14, hStereoMdct->lastCoh_fx ), &c_inv_e ); // Q2 = 15 - c_inv_e + + IF( NE_16( c_e, c_inv_e ) ) + { + IF( LT_16( c_e, c_inv_e ) ) + { + c = shr( c, sub( c_inv_e, c_e ) ); // Q0 + c_e = c_inv_e; + move16(); + } + ELSE + { + c_inv = shr( c_inv, sub( c_e, c_inv_e ) ); // Q0 + } + } + + /* pre-compute the noise shape for later weighting of the noise spectra */ + cngNoiseLevelPtr = &hFdCngCom->cngNoiseLevel[0]; + last_scf_e = hFdCngCom->cngNoiseLevelExp; + move16(); + + IF( GT_16( st->core, TCX_20_CORE ) ) + { + inc = 2; + } + ELSE + { + inc = 1; + } + move16(); + start_idx = idiv1616( hFdCngCom->startBand, inc ); + stop_idx = idiv1616( hFdCngCom->stopFFTbin, inc ); + + FOR( i = 0; i < start_idx; i++ ) + { + noise_shape_buffer[i] = 0; + move32(); + noise_shape_buffer_e[i] = 0; + move16(); + } + FOR( ; i < stop_idx; ( i++, cngNoiseLevelPtr += inc ) ) + { + noise_shape_buffer_e[i] = hFdCngCom->cngNoiseLevelExp; + move16(); + noise_shape_buffer[i] = Sqrt32( *( cngNoiseLevelPtr ), &noise_shape_buffer_e[i] ); // Q31-noise_shape_buffer_e[i] + move32(); + noise_shape_buffer_common_exp = s_max( noise_shape_buffer_e[i], noise_shape_buffer_common_exp ); + } + + FOR( i = 0; i < stop_idx; i++ ) + { + IF( NE_16( noise_shape_buffer_common_exp, noise_shape_buffer_e[i] ) ) + { + + noise_shape_buffer[i] = L_shr( noise_shape_buffer[i], sub( noise_shape_buffer_common_exp, noise_shape_buffer_e[i] ) ); // Q31- (noise_shape_buffer_common_exp-noise_shape_buffer_e[i]) + move32(); + } + } + + last_scf = Sqrt32( *( cngNoiseLevelPtr - inc ), &last_scf_e ); // Q31-last_scf_e + + IF( LT_16( noise_shape_buffer_common_exp, last_scf_e ) ) + { + Scale_sig32( noise_shape_buffer, stop_idx, sub( noise_shape_buffer_common_exp, last_scf_e ) ); // Q31- (noise_shape_buffer_common_exp-last_scf_e) + + noise_shape_buffer_common_exp = last_scf_e; + move16(); + } + ELSE + { + last_scf = L_shl( last_scf, sub( last_scf_e, noise_shape_buffer_common_exp ) ); // Q31-(last_scf_e-noise_shape_buffer_common_exp) + } + + FOR( ; i < max_noise_line; i++ ) + { + noise_shape_buffer[i] = last_scf; // Q31 - noise_shape_buffer_common_exp + move32(); + } + + /* fill the noise vector */ + hTonalMDCTConc->curr_noise_nrg = MDCT_ST_PLC_FADEOUT_MIN_NOISE_NRG_Q31; // Q31 + move32(); + hTonalMDCTConc->curr_noise_nrg_exp = 0; + move16(); + *concealment_noise_exp = add( 16, add( noise_shape_buffer_common_exp, c_e ) ); + move16(); + temp_e = hTonalMDCTConc->curr_noise_nrg_exp; + move16(); + + test(); + test(); + test(); + test(); + IF( EQ_16( noise_gen_mode, EQUAL_CORES ) || ( ( EQ_16( noise_gen_mode, TCX20_IN_0_TCX10_IN_1 ) && EQ_16( idchan, 0 ) ) || ( EQ_16( noise_gen_mode, TCX10_IN_0_TCX20_IN_1 ) && EQ_16( idchan, 1 ) ) ) ) + { + /* current channel is TCX20 -> generate noise for "full-length" spectrum */ + + FOR( i = 0; i < max_noise_line; i++ ) + { + *rnd = own_random( rnd ); // Q0 + *rnd_c = own_random( rnd_c ); + + move16(); + move16(); + + concealment_noise[i] = Mpy_32_32( L_add( L_shr( L_mult( c_inv, *rnd ), 1 ), L_shr( L_mult( c, *rnd_c ), 1 ) ), noise_shape_buffer[i] ); // Q31 - *concealment_noise_exp + move32(); + IF( concealment_noise[i] != 0 ) + { + hTonalMDCTConc->curr_noise_nrg = BASOP_Util_Add_Mant32Exp( hTonalMDCTConc->curr_noise_nrg, hTonalMDCTConc->curr_noise_nrg_exp, Mpy_32_32( concealment_noise[i], concealment_noise[i] ), shl( *concealment_noise_exp, 1 ), &temp_e ); // Q31-temp_e + } + hTonalMDCTConc->curr_noise_nrg_exp = temp_e; + move16(); + } + } + ELSE /* ( ( noise_gen_mode == TCX10_IN_0_TCX20_IN_1 && idchan == 0 ) || ( noise_gen_mode == TCX20_IN_0_TCX10_IN_1 && idchan == 1 ) ) */ + { + /* current channel is TCX10 and the other is TCX20 -> generate noise for "half-length" spectrum, but "increment" mid seed twice, to have the same seed in mid as the other (TCX20) channel for next frame */ + FOR( i = 0; i < max_noise_line; i++ ) + { + *rnd = own_random( rnd ); // Q0 + *rnd_c = own_random( rnd_c ); // Q0 + move16(); + move16(); + + concealment_noise[i] = Mpy_32_32( L_add( L_shr( L_mult( c_inv, *rnd ), 1 ), L_shr( L_mult( c, *rnd_c ), 1 ) ), noise_shape_buffer[i] ); + move32(); + IF( concealment_noise[i] != 0 ) + { + hTonalMDCTConc->curr_noise_nrg = BASOP_Util_Add_Mant32Exp( hTonalMDCTConc->curr_noise_nrg, hTonalMDCTConc->curr_noise_nrg_exp, Mpy_32_32( concealment_noise[i], concealment_noise[i] ), shl( *concealment_noise_exp, 1 ), &temp_e ); // Q31-temp_e + } + hTonalMDCTConc->curr_noise_nrg_exp = temp_e; + move16(); + + *rnd_c = own_random( rnd_c ); + move16(); + } + } + + IF( st->tonal_mdct_plc_active ) + { + FOR( i = crossOverFreq; i < s_max( crossOverFreq, hTonalMDCTConc->pTCI->lowerIndex[hTonalMDCTConc->pTCI->numIndexes - 1] ); ++i ) + { + concealment_noise[i] = 0; + move32(); + } + } + + /* restore common seed + - after finishing the first channel + - after a first subframe if the current channel is TCX10 */ + + test(); + test(); + test(); + test(); + test(); + IF( ( EQ_16( idchan, 0 ) && ( EQ_16( core, TCX_20 ) || ( EQ_16( core, TCX_10 ) && EQ_16( subframe_idx, 1 ) ) ) ) || ( EQ_16( core, TCX_10 ) && EQ_16( subframe_idx, 0 ) ) ) + { + *rnd_c = save_rnd_c; + move16(); + } + + st->seed_tcx_plc = *rnd; + move16(); + + pop_wmops(); + + return; +} + + +void TonalMdctConceal_whiten_noise_shape_ivas_fx( + Decoder_State *st, + const Word16 L_frame, + const TONALMDCTCONC_NOISE_SHAPE_WHITENING_MODE whitening_mode ) +{ + Word16 inc, start_idx, stop_idx, i; + Word32 *noiseLevelPtr, *scfs_bg, *scfs_for_shaping; + Word16 noiseLevelPtr_exp; + HANDLE_FD_CNG_COM hFdCngCom; + Word32 whitenend_noise_shape[L_FRAME16k]; + Word16 q_wns; + Word32 scfs_int[FDNS_NPTS]; + const PsychoacousticParameters *psychParams; + + push_wmops( "apply_sns_on_noise_shape" ); + + scfs_bg = &st->hTonalMDCTConc->scaleFactorsBackground_fx[0]; + psychParams = st->hTonalMDCTConc->psychParams; + hFdCngCom = st->hFdCngDec->hFdCngCom; + +#ifdef MSAN_FIX + set32_fx( whitenend_noise_shape, 0, L_FRAME16k ); +#endif + + IF( EQ_32( whitening_mode, ON_FIRST_LOST_FRAME ) ) + { + IF( GT_16( st->core, TCX_20_CORE ) ) + { + inc = 2; + move16(); + } + ELSE + { + inc = 1; + move16(); + } + } + ELSE + { + IF( GT_16( st->last_core, TCX_20_CORE ) ) + { + inc = 2; + move16(); + } + ELSE + { + inc = 1; + move16(); + } + } + start_idx = shr( hFdCngCom->startBand, sub( inc, 1 ) ); + stop_idx = shr( L_frame, sub( inc, 1 ) ); + noiseLevelPtr = hFdCngCom->cngNoiseLevel; + noiseLevelPtr_exp = hFdCngCom->cngNoiseLevelExp; + move16(); + + FOR( Word16 j = start_idx; j < stop_idx; j++ ) + { + whitenend_noise_shape[j] = L_shr( *noiseLevelPtr, 3 ); + move32(); + noiseLevelPtr += inc; + } + + IF( EQ_32( whitening_mode, ON_FIRST_LOST_FRAME ) ) + { + Word32 scf[SNS_NPTS]; + + sns_compute_scf_fx( whitenend_noise_shape, psychParams, L_frame, scf, sub( sub( 31, noiseLevelPtr_exp ), 3 ) ); + + sns_interpolate_scalefactors_fx( scfs_int, scf, ENC ); + sns_interpolate_scalefactors_fx( scfs_bg, scf, DEC ); + + scfs_for_shaping = &scfs_int[0]; // Q16 + } + ELSE /* whitening_mode == ON_FIRST_GOOD_FRAME */ + { + scfs_for_shaping = &scfs_bg[0]; // Q16 + } + + IF( sum32_sat( scfs_for_shaping, FDNS_NPTS ) > 0 ) + { + q_wns = sub( sub( 31, noiseLevelPtr_exp ), 3 ); + sns_shape_spectrum_fx( whitenend_noise_shape, &q_wns, psychParams, scfs_for_shaping, Q16, L_frame, NULL ); + + IF( GT_16( add( q_wns, 1 ), sub( 31, hFdCngCom->cngNoiseLevelExp ) ) ) + { + FOR( i = 0; i < sub( stop_idx, start_idx ); i++ ) + { + hFdCngCom->cngNoiseLevel[i] = L_shr( whitenend_noise_shape[start_idx + i], sub( add( q_wns, hFdCngCom->cngNoiseLevelExp ), 30 ) ); //(q_wns + 1) + move32(); + } + } + ELSE + { + Copy32( whitenend_noise_shape + start_idx, hFdCngCom->cngNoiseLevel, sub( stop_idx, start_idx ) ); + + scale_sig32( hFdCngCom->cngNoiseLevel + sub( stop_idx, start_idx ), sub( FFTCLDFBLEN, sub( stop_idx, start_idx ) ), sub( add( q_wns, hFdCngCom->cngNoiseLevelExp ), 30 ) ); + + hFdCngCom->cngNoiseLevelExp = sub( Q30, q_wns ); // Exponent = 31 - (q_wns + 1) + move16(); + } + } + ELSE + { + set32_fx( hFdCngCom->cngNoiseLevel, 0, sub( stop_idx, start_idx ) ); + } + + pop_wmops(); +} + + #ifdef IVAS_CODE_CNG_FIX185_PLC_FADEOUT void TonalMdctConceal_create_concealment_noise( float concealment_noise[L_FRAME48k], diff --git a/lib_dec/transition_dec.c b/lib_dec/transition_dec.c deleted file mode 100644 index d441f6ead49ddcb3a6a1ffab0962633db8157cd0..0000000000000000000000000000000000000000 --- a/lib_dec/transition_dec.c +++ /dev/null @@ -1,43 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include -#include "cnst.h" -#include "rom_com.h" -#include "prot.h" -#include "wmc_auto.h" diff --git a/lib_dec/transition_dec_fx.c b/lib_dec/transition_dec_fx.c index c7c5b5ab81a540568170bc6fa4da59957abfede2..b82378198604518d2b6ea4a15a4417d0a306a15e 100644 --- a/lib_dec/transition_dec_fx.c +++ b/lib_dec/transition_dec_fx.c @@ -789,11 +789,7 @@ static void tc_dec_fx( j = s_min( L_SUBFR, add( imp_pos, L_IMPULSE2 ) ); FOR( ; i <= j; i++ ) { -#ifdef BASOP_NOGLOB exc[i + i_subfr] = round_fx_o( L_shl_o( L_mult_o( pt_shape[i], gain_trans, &Overflow ), sc, &Overflow ), &Overflow ); /* (Qx * Q14 ) */ -#else - exc[i + i_subfr] = round_fx( L_shl( L_mult( pt_shape[i], gain_trans ), sc ) ); /* (Qx * Q14 ) */ -#endif move16(); } FOR( ; i < L_SUBFR; i++ ) diff --git a/lib_dec/updt_dec.c b/lib_dec/updt_dec.c deleted file mode 100644 index 2b370b05d8e9277dcc06bd7527fdc8260ce9ec57..0000000000000000000000000000000000000000 --- a/lib_dec/updt_dec.c +++ /dev/null @@ -1,44 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include -#include "options.h" -#include "prot.h" -#include "rom_com.h" -#include "cnst.h" -#include -#include "wmc_auto.h" diff --git a/lib_dec/updt_dec_fx.c b/lib_dec/updt_dec_fx.c index a7341ddc9f79a13c1b32f605697c32edfe1a216d..67621c442f24536792690208ac8915c5649d0846 100644 --- a/lib_dec/updt_dec_fx.c +++ b/lib_dec/updt_dec_fx.c @@ -401,11 +401,7 @@ void updt_bw_switching_fx( test(); IF( EQ_32( st_fx->output_Fs, 32000 ) && EQ_16( st_fx->bwidth, SWB ) ) { -#ifdef BASOP_NOGLOB st_fx->tilt_swb_fx = round_fx_sat( L_shl_sat( calc_tilt_bwe_fx( synth, Qpost, L_FRAME32k ), 3 ) ); // Q27 - 16 = Q11 -#else - st_fx->tilt_swb_fx = round_fx( L_shl( calc_tilt_bwe_fx( synth, Qpost, L_FRAME32k ), 3 ) ); -#endif } st_fx->prev_enerLH_fx = st_fx->enerLH_fx; // enerLH_fx_Q @@ -775,11 +771,7 @@ static void ivas_updt_bw_switching_fx( test(); IF( EQ_32( st_fx->output_Fs, 32000 ) && EQ_16( st_fx->bwidth, SWB ) ) { -#ifdef BASOP_NOGLOB st_fx->tilt_swb_fx = ivas_calc_tilt_bwe_fx( synth, Qpost, L_FRAME32k ); -#else - st_fx->tilt_swb_fx = round_fx( L_shl( calc_tilt_bwe_fx( synth, Qpost, L_FRAME32k ), 3 ) ); -#endif } st_fx->prev_enerLH_fx = st_fx->enerLH_fx; // enerLH_fx_Q diff --git a/lib_dec/vlpc_1st_dec.c b/lib_dec/vlpc_1st_dec.c deleted file mode 100644 index 97a511fb6147d83e4e1ad4814d4e5e7162d51f90..0000000000000000000000000000000000000000 --- a/lib_dec/vlpc_1st_dec.c +++ /dev/null @@ -1,42 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include -#include "options.h" -#include "prot.h" -#include "rom_com.h" -#include "wmc_auto.h" diff --git a/lib_dec/vlpc_2st_dec.c b/lib_dec/vlpc_2st_dec.c deleted file mode 100644 index e748899a9667996f0776eb65127752b66796a660..0000000000000000000000000000000000000000 --- a/lib_dec/vlpc_2st_dec.c +++ /dev/null @@ -1,40 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include "prot.h" -#include "wmc_auto.h" diff --git a/lib_dec/voiced_dec.c b/lib_dec/voiced_dec.c deleted file mode 100644 index 87f19fd33ef8183ad36f00fa878ea9f11a28379e..0000000000000000000000000000000000000000 --- a/lib_dec/voiced_dec.c +++ /dev/null @@ -1,55 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include -#include "prot.h" -#include "cnst.h" -#include "rom_com.h" -#include "wmc_auto.h" - -/*-------------------------------------------------------------------* - * ppp_voiced_decoder() - * - * Voiced decoder for SC-VBR - *-------------------------------------------------------------------*/ - -/*---------------------------------------------------------------------* - * sc_vbr_dec_init_flt() - * - * Initialize SC-VBR decoder - *---------------------------------------------------------------------*/ diff --git a/lib_dec/voiced_dec_fx.c b/lib_dec/voiced_dec_fx.c index d7ec44e9267ac3e488f3e3ba8fb531c567f21f8e..c937a3b2b6c032bb139c98919a65ae6af4f29f9f 100644 --- a/lib_dec/voiced_dec_fx.c +++ b/lib_dec/voiced_dec_fx.c @@ -242,30 +242,20 @@ ivas_error ppp_voiced_decoder_fx( /* Compensate for Q factor of energy to get log10(lag*eng) */ - Ltemp = log10_fx( Ltemp ); /* Ltemp=10log10(eng), Q23 */ -#ifdef BASOP_NOGLOB + Ltemp = log10_fx( Ltemp ); /* Ltemp=10log10(eng), Q23 */ Ltemp = L_add_sat( L_sub_sat( Ltemp, Ltemp_q ), logLag ); /* Ltemp=10*log10(lag*eng), Q23 */ hSC_VBR->lastLgainD_fx = round_fx_sat( L_shl_sat( (Word32) Mpy_32_16( extract_h( Ltemp ), extract_l( Ltemp ), 0x6666 ), 1 ) ); /* Q11 */ move16(); -#else - Ltemp = L_add( L_sub( Ltemp, Ltemp_q ), logLag ); /* Ltemp=10*log10(lag*eng), Q23 */ - hSC_VBR->lastLgainD_fx = round_fx( L_shl( (Word32) Mpy_32_16( extract_h( Ltemp ), extract_l( Ltemp ), 0x6666 ), 1 ) ); /* Q11 */ -#endif /* Process high band */ Ltemp = DTFS_setEngyHarm_fx( 2828, upper_cut_off_freq_of_interest, 2828, upper_cut_off_freq, 1, 0, &Qh, TMPDTFS_FX ); - Ltemp = log10_fx( Ltemp ); // Q23 -#ifdef BASOP_NOGLOB + Ltemp = log10_fx( Ltemp ); // Q23 Ltemp = L_add_sat( L_sub_sat( Ltemp, Ltemp_q ), logLag ); /* Ltemp=10*log10(lag*eng), Q23 */ hSC_VBR->lastHgainD_fx = round_fx_sat( L_shl_sat( (Word32) Mpy_32_16( extract_h( Ltemp ), extract_l( Ltemp ), 0x6666 ), 1 ) ); /* Q11 */ move16(); -#else - Ltemp = L_add( L_sub( Ltemp, Ltemp_q ), logLag ); /* Ltemp=10*log10(lag*eng), Q23 */ - hSC_VBR->lastHgainD_fx = round_fx( L_shl( (Word32) Mpy_32_16( extract_h( Ltemp ), extract_l( Ltemp ), 0x6666 ), 1 ) ); /* Q11 */ -#endif /* Need to unify the Q factors of both bands */ @@ -324,13 +314,8 @@ ivas_error ppp_voiced_decoder_fx( /* temp32_fx = (Word32)divide_dp((Word40)819200,(Word40)L_shl((Word32)CURRP_Q_D_FX->lag_fx,6),-23,1);//Q6 */ exp = norm_s( CURRP_Q_D_FX->lag_fx ); tmp = div_s( shl( 1, sub( 14, exp ) ), CURRP_Q_D_FX->lag_fx ); /*29-exp */ -#ifdef BASOP_NOGLOB L_tmp = L_shl_sat( L_mult0( tmp, 12800 ), sub( exp, 7 ) ); temp32_fx = round_fx_sat( L_tmp ); -#else - L_tmp = L_shl( L_mult0( tmp, 12800 ), sub( exp, 7 ) ); - temp32_fx = round_fx( L_tmp ); -#endif diff = round_fx( L_shl( temp32_fx, 16 - 6 ) ); /*Q0 */ CURRP_Q_D_FX->nH_fx = find_rem( upper_cut_off_freq, diff, &rem_fx ); /*Q0 */ diff --git a/lib_dec/waveadjust_fec_dec.c b/lib_dec/waveadjust_fec_dec.c deleted file mode 100644 index b573d3d7f8811e0014f216673ff2a11499026890..0000000000000000000000000000000000000000 --- a/lib_dec/waveadjust_fec_dec.c +++ /dev/null @@ -1,77 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include -#include "prot.h" -#include "wmc_auto.h" - - -/*-------------------------------------------------------------------* - * Local functions - * - *-------------------------------------------------------------------*/ - - -/*-------------------------------------------------------------------* - * waveform_adj2() - * - *-------------------------------------------------------------------*/ - -/*-------------------------------------------------------------------* - * concealment_decode() - * - * - *-------------------------------------------------------------------*/ - -/*-------------------------------------------------------------------* - * concealment_update() - * - * - *-------------------------------------------------------------------*/ - -/*-------------------------------------------------------------------* - * concealment_update2() - * - * - *-------------------------------------------------------------------*/ - -/*-------------------------------------------------------------------* - * concealment_signal_tuning() - * - * - *-------------------------------------------------------------------*/ diff --git a/lib_dec/waveadjust_fec_dec_fx.c b/lib_dec/waveadjust_fec_dec_fx.c index 0f7a45eb04d4cc5be0c54b7bf25ce2bbac0cb85e..80241a24c9f79d528f9c4e7004e9ab7a54348e6a 100644 --- a/lib_dec/waveadjust_fec_dec_fx.c +++ b/lib_dec/waveadjust_fec_dec_fx.c @@ -476,13 +476,8 @@ void pitch_modify_x( Word16 *s_LP /*Qx*/, Word16 *voicing /*Q15*/, Word16 *pitch eng1 = L_mult0( eng1_w, eng2_w ); norm = norm_l( eng1 ); -#ifdef BASOP_NOGLOB eng1_w = extract_h( L_shl_sat( eng1, norm ) ); eng2_w = extract_h( L_shl_sat( eng3, norm ) ); -#else - eng1_w = extract_h( L_shl( eng1, norm ) ); - eng2_w = extract_h( L_shl( eng3, norm ) ); -#endif IF( GE_32( eng3, eng1 ) ) { @@ -1246,32 +1241,18 @@ static void add_noise( Word16 *const sbuf, /*Qsbuf*/ IF( !firstFrame ) { -#ifdef BASOP_NOGLOB temp_OUT = sub_sat( noise_seg[0], mult( ( *outx_new_n1 ), 22282 /* 0.68 Q15 */ ) ); sbuf[0] = add_sat( sbuf[0], mult( ( temp_OUT ), *gain ) ); move16(); *gain = mac_r_sat( L_mult_sat( 32439 /* 0.99 Q15 */, *gain ), 328 /* 0.01 Q15 */, *gain_n ); -#else - temp_OUT = sub( noise_seg[0], mult( ( *outx_new_n1 ), 22282 /* 0.68 Q15 */ ) ); - sbuf[0] = add( sbuf[0], mult( ( temp_OUT ), *gain ) ); - move16(); - *gain = mac_r( L_mult( 32439 /* 0.99 Q15 */, *gain ), 328 /* 0.01 Q15 */, *gain_n ); -#endif } FOR( i = 1; i < Len; i++ ) { -#ifdef BASOP_NOGLOB temp_OUT = sub_sat( noise_seg[i], mult( ( noise_seg[i - 1] ), 22282 /* 0.68 Q15 */ ) ); sbuf[i] = add_sat( sbuf[i], mult( ( temp_OUT ), *gain ) ); move16(); *gain = mac_r_sat( L_mult( 32439 /* 0.99 Q15 */, *gain ), 328 /* 0.01 Q15 */, *gain_n ); -#else - temp_OUT = sub( noise_seg[i], mult( ( noise_seg[i - 1] ), 22282 /* 0.68 Q15 */ ) ); - sbuf[i] = add( sbuf[i], mult( ( temp_OUT ), *gain ) ); - move16(); - *gain = mac_r( L_mult( 32439 /* 0.99 Q15 */, *gain ), 328 /* 0.01 Q15 */, *gain_n ); -#endif } *outx_new_n1 = noise_seg[i - 1]; /*q0*/ @@ -1387,11 +1368,7 @@ static Word16 waveform_adj_fix( Word16 *overlapbuf, /*Qoverlapbuf*/ } FOR( i = 0; i < pitch125; i++ ) { -#ifdef BASOP_NOGLOB pitch125_data[i] = round_fx_sat( L_shr_sat( L_add_sat( ( L_mult( p_tmp[i], 20972 ) ), L_mac_sat( L_mult( p_tmp[i - 1], 5898 ), p_tmp[i + 1], 5898 ) ), s16MaxCoefNorm ) ); -#else - pitch125_data[i] = round_fx( L_shr( L_add( ( L_mult( p_tmp[i], 20972 ) ), L_mac( L_mult( p_tmp[i - 1], 5898 ), p_tmp[i + 1], 5898 ) ), s16MaxCoefNorm ) ); -#endif move16(); } } @@ -1553,26 +1530,14 @@ void waveform_adj2_fix( Word16 *overlapbuf, /*Qoverlapbuf*/ ratio = extract_l( L_shr( L_mult( i, ptable ), tablescale ) ); dat = shl( sbuf[i], s16MaxCoefNorm ); temp_OUT = mult( *recovery_gain, sub( 32767, ratio ) ); -#ifdef BASOP_NOGLOB outx_new[i] = round_fx_sat( L_add_sat( L_shr_sat( L_mult( temp_OUT, dat ), sub( s16MaxCoefNorm, 1 ) ), L_shr_sat( L_mult( shl( outx_new[i], s16MaxCoefNorm2 ), ratio ), s16MaxCoefNorm2 ) ) ); -#else - outx_new[i] = round_fx( L_add( L_shr( L_mult( temp_OUT, dat ), sub( s16MaxCoefNorm, 1 ) ), L_shr( L_mult( shl( outx_new[i], s16MaxCoefNorm2 ), ratio ), s16MaxCoefNorm2 ) ) ); -#endif move16(); -#ifdef BASOP_NOGLOB *recovery_gain = sub_sat( *recovery_gain, shr_r( step_concealgain, 1 ) ); /* q14 */ -#else - *recovery_gain = sub( *recovery_gain, shr_r( step_concealgain, 1 ) ); /* q14 */ -#endif } FOR( i = gain_zero_start; i < Framesize; i++ ) { ratio = extract_l( L_shr( L_mult( i, ptable ), tablescale ) ); -#ifdef BASOP_NOGLOB outx_new[i] = round_fx_sat( L_shr_sat( L_mult( shl( outx_new[i], s16MaxCoefNorm2 ), ratio ), s16MaxCoefNorm2 ) ); -#else - outx_new[i] = round_fx( L_shr( L_mult( shl( outx_new[i], s16MaxCoefNorm2 ), ratio ), s16MaxCoefNorm2 ) ); -#endif move16(); } diff --git a/lib_enc/ACcontextMapping_enc.c b/lib_enc/ACcontextMapping_enc.c deleted file mode 100644 index 250bfcf1ba83a538bcbe37c040e151911684b936..0000000000000000000000000000000000000000 --- a/lib_enc/ACcontextMapping_enc.c +++ /dev/null @@ -1,712 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include -#include "cnst.h" -#include "rom_com.h" -#include "prot.h" -#include "ivas_prot.h" /* Range coder header file */ -#include "ivas_rom_com.h" -#include "ivas_rom_enc.h" -#include "wmc_auto.h" -#include "prot_fx.h" - - -/*-------------------------------------------------------------------* - * ACcontextMapping_encode2_no_mem_s17_LC() - * - * Arithmetic encoder - *-------------------------------------------------------------------*/ -/*-------------------------------------------------------------------* - * find_last_nz_pair() - * - * - *-------------------------------------------------------------------*/ - -static Word16 find_last_nz_pair( - const Word16 x[], - const Word16 length, - const CONTEXT_HM_CONFIG *hm_cfg ) -{ - Word16 last_nz, i; - const Word16 *tmp; - - last_nz = 2; - move16(); - - IF( hm_cfg ) - { - /* mapped kernel */ - tmp = hm_cfg->indexBuffer; - - FOR( i = length; i >= 4; i -= 2 ) - { - test(); - IF( x[tmp[i - 2]] || x[tmp[i - 1]] ) - { - last_nz = i; - move16(); - BREAK; - } - } - } - ELSE - { - /* unmapped kernel */ - - FOR( i = length; i >= 4; i -= 2 ) - { - test(); - IF( x[i - 2] || x[i - 1] ) - { - last_nz = i; - move16(); - BREAK; - } - } - } - - return last_nz; -} - - -/*-------------------------------------------------------------------* - * ACcontextMapping_encode2_estimate_no_mem_s17_LC() - * - * - *-------------------------------------------------------------------*/ -/*-------------------------------------------------------------------* - * RCcontextMapping_encode2_estimate_no_mem_s17_LCS() - * - * Range coder bit-estimation - *-------------------------------------------------------------------*/ - -Word16 RCcontextMapping_encode2_estimate_no_mem_s17_LCS( - Word16 *x, /* Spectral coefficients */ - const Word16 nt, /* L - size of spectrum (no. of spectral coefficients) */ - Word16 *lastnz_out, - Word16 *nEncoded, /* No. of spectral coefficients that can be coded without an overflow occuring */ - const Word16 target, /* Target bits */ - Word16 *stop, - Word16 mode, - CONTEXT_HM_CONFIG *hm_cfg /* context-based harmonic model configuration */ -) -{ - /* Common variables */ - Word16 a1, b1; - Word16 k, pki, lev1; - UWord16 t; - Word16 lastnz, lastnz2; - Word16 rateFlag; - Word32 bit_estimate_fx; - Word16 bit_estimate_e; - Word16 symbol; - const UWord8 *lookup; - Word32 nbits2_fx; // Q23 - Word16 nbits2_e; // Q23 - - /* Initialization */ - bit_estimate_fx = 2 * ONE_IN_Q29; - bit_estimate_e = 2; - move32(); - nbits2_fx = 0; - nbits2_e = 0; - move32(); - - /* bits to encode lastnz */ - k = 1; - move16(); - - WHILE( LT_16( k, nt / 2 ) ) - { - bit_estimate_fx = BASOP_Util_Add_Mant32Exp( bit_estimate_fx, bit_estimate_e, ONE_IN_Q30, 1, &bit_estimate_e ); - k = k << 1; - /* check while condition */ - } - - nbits2_fx = bit_estimate_fx; - nbits2_e = bit_estimate_e; - - IF( hm_cfg ) - { - Word16 a1_i, b1_i; - Word16 stop2; - Word16 total_output_bits; - Word16 nt_half; - Word32 c[2], *ctx; - Word32 p1, p2; - Word16 ii[2]; - Word16 idx1, idx2, idx; - Word16 numPeakIndicesOrig = 0, numHoleIndices = 0; /* only to avoid compiler warning */ - move16(); - move16(); - - /* Rate flag */ - IF( GT_16( target, 400 ) ) - { - rateFlag = 2 << NBITS_CONTEXT; /* Select context-A for higher bitrates */ - move16(); - } - ELSE - { - rateFlag = 0; /* Select context-B for lower bitrates */ - move16(); - } - - nt_half = shr( nt, 1 ); - move16(); - stop2 = 0; - move16(); - c[0] = c[1] = 0; - move32(); - move32(); - - /* Find last non-zero tuple in the mapped domain signal */ - lastnz = find_last_nz_pair( x, nt, hm_cfg ); - - lastnz2 = 2; - move16(); - - /* mapped domain */ - numPeakIndicesOrig = hm_cfg->numPeakIndices; - move16(); - hm_cfg->numPeakIndices = s_min( hm_cfg->numPeakIndices, lastnz ); - move16(); - numHoleIndices = sub( lastnz, hm_cfg->numPeakIndices ); - - /* Mark hole indices beyond lastnz as pruned */ - FOR( k = numHoleIndices; k < hm_cfg->numHoleIndices; ++k ) - { - hm_cfg->holeIndices[k] = add( hm_cfg->holeIndices[k], nt ); - move16(); - } - - ii[0] = numPeakIndicesOrig; - move16(); - ii[1] = 0; - move16(); - - p1 = p2 = 0; /* to avoid compilation warnings */ - move32(); - move32(); - - /* Main Loop through the 2-tuples */ - FOR( k = 0; k < lastnz; k += 2 ) - { - a1_i = get_next_coeff_mapped_ivas_fx( ii, &p1, &idx1, hm_cfg ); - b1_i = get_next_coeff_mapped_ivas_fx( ii, &p2, &idx2, hm_cfg ); - - idx = s_min( idx1, idx2 ); - - /* Get context */ - ctx = &c[L_or( p1, p2 )]; - - t = (UWord16) L_add( *ctx, rateFlag ); - IF( LT_16( nt_half, idx ) ) - { - t = add( t, ( 1 << NBITS_CONTEXT ) ); - } - - /* Init current 2-tuple encoding */ - a1 = (Word16) abs( x[a1_i] ); - b1 = (Word16) abs( x[b1_i] ); - lev1 = -( 1 << ( NBITS_CONTEXT + NBITS_RATEQ ) ); - - bit_estimate_fx = BASOP_Util_Add_Mant32Exp( bit_estimate_fx, bit_estimate_e, s_min( a1, 1 ) * ONE_IN_Q30, 1, &bit_estimate_e ); - bit_estimate_fx = BASOP_Util_Add_Mant32Exp( bit_estimate_fx, bit_estimate_e, s_min( b1, 1 ) * ONE_IN_Q30, 1, &bit_estimate_e ); - - /* pre-compute address of ari_pk_s17_LC_ext[0][Val_esc] to avoid doing it multiple times inside the loop */ - lookup = &ari_lookup_s17_LC[t] + ( 1 << ( NBITS_CONTEXT + NBITS_RATEQ ) ); - - /* check while condition */ - /* MSBs coding */ - WHILE( GE_16( s_max( a1, b1 ), A_THRES ) ) - { - pki = lookup[lev1]; /* ESC symbol */ - - bit_estimate_fx = BASOP_Util_Add_Mant32Exp( bit_estimate_fx, bit_estimate_e, ari_bit_estimate_s17_LC_fx[pki][VAL_ESC], 8, &bit_estimate_e ); - bit_estimate_fx = BASOP_Util_Add_Mant32Exp( bit_estimate_fx, bit_estimate_e, 2 * ONE_IN_Q29, 2, &bit_estimate_e ); /* Add 2 LSB bits corresponding to the bit-plane */ - - ( a1 ) = shr( a1, 1 ); - ( b1 ) = shr( b1, 1 ); - - lev1 = s_min( add( lev1, ( 1 << ( NBITS_CONTEXT + NBITS_RATEQ ) ) ), 2 << ( NBITS_CONTEXT + NBITS_RATEQ ) ); - - /* check while condition */ - } - - pki = lookup[lev1]; - - symbol = add( a1, i_mult( A_THRES, b1 ) ); - bit_estimate_fx = BASOP_Util_Add_Mant32Exp( bit_estimate_fx, bit_estimate_e, ari_bit_estimate_s17_LC_fx[pki][symbol], 8, &bit_estimate_e ); - - /* Should we truncate? */ - IF( GT_32( L_shr( bit_estimate_fx, sub( Q16, bit_estimate_e ) ), L_shl( target, Q15 ) ) ) - { - stop2 = 1; - move16(); - - IF( *stop ) - { - BREAK; - } - } - ELSE - { - lastnz2 = add( b1_i, 1 ); - nbits2_fx = bit_estimate_fx; - move32(); - nbits2_e = bit_estimate_e; - move16(); - } - - /* Update context for next 2-tuple */ - IF( EQ_32( p1, p2 ) ) /* peak-peak or hole-hole context */ - { - lev1 = shr( lev1, NBITS_CONTEXT + NBITS_RATEQ ); - - IF( lev1 <= 0 ) - { - t = add( 1, i_mult( add( a1, b1 ), add( lev1, 2 ) ) ); - } - ELSE - { - t = add( 13, lev1 ); - } - - *ctx = L_add( imult3216( L_and( *ctx, 0xf ), 16 ), t ); - move32(); - } - ELSE - { - /* mixed context */ - - IF( s_and( idx1, 1 ) ) - { - /* update first context */ - c[p1] = update_mixed_context_ivas_fx( c[p1], (Word16) abs( x[a1_i] ) ); - move32(); - } - - IF( s_and( idx2, 1 ) ) - { - /* update second context */ - c[p2] = update_mixed_context_ivas_fx( c[p2], (Word16) abs( x[b1_i] ) ); - move32(); - } - } - - } /*end of the 2-tuples loop*/ - - total_output_bits = round_fx( L_shr( bit_estimate_fx, sub( Q15, bit_estimate_e ) ) ); - - IF( *stop ) - { - total_output_bits = round_fx( L_shr( nbits2_fx, sub( Q15, nbits2_e ) ) ); - } - - IF( stop2 ) - { - stop2 = total_output_bits; - move16(); - } - - *nEncoded = lastnz2; - move16(); - *stop = stop2; /* If zero, it means no overflow occured during bit-estimation */ - move16(); - *lastnz_out = lastnz; - move16(); - - /* Restore hole indices beyond lastnz */ - FOR( k = numHoleIndices; k < hm_cfg->numHoleIndices; ++k ) - { - hm_cfg->holeIndices[k] = sub( hm_cfg->holeIndices[k], nt ); - move16(); - } - hm_cfg->numPeakIndices = numPeakIndicesOrig; - move16(); - - return round_fx( L_add( L_shr( nbits2_fx, sub( Q15, nbits2_e ) ), ONE_IN_Q14 ) ); - } - ELSE /* if (!hm_cfg) */ - { - Word16 esc_nb, cp, rateQ; - UWord16 s; - Word16 tot_bits2; - Word16 overflow_flag = 0; - - /* Rate flag */ - IF( GT_16( target, 400 ) ) - { - rateFlag = 2; - move16(); - } - ELSE - { - rateFlag = 0; /* Select context-B for lower bitrates */ - move16(); - } - - t = 0; - move16(); - s = 0; - move16(); - cp = 0; - move16(); - lastnz = 1; - move16(); - lastnz2 = 0; - move16(); - tot_bits2 = 0; - move16(); - - /* Find last non-zero tuple in the mapped domain signal */ - FOR( lastnz = sub( nt, 2 ); lastnz >= 0; lastnz -= 2 ) - { - test(); - IF( ( x[lastnz] != 0 ) || ( x[lastnz + 1] != 0 ) ) - { - BREAK; - } - } - lastnz = add( lastnz, 2 ); - IF( LT_16( lastnz, 2 ) ) - { - lastnz = 2; /* At least one tuple is coded */ - move16(); - } - - lastnz2 = 2; - move16(); - - /* Main Loop through the 2-tuples */ - FOR( k = 0; k < lastnz; k += 2 ) - { - /* Init current 2-tuple encoding */ - a1 = abs_s( x[k] ); - b1 = abs_s( x[k + 1] ); - lev1 = 0; - move16(); - esc_nb = 0; - move16(); - rateQ = add( rateFlag, (Word16) GT_16( k, shr( nt, 1 ) ) ); - - bit_estimate_fx = BASOP_Util_Add_Mant32Exp( bit_estimate_fx, bit_estimate_e, s_min( a1, 1 ) * ONE_IN_Q30, 1, &bit_estimate_e ); - bit_estimate_fx = BASOP_Util_Add_Mant32Exp( bit_estimate_fx, bit_estimate_e, s_min( b1, 1 ) * ONE_IN_Q30, 1, &bit_estimate_e ); - - /* pre-compute address of ari_pk_s17_LC_ext[0][Val_esc] to avoid doing it multiple times inside the loop */ - lookup = &ari_lookup_s17_LC[t + shl( rateQ, NBITS_CONTEXT )]; - - /* check while condition */ - /* MSBs coding */ - WHILE( GE_16( s_max( a1, b1 ), A_THRES ) ) - { - pki = lookup[( esc_nb << ( NBITS_CONTEXT + NBITS_RATEQ ) )]; - - bit_estimate_fx = BASOP_Util_Add_Mant32Exp( bit_estimate_fx, bit_estimate_e, ari_bit_estimate_s17_LC_fx[pki][VAL_ESC], 8, &bit_estimate_e ); - bit_estimate_fx = BASOP_Util_Add_Mant32Exp( bit_estimate_fx, bit_estimate_e, 2 * ONE_IN_Q29, 2, &bit_estimate_e ); /* Add 2 LSB bits corresponding to the bit-plane */ - - ( a1 ) = shr( a1, 1 ); - ( b1 ) = shr( b1, 1 ); - - lev1 = add( lev1, 1 ); - esc_nb = s_min( lev1, 3 ); - - /* check while condition */ - } - - pki = lookup[( esc_nb << ( NBITS_CONTEXT + NBITS_RATEQ ) )]; - - symbol = add( a1, i_mult( A_THRES, b1 ) ); - bit_estimate_fx = BASOP_Util_Add_Mant32Exp( bit_estimate_fx, bit_estimate_e, ari_bit_estimate_s17_LC_fx[pki][symbol], 8, &bit_estimate_e ); - - /* Should we truncate? */ - IF( GT_32( L_shr( bit_estimate_fx, sub( Q16, bit_estimate_e ) ), L_shl( target, Q15 ) ) ) /* Overflow occured */ - { - overflow_flag = 1; - move16(); - } - ELSE - { - IF( abs_s( x[k] ) || abs_s( x[k + 1] ) ) /* No overflow & non-zero tuple */ - { - nbits2_fx = bit_estimate_fx; - nbits2_e = bit_estimate_e; - move32(); - lastnz2 = add( k, 2 ); - } - } - - /* Update context for next 2-tuple */ - IF( LT_16( esc_nb, 2 ) ) - { - cp = add( 1, i_mult( add( a1, b1 ), add( esc_nb, 1 ) ) ); - } - ELSE - { - cp = add( 12, esc_nb ); - } - /*shift old bits and replace last 4 bits*/ - s = ( s << 4 ) + cp; - t = ( s & 0xFF ); - - } /*end of the 2-tuples loop*/ - - tot_bits2 = round_fx( L_shr( nbits2_fx, sub( Q15, nbits2_e ) ) ); - IF( lastnz2 < lastnz ) /* Overflow occured because unable to code all tuples */ - { - overflow_flag = 1; - move16(); - } - IF( EQ_16( mode, -1 ) ) - { - tot_bits2 = round_fx( L_shr( bit_estimate_fx, sub( Q15, bit_estimate_e ) ) ); - } - IF( overflow_flag == 0 ) /* No overflow */ - { - *stop = 0; - move16(); - } - ELSE /* Overflow */ - { - IF( *stop ){ - *stop = tot_bits2; - move16(); - } - ELSE - { - *stop = round_fx( L_shr( bit_estimate_fx, sub( Q15, bit_estimate_e ) ) ); - move16(); - } -} - -*lastnz_out = lastnz; -move16(); -*nEncoded = lastnz2; -move16(); -/* Safety mechanism to avoid overflow */ -test(); -IF( EQ_16( lastnz2, 2 ) && EQ_16( overflow_flag, 1 ) ) -{ - FOR( k = 0; k < lastnz2; k++ ) - { - x[k] = 0; - move16(); - } -} - -return tot_bits2; -} -} - -/*-------------------------------------------------------------------* - * RCcontextMapping_encode2_estimate_bandWise_start() - * - * Range coder - start bandwise bit-estimation - *-------------------------------------------------------------------*/ - -Word16 RCcontextMapping_encode2_estimate_bandWise_start( - Word16 *x, - const Word16 nt, - const Word16 target, - HANDLE_RC_CONTEXT_MEM hContextMem ) -{ - Word16 i, k; - - /* Rate flag */ - IF( GT_16( target, 400 ) ) - { - hContextMem->rateFlag = 2 << NBITS_CONTEXT; - move16(); - } - ELSE - { - hContextMem->rateFlag = 0; - move16(); - } - - hContextMem->bit_estimate_fx = 2; - move32(); - hContextMem->bit_estimate_e = Q31; - move16(); - - - /* Init */ - hContextMem->nt_half = shr( nt, 1 ); - move16(); - - /* bits to encode lastnz */ - k = 1; - move16(); - - WHILE( LT_16( k, hContextMem->nt_half ) ) - { - hContextMem->bit_estimate_fx = L_add( hContextMem->bit_estimate_fx, 1 ); - move32(); - - k = shl( k, 1 ); - /* check while condition */ - } - - /* bits to encode lastnz */ - hContextMem->nbits_old = extract_l( hContextMem->bit_estimate_fx ); - move16(); - - hContextMem->ctx = 0; - move16(); - hContextMem->lastnz = 2; - move16(); - - /* Find last non-zero tuple */ - - FOR( i = nt; i >= 4; i -= 2 ) - { - test(); - IF( x[i - 2] != 0 || x[i - 1] != 0 ) - { - hContextMem->lastnz = i; - move16(); - break; - } - } - Word16 tmp2 = extract_l( hContextMem->bit_estimate_fx ); - Word16 tmp = norm_l( hContextMem->bit_estimate_fx ); - hContextMem->bit_estimate_e = sub( Q31, tmp ); - move16(); - hContextMem->bit_estimate_fx = L_shl( hContextMem->bit_estimate_fx, tmp ); - move32(); - - return tmp2; -} - -/*-------------------------------------------------------------------* - * RCcontextMapping_encode2_estimate_bandWise() - * - * Range coder - bandwise bit-estimation - *-------------------------------------------------------------------*/ - -Word16 RCcontextMapping_encode2_estimate_bandWise( - Word16 *x, - const Word16 start_line, - const Word16 end_line, - HANDLE_RC_CONTEXT_MEM hContextMem ) -{ - Word16 a1, b1, a1_i, b1_i; - Word16 k, pki, lev1; - UWord16 t; - Word16 bandBits = 0; - move16(); - Word16 total_output_bits; /* No. of bits after finalization */ - Word16 symbol; - const UWord8 *lookup; - Word16 idx; - - /* Main Loop through the 2-tuples */ - /*hContextMem->nt_half = end_line >> 1;*/ - FOR( k = start_line; k < min( hContextMem->lastnz, end_line ); k += 2 ) - { - a1_i = k; - move16(); - b1_i = add( k, 1 ); - - idx = k; - move16(); - - /* Get context */ - t = add( hContextMem->ctx, hContextMem->rateFlag ); - t = add( t, GE_16( hContextMem->nt_half, idx ) ? 0 : ( 1 << NBITS_CONTEXT ) ); - - /* Init current 2-tuple encoding */ - a1 = abs_s( x[a1_i] ); - b1 = abs_s( x[b1_i] ); - lev1 = -( 1 << ( NBITS_CONTEXT + NBITS_RATEQ ) ); - - /* Signs Bits */ - hContextMem->bit_estimate_fx = BASOP_Util_Add_Mant32Exp( hContextMem->bit_estimate_fx, hContextMem->bit_estimate_e, s_min( a1, 1 ) * ONE_IN_Q30, Q1, &hContextMem->bit_estimate_e ); - hContextMem->bit_estimate_fx = BASOP_Util_Add_Mant32Exp( hContextMem->bit_estimate_fx, hContextMem->bit_estimate_e, s_min( b1, 1 ) * ONE_IN_Q30, Q1, &hContextMem->bit_estimate_e ); - - /* pre-compute address of ari_pk_s17_LC_ext[0][Val_esc] to avoid doing it multiple times inside the loop */ - lookup = &ari_lookup_s17_LC[t] + ( 1 << ( NBITS_CONTEXT + NBITS_RATEQ ) ); - - /* check while condition */ - /* MSBs coding */ - WHILE( GE_16( s_max( a1, b1 ), A_THRES ) ) - { - pki = lookup[lev1]; - hContextMem->bit_estimate_fx = BASOP_Util_Add_Mant32Exp( hContextMem->bit_estimate_fx, hContextMem->bit_estimate_e, ari_bit_estimate_s17_LC_fx[pki][VAL_ESC], Q8, &hContextMem->bit_estimate_e ); - hContextMem->bit_estimate_fx = BASOP_Util_Add_Mant32Exp( hContextMem->bit_estimate_fx, hContextMem->bit_estimate_e, 2 * ONE_IN_Q29, Q2, &hContextMem->bit_estimate_e ); /* Add the 2 LSB bits that were shifted out */ - // hContextMem->bit_estimate = hContextMem->bit_estimate + ari_bit_estimate_s17_LC[pki][VAL_ESC]; - // hContextMem->bit_estimate += 2; /* Add the 2 LSB bits that were shifted out */ - - ( a1 ) = shr( a1, 1 ); - ( b1 ) = shr( b1, 1 ); - - lev1 = s_min( add( lev1, ( 1 << ( NBITS_CONTEXT + NBITS_RATEQ ) ) ), 2 << ( NBITS_CONTEXT + NBITS_RATEQ ) ); - /* check while condition */ - } - - pki = lookup[lev1]; - symbol = add( a1, i_mult( A_THRES, b1 ) ); /* MSB symbol */ - hContextMem->bit_estimate_fx = BASOP_Util_Add_Mant32Exp( hContextMem->bit_estimate_fx, hContextMem->bit_estimate_e, ari_bit_estimate_s17_LC_fx[pki][symbol], Q8, &hContextMem->bit_estimate_e ); - // hContextMem->bit_estimate = hContextMem->bit_estimate + ari_bit_estimate_s17_LC[pki][symbol]; - - /* Update context */ - lev1 = shr( lev1, NBITS_CONTEXT + NBITS_RATEQ ); - - IF( lev1 <= 0 ) - { - t = add( 1, i_mult( add( a1, b1 ), add( lev1, 2 ) ) ); - } - ELSE - { - t = add( 13, lev1 ); - } - - hContextMem->ctx = add( i_mult( s_and( hContextMem->ctx, 0xf ), 16 ), t ); - - } /*end of the 2-tuples loop*/ - total_output_bits = round_fx( L_shr( hContextMem->bit_estimate_fx, sub( Q15, hContextMem->bit_estimate_e ) ) ); - // total_output_bits = (Word16) ( hContextMem->bit_estimate + 0.5f ); - - bandBits = sub( total_output_bits, hContextMem->nbits_old ); - hContextMem->nbits_old = total_output_bits; - move16(); - - return bandBits; -} diff --git a/lib_enc/ACcontextMapping_enc_fx.c b/lib_enc/ACcontextMapping_enc_fx.c index 21089de9fd00cfbd08cbc87a2f430cc26fd55f69..c52fddf97ee55b28084b7e44ba010a1edf76d3d4 100644 --- a/lib_enc/ACcontextMapping_enc_fx.c +++ b/lib_enc/ACcontextMapping_enc_fx.c @@ -11,8 +11,12 @@ #include "ivas_prot_fx.h" #include "rom_com.h" #include "ivas_rom_com.h" +#include "ivas_rom_enc.h" #include "prot_fx_enc.h" +#define MAKE_NUMBER_QX( number, QX ) ( ( number ) << ( QX ) ) /* evaulated at compile time */ +#define MAKE_VARIABLE_QX( variable, QX ) W_shl( W_deposit32_l( L_deposit_l( ( variable ) ) ), ( QX ) ) /* evaluated at run time */ + /*-------------------------------------------------------------------* * ACcontextMapping_encode2_no_mem_s17_LC_fx() * @@ -29,11 +33,11 @@ */ void ACcontextMapping_encode2_no_mem_s17_LC_fx( BSTR_ENC_HANDLE hBstr, /* i/o: bitstream handle */ - Word16 *x, - Word16 nt, - Word16 lastnz, - Word16 nbbits, - Word16 resQMaxBits, + Word16 *x, /* Q0 */ + Word16 nt, /* Q0 */ + Word16 lastnz, /* Q0 */ + Word16 nbbits, /* Q0 */ + Word16 resQMaxBits, /* Q0 */ CONTEXT_HM_CONFIG *hm_cfg ) { Word16 ptr[BITBUFSIZE]; @@ -57,7 +61,8 @@ void ACcontextMapping_encode2_no_mem_s17_LC_fx( a1 = 0; /* to avoid compilation warnings */ b1 = 0; /* to avoid compilation warnings */ - + move16(); + move16(); /* Rate flag */ rateFlag = 0; @@ -75,41 +80,41 @@ void ACcontextMapping_encode2_no_mem_s17_LC_fx( move16(); /* Bits for encoding the number of encoded tuples */ - nbbits_ntuples = sub( 14, norm_s( negate( nt ) ) ); + nbbits_ntuples = sub( 14, norm_s( negate( nt ) ) ); /* Q0 */ t = 0; move16(); - bp = nbbits_ntuples; + bp = nbbits_ntuples; /* Q0 */ move16(); nbbits_signs = 0; move16(); nbbits_lsbs = 0; move16(); - nbbits_m2 = sub( nbbits, 2 ); + nbbits_m2 = sub( nbbits, 2 ); /* Q0 */ flag_overflow = 0; move16(); IF( hm_cfg ) /* mapped domain */ { - numPeakIndicesOrig = hm_cfg->numPeakIndices; + numPeakIndicesOrig = hm_cfg->numPeakIndices; /* Q0 */ move16(); - hm_cfg->numPeakIndices = s_min( hm_cfg->numPeakIndices, lastnz ); + hm_cfg->numPeakIndices = s_min( hm_cfg->numPeakIndices, lastnz ); /* Q0 */ move16(); - numHoleIndices = sub( lastnz, hm_cfg->numPeakIndices ); + numHoleIndices = sub( lastnz, hm_cfg->numPeakIndices ); /* Q0 */ /* Mark hole indices beyond lastnz as pruned */ FOR( k = numHoleIndices; k < hm_cfg->numHoleIndices; ++k ) { - hm_cfg->holeIndices[k] = add( hm_cfg->holeIndices[k], nt ); + hm_cfg->holeIndices[k] = add( hm_cfg->holeIndices[k], nt ); /* Q0 */ move16(); } - ii[0] = numPeakIndicesOrig; + ii[0] = numPeakIndicesOrig; /* Q0 */ move16(); ii[1] = 0; move16(); - get_next_coeff = get_next_coeff_mapped; + get_next_coeff = get_next_coeff_mapped; /* Q0 */ move16(); } ELSE /* unmapped domain */ @@ -121,7 +126,7 @@ void ACcontextMapping_encode2_no_mem_s17_LC_fx( move16(); move16(); - get_next_coeff = get_next_coeff_unmapped; + get_next_coeff = get_next_coeff_unmapped; /* Q0 */ move16(); /* Find last non-zero tuple */ @@ -133,7 +138,7 @@ void ACcontextMapping_encode2_no_mem_s17_LC_fx( WHILE( s_or( x[lastnz - 1], x[lastnz - 2] ) == 0 ) { - lastnz = sub( lastnz, 2 ); + lastnz = sub( lastnz, 2 ); /* Q0 */ } x[0] = a1; move16(); @@ -150,21 +155,20 @@ void ACcontextMapping_encode2_no_mem_s17_LC_fx( FOR( k = 0; k < lastnz; k += 2 ) { /* First coefficient */ - a1_i = get_next_coeff( ii, &p1, &idx1, hm_cfg ); + a1_i = get_next_coeff( ii, &p1, &idx1, hm_cfg ); /* Q0 */ /* Second coefficient */ - b1_i = get_next_coeff( ii, &p2, &idx2, hm_cfg ); + b1_i = get_next_coeff( ii, &p2, &idx2, hm_cfg ); /* Q0 */ - idx = s_min( idx1, idx2 ); + idx = s_min( idx1, idx2 ); /* Q0 */ /* Get context */ - ctx = &c[s_or( p1, p2 )]; - move16(); + ctx = &c[s_or( p1, p2 )]; /* Q0 */ /* _DIFF_FLOAT_FIX_ float is using t as UWord16 */ - t = add( *ctx, rateFlag ); + t = add( *ctx, rateFlag ); /* Q0 */ if ( GT_16( idx, nt_half ) ) { - t = add( t, 1 << NBITS_CONTEXT ); + t = add( t, 1 << NBITS_CONTEXT ); /* Q0 */ } /* Init current 2-tuple encoding */ @@ -179,43 +183,43 @@ void ACcontextMapping_encode2_no_mem_s17_LC_fx( move16(); } - a1 = abs_s( x[a1_i] ); - b1 = abs_s( x[b1_i] ); + a1 = abs_s( x[a1_i] ); /* Q0 */ + b1 = abs_s( x[b1_i] ); /* Q0 */ lev1 = -1; move16(); /*Copy states*/ ari_copy_states_fx( &as, &as_overflow ); - bp_overflow = bp; + bp_overflow = bp; /* Q0 */ move16(); - nbbits_signs_overflow = nbbits_signs; + nbbits_signs_overflow = nbbits_signs; /* Q0 */ move16(); - nbbits_lsbs_overflow = nbbits_lsbs; + nbbits_lsbs_overflow = nbbits_lsbs; /* Q0 */ move16(); /*Signs encoding*/ - signs[nbbits_signs] = lshr( x[a1_i], 15 ); + signs[nbbits_signs] = lshr( x[a1_i], 15 ); /* Q0 */ move16(); if ( a1 > 0 ) { - nbbits_signs = add( nbbits_signs, 1 ); + nbbits_signs = add( nbbits_signs, 1 ); /* Q0 */ } - signs[nbbits_signs] = lshr( x[b1_i], 15 ); + signs[nbbits_signs] = lshr( x[b1_i], 15 ); /* Q0 */ move16(); if ( b1 > 0 ) { - nbbits_signs = add( nbbits_signs, 1 ); + nbbits_signs = add( nbbits_signs, 1 ); /* Q0 */ } /* MSBs coding */ WHILE( GE_16( s_max( a1, b1 ), A_THRES ) ) { - tmp = add( t, Tab_esc_nb[lev1 + 1] ); + tmp = add( t, Tab_esc_nb[lev1 + 1] ); /* Q0 */ assert( tmp >= 0 && tmp < 4096 ); - pki = ari_lookup_s17_LC[tmp]; + pki = ari_lookup_s17_LC[tmp]; /* Q0 */ move16(); - bp = ari_encode_14bits_ext_fx( ptr, bp, &as, VAL_ESC, ari_pk_s17_LC_ext[pki] ); + bp = ari_encode_14bits_ext_fx( ptr, bp, &as, VAL_ESC, ari_pk_s17_LC_ext[pki] ); /* Q0 */ *lsbs_bits2-- = s_and( a1, 1 ); move16(); @@ -223,32 +227,32 @@ void ACcontextMapping_encode2_no_mem_s17_LC_fx( move16(); /* LSBs bit counting */ - nbbits_lsbs = add( nbbits_lsbs, 2 ); + nbbits_lsbs = add( nbbits_lsbs, 2 ); /* Q0 */ a1 = shr( a1, 1 ); b1 = shr( b1, 1 ); - lev1 = s_min( add( lev1, 1 ), 2 ); + lev1 = s_min( add( lev1, 1 ), 2 ); /* Q0 */ } - tmp = add( t, Tab_esc_nb[lev1 + 1] ); + tmp = add( t, Tab_esc_nb[lev1 + 1] ); /* Q0 */ assert( tmp >= 0 && tmp < 4096 ); - pki = ari_lookup_s17_LC[tmp]; + pki = ari_lookup_s17_LC[tmp]; /* Q0 */ move16(); - bp = ari_encode_14bits_ext_fx( ptr, bp, &as, add( a1, shl( b1, A_THRES_SHIFT ) ), ari_pk_s17_LC_ext[pki] ); + bp = ari_encode_14bits_ext_fx( ptr, bp, &as, add( a1, shl( b1, A_THRES_SHIFT ) ), ari_pk_s17_LC_ext[pki] ); /* Q0 */ /* Check bit budget */ IF( GT_16( add( add( add( bp, extract_l( as.value ) ), nbbits_signs ), nbbits_lsbs ), nbbits_m2 ) ) { ari_copy_states_fx( &as_overflow, &as ); - bp = bp_overflow; + bp = bp_overflow; /* Q0 */ move16(); IF( flag_overflow == 0 ) { - nbbits_signs = nbbits_signs_overflow; + nbbits_signs = nbbits_signs_overflow; /* Q0 */ move16(); - nbbits_lsbs = nbbits_lsbs_overflow; + nbbits_lsbs = nbbits_lsbs_overflow; /* Q0 */ move16(); IF( hm_cfg ) { @@ -264,14 +268,14 @@ void ACcontextMapping_encode2_no_mem_s17_LC_fx( move16(); assert( t >= 0 && t < 4096 ); - pki = ari_lookup_s17_LC[t]; + pki = ari_lookup_s17_LC[t]; /* Q0 */ move16(); - bp = ari_encode_14bits_ext_fx( ptr, bp, &as, 0, ari_pk_s17_LC_ext[pki] ); + bp = ari_encode_14bits_ext_fx( ptr, bp, &as, 0, ari_pk_s17_LC_ext[pki] ); /* Q0 */ IF( GT_16( add( add( add( bp, extract_l( as.value ) ), nbbits_signs ), nbbits_lsbs ), nbbits_m2 ) ) { ari_copy_states_fx( &as_overflow, &as ); - bp = bp_overflow; + bp = bp_overflow; /* Q0 */ move16(); BREAK; } @@ -297,27 +301,27 @@ void ACcontextMapping_encode2_no_mem_s17_LC_fx( if ( lev1 == 0 ) t = add( t, t ); - *ctx = add( shl( s_and( *ctx, 0xf ), 4 ), add( t, 1 ) ); + *ctx = add( shl( s_and( *ctx, 0xf ), 4 ), add( t, 1 ) ); /* Q0 */ move16(); } ELSE /* mixed context */ { IF( s_and( idx1, 1 ) ) /* update first context */ { - c[p1] = update_mixed_context( c[p1], abs_s( x[a1_i] ) ); + c[p1] = update_mixed_context( c[p1], abs_s( x[a1_i] ) ); /* Q0 */ move16(); } IF( s_and( idx2, 1 ) ) /* update second context */ { - c[p2] = update_mixed_context( c[p2], abs_s( x[b1_i] ) ); + c[p2] = update_mixed_context( c[p2], abs_s( x[b1_i] ) ); /* Q0 */ move16(); } } } /*end of the 2-tuples loop*/ /* End arithmetic coder, overflow management */ - bp = ari_done_encoding_14bits_fx( ptr, bp, &as ); + bp = ari_done_encoding_14bits_fx( ptr, bp, &as ); /* Q0 */ /* Overflow is detected */ IF( NE_16( k, lastnz ) ) @@ -325,20 +329,20 @@ void ACcontextMapping_encode2_no_mem_s17_LC_fx( IF( hm_cfg ) { /* Fill with zero to be sure that the decoder finishes the MSB decoding at the same position */ - tmp = sub( nbbits, add( nbbits_signs, nbbits_lsbs ) ); + tmp = sub( nbbits, add( nbbits_signs, nbbits_lsbs ) ); /* Q0 */ set16_fx( &ptr[bp], 0, sub( tmp, bp ) ); bp = tmp; move16(); } if ( !hm_cfg ) { - lastnz = k; + lastnz = k; /* Q0 */ move16(); } } /* Push number of encoded tuples */ - value = sub( shr( lastnz, 1 ), 1 ); + value = sub( shr( lastnz, 1 ), 1 ); /* Q0 */ push_next_indice_fx( hBstr, value, nbbits_ntuples ); /* Push arithmetic coded bits */ @@ -346,17 +350,17 @@ void ACcontextMapping_encode2_no_mem_s17_LC_fx( /* Push sign bits */ push_next_bits_fx( hBstr, signs, nbbits_signs ); - bp = add( bp, nbbits_signs ); + bp = add( bp, nbbits_signs ); /* Q0 */ /*write residual Quantization bits*/ - tmp = s_min( sub( sub( nbbits, bp ), nbbits_lsbs ), resQMaxBits ); + tmp = s_min( sub( sub( nbbits, bp ), nbbits_lsbs ), resQMaxBits ); /* Q0 */ FOR( k = 0; k < tmp; k++ ) { - ptr[nbbits - 1 - nbbits_lsbs - k] = x[nt + k]; + ptr[nbbits - 1 - nbbits_lsbs - k] = x[nt + k]; /* Q0 */ move16(); } /* Write filler bits */ - tmp = sub( nbbits, add( bp, nbbits_lsbs ) ); + tmp = sub( nbbits, add( bp, nbbits_lsbs ) ); /* Q0 */ FOR( ; k < tmp; ++k ) { ptr[nbbits - 1 - nbbits_lsbs - k] = 0; @@ -378,7 +382,7 @@ void ACcontextMapping_encode2_no_mem_s17_LC_fx( * *-------------------------------------------------------------------*/ static Word16 find_last_nz_pair( - const Word16 x[], + const Word16 x[], /* Q0 */ Word16 length, const CONTEXT_HM_CONFIG *hm_cfg ) { @@ -387,7 +391,7 @@ static Word16 find_last_nz_pair( if ( hm_cfg ) { - tmp = hm_cfg->indexBuffer; + tmp = hm_cfg->indexBuffer; /* Q0 */ move16(); } @@ -395,9 +399,9 @@ static Word16 find_last_nz_pair( move16(); lobs[1] = shr( length, 1 ); /* length/2 */ move16(); - lobs[2] = add( lobs[1], shr( length, 2 ) ); + lobs[2] = add( lobs[1], shr( length, 2 ) ); /* Q0 */ move16(); - lobs[3] = add( lobs[2], shr( length, 3 ) ); + lobs[3] = add( lobs[2], shr( length, 3 ) ); /* Q0 */ move16(); last_nz = 0; @@ -412,11 +416,11 @@ static Word16 find_last_nz_pair( { if ( x[tmp[i - 2]] != 0 ) { - last_nz = s_max( last_nz, i ); + last_nz = s_max( last_nz, i ); /* Q0 */ } if ( x[tmp[i - 1]] != 0 ) { - last_nz = s_max( last_nz, i ); + last_nz = s_max( last_nz, i ); /* Q0 */ } } } @@ -426,11 +430,11 @@ static Word16 find_last_nz_pair( { if ( x[i - 2] != 0 ) { - last_nz = s_max( last_nz, i ); + last_nz = s_max( last_nz, i ); /* Q0 */ } if ( x[i - 1] != 0 ) { - last_nz = s_max( last_nz, i ); + last_nz = s_max( last_nz, i ); /* Q0 */ } } } @@ -448,12 +452,12 @@ static Word16 find_last_nz_pair( * *-------------------------------------------------------------------*/ Word16 ACcontextMapping_encode2_estimate_no_mem_s17_LC_fx( - const Word16 *x, - Word16 nt, - Word16 *lastnz_out, - Word16 *nEncoded, - Word16 target, - Word16 *stop, + const Word16 *x, /* Q0 */ + Word16 nt, /* Q0 */ + Word16 *lastnz_out, /* Q0 */ + Word16 *nEncoded, /* Q0 */ + Word16 target, /* Q0 */ + Word16 *stop, /* Q0 */ CONTEXT_HM_CONFIG *hm_cfg ) { Word16 a1, b1, a1_i, b1_i; @@ -473,6 +477,8 @@ Word16 ACcontextMapping_encode2_estimate_no_mem_s17_LC_fx( Word16 p1, p2; Word16 ii[2], idx1, idx2, idx; Word16 numPeakIndicesOrig = 0, numHoleIndices = 0; /* initialize just to avoid compiler warning */ + move16(); + move16(); get_next_coeff_function get_next_coeff; @@ -481,12 +487,12 @@ Word16 ACcontextMapping_encode2_estimate_no_mem_s17_LC_fx( move16(); if ( GT_16( target, 400 ) ) { - rateFlag = 2 << NBITS_CONTEXT; + rateFlag = 2 << NBITS_CONTEXT; /* Q0 */ move16(); } /* proba coded on 14bits -> proba=1 */ - proba = L_deposit_l( 16384 ); + proba = L_deposit_l( 16384 ); /* Q0 */ /* Init */ nt_half = shr( nt, 1 ); @@ -497,13 +503,13 @@ Word16 ACcontextMapping_encode2_estimate_no_mem_s17_LC_fx( move16(); /* bits to encode lastnz + 2 bits headroom */ - nbits = sub( 2 + 14, norm_s( sub( nt, 1 ) ) ); - nbits_old = nbits; + nbits = sub( 2 + 14, norm_s( sub( nt, 1 ) ) ); /* Q0 */ + nbits_old = nbits; /* Q0 */ move16(); - nbits = sub( nbits, target ); + nbits = sub( nbits, target ); /* Q0 */ /* Find last non-zero tuple in the mapped domain signal */ - lastnz = find_last_nz_pair( x, nt, hm_cfg ); + lastnz = find_last_nz_pair( x, nt, hm_cfg ); /* Q0 */ /* At least one tuple is coded */ lastnz2 = 2; @@ -511,25 +517,25 @@ Word16 ACcontextMapping_encode2_estimate_no_mem_s17_LC_fx( IF( hm_cfg ) /* mapped domain */ { - numPeakIndicesOrig = hm_cfg->numPeakIndices; + numPeakIndicesOrig = hm_cfg->numPeakIndices; /* Q0 */ move16(); - hm_cfg->numPeakIndices = s_min( hm_cfg->numPeakIndices, lastnz ); + hm_cfg->numPeakIndices = s_min( hm_cfg->numPeakIndices, lastnz ); /* Q0 */ move16(); - numHoleIndices = sub( lastnz, hm_cfg->numPeakIndices ); + numHoleIndices = sub( lastnz, hm_cfg->numPeakIndices ); /* Q0 */ /* Mark hole indices beyond lastnz as pruned */ FOR( k = numHoleIndices; k < hm_cfg->numHoleIndices; ++k ) { - hm_cfg->holeIndices[k] = add( hm_cfg->holeIndices[k], nt ); + hm_cfg->holeIndices[k] = add( hm_cfg->holeIndices[k], nt ); /* Q0 */ move16(); } - ii[0] = numPeakIndicesOrig; + ii[0] = numPeakIndicesOrig; /* Q0 */ move16(); ii[1] = 0; move16(); - get_next_coeff = get_next_coeff_mapped; + get_next_coeff = get_next_coeff_mapped; /* Q0 */ move16(); } ELSE /* unmapped domain */ @@ -541,7 +547,7 @@ Word16 ACcontextMapping_encode2_estimate_no_mem_s17_LC_fx( move16(); move16(); - get_next_coeff = get_next_coeff_unmapped; + get_next_coeff = get_next_coeff_unmapped; /* Q0 */ move16(); } @@ -549,38 +555,37 @@ Word16 ACcontextMapping_encode2_estimate_no_mem_s17_LC_fx( FOR( k = 0; k < lastnz; k += 2 ) { /* First coefficient */ - a1_i = get_next_coeff( ii, &p1, &idx1, hm_cfg ); + a1_i = get_next_coeff( ii, &p1, &idx1, hm_cfg ); /* Q0 */ /* Second coefficient */ - b1_i = get_next_coeff( ii, &p2, &idx2, hm_cfg ); + b1_i = get_next_coeff( ii, &p2, &idx2, hm_cfg ); /* Q0 */ - idx = s_min( idx1, idx2 ); + idx = s_min( idx1, idx2 ); /* Q0 */ /* Get context */ - ctx = &c[s_or( p1, p2 )]; - move16(); + ctx = &c[s_or( p1, p2 )]; /* Q0 */ - t = add( *ctx, rateFlag ); + t = add( *ctx, rateFlag ); /* Q0 */ if ( GT_16( idx, nt_half ) ) { - t = add( t, 1 << NBITS_CONTEXT ); + t = add( t, 1 << NBITS_CONTEXT ); /* Q0 */ } /* Init current 2-tuple encoding */ - a1 = abs_s( x[a1_i] ); - b1 = abs_s( x[b1_i] ); + a1 = abs_s( x[a1_i] ); /* Q0 */ + b1 = abs_s( x[b1_i] ); /* Q0 */ lev1 = -( 1 << ( NBITS_CONTEXT + NBITS_RATEQ ) ); move16(); /* Signs Bits */ if ( a1 > 0 ) { - nbits = add( nbits, 1 ); + nbits = add( nbits, 1 ); /* Q0 */ } if ( b1 > 0 ) { - nbits = add( nbits, 1 ); + nbits = add( nbits, 1 ); /* Q0 */ } /* pre-compute address of ari_pk_s17_LC_ext[0][Val_esc] to avoid doing it multiple times inside the loop */ @@ -599,38 +604,38 @@ Word16 ACcontextMapping_encode2_estimate_no_mem_s17_LC_fx( cum_freq_norm_e = norm_s( cum_freq[0] ); cum_freq_norm = shl( cum_freq[0], cum_freq_norm_e ); proba = Mpy_32_16_1( proba, cum_freq_norm ); - proba = L_shl( proba, sub( 14, cum_freq_norm_e ) ); + proba = L_shl( proba, sub( 14, cum_freq_norm_e ) ); /* Q14 + cum_freq_norm_e */ /*Number of leading zero computed in one cycle=norm_l() in BASOP*/ nlz = sub( norm_l( proba ), 2 ); - proba = L_shl( proba, sub( nlz, 15 ) ); + proba = L_shl( proba, sub( nlz, 15 ) ); /* cum_freq_norm_e */ - nbits = add( nbits, nlz ); + nbits = add( nbits, nlz ); /* Q0 */ /*addition added as shift not done in norm_l(): real shift = 14-nlz*/ /*proba is rounded down on 14 bits ->automatic over-estimation of bit consumption*/ a1 = shr( a1, 1 ); b1 = shr( b1, 1 ); - lev1 = s_min( add( lev1, 1 << ( NBITS_CONTEXT + NBITS_RATEQ ) ), 2 << ( NBITS_CONTEXT + NBITS_RATEQ ) ); + lev1 = s_min( add( lev1, 1 << ( NBITS_CONTEXT + NBITS_RATEQ ) ), 2 << ( NBITS_CONTEXT + NBITS_RATEQ ) ); /* Q0 */ } - pki = lookup[lev1]; + pki = lookup[lev1]; /* Q0 */ move16(); - symbol = add( a1, shl( b1, A_THRES_SHIFT ) ); - cum_freq = ari_pk_s17_LC_ext[pki] + symbol; /* address calculation not counted */ + symbol = add( a1, shl( b1, A_THRES_SHIFT ) ); /* Q0 */ + cum_freq = ari_pk_s17_LC_ext[pki] + symbol; /* address calculation not counted */ /*p1*p2=proba on 28 bits: p=0.5->power(2,27)*/ cum_freq_norm = sub( cum_freq[0], cum_freq[1] ); cum_freq_norm_e = norm_s( cum_freq_norm ); cum_freq_norm = shl( cum_freq_norm, cum_freq_norm_e ); proba = Mpy_32_16_1( proba, cum_freq_norm ); - proba = L_shl( proba, sub( 15, cum_freq_norm_e ) ); + proba = L_shl( proba, sub( 15, cum_freq_norm_e ) ); /* Q15 + cum_freq_norm_e */ /*Number of leading zero computed in one cycle=norm_l() in BASOP*/ nlz = sub( norm_l( proba ), 3 ); - proba = L_shl( proba, sub( nlz, 14 ) ); + proba = L_shl( proba, sub( nlz, 14 ) ); /* cum_freq_norm_e */ - nbits = add( nbits, nlz ); + nbits = add( nbits, nlz ); /* Q0 */ /*addition added as shift not done in norm_l(): real shift = 14-nlz*/ /*proba is rounded down on 14 bits ->automatic over-estimation of bit consumption*/ @@ -652,15 +657,15 @@ Word16 ACcontextMapping_encode2_estimate_no_mem_s17_LC_fx( test(); IF( hm_cfg || k == 0 || s_or( x[a1_i], x[b1_i] ) ) { - nbits_old = add( nbits, target ); - lastnz2 = add( b1_i, 1 ); + nbits_old = add( nbits, target ); /* Q0 */ + lastnz2 = add( b1_i, 1 ); /* Q0 */ } } /* Update context for next 2-tuple */ IF( EQ_16( p1, p2 ) ) /* peak-peak or hole-hole context */ { - lev1 = shr( lev1, NBITS_CONTEXT + NBITS_RATEQ ); + lev1 = shr( lev1, NBITS_CONTEXT + NBITS_RATEQ ); /* Q0 */ if ( lev1 > 0 ) t = add( 12, lev1 ); if ( lev1 <= 0 ) @@ -668,46 +673,46 @@ Word16 ACcontextMapping_encode2_estimate_no_mem_s17_LC_fx( if ( lev1 == 0 ) t = add( t, t ); - *ctx = add( shl( s_and( *ctx, 0xf ), 4 ), add( t, 1 ) ); + *ctx = add( shl( s_and( *ctx, 0xf ), 4 ), add( t, 1 ) ); /* Q0 */ move16(); } ELSE /* mixed context */ { IF( s_and( idx1, 1 ) ) /* update first context */ { - c[p1] = update_mixed_context( c[p1], abs_s( x[a1_i] ) ); + c[p1] = update_mixed_context( c[p1], abs_s( x[a1_i] ) ); /* Q0 */ move16(); } IF( s_and( idx2, 1 ) ) /* update second context */ { - c[p2] = update_mixed_context( c[p2], abs_s( x[b1_i] ) ); + c[p2] = update_mixed_context( c[p2], abs_s( x[b1_i] ) ); /* Q0 */ move16(); } } } /* end of the 2-tuples loop */ - nbits = add( nbits, target ); + nbits = add( nbits, target ); /* Q0 */ /* Output */ if ( *stop ) { - nbits = nbits_old; + nbits = nbits_old; /* Q0 */ move16(); } if ( stop2 ) { - stop2 = nbits; + stop2 = nbits; /* Q0 */ move16(); } - *nEncoded = lastnz2; + *nEncoded = lastnz2; /* Q0 */ move16(); - *stop = stop2; + *stop = stop2; /* Q0 */ move16(); if ( lastnz_out ) { - *lastnz_out = lastnz; + *lastnz_out = lastnz; /* Q0 */ move16(); } @@ -716,10 +721,10 @@ Word16 ACcontextMapping_encode2_estimate_no_mem_s17_LC_fx( /* Restore hole indices beyond lastnz */ FOR( k = numHoleIndices; k < hm_cfg->numHoleIndices; ++k ) { - hm_cfg->holeIndices[k] = sub( hm_cfg->holeIndices[k], nt ); + hm_cfg->holeIndices[k] = sub( hm_cfg->holeIndices[k], nt ); /* Q0 */ move16(); } - hm_cfg->numPeakIndices = numPeakIndicesOrig; + hm_cfg->numPeakIndices = numPeakIndicesOrig; /* Q0 */ move16(); } @@ -736,12 +741,12 @@ Word16 ACcontextMapping_encode2_estimate_no_mem_s17_LC_fx( *-------------------------------------------------------------------*/ void RCcontextMapping_encode2_no_mem_s17_LCS_fx( - BSTR_ENC_HANDLE hBstr, /* i/o: bitstream handle */ - Word16 *x, - const Word16 nt, - Word16 lastnz, - const Word16 nbbits, - const Word16 resQMaxBits, + BSTR_ENC_HANDLE hBstr, /* i/o: bitstream handle */ + Word16 *x, /* Q0 */ + const Word16 nt, /* Q0 */ + Word16 lastnz, /* Q0 */ + const Word16 nbbits, /* Q0 */ + const Word16 resQMaxBits, /* Q0 */ CONTEXT_HM_CONFIG *hm_cfg ) { Word16 ptr[BITBUFSIZE]; @@ -760,6 +765,8 @@ void RCcontextMapping_encode2_no_mem_s17_LCS_fx( a1 = 0; /* to avoid compilation warnings */ b1 = 0; /* to avoid compilation warnings */ + move16(); + move16(); /* Init */ nt_half = shr( nt, 1 ); @@ -772,7 +779,7 @@ void RCcontextMapping_encode2_no_mem_s17_LCS_fx( WHILE( LT_16( k, shr( nt, 1 ) ) ) { - nbbits_ntuples = add( nbbits_ntuples, 1 ); + nbbits_ntuples = add( nbbits_ntuples, 1 ); /* Q0 */ k = shl( k, 1 ); } @@ -809,20 +816,20 @@ void RCcontextMapping_encode2_no_mem_s17_LCS_fx( move32(); /* mapped domain */ - numPeakIndicesOrig = hm_cfg->numPeakIndices; - hm_cfg->numPeakIndices = s_min( hm_cfg->numPeakIndices, lastnz ); - numHoleIndices = sub( lastnz, hm_cfg->numPeakIndices ); + numPeakIndicesOrig = hm_cfg->numPeakIndices; /* Q0 */ + hm_cfg->numPeakIndices = s_min( hm_cfg->numPeakIndices, lastnz ); /* Q0 */ + numHoleIndices = sub( lastnz, hm_cfg->numPeakIndices ); /* Q0 */ move16(); move16(); /* Mark hole indices beyond lastnz as pruned */ FOR( k = numHoleIndices; k < hm_cfg->numHoleIndices; ++k ) { - hm_cfg->holeIndices[k] = add( hm_cfg->holeIndices[k], nt ); + hm_cfg->holeIndices[k] = add( hm_cfg->holeIndices[k], nt ); /* Q0 */ move16(); } - ii[0] = numPeakIndicesOrig; + ii[0] = numPeakIndicesOrig; /* Q0 */ ii[1] = 0; move16(); move16(); @@ -835,7 +842,7 @@ void RCcontextMapping_encode2_no_mem_s17_LCS_fx( /*Start Encoding*/ /* Initialize range encoder */ - rc_uni_enc_init( &rc_st_enc ); + rc_uni_enc_init_fx( &rc_st_enc ); /*Main Loop through the 2-tuples*/ b1_i = -1; @@ -843,15 +850,15 @@ void RCcontextMapping_encode2_no_mem_s17_LCS_fx( FOR( k = 0; k < lastnz; k += 2 ) { - a1_i = get_next_coeff_mapped_ivas_fx( ii, &p1, &idx1, hm_cfg ); - b1_i = get_next_coeff_mapped_ivas_fx( ii, &p2, &idx2, hm_cfg ); + a1_i = get_next_coeff_mapped_ivas_fx( ii, &p1, &idx1, hm_cfg ); /* Q0 */ + b1_i = get_next_coeff_mapped_ivas_fx( ii, &p2, &idx2, hm_cfg ); /* Q0 */ - idx = s_min( idx1, idx2 ); + idx = s_min( idx1, idx2 ); /* Q0 */ /* Get context */ - ctx = &c[L_or( p1, p2 )]; + ctx = &c[L_or( p1, p2 )]; /* Q0 */ - t = (UWord16) L_add( *ctx, rateFlag ); + t = (UWord16) L_add( *ctx, rateFlag ); /* Q0 */ // t += ( nt_half >= idx ) ? 0 : ( 1 << NBITS_CONTEXT ); IF( LT_16( nt_half, idx ) ) { @@ -859,8 +866,8 @@ void RCcontextMapping_encode2_no_mem_s17_LCS_fx( } /* Init current 2-tuple encoding */ - a1 = abs_s( x[a1_i] ); - b1 = abs_s( x[b1_i] ); + a1 = abs_s( x[a1_i] ); /* Q0 */ + b1 = abs_s( x[b1_i] ); /* Q0 */ lev1 = -1; move16(); @@ -879,7 +886,7 @@ void RCcontextMapping_encode2_no_mem_s17_LCS_fx( signs[nbbits_signs] = 1; move16(); } - nbbits_signs = add( nbbits_signs, 1 ); + nbbits_signs = add( nbbits_signs, 1 ); /* Q0 */ } IF( b1 > 0 ) @@ -895,15 +902,15 @@ void RCcontextMapping_encode2_no_mem_s17_LCS_fx( signs[nbbits_signs] = 1; move16(); } - nbbits_signs = add( nbbits_signs, 1 ); + nbbits_signs = add( nbbits_signs, 1 ); /* Q0 */ } /* MSBs coding */ WHILE( GE_16( s_max( a1, b1 ), A_THRES ) ) { - pki = ari_lookup_s17_LC[t + ( ( lev1 + 1 ) << ( NBITS_CONTEXT + NBITS_RATEQ ) )]; + pki = ari_lookup_s17_LC[t + ( ( lev1 + 1 ) << ( NBITS_CONTEXT + NBITS_RATEQ ) )]; /* Q0 */ move16(); - rc_uni_enc_encode_symbol_fastS( &rc_st_enc, VAL_ESC, cum_freq_ari_pk_s17_LC_ext[pki], sym_freq_ari_pk_s17_LC_ext[pki], 14 ); /* Encode ESC symbol */ + rc_uni_enc_encode_symbol_fastS_fx( &rc_st_enc, VAL_ESC, cum_freq_ari_pk_s17_LC_ext[pki], sym_freq_ari_pk_s17_LC_ext[pki], 14 ); /* Encode ESC symbol */ *lsbs_bits-- = s_and( a1, 1 ); *lsbs_bits-- = s_and( b1, 1 ); @@ -911,17 +918,17 @@ void RCcontextMapping_encode2_no_mem_s17_LCS_fx( move16(); /* LSBs bit counting */ - nbbits_lsbs = add( nbbits_lsbs, 2 ); + nbbits_lsbs = add( nbbits_lsbs, 2 ); /* Q0 */ a1 = shr( a1, 1 ); b1 = shr( b1, 1 ); - lev1 = s_min( add( lev1, 1 ), 2 ); + lev1 = s_min( add( lev1, 1 ), 2 ); /* Q0 */ } - pki = ari_lookup_s17_LC[t + ( ( lev1 + 1 ) << ( NBITS_CONTEXT + NBITS_RATEQ ) )]; + pki = ari_lookup_s17_LC[t + ( ( lev1 + 1 ) << ( NBITS_CONTEXT + NBITS_RATEQ ) )]; /* Q0 */ move16(); - rc_uni_enc_encode_symbol_fastS( &rc_st_enc, a1 + A_THRES * b1, cum_freq_ari_pk_s17_LC_ext[pki], sym_freq_ari_pk_s17_LC_ext[pki], 14 ); /* Encode MSB symbol */ + rc_uni_enc_encode_symbol_fastS_fx( &rc_st_enc, a1 + A_THRES * b1, cum_freq_ari_pk_s17_LC_ext[pki], sym_freq_ari_pk_s17_LC_ext[pki], 14 ); /* Encode MSB symbol */ /*Confirm that there is no overflow, i.e. bit-budget has not exceeded */ @@ -932,14 +939,14 @@ void RCcontextMapping_encode2_no_mem_s17_LCS_fx( IF( lev1 <= 0 ) { - t = (UWord16) L_add( 1, L_mult0( add( a1, b1 ), add( lev1, 2 ) ) ); + t = (UWord16) L_add( 1, L_mult0( add( a1, b1 ), add( lev1, 2 ) ) ); /* Q0 */ } ELSE { - t = (UWord16) L_add( 13, lev1 ); + t = (UWord16) L_add( 13, lev1 ); /* Q0 */ } - *ctx = L_add( L_shl( L_and( *ctx, 0xf ), 4 ), t ); + *ctx = L_add( L_shl( L_and( *ctx, 0xf ), 4 ), t ); /* Q0 */ move32(); } ELSE @@ -949,14 +956,14 @@ void RCcontextMapping_encode2_no_mem_s17_LCS_fx( IF( s_and( idx1, 1 ) ) { /* update first context */ - c[p1] = update_mixed_context_ivas_fx( c[p1], abs_s( x[a1_i] ) ); + c[p1] = update_mixed_context_ivas_fx( c[p1], abs_s( x[a1_i] ) ); /* Q0 */ move32(); } IF( s_and( idx2, 1 ) ) { /* update second context */ - c[p2] = update_mixed_context_ivas_fx( c[p2], abs_s( x[b1_i] ) ); + c[p2] = update_mixed_context_ivas_fx( c[p2], abs_s( x[b1_i] ) ); /* Q0 */ move32(); } } @@ -994,7 +1001,7 @@ void RCcontextMapping_encode2_no_mem_s17_LCS_fx( WHILE( x[lastnz - 1] == 0 && x[lastnz - 2] == 0 ) { test(); - lastnz = sub( lastnz, 2 ); + lastnz = sub( lastnz, 2 ); /* Q0 */ } x[0] = a1; move16(); @@ -1003,15 +1010,15 @@ void RCcontextMapping_encode2_no_mem_s17_LCS_fx( /*Start Encoding*/ /* Initialize range encoder */ - rc_uni_enc_init( &rc_st_enc ); + rc_uni_enc_init_fx( &rc_st_enc ); /*Main Loop through the 2-tuples*/ FOR( k = 0; k < lastnz; k += 2 ) { /* Init current 2-tuple encoding */ - a1 = abs_s( x[k + 0] ); - b1 = abs_s( x[k + 1] ); + a1 = abs_s( x[k + 0] ); /* Q0 */ + b1 = abs_s( x[k + 1] ); /* Q0 */ lev1 = 0; esc_nb = 0; @@ -1032,7 +1039,7 @@ void RCcontextMapping_encode2_no_mem_s17_LCS_fx( signs[nbbits_signs] = 1; move16(); } - nbbits_signs = add( nbbits_signs, 1 ); + nbbits_signs = add( nbbits_signs, 1 ); /* Q0 */ } IF( b1 > 0 ) @@ -1048,17 +1055,17 @@ void RCcontextMapping_encode2_no_mem_s17_LCS_fx( signs[nbbits_signs] = 1; move16(); } - nbbits_signs = add( nbbits_signs, 1 ); + nbbits_signs = add( nbbits_signs, 1 ); /* Q0 */ } - rateQ = add( rateFlag, (Word16) GT_16( k, shr( nt, 1 ) ) ); + rateQ = add( rateFlag, extract_l( GT_16( k, shr( nt, 1 ) ) ) ); /* MSBs coding */ WHILE( GE_16( s_max( a1, b1 ), A_THRES ) ) { pki = ari_lookup_s17_LC[t + ( ( rateQ ) << NBITS_CONTEXT ) + ( esc_nb << ( NBITS_CONTEXT + NBITS_RATEQ ) )]; move16(); - rc_uni_enc_encode_symbol_fastS( &rc_st_enc, VAL_ESC, cum_freq_ari_pk_s17_LC_ext[pki], sym_freq_ari_pk_s17_LC_ext[pki], 14 ); /* Encode ESC symbol */ + rc_uni_enc_encode_symbol_fastS_fx( &rc_st_enc, VAL_ESC, cum_freq_ari_pk_s17_LC_ext[pki], sym_freq_ari_pk_s17_LC_ext[pki], 14 ); /* Encode ESC symbol */ *lsbs_bits-- = s_and( a1, 1 ); *lsbs_bits-- = s_and( b1, 1 ); @@ -1066,29 +1073,30 @@ void RCcontextMapping_encode2_no_mem_s17_LCS_fx( move16(); /* LSBs bit counting */ - nbbits_lsbs = add( nbbits_lsbs, 2 ); + nbbits_lsbs = add( nbbits_lsbs, 2 ); /* Q0 */ a1 = shr( a1, 1 ); b1 = shr( b1, 1 ); - lev1 = add( lev1, 1 ); - esc_nb = s_min( lev1, 3 ); + lev1 = add( lev1, 1 ); /* Q0 */ + esc_nb = s_min( lev1, 3 ); /* Q0 */ } move16(); - pki = ari_lookup_s17_LC[t + ( ( rateQ ) << NBITS_CONTEXT ) + ( esc_nb << ( NBITS_CONTEXT + NBITS_RATEQ ) )]; - rc_uni_enc_encode_symbol_fastS( &rc_st_enc, a1 + A_THRES * b1, cum_freq_ari_pk_s17_LC_ext[pki], sym_freq_ari_pk_s17_LC_ext[pki], 14 ); /* Encode MSB symbol */ + + pki = ari_lookup_s17_LC[t + ( ( rateQ ) << NBITS_CONTEXT ) + ( esc_nb << ( NBITS_CONTEXT + NBITS_RATEQ ) )]; /* Q0 */ + rc_uni_enc_encode_symbol_fastS_fx( &rc_st_enc, a1 + A_THRES * b1, cum_freq_ari_pk_s17_LC_ext[pki], sym_freq_ari_pk_s17_LC_ext[pki], 14 ); /* Encode MSB symbol */ /*Confirm that there is no overflow, i.e. bit-budget has not exceeded */ /* Update context for next 2-tuple */ IF( LT_16( esc_nb, 2 ) ) { - cp = add( 1, imult1616( add( a1, b1 ), add( esc_nb, 1 ) ) ); + cp = add( 1, imult1616( add( a1, b1 ), add( esc_nb, 1 ) ) ); /* Q0 */ } ELSE { - cp = add( 12, esc_nb ); + cp = add( 12, esc_nb ); /* Q0 */ } /*Shift old 4 bits, replace last 4 bits*/ @@ -1099,13 +1107,13 @@ void RCcontextMapping_encode2_no_mem_s17_LCS_fx( } /* Finish range encoder */ - rc_tot_bits = rc_uni_enc_finish( &rc_st_enc ); /* No. of bits consumed by range coder */ - bp = add( rc_tot_bits, nbbits_ntuples ); /* Update bitstream pointer */ + rc_tot_bits = rc_uni_enc_finish_fx( &rc_st_enc ); /* No. of bits consumed by range coder Q0*/ + bp = add( rc_tot_bits, nbbits_ntuples ); /* Update bitstream pointer Q0*/ /* Cross-check that there is no overflow */ /* Push number of encoded tuples */ - value = sub( shr( lastnz, 1 ), 1 ); + value = sub( shr( lastnz, 1 ), 1 ); /* Q0 */ push_next_indice( hBstr, value, nbbits_ntuples ); /* Push range coded bits from byte_buffer to bitstream */ @@ -1122,13 +1130,13 @@ void RCcontextMapping_encode2_no_mem_s17_LCS_fx( /* Push sign bits */ push_next_bits( hBstr, (UWord16 *) signs, nbbits_signs ); - bp = add( bp, nbbits_signs ); + bp = add( bp, nbbits_signs ); /* Q0 */ /*write residual Quantization bits*/ FOR( k = 0; k < s_min( nbbits - bp - nbbits_lsbs, resQMaxBits ); k++ ) { - ptr[nbbits - 1 - nbbits_lsbs - k] = x[nt + k]; + ptr[nbbits - 1 - nbbits_lsbs - k] = x[nt + k]; /* Q0 */ move16(); } /* Write filler bits */ @@ -1148,6 +1156,678 @@ void RCcontextMapping_encode2_no_mem_s17_LCS_fx( return; } +/*-------------------------------------------------------------------* + * find_last_nz_pair_fx() + * + * + *-------------------------------------------------------------------*/ + +static Word16 find_last_nz_pair_fx( + const Word16 x[], /* Q0 */ + const Word16 length, + const CONTEXT_HM_CONFIG *hm_cfg ) +{ + Word16 last_nz, i; + const Word16 *tmp; + + last_nz = 2; + move16(); + + IF( hm_cfg ) + { + /* mapped kernel */ + tmp = hm_cfg->indexBuffer; + + FOR( i = length; i >= 4; i -= 2 ) + { + test(); + IF( x[tmp[i - 2]] || x[tmp[i - 1]] ) + { + last_nz = i; /* Q0 */ + move16(); + BREAK; + } + } + } + ELSE + { + /* unmapped kernel */ + + FOR( i = length; i >= 4; i -= 2 ) + { + test(); + IF( x[i - 2] || x[i - 1] ) + { + last_nz = i; /* Q0 */ + move16(); + BREAK; + } + } + } + + return last_nz; +} + + +/*-------------------------------------------------------------------* + * RCcontextMapping_encode2_estimate_no_mem_s17_LCS_fx() + * + * Range coder bit-estimation + *-------------------------------------------------------------------*/ + +Word16 RCcontextMapping_encode2_estimate_no_mem_s17_LCS_fx( + Word16 *x, /* Spectral coefficients Q0*/ + const Word16 nt, /* L - size of spectrum (no. of spectral coefficients) Q0*/ + Word16 *lastnz_out, /* Q0 */ + Word16 *nEncoded, /* No. of spectral coefficients that can be coded without an overflow occuring Q0*/ + const Word16 target, /* Target bits Q0*/ + Word16 *stop, /* Q0 */ + Word16 mode, /* Q0 */ + CONTEXT_HM_CONFIG *hm_cfg /* context-based harmonic model configuration */ +) +{ + /* Common variables */ + Word16 a1, b1; + Word16 k, pki, lev1; + UWord16 t; + Word16 lastnz, lastnz2; + Word16 rateFlag; + Word64 bit_estimate_fx; /* Q23 */ + + Word16 symbol; + const UWord8 *lookup; + Word64 nbits2_fx; + + /* Initialization */ + bit_estimate_fx = MAKE_NUMBER_QX( 2, Q23 ); + move64(); + + nbits2_fx = 0; + move64(); + + /* bits to encode lastnz */ + k = 1; + move16(); + + WHILE( LT_16( k, nt / 2 ) ) + { + bit_estimate_fx = W_add( bit_estimate_fx, MAKE_NUMBER_QX( 1, Q23 ) ); + k = shl( k, 1 ); + /* check while condition */ + } + + nbits2_fx = bit_estimate_fx; + move64(); + + IF( hm_cfg ) + { + Word16 a1_i, b1_i; + Word16 stop2; + Word16 total_output_bits; + Word16 nt_half; + Word32 c[2], *ctx; + Word32 p1, p2; + Word16 ii[2]; + Word16 idx1, idx2, idx; + Word16 numPeakIndicesOrig = 0, numHoleIndices = 0; /* only to avoid compiler warning */ + move16(); + move16(); + + /* Rate flag */ + IF( GT_16( target, 400 ) ) + { + rateFlag = 2 << NBITS_CONTEXT; /* Select context-A for higher bitrates */ + move16(); + } + ELSE + { + rateFlag = 0; /* Select context-B for lower bitrates */ + move16(); + } + + nt_half = shr( nt, 1 ); + move16(); + stop2 = 0; + move16(); + c[0] = c[1] = 0; + move32(); + move32(); + + /* Find last non-zero tuple in the mapped domain signal */ + lastnz = find_last_nz_pair_fx( x, nt, hm_cfg ); + + lastnz2 = 2; + move16(); + + /* mapped domain */ + numPeakIndicesOrig = hm_cfg->numPeakIndices; /* Q0 */ + move16(); + hm_cfg->numPeakIndices = s_min( hm_cfg->numPeakIndices, lastnz ); /* Q0 */ + move16(); + numHoleIndices = sub( lastnz, hm_cfg->numPeakIndices ); /* Q0 */ + + /* Mark hole indices beyond lastnz as pruned */ + FOR( k = numHoleIndices; k < hm_cfg->numHoleIndices; ++k ) + { + hm_cfg->holeIndices[k] = add( hm_cfg->holeIndices[k], nt ); /* Q0 */ + move16(); + } + + ii[0] = numPeakIndicesOrig; /* Q0 */ + move16(); + ii[1] = 0; + move16(); + + p1 = p2 = 0; /* to avoid compilation warnings */ + move32(); + move32(); + + /* Main Loop through the 2-tuples */ + FOR( k = 0; k < lastnz; k += 2 ) + { + a1_i = get_next_coeff_mapped_ivas_fx( ii, &p1, &idx1, hm_cfg ); /* Q0 */ + b1_i = get_next_coeff_mapped_ivas_fx( ii, &p2, &idx2, hm_cfg ); /* Q0 */ + + idx = s_min( idx1, idx2 ); + + /* Get context */ + ctx = &c[L_or( p1, p2 )]; + + t = (UWord16) L_add( *ctx, rateFlag ); + IF( LT_16( nt_half, idx ) ) + { + t = add( t, ( 1 << NBITS_CONTEXT ) ); + } + + /* Init current 2-tuple encoding */ + a1 = abs_s( x[a1_i] ); + b1 = abs_s( x[b1_i] ); + lev1 = -( 1 << ( NBITS_CONTEXT + NBITS_RATEQ ) ); + + bit_estimate_fx = W_add( bit_estimate_fx, MAKE_VARIABLE_QX( s_min( a1, 1 ), Q23 ) ); + bit_estimate_fx = W_add( bit_estimate_fx, MAKE_VARIABLE_QX( s_min( b1, 1 ), Q23 ) ); + /* pre-compute address of ari_pk_s17_LC_ext[0][Val_esc] to avoid doing it multiple times inside the loop */ + lookup = &ari_lookup_s17_LC[t] + ( 1 << ( NBITS_CONTEXT + NBITS_RATEQ ) ); + + /* check while condition */ + /* MSBs coding */ + WHILE( GE_16( s_max( a1, b1 ), A_THRES ) ) + { + pki = lookup[lev1]; /* ESC symbol */ + + bit_estimate_fx = W_add( bit_estimate_fx, ari_bit_estimate_s17_LC_fx[pki][VAL_ESC] ); + bit_estimate_fx = W_add( bit_estimate_fx, MAKE_VARIABLE_QX( 2, Q23 ) ); + a1 = shr( a1, 1 ); + b1 = shr( b1, 1 ); + + lev1 = s_min( add( lev1, ( 1 << ( NBITS_CONTEXT + NBITS_RATEQ ) ) ), 2 << ( NBITS_CONTEXT + NBITS_RATEQ ) ); + + /* check while condition */ + } + + pki = lookup[lev1]; + + symbol = add( a1, i_mult( A_THRES, b1 ) ); /* Q0 */ + bit_estimate_fx = W_add( bit_estimate_fx, ari_bit_estimate_s17_LC_fx[pki][symbol] ); + + /* Should we truncate? */ + IF( GT_32( W_extract_l( W_shr( bit_estimate_fx, Q8 ) ), L_shl( target, Q15 ) ) ) + { + stop2 = 1; + move16(); + + IF( *stop ) + { + BREAK; + } + } + ELSE + { + lastnz2 = add( b1_i, 1 ); + nbits2_fx = bit_estimate_fx; + move64(); + } + + /* Update context for next 2-tuple */ + IF( EQ_32( p1, p2 ) ) /* peak-peak or hole-hole context */ + { + lev1 = shr( lev1, NBITS_CONTEXT + NBITS_RATEQ ); + + IF( lev1 <= 0 ) + { + t = add( 1, i_mult( add( a1, b1 ), add( lev1, 2 ) ) ); + } + ELSE + { + t = add( 13, lev1 ); + } + + *ctx = L_add( imult3216( L_and( *ctx, 0xf ), 16 ), t ); + move32(); + } + ELSE + { + /* mixed context */ + + IF( s_and( idx1, 1 ) ) + { + /* update first context */ + c[p1] = update_mixed_context_ivas_fx( c[p1], abs_s( x[a1_i] ) ); /* Q0 */ + move32(); + } + + IF( s_and( idx2, 1 ) ) + { + /* update second context */ + c[p2] = update_mixed_context_ivas_fx( c[p2], abs_s( x[b1_i] ) ); /* Q0 */ + move32(); + } + } + + } /*end of the 2-tuples loop*/ + + total_output_bits = round_fx( W_extract_l( W_shr( bit_estimate_fx, Q7 ) ) ); /* Q23 -> Q16 -> Q0 */ + + IF( *stop ) + { + total_output_bits = round_fx( W_extract_l( W_shr( nbits2_fx, Q7 ) ) ); /* Q23 -> Q16 -> Q0 */ + } + + IF( stop2 ) + { + stop2 = total_output_bits; /* Q0 */ + move16(); + } + + *nEncoded = lastnz2; /* Q0 */ + move16(); + *stop = stop2; /* If zero, it means no overflow occured during bit-estimation Q0*/ + move16(); + *lastnz_out = lastnz; /* Q0 */ + move16(); + + /* Restore hole indices beyond lastnz */ + FOR( k = numHoleIndices; k < hm_cfg->numHoleIndices; ++k ) + { + hm_cfg->holeIndices[k] = sub( hm_cfg->holeIndices[k], nt ); /* Q0 */ + move16(); + } + hm_cfg->numPeakIndices = numPeakIndicesOrig; /* Q0 */ + move16(); + + + return round_fx( L_add( W_extract_l( W_shr( nbits2_fx, Q7 ) ), ONE_IN_Q14 ) ); /* Q0 */ + } + ELSE /* if (!hm_cfg) */ + { + Word16 esc_nb, cp, rateQ; + UWord16 s; + Word16 tot_bits2; + Word16 overflow_flag = 0; + move16(); + + /* Rate flag */ + IF( GT_16( target, 400 ) ) + { + rateFlag = 2; /* Q0 */ + move16(); + } + ELSE + { + rateFlag = 0; /* Select context-B for lower bitrates */ + move16(); + } + + t = 0; + move16(); + s = 0; + move16(); + cp = 0; + move16(); + lastnz = 1; + move16(); + lastnz2 = 0; + move16(); + tot_bits2 = 0; + move16(); + + /* Find last non-zero tuple in the mapped domain signal */ + FOR( lastnz = sub( nt, 2 ); lastnz >= 0; lastnz -= 2 ) + { + test(); + IF( ( x[lastnz] != 0 ) || ( x[lastnz + 1] != 0 ) ) + { + BREAK; + } + } + lastnz = add( lastnz, 2 ); /* Q0 */ + IF( LT_16( lastnz, 2 ) ) + { + lastnz = 2; /* At least one tuple is coded Q0*/ + move16(); + } + + lastnz2 = 2; + move16(); + + /* Main Loop through the 2-tuples */ + FOR( k = 0; k < lastnz; k += 2 ) + { + /* Init current 2-tuple encoding */ + a1 = abs_s( x[k] ); /* Q0 */ + b1 = abs_s( x[k + 1] ); /* Q0 */ + lev1 = 0; + move16(); + esc_nb = 0; + move16(); + rateQ = add( rateFlag, extract_l( GT_16( k, shr( nt, 1 ) ) ) ); /* Q0 */ + + bit_estimate_fx = W_add( bit_estimate_fx, MAKE_VARIABLE_QX( s_min( a1, 1 ), Q23 ) ); + bit_estimate_fx = W_add( bit_estimate_fx, MAKE_VARIABLE_QX( s_min( b1, 1 ), Q23 ) ); + + /* pre-compute address of ari_pk_s17_LC_ext[0][Val_esc] to avoid doing it multiple times inside the loop */ + lookup = &ari_lookup_s17_LC[t + shl( rateQ, NBITS_CONTEXT )]; /* Q0 */ + + /* check while condition */ + /* MSBs coding */ + WHILE( GE_16( s_max( a1, b1 ), A_THRES ) ) + { + pki = lookup[( esc_nb << ( NBITS_CONTEXT + NBITS_RATEQ ) )]; /* Q0 */ + move16(); + + bit_estimate_fx = W_add( bit_estimate_fx, ari_bit_estimate_s17_LC_fx[pki][VAL_ESC] ); + bit_estimate_fx = W_add( bit_estimate_fx, MAKE_NUMBER_QX( 2, Q23 ) ); + + a1 = shr( a1, 1 ); + b1 = shr( b1, 1 ); + + lev1 = add( lev1, 1 ); + esc_nb = s_min( lev1, 3 ); + + /* check while condition */ + } + + pki = lookup[( esc_nb << ( NBITS_CONTEXT + NBITS_RATEQ ) )]; /* Q0 */ + move16(); + + symbol = add( a1, i_mult( A_THRES, b1 ) ); /* Q0 */ + bit_estimate_fx = W_add( bit_estimate_fx, ari_bit_estimate_s17_LC_fx[pki][symbol] ); + + /* Should we truncate? */ + IF( GT_32( W_extract_l( W_shr( bit_estimate_fx, Q8 ) ), L_shl( target, Q15 ) ) ) + { + overflow_flag = 1; + move16(); + } + ELSE + { + IF( abs_s( x[k] ) || abs_s( x[k + 1] ) ) /* No overflow & non-zero tuple */ + { + nbits2_fx = bit_estimate_fx; /* exp(bit_estimate_e) */ + move64(); + + lastnz2 = add( k, 2 ); + } + } + + /* Update context for next 2-tuple */ + IF( LT_16( esc_nb, 2 ) ) + { + cp = add( 1, i_mult( add( a1, b1 ), add( esc_nb, 1 ) ) ); /* Q0 */ + } + ELSE + { + cp = add( 12, esc_nb ); /* Q0 */ + } + /*shift old bits and replace last 4 bits*/ + s = (UWord16) L_add( L_shl( s, 4 ), cp ); + t = s_and( s, 0xFF ); + + } /*end of the 2-tuples loop*/ + + tot_bits2 = round_fx( W_extract_l( W_shr( nbits2_fx, Q7 ) ) ); /* Q23 -> Q16 -> Q0 */ + IF( LT_16( lastnz2, lastnz ) ) /* Overflow occured because unable to code all tuples */ + { + overflow_flag = 1; + move16(); + } + IF( EQ_16( mode, -1 ) ) + { + tot_bits2 = round_fx( W_extract_l( W_shr( bit_estimate_fx, Q7 ) ) ); /* Q23 -> Q16 -> Q0 */ + } + IF( overflow_flag == 0 ) /* No overflow */ + { + *stop = 0; + move16(); + } + ELSE /* Overflow */ + { + IF( *stop ){ + *stop = tot_bits2; /* Q0 */ + move16(); + } + ELSE + { + *stop = round_fx( W_extract_l( W_shr( bit_estimate_fx, Q7 ) ) ); /* Q23 -> Q16 -> Q0 */ + move16(); + } +} + +*lastnz_out = lastnz; /* Q0 */ +move16(); +*nEncoded = lastnz2; /* Q0 */ +move16(); +/* Safety mechanism to avoid overflow */ +test(); +IF( EQ_16( lastnz2, 2 ) && EQ_16( overflow_flag, 1 ) ) +{ + FOR( k = 0; k < lastnz2; k++ ) + { + x[k] = 0; + move16(); + } +} + +return tot_bits2; +} +} + + +/*-------------------------------------------------------------------* + * RCcontextMapping_encode2_estimate_bandWise_start_fx() + * + * Range coder - start bandwise bit-estimation + *-------------------------------------------------------------------*/ + +Word16 RCcontextMapping_encode2_estimate_bandWise_start_fx( + Word16 *x, /* Q0 */ + const Word16 nt, /* Q0 */ + const Word16 target, /* Q0 */ + HANDLE_RC_CONTEXT_MEM hContextMem ) +{ + Word16 i, k; + + /* Rate flag */ + IF( GT_16( target, 400 ) ) + { + hContextMem->rateFlag = 2 << NBITS_CONTEXT; + move16(); + } + ELSE + { + hContextMem->rateFlag = 0; + move16(); + } + + hContextMem->bit_estimate_fx = MAKE_NUMBER_QX( 2, Q23 ); + move64(); + + + /* Init */ + hContextMem->nt_half = shr( nt, 1 ); + move16(); + + /* bits to encode lastnz */ + k = 1; + move16(); + + WHILE( LT_16( k, hContextMem->nt_half ) ) + { + hContextMem->bit_estimate_fx = W_add( hContextMem->bit_estimate_fx, MAKE_NUMBER_QX( 1, Q23 ) ); + move64(); + + k = shl( k, 1 ); + /* check while condition */ + } + + /* bits to encode lastnz */ + hContextMem->nbits_old = round_fx( W_extract_l( W_shr( hContextMem->bit_estimate_fx, Q7 ) ) ); /* Q0 */ + move16(); + + hContextMem->ctx = 0; + move16(); + hContextMem->lastnz = 2; + move16(); + + /* Find last non-zero tuple */ + + FOR( i = nt; i >= 4; i -= 2 ) + { + test(); + IF( x[i - 2] != 0 || x[i - 1] != 0 ) + { + hContextMem->lastnz = i; + move16(); + BREAK; + } + } + + return hContextMem->nbits_old; +} + +/*-------------------------------------------------------------------* + * RCcontextMapping_encode2_estimate_bandWise_fx() + * + * Range coder - bandwise bit-estimation + *-------------------------------------------------------------------*/ + +Word16 RCcontextMapping_encode2_estimate_bandWise_fx( + Word16 *x, /* Q0 */ + const Word16 start_line, /* Q0 */ + const Word16 end_line, /* Q0 */ + HANDLE_RC_CONTEXT_MEM hContextMem ) +{ + Word16 a1, b1, a1_i, b1_i; + Word16 k, pki, lev1; + UWord16 t; + Word16 bandBits = 0; + move16(); + Word16 total_output_bits; /* No. of bits after finalization */ + Word16 symbol; + const UWord8 *lookup; + Word16 idx; + Word16 tmp; + + /* Main Loop through the 2-tuples */ + /*hContextMem->nt_half = end_line >> 1;*/ + Word16 len = s_min( hContextMem->lastnz, end_line ); + FOR( k = start_line; k < len; k += 2 ) + { + a1_i = k; /* Q0 */ + move16(); + b1_i = add( k, 1 ); /* Q0 */ + + idx = k; + move16(); + + /* Get context */ + t = add( hContextMem->ctx, hContextMem->rateFlag ); /* Q0 */ + + IF( GE_16( hContextMem->nt_half, idx ) ) + { + tmp = 0; + } + ELSE + { + tmp = ( 1 << NBITS_CONTEXT ); + } + + t = add( t, tmp ); /* Q0 */ + + /* Init current 2-tuple encoding */ + a1 = abs_s( x[a1_i] ); /* Q0 */ + b1 = abs_s( x[b1_i] ); /* Q0 */ + lev1 = -( 1 << ( NBITS_CONTEXT + NBITS_RATEQ ) ); /* Q0 */ + + /* Signs Bits */ + hContextMem->bit_estimate_fx = W_add( hContextMem->bit_estimate_fx, MAKE_VARIABLE_QX( s_min( a1, 1 ), Q23 ) ); + hContextMem->bit_estimate_fx = W_add( hContextMem->bit_estimate_fx, MAKE_VARIABLE_QX( s_min( b1, 1 ), Q23 ) ); + + move32(); + move32(); + + /* pre-compute address of ari_pk_s17_LC_ext[0][Val_esc] to avoid doing it multiple times inside the loop */ + lookup = &ari_lookup_s17_LC[t] + ( 1 << ( NBITS_CONTEXT + NBITS_RATEQ ) ); + + /* check while condition */ + /* MSBs coding */ + WHILE( GE_16( s_max( a1, b1 ), A_THRES ) ) + { + pki = lookup[lev1]; /* Q0 */ + move16(); + + hContextMem->bit_estimate_fx = W_add( hContextMem->bit_estimate_fx, ari_bit_estimate_s17_LC_fx[pki][VAL_ESC] ); + hContextMem->bit_estimate_fx = W_add( hContextMem->bit_estimate_fx, MAKE_NUMBER_QX( 2, Q23 ) ); + move32(); + move32(); + + + // hContextMem->bit_estimate = hContextMem->bit_estimate + ari_bit_estimate_s17_LC[pki][VAL_ESC]; + // hContextMem->bit_estimate += 2; /* Add the 2 LSB bits that were shifted out */ + + a1 = shr( a1, 1 ); + b1 = shr( b1, 1 ); + + lev1 = s_min( add( lev1, ( 1 << ( NBITS_CONTEXT + NBITS_RATEQ ) ) ), 2 << ( NBITS_CONTEXT + NBITS_RATEQ ) ); /* Q0 */ + /* check while condition */ + } + + pki = lookup[lev1]; /* Q0 */ + move16(); + symbol = add( a1, i_mult( A_THRES, b1 ) ); /* MSB symbol Q0*/ + hContextMem->bit_estimate_fx = W_add( hContextMem->bit_estimate_fx, ari_bit_estimate_s17_LC_fx[pki][symbol] ); + + move32(); + // hContextMem->bit_estimate = hContextMem->bit_estimate + ari_bit_estimate_s17_LC[pki][symbol]; + + /* Update context */ + lev1 = shr( lev1, NBITS_CONTEXT + NBITS_RATEQ ); + + IF( lev1 <= 0 ) + { + t = add( 1, i_mult( add( a1, b1 ), add( lev1, 2 ) ) ); /* Q0 */ + } + ELSE + { + t = add( 13, lev1 ); /* Q0 */ + } + + hContextMem->ctx = add( i_mult( s_and( hContextMem->ctx, 0xf ), 16 ), t ); /* Q0 */ + move16(); + + } /*end of the 2-tuples loop*/ + total_output_bits = round_fx( W_extract_l( W_shr( hContextMem->bit_estimate_fx, Q7 ) ) ); /* Q0 */ + // total_output_bits = (Word16) ( hContextMem->bit_estimate + 0.5f ); + + + bandBits = sub( total_output_bits, hContextMem->nbits_old ); /* Q0 */ + hContextMem->nbits_old = total_output_bits; /* Q0 */ + move16(); + + return bandBits; +} + + #ifdef IVAS_CODE_RANGE_CODER /*-------------------------------------------------------------------* diff --git a/lib_enc/FEC_enc.c b/lib_enc/FEC_enc.c deleted file mode 100644 index 3d5aa4f6b215a78e13905dd808f2ecf0e995115d..0000000000000000000000000000000000000000 --- a/lib_enc/FEC_enc.c +++ /dev/null @@ -1,216 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include -#include "cnst.h" -#include "prot.h" -#include "rom_com.h" -#include "wmc_auto.h" - -#include "ivas_prot_fx.h" -#include "prot_fx.h" - -/*-------------------------------------------------------------------* - * FEC_encode() - * - * Encoder supplementary information for FEC - *-------------------------------------------------------------------*/ - -void FEC_encode_ivas_fx( - BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ - const ACELP_config acelp_cfg, /* i/o: configuration of the ACELP */ - const Word16 *synth, /* i : pointer to synthesized speech for E computation */ - const Word16 coder_type, /* i : type of coder */ - Word16 clas, /* i : signal clas for current frame */ - const Word16 *fpit, /* i : close loop fractional pitch buffer Q6 */ - const Word16 *res, /* i : LP residual signal frame */ - Word16 *last_pulse_pos, /* i/o: Position of the last pulse */ - const Word16 L_frame, /* i : Frame length */ - const Word32 total_brate, /* i : total codec bitrate */ - const Word16 Q_synth /* i : input scaling */ -) -{ - Word16 tmpS, index; - Word16 maxi, sign, tmp_FER_pitch; - Word32 enr_q, Ltmp; - Word16 exp_enrq; - - tmpS = 0; - move16(); - enr_q = 1; - move16(); - sign = 0; - move16(); - test(); - test(); - IF( GT_16( coder_type, UNVOICED ) && LT_16( coder_type, AUDIO ) && acelp_cfg.FEC_mode > 0 ) - { - /*-----------------------------------------------------------------* - * encode signal class (not needed for VC mode since it is clearly voiced) (2 bits) - *-----------------------------------------------------------------*/ - IF( NE_16( coder_type, VOICED ) ) - { - /* encode signal clas with 2 bits */ - test(); - IF( EQ_16( clas, UNVOICED_CLAS ) ) - { - index = 0; - move16(); - } - ELSE IF( EQ_16( clas, VOICED_TRANSITION ) || EQ_16( clas, UNVOICED_TRANSITION ) ) - { - index = 1; - move16(); - } - ELSE IF( EQ_16( clas, VOICED_CLAS ) ) - { - index = 2; - move16(); - } - ELSE - { - index = 3; - move16(); - } - push_indice( hBstr, IND_FEC_CLAS, index, FEC_BITS_CLS ); - } - - /*-----------------------------------------------------------------* - * encode frame energy (5 bits) - *-----------------------------------------------------------------*/ - test(); - IF( GT_16( acelp_cfg.FEC_mode, 1 ) ) /* GENERIC and VOICED frames */ - { - /* frame energy (maximum energy per pitch period for voiced frames or mean energy per sample over 2nd halframe for unvoiced frames) */ - /*frame_ener( L_frame, clas, synth, fpit[(L_frame>>6)-1], &enr_q, 0 );*/ - Word32 synth32[L_FRAME16k]; - Copy_Scale_sig_16_32( synth, synth32, L_FRAME16k, 0 ); - fer_energy_fx( L_frame, clas, synth32, Q_synth, shr_r( fpit[sub( shr( L_frame, 6 ), 1 )], 6 ), &enr_q, L_frame ); - exp_enrq = sub( 31, shl( Q_synth, 1 ) ); - IF( EQ_16( clas, VOICED_CLAS ) || EQ_16( clas, ONSET ) || EQ_16( clas, SIN_ONSET ) ) /* Voiced or Onset current frame */ - { - exp_enrq = 31; - move16(); - } - /* linearly quantize the energy in the range 0 : FEC_ENR_STEP : 96 dB */ - /*tmpS = (short)( 10.0 * log10( enr_q + 0.001f ) / FEC_ENR_STEP )*/ /*To be converted fl_2_fx*/ - - Ltmp = Mpy_32_32( BASOP_Util_Log10( enr_q, exp_enrq ), 894784853 /* 10 / FEC_ENR_STEP Q28 */ ); // Q 25 + 28 - 31 = Q22 - IF( Ltmp < 0 ) - { - tmpS = extract_l( L_negate( L_shr( L_negate( Ltmp ), Q22 ) ) ); - } - ELSE - { - tmpS = extract_l( L_shr( Ltmp, Q22 ) ); - } - - tmpS = s_min( tmpS, FEC_ENR_QLIMIT ); - tmpS = s_max( tmpS, 0 ); - - push_indice( hBstr, IND_FEC_ENR, tmpS, FEC_BITS_ENR ); - } - /*-----------------------------------------------------------------* - * Encode last glottal pulse position (8 bits) - *-----------------------------------------------------------------*/ - test(); - IF( GT_16( acelp_cfg.FEC_mode, 2 ) ) /* GENERIC frames */ - { - /* retrieve the last glottal pulse position of the previous frame */ - /* use the current pitch information to scale or not the quantization */ - tmp_FER_pitch = shr( fpit[0], 6 ); /* take the 1st subframe pit, since it is easier to get on decoder side */ - sign = 0; - move16(); - maxi = *last_pulse_pos; - move16(); - IF( maxi < 0 ) - { - sign = 1; - move16(); - /*maxi = -maxi; */ - maxi = negate( maxi ); - } - - if ( GE_16( tmp_FER_pitch, 128 ) ) - { - maxi = shr( maxi, 1 ); - } - - if ( GT_16( maxi, 127 ) ) - { - /* better not use the glottal pulse position at all instead of using a wrong pulse */ - /* can happen only with pitch > 254 and max pit = 289 and should happen very rarely */ - maxi = 0; - move16(); - } - - if ( EQ_16( sign, 1 ) ) - { - maxi = add( maxi, 128 ); /* use 8 bits (MSB represent the sign of the pulse) */ - } - - push_indice( hBstr, IND_FEC_POS, maxi, FEC_BITS_POS ); - } - maxi = 0; - move16(); - - /* If bitrate < 24k4, then the pitch - is not represented in the same domain (12.k instead of 16k) */ - test(); - IF( GE_16( clas, VOICED_CLAS ) && GE_32( total_brate, ACELP_24k40 ) ) - { - /*maxi = findpulse( L_frame, res, (short)(fpit[(L_frame>>6)-1]), 0, &sign ); */ - maxi = findpulse_fx( L_frame, res, shr_r( fpit[sub( shr( L_frame, 6 ), 1 )], 6 ), 0, &sign ); - if ( EQ_16( sign, 1 ) ) - { - /*maxi = -maxi;*/ - maxi = negate( maxi ); - } - } - - *last_pulse_pos = maxi; - move16(); - } - ELSE - { - *last_pulse_pos = 0; - move16(); - } - - return; -} diff --git a/lib_enc/FEC_enc_fx.c b/lib_enc/FEC_enc_fx.c index d35f18b61a9dcf5be4bf1727d91abeb852530913..87243e8d2fa5268c37ab5a6cb7513969450575d9 100644 --- a/lib_enc/FEC_enc_fx.c +++ b/lib_enc/FEC_enc_fx.c @@ -5,10 +5,11 @@ #include "options.h" /* Compilation switches */ #include "cnst.h" /* Common constants */ //#include "prot_fx.h" /* Function prototypes */ -#include "rom_com_fx.h" /* Static table prototypes */ -#include "rom_com.h" /* Static table prototypes */ -#include "prot_fx.h" /* Function prototypes */ -#include "prot_fx_enc.h" /* Function prototypes */ +#include "rom_com_fx.h" /* Static table prototypes */ +#include "rom_com.h" /* Static table prototypes */ +#include "prot_fx.h" /* Function prototypes */ +#include "prot_fx_enc.h" /* Function prototypes */ +#include "ivas_prot_fx.h" /* Function prototypes */ /*============================================================================*/ @@ -37,18 +38,18 @@ /* */ /*============================================================================*/ void FEC_encode_fx( - BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ - const ACELP_config acelp_cfg, /* i/o: configuration of the ACELP */ - const Word16 *synth, /* i : pointer to synthesized speech for E computation */ - const Word16 coder_type, /* i : type of coder */ - Word16 clas, /* i : signal clas for current frame */ - const Word16 *fpit, /* i : close loop fractional pitch buffer */ - const Word16 *res, /* i : LP residual signal frame */ - Word16 *last_pulse_pos, /* i/o: Position of the last pulse */ - const Word16 L_frame, /* i : Frame length */ - const Word32 total_brate, /* i : total codec bitrate */ - const Word16 Q_new, /* i : input scaling */ - const Word16 shift /* i : scaling to get 12bits */ + BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ + const ACELP_config acelp_cfg, /* i/o: configuration of the ACELP */ + const Word16 *synth, /* i : pointer to synthesized speech for E computation Q_synth*/ + const Word16 coder_type, /* i : type of coder Q0*/ + Word16 clas, /* i : signal clas for current frame Q0*/ + const Word16 *fpit, /* i : close loop fractional pitch buffer Q6*/ + const Word16 *res, /* i : LP residual signal frame Qx*/ + Word16 *last_pulse_pos, /* i/o: Position of the last pulse Q0*/ + const Word16 L_frame, /* i : Frame length Q0*/ + const Word32 total_brate, /* i : total codec bitrate Q0*/ + const Word16 Q_new, /* i : input scaling */ + const Word16 shift /* i : scaling to get 12bits */ ) { Word16 tmpS, index; @@ -99,20 +100,19 @@ void FEC_encode_fx( /*-----------------------------------------------------------------* * encode frame energy (5 bits) *-----------------------------------------------------------------*/ - test(); IF( GT_16( acelp_cfg.FEC_mode, 1 ) ) /* GENERIC and VOICED frames */ { /* frame energy (maximum energy per pitch period for voiced frames or mean energy per sample over 2nd halframe for unvoiced frames) */ /*frame_ener( L_frame, clas, synth, fpit[(L_frame>>6)-1], &enr_q, 0 );*/ - exp_enrq = frame_ener_fx( L_frame, clas, synth, shr_r( fpit[sub( shr( L_frame, 6 ), 1 )], 6 ), &enr_q, L_frame, Q_new, shift, 1 ); + exp_enrq = frame_ener_fx( L_frame, clas, synth, shr_r( fpit[( L_frame >> 6 ) - 1], 6 ), &enr_q, L_frame, Q_new, shift, 1 ); /* linearly quantize the energy in the range 0 : FEC_ENR_STEP : 96 dB */ /*tmpS = (short)( 10.0 * log10( enr_q + 0.001f ) / FEC_ENR_STEP )*/ /*To be converted fl_2_fx*/ enr_lg_frac = Log2_norm_lc( enr_q ); - enr_lg_ent = sub( 30, exp_enrq ); - Ltmp = Mpy_32_16( enr_lg_ent, enr_lg_frac, LG10_s3_0 ); - tmpS = extract_h( L_shl( Ltmp, 1 ) ); + enr_lg_ent = sub( 30, exp_enrq ); /* Q15 */ + Ltmp = Mpy_32_16( enr_lg_ent, enr_lg_frac, LG10_s3_0 ); /* Q14 */ + tmpS = extract_h( L_shl( Ltmp, 1 ) ); /* Q15 + 1 -> Q0*/ tmpS = s_min( tmpS, 31 ); tmpS = s_max( tmpS, 0 ); @@ -122,7 +122,6 @@ void FEC_encode_fx( /*-----------------------------------------------------------------* * Encode last glottal pulse position (8 bits) *-----------------------------------------------------------------*/ - test(); IF( GT_16( acelp_cfg.FEC_mode, 2 ) ) /* GENERIC frames */ { /* retrieve the last glottal pulse position of the previous frame */ @@ -130,14 +129,14 @@ void FEC_encode_fx( tmp_FER_pitch = shr( fpit[0], 6 ); /* take the 1st subframe pit, since it is easier to get on decoder side */ sign = 0; move16(); - maxi = *last_pulse_pos; + maxi = *last_pulse_pos; /* Q0 */ move16(); IF( maxi < 0 ) { sign = 1; move16(); /*maxi = -maxi; */ - maxi = negate( maxi ); + maxi = negate( maxi ); /* Q0 */ } if ( GE_16( tmp_FER_pitch, 128 ) ) @@ -155,7 +154,7 @@ void FEC_encode_fx( if ( sign == 1 ) { - maxi = add( maxi, 128 ); /* use 8 bits (MSB represent the sign of the pulse) */ + maxi = add( maxi, 128 ); /* use 8 bits (MSB represent the sign of the pulse) Q0*/ } push_indice_fx( hBstr, IND_FEC_POS, maxi, FEC_BITS_POS ); @@ -169,15 +168,15 @@ void FEC_encode_fx( IF( GE_16( clas, VOICED_CLAS ) && GE_32( total_brate, ACELP_24k40 ) ) { /*maxi = findpulse( L_frame, res, (short)(fpit[(L_frame>>6)-1]), 0, &sign ); */ - maxi = findpulse_fx( L_frame, res, shr_r( fpit[sub( shr( L_frame, 6 ), 1 )], 6 ), 0, &sign ); + maxi = findpulse_fx( L_frame, res, shr_r( fpit[( L_frame >> 6 ) - 1], 6 ), 0, &sign ); /* Q0 */ if ( sign == 1 ) { /*maxi = -maxi;*/ - maxi = negate( maxi ); + maxi = negate( maxi ); /* Q0 */ } } - *last_pulse_pos = maxi; + *last_pulse_pos = maxi; /* Q0 */ move16(); } ELSE @@ -198,8 +197,8 @@ void FEC_encode_fx( *-------------------------------------------------------------------*/ void FEC_lsf_estim_enc_fx( - Encoder_State *st_fx, /* i : Encoder static memory */ - Word16 *lsf /* o : estimated LSF vector */ + Encoder_State *st_fx, /* i : Encoder static memory */ + Word16 *lsf /* o : estimated LSF vector Qlog2(2.56)*/ ) { Word16 i; @@ -222,7 +221,7 @@ void FEC_lsf_estim_enc_fx( IF( EQ_16( st_fx->last_coder_type, UNVOICED ) ) { /* clearly unvoiced */ - alpha = _ALPHA_UU_FX; + alpha = _ALPHA_UU_FX; /* Q15 */ move16(); } ELSE @@ -231,52 +230,54 @@ void FEC_lsf_estim_enc_fx( test(); IF( EQ_16( st_fx->last_coder_type, AUDIO ) || EQ_16( st_fx->clas, INACTIVE_CLAS ) ) { - alpha = 32604; + alpha = 32604; /* 0.995 in Q15 */ move16(); } ELSE IF( EQ_16( st_fx->clas, UNVOICED_CLAS ) ) { /* if stable, do not flatten the spectrum in the first erased frame */ /* alpha = st->stab_fac * (1.0f - 2.0f*ALPHA_U) + 2.0f*ALPHA_U; */ - alpha = add( mult( st_fx->stab_fac_fx, 32768 - _ALPHA_U_FX_X_2 ), _ALPHA_U_FX_X_2 ); + alpha = add( mult( st_fx->stab_fac_fx, 32768 - _ALPHA_U_FX_X_2 ), _ALPHA_U_FX_X_2 ); /* Q15 */ } ELSE IF( EQ_16( st_fx->clas, UNVOICED_TRANSITION ) ) { - alpha = _ALPHA_UT_FX; + alpha = _ALPHA_UT_FX; /* Q15 */ move16(); } ELSE IF( EQ_16( st_fx->clas, VOICED_CLAS ) || EQ_16( st_fx->clas, ONSET ) ) { /* clearly voiced - mild convergence to the CNG spectrum for the first three erased frames */ - alpha = _ALPHA_V_FX; + alpha = _ALPHA_V_FX; /* Q15 */ move16(); } ELSE IF( EQ_16( st_fx->clas, SIN_ONSET ) ) { - alpha = _ALPHA_S_FX; + alpha = _ALPHA_S_FX; /* Q15 */ move16(); } ELSE { /* long erasures and onsets - rapid convergence to the CNG spectrum */ - alpha = _ALPHA_VT_FX; + alpha = _ALPHA_VT_FX; /* Q15 */ move16(); } } /*----------------------------------------------------------------------* * Extrapolate LSF vector *----------------------------------------------------------------------*/ - tmp = sub( 32767, alpha ); + tmp = sub( 32767, alpha ); /* Q15 */ /* extrapolate the old LSF vector */ FOR( i = 0; i < M; i++ ) { /* calculate mean LSF vector */ /*lsf_mean[i] = BETA_FEC * lsf_mean[i] + (1-BETA_FEC) * st->lsf_adaptive_mean[i]; */ - lsf_mean[i] = mac_r( L_mult( BETA_FEC_FX, lsf_mean[i] ), 32768 - BETA_FEC_FX, st_fx->lsf_adaptive_mean_fx[i] ); + lsf_mean[i] = mac_r( L_mult( BETA_FEC_FX, lsf_mean[i] ), 32768 - BETA_FEC_FX, st_fx->lsf_adaptive_mean_fx[i] ); /* Qlog2(2.56) */ + move16(); /* move old LSF vector towards the mean LSF vector */ /* lsf[i] = alpha * st->lsf_old[i] + (1.0f - alpha) * lsf_mean[i]; */ - lsf[i] = mac_r( L_mult( alpha, st_fx->lsf_old_fx[i] ), tmp, lsf_mean[i] ); + lsf[i] = mac_r( L_mult( alpha, st_fx->lsf_old_fx[i] ), tmp, lsf_mean[i] ); /* Qlog2(2.56) */ + move16(); } /* check LSF stability through LSF ordering */ @@ -291,3 +292,175 @@ void FEC_lsf_estim_enc_fx( return; } + +/*-------------------------------------------------------------------* + * FEC_encode() + * + * Encoder supplementary information for FEC + *-------------------------------------------------------------------*/ + +void FEC_encode_ivas_fx( + BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ + const ACELP_config acelp_cfg, /* i/o: configuration of the ACELP */ + const Word16 *synth, /* i : pointer to synthesized speech for E computation Q_Synth*/ + const Word16 coder_type, /* i : type of coder Q0*/ + Word16 clas, /* i : signal clas for current frame Q0*/ + const Word16 *fpit, /* i : close loop fractional pitch buffer Q6*/ + const Word16 *res, /* i : LP residual signal frame Qx*/ + Word16 *last_pulse_pos, /* i/o: Position of the last pulse Q0*/ + const Word16 L_frame, /* i : Frame length Q0*/ + const Word32 total_brate, /* i : total codec bitrate Q0*/ + const Word16 Q_synth /* i : input scaling */ +) +{ + Word16 tmpS, index; + Word16 maxi, sign, tmp_FER_pitch; + Word32 enr_q, Ltmp; + Word16 exp_enrq; + + tmpS = 0; + move16(); + enr_q = 1; + move16(); + sign = 0; + move16(); + test(); + test(); + IF( GT_16( coder_type, UNVOICED ) && LT_16( coder_type, AUDIO ) && acelp_cfg.FEC_mode > 0 ) + { + /*-----------------------------------------------------------------* + * encode signal class (not needed for VC mode since it is clearly voiced) (2 bits) + *-----------------------------------------------------------------*/ + IF( NE_16( coder_type, VOICED ) ) + { + /* encode signal clas with 2 bits */ + test(); + IF( clas == UNVOICED_CLAS ) + { + index = 0; + move16(); + } + ELSE IF( EQ_16( clas, VOICED_TRANSITION ) || EQ_16( clas, UNVOICED_TRANSITION ) ) + { + index = 1; + move16(); + } + ELSE IF( EQ_16( clas, VOICED_CLAS ) ) + { + index = 2; + move16(); + } + ELSE + { + index = 3; + move16(); + } + push_indice( hBstr, IND_FEC_CLAS, index, FEC_BITS_CLS ); + } + + /*-----------------------------------------------------------------* + * encode frame energy (5 bits) + *-----------------------------------------------------------------*/ + IF( GT_16( acelp_cfg.FEC_mode, 1 ) ) /* GENERIC and VOICED frames */ + { + /* frame energy (maximum energy per pitch period for voiced frames or mean energy per sample over 2nd halframe for unvoiced frames) */ + /*frame_ener( L_frame, clas, synth, fpit[(L_frame>>6)-1], &enr_q, 0 );*/ + Word32 synth32[L_FRAME16k]; + Copy_Scale_sig_16_32_DEPREC( synth, synth32, L_FRAME16k, 0 ); /* Qsynth */ + fer_energy_fx( L_frame, clas, synth32, Q_synth, shr_r( fpit[( L_frame >> 6 ) - 1], 6 ), &enr_q, L_frame ); + exp_enrq = sub( 31, shl( Q_synth, 1 ) ); + + test(); + test(); + if ( EQ_16( clas, VOICED_CLAS ) || EQ_16( clas, ONSET ) || EQ_16( clas, SIN_ONSET ) ) /* Voiced or Onset current frame */ + { + exp_enrq = 31; + move16(); + } + /* linearly quantize the energy in the range 0 : FEC_ENR_STEP : 96 dB */ + /*tmpS = (short)( 10.0 * log10( enr_q + 0.001f ) / FEC_ENR_STEP )*/ /*To be converted fl_2_fx*/ + + Ltmp = Mpy_32_32( BASOP_Util_Log10( enr_q, exp_enrq ), 894784853 /* 10 / FEC_ENR_STEP Q28 */ ); // Q 25 + 28 - 31 = Q22 + IF( Ltmp < 0 ) + { + tmpS = extract_l( L_negate( L_shr( L_negate( Ltmp ), Q22 ) ) ); /* Q0 */ + } + ELSE + { + tmpS = extract_l( L_shr( Ltmp, Q22 ) ); /* Q0 */ + } + + tmpS = s_min( tmpS, FEC_ENR_QLIMIT ); + tmpS = s_max( tmpS, 0 ); + + push_indice( hBstr, IND_FEC_ENR, tmpS, FEC_BITS_ENR ); + } + /*-----------------------------------------------------------------* + * Encode last glottal pulse position (8 bits) + *-----------------------------------------------------------------*/ + + IF( GT_16( acelp_cfg.FEC_mode, 2 ) ) /* GENERIC frames */ + { + /* retrieve the last glottal pulse position of the previous frame */ + /* use the current pitch information to scale or not the quantization */ + tmp_FER_pitch = shr( fpit[0], 6 ); /* take the 1st subframe pit, since it is easier to get on decoder side */ + sign = 0; + move16(); + maxi = *last_pulse_pos; /* Q0 */ + move16(); + IF( maxi < 0 ) + { + sign = 1; + move16(); + /*maxi = -maxi; */ + maxi = negate( maxi ); + } + + if ( GE_16( tmp_FER_pitch, 128 ) ) + { + maxi = shr( maxi, 1 ); + } + + if ( GT_16( maxi, 127 ) ) + { + /* better not use the glottal pulse position at all instead of using a wrong pulse */ + /* can happen only with pitch > 254 and max pit = 289 and should happen very rarely */ + maxi = 0; + move16(); + } + + if ( EQ_16( sign, 1 ) ) + { + maxi = add( maxi, 128 ); /* use 8 bits (MSB represent the sign of the pulse) Q0*/ + } + + push_indice( hBstr, IND_FEC_POS, maxi, FEC_BITS_POS ); + } + maxi = 0; + move16(); + + /* If bitrate < 24k4, then the pitch + is not represented in the same domain (12.k instead of 16k) */ + test(); + IF( GE_16( clas, VOICED_CLAS ) && GE_32( total_brate, ACELP_24k40 ) ) + { + /*maxi = findpulse( L_frame, res, (short)(fpit[(L_frame>>6)-1]), 0, &sign ); */ + maxi = findpulse_fx( L_frame, res, shr_r( fpit[( L_frame >> 6 ) - 1], 6 ), 0, &sign ); + if ( EQ_16( sign, 1 ) ) + { + /*maxi = -maxi;*/ + maxi = negate( maxi ); + } + } + + *last_pulse_pos = maxi; /* Q0 */ + move16(); + } + ELSE + { + *last_pulse_pos = 0; + move16(); + } + + return; +} diff --git a/lib_enc/SNR_calc.c b/lib_enc/SNR_calc.c deleted file mode 100644 index 8d4adb219f2e97f01fc9e529ffbc94de34a8fde5..0000000000000000000000000000000000000000 --- a/lib_enc/SNR_calc.c +++ /dev/null @@ -1,42 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include -#include "prot.h" -#include "rom_enc.h" -#include "wmc_auto.h" diff --git a/lib_enc/SNR_calc_fx.c b/lib_enc/SNR_calc_fx.c index 320a68d255f539a42d1f543642c5abcd85a10863..09acfd5dca1bb7bde7ab0896faee5ba2148c79d1 100644 --- a/lib_enc/SNR_calc_fx.c +++ b/lib_enc/SNR_calc_fx.c @@ -19,16 +19,15 @@ *-------------------------------------------------------------------*/ void calc_lf_snr_fx( - Word32 *lf_snr_smooth, /* o : smoothed lf_snr*/ - Word32 *lf_snr, /* o : long time frequency domain - SNR calculated by l_speech_snr and l_silence_snr*/ - const Word32 l_speech_snr, /* i : sum of active frames snr */ - const Word32 l_speech_snr_count, /* i : amount of the active frame */ - const Word32 l_silence_snr, /* i : sum of the nonactive frames snr*/ - const Word32 l_silence_snr_count, /* i : amount of the nonactive frame */ - const Word16 fg_energy_count, /* i : amount of the foreground energy frame */ - const Word16 bg_energy_count, /* i : amount of the background energy frame */ - const Word16 bw_index /* i : band width index*/ + Word32 *lf_snr_smooth, /* o : smoothed lf_snr Q25*/ + Word32 *lf_snr, /* o : long time frequency domain SNR calculated by l_speech_snr and l_silence_snr Q25*/ + const Word32 l_speech_snr, /* i : sum of active frames snr Q16*/ + const Word32 l_speech_snr_count, /* i : amount of the active frame Q0*/ + const Word32 l_silence_snr, /* i : sum of the nonactive frames snr Q16*/ + const Word32 l_silence_snr_count, /* i : amount of the nonactive frame Q0*/ + const Word16 fg_energy_count, /* i : amount of the foreground energy frame Q0*/ + const Word16 bg_energy_count, /* i : amount of the background energy frame Q0*/ + const Word16 bw_index /* i : band width index Q0*/ ) { @@ -36,18 +35,18 @@ void calc_lf_snr_fx( Word16 q_divout, q_divout1; - div1 = VAD_L_div( l_speech_snr, l_speech_snr_count, 16, 0, &q_divout ); - div2 = VAD_L_div( l_silence_snr, l_silence_snr_count, 16, 0, &q_divout1 ); - l_snr = VAD_L_ADD( div1, q_divout, L_negate( div2 ), q_divout1, &q_divout ); + div1 = VAD_L_div( l_speech_snr, l_speech_snr_count, 16, 0, &q_divout ); /* q_divout */ + div2 = VAD_L_div( l_silence_snr, l_silence_snr_count, 16, 0, &q_divout1 ); /* q_divout1 */ + l_snr = VAD_L_ADD( div1, q_divout, L_negate( div2 ), q_divout1, &q_divout ); /* q_divout */ *lf_snr_smooth = MUL_F( *lf_snr_smooth, 29490 /* 0.9 Q15 */ ); move32(); - tmp = MUL_F( l_snr, 26214 ); - *lf_snr_smooth = VAD_L_ADD( *lf_snr_smooth, 25, tmp, add( 3, q_divout ), &q_divout1 ); + tmp = MUL_F( l_snr, 26214 /* 0.8 in Q15 */ ); + *lf_snr_smooth = VAD_L_ADD( *lf_snr_smooth, 25, tmp, add( 3, q_divout ), &q_divout1 ); /* q_divout1 */ move32(); - *lf_snr_smooth = L_shr( *lf_snr_smooth, sub( q_divout1, 25 ) ); + *lf_snr_smooth = L_shr( *lf_snr_smooth, sub( q_divout1, 25 ) ); /* Q25 */ move32(); - l_snr = L_shr( l_snr, sub( q_divout, 25 ) ); + l_snr = L_shr( l_snr, sub( q_divout, 25 ) ); /* Q25 */ test(); if ( ( LT_16( bg_energy_count, 56 ) ) || ( LT_16( fg_energy_count, 56 ) ) ) @@ -60,9 +59,9 @@ void calc_lf_snr_fx( l_snr = L_sub( l_snr, 12079595 /* 0.36 Q25 */ ); l_snr = L_max( 0, l_snr ); - l_snr = L_min( l_snr, MAX_LF_SNR_TAB_FX[bw_index] ); + l_snr = L_min( l_snr, MAX_LF_SNR_TAB_FX[bw_index] ); /* Q25 */ - *lf_snr = l_snr; + *lf_snr = l_snr; /* Q25 */ move32(); return; } @@ -73,14 +72,14 @@ void calc_lf_snr_fx( *-------------------------------------------------------------------*/ void calc_lt_snr_fx( VAD_CLDFB_HANDLE hVAD_CLDFB, /* i/o: CLDFB VAD state */ - Word32 *lt_snr_org_fp, /* o : original long time SNR*/ - Word32 *lt_snr_fp, /* o : long time SNR calculated by fg_energy and bg_energy*/ - Word32 fg_energy, /* i : foreground energy sum */ - Word16 fg_energy_count, /* i : amount of the foreground energy frame */ - Word32 bg_energy, /* i : background energy sum */ - Word16 bg_energy_count, /* i : amount of the background energy frame */ - Word16 bw_index, /* i : band width index*/ - Word16 lt_noise_sp_center0 /* i : long time noise spectral center by 0*/ + Word32 *lt_snr_org_fp, /* o : original long time SNR Q25*/ + Word32 *lt_snr_fp, /* o : long time SNR calculated by fg_energy and bg_energy Q25*/ + Word32 fg_energy, /* i : foreground energy sum Qx*/ + Word16 fg_energy_count, /* i : amount of the foreground energy frame Q0*/ + Word32 bg_energy, /* i : background energy sum Qx*/ + Word16 bg_energy_count, /* i : amount of the background energy frame Q0*/ + Word16 bw_index, /* i : band width index Q0*/ + Word16 lt_noise_sp_center0 /* i : long time noise spectral center by 0 Q10*/ ) { Word16 tmp_lt_noise_sp_center; @@ -89,7 +88,7 @@ void calc_lt_snr_fx( Word32 lt_snr, div1, div2, tmp; - tmp_lt_noise_sp_center = sub( lt_noise_sp_center0, 1432 /* 1.4 Q10 */ ); + tmp_lt_noise_sp_center = sub( lt_noise_sp_center0, 1432 /* 1.4 Q10 */ ); /* Q10 */ if ( GT_16( tmp_lt_noise_sp_center, 818 /* 0.8 Q10 */ ) ) { tmp_lt_noise_sp_center = 818 /* 0.8 Q10 */; @@ -103,28 +102,29 @@ void calc_lt_snr_fx( } div1 = MUL_F( fg_energy, bg_energy_count ); - div1 = VAD_L_ADD( div1, hVAD_CLDFB->fg_energy_scale, 1, 126, &q_div1 ); + div1 = VAD_L_ADD( div1, hVAD_CLDFB->fg_energy_scale, 1, 126, &q_div1 ); /* q_div1 */ div2 = MUL_F( bg_energy, fg_energy_count ); - div2 = VAD_L_ADD( div2, hVAD_CLDFB->bg_energy_scale, 1, 126, &q_div2 ); - if ( div2 == 0 ) + div2 = VAD_L_ADD( div2, hVAD_CLDFB->bg_energy_scale, 1, 126, &q_div2 ); /* q_div2 */ + IF( div2 == 0 ) { div2 = 1; move32(); /* div2==0 , may occur for >30000 frames all zero input */ if ( div1 != 0 ) { hVAD_CLDFB->bg_energy_scale = add( hVAD_CLDFB->fg_energy_scale, 50 ); + move16(); } } - div2 = VAD_L_div( div1, div2, q_div1, q_div2, &q_divout ); + div2 = VAD_L_div( div1, div2, q_div1, q_div2, &q_divout ); /* q_divout */ lt_snr_org = VAD_Log2( div2, q_divout ); - lt_snr_org = MUL_F( lt_snr_org, 9864 ); - lt_snr = lt_snr_org; + lt_snr_org = MUL_F( lt_snr_org, 9864 /* 0.3 in Q15 */ ); /* Q25 */ + lt_snr = lt_snr_org; /* Q25 */ move32(); - *lt_snr_org_fp = lt_snr; + *lt_snr_org_fp = lt_snr; /* Q25 */ move32(); test(); - IF( LT_16( bg_energy_count, 56 ) || LT_16( fg_energy_count, 56 ) ) + if ( LT_16( bg_energy_count, 56 ) || LT_16( fg_energy_count, 56 ) ) { lt_snr = 70464302 /* 2.1 Q25 */; move32(); @@ -132,26 +132,26 @@ void calc_lt_snr_fx( IF( EQ_16( bw_index, CLDFBVAD_NB_ID ) ) { - lt_snr = L_sub( L_shr( lt_snr, 1 ), 25165823 /* 0.75 Q25 */ ); + lt_snr = L_sub( L_shr( lt_snr, 1 ), 25165823 /* 0.75 Q25 */ ); /* Q25 */ } ELSE IF( EQ_16( bw_index, CLDFBVAD_WB_ID ) ) { - lt_snr = L_sub( L_shr( lt_snr, 1 ), 25165823 /* 0.75 Q25 */ ); + lt_snr = L_sub( L_shr( lt_snr, 1 ), 25165823 /* 0.75 Q25 */ ); /* Q25 */ } ELSE { - lt_snr = MUL_F( lt_snr, 15073 /* 0.46 Q15 */ ); - lt_snr = L_sub( lt_snr, 23152557 /* 0.69 Q25 */ ); + lt_snr = MUL_F( lt_snr, 15073 /* 0.46 Q15 */ ); /* Q25 */ + lt_snr = L_sub( lt_snr, 23152557 /* 0.69 Q25 */ ); /* Q25 */ } - tmp = MUL_F( lt_snr, 13107 /* 0.4 Q15 */ ); + tmp = MUL_F( lt_snr, 13107 /* 0.4 Q15 */ ); /* Q25 */ - tmp = L_add( L_shr( tmp, 1 ), -26214 ); + tmp = L_add( L_shr( tmp, 1 ), -26214 /* 0.0007 in Q25 */ ); - tmp = MUL_F( tmp, 13107 /* 0.4 Q15 */ ); + tmp = MUL_F( tmp, 13107 /* 0.4 Q15 */ ); /* Q25 */ tmp = MUL_F( tmp, tmp_lt_noise_sp_center ); - lt_snr = VAD_L_ADD( lt_snr, 25, tmp, 19, &q_divout1 ); - lt_snr = L_shr( lt_snr, sub( q_divout1, 25 ) ); + lt_snr = VAD_L_ADD( lt_snr, 25, tmp, 19, &q_divout1 ); /* q_divout1 */ + lt_snr = L_shr( lt_snr, sub( q_divout1, 25 ) ); /* Q25 */ lt_snr = L_max( 0, lt_snr ); @@ -161,7 +161,7 @@ void calc_lt_snr_fx( move32(); } - *lt_snr_fp = lt_snr; + *lt_snr_fp = lt_snr; /* Q25 */ move32(); return; } @@ -172,9 +172,9 @@ void calc_lt_snr_fx( * *-------------------------------------------------------------------*/ void calc_snr_flux_fx( - Word32 tsnr, /* i : time-domain SNR*/ - Word32 *pre_snr, /* i/o: time-domain SNR storage*/ - Word32 *snr_flux_fp /* o : average tsnr*/ + Word32 tsnr, /* i : time-domain SNR Q25*/ + Word32 *pre_snr, /* i/o: time-domain SNR storage Q25*/ + Word32 *snr_flux_fp /* o : average tsnr Q25*/ ) { Word32 i; @@ -186,7 +186,7 @@ void calc_snr_flux_fx( test(); IF( ( LT_32( L_shr( tsnr, 1 ), 43620759 /* 2.6f/2.0f Q25 */ ) ) && tsnr > 0 ) { - pre_snr[0] = tsnr; + pre_snr[0] = tsnr; /* Q25 */ move32(); } ELSE IF( tsnr <= 0 ) @@ -206,17 +206,17 @@ void calc_snr_flux_fx( s16MaxCoefNorm = sub( ffr_getSfWord32( pre_snr, 32 ), 5 ); FOR( i = 0; i < 32; i++ ) { - tmp = L_shl( pre_snr[i], s16MaxCoefNorm ); + tmp = L_shl( pre_snr[i], s16MaxCoefNorm ); /* Q25 + s16MaxCoefNorm */ snr_flux = L_add( snr_flux, tmp ); } snr_flux = L_shr( snr_flux, add( s16MaxCoefNorm, 5 ) ); - *snr_flux_fp = snr_flux; + *snr_flux_fp = snr_flux; /* Q25 */ move32(); /*update the tsnr storage pre_snr*/ FOR( i = PRE_SNR_NUM - 1; i > 0; i-- ) { - pre_snr[i] = pre_snr[i - 1]; + pre_snr[i] = pre_snr[i - 1]; /* Q25 */ move32(); } return; @@ -229,12 +229,12 @@ void calc_snr_flux_fx( * *-------------------------------------------------------------------*/ void snr_calc( - VAD_CLDFB_HANDLE hVAD_CLDFB, /* i/o: CLDFB VAD state */ - const Word16 sacle_sbpower, /* i : the Scaling of sbpower*/ - Word32 *snr, /* o : frequency domain SNR */ - Word32 *tsnr, /* o : time domain SNR */ - const Word32 frame_energy, /* i : current frame energy */ - const Word32 bwidth /* i : audio band width*/ + VAD_CLDFB_HANDLE hVAD_CLDFB, /* i/o: CLDFB VAD state */ + const Word16 sacle_sbpower, /* i : the Scaling of sbpower */ + Word32 *snr, /* o : frequency domain SNR Q25*/ + Word32 *tsnr, /* o : time domain SNR Q25*/ + const Word32 frame_energy, /* i : current frame energy sacle_sbpower*/ + const Word32 bwidth /* i : audio band width Q0*/ ) { Word32 i; @@ -248,10 +248,12 @@ void snr_calc( Word16 tmp_addQ1, tmp_addQ2, minscale, minscale1, minscale2, s16MaxCoefNorm, q_divout; Word32 tmpspec_amp; Word32 const CONSTfix = 1759218560; - Word32 snr_tmpidx[12] = { 0 }; + move32(); + Word32 snr_tmpidx[12]; + set_zero_fx( snr_tmpidx, 12 ); - SNR_sb_num = SNR_SUB_BAND_NUM[bwidth - CLDFBVAD_NB_ID]; + SNR_sb_num = SNR_SUB_BAND_NUM[bwidth - CLDFBVAD_NB_ID]; /* Q0 */ move16(); sb_bg_energy = hVAD_CLDFB->sb_bg_energy; frame_sb_energy = hVAD_CLDFB->frame_sb_energy; @@ -262,14 +264,14 @@ void snr_calc( move32(); FOR( i = 0; i < SNR_sb_num; i++ ) { - div1 = VAD_L_ADD( frame_sb_energy[i], hVAD_CLDFB->frame_sb_energy_scale, CONSTfix, 44, &tmp_addQ1 ); - div2 = VAD_L_ADD( sb_bg_energy[i], hVAD_CLDFB->sb_bg_energy_scale, CONSTfix, 44, &tmp_addQ2 ); - tmp = VAD_L_div( div1, div2, tmp_addQ1, tmp_addQ2, &q_divout ); + div1 = VAD_L_ADD( frame_sb_energy[i], hVAD_CLDFB->frame_sb_energy_scale, CONSTfix, 44, &tmp_addQ1 ); /* tmp_addQ1 */ + div2 = VAD_L_ADD( sb_bg_energy[i], hVAD_CLDFB->sb_bg_energy_scale, CONSTfix, 44, &tmp_addQ2 ); /* tmp_addQ2 */ + tmp = VAD_L_div( div1, div2, tmp_addQ1, tmp_addQ2, &q_divout ); /* q_divout */ tmp = VAD_Log2( tmp, q_divout ); if ( GT_32( tmp, -3355443 /* -0.10 Q25 */ ) ) { - snr_tmpidx[i] = tmp; + snr_tmpidx[i] = tmp; /* Q25 */ move32(); } } @@ -277,21 +279,21 @@ void snr_calc( s16MaxCoefNorm = sub( ffr_getSfWord32( snr_tmpidx, (Word16) SNR_sb_num ), 4 ); FOR( i = 0; i < SNR_sb_num; i++ ) { - tmpspec_amp = L_shl( snr_tmpidx[i], s16MaxCoefNorm ); + tmpspec_amp = L_shl( snr_tmpidx[i], s16MaxCoefNorm ); /* Q25 + s16MaxCoefNorm */ snr_tmp = L_add( snr_tmp, tmpspec_amp ); } snr_tmp = L_max( 0, snr_tmp ); - snr_tmp = MUL_F( snr_tmp, BAND_MUL[bwidth - CLDFBVAD_NB_ID] ); - *snr = L_shr( snr_tmp, s16MaxCoefNorm ); + snr_tmp = MUL_F( snr_tmp, BAND_MUL[bwidth - CLDFBVAD_NB_ID] ); /* Q25 + s16MaxCoefNorm */ + *snr = L_shr( snr_tmp, s16MaxCoefNorm ); /* Q25 */ move32(); - IF( bwidth == CLDFBVAD_SWB_ID ) + IF( EQ_32( bwidth, CLDFBVAD_SWB_ID ) ) { IF( t_bg_energy ) { minscale = norm_l( t_bg_energy ); minscale2 = sub( s_min( add( minscale, hVAD_CLDFB->scale_t_bg_energy ), 31 ), 1 ); - tmpsb_eg = L_shr( t_bg_energy, sub( hVAD_CLDFB->scale_t_bg_energy, minscale2 ) ); + tmpsb_eg = L_shr( t_bg_energy, sub( hVAD_CLDFB->scale_t_bg_energy, minscale2 ) ); /* minscale2 */ constff = L_shr( 1, sub( 31, minscale2 ) ); } ELSE @@ -304,12 +306,12 @@ void snr_calc( move16(); } div2 = L_add( tmpsb_eg, constff ); - tmp = VAD_L_div( frame_energy, div2, sacle_sbpower, minscale2, &q_divout ); + tmp = VAD_L_div( frame_energy, div2, sacle_sbpower, minscale2, &q_divout ); /* q_divout */ IF( tmp ) { minscale = norm_l( tmp ); minscale2 = sub( s_min( add( minscale, q_divout ), 31 ), 1 ); - tmpsb_eg = L_shr( tmp, limitScale32( sub( q_divout, minscale2 ) ) ); + tmpsb_eg = L_shr( tmp, limitScale32( sub( q_divout, minscale2 ) ) ); /* minscale2 */ constff = L_shr( 1, sub( 31, minscale2 ) ); tmp = L_add( tmpsb_eg, constff ); } @@ -322,11 +324,7 @@ void snr_calc( } *tsnr = VAD_Log2( tmp, minscale2 ); move32(); -#ifdef BASOP_NOGLOB - *tsnr = L_add_sat( *tsnr, MUL_F( *tsnr, 6226 ) ); /* *tsnr *= 1.2; */ -#else - *tsnr = L_add( *tsnr, MUL_F( *tsnr, 6226 ) ); /* *tsnr *= 1.2; */ -#endif + *tsnr = L_add_sat( *tsnr, MUL_F( *tsnr, 6226 ) ); /* *tsnr *= 1.2; Q25*/ move32(); } ELSE @@ -335,7 +333,7 @@ void snr_calc( { minscale = norm_l( frame_energy ); minscale1 = sub( s_min( add( minscale, sacle_sbpower ), 44 ), 1 ); - tmpframe_eg = L_shr( frame_energy, sub( sacle_sbpower, minscale1 ) ); + tmpframe_eg = L_shr( frame_energy, sub( sacle_sbpower, minscale1 ) ); /* minscale1 */ constff = L_shr( CONSTfix, sub( 44, minscale1 ) ); } ELSE @@ -352,7 +350,7 @@ void snr_calc( { minscale = norm_l( t_bg_energy ); minscale2 = sub( s_min( add( minscale, hVAD_CLDFB->scale_t_bg_energy ), 44 ), 1 ); - tmpsb_eg = L_shr( t_bg_energy, sub( hVAD_CLDFB->scale_t_bg_energy, minscale2 ) ); + tmpsb_eg = L_shr( t_bg_energy, sub( hVAD_CLDFB->scale_t_bg_energy, minscale2 ) ); /* minscale2 */ constff = L_shr( CONSTfix, sub( 44, minscale2 ) ); } ELSE @@ -365,29 +363,29 @@ void snr_calc( move16(); } div2 = L_add( tmpsb_eg, constff ); - tmp = VAD_L_div( div1, div2, minscale1, minscale2, &q_divout ); - *tsnr = VAD_Log2( tmp, q_divout ); + tmp = VAD_L_div( div1, div2, minscale1, minscale2, &q_divout ); /* q_divout */ + *tsnr = VAD_Log2( tmp, q_divout ); /* Q25 */ move32(); } return; } Word32 construct_snr_thresh_fx( - Word16 sp_center[], /* i : spectral center*/ - Word32 snr_flux, /* i : snr flux*/ - Word32 lt_snr, /* i : long time time domain snr*/ - Word32 l_snr, /* i : long time frequency domain snr*/ - Word32 continuous_speech_num, /* i : amount of continuous speech frames*/ - Word16 continuous_noise_num, /* i : amount of continuous noise frames*/ - Word32 fg_energy_est_start, /* i : whether if estimated energy*/ - Word16 bw_index /* i : band width index*/ + Word16 sp_center[], /* i : spectral center Q10*/ + Word32 snr_flux, /* i : snr flux Q25*/ + Word32 lt_snr, /* i : long time time domain snr Q25*/ + Word32 l_snr, /* i : long time frequency domain snr Q25*/ + Word32 continuous_speech_num, /* i : amount of continuous speech frames Q0*/ + Word16 continuous_noise_num, /* i : amount of continuous noise frames Q0*/ + Word32 fg_energy_est_start, /* i : whether if estimated energy Q0*/ + Word16 bw_index /* i : band width index Q0*/ ) { Word32 bw_snr, tmp_snr, snr_delta, test_l_snr, tmp, div1, div2; - snr_delta = COMVAD_INIT_SNR_DELTA_FX[bw_index]; + snr_delta = COMVAD_INIT_SNR_DELTA_FX[bw_index]; /* Q25 */ move32(); bw_snr = lt_snr; move32(); @@ -397,126 +395,108 @@ Word32 construct_snr_thresh_fx( move32(); IF( EQ_16( bw_index, CLDFBVAD_SWB_ID ) ) { - - IF( GT_16( sp_center[3], 2864 /* 2.80 Q10 */ ) ) + IF( GT_16( sp_center[2], 2660 /* 2.6 Q10 */ ) ) { - snr_delta = snr_delta; - move32(); - } - ELSE IF( GT_16( sp_center[2], 2660 /* 2.6 Q10 */ ) ) - { - snr_delta = L_add( snr_delta, 1006633 /* 0.03 Q25 */ ); + snr_delta = L_add( snr_delta, 1006633 /* 0.03 Q25 */ ); /* Q25 */ } ELSE IF( GT_16( sp_center[2], 1637 /* 1.6 Q10 */ ) ) { - snr_delta = L_add( snr_delta, 1677722 /* 0.05 Q25 */ ); + snr_delta = L_add( snr_delta, 1677722 /* 0.05 Q25 */ ); /* Q25 */ } ELSE IF( GT_16( sp_center[3], 1432 /* 1.4 Q10 */ ) ) { - snr_delta = L_add( snr_delta, 3355443 /* 0.10 Q25 */ ); + snr_delta = L_add( snr_delta, 3355443 /* 0.10 Q25 */ ); /* Q25 */ } ELSE { - snr_delta = L_add( snr_delta, 13421773 /* 0.40 Q25 */ ); + snr_delta = L_add( snr_delta, 13421773 /* 0.40 Q25 */ ); /* Q25 */ } - tmp = MUL_F( l_snr, 3277 /* 0.1 Q15 */ ); + tmp = MUL_F( l_snr, 3277 /* 0.1 Q15 */ ); /* Q25 */ tmp = L_add( tmp, 20132659 /* 0.6 Q25 */ ); test(); test(); IF( GT_32( continuous_speech_num, 8 ) && EQ_32( fg_energy_est_start, 1 ) ) { - snr_delta = L_sub( snr_delta, 6710886 /* 0.2 Q25 */ ); + snr_delta = L_sub( snr_delta, 6710886 /* 0.2 Q25 */ ); /* Q25 */ } ELSE IF( GT_16( continuous_noise_num, 12 ) && ( GT_32( snr_flux, tmp ) ) ) { - snr_delta = L_add( snr_delta, 3355443 /* 0.10 Q25 */ ); + snr_delta = L_add( snr_delta, 3355443 /* 0.10 Q25 */ ); /* Q25 */ } ELSE IF( GT_16( continuous_noise_num, 24 ) ) { - snr_delta = L_add( snr_delta, 6710886 /* 0.2 Q25 */ ); + snr_delta = L_add( snr_delta, 6710886 /* 0.2 Q25 */ ); /* Q25 */ } ELSE IF( ( GT_16( continuous_noise_num, 4 ) ) ) { - snr_delta = L_add( snr_delta, 3355443 /* 0.10 Q25 */ ); + snr_delta = L_add( snr_delta, 3355443 /* 0.10 Q25 */ ); /* Q25 */ } } ELSE IF( EQ_16( bw_index, CLDFBVAD_WB_ID ) ) { - - IF( GT_16( sp_center[3], 2864 /* 2.80 Q10 */ ) ) + IF( GT_16( sp_center[2], 2660 /* 2.6 Q10 */ ) ) { - snr_delta = snr_delta; - move32(); - } - ELSE IF( GT_16( sp_center[2], 2660 /* 2.6 Q10 */ ) ) - { - snr_delta = L_add( snr_delta, 1006633 /* 0.03 Q25 */ ); + snr_delta = L_add( snr_delta, 1006633 /* 0.03 Q25 */ ); /* Q25 */ } ELSE IF( GT_16( sp_center[2], 1637 /* 1.6 Q10 */ ) ) { - snr_delta = L_add( snr_delta, 1677722 /* 0.05 Q25 */ ); + snr_delta = L_add( snr_delta, 1677722 /* 0.05 Q25 */ ); /* Q25 */ } ELSE IF( GT_16( sp_center[3], 1432 /* 1.4 Q10 */ ) ) { - snr_delta = L_add( snr_delta, 3355443 /* 0.10 Q25 */ ); + snr_delta = L_add( snr_delta, 3355443 /* 0.10 Q25 */ ); /* Q25 */ } ELSE { - snr_delta = L_add( snr_delta, 10066330 /* 0.30 Q25 */ ); + snr_delta = L_add( snr_delta, 10066330 /* 0.30 Q25 */ ); /* Q25 */ } - tmp = MUL_F( bw_snr, 3277 /* 0.1 Q15 */ ); - tmp = L_add( tmp, 20132659 /* 0.6 Q25 */ ); + tmp = MUL_F( bw_snr, 3277 /* 0.1 Q15 */ ); /* Q25 */ + tmp = L_add( tmp, 20132659 /* 0.6 Q25 */ ); /* Q25 */ test(); test(); IF( GT_32( continuous_speech_num, 8 ) && EQ_32( fg_energy_est_start, 1 ) ) { - snr_delta = L_sub( snr_delta, 3355443 /* 0.10 Q25 */ ); + snr_delta = L_sub( snr_delta, 3355443 /* 0.10 Q25 */ ); /* Q25 */ } ELSE IF( GT_16( continuous_noise_num, 12 ) && ( GT_32( snr_flux, tmp ) ) ) { - snr_delta = L_add( snr_delta, 3355443 /* 0.10 Q25 */ ); + snr_delta = L_add( snr_delta, 3355443 /* 0.10 Q25 */ ); /* Q25 */ } ELSE IF( GT_16( continuous_noise_num, 24 ) ) { - snr_delta = L_add( snr_delta, 6710886 /* 0.20 Q25 */ ); + snr_delta = L_add( snr_delta, 6710886 /* 0.20 Q25 */ ); /* Q25 */ } ELSE IF( ( GT_16( continuous_noise_num, 4 ) ) ) { - snr_delta = L_add( snr_delta, 3355443 /* 0.10 Q25 */ ); + snr_delta = L_add( snr_delta, 3355443 /* 0.10 Q25 */ ); /* Q25 */ } } ELSE IF( EQ_16( bw_index, CLDFBVAD_NB_ID ) ) { - - IF( GT_16( sp_center[3], 3069 /* 3.0 Q10 */ ) ) - { - snr_delta = snr_delta; - move32(); - } - ELSE IF( GT_16( sp_center[2], 2660 /* 2.6 Q10 */ ) ) + IF( GT_16( sp_center[2], 2660 /* 2.6 Q10 */ ) ) { - snr_delta = L_add( snr_delta, 671089 /* 0.02 Q25 */ ); + snr_delta = L_add( snr_delta, 671089 /* 0.02 Q25 */ ); /* Q25 */ } ELSE IF( GT_16( sp_center[2], 1637 /* 1.6 Q10 */ ) ) { - snr_delta = L_add( snr_delta, 1342177 /* 0.04 Q25 */ ); + snr_delta = L_add( snr_delta, 1342177 /* 0.04 Q25 */ ); /* Q25 */ } ELSE IF( GT_16( sp_center[2], 1494 /* 1.46 Q10 */ ) ) { - snr_delta = L_add( snr_delta, 3355443 /* 0.10 Q25 */ ); + snr_delta = L_add( snr_delta, 3355443 /* 0.10 Q25 */ ); /* Q25 */ } ELSE { - snr_delta = L_add( snr_delta, 6039798 /* 0.18 Q25 */ ); + snr_delta = L_add( snr_delta, 6039798 /* 0.18 Q25 */ ); /* Q25 */ } - tmp = MUL_F( l_snr, 3277 /* 0.1 Q15 */ ); - div1 = L_add( tmp, 6710886 /* 0.2 Q25 */ ); - div2 = L_add( tmp, 20132659 /* 0.6 Q25 */ ); + tmp = MUL_F( l_snr, 3277 /* 0.1 Q15 */ ); /* Q25 */ + div1 = L_add( tmp, 6710886 /* 0.2 Q25 */ ); /* Q25 */ + div2 = L_add( tmp, 20132659 /* 0.6 Q25 */ ); /* Q25 */ test(); test(); @@ -525,19 +505,19 @@ Word32 construct_snr_thresh_fx( test(); IF( GT_32( continuous_speech_num, 80 ) && EQ_32( fg_energy_est_start, 1 ) && ( GT_16( sp_center[0], 1432 /* 1.4 Q10 */ ) ) ) { - snr_delta = L_sub( snr_delta, 10737418 /* 0.32 Q25 */ ); + snr_delta = L_sub( snr_delta, 10737418 /* 0.32 Q25 */ ); /* Q25 */ } ELSE IF( GT_32( continuous_speech_num, 8 ) && EQ_32( fg_energy_est_start, 1 ) && ( GT_32( snr_flux, div1 ) ) ) { - snr_delta = L_sub( snr_delta, 3355443 /* 0.10 Q25 */ ); + snr_delta = L_sub( snr_delta, 3355443 /* 0.10 Q25 */ ); /* Q25 */ } ELSE IF( GT_16( continuous_noise_num, 12 ) && ( GT_32( snr_flux, div2 ) ) ) { - snr_delta = L_add( snr_delta, 3355443 /* 0.10 Q25 */ ); + snr_delta = L_add( snr_delta, 3355443 /* 0.10 Q25 */ ); /* Q25 */ } ELSE IF( GT_16( continuous_noise_num, 24 ) ) { - snr_delta = L_add( snr_delta, 6710886 /* 0.2 Q25 */ ); + snr_delta = L_add( snr_delta, 6710886 /* 0.2 Q25 */ ); /* Q25 */ } } ELSE @@ -545,7 +525,7 @@ Word32 construct_snr_thresh_fx( snr_delta = 33554431 /* 1.0 Q25 */; move32(); } - tmp_snr = L_add( snr_delta, test_l_snr ); + tmp_snr = L_add( snr_delta, test_l_snr ); /* Q25 */ return tmp_snr; diff --git a/lib_enc/acelp_core_enc.c b/lib_enc/acelp_core_enc.c deleted file mode 100644 index d3d542f321dd3fc4ec9043fc0aead352da399fab..0000000000000000000000000000000000000000 --- a/lib_enc/acelp_core_enc.c +++ /dev/null @@ -1,968 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include -#include "cnst.h" -#include "rom_enc.h" -#include "rom_com.h" -#include "prot.h" -#include "ivas_cnst.h" -#include "ivas_prot.h" -#include "ivas_prot_fx.h" -#include "prot_fx.h" -#include "prot_fx_enc.h" -#include "ivas_rom_com.h" -#include "wmc_auto.h" -#include "options_warnings.h" - -#include "prot_fx_enc.h" -#include "prot_fx.h" - -/*-------------------------------------------------------------------* - * acelp_core_enc() - * - * ACELP core encoder - *--------------------------------------------------------------------*/ -ivas_error acelp_core_enc( - Encoder_State *st, /* i/o: encoder state structure */ - const Word16 inp[], /* i : input signal of the current frame */ - Word16 A[NB_SUBFR16k * ( M + 1 )], /* i : A(z) unquantized for the 4 subframes*/ - Word16 Aw[NB_SUBFR16k * ( M + 1 )], /* i : weighted A(z) unquant. for subframes*/ - const Word32 epsP[M + 1], /* i : LP prediction errors */ - Word16 lsp_new[M], /* i : LSPs at the end of the frame */ - Word16 lsp_mid[M], /* i : LSPs in the middle of the frame */ - const Word16 vad_hover_flag, /* i : VAD hangover flag */ - const Word16 attack_flag, /* i : attack flag (GSC or TC) */ - Word32 bwe_exc_extended_fx[], /* i/o: bandwidth extended excitation */ - Word16 *voice_factors_fx, /* o : voicing factors Q15 */ - Word16 old_syn_12k8_16k[], /* o : intermediate ACELP synthesis at 12.8kHz or 16kHz to be used by SWB BWE */ - Word16 *q_old_syn_12k8_16, - Word16 pitch_buf[NB_SUBFR16k], /* o : floating pitch for each subframe */ - Word16 *unbits, /* o : number of unused bits */ - STEREO_TD_ENC_DATA_HANDLE hStereoTD, /* i/o: TD stereo encoder handle */ - Word16 tdm_lsfQ_PCh[M], /* i : Q LSFs for primary channel */ - Word16 Q_new ) -{ - Word16 i, nBits; /* reserved bits */ - LPD_state_HANDLE hLPDmem; /* i/o: acelp memories */ - Word16 tc_subfr; /* TC sub-frame indication */ - Word16 allow_cn_step; - Word32 int_fs; - Word16 nb_bits; /* parameters handling */ - - /* SC-VBR - back-up memories for LSF quantizer and synthesis filter */ - Word16 pstreaklen; - Word16 sid_bw = -1; - Word16 next_force_sf_bck; - Word16 uc_two_stage_flag; - Word16 position; - Word16 ppp_mode, nelp_mode; - Word16 tdm_lp_reuse_flag, tdm_low_rate_mode, tdm_Pitch_reuse_flag; - - /* bitstream */ - BSTR_ENC_HANDLE hBstr = st->hBstr; - Word16 old_exc_fx[L_EXC], *exc_fx; /* excitation signal buffer */ - Word16 lsf_new_fx[M]; /* ISFs at the end of the frame */ - Word16 Aq[NB_SUBFR16k * ( M + 1 )]; /* A(z) quantized for the 4 subframes */ - Word16 syn_fx[L_FRAME16k]; /* synthesis vector */ - Word16 res_fx[L_FRAME16k]; /* Residual signal for FER protection */ - Word16 exc2_fx[L_FRAME16k]; /* enhanced excitation */ - Word16 Es_pred_fx; /* predicited scaled innovation energy */ - Word16 tmp_noise_fx; /* NB post-filter long-term noise energy*/ - Word16 old_bwe_exc_fx[( PIT16k_MAX + ( L_FRAME16k + 1 ) + L_SUBFR16k ) * 2]; /* excitation buffer Q_new */ - Word16 *bwe_exc_fx; /* excitation for SWB TBE Q_new */ - Word16 mem_MA_fx[M], mem_AR_fx[M], lsp_new_bck_fx[M], /*lsf_new_bck_fx[M],*/ lsp_mid_bck_fx[M], mem_syn_bck_fx[M]; - Word32 Bin_E_fx[L_FFT], Bin_E_old_fx[L_FFT / 2]; - Word16 clip_var_fx, mem_w0_bck_fx, streaklimit_fx; - -#ifdef MSAN_FIX - set16_fx( old_bwe_exc_fx, 0, ( PIT16k_MAX + ( L_FRAME16k + 1 ) + L_SUBFR16k ) * 2 ); - set16_fx( old_exc_fx, 0, L_EXC ); - set16_fx( Aq, 0, NB_SUBFR16k * ( M + 1 ) ); - set16_fx( syn_fx, 0, L_FRAME16k ); -#endif - - Word16 tilt_code_bck_fx; - Word32 gc_threshold_bck_fx; - Word16 clip_var_bck_fx[6]; - Word32 q_env_fx[NUM_ENV_CNG]; -#ifdef MSAN_FIX - set32_fx( q_env_fx, 0, NUM_ENV_CNG ); -#endif - Word16 exc3_fx[L_FRAME16k]; - Word16 syn1_fx[L_FRAME16k]; - Word16 *tdm_Pri_pitch_buf_fx; - - Word16 att_fx; - Word16 tmpF_fx; - - test(); - IF( !st->Opt_AMR_WB && st->hBWE_TD != NULL ) - { - Scale_sig( st->hBWE_TD->old_bwe_exc_fx, PIT16k_MAX * 2, sub( Q_new, st->prev_Q_new ) ); // Q_new - } - IF( st->hLPDmem ) - { - Scale_sig( st->hLPDmem->old_exc, L_EXC_MEM, sub( Q_new, st->hLPDmem->q_lpd_old_exc ) ); // Q_new - st->hLPDmem->q_lpd_old_exc = Q_new; - move16(); - Scale_sig( st->hLPDmem->syn, M + 1, sub( Q_new, st->hLPDmem->q_lpd_syn ) ); // Q_new - st->hLPDmem->q_lpd_syn = Q_new; - move16(); - Scale_sig( st->hLPDmem->mem_syn, M, sub( sub( Q_new, 1 ), st->hLPDmem->q_mem_syn ) ); // Q_new -1 - Scale_sig( st->hLPDmem->mem_syn1_fx, M, sub( sub( Q_new, 1 ), st->hLPDmem->q_mem_syn ) ); // Q_new -1 - Scale_sig( st->hLPDmem->mem_syn2, M, sub( sub( Q_new, 1 ), st->hLPDmem->q_mem_syn ) ); // Q_new -1 - Scale_sig( st->hLPDmem->mem_syn3, M, sub( sub( Q_new, 1 ), st->hLPDmem->q_mem_syn ) ); // Q_new -1 - Scale_sig( st->hLPDmem->mem_syn_r, L_SYN_MEM, sub( sub( Q_new, 1 ), st->hLPDmem->q_mem_syn ) ); // Q_new -1 - st->hLPDmem->mem_w0 = shl_sat( st->hLPDmem->mem_w0, sub( sub( Q_new, 1 ), st->hLPDmem->q_mem_syn ) ); // Q_new -1 - move16(); - st->hLPDmem->q_mem_syn = sub( Q_new, 1 ); - move16(); - } - - Scale_sig32( st->Bin_E_old_fx, L_FFT / 2, sub( add( Q_new, Q_SCALE - 2 ), st->q_Bin_E_old ) ); // Q_new + Q_scale - 2 - st->q_Bin_E_old = add( Q_new, Q_SCALE - 2 ); - move16(); - Scale_sig32( st->Bin_E_fx, L_FFT, sub( add( Q_new, Q_SCALE - 2 ), st->q_Bin_E ) ); // Q_new + Q_scale - 2 - st->q_Bin_E = add( Q_new, Q_SCALE - 2 ); - move16(); - - ivas_error error; - - error = IVAS_ERR_OK; - move32(); - - test(); - IF( EQ_16( st->element_mode, IVAS_CPE_MDCT ) && LE_32( st->core_brate, SID_2k40 ) ) - { - /* Core was ACELP because of DTX in MDCT-Stereo, but SID encoding for that is done in separate function */ - return error; - } - - push_wmops( "acelp_core_enc" ); - /*------------------------------------------------------------------* - * Initialization - *------------------------------------------------------------------*/ - - hLPDmem = st->hLPDmem; - - Es_pred_fx = 0; - move16(); - - exc_fx = old_exc_fx + L_EXC_MEM; /* pointer to excitation signal in the current frame */ - Copy( hLPDmem->old_exc, old_exc_fx, L_EXC_MEM ); - Scale_sig( old_exc_fx, L_EXC_MEM, sub( Q_new, hLPDmem->q_lpd_old_exc ) ); // Q_new - IF( st->hBWE_TD != NULL ) - { - bwe_exc_fx = old_bwe_exc_fx + PIT16k_MAX * 2; /* pointer to BWE excitation signal in the current frame */ - Copy( st->hBWE_TD->old_bwe_exc_fx, old_bwe_exc_fx, PIT16k_MAX * 2 ); - } - ELSE - { - bwe_exc_fx = NULL; - } - - st->bpf_off = 0; - move16(); - - test(); - test(); - test(); - IF( EQ_16( st->last_core, HQ_CORE ) || EQ_16( st->last_codec_mode, MODE2 ) || EQ_16( st->last_core, TCX_20_CORE ) || EQ_16( st->last_core, TCX_10_CORE ) ) - { - /* in case of HQ->ACELP switching, do not apply BPF */ - st->bpf_off = 1; - move16(); - /* reset the GSC pre echo energy threshold in case of switching */ - if ( st->hGSCEnc != NULL ) - { - st->hGSCEnc->Last_frame_ener_fx = MAX_32; - move32(); - } - } - - /* force safety-net LSFQ in the first frames after CNG segment */ - if ( LE_32( st->last_core_brate, SID_2k40 ) ) - { - st->Nb_ACELP_frames = 0; - move16(); - } - st->Nb_ACELP_frames = add( st->Nb_ACELP_frames, 1 ); - move16(); - - IF( EQ_16( st->L_frame, L_FRAME ) ) - { - int_fs = INT_FS_12k8; - move32(); - } - ELSE - { - int_fs = INT_FS_16k; - move32(); - } - - tmp_noise_fx = 0; - move16(); - tc_subfr = -1; - move16(); - position = -1; - move16(); - - /* SC-VBR temporary variables */ - pstreaklen = 0; - move16(); - clip_var_fx = 0; - move16(); - mem_w0_bck_fx = 0; - move16(); - streaklimit_fx = 0; - move16(); - - /* channel-aware mode */ - reset_rf_indices_fx( st ); - - /* VBR modes */ - IF( st->Opt_SC_VBR ) - { - ppp_mode = st->hSC_VBR->ppp_mode; - nelp_mode = st->hSC_VBR->nelp_mode; - } - ELSE - { - ppp_mode = 0; - nelp_mode = 0; - } - move16(); - move16(); - - test(); - /* TD stereo */ - - IF( EQ_16( st->element_mode, IVAS_CPE_TD ) && EQ_16( st->idchan, 1 ) ) - { - tdm_lp_reuse_flag = hStereoTD->tdm_lp_reuse_flag; - tdm_low_rate_mode = hStereoTD->tdm_low_rate_mode; - tdm_Pitch_reuse_flag = hStereoTD->tdm_Pitch_reuse_flag; - tdm_Pri_pitch_buf_fx = hStereoTD->tdm_Pri_pitch_buf_fx; - } - ELSE - { - tdm_lp_reuse_flag = 0; - tdm_low_rate_mode = 0; - test(); - if ( EQ_16( st->element_mode, IVAS_SCE ) && st->low_rate_mode ) - { - tdm_low_rate_mode = 1; - move16(); - } - tdm_Pitch_reuse_flag = 0; - tdm_Pri_pitch_buf_fx = NULL; - } - move16(); - move16(); - move16(); - - /*-----------------------------------------------------------------* - * ACELP@12k8 / ACELP@16k switching - *-----------------------------------------------------------------*/ - - test(); - test(); - IF( NE_16( st->last_L_frame, st->L_frame ) && ( st->last_core == ACELP_CORE || EQ_16( st->last_core, AMR_WB_CORE ) ) ) - { - /* in case of switching, do not apply BPF (flag employed also in updt_enc()) */ - st->bpf_off = 1; - move16(); - - /* force safety-net LSFQ in the first frames after ACELP@12k8/ACELP@16k switching */ - st->Nb_ACELP_frames = 1; - move16(); - - /* convert old quantized LSP vector */ - IF( EQ_16( st->L_frame, L_FRAME ) ) - { - st->rate_switching_reset = lsp_convert_poly_fx( st->lsp_old_fx, st->L_frame, 0 ); - move16(); - } - ELSE - { - st->rate_switching_reset = st->rate_switching_reset_16kHz; - move16(); - Copy( st->lsp_old16k_fx, st->lsp_old_fx, M ); // Q15 - } - - /* convert old quantized LSF vector */ - lsp2lsf_fx( st->lsp_old_fx, st->lsf_old_fx, M, int_fs ); - - /* interpolation of unquantized ISPs */ - IF( st->rate_switching_reset ) - { - /*extrapolation in case of unstable LSP*/ - int_lsp4_ivas_fx( st->L_frame, lsp_mid, lsp_mid, lsp_new, A, M, 0 ); - } - ELSE - { - int_lsp4_ivas_fx( st->L_frame, st->lsp_old_fx, lsp_mid, lsp_new, A, M, 0 ); - } - - /* Reset LPC mem */ - Copy( GEWB_Ave_fx, st->mem_AR_fx, M ); - set16_fx( st->mem_MA_fx, 0, M ); - - /* update synthesis filter memories */ - synth_mem_updt2( st->L_frame, st->last_L_frame, hLPDmem->old_exc, hLPDmem->mem_syn_r, hLPDmem->mem_syn2, hLPDmem->mem_syn, ENC ); - Copy( hLPDmem->old_exc, old_exc_fx, L_EXC_MEM ); - Copy( hLPDmem->mem_syn2, hLPDmem->mem_syn1_fx, M ); - Copy( hLPDmem->mem_syn2, hLPDmem->mem_syn3, M ); - - /* update Aw[] coefficients */ - weight_a_subfr_fx( shr( st->L_frame, 6 ), A, Aw, st->gamma, M ); - } - IF( st->hLPDmem ) - { - st->hLPDmem->q_mem_syn = sub( Q_new, 1 ); - move16(); - st->hLPDmem->q_lpd_old_exc = Q_new; - move16(); - st->hLPDmem->q_lpd_syn = Q_new; - move16(); - } - - test(); - test(); - if ( st->last_bwidth == NB && st->bwidth != NB && st->ini_frame != 0 ) - { - st->rate_switching_reset = 1; - move16(); - } - - /*----------------------------------------------------------------* - * Encoding of CNG frames - *----------------------------------------------------------------*/ - test(); - IF( EQ_32( st->core_brate, SID_2k40 ) || EQ_32( st->core_brate, FRAME_NO_DATA ) ) - { - IF( EQ_16( st->cng_type, LP_CNG ) ) - { - /* Run CNG post parameter update */ - cng_params_postupd_ivas_fx( st->hTdCngEnc->ho_circ_ptr, &st->hTdCngEnc->cng_buf_cnt, st->hTdCngEnc->cng_exc2_buf, st->hTdCngEnc->cng_Qexc_buf, st->hTdCngEnc->cng_brate_buf, st->hTdCngEnc->ho_env_circ_fx, st->element_mode, st->hFdCngEnc->hFdCngCom->CngBandwidth ); - - /* encode CNG parameters */ - CNG_enc_ivas_fx( st, Aq, inp, /*ener_fx,*/ lsp_mid, lsp_new, lsf_new_fx, &allow_cn_step, sub( Q_new, 1 ), q_env_fx, &sid_bw ); - - /* comfort noise generation */ - CNG_exc_fx( st->core_brate, st->L_frame, &st->hTdCngEnc->Enew_fx, &st->hTdCngEnc->cng_seed, exc_fx, exc2_fx, &st->hTdCngEnc->lp_ener_fx, st->last_core_brate, - &st->hDtxEnc->first_CNG, &st->hTdCngEnc->cng_ener_seed, bwe_exc_fx, allow_cn_step, &st->hTdCngEnc->last_allow_cn_step, sub( st->prev_Q_new, 1 ), sub( Q_new, 1 ), st->hTdCngEnc->num_ho, - q_env_fx, st->hTdCngEnc->lp_env_fx, st->hTdCngEnc->old_env_fx, st->hTdCngEnc->exc_mem_fx, st->hTdCngEnc->exc_mem1_fx, &sid_bw, &st->hTdCngEnc->cng_ener_seed1, exc3_fx, st->Opt_AMR_WB, EVS_MONO ); - - Scale_sig( exc_fx, st->L_frame, 1 ); - } - ELSE - { - test(); - IF( EQ_32( st->core_brate, SID_2k40 ) && NE_16( st->element_mode, IVAS_CPE_MDCT ) ) - { - FdCng_encodeSID_ivas_fx( st ); - st->hDtxEnc->last_CNG_L_frame = st->L_frame; - move16(); - } - - Word16 Q_cngNoise = Q31, zero_flag = 0; - move16(); - move16(); - FOR( Word16 j = 0; j < NPART; j++ ) - { - IF( st->hFdCngEnc->hFdCngCom->cngNoiseLevel[j] != 0 ) - { - zero_flag = 1; - move16(); - BREAK; - } - } - IF( zero_flag ) - { - Q_cngNoise = getScaleFactor32( st->hFdCngEnc->hFdCngCom->cngNoiseLevel, NPART ); - } - Scale_sig32( st->hFdCngEnc->hFdCngCom->cngNoiseLevel, NPART, Q_cngNoise ); - st->hFdCngEnc->hFdCngCom->cngNoiseLevelExp = sub( st->hFdCngEnc->hFdCngCom->cngNoiseLevelExp, Q_cngNoise ); - move16(); - - generate_comfort_noise_enc_ivas_fx( st, Q_new, 1 ); - st->hTcxEnc->q_Txnq = Q_new; - move16(); - Scale_sig( st->hFdCngEnc->hFdCngCom->A_cng, ( M + 1 ), sub( Q12, sub( 14, norm_s( st->hFdCngEnc->hFdCngCom->A_cng[0] ) ) ) ); - FdCng_exc( st->hFdCngEnc->hFdCngCom, &st->hDtxEnc->CNG_mode, st->L_frame, st->lsp_old_fx, st->hDtxEnc->first_CNG, st->hDtxEnc->lspCNG_fx, Aq, lsp_new, lsf_new_fx, exc_fx, exc2_fx, bwe_exc_fx ); - Copy( exc2_fx, exc3_fx, st->L_frame ); - - IF( EQ_32( st->core_brate, SID_2k40 ) ) - { - IF( st->hTdCngEnc != NULL ) - { - Word16 enr, enr_index; - enr = cng_energy_ivas_fx( st->element_mode, st->bwidth, st->hDtxEnc->CNG_mode, st->hTdCngEnc->CNG_att_fx, exc_fx, st->L_frame, Q_new ); - - /* calculate the energy quantization index */ - enr_index = add( enr, 512 /* Q8(2.0) */ ); /* enr + 2.0 */ - enr_index = extract_l( L_shr( L_mult0( enr_index, STEP_SID_FX ), 12 + 8 ) ); /* Q0 (8+12-(8+12)) */ - - /* limit the energy quantization index */ - enr_index = s_min( enr_index, 127 ); - enr_index = s_max( enr_index, 0 ); - st->hTdCngEnc->old_enr_index = enr_index; - move16(); - } - } - } - - /* Reset HO counter in the first SID frame */ - if ( st->hTdCngEnc != NULL ) - { - st->hTdCngEnc->burst_ho_cnt = 0; - move16(); - } - - Scale_sig( st->hLPDmem->mem_syn, M, sub( st->Q_syn, st->hLPDmem->q_mem_syn ) ); // st->Q_syn - Scale_sig( st->hLPDmem->mem_syn1_fx, M, sub( st->Q_syn, st->hLPDmem->q_mem_syn ) ); // st->Q_syn - Scale_sig( st->hLPDmem->mem_syn2, M, sub( st->Q_syn, st->hLPDmem->q_mem_syn ) ); // st->Q_syn - Scale_sig( st->hLPDmem->mem_syn3, M, sub( st->Q_syn, st->hLPDmem->q_mem_syn ) ); // st->Q_syn - Scale_sig( st->hLPDmem->mem_syn_r, L_SYN_MEM, sub( st->Q_syn, st->hLPDmem->q_mem_syn ) ); // st->Q_syn - st->hLPDmem->mem_w0 = shl_sat( st->hLPDmem->mem_w0, sub( st->Q_syn, st->hLPDmem->q_mem_syn ) ); // st->Q_syn - move16(); - st->hLPDmem->q_mem_syn = st->Q_syn; - move16(); - - /* synthesis at 12.8kHz sampling rate */ - syn_12k8_fx( st->L_frame, Aq, exc3_fx, syn1_fx, hLPDmem->mem_syn3, 1, sub( Q_new, 1 ), st->Q_syn ); - - /* reset the encoder */ - CNG_reset_enc_fx( st, hLPDmem, pitch_buf, voice_factors_fx, 0 ); - - /* update st->mem_syn1_flt for ACELP core switching */ - Copy( hLPDmem->mem_syn3, hLPDmem->mem_syn1_fx, M ); - - /* update ACELP core synthesis filter memory */ - Copy( hLPDmem->mem_syn3, hLPDmem->mem_syn, M ); - - /* update old synthesis buffer - needed for ACELP internal sampling rate switching */ - Copy( syn1_fx + sub( st->L_frame, L_SYN_MEM ), hLPDmem->mem_syn_r, L_SYN_MEM ); - - /* save and delay synthesis to be used by SWB BWE */ - IF( st->hBWE_FD != NULL ) - { - st->hBWE_FD->mem_deemph_old_syn_fx = shl_sat( st->hBWE_FD->mem_deemph_old_syn_fx, sub( st->Q_syn, st->hBWE_FD->q_mem_deemph_old_syn ) ); - move16(); - Scale_sig( st->hBWE_FD->old_syn_12k8_16k_fx, NS2SA( 16000, DELAY_FD_BWE_ENC_NS ), sub( st->Q_syn, st->hBWE_FD->q_mem_deemph_old_syn ) ); - save_old_syn_fx( st->L_frame, syn1_fx, old_syn_12k8_16k, st->hBWE_FD->old_syn_12k8_16k_fx, st->preemph_fac, &st->hBWE_FD->mem_deemph_old_syn_fx ); - *q_old_syn_12k8_16 = st->Q_syn; - move16(); - st->hBWE_FD->q_mem_deemph_old_syn = st->Q_syn; - move16(); - } - - Scale_sig( st->hLPDmem->syn, M + 1, sub( st->Q_syn, st->hLPDmem->q_lpd_syn ) ); - st->hLPDmem->q_lpd_syn = st->Q_syn; - move16(); - - /*Update MODE2 core switching memory*/ - deemph_fx( syn1_fx, st->preemph_fac, st->L_frame, &( hLPDmem->syn[M] ) ); - Copy( syn1_fx + add( st->L_frame, -M - 1 ), hLPDmem->syn, M + 1 ); - } - - /*----------------------------------------------------------------* - * Encoding of all other frames - *----------------------------------------------------------------*/ - ELSE - { - - /*-----------------------------------------------------------------* - * Configure ACELP bit allocation - *-----------------------------------------------------------------*/ - - Word16 temp = getScaleFactor16( st->hGSCEnc->last_exc_dct_in_fx, L_FRAME16k ); - Scale_sig( st->hGSCEnc->last_exc_dct_in_fx, L_FRAME16k, temp ); - st->hGSCEnc->Q_last_exc_dct_in = add( st->hGSCEnc->Q_last_exc_dct_in, temp ); - move16(); - nb_bits = 0; - move16(); - st->acelp_cfg.FEC_mode = 0; - move16(); - uc_two_stage_flag = 0; - move16(); - - test(); - IF( !nelp_mode && !ppp_mode ) - { - config_acelp1_IVAS( ENC, st->total_brate, st->core_brate, st->core, st->extl, st->extl_brate, st->L_frame, st->GSC_noisy_speech, &( st->acelp_cfg ), hBstr->nb_bits_tot, st->coder_type, tc_subfr, 0, &nb_bits, unbits, st->element_mode, &uc_two_stage_flag, tdm_lp_reuse_flag, tdm_low_rate_mode, st->idchan, st->active_cnt, tdm_Pitch_reuse_flag, st->tdm_LRTD_flag, st->GSC_IVAS_mode ); - } - - /*-----------------------------------------------------------------* - * After inactive period, use the most up-to-date ISPs - *-----------------------------------------------------------------*/ - - test(); - test(); - IF( st->hDtxEnc != NULL && ( st->last_core_brate == FRAME_NO_DATA || EQ_32( st->last_core_brate, SID_2k40 ) ) ) - { - Copy( st->hDtxEnc->lspCNG_fx, st->lsp_old_fx, M ); // Q15 - lsp2lsf_fx( st->hDtxEnc->lspCNG_fx, st->lsf_old_fx, M, int_fs ); - } - - /*-----------------------------------------------------------------* - * Reset higher ACELP pre-quantizer in case of switching - *-----------------------------------------------------------------*/ - - IF( !st->use_acelp_preq ) - { - st->mem_deemp_preQ_fx = 0; - move16(); - st->last_code_preq = 0; - move16(); - st->last_nq_preQ = 0; - move16(); - } - st->use_acelp_preq = 0; - move16(); - - /*-----------------------------------------------------------------* - * LSF Quantization - * A[z] calculation - *-----------------------------------------------------------------*/ - - /* SC-VBR & channel-aware mode - back-up memories for LSF quantizer and synthesis filter */ - lsf_syn_mem_backup_ivas_fx( st, &tilt_code_bck_fx, &gc_threshold_bck_fx, clip_var_bck_fx, &next_force_sf_bck, lsp_new, lsp_mid, &clip_var_fx, mem_AR_fx, mem_MA_fx, lsp_new_bck_fx, lsp_mid_bck_fx, Bin_E_fx, Bin_E_old_fx, mem_syn_bck_fx, &mem_w0_bck_fx, &streaklimit_fx, &pstreaklen ); - - IF( !tdm_lp_reuse_flag ) - { - lsf_enc_ivas_fx( st, lsf_new_fx, lsp_new, lsp_mid, Aq, tdm_low_rate_mode, st->GSC_IVAS_mode, tdm_lsfQ_PCh, Q_new ); - } - ELSE - { - const Word16 *pt_interp_2_fx; - - IF( NE_16( st->active_cnt, 1 ) ) - { - Word16 beta_index; - Word16 lsf_wgts_fx[M]; - - /* intra_frame prediction for the LSFs */ - lsp2lsf_fx( lsp_new, lsf_new_fx, M, 12800 ); - - Unified_weighting_fx( &st->Bin_E_fx[L_FFT / 2], add( Q_new, ( QSCALE - 2 ) ), lsf_new_fx, lsf_wgts_fx, st->bwidth == NB, (Word16) EQ_16( st->coder_type, UNVOICED ), st->sr_core, M ); - - tdm_SCh_lsf_reuse_fx( ENC, st->element_brate, lsf_new_fx, lsp_new, tdm_lsfQ_PCh, lsf_wgts_fx, &beta_index ); - - push_indice( hBstr, IND_IC_LSF_PRED, beta_index, TDM_IC_LSF_PRED_BITS ); - } - - pt_interp_2_fx = interpol_frac_12k8_fx; - - test(); - if ( EQ_16( tdm_low_rate_mode, 1 ) && GT_16( st->coder_type, UNVOICED ) ) - { - pt_interp_2_fx = interpol_frac2_fx; - } - - IF( EQ_16( st->active_cnt, 1 ) ) - { - Copy( lsp_new, st->lsp_old_fx, M ); // Q15 - lsp2lsf_fx( lsp_new, st->lsf_old_fx, M, st->sr_core ); // Q x2.56 - lsp2lsf_fx( lsp_new, lsf_new_fx, M, st->sr_core ); // Q x2.56 - } - - /* LSP interpolation and conversion of LSPs to A(z) */ - int_lsp_fx( st->L_frame, st->lsp_old_fx, lsp_new, Aq, M, pt_interp_2_fx, 0 ); - - /* Check LSF stability (distance between old LSFs and current LSFs) */ - st->stab_fac_fx = lsf_stab_fx( lsf_new_fx, st->lsf_old_fx, 0, st->L_frame ); // Q15 - } - test(); - IF( EQ_16( st->last_core, HQ_CORE ) && st->element_mode > EVS_MONO ) - { - /* Prepare ACB memory from last HQ frame */ - tmpF_fx = hLPDmem->old_exc[0]; - PREEMPH_FX( hLPDmem->old_exc, st->preemph_fac, st->L_frame, &tmpF_fx ); - Copy( hLPDmem->old_exc + sub( st->L_frame, M ), hLPDmem->mem_syn, M ); - Residu3_fx( Aq, hLPDmem->old_exc, old_exc_fx, st->L_frame, 0 ); - } - - test(); - IF( st->last_core != ACELP_CORE && st->element_mode > EVS_MONO ) - { - /* Prepare ACB memory of old_bwe_exc */ - IF( EQ_16( st->L_frame, L_FRAME ) ) - { - lerp( old_exc_fx, old_bwe_exc_fx, L_EXC_MEM_DEC * HIBND_ACB_L_FAC, L_EXC_MEM_DEC ); - } - ELSE - { - lerp( old_exc_fx, old_bwe_exc_fx, L_EXC_MEM_DEC * 2, L_EXC_MEM_DEC ); - } - } - - /*---------------------------------------------------------------* - * Calculation of LP residual (filtering through A[z] filter) - *---------------------------------------------------------------*/ - - calc_residu_fx( st, inp, res_fx, Aq ); - calculate_hangover_attenuation_gain_ivas_fx( st, &att_fx, vad_hover_flag ); - - IF( NE_16( att_fx, 32767 /* ONE_IN_Q15 */ ) ) - { - v_multc_fixed_16_16( res_fx, att_fx, res_fx, st->L_frame ); - } - - /*-----------------------------------------------------------------* - * Determine TC subframe classification - *-----------------------------------------------------------------*/ - - IF( EQ_16( st->coder_type, TRANSITION ) ) - { - tc_classif_enc_fx( Q_new, st->L_frame, &tc_subfr, &position, attack_flag, st->pitch[0], res_fx ); - - config_acelp1_IVAS( ENC, st->total_brate, st->core_brate, st->core, st->extl, st->extl_brate, st->L_frame, -1, &( st->acelp_cfg ), hBstr->nb_bits_tot, st->coder_type, tc_subfr, 1, NULL, unbits, st->element_mode, &uc_two_stage_flag, tdm_lp_reuse_flag, tdm_low_rate_mode, st->idchan, st->active_cnt, tdm_Pitch_reuse_flag, st->tdm_LRTD_flag, st->GSC_IVAS_mode ); - } - - /*---------------------------------------------------------------* - * Calculation of prediction for scaled innovation energy - * (for memory-less gain quantizer) - *---------------------------------------------------------------*/ - - IF( nb_bits > 0 ) - { - Es_pred_enc_fx( &Es_pred_fx, &i, st->L_frame, res_fx, st->voicing_fx, nb_bits, uc_two_stage_flag, Q_new ); - push_indice( hBstr, IND_ES_PRED, i, nb_bits ); - } - - /*------------------------------------------------------------* - * Encode excitation according to coding type - *------------------------------------------------------------*/ - test(); - test(); - IF( tdm_low_rate_mode ) /* tdm stereo low rate mode */ - { - IF( LE_16( st->coder_type, UNVOICED ) ) - { - tdm_low_rate_enc( st, Aq, res_fx, syn_fx, exc_fx, pitch_buf, voice_factors_fx, bwe_exc_fx, 0 /*attack_flag*/, lsf_new_fx, &tmp_noise_fx, Q_new ); - } - ELSE /* GENERIC */ - { - encod_gen_2sbfr( st, inp, Aw, Aq, res_fx, syn_fx, exc_fx, exc2_fx, pitch_buf, voice_factors_fx, bwe_exc_fx, tdm_Pitch_reuse_flag, tdm_Pri_pitch_buf_fx, Q_new, 0 ); - } - } - ELSE IF( nelp_mode ) - { - /* SC-VBR - NELP frames */ - encod_nelp_ivas_fx( st, inp, Aw, Aq, res_fx, syn_fx, &tmp_noise_fx, exc_fx, exc2_fx, pitch_buf, voice_factors_fx, bwe_exc_fx, Q_new, 0 ); - } - - ELSE IF( EQ_16( st->coder_type, UNVOICED ) ) - { - /* UNVOICED frames (Gauss. excitation) */ - encod_unvoiced_ivas_fx( st, inp, Aw, Aq, Es_pred_fx, uc_two_stage_flag, res_fx, syn_fx, &tmp_noise_fx, exc_fx, pitch_buf, voice_factors_fx, bwe_exc_fx, Q_new, 0 ); - } - ELSE IF( EQ_16( st->coder_type, TRANSITION ) ) - { - encod_tran_ivas_fx( st, inp, Aw, Aq, Es_pred_fx, res_fx, syn_fx, exc_fx, exc2_fx, pitch_buf, voice_factors_fx, bwe_exc_fx, tc_subfr, position, unbits, 0, Q_new ); - } - ELSE IF( ppp_mode ) - { - /* SC-VBR - PPP frames */ - IF( ( error = encod_ppp_ivas_fx( st, inp, Aw, Aq, res_fx, syn_fx, exc_fx, exc2_fx, pitch_buf, voice_factors_fx, bwe_exc_fx, Q_new, 0 ) ) != IVAS_ERR_OK ) - { - return error; - } - - IF( st->hSC_VBR->bump_up ) /* PPP failed, bump up */ - { - /* restore memories of LSF quantizer and synthesis filter */ - lsf_syn_mem_restore_ivas_fx( st, tilt_code_bck_fx, gc_threshold_bck_fx, clip_var_bck_fx, next_force_sf_bck, lsp_new, lsp_mid, clip_var_fx, mem_AR_fx, mem_MA_fx, lsp_new_bck_fx, lsp_mid_bck_fx, Bin_E_fx, Bin_E_old_fx, mem_syn_bck_fx, mem_w0_bck_fx, streaklimit_fx, pstreaklen ); - /* Configure ACELP bit allocation */ - config_acelp1_IVAS( ENC, st->total_brate, st->core_brate, st->core, st->extl, st->extl_brate, st->L_frame, -1, &( st->acelp_cfg ), hBstr->nb_bits_tot, st->coder_type, tc_subfr, 0, &nb_bits, unbits, 0, &uc_two_stage_flag, 0, 0, st->idchan, st->active_cnt, tdm_Pitch_reuse_flag, st->tdm_LRTD_flag, st->GSC_IVAS_mode ); - - /* redo LSF quantization */ - lsf_enc_ivas_fx( st, lsf_new_fx, lsp_new, lsp_mid, Aq, tdm_low_rate_mode, 0, NULL, Q_new ); - - /* recalculation of LP residual (filtering through A[z] filter) */ - calc_residu_fx( st, inp, res_fx, Aq ); - st->hTdCngEnc->burst_ho_cnt = 0; - move16(); - /* VOICED frames in SC-VBR */ - encod_gen_voic_ivas_fx( st, inp, Aw, Aq, Es_pred_fx, res_fx, syn_fx, exc_fx, exc2_fx, pitch_buf, voice_factors_fx, bwe_exc_fx, unbits, tdm_Pitch_reuse_flag, tdm_Pri_pitch_buf_fx, 0, Q_new ); - } - } - ELSE IF( EQ_16( st->coder_type, AUDIO ) || ( EQ_16( st->coder_type, INACTIVE ) && st->inactive_coder_type_flag ) ) - { - /* AUDIO and INACTIVE frames (coded by GSC technology) */ - encod_audio_ivas_fx( st, inp, Aw, Aq, res_fx, syn_fx, exc_fx, pitch_buf, voice_factors_fx, bwe_exc_fx, attack_flag, lsf_new_fx, &tmp_noise_fx, tdm_Pitch_reuse_flag, tdm_Pri_pitch_buf_fx, Q_new, 0 ); - } - ELSE - { - /* GENERIC, VOICED and INACTIVE frames (coded by AVQ technology) */ - encod_gen_voic_ivas_fx( st, inp, Aw, Aq, Es_pred_fx, res_fx, syn_fx, exc_fx, exc2_fx, pitch_buf, voice_factors_fx, bwe_exc_fx, unbits, tdm_Pitch_reuse_flag, tdm_Pri_pitch_buf_fx, 0, Q_new ); - } - - FOR( i = 0; i < NB_SUBFR16k; i++ ) - { - Scale_sig( &Aq[i * ( M + 1 )], ( M + 1 ), sub( Q12, sub( Q14, norm_s( Aq[i * ( M + 1 )] ) ) ) ); // Q12 - } - - /* update mem_syn1_flt for ACELP core switching */ - Copy( hLPDmem->mem_syn, hLPDmem->mem_syn1_fx, M ); - - /* update old synthesis buffer - needed for ACELP internal sampling rate switching */ - Copy( syn_fx + sub( st->L_frame, L_SYN_MEM ), hLPDmem->mem_syn_r, L_SYN_MEM ); - - Scale_sig( syn_fx, L_FRAME16k, sub( st->Q_syn, Q_new - 1 ) ); - /* save and delay synthesis to be used by SWB BWE */ - IF( st->hBWE_FD != NULL ) - { - st->hBWE_FD->mem_deemph_old_syn_fx = shl_sat( st->hBWE_FD->mem_deemph_old_syn_fx, sub( s_min( st->Q_syn, st->hBWE_FD->q_mem_deemph_old_syn ), st->hBWE_FD->q_mem_deemph_old_syn ) ); - move16(); - Scale_sig( st->hBWE_FD->old_syn_12k8_16k_fx, NS2SA( 16000, DELAY_FD_BWE_ENC_NS ), sub( s_min( st->Q_syn, st->hBWE_FD->q_mem_deemph_old_syn ), st->hBWE_FD->q_mem_deemph_old_syn ) ); - - save_old_syn_fx( st->L_frame, syn_fx, old_syn_12k8_16k, st->hBWE_FD->old_syn_12k8_16k_fx, st->preemph_fac, &st->hBWE_FD->mem_deemph_old_syn_fx ); - *q_old_syn_12k8_16 = s_min( st->Q_syn, st->hBWE_FD->q_mem_deemph_old_syn ); - move16(); - st->hBWE_FD->q_mem_deemph_old_syn = s_min( st->Q_syn, st->hBWE_FD->q_mem_deemph_old_syn ); - move16(); - Scale_sig( syn_fx, st->L_frame, sub( st->Q_syn, s_min( st->Q_syn, st->hBWE_FD->q_mem_deemph_old_syn ) ) ); - } - - /*Update MODE2 core switching memory*/ - Copy( syn_fx, syn1_fx, st->L_frame ); - - Scale_sig( st->hLPDmem->syn, M + 1, sub( st->Q_syn, st->hLPDmem->q_lpd_syn ) ); - st->hLPDmem->q_lpd_syn = st->Q_syn; - move16(); - - /*Update MODE2 core switching memory*/ - deemph_fx( syn1_fx, st->preemph_fac, st->L_frame, &( hLPDmem->syn[M] ) ); - - Copy( syn1_fx + add( st->L_frame, -M - 1 ), hLPDmem->syn, M + 1 ); - - test(); - IF( st->element_mode > EVS_MONO && st->hTcxEnc != NULL ) - { - Copy( syn1_fx + shr( st->L_frame, 1 ), st->hTcxEnc->Txnq, shr( st->L_frame, 1 ) ); -#ifdef MSAN_FIX - Scale_sig( st->hTcxEnc->Txnq + shr( st->L_frame, 1 ), sub( L_FRAME32k / 2 + 64, shr( st->L_frame, 1 ) ), sub( st->Q_syn, st->hTcxEnc->q_Txnq ) ); -#else - Scale_sig( st->hTcxEnc->Txnq + shr( st->L_frame, 1 ), sub( L_FRAME32k / 2 + 64, shr( st->L_frame, 2 ) ), sub( st->Q_syn, st->hTcxEnc->q_Txnq ) ); -#endif - st->hTcxEnc->q_Txnq = st->Q_syn; - move16(); - } - - /*--------------------------------------------------------------------------------------* - * Modify the excitation signal when the noise is stationary - *--------------------------------------------------------------------------------------*/ - test(); - test(); - test(); - test(); - IF( !( EQ_16( st->idchan, 1 ) && EQ_16( st->element_mode, IVAS_CPE_TD ) ) && NE_16( nelp_mode, 1 ) && !( EQ_16( st->element_mode, IVAS_SCE ) && tdm_low_rate_mode ) ) - { - /* exc2 buffer is needed only for updating of Aq[] which is needed for core switching */ - Copy( exc_fx, exc2_fx, st->L_frame ); - - stat_noise_uv_enc_ivas_fx( st, epsP, lsp_new, lsp_mid, Aq, exc2_fx, uc_two_stage_flag, Q_new ); - } - - /*-----------------------------------------------------------------* - * Encode supplementary information for Frame Error Concealment - *-----------------------------------------------------------------*/ - - Scale_sig( syn_fx, L_FRAME, sub( s_min( st->Q_syn, Q_new ), st->Q_syn ) ); -#ifdef MSAN_FIX - Scale_sig( res_fx, st->L_frame, sub( s_min( st->Q_syn, Q_new ), Q_new ) ); -#else - Scale_sig( res_fx, L_FRAME16k, sub( s_min( st->Q_syn, Q_new ), Q_new ) ); -#endif - FEC_encode_ivas_fx( hBstr, st->acelp_cfg, syn_fx, st->coder_type, st->clas, pitch_buf, res_fx, &st->Last_pulse_pos, st->L_frame, st->total_brate, s_min( st->Q_syn, Q_new ) ); - IF( st->hBWE_TD != NULL ) - { - IF( EQ_16( st->L_frame, L_FRAME ) ) - { - Copy( Aq + 2 * ( M + 1 ), st->hBWE_TD->cur_sub_Aq_fx, ( M + 1 ) ); - } - ELSE - { - Copy( Aq + 3 * ( M + 1 ), st->hBWE_TD->cur_sub_Aq_fx, ( M + 1 ) ); - } - } - - - } /* end of active inp coding */ - - /*-----------------------------------------------------------------* - * Write ACELP unused bits - *-----------------------------------------------------------------*/ - test(); - test(); - IF( NE_32( st->core_brate, SID_2k40 ) && NE_32( st->core_brate, FRAME_NO_DATA ) && NE_32( st->core_brate, PPP_NELP_2k80 ) ) - { - nBits = st->acelp_cfg.ubits; - move16(); - WHILE( nBits > 0 ) - { - i = s_min( nBits, 16 ); - push_indice( hBstr, IND_UNUSED, 0, i ); - nBits = sub( nBits, i ); - } - } - - /*-----------------------------------------------------------------* - * Apply non linearity in case of SWB TBE - *-----------------------------------------------------------------*/ - - IF( st->hBWE_TD != NULL ) - { - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - IF( ( EQ_16( st->last_Opt_SC_VBR, 1 ) && st->Opt_SC_VBR == 0 ) || ( ( EQ_16( st->extl, SWB_TBE ) || EQ_16( st->extl, WB_TBE ) || EQ_16( st->extl, FB_TBE ) ) && NE_16( st->last_extl, SWB_TBE ) && NE_16( st->last_extl, WB_TBE ) && NE_16( st->last_extl, FB_TBE ) ) || ( EQ_16( st->idchan, 1 ) && EQ_16( st->element_mode, IVAS_CPE_TD ) && !st->tdm_LRTD_flag ) ) - { - st->hBWE_TD->bwe_non_lin_prev_scale_fx = 0; - move16(); - set16_fx( st->hBWE_TD->old_bwe_exc_extended_fx, 0, NL_BUFF_OFFSET ); - } - - test(); - test(); - test(); - test(); - test(); - test(); - IF( !st->Opt_SC_VBR && ( st->idchan == 0 || NE_16( st->element_mode, IVAS_CPE_TD ) || ( EQ_16( st->idchan, 1 ) && EQ_16( st->element_mode, IVAS_CPE_TD ) && st->tdm_LRTD_flag ) ) ) - { - /* Apply a non linearity to the SHB excitation */ - Copy_Scale_sig_16_32( st->hBWE_TD->old_bwe_exc_extended_fx, bwe_exc_extended_fx, NL_BUFF_OFFSET, ( sub( shl( Q_new, 1 ), sub( st->prev_Q_bwe_exc, 16 ) ) ) ); // prev_Q_bwe_exc - non_linearity_ivas_fx( bwe_exc_fx, bwe_exc_extended_fx + NL_BUFF_OFFSET, L_FRAME32k, &st->hBWE_TD->bwe_non_lin_prev_scale_fx, Q_new, st->coder_type, voice_factors_fx, st->L_frame ); - Copy_Scale_sig_32_16( bwe_exc_extended_fx + L_FRAME32k, st->hBWE_TD->old_bwe_exc_extended_fx, NL_BUFF_OFFSET, negate( sub( shl( Q_new, 1 ), sub( st->prev_Q_bwe_exc, 16 ) ) ) ); // prev_Q_bwe_exc - } - - test(); - if ( EQ_32( st->core_brate, SID_2k40 ) || EQ_32( st->core_brate, FRAME_NO_DATA ) ) - { - st->hBWE_TD->bwe_non_lin_prev_scale_fx = 0; - move16(); - } - } - - /*-----------------------------------------------------------------* - * Updates - *-----------------------------------------------------------------*/ - - IF( st->hBWE_TD != NULL ) - { - st->Q_exc = Q_new; - move16(); - } - - updt_enc_fx( st, old_exc_fx, pitch_buf, Es_pred_fx, Aq, lsf_new_fx, lsp_new, old_bwe_exc_fx ); - st->hLPDmem->q_lpd_old_exc = Q_new; - move16(); - - test(); - test(); - IF( st->hTdCngEnc != NULL && st->Opt_DTX_ON && GT_32( st->core_brate, SID_2k40 ) ) - { - /* update CNG parameters in active frames */ - Word16 q_exc = st->hTdCngEnc->cng_Qexc_buf[0]; - move16(); - FOR( Word16 ii = 0; ii < HO_HIST_SIZE; ii++ ) - { - q_exc = s_min( q_exc, st->hTdCngEnc->cng_Qexc_buf[ii] ); - } - q_exc = s_min( q_exc, Q_new ); - - Scale_sig( exc_fx, L_EXC - L_EXC_MEM, sub( q_exc, Q_new ) ); - FOR( Word16 ii = 0; ii < HO_HIST_SIZE; ii++ ) - { - Scale_sig( st->hTdCngEnc->cng_exc2_buf + ii * L_FFT, L_FFT, sub( q_exc, st->hTdCngEnc->cng_Qexc_buf[ii] ) ); - st->hTdCngEnc->cng_Qexc_buf[ii] = q_exc; - move16(); - } - cng_params_upd_ivas_fx( lsp_new, exc_fx, st->L_frame, &st->hTdCngEnc->ho_circ_ptr, st->hTdCngEnc->ho_ener_circ_fx, - &st->hTdCngEnc->ho_circ_size, st->hTdCngEnc->ho_lsp_circ_fx, q_exc, ENC, st->hTdCngEnc->ho_env_circ_fx, &st->hTdCngEnc->cng_buf_cnt, - st->hTdCngEnc->cng_exc2_buf, st->hTdCngEnc->cng_Qexc_buf, st->hTdCngEnc->cng_brate_buf, st->hDtxEnc->last_active_brate, st->element_mode, - st->hFdCngEnc->hFdCngCom->CngBandwidth ); - - IF( EQ_16( st->L_frame, L_FRAME ) ) - { - /* store LSPs@16k, potentially to be used in CNG@16k */ - Copy( st->lsp_old16k_fx, &( st->hTdCngEnc->ho_lsp_circ2_fx[( st->hTdCngEnc->ho_circ_ptr ) * M] ), M ); - } - - /* set LSP@16k flag for the first buffer */ - IF( EQ_16( st->L_frame, L_FRAME ) ) - { - st->hTdCngEnc->ho_16k_lsp[st->hTdCngEnc->ho_circ_ptr] = 0; - } - ELSE - { - st->hTdCngEnc->ho_16k_lsp[st->hTdCngEnc->ho_circ_ptr] = 1; - } - move16(); - /* efficient DTX hangover control */ - IF( GT_16( st->hTdCngEnc->burst_ho_cnt, 1 ) ) - { - dtx_hangover_control_fx( st, lsp_new ); - } - } - - /* SC-VBR update of average data rate */ - IF( EQ_16( st->vad_flag, 1 ) ) - { - /* reset in case of bitrate switching in EVS */ - if ( st->hSC_VBR != NULL ) - { - update_average_rate_fx( st->hSC_VBR, st->core_brate ); - } - } - pop_wmops(); - - return error; -} diff --git a/lib_enc/acelp_core_enc_fx.c b/lib_enc/acelp_core_enc_fx.c index 66e34e2a58b614dace296d7eaea7ec8ceb7cc31b..7820061089f45aa3855e68c6f776f249a735f7a5 100644 --- a/lib_enc/acelp_core_enc_fx.c +++ b/lib_enc/acelp_core_enc_fx.c @@ -9,41 +9,38 @@ #include "prot_fx.h" #include "stat_enc.h" #include "rom_com.h" -#include "rom_enc.h" /* Encoder static table prototypes */ -#include "rom_com_fx.h" /* Static table prototypes */ -//#include "prot_fx.h" /* Function prototypes */ +#include "rom_enc.h" /* Encoder static table prototypes */ +#include "rom_com_fx.h" /* Static table prototypes */ #include "prot_fx_enc.h" /* Function prototypes */ +#include "ivas_cnst.h" +#include "ivas_prot_fx.h" /*-------------------------------------------------------------------* - * acelp_core_enc() + * acelp_core_enc_fx() * * ACELP core encoder *--------------------------------------------------------------------*/ ivas_error acelp_core_enc_fx( Encoder_State *st_fx, /* i/o: encoder state structure */ - const Word16 inp_fx[], /* i : input signal of the current frame */ - const Word32 ener_fx, /* i : residual energy from Levinson-Durbin*/ - Word16 A_fx[NB_SUBFR16k * ( M + 1 )], /* i : A(z) unquantized for the 4 subframes*/ - Word16 Aw_fx[NB_SUBFR16k * ( M + 1 )], /* i : weighted A(z) unquant. for subframes*/ - const Word16 epsP_h_fx[M + 1], /* i : LP prediction errors */ - const Word16 epsP_l_fx[M + 1], /* i : LP prediction errors */ - Word16 lsp_new_fx[M], /* i : LSPs at the end of the frame */ - Word16 lsp_mid_fx[M], /* i : LSPs in the middle of the frame */ - Word16 vad_hover_flag_fx, /* i : VAD hangover flag */ - const Word16 attack_flag, /* i : attack flag (GSC or TC) */ - Word32 bwe_exc_extended_fx[], /* i/o: bandwidth extended excitation */ - Word16 *voice_factors_fx, /* o : voicing factors */ - Word16 old_syn_12k8_16k_fx[], /* o : intermediate ACELP synthesis at 12.8kHz or 16kHz to be used by SWB BWE */ - Word16 pitch_buf_fx[NB_SUBFR16k], /* o : floating pitch for each subframe */ - Word16 *unbits_fx, /* o : number of unused bits */ + const Word16 inp_fx[], /* i : input signal of the current frame Q_new*/ + const Word32 ener_fx, /* i : residual energy from Levinson-Durbin Q6*/ + Word16 A_fx[NB_SUBFR16k * ( M + 1 )], /* i : A(z) unquantized for the 4 subframes Q12*/ + Word16 Aw_fx[NB_SUBFR16k * ( M + 1 )], /* i : weighted A(z) unquant. for subframes Q12*/ + const Word16 epsP_h_fx[M + 1], /* i : LP prediction errors Qx*/ + const Word16 epsP_l_fx[M + 1], /* i : LP prediction errors Qx*/ + Word16 lsp_new_fx[M], /* i : LSPs at the end of the frame Q15*/ + Word16 lsp_mid_fx[M], /* i : LSPs in the middle of the frame Q15*/ + Word16 vad_hover_flag_fx, /* i : VAD hangover flag Q0*/ + const Word16 attack_flag, /* i : attack flag (GSC or TC) Q0*/ + Word32 bwe_exc_extended_fx[], /* i/o: bandwidth extended excitation st->prev_Q_bwe_exc*/ + Word16 *voice_factors_fx, /* o : voicing factors Q15*/ + Word16 old_syn_12k8_16k_fx[], /* o : intermediate ACELP synthesis at 12.8kHz or 16kHz to be used by SWB BWE q_old_syn*/ + Word16 pitch_buf_fx[NB_SUBFR16k], /* o : floating pitch for each subframe Q6*/ + Word16 *unbits_fx, /* o : number of unused bits Q0*/ + STEREO_TD_ENC_DATA_HANDLE hStereoTD, /* i/o: TD stereo encoder handle */ + const float tdm_lsfQ_PCh[M], /* i : Q LSFs for primary channel */ const Word16 Q_new, - const Word16 shift -#ifdef ADD_LRTD - , - STEREO_TD_ENC_DATA_HANDLE hStereoTD, /* i/o: TD stereo encoder handle */ - const float tdm_lsfQ_PCh[M] /* i : Q LSFs for primary channel */ -#endif -) + const Word16 shift ) { Word16 nBits; /* reserved bits */ Word16 i; @@ -86,6 +83,7 @@ ivas_error acelp_core_enc_fx( Word16 *tdm_Pri_pitch_buf; Word16 uc_two_stage_flag; Word16 att; + move16(); SC_VBR_ENC_HANDLE hSC_VBR = st_fx->hSC_VBR; DTX_ENC_HANDLE hDtxEnc = st_fx->hDtxEnc; @@ -109,18 +107,21 @@ ivas_error acelp_core_enc_fx( * Initialization *------------------------------------------------------------------*/ + (void) tdm_lsfQ_PCh; + Es_pred_fx = 0; move16(); coder_type = st_fx->coder_type; + move16(); - exc_fx = old_exc_fx + L_EXC_MEM; /* pointer to excitation signal in the current frame */ - Copy( hLPDmem->old_exc, old_exc_fx, L_EXC_MEM ); + exc_fx = old_exc_fx + L_EXC_MEM; /* pointer to excitation signal in the current frame */ + Copy( hLPDmem->old_exc, old_exc_fx, L_EXC_MEM ); // q_lpd_old_exc IF( hBWE_TD != NULL ) { - bwe_exc_fx = old_bwe_exc_fx + PIT16k_MAX * 2; /* pointer to BWE excitation signal in the current frame */ - Copy( hBWE_TD->old_bwe_exc_fx, old_bwe_exc_fx, PIT16k_MAX * 2 ); + bwe_exc_fx = old_bwe_exc_fx + PIT16k_MAX * 2; /* pointer to BWE excitation signal in the current frame */ + Copy( hBWE_TD->old_bwe_exc_fx, old_bwe_exc_fx, PIT16k_MAX * 2 ); // Q_exc } ELSE { @@ -151,7 +152,8 @@ ivas_error acelp_core_enc_fx( st_fx->Nb_ACELP_frames = 0; move16(); } - st_fx->Nb_ACELP_frames = add( st_fx->Nb_ACELP_frames, 1 ); + st_fx->Nb_ACELP_frames = add_sat( st_fx->Nb_ACELP_frames, 1 ); // Q0 + move16(); int_fs_fx = INT_FS_16k_FX; move16(); @@ -200,16 +202,14 @@ ivas_error acelp_core_enc_fx( /* TD stereo */ test(); -#ifdef ADD_LRTD IF( EQ_16( st_fx->element_mode, IVAS_CPE_TD ) && EQ_16( st_fx->idchan, 1 ) ) { tdm_lp_reuse_flag = hStereoTD->tdm_lp_reuse_flag; tdm_low_rate_mode = hStereoTD->tdm_low_rate_mode; tdm_Pitch_reuse_flag = hStereoTD->tdm_Pitch_reuse_flag; - tdm_Pri_pitch_buf = hStereoTD->tdm_Pri_pitch_buf; + tdm_Pri_pitch_buf = hStereoTD->tdm_Pri_pitch_buf_fx; } ELSE -#endif { tdm_lp_reuse_flag = 0; tdm_low_rate_mode = 0; @@ -242,13 +242,14 @@ ivas_error acelp_core_enc_fx( /* convert old quantized LSP vector */ IF( EQ_16( st_fx->L_frame, L_FRAME ) ) { - st_fx->rate_switching_reset = lsp_convert_poly_fx( st_fx->lsp_old_fx, st_fx->L_frame, 0 ); + st_fx->rate_switching_reset = lsp_convert_poly_fx( st_fx->lsp_old_fx, st_fx->L_frame, 0 ); // Q0 + move16(); } ELSE { - st_fx->rate_switching_reset = st_fx->rate_switching_reset_16kHz; + st_fx->rate_switching_reset = st_fx->rate_switching_reset_16kHz; // Q0 move16(); - Copy( st_fx->lsp_old16k_fx, st_fx->lsp_old_fx, M ); + Copy( st_fx->lsp_old16k_fx, st_fx->lsp_old_fx, M ); // Q15 } /* convert old quantized LSF vector */ @@ -266,14 +267,14 @@ ivas_error acelp_core_enc_fx( } /* Reset LPC mem */ - Copy( GEWB_Ave_fx, st_fx->mem_AR_fx, M ); + Copy( GEWB_Ave_fx, st_fx->mem_AR_fx, M ); // x2.56 set16_fx( st_fx->mem_MA_fx, 0, M ); /* update synthesis filter memories */ synth_mem_updt2( st_fx->L_frame, st_fx->last_L_frame, hLPDmem->old_exc, hLPDmem->mem_syn_r, hLPDmem->mem_syn2, hLPDmem->mem_syn, ENC ); - Copy( hLPDmem->old_exc, old_exc_fx, L_EXC_MEM ); - Copy( hLPDmem->mem_syn2, hLPDmem->mem_syn1_fx, M ); - Copy( hLPDmem->mem_syn2, hLPDmem->mem_syn3, M ); + Copy( hLPDmem->old_exc, old_exc_fx, L_EXC_MEM ); // q_lpd_old_exc + Copy( hLPDmem->mem_syn2, hLPDmem->mem_syn1_fx, M ); // q_mem_syn + Copy( hLPDmem->mem_syn2, hLPDmem->mem_syn3, M ); // q_mem_syn /* update Aw[] coefficients */ weight_a_subfr_fx( shr( st_fx->L_frame, 6 ), A_fx, Aw_fx, st_fx->gamma, M ); @@ -320,24 +321,23 @@ ivas_error acelp_core_enc_fx( FdCng_exc( st_fx->hFdCngEnc->hFdCngCom, &hDtxEnc->CNG_mode, st_fx->L_frame, st_fx->lsp_old_fx, hDtxEnc->first_CNG, hDtxEnc->lspCNG_fx, Aq_fx, lsp_new_fx, lsf_new_fx, exc_fx, exc2_fx, bwe_exc_fx ); - Copy( exc2_fx, exc3_fx, st_fx->L_frame ); + Copy( exc2_fx, exc3_fx, st_fx->L_frame ); // Q12 IF( EQ_32( st_fx->core_brate, SID_2k40 ) ) { IF( hTdCngEnc != NULL ) { - /*IVAS_CODE CNG_att is missing */ - enr = cng_energy_fx( st_fx->element_mode, st_fx->bwidth, hDtxEnc->CNG_mode, /*st_fx->hTdCngEnc->CNG_att*/ 0, exc_fx, st_fx->L_frame, Q_new ); + enr = cng_energy_fx( st_fx->element_mode, st_fx->bwidth, hDtxEnc->CNG_mode, /*st_fx->hTdCngEnc->CNG_att*/ 0, exc_fx, st_fx->L_frame, Q_new ); // Q8 /* calculate the energy quantization index */ enr_index = add( enr, 512 /* Q8(2.0) */ ); /* enr + 2.0 */ enr_index = extract_l( L_shr( L_mult0( enr_index, STEP_SID_FX ), 12 + 8 ) ); /* Q0 (8+12-(8+12)) */ /* limit the energy quantization index */ - enr_index = s_min( enr_index, 127 ); + enr_index = s_min( enr_index, 127 ); // Q0 enr_index = s_max( enr_index, 0 ); - hTdCngEnc->old_enr_index = enr_index; + hTdCngEnc->old_enr_index = enr_index; /* Q0 */ move16(); } } @@ -361,7 +361,7 @@ ivas_error acelp_core_enc_fx( Copy( hLPDmem->mem_syn3, hLPDmem->mem_syn, M ); /* update old synthesis buffer - needed for ACELP internal sampling rate switching */ - Copy( syn1_fx + st_fx->L_frame - L_SYN_MEM, hLPDmem->mem_syn_r, L_SYN_MEM ); + Copy( syn1_fx + st_fx->L_frame - L_SYN_MEM, hLPDmem->mem_syn_r, L_SYN_MEM ); /* st_fx->Q_syn */ IF( hBWE_FD != NULL ) { @@ -372,7 +372,7 @@ ivas_error acelp_core_enc_fx( tmp16 = hLPDmem->syn[M]; move16(); E_UTIL_deemph2( sub( Q_new, 1 ), syn1_fx, st_fx->preemph_fac, st_fx->L_frame, &tmp16 ); - Copy( syn1_fx + st_fx->L_frame - M - 1, hLPDmem->syn, M + 1 ); + Copy( syn1_fx + st_fx->L_frame - M - 1, hLPDmem->syn, M + 1 ); /* st_fx->Q_syn */ } /*----------------------------------------------------------------* @@ -395,7 +395,11 @@ ivas_error acelp_core_enc_fx( IF( !nelp_mode && !ppp_mode ) { config_acelp1( ENC, st_fx->total_brate, st_fx->core_brate, st_fx->core, st_fx->extl, st_fx->extl_brate, +#ifdef NONBE_FIX_GSC_BSTR + st_fx->L_frame, st_fx->GSC_noisy_speech, &( st_fx->acelp_cfg ), hBstr->nb_bits_tot, st_fx->coder_type, st_fx->inactive_coder_type_flag, +#else st_fx->L_frame, st_fx->GSC_noisy_speech, &( st_fx->acelp_cfg ), hBstr->nb_bits_tot, st_fx->coder_type, +#endif tc_subfr_fx, 0, &nb_bits, unbits_fx, st_fx->element_mode, &uc_two_stage_flag, tdm_lp_reuse_flag, tdm_low_rate_mode, st_fx->idchan, st_fx->active_fr_cnt_fx, tdm_Pitch_reuse_flag, st_fx->tdm_LRTD_flag, st_fx->GSC_IVAS_mode ); } @@ -408,7 +412,7 @@ ivas_error acelp_core_enc_fx( test(); IF( st_fx->hDtxEnc != NULL && ( st_fx->last_core_brate == FRAME_NO_DATA || EQ_32( st_fx->last_core_brate, SID_2k40 ) ) ) { - Copy( hDtxEnc->lspCNG_fx, st_fx->lsp_old_fx, M ); + Copy( hDtxEnc->lspCNG_fx, st_fx->lsp_old_fx, M ); // Q15 lsp2lsf_fx( hDtxEnc->lspCNG_fx, st_fx->lsf_old_fx, M, int_fs_fx ); } @@ -442,78 +446,8 @@ ivas_error acelp_core_enc_fx( if ( !tdm_lp_reuse_flag ) { -#ifdef LSF_RE_USE_SECONDARY_CHANNEL - lsf_enc_fx( st_fx, lsf_new_fx, lsp_new_fx, lsp_mid_fx, Aq_fx, st_fx->Nb_ACELP_frames, tdm_low_rate_mode, st_fx->GSC_IVAS_mode, tdm_lsfQ_PCh, Q_new ); -#else lsf_enc_fx( st_fx, lsf_new_fx, lsp_new_fx, lsp_mid_fx, Aq_fx, st_fx->Nb_ACELP_frames, tdm_low_rate_mode, st_fx->GSC_IVAS_mode, Q_new ); -#endif - } -#ifdef ADD_LRTD - else - { - const float *pt_interp_2; -#ifdef LSF_RE_USE_SECONDARY_CHANNEL - if ( st->active_cnt != 1 ) - { - int16_t beta_index; - float lsf_wgts[M]; - - /* intra_frame prediction for the LSFs */ - lsp2lsf( lsp_new, lsf_new, M, 12800 ); - - Unified_weighting( &st->Bin_E[L_FFT / 2], lsf_new, lsf_wgts, st->bwidth == NB, st->coder_type == UNVOICED, st->sr_core, M ); - - tdm_SCh_lsf_reuse( ENC, st->element_brate, lsf_new, lsp_new, tdm_lsfQ_PCh, lsf_wgts, &beta_index ); - - push_indice( hBstr, IND_IC_LSF_PRED, beta_index, TDM_IC_LSF_PRED_BITS ); - } -#endif - pt_interp_2 = interpol_frac_12k8; - if ( tdm_low_rate_mode == 1 && st->coder_type > UNVOICED ) - { - pt_interp_2 = interpol_frac2; - } -#ifndef LSF_RE_USE_SECONDARY_CHANNEL - if ( st->active_cnt == 1 ) - { - mvr2r( lsp_new, st->lsp_old, M ); - lsp2lsf( lsp_new, st->lsf_old, M, st->sr_core ); - lsp2lsf( lsp_new, lsf_new, M, st->sr_core ); - } -#endif - /* LSP interpolation and conversion of LSPs to A(z) */ - int_lsp( st->L_frame, st->lsp_old, lsp_new, Aq, M, pt_interp_2, 0 ); - - /* Check LSF stability (distance between old LSFs and current LSFs) */ - st->stab_fac = lsf_stab( lsf_new, st->lsf_old, 0, st->L_frame ); - } - if ( st->last_core == HQ_CORE && st->element_mode > EVS_MONO ) - { - /* Prepare ACB memory from last HQ frame */ - tmpF = hLPDmem->old_exc[0]; - preemph( hLPDmem->old_exc, st->preemph_fac, st->L_frame, &tmpF ); - mvr2r( hLPDmem->old_exc + st->L_frame - M, hLPDmem->mem_syn, M ); - residu( Aq, M, hLPDmem->old_exc, old_exc, st->L_frame ); - } - - if ( st->last_core != ACELP_CORE && st->element_mode > EVS_MONO ) - { - /* Prepare ACB memory of old_bwe_exc */ -#ifdef CR_FIX_639_HQ_ACELP_TRANSITION - if ( st->L_frame == L_FRAME ) - { - lerp( old_exc, old_bwe_exc, L_EXC_MEM_DEC * HIBND_ACB_L_FAC, L_EXC_MEM_DEC ); - } - else - { - lerp( old_exc, old_bwe_exc, L_EXC_MEM_DEC * 2, L_EXC_MEM_DEC ); - } -#else - lerp( old_exc, old_bwe_exc, L_EXC_MEM_DEC * HIBND_ACB_L_FAC, L_EXC_MEM_DEC ); -#endif } -#endif - /*---------------------------------------------------------------* * Calculation of LP residual (filtering through A[z] filter) @@ -531,7 +465,11 @@ ivas_error acelp_core_enc_fx( tc_classif_enc_fx( Q_new, st_fx->L_frame, &tc_subfr_fx, &position, attack_flag, st_fx->pitch[0], res_fx ); config_acelp1( ENC, st_fx->total_brate, st_fx->core_brate, st_fx->core, st_fx->extl, st_fx->extl_brate, st_fx->L_frame, +#ifdef NONBE_FIX_GSC_BSTR + -1, &( st_fx->acelp_cfg ), hBstr->nb_bits_tot, TRANSITION, -1, tc_subfr_fx, 1, NULL, unbits_fx, st_fx->element_mode, &uc_two_stage_flag, +#else -1, &( st_fx->acelp_cfg ), hBstr->nb_bits_tot, st_fx->coder_type, tc_subfr_fx, 1, NULL, unbits_fx, st_fx->element_mode, &uc_two_stage_flag, +#endif tdm_lp_reuse_flag, tdm_low_rate_mode, st_fx->idchan, st_fx->active_fr_cnt_fx, tdm_Pitch_reuse_flag, st_fx->tdm_LRTD_flag, st_fx->GSC_IVAS_mode ); } @@ -551,26 +489,12 @@ ivas_error acelp_core_enc_fx( *------------------------------------------------------------*/ test(); test(); -#ifdef ADD_LRTD - if ( tdm_low_rate_mode ) /* tdm stereo low rate mode */ + IF( hSC_VBR->nelp_mode ) { - if ( st->coder_type <= UNVOICED ) - { - tdm_low_rate_enc( st, Aq, res, syn, exc, pitch_buf, voice_factors, bwe_exc, 0 /*attack_flag*/, lsf_new, &tmp_noise ); - } - else /* GENERIC */ - { - encod_gen_2sbfr( st, inp, Aw, Aq, res, syn, exc, exc2, pitch_buf, voice_factors, bwe_exc, tdm_Pitch_reuse_flag, tdm_Pri_pitch_buf ); - } + /* SC-VBR - NELP frames */ + encod_nelp_fx( st_fx, inp_fx, Aw_fx, Aq_fx, res_fx, syn_fx, &tmp_noise_fx, exc_fx, exc2_fx, pitch_buf_fx, + voice_factors_fx, bwe_exc_fx, Q_new, shift ); } - else -#endif - IF( hSC_VBR->nelp_mode ) - { - /* SC-VBR - NELP frames */ - encod_nelp_fx( st_fx, inp_fx, Aw_fx, Aq_fx, res_fx, syn_fx, &tmp_noise_fx, exc_fx, exc2_fx, pitch_buf_fx, - voice_factors_fx, bwe_exc_fx, Q_new, shift ); - } ELSE IF( EQ_16( coder_type, UNVOICED ) ) { /* UNVOICED frames (Gauss. excitation) */ @@ -580,8 +504,7 @@ ivas_error acelp_core_enc_fx( ELSE IF( EQ_16( coder_type, TRANSITION ) ) { tc_subfr_fx = encod_tran_fx( st_fx, inp_fx, Aw_fx, Aq_fx, Es_pred_fx, res_fx, syn_fx, - exc_fx, exc2_fx, pitch_buf_fx, voice_factors_fx, bwe_exc_fx, tc_subfr_fx, position, unbits_fx, shift, Q_new ); - move16(); + exc_fx, exc2_fx, pitch_buf_fx, voice_factors_fx, bwe_exc_fx, tc_subfr_fx, position, unbits_fx, shift, Q_new ); /* Q0 */ } ELSE IF( hSC_VBR->ppp_mode ) { @@ -599,15 +522,16 @@ ivas_error acelp_core_enc_fx( /* Configure ACELP bit allocation */ config_acelp1( ENC, st_fx->total_brate, st_fx->core_brate, st_fx->core, st_fx->extl, st_fx->extl_brate, st_fx->L_frame, +#ifdef NONBE_FIX_GSC_BSTR + -1, &( st_fx->acelp_cfg ), hBstr->nb_bits_tot, st_fx->coder_type, st_fx->inactive_coder_type_flag, tc_subfr_fx, 0, &nb_bits, unbits_fx, 0, &uc_two_stage_flag, 0, 0, +#else -1, &( st_fx->acelp_cfg ), hBstr->nb_bits_tot, st_fx->coder_type, tc_subfr_fx, 0, &nb_bits, unbits_fx, 0, &uc_two_stage_flag, 0, 0, +#endif st_fx->idchan, st_fx->active_fr_cnt_fx, tdm_Pitch_reuse_flag, st_fx->tdm_LRTD_flag, st_fx->GSC_IVAS_mode ); /* redo LSF quantization */ -#ifdef LSF_RE_USE_SECONDARY_CHANNEL - lsf_enc_fx( st_fx, lsf_new_fx, lsp_new_fx, lsp_mid_fx, Aq_fx, st_fx->Nb_ACELP_frames, tdm_low_rate_mode, st_fx->GSC_IVAS_mode, tdm_lsfQ_PCh, Q_new ); -#else lsf_enc_fx( st_fx, lsf_new_fx, lsp_new_fx, lsp_mid_fx, Aq_fx, st_fx->Nb_ACELP_frames, tdm_low_rate_mode, st_fx->GSC_IVAS_mode, Q_new ); -#endif + /* recalculation of LP residual (filtering through A[z] filter) */ calc_residu_fx( st_fx, inp_fx, res_fx, Aq_fx ); @@ -632,7 +556,7 @@ ivas_error acelp_core_enc_fx( } /* update st->mem_syn1 for ACELP core switching */ - Copy( hLPDmem->mem_syn, hLPDmem->mem_syn1_fx, M ); + Copy( hLPDmem->mem_syn, hLPDmem->mem_syn1_fx, M ); /* q_mem_syn */ /* update old synthesis buffer - needed for ACELP internal sampling rate switching */ Copy( syn_fx + st_fx->L_frame - L_SYN_MEM, hLPDmem->mem_syn_r, L_SYN_MEM ); @@ -643,25 +567,31 @@ ivas_error acelp_core_enc_fx( save_old_syn_fx( st_fx->L_frame, syn_fx, old_syn_12k8_16k_fx, hBWE_FD->old_syn_12k8_16k_fx, st_fx->preemph_fac, &hBWE_FD->mem_deemph_old_syn_fx ); } /*Update MODE2 core switching memory*/ - Copy( syn_fx, syn1_fx, st_fx->L_frame ); + Copy( syn_fx, syn1_fx, st_fx->L_frame ); // Q_syn E_UTIL_deemph2( sub( Q_new, 1 ), syn1_fx, st_fx->preemph_fac, st_fx->L_frame, &hLPDmem->syn[M] ); - Copy( syn1_fx + st_fx->L_frame - M - 1, hLPDmem->syn, M + 1 ); - IF( GT_16( st_fx->element_mode, EVS_MONO ) && st_fx->hTcxEnc != NULL ) + Copy( syn1_fx + st_fx->L_frame - M - 1, hLPDmem->syn, M + 1 ); // Q_syn + + test(); + IF( st_fx->element_mode > EVS_MONO && st_fx->hTcxEnc != NULL ) { - Copy( syn1_fx + st_fx->L_frame / 2, st_fx->hTcxEnc->Txnq, st_fx->L_frame / 2 ); + Copy( syn1_fx + st_fx->L_frame / 2, st_fx->hTcxEnc->Txnq, st_fx->L_frame / 2 ); // Q_syn } /*--------------------------------------------------------------------------------------* * Modify the excitation signal when the noise is stationary *--------------------------------------------------------------------------------------*/ + test(); + test(); + test(); + test(); IF( !( EQ_16( st_fx->idchan, 1 ) && EQ_16( st_fx->element_mode, IVAS_CPE_TD ) ) && NE_16( nelp_mode, 1 ) && !( EQ_16( st_fx->element_mode, IVAS_SCE ) && tdm_low_rate_mode ) ) { L_epsP[0] = L_Comp( epsP_h_fx[2], epsP_l_fx[2] ); move32(); L_epsP[1] = L_Comp( epsP_h_fx[M], epsP_l_fx[M] ); move32(); - Copy( exc_fx, exc2_fx, st_fx->L_frame ); + Copy( exc_fx, exc2_fx, st_fx->L_frame ); // Q_new stat_noise_uv_enc_fx( st_fx, L_epsP, lsp_new_fx, lsp_mid_fx, Aq_fx, exc2_fx, uc_two_stage_flag, Q_new ); } @@ -677,11 +607,11 @@ ivas_error acelp_core_enc_fx( { IF( EQ_16( st_fx->L_frame, L_FRAME ) ) { - Copy( Aq_fx + 2 * ( M + 1 ), hBWE_TD->cur_sub_Aq_fx, ( M + 1 ) ); + Copy( Aq_fx + 2 * ( M + 1 ), hBWE_TD->cur_sub_Aq_fx, ( M + 1 ) ); // Q12 } ELSE { - Copy( Aq_fx + 3 * ( M + 1 ), hBWE_TD->cur_sub_Aq_fx, ( M + 1 ) ); + Copy( Aq_fx + 3 * ( M + 1 ), hBWE_TD->cur_sub_Aq_fx, ( M + 1 ) ); // Q12 } } } /* end of active inp coding */ @@ -695,13 +625,14 @@ ivas_error acelp_core_enc_fx( IF( NE_32( st_fx->core_brate, SID_2k40 ) && NE_32( st_fx->core_brate, FRAME_NO_DATA ) && NE_32( st_fx->core_brate, PPP_NELP_2k80 ) ) { /* reserved bits */ - nBits = st_fx->acelp_cfg.ubits; + nBits = st_fx->acelp_cfg.ubits; // Q0 + move16(); WHILE( nBits > 0 ) { - i = s_min( nBits, 16 ); + i = s_min( nBits, 16 ); // Q0 push_indice_fx( st_fx->hBstr, IND_UNUSED, 0, i ); - nBits = sub( nBits, i ); + nBits = sub( nBits, i ); // Q0 } } @@ -742,6 +673,7 @@ ivas_error acelp_core_enc_fx( *-----------------------------------------------------------------*/ updt_enc_fx( st_fx, old_exc_fx, pitch_buf_fx, Es_pred_fx, Aq_fx, lsf_new_fx, lsp_new_fx, old_bwe_exc_fx ); + test(); test(); IF( hTdCngEnc != NULL && ( st_fx->Opt_DTX_ON != 0 ) && ( GT_32( st_fx->core_brate, SID_2k40 ) ) ) { @@ -753,7 +685,7 @@ ivas_error acelp_core_enc_fx( IF( EQ_16( st_fx->L_frame, L_FRAME ) ) { /* store LSPs@16k, potentially to be used in CNG@16k */ - Copy( st_fx->lsp_old16k_fx, &( hTdCngEnc->ho_lsp_circ2_fx[( hTdCngEnc->ho_circ_ptr ) * M] ), M ); + Copy( st_fx->lsp_old16k_fx, &( hTdCngEnc->ho_lsp_circ2_fx[( hTdCngEnc->ho_circ_ptr ) * M] ), M ); // Q15 } /* Set 16k LSP flag for CNG buffer */ @@ -773,6 +705,7 @@ ivas_error acelp_core_enc_fx( } /* SC-VBR update of average data rate */ + test(); IF( EQ_16( st_fx->vad_flag, 1 ) && ( hSC_VBR != NULL ) ) { update_average_rate_fx( hSC_VBR, st_fx->core_brate ); @@ -780,3 +713,941 @@ ivas_error acelp_core_enc_fx( return error; } + +/*-------------------------------------------------------------------* + * acelp_core_enc_ivas_fx() + * + * ACELP core encoder + *--------------------------------------------------------------------*/ +ivas_error acelp_core_enc_ivas_fx( + Encoder_State *st, /* i/o: encoder state structure */ + const Word16 inp[], /* i : input signal of the current frame Q_new*/ + Word16 A[NB_SUBFR16k * ( M + 1 )], /* i : A(z) unquantized for the 4 subframes Q12*/ + Word16 Aw[NB_SUBFR16k * ( M + 1 )], /* i : weighted A(z) unquant. for subframes Q12*/ + const Word32 epsP[M + 1], /* i : LP prediction errors Qx*/ + Word16 lsp_new[M], /* i : LSPs at the end of the frame Q15*/ + Word16 lsp_mid[M], /* i : LSPs in the middle of the frame Q15*/ + const Word16 vad_hover_flag, /* i : VAD hangover flag Q0*/ + const Word16 attack_flag, /* i : attack flag (GSC or TC) Q0*/ + Word32 bwe_exc_extended_fx[], /* i/o: bandwidth extended excitation st->prev_Q_bwe_exc*/ + Word16 *voice_factors_fx, /* o : voicing factors Q15*/ + Word16 old_syn_12k8_16k[], /* o : intermediate ACELP synthesis at 12.8kHz or 16kHz to be used by SWB BWE q_old_syn_12k8_16*/ + Word16 *q_old_syn_12k8_16, + Word16 pitch_buf[NB_SUBFR16k], /* o : floating pitch for each subframe Q6*/ + Word16 *unbits, /* o : number of unused bits Q0*/ + STEREO_TD_ENC_DATA_HANDLE hStereoTD, /* i/o: TD stereo encoder handle */ + Word16 tdm_lsfQ_PCh[M], /* i : Q LSFs for primary channel X2.56*/ + Word16 Q_new ) +{ + Word16 i, nBits; /* reserved bits */ + LPD_state_HANDLE hLPDmem; /* i/o: acelp memories */ + Word16 tc_subfr; /* TC sub-frame indication */ + Word16 allow_cn_step; + Word32 int_fs; + Word16 nb_bits; /* parameters handling */ + + /* SC-VBR - back-up memories for LSF quantizer and synthesis filter */ + Word16 pstreaklen; + Word16 sid_bw = -1; + move16(); + Word16 next_force_sf_bck; + Word16 uc_two_stage_flag; + Word16 position; + Word16 ppp_mode, nelp_mode; + Word16 tdm_lp_reuse_flag, tdm_low_rate_mode, tdm_Pitch_reuse_flag; + + /* bitstream */ + BSTR_ENC_HANDLE hBstr = st->hBstr; + Word16 old_exc_fx[L_EXC], *exc_fx; /* excitation signal buffer */ + Word16 lsf_new_fx[M]; /* ISFs at the end of the frame */ + Word16 Aq[NB_SUBFR16k * ( M + 1 )]; /* A(z) quantized for the 4 subframes */ + Word16 syn_fx[L_FRAME16k]; /* synthesis vector */ + Word16 res_fx[L_FRAME16k]; /* Residual signal for FER protection */ + Word16 exc2_fx[L_FRAME16k]; /* enhanced excitation */ + Word16 Es_pred_fx; /* predicited scaled innovation energy */ + Word16 tmp_noise_fx; /* NB post-filter long-term noise energy*/ + Word16 old_bwe_exc_fx[( PIT16k_MAX + ( L_FRAME16k + 1 ) + L_SUBFR16k ) * 2]; /* excitation buffer Q_new */ + Word16 *bwe_exc_fx; /* excitation for SWB TBE Q_new */ + Word16 mem_MA_fx[M], mem_AR_fx[M], lsp_new_bck_fx[M], /*lsf_new_bck_fx[M],*/ lsp_mid_bck_fx[M], mem_syn_bck_fx[M]; + Word32 Bin_E_fx[L_FFT], Bin_E_old_fx[L_FFT / 2]; + Word16 clip_var_fx, mem_w0_bck_fx, streaklimit_fx; + +#ifdef MSAN_FIX + set16_fx( old_bwe_exc_fx, 0, ( PIT16k_MAX + ( L_FRAME16k + 1 ) + L_SUBFR16k ) * 2 ); + set16_fx( old_exc_fx, 0, L_EXC ); + set16_fx( Aq, 0, NB_SUBFR16k * ( M + 1 ) ); + set16_fx( syn_fx, 0, L_FRAME16k ); +#endif + + Word16 tilt_code_bck_fx; + Word32 gc_threshold_bck_fx; + Word16 clip_var_bck_fx[6]; + Word32 q_env_fx[NUM_ENV_CNG]; +#ifdef MSAN_FIX + set32_fx( q_env_fx, 0, NUM_ENV_CNG ); + set16_fx( exc2_fx, 0, L_FRAME16k ); +#endif + Word16 exc3_fx[L_FRAME16k]; + Word16 syn1_fx[L_FRAME16k]; + Word16 *tdm_Pri_pitch_buf_fx; + + Word16 att_fx; + Word16 tmpF_fx; + + test(); + IF( !st->Opt_AMR_WB && st->hBWE_TD != NULL ) + { + Scale_sig( st->hBWE_TD->old_bwe_exc_fx, PIT16k_MAX * 2, sub( Q_new, st->prev_Q_new ) ); // Q_new + } + IF( st->hLPDmem ) + { + Scale_sig( st->hLPDmem->old_exc, L_EXC_MEM, sub( Q_new, st->hLPDmem->q_lpd_old_exc ) ); // Q_new + st->hLPDmem->q_lpd_old_exc = Q_new; + move16(); + Scale_sig( st->hLPDmem->syn, M + 1, sub( Q_new, st->hLPDmem->q_lpd_syn ) ); // Q_new + st->hLPDmem->q_lpd_syn = Q_new; + move16(); + Scale_sig( st->hLPDmem->mem_syn, M, sub( sub( Q_new, 1 ), st->hLPDmem->q_mem_syn ) ); // Q_new -1 + Scale_sig( st->hLPDmem->mem_syn1_fx, M, sub( sub( Q_new, 1 ), st->hLPDmem->q_mem_syn ) ); // Q_new -1 + Scale_sig( st->hLPDmem->mem_syn2, M, sub( sub( Q_new, 1 ), st->hLPDmem->q_mem_syn ) ); // Q_new -1 + Scale_sig( st->hLPDmem->mem_syn3, M, sub( sub( Q_new, 1 ), st->hLPDmem->q_mem_syn ) ); // Q_new -1 + Scale_sig( st->hLPDmem->mem_syn_r, L_SYN_MEM, sub( sub( Q_new, 1 ), st->hLPDmem->q_mem_syn ) ); // Q_new -1 + st->hLPDmem->mem_w0 = shl_sat( st->hLPDmem->mem_w0, sub( sub( Q_new, 1 ), st->hLPDmem->q_mem_syn ) ); // Q_new -1 + move16(); + st->hLPDmem->q_mem_syn = sub( Q_new, 1 ); + move16(); + } + + Scale_sig32( st->Bin_E_old_fx, L_FFT / 2, sub( add( Q_new, Q_SCALE - 2 ), st->q_Bin_E_old ) ); // Q_new + Q_scale - 2 + st->q_Bin_E_old = add( Q_new, Q_SCALE - 2 ); + move16(); + Scale_sig32( st->Bin_E_fx, L_FFT, sub( add( Q_new, Q_SCALE - 2 ), st->q_Bin_E ) ); // Q_new + Q_scale - 2 + st->q_Bin_E = add( Q_new, Q_SCALE - 2 ); + move16(); + + ivas_error error; + + error = IVAS_ERR_OK; + move32(); + + test(); + IF( EQ_16( st->element_mode, IVAS_CPE_MDCT ) && LE_32( st->core_brate, SID_2k40 ) ) + { + /* Core was ACELP because of DTX in MDCT-Stereo, but SID encoding for that is done in separate function */ + return error; + } + + push_wmops( "acelp_core_enc" ); + /*------------------------------------------------------------------* + * Initialization + *------------------------------------------------------------------*/ + + hLPDmem = st->hLPDmem; + + Es_pred_fx = 0; + move16(); + + exc_fx = old_exc_fx + L_EXC_MEM; /* pointer to excitation signal in the current frame */ + Copy( hLPDmem->old_exc, old_exc_fx, L_EXC_MEM ); /* Q_new */ + Scale_sig( old_exc_fx, L_EXC_MEM, sub( Q_new, hLPDmem->q_lpd_old_exc ) ); // Q_new + IF( st->hBWE_TD != NULL ) + { + bwe_exc_fx = old_bwe_exc_fx + PIT16k_MAX * 2; /* pointer to BWE excitation signal in the current frame */ + Copy( st->hBWE_TD->old_bwe_exc_fx, old_bwe_exc_fx, PIT16k_MAX * 2 ); // Q_new + } + ELSE + { + bwe_exc_fx = NULL; + } + + st->bpf_off = 0; + move16(); + + test(); + test(); + test(); + IF( EQ_16( st->last_core, HQ_CORE ) || EQ_16( st->last_codec_mode, MODE2 ) || EQ_16( st->last_core, TCX_20_CORE ) || EQ_16( st->last_core, TCX_10_CORE ) ) + { + /* in case of HQ->ACELP switching, do not apply BPF */ + st->bpf_off = 1; + move16(); + /* reset the GSC pre echo energy threshold in case of switching */ + if ( st->hGSCEnc != NULL ) + { + st->hGSCEnc->Last_frame_ener_fx = MAX_32; + move32(); + } + } + + /* force safety-net LSFQ in the first frames after CNG segment */ + if ( LE_32( st->last_core_brate, SID_2k40 ) ) + { + st->Nb_ACELP_frames = 0; + move16(); + } + st->Nb_ACELP_frames = add_sat( st->Nb_ACELP_frames, 1 ); + move16(); + + IF( EQ_16( st->L_frame, L_FRAME ) ) + { + int_fs = INT_FS_12k8; + move32(); + } + ELSE + { + int_fs = INT_FS_16k; + move32(); + } + + tmp_noise_fx = 0; + move16(); + tc_subfr = -1; + move16(); + position = -1; + move16(); + + /* SC-VBR temporary variables */ + pstreaklen = 0; + move16(); + clip_var_fx = 0; + move16(); + mem_w0_bck_fx = 0; + move16(); + streaklimit_fx = 0; + move16(); + + /* channel-aware mode */ + reset_rf_indices_fx( st ); + + /* VBR modes */ + IF( st->Opt_SC_VBR ) + { + ppp_mode = st->hSC_VBR->ppp_mode; + nelp_mode = st->hSC_VBR->nelp_mode; + } + ELSE + { + ppp_mode = 0; + nelp_mode = 0; + } + move16(); + move16(); + + test(); + /* TD stereo */ + + IF( EQ_16( st->element_mode, IVAS_CPE_TD ) && EQ_16( st->idchan, 1 ) ) + { + tdm_lp_reuse_flag = hStereoTD->tdm_lp_reuse_flag; // Q0 + tdm_low_rate_mode = hStereoTD->tdm_low_rate_mode; // Q0 + tdm_Pitch_reuse_flag = hStereoTD->tdm_Pitch_reuse_flag; // Q0 + tdm_Pri_pitch_buf_fx = hStereoTD->tdm_Pri_pitch_buf_fx; // Q6 + move16(); + move16(); + move16(); + } + ELSE + { + tdm_lp_reuse_flag = 0; + tdm_low_rate_mode = 0; + move16(); + move16(); + + test(); + if ( EQ_16( st->element_mode, IVAS_SCE ) && st->low_rate_mode ) + { + tdm_low_rate_mode = 1; + move16(); + } + tdm_Pitch_reuse_flag = 0; + move16(); + tdm_Pri_pitch_buf_fx = NULL; + } + + /*-----------------------------------------------------------------* + * ACELP@12k8 / ACELP@16k switching + *-----------------------------------------------------------------*/ + + test(); + test(); + IF( NE_16( st->last_L_frame, st->L_frame ) && ( st->last_core == ACELP_CORE || EQ_16( st->last_core, AMR_WB_CORE ) ) ) + { + /* in case of switching, do not apply BPF (flag employed also in updt_enc()) */ + st->bpf_off = 1; + move16(); + + /* force safety-net LSFQ in the first frames after ACELP@12k8/ACELP@16k switching */ + st->Nb_ACELP_frames = 1; + move16(); + + /* convert old quantized LSP vector */ + IF( EQ_16( st->L_frame, L_FRAME ) ) + { + st->rate_switching_reset = lsp_convert_poly_fx( st->lsp_old_fx, st->L_frame, 0 ); // Q0 + move16(); + } + ELSE + { + st->rate_switching_reset = st->rate_switching_reset_16kHz; // Q0 + move16(); + Copy( st->lsp_old16k_fx, st->lsp_old_fx, M ); // Q15 + } + + /* convert old quantized LSF vector */ + lsp2lsf_fx( st->lsp_old_fx, st->lsf_old_fx, M, int_fs ); + + /* interpolation of unquantized ISPs */ + IF( st->rate_switching_reset ) + { + /*extrapolation in case of unstable LSP*/ + int_lsp4_ivas_fx( st->L_frame, lsp_mid, lsp_mid, lsp_new, A, M, 0 ); + } + ELSE + { + int_lsp4_ivas_fx( st->L_frame, st->lsp_old_fx, lsp_mid, lsp_new, A, M, 0 ); + } + + /* Reset LPC mem */ + Copy( GEWB_Ave_fx, st->mem_AR_fx, M ); // Q2.56 + set16_fx( st->mem_MA_fx, 0, M ); + + /* update synthesis filter memories */ + synth_mem_updt2( st->L_frame, st->last_L_frame, hLPDmem->old_exc, hLPDmem->mem_syn_r, hLPDmem->mem_syn2, hLPDmem->mem_syn, ENC ); + Copy( hLPDmem->old_exc, old_exc_fx, L_EXC_MEM ); // Q_new + Copy( hLPDmem->mem_syn2, hLPDmem->mem_syn1_fx, M ); /* hLPDmem->q_mem_syn */ + Copy( hLPDmem->mem_syn2, hLPDmem->mem_syn3, M ); /* hLPDmem->q_mem_syn */ + + /* update Aw[] coefficients */ + weight_a_subfr_fx( shr( st->L_frame, 6 ), A, Aw, st->gamma, M ); + } + + test(); + test(); + if ( st->last_bwidth == NB && st->bwidth != NB && st->ini_frame != 0 ) + { + st->rate_switching_reset = 1; + move16(); + } + + /*----------------------------------------------------------------* + * Encoding of CNG frames + *----------------------------------------------------------------*/ + test(); + IF( EQ_32( st->core_brate, SID_2k40 ) || st->core_brate == FRAME_NO_DATA ) + { + IF( st->cng_type == LP_CNG ) + { + /* Run CNG post parameter update */ + cng_params_postupd_ivas_fx( st->hTdCngEnc->ho_circ_ptr, &st->hTdCngEnc->cng_buf_cnt, st->hTdCngEnc->cng_exc2_buf, st->hTdCngEnc->cng_Qexc_buf, st->hTdCngEnc->cng_brate_buf, st->hTdCngEnc->ho_env_circ_fx, st->element_mode, st->hFdCngEnc->hFdCngCom->CngBandwidth ); + + /* encode CNG parameters */ + CNG_enc_ivas_fx( st, Aq, inp, /*ener_fx,*/ lsp_mid, lsp_new, lsf_new_fx, &allow_cn_step, sub( Q_new, 1 ), q_env_fx, &sid_bw ); + + /* comfort noise generation */ + CNG_exc_fx( st->core_brate, st->L_frame, &st->hTdCngEnc->Enew_fx, &st->hTdCngEnc->cng_seed, exc_fx, exc2_fx, &st->hTdCngEnc->lp_ener_fx, st->last_core_brate, + &st->hDtxEnc->first_CNG, &st->hTdCngEnc->cng_ener_seed, bwe_exc_fx, allow_cn_step, &st->hTdCngEnc->last_allow_cn_step, sub( st->prev_Q_new, 1 ), sub( Q_new, 1 ), st->hTdCngEnc->num_ho, + q_env_fx, st->hTdCngEnc->lp_env_fx, st->hTdCngEnc->old_env_fx, st->hTdCngEnc->exc_mem_fx, st->hTdCngEnc->exc_mem1_fx, &sid_bw, &st->hTdCngEnc->cng_ener_seed1, exc3_fx, st->Opt_AMR_WB, EVS_MONO ); + + Scale_sig( exc_fx, st->L_frame, 1 ); // Q_new + 1 + } + ELSE + { + test(); + IF( EQ_32( st->core_brate, SID_2k40 ) && NE_16( st->element_mode, IVAS_CPE_MDCT ) ) + { + FdCng_encodeSID_ivas_fx( st ); + st->hDtxEnc->last_CNG_L_frame = st->L_frame; + move16(); + } + + Word16 Q_cngNoise = Q31, zero_flag = 0; + move16(); + move16(); + FOR( Word16 j = 0; j < NPART; j++ ) + { + IF( st->hFdCngEnc->hFdCngCom->cngNoiseLevel[j] != 0 ) + { + zero_flag = 1; + move16(); + BREAK; + } + } + IF( zero_flag ) + { + Q_cngNoise = getScaleFactor32( st->hFdCngEnc->hFdCngCom->cngNoiseLevel, NPART ); + } + Scale_sig32( st->hFdCngEnc->hFdCngCom->cngNoiseLevel, NPART, Q_cngNoise ); /* st->hFdCngEnc->hFdCngCom->cngNoiseLevelExp - Q_cngNoise */ + st->hFdCngEnc->hFdCngCom->cngNoiseLevelExp = sub( st->hFdCngEnc->hFdCngCom->cngNoiseLevelExp, Q_cngNoise ); + move16(); + + generate_comfort_noise_enc_ivas_fx( st, Q_new, 1 ); + st->hTcxEnc->q_Txnq = Q_new; + move16(); + Scale_sig( st->hFdCngEnc->hFdCngCom->A_cng, ( M + 1 ), sub( Q12, sub( 14, norm_s( st->hFdCngEnc->hFdCngCom->A_cng[0] ) ) ) ); /* Q12 */ + FdCng_exc( st->hFdCngEnc->hFdCngCom, &st->hDtxEnc->CNG_mode, st->L_frame, st->lsp_old_fx, st->hDtxEnc->first_CNG, st->hDtxEnc->lspCNG_fx, Aq, lsp_new, lsf_new_fx, exc_fx, exc2_fx, bwe_exc_fx ); + Copy( exc2_fx, exc3_fx, st->L_frame ); // Q_new + + IF( EQ_32( st->core_brate, SID_2k40 ) ) + { + IF( st->hTdCngEnc != NULL ) + { + Word16 enr, enr_index; + enr = cng_energy_ivas_fx( st->element_mode, st->bwidth, st->hDtxEnc->CNG_mode, st->hTdCngEnc->CNG_att_fx, exc_fx, st->L_frame, Q_new ); /* Q8 */ + + /* calculate the energy quantization index */ + enr_index = add( enr, 512 /* Q8(2.0) */ ); /* enr + 2.0 */ + enr_index = extract_l( L_shr( L_mult0( enr_index, STEP_SID_FX ), 12 + 8 ) ); /* Q0 (8+12-(8+12)) */ + + /* limit the energy quantization index */ + enr_index = s_min( enr_index, 127 ); /* Q0 */ + enr_index = s_max( enr_index, 0 ); + st->hTdCngEnc->old_enr_index = enr_index; /* Q0 */ + move16(); + } + } + } + + /* Reset HO counter in the first SID frame */ + if ( st->hTdCngEnc != NULL ) + { + st->hTdCngEnc->burst_ho_cnt = 0; + move16(); + } + + Scale_sig( st->hLPDmem->mem_syn, M, sub( st->Q_syn, st->hLPDmem->q_mem_syn ) ); // st->Q_syn + Scale_sig( st->hLPDmem->mem_syn1_fx, M, sub( st->Q_syn, st->hLPDmem->q_mem_syn ) ); // st->Q_syn + Scale_sig( st->hLPDmem->mem_syn2, M, sub( st->Q_syn, st->hLPDmem->q_mem_syn ) ); // st->Q_syn + Scale_sig( st->hLPDmem->mem_syn3, M, sub( st->Q_syn, st->hLPDmem->q_mem_syn ) ); // st->Q_syn + Scale_sig( st->hLPDmem->mem_syn_r, L_SYN_MEM, sub( st->Q_syn, st->hLPDmem->q_mem_syn ) ); // st->Q_syn + st->hLPDmem->mem_w0 = shl_sat( st->hLPDmem->mem_w0, sub( st->Q_syn, st->hLPDmem->q_mem_syn ) ); // st->Q_syn + move16(); + st->hLPDmem->q_mem_syn = st->Q_syn; + move16(); + + /* synthesis at 12.8kHz sampling rate */ + syn_12k8_fx( st->L_frame, Aq, exc3_fx, syn1_fx, hLPDmem->mem_syn3, 1, sub( Q_new, 1 ), st->Q_syn ); + + /* reset the encoder */ + CNG_reset_enc_fx( st, hLPDmem, pitch_buf, voice_factors_fx, 0 ); + + /* update st->mem_syn1_flt for ACELP core switching */ + Copy( hLPDmem->mem_syn3, hLPDmem->mem_syn1_fx, M ); /* hLPDmem->q_mem_syn */ + + /* update ACELP core synthesis filter memory */ + Copy( hLPDmem->mem_syn3, hLPDmem->mem_syn, M ); /* hLPDmem->q_mem_syn */ + + /* update old synthesis buffer - needed for ACELP internal sampling rate switching */ + Copy( syn1_fx + sub( st->L_frame, L_SYN_MEM ), hLPDmem->mem_syn_r, L_SYN_MEM ); // st->Q_syn + + /* save and delay synthesis to be used by SWB BWE */ + IF( st->hBWE_FD != NULL ) + { + st->hBWE_FD->mem_deemph_old_syn_fx = shl_sat( st->hBWE_FD->mem_deemph_old_syn_fx, sub( st->Q_syn, st->hBWE_FD->q_mem_deemph_old_syn ) ); /* st->Q_syn */ + move16(); + Scale_sig( st->hBWE_FD->old_syn_12k8_16k_fx, NS2SA( 16000, DELAY_FD_BWE_ENC_NS ), sub( st->Q_syn, st->hBWE_FD->q_mem_deemph_old_syn ) ); /* st->Q_syn */ + save_old_syn_fx( st->L_frame, syn1_fx, old_syn_12k8_16k, st->hBWE_FD->old_syn_12k8_16k_fx, st->preemph_fac, &st->hBWE_FD->mem_deemph_old_syn_fx ); + *q_old_syn_12k8_16 = st->Q_syn; + move16(); + st->hBWE_FD->q_mem_deemph_old_syn = st->Q_syn; + move16(); + } + + Scale_sig( st->hLPDmem->syn, M + 1, sub( st->Q_syn, st->hLPDmem->q_lpd_syn ) ); /* st->Q_syn */ + st->hLPDmem->q_lpd_syn = st->Q_syn; + move16(); + + /*Update MODE2 core switching memory*/ + deemph_fx( syn1_fx, st->preemph_fac, st->L_frame, &( hLPDmem->syn[M] ) ); + Copy( syn1_fx + add( st->L_frame, -M - 1 ), hLPDmem->syn, M + 1 ); /* st->Q_syn */ + } + + /*----------------------------------------------------------------* + * Encoding of all other frames + *----------------------------------------------------------------*/ + ELSE + { + + /*-----------------------------------------------------------------* + * Configure ACELP bit allocation + *-----------------------------------------------------------------*/ + + Word16 temp = getScaleFactor16( st->hGSCEnc->last_exc_dct_in_fx, L_FRAME16k ); + Scale_sig( st->hGSCEnc->last_exc_dct_in_fx, L_FRAME16k, temp ); /* Q_last_exc_dct_in + temp */ + st->hGSCEnc->Q_last_exc_dct_in = add( st->hGSCEnc->Q_last_exc_dct_in, temp ); + move16(); + nb_bits = 0; + move16(); + st->acelp_cfg.FEC_mode = 0; + move16(); + uc_two_stage_flag = 0; + move16(); + + test(); + IF( !nelp_mode && !ppp_mode ) + { +#ifdef NONBE_FIX_GSC_BSTR + config_acelp1_IVAS( ENC, st->total_brate, st->core_brate, st->core, st->extl, st->extl_brate, st->L_frame, st->GSC_noisy_speech, &( st->acelp_cfg ), hBstr->nb_bits_tot, st->coder_type, st->inactive_coder_type_flag, tc_subfr, 0, &nb_bits, unbits, st->element_mode, &uc_two_stage_flag, tdm_lp_reuse_flag, tdm_low_rate_mode, st->idchan, st->active_cnt, tdm_Pitch_reuse_flag, st->tdm_LRTD_flag, st->GSC_IVAS_mode ); +#else + config_acelp1_IVAS( ENC, st->total_brate, st->core_brate, st->core, st->extl, st->extl_brate, st->L_frame, st->GSC_noisy_speech, &( st->acelp_cfg ), hBstr->nb_bits_tot, st->coder_type, tc_subfr, 0, &nb_bits, unbits, st->element_mode, &uc_two_stage_flag, tdm_lp_reuse_flag, tdm_low_rate_mode, st->idchan, st->active_cnt, tdm_Pitch_reuse_flag, st->tdm_LRTD_flag, st->GSC_IVAS_mode ); +#endif + } + + /*-----------------------------------------------------------------* + * After inactive period, use the most up-to-date ISPs + *-----------------------------------------------------------------*/ + + test(); + test(); + IF( st->hDtxEnc != NULL && ( st->last_core_brate == FRAME_NO_DATA || EQ_32( st->last_core_brate, SID_2k40 ) ) ) + { + Copy( st->hDtxEnc->lspCNG_fx, st->lsp_old_fx, M ); // Q15 + lsp2lsf_fx( st->hDtxEnc->lspCNG_fx, st->lsf_old_fx, M, int_fs ); + } + + /*-----------------------------------------------------------------* + * Reset higher ACELP pre-quantizer in case of switching + *-----------------------------------------------------------------*/ + + IF( !st->use_acelp_preq ) + { + st->mem_deemp_preQ_fx = 0; + move16(); + st->mem_preemp_preQ_fx = 0; + move16(); + st->last_code_preq = 0; + move16(); + st->last_nq_preQ = 0; + move16(); + } + st->use_acelp_preq = 0; + move16(); + + /*-----------------------------------------------------------------* + * LSF Quantization + * A[z] calculation + *-----------------------------------------------------------------*/ + + /* SC-VBR & channel-aware mode - back-up memories for LSF quantizer and synthesis filter */ + lsf_syn_mem_backup_ivas_fx( st, &tilt_code_bck_fx, &gc_threshold_bck_fx, clip_var_bck_fx, &next_force_sf_bck, lsp_new, lsp_mid, &clip_var_fx, mem_AR_fx, mem_MA_fx, lsp_new_bck_fx, lsp_mid_bck_fx, Bin_E_fx, Bin_E_old_fx, mem_syn_bck_fx, &mem_w0_bck_fx, &streaklimit_fx, &pstreaklen ); + + IF( !tdm_lp_reuse_flag ) + { + lsf_enc_ivas_fx( st, lsf_new_fx, lsp_new, lsp_mid, Aq, tdm_low_rate_mode, st->GSC_IVAS_mode, tdm_lsfQ_PCh, Q_new ); + } + ELSE + { + const Word16 *pt_interp_2_fx; + + IF( NE_16( st->active_cnt, 1 ) ) + { + Word16 beta_index; + Word16 lsf_wgts_fx[M]; + + /* intra_frame prediction for the LSFs */ + lsp2lsf_fx( lsp_new, lsf_new_fx, M, 12800 ); + + Unified_weighting_fx( &st->Bin_E_fx[L_FFT / 2], add( Q_new, ( QSCALE - 2 ) ), lsf_new_fx, lsf_wgts_fx, st->bwidth == NB, (Word16) EQ_16( st->coder_type, UNVOICED ), st->sr_core, M ); + + tdm_SCh_lsf_reuse_fx( ENC, st->element_brate, lsf_new_fx, lsp_new, tdm_lsfQ_PCh, lsf_wgts_fx, &beta_index ); + + push_indice( hBstr, IND_IC_LSF_PRED, beta_index, TDM_IC_LSF_PRED_BITS ); + } + + pt_interp_2_fx = interpol_frac_12k8_fx; + + test(); + if ( EQ_16( tdm_low_rate_mode, 1 ) && GT_16( st->coder_type, UNVOICED ) ) + { + pt_interp_2_fx = interpol_frac2_fx; // Q15 + } + + IF( EQ_16( st->active_cnt, 1 ) ) + { + Copy( lsp_new, st->lsp_old_fx, M ); // Q15 + lsp2lsf_fx( lsp_new, st->lsf_old_fx, M, st->sr_core ); // Q x2.56 + lsp2lsf_fx( lsp_new, lsf_new_fx, M, st->sr_core ); // Q x2.56 + } + + /* LSP interpolation and conversion of LSPs to A(z) */ + int_lsp_fx( st->L_frame, st->lsp_old_fx, lsp_new, Aq, M, pt_interp_2_fx, 0 ); + + /* Check LSF stability (distance between old LSFs and current LSFs) */ + st->stab_fac_fx = lsf_stab_fx( lsf_new_fx, st->lsf_old_fx, 0, st->L_frame ); // Q15 + move16(); + } + test(); + IF( EQ_16( st->last_core, HQ_CORE ) && st->element_mode > EVS_MONO ) + { + /* Prepare ACB memory from last HQ frame */ + tmpF_fx = hLPDmem->old_exc[0]; + move16(); + PREEMPH_FX( hLPDmem->old_exc, st->preemph_fac, st->L_frame, &tmpF_fx ); + Copy( hLPDmem->old_exc + sub( st->L_frame, M ), hLPDmem->mem_syn, M ); /* Q_new */ + Scale_sig( st->hLPDmem->mem_syn, M, sub( st->hLPDmem->q_mem_syn, Q_new ) ); + Residu3_fx( Aq, hLPDmem->old_exc, old_exc_fx, st->L_frame, 0 ); + } + + test(); + IF( st->last_core != ACELP_CORE && st->element_mode > EVS_MONO ) + { + /* Prepare ACB memory of old_bwe_exc */ + IF( EQ_16( st->L_frame, L_FRAME ) ) + { + lerp( old_exc_fx, old_bwe_exc_fx, L_EXC_MEM_DEC * HIBND_ACB_L_FAC, L_EXC_MEM_DEC ); + } + ELSE + { + lerp( old_exc_fx, old_bwe_exc_fx, L_EXC_MEM_DEC * 2, L_EXC_MEM_DEC ); + } + } + + /*---------------------------------------------------------------* + * Calculation of LP residual (filtering through A[z] filter) + *---------------------------------------------------------------*/ + + calc_residu_fx( st, inp, res_fx, Aq ); + calculate_hangover_attenuation_gain_ivas_fx( st, &att_fx, vad_hover_flag ); + + IF( NE_16( att_fx, 32767 /* ONE_IN_Q15 */ ) ) + { + v_multc_fixed_16_16( res_fx, att_fx, res_fx, st->L_frame ); + } + + // Scaling Aq and Aw to Q12 + FOR( Word16 k = 0; k < NB_SUBFR16k; k++ ) + { + Scale_sig( &Aq[( M + 1 ) * k], M + 1, sub( norm_s( Aq[( M + 1 ) * k] ), 2 ) ); + Scale_sig( &Aw[( M + 1 ) * k], M + 1, sub( norm_s( Aw[( M + 1 ) * k] ), 2 ) ); + } + /*-----------------------------------------------------------------* + * Determine TC subframe classification + *-----------------------------------------------------------------*/ + + IF( EQ_16( st->coder_type, TRANSITION ) ) + { + tc_classif_enc_fx( Q_new, st->L_frame, &tc_subfr, &position, attack_flag, st->pitch[0], res_fx ); + +#ifdef NONBE_FIX_GSC_BSTR + config_acelp1_IVAS( ENC, st->total_brate, st->core_brate, st->core, st->extl, st->extl_brate, st->L_frame, -1, &( st->acelp_cfg ), hBstr->nb_bits_tot, TRANSITION, -1, tc_subfr, 1, NULL, unbits, st->element_mode, &uc_two_stage_flag, tdm_lp_reuse_flag, tdm_low_rate_mode, st->idchan, st->active_cnt, tdm_Pitch_reuse_flag, st->tdm_LRTD_flag, st->GSC_IVAS_mode ); +#else + config_acelp1_IVAS( ENC, st->total_brate, st->core_brate, st->core, st->extl, st->extl_brate, st->L_frame, -1, &( st->acelp_cfg ), hBstr->nb_bits_tot, st->coder_type, tc_subfr, 1, NULL, unbits, st->element_mode, &uc_two_stage_flag, tdm_lp_reuse_flag, tdm_low_rate_mode, st->idchan, st->active_cnt, tdm_Pitch_reuse_flag, st->tdm_LRTD_flag, st->GSC_IVAS_mode ); +#endif + } + + /*---------------------------------------------------------------* + * Calculation of prediction for scaled innovation energy + * (for memory-less gain quantizer) + *---------------------------------------------------------------*/ + + IF( nb_bits > 0 ) + { + Es_pred_enc_fx( &Es_pred_fx, &i, st->L_frame, res_fx, st->voicing_fx, nb_bits, uc_two_stage_flag, Q_new ); + push_indice( hBstr, IND_ES_PRED, i, nb_bits ); + } + + /*------------------------------------------------------------* + * Encode excitation according to coding type + *------------------------------------------------------------*/ + test(); + test(); + IF( tdm_low_rate_mode ) /* tdm stereo low rate mode */ + { + IF( LE_16( st->coder_type, UNVOICED ) ) + { + tdm_low_rate_enc( st, Aq, res_fx, syn_fx, exc_fx, pitch_buf, voice_factors_fx, bwe_exc_fx, 0 /*attack_flag*/, lsf_new_fx, &tmp_noise_fx, Q_new ); + } + ELSE /* GENERIC */ + { + encod_gen_2sbfr( st, inp, Aw, Aq, res_fx, syn_fx, exc_fx, exc2_fx, pitch_buf, voice_factors_fx, bwe_exc_fx, tdm_Pitch_reuse_flag, tdm_Pri_pitch_buf_fx, Q_new, 0 ); + } + } + ELSE IF( nelp_mode ) + { + /* SC-VBR - NELP frames */ + encod_nelp_ivas_fx( st, inp, Aw, Aq, res_fx, syn_fx, &tmp_noise_fx, exc_fx, exc2_fx, pitch_buf, voice_factors_fx, bwe_exc_fx, Q_new, 0 ); + } + + ELSE IF( EQ_16( st->coder_type, UNVOICED ) ) + { + /* UNVOICED frames (Gauss. excitation) */ + encod_unvoiced_ivas_fx( st, inp, Aw, Aq, Es_pred_fx, uc_two_stage_flag, res_fx, syn_fx, &tmp_noise_fx, exc_fx, pitch_buf, voice_factors_fx, bwe_exc_fx, Q_new, 0 ); + } + ELSE IF( EQ_16( st->coder_type, TRANSITION ) ) + { + encod_tran_ivas_fx( st, inp, Aw, Aq, Es_pred_fx, res_fx, syn_fx, exc_fx, exc2_fx, pitch_buf, voice_factors_fx, bwe_exc_fx, tc_subfr, position, unbits, 0, Q_new ); + } + ELSE IF( ppp_mode ) + { + /* SC-VBR - PPP frames */ + IF( ( error = encod_ppp_ivas_fx( st, inp, Aw, Aq, res_fx, syn_fx, exc_fx, exc2_fx, pitch_buf, voice_factors_fx, bwe_exc_fx, Q_new, 0 ) ) != IVAS_ERR_OK ) + { + return error; + } + + IF( st->hSC_VBR->bump_up ) /* PPP failed, bump up */ + { + /* restore memories of LSF quantizer and synthesis filter */ + lsf_syn_mem_restore_ivas_fx( st, tilt_code_bck_fx, gc_threshold_bck_fx, clip_var_bck_fx, next_force_sf_bck, lsp_new, lsp_mid, clip_var_fx, mem_AR_fx, mem_MA_fx, lsp_new_bck_fx, lsp_mid_bck_fx, Bin_E_fx, Bin_E_old_fx, mem_syn_bck_fx, mem_w0_bck_fx, streaklimit_fx, pstreaklen ); + + /* Configure ACELP bit allocation */ +#ifdef NONBE_FIX_GSC_BSTR + config_acelp1_IVAS( ENC, st->total_brate, st->core_brate, st->core, st->extl, st->extl_brate, st->L_frame, -1, &( st->acelp_cfg ), hBstr->nb_bits_tot, st->coder_type, st->inactive_coder_type_flag, tc_subfr, 0, &nb_bits, unbits, 0, &uc_two_stage_flag, 0, 0, st->idchan, st->active_cnt, tdm_Pitch_reuse_flag, st->tdm_LRTD_flag, st->GSC_IVAS_mode ); +#else + config_acelp1_IVAS( ENC, st->total_brate, st->core_brate, st->core, st->extl, st->extl_brate, st->L_frame, -1, &( st->acelp_cfg ), hBstr->nb_bits_tot, st->coder_type, tc_subfr, 0, &nb_bits, unbits, 0, &uc_two_stage_flag, 0, 0, st->idchan, st->active_cnt, tdm_Pitch_reuse_flag, st->tdm_LRTD_flag, st->GSC_IVAS_mode ); +#endif + + /* redo LSF quantization */ + lsf_enc_ivas_fx( st, lsf_new_fx, lsp_new, lsp_mid, Aq, tdm_low_rate_mode, 0, NULL, Q_new ); + + /* recalculation of LP residual (filtering through A[z] filter) */ + calc_residu_fx( st, inp, res_fx, Aq ); + st->hTdCngEnc->burst_ho_cnt = 0; + move16(); + /* VOICED frames in SC-VBR */ + encod_gen_voic_ivas_fx( st, inp, Aw, Aq, Es_pred_fx, res_fx, syn_fx, exc_fx, exc2_fx, pitch_buf, voice_factors_fx, bwe_exc_fx, unbits, tdm_Pitch_reuse_flag, tdm_Pri_pitch_buf_fx, 0, Q_new ); + } + } + ELSE IF( EQ_16( st->coder_type, AUDIO ) || ( st->coder_type == INACTIVE && st->inactive_coder_type_flag ) ) + { + /* AUDIO and INACTIVE frames (coded by GSC technology) */ + encod_audio_ivas_fx( st, inp, Aw, Aq, res_fx, syn_fx, exc_fx, pitch_buf, voice_factors_fx, bwe_exc_fx, attack_flag, lsf_new_fx, &tmp_noise_fx, tdm_Pitch_reuse_flag, tdm_Pri_pitch_buf_fx, Q_new, 0 ); + } + ELSE + { + /* GENERIC, VOICED and INACTIVE frames (coded by AVQ technology) */ + encod_gen_voic_ivas_fx( st, inp, Aw, Aq, Es_pred_fx, res_fx, syn_fx, exc_fx, exc2_fx, pitch_buf, voice_factors_fx, bwe_exc_fx, unbits, tdm_Pitch_reuse_flag, tdm_Pri_pitch_buf_fx, 0, Q_new ); + } + + FOR( i = 0; i < NB_SUBFR16k; i++ ) + { + Scale_sig( &Aq[i * ( M + 1 )], ( M + 1 ), sub( Q12, sub( Q14, norm_s( Aq[i * ( M + 1 )] ) ) ) ); // Q12 + } + + /* update mem_syn1_flt for ACELP core switching */ + Copy( hLPDmem->mem_syn, hLPDmem->mem_syn1_fx, M ); // Q_syn + + /* update old synthesis buffer - needed for ACELP internal sampling rate switching */ + Copy( syn_fx + sub( st->L_frame, L_SYN_MEM ), hLPDmem->mem_syn_r, L_SYN_MEM ); // st->Q_syn + + Scale_sig( syn_fx, L_FRAME16k, sub( st->Q_syn, Q_new - 1 ) ); // Q_syn + /* save and delay synthesis to be used by SWB BWE */ + IF( st->hBWE_FD != NULL ) + { + st->hBWE_FD->mem_deemph_old_syn_fx = shl_sat( st->hBWE_FD->mem_deemph_old_syn_fx, sub( s_min( st->Q_syn, st->hBWE_FD->q_mem_deemph_old_syn ), st->hBWE_FD->q_mem_deemph_old_syn ) ); // s_min( st->Q_syn, st->hBWE_FD->q_mem_deemph_old_syn ) + move16(); + Scale_sig( st->hBWE_FD->old_syn_12k8_16k_fx, NS2SA( 16000, DELAY_FD_BWE_ENC_NS ), sub( s_min( st->Q_syn, st->hBWE_FD->q_mem_deemph_old_syn ), st->hBWE_FD->q_mem_deemph_old_syn ) ); // s_min( st->Q_syn, st->hBWE_FD->q_mem_deemph_old_syn ) + + save_old_syn_fx( st->L_frame, syn_fx, old_syn_12k8_16k, st->hBWE_FD->old_syn_12k8_16k_fx, st->preemph_fac, &st->hBWE_FD->mem_deemph_old_syn_fx ); + *q_old_syn_12k8_16 = s_min( st->Q_syn, st->hBWE_FD->q_mem_deemph_old_syn ); + move16(); + st->hBWE_FD->q_mem_deemph_old_syn = s_min( st->Q_syn, st->hBWE_FD->q_mem_deemph_old_syn ); + move16(); + Scale_sig( syn_fx, st->L_frame, sub( st->Q_syn, s_min( st->Q_syn, st->hBWE_FD->q_mem_deemph_old_syn ) ) ); // st->Q_syn + } + + /*Update MODE2 core switching memory*/ + Copy( syn_fx, syn1_fx, st->L_frame ); // st->Q_syn + + Scale_sig( st->hLPDmem->syn, M + 1, sub( st->Q_syn, st->hLPDmem->q_lpd_syn ) ); // st->Q_syn + st->hLPDmem->q_lpd_syn = st->Q_syn; + move16(); + + /*Update MODE2 core switching memory*/ + deemph_fx( syn1_fx, st->preemph_fac, st->L_frame, &( hLPDmem->syn[M] ) ); + + Copy( syn1_fx + add( st->L_frame, -M - 1 ), hLPDmem->syn, M + 1 ); // st->Q_syn + + test(); + IF( st->element_mode > EVS_MONO && st->hTcxEnc != NULL ) + { + Copy( syn1_fx + shr( st->L_frame, 1 ), st->hTcxEnc->Txnq, shr( st->L_frame, 1 ) ); // st->Q_syn +#ifdef MSAN_FIX + Scale_sig( st->hTcxEnc->Txnq + shr( st->L_frame, 1 ), sub( L_FRAME32k / 2 + 64, shr( st->L_frame, 1 ) ), sub( st->Q_syn, st->hTcxEnc->q_Txnq ) ); // st->Q_syn +#else + Scale_sig( st->hTcxEnc->Txnq + shr( st->L_frame, 1 ), sub( L_FRAME32k / 2 + 64, shr( st->L_frame, 2 ) ), sub( st->Q_syn, st->hTcxEnc->q_Txnq ) ); +#endif + st->hTcxEnc->q_Txnq = st->Q_syn; + move16(); + } + + /*--------------------------------------------------------------------------------------* + * Modify the excitation signal when the noise is stationary + *--------------------------------------------------------------------------------------*/ + test(); + test(); + test(); + test(); + IF( !( EQ_16( st->idchan, 1 ) && EQ_16( st->element_mode, IVAS_CPE_TD ) ) && NE_16( nelp_mode, 1 ) && !( EQ_16( st->element_mode, IVAS_SCE ) && tdm_low_rate_mode ) ) + { + /* exc2 buffer is needed only for updating of Aq[] which is needed for core switching */ + Copy( exc_fx, exc2_fx, st->L_frame ); // Q_new + + stat_noise_uv_enc_ivas_fx( st, epsP, lsp_new, lsp_mid, Aq, exc2_fx, uc_two_stage_flag, Q_new ); + } + + /*-----------------------------------------------------------------* + * Encode supplementary information for Frame Error Concealment + *-----------------------------------------------------------------*/ + + Scale_sig( syn_fx, L_FRAME, sub( s_min( st->Q_syn, Q_new ), st->Q_syn ) ); // min( st->Q_syn, Q_new ) +#ifdef MSAN_FIX + Scale_sig( res_fx, st->L_frame, sub( s_min( st->Q_syn, Q_new ), Q_new ) ); // min( st->Q_syn, Q_new ) +#else + Scale_sig( res_fx, L_FRAME16k, sub( s_min( st->Q_syn, Q_new ), Q_new ) ); +#endif + FEC_encode_ivas_fx( hBstr, st->acelp_cfg, syn_fx, st->coder_type, st->clas, pitch_buf, res_fx, &st->Last_pulse_pos, st->L_frame, st->total_brate, s_min( st->Q_syn, Q_new ) ); + IF( st->hBWE_TD != NULL ) + { + IF( EQ_16( st->L_frame, L_FRAME ) ) + { + Copy( Aq + 2 * ( M + 1 ), st->hBWE_TD->cur_sub_Aq_fx, ( M + 1 ) ); // Q12 + } + ELSE + { + Copy( Aq + 3 * ( M + 1 ), st->hBWE_TD->cur_sub_Aq_fx, ( M + 1 ) ); // Q12 + } + } + + + } /* end of active inp coding */ + + /*-----------------------------------------------------------------* + * Write ACELP unused bits + *-----------------------------------------------------------------*/ + test(); + test(); + IF( NE_32( st->core_brate, SID_2k40 ) && st->core_brate != FRAME_NO_DATA && NE_32( st->core_brate, PPP_NELP_2k80 ) ) + { + nBits = st->acelp_cfg.ubits; // Q0 + move16(); + WHILE( nBits > 0 ) + { + i = s_min( nBits, 16 ); // Q0 + push_indice( hBstr, IND_UNUSED, 0, i ); + nBits = sub( nBits, i ); // Q0 + } + } + + /*-----------------------------------------------------------------* + * Apply non linearity in case of SWB TBE + *-----------------------------------------------------------------*/ + + IF( st->hBWE_TD != NULL ) + { + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + IF( ( EQ_16( st->last_Opt_SC_VBR, 1 ) && st->Opt_SC_VBR == 0 ) || ( ( EQ_16( st->extl, SWB_TBE ) || EQ_16( st->extl, WB_TBE ) || EQ_16( st->extl, FB_TBE ) ) && NE_16( st->last_extl, SWB_TBE ) && NE_16( st->last_extl, WB_TBE ) && NE_16( st->last_extl, FB_TBE ) ) || ( EQ_16( st->idchan, 1 ) && EQ_16( st->element_mode, IVAS_CPE_TD ) && !st->tdm_LRTD_flag ) ) + { + st->hBWE_TD->bwe_non_lin_prev_scale_fx = 0; + move16(); + set16_fx( st->hBWE_TD->old_bwe_exc_extended_fx, 0, NL_BUFF_OFFSET ); + } + + test(); + test(); + test(); + test(); + test(); + IF( !st->Opt_SC_VBR && ( st->idchan == 0 || NE_16( st->element_mode, IVAS_CPE_TD ) || ( EQ_16( st->idchan, 1 ) && EQ_16( st->element_mode, IVAS_CPE_TD ) && st->tdm_LRTD_flag ) ) ) + { + /* Apply a non linearity to the SHB excitation */ +#ifdef FIX_ISSUE_1237 + Copy_Scale_sig_16_32_no_sat( st->hBWE_TD->old_bwe_exc_extended_fx, bwe_exc_extended_fx, NL_BUFF_OFFSET, ( sub( shl( Q_new, 1 ), sub( st->prev_Q_bwe_exc, 16 ) ) ) ); // prev_Q_bwe_exc +#else + Copy_Scale_sig_16_32_DEPREC( st->hBWE_TD->old_bwe_exc_extended_fx, bwe_exc_extended_fx, NL_BUFF_OFFSET, ( sub( shl( Q_new, 1 ), sub( st->prev_Q_bwe_exc, 16 ) ) ) ); // prev_Q_bwe_exc +#endif + non_linearity_ivas_fx( bwe_exc_fx, bwe_exc_extended_fx + NL_BUFF_OFFSET, L_FRAME32k, &st->hBWE_TD->bwe_non_lin_prev_scale_fx, Q_new, st->coder_type, voice_factors_fx, st->L_frame ); + Copy_Scale_sig_32_16( bwe_exc_extended_fx + L_FRAME32k, st->hBWE_TD->old_bwe_exc_extended_fx, NL_BUFF_OFFSET, negate( sub( shl( Q_new, 1 ), sub( st->prev_Q_bwe_exc, 16 ) ) ) ); // prev_Q_bwe_exc + } + + test(); + if ( EQ_32( st->core_brate, SID_2k40 ) || st->core_brate == FRAME_NO_DATA ) + { + st->hBWE_TD->bwe_non_lin_prev_scale_fx = 0; + move16(); + } + } + + /*-----------------------------------------------------------------* + * Updates + *-----------------------------------------------------------------*/ + + if ( st->hBWE_TD != NULL ) + { + st->Q_exc = Q_new; + move16(); + } + + updt_enc_fx( st, old_exc_fx, pitch_buf, Es_pred_fx, Aq, lsf_new_fx, lsp_new, old_bwe_exc_fx ); + st->hLPDmem->q_lpd_old_exc = Q_new; + move16(); + + test(); + test(); + IF( st->hTdCngEnc != NULL && st->Opt_DTX_ON && GT_32( st->core_brate, SID_2k40 ) ) + { + /* update CNG parameters in active frames */ + Word16 q_exc = st->hTdCngEnc->cng_Qexc_buf[0]; + move16(); + FOR( Word16 ii = 0; ii < HO_HIST_SIZE; ii++ ) + { + q_exc = s_min( q_exc, st->hTdCngEnc->cng_Qexc_buf[ii] ); + } + q_exc = s_min( q_exc, Q_new ); + + Scale_sig( exc_fx, L_EXC - L_EXC_MEM, sub( q_exc, Q_new ) ); // q_exc + FOR( Word16 ii = 0; ii < HO_HIST_SIZE; ii++ ) + { + Scale_sig( st->hTdCngEnc->cng_exc2_buf + ii * L_FFT, L_FFT, sub( q_exc, st->hTdCngEnc->cng_Qexc_buf[ii] ) ); // Q_exc + st->hTdCngEnc->cng_Qexc_buf[ii] = q_exc; + move16(); + } + cng_params_upd_ivas_fx( lsp_new, exc_fx, st->L_frame, &st->hTdCngEnc->ho_circ_ptr, st->hTdCngEnc->ho_ener_circ_fx, + &st->hTdCngEnc->ho_circ_size, st->hTdCngEnc->ho_lsp_circ_fx, q_exc, ENC, st->hTdCngEnc->ho_env_circ_fx, &st->hTdCngEnc->cng_buf_cnt, + st->hTdCngEnc->cng_exc2_buf, st->hTdCngEnc->cng_Qexc_buf, st->hTdCngEnc->cng_brate_buf, st->hDtxEnc->last_active_brate, st->element_mode, + st->hFdCngEnc->hFdCngCom->CngBandwidth ); + + IF( EQ_16( st->L_frame, L_FRAME ) ) + { + /* store LSPs@16k, potentially to be used in CNG@16k */ + Copy( st->lsp_old16k_fx, &( st->hTdCngEnc->ho_lsp_circ2_fx[( st->hTdCngEnc->ho_circ_ptr ) * M] ), M ); // Q15 + } + + /* set LSP@16k flag for the first buffer */ + IF( EQ_16( st->L_frame, L_FRAME ) ) + { + st->hTdCngEnc->ho_16k_lsp[st->hTdCngEnc->ho_circ_ptr] = 0; + } + ELSE + { + st->hTdCngEnc->ho_16k_lsp[st->hTdCngEnc->ho_circ_ptr] = 1; + } + move16(); + /* efficient DTX hangover control */ + IF( GT_16( st->hTdCngEnc->burst_ho_cnt, 1 ) ) + { + dtx_hangover_control_fx( st, lsp_new ); + } + } + + /* SC-VBR update of average data rate */ + IF( EQ_16( st->vad_flag, 1 ) ) + { + /* reset in case of bitrate switching in EVS */ + if ( st->hSC_VBR != NULL ) + { + update_average_rate_fx( st->hSC_VBR, st->core_brate ); + } + } + pop_wmops(); + + return error; +} diff --git a/lib_enc/acelp_core_switch_enc.c b/lib_enc/acelp_core_switch_enc.c deleted file mode 100644 index 9d6f499db09e405ecf613f29cb1442072afc3305..0000000000000000000000000000000000000000 --- a/lib_enc/acelp_core_switch_enc.c +++ /dev/null @@ -1,44 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include -#include "cnst.h" -#include "rom_enc.h" -#include "rom_com.h" -#include "prot.h" -#include "wmc_auto.h" diff --git a/lib_enc/acelp_core_switch_enc_fx.c b/lib_enc/acelp_core_switch_enc_fx.c index 029e3083ea893830d663c161a859cc83aa2943f9..d88e1523ed825acceb35a351a58e66b63f4906ce 100644 --- a/lib_enc/acelp_core_switch_enc_fx.c +++ b/lib_enc/acelp_core_switch_enc_fx.c @@ -11,7 +11,6 @@ #include "prot_fx.h" /* Function prototypes */ #include "prot_fx_enc.h" /* Function prototypes */ #include "basop_util.h" /* Function prototypes */ -#include "prot.h" /*---------------------------------------------------------------------* * Local function prototypes *---------------------------------------------------------------------*/ @@ -71,11 +70,11 @@ void acelp_core_switch_enc_fx( move16(); /* pointer to excitation signal in the current frame */ Copy( hLPDmem->old_exc, old_exc, L_EXC_MEM ); /*now old_exc has the same scaling as st_fx->old_exc; need to change later? */ - Copy( st_fx->old_Aq_12_8_fx, Aq, M + 1 ); - Copy( st_fx->old_Aq_12_8_fx, Aq + ( M + 1 ), M + 1 ); - T_op[0] = st_fx->pitch[0]; + Copy( st_fx->old_Aq_12_8_fx, Aq, M + 1 ); /* Q12 */ + Copy( st_fx->old_Aq_12_8_fx, Aq + ( M + 1 ), M + 1 ); /* Q12 */ + T_op[0] = st_fx->pitch[0]; /* Q0 */ move16(); - T_op[1] = st_fx->pitch[1]; + T_op[1] = st_fx->pitch[1]; /* Q0 */ move16(); /*----------------------------------------------------------------* @@ -84,7 +83,7 @@ void acelp_core_switch_enc_fx( IF( EQ_16( st_fx->last_L_frame, L_FRAME ) ) /* ACELP@12k8 core */ { - inp = inp12k8; + inp = inp12k8; /* Q0 */ IF( GT_32( st_fx->core_brate, ACELP_24k40 ) ) { @@ -97,7 +96,7 @@ void acelp_core_switch_enc_fx( } ELSE /* ACELP@16k core */ { - inp = inp16k; + inp = inp16k; /* Q0 */ IF( LE_32( st_fx->core_brate, ACELP_8k00 ) ) { @@ -139,45 +138,37 @@ void acelp_core_switch_enc_fx( #else IF( NE_16( st_fx->last_L_frame, L_FRAME ) ) { - T_op[0] = shr( add( round_fx( L_shl( L_mult( 20480, T_op[0] ), 2 ) ), 1 ), 1 ); + T_op[0] = shr( add( round_fx( L_shl( L_mult( 20480, T_op[0] ), 2 ) ), 1 ), 1 ); /* Q0 */ move16(); - T_op[1] = shr( add( round_fx( L_shl( L_mult( 20480, T_op[1] ), 2 ) ), 1 ), 1 ); + T_op[1] = shr( add( round_fx( L_shl( L_mult( 20480, T_op[1] ), 2 ) ), 1 ), 1 ); /* Q0 */ move16(); } #endif /*----------------------------------------------------------------* * Excitation encoding *----------------------------------------------------------------*/ + config_acelp1( ENC, st_fx->total_brate, cbrate, st_fx->core, -1, -1, st_fx->last_L_frame, -1, &( st_fx->acelp_cfg ), hBstr->nb_bits_tot, +#ifdef NONBE_FIX_GSC_BSTR + GENERIC, st_fx->inactive_coder_type_flag, -1, -1, &j, &i, st_fx->element_mode, &i /*dummy*/, 0 /*tdm_lp_reuse_flag*/, 0 /*tdm_low_rate_mode*/, st_fx->idchan, st_fx->active_fr_cnt_fx, 0 /*tdm_Pitch_reuse_flag*/, 0, 0 /*GSC_IVAS_mode*/ ); +#else GENERIC, -1, -1, &j, &i, st_fx->element_mode, &i /*dummy*/, 0 /*tdm_lp_reuse_flag*/, 0 /*tdm_low_rate_mode*/, st_fx->idchan, st_fx->active_fr_cnt_fx, 0 /*tdm_Pitch_reuse_flag*/, 0, 0 /*GSC_IVAS_mode*/ ); +#endif encod_gen_voic_core_switch_fx( st_fx, st_fx->last_L_frame, inp, Aq, A, T_op, exc, cbrate, shift, Q_new ); /*----------------------------------------------------------------* * bit-stream: modify the layer of sub frame CELP *----------------------------------------------------------------*/ -#ifdef IVAS_CODE_BITSTREAM - i = find_indice( hBstr, TAG_ACELP_SUBFR_LOOP_START, &value, &nb_bits ); -#ifdef DEBUGGING - assert( i >= 0 && "Internal error in ACELP core switching - unable to find ACELP subframe indices!" ); -#endif - while ( hBstr->ind_list[i].id == TAG_ACELP_SUBFR_LOOP_START ) - { - push_indice( hBstr, IND_CORE_SWITCHING_CELP_SUBFRAME, hBstr->ind_list[i].value, hBstr->ind_list[i].nb_bits ); - i++; - } - delete_indice( hBstr, TAG_ACELP_SUBFR_LOOP_START ); -#else FOR( i = 0; i < 20; i++ ) { - hBstr->ind_list[IND_CORE_SWITCHING_CELP_SUBFRAME + i].value = hBstr->ind_list[TAG_ACELP_SUBFR_LOOP_START + i].value; + hBstr->ind_list[IND_CORE_SWITCHING_CELP_SUBFRAME + i].value = hBstr->ind_list[TAG_ACELP_SUBFR_LOOP_START + i].value; /* Q0 */ move16(); - hBstr->ind_list[IND_CORE_SWITCHING_CELP_SUBFRAME + i].nb_bits = hBstr->ind_list[TAG_ACELP_SUBFR_LOOP_START + i].nb_bits; + hBstr->ind_list[IND_CORE_SWITCHING_CELP_SUBFRAME + i].nb_bits = hBstr->ind_list[TAG_ACELP_SUBFR_LOOP_START + i].nb_bits; /* Q0 */ move16(); - hBstr->ind_list[TAG_ACELP_SUBFR_LOOP_START + i].nb_bits = -1; + hBstr->ind_list[TAG_ACELP_SUBFR_LOOP_START + i].nb_bits = -1; /* Q0 */ move16(); } -#endif /*----------------------------------------------------------------* * BWE encoding *----------------------------------------------------------------*/ @@ -218,11 +209,11 @@ void acelp_core_switch_enc_ivas_fx( move16(); /* pointer to excitation signal in the current frame */ Copy( hLPDmem->old_exc, old_exc, L_EXC_MEM ); /*now old_exc has the same scaling as st_fx->old_exc; need to change later? */ - Copy( st_fx->old_Aq_12_8_fx, Aq, M + 1 ); - Copy( st_fx->old_Aq_12_8_fx, Aq + ( M + 1 ), M + 1 ); - T_op[0] = st_fx->pitch[0]; + Copy( st_fx->old_Aq_12_8_fx, Aq, M + 1 ); /* Q12 */ + Copy( st_fx->old_Aq_12_8_fx, Aq + ( M + 1 ), M + 1 ); /* Q12 */ + T_op[0] = st_fx->pitch[0]; /* Q12 */ move16(); - T_op[1] = st_fx->pitch[1]; + T_op[1] = st_fx->pitch[1]; /* Q12 */ move16(); /*----------------------------------------------------------------* @@ -231,7 +222,7 @@ void acelp_core_switch_enc_ivas_fx( IF( EQ_16( st_fx->last_L_frame, L_FRAME ) ) /* ACELP@12k8 core */ { - inp = inp12k8; + inp = inp12k8; /* Q0 */ IF( GT_32( st_fx->core_brate, ACELP_24k40 ) ) { @@ -244,7 +235,7 @@ void acelp_core_switch_enc_ivas_fx( } ELSE /* ACELP@16k core */ { - inp = inp16k; + inp = inp16k; /* Q0 */ IF( LE_32( st_fx->core_brate, ACELP_8k00 ) ) { @@ -256,23 +247,28 @@ void acelp_core_switch_enc_ivas_fx( } ELSE { - cbrate = L_min( st_fx->core_brate, ACELP_22k60 ); + cbrate = L_min( st_fx->core_brate, ACELP_22k60 ); /* Q0 */ } } IF( NE_16( st_fx->last_L_frame, L_FRAME ) ) { - T_op[0] = shr( add( round_fx( L_shl( L_mult( 20480, T_op[0] ), 2 ) ), 1 ), 1 ); + T_op[0] = shr( add( round_fx( L_shl( L_mult( 20480 /* 1.25 in Q14 */, T_op[0] ), 2 ) ), 1 ), 1 ); /* Q0 */ move16(); - T_op[1] = shr( add( round_fx( L_shl( L_mult( 20480, T_op[1] ), 2 ) ), 1 ), 1 ); + T_op[1] = shr( add( round_fx( L_shl( L_mult( 20480 /* 1.25 in Q14 */, T_op[1] ), 2 ) ), 1 ), 1 ); /* Q0 */ move16(); } /*----------------------------------------------------------------* * Excitation encoding *----------------------------------------------------------------*/ + config_acelp1_IVAS( ENC, st_fx->total_brate, cbrate, st_fx->core, -1, -1, st_fx->last_L_frame, -1, &( st_fx->acelp_cfg ), hBstr->nb_bits_tot, +#ifdef NONBE_FIX_GSC_BSTR + GENERIC, st_fx->inactive_coder_type_flag, -1, -1, &j, &i, st_fx->element_mode, &i /*dummy*/, 0 /*tdm_lp_reuse_flag*/, 0 /*tdm_low_rate_mode*/, st_fx->idchan, st_fx->active_fr_cnt_fx, 0 /*tdm_Pitch_reuse_flag*/, 0, 0 /*GSC_IVAS_mode*/ ); +#else GENERIC, -1, -1, &j, &i, st_fx->element_mode, &i /*dummy*/, 0 /*tdm_lp_reuse_flag*/, 0 /*tdm_low_rate_mode*/, st_fx->idchan, st_fx->active_fr_cnt_fx, 0 /*tdm_Pitch_reuse_flag*/, 0, 0 /*GSC_IVAS_mode*/ ); +#endif encod_gen_voic_core_switch_ivas_fx( st_fx, st_fx->last_L_frame, inp, Aq, A, T_op, exc, cbrate, shift, Q_new ); @@ -280,7 +276,7 @@ void acelp_core_switch_enc_ivas_fx( * bit-stream: modify the layer of sub frame CELP *----------------------------------------------------------------*/ - i = find_indice( hBstr, TAG_ACELP_SUBFR_LOOP_START, &value, &nb_bits ); + i = find_indice( hBstr, TAG_ACELP_SUBFR_LOOP_START, &value, &nb_bits ); /* Q0 */ while ( hBstr->ind_list[i].id == TAG_ACELP_SUBFR_LOOP_START ) { @@ -312,13 +308,13 @@ void acelp_core_switch_enc_ivas_fx( static void encod_gen_voic_core_switch_fx( Encoder_State *st_fx, /* i/o: state structure */ - const Word16 L_frame, /* i : length of the frame */ - const Word16 inp[], /* i : input signal */ - const Word16 Aq[], /* i : LP coefficients */ - const Word16 A[], /* i : unquantized A(z) filter */ - const Word16 T_op[], /* i : open loop pitch */ - Word16 *exc, /* i/o: current non-enhanced excitation */ - const Word32 core_bitrate, /* i : switching frame bitrate */ + const Word16 L_frame, /* i : length of the frame Q0*/ + const Word16 inp[], /* i : input signal Q0*/ + const Word16 Aq[], /* i : LP coefficients Q12*/ + const Word16 A[], /* i : unquantized A(z) filter Q12*/ + const Word16 T_op[], /* i : open loop pitch Q0*/ + Word16 *exc, /* i/o: current non-enhanced excitation Q_exc*/ + const Word32 core_bitrate, /* i : switching frame bitrate Q0*/ Word16 shift, Word16 Q_new ) { @@ -396,7 +392,7 @@ static void encod_gen_voic_core_switch_fx( hTdCngEnc->burst_ho_cnt = 0; move16(); - st_fx->L_frame = tmp16; + st_fx->L_frame = tmp16; /* Q0 */ move16(); /*------------------------------------------------------------------* @@ -404,7 +400,7 @@ static void encod_gen_voic_core_switch_fx( *------------------------------------------------------------------*/ - Copy( res, exc, L_SUBFR ); + Copy( res, exc, L_SUBFR ); /* Q1 */ IF( EQ_16( L_frame, L_FRAME16k ) ) { @@ -422,7 +418,7 @@ static void encod_gen_voic_core_switch_fx( Scale_sig( h1, L_SUBFR, add( 1, shift ) ); /* set h1[] in Q14 with scaling for convolution */ /* scaling of xn[] to limit dynamic at 12 bits */ - Scale_sig( xn, L_SUBFR, shift ); + Scale_sig( xn, L_SUBFR, shift ); /* Q_new */ /*----------------------------------------------------------------* * Close-loop pitch search and quantization @@ -430,7 +426,7 @@ static void encod_gen_voic_core_switch_fx( *----------------------------------------------------------------*/ set16_fx( dummyF, -1, NB_SUBFR16k ); /* hack to signal ACELP->HQ switching frame */ pitch = pit_encode_fx( hBstr, - st_fx->acelp_cfg.pitch_bits, core_bitrate, 0, L_frame, GENERIC, &pitch_limit_flag, 0, exc, L_SUBFR, T_op, &T0_min, &T0_max, &T0, &T0_frac, h1, xn, 0 /*hStereoTD->tdm_Pitch_reuse_flag*/, dummyF /*hStereoTD->tdm_Pri_pitch_buf*/ ); + st_fx->acelp_cfg.pitch_bits, core_bitrate, 0, L_frame, GENERIC, &pitch_limit_flag, 0, exc, L_SUBFR, T_op, &T0_min, &T0_max, &T0, &T0_frac, h1, xn, 0 /*hStereoTD->tdm_Pitch_reuse_flag*/, dummyF /*hStereoTD->tdm_Pri_pitch_buf*/ ); /* Q6 */ /*-----------------------------------------------------------------* * Find adaptive exitation @@ -443,13 +439,13 @@ static void encod_gen_voic_core_switch_fx( * or in case of floating point encoder & fixed p. decoder *-----------------------------------------------------------------*/ - clip_gain = gp_clip_fx( st_fx->element_mode, core_bitrate, st_fx->voicing_fx, 0, GENERIC, xn, st_fx->clip_var_fx, sub( shift_wsp, 1 ) ); + clip_gain = gp_clip_fx( st_fx->element_mode, core_bitrate, st_fx->voicing_fx, 0, GENERIC, xn, st_fx->clip_var_fx, sub( shift_wsp, 1 ) ); /* Q0 */ /*-----------------------------------------------------------------* * LP filtering of the adaptive excitation, codebook target computation *-----------------------------------------------------------------*/ - lp_flag = st_fx->acelp_cfg.ltf_mode; - lp_select = lp_filt_exc_enc_fx( MODE1, GENERIC, 0, exc, h1, xn, y1, xn2, L_SUBFR, L_frame, g_corr, clip_gain, &gain_pit, &lp_flag ); + lp_flag = st_fx->acelp_cfg.ltf_mode; /* Q0 */ + lp_select = lp_filt_exc_enc_fx( MODE1, GENERIC, 0, exc, h1, xn, y1, xn2, L_SUBFR, L_frame, g_corr, clip_gain, &gain_pit, &lp_flag ); /* Q0 */ IF( EQ_16( lp_flag, NORMAL_OPERATION ) ) { @@ -480,7 +476,7 @@ static void encod_gen_voic_core_switch_fx( gp_clip_test_gain_pit_fx( st_fx->element_mode, core_bitrate, gain_pit, st_fx->clip_var_fx ); Lgcode = L_shl( gain_code, Q_new ); /* scaled gain_code with Qnew -> Q16*/ - gcode16 = round_fx( Lgcode ); + gcode16 = round_fx( Lgcode ); /* Q0 */ hLPDmem->tilt_code = Est_tilt2( exc + 0, gain_pit, code, gain_code, &voice_fac, shift ); @@ -491,18 +487,11 @@ static void encod_gen_voic_core_switch_fx( FOR( i = 0; i < L_SUBFR; i++ ) { /* code in Q9, gain_pit in Q14 */ - L_tmp = L_mult( gcode16, code[i] ); -#ifdef BASOP_NOGLOB - L_tmp = L_shl_sat( L_tmp, 5 ); + L_tmp = L_mult( gcode16, code[i] ); /* Q10 */ + L_tmp = L_shl_sat( L_tmp, 5 ); /* Q15 */ L_tmp = L_mac_sat( L_tmp, exc[i], gain_pit ); - L_tmp = L_shl_sat( L_tmp, 1 ); /* saturation can occur here */ - exc[i] = round_fx_sat( L_tmp ); -#else - L_tmp = L_shl( L_tmp, 5 ); - L_tmp = L_mac( L_tmp, exc[i], gain_pit ); - L_tmp = L_shl( L_tmp, 1 ); /* saturation can occur here */ - exc[i] = round_fx( L_tmp ); -#endif + L_tmp = L_shl_sat( L_tmp, 1 ); /* saturation can occur here */ + exc[i] = round_fx_sat( L_tmp ); /* Q_exc */ } /* write reserved bits */ @@ -519,11 +508,7 @@ static void encod_gen_voic_core_switch_fx( FOR( i = L_SUBFR; i < 2 * L_SUBFR; i++ ) { -#ifdef BASOP_NOGLOB - exc[i] = round_fx_sat( L_shl_sat( L_mult_sat( exc[i], gain_pit ), 1 ) ); -#else - exc[i] = round_fx( L_shl( L_mult( exc[i], gain_pit ), 1 ) ); -#endif + exc[i] = round_fx_sat( L_shl_sat( L_mult_sat( exc[i], gain_pit ), 1 ) ); /* Q_exc */ } return; @@ -531,13 +516,13 @@ static void encod_gen_voic_core_switch_fx( static void encod_gen_voic_core_switch_ivas_fx( Encoder_State *st_fx, /* i/o: state structure */ - const Word16 L_frame, /* i : length of the frame */ - const Word16 inp[], /* i : input signal */ - const Word16 Aq[], /* i : LP coefficients */ - const Word16 A[], /* i : unquantized A(z) filter */ - const Word16 T_op[], /* i : open loop pitch */ - Word16 *exc, /* i/o: current non-enhanced excitation */ - const Word32 core_bitrate, /* i : switching frame bitrate */ + const Word16 L_frame, /* i : length of the frame Q0*/ + const Word16 inp[], /* i : input signal Q0*/ + const Word16 Aq[], /* i : LP coefficients Q12*/ + const Word16 A[], /* i : unquantized A(z) filter Q12*/ + const Word16 T_op[], /* i : open loop pitch Q0*/ + Word16 *exc, /* i/o: current non-enhanced excitation Q_exc*/ + const Word32 core_bitrate, /* i : switching frame bitrate Q0*/ Word16 shift, Word16 Q_new ) { @@ -571,6 +556,7 @@ static void encod_gen_voic_core_switch_ivas_fx( Word16 h2[L_SUBFR + ( M + 1 )]; Word16 dummyF[NB_SUBFR16k]; Word16 lp_select, lp_flag; + Word16 q_h1; LPD_state_HANDLE hLPDmem; /* ACELP LPDmem memories */ BSTR_ENC_HANDLE hBstr; @@ -607,14 +593,14 @@ static void encod_gen_voic_core_switch_ivas_fx( * Calculation of LP residual (filtering through A[z] filter) *------------------------------------------------------------------*/ - tmp16 = st_fx->L_frame; + tmp16 = st_fx->L_frame; /* Q0 */ move16(); st_fx->L_frame = L_SUBFR; move16(); calc_residu_fx( st_fx, inp, res, Aq ); // hTdCngEnc->burst_ho_cnt = 0; - st_fx->L_frame = tmp16; + st_fx->L_frame = tmp16; /* Q0 */ move16(); /*------------------------------------------------------------------* @@ -622,7 +608,7 @@ static void encod_gen_voic_core_switch_ivas_fx( *------------------------------------------------------------------*/ - Copy( res, exc, L_SUBFR ); + Copy( res, exc, L_SUBFR ); /* Q_exc */ IF( EQ_16( L_frame, L_FRAME16k ) ) { @@ -635,20 +621,20 @@ static void encod_gen_voic_core_switch_ivas_fx( find_targets_ivas_fx( inp, hLPDmem->mem_syn, 0, &( hLPDmem->mem_w0 ), Aq, res, L_SUBFR, Ap, TILT_FAC_FX, xn, cn, h1 ); } - /*Scale_sig(h1, L_SUBFR, shift); */ /*Q14-shift */ - Copy_Scale_sig( h1, h2, L_SUBFR, -2 ); - Scale_sig( h1, L_SUBFR, add( 1, shift ) ); /* set h1[] in Q14 with scaling for convolution */ + q_h1 = sub( 14, norm_s( h1[0] ) ); + Copy_Scale_sig( h1, h2, L_SUBFR, sub( 11, q_h1 ) ); /*Q11*/ /* scaling of xn[] to limit dynamic at 12 bits */ - Scale_sig( xn, L_SUBFR, shift ); + Scale_sig( xn, L_SUBFR, shift ); /* Q_new */ /*----------------------------------------------------------------* * Close-loop pitch search and quantization * Adaptive exc. construction *----------------------------------------------------------------*/ set16_fx( dummyF, -1, NB_SUBFR16k ); /* hack to signal ACELP->HQ switching frame */ + pitch = pit_encode_ivas_fx( hBstr, - st_fx->acelp_cfg.pitch_bits, core_bitrate, 0, L_frame, GENERIC, &pitch_limit_flag, 0, exc, L_SUBFR, T_op, &T0_min, &T0_max, &T0, &T0_frac, h1, xn, 0 /*hStereoTD->tdm_Pitch_reuse_flag*/, dummyF /*hStereoTD->tdm_Pri_pitch_buf*/ ); + st_fx->acelp_cfg.pitch_bits, core_bitrate, 0, L_frame, GENERIC, &pitch_limit_flag, 0, exc, L_SUBFR, T_op, &T0_min, &T0_max, &T0, &T0_frac, h1, xn, 0 /*hStereoTD->tdm_Pitch_reuse_flag*/, dummyF /*hStereoTD->tdm_Pri_pitch_buf*/, Q_new ); /* Q6 */ /*-----------------------------------------------------------------* * Find adaptive exitation @@ -661,13 +647,14 @@ static void encod_gen_voic_core_switch_ivas_fx( * or in case of floating point encoder & fixed p. decoder *-----------------------------------------------------------------*/ - clip_gain = gp_clip_fx( st_fx->element_mode, core_bitrate, st_fx->voicing_fx, 0, GENERIC, xn, st_fx->clip_var_fx, sub( shift_wsp, 1 ) ); + clip_gain = gp_clip_fx( st_fx->element_mode, core_bitrate, st_fx->voicing_fx, 0, GENERIC, xn, st_fx->clip_var_fx, sub( shift_wsp, 1 ) ); /* Q0 */ /*-----------------------------------------------------------------* * LP filtering of the adaptive excitation, codebook target computation *-----------------------------------------------------------------*/ - lp_flag = st_fx->acelp_cfg.ltf_mode; - lp_select = lp_filt_exc_enc_ivas_fx( MODE1, GENERIC, 0, exc, h1, xn, y1, xn2, L_SUBFR, L_frame, g_corr, clip_gain, &gain_pit, &lp_flag ); + lp_flag = st_fx->acelp_cfg.ltf_mode; /* Q0 */ + Scale_sig( h1, L_SUBFR, sub( 14, q_h1 ) ); /* set h1[] in Q14 with scaling for convolution Q14+shift*/ + lp_select = lp_filt_exc_enc_ivas_fx( MODE1, GENERIC, 0, exc, h1, xn, y1, xn2, L_SUBFR, L_frame, g_corr, clip_gain, &gain_pit, &lp_flag ); /* Q0 */ IF( EQ_16( lp_flag, NORMAL_OPERATION ) ) { @@ -698,11 +685,11 @@ static void encod_gen_voic_core_switch_ivas_fx( gp_clip_test_gain_pit_fx( st_fx->element_mode, core_bitrate, gain_pit, st_fx->clip_var_fx ); Lgcode = L_shl( gain_code, Q_new ); /* scaled gain_code with Qnew -> Q16*/ - gcode16 = round_fx( Lgcode ); + gcode16 = round_fx( Lgcode ); /* Q0 */ // hLPDmem->tilt_code = Est_tilt2( exc + 0, gain_pit, code, gain_code, &voice_fac, shift ); // Q_new or shift ?? ->Qexc - hLPDmem->tilt_code = est_tilt_ivas_fx( exc + 0, gain_pit, code, gain_code, &voice_fac, Q_new, L_SUBFR, 0 ); + hLPDmem->tilt_code = est_tilt_ivas_fx( exc + 0, gain_pit, code, gain_code, &voice_fac, Q_new, L_SUBFR, 0 ); /* Q15 */ move16(); /*-----------------------------------------------------------------* * Construct adaptive part of the excitation @@ -711,18 +698,11 @@ static void encod_gen_voic_core_switch_ivas_fx( FOR( i = 0; i < L_SUBFR; i++ ) { /* code in Q9, gain_pit in Q14 */ - L_tmp = L_mult( gcode16, code[i] ); -#ifdef BASOP_NOGLOB - L_tmp = L_shl_sat( L_tmp, 5 ); + L_tmp = L_mult( gcode16, code[i] ); /* Q10 */ + L_tmp = L_shl_sat( L_tmp, 5 ); /* Q15 */ L_tmp = L_mac_sat( L_tmp, exc[i], gain_pit ); - L_tmp = L_shl_sat( L_tmp, 1 ); /* saturation can occur here */ - exc[i] = round_fx_sat( L_tmp ); -#else - L_tmp = L_shl( L_tmp, 5 ); - L_tmp = L_mac( L_tmp, exc[i], gain_pit ); - L_tmp = L_shl( L_tmp, 1 ); /* saturation can occur here */ - exc[i] = round_fx( L_tmp ); -#endif + L_tmp = L_shl_sat( L_tmp, 1 ); /* saturation can occur here */ + exc[i] = round_fx_sat( L_tmp ); /* Q_exc */ move16(); } @@ -740,11 +720,7 @@ static void encod_gen_voic_core_switch_ivas_fx( FOR( i = L_SUBFR; i < 2 * L_SUBFR; i++ ) { -#ifdef BASOP_NOGLOB - exc[i] = round_fx_sat( L_shl_sat( L_mult_sat( exc[i], gain_pit ), 1 ) ); -#else - exc[i] = round_fx( L_shl( L_mult( exc[i], gain_pit ), 1 ) ); -#endif + exc[i] = round_fx_sat( L_shl_sat( L_mult_sat( exc[i], gain_pit ), 1 ) ); /* Q_exc */ move16(); } @@ -780,45 +756,47 @@ static void bwe_switch_enc_fx( BSTR_ENC_HANDLE hBstr; #ifdef BASOP_NOGLOB_DECLARE_LOCAL Flag Overflow = 0; + move32(); #endif hBstr = st_fx->hBstr; L = NS2SA_FX2( st_fx->input_Fs, FRAME_SIZE_NS ); /* set multiplication factor according to the sampling rate */ - tmp = extract_l( L_shr( st_fx->input_Fs, 14 ) ); - delta_fx = add( tmp, 1 ); + tmp = extract_l( L_shr( st_fx->input_Fs, 14 ) ); /* Q0 */ + delta_fx = add( tmp, 1 ); /* Q0 */ Fs_kHz = shl( delta_fx, 4 ); tmp = add( tmp, i_mult2( 3, ( sub( st_fx->last_L_frame, L_FRAME ) != 0 ) ) ); - ptmp = fpointers_tab[tmp]; + ptmp = fpointers_tab[tmp]; /* Q15 */ move16(); - hp_filter_fx = ptmp; - fdelay_fx = i_mult2( 16, delta_fx ); + hp_filter_fx = ptmp; /* Q15 */ + fdelay_fx = i_mult2( 16, delta_fx ); /* Q0 */ IF( EQ_16( st_fx->last_L_frame, L_FRAME ) ) { - fdelay_fx = i_mult2( 20, delta_fx ); + fdelay_fx = i_mult2( 20, delta_fx ); /* Q0 */ } - n = i_mult2( N16_CORE_SW, delta_fx ); + n = i_mult2( N16_CORE_SW, delta_fx ); /* Q0 */ set16_fx( tmp_mem_fx, 0, 2 * L_FILT48k ); set16_fx( tmp_mem2_fx, 0, 2 * L_FILT48k ); - Loverlapp_fx = i_mult2( delta_fx, SWITCH_OVERLAP_8k * 2 ); - gapsize_fx = i_mult2( delta_fx, NS2SA( 16000, SWITCH_GAP_LENGTH_NS ) ); + Loverlapp_fx = i_mult2( delta_fx, SWITCH_OVERLAP_8k * 2 ); /* Q0 */ + gapsize_fx = i_mult2( delta_fx, NS2SA( 16000, SWITCH_GAP_LENGTH_NS ) ); /* Q0 */ shift = sub( add( add( shr( L, 1 ), n ), Loverlapp_fx ), gapsize_fx ); - Copy( new_speech_fx + shift, synth_subfr_bwe_fx, add( gapsize_fx, fdelay_fx ) ); - Copy( new_speech_fx + sub( shift, fdelay_fx ), tmp_mem_fx, fdelay_fx ); + Copy( new_speech_fx + shift, synth_subfr_bwe_fx, add( gapsize_fx, fdelay_fx ) ); /* Q0 */ + Copy( new_speech_fx + sub( shift, fdelay_fx ), tmp_mem_fx, fdelay_fx ); /* Q0 */ - tmp = add( gapsize_fx, fdelay_fx ); - fir_fx( synth_subfr_bwe_fx, hp_filter_fx, synth_subfr_bwe_fx, tmp_mem_fx, tmp, fdelay_fx, 1, 0 ); - Copy( synth_subfr_bwe_fx + shr( fdelay_fx, 1 ), synth_subfr_bwe_fx, sub( gapsize_fx, shr( fdelay_fx, 1 ) ) ); + tmp = add( gapsize_fx, fdelay_fx ); /* Q0 */ + fir_fx( synth_subfr_bwe_fx, hp_filter_fx, synth_subfr_bwe_fx, tmp_mem_fx, tmp, fdelay_fx, 1, 0 ); /* Q0 */ + Copy( synth_subfr_bwe_fx + shr( fdelay_fx, 1 ), synth_subfr_bwe_fx, sub( gapsize_fx, shr( fdelay_fx, 1 ) ) ); /* Q0 */ - tmp = i_mult2( Fs_kHz, 10 ); + tmp = i_mult2( Fs_kHz, 10 ); /* Q0 */ fir_fx( new_speech_fx, hp_filter_fx, hb_synth_tmp_fx, tmp_mem2_fx, tmp, fdelay_fx, 1, 0 ); - min_sq_cross_fx = L_negate( 1 ); + min_sq_cross_fx = -1; + move32(); Qsq = 0; move16(); min_corr_fx = 0; @@ -828,15 +806,15 @@ static void bwe_switch_enc_fx( d1m_fx = 0; move16(); - maxd1_fx = sub( tmp, add( gapsize_fx, fdelay_fx ) ); + maxd1_fx = sub( tmp, add( gapsize_fx, fdelay_fx ) ); /* Q0 */ IF( EQ_16( delta_fx, 2 ) ) { - maxd1_fx = shr( maxd1_fx, 1 ); + maxd1_fx = shr( maxd1_fx, 1 ); /* Q0 */ } ELSE IF( EQ_16( delta_fx, 3 ) ) { - maxd1_fx = extract_h( L_mult( maxd1_fx, 10923 ) ); + maxd1_fx = extract_h( L_mult( maxd1_fx, 10923 /* 0.333 in Q15 */ ) ); /* Q0 */ } /* find delay */ @@ -870,21 +848,23 @@ static void bwe_switch_enc_fx( push_indice_fx( hBstr, IND_CORE_SWITCHING_AUDIO_DELAY, d1m_fx, AUDIODELAYBITS ); - tmp = add( i_mult2( d1m_fx, delta_fx ), fdelay_fx ); - ptmp = &hb_synth_tmp_fx[tmp]; + tmp = add( i_mult2( d1m_fx, delta_fx ), fdelay_fx ); /* Q0 */ + ptmp = &hb_synth_tmp_fx[tmp]; /* Q0 */ move16(); E1_fx = dotprod_satcont( synth_subfr_bwe_fx, synth_subfr_bwe_fx, 0, 0, &q_tmp1, gapsize_fx, 1 ); E2_fx = dotprod_satcont( ptmp, ptmp, 0, 0, &q_tmp2, gapsize_fx, 1 ); IF( !E1_fx ) { - E1_fx = shl( 1, 14 ); + E1_fx = 1 << 14; + move16(); q_tmp1 = 14; move16(); } IF( !E2_fx ) { - E2_fx = shl( 1, 14 ); + E2_fx = 1 << 14; + move16(); q_tmp2 = 14; move16(); } @@ -893,12 +873,8 @@ static void bwe_switch_enc_fx( L_tmp1 = L_mult( tmp, E2_fx ); /*30-q_tmp1+q_tmp2 */ q_tmp2 = sub( q_tmp1, q_tmp2 ); /*30-q_tmp2 */ L_tmp1 = L_shl( L_tmp1, sub( q_tmp2, 24 ) ); -#ifdef BASOP_NOGLOB - gain_fx = round_fx_o( Isqrt( L_tmp1 ), &Overflow ); /*Q12 */ -#else - gain_fx = round_fx( Isqrt( L_tmp1 ) ); /*Q12 */ -#endif - ind1_fx = usquant_fx( gain_fx, &gain_fx, shr( MINVALUEOFFIRSTGAIN_FX, 1 ), shr( DELTAOFFIRSTGAIN_FX, 4 ), ( 1 << NOOFGAINBITS1 ) ); + gain_fx = round_fx_o( Isqrt( L_tmp1 ), &Overflow ); /*Q12 */ + ind1_fx = usquant_fx( gain_fx, &gain_fx, shr( MINVALUEOFFIRSTGAIN_FX, 1 ), shr( DELTAOFFIRSTGAIN_FX, 4 ), ( 1 << NOOFGAINBITS1 ) ); /* Q0 */ push_indice_fx( hBstr, IND_CORE_SWITCHING_AUDIO_GAIN, ind1_fx, NOOFGAINBITS1 ); return; @@ -1040,11 +1016,7 @@ static void bwe_switch_enc_ivas_fx( L_tmp1 = L_mult( tmp, E2_fx ); /*30-q_tmp1+q_tmp2 */ q_tmp2 = sub( q_tmp1, q_tmp2 ); /*30-q_tmp2 */ L_tmp1 = L_shl( L_tmp1, sub( q_tmp2, 24 ) ); -#ifdef BASOP_NOGLOB gain_fx = round_fx_o( Isqrt( L_tmp1 ), &Overflow ); /*Q12 */ -#else - gain_fx = round_fx( Isqrt( L_tmp1 ) ); /*Q12 */ -#endif ind1_fx = usquant_fx( gain_fx, &gain_fx, shr( MINVALUEOFFIRSTGAIN_FX, 1 ), shr( DELTAOFFIRSTGAIN_FX, 4 ), ( 1 << NOOFGAINBITS1 ) ); push_indice( hBstr, IND_CORE_SWITCHING_AUDIO_GAIN, ind1_fx, NOOFGAINBITS1 ); @@ -1052,7 +1024,15 @@ static void bwe_switch_enc_ivas_fx( } -static Word16 dotprod_satcont( const Word16 *x, const Word16 *y, Word16 qx, Word16 qy, Word16 *qo, Word16 len, Word16 delta ) +static Word16 dotprod_satcont( + const Word16 *x, /* qx */ + const Word16 *y, /* qy */ + Word16 qx, + Word16 qy, + Word16 *qo, + Word16 len, /* Q0 */ + Word16 delta /* Q0 */ +) { Word16 tmp_tabx[L_FRAME48k], tmp_taby[L_FRAME48k]; Word16 shift, q, ener, i; @@ -1061,8 +1041,8 @@ static Word16 dotprod_satcont( const Word16 *x, const Word16 *y, Word16 qx, Word Flag Overflow = 0; #endif - Copy( x, tmp_tabx, len ); - Copy( y, tmp_taby, len ); + Copy( x, tmp_tabx, len ); /* qx */ + Copy( y, tmp_taby, len ); /* qy */ shift = 0; move16(); DO @@ -1072,20 +1052,16 @@ static Word16 dotprod_satcont( const Word16 *x, const Word16 *y, Word16 qx, Word move16(); FOR( i = 0; i < len; i += delta ) { -#ifdef BASOP_NOGLOB /* Critical Overflow*/ L_tmp = L_mac0_o( L_tmp, tmp_tabx[i], tmp_taby[i], &Overflow ); /*Q(qx+qy-shift) */ -#else /* BASOP_NOGLOB */ - L_tmp = L_mac0( L_tmp, tmp_tabx[i], tmp_taby[i] ); /*Q(qx+qy-shift) */ -#endif } IF( Overflow != 0 ) { FOR( i = 0; i < len; i += delta ) { - tmp_tabx[i] = shr( tmp_tabx[i], 2 ); + tmp_tabx[i] = shr( tmp_tabx[i], 2 ); /* qx - 2 */ move16(); - tmp_taby[i] = shr( tmp_taby[i], 2 ); + tmp_taby[i] = shr( tmp_taby[i], 2 ); /* qx - 2 */ move16(); } shift = add( shift, 4 ); diff --git a/lib_enc/acelp_enc_util.c b/lib_enc/acelp_enc_util.c deleted file mode 100644 index eb574bd70a8cd1b2a23801d28b3bc6442f2644ac..0000000000000000000000000000000000000000 --- a/lib_enc/acelp_enc_util.c +++ /dev/null @@ -1,48 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include "prot.h" -#include "cnst.h" -#include "rom_com.h" -#include "wmc_auto.h" - -/*-------------------------------------------------------------------* - * E_ACELP_toeplitz_mul() - * - * Multiplication of Toeplitz matrix with vector c, such that d = toeplitz(R)*c - *-------------------------------------------------------------------*/ diff --git a/lib_enc/acelp_enc_util_fx.c b/lib_enc/acelp_enc_util_fx.c index 8fb74129723e6127d02c26efde383be94b41d343..181583e91d23686fd8a753128ec344665e4e27a2 100644 --- a/lib_enc/acelp_enc_util_fx.c +++ b/lib_enc/acelp_enc_util_fx.c @@ -34,11 +34,12 @@ * Vector length is L_SUBFR */ Word16 E_ACELP_toeplitz_mul_fx( - const Word16 R[], - const Word16 c[], - Word16 d[], - const Word16 L_subfr, - const Word16 highrate ) + const Word16 R[], /* Q9 */ + const Word16 c[], /* Qx */ + Word16 d[], /* exp(j) */ + const Word16 L_subfr, /* Q0 */ + const Word16 highrate /* Q0 */ +) { static const Word16 step = 4; Word16 k, j, i; @@ -57,26 +58,25 @@ Word16 E_ACELP_toeplitz_mul_fx( L_maxloc = L_deposit_l( 0 ); FOR( i = k; i < L_subfr; i += step ) { - s = L_mult( R[i], c[0] ); + s = L_mult( R[i], c[0] ); /* Q10 + Qx */ FOR( j = 1; j < i; j++ ) { - s = L_mac( s, R[i - j], c[j] ); + s = L_mac( s, R[i - j], c[j] ); /* Q10 + Qx */ } FOR( ; j < L_subfr; j++ ) { - s = L_mac( s, R[j - i], c[j] ); + s = L_mac( s, R[j - i], c[j] ); /* Q10 + Qx */ } y32[i] = s; move32(); s = L_abs( s ); - L_maxloc = L_max( s, L_maxloc ); + L_maxloc = L_max( s, L_maxloc ); /* Q10 + Qx */ } /* tot += 3*max / 8 */ L_maxloc = L_shr( L_maxloc, 2 ); /* Do not warn saturation of L_tot, since its for headroom estimation. */ BASOP_SATURATE_WARNING_OFF_EVS -#ifdef BASOP_NOGLOB L_tot = L_add_sat( L_tot, L_maxloc ); /* +max/4 */ L_maxloc = L_shr( L_maxloc, 1 ); L_tot = L_add_sat( L_tot, L_maxloc ); /* +max/8 */ @@ -89,20 +89,6 @@ Word16 E_ACELP_toeplitz_mul_fx( { L_tot = L_add_sat( L_tot, L_maxloc ); /* +max/16 */ } -#else - L_tot = L_add( L_tot, L_maxloc ); /* +max/4 */ - L_maxloc = L_shr( L_maxloc, 1 ); - L_tot = L_add( L_tot, L_maxloc ); /* +max/8 */ - if ( highrate ) - { - L_tot = L_add( L_tot, L_maxloc ); /* +max/8 */ - } - L_maxloc = L_shr( L_maxloc, 1 ); - if ( highrate ) - { - L_tot = L_add( L_tot, L_maxloc ); /* +max/16 */ - } -#endif BASOP_SATURATE_WARNING_ON_EVS } @@ -113,16 +99,16 @@ Word16 E_ACELP_toeplitz_mul_fx( /* Limit exponent to avoid overflows elsewhere. */ j = s_min( sub( norm_l( L_tot ), 4 + 16 ), 15 - 16 ); /* 4 -> 16 x tot */ - Copy_Scale_sig_32_16( y32, d, L_subfr, j ); + Copy_Scale_sig_32_16( y32, d, L_subfr, j ); /* exp(j) */ return j; } void E_ACELP_weighted_code( - const Word16 code[], /* i: code */ - const Word16 H[], /* i: impulse response */ - Word16 Q, /* i: Q format of H */ - Word16 y[] /* o: weighted code */ + const Word16 code[], /* i: code Q9*/ + const Word16 H[], /* i: impulse response Q*/ + Word16 Q, /* i: Q format of H */ + Word16 y[] /* o: weighted code Q9*/ ) { Word16 i, j, k, one, n, nz[L_SUBFR]; @@ -150,8 +136,8 @@ void E_ACELP_weighted_code( set16_fx( y, 0, j ); FOR( k = 0; k < L_SUBFR - j; k++ ) { - L_tmp = L_mult( code[j], H[k] ); - y[j + k] = extract_h( L_shl( L_tmp, Q ) ); + L_tmp = L_mult( code[j], H[k] ); /* Q10 + Q */ + y[j + k] = extract_h( L_shl( L_tmp, Q ) ); /* Q9 */ } FOR( i = 1; i < n; ++i ) @@ -161,16 +147,16 @@ void E_ACELP_weighted_code( FOR( k = 0; k < L_SUBFR - j; k++ ) { L_tmp = L_mult( y[j + k], one ); - L_tmp = L_mac( L_tmp, code[j], H[k] ); - y[j + k] = extract_h( L_shl( L_tmp, Q ) ); + L_tmp = L_mac( L_tmp, code[j], H[k] ); /* Q10 + Q */ + y[j + k] = extract_h( L_shl( L_tmp, Q ) ); /* Q9*/ } } } void E_ACELP_conv( - const Word16 xn2[], /* i */ - const Word16 h2[], /* i */ - Word16 cn2[] /* o */ + const Word16 xn2[], /* i Qx*/ + const Word16 h2[], /* i Q12*/ + Word16 cn2[] /* o Q0*/ ) { Word16 i, k; @@ -182,25 +168,21 @@ void E_ACELP_conv( { /*cn2[k] = xn2[k]; */ Word64 L_tmp_64; - L_tmp_64 = W_deposit32_l( L_mult( xn2[k], 0x800 ) ); + L_tmp_64 = W_deposit32_l( L_mult( xn2[k], 0x800 ) ); /* 4Q11 */ FOR( i = 0; i < k; i++ ) { /*cn2[k]-=cn2[i]*h2[k-i];*/ L_tmp_64 = W_msu0_16_16( L_tmp_64, cn2[i], h2[k - i] ); /*h2 4Q11*/ } - L_tmp = W_sat_l( L_tmp_64 ); -#ifdef BASOP_NOGLOB - cn2[k] = round_fx_o( L_shl_o( L_tmp, 5, &Overflow ), &Overflow ); -#else - cn2[k] = round_fx( L_shl( L_tmp, 5 ) ); -#endif + L_tmp = W_sat_l( L_tmp_64 ); /* 4Q11 */ + cn2[k] = round_fx_o( L_shl_o( L_tmp, 5, &Overflow ), &Overflow ); /* Q0 */ } } -void E_ACELP_conv_ivas( - const Word16 xn2[], /* i */ - const Word16 h2[], /* i */ - Word16 cn2[] /* o */ +void E_ACELP_conv_ivas_fx( + const Word16 xn2[], /* i Qx*/ + const Word16 h2[], /* i Q12*/ + Word16 cn2[] /* o Q0*/ ) { Word16 i, k; @@ -212,27 +194,23 @@ void E_ACELP_conv_ivas( { /*cn2[k] = xn2[k]; */ Word64 L_tmp_64; - L_tmp_64 = W_deposit32_l( L_mult0( xn2[k], 0x800 ) ); + L_tmp_64 = W_deposit32_l( L_mult0( xn2[k], 0x800 ) ); /* 4Q11 */ FOR( i = 0; i < k; i++ ) { /*cn2[k]-=cn2[i]*h2[k-i];*/ L_tmp_64 = W_msu0_16_16( L_tmp_64, cn2[i], h2[k - i] ); /*h2 4Q11*/ } - L_tmp = W_sat_l( L_tmp_64 ); -#ifdef BASOP_NOGLOB - cn2[k] = round_fx_o( L_shl_o( L_tmp, 5, &Overflow ), &Overflow ); -#else - cn2[k] = round_fx( L_shl( L_tmp, 5 ) ); -#endif + L_tmp = W_sat_l( L_tmp_64 ); /* 4Q11 */ + cn2[k] = round_fx_o( L_shl_o( L_tmp, 5, &Overflow ), &Overflow ); /* Q0*/ move16(); } } void E_ACELP_build_code( - Word16 nb_pulse, /* i */ - const Word16 codvec[], /* i */ - const Word16 sign[], /* i */ - Word16 code[], /* o */ - Word16 ind[] /* o */ + Word16 nb_pulse, /* i Q0*/ + const Word16 codvec[], /* i Q0*/ + const Word16 sign[], /* i Q0*/ + Word16 code[], /* o Q9*/ + Word16 ind[] /* o Q0*/ ) { Word16 i, k, val, index, track, tmp, vec[4]; @@ -252,42 +230,42 @@ void E_ACELP_build_code( FOR( k = 0; k < nb_pulse; ++k ) { - i = codvec[k]; /* read pulse position */ + i = codvec[k]; /* read pulse position Q0*/ move16(); - val = sign[i]; /* read sign */ + val = sign[i]; /* read sign Q0*/ move16(); index = shr( i, 2 ); /* pos of pulse (0..15) */ track = s_and( i, 4 - 1 ); /* i % 4; */ - tmp = add( code[i], _1_Q9 ); + tmp = add( code[i], _1_Q9 ); /* Q9 */ if ( val <= 0 ) { - tmp = sub( code[i], _1_Q9 ); + tmp = sub( code[i], _1_Q9 ); /* Q9 */ } - code[i] = tmp; + code[i] = tmp; /* Q9 */ move16(); if ( val <= 0 ) { - index = add( index, 16 ); + index = add( index, 16 ); /* Q0 */ } /* Calculate Current Store Index (we started at -1) so we increment first */ - i = add( vec[track], 1 ); + i = add( vec[track], 1 ); /* Q0 */ /* Save Next Store Index */ - vec[track] = i; + vec[track] = i; /* Q0 */ move16(); - ind[i] = index; + ind[i] = index; /* Q0 */ move16(); } } void E_ACELP_setup_pulse_search_pos( - const PulseConfig *config, /* i: pulse configuration */ - Word16 k, /* i: interation number */ - UWord8 ipos[] /* o: pulse search positions */ + const PulseConfig *config, /* i: pulse configuration */ + Word16 k, /* i: interation number Q0*/ + UWord8 ipos[] /* o: pulse search positions Q0*/ ) { Word16 restpulses, iPulse; @@ -308,30 +286,30 @@ void E_ACELP_setup_pulse_search_pos( /* add tracks from left */ FOR( iPulse = 0; iPulse < restpulses; iPulse++ ) { - ipos[config->nb_pulse - restpulses + iPulse] = (UWord8) iPulse; + ipos[config->nb_pulse - restpulses + iPulse] = (UWord8) iPulse; /* Q0 */ move16(); } /* Put the same track on the next position, because the 1-pulse search * will access it to determine if this could be in any track. */ - ipos[config->nb_pulse] = ipos[config->nb_pulse - 1]; + ipos[config->nb_pulse] = ipos[config->nb_pulse - 1]; /* Q0 */ move16(); BREAK; case TRACKPOS_FIXED_EVEN: /* fixed track positions, odd tracks */ /* odd tracks, switch order for every iteration */ - ipos[config->nb_pulse - restpulses] = (UWord8) s_and( lshl( k, 1 ), 2 ); - move16(); /* 0 for even k, 2 for odd */ - ipos[config->nb_pulse - restpulses + 1] = (UWord8) s_xor( ipos[config->nb_pulse - restpulses], 2 ); - move16(); /* 2 for even k, 0 for odd */ + ipos[config->nb_pulse - restpulses] = (UWord8) s_and( lshl( k, 1 ), 2 ); /* Q0 */ + move16(); /* 0 for even k, 2 for odd */ + ipos[config->nb_pulse - restpulses + 1] = (UWord8) s_xor( ipos[config->nb_pulse - restpulses], 2 ); /* Q0 */ + move16(); /* 2 for even k, 0 for odd */ BREAK; case TRACKPOS_FIXED_TWO: /* two tracks instead of four */ /* Put the next track on the next position, because the 1-pulse search * will access it to determine if this could be in any track. */ - ipos[config->nb_pulse] = (UWord8) s_and( add( ipos[config->nb_pulse - 1], 1 ), 3 ); + ipos[config->nb_pulse] = (UWord8) s_and( add( ipos[config->nb_pulse - 1], 1 ), 3 ); /* Q0 */ move16(); BREAK; default: /* one or three free track positions */ /* copy an extra position from table - 1pulse search will access this */ - ipos[config->nb_pulse] = E_ROM_tipos[add( shl( k, 2 ), config->nb_pulse )]; + ipos[config->nb_pulse] = E_ROM_tipos[add( shl( k, 2 ), config->nb_pulse )]; /* Q0 */ move16(); BREAK; } diff --git a/lib_enc/amr_wb_enc.c b/lib_enc/amr_wb_enc.c deleted file mode 100644 index 6056f600b461d55e0226c5ee5c53648597aabd79..0000000000000000000000000000000000000000 --- a/lib_enc/amr_wb_enc.c +++ /dev/null @@ -1,45 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include "cnst.h" -#include "rom_enc.h" -#include "rom_com.h" -#include "prot.h" -#include "wmc_auto.h" - -#include "prot_fx.h" diff --git a/lib_enc/amr_wb_enc_fx.c b/lib_enc/amr_wb_enc_fx.c index 7b177d99a067b14fa75e57f906fe7c541ac4cb7f..976826949541973f351346dd0a2ef79abe39f42b 100644 --- a/lib_enc/amr_wb_enc_fx.c +++ b/lib_enc/amr_wb_enc_fx.c @@ -25,8 +25,8 @@ void amr_wb_enc_fx( Encoder_State *st, /* i/o: encoder state structure */ - const Word16 input_sp[], /* i : input signal */ - const Word16 n_samples /* i : number of input samples */ + const Word16 input_sp[], /* i : input signal Q0*/ + const Word16 n_samples /* i : number of input samples Q0*/ ) { Word16 i, delay; @@ -95,25 +95,28 @@ void amr_wb_enc_fx( * Initialization *------------------------------------------------------------------*/ - st->L_frame = L_FRAME; + st->L_frame = L_FRAME; /* Q0 */ move16(); - st->gamma = GAMMA1; + st->gamma = GAMMA1; /* Q15 */ move16(); - st->core = AMR_WB_CORE; + st->core = AMR_WB_CORE; /* Q0 */ move16(); - st->core_brate = st->total_brate; + st->core_brate = st->total_brate; /* Q0 */ move16(); - st->input_bwidth = st->last_input_bwidth; + st->input_bwidth = st->last_input_bwidth; /* Q0 */ move16(); - st->bwidth = st->last_bwidth; + st->bwidth = st->last_bwidth; /* Q0 */ move16(); st->coder_type = GENERIC; move16(); input_frame = st->input_frame_fx; move16(); /* frame length of the input signal */ st->extl = -1; + move16(); st->encoderPastSamples_enc = ( L_FRAME * 9 ) / 16; + move16(); st->encoderLookahead_enc = L_LOOK_12k8; + move16(); st->bpf_off = 0; move16(); test(); @@ -140,18 +143,18 @@ void amr_wb_enc_fx( set16_fx( old_inp, 0, L_INP_12k8 ); exc = old_exc + L_EXC_MEM; /* pointer to excitation signal in the current frame */ - Copy( hLPDmem->old_exc, old_exc, L_EXC_MEM ); + Copy( hLPDmem->old_exc, old_exc, L_EXC_MEM ); /* q_lpd_old_exc */ new_inp = old_inp + L_INP_MEM; /* pointer to new samples of the input signal */ inp = new_inp - L_LOOK_12k8; /* pointer to current frame of input signal */ wsp = old_wsp + L_WSP_MEM; /* pointer to current frame of weighted signal */ - Copy( st->old_inp_12k8_fx, old_inp, L_INP_MEM ); - Copy( st->old_wsp_fx, old_wsp, L_WSP_MEM ); + Copy( st->old_inp_12k8_fx, old_inp, L_INP_MEM ); /* exp_old_inp_12k8 */ + Copy( st->old_wsp_fx, old_wsp, L_WSP_MEM ); /* exp(exp_old_wsp) */ - new_inp_16k = old_inp_16k + L_INP_MEM; /* pointer to new samples of the input signal in 16kHz core */ - inp_16k = new_inp_16k - L_LOOK_16k; /* pointer to the current frame of input signal in 16kHz core */ - Copy( st->old_inp_16k_fx, old_inp_16k, L_INP_MEM ); + new_inp_16k = old_inp_16k + L_INP_MEM; /* pointer to new samples of the input signal in 16kHz core */ + inp_16k = new_inp_16k - L_LOOK_16k; /* pointer to the current frame of input signal in 16kHz core */ + Copy( st->old_inp_16k_fx, old_inp_16k, L_INP_MEM ); /* q_old_inp */ /* in case of switching, reset AMR-WB BWE memories */ test(); @@ -167,14 +170,14 @@ void amr_wb_enc_fx( /* get delay to synchronize ACELP and MDCT frame */ delay = NS2SA_FX2( st->input_Fs, DELAY_FIR_RESAMPL_NS ); - Copy( st->input_fx - delay, st->old_input_signal_fx, input_frame + delay ); + Copy( st->input_fx - delay, st->old_input_signal_fx, input_frame + delay ); /* q_inp */ /*----------------------------------------------------------------* * Buffering of input signal * HP filtering *----------------------------------------------------------------*/ - Copy( input_sp, st->input_fx, n_samples ); + Copy( input_sp, st->input_fx, n_samples ); /* Q0 */ FOR( i = n_samples; i < input_frame; i++ ) { st->input_fx[i] = 0; @@ -195,25 +198,25 @@ void amr_wb_enc_fx( /* in case of switching, do not apply BPF */ st->bpf_off = 1; move16(); - st->rate_switching_reset = lsp_convert_poly_fx( st->lsp_old_fx, L_FRAME, 1 ); + st->rate_switching_reset = lsp_convert_poly_fx( st->lsp_old_fx, L_FRAME, 1 ); /* Q0 */ /* convert old quantized LSF vector */ lsp2lsf_fx( st->lsp_old_fx, st->lsf_old_fx, M, INT_FS_FX ); /* Reset LPC mem */ - Copy( GEWB_Ave_fx, st->mem_AR_fx, M ); + Copy( GEWB_Ave_fx, st->mem_AR_fx, M ); /* x2.56 */ set16_fx( st->mem_MA_fx, 0, M ); /* update synthesis filter memories */ synth_mem_updt2( L_FRAME, st->last_L_frame, hLPDmem->old_exc, hLPDmem->mem_syn_r, hLPDmem->mem_syn1_fx, hLPDmem->mem_syn, ENC ); - Copy( hLPDmem->mem_syn1_fx, hLPDmem->mem_syn2, M ); + Copy( hLPDmem->mem_syn1_fx, hLPDmem->mem_syn2, M ); /* q_mem_syn */ - Copy( hLPDmem->old_exc, old_exc, L_EXC_MEM ); - Copy( hLPDmem->mem_syn2, hLPDmem->mem_syn3, M ); + Copy( hLPDmem->old_exc, old_exc, L_EXC_MEM ); /* q_lpd_old_exc */ + Copy( hLPDmem->mem_syn2, hLPDmem->mem_syn3, M ); /* q_mem_syn */ /* lsp -> isp */ Copy( stable_ISP_fx, isp_tmp, M ); - lsp2isp_fx( st->lsp_old_fx, st->lsp_old_fx, isp_tmp, M ); + lsp2isp_fx( st->lsp_old_fx, st->lsp_old_fx, isp_tmp, M ); /* Q15 */ } /* update buffer of old subframe pitch values */ @@ -223,17 +226,17 @@ void amr_wb_enc_fx( IF( EQ_16( st->last_L_frame, L_FRAME32k ) ) { /* (float)12800/(float)32000; */ - tmp = 13107; + tmp = 13107; /* 0.4 in Q15 */ } ELSE IF( EQ_16( st->last_L_frame, 512 ) ) { /* (float)12800/(float)25600; */ - tmp = 16384; + tmp = 16384; /* 0.5 in Q15 */ } ELSE /* st->last_L_frame == L_FRAME16k */ { /* (float)12800/(float)16000; */ - tmp = 26214; + tmp = 26214; /* 0.8 in Q15 */ } FOR( i = NB_SUBFR16k - NB_SUBFR; i < NB_SUBFR16k; i++ ) @@ -252,7 +255,7 @@ void amr_wb_enc_fx( test(); if ( EQ_16( st->last_bwidth, NB ) && st->ini_frame != 0 ) { - st->rate_switching_reset = 1; + st->rate_switching_reset = 1; /* Q0 */ move16(); } @@ -263,8 +266,8 @@ void amr_wb_enc_fx( modify_Fs_fx( st->input_fx, input_frame, st->input_Fs, new_inp, 12800, st->mem_decim_fx, 0, &Q_new_inp, &mem_decim_size ); /* update signal buffer */ - Copy( new_inp, st->buf_speech_enc + L_FRAME, L_FRAME ); - Scale_sig( st->buf_speech_enc + L_FRAME, L_FRAME, 1 ); + Copy( new_inp, st->buf_speech_enc + L_FRAME, L_FRAME ); /* Q0 */ + Scale_sig( st->buf_speech_enc + L_FRAME, L_FRAME, 1 ); /* Q1 */ /*------------------------------------------------------------------* * Perform fixed preemphasis through 1 - g*z^-1 @@ -273,7 +276,6 @@ void amr_wb_enc_fx( Preemph_scaled( new_inp, &Q_new, &st->mem_preemph_fx, st->Q_max, PREEMPH_FAC, 0, 1, L_Q_MEM, L_FRAME, st->last_coder_type, 1 ); Q_exp = sub( Q_new, st->Q_old ); - move16(); st->Q_old = Q_new; move16(); @@ -281,7 +283,6 @@ void amr_wb_enc_fx( hNoiseEst->ave_enr2_fx, hNoiseEst->fr_bands1_fx, hNoiseEst->fr_bands2_fx, st->Bin_E_old_fx ); Q_exp = sub( Q_new, st->prev_Q_new ); - move16(); Scale_mem_enc( Q_exp, old_inp_16k, old_exc, hBWE_TD->old_bwe_exc_fx, &( hLPDmem->mem_w0 ), hLPDmem->mem_syn, hLPDmem->mem_syn2, &st->mem_deemp_preQ_fx, hGSCEnc->last_exc_dct_in_fx, hBWE_FD->old_input_lp_fx ); @@ -291,11 +292,7 @@ void amr_wb_enc_fx( * Detect NB spectrum in a 16kHz-sampled input *----------------------------------------------------------------*/ - analy_sp_fx( st->element_mode, -#ifdef IVAS_CODE_CPE - hCPE, -#endif - st->input_Fs, inp, Q_new, fr_bands, lf_E, &Etot, st->min_band, st->max_band, Le_min_scaled, Scale_fac, st->Bin_E_fx, + analy_sp_fx( st->element_mode, inp, Q_new, fr_bands, lf_E, &Etot, st->min_band, st->max_band, Le_min_scaled, Scale_fac, st->Bin_E_fx, st->Bin_E_old_fx, PS, st->lgBin_E_fx, st->band_energies, fft_buff ); noise_est_pre_fx( Etot, st->ini_frame, hNoiseEst, 0, EVS_MONO, EVS_MONO ); @@ -305,7 +302,8 @@ void amr_wb_enc_fx( *----------------------------------------------------------------*/ st->vad_flag = wb_vad_fx( st, fr_bands, &noisy_speech_HO, &clean_speech_HO, &NB_speech_HO, - &snr_sum_he, &localVAD_HE_SAD, &( st->flag_noisy_speech_snr ), Q_new, hVAD, hNoiseEst, st->lp_speech_fx, st->lp_noise_fx ); + &snr_sum_he, &localVAD_HE_SAD, &( st->flag_noisy_speech_snr ), Q_new, hVAD, hNoiseEst, st->lp_speech_fx, st->lp_noise_fx ); /* Q0 */ + move16(); if ( st->vad_flag == 0 ) { @@ -322,12 +320,13 @@ void amr_wb_enc_fx( IF( NE_16( st->last_core, AMR_WB_CORE ) ) { - st->fd_cng_reset_flag = 1; + st->fd_cng_reset_flag = 1; /* Q0 */ move16(); } ELSE IF( s_and( ( st->fd_cng_reset_flag > 0 ), (Word16) ( LT_16( st->fd_cng_reset_flag, 10 ) ) ) ) { - st->fd_cng_reset_flag = add( st->fd_cng_reset_flag, 1 ); + st->fd_cng_reset_flag = add( st->fd_cng_reset_flag, 1 ); /* Q0 */ + move16(); } ELSE { @@ -348,36 +347,27 @@ void amr_wb_enc_fx( high_lpn_flag = 0; move16(); /* Q0 flag */ - long_enr_fx( st, Etot, localVAD_HE_SAD, high_lpn_flag -#ifdef IVAS_CODE - , - NULL, 1, NULL, NULL -#endif - ); + long_enr_fx( st, Etot, localVAD_HE_SAD, high_lpn_flag ); relE = sub( Etot, st->lp_speech_fx ); /* Q8 */ IF( NE_16( st->bwidth, NB ) ) { - lp_bckr = Mean32( hNoiseEst->bckr_fx, 10 ); + lp_bckr = Mean32( hNoiseEst->bckr_fx, 10 ); /* q_bckr */ } ELSE { - lp_bckr = Mean32( hNoiseEst->bckr_fx + 1, 9 ); + lp_bckr = Mean32( hNoiseEst->bckr_fx + 1, 9 ); /* q_bckr */ } -#ifdef BASOP_NOGLOB - hp_bckr = L_shr( L_add_sat( hNoiseEst->bckr_fx[st->max_band - 1], hNoiseEst->bckr_fx[st->max_band] ), 1 ); -#else - hp_bckr = L_shr( L_add( hNoiseEst->bckr_fx[st->max_band - 1], hNoiseEst->bckr_fx[st->max_band] ), 1 ); -#endif - if ( hp_bckr == 0 ) /* Avoid division by zero. */ + hp_bckr = L_shr( L_add_sat( hNoiseEst->bckr_fx[st->max_band - 1], hNoiseEst->bckr_fx[st->max_band] ), 1 ); /* q_bckr */ + if ( hp_bckr == 0 ) /* Avoid division by zero. */ { hp_bckr = L_deposit_l( 1 ); } - tmp = BASOP_Util_Divide3232_Scale( lp_bckr, hp_bckr, &e_tmp ); + tmp = BASOP_Util_Divide3232_Scale( lp_bckr, hp_bckr, &e_tmp ); /* exp(e_tmp) */ Ltmp = L_shr_r( L_deposit_h( tmp ), sub( 15, e_tmp ) ); - st->bckr_tilt_lt = L_add( Mpy_32_16_r( st->bckr_tilt_lt, 29491 ), Mpy_32_16_r( Ltmp, 3277 ) ); + st->bckr_tilt_lt = L_add( Mpy_32_16_r( st->bckr_tilt_lt, 29491 ), Mpy_32_16_r( Ltmp, 3277 ) ); /* Q16 */ - corr_shift = correlation_shift_fx( hNoiseEst->totalNoise_fx ); + corr_shift = correlation_shift_fx( hNoiseEst->totalNoise_fx ); /* Q15 */ /*----------------------------------------------------------------* * WB, SWB and FB bandwidth detector @@ -404,7 +394,7 @@ void amr_wb_enc_fx( /* reset the OL pitch tracker memories during inactive frames */ pitch_ol_init_fx( &st->old_thres_fx, &st->old_pitch, &st->delta_pit, &st->old_corr_fx ); } - old_pitch1 = st->pitch[1]; + old_pitch1 = st->pitch[1]; /* Q0 */ move16(); analy_lp_AMR_WB_fx( inp, &ener, A, epsP_h, epsP_l, isp_new, st->lsp_old1_fx, isf_new, st->old_pitch_la, st->old_voicing_la, Q_new, Q_r ); @@ -427,9 +417,9 @@ void amr_wb_enc_fx( move16(); } pitch_ol_fx( st->pitch, st->voicing_fx, &st->old_pitch, &st->old_corr_fx, corr_shift, &st->old_thres_fx, &st->delta_pit, st->old_wsp2_fx, wsp, st->mem_decim2_fx, relE, 0, st->bwidth, st->Opt_SC_VBR ); - st->old_pitch_la = st->pitch[2]; + st->old_pitch_la = st->pitch[2]; /* Q0 */ move16(); - st->old_voicing_la = st->voicing_fx[2]; + st->old_voicing_la = st->voicing_fx[2]; /* Q15 */ move16(); /* VAD parameters update */ @@ -442,9 +432,6 @@ void amr_wb_enc_fx( noise_est_fx( st, old_pitch1, tmpN, epsP_h, epsP_l, Etot, relE, corr_shift, tmpE, fr_bands, &cor_map_sum, NULL, &sp_div, &Q_sp_div, &non_staX, &harm_flag, lf_E, &hNoiseEst->harm_cor_cnt, hNoiseEst->Etot_l_lp_fx, hNoiseEst->Etot_v_h2_fx, &hNoiseEst->bg_cnt, st->lgBin_E_fx, Q_new, Le_min_scaled, &sp_floor, NULL, -#ifdef IVAS_CODE - NULL, NULL, -#endif st->ini_frame ); /*----------------------------------------------------------------* @@ -456,7 +443,7 @@ void amr_wb_enc_fx( IF( EQ_32( st->input_Fs, 16000 ) ) { /* no resampling needed, only delay adjustement to account for the FIR resampling delay */ - tmps = NS2SA_FX2( 16000, DELAY_FIR_RESAMPL_NS ); + tmps = NS2SA( 16000, DELAY_FIR_RESAMPL_NS ); Copy_Scale_sig( &st->mem_decim16k_fx[tmps], new_inp_16k, tmps, -1 ); /* Input in Q0 -> Output in Q-1 to mimic the resampling filter */ Copy_Scale_sig( st->input_fx, new_inp_16k + tmps, sub( input_frame, tmps ), -1 ); /* Input in Q0 -> Output in Q-1 to mimic the resampling filter */ Copy( st->input_fx + input_frame - shl( tmps, 1 ), st->mem_decim16k_fx, shl( tmps, 1 ) ); /* memory still in Q0 */ @@ -495,16 +482,16 @@ void amr_wb_enc_fx( CNG_reset_enc_fx( st, hLPDmem, pitch_buf, dummy_buf + L_FRAME, 0 ); /* update st->mem_syn1 for ACELP core switching */ - Copy( hLPDmem->mem_syn3, hLPDmem->mem_syn1_fx, M ); + Copy( hLPDmem->mem_syn3, hLPDmem->mem_syn1_fx, M ); /* q_mem_syn */ /* update ACELP core synthesis filter memory */ - Copy( hLPDmem->mem_syn3, hLPDmem->mem_syn, M ); + Copy( hLPDmem->mem_syn3, hLPDmem->mem_syn, M ); /* q_mem_syn */ /* update old synthesis buffer - needed for ACELP internal sampling rate switching */ - Copy( dummy_buf + L_FRAME - L_SYN_MEM, hLPDmem->mem_syn_r, L_SYN_MEM ); + Copy( dummy_buf + L_FRAME - L_SYN_MEM, hLPDmem->mem_syn_r, L_SYN_MEM ); /* st->Q_syn */ /* Update MODE2 core switching memory */ E_UTIL_deemph2( sub( Q_new, 1 ), dummy_buf, PREEMPH_FAC, L_FRAME, &( hLPDmem->syn[M] ) ); - Copy( dummy_buf + L_FRAME - M - 1, hLPDmem->syn, M + 1 ); + Copy( dummy_buf + L_FRAME - M - 1, hLPDmem->syn, M + 1 ); /* st->Q_syn */ } /*----------------------------------------------------------------* @@ -519,7 +506,7 @@ void amr_wb_enc_fx( test(); IF( EQ_32( st->last_core_brate, FRAME_NO_DATA ) || EQ_32( st->last_core_brate, SID_1k75 ) ) { - Copy( hDtxEnc->lspCNG_fx, st->lsp_old_fx, M ); + Copy( hDtxEnc->lspCNG_fx, st->lsp_old_fx, M ); /* Q15 */ E_LPC_isp_isf_conversion( hDtxEnc->lspCNG_fx, st->lsf_old_fx, M ); set16_fx( old_exc, 0, L_EXC_MEM ); } @@ -549,14 +536,14 @@ void amr_wb_enc_fx( encod_amr_wb_fx( st, inp, Aw, Aq, res, syn, exc, exc2, pitch_buf, hf_gain_fx, inp_16k, shift, Q_new ); /* update st->mem_syn1 for ACELP core switching */ - Copy( hLPDmem->mem_syn, hLPDmem->mem_syn1_fx, M ); + Copy( hLPDmem->mem_syn, hLPDmem->mem_syn1_fx, M ); /* st->q_mem_syn */ /* update old synthesis buffer - needed for ACELP internal sampling rate switching */ - Copy( syn + L_FRAME - L_SYN_MEM, hLPDmem->mem_syn_r, L_SYN_MEM ); + Copy( syn + L_FRAME - L_SYN_MEM, hLPDmem->mem_syn_r, L_SYN_MEM ); /* st->Q_syn */ /* Update MODE2 core switching memory */ E_UTIL_deemph2( sub( Q_new, 1 ), syn, PREEMPH_FAC, L_FRAME, &( hLPDmem->syn[M] ) ); - Copy( syn + L_FRAME - M - 1, hLPDmem->syn, M + 1 ); + Copy( syn + L_FRAME - M - 1, hLPDmem->syn, M + 1 ); /* st->Q_syn */ /*--------------------------------------------------------------------------------------* * Write VAD information into the bitstream in AMR-WB IO mode @@ -570,27 +557,27 @@ void amr_wb_enc_fx( *-----------------------------------------------------------------*/ /* update old weighted speech buffer - for OL pitch analysis */ - Copy( &old_wsp[L_FRAME], st->old_wsp_fx, L_WSP_MEM ); + Copy( &old_wsp[L_FRAME], st->old_wsp_fx, L_WSP_MEM ); /* exp(exp_old_wsp) */ /* update old input signal buffer */ - Copy( &old_inp[L_FRAME], st->old_inp_12k8_fx, L_INP_MEM ); + Copy( &old_inp[L_FRAME], st->old_inp_12k8_fx, L_INP_MEM ); /* exp(exp_old_inp_12k8) */ /* update old input signal @16kHz buffer */ IF( GT_32( st->input_Fs, 8000 ) ) { - Copy( &old_inp_16k[L_FRAME16k], st->old_inp_16k_fx, L_INP_MEM ); + Copy( &old_inp_16k[L_FRAME16k], st->old_inp_16k_fx, L_INP_MEM ); /* exp(exp_old_inp_16k) */ } /* update of old per-band energy spectrum */ - Copy32( fr_bands + NB_BANDS, hNoiseEst->enrO_fx, NB_BANDS ); + Copy32( fr_bands + NB_BANDS, hNoiseEst->enrO_fx, NB_BANDS ); /* Q_new */ /* update the last bandwidth */ - st->last_input_bwidth = st->input_bwidth; - st->last_bwidth = st->bwidth; + st->last_input_bwidth = st->input_bwidth; /* Q0 */ + st->last_bwidth = st->bwidth; /* Q0 */ /* update signal buffers */ - Copy( new_inp, st->buf_speech_enc_pe + L_FRAME, L_FRAME ); - Copy( wsp, st->buf_wspeech_enc + L_FRAME + L_SUBFR, L_FRAME + L_LOOK_12k8 ); + Copy( new_inp, st->buf_speech_enc_pe + L_FRAME, L_FRAME ); /* Q0 */ + Copy( wsp, st->buf_wspeech_enc + L_FRAME + L_SUBFR, L_FRAME + L_LOOK_12k8 ); /* exp(exp_buf_wspeech_enc) */ updt_enc_fx( st, old_exc, pitch_buf, 0, Aq, isf_new, isp_new, dummy_buf ); /* update main codec parameters */ @@ -625,7 +612,7 @@ void amr_wb_enc_init_fx( AMRWB_IO_ENC_HANDLE hAmrwb_IO /* i/o: AMR-WB IO encoder handle */ ) { - int16_t i; + Word16 i; /* HF (6-7kHz) BWE */ hAmrwb_IO->seed2_enc = RANDOM_INITSEED; @@ -633,7 +620,7 @@ void amr_wb_enc_init_fx( FOR( i = 0; i < GAIN_PRED_ORDER; i++ ) { - hAmrwb_IO->past_qua_en_fx[i] = -14336; /* Q10gain quantization memory (used also in AMR-WB IO mode) */ + hAmrwb_IO->past_qua_en_fx[i] = -14336; /* Q10 gain quantization memory (used also in AMR-WB IO mode) */ move16(); } diff --git a/lib_enc/analy_lp.c b/lib_enc/analy_lp.c deleted file mode 100644 index 2e657e155b94f2ee095cf1922c203d19c79fa7dc..0000000000000000000000000000000000000000 --- a/lib_enc/analy_lp.c +++ /dev/null @@ -1,54 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include "cnst.h" -#include "rom_com.h" -#include "prot.h" -#include "wmc_auto.h" - -/*-------------------------------------------------------------------* - * analy_lp() - * - * Perform LP analysis - * - * - autocorrelations + lag windowing - * - Levinson-Durbin algorithm to find A(z) - * - convert A(z) to LSPs - * - find interpolated LSPs and convert back to A(z) for all subframes - * - update LSPs for the next frame - *-------------------------------------------------------------------*/ diff --git a/lib_enc/analy_lp_fx.c b/lib_enc/analy_lp_fx.c index dc0e9c545f5edc38ce7b672e543496fa11f70e67..c2f9d0585d356c513226ee2059d219e835976724 100644 --- a/lib_enc/analy_lp_fx.c +++ b/lib_enc/analy_lp_fx.c @@ -63,7 +63,7 @@ void analy_lp_ivas_fx( move16(); wind = assym_window_16k_fx; /*q15*/ } - lsp = lsp_mid; + lsp = lsp_mid; /* Q15 */ half_frame = shr( L_frame, 1 ); FOR( i_subfr = 0; i_subfr <= 1; i_subfr++ ) @@ -105,7 +105,7 @@ void analy_lp_ivas_fx( /* Conversion of A(z) to LSPs */ E_LPC_a_lsp_conversion( A, lsp, lsp_old, M ); - lsp = lsp_new; + lsp = lsp_new; /* Q15 */ } IF( EQ_16( sec_chan_low_rate, 1 ) ) { @@ -117,28 +117,28 @@ void analy_lp_ivas_fx( /* LSP interpolation */ int_lsp4_ivas_fx( L_frame, lsp_old, lsp_mid, lsp_new, A, M, 0 ); } - Copy( lsp_new, lsp_old, M ); - *ener = L_Comp( epsP_h[M], epsP_l[M] ); + Copy( lsp_new, lsp_old, M ); /* Q15 */ + *ener = L_Comp( epsP_h[M], epsP_l[M] ); /* Q_r */ move32(); return; } void analy_lp_fx( - const Word16 speech[], /* i : pointer to the speech frame */ - const Word16 L_frame, /* i : length of the frame */ - const Word16 L_look, /* i : look-ahead */ - Word32 *ener, /* o : residual energy from Levinson-Durbin */ - Word16 A[], /* o : A(z) filter coefficients */ - Word16 epsP_h[], /* o : LP analysis residual energies for each iteration */ - Word16 epsP_l[], /* o : LP analysis residual energies for each iteration */ - Word16 lsp_new[], /* o : current frame LSPs */ - Word16 lsp_mid[], /* o : current mid-frame LSPs */ - Word16 lsp_old[], /* i/o: previous frame unquantized LSPs */ - const Word16 Top[2], /* i : open loop pitch lag */ - const Word16 Tnc[2], /* i : open loop pitch gain */ - const Word32 Core_sr, /* i : Internal core sampling rate */ - const Word16 sec_chan_low_rate, /* i : flag to signal second channel */ + const Word16 speech[], /* i : pointer to the speech frame Q_new*/ + const Word16 L_frame, /* i : length of the frame Q0*/ + const Word16 L_look, /* i : look-ahead Q0*/ + Word32 *ener, /* o : residual energy from Levinson-Durbin Q_r*/ + Word16 A[], /* o : A(z) filter coefficients Q14*/ + Word16 epsP_h[], /* o : LP analysis residual energies for each iteration Q_r*/ + Word16 epsP_l[], /* o : LP analysis residual energies for each iteration Q_r*/ + Word16 lsp_new[], /* o : current frame LSPs Q15*/ + Word16 lsp_mid[], /* o : current mid-frame LSPs Q15*/ + Word16 lsp_old[], /* i/o: previous frame unquantized LSPs Q15*/ + const Word16 Top[2], /* i : open loop pitch lag Q0*/ + const Word16 Tnc[2], /* i : open loop pitch gain Q15*/ + const Word32 Core_sr, /* i : Internal core sampling rate Q0*/ + const Word16 sec_chan_low_rate, /* i : flag to signal second channel Q0*/ Word16 Q_new, Word16 *Q_r ) { @@ -155,15 +155,15 @@ void analy_lp_fx( { wind_length = L_LP; move16(); - wind = Assym_window_W16fx; + wind = Assym_window_W16fx; /* Q15 */ } ELSE /* L_frame == L_FRAME16k */ { wind_length = L_LP_16k; move16(); - wind = assym_window_16k_fx; + wind = assym_window_16k_fx; /* Q15 */ } - lsp = lsp_mid; + lsp = lsp_mid; /* Q15 */ half_frame = shr( L_frame, 1 ); FOR( i_subfr = 0; i_subfr <= 1; i_subfr++ ) @@ -190,7 +190,7 @@ void analy_lp_fx( /* Conversion of A(z) to LSPs */ E_LPC_a_lsp_conversion( A, lsp, lsp_old, M ); - lsp = lsp_new; + lsp = lsp_new; /* Q15 */ } IF( EQ_16( sec_chan_low_rate, 1 ) ) { @@ -202,8 +202,8 @@ void analy_lp_fx( /* LSP interpolation */ int_lsp4_fx( L_frame, lsp_old, lsp_mid, lsp_new, A, M, 0 ); } - Copy( lsp_new, lsp_old, M ); - *ener = L_Comp( epsP_h[M], epsP_l[M] ); + Copy( lsp_new, lsp_old, M ); /* Q15 */ + *ener = L_Comp( epsP_h[M], epsP_l[M] ); /* Q_r */ move32(); return; @@ -223,16 +223,16 @@ void analy_lp_fx( *-------------------------------------------------------------------*/ void analy_lp_AMR_WB_fx( - const Word16 speech[], /* i : pointer to the speech frame */ - Word32 *ener, /* o : residual energy from Levinson-Durbin */ - Word16 A[], /* o : A(z) filter coefficients */ - Word16 epsP_h[], /* o : LP analysis residual energies for each iteration */ - Word16 epsP_l[], /* o : LP analysis residual energies for each iteration */ - Word16 isp_new[], /* o : current frame ISPs */ - Word16 isp_old[], /* i/o: previous frame unquantized ISPs */ - Word16 isf_new[], /* o : current frame ISPs */ - Word16 Top, /* i : open loop pitch lag */ - Word16 Tnc, /* i : open loop pitch gain */ + const Word16 speech[], /* i : pointer to the speech frame Q_new*/ + Word32 *ener, /* o : residual energy from Levinson-Durbin Q_r*/ + Word16 A[], /* o : A(z) filter coefficients Q14*/ + Word16 epsP_h[], /* o : LP analysis residual energies for each iteration Q_r*/ + Word16 epsP_l[], /* o : LP analysis residual energies for each iteration Q_r*/ + Word16 isp_new[], /* o : current frame ISPs Q15*/ + Word16 isp_old[], /* i/o: previous frame unquantized ISPs Q15*/ + Word16 isf_new[], /* o : current frame ISPs Q15*/ + Word16 Top, /* i : open loop pitch lag Q0*/ + Word16 Tnc, /* i : open loop pitch gain Qx*/ Word16 Q_new, Word16 *Q_r ) { @@ -271,11 +271,11 @@ void analy_lp_AMR_WB_fx( int_lsp_fx( L_FRAME, isp_old, isp_new, A, M, interpol_isp_amr_wb_fx, 1 ); /**ener = epsP[M];*/ - *ener = L_Comp( epsP_h[M], epsP_l[M] ); + *ener = L_Comp( epsP_h[M], epsP_l[M] ); /* Q_r */ move32(); /* updates */ - Copy( isp_new, isp_old, M ); + Copy( isp_new, isp_old, M ); /* Q15 */ return; } diff --git a/lib_enc/analy_sp.c b/lib_enc/analy_sp.c deleted file mode 100644 index 0be76e525dda92b012f35a545e02e2cf42a331ce..0000000000000000000000000000000000000000 --- a/lib_enc/analy_sp.c +++ /dev/null @@ -1,46 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include -#include "cnst.h" -#include "rom_enc.h" -#include "rom_com.h" -#include "prot.h" -#include "wmc_auto.h" -#include -#include "ivas_cnst.h" diff --git a/lib_enc/analy_sp_fx.c b/lib_enc/analy_sp_fx.c index d2e34b0124327ad3d66e2ba6a1d80605d7c9b8e3..185bac26bc7847ecd023228e95a204404ee2b044 100644 --- a/lib_enc/analy_sp_fx.c +++ b/lib_enc/analy_sp_fx.c @@ -18,11 +18,8 @@ *-------------------------------------------------------------------*/ static void find_enr( Word16 data[], Word32 band[], Word32 *ptE, Word32 *LEtot, const Word16 min_band, const Word16 max_band, const Word16 Q_new2, const Word32 e_min, Word32 *Bin_E, Word16 BIN_FREQ_FX, Word32 *band_energies ); -static void ivas_find_enr( Word16 data[], Word32 band[], Word32 *ptE, Word32 *LEtot, const Word16 min_band, const Word16 max_band, const Word16 Q_new2, const Word32 e_min, Word32 *Bin_E, Word16 BIN_FREQ_FX, Word32 *band_energies ); -static void ivas_find_enr1( Word16 *data, Word16 q_data, Word32 *band, Word32 *ptE, Word32 *LEtot, const Word16 min_band, const Word16 max_band, const Word16 Q_new, const Word32 e_min, Word32 *Bin_E, Word16 BIN_FREQ_FX, Word32 *band_energies ); -#ifdef IVAS_CODE_CPE -static void find_enr_dft( CPE_ENC_HANDLE hCPE, const int32_t input_Fs, float DFT_past_DMX[], float band[], float *ptE, float *Etot, const int16_t min_band, const int16_t max_band, float *Bin_E, float *band_ener ); -#endif +static void ivas_find_enr( Word16 *data, Word16 q_data, Word32 *band, Word16 *q_band, Word32 *ptE, Word16 *q_ptE, Word64 *LEtot, const Word16 min_band, const Word16 max_band, Word32 *Bin_E, Word16 BIN_FREQ_FX, Word32 *band_energies ); + /*-------------------------------------------------------------------* * analy_sp_fx() @@ -32,10 +29,6 @@ static void find_enr_dft( CPE_ENC_HANDLE hCPE, const int32_t input_Fs, float DFT void analy_sp_fx( const Word16 element_mode, /* i : element mode */ -#ifdef IVAS_CODE_CPE - CPE_ENC_HANDLE hCPE, /* i/o: CPE encoder structure */ -#endif - const Word32 input_Fs, /* i : input sampling rate */ Word16 *speech, /* i : speech buffer Q_new - preemph_bits */ const Word16 Q_new, /* i : current scaling exp Q0 */ Word32 *fr_bands, /* o : energy in critical frequency bands Q_new + QSCALE */ @@ -61,52 +54,58 @@ void analy_sp_fx( Word16 Min_val, Max_val; Word16 Scale_fac2; Word16 fft_temp[L_FFT]; -#ifndef IVAS_CODE_CPE - (void) input_Fs; -#endif + /*-----------------------------------------------------------------* * Compute spectrum * find energy per critical frequency band and total energy in dB *-----------------------------------------------------------------*/ - pt_bands = fr_bands; + pt_bands = fr_bands; /* Q_new + QSCALE */ pt_fft = fft_buff; LEtot = L_deposit_l( 0 ); IF( NE_16( element_mode, IVAS_CPE_DFT ) ) { FOR( i_subfr = 0; i_subfr <= 1; i_subfr++ ) { - pt = speech + 3 * ( L_SUBFR / 2 ) - L_FFT / 2; + pt = speech + 3 * ( L_SUBFR / 2 ) - L_FFT / 2; /* Q_new - preemph_bits */ if ( i_subfr != 0 ) { - pt = speech + 7 * ( L_SUBFR / 2 ) - L_FFT / 2; + pt = speech + 7 * ( L_SUBFR / 2 ) - L_FFT / 2; /* Q_new - preemph_bits */ } /* Clear 1st value of 1st part, copy 1st value of 2nd part */ fft_temp[0] = 0; move16(); - fft_temp[L_FFT / 2] = pt[L_FFT / 2]; + fft_temp[L_FFT / 2] = pt[L_FFT / 2]; /* Q_new - preemph_bits */ move16(); - Max_val = s_max( fft_temp[0], fft_temp[L_FFT / 2] ); - Min_val = s_min( fft_temp[0], fft_temp[L_FFT / 2] ); + Max_val = s_max( fft_temp[0], fft_temp[L_FFT / 2] ); /* Q_new - preemph_bits */ + Min_val = s_min( fft_temp[0], fft_temp[L_FFT / 2] ); /* Q_new - preemph_bits */ FOR( i = 1; i < L_FFT / 2; i++ ) { /* 1st windowed part */ - fft_temp[i] = mult_r( pt[i], sqrt_han_window_fx[i] ); + fft_temp[i] = mult_r( pt[i], sqrt_han_window_fx[i] ); /* Q_new - preemph_bits */ move16(); - if ( fft_temp[i] > 0 ) - Max_val = s_max( Max_val, fft_temp[i] ); - if ( fft_temp[i] < 0 ) - Min_val = s_min( Min_val, fft_temp[i] ); + IF( fft_temp[i] > 0 ) + { + Max_val = s_max( Max_val, fft_temp[i] ); /* Q_new - preemph_bits */ + } + IF( fft_temp[i] < 0 ) + { + Min_val = s_min( Min_val, fft_temp[i] ); /* Q_new - preemph_bits */ + } /* 2nd windowed part */ - fft_temp[L_FFT - i] = mult_r( pt[L_FFT - i], sqrt_han_window_fx[i] ); + fft_temp[L_FFT - i] = mult_r( pt[L_FFT - i], sqrt_han_window_fx[i] ); /* Q_new - preemph_bits */ move16(); - if ( fft_temp[L_FFT - i] > 0 ) - Max_val = s_max( Max_val, fft_temp[L_FFT - i] ); - if ( fft_temp[L_FFT - i] < 0 ) - Min_val = s_min( Min_val, fft_temp[L_FFT - i] ); + IF( fft_temp[L_FFT - i] > 0 ) + { + Max_val = s_max( Max_val, fft_temp[L_FFT - i] ); /* Q_new - preemph_bits */ + } + IF( fft_temp[L_FFT - i] < 0 ) + { + Min_val = s_min( Min_val, fft_temp[L_FFT - i] ); /* Q_new - preemph_bits */ + } } /* Combine -Min_val and Max_val into one */ @@ -115,7 +114,7 @@ void analy_sp_fx( Scale_fac[i_subfr] = s_min( sub( norm_s( Max_val ), 1 ), 6 ); move16(); Scale_fac2 = shl( Scale_fac[i_subfr], 1 ); - Scale_sig( fft_temp, L_FRAME_12k8, Scale_fac[i_subfr] ); + Scale_sig( fft_temp, L_FRAME_12k8, Scale_fac[i_subfr] ); /* Q_new - preemph_bits + Scale_fac */ r_fft_fx_lc( FFT_W128, SIZE_256, SIZE2_256, NUM_STAGE_256, fft_temp, pt_fft, 1 ); @@ -127,18 +126,6 @@ void analy_sp_fx( pt_fft += L_FFT; } } -#ifdef IVAS_CODE_CPE - ELSE - { - /* find energy per critical band */ - find_enr_dft( hCPE, input_Fs, hCPE->hStereoDft->DFT[0], pt_bands, lf_E, Etot, min_band, max_band, Bin_E, band_ener ); - mvr2r( lf_E, lf_E + VOIC_BINS, VOIC_BINS ); - mvr2r( Bin_E, Bin_E + ( L_FFT / 2 ), L_FFT / 2 ); - mvr2r( band_ener, band_ener + NB_BANDS, NB_BANDS ); - mvr2r( pt_bands, pt_bands + NB_BANDS, NB_BANDS ); - *Etot *= 2.f; - } -#endif /* Average total log energy over both half-frames */ frac_etot = 0; @@ -153,7 +140,7 @@ void analy_sp_fx( Ltmp = Mpy_32( exp_etot, frac_etot, LG10, 0 ); /*Q8 Averaged the total energy over both half-frames in log10 */ - *Etot = extract_l( L_shr( Ltmp, 14 - 8 ) ); + *Etot = extract_l( L_shr( Ltmp, 14 - 8 ) ); /* Q8 */ Bin_E[L_FFT / 2 - 1] = Bin_E[L_FFT / 2 - 2]; move32(); @@ -187,7 +174,7 @@ void analy_sp_fx( /* -56783L is to substract 0.86643 in Q16 */ /* 28391 is 0.86643 in Q15 */ /* 1774 is (0.86643 in Q15) * 8 / 128 (/128 to go in Q7) */ - EspecdB[i] = mac_r( L_shl( L_msu( L_tmp2, exp, 28391 ), 3 + 7 ), exp_frac, 887 ); + EspecdB[i] = mac_r( L_shl( L_msu( L_tmp2, exp, 28391 ), 3 + 7 ), exp_frac, 887 ); /* Q7 */ move16(); } @@ -201,131 +188,149 @@ void analy_sp_fx( * find input signal energy for each critical band using the DFT buffers *------------------------------------------------------------------------*/ -static void find_enr_dft_fx( - CPE_ENC_HANDLE hCPE, /* i/o: CPE encoder structure */ - const Word32 input_Fs, /* i : input sampling rate */ - Word32 DFT_past_DMX_fx[], /* i:input DFT_Dmx (Q_inp_dmx ) */ - Word32 band_fx[], /* o : per band energy */ - Word32 *ptE_fx, /* o : per bin energy for low frequencies */ - Word32 *Etot_fx, /* i/o: total energy (Q8) */ - const Word16 min_band, /* i : minimum critical band */ - const Word16 max_band, /* i : maximum critical band */ - Word32 *Bin_E_fx, /* o : Per bin energy (Q7) */ - Word32 *band_ener_fx, /* o : per band energy without E_MIN (Qout) */ - Word16 Q_inp_dmx, - Word16 *Qout ) + +static void find_enr_dft_ivas_fx( + CPE_ENC_HANDLE hCPE, /* i/o: CPE encoder structure */ + const Word32 input_Fs, /* i : input sampling rate Q0*/ + Word32 DFT_past_DMX_fx[], /* i :input DFT_Dmx (Q_inp_dmx ) */ + Word32 band_fx[], /* o : per band energy (*q_band) */ + Word16 *q_band, /* o : Q of per band energy */ + Word32 *ptE_fx, /* o : per bin energy for low frequencies (*q_ptE) */ + Word16 *q_ptE, /* o : Q of per bin energy for low frequencies */ + Word64 *Etot_fx, /* i/o: total energy (Q8) */ + const Word16 min_band, /* i : minimum critical band Q0*/ + const Word16 max_band, /* i : maximum critical band Q0*/ + Word32 *Bin_E_fx, /* o : Per bin energy (Q7) */ + Word16 *q_Bin_E, /* o : Q of Per bin energy (*q_band) */ + Word32 *band_ener_fx, /* o : per band energy without E_MIN */ + Word16 Q_inp_dmx ) { - Word16 i, cnt; - Word32 tmp_fx; + Word16 i; + Word64 tot_ener; Word32 freq; const Word32 *ptR_fx, *ptI_fx; - Word32 norm_val_fx; - Word16 bin_cnt = 0; - move16(); - // Word32 band_ener_fx[2 * NB_BANDS]; - // Etot_fx[0] = Etot[0] * ONE_IN_Q8; + Word16 norm_val_fx; + Word16 bin_cnt; Word32 c_fx, s_fx; + Word32 g_fx; + Word32 scaleWin_fx; + Word16 bin_freq; + Word16 temp1, temp2, exp, exp1; + Word16 q_norm_val; + Word32 BinE_fx[STEREO_DFT_N_12k8_ENC / 2]; /* NB_BANDS = 20 (= 6350Hz) = highest band available for SR 12.8 -> bin_cnt = 158 */ + Word32 c_1_fx, s_1_fx, g_1_fx, g_2_fx; + Word64 band_ener; + Word32 BinE, tmp_fx; + Word32 start_freq; + Word32 min_ener; + Word16 shift = 0; + move16(); + /* One window - 40ms*12.8kHz = 512 samples */ - Word32 c_1_fx = 2147321984; // cosf( PI2 / STEREO_DFT_N_12k8_ENC ) * ONE_IN_Q31; - Word32 s_1_fx = 26352928; // sinf( PI2 / STEREO_DFT_N_12k8_ENC ) * ONE_IN_Q31; - Word32 g_1_fx = 1570240000; // ( 1.f + 0.68f * 0.68f ) * ONE_IN_Q30; - Word32 g_2_fx = 1460288896; // 2 * 0.68f * ONE_IN_Q30; + c_1_fx = 1073660991; // 0.999924719 in Q30, cosf( PI2 / STEREO_DFT_N_12k8_ENC ) + s_1_fx = 13176464; // 0.0122715384 in Q30, sinf( PI2 / STEREO_DFT_N_12k8_ENC ) + g_1_fx = 1570240043; // 1.4624 in Q30, ( 1.f + 0.68f * 0.68f ) + g_2_fx = 1460288880; // 1.36 in Q30, 2 * 0.68f move32(); move32(); move32(); move32(); - Word32 g_fx; - Word32 scaleWin_fx; - - Word32 BinE_fx[STEREO_DFT_N_12k8_ENC / 2]; /* NB_BANDS = 20 (= 6350Hz) = highest band available for SR 12.8 -> bin_cnt = 158 */ - Word16 tmp16, scale = 0; - tmp16 = BASOP_Util_Divide3216_Scale( input_Fs, hCPE->hStereoDft->NFFT, &scale ); - tmp16 = shr( tmp16, negate( add( 1, scale ) ) ); - Word16 bin_freq = tmp16; // input_Fs / (float) hCPE->hStereoDft->NFFT; /* adaptive frequency bin width */ - - // scaleWin = 1 / ( 2 * hCPE->hStereoDft->win_ana_energy ); - // scaleWin_fx = ONE_IN_Q31/ ( hCPE->hStereoDft->win_ana_energy_fx ); - scaleWin_fx = BASOP_Util_Divide3216_Scale( ONE_IN_Q31, hCPE->hStereoDft->win_ana_energy_fx, &scale ); // q = 16-scale - Word16 scalewin_q = sub( 16, scale ); - tmp16 = BASOP_Util_Divide3216_Scale( BIN, bin_freq, &scale ); - tmp16 = shr( tmp16, negate( add( 1, scale ) ) ); - Word16 x_fx = tmp16; + bin_cnt = 0; move16(); - scaleWin_fx = L_mult0( x_fx, extract_l( scaleWin_fx ) ); // scalewin_q - // scaleWin *= (float) BIN / bin_freq; - // norm_val = scaleWin * 4.0f / ( hCPE->hStereoDft->NFFT * hCPE->hStereoDft->NFFT ); - norm_val_fx = L_deposit_l( BASOP_Util_Divide3232_Scale( L_shl( scaleWin_fx, Q2 ), L_mult0( hCPE->hStereoDft->NFFT, hCPE->hStereoDft->NFFT ), &scale ) ); - norm_val_fx = L_shl( norm_val_fx, Q31 - ( scalewin_q + 15 - scale ) ); // q31 + + /* input_Fs / (float) hCPE->hStereoDft->NFFT;*/ /* adaptive frequency bin width */ + bin_freq = BASOP_Util_Divide3216_Scale( input_Fs, hCPE->hStereoDft->NFFT, &exp ); + bin_freq = shl( bin_freq, add( 1, exp ) ); // Q0 + + /* scaleWin = 1 / ( 2 * hCPE->hStereoDft->win_ana_energy ); + scaleWin *= (float) BIN / bin_freq; */ + + temp2 = BASOP_Util_Divide3216_Scale( BIN, bin_freq, &exp ); + temp2 = shl( temp2, add( 1, exp ) ); // Q0 + exp = norm_s( hCPE->hStereoDft->win_ana_energy_fx ); + temp1 = div_s( ONE_IN_Q14, shl( hCPE->hStereoDft->win_ana_energy_fx, exp ) ); // 14-(15+exp-1)+15 = 15+exp + scaleWin_fx = L_mult0( temp1, temp2 ); // 15+exp + + /* scaleWin * 4.0f makes Q of scaleWin_fx from 15+exp to 13+exp + norm_val = scaleWin * 4.0f / ( hCPE->hStereoDft->NFFT * hCPE->hStereoDft->NFFT ); */ + + norm_val_fx = BASOP_Util_Divide3232_Scale( scaleWin_fx, L_mult0( hCPE->hStereoDft->NFFT, hCPE->hStereoDft->NFFT ), &exp1 ); // 13+exp+15-exp1 = 28+exp-exp1 + q_norm_val = add( 28, sub( exp, exp1 ) ); ptR_fx = &DFT_past_DMX_fx[2]; /* first real */ ptI_fx = &DFT_past_DMX_fx[3]; /* first imaginary */ - move32(); - move32(); - c_fx = c_1_fx; - s_fx = s_1_fx; + + c_fx = c_1_fx; // Q30 + s_fx = s_1_fx; // Q30 move32(); move32(); /* for low frequency bins, save per bin energy for the use in find_tilt() */ freq = bin_freq; move32(); + + *q_band = add( shl( Q_inp_dmx, 1 ), sub( q_norm_val, 48 ) ); + move16(); + *q_Bin_E = *q_band; + move16(); + + IF( GT_16( *q_band, 39 ) ) + { + shift = sub( *q_band, 39 ); + *q_band = 39; + move16(); + } + + min_ener = L_shl( E_MIN_FXQ31 /* 0.0035 in Q31 */, sub( *q_band, 31 ) ); FOR( i = 0; i < NB_BANDS - 1; i++ ) /* up to maximum allowed voiced critical band */ { - band_fx[i] = 0; + band_ener = 0; + move64(); + start_freq = freq; move32(); - cnt = 0; - move16(); + /* bins up to crit_band 17 (<= 3700 Hz): * bin_cnt old (bin_width 50 Hz): 74 (74 * FRAMES_PER_SEC = 3700) * bin_cnt new (bin_width 40 Hz): 92 (92 * 40 = 3680) */ - tmp16 = BASOP_Util_Divide3216_Scale( L_sub( crit_bands_fx[i], freq ), bin_freq, &scale ); - tmp16 = shr( tmp16, negate( add( 1, scale ) ) ); - Word32 freq_diff = L_deposit_l( tmp16 ); - Word16 guarded_bits; - guarded_bits = find_guarded_bits_fx( freq_diff ); - s_fx = L_shr( s_fx, guarded_bits ); - c_fx = L_shr( c_fx, guarded_bits ); + WHILE( LE_32( freq, crit_bands_fx[i] ) ) { - Word64 te = ( W_add( W_mult0_32_32( *ptR_fx, *ptR_fx ), W_mult0_32_32( *ptI_fx, *ptI_fx ) ) ); - Word16 te_exp = W_norm( te ); - te = W_shl( te, te_exp ); // 2 * Q_inp_dmx + te_exp - BinE_fx[bin_cnt] = W_extract_h( te ); // 2 * Q_inp_dmx + te_exp - 32 - move32(); - g_fx = L_sub( L_shr( g_1_fx, guarded_bits ), Mpy_32_32( g_2_fx, c_fx ) ); // 30 - guarded_bits - tmp_fx = L_sub( Mpy_32_32( c_fx, c_1_fx ), Mpy_32_32( s_fx, s_1_fx ) ); // 31 - guarded_bits - s_fx = L_add( Mpy_32_32( s_fx, c_1_fx ), Mpy_32_32( c_fx, s_1_fx ) ); // 31 - guarded_bits - c_fx = tmp_fx; // 31 - guarded_bits + // g_fx = L_sub( g_1_fx, L_shl( Mpy_32_32( g_2_fx, c_fx ), 1 ) ); // 30 + g_fx = L_sub( L_shr( g_1_fx, 1 ), Mpy_32_32( g_2_fx, c_fx ) ); // 29 + tmp_fx = Msub_32_32( Mpy_32_32( c_fx, c_1_fx ), s_fx, s_1_fx ); // 29 + s_fx = L_shl( Madd_32_32( Mpy_32_32( s_fx, c_1_fx ), c_fx, s_1_fx ), 1 ); // 30 + c_fx = L_shl( tmp_fx, 1 ); // 30 + + BinE = Madd_32_32( Mpy_32_32( *ptR_fx, *ptR_fx ), *ptI_fx, *ptI_fx ); // 2*Q_inp_dmx-31 + BinE_fx[bin_cnt] = Mpy_32_32( BinE, Mpy_32_16_1( g_fx, norm_val_fx ) ); // (2*Q_inp_dmx-31)+(q_norm_val+29-15)-31 = 2*Q_inp_dmx+q_norm_val-48 = *q_Bin_E move32(); - Word64 ngmult = W_mult0_32_32( norm_val_fx, g_fx ); // Q31 + Q30 - gaurded_bits - Word16 ngmult_exp = W_norm( ngmult ); - ngmult = W_shl( ngmult, ngmult_exp ); // Q31 + Q30 - gaurded_bits + ngmult_exp - BinE_fx[bin_cnt] = Mpy_32_32( W_extract_h( ngmult ), BinE_fx[bin_cnt] ); //(Q31 + Q31 - gaurded_bits + ngmult_exp) - Q32 + (2 * Q_inp_dmx + te_exp - 32) - 31 - move32(); - // To Be Checked - BinE_fx[bin_cnt] = L_shl_sat( BinE_fx[bin_cnt], sub( *Qout, sub( sub( add( add( shl( Q_inp_dmx, 1 ), te_exp ), ngmult_exp ), 34 ), guarded_bits ) ) ); - move32(); - // To Be Checked - band_fx[i] = L_add_sat( BinE_fx[bin_cnt], band_fx[i] ); - move32(); + /* + BIN_FREQ_FX = BIN, cnt = ( ( crit_bands_fx[i] - start_freq ) / bin_freq ) + 1 + band[i] = BinE[bin_cnt]; + band[i] *= inv_tbl[cnt]; // normalization per frequency bin + */ + band_ener = W_mac_32_16( band_ener, BinE_fx[bin_cnt], inv_tbl_fx[( ( crit_bands_fx[i] - start_freq ) / bin_freq ) + 1] ); // *q_band+shift+16 + ptR_fx += 2; ptI_fx += 2; - freq = L_add( freq, L_deposit_l( bin_freq ) ); - cnt = add( cnt, 1 ); + freq = L_mac0( freq, bin_freq, 1 ); bin_cnt = add( bin_cnt, 1 ); } - s_fx = L_shl( s_fx, guarded_bits ); - c_fx = L_shl( c_fx, guarded_bits ); - band_fx[i] = Mpy_32_16_r( band_fx[i], inv_tbl_fx[cnt] ); /* normalization per frequency bin */ + + /* normalization per frequency bin */ + band_fx[i] = W_extract_h( W_shl( band_ener, sub( Q16, shift ) ) ); // *q_band move32(); - band_ener_fx[i] = band_fx[i]; /* per band energy without E_MIN */ + + /* per band energy without E_MIN */ + band_ener_fx[i] = band_fx[i]; // *q_band move32(); - IF( LT_32( band_fx[i], L_shl( E_MIN_Q11_FX, sub( *Qout, Q11 ) ) ) ) + + if ( LT_32( band_fx[i], min_ener ) ) { - band_fx[i] = L_shl( E_MIN_Q11_FX, sub( *Qout, Q11 ) ); + band_fx[i] = min_ener; // *q_band move32(); } } @@ -343,52 +348,47 @@ static void find_enr_dft_fx( /* NB_BANDS = 24 (= 15500Hz) = highest band available for SR 32 -> bin_cnt = 387 */ /* NB_BANDS = 24 (= 15500Hz) = highest band available for SR 48 -> bin_cnt = 387 */ - for ( ; i < NB_BANDS; i++ ) + FOR( ; i < NB_BANDS; i++ ) { - band_fx[i] = 0; + band_ener = 0; + move64(); + start_freq = freq; move32(); - cnt = 0; - move16(); - tmp16 = BASOP_Util_Divide3216_Scale( L_sub( 6399, freq ), bin_freq, &scale ); - tmp16 = shr( tmp16, negate( add( 1, scale ) ) ); - Word32 freq_diff = L_deposit_l( tmp16 ); - Word16 guarded_bits; - guarded_bits = find_guarded_bits_fx( freq_diff ); - c_fx = L_shr( c_fx, guarded_bits ); + WHILE( LT_32( freq, 6399 ) ) { - Word64 te = ( W_add( W_mult0_32_32( *ptR_fx, *ptR_fx ), W_mult0_32_32( *ptI_fx, *ptI_fx ) ) ); - Word16 te_exp = W_norm( te ); - te = W_shl( te, te_exp ); // 2 * Q_inp_dmx + te_exp - BinE_fx[bin_cnt] = W_extract_h( te ); // 2 * Q_inp_dmx + te_exp - 32 - move32(); - g_fx = L_sub( L_shr( g_1_fx, guarded_bits ), Mpy_32_32( g_2_fx, c_fx ) ); - Word64 ngmult = W_mult0_32_32( norm_val_fx, g_fx ); // Q31 + Q31 - gaurded_bits - Word16 ngmult_exp = W_norm( ngmult ); - ngmult = W_shl( ngmult, ngmult_exp ); // Q31 + Q31 - gaurded_bits + ngmult_exp - BinE_fx[bin_cnt] = Mpy_32_32( W_extract_h( ngmult ), BinE_fx[bin_cnt] ); //(Q31 + Q31 - gaurded_bits + ngmult_exp) - Q32 + (2 * Q_inp_dmx + te_exp - 32) - 31 - move32(); - // To Be Checked - BinE_fx[bin_cnt] = L_shl_sat( BinE_fx[bin_cnt], sub( *Qout, sub( sub( add( add( shl( Q_inp_dmx, 1 ), te_exp ), ngmult_exp ), 34 ), guarded_bits ) ) ); - move32(); - // To Be Checked - band_fx[i] = L_add_sat( BinE_fx[bin_cnt], band_fx[i] ); + // g_fx = L_sub( g_1_fx, L_shl( Mpy_32_32( g_2_fx, c_fx ), 1 ) ); // 30 + g_fx = L_sub( L_shr( g_1_fx, 1 ), Mpy_32_32( g_2_fx, c_fx ) ); // 29 + + BinE = Madd_32_32( Mpy_32_32( *ptR_fx, *ptR_fx ), *ptI_fx, *ptI_fx ); // 2*Q_inp_dmx-31 + BinE_fx[bin_cnt] = Mpy_32_32( BinE, Mpy_32_16_1( g_fx, norm_val_fx ) ); // (2*Q_inp_dmx-31)+(q_norm_val+29-15)-31 = 2*Q_inp_dmx+q_norm_val-48 = *q_Bin_E move32(); + + /* + BIN_FREQ_FX = BIN, cnt = ( ( 6399 - start_freq ) / bin_freq ) + 1 + band[i] = BinE[bin_cnt]; + band[i] *= inv_tbl[cnt]; // normalization per frequency bin + */ + band_ener = W_mac_32_16( band_ener, BinE_fx[bin_cnt], inv_tbl_fx[( ( 6399 - start_freq ) / bin_freq ) + 1] ); // *q_band+shift + ptR_fx += 2; ptI_fx += 2; - freq = L_add( freq, L_deposit_l( bin_freq ) ); - cnt = add( cnt, 1 ); + freq = L_mac0( freq, bin_freq, 1 ); bin_cnt = add( bin_cnt, 1 ); } - c_fx = L_shl( c_fx, guarded_bits ); - band_fx[i] = Mpy_32_16_r( band_fx[i], inv_tbl_fx[cnt] ); + + /* normalization per frequency bin */ + band_fx[i] = W_extract_h( W_shl( band_ener, sub( Q16, shift ) ) ); // *q_band move32(); - band_ener_fx[i] = band_fx[i]; + + /* per band energy without E_MIN */ + band_ener_fx[i] = band_fx[i]; // *q_band move32(); - IF( LT_32( band_fx[i], L_shl( E_MIN_Q11_FX, sub( *Qout, Q11 ) ) ) ) + + if ( LT_32( band_fx[i], min_ener ) ) { - band_fx[i] = L_shl( E_MIN_Q11_FX, sub( *Qout, Q11 ) ); + band_fx[i] = min_ener; // *q_band move32(); } } @@ -396,20 +396,26 @@ static void find_enr_dft_fx( /* put bin energies from BinE into Bin_E[L_FFT/2-1] (interpolate 40 Hz bin values to fit into 50 Hz bins) */ /* Last value of Bin_E is handled outside this function*/ assert( bin_cnt == ( STEREO_DFT_N_12k8_ENC / 2 - 1 ) ); - BinE_fx[STEREO_DFT_N_12k8_ENC / 2 - 1] = BinE_fx[STEREO_DFT_N_12k8_ENC / 2 - 2]; + BinE_fx[STEREO_DFT_N_12k8_ENC / 2 - 1] = BinE_fx[STEREO_DFT_N_12k8_ENC / 2 - 2]; // // *q_Bin_E move32(); - L_lerp_fx( BinE_fx, Bin_E_fx, L_FFT / 2, STEREO_DFT_N_12k8_ENC / 2, Qout ); - MVR2R_WORD32( Bin_E_fx, ptE_fx, VOIC_BINS ); // Qout + + L_lerp_fx( BinE_fx, Bin_E_fx, L_FFT / 2, STEREO_DFT_N_12k8_ENC / 2, q_Bin_E ); + + MVR2R_WORD32( Bin_E_fx, ptE_fx, VOIC_BINS ); // *q_Bin_E + *q_ptE = *q_Bin_E; + move16(); /* find the total log energy */ - tmp_fx = *Etot_fx; - move32(); + tot_ener = *Etot_fx; + move64(); + FOR( i = min_band; i <= max_band; i++ ) { - tmp_fx = L_add( tmp_fx, band_fx[i] ); // Qout + tot_ener = W_mac_32_32( tot_ener, band_fx[i], 1 ); // *q_band+1 } - *Etot_fx = tmp_fx; - move32(); + + *Etot_fx = tot_ener; + move64(); return; } @@ -418,38 +424,43 @@ static void find_enr_dft_fx( * * Spectral analysis of 12.8kHz input *-------------------------------------------------------------------*/ - void ivas_analy_sp_fx( - const Word16 element_mode, /* i : element mode */ - CPE_ENC_HANDLE hCPE, /* i/o: CPE encoder structure */ - const Word32 input_Fs, /* i : input sampling rate */ - Word16 *speech, /* i : speech buffer Q_new - preemph_bits */ - const Word16 Q_new, /* i : current scaling exp Q0 */ - Word32 *fr_bands, /* o : energy in critical frequency bands Q_new + QSCALE */ - Word32 *lf_E, /* o : per bin E for first... Q_new + QSCALE - 2*/ - Word16 *Etot, /* o : total input energy Q8 */ - const Word16 min_band, /* i : minimum critical band Q0 */ - const Word16 max_band, /* i : maximum critical band Q0 */ - const Word32 e_min_scaled, /* i : minimum energy scaled Q_new + QSCALE */ - Word16 Scale_fac[2], /* o : FFT scales factors (2 values by frame) Q0 */ - Word32 *Bin_E, /* o : per-bin energy spectrum Q7 */ - Word32 *Bin_E_old, /* o : per-bin energy spectrum of the previous frame Q7 */ - Word32 *PS, /* o : per-bin energy spectrum Q_new + QSCALE */ - Word16 *EspecdB, /* o : per-bin log energy spectrum (with f=0) Q7 */ - Word32 *band_energies, /* o : energy in critical frequency bands without minimum noise floor MODE2_E_MIN (Q_new + QSCALE + 2)*/ - Word16 *fft_buff /* o : FFT coefficients (Q_new + QSCALE + 2) */ + const Word16 element_mode, /* i : element mode Q0 */ + CPE_ENC_HANDLE hCPE, /* i/o: CPE encoder structure */ + const Word32 input_Fs, /* i : input sampling rate Q0 */ + Word16 *speech, /* i : speech buffer Q_new */ + const Word16 Q_new, /* i : current scaling exp Q0 */ + Word32 *fr_bands, /* o : energy in critical frequency bands q_fr_bands */ + Word16 *q_fr_bands, /* o : energy in critical frequency bands Q0 */ + Word32 *lf_E, /* o : per bin E for first... q_lf_E */ + Word16 *q_lf_E, /* o : per bin E for first... Q0 */ + Word16 *Etot, /* o : total input energy Q8 */ + const Word16 min_band, /* i : minimum critical band Q0 */ + const Word16 max_band, /* i : maximum critical band Q0 */ + Word32 *Bin_E, /* o : per-bin energy spectrum q_Bin_E */ + Word16 *q_Bin_E, /* o : per-bin energy spectrum Q0 */ + Word32 *Bin_E_old, /* o : per-bin energy spectrum of the previous frame q_Bin_E_old */ + Word16 *q_Bin_E_old, /* o : per-bin energy spectrum of the previous frame Q0 */ + Word32 *PS, /* o : per-bin energy spectrum q_PS */ + Word16 *q_PS, /* o : per-bin energy spectrum Q0 */ + Word16 *EspecdB, /* o : per-bin log energy spectrum (with f=0) Q7 */ + Word32 *band_energies, /* o : energy in critical frequency bands without minimum noise floor MODE2_E_MIN (q_band_energies) */ + Word16 *q_band_energies, /* o : Q of energy in critical frequency bands without minimum noise floor MODE2_E_MIN */ + Word16 *fft_buff, /* o : FFT coefficients (q_fft_buff) */ + Word16 *q_fft_buff /* o : Q of FFT coefficients Q0 */ ) { Word16 *pt; Word16 i_subfr, i; Word32 *pt_bands; - Word32 Ltmp, LEtot; + Word32 Ltmp; Word16 *pt_fft; - Word16 Min_val, Max_val; - Word16 Scale_fac2; - Word16 fft_temp[L_FFT]; - - (void) input_Fs; + Word16 exp, tmp; + Word16 resultant_q; + Word16 exp2; + Word64 LEtot; + LEtot = 0; + move64(); /*-----------------------------------------------------------------* * Compute spectrum * find energy per critical frequency band and total energy in dB @@ -457,284 +468,217 @@ void ivas_analy_sp_fx( pt_bands = fr_bands; pt_fft = fft_buff; - LEtot = L_deposit_l( 0 ); + IF( NE_16( element_mode, IVAS_CPE_DFT ) ) { - FOR( i_subfr = 0; i_subfr <= 1; i_subfr++ ) + IF( is_zero_arr16( speech + 3 * ( L_SUBFR / 2 ) - L_FFT / 2, L_FFT + 4 * ( L_SUBFR / 2 ) ) ) { - pt = speech + 3 * ( L_SUBFR / 2 ) - L_FFT / 2; - IF( i_subfr != 0 ) - { - pt = speech + 7 * ( L_SUBFR / 2 ) - L_FFT / 2; - } - - /* Clear 1st value of 1st part, copy 1st value of 2nd part */ - fft_temp[0] = 0; - move16(); - fft_temp[L_FFT / 2] = pt[L_FFT / 2]; + set16_fx( pt_fft, 0, 2 * L_FFT ); + *q_fft_buff = Q15; move16(); - Max_val = s_max( fft_temp[0], fft_temp[L_FFT / 2] ); - Min_val = s_min( fft_temp[0], fft_temp[L_FFT / 2] ); - - FOR( i = 1; i < L_FFT / 2; i++ ) - { - /* 1st windowed part */ - fft_temp[i] = mult_r( pt[i], sqrt_han_window_fx[i] ); - move16(); - if ( fft_temp[i] > 0 ) - Max_val = s_max( Max_val, fft_temp[i] ); - if ( fft_temp[i] < 0 ) - Min_val = s_min( Min_val, fft_temp[i] ); - - /* 2nd windowed part */ - fft_temp[L_FFT - i] = mult_r( pt[L_FFT - i], sqrt_han_window_fx[i] ); - move16(); - if ( fft_temp[L_FFT - i] > 0 ) - Max_val = s_max( Max_val, fft_temp[L_FFT - i] ); - if ( fft_temp[L_FFT - i] < 0 ) - Min_val = s_min( Min_val, fft_temp[L_FFT - i] ); - } - /* Combine -Min_val and Max_val into one */ - Max_val = s_max( negate( Min_val ), Max_val ); + set32_fx( Bin_E, 0, L_FFT ); + set32_fx( lf_E, 0, 2 * VOIC_BINS ); + set32_fx( band_energies, 0, 2 * NB_BANDS ); + set32_fx( fr_bands, E_MIN_FXQ31, 2 * NB_BANDS ); // Q31 (*q_fr_bands) - Scale_fac[i_subfr] = s_min( sub( norm_s( Max_val ), 1 ), 6 ); + LEtot = W_shl( W_mult_32_16( E_MIN_FXQ31, add( sub( max_band, min_band ), 1 ) ), 1 ); // Q32 (*q_fr_bands+1) + *q_fr_bands = Q31; + *q_lf_E = *q_fr_bands; move16(); - Scale_fac2 = shl( Scale_fac[i_subfr], 1 ); - Scale_sig( fft_temp, L_FRAME_12k8, Scale_fac[i_subfr] ); - - r_fft_fx_lc( FFT_W128, SIZE_256, SIZE2_256, NUM_STAGE_256, fft_temp, pt_fft, 1 ); - Scale_sig( pt_fft, L_FFT, -1 ); // Q(-1) - /*e_min_scaled = Q_new + QSCALE + 2*/ - ivas_find_enr( pt_fft, pt_bands, lf_E + i_subfr * VOIC_BINS, &LEtot, min_band, max_band, - add( Q_new, Scale_fac2 ), e_min_scaled, &Bin_E[i_subfr * L_FFT / 2], BIN, band_energies + i_subfr * NB_BANDS ); - pt_bands += NB_BANDS; - pt_fft += L_FFT; - } - LEtot = L_shl_sat( LEtot, 2 ); // Q_new + Q_SCALE - 2 - } - ELSE - { - Word16 Qout = add( Q_new, QSCALE - 2 ); - find_enr_dft_fx( hCPE, input_Fs, hCPE->hStereoDft->DFT_fx[0], pt_bands, lf_E, &LEtot, min_band, max_band, Bin_E, band_energies, sub( Q31, hCPE->hStereoDft->DFT_fx_e[0] ), &Qout ); - MVR2R_WORD32( lf_E, lf_E + VOIC_BINS, VOIC_BINS ); - MVR2R_WORD32( Bin_E, Bin_E + ( L_FFT / 2 ), L_FFT / 2 ); - MVR2R_WORD32( band_energies, band_energies + NB_BANDS, NB_BANDS ); - MVR2R_WORD32( pt_bands, pt_bands + NB_BANDS, NB_BANDS ); - LEtot = L_shl( LEtot, 1 ); - } - Word32 temp32_log; - temp32_log = L_add( BASOP_Util_Log2( L_shr( LEtot, 1 ) ), L_shl( sub( Q31, add( Q_new, QSCALE - Q2 ) ), Q25 ) ); - temp32_log = Mpy_32_32( temp32_log, 1616142483 ); // log10(x) = log2(x)/log2(10) - /* 10.0 * log10( (float) tmp )*/ - /* 10.0/log2(10) in Q29 = 1616142483*/ - *Etot = extract_l( L_shr( temp32_log, 23 - 8 ) ); // Q8 - - Bin_E[L_FFT / 2 - 1] = Bin_E[L_FFT / 2 - 2]; - move32(); - Bin_E[L_FFT - 1] = Bin_E[L_FFT - 2]; - move32(); - - /* Per-bin log-energy spectrum */ - - FOR( i = 0; i < L_FFT / 2; i++ ) - { - Bin_E_old[i] = Bin_E[i]; - move32(); - /* tmp = (input[i] + input[i+Len]+0.001f)/2.0f */ - Ltmp = L_max( L_shr( 21474, sub( Q31, add( Q_new, QSCALE ) ) ), L_add( L_shr( Bin_E[i], 1 ), L_shr( Bin_E[i + L_FFT / 2], 1 ) ) ); - if ( PS != NULL ) - { - PS[i] = Ltmp; - move32(); - } - if ( EspecdB != NULL ) - { - temp32_log = L_add( BASOP_Util_Log2( Ltmp ), L_shl( sub( Q31, Q_new + QSCALE ), Q25 ) ); - EspecdB[i] = extract_l( L_shr( Mpy_32_32( temp32_log, 1860652798 ), Q22 - Q7 ) ); /*log(x) = log2(x)*logf(2)*/ - /* 10.0*log((float)tmp) */ - /* 10.0*logf(2) in Q28 = 1860652798 */ - move16(); } - } - - - return; -} - -void ivas_analy_sp_fx_front( - const Word16 element_mode, /* i : element mode */ - CPE_ENC_HANDLE hCPE, /* i/o: CPE encoder structure */ - const Word32 input_Fs, /* i : input sampling rate */ - Word16 *speech, /* i : speech buffer Q_new - preemph_bits */ - const Word16 Q_new, /* i : current scaling exp Q0 */ - Word32 *fr_bands, /* o : energy in critical frequency bands Q_new + QSCALE - 2 */ - Word32 *lf_E, /* o : per bin E for first... Q_new + QSCALE - 2 */ - Word16 *Etot, /* o : total input energy Q8 */ - const Word16 min_band, /* i : minimum critical band Q0 */ - const Word16 max_band, /* i : maximum critical band Q0 */ - const Word32 e_min_scaled, /* i : minimum energy scaled Q_new + QSCALE - 2 */ - Word16 Scale_fac[2], /* o : FFT scales factors (2 values by frame) Q0 */ - Word32 *Bin_E, /* o : per-bin energy spectrum Q7 */ - Word32 *Bin_E_old, /* o : per-bin energy spectrum of the previous frame Q7 */ - Word32 *PS, /* o : per-bin energy spectrum Q_new + QSCALE - 2 */ - Word16 *EspecdB, /* o : per-bin log energy spectrum (with f=0) Q7 */ - Word32 *band_energies, /* o : energy in critical frequency bands without minimum noise floor MODE2_E_MIN (Q_new + QSCALE - 2)*/ - Word16 *fft_buff /* o : FFT coefficients (Q_new + Scale_fac[i_subfr]) */ -) -{ - Word16 *pt; - Word16 i_subfr, i; - Word32 *pt_bands; - Word32 Ltmp, LEtot; - Word16 *pt_fft; - Word32 temp32_log; - Word16 max_pfft; - /*-----------------------------------------------------------------* - * Compute spectrum - * find energy per critical frequency band and total energy in dB - *-----------------------------------------------------------------*/ - - pt_bands = fr_bands; - pt_fft = fft_buff; - LEtot = L_deposit_l( 0 ); - IF( NE_16( element_mode, IVAS_CPE_DFT ) ) - { - FOR( i_subfr = 0; i_subfr <= 1; i_subfr++ ) + ELSE { - /* set pointer to the beginning of the signal for spectral analysis */ - /* set the pointer for first analysis window */ - pt = speech + 3 * ( L_SUBFR / 2 ) - L_FFT / 2; - IF( i_subfr != 0 ) - { - /* set the pointer for second analysis window */ - pt = speech + 7 * ( L_SUBFR / 2 ) - L_FFT / 2; - } - - /* Clear 1st value of 1st part, copy 1st value of 2nd part */ - pt_fft[0] = 0; - move16(); - pt_fft[L_FFT / 2] = pt[L_FFT / 2]; + Word16 scale = 0; move16(); - FOR( i = 1; i < L_FFT / 2; i++ ) + FOR( i_subfr = 0; i_subfr <= 1; i_subfr++ ) { - /* 1st windowed part */ - pt_fft[i] = mult_r( pt[i], sqrt_han_window_fx[i] ); - move16(); + /* set pointer to the beginning of the signal for spectral analysis */ + /* set the pointer for first analysis window */ + pt = speech + 3 * ( L_SUBFR / 2 ) - L_FFT / 2; + if ( i_subfr != 0 ) + { + /* set the pointer for second analysis window */ + pt = speech + 7 * ( L_SUBFR / 2 ) - L_FFT / 2; + } - /* 2nd windowed part */ - pt_fft[L_FFT - i] = mult_r( pt[L_FFT - i], sqrt_han_window_fx[i] ); + /* Clear 1st value of 1st part, copy 1st value of 2nd part */ + pt_fft[0] = 0; move16(); - } - - maximum_abs_16_fx( pt_fft, L_FFT, &max_pfft ); - IF( max_pfft > 0 ) - { - Scale_fac[i_subfr] = sub( norm_s( max_pfft ), LOG2_L_FFT ); + pt_fft[L_FFT / 2] = pt[L_FFT / 2]; // Q_new - preemph_bits move16(); - } - Scale_sig( pt_fft, L_FFT, Scale_fac[i_subfr] ); + FOR( i = 1; i < L_FFT / 2; i++ ) + { + /* 1st windowed part */ + pt_fft[i] = mult_r( pt[i], sqrt_han_window_fx[i] ); // Q_new - preemph_bits + move16(); - /* compute the spectrum */ - fft_rel_fx( pt_fft, L_FFT, LOG2_L_FFT ); + /* 2nd windowed part */ + pt_fft[L_FFT - i] = mult_r( pt[L_FFT - i], sqrt_han_window_fx[i] ); // Q_new - preemph_bits + move16(); + } - /* find energy per critical band */ - ivas_find_enr1( pt_fft, add( Q_new, Scale_fac[i_subfr] ), pt_bands, lf_E + i_subfr * VOIC_BINS, &LEtot, min_band, max_band, - Q_new, e_min_scaled, &Bin_E[i_subfr * L_FFT / 2], BIN, band_energies + i_subfr * NB_BANDS ); + /* compute the spectrum */ + fft_rel_16_32fx( pt_fft, &scale, i_subfr, L_FFT, LOG2_L_FFT ); + *q_fft_buff = add( Q_new, scale ); // resultant q for fft_buff + move16(); + IF( EQ_16( i_subfr, 1 ) ) + { + Word16 new_q_lf_E = add( shl( *q_fft_buff, 1 ), 14 ); + Word16 new_q_bands = new_q_lf_E; + IF( GT_16( new_q_bands, 39 ) ) + { + new_q_bands = 39; + move16(); + } + scale_sig32( fr_bands, NB_BANDS, sub( new_q_bands, *q_fr_bands ) ); + scale_sig32( lf_E, VOIC_BINS, sub( new_q_lf_E, *q_lf_E ) ); + LEtot = W_shl( LEtot, sub( new_q_bands, *q_fr_bands ) ); + scale_sig32( Bin_E, L_FFT / 2, sub( new_q_lf_E, *q_lf_E ) ); + scale_sig32( band_energies, NB_BANDS, sub( new_q_bands, *q_fr_bands ) ); + } + /* find energy per critical band */ + ivas_find_enr( pt_fft, *q_fft_buff, pt_bands, q_fr_bands, lf_E + i_subfr * VOIC_BINS, q_lf_E, &LEtot, min_band, max_band, + &Bin_E[i_subfr * L_FFT / 2], BIN, band_energies + i_subfr * NB_BANDS ); - pt_bands += NB_BANDS; - pt_fft += L_FFT; + pt_bands += NB_BANDS; + pt_fft += L_FFT; + } } + *q_Bin_E = *q_lf_E; + move16(); + /* Average total log energy over both half-frames */ /* *Etot = 10.0f * (float)log10(0.5f * *Etot); */ *Etot = -12800 /* 10.f * logf(0.00001f) in Q8 */; move16(); IF( LEtot != 0 ) { - /* Q of LEtot is Q_new + Q_SCALE - 1, LEtot / 2 can be considered as LEtot in Q_new + Q_SCALE - 1*/ - temp32_log = BASOP_Util_Log10( LEtot, sub( Q31, add( Q_new, QSCALE - Q1 ) ) ); // Q25 - temp32_log = Mpy_32_32( temp32_log, 1342177280 /* 10.f in Q27 */ ); // (Q25, Q27) -> Q21 - *Etot = extract_l( L_shr( temp32_log, Q21 - Q8 ) ); // Q8 + /* Q of LEtot is q_fr_bands+1, LEtot / 2 can be considered as LEtot in q_fr_bands+2 */ + exp = W_norm( LEtot ); + LEtot = W_shl( LEtot, exp ); // q_fr_bands+2+exp + Ltmp = BASOP_Util_Log10( W_extract_h( LEtot ), sub( 61, add( *q_fr_bands, exp ) ) /* 31-(q_fr_bands+2+exp-32) */ ); // Q25 + Ltmp = Mpy_32_32( Ltmp, 1342177280 /* 10.f in Q27 */ ); // (Q25, Q27) -> Q21 + *Etot = extract_h( L_shl( Ltmp, Q24 - Q21 ) ); // Q8 move16(); } } ELSE { - Word16 Qout = add( Q_new, QSCALE - 2 ); - find_enr_dft_fx( hCPE, input_Fs, hCPE->hStereoDft->DFT_fx[0], pt_bands, lf_E, &LEtot, min_band, max_band, Bin_E, band_energies, sub( Q31, hCPE->hStereoDft->DFT_fx_e[0] ), &Qout ); - scale_sig32( lf_E, VOIC_BINS, sub( add( Q_new, QSCALE - 2 ), Qout ) ); - scale_sig32( Bin_E, ( L_FFT / 2 ), sub( add( Q_new, QSCALE - 2 ), Qout ) ); - MVR2R_WORD32( lf_E, lf_E + VOIC_BINS, VOIC_BINS ); - MVR2R_WORD32( Bin_E, Bin_E + ( L_FFT / 2 ), L_FFT / 2 ); - MVR2R_WORD32( band_energies, band_energies + NB_BANDS, NB_BANDS ); - MVR2R_WORD32( pt_bands, pt_bands + NB_BANDS, NB_BANDS ); - - /* *Etot *= 2.f; - *Etot = 10.0f * (float)log10(0.5f * *Etot); - => *Etot = 10.0f * (float)log10(*Etot); - */ + IF( is_zero_arr( hCPE->hStereoDft->DFT_fx[0], STEREO_DFT_N_MAX_ENC ) ) + { + set32_fx( Bin_E, 0, L_FFT ); + set32_fx( lf_E, 0, 2 * VOIC_BINS ); + set32_fx( band_energies, 0, 2 * NB_BANDS ); + set32_fx( fr_bands, E_MIN_FXQ31, 2 * NB_BANDS ); // Q31 (*q_fr_bands) + + LEtot = W_shl( W_mult_32_16( E_MIN_FXQ31, add( sub( max_band, min_band ), 1 ) ), 1 ); // Q32 (*q_fr_bands+1) + *q_fr_bands = Q31; + *q_lf_E = *q_fr_bands; + move16(); + move16(); + } + ELSE + { + exp = sub( getScaleFactor32( hCPE->hStereoDft->DFT_fx[0], STEREO_DFT_N_MAX_ENC ), 1 ); + scale_sig32( hCPE->hStereoDft->DFT_fx[0], STEREO_DFT_N_MAX_ENC, exp ); /* exp(hCPE->hStereoDft->DFT_fx_e[0] - exp) */ + hCPE->hStereoDft->DFT_fx_e[0] = sub( hCPE->hStereoDft->DFT_fx_e[0], exp ); + move16(); + find_enr_dft_ivas_fx( hCPE, input_Fs, hCPE->hStereoDft->DFT_fx[0], pt_bands, q_fr_bands, lf_E, q_lf_E, &LEtot, min_band, max_band, Bin_E, q_Bin_E, band_energies, sub( Q31, hCPE->hStereoDft->DFT_fx_e[0] ) ); + MVR2R_WORD32( lf_E, lf_E + VOIC_BINS, VOIC_BINS ); + MVR2R_WORD32( Bin_E, Bin_E + ( L_FFT / 2 ), L_FFT / 2 ); + MVR2R_WORD32( band_energies, band_energies + NB_BANDS, NB_BANDS ); + MVR2R_WORD32( pt_bands, pt_bands + NB_BANDS, NB_BANDS ); + } /* Average total log energy over both half-frames */ *Etot = -12800 /* 10.f * logf(0.00001f) in Q8 */; move16(); IF( LEtot != 0 ) { - temp32_log = BASOP_Util_Log10( LEtot, sub( Q31, add( Q_new, QSCALE - Q2 ) ) ); // Q25 - temp32_log = Mpy_32_32( temp32_log, 1342177280 /* 10.f in Q27 */ ); // (Q25, Q27) -> Q21 - *Etot = extract_l( L_shr( temp32_log, Q21 - Q8 ) ); // Q8 + exp = W_norm( LEtot ); + LEtot = W_shl( LEtot, exp ); // q_fr_bands+exp + Ltmp = BASOP_Util_Log10( W_extract_h( LEtot ), sub( 62, add( *q_fr_bands, exp ) ) /* 31-(q_fr_bands+1+exp-32) */ ); // Q25 + Ltmp = Mpy_32_32( Ltmp, 1342177280 /* 10.f in Q27 */ ); // (Q25, Q27) -> Q21 + *Etot = extract_h( L_shl( Ltmp, Q24 - Q21 ) ); // Q8 move16(); } } + *q_band_energies = *q_fr_bands; + move16(); + + exp = sub( getScaleFactor32( fr_bands, 2 * NB_BANDS ), 1 ); + scale_sig32( fr_bands, 2 * NB_BANDS, exp ); /* q_fr_bands + exp */ + *q_fr_bands = add( *q_fr_bands, exp ); + move16(); + + exp = sub( getScaleFactor32( band_energies, 2 * NB_BANDS ), 1 ); + scale_sig32( band_energies, 2 * NB_BANDS, exp ); /* q_band_energies + exp */ + *q_band_energies = add( *q_band_energies, exp ); + move16(); + + *q_Bin_E_old = *q_Bin_E; + move16(); + + /* Per-bin log-energy spectrum */ - Bin_E[L_FFT / 2 - 1] = Bin_E[L_FFT / 2 - 2]; + Bin_E[L_FFT / 2 - 1] = Bin_E[L_FFT / 2 - 2]; // *q_Bin_E move32(); - Bin_E[L_FFT - 1] = Bin_E[L_FFT - 2]; + Bin_E[L_FFT - 1] = Bin_E[L_FFT - 2]; // *q_Bin_E move32(); FOR( i = 0; i < L_FFT / 2; i++ ) { - Bin_E_old[i] = Bin_E[i]; + Bin_E_old[i] = Bin_E[i]; // *q_Bin_E move32(); - /* tmp = (input[i] + input[i+Len]+0.001f)/2.0f */ - // Ltmp = L_max( L_shr( 21474, sub( Q31, add( Q_new, QSCALE ) ) ), L_add( L_shr( Bin_E[i], 1 ), L_shr( Bin_E[i + L_FFT / 2], 1 ) ) ); - Ltmp = L_add( L_shr( Bin_E[i], 1 ), L_shr( Bin_E[i + L_FFT / 2], 1 ) ); // average - if ( Ltmp == 0 ) - { - // Ltmp = L_min( L_shr( 21474, sub( Q31, add( Q_new, QSCALE - 2 ) ) ), 1 ); - Ltmp = L_max( L_shr( 21474, sub( Q31, add( Q_new, QSCALE - 2 ) ) ), 1 ); - if ( EspecdB != NULL ) - { - // temp32_log = L_add( BASOP_Util_Log2( Ltmp ), L_shl( sub( Q31, Q_new + QSCALE ), Q25 ) ); - // EspecdB[i] = -1474; /* log(1e-5) in Q7 */ - EspecdB[i] = -14736; /* log(1e-5) in Q7 */ - move16(); - } + /* PS[i] = ( Bin_E[i] + 1e-5f + Bin_E[i + L_FFT / 2] + 1e-5f ) / 2.0f; */ + PS[i] = W_extract_h( W_mac_32_32( W_mult_32_32( Bin_E[i], ONE_IN_Q30 ), Bin_E[i + L_FFT / 2], ONE_IN_Q30 ) ); // *q_Bin_E + move32(); + + /* Bin_E[i] = (float) ( 10.0f * log( PS[i] ) ); */ + IF( EspecdB != NULL ) + { + EspecdB[i] = -14736; /* ln(1e-5) in Q7 */ + move16(); } - else + + Bin_E[i] = -482887093; /* ln(1e-5) in Q22 */ + move32(); + + IF( GT_32( PS[i], L_shl_sat( 21475, sub( *q_Bin_E, Q31 ) ) ) /*1e - 5 in *q_bin_E */ ) { + Ltmp = L_add( BASOP_Util_Log2( PS[i] ), L_shl( sub( Q31, *q_Bin_E ), Q25 ) ); + Bin_E[i] = Mpy_32_32( Ltmp, 1860652798 /*10.0*logf(2) in Q28 */ ); // Q22 + move32(); + + tmp = extract_h( L_shl( Bin_E[i], Q23 - Q22 ) ); // Q7 if ( EspecdB != NULL ) { - temp32_log = L_add( BASOP_Util_Log2( Ltmp ), L_shl( sub( Q31, Q_new + QSCALE - 2 ), Q25 ) ); - EspecdB[i] = extract_l( L_shr( Mpy_32_32( temp32_log, 1860652798 ), Q22 - Q7 ) ); /*log(x) = log2(x)*logf(2)*/ - /* 10.0*log((float)tmp) */ - /* 10.0*logf(2) in Q28 = 1860652798 */ - + EspecdB[i] = tmp; // Q7 move16(); } } - if ( PS != NULL ) - { - PS[i] = Ltmp; - move32(); - } } + if ( q_PS != NULL ) + { + *q_PS = *q_Bin_E; + move16(); + } + + exp = L_norm_arr( Bin_E, L_FFT / 2 ); + exp2 = L_norm_arr( Bin_E + L_FFT / 2, L_FFT / 2 ); + resultant_q = s_min( Q22, s_min( add( *q_Bin_E, exp2 ), add( exp, Q22 ) ) ); // calculating resultant q after scaling + scale_sig32( Bin_E, L_FFT / 2, sub( resultant_q, Q22 ) ); // Q22=>resultant_q + scale_sig32( Bin_E + L_FFT / 2, L_FFT / 2, sub( resultant_q, *q_Bin_E ) ); // q_Bin_E=>resultant_q + *q_Bin_E = resultant_q; + move16(); return; } @@ -746,329 +690,108 @@ void ivas_analy_sp_fx_front( * The energy is normalized by the number of frequency bins in a channel *------------------------------------------------------------------------*/ +/* Merge with ivas_find_enr function once analy_sp is unified */ static void ivas_find_enr( Word16 data[], /* i : fft result */ - Word32 band[], /* o : per band energy Q_new + QSCALE */ - Word32 *ptE, /* o : per bin energy for low frequencies Q_new + QSCALE-2 */ - Word32 *LEtot, /* o : total energy Q_new + QSCALE */ + Word16 q_data, /* i : Q of fft result */ + Word32 band[], /* o : per band energy q_band */ + Word16 *q_band, /* o : Q of per band energy */ + Word32 *ptE, /* o : per bin energy for low frequencies q_ptE */ + Word16 *q_ptE, /* o : Q of per bin energy for low frequencies Q0 */ + Word64 *LEtot, /* o : total energy q_band+1 */ const Word16 min_band, /* i : minimum critical band Q0 */ const Word16 max_band, /* i : maximum critical band Q0 */ - const Word16 Q_new2, /* i : scaling factor Q0 */ - const Word32 e_min, /* i : minimum energy scaled Q_new + QSCALE */ - Word32 *Bin_E, /* o : Per bin energy Q_new + QSCALE-2 */ - Word16 BIN_FREQ_FX, /* i : Number of frequency bins */ - Word32 *band_energies /* o : per band energy without MODE2_E_MIN */ + Word32 *Bin_E, /* o : Per bin energy q_ptE */ + Word16 BIN_FREQ_FX, /* i : Number of frequency bins Q0 */ + Word32 *band_energies /* o : per band energy without MODE2_E_MIN q_band */ ) { - Word16 i, cnt, shift_to_norm; - Word16 freq, wtmp; - Word16 *ptR, *ptI, diff_scaleP1, diff_scaleM2; - Word16 exp_band; - Word32 Ltmp, Ltmp1; + Word16 i; + Word16 freq; + Word16 *ptR, *ptI; Word16 voic_band; - Word32 etot; - Word16 exp_etot; - Word32 *tmpptr; -#ifdef BASOP_NOGLOB_DECLARE_LOCAL - Flag Overflow = 0; + Word64 etot, band_ener; + Word16 start_freq; + Word32 min_ener; + Word16 shift = 0; move16(); -#endif - ptR = &data[1]; /* first real */ ptI = &data[L_FFT - 1]; /* first imaginary */ - /*-----------------------------------------------------------------------------------* - * Scaling needed by band and ptE output - * Wants all energies scaled by Q_new + QSCALE to maintain maximum - * precision on bckr noise in clean speech - * First shift left by Q_new + QSCALE than shift right by 2*Q_new-1 - * shift left (Q_new + QSCALE - (2*Q_new -1)) - * shift left (QSCALE - Q_new + 1) == shift left by (QSCALE+1) - Q_new - *-----------------------------------------------------------------------------------*/ - - diff_scaleP1 = sub( QSCALE + 1 + 1, Q_new2 ); - diff_scaleM2 = sub( QSCALE + 1 - 2, Q_new2 ); - voic_band = VOIC_BAND_8k; move16(); assert( VOIC_BAND == VOIC_BAND_8k ); - etot = L_deposit_l( 0 ); - exp_etot = 0; - move16(); - /*-----------------------------------------------------------------* * For low frequency bins, save per bin energy for the use * in NS and find_tilt() *-----------------------------------------------------------------*/ - freq = BIN_FREQ_FX; + *q_ptE = add( shl( q_data, 1 ), 14 ); + move16(); + *q_band = add( shl( q_data, 1 ), 14 ); move16(); - FOR( i = 0; i < voic_band; i++ ) /* up to maximum allowed voiced critical band */ - { - tmpptr = Bin_E; - move16(); - Ltmp1 = L_deposit_l( 0 ); - - FOR( ; freq <= crit_bands_fx[i]; freq += BIN_FREQ_FX ) - { - /*ptE = *ptR * *ptR + *ptI * *ptI */ /* energy */ - Word64 te = ( W_add( W_mult0_32_32( *ptR, *ptR ), W_mult0_32_32( *ptI, *ptI ) ) ); // 2 * Qfft - Word16 te_exp = W_norm( te ); - te = W_shl( te, te_exp ); // 2 * Qfft + te_exp - Ltmp = W_extract_h( te ); // 2 * Qfft + te_exp - 32 - - Ltmp = L_shr( Ltmp, sub( te_exp, 32 ) ); - /* *ptE *= 4.0 / (L_FFT*L_FFT) */ - /* normalization - corresponds to FFT normalization by 2/L_FFT */ - BASOP_SATURATE_WARNING_OFF_EVS; /* saturation seems to have no effect (tested by simulation) */ -#ifdef BASOP_NOGLOB - *ptE = L_shl_o( Ltmp, diff_scaleM2, &Overflow ); -#else /* BASOP_NOGLOB */ - *ptE = L_shl( Ltmp, diff_scaleM2 ); -#endif /* BASOP_NOGLOB */ - move32(); /* scaled by Q_new + QSCALE - 2 */ - BASOP_SATURATE_WARNING_ON_EVS; - /*band[i] += *ptE++;*/ - *Bin_E = *ptE; - move32(); - Bin_E++; - Ltmp1 = L_add( Ltmp1, Ltmp ); - - ptE++; - ptR++; - ptI--; - } - - exp_band = sub( norm_l( Ltmp1 ), 1 ); /* divide by 2 to ensure band < cnt */ - wtmp = round_fx( L_shl( Ltmp1, exp_band ) ); - - /* band[i] /= cnt */ /* normalization per frequency bin */ - cnt = (Word16) ( Bin_E - tmpptr ); - shift_to_norm = norm_s( cnt ); - wtmp = div_s( wtmp, shl( cnt, shift_to_norm ) ); - Ltmp1 = L_deposit_l( wtmp ); - - exp_band = sub( exp_band, shift_to_norm ); - exp_band = sub( diff_scaleP1, exp_band ); - BASOP_SATURATE_WARNING_OFF_EVS; /* saturation seems to have no effect (tested by simulation) */ -#ifdef BASOP_NOGLOB - band[i] = L_shl_o( Ltmp1, exp_band, &Overflow ); -#else /* BASOP_NOGLOB */ - band[i] = L_shl( Ltmp1, exp_band ); -#endif /* BASOP_NOGLOB */ - move32(); /* band scaled by Q_new + QSCALE */ - BASOP_SATURATE_WARNING_ON_EVS; - - test(); - IF( GE_16( i, min_band ) && LE_16( i, max_band ) ) - { - IF( LT_32( band[i], e_min ) ) - { - Ltmp1 = L_shl( e_min, 0 ); - exp_band = 0; - move16(); - } - - wtmp = sub( exp_band, exp_etot ); - if ( wtmp > 0 ) - { - etot = L_shr( etot, wtmp ); - } - exp_etot = s_max( exp_etot, exp_band ); - etot = L_add( etot, L_shl( Ltmp1, sub( exp_band, exp_etot ) ) ); - } - - band_energies[i] = band[i]; - move32(); - - band[i] = L_max( band[i], e_min ); - move32(); - } - IF( EQ_16( BIN_FREQ_FX, 50 ) ) + IF( GT_16( *q_band, 39 ) ) { - /*-----------------------------------------------------------------* - * Continue compute the E per critical band for high frequencies - *-----------------------------------------------------------------*/ - - FOR( i = voic_band; i < NB_BANDS; i++ ) - { - tmpptr = Bin_E; - move16(); - Ltmp1 = L_deposit_l( 0 ); - - FOR( ; freq <= crit_bands_fx[i]; freq += BIN_FREQ_FX ) - { - /* *ptE = *ptR * *ptR + *ptI * *ptI */ - Word64 te = ( W_add( W_mult0_32_32( *ptR, *ptR ), W_mult0_32_32( *ptI, *ptI ) ) ); - Word16 te_exp = W_norm( te ); - te = W_shl( te, te_exp ); - Ltmp = W_extract_h( te ); - Ltmp = L_shr( Ltmp, sub( te_exp, 32 ) ); - - /* *ptE *= 4.0 / (L_FFT*L_FFT) */ - /* normalization - corresponds to FFT normalization by 2/L_FFT */ - BASOP_SATURATE_WARNING_OFF_EVS; /* saturation seems to have no effect (tested by simulation) */ -#ifdef BASOP_NOGLOB - *Bin_E = L_shl_o( Ltmp, diff_scaleM2, &Overflow ); -#else /* BASOP_NOGLOB */ - *Bin_E = L_shl( Ltmp, diff_scaleM2 ); -#endif /* BASOP_NOGLOB */ - move32(); /* scaled by Q_new + QSCALE - 2 */ - BASOP_SATURATE_WARNING_ON_EVS; - Bin_E++; - Ltmp1 = L_add( Ltmp1, Ltmp ); - - ptR++; - ptI--; - } - - exp_band = sub( norm_l( Ltmp1 ), 1 ); /* divide by 2 to ensure band < cnt */ - wtmp = round_fx( L_shl( Ltmp1, exp_band ) ); - - /* band[i] /= cnt */ /* normalization per frequency bin */ - cnt = (Word16) ( Bin_E - tmpptr ); - shift_to_norm = norm_s( cnt ); - wtmp = div_s( wtmp, shl( cnt, shift_to_norm ) ); - Ltmp1 = L_deposit_l( wtmp ); - - exp_band = sub( exp_band, shift_to_norm ); - exp_band = sub( diff_scaleP1, exp_band ); - BASOP_SATURATE_WARNING_OFF_EVS; /* saturation seems to have no effect (tested by simulation) */ -#ifdef BASOP_NOGLOB - band[i] = L_shl_o( Ltmp1, exp_band, &Overflow ); -#else /* BASOP_NOGLOB */ - band[i] = L_shl( Ltmp1, exp_band ); -#endif - move32(); /* band scaled by Q_new + QSCALE */ - BASOP_SATURATE_WARNING_ON_EVS; - - test(); - IF( GE_16( i, min_band ) && LE_16( i, max_band ) ) - { - IF( LT_32( band[i], e_min ) ) - { - Ltmp1 = L_shl( e_min, 0 ); - exp_band = 0; - move16(); - } - - wtmp = sub( exp_band, exp_etot ); - if ( wtmp > 0 ) - { - etot = L_shr( etot, wtmp ); - } - exp_etot = s_max( exp_etot, exp_band ); - - etot = L_add( etot, L_shl( Ltmp1, sub( exp_band, exp_etot ) ) ); - } - - band_energies[i] = band[i]; - move32(); - - band[i] = L_max( band[i], e_min ); - move32(); - } + shift = sub( *q_band, 39 ); + *q_band = 39; + move16(); } - /*-----------------------------------------------------------------* - * Find the total energy over the input bandwidth - *-----------------------------------------------------------------*/ - -#ifdef BASOP_NOGLOB - etot = L_add_sat( *LEtot, L_shl_sat( etot, sub( exp_etot, 4 ) ) ); -#else - etot = L_add( *LEtot, L_shl( etot, sub( exp_etot, 4 ) ) ); -#endif - *LEtot = etot; - move32(); - - - return; -} - -/* Merge with ivas_find_enr function once analy_sp is unified */ -static void ivas_find_enr1( - Word16 data[], /* i : fft result */ - Word16 q_data, /* i : Q of fft result */ - Word32 band[], /* o : per band energy Q_new + QSCALE-2 */ - Word32 *ptE, /* o : per bin energy for low frequencies Q_new + QSCALE-2 */ - Word32 *LEtot, /* o : total energy Q_new + QSCALE-2 */ - const Word16 min_band, /* i : minimum critical band Q0 */ - const Word16 max_band, /* i : maximum critical band Q0 */ - const Word16 Q_new, /* i : scaling factor Q0 */ - const Word32 e_min, /* i : minimum energy scaled Q_new + QSCALE-2 */ - Word32 *Bin_E, /* o : Per bin energy Q_new + QSCALE-2 */ - Word16 BIN_FREQ_FX, /* i : Number of frequency bins */ - Word32 *band_energies /* o : per band energy without MODE2_E_MIN Q_new + QSCALE-2 */ -) -{ - Word16 i, cnt; - Word16 freq; - Word16 *ptR, *ptI; - Word32 Ltmp; - Word16 voic_band; - Word32 etot; - Word32 norm_val; - - norm_val = 131072 /* 4.0f / ( L_FFT * L_FFT ) in Q31 */; - move32(); - - ptR = &data[1]; /* first real */ - ptI = &data[L_FFT - 1]; /* first imaginary */ - - voic_band = VOIC_BAND_8k; - move16(); - assert( VOIC_BAND == VOIC_BAND_8k ); - - /*-----------------------------------------------------------------* - * For low frequency bins, save per bin energy for the use - * in NS and find_tilt() - *-----------------------------------------------------------------*/ + min_ener = L_shl( E_MIN_FXQ31, sub( *q_band, Q31 ) ); // *q_band freq = BIN_FREQ_FX; move16(); FOR( i = 0; i < voic_band; i++ ) /* up to maximum allowed voiced critical band */ { - band[i] = 0; - move32(); - cnt = 0; + band_ener = 0; + move64(); + start_freq = freq; move16(); WHILE( LE_32( freq, crit_bands_fx[i] ) ) { - // *ptE = *ptR * *ptR + *ptI * *ptI; /* energy */ - Word64 te = ( W_add( W_mult0_32_32( *ptR, *ptR ), W_mult0_32_32( *ptI, *ptI ) ) ); // 2 * Qfft - Word16 te_exp = W_norm( te ); - te = W_shl( te, te_exp ); // 2 * Qfft + te_exp - Ltmp = W_extract_h( te ); // 2 * Qfft + te_exp - 32 - - // *ptE *= norm_val; /* normalization - corresponds to FFT normalization by 2/L_FFT */ - Ltmp = Mpy_32_32( Ltmp, norm_val ); // 2 * Qfft + te_exp - 32 - *ptE = L_shl_sat( Ltmp, sub( add( Q_new, QSCALE - 2 ), add( shl( q_data, Q1 ), sub( te_exp, 32 ) ) ) ); // Q_new + QSCALE - 2 - move32(); + /* + *ptE = *ptR * *ptR + *ptI * *ptI; + + Overflow occurs in the above operation only when ptR and ptI values are equal to -32768. + In that case, energy value will be 2^31 (only one greater than max 32 bit value). + Hence, saturation is added. - *Bin_E++ = *ptE; // Q_new + QSCALE - 2 + *ptE *= norm_val; + norm_val = 4 / (256 * 256), As the value is in power's of 2, result can be obtained by increasing the Q factor + + Q of energy = 2 * q_data + 14 = *q_ptE + */ + + *ptE = L_mac0_sat( L_mult0( *ptR, *ptR ), *ptI, *ptI ); // *q_ptE move32(); - band[i] = L_add_sat( band[i], *ptE++ ); // Q_new + QSCALE - 2 + + *Bin_E++ = *ptE; // *q_ptE move32(); + + /* + BIN_FREQ_FX = BIN, cnt = ( ( crit_bands_fx[i] - start_freq ) / BIN ) + 1 + band[i] += *ptE++; + band[i] *= inv_tbl[cnt]; // normalization per frequency bin + */ + band_ener = W_mac_32_16( band_ener, *ptE, inv_tbl_fx[( ( crit_bands_fx[i] - start_freq ) / BIN ) + 1] ); // *q_band+16+shift ptR++; ptI--; - + ptE++; freq = add( freq, BIN_FREQ_FX ); - cnt = add( cnt, 1 ); } - band[i] = Mpy_32_16_1( band[i], inv_tbl_fx[cnt] ); /* normalization per frequency bin */ // Q_new + QSCALE - 2 + band[i] = W_extract_h( W_shl( band_ener, sub( Q16, shift ) ) ); // *q_band move32(); - band_energies[i] = band[i]; /* per band energy without E_MIN */ // Q_new + QSCALE - 2 + band_energies[i] = band[i]; /* per band energy without E_MIN */ // *q_band move32(); - if ( LT_32( band[i], e_min ) ) // Q_new + QSCALE - 2 + if ( LT_32( band[i], min_ener ) ) // *q_band { - band[i] = e_min; // Q_new + QSCALE - 2 + band[i] = min_ener; // *q_band move32(); } } @@ -1081,41 +804,50 @@ static void ivas_find_enr1( FOR( i = voic_band; i < NB_BANDS; i++ ) { - band[i] = 0; - move32(); - cnt = 0; + band_ener = 0; + move64(); + start_freq = freq; move16(); WHILE( LE_32( freq, crit_bands_fx[i] ) ) { - // *Bin_E = *ptR * *ptR + *ptI * *ptI; - Word64 te = ( W_add( W_mult0_32_32( *ptR, *ptR ), W_mult0_32_32( *ptI, *ptI ) ) ); // 2 * Qfft - Word16 te_exp = W_norm( te ); - te = W_shl( te, te_exp ); // 2 * Qfft + te_exp - Ltmp = W_extract_h( te ); // 2 * Qfft + te_exp - 32 - - // *Bin_E *= norm_val; - Ltmp = Mpy_32_32( Ltmp, norm_val ); // 2 * Qfft + te_exp - 32 - *Bin_E = L_shl_sat( Ltmp, sub( add( Q_new, QSCALE - 2 ), add( shl( q_data, Q1 ), sub( te_exp, 32 ) ) ) ); // Q_new + QSCALE - 2 - move32(); + /* + *Bin_E = *ptR * *ptR + *ptI * *ptI; - band[i] = L_add_sat( band[i], *Bin_E++ ); // Q_new + QSCALE - 2 + Overflow occurs in the below operation only when ptR and ptI values are equal to - 32768. + In that case, energy value will be 2 ^ 31 (only one greater than max 32 bit value). + Hence, saturation is added. + + *Bin_E *= norm_val; + norm_val = 4 / (256 * 256), As the value is in power's of 2, result can be obtained by increasing the Q factor + + Q of energy = 2 * q_data + 14 = *q_ptE + */ + + *Bin_E = L_mac0_sat( L_mult0( *ptR, *ptR ), *ptI, *ptI ); // 2*q_data+14 = *q_ptE move32(); + + /* + BIN_FREQ_FX = BIN, cnt = ( ( crit_bands_fx[i] - start_freq ) / BIN ) + 1 + band[i] += *ptE++; + band[i] *= inv_tbl[cnt]; // normalization per frequency bin + */ + band_ener = W_mac_32_16( band_ener, *Bin_E, inv_tbl_fx[( ( crit_bands_fx[i] - start_freq ) / BIN ) + 1] ); // *q_band+16+shift ptR++; ptI--; + Bin_E++; freq = add( freq, BIN_FREQ_FX ); - cnt = add( cnt, 1 ); } - band[i] = Mpy_32_16_1( band[i], inv_tbl_fx[cnt] ); /* normalization per frequency bin */ // Q_new + QSCALE - 2 + band[i] = W_extract_h( W_shl_nosat( band_ener, sub( Q16, shift ) ) ); // *q_band move32(); - band_energies[i] = band[i]; /* per band energy without E_MIN */ // Q_new + QSCALE - 2 + band_energies[i] = band[i]; /* per band energy without E_MIN */ // *q_band move32(); - if ( LT_32( band[i], e_min ) ) // Q_new + QSCALE - 2 + if ( LT_32( band[i], min_ener ) ) // *q_band { - band[i] = e_min; // Q_new + QSCALE - 2 + band[i] = min_ener; // *q_band move32(); } } @@ -1125,14 +857,14 @@ static void ivas_find_enr1( * Find the total energy over the input bandwidth *-----------------------------------------------------------------*/ - etot = *LEtot; - move32(); + etot = *LEtot; // *q_band + move64(); FOR( i = min_band; i <= max_band; i++ ) { - etot = L_add_sat( etot, band[i] ); // Q_new + QSCALE - 2 + etot = W_mac_32_32( etot, band[i], 1 ); // *q_band+1 } - *LEtot = etot; - move32(); + *LEtot = etot; // *q_band+1 + move64(); return; } @@ -1147,7 +879,7 @@ static void find_enr( const Word16 Q_new2, /* i : scaling factor Q0 */ const Word32 e_min, /* i : minimum energy scaled Q_new + QSCALE */ Word32 *Bin_E, /* o : Per bin energy Q_new + QSCALE-2 */ - Word16 BIN_FREQ_FX, /* i : Number of frequency bins */ + Word16 BIN_FREQ_FX, /* i : Number of frequency bins Q0 */ Word32 *band_energies /* o : per band energy without MODE2_E_MIN */ ) { @@ -1162,7 +894,7 @@ static void find_enr( Word32 *tmpptr; #ifdef BASOP_NOGLOB_DECLARE_LOCAL Flag Overflow = 0; - move16(); + move32(); #endif @@ -1198,7 +930,7 @@ static void find_enr( move16(); FOR( i = 0; i < voic_band; i++ ) /* up to maximum allowed voiced critical band */ { - tmpptr = Bin_E; + tmpptr = Bin_E; /* Q_new + QSCALE - 2 */ move16(); Ltmp1 = L_deposit_l( 0 ); @@ -1210,13 +942,9 @@ static void find_enr( /* *ptE *= 4.0 / (L_FFT*L_FFT) */ /* normalization - corresponds to FFT normalization by 2/L_FFT */ - BASOP_SATURATE_WARNING_OFF_EVS; /* saturation seems to have no effect (tested by simulation) */ -#ifdef BASOP_NOGLOB - *ptE = L_shl_o( Ltmp, diff_scaleM2, &Overflow ); -#else /* BASOP_NOGLOB */ - *ptE = L_shl( Ltmp, diff_scaleM2 ); -#endif /* BASOP_NOGLOB */ - move32(); /* scaled by Q_new + QSCALE - 2 */ + BASOP_SATURATE_WARNING_OFF_EVS; /* saturation seems to have no effect (tested by simulation) */ + *ptE = L_shl_o( Ltmp, diff_scaleM2, &Overflow ); /* Q_new + QSCALE - 2 */ + move32(); /* scaled by Q_new + QSCALE - 2 */ BASOP_SATURATE_WARNING_ON_EVS; /*band[i] += *ptE++;*/ *Bin_E = *ptE; @@ -1235,18 +963,14 @@ static void find_enr( /* band[i] /= cnt */ /* normalization per frequency bin */ cnt = (Word16) ( Bin_E - tmpptr ); shift_to_norm = norm_s( cnt ); - wtmp = div_s( wtmp, shl( cnt, shift_to_norm ) ); - Ltmp1 = L_deposit_l( wtmp ); + wtmp = div_s( wtmp, shl( cnt, shift_to_norm ) ); /* Q15 */ + Ltmp1 = L_deposit_l( wtmp ); /* Q15 */ exp_band = sub( exp_band, shift_to_norm ); exp_band = sub( diff_scaleP1, exp_band ); - BASOP_SATURATE_WARNING_OFF_EVS; /* saturation seems to have no effect (tested by simulation) */ -#ifdef BASOP_NOGLOB - band[i] = L_shl_o( Ltmp1, exp_band, &Overflow ); -#else /* BASOP_NOGLOB */ - band[i] = L_shl( Ltmp1, exp_band ); -#endif /* BASOP_NOGLOB */ - move32(); /* band scaled by Q_new + QSCALE */ + BASOP_SATURATE_WARNING_OFF_EVS; /* saturation seems to have no effect (tested by simulation) */ + band[i] = L_shl_o( Ltmp1, exp_band, &Overflow ); /* Q15 + exp_band */ + move32(); /* band scaled by Q_new + QSCALE */ BASOP_SATURATE_WARNING_ON_EVS; test(); @@ -1268,7 +992,7 @@ static void find_enr( etot = L_add( etot, L_shl( Ltmp1, sub( exp_band, exp_etot ) ) ); } - band_energies[i] = band[i]; + band_energies[i] = band[i]; /* Q_new + QSCALE */ move32(); band[i] = L_max( band[i], e_min ); @@ -1295,13 +1019,9 @@ static void find_enr( /* *ptE *= 4.0 / (L_FFT*L_FFT) */ /* normalization - corresponds to FFT normalization by 2/L_FFT */ - BASOP_SATURATE_WARNING_OFF_EVS; /* saturation seems to have no effect (tested by simulation) */ -#ifdef BASOP_NOGLOB - *Bin_E = L_shl_o( Ltmp, diff_scaleM2, &Overflow ); -#else /* BASOP_NOGLOB */ - *Bin_E = L_shl( Ltmp, diff_scaleM2 ); -#endif /* BASOP_NOGLOB */ - move32(); /* scaled by Q_new + QSCALE - 2 */ + BASOP_SATURATE_WARNING_OFF_EVS; /* saturation seems to have no effect (tested by simulation) */ + *Bin_E = L_shl_o( Ltmp, diff_scaleM2, &Overflow ); /* Q_new + QSCALE */ + move32(); /* scaled by Q_new + QSCALE - 2 */ BASOP_SATURATE_WARNING_ON_EVS; Bin_E++; Ltmp1 = L_add( Ltmp1, Ltmp ); @@ -1322,255 +1042,7 @@ static void find_enr( exp_band = sub( exp_band, shift_to_norm ); exp_band = sub( diff_scaleP1, exp_band ); BASOP_SATURATE_WARNING_OFF_EVS; /* saturation seems to have no effect (tested by simulation) */ -#ifdef BASOP_NOGLOB - band[i] = L_shl_o( Ltmp1, exp_band, &Overflow ); -#else /* BASOP_NOGLOB */ - band[i] = L_shl( Ltmp1, exp_band ); -#endif - move32(); /* band scaled by Q_new + QSCALE */ - BASOP_SATURATE_WARNING_ON_EVS; - - test(); - IF( GE_16( i, min_band ) && LE_16( i, max_band ) ) - { - IF( LT_32( band[i], e_min ) ) - { - Ltmp1 = L_shl( e_min, 0 ); - exp_band = 0; - move16(); - } - - wtmp = sub( exp_band, exp_etot ); - if ( wtmp > 0 ) - { - etot = L_shr( etot, wtmp ); - } - exp_etot = s_max( exp_etot, exp_band ); - - etot = L_add( etot, L_shl( Ltmp1, sub( exp_band, exp_etot ) ) ); - } - - band_energies[i] = band[i]; - move32(); - - band[i] = L_max( band[i], e_min ); - move32(); - } - } - - /*-----------------------------------------------------------------* - * Find the total energy over the input bandwidth - *-----------------------------------------------------------------*/ - -#ifdef BASOP_NOGLOB - etot = L_add_sat( *LEtot, L_shl_sat( etot, sub( exp_etot, 4 ) ) ); -#else - etot = L_add( *LEtot, L_shl( etot, sub( exp_etot, 4 ) ) ); -#endif - *LEtot = etot; - move32(); - - - return; -} - -#ifdef IVAS_FLOAT_FIXED1 -/*------------------------------------------------------------------------* - * ivas_find_enr() - * - * find input signal energy for each critical band and first 74 LF bins - * The energy is normalized by the number of frequency bins in a channel - *------------------------------------------------------------------------*/ - -static void ivas_find_enr( - Word16 data[], /* i : fft result */ - Word32 band[], /* o : per band energy Q_new + QSCALE */ - Word32 *ptE, /* o : per bin energy for low frequencies Q_new + QSCALE-2 */ - Word32 *LEtot, /* o : total energy Q_new + QSCALE */ - const Word16 min_band, /* i : minimum critical band Q0 */ - const Word16 max_band, /* i : maximum critical band Q0 */ - const Word16 Q_new2, /* i : scaling factor Q0 */ - const Word32 e_min, /* i : minimum energy scaled Q_new + QSCALE */ - Word32 *Bin_E, /* o : Per bin energy Q_new + QSCALE-2 */ - Word16 BIN_FREQ_FX, /* i : Number of frequency bins */ - Word32 *band_energies /* o : per band energy without MODE2_E_MIN */ -) -{ - Word16 i, cnt, shift_to_norm; - Word16 freq, wtmp; - Word16 *ptR, *ptI, diff_scaleP1, diff_scaleM2; - Word16 exp_band; - Word32 Ltmp, Ltmp1; - Word16 voic_band; - Word32 etot; - Word16 exp_etot; - Word32 *tmpptr; -#ifdef BASOP_NOGLOB_DECLARE_LOCAL - Flag Overflow = 0; -#endif - - - ptR = &data[1]; /* first real */ - ptI = &data[L_FFT - 1]; /* first imaginary */ - - /*-----------------------------------------------------------------------------------* - * Scaling needed by band and ptE output - * Wants all energies scaled by Q_new + QSCALE to maintain maximum - * precision on bckr noise in clean speech - * First shift left by Q_new + QSCALE than shift right by 2*Q_new-1 - * shift left (Q_new + QSCALE - (2*Q_new -1)) - * shift left (QSCALE - Q_new + 1) == shift left by (QSCALE+1) - Q_new - *-----------------------------------------------------------------------------------*/ - - diff_scaleP1 = sub( QSCALE + 1 + 1, Q_new2 ); - diff_scaleM2 = sub( QSCALE + 1 - 2, Q_new2 ); - - voic_band = VOIC_BAND_8k; - move16(); - assert( VOIC_BAND == VOIC_BAND_8k ); - - etot = L_deposit_l( 0 ); - exp_etot = 0; - move16(); - - /*-----------------------------------------------------------------* - * For low frequency bins, save per bin energy for the use - * in NS and find_tilt() - *-----------------------------------------------------------------*/ - - freq = BIN_FREQ_FX; - move16(); - FOR( i = 0; i < voic_band; i++ ) /* up to maximum allowed voiced critical band */ - { - tmpptr = Bin_E; - move16(); - Ltmp1 = L_deposit_l( 0 ); - - FOR( ; freq <= crit_bands[i]; freq += BIN_FREQ_FX ) - { - /*ptE = *ptR * *ptR + *ptI * *ptI */ /* energy */ - Ltmp = L_mult( *ptI, *ptI ); - Ltmp = L_mac( Ltmp, *ptR, *ptR ); - - /* *ptE *= 4.0 / (L_FFT*L_FFT) */ - /* normalization - corresponds to FFT normalization by 2/L_FFT */ - BASOP_SATURATE_WARNING_OFF_EVS; /* saturation seems to have no effect (tested by simulation) */ -#ifdef BASOP_NOGLOB - *ptE = L_shl_o( Ltmp, diff_scaleM2, &Overflow ); -#else /* BASOP_NOGLOB */ - *ptE = L_shl( Ltmp, diff_scaleM2 ); -#endif /* BASOP_NOGLOB */ - move32(); /* scaled by Q_new + QSCALE - 2 */ - BASOP_SATURATE_WARNING_ON_EVS; - /*band[i] += *ptE++;*/ - *Bin_E = *ptE; - move32(); - Bin_E++; - Ltmp1 = L_add_sat( Ltmp1, Ltmp ); - - ptE++; - ptR++; - ptI--; - } - - exp_band = sub( norm_l( Ltmp1 ), 1 ); /* divide by 2 to ensure band < cnt */ - wtmp = round_fx( L_shl( Ltmp1, exp_band ) ); - - /* band[i] /= cnt */ /* normalization per frequency bin */ - cnt = (Word16) ( Bin_E - tmpptr ); - shift_to_norm = norm_s( cnt ); - wtmp = div_s( wtmp, shl( cnt, shift_to_norm ) ); - Ltmp1 = L_deposit_l( wtmp ); - - exp_band = sub( exp_band, shift_to_norm ); - exp_band = sub( diff_scaleP1, exp_band ); - BASOP_SATURATE_WARNING_OFF_EVS; /* saturation seems to have no effect (tested by simulation) */ -#ifdef BASOP_NOGLOB - band[i] = L_shl_o( Ltmp1, exp_band, &Overflow ); -#else /* BASOP_NOGLOB */ - band[i] = L_shl( Ltmp1, exp_band ); -#endif /* BASOP_NOGLOB */ - move32(); /* band scaled by Q_new + QSCALE */ - BASOP_SATURATE_WARNING_ON_EVS; - - test(); - IF( GE_16( i, min_band ) && LE_16( i, max_band ) ) - { - IF( LT_32( band[i], e_min ) ) - { - Ltmp1 = L_shl( e_min, 0 ); - exp_band = 0; - move16(); - } - - wtmp = sub( exp_band, exp_etot ); - if ( wtmp > 0 ) - { - etot = L_shr( etot, wtmp ); - } - exp_etot = s_max( exp_etot, exp_band ); - etot = L_add( etot, L_shl( Ltmp1, sub( exp_band, exp_etot ) ) ); - } - - band_energies[i] = band[i]; - move32(); - - band[i] = L_max( band[i], e_min ); - move32(); - } - - IF( EQ_16( BIN_FREQ_FX, 50 ) ) - { - /*-----------------------------------------------------------------* - * Continue compute the E per critical band for high frequencies - *-----------------------------------------------------------------*/ - - FOR( i = voic_band; i < NB_BANDS; i++ ) - { - tmpptr = Bin_E; - move16(); - Ltmp1 = L_deposit_l( 0 ); - - FOR( ; freq <= crit_bands[i]; freq += BIN_FREQ_FX ) - { - /* *ptE = *ptR * *ptR + *ptI * *ptI */ - Ltmp = L_mult( *ptI, *ptI ); - Ltmp = L_mac_sat( Ltmp, *ptR, *ptR ); - - /* *ptE *= 4.0 / (L_FFT*L_FFT) */ - /* normalization - corresponds to FFT normalization by 2/L_FFT */ - BASOP_SATURATE_WARNING_OFF_EVS; /* saturation seems to have no effect (tested by simulation) */ -#ifdef BASOP_NOGLOB - *Bin_E = L_shl_o( Ltmp, diff_scaleM2, &Overflow ); -#else /* BASOP_NOGLOB */ - *Bin_E = L_shl( Ltmp, diff_scaleM2 ); -#endif /* BASOP_NOGLOB */ - move32(); /* scaled by Q_new + QSCALE - 2 */ - BASOP_SATURATE_WARNING_ON_EVS; - Bin_E++; - Ltmp1 = L_add_sat( Ltmp1, Ltmp ); - - ptR++; - ptI--; - } - - exp_band = sub( norm_l( Ltmp1 ), 1 ); /* divide by 2 to ensure band < cnt */ - wtmp = round_fx( L_shl( Ltmp1, exp_band ) ); - - /* band[i] /= cnt */ /* normalization per frequency bin */ - cnt = (Word16) ( Bin_E - tmpptr ); - shift_to_norm = norm_s( cnt ); - wtmp = div_s( wtmp, shl( cnt, shift_to_norm ) ); - Ltmp1 = L_deposit_l( wtmp ); - - exp_band = sub( exp_band, shift_to_norm ); - exp_band = sub( diff_scaleP1, exp_band ); - BASOP_SATURATE_WARNING_OFF_EVS; /* saturation seems to have no effect (tested by simulation) */ -#ifdef BASOP_NOGLOB band[i] = L_shl_o( Ltmp1, exp_band, &Overflow ); -#else /* BASOP_NOGLOB */ - band[i] = L_shl( Ltmp1, exp_band ); -#endif move32(); /* band scaled by Q_new + QSCALE */ BASOP_SATURATE_WARNING_ON_EVS; @@ -1606,163 +1078,10 @@ static void ivas_find_enr( * Find the total energy over the input bandwidth *-----------------------------------------------------------------*/ -#ifdef BASOP_NOGLOB etot = L_add_sat( *LEtot, L_shl_sat( etot, sub( exp_etot, 4 ) ) ); -#else - etot = L_add( *LEtot, L_shl( etot, sub( exp_etot, 4 ) ) ); -#endif *LEtot = etot; move32(); return; } -#endif -#ifdef IVAS_CODE_CPE -/*------------------------------------------------------------------------* - * find_enr_dft() - * - * find input signal energy for each critical band using the DFT buffers - *------------------------------------------------------------------------*/ - -static void find_enr_dft( - CPE_ENC_HANDLE hCPE, /* i/o: CPE encoder structure */ - const int32_t input_Fs, /* i : input sampling rate */ - float DFT_past_DMX[], - float band[], /* o : per band energy */ - float *ptE, /* o : per bin energy for low frequencies */ - float *Etot, /* i/o: total energy */ - const int16_t min_band, /* i : minimum critical band */ - const int16_t max_band, /* i : maximum critical band */ - float *Bin_E, /* o : Per bin energy */ - float *band_ener /* o : per band energy without E_MIN */ -) -{ - int16_t i, cnt; - float freq, tmp; - const float *ptR, *ptI; - float norm_val; - int16_t bin_cnt = 0; - - float c, s; - /* One window - 40ms*12.8kHz = 512 samples */ - float c_1 = cosf( PI2 / STEREO_DFT_N_12k8_ENC ); - float s_1 = sinf( PI2 / STEREO_DFT_N_12k8_ENC ); - float g_1 = 1.f + 0.68f * 0.68f; - float g_2 = 2 * 0.68f; - float g; - float scaleWin; - - float BinE[STEREO_DFT_N_12k8_ENC / 2]; /* NB_BANDS = 20 (= 6350Hz) = highest band available for SR 12.8 -> bin_cnt = 158 */ - float bin_freq = input_Fs / (float) hCPE->hStereoDft->NFFT; /* adaptive frequency bin width */ - - scaleWin = 1 / ( 2 * hCPE->hStereoDft->win_ana_energy ); - scaleWin *= (float) BIN / bin_freq; - norm_val = scaleWin * 4.0f / ( hCPE->hStereoDft->NFFT * hCPE->hStereoDft->NFFT ); - - ptR = &DFT_past_DMX[2]; /* first real */ - ptI = &DFT_past_DMX[3]; /* first imaginary */ - c = c_1; - s = s_1; - - /* for low frequency bins, save per bin energy for the use in find_tilt() */ - freq = bin_freq; - for ( i = 0; i < NB_BANDS - 1; i++ ) /* up to maximum allowed voiced critical band */ - { - band[i] = 0.0f; - cnt = 0; - - /* bins up to crit_band 17 (<= 3700 Hz): - * bin_cnt old (bin_width 50 Hz): 74 (74 * FRAMES_PER_SEC = 3700) - * bin_cnt new (bin_width 40 Hz): 92 (92 * 40 = 3680) - */ - - while ( freq <= crit_bands[i] ) - { - BinE[bin_cnt] = *ptR * *ptR + *ptI * *ptI; /* energy */ - g = g_1 - g_2 * c; - tmp = c * c_1 - s * s_1; - s = s * c_1 + c * s_1; - c = tmp; - BinE[bin_cnt] *= norm_val * g; /* normalization - corresponds to FFT normalization by 2/L_FFT */ - band[i] += BinE[bin_cnt]; - ptR += 2; - ptI += 2; - - freq += bin_freq; - cnt++; - bin_cnt++; - } - - band[i] *= inv_tbl[cnt]; /* normalization per frequency bin */ - - band_ener[i] = band[i]; /* per band energy without E_MIN */ - - if ( band[i] < E_MIN ) - { - band[i] = E_MIN; - } - } - - /* continue computing the energy per critical band for higher frequencies */ - - /* old version, FFT 256 @ SR12.8 (-> bin_width = 50 Hz): - NB_BANDS = 20 (= 6350Hz) = highest band available for SR 12.8 -> bin_cnt = 127 = L_FFT/2-1*/ - - /* new version: DFT (1200/800/400) @ input SR (48/32/16) (-> bin_width = 40 Hz): - * - */ - /* NB_BANDS = 20 (= 6350Hz) = highest band available for SR 12.8 -> bin_cnt = 158 */ - /* NB_BANDS = 21 (= 7700Hz) = highest band available for SR 16 -> bin_cnt = 192 */ - /* NB_BANDS = 24 (= 15500Hz) = highest band available for SR 32 -> bin_cnt = 387 */ - /* NB_BANDS = 24 (= 15500Hz) = highest band available for SR 48 -> bin_cnt = 387 */ - - for ( ; i < NB_BANDS; i++ ) - { - band[i] = 0.0f; - cnt = 0; - while ( freq < 6399.0f ) - { - BinE[bin_cnt] = *ptR * *ptR + *ptI * *ptI; - g = g_1 - g_2 * c; - BinE[bin_cnt] *= norm_val * g; - band[i] += BinE[bin_cnt]; - ptR += 2; - ptI += 2; - - freq += bin_freq; - cnt++; - bin_cnt++; - } - - band[i] *= inv_tbl[cnt]; /* normalization per frequency bin */ - - band_ener[i] = band[i]; /* per band energy without E_MIN */ - - if ( band[i] < E_MIN ) - { - band[i] = E_MIN; - } - } - - /* put bin energies from BinE into Bin_E[L_FFT/2-1] (interpolate 40 Hz bin values to fit into 50 Hz bins) */ - /* Last value of Bin_E is handled outside this function*/ - assert( bin_cnt == ( STEREO_DFT_N_12k8_ENC / 2 - 1 ) ); - BinE[STEREO_DFT_N_12k8_ENC / 2 - 1] = BinE[STEREO_DFT_N_12k8_ENC / 2 - 2]; - lerp( BinE, Bin_E, L_FFT / 2, STEREO_DFT_N_12k8_ENC / 2 ); - mvr2r( Bin_E, ptE, VOIC_BINS ); - - - /* find the total log energy */ - tmp = *Etot; - for ( i = min_band; i <= max_band; i++ ) - { - tmp += band[i]; - } - - *Etot = tmp; - - return; -} - -#endif diff --git a/lib_enc/ari_enc.c b/lib_enc/ari_enc.c deleted file mode 100644 index 733e3e72a10274c2ce2627330e37b3aa5e46c0cf..0000000000000000000000000000000000000000 --- a/lib_enc/ari_enc.c +++ /dev/null @@ -1,295 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include -#include "options.h" -#include "cnst.h" -#include "prot.h" -#include "prot_fx.h" -#include "stat_com.h" -#include "basop_util.h" -#include "wmc_auto.h" -#include "prot_fx_enc.h" - - -/*--------------------------------------------------------------- - * ari_copy_states() - * - * Copy state - *-------------------------------------------------------------*/ - -void ari_copy_states( - Tastat *source, - Tastat *dest ) -{ - dest->low = source->low; - dest->high = source->high; - dest->bits_to_follow = source->bits_to_follow; - - return; -} - -/*--------------------------------------------------------------- - Ari encoder 14 bits routines - -------------------------------------------------------------*/ - -/*--------------------------------------------------------------- - * ari_start_encoding_14bits() - * - * Start ArCo encoding - *-------------------------------------------------------------*/ - -void ari_start_encoding_14bits( - Tastat *s ) -{ - /* : addressing is made with walking pointer s */ - s->low = 0; - s->high = ari_q4new; - s->bits_to_follow = 0; - - return; -} -void ari_start_encoding_14bits_ivas_fx( - Tastat *s ) -{ - /* : addressing is made with walking pointer s */ - s->low = 0; - s->high = ari_q4new; - s->bits_to_follow = 0; - move32(); - move32(); - move32(); - - return; -} - -/*--------------------------------------------------------------- - * ari_done_encoding_14bits() - * - * Finish ArCo encoding - *-------------------------------------------------------------*/ - -Word16 ari_done_encoding_14bits( Word16 *ptr, Word16 bp, Tastat *s ) -{ - Word16 bit; - - bit = 0; - move16(); - if ( GE_32( s->low, ari_q1new ) ) - { - bit = s_xor( bit, 1 ); - } - return ari_put_bit_plus_follow( ptr, bp, add( extract_l( s->bits_to_follow ), 1 ), bit ); -} - - -/*--------------------------------------------------------------- - * ari_encode_14bits_ext() - * - * encode function for extended proba tables: less branches needed for coding - * - *-------------------------------------------------------------*/ -Word16 ari_encode_14bits_ext( - Word16 *ptr, - Word16 bp, - Tastat *s, - Word32 symbol, - UWord16 const *cum_freq ) -{ - Word32 low; - Word32 high; - Word32 range; - Word16 bits_to_follow; - Word16 i; - UWord16 temp; - Word32 L_temp1, L_temp2; - - high = L_add( s->high, 0 ); - low = L_add( s->low, 0 ); - range = L_add( L_sub( high, low ), 1 ); - - L_temp1 = L_shl( range, 15 - stat_bitsnew /*both are constants*/ ); - Mpy_32_16_ss( L_temp1, cum_freq[symbol + 1], &L_temp2, &temp ); - IF( symbol != 0 ) /* when symbol is 0, range remains unchanged */ - { - Mpy_32_16_ss( L_temp1, cum_freq[symbol], &range, &temp ); - } - high = L_sub( L_add( low, range ), 1 ); - low = L_add( low, L_temp2 ); - - assert( s->bits_to_follow <= MAX_16 ); - bits_to_follow = extract_l( s->bits_to_follow ); - - FOR( i = 0; i < 0x7FFF; i++ ) - { - IF( LT_32( high, ari_q2new ) ) - { - bp = ari_put_bit_plus_follow( ptr, bp, bits_to_follow, 0 ); - bits_to_follow = 0; - move16(); - } - ELSE IF( GE_32( low, ari_q2new ) ) - { - bp = ari_put_bit_plus_follow( ptr, bp, bits_to_follow, 1 ); - bits_to_follow = 0; - move16(); - low = L_sub( low, ari_q2new ); - high = L_sub( high, ari_q2new ); /* Subtract offset to top. */ - } - ELSE - { - test(); - IF( GE_32( low, ari_q1new ) && LT_32( high, ari_q3new ) ) - { - /* Output an opposite bit */ - /* later if in middle half. */ - bits_to_follow = add( bits_to_follow, 1 ); - low = L_sub( low, ari_q1new ); /* Subtract offset to middle*/ - high = L_sub( high, ari_q1new ); - } - ELSE - { - BREAK; /* Otherwise exit loop. */ - } - } - low = L_add( low, low ); - high = L_add( L_add( high, high ), 1 ); /* Scale up code range. */ - } - - s->low = low; - move32(); - s->high = high; - move32(); - s->bits_to_follow = bits_to_follow; - move32(); - - return bp; -} - - -/*------------------------------------------------------------------------ - * Function: ari_encode_14bits_range() - * - * Encode an cumulative frequency interval. - *-------------------------------------------------------------------------*/ -/*------------------------------------------------------------------------ - * Function: ari_encode_14bits_sign() - * - * Encode a sign with equal probabilities. - *-------------------------------------------------------------------------*/ -static Word16 ari_encode_14bits_high_low( Word16 *ptr, Word16 bp, Word16 bits, Tastat *s, Word32 high, Word32 low ) -{ - Word16 bits_to_follow, tmp; - - bits_to_follow = extract_l( s->bits_to_follow ); - move16(); - - /* while there are more than 16 bits left */ - tmp = sub( 16, bits ); - WHILE( add( add( bp, bits_to_follow ), tmp ) < 0 ) - { - IF( LE_32( high, ari_q2new ) ) - { - bp = ari_put_bit_plus_follow( ptr, bp, bits_to_follow, 0 ); - bits_to_follow = 0; - move16(); - } - ELSE IF( GE_32( low, ari_q2new ) ) - { - bp = ari_put_bit_plus_follow( ptr, bp, bits_to_follow, 1 ); - bits_to_follow = 0; - move16(); - low = L_sub( low, ari_q2new ); - high = L_sub( high, ari_q2new ); /* Subtract offset to top. */ - } - ELSE - { - test(); - IF( GE_32( low, ari_q1new ) && LE_32( high, ari_q3new ) ) - { - /* Output an opposite bit */ - /* later if in middle half. */ - bits_to_follow = add( bits_to_follow, 1 ); - low = L_sub( low, ari_q1new ); /* Subtract offset to middle*/ - high = L_sub( high, ari_q1new ); - } - ELSE - { - BREAK; /* Otherwise exit loop. */ - } - } - - low = L_add( low, low ); - high = L_add( high, high ); /* Scale up code range. */ - } - - s->low = low; - move32(); - s->high = L_sub( high, 1 ); - move32(); - s->bits_to_follow = bits_to_follow; - move16(); - - return bp; -} -Word16 ari_encode_14bits_sign( Word16 *ptr, Word16 bp, Word32 bits, Tastat *s, Word16 sign ) -{ - Word32 low, high, range; - Word32 L_tmp; - - high = L_add( s->high, 1 ); - low = L_add( s->low, 0 ); - range = L_sub( high, low ); - - L_tmp = L_shr( range, 1 ); - if ( sign != 0 ) - { - high = L_add( low, L_tmp ); - } - if ( sign == 0 ) - { - low = L_add( low, L_tmp ); - } - - return ari_encode_14bits_high_low( ptr, bp, extract_l( bits ), s, high, low ); -} - -/*------------------------------------------------------------------------ - * Function: ari_done_cbr_encoding_14bits() - * - * Finish up encoding in CBR mode. - *-------------------------------------------------------------------------*/ diff --git a/lib_enc/ari_enc_fx.c b/lib_enc/ari_enc_fx.c index 872b6a1f3b6acb78d4db2987de223500ef45b48f..29ddd838c69cfb2be54ccfd8d304168190e848bf 100644 --- a/lib_enc/ari_enc_fx.c +++ b/lib_enc/ari_enc_fx.c @@ -56,19 +56,19 @@ void ari_start_encoding_14bits_fx( TastatEnc *s ) * Returns: new bit-stream position *-------------------------------------------------------------*/ Word16 ari_put_bit_plus_follow( - Word16 ptr[], /* o: bit-stream */ - Word16 bp, /* i: bit-stream position */ - Word16 bits_to_follow, /* i: number of opposite bits to follow 'bit' */ - Word16 bit /* i: bit to send */ + Word16 ptr[], /* o: bit-stream Q0*/ + Word16 bp, /* i: bit-stream position Q0*/ + Word16 bits_to_follow, /* i: number of opposite bits to follow 'bit' Q0*/ + Word16 bit /* i: bit to send Q0*/ ) { assert( bit == 0 || bit == 1 ); - ptr[bp++] = bit; /* send initially a zero or one */ + ptr[bp++] = bit; /* send initially a zero or one Q0*/ move16(); bit = s_xor( bit, 1 ); /* invert bit to send */ FOR( ; bits_to_follow > 0; bits_to_follow-- ) { - ptr[bp++] = bit; /* send inverted bit */ + ptr[bp++] = bit; /* send inverted bit Q0*/ move16(); } return bp; @@ -84,7 +84,10 @@ Word16 ari_put_bit_plus_follow( * * \return bit consumption * ------------------------------------------------------------ - */ -Word16 ari_done_encoding_14bits_fx( Word16 *ptr, Word16 bp, TastatEnc *s ) +Word16 ari_done_encoding_14bits_fx( + Word16 *ptr, /* Q0 */ + Word16 bp, /* Q0 */ + TastatEnc *s ) { Word16 bit; @@ -113,11 +116,12 @@ Word16 ari_done_encoding_14bits_fx( Word16 *ptr, Word16 bp, TastatEnc *s ) * \return bit consumption * ------------------------------------------------------------ - */ Word16 ari_encode_14bits_ext_fx( - Word16 *ptr, - Word16 bp, + Word16 *ptr, /* Q0 */ + Word16 bp, /* Q0 */ TastatEnc *s, - Word32 symbol, - UWord16 const *cum_freq ) + Word32 symbol, /* Q0 */ + UWord16 const *cum_freq /* Q0 */ +) { Word32 low; Word32 high; @@ -129,7 +133,7 @@ Word16 ari_encode_14bits_ext_fx( high = L_add( s->high, 0 ); low = L_add( s->low, 0 ); - range = L_sub( high, low ); + range = L_sub( high, low ); /* Q0 */ L_temp1 = L_shl( range, 15 - stat_bitsnew /*both are constants*/ ); Mpy_32_16_ss( L_temp1, cum_freq[symbol + 1], &L_temp2, &temp ); @@ -137,27 +141,27 @@ Word16 ari_encode_14bits_ext_fx( { Mpy_32_16_ss( L_temp1, cum_freq[symbol], &range, &temp ); } - high = L_add( low, range ); - low = L_add( low, L_temp2 ); + high = L_add( low, range ); /* Q0 */ + low = L_add( low, L_temp2 ); /* Q0 */ - bits_to_follow = s->value; + bits_to_follow = s->value; /* Q0 */ move16(); FOR( i = 0; i < 0x7FFF; i++ ) { IF( LE_32( high, ari_q2new ) ) { - bp = ari_put_bit_plus_follow( ptr, bp, bits_to_follow, 0 ); + bp = ari_put_bit_plus_follow( ptr, bp, bits_to_follow, 0 ); /* Q0 */ bits_to_follow = 0; move16(); } ELSE IF( GE_32( low, ari_q2new ) ) { - bp = ari_put_bit_plus_follow( ptr, bp, bits_to_follow, 1 ); + bp = ari_put_bit_plus_follow( ptr, bp, bits_to_follow, 1 ); /* Q0 */ bits_to_follow = 0; move16(); - low = L_sub( low, ari_q2new ); - high = L_sub( high, ari_q2new ); /* Subtract offset to top. */ + low = L_sub( low, ari_q2new ); /* Q0 */ + high = L_sub( high, ari_q2new ); /* Subtract offset to top. Q0*/ } ELSE { @@ -166,9 +170,9 @@ Word16 ari_encode_14bits_ext_fx( { /* Output an opposite bit */ /* later if in middle half. */ - bits_to_follow = add( bits_to_follow, 1 ); - low = L_sub( low, ari_q1new ); /* Subtract offset to middle*/ - high = L_sub( high, ari_q1new ); + bits_to_follow = add( bits_to_follow, 1 ); /* Q0 */ + low = L_sub( low, ari_q1new ); /* Subtract offset to middle Q0*/ + high = L_sub( high, ari_q1new ); /* Q0 */ } ELSE { @@ -176,15 +180,15 @@ Word16 ari_encode_14bits_ext_fx( } } - low = L_add( low, low ); - high = L_add( high, high ); /* Scale up code range. */ + low = L_add( low, low ); /* Q0 */ + high = L_add( high, high ); /* Scale up code range. Q0*/ } - s->low = low; + s->low = low; /* Q0 */ move32(); - s->high = high; + s->high = high; /* Q0 */ move32(); - s->value = bits_to_follow; + s->value = bits_to_follow; /* Q0 */ move16(); return bp; @@ -204,7 +208,14 @@ Word16 ari_encode_overflow_fx( TastatEnc *s ) * * *-------------------------------------------------------------------------*/ -static Word16 ari_encode_14bits_high_low( Word16 *ptr, Word16 bp, Word16 bits, TastatEnc *s, Word32 high, Word32 low ) +static Word16 ari_encode_14bits_high_low( + Word16 *ptr, /* Q0 */ + Word16 bp, /* Q0 */ + Word16 bits, /* Q0 */ + TastatEnc *s, + Word32 high, /* Q0 */ + Word32 low /* Q0 */ +) { Word16 bits_to_follow, tmp; @@ -212,22 +223,22 @@ static Word16 ari_encode_14bits_high_low( Word16 *ptr, Word16 bp, Word16 bits, T move16(); /* while there are more than 16 bits left */ - tmp = sub( 16, bits ); + tmp = sub( 16, bits ); /* Q0 */ WHILE( add( add( bp, bits_to_follow ), tmp ) < 0 ) { IF( LE_32( high, ari_q2new ) ) { - bp = ari_put_bit_plus_follow( ptr, bp, bits_to_follow, 0 ); + bp = ari_put_bit_plus_follow( ptr, bp, bits_to_follow, 0 ); /* Q0 */ bits_to_follow = 0; move16(); } ELSE IF( GE_32( low, ari_q2new ) ) { - bp = ari_put_bit_plus_follow( ptr, bp, bits_to_follow, 1 ); + bp = ari_put_bit_plus_follow( ptr, bp, bits_to_follow, 1 ); /* Q0 */ bits_to_follow = 0; move16(); - low = L_sub( low, ari_q2new ); - high = L_sub( high, ari_q2new ); /* Subtract offset to top. */ + low = L_sub( low, ari_q2new ); /* Q0 */ + high = L_sub( high, ari_q2new ); /* Subtract offset to top. Q0*/ } ELSE { @@ -236,9 +247,9 @@ static Word16 ari_encode_14bits_high_low( Word16 *ptr, Word16 bp, Word16 bits, T { /* Output an opposite bit */ /* later if in middle half. */ - bits_to_follow = add( bits_to_follow, 1 ); - low = L_sub( low, ari_q1new ); /* Subtract offset to middle*/ - high = L_sub( high, ari_q1new ); + bits_to_follow = add( bits_to_follow, 1 ); /* Q0 */ + low = L_sub( low, ari_q1new ); /* Subtract offset to middle Q0*/ + high = L_sub( high, ari_q1new ); /* Q0 */ } ELSE { @@ -246,15 +257,15 @@ static Word16 ari_encode_14bits_high_low( Word16 *ptr, Word16 bp, Word16 bits, T } } - low = L_add( low, low ); - high = L_add( high, high ); /* Scale up code range. */ + low = L_add( low, low ); /* Q0 */ + high = L_add( high, high ); /* Scale up code range. Q0*/ } - s->low = low; + s->low = low; /* Q0 */ move32(); - s->high = high; + s->high = high; /* Q0 */ move32(); - s->value = bits_to_follow; + s->value = bits_to_follow; /* Q0 */ move16(); return bp; @@ -266,14 +277,21 @@ static Word16 ari_encode_14bits_high_low( Word16 *ptr, Word16 bp, Word16 bits, T * Encode an cumulative frequency interval. *-------------------------------------------------------------------------*/ -Word16 ari_encode_14bits_range_fx( Word16 *ptr, Word16 bp, Word16 bits, TastatEnc *s, Word16 cum_freq_low, Word16 cum_freq_high ) +Word16 ari_encode_14bits_range_fx( + Word16 *ptr, /* Q0 */ + Word16 bp, /* Q0 */ + Word16 bits, /* Q0 */ + TastatEnc *s, + Word16 cum_freq_low, /* Q0 */ + Word16 cum_freq_high /* Q0 */ +) { Word32 low, high, range; - range = L_sub( s->high, s->low ); + range = L_sub( s->high, s->low ); /* Q0 */ - high = L_add( s->low, mul_sbc_14bits( range, cum_freq_high ) ); - low = L_add( s->low, mul_sbc_14bits( range, cum_freq_low ) ); + high = L_add( s->low, mul_sbc_14bits( range, cum_freq_high ) ); /* Q0 */ + low = L_add( s->low, mul_sbc_14bits( range, cum_freq_low ) ); /* Q0 */ return ari_encode_14bits_high_low( ptr, bp, bits, s, high, low ); } @@ -284,23 +302,29 @@ Word16 ari_encode_14bits_range_fx( Word16 *ptr, Word16 bp, Word16 bits, TastatEn * * Encode a sign with equal probabilities. *-------------------------------------------------------------------------*/ -Word16 ari_encode_14bits_sign_fx( Word16 *ptr, Word16 bp, Word16 bits, TastatEnc *s, Word16 sign ) +Word16 ari_encode_14bits_sign_fx( + Word16 *ptr, /* Q0 */ + Word16 bp, /* Q0 */ + Word16 bits, /* Q0 */ + TastatEnc *s, + Word16 sign /* Q0 */ +) { Word32 low, high, range; Word32 L_tmp; high = L_add( s->high, 0 ); low = L_add( s->low, 0 ); - range = L_sub( high, low ); + range = L_sub( high, low ); /* Q0 */ L_tmp = L_shr( range, 1 ); if ( sign != 0 ) { - high = L_add( low, L_tmp ); + high = L_add( low, L_tmp ); /* Q0 */ } if ( sign == 0 ) { - low = L_add( low, L_tmp ); + low = L_add( low, L_tmp ); /* Q0 */ } return ari_encode_14bits_high_low( ptr, bp, bits, s, high, low ); @@ -311,28 +335,255 @@ Word16 ari_encode_14bits_sign_fx( Word16 *ptr, Word16 bp, Word16 bits, TastatEnc * * Finish up encoding in CBR mode. *-------------------------------------------------------------------------*/ -Word16 ari_done_cbr_encoding_14bits_fx( Word16 *ptr, Word16 bp, Word16 bits, TastatEnc *s ) +Word16 ari_done_cbr_encoding_14bits_fx( + Word16 *ptr, /* Q0 */ + Word16 bp, /* Q0 */ + Word16 bits, /* Q0 */ + TastatEnc *s ) { Word16 high, tmp, k; - tmp = sub( bits, 16 ); + tmp = sub( bits, 16 ); /* Q0 */ WHILE( GT_16( sub( tmp, bp ), s->value ) ) { - bp = ari_encode_14bits_sign_fx( ptr, bp, bits, s, 0 ); + bp = ari_encode_14bits_sign_fx( ptr, bp, bits, s, 0 ); /* Q0 */ } - high = extract_l( L_sub( s->high, 1 ) ); + high = extract_l( L_sub( s->high, 1 ) ); /* Q0 */ - bp = ari_put_bit_plus_follow( ptr, bp, s->value, lshr( high, 15 ) ); + bp = ari_put_bit_plus_follow( ptr, bp, s->value, lshr( high, 15 ) ); /* Q0 */ high = lshl( high, 1 ); tmp = s_min( 15, sub( bits, bp ) ); FOR( k = 0; k < tmp; ++k ) { - ptr[bp++] = lshr( high, 15 ); + ptr[bp++] = lshr( high, 15 ); /* Q0 */ move16(); high = lshl( high, 1 ); } return bp; } + +void ari_start_encoding_14bits_ivas_fx( + Tastat *s ) +{ + /* : addressing is made with walking pointer s */ + s->low = 0; + s->high = ari_q4new; + s->bits_to_follow = 0; + move32(); + move32(); + move32(); + + return; +} + +/*--------------------------------------------------------------- + * ari_done_encoding_14bits_ivas_fx() + * + * Finish ArCo encoding + *-------------------------------------------------------------*/ + +Word16 ari_done_encoding_14bits_ivas_fx( + Word16 *ptr, /* Q0 */ + Word16 bp, /* Q0 */ + Tastat *s ) +{ + Word16 bit; + + bit = 0; + move16(); + IF( GE_32( s->low, ari_q1new ) ) + { + bit = s_xor( bit, 1 ); + } + return ari_put_bit_plus_follow( ptr, bp, add( extract_l( s->bits_to_follow ), 1 ), bit ); +} + + +/*--------------------------------------------------------------- + * ari_encode_14bits_ext_ivas_fx() + * + * encode function for extended proba tables: less branches needed for coding + * + *-------------------------------------------------------------*/ +Word16 ari_encode_14bits_ext_ivas_fx( + Word16 *ptr, /* Q0 */ + Word16 bp, /* Q0 */ + Tastat *s, + Word32 symbol, /* Q0 */ + UWord16 const *cum_freq /* Q0 */ +) +{ + Word32 low; + Word32 high; + Word32 range; + Word16 bits_to_follow; + Word16 i; + UWord16 temp; + Word32 L_temp1, L_temp2; + + high = L_add( s->high, 0 ); + low = L_add( s->low, 0 ); + range = L_add( L_sub( high, low ), 1 ); /* Q0 */ + + L_temp1 = L_shl( range, 15 - stat_bitsnew /*both are constants*/ ); + Mpy_32_16_ss( L_temp1, cum_freq[symbol + 1], &L_temp2, &temp ); + IF( symbol != 0 ) /* when symbol is 0, range remains unchanged */ + { + Mpy_32_16_ss( L_temp1, cum_freq[symbol], &range, &temp ); + } + high = L_sub( L_add( low, range ), 1 ); /* Q0 */ + low = L_add( low, L_temp2 ); /* Q0 */ + + assert( s->bits_to_follow <= MAX_16 ); + bits_to_follow = extract_l( s->bits_to_follow ); /* Q0 */ + + FOR( i = 0; i < 0x7FFF; i++ ) + { + IF( LT_32( high, ari_q2new ) ) + { + bp = ari_put_bit_plus_follow( ptr, bp, bits_to_follow, 0 ); /* Q0 */ + bits_to_follow = 0; + move16(); + } + ELSE IF( GE_32( low, ari_q2new ) ) + { + bp = ari_put_bit_plus_follow( ptr, bp, bits_to_follow, 1 ); /* Q0 */ + bits_to_follow = 0; + move16(); + low = L_sub( low, ari_q2new ); + high = L_sub( high, ari_q2new ); /* Subtract offset to top. */ + } + ELSE + { + test(); + IF( GE_32( low, ari_q1new ) && LT_32( high, ari_q3new ) ) + { + /* Output an opposite bit */ + /* later if in middle half. */ + bits_to_follow = add( bits_to_follow, 1 ); /* Q0 */ + low = L_sub( low, ari_q1new ); /* Subtract offset to middle*/ + high = L_sub( high, ari_q1new ); + } + ELSE + { + BREAK; /* Otherwise exit loop. */ + } + } + low = L_add( low, low ); /* Q0 */ + high = L_add( L_add( high, high ), 1 ); /* Scale up code range. Q0*/ + } + + s->low = low; /* Q0 */ + move32(); + s->high = high; /* Q0 */ + move32(); + s->bits_to_follow = bits_to_follow; /* Q0 */ + move32(); + + return bp; +} + + +/*------------------------------------------------------------------------ + * Function: ari_encode_14bits_high_low_fx() + * + *-------------------------------------------------------------------------*/ + +static Word16 ari_encode_14bits_high_low_ivas_fx( + Word16 *ptr, /* Q0 */ + Word16 bp, /* Q0 */ + Word16 bits, /* Q0 */ + Tastat *s, + Word32 high, /* Q0 */ + Word32 low /* Q0 */ +) +{ + Word16 bits_to_follow, tmp; + + bits_to_follow = extract_l( s->bits_to_follow ); /* Q0 */ + move16(); + + /* while there are more than 16 bits left */ + tmp = sub( 16, bits ); /* Q0 */ + WHILE( add( add( bp, bits_to_follow ), tmp ) < 0 ) + { + IF( LE_32( high, ari_q2new ) ) + { + bp = ari_put_bit_plus_follow( ptr, bp, bits_to_follow, 0 ); /* Q0 */ + bits_to_follow = 0; + move16(); + } + ELSE IF( GE_32( low, ari_q2new ) ) + { + bp = ari_put_bit_plus_follow( ptr, bp, bits_to_follow, 1 ); /* Q0 */ + bits_to_follow = 0; + move16(); + low = L_sub( low, ari_q2new ); /* Q0 */ + high = L_sub( high, ari_q2new ); /* Subtract offset to top. Q0*/ + } + ELSE + { + test(); + IF( GE_32( low, ari_q1new ) && LE_32( high, ari_q3new ) ) + { + /* Output an opposite bit */ + /* later if in middle half. */ + bits_to_follow = add( bits_to_follow, 1 ); /* Q0 */ + low = L_sub( low, ari_q1new ); /* Subtract offset to middle Q0*/ + high = L_sub( high, ari_q1new ); /* Q0 */ + } + ELSE + { + BREAK; /* Otherwise exit loop. */ + } + } + + low = L_add( low, low ); + high = L_add( high, high ); /* Scale up code range. */ + } + + s->low = low; /* Q0 */ + move32(); + s->high = L_sub( high, 1 ); /* Q0 */ + move32(); + s->bits_to_follow = bits_to_follow; /* Q0 */ + move16(); + + return bp; +} + +/*------------------------------------------------------------------------ + * Function: ari_encode_14bits_sign_ivas_fx() + * + * Encode a sign with equal probabilities. + *-------------------------------------------------------------------------*/ +Word16 ari_encode_14bits_sign_ivas_fx( + Word16 *ptr, /* Q0 */ + Word16 bp, /* Q0 */ + Word32 bits, /* Q0 */ + Tastat *s, + Word16 sign /* Q0 */ +) +{ + Word32 low, high, range; + Word32 L_tmp; + + high = L_add( s->high, 1 ); + low = L_add( s->low, 0 ); + range = L_sub( high, low ); /* Q0 */ + + L_tmp = L_shr( range, 1 ); + if ( sign != 0 ) + { + high = L_add( low, L_tmp ); /* Q0 */ + } + if ( sign == 0 ) + { + low = L_add( low, L_tmp ); /* Q0 */ + } + + return ari_encode_14bits_high_low_ivas_fx( ptr, bp, extract_l( bits ), s, high, low ); +} diff --git a/lib_enc/ari_hm_enc.c b/lib_enc/ari_hm_enc.c deleted file mode 100644 index a227784dc30e0652485647f39060944aeb5d5d0c..0000000000000000000000000000000000000000 --- a/lib_enc/ari_hm_enc.c +++ /dev/null @@ -1,53 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include -#include "options.h" -#include -#include "cnst.h" -#include "rom_enc.h" -#include "stl.h" -#include "basop_util.h" -#include "prot.h" -#include "rom_com.h" -#include "wmc_auto.h" - -/*-------------------------------------------------------------------* - * EncodeIndex() - * - * - *-------------------------------------------------------------------*/ diff --git a/lib_enc/ari_hm_enc_fx.c b/lib_enc/ari_hm_enc_fx.c index 3e6519a3b5fece3f0303e3cece17091315d6df23..76d48ccf4318fd1aa0931b8b8358876751c1d6e1 100644 --- a/lib_enc/ari_hm_enc_fx.c +++ b/lib_enc/ari_hm_enc_fx.c @@ -10,9 +10,7 @@ #include "basop_util.h" #include "rom_com.h" #include "rom_enc.h" -#include "prot.h" -//#include "prot_fx.h" -#include "prot_fx.h" /* Function prototypes */ +#include "prot_fx.h" #include "prot_fx_enc.h" /* Function prototypes */ /*-------------------------------------------------------------------* @@ -87,7 +85,7 @@ Word16 EncodeIndex_ivas_fx( * *-------------------------------------------------------------------*/ static Word16 SearchPeriodicityIndex_Single( - const Word16 AbsMdct3[], + const Word16 AbsMdct3[], // Qx const Word16 NumToConsider, const Word32 Lag, const Word16 FractionalResolution ) @@ -131,7 +129,7 @@ static Word16 SearchPeriodicityIndex_Single( * *-------------------------------------------------------------------*/ static void SearchPeriodicityIndex_Range( - const Word16 AbsMdct3[], + const Word16 AbsMdct3[], // Qx const Word16 NumToConsider, const Word16 Lo, const Word16 Hi, @@ -139,7 +137,8 @@ static void SearchPeriodicityIndex_Range( const Word16 Adj, const Word16 Spacing, Word16 *PeriodicityIndex, - Word16 *Score ) + Word16 *Score // Q0 +) { Word16 Index, BestIndex; Word16 CurrentScore, BestScore; @@ -194,7 +193,7 @@ static void SearchPeriodicityIndex_Range( B = add( BestIndex, shr( Spacing, 1 ) ); - FOR( Index = add( BestIndex, 1 ); Index <= B; ++Index ) + FOR( Index = BestIndex + 1; Index <= B; ++Index ) { CurrentScore = SearchPeriodicityIndex_Single( AbsMdct3, @@ -225,7 +224,7 @@ Word16 SearchPeriodicityIndex_fx( Word16 NumToConsider, /* i : Number of coefficients */ const Word16 TargetBits, /* i : Target bit budget (excl. Done flag) */ const Word16 LtpPitchLag, /* i : TCX-LTP pitch */ - const Word16 LtpGain, /* i : LTP gain */ + const Word16 LtpGain, /* i : LTP gain Q15 */ Word16 *RelativeScore /* o : Energy concentration factor (2Q13) */ ) { @@ -244,11 +243,12 @@ Word16 SearchPeriodicityIndex_fx( Word32 tmp32; #ifdef BASOP_NOGLOB_DECLARE_LOCAL Flag Overflow = 0; + move32(); #endif /* Debug init (not instrumented) */ C = -3000; - + move32(); PeriodicityIndex = 0; move16(); Score = -1; @@ -264,18 +264,22 @@ Word16 SearchPeriodicityIndex_fx( { C = L_shl( L_abs( Mdct[i + 1] ), s ); AbsMdct3[i] = round_fx( L_add( L_add( A, B ), C ) ); + move16(); A = L_shl( L_abs( Mdct[i + 2] ), s ); AbsMdct3[i + 1] = round_fx( L_add( L_add( A, B ), C ) ); + move16(); B = L_shl( L_abs( Mdct[i + 3] ), s ); AbsMdct3[i + 2] = round_fx( L_add( L_add( A, B ), C ) ); + move16(); } IF( LT_16( i, sub( NumToConsider, 1 ) ) ) { C = L_shl( L_abs( Mdct[i + 1] ), s ); AbsMdct3[i] = round_fx( L_add( L_add( A, B ), C ) ); + move16(); } IF( LT_16( i, sub( NumToConsider, 2 ) ) ) @@ -283,6 +287,7 @@ Word16 SearchPeriodicityIndex_fx( A = L_shl( L_abs( Mdct[i + 2] ), s ); assert( C != -3000 ); AbsMdct3[i + 1] = round_fx( L_add( L_add( A, B ), C ) ); + move16(); } AbsTotal = L_deposit_l( 0 ); @@ -452,17 +457,9 @@ Word16 SearchPeriodicityIndex_fx( tmp32 = L_mult0( Score, NumToConsider ); /* -> 16Q15 */ tmp = sub( norm_l( tmp32 ), 1 ); tmp2 = norm_l( AbsTotal ); -#ifdef BASOP_NOGLOB tmp3 = div_s( round_fx_o( L_shl_o( tmp32, tmp, &Overflow ), &Overflow ), round_fx_o( L_shl_o( AbsTotal, tmp2, &Overflow ), &Overflow ) ); *RelativeScore = shr_o( tmp3, add( sub( tmp, tmp2 ), 2 ), &Overflow ); /* -> 2Q13 */ move16(); -#else - tmp3 = div_s( round_fx( L_shl( tmp32, tmp ) ), round_fx( L_shl( AbsTotal, tmp2 ) ) ); - BASOP_SATURATE_WARNING_OFF_EVS - *RelativeScore = shr( tmp3, add( sub( tmp, tmp2 ), 2 ) ); /* -> 2Q13 */ - move16(); - BASOP_SATURATE_WARNING_ON_EVS -#endif } ELSE { @@ -479,8 +476,8 @@ Word16 SearchPeriodicityIndex_fx( *-------------------------------------------------------------------*/ static void PeakFilter( - const Word32 x[], /* i : absolute spectrum */ - Word32 y[], /* O : filtered absolute spectrum, must not alias x[] */ + const Word32 x[], /* i : absolute spectrum Qx */ + Word32 y[], /* O : filtered absolute spectrum, must not alias x[] Q(x-4)*/ const Word16 L_frame /* i : number of spectral lines */ ) { @@ -491,7 +488,7 @@ static void PeakFilter( flen = shr( L_frame, 4 ); /* m = kPeakElevationThreshold / (float)(2*flen + 1); */ - m = shr( div_s( 8 /*kPeakElevationThreshold Q3*/, add( shl( flen, 1 ), 1 ) ), 3 ); + m = shr( div_s( 8 /*kPeakElevationThreshold Q3*/, add( shl( flen, 1 ), 1 ) ), 3 ); // Q15 a = L_deposit_l( 0 ); FOR( i = 0; i < flen; ++i ) @@ -501,14 +498,14 @@ static void PeakFilter( FOR( i = 0; i < flen; ++i ) { - y[i] = L_max( 0, L_sub( L_shr( x[i], 4 ), Mpy_32_16_1( a, m ) ) ); + y[i] = L_max( 0, L_sub( L_shr( x[i], 4 ), Mpy_32_16_1( a, m ) ) ); // Q(x-4) move32(); a = L_add( a, L_shr( x[i + flen], 4 ) ); } sub( 0, 0 ); FOR( ; i < L_frame - flen; ++i ) { - y[i] = L_max( 0, L_sub( L_shr( x[i], 4 ), Mpy_32_16_1( a, m ) ) ); + y[i] = L_max( 0, L_sub( L_shr( x[i], 4 ), Mpy_32_16_1( a, m ) ) ); // Q(x-4) move32(); a = L_sub( a, L_shr( x[i - flen], 4 ) ); a = L_add( a, L_shr( x[i + flen], 4 ) ); @@ -516,7 +513,7 @@ static void PeakFilter( FOR( ; i < L_frame; ++i ) { - y[i] = L_max( 0, L_sub( L_shr( x[i], 4 ), Mpy_32_16_1( a, m ) ) ); + y[i] = L_max( 0, L_sub( L_shr( x[i], 4 ), Mpy_32_16_1( a, m ) ) ); // Q(x-4) move32(); a = L_sub( a, L_shr( x[i - flen], 4 ) ); } @@ -598,7 +595,7 @@ static Word32 tcx_hm_get_re( *-------------------------------------------------------------------*/ static void tcx_hm_quantize_gain( - const Word32 x[], /* i: absolute spectrum Q31-e */ + const Word32 x[], /* i: absolute spectrum Q31-x_e */ const Word16 *x_e, /* i: absolute spectrum exponent Q0 */ const Word32 env[], /* i: envelope Q16 */ const Word32 lag, /* i: pitch lag Q0 */ @@ -645,6 +642,7 @@ static void tcx_hm_quantize_gain( FOR( i = 0; i < L_frame; ++i ) { x16[i] = extract_h( L_shl( x[i], s_x ) ); + move16(); } be = tcx_hm_get_re( x16, *gain, lag, fract_res, p, env, L_frame ); @@ -698,7 +696,8 @@ static void tcx_hm_quantize_gain( /* Minimum selection, pe is Q14 */ IF( LT_32( L_shl( Mpy_32_16_1( e, pe ), 1 ), be ) ) { - be = L_add( e, 0 ); + be = e; + move32(); *gain_idx = g; move16(); *gain = qGains[s][g]; diff --git a/lib_enc/arith_coder_enc.c b/lib_enc/arith_coder_enc.c deleted file mode 100644 index 5680feed42ee0e30f885765fcede5cc00420d9fa..0000000000000000000000000000000000000000 --- a/lib_enc/arith_coder_enc.c +++ /dev/null @@ -1,51 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include -#include "options.h" -#include -#include "cnst.h" -#include "prot.h" -#include "rom_com.h" -#include "basop_util.h" -#include "basop_proto_func.h" -#include "wmc_auto.h" -#include "prot_fx.h" - -/*-------------------------------------------------------------------* - * Local constants - *-------------------------------------------------------------------*/ diff --git a/lib_enc/arith_coder_enc_fx.c b/lib_enc/arith_coder_enc_fx.c index 6b137f31e1b30c7a61fc9386be150537360c3a62..98a5173f592f6f5c41fd26316bd5ec30b4d72ede 100644 --- a/lib_enc/arith_coder_enc_fx.c +++ b/lib_enc/arith_coder_enc_fx.c @@ -50,6 +50,7 @@ static Word16 tcx_arith_estimate_scale( Word32 L_tmp, accu; #ifdef BASOP_NOGLOB_DECLARE_LOCAL Flag Overflow = 0; + move32(); #endif @@ -71,11 +72,7 @@ static Word16 tcx_arith_estimate_scale( s1 = norm_l( abs_spectrum[k] ); } -#ifdef BASOP_NOGLOB tmp = mult_r( round_fx_o( L_shl( abs_spectrum[k], s1 ), &Overflow ), envelope[k] ); -#else /* BASOP_NOGLOB */ - tmp = mult_r( round_fx( L_shl( abs_spectrum[k], s1 ) ), envelope[k] ); -#endif /* BASOP_NOGLOB */ L_tmp = L_mult0( tmp, tmp ); tmp = sub( shl( s1, 1 ), 1 ); @@ -92,11 +89,7 @@ static Word16 tcx_arith_estimate_scale( /* scale and accumulate */ BASOP_SATURATE_WARNING_OFF_EVS; -#ifdef BASOP_NOGLOB accu = L_add_sat( accu, L_shr( L_tmp, sub( tmp, s ) ) ); -#else - accu = L_add( accu, L_shr( L_tmp, sub( tmp, s ) ) ); -#endif BASOP_SATURATE_WARNING_ON_EVS; } s = sub( shl( add( abs_spectrum_e, envelope_e ), 1 ), s ); @@ -195,19 +188,21 @@ static Word16 tcx_arith_find_max_scale( /* Q15-e * Heap heap = { { { 0, 0 } }, 0 }; /* silence a compiler warning */ Word16 tmpi1, tmpi2; const Word32 limit = -325614240l /*-9.70406052784f Q25*/; /* = ln(1/16384): log of smallest allowed probability */ - + move32(); /* Find the top most offending lines according to probability estimates */ FOR( i = 0; i < kMaxNumHeapElems; i++ ) { heap.mElem[i].mIndex = 0; move16(); heap.mElem[i].mScore = L_deposit_l( 0 ); + move32(); } tmp = add( shl( kMaxNumHeapElems, 1 ), 1 ); FOR( ; i < tmp; i++ ) { heap.mElem[i].mScore = L_deposit_h( 0x7FFF ); + move32(); } FOR( k = 0; k < L_frame; k++ ) @@ -374,6 +369,7 @@ static Word16 tcx_arith_rateloop( Word32 tmp2; #ifdef BASOP_NOGLOB_DECLARE_LOCAL Flag Overflow = 0; + move32(); #endif @@ -383,13 +379,7 @@ static Word16 tcx_arith_rateloop( scale_max = tcx_arith_find_max_scale( abs_spectrum, abs_spectrum_e, L_frame, envelope, envelope_e, exps, deadzone, scale_e ); -#ifdef BASOP_NOGLOB scale = shl_o( scale, sub( tmp, *scale_e ), &Overflow ); -#else - BASOP_SATURATE_WARNING_OFF_EVS; - scale = shl( scale, sub( tmp, *scale_e ) ); - BASOP_SATURATE_WARNING_ON_EVS; -#endif scale = s_min( scale, scale_max ); scale_best = scale; @@ -414,13 +404,14 @@ static Word16 tcx_arith_rateloop( L_tmp = L_mac( 0x7FFFFFFF, exps[k], (Word16) 0x8000 ); /* Q31 */ L_tmp = L_negate( BASOP_Util_Log2( L_tmp ) ); /* Q25 */ fixed_bits[0][k] = round_fx( L_tmp ); /* Q9 */ - + move16(); /* fixed_bits[1][k] = 1 - s*0.5f*LOG2_E - log2f(1 - (exps[k]/65536.0f) * (exps[k]/65536.0f)); */ L_tmp = L_msu( 0x7FFFFFFF, exps[k], exps[k] ); /* Q31 */ L_tmp = BASOP_Util_Log2( L_tmp ); /* Q25 */ L_tmp = L_sub( 1 << 25, L_tmp ); L_tmp = L_sub( L_tmp, L_shl( L_mult0( mult_r( envelope[k], LOG2_E ), 1 << 10 ), envelope_e ) ); fixed_bits[1][k] = round_fx( L_tmp ); /* Q9 */ + move16(); } tmp2 = L_msu0( L_sub( max_complexity, 48 ), L_frame, 11 ); @@ -449,13 +440,7 @@ static Word16 tcx_arith_rateloop( { /* Update estimator temporal compensation factor */ tmp = BASOP_Util_Divide3232_Scale( L_mult0( target_bits, 1 << 9 ), bits, &s ); -#ifdef BASOP_NOGLOB tmp = shl_o( mult_r( *target_bits_fac, tmp ), s, &Overflow ); -#else - BASOP_SATURATE_WARNING_OFF_EVS; - tmp = shl( mult_r( *target_bits_fac, tmp ), s ); - BASOP_SATURATE_WARNING_ON_EVS; -#endif tmp = s_min( tmp, 20480 /*1.25f Q14*/ ); tmp = s_max( tmp, 12288 /*0.75f Q14*/ ); *target_bits_fac = tmp; @@ -485,15 +470,8 @@ static Word16 tcx_arith_rateloop( { /* adjust = 1.25f * target_bits / (float)bits; */ tmp = BASOP_Util_Divide3232_Scale( L_mult0( target_bits, 0x280 ), bits, &s ); -#ifdef BASOP_NOGLOB adjust = shl_o( tmp, sub( s, 1 ), &Overflow ); /* Q14 */ scale = shl_o( mult_r( scale, adjust ), 1, &Overflow ); -#else - BASOP_SATURATE_WARNING_OFF_EVS; /* adjust limited to <= 2.0, scale to <= scale_max */ - adjust = shl( tmp, sub( s, 1 ) ); /* Q14 */ - scale = shl( mult_r( scale, adjust ), 1 ); - BASOP_SATURATE_WARNING_ON_EVS; -#endif scale = s_min( scale, scale_max ); } } @@ -708,6 +686,8 @@ void tcx_arith_encode_envelope_fx( #ifdef BASOP_NOGLOB_DECLARE_LOCAL Flag Overflow = 0; Flag Carry = 0; + move32(); + move32(); #endif assert( L_spec <= N_MAX_ARI ); @@ -730,6 +710,7 @@ void tcx_arith_encode_envelope_fx( FOR( k = 0; k < L_spec; k++ ) { signs[k] = extract_l( L_lshr( spectrum[k], 31 ) ); + move16(); if ( spectrum[k] < 0 ) { spectrum[k] = L_abs( spectrum[k] ); @@ -767,6 +748,7 @@ void tcx_arith_encode_envelope_fx( FOR( k = 0; k < L_spec; k++ ) { exponents[k] = round_fx( expfp( envelope[k], tmp ) ); + move16(); } scale = tcx_arith_rateloop( spectrum, *spectrum_e, L_spec, envelope, envelope_e, exponents, target_bits, deadzone, deadzone_flags, &( hTcxEnc->tcx_target_bits_fac ), &scale_e ); @@ -782,20 +764,18 @@ void tcx_arith_encode_envelope_fx( { /* quantise using dead-zone */ q_spectrum[k] = extract_h( L_add( L_shl( Mpy_32_16_1( spectrum[k], scale ), tmp ), L_tmp ) ); + move16(); } /* Final encoding */ *arith_bits = tcx_arith_encode( q_spectrum, signs, kMax, L_spec, exponents, target_bits, prm ); + move16(); /* Multiply back the signs */ L_tmp2 = L_deposit_l( 0 ); FOR( k = 0; k <= kMax; k++ ) { -#ifdef BASOP_NOGLOB L_tmp2 = L_macNs_co( L_tmp2, q_spectrum[k], k, &Carry, &Overflow ); -#else /* BASOP_NOGLOB */ - L_tmp2 = L_macNs( L_tmp2, q_spectrum[k], k ); -#endif if ( signs[k] != 0 ) L_tmp = L_mult( q_spectrum[k], -( 1 << ( 30 - SPEC_EXP_DEC ) ) ); @@ -810,4 +790,136 @@ void tcx_arith_encode_envelope_fx( /* noise filling seed */ *nf_seed = extract_l( L_tmp2 ); + move16(); +} + +void tcx_arith_encode_envelope_ivas_fx( + Word32 spectrum[], /* i/o: MDCT coefficients Q31-e */ + Word16 *spectrum_e, /* i/o: MDCT exponent Q0 */ + Word16 signs[], /* o: signs (spectrum[.]<0) Q0 */ + const Word16 L_frame, /* i: frame or MDCT length Q0 */ + const Word16 L_spec, /* i: frame or MDCT length Q0 */ + Encoder_State *st, /* i/o: coder state */ + const Word16 A_ind[], /* i: quantised LPC coefficients Q12 */ + Word16 target_bits, /* i: number of available bits Q0 */ + Word16 prm[], /* o: bitstream parameters Q0 */ + const Word8 use_hm, /* i: use HM in current frame? */ + Word16 prm_hm[], /* o: HM parameter area Q0 */ + const Word16 tcxltp_pitch, /* i: TCX LTP pitch in FD, -1 if n/a Q0*/ + Word16 *arith_bits, /* o: bits used for ari. coding Q0 */ + Word16 *signaling_bits, /* o: bits used for signaling Q0 */ + const Word16 low_complexity /* i: low-complexity flag Q0 */ +) +{ + Word32 env[N_MAX_ARI]; /* unscaled envelope (Q16) */ + Word16 *envelope; /* scaled envelope (Q15-e) */ + Word16 envelope_e; + Word16 exponents[N_MAX_ARI]; /* Q15 */ + Word16 L_spec_core; + Word16 *q_spectrum; + TCX_CONFIG_HANDLE hTcxCfg; + Word16 scale, scale_e; + Word16 k, kMax; + Word16 deadzone; + const Word8 *deadzone_flags; + Word16 gamma_w, gamma_uw; + Word16 hm_bits; + Word32 L_tmp; + Word16 tmp; + TCX_ENC_HANDLE hTcxEnc = st->hTcxEnc; + + assert( L_spec <= N_MAX_ARI ); + + hTcxCfg = st->hTcxCfg; + deadzone = hTcxCfg->sq_rounding; + move16(); + deadzone_flags = hTcxEnc->memQuantZeros; + *signaling_bits = 0; + move16(); + + assert( st->enableTcxLpc ); + gamma_w = 32767 /*1.0f Q15*/; + move16(); + gamma_uw = st->inv_gamma; + move16(); + + tcx_arith_render_envelope( A_ind, L_frame, L_spec, hTcxCfg->preemph_fac, gamma_w, gamma_uw, env ); + + FOR( k = 0; k < L_spec; k++ ) + { + signs[k] = extract_l( L_lshr( spectrum[k], 31 ) ); + move16(); + if ( spectrum[k] < 0 ) + { + spectrum[k] = L_abs( spectrum[k] ); + move32(); + } + } + + IF( use_hm != 0 ) + { + tcx_hm_analyse_fx( spectrum, spectrum_e, L_spec, env, target_bits, hTcxCfg->coder_type, prm_hm, tcxltp_pitch, hTcxEnc->tcxltp_gain, &hm_bits ); + + target_bits = sub( target_bits, hm_bits ); + *signaling_bits = add( *signaling_bits, hm_bits ); + move16(); + } + ELSE + { + prm_hm[0] = 0; /* just to be sure */ + move16(); + hm_bits = 0; + move16(); + } + + L_spec_core = L_spec; + move16(); + if ( st->igf ) + { + L_spec_core = s_min( L_spec_core, st->hIGFEnc->infoStartLine ); + } + envelope = (Word16 *) env; + + tcx_arith_scale_envelope( L_spec, L_spec_core, env, target_bits, low_complexity, envelope, &envelope_e ); + + tmp = sub( envelope_e, 1 + 15 ); + FOR( k = 0; k < L_spec; k++ ) + { + exponents[k] = round_fx( expfp( envelope[k], tmp ) ); + move16(); + } + + scale = tcx_arith_rateloop( spectrum, *spectrum_e, L_spec, envelope, envelope_e, exponents, target_bits, deadzone, deadzone_flags, &( hTcxEnc->tcx_target_bits_fac ), &scale_e ); + + /* Final quantization */ + kMax = tcx_arith_find_kMax( spectrum, *spectrum_e, L_spec, scale, scale_e, deadzone, deadzone_flags ); + + q_spectrum = (Word16 *) env; /* Reuse buffer */ + + L_tmp = L_mult( deadzone, 1 ); /* Q16 */ + tmp = add( sub( *spectrum_e, 15 ), scale_e ); + FOR( k = 0; k <= kMax; k++ ) + { + /* quantise using dead-zone */ + q_spectrum[k] = extract_h( L_add( L_shl( Mpy_32_16_1( spectrum[k], scale ), tmp ), L_tmp ) ); + move16(); + } + + /* Final encoding */ + *arith_bits = tcx_arith_encode( q_spectrum, signs, kMax, L_spec, exponents, target_bits, prm ); + move16(); + + /* Multiply back the signs */ + FOR( k = 0; k <= kMax; k++ ) + { + if ( signs[k] != 0 ) + L_tmp = L_mult( q_spectrum[k], -( 1 << ( 30 - SPEC_EXP_DEC ) ) ); + if ( signs[k] == 0 ) + L_tmp = L_mult( q_spectrum[k], 1 << ( 30 - SPEC_EXP_DEC ) ); + spectrum[k] = L_tmp; + move32(); + } + *spectrum_e = SPEC_EXP_DEC; + move16(); + set32_fx( spectrum + k, 0, sub( s_max( L_frame, L_spec ), k ) ); } diff --git a/lib_enc/avq_cod.c b/lib_enc/avq_cod.c deleted file mode 100644 index 8e752f0ac516550ba25f4c9dcce588dfd9e16b42..0000000000000000000000000000000000000000 --- a/lib_enc/avq_cod.c +++ /dev/null @@ -1,42 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include -#include "prot.h" -#include "rom_com.h" -#include "wmc_auto.h" diff --git a/lib_enc/avq_cod_fx.c b/lib_enc/avq_cod_fx.c index 094d3fd78340282c0991914c8ee18a9216c1a0b1..962b715cd7a1068638db2451a6547556ac1c0eb8 100644 --- a/lib_enc/avq_cod_fx.c +++ b/lib_enc/avq_cod_fx.c @@ -5,9 +5,7 @@ #include #include "options.h" /* Compilation switches */ #include "cnst.h" -#include /* Compilation switches */ -#include "prot.h" /* Function prototypes */ -//#include "prot_fx.h" /* Function prototypes */ +#include /* Compilation switches */ #include "prot_fx.h" /* Function prototypes */ #include "prot_fx_enc.h" /* Function prototypes */ #include "rom_com.h" /* Static table prototypes */ @@ -16,7 +14,7 @@ * Local prototypes *-------------------------------------------------------------------*/ static void wrte_cv( BSTR_ENC_HANDLE hBstr, const Word16 nq, const Word16 i_ind, const Word16 kv_ind, UWord16 I, Word16 kv[], Word16 *bits ); -static void wrte_cv_ivas( BSTR_ENC_HANDLE hBstr, const Word16 nq, const Word16 i_ind, const Word16 kv_ind, UWord16 I, Word16 kv[], Word16 *bits ); +static void wrte_cv_ivas_fx( BSTR_ENC_HANDLE hBstr, const Word16 nq, const Word16 i_ind, const Word16 kv_ind, UWord16 I, Word16 kv[], Word16 *bits ); /*-------------------------------------------------------------------* * Function AVQ_cod() * @@ -25,7 +23,7 @@ static void wrte_cv_ivas( BSTR_ENC_HANDLE hBstr, const Word16 nq, const Word16 i *-------------------------------------------------------------------*/ void AVQ_cod_fx( /* o: comfort noise gain factor */ - const Word16 xri[], /* i: vector to quantize */ + const Word16 xri[], /* i: vector to quantize Qx*/ Word16 xriq[], /* o: quantized normalized vector (assuming the bit budget is enough) */ const Word16 NB_BITS, /* i: number of allocated bits */ const Word16 Nsv, /* i: number of subvectors (lg=Nsv*8) */ @@ -55,11 +53,7 @@ void AVQ_cod_fx( /* o: comfort noise gain factor Lener = L_shl( 4, shl( Q_in, 1 ) ); /* to set ebits >= 0 */ FOR( i = 0; i < 8; i++ ) { -#ifdef BASOP_NOGLOB Lener = L_mac_o( Lener, xri[l * 8 + i], xri[l * 8 + i], &Overflow ); -#else - Lener = L_mac( Lener, xri[l * 8 + i], xri[l * 8 + i] ); -#endif } /* estimated bit consumption when gain=1 */ /* ebits[l] = 5.0 * FAC_LOG2 * (Word16)log10(ener * 0.5) */ @@ -72,7 +66,8 @@ void AVQ_cod_fx( /* o: comfort noise gain factor Ltmp = L_mac( Ltmp, f_ebits, 1 ); Ltmp = L_add( L_shl( Ltmp, 6 ), L_shl( Ltmp, 4 ) ); /* Mult by 5.0 and then by 16 (To go to Q4). Do it using Mult by 80 (which is 64+16) */ ebits[l] = round_fx( Ltmp ); /*Q4*/ - tot_est_bits = add( tot_est_bits, shr( ebits[l], 4 ) ); + move16(); + tot_est_bits = add( tot_est_bits, shr( ebits[l], 4 ) ); // Q0 } test(); test(); @@ -89,12 +84,12 @@ void AVQ_cod_fx( /* o: comfort noise gain factor /* estimate gain according to number of bits allowed */ /* start at the middle (offset range = 0 to 255.75) Q6 */ - fac = 2048; + fac = 2048; // 128.0f in Q4 move16(); offset = 0; move16(); - Ltmp = L_mult( 31130, sub( NB_BITS, Nsv ) ); /* (1810 - 8 - 1152/8)*.95*/ + Ltmp = L_mult( 31130 /*.95f in Q15*/, sub( NB_BITS, Nsv ) ); /* (1810 - 8 - 1152/8)*.95*/ nbits_max = round_fx( L_shl( Ltmp, 4 ) ); /* tree search with 10 iterations : offset with step of 0.25 bits (0.3 dB) */ @@ -115,7 +110,7 @@ void AVQ_cod_fx( /* o: comfort noise gain factor { offset = sub( offset, fac ); } - fac = mult( fac, 16384 ); + fac = mult( fac, 16384 /*.5 in Q15*/ ); } Ltmp = L_shr( L_mult( offset, 13107 ), 6 ); /* offset((2^21)/160 */ @@ -123,11 +118,7 @@ void AVQ_cod_fx( /* o: comfort noise gain factor /* estimated gain (when offset=0, estimated gain=1) */ f_tmp = L_Extract_lc( Ltmp, &e_tmp ); tmp16 = extract_l( Pow2( 14, f_tmp ) ); -#ifdef BASOP_NOGLOB Lgain = L_shl_sat( tmp16, e_tmp ); -#else - Lgain = L_shl( tmp16, e_tmp ); -#endif /* gain_inv = 1.0f / gain */ e_tmp = norm_l( Lgain ); tmp16 = extract_h( L_shl( Lgain, e_tmp ) ); @@ -141,7 +132,7 @@ void AVQ_cod_fx( /* o: comfort noise gain factor l_8 = shl( l, 3 ); FOR( i = 0; i < 8; i++ ) { - x1[i] = L_shl( L_mult( xri[l_8 + i], gain_inv ), e_tmp ); + x1[i] = L_shl( L_mult( xri[l_8 + i], gain_inv ), e_tmp ); // Q15 move32(); } @@ -149,7 +140,7 @@ void AVQ_cod_fx( /* o: comfort noise gain factor FOR( i = 0; i < 8; i++ ) { - xriq[l_8 + i] = c[i]; + xriq[l_8 + i] = c[i]; // Q0 move16(); } } @@ -157,7 +148,7 @@ void AVQ_cod_fx( /* o: comfort noise gain factor /* round_fx bit allocations and save */ FOR( i = 0; i < Nsv; i++ ) { - xriq[( Nsv * 8 ) + i] = shl( ebits[i], 7 - 4 ); + xriq[( Nsv * 8 ) + i] = shl( ebits[i], 7 - 4 ); // Q0 move16(); } @@ -229,8 +220,8 @@ void AVQ_encmux_fx( /* sort subvectors by estimated bit allocations in decreasing order */ t = kv; - move16(); /* reuse vector to save memory */ - move16(); /*ptr init*/ + /* reuse vector to save memory */ + /*ptr init*/ FOR( i = 0; i < Nsv; i++ ) { t[i] = xriq[8 * Nsv + i]; @@ -325,11 +316,12 @@ void AVQ_encmux_fx( move16(); move16(); move16(); + move16(); if ( EQ_16( avq_bit_sFlag, 2 ) ) { j = add( i, 1 ); } - WHILE( LT_16( i, Nsvm1 ) ) + WHILE( i < Nsvm1 ) { svOrder[i] = j; move16(); @@ -414,7 +406,7 @@ void AVQ_encmux_fx( } /* for */ /* Bit Saving Solution */ test(); - IF( avq_bit_sFlag > 0 && bits > 8 ) + IF( avq_bit_sFlag > 0 && GT_16( bits, 8 ) ) { // PMT("code not validated yet") bitsMod = s_and( bits, 4 /*bits%5*/ ); @@ -453,7 +445,7 @@ void AVQ_encmux_fx( bitsMod = 0; move16(); } - ELSE IF( nq_est > 4 && ( ( bitsMod == 0 && nullVec > 3 && nullVec < 6 ) || ( bitsMod == 4 && nullVec == 5 ) ) && nq[svOrder[Nsvm2]] == 0 ) /* wasted bits 4, 5 for nq 6,7..*/ + ELSE IF( nq_est > 4 && ( ( bitsMod == 0 && GT_16( nullVec, 3 ) && GT_16( nullVec, 6 ) ) || ( EQ_16( bitsMod, 4 ) && EQ_16( nullVec, 5 ) ) ) && nq[svOrder[Nsvm2]] == 0 ) /* wasted bits 4, 5 for nq 6,7..*/ { overflow = 0; move16(); @@ -527,7 +519,7 @@ void AVQ_encmux_fx( bit_tmp = add( unusedbitsFlag, unused_bits_idx ); /*nq_est = (int16_t)ceil(0.2f * (bits - 5 * (unusedbitsFlag + unused_bits_idx)));*/ nq_est = mult( 6554, sub( bits, add( shl( bit_tmp, 2 ), bit_tmp ) ) ); - assert( (int16_t) ceil( 0.2f * ( bits - 5 * ( unusedbitsFlag + unused_bits_idx ) ) ) == nq_est ); + assert( (Word16) ceil( 0.2f * ( bits - 5 * ( unusedbitsFlag + unused_bits_idx ) ) ) == nq_est ); if ( EQ_16( nq_est, 1 ) ) { @@ -627,8 +619,8 @@ void AVQ_encmux_ivas_fx( /* sort subvectors by estimated bit allocations in decreasing order */ t = kv; - move16(); /* reuse vector to save memory */ - move16(); /*ptr init*/ + /* reuse vector to save memory */ + /*ptr init*/ FOR( i = 0; i < Nsv; i++ ) { t[i] = xriq[8 * Nsv + i]; @@ -723,6 +715,7 @@ void AVQ_encmux_ivas_fx( move16(); move16(); move16(); + move16(); if ( EQ_16( avq_bit_sFlag, 2 ) ) { j = add( i, 1 ); @@ -814,17 +807,18 @@ void AVQ_encmux_ivas_fx( bits = sub( bits, 1 ); } - wrte_cv_ivas( hBstr, nq[k], i_ind, kv_ind, I[k], &kv[k * 8], &bits ); + wrte_cv_ivas_fx( hBstr, nq[k], i_ind, kv_ind, I[k], &kv[k * 8], &bits ); } } /* for */ /* Bit Saving Solution */ test(); - IF( avq_bit_sFlag > 0 && bits > 8 ) + IF( avq_bit_sFlag > 0 && GT_16( bits, 8 ) ) { // PMT("code not validated yet") // bitsMod = bits%5; bitsMod = bits; - WHILE( GE_16( bitsMod, 5 ) ) + move16(); + WHILE( bitsMod >= 5 ) { bitsMod = sub( bitsMod, 5 ); } @@ -837,13 +831,13 @@ void AVQ_encmux_ivas_fx( move16(); FOR( j = i; j < Nsv - 1; j++ ) { - if ( nq[svOrder[j]] == 0 ) + IF( nq[svOrder[j]] == 0 ) { nullVec = add( nullVec, 1 ); } } /*nq_est = bits / 5;*/ - nq_est = mult( bits, 6554 ); + nq_est = mult( bits, 6554 /*1/5 in Q15*/ ); assert( nq_est == bits / 5 ); test(); @@ -856,7 +850,7 @@ void AVQ_encmux_ivas_fx( test(); test(); test(); - test(); + IF( ( bitsMod > 0 || ( EQ_16( nullVec, 4 ) && EQ_16( nq_est, 5 ) ) ) && NE_16( bitsMod, 4 ) && GE_16( add( bits, nullVec ), add( add( shl( nq_est, 2 ), nq_est ), 4 ) ) /*5 * nq_est + 4*/ && nq[svOrder[Nsvm2]] == 0 ) /* detect need for dummy bits */ { dummy_bits = sub( 5, bitsMod ); @@ -864,12 +858,12 @@ void AVQ_encmux_ivas_fx( bitsMod = 0; move16(); } - ELSE IF( nq_est > 4 && ( ( bitsMod == 0 && nullVec > 3 && nullVec < 6 ) || ( bitsMod == 4 && nullVec == 5 ) ) && nq[svOrder[Nsvm2]] == 0 ) /* wasted bits 4, 5 for nq 6,7..*/ + ELSE IF( GT_16( nq_est, 4 ) && ( ( bitsMod == 0 && GT_16( nullVec, 3 ) && LT_16( nullVec, 6 ) ) || ( EQ_16( bitsMod, 4 ) && EQ_16( nullVec, 5 ) ) ) && nq[svOrder[Nsvm2]] == 0 ) /* wasted bits 4, 5 for nq 6,7..*/ { overflow = 0; move16(); tmp = add( bitsMod, nullVec ); - WHILE( GE_16( tmp, 5 ) ) + WHILE( tmp >= 5 ) { tmp = sub( tmp, 5 ); } @@ -896,18 +890,18 @@ void AVQ_encmux_ivas_fx( } bits = add( bits, overflow ); /*add fake bit */ unused_bits = sub( bits, add( shl( nq[i], 2 ), nq[i] ) ); - if ( nq[i] == 0 ) /*no bit savings*/ + IF( nq[i] == 0 ) /*no bit savings*/ { unused_bits = sub( unused_bits, 1 ); /*Stop Bit*/ } /*unused_bits_idx = (int16_t)unused_bits / 5;*/ IF( unused_bits >= 0 ) { - unused_bits_idx = mult( unused_bits, 6554 ); + unused_bits_idx = mult( unused_bits, 6554 /*1/5 in Q15*/ ); } ELSE { - unused_bits_idx = negate( mult( negate( unused_bits ), 6554 ) ); + unused_bits_idx = negate( mult( negate( unused_bits ), 6554 /*1/5 in Q15*/ ) ); } assert( unused_bits_idx == unused_bits / 5 ); unusedbitsFlag = 0; @@ -951,8 +945,8 @@ void AVQ_encmux_ivas_fx( /*Compute AVQ code book number from unused Bits */ bit_tmp = add( unusedbitsFlag, unused_bits_idx ); /*nq_est = (int16_t)ceil(0.2f * (bits - 5 * (unusedbitsFlag + unused_bits_idx)));*/ - nq_est = mult( 6554, sub( bits, add( shl( bit_tmp, 2 ), bit_tmp ) ) ); - assert( (int16_t) ceil( 0.2f * ( bits - 5 * ( unusedbitsFlag + unused_bits_idx ) ) ) == nq_est ); + nq_est = mult( 6554 /*.2 in Q15*/, sub( bits, add( shl( bit_tmp, 2 ), bit_tmp ) ) ); + assert( (Word16) ceil( 0.2f * ( bits - 5 * ( unusedbitsFlag + unused_bits_idx ) ) ) == nq_est ); if ( EQ_16( nq_est, 1 ) ) { @@ -963,7 +957,7 @@ void AVQ_encmux_ivas_fx( bits = sub( bits, j ); - if ( nq_est != 0 ) + IF( nq_est != 0 ) { bits = sub( bits, 1 ); } @@ -971,11 +965,11 @@ void AVQ_encmux_ivas_fx( move16(); /* write codebook indices (rank I and event. Voronoi index kv) */ - wrte_cv_ivas( hBstr, nq[i], i_ind, kv_ind, I[i], &kv[i * 8], &bits ); + wrte_cv_ivas_fx( hBstr, nq[i], i_ind, kv_ind, I[i], &kv[i * 8], &bits ); bits = sub( bits, dummy_bits ); - if ( NE_16( bitsMod, 4 ) ) + IF( NE_16( bitsMod, 4 ) ) { bits = add( bits, bitsMod ); } @@ -1091,8 +1085,8 @@ static void wrte_cv( Word16 *nbits /* i/o: bits */ ) { - int16_t pos, j; - int16_t bits, nq4; + Word16 pos, j; + Word16 bits, nq4; bits = *nbits; move16(); @@ -1141,7 +1135,7 @@ static void wrte_cv( return; } -static void wrte_cv_ivas( +static void wrte_cv_ivas_fx( BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ const Word16 nq, /* i : AVQ nq index */ const Word16 i_ind, /* i : Base Bitstream index */ @@ -1151,8 +1145,8 @@ static void wrte_cv_ivas( Word16 *nbits /* i/o: bits */ ) { - int16_t pos, j; - int16_t bits, nq4; + Word16 pos, j; + Word16 bits, nq4; bits = *nbits; move16(); diff --git a/lib_enc/bass_psfilter_enc.c b/lib_enc/bass_psfilter_enc.c deleted file mode 100644 index 8e752f0ac516550ba25f4c9dcce588dfd9e16b42..0000000000000000000000000000000000000000 --- a/lib_enc/bass_psfilter_enc.c +++ /dev/null @@ -1,42 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include -#include "prot.h" -#include "rom_com.h" -#include "wmc_auto.h" diff --git a/lib_enc/bass_psfilter_enc_fx.c b/lib_enc/bass_psfilter_enc_fx.c index df52213c2bdc3d56ff7cbb9302ceaae8b3d78479..a1d672fe0059f3a6971fa0fb7f6bb6800745d88a 100644 --- a/lib_enc/bass_psfilter_enc_fx.c +++ b/lib_enc/bass_psfilter_enc_fx.c @@ -38,6 +38,7 @@ Word16 bass_pf_enc_fx( Word32 ener2; #ifdef BASOP_NOGLOB_DECLARE_LOCAL Flag Overflow = 0; + move32(); #endif @@ -69,10 +70,12 @@ Word16 bass_pf_enc_fx( move16(); s3 = s4 = 0; /* initialization of s3 and s4 to suppress compiler warnings; s3 and s4 get initialized for i_subfr == 0 */ - + move16(); + move16(); nrg1 = nrg2 = 0; /* initialization fo nrg1 and nrg2 to suppress compiler warnings; nrg1 and nrg1 get initialized for i_subfr == 0 */ - + move32(); + move32(); FOR( i_subfr = 0; i_subfr < l_frame; i_subfr += l_subfr ) { T = T_sf[sf]; @@ -126,11 +129,7 @@ Word16 bass_pf_enc_fx( /* gain = tmp/nrg; */ gain = BASOP_Util_Divide3232_Scale( tmp, nrg, &tmp16 ); BASOP_SATURATE_WARNING_OFF_EVS; -#ifdef BASOP_NOGLOB gain = shl_o( gain, tmp16, &Overflow ); /* Q15 */ -#else /* BASOP_NOGLOB */ - gain = shl( gain, tmp16 ); /* Q15 */ -#endif /* BASOP_NOGLOB */ BASOP_SATURATE_WARNING_ON_EVS; if ( gain < 0 ) @@ -154,26 +153,14 @@ Word16 bass_pf_enc_fx( FOR( i = 0; i < lg; i++ ) { tmp32 = L_msu0( 0, gain, syn[i + i_subfr - T] ); -#ifdef BASOP_NOGLOB tmp32 = L_msu0_o( tmp32, gain, syn[i + i_subfr + T], &Overflow ); tmp16 = mac_ro( tmp32, gain, syn[i + i_subfr], &Overflow ); /* Q0 */ -#else - tmp32 = L_msu0( tmp32, gain, syn[i + i_subfr + T] ); - tmp16 = mac_r( tmp32, gain, syn[i + i_subfr] ); /* Q0 */ -#endif lp_error = Mpy_32_16_1( lp_error, 29491 /*0.9f Q15*/ ); -#ifdef BASOP_NOGLOB lp_error = L_mac_o( lp_error, tmp16, 0x1000, &Overflow ); /* Q13 */ tmp16 = round_fx_o( L_shl_o( lp_error, s1, &Overflow ), &Overflow ); /* Q0+s1-3 */ ener2 = L_mac0_o( ener2, tmp16, tmp16, &Overflow ); /* Q0+(s1-3)*2 */ -#else - lp_error = L_mac( lp_error, tmp16, 0x1000 ); /* Q13 */ - - tmp16 = round_fx( L_shl( lp_error, s1 ) ); /* Q0+s1-3 */ - ener2 = L_mac0( ener2, tmp16, tmp16 ); /* Q0+(s1-3)*2 */ -#endif } } @@ -182,25 +169,13 @@ Word16 bass_pf_enc_fx( FOR( i = lg; i < l_subfr; i++ ) { tmp32 = L_mult0( gain, syn[i + i_subfr] ); -#ifdef BASOP_NOGLOB tmp32 = L_msu0_o( tmp32, gain, syn[i + i_subfr - T], &Overflow ); /* Q0 */ tmp16 = round_fx_o( tmp32, &Overflow ); -#else - tmp32 = L_msu0( tmp32, gain, syn[i + i_subfr - T] ); /* Q0 */ - tmp16 = round_fx( tmp32 ); -#endif lp_error = Mpy_32_16_1( lp_error, 29491 /*0.9f Q15*/ ); -#ifdef BASOP_NOGLOB lp_error = L_mac_o( lp_error, tmp16, 0x1000, &Overflow ); /* Q13 */ tmp16 = round_fx_o( L_shl_o( lp_error, s1, &Overflow ), &Overflow ); /* Q0+s1-3 */ ener2 = L_mac0_o( ener2, tmp16, tmp16, &Overflow ); /* Q0+(s1-3)*2 */ -#else - lp_error = L_mac( lp_error, tmp16, 0x1000 ); /* Q13 */ - - tmp16 = round_fx( L_shl( lp_error, s1 ) ); /* Q0+s1-3 */ - ener2 = L_mac0( ener2, tmp16, tmp16 ); /* Q0+(s1-3)*2 */ -#endif } } @@ -218,7 +193,7 @@ Word16 bass_pf_enc_fx( } mem_bpf->lp_error_ener = L_add( Mpy_32_16_1( L_sub( mem_bpf->lp_error_ener, ener2 ), 32440 /*0.99f Q15*/ ), ener2 ); /* 15Q16 */ - + move32(); st = add( st, 6 ); ener2 = L_sub( mem_bpf->lp_error_ener, L_deposit_h( sub( 31, st ) ) ); IF( ener2 >= 0 ) @@ -235,11 +210,7 @@ Word16 bass_pf_enc_fx( tmp32 = L_deposit_l( 1 ); tmp16 = BASOP_Util_Divide3232_Scale( tmp, tmp32, &st ); BASOP_SATURATE_WARNING_OFF_EVS; -#ifdef BASOP_NOGLOB tmp16 = shl_o( tmp16, sub( st, 2 ), &Overflow ); /* Q15 */ -#else /* BASOP_NOGLOB */ - tmp16 = shl( tmp16, sub( st, 2 ) ); /* Q15 */ -#endif /* BASOP_NOGLOB */ if ( GT_16( tmp16, 16384 /*0.5f Q15*/ ) ) { @@ -265,13 +236,8 @@ Word16 bass_pf_enc_fx( tmp32 = L_mac( tmp32, tmp16, syn[i + i_subfr] ); noise_in[i] = round_fx( L_shl( tmp32, s2 ) ); /* Q0+s2 */ -#ifdef BASOP_NOGLOB error_in[i] = sub_o( orig[i + i_subfr], syn[i + i_subfr], &Overflow ); /*Q0*/ move16(); -#else - error_in[i] = sub( orig[i + i_subfr], syn[i + i_subfr] ); /*Q0*/ - move16(); -#endif } } @@ -282,14 +248,10 @@ Word16 bass_pf_enc_fx( tmp32 = L_mult0( tmp16, syn[i + i_subfr] ); tmp32 = L_msu0( tmp32, tmp16, syn[i + i_subfr - T] ); noise_in[i] = round_fx( L_shl( tmp32, s2 ) ); /* Q0+s2 */ + move16(); -#ifdef BASOP_NOGLOB error_in[i] = sub_o( orig[i + i_subfr], syn[i + i_subfr], &Overflow ); /*Q0*/ move16(); -#else - error_in[i] = sub( orig[i + i_subfr], syn[i + i_subfr] ); /*Q0*/ - move16(); -#endif } } } @@ -298,6 +260,7 @@ Word16 bass_pf_enc_fx( set16_fx( noise_in, 0, l_subfr ); set16_fx( error_in, 0, l_subfr ); s2 = s2_old; + move16(); } tmp16 = shl( l_filt, 1 ); @@ -306,7 +269,11 @@ Word16 bass_pf_enc_fx( st = sub( s2, s2_old ); FOR( i = 0; i < tmp16; i++ ) { +#ifdef FIX_ISSUE_1187 + noise_buf[i] = shl_sat( mem_bpf->noise_buf[i], st ); +#else noise_buf[i] = shl( mem_bpf->noise_buf[i], st ); +#endif move16(); } Copy( noise_buf + l_subfr, mem_bpf->noise_buf, tmp16 ); @@ -402,13 +369,8 @@ Word16 bass_pf_enc_fx( /* *gain_factor_param = (int)(-2.f*(cross_n_d/nrg_n)+0.5f); */ tmp16 = BASOP_Util_Divide3232_Scale( cross_n_d, nrg_n, &st ); /* Q15-st-s3+s4 */ BASOP_SATURATE_WARNING_OFF_EVS; -#ifdef BASOP_NOGLOB tmp16 = shl_sat( negate( tmp16 ), add( sub( add( st, s3 ), s4 ), 1 - 14 ) ); /* Q1 */ tmp16 = shr( add_sat( tmp16, 1 ), 1 ); /* Q0 */ -#else - tmp16 = shl( negate( tmp16 ), add( sub( add( st, s3 ), s4 ), 1 - 14 ) ); /* Q1 */ - tmp16 = shr( add( tmp16, 1 ), 1 ); /* Q0 */ -#endif BASOP_SATURATE_WARNING_ON_EVS; *gain_factor_param = tmp16; diff --git a/lib_enc/bw_detect_fx.c b/lib_enc/bw_detect_fx.c index f572f4be37c41448fc990d70d53adac98cefa0e8..2e9b2c5db1fa63e6e80f58b43617227bab6bd2cb 100644 --- a/lib_enc/bw_detect_fx.c +++ b/lib_enc/bw_detect_fx.c @@ -40,12 +40,12 @@ void bw_detect_fx( Encoder_State *st, /* i/o: Encoder State */ - const Word16 signal_in[], /* i : input signal */ - Word16 *spectrum, /* i : MDCT spectrum */ + const Word16 signal_in[], /* i : input signal */ + Word16 *spectrum, /* i : MDCT spectrum */ const Word32 *enerBuffer, /* i : CLDFB Energy Q31 */ const Word16 *cldfbBuf_Ener_Exp, /* i : CLDFB Energy Exponent */ const IVAS_FORMAT ivas_format, /* i : IVAS format */ - const int16_t mct_on /* i : flag MCT mode */ + const Word16 mct_on /* i : flag MCT mode */ ) { Word16 Q_dct; @@ -63,17 +63,13 @@ void bw_detect_fx( Word32 cldfb_bin[9]; Word16 cldfb_bin_Exp[9]; Word16 cldfb_bin_width = 4; + move16(); const Word32 *pt32; Word32 max_NB32, max_WB32, max_SWB32, max_FB32, mean_NB32, mean_WB32, mean_SWB32, mean_FB32; /* Q11*/ /* we need Word32 for the new cldfb energy vectors */ Word16 bwd_count_wider_bw; -#ifdef IVAS_CODE_DFT - Word16 l_frame; -#endif -#ifndef IVAS_CODE_BWD - (void) spectrum; -#endif #ifdef BASOP_NOGLOB_DECLARE_LOCAL Flag Overflow = 0; + move32(); #endif bwd_count_wider_bw = BWD_COUNT_WIDER_BW; @@ -120,21 +116,18 @@ void bw_detect_fx( move32(); /* result: Q31 */ } - cldfb_bin[0] = Mpy_32_16_1( cldfb_bin[0], ScalFac ); - move32(); /* Q31 */ + cldfb_bin[0] = Mpy_32_16_1( cldfb_bin[0], ScalFac ); // Q(31-cldfb_bin_Exp) + move32(); /* Q31 */ cldfb_bin_Exp[0] = add( cldfb_bin_Exp[0], CLDFBscalingFactor_EXP ); move16(); if ( cldfb_bin[i] == 0 ) { cldfb_bin[i] = L_deposit_l( 1 ); + move32(); } - L_tmp = BASOP_Util_Log2( cldfb_bin[0] ); /*(log2(660423549*2^(-31))/64)*2^31*/ -#ifdef BASOP_NOGLOB + L_tmp = BASOP_Util_Log2( cldfb_bin[0] ); /*(log2(660423549*2^(-31))/64)*2^31*/ L_tmp = L_add_o( L_tmp, L_shl( L_deposit_l( cldfb_bin_Exp[0] ), 31 - LD_DATA_SCALE ), &Overflow ); /* Q25 */ -#else /* BASOP_NOGLOB */ - L_tmp = L_add( L_tmp, L_shl( L_deposit_l( cldfb_bin_Exp[0] ), 31 - LD_DATA_SCALE ) ); /* Q25 */ -#endif /* BASOP_NOGLOB */ cldfb_bin[0] = Mpy_32_16_1( L_tmp, 9864 /*1.0f/3.3219280948873623478703194294894f Q15*/ ); move32(); /* 1/log2(10) */ /* Q25 */ @@ -153,7 +146,7 @@ void bw_detect_fx( } FOR( i = 1; i <= 2; i++ ) { - cldfb_bin[i] = Mpy_32_16_1( cldfb_bin[i], ScalFac ); + cldfb_bin[i] = Mpy_32_16_1( cldfb_bin[i], ScalFac ); // Q(31-(cldfv_bin_Exp+CLDFBscalingFactor_EXP)) move32(); cldfb_bin_Exp[i] = add( cldfb_bin_Exp[i], CLDFBscalingFactor_EXP ); move16(); @@ -161,6 +154,7 @@ void bw_detect_fx( if ( cldfb_bin[i] == 0 ) { cldfb_bin[i] = L_deposit_l( 1 ); + move32(); } L_tmp = BASOP_Util_Log2( cldfb_bin[i] ); /*(log2(660423549*2^(-31))/64)*2^31*/ L_tmp = L_add( L_tmp, L_shl( L_deposit_l( cldfb_bin_Exp[i] ), 31 - LD_DATA_SCALE ) ); /* Q25 */ @@ -191,7 +185,7 @@ void bw_detect_fx( } FOR( i = 3; i <= 6; i++ ) { - cldfb_bin[i] = Mpy_32_16_1( cldfb_bin[i], ScalFac ); + cldfb_bin[i] = Mpy_32_16_1( cldfb_bin[i], ScalFac ); // Q(31-(cldfv_bin_Exp+CLDFBscalingFactor_EXP)) move32(); cldfb_bin_Exp[i] = add( cldfb_bin_Exp[i], CLDFBscalingFactor_EXP ); move16(); @@ -199,6 +193,7 @@ void bw_detect_fx( if ( cldfb_bin[i] == 0 ) { cldfb_bin[i] = L_deposit_l( 1 ); + move32(); } L_tmp = BASOP_Util_Log2( cldfb_bin[i] ); /*(log2(660423549*2^(-31))/64)*2^31*/ L_tmp = L_add( L_tmp, L_shl( L_deposit_l( cldfb_bin_Exp[i] ), 31 - LD_DATA_SCALE ) ); /* Q25 */ @@ -231,6 +226,7 @@ void bw_detect_fx( if ( cldfb_bin[i] == 0 ) { cldfb_bin[i] = L_deposit_l( 1 ); + move32(); } L_tmp = BASOP_Util_Log2( cldfb_bin[i] ); /*(log2(660423549*2^(-31))/64)*2^31*/ L_tmp = L_add( L_tmp, L_shl( L_deposit_l( cldfb_bin_Exp[i] ), 31 - LD_DATA_SCALE ) ); /* Q25 */ @@ -300,18 +296,15 @@ void bw_detect_fx( FOR( i = 0; i < BWD_TOTAL_WIDTH; i++ ) { -#ifdef BASOP_NOGLOB spect[i] = round_fx_o( L_shr_o( spect32[i], Q_dct, &Overflow ), &Overflow ); -#else /* BASOP_NOGLOB */ - spect[i] = round_fx( L_shr( spect32[i], Q_dct ) ); -#endif + move16(); } Q_dct = -2; move16(); } ELSE { - Word16 l_frame = (int16_t) ( st->input_Fs / FRAMES_PER_SEC ); + Word16 l_frame = extract_l( st->input_Fs / FRAMES_PER_SEC ); IF( EQ_16( st->core, TCX_10_CORE ) ) { l_frame = shr( l_frame, 1 ); @@ -335,11 +328,7 @@ void bw_detect_fx( pt1 = &spect[i_mult2( i, bin_width )]; FOR( j = 0; j < bin_width; j++ ) { -#ifdef BASOP_NOGLOB sum32 = L_mac0_o( sum32, *pt1, *pt1, &Overflow ); -#else - sum32 = L_mac0( sum32, *pt1, *pt1 ); -#endif pt1++; } @@ -359,6 +348,7 @@ void bw_detect_fx( e_tmp = sub( sub( 30, e_tmp ), Q_dct ); L_tmp = Mpy_32_16( e_tmp, f_tmp, 9864 ); /* Q16 */ spect_bin[i] = round_fx( L_shl( L_tmp, 11 ) ); /* Q11 */ + move16(); } } } @@ -527,23 +517,25 @@ void bw_detect_fx( /*if( localVAD || st->lp_noise > 30 )*/ test(); - IF( st->localVAD || GT_16( st->lp_noise_fx, 7680 ) ) + IF( st->localVAD || GT_16( st->lp_noise_fx, 7680 /*30 in Q8*/ ) ) { /*st->lt_mean_NB_fx = ALPHA_BWD * st->lt_mean_NB_fx + (1-ALPHA_BWD) * mean_NB;*/ L_tmp = L_mult( ALPHA_BWD_FX, st->lt_mean_NB_fx ); /* Q15 * Q11 -> Q27 */ L_tmp = L_mac( L_tmp, 32768 - ALPHA_BWD_FX, mean_NB ); /* Q15 * Q11) -> L_mac(Q27, Q27) -> Q27*/ st->lt_mean_NB_fx = round_fx( L_tmp ); /* Q11 (27-16) */ + move16(); /*st->lt_mean_WB_fx = ALPHA_BWD * st->lt_mean_WB_fx + (1-ALPHA_BWD) * mean_WB;*/ L_tmp = L_mult( ALPHA_BWD_FX, st->lt_mean_WB_fx ); L_tmp = L_mac( L_tmp, 32768 - ALPHA_BWD_FX, mean_WB ); st->lt_mean_WB_fx = round_fx( L_tmp ); + move16(); /*st->lt_mean_SWB_fx = ALPHA_BWD * st->lt_mean_SWB_fx + (1-ALPHA_BWD) * mean_SWB;*/ L_tmp = L_mult( ALPHA_BWD_FX, st->lt_mean_SWB_fx ); L_tmp = L_mac( L_tmp, 32768 - ALPHA_BWD_FX, mean_SWB ); st->lt_mean_SWB_fx = round_fx( L_tmp ); - + move16(); IF( enerBuffer != NULL ) { @@ -565,6 +557,7 @@ void bw_detect_fx( IF( GT_32( L_tmp, L_tmp1 ) ) /* Q24 */ { st->count_WB = add( st->count_WB, 1 ); + move16(); } } ELSE @@ -576,6 +569,7 @@ void bw_detect_fx( IF( L_tmp < 0 ) { st->count_WB = sub( st->count_WB, 1 ); + move16(); } } @@ -603,6 +597,7 @@ void bw_detect_fx( IF( L_tmp1 > 0 ) { st->count_SWB = add( st->count_SWB, 1 ); + move16(); } } ELSE @@ -614,6 +609,7 @@ void bw_detect_fx( IF( L_tmp1 < 0 ) { st->count_SWB = sub( st->count_SWB, 1 ); + move16(); } } /*if( max_FB > BWD_LT_THRESH_FX * st->lt_mean_SWB_fx && 0.83f * max_SWB > BWD_LT_THRESH_FX * st->lt_mean_WB_fx && max_WB > BWD_LT_THRESH_FX * st->lt_mean_NB_fx )*/ @@ -645,6 +641,7 @@ void bw_detect_fx( IF( L_tmp1 > 0 ) { st->count_FB = add( st->count_FB, 1 ); + move16(); } } ELSE @@ -656,6 +653,7 @@ void bw_detect_fx( IF( L_tmp1 < 0 ) { st->count_FB = sub( st->count_FB, 1 ); + move16(); } } } @@ -666,9 +664,10 @@ void bw_detect_fx( { /*if( 2 * max_WB > max_NB )*/ L_tmp = L_mult( 8192, max_WB ); /* 2.0 in Q12 x Q11 -> Q24*/ - if ( L_msu( L_tmp, max_NB, 4096 ) > 0 ) + IF( L_msu( L_tmp, max_NB, 4096 ) > 0 ) { st->count_WB = add( st->count_WB, 1 ); + move16(); } } ELSE @@ -678,22 +677,23 @@ void bw_detect_fx( L_tmp = L_msu( L_tmp, mean_NB, 4096 ); test(); test(); - if ( L_tmp < 0 && !( EQ_16( mean_WB, -1 ) && EQ_16( mean_NB, -1 ) ) ) + IF( L_tmp < 0 && !( EQ_16( mean_WB, -1 ) && EQ_16( mean_NB, -1 ) ) ) { st->count_WB = sub( st->count_WB, 1 ); + move16(); } } - test(); /*if( max_SWB > BWD_LT_THRESH * st->lt_mean_WB_fx && max_WB > BWD_LT_THRESH * st->lt_mean_NB_fx )*/ test(); IF( L_msu( L_deposit_h( max_SWB ), BWD_LT_THRESH_FX, st->lt_mean_WB_fx ) > 0 && L_msu( L_deposit_h( max_WB ), BWD_LT_THRESH_FX, st->lt_mean_NB_fx ) > 0 ) { /*if( 2 * max_SWB > max_WB )*/ L_tmp = L_mult( 8192, max_SWB ); /* 2.0 in Q12 x Q11 -> Q24*/ - if ( L_msu( L_tmp, max_WB, 4096 ) > 0 ) + IF( L_msu( L_tmp, max_WB, 4096 ) > 0 ) { st->count_SWB = add( st->count_SWB, 1 ); + move16(); } } ELSE @@ -703,9 +703,10 @@ void bw_detect_fx( L_tmp = L_msu( L_tmp, mean_WB, 4096 ); test(); test(); - if ( L_tmp < 0 && !( EQ_16( mean_SWB, -1 ) && EQ_16( mean_WB, -1 ) ) ) + IF( L_tmp < 0 && !( EQ_16( mean_SWB, -1 ) && EQ_16( mean_WB, -1 ) ) ) { st->count_SWB = sub( st->count_SWB, 1 ); + move16(); } } @@ -716,9 +717,10 @@ void bw_detect_fx( { /*if( 2 * max_FB > max_SWB )*/ L_tmp = L_mult( 8192, max_FB ); /* 2.0 in Q12 x Q11 -> Q24*/ - if ( L_msu( L_tmp, max_SWB, 4096 ) > 0 ) + IF( L_msu( L_tmp, max_SWB, 4096 ) > 0 ) { st->count_FB = add( st->count_FB, 1 ); + move16(); } } ELSE @@ -727,9 +729,10 @@ void bw_detect_fx( L_tmp = L_mult( 12288, mean_FB ); /* 3.0 in Q12 x Q11 -> Q24*/ test(); test(); - if ( L_msu( L_tmp, mean_SWB, 4096 ) < 0 && !( EQ_16( mean_FB, -1 ) && EQ_16( mean_SWB, -1 ) ) ) + IF( L_msu( L_tmp, mean_SWB, 4096 ) < 0 && !( EQ_16( mean_FB, -1 ) && EQ_16( mean_SWB, -1 ) ) ) { st->count_FB = sub( st->count_FB, 1 ); + move16(); } } } @@ -887,12 +890,12 @@ void bw_detect_fx( /* verify that maximum encoded bandwidth (specified on the command line) is not exceeded */ - IF( GT_16( st->input_bwidth, st->max_bwidth ) ) + if ( GT_16( st->input_bwidth, st->max_bwidth ) ) { st->input_bwidth = st->max_bwidth; move16(); } - IF( EQ_16( st->element_mode, EVS_MONO ) ) + IF( st->element_mode == EVS_MONO ) { set_bw_fx( -1, -1, st, st->codec_mode ); } @@ -1022,7 +1025,7 @@ void set_bw_fx( BREAK; } } - if ( EQ_16( n, FRAME_SIZE_NB ) ) + IF( EQ_16( n, FRAME_SIZE_NB ) ) { assert( !"Bitrate not supported: not part of EVS" ); } @@ -1037,7 +1040,7 @@ void set_bw_fx( move16(); } } -//#ifdef IVAS_CODE_BWD + /*-------------------------------------------------------------------* * set_bw_stereo() @@ -1084,7 +1087,8 @@ void set_bw_stereo_fx( return; } -//#endif + + /*-------------------------------------------------------------------* * set_bw_mct() * diff --git a/lib_enc/cng_enc.c b/lib_enc/cng_enc.c deleted file mode 100644 index dde1a574ad1dba8585f581d8e9750bd9cf162a0b..0000000000000000000000000000000000000000 --- a/lib_enc/cng_enc.c +++ /dev/null @@ -1,448 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include -#include "cnst.h" -#include "rom_enc.h" -#include "rom_com.h" -#include "prot.h" -#include "wmc_auto.h" - -#include "prot_fx_enc.h" -#include "prot_fx.h" -#include "ivas_rom_com_fx.h" - -/*---------------------------------------------------------------------* - * Local constants - *---------------------------------------------------------------------*/ - -#define MAX_DELTA_CNG 1 -#define ENER_MID_DEAD_ZONE 0.01 /* dead-zone width around mid points between quantization levels */ - -/*---------------------------------------------------------------------* - * Local function prototypes - *---------------------------------------------------------------------*/ - -static Word16 shb_DTX_ivas_fx( Encoder_State *st, const Word16 *shb_speech_fx, const Word16 *syn_12k8_16k_fx ); - -static void shb_CNG_encod_ivas_fx( Encoder_State *st, const Word16 update ); - - -void swb_CNG_enc_ivas_fx( - Encoder_State *st, /* i/o: State structure */ - const Word16 *shb_speech_fx, /* i : SHB target signal (6-14kHz) at 16kHz Q0 */ - const Word16 *syn_12k8_16k_fx /* i : ACELP core synthesis at 12.8kHz or 16kHz Q0 */ -) -{ - Word16 shb_SID_updt; - - test(); - IF( EQ_32( st->core_brate, SID_2k40 ) || st->core_brate == FRAME_NO_DATA ) - { - IF( st->cng_type == LP_CNG ) - { - test(); - IF( GE_32( st->input_Fs, L_FRAME32k * FRAMES_PER_SEC ) ) - { - /* decide if SHB SID encoding or not */ - shb_SID_updt = shb_DTX_ivas_fx( st, shb_speech_fx, syn_12k8_16k_fx ); - - /* SHB CNG encoding */ - shb_CNG_encod_ivas_fx( st, shb_SID_updt ); - } - ELSE IF( EQ_16( st->element_mode, IVAS_CPE_DFT ) && EQ_32( st->core_brate, SID_2k40 ) ) - { - /* LF-boost not used in DFT-stereo, instead the bandwidth is transmitted */ - delete_indice( st->hBstr, IND_CNG_ENV1 ); - push_indice( st->hBstr, IND_BWIDTH, st->bwidth, 2 ); - push_indice( st->hBstr, IND_UNUSED, 0, 4 ); - push_indice( st->hBstr, IND_SID_BW, 1, 1 ); - } - } - st->hTdCngEnc->last_vad = 0; - move16(); - } - ELSE - { - st->hTdCngEnc->last_vad = 1; - move16(); - } - - return; -} - - -/*---------------------------------------------------------------------* - * shb_CNG_encod() - * - * SID parameters encoding for SHB signal - *---------------------------------------------------------------------*/ - -static void shb_CNG_encod_ivas_fx( - Encoder_State *st, /* i/o: State structure */ - const Word16 update /* i : SID update flag */ -) -{ - Word16 idx_ener = 0; - move16(); - BSTR_ENC_HANDLE hBstr = st->hBstr; - - Word16 ener_mid_dec_thr_fx; - - IF( EQ_16( update, 1 ) ) - { - IF( st->element_mode == EVS_MONO ) - { - /* 6.0 in Q8 -> 1510 */ - /* 0.9 in Q15 29491 */ - /* ( 1 / log10(2.0) ) * 0.1 in Q15 ->10886 */ - idx_ener = shr( mult( add( mult( st->hTdCngEnc->mov_shb_cng_ener_fx, 10886 ), 1510 ), 29491 ), 8 ); /* Q0 */ - } - ELSE - { - /*idx_ener = (int16_t)(0.7f * (0.1f * st->hTdCngEnc->mov_shb_cng_ener / (float)log10(2.0f) + 6.0f) + 0.5f);*/ - // PMT("shb_CNG_encod_fx quantization in missing") - /* 6.0 in Q8 -> 1510 */ - /* 0.7 in Q15 22938 */ - /* ( 1 / log10(2.0) ) * 0.1 in Q15 -> 10886 */ - idx_ener = shr( mult( add( mult( st->hTdCngEnc->mov_shb_cng_ener_fx, 10886 ), 1510 ), 22938 ), 8 ); /* Q0 */ - } - - - if ( LT_16( st->bwidth, SWB ) ) - { - idx_ener = 0; - move16(); - } - - IF( GT_16( idx_ener, 15 ) ) - { - idx_ener = 15; - move16(); - } - ELSE IF( idx_ener < 0 ) - { - idx_ener = 0; - move16(); - } - - /* prevent toggling of idx_ener by adding small dead-zone interval around decision thresholds */ - IF( st->element_mode != EVS_MONO ) - { - IF( EQ_16( abs_s( sub( idx_ener, st->hTdCngEnc->last_idx_ener ) ), 1 ) ) - { - - Word16 tmp, tmp1, tmp2, scale, exp1, exp2, ener_mid_dec_thr_e; - tmp = BASOP_Util_Divide1616_Scale( st->hTdCngEnc->last_idx_ener, 22938, &scale ); // 0.7 in Q15 ->exp 0 - scale = scale + ( 15 - 0 ); - tmp = sub( tmp, shl( 6, sub( Q15, scale ) ) ); - tmp1 = BASOP_Util_Divide1616_Scale( tmp, 3277, &exp1 ); - exp1 = exp1 + ( scale - 0 ); - - ener_mid_dec_thr_fx = shr( mult( tmp1, 9864 ), 1 ); // exp = exp - - tmp = BASOP_Util_Divide1616_Scale( idx_ener, 22938, &scale ); // 0.7 in Q15 ->exp 0 - scale = add( scale, ( 15 - 0 ) ); - tmp = sub( tmp, shl( 6, sub( Q15, scale ) ) ); - tmp1 = BASOP_Util_Divide1616_Scale( tmp, 3277, &exp2 ); - exp2 = add( exp2, ( scale - 0 ) ); - - tmp2 = shr( mult( tmp1, 9864 ), 1 ); // exp = exp - - ener_mid_dec_thr_e = BASOP_Util_Add_MantExp( tmp2, exp2, ener_mid_dec_thr_fx, exp1, &ener_mid_dec_thr_fx ); - - - scale = BASOP_Util_Add_MantExp( st->hTdCngEnc->mov_shb_cng_ener_fx, 7, negate( ener_mid_dec_thr_fx ), ener_mid_dec_thr_e, &tmp ); - tmp1 = BASOP_Util_Divide1616_Scale( tmp, ener_mid_dec_thr_fx, &exp1 ); - exp1 = add( exp1, sub( scale, ener_mid_dec_thr_e ) ); - IF( LT_16( abs_s( tmp1 ), shr( 328, sub( 15, exp1 ) ) ) ) - { - idx_ener = st->hTdCngEnc->last_idx_ener; - move16(); - } - } - } - - st->hTdCngEnc->last_idx_ener = idx_ener; - move16(); - - push_indice( hBstr, IND_SHB_CNG_GAIN, idx_ener, 4 ); - push_indice( hBstr, IND_SID_BW, 1, 1 ); - delete_indice( hBstr, IND_CNG_ENV1 ); - IF( EQ_16( st->element_mode, IVAS_CPE_DFT ) ) - { - push_indice( st->hBstr, IND_BWIDTH, st->bwidth, 2 ); - } - ELSE - { - push_indice( hBstr, IND_UNUSED, 0, 2 ); - } - st->hTdCngEnc->ho_sid_bw = L_shl( L_and( st->hTdCngEnc->ho_sid_bw, (Word32) 0x3fffffffL ), 1 ); - st->hTdCngEnc->ho_sid_bw = L_or( st->hTdCngEnc->ho_sid_bw, 0x1L ); - move32(); - move32(); - } - ELSE IF( EQ_32( st->core_brate, SID_2k40 ) ) - { - st->hTdCngEnc->ho_sid_bw = L_shl( L_and( st->hTdCngEnc->ho_sid_bw, (Word32) 0x3fffffffL ), 1 ); - move32(); - push_indice( hBstr, IND_SID_BW, 0, 1 ); - } - - return; -} - -/*---------------------------------------------------------------------* - * shb_DTX() - * - * Decide if encoding SHB SID or not - *---------------------------------------------------------------------*/ - -static Word16 shb_DTX_ivas_fx( - Encoder_State *st, /* i/o: State structure */ - const Word16 *shb_speech_fx, /* i : SHB target signal (6-14kHz) at 16kHz Q0 */ - const Word16 *syn_12k8_16k_fx /* i : ACELP core synthesis at 12.8kHz or 16kHz Q0 */ -) -{ - Word16 i; - Word16 update; - - Word16 allow_cn_step = 0; - move16(); - Word16 shb_old_speech_fx[( ACELP_LOOK_12k8 + L_SUBFR + L_FRAME ) * 5 / 4]; - Word16 *shb_new_speech_fx; - Word32 wb_ener_fx; - Word32 shb_ener_fx; - Word16 log_wb_ener_fx; - Word16 log_shb_ener_fx; - Word16 tmp; - Word16 exp; - Word16 fra; - Word16 att_fx; /*Q8*/ - - TD_CNG_ENC_HANDLE hTdCngEnc = st->hTdCngEnc; - TD_BWE_ENC_HANDLE hBWE_TD = st->hBWE_TD; - - -#ifdef BASOP_NOGLOB_DECLARE_LOCAL - Flag Overflow = 0; - move16(); -#endif - - shb_new_speech_fx = shb_old_speech_fx + ( ACELP_LOOK_12k8 + L_SUBFR ) * 5 / 4; - Copy( hBWE_TD->old_speech_shb_fx, shb_old_speech_fx, ( ACELP_LOOK_12k8 + L_SUBFR ) * 5 / 4 ); // old_speech_shb_fx -> Q0 - Copy( shb_speech_fx, shb_new_speech_fx, L_FRAME16k ); // Q0 - Copy( shb_old_speech_fx + L_FRAME16k, hBWE_TD->old_speech_shb_fx, ( ACELP_LOOK_12k8 + L_SUBFR ) * 5 / 4 ); // Q0 - - shb_ener_fx = L_deposit_l( 0 ); - FOR( i = 0; i < L_FRAME16k; i++ ) - { -#ifdef BASOP_NOGLOB - shb_ener_fx = L_mac_sat( shb_ener_fx, shb_old_speech_fx[i], shb_old_speech_fx[i] ); // ( Q0 + Q0 + Q1 ) --> Q1 due to left shift in L_mac -#else - shb_ener_fx = L_mac( shb_ener_fx, shb_old_speech_fx[i], shb_old_speech_fx[i] ); -#endif - } - - shb_ener_fx = L_add( Mpy_32_16_1( shb_ener_fx, 102 ), 1 ); /* ( 1 / L_FRAME16K ) -> 102 in Q15, shb_ener_fx in Q1 */ - - wb_ener_fx = L_deposit_l( 0 ); - FOR( i = 0; i < st->L_frame; i++ ) - { -#ifdef BASOP_NOGLOB - wb_ener_fx = L_mac_o( wb_ener_fx, syn_12k8_16k_fx[i], syn_12k8_16k_fx[i], &Overflow ); // ( Q0 + Q0 + Q1 ) --> Q1 due to left shift in L_mac -#else - wb_ener_fx = L_mac( wb_ener_fx, syn_12k8_16k[i], syn_12k8_16k[i] ); -#endif - } - - wb_ener_fx = L_add( Mpy_32_16_1( wb_ener_fx, 128 ), 1 ); /* 128 in Q15, wb_ener_fx in Q1 */ - - exp = norm_l( wb_ener_fx ); - fra = Log2_norm_lc( L_shl( wb_ener_fx, exp ) ); - exp = sub( 30 - 1, exp ); - wb_ener_fx = Mpy_32_16( exp, fra, LG10 ); - -#ifdef BASOP_NOGLOB - log_wb_ener_fx = round_fx_o( L_shl_o( wb_ener_fx, 10, &Overflow ), &Overflow ); /* log_wb_ener_fx in Q8 */ -#else - log_wb_ener_fx = round_fx( L_shl( wb_ener_fx, 10 ) ); /* log_wb_ener_fx in Q8 */ -#endif - exp = norm_l( shb_ener_fx ); - fra = Log2_norm_lc( L_shl( shb_ener_fx, exp ) ); - exp = sub( 30 - 1, exp ); - shb_ener_fx = Mpy_32_16( exp, fra, LG10 ); - - - test(); - IF( EQ_16( st->element_mode, IVAS_SCE ) || EQ_16( st->element_mode, IVAS_CPE_DFT ) ) - { - Word32 att_fx32 = 0; - move32(); - Word16 index; - - apply_scale_ivas_fx( &att_fx32, st->hFdCngEnc->hFdCngCom->CngBandwidth, st->hFdCngEnc->hFdCngCom->CngBitrate, scaleTableStereo, SIZE_SCALE_TABLE_STEREO, &index ); // Q23; - - att_fx = extract_l( L_shr( att_fx32, 15 ) ); // Q8 - } - ELSE - { - att_fx = -1664; // Q8 - move16(); - } - - -#ifdef BASOP_NOGLOB - log_shb_ener_fx = sub_o( round_fx_o( L_shl_o( shb_ener_fx, 10, &Overflow ), &Overflow ), att_fx, &Overflow ); /* log_shb_ener_fx in Q8 */ -#else - log_shb_ener_fx = sub( round_fx( L_shl( shb_ener_fx, 10 ) ), att_fx ); /* log_shb_ener_fx in Q8 */ -#endif - - IF( st->hDtxEnc->first_CNG == 0 ) - { - - - hTdCngEnc->mov_wb_cng_ener_fx = log_wb_ener_fx; // Q8 - hTdCngEnc->mov_shb_cng_ener_fx = log_shb_ener_fx; // Q8 - hTdCngEnc->last_wb_cng_ener_fx = log_wb_ener_fx; // Q8 - hTdCngEnc->last_shb_cng_ener_fx = log_shb_ener_fx; // Q8 - move16(); - move16(); - move16(); - move16(); - } - IF( GT_16( abs_s( sub( log_wb_ener_fx, hTdCngEnc->mov_wb_cng_ener_fx ) ), 3072 ) ) // 12 in Q8 - { - allow_cn_step = 1; - move16(); - } - - /* Also allow step if shb energy has dropped 12 dB */ - test(); - test(); - IF( ( EQ_16( st->element_mode, IVAS_CPE_DFT ) || EQ_16( st->element_mode, IVAS_CPE_TD ) ) && GT_16( sub( hTdCngEnc->mov_shb_cng_ener_fx, log_shb_ener_fx ), 3072 ) ) - { - allow_cn_step = 1; - move16(); - } - - IF( EQ_16( allow_cn_step, 1 ) ) - { - hTdCngEnc->mov_wb_cng_ener_fx = log_wb_ener_fx; - hTdCngEnc->mov_shb_cng_ener_fx = log_shb_ener_fx; - } - ELSE - { - tmp = sub( log_wb_ener_fx, hTdCngEnc->mov_wb_cng_ener_fx ); /* Q8 */ - tmp = mult( tmp, 29491 ); /* Q8 */ - hTdCngEnc->mov_wb_cng_ener_fx = add( hTdCngEnc->mov_wb_cng_ener_fx, tmp ); /* Q8 */ - - tmp = sub( log_shb_ener_fx, hTdCngEnc->mov_shb_cng_ener_fx ); - tmp = mult( tmp, 8192 ); /* Q8 */ - hTdCngEnc->mov_shb_cng_ener_fx = add( hTdCngEnc->mov_shb_cng_ener_fx, tmp ); /* Q8 */ - } - - hTdCngEnc->shb_NO_DATA_cnt = add( hTdCngEnc->shb_NO_DATA_cnt, 1 ); - update = 0; - - move16(); - move16(); - - test(); - test(); - IF( EQ_32( st->core_brate, SID_2k40 ) ) - { - IF( st->hDtxEnc->first_CNG == 0 ) - { - update = 1; - move16(); - } - ELSE IF( hTdCngEnc->shb_cng_ini_cnt > 0 ) - { - hTdCngEnc->shb_cng_ini_cnt = sub( hTdCngEnc->shb_cng_ini_cnt, 1 ); - update = 1; - move16(); - move16(); - } - ELSE IF( EQ_16( hTdCngEnc->last_vad, 1 ) ) - { - update = 1; - move16(); - } - ELSE IF( GE_16( hTdCngEnc->shb_NO_DATA_cnt, 100 ) ) - { - update = 1; - move16(); - } - ELSE IF( GT_16( abs_s( sub( sub( hTdCngEnc->mov_wb_cng_ener_fx, hTdCngEnc->mov_shb_cng_ener_fx ), sub( hTdCngEnc->last_wb_cng_ener_fx, hTdCngEnc->last_shb_cng_ener_fx ) ) ), 768 ) ) - { - update = 1; - move16(); - } - ELSE IF( ( GE_16( st->bwidth, SWB ) && LT_16( hTdCngEnc->last_SID_bwidth, SWB ) ) || ( LT_16( st->bwidth, SWB ) && GE_16( hTdCngEnc->last_SID_bwidth, SWB ) ) ) - { - update = 1; - move16(); - } - - hTdCngEnc->last_SID_bwidth = st->bwidth; - move16(); - } - - /* LF-boost not yet implemented in decoder which means that the specific wb_sid information is not used */ - test(); - test(); - if ( ( EQ_16( st->element_mode, IVAS_CPE_DFT ) || EQ_16( st->element_mode, IVAS_CPE_TD ) ) && EQ_32( st->core_brate, SID_2k40 ) ) - { - update = 1; - move16(); - } - - IF( EQ_16( update, 1 ) ) - { - hTdCngEnc->last_wb_cng_ener_fx = hTdCngEnc->mov_wb_cng_ener_fx; - hTdCngEnc->last_shb_cng_ener_fx = hTdCngEnc->mov_shb_cng_ener_fx; - hTdCngEnc->shb_NO_DATA_cnt = 0; - move16(); - move16(); - move16(); - } - - test(); - return ( update ); -} diff --git a/lib_enc/cng_enc_fx.c b/lib_enc/cng_enc_fx.c index 44ce22cc9d629151ac2cb0a67bfd0e5c19d4b3ff..e1b5ca5625949a8625c300fcdde0e0fba92cef03 100644 --- a/lib_enc/cng_enc_fx.c +++ b/lib_enc/cng_enc_fx.c @@ -2,12 +2,10 @@ EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0 ====================================================================================*/ #include -#include "options.h" /* Compilation switches */ -#include "cnst.h" /* Common constants */ -#include "rom_enc.h" /* Encoder static table prototypes */ -#include "rom_com.h" /* Static table prototypes */ -//#include "prot_fx.h" /* Function prototypes */ -#include "prot.h" /* Function prototypes */ +#include "options.h" /* Compilation switches */ +#include "cnst.h" /* Common constants */ +#include "rom_enc.h" /* Encoder static table prototypes */ +#include "rom_com.h" /* Static table prototypes */ #include "prot_fx.h" /* Function prototypes */ #include "prot_fx_enc.h" /* Function prototypes */ //#include "basop_mpy.h" @@ -27,6 +25,8 @@ *---------------------------------------------------------------------*/ static void shb_CNG_encod_fx( Encoder_State *st_fx, const Word16 update_fx ); static Word16 shb_DTX_fx( Encoder_State *st_fx, const Word16 *shb_speech_fx, const Word16 *syn_12k8_16k ); +static Word16 shb_DTX_ivas_fx( Encoder_State *st, const Word16 *shb_speech_fx, const Word16 *syn_12k8_16k_fx ); +static void shb_CNG_encod_ivas_fx( Encoder_State *st, const Word16 update ); /*---------------------------------------------------------------------* * CNG_enc() * @@ -50,10 +50,14 @@ void CNG_enc_fx( Word16 m1; Word16 res[L_FRAME16k]; Word16 step_inv = 0; + move16(); Word16 hi, lo; Word16 maxl = 0; + move16(); Word16 num_bits = 0; + move16(); Word16 step = 0; + move16(); Word16 *pt_res; const Word16 *pt_sp; Word16 enr; @@ -64,9 +68,11 @@ void CNG_enc_fx( Word32 L_tmp1; Word16 exp; Word16 m = 0; + move16(); Word16 tmp[HO_HIST_SIZE * M]; Word16 ll, s_ptr; Word16 tmpv, maxv, scale, att = 1; + move16(); Word16 lsf_tmp[M]; Word32 C[M]; Word32 max_val[2]; @@ -77,9 +83,12 @@ void CNG_enc_fx( Word16 max_dev; Word16 dist; Word16 max_idx1[2] = { 0, 0 }; + move16(); + move16(); Word16 fft_io[L_FRAME16k]; Word16 *ptR, *ptI; Word32 enr1 = 0; + move32(); Word32 env[NUM_ENV_CNG]; Word32 min1; Word16 min1_idx; @@ -90,21 +99,24 @@ void CNG_enc_fx( Word16 temp_lo_fx, temp_hi_fx; Word16 exp_pow; Word16 force_cn_step = 0; + move16(); Word16 tmp_loop; Word16 st_lp_sp_enr; DTX_ENC_HANDLE hDtxEnc = st_fx->hDtxEnc; TD_CNG_ENC_HANDLE hTdCngEnc = st_fx->hTdCngEnc; BSTR_ENC_HANDLE hBstr = st_fx->hBstr; st_lp_sp_enr = hTdCngEnc->lp_sp_enr_fx; + move16(); Word16 lp_ener_thr_scale; #ifdef BASOP_NOGLOB_DECLARE_LOCAL Flag Overflow = 0; + move32(); #endif /* Temp variables for floating point functions */ lp_ener_thr_scale = 8; /* 4.0f*/ /*IVAS_CODE Q2 */ move16(); - if ( NE_16( st_fx->element_mode, EVS_MONO ) ) + if ( st_fx->element_mode != EVS_MONO ) { lp_ener_thr_scale = 7; /* 3.5f;*/ move16(); @@ -163,8 +175,9 @@ void CNG_enc_fx( test(); test(); test(); - IF( GT_32( st_fx->last_core_brate, SID_2k40 ) && ( EQ_16( st_fx->last_core, HQ_CORE ) || st_fx->hTdCngEnc->burst_ho_cnt > 0 ) && LT_16( hTdCngEnc->lp_sp_enr_fx, 1536 ) && - GT_16( sub( sp_enr, hTdCngEnc->lp_sp_enr_fx ), 1024 ) && GT_16( sp_enr, 1536 ) ) + test(); + IF( GT_32( st_fx->last_core_brate, SID_2k40 ) && ( EQ_16( st_fx->last_core, HQ_CORE ) || st_fx->hTdCngEnc->burst_ho_cnt > 0 ) && LT_16( hTdCngEnc->lp_sp_enr_fx, 1536 /*6.0f in Q8*/ ) && + GT_16( sub( sp_enr, hTdCngEnc->lp_sp_enr_fx ), 1024 /*4.0f in Q8*/ ) && GT_16( sp_enr, 1536 /*6.0f in Q8*/ ) ) { hTdCngEnc->lp_sp_enr_fx = sp_enr; move16(); @@ -174,10 +187,12 @@ void CNG_enc_fx( ELSE { hTdCngEnc->lp_sp_enr_fx = round_fx( L_mac( L_mult( 29491 /* 0.9, Q15 */, hTdCngEnc->lp_sp_enr_fx ), 3277 /* 0.1, Q15 */, sp_enr ) ); /* Q8 (8+15+1-16) */ + move16(); } } /* update the pointer to circular buffer of old LSP vectors */ hTdCngEnc->cng_hist_ptr = add( hTdCngEnc->cng_hist_ptr, 1 ); + move16(); if ( EQ_16( hTdCngEnc->cng_hist_ptr, DTX_HIST_SIZE ) ) { hTdCngEnc->cng_hist_ptr = 0; @@ -203,7 +218,7 @@ void CNG_enc_fx( IF( EQ_16( st_fx->L_frame, L_FRAME ) ) { lsp2lsf_fx( &hTdCngEnc->cng_lsp_hist_fx[i * M], lsf_tmp, M, INT_FS_FX ); - ftmp_fx = 964; + ftmp_fx = 964; /*(6400/(M+1))X2.56 */ move16(); /*QX2.56 */ tmpv = sub( 16384, add( lsf_tmp[M - 1], ftmp_fx ) ); /*QX2.56 */ L_tmp = L_mult0( tmpv, tmpv ); /*QX6.5536 */ @@ -211,7 +226,7 @@ void CNG_enc_fx( ELSE { lsp2lsf_fx( &hTdCngEnc->cng_lsp_hist_fx[i * M], lsf_tmp, M, INT_FS_16k ); - ftmp_fx = 1205; + ftmp_fx = 1205; /*(8000/(M+1))X2.56*/ move16(); /*QX2.56 */ tmpv = sub( 20480, add( lsf_tmp[M - 1], ftmp_fx ) ); /*QX2.56 */ L_tmp = L_mult0( tmpv, tmpv ); /*QX6.5536 */ @@ -225,7 +240,7 @@ void CNG_enc_fx( L_tmp = L_mac0( L_tmp, tmpv, tmpv ); /*QX6.5536 */ } - C[i] = Mpy_32_16_1( L_tmp, 1928 ); + C[i] = Mpy_32_16_1( L_tmp, 1928 /*.0588235f Q15*/ ); move32(); /*QX6.5536 */ IF( GT_32( C[i], max_val[0] ) ) @@ -251,6 +266,7 @@ void CNG_enc_fx( FOR( i = 0; i < M; i++ ) { L_tmp = 0; + move32(); FOR( j = 0; j < hDtxEnc->cng_hist_size; j++ ) { L_tmp = L_add( L_tmp, L_deposit_l( hTdCngEnc->cng_lsp_hist_fx[j * M + i] ) ); /*Q15 */ @@ -260,6 +276,7 @@ void CNG_enc_fx( tmpv = div_s( 1, sub( hDtxEnc->cng_hist_size, 2 ) ); /*Q15 */ L_tmp = Mpy_32_16_1( L_tmp, tmpv ); /*Q15 */ lsp_new[i] = extract_l( L_tmp ); /*Q15 */ + move16(); } max_idx1[0] = max_idx[0]; move16(); @@ -280,7 +297,7 @@ void CNG_enc_fx( test(); test(); IF( ( ( hDtxEnc->cng_cnt == 0 ) && - GT_16( hTdCngEnc->lp_sp_enr_fx, 1536 ) && + GT_16( hTdCngEnc->lp_sp_enr_fx, 1536 /* 6.0, Q8 */ ) && ( LT_16( add( st_lp_sp_enr, 1024 /* 4.0, Q8 */ ), sp_enr ) ) && ( hDtxEnc->first_CNG != 0 ) && ( hTdCngEnc->old_enr_index >= 0 ) && @@ -297,12 +314,12 @@ void CNG_enc_fx( Copy( st_fx->lsp_old_fx, hDtxEnc->lspCNG_fx, M ); /* Average the CNG spectral envelope in case of the very first CNG frame */ - IF( NE_16( st_fx->element_mode, EVS_MONO ) ) + IF( st_fx->element_mode != EVS_MONO ) { FOR( i = 0; i < M; i++ ) { /*lsp_new[i] = 0.5f * (lsp_mid[i] + lsp_new[i]);*/ - lsp_new[i] = mac_r( L_mult( lsp_mid[i], 16384 ), lsp_new[i], 16384 ); + lsp_new[i] = mac_r( L_mult( lsp_mid[i], 16384 ), lsp_new[i], 16384 /*.5 Q15*/ ); move16(); } } @@ -319,11 +336,7 @@ void CNG_enc_fx( } ELSE { -#ifdef LSF_RE_USE_SECONDARY_CHANNEL - lsf_enc_fx( st_fx, lsf_new, lsp_new, NULL, NULL, 100, 0, 0, NULL, Q_new ); -#else lsf_enc_fx( st_fx, lsf_new, lsp_new, NULL, NULL, 100, 0, 0, Q_new ); -#endif } /* Reset CNG history if CNG frame length is changed */ test(); @@ -372,7 +385,8 @@ void CNG_enc_fx( test(); test(); test(); - IF( EQ_16( st_fx->element_mode, EVS_MONO ) && ( ( st_fx->Opt_AMR_WB || EQ_16( st_fx->bwidth, WB ) ) && ( !hDtxEnc->first_CNG || GE_16( hTdCngEnc->act_cnt2, MIN_ACT_CNG_UPD ) ) ) ) + test(); + IF( st_fx->element_mode == EVS_MONO && ( ( st_fx->Opt_AMR_WB || EQ_16( st_fx->bwidth, WB ) ) && ( !hDtxEnc->first_CNG || GE_16( hTdCngEnc->act_cnt2, MIN_ACT_CNG_UPD ) ) ) ) { IF( GT_32( hDtxEnc->last_active_brate, ACELP_16k40 ) ) { @@ -382,11 +396,13 @@ void CNG_enc_fx( ELSE { hDtxEnc->CNG_mode = get_cng_mode( hDtxEnc->last_active_brate ); + move16(); } } /* If first sid after active burst update LSF history from circ buffer */ hTdCngEnc->burst_ho_cnt = s_min( hTdCngEnc->burst_ho_cnt, hTdCngEnc->ho_circ_size ); + move16(); hTdCngEnc->act_cnt = 0; move16(); s_ptr = add( sub( hTdCngEnc->ho_circ_ptr, hTdCngEnc->burst_ho_cnt ), 1 ); @@ -399,6 +415,7 @@ void CNG_enc_fx( FOR( ll = hTdCngEnc->burst_ho_cnt; ll > 0; ll-- ) { hTdCngEnc->ho_hist_ptr = add( hTdCngEnc->ho_hist_ptr, 1 ); + move16(); if ( EQ_16( hTdCngEnc->ho_hist_ptr, HO_HIST_SIZE ) ) { hTdCngEnc->ho_hist_ptr = 0; @@ -422,9 +439,11 @@ void CNG_enc_fx( Copy( &( hTdCngEnc->ho_lsp_circ_fx[s_ptr * M] ), &( hTdCngEnc->ho_lsp_hist_fx[hTdCngEnc->ho_hist_ptr * M] ), M ); Copy32( &( hTdCngEnc->ho_ener_circ_fx[s_ptr] ), &( hTdCngEnc->ho_ener_hist_fx[hTdCngEnc->ho_hist_ptr] ), 1 ); hTdCngEnc->ho_sid_bw = L_shl( L_and( hTdCngEnc->ho_sid_bw, (Word32) 0x3fffffffL ), 1 ); + move32(); Copy32( &( hTdCngEnc->ho_env_circ_fx[s_ptr * NUM_ENV_CNG] ), &( hTdCngEnc->ho_env_hist_fx[hTdCngEnc->ho_hist_ptr * NUM_ENV_CNG] ), NUM_ENV_CNG ); hTdCngEnc->ho_hist_size = add( hTdCngEnc->ho_hist_size, 1 ); + move16(); if ( GT_16( hTdCngEnc->ho_hist_size, HO_HIST_SIZE ) ) { hTdCngEnc->ho_hist_size = HO_HIST_SIZE; @@ -458,9 +477,10 @@ void CNG_enc_fx( #endif test(); test(); - IF( ( hDtxEnc->first_CNG > 0 || EQ_16( st_fx->element_mode, EVS_MONO ) ) && L_tmp1 > 0 ) + IF( ( hDtxEnc->first_CNG > 0 || st_fx->element_mode == EVS_MONO ) && L_tmp1 > 0 ) { *allow_cn_step = s_or( *allow_cn_step, 1 ); + move16(); } } test(); @@ -481,7 +501,7 @@ void CNG_enc_fx( L_enr = Mult_32_16( hTdCngEnc->ho_ener_hist_fx[ptr], W_DTX_HO_FX[0] ); /* Q6+15-15->Q6 */ weights = W_DTX_HO_FX[0]; /* Q15 */ - + move16(); m = 1; move16(); FOR( k = 1; k < hTdCngEnc->ho_hist_size; k++ ) @@ -531,7 +551,7 @@ void CNG_enc_fx( IF( EQ_16( st_fx->L_frame, L_FRAME ) ) { lsp2lsf_fx( &tmp[i * M], lsf_tmp, M, INT_FS_FX ); - ftmp_fx = 964; + ftmp_fx = 964; /*(6400/(M+1))X2.56*/ move16(); /*QX2.56 */ tmpv = sub( 16384, add( lsf_tmp[M - 1], ftmp_fx ) ); /*QX2.56 */ L_tmp = L_mult0( tmpv, tmpv ); /*QX6.5536 */ @@ -539,7 +559,7 @@ void CNG_enc_fx( ELSE { lsp2lsf_fx( &tmp[i * M], lsf_tmp, M, INT_FS_16k ); - ftmp_fx = 1205; + ftmp_fx = 1205; /*(8000/(M+1))X2.56*/ move16(); /*QX2.56 */ tmpv = sub( 20480, add( lsf_tmp[M - 1], ftmp_fx ) ); /*QX2.56 */ L_tmp = L_mult0( tmpv, tmpv ); /*QX6.5536 */ @@ -615,14 +635,12 @@ void CNG_enc_fx( dist = 0; /*Q15 */ max_dev = 0; /*Q15 */ + move16(); + move16(); FOR( i = 0; i < M; i++ ) { dev = abs_s( sub( lsp_tmp[i], lsp_new[i] ) ); /*Q15 */ -#ifdef BASOP_NOGLOB - dist = add_o( dist, dev, &Overflow ); /*Q15 */ -#else - dist = add( dist, dev ); /*Q15 */ -#endif + dist = add_o( dist, dev, &Overflow ); /*Q15 */ if ( GT_16( dev, max_dev ) ) { max_dev = dev; @@ -656,31 +674,19 @@ void CNG_enc_fx( FOR( j = 0; j < m1; j++ ) { /* env[i] += tmp_env[j*NUM_ENV_CNG+i]; */ -#ifdef BASOP_NOGLOB L_tmp = L_add_sat( L_tmp, tmp_env[j * NUM_ENV_CNG + i] ); -#else - L_tmp = L_add( L_tmp, tmp_env[j * NUM_ENV_CNG + i] ); -#endif } /* env[i] /= (float)m1; */ /* env[i] = env[i] - 2*hTdCngEnc->lp_ener_fx; */ IF( EQ_16( m1, 1 ) ) { -#ifdef BASOP_NOGLOB L_tmp = L_sub_sat( L_tmp, L_add_sat( hTdCngEnc->lp_ener_fx, hTdCngEnc->lp_ener_fx ) ); -#else - L_tmp = L_sub( L_tmp, L_add( hTdCngEnc->lp_ener_fx, hTdCngEnc->lp_ener_fx ) ); -#endif } ELSE { tmp1 = div_s( 1, m1 ); L_tmp = Mult_32_16( L_tmp, tmp1 ); -#ifdef BASOP_NOGLOB L_tmp = L_sub_sat( L_tmp, L_add_sat( hTdCngEnc->lp_ener_fx, hTdCngEnc->lp_ener_fx ) ); -#else - L_tmp = L_sub( L_tmp, L_add( hTdCngEnc->lp_ener_fx, hTdCngEnc->lp_ener_fx ) ); -#endif } env[i] = L_tmp; @@ -719,11 +725,6 @@ void CNG_enc_fx( test(); IF( EQ_16( st_fx->element_mode, IVAS_CPE_DFT ) || EQ_16( st_fx->element_mode, IVAS_CPE_TD ) ) { - // PMT("Code to be completed") -#ifdef IVAS_CODE - att = powf( 10.0f, hTdCngEnc->CNG_att / 20.0f ); - v_multc( res1, att, res1, st->L_frame ); -#endif } ELSE IF( NE_16( st_fx->bwidth, NB ) ) { @@ -731,16 +732,17 @@ void CNG_enc_fx( IF( EQ_16( st_fx->bwidth, WB ) && hDtxEnc->CNG_mode >= 0 ) { ftmp_fx = HO_ATT_FX[hDtxEnc->CNG_mode]; + move16(); } ELSE { - ftmp_fx = 19661; + ftmp_fx = 19661; /*0.6f in Q15*/ move16(); } - att = mult( ftmp_fx, 5461 ); /* Q15 */ - L_tmp = L_mult( att, 8 ); /* Q16 */ - tmp1 = extract_l( L_shr( L_tmp, 2 ) ); /* Q14 */ + att = mult( ftmp_fx, 5461 /*1/6f in Q15*/ ); /* Q15 */ + L_tmp = L_mult( att, 8 ); /* Q16 */ + tmp1 = extract_l( L_shr( L_tmp, 2 ) ); /* Q14 */ tmp1 = add( 16384, tmp1 ); att = div_s( 16374, tmp1 ); /* Q15 */ @@ -769,15 +771,9 @@ void CNG_enc_fx( FOR( i = 0; i < NUM_ENV_CNG; i++ ) { /* env[i] = 2.0f*(*ptR * *ptR + *ptI * *ptI)/L_FFT; */ -#ifdef BASOP_NOGLOB L_tmp = L_mult_o( *ptR, *ptR, &Overflow ); /* 2*Q_new+1 */ L_tmp = L_add_o( L_tmp, L_mult_o( *ptI, *ptI, &Overflow ), &Overflow ); /* 2*Q_new+1 */ L_tmp = L_add_o( L_tmp, L_tmp, &Overflow ); /* 2*Q_new+1 */ -#else /* BASOP_NOGLOB */ - L_tmp = L_mult( *ptR, *ptR ); /* 2*Q_new+1 */ - L_tmp = L_add( L_tmp, L_mult( *ptI, *ptI ) ); /* 2*Q_new+1 */ - L_tmp = L_add( L_tmp, L_tmp ); /* 2*Q_new+1 */ -#endif /* BASOP_NOGLOB */ L_tmp = Mult_32_16( L_tmp, 128 ); /* 2*Q_new+1 */ tmp1 = add( add( Q_new, Q_new ), 1 ); env[i] = L_shr( L_tmp, sub( tmp1, 6 ) ); @@ -807,15 +803,9 @@ void CNG_enc_fx( L_tmp = L_mult0( tmpv, tmpv ); pt_res++; tmpv = shl( *pt_res, scale ); -#ifdef BASOP_NOGLOB L_tmp = L_mac0_sat( L_tmp, tmpv, tmpv ); /* 2*(Q_new+scale) */ pt_res++; L_ener = L_add_sat( L_ener, L_shr( L_tmp, 7 ) ); /* 2*(Q_new+scale)+1, divide by L_frame done here */ -#else - L_tmp = L_mac0( L_tmp, tmpv, tmpv ); /* 2*(Q_new+scale) */ - pt_res++; - L_ener = L_add( L_ener, L_shr( L_tmp, 7 ) ); /* 2*(Q_new+scale)+1, divide by L_frame done here */ -#endif } } ELSE /* L_FRAME16k */ @@ -826,15 +816,9 @@ void CNG_enc_fx( L_tmp = L_mult0( tmpv, tmpv ); pt_res++; tmpv = shl( *pt_res, scale ); -#ifdef BASOP_NOGLOB L_tmp = L_mac0_sat( L_tmp, tmpv, tmpv ); /* 2*(Q_new+scale) */ pt_res++; L_ener = L_add_sat( L_ener, L_shr( Mult_32_16( L_tmp, 26214 /* 256/320, Q15 */ ), 7 ) ); /* 2*(Q_new+scale)+15+1-16+1, divide by L_frame done here */ -#else - L_tmp = L_mac0( L_tmp, tmpv, tmpv ); /* 2*(Q_new+scale) */ - pt_res++; - L_ener = L_add( L_ener, L_shr( Mult_32_16( L_tmp, 26214 /* 256/320, Q15 */ ), 7 ) ); /* 2*(Q_new+scale)+15+1-16+1, divide by L_frame done here */ -#endif } } /* convert log2 of residual signal energy */ @@ -864,11 +848,7 @@ void CNG_enc_fx( L_tmp1 = L_add( env[i], 0 ); FOR( j = 0; j < hDtxEnc->cng_hist_size; j++ ) { -#ifdef BASOP_NOGLOB L_tmp1 = L_add_sat( L_tmp1, hTdCngEnc->cng_res_env_fx[j * NUM_ENV_CNG + i] ); -#else - L_tmp1 = L_add( L_tmp1, hTdCngEnc->cng_res_env_fx[j * NUM_ENV_CNG + i] ); -#endif } L_tmp = L_add( hTdCngEnc->cng_res_env_fx[max_idx1[0] * NUM_ENV_CNG + i], hTdCngEnc->cng_res_env_fx[max_idx1[1] * NUM_ENV_CNG + i] ); L_tmp1 = L_sub( L_tmp1, L_tmp ); @@ -919,11 +899,9 @@ void CNG_enc_fx( enr = round_fx( L_tmp ); /* Q8 */ } /* decrease the energy in case of WB input */ + test(); IF( EQ_16( st_fx->element_mode, IVAS_SCE ) || EQ_16( st_fx->element_mode, IVAS_CPE_DFT ) ) { - // PMT("CNG IVAS_SCE and IVAS_CPE_DFT code missing") - // IVAS_CODE - // enr += hTdCngEnc->CNG_att * FAC_LOG2 / 10.0f; } ELSE IF( NE_16( st_fx->bwidth, NB ) ) { @@ -1011,6 +989,7 @@ void CNG_enc_fx( /* substract by 2 not done to leave Energy in Q2 */ lo = L_Extract_lc( L_tmp, &hi ); hTdCngEnc->Enew_fx = Pow2( add( hi, 4 ), lo ); /* Q6 */ + move32(); IF( EQ_32( st_fx->core_brate, SID_2k40 ) ) { /* enr1 = (float)log10( st->Enew*L_frame + 0.1f ) / (float)log10( 2.0f );*/ @@ -1018,11 +997,7 @@ void CNG_enc_fx( L_tmp = L_shl( hTdCngEnc->Enew_fx, exp ); /*Q(exp+6) */ L_tmp = Mult_32_16( L_tmp, shl( st_fx->L_frame, 5 ) ); /* Q(exp+6+5-15=exp-4) */ -#ifdef BASOP_NOGLOB L_tmp = L_shr_sat( L_tmp, sub( exp, 10 ) ); /* Q6 */ -#else - L_tmp = L_shr( L_tmp, sub( exp, 10 ) ); /* Q6 */ -#endif exp = norm_l( L_tmp ); fra = Log2_norm_lc( L_shl( L_tmp, exp ) ); @@ -1075,13 +1050,9 @@ void CNG_enc_fx( /* d += (env[j] - CNG_details_codebook_fx[i][j]) * (env[j] - CNG_details_codebook_fx[i][j]);*/ L_tmp = L_sub( env[j], L_deposit_l( CNG_details_codebook_fx[i][j] ) ); /* Q6 */ exp = norm_l( L_tmp ); - L_tmp = L_shl( L_tmp, exp ); /*Q(exp+6)*/ - tmp1 = extract_h( L_tmp ); /*Q(exp+6-16)=exp-10*/ -#ifdef BASOP_NOGLOB - L_tmp = L_mult_o( tmp1, tmp1, &Overflow ); /*Q(2*exp - 19)*/ -#else /* BASOP_NOGLOB */ - L_tmp = L_mult( tmp1, tmp1 ); /*Q(2*exp - 19)*/ -#endif + L_tmp = L_shl( L_tmp, exp ); /*Q(exp+6)*/ + tmp1 = extract_h( L_tmp ); /*Q(exp+6-16)=exp-10*/ + L_tmp = L_mult_o( tmp1, tmp1, &Overflow ); /*Q(2*exp - 19)*/ L_tmp = L_shr( L_tmp, sub( add( exp, exp ), 36 ) ); /* Q17 */ d = L_add( d, L_tmp ); } @@ -1098,6 +1069,7 @@ void CNG_enc_fx( FOR( i = 0; i < NUM_ENV_CNG; i++ ) { q_env[i] = L_deposit_l( CNG_details_codebook_fx[min1_idx][i] ); + move32(); } } /* Update hangover memory during CNG */ @@ -1106,6 +1078,7 @@ void CNG_enc_fx( { /* update the pointer to circular buffer of old LSP vectors */ hTdCngEnc->ho_hist_ptr = add( hTdCngEnc->ho_hist_ptr, 1 ); + move16(); if ( EQ_16( hTdCngEnc->ho_hist_ptr, HO_HIST_SIZE ) ) { hTdCngEnc->ho_hist_ptr = 0; @@ -1139,6 +1112,7 @@ void CNG_enc_fx( Copy32( env, &( hTdCngEnc->ho_env_hist_fx[( hTdCngEnc->ho_hist_ptr ) * NUM_ENV_CNG] ), NUM_ENV_CNG ); } hTdCngEnc->ho_hist_size = add( hTdCngEnc->ho_hist_size, 1 ); + move16(); if ( GT_16( hTdCngEnc->ho_hist_size, HO_HIST_SIZE ) ) { hTdCngEnc->ho_hist_size = HO_HIST_SIZE; @@ -1167,6 +1141,7 @@ void CNG_enc_fx( move16(); push_indice_fx( hBstr, IND_SID_TYPE, 0, 1 ); + test(); IF( LT_32( st_fx->input_Fs, 32000 ) && NE_16( st_fx->element_mode, IVAS_CPE_DFT ) ) { push_indice_fx( hBstr, IND_SID_BW, 0, 1 ); @@ -1193,6 +1168,7 @@ void CNG_enc_fx( ELSE { hDtxEnc->cng_cnt = add( hDtxEnc->cng_cnt, 1 ); + move16(); } return; @@ -1419,7 +1395,7 @@ void CNG_enc_ivas_fx( IF( EQ_16( st_fx->L_frame, L_FRAME ) ) { lsp2lsf_fx( &hTdCngEnc->cng_lsp_hist_fx[i * M], lsf_tmp, M, INT_FS_FX ); - ftmp_fx = 964; + ftmp_fx = 964; /*(6400/(M+1))X2.56*/ move16(); /*QX2.56 */ tmpv = sub( 16384, add( lsf_tmp[M - 1], ftmp_fx ) ); /*QX2.56 */ L_tmp = L_mult0( tmpv, tmpv ); /*QX6.5536 */ @@ -1427,7 +1403,7 @@ void CNG_enc_ivas_fx( ELSE { lsp2lsf_fx( &hTdCngEnc->cng_lsp_hist_fx[i * M], lsf_tmp, M, INT_FS_16k ); - ftmp_fx = 1205; + ftmp_fx = 1205; /*(8000/(M+1))X2.56*/ move16(); /*QX2.56 */ tmpv = sub( 20480, add( lsf_tmp[M - 1], ftmp_fx ) ); /*QX2.56 */ L_tmp = L_mult0( tmpv, tmpv ); /*QX6.5536 */ @@ -1467,6 +1443,7 @@ void CNG_enc_ivas_fx( FOR( i = 0; i < M; i++ ) { L_tmp = 0; + move32(); FOR( j = 0; j < hDtxEnc->cng_hist_size; j++ ) { L_tmp = L_add( L_tmp, L_deposit_l( hTdCngEnc->cng_lsp_hist_fx[j * M + i] ) ); /*Q15 */ @@ -1476,6 +1453,7 @@ void CNG_enc_ivas_fx( tmpv = div_s( 1, sub( hDtxEnc->cng_hist_size, 2 ) ); /*Q15 */ L_tmp = Mpy_32_16_1( L_tmp, tmpv ); /*Q15 */ lsp_new[i] = extract_l( L_tmp ); /*Q15 */ + move16(); } max_idx1[0] = max_idx[0]; move16(); @@ -1518,7 +1496,7 @@ void CNG_enc_ivas_fx( FOR( i = 0; i < M; i++ ) { /*lsp_new[i] = 0.5f * (lsp_mid[i] + lsp_new[i]);*/ - lsp_new[i] = mac_r( L_mult( lsp_mid[i], 16384 ), lsp_new[i], 16384 ); + lsp_new[i] = mac_r( L_mult( lsp_mid[i], 16384 /*.5f Q15*/ ), lsp_new[i], 16384 /*.5f Q15*/ ); move16(); } } @@ -1574,7 +1552,7 @@ void CNG_enc_ivas_fx( FOR( i = 0; i < M; i++ ) { /* AR low-pass filter */ - hDtxEnc->lspCNG_fx[i] = mac_r( L_mult( CNG_ISF_FACT_FX, hDtxEnc->lspCNG_fx[i] ), 32768 - CNG_ISF_FACT_FX, lsp_new[i] ); + hDtxEnc->lspCNG_fx[i] = mac_r( L_mult( CNG_ISF_FACT_FX, hDtxEnc->lspCNG_fx[i] ), 32768 /*1f Q15*/ - CNG_ISF_FACT_FX, lsp_new[i] ); move16(); /* Q15 (15+15+1-16) */ } } @@ -1585,6 +1563,7 @@ void CNG_enc_ivas_fx( test(); test(); test(); + test(); IF( ( st_fx->element_mode == EVS_MONO ) && ( ( st_fx->Opt_AMR_WB || EQ_16( st_fx->bwidth, WB ) ) && ( !hDtxEnc->first_CNG || GE_16( hTdCngEnc->act_cnt2, MIN_ACT_CNG_UPD ) ) ) ) { IF( GT_32( hDtxEnc->last_active_brate, ACELP_16k40 ) ) @@ -1595,6 +1574,7 @@ void CNG_enc_ivas_fx( ELSE { hDtxEnc->CNG_mode = get_cng_mode( hDtxEnc->last_active_brate ); + move16(); } } @@ -1688,7 +1668,7 @@ void CNG_enc_ivas_fx( L_ener = Mult_32_16( hTdCngEnc->ho_ener_hist_fx[ptr], W_DTX_HO_FX[0] ); /* Q6+15-15->Q6 */ weights = W_DTX_HO_FX[0]; /* Q15 */ - + move16(); m = 1; move16(); FOR( k = 1; k < hTdCngEnc->ho_hist_size; k++ ) @@ -1738,7 +1718,7 @@ void CNG_enc_ivas_fx( IF( EQ_16( st_fx->L_frame, L_FRAME ) ) { lsp2lsf_fx( &tmp[i * M], lsf_tmp, M, INT_FS_FX ); - ftmp_fx = 964; + ftmp_fx = 964; /*(6400/(M+1))X2.56*/ move16(); /*QX2.56 */ tmpv = sub( 16384, add( lsf_tmp[M - 1], ftmp_fx ) ); /*QX2.56 */ L_tmp = L_mult0( tmpv, tmpv ); /*QX6.5536 */ @@ -1746,7 +1726,7 @@ void CNG_enc_ivas_fx( ELSE { lsp2lsf_fx( &tmp[i * M], lsf_tmp, M, INT_FS_16k ); - ftmp_fx = 1205; + ftmp_fx = 1205; /*(8000/(M+1))X2.56*/ move16(); /*QX2.56 */ tmpv = sub( 20480, add( lsf_tmp[M - 1], ftmp_fx ) ); /*QX2.56 */ L_tmp = L_mult0( tmpv, tmpv ); /*QX6.5536 */ @@ -1815,9 +1795,9 @@ void CNG_enc_ivas_fx( } L_tmp = L_sub( L_tmp, L_add( L_deposit_l( tmp[max_idx[0] * M + i] ), L_deposit_l( tmp[max_idx[1] * M + i] ) ) ); /*Q15 */ - tmpv = div_s( 1, sub( m, 2 ) ); /*Q15 */ - L_tmp = Mpy_32_16_1( L_tmp, tmpv ); /*Q15 */ - lsp_tmp[i] = extract_l( L_tmp ); /*Q15 */ + tmpv = div_s( 1, sub( m, 2 ) ); /*Q15 */ /*Q15 */ + L_tmp = Mpy_32_16_1( L_tmp, tmpv ); /*Q15 */ /*Q15 */ + lsp_tmp[i] = extract_l( L_tmp ); /*Q15 */ /*Q15 */ move16(); } } @@ -1851,7 +1831,7 @@ void CNG_enc_ivas_fx( FOR( i = 0; i < M; i++ ) { /* AR low-pass filter */ - hDtxEnc->lspCNG_fx[i] = add( mult_r( 26214, lsp_tmp[i] ), mult_r( 6554, lsp_new[i] ) ); /* Q15 */ + hDtxEnc->lspCNG_fx[i] = add( mult_r( 26214 /*.8f Q15*/, lsp_tmp[i] ), mult_r( 6554 /*.2f Q15*/, lsp_new[i] ) ); /* Q15 */ move16(); } } @@ -1863,31 +1843,19 @@ void CNG_enc_ivas_fx( FOR( j = 0; j < m1; j++ ) { /* env[i] += tmp_env[j*NUM_ENV_CNG+i]; */ -#ifdef BASOP_NOGLOB L_tmp = L_add_sat( L_tmp, tmp_env[j * NUM_ENV_CNG + i] ); -#else - L_tmp = L_add( L_tmp, tmp_env[j * NUM_ENV_CNG + i] ); -#endif } /* env[i] /= (float)m1; */ /* env[i] = env[i] - 2*hTdCngEnc->lp_ener_fx; */ IF( EQ_16( m1, 1 ) ) { -#ifdef BASOP_NOGLOB L_tmp = L_sub_sat( L_tmp, L_add_sat( hTdCngEnc->lp_ener_fx, hTdCngEnc->lp_ener_fx ) ); -#else - L_tmp = L_sub( L_tmp, L_add( hTdCngEnc->lp_ener_fx, hTdCngEnc->lp_ener_fx ) ); -#endif } ELSE { tmp1 = div_s( 1, m1 ); L_tmp = Mult_32_16( L_tmp, tmp1 ); -#ifdef BASOP_NOGLOB L_tmp = L_sub_sat( L_tmp, L_add_sat( hTdCngEnc->lp_ener_fx, hTdCngEnc->lp_ener_fx ) ); -#else - L_tmp = L_sub( L_tmp, L_add( hTdCngEnc->lp_ener_fx, hTdCngEnc->lp_ener_fx ) ); -#endif } env[i] = L_tmp; /* Q6*/ @@ -1909,7 +1877,7 @@ void CNG_enc_ivas_fx( { E_LPC_f_lsp_a_conversion( hDtxEnc->lspCNG_fx, Aq, M ); exp = sub( Q14, norm_s( Aq[0] ) ); - Scale_sig( Aq, M, sub( Q12, exp ) ); + Scale_sig( Aq, M, sub( Q12, exp ) ); // Q12 } tmp_loop = shr( st_fx->L_frame, 6 ); @@ -1930,8 +1898,8 @@ void CNG_enc_ivas_fx( { L_tmp1 = L_mult0( hTdCngEnc->CNG_att_fx, 26214 /* 1/20.0f in Q19 */ ); // Q26 (7 + 19) L_tmp1 = BASOP_Util_fPow( 1342177280 /*10 in Q27 */, 4, L_tmp1, 5, &exp ); - att = extract_h( L_shl( L_tmp1, exp ) ); // Q15 - v_multc_fixed_16_16( res1, att, res1, st_fx->L_frame ); /* Q_new */ + att = extract_h( L_shl( L_sub( L_tmp1, EPSILON_FX ), exp ) ); // Q15 // Subtracting by EPSILON_FX to avoid assertion when L_tmp1 value is 1073741824 and exp =1 + v_multc_fixed_16_16( res1, att, res1, st_fx->L_frame ); /* Q_new */ } ELSE IF( st_fx->bwidth != NB ) { @@ -1943,7 +1911,7 @@ void CNG_enc_ivas_fx( } ELSE { - ftmp_fx = 19661; + ftmp_fx = 19661; /*.6f in Q15*/ move16(); } @@ -1978,15 +1946,9 @@ void CNG_enc_ivas_fx( FOR( i = 0; i < NUM_ENV_CNG; i++ ) { /* env[i] = 2.0f*(*ptR * *ptR + *ptI * *ptI)/L_FFT; */ -#ifdef BASOP_NOGLOB L_tmp = L_mult_o( *ptR, *ptR, &Overflow ); /* 2*Q_new+1 */ L_tmp = L_add_o( L_tmp, L_mult_o( *ptI, *ptI, &Overflow ), &Overflow ); /* 2*Q_new+1 */ L_tmp = L_add_o( L_tmp, L_tmp, &Overflow ); /* 2*Q_new+1 */ -#else /* BASOP_NOGLOB */ - L_tmp = L_mult( *ptR, *ptR ); /* 2*Q_new+1 */ - L_tmp = L_add( L_tmp, L_mult( *ptI, *ptI ) ); /* 2*Q_new+1 */ - L_tmp = L_add( L_tmp, L_tmp ); /* 2*Q_new+1 */ -#endif /* BASOP_NOGLOB */ L_tmp = Mult_32_16( L_tmp, 128 ); /* 2*Q_new+1 */ tmp1 = add( add( Q_new, Q_new ), 1 ); env[i] = L_shr( L_tmp, sub( tmp1, 6 ) ); @@ -2050,13 +2012,23 @@ void CNG_enc_ivas_fx( /* convert log2 of residual signal energy */ /*enr = (float)log10( enr + 0.1f ) / (float)log10( 2.0f ); */ - hi = norm_l( L_ener ); - lo = Log2_norm_lc( L_shl( L_ener, hi ) ); - hi = sub( 29, hi ); /* log2 exp in Q2*Q_new */ - hi = sub( hi, shl( Q_new, 1 ) ); /* Q0 */ - L_tmp = L_Comp( hi, lo ); /* Q16 */ - enr = round_fx( L_shl( L_tmp, 8 ) ); /* Q8 (16+8-16) */ +#ifdef FIX_ISSUE_1245 + IF( L_ener == 0 ) + { + enr = -850; /*log(0.1) base 2 in Q8*/ + move16(); + } + ELSE +#endif + { + hi = norm_l( L_ener ); + lo = Log2_norm_lc( L_shl( L_ener, hi ) ); + hi = sub( 29, hi ); /* log2 exp in Q2*Q_new */ + hi = sub( hi, shl( Q_new, 1 ) ); /* Q0 */ + L_tmp = L_Comp( hi, lo ); /* Q16 */ + enr = round_fx( L_shl( L_tmp, 8 ) ); /* Q8 (16+8-16) */ + } /* update the circular buffer of old energies */ hTdCngEnc->cng_ener_hist_fx[hTdCngEnc->cng_hist_ptr] = enr; move16(); /* Q8 */ @@ -2075,11 +2047,7 @@ void CNG_enc_ivas_fx( L_tmp1 = L_add( env[i], 0 ); FOR( j = 0; j < hDtxEnc->cng_hist_size; j++ ) { -#ifdef BASOP_NOGLOB L_tmp1 = L_add_sat( L_tmp1, hTdCngEnc->cng_res_env_fx[j * NUM_ENV_CNG + i] ); -#else - L_tmp1 = L_add( L_tmp1, hTdCngEnc->cng_res_env_fx[j * NUM_ENV_CNG + i] ); -#endif } L_tmp = L_add( hTdCngEnc->cng_res_env_fx[max_idx1[0] * NUM_ENV_CNG + i], hTdCngEnc->cng_res_env_fx[max_idx1[1] * NUM_ENV_CNG + i] ); L_tmp1 = L_sub( L_tmp1, L_tmp ); @@ -2130,6 +2098,7 @@ void CNG_enc_ivas_fx( enr = round_fx( L_tmp ); /* Q8 */ } /* decrease the energy in case of WB input */ + test(); IF( EQ_16( st_fx->element_mode, IVAS_SCE ) || EQ_16( st_fx->element_mode, IVAS_CPE_DFT ) ) { enr = add( enr, mult( hTdCngEnc->CNG_att_fx, FAC_LOG2_BY10_Q16 ) ); /* Q8 (Q7 + Q16 - Q15)*/ @@ -2154,7 +2123,7 @@ void CNG_enc_ivas_fx( ELSE { att = 384; - move16(); /*Q8*/ + move16(); /*1.5f Q8*/ } enr = sub( enr, att ); } @@ -2220,6 +2189,7 @@ void CNG_enc_ivas_fx( /* substract by 2 not done to leave Energy in Q2 */ lo = L_Extract_lc( L_tmp, &hi ); hTdCngEnc->Enew_fx = Pow2( add( hi, 4 ), lo ); /* Q6 */ + move32(); IF( EQ_32( st_fx->core_brate, SID_2k40 ) ) { /* enr1 = (float)log10( st->Enew*L_frame + 0.1f ) / (float)log10( 2.0f );*/ @@ -2227,11 +2197,7 @@ void CNG_enc_ivas_fx( L_tmp = L_shl( hTdCngEnc->Enew_fx, exp ); /*Q(exp+6) */ L_tmp = Mult_32_16( L_tmp, shl( st_fx->L_frame, 5 ) ); /* Q(exp+6+5-15=exp-4) */ -#ifdef BASOP_NOGLOB L_tmp = L_shr_sat( L_tmp, sub( exp, 10 ) ); /* Q6 */ -#else - L_tmp = L_shr( L_tmp, sub( exp, 10 ) ); /* Q6 */ -#endif exp = norm_l( L_tmp ); fra = Log2_norm_lc( L_shl( L_tmp, exp ) ); @@ -2272,7 +2238,7 @@ void CNG_enc_ivas_fx( } /* codebook search */ - min1 = 1310588928; /* Q17 */ + min1 = 1310588928; /* 9999.0f Q17 */ move32(); min1_idx = 0; move16(); @@ -2285,13 +2251,9 @@ void CNG_enc_ivas_fx( /* d += (env[j] - CNG_details_codebook_fx[i][j]) * (env[j] - CNG_details_codebook_fx[i][j]);*/ L_tmp = L_sub( env[j], L_deposit_l( CNG_details_codebook_fx[i][j] ) ); /* Q6 */ exp = norm_l( L_tmp ); - L_tmp = L_shl( L_tmp, exp ); /*Q(exp+6)*/ - tmp1 = extract_h( L_tmp ); /*Q(exp+6-16)=exp-10*/ -#ifdef BASOP_NOGLOB - L_tmp = L_mult_o( tmp1, tmp1, &Overflow ); /*Q(2*exp - 19)*/ -#else /* BASOP_NOGLOB */ - L_tmp = L_mult( tmp1, tmp1 ); /*Q(2*exp - 19)*/ -#endif + L_tmp = L_shl( L_tmp, exp ); /*Q(exp+6)*/ + tmp1 = extract_h( L_tmp ); /*Q(exp+6-16)=exp-10*/ + L_tmp = L_mult_o( tmp1, tmp1, &Overflow ); /*Q(2*exp - 19)*/ L_tmp = L_shr( L_tmp, sub( add( exp, exp ), 36 ) ); /* Q17 */ d = L_add( d, L_tmp ); /* Q17 */ } @@ -2425,6 +2387,7 @@ void swb_CNG_enc_fx( ) { Word16 shb_SID_updt_fx = 0; + move16(); TD_CNG_ENC_HANDLE hTdCngEnc = st_fx->hTdCngEnc; test(); @@ -2442,14 +2405,6 @@ void swb_CNG_enc_fx( } ELSE IF( EQ_16( st_fx->element_mode, IVAS_CPE_DFT ) && EQ_32( st_fx->core_brate, SID_2k40 ) ) { - // PMT("CNG IVAS_CPE_DFT code not implemented") -#ifdef IVAS_CODE - /* LF-boost not used in DFT-stereo, instead the bandwidth is transmitted */ - delete_indice( st->hBstr, IND_CNG_ENV1 ); - push_indice( st->hBstr, IND_BWIDTH, st->bwidth, 2 ); - push_indice( st->hBstr, IND_UNUSED, 0, 4 ); - push_indice( st->hBstr, IND_SID_BW, 1, 1 ); -#endif } } hTdCngEnc->last_vad = 0; @@ -2477,9 +2432,6 @@ static void shb_CNG_encod_fx( Word16 idx_ener_fx; TD_CNG_ENC_HANDLE hTdCngEnc = st_fx->hTdCngEnc; BSTR_ENC_HANDLE hBstr = st_fx->hBstr; -#ifdef IVAS_CODE - Word16 ener_mid_dec_thr; -#endif idx_ener_fx = 0; move16(); @@ -2492,8 +2444,6 @@ static void shb_CNG_encod_fx( } ELSE { - /*idx_ener = (int16_t)(0.7f * (0.1f * st->hTdCngEnc->mov_shb_cng_ener / (float)log10(2.0f) + 6.0f) + 0.5f);*/ - // PMT("shb_CNG_encod_fx quantization in missing") } if ( LT_16( st_fx->bwidth, SWB ) ) @@ -2511,45 +2461,25 @@ static void shb_CNG_encod_fx( { idx_ener_fx = s_max( idx_ener_fx, 0 ); } -#ifdef IVAS_CODE - /* prevent toggling of idx_ener by adding small dead-zone interval around decision thresholds */ - if ( st->element_mode != EVS_MONO ) - { - if ( abs( idx_ener - st->hTdCngEnc->last_idx_ener ) == 1 ) - { - ener_mid_dec_thr = 0.5f * ( ( st->hTdCngEnc->last_idx_ener / 0.7f - 6.0f ) / 0.1f ) * (float) log10( 2.0f ); - ener_mid_dec_thr += 0.5f * ( ( idx_ener / 0.7f - 6.0f ) / 0.1f ) * (float) log10( 2.0f ); - if ( fabs( st->hTdCngEnc->mov_shb_cng_ener - ener_mid_dec_thr ) / ener_mid_dec_thr < ENER_MID_DEAD_ZONE ) - { - idx_ener = st->hTdCngEnc->last_idx_ener; - } - } - } - - st->hTdCngEnc->last_idx_ener = idx_ener; -#endif push_indice_fx( hBstr, IND_SHB_CNG_GAIN, idx_ener_fx, 4 ); push_indice_fx( hBstr, IND_SID_BW, 1, 1 ); -#ifndef IVAS_CODE hBstr->nb_bits_tot = sub( hBstr->nb_bits_tot, hBstr->ind_list[IND_CNG_ENV1].nb_bits ); hBstr->ind_list[IND_CNG_ENV1].nb_bits = -1; -#else - delete_indice( hBstr, IND_CNG_ENV1 ); -#endif move16(); -#ifdef IVAS_CODE - if ( st->element_mode == IVAS_CPE_DFT ) + move16(); + + if ( st_fx->element_mode == IVAS_CPE_DFT ) { - push_indice( st->hBstr, IND_BWIDTH, st->bwidth, 2 ); } else -#endif { push_indice_fx( hBstr, IND_UNUSED, 0, 2 ); } hTdCngEnc->ho_sid_bw = L_shl( L_and( hTdCngEnc->ho_sid_bw, (Word32) 0x3fffffffL ), 1 ); hTdCngEnc->ho_sid_bw = L_or( hTdCngEnc->ho_sid_bw, 0x1L ); + move32(); + move32(); } ELSE { @@ -2587,11 +2517,13 @@ static Word16 shb_DTX_fx( Word16 fra; Word16 att; /*Q8*/ Word16 allow_cn_step_fx = 0; + move16(); DTX_ENC_HANDLE hDtxEnc = st_fx->hDtxEnc; TD_CNG_ENC_HANDLE hTdCngEnc = st_fx->hTdCngEnc; TD_BWE_ENC_HANDLE hBWE_TD = st_fx->hBWE_TD; #ifdef BASOP_NOGLOB_DECLARE_LOCAL Flag Overflow = 0; + move32(); #endif shb_new_speech_fx = shb_old_speech_fx + ( ACELP_LOOK_12k8 + L_SUBFR ) * 5 / 4; Copy( hBWE_TD->old_speech_shb_fx, shb_old_speech_fx, ( ACELP_LOOK_12k8 + L_SUBFR ) * 5 / 4 ); @@ -2601,11 +2533,7 @@ static Word16 shb_DTX_fx( shb_ener_fx = L_deposit_l( 0 ); FOR( i = 0; i < L_FRAME16k; i++ ) { -#ifdef BASOP_NOGLOB shb_ener_fx = L_mac_sat( shb_ener_fx, shb_old_speech_fx[i], shb_old_speech_fx[i] ); -#else - shb_ener_fx = L_mac( shb_ener_fx, shb_old_speech_fx[i], shb_old_speech_fx[i] ); -#endif } shb_ener_fx = L_add( Mpy_32_16_1( shb_ener_fx, 102 ), 1 ); /* 102 in Q15, shb_ener_fx in Q1 */ @@ -2613,11 +2541,7 @@ static Word16 shb_DTX_fx( wb_ener_fx = L_deposit_l( 0 ); FOR( i = 0; i < st_fx->L_frame; i++ ) { -#ifdef BASOP_NOGLOB wb_ener_fx = L_mac_o( wb_ener_fx, syn_12k8_16k[i], syn_12k8_16k[i], &Overflow ); -#else - wb_ener_fx = L_mac( wb_ener_fx, syn_12k8_16k[i], syn_12k8_16k[i] ); -#endif } wb_ener_fx = L_add( Mpy_32_16_1( wb_ener_fx, 128 ), 1 ); /* 128 in Q15, wb_ener_fx in Q1 */ @@ -2626,11 +2550,7 @@ static Word16 shb_DTX_fx( fra = Log2_norm_lc( L_shl( wb_ener_fx, exp ) ); exp = sub( 30 - 1, exp ); wb_ener_fx = Mpy_32_16( exp, fra, LG10 ); -#ifdef BASOP_NOGLOB log_wb_ener_fx = round_fx_o( L_shl_o( wb_ener_fx, 10, &Overflow ), &Overflow ); /* log_wb_ener_fx in Q8 */ -#else - log_wb_ener_fx = round_fx( L_shl( wb_ener_fx, 10 ) ); /* log_wb_ener_fx in Q8 */ -#endif exp = norm_l( shb_ener_fx ); fra = Log2_norm_lc( L_shl( shb_ener_fx, exp ) ); exp = sub( 30 - 1, exp ); @@ -2649,11 +2569,7 @@ static Word16 shb_DTX_fx( move16(); } -#ifdef BASOP_NOGLOB log_shb_ener_fx = sub_o( round_fx_o( L_shl_o( shb_ener_fx, 10, &Overflow ), &Overflow ), att, &Overflow ); /* log_shb_ener_fx in Q8 */ -#else - log_shb_ener_fx = sub( round_fx( L_shl( shb_ener_fx, 10 ) ), att ); /* log_shb_ener_fx in Q8 */ -#endif IF( hDtxEnc->first_CNG == 0 ) { hTdCngEnc->mov_wb_cng_ener_fx = log_wb_ener_fx; @@ -2666,18 +2582,12 @@ static Word16 shb_DTX_fx( move16(); } - if ( GT_16( abs_s( sub( log_wb_ener_fx, hTdCngEnc->mov_wb_cng_ener_fx ) ), 3072 ) ) + if ( GT_16( abs_s( sub( log_wb_ener_fx, hTdCngEnc->mov_wb_cng_ener_fx ) ), 3072 /*12.0f Q8*/ ) ) { allow_cn_step_fx = 1; move16(); } -#ifdef IVAS_CODE - /* Also allow step if shb energy has dropped 12 dB */ - if ( ( st->element_mode == IVAS_CPE_DFT || st->element_mode == IVAS_CPE_TD ) && ( ( hTdCngEnc->mov_shb_cng_ener - log_shb_ener ) > 12.0f ) ) - { - allow_cn_step = 1; - } -#endif + IF( EQ_16( allow_cn_step_fx, 1 ) ) { hTdCngEnc->mov_wb_cng_ener_fx = log_wb_ener_fx; @@ -2688,15 +2598,16 @@ static Word16 shb_DTX_fx( ELSE { tmp = sub( log_wb_ener_fx, hTdCngEnc->mov_wb_cng_ener_fx ); /* Q8 */ - tmp = mult( tmp, 29491 ); /* Q8 */ + tmp = mult( tmp, 29491 /*.9f in Q15*/ ); /* Q8 */ hTdCngEnc->mov_wb_cng_ener_fx = add( hTdCngEnc->mov_wb_cng_ener_fx, tmp ); /* Q8 */ - + move16(); tmp = sub( log_shb_ener_fx, hTdCngEnc->mov_shb_cng_ener_fx ); - tmp = mult( tmp, 8192 ); /* Q8 */ + tmp = mult( tmp, 8192 /*.25f in Q15*/ ); /* Q8 */ hTdCngEnc->mov_shb_cng_ener_fx = add( hTdCngEnc->mov_shb_cng_ener_fx, tmp ); /* Q8 */ + move16(); } hTdCngEnc->shb_NO_DATA_cnt = add( hTdCngEnc->shb_NO_DATA_cnt, 1 ); - + move16(); update_fx = 0; move16(); IF( EQ_32( st_fx->core_brate, SID_2k40 ) ) @@ -2715,10 +2626,11 @@ static Word16 shb_DTX_fx( update_fx = 1; move16(); hTdCngEnc->shb_cng_ini_cnt = sub( hTdCngEnc->shb_cng_ini_cnt, 1 ); + move16(); } ELSE { - IF( GT_16( abs_s( sub( sub( hTdCngEnc->mov_wb_cng_ener_fx, hTdCngEnc->mov_shb_cng_ener_fx ), sub( hTdCngEnc->last_wb_cng_ener_fx, hTdCngEnc->last_shb_cng_ener_fx ) ) ), 768 ) ) + IF( GT_16( abs_s( sub( sub( hTdCngEnc->mov_wb_cng_ener_fx, hTdCngEnc->mov_shb_cng_ener_fx ), sub( hTdCngEnc->last_wb_cng_ener_fx, hTdCngEnc->last_shb_cng_ener_fx ) ) ), 768 /*3.0f in Q8*/ ) ) { update_fx = 1; move16(); @@ -2777,14 +2689,14 @@ static Word16 shb_DTX_fx( *---------------------------------------------------------------------*/ void calculate_hangover_attenuation_gain_fx( Encoder_State *st, /* i : encoder state structure */ - Word16 *att, /* o : attenuation factor */ + Word16 *att, /* o : attenuation factor Q15 */ const Word16 vad_hover_flag /* i : VAD hangover flag */ ) { Word16 offset; TD_CNG_ENC_HANDLE hTdCngEnc = st->hTdCngEnc; - *att = 32767; + *att = 32767; // 1.0f in Q15 move16(); /* smoothing in case of CNG */ @@ -2793,17 +2705,15 @@ void calculate_hangover_attenuation_gain_fx( test(); test(); test(); - IF( hTdCngEnc->burst_ho_cnt > 0 && ( vad_hover_flag != 0 ) && ( NE_16( st->bwidth, NB ) || GT_16( st->element_mode, EVS_MONO ) ) ) /* corresponds to line 504 in FLT acelp_core_enc.c */ + IF( hTdCngEnc->burst_ho_cnt > 0 && ( vad_hover_flag != 0 ) && ( NE_16( st->bwidth, NB ) || st->element_mode > EVS_MONO ) ) /* corresponds to line 504 in FLT acelp_core_enc.c */ { -#ifdef IVAS_CODE if ( st->element_mode == IVAS_CPE_DFT || st->element_mode == IVAS_CPE_TD ) { - *att = powf( 10.0f, ( st->hTdCngEnc->CNG_att / 160.0f ) * st->hTdCngEnc->burst_ho_cnt ); } else -#endif { offset = 5; + move16(); test(); if ( EQ_16( st->bwidth, WB ) && st->hDtxEnc->CNG_mode >= 0 ) { @@ -2811,7 +2721,7 @@ void calculate_hangover_attenuation_gain_fx( move16(); } assert( hTdCngEnc->burst_ho_cnt > 0 ); - *att = CNG_burst_att_fx[offset][sub( hTdCngEnc->burst_ho_cnt, 1 )]; /*Q15*/ + *att = CNG_burst_att_fx[offset][hTdCngEnc->burst_ho_cnt - 1]; /*Q15*/ move16(); } } @@ -2821,20 +2731,20 @@ void calculate_hangover_attenuation_gain_fx( void calculate_hangover_attenuation_gain_ivas_fx( Encoder_State *st, /* i : encoder state structure */ - Word16 *att, /* o : attenuation factor */ + Word16 *att, /* o : attenuation factor Q15 */ const Word16 vad_hover_flag /* i : VAD hangover flag */ ) { Word16 lim, result_e; - *att = 32767; + *att = 32767; // 1.0f in Q15 move16(); test(); test(); test(); test(); - IF( st->hTdCngEnc != NULL && ( vad_hover_flag != 0 ) && GT_16( st->hTdCngEnc->burst_ho_cnt, 0 ) && ( NE_16( st->bwidth, NB ) || GT_16( st->element_mode, EVS_MONO ) ) ) + IF( st->hTdCngEnc != NULL && ( vad_hover_flag != 0 ) && GT_16( st->hTdCngEnc->burst_ho_cnt, 0 ) && ( NE_16( st->bwidth, NB ) || st->element_mode > EVS_MONO ) ) { test(); IF( EQ_16( st->element_mode, IVAS_CPE_DFT ) || EQ_16( st->element_mode, IVAS_CPE_TD ) ) @@ -2872,3 +2782,375 @@ void calculate_hangover_attenuation_gain_ivas_fx( return; } + +void swb_CNG_enc_ivas_fx( + Encoder_State *st, /* i/o: State structure */ + const Word16 *shb_speech_fx, /* i : SHB target signal (6-14kHz) at 16kHz Q0 */ + const Word16 *syn_12k8_16k_fx /* i : ACELP core synthesis at 12.8kHz or 16kHz Q0 */ +) +{ + Word16 shb_SID_updt; + + test(); + IF( EQ_32( st->core_brate, SID_2k40 ) || st->core_brate == FRAME_NO_DATA ) + { + IF( st->cng_type == LP_CNG ) + { + test(); + IF( GE_32( st->input_Fs, L_FRAME32k * FRAMES_PER_SEC ) ) + { + /* decide if SHB SID encoding or not */ + shb_SID_updt = shb_DTX_ivas_fx( st, shb_speech_fx, syn_12k8_16k_fx ); + + /* SHB CNG encoding */ + shb_CNG_encod_ivas_fx( st, shb_SID_updt ); + } + ELSE IF( EQ_16( st->element_mode, IVAS_CPE_DFT ) && EQ_32( st->core_brate, SID_2k40 ) ) + { + /* LF-boost not used in DFT-stereo, instead the bandwidth is transmitted */ + delete_indice( st->hBstr, IND_CNG_ENV1 ); + push_indice( st->hBstr, IND_BWIDTH, st->bwidth, 2 ); + push_indice( st->hBstr, IND_UNUSED, 0, 4 ); + push_indice( st->hBstr, IND_SID_BW, 1, 1 ); + } + } + st->hTdCngEnc->last_vad = 0; + move16(); + } + ELSE + { + st->hTdCngEnc->last_vad = 1; + move16(); + } + + return; +} + + +/*---------------------------------------------------------------------* + * shb_CNG_encod() + * + * SID parameters encoding for SHB signal + *---------------------------------------------------------------------*/ + +static void shb_CNG_encod_ivas_fx( + Encoder_State *st, /* i/o: State structure */ + const Word16 update /* i : SID update flag */ +) +{ + Word16 idx_ener = 0; + move16(); + BSTR_ENC_HANDLE hBstr = st->hBstr; + + Word16 ener_mid_dec_thr_fx; + + IF( EQ_16( update, 1 ) ) + { + IF( st->element_mode == EVS_MONO ) + { + /* 6.0 in Q8 -> 1510 */ + /* 0.9 in Q15 29491 */ + /* ( 1 / log10(2.0) ) * 0.1 in Q15 ->10886 */ + idx_ener = shr( mult( add( mult( st->hTdCngEnc->mov_shb_cng_ener_fx, 10886 ), 1510 ), 29491 ), 8 ); /* Q0 */ + } + ELSE + { + /*idx_ener = (int16_t)(0.7f * (0.1f * st->hTdCngEnc->mov_shb_cng_ener / (float)log10(2.0f) + 6.0f) + 0.5f);*/ + // PMT("shb_CNG_encod_fx quantization in missing") + /* 6.0 in Q8 -> 1510 */ + /* 0.7 in Q15 22938 */ + /* ( 1 / log10(2.0) ) * 0.1 in Q15 -> 10886 */ + idx_ener = shr( mult( add( mult( st->hTdCngEnc->mov_shb_cng_ener_fx, 10886 ), 1510 ), 22938 ), 8 ); /* Q0 */ + } + + + if ( LT_16( st->bwidth, SWB ) ) + { + idx_ener = 0; + move16(); + } + + IF( GT_16( idx_ener, 15 ) ) + { + idx_ener = 15; + move16(); + } + ELSE IF( idx_ener < 0 ) + { + idx_ener = 0; + move16(); + } + + /* prevent toggling of idx_ener by adding small dead-zone interval around decision thresholds */ + IF( st->element_mode != EVS_MONO ) + { + IF( EQ_16( abs_s( sub( idx_ener, st->hTdCngEnc->last_idx_ener ) ), 1 ) ) + { + + Word16 tmp, tmp1, tmp2, scale, exp1, exp2, ener_mid_dec_thr_e; + tmp = BASOP_Util_Divide1616_Scale( st->hTdCngEnc->last_idx_ener, 22938, &scale ); // 0.7 in Q15 ->exp 0 + scale = add( scale, ( 15 - 0 ) ); + tmp = sub( tmp, shl( 6, sub( Q15, scale ) ) ); + tmp1 = BASOP_Util_Divide1616_Scale( tmp, 3277, &exp1 ); + exp1 = add( exp1, ( scale - 0 ) ); + + ener_mid_dec_thr_fx = shr( mult( tmp1, 9864 ), 1 ); // exp = exp + + tmp = BASOP_Util_Divide1616_Scale( idx_ener, 22938, &scale ); // 0.7 in Q15 ->exp 0 + scale = add( scale, ( 15 - 0 ) ); + tmp = sub( tmp, shl( 6, sub( Q15, scale ) ) ); + tmp1 = BASOP_Util_Divide1616_Scale( tmp, 3277, &exp2 ); + exp2 = add( exp2, ( scale - 0 ) ); + + tmp2 = shr( mult( tmp1, 9864 ), 1 ); // exp = exp + + ener_mid_dec_thr_e = BASOP_Util_Add_MantExp( tmp2, exp2, ener_mid_dec_thr_fx, exp1, &ener_mid_dec_thr_fx ); + + + scale = BASOP_Util_Add_MantExp( st->hTdCngEnc->mov_shb_cng_ener_fx, 7, negate( ener_mid_dec_thr_fx ), ener_mid_dec_thr_e, &tmp ); + tmp1 = BASOP_Util_Divide1616_Scale( tmp, ener_mid_dec_thr_fx, &exp1 ); + exp1 = add( exp1, sub( scale, ener_mid_dec_thr_e ) ); + IF( LT_16( abs_s( tmp1 ), shr( 328, sub( 15, exp1 ) ) ) ) + { + idx_ener = st->hTdCngEnc->last_idx_ener; + move16(); + } + } + } + + st->hTdCngEnc->last_idx_ener = idx_ener; + move16(); + + push_indice( hBstr, IND_SHB_CNG_GAIN, idx_ener, 4 ); + push_indice( hBstr, IND_SID_BW, 1, 1 ); + delete_indice( hBstr, IND_CNG_ENV1 ); + IF( EQ_16( st->element_mode, IVAS_CPE_DFT ) ) + { + push_indice( st->hBstr, IND_BWIDTH, st->bwidth, 2 ); + } + ELSE + { + push_indice( hBstr, IND_UNUSED, 0, 2 ); + } + st->hTdCngEnc->ho_sid_bw = L_shl( L_and( st->hTdCngEnc->ho_sid_bw, (Word32) 0x3fffffffL ), 1 ); + st->hTdCngEnc->ho_sid_bw = L_or( st->hTdCngEnc->ho_sid_bw, 0x1L ); + move32(); + move32(); + } + ELSE IF( EQ_32( st->core_brate, SID_2k40 ) ) + { + st->hTdCngEnc->ho_sid_bw = L_shl( L_and( st->hTdCngEnc->ho_sid_bw, (Word32) 0x3fffffffL ), 1 ); + move32(); + push_indice( hBstr, IND_SID_BW, 0, 1 ); + } + + return; +} + +/*---------------------------------------------------------------------* + * shb_DTX() + * + * Decide if encoding SHB SID or not + *---------------------------------------------------------------------*/ + +static Word16 shb_DTX_ivas_fx( + Encoder_State *st, /* i/o: State structure */ + const Word16 *shb_speech_fx, /* i : SHB target signal (6-14kHz) at 16kHz Q0 */ + const Word16 *syn_12k8_16k_fx /* i : ACELP core synthesis at 12.8kHz or 16kHz Q0 */ +) +{ + Word16 i; + Word16 update; + + Word16 allow_cn_step = 0; + move16(); + Word16 shb_old_speech_fx[( ACELP_LOOK_12k8 + L_SUBFR + L_FRAME ) * 5 / 4]; + Word16 *shb_new_speech_fx; + Word32 wb_ener_fx; + Word32 shb_ener_fx; + Word16 log_wb_ener_fx; + Word16 log_shb_ener_fx; + Word16 tmp; + Word16 exp; + Word16 fra; + Word16 att_fx; /*Q8*/ + + TD_CNG_ENC_HANDLE hTdCngEnc = st->hTdCngEnc; + TD_BWE_ENC_HANDLE hBWE_TD = st->hBWE_TD; + + +#ifdef BASOP_NOGLOB_DECLARE_LOCAL + Flag Overflow = 0; + move16(); +#endif + + shb_new_speech_fx = shb_old_speech_fx + ( ACELP_LOOK_12k8 + L_SUBFR ) * 5 / 4; + Copy( hBWE_TD->old_speech_shb_fx, shb_old_speech_fx, ( ACELP_LOOK_12k8 + L_SUBFR ) * 5 / 4 ); // old_speech_shb_fx -> Q0 + Copy( shb_speech_fx, shb_new_speech_fx, L_FRAME16k ); // Q0 + Copy( shb_old_speech_fx + L_FRAME16k, hBWE_TD->old_speech_shb_fx, ( ACELP_LOOK_12k8 + L_SUBFR ) * 5 / 4 ); // Q0 + + shb_ener_fx = L_deposit_l( 0 ); + FOR( i = 0; i < L_FRAME16k; i++ ) + { + shb_ener_fx = L_mac_sat( shb_ener_fx, shb_old_speech_fx[i], shb_old_speech_fx[i] ); // ( Q0 + Q0 + Q1 ) --> Q1 due to left shift in L_mac + } + + shb_ener_fx = L_add( Mpy_32_16_1( shb_ener_fx, 102 ), 1 ); /* ( 1 / L_FRAME16K ) -> 102 in Q15, shb_ener_fx in Q1 */ + + wb_ener_fx = L_deposit_l( 0 ); + FOR( i = 0; i < st->L_frame; i++ ) + { + wb_ener_fx = L_mac_o( wb_ener_fx, syn_12k8_16k_fx[i], syn_12k8_16k_fx[i], &Overflow ); // ( Q0 + Q0 + Q1 ) --> Q1 due to left shift in L_mac + } + + wb_ener_fx = L_add( Mpy_32_16_1( wb_ener_fx, 128 ), 1 ); /* 128 in Q15, wb_ener_fx in Q1 */ + + exp = norm_l( wb_ener_fx ); + fra = Log2_norm_lc( L_shl( wb_ener_fx, exp ) ); + exp = sub( 30 - 1, exp ); + wb_ener_fx = Mpy_32_16( exp, fra, LG10 ); + + log_wb_ener_fx = round_fx_o( L_shl_o( wb_ener_fx, 10, &Overflow ), &Overflow ); /* log_wb_ener_fx in Q8 */ + exp = norm_l( shb_ener_fx ); + fra = Log2_norm_lc( L_shl( shb_ener_fx, exp ) ); + exp = sub( 30 - 1, exp ); + shb_ener_fx = Mpy_32_16( exp, fra, LG10 ); + + + test(); + IF( EQ_16( st->element_mode, IVAS_SCE ) || EQ_16( st->element_mode, IVAS_CPE_DFT ) ) + { + Word32 att_fx32 = 0; + move32(); + Word16 index; + + apply_scale_ivas_fx( &att_fx32, st->hFdCngEnc->hFdCngCom->CngBandwidth, st->hFdCngEnc->hFdCngCom->CngBitrate, scaleTableStereo, SIZE_SCALE_TABLE_STEREO, &index ); // Q23; + + att_fx = extract_l( L_shr( att_fx32, 15 ) ); // Q8 + } + ELSE + { + att_fx = -1664; // Q8 + move16(); + } + + + log_shb_ener_fx = sub_o( round_fx_o( L_shl_o( shb_ener_fx, 10, &Overflow ), &Overflow ), att_fx, &Overflow ); /* log_shb_ener_fx in Q8 */ + + IF( st->hDtxEnc->first_CNG == 0 ) + { + + + hTdCngEnc->mov_wb_cng_ener_fx = log_wb_ener_fx; // Q8 + hTdCngEnc->mov_shb_cng_ener_fx = log_shb_ener_fx; // Q8 + hTdCngEnc->last_wb_cng_ener_fx = log_wb_ener_fx; // Q8 + hTdCngEnc->last_shb_cng_ener_fx = log_shb_ener_fx; // Q8 + move16(); + move16(); + move16(); + move16(); + } + IF( GT_16( abs_s( sub( log_wb_ener_fx, hTdCngEnc->mov_wb_cng_ener_fx ) ), 3072 /*12 in Q8*/ ) ) + { + allow_cn_step = 1; + move16(); + } + + /* Also allow step if shb energy has dropped 12 dB */ + test(); + test(); + IF( ( EQ_16( st->element_mode, IVAS_CPE_DFT ) || EQ_16( st->element_mode, IVAS_CPE_TD ) ) && GT_16( sub( hTdCngEnc->mov_shb_cng_ener_fx, log_shb_ener_fx ), 3072 /*12 in Q8*/ ) ) + { + allow_cn_step = 1; + move16(); + } + + IF( EQ_16( allow_cn_step, 1 ) ) + { + hTdCngEnc->mov_wb_cng_ener_fx = log_wb_ener_fx; + hTdCngEnc->mov_shb_cng_ener_fx = log_shb_ener_fx; + move16(); + move16(); + } + ELSE + { + tmp = sub( log_wb_ener_fx, hTdCngEnc->mov_wb_cng_ener_fx ); /* Q8 */ + tmp = mult( tmp, 29491 /* .9f in Q15*/ ); /* Q8 */ + hTdCngEnc->mov_wb_cng_ener_fx = add( hTdCngEnc->mov_wb_cng_ener_fx, tmp ); /* Q8 */ + move16(); + + tmp = sub( log_shb_ener_fx, hTdCngEnc->mov_shb_cng_ener_fx ); + tmp = mult( tmp, 8192 /* .25f in Q15*/ ); /* Q8 */ + hTdCngEnc->mov_shb_cng_ener_fx = add( hTdCngEnc->mov_shb_cng_ener_fx, tmp ); /* Q8 */ + move16(); + } + + hTdCngEnc->shb_NO_DATA_cnt = add( hTdCngEnc->shb_NO_DATA_cnt, 1 ); + update = 0; + + move16(); + move16(); + + IF( EQ_32( st->core_brate, SID_2k40 ) ) + { + test(); + test(); + test(); + IF( st->hDtxEnc->first_CNG == 0 ) + { + update = 1; + move16(); + } + ELSE IF( hTdCngEnc->shb_cng_ini_cnt > 0 ) + { + hTdCngEnc->shb_cng_ini_cnt = sub( hTdCngEnc->shb_cng_ini_cnt, 1 ); + update = 1; + move16(); + move16(); + } + ELSE IF( EQ_16( hTdCngEnc->last_vad, 1 ) ) + { + update = 1; + move16(); + } + ELSE IF( GE_16( hTdCngEnc->shb_NO_DATA_cnt, 100 ) ) + { + update = 1; + move16(); + } + ELSE IF( GT_16( abs_s( sub( sub( hTdCngEnc->mov_wb_cng_ener_fx, hTdCngEnc->mov_shb_cng_ener_fx ), sub( hTdCngEnc->last_wb_cng_ener_fx, hTdCngEnc->last_shb_cng_ener_fx ) ) ), 768 ) ) + { + update = 1; + move16(); + } + ELSE IF( ( GE_16( st->bwidth, SWB ) && LT_16( hTdCngEnc->last_SID_bwidth, SWB ) ) || ( LT_16( st->bwidth, SWB ) && GE_16( hTdCngEnc->last_SID_bwidth, SWB ) ) ) + { + update = 1; + move16(); + } + + hTdCngEnc->last_SID_bwidth = st->bwidth; + move16(); + } + + /* LF-boost not yet implemented in decoder which means that the specific wb_sid information is not used */ + test(); + test(); + if ( ( EQ_16( st->element_mode, IVAS_CPE_DFT ) || EQ_16( st->element_mode, IVAS_CPE_TD ) ) && EQ_32( st->core_brate, SID_2k40 ) ) + { + update = 1; + move16(); + } + + IF( EQ_16( update, 1 ) ) + { + hTdCngEnc->last_wb_cng_ener_fx = hTdCngEnc->mov_wb_cng_ener_fx; + hTdCngEnc->last_shb_cng_ener_fx = hTdCngEnc->mov_shb_cng_ener_fx; + hTdCngEnc->shb_NO_DATA_cnt = 0; + move16(); + move16(); + move16(); + } + + return ( update ); +} diff --git a/lib_enc/cod2t32.c b/lib_enc/cod2t32.c deleted file mode 100644 index e7a8ca967132cf8896fc4a231dbaf74eed596840..0000000000000000000000000000000000000000 --- a/lib_enc/cod2t32.c +++ /dev/null @@ -1,41 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include "cnst.h" -#include "prot.h" -#include "wmc_auto.h" diff --git a/lib_enc/cod2t32_fx.c b/lib_enc/cod2t32_fx.c index d933989970e0a6297977d86702570cf5eb5a6442..a948a4656c7154b56e7af98b6e3fae967d5e5ec2 100644 --- a/lib_enc/cod2t32_fx.c +++ b/lib_enc/cod2t32_fx.c @@ -5,7 +5,6 @@ #include "options.h" /* Compilation switches */ #include "cnst.h" /* Common constants */ #include "rom_com.h" /* Common constants */ -#include "prot.h" /* Function prototypes */ #include "prot_fx.h" /* Function prototypes */ #include "prot_fx_enc.h" /* Function prototypes */ @@ -30,10 +29,10 @@ void acelp_2t32_fx( BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ - const Word16 dn[], /* i : corr. between target and h[]. */ - const Word16 h[], /* i : impulse response of weighted synthesis filter */ - Word16 code[], /* o : algebraic (fixed) codebook excitation */ - Word16 y[] /* o : filtered fixed codebook excitation */ + const Word16 dn[], /* i : corr. between target and h[]. Qx*/ + const Word16 h[], /* i : impulse response of weighted synthesis filter Q12*/ + Word16 code[], /* o : algebraic (fixed) codebook excitation Q9*/ + Word16 y[] /* o : filtered fixed codebook excitation Q9*/ ) { Word16 i, j, k, i0, i1, ix, iy, pos, pos2, sign0, sign1, index; @@ -50,6 +49,7 @@ void acelp_2t32_fx( Word16 rrixiy[MSIZE]; #ifdef BASOP_NOGLOB_DECLARE_LOCAL Flag Overflow = 0; + move32(); #endif /*----------------------------------------------------------------* * Compute rrixix[][] needed for the codebook search. @@ -57,37 +57,24 @@ void acelp_2t32_fx( /* Init pointers to last position of rrixix[] */ p0 = &rrixix[0][NB_POS_FCB_2T - 1]; - move16(); p1 = &rrixix[1][NB_POS_FCB_2T - 1]; - move16(); ptr_h1 = h; - move16(); L_cor = L_deposit_h( 1 ); FOR( i = 0; i < NB_POS_FCB_2T; i++ ) { -#ifdef BASOP_NOGLOB L_cor = L_mac_o( L_cor, *ptr_h1, *ptr_h1, &Overflow ); -#else - L_cor = L_mac( L_cor, *ptr_h1, *ptr_h1 ); -#endif ptr_h1++; *p1-- = extract_h( L_cor ); move16(); /*Q9 Q7*/ -#ifdef BASOP_NOGLOB L_cor = L_mac_o( L_cor, *ptr_h1, *ptr_h1, &Overflow ); -#else - L_cor = L_mac( L_cor, *ptr_h1, *ptr_h1 ); -#endif ptr_h1++; *p0-- = extract_h( L_cor ); move16(); /*Q9 Q7*/ } p0 = rrixix[0]; - move16(); p1 = rrixix[1]; - move16(); FOR( i = 0; i < NB_POS_FCB_2T; i++ ) { @@ -108,54 +95,34 @@ void acelp_2t32_fx( pos2 = MSIZE - 2; move16(); ptr_hf = h + 1; - move16(); FOR( k = 0; k < NB_POS_FCB_2T; k++ ) { /* Init pointers to last position of diagonals */ p1 = &rrixiy[pos]; - move16(); p0 = &rrixiy[pos2]; - move16(); ptr_h1 = h; - move16(); ptr_h2 = ptr_hf; - move16(); - L_cor = L_mult( *ptr_h1++, *ptr_h2++ ); + L_cor = L_mult( *ptr_h1++, *ptr_h2++ ); // Q(12+12+1) FOR( i = k; i < NB_POS_FCB_2T - 1; i++ ) { -#ifdef BASOP_NOGLOB - *p1 = round_fx_o( L_cor, &Overflow ); + *p1 = round_fx_o( L_cor, &Overflow ); // Q(25-16) L_cor = L_mac_o( L_cor, *ptr_h1++, *ptr_h2++, &Overflow ); -#else - *p1 = round_fx( L_cor ); - L_cor = L_mac( L_cor, *ptr_h1++, *ptr_h2++ ); -#endif -#ifdef BASOP_NOGLOB - *p0 = round_fx_o( L_cor, &Overflow ); + *p0 = round_fx_o( L_cor, &Overflow ); // Q(9) L_cor = L_mac_o( L_cor, *ptr_h1++, *ptr_h2++, &Overflow ); -#else - *p0 = round_fx( L_cor ); - L_cor = L_mac( L_cor, *ptr_h1++, *ptr_h2++ ); -#endif - p1 -= ( NB_POS_FCB_2T + 1 ); move16(); - p0 -= ( NB_POS_FCB_2T + 1 ); move16(); + p1 -= ( NB_POS_FCB_2T + 1 ); + p0 -= ( NB_POS_FCB_2T + 1 ); } -#ifdef BASOP_NOGLOB - *p1 = round_fx_o( L_cor, &Overflow ); -#else - *p1 = round_fx( L_cor ); -#endif + *p1 = round_fx_o( L_cor, &Overflow ); // Q9 pos -= NB_POS_FCB_2T; move16(); pos2--; ptr_hf += STEP; - move16(); } /*----------------------------------------------------------------* @@ -168,18 +135,18 @@ void acelp_2t32_fx( /* FIR high-pass filtering */ IF( i == 0 ) { - L_tmp = L_msu( L_tmp, dn[1], 11469 ); + L_tmp = L_msu( L_tmp, dn[1], 11469 /*.3f Q15*/ ); } ELSE IF( EQ_16( i, L_SUBFR - 1 ) ) { L_tmp = L_deposit_h( dn[i] ); - L_tmp = L_msu( L_tmp, dn[i - 1], 11469 ); + L_tmp = L_msu( L_tmp, dn[i - 1], 11469 /*.3f Q15*/ ); } ELSE { L_tmp = L_deposit_h( dn[i] ); - L_tmp = L_msu( L_tmp, dn[i - 1], 11469 ); - L_tmp = L_msu( L_tmp, dn[i + 1], 11469 ); + L_tmp = L_msu( L_tmp, dn[i - 1], 11469 /*.3f Q15*/ ); + L_tmp = L_msu( L_tmp, dn[i + 1], 11469 /*.3f Q15*/ ); } /* pre-selection of polarities */ @@ -232,11 +199,8 @@ void acelp_2t32_fx( *----------------------------------------------------------------*/ p0 = rrixix[0]; - move16(); p1 = rrixix[1]; - move16(); p2 = rrixiy; - move16(); psk = -1; move16(); alpk = 1; @@ -257,17 +221,9 @@ void acelp_2t32_fx( FOR( i1 = 1; i1 < L_SUBFR; i1 += STEP ) { ps2 = add( ps1, dn_p[i1] ); -#ifdef BASOP_NOGLOB alp2 = add_o( alp1, add_o( *p1++, *p2++, &Overflow ), &Overflow ); -#else - alp2 = add( alp1, add( *p1++, *p2++ ) ); -#endif sq = mult( ps2, ps2 ); -#ifdef BASOP_NOGLOB s = L_msu_o( L_mult( alpk, sq ), psk, alp2, &Overflow ); -#else - s = L_msu( L_mult( alpk, sq ), psk, alp2 ); -#endif IF( s > 0 ) { psk = sq; @@ -279,7 +235,6 @@ void acelp_2t32_fx( } } p1 -= NB_POS_FCB_2T; - move16(); IF( pos >= 0 ) { @@ -293,8 +248,8 @@ void acelp_2t32_fx( i0 = shr( ix, 1 ); i1 = shr( iy, 1 ); - sign0 = shl( pol[ix], 9 ); - sign1 = shl( pol[iy], 9 ); + sign0 = shl( pol[ix], 9 ); // Q9 + sign1 = shl( pol[iy], 9 ); // Q9 /*-------------------------------------------------------------------* * Build the codeword, the filtered codeword and index of codevector. @@ -327,12 +282,13 @@ void acelp_2t32_fx( FOR( i = ix; i < L_SUBFR; i++ ) { - y[i] = mult_r( sign0, h[i - ix] ); + y[i] = mult_r( sign0, h[i - ix] ); // Q9 move16(); } FOR( i = iy; i < L_SUBFR; i++ ) { - y[i] = round_fx( L_mac( L_deposit_h( y[i] ), sign1, h[i - iy] ) ); + y[i] = round_fx( L_mac( L_deposit_h( y[i] ), sign1, h[i - iy] ) ); // Q9 + move16(); } { /* write index to array of indices */ @@ -343,10 +299,10 @@ void acelp_2t32_fx( void acelp_2t32_ivas_fx( BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ - const Word16 dn[], /* i : corr. between target and h[]. */ - const Word16 h[], /* i : impulse response of weighted synthesis filter */ - Word16 code[], /* o : algebraic (fixed) codebook excitation */ - Word16 y[] /* o : filtered fixed codebook excitation */ + const Word16 dn[], /* i : corr. between target and h[]. Qx*/ + const Word16 h[], /* i : impulse response of weighted synthesis filter Q12*/ + Word16 code[], /* o : algebraic (fixed) codebook excitation Q9 */ + Word16 y[] /* o : filtered fixed codebook excitation Q9 */ ) { Word16 i, j, k, i0, i1, ix, iy, pos, pos2, sign0, sign1, index; @@ -371,37 +327,25 @@ void acelp_2t32_ivas_fx( /* Init pointers to last position of rrixix[] */ p0 = &rrixix[0][NB_POS_FCB_2T - 1]; - move16(); p1 = &rrixix[1][NB_POS_FCB_2T - 1]; - move16(); ptr_h1 = h; move16(); L_cor = L_deposit_h( 1 ); FOR( i = 0; i < NB_POS_FCB_2T; i++ ) { -#ifdef BASOP_NOGLOB L_cor = L_mac_o( L_cor, *ptr_h1, *ptr_h1, &Overflow ); -#else - L_cor = L_mac( L_cor, *ptr_h1, *ptr_h1 ); -#endif ptr_h1++; *p1-- = extract_h( L_cor ); move16(); /*Q9 Q7*/ -#ifdef BASOP_NOGLOB L_cor = L_mac_o( L_cor, *ptr_h1, *ptr_h1, &Overflow ); -#else - L_cor = L_mac( L_cor, *ptr_h1, *ptr_h1 ); -#endif ptr_h1++; *p0-- = extract_h( L_cor ); move16(); /*Q9 Q7*/ } p0 = rrixix[0]; - move16(); p1 = rrixix[1]; - move16(); FOR( i = 0; i < NB_POS_FCB_2T; i++ ) { @@ -422,52 +366,33 @@ void acelp_2t32_ivas_fx( pos2 = MSIZE - 2; move16(); ptr_hf = h + 1; - move16(); FOR( k = 0; k < NB_POS_FCB_2T; k++ ) { /* Init pointers to last position of diagonals */ p1 = &rrixiy[pos]; - move16(); p0 = &rrixiy[pos2]; - move16(); ptr_h1 = h; - move16(); ptr_h2 = ptr_hf; - move16(); - L_cor = L_mult( *ptr_h1++, *ptr_h2++ ); + L_cor = L_mult( *ptr_h1++, *ptr_h2++ ); // Q25 FOR( i = k; i < NB_POS_FCB_2T - 1; i++ ) { -#ifdef BASOP_NOGLOB - *p1 = round_fx_o( L_cor, &Overflow ); + *p1 = round_fx_o( L_cor, &Overflow ); // Q9 L_cor = L_mac_o( L_cor, *ptr_h1++, *ptr_h2++, &Overflow ); -#else - *p1 = round_fx( L_cor ); - L_cor = L_mac( L_cor, *ptr_h1++, *ptr_h2++ ); -#endif -#ifdef BASOP_NOGLOB - *p0 = round_fx_o( L_cor, &Overflow ); + *p0 = round_fx_o( L_cor, &Overflow ); // Q9 L_cor = L_mac_o( L_cor, *ptr_h1++, *ptr_h2++, &Overflow ); -#else - *p0 = round_fx( L_cor ); - L_cor = L_mac( L_cor, *ptr_h1++, *ptr_h2++ ); -#endif - p1 -= ( NB_POS_FCB_2T + 1 ); move16(); - p0 -= ( NB_POS_FCB_2T + 1 ); move16(); + p1 -= ( NB_POS_FCB_2T + 1 ); + p0 -= ( NB_POS_FCB_2T + 1 ); } -#ifdef BASOP_NOGLOB *p1 = round_fx_o( L_cor, &Overflow ); -#else - *p1 = round_fx( L_cor ); -#endif pos -= NB_POS_FCB_2T; move16(); - pos2--; + pos2 = sub( pos2, 1 ); ptr_hf += STEP; move16(); } @@ -482,18 +407,18 @@ void acelp_2t32_ivas_fx( /* FIR high-pass filtering */ IF( i == 0 ) { - L_tmp = L_msu( L_tmp, dn[1], 11469 ); + L_tmp = L_msu( L_tmp, dn[1], 11469 /*.3f Q15*/ ); } ELSE IF( EQ_16( i, L_SUBFR - 1 ) ) { L_tmp = L_deposit_h( dn[i] ); - L_tmp = L_msu( L_tmp, dn[i - 1], 11469 ); + L_tmp = L_msu( L_tmp, dn[i - 1], 11469 /*.3f Q15*/ ); } ELSE { L_tmp = L_deposit_h( dn[i] ); - L_tmp = L_msu( L_tmp, dn[i - 1], 11469 ); - L_tmp = L_msu( L_tmp, dn[i + 1], 11469 ); + L_tmp = L_msu( L_tmp, dn[i - 1], 11469 /*.3f Q15*/ ); + L_tmp = L_msu( L_tmp, dn[i + 1], 11469 /*.3f Q15*/ ); } /* pre-selection of polarities */ @@ -546,11 +471,8 @@ void acelp_2t32_ivas_fx( *----------------------------------------------------------------*/ p0 = rrixix[0]; - move16(); p1 = rrixix[1]; - move16(); p2 = rrixiy; - move16(); psk = -1; move16(); alpk = 1; @@ -571,17 +493,9 @@ void acelp_2t32_ivas_fx( FOR( i1 = 1; i1 < L_SUBFR; i1 += STEP ) { ps2 = add( ps1, dn_p[i1] ); -#ifdef BASOP_NOGLOB alp2 = add_o( alp1, add_o( *p1++, *p2++, &Overflow ), &Overflow ); -#else - alp2 = add( alp1, add( *p1++, *p2++ ) ); -#endif sq = mult( ps2, ps2 ); -#ifdef BASOP_NOGLOB s = L_msu_o( L_mult( alpk, sq ), psk, alp2, &Overflow ); -#else - s = L_msu( L_mult( alpk, sq ), psk, alp2 ); -#endif IF( s > 0 ) { psk = sq; @@ -593,7 +507,6 @@ void acelp_2t32_ivas_fx( } } p1 -= NB_POS_FCB_2T; - move16(); IF( pos >= 0 ) { @@ -607,8 +520,8 @@ void acelp_2t32_ivas_fx( i0 = shr( ix, 1 ); i1 = shr( iy, 1 ); - sign0 = shl( pol[ix], 9 ); - sign1 = shl( pol[iy], 9 ); + sign0 = shl( pol[ix], 9 ); // Q9 + sign1 = shl( pol[iy], 9 ); // Q9 /*-------------------------------------------------------------------* * Build the codeword, the filtered codeword and index of codevector. @@ -641,12 +554,13 @@ void acelp_2t32_ivas_fx( FOR( i = ix; i < L_SUBFR; i++ ) { - y[i] = mult_r( sign0, h[i - ix] ); + y[i] = mult_r( sign0, h[i - ix] ); // Q9 move16(); } FOR( i = iy; i < L_SUBFR; i++ ) { - y[i] = round_fx( L_mac( L_deposit_h( y[i] ), sign1, h[i - iy] ) ); + y[i] = round_fx( L_mac( L_deposit_h( y[i] ), sign1, h[i - iy] ) ); // Q9 + move16(); } { /* write index to array of indices */ @@ -665,10 +579,10 @@ void acelp_2t32_ivas_fx( void acelp_1t64_fx( BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ - const Word16 dn[], /* i : corr. between target and h[]. */ - const Word16 h[], /* i : impulse response of weighted synthesis filter */ - Word16 code[], /* o : algebraic (fixed) codebook excitation */ - Word16 y[], /* o : filtered fixed codebook excitation */ + const Word16 dn[], /* i : corr. between target and h[]. Qx*/ + const Word16 h[], /* i : impulse response of weighted synthesis filter Q12 */ + Word16 code[], /* o : algebraic (fixed) codebook excitation Q9 */ + Word16 y[], /* o : filtered fixed codebook excitation Q9 */ const Word16 L_subfr /* i : subframe length */ ) { @@ -681,12 +595,12 @@ void acelp_1t64_fx( IF( dn[pos] < 0 ) { - sgn = -512; + sgn = -512; //-1 in Q9 move16(); } ELSE { - sgn = 512; + sgn = 512; // 1 in Q9 move16(); } @@ -704,12 +618,12 @@ void acelp_1t64_fx( { IF( sgn > 0 ) { - y[i] = shr_r( h[i - pos], 3 ); + y[i] = shr_r( h[i - pos], 3 ); // Q9 move16(); } ELSE { - y[i] = negate( shr_r( h[i - pos], 3 ) ); + y[i] = negate( shr_r( h[i - pos], 3 ) ); // Q9 move16(); } } @@ -734,10 +648,10 @@ void acelp_1t64_fx( void acelp_1t64_ivas_fx( BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ - const Word16 dn[], /* i : corr. between target and h[]. */ - const Word16 h[], /* i : impulse response of weighted synthesis filter */ - Word16 code[], /* o : algebraic (fixed) codebook excitation */ - Word16 y[], /* o : filtered fixed codebook excitation */ + const Word16 dn[], /* i : corr. between target and h[]. Qx */ + const Word16 h[], /* i : impulse response of weighted synthesis filter Q12*/ + Word16 code[], /* o : algebraic (fixed) codebook excitation Q9*/ + Word16 y[], /* o : filtered fixed codebook excitation Q9*/ const Word16 L_subfr /* i : subframe length */ ) { @@ -773,12 +687,12 @@ void acelp_1t64_ivas_fx( { IF( sgn > 0 ) { - y[i] = shr_r( h[i - pos], 3 ); + y[i] = shr_r( h[i - pos], 3 ); // Q9 move16(); } ELSE { - y[i] = negate( shr_r( h[i - pos], 3 ) ); + y[i] = negate( shr_r( h[i - pos], 3 ) ); // Q9 move16(); } } diff --git a/lib_enc/cod4t64.c b/lib_enc/cod4t64.c deleted file mode 100644 index b4081d00ffcfc5033234c111840eb5e62b62aa26..0000000000000000000000000000000000000000 --- a/lib_enc/cod4t64.c +++ /dev/null @@ -1,48 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include -#include "cnst.h" -#include "rom_enc.h" -#include "prot.h" -#include "rom_com.h" -#include "wmc_auto.h" - -/*---------------------------------------------------------------------* - * Local function prototypes - *---------------------------------------------------------------------*/ diff --git a/lib_enc/cod4t64_fast.c b/lib_enc/cod4t64_fast.c index e40766bec0d6a18fcb61125176bcca1bc8dc3002..0e4c02744823c9718cfae159a01f6aaf362ff25a 100644 --- a/lib_enc/cod4t64_fast.c +++ b/lib_enc/cod4t64_fast.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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,9 +34,7 @@ #include "options.h" #include #include "cnst.h" -#include "prot.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "ivas_prot_fx.h" #include "rom_com.h" #include "wmc_auto.h" @@ -60,7 +58,7 @@ *---------------------------------------------------------------------*/ /*! r: return index (N+1 bits) */ -static Word16 quant_1p_N1_L_subfr( +static Word16 quant_1p_N1_L_subfr_fx( const Word16 nb_pos, /* i : number of positions */ const Word16 pos, /* i : position of the pulse */ const Word16 N /* i : number of bits for position */ @@ -72,7 +70,7 @@ static Word16 quant_1p_N1_L_subfr( index = s_and( pos, mask ); - if ( s_and( pos, nb_pos ) != 0 ) + IF( s_and( pos, nb_pos ) != 0 ) { index = add( index, shl( 1, N ) ); } @@ -83,14 +81,15 @@ static Word16 find_best_pulse_fx( const Word16 L_subfr, const Word16 nb_tracks, const Word16 track, - const Word32 dn[], - const Word16 sign[], - Word16 *s ) + const Word32 dn[], // Qx + const Word16 sign[], // Q0 + Word16 *s // Q0 +) { Word16 m, i; Word32 temp, max_val; - max_val = MIN_32; + max_val = EPSILLON_FX; move32(); m = track; move16(); @@ -370,7 +369,7 @@ void acelp_fast_fx( { h[i] = H[i]; move16(); - h_inv[i] = -H[i]; + h_inv[i] = negate( H[i] ); move16(); } @@ -594,7 +593,7 @@ void acelp_fast_fx( move16(); s64 = 0; - + move64(); FOR( i = track; i < L_subfr; i += nb_tracks ) { dn[i] = L_shr( L_msu( L_mult0( Gd, dn_orig[i] ), G, *alp_pos0 ), 6 ); // Q_dn @@ -606,11 +605,18 @@ void acelp_fast_fx( dndn_fx = W_extract_h( W_shl( s64, exp1 ) ); // 2 * Q_dyn + exp1 - 31 dndn_e = sub( 31, sub( add( shl( Q_dn, 1 ), exp ), 31 ) ); + IF( dndn_fx == 0 ) + { + dndn_fx = 214748365 /* 0.1f in Q31 */; + move32(); + dndn_e = 0; + move16(); + } s_coef_fx = BASOP_Util_Divide3232_Scale( dndn_fx, cncn_track[track], &exp1 ); exp1 = add( exp1, sub( dndn_e, cncn_track_e[track] ) ); s_coef_fx = Sqrt16( s_coef_fx, &exp1 ); exp1 = sub( exp1, shift ); - max_val_fx = MIN_16; + max_val_fx = EPSILLON_FX; move16(); m[1] = track; // Q0 move16(); @@ -641,6 +647,7 @@ void acelp_fast_fx( { Gn = add( Gn, i_mult( s[1], shr( dn_orig[m[1]], 1 ) ) ); // Q_dn -1 Gd32 = Gd; + move16(); Gd32 = L_add( Gd32, L_add( alp[0], L_mult0( i_mult( shl( s[0], 1 ), s[1] ), alp[m[0] - m[1]] ) ) ); // Q6 G = Gn; // Q_dn - 1 move16(); @@ -672,6 +679,7 @@ void acelp_fast_fx( { Gn = add( Gn, i_mult( s[2], shr( dn_orig[m[2]], 1 ) ) ); // Q_dn-1 Gd32 = Gd; + move16(); Gd32 = L_add( Gd32, L_add( L_add( alp[0], L_mult0( i_mult( shl( s[0], 1 ), s[2] ), alp[m[0] - m[2]] ) ), L_mult0( i_mult( shl( s[1], 1 ), s[2] ), alp[m[1] - m[2]] ) ) ); // Q6 G = Gn; // Q_dn-1 move16(); @@ -711,12 +719,14 @@ void acelp_fast_fx( { Gn = add( Gn, i_mult( s[3], shr( dn_orig[m[3]], 1 ) ) ); // Q_dn-1 Gd32 = Gd; + move16(); Gd32 = L_add( Gd32, L_add( L_add( L_add( alp[0], L_mult0( i_mult( shl( s[0], 1 ), s[3] ), alp[m[0] - m[3]] ) ), L_mult0( i_mult( shl( s[1], 1 ), s[3] ), alp[m[1] - m[3]] ) ), L_mult0( i_mult( shl( s[2], 1 ), s[3] ), alp[m[2] - m[3]] ) ) ); // Q6 - G = Gn; // Q_dn-1 - G1 = i_mult( G, s[1] ); // Q_dn-1 - G2 = i_mult( G, s[2] ); // Q_dn-1 - G3 = i_mult( G, s[3] ); // Q_dn-1 - G = i_mult( G, s[0] ); // Q_dn-1 + G = Gn; + move16(); // Q_dn-1 + G1 = i_mult( G, s[1] ); // Q_dn-1 + G2 = i_mult( G, s[2] ); // Q_dn-1 + G3 = i_mult( G, s[3] ); // Q_dn-1 + G = i_mult( G, s[0] ); // Q_dn-1 IF( EQ_16( cdk_index, 6 ) ) { @@ -758,7 +768,30 @@ void acelp_fast_fx( alp_pos3++; } - i = emaximum_32fx( Q_dn, dn, L_subfr, &L_tmp1 ); + Word16 k; + Word64 W_tmp, W_tmp1; + Word64 emax; + + emax = W_mult0_32_32( dn[0], dn[0] ); + i = 0; + move16(); + + FOR( k = 1; k < L_subfr; k++ ) + { + W_tmp = W_mult0_32_32( dn[k], dn[k] ); + W_tmp1 = W_sub( W_tmp, emax ); + if ( W_tmp1 > 0 ) + { + i = k; + move16(); + } + if ( LE_64( emax, W_tmp ) ) + { + emax = W_tmp; + move64(); + } + } + track = i % nb_tracks; move16(); @@ -814,9 +847,9 @@ void acelp_fast_fx( crit_den = W_extract_h( W_shl( s64, exp1 ) ); // 2*q_H + exp1 - 32 q_crit_den = add( shl( q_H, 1 ), sub( exp1, 32 ) ); - L_tmp1 = Mpy_32_32( crit_num, crit_den_max ); + L_tmp1 = Mpy_32_32( crit_num, crit_den_max ); // q_crit_num+q_crit_den_max-31 exp = sub( add( q_crit_num, q_crit_den_max ), 31 ); - L_tmp2 = Mpy_32_32( crit_den, crit_num_max ); + L_tmp2 = Mpy_32_32( crit_den, crit_num_max ); // q_crit_den+q_crit_num_max-31 exp1 = sub( add( q_crit_den, q_crit_num_max ), 31 ); IF( GT_16( exp, exp1 ) ) @@ -866,7 +899,7 @@ void acelp_fast_fx( move16(); } - Copy( y_tmp, y, L_subfr ); // q_H + Copy_Scale_sig( y_tmp, y, L_subfr, sub( 9, q_H ) ); // y in Q9 skip_track_max = skip_track[q]; move16(); } @@ -984,7 +1017,7 @@ void acelp_fast_fx( j = i_mult( q, NPMAXPT ); IF( NE_16( ind_stream[j], -1 ) ) { - idx = quant_1p_N1_L_subfr( nb_pos, ind_stream[j], bits_track ); + idx = quant_1p_N1_L_subfr_fx( nb_pos, ind_stream[j], bits_track ); push_indice( hBstr, IND_ALG_CDBK_4T64, idx, add( bits_track, 1 ) ); } } @@ -1001,7 +1034,7 @@ void acelp_fast_fx( } ELSE { - idx = quant_1p_N1_L_subfr( nb_pos, ind_stream[j], bits_track ); + idx = quant_1p_N1_L_subfr_fx( nb_pos, ind_stream[j], bits_track ); push_indice( hBstr, IND_ALG_CDBK_4T64, idx, add( bits_track, 1 ) ); } } diff --git a/lib_enc/cod4t64_fx.c b/lib_enc/cod4t64_fx.c index 92db2139b7b4c08b412056294c6f194875c646fc..99b794b42325932654eef0f13ab6f90b733671d2 100644 --- a/lib_enc/cod4t64_fx.c +++ b/lib_enc/cod4t64_fx.c @@ -5,10 +5,9 @@ #include "options.h" /* VMR-WB compilation switches */ #include "cnst.h" /* Common constants */ #include "rom_enc.h" /* Encoder static table prototypes */ -#include "prot.h" /* Function prototypes */ +#include "prot_fx.h" /* Function prototypes */ #include "rom_com_fx.h" /* Static table prototypes */ #include "rom_com.h" /* Static table prototypes */ -#include "prot_fx.h" /* Function prototypes */ #include "prot_fx_enc.h" /* Function prototypes */ @@ -57,10 +56,10 @@ static Word32 pre_process_fx( const Word16 v[], Word16 sector_6p[], Word32 secto Word16 acelp_4t64_fx( BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ - Word16 dn[], /* i : corr. between target and h[]. */ + Word16 dn[], /* i : corr. between target and h[]. */ const Word16 cn[], /* i : residual after long term prediction Q_new*/ const Word16 H[], /* i : impulse response of weighted synthesis filter Q12*/ - Word16 R[], /* i : autocorrelation values */ + Word16 R[], /* i : autocorrelation values */ const Word16 acelpautoc, /* i : autocorrealtion flag */ Word16 code[], /* o : algebraic (fixed) codebook excitation Q9*/ Word16 y[], /* o : filtered fixed codebook excitation Q9*/ @@ -100,9 +99,9 @@ Word16 acelp_4t64_fx( case 28: /* EVS pulse indexing: 28 bits, 6 pulses, 4 tracks */ config.nbiter = 4; - move16(); /* 4x20x16=1280 loops */ - config.alp = 8192; - move16(); /* coeff FOR sign setting */ + move16(); /* 4x20x16=1280 loops */ + config.alp = 8192; /*1 in Q13*/ + move16(); /* coeff FOR sign setting */ config.nb_pulse = 6; move16(); config.fixedpulses = 0; @@ -117,9 +116,9 @@ Word16 acelp_4t64_fx( case 36: /* EVS/AMR-WB pulse indexing: 36 bits, 8 pulses, 4 tracks */ config.nbiter = 4; - move16(); /* 4x20x16=1280 loops */ - config.alp = 8192; - move16(); /* coeff FOR sign setting */ + move16(); /* 4x20x16=1280 loops */ + config.alp = 8192; /*1 in Q13*/ + move16(); /* coeff FOR sign setting */ config.nb_pulse = 8; move16(); config.fixedpulses = 2; @@ -135,8 +134,8 @@ Word16 acelp_4t64_fx( case 43: /* EVS pulse indexing: 43 bits, 10 pulses, 4 tracks */ case 44: /* AMR-WB pulse indexing: 44 bits, 10 pulses, 4 tracks */ config.nbiter = 4; - move16(); /* 4x26x16=1664 loops */ - config.alp = 8192; + move16(); /* 4x26x16=1664 loops */ + config.alp = 8192; /*1 in Q13*/ move16(); config.nb_pulse = 10; move16(); @@ -155,8 +154,8 @@ Word16 acelp_4t64_fx( case 50: /* EVS pulse indexing: 50 bits, 12 pulses, 4 tracks */ case 52: /* AMR-WB pulse indexing: 52 bits, 12 pulses, 4 tracks */ config.nbiter = 4; - move16(); /* 4x26x16=1664 loops */ - config.alp = 8192; + move16(); /* 4x26x16=1664 loops */ + config.alp = 8192; /*1 in Q13*/ move16(); config.nb_pulse = 12; move16(); @@ -175,8 +174,8 @@ Word16 acelp_4t64_fx( case 62: /* EVS pulse indexing: 62 bits, 16 pulses, 4 tracks */ case 64: /* AMR-WB pulse indexing: 64 bits, 16 pulses, 4 tracks */ config.nbiter = 3; - move16(); /* 3x36x16=1728 loops */ - config.alp = 6554; + move16(); /* 3x36x16=1728 loops */ + config.alp = 6554; /*.8f in Q13*/ move16(); config.nb_pulse = 16; move16(); @@ -198,8 +197,8 @@ Word16 acelp_4t64_fx( case 72: /* AMR-WB pulse indexing: 72 bits, 18 pulses, 4 tracks */ config.nbiter = 3; - move16(); /* 3x35x16=1680 loops */ - config.alp = 6144; + move16(); /* 3x35x16=1680 loops */ + config.alp = 6144; /*.75f in Q13*/ move16(); config.nb_pulse = 18; move16(); @@ -223,8 +222,8 @@ Word16 acelp_4t64_fx( case 88: /* AMR-WB pulse indexing: 88 bits, 24 pulses, 4 tracks */ config.nbiter = 2; - move16(); /* 2x53x16=1696 loop */ - config.alp = 4096; + move16(); /* 2x53x16=1696 loop */ + config.alp = 4096; /*.5f in Q13*/ move16(); config.nb_pulse = 24; move16(); @@ -255,7 +254,7 @@ Word16 acelp_4t64_fx( case 87: /* EVS pulse indexing: 87 bits, 26 pulses, 4 tracks */ config.nbiter = 1; move16(); - config.alp = 4096; + config.alp = 4096; /*.5f in Q13*/ move16(); config.nb_pulse = 26; move16(); @@ -472,10 +471,10 @@ Word16 acelp_4t64_fx( Word16 acelp_4t64_ivas_fx( BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ - Word16 dn[], /* i : corr. between target and h[]. */ + Word16 dn[], /* i : corr. between target and h[]. */ const Word16 cn[], /* i : residual after long term prediction Q_new*/ const Word16 H[], /* i : impulse response of weighted synthesis filter Q12*/ - Word16 R[], /* i : autocorrelation values */ + Word16 R[], /* i : autocorrelation values */ const Word16 acelpautoc, /* i : autocorrealtion flag */ Word16 code[], /* o : algebraic (fixed) codebook excitation Q9*/ Word16 y[], /* o : filtered fixed codebook excitation Q9*/ @@ -515,9 +514,9 @@ Word16 acelp_4t64_ivas_fx( case 28: /* EVS pulse indexing: 28 bits, 6 pulses, 4 tracks */ config.nbiter = 4; - move16(); /* 4x20x16=1280 loops */ - config.alp = 8192; - move16(); /* coeff FOR sign setting */ + move16(); /* 4x20x16=1280 loops */ + config.alp = 8192; /*1 in Q13*/ + move16(); /* coeff FOR sign setting */ config.nb_pulse = 6; move16(); config.fixedpulses = 0; @@ -532,9 +531,9 @@ Word16 acelp_4t64_ivas_fx( case 36: /* EVS/AMR-WB pulse indexing: 36 bits, 8 pulses, 4 tracks */ config.nbiter = 4; - move16(); /* 4x20x16=1280 loops */ - config.alp = 8192; - move16(); /* coeff FOR sign setting */ + move16(); /* 4x20x16=1280 loops */ + config.alp = 8192; /*1 in Q13*/ + move16(); /* coeff FOR sign setting */ config.nb_pulse = 8; move16(); config.fixedpulses = 2; @@ -550,8 +549,8 @@ Word16 acelp_4t64_ivas_fx( case 43: /* EVS pulse indexing: 43 bits, 10 pulses, 4 tracks */ case 44: /* AMR-WB pulse indexing: 44 bits, 10 pulses, 4 tracks */ config.nbiter = 4; - move16(); /* 4x26x16=1664 loops */ - config.alp = 8192; + move16(); /* 4x26x16=1664 loops */ + config.alp = 8192; /*1 in Q13*/ move16(); config.nb_pulse = 10; move16(); @@ -570,8 +569,8 @@ Word16 acelp_4t64_ivas_fx( case 50: /* EVS pulse indexing: 50 bits, 12 pulses, 4 tracks */ case 52: /* AMR-WB pulse indexing: 52 bits, 12 pulses, 4 tracks */ config.nbiter = 4; - move16(); /* 4x26x16=1664 loops */ - config.alp = 8192; + move16(); /* 4x26x16=1664 loops */ + config.alp = 8192; /*1 in Q13*/ move16(); config.nb_pulse = 12; move16(); @@ -590,8 +589,8 @@ Word16 acelp_4t64_ivas_fx( case 62: /* EVS pulse indexing: 62 bits, 16 pulses, 4 tracks */ case 64: /* AMR-WB pulse indexing: 64 bits, 16 pulses, 4 tracks */ config.nbiter = 3; - move16(); /* 3x36x16=1728 loops */ - config.alp = 6554; + move16(); /* 3x36x16=1728 loops */ + config.alp = 6554; /*.8f in Q13*/ move16(); config.nb_pulse = 16; move16(); @@ -613,8 +612,8 @@ Word16 acelp_4t64_ivas_fx( case 72: /* AMR-WB pulse indexing: 72 bits, 18 pulses, 4 tracks */ config.nbiter = 3; - move16(); /* 3x35x16=1680 loops */ - config.alp = 6144; + move16(); /* 3x35x16=1680 loops */ + config.alp = 6144; /*.75f in Q13*/ move16(); config.nb_pulse = 18; move16(); @@ -638,8 +637,8 @@ Word16 acelp_4t64_ivas_fx( case 88: /* AMR-WB pulse indexing: 88 bits, 24 pulses, 4 tracks */ config.nbiter = 2; - move16(); /* 2x53x16=1696 loop */ - config.alp = 4096; + move16(); /* 2x53x16=1696 loop */ + config.alp = 4096; /*.5f in Q13*/ move16(); config.nb_pulse = 24; move16(); @@ -670,7 +669,7 @@ Word16 acelp_4t64_ivas_fx( case 87: /* EVS pulse indexing: 87 bits, 26 pulses, 4 tracks */ config.nbiter = 1; move16(); - config.alp = 4096; + config.alp = 4096; /*.5f in Q13*/ move16(); config.nb_pulse = 26; move16(); @@ -709,7 +708,7 @@ Word16 acelp_4t64_ivas_fx( } config.codetrackpos = TRACKPOS_FIXED_FIRST; - move16(); + move32(); config.bits = nbbits; move16(); @@ -905,7 +904,7 @@ static Word32 fcb_encode_cl_fx( /* o: class index of t FOR( i = 0; i < pulse_num; i++ ) { - k = L_sub( k, PI_select_table[L_sub( temp1, buffer[i] )][temp2--] ); + k = L_sub( k, PI_select_table[temp1 - buffer[i]][temp2--] ); temp1 = L_sub( temp1, 1 ); } @@ -917,7 +916,7 @@ static Word32 fcb_encode_cl_fx( /* o: class index of t *encode fcb pulse index * *---------------------------------------------------------------------*/ static Word32 fcb_encode_PI_fx( /* o: return index of the pulse on a track */ - const Word16 v[], /* i: pulse on a track */ + const Word16 v[], /* i: pulse on a track Q9 */ const Word32 pulse_num /* i: number of the pulse on a track */ ) { @@ -935,7 +934,7 @@ static Word32 fcb_encode_PI_fx( /* o: return index of t /*encode the class and compute class offset*/ code_index = L_add( code_index, fcb_encode_class_fx( sector_p_num, pulse_num, pulse_pos_num ) ); - code_index = L_add( PI_offset[pulse_num][L_sub( L_add( pulse_num, 1L ), pulse_pos_num )], L_add( L_shl( code_index, extract_l( pulse_pos_num ) ), sign ) ); + code_index = L_add( PI_offset[pulse_num][( ( pulse_num + 1L ) - pulse_pos_num )], L_add( L_shl( code_index, extract_l( pulse_pos_num ) ), sign ) ); return code_index; } @@ -999,7 +998,7 @@ static Word32 fcb_encode_position_fx( /* o: return FOR( i = 0; i < pos_num; i++ ) { /*mmm1 -= PI_select_table_fx[sub(n,pos_vector[i]-1)][temp2--];*/ - mmm1 = L_sub( mmm1, PI_select_table[L_sub( n, add( pos_vector[i], 1 ) )][temp2--] ); + mmm1 = L_sub( mmm1, PI_select_table[n - ( pos_vector[i] + 1 )][temp2--] ); } } ELSE @@ -1008,7 +1007,7 @@ static Word32 fcb_encode_position_fx( /* o: return FOR( i = 0; i < pos_num; i++ ) { /*mmm1 -= PI_select_table_fx[n-pos_vector[i]-1][temp2--];*/ - mmm1 = L_sub( mmm1, PI_select_table[L_sub( n, add( pos_vector[i], 1 ) )][temp2--] ); + mmm1 = L_sub( mmm1, PI_select_table[n - ( pos_vector[i] + 1 )][temp2--] ); n = L_sub( n, 1 ); } } @@ -1232,7 +1231,7 @@ static Word32 quant_4p_4N_fx( /* o : return 4*N bits Word16 posA[4], posB[4]; Word32 index; - n_1 = (Word16) ( N - 1 ); + n_1 = sub( N, 1 ); move16(); nb_pos = shl( 1, n_1 ); /* nb_pos = (1< it doesn't need to be operated by Basic Operators */ - n_1 = (Word16) ( N - 1 ); - move16(); + n_1 = sub( N, 1 ); nb_pos = shl( 1, n_1 ); /* nb_pos = (1< 1, Q0 */ + move32(); IF( v[k] > 0 ) { sign = L_shl( sign, 1 ); @@ -1492,6 +1493,7 @@ static Word32 pre_process_fx( /* o: return sign value } } *pulse_pos_num = L_deposit_l( j ); +move32(); return sign; } @@ -1510,7 +1512,7 @@ return sign; *--------------------------------------------------------------------------*/ Word16 E_ACELP_code43bit_fx( - const Word16 code[], + const Word16 code[], /*Q9*/ UWord32 *ps, Word16 *p, UWord16 idxs[] ) @@ -1522,8 +1524,9 @@ Word16 E_ACELP_code43bit_fx( Word32 L_tmp; Word32 joint_index; static const Word32 joint_offset = 3611648; /*offset for 3 pulses per track*/ + move32(); Word16 saved_bits = 0; - + move16(); FOR( track = 0; track < 2; track++ ) { ps[track] = fcb_encode_PI_fx( code + track, 3 ); @@ -1535,19 +1538,19 @@ Word16 E_ACELP_code43bit_fx( FOR( track = 2; track < NB_TRACK_FCB_4T; track++ ) { i = j = i_mult2( track, NPMAXPT ); - move16(); + FOR( k = track; k < 64; k += 4 ) { IF( code[k] ) { tmp = shr( k, 2 ); - if ( code[k] < 0 ) + IF( code[k] < 0 ) { tmp = add( tmp, 16 ); } ind[j] = tmp; move16(); - IF( GT_16( abs_s( code[k] ), 512 ) ) + IF( GT_16( abs_s( code[k] ), 512 /*Q9*/ ) ) { ind[j + 1] = tmp; move16(); @@ -1580,6 +1583,8 @@ Word16 E_ACELP_code43bit_fx( idxs[0] = extract_l( L_add( L_shl( ps[2], 9 ), ps[3] ) ); idxs[1] = extract_l( L_add( L_shl( joint_index, 2 ), L_shr( ps[2], 7 ) ) ); idxs[2] = extract_l( L_shr( joint_index, 14 ) ); - + move16(); + move16(); + move16(); return saved_bits; } diff --git a/lib_enc/cod_ace.c b/lib_enc/cod_ace.c deleted file mode 100644 index 3ee7cc7b2d7534bb92818b41e1cdef4341d0f9ec..0000000000000000000000000000000000000000 --- a/lib_enc/cod_ace.c +++ /dev/null @@ -1,42 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "prot.h" -#include -#include "options.h" -#include "rom_com.h" -#include "wmc_auto.h" diff --git a/lib_enc/cod_ace_fx.c b/lib_enc/cod_ace_fx.c index e11f068b60025545274b06dee47173f94398c4de..e701b8e466b946d9c4c6cbc739f4a77476e558ca 100644 --- a/lib_enc/cod_ace_fx.c +++ b/lib_enc/cod_ace_fx.c @@ -22,19 +22,19 @@ *-------------------------------------------------------------------*/ Word16 coder_acelp_fx( /* o : SEGSNR for CL decision */ - const Word16 A[], /* i : coefficients 4xAz[M+1] */ - const Word16 Aq[], /* i : coefficients 4xAz_q[M+1] */ - const Word16 speech[], /* i : speech[-M..lg] */ + const Word16 A[], /* i : coefficients 4xAz[M+1] Qx*/ + const Word16 Aq[], /* i : coefficients 4xAz_q[M+1] Q12*/ + const Word16 speech[], /* i : speech[-M..lg] Qx*/ Word16 *prm, /* o : acelp parameters */ - Word16 stab_fac, + Word16 stab_fac, /*Q15 */ Encoder_State *st, PLC_ENC_EVS_HANDLE hPlc_Ext, const Word16 target_bits, /* i/o: coder memory state */ const Word16 Q_new, const Word16 shift, Word16 *pitch_buf, /* o : pitch values for each subfr.*/ - Word16 *voice_factors, /* o : voicing factors */ - Word16 *bwe_exc /* o : excitation for SWB TBE */ + Word16 *voice_factors, /* o : voicing factors Q15 */ + Word16 *bwe_exc /* o : excitation for SWB TBE Qx */ ) { #ifndef SIMPLIFY_CODE_BE @@ -73,13 +73,17 @@ Word16 coder_acelp_fx( /* o : SEGSNR for CL decision * Word16 code2[L_SUBFR]; Word16 y22[L_SUBFR]; /* Filtered adaptive excitation */ Word16 error = 0; - Word16 gain_preQ = 0; /* Gain of prequantizer excitation */ + move16(); + Word16 gain_preQ = 0; /* Gain of prequantizer excitation */ + move16(); Word16 code_preQ[L_SUBFR]; /* Prequantizer excitation */ Word16 dummy = 0; + move16(); ACELP_config *acelp_cfg; #ifdef BASOP_NOGLOB_DECLARE_LOCAL Flag Overflow = 0; + move32(); #endif acelp_cfg = &( st->acelp_cfg ); @@ -109,8 +113,9 @@ Word16 coder_acelp_fx( /* o : SEGSNR for CL decision * move16(); move16(); move16(); + move16(); L_frame = st->L_frame; - + move16(); /*------------------------------------------------------------------------* * Previous frame is TCX (for non-EVS modes)(deactivated permanently) * @@ -126,11 +131,10 @@ Word16 coder_acelp_fx( /* o : SEGSNR for CL decision * Q_new_p5 = add( Q_new, 5 ); /* Reset phase dispersion */ - IF( GT_16( st->last_core, ACELP_CORE ) ) + IF( st->last_core > ACELP_CORE ) { move16(); move16(); - move16(); hLPDmem->dm_fx.prev_gain_code = 0; set16_fx( hLPDmem->dm_fx.prev_gain_pit, 0, 6 ); @@ -138,8 +142,6 @@ Word16 coder_acelp_fx( /* o : SEGSNR for CL decision * } /* set excitation memory*/ - move16(); - move16(); exc = exc_buf + L_EXC_MEM; Copy( hLPDmem->old_exc, exc_buf, L_EXC_MEM ); *( exc + st->L_frame ) = 0; @@ -193,8 +195,7 @@ Word16 coder_acelp_fx( /* o : SEGSNR for CL decision * * - find synthesis speech * * - update states of weighting filter * *------------------------------------------------------------------------*/ - move16(); - move16(); + p_A = A; p_Aq = Aq; @@ -231,7 +232,7 @@ Word16 coder_acelp_fx( /* o : SEGSNR for CL decision * * or in case of floating point encoder & fixed p. decoder *-----------------------------------------------------------------*/ - clip_gain = Mode2_gp_clip( st->voicing_fx, i_subfr, st->coder_type, xn, st->clip_var_fx, L_SUBFR, Q_xn ); + clip_gain = Mode2_gp_clip_fx( st->voicing_fx, i_subfr, st->coder_type, xn, st->clip_var_fx, L_SUBFR, Q_xn ); /*-----------------------------------------------------------------* * - find unity gain pitch excitation (adaptive codebook entry) * @@ -292,7 +293,10 @@ Word16 coder_acelp_fx( /* o : SEGSNR for CL decision * g_corr.xy2_e = sub( g_corr.xy2_e, add( Q_xn, 9 ) ); /* -(Q_xn+9) (xn: Q_xn y2: Q9) */ g_corr.y1y2_e = sub( g_corr.y1y2_e, add( Q_xn, 9 ) ); /* -(Q_xn+9) (y1: Q_xn y2: Q9) */ g_corr.xx_e = sub( g_corr.xx_e, add( Q_xn, Q_xn ) ); /* -(Q_xn+Q_xn) (xn: Q_xn) */ - + move16(); + move16(); + move16(); + move16(); /*----------------------------------------------------------------------* * Add Gaussian excitation * @@ -334,6 +338,7 @@ Word16 coder_acelp_fx( /* o : SEGSNR for CL decision * IF( st->Opt_RF_ON ) { hRF->rf_tilt_buf[i_subfr / L_SUBFR] = hLPDmem->tilt_code; + move16(); } /*-----------------------------------------------------------------* * Update memory of the weighting filter @@ -349,11 +354,8 @@ Word16 coder_acelp_fx( /* o : SEGSNR for CL decision * hLPDmem->mem_w0 = sub( xn[L_SUBFR - 1], round_fx( L_shl( Ltmp, 1 ) ) ); move16(); BASOP_SATURATE_WARNING_OFF_EVS; -#ifdef BASOP_NOGLOB hLPDmem->mem_w0 = shr_sat( hLPDmem->mem_w0, shift ); /*Qnew-1*/ -#else - hLPDmem->mem_w0 = shr( hLPDmem->mem_w0, shift ); /*Qnew-1*/ -#endif + move16(); BASOP_SATURATE_WARNING_ON_EVS; /*-------------------------------------------------------* @@ -391,31 +393,14 @@ Word16 coder_acelp_fx( /* o : SEGSNR for CL decision * Ltmp = Mpy_32_16_1( gain_code2, code2[i] ); Ltmp = L_shl( Ltmp, Q_new_p5 ); Ltmp = L_mac( Ltmp, gain_pit, exc[i + i_subfr] ); -#ifdef BASOP_NOGLOB exc2[i] = round_fx_sat( L_shl_o( Ltmp, 1, &Overflow ) ); -#else - BASOP_SATURATE_WARNING_OFF_EVS - exc2[i] = round_fx( L_shl( Ltmp, 1 ) ); - BASOP_SATURATE_WARNING_ON_EVS -#endif - + move16(); Ltmp2 = Mpy_32_16_1( gain_code, code[i] ); -#ifdef BASOP_NOGLOB Ltmp2 = L_shl_sat( Ltmp2, Q_new_p5 ); Ltmp = L_add_sat( Ltmp, Ltmp2 ); -#else - Ltmp2 = L_shl( Ltmp2, Q_new_p5 ); - Ltmp = L_add( Ltmp, Ltmp2 ); -#endif -#ifdef BASOP_NOGLOB Ltmp = L_shl_o( Ltmp, 1, &Overflow ); /* saturation can occur here */ exc[i + i_subfr] = round_fx_o( Ltmp, &Overflow ); -#else - BASOP_SATURATE_WARNING_OFF_EVS - Ltmp = L_shl( Ltmp, 1 ); /* saturation can occur here */ - BASOP_SATURATE_WARNING_ON_EVS - exc[i + i_subfr] = round_fx( Ltmp ); -#endif + move16(); } #endif /*-----------------------------------------------------------------* @@ -454,8 +439,7 @@ Word16 coder_acelp_fx( /* o : SEGSNR for CL decision * /*----------------------------------------------------------* * Update * *----------------------------------------------------------*/ - move16(); - move16(); + p_A += ( M + 1 ); p_Aq += ( M + 1 ); @@ -499,7 +483,7 @@ Word16 coder_acelp_fx( /* o : SEGSNR for CL decision * tmp = hLPDmem->syn[M]; E_UTIL_deemph2( sub( Q_new, 1 ), syn, st->preemph_fac, L_frame, &tmp ); - if ( st->hTcxEnc != NULL ) + IF( st->hTcxEnc != NULL ) { bufferCopyFx( syn + L_frame - ( L_frame / 2 ), hTcxEnc->Txnq, shr( L_frame, 1 ), 0 /*Qf_syn*/, -1 /*Qf_Txnq*/, 0 /*Q_syn*/, 0 /*Q_Txnq*/ ); } @@ -511,6 +495,6 @@ Word16 coder_acelp_fx( /* o : SEGSNR for CL decision * /*Update MODE1*/ Copy( p_Aq, st->old_Aq_12_8_fx, M + 1 ); st->old_Es_pred_fx = Es_pred; - + move16(); return 0; } diff --git a/lib_enc/cod_tcx.c b/lib_enc/cod_tcx.c deleted file mode 100644 index 72cfb8e96af4d2af62f59747899df8b8a13f6704..0000000000000000000000000000000000000000 --- a/lib_enc/cod_tcx.c +++ /dev/null @@ -1,762 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include -#include "options.h" -#include -#include "cnst.h" -#include "prot.h" -#include "wmc_auto.h" -#include "ivas_prot.h" -#include "ivas_rom_com.h" -#include "ivas_rom_com_fx.h" -#include "prot_fx_enc.h" -#include "prot_fx.h" -#include "ivas_prot_fx.h" - - -/*-------------------------------------------------------------------* - * TNSAnalysisStereo() - * - * - *-------------------------------------------------------------------*/ - -#define SIMILAR_TNS_THRESHOLD ( 0.04f ) -#define SIMILAR_TNS_THRESHOLD_FX_IN_Q15 ( 1311 ) -#define TNS_GAIN_THRESHOLD_FOR_WHITE ( 3.0f ) -#define TNS_GAIN_THRESHOLD_FOR_WHITE_FX_IN_Q7 ( 384 ) -void TNSAnalysisStereo_fx( - Encoder_State **sts, /* i : encoder state handle */ - Word32 *mdst_spectrum_fx[CPE_CHANNELS][NB_DIV], /* o : MDST spectrum Qx*/ - const Word16 bWhitenedDomain, /* i : whitened domain flag Q0*/ - Word16 tnsSize[CPE_CHANNELS][NB_DIV], /* i : number of tns parameters put into prm Q0*/ - Word16 tnsBits[CPE_CHANNELS][NB_DIV], /* i : number of tns bits in the frame Q0*/ - Word16 param_core[][NB_DIV * NPRM_DIV], /* o : TNS parameters Q0*/ - const Word16 mct_on /* i : flag mct block (1) or stereo (0) Q0*/ -) -{ - Word16 ch, k, L_spec, L_frame, nSubframes, iFilter; - Word32 *spectrum_fx; - Encoder_State *st = NULL; - TCX_ENC_HANDLE hTcxEnc = NULL; - Word16 individual_decision[NB_DIV]; - Word16 maxPredictionGain_fx = 0, meanPredictionGain_fx; - move16(); - - individual_decision[0] = 0; - move16(); - individual_decision[1] = 0; - move16(); - L_spec = -1; - move16(); - L_frame = -1; - move16(); - - /* TNS filter analysis, loop over channels */ - FOR( ch = 0; ch < CPE_CHANNELS; ch++ ) - { - st = sts[ch]; - IF( EQ_16( st->mct_chan_mode, MCT_CHAN_MODE_IGNORE ) ) - { - continue; - } - - hTcxEnc = st->hTcxEnc; - - IF( EQ_16( hTcxEnc->tcxMode, TCX_20 ) ) - { - nSubframes = 1; - } - ELSE - { - nSubframes = NB_DIV; - } - move16(); - - FOR( k = 0; k < nSubframes; k++ ) - { - /* reset tns on whitened domain flag */ - IF( !bWhitenedDomain ) - { - hTcxEnc->bTnsOnWhithenedSpectra[k] = 0; - move16(); - hTcxEnc->fUseTns[k] = 0; - move16(); - } - test(); - test(); - IF( st->hTcxCfg->fIsTNSAllowed && ( !bWhitenedDomain || hTcxEnc->bTnsOnWhithenedSpectra[k] ) ) - { - spectrum_fx = hTcxEnc->spectrum_fx[k]; - - L_frame = hTcxEnc->L_frameTCX; - move16(); - st->hTcxCfg->pCurrentTnsConfig = &st->hTcxCfg->tnsConfig[hTcxEnc->transform_type[k] == TCX_20][( k == 0 ) && ( st->last_core == ACELP_CORE )]; - L_spec = st->hTcxCfg->pCurrentTnsConfig->iFilterBorders[0]; - move16(); - /*-----------------------------------------------------------* - * Temporal Noise Shaping analysis * - *-----------------------------------------------------------*/ - - IF( hTcxEnc->transform_type[k] == TCX_5 ) - { - /* rearrange LF sub-window lines prior to TNS analysis & filtering */ - tcx5TnsGrouping_fx( shr( L_frame, 2 ), shr( L_spec, 1 ), spectrum_fx ); - } - - /* WMOPS: All initializations are either for safety or static (tables) and thus not to be counted */ - - ResetTnsData( &hTcxEnc->tnsData[k] ); - if ( st->hTcxCfg->pCurrentTnsConfig->maxOrder <= 0 ) - { - break; - } - - CalculateTnsFilt_fx( st->hTcxCfg->pCurrentTnsConfig, spectrum_fx, &hTcxEnc->tnsData[k], NULL ); - } - } - } - - IF( !mct_on ) - { - /* TNS decision */ - /* if framing differs between channels, keep the filter decision per channel */ - test(); - test(); - IF( ( NE_16( sts[0]->hTcxEnc->transform_type[0], sts[1]->hTcxEnc->transform_type[0] ) && - NE_16( sts[0]->hTcxEnc->transform_type[1], sts[1]->hTcxEnc->transform_type[1] ) ) || - NE_16( sts[0]->hTcxCfg->fIsTNSAllowed, sts[1]->hTcxCfg->fIsTNSAllowed ) ) - { - individual_decision[0] = individual_decision[1] = 1; - move16(); - move16(); - } - ELSE IF( bWhitenedDomain ) - { - IF( EQ_16( sts[0]->hTcxEnc->tcxMode, TCX_20 ) ) - { - nSubframes = 1; - } - ELSE - { - nSubframes = NB_DIV; - } - move16(); - FOR( k = 0; k < nSubframes; k++ ) - { - IF( NE_16( sts[0]->hTcxEnc->bTnsOnWhithenedSpectra[k], sts[1]->hTcxEnc->bTnsOnWhithenedSpectra[k] ) ) - { - individual_decision[k] = 1; - move16(); - } - } - } - - /* framing equal, check for similar filters, if very similar (also indicator for and M signal), - * use at least the same decision, maybe use the same filter - */ - { - Word8 isTCX10; - - IF( EQ_16( sts[0]->hTcxEnc->tcxMode, TCX_20 ) ) - { - nSubframes = 1; - isTCX10 = 0; - } - ELSE - { - nSubframes = NB_DIV; - isTCX10 = 1; - } - move16(); - move16(); - FOR( k = 0; k < nSubframes; k++ ) - { - test(); - test(); - test(); - IF( sts[0]->hTcxCfg->fIsTNSAllowed && NE_16( individual_decision[k], 1 ) && ( !bWhitenedDomain || sts[0]->hTcxEnc->bTnsOnWhithenedSpectra[k] ) ) - { - Word16 maxPredGain_fx = -ONE_IN_Q7; - move16(); - sts[0]->hTcxCfg->pCurrentTnsConfig = &sts[0]->hTcxCfg->tnsConfig[sts[0]->hTcxEnc->transform_type[k] == TCX_20][( k == 0 ) && ( sts[0]->last_core == ACELP_CORE )]; - sts[1]->hTcxCfg->pCurrentTnsConfig = &sts[1]->hTcxCfg->tnsConfig[sts[1]->hTcxEnc->transform_type[k] == TCX_20][( k == 0 ) && ( sts[1]->last_core == ACELP_CORE )]; - - FOR( iFilter = sub( sts[0]->hTcxCfg->pCurrentTnsConfig->nMaxFilters, 1 ); iFilter >= 0; iFilter-- ) - { - STnsFilter *pFilter[2]; - struct TnsParameters const *pTnsParameters[2]; - pFilter[0] = sts[0]->hTcxEnc->tnsData[k].filter + iFilter; - pTnsParameters[0] = sts[0]->hTcxCfg->pCurrentTnsConfig->pTnsParameters + iFilter; - pFilter[1] = sts[1]->hTcxEnc->tnsData[k].filter + iFilter; - pTnsParameters[1] = sts[1]->hTcxCfg->pCurrentTnsConfig->pTnsParameters + iFilter; - - /* if prediction gain and avgSqrCoef are both close we are pretty sure the filters are quite similar, use the avg of - * both filters for the decision - */ - - meanPredictionGain_fx = mac_r( L_mult( pFilter[0]->predictionGain, 16384 ), pFilter[1]->predictionGain, 16384 ); // Q7 - maxPredictionGain_fx = s_max( maxPredictionGain_fx, meanPredictionGain_fx ); // Q7 - - test(); - test(); - test(); - IF( GT_16( pFilter[0]->predictionGain, pTnsParameters[0]->minPredictionGain ) && LT_32( sts[0]->element_brate, IVAS_80k ) && - GT_16( pFilter[1]->predictionGain, pTnsParameters[1]->minPredictionGain ) && EQ_16( sts[0]->hTcxEnc->tnsData[k].nFilters, sts[1]->hTcxEnc->tnsData[k].nFilters ) ) - { - pFilter[0]->predictionGain = pFilter[1]->predictionGain = meanPredictionGain_fx; /* more TNS filter sync at 48kbps */ - move16(); - move16(); - } - test(); - IF( LT_16( abs_s( sub( pFilter[0]->predictionGain, pFilter[1]->predictionGain ) ), mult( SIMILAR_TNS_THRESHOLD_FX_IN_Q15, meanPredictionGain_fx ) ) && - ( sts[0]->hTcxEnc->tnsData[k].nFilters == sts[1]->hTcxEnc->tnsData[k].nFilters ) ) - { - - Word16 maxAvgSqrCoef_fx = s_max( pFilter[0]->avgSqrCoef, pFilter[1]->avgSqrCoef ); // Q15 - Word16 meanLtpGain_fx = add( shr( sts[0]->hTcxEnc->tcxltp_gain, 1 ), shr( sts[1]->hTcxEnc->tcxltp_gain, 1 ) ); - maxPredGain_fx = s_max( maxPredGain_fx, meanPredictionGain_fx ); - test(); - test(); - IF( GT_16( meanPredictionGain_fx, pTnsParameters[0]->minPredictionGain ) || GT_16( maxAvgSqrCoef_fx, pTnsParameters[0]->minAvgSqrCoef ) ) - { - test(); - test(); - test(); - IF( sts[0]->hTcxEnc->tnsData[k].nFilters > 0 || sts[1]->hTcxEnc->tnsData[k].nFilters > 0 || isTCX10 || LT_16( meanLtpGain_fx, 19660 /* 0.6 in Q15*/ ) ) - { - ++sts[0]->hTcxEnc->tnsData[k].nFilters; - /* When order parameter is evaluated as 0 and change in precision causes the flow to reach here, - this may result in crash later. Changing the filter type here so the order is taken here in further section */ - IF( pFilter[0]->order != 0 ) - { - pFilter[0]->filterType = TNS_FILTER_ON; - move16(); - } - ELSE - { - pFilter[0]->filterType = TNS_FILTER_ON_ZERO; - move16(); - } - ++sts[1]->hTcxEnc->tnsData[k].nFilters; - IF( pFilter[1]->order != 0 ) - { - pFilter[1]->filterType = TNS_FILTER_ON; - move16(); - } - ELSE - { - pFilter[1]->filterType = TNS_FILTER_ON_ZERO; - move16(); - } - } - ELSE - { - Word16 maxEnergyChange_fx; - maxEnergyChange_fx = mac_r( L_mult( GetTCXMaxenergyChange_ivas_fx( sts[0]->hTranDet, isTCX10, NSUBBLOCKS, 3 ), 16384 ), GetTCXMaxenergyChange_ivas_fx( sts[1]->hTranDet, isTCX10, NSUBBLOCKS, 3 ), 16384 ); - - IF( GE_16( maxEnergyChange_fx, pTnsParameters[0]->minEnergyChange ) ) - { - ++sts[0]->hTcxEnc->tnsData[k].nFilters; - /* When order parameter is evaluated as 0 and change in precision causes the flow to reach here, - this may result in crash later. Changing the filter type here so the order is taken here in further section */ - IF( pFilter[0]->order != 0 ) - { - pFilter[0]->filterType = TNS_FILTER_ON; - move16(); - } - ELSE - { - pFilter[0]->filterType = TNS_FILTER_ON_ZERO; - move16(); - } - ++sts[1]->hTcxEnc->tnsData[k].nFilters; - IF( pFilter[1]->order != 0 ) - { - pFilter[1]->filterType = TNS_FILTER_ON; - move16(); - } - ELSE - { - pFilter[1]->filterType = TNS_FILTER_ON_ZERO; - move16(); - } - } - ELSE - { - pFilter[0]->filterType = TNS_FILTER_OFF; - move16(); - pFilter[1]->filterType = TNS_FILTER_OFF; - move16(); - } - } - } - ELSE IF( sts[0]->hTcxEnc->tnsData[k].nFilters > 0 && sts[1]->hTcxEnc->tnsData[k].nFilters > 0 ) /* If a previous filter is turned on */ - { - pFilter[0]->filterType = TNS_FILTER_ON_ZERO; - pFilter[1]->filterType = TNS_FILTER_ON_ZERO; - ++sts[0]->hTcxEnc->tnsData[k].nFilters; - ++sts[1]->hTcxEnc->tnsData[k].nFilters; - } - ELSE IF( NE_16( sts[0]->hTcxEnc->tnsData[k].nFilters, sts[1]->hTcxEnc->tnsData[k].nFilters ) ) /* sanity check */ - { - assert( 0 ); - } - ELSE - { - pFilter[0]->filterType = TNS_FILTER_OFF; - move16(); - pFilter[1]->filterType = TNS_FILTER_OFF; - move16(); - } - - test(); - test(); - IF( EQ_16( pFilter[0]->filterType, TNS_FILTER_ON ) && EQ_16( pFilter[1]->filterType, TNS_FILTER_ON ) && LT_32( sts[0]->element_brate, IVAS_80k ) ) - { - Word16 tmpIntValue = 0; - move16(); - Word16 tmpCoeff[TNS_MAX_FILTER_ORDER]; - Word16 i, maxOrder = s_max( pFilter[0]->order, pFilter[1]->order ); - - set16_fx( tmpCoeff, 0, TNS_MAX_FILTER_ORDER ); - FOR( i = 0; i < maxOrder; i++ ) - { - tmpIntValue = s_max( tmpIntValue, abs_s( sub( pFilter[0]->coefIndex[i], pFilter[1]->coefIndex[i] ) ) ); - } - - IF( EQ_16( tmpIntValue, 1 ) ) /* the TNS coefficients are sufficiently similar to equalize the two filters */ - { - FOR( i = sub( maxOrder, 1 ); i >= 0; i-- ) - { - IF( LT_16( abs_s( pFilter[0]->coefIndex[i] ), abs_s( pFilter[1]->coefIndex[i] ) ) ) - { - tmpCoeff[i] = pFilter[0]->coefIndex[i]; - } - ELSE - { - tmpCoeff[i] = pFilter[1]->coefIndex[i]; - } - move16(); - IF( ( tmpIntValue > 0 ) && ( tmpCoeff[i] == 0 ) ) - { - maxOrder = sub( maxOrder, 1 ); - } - ELSE - { - tmpIntValue = 0; - move16(); - } - } - /* make sure that maxOrder is non zero and not all coefficients are zero (could happen in rare cases) */ - IF( maxOrder > 0 ) - { - FOR( i = TNS_MAX_FILTER_ORDER - 1; i >= 0; i-- ) - { - pFilter[0]->coefIndex[i] = pFilter[1]->coefIndex[i] = tmpCoeff[i]; - move16(); - move16(); - } - - pFilter[0]->order = pFilter[1]->order = maxOrder; - move16(); - move16(); - } - } - } - } - ELSE - { - individual_decision[k] = 1; - move16(); - } - } - - IF( individual_decision[k] == 0 ) - { - IF( ( sts[0]->hTcxEnc->tnsData[k].nFilters > 0 ) ) - { - sts[0]->hTcxEnc->fUseTns[k] = 1; - } - ELSE - { - sts[0]->hTcxEnc->fUseTns[k] = 0; - } - move16(); - - IF( ( sts[1]->hTcxEnc->tnsData[k].nFilters > 0 ) ) - { - sts[1]->hTcxEnc->fUseTns[k] = 1; - } - ELSE - { - sts[1]->hTcxEnc->fUseTns[k] = 0; - } - move16(); - } - ELSE - { - sts[0]->hTcxEnc->tnsData[k].nFilters = 0; - move16(); - sts[1]->hTcxEnc->tnsData[k].nFilters = 0; - move16(); - sts[0]->hTcxEnc->fUseTns[k] = 0; - move16(); - sts[1]->hTcxEnc->fUseTns[k] = 0; - move16(); - FOR( iFilter = sub( sts[0]->hTcxCfg->pCurrentTnsConfig->nMaxFilters, 1 ); iFilter >= 0; iFilter-- ) - { - sts[0]->hTcxEnc->tnsData[k].filter[iFilter].filterType = TNS_FILTER_OFF; - move16(); - sts[1]->hTcxEnc->tnsData[k].filter[iFilter].filterType = TNS_FILTER_OFF; - move16(); - } - } - test(); - test(); - test(); - IF( !bWhitenedDomain && individual_decision[k] == 0 && LT_16( maxPredGain_fx, TNS_GAIN_THRESHOLD_FOR_WHITE_FX_IN_Q7 ) && NE_16( sts[0]->hTcxEnc->transform_type[k], TCX_5 ) ) - { - sts[0]->hTcxEnc->bTnsOnWhithenedSpectra[k] = 1; - move16(); - sts[1]->hTcxEnc->bTnsOnWhithenedSpectra[k] = 1; - move16(); - sts[0]->hTcxEnc->tnsData[k].nFilters = 0; - move16(); - sts[1]->hTcxEnc->tnsData[k].nFilters = 0; - move16(); - sts[0]->hTcxEnc->fUseTns[k] = 0; - move16(); - sts[1]->hTcxEnc->fUseTns[k] = 0; - move16(); - FOR( iFilter = sub( sts[0]->hTcxCfg->pCurrentTnsConfig->nMaxFilters, 1 ); iFilter >= 0; iFilter-- ) - { - ClearTnsFilterCoefficients( sts[0]->hTcxEnc->tnsData[k].filter + iFilter ); - ClearTnsFilterCoefficients( sts[1]->hTcxEnc->tnsData[k].filter + iFilter ); - } - } - maxPredictionGain_fx = s_max( maxPredictionGain_fx, maxPredGain_fx ); - } - } - } - } - - /* individual decision for each channel */ - FOR( ch = 0; ch < CPE_CHANNELS; ch++ ) - { - if ( sts[ch]->mct_chan_mode == MCT_CHAN_MODE_IGNORE ) - { - continue; - } - - Word8 isTCX10; - - IF( EQ_16( sts[ch]->hTcxEnc->tcxMode, TCX_20 ) ) - { - nSubframes = 1; - isTCX10 = 0; - } - ELSE - { - nSubframes = NB_DIV; - isTCX10 = 1; - } - move16(); - move16(); - - FOR( k = 0; k < nSubframes; k++ ) - { - test(); - test(); - test(); - test(); - IF( sts[ch]->hTcxCfg->fIsTNSAllowed && ( individual_decision[k] || mct_on ) && - ( !bWhitenedDomain || sts[ch]->hTcxEnc->bTnsOnWhithenedSpectra[k] ) ) - { - Word16 maxPredGain_fx = -ONE_IN_Q7; // Q7 - move16(); - sts[ch]->hTcxCfg->pCurrentTnsConfig = &sts[ch]->hTcxCfg->tnsConfig[sts[ch]->hTcxEnc->transform_type[k] == TCX_20][( k == 0 ) && ( sts[ch]->last_core == ACELP_CORE )]; - - FOR( iFilter = sub( sts[ch]->hTcxCfg->pCurrentTnsConfig->nMaxFilters, 1 ); iFilter >= 0; iFilter-- ) - { - STnsFilter *pFilter; - struct TnsParameters const *pTnsParameters; - pFilter = sts[ch]->hTcxEnc->tnsData[k].filter + iFilter; - pTnsParameters = sts[ch]->hTcxCfg->pCurrentTnsConfig->pTnsParameters + iFilter; - - maxPredGain_fx = s_max( maxPredGain_fx, pFilter->predictionGain ); - test(); - IF( GT_16( pFilter->predictionGain, pTnsParameters->minPredictionGain ) || GT_16( pFilter->avgSqrCoef, pTnsParameters->minAvgSqrCoef ) ) - { - test(); - test(); - IF( sts[ch]->hTcxEnc->tnsData[k].nFilters > 0 || isTCX10 || LT_16( sts[ch]->hTcxEnc->tcxltp_gain, 19660 ) ) - { - ++sts[ch]->hTcxEnc->tnsData[k].nFilters; - /* When order parameter is evaluated as 0 and change in precision causes the flow to reach here, - this may result in crash later. Changing the filter type here so the order is taken here in further section */ - IF( pFilter->order != 0 ) - { - pFilter->filterType = TNS_FILTER_ON; - move16(); - } - ELSE - { - pFilter->filterType = TNS_FILTER_ON_ZERO; - move16(); - } - } - ELSE - { - Word16 maxEnergyChange_fx = GetTCXMaxenergyChange_ivas_fx( sts[ch]->hTranDet, isTCX10, NSUBBLOCKS, 3 ); - - IF( GE_16( maxEnergyChange_fx, pTnsParameters->minEnergyChange ) ) - { - ++sts[ch]->hTcxEnc->tnsData[k].nFilters; - /* When order parameter is evaluated as 0 and change in precision causes the flow to reach here, - this may result in crash later. Changing the filter type here so the order is taken here in further section */ - IF( pFilter->order != 0 ) - { - pFilter->filterType = TNS_FILTER_ON; - move16(); - } - ELSE - { - pFilter->filterType = TNS_FILTER_ON_ZERO; - move16(); - } - } - ELSE - { - pFilter->filterType = TNS_FILTER_OFF; - move16(); - } - } - } - ELSE IF( sts[ch]->hTcxEnc->tnsData[k].nFilters > 0 ) /* If a previous filter is turned on */ - { - pFilter->filterType = TNS_FILTER_ON_ZERO; - move16(); - ++sts[ch]->hTcxEnc->tnsData[k].nFilters; - } - ELSE - { - pFilter->filterType = TNS_FILTER_OFF; - move16(); - } - } - - IF( ( sts[ch]->hTcxEnc->tnsData[k].nFilters > 0 ) ) - { - sts[ch]->hTcxEnc->fUseTns[k] = 1; - } - ELSE - { - sts[ch]->hTcxEnc->fUseTns[k] = 0; - } - move16(); - test(); - test(); - IF( !bWhitenedDomain && LT_16( maxPredGain_fx, TNS_GAIN_THRESHOLD_FOR_WHITE_FX_IN_Q7 ) && NE_16( sts[ch]->hTcxEnc->transform_type[k], TCX_5 ) ) - { - sts[ch]->hTcxEnc->fUseTns[k] = 0; - move16(); - sts[ch]->hTcxEnc->bTnsOnWhithenedSpectra[k] = 1; - move16(); - sts[ch]->hTcxEnc->tnsData[k].nFilters = 0; - move16(); - FOR( iFilter = sub( sts[ch]->hTcxCfg->pCurrentTnsConfig->nMaxFilters, 1 ); iFilter >= 0; iFilter-- ) - { - ClearTnsFilterCoefficients( sts[ch]->hTcxEnc->tnsData[k].filter + iFilter ); - sts[ch]->hTcxEnc->tnsData[k].filter[iFilter].filterType = TNS_FILTER_OFF; - move16(); - } - } - maxPredictionGain_fx = s_max( maxPredictionGain_fx, maxPredGain_fx ); - } - } - } - - - /* we have the decision, set filter data accordingly */ - FOR( ch = 0; ch < CPE_CHANNELS; ch++ ) - { - if ( EQ_16( sts[ch]->mct_chan_mode, MCT_CHAN_MODE_IGNORE ) ) - { - continue; - } - - IF( EQ_16( sts[ch]->hTcxEnc->tcxMode, TCX_20 ) ) - { - nSubframes = 1; - } - ELSE - { - nSubframes = NB_DIV; - } - move16(); - FOR( k = 0; k < nSubframes; k++ ) - { - test(); - test(); - IF( sts[ch]->hTcxCfg->fIsTNSAllowed && ( !bWhitenedDomain || sts[ch]->hTcxEnc->bTnsOnWhithenedSpectra[k] ) ) - { - sts[ch]->hTcxCfg->pCurrentTnsConfig = &sts[ch]->hTcxCfg->tnsConfig[sts[ch]->hTcxEnc->transform_type[k] == TCX_20][( k == 0 ) && ( sts[ch]->last_core == ACELP_CORE )]; - - FOR( iFilter = sub( sts[ch]->hTcxCfg->pCurrentTnsConfig->nMaxFilters, 1 ); iFilter >= 0; iFilter-- ) - { - STnsFilter *pFilter; - pFilter = sts[ch]->hTcxEnc->tnsData[k].filter + iFilter; - SWITCH( pFilter->filterType ) - { - case TNS_FILTER_OFF: - ClearTnsFilterCoefficients( sts[ch]->hTcxEnc->tnsData[k].filter + iFilter ); - BREAK; - case TNS_FILTER_ON_ZERO: - /* Since TNS filter of order 0 is not allowed we have to signal in the stream filter of order 1 with the 0th coefficient equal to 0 */ - ClearTnsFilterCoefficients( pFilter ); - pFilter->order = 1; - move16(); - BREAK; - } - } - } - } - } - - /* Apply filters, loop over channels */ - FOR( ch = 0; ch < CPE_CHANNELS; ch++ ) - { - st = sts[ch]; - if ( st->mct_chan_mode == MCT_CHAN_MODE_IGNORE ) - { - continue; - } - - IF( EQ_16( st->hTcxEnc->tcxMode, TCX_20 ) ) - { - nSubframes = 1; - } - ELSE - { - nSubframes = NB_DIV; - } - move16(); - - FOR( k = 0; k < nSubframes; k++ ) - { - test(); - test(); - test(); - test(); - IF( bWhitenedDomain && ( ch > 0 ) && /* test for identical TNS filter data in both channels */ - sts[0]->hTcxCfg->fIsTNSAllowed && sts[0]->hTcxEnc->fUseTns[k] && - sts[1]->hTcxCfg->fIsTNSAllowed && sts[1]->hTcxEnc->fUseTns[k] ) - { - Word16 equalFilterData = 0; - move16(); - test(); - test(); - if ( EQ_16( sts[0]->hTcxCfg->pCurrentTnsConfig->nMaxFilters, sts[1]->hTcxCfg->pCurrentTnsConfig->nMaxFilters ) && - EQ_16( sts[0]->hTcxEnc->bTnsOnWhithenedSpectra[k], sts[1]->hTcxEnc->bTnsOnWhithenedSpectra[k] ) && - EQ_16( sts[0]->hTcxEnc->tnsData[k].nFilters, sts[1]->hTcxEnc->tnsData[k].nFilters ) ) - { - equalFilterData = 1; - move16(); - } - - IF( equalFilterData ) - { - FOR( iFilter = sub( st->hTcxCfg->pCurrentTnsConfig->nMaxFilters, 1 ); iFilter >= 0; iFilter-- ) - { - const Word16 *pDataCh0 = (const Word16 *) &sts[0]->hTcxEnc->tnsData[k].filter[iFilter]; - const Word16 *pDataCh1 = (const Word16 *) &sts[1]->hTcxEnc->tnsData[k].filter[iFilter]; - Word16 i = 2 + TNS_MAX_FILTER_ORDER; /* excl. informative float data. Portable? */ - - move16(); - test(); - WHILE( ( i >= 0 ) && EQ_16( pDataCh0[i], pDataCh1[i] ) ) - { - i = sub( i, 1 ); - } - if ( i >= 0 ) - { - equalFilterData = 0; - move16(); - break; - } - } - IF( equalFilterData ) - { - st->hTcxEnc->tnsData[k].nFilters = i_mult( st->hTcxEnc->tnsData[k].nFilters, -1 ); /* signals common TNS */ - } - } - } - test(); - test(); - IF( st->hTcxCfg->fIsTNSAllowed && ( !bWhitenedDomain || st->hTcxEnc->bTnsOnWhithenedSpectra[k] ) ) - { - L_spec = st->hTcxCfg->pCurrentTnsConfig->iFilterBorders[0]; - move16(); - spectrum_fx = st->hTcxEnc->spectrum_fx[k]; - /* If TNS should be used then get the residual after applying it inplace in the spectrum */ - IF( st->hTcxEnc->fUseTns[k] ) - { - st->hTcxCfg->pCurrentTnsConfig = &st->hTcxCfg->tnsConfig[st->hTcxEnc->transform_type[k] == TCX_20][( k == 0 ) && ( st->last_core == ACELP_CORE )]; - - ApplyTnsFilter( st->hTcxCfg->pCurrentTnsConfig, &st->hTcxEnc->tnsData[k], spectrum_fx, 1 ); - } - - IF( EQ_16( st->hTcxEnc->transform_type[k], TCX_5 ) ) - { - tcx5TnsUngrouping_fx( shr( L_frame, 2 ), shr( L_spec, 1 ), st->hTcxEnc->spectrum_fx[k], ENC ); - } - - st->hTcxEnc->tnsData[k].tnsOnWhitenedSpectra = st->hTcxEnc->bTnsOnWhithenedSpectra[k]; - - EncodeTnsData_ivas_fx( st->hTcxCfg->pCurrentTnsConfig, &st->hTcxEnc->tnsData[k], param_core[ch] + k * NPRM_DIV + 1 + NOISE_FILL_RANGES + LTPSIZE, tnsSize[ch] + k, tnsBits[ch] + k ); - } - - IF( EQ_16( st->hTcxEnc->transform_type[k], TCX_5 ) ) - { - tcx5SpectrumInterleaving_fx( st->hTcxCfg->tcx5SizeFB, st->hTcxEnc->spectrum_fx[k] ); - tcx5SpectrumInterleaving_fx( st->hTcxCfg->tcx5SizeFB, mdst_spectrum_fx[ch][k] ); - } - } - } - return; -} diff --git a/lib_enc/cod_tcx_fx.c b/lib_enc/cod_tcx_fx.c index 890f98e12e9b5fa6b4f750cca9d3811999a14db6..e6fc25e367957fef69abbe7dc45e9035bd516f31 100644 --- a/lib_enc/cod_tcx_fx.c +++ b/lib_enc/cod_tcx_fx.c @@ -16,23 +16,23 @@ #include "prot_fx_enc.h" #ifdef IVAS_FLOAT_FIXED_CONVERSIONS #include -#include "prot.h" -#include "ivas_prot.h" #include "ivas_prot_fx.h" #include "ivas_rom_com_fx.h" -#include "prot.h" #endif #ifdef DEBUGGING #include "debug.h" #endif +#define SIMILAR_TNS_THRESHOLD_FX_IN_Q15 ( 1311 ) +#define TNS_GAIN_THRESHOLD_FOR_WHITE_FX_IN_Q7 ( 384 ) +#define TNS_GAIN_THRESHOLD_FOR_WHITE_FX_IN_Q23 ( 25165824 ) /* Up to the Autocorrelation it is the same code as in GetMDCT, with the difference in the parameters in the call to tcx_windowing_analysis */ void HBAutocorrelation_fx( TCX_CONFIG_HANDLE hTcxCfg, /* i : configuration of TCX */ Word16 left_overlap_mode, /* input: overlap mode of left window half */ Word16 right_overlap_mode, /* input: overlap mode of right window half */ - Word16 speech[], /* input: speech[-LFAC..L_frame+LFAC] */ + Word16 speech[], /* input: speech[-LFAC..L_frame+LFAC] Qx*/ Word16 L_frame, /* input: frame length */ Word32 *r, /* output: autocorrelations vector */ Word16 m /* input : order of LP filter */ @@ -45,6 +45,7 @@ void HBAutocorrelation_fx( #ifdef BASOP_NOGLOB_DECLARE_LOCAL Flag Overflow = 0; + move32(); #endif /*-----------------------------------------------------------* @@ -64,70 +65,42 @@ void HBAutocorrelation_fx( move16(); L_sum = L_deposit_l( 0 ); Overflow = 0; - move16(); + move32(); FOR( i = 0; i < len; i += 1 ) { /* Test Addition */ -#ifdef BASOP_NOGLOB /* Critical Overflow, all operations below needs to check for Overflow if we want to ensure bit exactness */ L_mac0_o( L_sum, y[i], y[i], &Overflow ); -#else /* BASOP_NOGLOB */ - L_mac0( L_sum, y[i], y[i] ); -#endif /* BASOP_NOGLOB */ IF( Overflow ) { Overflow = 0; - move16(); + move32(); shift = 1; move16(); L_tmp = L_msu0( 0, y[i], y[i] ); L_tmp = L_shr( L_tmp, 1 ); -#ifdef BASOP_NOGLOB /* Only the sub can overflow if the current L_sum is negative and already close to MIN */ L_sum = L_add( L_shr( L_sub_o( L_sum, 1, &Overflow ), 1 ), 1 ); -#else - L_sum = L_add( L_shr( L_sub( L_sum, 1 ), 1 ), 1 ); -#endif -#ifdef BASOP_NOGLOB /* Critical Overflow */ L_sum = L_sub_o( L_sum, L_tmp, &Overflow ); -#else - L_sum = L_sub( L_sum, L_tmp ); -#endif - FOR( j = add( i, 1 ); j < len; j++ ) + FOR( j = i + 1; j < len; j++ ) { L_tmp = L_msu0( 0, y[j], y[j] ); L_tmp = L_shr( L_tmp, shift ); /* Test Addition */ -#ifdef BASOP_NOGLOB /* Critical Overflow */ L_sub_o( L_sum, L_tmp, &Overflow ); -#else /* BASOP_NOGLOB */ - L_sub( L_sum, L_tmp ); -#endif /* BASOP_NOGLOB */ IF( Overflow ) { Overflow = 0; - move16(); + move32(); shift = add( shift, 1 ); L_tmp = L_shr( L_tmp, 1 ); -#ifdef BASOP_NOGLOB /* Critical Overflow */ L_sum = L_add( L_shr( L_sub_o( L_sum, 1, &Overflow ), 1 ), 1 ); -#else - L_sum = L_add( L_shr( L_sub( L_sum, 1 ), 1 ), 1 ); -#endif } -#ifdef BASOP_NOGLOB /* Critical Overflow */ L_sum = L_sub_o( L_sum, L_tmp, &Overflow ); -#else - L_sum = L_sub( L_sum, L_tmp ); -#endif } BREAK; } /* Perform Addition */ -#ifdef BASOP_NOGLOB /* Critical Overflow */ L_sum = L_mac0_o( L_sum, y[i], y[i], &Overflow ); -#else - L_sum = L_mac0( L_sum, y[i], y[i] ); -#endif } /* scale signal to avoid overflow in autocorrelation */ @@ -652,17 +625,19 @@ void TNSAnalysis_fx( TCX_CONFIG_HANDLE hTcxCfg, /* i : configuration of TCX */ Word16 L_frame, /* input: frame length */ Word16 L_spec, - Word16 tcxMode, /* input: TCX mode for the frame/subframe - TCX20 | TCX10 | TCX 5 (meaning 2 x TCX 5) */ - Word8 isAfterACELP, /* input: Flag indicating if the last frame was ACELP. For the second TCX subframe it should be 0 */ - Word32 spectrum[], /* input: MDCT spectrum */ - STnsData *pTnsData, /* output: Tns data */ - Word8 *pfUseTns, /* output: Flag indicating if TNS is used */ - Word16 *predictionGain ) + Word16 tcxMode, /* input: TCX mode for the frame/subframe - TCX20 | TCX10 | TCX 5 (meaning 2 x TCX 5) */ + Word8 isAfterACELP, /* input: Flag indicating if the last frame was ACELP. For the second TCX subframe it should be 0 */ + Word32 spectrum[], /* input: MDCT spectrum Qx*/ + STnsData *pTnsData, /* output: Tns data */ + Word8 *pfUseTns, /* output: Flag indicating if TNS is used */ + Word16 *predictionGain /*Q7*/ +) { Word32 buff[8]; Word16 tmp = 0; /* initialization only to avoid compiler warning, not counted */ Word16 tmp2 = 0; /* initialization only to avoid compiler warning, not counted */ - + move16(); + move16(); /* Init TNS */ *pfUseTns = 0; @@ -670,8 +645,7 @@ void TNSAnalysis_fx( IF( hTcxCfg->fIsTNSAllowed != 0 ) { - hTcxCfg->pCurrentTnsConfig = &hTcxCfg->tnsConfig[sub( tcxMode, TCX_20 ) == 0][isAfterACELP]; - test(); + hTcxCfg->pCurrentTnsConfig = &hTcxCfg->tnsConfig[( tcxMode - TCX_20 ) == 0][isAfterACELP]; L_spec = hTcxCfg->pCurrentTnsConfig->iFilterBorders[0]; move16(); @@ -756,8 +730,7 @@ void TNSAnalysis_ivas_fx( IF( hTcxCfg->fIsTNSAllowed != 0 ) { - hTcxCfg->pCurrentTnsConfig = &hTcxCfg->tnsConfig[sub( transform_type, TCX_20 ) == 0][isAfterACELP]; - test(); + hTcxCfg->pCurrentTnsConfig = &hTcxCfg->tnsConfig[( transform_type - TCX_20 ) == 0][isAfterACELP]; L_spec = hTcxCfg->pCurrentTnsConfig->iFilterBorders[0]; move16(); @@ -818,8 +791,8 @@ void TNSAnalysis_ivas_fx( void ShapeSpectrum_fx( TCX_CONFIG_HANDLE hTcxCfg, /* i : configuration of TCX */ - Word16 A[], /* input: quantized coefficients NxAz_q[M+1] */ - Word16 gainlpc[], /* output: MDCT gains for the previous frame */ + Word16 A[], /* input: quantized coefficients NxAz_q[M+1] Q = 14 - norm(A[0])*/ + Word16 gainlpc[], /* output: MDCT gains for the previous frame Q(15-gainlpc_e)*/ Word16 gainlpc_e[], /* output: MDCT gains exponents */ Word16 L_frame_glob, /* input: frame length */ Word16 L_spec, @@ -834,6 +807,8 @@ void ShapeSpectrum_fx( Word16 gainlpc_noinv_e[FDNS_NPTS]; Word16 i; Word32 max_low_pre = 0, max_high_pre = 0; + move32(); + move32(); TCX_ENC_HANDLE hTcxEnc = st->hTcxEnc; /*-----------------------------------------------------------* @@ -875,6 +850,7 @@ void ShapeSpectrum_fx( IF( st->enablePlcWaveadjust ) { hTcxCfg->SFM2 = SFM_Cal_fx( spectrum, s_min( 200, L_frame ) ); + move32(); } test(); @@ -897,7 +873,7 @@ void ShapeSpectrum_fx( max_high_pre = 0; move32(); - for ( i = 0; i < L_spec - L_frame; i++ ) + FOR( i = 0; i < L_spec - L_frame; i++ ) { Word32 tmp = L_abs( spectrum[L_frame + i] ); if ( GT_32( tmp, max_high_pre ) ) @@ -925,6 +901,8 @@ void ShapeSpectrum_fx( /* reduce the peaks in the IGF region, to make life of the core-coder easier... */ test(); + test(); + test(); IF( ( EQ_32( st->total_brate, ACELP_9k60 ) && EQ_16( st->bwidth, SWB ) ) || ( EQ_32( st->total_brate, ACELP_13k20 ) && EQ_16( st->bwidth, SWB ) ) ) { @@ -967,7 +945,7 @@ void ShapeSpectrum_fx( max_low1 = 0; move32(); - FOR( i = 0; i < sub( L_frame, sf_width ); i++ ) + FOR( i = 0; i < ( L_frame - sf_width ); i++ ) { Word32 tmp = L_abs( spectrum[L_frame - sf_width - 1 - i] ); if ( GT_32( tmp, max_low1 ) ) @@ -975,7 +953,7 @@ void ShapeSpectrum_fx( max_low1 = tmp; move32(); } - if ( tmp > max_low2 ) + if ( GT_32( tmp, max_low2 ) ) { dist_low = add( sf_width, i ); } @@ -987,10 +965,10 @@ void ShapeSpectrum_fx( move32(); dist_high = 0; move16(); - FOR( i = 0; i < sub( L_spec, L_frame ); i++ ) + FOR( i = 0; i < ( L_spec - L_frame ); i++ ) { Word32 tmp = L_abs( spectrum[L_frame + i] ); - if ( GT_32( tmp, max_high ) ) + IF( GT_32( tmp, max_high ) ) { max_high = tmp; move32(); @@ -1036,6 +1014,7 @@ void ShapeSpectrum_fx( FOR( i = 0; i < sub( L_spec, L_frame ); i++ ) { spectrum[L_frame + i] = Mpy_32_16_1( spectrum[L_frame + i], fac ); + move32(); } } } @@ -1052,11 +1031,11 @@ void ShapeSpectrum_fx( void ShapeSpectrum_ivas_fx( TCX_CONFIG_HANDLE hTcxCfg, /* i : configuration of TCX */ Word16 A[], /* input: quantized coefficients NxAz_q[M+1], Q = 14 - norm(A[0]) */ - Word16 gainlpc[], /* output: MDCT gains for the previous frame */ + Word16 gainlpc[], /* output: MDCT gains for the previous frame Q(15-gainlpc_e)*/ Word16 gainlpc_e[], /* output: MDCT gains exponents */ Word16 L_frame_glob, /* input: frame length */ Word16 L_spec, - Word32 spectrum[], /* i/o: MDCT spectrum */ + Word32 spectrum[], /* i/o: MDCT spectrum Q(31-spectrum_e) */ Word16 *spectrum_e, /* i/o: MDCT spectrum exponent */ Word8 pfUseTns, /* output: Flag indicating if TNS is used */ Encoder_State *st, @@ -1075,6 +1054,13 @@ void ShapeSpectrum_ivas_fx( TCX_ENC_HANDLE hTcxEnc = st->hTcxEnc; move32(); move32(); + Word32 total_brate = st->total_brate; + move32(); + if ( EQ_16( st->element_mode, IVAS_CPE_MDCT ) ) + { + total_brate = st->element_brate; + move32(); + } /*-----------------------------------------------------------* * Init * @@ -1098,7 +1084,7 @@ void ShapeSpectrum_ivas_fx( { L_frame = add( L_frame, hTcxCfg->tcx_offset ); L_spec = add( L_spec, shr( hTcxCfg->tcx_coded_lines, 2 ) ); - IF( hTcxCfg->lfacNext < 0 ) + if ( hTcxCfg->lfacNext < 0 ) { L_frame = sub( L_frame, hTcxCfg->lfacNext ); move16(); @@ -1110,7 +1096,7 @@ void ShapeSpectrum_ivas_fx( tcxGetNoiseFillingTilt( A, M, L_frame, - ( GE_32( st->total_brate, ACELP_13k20 ) && st->rf_mode == 0 ), + ( GE_32( total_brate, ACELP_13k20 ) && st->rf_mode == 0 ), &hTcxEnc->noiseTiltFactor ); /* Calculate Spectrum Flatness Measure for the TCX Concealment */ @@ -1121,7 +1107,7 @@ void ShapeSpectrum_ivas_fx( } test(); - IF( LE_32( st->total_brate, ACELP_13k20 ) && EQ_16( st->bwidth, SWB ) ) + IF( LE_32( total_brate, ACELP_13k20 ) && EQ_16( st->bwidth, SWB ) ) { max_low_pre = 0; move32(); @@ -1160,19 +1146,18 @@ void ShapeSpectrum_ivas_fx( test(); IF( NE_16( len, L_spec ) && LT_16( add( q_spectrum, 1 ), sub( 31, *spectrum_e ) ) ) { - scale_sig32( spectrum + len, sub( L_spec, len ), sub( add( q_spectrum, 1 ), sub( 31, *spectrum_e ) ) ); + scale_sig32( spectrum + len, sub( L_spec, len ), sub( add( q_spectrum, 1 ), sub( 31, *spectrum_e ) ) ); // Q31 } ELSE IF( NE_16( len, L_spec ) && GT_16( add( q_spectrum, 1 ), sub( 31, *spectrum_e ) ) ) { - scale_sig32( spectrum, len, sub( sub( 31, *spectrum_e ), add( q_spectrum, 1 ) ) ); + scale_sig32( spectrum, len, sub( sub( 31, *spectrum_e ), add( q_spectrum, 1 ) ) ); // Q(30-specturm_e) q_spectrum = sub( 31 - 1, *spectrum_e ); } FOR( i = L_frame; i < L_spec; i++ ) { W_tmp = W_mult0_32_32( spectrum[i], sns_int_scf[hTcxCfg->psychParamsCurrent->nBands - 1] ); - W_tmp = W_shr( W_tmp, Q16 ); - spectrum[i] = W_extract_l( W_tmp ); + spectrum[i] = W_extract_h( W_shl( W_tmp, Q16 ) ); move32(); } *spectrum_e = sub( 31 - 1, q_spectrum ); // As the output spectrum from sns_shape_spectrum_fx has Q = q_spectrum + 1 @@ -1198,7 +1183,7 @@ void ShapeSpectrum_ivas_fx( /* reduce the peaks in the IGF region, to make life of the core-coder easier... */ test(); - IF( LE_32( st->total_brate, ACELP_13k20 ) && EQ_16( st->bwidth, SWB ) ) + IF( LE_32( total_brate, ACELP_13k20 ) && EQ_16( st->bwidth, SWB ) ) { Word16 sf_width; Word16 dist_low, dist_high; @@ -1247,7 +1232,7 @@ void ShapeSpectrum_ivas_fx( max_low1 = tmp; move32(); } - IF( GT_32( tmp, max_low2 ) ) + if ( GT_32( tmp, max_low2 ) ) { dist_low = add( sf_width, i ); } @@ -1259,10 +1244,10 @@ void ShapeSpectrum_ivas_fx( move32(); dist_high = 0; move16(); - FOR( i = 0; i < sub( L_spec, L_frame ); i++ ) + FOR( i = 0; i < ( L_spec - L_frame ); i++ ) { Word32 tmp = L_abs( spectrum[L_frame + i] ); - if ( GT_32( tmp, max_high ) ) + IF( GT_32( tmp, max_high ) ) { max_high = tmp; move32(); @@ -1526,15 +1511,15 @@ static Word16 GetTransWidth_ivas_fx( static void EstimateTCXNoiseLevel_ivas_fx( Encoder_State *st, /* i : encoder state handle */ - Word32 x_orig[], /* i : shaped MDCT spectrum */ + Word32 x_orig[], /* i : shaped MDCT spectrum Q(31-x_orig_e) */ Word16 x_orig_e, /* i : shaped MDCT spectrum exponent */ Word32 spectrum[], /* i/o: quantized MDCT spectrum */ - const Word16 gain_tcx, /* i : global gain */ + const Word16 gain_tcx, /* i : global gain Q(15-gain_tcx_e) */ const Word16 gain_tcx_e, /* i : global gain exponent */ const Word16 L_frame, /* i : frame length */ const Word16 noiseFillingBorder, /* i : noise filling border */ const Word16 hm_active, /* i : flag indicating if the harmonic model is active */ - Word16 *fac_ns, /* o : noise filling level, Q15 */ + Word16 *fac_ns, /* o : noise filling level, fac_ns_q */ Word16 *fac_ns_q /* o : quantized noise filling level, Q0 */ ) { @@ -1628,7 +1613,7 @@ void QuantizeSpectrum_ivas_fx( Encoder_State *st, /* i/o: encoder state structure */ const Word16 A_fx[], /* i : quantized coefficients NxAz_q[M+1], Q = 14 - norm_s(A_fx[0]) */ const Word16 Aqind[], /* i : frame-independent quantized coefficients (M+1) */ - Word16 gainlpc_fx[], /* i : MDCT gains of the previous frame */ + Word16 gainlpc_fx[], /* i : MDCT gains of the previous frame Q(15-gainlpc_e) */ Word16 gainlpc_e[], /* i : exponents of MDCT gains of the previous frame */ Word16 synth[], /* o : synthesis buffer, Q0 */ const Word16 nb_bits, /* i : bit budget */ @@ -1665,6 +1650,12 @@ void QuantizeSpectrum_ivas_fx( QuantizeTCXSpectrum_fx( st, frame_cnt, hTcxEnc->spectrum_fx[frame_cnt], hTcxEnc->spectrum_e[frame_cnt], gainlpc_fx, gainlpc_e, Aqind, tnsSize, nb_bits, vad_hover_flag, &L_frameTCX, &L_frame, &L_spec, &tcx_offset, &noiseFillingBorder, quantized_spectrum_fx, &quantized_spectrum_e, hm_cfg, &hm_active, lf_deemph_fact_fx, &nf_seed, &ener_fx, &ener_e, &gain_tcx_fx, &gain_tcx_e, prm ); + if ( hTcxEnc->spectrum_e[frame_cnt] < 0 ) + { + /*buffer is already scaled inside QuantizeTCXSpectrum_fx*/ + hTcxEnc->spectrum_e[frame_cnt] = 0; + move16(); + } Word16 s1 = sub( getScaleFactor32( st->hTcxEnc->spectrum_fx[frame_cnt], L_frame ), 6 ); Word16 s2 = getScaleFactor32( quantized_spectrum_fx, s_max( L_frame, L_spec ) ); @@ -1707,8 +1698,8 @@ void QuantizeSpectrum_ivas_fx( void EstimateStereoTCXNoiseLevel_fx( Encoder_State **sts, /* i : state handle */ - Word32 *q_spectrum[CPE_CHANNELS][NB_DIV], /* i : quantized MDCT spectrum */ - Word16 gain_tcx[][NB_DIV], /* i : global gain */ + Word32 *q_spectrum[CPE_CHANNELS][NB_DIV], /* i : quantized MDCT spectrum Qx */ + Word16 gain_tcx[][NB_DIV], /* i : global gain Q(15-gain_tcx_e) */ Word16 gain_tcx_e[][NB_DIV], /* i : global gain exponent */ Word16 L_frame[][NB_DIV], /* i : frame length */ Word16 noiseFillingBorder[][NB_DIV], /* i : noise filling border */ @@ -1726,6 +1717,10 @@ void EstimateStereoTCXNoiseLevel_fx( Word16 *fac_ns_q; Word32 total_brate; +#ifdef MSAN_FIX + set32_fx( combined_q_spectrum, 0, N_MAX ); +#endif + FOR( ch = 0; ch < CPE_CHANNELS; ch++ ) { Encoder_State *st = sts[ch]; @@ -1742,9 +1737,9 @@ void EstimateStereoTCXNoiseLevel_fx( move16(); } - if ( ignore_chan[ch] ) + IF( ignore_chan[ch] ) { - continue; + CONTINUE; } IF( EQ_16( st->element_mode, IVAS_CPE_MDCT ) && !MCT_flag ) @@ -1811,8 +1806,8 @@ void EstimateStereoTCXNoiseLevel_fx( test(); IF( L_tmp != 0 || L_tmp1 != 0 ) { - scale_sig32( hTcxEnc->spectrum_fx[n], L_frame[ch][n], -Q1 ); - scale_sig32( combined_q_spectrum, L_frame[ch][n], -Q1 ); + scale_sig32( hTcxEnc->spectrum_fx[n], L_frame[ch][n], -Q1 ); // Q(31-(spectrum_e+1) + scale_sig32( combined_q_spectrum, L_frame[ch][n], -Q1 ); // Q(31-(spectrum_e+1) hTcxEnc->spectrum_e[n] = add( hTcxEnc->spectrum_e[n], Q1 ); move16(); } @@ -1842,6 +1837,7 @@ void EstimateStereoTCXNoiseLevel_fx( ELSE { hTcxEnc->noiseLevelMemory_cnt = sub( -1, hTcxEnc->noiseLevelMemory_cnt ); + move16(); } } ELSE @@ -1861,7 +1857,7 @@ void QuantizeSpectrum_fx( TCX_CONFIG_HANDLE hTcxCfg, /* i : configuration of TCX */ Word16 A[], /* input: quantized coefficients NxAz_q[M+1] */ Word16 Aqind[], /* input: frame-independent quantized coefficients (M+1) */ - Word16 gainlpc[], /* input: MDCT gains of the previous frame */ + Word16 gainlpc[], /* input: MDCT gains of the previous frame Q(15-gainlpc_e)*/ Word16 gainlpc_e[], /* input: MDCT gains exponents */ Word16 synth[], Word16 L_frame_glob, /* input: frame length */ @@ -1869,7 +1865,7 @@ void QuantizeSpectrum_fx( Word16 L_spec, Word16 nb_bits, /*input: bit budget*/ Word8 tcxonly, /*input: only TCX flag*/ - Word32 spectrum[], /* i/o: MDCT spectrum, input is shaped MDCT spectrum */ + Word32 spectrum[], /* i/o: MDCT spectrum, input is shaped MDCT spectrum Q(31-spectrum_e) */ Word16 *spectrum_e, /* i/o: MDCT spectrum exponent */ STnsData *pTnsData, /* input: Tns data */ Word8 fUseTns, /* input: Flag indicating if TNS is used */ @@ -2087,6 +2083,7 @@ void QuantizeSpectrum_fx( FOR( i = st->hIGFEnc->infoStopLine; i < L_frameTCX; i++ ) { spectrum[i] = L_deposit_l( 0 ); + move32(); } /*-----------------------------------------------------------* @@ -2292,11 +2289,8 @@ void QuantizeSpectrum_fx( tmp1 = BASOP_Util_Divide1616_Scale( sqTargetBits, tmp1, &tmp2 ); BASOP_SATURATE_WARNING_OFF_EVS -#ifdef BASOP_NOGLOB hTcxEnc->tcx_target_bits_fac = shl_o( mult( hTcxEnc->tcx_target_bits_fac, tmp1 ), tmp2, &Overflow ); -#else /* BASOP_NOGLOB */ - hTcxEnc->tcx_target_bits_fac = shl( mult( hTcxEnc->tcx_target_bits_fac, tmp1 ), tmp2 ); -#endif /* BASOP_NOGLOB */ + move16(); BASOP_SATURATE_WARNING_ON_EVS if ( GT_16( hTcxEnc->tcx_target_bits_fac, 0x5000 ) ) @@ -2415,11 +2409,7 @@ void QuantizeSpectrum_fx( } /* Limit low sqGain for avoiding saturation of the gain quantizer*/ -#ifdef BASOP_NOGLOB tmp1 = mult_r( shl_o( L_spec, 5, &Overflow ), 26214 /*128.f/NORM_MDCT_FACTOR Q15*/ ); -#else - tmp1 = mult_r( shl( L_spec, 5 ), 26214 /*128.f/NORM_MDCT_FACTOR Q15*/ ); -#endif s = 15 - 5 - 7; IF( L_spec >= 1024 ) { @@ -2433,11 +2423,7 @@ void QuantizeSpectrum_fx( IF( tmp2 >= 0 ) { BASOP_SATURATE_WARNING_OFF_EVS; -#ifdef BASOP_NOGLOB tmp2 = sub_sat( sqGain, shr_sat( tmp1, tmp2 ) ); -#else - tmp2 = sub( sqGain, shr( tmp1, tmp2 ) ); -#endif BASOP_SATURATE_WARNING_ON_EVS; } ELSE @@ -2490,11 +2476,7 @@ void QuantizeSpectrum_fx( spectrum[i] = L_mult( sqQ[i], 1 << ( 30 - SPEC_EXP_DEC ) ); move32(); /* noise filling seed */ -#ifdef BASOP_NOGLOB tmp32 = L_macNs_co( tmp32, abs_s( sqQ[i] ), i, &Carry, &Overflow ); -#else /* BASOP_NOGLOB */ - tmp32 = L_macNs( tmp32, abs_s( sqQ[i] ), i ); -#endif /* BASOP_NOGLOB */ } *spectrum_e = SPEC_EXP_DEC; move16(); @@ -2529,7 +2511,7 @@ void QuantizeSpectrum_fx( tmp8 = 1; move16(); - if ( EQ_16( st->last_core, ACELP_CORE ) ) + if ( st->last_core == ACELP_CORE ) { tmp8 = 0; move16(); @@ -2598,7 +2580,7 @@ void QuantizeSpectrum_fx( /*-----------------------------------------------------------* * Quantize TCX gain * *-----------------------------------------------------------*/ - + test(); IF( GE_32( st->total_brate, ACELP_13k20 ) && st->rf_mode == 0 ) { QuantizeGain( L_spec, &gain_tcx, &gain_tcx_e, &prm[0] ); @@ -2695,6 +2677,7 @@ void QuantizeSpectrum_fx( { /* noise filling start bin */ i = shr( L_frame, 3 ); + test(); IF( GE_32( st->total_brate, ACELP_13k20 ) && st->rf_mode == 0 ) { i = idiv1616U( L_frame, 6 ); @@ -2736,6 +2719,7 @@ void QuantizeSpectrum_fx( IF( EQ_16( prm[NOISE_FILL_RANGES], 1 ) ) { hTcxEnc->noiseLevelMemory_cnt = add( 1, abs_s( hTcxEnc->noiseLevelMemory_cnt ) ); /* update counter */ + move16(); } ELSE { @@ -2756,6 +2740,7 @@ void QuantizeSpectrum_fx( tmp1 = sub( -1, hTcxEnc->noiseLevelMemory_cnt ); } hTcxEnc->noiseLevelMemory_cnt = tmp1; + move16(); } ELSE { @@ -2790,6 +2775,7 @@ void QuantizeSpectrum_fx( * Noise Filling. * *-----------------------------------------------------------*/ + test(); /* Replication of ACELP formant enhancement for low rates */ IF( LT_32( st->total_brate, ACELP_13k20 ) || st->rf_mode != 0 ) { @@ -2800,6 +2786,7 @@ void QuantizeSpectrum_fx( { tmp1 = 0; move16(); + test(); if ( GE_32( st->total_brate, ACELP_13k20 ) && st->rf_mode == 0 ) { tmp1 = 1; @@ -2814,7 +2801,7 @@ void QuantizeSpectrum_fx( tcx_noise_filling( spectrum, *spectrum_e, nf_seed /* seed */, i, noiseFillingSize, noiseTransWidth, L_frame, hTcxEnc->noiseTiltFactor, fac_ns, NULL, st->element_mode ); } - + test(); IF( LT_32( st->total_brate, ACELP_13k20 ) || st->rf_mode != 0 ) { /* partially recompute global gain (energy part), taking noise filling and formant enhancement into account */ @@ -2849,14 +2836,14 @@ void QuantizeSpectrum_fx( /*-----------------------------------------------------------* * Apply gain * *-----------------------------------------------------------*/ - IF( EQ_16( st->hTcxCfg->coder_type, INACTIVE ) ) + IF( st->hTcxCfg->coder_type == INACTIVE ) { gain_tcx = mult_r( gain_tcx, hTcxCfg->na_scale ); } FOR( i = 0; i < L_spec; i++ ) { - spectrum[i] = Mpy_32_16_1( spectrum[i], gain_tcx ); + spectrum[i] = Mpy_32_16_1( spectrum[i], gain_tcx ); // Q(31-(spectrum_e+gain_tcx_e)) move32(); } *spectrum_e = add( *spectrum_e, gain_tcx_e ); @@ -2896,8 +2883,6 @@ void QuantizeSpectrum_fx( IF( hTcxCfg->fIsTNSAllowed != 0 ) { - test(); - test(); test(); SetTnsConfig( hTcxCfg, sub( L_frame_glob, st->L_frame ) == 0, ( st->last_core == ACELP_CORE ) && ( frame_cnt == 0 ) ); @@ -2931,7 +2916,7 @@ void QuantizeSpectrum_fx( s = getScaleFactor32( spectrum, L_frame ); FOR( i = 0; i < L_frame; i++ ) { - spectrum[i] = L_shl( spectrum[i], s ); + spectrum[i] = L_shl( spectrum[i], s ); // Q(31-(spectrum_e-s)) move32(); } *spectrum_e = sub( *spectrum_e, s ); @@ -3047,11 +3032,7 @@ void QuantizeSpectrum_fx( /* add part of current sub-window overlapping with previous window */ FOR( i = 0; i < L_ola; i++ ) { -#ifdef BASOP_NOGLOB tmpP16[i] = add_sat( tmpP16[i], win[i] ); -#else - tmpP16[i] = add( tmpP16[i], win[i] ); -#endif move16(); } /* copy new sub-window region not overlapping with previous window */ @@ -3115,7 +3096,6 @@ void QuantizeSpectrum_fx( 0 ); - move16(); tmpP16 = xn_buf16 + add( sub( L_win, shr( L_ola, 1 ) ), shr( overlap, 1 ) ); tcx_windowing_synthesis_past_frame( tmpP16, @@ -3130,11 +3110,7 @@ void QuantizeSpectrum_fx( /* add part of current sub-window overlapping with previous window */ FOR( i = 0; i < L_ola; i++ ) { -#ifdef BASOP_NOGLOB tmpP16[i] = add_sat( tmpP16[i], win[i] ); -#else - tmpP16[i] = add( tmpP16[i], win[i] ); -#endif move16(); } @@ -3144,7 +3120,7 @@ void QuantizeSpectrum_fx( L_win ); /* extra folding-out on left side of win, for perfect reconstruction */ - FOR( w = shr( overlap, 1 ); w < overlap; w++ ) + FOR( w = overlap / 2; w < overlap; w++ ) { xn_buf16[overlap - 1 - w] = negate( xn_buf16[w] ); move16(); @@ -3260,11 +3236,7 @@ void QuantizeSpectrum_fx( /* scale output */ FOR( i = 0; i < L_frame; i++ ) { -#ifdef BASOP_NOGLOB xn_buf16[i] = shr_o( xn_buf16[i], Q, &Overflow ); -#else /* BASOP_NOGLOB */ - xn_buf16[i] = shr( xn_buf16[i], Q ); -#endif /* BASOP_NOGLOB */ move16(); } @@ -3324,11 +3296,7 @@ void QuantizeSpectrum_fx( tmp1 = sub( overlap, hTcxCfg->tcx_mdct_window_min_length ); FOR( i = 0; i < tmp1; i++ ) { -#ifdef BASOP_NOGLOB xn_buf16[i] = shl_sat( add_sat( xn_buf16[i], shr_sat( hTcxEnc->old_out_fx[i + nz], tmp2 ) ), TCX_IMDCT_HEADROOM ); -#else - xn_buf16[i] = shl( add( xn_buf16[i], shr( hTcxEnc->old_out_fx[i + nz], tmp2 ) ), TCX_IMDCT_HEADROOM ); -#endif move16(); } @@ -3337,31 +3305,19 @@ void QuantizeSpectrum_fx( FOR( ; i < tmp1; i++ ) { tmp3 = mult_r( shr( hTcxEnc->old_out_fx[i + nz], tmp2 ), hTcxCfg->tcx_mdct_window_minimum[i - overlap + hTcxCfg->tcx_mdct_window_min_length].v.re ); -#ifdef BASOP_NOGLOB xn_buf16[i] = shl_sat( add_sat( xn_buf16[i], tmp3 ), TCX_IMDCT_HEADROOM ); -#else - xn_buf16[i] = shl( add( xn_buf16[i], tmp3 ), TCX_IMDCT_HEADROOM ); -#endif move16(); } FOR( ; i < overlap; i++ ) { tmp3 = mult_r( shr( hTcxEnc->old_out_fx[i + nz], tmp2 ), hTcxCfg->tcx_mdct_window_minimum[overlap - 1 - i].v.im ); -#ifdef BASOP_NOGLOB xn_buf16[i] = shl_sat( add_sat( xn_buf16[i], tmp3 ), TCX_IMDCT_HEADROOM ); -#else - xn_buf16[i] = shl( add( xn_buf16[i], tmp3 ), TCX_IMDCT_HEADROOM ); -#endif move16(); } FOR( ; i < L_frame; i++ ) { -#ifdef BASOP_NOGLOB xn_buf16[i] = shl_sat( xn_buf16[i], TCX_IMDCT_HEADROOM ); -#else - xn_buf16[i] = shl( xn_buf16[i], TCX_IMDCT_HEADROOM ); -#endif move16(); } } @@ -3391,11 +3347,7 @@ void QuantizeSpectrum_fx( BASOP_SATURATE_WARNING_OFF_EVS; FOR( i = 0; i < overlap; i++ ) { -#ifdef BASOP_NOGLOB xn_buf16[i] = shl_sat( add( xn_buf16[i], hTcxEnc->Txnq[i] ), TCX_IMDCT_HEADROOM ); -#else - xn_buf16[i] = shl( add( xn_buf16[i], hTcxEnc->Txnq[i] ), TCX_IMDCT_HEADROOM ); -#endif move16(); } @@ -3403,11 +3355,7 @@ void QuantizeSpectrum_fx( { FOR( ; i < L_frame; i++ ) { -#ifdef BASOP_NOGLOB xn_buf16[i] = shl_sat( xn_buf16[i], TCX_IMDCT_HEADROOM ); -#else - xn_buf16[i] = shl( xn_buf16[i], TCX_IMDCT_HEADROOM ); -#endif move16(); } } @@ -3421,11 +3369,7 @@ void QuantizeSpectrum_fx( BASOP_SATURATE_WARNING_OFF_EVS; FOR( i = 0; i < L_frame; i++ ) { -#ifdef BASOP_NOGLOB xn_buf16[i] = shl_o( xn_buf16[i], TCX_IMDCT_HEADROOM, &Overflow ); -#else /* BASOP_NOGLOB */ - xn_buf16[i] = shl( xn_buf16[i], TCX_IMDCT_HEADROOM ); -#endif move16(); } BASOP_SATURATE_WARNING_ON_EVS; @@ -3546,9 +3490,9 @@ static Word16 DecideTonalSideInfo_fx( void QuantizeTCXSpectrum_fx( Encoder_State *st, /* i : state handle */ const Word16 frame_cnt, /* i : frame counter in the super_frame Q0 */ - Word32 *x_orig_fx, /* i : shaped MDCT spectrum */ - const Word16 x_orig_e, /* i : exp of shaped MDCT spectrum */ - Word16 *gainlpc_fx, /* i : FDNS gains */ + Word32 *x_orig_fx, /* i : shaped MDCT spectrum Q(31-x_orig_e)*/ + Word16 x_orig_e, /* i : exp of shaped MDCT spectrum */ + Word16 *gainlpc_fx, /* i : FDNS gains Q(15-gainlpc_e)*/ Word16 *gainlpc_e, /* i : exp of FDNS gains */ const Word16 *Aqind, /* i : frame-independent quantized coefficients (M+1) Q0 */ const Word16 tnsSize, /* i : number of tns parameters put into prm Q0 */ @@ -3559,15 +3503,15 @@ void QuantizeTCXSpectrum_fx( Word16 *pL_spec, /* o : length of the coded spectrum Q0 */ Word16 *ptcx_offset, /* o : folding point offset relative to the end of the previous frame Q0 */ Word16 *pnoiseFillingBorder, /* o : noise filling border Q0 */ - Word32 spectrum_fx[], /* o : quantized MDCT spectrum */ + Word32 spectrum_fx[], /* o : quantized MDCT spectrum Q(31-spectrum_e)*/ Word16 *spectrum_e, /* o : exp of quantized MDCT spectrum */ CONTEXT_HM_CONFIG *hm_cfg, /* o : Context-based harmonic model configuration */ Word16 *hm_active, /* o : flag indicating if the harmonic model is active */ Word16 lf_deemph_fact_fx[], /* o : low frequency deemphasis factors Q14*/ Word16 *nf_seed, /* o : noise filling random seed Q0*/ - Word32 *ener_fx, /* o : energy of the quantized spectrum */ + Word32 *ener_fx, /* o : energy of the quantized spectrum Q(31-ener_e) */ Word16 *ener_e, /* o : exp of energy of the quantized spectrum */ - Word16 *gain_tcx_fx, /* o : global gain */ + Word16 *gain_tcx_fx, /* o : global gain Q(15-gain_tcx_e) */ Word16 *gain_tcx_e, /* o : exp of global gain */ Word16 prm[] /* o : tcx parameters Q0 */ ) @@ -3692,6 +3636,7 @@ void QuantizeTCXSpectrum_fx( IF( EQ_16( st->core, TCX_20_CORE ) ) { L_frame_glob = st->L_frame; + move16(); } ELSE { @@ -3702,6 +3647,15 @@ void QuantizeTCXSpectrum_fx( } /* Start with the pre-shaped spectrum*/ + + /*scaling buffer to Q31 if exp < 0 to avoid overflow while scaling constants*/ + IF( x_orig_e < 0 ) + { + scale_sig32( x_orig_fx, L_spec, x_orig_e ); + x_orig_e = 0; + move16(); + } + Copy32( x_orig_fx, spectrum_fx, L_spec ); *spectrum_e = x_orig_e; move16(); @@ -3793,7 +3747,7 @@ void QuantizeTCXSpectrum_fx( } /* Quantize original spectrum */ - sqGain_fx = SQ_gain_fx( spectrum_fx, *spectrum_e, shl( mult( hTcxEnc->tcx_target_bits_fac, sqTargetBits ), 1 ), L_spec, &sqGain_e ); + sqGain_fx = SQ_gain_ivas_fx( spectrum_fx, *spectrum_e, shl( mult( hTcxEnc->tcx_target_bits_fac, sqTargetBits ), 1 ), L_spec, &sqGain_e ); tcx_scalar_quantization_ivas_fx( spectrum_fx, *spectrum_e, sqQ, L_spec, sqGain_fx, sqGain_e, st->hTcxCfg->sq_rounding, hTcxEnc->memQuantZeros, st->tcxonly ); @@ -3802,7 +3756,7 @@ void QuantizeTCXSpectrum_fx( move16(); IF( st->element_mode > EVS_MONO ) { - sqBits = RCcontextMapping_encode2_estimate_no_mem_s17_LCS( sqQ, L_spec, &lastnz, &nEncoded, sqTargetBits, &stop, 0, NULL ); + sqBits = RCcontextMapping_encode2_estimate_no_mem_s17_LCS_fx( sqQ, L_spec, &lastnz, &nEncoded, sqTargetBits, &stop, 0, NULL ); } ELSE { @@ -3816,7 +3770,7 @@ void QuantizeTCXSpectrum_fx( /* Context Mapping */ IF( st->element_mode > EVS_MONO ) { - sqBitsCtxHm = RCcontextMapping_encode2_estimate_no_mem_s17_LCS( sqQ, L_spec, &lastnzCtxHm, &nEncodedCtxHm, sqTargetBits - NumIndexBits, &stopCtxHm, 0, hm_cfg ); + sqBitsCtxHm = RCcontextMapping_encode2_estimate_no_mem_s17_LCS_fx( sqQ, L_spec, &lastnzCtxHm, &nEncodedCtxHm, sqTargetBits - NumIndexBits, &stopCtxHm, 0, hm_cfg ); } ELSE { @@ -3881,7 +3835,7 @@ void QuantizeTCXSpectrum_fx( } ELSE { - sqGain_fx = SQ_gain_fx( spectrum_fx, *spectrum_e, shl( mult( hTcxEnc->tcx_target_bits_fac, sqTargetBits ), 1 ), L_spec, &sqGain_e ); + sqGain_fx = SQ_gain_ivas_fx( spectrum_fx, *spectrum_e, shl( mult( hTcxEnc->tcx_target_bits_fac, sqTargetBits ), 1 ), L_spec, &sqGain_e ); } /* Quantize spectrum */ tcx_scalar_quantization_ivas_fx( spectrum_fx, *spectrum_e, sqQ, L_spec, sqGain_fx, sqGain_e, st->hTcxCfg->sq_rounding, hTcxEnc->memQuantZeros, st->tcxonly ); @@ -3892,7 +3846,7 @@ void QuantizeTCXSpectrum_fx( IF( st->element_mode > EVS_MONO ) { - sqBits_noStop = sqBits = RCcontextMapping_encode2_estimate_no_mem_s17_LCS( sqQ, L_spec, prm_lastnz, &nEncoded, sqTargetBits, &stop, 0, NULL ); + sqBits_noStop = sqBits = RCcontextMapping_encode2_estimate_no_mem_s17_LCS_fx( sqQ, L_spec, prm_lastnz, &nEncoded, sqTargetBits, &stop, 0, NULL ); move16(); } ELSE @@ -3919,19 +3873,15 @@ void QuantizeTCXSpectrum_fx( tmp1 = BASOP_Util_Divide1616_Scale( sqTargetBits, tmp1, &tmp2 ); BASOP_SATURATE_WARNING_OFF_EVS -#ifdef BASOP_NOGLOB hTcxEnc->tcx_target_bits_fac = shl_o( mult( hTcxEnc->tcx_target_bits_fac, tmp1 ), tmp2, &Overflow ); -#else /* BASOP_NOGLOB */ - hTcxEnc->tcx_target_bits_fac = shl( mult( hTcxEnc->tcx_target_bits_fac, tmp1 ), tmp2 ); -#endif /* BASOP_NOGLOB */ BASOP_SATURATE_WARNING_ON_EVS - if ( GT_16( hTcxEnc->tcx_target_bits_fac, 20480 ) ) + if ( GT_16( hTcxEnc->tcx_target_bits_fac, 20480 /*1.25 in Q14*/ ) ) { hTcxEnc->tcx_target_bits_fac = 20480; move16(); } - if ( LT_16( hTcxEnc->tcx_target_bits_fac, 12288 ) ) + if ( LT_16( hTcxEnc->tcx_target_bits_fac, 12288 /*.75 in Q14*/ ) ) { hTcxEnc->tcx_target_bits_fac = 12288; move16(); @@ -3981,7 +3931,7 @@ void QuantizeTCXSpectrum_fx( IF( st->element_mode > EVS_MONO ) { /* Fix: Use updated value for target bits (sqTargetBits + NumIndexBits) before computing non-mapped estimate */ - sqBitsCtxHm = RCcontextMapping_encode2_estimate_no_mem_s17_LCS( sqQ, L_spec, &lastnz, &nEncodedCtxHm, sqTargetBits + NumIndexBits, &stopCtxHm, 0, NULL ); + sqBitsCtxHm = RCcontextMapping_encode2_estimate_no_mem_s17_LCS_fx( sqQ, L_spec, &lastnz, &nEncodedCtxHm, sqTargetBits + NumIndexBits, &stopCtxHm, 0, NULL ); } ELSE { @@ -4056,7 +4006,7 @@ void QuantizeTCXSpectrum_fx( move16(); IF( st->element_mode > EVS_MONO ) { - sqBitsCtxHm = RCcontextMapping_encode2_estimate_no_mem_s17_LCS( sqQ, L_spec, &lastnzCtxHm, &nEncodedCtxHm, sqTargetBits - NumIndexBits, &stopCtxHm, 0, hm_cfg ); + sqBitsCtxHm = RCcontextMapping_encode2_estimate_no_mem_s17_LCS_fx( sqQ, L_spec, &lastnzCtxHm, &nEncodedCtxHm, sqTargetBits - NumIndexBits, &stopCtxHm, 0, hm_cfg ); } ELSE { @@ -4170,7 +4120,7 @@ void QuantizeTCXSpectrum_fx( sqTargetBits = add( sqTargetBits, NumIndexBits ); ctxHmBits = sub( ctxHmBits, NumIndexBits ); } - sqBits = RCcontextMapping_encode2_estimate_no_mem_s17_LCS( sqQ, L_spec, prm_lastnz, &nEncoded, sqTargetBits, &stop, 0, NULL ); + sqBits = RCcontextMapping_encode2_estimate_no_mem_s17_LCS_fx( sqQ, L_spec, prm_lastnz, &nEncoded, sqTargetBits, &stop, 0, NULL ); } ELSE { @@ -4194,8 +4144,10 @@ void QuantizeTCXSpectrum_fx( FOR( i = 0; i < L_spec; i++ ) { spectrum_fx[i] = (Word32) sqQ[i]; + move32(); /* noise filling seed */ *nf_seed = (Word16) L_add( *nf_seed, L_mult0( abs_s( sqQ[i] ), shl( i, 1 ) ) ); + move16(); } tmp32 = L_deposit_l( 0 ); @@ -4204,11 +4156,7 @@ void QuantizeTCXSpectrum_fx( spectrum_fx[i] = L_mult( sqQ[i], 1 << ( 30 - SPEC_EXP_DEC ) ); move32(); /* noise filling seed */ -#ifdef BASOP_NOGLOB tmp32 = L_macNs_co( tmp32, abs_s( sqQ[i] ), i, &Carry, &Overflow ); -#else /* BASOP_NOGLOB */ - tmp32 = L_macNs( tmp32, abs_s( sqQ[i] ), i ); -#endif /* BASOP_NOGLOB */ } *spectrum_e = SPEC_EXP_DEC; move16(); @@ -4236,7 +4184,7 @@ void QuantizeTCXSpectrum_fx( Word8 tmp8 = 1; move16(); - if ( ( st->last_core == ACELP_CORE ) ) + if ( st->last_core == ACELP_CORE ) { tmp8 = 0; move16(); @@ -4248,13 +4196,22 @@ void QuantizeTCXSpectrum_fx( low_complexiety = 1; move16(); } - tcx_arith_encode_envelope_fx( spectrum_fx, spectrum_e, hm_cfg->indexBuffer, L_frame, L_spec, st, Aqind, sqTargetBits, sqQ, tmp8, prm_hm, /* HM parameter area */ LtpPitchLag, &sqBits, &signaling_bits, nf_seed, low_complexiety ); + tcx_arith_encode_envelope_ivas_fx( spectrum_fx, spectrum_e, hm_cfg->indexBuffer, L_frame, L_spec, st, Aqind, sqTargetBits, sqQ, tmp8, prm_hm, /* HM parameter area */ LtpPitchLag, &sqBits, &signaling_bits, low_complexiety ); sqTargetBits = sub( sqTargetBits, signaling_bits ); *prm_target = sqTargetBits; move16(); /* Noise filling seed */ + Word64 seed = 0; + move64(); + FOR( i = 0; i < noiseFillingBorder; ++i ) + { + /* *nf_seed += (int16_t) ( abs( (int16_t) spectrum[i] ) * i * 2 ); */ + seed = W_mac_32_32( seed, L_abs( spectrum_fx[i] ), i ); // exp: spectrum_e + } + *nf_seed = extract_l( W_extract_l( W_shr( seed, sub( 31, *spectrum_e ) ) ) ); // Q0 + move16(); } *hm_active = prm_hm[0]; @@ -4300,6 +4257,7 @@ void QuantizeTCXSpectrum_fx( { calculate_hangover_attenuation_gain_ivas_fx( st, &att_fx, vad_hover_flag ); *gain_tcx_fx = mult( *gain_tcx_fx, att_fx ); + move16(); } /*-----------------------------------------------------------* @@ -4383,13 +4341,13 @@ void coder_tcx_fx( TCX_CONFIG_HANDLE hTcxCfg, /* i : configuration of TCX */ Word16 A[], /* input: quantized coefficients NxAz_q[M+1] */ Word16 Aqind[], /* input: frame-independent quantized coefficients (M+1) */ - Word16 synth[], - Word16 L_frame_glob, /* input: frame length */ + Word16 synth[], /*Qx*/ + Word16 L_frame_glob, /* input: frame length */ Word16 L_frameTCX_glob, Word16 L_spec, Word16 nb_bits, /*input: bit budget*/ Word8 tcxonly, /*input: only TCX flag*/ - Word32 spectrum[], /* i/o: MDCT spectrum */ + Word32 spectrum[], /* i/o: MDCT spectrum Q(31-spectrum_e)*/ Word16 *spectrum_e, /* i/o: MDCT spectrum exponent */ Word16 prm[], /* output: tcx parameters */ Encoder_State *st, @@ -4485,6 +4443,7 @@ void coder_tcx_fx( /* DCT */ edct_fx( tmp_buf, spectrum, L_frame, &Q ); *spectrum_e = sub( 31, Q ); + move16(); } @@ -4523,8 +4482,7 @@ void coder_tcx_fx( powerSpec, &powerSpec_e ); IF( hTcxCfg->fIsTNSAllowed != 0 ) { - test(); - test(); + SetTnsConfig( hTcxCfg, sub( L_frame_glob, st->L_frame ) == 0, st->last_core == 0 ); TNSAnalysis_fx( hTcxCfg, L_frame, L_spec, TCX_20, st->last_core == 0, spectrum, hTcxEnc->tnsData, hTcxEnc->fUseTns, &st->hIGFEnc->tns_predictionGain ); @@ -4577,6 +4535,7 @@ void coder_tcx_fx( #ifndef MSAN_FIX hLPDmem->nbits = add( hLPDmem->nbits, add( tnsBits, ltpBits ) ); + move16(); #endif } @@ -4655,18 +4614,18 @@ void InternalTCXDecoder_fx( const Word16 tcx_offset, /* i : folding point offset relative to the end of the previous frame */ const Word16 noiseFillingBorder, /* i : noise filling border */ const Word32 *x_quant_fx, /* i : quantized spectrum, exponent same as spectrum_e */ - const Word32 ener_fx, /* i : energy of the quantized spectrum */ + const Word32 ener_fx, /* i : energy of the quantized spectrum Q(31-ener_e) */ const Word16 ener_e, /* i : exponent of energy of the quantized spectrum */ Word16 lf_deemph_fact_fx[], /* i/o: low frequency deemphasis factors */ const Word16 fac_ns_fx, /* i : noise filling level, Q15 */ const Word16 nf_seed, /* i : noise filling random seed, Q0 */ const Word16 *A_fx, /* i : LPC representation of the FDNS gains, Q = 14 - norm_s(A_fx[0]) */ - Word16 gainlpc_fx[], /* i/o: FDNS gains */ + Word16 gainlpc_fx[], /* i/o: FDNS gains Q(15-gainlpc_e) */ Word16 gainlpc_e[], /* i/o: FDNS gains exponents */ const Word16 hm_active, /* i : flag indicating if the harmonic model is active */ - Word16 gain_tcx_fx, /* i/o: global gain / quantized global gain */ + Word16 gain_tcx_fx, /* i/o: global gain / quantized global gain Q(15-gain_tcx_e) */ Word16 *gain_tcx_e, /* i/o: global gain / quantized global gain exponent */ - Word32 spectrum_fx[], /* o : dequantized spectrum */ + Word32 spectrum_fx[], /* o : dequantized spectrum Q(31-spectrum_e) */ Word16 *spectrum_e, /* o : exponent of dequantized spectrum */ Word16 synth[], /* o : time domain signal */ Word16 *gain_tcx_q /* o : quantized global gain (at low bitrates), Q0 */ @@ -4746,7 +4705,7 @@ void InternalTCXDecoder_fx( tmp2 = add( tmp2, sub( ener_e, add( shl( sub( *spectrum_e, s ), 1 ), 1 ) ) ); tmp1 = Sqrt16( tmp1, &tmp2 ); - gain_tcx_fx = mult( gain_tcx_fx, tmp1 ); + gain_tcx_fx = mult( gain_tcx_fx, tmp1 ); // Q(15-(gain_tcx_e+tmp2)) *gain_tcx_e = add( *gain_tcx_e, tmp2 ); move16(); @@ -4761,7 +4720,7 @@ void InternalTCXDecoder_fx( IF( EQ_16( st->element_mode, IVAS_CPE_MDCT ) ) { - Copy_Scale_sig_16_32( A_fx, A_fx32, M + 1, add( norm_s( A_fx[0] ), 2 ) ); // Copying the Word16 A_fx buffer to a temporary Word32 buffer in Q16 + Copy_Scale_sig_16_32_DEPREC( A_fx, A_fx32, M + 1, add( norm_s( A_fx[0] ), 2 ) ); // Copying the Word16 A_fx buffer to a temporary Word32 buffer in Q16 q_spec = sub( 31, *spectrum_e ); sns_interpolate_scalefactors_fx( sns_interpolated_scalefactors_fx, A_fx32, DEC ); @@ -4771,11 +4730,11 @@ void InternalTCXDecoder_fx( test(); IF( NE_16( len, L_frame ) && LT_16( q_spec, sub( 31, *spectrum_e ) ) ) { - scale_sig32( spectrum_fx + len, sub( L_frame, len ), sub( q_spec, sub( 15, *spectrum_e ) ) ); + scale_sig32( spectrum_fx + len, sub( L_frame, len ), sub( q_spec, sub( 15, *spectrum_e ) ) ); // q_spec } ELSE IF( NE_16( len, L_frame ) && GT_16( q_spec, sub( 31, *spectrum_e ) ) ) { - scale_sig32( spectrum_fx, len, sub( sub( 15, *spectrum_e ), q_spec ) ); + scale_sig32( spectrum_fx, len, sub( sub( 15, *spectrum_e ), q_spec ) ); // Q(31-spectrum_e) q_spec = sub( 31, *spectrum_e ); } *spectrum_e = sub( 31, q_spec ); @@ -4789,7 +4748,7 @@ void InternalTCXDecoder_fx( * Apply gain * *-----------------------------------------------------------*/ - IF( EQ_16( st->hTcxCfg->coder_type, INACTIVE ) ) + IF( st->hTcxCfg->coder_type == INACTIVE ) { gain_tcx_fx = mult_r( gain_tcx_fx, st->hTcxCfg->na_scale ); } @@ -5000,11 +4959,7 @@ void InternalTCXDecoder_fx( /* add part of current sub-window overlapping with previous window */ FOR( i = 0; i < L_ola; i++ ) { -#ifdef BASOP_NOGLOB tmpP16[i] = add_sat( tmpP16[i], win[i] ); -#else - tmpP16[i] = add( tmpP16[i], win[i] ); -#endif move16(); } /* copy new sub-window region not overlapping with previous window */ @@ -5068,7 +5023,6 @@ void InternalTCXDecoder_fx( 0 ); - move16(); tmpP16 = xn_buf16 + add( sub( L_win, shr( L_ola, 1 ) ), shr( overlap, 1 ) ); tcx_windowing_synthesis_past_frame( tmpP16, @@ -5083,11 +5037,7 @@ void InternalTCXDecoder_fx( /* add part of current sub-window overlapping with previous window */ FOR( i = 0; i < L_ola; i++ ) { -#ifdef BASOP_NOGLOB tmpP16[i] = add_sat( tmpP16[i], win[i] ); -#else - tmpP16[i] = add( tmpP16[i], win[i] ); -#endif move16(); } @@ -5182,7 +5132,7 @@ void InternalTCXDecoder_fx( /* DCT */ Q = sub( 31, *spectrum_e ); - edct_fx( spectrum_fx, tmp_buf, L_frame, &Q ); + edct_ivas_fx( spectrum_fx, tmp_buf, L_frame, &Q ); /* scale by sqrt(L / NORM_MDCT_FACTOR) */ tmp1 = mult_r( shl( L_frame, 4 ), 26214 /*128.f / NORM_MDCT_FACTOR Q15*/ ); /* 4Q11 */ @@ -5213,11 +5163,7 @@ void InternalTCXDecoder_fx( /* scale output */ FOR( i = 0; i < L_frame; i++ ) { -#ifdef BASOP_NOGLOB xn_buf16[i] = shr_o( xn_buf16[i], Q, &Overflow ); -#else /* BASOP_NOGLOB */ - xn_buf16[i] = shr( xn_buf16[i], Q ); -#endif /* BASOP_NOGLOB */ move16(); } @@ -5277,11 +5223,7 @@ void InternalTCXDecoder_fx( tmp1 = sub( overlap, st->hTcxCfg->tcx_mdct_window_min_length ); FOR( i = 0; i < tmp1; i++ ) { -#ifdef BASOP_NOGLOB xn_buf16[i] = shl_sat( add_sat( xn_buf16[i], shr_sat( hTcxEnc->old_out_fx[i + nz], tmp2 ) ), TCX_IMDCT_HEADROOM ); -#else - xn_buf16[i] = shl( add( xn_buf16[i], shr( hTcxEnc->old_out_fx[i + nz], tmp2 ) ), TCX_IMDCT_HEADROOM ); -#endif move16(); } @@ -5290,31 +5232,19 @@ void InternalTCXDecoder_fx( FOR( ; i < tmp1; i++ ) { tmp3 = mult_r( shr( hTcxEnc->old_out_fx[i + nz], tmp2 ), st->hTcxCfg->tcx_mdct_window_minimum[i - overlap + st->hTcxCfg->tcx_mdct_window_min_length].v.re ); -#ifdef BASOP_NOGLOB xn_buf16[i] = shl_sat( add_sat( xn_buf16[i], tmp3 ), TCX_IMDCT_HEADROOM ); -#else - xn_buf16[i] = shl( add( xn_buf16[i], tmp3 ), TCX_IMDCT_HEADROOM ); -#endif move16(); } FOR( ; i < overlap; i++ ) { tmp3 = mult_r( shr( hTcxEnc->old_out_fx[i + nz], tmp2 ), st->hTcxCfg->tcx_mdct_window_minimum[overlap - 1 - i].v.im ); -#ifdef BASOP_NOGLOB xn_buf16[i] = shl_sat( add_sat( xn_buf16[i], tmp3 ), TCX_IMDCT_HEADROOM ); -#else - xn_buf16[i] = shl( add( xn_buf16[i], tmp3 ), TCX_IMDCT_HEADROOM ); -#endif move16(); } FOR( ; i < L_frame; i++ ) { -#ifdef BASOP_NOGLOB xn_buf16[i] = shl_sat( xn_buf16[i], TCX_IMDCT_HEADROOM ); -#else - xn_buf16[i] = shl( xn_buf16[i], TCX_IMDCT_HEADROOM ); -#endif move16(); } } @@ -5344,11 +5274,7 @@ void InternalTCXDecoder_fx( BASOP_SATURATE_WARNING_OFF_EVS; FOR( i = 0; i < overlap; i++ ) { -#ifdef BASOP_NOGLOB xn_buf16[i] = shl_sat( add( xn_buf16[i], hTcxEnc->Txnq[i] ), TCX_IMDCT_HEADROOM ); -#else - xn_buf16[i] = shl( add( xn_buf16[i], hTcxEnc->Txnq[i] ), TCX_IMDCT_HEADROOM ); -#endif move16(); } @@ -5356,11 +5282,7 @@ void InternalTCXDecoder_fx( { FOR( ; i < L_frame; i++ ) { -#ifdef BASOP_NOGLOB xn_buf16[i] = shl_sat( xn_buf16[i], TCX_IMDCT_HEADROOM ); -#else - xn_buf16[i] = shl( xn_buf16[i], TCX_IMDCT_HEADROOM ); -#endif move16(); } } @@ -5374,11 +5296,7 @@ void InternalTCXDecoder_fx( BASOP_SATURATE_WARNING_OFF_EVS; FOR( i = 0; i < L_frame; i++ ) { -#ifdef BASOP_NOGLOB xn_buf16[i] = shl_o( xn_buf16[i], TCX_IMDCT_HEADROOM, &Overflow ); -#else /* BASOP_NOGLOB */ - xn_buf16[i] = shl( xn_buf16[i], TCX_IMDCT_HEADROOM ); -#endif move16(); } BASOP_SATURATE_WARNING_ON_EVS; @@ -5411,7 +5329,7 @@ void InternalTCXDecoder_fx( st->hTcxCfg->tcx_curr_overlap_mode ); /* If current overlap mode = FULL_OVERLAP -> ALDO_WINDOW */ - IF( EQ_16( st->hTcxCfg->tcx_curr_overlap_mode, FULL_OVERLAP ) ) + IF( st->hTcxCfg->tcx_curr_overlap_mode == FULL_OVERLAP ) { FOR( i = 0; i < nz; i++ ) { @@ -5445,3 +5363,778 @@ void InternalTCXDecoder_fx( return; } + + +void TNSAnalysisStereo_fx( + Encoder_State **sts, /* i : encoder state handle */ + Word32 *mdst_spectrum_fx[CPE_CHANNELS][NB_DIV], /* o : MDST spectrum Qx*/ + const Word16 bWhitenedDomain, /* i : whitened domain flag Q0*/ + Word16 tnsSize[CPE_CHANNELS][NB_DIV], /* i : number of tns parameters put into prm Q0*/ + Word16 tnsBits[CPE_CHANNELS][NB_DIV], /* i : number of tns bits in the frame Q0*/ + Word16 param_core[][NB_DIV * NPRM_DIV], /* o : TNS parameters Q0*/ + const Word16 mct_on /* i : flag mct block (1) or stereo (0) Q0*/ +) +{ + Word16 ch, k, L_spec, L_frame, nSubframes, iFilter; + Word32 *spectrum_fx, sum; + Encoder_State *st = NULL; + TCX_ENC_HANDLE hTcxEnc = NULL; + Word16 individual_decision[NB_DIV]; + Word32 maxPredictionGain_fx = 0, meanPredictionGain_fx; + move32(); + Word16 maxPredictionGain_e = 0, meanPredictionGain_e; + move16(); + Word16 sum_e = 0; + move16(); + individual_decision[0] = 0; + move16(); + individual_decision[1] = 0; + move16(); + L_spec = -1; + move16(); + L_frame = -1; + move16(); + + /* TNS filter analysis, loop over channels */ + FOR( ch = 0; ch < CPE_CHANNELS; ch++ ) + { + st = sts[ch]; + IF( EQ_16( st->mct_chan_mode, MCT_CHAN_MODE_IGNORE ) ) + { + CONTINUE; + } + + hTcxEnc = st->hTcxEnc; + + IF( EQ_16( hTcxEnc->tcxMode, TCX_20 ) ) + { + nSubframes = 1; + } + ELSE + { + nSubframes = NB_DIV; + } + move16(); + + FOR( k = 0; k < nSubframes; k++ ) + { + /* reset tns on whitened domain flag */ + IF( !bWhitenedDomain ) + { + hTcxEnc->bTnsOnWhithenedSpectra[k] = 0; + move16(); + hTcxEnc->fUseTns[k] = 0; + move16(); + } + test(); + test(); + IF( st->hTcxCfg->fIsTNSAllowed && ( !bWhitenedDomain || hTcxEnc->bTnsOnWhithenedSpectra[k] ) ) + { + spectrum_fx = hTcxEnc->spectrum_fx[k]; + + L_frame = hTcxEnc->L_frameTCX; + move16(); + st->hTcxCfg->pCurrentTnsConfig = &st->hTcxCfg->tnsConfig[hTcxEnc->transform_type[k] == TCX_20][( k == 0 ) && ( st->last_core == ACELP_CORE )]; + L_spec = st->hTcxCfg->pCurrentTnsConfig->iFilterBorders[0]; + move16(); + /*-----------------------------------------------------------* + * Temporal Noise Shaping analysis * + *-----------------------------------------------------------*/ + + IF( EQ_16( hTcxEnc->transform_type[k], TCX_5 ) ) + { + /* rearrange LF sub-window lines prior to TNS analysis & filtering */ + tcx5TnsGrouping_fx( shr( L_frame, 2 ), shr( L_spec, 1 ), spectrum_fx ); + } + + /* WMOPS: All initializations are either for safety or static (tables) and thus not to be counted */ + + ResetTnsData( &hTcxEnc->tnsData[k] ); + IF( st->hTcxCfg->pCurrentTnsConfig->maxOrder <= 0 ) + { + BREAK; + } + + CalculateTnsFilt_fx( st->hTcxCfg->pCurrentTnsConfig, spectrum_fx, hTcxEnc->spectrum_e[k], &hTcxEnc->tnsData[k] ); + } + } + } + + IF( !mct_on ) + { + /* TNS decision */ + /* if framing differs between channels, keep the filter decision per channel */ + test(); + test(); + IF( ( NE_16( sts[0]->hTcxEnc->transform_type[0], sts[1]->hTcxEnc->transform_type[0] ) && + NE_16( sts[0]->hTcxEnc->transform_type[1], sts[1]->hTcxEnc->transform_type[1] ) ) || + NE_16( sts[0]->hTcxCfg->fIsTNSAllowed, sts[1]->hTcxCfg->fIsTNSAllowed ) ) + { + individual_decision[0] = individual_decision[1] = 1; + move16(); + move16(); + } + ELSE IF( bWhitenedDomain ) + { + IF( EQ_16( sts[0]->hTcxEnc->tcxMode, TCX_20 ) ) + { + nSubframes = 1; + } + ELSE + { + nSubframes = NB_DIV; + } + move16(); + FOR( k = 0; k < nSubframes; k++ ) + { + IF( NE_16( sts[0]->hTcxEnc->bTnsOnWhithenedSpectra[k], sts[1]->hTcxEnc->bTnsOnWhithenedSpectra[k] ) ) + { + individual_decision[k] = 1; + move16(); + } + } + } + + /* framing equal, check for similar filters, if very similar (also indicator for and M signal), + * use at least the same decision, maybe use the same filter + */ + { + Word8 isTCX10; + + IF( EQ_16( sts[0]->hTcxEnc->tcxMode, TCX_20 ) ) + { + nSubframes = 1; + isTCX10 = 0; + } + ELSE + { + nSubframes = NB_DIV; + isTCX10 = 1; + } + move16(); + move16(); + FOR( k = 0; k < nSubframes; k++ ) + { + test(); + test(); + test(); + IF( sts[0]->hTcxCfg->fIsTNSAllowed && NE_16( individual_decision[k], 1 ) && ( !bWhitenedDomain || sts[0]->hTcxEnc->bTnsOnWhithenedSpectra[k] ) ) + { + Word32 maxPredGain_fx = -ONE_IN_Q31; + move32(); + Word16 maxPredGain_e = 0; + move16(); + sts[0]->hTcxCfg->pCurrentTnsConfig = &sts[0]->hTcxCfg->tnsConfig[sts[0]->hTcxEnc->transform_type[k] == TCX_20][( k == 0 ) && ( sts[0]->last_core == ACELP_CORE )]; + sts[1]->hTcxCfg->pCurrentTnsConfig = &sts[1]->hTcxCfg->tnsConfig[sts[1]->hTcxEnc->transform_type[k] == TCX_20][( k == 0 ) && ( sts[1]->last_core == ACELP_CORE )]; + + FOR( iFilter = sts[0]->hTcxCfg->pCurrentTnsConfig->nMaxFilters - 1; iFilter >= 0; iFilter-- ) + { + STnsFilter *pFilter[2]; + struct TnsParameters const *pTnsParameters[2]; + pFilter[0] = sts[0]->hTcxEnc->tnsData[k].filter + iFilter; + pTnsParameters[0] = sts[0]->hTcxCfg->pCurrentTnsConfig->pTnsParameters + iFilter; + pFilter[1] = sts[1]->hTcxEnc->tnsData[k].filter + iFilter; + pTnsParameters[1] = sts[1]->hTcxCfg->pCurrentTnsConfig->pTnsParameters + iFilter; + + /* if prediction gain and avgSqrCoef are both close we are pretty sure the filters are quite similar, use the avg of + * both filters for the decision + */ + + meanPredictionGain_fx = BASOP_Util_Add_Mant32Exp( Mpy_32_16_1( pFilter[0]->predictionGain32, 16384 /*0.5f Q15*/ ), pFilter[0]->predictionGain_e, Mpy_32_16_1( pFilter[1]->predictionGain32, 16384 /*0.5f Q15*/ ), pFilter[1]->predictionGain_e, &meanPredictionGain_e ); // meanPredictionGain_e + + /* maxPredictionGain = max( maxPredictionGain, meanPredictionGain );*/ + IF( GT_32( meanPredictionGain_fx, L_shl_sat( maxPredictionGain_fx, sub( maxPredictionGain_e, meanPredictionGain_e ) ) ) ) /* exp: meanPredictionGain_e */ + { + maxPredictionGain_fx = meanPredictionGain_fx; + maxPredictionGain_e = meanPredictionGain_e; + move32(); + move16(); + } + + test(); + test(); + test(); + IF( GT_32( pFilter[0]->predictionGain32, L_shl_sat( L_deposit_h( pTnsParameters[0]->minPredictionGain ), sub( PRED_GAIN_E, pFilter[0]->predictionGain_e ) ) ) && LT_32( sts[0]->element_brate, IVAS_80k ) && + GT_32( pFilter[1]->predictionGain32, L_shl_sat( L_deposit_h( pTnsParameters[1]->minPredictionGain ), sub( PRED_GAIN_E, pFilter[1]->predictionGain_e ) ) ) && EQ_16( sts[0]->hTcxEnc->tnsData[k].nFilters, sts[1]->hTcxEnc->tnsData[k].nFilters ) ) + { + pFilter[0]->predictionGain32 = pFilter[1]->predictionGain32 = meanPredictionGain_fx; /* more TNS filter sync at 48kbps */ + move32(); + move32(); + pFilter[0]->predictionGain_e = pFilter[1]->predictionGain_e = meanPredictionGain_e; /* more TNS filter sync at 48kbps */ + move16(); + move16(); + pFilter[0]->predictionGain = pFilter[1]->predictionGain = shl_sat( extract_h( meanPredictionGain_fx ), sub( meanPredictionGain_e, PRED_GAIN_E ) ); /* Q7 */ + move16(); + } + sum_e = s_max( pFilter[0]->predictionGain_e, pFilter[1]->predictionGain_e ); + sum = L_abs( L_sub_sat( L_shl( pFilter[0]->predictionGain32, sub( pFilter[0]->predictionGain_e, sum_e ) ), L_shl( pFilter[1]->predictionGain32, sub( pFilter[1]->predictionGain_e, sum_e ) ) ) ); // sum_e + + IF( LT_32( L_shl_sat( sum, sub( sum_e, meanPredictionGain_e ) ), Mpy_32_16_1( meanPredictionGain_fx, SIMILAR_TNS_THRESHOLD_FX_IN_Q15 ) ) && + ( EQ_16( sts[0]->hTcxEnc->tnsData[k].nFilters, sts[1]->hTcxEnc->tnsData[k].nFilters ) ) ) + { + + Word16 maxAvgSqrCoef_fx = s_max( pFilter[0]->avgSqrCoef, pFilter[1]->avgSqrCoef ); // Q15 + Word16 meanLtpGain_fx = add( shr( sts[0]->hTcxEnc->tcxltp_gain, 1 ), shr( sts[1]->hTcxEnc->tcxltp_gain, 1 ) ); + + /* maxPredGain_fx = L_max( maxPredGain_fx, meanPredictionGain_fx ); */ + IF( GT_32( meanPredictionGain_fx, L_shl_sat( maxPredGain_fx, sub( maxPredGain_e, maxPredictionGain_e ) ) ) ) /* exp: meanPredictionGain_e */ + { + maxPredGain_fx = meanPredictionGain_fx; + maxPredGain_e = meanPredictionGain_e; + move32(); + move16(); + } + + test(); + test(); + IF( GT_32( meanPredictionGain_fx, L_shl_sat( L_deposit_h( pTnsParameters[0]->minPredictionGain ), sub( PRED_GAIN_E, meanPredictionGain_e ) ) ) || GT_16( maxAvgSqrCoef_fx, pTnsParameters[0]->minAvgSqrCoef ) ) + { + test(); + test(); + test(); + IF( sts[0]->hTcxEnc->tnsData[k].nFilters > 0 || sts[1]->hTcxEnc->tnsData[k].nFilters > 0 || isTCX10 || LT_16( meanLtpGain_fx, 19660 /* 0.6 in Q15*/ ) ) + { + + sts[0]->hTcxEnc->tnsData[k].nFilters = add( sts[0]->hTcxEnc->tnsData[k].nFilters, 1 ); + move16(); + /* When order parameter is evaluated as 0 and change in precision causes the flow to reach here, + this may result in crash later. Changing the filter type here so the order is taken here in further section */ + IF( pFilter[0]->order != 0 ) + { + pFilter[0]->filterType = TNS_FILTER_ON; + move16(); + } + ELSE + { + pFilter[0]->filterType = TNS_FILTER_ON_ZERO; + move16(); + } + sts[1]->hTcxEnc->tnsData[k].nFilters = add( sts[1]->hTcxEnc->tnsData[k].nFilters, 1 ); + move16(); + IF( pFilter[1]->order != 0 ) + { + pFilter[1]->filterType = TNS_FILTER_ON; + move16(); + } + ELSE + { + pFilter[1]->filterType = TNS_FILTER_ON_ZERO; + move16(); + } + } + ELSE + { + Word16 maxEnergyChange_fx; + maxEnergyChange_fx = mac_r( L_mult( GetTCXMaxenergyChange_ivas_fx( sts[0]->hTranDet, isTCX10, NSUBBLOCKS, 3 ), 16384 ), GetTCXMaxenergyChange_ivas_fx( sts[1]->hTranDet, isTCX10, NSUBBLOCKS, 3 ), 16384 ); + + IF( GE_16( maxEnergyChange_fx, shl( pTnsParameters[0]->minEnergyChange, Q3 - Q7 ) ) ) + { + sts[0]->hTcxEnc->tnsData[k].nFilters = add( sts[0]->hTcxEnc->tnsData[k].nFilters, 1 ); + move16(); + /* When order parameter is evaluated as 0 and change in precision causes the flow to reach here, + this may result in crash later. Changing the filter type here so the order is taken here in further section */ + IF( pFilter[0]->order != 0 ) + { + pFilter[0]->filterType = TNS_FILTER_ON; + move16(); + } + ELSE + { + pFilter[0]->filterType = TNS_FILTER_ON_ZERO; + move16(); + } + sts[1]->hTcxEnc->tnsData[k].nFilters = add( sts[1]->hTcxEnc->tnsData[k].nFilters, 1 ); + move16(); + IF( pFilter[1]->order != 0 ) + { + pFilter[1]->filterType = TNS_FILTER_ON; + move16(); + } + ELSE + { + pFilter[1]->filterType = TNS_FILTER_ON_ZERO; + move16(); + } + } + ELSE + { + pFilter[0]->filterType = TNS_FILTER_OFF; + move16(); + pFilter[1]->filterType = TNS_FILTER_OFF; + move16(); + } + } + } + ELSE IF( sts[0]->hTcxEnc->tnsData[k].nFilters > 0 && sts[1]->hTcxEnc->tnsData[k].nFilters > 0 ) /* If a previous filter is turned on */ + { + pFilter[0]->filterType = TNS_FILTER_ON_ZERO; + pFilter[1]->filterType = TNS_FILTER_ON_ZERO; + move16(); + move16(); + sts[0]->hTcxEnc->tnsData[k].nFilters = add( sts[0]->hTcxEnc->tnsData[k].nFilters, 1 ); + move16(); + sts[1]->hTcxEnc->tnsData[k].nFilters = add( sts[1]->hTcxEnc->tnsData[k].nFilters, 1 ); + move16(); + } + ELSE IF( NE_16( sts[0]->hTcxEnc->tnsData[k].nFilters, sts[1]->hTcxEnc->tnsData[k].nFilters ) ) /* sanity check */ + { + assert( 0 ); + } + ELSE + { + pFilter[0]->filterType = TNS_FILTER_OFF; + move16(); + pFilter[1]->filterType = TNS_FILTER_OFF; + move16(); + } + + test(); + test(); + IF( EQ_16( pFilter[0]->filterType, TNS_FILTER_ON ) && EQ_16( pFilter[1]->filterType, TNS_FILTER_ON ) && LT_32( sts[0]->element_brate, IVAS_80k ) ) + { + Word16 tmpIntValue = 0; + move16(); + Word16 tmpCoeff[TNS_MAX_FILTER_ORDER]; + Word16 i, maxOrder = s_max( pFilter[0]->order, pFilter[1]->order ); + + set16_fx( tmpCoeff, 0, TNS_MAX_FILTER_ORDER ); + FOR( i = 0; i < maxOrder; i++ ) + { + tmpIntValue = s_max( tmpIntValue, abs_s( sub( pFilter[0]->coefIndex[i], pFilter[1]->coefIndex[i] ) ) ); + } + + IF( EQ_16( tmpIntValue, 1 ) ) /* the TNS coefficients are sufficiently similar to equalize the two filters */ + { + FOR( i = maxOrder - 1; i >= 0; i-- ) + { + IF( LT_16( abs_s( pFilter[0]->coefIndex[i] ), abs_s( pFilter[1]->coefIndex[i] ) ) ) + { + tmpCoeff[i] = pFilter[0]->coefIndex[i]; + } + ELSE + { + tmpCoeff[i] = pFilter[1]->coefIndex[i]; + } + move16(); + IF( ( tmpIntValue > 0 ) && ( tmpCoeff[i] == 0 ) ) + { + maxOrder = sub( maxOrder, 1 ); + } + ELSE + { + tmpIntValue = 0; + move16(); + } + } + /* make sure that maxOrder is non zero and not all coefficients are zero (could happen in rare cases) */ + IF( maxOrder > 0 ) + { + FOR( i = TNS_MAX_FILTER_ORDER - 1; i >= 0; i-- ) + { + pFilter[0]->coefIndex[i] = pFilter[1]->coefIndex[i] = tmpCoeff[i]; + move16(); + move16(); + } + + pFilter[0]->order = pFilter[1]->order = maxOrder; + move16(); + move16(); + } + } + } + } + ELSE + { + individual_decision[k] = 1; + move16(); + } + } + + IF( individual_decision[k] == 0 ) + { + IF( ( sts[0]->hTcxEnc->tnsData[k].nFilters > 0 ) ) + { + sts[0]->hTcxEnc->fUseTns[k] = 1; + } + ELSE + { + sts[0]->hTcxEnc->fUseTns[k] = 0; + } + move16(); + + IF( ( sts[1]->hTcxEnc->tnsData[k].nFilters > 0 ) ) + { + sts[1]->hTcxEnc->fUseTns[k] = 1; + } + ELSE + { + sts[1]->hTcxEnc->fUseTns[k] = 0; + } + move16(); + } + ELSE + { + sts[0]->hTcxEnc->tnsData[k].nFilters = 0; + move16(); + sts[1]->hTcxEnc->tnsData[k].nFilters = 0; + move16(); + sts[0]->hTcxEnc->fUseTns[k] = 0; + move16(); + sts[1]->hTcxEnc->fUseTns[k] = 0; + move16(); + FOR( iFilter = sts[0]->hTcxCfg->pCurrentTnsConfig->nMaxFilters - 1; iFilter >= 0; iFilter-- ) + { + sts[0]->hTcxEnc->tnsData[k].filter[iFilter].filterType = TNS_FILTER_OFF; + move16(); + sts[1]->hTcxEnc->tnsData[k].filter[iFilter].filterType = TNS_FILTER_OFF; + move16(); + } + } + + test(); + test(); + test(); + IF( !bWhitenedDomain && individual_decision[k] == 0 && + LT_32( L_shl_sat( maxPredGain_fx, sub( maxPredGain_e, PRED_GAIN_E ) ), TNS_GAIN_THRESHOLD_FOR_WHITE_FX_IN_Q23 ) && + NE_16( sts[0]->hTcxEnc->transform_type[k], TCX_5 ) ) + { + sts[0]->hTcxEnc->bTnsOnWhithenedSpectra[k] = 1; + move16(); + sts[1]->hTcxEnc->bTnsOnWhithenedSpectra[k] = 1; + move16(); + sts[0]->hTcxEnc->tnsData[k].nFilters = 0; + move16(); + sts[1]->hTcxEnc->tnsData[k].nFilters = 0; + move16(); + sts[0]->hTcxEnc->fUseTns[k] = 0; + move16(); + sts[1]->hTcxEnc->fUseTns[k] = 0; + move16(); + FOR( iFilter = sts[0]->hTcxCfg->pCurrentTnsConfig->nMaxFilters - 1; iFilter >= 0; iFilter-- ) + { + ClearTnsFilterCoefficients( sts[0]->hTcxEnc->tnsData[k].filter + iFilter ); + ClearTnsFilterCoefficients( sts[1]->hTcxEnc->tnsData[k].filter + iFilter ); + } + } + + /* maxPredictionGain_fx = L_max( maxPredictionGain_fx, maxPredGain_fx ); */ + IF( GT_32( maxPredGain_fx, L_shl_sat( maxPredictionGain_fx, sub( maxPredictionGain_e, maxPredGain_e ) ) ) ) /* exp: maxPredGain_e */ + { + maxPredictionGain_fx = maxPredGain_fx; + maxPredictionGain_e = maxPredGain_e; + move32(); + move16(); + } + } + } + } + } + + /* individual decision for each channel */ + FOR( ch = 0; ch < CPE_CHANNELS; ch++ ) + { + IF( EQ_32( sts[ch]->mct_chan_mode, MCT_CHAN_MODE_IGNORE ) ) + { + CONTINUE; + } + + Word8 isTCX10; + + IF( EQ_16( sts[ch]->hTcxEnc->tcxMode, TCX_20 ) ) + { + nSubframes = 1; + isTCX10 = 0; + } + ELSE + { + nSubframes = NB_DIV; + isTCX10 = 1; + } + move16(); + move16(); + + FOR( k = 0; k < nSubframes; k++ ) + { + test(); + test(); + test(); + test(); + IF( sts[ch]->hTcxCfg->fIsTNSAllowed && ( individual_decision[k] || mct_on ) && + ( !bWhitenedDomain || sts[ch]->hTcxEnc->bTnsOnWhithenedSpectra[k] ) ) + { + Word32 maxPredGain_fx = -ONE_IN_Q31; // Q31 + move32(); + Word16 maxPredGain_e = 0; + move16(); + sts[ch]->hTcxCfg->pCurrentTnsConfig = &sts[ch]->hTcxCfg->tnsConfig[sts[ch]->hTcxEnc->transform_type[k] == TCX_20][( k == 0 ) && ( sts[ch]->last_core == ACELP_CORE )]; + + FOR( iFilter = sts[ch]->hTcxCfg->pCurrentTnsConfig->nMaxFilters - 1; iFilter >= 0; iFilter-- ) + { + STnsFilter *pFilter; + struct TnsParameters const *pTnsParameters; + pFilter = sts[ch]->hTcxEnc->tnsData[k].filter + iFilter; + pTnsParameters = sts[ch]->hTcxCfg->pCurrentTnsConfig->pTnsParameters + iFilter; + + // maxPredGain_fx = L_max( maxPredGain_fx, pFilter->predictionGain32 ); + IF( GT_32( pFilter->predictionGain32, L_shl_sat( maxPredGain_fx, sub( maxPredGain_e, pFilter->predictionGain_e ) ) ) ) /* pFilter->predictionGain_e */ + { + maxPredGain_fx = pFilter->predictionGain32; + maxPredGain_e = pFilter->predictionGain_e; + move32(); + move16(); + } + + test(); + IF( GT_32( pFilter->predictionGain32, L_shl_sat( L_deposit_h( pTnsParameters->minPredictionGain ), sub( PRED_GAIN_E, pFilter->predictionGain_e ) ) ) || GT_16( pFilter->avgSqrCoef, pTnsParameters->minAvgSqrCoef ) ) + { + test(); + test(); + IF( sts[ch]->hTcxEnc->tnsData[k].nFilters > 0 || isTCX10 || LT_16( sts[ch]->hTcxEnc->tcxltp_gain, 19660 /*.6f in Q15*/ ) ) + { + sts[ch]->hTcxEnc->tnsData[k].nFilters = add( sts[ch]->hTcxEnc->tnsData[k].nFilters, 1 ); + move16(); + /* When order parameter is evaluated as 0 and change in precision causes the flow to reach here, + this may result in crash later. Changing the filter type here so the order is taken here in further section */ + IF( pFilter->order != 0 ) + { + pFilter->filterType = TNS_FILTER_ON; + move16(); + } + ELSE + { + pFilter->filterType = TNS_FILTER_ON_ZERO; + move16(); + } + } + ELSE + { + Word16 maxEnergyChange_fx = GetTCXMaxenergyChange_ivas_fx( sts[ch]->hTranDet, isTCX10, NSUBBLOCKS, 3 ); + + IF( GE_16( maxEnergyChange_fx, shl( pTnsParameters->minEnergyChange, Q3 - Q7 ) ) ) + { + sts[ch]->hTcxEnc->tnsData[k].nFilters = add( sts[ch]->hTcxEnc->tnsData[k].nFilters, 1 ); + move16(); + /* When order parameter is evaluated as 0 and change in precision causes the flow to reach here, + this may result in crash later. Changing the filter type here so the order is taken here in further section */ + IF( pFilter->order != 0 ) + { + pFilter->filterType = TNS_FILTER_ON; + move16(); + } + ELSE + { + pFilter->filterType = TNS_FILTER_ON_ZERO; + move16(); + } + } + ELSE + { + pFilter->filterType = TNS_FILTER_OFF; + move16(); + } + } + } + ELSE IF( sts[ch]->hTcxEnc->tnsData[k].nFilters > 0 ) /* If a previous filter is turned on */ + { + pFilter->filterType = TNS_FILTER_ON_ZERO; + move16(); + sts[ch]->hTcxEnc->tnsData[k].nFilters = add( sts[ch]->hTcxEnc->tnsData[k].nFilters, 1 ); + move16(); + } + ELSE + { + pFilter->filterType = TNS_FILTER_OFF; + move16(); + } + } + + sts[ch]->hTcxEnc->fUseTns[k] = 0; + move16(); + if ( sts[ch]->hTcxEnc->tnsData[k].nFilters > 0 ) + { + sts[ch]->hTcxEnc->fUseTns[k] = 1; + move16(); + } + + test(); + test(); + IF( !bWhitenedDomain && LT_32( L_shl_sat( maxPredGain_fx, sub( maxPredGain_e, PRED_GAIN_E ) ), TNS_GAIN_THRESHOLD_FOR_WHITE_FX_IN_Q23 ) && NE_16( sts[ch]->hTcxEnc->transform_type[k], TCX_5 ) ) + { + sts[ch]->hTcxEnc->fUseTns[k] = 0; + move16(); + sts[ch]->hTcxEnc->bTnsOnWhithenedSpectra[k] = 1; + move16(); + sts[ch]->hTcxEnc->tnsData[k].nFilters = 0; + move16(); + FOR( iFilter = sts[ch]->hTcxCfg->pCurrentTnsConfig->nMaxFilters - 1; iFilter >= 0; iFilter-- ) + { + ClearTnsFilterCoefficients( sts[ch]->hTcxEnc->tnsData[k].filter + iFilter ); + sts[ch]->hTcxEnc->tnsData[k].filter[iFilter].filterType = TNS_FILTER_OFF; + move16(); + } + } + + // maxPredictionGain_fx = L_max( maxPredictionGain_fx, maxPredGain_fx ); + IF( GT_32( maxPredGain_fx, L_shl_sat( maxPredictionGain_fx, sub( maxPredictionGain_e, maxPredGain_e ) ) ) ) /* maxPredGain_e */ + { + maxPredictionGain_fx = maxPredGain_fx; + maxPredictionGain_e = maxPredGain_e; + move32(); + move16(); + } + } + } + } + + + /* we have the decision, set filter data accordingly */ + FOR( ch = 0; ch < CPE_CHANNELS; ch++ ) + { + IF( EQ_16( sts[ch]->mct_chan_mode, MCT_CHAN_MODE_IGNORE ) ) + { + CONTINUE; + } + + IF( EQ_16( sts[ch]->hTcxEnc->tcxMode, TCX_20 ) ) + { + nSubframes = 1; + } + ELSE + { + nSubframes = NB_DIV; + } + move16(); + FOR( k = 0; k < nSubframes; k++ ) + { + test(); + test(); + IF( sts[ch]->hTcxCfg->fIsTNSAllowed && ( !bWhitenedDomain || sts[ch]->hTcxEnc->bTnsOnWhithenedSpectra[k] ) ) + { + sts[ch]->hTcxCfg->pCurrentTnsConfig = &sts[ch]->hTcxCfg->tnsConfig[sts[ch]->hTcxEnc->transform_type[k] == TCX_20][( k == 0 ) && ( sts[ch]->last_core == ACELP_CORE )]; + + FOR( iFilter = sts[ch]->hTcxCfg->pCurrentTnsConfig->nMaxFilters - 1; iFilter >= 0; iFilter-- ) + { + STnsFilter *pFilter; + pFilter = sts[ch]->hTcxEnc->tnsData[k].filter + iFilter; + SWITCH( pFilter->filterType ) + { + case TNS_FILTER_OFF: + ClearTnsFilterCoefficients( sts[ch]->hTcxEnc->tnsData[k].filter + iFilter ); + BREAK; + case TNS_FILTER_ON_ZERO: + /* Since TNS filter of order 0 is not allowed we have to signal in the stream filter of order 1 with the 0th coefficient equal to 0 */ + ClearTnsFilterCoefficients( pFilter ); + pFilter->order = 1; + move16(); + BREAK; + } + } + } + } + } + + /* Apply filters, loop over channels */ + FOR( ch = 0; ch < CPE_CHANNELS; ch++ ) + { + st = sts[ch]; + IF( EQ_32( st->mct_chan_mode, MCT_CHAN_MODE_IGNORE ) ) + { + CONTINUE; + } + + IF( EQ_16( st->hTcxEnc->tcxMode, TCX_20 ) ) + { + nSubframes = 1; + } + ELSE + { + nSubframes = NB_DIV; + } + move16(); + + FOR( k = 0; k < nSubframes; k++ ) + { + test(); + test(); + test(); + test(); + test(); + IF( bWhitenedDomain && ( ch > 0 ) && /* test for identical TNS filter data in both channels */ + sts[0]->hTcxCfg->fIsTNSAllowed && sts[0]->hTcxEnc->fUseTns[k] && + sts[1]->hTcxCfg->fIsTNSAllowed && sts[1]->hTcxEnc->fUseTns[k] ) + { + Word16 equalFilterData = 0; + move16(); + test(); + test(); + if ( EQ_16( sts[0]->hTcxCfg->pCurrentTnsConfig->nMaxFilters, sts[1]->hTcxCfg->pCurrentTnsConfig->nMaxFilters ) && + EQ_16( sts[0]->hTcxEnc->bTnsOnWhithenedSpectra[k], sts[1]->hTcxEnc->bTnsOnWhithenedSpectra[k] ) && + EQ_16( sts[0]->hTcxEnc->tnsData[k].nFilters, sts[1]->hTcxEnc->tnsData[k].nFilters ) ) + { + equalFilterData = 1; + move16(); + } + + IF( equalFilterData ) + { + FOR( iFilter = st->hTcxCfg->pCurrentTnsConfig->nMaxFilters - 1; iFilter >= 0; iFilter-- ) + { + const Word16 *pDataCh0 = (const Word16 *) &sts[0]->hTcxEnc->tnsData[k].filter[iFilter]; + const Word16 *pDataCh1 = (const Word16 *) &sts[1]->hTcxEnc->tnsData[k].filter[iFilter]; + Word16 i = 2 + TNS_MAX_FILTER_ORDER; /* excl. informative float data. Portable? */ + + move16(); + test(); + WHILE( ( i >= 0 ) && EQ_16( pDataCh0[i], pDataCh1[i] ) ) + { + test(); + i = sub( i, 1 ); + } + IF( i >= 0 ) + { + equalFilterData = 0; + move16(); + BREAK; + } + } + IF( equalFilterData ) + { + st->hTcxEnc->tnsData[k].nFilters = i_mult( st->hTcxEnc->tnsData[k].nFilters, -1 ); /* signals common TNS */ + move16(); + } + } + } + test(); + test(); + IF( st->hTcxCfg->fIsTNSAllowed && ( !bWhitenedDomain || st->hTcxEnc->bTnsOnWhithenedSpectra[k] ) ) + { + L_spec = st->hTcxCfg->pCurrentTnsConfig->iFilterBorders[0]; + move16(); + spectrum_fx = st->hTcxEnc->spectrum_fx[k]; + /* If TNS should be used then get the residual after applying it inplace in the spectrum */ + IF( st->hTcxEnc->fUseTns[k] ) + { + st->hTcxCfg->pCurrentTnsConfig = &st->hTcxCfg->tnsConfig[st->hTcxEnc->transform_type[k] == TCX_20][( k == 0 ) && ( st->last_core == ACELP_CORE )]; + + ApplyTnsFilter( st->hTcxCfg->pCurrentTnsConfig, &st->hTcxEnc->tnsData[k], spectrum_fx, 1 ); + } + + IF( EQ_16( st->hTcxEnc->transform_type[k], TCX_5 ) ) + { + tcx5TnsUngrouping_fx( shr( L_frame, 2 ), shr( L_spec, 1 ), st->hTcxEnc->spectrum_fx[k], ENC ); + } + + st->hTcxEnc->tnsData[k].tnsOnWhitenedSpectra = st->hTcxEnc->bTnsOnWhithenedSpectra[k]; + move16(); + EncodeTnsData_ivas_fx( st->hTcxCfg->pCurrentTnsConfig, &st->hTcxEnc->tnsData[k], param_core[ch] + k * NPRM_DIV + 1 + NOISE_FILL_RANGES + LTPSIZE, tnsSize[ch] + k, tnsBits[ch] + k ); + } + + IF( EQ_16( st->hTcxEnc->transform_type[k], TCX_5 ) ) + { + tcx5SpectrumInterleaving_fx( st->hTcxCfg->tcx5SizeFB, st->hTcxEnc->spectrum_fx[k] ); + tcx5SpectrumInterleaving_fx( st->hTcxCfg->tcx5SizeFB, mdst_spectrum_fx[ch][k] ); + } + } + } + return; +} diff --git a/lib_enc/cod_uv.c b/lib_enc/cod_uv.c deleted file mode 100644 index e748899a9667996f0776eb65127752b66796a660..0000000000000000000000000000000000000000 --- a/lib_enc/cod_uv.c +++ /dev/null @@ -1,40 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include "prot.h" -#include "wmc_auto.h" diff --git a/lib_enc/cod_uv_fx.c b/lib_enc/cod_uv_fx.c index ca17c0f2506a20a33a41b2686efcafc2a7350615..8eccddc0b822eb5eaba77b68f5eba4f6f1cc3411 100644 --- a/lib_enc/cod_uv_fx.c +++ b/lib_enc/cod_uv_fx.c @@ -64,7 +64,7 @@ void gauss_L2_fx( E_UTIL_f_convolve( code, h, y11, L_SUBFR ); /* y11: Q8+shift */ Scale_sig( y11, L_SUBFR, sub( 1, shift ) ); /* Q9 */ *gain = L_deposit_l( 0 ); - + move32(); /*Update correlations for gains coding */ tmp32 = L_shr( 21474836l /*0.01f Q31*/, 31 - 18 ); /* Q18 */ tmp32_2 = L_shr( 21474836l /*0.01f Q31*/, 31 - 18 ); /* Q18 */ @@ -76,22 +76,16 @@ void gauss_L2_fx( } tmp16 = norm_l( tmp32 ); -#ifdef BASOP_NOGLOB g_corr->y1y1 = round_fx_sat( L_shl( tmp32, tmp16 ) ); -#else - g_corr->y1y1 = round_fx( L_shl( tmp32, tmp16 ) ); -#endif g_corr->y1y1_e = sub( 31 - 18, tmp16 ); move16(); + move16(); tmp16 = norm_l( tmp32_2 ); -#ifdef BASOP_NOGLOB g_corr->y1y2 = round_fx_sat( L_shl( tmp32_2, tmp16 ) ); -#else - g_corr->y1y2 = round_fx( L_shl( tmp32_2, tmp16 ) ); -#endif g_corr->y1y2_e = sub( 31 - 18, tmp16 ); move16(); + move16(); } void gauss_L2_ivas_fx( @@ -139,29 +133,45 @@ void gauss_L2_ivas_fx( E_UTIL_f_convolve( code, h, y11, L_SUBFR ); /* y11: Q8+shift */ Scale_sig( y11, L_SUBFR, sub( 1, shift ) ); /* Q9 */ *gain = L_deposit_l( 0 ); - + move32(); /*Update correlations for gains coding */ +#ifdef FIX_ISSUE_1167 + tmp32 = L_shr( 21474836l /*0.01f Q31*/, 31 - 16 ); /* Q16 */ + tmp32_2 = L_shr( 21474836l /*0.01f Q31*/, 31 - 16 ); /* Q16 */ + FOR( i = 0; i < L_SUBFR; i++ ) + { + tmp16 = shr( y11[i], 1 ); + tmp32 = L_mac0( tmp32, tmp16, tmp16 ); /* Q16 */ + tmp32_2 = L_mac0( tmp32_2, tmp16, shr( y2[i], 1 ) ); /* Q16 */ + } +#else tmp32 = L_shr( 21474836l /*0.01f Q31*/, 31 - 18 ); /* Q18 */ tmp32_2 = L_shr( 21474836l /*0.01f Q31*/, 31 - 18 ); /* Q18 */ - FOR( i = 0; i < L_SUBFR; i++ ) { tmp32 = L_mac0( tmp32, y11[i], y11[i] ); /* Q18 */ tmp32_2 = L_mac0( tmp32_2, y11[i], y2[i] ); /* Q18 */ } +#endif tmp16 = norm_l( tmp32 ); // To be checked -#ifdef BASOP_NOGLOB g_corr->y1y1 = round_fx_sat( L_shl( tmp32, tmp16 ) ); +#ifdef FIX_ISSUE_1167 + g_corr->y1y1_e = sub( 31 - 16, tmp16 ); #else - g_corr->y1y1 = round_fx( L_shl( tmp32, tmp16 ) ); -#endif g_corr->y1y1_e = sub( 31 - 18, tmp16 ); +#endif + move16(); move16(); tmp16 = norm_l( tmp32_2 ); g_corr->y1y2 = round_fx_sat( L_shl( tmp32_2, tmp16 ) ); +#ifdef FIX_ISSUE_1167 + g_corr->y1y2_e = sub( 31 - 16, tmp16 ); +#else g_corr->y1y2_e = sub( 31 - 18, tmp16 ); +#endif + move16(); move16(); } diff --git a/lib_enc/comvad_decision.c b/lib_enc/comvad_decision.c deleted file mode 100644 index f6ca036b27f7e95c3f6ba78df12466fae5467faa..0000000000000000000000000000000000000000 --- a/lib_enc/comvad_decision.c +++ /dev/null @@ -1,41 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include "prot.h" -#include "rom_enc.h" -#include "wmc_auto.h" diff --git a/lib_enc/comvad_decision_fx.c b/lib_enc/comvad_decision_fx.c index 505e18326fb3483811fef7a6904da7b22a9d68b4..1499bbfce0e51540ecf72e3d742924df9442ebaf 100644 --- a/lib_enc/comvad_decision_fx.c +++ b/lib_enc/comvad_decision_fx.c @@ -24,10 +24,10 @@ /*#define CLDFB_VAD*/ /* test on the CLDFB-VAD */ static Word16 comvad_hangover( - const Word32 lt_snr_org, /* i : original long time SNR*/ - const Word32 snr, /* i : frequency domain SNR */ - const Word32 l_snr, /* i : long time frequency domain SNR calculated by l_speech_snr and l_silence_snr*/ - const Word32 snr_flux, /* i : average tsnr*/ + const Word32 lt_snr_org, /* i : original long time SNR Q25*/ + const Word32 snr, /* i : frequency domain SNR Q25*/ + const Word32 l_snr, /* i : long time frequency domain SNR calculated by l_speech_snr and l_silence_snr Q25*/ + const Word32 snr_flux, /* i : average tsnr Q25*/ const Word16 bw_index, /* i : band width index*/ const Word16 vad_flag, const Word16 pre_res_hang_num, /* i : residual amount of previous hangover */ @@ -379,7 +379,7 @@ static Word16 comvad_hangover( { IF( ( NE_16( noisy_type, SILENCE ) ) ) { - speech_flag--; + speech_flag = sub( speech_flag, 1 ); } ELSE { @@ -395,13 +395,13 @@ static Word16 comvad_hangover( Word16 comvad_decision_fx( VAD_CLDFB_HANDLE hVAD_CLDFB, /* i/o: CLDFB VAD state */ - const Word32 l_snr, /* i : long time frequency domain*/ - const Word32 lt_snr_org, /* i : original long time SNR*/ - const Word32 lt_snr, /* i : long time SNR calculated by fg_energy and bg_energy*/ - const Word32 snr_flux, /* i : average tsnr of several frames*/ - const Word32 snr, /* i : frequency domain SNR */ - Word32 tsnr, /* i : time domain SNR */ - const Word32 frame_energy, /* i : current frame energy */ + const Word32 l_snr, /* i : long time frequency domain Q25*/ + const Word32 lt_snr_org, /* i : original long time SNR Q25*/ + const Word32 lt_snr, /* i : long time SNR calculated by fg_energy and bg_energy Q25*/ + const Word32 snr_flux, /* i : average tsnr of several frames Q25*/ + const Word32 snr, /* i : frequency domain SNR Q25 */ + Word32 tsnr, /* i : time domain SNR Q25*/ + const Word32 frame_energy, /* i : current frame energy Q(frame_energy_Q)*/ const Word16 music_backgound_f, /* i : background music flag*/ const Word16 frame_energy_Q, /* i : the Scaling of current frame energy*/ Word16 *cldfb_addition, /* o : adjust the harmonized hangover */ @@ -443,7 +443,7 @@ Word16 comvad_decision_fx( move16(); test(); - IF( GT_32( hVAD_CLDFB->lf_snr_smooth, LS_MIN_SILENCE_SNR[hVAD_CLDFB->bw_index - CLDFBVAD_NB_ID] ) && GT_32( lt_snr_org, LT_MIN_SILENCE_SNR_FX[hVAD_CLDFB->bw_index - CLDFBVAD_NB_ID] ) ) + if ( GT_32( hVAD_CLDFB->lf_snr_smooth, LS_MIN_SILENCE_SNR[hVAD_CLDFB->bw_index - CLDFBVAD_NB_ID] ) && GT_32( lt_snr_org, LT_MIN_SILENCE_SNR_FX[hVAD_CLDFB->bw_index - CLDFBVAD_NB_ID] ) ) { noisy_type = SILENCE; move16(); @@ -477,7 +477,7 @@ Word16 comvad_decision_fx( IF( EQ_16( hVAD_CLDFB->fg_energy_count, 512 ) ) { - fg_energy = MUL_F( fg_energy, 0x6000 ); + fg_energy = MUL_F( fg_energy, 0x6000 /*.75f in Q15*/ ); hVAD_CLDFB->fg_energy_count = 384; move16(); } @@ -527,7 +527,7 @@ Word16 comvad_decision_fx( l_silence_snr_count = L_shl( hVAD_CLDFB->l_silence_snr_count, Qnorm_silence_count ); snr_div_fix = div_l( l_silence_snr, extract_h( l_silence_snr_count ) ); } - snr_sub = L_sub( snr, 0x3000000 ); + snr_sub = L_sub( snr, 0x3000000 /*1.5f in Q25*/ ); snr_div_fix32 = L_deposit_l( snr_div_fix ); snr_div_fix32 = L_shr( snr_div_fix32, add( 6, sub( Qnorm_silence, Qnorm_silence_count ) ) ); @@ -536,7 +536,7 @@ Word16 comvad_decision_fx( { IF( EQ_32( hVAD_CLDFB->l_speech_snr_count, 512 ) ) { - hVAD_CLDFB->l_speech_snr = L_add( MUL_F( hVAD_CLDFB->l_speech_snr, 0x6000 ), L_shr( snr, 9 ) ); + hVAD_CLDFB->l_speech_snr = L_add( MUL_F( hVAD_CLDFB->l_speech_snr, 0x6000 /*.75f in Q15*/ ), L_shr( snr, 9 ) ); move32(); hVAD_CLDFB->l_speech_snr_count = L_deposit_l( 384 + 1 ); move32(); @@ -557,7 +557,7 @@ Word16 comvad_decision_fx( { Word32 lt_snr_add; - lt_snr_add = L_add( 0x03cccccd, MUL_F( lt_snr, 0x23d7 ) ); + lt_snr_add = L_add( 0x03cccccd /*1.9 in Q25*/, MUL_F( lt_snr, 0x23d7 ) ); if ( GT_32( snr_flux, lt_snr_add ) ) { @@ -593,7 +593,7 @@ Word16 comvad_decision_fx( { Word32 lt_snr_add; - lt_snr_add = L_add( 0x04333333, MUL_F( lt_snr, 0x1eb8 ) ); + lt_snr_add = L_add( 0x04333333 /*2.1 in Q25*/, MUL_F( lt_snr, 0x1eb8 ) ); if ( GT_32( snr_flux, lt_snr_add ) ) { @@ -629,7 +629,7 @@ Word16 comvad_decision_fx( { Word32 lt_snr_add; - lt_snr_add = L_add( 0x04333333, MUL_F( lt_snr, 0x28f5 ) ); + lt_snr_add = L_add( 0x04333333 /*2.1 Q25*/, MUL_F( lt_snr, 0x28f5 ) ); if ( ( GT_32( snr_flux, lt_snr_add ) ) ) { @@ -671,7 +671,8 @@ Word16 comvad_decision_fx( test(); if ( GT_16( hVAD_CLDFB->ltd_stable_rate[0], 2621 /* 0.08 Q15 */ ) && EQ_16( vad_flag, 1 ) && ( tmpout > 0 ) ) { - hVAD_CLDFB->fg_energy_est_start = L_deposit_l( 1 ); + hVAD_CLDFB->fg_energy_est_start = 1; + move32(); } } @@ -694,7 +695,7 @@ Word16 comvad_decision_fx( move16(); } vadb_flag = vad_flag; - + move16(); IF( EQ_16( hVAD_CLDFB->bw_index, CLDFBVAD_SWB_ID ) ) { test(); @@ -710,13 +711,14 @@ Word16 comvad_decision_fx( test(); test(); test(); - IF( GT_32( snr_flux, 83886078 /* 2.5 Q25 */ ) || ( hVAD_CLDFB->continuous_speech_num2 > 40 && GT_32( snr_flux, 67108862 /* 2.0 Q25 */ ) ) || music_backgound_f == 1 ) + IF( GT_32( snr_flux, 83886078 /* 2.5 Q25 */ ) || ( hVAD_CLDFB->continuous_speech_num2 > 40 && GT_32( snr_flux, 67108862 /* 2.0 Q25 */ ) ) || EQ_16( music_backgound_f, 1 ) ) { vad_flag = s_or( vad_flag, vada_flag ); } ELSE IF( EQ_16( SILENCE, noisy_type ) ) { vad_flag = vada_flag; + move16(); } } } @@ -735,13 +737,14 @@ Word16 comvad_decision_fx( test(); test(); test(); - IF( GT_32( snr_flux, 73819748 /* 2.2 Q25 */ ) || ( hVAD_CLDFB->continuous_speech_num2 > 40 && GT_32( snr_flux, 57042532 /* 1.7 Q25 */ ) ) || music_backgound_f == 1 ) + IF( GT_32( snr_flux, 73819748 /* 2.2 Q25 */ ) || ( hVAD_CLDFB->continuous_speech_num2 > 40 && GT_32( snr_flux, 57042532 /* 1.7 Q25 */ ) ) || EQ_16( music_backgound_f, 1 ) ) { vad_flag = s_or( vad_flag, vada_flag ); } ELSE IF( EQ_16( SILENCE, noisy_type ) ) { vad_flag = vada_flag; + move16(); } } } @@ -753,6 +756,7 @@ Word16 comvad_decision_fx( IF( GT_32( hVAD_CLDFB->lf_snr_smooth, 419430388 /* 12.5 Q25 */ ) && music_backgound_f == 0 ) { vad_flag = vada_flag; + move16(); } } ELSE @@ -760,7 +764,7 @@ Word16 comvad_decision_fx( test(); test(); test(); - IF( GT_32( snr_flux, 67108862 /* 2.0 Q25 */ ) || ( hVAD_CLDFB->continuous_speech_num2 > 30 && GT_32( snr_flux, 50331647 /* 1.5 Q25 */ ) ) || music_backgound_f == 1 ) + IF( GT_32( snr_flux, 67108862 /* 2.0 Q25 */ ) || ( GT_16( hVAD_CLDFB->continuous_speech_num2, 30 ) && GT_32( snr_flux, 50331647 /* 1.5 Q25 */ ) ) || EQ_16( music_backgound_f, 1 ) ) { vad_flag = s_or( vad_flag, vada_flag ); } @@ -771,7 +775,7 @@ Word16 comvad_decision_fx( { IF( EQ_32( hVAD_CLDFB->l_silence_snr_count, 512 ) ) { - hVAD_CLDFB->l_silence_snr = L_add( MUL_F( hVAD_CLDFB->l_silence_snr, 0x6000 ), L_shr( snr, 9 ) ); + hVAD_CLDFB->l_silence_snr = L_add( MUL_F( hVAD_CLDFB->l_silence_snr, 0x6000 /*.75f Q15*/ ), L_shr( snr, 9 ) ); move32(); hVAD_CLDFB->l_silence_snr_count = L_deposit_l( 384 + 1 ); move32(); @@ -789,7 +793,7 @@ Word16 comvad_decision_fx( { IF( EQ_16( hVAD_CLDFB->bg_energy_count, 512 ) ) { - bg_energy = MUL_F( bg_energy, 0x6000 ); + bg_energy = MUL_F( bg_energy, 0x6000 /*.75f Q15*/ ); hVAD_CLDFB->bg_energy_count = 384; move16(); } @@ -804,9 +808,11 @@ Word16 comvad_decision_fx( test(); hVAD_CLDFB->vad_flag_for_bk_update = vad_flag; + move16(); IF( LT_16( hVAD_CLDFB->update_count, 12 ) && EQ_16( vadb_flag, 1 ) ) { hVAD_CLDFB->warm_hang_num = s_max( 20, speech_flag ); + move16(); } test(); IF( vad_flag == 0 && hVAD_CLDFB->warm_hang_num > 0 ) @@ -814,6 +820,7 @@ Word16 comvad_decision_fx( hVAD_CLDFB->warm_hang_num = sub( hVAD_CLDFB->warm_hang_num, 1 ); vad_flag = 1; move16(); + move16(); } @@ -827,15 +834,16 @@ Word16 comvad_decision_fx( hVAD_CLDFB->speech_flag = speech_flag; move16(); - move16(); test(); IF( EQ_16( noisy_type, SILENCE ) && NE_16( hVAD_CLDFB->bw_index, CLDFBVAD_NB_ID ) ) { *cldfb_addition = 2; + move16(); } ELSE { *cldfb_addition = 0; + move16(); if ( EQ_16( hVAD_CLDFB->bw_index, CLDFBVAD_WB_ID ) ) { diff --git a/lib_enc/cor_shif.c b/lib_enc/cor_shif.c deleted file mode 100644 index 825401325748d89d4db5894372ff8dd2e53d76ec..0000000000000000000000000000000000000000 --- a/lib_enc/cor_shif.c +++ /dev/null @@ -1,41 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include -#include "prot.h" -#include "wmc_auto.h" diff --git a/lib_enc/cor_shif_fx.c b/lib_enc/cor_shif_fx.c index 1120235052e6863cee83f1794f0cc5697929428a..28e837f486cc10b95f9852599f2b98002369c087 100644 --- a/lib_enc/cor_shif_fx.c +++ b/lib_enc/cor_shif_fx.c @@ -40,13 +40,9 @@ Word16 correlation_shift_fx( /* o : noise dependent f_Noise = L_Extract_lc( Ltmp, &e_Noise ); wtmp = extract_l( Pow2( 14, f_Noise ) ); /* Put 14 as exponent */ - e_Noise = sub( e_Noise, 14 ); /* Retreive exponent of wtmp */ - Ltmp = Mpy_32_16( 8, 837, wtmp ); /* 2.4492e-4(Q31) * exp(0.1596*totalNoise) */ -#ifdef BASOP_NOGLOB - Ltmp = L_shl_sat( Ltmp, add( e_Noise, 15 ) ); /* Result in Q31 */ -#else - Ltmp = L_shl( Ltmp, add( e_Noise, 15 ) ); /* Result in Q31 */ -#endif + e_Noise = sub( e_Noise, 14 ); /* Retreive exponent of wtmp */ + Ltmp = Mpy_32_16( 8, 837, wtmp ); /* 2.4492e-4(Q31) * exp(0.1596*totalNoise) */ + Ltmp = L_shl_sat( Ltmp, add( e_Noise, 15 ) ); /* Result in Q31 */ corr_shift_fx = round_fx( L_sub( Ltmp, 47244640 ) ); /* Represents corr_shift in Q15 */ } corr_shift_fx = s_min( corr_shift_fx, 16384 ); /* limit to 0.5 */ diff --git a/lib_enc/core_enc_2div.c b/lib_enc/core_enc_2div.c deleted file mode 100644 index 0fe8682daace6673130ca2ca05de2a188e8e2ae0..0000000000000000000000000000000000000000 --- a/lib_enc/core_enc_2div.c +++ /dev/null @@ -1,42 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include "cnst.h" -#include "prot.h" -#include "rom_com.h" -#include "wmc_auto.h" diff --git a/lib_enc/core_enc_2div_fx.c b/lib_enc/core_enc_2div_fx.c index 151561b091bea6801e7c95d3ddd5cc9bdfba53c4..fa74ec6b562f88a5e675aba13685de56fa703fdb 100644 --- a/lib_enc/core_enc_2div_fx.c +++ b/lib_enc/core_enc_2div_fx.c @@ -22,7 +22,7 @@ *-------------------------------------------------------------------*/ void core_encode_twodiv_fx( - const Word16 new_samples[], /* i : new samples */ + const Word16 new_samples[], /* i : new samples */ Encoder_State *st, /* i/o: coder memory state */ const Word16 coder_type, /* i : coding type */ Word16 Aw[NB_SUBFR16k * ( M + 1 )], /* i : weighted A(z) unquant. for subframes*/ @@ -60,9 +60,7 @@ void core_encode_twodiv_fx( spectrum[1] = spectrum_buf + N_TCX10_MAX; hm_cfg[0].indexBuffer = &indexBuffer[0]; - move16(); hm_cfg[1].indexBuffer = &indexBuffer[N_MAX / 2 + 1]; - move16(); move16(); move16(); @@ -203,19 +201,19 @@ void core_encode_twodiv_fx( /* calculate noise-filling over whole spectrum for TCX10 frames */ move16(); - hTcxEnc->measuredBwRatio = 0x4000; + hTcxEnc->measuredBwRatio = 0x4000; // 1 in Q14 FOR( n = 0; n < 2; n++ ) { target_bits = sub( shr( sub( add( bitsAvailable, 1 ), n ), 1 ), tnsBits[n] ); - if ( n == 0 ) + IF( n == 0 ) { target_bits = sub( target_bits, ltpBits ); } test(); - if ( st->enablePlcWaveadjust && n ) + IF( st->enablePlcWaveadjust && n ) { target_bits = sub( target_bits, 1 ); } @@ -285,7 +283,7 @@ void core_encode_twodiv_fx( /* subtract bits for TCX overlap mode (1 bit: full, 2 bits: half or no overlap) */ target_bits = sub( target_bits, 1 ); test(); - if ( EQ_16( st->hTcxCfg->tcx_curr_overlap_mode, HALF_OVERLAP ) || EQ_16( st->hTcxCfg->tcx_curr_overlap_mode, MIN_OVERLAP ) ) + IF( EQ_16( st->hTcxCfg->tcx_curr_overlap_mode, HALF_OVERLAP ) || EQ_16( st->hTcxCfg->tcx_curr_overlap_mode, MIN_OVERLAP ) ) { target_bits = sub( target_bits, 1 ); } @@ -293,7 +291,7 @@ void core_encode_twodiv_fx( target_bits = sub( target_bits, st->hIGFEnc->infoTotalBitsPerFrameWritten ); - if ( st->enablePlcWaveadjust ) + IF( st->enablePlcWaveadjust ) { target_bits = sub( target_bits, 1 ); } diff --git a/lib_enc/core_enc_init.c b/lib_enc/core_enc_init.c deleted file mode 100644 index c378731ad5ad216a71d2715360d782733d3e1b29..0000000000000000000000000000000000000000 --- a/lib_enc/core_enc_init.c +++ /dev/null @@ -1,1265 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include "options_warnings.h" -#include "cnst.h" -#include "prot.h" -#include "ivas_prot.h" -#include "rom_com.h" -#include "wmc_auto.h" -#include "prot_fx.h" -#include "prot_fx_enc.h" - -#include "prot_fx.h" - -/*-----------------------------------------------------------------------* - * Local function prototypes - *-----------------------------------------------------------------------*/ -static void init_tcx_ivas_fx( Encoder_State *st, const Word16 L_frame_old, const Word32 total_brate, const Word32 last_total_brate, const Word16 MCT_flag ); -static void init_core_sig_ana_ivas_fx( Encoder_State *st ); -static void init_modes_ivas_fx( Encoder_State *st, const int32_t last_total_brate ); -static void init_sig_buffers_ivas_fx( Encoder_State *st, const Word16 L_frame_old, const Word16 L_subfr ); -static void init_acelp_ivas_fx( Encoder_State *st, Word16 L_frame_old, Word16 shift ); -/*-----------------------------------------------------------------------* - * init_coder_ace_plus() - * - * Initialization of state variables - *-----------------------------------------------------------------------*/ -void init_coder_ace_plus_ivas_fx( - Encoder_State *st, /* i : Encoder state */ - const Word32 last_total_brate, /* i : last total bitrate */ - const Word16 MCT_flag /* i : hMCT handle allocated (1) or not (0) */ -) -{ - TCX_ENC_HANDLE hTcxEnc = st->hTcxEnc; - Word16 L_frame_old; /*keep old frame size for switching */ - Word16 L_subfr; - - /* Bitrate */ - st->tcxonly = getTcxonly_ivas_fx( st->element_mode, st->total_brate, MCT_flag, st->is_ism_format ); - move16(); - - /* Core Sampling Rate */ - st->sr_core = getCoreSamplerateMode2( st->element_mode, st->total_brate, st->bwidth, st->flag_ACELP16k, st->rf_mode, st->is_ism_format ); - st->fscale = sr2fscale_fx( st->sr_core ); - move32(); - move16(); - - /* Narrowband? */ - IF( EQ_16( st->bwidth, NB ) ) - { - st->narrowBand = 1; - move16(); - } - ELSE - { - st->narrowBand = 0; - move16(); - } - - /* Core Framing */ - L_frame_old = st->last_L_frame; - move16(); - st->L_frame = extract_l( Mult_32_16( st->sr_core, 0x0290 ) ); /* 0x0290 is 1/FRAMES_PER_SEC in Q15*/ - move16(); - st->L_frame_past = -1; - move16(); - - IF( hTcxEnc != NULL ) - { - hTcxEnc->L_frameTCX = extract_l( Mult_32_16( st->input_Fs, 0x0290 ) ); /* 0x0290 is 1/FRAMES_PER_SEC in Q15*/ - move16(); - - IF( st->ini_frame == 0 ) - { - set16_fx( hTcxEnc->Txnq, 0, L_FRAME32k / 2 + 64 ); - hTcxEnc->acelp_zir = hTcxEnc->Txnq + L_FRAME / 2; - hTcxEnc->q_Txnq = Q15; - move16(); - hTcxEnc->tcx_target_bits_fac = ONE_IN_Q14; - move16(); - } - } - - test(); - test(); - test(); - test(); - test(); - IF( ( EQ_16( st->element_mode, EVS_MONO ) && EQ_32( st->L_frame, L_FRAME16k ) && LE_32( st->total_brate, ACELP_32k ) ) || ( GT_16( st->element_mode, EVS_MONO ) && EQ_32( st->L_frame, L_FRAME16k ) && LE_32( st->total_brate, MAX_ACELP_BRATE ) ) ) - { - st->nb_subfr = NB_SUBFR16k; - move16(); - } - ELSE - { - st->nb_subfr = NB_SUBFR; - move16(); - } - L_subfr = idiv1616( st->L_frame, st->nb_subfr ); - - /* Core Lookahead */ - st->encoderLookahead_enc = NS2SA_FX2( st->sr_core, ACELP_LOOK_NS ); - st->encoderLookahead_FB = NS2SA_FX2( st->input_Fs, ACELP_LOOK_NS ); - move16(); - move16(); - - IF( st->ini_frame == 0 ) - { - st->acelpFramesCount = 0; - move16(); - st->prevTempFlatness_fx = 128 /*1.0f Q7*/; - move16(); - } - - /* Initialize TBE */ - IF( st->hBWE_TD != NULL ) - { - st->hBWE_TD->prev_coder_type = GENERIC; - move16(); - set16_fx( st->hBWE_TD->prev_lsf_diff_fx, 16384, LPC_SHB_ORDER - 2 ); - st->hBWE_TD->prev_tilt_para_fx = 0; - move16(); - set16_fx( st->hBWE_TD->cur_sub_Aq_fx, 0, M + 1 ); - } - - st->currEnergyHF_fx = 0; - move32(); - - test(); - /* Initialize LPC analysis/quantization */ - IF( LE_32( st->sr_core, INT_FS_16k ) && st->tcxonly == 0 ) - { - st->lpcQuantization = 1; - move16(); - } - ELSE - { - st->lpcQuantization = 0; - move16(); - } - - st->next_force_safety_net = 0; - move16(); - test(); - test(); - IF( ( NE_16( st->last_L_frame, st->L_frame ) ) || ( EQ_16( st->last_core, AMR_WB_CORE ) ) || ( EQ_16( st->last_core, HQ_CORE ) ) ) - { - set16_fx( st->mem_MA_fx, 0, M ); - Copy( GEWB_Ave_fx, st->mem_AR_fx, M ); - } - - /* Initialize IGF */ - if ( st->hIGFEnc != NULL ) - { - st->hIGFEnc->infoStopFrequency = -1; - move16(); - } - - test(); - IF( st->igf && st->hIGFEnc != NULL ) - { - IGFEncSetMode_ivas_fx( st->hIGFEnc, st->total_brate, st->bwidth, st->element_mode, st->rf_mode ); - } - ELSE IF( st->hIGFEnc != NULL ) - { - st->hIGFEnc->infoTotalBitsWritten = 0; - move16(); - st->hIGFEnc->infoTotalBitsPerFrameWritten = 0; - move16(); - } - - /* Initialize Core Signal Analysis Module */ - init_core_sig_ana_ivas_fx( st ); - - - /* Initialize TCX */ - IF( hTcxEnc != NULL ) - { - init_tcx_ivas_fx( st, L_frame_old, st->total_brate, last_total_brate, MCT_flag ); - } - - /* Initialize Signal Buffers */ - init_sig_buffers_ivas_fx( st, L_frame_old, L_subfr ); - - /* Initialize ACELP */ - - init_acelp_ivas_fx( st, L_frame_old, 0 ); - - IF( st->ini_frame == 0 ) - { - st->tec_tfa = 0; - move16(); - } - - IF( st->hTECEnc != NULL ) - { - resetTecEnc_Fx( st->hTECEnc, st->tec_tfa ); - } - - test(); - test(); - test(); - IF( EQ_16( st->bwidth, SWB ) && ( EQ_32( st->total_brate, ACELP_16k40 ) || EQ_32( st->total_brate, ACELP_24k40 ) ) && EQ_16( st->element_mode, EVS_MONO ) ) - { - st->tec_tfa = 1; - move16(); - } - ELSE - { - st->tec_tfa = 0; - move16(); - } - - st->tec_flag = 0; - move16(); - st->tfa_flag = 0; - move16(); - - test(); - test(); - test(); - IF( ( EQ_32( st->total_brate, ACELP_9k60 ) || EQ_32( st->total_brate, ACELP_16k40 ) || EQ_32( st->total_brate, ACELP_24k40 ) ) && EQ_16( st->element_mode, EVS_MONO ) ) - { - st->glr = 1; - move16(); - } - ELSE - { - st->glr = 0; - move16(); - } - - st->glr_reset = 0; - move16(); - - /* Initialize ACELP/TCX Modes */ - init_modes_ivas_fx( st, last_total_brate ); - - /* Adaptive BPF */ - set32_fx( st->mem_bpf_fx1, 0, 2 * L_FILT16k ); - set32_fx( st->mem_error_bpf_fx, 0, 2 * L_FILT16k ); - - IF( st->ini_frame == 0 ) - { - st->Q_max_enc[0] = 15; - move16(); - st->Q_max_enc[1] = 15; - move16(); - } - - IF( GE_32( st->total_brate, HQ_48k ) ) - { - st->enablePlcWaveadjust = 1; - move16(); - } - ELSE - { - st->enablePlcWaveadjust = 0; - move16(); - } - - IF( st->hPlcExt ) - { - init_PLC_enc_fx( st->hPlcExt, st->sr_core ); - } - - st->glr_idx[0] = 0; - move16(); - st->glr_idx[1] = 0; - move16(); - st->mean_gc[0] = 0; - move16(); - st->mean_gc[1] = 0; - move16(); - st->prev_lsf4_mean = 0; - move16(); - st->last_stab_fac = 0; - move16(); - - return; -} - -void init_coder_ace_plus( - Encoder_State *st, /* i : Encoder state */ - const int32_t last_total_brate, /* i : last total bitrate */ - const int16_t MCT_flag /* i : hMCT handle allocated (1) or not (0) */ -) -{ - TCX_ENC_HANDLE hTcxEnc = st->hTcxEnc; - int16_t L_frame_old; /*keep old frame size for switching */ - int16_t L_subfr; - - /* Bitrate */ - st->tcxonly = getTcxonly_ivas_fx( st->element_mode, st->total_brate, MCT_flag, st->is_ism_format ); - - /* Core Sampling Rate */ - st->sr_core = getCoreSamplerateMode2_flt( st->element_mode, st->total_brate, st->bwidth, st->flag_ACELP16k, st->rf_mode, st->is_ism_format ); - st->fscale = sr2fscale( st->sr_core ); - - /* Narrowband? */ - st->narrowBand = ( st->bwidth == NB ) ? 1 : 0; - - /* Core Framing */ - L_frame_old = st->last_L_frame; - st->L_frame = (int16_t) ( st->sr_core / FRAMES_PER_SEC ); - st->L_frame_past = -1; - - if ( hTcxEnc != NULL ) - { - hTcxEnc->L_frameTCX = (int16_t) ( st->input_Fs / FRAMES_PER_SEC ); - - if ( st->ini_frame == 0 ) - { - hTcxEnc->tcx_target_bits_fac = ONE_IN_Q14; - - set16_fx( hTcxEnc->Txnq, 0, L_FRAME32k / 2 + 64 ); - hTcxEnc->acelp_zir = hTcxEnc->Txnq + L_FRAME / 2; - hTcxEnc->q_Txnq = Q15; - move16(); - } - } - - if ( ( st->element_mode == EVS_MONO && st->L_frame == L_FRAME16k && st->total_brate <= ACELP_32k ) || ( st->element_mode > EVS_MONO && st->L_frame == L_FRAME16k && st->total_brate <= MAX_ACELP_BRATE ) ) - { - st->nb_subfr = NB_SUBFR16k; - } - else - { - st->nb_subfr = NB_SUBFR; - } - L_subfr = st->L_frame / st->nb_subfr; - - /* Core Lookahead */ - st->encoderLookahead_enc = NS2SA( st->sr_core, ACELP_LOOK_NS ); - st->encoderLookahead_FB = NS2SA( st->input_Fs, ACELP_LOOK_NS ); - - if ( st->ini_frame == 0 ) - { - st->acelpFramesCount = 0; -#ifdef MSAN_FIX - st->prevTempFlatness_fx = 128; // Q7 -#endif - } - - /* Initialize TBE */ - if ( st->hBWE_TD != NULL ) - { - st->hBWE_TD->prev_coder_type = GENERIC; - set16_fx( st->hBWE_TD->prev_lsf_diff_fx, 16384, LPC_SHB_ORDER - 2 ); - st->hBWE_TD->prev_tilt_para_fx = 0; - set16_fx( st->hBWE_TD->cur_sub_Aq_fx, 0, M + 1 ); - move16(); - } - - st->currEnergyHF_fx = 0; - move32(); - - /* Initialize LPC analysis/quantization */ - if ( st->sr_core <= INT_FS_16k && st->tcxonly == 0 ) - { - st->lpcQuantization = 1; - } - else - { - st->lpcQuantization = 0; - } - - st->next_force_safety_net = 0; - if ( ( st->last_L_frame != st->L_frame ) || ( st->last_core == AMR_WB_CORE ) || ( st->last_core == HQ_CORE ) ) - { - set16_fx( st->mem_MA_fx, 0, M ); - Copy( GEWB_Ave_fx, st->mem_AR_fx, M ); - } - - /* Initialize IGF */ - if ( st->hIGFEnc != NULL ) - { - st->hIGFEnc->infoStopFrequency = -1; - } - - if ( st->igf && st->hIGFEnc != NULL ) - { - IGFEncSetMode_ivas_fx( st->hIGFEnc, st->total_brate, st->bwidth, st->element_mode, st->rf_mode ); - } - else if ( st->hIGFEnc != NULL ) - { - st->hIGFEnc->infoTotalBitsWritten = 0; - st->hIGFEnc->infoTotalBitsPerFrameWritten = 0; - } - - /* Initialize Core Signal Analysis Module */ - init_core_sig_ana_ivas_fx( st ); - - /* Initialize TCX */ - if ( hTcxEnc != NULL ) - { - init_tcx_ivas_fx( st, L_frame_old, st->total_brate, last_total_brate, MCT_flag ); - } - - /* Initialize Signal Buffers */ - init_sig_buffers_ivas_fx( st, L_frame_old, L_subfr ); - - /* Initialize ACELP */ - init_acelp_ivas_fx( st, L_frame_old, 0 ); - - if ( st->ini_frame == 0 ) - { - st->tec_tfa = 0; - } - - if ( st->hTECEnc != NULL ) - { - resetTecEnc_Fx( st->hTECEnc, st->tec_tfa ); - } - - if ( st->bwidth == SWB && ( st->total_brate == ACELP_16k40 || st->total_brate == ACELP_24k40 ) && st->element_mode == EVS_MONO ) - { - st->tec_tfa = 1; - } - else - { - st->tec_tfa = 0; - } - - st->tec_flag = 0; - st->tfa_flag = 0; - - - if ( ( st->total_brate == ACELP_9k60 || st->total_brate == ACELP_16k40 || st->total_brate == ACELP_24k40 ) && st->element_mode == EVS_MONO ) - { - st->glr = 1; - } - else - { - st->glr = 0; - } - - st->glr_reset = 0; - - /* Initialize ACELP/TCX Modes */ - init_modes_ivas_fx( st, last_total_brate ); - - /* Adaptive BPF */ - if ( st->total_brate >= HQ_48k ) - { - st->enablePlcWaveadjust = 1; - } - else - { - st->enablePlcWaveadjust = 0; - } - - set32_fx( st->mem_bpf_fx1, 0, 2 * L_FILT16k ); - set32_fx( st->mem_error_bpf_fx, 0, 2 * L_FILT16k ); - - IF( st->ini_frame == 0 ) - { - st->Q_max_enc[0] = 15; - move16(); - st->Q_max_enc[1] = 15; - move16(); - } - - IF( st->total_brate >= HQ_48k ) - { - st->enablePlcWaveadjust = 1; - move16(); - } - ELSE - { - st->enablePlcWaveadjust = 0; - move16(); - } - - if ( st->hPlcExt ) - { - init_PLC_enc_fx( st->hPlcExt, st->sr_core ); - } - - st->glr_idx[0] = 0; - st->glr_idx[1] = 0; - st->mean_gc[0] = 0; - st->mean_gc[1] = 0; - st->prev_lsf4_mean = 0; - st->last_stab_fac = 0; - - return; -} - -/*-----------------------------------------------------------------------* - * init_tcx() - * - * Initialization of TCX - *-----------------------------------------------------------------------*/ - - -static void init_tcx_ivas_fx( - Encoder_State *st, - const Word16 L_frame_old, - const Word32 total_brate, - const Word32 last_total_brate, - const Word16 MCT_flag ) -{ - TCX_ENC_HANDLE hTcxEnc = st->hTcxEnc; - - /* Share the memories for 2xTCX10/4xTCX5 and for TCX20 */ - hTcxEnc->spectrum_fx[0] = hTcxEnc->spectrum_long_fx; - hTcxEnc->spectrum_fx[1] = hTcxEnc->spectrum_long_fx + N_TCX10_MAX; - st->hTcxEnc->spectrum_e[0] = st->hTcxEnc->spectrum_e[1] = 0; - move16(); - move16(); - - init_tcx_cfg_ivas_fx( st->hTcxCfg, total_brate, st->sr_core, st->input_Fs, st->L_frame, st->bwidth, hTcxEnc->L_frameTCX, - st->fscale, st->preemph_fac, st->tcxonly, st->rf_mode, st->igf, - st->hIGFEnc != NULL ? st->hIGFEnc->infoStopFrequency : 0, st->element_mode, st->ini_frame, MCT_flag ); - - /* Init TCX target bits correction factor */ - hTcxEnc->tcx_target_bits_fac = 0x4000; /*1.0f in 1Q14*/ - move16(); - hTcxEnc->measuredBwRatio = 0x4000; /*1.0f in 1Q14*/ - move16(); - hTcxEnc->noiseTiltFactor = 9216; /*0.5625f in 1Q14*/ - move16(); - hTcxEnc->noiseLevelMemory_cnt = 0; - move16(); - - set16_fx( hTcxEnc->ltpGainMemory_fx, 0, N_LTP_GAIN_MEMS ); - set8_fx( hTcxEnc->memQuantZeros, 0, L_FRAME_PLUS ); - - /* TCX-LTP */ - hTcxEnc->tcxltp = getTcxLtp( st->sr_core ); - move16(); - - test(); - test(); - test(); - test(); - IF( st->ini_frame == 0 ) - { - hTcxEnc->tcxltp_pitch_int_past = st->L_frame; - hTcxEnc->tcxltp_pitch_fr_past = 0; - hTcxEnc->tcxltp_gain_past = 0; - hTcxEnc->tcxltp_norm_corr_past = 0; - hTcxEnc->tcxltp_norm_corr_mem = 0; - hTcxEnc->kernel_switch_corr_past = 0; - hTcxEnc->kernel_symmetry_past = 0; /* MDCT_IV & 1 */ - hTcxEnc->enc_ste_pre_corr_past = 0; - hTcxEnc->tfm_mem_fx = 1610612736; /* 0.75 in Q31 */ - hTcxEnc->tcxltp_on_mem = 0; - move16(); - move16(); - move16(); - move16(); - move16(); - move16(); - move16(); - move16(); - move16(); - move16(); - } - ELSE IF( NE_16( st->L_frame, L_frame_old ) && !( ( GE_32( total_brate, ACELP_16k40 ) && LE_32( total_brate, ACELP_24k40 ) ) && - ( EQ_32( total_brate, last_total_brate ) ) && ( EQ_16( st->last_bwidth, st->bwidth ) ) ) ) - { - Word16 pitres, pitres_old; - Word16 pit, pit_old; - - pitres_old = 4; - move16(); - if ( EQ_16( 160, shr( L_frame_old, sub( 7, norm_s( L_frame_old ) ) ) ) ) /*if ( L_frame_old%160==0 )*/ - { - pitres_old = 6; - move16(); - } - - /*pit_old = (float)st->tcxltp_pitch_int_past + (float)st->tcxltp_pitch_fr_past/(float)pitres_old;*/ - pit_old = add( hTcxEnc->tcxltp_pitch_int_past, mult_r( hTcxEnc->tcxltp_pitch_fr_past, div_s( 1, pitres_old ) ) ); - - pitres = 4; - move16(); - if ( EQ_16( 160, shr( st->L_frame, sub( 7, norm_s( st->L_frame ) ) ) ) ) /*if ( st->L_frame%160==0 )*/ - { - pitres = 6; - move16(); - } - -#ifdef BASOP_NOGLOB - /*pit = pit_old * (float)st->L_frame/(float)L_frame_old;*/ - pit = shl_sat( mult_r( pit_old, div_s( st->L_frame, shl( L_frame_old, 2 ) ) ), 2 ); - /* Note : the saturation here that can happens when FS == 32kHz*/ -#else - pit = shl( mult_r( pit_old, div_s( st->L_frame, shl( L_frame_old, 2 ) ) ), 2 ); -#endif - /* assert(pit <= st->L_frame);*/ - - hTcxEnc->tcxltp_pitch_int_past = pit; - move16(); - hTcxEnc->tcxltp_pitch_fr_past = i_mult2( sub( pit, hTcxEnc->tcxltp_pitch_int_past ), pitres ); - move16(); - } - - hTcxEnc->tcx_lpc_shaped_ari = getTcxLpcShapedAri( st->total_brate, st->rf_mode, st->element_mode ); - move16(); - - return; -} - -/*-----------------------------------------------------------------------* - * init_sig_buffers() - * - * Initialization of signal buffers - *-----------------------------------------------------------------------*/ -/*copy of evs function since it was static */ -static void init_sig_buffers_ivas_fx( Encoder_State *st, const Word16 L_frame_old, const Word16 L_subfr ) -{ - - LPD_state_HANDLE hLPDmem = st->hLPDmem; - TCX_ENC_HANDLE hTcxEnc = st->hTcxEnc; - - /* Encoder Past Samples at encoder-sampling-rate */ - st->encoderPastSamples_enc = shr( imult1616( st->L_frame, 9 ), 4 ); - move16(); - - /* Initialize Signal Buffers and Pointers at encoder-sampling-rate */ - IF( st->ini_frame == 0 ) - { - set16_fx( st->buf_speech_enc, 0, L_PAST_MAX_32k + L_FRAME32k + L_NEXT_MAX_32k ); - st->exp_buf_speech_enc = 0; - move16(); - set16_fx( st->buf_speech_enc_pe, 0, L_PAST_MAX_32k + L_FRAME32k + L_NEXT_MAX_32k ); - st->exp_buf_speech_enc_pe = 0; - move16(); - if ( hTcxEnc != NULL ) - { - set16_fx( hTcxEnc->buf_speech_ltp, 0, L_PAST_MAX_32k + L_FRAME32k + L_NEXT_MAX_32k ); - hTcxEnc->exp_buf_speech_ltp = 0; - move16(); - } - set16_fx( st->buf_wspeech_enc, 0, L_FRAME16k + L_SUBFR + L_FRAME16k + L_NEXT_MAX_16k + 320 ); /* increased by 320 to avoid memory overlap in ivas_find_wsp() and also to accomodate for the wspeech_enc */ - st->exp_buf_wspeech_enc = 0; - move16(); - } - ELSE - { - test(); - test(); - test(); - test(); - test(); - IF( NE_16( st->L_frame, L_frame_old ) && !( ( EQ_32( st->total_brate, ACELP_16k40 ) || EQ_32( st->total_brate, ACELP_24k40 ) ) && ( EQ_32( st->total_brate, st->last_total_brate ) ) && ( EQ_16( st->last_bwidth, st->bwidth ) ) ) ) - { - lerp( st->buf_speech_enc, st->buf_speech_enc, st->L_frame, L_frame_old ); - test(); - IF( NE_16( st->last_core, TCX_20_CORE ) && NE_16( st->last_core, TCX_10_CORE ) ) /* condition should be checked again */ - { - Copy( st->buf_speech_enc, hTcxEnc->buf_speech_ltp, st->L_frame ); - Scale_sig( hTcxEnc->buf_speech_ltp, st->L_frame, sub( st->exp_buf_speech_enc, s_max( st->exp_buf_speech_enc, hTcxEnc->exp_buf_speech_ltp ) ) ); - Scale_sig( hTcxEnc->buf_speech_ltp + st->L_frame, sub( L_PAST_MAX_32k + L_FRAME32k + L_NEXT_MAX_32k, st->L_frame ), sub( hTcxEnc->exp_buf_speech_ltp, s_max( st->exp_buf_speech_enc, hTcxEnc->exp_buf_speech_ltp ) ) ); - hTcxEnc->exp_buf_speech_ltp = s_max( hTcxEnc->exp_buf_speech_ltp, st->exp_buf_speech_enc ); - move16(); - } - - // Copy_Scale_sig( st->old_wsp_fx, st->buf_wspeech_enc + st->L_frame + L_SUBFR - L_WSP_MEM, L_WSP_MEM, sub( st->prev_Q_new, st->prev_Q_old ) ); - Copy( st->old_wsp_fx, st->buf_wspeech_enc + st->L_frame + L_SUBFR - L_WSP_MEM, L_WSP_MEM ); - st->exp_buf_wspeech_enc = st->exp_old_wsp; - move16(); - - /*Resamp buffers needed only for ACELP*/ - test(); - test(); - IF( EQ_16( st->L_frame, L_FRAME ) && !st->tcxonly ) - { - // Copy_Scale_sig( st->old_inp_12k8_fx, st->buf_speech_enc_pe + st->L_frame - L_INP_MEM, L_INP_MEM, sub( st->prev_Q_new, st->prev_Q_old ) ); - Copy( st->old_inp_12k8_fx, st->buf_speech_enc_pe + st->L_frame - L_INP_MEM, L_INP_MEM ); - /* SCaling to common exponent*/ - Scale_sig( st->buf_speech_enc_pe + sub( st->L_frame, L_INP_MEM ), L_INP_MEM, sub( st->exp_old_inp_12k8, s_max( st->exp_old_inp_12k8, st->exp_buf_speech_enc_pe ) ) ); - Scale_sig( st->buf_speech_enc_pe, sub( st->L_frame, L_INP_MEM ), sub( st->exp_buf_speech_enc_pe, s_max( st->exp_old_inp_12k8, st->exp_buf_speech_enc_pe ) ) ); - Scale_sig( st->buf_speech_enc_pe + st->L_frame, sub( L_PAST_MAX_32k + L_FRAME32k + L_NEXT_MAX_32k, st->L_frame ), sub( st->exp_buf_speech_enc_pe, s_max( st->exp_old_inp_12k8, st->exp_buf_speech_enc_pe ) ) ); - st->exp_buf_speech_enc_pe = s_max( st->exp_old_inp_12k8, st->exp_buf_speech_enc_pe ); - move16(); - } - ELSE IF( EQ_16( st->L_frame, L_FRAME16k ) && !st->tcxonly ) - { - lerp( st->buf_wspeech_enc + st->L_frame + L_SUBFR - L_WSP_MEM, st->buf_wspeech_enc + st->L_frame + L_SUBFR - 310, 310, L_WSP_MEM ); - Copy( st->old_inp_16k_fx, st->buf_speech_enc_pe + st->L_frame - L_INP_MEM, L_INP_MEM ); - /* SCaling to common exponent*/ - Scale_sig( st->buf_speech_enc_pe + sub( st->L_frame, L_INP_MEM ), L_INP_MEM, sub( st->exp_old_inp_16k, s_max( st->exp_old_inp_16k, st->exp_buf_speech_enc_pe ) ) ); - Scale_sig( st->buf_speech_enc_pe, sub( st->L_frame, L_INP_MEM ), sub( st->exp_buf_speech_enc_pe, s_max( st->exp_old_inp_16k, st->exp_buf_speech_enc_pe ) ) ); - Scale_sig( st->buf_speech_enc_pe + st->L_frame, sub( L_PAST_MAX_32k + L_FRAME32k + L_NEXT_MAX_32k, st->L_frame ), sub( st->exp_buf_speech_enc_pe, s_max( st->exp_old_inp_16k, st->exp_buf_speech_enc_pe ) ) ); - st->exp_buf_speech_enc_pe = s_max( st->exp_old_inp_16k, st->exp_buf_speech_enc_pe ); - move16(); - } - - st->mem_preemph_enc = st->buf_speech_enc[st->encoderPastSamples_enc + st->encoderLookahead_enc - 1]; - move16(); - st->exp_mem_preemph_enc = st->exp_buf_speech_enc; - move16(); - st->mem_wsp_enc = shr( st->buf_wspeech_enc[st->L_frame + L_SUBFR - 1], sub( Q16, st->exp_buf_wspeech_enc ) ); // Q-1 - move16(); - } - /*coming from TCXonly modes*/ - ELSE IF( !st->tcxonly && GE_32( st->last_total_brate, ACELP_32k ) ) - { - - Copy( st->old_wsp_fx, st->buf_wspeech_enc + st->L_frame + L_SUBFR - L_WSP_MEM, L_WSP_MEM ); - // Copy_Scale_sig( st->old_wsp_fx, st->buf_wspeech_enc + st->L_frame + L_SUBFR - L_WSP_MEM, L_WSP_MEM, sub( st->prev_Q_new, st->prev_Q_old ) ); - - /*Resamp buffers needed only for ACELP*/ - IF( EQ_16( st->L_frame, L_FRAME16k ) ) - { - lerp( st->buf_wspeech_enc + st->L_frame + L_SUBFR - L_WSP_MEM, st->buf_wspeech_enc + st->L_frame + L_SUBFR - 310, 310, L_WSP_MEM ); - } - hLPDmem->mem_w0 = 0; - move16(); - st->mem_wsp_enc = shr( st->buf_wspeech_enc[st->L_frame + L_SUBFR - 1], sub( Q16, st->exp_buf_wspeech_enc ) ); // Q-1 - move16(); - } - } - - st->new_speech_enc = st->buf_speech_enc + st->encoderPastSamples_enc + st->encoderLookahead_enc; - st->new_speech_enc_pe = st->buf_speech_enc_pe + st->encoderPastSamples_enc + st->encoderLookahead_enc; - if ( hTcxEnc != NULL ) - { - hTcxEnc->new_speech_ltp = hTcxEnc->buf_speech_ltp + st->encoderPastSamples_enc + st->encoderLookahead_enc; - } - - if ( st->hTcxEnc != NULL ) - { - st->hTcxEnc->new_speech_TCX = st->input_buff_fx + Mpy_32_32( st->input_Fs, ONE_BY_FRAMES_PER_SEC_Q31 ); - st->hTcxEnc->speech_TCX = st->hTcxEnc->new_speech_TCX - st->encoderLookahead_FB; - } - st->speech_enc = st->buf_speech_enc + st->encoderPastSamples_enc; - st->speech_enc_pe = st->buf_speech_enc_pe + st->encoderPastSamples_enc; - - if ( hTcxEnc != NULL ) - { - hTcxEnc->speech_ltp = hTcxEnc->buf_speech_ltp + st->encoderPastSamples_enc; - } - - IF( GT_16( st->element_mode, EVS_MONO ) ) - { - st->wspeech_enc = st->buf_wspeech_enc + st->L_frame + L_SUBFR; - } - ELSE - { - st->wspeech_enc = st->buf_wspeech_enc + st->L_frame + L_subfr; - } - - test(); - test(); - IF( st->ini_frame == 0 || NE_16( st->L_frame, L_frame_old ) || EQ_16( st->last_codec_mode, MODE1 ) ) - { - set16_fx( st->buf_synth, 0, OLD_SYNTH_SIZE_ENC + L_FRAME32k ); - } - - st->synth = st->buf_synth + st->L_frame + L_subfr; - - - return; -} - -/*-----------------------------------------------------------------------* - * init_core_sig_ana() - * - * - *-----------------------------------------------------------------------*/ -static void init_core_sig_ana_ivas_fx( Encoder_State *st ) -{ - - /* Pre-emphasis factor and memory */ - - st->preemph_fac = PREEMPH_FAC_SWB; /*SWB*/ - move16(); - IF( LT_16( st->fscale, ( 16000 * FSCALE_DENOM ) / 12800 ) ) - { - st->preemph_fac = PREEMPH_FAC; /*WB*/ - move16(); - } - ELSE IF( LT_16( st->fscale, ( 24000 * FSCALE_DENOM ) / 12800 ) ) - { - st->preemph_fac = PREEMPH_FAC_16k; /*WB*/ - move16(); - } - - st->gamma = GAMMA1; - move16(); - st->inv_gamma = GAMMA1_INV; - move16(); - IF( EQ_32( st->sr_core, 16000 ) ) - { - st->gamma = GAMMA16k; - move16(); - st->inv_gamma = GAMMA16k_INV; - move16(); - } - - - st->min_band = 1; - move16(); - st->max_band = 16; - move16(); - - IF( st->narrowBand == 0 ) - { - st->min_band = 0; - move16(); - st->max_band = 19; - move16(); - } - - - return; -} -/*-----------------------------------------------------------------------* - * init_acelp() - * - * - *-----------------------------------------------------------------------*/ -static void init_acelp_ivas_fx( Encoder_State *st, Word16 L_frame_old, Word16 shift ) -{ - Word16 mem_syn_r_size_old; - Word16 mem_syn_r_size_new; - LPD_state_HANDLE hLPDmem = st->hLPDmem; - TCX_ENC_HANDLE hTcxEnc = st->hTcxEnc; - - /* Init pitch lag */ - IF( EQ_16( st->element_mode, IVAS_CPE_MDCT ) ) - { - /* TCX LTP ana always runs @12.8kHz */ - st->pit_res_max = initPitchLagParameters( 12800, &st->pit_min, &st->pit_fr1, &st->pit_fr1b, &st->pit_fr2, &st->pit_max ); - move16(); - } - ELSE - { - st->pit_res_max = initPitchLagParameters( st->sr_core, &st->pit_min, &st->pit_fr1, &st->pit_fr1b, &st->pit_fr2, &st->pit_max ); - move16(); - } - - /* Init LPDmem */ - IF( st->ini_frame == 0 ) - { - IF( hLPDmem != NULL ) - { - set16_fx( hLPDmem->syn, 0, 1 + M ); - set16_fx( hLPDmem->mem_syn_r, 0, L_SYN_MEM ); - } - - IF( st->hTcxEnc != NULL ) - { - set16_fx( st->hTcxEnc->Txnq, 0, L_FRAME32k / 2 + 64 ); - st->hTcxEnc->q_Txnq = Q15; - move16(); - st->hTcxEnc->acelp_zir = st->hTcxEnc->Txnq + shr( st->L_frame, 1 ); - } - } - ELSE /*Rate switching*/ - { - IF( EQ_16( st->last_core, ACELP_CORE ) ) - { - lerp( hTcxEnc->Txnq, hTcxEnc->Txnq, shr( st->L_frame, 1 ), shr( L_frame_old, 1 ) ); - } - ELSE - { - lerp( hTcxEnc->Txnq, hTcxEnc->Txnq, st->hTcxCfg->tcx_mdct_window_length, st->hTcxCfg->tcx_mdct_window_length_old ); - } - hTcxEnc->acelp_zir = hTcxEnc->Txnq + shr( st->L_frame, 1 ); - - /* Rate switching */ - IF( EQ_16( st->last_codec_mode, MODE1 ) && EQ_16( st->element_mode, EVS_MONO ) ) - { - IF( hLPDmem != NULL ) - { - Copy( hLPDmem->mem_syn1_fx, hLPDmem->mem_syn2, M ); - set16_fx( hLPDmem->syn, 0, M ); - hLPDmem->q_lpd_syn = Q15; - move16(); - } - IF( st->hTcxEnc != NULL ) - { - set16_fx( hTcxEnc->Txnq, 0, L_FRAME32k / 2 + 64 ); - st->hTcxEnc->q_Txnq = Q15; - move16(); - } - } - - /*AMR-WBIO->MODE2*/ - IF( EQ_16( st->last_core, AMR_WB_CORE ) ) - { - st->next_force_safety_net = 1; - move16(); - st->last_core = ACELP_CORE; - move16(); - } - /*HQ-CORE->MODE2*/ - test(); - IF( EQ_16( st->last_codec_mode, MODE1 ) && EQ_16( st->last_core, HQ_CORE ) ) - { - /*Reset of ACELP memories*/ - st->next_force_safety_net = 1; - move16(); - st->rate_switching_reset = 1; - move16(); - IF( hLPDmem != NULL ) - { - hLPDmem->tilt_code = TILT_CODE; - move16(); - set16_fx( hLPDmem->old_exc, 0, L_EXC_MEM ); - set16_fx( hLPDmem->syn, 0, 1 + M ); - hLPDmem->q_lpd_syn = Q15; - move16(); - hLPDmem->q_lpd_old_exc = Q15; - move16(); - hLPDmem->mem_w0 = 0; - move16(); - set16_fx( hLPDmem->mem_syn, 0, M ); - set16_fx( hLPDmem->mem_syn2, 0, M ); - hLPDmem->q_mem_syn = Q15; - move16(); - } - - /* unquantized LPC*/ - test(); - test(); - test(); - IF( !( ( GE_32( st->total_brate, ACELP_16k40 ) && LE_32( st->total_brate, ACELP_24k40 ) ) && ( EQ_32( st->total_brate, st->last_total_brate ) ) && ( EQ_16( st->last_bwidth, st->bwidth ) ) ) ) - { - Copy( st->lsp_old1_fx, st->lspold_enc_fx, M ); /*lsp old @12.8kHz*/ - IF( EQ_16( st->L_frame, L_FRAME16k ) ) - { - lsp_convert_poly_fx( st->lspold_enc_fx, st->L_frame, 0 ); - } - } - Copy( st->lspold_enc_fx, st->lsp_old_fx, M ); /*used unquantized values for mid-LSF Q*/ - IF( st->tcxonly == 0 ) - { - lsp2lsf_fx( st->lsp_old_fx, st->lsf_old_fx, M, st->sr_core ); - } - ELSE - { - E_LPC_lsp_lsf_conversion( st->lsp_old_fx, st->lsf_old_fx, M ); - } - st->last_core = TCX_20_CORE; - move16(); - - st->hTcxCfg->last_aldo = 1; /*It was previously ALDO*/ - st->hTcxCfg->tcx_curr_overlap_mode = ALDO_WINDOW; - move16(); - move16(); - /*ALDO overlap windowed past: also used in MODE1 but for other MDCT-FB*/ - set16_fx( hTcxEnc->old_out_fx, 0, st->L_frame ); - } - ELSE - { - test(); - test(); - test(); - test(); - IF( ( NE_16( st->L_frame, L_frame_old ) ) && ( LE_16( st->L_frame, L_FRAME16k ) ) && ( LE_16( L_frame_old, L_FRAME16k ) ) ) - { - /* convert quantized LSP vector */ - st->rate_switching_reset = lsp_convert_poly_fx( st->lsp_old_fx, st->L_frame, 0 ); - move16(); - IF( st->tcxonly == 0 ) - { - lsp2lsf_fx( st->lsp_old_fx, st->lsf_old_fx, M, st->sr_core ); - } - ELSE - { - E_LPC_lsp_lsf_conversion( st->lsp_old_fx, st->lsf_old_fx, M ); - } - IF( EQ_16( st->L_frame, L_FRAME16k ) ) - { - Copy( st->lsp_old_fx, st->lspold_enc_fx, M ); - } - ELSE - { - Copy( st->lsp_old1_fx, st->lspold_enc_fx, M ); - } - - - /*Mem of deemphasis stay unchanged : hLPDmem->syn*/ - IF( hLPDmem != NULL ) - { - synth_mem_updt2( st->L_frame, st->last_L_frame, hLPDmem->old_exc, hLPDmem->mem_syn_r, hLPDmem->mem_syn2, hLPDmem->mem_syn, ENC ); - Word16 tmp, A[M + 1], Ap[M + 1], tmp_buf[M + 1]; - /* Update wsyn */ - /* lsp2a_stab( st->lsp_old, A, M ); */ - E_LPC_f_lsp_a_conversion( st->lsp_old_fx, A, M ); - weight_a_fx( A, Ap, GAMMA1, M ); - tmp = 0; - move16(); - tmp_buf[0] = 0; - move16(); - Copy( hLPDmem->mem_syn2, tmp_buf + 1, M ); - deemph_fx( tmp_buf + 1, st->preemph_fac, M, &tmp ); - Residu3_fx( Ap, tmp_buf + M, &tmp, 1, 1 ); -#ifdef BASOP_NOGLOB - hLPDmem->mem_w0 = sub_sat( shr_sat( st->wspeech_enc[-1], shift ), tmp ); - move16(); -#else - hLPDmem->mem_w0 = sub( shr( st->wspeech_enc[-1], shift ), tmp ); -#endif - } - } - ELSE IF( ( NE_16( st->L_frame, L_frame_old ) ) ) - { - /*Partial reset of ACELP memories*/ - st->next_force_safety_net = 1; - move16(); - st->rate_switching_reset = 1; - move16(); - - /*reset partly some memories*/ - IF( hLPDmem != NULL ) - { - hLPDmem->tilt_code = TILT_CODE; - move16(); - set16_fx( hLPDmem->old_exc, 0, L_EXC_MEM ); - move16(); - hLPDmem->q_lpd_old_exc = Q15; - move16(); - /*Resamp others memories*/ - /*Size of LPC syn memory*/ - /* 1.25/20.0 = 1.0/16.0 -> shift 4 to the right. */ - mem_syn_r_size_old = shr( L_frame_old, 4 ); - mem_syn_r_size_new = shr( st->L_frame, 4 ); - - lerp( hLPDmem->mem_syn_r + L_SYN_MEM - mem_syn_r_size_old, hLPDmem->mem_syn_r + L_SYN_MEM - mem_syn_r_size_new, mem_syn_r_size_new, mem_syn_r_size_old ); - Copy( hLPDmem->mem_syn_r + L_SYN_MEM - M, hLPDmem->mem_syn, M ); - Copy( hLPDmem->mem_syn, hLPDmem->mem_syn2, M ); - - /*Untouched memories : hLPDmem->syn & hLPDmem->mem_w0*/ - hLPDmem->mem_w0 = 0; - move16(); - } - /* unquantized LPC*/ - Copy( st->lsp_old1_fx, st->lspold_enc_fx, M ); /*lsp old @12.8kHz*/ - IF( EQ_16( st->L_frame, L_FRAME16k ) ) - { - lsp_convert_poly_fx( st->lspold_enc_fx, st->L_frame, 0 ); - } - Copy( st->lspold_enc_fx, st->lsp_old_fx, M ); /*used unquantized values for mid-LSF Q*/ - IF( st->tcxonly == 0 ) - { - lsp2lsf_fx( st->lsp_old_fx, st->lsf_old_fx, M, st->sr_core ); - } - ELSE - { - E_LPC_lsp_lsf_conversion( st->lsp_old_fx, st->lsf_old_fx, M ); - } - } - ELSE IF( !st->tcxonly && EQ_16( st->L_frame, L_FRAME16k ) && GT_32( st->last_total_brate, ACELP_32k ) ) - { - lsp2lsf_fx( st->lsp_old_fx, st->lsf_old_fx, M, st->sr_core ); - } - } - } - - test(); - test(); - if ( EQ_16( st->last_bwidth, NB ) && NE_16( st->bwidth, NB ) && st->ini_frame != 0 ) - { - st->rate_switching_reset = 1; - move16(); - } - - /* Post-processing */ - /*EVS specific*/ - /* hLPDmem->dm_fx.prev_gain_code = L_deposit_l( 0 ); - set16_fx( hLPDmem->dm_fx.prev_gain_pit, 0, 6 ); - hLPDmem->dm_fx.prev_state = 0;*/ - /*------------*/ - - if ( hLPDmem != NULL ) - { - hLPDmem->dm_fx.prev_state = 0; - move16(); /* This corresponds to st_fx->dispMem in FLP */ - hLPDmem->dm_fx.prev_gain_code = 0; - move32(); - - FOR( Word16 i = 2; i < 8; i++ ) - { - hLPDmem->dm_fx.prev_gain_pit[i - 2] = 0; - move16(); - } - hLPDmem->gc_threshold = 0; - move16(); - } - - /* Pulse Search configuration */ - st->acelp_autocorr = 1; - move16(); - - /*Use for 12.8 kHz sampling rate and low bitrates, the conventional pulse search->better SNR*/ - test(); - test(); - if ( ( LE_32( st->total_brate, ACELP_9k60 ) || EQ_16( st->rf_mode, 1 ) ) && ( EQ_32( st->sr_core, 12800 ) ) ) - { - st->acelp_autocorr = 0; - move16(); - } - - - /*BPF parameters for adjusting gain in function of background noise*/ - IF( EQ_16( st->codec_mode, MODE2 ) ) - { - st->mem_bpf_fx.lp_error_ener = L_deposit_l( 0 ); - move32(); - st->pst_lp_ener_fx = 0; - move16(); - if ( EQ_16( st->last_codec_mode, MODE1 ) ) - { - st->mem_bpf_fx.lp_error = L_deposit_l( 0 ); - move32(); - st->pst_mem_deemp_err_fx = 0; - move16(); - } - } - - return; -} -/*-----------------------------------------------------------------------* - * init_modes() - * - * - *-----------------------------------------------------------------------*/ - -static void init_modes_ivas_fx( - Encoder_State *st, - const Word32 last_total_brate ) -{ - Word8 n; - Word32 tmp32; - TCX_ENC_HANDLE hTcxEnc = st->hTcxEnc; - (void) last_total_brate; - - - /* Restrict ACE/TCX20/TCX10 mode */ - move16(); - st->restrictedMode = getRestrictedMode( st->element_mode, st->total_brate, st->Opt_AMR_WB ); - move16(); - st->acelpEnabled = 0; - move16(); - st->tcx20Enabled = 0; - move16(); - st->tcx10Enabled = 0; - - if ( EQ_16( s_and( st->restrictedMode, 1 ), 1 ) ) - { - st->acelpEnabled = 1; - move16(); - } - if ( EQ_16( s_and( st->restrictedMode, 2 ), 2 ) ) - { - st->tcx20Enabled = 1; - move16(); - } - if ( EQ_16( s_and( st->restrictedMode, 4 ), 4 ) ) - { - st->tcx10Enabled = 1; - move16(); - } - - - /* TCX mode (TCX20 TCX10_10 or NO_TCX) */ - if ( st->hTcxEnc != NULL ) - { - hTcxEnc->tcxMode = NO_TCX; - move16(); - } - - /* Bits Budget */ - /*st->bits_frame_nominal = (int)( (float)st->L_frame * (float)FSCALE_DENOM * (float)st->bitrate / ( (float)st->fscale * 12800.0f ) );*/ - /*st->bits_frame_nominal = (int)( (float)st->L_frame/(float)st->fscale * (float)FSCALE_DENOM/128.0f * (float)st->bitrate/100.0f + 0.49f );*/ - /*328 = 0.010009765625 in 0Q15*/ - /* st->bits_frame_nominal = extract_h(L_add(L_mult(div_l(L_mult(shl(st->L_frame,2),st->bitrate),st->fscale),328),16056)); */ - - /* st->bits_frame_nominal = (int)( (float)st->L_frame/(float)st->fscale * (float)FSCALE_DENOM/128.0f * (float)st->bitrate/100.0f + 0.49f ); */ - tmp32 = L_shl( st->total_brate, 1 ); /* (float)st->L_frame/(float)st->fscale * (float)FSCALE_DENOM/128.0f * (float)st->bitrate */ - st->bits_frame_nominal = extract_l( L_shr( Mpy_32_16_1( tmp32, 20972 ), 6 ) ); /* 20972 = 0.01 * 64 * 32768 */ - move16(); - - IF( st->Opt_AMR_WB ) - { - st->bits_frame = st->bits_frame_nominal; - move16(); - st->bits_frame_core = st->bits_frame_nominal; - move16(); - st->frame_size_index = 0; - move16(); - } - ELSE - { - FOR( n = 0; n < FRAME_SIZE_NB; n++ ) - { - IF( LT_32( n, FRAME_SIZE_NB - 1 ) ) - { - test(); - IF( LE_32( FrameSizeConfig[n].frame_bits, st->bits_frame_nominal ) && GT_32( FrameSizeConfig[n + 1].frame_bits, st->bits_frame_nominal ) ) - { - st->frame_size_index = n; - move16(); - st->bits_frame = st->bits_frame_nominal; - move16(); - st->bits_frame_core = sub( sub( sub( st->bits_frame_nominal, FrameSizeConfig[n].transmission_bits ), FrameSizeConfig[n].bandwidth_bits ), FrameSizeConfig[n].reserved_bits ); - move16(); - BREAK; - } - } - ELSE - { - IF( LE_32( FrameSizeConfig[n].frame_bits, st->bits_frame_nominal ) ) - { - st->frame_size_index = n; - move16(); - st->bits_frame = st->bits_frame_nominal; - move16(); - st->bits_frame_core = sub( sub( sub( st->bits_frame_nominal, FrameSizeConfig[n].transmission_bits ), FrameSizeConfig[n].bandwidth_bits ), FrameSizeConfig[n].reserved_bits ); - move16(); - BREAK; - } - } - } - } - - /* Reconfigure core */ - core_coder_reconfig_ivas_fx( st ); - - - return; -} diff --git a/lib_enc/core_enc_init_fx.c b/lib_enc/core_enc_init_fx.c index d35a443d82a1d25aa937d8e2012a071d0f676c1f..1c60f2ecd1ab475bd2a0ab3732b951edc5e1cc1b 100644 --- a/lib_enc/core_enc_init_fx.c +++ b/lib_enc/core_enc_init_fx.c @@ -3,8 +3,8 @@ ====================================================================================*/ #include -//#include "prot_fx.h" -//#include "basop_mpy.h" +// #include "prot_fx.h" +// #include "basop_mpy.h" #include "options.h" #include "cnst.h" #include "stl.h" @@ -13,7 +13,6 @@ #include "ivas_cnst.h" #include #include "rom_com.h" /* Common constants */ -#include "prot.h" /* Function prototypes */ #include "prot_fx.h" /* Function prototypes */ #include "prot_fx_enc.h" /* Function prototypes */ #include "basop_util.h" /* Function prototypes */ @@ -28,6 +27,11 @@ static void init_core_sig_ana_fx( Encoder_State *st ); static void init_acelp_fx( Encoder_State *st, Word16 L_frame_old, const Word16 shift ); static void init_modes_fx( Encoder_State *st, const Word32 Last_total_brate ); static void init_sig_buffers_fx( Encoder_State *st, const Word16 L_frame_old, const Word16 L_subfr ); +static void init_tcx_ivas_fx( Encoder_State *st, const Word16 L_frame_old, const Word32 total_brate, const Word32 last_total_brate, const Word16 MCT_flag ); +static void init_core_sig_ana_ivas_fx( Encoder_State *st ); +static void init_modes_ivas_fx( Encoder_State *st, const Word32 last_total_brate ); +static void init_sig_buffers_ivas_fx( Encoder_State *st, const Word16 L_frame_old, const Word16 L_subfr, const Word32 last_total_brate ); +static void init_acelp_ivas_fx( Encoder_State *st, Word16 L_frame_old, Word16 shift, const Word32 last_total_brate ); /*-----------------------------------------------------------------------* * init_coder_ace_plus_fx() @@ -63,6 +67,7 @@ void init_coder_ace_plus_fx( /* Core Sampling Rate */ st->sr_core = getCoreSamplerateMode2( st->element_mode, st->total_brate, st->bwidth, st->flag_ACELP16k, st->rf_mode, st->is_ism_format ); st->fscale = sr2fscale( st->sr_core ); + move32(); move16(); /* Narrowband? */ @@ -77,12 +82,13 @@ void init_coder_ace_plus_fx( /* Core Framing */ L_frame_old = st->last_L_frame; move16(); - st->L_frame = extract_l( Mult_32_16( st->sr_core, 0x0290 ) ); + st->L_frame = extract_l( Mult_32_16( st->sr_core, 0x0290 /* 1/FRAMES_PER_SEC in Q15*/ ) ); st->L_frame_past = -1; move16(); + move16(); - hTcxEnc->L_frameTCX = extract_l( Mult_32_16( st->input_Fs, 0x0290 ) ); - + hTcxEnc->L_frameTCX = extract_l( Mult_32_16( st->input_Fs, 0x0290 /* 1/FRAMES_PER_SEC in Q15*/ ) ); + move16(); st->nb_subfr = NB_SUBFR; move16(); L_subfr = shr( st->L_frame, 2 ); @@ -112,7 +118,7 @@ void init_coder_ace_plus_fx( /* Initialize TBE */ hBWE_TD->prev_coder_type = GENERIC; move16(); - set16_fx( hBWE_TD->prev_lsf_diff_fx, 16384, LPC_SHB_ORDER - 2 ); + set16_fx( hBWE_TD->prev_lsf_diff_fx, 16384 /*.5f Q15*/, LPC_SHB_ORDER - 2 ); hBWE_TD->prev_tilt_para_fx = 0; move16(); set16_fx( hBWE_TD->cur_sub_Aq_fx, 0, M + 1 ); @@ -149,8 +155,9 @@ void init_coder_ace_plus_fx( if ( st->hIGFEnc != NULL ) { st->hIGFEnc->infoStopFrequency = -1; + move16(); } - move16(); + IF( st->igf ) { IGFEncSetMode_fx( st->hIGFEnc, st->total_brate, st->bwidth, st->element_mode, st->rf_mode ); @@ -158,9 +165,11 @@ void init_coder_ace_plus_fx( ELSE IF( st->hIGFEnc != NULL ) { st->hIGFEnc->infoTotalBitsWritten = 0; + move16(); if ( EQ_16( MCT_flag, -10 ) ) { st->hIGFEnc->infoTotalBitsPerFrameWritten = 0; + move16(); } /* the line above is needed for some transition, but when going from low rate to high rate, ex 7k2 to 96k, EVS fix point doesn't do the reset (or it does somewhere else */ } @@ -209,7 +218,6 @@ void init_coder_ace_plus_fx( /* Initialize DTX */ IF( st->ini_frame == 0 ) { - vad_init_fx( &st->vad_st ); } @@ -269,8 +277,8 @@ void init_coder_ace_plus_fx( move16(); move16(); move16(); /* casts */ - st->mean_gc[0] = L_deposit_h( 0 ); - st->mean_gc[1] = L_deposit_h( 0 ); + st->mean_gc[0] = 0; + st->mean_gc[1] = 0; st->prev_lsf4_mean = 0; move16(); @@ -314,7 +322,7 @@ static void init_tcx_fx( st->hTcxCfg->lfacNext = sub( st->hTcxCfg->tcx_offset, shr( st->L_frame, 2 ) ); move16(); st->hTcxCfg->lfacNextFB = sub( st->hTcxCfg->tcx_offsetFB, shr( hTcxEnc->L_frameTCX, 2 ) ); - + move16(); IF( st->ini_frame == 0 ) { st->hTcxCfg->tcx_curr_overlap_mode = st->hTcxCfg->tcx_last_overlap_mode = ALDO_WINDOW; @@ -375,7 +383,7 @@ static void init_tcx_fx( /* TCX-LTP */ hTcxEnc->tcxltp = getTcxLtp( st->sr_core ); - + move16(); test(); test(); test(); @@ -392,7 +400,7 @@ static void init_tcx_fx( hTcxEnc->tcxltp_norm_corr_past = 0; move16(); } - ELSE IF( NE_16( st->L_frame, L_frame_old ) && !( ( st->total_brate == 16400 || st->total_brate == 24400 ) && ( st->total_brate == st->last_total_brate ) && ( st->last_bwidth == st->bwidth ) ) ) + ELSE IF( NE_16( st->L_frame, L_frame_old ) && !( ( EQ_32( st->total_brate, 16400 ) || EQ_32( st->total_brate, 24400 ) ) && ( EQ_32( st->total_brate, st->last_total_brate ) ) && ( EQ_32( st->last_bwidth, st->bwidth ) ) ) ) { Word16 pitres, pitres_old; Word16 pit, pit_old; @@ -416,18 +424,13 @@ static void init_tcx_fx( move16(); } -#ifdef BASOP_NOGLOB /*pit = pit_old * (float)st->L_frame/(float)L_frame_old;*/ pit = shl_sat( mult_r( pit_old, div_s( st->L_frame, shl( L_frame_old, 2 ) ) ), 2 ); -/* Note : the saturation here that can happens when FS == 32kHz*/ -#else - pit = shl( mult_r( pit_old, div_s( st->L_frame, shl( L_frame_old, 2 ) ) ), 2 ); -#endif + /* Note : the saturation here that can happens when FS == 32kHz*/ /* assert(pit <= st->L_frame);*/ hTcxEnc->tcxltp_pitch_int_past = pit; move16(); - move16(); hTcxEnc->tcxltp_pitch_fr_past = i_mult2( sub( pit, hTcxEnc->tcxltp_pitch_int_past ), pitres ); move16(); } @@ -444,8 +447,9 @@ static void init_tcx_fx( } st->hTcxCfg->ctx_hm = getCtxHm( st->element_mode, st->total_brate, st->rf_mode ); - + move16(); hTcxEnc->tcx_lpc_shaped_ari = getTcxLpcShapedAri( st->total_brate, st->rf_mode, st->element_mode ); + move16(); } void init_sig_buffers_fx( Encoder_State *st, const Word16 L_frame_old, const Word16 L_subfr ) @@ -485,14 +489,14 @@ void init_sig_buffers_fx( Encoder_State *st, const Word16 L_frame_old, const Wor Copy( st->buf_speech_enc, hTcxEnc->buf_speech_ltp, st->L_frame ); } - Copy_Scale_sig( st->old_wsp_fx, st->buf_wspeech_enc + st->L_frame + L_SUBFR - L_WSP_MEM, L_WSP_MEM, sub( st->prev_Q_new, st->prev_Q_old ) ); + Copy_Scale_sig( st->old_wsp_fx, st->buf_wspeech_enc + st->L_frame + L_SUBFR - L_WSP_MEM, L_WSP_MEM, sub( st->prev_Q_new, st->prev_Q_old ) ); // Q(prev_Q_new) /*Resamp buffers needed only for ACELP*/ test(); test(); IF( EQ_16( st->L_frame, L_FRAME ) && !st->tcxonly ) { - Copy_Scale_sig( st->old_inp_12k8_fx, st->buf_speech_enc_pe + st->L_frame - L_INP_MEM, L_INP_MEM, sub( st->prev_Q_new, st->prev_Q_old ) ); + Copy_Scale_sig( st->old_inp_12k8_fx, st->buf_speech_enc_pe + st->L_frame - L_INP_MEM, L_INP_MEM, sub( st->prev_Q_new, st->prev_Q_old ) ); // Q(prev_Q_new) } ELSE IF( EQ_16( st->L_frame, L_FRAME16k ) && !st->tcxonly ) { @@ -509,7 +513,7 @@ void init_sig_buffers_fx( Encoder_State *st, const Word16 L_frame_old, const Wor ELSE IF( !st->tcxonly && GE_32( st->last_total_brate, ACELP_32k ) ) { - Copy_Scale_sig( st->old_wsp_fx, st->buf_wspeech_enc + st->L_frame + L_SUBFR - L_WSP_MEM, L_WSP_MEM, sub( st->prev_Q_new, st->prev_Q_old ) ); + Copy_Scale_sig( st->old_wsp_fx, st->buf_wspeech_enc + st->L_frame + L_SUBFR - L_WSP_MEM, L_WSP_MEM, sub( st->prev_Q_new, st->prev_Q_old ) ); // Q(prev_Q_new) /*Resamp buffers needed only for ACELP*/ IF( EQ_16( st->L_frame, L_FRAME16k ) ) @@ -526,7 +530,7 @@ void init_sig_buffers_fx( Encoder_State *st, const Word16 L_frame_old, const Wor st->new_speech_enc = st->buf_speech_enc + st->encoderPastSamples_enc + st->encoderLookahead_enc; st->new_speech_enc_pe = st->buf_speech_enc_pe + st->encoderPastSamples_enc + st->encoderLookahead_enc; hTcxEnc->new_speech_ltp = hTcxEnc->buf_speech_ltp + st->encoderPastSamples_enc + st->encoderLookahead_enc; - hTcxEnc->new_speech_TCX = st->input_buff_fx + L_FRAME48k + NS2SA( 48000, DELAY_FIR_RESAMPL_NS ) - NS2SA( st->input_Fs, DELAY_FIR_RESAMPL_NS ); + hTcxEnc->new_speech_TCX = st->input_buff_fx + L_FRAME48k + NS2SA( 48000, DELAY_FIR_RESAMPL_NS ) - NS2SA_FX2( st->input_Fs, DELAY_FIR_RESAMPL_NS ); st->speech_enc = st->buf_speech_enc + st->encoderPastSamples_enc; st->speech_enc_pe = st->buf_speech_enc_pe + st->encoderPastSamples_enc; @@ -608,7 +612,7 @@ static void init_acelp_fx( Encoder_State *st, Word16 L_frame_old, const Word16 s /* Init pitch lag */ st->pit_res_max = initPitchLagParameters( st->sr_core, &st->pit_min, &st->pit_fr1, &st->pit_fr1b, &st->pit_fr2, &st->pit_max ); - + move16(); /* Init LPDmem */ IF( st->ini_frame == 0 ) @@ -671,6 +675,8 @@ static void init_acelp_fx( Encoder_State *st, Word16 L_frame_old, const Word16 s /* unquantized LPC*/ test(); + test(); + test(); IF( !( ( EQ_32( st->total_brate, ACELP_16k40 ) || EQ_32( st->total_brate, ACELP_24k40 ) ) && ( EQ_32( st->total_brate, st->last_total_brate ) ) && ( EQ_16( st->last_bwidth, st->bwidth ) ) ) ) { Copy( st->lsp_old1_fx, st->lspold_enc_fx, M ); /*lsp old @12.8kHz*/ @@ -693,6 +699,8 @@ static void init_acelp_fx( Encoder_State *st, Word16 L_frame_old, const Word16 s st->hTcxCfg->last_aldo = 1; /*It was previously ALDO*/ st->hTcxCfg->tcx_curr_overlap_mode = ALDO_WINDOW; + move16(); + move16(); /*ALDO overlap windowed past: also used in MODE1 but for other MDCT-FB*/ set16_fx( hTcxEnc->old_out_fx, 0, st->L_frame ); } @@ -704,6 +712,7 @@ static void init_acelp_fx( Encoder_State *st, Word16 L_frame_old, const Word16 s { /* convert quantized LSP vector */ st->rate_switching_reset = lsp_convert_poly_fx( st->lsp_old_fx, st->L_frame, 0 ); + move16(); IF( st->tcxonly == 0 ) { lsp2lsf_fx( st->lsp_old_fx, st->lsf_old_fx, M, st->sr_core ); @@ -737,11 +746,8 @@ static void init_acelp_fx( Encoder_State *st, Word16 L_frame_old, const Word16 s Copy( hLPDmem->mem_syn2, tmp_buf + 1, M ); deemph_fx( tmp_buf + 1, st->preemph_fac, M, &tmp ); Residu3_fx( Ap, tmp_buf + M, &tmp, 1, 1 ); -#ifdef BASOP_NOGLOB hLPDmem->mem_w0 = sub_sat( shr_sat( st->wspeech_enc[-1], shift ), tmp ); -#else - hLPDmem->mem_w0 = sub( shr( st->wspeech_enc[-1], shift ), tmp ); -#endif + move16(); } } ELSE IF( ( NE_16( st->L_frame, L_frame_old ) ) ) @@ -804,7 +810,8 @@ static void init_acelp_fx( Encoder_State *st, Word16 L_frame_old, const Word16 s } /* Post-processing */ - hLPDmem->dm_fx.prev_gain_code = L_deposit_l( 0 ); + hLPDmem->dm_fx.prev_gain_code = 0; + move32(); set16_fx( hLPDmem->dm_fx.prev_gain_pit, 0, 6 ); hLPDmem->dm_fx.prev_state = 0; @@ -815,7 +822,8 @@ static void init_acelp_fx( Encoder_State *st, Word16 L_frame_old, const Word16 s /* Pulse Search configuration */ st->acelp_autocorr = 1; move16(); - + test(); + test(); /*Use for 12.8 kHz sampling rate and low bitrates, the conventional pulse search->better SNR*/ if ( ( LE_32( st->total_brate, ACELP_9k60 ) || st->rf_mode != 0 ) && ( EQ_32( st->sr_core, 12800 ) ) ) { @@ -827,10 +835,12 @@ static void init_acelp_fx( Encoder_State *st, Word16 L_frame_old, const Word16 s /*BPF parameters for adjusting gain in function of background noise*/ IF( EQ_16( st->codec_mode, MODE2 ) ) { - st->mem_bpf_fx.lp_error_ener = L_deposit_l( 0 ); - if ( st->last_codec_mode == MODE1 ) + st->mem_bpf_fx.lp_error_ener = 0; + move32(); + if ( EQ_16( st->last_codec_mode, MODE1 ) ) { - st->mem_bpf_fx.lp_error = L_deposit_l( 0 ); + st->mem_bpf_fx.lp_error = 0; + move32(); } } @@ -889,13 +899,15 @@ static void init_modes_fx( assert( st->fscale == 2 * st->L_frame ); /* this assumption is true if operated in 20ms frames with FSCALE_DENOM == 512, which is the current default */ tmp32 = L_shl( st->total_brate, 1 ); /* (float)st->L_frame/(float)st->fscale * (float)FSCALE_DENOM/128.0f * (float)st->bitrate */ st->bits_frame_nominal = extract_l( L_shr( Mpy_32_16_1( tmp32, 20972 ), 6 ) ); /* 20972 = 0.01 * 64 * 32768 */ - + move16(); IF( st->Opt_AMR_WB ) { st->bits_frame = st->bits_frame_nominal; st->bits_frame_core = st->bits_frame_nominal; st->frame_size_index = 0; move16(); + move16(); + move16(); } ELSE { @@ -922,5 +934,1017 @@ static void init_modes_fx( core_coder_reconfig_fx( st, last_total_brate ); + return; +} + +/*-----------------------------------------------------------------------* + * init_coder_ace_plus() + * + * Initialization of state variables + *-----------------------------------------------------------------------*/ +void init_coder_ace_plus_ivas_fx( + Encoder_State *st, /* i : Encoder state */ + const Word32 last_total_brate, /* i : last total bitrate */ +#ifdef FIX_920_IGF_INIT_ERROR + const Word32 igf_brate, /* i : IGF configuration bitrate */ +#endif + const Word16 MCT_flag /* i : hMCT handle allocated (1) or not (0) */ +) +{ + TCX_ENC_HANDLE hTcxEnc = st->hTcxEnc; + Word16 L_frame_old; /*keep old frame size for switching */ + Word16 L_subfr; + + /* Bitrate */ + st->tcxonly = getTcxonly_ivas_fx( st->element_mode, st->total_brate, MCT_flag, st->is_ism_format ); + move16(); + + /* Core Sampling Rate */ + st->sr_core = getCoreSamplerateMode2( st->element_mode, st->total_brate, st->bwidth, st->flag_ACELP16k, st->rf_mode, st->is_ism_format ); + st->fscale = sr2fscale_fx( st->sr_core ); + move32(); + move16(); + + /* Narrowband? */ + IF( EQ_16( st->bwidth, NB ) ) + { + st->narrowBand = 1; + move16(); + } + ELSE + { + st->narrowBand = 0; + move16(); + } + + /* Core Framing */ + L_frame_old = st->last_L_frame; + move16(); + st->L_frame = extract_l( Mult_32_16( st->sr_core, 0x0290 ) ); /* 0x0290 is 1/FRAMES_PER_SEC in Q15*/ + move16(); + st->L_frame_past = -1; + move16(); + + IF( hTcxEnc != NULL ) + { + hTcxEnc->L_frameTCX = extract_l( Mult_32_16( st->input_Fs, 0x0290 ) ); /* 0x0290 is 1/FRAMES_PER_SEC in Q15*/ + move16(); + + IF( st->ini_frame == 0 ) + { + set16_fx( hTcxEnc->Txnq, 0, L_FRAME32k / 2 + 64 ); + hTcxEnc->acelp_zir = hTcxEnc->Txnq + L_FRAME / 2; + hTcxEnc->q_Txnq = Q15; + move16(); + hTcxEnc->tcx_target_bits_fac = ONE_IN_Q14; + move16(); + } + } + + test(); + test(); + test(); + test(); + test(); + IF( ( st->element_mode == EVS_MONO && EQ_32( st->L_frame, L_FRAME16k ) && LE_32( st->total_brate, ACELP_32k ) ) || ( st->element_mode > EVS_MONO && EQ_32( st->L_frame, L_FRAME16k ) && LE_32( st->total_brate, MAX_ACELP_BRATE ) ) ) + { + st->nb_subfr = NB_SUBFR16k; + move16(); + } + ELSE + { + st->nb_subfr = NB_SUBFR; + move16(); + } + L_subfr = idiv1616( st->L_frame, st->nb_subfr ); + + /* Core Lookahead */ + st->encoderLookahead_enc = NS2SA_FX2( st->sr_core, ACELP_LOOK_NS ); + st->encoderLookahead_FB = NS2SA_FX2( st->input_Fs, ACELP_LOOK_NS ); + move16(); + move16(); + + IF( st->ini_frame == 0 ) + { + st->acelpFramesCount = 0; + move16(); + st->prevTempFlatness_fx = 128 /*1.0f Q7*/; + move16(); + } + + /* Initialize TBE */ + IF( st->hBWE_TD != NULL ) + { + st->hBWE_TD->prev_coder_type = GENERIC; + move16(); + set16_fx( st->hBWE_TD->prev_lsf_diff_fx, 16384, LPC_SHB_ORDER - 2 ); + st->hBWE_TD->prev_tilt_para_fx = 0; + move16(); + set16_fx( st->hBWE_TD->cur_sub_Aq_fx, 0, M + 1 ); + } + + st->currEnergyHF_fx = 0; + move32(); + st->currEnergyHF_e_fx = 0; + move16(); + test(); + /* Initialize LPC analysis/quantization */ + IF( LE_32( st->sr_core, INT_FS_16k ) && st->tcxonly == 0 ) + { + st->lpcQuantization = 1; + move16(); + } + ELSE + { + st->lpcQuantization = 0; + move16(); + } + + st->next_force_safety_net = 0; + move16(); + test(); + test(); + IF( ( NE_16( st->last_L_frame, st->L_frame ) ) || ( EQ_16( st->last_core, AMR_WB_CORE ) ) || ( EQ_16( st->last_core, HQ_CORE ) ) ) + { + set16_fx( st->mem_MA_fx, 0, M ); + Copy( GEWB_Ave_fx, st->mem_AR_fx, M ); + } + + /* Initialize IGF */ + if ( st->hIGFEnc != NULL ) + { + st->hIGFEnc->infoStopFrequency = -1; + move16(); + } + + test(); + IF( st->igf && st->hIGFEnc != NULL ) + { +#ifdef FIX_920_IGF_INIT_ERROR + IGFEncSetMode_ivas_fx( st->hIGFEnc, igf_brate, st->bwidth, st->element_mode, st->rf_mode ); +#else + IGFEncSetMode_ivas_fx( st->hIGFEnc, st->total_brate, st->bwidth, st->element_mode, st->rf_mode ); +#endif + } + ELSE IF( st->hIGFEnc != NULL ) + { + st->hIGFEnc->infoTotalBitsWritten = 0; + move16(); + st->hIGFEnc->infoTotalBitsPerFrameWritten = 0; + move16(); + } + + /* Initialize Core Signal Analysis Module */ + init_core_sig_ana_ivas_fx( st ); + + + /* Initialize TCX */ + IF( hTcxEnc != NULL ) + { + init_tcx_ivas_fx( st, L_frame_old, st->total_brate, last_total_brate, MCT_flag ); + } + + /* Initialize Signal Buffers */ + init_sig_buffers_ivas_fx( st, L_frame_old, L_subfr, last_total_brate ); + + /* Initialize ACELP */ + + init_acelp_ivas_fx( st, L_frame_old, 0, last_total_brate ); + + if ( st->ini_frame == 0 ) + { + st->tec_tfa = 0; + move16(); + } + + IF( st->hTECEnc != NULL ) + { + resetTecEnc_Fx( st->hTECEnc, st->tec_tfa ); + } + + test(); + test(); + test(); + IF( EQ_16( st->bwidth, SWB ) && ( EQ_32( st->total_brate, ACELP_16k40 ) || EQ_32( st->total_brate, ACELP_24k40 ) ) && st->element_mode == EVS_MONO ) + { + st->tec_tfa = 1; + move16(); + } + ELSE + { + st->tec_tfa = 0; + move16(); + } + + st->tec_flag = 0; + move16(); + st->tfa_flag = 0; + move16(); + + test(); + test(); + test(); + IF( ( EQ_32( st->total_brate, ACELP_9k60 ) || EQ_32( st->total_brate, ACELP_16k40 ) || EQ_32( st->total_brate, ACELP_24k40 ) ) && st->element_mode == EVS_MONO ) + { + st->glr = 1; + move16(); + } + ELSE + { + st->glr = 0; + move16(); + } + + st->glr_reset = 0; + move16(); + + /* Initialize ACELP/TCX Modes */ + init_modes_ivas_fx( st, last_total_brate ); + + /* Adaptive BPF */ + set32_fx( st->mem_bpf_fx1, 0, 2 * L_FILT16k ); + set32_fx( st->mem_error_bpf_fx, 0, 2 * L_FILT16k ); + + IF( st->ini_frame == 0 ) + { + st->Q_max_enc[0] = 15; + move16(); + st->Q_max_enc[1] = 15; + move16(); + } + + IF( GE_32( st->total_brate, HQ_48k ) ) + { + st->enablePlcWaveadjust = 1; + move16(); + } + ELSE + { + st->enablePlcWaveadjust = 0; + move16(); + } + + IF( st->hPlcExt ) + { + init_PLC_enc_fx( st->hPlcExt, st->sr_core ); + } + + st->glr_idx[0] = 0; + move16(); + st->glr_idx[1] = 0; + move16(); + st->mean_gc[0] = 0; + move16(); + st->mean_gc[1] = 0; + move16(); + st->prev_lsf4_mean = 0; + move16(); + st->last_stab_fac = 0; + move16(); + + return; +} + +/*-----------------------------------------------------------------------* + * init_tcx() + * + * Initialization of TCX + *-----------------------------------------------------------------------*/ + + +static void init_tcx_ivas_fx( + Encoder_State *st, + const Word16 L_frame_old, + const Word32 total_brate, + const Word32 last_total_brate, + const Word16 MCT_flag ) +{ + TCX_ENC_HANDLE hTcxEnc = st->hTcxEnc; + + /* Share the memories for 2xTCX10/4xTCX5 and for TCX20 */ + hTcxEnc->spectrum_fx[0] = hTcxEnc->spectrum_long_fx; + hTcxEnc->spectrum_fx[1] = hTcxEnc->spectrum_long_fx + N_TCX10_MAX; + st->hTcxEnc->spectrum_e[0] = st->hTcxEnc->spectrum_e[1] = 0; + move16(); + move16(); + + init_tcx_cfg_ivas_fx( st->hTcxCfg, total_brate, st->sr_core, st->input_Fs, st->L_frame, st->bwidth, hTcxEnc->L_frameTCX, + st->fscale, st->preemph_fac, st->tcxonly, st->rf_mode, st->igf, + st->hIGFEnc != NULL ? st->hIGFEnc->infoStopFrequency : 0, st->element_mode, st->ini_frame, MCT_flag ); + + /* Init TCX target bits correction factor */ + hTcxEnc->tcx_target_bits_fac = 0x4000; /*1.0f in 1Q14*/ + move16(); + hTcxEnc->measuredBwRatio = 0x4000; /*1.0f in 1Q14*/ + move16(); + hTcxEnc->noiseTiltFactor = 9216; /*0.5625f in 1Q14*/ + move16(); + hTcxEnc->noiseLevelMemory_cnt = 0; + move16(); + + set16_fx( hTcxEnc->ltpGainMemory_fx, 0, N_LTP_GAIN_MEMS ); + set8_fx( hTcxEnc->memQuantZeros, 0, L_FRAME_PLUS ); + + /* TCX-LTP */ + hTcxEnc->tcxltp = getTcxLtp( st->sr_core ); + move16(); + + test(); + test(); + test(); + test(); + IF( st->ini_frame == 0 ) + { + hTcxEnc->tcxltp_pitch_int_past = st->L_frame; + hTcxEnc->tcxltp_pitch_fr_past = 0; + hTcxEnc->tcxltp_gain_past = 0; + hTcxEnc->tcxltp_norm_corr_past = 0; + hTcxEnc->tcxltp_norm_corr_mem = 0; + hTcxEnc->kernel_switch_corr_past = 0; + hTcxEnc->kernel_symmetry_past = 0; /* MDCT_IV & 1 */ + hTcxEnc->enc_ste_pre_corr_past = 0; + hTcxEnc->tfm_mem_fx = 1610612736; /* 0.75 in Q31 */ + hTcxEnc->tcxltp_on_mem = 0; + move16(); + move16(); + move16(); + move16(); + move16(); + move16(); + move16(); + move16(); + move16(); + move16(); + } + ELSE IF( NE_16( st->L_frame, L_frame_old ) && !( ( GE_32( total_brate, ACELP_16k40 ) && LE_32( total_brate, ACELP_24k40 ) ) && + ( EQ_32( total_brate, last_total_brate ) ) && ( EQ_16( st->last_bwidth, st->bwidth ) ) ) ) + { + Word16 pitres, pitres_old; + Word16 pit, pit_old; + + pitres_old = 4; + move16(); + if ( EQ_16( 160, shr( L_frame_old, sub( 7, norm_s( L_frame_old ) ) ) ) ) /*if ( L_frame_old%160==0 )*/ + { + pitres_old = 6; + move16(); + } + + /*pit_old = (float)st->tcxltp_pitch_int_past + (float)st->tcxltp_pitch_fr_past/(float)pitres_old;*/ + pit_old = add( hTcxEnc->tcxltp_pitch_int_past, mult_r( hTcxEnc->tcxltp_pitch_fr_past, div_s( 1, pitres_old ) ) ); + + pitres = 4; + move16(); + if ( EQ_16( 160, shr( st->L_frame, sub( 7, norm_s( st->L_frame ) ) ) ) ) /*if ( st->L_frame%160==0 )*/ + { + pitres = 6; + move16(); + } + + /*pit = pit_old * (float)st->L_frame/(float)L_frame_old;*/ + pit = shl_sat( mult_r( pit_old, div_s( st->L_frame, shl( L_frame_old, 2 ) ) ), 2 ); + /* Note : the saturation here that can happens when FS == 32kHz*/ + /* assert(pit <= st->L_frame);*/ + + hTcxEnc->tcxltp_pitch_int_past = pit; + move16(); + hTcxEnc->tcxltp_pitch_fr_past = i_mult2( sub( pit, hTcxEnc->tcxltp_pitch_int_past ), pitres ); + move16(); + } + + hTcxEnc->tcx_lpc_shaped_ari = getTcxLpcShapedAri( st->total_brate, st->rf_mode, st->element_mode ); + move16(); + + return; +} + +/*-----------------------------------------------------------------------* + * init_sig_buffers() + * + * Initialization of signal buffers + *-----------------------------------------------------------------------*/ +/*copy of evs function since it was static */ +static void init_sig_buffers_ivas_fx( Encoder_State *st, const Word16 L_frame_old, const Word16 L_subfr, const Word32 last_total_brate ) +{ + + LPD_state_HANDLE hLPDmem = st->hLPDmem; + TCX_ENC_HANDLE hTcxEnc = st->hTcxEnc; + + /* Encoder Past Samples at encoder-sampling-rate */ + st->encoderPastSamples_enc = shr( imult1616( st->L_frame, 9 ), 4 ); + move16(); + + /* Initialize Signal Buffers and Pointers at encoder-sampling-rate */ + IF( st->ini_frame == 0 ) + { + set16_fx( st->buf_speech_enc, 0, L_PAST_MAX_32k + L_FRAME32k + L_NEXT_MAX_32k ); + st->exp_buf_speech_enc = 0; + move16(); + set16_fx( st->buf_speech_enc_pe, 0, L_PAST_MAX_32k + L_FRAME32k + L_NEXT_MAX_32k ); + st->exp_buf_speech_enc_pe = 0; + move16(); + if ( hTcxEnc != NULL ) + { + set16_fx( hTcxEnc->buf_speech_ltp, 0, L_PAST_MAX_32k + L_FRAME32k + L_NEXT_MAX_32k ); + hTcxEnc->exp_buf_speech_ltp = 0; + move16(); + } + set16_fx( st->buf_wspeech_enc, 0, L_FRAME16k + L_SUBFR + L_FRAME16k + L_NEXT_MAX_16k + 320 ); /* increased by 320 to avoid memory overlap in ivas_find_wsp_fx() and also to accomodate for the wspeech_enc */ + st->exp_buf_wspeech_enc = 0; + move16(); + } + ELSE + { + test(); + test(); + test(); + test(); + test(); + IF( NE_16( st->L_frame, L_frame_old ) && !( ( EQ_32( st->total_brate, ACELP_16k40 ) || EQ_32( st->total_brate, ACELP_24k40 ) ) && ( EQ_32( st->total_brate, last_total_brate ) ) && ( EQ_16( st->last_bwidth, st->bwidth ) ) ) ) + { + lerp( st->buf_speech_enc, st->buf_speech_enc, st->L_frame, L_frame_old ); + test(); + IF( NE_16( st->last_core, TCX_20_CORE ) && NE_16( st->last_core, TCX_10_CORE ) ) /* condition should be checked again */ + { + Copy( st->buf_speech_enc, hTcxEnc->buf_speech_ltp, st->L_frame ); + Scale_sig( hTcxEnc->buf_speech_ltp, st->L_frame, sub( st->exp_buf_speech_enc, s_max( st->exp_buf_speech_enc, hTcxEnc->exp_buf_speech_ltp ) ) ); // Q(15-max(st->exp_buf_speech_enc, hTcxEnc->exp_buf_speech_ltp)) + Scale_sig( hTcxEnc->buf_speech_ltp + st->L_frame, sub( L_PAST_MAX_32k + L_FRAME32k + L_NEXT_MAX_32k, st->L_frame ), sub( hTcxEnc->exp_buf_speech_ltp, s_max( st->exp_buf_speech_enc, hTcxEnc->exp_buf_speech_ltp ) ) ); // Q(15-max(st->exp_buf_speech_enc, hTcxEnc->exp_buf_speech_ltp)) + hTcxEnc->exp_buf_speech_ltp = s_max( hTcxEnc->exp_buf_speech_ltp, st->exp_buf_speech_enc ); + move16(); + } + + // Copy_Scale_sig( st->old_wsp_fx, st->buf_wspeech_enc + st->L_frame + L_SUBFR - L_WSP_MEM, L_WSP_MEM, sub( st->prev_Q_new, st->prev_Q_old ) ); + Scale_sig( st->buf_wspeech_enc, L_FRAME16k + L_SUBFR + L_FRAME16k + L_NEXT_MAX_16k + 320, sub( 0, sub( st->exp_old_wsp, st->exp_buf_wspeech_enc ) ) ); + Copy( st->old_wsp_fx, st->buf_wspeech_enc + st->L_frame + L_SUBFR - L_WSP_MEM, L_WSP_MEM ); + st->exp_buf_wspeech_enc = st->exp_old_wsp; + move16(); + + /*Resamp buffers needed only for ACELP*/ + test(); + test(); + IF( EQ_16( st->L_frame, L_FRAME ) && !st->tcxonly ) + { + if ( st->exp_buf_speech_enc_pe >= st->exp_old_inp_12k8 ) + { + Copy_Scale_sig( st->old_inp_12k8_fx, st->buf_speech_enc_pe + st->L_frame - L_INP_MEM, L_INP_MEM, sub( st->exp_old_inp_12k8, st->exp_buf_speech_enc_pe ) ); // Scaling to common Q + // st->buf_speech_enc_pe is in st->exp_buf_speech_enc_pe + } + else + { + Scale_sig( st->buf_speech_enc_pe, L_PAST_MAX_32k + L_FRAME32k + L_NEXT_MAX_32k, sub( st->exp_buf_speech_enc_pe, st->exp_old_inp_12k8 ) ); // Scaling to common Q + Copy( st->old_inp_12k8_fx, st->buf_speech_enc_pe + st->L_frame - L_INP_MEM, L_INP_MEM ); + st->exp_buf_speech_enc_pe = st->exp_old_inp_12k8; + // st->buf_speech_enc_pe is in st->exp_buf_speech_enc_pe + move16(); + } + } + ELSE IF( EQ_16( st->L_frame, L_FRAME16k ) && !st->tcxonly ) + { + lerp( st->buf_wspeech_enc + st->L_frame + L_SUBFR - L_WSP_MEM, st->buf_wspeech_enc + st->L_frame + L_SUBFR - 310, 310, L_WSP_MEM ); + if ( st->exp_buf_speech_enc_pe >= st->exp_old_inp_16k ) + { + Copy_Scale_sig( st->old_inp_16k_fx, st->buf_speech_enc_pe + st->L_frame - L_INP_MEM, L_INP_MEM, sub( st->exp_old_inp_16k, st->exp_buf_speech_enc_pe ) ); // Scaling to common Q + // st->buf_speech_enc_pe is in st->exp_buf_speech_enc_pe + } + else + { + Scale_sig( st->buf_speech_enc_pe, L_PAST_MAX_32k + L_FRAME32k + L_NEXT_MAX_32k, sub( st->exp_buf_speech_enc_pe, st->exp_old_inp_16k ) ); // Scaling to common Q + Copy( st->old_inp_16k_fx, st->buf_speech_enc_pe + st->L_frame - L_INP_MEM, L_INP_MEM ); + st->exp_buf_speech_enc_pe = st->exp_old_inp_16k; + // st->buf_speech_enc_pe is in st->exp_buf_speech_enc_pe + move16(); + } + } + + st->mem_preemph_enc = st->buf_speech_enc[st->encoderPastSamples_enc + st->encoderLookahead_enc - 1]; + move16(); + st->exp_mem_preemph_enc = st->exp_buf_speech_enc; + move16(); + st->mem_wsp_enc = shr( st->buf_wspeech_enc[st->L_frame + L_SUBFR - 1], sub( Q16, st->exp_buf_wspeech_enc ) ); // Q-1 + move16(); + } + /*coming from TCXonly modes*/ + ELSE IF( !st->tcxonly && GE_32( last_total_brate, ACELP_32k ) ) + { + + Scale_sig( st->buf_wspeech_enc, L_FRAME16k + L_SUBFR + L_FRAME16k + L_NEXT_MAX_16k + 320, sub( 0, sub( st->exp_old_wsp, st->exp_buf_wspeech_enc ) ) ); + Copy( st->old_wsp_fx, st->buf_wspeech_enc + st->L_frame + L_SUBFR - L_WSP_MEM, L_WSP_MEM ); + // Copy_Scale_sig( st->old_wsp_fx, st->buf_wspeech_enc + st->L_frame + L_SUBFR - L_WSP_MEM, L_WSP_MEM, sub( st->prev_Q_new, st->prev_Q_old ) ); + st->exp_buf_wspeech_enc = st->exp_old_wsp; + move16(); /*Resamp buffers needed only for ACELP*/ + IF( EQ_16( st->L_frame, L_FRAME16k ) ) + { + lerp( st->buf_wspeech_enc + st->L_frame + L_SUBFR - L_WSP_MEM, st->buf_wspeech_enc + st->L_frame + L_SUBFR - 310, 310, L_WSP_MEM ); + } + hLPDmem->mem_w0 = 0; + move16(); + st->mem_wsp_enc = shr( st->buf_wspeech_enc[st->L_frame + L_SUBFR - 1], sub( Q16, st->exp_buf_wspeech_enc ) ); // Q-1 + move16(); + } + } + + st->new_speech_enc = st->buf_speech_enc + st->encoderPastSamples_enc + st->encoderLookahead_enc; + st->new_speech_enc_pe = st->buf_speech_enc_pe + st->encoderPastSamples_enc + st->encoderLookahead_enc; + if ( hTcxEnc != NULL ) + { + hTcxEnc->new_speech_ltp = hTcxEnc->buf_speech_ltp + st->encoderPastSamples_enc + st->encoderLookahead_enc; + } + + IF( st->hTcxEnc != NULL ) + { + st->hTcxEnc->new_speech_TCX = st->input_buff_fx + Mpy_32_32( st->input_Fs, ONE_BY_FRAMES_PER_SEC_Q31 ); + st->hTcxEnc->speech_TCX = st->hTcxEnc->new_speech_TCX - st->encoderLookahead_FB; + } + st->speech_enc = st->buf_speech_enc + st->encoderPastSamples_enc; + st->speech_enc_pe = st->buf_speech_enc_pe + st->encoderPastSamples_enc; + + if ( hTcxEnc != NULL ) + { + hTcxEnc->speech_ltp = hTcxEnc->buf_speech_ltp + st->encoderPastSamples_enc; + } + + IF( st->element_mode > EVS_MONO ) + { + st->wspeech_enc = st->buf_wspeech_enc + st->L_frame + L_SUBFR; + } + ELSE + { + st->wspeech_enc = st->buf_wspeech_enc + st->L_frame + L_subfr; + } + + test(); + test(); + IF( st->ini_frame == 0 || NE_16( st->L_frame, L_frame_old ) || EQ_16( st->last_codec_mode, MODE1 ) ) + { + set16_fx( st->buf_synth, 0, OLD_SYNTH_SIZE_ENC + L_FRAME32k ); + } + + st->synth = st->buf_synth + st->L_frame + L_subfr; + + + return; +} + +/*-----------------------------------------------------------------------* + * init_core_sig_ana() + * + * + *-----------------------------------------------------------------------*/ +static void init_core_sig_ana_ivas_fx( Encoder_State *st ) +{ + + /* Pre-emphasis factor and memory */ + + st->preemph_fac = PREEMPH_FAC_SWB; /*SWB*/ + move16(); + IF( LT_16( st->fscale, ( 16000 * FSCALE_DENOM ) / 12800 ) ) + { + st->preemph_fac = PREEMPH_FAC; /*WB*/ + move16(); + } + ELSE IF( LT_16( st->fscale, ( 24000 * FSCALE_DENOM ) / 12800 ) ) + { + st->preemph_fac = PREEMPH_FAC_16k; /*WB*/ + move16(); + } + + st->gamma = GAMMA1; + move16(); + st->inv_gamma = GAMMA1_INV; + move16(); + IF( EQ_32( st->sr_core, 16000 ) ) + { + st->gamma = GAMMA16k; + move16(); + st->inv_gamma = GAMMA16k_INV; + move16(); + } + + + st->min_band = 1; + move16(); + st->max_band = 16; + move16(); + + IF( st->narrowBand == 0 ) + { + st->min_band = 0; + move16(); + st->max_band = 19; + move16(); + } + + + return; +} +/*-----------------------------------------------------------------------* + * init_acelp() + * + * + *-----------------------------------------------------------------------*/ +static void init_acelp_ivas_fx( Encoder_State *st, Word16 L_frame_old, Word16 shift, const Word32 last_total_brate ) +{ + Word16 mem_syn_r_size_old; + Word16 mem_syn_r_size_new; + LPD_state_HANDLE hLPDmem = st->hLPDmem; + TCX_ENC_HANDLE hTcxEnc = st->hTcxEnc; + + /* Init pitch lag */ + IF( EQ_16( st->element_mode, IVAS_CPE_MDCT ) ) + { + /* TCX LTP ana always runs @12.8kHz */ + st->pit_res_max = initPitchLagParameters( 12800, &st->pit_min, &st->pit_fr1, &st->pit_fr1b, &st->pit_fr2, &st->pit_max ); + move16(); + } + ELSE + { + st->pit_res_max = initPitchLagParameters( st->sr_core, &st->pit_min, &st->pit_fr1, &st->pit_fr1b, &st->pit_fr2, &st->pit_max ); + move16(); + } + + /* Init LPDmem */ + IF( st->ini_frame == 0 ) + { + IF( hLPDmem != NULL ) + { + set16_fx( hLPDmem->syn, 0, 1 + M ); + set16_fx( hLPDmem->mem_syn_r, 0, L_SYN_MEM ); + } + + IF( st->hTcxEnc != NULL ) + { + set16_fx( st->hTcxEnc->Txnq, 0, L_FRAME32k / 2 + 64 ); + st->hTcxEnc->q_Txnq = Q15; + move16(); + st->hTcxEnc->acelp_zir = st->hTcxEnc->Txnq + shr( st->L_frame, 1 ); + } + } + ELSE /*Rate switching*/ + { + IF( st->last_core == ACELP_CORE ) + { + lerp( hTcxEnc->Txnq, hTcxEnc->Txnq, shr( st->L_frame, 1 ), shr( L_frame_old, 1 ) ); + } + ELSE + { + lerp( hTcxEnc->Txnq, hTcxEnc->Txnq, st->hTcxCfg->tcx_mdct_window_length, st->hTcxCfg->tcx_mdct_window_length_old ); + } + hTcxEnc->acelp_zir = hTcxEnc->Txnq + shr( st->L_frame, 1 ); + + /* Rate switching */ + IF( EQ_16( st->last_codec_mode, MODE1 ) && st->element_mode == EVS_MONO ) + { + IF( hLPDmem != NULL ) + { + Copy( hLPDmem->mem_syn1_fx, hLPDmem->mem_syn2, M ); + set16_fx( hLPDmem->syn, 0, M ); + hLPDmem->q_lpd_syn = Q15; + move16(); + } + IF( st->hTcxEnc != NULL ) + { + set16_fx( hTcxEnc->Txnq, 0, L_FRAME32k / 2 + 64 ); + st->hTcxEnc->q_Txnq = Q15; + move16(); + } + } + + /*AMR-WBIO->MODE2*/ + IF( EQ_16( st->last_core, AMR_WB_CORE ) ) + { + st->next_force_safety_net = 1; + move16(); + st->last_core = ACELP_CORE; + move16(); + } + /*HQ-CORE->MODE2*/ + test(); + IF( EQ_16( st->last_codec_mode, MODE1 ) && EQ_16( st->last_core, HQ_CORE ) ) + { + /*Reset of ACELP memories*/ + st->next_force_safety_net = 1; + move16(); + st->rate_switching_reset = 1; + move16(); + IF( hLPDmem != NULL ) + { + hLPDmem->tilt_code = TILT_CODE; + move16(); + set16_fx( hLPDmem->old_exc, 0, L_EXC_MEM ); + set16_fx( hLPDmem->syn, 0, 1 + M ); + hLPDmem->q_lpd_syn = Q15; + move16(); + hLPDmem->q_lpd_old_exc = Q15; + move16(); + hLPDmem->mem_w0 = 0; + move16(); + set16_fx( hLPDmem->mem_syn, 0, M ); + set16_fx( hLPDmem->mem_syn2, 0, M ); + hLPDmem->q_mem_syn = Q15; + move16(); + } + + /* unquantized LPC*/ + test(); + test(); + test(); + IF( !( ( GE_32( st->total_brate, ACELP_16k40 ) && LE_32( st->total_brate, ACELP_24k40 ) ) && ( EQ_32( st->total_brate, last_total_brate ) ) && ( EQ_16( st->last_bwidth, st->bwidth ) ) ) ) + { + Copy( st->lsp_old1_fx, st->lspold_enc_fx, M ); /*lsp old @12.8kHz*/ + IF( EQ_16( st->L_frame, L_FRAME16k ) ) + { + lsp_convert_poly_fx( st->lspold_enc_fx, st->L_frame, 0 ); + } + } + Copy( st->lspold_enc_fx, st->lsp_old_fx, M ); /*used unquantized values for mid-LSF Q*/ + IF( st->tcxonly == 0 ) + { + lsp2lsf_fx( st->lsp_old_fx, st->lsf_old_fx, M, st->sr_core ); + } + ELSE + { + E_LPC_lsp_lsf_conversion( st->lsp_old_fx, st->lsf_old_fx, M ); + } + st->last_core = TCX_20_CORE; + move16(); + + st->hTcxCfg->last_aldo = 1; /*It was previously ALDO*/ + st->hTcxCfg->tcx_curr_overlap_mode = ALDO_WINDOW; + move16(); + move16(); + /*ALDO overlap windowed past: also used in MODE1 but for other MDCT-FB*/ + set16_fx( hTcxEnc->old_out_fx, 0, st->L_frame ); + } + ELSE + { + test(); + test(); + test(); + test(); + IF( ( NE_16( st->L_frame, L_frame_old ) ) && ( LE_16( st->L_frame, L_FRAME16k ) ) && ( LE_16( L_frame_old, L_FRAME16k ) ) ) + { + /* convert quantized LSP vector */ + st->rate_switching_reset = lsp_convert_poly_fx( st->lsp_old_fx, st->L_frame, 0 ); + move16(); + IF( st->tcxonly == 0 ) + { + lsp2lsf_fx( st->lsp_old_fx, st->lsf_old_fx, M, st->sr_core ); + } + ELSE + { + E_LPC_lsp_lsf_conversion( st->lsp_old_fx, st->lsf_old_fx, M ); + } + IF( EQ_16( st->L_frame, L_FRAME16k ) ) + { + Copy( st->lsp_old_fx, st->lspold_enc_fx, M ); + } + ELSE + { + Copy( st->lsp_old1_fx, st->lspold_enc_fx, M ); + } + + + /*Mem of deemphasis stay unchanged : hLPDmem->syn*/ + IF( hLPDmem != NULL ) + { + synth_mem_updt2( st->L_frame, st->last_L_frame, hLPDmem->old_exc, hLPDmem->mem_syn_r, hLPDmem->mem_syn2, hLPDmem->mem_syn, ENC ); + Word16 tmp, A[M + 1], Ap[M + 1], tmp_buf[M + 1]; + /* Update wsyn */ + /* lsp2a_stab( st->lsp_old, A, M ); */ + E_LPC_f_lsp_a_conversion( st->lsp_old_fx, A, M ); + weight_a_fx( A, Ap, GAMMA1, M ); + tmp = 0; + move16(); + tmp_buf[0] = 0; + move16(); + Copy( hLPDmem->mem_syn2, tmp_buf + 1, M ); + deemph_fx( tmp_buf + 1, st->preemph_fac, M, &tmp ); + Residu3_fx( Ap, tmp_buf + M, &tmp, 1, 1 ); + hLPDmem->mem_w0 = sub_sat( shr_sat( st->wspeech_enc[-1], shift ), tmp ); + move16(); + } + } + ELSE IF( ( NE_16( st->L_frame, L_frame_old ) ) ) + { + /*Partial reset of ACELP memories*/ + st->next_force_safety_net = 1; + move16(); + st->rate_switching_reset = 1; + move16(); + + /*reset partly some memories*/ + IF( hLPDmem != NULL ) + { + hLPDmem->tilt_code = TILT_CODE; + move16(); + set16_fx( hLPDmem->old_exc, 0, L_EXC_MEM ); + move16(); + hLPDmem->q_lpd_old_exc = Q15; + move16(); + /*Resamp others memories*/ + /*Size of LPC syn memory*/ + /* 1.25/20.0 = 1.0/16.0 -> shift 4 to the right. */ + mem_syn_r_size_old = shr( L_frame_old, 4 ); + mem_syn_r_size_new = shr( st->L_frame, 4 ); + + lerp( hLPDmem->mem_syn_r + L_SYN_MEM - mem_syn_r_size_old, hLPDmem->mem_syn_r + L_SYN_MEM - mem_syn_r_size_new, mem_syn_r_size_new, mem_syn_r_size_old ); + Copy( hLPDmem->mem_syn_r + L_SYN_MEM - M, hLPDmem->mem_syn, M ); + Copy( hLPDmem->mem_syn, hLPDmem->mem_syn2, M ); + + /*Untouched memories : hLPDmem->syn & hLPDmem->mem_w0*/ + hLPDmem->mem_w0 = 0; + move16(); + } + /* unquantized LPC*/ + Copy( st->lsp_old1_fx, st->lspold_enc_fx, M ); /*lsp old @12.8kHz*/ + IF( EQ_16( st->L_frame, L_FRAME16k ) ) + { + lsp_convert_poly_fx( st->lspold_enc_fx, st->L_frame, 0 ); + } + Copy( st->lspold_enc_fx, st->lsp_old_fx, M ); /*used unquantized values for mid-LSF Q*/ + IF( st->tcxonly == 0 ) + { + lsp2lsf_fx( st->lsp_old_fx, st->lsf_old_fx, M, st->sr_core ); + } + ELSE + { + E_LPC_lsp_lsf_conversion( st->lsp_old_fx, st->lsf_old_fx, M ); + } + } + ELSE IF( !st->tcxonly && EQ_16( st->L_frame, L_FRAME16k ) && GT_32( st->last_total_brate, ACELP_32k ) ) + { + lsp2lsf_fx( st->lsp_old_fx, st->lsf_old_fx, M, st->sr_core ); + } + } + } + + test(); + test(); + if ( EQ_16( st->last_bwidth, NB ) && NE_16( st->bwidth, NB ) && st->ini_frame != 0 ) + { + st->rate_switching_reset = 1; + move16(); + } + + /* Post-processing */ + /*EVS specific*/ + /* hLPDmem->dm_fx.prev_gain_code = L_deposit_l( 0 ); + set16_fx( hLPDmem->dm_fx.prev_gain_pit, 0, 6 ); + hLPDmem->dm_fx.prev_state = 0;*/ + /*------------*/ + + if ( hLPDmem != NULL ) + { + hLPDmem->dm_fx.prev_state = 0; + move16(); /* This corresponds to st_fx->dispMem in FLP */ + hLPDmem->dm_fx.prev_gain_code = 0; + move32(); + + FOR( Word16 i = 2; i < 8; i++ ) + { + hLPDmem->dm_fx.prev_gain_pit[i - 2] = 0; + move16(); + } + hLPDmem->gc_threshold = 0; + move16(); + } + + /* Pulse Search configuration */ + st->acelp_autocorr = 1; + move16(); + + /*Use for 12.8 kHz sampling rate and low bitrates, the conventional pulse search->better SNR*/ + test(); + test(); + if ( ( LE_32( st->total_brate, ACELP_9k60 ) || EQ_16( st->rf_mode, 1 ) ) && ( EQ_32( st->sr_core, 12800 ) ) ) + { + st->acelp_autocorr = 0; + move16(); + } + + + /*BPF parameters for adjusting gain in function of background noise*/ + IF( EQ_16( st->codec_mode, MODE2 ) ) + { + st->mem_bpf_fx.lp_error_ener = L_deposit_l( 0 ); + move32(); + st->pst_lp_ener_fx = 0; + move16(); + IF( EQ_16( st->last_codec_mode, MODE1 ) ) + { + st->mem_bpf_fx.lp_error = 0; + move32(); + st->pst_mem_deemp_err_fx = 0; + move16(); + } + } + + return; +} +/*-----------------------------------------------------------------------* + * init_modes() + * + * + *-----------------------------------------------------------------------*/ + +static void init_modes_ivas_fx( + Encoder_State *st, + const Word32 last_total_brate ) +{ + Word8 n; + Word32 tmp32; + TCX_ENC_HANDLE hTcxEnc = st->hTcxEnc; + + /* Restrict ACE/TCX20/TCX10 mode */ + move16(); + st->restrictedMode = getRestrictedMode( st->element_mode, st->total_brate, st->Opt_AMR_WB ); + move16(); + st->acelpEnabled = 0; + move16(); + st->tcx20Enabled = 0; + move16(); + st->tcx10Enabled = 0; + + if ( EQ_16( s_and( st->restrictedMode, 1 ), 1 ) ) + { + st->acelpEnabled = 1; + move16(); + } + if ( EQ_16( s_and( st->restrictedMode, 2 ), 2 ) ) + { + st->tcx20Enabled = 1; + move16(); + } + if ( EQ_16( s_and( st->restrictedMode, 4 ), 4 ) ) + { + st->tcx10Enabled = 1; + move16(); + } + + /* TCX mode (TCX20 TCX10_10 or NO_TCX) */ + if ( st->hTcxEnc != NULL ) + { + hTcxEnc->tcxMode = NO_TCX; + move16(); + } + + /* Bits Budget */ + /*st->bits_frame_nominal = (int)( (float)st->L_frame * (float)FSCALE_DENOM * (float)st->bitrate / ( (float)st->fscale * 12800.0f ) );*/ + /*st->bits_frame_nominal = (int)( (float)st->L_frame/(float)st->fscale * (float)FSCALE_DENOM/128.0f * (float)st->bitrate/100.0f + 0.49f );*/ + /*328 = 0.010009765625 in 0Q15*/ + /* st->bits_frame_nominal = extract_h(L_add(L_mult(div_l(L_mult(shl(st->L_frame,2),st->bitrate),st->fscale),328),16056)); */ + + /* st->bits_frame_nominal = (int)( (float)st->L_frame/(float)st->fscale * (float)FSCALE_DENOM/128.0f * (float)st->bitrate/100.0f + 0.49f ); */ + tmp32 = L_shl( st->total_brate, 1 ); /* (float)st->L_frame/(float)st->fscale * (float)FSCALE_DENOM/128.0f * (float)st->bitrate */ + st->bits_frame_nominal = extract_l( L_shr( Mpy_32_16_1( tmp32, 20972 ), 6 ) ); /* 20972 = 0.01 * 64 * 32768 */ + move16(); + + IF( st->Opt_AMR_WB ) + { + st->bits_frame = st->bits_frame_nominal; + move16(); + st->bits_frame_core = st->bits_frame_nominal; + move16(); + st->frame_size_index = 0; + move16(); + } + ELSE + { + FOR( n = 0; n < FRAME_SIZE_NB; n++ ) + { + IF( LT_32( n, FRAME_SIZE_NB - 1 ) ) + { + test(); + IF( LE_32( FrameSizeConfig[n].frame_bits, st->bits_frame_nominal ) && GT_32( FrameSizeConfig[n + 1].frame_bits, st->bits_frame_nominal ) ) + { + st->frame_size_index = n; + move16(); + st->bits_frame = st->bits_frame_nominal; + move16(); + st->bits_frame_core = sub( sub( sub( st->bits_frame_nominal, FrameSizeConfig[n].transmission_bits ), FrameSizeConfig[n].bandwidth_bits ), FrameSizeConfig[n].reserved_bits ); + move16(); + BREAK; + } + } + ELSE + { + IF( LE_32( FrameSizeConfig[n].frame_bits, st->bits_frame_nominal ) ) + { + st->frame_size_index = n; + move16(); + st->bits_frame = st->bits_frame_nominal; + move16(); + st->bits_frame_core = sub( sub( sub( st->bits_frame_nominal, FrameSizeConfig[n].transmission_bits ), FrameSizeConfig[n].bandwidth_bits ), FrameSizeConfig[n].reserved_bits ); + move16(); + BREAK; + } + } + } + } + + /* Reconfigure core */ + core_coder_reconfig_ivas_fx( st, last_total_brate ); + + return; } diff --git a/lib_enc/core_enc_ol.c b/lib_enc/core_enc_ol.c deleted file mode 100644 index d86e50ff19101cd541acce3b29d693c0dddde5b4..0000000000000000000000000000000000000000 --- a/lib_enc/core_enc_ol.c +++ /dev/null @@ -1,46 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include -#include "options.h" -#include -#include "prot.h" -#include "rom_com.h" -#include "basop_proto_func.h" -#include "wmc_auto.h" -#include "prot_fx.h" -#include "prot_fx_enc.h" diff --git a/lib_enc/core_enc_ol_fx.c b/lib_enc/core_enc_ol_fx.c index 89bd8b524b280bc48093e3f6c748206effec488b..04857c334d7130aa8b298baaa0bdb78f8cd5e82e 100644 --- a/lib_enc/core_enc_ol_fx.c +++ b/lib_enc/core_enc_ol_fx.c @@ -33,12 +33,12 @@ static void BITS_ALLOC_TCX_config_rf( Word16 *rf_frame_type, Word16 *rf_target_b void core_encode_openloop_fx( Encoder_State *st, /* i/o: encoder state structure */ const Word16 coder_type, /* i : coding type */ - const Word16 Aw[NB_SUBFR16k * ( M + 1 )], /* i : weighted A(z) unquant. for subframes*/ - const Word16 *lsp_new, /* i : LSPs at the end of the frame */ - const Word16 *lsp_mid, /* i : LSPs at the middle of the frame */ - Word16 *pitch_buf, /* i/o: floating pitch values for each subfr*/ - Word16 *voice_factors, /* o : voicing factors */ - Word16 *ptr_bwe_exc, /* o : excitation for SWB TBE */ + const Word16 Aw[NB_SUBFR16k * ( M + 1 )], /* i : weighted A(z) unquant. for subframes */ + const Word16 *lsp_new, /* i : LSPs at the end of the frame Q15*/ + const Word16 *lsp_mid, /* i : LSPs at the middle of the frame Q15*/ + Word16 *pitch_buf, /* i/o: floating pitch values for each subfr Q6*/ + Word16 *voice_factors, /* o : voicing factors Q15*/ + Word16 *ptr_bwe_exc, /* o : excitation for SWB TBE Qexc*/ const Word16 vad_hover_flag, const Word16 vad_flag_dtx, Word16 Q_new, @@ -86,6 +86,7 @@ void core_encode_openloop_fx( #endif #ifdef BASOP_NOGLOB_DECLARE_LOCAL Flag Overflow = 0; + move32(); #endif TCX_ENC_HANDLE hTcxEnc = st->hTcxEnc; RF_ENC_HANDLE hRF = st->hRF; @@ -123,23 +124,26 @@ void core_encode_openloop_fx( /* back up LPD mem_w0 target generation memory */ hRF->rf_mem_w0 = hLPDmem->mem_w0; - + move16(); /* back up clip gain memory */ Copy( st->clip_var_fx, hRF->rf_clip_var, 6 ); /* back up tilt code */ hRF->rf_tilt_code = hLPDmem->tilt_code; - + move16(); /* back up dispMem */ hRF->rf_dm_fx.prev_state = hLPDmem->dm_fx.prev_state; + move16(); hRF->rf_dm_fx.prev_gain_code = hLPDmem->dm_fx.prev_gain_code; + move32(); FOR( i = 0; i < 6; i++ ) { hRF->rf_dm_fx.prev_gain_pit[i] = hLPDmem->dm_fx.prev_gain_pit[i]; + move16(); } /* back up gc_threshold for noise addition */ hRF->rf_gc_threshold = hLPDmem->gc_threshold; - + move32(); /* initialization */ tcx_lpc_cdk = 0; @@ -233,7 +237,7 @@ void core_encode_openloop_fx( /* calculate target bits for core coding */ target_bits = sub( target_bits, st->rf_target_bits_write ); } - IF( st->igf != 0 ) + if ( st->igf != 0 ) { target_bits = sub( target_bits, get_tbe_bits_fx( st->total_brate, st->bwidth, st->rf_mode ) ); } @@ -249,7 +253,7 @@ void core_encode_openloop_fx( } /* reset TBE buffers previous frame frame wasn't ACELP*/ - IF( NE_16( st->last_core, ACELP_CORE ) ) + IF( st->last_core != ACELP_CORE ) { TBEreset_enc_fx( st, st->bwidth ); } @@ -261,6 +265,7 @@ void core_encode_openloop_fx( IF( st->hPlcExt ) { st->glr_idx[0] = encSideSpecPowDiffuseDetector_fx( st->hPlcExt->last_lsf_ref, st->hPlcExt->last_lsf_con, st->last_sr_core, &( st->prev_lsf4_mean ), (Word8) st->glr, coder_type ); + move16(); Copy( lsf_q, st->hPlcExt->last_lsf_ref, M ); Copy( st->hPlcExt->lsf_con, st->hPlcExt->last_lsf_con, M ); @@ -272,12 +277,11 @@ void core_encode_openloop_fx( st->glr_idx[0] = 0; } move16(); - move16(); st->hPlcExt->LPDmem = hLPDmem; encoderSideLossSimulation_fx( st, st->hPlcExt, lsf_q, stab_fac, st->hPlcExt->calcOnlylsf, st->L_frame ); } st->last_stab_fac = stab_fac; - + move16(); hTcxEnc->tcxltp_norm_corr_past = st->voicing_fx[1]; move16(); @@ -355,7 +359,7 @@ void core_encode_openloop_fx( /* Account for core signaling bits difference: bandwidth and ACELP/TCX signaling bit are replaced */ target_bits = add( target_bits, sub( add( FrameSizeConfig[st->frame_size_index].bandwidth_bits, 1 ), signalling_mode1_tcx20_enc_fx( st, 0 ) ) ); } - ELSE if ( EQ_16( st->mdct_sw_enable, MODE2 ) ) + ELSE IF( EQ_16( st->mdct_sw_enable, MODE2 ) ) { target_bits = sub( target_bits, 1 ); } @@ -396,7 +400,6 @@ void core_encode_openloop_fx( coder_tcx_post_fx( st, hLPDmem, st->hTcxCfg, st->synth, A_q, Aw, st->wspeech_enc, Q_new, shift ); - move16(); IF( st->hPlcExt ) { st->hPlcExt->LPDmem = hLPDmem; @@ -430,7 +433,9 @@ void core_encode_openloop_fx( lsf_update_memory( st->narrowBand, st->lsf_old_fx, st->mem_MA_fx, st->mem_MA_fx, M ); st->pstreaklen = 0; - st->streaklimit_fx = 32767; + st->streaklimit_fx = 32767; /*1 Q15*/ + move16(); + move16(); /* check resonance for pitch clipping algorithm */ gp_clip_test_lsf_fx( st->element_mode, st->lsf_old_fx, st->clip_var_fx, 0 ); Copy( st->lsf_old_fx, st->mem_AR_fx, M ); @@ -447,6 +452,8 @@ void core_encode_openloop_fx( *--------------------------------------------------------------*/ IF( st->Opt_DTX_ON != 0 ) { + test(); + test(); /* update CNG parameters in active frames */ IF( EQ_16( st->bwidth, NB ) && st->enableTcxLpc && st->core != ACELP_CORE ) { @@ -454,6 +461,7 @@ void core_encode_openloop_fx( assert( st->L_frame == L_FRAME ); Copy( st->synth + L_FRAME - L_LP, buf, L_LP ); tmp = st->synth[L_FRAME - L_LP - 1]; + move16(); E_UTIL_f_preemph2( Q_new - 1, buf, st->preemph_fac, L_LP, &tmp ); autocorr_fx( buf, M, r_h, r_l, &Q_r, L_LP, Assym_window_W16fx, 0, 0 ); lag_wind( r_h, r_l, M, INT_FS_FX, LAGW_WEAK ); @@ -501,12 +509,13 @@ void core_encode_openloop_fx( *---------------------------------------------------------------*/ test(); - IF( GT_16( st->core, ACELP_CORE ) || ( st->rate_switching_reset != 0 ) ) + IF( ( st->core > ACELP_CORE ) || ( st->rate_switching_reset != 0 ) ) { /*TCX mode: copy values*/ set16_fx( st->mem_bpf_fx.noise_buf, 0, 2 * L_FILT16k ); /*TCX->no gain*/ set16_fx( st->mem_bpf_fx.error_buf, 0, L_FILT16k ); /*TCX->no gain*/ st->bpf_gain_param = 0; + move16(); } ELSE IF( st->acelp_cfg.bpf_mode > 0 ) { @@ -532,7 +541,7 @@ void core_encode_openloop_fx( IF( EQ_16( st->rf_mode, 1 ) ) { set16_fx( lsf_q_1st_rf, 0, M ); - IF( EQ_16( st->core, ACELP_CORE ) ) + IF( st->core == ACELP_CORE ) { /* convert LSPs to LP coefficients */ lsp2lsf_fx( lsp_new, lsf_uq_rf, M, st->sr_core ); @@ -541,14 +550,12 @@ void core_encode_openloop_fx( /* first stage VQ, 8 bits; reuse TCX high rate codebook */ hRF->rf_indx_lsf[0][0] = vlpc_1st_cod_fx( lsf_uq_rf, lsf_q_1st_rf, w_rf, st->rf_mode ); + move16(); /*v_sub(lsf_uq_rf, lsf_q_1st_rf, lsf_q_d_rf, M);*/ FOR( i = 0; i < M; i++ ) { -#ifdef BASOP_NOGLOB lsf_q_d_rf[i] = shl_o( mult_r( sub_o( lsf_uq_rf[i], lsf_q_1st_rf[i], &Overflow ), 25600 ), 5, &Overflow ); -#else - lsf_q_d_rf[i] = shl( mult_r( sub( lsf_uq_rf[i], lsf_q_1st_rf[i] ), 25600 ), 5 ); -#endif + move16(); /*input value is in Qx2.56, convert to Q6 to match table, quantizer table kept at Q6 to avoid losing precision */ /*Assume this difference data max range can be represented by Q6*/ } @@ -567,6 +574,7 @@ void core_encode_openloop_fx( tmp = lsf_q_diff_cb_8b_rf[i + M * hRF->rf_indx_lsf[0][1]]; /*tmp = quantized lsf_q_d_rf in Q6*/ tmp = shr( mult_r( tmp, 20972 ), 4 ); /* bring lsf_q_d_rf to Qx2.56 for addition */ lsf_q_rf[i] = add( lsf_q_1st_rf[i], tmp ); + move16(); } v_sort( lsf_q_rf, 0, M - 1 ); @@ -584,9 +592,12 @@ void core_encode_openloop_fx( hRF->rf_indx_lsf[0][0] = param_lpc[1]; hRF->rf_indx_lsf[0][1] = param_lpc[2]; hRF->rf_indx_lsf[0][2] = param_lpc[3]; + move16(); + move16(); + move16(); } - IF( EQ_16( st->core, ACELP_CORE ) ) + IF( st->core == ACELP_CORE ) { /* current n-th ACELP frame and its corresponding partial copy */ @@ -608,8 +619,9 @@ void core_encode_openloop_fx( /* RF frame type in the buffer */ hRF->rf_indx_frametype[0] = hRF->rf_frame_type; hRF->rf_targetbits_buff[0] = hRF->rf_target_bits; - - IF( NE_16( hRF->rf_frame_type, RF_NO_DATA ) ) + move16(); + move16(); + IF( hRF->rf_frame_type != RF_NO_DATA ) { /* coder_acelp_rf_fx does the partial copy encoding based on the rf frame type chosen for the RF encoding */ coder_acelp_rf_fx( &( hRF->acelp_cfg_rf ), coder_type, Aw, Aq_rf, st->speech_enc_pe, st->voicing_fx, st->pitch, @@ -651,7 +663,7 @@ void core_encode_openloop_fx( test(); test(); test(); - IF( + if ( ( EQ_16( st->core, TCX_20_CORE ) ) /*(st->core == TCX_20_CORE)*/ && ( EQ_16( st->last_core, TCX_20_CORE ) ) /*&&(st->last_core == TCX_20_CORE)*/ && ( EQ_16( hRF->rf_second_last_core, TCX_20_CORE ) ) /*&& (st->rf_second_last_core == TCX_20_CORE)*/ @@ -687,10 +699,12 @@ void core_encode_openloop_fx( LT_16( hRF->rf_gain_tcx[0], mult_r( hRF->rf_gain_tcx[1], 29491 /*0.90f Q15*/ ) ) ) ) { TD_mode = 0; + move16(); } ELSE { TD_mode = 1; + move16(); } /* updates */ @@ -743,6 +757,7 @@ static void closest_centroid_rf( Word32 L_tmp, best_werr, werr; #ifdef BASOP_NOGLOB_DECLARE_LOCAL Flag Overflow = 0; + move32(); #endif ind_vec[0] = 0; @@ -758,13 +773,8 @@ static void closest_centroid_rf( tmpL = i_mult2( i, length ); FOR( j = 0; j < length; j++ ) { -#ifdef BASOP_NOGLOB tmp = sub_o( data[j], quantizer[tmpL + j], &Overflow ); L_tmp = L_mult_o( tmp, tmp, &Overflow ); -#else - tmp = sub( data[j], quantizer[tmpL + j] ); - L_tmp = L_mult( tmp, tmp ); -#endif werr_64 = W_mac_32_16( werr_64, L_tmp, weights[j] ); } werr = W_sat_m( werr_64 ); @@ -782,12 +792,12 @@ static void closest_centroid_rf( void core_acelp_tcx20_switching_fx( Encoder_State *st, /* i/o: encoder state structure */ - Word16 non_staX, /* i : unbound non-stationarity for sp/mu clas */ - Word16 *pitch_fr, /* i/o: fraction pitch values */ - Word16 *voicing_fr, /* i/o: fractional voicing values */ - const Word16 currFlatness, /* i : flatness */ - const Word16 lsp_mid[M], /* i : LSPs at the middle of the frame */ - const Word16 stab_fac, /* i : LP filter stability */ + Word16 non_staX, /* i : unbound non-stationarity for sp/mu clas Q8*/ + Word16 *pitch_fr, /* i/o: fraction pitch values Q6*/ + Word16 *voicing_fr, /* i/o: fractional voicing values Q15*/ + const Word16 currFlatness, /* i : flatness Q7*/ + const Word16 lsp_mid[M], /* i : LSPs at the middle of the frame Q15*/ + const Word16 stab_fac, /* i : LP filter stability Q15*/ Word16 Q_new, Word16 shift ) { @@ -818,6 +828,7 @@ void core_acelp_tcx20_switching_fx( SP_MUS_CLAS_HANDLE hSpMusClas = st->hSpMusClas; #ifdef BASOP_NOGLOB_DECLARE_LOCAL Flag Overflow = 0; + move32(); #endif /* Check minimum pitch for quantization */ @@ -920,7 +931,7 @@ void core_acelp_tcx20_switching_fx( Copy( hTcxEnc->speech_ltp + sub( tcx_offset, shr( overlap, 1 ) ), xn_buf, add( L_frame, overlap ) ); tmp16 = shr( overlap, 1 ); - IF( EQ_16( st->last_core, ACELP_CORE ) ) + IF( st->last_core == ACELP_CORE ) { IF( tcx_offset < 0 ) { @@ -958,7 +969,7 @@ void core_acelp_tcx20_switching_fx( tmp16 = mult_r( shl( L_frame, 5 ), 29309 /*16*0.0559017 Q15*/ ); /* L_frame / sqrt(2*NORM_MDCT_FACTOR); Q9 */ FOR( i = 0; i < L_frame; i++ ) { - x[i] = Mpy_32_16_1( x[i], tmp16 ); + x[i] = Mpy_32_16_1( x[i], tmp16 ); // Q(31-(x_e+6)) move32(); } x_e = add( x_e, 6 ); @@ -971,7 +982,7 @@ void core_acelp_tcx20_switching_fx( IF( st->narrowBand ) { - j = mult( L_frame, 20480 ); + j = mult( L_frame, 20480 /* .625 Q15*/ ); set32_fx( &x[j], 0, sub( L_frame, j ) ); } @@ -1094,11 +1105,7 @@ void core_acelp_tcx20_switching_fx( FOR( j = 0; j < L_SUBFR; j++ ) { -#ifdef BASOP_NOGLOB tmp32 = L_mac0_o( tmp32, st->wspeech_enc[i + j], st->wspeech_enc[i + j], &Overflow ); -#else - tmp32 = L_mac0( tmp32, st->wspeech_enc[i + j], st->wspeech_enc[i + j] ); -#endif } tmp32 = L_shr( BASOP_Util_Log2( tmp32 ), 9 ); /* 15Q16 */ tmp32 = L_add( tmp32, L_sub( 0x1F0000, L_shl( L_deposit_h( add( Q_new, sub( shift, 1 ) ) ), 1 ) ) ); /* wspeech_enc scaling */ @@ -1116,11 +1123,7 @@ void core_acelp_tcx20_switching_fx( tcx_snr = L_shl( Mpy_32_16_1( tcx_snr, 0x6054 ), 2 ); /* 0x6054 -> 10/log2(10) (2Q13) */ BASOP_SATURATE_WARNING_OFF_EVS -#ifdef BASOP_NOGLOB snr_tcx = round_fx_o( L_shl_o( tcx_snr, 8, &Overflow ), &Overflow ); /* 7Q8 */ -#else /* BASOP_NOGLOB */ - snr_tcx = round_fx( L_shl( tcx_snr, 8 ) ); /* 7Q8 */ -#endif /* BASOP_NOGLOB */ BASOP_SATURATE_WARNING_ON_EVS /*--------------------------------------------------------------* @@ -1154,19 +1157,11 @@ void core_acelp_tcx20_switching_fx( FOR( j = 0; j < L_SUBFR; j++ ) { -#ifdef BASOP_NOGLOB signal = L_mac0_o( signal, st->wspeech_enc[i + j], st->wspeech_enc[i + j], &Overflow ); tmp16 = round_fx_o( L_shl_o( Mpy_32_16_r( gain, st->wspeech_enc[i + j - T0] ), 15, &Overflow ), &Overflow ); tmp16 = sub_o( st->wspeech_enc[i + j], tmp16, &Overflow ); noise = L_mac0_o( noise, tmp16, tmp16, &Overflow ); -#else - signal = L_mac0( signal, st->wspeech_enc[i + j], st->wspeech_enc[i + j] ); - - tmp16 = round_fx( L_shl( Mpy_32_16_r( gain, st->wspeech_enc[i + j - T0] ), 15 ) ); - tmp16 = sub( st->wspeech_enc[i + j], tmp16 ); - noise = L_mac0( noise, tmp16, tmp16 ); -#endif } /* Assume always 4 sub frames. */ /*assert( (st->L_frame / L_SUBFR) == 4);*/ @@ -1219,16 +1214,8 @@ void core_acelp_tcx20_switching_fx( test(); if ( ( GT_16( snr_acelp, snr_tcx ) ) && ( LT_16( snr_acelp, add( snr_tcx, 512 /*2.0f Q8*/ ) ) ) && -#ifdef BASOP_NOGLOB - ( LT_16( add_o( st->prevTempFlatness_fx, currFlatness, &Overflow ), 416 /*3.25f Q7*/ ) || EQ_16( stab_fac, 0x7fff ) || -#else /* BASOP_NOGLOB */ - ( LT_16( add( st->prevTempFlatness_fx, currFlatness ), 416 /*3.25f Q7*/ ) || EQ_16( stab_fac, 0x7fff ) || -#endif -#ifdef BASOP_NOGLOB + ( LT_16( add_o( st->prevTempFlatness_fx, currFlatness, &Overflow ), 416 /*3.25f Q7*/ ) || EQ_16( stab_fac, 0x7fff /*1 Q15*/ ) || ( EQ_32( st->sr_core, INT_FS_12k8 ) && EQ_16( st->sp_aud_decision0, 1 ) && LT_16( add_sat( st->prevTempFlatness_fx, currFlatness ), 2560 /*20.f Q7*/ ) ) ) && -#else - ( EQ_32( st->sr_core, INT_FS_12k8 ) && EQ_16( st->sp_aud_decision0, 1 ) && LT_16( add( st->prevTempFlatness_fx, currFlatness ), 2560 /*20.f Q7*/ ) ) ) && -#endif ( LE_16( st->acelpFramesCount, 6 ) ) ) { dsnr = -512 /*-2.0f Q8*/; @@ -1241,11 +1228,7 @@ void core_acelp_tcx20_switching_fx( test(); if ( ( LT_16( snr_acelp, snr_tcx ) ) && ( GT_16( snr_acelp, sub( snr_tcx, 512 /*2.0f Q8*/ ) ) ) && -#ifdef BASOP_NOGLOB ( GT_16( add_sat( st->prevTempFlatness_fx, currFlatness ), 416 /*3.25f Q7*/ ) ) && -#else - ( GT_16( add( st->prevTempFlatness_fx, currFlatness ), 416 /*3.25f Q7*/ ) ) && -#endif ( GE_16( st->acelpFramesCount, 6 ) ) ) { dsnr = 512 /*2.0f Q8*/; @@ -1269,7 +1252,7 @@ void core_acelp_tcx20_switching_fx( test(); test(); test(); - if ( EQ_32( st->sr_core, INT_FS_12k8 ) && ( offset_tcx < 0x18950F ) && GT_16( non_staX, 1280 /*5.0f Q8*/ ) && ( snr_acelp >= snr_tcx - 1024 /*4.0f in Q8*/ ) && GE_16( st->acelpFramesCount, 1 ) && ( ( GT_16( hSpMusClas->lps_fx, hSpMusClas->lpm_fx ) && GE_16( tmp16, 9830 ) ) || ( GE_16( st->acelpFramesCount, 6 ) && ( hSpMusClas->lps_fx > hSpMusClas->lpm_fx - 768 ) ) ) && ( st->sp_aud_decision0 == 0 ) && st->vad_flag != 0 ) + if ( EQ_32( st->sr_core, INT_FS_12k8 ) && ( offset_tcx < 0x18950F ) && GT_16( non_staX, 1280 /*5.0f Q8*/ ) && ( GE_16( snr_acelp, sub( snr_tcx, 1024 /*4.0f in Q8*/ ) ) ) && GE_16( st->acelpFramesCount, 1 ) && ( ( GT_16( hSpMusClas->lps_fx, hSpMusClas->lpm_fx ) && GE_16( tmp16, 9830 ) ) || ( GE_16( st->acelpFramesCount, 6 ) && ( GT_16( hSpMusClas->lps_fx, sub( hSpMusClas->lpm_fx, 768 ) ) ) ) ) && ( st->sp_aud_decision0 == 0 ) && st->vad_flag != 0 ) { /* Fine tuned across various databases based on various metrics to detect TCX frames in speech.*/ dsnr = 1024; @@ -1296,15 +1279,17 @@ void core_acelp_tcx20_switching_fx( test(); test(); if ( EQ_32( st->sr_core, INT_FS_12k8 ) && ( LT_16( non_staX, 512 /*2.0f Q8*/ ) || ( st->flag_noisy_speech_snr == 0 && EQ_16( st->vad_flag, 1 ) && ( offset_tcx == L_add( 0xFFD57AB5, 0 ) ) && GE_16( st->acelpFramesCount, 6 ) ) ) && - ( st->last_core == ACELP_CORE || st->last_core == TCX_20_CORE ) ) + ( st->last_core == ACELP_CORE || EQ_16( st->last_core, TCX_20_CORE ) ) ) { st->core = st->last_core; + move16(); } ELSE IF( GT_16( add( snr_acelp, dsnr ), snr_tcx ) ) { st->core = ACELP_CORE; move16(); st->acelpFramesCount = s_min( 32767 - 1, add( st->acelpFramesCount, 1 ) ); + move16(); } ELSE { @@ -1356,12 +1341,13 @@ void core_acelp_tcx20_switching_fx( *-------------------------------------------------------------------*/ static void BITS_ALLOC_ACELP_config_rf( const Word16 coder_type, - Word16 *tilt_code, + Word16 *tilt_code, // Q15 Word16 *rf_frame_type, Word16 *rf_target_bits, Word16 nb_subfr, Word16 rf_fec_indicator, - Word16 *pitch_buf ) + Word16 *pitch_buf // Q6 +) { Word16 mean_tc, min_tilt_code, max_tilt_code; Word16 nrgMode, ltfMode, ltpMode, gainsMode; @@ -1417,6 +1403,10 @@ static void BITS_ALLOC_ACELP_config_rf( IF( EQ_16( rf_fec_indicator, 1 ) ) { + test(); + test(); + test(); + test(); test(); test(); test(); @@ -1434,6 +1424,10 @@ static void BITS_ALLOC_ACELP_config_rf( } ELSE { + test(); + test(); + test(); + test(); test(); test(); test(); @@ -1456,41 +1450,52 @@ static void BITS_ALLOC_ACELP_config_rf( /* rf_mode, 1 bit */ *rf_target_bits = add( *rf_target_bits, 1 ); - + move16(); /* rf_fec_offset 2 bits */ *rf_target_bits = add( *rf_target_bits, 2 ); - + move16(); /* rf_frame_type, 3 bits */ *rf_target_bits = add( *rf_target_bits, 3 ); - + move16(); /* LSF bits 8 + 8 bits */ *rf_target_bits = add( *rf_target_bits, 16 ); - + move16(); /* Intialize the RF mode frame type to all-pred */ *rf_frame_type = RF_ALLPRED; - + move16(); + test(); test(); - IF( EQ_16( coder_type, INACTIVE ) || en_partial_red == 0 ) + test(); + test(); + IF( coder_type == INACTIVE || en_partial_red == 0 ) { *rf_frame_type = RF_NO_DATA; + move16(); } - ELSE IF( EQ_16( coder_type, UNVOICED ) || EQ_16( coder_type, INACTIVE ) ) + ELSE IF( EQ_16( coder_type, UNVOICED ) || ( coder_type == INACTIVE ) ) { *rf_frame_type = RF_NELP; + move16(); } ELSE IF( EQ_16( coder_type, GENERIC ) && LT_16( max_tilt_code, 1638 /*0.05f Q15*/ ) ) { *rf_frame_type = RF_NOPRED; + move16(); } ELSE IF( EQ_16( coder_type, GENERIC ) && LT_16( mean_tc, 9830 /*0.3f Q15*/ ) ) { *rf_frame_type = RF_GENPRED; + move16(); } nrgMode = ACELP_NRG_MODE[1][1][*rf_frame_type]; ltfMode = ACELP_LTF_MODE[1][1][*rf_frame_type]; ltpMode = ACELP_LTP_MODE[1][1][*rf_frame_type]; gainsMode = ACELP_GAINS_MODE[1][1][*rf_frame_type]; + move16(); + move16(); + move16(); + move16(); /* Number of RF bits for different RF coder types */ SWITCH( *rf_frame_type ) @@ -1499,6 +1504,7 @@ static void BITS_ALLOC_ACELP_config_rf( /* Es_pred bits 3 bits, LTF: 1, pitch: 8,5,5,5, FCB: 0, gain: 7,0,7,0, Diff GFr: 4*/ *rf_target_bits += ( ACELP_NRG_BITS[nrgMode] + ACELP_LTF_BITS[ltfMode] + ACELP_LTP_BITS_SFR[ltpMode][0] + ACELP_LTP_BITS_SFR[ltpMode][1] + ACELP_LTP_BITS_SFR[ltpMode][2] + ACELP_LTP_BITS_SFR[ltpMode][3] + ACELP_GAINS_BITS[gainsMode] + ACELP_GAINS_BITS[gainsMode] + 2 /*2 bits for PartialCopy GainFrame*/ ); + move16(); BREAK; case RF_NOPRED: @@ -1506,6 +1512,7 @@ static void BITS_ALLOC_ACELP_config_rf( /*bits += (3 + 0 + 0 + 28 + 12 + 2); */ /* 64 rf bits */ *rf_target_bits += ( ACELP_NRG_BITS[nrgMode] + ACELP_LTF_BITS[ltfMode] + 28 + ACELP_GAINS_BITS[gainsMode] + ACELP_GAINS_BITS[gainsMode] + 2 /*2 bits for PartialCopy GainFrame*/ ); + move16(); BREAK; case RF_GENPRED: @@ -1513,16 +1520,19 @@ static void BITS_ALLOC_ACELP_config_rf( /*bits += (3 + 0 + 16 + 23 + 10 + 0); */ /* 72 rf bits */ *rf_target_bits += ( ACELP_NRG_BITS[nrgMode] + ACELP_LTF_BITS[ltfMode] + ACELP_LTP_BITS_SFR[ltpMode][0] + ACELP_LTP_BITS_SFR[ltpMode][1] + ACELP_LTP_BITS_SFR[ltpMode][2] + ACELP_LTP_BITS_SFR[ltpMode][3] + 14 + ACELP_GAINS_BITS[gainsMode] + ACELP_GAINS_BITS[gainsMode] + 2 /*2 bits for PartialCopy GainFrame*/ ); + move16(); BREAK; case RF_NELP: /* gain: 19, Diff GFr: 5 */ /*bits += (19 + 5); */ *rf_target_bits += ( 19 + NUM_BITS_SHB_FRAMEGAIN ); + move16(); BREAK; case RF_NO_DATA: *rf_target_bits = 6; + move16(); BREAK; default: @@ -1553,7 +1563,7 @@ static void BITS_ALLOC_TCX_config_rf( move16(); test(); - IF( EQ_16( coder_type, INACTIVE ) || EQ_16( last_core, ACELP_CORE ) ) + IF( ( coder_type == INACTIVE ) || ( last_core == ACELP_CORE ) ) { *rf_frame_type = RF_NO_DATA; move16(); diff --git a/lib_enc/core_enc_reconf.c b/lib_enc/core_enc_reconf.c deleted file mode 100644 index 24729c1241da0adae89e9cbe65962bb739122ed3..0000000000000000000000000000000000000000 --- a/lib_enc/core_enc_reconf.c +++ /dev/null @@ -1,345 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include "prot.h" -#include "rom_com.h" -#include "rom_enc.h" -#include "wmc_auto.h" -#include "prot_fx.h" - -/*-----------------------------------------------------------------* - * Funtion core_coder_reconfig * - * ~~~~~~~~~~~~~~~~~~~ * - * - reconfig core coder when switching to another frame type * - *-----------------------------------------------------------------*/ - -void core_coder_reconfig_ivas_fx( - Encoder_State *st ) -{ - Word16 i, bwidth, index; - TCX_ENC_HANDLE hTcxEnc = st->hTcxEnc; - /*Configuration of ACELP*/ - BITS_ALLOC_init_config_acelp( st->total_brate, st->narrowBand, st->nb_subfr, &( st->acelp_cfg ) ); - - /*Configuration of partial copy*/ - IF( st->Opt_RF_ON ) - { - st->hRF->acelp_cfg_rf.mode_index = 1; - st->hRF->acelp_cfg_rf.midLpc = 0; - st->hRF->acelp_cfg_rf.midLpc_enable = 0; - st->hRF->acelp_cfg_rf.pre_emphasis = 0; - st->hRF->acelp_cfg_rf.formant_enh = 1; - st->hRF->acelp_cfg_rf.formant_tilt = 1; - st->hRF->acelp_cfg_rf.voice_tilt = 1; - st->hRF->acelp_cfg_rf.formant_enh_num = FORMANT_SHARPENING_G1; - st->hRF->acelp_cfg_rf.formant_enh_den = FORMANT_SHARPENING_G2; - move16(); - move16(); - move16(); - move16(); - move16(); - move16(); - move16(); - move16(); - move16(); - } - - IF( EQ_16( st->element_mode, IVAS_CPE_MDCT ) ) - { - st->nb_bits_header_tcx = 2; /* signal class */ - move16(); - } - ELSE IF( st->tcxonly ) - { - st->nb_bits_header_tcx = 1 + 1; /*TCX20/TCX10 + last_core*/ - st->nb_bits_header_tcx = add( st->nb_bits_header_tcx, 2 ); /* Siganl class*/ - move16(); - move16(); - } - ELSE - { - st->nb_bits_header_ace = 1 + 2 + 1; /*TCX/ACELP+coder_type + last_core*/ - st->nb_bits_header_tcx = st->nb_bits_header_ace; - move16(); - move16(); - - IF( st->hTcxCfg != NULL ) - { - IF( st->hTcxCfg->lfacNext <= 0 ) - { - st->nb_bits_header_ace = sub( st->nb_bits_header_ace, 1 ); /*No last_core*/ - move16(); - } - } - } - - - /*Switch off TCX or ACELP?*/ - IF( EQ_32( st->sr_core, INT_FS_12k8 ) ) - { - st->acelpEnabled = extract_l( EQ_16( ( s_and( st->restrictedMode, 1 ) ), 1 ) ); - st->tcx20Enabled = extract_l( EQ_16( ( s_and( st->restrictedMode, 2 ) ), 2 ) ); - move16(); - move16(); - } - st->prevEnergyHF_fx = st->currEnergyHF_fx = 1073725440l /*65535.0f Q14*/; /* prevent block switch */ - st->currEnergyHF_e_fx = 17; - move32(); - move16(); - - /*Sanity check : don't need to be instrumented*/ - IF( st->tcxonly == 0 ) - { - assert( st->acelpEnabled || st->tcx20Enabled || st->frame_size_index == 0 ); - } - ELSE - { - assert( st->tcx10Enabled || st->tcx20Enabled || st->frame_size_index == 0 ); - } - - /* TCX-LTP */ - IF( st->hTcxEnc != NULL ) - { - hTcxEnc->tcxltp = getTcxLtp( st->sr_core ); - move16(); - } - - /*Use for 12.8 kHz sampling rate and low bitrates, the conventional pulse search->better SNR*/ - - st->acelp_autocorr = 1; - move16(); - - test(); - if ( ( LE_32( st->total_brate, ACELP_9k60 ) ) && ( EQ_32( st->sr_core, INT_FS_12k8 ) ) ) - { - st->acelp_autocorr = 0; - move16(); - } - - /*Get bandwidth mode*/ - IF( st->narrowBand ) - { - move16(); - bwidth = NB; - } - ELSE IF( LE_32( st->sr_core, INT_FS_16k ) ) - { - move16(); - bwidth = WB; - } - ELSE - { - move16(); - bwidth = SWB; - } - - /*Scale TCX for non-active frames to adjust loudness with ACELP*/ - IF( st->hTcxCfg != NULL ) - { - st->hTcxCfg->na_scale = 32767 /*1.0f Q15*/; - move16(); - - test(); - IF( LT_16( bwidth, 2 ) && ( st->tcxonly == 0 ) ) - { - /*const Word16 scaleTableSize = sizeof(scaleTcxTable) / sizeof(scaleTcxTable[0]);*/ - - FOR( i = 0; i < SIZE_SCALE_TABLE_TCX; i++ ) - { - - test(); - test(); - IF( EQ_16( bwidth, scaleTcxTable[i].bwmode ) && - GE_32( st->total_brate, scaleTcxTable[i].bitrateFrom ) && - LT_32( st->total_brate, scaleTcxTable[i].bitrateTo ) ) - { - if ( st->rf_mode ) - { - i = sub( i, 1 ); - } - move16(); - st->hTcxCfg->na_scale = scaleTcxTable[i].scale; - BREAK; - } - } - } - } - st->enableTcxLpc = 0; - move16(); - IF( GT_16( st->element_mode, IVAS_SCE ) ) - { - test(); - test(); - st->enableTcxLpc = ( EQ_16( st->lpcQuantization, 1 ) && ( LE_32( st->total_brate, LOWRATE_TCXLPC_MAX_BR_CPE ) || st->rf_mode ) ); - move16(); - } - ELSE - { - test(); - test(); - if ( EQ_16( st->lpcQuantization, 1 ) && ( LE_32( st->total_brate, LOWRATE_TCXLPC_MAX_BR ) || st->rf_mode != 0 ) ) - { - st->enableTcxLpc = 1; - move16(); - } - } - test(); - IF( st->ini_frame == 0 || EQ_16( st->last_codec_mode, MODE1 ) ) - { - st->envWeighted = 0; - move16(); - } - - test(); - test(); - test(); - IF( EQ_16( st->bwidth, SWB ) && - ( EQ_32( st->total_brate, ACELP_16k40 ) || EQ_32( st->total_brate, ACELP_24k40 ) ) && st->element_mode == EVS_MONO ) - { - IF( st->tec_tfa == 0 ) - { - FOR( i = 0; i < MAX_TEC_SMOOTHING_DEG; i++ ) - { - st->hTECEnc->loBuffer[i] = 0; - move16(); - } - } - st->tec_tfa = 1; - move16(); - } - ELSE - { - st->tec_tfa = 0; - move16(); - } - - st->enablePlcWaveadjust = 0; - move16(); - if ( GE_32( st->total_brate, HQ_48k ) ) - { - st->enablePlcWaveadjust = 1; - move16(); - } - - - move16(); - st->glr = 0; - test(); - test(); - test(); - if ( ( EQ_32( st->total_brate, ACELP_9k60 ) || EQ_32( st->total_brate, ACELP_16k40 ) || EQ_32( st->total_brate, ACELP_24k40 ) ) && ( st->element_mode == EVS_MONO ) ) - { - move16(); - st->glr = 1; - } - - IF( st->glr ) - { - move16(); - st->nb_bits_header_ace = add( st->nb_bits_header_ace, G_LPC_RECOVERY_BITS ); - } - IF( hTcxEnc != NULL ) - { - test(); - IF( EQ_16( st->bwidth, NB ) || EQ_16( st->bwidth, WB ) ) - { - IF( st->rf_mode == 0 ) - { - index = s_min( N_TCX_STARTLINE_NOISE_WB - 1, s_max( 3, st->frame_size_index ) ); - } - ELSE - { - index = s_min( N_TCX_STARTLINE_NOISE_WB - 1, s_max( 3, st->frame_size_index - 1 ) ); - } - hTcxEnc->nmStartLine = startLineWB[index]; - move16(); - } - ELSE /* (st->bwidth == SWB || st->bwidth == FB) */ - { - IF( st->rf_mode == 0 ) - { - index = s_min( N_TCX_STARTLINE_NOISE_SWB - 1, sub( s_max( 3, st->frame_size_index ), 3 ) ); - } - ELSE - { - index = s_min( N_TCX_STARTLINE_NOISE_SWB - 1, sub( s_max( 3, st->frame_size_index - 1 ), 3 ) ); - } - test(); - test(); - if ( GE_32( st->total_brate, IVAS_96k ) && LE_32( st->total_brate, IVAS_192k ) && GT_16( st->element_mode, IVAS_SCE ) ) - { - index = sub( index, 1 ); - } - hTcxEnc->nmStartLine = startLineSWB[index]; - move16(); - test(); - test(); - IF( EQ_32( st->total_brate, IVAS_48k ) && EQ_16( st->element_mode, IVAS_CPE_MDCT ) && LT_16( add( hTcxEnc->nmStartLine, shl( hTcxEnc->nmStartLine, 2 ) ), shl( st->L_frame, 2 ) ) ) - { - hTcxEnc->nmStartLine = shr( add( hTcxEnc->nmStartLine, shl( hTcxEnc->nmStartLine, 2 ) ), 2 ); /* low-rate stereo is more efficient than dual-mono due to stereo processing */ - move16(); - } - } - } - - IF( hTcxEnc != NULL ) - { - test(); - test(); - test(); - test(); - test(); - IF( ( LT_32( st->total_brate, ACELP_24k40 ) ) && ( ( GT_32( st->total_brate, st->last_total_brate ) ) || ( EQ_16( st->last_codec_mode, MODE1 ) ) ) ) - { - /* low-freq memQuantZeros_fx must be reset partially if bitrate increased */ - FOR( i = 0; i < hTcxEnc->nmStartLine; i++ ) - { - hTcxEnc->memQuantZeros[i] = 0; - move16(); - } - } - ELSE IF( ( GE_32( st->total_brate, ACELP_24k40 ) ) && ( LE_32( st->total_brate, ACELP_32k ) ) && ( GE_32( st->last_total_brate, ACELP_13k20 ) ) && ( LT_32( st->last_total_brate, ACELP_24k40 ) ) ) - { - FOR( i = 0; i < st->L_frame; i++ ) /* memQuantZeros_fx won't be updated */ - { - hTcxEnc->memQuantZeros[i] = 0; - move16(); - } - } - } -} diff --git a/lib_enc/core_enc_reconf_fx.c b/lib_enc/core_enc_reconf_fx.c index 3140422be5d88531fba60b90693049aa84388a8b..1ba496b0e4f3eca516d5a3b7d53b44b9a84b1500 100644 --- a/lib_enc/core_enc_reconf_fx.c +++ b/lib_enc/core_enc_reconf_fx.c @@ -334,3 +334,307 @@ void core_coder_reconfig_fx( } } } + + +/*-----------------------------------------------------------------* + * Funtion core_coder_reconfig * + * ~~~~~~~~~~~~~~~~~~~ * + * - reconfig core coder when switching to another frame type * + *-----------------------------------------------------------------*/ + +void core_coder_reconfig_ivas_fx( + Encoder_State *st, + const Word32 last_total_brate ) +{ + Word16 i, bwidth, index; + TCX_ENC_HANDLE hTcxEnc = st->hTcxEnc; + /*Configuration of ACELP*/ + BITS_ALLOC_init_config_acelp( st->total_brate, st->narrowBand, st->nb_subfr, &( st->acelp_cfg ) ); + + /*Configuration of partial copy*/ + IF( st->Opt_RF_ON ) + { + st->hRF->acelp_cfg_rf.mode_index = 1; + st->hRF->acelp_cfg_rf.midLpc = 0; + st->hRF->acelp_cfg_rf.midLpc_enable = 0; + st->hRF->acelp_cfg_rf.pre_emphasis = 0; + st->hRF->acelp_cfg_rf.formant_enh = 1; + st->hRF->acelp_cfg_rf.formant_tilt = 1; + st->hRF->acelp_cfg_rf.voice_tilt = 1; + st->hRF->acelp_cfg_rf.formant_enh_num = FORMANT_SHARPENING_G1; + st->hRF->acelp_cfg_rf.formant_enh_den = FORMANT_SHARPENING_G2; + move16(); + move16(); + move16(); + move16(); + move16(); + move16(); + move16(); + move16(); + move16(); + } + + IF( EQ_16( st->element_mode, IVAS_CPE_MDCT ) ) + { + st->nb_bits_header_tcx = 2; /* signal class */ + move16(); + } + ELSE IF( st->tcxonly ) + { + st->nb_bits_header_tcx = 1 + 1; /*TCX20/TCX10 + last_core*/ + st->nb_bits_header_tcx = add( st->nb_bits_header_tcx, 2 ); /* Siganl class*/ + move16(); + move16(); + } + ELSE + { + st->nb_bits_header_ace = 1 + 2 + 1; /*TCX/ACELP+coder_type + last_core*/ + st->nb_bits_header_tcx = st->nb_bits_header_ace; + move16(); + move16(); + + IF( st->hTcxCfg != NULL ) + { + IF( st->hTcxCfg->lfacNext <= 0 ) + { + st->nb_bits_header_ace = sub( st->nb_bits_header_ace, 1 ); /*No last_core*/ + move16(); + } + } + } + + + /*Switch off TCX or ACELP?*/ + IF( EQ_32( st->sr_core, INT_FS_12k8 ) ) + { + st->acelpEnabled = extract_l( EQ_16( ( s_and( st->restrictedMode, 1 ) ), 1 ) ); + st->tcx20Enabled = extract_l( EQ_16( ( s_and( st->restrictedMode, 2 ) ), 2 ) ); + move16(); + move16(); + } + st->prevEnergyHF_fx = st->currEnergyHF_fx = 1073725440l /*65535.0f Q14*/; /* prevent block switch */ + st->currEnergyHF_e_fx = 17; + move32(); + move16(); + + /*Sanity check : don't need to be instrumented*/ + IF( st->tcxonly == 0 ) + { + assert( st->acelpEnabled || st->tcx20Enabled || st->frame_size_index == 0 ); + } + ELSE + { + assert( st->tcx10Enabled || st->tcx20Enabled || st->frame_size_index == 0 ); + } + + /* TCX-LTP */ + IF( st->hTcxEnc != NULL ) + { + hTcxEnc->tcxltp = getTcxLtp( st->sr_core ); + move16(); + } + + /*Use for 12.8 kHz sampling rate and low bitrates, the conventional pulse search->better SNR*/ + + st->acelp_autocorr = 1; + move16(); + + test(); + if ( ( LE_32( st->total_brate, ACELP_9k60 ) ) && ( EQ_32( st->sr_core, INT_FS_12k8 ) ) ) + { + st->acelp_autocorr = 0; + move16(); + } + + /*Get bandwidth mode*/ + IF( st->narrowBand ) + { + move16(); + bwidth = NB; + } + ELSE IF( LE_32( st->sr_core, INT_FS_16k ) ) + { + move16(); + bwidth = WB; + } + ELSE + { + move16(); + bwidth = SWB; + } + + /*Scale TCX for non-active frames to adjust loudness with ACELP*/ + IF( st->hTcxCfg != NULL ) + { + st->hTcxCfg->na_scale = 32767 /*1.0f Q15*/; + move16(); + + test(); + IF( LT_16( bwidth, 2 ) && ( st->tcxonly == 0 ) ) + { + /*const Word16 scaleTableSize = sizeof(scaleTcxTable) / sizeof(scaleTcxTable[0]);*/ + + FOR( i = 0; i < SIZE_SCALE_TABLE_TCX; i++ ) + { + + test(); + test(); + IF( EQ_16( bwidth, scaleTcxTable[i].bwmode ) && + GE_32( st->total_brate, scaleTcxTable[i].bitrateFrom ) && + LT_32( st->total_brate, scaleTcxTable[i].bitrateTo ) ) + { + if ( st->rf_mode ) + { + i = sub( i, 1 ); + } + move16(); + st->hTcxCfg->na_scale = scaleTcxTable[i].scale; + BREAK; + } + } + } + } + st->enableTcxLpc = 0; + move16(); + IF( GT_16( st->element_mode, IVAS_SCE ) ) + { + test(); + test(); + st->enableTcxLpc = ( EQ_16( st->lpcQuantization, 1 ) && ( LE_32( st->total_brate, LOWRATE_TCXLPC_MAX_BR_CPE ) || st->rf_mode ) ); + move16(); + } + ELSE + { + test(); + test(); + if ( EQ_16( st->lpcQuantization, 1 ) && ( LE_32( st->total_brate, LOWRATE_TCXLPC_MAX_BR ) || st->rf_mode != 0 ) ) + { + st->enableTcxLpc = 1; + move16(); + } + } + test(); + IF( st->ini_frame == 0 || EQ_16( st->last_codec_mode, MODE1 ) ) + { + st->envWeighted = 0; + move16(); + } + + test(); + test(); + test(); + IF( EQ_16( st->bwidth, SWB ) && + ( EQ_32( st->total_brate, ACELP_16k40 ) || EQ_32( st->total_brate, ACELP_24k40 ) ) && st->element_mode == EVS_MONO ) + { + IF( st->tec_tfa == 0 ) + { + FOR( i = 0; i < MAX_TEC_SMOOTHING_DEG; i++ ) + { + st->hTECEnc->loBuffer[i] = 0; + move16(); + } + } + st->tec_tfa = 1; + move16(); + } + ELSE + { + st->tec_tfa = 0; + move16(); + } + + st->enablePlcWaveadjust = 0; + move16(); + if ( GE_32( st->total_brate, HQ_48k ) ) + { + st->enablePlcWaveadjust = 1; + move16(); + } + + + move16(); + st->glr = 0; + test(); + test(); + test(); + if ( ( EQ_32( st->total_brate, ACELP_9k60 ) || EQ_32( st->total_brate, ACELP_16k40 ) || EQ_32( st->total_brate, ACELP_24k40 ) ) && ( st->element_mode == EVS_MONO ) ) + { + move16(); + st->glr = 1; + } + + IF( st->glr ) + { + move16(); + st->nb_bits_header_ace = add( st->nb_bits_header_ace, G_LPC_RECOVERY_BITS ); + } + IF( hTcxEnc != NULL ) + { + test(); + IF( EQ_16( st->bwidth, NB ) || EQ_16( st->bwidth, WB ) ) + { + IF( st->rf_mode == 0 ) + { + index = s_min( N_TCX_STARTLINE_NOISE_WB - 1, s_max( 3, st->frame_size_index ) ); + } + ELSE + { + index = s_min( N_TCX_STARTLINE_NOISE_WB - 1, s_max( 3, st->frame_size_index - 1 ) ); + } + hTcxEnc->nmStartLine = startLineWB[index]; + move16(); + } + ELSE /* (st->bwidth == SWB || st->bwidth == FB) */ + { + IF( st->rf_mode == 0 ) + { + index = s_min( N_TCX_STARTLINE_NOISE_SWB - 1, sub( s_max( 3, st->frame_size_index ), 3 ) ); + } + ELSE + { + index = s_min( N_TCX_STARTLINE_NOISE_SWB - 1, sub( s_max( 3, st->frame_size_index - 1 ), 3 ) ); + } + test(); + test(); + if ( GE_32( st->total_brate, IVAS_96k ) && LE_32( st->total_brate, IVAS_192k ) && GT_16( st->element_mode, IVAS_SCE ) ) + { + index = sub( index, 1 ); + } + hTcxEnc->nmStartLine = startLineSWB[index]; + move16(); + test(); + test(); + IF( EQ_32( st->total_brate, IVAS_48k ) && EQ_16( st->element_mode, IVAS_CPE_MDCT ) && LT_16( add( hTcxEnc->nmStartLine, shl( hTcxEnc->nmStartLine, 2 ) ), shl( st->L_frame, 2 ) ) ) + { + hTcxEnc->nmStartLine = shr( add( hTcxEnc->nmStartLine, shl( hTcxEnc->nmStartLine, 2 ) ), 2 ); /* low-rate stereo is more efficient than dual-mono due to stereo processing */ + move16(); + } + } + } + + IF( hTcxEnc != NULL ) + { + test(); + test(); + test(); + test(); + test(); + IF( ( LT_32( st->total_brate, ACELP_24k40 ) ) && ( ( GT_32( st->total_brate, last_total_brate ) ) || ( EQ_16( st->last_codec_mode, MODE1 ) ) ) ) + { + /* low-freq memQuantZeros_fx must be reset partially if bitrate increased */ + FOR( i = 0; i < hTcxEnc->nmStartLine; i++ ) + { + hTcxEnc->memQuantZeros[i] = 0; + move16(); + } + } + ELSE IF( ( GE_32( st->total_brate, ACELP_24k40 ) ) && ( LE_32( st->total_brate, ACELP_32k ) ) && ( GE_32( last_total_brate, ACELP_13k20 ) ) && ( LT_32( last_total_brate, ACELP_24k40 ) ) ) + { + FOR( i = 0; i < st->L_frame; i++ ) /* memQuantZeros_fx won't be updated */ + { + hTcxEnc->memQuantZeros[i] = 0; + move16(); + } + } + } +} diff --git a/lib_enc/core_enc_switch.c b/lib_enc/core_enc_switch.c deleted file mode 100644 index ba842b9ccd1542e261c12e381de5cab619dc2661..0000000000000000000000000000000000000000 --- a/lib_enc/core_enc_switch.c +++ /dev/null @@ -1,296 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include "prot.h" -#include "rom_com.h" -#include "wmc_auto.h" -#include "prot_fx.h" -#include "prot_fx_enc.h" - - -/*-------------------------------------------------------------------* - * core_coder_mode_switch() - * - * - *-------------------------------------------------------------------*/ -void core_coder_mode_switch_ivas_fx( - Encoder_State *st, /* i/o: encoder state structure */ - const Word32 last_total_brate, /* i : last bitrate */ - const Word16 MCT_flag /* i : hMCT handle allocated (1) or not (0)*/ -) -{ - TCX_ENC_HANDLE hTcxEnc = st->hTcxEnc; - Word16 i, fscale, switchWB; - Word32 sr_core; - Word16 bSwitchFromAmrwbIO; - Word16 tcxonly_tmp, exp_res; - - switchWB = 0; - move16(); - bSwitchFromAmrwbIO = 0; - move16(); - exp_res = 0; - move16(); - - - if ( EQ_16( st->last_core, AMR_WB_CORE ) ) - { - bSwitchFromAmrwbIO = 1; - move16(); - } - - /* force active frame for the first frame when switching from high bitrates when DTX is enabled*/ - sr_core = getCoreSamplerateMode2( st->element_mode, st->total_brate, st->bwidth, st->flag_ACELP16k, st->rf_mode, st->is_ism_format ); - - fscale = sr2fscale_fx( sr_core ); - if ( EQ_16( st->last_codec_mode, MODE1 ) ) - { - switchWB = 1; /*force init when coming from MODE1*/ - move16(); - } - - tcxonly_tmp = getTcxonly_fx( st->element_mode, st->total_brate, MCT_flag, st->is_ism_format ); - - if ( NE_32( tcxonly_tmp, st->tcxonly ) ) - { - switchWB = 1; /*force init when coming from MODE1*/ - move16(); - } - - test(); - test(); - IF( EQ_32( fscale, st->fscale ) && !bSwitchFromAmrwbIO && !switchWB ) - { - st->sr_core = sr_core; - move16(); - Word16 tmp = BASOP_Util_Divide3232_Scale( sr_core, FRAMES_PER_SEC, &exp_res ); - st->L_frame = shr( tmp, sub( 15, exp_res ) ); // Q0 - move16(); - - st->tcxonly = getTcxonly_fx( st->element_mode, st->total_brate, MCT_flag, st->is_ism_format ); - move16(); - - Word16 exp_tmp1 = 0; - move16(); - Word16 tmp1 = BASOP_Util_Divide1616_Scale( ONE_IN_Q9, 128, &exp_tmp1 ); - - Word16 exp_tmp2 = 0; - move16(); - Word16 tmp2 = BASOP_Util_Divide3232_Scale( st->total_brate, 100, &exp_tmp2 ); - - Word16 exp_tmp3 = 0; - move16(); - Word16 tmp3 = BASOP_Util_Divide3232_Scale( st->L_frame, st->fscale, &exp_tmp3 ); - - Word32 tmp4 = L_mult0( tmp1, tmp2 ); // exp_tmp1 + exp_tmp2 - Word32 tmp5 = L_shl( Mpy_32_16_1( tmp4, tmp3 ), 1 ); // exp_tmp1 + exp_tmp2 + exp_tmp3 - st->bits_frame_nominal = extract_l( L_shr( tmp5, sub( 31, ( add( add( exp_tmp1, exp_tmp2 ), exp_tmp3 ) ) ) ) ); - move16(); - st->igf = getIgfPresent_fx( st->element_mode, st->total_brate, st->bwidth, st->rf_mode ); - move16(); - /* switch IGF configuration */ - IF( st->igf ) - { - IGFEncSetMode_fx( st->hIGFEnc, st->total_brate, st->bwidth, st->element_mode, st->rf_mode ); - } - st->hTcxCfg->tcx_coded_lines = getNumTcxCodedLines( st->bwidth ); - move16(); - - st->hTcxCfg->bandwidth = getTcxBandwidth( st->bwidth ); - move16(); - if ( st->tcxonly ) - { - st->hTcxCfg->tcxRateLoopOpt = 2; - move16(); - } - else - { - st->hTcxCfg->tcxRateLoopOpt = 0; - move16(); - } - if ( EQ_16( st->element_mode, IVAS_CPE_MDCT ) ) - { - st->hTcxCfg->tcxRateLoopOpt = 3; - move16(); - } - st->hTcxCfg->ctx_hm = getCtxHm( st->element_mode, st->total_brate, st->rf_mode ); - st->hTcxCfg->resq = getResq( st->total_brate ); - hTcxEnc->tcx_lpc_shaped_ari = getTcxLpcShapedAri( st->total_brate, st->rf_mode, st->element_mode ); - test(); - if ( st->hTcxCfg->resq && !st->tcxonly ) - { - st->hTcxCfg->tcxRateLoopOpt = 1; - move16(); - } - st->hTcxCfg->fIsTNSAllowed = getTnsAllowed( st->total_brate, st->igf, st->element_mode ); - move16(); - move16(); - move16(); - move16(); - move16(); - move16(); - move16(); - - IF( st->hTcxCfg->fIsTNSAllowed ) - { - InitTnsConfigs_ivas_fx( st->bwidth, st->hTcxCfg->tcx_coded_lines, st->hTcxCfg->tnsConfig, st->hIGFEnc->infoStopFrequency, st->total_brate, st->element_mode, MCT_flag ); - - SetAllowTnsOnWhite( st->hTcxCfg->tnsConfig, st->element_mode == IVAS_CPE_MDCT ); - } - - IF( EQ_16( st->bwidth, NB ) ) - { - st->narrowBand = 1; - st->min_band = 1; - st->max_band = 16; - } - ELSE - { - st->narrowBand = 0; - st->min_band = 0; - st->max_band = 19; - } - - move16(); - move16(); - move16(); - - FOR( i = 0; i < FRAME_SIZE_NB; i++ ) - { - IF( EQ_32( FrameSizeConfig[i].frame_bits, st->bits_frame_nominal ) ) - { - st->frame_size_index = i; - st->bits_frame = FrameSizeConfig[i].frame_bits; - st->bits_frame_core = FrameSizeConfig[i].frame_net_bits; - move16(); - move16(); - move16(); - BREAK; - } - } - - st->restrictedMode = getRestrictedMode( st->element_mode, st->total_brate, 0 ); - move16(); - core_coder_reconfig_ivas_fx( st ); - } - ELSE - { - st->igf = getIgfPresent_fx( st->element_mode, st->total_brate, st->bwidth, st->rf_mode ); - move16(); - IF( hTcxEnc != NULL ) - { - hTcxEnc->L_frameTCX = extract_l( Mult_32_16( st->input_Fs, 0x0290 ) ); /* 0x0290 is 1/FRAMES_PER_SEC in Q15*/ - move16(); - } - st->currEnergyHF_fx = 0; - move32(); - Word16 shift = getScaleFactor16( st->old_inp_16k_fx, L_INP_MEM ); - Scale_sig( st->old_inp_16k_fx, L_INP_MEM, shift ); - st->exp_old_inp_16k = sub( st->exp_old_inp_16k, shift ); - move16(); - shift = getScaleFactor16( st->old_inp_12k8_fx, L_INP_MEM ); - Scale_sig( st->old_inp_12k8_fx, L_INP_MEM, shift ); - st->exp_old_inp_12k8 = sub( st->exp_old_inp_12k8, shift ); - move16(); - init_coder_ace_plus_ivas_fx( st, last_total_brate, MCT_flag ); - if ( st->hLPDmem != NULL ) - { - st->hLPDmem->q_lpd_old_exc = st->prev_Q_new; - move16(); - } - } - - test(); - IF( st->igf && st->hBWE_TD != NULL ) - { - /* reset TBE */ - test(); - test(); - test(); - test(); - test(); - IF( ( EQ_16( st->bwidth, WB ) && NE_16( st->last_extl, WB_TBE ) ) || - ( EQ_16( st->bwidth, SWB ) && NE_16( st->last_extl, SWB_TBE ) ) || - ( EQ_16( st->bwidth, FB ) && NE_16( st->last_extl, FB_TBE ) ) ) - { - TBEreset_enc_fx( st, st->bwidth ); - } - ELSE - { - set16_fx( st->hBWE_TD->state_lpc_syn_fx, 0, LPC_SHB_ORDER ); - set16_fx( st->hBWE_TD->state_syn_shbexc_fx, 0, L_SHB_LAHEAD ); - set16_fx( st->hBWE_TD->mem_stp_swb_fx, 0, LPC_SHB_ORDER ); - set16_fx( st->hBWE_TD->mem_zero_swb_fx, 0, LPC_SHB_ORDER ); - st->hBWE_TD->gain_prec_swb_fx = ONE_IN_Q14; - move16(); - } - } - test(); - IF( st->envWeighted && !st->enableTcxLpc ) - { - /* Unweight the envelope */ - st->inv_gamma = BASOP_Util_Divide1616_Scale( MAX16B, st->gamma, &exp_res ); - move16(); - st->inv_gamma = shr( st->inv_gamma, sub( Q1, exp_res ) ); /* Q14 */ - move16(); - E_LPC_lsp_unweight( st->lsp_old_fx, st->lsp_old_fx, st->lsf_old_fx, st->inv_gamma, M ); - st->envWeighted = 0; - move16(); - } - - IF( GE_32( st->total_brate, HQ_48k ) ) - { - st->enablePlcWaveadjust = 1; - move16(); - } - ELSE - { - st->enablePlcWaveadjust = 0; - move16(); - } - - test(); - test(); - if ( ( GT_32( last_total_brate, HQ_32k ) || EQ_16( st->last_codec_mode, MODE1 ) ) && ( st->element_mode == EVS_MONO ) ) - { - st->glr_reset = 1; - move16(); - } - - return; -} diff --git a/lib_enc/core_enc_switch_fx.c b/lib_enc/core_enc_switch_fx.c index 1096cfb492cb75edc8ad6ba65069ae4690ec5ef6..f3b4aea6b733fb4dca0a8e778a430f4368e34f96 100644 --- a/lib_enc/core_enc_switch_fx.c +++ b/lib_enc/core_enc_switch_fx.c @@ -4,14 +4,11 @@ #include #include #include "options.h" -#include "prot.h" -//#include "prot_fx.h" -//#include "basop_mpy.h" +#include "prot_fx.h" #include "cnst.h" /* Common constants */ #include "ivas_cnst.h" #include "rom_com_fx.h" #include "rom_com.h" /* Common constants */ -#include "prot_fx.h" /* Function prototypes */ #include "prot_fx_enc.h" /* Function prototypes */ #include "basop_util.h" /* Function prototypes */ @@ -223,3 +220,262 @@ void core_coder_mode_switch_fx( st->glr_reset = 1; } } + + +/*-------------------------------------------------------------------* + * core_coder_mode_switch() + * + * + *-------------------------------------------------------------------*/ +void core_coder_mode_switch_ivas_fx( + Encoder_State *st, /* i/o: encoder state structure */ + const Word32 last_total_brate, /* i : last bitrate */ + const Word16 MCT_flag /* i : hMCT handle allocated (1) or not (0)*/ +) +{ + TCX_ENC_HANDLE hTcxEnc = st->hTcxEnc; + Word16 i, fscale, switchWB; + Word32 sr_core; + Word16 bSwitchFromAmrwbIO; + Word16 tcxonly_tmp, exp_res; + + switchWB = 0; + move16(); + bSwitchFromAmrwbIO = 0; + move16(); + exp_res = 0; + move16(); + + + if ( EQ_16( st->last_core, AMR_WB_CORE ) ) + { + bSwitchFromAmrwbIO = 1; + move16(); + } + + /* force active frame for the first frame when switching from high bitrates when DTX is enabled*/ + sr_core = getCoreSamplerateMode2( st->element_mode, st->total_brate, st->bwidth, st->flag_ACELP16k, st->rf_mode, st->is_ism_format ); + + fscale = sr2fscale_fx( sr_core ); + if ( EQ_16( st->last_codec_mode, MODE1 ) ) + { + switchWB = 1; /*force init when coming from MODE1*/ + move16(); + } + + tcxonly_tmp = getTcxonly_fx( st->element_mode, st->total_brate, MCT_flag, st->is_ism_format ); + + if ( NE_32( tcxonly_tmp, st->tcxonly ) ) + { + switchWB = 1; /*force init when coming from MODE1*/ + move16(); + } + + test(); + test(); + IF( EQ_32( fscale, st->fscale ) && !bSwitchFromAmrwbIO && !switchWB ) + { + st->sr_core = sr_core; + move16(); + Word16 tmp = BASOP_Util_Divide3232_Scale( sr_core, FRAMES_PER_SEC, &exp_res ); + st->L_frame = shr( tmp, sub( 15, exp_res ) ); // Q0 + move16(); + + st->tcxonly = getTcxonly_fx( st->element_mode, st->total_brate, MCT_flag, st->is_ism_format ); + move16(); + + Word16 exp_tmp1 = 0; + move16(); + Word16 tmp1 = BASOP_Util_Divide1616_Scale( ONE_IN_Q9, 128, &exp_tmp1 ); + + Word16 exp_tmp2 = 0; + move16(); + Word16 tmp2 = BASOP_Util_Divide3232_Scale( st->total_brate, 100, &exp_tmp2 ); + + Word16 exp_tmp3 = 0; + move16(); + Word16 tmp3 = BASOP_Util_Divide3232_Scale( st->L_frame, st->fscale, &exp_tmp3 ); + + Word32 tmp4 = L_mult0( tmp1, tmp2 ); // exp_tmp1 + exp_tmp2 + Word32 tmp5 = L_shl( Mpy_32_16_1( tmp4, tmp3 ), 1 ); // exp_tmp1 + exp_tmp2 + exp_tmp3 + st->bits_frame_nominal = extract_l( L_shr( tmp5, sub( 31, ( add( add( exp_tmp1, exp_tmp2 ), exp_tmp3 ) ) ) ) ); + move16(); + st->igf = getIgfPresent_fx( st->element_mode, st->total_brate, st->bwidth, st->rf_mode ); + move16(); + /* switch IGF configuration */ + IF( st->igf ) + { + IGFEncSetMode_fx( st->hIGFEnc, st->total_brate, st->bwidth, st->element_mode, st->rf_mode ); + } + st->hTcxCfg->tcx_coded_lines = getNumTcxCodedLines( st->bwidth ); + move16(); + + st->hTcxCfg->bandwidth = getTcxBandwidth( st->bwidth ); + move16(); + if ( st->tcxonly ) + { + st->hTcxCfg->tcxRateLoopOpt = 2; + move16(); + } + else + { + st->hTcxCfg->tcxRateLoopOpt = 0; + move16(); + } + if ( EQ_16( st->element_mode, IVAS_CPE_MDCT ) ) + { + st->hTcxCfg->tcxRateLoopOpt = 3; + move16(); + } + st->hTcxCfg->ctx_hm = getCtxHm( st->element_mode, st->total_brate, st->rf_mode ); + st->hTcxCfg->resq = getResq( st->total_brate ); + hTcxEnc->tcx_lpc_shaped_ari = getTcxLpcShapedAri( st->total_brate, st->rf_mode, st->element_mode ); + test(); + if ( st->hTcxCfg->resq && !st->tcxonly ) + { + st->hTcxCfg->tcxRateLoopOpt = 1; + move16(); + } + st->hTcxCfg->fIsTNSAllowed = getTnsAllowed( st->total_brate, st->igf, st->element_mode ); + move16(); + move16(); + move16(); + move16(); + move16(); + move16(); + move16(); + + IF( st->hTcxCfg->fIsTNSAllowed ) + { + InitTnsConfigs_ivas_fx( st->bwidth, st->hTcxCfg->tcx_coded_lines, st->hTcxCfg->tnsConfig, st->hIGFEnc->infoStopFrequency, st->total_brate, st->element_mode, MCT_flag ); + + SetAllowTnsOnWhite( st->hTcxCfg->tnsConfig, st->element_mode == IVAS_CPE_MDCT ); + } + + IF( EQ_16( st->bwidth, NB ) ) + { + st->narrowBand = 1; + st->min_band = 1; + st->max_band = 16; + } + ELSE + { + st->narrowBand = 0; + st->min_band = 0; + st->max_band = 19; + } + + move16(); + move16(); + move16(); + + FOR( i = 0; i < FRAME_SIZE_NB; i++ ) + { + IF( EQ_32( FrameSizeConfig[i].frame_bits, st->bits_frame_nominal ) ) + { + st->frame_size_index = i; + st->bits_frame = FrameSizeConfig[i].frame_bits; + st->bits_frame_core = FrameSizeConfig[i].frame_net_bits; + move16(); + move16(); + move16(); + BREAK; + } + } + + st->restrictedMode = getRestrictedMode( st->element_mode, st->total_brate, 0 ); + move16(); + core_coder_reconfig_ivas_fx( st, last_total_brate ); + } + ELSE + { + st->igf = getIgfPresent_fx( st->element_mode, st->total_brate, st->bwidth, st->rf_mode ); + move16(); + IF( hTcxEnc != NULL ) + { + hTcxEnc->L_frameTCX = extract_l( Mult_32_16( st->input_Fs, 0x0290 ) ); /* 0x0290 is 1/FRAMES_PER_SEC in Q15*/ + move16(); + } + st->currEnergyHF_fx = 0; + move32(); + st->currEnergyHF_e_fx = 0; + move16(); + Word16 shift = getScaleFactor16( st->old_inp_16k_fx, L_INP_MEM ); + Scale_sig( st->old_inp_16k_fx, L_INP_MEM, shift ); + st->exp_old_inp_16k = sub( st->exp_old_inp_16k, shift ); + move16(); + shift = getScaleFactor16( st->old_inp_12k8_fx, L_INP_MEM ); + Scale_sig( st->old_inp_12k8_fx, L_INP_MEM, shift ); + st->exp_old_inp_12k8 = sub( st->exp_old_inp_12k8, shift ); + move16(); +#ifdef FIX_920_IGF_INIT_ERROR + init_coder_ace_plus_ivas_fx( st, last_total_brate, st->total_brate, MCT_flag ); +#else + init_coder_ace_plus_ivas_fx( st, last_total_brate, MCT_flag ); +#endif + if ( st->hLPDmem != NULL ) + { + st->hLPDmem->q_lpd_old_exc = st->prev_Q_new; + move16(); + } + } + + test(); + IF( st->igf && st->hBWE_TD != NULL ) + { + /* reset TBE */ + test(); + test(); + test(); + test(); + test(); + IF( ( EQ_16( st->bwidth, WB ) && NE_16( st->last_extl, WB_TBE ) ) || + ( EQ_16( st->bwidth, SWB ) && NE_16( st->last_extl, SWB_TBE ) ) || + ( EQ_16( st->bwidth, FB ) && NE_16( st->last_extl, FB_TBE ) ) ) + { + TBEreset_enc_fx( st, st->bwidth ); + } + ELSE + { + set16_fx( st->hBWE_TD->state_lpc_syn_fx, 0, LPC_SHB_ORDER ); + set16_fx( st->hBWE_TD->state_syn_shbexc_fx, 0, L_SHB_LAHEAD ); + set16_fx( st->hBWE_TD->mem_stp_swb_fx, 0, LPC_SHB_ORDER ); + set16_fx( st->hBWE_TD->mem_zero_swb_fx, 0, LPC_SHB_ORDER ); + st->hBWE_TD->gain_prec_swb_fx = ONE_IN_Q14; + move16(); + } + } + test(); + IF( st->envWeighted && !st->enableTcxLpc ) + { + /* Unweight the envelope */ + st->inv_gamma = BASOP_Util_Divide1616_Scale( MAX16B, st->gamma, &exp_res ); + move16(); + st->inv_gamma = shr( st->inv_gamma, sub( Q1, exp_res ) ); /* Q14 */ + move16(); + E_LPC_lsp_unweight( st->lsp_old_fx, st->lsp_old_fx, st->lsf_old_fx, st->inv_gamma, M ); + st->envWeighted = 0; + move16(); + } + + IF( GE_32( st->total_brate, HQ_48k ) ) + { + st->enablePlcWaveadjust = 1; + move16(); + } + ELSE + { + st->enablePlcWaveadjust = 0; + move16(); + } + + test(); + test(); + if ( ( GT_32( last_total_brate, HQ_32k ) || EQ_16( st->last_codec_mode, MODE1 ) ) && ( st->element_mode == EVS_MONO ) ) + { + st->glr_reset = 1; + move16(); + } + + return; +} diff --git a/lib_enc/core_enc_updt.c b/lib_enc/core_enc_updt.c deleted file mode 100644 index 92a2a7b9e16bca99edaa15efd4e6acc4bdbca01e..0000000000000000000000000000000000000000 --- a/lib_enc/core_enc_updt.c +++ /dev/null @@ -1,117 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include "prot.h" -#include "rom_com.h" -#include "cnst.h" -#include "wmc_auto.h" -#include "prot_fx.h" - -/*-------------------------------------------------------------------* - * core_encode_update() - * - * Common updates of buffers - *-------------------------------------------------------------------*/ - -void core_encode_update_ivas_fx( - Encoder_State *st /* i/o: Encoder state structure */ -) -{ - TCX_ENC_HANDLE hTcxEnc = st->hTcxEnc; - Word16 n; - - /* Update Input Signal Buffers */ - n = add( st->encoderPastSamples_enc, st->encoderLookahead_enc ); - - Copy( st->buf_speech_enc_pe + st->L_frame, st->buf_speech_enc_pe, n ); - Copy( st->buf_speech_enc + st->L_frame, st->buf_speech_enc, n ); - - IF( !st->tcxonly ) - { - n = add( st->L_frame, shr( st->L_frame, 2 ) ); - Copy( st->buf_wspeech_enc + st->L_frame, st->buf_wspeech_enc, n ); - } - - IF( hTcxEnc != NULL ) - { - test(); - test(); - test(); - IF( ( st->core == ACELP_CORE ) || EQ_16( st->core, AMR_WB_CORE ) || EQ_32( st->core_brate, SID_2k40 ) || ( st->core_brate == FRAME_NO_DATA ) ) - { - Word16 max_e = s_max( st->hTcxEnc->exp_buf_speech_ltp, hTcxEnc->exp_buf_speech_ltp ); - Scale_sig( hTcxEnc->buf_speech_ltp, L_PAST_MAX_32k + L_FRAME32k + L_NEXT_MAX_32k, negate( sub( max_e, st->hTcxEnc->exp_buf_speech_ltp ) ) ); // Q(31-max_e) - Copy_Scale_sig( st->buf_speech_enc + st->L_frame, hTcxEnc->buf_speech_ltp + st->L_frame, st->L_frame, negate( sub( max_e, st->exp_buf_speech_enc ) ) ); // Q(31-max_e) - st->hTcxEnc->exp_buf_speech_ltp = max_e; - move16(); - } - } - - n = add( st->encoderPastSamples_enc, st->encoderLookahead_enc ); - Copy( st->buf_synth + st->L_frame, st->buf_synth, add( st->L_frame, L_SUBFR ) ); - IF( hTcxEnc != NULL ) - { - Copy( hTcxEnc->buf_speech_ltp + st->L_frame, hTcxEnc->buf_speech_ltp, n ); - - IF( NE_16( st->element_mode, IVAS_CPE_MDCT ) ) - { - st->hTcxEnc->kernel_switch_corr_past = 0; - st->hTcxEnc->kernel_type[0] = MDCT_IV; - st->hTcxEnc->kernel_symmetry_past = 0; - st->hTcxEnc->enc_ste_pre_corr_past = 0; - - move16(); - move16(); - move16(); - move16(); - } - } - - test(); - test(); - test(); - test(); - test(); - IF( ( st->Opt_DTX_ON && LE_32( st->core_brate, SID_2k40 ) && EQ_16( st->cng_type, FD_CNG ) ) || ( st->tcxonly && ( EQ_16( st->codec_mode, MODE2 ) || ( st->element_mode > EVS_MONO ) ) ) ) - { - /* reset LP memories */ - set16_fx( st->mem_MA_fx, 0, M ); - Copy( GEWB_Ave_fx, st->mem_AR_fx, M ); // 2.56 scaling - } - return; -} diff --git a/lib_enc/core_enc_updt_fx.c b/lib_enc/core_enc_updt_fx.c index 125f0cd524c024eacb7ba95c1e8df1394853be01..305c2a92fe5f74d7c02317667cb6aa3c234f1401 100644 --- a/lib_enc/core_enc_updt_fx.c +++ b/lib_enc/core_enc_updt_fx.c @@ -211,3 +211,77 @@ void core_encode_update_cng_fx( return; } + +/*-------------------------------------------------------------------* + * core_encode_update() + * + * Common updates of buffers + *-------------------------------------------------------------------*/ + +void core_encode_update_ivas_fx( + Encoder_State *st /* i/o: Encoder state structure */ +) +{ + TCX_ENC_HANDLE hTcxEnc = st->hTcxEnc; + Word16 n; + + /* Update Input Signal Buffers */ + n = add( st->encoderPastSamples_enc, st->encoderLookahead_enc ); + + Copy( st->buf_speech_enc_pe + st->L_frame, st->buf_speech_enc_pe, n ); + Copy( st->buf_speech_enc + st->L_frame, st->buf_speech_enc, n ); + + IF( !st->tcxonly ) + { + n = add( st->L_frame, shr( st->L_frame, 2 ) ); + Copy( st->buf_wspeech_enc + st->L_frame, st->buf_wspeech_enc, n ); + } + + IF( hTcxEnc != NULL ) + { + test(); + test(); + test(); + IF( ( st->core == ACELP_CORE ) || EQ_16( st->core, AMR_WB_CORE ) || EQ_32( st->core_brate, SID_2k40 ) || ( st->core_brate == FRAME_NO_DATA ) ) + { + Word16 max_e = s_max( st->hTcxEnc->exp_buf_speech_ltp, st->exp_buf_speech_enc ); + Scale_sig( hTcxEnc->buf_speech_ltp, L_PAST_MAX_32k + L_FRAME32k + L_NEXT_MAX_32k, negate( sub( max_e, st->hTcxEnc->exp_buf_speech_ltp ) ) ); // Q(31-max_e) + Copy_Scale_sig( st->buf_speech_enc + st->L_frame, hTcxEnc->buf_speech_ltp + st->L_frame, st->L_frame, negate( sub( max_e, st->exp_buf_speech_enc ) ) ); // Q(31-max_e) + st->hTcxEnc->exp_buf_speech_ltp = max_e; + move16(); + } + } + + n = add( st->encoderPastSamples_enc, st->encoderLookahead_enc ); + Copy( st->buf_synth + st->L_frame, st->buf_synth, add( st->L_frame, L_SUBFR ) ); + IF( hTcxEnc != NULL ) + { + Copy( hTcxEnc->buf_speech_ltp + st->L_frame, hTcxEnc->buf_speech_ltp, n ); + + IF( NE_16( st->element_mode, IVAS_CPE_MDCT ) ) + { + st->hTcxEnc->kernel_switch_corr_past = 0; + st->hTcxEnc->kernel_type[0] = MDCT_IV; + st->hTcxEnc->kernel_symmetry_past = 0; + st->hTcxEnc->enc_ste_pre_corr_past = 0; + + move16(); + move16(); + move16(); + move16(); + } + } + + test(); + test(); + test(); + test(); + test(); + IF( ( st->Opt_DTX_ON && LE_32( st->core_brate, SID_2k40 ) && EQ_16( st->cng_type, FD_CNG ) ) || ( st->tcxonly && ( EQ_16( st->codec_mode, MODE2 ) || ( st->element_mode > EVS_MONO ) ) ) ) + { + /* reset LP memories */ + set16_fx( st->mem_MA_fx, 0, M ); + Copy( GEWB_Ave_fx, st->mem_AR_fx, M ); // 2.56 scaling + } + return; +} diff --git a/lib_enc/core_switching_enc.c b/lib_enc/core_switching_enc.c deleted file mode 100644 index 1b69de26d8a6fcfbcc65d8b07999bf079d6e867d..0000000000000000000000000000000000000000 --- a/lib_enc/core_switching_enc.c +++ /dev/null @@ -1,597 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include -#include "cnst.h" -#include "rom_enc.h" -#include "rom_com.h" -#include "prot.h" -#include "wmc_auto.h" -#include "prot_fx.h" -#include "prot_fx_enc.h" -#include "ivas_prot_fx.h" - -void core_switching_pre_enc_ivas_fx( - Encoder_State *st_fx, /* i/o: encoder state structure */ - const Word16 *old_inp_12k8, /* i : old input signal @12.8kHz q_old_inp_12k8 */ - const Word16 q_old_inp_12k8, /* i : Q old input signal @12.8kHz */ - const Word16 *old_inp_16k, /* i : old input signal @16kHz q_old_inp_16k */ - const Word16 q_old_inp_16k, /* i : Q old input signal @16kHz */ - const Word16 active_cnt, /* i : active frame counter */ - const Word16 last_element_mode /* i : last_element_mode */ -) -{ - Word16 Sample_Delay_HP, Sample_Delay_LP; - Word16 tmp16; - Word16 tmp; - SC_VBR_ENC_HANDLE hSC_VBR = st_fx->hSC_VBR; - LPD_state_HANDLE hLPDmem = st_fx->hLPDmem; - HQ_ENC_HANDLE hHQ_core = st_fx->hHQ_core; - TD_BWE_ENC_HANDLE hBWE_TD = st_fx->hBWE_TD; - TCX_ENC_HANDLE hTcxEnc = st_fx->hTcxEnc; - FD_BWE_ENC_HANDLE hBWE_FD = st_fx->hBWE_FD; - - /* Mode switching */ - test(); - test(); - test(); - IF( EQ_16( st_fx->last_codec_mode, MODE2 ) || ( ( ( EQ_16( st_fx->last_core, TCX_20_CORE ) || EQ_16( st_fx->last_core, TCX_10_CORE ) ) && ( st_fx->element_mode > EVS_MONO ) ) ) ) - { - IF( hLPDmem != NULL ) - { - st_fx->mem_deemph_fx = hLPDmem->syn[M]; - move16(); - Copy( hLPDmem->mem_syn2, hLPDmem->mem_syn1_fx, M ); - } - - if ( NE_16( st_fx->element_mode, IVAS_CPE_MDCT ) ) - { - st_fx->igf = 0; - move16(); - } - - IF( hBWE_TD != NULL ) - { - IF( st_fx->last_core != ACELP_CORE ) - { - /* reset BWE memories */ - set16_fx( hBWE_TD->old_bwe_exc_fx, 0, PIT16k_MAX * 2 ); - hBWE_TD->bwe_non_lin_prev_scale_fx = L_deposit_l( 0 ); - move32(); - } - - set16_fx( hBWE_FD->old_syn_12k8_16k_fx, 0, NS2SA( 16000, DELAY_FD_BWE_ENC_NS ) ); - } - test(); - IF( EQ_16( st_fx->last_core, TCX_20_CORE ) || EQ_16( st_fx->last_core, TCX_10_CORE ) ) - { - if ( st_fx->element_mode == EVS_MONO ) - { - st_fx->last_core = HQ_CORE; - move16(); - } - IF( hHQ_core != NULL ) - { - set32_fx( hHQ_core->last_ni_gain_fx, 0, BANDS_MAX ); - set16_fx( hHQ_core->last_env_fx, 0, BANDS_MAX ); - hHQ_core->last_max_pos_pulse = 0; - move16(); - - hHQ_core->mode_count = 0; - move16(); - hHQ_core->mode_count1 = 0; - move16(); - - set16_fx( hHQ_core->prev_SWB_peak_pos, 0, SPT_SHORTEN_SBNUM ); - hHQ_core->prev_frm_hfe2 = 0; - move16(); - hHQ_core->prev_stab_hfe2 = 0; - move16(); - } - test(); - /*ALDO overlap windowed past: also used in MODE2 but for other MDCT-LB*/ - IF( ( st_fx->element_mode == EVS_MONO ) && hTcxEnc != NULL ) - { - set16_fx( hTcxEnc->old_out_fx, 0, L_FRAME32k ); - } - } - - test(); - IF( ( EQ_16( st_fx->L_frame, L_FRAME16k ) ) && ( EQ_16( st_fx->last_L_frame, L_FRAME ) ) ) - { - Copy( st_fx->lsp_old_fx, st_fx->lsp_old16k_fx, M ); - - st_fx->rate_switching_reset_16kHz = lsp_convert_poly_fx( st_fx->lsp_old16k_fx, st_fx->L_frame, 0 ); - move16(); - } - - st_fx->use_acelp_preq = 0; - move16(); - } - - test(); - test(); - test(); - if ( EQ_16( st_fx->last_core, -1 ) && ( EQ_16( st_fx->core, HQ_CORE ) || EQ_16( st_fx->core, TCX_20_CORE ) || EQ_16( st_fx->core, TCX_10_CORE ) ) ) - { - /* very first frame is HQ_CORE */ - st_fx->last_core = HQ_CORE; - move16(); - } - - test(); - test(); - IF( EQ_16( st_fx->core, HQ_CORE ) && ( ( st_fx->last_core == ACELP_CORE ) || EQ_16( st_fx->last_core, AMR_WB_CORE ) ) ) /* HQ init */ - { - set32_fx( hHQ_core->last_ni_gain_fx, 0, BANDS_MAX ); - set16_fx( hHQ_core->last_env_fx, 0, BANDS_MAX ); - hHQ_core->last_max_pos_pulse = 0; - move16(); - - hHQ_core->mode_count = 0; - move16(); - hHQ_core->mode_count1 = 0; - move16(); - - set16_fx( hHQ_core->prev_SWB_peak_pos, 0, SPT_SHORTEN_SBNUM ); - hHQ_core->prev_frm_hfe2 = 0; - move16(); - hHQ_core->prev_stab_hfe2 = 0; - move16(); - - IF( hTcxEnc != NULL ) - { - set16_fx( hTcxEnc->old_out_fx, 0, L_FRAME32k ); - } - } - - /* Here we only handle cases where last_ppp and last_nelp not updated when coming from CodecB or other cores - within ACELP_CORE if switching from another bitarate to vbr, last_ppp and last_nelp is always updated in the previous frame */ - test(); - test(); - IF( ( st_fx->core == ACELP_CORE ) && ( ( st_fx->last_core != ACELP_CORE ) || EQ_16( st_fx->last_codec_mode, MODE2 ) ) ) - { - IF( hSC_VBR != NULL ) - { - hSC_VBR->last_last_ppp_mode = 0; - move16(); - hSC_VBR->last_ppp_mode = 0; - move16(); - hSC_VBR->last_nelp_mode = 0; - move16(); - } - } - - test(); - test(); - test(); - IF( ( st_fx->core == ACELP_CORE ) && ( ( st_fx->last_core != ACELP_CORE ) || EQ_16( st_fx->last_codec_mode, MODE2 ) || LE_32( st_fx->last_total_brate, PPP_NELP_2k80 ) ) ) - { - st_fx->act_count = 3; - move16(); - st_fx->uv_count = 0; - move16(); - } - - test(); - test(); - test(); - test(); - test(); - test(); - test(); - IF( ( ( ( st_fx->core == ACELP_CORE ) || EQ_16( st_fx->core, AMR_WB_CORE ) ) && EQ_16( st_fx->last_core, HQ_CORE ) ) || - ( ( EQ_16( st_fx->element_mode, IVAS_CPE_DFT ) || EQ_16( st_fx->element_mode, IVAS_CPE_TD ) || ( EQ_16( st_fx->element_mode, IVAS_CPE_MDCT ) && EQ_16( last_element_mode, IVAS_CPE_DFT ) ) ) && EQ_16( active_cnt, 1 ) ) ) - { - IF( EQ_16( st_fx->L_frame, L_FRAME16k ) ) - { - Copy( TRWB2_Ave_fx, st_fx->lsf_old_fx, M ); /* init of LSP */ - lsf2lsp_fx( st_fx->lsf_old_fx, st_fx->lsp_old_fx, M, INT_FS_16k ); - } - ELSE - { - Copy( TRWB_Ave_fx, st_fx->lsf_old_fx, M ); /* init of LSP */ - lsf2lsp_fx( st_fx->lsf_old_fx, st_fx->lsp_old_fx, M, INT_FS_FX ); - } - - st_fx->mem_deemph_fx = 0; - move16(); - /* Reset ACELP parameters */ - IF( hLPDmem != NULL ) - { - move16(); - hLPDmem->syn[M] = 0; - move16(); - set16_fx( hLPDmem->mem_syn2, 0, M ); - set16_fx( hLPDmem->mem_syn, 0, M ); - set16_fx( hLPDmem->mem_syn1_fx, 0, M ); - hLPDmem->q_mem_syn = Q15; - move16(); - hLPDmem->mem_w0 = 0; - move16(); - hLPDmem->tilt_code = 0; - move16(); - hLPDmem->gc_threshold = 0; - move32(); - /* set16_fx( st_fx->dispMem, 0, 8 ); */ - set16_fx( hLPDmem->dm_fx.prev_gain_pit, 0, 6 ); - hLPDmem->dm_fx.prev_state = 0; - move16(); - hLPDmem->dm_fx.prev_gain_code = L_deposit_l( 0 ); - } - st_fx->Nb_ACELP_frames = 0; - move16(); - - set16_fx( st_fx->mem_MA_fx, 0, M ); - Copy( GEWB_Ave_fx, st_fx->mem_AR_fx, M ); - init_gp_clip_fx( st_fx->clip_var_fx ); - st_fx->last_coder_type = GENERIC; - move16(); - - tmp16 = add( NB_SUBFR, 1 ); - - if ( EQ_16( st_fx->L_frame, L_FRAME ) ) - { - tmp16 = NB_SUBFR; - move16(); - } - - Copy( st_fx->old_pitch_buf_fx + tmp16, st_fx->old_pitch_buf_fx, tmp16 ); - set16_fx( st_fx->old_pitch_buf_fx + tmp16, L_SUBFR, tmp16 ); - - /* Reset old ACELP buffers */ - test(); - IF( ( st_fx->element_mode == EVS_MONO ) && hLPDmem != NULL ) - { - set16_fx( hLPDmem->old_exc, 0, L_EXC_MEM ); - } - IF( hBWE_TD != NULL ) - { - set16_fx( hBWE_TD->old_bwe_exc_fx, 0, PIT16k_MAX * 2 ); - - /* reset BWE memories */ - hBWE_TD->bwe_non_lin_prev_scale_fx = 0; - move32(); - } - IF( hBWE_FD != NULL ) - { - set16_fx( hBWE_FD->old_syn_12k8_16k_fx, 0, NS2SA( 16000, DELAY_FD_BWE_ENC_NS ) ); - } - } - test(); - test(); - test(); - IF( ( ( st_fx->core == ACELP_CORE ) || EQ_16( st_fx->core, AMR_WB_CORE ) ) && ( EQ_16( st_fx->last_core, TCX_20_CORE ) || EQ_16( st_fx->last_core, TCX_10_CORE ) ) ) - { - /* Reset the ACELP core in case of TCX->ACELP core switching */ - st_fx->Nb_ACELP_frames = 0; - move16(); - - IF( hLPDmem != NULL ) - { - hLPDmem->mem_w0 = 0; - move16(); - hLPDmem->tilt_code = 0; - move16(); - hLPDmem->gc_threshold = 0; - move32(); - init_gp_clip_fx( st_fx->clip_var_fx ); - set16_fx( hLPDmem->dm_fx.prev_gain_pit, 0, 6 ); - hLPDmem->dm_fx.prev_state = 0; - move16(); - hLPDmem->dm_fx.prev_gain_code = 0; - move32(); - } - - st_fx->last_coder_type = GENERIC; - move16(); - - tmp16 = shr( st_fx->L_frame, 6 ); - Copy( st_fx->old_pitch_buf_fx + tmp16, st_fx->old_pitch_buf_fx, tmp16 ); - set16_fx( st_fx->old_pitch_buf_fx + tmp16, L_SUBFR, tmp16 ); - - /* Reset old TD BWE buffers */ - IF( hBWE_TD != NULL ) - { - set16_fx( hBWE_TD->old_bwe_exc_fx, 0, PIT16k_MAX * 2 ); - hBWE_TD->bwe_non_lin_prev_scale_fx = 0; - move32(); - } - - /* reset BWE memories */ - IF( hBWE_FD != NULL ) - { - set16_fx( hBWE_FD->old_syn_12k8_16k_fx, 0, NS2SA( 16000, DELAY_FD_BWE_ENC_NS ) ); /* TODO : this might not be needed */ - } - } - test(); - test(); - test(); - IF( GE_32( st_fx->input_Fs, 16000 ) && NE_16( st_fx->last_extl, WB_BWE ) && EQ_16( st_fx->extl, WB_BWE ) && hBWE_FD != NULL ) - { - test(); - IF( NE_16( st_fx->last_extl, SWB_BWE ) && NE_16( st_fx->last_extl, FB_BWE ) ) - { - hBWE_FD->prev_mode = NORMAL; - move16(); - hBWE_FD->modeCount = 0; - move16(); - } - - hBWE_FD->prev_L_swb_norm1 = 8; - move16(); - } - - test(); - test(); - test(); - test(); - test(); - IF( ( GE_32( st_fx->input_Fs, 32000 ) && NE_16( st_fx->last_extl, SWB_BWE ) && EQ_16( st_fx->extl, SWB_BWE ) ) || - ( GE_32( st_fx->input_Fs, 48000 ) && NE_16( st_fx->last_extl, FB_BWE ) && EQ_16( st_fx->extl, FB_BWE ) ) ) - { - /* we are switching to SWB BWE - reset SWB BWE buffers */ - - IF( EQ_16( st_fx->L_frame, L_FRAME ) ) - { - Sample_Delay_HP = NS2SA( 16000, ACELP_LOOK_NS + DELAY_FD_BWE_ENC_12k8_NS + DELAY_FIR_RESAMPL_NS - DELAY_CLDFB_NS ); - Sample_Delay_LP = NS2SA( 12800, ACELP_LOOK_NS + DELAY_FD_BWE_ENC_12k8_NS ); - IF( ( st_fx->element_mode > EVS_MONO ) ) - { - IF( EQ_16( st_fx->element_mode, IVAS_CPE_TD ) ) - { - Sample_Delay_HP = NS2SA( 16000, ACELP_LOOK_NS + DELAY_FD_BWE_ENC_12k8_NS + DELAY_FIR_RESAMPL_NS - DELAY_CLDFB_NS - L_MEM_RECALC_TBE_NS ); - } - Sample_Delay_HP = sub( Sample_Delay_HP, NS2SA( 16000, DELAY_FIR_RESAMPL_NS ) ); - } - IF( GT_16( q_old_inp_12k8, hBWE_FD->prev_Q_input_lp ) ) - { - Copy_Scale_sig( old_inp_12k8 + sub( L_INP_MEM + L_FRAME, Sample_Delay_LP ), hBWE_FD->old_input_lp_fx, Sample_Delay_LP, sub( hBWE_FD->prev_Q_input_lp, q_old_inp_12k8 ) ); // prev_Q_input_lp - } - ELSE - { - Scale_sig( hBWE_FD->old_input_lp_fx, NS2SA( 16000, ACELP_LOOK_NS + DELAY_FD_BWE_ENC_NS ), sub( q_old_inp_12k8, hBWE_FD->prev_Q_input_lp ) ); // q_old_inp_12k8 - hBWE_FD->prev_Q_input_lp = q_old_inp_12k8; - move16(); - Copy( old_inp_12k8 + sub( L_INP_MEM + L_FRAME, Sample_Delay_LP ), hBWE_FD->old_input_lp_fx, Sample_Delay_LP ); - } - } - ELSE - { - Sample_Delay_HP = NS2SA( 16000, ACELP_LOOK_NS + DELAY_FD_BWE_ENC_16k_NS + DELAY_FIR_RESAMPL_NS - DELAY_CLDFB_NS ); - Sample_Delay_LP = NS2SA( 16000, ACELP_LOOK_NS + DELAY_FD_BWE_ENC_16k_NS ); - IF( GT_16( st_fx->element_mode, EVS_MONO ) ) - { - IF( EQ_16( st_fx->element_mode, IVAS_CPE_TD ) ) - { - Sample_Delay_HP = NS2SA( 16000, ACELP_LOOK_NS + DELAY_FD_BWE_ENC_16k_NS + DELAY_FIR_RESAMPL_NS - DELAY_CLDFB_NS - L_MEM_RECALC_TBE_NS ); - } - Sample_Delay_HP = sub( Sample_Delay_HP, NS2SA( 16000, DELAY_FIR_RESAMPL_NS ) ); - } - IF( GT_16( q_old_inp_16k, hBWE_FD->prev_Q_input_lp ) ) - { - Copy_Scale_sig( old_inp_16k + sub( L_INP_MEM + L_FRAME, Sample_Delay_LP ), hBWE_FD->old_input_lp_fx, Sample_Delay_LP, sub( hBWE_FD->prev_Q_input_lp, q_old_inp_16k ) ); // prev_Q_input_lp - } - ELSE - { - Scale_sig( hBWE_FD->old_input_lp_fx, NS2SA( 16000, ACELP_LOOK_NS + DELAY_FD_BWE_ENC_NS ), sub( q_old_inp_16k, hBWE_FD->prev_Q_input_lp ) ); // q_old_inp_16k - hBWE_FD->prev_Q_input_lp = q_old_inp_16k; - move16(); - Copy( old_inp_16k + sub( L_INP_MEM + L_FRAME, Sample_Delay_LP ), hBWE_FD->old_input_lp_fx, Sample_Delay_LP ); - } - } - - tmp = sub( L_LOOK_16k + L_SUBFR16k, Sample_Delay_HP ); - Copy( &hBWE_TD->old_speech_shb_fx[tmp], hBWE_FD->new_input_hp_fx, Sample_Delay_HP ); - - IF( NE_16( st_fx->last_extl, WB_BWE ) ) - { - hBWE_FD->prev_mode = NORMAL; - move16(); - hBWE_FD->modeCount = 0; - move16(); - } - hBWE_FD->EnergyLF_fx = 0; - move32(); - hBWE_FD->prev_L_swb_norm1 = 8; - move16(); /*8.0 in Q0 */ - st_fx->EnergyLT_fx_exp = 30; - move16(); /* Set to a High Exponent so it is 1^-30 */ - } - /*---------------------------------------------------------------------* - * band-width switching from WB -> SWB/FB - *---------------------------------------------------------------------*/ - IF( st_fx->element_mode > EVS_MONO ) - { - IF( st_fx->bwidth_sw_cnt == 0 ) - { - test(); - IF( GE_16( st_fx->bwidth, SWB ) && EQ_16( st_fx->last_bwidth, WB ) ) - { - st_fx->bwidth_sw_cnt = add( st_fx->bwidth_sw_cnt, 1 ); - move16(); - } - } - ELSE - { - st_fx->bwidth_sw_cnt = add( st_fx->bwidth_sw_cnt, 1 ); - move16(); - IF( EQ_16( st_fx->bwidth_sw_cnt, BWS_TRAN_PERIOD ) ) - { - st_fx->bwidth_sw_cnt = 0; - move16(); - } - } - } - - return; -} - -/*---------------------------------------------------------------------* - * core_switching_post_enc() - * - * Postprocessing for ACELP/HQ core switching - *---------------------------------------------------------------------*/ - -void core_switching_post_enc_ivas_fx( - Encoder_State *st, /* i/o: encoder state structure */ - Word16 *old_inp_12k8_fx, /* i : old input signal @12.8kHz Q_new-1 */ - Word16 *old_inp_16k_fx, /* i : old input signal @16kHz Q_new-1 */ - Word16 A_fx[], /* i : unquant. LP filter coefs. Q12 */ - Word16 Q_new ) -{ - IF( EQ_16( st->core, HQ_CORE ) ) - { - st->use_acelp_preq = 0; - move16(); - test(); - test(); - IF( ( st->last_core == ACELP_CORE || EQ_16( st->last_core, AMR_WB_CORE ) ) && st->element_mode == EVS_MONO ) /* core switching ==> ACELP subframe encoding */ - { - /* Memory scaling to keep everything in common q */ - Scale_sig( st->hLPDmem->mem_syn, M, sub( sub( Q_new, 1 ), st->hLPDmem->q_mem_syn ) ); /* Q_new-1 */ - Scale_sig( st->hLPDmem->mem_syn1_fx, M, sub( sub( Q_new, 1 ), st->hLPDmem->q_mem_syn ) ); /* Q_new-1 */ - Scale_sig( st->hLPDmem->mem_syn2, M, sub( sub( Q_new, 1 ), st->hLPDmem->q_mem_syn ) ); /* Q_new-1 */ - Scale_sig( st->hLPDmem->mem_syn3, M, sub( sub( Q_new, 1 ), st->hLPDmem->q_mem_syn ) ); /* Q_new-1 */ - Scale_sig( st->hLPDmem->mem_syn_r, L_SYN_MEM, sub( sub( Q_new, 1 ), st->hLPDmem->q_mem_syn ) ); /* Q_new-1 */ - st->hLPDmem->mem_w0 = shl( st->hLPDmem->mem_w0, sub( sub( Q_new, 1 ), st->hLPDmem->q_mem_syn ) ); /* Q_new-1 */ - move16(); - st->hLPDmem->q_mem_syn = sub( Q_new, 1 ); - move16(); - - acelp_core_switch_enc_ivas_fx( st, old_inp_12k8_fx + L_INP_MEM - NS2SA( INT_FS_12k8, ACELP_LOOK_NS ), old_inp_16k_fx + L_INP_MEM - NS2SA( INT_FS_16k, ACELP_LOOK_NS ), A_fx, 0, sub( Q_new, 1 ) ); - } - - st->hBWE_TD->bwe_non_lin_prev_scale_fx = 0; - move32(); - st->hBWE_FD->mem_deemph_old_syn_fx = 0; - move16(); - st->hBWE_FD->q_mem_deemph_old_syn = 0; - move16(); - } - ELSE - { - IF( st->hBWE_TD == NULL ) - { - return; - } - - test(); - /* reset SWB TBE buffers */ - IF( EQ_16( st->extl, WB_TBE ) && NE_16( st->last_extl, WB_TBE ) ) - { - wb_tbe_extras_reset_fx( st->hBWE_TD->mem_genSHBexc_filt_down_wb2_fx, st->hBWE_TD->mem_genSHBexc_filt_down_wb3_fx ); - - IF( NE_16( st->last_extl, WB_BWE ) ) - { - set16_fx( st->hBWE_TD->decim_state1_fx, 0, ( 2 * ALLPASSSECTIONS_STEEP + 1 ) ); - set16_fx( st->hBWE_TD->decim_state2_fx, 0, ( 2 * ALLPASSSECTIONS_STEEP + 1 ) ); - } - - set16_fx( st->hBWE_TD->state_syn_shbexc_fx, 0, L_SHB_LAHEAD / 4 ); - set16_fx( st->hBWE_TD->syn_overlap_fx, 0, L_SHB_LAHEAD ); - set32_fx( st->hBWE_TD->mem_csfilt_fx, 0, 2 ); - } - - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - - IF( ( EQ_16( st->extl, SWB_TBE ) || EQ_16( st->extl, FB_TBE ) ) && - ( EQ_16( st->last_core, HQ_CORE ) || NE_16( st->L_frame, st->last_L_frame ) || ( NE_16( st->last_extl, SWB_TBE ) && NE_16( st->last_extl, FB_TBE ) && NE_16( st->last_core, TCX_20_CORE ) && NE_16( st->last_core, TCX_10_CORE ) ) ) ) - { - set16_fx( st->hBWE_TD->state_ana_filt_shb_fx, 0, ( 2 * ALLPASSSECTIONS_STEEP + 1 ) ); - - InitSWBencBufferStates_fx( st->hBWE_TD, NULL ); - swb_tbe_reset_fx( st->hBWE_TD->mem_csfilt_fx, st->hBWE_TD->mem_genSHBexc_filt_down_shb_fx, st->hBWE_TD->state_lpc_syn_fx, st->hBWE_TD->syn_overlap_fx, st->hBWE_TD->state_syn_shbexc_fx, &( st->hBWE_TD->tbe_demph_fx ), &( st->hBWE_TD->tbe_premph_fx ), st->hBWE_TD->mem_stp_swb_fx, &( st->hBWE_TD->gain_prec_swb_fx ) ); - - set16_fx( st->hBWE_TD->dec_2_over_3_mem_fx, 0, L_FILT_2OVER3 ); - set16_fx( st->hBWE_TD->dec_2_over_3_mem_lp_fx, 0, L_FILT_2OVER3_LP ); - } - ELSE IF( ( EQ_16( st->extl, SWB_TBE ) || EQ_16( st->extl, FB_TBE ) ) && ( ( EQ_16( st->element_mode, IVAS_CPE_TD ) && NE_16( st->last_extl, SWB_TBE ) && NE_16( st->last_extl, FB_TBE ) ) || ( NE_16( st->element_mode, IVAS_CPE_TD ) && NE_32( st->last_total_brate, st->total_brate ) ) || ( NE_16( st->last_bwidth, st->bwidth ) ) || ( NE_16( st->last_codec_mode, MODE1 ) ) || ( NE_16( st->rf_mode_last, st->rf_mode ) ) ) ) - { - set16_fx( st->hBWE_TD->state_lpc_syn_fx, 0, LPC_SHB_ORDER ); - set16_fx( st->hBWE_TD->state_syn_shbexc_fx, 0, L_SHB_LAHEAD ); - set16_fx( st->hBWE_TD->mem_stp_swb_fx, 0, LPC_SHB_ORDER ); - set16_fx( st->hBWE_TD->mem_zero_swb_fx, 0, LPC_SHB_ORDER ); - st->hBWE_TD->gain_prec_swb_fx = ONE_IN_Q14; - move16(); - } - ELSE IF( EQ_16( st->last_core, TCX_20_CORE ) || EQ_16( st->last_core, TCX_10_CORE ) ) - { - TBEreset_enc_fx( st, st->bwidth ); - } - - test(); - test(); - test(); - test(); - /* Interp_3_2 CNG buffers reset */ - IF( EQ_16( st->extl, FB_TBE ) && ( ( NE_16( st->last_extl, FB_TBE ) && NE_16( st->last_core, TCX_20_CORE ) && NE_16( st->last_core, TCX_10_CORE ) ) || NE_16( st->L_frame, st->last_L_frame ) ) ) - { - set16_fx( st->hBWE_TD->fb_state_lpc_syn_fx, 0, LPC_SHB_ORDER ); - st->hBWE_TD->fb_tbe_demph_fx = 0; - move16(); - fb_tbe_reset_enc_fx( st->hBWE_TD->elliptic_bpf_2_48k_mem_fx, &st->hBWE_TD->prev_fb_energy_fx, st->hBWE_TD->elliptic_bpf_2_48k_mem_fx_Q, &st->hBWE_TD->prev_fb_energy_fx_Q ); - } - /* Fade towards init value for non HQ_CORE */ - IF( st->hHQ_core != NULL ) - { - st->hHQ_core->crest_lp_fx = L_add( Mpy_32_32( HQ_CREST_FAC_SM_FX, st->hHQ_core->crest_lp_fx ), Mpy_32_32( L_sub( ONE_IN_Q31, HQ_CREST_FAC_SM_FX ), L_shr( HQ_CREST_THRESHOLD_FX, sub( Q28, st->hHQ_core->crest_lp_q ) ) ) ); /*crest_lp_q*/ - move32(); - st->hHQ_core->crest_mod_lp_fx = L_add( Mpy_32_32( HQ_CREST_FAC_SM_FX, st->hHQ_core->crest_mod_lp_fx ), Mpy_32_32( L_sub( ONE_IN_Q31, HQ_CREST_FAC_SM_FX ), L_shr( HQ_CREST_MOD_THRESHOLD_FX, sub( Q29, st->hHQ_core->crest_mod_lp_q ) ) ) ); /*crest_mod_lp_q*/ - move32(); - } - } - - return; -} diff --git a/lib_enc/core_switching_enc_fx.c b/lib_enc/core_switching_enc_fx.c index 07468363f7f5f2e537499e8ebf549bbd6d09fef8..dc306229884ed4b3834ea6e0b6da1fcc2ba324a1 100644 --- a/lib_enc/core_switching_enc_fx.c +++ b/lib_enc/core_switching_enc_fx.c @@ -8,8 +8,9 @@ #include "rom_com_fx.h" /* Static table prototypes */ #include "rom_com.h" /* Static table prototypes */ //#include "prot_fx.h" /* Function prototypes */ -#include "prot_fx.h" /* Function prototypes */ -#include "prot_fx_enc.h" /* Function prototypes */ +#include "prot_fx.h" /* Function prototypes */ +#include "ivas_prot_fx.h" /* Function prototypes */ +#include "prot_fx_enc.h" /* Function prototypes */ /*---------------------------------------------------------------------* @@ -372,31 +373,6 @@ void core_switching_pre_enc_fx( st_fx->EnergyLT_fx_exp = 30; move16(); /* Set to a High Exponent so it is 1^-30 */ } - /*---------------------------------------------------------------------* - * band-width switching from WB -> SWB/FB - *---------------------------------------------------------------------*/ -#ifdef IVAS_CODE - IF( GT_16( st_fx->element_mode, EVS_MONO ) ) - { - IF( st_fx->bwidth_sw_cnt_fx == 0 ) - { - IF( GE_16( st_fx->bwidth, SWB ) && EQ_16( st_fx->last_bwidth, WB ) ) - { - st_fx->bwidth_sw_cnt_fx = add( st_fx->bwidth_sw_cnt_fx, 1 ); - } - } - ELSE - { - st_fx->bwidth_sw_cnt_fx = add( st_fx->bwidth_sw_cnt_fx, 1 ); - - IF( EQ_16( st_fx->bwidth_sw_cnt_fx, BWS_TRAN_PERIOD ) ) - { - st_fx->bwidth_sw_cnt_fx = 0; - move16(); - } - } - } -#endif return; } @@ -430,8 +406,8 @@ void core_switching_post_enc_fx( test(); IF( ( ( st_fx->last_core == ACELP_CORE ) || EQ_16( st_fx->last_core, AMR_WB_CORE ) ) && EQ_16( st_fx->element_mode, EVS_MONO ) ) /* core switching ==> CELP subframe encoding */ { - acelp_core_switch_enc_fx( st_fx, old_inp_12k8 + L_INP_MEM - NS2SA_FX2( INT_FS_FX, ACELP_LOOK_NS ), - old_inp_16k + L_INP_MEM - NS2SA_FX2( INT_FS_16k, ACELP_LOOK_NS ), A, Qshift, Q_new ); + acelp_core_switch_enc_fx( st_fx, old_inp_12k8 + L_INP_MEM - NS2SA( INT_FS_FX, ACELP_LOOK_NS ), + old_inp_16k + L_INP_MEM - NS2SA( INT_FS_16k, ACELP_LOOK_NS ), A, Qshift, Q_new ); } hBWE_TD->bwe_non_lin_prev_scale_fx = L_deposit_l( 0 ); @@ -482,22 +458,6 @@ void core_switching_post_enc_fx( set16_fx( hBWE_TD->state_ana_filt_shb_fx, 0, ( 2 * ALLPASSSECTIONS_STEEP + 1 ) ); set16_fx( hBWE_TD->old_speech_shb_fx, 0, L_LOOK_16k + L_SUBFR16k ); -#ifdef IVAS_CODE - set16_fx( hBWE_TD->mem_shb_res_fx, 0, MAX_LEN_MA_FILTER ); - set16_fx( hBWE_TD->old_EnvSHBres_fx, 0, L_FRAME4k ); - hBWE_TD->old_mean_EnvSHBres_fx = 0; - hBWE_TD->prev_enr_EnvSHBres_fx = 32767; /*Q15 ??? */ - hBWE_TD->prev_shb_env_tilt_fx = 0; - hBWE_TD->prev_pow_exc16kWhtnd_fx = 32767; /*Q15 ??? */ - hBWE_TD->prev_mix_factor_fx = 32767; /*Q15 ??? */ - hBWE_TD->prev_Env_error_fx = 0; - move16(); - move16(); - move16(); - move16(); - move16(); - move16(); -#endif swb_tbe_reset_fx( hBWE_TD->mem_csfilt_fx, hBWE_TD->mem_genSHBexc_filt_down_shb_fx, hBWE_TD->state_lpc_syn_fx, hBWE_TD->syn_overlap_fx, hBWE_TD->state_syn_shbexc_fx, &( hBWE_TD->tbe_demph_fx ), &( hBWE_TD->tbe_premph_fx ), hBWE_TD->mem_stp_swb_fx, &( hBWE_TD->gain_prec_swb_fx ) ); @@ -530,14 +490,6 @@ void core_switching_post_enc_fx( hBWE_TD->fb_tbe_demph_fx = 0; fb_tbe_reset_enc_fx( hBWE_TD->elliptic_bpf_2_48k_mem_fx, &hBWE_TD->prev_fb_energy_fx, hBWE_TD->elliptic_bpf_2_48k_mem_fx_Q, &hBWE_TD->prev_fb_energy_fx_Q ); } - /* Fade towards init value for non HQ_CORE */ - IF( st_fx->hHQ_core != NULL ) - { -#ifdef IVAS_CODE - st_fx->hHQ_core->crest_lp = HQ_CREST_FAC_SM * ( st_fx->hHQ_core->crest_lp ) + ( 1.0f - HQ_CREST_FAC_SM ) * HQ_CREST_THRESHOLD; - st_fx->hHQ_core->crest_mod_lp = HQ_CREST_FAC_SM * ( st_fx->hHQ_core->crest_mod_lp ) + ( 1.0f - HQ_CREST_FAC_SM ) * HQ_CREST_MOD_THRESHOLD; -#endif - } } return; @@ -672,3 +624,559 @@ void core_switching_hq_prepare_enc_fx( } return; } + +void core_switching_pre_enc_ivas_fx( + Encoder_State *st_fx, /* i/o: encoder state structure */ + const Word16 *old_inp_12k8, /* i : old input signal @12.8kHz q_old_inp_12k8 */ + const Word16 q_old_inp_12k8, /* i : Q old input signal @12.8kHz */ + const Word16 *old_inp_16k, /* i : old input signal @16kHz q_old_inp_16k */ + const Word16 q_old_inp_16k, /* i : Q old input signal @16kHz */ + const Word16 active_cnt, /* i : active frame counter */ + const Word16 last_element_mode /* i : last_element_mode */ +) +{ + Word16 Sample_Delay_HP, Sample_Delay_LP; + Word16 tmp16; + Word16 tmp; + SC_VBR_ENC_HANDLE hSC_VBR = st_fx->hSC_VBR; + LPD_state_HANDLE hLPDmem = st_fx->hLPDmem; + HQ_ENC_HANDLE hHQ_core = st_fx->hHQ_core; + TD_BWE_ENC_HANDLE hBWE_TD = st_fx->hBWE_TD; + TCX_ENC_HANDLE hTcxEnc = st_fx->hTcxEnc; + FD_BWE_ENC_HANDLE hBWE_FD = st_fx->hBWE_FD; + + /* Mode switching */ + test(); + test(); + test(); + IF( EQ_16( st_fx->last_codec_mode, MODE2 ) || ( ( ( EQ_16( st_fx->last_core, TCX_20_CORE ) || EQ_16( st_fx->last_core, TCX_10_CORE ) ) && ( st_fx->element_mode > EVS_MONO ) ) ) ) + { + IF( hLPDmem != NULL ) + { + st_fx->mem_deemph_fx = hLPDmem->syn[M]; + move16(); + Copy( hLPDmem->mem_syn2, hLPDmem->mem_syn1_fx, M ); + } + + if ( NE_16( st_fx->element_mode, IVAS_CPE_MDCT ) ) + { + st_fx->igf = 0; + move16(); + } + + IF( hBWE_TD != NULL ) + { + IF( st_fx->last_core != ACELP_CORE ) + { + /* reset BWE memories */ + set16_fx( hBWE_TD->old_bwe_exc_fx, 0, PIT16k_MAX * 2 ); + hBWE_TD->bwe_non_lin_prev_scale_fx = L_deposit_l( 0 ); + move32(); + } + + set16_fx( hBWE_FD->old_syn_12k8_16k_fx, 0, NS2SA( 16000, DELAY_FD_BWE_ENC_NS ) ); + } + test(); + IF( EQ_16( st_fx->last_core, TCX_20_CORE ) || EQ_16( st_fx->last_core, TCX_10_CORE ) ) + { + if ( st_fx->element_mode == EVS_MONO ) + { + st_fx->last_core = HQ_CORE; + move16(); + } + IF( hHQ_core != NULL ) + { + set32_fx( hHQ_core->last_ni_gain_fx, 0, BANDS_MAX ); + set16_fx( hHQ_core->last_env_fx, 0, BANDS_MAX ); + hHQ_core->last_max_pos_pulse = 0; + move16(); + + hHQ_core->mode_count = 0; + move16(); + hHQ_core->mode_count1 = 0; + move16(); + + set16_fx( hHQ_core->prev_SWB_peak_pos, 0, SPT_SHORTEN_SBNUM ); + hHQ_core->prev_frm_hfe2 = 0; + move16(); + hHQ_core->prev_stab_hfe2 = 0; + move16(); + } + test(); + /*ALDO overlap windowed past: also used in MODE2 but for other MDCT-LB*/ + IF( ( st_fx->element_mode == EVS_MONO ) && hTcxEnc != NULL ) + { + set16_fx( hTcxEnc->old_out_fx, 0, L_FRAME32k ); + } + } + + test(); + IF( ( EQ_16( st_fx->L_frame, L_FRAME16k ) ) && ( EQ_16( st_fx->last_L_frame, L_FRAME ) ) ) + { + Copy( st_fx->lsp_old_fx, st_fx->lsp_old16k_fx, M ); + + st_fx->rate_switching_reset_16kHz = lsp_convert_poly_fx( st_fx->lsp_old16k_fx, st_fx->L_frame, 0 ); + move16(); + } + + st_fx->use_acelp_preq = 0; + move16(); + } + + test(); + test(); + test(); + if ( EQ_16( st_fx->last_core, -1 ) && ( EQ_16( st_fx->core, HQ_CORE ) || EQ_16( st_fx->core, TCX_20_CORE ) || EQ_16( st_fx->core, TCX_10_CORE ) ) ) + { + /* very first frame is HQ_CORE */ + st_fx->last_core = HQ_CORE; + move16(); + } + + test(); + test(); + IF( EQ_16( st_fx->core, HQ_CORE ) && ( ( st_fx->last_core == ACELP_CORE ) || EQ_16( st_fx->last_core, AMR_WB_CORE ) ) ) /* HQ init */ + { + set32_fx( hHQ_core->last_ni_gain_fx, 0, BANDS_MAX ); + set16_fx( hHQ_core->last_env_fx, 0, BANDS_MAX ); + hHQ_core->last_max_pos_pulse = 0; + move16(); + + hHQ_core->mode_count = 0; + move16(); + hHQ_core->mode_count1 = 0; + move16(); + + set16_fx( hHQ_core->prev_SWB_peak_pos, 0, SPT_SHORTEN_SBNUM ); + hHQ_core->prev_frm_hfe2 = 0; + move16(); + hHQ_core->prev_stab_hfe2 = 0; + move16(); + + IF( hTcxEnc != NULL ) + { + set16_fx( hTcxEnc->old_out_fx, 0, L_FRAME32k ); + } + } + + /* Here we only handle cases where last_ppp and last_nelp not updated when coming from CodecB or other cores + within ACELP_CORE if switching from another bitarate to vbr, last_ppp and last_nelp is always updated in the previous frame */ + test(); + test(); + IF( ( st_fx->core == ACELP_CORE ) && ( ( st_fx->last_core != ACELP_CORE ) || EQ_16( st_fx->last_codec_mode, MODE2 ) ) ) + { + IF( hSC_VBR != NULL ) + { + hSC_VBR->last_last_ppp_mode = 0; + move16(); + hSC_VBR->last_ppp_mode = 0; + move16(); + hSC_VBR->last_nelp_mode = 0; + move16(); + } + } + + test(); + test(); + test(); + IF( ( st_fx->core == ACELP_CORE ) && ( ( st_fx->last_core != ACELP_CORE ) || EQ_16( st_fx->last_codec_mode, MODE2 ) || LE_32( st_fx->last_total_brate, PPP_NELP_2k80 ) ) ) + { + st_fx->act_count = 3; + move16(); + st_fx->uv_count = 0; + move16(); + } + + test(); + test(); + test(); + test(); + test(); + test(); + test(); + IF( ( ( ( st_fx->core == ACELP_CORE ) || EQ_16( st_fx->core, AMR_WB_CORE ) ) && EQ_16( st_fx->last_core, HQ_CORE ) ) || + ( ( EQ_16( st_fx->element_mode, IVAS_CPE_DFT ) || EQ_16( st_fx->element_mode, IVAS_CPE_TD ) || ( EQ_16( st_fx->element_mode, IVAS_CPE_MDCT ) && EQ_16( last_element_mode, IVAS_CPE_DFT ) ) ) && EQ_16( active_cnt, 1 ) ) ) + { + IF( EQ_16( st_fx->L_frame, L_FRAME16k ) ) + { + Copy( TRWB2_Ave_fx, st_fx->lsf_old_fx, M ); /* init of LSP */ + lsf2lsp_fx( st_fx->lsf_old_fx, st_fx->lsp_old_fx, M, INT_FS_16k ); + } + ELSE + { + Copy( TRWB_Ave_fx, st_fx->lsf_old_fx, M ); /* init of LSP */ + lsf2lsp_fx( st_fx->lsf_old_fx, st_fx->lsp_old_fx, M, INT_FS_FX ); + } + + st_fx->mem_deemph_fx = 0; + move16(); + /* Reset ACELP parameters */ + IF( hLPDmem != NULL ) + { + move16(); + hLPDmem->syn[M] = 0; + move16(); + set16_fx( hLPDmem->mem_syn2, 0, M ); + set16_fx( hLPDmem->mem_syn, 0, M ); + set16_fx( hLPDmem->mem_syn1_fx, 0, M ); + hLPDmem->q_mem_syn = Q15; + move16(); + hLPDmem->mem_w0 = 0; + move16(); + hLPDmem->tilt_code = 0; + move16(); + hLPDmem->gc_threshold = 0; + move32(); + /* set16_fx( st_fx->dispMem, 0, 8 ); */ + set16_fx( hLPDmem->dm_fx.prev_gain_pit, 0, 6 ); + hLPDmem->dm_fx.prev_state = 0; + move16(); + hLPDmem->dm_fx.prev_gain_code = L_deposit_l( 0 ); + } + st_fx->Nb_ACELP_frames = 0; + move16(); + + set16_fx( st_fx->mem_MA_fx, 0, M ); + Copy( GEWB_Ave_fx, st_fx->mem_AR_fx, M ); + init_gp_clip_fx( st_fx->clip_var_fx ); + st_fx->last_coder_type = GENERIC; + move16(); + + tmp16 = add( NB_SUBFR, 1 ); + + if ( EQ_16( st_fx->L_frame, L_FRAME ) ) + { + tmp16 = NB_SUBFR; + move16(); + } + + Copy( st_fx->old_pitch_buf_fx + tmp16, st_fx->old_pitch_buf_fx, tmp16 ); + set16_fx( st_fx->old_pitch_buf_fx + tmp16, L_SUBFR, tmp16 ); + + /* Reset old ACELP buffers */ + test(); + IF( ( st_fx->element_mode == EVS_MONO ) && hLPDmem != NULL ) + { + set16_fx( hLPDmem->old_exc, 0, L_EXC_MEM ); + } + IF( hBWE_TD != NULL ) + { + set16_fx( hBWE_TD->old_bwe_exc_fx, 0, PIT16k_MAX * 2 ); + + /* reset BWE memories */ + hBWE_TD->bwe_non_lin_prev_scale_fx = 0; + move32(); + } + IF( hBWE_FD != NULL ) + { + set16_fx( hBWE_FD->old_syn_12k8_16k_fx, 0, NS2SA( 16000, DELAY_FD_BWE_ENC_NS ) ); + } + } + test(); + test(); + test(); + IF( ( ( st_fx->core == ACELP_CORE ) || EQ_16( st_fx->core, AMR_WB_CORE ) ) && ( EQ_16( st_fx->last_core, TCX_20_CORE ) || EQ_16( st_fx->last_core, TCX_10_CORE ) ) ) + { + /* Reset the ACELP core in case of TCX->ACELP core switching */ + st_fx->Nb_ACELP_frames = 0; + move16(); + + IF( hLPDmem != NULL ) + { + hLPDmem->mem_w0 = 0; + move16(); + hLPDmem->tilt_code = 0; + move16(); + hLPDmem->gc_threshold = 0; + move32(); + init_gp_clip_fx( st_fx->clip_var_fx ); + set16_fx( hLPDmem->dm_fx.prev_gain_pit, 0, 6 ); + hLPDmem->dm_fx.prev_state = 0; + move16(); + hLPDmem->dm_fx.prev_gain_code = 0; + move32(); + } + + st_fx->last_coder_type = GENERIC; + move16(); + + tmp16 = shr( st_fx->L_frame, 6 ); + Copy( st_fx->old_pitch_buf_fx + tmp16, st_fx->old_pitch_buf_fx, tmp16 ); + set16_fx( st_fx->old_pitch_buf_fx + tmp16, L_SUBFR, tmp16 ); + + /* Reset old TD BWE buffers */ + IF( hBWE_TD != NULL ) + { + set16_fx( hBWE_TD->old_bwe_exc_fx, 0, PIT16k_MAX * 2 ); + hBWE_TD->bwe_non_lin_prev_scale_fx = 0; + move32(); + } + + /* reset BWE memories */ + IF( hBWE_FD != NULL ) + { + set16_fx( hBWE_FD->old_syn_12k8_16k_fx, 0, NS2SA( 16000, DELAY_FD_BWE_ENC_NS ) ); /* TODO : this might not be needed */ + } + } + test(); + test(); + test(); + IF( GE_32( st_fx->input_Fs, 16000 ) && NE_16( st_fx->last_extl, WB_BWE ) && EQ_16( st_fx->extl, WB_BWE ) && hBWE_FD != NULL ) + { + test(); + IF( NE_16( st_fx->last_extl, SWB_BWE ) && NE_16( st_fx->last_extl, FB_BWE ) ) + { + hBWE_FD->prev_mode = NORMAL; + move16(); + hBWE_FD->modeCount = 0; + move16(); + } + + hBWE_FD->prev_L_swb_norm1 = 8; + move16(); + } + + test(); + test(); + test(); + test(); + test(); + IF( ( GE_32( st_fx->input_Fs, 32000 ) && NE_16( st_fx->last_extl, SWB_BWE ) && EQ_16( st_fx->extl, SWB_BWE ) ) || + ( GE_32( st_fx->input_Fs, 48000 ) && NE_16( st_fx->last_extl, FB_BWE ) && EQ_16( st_fx->extl, FB_BWE ) ) ) + { + /* we are switching to SWB BWE - reset SWB BWE buffers */ + + IF( EQ_16( st_fx->L_frame, L_FRAME ) ) + { + Sample_Delay_HP = NS2SA( 16000, ACELP_LOOK_NS + DELAY_FD_BWE_ENC_12k8_NS + DELAY_FIR_RESAMPL_NS - DELAY_CLDFB_NS ); + Sample_Delay_LP = NS2SA( 12800, ACELP_LOOK_NS + DELAY_FD_BWE_ENC_12k8_NS ); + IF( ( st_fx->element_mode > EVS_MONO ) ) + { + IF( EQ_16( st_fx->element_mode, IVAS_CPE_TD ) ) + { + Sample_Delay_HP = NS2SA( 16000, ACELP_LOOK_NS + DELAY_FD_BWE_ENC_12k8_NS + DELAY_FIR_RESAMPL_NS - DELAY_CLDFB_NS - L_MEM_RECALC_TBE_NS ); + } + Sample_Delay_HP = sub( Sample_Delay_HP, NS2SA( 16000, DELAY_FIR_RESAMPL_NS ) ); + } + IF( GT_16( q_old_inp_12k8, hBWE_FD->prev_Q_input_lp ) ) + { + Copy_Scale_sig( old_inp_12k8 + sub( L_INP_MEM + L_FRAME, Sample_Delay_LP ), hBWE_FD->old_input_lp_fx, Sample_Delay_LP, sub( hBWE_FD->prev_Q_input_lp, q_old_inp_12k8 ) ); // prev_Q_input_lp + } + ELSE + { + Scale_sig( hBWE_FD->old_input_lp_fx, NS2SA( 16000, ACELP_LOOK_NS + DELAY_FD_BWE_ENC_NS ), sub( q_old_inp_12k8, hBWE_FD->prev_Q_input_lp ) ); // q_old_inp_12k8 + hBWE_FD->prev_Q_input_lp = q_old_inp_12k8; + move16(); + Copy( old_inp_12k8 + sub( L_INP_MEM + L_FRAME, Sample_Delay_LP ), hBWE_FD->old_input_lp_fx, Sample_Delay_LP ); + } + } + ELSE + { + Sample_Delay_HP = NS2SA( 16000, ACELP_LOOK_NS + DELAY_FD_BWE_ENC_16k_NS + DELAY_FIR_RESAMPL_NS - DELAY_CLDFB_NS ); + Sample_Delay_LP = NS2SA( 16000, ACELP_LOOK_NS + DELAY_FD_BWE_ENC_16k_NS ); + IF( GT_16( st_fx->element_mode, EVS_MONO ) ) + { + IF( EQ_16( st_fx->element_mode, IVAS_CPE_TD ) ) + { + Sample_Delay_HP = NS2SA( 16000, ACELP_LOOK_NS + DELAY_FD_BWE_ENC_16k_NS + DELAY_FIR_RESAMPL_NS - DELAY_CLDFB_NS - L_MEM_RECALC_TBE_NS ); + } + Sample_Delay_HP = sub( Sample_Delay_HP, NS2SA( 16000, DELAY_FIR_RESAMPL_NS ) ); + } + IF( GT_16( q_old_inp_16k, hBWE_FD->prev_Q_input_lp ) ) + { + Copy_Scale_sig( old_inp_16k + sub( L_INP_MEM + L_FRAME, Sample_Delay_LP ), hBWE_FD->old_input_lp_fx, Sample_Delay_LP, sub( hBWE_FD->prev_Q_input_lp, q_old_inp_16k ) ); // prev_Q_input_lp + } + ELSE + { + Scale_sig( hBWE_FD->old_input_lp_fx, NS2SA( 16000, ACELP_LOOK_NS + DELAY_FD_BWE_ENC_NS ), sub( q_old_inp_16k, hBWE_FD->prev_Q_input_lp ) ); // q_old_inp_16k + hBWE_FD->prev_Q_input_lp = q_old_inp_16k; + move16(); + Copy( old_inp_16k + sub( L_INP_MEM + L_FRAME, Sample_Delay_LP ), hBWE_FD->old_input_lp_fx, Sample_Delay_LP ); + } + } + + tmp = sub( L_LOOK_16k + L_SUBFR16k, Sample_Delay_HP ); + Copy( &hBWE_TD->old_speech_shb_fx[tmp], hBWE_FD->new_input_hp_fx, Sample_Delay_HP ); +#ifdef FIX_ISSUE_1230 + hBWE_FD->Q_new_input_hp = 0; + move16(); +#endif + + IF( NE_16( st_fx->last_extl, WB_BWE ) ) + { + hBWE_FD->prev_mode = NORMAL; + move16(); + hBWE_FD->modeCount = 0; + move16(); + } + hBWE_FD->EnergyLF_fx = 0; + hBWE_FD->EnergyLF_exp = 0; + move32(); + move16(); + hBWE_FD->prev_L_swb_norm1 = 8; + move16(); /*8.0 in Q0 */ + st_fx->EnergyLT_fx_exp = 30; + move16(); /* Set to a High Exponent so it is 1^-30 */ + } + /*---------------------------------------------------------------------* + * band-width switching from WB -> SWB/FB + *---------------------------------------------------------------------*/ + IF( st_fx->element_mode > EVS_MONO ) + { + IF( st_fx->bwidth_sw_cnt == 0 ) + { + test(); + IF( GE_16( st_fx->bwidth, SWB ) && EQ_16( st_fx->last_bwidth, WB ) ) + { + st_fx->bwidth_sw_cnt = add( st_fx->bwidth_sw_cnt, 1 ); + move16(); + } + } + ELSE + { + st_fx->bwidth_sw_cnt = add( st_fx->bwidth_sw_cnt, 1 ); + move16(); + IF( EQ_16( st_fx->bwidth_sw_cnt, BWS_TRAN_PERIOD ) ) + { + st_fx->bwidth_sw_cnt = 0; + move16(); + } + } + } + + return; +} + +/*---------------------------------------------------------------------* + * core_switching_post_enc() + * + * Postprocessing for ACELP/HQ core switching + *---------------------------------------------------------------------*/ + +void core_switching_post_enc_ivas_fx( + Encoder_State *st, /* i/o: encoder state structure */ + Word16 *old_inp_12k8_fx, /* i : old input signal @12.8kHz Q_new-1 */ + Word16 *old_inp_16k_fx, /* i : old input signal @16kHz Q_new-1 */ + Word16 A_fx[], /* i : unquant. LP filter coefs. Q12 */ + Word16 Q_new ) +{ + IF( EQ_16( st->core, HQ_CORE ) ) + { + st->use_acelp_preq = 0; + move16(); + test(); + test(); + IF( ( st->last_core == ACELP_CORE || EQ_16( st->last_core, AMR_WB_CORE ) ) && st->element_mode == EVS_MONO ) /* core switching ==> ACELP subframe encoding */ + { + /* Memory scaling to keep everything in common q */ + Scale_sig( st->hLPDmem->mem_syn, M, sub( sub( Q_new, 1 ), st->hLPDmem->q_mem_syn ) ); /* Q_new-1 */ + Scale_sig( st->hLPDmem->mem_syn1_fx, M, sub( sub( Q_new, 1 ), st->hLPDmem->q_mem_syn ) ); /* Q_new-1 */ + Scale_sig( st->hLPDmem->mem_syn2, M, sub( sub( Q_new, 1 ), st->hLPDmem->q_mem_syn ) ); /* Q_new-1 */ + Scale_sig( st->hLPDmem->mem_syn3, M, sub( sub( Q_new, 1 ), st->hLPDmem->q_mem_syn ) ); /* Q_new-1 */ + Scale_sig( st->hLPDmem->mem_syn_r, L_SYN_MEM, sub( sub( Q_new, 1 ), st->hLPDmem->q_mem_syn ) ); /* Q_new-1 */ + st->hLPDmem->mem_w0 = shl( st->hLPDmem->mem_w0, sub( sub( Q_new, 1 ), st->hLPDmem->q_mem_syn ) ); /* Q_new-1 */ + move16(); + st->hLPDmem->q_mem_syn = sub( Q_new, 1 ); + move16(); + + acelp_core_switch_enc_ivas_fx( st, old_inp_12k8_fx + L_INP_MEM - NS2SA( INT_FS_12k8, ACELP_LOOK_NS ), old_inp_16k_fx + L_INP_MEM - NS2SA( INT_FS_16k, ACELP_LOOK_NS ), A_fx, 0, sub( Q_new, 1 ) ); + } + + st->hBWE_TD->bwe_non_lin_prev_scale_fx = 0; + move32(); + st->hBWE_FD->mem_deemph_old_syn_fx = 0; + move16(); + st->hBWE_FD->q_mem_deemph_old_syn = 0; + move16(); + } + ELSE + { + IF( st->hBWE_TD == NULL ) + { + return; + } + + test(); + /* reset SWB TBE buffers */ + IF( EQ_16( st->extl, WB_TBE ) && NE_16( st->last_extl, WB_TBE ) ) + { + wb_tbe_extras_reset_fx( st->hBWE_TD->mem_genSHBexc_filt_down_wb2_fx, st->hBWE_TD->mem_genSHBexc_filt_down_wb3_fx ); + + IF( NE_16( st->last_extl, WB_BWE ) ) + { + set16_fx( st->hBWE_TD->decim_state1_fx, 0, ( 2 * ALLPASSSECTIONS_STEEP + 1 ) ); + set16_fx( st->hBWE_TD->decim_state2_fx, 0, ( 2 * ALLPASSSECTIONS_STEEP + 1 ) ); + } + + set16_fx( st->hBWE_TD->state_syn_shbexc_fx, 0, L_SHB_LAHEAD / 4 ); + set16_fx( st->hBWE_TD->syn_overlap_fx, 0, L_SHB_LAHEAD ); + set32_fx( st->hBWE_TD->mem_csfilt_fx, 0, 2 ); + } + + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + + IF( ( EQ_16( st->extl, SWB_TBE ) || EQ_16( st->extl, FB_TBE ) ) && + ( EQ_16( st->last_core, HQ_CORE ) || NE_16( st->L_frame, st->last_L_frame ) || ( NE_16( st->last_extl, SWB_TBE ) && NE_16( st->last_extl, FB_TBE ) && NE_16( st->last_core, TCX_20_CORE ) && NE_16( st->last_core, TCX_10_CORE ) ) ) ) + { + set16_fx( st->hBWE_TD->state_ana_filt_shb_fx, 0, ( 2 * ALLPASSSECTIONS_STEEP + 1 ) ); + + InitSWBencBufferStates_fx( st->hBWE_TD, NULL ); + swb_tbe_reset_fx( st->hBWE_TD->mem_csfilt_fx, st->hBWE_TD->mem_genSHBexc_filt_down_shb_fx, st->hBWE_TD->state_lpc_syn_fx, st->hBWE_TD->syn_overlap_fx, st->hBWE_TD->state_syn_shbexc_fx, &( st->hBWE_TD->tbe_demph_fx ), &( st->hBWE_TD->tbe_premph_fx ), st->hBWE_TD->mem_stp_swb_fx, &( st->hBWE_TD->gain_prec_swb_fx ) ); + + set16_fx( st->hBWE_TD->dec_2_over_3_mem_fx, 0, L_FILT_2OVER3 ); + set16_fx( st->hBWE_TD->dec_2_over_3_mem_lp_fx, 0, L_FILT_2OVER3_LP ); + } + ELSE IF( ( EQ_16( st->extl, SWB_TBE ) || EQ_16( st->extl, FB_TBE ) ) && ( ( EQ_16( st->element_mode, IVAS_CPE_TD ) && NE_16( st->last_extl, SWB_TBE ) && NE_16( st->last_extl, FB_TBE ) ) || ( NE_16( st->element_mode, IVAS_CPE_TD ) && NE_32( st->last_total_brate, st->total_brate ) ) || ( NE_16( st->last_bwidth, st->bwidth ) ) || ( NE_16( st->last_codec_mode, MODE1 ) ) || ( NE_16( st->rf_mode_last, st->rf_mode ) ) ) ) + { + set16_fx( st->hBWE_TD->state_lpc_syn_fx, 0, LPC_SHB_ORDER ); + set16_fx( st->hBWE_TD->state_syn_shbexc_fx, 0, L_SHB_LAHEAD ); + set16_fx( st->hBWE_TD->mem_stp_swb_fx, 0, LPC_SHB_ORDER ); + set16_fx( st->hBWE_TD->mem_zero_swb_fx, 0, LPC_SHB_ORDER ); + st->hBWE_TD->gain_prec_swb_fx = ONE_IN_Q14; + move16(); + } + ELSE IF( EQ_16( st->last_core, TCX_20_CORE ) || EQ_16( st->last_core, TCX_10_CORE ) ) + { + TBEreset_enc_fx( st, st->bwidth ); + } + + test(); + test(); + test(); + test(); + /* Interp_3_2 CNG buffers reset */ + IF( EQ_16( st->extl, FB_TBE ) && ( ( NE_16( st->last_extl, FB_TBE ) && NE_16( st->last_core, TCX_20_CORE ) && NE_16( st->last_core, TCX_10_CORE ) ) || NE_16( st->L_frame, st->last_L_frame ) ) ) + { + set16_fx( st->hBWE_TD->fb_state_lpc_syn_fx, 0, LPC_SHB_ORDER ); + st->hBWE_TD->fb_tbe_demph_fx = 0; + move16(); + fb_tbe_reset_enc_fx( st->hBWE_TD->elliptic_bpf_2_48k_mem_fx, &st->hBWE_TD->prev_fb_energy_fx, st->hBWE_TD->elliptic_bpf_2_48k_mem_fx_Q, &st->hBWE_TD->prev_fb_energy_fx_Q ); + } + /* Fade towards init value for non HQ_CORE */ + IF( st->hHQ_core != NULL ) + { + st->hHQ_core->crest_lp_fx = L_add( Mpy_32_32( HQ_CREST_FAC_SM_FX, st->hHQ_core->crest_lp_fx ), Mpy_32_32( L_sub( ONE_IN_Q31, HQ_CREST_FAC_SM_FX ), L_shr( HQ_CREST_THRESHOLD_FX, sub( Q28, st->hHQ_core->crest_lp_q ) ) ) ); /*crest_lp_q*/ + move32(); + st->hHQ_core->crest_mod_lp_fx = L_add( Mpy_32_32( HQ_CREST_FAC_SM_FX, st->hHQ_core->crest_mod_lp_fx ), Mpy_32_32( L_sub( ONE_IN_Q31, HQ_CREST_FAC_SM_FX ), L_shr( HQ_CREST_MOD_THRESHOLD_FX, sub( Q29, st->hHQ_core->crest_mod_lp_q ) ) ) ); /*crest_mod_lp_q*/ + move32(); + } + } + + return; +} diff --git a/lib_enc/corr_xh.c b/lib_enc/corr_xh.c deleted file mode 100644 index 68195a7eccbfde1ac6b60711878e1ad2fca7bf66..0000000000000000000000000000000000000000 --- a/lib_enc/corr_xh.c +++ /dev/null @@ -1,41 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include "prot.h" -#include "cnst.h" -#include "wmc_auto.h" diff --git a/lib_enc/corr_xh_fx.c b/lib_enc/corr_xh_fx.c index 8a1c8c483903fcce7a46e09de2ab947077822b88..51165d141e93973a92e5c45de7c4a803f7c80075 100644 --- a/lib_enc/corr_xh_fx.c +++ b/lib_enc/corr_xh_fx.c @@ -47,11 +47,7 @@ void corr_xh_fx( L_tmp = L_mac( 1L, x[i], h[0] ); /* 1 -> to avoid null dn[] Qx+15*/ FOR( j = i; j < L_SUBFR - 1; j++ ) { -#ifdef BASOP_NOGLOB L_tmp = L_mac_o( L_tmp, x[j + 1], h[j + 1 - i], &Overflow ); /*Qx+15*/ -#else - L_tmp = L_mac( L_tmp, x[j + 1], h[j + 1 - i] ); -#endif } y32[i] = L_tmp; /*Qx+15*/ @@ -61,13 +57,8 @@ void corr_xh_fx( } /* tot += 3*max / 8 */ L_maxloc = L_shr( L_maxloc, 2 ); -#ifdef BASOP_NOGLOB L_tot = L_add_o( L_tot, L_maxloc, &Overflow ); /* +max/4 */ L_tot = L_add_o( L_tot, L_shr( L_maxloc, 1 ), &Overflow ); /* +max/8 */ -#else - L_tot = L_add( L_tot, L_maxloc ); /* +max/4 */ - L_tot = L_add( L_tot, L_shr( L_maxloc, 1 ) ); /* +max/8 */ -#endif } /* Find the number of right shifts to do on y32[] so that */ @@ -107,11 +98,7 @@ void corr_hh_ivas_fx( L_tmp = L_mac( 1L, shr( h[i], 3 ), shr( h[0], 3 ) ); /* 1 -> to avoid null dn[] */ // 2*(15 - norm_s(h[0]) -3) - 1 FOR( j = i; j < L_subfr - 1; j++ ) { -#ifdef BASOP_NOGLOB L_tmp = L_mac_o( L_tmp, shr( h[j + 1], 3 ), shr( h[j + 1 - i], 3 ), &Overflow ); // 2*(15 - norm_s(h[0]) -3) - 1 -#else - L_tmp = L_mac( L_tmp, x[j + 1], h[j + 1 - i] ); -#endif } y32[i] = L_tmp; // 2*(15 - norm_s(h[0]) -3) - 1 @@ -121,13 +108,8 @@ void corr_hh_ivas_fx( } /* tot += 3*max / 8 */ L_maxloc = L_shr( L_maxloc, 2 ); -#ifdef BASOP_NOGLOB L_tot = L_add_o( L_tot, L_maxloc, &Overflow ); /* +max/4 */ L_tot = L_add_o( L_tot, L_shr( L_maxloc, 1 ), &Overflow ); /* +max/8 */ -#else - L_tot = L_add( L_tot, L_maxloc ); /* +max/4 */ - L_tot = L_add( L_tot, L_shr( L_maxloc, 1 ) ); /* +max/8 */ -#endif } /* Find the number of right shifts to do on y32[] so that */ @@ -173,11 +155,7 @@ void corr_xh_ivas_fx( L_tmp = L_mac( 0, x[i], h[0] ); // Qx+(15 - norm_s(h[0])) FOR( j = i; j < L_subfr - 1; j++ ) { -#ifdef BASOP_NOGLOB L_tmp = L_mac_o( L_tmp, x[j + 1], h[j + 1 - i], &Overflow ); // Qx+(15 - norm_s(h[0])) -#else - L_tmp = L_mac( L_tmp, x[j + 1], h[j + 1 - i] ); -#endif } y32[i] = L_tmp; // Qx+(15 - norm_s(h[0])) @@ -187,13 +165,8 @@ void corr_xh_ivas_fx( } /* tot += 3*max / 8 */ L_maxloc = L_shr( L_maxloc, 2 ); -#ifdef BASOP_NOGLOB L_tot = L_add_o( L_tot, L_maxloc, &Overflow ); /* +max/4 */ L_tot = L_add_o( L_tot, L_shr( L_maxloc, 1 ), &Overflow ); /* +max/8 */ -#else - L_tot = L_add( L_tot, L_maxloc ); /* +max/4 */ - L_tot = L_add( L_tot, L_shr( L_maxloc, 1 ) ); /* +max/8 */ -#endif } /* Find the number of right shifts to do on y32[] so that */ diff --git a/lib_enc/decision_matrix_enc.c b/lib_enc/decision_matrix_enc.c deleted file mode 100644 index 34d9fd39d4606f13573a7956c1a6b9ae26a016f5..0000000000000000000000000000000000000000 --- a/lib_enc/decision_matrix_enc.c +++ /dev/null @@ -1,45 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include -#include "options.h" -#include "prot.h" -#include "prot_fx_enc.h" -#include "stat_enc.h" -#include "stat_dec.h" -#include "rom_com.h" -#include "wmc_auto.h" diff --git a/lib_enc/decision_matrix_enc_fx.c b/lib_enc/decision_matrix_enc_fx.c index 2ebb7289a2196a79839f2a2021cec8d13b32f608..3624cf37463b4f56b24b40fb5660b567a406ced2 100644 --- a/lib_enc/decision_matrix_enc_fx.c +++ b/lib_enc/decision_matrix_enc_fx.c @@ -386,6 +386,21 @@ void decision_matrix_enc_fx( move16(); } +#ifdef NONBE_FIX_GSC_BSTR + /*-----------------------------------------------------------------* + * set inactive coder_type flag in ACELP core + *-----------------------------------------------------------------*/ + + st_fx->inactive_coder_type_flag = 0; /* AVQ by default */ + move16(); + + if ( LE_32( st_fx->total_brate, MAX_GSC_INACTIVE_BRATE ) ) + { + st_fx->inactive_coder_type_flag = 1; /* GSC */ + move16(); + } + +#endif return; } diff --git a/lib_enc/detect_transient.c b/lib_enc/detect_transient.c deleted file mode 100644 index 4922b9e4cac63a8b7e0bad323eeb65ac2b6706ba..0000000000000000000000000000000000000000 --- a/lib_enc/detect_transient.c +++ /dev/null @@ -1,42 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include "prot.h" -#include "cnst.h" -#include "rom_com.h" -#include "wmc_auto.h" diff --git a/lib_enc/detect_transient_fx.c b/lib_enc/detect_transient_fx.c index c4dbc6fe71357024ffcb49b4659f0b10cee8c14c..51f1cb47692fb74518524ee8f876adfb4082a58e 100644 --- a/lib_enc/detect_transient_fx.c +++ b/lib_enc/detect_transient_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other @@ -69,30 +69,15 @@ static void hp_filter_fx( /*y[0] = 0.4931f * *oldy + 0.7466f*(x[0] - *oldx); */ -#ifdef BASOP_NOGLOB L_tmp = L_mult( sub_o( x[0], *oldx, &Overflow ), 24465 /*0.7466f in Q15*/ ); /*Q_new+16 */ -#else /* BASOP_NOGLOB */ - L_tmp = L_mult( sub( x[0], *oldx ), 24465 ); /*Q_new+16 */ -#endif /* BASOP_NOGLOB */ -#ifdef BASOP_NOGLOB - L_tmp = L_mac_sat( L_tmp, *oldy, 16158 /*0.4931f in Q15*/ ); /*Q_new+16 */ - y[0] = round_fx_sat( L_tmp ); /*Q_new */ -#else - L_tmp = L_mac( L_tmp, *oldy, 16158 ); /*Q_new+16 */ - y[0] = round_fx( L_tmp ); /*Q_new */ -#endif + L_tmp = L_mac_sat( L_tmp, *oldy, 16158 /*0.4931f in Q15*/ ); /*Q_new+16 */ + y[0] = round_fx_sat( L_tmp ); /*Q_new */ FOR( i = 1; i < L; i++ ) { /*y[i] = 0.4931f*y[i-1] + 0.7466f*(x[i] - x[i-1]); */ -#ifdef BASOP_NOGLOB L_tmp = L_mult( sub_o( x[i], x[i - 1], &Overflow ), 24465 /*0.7466f in Q15*/ ); /*Q_new+16 */ L_tmp = L_mac_o( L_tmp, y[i - 1], 16158 /*0.4931f in Q15*/, &Overflow ); /*Q_new+16 */ y[i] = round_fx_o( L_tmp, &Overflow ); /*Q_new */ -#else /* BASOP_NOGLOB */ - L_tmp = L_mult( sub( x[i], x[i - 1] ), 24465 ); /*Q_new+16 */ - L_tmp = L_mac( L_tmp, y[i - 1], 16158 ); /*Q_new+16 */ - y[i] = round_fx( L_tmp ); /*Q_new */ -#endif /* BASOP_NOGLOB */ } *oldx = x[L - 1]; @@ -166,11 +151,7 @@ Word16 detect_transient_fx( FOR( i = 0; i < L / 4; i++ ) { /*EnergyLT += out_filt[i] * out_filt[i]; */ -#ifdef BASOP_NOGLOB EnergyLT = L_mac0_o( EnergyLT, out_filt_fx[i], out_filt_fx[i], &Overflow ); /*2Q_new */ -#else - EnergyLT = L_mac0( EnergyLT, out_filt_fx[i], out_filt_fx[i] ); /*2Q_new */ -#endif } } ELSE @@ -189,27 +170,14 @@ Word16 detect_transient_fx( FOR( i = 0; i < L / 4; i++ ) { temp16 = extract_l( L_shr( out_filt_fx[i + blk * ( L / 4 )], 12 ) ); -#ifdef BASOP_NOGLOB Energy_fx = L_add_o( Energy_fx, L_mult0( temp16, temp16 ), &Overflow ); -#else - Energy_fx = L_add( Energy_fx, L_mult0( temp16, temp16 ) ); -#endif - temp16 = shr( in_fx[i + blk * ( L / 4 )], Q_new ); /*Q0*/ -#ifdef BASOP_NOGLOB + temp16 = shr( in_fx[i + blk * ( L / 4 )], Q_new ); /*Q0*/ Energy_in_fx[blk + 1] = L_add_o( Energy_in_fx[blk + 1], L_mult0( temp16, temp16 ), &Overflow ); /*Q0*/ -#else - Energy_in_fx[blk + 1] = L_add( Energy_in_fx[blk + 1], L_mult0( temp16, temp16 ) ); -#endif move32(); } -#ifdef BASOP_NOGLOB E_in_fx = L_add_o( E_in_fx, Energy_in_fx[blk + 1], &Overflow ); /*Q0*/ E_out_fx = L_add_o( E_out_fx, Energy_fx, &Overflow ); /*Q0*/ -#else - E_in_fx = L_add( E_in_fx, Energy_in_fx[blk + 1] ); - E_out_fx = L_add( E_out_fx, Energy_fx ); -#endif Thres_fx = 2185; /*1 /15 Q15*/ move16(); @@ -233,29 +201,17 @@ Word16 detect_transient_fx( FOR( i = 0; i < L / 8; i++ ) { /*Energy += out_filt_fx[i + blk*(L/4)] * out_filt_fx[i + blk*(L/4)]; */ -#ifdef BASOP_NOGLOB L_tmp = L_mac0_o( L_tmp, out_filt_fx[i + blk * ( L / 4 )], out_filt_fx[i + blk * ( L / 4 )], &Overflow ); /*2Q_new */ -#else - L_tmp = L_mac0( L_tmp, out_filt_fx[i + blk * ( L / 4 )], out_filt_fx[i + blk * ( L / 4 )] ); /*2Q_new */ -#endif } L_tmp2 = L_deposit_l( 0 ); FOR( ; i < L / 4; i++ ) { /*Energy += out_filt_fx[i + blk*(L/4)] * out_filt_fx[i + blk*(L/4)]; */ -#ifdef BASOP_NOGLOB L_tmp2 = L_mac0_o( L_tmp2, out_filt_fx[i + blk * ( L / 4 )], out_filt_fx[i + blk * ( L / 4 )], &Overflow ); /*2Q_new */ -#else - L_tmp2 = L_mac0( L_tmp2, out_filt_fx[i + blk * ( L / 4 )], out_filt_fx[i + blk * ( L / 4 )] ); /*2Q_new */ -#endif } Overflow = 0; move16(); -#ifdef BASOP_NOGLOB /* Critical Overflow */ Energy = L_add_o( L_tmp, L_tmp2, &Overflow ); /*2Q_new */ -#else - Energy = L_add( L_tmp, L_tmp2 ); -#endif shift = 0; if ( Overflow != 0 ) { @@ -265,11 +221,7 @@ Word16 detect_transient_fx( Overflow = 0; move16(); -#ifdef BASOP_NOGLOB /* shift is >= 0, not overflow possible for shr */ Energy = L_add_o( L_shr( L_tmp, shift ), L_shr( L_tmp2, shift ), &Overflow ); /*2Q_new - shift*/ -#else - Energy = L_add( L_shr( L_tmp, shift ), L_shr( L_tmp2, shift ) ); -#endif test(); IF( EQ_16( st_fx->extl, SWB_BWE ) || EQ_16( st_fx->extl, FB_BWE ) ) { @@ -310,11 +262,7 @@ Word16 detect_transient_fx( } /*EnergyLT = 0.75f*EnergyLT + 0.25f*Energy; */ /*0.75f*EnergyLT in Q0 //0.25f*Energy in Q0 */ -#ifdef BASOP_NOGLOB EnergyLT = L_add_o( Mult_32_16( EnergyLT, 24576 /*0.75f in Q15*/ ), Mult_32_16( Energy, shl( 8192 /*0.25 in Q15*/, shift ) ), &Overflow ); /*2Q_new */ -#else /* BASOP_NOGLOB */ - EnergyLT = L_add( Mult_32_16( EnergyLT, 24576 ), Mult_32_16( Energy, shl( 8192, shift ) ) ); /*2Q_new */ -#endif } } st_fx->EnergyLT_fx = EnergyLT; @@ -342,11 +290,7 @@ Word16 detect_transient_fx( { /*blk++; */ blk = add( blk, 1 ); -#ifdef BASOP_NOGLOB E_low_fx = L_add_sat( E_low_fx, Energy_in_fx[i] ); /*Q0*/ -#else - E_low_fx = L_add( E_low_fx, Energy_in_fx[i] ); -#endif } exp = norm_s( blk ); @@ -362,11 +306,7 @@ Word16 detect_transient_fx( { /*blk++; */ blk = add( blk, 1 ); -#ifdef BASOP_NOGLOB E_high_fx = L_add_sat( E_high_fx, Energy_in_fx[i] ); /*Q0*/ -#else - E_high_fx = L_add( E_high_fx, Energy_in_fx[i] ); -#endif } exp = norm_s( blk ); diff --git a/lib_enc/diffcod.c b/lib_enc/diffcod.c deleted file mode 100644 index 3c07227e236a7fc455636c9c30dba4bdae0b83d8..0000000000000000000000000000000000000000 --- a/lib_enc/diffcod.c +++ /dev/null @@ -1,149 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include "prot.h" -#include "rom_com.h" -#include "wmc_auto.h" - -/*--------------------------------------------------------------------------*/ -/* Function diffcod() */ -/* */ -/* Differential coding for indices of quantized norms */ -/*--------------------------------------------------------------------------*/ - -void diffcod( - const int16_t N, /* i : number of sub-vectors */ - int16_t *y, /* i/o: indices of quantized norms */ - int16_t *difidx /* o : differential code */ -) -{ - int16_t i, k, r; - - for ( i = N - 1; i > 0; i-- ) - { - r = i - 1; - k = y[i] - y[r]; - if ( k < ( -15 ) ) - { - y[r] = y[i] + 15; - } - } - - for ( i = 1; i < N; i++ ) - { - r = i - 1; - k = y[i] - y[r]; - if ( k > 16 ) - { - k = 16; - y[i] = y[r] + 16; - } - difidx[r] = k + 15; - } - - return; -} - - -/*-------------------------------------------------------------------------- - * diffcod_lrmdct() - * - * Differential coding for indices of quantized norms - *--------------------------------------------------------------------------*/ - -void diffcod_lrmdct( - const int16_t N, /* i : number of sub-vectors */ - const int16_t be_ref, /* i : band energy reference */ - int16_t *y, /* i/o: indices of quantized norms */ - int16_t *difidx, /* o : differential code */ - const int16_t is_transient /* i : transient flag */ -) -{ - int16_t i, m, r; - int16_t k; - int16_t thr_l, thr_h; - - if ( is_transient ) - { - thr_l = -15; - thr_h = 16; - } - else - { - thr_l = -32; - thr_h = 31; - } - - difidx[0] = y[0] - be_ref; - if ( difidx[0] > thr_h ) - { - difidx[0] = thr_h; - y[0] = be_ref + thr_h; - } - - if ( difidx[0] < thr_l ) - { - difidx[0] = thr_l; - y[0] = be_ref + thr_l; - } - - m = N - 1; - for ( i = m; i > 0; i-- ) - { - r = i - 1; - k = y[i] - y[r]; - if ( k < thr_l ) - { - y[r] = y[i] - thr_l; - } - } - - for ( i = 1; i < N; i++ ) - { - r = i - 1; - k = y[i] - y[r]; - if ( k > thr_h ) - { - k = thr_h; - y[i] = y[r] + thr_h; - } - difidx[i] = k; - } - - return; -} diff --git a/lib_enc/dtx.c b/lib_enc/dtx.c deleted file mode 100644 index fd519a119104aa9247c536bd421877d8753ce465..0000000000000000000000000000000000000000 --- a/lib_enc/dtx.c +++ /dev/null @@ -1,45 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include -#include "options.h" -#include -#include "cnst.h" -#include "prot.h" -#include "ivas_prot.h" -#include "rom_com.h" -#include "wmc_auto.h" diff --git a/lib_enc/dtx_fx.c b/lib_enc/dtx_fx.c index a8978c49717a631fe207a39ac9cbf7eab95126b6..154b43c124b83fe0394d7662fdad731a8d288d5c 100644 --- a/lib_enc/dtx_fx.c +++ b/lib_enc/dtx_fx.c @@ -10,7 +10,6 @@ #include #include "prot_fx.h" /* Function prototypes */ #include "prot_fx_enc.h" /* Function prototypes */ -#include "prot.h" /*-------------------------------------------------------------------* * Local constants @@ -30,12 +29,12 @@ #define CNG_TYPE_HO 20 /* hangover for switching between CNG types */ -/* _DIFF_FLOAT_FIX_ : lp_noise_fx threshold is different between float (15) and fix (5*256) */ -#define LP_NOISE_LV 5 /* LP_NOISE level */ - +#ifndef NONBE_FIX_1277_EVS_DTX_HIGH_RATE_THRESHOLD +#define DTX_THR 5 /* LP_NOISE level */ +#endif #define MAX_BRATE_DTX_EVS ACELP_24k40 /* maximum bitrate to which the default DTX is applied in EVS; otherwise DTX is applied only in silence */ -#define MAX_BRATE_DTX_IVAS IVAS_64k /* maximum bitrate to which the default DTX is applied in IVAS; otherwise DTX is applied only in silence */ +#define MAX_BRATE_DTX_IVAS IVAS_80k /* maximum bitrate to which the default DTX is applied in IVAS; otherwise DTX is applied only in silence */ /*-------------------------------------------------------------------* * Local function prototypes @@ -64,7 +63,10 @@ static void update_SID_cnt_fx( DTX_ENC_HANDLE hDtxEnc, const Word32 core_brate, /* _ None */ /*==================================================================================*/ void dtx_ivas_fx( - Encoder_State *st_fx, /* i/o: encoder state structure */ + Encoder_State *st_fx, /* i/o: encoder state structure */ +#ifdef NONBE_1211_DTX_BR_SWITCHING + const Word32 last_ivas_total_brate, /* i : last IVAS total bitrate Q0*/ +#endif const Word32 ivas_total_brate, /* i : IVAS total bitrate Q0*/ const Word16 vad, /* i : vad flag for DTX Q0*/ const Word16 speech[], /* i : Pointer to the speech frame Q_speech*/ @@ -81,31 +83,46 @@ void dtx_ivas_fx( Flag Overflow = 0; move32(); #endif +#ifdef NONBE_1211_DTX_BR_SWITCHING + Word32 total_brate_ref; + + total_brate_ref = st_fx->total_brate; + move32(); +#endif IF( st_fx->dtx_sce_sba != 0 ) { last_br_cng_flag = 1; last_br_flag = 1; +#ifndef NONBE_1211_DTX_BR_SWITCHING br_dtx_flag = 1; move16(); +#endif move16(); move16(); } ELSE { - /* _DIFF_FLOAT_FIX_ : lp_noise_fx threshold is different between float (15) and fix (5*256) */ test(); test(); test(); - last_br_cng_flag = LE_32( st_fx->last_total_brate_cng, ACELP_24k40 ) || LT_16( st_fx->lp_noise_fx, LP_NOISE_LV * 256 ) || ( EQ_16( st_fx->element_mode, IVAS_SCE ) && LE_32( st_fx->last_total_brate_cng, ACELP_32k ) ); + last_br_cng_flag = LE_32( st_fx->last_total_brate_cng, MAX_BRATE_DTX_EVS ) || LT_16( st_fx->lp_noise_fx, DTX_THR * 256 ) || ( EQ_16( st_fx->element_mode, IVAS_SCE ) && LE_32( st_fx->last_total_brate_cng, MAX_BRATE_DTX_IVAS ) ); test(); test(); test(); - last_br_flag = LE_32( st_fx->last_total_brate, ACELP_24k40 ) || LT_16( st_fx->lp_noise_fx, LP_NOISE_LV * 256 ) || ( EQ_16( st_fx->element_mode, IVAS_SCE ) && LE_32( st_fx->last_total_brate, ACELP_32k ) ); + +#ifdef NONBE_1211_DTX_BR_SWITCHING + last_br_flag = ( st_fx->element_mode == EVS_MONO && LE_32( st_fx->last_total_brate, MAX_BRATE_DTX_EVS ) ) || + ( st_fx->element_mode != EVS_MONO && LE_32( last_ivas_total_brate, MAX_BRATE_DTX_IVAS ) ) || + LT_16( st_fx->lp_noise_fx, DTX_THR * 256 ); +#else + last_br_flag = LE_32( st_fx->last_total_brate, MAX_BRATE_DTX_EVS ) || LT_16( st_fx->lp_noise_fx, DTX_THR * 256 ) || ( EQ_16( st_fx->element_mode, IVAS_SCE ) && LE_32( st_fx->last_total_brate, MAX_BRATE_DTX_IVAS ) ); br_dtx_flag = 0; move16(); +#endif } + /* Initialization */ IF( st_fx->ini_frame == 0 ) { @@ -117,7 +134,7 @@ void dtx_ivas_fx( test(); test(); test(); - if ( ( EQ_16( st_fx->codec_mode, MODE1 ) || st_fx->Opt_AMR_WB ) && EQ_16( st_fx->element_mode, IVAS_SCE ) && EQ_16( st_fx->element_mode, IVAS_CPE_MDCT ) ) + if ( ( EQ_16( st_fx->codec_mode, MODE1 ) || st_fx->Opt_AMR_WB ) && NE_16( st_fx->element_mode, IVAS_SCE ) && NE_16( st_fx->element_mode, IVAS_CPE_MDCT ) ) { st_fx->cng_type = LP_CNG; move16(); @@ -199,6 +216,12 @@ void dtx_ivas_fx( /*------------------------------------------------------------------------* * Select SID or FRAME_NO_DATA frame if DTX is enabled *------------------------------------------------------------------------*/ + +#ifdef NONBE_1211_DTX_BR_SWITCHING + br_dtx_flag = 1; + move16(); +#endif + IF( st_fx->dtx_sce_sba == 0 ) { test(); @@ -207,7 +230,11 @@ void dtx_ivas_fx( test(); br_dtx_flag = ( ( st_fx->element_mode == EVS_MONO ) && LE_32( st_fx->total_brate, MAX_BRATE_DTX_EVS ) ) || ( ( st_fx->element_mode != EVS_MONO ) && LE_32( ivas_total_brate, MAX_BRATE_DTX_IVAS ) ) || +#ifdef NONBE_FIX_1277_EVS_DTX_HIGH_RATE_THRESHOLD + LT_16( st_fx->lp_noise_fx, DTX_THR * 256 ); +#else LT_16( st_fx->lp_noise_fx, 3840 /*15 in Q8*/ ); +#endif } test(); test(); @@ -226,8 +253,6 @@ void dtx_ivas_fx( { st_fx->last_total_brate_cng = -1; move16(); - st_fx->last_rf_mode_cng = st_fx->rf_mode; - move16(); } ELSE { @@ -237,6 +262,8 @@ void dtx_ivas_fx( move16(); st_fx->last_codec_mode_cng = st_fx->codec_mode; move16(); + st_fx->last_rf_mode_cng = st_fx->rf_mode; + move16(); } IF( hDtxEnc->cnt_SID == 0 ) @@ -293,7 +320,7 @@ void dtx_ivas_fx( test(); test(); test(); - IF( ( EQ_16( st_fx->cng_type, FD_CNG ) && ( LE_32( st_fx->total_brate, ACELP_24k40 ) || ( ( st_fx->element_mode != EVS_MONO ) && LE_32( st_fx->total_brate, ACELP_32k ) ) ) ) || ( EQ_16( st_fx->element_mode, IVAS_CPE_MDCT ) ) ) /* at highest bitrates, use exclusively LP_CNG */ + IF( ( EQ_16( st_fx->cng_type, FD_CNG ) && ( LE_32( st_fx->total_brate, MAX_BRATE_DTX_EVS ) || ( ( st_fx->element_mode != EVS_MONO ) && LE_32( ivas_total_brate, MAX_BRATE_DTX_IVAS ) ) ) ) || ( EQ_16( st_fx->element_mode, IVAS_CPE_MDCT ) ) ) /* at highest bitrates, use exclusively LP_CNG */ { test(); test(); @@ -322,9 +349,16 @@ void dtx_ivas_fx( IF( NE_16( st_fx->element_mode, IVAS_CPE_MDCT ) && st_fx->hBstr != NULL ) { - reset_indices_enc( st_fx->hBstr, st_fx->hBstr->nb_ind_tot ); + reset_indices_enc_fx( st_fx->hBstr, st_fx->hBstr->nb_ind_tot ); } } +#ifdef NONBE_1211_DTX_BR_SWITCHING + ELSE IF( st_fx->element_mode != EVS_MONO ) + { + st_fx->total_brate = total_brate_ref; + move32(); + } +#endif /*------------------------------------------------------------------------* * Reset counters when in active frame (not in SID or FRAME_NO_DATA frame) @@ -452,11 +486,7 @@ void dtx_ivas_fx( speech++; FOR( i = 1; i < L_FRAME / 16; i++ ) { -#ifdef BASOP_NOGLOB L_tmp = L_mac0_o( L_tmp, *speech, *speech, &Overflow ); /*2*Q_speech*/ -#else /* BASOP_NOGLOB */ - L_tmp = L_mac0( L_tmp, *speech, *speech ); -#endif /* BASOP_NOGLOB */ speech++; } hDtxEnc->frame_ener_fx = L_add( hDtxEnc->frame_ener_fx, L_shr( L_tmp, Q_speech2 ) ); /* Q(-7) */ @@ -631,11 +661,7 @@ void dtx_fx( move32(); #endif -#ifdef IVAS_CODE IF( st_fx->dtx_sce_sba != 0 ) -#else - if ( 0 ) -#endif { last_br_cng_flag = 1; last_br_flag = 1; @@ -646,10 +672,9 @@ void dtx_fx( } ELSE { - /* _DIFF_FLOAT_FIX_ : lp_noise_fx threshold is different between float (15) and fix (5*256) */ - last_br_cng_flag = LE_32( st_fx->last_total_brate_cng, ACELP_24k40 ) || LT_16( st_fx->lp_noise_fx, LP_NOISE_LV * 256 ) || ( EQ_16( st_fx->element_mode, IVAS_SCE ) && LE_32( st_fx->last_total_brate_cng, ACELP_32k ) ); + last_br_cng_flag = LE_32( st_fx->last_total_brate_cng, ACELP_24k40 ) || LT_16( st_fx->lp_noise_fx, DTX_THR * 256 ) || ( EQ_16( st_fx->element_mode, IVAS_SCE ) && LE_32( st_fx->last_total_brate_cng, ACELP_32k ) ); - last_br_flag = LE_32( st_fx->last_total_brate, ACELP_24k40 ) || LT_16( st_fx->lp_noise_fx, LP_NOISE_LV * 256 ) || ( EQ_16( st_fx->element_mode, IVAS_SCE ) && LE_32( st_fx->last_total_brate, ACELP_32k ) ); + last_br_flag = LE_32( st_fx->last_total_brate, ACELP_24k40 ) || LT_16( st_fx->lp_noise_fx, DTX_THR * 256 ) || ( EQ_16( st_fx->element_mode, IVAS_SCE ) && LE_32( st_fx->last_total_brate, ACELP_32k ) ); br_dtx_flag = 0; move16(); } @@ -740,12 +765,11 @@ void dtx_fx( /*------------------------------------------------------------------------* * Select SID or FRAME_NO_DATA frame if DTX is enabled *------------------------------------------------------------------------*/ -#ifdef IVAS_CODE + if ( st_fx->dtx_sce_sba == 0 ) -#endif { - br_dtx_flag = LE_32( st_fx->total_brate, ACELP_24k40 ) || LT_16( st_fx->lp_noise_fx, LP_NOISE_LV * 256 ) || ( EQ_16( st_fx->element_mode, IVAS_SCE ) && LE_32( st_fx->total_brate, ACELP_32k ) ) || - EQ_16( st_fx->element_mode, IVAS_CPE_DFT ) || ( EQ_16( st_fx->element_mode, IVAS_CPE_MDCT ) && ( LE_32( st_fx->element_brate, IVAS_64k ) || LT_16( st_fx->lp_noise_fx, LP_NOISE_LV * 256 ) ) ); + br_dtx_flag = LE_32( st_fx->total_brate, ACELP_24k40 ) || LT_16( st_fx->lp_noise_fx, DTX_THR * 256 ) || ( EQ_16( st_fx->element_mode, IVAS_SCE ) && LE_32( st_fx->total_brate, ACELP_32k ) ) || + EQ_16( st_fx->element_mode, IVAS_CPE_DFT ) || ( EQ_16( st_fx->element_mode, IVAS_CPE_MDCT ) && ( LE_32( st_fx->element_brate, IVAS_64k ) || LT_16( st_fx->lp_noise_fx, DTX_THR * 256 ) ) ); } test(); test(); @@ -806,20 +830,7 @@ void dtx_fx( st_fx->core_brate = SID_2k40; move32(); } - // PMT("dtx_sce_sba code is missing") -#ifdef IVAS_CODE - IF( ( NE_16( st_fx->last_core, ACELP_CORE ) || EQ_16( st_fx->cng_type, FD_CNG ) ) && EQ_16( st_fx->dtx_sce_sba, 1 ) ) - { - st_fx->cng_type = FD_CNG; - move16(); - if ( EQ_16( st_fx->element_mode, EVS_MONO ) && ( EQ_32( st_fx->total_brate, ACELP_9k60 ) || EQ_32( st_fx->total_brate, ACELP_16k40 ) || EQ_32( st_fx->total_brate, ACELP_24k40 ) || EQ_32( st_fx->total_brate, ACELP_48k ) || EQ_32( st_fx->total_brate, HQ_96k ) || EQ_32( st_fx->total_brate, HQ_128k ) ) ) - { - st_fx->codec_mode = MODE2; - move16(); - } - } - ELSE -#endif + { test(); test(); @@ -849,17 +860,11 @@ void dtx_fx( } } -#if 1 // def IVAS_CODE /* reset the bitstream (IVAS format signalling was already written) */ IF( NE_16( st_fx->element_mode, IVAS_CPE_MDCT ) && st_fx->hBstr != NULL ) { -#ifndef IVAS_CODE_BITSTREAM - reset_indices_enc_fx( st_fx->hBstr ); -#else - reset_indices_enc( st_fx->hBstr, st_fx->hBstr->nb_ind_tot ); -#endif + reset_indices_enc_fx( st_fx->hBstr, MAX_NUM_INDICES ); } -#endif } /*------------------------------------------------------------------------* @@ -902,32 +907,6 @@ void dtx_fx( { IF( EQ_16( st_fx->element_mode, IVAS_SCE ) ) { -#ifdef IVAS_CODE - Word16 lp_thresh, fd_thresh; - PMT( "lp_thresh scaling is to be found" ) - test(); - IF( st_fx->Opt_DTX_ON && EQ_16( st_fx->dtx_sce_sba, 1 ) ) - { - lp_thresh = 5.f; - fd_thresh = 2.f; - } - ELSE - - { - lp_thresh = 10.f; - fd_thresh = 5.f; - } - - /*More conservative selection of LP-CNG for SCE*/ - if ( st->cng_type == LP_CNG && ( st->bckr_tilt_lt > lp_thresh ) ) - { - st->cng_type = FD_CNG; - } - else if ( st->cng_type == FD_CNG && ( st->bckr_tilt_lt < fd_thresh ) && ( st->lp_noise > 2.f ) ) - { - st->cng_type = LP_CNG; - } -#endif } ELSE { @@ -977,11 +956,7 @@ void dtx_fx( speech++; FOR( i = 1; i < L_FRAME / 16; i++ ) { -#ifdef BASOP_NOGLOB L_tmp = L_mac0_o( L_tmp, *speech, *speech, &Overflow ); /*2*Q_speech*/ -#else /* BASOP_NOGLOB */ - L_tmp = L_mac0( L_tmp, *speech, *speech ); -#endif /* BASOP_NOGLOB */ speech++; } hDtxEnc->frame_ener_fx = L_add( hDtxEnc->frame_ener_fx, L_shr( L_tmp, Q_speech2 ) ); /*Q(-7) */ @@ -1347,11 +1322,7 @@ void dtx_hangover_control_fx( } exp = norm_l( enr_est ); -#ifdef BASOP_NOGLOB fra = round_fx_sat( L_shl_sat( enr_est, exp ) ); /*Q6+exp-16*/ -#else - fra = round_fx( L_shl( enr_est, exp ) ); -#endif exp2 = norm_s( weights ); fra2 = shl( weights, exp2 ); /*Q15+exp2*/ exp = sub( sub( exp, 16 ), exp2 ); @@ -1461,11 +1432,7 @@ void dtx_hangover_control_fx( move16(); FOR( j = 0; j < m; j++ ) { -#ifdef BASOP_NOGLOB lsp_est[i] = add_o( lsp_est[i], tmp[j * M + i], &Overflow ); /*Q15 */ -#else /* BASOP_NOGLOB */ - lsp_est[i] = add( lsp_est[i], tmp[j * M + i] ); /*Q15 */ -#endif /* BASOP_NOGLOB */ } lsp_est[i] = sub( lsp_est[i], tmp[max_idx[0] * M + i] ); /*Q15 */ @@ -1481,20 +1448,12 @@ void dtx_hangover_control_fx( move16(); FOR( j = 0; j < m; j++ ) { -#ifdef BASOP_NOGLOB lsp_est[i] = add_o( lsp_est[i], tmp[j * M + i], &Overflow ); /*Q15 */ -#else - lsp_est[i] = add( lsp_est[i], tmp[j * M + i] ); /*Q15 */ -#endif } -#ifdef BASOP_NOGLOB lsp_est[i] = sub_o( lsp_est[i], add_o( tmp[max_idx[0] * M + i], tmp[max_idx[1] * M + i], &Overflow ), &Overflow ); /*Q15 */ -#else - lsp_est[i] = sub( lsp_est[i], add( tmp[max_idx[0] * M + i], tmp[max_idx[1] * M + i] ) ); /*Q15 */ -#endif - S_tmp = div_s( 1, sub( m, 2 ) ); /*Q15 */ - lsp_est[i] = mult_r( lsp_est[i], S_tmp ); /*Q15 */ + S_tmp = div_s( 1, sub( m, 2 ) ); /*Q15 */ + lsp_est[i] = mult_r( lsp_est[i], S_tmp ); /*Q15 */ } } @@ -1502,11 +1461,7 @@ void dtx_hangover_control_fx( move16(); FOR( i = 0; i < M; i++ ) { -#ifdef BASOP_NOGLOB Dlsp_n2e = add_o( Dlsp_n2e, abs_s( sub( lsp_new_fx[i], lsp_est[i] ) ), &Overflow ); /*Q15 */ -#else /* BASOP_NOGLOB */ - Dlsp_n2e = add( Dlsp_n2e, abs_s( sub( lsp_new_fx[i], lsp_est[i] ) ) ); /*Q15 */ -#endif /* BASOP_NOGLOB */ lsp_est[i] = add( mult_r( 26214, lsp_est[i] ), mult_r( 6554, lsp_new_fx[i] ) ); /*Q15 */ } @@ -1519,11 +1474,7 @@ void dtx_hangover_control_fx( FOR( i = 0; i < M; i++ ) { S_tmp = abs_s( sub( hDtxEnc->lspCNG_fx[i], lsp_est[i] ) ); /*Q15 */ -#ifdef BASOP_NOGLOB - Dlsp = add_o( Dlsp, S_tmp, &Overflow ); /*Q15 */ -#else /* BASOP_NOGLOB */ - Dlsp = add( Dlsp, S_tmp ); /*Q15 */ -#endif + Dlsp = add_o( Dlsp, S_tmp, &Overflow ); /*Q15 */ IF( GT_16( S_tmp, S_max ) ) { S_max = S_tmp; /*Q15 */ @@ -1628,11 +1579,6 @@ void td_cng_enc_init_fx( move16(); move16(); -#ifdef IVAS_CODE - hTdCngEnc->CNG_att_fx = 0; - hTdCngEnc->last_idx_ener_fx = 0; -#endif - hTdCngEnc->cng_buf_cnt = 0; diff --git a/lib_enc/enc_acelp.c b/lib_enc/enc_acelp.c deleted file mode 100644 index e1517cb69321e96a0bf5f99655fc3566320fe29d..0000000000000000000000000000000000000000 --- a/lib_enc/enc_acelp.c +++ /dev/null @@ -1,91 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - - -#include -#include -#include "options.h" -#include -#include "prot.h" -#include "rom_com.h" -#include "rom_enc.h" -#include "wmc_auto.h" - - -/* - * acelp_2pulse_search - * - * Parameters: - * nb_pos_ix I: nb of pos for pulse 1 (1..8) - * track_x I: track of pulse 1 - * track_y I: track of pulse 2 - * ps I/O: correlation of all fixed pulses - * alp I/O: energy of all fixed pulses - * ix O: position of pulse 1 - * iy O: position of pulse 2 - * dn I: corr. between target and h[] - * dn2 I: vector of selected positions - * cor_x I: corr. of pulse 1 with fixed pulses - * cor_y I: corr. of pulse 2 with fixed pulses - * rrixiy I: corr. of pulse 1 with pulse 2 - * - * Function: - * Find the best positions of 2 pulses in a subframe - * - * Returns: - * void - */ - - -/* - * E_ACELP_1pulse_search - * - * Parameters: - * track_x I: track of pulse 1 - * track_y I: track of pulse 2 - * ps I/O: correlation of all fixed pulses - * alp I/O: energy of all fixed pulses - * ix O: position of pulse 1 - * dn I: corr. between target and h[] - * cor_x I: corr. of pulse 1 with fixed pulses - * cor_y I: corr. of pulse 2 with fixed pulses - * - * Function: - * Find the best positions of 1 pulse in a subframe - * - * Returns: - * void - */ diff --git a/lib_enc/enc_acelp_fx.c b/lib_enc/enc_acelp_fx.c index ee57efffe3b2735dcd2abba7fb1da5d9d236c078..a509a7cd74346749a88061b9a841e5bbad9ac4cc 100644 --- a/lib_enc/enc_acelp_fx.c +++ b/lib_enc/enc_acelp_fx.c @@ -20,19 +20,19 @@ #define _1_ 0x2000 /*Q12*/ #define _1_Q9 0x200 -static void E_ACELP_codearithp_fx( const Word16 v[], UWord32 *n, UWord32 *ps, Word16 *p ); +static void E_ACELP_codearithp_fx( const Word16 v[] /*Q9*/, UWord32 *n /*Q0*/, UWord32 *ps /*Q0*/, Word16 *p /*Q0*/ ); -void E_ACELP_h_vec_corr1( Word16 h[], Word16 vec[], UWord8 track, Word16 sign[], Word16 ( *rrixix )[16], Word16 cor[], Word16 dn2_pos[], Word16 nb_pulse ); +void E_ACELP_h_vec_corr1_fx( Word16 h[] /*Qx*/, Word16 vec[] /*Qx*/, UWord8 track /*Q0*/, Word16 sign[] /*Q15*/, Word16 ( *rrixix )[16] /*Q9*/, Word16 cor[] /*Q9*/, Word16 dn2_pos[] /*Q0*/, Word16 nb_pulse /*Q0*/ ); -void E_ACELP_h_vec_corr2( Word16 h[], Word16 vec[], UWord8 track, Word16 sign[], Word16 ( *rrixix )[16], Word16 cor[] ); +void E_ACELP_h_vec_corr2_fx( Word16 h[] /*Qx*/, Word16 vec[] /*Qx*/, UWord8 track /*Q0*/, Word16 sign[] /*Q15*/, Word16 ( *rrixix )[16] /*Q9*/, Word16 cor[] /*Q9*/ ); -Word16 E_ACELP_xy1_corr( Word16 xn[], Word16 y1[], ACELP_CbkCorr *g_corr, Word16 norm_flag, Word16 L_subfr, Word16 exp_xn ); +Word16 E_ACELP_xy1_corr_fx( Word16 xn[] /*Q15-exp_xn*/, Word16 y1[] /*Q15-exp_xn*/, ACELP_CbkCorr *g_corr, Word16 norm_flag /*Q0*/, Word16 L_subfr /*Q0*/, Word16 exp_xn ); -void E_ACELP_codebook_target_update( Word16 *x, Word16 *x2, Word16 *y, Word16 gain, Word16 L_subfr ); +void E_ACELP_codebook_target_update_fx( Word16 *x /*Q_xn*/, Word16 *x2 /*Q_xn*/, Word16 *y /*Q_xn*/, Word16 gain /*Q14*/, Word16 L_subfr /*Q0*/ ); -void E_ACELP_vec_neg( Word16 h[], Word16 h_inv[], Word16 L_subfr ); +void E_ACELP_vec_neg_fx( Word16 h[] /*Qx*/, Word16 h_inv[] /*Qx*/, Word16 L_subfr /*Q0*/ ); -void E_ACELP_corrmatrix( Word16 h[], Word16 sign[], Word16 vec[], Word16 rrixix[4][16], Word16 rrixiy[4][256] ); +void E_ACELP_corrmatrix_fx( Word16 h[] /*Q12*/, Word16 sign[] /*Q0*/, Word16 vec[] /*Q15*/, Word16 rrixix[4][16] /*Q9*/, Word16 rrixiy[4][256] /*Q9*/ ); /* * E_ACELP_h_vec_corrx @@ -51,7 +51,7 @@ void E_ACELP_corrmatrix( Word16 h[], Word16 sign[], Word16 vec[], Word16 rrixix[ * Returns: * void */ -void E_ACELP_h_vec_corr1( Word16 h[], Word16 vec[], UWord8 track, Word16 sign[], Word16 ( *rrixix )[16], Word16 cor[], Word16 dn2_pos[], Word16 nb_pulse ) +void E_ACELP_h_vec_corr1_fx( Word16 h[] /*Qx*/, Word16 vec[] /*Qx*/, UWord8 track /*Q0*/, Word16 sign[] /*Q15*/, Word16 ( *rrixix )[16] /*Q9*/, Word16 cor[] /*Q9*/, Word16 dn2_pos[] /*Q0*/, Word16 nb_pulse /*Q0*/ ) { Word16 i, j; Word16 dn, corr; @@ -60,109 +60,79 @@ void E_ACELP_h_vec_corr1( Word16 h[], Word16 vec[], UWord8 track, Word16 sign[], Word32 L_sum; #ifdef BASOP_NOGLOB_DECLARE_LOCAL Flag Overflow = 0; + move32(); #endif - dn2 = &dn2_pos[shl( track, 3 )]; - p0 = rrixix[track]; + dn2 = &dn2_pos[( track * 8 )]; /*Q0*/ + p0 = rrixix[track]; /*Q9*/ FOR( i = 0; i < nb_pulse; i++ ) { - dn = dn2[i]; + dn = dn2[i]; /*Q0*/ move16(); L_sum = L_deposit_l( 0 ); - p1 = h; - p2 = &vec[dn]; + p1 = h; /*Qx*/ + p2 = &vec[dn]; /*Qx*/ FOR( j = dn; j < L_SUBFR - 1; j++ ) { -#ifdef BASOP_NOGLOB - L_sum = L_mac_o( L_sum, *p1++, *p2++, &Overflow ); -#else - L_sum = L_mac( L_sum, *p1++, *p2++ ); -#endif + L_sum = L_mac_o( L_sum, *p1++, *p2++, &Overflow ); /*2*Qx+1*/ } -#ifdef BASOP_NOGLOB corr = mac_ro( L_sum, *p1++, *p2++, &Overflow ); /*Q9*/ -#else /* BASOP_NOGLOB */ - corr = mac_r( L_sum, *p1++, *p2++ ); /*Q9*/ -#endif /* BASOP_NOGLOB */ /*cor[dn >> 2] = sign[dn] * s + p0[dn >> 2];*/ j = shr( dn, 2 ); if ( sign[dn] > 0 ) { -#ifdef BASOP_NOGLOB - corr = add_o( p0[j], corr, &Overflow ); -#else - corr = add( p0[j], corr ); -#endif + corr = add_o( p0[j], corr, &Overflow ); /*Q9*/ } if ( sign[dn] < 0 ) { -#ifdef BASOP_NOGLOB - corr = sub_o( p0[j], corr, &Overflow ); -#else /* BASOP_NOGLOB */ - corr = sub( p0[j], corr ); -#endif /* BASOP_NOGLOB */ + corr = sub_o( p0[j], corr, &Overflow ); /*Q9*/ } - cor[j] = corr; + cor[j] = corr; /*Q9*/ move16(); } return; } -void E_ACELP_h_vec_corr2( Word16 h[], Word16 vec[], UWord8 track, Word16 sign[], Word16 ( *rrixix )[16], Word16 cor[] ) +void E_ACELP_h_vec_corr2_fx( Word16 h[] /*Qx*/, Word16 vec[] /*Qx*/, UWord8 track /*Q0*/, Word16 sign[] /*Q15*/, Word16 ( *rrixix )[16] /*Q9*/, Word16 cor[] /*Q9*/ ) { Word16 i, j, pos, corr; Word16 *p0, *p1, *p2; Word32 L_sum; #ifdef BASOP_NOGLOB_DECLARE_LOCAL Flag Overflow = 0; + move32(); #endif - p0 = rrixix[track]; + p0 = rrixix[track]; /*Q9*/ - pos = track; + pos = track; /*Q0*/ move16(); FOR( i = 0; i < 16; i++ ) { L_sum = L_deposit_l( 0 ); - p1 = h; - p2 = &vec[pos]; + p1 = h; /*Qx*/ + p2 = &vec[pos]; /*Qx*/ FOR( j = pos; j < L_SUBFR - 1; j++ ) { -#ifdef BASOP_NOGLOB - L_sum = L_mac_o( L_sum, *p1++, *p2++, &Overflow ); -#else - L_sum = L_mac( L_sum, *p1++, *p2++ ); -#endif + L_sum = L_mac_o( L_sum, *p1++, *p2++, &Overflow ); /* 2*Qx+1 */ } -#ifdef BASOP_NOGLOB corr = mac_ro( L_sum, *p1++, *p2++, &Overflow ); /*Q9*/ -#else /* BASOP_NOGLOB */ - corr = mac_r( L_sum, *p1++, *p2++ ); /*Q9*/ -#endif /* BASOP_NOGLOB */ /*cor[i] = s * sign[track] + p0[i];*/ if ( sign[pos] > 0 ) { -#ifdef BASOP_NOGLOB - corr = add_o( *p0++, corr, &Overflow ); -#else - corr = add( *p0++, corr ); -#endif + corr = add_o( *p0++, corr, &Overflow ); /*Q9*/ } if ( sign[pos] < 0 ) { -#ifdef BASOP_NOGLOB - corr = sub_o( *p0++, corr, &Overflow ); -#else - corr = sub( *p0++, corr ); -#endif + corr = sub_o( *p0++, corr, &Overflow ); /*Q9*/ } - cor[i] = corr; + cor[i] = corr; /*Q9*/ move16(); pos = add( pos, 4 ); @@ -194,7 +164,7 @@ void E_ACELP_h_vec_corr2( Word16 h[], Word16 vec[], UWord8 track, Word16 sign[], * Returns: * void */ -static void E_ACELP_2pulse_search( Word16 nb_pos_ix, UWord8 track_x, UWord8 track_y, Word16 *ps, Word16 *alp, Word16 *ix, Word16 *iy, Word16 dn[], Word16 *dn2, Word16 cor_x[], Word16 cor_y[], Word16 ( *rrixiy )[256] ) +static void E_ACELP_2pulse_search( Word16 nb_pos_ix /*Q0*/, UWord8 track_x /*Q0*/, UWord8 track_y /*Q0*/, Word16 *ps /*Qdn*/, Word16 *alp /*Qx*/, Word16 *ix /*Q0*/, Word16 *iy /*Q0*/, Word16 dn[] /*Qdn*/, Word16 *dn2 /*Q0*/, Word16 cor_x[] /*Qx*/, Word16 cor_y[] /*Qx*/, Word16 ( *rrixiy )[256] /*Q9*/ ) { Word16 x, x2, y, i, *pos_x; Word16 ps0, ps1, alp2_16, ps2, sq; @@ -203,78 +173,68 @@ static void E_ACELP_2pulse_search( Word16 nb_pos_ix, UWord8 track_x, UWord8 trac Word16 sqk[2], alpk[2], ik; Word32 xy_save; Word16 check = 0; /* debug code not instrumented */ + #ifdef BASOP_NOGLOB_DECLARE_LOCAL Flag Overflow = 0; + move32(); #endif /* eight dn2 max positions per track */ /*pos_x = &dn2[track_x << 3]; SHIFT(1); PTR_INIT(1);*/ - pos_x = &dn2[shl( track_x, 3 )]; + pos_x = &dn2[( track_x * 8 )]; /*Qdn*/ move16(); /* save these to limit memory searches */ - alp0 = L_deposit_h( *alp ); - ps0 = *ps; + alp0 = L_deposit_h( *alp ); /*Qx-16*/ + ps0 = *ps; /*Qdn*/ move16(); alpk[0] = 1; move16(); sqk[0] = -1; move16(); - x2 = shr( pos_x[0], 2 ); -#ifdef BASOP_NOGLOB - if ( mac_ro( L_mac_o( L_mac_o( alp0, cor_x[x2], _1_, &Overflow ), cor_y[0], _1_, &Overflow ), rrixiy[track_x][shl( x2, 4 )], _1_, &Overflow ) < 0 ) -#else /* BASOP_NOGLOB */ - if ( mac_r( L_mac( L_mac( alp0, cor_x[x2], _1_ ), cor_y[0], _1_ ), rrixiy[track_x][shl( x2, 4 )], _1_ ) < 0 ) -#endif /* BASOP_NOGLOB */ + x2 = shr( pos_x[0], 2 ); /*Qdn*/ + if ( mac_ro( L_mac_o( L_mac_o( alp0, cor_x[x2], _1_, &Overflow ), cor_y[0], _1_, &Overflow ), rrixiy[track_x][( x2 * 16 )], _1_, &Overflow ) < 0 ) { sqk[0] = 1; move16(); } ik = 0; move16(); - xy_save = L_mac0( L_deposit_l( track_y ), track_x, L_SUBFR ); + xy_save = L_mac0( L_deposit_l( track_y ), track_x, L_SUBFR ); /*Q0*/ /* loop track 1 */ FOR( i = 0; i < nb_pos_ix; i++ ) { - x = pos_x[i]; + x = pos_x[i]; /*Qdn*/ move16(); x2 = shr( x, 2 ); /* dn[x] has only nb_pos_ix positions saved */ /*ps1 = ps0 + dn[x];*/ - ps1 = add( ps0, dn[x] ); + ps1 = add( ps0, dn[x] ); /*Qdn*/ /*alp1 = alp0 + cor_x[x2];*/ -#ifdef BASOP_NOGLOB alp1 = L_mac_o( alp0, cor_x[x2], _1_, &Overflow ); /*Q22*/ -#else /* BASOP_NOGLOB */ - alp1 = L_mac( alp0, cor_x[x2], _1_ ); /*Q22*/ -#endif /* BASOP_NOGLOB */ - p1 = cor_y; - p2 = &rrixiy[track_x][shl( x2, 4 )]; + p1 = cor_y; /*Qx*/ + p2 = &rrixiy[track_x][( x2 * 16 )]; /*Q9*/ FOR( y = track_y; y < L_SUBFR; y += 4 ) { /*ps2 = ps1 + dn[y];*/ - ps2 = add( ps1, dn[y] ); + ps2 = add( ps1, dn[y] ); /*Qdn*/ + move16(); /*alp2 = alp1 + (*p1++) + (*p2++);*/ -#ifdef BASOP_NOGLOB - alp2 = L_mac_o( alp1, *p1++, _1_, &Overflow ); + alp2 = L_mac_o( alp1, *p1++, _1_, &Overflow ); /*Qx+12+1*/ alp2_16 = mac_ro( alp2, *p2++, _1_, &Overflow ); /*Q6*/ -#else /* BASOP_NOGLOB */ - alp2 = L_mac( alp1, *p1++, _1_ ); - alp2_16 = mac_r( alp2, *p2++, _1_ ); /*Q6*/ -#endif /* BASOP_NOGLOB */ - alpk[1 - ik] = alp2_16; + alpk[1 - ik] = alp2_16; /*Q6*/ move16(); /*sq = ps2 * ps2;*/ - sq = mult( ps2, ps2 ); - sqk[1 - ik] = sq; + sq = mult( ps2, ps2 ); /*2*Qdn+1*/ + sqk[1 - ik] = sq; /*2*Qdn+1*/ move16(); /*s = (alpk[ik] * sq) - (sqk[0] * alp2);*/ @@ -283,28 +243,30 @@ static void E_ACELP_2pulse_search( Word16 nb_pos_ix, UWord8 track_x, UWord8 trac if ( s > 0 ) { ik = sub( 1, ik ); + move16(); check = 1; /* debug code not instrumented */ + move16(); } if ( s > 0 ) { - xy_save = L_mac0( y, x, L_SUBFR ); + xy_save = L_mac0( y, x, L_SUBFR ); /*Qdn*/ } } } assert( check ); /* debug code not instrumented */ - ps2 = extract_l( xy_save ); - *iy = s_and( ps2, L_SUBFR - 1 ); + ps2 = extract_l( xy_save ); /*Qdn*/ + *iy = s_and( ps2, L_SUBFR - 1 ); /*Q0*/ move16(); - *ix = lshr( ps2, 6 ); + *ix = lshr( ps2, 6 ); /*Q0*/ move16(); /**ps = ps0 + dn[*ix] + dn[*iy];*/ - *ps = add( ps0, add( dn[*ix], dn[*iy] ) ); + *ps = add( ps0, add( dn[*ix], dn[*iy] ) ); /*Qdn*/ move16(); - *alp = alpk[ik]; + *alp = alpk[ik]; /*Q6*/ move16(); return; } @@ -330,12 +292,12 @@ static void E_ACELP_2pulse_search( Word16 nb_pos_ix, UWord8 track_x, UWord8 trac * void */ static void E_ACELP_1pulse_search( UWord8 tracks[2], - Word16 *ps, - Word16 *alp, - Word16 *ix, - Word16 dn[], - Word16 cor_x[], - Word16 cor_y[] ) + Word16 *ps, /*Qdn*/ + Word16 *alp, /*Qx*/ + Word16 *ix, /*Q0*/ + Word16 dn[], /*Qdn*/ + Word16 cor_x[], /*Q6*/ + Word16 cor_y[] /*Q6*/ ) { Word16 x, x_save = 0; Word16 ps0; @@ -348,14 +310,14 @@ static void E_ACELP_1pulse_search( UWord8 tracks[2], /* save these to limit memory searches */ alp0 = L_deposit_h( *alp ); - ps0 = *ps; + ps0 = *ps; /*Qdn*/ move16(); alpk[0] = 1; move16(); sqk[0] = -1; move16(); - if ( mac_r_sat( alp0, cor_x[shr( tracks[0], 2 )], _1_ ) < 0 ) + if ( mac_r_sat( alp0, cor_x[( tracks[0] / 4 )], _1_ ) < 0 ) { sqk[0] = 1; move16(); @@ -364,6 +326,7 @@ static void E_ACELP_1pulse_search( UWord8 tracks[2], move16(); ntracks = 1; + move16(); if ( NE_16( tracks[1], tracks[0] ) ) { ntracks = 2; @@ -379,16 +342,16 @@ static void E_ACELP_1pulse_search( UWord8 tracks[2], FOR( x = tracks[t]; x < L_SUBFR; x += 4 ) { /*ps1 = ps0 + dn[x]; ADD(1);*/ - ps1 = add( ps0, dn[x] ); + ps1 = add( ps0, dn[x] ); /*Qdn*/ /*alp1 = alp0 + cor_x[x>>2]; SHIFT(1);ADD(1);*/ - alp1 = mac_r_sat( alp0, cor_x[shr( x, 2 )], _1_ ); /*Q6*/ - alpk[1 - ik] = alp1; + alp1 = mac_r_sat( alp0, cor_x[( x / 4 )], _1_ ); /*Q6*/ + alpk[1 - ik] = alp1; /*Q6*/ move16(); /*sq = ps1 * ps1; MULT(1);*/ - sq = mult( ps1, ps1 ); - sqk[1 - ik] = sq; + sq = mult( ps1, ps1 ); /*2*Qdn+1*/ + sqk[1 - ik] = sq; /*2*Qdn+1*/ move16(); /*s = (alpk * sq) - (sqk * alp1); MULT(1);MAC(1); */ @@ -408,11 +371,11 @@ static void E_ACELP_1pulse_search( UWord8 tracks[2], assert( check ); /* debug code not instrumented */ } - *ps = add( ps0, dn[x_save] ); + *ps = add( ps0, dn[x_save] ); /*2*Qdn+1*/ move16(); - *alp = alpk[ik]; + *alp = alpk[ik]; /*Q6*/ move16(); - *ix = x_save; + *ix = x_save; /*Q0*/ move16(); return; } @@ -437,7 +400,7 @@ static void E_ACELP_1pulse_search( UWord8 tracks[2], * Returns: * void */ -static void E_ACELP_xh_corr( Word16 *x, Word16 *y, Word16 *h, Word16 L_subfr ) +static void E_ACELP_xh_corr( Word16 *x /*Qx*/, Word16 *y /*Qy*/, Word16 *h /*Q12*/, Word16 L_subfr /*Q0*/ ) { Word16 i, j, k; Word32 L_tmp, y32[L_SUBFR16k], L_maxloc, L_tot; @@ -452,28 +415,23 @@ static void E_ACELP_xh_corr( Word16 *x, Word16 *y, Word16 *h, Word16 L_subfr ) L_maxloc = L_deposit_l( 0 ); FOR( i = k; i < L_subfr; i += 4 ) { - L_tmp = L_mac0( 1L, x[i], h[0] ); /* 1 -> to avoid null dn[] */ + L_tmp = L_mac0( 1L, x[i], h[0] ); /* 1 -> to avoid null dn[] Qx+Q12*/ FOR( j = i; j < L_subfr - 1; j++ ) { - L_tmp = L_mac0( L_tmp, x[j + 1], h[j + 1 - i] ); + L_tmp = L_mac0( L_tmp, x[j + 1], h[j + 1 - i] ); /*Qx+Q12*/ } - y32[i] = L_tmp; + y32[i] = L_tmp; /*Qx+Q12*/ move32(); - L_tmp = L_abs( L_tmp ); - L_maxloc = L_max( L_tmp, L_maxloc ); + L_tmp = L_abs( L_tmp ); /*Qx+Q12*/ + L_maxloc = L_max( L_tmp, L_maxloc ); /*Qx+Q12*/ } /* tot += 3*max / 8 */ L_maxloc = L_shr( L_maxloc, 2 ); /* Do not warn saturation of L_tot, since its for headroom estimation. */ BASOP_SATURATE_WARNING_OFF_EVS -#ifdef BASOP_NOGLOB L_tot = L_add_sat( L_tot, L_maxloc ); /* +max/4 */ L_tot = L_add_sat( L_tot, L_shr( L_maxloc, 1 ) ); /* +max/8 */ -#else - L_tot = L_add( L_tot, L_maxloc ); /* +max/4 */ - L_tot = L_add( L_tot, L_shr( L_maxloc, 1 ) ); /* +max/8 */ -#endif BASOP_SATURATE_WARNING_ON_EVS } @@ -482,7 +440,7 @@ static void E_ACELP_xh_corr( Word16 *x, Word16 *y, Word16 *h, Word16 L_subfr ) j = sub( norm_l( L_tot ), 4 + 16 ); /* 4 -> 16 x tot */ - Copy_Scale_sig_32_16( y32, y, L_subfr, j ); + Copy_Scale_sig_32_16( y32, y, L_subfr, j ); /*Qy = Qx+Q12+j*/ return; } @@ -494,7 +452,7 @@ static void E_ACELP_xh_corr( Word16 *x, Word16 *y, Word16 *h, Word16 L_subfr ) * \param bits amount of target headroom bits for y * \return exponent of y */ -Word16 E_ACELP_hh_corr( Word16 *x, Word16 *y, Word16 L_subfr, Word16 bits ) +Word16 E_ACELP_hh_corr( Word16 *x /*Q11*/, Word16 *y /*Qy*/, Word16 L_subfr /*Q0*/, Word16 bits /*Q0*/ ) { Word16 i, j, k = 0; /* initialize just to avoid compiler warning */ Word32 L_tmp, L_sum; @@ -504,21 +462,21 @@ Word16 E_ACELP_hh_corr( Word16 *x, Word16 *y, Word16 L_subfr, Word16 bits ) Word64 L_tmp_64; Word64 L_sum_64; - L_tmp_64 = W_mult0_16_16( x[i], x[0] ); + L_tmp_64 = W_mult0_16_16( x[i], x[0] ); /*Q22*/ FOR( j = i + 2; j < L_subfr; j += 2 ) { - L_tmp_64 = W_mac0_16_16( L_tmp_64, x[j], x[j - i] ); + L_tmp_64 = W_mac0_16_16( L_tmp_64, x[j], x[j - i] ); /*Q22*/ } L_sum_64 = L_tmp_64; move64(); - L_tmp_64 = W_mult0_16_16( x[i + 1], x[1] ); + L_tmp_64 = W_mult0_16_16( x[i + 1], x[1] ); /*Q22*/ FOR( j = i + 3; j < L_subfr; j += 2 ) { - L_tmp_64 = W_mac0_16_16( L_tmp_64, x[j], x[j - i] ); + L_tmp_64 = W_mac0_16_16( L_tmp_64, x[j], x[j - i] ); /*Q22*/ } L_sum_64 = W_add_nosat( W_shr( L_sum_64, 1 ), W_shr( L_tmp_64, 1 ) ); - L_sum = W_sat_l( L_sum_64 ); + L_sum = W_sat_l( L_sum_64 ); /*Q22*/ /* L_sum = L_shr( L_sum, 1 ); */ if ( i == 0 ) { @@ -529,12 +487,12 @@ Word16 E_ACELP_hh_corr( Word16 *x, Word16 *y, Word16 L_subfr, Word16 bits ) k = sub( k, bits ); } - y[i] = round_fx( L_shl( L_sum, k ) ); + y[i] = round_fx( L_shl( L_sum, k ) ); /*Q22+k-16*/ } - L_tmp = L_mult0( x[i], x[0] ); + L_tmp = L_mult0( x[i], x[0] ); /*Q22*/ L_sum = L_shr( L_tmp, 1 ); - y[i] = round_fx( L_shl( L_sum, k ) ); + y[i] = round_fx( L_shl( L_sum, k ) ); /*Qy = Q22+k-16*/ k = add( 1, k ); @@ -560,31 +518,24 @@ Word16 E_ACELP_hh_corr( Word16 *x, Word16 *y, Word16 L_subfr, Word16 bits ) * Returns: * pitch gain (0 ... 1.2F) (Q14) */ -Word16 E_ACELP_xy1_corr( Word16 xn[], Word16 y1[], ACELP_CbkCorr *g_corr, Word16 norm_flag, Word16 L_subfr, Word16 exp_xn ) +Word16 E_ACELP_xy1_corr_fx( Word16 xn[] /*Q15-exp_xn*/, Word16 y1[] /*Q15-exp_xn*/, ACELP_CbkCorr *g_corr, Word16 norm_flag /*Q0*/, Word16 L_subfr /*Q0*/, Word16 exp_xn ) { Word16 i, Q_xn; Word16 xy, yy, exp_xy, exp_yy, gain; Word32 L_off; #ifdef BASOP_NOGLOB_DECLARE_LOCAL Flag Overflow = 0; + move32(); #endif L_off = L_shr( 10737418l /*0.01f/2.0f Q31*/, s_min( add( exp_xn, exp_xn ), 31 ) ); L_off = L_max( 1, L_off ); /* ensure at least a '1' */ -#ifdef BASOP_NOGLOB /* Compute scalar product t1: */ - yy = round_fx_o( Dot_product15_offs( y1, y1, L_subfr, &exp_yy, L_off ), &Overflow ); + yy = round_fx_o( Dot_product15_offs( y1, y1, L_subfr, &exp_yy, L_off ), &Overflow ); /*Q15 - exp_yy*/ /* Compute scalar product t0: */ - xy = round_fx_o( Dot_product12_offs( xn, y1, L_subfr, &exp_xy, L_off ), &Overflow ); -#else - /* Compute scalar product t1: */ - yy = round_fx( Dot_product15_offs( y1, y1, L_subfr, &exp_yy, L_off ) ); - - /* Compute scalar product t0: */ - xy = round_fx( Dot_product12_offs( xn, y1, L_subfr, &exp_xy, L_off ) ); -#endif + xy = round_fx_o( Dot_product12_offs( xn, y1, L_subfr, &exp_xy, L_off ), &Overflow ); /*Q15 - exp_xy*/ /* Compute doubled format out of the exponent */ Q_xn = shl( sub( 15, exp_xn ), 1 ); g_corr->y1y1 = yy; @@ -606,23 +557,19 @@ Word16 E_ACELP_xy1_corr( Word16 xn[], Word16 y1[], ACELP_CbkCorr *g_corr, Word16 /* compute gain = xy/yy */ - xy = mult_r( xy, 0x4000 ); /* Be sure xy < yy */ - gain = div_s( xy, yy ); + xy = mult_r( xy, 0x4000 ); /* Be sure xy < yy Q15 - exp_xy*/ + gain = div_s( xy, yy ); /*Q14*/ i = add( exp_xy, 1 - 1 ); /* -1 -> gain in Q14 */ i = sub( i, exp_yy ); BASOP_SATURATE_WARNING_OFF_EVS -#ifdef BASOP_NOGLOB gain = shl_o( gain, i, &Overflow ); /* saturation can occur here */ -#else /* BASOP_NOGLOB */ - gain = shl( gain, i ); /* saturation can occur here */ -#endif /* BASOP_NOGLOB */ BASOP_SATURATE_WARNING_ON_EVS /* gain = s_max(0, gain); */ /* see above xy < 0. */ /* if (gain > 1.2) gain = 1.2 in Q14 */ - gain = s_min( 19661 /*1.2f Q14*/ /* 19661 */, gain ); + gain = s_min( 19661 /*1.2f Q14*/ /* 19661 */, gain ); /*Q14*/ /*Limit the energy of pitch contribution*/ IF( norm_flag ) @@ -630,28 +577,20 @@ Word16 E_ACELP_xy1_corr( Word16 xn[], Word16 y1[], ACELP_CbkCorr *g_corr, Word16 Word16 tmp, exp_tmp, exp_div; /* Compute scalar product */ -#ifdef BASOP_NOGLOB - tmp = round_fx_o( Dot_product12_offs( xn, xn, L_subfr, &exp_tmp, 1 ), &Overflow ); -#else - tmp = round_fx( Dot_product12_offs( xn, xn, L_subfr, &exp_tmp, 1 ) ); -#endif + tmp = round_fx_o( Dot_product12_offs( xn, xn, L_subfr, &exp_tmp, 1 ), &Overflow ); /*Q15 - exp_tmp*/ /* gain_p_snr = sqrt(/) */ tmp = BASOP_Util_Divide1616_Scale( tmp, yy, &exp_div ); exp_tmp = add( sub( exp_tmp, exp_yy ), exp_div ); - tmp = Sqrt16( tmp, &exp_tmp ); + tmp = Sqrt16( tmp, &exp_tmp ); /*Q15 - exp_tmp*/ /* Note: shl works as shl or shr. */ exp_tmp = sub( exp_tmp, 1 ); BASOP_SATURATE_WARNING_OFF_EVS -#ifdef BASOP_NOGLOB - tmp = round_fx_o( L_shl_o( Mpy_32_16_1( 1717986944l /*ACELP_GAINS_CONST Q31*/, tmp ), exp_tmp, &Overflow ), &Overflow ); -#else /* BASOP_NOGLOB */ - tmp = round_fx( L_shl( Mpy_32_16_1( 1717986944l /*ACELP_GAINS_CONST Q31*/, tmp ), exp_tmp ) ); -#endif /* BASOP_NOGLOB */ + tmp = round_fx_o( L_shl_o( Mpy_32_16_1( 1717986944l /*ACELP_GAINS_CONST Q31*/, tmp ), exp_tmp, &Overflow ), &Overflow ); /*Q14*/ BASOP_SATURATE_WARNING_ON_EVS - gain = s_min( gain, tmp ); + gain = s_min( gain, tmp ); /*Q14*/ } bail: @@ -679,7 +618,7 @@ bail: * Returns: * pitch gain (0 ... 1.2F) */ -void E_ACELP_xy2_corr( Word16 xn[], Word16 y1[], Word16 y2[], ACELP_CbkCorr *g_corr, Word16 L_subfr, Word16 exp_xn ) +void E_ACELP_xy2_corr( Word16 xn[] /*Q_xn*/, Word16 y1[] /*Q_xn*/, Word16 y2[] /*Q9*/, ACELP_CbkCorr *g_corr, Word16 L_subfr /*Q0*/, Word16 exp_xn ) { Word16 xny2, y2y2, y1y2, xx, exp_xny2, exp_y2y2, exp_y1y2, exp_xx; Word32 L_off; @@ -687,20 +626,20 @@ void E_ACELP_xy2_corr( Word16 xn[], Word16 y1[], Word16 y2[], ACELP_CbkCorr *g_c BASOP_SATURATE_ERROR_ON_EVS; /* Compute scalar product */ - y2y2 = extract_h( Dot_product15_offs( y2, y2, L_subfr, &exp_y2y2, 5243l /*0.01f Q19*/ ) ); + y2y2 = extract_h( Dot_product15_offs( y2, y2, L_subfr, &exp_y2y2, 5243l /*0.01f Q19*/ ) ); /*Q15-exp_y2y2*/ /* L_off = 1L; */ L_off = L_shr( 10737418l /*0.01f/2.0f Q31*/, sub( 30 - 9, exp_xn ) ); /* Compute scalar product */ - xny2 = extract_h( Dot_product12_offs( xn, y2, L_subfr, &exp_xny2, L_off ) ); + xny2 = extract_h( Dot_product12_offs( xn, y2, L_subfr, &exp_xny2, L_off ) ); /*Q15-exp_xny2*/ /* Compute scalar product */ - y1y2 = extract_h( Dot_product12_offs( y1, y2, L_subfr, &exp_y1y2, L_off ) ); + y1y2 = extract_h( Dot_product12_offs( y1, y2, L_subfr, &exp_y1y2, L_off ) ); /*Q15-exp_y1y2*/ /* Compute scalar product */ L_off = L_shr( 21474836l /*0.01f Q31*/, s_min( 31, sub( 30, shl( exp_xn, 1 ) ) ) ); - xx = extract_h( Dot_product12_offs( xn, xn, L_subfr, &exp_xx, L_off ) ); + xx = extract_h( Dot_product12_offs( xn, xn, L_subfr, &exp_xx, L_off ) ); /*Q15-exp_xx*/ g_corr->y2y2 = y2y2; @@ -741,12 +680,13 @@ void E_ACELP_xy2_corr( Word16 xn[], Word16 y1[], Word16 y2[], ACELP_CbkCorr *g_c * Returns: * void */ -void E_ACELP_codebook_target_update( Word16 *x, Word16 *x2, Word16 *y, Word16 gain, Word16 L_subfr ) +void E_ACELP_codebook_target_update_fx( Word16 *x /*Q_xn*/, Word16 *x2 /*Q_xn*/, Word16 *y /*Q_xn*/, Word16 gain /*Q14*/, Word16 L_subfr /*Q0*/ ) { Word16 i, Q15_flag; Word32 L_tmp; #ifdef BASOP_NOGLOB_DECLARE_LOCAL Flag Overflow = 0; + move32(); #endif assert( gain >= 0 ); @@ -757,24 +697,16 @@ void E_ACELP_codebook_target_update( Word16 *x, Word16 *x2, Word16 *y, Word16 ga Q15_flag = 1; move16(); } - gain = shl( gain, Q15_flag ); + gain = shl( gain, Q15_flag ); /*Q14*/ FOR( i = 0; i < L_subfr; i++ ) { - L_tmp = L_deposit_h( x[i] ); + L_tmp = L_deposit_h( x[i] ); /*Q_xn+16*/ if ( Q15_flag == 0 ) { -#ifdef BASOP_NOGLOB - L_tmp = L_msu_o( L_tmp, y[i], gain, &Overflow ); -#else - L_tmp = L_msu( L_tmp, y[i], gain ); -#endif + L_tmp = L_msu_o( L_tmp, y[i], gain, &Overflow ); /*Q_xn+15*/ } -#ifdef BASOP_NOGLOB - x2[i] = msu_ro( L_tmp, y[i], gain, &Overflow ); -#else - x2[i] = msu_r( L_tmp, y[i], gain ); -#endif + x2[i] = msu_ro( L_tmp, y[i], gain, &Overflow ); /*Q_xn*/ move16(); } } @@ -800,7 +732,7 @@ void E_ACELP_codebook_target_update( Word16 *x, Word16 *x2, Word16 *y, Word16 ga * Returns: * void */ -void E_ACELP_pulsesign( const Word16 cn[], Word16 dn[], Word16 dn2[], Word16 sign[], Word16 vec[], const Word16 alp, const Word16 sign_val, const Word16 L_subfr ) +void E_ACELP_pulsesign( const Word16 cn[] /*Q_xn*/, Word16 dn[] /*Qdn*/, Word16 dn2[] /*Qdn2*/, Word16 sign[] /*Q13*/, Word16 vec[] /*Q15*/, const Word16 alp /*Q13*/, const Word16 sign_val /*Q15*/, const Word16 L_subfr /*Q0*/ ) { Word16 i; Word32 Lval, Lcor; @@ -810,21 +742,18 @@ void E_ACELP_pulsesign( const Word16 cn[], Word16 dn[], Word16 dn2[], Word16 sig Word16 val, index; #ifdef BASOP_NOGLOB_DECLARE_LOCAL Flag Overflow = 0; + move32(); #endif /* calculate energy for normalization of cn[] and dn[] */ - Lval = L_mac0( 1, cn[0], cn[0] ); - Lcor = L_mac0( 1, dn[0], dn[0] ); + Lval = L_mac0( 1, cn[0], cn[0] ); /*2*Q_xn*/ + Lcor = L_mac0( 1, dn[0], dn[0] ); /*2*Qdn*/ FOR( i = 1; i < L_subfr; i++ ) { -#ifdef BASOP_NOGLOB - Lval = L_mac0_o( Lval, cn[i], cn[i], &Overflow ); -#else /* BASOP_NOGLOB */ - Lval = L_mac0( Lval, cn[i], cn[i] ); -#endif /* BASOP_NOGLOB */ - Lcor = L_mac0( Lcor, dn[i], dn[i] ); + Lval = L_mac0_o( Lval, cn[i], cn[i], &Overflow ); /*2*Q_xn*/ + Lcor = L_mac0( Lcor, dn[i], dn[i] ); /*2*Qdn*/ } e_dn = 31; @@ -832,64 +761,55 @@ void E_ACELP_pulsesign( const Word16 cn[], Word16 dn[], Word16 dn2[], Word16 sig e_cn = 31; move16(); - Lval = Sqrt32( Lval, &e_dn ); - Lcor = Sqrt32( Lcor, &e_cn ); + Lval = Sqrt32( Lval, &e_dn ); /*Q31 - e_dn*/ + Lcor = Sqrt32( Lcor, &e_cn ); /*Q31 - e_cn*/ i = sub( e_dn, e_cn ); if ( i < 0 ) Lval = L_shl( Lval, i ); if ( i > 0 ) Lcor = L_shr( Lcor, i ); -#ifdef BASOP_NOGLOB - k_dn = round_fx_o( Lval, &Overflow ); - k_cn = round_fx_o( Lcor, &Overflow ); -#else /* BASOP_NOGLOB */ - k_dn = round_fx( Lval ); - k_cn = round_fx( Lcor ); -#endif /* BASOP_NOGLOB */ + k_dn = round_fx_o( Lval, &Overflow ); /*Q15 - e_dn*/ + k_cn = round_fx_o( Lcor, &Overflow ); /*Q15 - e_cn*/ k_cn = mult_r( 0x2000, k_cn ); /* 1 in Q13 */ k_dn = mult_r( alp, k_dn ); /* alp in Q13 */ - sign_neg = negate( sign_val ); + sign_neg = negate( sign_val ); /*Q15*/ - signs[0] = sign_neg; + signs[0] = sign_neg; /*Q15*/ move16(); - signs[1] = sign_val; + signs[1] = sign_val; /*Q15*/ move16(); - signs[2] = sign_neg; + signs[2] = sign_neg; /*Q15*/ move16(); - ptr16 = &signs[1]; + ptr16 = &signs[1]; /*Q15*/ FOR( i = 0; i < L_subfr; i++ ) { /*cor = (s * cn[i]) + (alp * dn[i]); MULT(1);MAC(1);*/ - Lcor = L_mult( cn[i], k_cn ); - Lcor = L_mac( Lcor, dn[i], k_dn ); -#ifdef BASOP_NOGLOB - val = round_fx_o( L_shl_o( Lcor, 4, &Overflow ), &Overflow ); /*shifting by 4 may overflow but improves accuracy*/ -#else - val = round_fx( L_shl( Lcor, 4 ) ); /*shifting by 4 may overflow but improves accuracy*/ -#endif + Lcor = L_mult( cn[i], k_cn ); /*Q_xn + Q15 - e_cn + 1*/ + Lcor = L_mac( Lcor, dn[i], k_dn ); /*Qdn + Q15 - e_dn + 1*/ + val = round_fx_o( L_shl_o( Lcor, 4, &Overflow ), &Overflow ); /*shifting by 4 may overflow but improves accuracy Qdn + 4 - e_dn*/ index = shr( val, 15 ); - sign[i] = ptr16[index]; - move16(); /* yields -1 (when ps < 0) or 0 (when ps >= 0) */ - vec[i] = ptr16[index + 1]; + sign[i] = ptr16[index]; /*Q15*/ + move16(); /* yields -1 (when ps < 0) or 0 (when ps >= 0) */ + vec[i] = ptr16[index + 1]; /*Q15*/ move16(); if ( val < 0 ) { - dn[i] = negate( dn[i] ); + dn[i] = negate( dn[i] ); /*Qdn*/ move16(); } - dn2[i] = abs_s( val ); - move16(); /* dn2[] = mix of dn[] and cn[] */ + dn2[i] = abs_s( val ); /*Qdn2 = Qdn + 4 - e_dn*/ + move16(); /* dn2[] = mix of dn[] and cn[] */ } } -void E_ACELP_findcandidates( Word16 dn2[], Word16 dn2_pos[], Word16 pos_max[] ) +void E_ACELP_findcandidates( Word16 dn2[] /*Qx*/, Word16 dn2_pos[] /*Q0*/, Word16 pos_max[] /*Q0*/ ) { Word16 i, k, j, i8; Word16 *ps_ptr; @@ -899,13 +819,13 @@ void E_ACELP_findcandidates( Word16 dn2[], Word16 dn2_pos[], Word16 pos_max[] ) i8 = shl( i, 3 ); FOR( k = i8; k < i8 + 8; k++ ) { - ps_ptr = &dn2[i]; + ps_ptr = &dn2[i]; /*Qx*/ FOR( j = i + 4; j < L_SUBFR; j += 4 ) { if ( GT_16( dn2[j], *ps_ptr ) ) { - ps_ptr = &dn2[j]; + ps_ptr = &dn2[j]; /*Qx*/ move16(); } } @@ -915,15 +835,15 @@ void E_ACELP_findcandidates( Word16 dn2[], Word16 dn2_pos[], Word16 pos_max[] ) dn2_pos[k] = (Word16) ( ps_ptr - dn2 ); move16(); } - pos_max[i] = dn2_pos[i8]; + pos_max[i] = dn2_pos[i8]; /*Q0*/ move16(); } } -static void E_ACELP_apply_sign( Word16 *p0, Word16 *psign0 ) +static void E_ACELP_apply_sign( Word16 *p0 /*Qx*/, Word16 *psign0 /*Q15*/ ) { - p0[0] = mult_r( p0[0], psign0[0] ); + p0[0] = mult_r( p0[0], psign0[0] ); /*Qx*/ move16(); p0[1] = mult_r( p0[1], psign0[4] ); move16(); @@ -957,7 +877,7 @@ static void E_ACELP_apply_sign( Word16 *p0, Word16 *psign0 ) move16(); } -void E_ACELP_vec_neg( Word16 h[], Word16 h_inv[], Word16 L_subfr ) +void E_ACELP_vec_neg_fx( Word16 h[] /*Qx*/, Word16 h_inv[] /*Qx*/, Word16 L_subfr /*Q0*/ ) { Word16 i; @@ -969,7 +889,7 @@ void E_ACELP_vec_neg( Word16 h[], Word16 h_inv[], Word16 L_subfr ) } -void E_ACELP_corrmatrix( Word16 h[], Word16 sign[], Word16 vec[], Word16 rrixix[4][16], Word16 rrixiy[4][256] ) +void E_ACELP_corrmatrix_fx( Word16 h[] /*Q12*/, Word16 sign[] /*Q0*/, Word16 vec[] /*Q15*/, Word16 rrixix[4][16] /*Q9*/, Word16 rrixiy[4][256] /*Q9*/ ) { Word16 *p0, *p1, *p2, *p3, *psign0, *psign1, *psign2, *psign3; @@ -989,20 +909,20 @@ void E_ACELP_corrmatrix( Word16 h[], Word16 sign[], Word16 vec[], Word16 rrixix[ p2 = &rrixix[2][16 - 1]; p3 = &rrixix[3][16 - 1]; - ptr_h1 = h; + ptr_h1 = h; /*Q12*/ cor = L_deposit_l( 0 ); FOR( i = 0; i < 16; i++ ) { - cor = L_mac( cor, *ptr_h1, *ptr_h1 ); + cor = L_mac( cor, *ptr_h1, *ptr_h1 ); /*Q25*/ ptr_h1++; - *p3-- = round_fx( L_shr( cor, 1 ) ); - cor = L_mac( cor, *ptr_h1, *ptr_h1 ); + *p3-- = round_fx( L_shr( cor, 1 ) ); /* Q9 */ + cor = L_mac( cor, *ptr_h1, *ptr_h1 ); /*Q25*/ ptr_h1++; - *p2-- = round_fx( L_shr( cor, 1 ) ); - cor = L_mac( cor, *ptr_h1, *ptr_h1 ); + *p2-- = round_fx( L_shr( cor, 1 ) ); /* Q9 */ + cor = L_mac( cor, *ptr_h1, *ptr_h1 ); /*Q25*/ ptr_h1++; - *p1-- = round_fx( L_shr( cor, 1 ) ); - cor = L_mac( cor, *ptr_h1, *ptr_h1 ); + *p1-- = round_fx( L_shr( cor, 1 ) ); /* Q9 */ + cor = L_mac( cor, *ptr_h1, *ptr_h1 ); /*Q25*/ ptr_h1++; *p0-- = round_fx( L_shr( cor, 1 ) ); /* Q9 */ } @@ -1015,77 +935,88 @@ void E_ACELP_corrmatrix( Word16 h[], Word16 sign[], Word16 vec[], Word16 rrixix[ /* storage order --> i2i3, i1i2, i0i1, i3i0 */ pos = 256 - 1; - ptr_hf = h + 1; + move16(); + ptr_hf = h + 1; /*Q12*/ FOR( k = 0; k < 16; k++ ) { - p3 = &rrixiy[2][pos]; + p3 = &rrixiy[2][pos]; /* Q9 */ p2 = &rrixiy[1][pos]; p1 = &rrixiy[0][pos]; p0 = &rrixiy[3][pos - 16]; cor = L_deposit_h( 0 ); - ptr_h1 = h; - ptr_h2 = ptr_hf; + ptr_h1 = h; /*Q12*/ + ptr_h2 = ptr_hf; /*Q12*/ FOR( i = k; i < 16 - 1; i++ ) { - cor = L_mac( cor, *ptr_h1++, *ptr_h2++ ); - *p3 = round_fx( cor ); - cor = L_mac( cor, *ptr_h1++, *ptr_h2++ ); - *p2 = round_fx( cor ); - cor = L_mac( cor, *ptr_h1++, *ptr_h2++ ); - *p1 = round_fx( cor ); - cor = L_mac( cor, *ptr_h1++, *ptr_h2++ ); - *p0 = round_fx( cor ); + cor = L_mac( cor, *ptr_h1++, *ptr_h2++ ); /*Q25*/ + *p3 = round_fx( cor ); /*Q9*/ + cor = L_mac( cor, *ptr_h1++, *ptr_h2++ ); /*Q25*/ + *p2 = round_fx( cor ); /*Q9*/ + cor = L_mac( cor, *ptr_h1++, *ptr_h2++ ); /*Q25*/ + *p1 = round_fx( cor ); /*Q9*/ + cor = L_mac( cor, *ptr_h1++, *ptr_h2++ ); /*Q25*/ + *p0 = round_fx( cor ); /*Q9*/ p3 -= ( 16 + 1 ); p2 -= ( 16 + 1 ); p1 -= ( 16 + 1 ); p0 -= ( 16 + 1 ); } - cor = L_mac( cor, *ptr_h1++, *ptr_h2++ ); - *p3 = round_fx( cor ); - cor = L_mac( cor, *ptr_h1++, *ptr_h2++ ); - *p2 = round_fx( cor ); - cor = L_mac( cor, *ptr_h1++, *ptr_h2++ ); - *p1 = round_fx( cor ); + cor = L_mac( cor, *ptr_h1++, *ptr_h2++ ); /*Q25*/ + *p3 = round_fx( cor ); /*Q9*/ + cor = L_mac( cor, *ptr_h1++, *ptr_h2++ ); /*Q25*/ + *p2 = round_fx( cor ); /*Q9*/ + cor = L_mac( cor, *ptr_h1++, *ptr_h2++ ); /*Q25*/ + *p1 = round_fx( cor ); /*Q9*/ + move16(); + move16(); + move16(); pos -= 16; + move16(); ptr_hf += 4; } /* storage order --> i3i0, i2i3, i1i2, i0i1 */ pos = 256 - 1; - ptr_hf = h + 3; + move16(); + ptr_hf = h + 3; /*Q12*/ FOR( k = 0; k < 16; k++ ) { - p3 = &rrixiy[3][pos]; + p3 = &rrixiy[3][pos]; /*Q9*/ p2 = &rrixiy[2][pos - 1]; p1 = &rrixiy[1][pos - 1]; p0 = &rrixiy[0][pos - 1]; cor = L_deposit_h( 0 ); - ptr_h1 = h; - ptr_h2 = ptr_hf; + ptr_h1 = h; /*Q12*/ + ptr_h2 = ptr_hf; /*Q12*/ FOR( i = k; i < 16 - 1; i++ ) { - cor = L_mac( cor, *ptr_h1++, *ptr_h2++ ); - *p3 = round_fx( cor ); - cor = L_mac( cor, *ptr_h1++, *ptr_h2++ ); - *p2 = round_fx( cor ); - cor = L_mac( cor, *ptr_h1++, *ptr_h2++ ); - *p1 = round_fx( cor ); - cor = L_mac( cor, *ptr_h1++, *ptr_h2++ ); - *p0 = round_fx( cor ); + cor = L_mac( cor, *ptr_h1++, *ptr_h2++ ); /*Q25*/ + *p3 = round_fx( cor ); /*Q9*/ + cor = L_mac( cor, *ptr_h1++, *ptr_h2++ ); /*Q25*/ + *p2 = round_fx( cor ); /*Q9*/ + cor = L_mac( cor, *ptr_h1++, *ptr_h2++ ); /*Q25*/ + *p1 = round_fx( cor ); /*Q9*/ + cor = L_mac( cor, *ptr_h1++, *ptr_h2++ ); /*Q25*/ + *p0 = round_fx( cor ); /*Q9*/ + move16(); + move16(); + move16(); + move16(); p3 -= ( 16 + 1 ); p2 -= ( 16 + 1 ); p1 -= ( 16 + 1 ); p0 -= ( 16 + 1 ); } - cor = L_mac( cor, *ptr_h1++, *ptr_h2++ ); - *p3 = round_fx( cor ); + cor = L_mac( cor, *ptr_h1++, *ptr_h2++ ); /*Q25*/ + *p3 = round_fx( cor ); /*Q9*/ + move16(); pos--; ptr_hf += 4; @@ -1095,7 +1026,7 @@ void E_ACELP_corrmatrix( Word16 h[], Word16 sign[], Word16 vec[], Word16 rrixix[ * Modification of rrixiy[][] to take signs into account. */ - p0 = &rrixiy[0][0]; + p0 = &rrixiy[0][0]; /*Q9*/ /* speed-up: 11% */ p1 = &rrixiy[1][0]; @@ -1105,19 +1036,19 @@ void E_ACELP_corrmatrix( Word16 h[], Word16 sign[], Word16 vec[], Word16 rrixix[ FOR( i = 0; i < L_SUBFR; i += 4 ) { - psign0 = &vec[1]; + psign0 = &vec[1]; /*Q15*/ if ( sign[i + 0] > 0 ) psign0 = &sign[1]; - psign1 = &vec[2]; + psign1 = &vec[2]; /*Q15*/ if ( sign[i + 1] > 0 ) psign1 = &sign[2]; - psign2 = &vec[3]; + psign2 = &vec[3]; /*Q15*/ if ( sign[i + 2] > 0 ) psign2 = &sign[3]; - psign3 = &vec[0]; + psign3 = &vec[0]; /*Q15*/ if ( sign[i + 3] > 0 ) psign3 = &sign[0]; @@ -1136,7 +1067,7 @@ void E_ACELP_corrmatrix( Word16 h[], Word16 sign[], Word16 vec[], Word16 rrixix[ return; } -void E_ACELP_4tsearch_fx( Word16 dn[], const Word16 cn[], const Word16 H[], Word16 code[], const PulseConfig *config, Word16 ind[], Word16 y[] ) +void E_ACELP_4tsearch_fx( Word16 dn[] /*Qdn*/, const Word16 cn[] /*Q_xn*/, const Word16 H[] /*Q12*/, Word16 code[] /*Q9*/, const PulseConfig *config, Word16 ind[] /*Q0*/, Word16 y[] /*Qy*/ ) { Word16 sign[L_SUBFR], vec[L_SUBFR]; Word16 cor_x[16], cor_y[16], h_buf[4 * L_SUBFR]; @@ -1157,6 +1088,7 @@ void E_ACELP_4tsearch_fx( Word16 dn[], const Word16 cn[], const Word16 H[], Word Word16 check = 0; /* debug code not instrumented */ #ifdef BASOP_NOGLOB_DECLARE_LOCAL Flag Overflow = 0; + move32(); #endif @@ -1196,13 +1128,9 @@ void E_ACELP_4tsearch_fx( Word16 dn[], const Word16 cn[], const Word16 H[], Word BASOP_SATURATE_WARNING_OFF_EVS FOR( i = 0; i < L_SUBFR; i++ ) { -#ifdef BASOP_NOGLOB - L_tmp = L_mac_o( L_tmp, H[i], H[i], &Overflow ); -#else - L_tmp = L_mac( L_tmp, H[i], H[i] ); -#endif + L_tmp = L_mac_o( L_tmp, H[i], H[i], &Overflow ); /*Q25*/ } - val = extract_h( L_tmp ); + val = extract_h( L_tmp ); /*Q9*/ BASOP_SATURATE_WARNING_ON_EVS if ( GT_16( val, 0x2000 ) ) @@ -1216,15 +1144,15 @@ void E_ACELP_4tsearch_fx( Word16 dn[], const Word16 cn[], const Word16 H[], Word move16(); } - Copy_Scale_sig( H, h, L_SUBFR, scale ); + Copy_Scale_sig( H, h, L_SUBFR, scale ); /*Q12+scale*/ - E_ACELP_vec_neg( h, h_inv, L_SUBFR ); + E_ACELP_vec_neg_fx( h, h_inv, L_SUBFR ); /* * Compute correlation matrices needed for the codebook search. */ - E_ACELP_corrmatrix( h, sign, vec, rrixix, rrixiy ); + E_ACELP_corrmatrix_fx( h, sign, vec, rrixix, rrixiy ); /* @@ -1275,25 +1203,25 @@ void E_ACELP_4tsearch_fx( Word16 dn[], const Word16 cn[], const Word16 H[], Word i = shr( ind[0], 2 ); j = shr( ind[1], 2 ); l = add( shl( i, 4 ), j ); - s = L_mult( rrixix[ipos[0]][i], _1_ ); /* Q9+Q12+1 */ - s = L_mac( s, rrixix[ipos[1]][j], _1_ ); - alp = mac_r( s, rrixiy[ipos[0]][l], _1_ ); + s = L_mult( rrixix[ipos[0]][i], _1_ ); /* Q9+Q12+1 */ + s = L_mac( s, rrixix[ipos[1]][j], _1_ ); /* Q9+Q12+1 */ + alp = mac_r( s, rrixiy[ipos[0]][l], _1_ ); /* Q9+Q12+1-16 */ - p0 = h - ind[0]; + p0 = h - ind[0]; /*Q12+scale*/ if ( sign[ind[0]] < 0 ) { - p0 = h_inv - ind[0]; + p0 = h_inv - ind[0]; /*Q12+scale*/ } - p1 = h - ind[1]; + p1 = h - ind[1]; /*Q12+scale*/ if ( sign[ind[1]] < 0 ) { - p1 = h_inv - ind[1]; + p1 = h_inv - ind[1]; /*Q12+scale*/ } FOR( i = 0; i < L_SUBFR; i++ ) { - vec[i] = add( *p0++, *p1++ ); + vec[i] = add( *p0++, *p1++ ); /*Q12+scale*/ move16(); } } @@ -1301,57 +1229,53 @@ void E_ACELP_4tsearch_fx( Word16 dn[], const Word16 cn[], const Word16 H[], Word { /* first stage: fix 4 pulses */ - ind[0] = pos_max[ipos[0]]; + ind[0] = pos_max[ipos[0]]; /*Q0*/ move16(); - ind[1] = pos_max[ipos[1]]; + ind[1] = pos_max[ipos[1]]; /*Q0*/ move16(); - ind[2] = pos_max[ipos[2]]; + ind[2] = pos_max[ipos[2]]; /*Q0*/ move16(); - ind[3] = pos_max[ipos[3]]; + ind[3] = pos_max[ipos[3]]; /*Q0*/ move16(); /*ps = dn[ind[0]] + dn[ind[1]] + dn[ind[2]] + dn[ind[3]];*/ ps = add( add( add( dn[ind[0]], dn[ind[1]] ), dn[ind[2]] ), dn[ind[3]] ); - p0 = h - ind[0]; + p0 = h - ind[0]; /*Q12+scale*/ if ( sign[ind[0]] < 0 ) { - p0 = h_inv - ind[0]; + p0 = h_inv - ind[0]; /*Q12+scale*/ } - p1 = h - ind[1]; + p1 = h - ind[1]; /*Q12+scale*/ if ( sign[ind[1]] < 0 ) { - p1 = h_inv - ind[1]; + p1 = h_inv - ind[1]; /*Q12+scale*/ } - p2 = h - ind[2]; + p2 = h - ind[2]; /*Q12+scale*/ if ( sign[ind[2]] < 0 ) { - p2 = h_inv - ind[2]; + p2 = h_inv - ind[2]; /*Q12+scale*/ } - p3 = h - ind[3]; + p3 = h - ind[3]; /*Q12+scale*/ if ( sign[ind[3]] < 0 ) { - p3 = h_inv - ind[3]; + p3 = h_inv - ind[3]; /*Q12+scale*/ } FOR( i = 0; i < L_SUBFR; i++ ) { - vec[i] = add( add( add( *p0++, *p1++ ), *p2++ ), *p3++ ); + vec[i] = add( add( add( *p0++, *p1++ ), *p2++ ), *p3++ ); /*Q12+scale*/ move16(); } - L_tmp = L_mult( vec[0], vec[0] ); + L_tmp = L_mult( vec[0], vec[0] ); /*Q25+2*scale*/ FOR( i = 1; i < L_SUBFR; i++ ) -#ifdef BASOP_NOGLOB - L_tmp = L_mac_o( L_tmp, vec[i], vec[i], &Overflow ); -#else - L_tmp = L_mac( L_tmp, vec[i], vec[i] ); -#endif + L_tmp = L_mac_o( L_tmp, vec[i], vec[i], &Overflow ); /*Q25+2*scale*/ - alp = round_fx( L_shr( L_tmp, 3 ) ); + alp = round_fx( L_shr( L_tmp, 3 ) ); /*Q6+2*scale*/ /*alp *= 0.5F; */ } @@ -1368,9 +1292,9 @@ void E_ACELP_4tsearch_fx( Word16 dn[], const Word16 cn[], const Word16 H[], Word * of the next 2 pulses with previous fixed pulses. * Each pulse can have 16 possible positions. */ - E_ACELP_h_vec_corr1( h, vec, ipos[j], sign, rrixix, cor_x, dn2_pos, config->nbpos[st] ); + E_ACELP_h_vec_corr1_fx( h, vec, ipos[j], sign, rrixix, cor_x, dn2_pos, config->nbpos[st] ); - E_ACELP_h_vec_corr2( h, vec, ipos[j + 1], sign, rrixix, cor_y ); + E_ACELP_h_vec_corr2_fx( h, vec, ipos[j + 1], sign, rrixix, cor_y ); /* * Find best positions of 2 pulses. @@ -1380,9 +1304,9 @@ void E_ACELP_4tsearch_fx( Word16 dn[], const Word16 cn[], const Word16 H[], Word } ELSE /* single pulse search */ { - E_ACELP_h_vec_corr2( h, vec, ipos[j], sign, rrixix, cor_x ); + E_ACELP_h_vec_corr2_fx( h, vec, ipos[j], sign, rrixix, cor_x ); - E_ACELP_h_vec_corr2( h, vec, ipos[j + 1], sign, rrixix, cor_y ); + E_ACELP_h_vec_corr2_fx( h, vec, ipos[j + 1], sign, rrixix, cor_y ); E_ACELP_1pulse_search( &ipos[j], &ps, &alp, &ind[j], dn, cor_x, cor_y ); @@ -1390,29 +1314,24 @@ void E_ACELP_4tsearch_fx( Word16 dn[], const Word16 cn[], const Word16 H[], Word IF( GT_16( nb_pulse_m2, j ) ) { - p0 = h - ind[j]; + p0 = h - ind[j]; /*Q12+scale*/ if ( sign[ind[j]] < 0 ) { - p0 = h_inv - ind[j]; + p0 = h_inv - ind[j]; /*Q12+scale*/ } - p1 = h - ind[j + 1]; + p1 = h - ind[j + 1]; /*Q12+scale*/ if ( sign[ind[j + 1]] < 0 ) { - p1 = h_inv - ind[j + 1]; + p1 = h_inv - ind[j + 1]; /*Q12+scale*/ } FOR( i = 0; i < L_SUBFR; i++ ) { tmp = add( *p0++, *p1++ ); -#ifdef BASOP_NOGLOB vec[i] = add_o( vec[i], tmp, &Overflow ); /* can saturate here. */ move16(); -#else - vec[i] = add( vec[i], tmp ); /* can saturate here. */ - move16(); -#endif } } st = add( st, 1 ); @@ -1428,6 +1347,7 @@ void E_ACELP_4tsearch_fx( Word16 dn[], const Word16 cn[], const Word16 H[], Word if ( psk < 0 ) { s = 1; + move32(); } IF( s > 0 ) { @@ -1435,8 +1355,8 @@ void E_ACELP_4tsearch_fx( Word16 dn[], const Word16 cn[], const Word16 H[], Word move16(); alpk = alp; move16(); - Copy( ind, codvec, nb_pulse ); - check = 1; /* debug code not instrumented */ + Copy( ind, codvec, nb_pulse ); /*Q0*/ + check = 1; /* debug code not instrumented */ } } @@ -1451,26 +1371,348 @@ void E_ACELP_4tsearch_fx( Word16 dn[], const Word16 cn[], const Word16 H[], Word set16_fx( y, 0, L_SUBFR ); FOR( k = 0; k < nb_pulse; ++k ) { - i = codvec[k]; + i = codvec[k]; /*Q0*/ move16(); - p0 = h_inv - i; + p0 = h_inv - i; /*Q12+scale*/ if ( sign[i] > 0 ) { p0 -= 2 * L_SUBFR; } FOR( i = 0; i < L_SUBFR; i++ ) { -#ifdef BASOP_NOGLOB - y[i] = add_o( y[i], *p0++, &Overflow ); -#else - y[i] = add( y[i], *p0++ ); -#endif + y[i] = add_o( y[i], *p0++, &Overflow ); /*Q12+scale*/ move16(); } } return; } +#ifdef FIX_ISSUE_1165 +void E_ACELP_4tsearch_ivas_fx( Word16 dn[] /*Qdn*/, const Word16 cn[] /*Q_xn*/, const Word16 H[] /*Q12*/, Word16 code[] /*Q9*/, const PulseConfig *config, Word16 ind[] /*Q0*/, Word16 y[] /*Qy*/ ) +{ + Word16 sign[L_SUBFR], vec[L_SUBFR]; + Word16 cor_x[16], cor_y[16], h_buf[4 * L_SUBFR]; + Word16 rrixix[4][16]; + Word16 rrixiy[4][256]; + Word16 dn2[L_SUBFR]; + Word16 psk, ps, alpk, alp = 0; + Word16 codvec[NB_PULSE_MAX]; + Word16 pos_max[4]; + Word16 dn2_pos[8 * 4]; + UWord8 ipos[NB_PULSE_MAX]; + Word16 *p0, *p1, *p2, *p3; + Word16 *h, *h_inv; + Word16 i, j, k, l, st, pos; + Word16 val, tmp, scale; + Word32 s, L_tmp; + Word16 nb_pulse, nb_pulse_m2; + Word16 check = 0; /* debug code not instrumented */ +#ifdef BASOP_NOGLOB_DECLARE_LOCAL + Flag Overflow = 0; + move32(); +#endif + + + alp = config->alp; /* Q13 */ /* initial value for energy of all fixed pulses */ + move16(); + nb_pulse = config->nb_pulse; + move16(); + nb_pulse_m2 = sub( nb_pulse, 2 ); + + set16_fx( codvec, 0, nb_pulse ); + + /* + * Find sign for each pulse position. + */ + + E_ACELP_pulsesign( cn, dn, dn2, sign, vec, alp, 0x7fff, L_SUBFR ); + + /* + * Select the most important 8 position per track according to dn2[]. + */ + E_ACELP_findcandidates( dn2, dn2_pos, pos_max ); + + /* + * Compute h_inv[i]. + */ + set16_fx( h_buf, 0, L_SUBFR ); + + set16_fx( h_buf + ( 2 * L_SUBFR ), 0, L_SUBFR ); + + h = h_buf + L_SUBFR; + h_inv = h_buf + ( 3 * L_SUBFR ); + + /*Check the energy if it is too high then scale to prevent an overflow*/ + scale = 0; + move16(); + L_tmp = L_deposit_l( 0 ); + BASOP_SATURATE_WARNING_OFF_EVS + FOR( i = 0; i < L_SUBFR; i++ ) + { + L_tmp = L_mac_o( L_tmp, H[i], H[i], &Overflow ); /*Q25*/ + } + val = extract_h( L_tmp ); /*Q9*/ + BASOP_SATURATE_WARNING_ON_EVS + + if ( GT_16( val, 0x2000 ) ) + { + scale = -1; + move16(); + } + if ( GT_16( val, 0x7000 ) ) + { + scale = -2; + move16(); + } + if ( EQ_16( val, 32767 ) ) + { + scale = -3; + move16(); + } + + Copy_Scale_sig( H, h, L_SUBFR, scale ); /*Q12+scale*/ + + E_ACELP_vec_neg_fx( h, h_inv, L_SUBFR ); + + + /* + * Compute correlation matrices needed for the codebook search. + */ + E_ACELP_corrmatrix_fx( h, sign, vec, rrixix, rrixiy ); + + + /* + * Deep first search: + * ------------------ + * 20 bits (4p): 4 iter x ((4x16)+(8x16)) = 768 tests + * 36 bits (8p): 4 iter x ((1x1)+(4x16)+(8x16)+(8x16)) = 1280 tests + * 52 bits (12p): 3 iter x ((1x1)+(1x1)+(4x16)+(6x16) + * +(8x16)+(8x16)) = 1248 tests + * 64 bits (16p): 2 iter x ((1x1)+(1x1)+(4x16)+(6x16) + * +(6x16)+(8x16)+(8x16)+(8x16)) = 1280 tests + */ + psk = -1; + move16(); + alpk = 1; + move16(); + + /*Number of iterations*/ + FOR( k = 0; k < config->nbiter; k++ ) + { + E_ACELP_setup_pulse_search_pos( config, k, ipos ); + + /* format of alp changes to Q(15-ALP2_E) */ + + pos = config->fixedpulses; + move16(); + + IF( config->fixedpulses == 0 ) /* 1100, 11, 1110, 1111, 2211 */ + { + ps = 0; + move16(); + alp = 0; + move16(); + set16_fx( vec, 0, L_SUBFR ); + } + ELSE IF( EQ_16( config->fixedpulses, 2 ) ) /* 2222 and 3322 */ + { + /* first stage: fix 2 pulses */ + ind[0] = pos_max[ipos[0]]; + move16(); + ind[1] = pos_max[ipos[1]]; + move16(); + ps = add( dn[ind[0]], dn[ind[1]] ); + + /*alp = rrixix[ipos[0]][ind[0] >> 2] + rrixix[ipos[1]][ind[1] >> 2] + + rrixiy[ipos[0]][((ind[0] >> 2) << 4) + (ind[1] >> 2)];*/ + + i = shr( ind[0], 2 ); + j = shr( ind[1], 2 ); + l = add( shl( i, 4 ), j ); + s = L_mult( rrixix[ipos[0]][i], _1_ ); /* Q9+Q12+1 */ + s = L_mac( s, rrixix[ipos[1]][j], _1_ ); /* Q9+Q12+1 */ + alp = mac_r( s, rrixiy[ipos[0]][l], _1_ ); /* Q9+Q12+1-16 */ + + p0 = h - ind[0]; /*Q12+scale*/ + IF( sign[ind[0]] < 0 ) + { + p0 = h_inv - ind[0]; /*Q12+scale*/ + } + + p1 = h - ind[1]; /*Q12+scale*/ + IF( sign[ind[1]] < 0 ) + { + p1 = h_inv - ind[1]; /*Q12+scale*/ + } + + FOR( i = 0; i < L_SUBFR; i++ ) + { + vec[i] = add( *p0++, *p1++ ); /*Q12+scale*/ + move16(); + } + } + ELSE /* 3333 and above */ + { + /* first stage: fix 4 pulses */ + + ind[0] = pos_max[ipos[0]]; /*Q0*/ + move16(); + ind[1] = pos_max[ipos[1]]; /*Q0*/ + move16(); + ind[2] = pos_max[ipos[2]]; /*Q0*/ + move16(); + ind[3] = pos_max[ipos[3]]; /*Q0*/ + move16(); + + /*ps = dn[ind[0]] + dn[ind[1]] + dn[ind[2]] + dn[ind[3]];*/ + ps = add( add( add( dn[ind[0]], dn[ind[1]] ), dn[ind[2]] ), dn[ind[3]] ); + + p0 = h - ind[0]; /*Q12+scale*/ + IF( sign[ind[0]] < 0 ) + { + p0 = h_inv - ind[0]; /*Q12+scale*/ + } + + p1 = h - ind[1]; /*Q12+scale*/ + IF( sign[ind[1]] < 0 ) + { + p1 = h_inv - ind[1]; /*Q12+scale*/ + } + + p2 = h - ind[2]; /*Q12+scale*/ + IF( sign[ind[2]] < 0 ) + { + p2 = h_inv - ind[2]; /*Q12+scale*/ + } + + p3 = h - ind[3]; /*Q12+scale*/ + IF( sign[ind[3]] < 0 ) + { + p3 = h_inv - ind[3]; /*Q12+scale*/ + } + + FOR( i = 0; i < L_SUBFR; i++ ) + { + vec[i] = add( add( add( *p0++, *p1++ ), *p2++ ), *p3++ ); /*Q12+scale*/ + move16(); + } + + L_tmp = L_mult( vec[0], vec[0] ); /*Q25+2*scale*/ + FOR( i = 1; i < L_SUBFR; i++ ) + L_tmp = L_mac_o( L_tmp, vec[i], vec[i], &Overflow ); /*Q25+2*scale*/ + + alp = round_fx( L_shr( L_tmp, 3 ) ); /*Q6+2*scale*/ + + /*alp *= 0.5F; */ + } + + /* other stages of 2 pulses */ + st = 0; + move16(); + FOR( j = pos; j < nb_pulse; j += 2 ) + { + IF( GE_16( nb_pulse_m2, j ) ) /* pair-wise search */ + { + /* + * Calculate correlation of all possible positions + * of the next 2 pulses with previous fixed pulses. + * Each pulse can have 16 possible positions. + */ + E_ACELP_h_vec_corr1_fx( h, vec, ipos[j], sign, rrixix, cor_x, dn2_pos, config->nbpos[st] ); + + E_ACELP_h_vec_corr2_fx( h, vec, ipos[j + 1], sign, rrixix, cor_y ); + + /* + * Find best positions of 2 pulses. + */ + E_ACELP_2pulse_search( config->nbpos[st], ipos[j], ipos[j + 1], &ps, &alp, + &ind[j], &ind[j + 1], dn, dn2_pos, cor_x, cor_y, rrixiy ); + } + ELSE /* single pulse search */ + { + E_ACELP_h_vec_corr2_fx( h, vec, ipos[j], sign, rrixix, cor_x ); + + E_ACELP_h_vec_corr2_fx( h, vec, ipos[j + 1], sign, rrixix, cor_y ); + + E_ACELP_1pulse_search( &ipos[j], &ps, &alp, + &ind[j], dn, cor_x, cor_y ); + } + + IF( GT_16( nb_pulse_m2, j ) ) + { + p0 = h - ind[j]; /*Q12+scale*/ + IF( sign[ind[j]] < 0 ) + { + p0 = h_inv - ind[j]; /*Q12+scale*/ + } + + p1 = h - ind[j + 1]; /*Q12+scale*/ + IF( sign[ind[j + 1]] < 0 ) + { + p1 = h_inv - ind[j + 1]; /*Q12+scale*/ + } + + + FOR( i = 0; i < L_SUBFR; i++ ) + { + tmp = add( *p0++, *p1++ ); + vec[i] = add_o( vec[i], tmp, &Overflow ); /* can saturate here. */ + move16(); + } + } + st = add( st, 1 ); + } + + /* memorise the best codevector */ + + /*ps = ps * ps; MULT(1);*/ + ps = mult( ps, ps ); + /*s = (alpk * ps) - (psk * alp); MULT(2);ADD(1);*/ + s = L_msu( L_mult( alpk, ps ), psk, alp ); /*Q9+Q6+1=Q16*/ + + if ( psk < 0 ) + { + s = 1; + move32(); + } + IF( s > 0 ) + { + psk = ps; + move16(); + alpk = alp; + move16(); + Copy( ind, codvec, nb_pulse ); /*Q0*/ + check = 1; /* debug code not instrumented */ + } + } + + assert( check ); /* debug code not instrumented */ + + /* + * Build the codeword, the filtered codeword and index of codevector, as well as store weighted correlations. + */ + + E_ACELP_build_code( nb_pulse, codvec, sign, code, ind ); + + set16_fx( y, 0, L_SUBFR ); + FOR( k = 0; k < nb_pulse; ++k ) + { + i = codvec[k]; /*Q0*/ + move16(); + p0 = h_inv - i; /*Q12+scale*/ + IF( sign[i] > 0 ) + { + p0 -= 2 * L_SUBFR; + } + FOR( i = 0; i < L_SUBFR; i++ ) + { + y[i] = add_o( y[i], *p0++, &Overflow ); /*Q12+scale*/ + move16(); + } + } + return; +} +#endif /* * E_ACELP_4t_fx @@ -1507,19 +1749,19 @@ void E_ACELP_4tsearch_fx( Word16 dn[], const Word16 cn[], const Word16 H[], Word * void */ void E_ACELP_4t_fx( - Word16 dn[], + Word16 dn[], /*Qdn*/ Word16 cn[] /* Q_xn */, - Word16 H[], - Word16 R[], - Word8 acelpautoc, - Word16 code[], - Word16 cdk_index, - Word16 _index[], - const Word16 L_frame, - const Word16 last_L_frame, - const Word32 total_brate, - const Word16 i_subfr, - const int16_t cmpl_flag ) + Word16 H[], /*Q12*/ + Word16 R[], /*Qx*/ + Word8 acelpautoc, /*Q0*/ + Word16 code[], /*Q9*/ + Word16 cdk_index, /*Q0*/ + Word16 _index[], /*Q0*/ + const Word16 L_frame, /*Q0*/ + const Word16 last_L_frame, /*Q0*/ + const Word32 total_brate, /*Q0*/ + const Word16 i_subfr, /*Q0*/ + const Word16 cmpl_flag /*Q0*/ ) { PulseConfig config; Word16 ind[NPMAXPT * 4]; @@ -1570,20 +1812,20 @@ void E_ACELP_4t_fx( } void E_ACELP_4t_ivas_fx( - Word16 dn[], + Word16 dn[], /*Qdn*/ Word16 cn[] /* Q_xn */, - Word16 H[], - Word16 R[], - Word8 acelpautoc, - Word16 code[], - Word16 cdk_index, - Word16 _index[], - const Word16 L_frame, - const Word16 last_L_frame, - const Word32 total_brate, - const Word16 i_subfr, - const int16_t cmpl_flag, - Word16 element_mode ) + Word16 H[], /*Q12*/ + Word16 R[], /*Qx*/ + Word8 acelpautoc, /*Q0*/ + Word16 code[], /*Q9*/ + Word16 cdk_index, /*Q0*/ + Word16 _index[], /*Q0*/ + const Word16 L_frame, /*Q0*/ + const Word16 last_L_frame, /*Q0*/ + const Word32 total_brate, /*Q0*/ + const Word16 i_subfr, /*Q0*/ + const Word16 cmpl_flag, /*Q0*/ + Word16 element_mode /*Q0*/ ) { PulseConfig config; Word16 ind[NPMAXPT * 4]; @@ -1627,18 +1869,22 @@ void E_ACELP_4t_ivas_fx( } ELSE { +#ifdef FIX_ISSUE_1165 + E_ACELP_4tsearch_ivas_fx( dn, cn, H, code, &config, ind, y ); +#else E_ACELP_4tsearch_fx( dn, cn, H, code, &config, ind, y ); +#endif } E_ACELP_indexing_fx( code, &config, NB_TRACK_FCB_4T, _index ); return; } static void E_ACELP_indexing_shift( - Word16 wordcnt, /* i: 16-bit word count including the newly shifted-in bits */ - Word16 shift_bits, /* i: number of bits to shift in from the lsb */ - UWord16 lsb_bits, /* i: bits to shift in from the lsb */ - const UWord16 src[], /* i: source buffer */ - UWord16 dst[] /* o: destination buffer */ + Word16 wordcnt, /* i: 16-bit word count including the newly shifted-in bits Q0*/ + Word16 shift_bits, /* i: number of bits to shift in from the lsb Q0*/ + UWord16 lsb_bits, /* i: bits to shift in from the lsb Q0*/ + const UWord16 src[], /* i: source buffer Q0*/ + UWord16 dst[] /* o: destination buffer Q(shift_bits)*/ ) { Word16 right_shift, i; @@ -1649,10 +1895,10 @@ static void E_ACELP_indexing_shift( FOR( i = sub( wordcnt, 1 ); i > 0; --i ) { - dst[i] = s_or( lshl( src[i], shift_bits ), lshr( src[i - 1], right_shift ) ); + dst[i] = s_or( lshl( src[i], shift_bits ), lshr( src[i - 1], right_shift ) ); /*Q0+shift_bits*/ move16(); } - dst[i] = s_or( lshl( src[i], shift_bits ), lsb_bits ); + dst[i] = s_or( lshl( src[i], shift_bits ), lsb_bits ); /*Q(shift_bits)*/ move16(); return; } @@ -1660,10 +1906,10 @@ static void E_ACELP_indexing_shift( #define MAX_IDX_LEN 9 Word16 E_ACELP_indexing_fx( - const Word16 code[], + const Word16 code[], /*Q9*/ const PulseConfig *config, - Word16 num_tracks, - Word16 prm[] ) + Word16 num_tracks, /*Q0*/ + Word16 prm[] /*Q(shift_bits)*/ ) { Word16 track, shift_bits; Word16 p[NB_TRACK_FCB_4T], wordcnt; @@ -1716,6 +1962,7 @@ Word16 E_ACELP_indexing_fx( if ( GT_16( p[3], p[1] ) ) { track = add( track, 2 ); + move16(); } shift_bits = 2; move16(); @@ -1788,15 +2035,15 @@ Word16 E_ACELP_indexing_fx( void E_ACELP_adaptive_codebook( Word16 *exc, /* i/o: pointer to the excitation frame Q_new */ Word16 T0, /* i : integer pitch lag Q0 */ - Word16 T0_frac, /* i : fraction of lag */ - Word16 T0_res, /* i : pitch resolution */ - Word16 T0_res_max, /* i : maximum pitch resolution */ - Word16 mode, /* i : filtering mode (0: no, 1: yes, 2: adaptive) */ + Word16 T0_frac, /* i : fraction of lag Q0 */ + Word16 T0_res, /* i : pitch resolution Q0 */ + Word16 T0_res_max, /* i : maximum pitch resolution Q0 */ + Word16 mode, /* i : filtering mode (0: no, 1: yes, 2: adaptive) Q0 */ Word16 i_subfr, /* i : subframe index */ - Word16 L_subfr, /* i : subframe length */ - Word16 L_frame, /* i : subframe length */ + Word16 L_subfr, /* i : subframe length Q0 */ + Word16 L_frame, /* i : subframe length Q0 */ Word16 *h1, /* i : impulse response of weighted synthesis filter 1Q14+shift */ - Word16 clip_gain, /* i : flag to indicate ??? */ + Word16 clip_gain, /* i : flag to indicate ??? Q14 */ Word16 *xn, /* i : Close-loop Pitch search target vector Q_xn */ Word16 *y1, /* o : zero-memory filtered adaptive excitation Q_xn */ ACELP_CbkCorr *g_corr, /* o : ACELP correlation values */ @@ -1813,15 +2060,20 @@ void E_ACELP_adaptive_codebook( Word16 y2[L_SUBFR], xn2[L_SUBFR], code[L_SUBFR]; ACELP_CbkCorr g_corr2; Word16 gain1 = 0, gain2 = 0, fac_m, fac_n; + move16(); + move16(); Word16 i, select, exp_ener; Word32 L_tmp, L_ener; const Word16 *pitch_inter; Word16 pit_L_interpol, pit_up_samp; Word16 use_prev_sf_pit_gain = 0; + move16(); - if ( rf_mode == 1 && rf_coder_type == 100 ) + test(); + IF( EQ_16( rf_mode, 1 ) && EQ_16( rf_coder_type, 100 ) ) { use_prev_sf_pit_gain = 1; + move16(); } BASOP_SATURATE_ERROR_ON_EVS; @@ -1830,14 +2082,15 @@ void E_ACELP_adaptive_codebook( /* find pitch excitation */ /*for &exc[i_subfr]*/ - if ( EQ_16( T0_res, shr( T0_res_max, 1 ) ) ) + IF( EQ_16( T0_res, shr( T0_res_max, 1 ) ) ) { - T0_frac = shl( T0_frac, 1 ); + T0_frac = shl( T0_frac, 1 ); /*Q0*/ } + test(); IF( EQ_16( T0_res_max, 6 ) && rf_mode == 0 ) { - pitch_inter = pitch_inter6_2; + pitch_inter = pitch_inter6_2; /*Q14*/ pit_L_interpol = PIT_L_INTERPOL6_2; move16(); pit_up_samp = PIT_UP_SAMP6; @@ -1845,7 +2098,7 @@ void E_ACELP_adaptive_codebook( } ELSE { - pitch_inter = pitch_inter4_2; + pitch_inter = pitch_inter4_2; /*Q14*/ pit_L_interpol = L_INTERPOL2; move16(); pit_up_samp = PIT_UP_SAMP; @@ -1861,22 +2114,23 @@ void E_ACELP_adaptive_codebook( IF( use_prev_sf_pit_gain == 0 ) { - gain1 = E_ACELP_xy1_corr( xn, y1, g_corr, 1, L_subfr, exp_xn ); + gain1 = E_ACELP_xy1_corr_fx( xn, y1, g_corr, 1, L_subfr, exp_xn ); /*Q14*/ - /* clip gain if necessary to avoid problem at decoder */ test(); - if ( clip_gain && GT_16( gain1, 15565 /*0.95 Q14*/ ) ) + /* clip gain if necessary to avoid problem at decoder */ + test(); + IF( clip_gain && GT_16( gain1, 15565 /*0.95 Q14*/ ) ) { gain1 = 15565 /*0.95f Q14*/; move16(); } - *pitch_gain = gain1; + *pitch_gain = gain1; /*Q14*/ move16(); } /* find energy of new target xn2[] */ - E_ACELP_codebook_target_update( xn, xn2, y1, gain1, L_subfr ); - L_ener = Dot_product12_offs( xn2, xn2, L_subfr, &exp_ener, 0 ); - L_ener = L_shr( L_ener, sub( 31, exp_ener ) ); + E_ACELP_codebook_target_update_fx( xn, xn2, y1, gain1, L_subfr ); + L_ener = Dot_product12_offs( xn2, xn2, L_subfr, &exp_ener, 0 ); /*Q31-exp_ener*/ + L_ener = L_shr( L_ener, sub( 31, exp_ener ) ); /*Q0*/ } /*-----------------------------------------------------------------* @@ -1896,28 +2150,29 @@ void E_ACELP_adaptive_codebook( move16(); } /* fac_n = 0.5*(1.0-fac_m); */ - fac_n = mult_r( sub( 0x7FFF, fac_m ), 0x4000 ); + fac_n = mult_r( sub( 0x7FFF, fac_m ), 0x4000 ); /*Q15*/ FOR( i = 0; i < L_subfr; i++ ) { - L_tmp = L_mult( fac_n, exc[i - 1 + i_subfr] ); - L_tmp = L_mac( L_tmp, fac_m, exc[i + 0 + i_subfr] ); - code[i] = mac_r( L_tmp, fac_n, exc[i + 1 + i_subfr] ); + L_tmp = L_mult( fac_n, exc[i - 1 + i_subfr] ); /*Q_new+Q16*/ + L_tmp = L_mac( L_tmp, fac_m, exc[i + 0 + i_subfr] ); /*Q_new+Q16*/ + code[i] = mac_r( L_tmp, fac_n, exc[i + 1 + i_subfr] ); /*Q_new*/ move16(); } E_UTIL_f_convolve( code, h1, y2, L_subfr ); - gain2 = E_ACELP_xy1_corr( xn, y2, &g_corr2, 1, L_subfr, exp_xn ); + gain2 = E_ACELP_xy1_corr_fx( xn, y2, &g_corr2, 1, L_subfr, exp_xn ); /*Q14*/ - /* clip gain if necessary to avoid problem at decoder */ test(); - if ( clip_gain && GT_16( gain2, 15565 /*0.95 Q14*/ ) ) + /* clip gain if necessary to avoid problem at decoder */ + test(); + IF( clip_gain && GT_16( gain2, 15565 /*0.95 Q14*/ ) ) { gain2 = 15565 /*0.95f Q14*/; move16(); } /* find energy of new target xn2[] */ - E_ACELP_codebook_target_update( xn, xn2, y2, gain2, L_subfr ); - L_tmp = Dot_product12_offs( xn2, xn2, L_subfr, &exp_ener, 0 ); - L_tmp = L_shr( L_tmp, sub( 31, exp_ener ) ); + E_ACELP_codebook_target_update_fx( xn, xn2, y2, gain2, L_subfr ); + L_tmp = Dot_product12_offs( xn2, xn2, L_subfr, &exp_ener, 0 ); /*Q31 - exp_ener*/ + L_tmp = L_shr( L_tmp, sub( 31, exp_ener ) ); /*Q0*/ /*-----------------------------------------------------------------* * use the best prediction (minimise quadratic error). * @@ -1928,9 +2183,9 @@ void E_ACELP_adaptive_codebook( /* use the lp filter for pitch excitation prediction */ select = LOW_PASS; move16(); - Copy( code, &exc[i_subfr], L_subfr ); - Copy( y2, y1, L_subfr ); - *pitch_gain = gain2; + Copy( code, &exc[i_subfr], L_subfr ); /*Q_new*/ + Copy( y2, y1, L_subfr ); /*Q_xn*/ + *pitch_gain = gain2; /*Q14*/ move16(); g_corr->y1y1 = g_corr2.y1y1; move16(); @@ -1946,7 +2201,7 @@ void E_ACELP_adaptive_codebook( /* no filter used for pitch excitation prediction */ select = FULL_BAND; move16(); - *pitch_gain = gain1; + *pitch_gain = gain1; /*Q14*/ move16(); } @@ -1964,6 +2219,7 @@ void E_ACELP_adaptive_codebook( move16(); } *lp_select = select; + move16(); BASOP_SATURATE_ERROR_OFF_EVS; } @@ -1993,9 +2249,9 @@ void E_ACELP_innovative_codebook_fx( Word16 **pt_indice, /* i/o: quantization indices pointer */ Word16 *code, /* o : innovative codebook Q9 Q9 */ Word16 shift, /* i : Scaling to get 12 bits */ - const Word16 L_frame, /* i : length of the frame */ - const Word16 last_L_frame, /* i : length of the last frame */ - const Word32 total_brate /* i : ttoal bit-rate */ + const Word16 L_frame, /* i : length of the frame Q0*/ + const Word16 last_L_frame, /* i : length of the last frame Q0*/ + const Word32 total_brate /* i : ttoal bit-rate Q0*/ ) { Word16 xn2[L_SUBFR] /* Q_xn */, cn2[L_SUBFR] /* Q_xn */, dn[L_SUBFR] /* Rw2*cn2 */, h2[L_SUBFR] /* 4Q11 */; @@ -2014,7 +2270,7 @@ void E_ACELP_innovative_codebook_fx( BASOP_SATURATE_ERROR_ON_EVS; /* Update target vector for ACELP codebook search */ - E_ACELP_codebook_target_update( xn, xn2, y1, pitch_gain, L_SUBFR ); + E_ACELP_codebook_target_update_fx( xn, xn2, y1, pitch_gain, L_SUBFR ); /* Include fixed-gain pitch contribution into impulse resp. h1[] */ Copy_Scale_sig( h1, h2, L_SUBFR, sub( -3, shift ) ); /*h2 1Q14+shift -> 4Q11, 1bit of headroom for Residu and xh_corr*/ @@ -2036,7 +2292,7 @@ void E_ACELP_innovative_codebook_fx( ELSE { BASOP_SATURATE_WARNING_OFF_EVS; - E_ACELP_codebook_target_update( cn, cn2, &exc[i_subfr], pitch_gain, L_SUBFR ); + E_ACELP_codebook_target_update_fx( cn, cn2, &exc[i_subfr], pitch_gain, L_SUBFR ); BASOP_SATURATE_WARNING_ON_EVS; Scale_sig( cn2, L_SUBFR, shift ); E_ACELP_xh_corr( xn2, dn, h2, L_SUBFR ); @@ -2073,7 +2329,7 @@ void E_ACELP_innovative_codebook_fx( * n - (output) range of possible states (0...n-1) * p - (output) number of pulses found *--------------------------------------------------------------------------*/ -static void E_ACELP_codearithp_fx( const Word16 v[], UWord32 *n, UWord32 *ps, Word16 *p ) +static void E_ACELP_codearithp_fx( const Word16 v[] /*Q9*/, UWord32 *n /*Q0*/, UWord32 *ps /*Q0*/, Word16 *p /*Q0*/ ) { Word16 k, nb_pulse, i, t, pos[NPMAXPT], posno; Word16 sign, m; @@ -2081,6 +2337,8 @@ static void E_ACELP_codearithp_fx( const Word16 v[], UWord32 *n, UWord32 *ps, Wo #ifdef BASOP_NOGLOB_DECLARE_LOCAL Flag Overflow = 0; Flag Carry = 0; + move32(); + move32(); #endif /* Collect different pulse positions to pos[], number of them to posno */ @@ -2096,6 +2354,7 @@ static void E_ACELP_codearithp_fx( const Word16 v[], UWord32 *n, UWord32 *ps, Wo move16(); } t = add( t, 1 ); + move16(); if ( sub( posno, NPMAXPT ) >= 0 ) { BREAK; @@ -2110,18 +2369,15 @@ static void E_ACELP_codearithp_fx( const Word16 v[], UWord32 *n, UWord32 *ps, Wo move16(); FOR( k = 0; k < posno; ++k ) { - sign = shr( v[shl( pos[k], 2 )], 9 ); /* sign with multiplicity */ - m = abs_s( sign ); /* multiplicity */ + sign = shr( v[( pos[k] * 4 )], 9 ); /* sign with multiplicity Q0*/ + m = abs_s( sign ); /* multiplicity */ nb_pulse = add( nb_pulse, m ); /* Code m-1 pulses */ FOR( i = 1; i < m; ++i ) { Carry = 0; -#ifdef BASOP_NOGLOB + move32(); s = L_add_co( s, pulsestostates[pos[k]][t], &Carry, &Overflow ); -#else /* BASOP_NOGLOB */ - s = L_add_c( s, pulsestostates[pos[k]][t] ); -#endif /* BASOP_NOGLOB */ t = add( t, 1 ); if ( sub( t, NPMAXPT ) > 0 ) { @@ -2133,41 +2389,35 @@ static void E_ACELP_codearithp_fx( const Word16 v[], UWord32 *n, UWord32 *ps, Wo /* We use L_add_c since we want to work with unsigned UWord32 */ /* Therefore, we have to clear carry */ Carry = 0; + move32(); s = L_lshl( s, 1 ); if ( sign < 0 ) { -#ifdef BASOP_NOGLOB s = L_add_co( s, 1, &Carry, &Overflow ); -#else /* BASOP_NOGLOB */ - s = L_add_c( s, 1 ); -#endif /* BASOP_NOGLOB */ } /* Code last pulse */ Carry = 0; -#ifdef BASOP_NOGLOB + move32(); s = L_add_co( s, pulsestostates[pos[k]][t], &Carry, &Overflow ); -#else /* BASOP_NOGLOB */ - s = L_add_c( s, pulsestostates[pos[k]][t] ); -#endif t = add( t, 1 ); } - *ps = s; + *ps = s; /*Q0*/ move32(); *n = L_deposit_l( 0 ); if ( nb_pulse ) { - *n = pulsestostates[NB_POS_FCB_4T][nb_pulse - 1]; + *n = pulsestostates[NB_POS_FCB_4T][nb_pulse - 1]; /*Q0*/ move32(); } - *p = nb_pulse; + *p = nb_pulse; /*Q0*/ move16(); return; } -void fcb_pulse_track_joint_fx( UWord16 *idxs, Word16 wordcnt, UWord32 *index_n, Word16 *pulse_num, Word16 track_num ) +void fcb_pulse_track_joint_fx( UWord16 *idxs /*Q0*/, Word16 wordcnt /*Q0*/, UWord32 *index_n /*Q0*/, Word16 *pulse_num /*Q0*/, Word16 track_num /*Q0*/ ) { Word16 hi_to_low[10]; UWord32 index, index_mask; @@ -2176,7 +2426,7 @@ void fcb_pulse_track_joint_fx( UWord16 *idxs, Word16 wordcnt, UWord32 *index_n, Word16 track, track_num1, pulse_num0, pulse_num1; Word16 indx_flag_2; - Copy( hi_to_low_tmpl, hi_to_low, 10 ); + Copy( hi_to_low_tmpl, hi_to_low, 10 ); /*Q0*/ indx_flag = 0; move16(); @@ -2196,7 +2446,7 @@ void fcb_pulse_track_joint_fx( UWord16 *idxs, Word16 wordcnt, UWord32 *index_n, { hi_to_low[7] = 9; move16(); - index_mask = 0xFFFFFF; + index_mask = 0xFFFFFF; /*Q0*/ move32(); } ELSE @@ -2206,34 +2456,35 @@ void fcb_pulse_track_joint_fx( UWord16 *idxs, Word16 wordcnt, UWord32 *index_n, hi_to_low[4] = 1; move16(); } - index_mask = L_shr( 0xFFFF, sub( 9, hi_to_low[4] ) ); + index_mask = L_shr( 0xFFFF, sub( 9, hi_to_low[4] ) ); /*Q0*/ } IF( GE_16( indx_flag_1, track_num ) ) { indx_tmp = L_deposit_l( 0 ); - index = L_shr( index_n[0], low_len[pulse_num[0]] ); + index = L_shr( index_n[0], low_len[pulse_num[0]] ); /*Q0*/ FOR( track = 1; track < track_num; track++ ) { - pulse_num0 = pulse_num[track - 1]; + pulse_num0 = pulse_num[track - 1]; /*Q0*/ move16(); - pulse_num1 = pulse_num[track]; + pulse_num1 = pulse_num[track]; /*Q0*/ move16(); - indx_tmp = L_lshr( index_n[track], low_len[pulse_num1] ); + indx_tmp = L_lshr( index_n[track], low_len[pulse_num1] ); /*Q0*/ /* index = index * indx_fact[pulse_num1] + indx_tmp; */ - index = UL_Mpy_32_32( index, UL_deposit_l( indx_fact[pulse_num1] ) ); + index = UL_Mpy_32_32( index, UL_deposit_l( indx_fact[pulse_num1] ) ); /*Q0*/ index = UL_addNsD( index, indx_tmp ); index_n[track - 1] = L_add( L_and( index_n[track - 1], low_mask[pulse_num0] ), - L_and( L_lshl( index, low_len[pulse_num0] ), index_mask ) ); + L_and( L_lshl( index, low_len[pulse_num0] ), index_mask ) ); /*Q0*/ index = L_lshr( index, hi_to_low[pulse_num0] ); } track_num1 = sub( track_num, 1 ); - pulse_num1 = pulse_num[track_num1]; + move16(); + pulse_num1 = pulse_num[track_num1]; /*Q0*/ move16(); index_n[track_num1] = L_and( L_add( L_and( index_n[track_num1], low_mask[pulse_num1] ), L_lshl( index, low_len[pulse_num1] ) ), - index_mask ); + index_mask ); /*Q0*/ index = L_lshr( index, hi_to_low[pulse_num1] ); IF( GE_16( indx_flag, track_num ) ) { @@ -2266,11 +2517,11 @@ void fcb_pulse_track_joint_fx( UWord16 *idxs, Word16 wordcnt, UWord32 *index_n, } ELSE { - index = index_n[0]; + index = index_n[0]; /*Q0*/ move32(); FOR( track = 1; track < 4; track++ ) { - pulse_num1 = pulse_num[track]; + pulse_num1 = pulse_num[track]; /*Q0*/ index = L_add( L_lshl( index, index_len[pulse_num1] ), index_n[track] ); } track = 0; diff --git a/lib_enc/enc_acelp_tcx_main.c b/lib_enc/enc_acelp_tcx_main.c deleted file mode 100644 index fc894ba6cc3b0f6891e5522d7bdaa893786ada84..0000000000000000000000000000000000000000 --- a/lib_enc/enc_acelp_tcx_main.c +++ /dev/null @@ -1,41 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include "prot.h" -#include "rom_com.h" -#include "wmc_auto.h" diff --git a/lib_enc/enc_acelp_tcx_main_fx.c b/lib_enc/enc_acelp_tcx_main_fx.c index 0ee3c51856af219d536d57f65af0ff536d9fa766..3498321646e22d98a77ebd738db6e55f43fdee03 100644 --- a/lib_enc/enc_acelp_tcx_main_fx.c +++ b/lib_enc/enc_acelp_tcx_main_fx.c @@ -18,15 +18,15 @@ * encoder function for coding ACELP/TCX *--------------------------------------------------------------------*/ void enc_acelp_tcx_main_fx( - const Word16 new_samples[], /* i : new samples */ - Encoder_State *st, /* i/o: encoder state structure */ - Word16 Aw[NB_SUBFR16k * ( M + 1 )], /* i : weighted A(z) unquant. for subframes*/ - const Word16 lsp_new[M], /* i : LSPs at the end of the frame */ - const Word16 lsp_mid[M], /* i : LSPs at the middle of the frame */ - Word32 bwe_exc_extended[], /* i/o: bandwidth extended excitation */ - Word16 *voice_factors, /* o : voicing factors */ - Word16 pitch_buf[], /* o : floating pitch for each subframe */ - Word16 vad_hover_flag, /* i : VAD hangover flag */ + const Word16 new_samples[], /* i : new samples Q15*/ + Encoder_State *st, /* i/o: encoder state structure */ + Word16 Aw[NB_SUBFR16k * ( M + 1 )], /* i : weighted A(z) unquant. for subframes Q12*/ + const Word16 lsp_new[M], /* i : LSPs at the end of the frame Q15*/ + const Word16 lsp_mid[M], /* i : LSPs at the middle of the frame Q15*/ + Word32 bwe_exc_extended[], /* i/o: bandwidth extended excitation Q_new*/ + Word16 *voice_factors, /* o : voicing factors Q15*/ + Word16 pitch_buf[], /* o : floating pitch for each subframe Q6*/ + Word16 vad_hover_flag, /* i : VAD hangover flag Q0*/ Word16 *Q_new, Word16 *shift ) { @@ -39,7 +39,7 @@ void enc_acelp_tcx_main_fx( IF( EQ_16( st->last_core, ACELP_CORE ) ) { set16_fx( old_bwe_exc + PIT16k_MAX * 2, 0, ( ( L_FRAME16k + 1 ) + L_SUBFR16k ) * 2 ); - Copy( hBWE_TD->old_bwe_exc_fx, old_bwe_exc, PIT16k_MAX * 2 ); + Copy( hBWE_TD->old_bwe_exc_fx, old_bwe_exc, PIT16k_MAX * 2 ); /*Q_exc*/ } ELSE { @@ -74,7 +74,7 @@ void enc_acelp_tcx_main_fx( non_linearity_fx( ptr_bwe_exc, bwe_exc_extended, L_FRAME32k, &hBWE_TD->bwe_non_lin_prev_scale_fx, *Q_new, st->coder_type, voice_factors, st->L_frame ); /* update the old BWE exe memory */ - Copy( &old_bwe_exc[L_FRAME32k], hBWE_TD->old_bwe_exc_fx, PIT16k_MAX * 2 ); + Copy( &old_bwe_exc[L_FRAME32k], hBWE_TD->old_bwe_exc_fx, PIT16k_MAX * 2 ); /*Q_exc*/ } ELSE { diff --git a/lib_enc/enc_acelpx.c b/lib_enc/enc_acelpx.c deleted file mode 100644 index 661cc4b7b44a35c09c0ee29a47f1b5d01df6c3fe..0000000000000000000000000000000000000000 --- a/lib_enc/enc_acelpx.c +++ /dev/null @@ -1,42 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include -#include "options.h" -#include "prot.h" -#include "rom_enc.h" -#include "wmc_auto.h" diff --git a/lib_enc/enc_acelpx_fx.c b/lib_enc/enc_acelpx_fx.c index af773cac453fa0e258ffb57e8936fc6cd0c5b302..f18da2ef27024789870875f55f2b3f04c1b01b1c 100644 --- a/lib_enc/enc_acelpx_fx.c +++ b/lib_enc/enc_acelpx_fx.c @@ -19,13 +19,13 @@ /*--------------------------------------------------------------------------------------* * E_ACELP_update_cor *--------------------------------------------------------------------------------------*/ -static void E_ACELP_update_cor( - const Word16 pos[], /* i */ - Word16 nb_pulse, /* i */ - const Word16 sign[], /* i */ - const Word16 R[], /* i */ - const Word16 cor_in[], /* i */ - Word16 cor_out[] /* o */ +static void E_ACELP_update_cor_fx( + const Word16 pos[], /* i Q0*/ + Word16 nb_pulse, /* i Q0*/ + const Word16 sign[], /* i Q13*/ + const Word16 R[], /* i Q9+scale*/ + const Word16 cor_in[], /* i Q9*/ + Word16 cor_out[] /* o Q9*/ ) { Word16 sign_x, sign_y; @@ -36,9 +36,9 @@ static void E_ACELP_update_cor( { /* Update product of autocorrelation and already fixed pulses. with the * two newly found ones */ - sign_x = sign[pos[0]]; + sign_x = sign[pos[0]]; /*Q13*/ move16(); - sign_y = sign[pos[1]]; + sign_y = sign[pos[1]]; /*Q13*/ move16(); IF( s_xor( sign_x, sign_y ) < 0 ) @@ -50,24 +50,24 @@ static void E_ACELP_update_cor( i = 0; move16(); } - pRx = R - pos[i]; - pRy = R - pos[1 - i]; + pRx = R - pos[i]; /*Q9+scale*/ + pRy = R - pos[1 - i]; /*Q9+scale*/ /* different sign x and y */ FOR( i = 0; i < L_SUBFR; i++ ) { tmp = sub( pRx[i], pRy[i] ); if ( cor_in != NULL ) { - tmp = add( tmp, cor_in[i] ); + tmp = add( tmp, cor_in[i] ); /* Q9 */ } - cor_out[i] = tmp; + cor_out[i] = tmp; /* Q9 */ move16(); } } ELSE { - pRx = R - pos[0]; - pRy = R - pos[1]; + pRx = R - pos[0]; /*Q9+scale*/ + pRy = R - pos[1]; /*Q9+scale*/ IF( sign_x > 0 ) { /* sign x and y is positive */ @@ -76,9 +76,9 @@ static void E_ACELP_update_cor( tmp = add( pRx[i], pRy[i] ); if ( cor_in != NULL ) { - tmp = add( tmp, cor_in[i] ); + tmp = add( tmp, cor_in[i] ); /* Q9 */ } - cor_out[i] = tmp; + cor_out[i] = tmp; /* Q9 */ move16(); } } @@ -90,13 +90,13 @@ static void E_ACELP_update_cor( tmp = add( pRx[i], pRy[i] ); if ( cor_in != NULL ) { - tmp = sub( cor_in[i], tmp ); + tmp = sub( cor_in[i], tmp ); /* Q9 */ } if ( cor_in == NULL ) { tmp = negate( tmp ); } - cor_out[i] = tmp; + cor_out[i] = tmp; /* Q9 */ move16(); } } @@ -104,8 +104,8 @@ static void E_ACELP_update_cor( } ELSE IF( EQ_16( nb_pulse, 4 ) ) { - E_ACELP_update_cor( pos, 2, sign, R, cor_in, cor_out ); - E_ACELP_update_cor( pos + 2, 2, sign, R, cor_out, cor_out ); + E_ACELP_update_cor_fx( pos, 2, sign, R, cor_in, cor_out ); + E_ACELP_update_cor_fx( pos + 2, 2, sign, R, cor_out, cor_out ); } else { @@ -116,20 +116,20 @@ static void E_ACELP_update_cor( * E_ACELP_2pulse_searchx * Iterations: nb_pos_ix*16 *--------------------------------------------------------------------------------------*/ -static void E_ACELP_2pulse_searchx( - const Word16 nb_pos_ix, - const Word16 track_x, - const Word16 track_y, - Word16 *R, - Word16 *ps, - Word16 *alp, - Word16 *ix, - Word16 *iy, - Word16 dn[], - Word16 *dn2, - Word16 cor[], - Word16 sign[], - Word16 sign_val_2 ) +static void E_ACELP_2pulse_searchx_fx( + const Word16 nb_pos_ix, /*Q0*/ + const Word16 track_x, /*Q0*/ + const Word16 track_y, /*Q0*/ + Word16 *R, /*Q9+scale*/ + Word16 *ps, /*Qdn*/ + Word16 *alp, /*Q6*/ + Word16 *ix, /*Q0*/ + Word16 *iy, /*Q0*/ + Word16 dn[], /*Qdn*/ + Word16 *dn2, /*Q0*/ + Word16 cor[], /*Q9*/ + Word16 sign[], /*Q13*/ + Word16 sign_val_2 /*Q15*/ ) { Word16 i, x; Word32 y; @@ -141,21 +141,18 @@ static void E_ACELP_2pulse_searchx( Word16 sqk[2], alpk[2], ik; #ifdef BASOP_NOGLOB_DECLARE_LOCAL Flag Overflow = 0; + move32(); #endif /* eight dn2 max positions per track */ - pos_x = &dn2[shl( track_x, 3 )]; + pos_x = &dn2[( track_x * 8 )]; /*Qdn*/ move16(); /* save these to limit memory searches */ - ps0 = *ps; + ps0 = *ps; /*Qdn*/ move16(); /*alp0 = *alp + 2.0f*R[0]; move16();*/ - alp0 = L_deposit_h( *alp ); /* Qalp = Q_R*Q_signval */ -#ifdef BASOP_NOGLOB - alp0 = L_mac_sat( alp0, R[0], sign_val_2 ); -#else - alp0 = L_mac( alp0, R[0], sign_val_2 ); -#endif + alp0 = L_deposit_h( *alp ); /* Qalp = Q_R*Q_signval */ + alp0 = L_mac_sat( alp0, R[0], sign_val_2 ); /*Q9+scale+Q15*/ /* Ensure that in the loop below s > 0 in the first iteration, the actual values do not matter. */ sqk[0] = -1; @@ -164,17 +161,13 @@ static void E_ACELP_2pulse_searchx( move16(); x = pos_x[0]; move16(); - sgnx = sign[track_y]; + sgnx = sign[track_y]; /*Q13*/ move16(); if ( sign[x] < 0 ) { sgnx = negate( sgnx ); } -#ifdef BASOP_NOGLOB if ( mac_ro( L_mac_o( L_mac_o( alp0, cor[x], sign[x], &Overflow ), cor[track_y], sign[track_y], &Overflow ), R[track_y - x], sgnx, &Overflow ) < 0 ) -#else - if ( mac_r( L_mac( L_mac( alp0, cor[x], sign[x] ), cor[track_y], sign[track_y] ), R[track_y - x], sgnx ) < 0 ) -#endif { sqk[0] = 1; @@ -183,38 +176,26 @@ static void E_ACELP_2pulse_searchx( ik = 0; move16(); - xy_save = L_mac0( L_deposit_l( track_y ), track_x, L_SUBFR ); + xy_save = L_mac0( L_deposit_l( track_y ), track_x, L_SUBFR ); /*Q0*/ /* loop track 1 */ FOR( i = 0; i < nb_pos_ix; i++ ) { - x = pos_x[i]; + x = pos_x[i]; /*Q0*/ move16(); - sgnx = sign[x]; + sgnx = sign[x]; /*Q13*/ move16(); /* dn[x] has only nb_pos_ix positions saved */ /*ps1 = ps0 + dn[x]; INDIRECT(1);ADD(1);*/ -#ifdef BASOP_NOGLOB - ps1 = add_sat( ps0, dn[x] ); -#else - ps1 = add( ps0, dn[x] ); -#endif + ps1 = add_sat( ps0, dn[x] ); /*Qdn*/ /*alp1 = alp0 + 2*sgnx*cor[x]; INDIRECT(1);MULT(1); MAC(1);*/ -#ifdef BASOP_NOGLOB alp1 = L_mac_o( alp0, cor[x], sgnx, &Overflow ); /* Qalp = (Q_R=Q_cor)*Q_signval */ -#else - alp1 = L_mac( alp0, cor[x], sgnx ); /* Qalp = (Q_R=Q_cor)*Q_signval */ -#endif - pR = R - x; + pR = R - x; /*Q9+scale*/ FOR( y = track_y; y < L_SUBFR; y += 4 ) { /*ps2 = ps1 + dn[y]; ADD(1);*/ -#ifdef BASOP_NOGLOB - ps2 = add_sat( ps1, dn[y] ); -#else - ps2 = add( ps1, dn[y] ); -#endif + ps2 = add_sat( ps1, dn[y] ); /*Qdn*/ /*alp2 = alp1 + 2.0f*sign[y]*(cor[y] + sgnx*pR[y]); MULT(1); MAC(2);*/ /*alp2 = alp1 + 2.0f*sign[y]*cor[y] + 2.0f*sign[y]*sgnx*pR[y]; MULT(1); MAC(2);*/ assert( sign[y] == sign_val_2 || sign[y] == -sign_val_2 ); @@ -223,49 +204,33 @@ static void E_ACELP_2pulse_searchx( assert( sgnx != 0 ); alp2_16 = 0; -#ifdef BASOP_NOGLOB alp2 = L_mac_o( alp1, cor[y], sign[y], &Overflow ); /* Qalp = (Q_R=Q_cor)*Q_signval */ -#else - alp2 = L_mac( alp1, cor[y], sign[y] ); /* Qalp = (Q_R=Q_cor)*Q_signval */ -#endif if ( sgnx > 0 ) { -#ifdef BASOP_NOGLOB alp2_16 = mac_ro( alp2, pR[y], sign[y], &Overflow ); /* Qalp = (Q_R=Q_cor)*Q_signval */ -#else - alp2_16 = mac_r( alp2, pR[y], sign[y] ); /* Qalp = (Q_R=Q_cor)*Q_signval */ -#endif } if ( sgnx < 0 ) { -#ifdef BASOP_NOGLOB alp2_16 = msu_ro( alp2, pR[y], sign[y], &Overflow ); /* Qalp = (Q_R=Q_cor)*Q_signval */ -#else - alp2_16 = msu_r( alp2, pR[y], sign[y] ); /* Qalp = (Q_R=Q_cor)*Q_signval */ -#endif } - alpk[1 - ik] = alp2_16; + alpk[1 - ik] = alp2_16; /* Qalp */ move16(); /*sq = ps2 * ps2; MULT(1);*/ sq = mult_r( ps2, ps2 ); /* (3+3)Q -> 6Q9 */ - sqk[1 - ik] = sq; + sqk[1 - ik] = sq; /* Q9 */ move16(); /*s = (alpk * sq) - (sqk * alp2); MULT(1);MAC(1);*/ -#ifdef BASOP_NOGLOB s = L_msu_o( L_mult( alpk[ik], sq ), sqk[ik], alp2_16, &Overflow ); /* Q_sq = Q_sqk, Q_alpk = Q_alp */ -#else - s = L_msu( L_mult( alpk[ik], sq ), sqk[ik], alp2_16 ); /* Q_sq = Q_sqk, Q_alpk = Q_alp */ -#endif if ( s > 0 ) { ik = sub( 1, ik ); } if ( s > 0 ) { - xy_save = L_mac0( y, x, L_SUBFR ); + xy_save = L_mac0( y, x, L_SUBFR ); /* Q0 */ } assert( ( ( s >= 0 && i == 0 && y == track_y ) ) || ( y > track_y ) || ( i > 0 ) ); } @@ -273,21 +238,21 @@ static void E_ACELP_2pulse_searchx( ps1 = extract_l( xy_save ); pos[1] = s_and( ps1, L_SUBFR - 1 ); move16(); - pos[0] = lshr( ps1, 6 ); + pos[0] = lshr( ps1, 6 ); /* Q0 */ move16(); /* Update numerator */ - *ps = add( add( ps0, dn[pos[0]] ), dn[pos[1]] ); + *ps = add( add( ps0, dn[pos[0]] ), dn[pos[1]] ); /* Qdn */ move16(); /* Update denominator */ - *alp = alpk[ik]; + *alp = alpk[ik]; /* Q_alp */ move16(); - E_ACELP_update_cor( pos, 2, sign, R, cor, cor ); + E_ACELP_update_cor_fx( pos, 2, sign, R, cor, cor ); - *ix = pos[0]; + *ix = pos[0]; /* Q0 */ move16(); - *iy = pos[1]; + *iy = pos[1]; /* Q0 */ move16(); assert( ( ( pos[0] & 3 ) == track_x ) && ( ( pos[1] & 3 ) == track_y ) ); /* sanity check */ @@ -296,16 +261,16 @@ static void E_ACELP_2pulse_searchx( /*--------------------------------------------------------------------------------------* * E_ACELP_1pulse_searchx *--------------------------------------------------------------------------------------*/ -static void E_ACELP_1pulse_searchx( - UWord8 tracks[2], - Word16 *R, - Word16 *ps, - Word16 *alp, - Word16 *ix, - Word16 dn[], - Word16 cor[], - Word16 sign[], - Word16 sign_val_1 ) +static void E_ACELP_1pulse_searchx_fx( + UWord8 tracks[2], /*Q0*/ + Word16 *R, /*Q9+scale*/ + Word16 *ps, /* Qdn */ + Word16 *alp, /*Q6*/ + Word16 *ix, /*Q0*/ + Word16 dn[], /* Qdn */ + Word16 cor[], /* Q9 */ + Word16 sign[], /* Q13 */ + Word16 sign_val_1 /* Q15 */ ) { Word16 x, x_save = 0; Word16 ps0; @@ -315,14 +280,16 @@ static void E_ACELP_1pulse_searchx( Word32 s; Word16 ntracks, t; Word16 sqk[2], alpk[2], ik; + move16(); #ifdef BASOP_NOGLOB_DECLARE_LOCAL Flag Overflow = 0; + move32(); #endif /* save these to limit memory searches */ /*alp0 = *alp + R[0]; INDIRECT(1);*/ - ps0 = *ps; + ps0 = *ps; /* Qdn */ move16(); - alp0 = L_deposit_h( *alp ); + alp0 = L_deposit_h( *alp ); /* Q22 */ alp0 = L_mac( alp0, R[0], sign_val_1 ); /* Qalp = (Q_R=Q_cor)*Q_signval */ /* Ensure that in the loop below s > 0 in the first iteration, the actual values do not matter. */ @@ -332,20 +299,17 @@ static void E_ACELP_1pulse_searchx( sqk[0] = -1; ik = 0; move16(); -#ifdef BASOP_NOGLOB if ( mac_ro( alp0, cor[tracks[0]], sign[tracks[0]], &Overflow ) < 0 ) -#else - if ( mac_r( alp0, cor[tracks[0]], sign[tracks[0]] ) < 0 ) -#endif { sqk[0] = 1; move16(); } - x_save = tracks[0]; + x_save = tracks[0]; /* Q0 */ move16(); ntracks = 1; + move16(); if ( NE_16( tracks[1], tracks[0] ) ) { ntracks = 2; @@ -359,26 +323,18 @@ static void E_ACELP_1pulse_searchx( ps1 = add( ps0, dn[x] ); /* alp1 = alp0 + 2*sign[x]*cor[x]; MAC(1); MULT(1);*/ assert( sign[x] == sign_val_1 << 1 || sign[x] == -( sign_val_1 << 1 ) ); -#ifdef BASOP_NOGLOB alp1 = mac_ro( alp0, cor[x], sign[x], &Overflow ); /* Qalp = (Q_R=Q_cor)*Q_signval */ -#else - alp1 = mac_r( alp0, cor[x], sign[x] ); /* Qalp = (Q_R=Q_cor)*Q_signval */ -#endif - alpk[1 - ik] = alp1; + alpk[1 - ik] = alp1; /* Qalp */ move16(); /*sq = ps1 * ps1; MULT(1);*/ sq = mult_r( ps1, ps1 ); /* 6Q9 */ - sqk[1 - ik] = sq; + sqk[1 - ik] = sq; /* Q9 */ move16(); /*s = (alpk[ik] * sq) - (sqk[ik] * alp1); MULT(1);MAC(1);*/ -#ifdef BASOP_NOGLOB - s = L_msu_o( L_mult_o( alpk[ik], sq, &Overflow ), sqk[ik], alp1, &Overflow ); -#else - s = L_msu( L_mult( alpk[ik], sq ), sqk[ik], alp1 ); -#endif + s = L_msu_o( L_mult_o( alpk[ik], sq, &Overflow ), sqk[ik], alp1, &Overflow ); /* Q9+Qalp+1 */ if ( s > 0 ) { ik = sub( 1, ik ); @@ -392,11 +348,11 @@ static void E_ACELP_1pulse_searchx( } } - *ps = add( ps0, dn[x_save] ); + *ps = add( ps0, dn[x_save] ); /* Qdn */ move16(); - *alp = alpk[ik]; + *alp = alpk[ik]; /* Qalp */ move16(); - *ix = x_save; + *ix = x_save; /* Q0 */ move16(); } @@ -406,12 +362,12 @@ static void E_ACELP_1pulse_searchx( * Algorithm is identical to traditional covariance method *--------------------------------------------------------------------------------------*/ void E_ACELP_4tsearchx_fx( - Word16 dn[], - const Word16 cn[], - Word16 Rw[], - Word16 code[], + Word16 dn[], /*Qdn*/ + const Word16 cn[], /*Q_new*/ + Word16 Rw[], /*Q9*/ + Word16 code[], /*Q9*/ const PulseConfig *config, - Word16 ind[] ) + Word16 ind[] /*Q0*/ ) { Word16 sign[L_SUBFR], vec[L_SUBFR]; Word16 cor[L_SUBFR]; @@ -427,8 +383,11 @@ void E_ACELP_4tsearchx_fx( Word16 scale; Word16 sign_val_1, sign_val_2; Word16 nb_pulse, nb_pulse_m2; + move16(); + move16(); ps = 0; /* to avoid compilation warnings */ + move16(); alp = config->alp; /* Q13 */ @@ -447,10 +406,10 @@ void E_ACELP_4tsearchx_fx( scale = 0; move16(); - s = L_mult0( Rw[0], Rw[0] ); + s = L_mult0( Rw[0], Rw[0] ); /*Q18*/ FOR( i = 1; i < L_SUBFR; i++ ) { - s = L_mac0( s, Rw[i], Rw[i] ); + s = L_mac0( s, Rw[i], Rw[i] ); /*Q18*/ } if ( s_and( (Word16) GE_16( nb_pulse, 9 ), (Word16) GT_32( s, 0x800000 ) ) ) { @@ -493,7 +452,7 @@ void E_ACELP_4tsearchx_fx( /* Set up autocorrelation vector */ R = R_buf + L_SUBFR - 1; - Copy_Scale_sig( Rw, R, L_SUBFR, scale ); + Copy_Scale_sig( Rw, R, L_SUBFR, scale ); /*Q9+scale*/ FOR( k = 1; k < L_SUBFR; k++ ) { R[-k] = R[k]; @@ -501,13 +460,13 @@ void E_ACELP_4tsearchx_fx( } /* Sign value */ - sign_val_2 = 0x2000; + sign_val_2 = 0x2000; /* Q15 */ move16(); if ( GE_16( nb_pulse, 24 ) ) { - sign_val_2 = shr( sign_val_2, 1 ); + sign_val_2 = shr( sign_val_2, 1 ); /* Q15 */ } - sign_val_1 = shr( sign_val_2, 1 ); + sign_val_1 = shr( sign_val_2, 1 ); /* Q15 */ /* * Find sign for each pulse position. @@ -535,7 +494,7 @@ void E_ACELP_4tsearchx_fx( E_ACELP_setup_pulse_search_pos( config, k, ipos ); /* index to first non-fixed position */ - pos = config->fixedpulses; + pos = config->fixedpulses; /* Q0 */ move16(); IF( config->fixedpulses == 0 ) /* 1100, 11, 1110, 1111, 2211 */ @@ -553,23 +512,23 @@ void E_ACELP_4tsearchx_fx( /* set fixed positions */ FOR( i = 0; i < pos; ++i ) { - ind[i] = pos_max[ipos[i]]; + ind[i] = pos_max[ipos[i]]; /* Q0 */ move16(); } /* multiplication of autocorrelation with signed fixed pulses */ - E_ACELP_update_cor( ind, config->fixedpulses, sign, R, NULL, cor ); + E_ACELP_update_cor_fx( ind, config->fixedpulses, sign, R, NULL, cor ); /* normalisation contribution of fixed part */ - s = L_mult0( cor[ind[0]], sign[ind[0]] ); - ps = dn[ind[0]]; + s = L_mult0( cor[ind[0]], sign[ind[0]] ); /* Q22 */ + ps = dn[ind[0]]; /* Qdn */ move16(); FOR( i = 1; i < pos; ++i ) { - s = L_mac0( s, cor[ind[i]], sign[ind[i]] ); /*Q12+Q9+1=Q6 */ - ps = add( ps, dn[ind[i]] ); + s = L_mac0( s, cor[ind[i]], sign[ind[i]] ); /*Q12+Q9+1=Q22 */ + ps = add( ps, dn[ind[i]] ); /* Qdn */ } - alp = round_fx( s ); /*mac0 >>1 sign = 2*/ + alp = round_fx( s ); /*mac0 >>1 sign = 2 Q6*/ } /* other stages of 2 pulses */ @@ -585,13 +544,13 @@ void E_ACELP_4tsearchx_fx( * Each pulse can have 16 possible positions. */ - E_ACELP_2pulse_searchx( config->nbpos[st], ipos[j], ipos[j + 1], R, &ps, &alp, - &ind[j], &ind[j + 1], dn, dn2_pos, cor, sign, sign_val_2 ); + E_ACELP_2pulse_searchx_fx( config->nbpos[st], ipos[j], ipos[j + 1], R, &ps, &alp, + &ind[j], &ind[j + 1], dn, dn2_pos, cor, sign, sign_val_2 ); } ELSE /* single pulse search */ { - E_ACELP_1pulse_searchx( &ipos[j], R, &ps, &alp, - &ind[j], dn, cor, sign, sign_val_1 ); + E_ACELP_1pulse_searchx_fx( &ipos[j], R, &ps, &alp, + &ind[j], dn, cor, sign, sign_val_1 ); } @@ -600,10 +559,10 @@ void E_ACELP_4tsearchx_fx( /* memorise the best codevector */ /*ps2 = ps * ps; MULT(1);*/ - ps2 = mult( ps, ps ); + ps2 = mult( ps, ps ); /* 2*Qdn+1 */ /*s = (alpk * ps2) - (ps2k * alp); MULT(2);ADD(1);*/ - s = L_msu( L_mult( alpk, ps2 ), ps2k, alp ); + s = L_msu( L_mult( alpk, ps2 ), ps2k, alp ); /* 2*Qdn+8 */ IF( s > 0 ) { @@ -611,7 +570,7 @@ void E_ACELP_4tsearchx_fx( move16(); alpk = alp; move16(); - Copy( ind, codvec, nb_pulse ); + Copy( ind, codvec, nb_pulse ); /* Q0 */ } } @@ -623,12 +582,12 @@ void E_ACELP_4tsearchx_fx( } void E_ACELP_4tsearchx_ivas_fx( - Word16 dn[], - const Word16 cn[], - Word16 Rw[], - Word16 code[], + Word16 dn[], /*Qdn*/ + const Word16 cn[], /*Q_new*/ + Word16 Rw[], /*Q9*/ + Word16 code[], /*Q9*/ const PulseConfig *config, - Word16 ind[], + Word16 ind[], /*Q0*/ Word16 element_mode ) { Word16 sign[L_SUBFR], vec[L_SUBFR]; @@ -670,10 +629,10 @@ void E_ACELP_4tsearchx_ivas_fx( scale = 0; move16(); - s = L_mult0( Rw[0], Rw[0] ); + s = L_mult0( Rw[0], Rw[0] ); /* Q18 */ FOR( i = 1; i < L_SUBFR; i++ ) { - s = L_mac0( s, Rw[i], Rw[i] ); + s = L_mac0( s, Rw[i], Rw[i] ); /* Q18 */ } if ( s_and( (Word16) GE_16( nb_pulse, 9 ), (Word16) GT_32( s, 0x800000 ) ) ) { @@ -716,7 +675,7 @@ void E_ACELP_4tsearchx_ivas_fx( /* Set up autocorrelation vector */ R = R_buf + L_SUBFR - 1; - Copy_Scale_sig( Rw, R, L_SUBFR, scale ); + Copy_Scale_sig( Rw, R, L_SUBFR, scale ); /* Q9 + scale */ FOR( k = 1; k < L_SUBFR; k++ ) { R[-k] = R[k]; @@ -724,13 +683,13 @@ void E_ACELP_4tsearchx_ivas_fx( } /* Sign value */ - sign_val_2 = 0x2000; + sign_val_2 = 0x2000; /* Q15 */ move16(); if ( GE_16( nb_pulse, 24 ) ) { - sign_val_2 = shr( sign_val_2, 1 ); + sign_val_2 = shr( sign_val_2, 1 ); /* Q15 */ } - sign_val_1 = shr( sign_val_2, 1 ); + sign_val_1 = shr( sign_val_2, 1 ); /* Q15 */ /* * Find sign for each pulse position. @@ -758,7 +717,7 @@ void E_ACELP_4tsearchx_ivas_fx( E_ACELP_setup_pulse_search_pos( config, k, ipos ); /* index to first non-fixed position */ - pos = config->fixedpulses; + pos = config->fixedpulses; /* Q0 */ move16(); IF( config->fixedpulses == 0 ) /* 1100, 11, 1110, 1111, 2211 */ @@ -776,23 +735,23 @@ void E_ACELP_4tsearchx_ivas_fx( /* set fixed positions */ FOR( i = 0; i < pos; ++i ) { - ind[i] = pos_max[ipos[i]]; + ind[i] = pos_max[ipos[i]]; /* Q0 */ move16(); } /* multiplication of autocorrelation with signed fixed pulses */ - E_ACELP_update_cor( ind, config->fixedpulses, sign, R, NULL, cor ); + E_ACELP_update_cor_fx( ind, config->fixedpulses, sign, R, NULL, cor ); /* normalisation contribution of fixed part */ - s = L_mult0( cor[ind[0]], sign[ind[0]] ); - ps = dn[ind[0]]; + s = L_mult0( cor[ind[0]], sign[ind[0]] ); /* Q22 */ + ps = dn[ind[0]]; /* Qdn */ move16(); FOR( i = 1; i < pos; ++i ) { - s = L_mac0( s, cor[ind[i]], sign[ind[i]] ); /*Q12+Q9+1=Q6 */ + s = L_mac0( s, cor[ind[i]], sign[ind[i]] ); /*Q12+Q9+1=Q22 */ ps = add( ps, dn[ind[i]] ); } - alp = round_fx( s ); /*mac0 >>1 sign = 2*/ + alp = round_fx( s ); /*mac0 >>1 sign = 2 Q6*/ } /* other stages of 2 pulses */ @@ -808,24 +767,24 @@ void E_ACELP_4tsearchx_ivas_fx( * Each pulse can have 16 possible positions. */ - E_ACELP_2pulse_searchx( config->nbpos[st], ipos[j], ipos[j + 1], R, &ps, &alp, - &ind[j], &ind[j + 1], dn, dn2_pos, cor, sign, sign_val_2 ); + E_ACELP_2pulse_searchx_fx( config->nbpos[st], ipos[j], ipos[j + 1], R, &ps, &alp, + &ind[j], &ind[j + 1], dn, dn2_pos, cor, sign, sign_val_2 ); } ELSE /* single pulse search */ { - E_ACELP_1pulse_searchx( &ipos[j], R, &ps, &alp, - &ind[j], dn, cor, sign, sign_val_1 ); + E_ACELP_1pulse_searchx_fx( &ipos[j], R, &ps, &alp, + &ind[j], dn, cor, sign, sign_val_1 ); } IF( GT_16( alp, ONE_IN_Q14 ) ) { alp = shr( alp, 1 ); - Scale_sig( cor, L_SUBFR, -1 ); - Scale_sig( R_buf, 2 * L_SUBFR - 1, -1 ); + Scale_sig( cor, L_SUBFR, -1 ); /*Q8*/ + Scale_sig( R_buf, 2 * L_SUBFR - 1, -1 ); /*Q8+scale*/ #ifndef MSAN_FIX Scale_sig( dn, 2 * L_SUBFR, -1 ); #else - Scale_sig( dn, L_SUBFR, -1 ); + Scale_sig( dn, L_SUBFR, -1 ); /*Qdn-1*/ #endif } @@ -835,10 +794,10 @@ void E_ACELP_4tsearchx_ivas_fx( /* memorise the best codevector */ /*ps2 = ps * ps; MULT(1);*/ - ps2 = mult( ps, ps ); + ps2 = mult( ps, ps ); /* 2*Qdn+1 */ /*s = (alpk * ps2) - (ps2k * alp); MULT(2);ADD(1);*/ - s = L_msu( L_mult( alpk, ps2 ), ps2k, alp ); + s = L_msu( L_mult( alpk, ps2 ), ps2k, alp ); /* 2*Qdn+8 */ IF( s > 0 ) { @@ -848,7 +807,7 @@ void E_ACELP_4tsearchx_ivas_fx( move16(); alpk = alp; move16(); - Copy( ind, codvec, nb_pulse ); + Copy( ind, codvec, nb_pulse ); /*Q0*/ } } @@ -868,9 +827,9 @@ void E_ACELP_4tsearchx_ivas_fx( FOR( k = 0; k < config->nb_pulse; k++ ) { - i = codvec[k]; /* read pulse position */ + i = codvec[k]; /* read pulse position Q0*/ move16(); - val = sign[i]; /* read sign */ + val = sign[i]; /* read sign Q13*/ move16(); index = shr( i, 2 ); /* pos of pulse (0..15) */ @@ -878,16 +837,16 @@ void E_ACELP_4tsearchx_ivas_fx( track = s_and( i, 3 ); IF( L_mult0( val, psk ) > 0 ) { - code[i] = add( code[i], ONE_IN_Q9 /*1.0f*/ ); + code[i] = add( code[i], ONE_IN_Q9 /*1.0f*/ ); /* Q9 */ move16(); - codvec[k] = add( codvec[k], 2 * L_SUBFR ); + codvec[k] = add( codvec[k], 2 * L_SUBFR ); /* Q0 */ move16(); } ELSE { - code[i] = sub( code[i], ONE_IN_Q9 /*1.0f*/ ); + code[i] = sub( code[i], ONE_IN_Q9 /*1.0f*/ ); /* Q9 */ move16(); - index = add( index, 16 ); + index = add( index, 16 ); /* Q0 */ } i = imult1616( track, NPMAXPT ); diff --git a/lib_enc/enc_amr_wb.c b/lib_enc/enc_amr_wb.c deleted file mode 100644 index 0fe8682daace6673130ca2ca05de2a188e8e2ae0..0000000000000000000000000000000000000000 --- a/lib_enc/enc_amr_wb.c +++ /dev/null @@ -1,42 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include "cnst.h" -#include "prot.h" -#include "rom_com.h" -#include "wmc_auto.h" diff --git a/lib_enc/enc_amr_wb_fx.c b/lib_enc/enc_amr_wb_fx.c index 5d5ee6c48af075fa34ded5aadf29b936f275607e..08a20bbb9b8effbccc2227ae263e1c7a0d32ba4d 100644 --- a/lib_enc/enc_amr_wb_fx.c +++ b/lib_enc/enc_amr_wb_fx.c @@ -18,16 +18,16 @@ *-------------------------------------------------------------------*/ void encod_amr_wb_fx( Encoder_State *st, /* i/o: state structure */ - const Word16 speech[], /* i : input speech */ - const Word16 Aw[], /* i : weighted A(z) unquantized for subframes */ - const Word16 Aq[], /* i : 12k8 Lp coefficient */ - const Word16 *res, /* i : residual signal */ - Word16 *syn, /* i/o: core synthesis */ - Word16 *exc, /* i/o: current non-enhanced excitation */ - Word16 *exc2, /* i/o: current enhanced excitation */ - Word16 *pitch_buf, /* i/o: floating pitch values for each subframe */ - Word16 hf_gain_fx[NB_SUBFR], /* o : decoded HF gain */ - const Word16 *speech16k_fx, /* i : input speech @16kHz */ + const Word16 speech[], /* i : input speech Q_new-1*/ + const Word16 Aw[], /* i : weighted A(z) unquantized for subframes Q12*/ + const Word16 Aq[], /* i : 12k8 Lp coefficient Q12*/ + const Word16 *res, /* i : residual signal Q_new*/ + Word16 *syn, /* i/o: core synthesis st->Q_syn*/ + Word16 *exc, /* i/o: current non-enhanced excitation Q_new*/ + Word16 *exc2, /* i/o: current enhanced excitation Q_new*/ + Word16 *pitch_buf, /* i/o: floating pitch values for each subframe Q6*/ + Word16 hf_gain_fx[NB_SUBFR], /* o : decoded HF gain Q0*/ + const Word16 *speech16k_fx, /* i : input speech @16kHz Qx*/ Word16 shift, Word16 Q_new ) { @@ -66,6 +66,7 @@ void encod_amr_wb_fx( LPD_state_HANDLE hLPDmem = st->hLPDmem; #ifdef BASOP_NOGLOB_DECLARE_LOCAL Flag Overflow = 0; + move32(); #endif /*------------------------------------------------------------------* @@ -84,31 +85,33 @@ void encod_amr_wb_fx( unbits = 0; move16(); - p_Aw = Aw; - p_Aq = Aq; - pt_pitch = pitch_buf; + p_Aw = Aw; /*Q12*/ + p_Aq = Aq; /*Q12*/ + pt_pitch = pitch_buf; /*Q6*/ shift_wsp = add( Q_new, shift ); - Copy( st->pitch, T_op, 2 ); + Copy( st->pitch, T_op, 2 ); /*Q0*/ if ( LE_16( T_op[0], PIT_MIN ) ) { - T_op[0] = shl( T_op[0], 1 ); + T_op[0] = shl( T_op[0], 1 ); /*Q0*/ move16(); } if ( LE_16( T_op[1], PIT_MIN ) ) { /*T_op[1] *= 2;*/ - T_op[1] = shl( T_op[1], 1 ); + T_op[1] = shl( T_op[1], 1 ); /*Q0*/ move16(); } st->acelp_cfg.fcb_mode = 0; /* flag used in inov_encode() */ + move16(); /*-----------------------------------------------------------------* * Select LP filtering flag *-----------------------------------------------------------------*/ lp_flag = NORMAL_OPERATION; + move16(); if ( LT_32( st->core_brate, ACELP_11k60 ) ) { lp_flag = LOW_PASS; @@ -126,7 +129,7 @@ void encod_amr_wb_fx( * target in residual domain "cn" * Compute impulse response, h1[], of weighted synthesis filter *----------------------------------------------------------------*/ - Copy( &res[i_subfr], &exc[i_subfr], L_SUBFR ); + Copy( &res[i_subfr], &exc[i_subfr], L_SUBFR ); /*Q_new*/ find_targets_fx( speech, hLPDmem->mem_syn, i_subfr, &hLPDmem->mem_w0, p_Aq, res, L_SUBFR, p_Aw, TILT_FAC_FX, xn, cn, h1 ); @@ -184,23 +187,15 @@ void encod_amr_wb_fx( &gain_inov, &norm_gain_code, g_corr, clip_gain, hAmrwb_IO->past_qua_en_fx ); gp_clip_test_gain_pit_fx( st->element_mode, st->core_brate, gain_pit, st->clip_var_fx ); -#ifdef BASOP_NOGLOB Lgcode = L_shl_o( gain_code, Q_new, &Overflow ); /* scaled gain_code with Qnew -> Q16*/ - gcode16 = round_fx_o( Lgcode, &Overflow ); -#else /* BASOP_NOGLOB */ - Lgcode = L_shl( gain_code, Q_new ); /* scaled gain_code with Qnew -> Q16*/ - gcode16 = round_fx( Lgcode ); -#endif /* BASOP_NOGLOB */ + gcode16 = round_fx_o( Lgcode, &Overflow ); /*Q0*/ - hLPDmem->tilt_code = Est_tilt2( exc + i_subfr, gain_pit, code, Lgcode, &voice_fac, shift ); + hLPDmem->tilt_code = Est_tilt2( exc + i_subfr, gain_pit, code, Lgcode, &voice_fac, shift ); /*Q15*/ FOR( i = 0; i < L_SUBFR; i++ ) { -#ifdef BASOP_NOGLOB - exc2[i + i_subfr] = round_fx_o( L_shl_o( L_mult( gain_pit, exc[i + i_subfr] ), 1, &Overflow ), &Overflow ); -#else /* BASOP_NOGLOB */ - exc2[i + i_subfr] = round_fx( L_shl( L_mult( gain_pit, exc[i + i_subfr] ), 1 ) ); -#endif /* BASOP_NOGLOB */ + exc2[i + i_subfr] = round_fx_o( L_shl_o( L_mult( gain_pit, exc[i + i_subfr] ), 1, &Overflow ), &Overflow ); /*Q_new*/ + move16(); } /*-----------------------------------------------------------------* @@ -208,38 +203,25 @@ void encod_amr_wb_fx( *-----------------------------------------------------------------*/ /*st->mem_w0 = xn[L_SUBFR-1] - gain_pit * y1[L_SUBFR-1] - gain_code * y2[L_SUBFR-1];*/ - Ltmp = L_mult( gcode16, y2[L_SUBFR - 1] ); - Ltmp = L_shl( Ltmp, add( 5, shift ) ); + Ltmp = L_mult( gcode16, y2[L_SUBFR - 1] ); /*Q10*/ + Ltmp = L_shl( Ltmp, add( 5, shift ) ); /*Q15 - shift*/ Ltmp = L_negate( Ltmp ); - Ltmp = L_mac( Ltmp, xn[L_SUBFR - 1], 16384 ); - Ltmp = L_msu( Ltmp, y1[L_SUBFR - 1], gain_pit ); -#ifdef BASOP_NOGLOB - Ltmp = L_shl_sat( Ltmp, sub( 1, shift ) ); - hLPDmem->mem_w0 = round_fx_sat( Ltmp ); /*Q_new-1 */ -#else - Ltmp = L_shl( Ltmp, sub( 1, shift ) ); - hLPDmem->mem_w0 = round_fx( Ltmp ); /*Q_new-1 */ -#endif + Ltmp = L_mac( Ltmp, xn[L_SUBFR - 1], 16384 /*Q14*/ ); /* Q_new-1+shift+14+1 */ + Ltmp = L_msu( Ltmp, y1[L_SUBFR - 1], gain_pit /*Q14*/ ); /* Q_new-1+shift+14+1 */ + Ltmp = L_shl_sat( Ltmp, sub( 1, shift ) ); /* Q_new+15 */ + hLPDmem->mem_w0 = round_fx_sat( Ltmp ); /*Q_new-1 */ + move16(); /*-----------------------------------------------------------------* * Find the total excitation *-----------------------------------------------------------------*/ FOR( i = 0; i < L_SUBFR; i++ ) { - L_tmp = L_mult( gcode16, code[i] ); -#ifdef BASOP_NOGLOB - L_tmp = L_shl_sat( L_tmp, 5 ); - L_tmp = L_mac_sat( L_tmp, exc[i + i_subfr], gain_pit ); -#else - L_tmp = L_shl( L_tmp, 5 ); - L_tmp = L_mac( L_tmp, exc[i + i_subfr], gain_pit ); -#endif -#ifdef BASOP_NOGLOB - L_tmp = L_shl_o( L_tmp, 1, &Overflow ); /* saturation can occur here */ - exc[i + i_subfr] = round_fx_o( L_tmp, &Overflow ); -#else /* BASOP_NOGLOB */ - L_tmp = L_shl( L_tmp, 1 ); /* saturation can occur here */ - exc[i + i_subfr] = round_fx( L_tmp ); -#endif + L_tmp = L_mult( gcode16, code[i] ); /*Q10*/ + L_tmp = L_shl_sat( L_tmp, 5 ); /*Q15*/ + L_tmp = L_mac_sat( L_tmp, exc[i + i_subfr], gain_pit ); /* Q_new+15 */ + L_tmp = L_shl_o( L_tmp, 1, &Overflow ); /* saturation can occur here Q_new+15*/ + exc[i + i_subfr] = round_fx_o( L_tmp, &Overflow ); /*Q_new*/ + move16(); } /*-----------------------------------------------------------------* diff --git a/lib_enc/enc_gain.c b/lib_enc/enc_gain.c deleted file mode 100644 index a82d2075a76f57609097ce569d3cdc6d524f64e8..0000000000000000000000000000000000000000 --- a/lib_enc/enc_gain.c +++ /dev/null @@ -1,43 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include -#include "options.h" -#include "prot.h" -#include "rom_enc.h" -#include "rom_com.h" -#include "wmc_auto.h" diff --git a/lib_enc/enc_gain_fx.c b/lib_enc/enc_gain_fx.c index 3bf3db1aa705c07972ac8d67bb437604ce668cdb..7c9606cfc24bcf592bfd1a0390ea625645414b50 100644 --- a/lib_enc/enc_gain_fx.c +++ b/lib_enc/enc_gain_fx.c @@ -14,7 +14,7 @@ #include "prot_fx.h" /* Function prototypes */ #include "prot_fx_enc.h" /* Function prototypes */ -void E_GAIN_norm_corr( Word16 exc[], Word16 xn[], Word16 h[], Word16 t_min, Word16 t_max, Word16 corr_norm[], Word16 L_subfr ); +void E_GAIN_norm_corr_fx( Word16 exc[] /*Q_new*/, Word16 xn[] /*(Q_new+shift-1)*/, Word16 h[] /*(Q14+shift)*/, Word16 t_min, Word16 t_max, Word16 corr_norm[] /*(Q15+(Q_new+shift-1)+scale)*/, Word16 L_subfr ); /* * E_GAIN_norm_corr @@ -36,7 +36,7 @@ void E_GAIN_norm_corr( Word16 exc[], Word16 xn[], Word16 h[], Word16 t_min, Word * Returns: * void */ -void E_GAIN_norm_corr( Word16 exc[], Word16 xn[], Word16 h[], Word16 t_min, Word16 t_max, Word16 corr_norm[], Word16 L_subfr ) +void E_GAIN_norm_corr_fx( Word16 exc[] /*Q_new*/, Word16 xn[] /*(Q_new+shift-1)*/, Word16 h[] /*(Q14+shift)*/, Word16 t_min, Word16 t_max, Word16 corr_norm[] /*(Q15+(Q_new+shift-1)+scale)*/, Word16 L_subfr ) { Word16 excf[L_SUBFR]; /* filtered past excitation (Q_new+shift-1) */ Word16 ps, norm, exp_alp, exp_ps, scale, L_subfr2; @@ -53,7 +53,8 @@ void E_GAIN_norm_corr( Word16 exc[], Word16 xn[], Word16 h[], Word16 t_min, Word /* Compute rounded down 1/sqrt(energy of xn[]) */ Dot_product12_offs( xn, xn, L_subfr, &scale, 1 ); - scale = add( scale, 2 + 1 ); /* energy of xn[] x 2 + rounded up */ + scale = add( scale, 2 + 1 ); /* energy of xn[] x 2 + rounded up */ + move16(); scale = negate( shr( scale, 1 ) ); /* (1< 0 ) { t0_min = add( t0_min, 1 ); + move16(); } t_min = sub( t0_min, L_INTERPOL1 ); t_max = add( t0_max, L_INTERPOL1 ); + move16(); + move16(); /* allocate memory to normalized correlation vector */ corr = &corr_v[negate( t_min )]; /* corr[t_min..t_max] */ /* Compute normalized correlation between target and filtered excitation */ - E_GAIN_norm_corr( exc, xn, h, t_min, t_max, corr_v, L_subfr ); + E_GAIN_norm_corr_fx( exc, xn, h, t_min, t_max, corr_v, L_subfr ); /* find integer pitch */ - max = corr[t0_min]; + max = corr[t0_min]; /*(Q15+(Q_new+shift-1)+scale)*/ move16(); - t0 = t0_min; + t0 = t0_min; /*Q0*/ move16(); FOR( i = t0_min + 1; i <= t0_max; i++ ) @@ -306,26 +310,28 @@ Word16 E_GAIN_closed_loop_search_fx( Word16 exc[], IF( EQ_16( t0_min_max_res, shr( pit_res_max, 1 ) ) ) { - t0_min_frac = shl( t0_min_frac, 1 ); - t0_max_frac = shl( t0_max_frac, 1 ); + t0_min_frac = shl( t0_min_frac, 1 ); /*Q0*/ + t0_max_frac = shl( t0_max_frac, 1 ); /*Q0*/ } step = 1; - frac1 = sub( 1, pit_res_max ); - frac2 = sub( pit_res_max, 1 ); + move16(); + frac1 = sub( 1, pit_res_max ); /*Q0*/ + frac2 = sub( pit_res_max, 1 ); /*Q0*/ test(); test(); IF( ( ( i_subfr == 0 ) && GE_16( t0, pit_fr2 ) ) || LE_16( pit_fr2, pit_min ) ) { step = 2; - frac1 = sub( 2, pit_res_max ); - frac2 = sub( pit_res_max, 2 ); + move16(); + frac1 = sub( 2, pit_res_max ); /*Q0*/ + frac2 = sub( pit_res_max, 2 ); /*Q0*/ } test(); IF( ( EQ_16( t0, t0_min ) ) && ( t0_min_frac == 0 ) ) { - frac1 = t0_min_frac; + frac1 = t0_min_frac; /*Q0*/ move16(); } ELSE @@ -333,28 +339,29 @@ Word16 E_GAIN_closed_loop_search_fx( Word16 exc[], test(); IF( ( EQ_16( t0, t0_min ) ) && ( LT_16( add( frac1, pit_res_max ), t0_min_frac ) ) ) { - frac1 = sub( t0_min_frac, pit_res_max ); + frac1 = sub( t0_min_frac, pit_res_max ); /*Q0*/ } } if ( EQ_16( t0, t0_max ) ) { - frac2 = t0_max_frac; + frac2 = t0_max_frac; /*Q0*/ move16(); } assert( frac1 <= 0 && frac2 >= 0 && frac2 > frac1 ); IF( EQ_16( pit_res_max, 6 ) ) { - cor_max = E_GAIN_norm_corr_interpolate6( &corr[t0], frac1 ); - fraction = frac1; + cor_max = E_GAIN_norm_corr_interpolate6_fx( &corr[t0], frac1 ); /*(Q15+(Q_new+shift-1)+scale)*/ + fraction = frac1; /*Q0*/ + move16(); FOR( i = ( frac1 + step ); i <= frac2; i += step ) { - temp = E_GAIN_norm_corr_interpolate6( &corr[t0], i ); + temp = E_GAIN_norm_corr_interpolate6_fx( &corr[t0], i ); /*(Q15+(Q_new+shift-1)+scale)*/ IF( GT_16( temp, cor_max ) ) { - cor_max = temp; + cor_max = temp; /*(Q15+(Q_new+shift-1)+scale)*/ move16(); fraction = i; move16(); @@ -363,15 +370,16 @@ Word16 E_GAIN_closed_loop_search_fx( Word16 exc[], } ELSE { - cor_max = E_GAIN_norm_corr_interpolate( &corr[t0], frac1 ); - fraction = frac1; + cor_max = E_GAIN_norm_corr_interpolate_fx( &corr[t0], frac1 ); /*(Q15+(Q_new+shift-1)+scale)*/ + fraction = frac1; /*Q0*/ + move16(); FOR( i = ( frac1 + step ); i <= frac2; i += step ) { - temp = E_GAIN_norm_corr_interpolate( &corr[t0], i ); + temp = E_GAIN_norm_corr_interpolate_fx( &corr[t0], i ); /*(Q15+(Q_new+shift-1)+scale)*/ IF( GT_16( temp, cor_max ) ) { - cor_max = temp; + cor_max = temp; /*(Q15+(Q_new+shift-1)+scale)*/ move16(); fraction = i; move16(); @@ -382,23 +390,23 @@ Word16 E_GAIN_closed_loop_search_fx( Word16 exc[], /* limit the fraction value */ IF( fraction < 0 ) { - fraction = add( fraction, pit_res_max ); + fraction = add( fraction, pit_res_max ); /*Q0*/ t0 = sub( t0, 1 ); } test(); test(); IF( ( ( i_subfr == 0 ) && GE_16( t0, pit_fr2 ) ) || LE_16( pit_fr2, pit_min ) ) { - *pit_res = shr( pit_res_max, 1 ); + *pit_res = shr( pit_res_max, 1 ); /*Q0*/ move16(); - *pit_frac = shr( fraction, 1 ); + *pit_frac = shr( fraction, 1 ); /*Q0*/ move16(); } ELSE { - *pit_res = pit_res_max; + *pit_res = pit_res_max; /*Q0*/ move16(); - *pit_frac = fraction; + *pit_frac = fraction; /*Q0*/ move16(); } return ( t0 ); diff --git a/lib_enc/enc_gen_voic.c b/lib_enc/enc_gen_voic.c deleted file mode 100644 index 0fe8682daace6673130ca2ca05de2a188e8e2ae0..0000000000000000000000000000000000000000 --- a/lib_enc/enc_gen_voic.c +++ /dev/null @@ -1,42 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include "cnst.h" -#include "prot.h" -#include "rom_com.h" -#include "wmc_auto.h" diff --git a/lib_enc/enc_gen_voic_fx.c b/lib_enc/enc_gen_voic_fx.c index 856a4312fb88a0c92bbb3fb5228cada468bf8512..06c49a8d3a3d9b7ed08f81da11f2030ac5da0127 100644 --- a/lib_enc/enc_gen_voic_fx.c +++ b/lib_enc/enc_gen_voic_fx.c @@ -4,10 +4,9 @@ #include #include "options.h" /* Compilation switches */ #include "cnst.h" /* Common constants */ -#include "prot.h" /* Function prototypes */ +#include "prot_fx.h" /* Function prototypes */ #include "rom_com_fx.h" /* Static table prototypes */ #include "rom_com.h" /* Static table prototypes */ -#include "prot_fx.h" /* Function prototypes */ #include "prot_fx_enc.h" /* Function prototypes */ /*======================================================================*/ @@ -51,20 +50,20 @@ void encod_gen_voic_fx( Encoder_State *st_fx, /* i/o: state structure */ - const Word16 speech_fx[], /* i : input speech */ - const Word16 Aw_fx[], /* i : weighted A(z) unquantized for subframes */ - const Word16 Aq_fx[], /* i : 12k8 Lp coefficient */ - const Word16 Es_pred_fx, /* i : predicted scaled innov. energy */ - const Word16 *res_fx, /* i : residual signal */ - Word16 *syn_fx, /* i/o: core synthesis */ - Word16 *exc_fx, /* i/o: current non-enhanced excitation */ - Word16 *exc2_fx, /* i/o: current enhanced excitation */ - Word16 *pitch_buf_fx, /* i/o: floating pitch values for each subframe */ - Word16 *voice_factors_fx, /* o : voicing factors */ - Word16 *bwe_exc_fx, /* o : excitation for SWB TBE */ - Word16 *unbits_fx, /* i/o: number of unused bits */ - const Word16 tdm_Pitch_reuse_flag, /* i : primary channel pitch reuse flag */ - const Word16 tdm_Pri_pitch_buf[], /* i : primary channel pitch buffer */ + const Word16 speech_fx[], /* i : input speech Q0*/ + const Word16 Aw_fx[], /* i : weighted A(z) unquantized for subframes Q12*/ + const Word16 Aq_fx[], /* i : 12k8 Lp coefficient Q12*/ + const Word16 Es_pred_fx, /* i : predicted scaled innov. energy Q8*/ + const Word16 *res_fx, /* i : residual signal Q_new*/ + Word16 *syn_fx, /* i/o: core synthesis Q_new*/ + Word16 *exc_fx, /* i/o: current non-enhanced excitation Q0*/ + Word16 *exc2_fx, /* i/o: current enhanced excitation Q0*/ + Word16 *pitch_buf_fx, /* i/o: floating pitch values for each subframe Q6*/ + Word16 *voice_factors_fx, /* o : voicing factors Q15*/ + Word16 *bwe_exc_fx, /* o : excitation for SWB TBE Q0*/ + Word16 *unbits_fx, /* i/o: number of unused bits Q0*/ + const Word16 tdm_Pitch_reuse_flag, /* i : primary channel pitch reuse flag Q0*/ + const Word16 tdm_Pri_pitch_buf[], /* i : primary channel pitch buffer Q6*/ Word16 shift, Word16 Q_new ) { @@ -77,23 +76,32 @@ void encod_gen_voic_fx( Word16 y1_fx[L_SUBFR] = { 0 }; /* Filtered adaptive excitation */ Word16 y2_fx[L_SUBFR]; /* Filtered algebraic excitation */ Word16 gain_pit_fx = 0; /* Pitch gain */ - Word16 voice_fac_fx; /* Voicing factor */ - Word32 gain_code_fx = 0; /* Gain of code */ - Word16 gain_inov_fx = 0; /* inovation gain */ - Word32 gc_mem[NB_SUBFR - 1]; /* gain_code from previous subframes */ - Word16 gp_mem[NB_SUBFR - 1]; /* gain_pitch from previous subframes*/ - Word16 i, i_subfr_fx; /* tmp variables */ - Word16 T0_fx = 0, T0_frac_fx = 0; /* close loop integer pitch and fractional part */ - Word16 T0_min_fx, T0_max_fx; /* pitch variables */ - Word16 *pt_pitch_fx; /* pointer to floating pitch buffer */ - Word16 g_corr_fx[10]; /* ACELP correl, values + gain pitch */ - Word16 clip_gain_fx; /* LSF clip gain */ - const Word16 *p_Aw_fx, *p_Aq_fx; /* pointer to LP filter coeff. vector*/ + move16(); + Word16 voice_fac_fx; /* Voicing factor */ + Word32 gain_code_fx = 0; /* Gain of code */ + move32(); + Word16 gain_inov_fx = 0; /* inovation gain */ + move16(); + Word32 gc_mem[NB_SUBFR - 1]; /* gain_code from previous subframes */ + Word16 gp_mem[NB_SUBFR - 1]; /* gain_pitch from previous subframes*/ + Word16 i, i_subfr_fx; /* tmp variables */ + Word16 T0_fx = 0, T0_frac_fx = 0; /* close loop integer pitch and fractional part */ + move16(); + move16(); + Word16 T0_min_fx, T0_max_fx; /* pitch variables */ + Word16 *pt_pitch_fx; /* pointer to floating pitch buffer */ + Word16 g_corr_fx[10]; /* ACELP correl, values + gain pitch */ + Word16 clip_gain_fx; /* LSF clip gain */ + const Word16 *p_Aw_fx, *p_Aq_fx; /* pointer to LP filter coeff. vector*/ Word16 error_fx = 0; - Word16 gain_preQ_fx = 0; /* Gain of prequantizer excitation */ + Word16 gain_preQ_fx = 0; /* Gain of prequantizer excitation */ + move16(); + move16(); Word16 code_preQ_fx[L_SUBFR]; /* Prequantizer excitation */ Word16 unbits_PI_fx = 0; /* number of unused bits for PI */ Word32 norm_gain_code_fx = 0; + move16(); + move32(); Word16 pitch_limit_flag; Word16 gcode16; Word32 Ltmp; @@ -105,6 +113,7 @@ void encod_gen_voic_fx( Word16 lp_select, lp_flag, L_frame; #ifdef BASOP_NOGLOB_DECLARE_LOCAL Flag Overflow = 0; + move32(); #endif SC_VBR_ENC_HANDLE hSC_VBR = st_fx->hSC_VBR; BSTR_ENC_HANDLE hBstr = st_fx->hBstr; @@ -148,9 +157,9 @@ void encod_gen_voic_fx( *unbits_fx = 0; move16(); - p_Aw_fx = Aw_fx; - p_Aq_fx = Aq_fx; - pt_pitch_fx = pitch_buf_fx; + p_Aw_fx = Aw_fx; /* Q12 */ + p_Aq_fx = Aq_fx; /* Q12 */ + pt_pitch_fx = pitch_buf_fx; /* Q6 */ gain_preQ_fx = 0; move16(); set16_fx( code_preQ_fx, 0, L_SUBFR ); @@ -186,19 +195,19 @@ void encod_gen_voic_fx( * Compute impulse response, h1[], of weighted synthesis filter *----------------------------------------------------------------*/ - Copy( &res_fx[i_subfr_fx], &exc_fx[i_subfr_fx], L_SUBFR ); + Copy( &res_fx[i_subfr_fx], &exc_fx[i_subfr_fx], L_SUBFR ); /*Q_new*/ find_targets_fx( speech_fx, hLPDmem->mem_syn, i_subfr_fx, &hLPDmem->mem_w0, p_Aq_fx, res_fx, L_SUBFR, p_Aw_fx, st_fx->preemph_fac, xn_fx, cn_fx, h1_fx ); - Copy_Scale_sig( h1_fx, h2_fx, L_SUBFR, -2 ); - Scale_sig( h1_fx, L_SUBFR, add( 1, shift ) ); /* set h1[] in Q14 with scaling for convolution */ + Copy_Scale_sig( h1_fx, h2_fx, L_SUBFR, -2 ); /*Q11*/ + Scale_sig( h1_fx, L_SUBFR, add( 1, shift ) ); /* set h1[] in Q14 with scaling for convolution Q(14+shift)*/ /* scaling of xn[] to limit dynamic at 12 bits */ Scale_sig( xn_fx, L_SUBFR, shift ); *pt_pitch_fx = pit_encode_fx( hBstr, st_fx->acelp_cfg.pitch_bits, st_fx->core_brate, 0, L_frame, st_fx->coder_type, &pitch_limit_flag, i_subfr_fx, exc_fx, - L_SUBFR, st_fx->pitch, &T0_min_fx, &T0_max_fx, &T0_fx, &T0_frac_fx, h1_fx, xn_fx, tdm_Pitch_reuse_flag, tdm_Pri_pitch_buf ); + L_SUBFR, st_fx->pitch, &T0_min_fx, &T0_max_fx, &T0_fx, &T0_frac_fx, h1_fx, xn_fx, tdm_Pitch_reuse_flag, tdm_Pri_pitch_buf ); /* Q6 */ tbe_celp_exc( L_frame, i_subfr_fx, T0_fx, T0_frac_fx, &error_fx, bwe_exc_fx ); @@ -234,11 +243,7 @@ void encod_gen_voic_fx( } /*st_fx->lowrate_pitchGain = 0.9f * st_fx->lowrate_pitchGain + 0.1f * gain_pit_fx;*/ -#ifdef BASOP_NOGLOB hSpMusClas->lowrate_pitchGain = round_fx_o( L_mac_o( L_mult( 29491, hSpMusClas->lowrate_pitchGain ), 6554, gain_pit_fx, &Overflow ), &Overflow ); /*Q14*Q16(0.1) + Q15 -> Q15*/ -#else - hSpMusClas->lowrate_pitchGain = round_fx( L_mac( L_mult( 29491, hSpMusClas->lowrate_pitchGain ), 6554, gain_pit_fx ) ); /*Q14*Q16(0.1) + Q15 -> Q15*/ -#endif /*-----------------------------------------------------------------* * Transform domain contribution encoding - active frames @@ -283,21 +288,17 @@ void encod_gen_voic_fx( if ( EQ_16( hSC_VBR->last_ppp_mode, 1 ) ) { /* SC-VBR - all other st->clip_var values will be updated even in a PPP frame */ - st_fx->clip_var_fx[1] = gain_pit_fx; + st_fx->clip_var_fx[1] = gain_pit_fx; /*Q14*/ move16(); } } gp_clip_test_gain_pit_fx( st_fx->element_mode, st_fx->core_brate, gain_pit_fx, st_fx->clip_var_fx ); -#ifdef BASOP_NOGLOB Lgcode = L_shl_o( gain_code_fx, Q_new, &Overflow ); /* scaled gain_code with Qnew -> Q16*/ - gcode16 = round_fx_o( Lgcode, &Overflow ); -#else - Lgcode = L_shl( gain_code_fx, Q_new ); /* scaled gain_code with Qnew -> Q16*/ - gcode16 = round_fx( Lgcode ); -#endif + gcode16 = round_fx_o( Lgcode, &Overflow ); /*Q0*/ - hLPDmem->tilt_code = Est_tilt2( &exc_fx[i_subfr_fx], gain_pit_fx, code_fx, Lgcode, &voice_fac_fx, shift ); + hLPDmem->tilt_code = Est_tilt2( &exc_fx[i_subfr_fx], gain_pit_fx, code_fx, Lgcode, &voice_fac_fx, shift ); /* Q15 */ + move16(); /*-----------------------------------------------------------------* * Transform domain contribution encoding - inactive frames @@ -315,54 +316,35 @@ void encod_gen_voic_fx( *-----------------------------------------------------------------*/ /* st_fx->mem_w0 = xn[L_SUBFR-1] - (gain_pit*y1[L_SUBFR-1]) - (gain_code*y2[L_SUBFR-1]); */ - Ltmp = L_mult( gcode16, y2_fx[L_SUBFR - 1] ); - Ltmp = L_shl( Ltmp, add( 5, shift ) ); + Ltmp = L_mult( gcode16, y2_fx[L_SUBFR - 1] ); /*Q10*/ + Ltmp = L_shl( Ltmp, add( 5, shift ) ); /*Q15+shift*/ Ltmp = L_negate( Ltmp ); - Ltmp = L_mac( Ltmp, xn_fx[L_SUBFR - 1], 16384 ); - Ltmp = L_msu( Ltmp, y1_fx[L_SUBFR - 1], gain_pit_fx ); -#ifdef BASOP_NOGLOB - Ltmp = L_shl_sat( Ltmp, sub( 1, shift ) ); - hLPDmem->mem_w0 = round_fx_sat( Ltmp ); /*Q_new-1 */ -#else - Ltmp = L_shl( Ltmp, sub( 1, shift ) ); - hLPDmem->mem_w0 = round_fx( Ltmp ); /*Q_new-1 */ -#endif + Ltmp = L_mac( Ltmp, xn_fx[L_SUBFR - 1], 16384 /*Q14*/ ); /* Q_new-1+shift+14+1 */ + Ltmp = L_msu( Ltmp, y1_fx[L_SUBFR - 1], gain_pit_fx /*Q14*/ ); /* Q_new-1+shift+14+1 */ + Ltmp = L_shl_sat( Ltmp, sub( 1, shift ) ); /* 15 + Q_new */ + hLPDmem->mem_w0 = round_fx_sat( Ltmp ); /*Q_new-1 */ + move16(); IF( gain_preQ_fx != 0 ) { tmp1_fx = add( 16 - ( 2 + Q_AVQ_OUT_DEC + 1 ), Q_new ); FOR( i = 0; i < L_SUBFR; i++ ) { -#ifdef BASOP_NOGLOB /* Contribution from AVQ layer */ Ltmp1 = L_mult_o( gain_preQ_fx, code_preQ_fx[i], &Overflow ); /* Q2 + Q6 -> Q9*/ Ltmp1 = L_shl_o( Ltmp1, tmp1_fx, &Overflow ); /* Q16 + Q_exc */ /* Compute exc2 */ - Ltmp = L_shl_o( L_mult( gain_pit_fx, exc_fx[i + i_subfr_fx] ), 1, &Overflow ); - exc2_fx[i + i_subfr_fx] = round_fx_o( L_add_o( Ltmp, Ltmp1, &Overflow ), &Overflow ); -#else - /* Contribution from AVQ layer */ - Ltmp1 = L_mult( gain_preQ_fx, code_preQ_fx[i] ); /* Q2 + Q6 -> Q9*/ - Ltmp1 = L_shl( Ltmp1, tmp1_fx ); /* Q16 + Q_exc */ - - /* Compute exc2 */ - Ltmp = L_shl( L_mult( gain_pit_fx, exc_fx[i + i_subfr_fx] ), 1 ); - exc2_fx[i + i_subfr_fx] = round_fx( L_add( Ltmp, Ltmp1 ) ); -#endif + Ltmp = L_shl_o( L_mult( gain_pit_fx, exc_fx[i + i_subfr_fx] ), 1, &Overflow ); /* Q16 */ + exc2_fx[i + i_subfr_fx] = round_fx_o( L_add_o( Ltmp, Ltmp1, &Overflow ), &Overflow ); /* Q0 */ + move16(); /* code in Q9, gain_pit in Q14 */ - Ltmp = L_mult( gcode16, code_fx[i] ); - Ltmp = L_shl( Ltmp, 5 ); - Ltmp = L_mac( Ltmp, exc_fx[i + i_subfr_fx], gain_pit_fx ); -#ifdef BASOP_NOGLOB - Ltmp = L_shl_o( Ltmp, 1, &Overflow ); /* saturation can occur here */ - exc_fx[i + i_subfr_fx] = round_fx_o( L_add_o( Ltmp, Ltmp1, &Overflow ), &Overflow ); -#else - Ltmp = L_shl( Ltmp, 1 ); /* saturation can occur here */ - - exc_fx[i + i_subfr_fx] = round_fx( L_add( Ltmp, Ltmp1 ) ); -#endif + Ltmp = L_mult( gcode16, code_fx[i] ); /* Q10 */ + Ltmp = L_shl( Ltmp, 5 ); /* Q15 */ + Ltmp = L_mac( Ltmp, exc_fx[i + i_subfr_fx], gain_pit_fx ); /* Q15 */ + Ltmp = L_shl_o( Ltmp, 1, &Overflow ); /* saturation can occur here Q16*/ + exc_fx[i + i_subfr_fx] = round_fx_o( L_add_o( Ltmp, Ltmp1, &Overflow ), &Overflow ); /* Q0 */ } } ELSE @@ -374,18 +356,11 @@ void encod_gen_voic_fx( FOR( i = 0; i < L_SUBFR; i++ ) { /* code in Q9, gain_pit in Q14 */ - Ltmp = L_mult( gcode16, code_fx[i] ); -#ifdef BASOP_NOGLOB - Ltmp = L_shl_o( Ltmp, 5, &Overflow ); - Ltmp = L_mac_o( Ltmp, exc_fx[i + i_subfr_fx], gain_pit_fx, &Overflow ); - Ltmp = L_shl_o( Ltmp, 1, &Overflow ); /* saturation can occur here */ - exc_fx[i + i_subfr_fx] = round_fx_o( Ltmp, &Overflow ); -#else - Ltmp = L_shl( Ltmp, 5 ); - Ltmp = L_mac( Ltmp, exc_fx[i + i_subfr_fx], gain_pit_fx ); - Ltmp = L_shl( Ltmp, 1 ); /* saturation can occur here */ - exc_fx[i + i_subfr_fx] = round_fx( Ltmp ); -#endif + Ltmp = L_mult( gcode16, code_fx[i] ); /* Q10 */ + Ltmp = L_shl_o( Ltmp, 5, &Overflow ); /* Q15 */ + Ltmp = L_mac_o( Ltmp, exc_fx[i + i_subfr_fx], gain_pit_fx, &Overflow ); /* Q15 */ + Ltmp = L_shl_o( Ltmp, 1, &Overflow ); /* saturation can occur here Q16*/ + exc_fx[i + i_subfr_fx] = round_fx_o( Ltmp, &Overflow ); /* Q0 */ } } /*-----------------------------------------------------------------* @@ -418,9 +393,9 @@ void encod_gen_voic_fx( IF( st_fx->Opt_SC_VBR ) { /* SC-VBR */ - hSC_VBR->prev_ppp_gain_pit_fx = gain_pit_fx; + hSC_VBR->prev_ppp_gain_pit_fx = gain_pit_fx; /* Q14 */ move16(); - hSC_VBR->prev_tilt_code_fx = hLPDmem->tilt_code; + hSC_VBR->prev_tilt_code_fx = hLPDmem->tilt_code; /* Q15 */ move16(); } return; @@ -428,20 +403,20 @@ void encod_gen_voic_fx( void encod_gen_voic_ivas_fx( Encoder_State *st_fx, /* i/o: state structure */ - const Word16 speech_fx[], /* i : input speech */ - const Word16 Aw_fx[], /* i : weighted A(z) unquantized for subframes */ - const Word16 Aq_fx[], /* i : 12k8 Lp coefficient */ - const Word16 Es_pred_fx, /* i : predicted scaled innov. energy */ - const Word16 *res_fx, /* i : residual signal */ - Word16 *syn_fx, /* i/o: core synthesis */ - Word16 *exc_fx, /* i/o: current non-enhanced excitation */ - Word16 *exc2_fx, /* i/o: current enhanced excitation */ - Word16 *pitch_buf_fx, /* i/o: floating pitch values for each subframe */ - Word16 *voice_factors_fx, /* o : voicing factors */ - Word16 *bwe_exc_fx, /* o : excitation for SWB TBE */ - Word16 *unbits_fx, /* i/o: number of unused bits */ - const Word16 tdm_Pitch_reuse_flag, /* i : primary channel pitch reuse flag */ - const Word16 tdm_Pri_pitch_buf[], /* i : primary channel pitch buffer */ + const Word16 speech_fx[], /* i : input speech Q0*/ + const Word16 Aw_fx[], /* i : weighted A(z) unquantized for subframes Q12*/ + const Word16 Aq_fx[], /* i : 12k8 Lp coefficient Q12*/ + const Word16 Es_pred_fx, /* i : predicted scaled innov. energy Q8*/ + const Word16 *res_fx, /* i : residual signal Q_new*/ + Word16 *syn_fx, /* i/o: core synthesis Q_new*/ + Word16 *exc_fx, /* i/o: current non-enhanced excitation Q0*/ + Word16 *exc2_fx, /* i/o: current enhanced excitation Q0*/ + Word16 *pitch_buf_fx, /* i/o: floating pitch values for each subframe Q6*/ + Word16 *voice_factors_fx, /* o : voicing factors Q15*/ + Word16 *bwe_exc_fx, /* o : excitation for SWB TBE Q0*/ + Word16 *unbits_fx, /* i/o: number of unused bits Q0*/ + const Word16 tdm_Pitch_reuse_flag, /* i : primary channel pitch reuse flag Q0*/ + const Word16 tdm_Pri_pitch_buf[], /* i : primary channel pitch buffer Q6*/ Word16 shift, Word16 Q_new ) { @@ -454,23 +429,32 @@ void encod_gen_voic_ivas_fx( Word16 y1_fx[L_SUBFR] = { 0 }; /* Filtered adaptive excitation */ Word16 y2_fx[L_SUBFR]; /* Filtered algebraic excitation */ Word16 gain_pit_fx = 0; /* Pitch gain */ - Word16 voice_fac_fx; /* Voicing factor */ - Word32 gain_code_fx = 0; /* Gain of code */ - Word16 gain_inov_fx = 0; /* inovation gain */ - Word32 gc_mem[NB_SUBFR - 1]; /* gain_code from previous subframes */ - Word16 gp_mem[NB_SUBFR - 1]; /* gain_pitch from previous subframes*/ - Word16 i, i_subfr_fx; /* tmp variables */ - Word16 T0_fx = 0, T0_frac_fx = 0; /* close loop integer pitch and fractional part */ - Word16 T0_min_fx, T0_max_fx; /* pitch variables */ - Word16 *pt_pitch_fx; /* pointer to floating pitch buffer */ - Word16 g_corr_fx[10]; /* ACELP correl, values + gain pitch */ - Word16 clip_gain_fx; /* LSF clip gain */ - const Word16 *p_Aw_fx, *p_Aq_fx; /* pointer to LP filter coeff. vector*/ + move16(); + Word16 voice_fac_fx; /* Voicing factor */ + Word32 gain_code_fx = 0; /* Gain of code */ + Word16 gain_inov_fx = 0; /* inovation gain */ + move32(); + move16(); + Word32 gc_mem[NB_SUBFR - 1]; /* gain_code from previous subframes */ + Word16 gp_mem[NB_SUBFR - 1]; /* gain_pitch from previous subframes*/ + Word16 i, i_subfr_fx; /* tmp variables */ + Word16 T0_fx = 0, T0_frac_fx = 0; /* close loop integer pitch and fractional part */ + move16(); + move16(); + Word16 T0_min_fx, T0_max_fx; /* pitch variables */ + Word16 *pt_pitch_fx; /* pointer to floating pitch buffer */ + Word16 g_corr_fx[10]; /* ACELP correl, values + gain pitch */ + Word16 clip_gain_fx; /* LSF clip gain */ + const Word16 *p_Aw_fx, *p_Aq_fx; /* pointer to LP filter coeff. vector*/ Word16 error_fx = 0; - Word16 gain_preQ_fx = 0; /* Gain of prequantizer excitation */ + Word16 gain_preQ_fx = 0; /* Gain of prequantizer excitation */ + move16(); + move16(); Word16 code_preQ_fx[L_SUBFR]; /* Prequantizer excitation */ Word16 unbits_PI_fx = 0; /* number of unused bits for PI */ Word32 norm_gain_code_fx = 0; + move16(); + move32(); Word16 pitch_limit_flag; Word16 gcode16; Word32 Ltmp; @@ -480,12 +464,13 @@ void encod_gen_voic_ivas_fx( Word16 shift_wsp; Word16 harm_flag_acelp; Word16 lp_select, lp_flag, L_frame; + Word16 q_h1; #ifdef BASOP_NOGLOB_DECLARE_LOCAL Flag Overflow = 0; + move32(); #endif SC_VBR_ENC_HANDLE hSC_VBR = st_fx->hSC_VBR; BSTR_ENC_HANDLE hBstr = st_fx->hBstr; - SP_MUS_CLAS_HANDLE hSpMusClas = st_fx->hSpMusClas; LPD_state_HANDLE hLPDmem = st_fx->hLPDmem; /*------------------------------------------------------------------* @@ -525,9 +510,9 @@ void encod_gen_voic_ivas_fx( *unbits_fx = 0; move16(); - p_Aw_fx = Aw_fx; - p_Aq_fx = Aq_fx; - pt_pitch_fx = pitch_buf_fx; + p_Aw_fx = Aw_fx; /*Q12*/ + p_Aq_fx = Aq_fx; /*Q12*/ + pt_pitch_fx = pitch_buf_fx; /*Q6*/ gain_preQ_fx = 0; move16(); set16_fx( code_preQ_fx, 0, L_SUBFR ); @@ -563,21 +548,21 @@ void encod_gen_voic_ivas_fx( * Compute impulse response, h1[], of weighted synthesis filter *----------------------------------------------------------------*/ - Copy( &res_fx[i_subfr_fx], &exc_fx[i_subfr_fx], L_SUBFR ); + Copy( &res_fx[i_subfr_fx], &exc_fx[i_subfr_fx], L_SUBFR ); /*Q_new*/ find_targets_ivas_fx( speech_fx, hLPDmem->mem_syn, i_subfr_fx, &hLPDmem->mem_w0, p_Aq_fx, res_fx, L_SUBFR, p_Aw_fx, st_fx->preemph_fac, xn_fx, cn_fx, h1_fx ); - Copy_Scale_sig( h1_fx, h2_fx, L_SUBFR, -2 ); - Scale_sig( h1_fx, L_SUBFR, add( 1, shift ) ); /* set h1[] in Q14 with scaling for convolution */ + q_h1 = sub( 14, norm_s( h1_fx[0] ) ); + Copy_Scale_sig( h1_fx, h2_fx, L_SUBFR, sub( 11, q_h1 ) ); /*Q11*/ /* scaling of xn[] to limit dynamic at 12 bits */ Scale_sig( xn_fx, L_SUBFR, shift ); *pt_pitch_fx = pit_encode_ivas_fx( hBstr, st_fx->acelp_cfg.pitch_bits, st_fx->core_brate, 0, L_frame, st_fx->coder_type, &pitch_limit_flag, i_subfr_fx, exc_fx, - L_SUBFR, st_fx->pitch, &T0_min_fx, &T0_max_fx, &T0_fx, &T0_frac_fx, h1_fx, xn_fx, tdm_Pitch_reuse_flag, tdm_Pri_pitch_buf ); + L_SUBFR, st_fx->pitch, &T0_min_fx, &T0_max_fx, &T0_fx, &T0_frac_fx, h1_fx, xn_fx, tdm_Pitch_reuse_flag, tdm_Pri_pitch_buf, Q_new ); /* Q6 */ + move16(); - // tbe_celp_exc(L_frame, i_subfr_fx, T0_fx, T0_frac_fx, &error_fx, bwe_exc_fx); tbe_celp_exc_ivas( st_fx->element_mode, st_fx->idchan, L_frame, L_SUBFR, i_subfr_fx, T0_fx, T0_frac_fx, &error_fx, bwe_exc_fx, st_fx->tdm_LRTD_flag ); /*-----------------------------------------------------------------* @@ -602,22 +587,15 @@ void encod_gen_voic_ivas_fx( /*-----------------------------------------------------------------* * LP filtering of the adaptive excitation, codebook target computation *-----------------------------------------------------------------*/ - - lp_select = lp_filt_exc_enc_fx( MODE1, st_fx->coder_type, i_subfr_fx, exc_fx, h1_fx, - xn_fx, y1_fx, xn2_fx, L_SUBFR, L_frame, g_corr_fx, clip_gain_fx, &gain_pit_fx, &lp_flag ); + Scale_sig( h1_fx, L_SUBFR, sub( 14, q_h1 ) ); /* set h1[] in Q14 with scaling for convolution Q14*/ + lp_select = lp_filt_exc_enc_ivas_fx( MODE1, st_fx->coder_type, i_subfr_fx, exc_fx, h1_fx, + xn_fx, y1_fx, xn2_fx, L_SUBFR, L_frame, g_corr_fx, clip_gain_fx, &gain_pit_fx, &lp_flag ); IF( EQ_16( lp_flag, NORMAL_OPERATION ) ) { push_indice( hBstr, IND_LP_FILT_SELECT, lp_select, 1 ); } - /*st_fx->lowrate_pitchGain = 0.9f * st_fx->lowrate_pitchGain + 0.1f * gain_pit_fx;*/ -#ifdef BASOP_NOGLOB - hSpMusClas->lowrate_pitchGain = round_fx_o( L_mac_o( L_mult( 29491, hSpMusClas->lowrate_pitchGain ), 6554, gain_pit_fx, &Overflow ), &Overflow ); /*Q14*Q16(0.1) + Q15 -> Q15*/ -#else - hSpMusClas->lowrate_pitchGain = round_fx( L_mac( L_mult( 29491, hSpMusClas->lowrate_pitchGain ), 6554, gain_pit_fx ) ); /*Q14*Q16(0.1) + Q15 -> Q15*/ -#endif - /*-----------------------------------------------------------------* * Transform domain contribution encoding - active frames *-----------------------------------------------------------------*/ @@ -661,28 +639,28 @@ void encod_gen_voic_ivas_fx( if ( EQ_16( hSC_VBR->last_ppp_mode, 1 ) ) { /* SC-VBR - all other st->clip_var values will be updated even in a PPP frame */ - st_fx->clip_var_fx[1] = gain_pit_fx; + st_fx->clip_var_fx[1] = gain_pit_fx; /* Q14 */ move16(); } } gp_clip_test_gain_pit_fx( st_fx->element_mode, st_fx->core_brate, gain_pit_fx, st_fx->clip_var_fx ); -#ifdef BASOP_NOGLOB Lgcode = L_shl_o( gain_code_fx, Q_new, &Overflow ); /* scaled gain_code with Qnew -> Q16*/ - gcode16 = round_fx_o( Lgcode, &Overflow ); -#else - Lgcode = L_shl( gain_code_fx, Q_new ); /* scaled gain_code with Qnew -> Q16*/ - gcode16 = round_fx( Lgcode ); -#endif + gcode16 = round_fx_o( Lgcode, &Overflow ); /* Q0 */ - hLPDmem->tilt_code = Est_tilt2( &exc_fx[i_subfr_fx], gain_pit_fx, code_fx, Lgcode, &voice_fac_fx, shift ); + hLPDmem->tilt_code = est_tilt_ivas_fx( &exc_fx[i_subfr_fx], gain_pit_fx, code_fx, gain_code_fx, &voice_fac_fx, Q_new, L_SUBFR, 0 ); /* Q15 */ + move16(); /*-----------------------------------------------------------------* * Transform domain contribution encoding - inactive frames *-----------------------------------------------------------------*/ test(); +#ifdef NONBE_FIX_GSC_BSTR + IF( !st_fx->inactive_coder_type_flag && EQ_16( st_fx->coder_type, INACTIVE ) ) +#else IF( GE_32( st_fx->total_brate, MAX_GSC_INACTIVE_BRATE ) && EQ_16( st_fx->coder_type, INACTIVE ) ) +#endif { transf_cdbk_enc_ivas_fx( st_fx, 0, i_subfr_fx, cn_fx, exc_fx, p_Aq_fx, p_Aw_fx, h1_fx, xn_fx, xn2_fx, y1_fx, y2_fx, Es_pred_fx, &gain_pit_fx, gain_code_fx, g_corr_fx, clip_gain_fx, &gain_preQ_fx, code_preQ_fx, unbits_fx, Q_new, shift ); @@ -693,54 +671,36 @@ void encod_gen_voic_ivas_fx( *-----------------------------------------------------------------*/ /* st_fx->mem_w0 = xn[L_SUBFR-1] - (gain_pit*y1[L_SUBFR-1]) - (gain_code*y2[L_SUBFR-1]); */ - Ltmp = L_mult0( gcode16, y2_fx[L_SUBFR - 1] ); - Ltmp = L_shl( Ltmp, add( 5, shift ) ); // Q_new+14+shift + Ltmp = L_mult0( gcode16, y2_fx[L_SUBFR - 1] ); /* Q9 */ + Ltmp = L_shl( Ltmp, add( 5, shift ) ); // Q_new+14+shift Ltmp = L_negate( Ltmp ); - Ltmp = L_mac( Ltmp, xn_fx[L_SUBFR - 1], 16384 ); // Q_new-1+15+shift - Ltmp = L_msu( Ltmp, y1_fx[L_SUBFR - 1], gain_pit_fx ); // Q_new-1+15+shift -#ifdef BASOP_NOGLOB - Ltmp = L_shl_sat( Ltmp, sub( 1, shift ) ); // Q_new+15 - hLPDmem->mem_w0 = round_fx_sat( Ltmp ); /*Q_new-1 */ -#else - Ltmp = L_shl( Ltmp, sub( 1, shift ) ); - hLPDmem->mem_w0 = round_fx( Ltmp ); /*Q_new-1 */ -#endif + Ltmp = L_mac( Ltmp, xn_fx[L_SUBFR - 1], 16384 /*Q14*/ ); // Q_new-1+15+shift + Ltmp = L_msu( Ltmp, y1_fx[L_SUBFR - 1], gain_pit_fx /*Q14*/ ); // Q_new-1+15+shift + Ltmp = L_shl_sat( Ltmp, sub( 1, shift ) ); // Q_new+15 + hLPDmem->mem_w0 = round_fx_sat( Ltmp ); /*Q_new-1 */ + move16(); IF( gain_preQ_fx != 0 ) { tmp1_fx = add( 16 - ( 2 + Q_AVQ_OUT_DEC + 1 ), Q_new ); FOR( i = 0; i < L_SUBFR; i++ ) { -#ifdef BASOP_NOGLOB /* Contribution from AVQ layer */ Ltmp1 = L_mult_o( gain_preQ_fx, code_preQ_fx[i], &Overflow ); /* Q2 + Q6 -> Q9*/ Ltmp1 = L_shl_o( Ltmp1, tmp1_fx, &Overflow ); /* Q16 + Q_exc */ /* Compute exc2 */ - Ltmp = L_shl_o( L_mult( gain_pit_fx, exc_fx[i + i_subfr_fx] ), 1, &Overflow ); - exc2_fx[i + i_subfr_fx] = round_fx_o( L_add_o( Ltmp, Ltmp1, &Overflow ), &Overflow ); -#else - /* Contribution from AVQ layer */ - Ltmp1 = L_mult( gain_preQ_fx, code_preQ_fx[i] ); /* Q2 + Q6 -> Q9*/ - Ltmp1 = L_shl( Ltmp1, tmp1_fx ); /* Q16 + Q_exc */ - - /* Compute exc2 */ - Ltmp = L_shl( L_mult( gain_pit_fx, exc_fx[i + i_subfr_fx] ), 1 ); - exc2_fx[i + i_subfr_fx] = round_fx( L_add( Ltmp, Ltmp1 ) ); -#endif + Ltmp = L_shl_o( L_mult( gain_pit_fx, exc_fx[i + i_subfr_fx] ), 1, &Overflow ); /* Q0 */ + exc2_fx[i + i_subfr_fx] = round_fx_o( L_add_o( Ltmp, Ltmp1, &Overflow ), &Overflow ); /* Q0 */ + move16(); /* code in Q9, gain_pit in Q14 */ - Ltmp = L_mult( gcode16, code_fx[i] ); - Ltmp = L_shl( Ltmp, 5 ); - Ltmp = L_mac( Ltmp, exc_fx[i + i_subfr_fx], gain_pit_fx ); -#ifdef BASOP_NOGLOB - Ltmp = L_shl_o( Ltmp, 1, &Overflow ); /* saturation can occur here */ - exc_fx[i + i_subfr_fx] = round_fx_o( L_add_o( Ltmp, Ltmp1, &Overflow ), &Overflow ); -#else - Ltmp = L_shl( Ltmp, 1 ); /* saturation can occur here */ - - exc_fx[i + i_subfr_fx] = round_fx( L_add( Ltmp, Ltmp1 ) ); -#endif + Ltmp = L_mult( gcode16, code_fx[i] ); /* Q10 */ + Ltmp = L_shl( Ltmp, 5 ); /* Q15 */ + Ltmp = L_mac( Ltmp, exc_fx[i + i_subfr_fx], gain_pit_fx ); /* Q15 */ + Ltmp = L_shl_o( Ltmp, 1, &Overflow ); /* saturation can occur here Q16*/ + exc_fx[i + i_subfr_fx] = round_fx_o( L_add_o( Ltmp, Ltmp1, &Overflow ), &Overflow ); /* Q0 */ + move16(); } } ELSE @@ -752,18 +712,11 @@ void encod_gen_voic_ivas_fx( FOR( i = 0; i < L_SUBFR; i++ ) { /* code in Q9, gain_pit in Q14 */ - Ltmp = L_mult( gcode16, code_fx[i] ); -#ifdef BASOP_NOGLOB - Ltmp = L_shl_o( Ltmp, 5, &Overflow ); - Ltmp = L_mac_o( Ltmp, exc_fx[i + i_subfr_fx], gain_pit_fx, &Overflow ); - Ltmp = L_shl_o( Ltmp, 1, &Overflow ); /* saturation can occur here */ - exc_fx[i + i_subfr_fx] = round_fx_o( Ltmp, &Overflow ); -#else - Ltmp = L_shl( Ltmp, 5 ); - Ltmp = L_mac( Ltmp, exc_fx[i + i_subfr_fx], gain_pit_fx ); - Ltmp = L_shl( Ltmp, 1 ); /* saturation can occur here */ - exc_fx[i + i_subfr_fx] = round_fx( Ltmp ); -#endif + Ltmp = L_mult( gcode16, code_fx[i] ); /* Q10 */ + Ltmp = L_shl_o( Ltmp, 5, &Overflow ); /* Q15 */ + Ltmp = L_mac_o( Ltmp, exc_fx[i + i_subfr_fx], gain_pit_fx, &Overflow ); /* Q15 */ + Ltmp = L_shl_o( Ltmp, 1, &Overflow ); /* saturation can occur here Q16*/ + exc_fx[i + i_subfr_fx] = round_fx_o( Ltmp, &Overflow ); /* Q0 */ } } /*-----------------------------------------------------------------* diff --git a/lib_enc/enc_gen_voic_rf.c b/lib_enc/enc_gen_voic_rf.c deleted file mode 100644 index 33df891b88cc405395df6c65726cdab8fcfcb354..0000000000000000000000000000000000000000 --- a/lib_enc/enc_gen_voic_rf.c +++ /dev/null @@ -1,43 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include "cnst.h" -#include "prot.h" -#include "rom_com.h" -#include "wmc_auto.h" -#include "prot_fx.h" diff --git a/lib_enc/enc_gen_voic_rf_fx.c b/lib_enc/enc_gen_voic_rf_fx.c index ae70dc6b33a5f4761cc65573c624c993b2f5394b..e9c9d87f74bfa057d719079170b1496c85b61887 100644 --- a/lib_enc/enc_gen_voic_rf_fx.c +++ b/lib_enc/enc_gen_voic_rf_fx.c @@ -5,11 +5,9 @@ #include #include "options.h" #include "cnst.h" -//#include "prot_fx.h" #include "rom_com_fx.h" #include "stl.h" #include "rom_basop_util.h" -//#include "basop_mpy.h" #include "rom_com.h" /* Common constants */ #include "prot_fx.h" /* Function prototypes */ #include "prot_fx_enc.h" /* Function prototypes */ @@ -50,7 +48,7 @@ void reset_rf_indices_fx( hRF->rf_target_bits = 0; move16(); - hRF->rf_tcxltp_pitch_int_past = st->L_frame; + hRF->rf_tcxltp_pitch_int_past = st->L_frame; /* Q0 */ move16(); hRF->rf_last_tns_active = 0; move16(); @@ -117,18 +115,18 @@ void reset_rf_indices_fx( *-------------------------------------------------------------------*/ void coder_acelp_rf_fx( ACELP_config *acelp_cfg, /*input/output: configuration of the ACELP coding*/ - const Word16 coder_type, /* input: coding type */ - const Word16 A[], /* input: coefficients 4xAz[M+1] */ - const Word16 Aq[], /* input: coefficients 4xAz_q[M+1] */ - Word16 speech[], /* input: speech[-M..lg] */ - const Word16 voicing[], /* input: open-loop LTP gain */ - const Word16 T_op[], /* input: open-loop LTP lag */ - Word16 stab_fac, + const Word16 coder_type, /* input: coding type Q0*/ + const Word16 A[], /* input: coefficients 4xAz[M+1] Q12*/ + const Word16 Aq[], /* input: coefficients 4xAz_q[M+1] Q12*/ + Word16 speech[], /* input: speech[-M..lg] Q_new-1*/ + const Word16 voicing[], /* input: open-loop LTP gain Q15*/ + const Word16 T_op[], /* input: open-loop LTP lag Q0*/ + Word16 stab_fac, /* Q15 */ Encoder_State *st, - Word16 target_bits, /* i/o : coder memory state */ - const Word16 rf_frame_type, /* i : rf_frame_type */ - Word16 *exc_rf, /* i/o: pointer to RF excitation */ - Word16 *syn_rf, /* i/o: pointer to RF synthesis */ + Word16 target_bits, /* i/o : coder memory state Q0*/ + const Word16 rf_frame_type, /* i : rf_frame_type Q0*/ + Word16 *exc_rf, /* i/o: pointer to RF excitation Q_new*/ + Word16 *syn_rf, /* i/o: pointer to RF synthesis Q_new-1*/ Word16 Q_new, Word16 shift ) { @@ -169,6 +167,7 @@ void coder_acelp_rf_fx( Word16 lp_select; #ifdef BASOP_NOGLOB_DECLARE_LOCAL Flag Overflow = 0; + move32(); #endif RF_ENC_HANDLE hRF = st->hRF; @@ -184,16 +183,26 @@ void coder_acelp_rf_fx( voice_fac = 0; prev_gain_pit = 0; Es_pred_rf = 0; + move32(); + move32(); + move16(); + move16(); + move16(); + move16(); + move16(); + move16(); + move16(); + set16_fx( code, 0, L_SUBFR ); /*-----------------------------------------------------------------------* * Configure ACELP partial copy * *------------------------------------------------------------------------*/ - tmp2 = BITS_ALLOC_config_acelp( target_bits, rf_frame_type, &( hRF->acelp_cfg_rf ), 0, st->nb_subfr ); + tmp2 = BITS_ALLOC_config_acelp( target_bits, rf_frame_type, &( hRF->acelp_cfg_rf ), 0, st->nb_subfr ); /* Q0 */ /* Init Framing parameters */ - L_frame = st->L_frame; - + L_frame = st->L_frame; /* Q0 */ + move16(); /*------------------------------------------------------------------------* * Initialize buffers * *------------------------------------------------------------------------*/ @@ -219,10 +228,13 @@ void coder_acelp_rf_fx( *------------------------------------------------------------------------*/ Es_pred_rf = 0; + move16(); + + test(); IF( acelp_cfg->nrg_mode > 0 && NE_16( rf_frame_type, RF_NELP ) ) { Es_pred_enc_fx( &Es_pred_rf, &hRF->rf_indx_EsPred[0], L_frame, exc_rf, voicing, - acelp_cfg->nrg_bits, acelp_cfg->nrg_mode > 1, Q_new ); + acelp_cfg->nrg_bits, extract_l( GT_16( acelp_cfg->nrg_mode, 1 ) ), Q_new ); } /*------------------------------------------------------------------------* @@ -275,7 +287,7 @@ void coder_acelp_rf_fx( Scale_sig( h1, L_SUBFR, add( 1, shift ) ); /* Q13+1-shift */ /* scaling of xn[] to limit dynamic at 12 bits */ - Scale_sig( xn, L_SUBFR, shift ); + Scale_sig( xn, L_SUBFR, shift ); /* Q_new + shift */ } @@ -290,12 +302,12 @@ void coder_acelp_rf_fx( { nelp_encoder_fx( st, exc_rf, exc_nelp, &Q_new, 0 ); } - Copy( &exc_nelp[i_subfr], exc2, L_SUBFR ); - Copy( &exc_nelp[i_subfr], exc_rf, L_SUBFR ); + Copy( &exc_nelp[i_subfr], exc2, L_SUBFR ); /* Q_new */ + Copy( &exc_nelp[i_subfr], exc_rf, L_SUBFR ); /* Q_new */ } ELSE { - clip_gain = Mode2_gp_clip( voicing, i_subfr, coder_type, xn, hRF->rf_clip_var, L_SUBFR, Q_xn ); + clip_gain = Mode2_gp_clip_fx( voicing, i_subfr, coder_type, xn, hRF->rf_clip_var, L_SUBFR, Q_xn ); // Q0 /*-----------------------------------------------------------------* * - find unity gain pitch excitation (adaptive codebook entry) * @@ -311,7 +323,7 @@ void coder_acelp_rf_fx( IF( acelp_cfg->ltp_bits != 0 ) { - prm_rf = &hRF->rf_indx_pitch[0][nSubfr]; + prm_rf = &hRF->rf_indx_pitch[0][nSubfr]; /* Q0 */ /* Adaptive Codebook (GC and VC) */ Mode2_pit_encode_fx( acelp_cfg->ltp_mode, i_subfr, &prm_rf, &exc_rf[i_subfr], @@ -324,7 +336,7 @@ void coder_acelp_rf_fx( move16(); if ( acelp_cfg->gains_mode[i_subfr / L_SUBFR] > 0 ) { - rf_coder_type = acelp_cfg->gains_mode[i_subfr / L_SUBFR]; + rf_coder_type = acelp_cfg->gains_mode[i_subfr / L_SUBFR]; /* Q0 */ move16(); } @@ -335,7 +347,7 @@ void coder_acelp_rf_fx( if ( EQ_16( acelp_cfg->ltf_mode, NORMAL_OPERATION ) ) { - hRF->rf_indx_ltfMode[0][nSubfr] = lp_select; + hRF->rf_indx_ltfMode[0][nSubfr] = lp_select; /* Q0 */ move16(); } } @@ -402,7 +414,7 @@ void coder_acelp_rf_fx( *----------------------------------------------------------*/ IF( acelp_cfg->gains_mode[i_subfr / L_SUBFR] != 0 ) { - prm_rf = &hRF->rf_indx_gain[0][nSubfr]; + prm_rf = &hRF->rf_indx_gain[0][nSubfr]; /* Q0 */ encode_acelp_gains_fx( code, acelp_cfg->gains_mode[j_subfr], Es_pred_rf, clip_gain, &g_corr, &gain_pit, &gain_code, &prm_rf, &past_gcode, @@ -428,31 +440,16 @@ void coder_acelp_rf_fx( * Update memory of the weighting filter *-----------------------------------------------------------------*/ /* st_fx->_rf_mem_w0 = xn[L_SUBFR-1] - (gain_pit*y1[L_SUBFR-1]) - (gain_code*y2[L_SUBFR-1]); */ - Ltmp = Mpy_32_16_1( gain_code, y2[L_SUBFR - 1] ); -#ifdef BASOP_NOGLOB - Ltmp = L_shl_o( Ltmp, add( 5, Q_xn ), &Overflow ); - Ltmp = L_mac_o( Ltmp, y1[L_SUBFR - 1], gain_pit, &Overflow ); -#else - Ltmp = L_shl( Ltmp, add( 5, Q_xn ) ); - Ltmp = L_mac( Ltmp, y1[L_SUBFR - 1], gain_pit ); -#endif + Ltmp = Mpy_32_16_1( gain_code, y2[L_SUBFR - 1] ); /* Q10 */ + Ltmp = L_shl_o( Ltmp, add( 5, Q_xn ), &Overflow ); /* Q15 + Q_xn */ + Ltmp = L_mac_o( Ltmp, y1[L_SUBFR - 1], gain_pit, &Overflow ); /* Q15 + Q_xn */ /* Add Gaussian contribution*/ - Ltmp2 = Mpy_32_16_1( gain_code2, y22[L_SUBFR - 1] ); -#ifdef BASOP_NOGLOB - Ltmp2 = L_shl_o( Ltmp2, add( 5, Q_xn ), &Overflow ); - Ltmp = L_add_o( Ltmp, Ltmp2, &Overflow ); - hRF->rf_mem_w0 = sub_o( xn[L_SUBFR - 1], round_fx_o( L_shl_o( Ltmp, 1, &Overflow ), &Overflow ), &Overflow ); + Ltmp2 = Mpy_32_16_1( gain_code2, y22[L_SUBFR - 1] ); /* Q10 */ + Ltmp2 = L_shl_o( Ltmp2, add( 5, Q_xn ), &Overflow ); /* Q15 + Q_xn */ + Ltmp = L_add_o( Ltmp, Ltmp2, &Overflow ); /* Q15 + Q_xn */ + hRF->rf_mem_w0 = sub_o( xn[L_SUBFR - 1], round_fx_o( L_shl_o( Ltmp, 1, &Overflow ), &Overflow ), &Overflow ); /* Q_xn */ move16(); hRF->rf_mem_w0 = shr_o( hRF->rf_mem_w0, shift, &Overflow ); /*Qnew-1*/ -#else - Ltmp2 = L_shl( Ltmp2, add( 5, Q_xn ) ); - Ltmp = L_add( Ltmp, Ltmp2 ); - hRF->rf_mem_w0 = sub( xn[L_SUBFR - 1], round_fx( L_shl( Ltmp, 1 ) ) ); - move16(); - BASOP_SATURATE_WARNING_OFF_EVS; - hRF->rf_mem_w0 = shr( hRF->rf_mem_w0, shift ); /*Qnew-1*/ - BASOP_SATURATE_WARNING_ON_EVS; -#endif /*-------------------------------------------------------* @@ -465,34 +462,20 @@ void coder_acelp_rf_fx( FOR( i = sub( tmp2, shr( L_SUBFR, 1 ) ); i < tmp2; i++ ) { /* code in Q9, gain_pit in Q14; exc Q_new */ - Ltmp = Mpy_32_16_1( gain_code2, code2[i] ); -#ifdef BASOP_NOGLOB - Ltmp = L_shl_o( Ltmp, Q_new_p5, &Overflow ); - Ltmp = L_mac_o( Ltmp, gain_pit, exc_rf[i + i_subfr], &Overflow ); - exc2[i] = round_fx_o( L_shl_o( Ltmp, 1, &Overflow ), &Overflow ); -#else - Ltmp = L_shl( Ltmp, Q_new_p5 ); - Ltmp = L_mac( Ltmp, gain_pit, exc_rf[i + i_subfr] ); - BASOP_SATURATE_WARNING_OFF_EVS - exc2[i] = round_fx( L_shl( Ltmp, 1 ) ); - BASOP_SATURATE_WARNING_ON_EVS -#endif - Ltmp2 = Mpy_32_16_1( gain_code_vect[j], code[i] ); -#ifdef BASOP_NOGLOB - Ltmp2 = L_shl_o( Ltmp2, Q_new_p5, &Overflow ); - Ltmp = L_add_o( Ltmp, Ltmp2, &Overflow ); - Ltmp = L_shl_o( Ltmp, 1, &Overflow ); /* saturation can occur here */ - exc_rf[i + i_subfr] = round_fx_o( Ltmp, &Overflow ); -#else - Ltmp2 = L_shl( Ltmp2, Q_new_p5 ); - Ltmp = L_add( Ltmp, Ltmp2 ); - BASOP_SATURATE_WARNING_OFF_EVS - Ltmp = L_shl( Ltmp, 1 ); /* saturation can occur here */ - BASOP_SATURATE_WARNING_ON_EVS - exc_rf[i + i_subfr] = round_fx( Ltmp ); -#endif + Ltmp = Mpy_32_16_1( gain_code2, code2[i] ); /* Q10 */ + Ltmp = L_shl_o( Ltmp, Q_new_p5, &Overflow ); /* Q15 + Q_new */ + Ltmp = L_mac_o( Ltmp, gain_pit, exc_rf[i + i_subfr], &Overflow ); /* Q15 + Q_new */ + exc2[i] = round_fx_o( L_shl_o( Ltmp, 1, &Overflow ), &Overflow ); /* Q_new */ + move16(); + Ltmp2 = Mpy_32_16_1( gain_code_vect[j], code[i] ); /* Q10 */ + Ltmp2 = L_shl_o( Ltmp2, Q_new_p5, &Overflow ); /* Q15 + Q_new */ + Ltmp = L_add_o( Ltmp, Ltmp2, &Overflow ); /* Q15 + Q_new */ + Ltmp = L_shl_o( Ltmp, 1, &Overflow ); /* saturation can occur here Q16 + Q_new*/ + exc_rf[i + i_subfr] = round_fx_o( Ltmp, &Overflow ); /* Q_new */ + move16(); } tmp2 = L_SUBFR; + move16(); } @@ -506,7 +489,8 @@ void coder_acelp_rf_fx( } } - IF( i_subfr < sub( L_frame, L_SUBFR ) || NE_16( rf_frame_type, RF_NELP ) ) + test(); + IF( LT_16( i_subfr, sub( L_frame, L_SUBFR ) ) || NE_16( rf_frame_type, RF_NELP ) ) { /*----------------------------------------------------------* @@ -524,11 +508,12 @@ void coder_acelp_rf_fx( p_Aq += ( M + 1 ); nSubfr++; - st->gain_code[j_subfr] = gain_code; + st->gain_code[j_subfr] = gain_code; /* Q16 */ j_subfr = add( j_subfr, 1 ); /* copy current gain for next subframe use, in case there is no explicit encoding */ prev_gain_pit = gain_pit; + move16(); } diff --git a/lib_enc/enc_higher_acelp.c b/lib_enc/enc_higher_acelp.c deleted file mode 100644 index a01b229ff9cdd26addc170ce3100e40a897bbc12..0000000000000000000000000000000000000000 --- a/lib_enc/enc_higher_acelp.c +++ /dev/null @@ -1,47 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include -#include "cnst.h" -#include "prot.h" -#include "rom_com.h" -#include "wmc_auto.h" - -/*---------------------------------------------------------------------* - * Local function prototypes - *---------------------------------------------------------------------*/ diff --git a/lib_enc/enc_higher_acelp_fx.c b/lib_enc/enc_higher_acelp_fx.c index da58fe7212671e771cf5d8ff01b7761b2866028e..64a11be5b145b5db326b69af31dc1b4d627ea512 100644 --- a/lib_enc/enc_higher_acelp_fx.c +++ b/lib_enc/enc_higher_acelp_fx.c @@ -4,10 +4,9 @@ #include #include "options.h" /* Compilation switches */ #include "cnst.h" /* Common constants */ -#include "prot.h" /* Function prototypes */ +#include "prot_fx.h" /* Function prototypes */ #include "rom_com_fx.h" /* Static table prototypes */ #include "rom_com.h" /* Static table prototypes */ -#include "prot_fx.h" #include "prot_fx_enc.h" /*---------------------------------------------------------------------* @@ -21,25 +20,25 @@ static void find_cn_fx( const Word16 xn[], const Word16 Ap[], const Word16 *p_Aq #define Q_MINUS 4 void transf_cdbk_enc_fx( Encoder_State *st_fx, /* i/o: encoder state structure */ - const Word16 harm_flag_acelp, /* i : harmonic flag for higher rates ACELP */ - const Word16 i_subfr, /* i : subframe index */ - Word16 cn[], /* i/o: target vector in residual domain */ - Word16 exc[], /* i/o: pointer to excitation signal frame */ - const Word16 *p_Aq, /* i : 12k8 Lp coefficient */ - const Word16 Ap[], /* i : weighted LP filter coefficients */ - const Word16 h1[], /* i : weighted filter input response */ - Word16 xn[], /* i/o: target vector */ - Word16 xn2[], /* i/o: target vector for innovation search */ - Word16 y1[], /* i/o: zero-memory filtered adaptive excitation */ - const Word16 y2[], /* i : zero-memory filtered innovative excitation */ - const Word16 Es_pred, /* i : predicited scaled innovation energy */ - Word16 *gain_pit, /* i/o: adaptive excitation gain */ - const Word32 gain_code, /* i : innovative excitation gain */ - Word16 g_corr[], /* o : ACELP correlation values */ - const Word16 clip_gain, /* i : adaptive gain clipping flag */ - Word16 *gain_preQ, /* o : prequantizer excitation gain */ - Word16 code_preQ[], /* o : prequantizer excitation */ - Word16 *unbits, /* o : number of AVQ unused bits */ + const Word16 harm_flag_acelp, /* i : harmonic flag for higher rates ACELP Q0*/ + const Word16 i_subfr, /* i : subframe index Q0*/ + Word16 cn[], /* i/o: target vector in residual domain Q_new*/ + Word16 exc[], /* i/o: pointer to excitation signal frame Q_new*/ + const Word16 *p_Aq, /* i : 12k8 Lp coefficient Q12*/ + const Word16 Ap[], /* i : weighted LP filter coefficients Q12*/ + const Word16 h1[], /* i : weighted filter input response Q15*/ + Word16 xn[], /* i/o: target vector Q_new + shift -1*/ + Word16 xn2[], /* i/o: target vector for innovation search Q_new + shift -1*/ + Word16 y1[], /* i/o: zero-memory filtered adaptive excitation Q_new + shift -1*/ + const Word16 y2[], /* i : zero-memory filtered innovative excitation Q9*/ + const Word16 Es_pred, /* i : predicited scaled innovation energy Q8*/ + Word16 *gain_pit, /* i/o: adaptive excitation gain Q14*/ + const Word32 gain_code, /* i : innovative excitation gain Q16*/ + Word16 g_corr[], /* o : ACELP correlation values Q15*/ + const Word16 clip_gain, /* i : adaptive gain clipping flag Q0*/ + Word16 *gain_preQ, /* o : prequantizer excitation gain Q2*/ + Word16 code_preQ[], /* o : prequantizer excitation Q_AVQ_OUT_DEC*/ + Word16 *unbits, /* o : number of AVQ unused bits Q0*/ const Word16 Q_new, /* i : Current frame scaling */ const Word16 shift /* i : shifting applied to y1, xn,... */ ) @@ -56,11 +55,12 @@ void transf_cdbk_enc_fx( Word16 trgtSvPos; #ifdef BASOP_NOGLOB_DECLARE_LOCAL Flag Overflow = 0; + move32(); #endif avq_bit_sFlag = 0; move16(); - if ( GT_16( st_fx->element_mode, EVS_MONO ) ) + if ( st_fx->element_mode > EVS_MONO ) { avq_bit_sFlag = 1; move16(); @@ -72,7 +72,7 @@ void transf_cdbk_enc_fx( Nsv = 8; move16(); - nBits = st_fx->acelp_cfg.AVQ_cdk_bits[shr( i_subfr, 6 )]; + nBits = st_fx->acelp_cfg.AVQ_cdk_bits[shr( i_subfr, 6 )]; /* Q0 */ move16(); /* increase # of AVQ allocated bits by unused bits from the previous subframe */ @@ -85,11 +85,7 @@ void transf_cdbk_enc_fx( *--------------------------------------------------------------*/ IF( EQ_16( st_fx->coder_type, INACTIVE ) ) { -#ifdef BASOP_NOGLOB gcode16 = round_fx_o( L_shl_o( gain_code, Q_new, &Overflow ), &Overflow ); -#else - gcode16 = round_fx( L_shl( gain_code, Q_new ) ); -#endif FOR( i = 0; i < L_SUBFR; i++ ) { /*x_tran[i] = xn[i] - *gain_pit * y1[i] - gain_code * y2[i];*/ @@ -97,14 +93,10 @@ void transf_cdbk_enc_fx( Ltmp = L_shl( Ltmp, add( 5, shift ) ); Ltmp = L_negate( Ltmp ); Ltmp = L_mac( Ltmp, xn[i], 16384 ); - Ltmp = L_msu( Ltmp, y1[i], *gain_pit ); -#ifdef BASOP_NOGLOB - Ltmp = L_shl_sat( Ltmp, sub( 1, shift ) ); - x_tran[i] = round_fx_sat( Ltmp ); /*Q_new-1 */ -#else - Ltmp = L_shl( Ltmp, sub( 1, shift ) ); - x_tran[i] = round_fx( Ltmp ); /*Q_new-1 */ -#endif + Ltmp = L_msu( Ltmp, y1[i], *gain_pit ); /* Q_new + 14 + shift */ + Ltmp = L_shl_sat( Ltmp, sub( 1, shift ) ); /* Q_new + 15 */ + x_tran[i] = round_fx_sat( Ltmp ); /*Q_new-1 */ + move16(); } find_cn_fx( x_tran, Ap, p_Aq, x_in ); } @@ -152,15 +144,9 @@ void transf_cdbk_enc_fx( { /*fcorr += fx_tran[i]*(float)ix_norm[i];*/ /*fener += (float)ix_norm[i]*(float)ix_norm[i];*/ -#ifdef BASOP_NOGLOB stmp = shl_sat( x_norm[i], Q_AVQ_OUT ); L_corr = L_mac_sat( L_corr, x_tran[i], stmp ); L_ener = L_mac_sat( L_ener, stmp, stmp ); -#else - stmp = shl( x_norm[i], Q_AVQ_OUT ); - L_corr = L_mac( L_corr, x_tran[i], stmp ); - L_ener = L_mac( L_ener, stmp, stmp ); -#endif } L_ener = L_max( L_ener, 1 ); @@ -179,34 +165,22 @@ void transf_cdbk_enc_fx( m_corr = shr( m_corr, 1 ); e_corr = add( e_corr, 1 ); } - m_corr = div_s( m_corr, m_ener ); + m_corr = div_s( m_corr, m_ener ); /* e_corr - e_ener */ e_corr = sub( e_corr, e_ener ); -#ifdef BASOP_NOGLOB Ltmp = L_shl_sat( m_corr, s_min( add( e_corr, 1 ), 31 ) ); /* Lgain in Q16 */ -#else - Ltmp = L_shl( m_corr, s_min( add( e_corr, 1 ), 31 ) ); /* Lgain in Q16 */ -#endif IF( EQ_16( st_fx->coder_type, INACTIVE ) ) { Ltmp1 = L_max( gain_code, 1 ); e_den = norm_l( Ltmp1 ); -#ifdef BASOP_NOGLOB m_den = extract_h( L_shl_sat( Ltmp1, e_den ) ); -#else - m_den = extract_h( L_shl( Ltmp1, e_den ) ); -#endif /* ensure m_corr < m_den */ test(); IF( m_corr > 0 && m_den > 0 ) { m_corr = div_s( 16384, m_den ); e_corr = sub( 14 + 4, e_den ); - Ltmp = L_shr( Mult_32_16( Ltmp, m_corr ), e_corr ); /*Q12*/ -#ifdef BASOP_NOGLOB - stmp = round_fx_o( L_shl_o( Ltmp, 16, &Overflow ), &Overflow ); -#else - stmp = round_fx( L_shl( Ltmp, 16 ) ); -#endif + Ltmp = L_shr( Mult_32_16( Ltmp, m_corr ), e_corr ); /*Q12*/ + stmp = round_fx_o( L_shl_o( Ltmp, 16, &Overflow ), &Overflow ); /* Q12 */ } ELSE { @@ -215,34 +189,29 @@ void transf_cdbk_enc_fx( } IF( GT_32( st_fx->core_brate, 56000 ) ) { - index = usquant_fx( stmp, &stmp, G_AVQ_MIN_INACT_64k_Q12, G_AVQ_DELTA_INACT_64k_Q12 >> 1, ( 1 << G_AVQ_BITS ) ); + index = usquant_fx( stmp, &stmp, G_AVQ_MIN_INACT_64k_Q12, G_AVQ_DELTA_INACT_64k_Q12 >> 1, ( 1 << G_AVQ_BITS ) ); /* Q0 */ } ELSE IF( GT_32( st_fx->core_brate, 42000 ) ) { - index = usquant_fx( stmp, &stmp, G_AVQ_MIN_INACT_48k_Q12, G_AVQ_DELTA_INACT_48k_Q12 >> 1, ( 1 << G_AVQ_BITS ) ); + index = usquant_fx( stmp, &stmp, G_AVQ_MIN_INACT_48k_Q12, G_AVQ_DELTA_INACT_48k_Q12 >> 1, ( 1 << G_AVQ_BITS ) ); /* Q0 */ } ELSE { - index = usquant_fx( stmp, &stmp, G_AVQ_MIN_INACT_Q12, G_AVQ_DELTA_INACT_Q12 >> 1, ( 1 << G_AVQ_BITS ) ); + index = usquant_fx( stmp, &stmp, G_AVQ_MIN_INACT_Q12, G_AVQ_DELTA_INACT_Q12 >> 1, ( 1 << G_AVQ_BITS ) ); /* Q0 */ } Ltmp = Mult_32_16( gain_code, stmp ); /* Q16 * Q12 - 15 -> Q13*/ -#ifdef BASOP_NOGLOB - Ltmp = L_shl_sat( Ltmp, 5 ); /* Q13 -> Q18*/ - *gain_preQ = round_fx_sat( Ltmp ); /* Q2*/ -#else - Ltmp = L_shl( Ltmp, 5 ); /* Q13 -> Q18*/ - *gain_preQ = round_fx( Ltmp ); /* Q2*/ -#endif + Ltmp = L_shl_sat( Ltmp, 5 ); /* Q13 -> Q18*/ + *gain_preQ = round_fx_sat( Ltmp ); /* Q2*/ } ELSE { IF( Es_pred < 0 ) { - Es_pred_loc = shr( negate( Es_pred ), 2 ); + Es_pred_loc = shr( negate( Es_pred ), 2 ); /* Q8 */ } ELSE { - Es_pred_loc = Es_pred; + Es_pred_loc = Es_pred; /* Q8 */ move16(); } @@ -252,9 +221,9 @@ void transf_cdbk_enc_fx( test(); IF( m_corr > 0 && m_den > 0 ) { - m_corr = div_s( 16384, m_den ); + m_corr = div_s( 16384, m_den ); /* 14 - 8 - e_den */ e_corr = sub( 14 - 8, e_den ); - Ltmp = L_shr( Mult_32_16( Ltmp, m_corr ), e_corr ); + Ltmp = L_shr( Mult_32_16( Ltmp, m_corr ), e_corr ); /* Q18 */ } ELSE { @@ -263,11 +232,11 @@ void transf_cdbk_enc_fx( test(); IF( LE_32( st_fx->core_brate, 42000 ) && GT_32( st_fx->core_brate, ACELP_24k40 ) ) { - index = gain_quant_fx( &Ltmp, &stmp, LG10_G_AVQ_MIN_32kbps_Q14, LG10_G_AVQ_MAX_Q13, G_AVQ_BITS, &e_den ); + index = gain_quant_fx( &Ltmp, &stmp, LG10_G_AVQ_MIN_32kbps_Q14, LG10_G_AVQ_MAX_Q13, G_AVQ_BITS, &e_den ); /* Q0 */ } ELSE { - index = gain_quant_fx( &Ltmp, &stmp, LG10_G_AVQ_MIN_Q14, LG10_G_AVQ_MAX_Q13, G_AVQ_BITS, &e_den ); + index = gain_quant_fx( &Ltmp, &stmp, LG10_G_AVQ_MIN_Q14, LG10_G_AVQ_MAX_Q13, G_AVQ_BITS, &e_den ); /* Q0 */ } Ltmp = L_mult( stmp, Es_pred_loc ); /* Q0*Q8 -> Q9*/ Ltmp = L_shl( Ltmp, add( e_den, 9 ) ); /* Q18*/ @@ -296,7 +265,7 @@ void transf_cdbk_enc_fx( AVQ_encmux_fx( st_fx->hBstr, -1, x_norm, &nBits, Nsv, nq, avq_bit_sFlag, trgtSvPos ); /* save # of AVQ unused bits for next subframe */ - *unbits = nBits; + *unbits = nBits; /* Q0 */ move16(); /* at the last subframe, write AVQ unused bits */ @@ -318,11 +287,7 @@ void transf_cdbk_enc_fx( FOR( i = 0; i < Nsv * WIDTH_BAND; i++ ) { -#ifdef BASOP_NOGLOB x_tran[i] = shl_o( x_norm[i], Q_AVQ_OUT_DEC, &Overflow ); -#else - x_tran[i] = shl( x_norm[i], Q_AVQ_OUT_DEC ); -#endif move16(); } set16_fx( x_tran + Nsv * WIDTH_BAND, 0, sub( L_SUBFR, i_mult2( WIDTH_BAND, Nsv ) ) ); @@ -332,7 +297,7 @@ void transf_cdbk_enc_fx( test(); IF( NE_16( st_fx->coder_type, INACTIVE ) && LE_32( st_fx->core_brate, MAX_BRATE_AVQ_EXC_TD ) && GE_32( st_fx->core_brate, MIN_BRATE_AVQ_EXC ) && !harm_flag_acelp ) { - Copy( x_tran, code_preQ, L_SUBFR ); + Copy( x_tran, code_preQ, L_SUBFR ); /* Q_AVQ_OUT_DEC */ } ELSE { @@ -358,22 +323,7 @@ void transf_cdbk_enc_fx( } st_fx->last_nq_preQ = nq[7]; move16(); -#ifdef IVAS_CODE - /* TD pre-quantizer: in extreme cases at subframe boundaries, lower the preemphasis memory to avoid a saturation */ - if ( st->element_mode > EVS_MONO && st->coder_type != INACTIVE && st->core_brate >= MIN_BRATE_AVQ_EXC && st->core_brate <= MAX_BRATE_AVQ_EXC_TD && !harm_flag_acelp && code_preQ[0] != 0 ) - { - if ( (float) abs( st->last_code_preq ) > 16.0f * (float) fabs( code_preQ[0] ) ) - { - st->mem_preemp_preQ /= 16; - } - else if ( (float) abs( st->last_code_preq ) > 8.0f * (float) fabs( code_preQ[0] ) ) - { - st->mem_preemp_preQ /= 8; - } - } - st->last_code_preq = (int16_t) code_preQ[L_SUBFR - 1]; -#endif PREEMPH_FX( code_preQ, FAC_PRE_AVQ_FX, L_SUBFR, &( st_fx->mem_preemp_preQ_fx ) ); /*--------------------------------------------------------------* @@ -403,16 +353,12 @@ void transf_cdbk_enc_fx( updt_tar_HR_fx( cn, cn, code_preQ, *gain_preQ, sub( Q_new, add( -15 + 2, Q_AVQ_OUT_DEC ) ), L_SUBFR ); updt_tar_HR_fx( xn, xn, x_tran, *gain_preQ, sub( Q_new, add( -15 + 2, Q_AVQ_OUT_DEC ) ), L_SUBFR ); -#ifdef BASOP_NOGLOB - *gain_pit = corr_xy1_fx( xn, y1, g_corr, L_SUBFR, 0, &Overflow ); -#else - *gain_pit = corr_xy1_fx( xn, y1, g_corr, L_SUBFR, 0 ); -#endif + *gain_pit = corr_xy1_fx( xn, y1, g_corr, L_SUBFR, 0, &Overflow ); /* Q14 */ /* clip gain if necessary to avoid problems at decoder */ test(); if ( EQ_16( clip_gain, 1 ) && GT_16( *gain_pit, 15565 ) ) { - *gain_pit = 15565; + *gain_pit = 15565; /* 0.95 in Q15 */ move16(); } updt_tar_fx( xn, xn2, y1, *gain_pit, L_SUBFR ); @@ -425,25 +371,25 @@ void transf_cdbk_enc_fx( } void transf_cdbk_enc_ivas_fx( Encoder_State *st_fx, /* i/o: encoder state structure */ - const Word16 harm_flag_acelp, /* i : harmonic flag for higher rates ACELP */ - const Word16 i_subfr, /* i : subframe index */ - Word16 cn[], /* i/o: target vector in residual domain */ - Word16 exc[], /* i/o: pointer to excitation signal frame */ - const Word16 *p_Aq, /* i : 12k8 Lp coefficient */ - const Word16 Ap[], /* i : weighted LP filter coefficients */ - const Word16 h1[], /* i : weighted filter input response */ - Word16 xn[], /* i/o: target vector */ - Word16 xn2[], /* i/o: target vector for innovation search */ - Word16 y1[], /* i/o: zero-memory filtered adaptive excitation */ - const Word16 y2[], /* i : zero-memory filtered innovative excitation */ - const Word16 Es_pred, /* i : predicited scaled innovation energy */ - Word16 *gain_pit, /* i/o: adaptive excitation gain */ - const Word32 gain_code, /* i : innovative excitation gain */ - Word16 g_corr[], /* o : ACELP correlation values */ - const Word16 clip_gain, /* i : adaptive gain clipping flag */ - Word16 *gain_preQ, /* o : prequantizer excitation gain */ - Word16 code_preQ[], /* o : prequantizer excitation */ - Word16 *unbits, /* o : number of AVQ unused bits */ + const Word16 harm_flag_acelp, /* i : harmonic flag for higher rates ACELP Q0*/ + const Word16 i_subfr, /* i : subframe index Q0*/ + Word16 cn[], /* i/o: target vector in residual domain Q_new*/ + Word16 exc[], /* i/o: pointer to excitation signal frame Q_new*/ + const Word16 *p_Aq, /* i : 12k8 Lp coefficient Q12*/ + const Word16 Ap[], /* i : weighted LP filter coefficients Q12*/ + const Word16 h1[], /* i : weighted filter input response Q15*/ + Word16 xn[], /* i/o: target vector Q_new + shift -1*/ + Word16 xn2[], /* i/o: target vector for innovation search Q_new + shift -1*/ + Word16 y1[], /* i/o: zero-memory filtered adaptive excitation Q_new + shift -1*/ + const Word16 y2[], /* i : zero-memory filtered innovative excitation Q9*/ + const Word16 Es_pred, /* i : predicited scaled innovation energy Q8*/ + Word16 *gain_pit, /* i/o: adaptive excitation gain Q14*/ + const Word32 gain_code, /* i : innovative excitation gain Q16*/ + Word16 g_corr[], /* o : ACELP correlation values Q15*/ + const Word16 clip_gain, /* i : adaptive gain clipping flag Q0*/ + Word16 *gain_preQ, /* o : prequantizer excitation gain Q2*/ + Word16 code_preQ[], /* o : prequantizer excitation Q_AVQ_OUT_DEC*/ + Word16 *unbits, /* o : number of AVQ unused bits Q0*/ const Word16 Q_new, /* i : Current frame scaling */ const Word16 shift /* i : shifting applied to y1, xn,... */ ) @@ -460,11 +406,12 @@ void transf_cdbk_enc_ivas_fx( Word16 trgtSvPos; #ifdef BASOP_NOGLOB_DECLARE_LOCAL Flag Overflow = 0; + move32(); #endif avq_bit_sFlag = 0; move16(); - if ( GT_16( st_fx->element_mode, EVS_MONO ) ) + if ( st_fx->element_mode > EVS_MONO ) { avq_bit_sFlag = 1; move16(); @@ -476,7 +423,7 @@ void transf_cdbk_enc_ivas_fx( Nsv = 8; move16(); - nBits = st_fx->acelp_cfg.AVQ_cdk_bits[shr( i_subfr, 6 )]; + nBits = st_fx->acelp_cfg.AVQ_cdk_bits[i_subfr >> 6]; /* Q0 */ move16(); /* increase # of AVQ allocated bits by unused bits from the previous subframe */ @@ -489,11 +436,7 @@ void transf_cdbk_enc_ivas_fx( *--------------------------------------------------------------*/ IF( EQ_16( st_fx->coder_type, INACTIVE ) ) { -#ifdef BASOP_NOGLOB gcode16 = round_fx_o( L_shl_o( gain_code, Q_new, &Overflow ), &Overflow ); -#else - gcode16 = round_fx( L_shl( gain_code, Q_new ) ); -#endif FOR( i = 0; i < L_SUBFR; i++ ) { /*x_tran[i] = xn[i] - *gain_pit * y1[i] - gain_code * y2[i];*/ @@ -501,14 +444,9 @@ void transf_cdbk_enc_ivas_fx( Ltmp = L_shl( Ltmp, add( 5, shift ) ); Ltmp = L_negate( Ltmp ); Ltmp = L_mac( Ltmp, xn[i], 16384 ); - Ltmp = L_msu( Ltmp, y1[i], *gain_pit ); -#ifdef BASOP_NOGLOB - Ltmp = L_shl_sat( Ltmp, sub( 1, shift ) ); - x_tran[i] = round_fx_sat( Ltmp ); /*Q_new-1 */ -#else - Ltmp = L_shl( Ltmp, sub( 1, shift ) ); - x_tran[i] = round_fx( Ltmp ); /*Q_new-1 */ -#endif + Ltmp = L_msu( Ltmp, y1[i], *gain_pit ); /* Q_new + 14 + shift */ + Ltmp = L_shl_sat( Ltmp, sub( 1, shift ) ); /* Q_new + 15 */ + x_tran[i] = round_fx_sat( Ltmp ); /*Q_new-1 */ } find_cn_fx( x_tran, Ap, p_Aq, x_in ); } @@ -556,15 +494,9 @@ void transf_cdbk_enc_ivas_fx( { /*fcorr += fx_tran[i]*(float)ix_norm[i];*/ /*fener += (float)ix_norm[i]*(float)ix_norm[i];*/ -#ifdef BASOP_NOGLOB stmp = shl_sat( x_norm[i], Q_AVQ_OUT ); L_corr = L_mac_sat( L_corr, x_tran[i], stmp ); L_ener = L_mac_sat( L_ener, stmp, stmp ); -#else - stmp = shl( x_norm[i], Q_AVQ_OUT ); - L_corr = L_mac( L_corr, x_tran[i], stmp ); - L_ener = L_mac( L_ener, stmp, stmp ); -#endif } L_ener = L_max( L_ener, 1 ); @@ -575,42 +507,30 @@ void transf_cdbk_enc_ivas_fx( m_corr = extract_h( L_shl( L_corr, e_corr ) ); e_corr = sub( 30, add( e_corr, sub( Qdct, Q_AVQ_OUT ) ) ); e_ener = norm_l( L_ener ); - m_ener = extract_h( L_shl( L_ener, e_ener ) ); + m_ener = extract_h( L_shl( L_ener, e_ener ) ); /* 30 - e-ener */ e_ener = sub( 30, e_ener ); IF( GT_16( m_corr, m_ener ) ) { - m_corr = shr( m_corr, 1 ); + m_corr = shr( m_corr, 1 ); /* e_corr + 1 */ e_corr = add( e_corr, 1 ); } - m_corr = div_s( m_corr, m_ener ); + m_corr = div_s( m_corr, m_ener ); /* e_corr - e_ener */ e_corr = sub( e_corr, e_ener ); -#ifdef BASOP_NOGLOB Ltmp = L_shl_sat( m_corr, s_min( add( e_corr, 1 ), 31 ) ); /* Lgain in Q16 */ -#else - Ltmp = L_shl( m_corr, s_min( add( e_corr, 1 ), 31 ) ); /* Lgain in Q16 */ -#endif IF( EQ_16( st_fx->coder_type, INACTIVE ) ) { Ltmp1 = L_max( gain_code, 1 ); e_den = norm_l( Ltmp1 ); -#ifdef BASOP_NOGLOB m_den = extract_h( L_shl_sat( Ltmp1, e_den ) ); -#else - m_den = extract_h( L_shl( Ltmp1, e_den ) ); -#endif /* ensure m_corr < m_den */ test(); IF( m_corr > 0 && m_den > 0 ) { m_corr = div_s( 16384, m_den ); e_corr = sub( 14 + 4, e_den ); - Ltmp = L_shr( Mult_32_16( Ltmp, m_corr ), e_corr ); /*Q12*/ -#ifdef BASOP_NOGLOB - stmp = round_fx_o( L_shl_o( Ltmp, 16, &Overflow ), &Overflow ); -#else - stmp = round_fx( L_shl( Ltmp, 16 ) ); -#endif + Ltmp = L_shr( Mult_32_16( Ltmp, m_corr ), e_corr ); /*Q12*/ + stmp = round_fx_o( L_shl_o( Ltmp, 16, &Overflow ), &Overflow ); /* Q12 */ } ELSE { @@ -619,24 +539,20 @@ void transf_cdbk_enc_ivas_fx( } IF( GT_32( st_fx->core_brate, 56000 ) ) { - index = usquant_fx( stmp, &stmp, G_AVQ_MIN_INACT_64k_Q12, G_AVQ_DELTA_INACT_64k_Q12 >> 1, ( 1 << G_AVQ_BITS ) ); + index = usquant_fx( stmp, &stmp, G_AVQ_MIN_INACT_64k_Q12, G_AVQ_DELTA_INACT_64k_Q12 >> 1, ( 1 << G_AVQ_BITS ) ); /* Q0 */ } ELSE IF( GT_32( st_fx->core_brate, 42000 ) ) { - index = usquant_fx( stmp, &stmp, G_AVQ_MIN_INACT_48k_Q12, G_AVQ_DELTA_INACT_48k_Q12 >> 1, ( 1 << G_AVQ_BITS ) ); + index = usquant_fx( stmp, &stmp, G_AVQ_MIN_INACT_48k_Q12, G_AVQ_DELTA_INACT_48k_Q12 >> 1, ( 1 << G_AVQ_BITS ) ); /* Q0 */ } ELSE { - index = usquant_fx( stmp, &stmp, G_AVQ_MIN_INACT_Q12, G_AVQ_DELTA_INACT_Q12 >> 1, ( 1 << G_AVQ_BITS ) ); + index = usquant_fx( stmp, &stmp, G_AVQ_MIN_INACT_Q12, G_AVQ_DELTA_INACT_Q12 >> 1, ( 1 << G_AVQ_BITS ) ); /* Q0 */ } Ltmp = Mult_32_16( gain_code, stmp ); /* Q16 * Q12 - 15 -> Q13*/ -#ifdef BASOP_NOGLOB - Ltmp = L_shl_sat( Ltmp, 5 ); /* Q13 -> Q18*/ - *gain_preQ = round_fx_sat( Ltmp ); /* Q2*/ -#else - Ltmp = L_shl( Ltmp, 5 ); /* Q13 -> Q18*/ - *gain_preQ = round_fx( Ltmp ); /* Q2*/ -#endif + Ltmp = L_shl_sat( Ltmp, 5 ); /* Q13 -> Q18*/ + *gain_preQ = round_fx_sat( Ltmp ); /* Q2*/ + move16(); } ELSE { @@ -658,7 +574,7 @@ void transf_cdbk_enc_ivas_fx( { m_corr = div_s( 16384, m_den ); e_corr = sub( 14 - 8, e_den ); - Ltmp = L_shr( Mult_32_16( Ltmp, m_corr ), e_corr ); + Ltmp = L_shr( Mult_32_16( Ltmp, m_corr ), e_corr ); /* Q16 */ } ELSE { @@ -667,22 +583,23 @@ void transf_cdbk_enc_ivas_fx( test(); IF( LE_32( st_fx->core_brate, 42000 ) && GT_32( st_fx->core_brate, ACELP_24k40 ) ) { - index = gain_quant_fx( &Ltmp, &stmp, LG10_G_AVQ_MIN_32kbps_Q14, LG10_G_AVQ_MAX_Q13, G_AVQ_BITS, &e_den ); + index = gain_quant_fx( &Ltmp, &stmp, LG10_G_AVQ_MIN_32kbps_Q14, LG10_G_AVQ_MAX_Q13, G_AVQ_BITS, &e_den ); /* Q0 */ } ELSE { - index = gain_quant_fx( &Ltmp, &stmp, LG10_G_AVQ_MIN_Q14, LG10_G_AVQ_MAX_Q13, G_AVQ_BITS, &e_den ); + index = gain_quant_fx( &Ltmp, &stmp, LG10_G_AVQ_MIN_Q14, LG10_G_AVQ_MAX_Q13, G_AVQ_BITS, &e_den ); /* Q0 */ } Ltmp = L_mult( stmp, Es_pred_loc ); /* Q0*Q8 -> Q9*/ Ltmp = L_shl( Ltmp, add( e_den, 9 ) ); /* Q18*/ *gain_preQ = round_fx( Ltmp ); /* Q2*/ + move16(); } push_indice( st_fx->hBstr, IND_AVQ_GAIN, index, G_AVQ_BITS ); /*--------------------------------------------------------------* * Encode and multiplex subvectors into bit-stream *--------------------------------------------------------------*/ - trgtSvPos = Nsv - 1; + trgtSvPos = sub( Nsv, 1 ); move16(); test(); test(); @@ -712,7 +629,8 @@ void transf_cdbk_enc_ivas_fx( { i = s_min( *unbits, 16 ); push_indice( st_fx->hBstr, IND_UNUSED, 0, i ); - *unbits -= i; + *unbits = sub( *unbits, i ); + move16(); } } @@ -722,11 +640,7 @@ void transf_cdbk_enc_ivas_fx( FOR( i = 0; i < Nsv * WIDTH_BAND; i++ ) { -#ifdef BASOP_NOGLOB x_tran[i] = shl_o( x_norm[i], Q_AVQ_OUT_DEC, &Overflow ); -#else - x_tran[i] = shl( x_norm[i], Q_AVQ_OUT_DEC ); -#endif move16(); } set16_fx( x_tran + Nsv * WIDTH_BAND, 0, sub( L_SUBFR, i_mult2( WIDTH_BAND, Nsv ) ) ); @@ -736,7 +650,7 @@ void transf_cdbk_enc_ivas_fx( test(); IF( NE_16( st_fx->coder_type, INACTIVE ) && LE_32( st_fx->core_brate, MAX_BRATE_AVQ_EXC_TD ) && GE_32( st_fx->core_brate, MIN_BRATE_AVQ_EXC ) && !harm_flag_acelp ) { - Copy( x_tran, code_preQ, L_SUBFR ); + Copy( x_tran, code_preQ, L_SUBFR ); /* Q_AVQ_OUT_DEC */ } ELSE { @@ -762,7 +676,7 @@ void transf_cdbk_enc_ivas_fx( } st_fx->last_nq_preQ = nq[7]; move16(); -#if 1 // def IVAS_CODE + /* TD pre-quantizer: in extreme cases at subframe boundaries, lower the preemphasis memory to avoid a saturation */ test(); test(); @@ -771,23 +685,21 @@ void transf_cdbk_enc_ivas_fx( test(); IF( GT_16( st_fx->element_mode, EVS_MONO ) && NE_16( st_fx->coder_type, INACTIVE ) && GE_32( st_fx->core_brate, MIN_BRATE_AVQ_EXC ) && LE_32( st_fx->core_brate, MAX_BRATE_AVQ_EXC_TD ) && !harm_flag_acelp && code_preQ[0] != 0 ) { - // if ( (float) abs( st->last_code_preq ) > 16.0f * (float) fabs( code_preQ[0] ) ) - if ( GT_16( abs_s( st_fx->last_code_preq ), shl_sat( abs_s( code_preQ[0] ), 4 ) ) ) + IF( GT_16( abs_s( st_fx->last_code_preq ), shl_sat( abs_s( code_preQ[0] ), 4 ) ) ) { st_fx->mem_preemp_preQ_fx = shr( st_fx->mem_preemp_preQ_fx, 4 ); move16(); } - // else if ( (float) abs( st->last_code_preq ) > 8.0f * (float) fabs( code_preQ[0] ) ) - if ( GT_16( abs_s( st_fx->last_code_preq ), shl_sat( abs_s( code_preQ[0] ), 3 ) ) ) + ELSE IF( GT_16( abs_s( st_fx->last_code_preq ), shl_sat( abs_s( code_preQ[0] ), 3 ) ) ) { st_fx->mem_preemp_preQ_fx = shr( st_fx->mem_preemp_preQ_fx, 3 ); move16(); } } - // st->last_code_preq = (int16_t) code_preQ[L_SUBFR - 1]; st_fx->last_code_preq = shr( code_preQ[L_SUBFR - 1], 9 ); // Q0 -#endif + move16(); + PREEMPH_FX( code_preQ, FAC_PRE_AVQ_FX, L_SUBFR, &( st_fx->mem_preemp_preQ_fx ) ); /*--------------------------------------------------------------* @@ -817,16 +729,13 @@ void transf_cdbk_enc_ivas_fx( updt_tar_HR_fx( cn, cn, code_preQ, *gain_preQ, sub( Q_new, add( -15 + 2, Q_AVQ_OUT_DEC ) ), L_SUBFR ); updt_tar_HR_fx( xn, xn, x_tran, *gain_preQ, sub( Q_new, add( -15 + 2, Q_AVQ_OUT_DEC ) ), L_SUBFR ); -#ifdef BASOP_NOGLOB - *gain_pit = corr_xy1_fx( xn, y1, g_corr, L_SUBFR, 0, &Overflow ); -#else - *gain_pit = corr_xy1_fx( xn, y1, g_corr, L_SUBFR, 0 ); -#endif + *gain_pit = corr_xy1_fx( xn, y1, g_corr, L_SUBFR, 0, &Overflow ); /* Q14 */ + move16(); /* clip gain if necessary to avoid problems at decoder */ test(); if ( EQ_16( clip_gain, 1 ) && GT_16( *gain_pit, 15565 ) ) { - *gain_pit = 15565; + *gain_pit = 15565; /* 0.95 in Q14 */ move16(); } updt_tar_fx( xn, xn2, y1, *gain_pit, L_SUBFR ); @@ -842,16 +751,16 @@ void transf_cdbk_enc_ivas_fx( *-------------------------------------------------------------------*/ static void find_cn_fx( - const Word16 xn[], /* i : target signal */ - const Word16 Ap[], /* i : weighted LP filter coefficients */ - const Word16 *p_Aq, /* i : 12k8 LP coefficients */ - Word16 cn[] /* o : target signal in residual domain */ + const Word16 xn[], /* i : target signal Qx*/ + const Word16 Ap[], /* i : weighted LP filter coefficients Q12*/ + const Word16 *p_Aq, /* i : 12k8 LP coefficients Q12*/ + Word16 cn[] /* o : target signal in residual domain Qx*/ ) { Word16 tmp, tmp_fl[L_SUBFR + M]; set16_fx( tmp_fl, 0, M ); - Copy( xn, tmp_fl + M, L_SUBFR ); + Copy( xn, tmp_fl + M, L_SUBFR ); /* Qx */ tmp = 0; move16(); PREEMPH_FX( tmp_fl + M, PREEMPH_FAC_16k, L_SUBFR, &tmp ); @@ -865,12 +774,12 @@ static void find_cn_fx( /*-----------------------------------------------------------------* * Transform domain contribution encoding *-----------------------------------------------------------------*/ -Word16 gain_quant_fx( /* o: quantization index */ - Word32 *gain, /* i: quantized gain (Q16) */ - Word16 *gain16, /* o: quantized gain (expg) */ - const Word16 c_min, /* i: log10 of lower limit in Q14 */ - const Word16 c_max, /* i: log10 of upper limit in Q13 */ - const Word16 bits, /* i: number of bits to quantize */ +Word16 gain_quant_fx( /* o: quantization index Q0*/ + Word32 *gain, /* i: quantized gain Q16*/ + Word16 *gain16, /* o: quantized gain expg*/ + const Word16 c_min, /* i: log10 of lower limit in Q14*/ + const Word16 c_max, /* i: log10 of upper limit in Q13*/ + const Word16 bits, /* i: number of bits to quantize Q0*/ Word16 *expg /* o: output exponent of gain16 */ ) { @@ -903,25 +812,20 @@ Word16 gain_quant_fx( /* o: quantization index /*tmp1 = sub(c_max,c_min); Q14*/ /*tmp2 = sub(c_gain,c_min); Q14*/ -#ifdef BASOP_NOGLOB tmp1 = msu_r_sat( L_deposit_h( c_max /*in Q13 already*/ ), c_min, 16384 ); /*Q13*/ tmp2 = msu_r_sat( L_deposit_h( c_gain /*in Q13 already*/ ), c_min, 16384 ); /*Q13*/ -#else - tmp1 = msu_r( L_deposit_h( c_max /*in Q13 already*/ ), c_min, 16384 ); /*Q13*/ - tmp2 = msu_r( L_deposit_h( c_gain /*in Q13 already*/ ), c_min, 16384 ); /*Q13*/ -#endif IF( tmp1 != 0 ) { exp = norm_s( tmp1 ); - frac = div_s( shl( 1, sub( 14, exp ) ), tmp1 ); /*Q(15-exp)*/ - L_tmp = L_mult( tmp2, frac ); /*Q(30-exp)*/ - L_tmp = Mult_32_16( L_tmp, sub( levels, 1 ) ); /*Q(15-exp)*/ - index = extract_l( L_shr( L_add( L_tmp, shr( 1 << 14, exp ) ), sub( 15, exp ) ) ); + frac = div_s( shl( 1, sub( 14, exp ) ), tmp1 ); /*Q(15-exp)*/ + L_tmp = L_mult( tmp2, frac ); /*Q(30-exp)*/ + L_tmp = Mult_32_16( L_tmp, sub( levels, 1 ) ); /*Q(15-exp)*/ + index = extract_l( L_shr( L_add( L_tmp, shr( 1 << 14, exp ) ), sub( 15, exp ) ) ); /* Q0 */ } ELSE { - L_tmp = L_mult( tmp2, sub( levels, 1 ) ); /*Q15*/ - index = extract_l( L_shr( L_add( L_tmp, 1 << 14 ), 15 ) ); + L_tmp = L_mult( tmp2, sub( levels, 1 ) ); /*Q15*/ + index = extract_l( L_shr( L_add( L_tmp, 1 << 14 ), 15 ) ); /* Q0 */ } index = s_max( index, 0 ); diff --git a/lib_enc/enc_nelp.c b/lib_enc/enc_nelp.c deleted file mode 100644 index fd4f3cb7c53af6bc1a4a149c6db6799b8f39655e..0000000000000000000000000000000000000000 --- a/lib_enc/enc_nelp.c +++ /dev/null @@ -1,42 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include "cnst.h" -#include "rom_com.h" -#include "prot.h" -#include "wmc_auto.h" diff --git a/lib_enc/enc_nelp_fx.c b/lib_enc/enc_nelp_fx.c index 004b43fd364f96b4fc9196af485e3aa38531e207..c3eb2ae189911eb524d0ed32b015b0a58959554d 100644 --- a/lib_enc/enc_nelp_fx.c +++ b/lib_enc/enc_nelp_fx.c @@ -43,17 +43,17 @@ /*==============================================================================*/ void encod_nelp_fx( Encoder_State *st_fx, /* i/o: state structure */ - const Word16 *speech_fx, /* i : input speech */ - const Word16 Aw_fx[], /* i : weighted A(z) unquantized for subframes */ - const Word16 Aq_fx[], /* i : 12k8 Lp coefficient */ - Word16 *res_fx, /* o : residual signal */ - Word16 *synth_fx, /* o : core synthesis */ - Word16 *tmp_noise_fx, /* o : long-term noise energy */ - Word16 *exc_fx, /* i/o: current non-enhanced excitation */ - Word16 *exc2_fx, /* i/o: current enhanced excitation */ - Word16 *pitch_buf_fx, /* o : floating pitch values for each subframe */ - Word16 *voice_factors_fx, /* o : voicing factors */ - Word16 *bwe_exc_fx, /* o : excitation for SWB TBE */ + const Word16 *speech_fx, /* i : input speech Q_new-1*/ + const Word16 Aw_fx[], /* i : weighted A(z) unquantized for subframes Q12*/ + const Word16 Aq_fx[], /* i : 12k8 Lp coefficient Q12*/ + Word16 *res_fx, /* o : residual signal Q_new*/ + Word16 *synth_fx, /* o : core synthesis Q_new*/ + Word16 *tmp_noise_fx, /* o : long-term noise energy Q0*/ + Word16 *exc_fx, /* i/o: current non-enhanced excitation Q_new*/ + Word16 *exc2_fx, /* i/o: current enhanced excitation Q_new*/ + Word16 *pitch_buf_fx, /* o : floating pitch values for each subframe Q6*/ + Word16 *voice_factors_fx, /* o : voicing factors Q15*/ + Word16 *bwe_exc_fx, /* o : excitation for SWB TBE Q_new*/ Word16 Q_new, Word16 shift @@ -69,6 +69,7 @@ void encod_nelp_fx( Word16 saved_Q_new = Q_new; Word16 reduce_gains = 0; + move16(); LPD_state_HANDLE hLPDmem = st_fx->hLPDmem; SC_VBR_ENC_HANDLE hSC_VBR = st_fx->hSC_VBR; @@ -95,13 +96,13 @@ void encod_nelp_fx( * target in residual domain "cn" * - Compute impulse response, h1[], of weighted synthesis filter *----------------------------------------------------------------*/ - Copy( &res_fx[i_subfr], &exc_fx[i_subfr], L_SUBFR ); + Copy( &res_fx[i_subfr], &exc_fx[i_subfr], L_SUBFR ); /* Q_new */ find_targets_fx( speech_fx, hLPDmem->mem_syn, i_subfr, &hLPDmem->mem_w0, p_Aq_fx, res_fx, L_SUBFR, p_Aw_fx, TILT_FAC_FX, xn_fx, NULL, h1_fx ); /* scale xn[] and h1[] to avoid overflow in dot_product12() */ - Scale_sig( xn_fx, L_SUBFR, shift ); /* scaling of xn[] to limit dynamic at 12 bits */ + Scale_sig( xn_fx, L_SUBFR, shift ); /* scaling of xn[] to limit dynamic at 12 bits Q_new -1 + shift */ IF( i_subfr == 0 ) { @@ -109,11 +110,12 @@ void encod_nelp_fx( IF( EQ_16( hSC_VBR->Local_VAD, 1 ) && EQ_16( st_fx->bwidth, NB ) ) { reduce_gains = 1; + move16(); } nelp_encoder_fx( st_fx, res_fx, exc_nelp_fx, &Q_new, reduce_gains ); - Scale_sig( exc_nelp_fx, L_FRAME, ( saved_Q_new - Q_new ) ); + Scale_sig( exc_nelp_fx, L_FRAME, ( saved_Q_new - Q_new ) ); /* saved_Q_new*/ } @@ -137,36 +139,32 @@ void encod_nelp_fx( move16(); } - Copy( exc_nelp_fx, exc_fx, L_FRAME ); + Copy( exc_nelp_fx, exc_fx, L_FRAME ); /* Q_new */ /*-----------------------------------------------------------------* * Updates: last value of new target is stored in mem_w0 *-----------------------------------------------------------------*/ -#ifdef BASOP_NOGLOB hLPDmem->mem_w0 = sub_sat( shr_sat( xn_fx[L_SUBFR - 1], shift ), shr( exc_fx[L_FRAME - 1], 1 ) ); -#else - hLPDmem->mem_w0 = sub( shr( xn_fx[L_SUBFR - 1], shift ), shr( exc_fx[L_FRAME - 1], 1 ) ); -#endif move16(); /*Q_new-1 */ hLPDmem->tilt_code = 0; - move16(); /* purely unvoiced */ - hSC_VBR->prev_tilt_code_fx = hLPDmem->tilt_code; + move16(); /* purely unvoiced */ + hSC_VBR->prev_tilt_code_fx = hLPDmem->tilt_code; /* Q15 */ move16(); - Copy( exc_fx, exc2_fx, L_FRAME ); + Copy( exc_fx, exc2_fx, L_FRAME ); /* Q_new */ hSC_VBR->prev_ppp_gain_pit_fx = 0; move16(); hLPDmem->dm_fx.prev_state = 0; move16(); - hLPDmem->dm_fx.prev_gain_pit[0] = hSC_VBR->prev_ppp_gain_pit_fx; + hLPDmem->dm_fx.prev_gain_pit[0] = hSC_VBR->prev_ppp_gain_pit_fx; /* Q14 */ move16(); FOR( j = 1; j < 5; j++ ) { - hLPDmem->dm_fx.prev_gain_pit[j] = hLPDmem->dm_fx.prev_gain_pit[j - 1]; + hLPDmem->dm_fx.prev_gain_pit[j] = hLPDmem->dm_fx.prev_gain_pit[j - 1]; /* Q14 */ move16(); } interp_code_5over2_fx( exc2_fx, bwe_exc_fx, L_FRAME ); @@ -224,7 +222,7 @@ void encod_nelp_ivas_fx( { set16_fx( hSC_VBR->nelp_lp_fit_mem, 0, NELP_LP_ORDER * 2 ); } - Scale_sig( hSC_VBR->nelp_lp_fit_mem, NELP_LP_ORDER * 2, sub( Q_new, st_fx->prev_Q_new ) ); + Scale_sig( hSC_VBR->nelp_lp_fit_mem, NELP_LP_ORDER * 2, sub( Q_new, st_fx->prev_Q_new ) ); /* Q_new */ pz_filter_sp_fx( num_nelp_lp_fx, den_nelp_lp_fx, res_fx, res_fx, hSC_VBR->nelp_lp_fit_mem, NELP_LP_ORDER, NELP_LP_ORDER, L_FRAME, 3 ); /*16-Q of filter coeff*/ } @@ -241,13 +239,13 @@ void encod_nelp_ivas_fx( * target in residual domain "cn" * - Compute impulse response, h1[], of weighted synthesis filter *----------------------------------------------------------------*/ - Copy( &res_fx[i_subfr], &exc_fx[i_subfr], L_SUBFR ); + Copy( &res_fx[i_subfr], &exc_fx[i_subfr], L_SUBFR ); /* Q_new */ find_targets_ivas_fx( speech_fx, hLPDmem->mem_syn, i_subfr, &hLPDmem->mem_w0, p_Aq_fx, res_fx, L_SUBFR, p_Aw_fx, TILT_FAC_FX, xn_fx, NULL, h1_fx ); /* scale xn[] and h1[] to avoid overflow in dot_product12() */ - Scale_sig( xn_fx, L_SUBFR, shift ); /* scaling of xn[] to limit dynamic at 12 bits */ + Scale_sig( xn_fx, L_SUBFR, shift ); /* scaling of xn[] to limit dynamic at 12 bits Q_new-1+shift */ IF( i_subfr == 0 ) { @@ -260,7 +258,7 @@ void encod_nelp_ivas_fx( nelp_encoder_ivas_fx( st_fx, res_fx, exc_nelp_fx, &Q_new, reduce_gains ); - Scale_sig( exc_nelp_fx, L_FRAME, ( saved_Q_new - Q_new ) ); + Scale_sig( exc_nelp_fx, L_FRAME, ( saved_Q_new - Q_new ) ); /* saved_Q_new */ } @@ -275,42 +273,38 @@ void encod_nelp_ivas_fx( p_Aw_fx += ( M + 1 ); p_Aq_fx += ( M + 1 ); - *pitch_buf_fx = L_SUBFR_Q6; + *pitch_buf_fx = L_SUBFR_Q6; /* Q6 */ move16(); pitch_buf_fx++; } - Copy( exc_nelp_fx, exc_fx, L_FRAME ); + Copy( exc_nelp_fx, exc_fx, L_FRAME ); /* Q_new */ /*-----------------------------------------------------------------* * Updates: last value of new target is stored in mem_w0 *-----------------------------------------------------------------*/ -#ifdef BASOP_NOGLOB hLPDmem->mem_w0 = sub_sat( shr_sat( xn_fx[L_SUBFR - 1], shift ), shr( exc_fx[L_FRAME - 1], 1 ) ); -#else - hLPDmem->mem_w0 = sub( shr( xn_fx[L_SUBFR - 1], shift ), shr( exc_fx[L_FRAME - 1], 1 ) ); -#endif move16(); /*Q_new-1 */ hLPDmem->tilt_code = 0; move16(); /* purely unvoiced */ hSC_VBR->prev_tilt_code_fx = hLPDmem->tilt_code; move16(); - Copy( exc_fx, exc2_fx, L_FRAME ); + Copy( exc_fx, exc2_fx, L_FRAME ); /* Q_new */ hSC_VBR->prev_ppp_gain_pit_fx = 0; move16(); hLPDmem->dm_fx.prev_state = 0; move16(); - hLPDmem->dm_fx.prev_gain_pit[0] = hSC_VBR->prev_ppp_gain_pit_fx; + hLPDmem->dm_fx.prev_gain_pit[0] = hSC_VBR->prev_ppp_gain_pit_fx; /* Q14 */ move16(); FOR( j = 1; j < 5; j++ ) { - hLPDmem->dm_fx.prev_gain_pit[j] = hLPDmem->dm_fx.prev_gain_pit[j - 1]; + hLPDmem->dm_fx.prev_gain_pit[j] = hLPDmem->dm_fx.prev_gain_pit[j - 1]; /* Q14 */ move16(); } interp_code_5over2_fx( exc2_fx, bwe_exc_fx, L_FRAME ); diff --git a/lib_enc/enc_pit_exc.c b/lib_enc/enc_pit_exc.c deleted file mode 100644 index fd4f3cb7c53af6bc1a4a149c6db6799b8f39655e..0000000000000000000000000000000000000000 --- a/lib_enc/enc_pit_exc.c +++ /dev/null @@ -1,42 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include "cnst.h" -#include "rom_com.h" -#include "prot.h" -#include "wmc_auto.h" diff --git a/lib_enc/enc_pit_exc_fx.c b/lib_enc/enc_pit_exc_fx.c index 08f6a7a3bdbd7df7d556bea5214432594b01b609..3ed50017cc30c56612bd19f149abfccc203e7fd2 100644 --- a/lib_enc/enc_pit_exc_fx.c +++ b/lib_enc/enc_pit_exc_fx.c @@ -6,7 +6,6 @@ #include "cnst.h" /* Common constants */ #include "rom_com_fx.h" /* Static table prototypes */ #include "rom_com.h" /* Static table prototypes */ -#include "prot.h" /* Function prototypes */ #include "prot_fx.h" /* Function prototypes */ #include "prot_fx_enc.h" /* Function prototypes */ @@ -48,21 +47,21 @@ /*=======================================================================*/ void enc_pit_exc_fx( Encoder_State *st_fx, /* i/o: State structure */ - const Word16 *speech, /* i : Input speech */ - const Word16 Aw[], /* i : weighted A(z) unquantized for subframes */ - const Word16 Aq[], /* i : 12k8 Lp coefficient */ - const Word16 Es_pred, /* i : predicted scaled innov. energy */ - const Word16 *res, /* i : residual signal */ - Word16 *synth, /* i/o: core synthesis */ - Word16 *exc, /* i/o: current non-enhanced excitation */ - Word16 *T0, /* i/o: close loop integer pitch */ - Word16 *T0_frac, /* i/o: close-loop pitch period - fractional part */ - Word16 *pitch_buf, /* i/o: Fractionnal per subframe pitch */ - const Word16 nb_subfr, /* i : Number of subframe considered */ - Word16 *gpit, /* o : pitch mean gpit */ - Word16 *saved_bit_pos, /* o : saved position in the bitstream before pitch contribution */ - const Word16 tdm_Pitch_reuse_flag, /* i : primary channel pitch reuse flag */ - const Word16 tdm_Pri_pitch_buf[], /* i : primary channel pitch buffer */ + const Word16 *speech, /* i : Input speech Q_new-1*/ + const Word16 Aw[], /* i : weighted A(z) unquantized for subframes Q12*/ + const Word16 Aq[], /* i : 12k8 Lp coefficient Q12*/ + const Word16 Es_pred, /* i : predicted scaled innov. energy Q8*/ + const Word16 *res, /* i : residual signal Q_new*/ + Word16 *synth, /* i/o: core synthesis Q_new*/ + Word16 *exc, /* i/o: current non-enhanced excitation Q_new*/ + Word16 *T0, /* i/o: close loop integer pitch Q0*/ + Word16 *T0_frac, /* i/o: close-loop pitch period - fractional part Q0*/ + Word16 *pitch_buf, /* i/o: Fractionnal per subframe pitch Q6*/ + const Word16 nb_subfr, /* i : Number of subframe considered Q0*/ + Word16 *gpit, /* o : pitch mean gpit Q15*/ + Word16 *saved_bit_pos, /* o : saved position in the bitstream before pitch contribution Q0*/ + const Word16 tdm_Pitch_reuse_flag, /* i : primary channel pitch reuse flag Q0*/ + const Word16 tdm_Pri_pitch_buf[], /* i : primary channel pitch buffer Q6*/ Word16 Q_new, Word16 shift ) { @@ -87,6 +86,7 @@ void enc_pit_exc_fx( Word16 cum_gpit, gpit_tmp; Word32 Local_BR, Pitch_BR; Word16 Pitch_CT, unbits_PI = 0; /* saved bits for PI */ + move16(); Word32 norm_gain_code; Word16 pitch_limit_flag; Word16 h2[PIT_EXC_L_SUBFR + ( M + 1 )]; /* Impulse response vector */ @@ -104,6 +104,7 @@ void enc_pit_exc_fx( LPD_state_HANDLE hLPDmem = st_fx->hLPDmem; #ifdef BASOP_NOGLOB_DECLARE_LOCAL Flag Overflow = 0; + move32(); #endif /*------------------------------------------------------------------* @@ -114,11 +115,13 @@ void enc_pit_exc_fx( move16(); /* always extended pitch Q range */ use_fcb = 0; unbits_PI = 0; - test(); - test(); + move16(); + move16(); Pitch_CT = GENERIC; move16(); + test(); + test(); IF( st_fx->GSC_IVAS_mode > 0 && ( st_fx->GSC_noisy_speech || GT_32( st_fx->core_brate, GSC_H_RATE_STG ) ) ) { Local_BR = ACELP_8k00; @@ -134,7 +137,7 @@ void enc_pit_exc_fx( Local_BR = ACELP_9k60; move32(); } - Pitch_BR = st_fx->core_brate; + Pitch_BR = st_fx->core_brate; /* Q0 */ move32(); } } @@ -148,7 +151,7 @@ void enc_pit_exc_fx( move16(); if ( EQ_16( st_fx->L_frame, L_FRAME16k ) ) { - Pitch_BR = st_fx->core_brate; + Pitch_BR = st_fx->core_brate; /* Q0 */ move32(); } } @@ -157,12 +160,12 @@ void enc_pit_exc_fx( Local_BR = ACELP_7k20; move32(); - Pitch_BR = st_fx->core_brate; + Pitch_BR = st_fx->core_brate; /* Q0 */ move32(); Pitch_CT = AUDIO; move16(); - if ( EQ_16( st_fx->L_frame, L_FRAME16k ) ) + IF( EQ_16( st_fx->L_frame, L_FRAME16k ) ) { Local_BR = ACELP_13k20; move32(); @@ -188,9 +191,9 @@ void enc_pit_exc_fx( cum_gpit = 0; move16(); - L_subfr = mult_r( st_fx->L_frame, div_s( 1, nb_subfr ) ); + L_subfr = mult_r( st_fx->L_frame, div_s( 1, nb_subfr ) ); /* Q0 */ - lp_flag = st_fx->acelp_cfg.ltf_mode; + lp_flag = st_fx->acelp_cfg.ltf_mode; /* Q0 */ test(); test(); @@ -245,27 +248,27 @@ void enc_pit_exc_fx( * target in residual domain "cn" * Compute impulse response, h1[], of weighted synthesis filter *----------------------------------------------------------------*/ - Copy( &res[i_subfr], &exc[i_subfr], L_subfr ); - /* condition on target (compared to float) has been put outside the loop */ -#if 1 // ndef BUG_FIX + Copy( &res[i_subfr], &exc[i_subfr], L_subfr ); /* Q_new */ + /* condition on target (compared to float) has been put outside the loop */ +#if 1 // ndef BUG_FIX find_targets_fx( speech, hLPDmem->mem_syn, i_subfr, &hLPDmem->mem_w0, p_Aq, res, L_subfr, p_Aw, st_fx->preemph_fac, xn, cn, h1 ); #else find_targets_fx( speech, hGSCEnc->mem_syn_tmp_fx, i_subfr, &hLPDmem->mem_w0, p_Aq, /*_DIFF_FLOAT_FIX_ --> Here I think mem_syn_tmp_fx should be used */ res, L_subfr, p_Aw, st_fx->preemph_fac, xn, cn, h1 ); #endif - Copy_Scale_sig( h1, h2, L_subfr, -2 ); + Copy_Scale_sig( h1, h2, L_subfr, -2 ); /* Q13 */ Scale_sig( h1, L_subfr, add( 1, shift ) ); /* set h1[] in Q14 with scaling for convolution */ /* scaling of xn[] to limit dynamic at 12 bits */ - Scale_sig( xn, L_subfr, shift ); + Scale_sig( xn, L_subfr, shift ); /* Q_new - 1 + shift */ /*----------------------------------------------------------------* * Close-loop pitch search and quantization * Adaptive exc. construction *----------------------------------------------------------------*/ *pt_pitch = pit_encode_fx( hBstr, st_fx->acelp_cfg.pitch_bits, Pitch_BR, 0, st_fx->L_frame, Pitch_CT, &pitch_limit_flag, i_subfr, exc, - L_subfr, st_fx->pitch, &T0_min, &T0_max, T0, T0_frac, h1, xn, tdm_Pitch_reuse_flag, tdm_Pri_pitch_buf ); + L_subfr, st_fx->pitch, &T0_min, &T0_max, T0, T0_frac, h1, xn, tdm_Pitch_reuse_flag, tdm_Pri_pitch_buf ); /* Q6 */ /*-----------------------------------------------------------------* * Find adaptive exitation *-----------------------------------------------------------------*/ @@ -276,7 +279,7 @@ void enc_pit_exc_fx( * or in case of floating point encoder & fixed p. decoder *-----------------------------------------------------------------*/ - clip_gain = gp_clip_fx( st_fx->element_mode, st_fx->core_brate, st_fx->voicing_fx, i_subfr, AUDIO, xn, st_fx->clip_var_fx, sub( shift_wsp, 1 ) ); + clip_gain = gp_clip_fx( st_fx->element_mode, st_fx->core_brate, st_fx->voicing_fx, i_subfr, AUDIO, xn, st_fx->clip_var_fx, sub( shift_wsp, 1 ) ); /* Q0 */ /*-----------------------------------------------------------------* * Codebook target computation @@ -284,7 +287,7 @@ void enc_pit_exc_fx( *-----------------------------------------------------------------*/ lp_select = lp_filt_exc_enc_fx( MODE1, AUDIO, i_subfr, exc, h1, - xn, y1, xn2, L_subfr, st_fx->L_frame, g_corr, clip_gain, &gain_pit, &lp_flag ); + xn, y1, xn2, L_subfr, st_fx->L_frame, g_corr, clip_gain, &gain_pit, &lp_flag ); /* Q0 */ IF( EQ_16( lp_flag, NORMAL_OPERATION ) ) { @@ -292,11 +295,7 @@ void enc_pit_exc_fx( } /*st_fx->lowrate_pitchGain = 0.9f * st_fx->lowrate_pitchGain + 0.1f * gain_pit;*/ -#ifdef BASOP_NOGLOB hSpMusClas->lowrate_pitchGain = round_fx_o( L_mac_o( L_mult( 29491, hSpMusClas->lowrate_pitchGain ), 6554, gain_pit, &Overflow ), &Overflow ); /*Q14*Q16(0.1) + Q15 -> Q15*/ -#else - hSpMusClas->lowrate_pitchGain = round_fx( L_mac( L_mult( 29491, hSpMusClas->lowrate_pitchGain ), 6554, gain_pit ) ); /*Q14*Q16(0.1) + Q15 -> Q15*/ -#endif gpit_tmp = gain_pit; move16(); /*Q14*/ @@ -312,12 +311,12 @@ void enc_pit_exc_fx( { IF( GE_32( st_fx->core_brate, MIN_RATE_FCB ) ) { - pit_idx = vquant_fx( &gain_pit, mean_gp_fx, &gain_pit, dic_gp_fx, 1, 32 ); + pit_idx = vquant_fx( &gain_pit, mean_gp_fx, &gain_pit, dic_gp_fx, 1, 32 ); /* Q0 */ push_indice_fx( hBstr, IND_PIT_IDX, pit_idx, 5 ); } ELSE { - pit_idx = vquant_fx( &gain_pit, mean_gp_fx, &gain_pit, dic_gp_fx, 1, 16 ); + pit_idx = vquant_fx( &gain_pit, mean_gp_fx, &gain_pit, dic_gp_fx, 1, 16 ); /* Q0 */ push_indice_fx( hBstr, IND_PIT_IDX, pit_idx, 4 ); } } @@ -329,7 +328,7 @@ void enc_pit_exc_fx( inov_encode_fx( st_fx, st_fx->core_brate, 0, st_fx->L_frame, st_fx->last_L_frame, GENERIC, st_fx->bwidth, 0, i_subfr, -1, p_Aq, gain_pit, cn, exc, h2, st_fx->hLPDmem->tilt_code, *pt_pitch, xn2, code, y2, &unbits_PI, 2 * L_SUBFR, shift ); - // PMT("code to be validated") + /*-----------------------------------------------------------------* * Gain encoding *-----------------------------------------------------------------*/ @@ -352,16 +351,11 @@ void enc_pit_exc_fx( } gp_clip_test_gain_pit_fx( st_fx->element_mode, st_fx->core_brate, gain_pit, st_fx->clip_var_fx ); -#ifdef BASOP_NOGLOB Lgcode = L_shl_sat( gain_code, Q_new ); /* scaled gain_code with Qnew -> Q16*/ gcode16 = round_fx_sat( Lgcode ); -#else - Lgcode = L_shl( gain_code, Q_new ); /* scaled gain_code with Qnew -> Q16*/ - gcode16 = round_fx( Lgcode ); -#endif IF( use_fcb != 0 ) { - hLPDmem->tilt_code = Est_tilt2( &exc[i_subfr], gain_pit, code, Lgcode, &voice_fac, shift ); + hLPDmem->tilt_code = Est_tilt2( &exc[i_subfr], gain_pit, code, Lgcode, &voice_fac, shift ); /* Q15 */ move16(); } ELSE @@ -374,36 +368,22 @@ void enc_pit_exc_fx( *-----------------------------------------------------------------*/ IF( use_fcb != 0 ) { - Ltmp = L_mult( gcode16, y2[L_subfr - 1] ); -#ifdef BASOP_NOGLOB - Ltmp = L_shl_o( Ltmp, add( 5, shift ), &Overflow ); + Ltmp = L_mult( gcode16, y2[L_subfr - 1] ); /* Q10 + Q_new */ + Ltmp = L_shl_o( Ltmp, add( 5, shift ), &Overflow ); /* Q15 + Q_new + shift */ Ltmp = L_negate( Ltmp ); - Ltmp = L_mac_o( Ltmp, xn[L_subfr - 1], 16384, &Overflow ); - Ltmp = L_msu_o( Ltmp, y1[L_subfr - 1], gain_pit, &Overflow ); - Ltmp = L_shl_o( Ltmp, sub( 1, shift ), &Overflow ); - hLPDmem->mem_w0 = round_fx_o( Ltmp, &Overflow ); /*Q_new-1 */ -#else - Ltmp = L_mult( gcode16, y2[L_subfr - 1] ); - Ltmp = L_shl( Ltmp, add( 5, shift ) ); - Ltmp = L_negate( Ltmp ); - Ltmp = L_mac( Ltmp, xn[L_subfr - 1], 16384 ); - Ltmp = L_msu( Ltmp, y1[L_subfr - 1], gain_pit ); - Ltmp = L_shl( Ltmp, sub( 1, shift ) ); - hLPDmem->mem_w0 = round_fx( Ltmp ); /*Q_new-1 */ -#endif + Ltmp = L_mac_o( Ltmp, xn[L_subfr - 1], 16384, &Overflow ); /* Q_new + Q15 + shift */ + Ltmp = L_msu_o( Ltmp, y1[L_subfr - 1], gain_pit, &Overflow ); /* Q_new + Q15 + shift */ + Ltmp = L_shl_o( Ltmp, sub( 1, shift ), &Overflow ); /* Q_new + 15 */ + hLPDmem->mem_w0 = round_fx_o( Ltmp, &Overflow ); /*Q_new-1 */ + move16(); } ELSE { - Ltmp = L_mult( xn[L_subfr - 1], 16384 ); -#ifdef BASOP_NOGLOB - Ltmp = L_msu_sat( Ltmp, y1[L_subfr - 1], gain_pit ); - Ltmp = L_shl_sat( Ltmp, sub( 1, shift ) ); - hLPDmem->mem_w0 = round_fx_sat( Ltmp ); /*Q_new-1 */ -#else - Ltmp = L_msu( Ltmp, y1[L_subfr - 1], gain_pit ); - Ltmp = L_shl( Ltmp, sub( 1, shift ) ); - hLPDmem->mem_w0 = round_fx( Ltmp ); /*Q_new-1 */ -#endif + Ltmp = L_mult( xn[L_subfr - 1], 16384 ); /* Q_new + 14 -shift */ + Ltmp = L_msu_sat( Ltmp, y1[L_subfr - 1], gain_pit ); /* Q_new + 14 -shift */ + Ltmp = L_shl_sat( Ltmp, sub( 1, shift ) ); /* Q_new + 15 */ + hLPDmem->mem_w0 = round_fx_sat( Ltmp ); /*Q_new-1 */ + move16(); } /*-----------------------------------------------------------------* @@ -415,19 +395,12 @@ void enc_pit_exc_fx( FOR( i = 0; i < L_subfr; i++ ) { /* code in Q9, gain_pit in Q14 */ - Ltmp = L_mult( gcode16, code[i] ); -#ifdef BASOP_NOGLOB - Ltmp = L_shl_o( Ltmp, 5, &Overflow ); - Ltmp = L_mac_o( Ltmp, exc[i + i_subfr], gain_pit, &Overflow ); - Ltmp = L_shl_o( Ltmp, 1, &Overflow ); /* saturation can occur here */ - exc[i + i_subfr] = round_fx_o( Ltmp, &Overflow ); -#else - Ltmp = L_mult( gcode16, code[i] ); - Ltmp = L_shl( Ltmp, 5 ); - Ltmp = L_mac( Ltmp, exc[i + i_subfr], gain_pit ); - Ltmp = L_shl( Ltmp, 1 ); /* saturation can occur here */ - exc[i + i_subfr] = round_fx( Ltmp ); -#endif + Ltmp = L_mult( gcode16, code[i] ); /* Q10 + Q_new */ + Ltmp = L_shl_o( Ltmp, 5, &Overflow ); /* Q15 + Q_new */ + Ltmp = L_mac_o( Ltmp, exc[i + i_subfr], gain_pit, &Overflow ); /* Q15 + Q_new */ + Ltmp = L_shl_o( Ltmp, 1, &Overflow ); /* saturation can occur here Q_new + Q16*/ + exc[i + i_subfr] = round_fx_o( Ltmp, &Overflow ); /* Q_new */ + move16(); } } ELSE @@ -435,14 +408,9 @@ void enc_pit_exc_fx( FOR( i = 0; i < L_subfr; i++ ) { - Ltmp = L_mult( exc[i + i_subfr], gain_pit ); -#ifdef BASOP_NOGLOB - Ltmp = L_shl_sat( Ltmp, 1 ); /* saturation can occur here */ - exc[i + i_subfr] = round_fx_sat( Ltmp ); -#else - Ltmp = L_shl( Ltmp, 1 ); /* saturation can occur here */ - exc[i + i_subfr] = round_fx( Ltmp ); -#endif + Ltmp = L_mult( exc[i + i_subfr], gain_pit ); /* Q15 + Q_new */ + Ltmp = L_shl_sat( Ltmp, 1 ); /* saturation can occur here Q16 + Q_new */ + exc[i + i_subfr] = round_fx_sat( Ltmp ); /* Q_new */ } } @@ -455,7 +423,7 @@ void enc_pit_exc_fx( IF( EQ_16( L_subfr, 5 * L_SUBFR ) ) { - cum_gpit = gpit_tmp; + cum_gpit = gpit_tmp; /* Q14 */ move16(); pt_pitch++; *pt_pitch = *( pt_pitch - 1 ); @@ -478,7 +446,7 @@ void enc_pit_exc_fx( { IF( i_subfr == 0 ) { - cum_gpit = mult_r( gpit_tmp, 13107 ); /* .4f*/ + cum_gpit = mult_r( gpit_tmp, 13107 /* .4f in Q15 */ ); /* Q14 */ pt_pitch++; *pt_pitch = *( pt_pitch - 1 ); move16(); @@ -488,7 +456,7 @@ void enc_pit_exc_fx( } ELSE { - cum_gpit = add( cum_gpit, mult_r( gpit_tmp, 19660 ) ); /*0.6*/ + cum_gpit = add( cum_gpit, mult_r( gpit_tmp, 19660 /* 0.6 in Q15 */ ) ); /* Q14 */ pt_pitch++; *pt_pitch = *( pt_pitch - 1 ); move16(); @@ -504,11 +472,11 @@ void enc_pit_exc_fx( { IF( i_subfr == 0 ) { - cum_gpit = mult_r( gpit_tmp, 16384 ); + cum_gpit = mult_r( gpit_tmp, 16384 /* 0.5 in Q15 */ ); /* Q14 */ } ELSE { - cum_gpit = add( cum_gpit, mult_r( gpit_tmp, 16384 ) ); + cum_gpit = add( cum_gpit, mult_r( gpit_tmp, 16384 /* 0.5 in Q15 */ ) ); /* Q14 */ } p_Aw += 2 * ( M + 1 ); move16(); @@ -521,7 +489,7 @@ void enc_pit_exc_fx( } ELSE IF( EQ_16( L_subfr, 4 * L_SUBFR ) ) { - cum_gpit = gpit_tmp; + cum_gpit = gpit_tmp; /* Q14 */ move16(); pt_pitch++; @@ -541,11 +509,11 @@ void enc_pit_exc_fx( IF( i_subfr == 0 ) { - cum_gpit = mult_r( gpit_tmp, 8192 ); + cum_gpit = mult_r( gpit_tmp, 8192 /* 0.25 in Q15 */ ); /* Q14 */ } ELSE { - cum_gpit = add( cum_gpit, mult_r( gpit_tmp, 8192 ) ); + cum_gpit = add( cum_gpit, mult_r( gpit_tmp, 8192 /* 0.25 in Q15 */ ) ); /* Q14 */ } pt_pitch++; @@ -554,31 +522,27 @@ void enc_pit_exc_fx( } } -#ifdef BASOP_NOGLOB - cum_gpit = shl_o( cum_gpit, 1, &Overflow ); /*Q15*/ -#else /* BASOP_NOGLOB */ - cum_gpit = shl( cum_gpit, 1 ); /*Q15*/ -#endif + cum_gpit = shl_o( cum_gpit, 1, &Overflow ); /*Q15*/ *gpit = round_fx( L_mac( L_mult( 3277, *gpit ), 29491, cum_gpit ) ); /*Q15*/ } void enc_pit_exc_ivas_fx( Encoder_State *st_fx, /* i/o: State structure */ - const Word16 *speech, /* i : Input speech */ - const Word16 Aw[], /* i : weighted A(z) unquantized for subframes */ - const Word16 Aq[], /* i : 12k8 Lp coefficient */ - const Word16 Es_pred, /* i : predicted scaled innov. energy */ - const Word16 *res, /* i : residual signal */ - Word16 *synth, /* i/o: core synthesis */ - Word16 *exc, /* i/o: current non-enhanced excitation */ - Word16 *T0, /* i/o: close loop integer pitch */ - Word16 *T0_frac, /* i/o: close-loop pitch period - fractional part */ - Word16 *pitch_buf, /* i/o: Fractionnal per subframe pitch */ - const Word16 nb_subfr, /* i : Number of subframe considered */ - Word16 *gpit, /* o : pitch mean gpit */ - Word16 *saved_bit_pos, /* o : saved position in the bitstream before pitch contribution */ - const Word16 tdm_Pitch_reuse_flag, /* i : primary channel pitch reuse flag */ - const Word16 tdm_Pri_pitch_buf[], /* i : primary channel pitch buffer */ + const Word16 *speech, /* i : Input speech Q_new-1*/ + const Word16 Aw[], /* i : weighted A(z) unquantized for subframes Q12*/ + const Word16 Aq[], /* i : 12k8 Lp coefficient Q12*/ + const Word16 Es_pred, /* i : predicted scaled innov. energy Q8*/ + const Word16 *res, /* i : residual signal Q_new*/ + Word16 *synth, /* i/o: core synthesis Q_new*/ + Word16 *exc, /* i/o: current non-enhanced excitation Q_new*/ + Word16 *T0, /* i/o: close loop integer pitch Q0*/ + Word16 *T0_frac, /* i/o: close-loop pitch period - fractional part Q0*/ + Word16 *pitch_buf, /* i/o: Fractionnal per subframe pitch Q6*/ + const Word16 nb_subfr, /* i : Number of subframe considered Q0*/ + Word16 *gpit, /* o : pitch mean gpit Q15*/ + Word16 *saved_bit_pos, /* o : saved position in the bitstream before pitch contribution Q0*/ + const Word16 tdm_Pitch_reuse_flag, /* i : primary channel pitch reuse flag Q0*/ + const Word16 tdm_Pri_pitch_buf[], /* i : primary channel pitch buffer Q6*/ Word16 Q_new, Word16 shift ) { @@ -614,12 +578,14 @@ void enc_pit_exc_ivas_fx( Word16 use_fcb; Word32 gc_mem[NB_SUBFR - 1]; /* gain_code from previous subframes */ Word16 gp_mem[NB_SUBFR - 1]; /* gain_pitch from previous subframes*/ - SP_MUS_CLAS_HANDLE hSpMusClas = st_fx->hSpMusClas; + Word16 h1_q15[PIT_EXC_L_SUBFR + ( M + 1 )]; + Word16 q_h1; BSTR_ENC_HANDLE hBstr = st_fx->hBstr; GSC_ENC_HANDLE hGSCEnc = st_fx->hGSCEnc; LPD_state_HANDLE hLPDmem = st_fx->hLPDmem; #ifdef BASOP_NOGLOB_DECLARE_LOCAL Flag Overflow = 0; + move32(); #endif /*------------------------------------------------------------------* @@ -630,13 +596,15 @@ void enc_pit_exc_ivas_fx( move16(); /* always extended pitch Q range */ use_fcb = 0; unbits_PI = 0; - test(); - test(); + move16(); + move16(); Pitch_CT = GENERIC; move16(); #ifdef MSAN_FIX set16_fx( cn1, 0, PIT_EXC_L_SUBFR ); #endif + test(); + test(); IF( st_fx->GSC_IVAS_mode > 0 && ( st_fx->GSC_noisy_speech || GT_32( st_fx->core_brate, GSC_H_RATE_STG ) ) ) { Local_BR = ACELP_8k00; @@ -706,9 +674,10 @@ void enc_pit_exc_ivas_fx( cum_gpit = 0; move16(); - L_subfr = mult_r( st_fx->L_frame, div_s( 1, nb_subfr ) ); + L_subfr = mult_r( st_fx->L_frame, div_s( 1, nb_subfr ) ); /* Q0 */ lp_flag = st_fx->acelp_cfg.ltf_mode; + move16(); test(); test(); @@ -737,13 +706,14 @@ void enc_pit_exc_ivas_fx( set16_fx( st_fx->acelp_cfg.fixed_cdk_index, 14, NB_SUBFR16k ); } - *saved_bit_pos = st_fx->next_bit_pos_fx; + *saved_bit_pos = st_fx->next_bit_pos_fx; /* Q0 */ move16(); /*------------------------------------------------------------------* * ACELP subframe loop *------------------------------------------------------------------*/ cn = NULL; + test(); if ( EQ_16( L_subfr, L_SUBFR ) || EQ_16( L_subfr, L_SUBFR * 2 ) ) { cn = cn1; @@ -763,24 +733,28 @@ void enc_pit_exc_ivas_fx( * target in residual domain "cn" * Compute impulse response, h1[], of weighted synthesis filter *----------------------------------------------------------------*/ - Copy( &res[i_subfr], &exc[i_subfr], L_subfr ); + Copy( &res[i_subfr], &exc[i_subfr], L_subfr ); /* Q_new */ /* condition on target (compared to float) has been put outside the loop */ - find_targets_ivas_fx( speech, hLPDmem->mem_syn, i_subfr, &hLPDmem->mem_w0, p_Aq, + find_targets_ivas_fx( speech, hGSCEnc->mem_syn_tmp_fx, i_subfr, &hGSCEnc->mem_w0_tmp_fx, p_Aq, res, L_subfr, p_Aw, st_fx->preemph_fac, xn, cn, h1 ); - Copy_Scale_sig( h1, h2, L_subfr, -2 ); - Scale_sig( h1, L_subfr, add( 1, shift ) ); /* set h1[] in Q14 with scaling for convolution */ + q_h1 = sub( 14, norm_s( h1[0] ) ); + Copy_Scale_sig( h1, h2, L_subfr, sub( 11, q_h1 ) ); /*Q11*/ /* scaling of xn[] to limit dynamic at 12 bits */ - Scale_sig( xn, L_subfr, shift ); + Scale_sig( xn, L_subfr, shift ); /* Q_new - 1 + shift */ /*----------------------------------------------------------------* * Close-loop pitch search and quantization * Adaptive exc. construction *----------------------------------------------------------------*/ + *pt_pitch = pit_encode_ivas_fx( hBstr, st_fx->acelp_cfg.pitch_bits, Pitch_BR, 0, st_fx->L_frame, Pitch_CT, &pitch_limit_flag, i_subfr, exc, - L_subfr, st_fx->pitch, &T0_min, &T0_max, T0, T0_frac, h1, xn, tdm_Pitch_reuse_flag, tdm_Pri_pitch_buf ); + L_subfr, st_fx->pitch, &T0_min, &T0_max, T0, T0_frac, h1, xn, tdm_Pitch_reuse_flag, tdm_Pri_pitch_buf, Q_new ); /* Q6 */ + move16(); + Scale_sig( h1, L_subfr, sub( 14, q_h1 ) ); /* set h1[] in Q14 with scaling for convolution Q14*/ + /*-----------------------------------------------------------------* * Find adaptive exitation *-----------------------------------------------------------------*/ @@ -791,28 +765,22 @@ void enc_pit_exc_ivas_fx( * or in case of floating point encoder & fixed p. decoder *-----------------------------------------------------------------*/ - clip_gain = gp_clip_fx( st_fx->element_mode, st_fx->core_brate, st_fx->voicing_fx, i_subfr, AUDIO, xn, st_fx->clip_var_fx, sub( shift_wsp, 1 ) ); + clip_gain = gp_clip_fx( st_fx->element_mode, st_fx->core_brate, st_fx->voicing_fx, i_subfr, AUDIO, xn, st_fx->clip_var_fx, sub( shift_wsp, 1 ) ); /* Q0 */ /*-----------------------------------------------------------------* * Codebook target computation * (No LP filtering of the adaptive excitation) *-----------------------------------------------------------------*/ + Copy_Scale_sig( h1, h1_q15, L_subfr, 1 ); // Q14 -> Q15 - lp_select = lp_filt_exc_enc_fx( MODE1, AUDIO, i_subfr, exc, h1, - xn, y1, xn2, L_subfr, st_fx->L_frame, g_corr, clip_gain, &gain_pit, &lp_flag ); + lp_select = lp_filt_exc_enc_ivas_fx( MODE1, AUDIO, i_subfr, exc, h1_q15, + xn, y1, xn2, L_subfr, st_fx->L_frame, g_corr, clip_gain, &gain_pit, &lp_flag ); /* Q0 */ IF( EQ_16( lp_flag, NORMAL_OPERATION ) ) { push_indice( hBstr, IND_LP_FILT_SELECT, lp_select, 1 ); } - /*st_fx->lowrate_pitchGain = 0.9f * st_fx->lowrate_pitchGain + 0.1f * gain_pit;*/ -#ifdef BASOP_NOGLOB - hSpMusClas->lowrate_pitchGain = round_fx_o( L_mac_o( L_mult( 29491, hSpMusClas->lowrate_pitchGain ), 6554, gain_pit, &Overflow ), &Overflow ); /*Q14*Q16(0.1) + Q15 -> Q15*/ -#else - hSpMusClas->lowrate_pitchGain = round_fx( L_mac( L_mult( 29491, hSpMusClas->lowrate_pitchGain ), 6554, gain_pit ) ); /*Q14*Q16(0.1) + Q15 -> Q15*/ -#endif - gpit_tmp = gain_pit; move16(); /*Q14*/ test(); @@ -842,10 +810,9 @@ void enc_pit_exc_ivas_fx( * Innovation encoding *-----------------------------------------------------------------*/ - inov_encode_ivas_fx( st_fx, st_fx->core_brate, 0, st_fx->L_frame, st_fx->last_L_frame, GENERIC, st_fx->bwidth, 0, i_subfr, -1, p_Aq, gain_pit, cn, exc, h2, st_fx->hLPDmem->tilt_code, *pt_pitch, xn2, code, y2, &unbits_PI, 2 * L_SUBFR, shift, Q_new ); - // PMT("code to be validated") + /*-----------------------------------------------------------------* * Gain encoding *-----------------------------------------------------------------*/ @@ -868,16 +835,11 @@ void enc_pit_exc_ivas_fx( } gp_clip_test_gain_pit_fx( st_fx->element_mode, st_fx->core_brate, gain_pit, st_fx->clip_var_fx ); -#ifdef BASOP_NOGLOB Lgcode = L_shl_sat( gain_code, Q_new ); /* scaled gain_code with Qnew -> Q16*/ gcode16 = round_fx_sat( Lgcode ); -#else - Lgcode = L_shl( gain_code, Q_new ); /* scaled gain_code with Qnew -> Q16*/ - gcode16 = round_fx( Lgcode ); -#endif IF( use_fcb != 0 ) { - hLPDmem->tilt_code = Est_tilt2( &exc[i_subfr], gain_pit, code, Lgcode, &voice_fac, shift ); + hLPDmem->tilt_code = est_tilt_ivas_fx( &exc[i_subfr], gain_pit, code, gain_code, &voice_fac, Q_new, L_SUBFR, 0 ); // Q15 move16(); } ELSE @@ -891,35 +853,19 @@ void enc_pit_exc_ivas_fx( IF( use_fcb != 0 ) { Ltmp = L_mult0( gcode16, y2[L_subfr - 1] ); -#ifdef BASOP_NOGLOB Ltmp = L_shl_o( Ltmp, add( 5, shift ), &Overflow ); // Q_new+14+shift Ltmp = L_negate( Ltmp ); Ltmp = L_mac_o( Ltmp, xn[L_subfr - 1], 16384, &Overflow ); // Q_new-1+15+shift Ltmp = L_msu_o( Ltmp, y1[L_subfr - 1], gain_pit, &Overflow ); // Q_new-1+15+shift Ltmp = L_shl_o( Ltmp, sub( 1, shift ), &Overflow ); // Q_new+15 - hLPDmem->mem_w0 = round_fx_o( Ltmp, &Overflow ); /*Q_new-1 */ -#else - Ltmp = L_mult( gcode16, y2[L_subfr - 1] ); - Ltmp = L_shl( Ltmp, add( 5, shift ) ); - Ltmp = L_negate( Ltmp ); - Ltmp = L_mac( Ltmp, xn[L_subfr - 1], 16384 ); - Ltmp = L_msu( Ltmp, y1[L_subfr - 1], gain_pit ); - Ltmp = L_shl( Ltmp, sub( 1, shift ) ); - hLPDmem->mem_w0 = round_fx( Ltmp ); /*Q_new-1 */ -#endif + hGSCEnc->mem_w0_tmp_fx = round_fx_o( Ltmp, &Overflow ); /*Q_new-1 */ } ELSE { - Ltmp = L_mult( xn[L_subfr - 1], 16384 ); // Q_new-1+15+shift -#ifdef BASOP_NOGLOB + Ltmp = L_mult( xn[L_subfr - 1], 16384 ); // Q_new-1+15+shift Ltmp = L_msu_sat( Ltmp, y1[L_subfr - 1], gain_pit ); // Q_new-1+15+shift Ltmp = L_shl_sat( Ltmp, sub( 1, shift ) ); // Q_new+15 - hLPDmem->mem_w0 = round_fx_sat( Ltmp ); /*Q_new-1 */ -#else - Ltmp = L_msu( Ltmp, y1[L_subfr - 1], gain_pit ); - Ltmp = L_shl( Ltmp, sub( 1, shift ) ); - hLPDmem->mem_w0 = round_fx( Ltmp ); /*Q_new-1 */ -#endif + hGSCEnc->mem_w0_tmp_fx = round_fx_sat( Ltmp ); /*Q_new-1 */ } /*-----------------------------------------------------------------* @@ -931,19 +877,12 @@ void enc_pit_exc_ivas_fx( FOR( i = 0; i < L_subfr; i++ ) { /* code in Q9, gain_pit in Q14 */ - Ltmp = L_mult( gcode16, code[i] ); -#ifdef BASOP_NOGLOB - Ltmp = L_shl_o( Ltmp, 5, &Overflow ); - Ltmp = L_mac_o( Ltmp, exc[i + i_subfr], gain_pit, &Overflow ); - Ltmp = L_shl_o( Ltmp, 1, &Overflow ); /* saturation can occur here */ - exc[i + i_subfr] = round_fx_o( Ltmp, &Overflow ); -#else - Ltmp = L_mult( gcode16, code[i] ); - Ltmp = L_shl( Ltmp, 5 ); - Ltmp = L_mac( Ltmp, exc[i + i_subfr], gain_pit ); - Ltmp = L_shl( Ltmp, 1 ); /* saturation can occur here */ - exc[i + i_subfr] = round_fx( Ltmp ); -#endif + Ltmp = L_mult( gcode16, code[i] ); /* Q10 + Q_new */ + Ltmp = L_shl_o( Ltmp, 5, &Overflow ); /* Q15 + Q_new */ + Ltmp = L_mac_o( Ltmp, exc[i + i_subfr], gain_pit, &Overflow ); /* Q15 + Q_new */ + Ltmp = L_shl_o( Ltmp, 1, &Overflow ); /* saturation can occur here Q16 + Q_new */ + exc[i + i_subfr] = round_fx_o( Ltmp, &Overflow ); /* Q_new */ + move16(); } } ELSE @@ -951,14 +890,10 @@ void enc_pit_exc_ivas_fx( FOR( i = 0; i < L_subfr; i++ ) { - Ltmp = L_mult( exc[i + i_subfr], gain_pit ); -#ifdef BASOP_NOGLOB - Ltmp = L_shl_sat( Ltmp, 1 ); /* saturation can occur here */ - exc[i + i_subfr] = round_fx_sat( Ltmp ); -#else - Ltmp = L_shl( Ltmp, 1 ); /* saturation can occur here */ - exc[i + i_subfr] = round_fx( Ltmp ); -#endif + Ltmp = L_mult( exc[i + i_subfr], gain_pit ); /* Q15 + Q_new */ + Ltmp = L_shl_sat( Ltmp, 1 ); /* saturation can occur here Q16 + Q_new */ + exc[i + i_subfr] = round_fx_sat( Ltmp ); /* Q_new */ + move16(); } } @@ -994,7 +929,7 @@ void enc_pit_exc_ivas_fx( { IF( i_subfr == 0 ) { - cum_gpit = mult_r( gpit_tmp, 13107 ); /* .4f*/ + cum_gpit = mult_r( gpit_tmp, 13107 /* .4f in Q15 */ ); /* Q14 */ pt_pitch++; *pt_pitch = *( pt_pitch - 1 ); move16(); @@ -1004,7 +939,7 @@ void enc_pit_exc_ivas_fx( } ELSE { - cum_gpit = add( cum_gpit, mult_r( gpit_tmp, 19660 ) ); /*0.6*/ + cum_gpit = add( cum_gpit, mult_r( gpit_tmp, 19660 /* 0.6 in Q15 */ ) ); /* Q14 */ pt_pitch++; *pt_pitch = *( pt_pitch - 1 ); move16(); @@ -1020,11 +955,11 @@ void enc_pit_exc_ivas_fx( { IF( i_subfr == 0 ) { - cum_gpit = mult_r( gpit_tmp, 16384 ); + cum_gpit = mult_r( gpit_tmp, 16384 /* 0.5 in Q15 */ ); /* Q14 */ } ELSE { - cum_gpit = add( cum_gpit, mult_r( gpit_tmp, 16384 ) ); + cum_gpit = add( cum_gpit, mult_r( gpit_tmp, 16384 /* 0.5 in Q15 */ ) ); /* Q14 */ } p_Aw += 2 * ( M + 1 ); move16(); @@ -1057,11 +992,11 @@ void enc_pit_exc_ivas_fx( IF( i_subfr == 0 ) { - cum_gpit = mult_r( gpit_tmp, 8192 ); + cum_gpit = mult_r( gpit_tmp, 8192 /* 0.25 in Q15 */ ); /* Q14 */ } ELSE { - cum_gpit = add( cum_gpit, mult_r( gpit_tmp, 8192 ) ); + cum_gpit = add( cum_gpit, mult_r( gpit_tmp, 8192 /* 0.25 in Q15 */ ) ); /* Q14 */ } pt_pitch++; @@ -1070,10 +1005,6 @@ void enc_pit_exc_ivas_fx( } } -#ifdef BASOP_NOGLOB - cum_gpit = shl_o( cum_gpit, 1, &Overflow ); /*Q15*/ -#else /* BASOP_NOGLOB */ - cum_gpit = shl( cum_gpit, 1 ); /*Q15*/ -#endif + cum_gpit = shl_o( cum_gpit, 1, &Overflow ); /*Q15*/ *gpit = round_fx( L_mac( L_mult( 3277, *gpit ), 29491, cum_gpit ) ); /*Q15*/ } diff --git a/lib_enc/enc_ppp.c b/lib_enc/enc_ppp.c deleted file mode 100644 index e7a8ca967132cf8896fc4a231dbaf74eed596840..0000000000000000000000000000000000000000 --- a/lib_enc/enc_ppp.c +++ /dev/null @@ -1,41 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include "cnst.h" -#include "prot.h" -#include "wmc_auto.h" diff --git a/lib_enc/enc_ppp_fx.c b/lib_enc/enc_ppp_fx.c index 775a863d3379a11e3bae50bc02bd3f27329329d0..c2aeaa7ca3d4ec2d9aad3c65eb64e7cac8177e6c 100644 --- a/lib_enc/enc_ppp_fx.c +++ b/lib_enc/enc_ppp_fx.c @@ -53,16 +53,16 @@ void E_LPC_f_lsp_a_conversion( const Word16 *lsp, Word16 *a, const Word16 m ); /*=======================================================================================*/ ivas_error encod_ppp_fx( Encoder_State *st_fx, /* i/o: state structure */ - const Word16 speech_fx[], /* i : input speech Q_new*/ - const Word16 Aw_fx[], /* i : weighted A(z) unquantized for subframes */ - const Word16 Aq_fx[], /* i : 12k8 Lp coefficient */ - Word16 *res_fx, /* i : residual signal Q_new*/ - Word16 *synth_fx, /* o : core synthesis Q-1*/ - Word16 *exc_fx, /* i/o: current non-enhanced excitation Q_new*/ - Word16 *exc2_fx, /* o : current enhanced excitation Q0*/ - Word16 *pitch_buf_fx, /* o : floating pitch values for each subframe Q6*/ - Word16 *voice_factors, /* o : voicing factors */ - Word16 *bwe_exc, /* o : excitation for SWB TBE */ + const Word16 speech_fx[], /* i : input speech Q_new*/ + const Word16 Aw_fx[], /* i : weighted A(z) unquantized for subframes Q12*/ + const Word16 Aq_fx[], /* i : 12k8 Lp coefficient Q14*/ + Word16 *res_fx, /* i : residual signal Q_new*/ + Word16 *synth_fx, /* o : core synthesis Q-1*/ + Word16 *exc_fx, /* i/o: current non-enhanced excitation Q_new*/ + Word16 *exc2_fx, /* o : current enhanced excitation Q0*/ + Word16 *pitch_buf_fx, /* o : floating pitch values for each subframe Q6*/ + Word16 *voice_factors, /* o : voicing factors Q15*/ + Word16 *bwe_exc, /* o : excitation for SWB TBE Q_new*/ Word16 Q_new, Word16 shift ) { @@ -77,6 +77,7 @@ ivas_error encod_ppp_fx( Word16 shift_wsp = add( Q_new, shift ); Word16 rate_ctrl_fx; Word16 saved_Q_new = Q_new; + move16(); LPD_state_HANDLE hLPDmem = st_fx->hLPDmem; SC_VBR_ENC_HANDLE hSC_VBR = st_fx->hSC_VBR; BSTR_ENC_HANDLE hBstr = st_fx->hBstr; @@ -101,7 +102,7 @@ ivas_error encod_ppp_fx( * Compute impulse response, h1[], of weighted synthesis filter *----------------------------------------------------------------*/ - Copy( &res_fx[i_subfr], &exc_fx[i_subfr], L_SUBFR ); + Copy( &res_fx[i_subfr], &exc_fx[i_subfr], L_SUBFR ); /* Q_new */ find_targets_fx( speech_fx, hLPDmem->mem_syn, i_subfr, &hLPDmem->mem_w0, p_Aq_fx, res_fx, L_SUBFR, p_Aw_fx, TILT_FAC_FX, xn_fx, NULL, h1_fx ); @@ -130,7 +131,7 @@ ivas_error encod_ppp_fx( return error; } - Scale_sig( exc_fx, L_FRAME, ( saved_Q_new - Q_new ) ); + Scale_sig( exc_fx, L_FRAME, ( saved_Q_new - Q_new ) ); /* saved_Q_new */ if ( EQ_16( hSC_VBR->bump_up, 1 ) ) { i_subfr = L_FRAME; @@ -188,48 +189,45 @@ ivas_error encod_ppp_fx( /* We write signalling indices again only in case of bump_up */ /* delete previous indices */ -#ifndef IVAS_CODE_BITSTREAM - reset_indices_enc_fx( hBstr ); -#else - reset_indices_enc_fx( hBstr, hBstr->nb_ind_tot ); -#endif + reset_indices_enc_fx( hBstr, MAX_NUM_INDICES ); /* signalling matrix (writing of signalling bits) */ signalling_enc_fx( st_fx ); } ELSE { - Copy( excQ_ppp_fx, exc_fx, L_FRAME ); + Copy( excQ_ppp_fx, exc_fx, L_FRAME ); /* Q_new */ /*-----------------------------------------------------------------* * Updates: last value of new target is stored in mem_w0 *-----------------------------------------------------------------*/ hLPDmem->mem_w0 = sub( shr( xn_fx[L_SUBFR - 1], shift ), shr( exc_fx[L_FRAME - 1], 1 ) ); /*Q_new-1 */ + move16(); - Copy( exc_fx, exc2_fx, L_FRAME ); + Copy( exc_fx, exc2_fx, L_FRAME ); /* Q_new */ hLPDmem->dm_fx.prev_state = 2; - move16(); /*Q0 dispMem index 0 */ - hLPDmem->dm_fx.prev_gain_pit[0] = hSC_VBR->prev_ppp_gain_pit_fx; - move16(); /*Q14 dispMem index 2 */ + move16(); /*Q0 dispMem index 0 */ + hLPDmem->dm_fx.prev_gain_pit[0] = hSC_VBR->prev_ppp_gain_pit_fx; /* Q14 */ + move16(); /*Q14 dispMem index 2 */ FOR( k = 1; k < 5; k++ ) { - hLPDmem->dm_fx.prev_gain_pit[k] = hLPDmem->dm_fx.prev_gain_pit[k - 1]; + hLPDmem->dm_fx.prev_gain_pit[k] = hLPDmem->dm_fx.prev_gain_pit[k - 1]; /* Q14 */ move16(); } - hLPDmem->tilt_code = hSC_VBR->prev_tilt_code_fx; + hLPDmem->tilt_code = hSC_VBR->prev_tilt_code_fx; /* Q15 */ move16(); - Copy( pitch_fx, pitch_buf_fx, NB_SUBFR ); - pitch_buf_fx[NB_SUBFR16k - 1] = pitch_fx[NB_SUBFR - 1]; + Copy( pitch_fx, pitch_buf_fx, NB_SUBFR ); /* Q6 */ + pitch_buf_fx[NB_SUBFR16k - 1] = pitch_fx[NB_SUBFR - 1]; /* Q6 */ interp_code_5over2_fx( exc2_fx, bwe_exc, L_FRAME ); set16_fx( voice_factors, 0, NB_SUBFR16k ); } - hSC_VBR->rate_control = rate_ctrl_fx; + hSC_VBR->rate_control = rate_ctrl_fx; /* Q0 */ move16(); set16_fx( hSC_VBR->nelp_lp_fit_mem, 0, NELP_LP_ORDER * 2 ); @@ -239,16 +237,16 @@ ivas_error encod_ppp_fx( ivas_error encod_ppp_ivas_fx( Encoder_State *st_fx, /* i/o: state structure */ - const Word16 speech_fx[], /* i : input speech Q_new*/ - const Word16 Aw_fx[], /* i : weighted A(z) unquantized for subframes */ - const Word16 Aq_fx[], /* i : 12k8 Lp coefficient */ - Word16 *res_fx, /* i : residual signal Q_new*/ - Word16 *synth_fx, /* o : core synthesis Q-1*/ - Word16 *exc_fx, /* i/o: current non-enhanced excitation Q_new*/ - Word16 *exc2_fx, /* o : current enhanced excitation Q0*/ - Word16 *pitch_buf_fx, /* o : floating pitch values for each subframe Q6*/ - Word16 *voice_factors, /* o : voicing factors */ - Word16 *bwe_exc, /* o : excitation for SWB TBE */ + const Word16 speech_fx[], /* i : input speech Q_new*/ + const Word16 Aw_fx[], /* i : weighted A(z) unquantized for subframes Q12*/ + const Word16 Aq_fx[], /* i : 12k8 Lp coefficient Q12*/ + Word16 *res_fx, /* i : residual signal Q_new*/ + Word16 *synth_fx, /* o : core synthesis Q-1*/ + Word16 *exc_fx, /* i/o: current non-enhanced excitation Q_new*/ + Word16 *exc2_fx, /* o : current enhanced excitation Q0*/ + Word16 *pitch_buf_fx, /* o : floating pitch values for each subframe Q6*/ + Word16 *voice_factors, /* o : voicing factors Q15*/ + Word16 *bwe_exc, /* o : excitation for SWB TBE Q_new*/ Word16 Q_new, Word16 shift ) { @@ -288,7 +286,7 @@ ivas_error encod_ppp_ivas_fx( * Compute impulse response, h1[], of weighted synthesis filter *----------------------------------------------------------------*/ - Copy( &res_fx[i_subfr], &exc_fx[i_subfr], L_SUBFR ); + Copy( &res_fx[i_subfr], &exc_fx[i_subfr], L_SUBFR ); /* Q_new */ find_targets_ivas_fx( speech_fx, hLPDmem->mem_syn, i_subfr, &hLPDmem->mem_w0, p_Aq_fx, res_fx, L_SUBFR, p_Aw_fx, TILT_FAC_FX, xn_fx, NULL, h1_fx ); @@ -301,7 +299,7 @@ ivas_error encod_ppp_ivas_fx( { FOR( k = 0; k < M; k++ ) { - p_Aq_curr_fx[k] = p_Aq_fx[k + ( 3 * ( M + 1 ) ) + 1]; + p_Aq_curr_fx[k] = p_Aq_fx[k + ( 3 * ( M + 1 ) ) + 1]; /* Q12 */ move16(); } @@ -317,7 +315,7 @@ ivas_error encod_ppp_ivas_fx( return error; } - Scale_sig( exc_fx, L_FRAME, sub( saved_Q_new, Q_new ) ); + Scale_sig( exc_fx, L_FRAME, sub( saved_Q_new, Q_new ) ); /* saved_Q_new */ if ( EQ_16( hSC_VBR->bump_up, 1 ) ) { i_subfr = L_FRAME; @@ -375,18 +373,14 @@ ivas_error encod_ppp_ivas_fx( /* We write signalling indices again only in case of bump_up */ /* delete previous indices */ -#ifndef IVAS_CODE_BITSTREAM - reset_indices_enc_fx( hBstr ); -#else - reset_indices_enc_fx( hBstr, hBstr->nb_ind_tot ); -#endif + reset_indices_enc_fx( hBstr, MAX_NUM_INDICES ); /* signalling matrix (writing of signalling bits) */ signalling_enc_fx( st_fx ); } ELSE { - Copy( excQ_ppp_fx, exc_fx, L_FRAME ); + Copy( excQ_ppp_fx, exc_fx, L_FRAME ); /* Q_new */ /*-----------------------------------------------------------------* * Updates: last value of new target is stored in mem_w0 @@ -394,7 +388,7 @@ ivas_error encod_ppp_ivas_fx( hLPDmem->mem_w0 = sub( shr( xn_fx[L_SUBFR - 1], shift ), shr( exc_fx[L_FRAME - 1], 1 ) ); /*Q_new-1 */ - Copy( exc_fx, exc2_fx, L_FRAME ); + Copy( exc_fx, exc2_fx, L_FRAME ); /* Q_new */ hLPDmem->dm_fx.prev_state = 2; move16(); /*Q0 dispMem index 0 */ @@ -403,11 +397,11 @@ ivas_error encod_ppp_ivas_fx( FOR( k = 1; k < 5; k++ ) { - hLPDmem->dm_fx.prev_gain_pit[k] = hLPDmem->dm_fx.prev_gain_pit[k - 1]; + hLPDmem->dm_fx.prev_gain_pit[k] = hLPDmem->dm_fx.prev_gain_pit[k - 1]; /* Q14 */ move16(); } - hLPDmem->tilt_code = hSC_VBR->prev_tilt_code_fx; + hLPDmem->tilt_code = hSC_VBR->prev_tilt_code_fx; /* Q15 */ move16(); Copy( pitch_fx, pitch_buf_fx, NB_SUBFR ); pitch_buf_fx[NB_SUBFR16k - 1] = pitch_fx[NB_SUBFR - 1]; @@ -416,7 +410,7 @@ ivas_error encod_ppp_ivas_fx( set16_fx( voice_factors, 0, NB_SUBFR16k ); } - hSC_VBR->rate_control = rate_ctrl_fx; + hSC_VBR->rate_control = rate_ctrl_fx; /* Q0 */ move16(); set16_fx( hSC_VBR->nelp_lp_fit_mem, 0, NELP_LP_ORDER * 2 ); diff --git a/lib_enc/enc_prm.c b/lib_enc/enc_prm.c deleted file mode 100644 index 1239a104c6ca7ec870e4cfb55f2167f8f2f14a4d..0000000000000000000000000000000000000000 --- a/lib_enc/enc_prm.c +++ /dev/null @@ -1,231 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include -#include "options.h" -#include "cnst.h" -#include "rom_com.h" -#include "prot.h" -#include "wmc_auto.h" - - -/*-------------------------------------------------------------------* - * writeTCXMode() - * - * write TCX mode - *--------------------------------------------------------------------*/ - -void writeTCXMode( - Encoder_State *st, /* i/o: encoder state structure */ - BSTR_ENC_HANDLE hBstr, /* i/o: bitstream handle */ - const Word16 MCT_flag, /* i : hMCT handle allocated (1) or not (0) */ - Word16 *nbits_start /* o : nbits start */ -) -{ - UWord16 index; - Word16 idx, start_idx; - Word16 nBits; - - IF( st->tcxonly ) - { - push_next_indice( hBstr, (UWord16) EQ_16( st->core, TCX_10_CORE ), 1 ); - - test(); - IF( EQ_16( st->clas, UNVOICED_CLAS ) ) - { - index = 0; - move16(); - } - ELSE IF( EQ_16( st->clas, VOICED_TRANSITION ) || EQ_16( st->clas, UNVOICED_TRANSITION ) ) - { - index = 1; - move16(); - } - ELSE IF( EQ_16( st->clas, VOICED_CLAS ) ) - { - index = 2; - move16(); - } - ELSE - { - index = 3; - move16(); - } - - push_next_indice( hBstr, index, 2 ); - - test(); - IF( EQ_16( st->element_mode, IVAS_CPE_MDCT ) && !MCT_flag ) - { - push_next_indice( hBstr, st->vad_flag, 1 ); - } - } - ELSE - { - IF( EQ_16( st->core, ACELP_CORE ) ) - { - /* write the RF signaling information */ - IF( EQ_16( st->rf_mode, 1 ) ) - { - /* find the section in the ACELP signaling table corresponding to bitrate */ - idx = 0; - move16(); - WHILE( NE_32( acelp_sig_tbl[idx], st->total_brate ) ) /* total bitrate is kept at 13.2kbps */ - { - idx = add( idx, 1 ); - } - - /* retrieve the number of bits for signaling */ - idx = add( idx, 1 ); - nBits = extract_l( acelp_sig_tbl[idx] ); - - /* retrieve the signaling index */ - idx = add( idx, 1 ); - start_idx = idx; - move16(); - WHILE( NE_32( acelp_sig_tbl[idx], SIG2IND( st->coder_type, st->bwidth, st->sharpFlag, st->rf_mode ) ) ) - { - idx = add( idx, 1 ); - } - push_next_indice( hBstr, sub( idx, start_idx ), nBits ); - push_next_indice( hBstr, 0, 1 ); /* Indicate to the decoder that the core is ACELP*/ - *nbits_start = 3; - move16(); - } - ELSE - { - push_next_indice( hBstr, st->coder_type, 3 ); - } - } - ELSE - { - IF( EQ_16( st->mdct_sw, MODE1 ) ) - { - /* 2 bits instead of 3 as TCX is already signaled */ - push_next_indice( hBstr, st->hTcxCfg->coder_type, 2 ); - } - ELSE - { - IF( EQ_16( st->mdct_sw_enable, MODE2 ) ) - { - push_next_indice( hBstr, 1, 1 ); /* TCX */ - push_next_indice( hBstr, 0, 1 ); /* not HQ_CORE */ - push_next_indice( hBstr, st->hTcxCfg->coder_type, 2 ); - } - ELSE - { - /*write the RF signaling information*/ - IF( EQ_16( st->rf_mode, 1 ) ) - { - /* find the section in the ACELP signaling table corresponding to bitrate */ - idx = 0; - move16(); - WHILE( NE_32( acelp_sig_tbl[idx], st->total_brate ) ) - { - idx = add( idx, 1 ); - } - - /* retrieve the number of bits for signaling */ - idx = add( idx, 1 ); - nBits = extract_l( acelp_sig_tbl[idx] ); - - test(); - test(); - IF( EQ_16( st->hTcxCfg->coder_type, VOICED ) || EQ_16( st->hTcxCfg->coder_type, GENERIC ) || EQ_16( st->hTcxCfg->coder_type, TRANSITION ) ) - { - st->sharpFlag = 1; - move16(); - } - ELSE - { - st->sharpFlag = 0; - move16(); - } - - /* retrieve the signaling index */ - idx = add( idx, 1 ); - start_idx = idx; - move16(); - WHILE( NE_32( acelp_sig_tbl[idx], SIG2IND( st->hTcxCfg->coder_type, st->bwidth, st->sharpFlag, st->rf_mode ) ) ) - { - idx = add( idx, 1 ); - } - push_next_indice( hBstr, sub( idx, start_idx ), nBits ); - push_next_indice( hBstr, 1, 1 ); /* Indicate to the decoder that the core is TCX*/ - *nbits_start = 3; - move16(); - } - ELSE - { - push_next_indice( hBstr, add( ACELP_MODE_MAX, st->hTcxCfg->coder_type ), 3 ); - } - } - } - } - } - - return; -} - - -/*-------------------------------------------------------------------* - * writeTCXWindowing() - * - * write TCX transform type - *-------------------------------------------------------------------*/ - -void writeTCXWindowing( - BSTR_ENC_HANDLE hBstr, /* i/o: bitstream handle */ - const Word16 overlap_mode /* i : overlap mode */ -) -{ - - IF( EQ_16( overlap_mode, MIN_OVERLAP ) ) - { - push_next_indice( hBstr, 2, 2 ); - } - ELSE IF( EQ_16( overlap_mode, HALF_OVERLAP ) ) - { - push_next_indice( hBstr, 3, 2 ); - } - ELSE - { - push_next_indice( hBstr, 0, 1 ); - } - - return; -} diff --git a/lib_enc/enc_prm_fx.c b/lib_enc/enc_prm_fx.c index c67a3f447e06f266b3e8f0c986862d5b53e3e17e..ecd4e2f013b4bb937d8fa8cb5d8f88a19b1482b6 100644 --- a/lib_enc/enc_prm_fx.c +++ b/lib_enc/enc_prm_fx.c @@ -11,15 +11,15 @@ #include "rom_com_fx.h" #include "rom_com.h" #include "stl.h" -//#include "prot_fx.h" -#include "prot_fx.h" /* Function prototypes */ +#include "prot_fx.h" #include "prot_fx_enc.h" /* Function prototypes */ static void enc_prm_hm( - Word16 *prm_hm, + Word16 *prm_hm, /* Q0 */ Encoder_State *st, - Word16 L_frame ) + Word16 L_frame /* Q0 */ +) { Word8 flag; BSTR_ENC_HANDLE hBstr = st->hBstr; @@ -55,9 +55,10 @@ static void enc_prm_hm( } } static void enc_prm_hm_ivas_fx( - Word16 *prm_hm, + Word16 *prm_hm, /* Q0 */ Encoder_State *st, - Word16 L_frame ) + Word16 L_frame /* Q0 */ +) { Word8 flag; BSTR_ENC_HANDLE hBstr = st->hBstr; @@ -100,9 +101,11 @@ static void enc_prm_hm_ivas_fx( * encode RF parameters for ACELP and TCX partial copy * *-----------------------------------------------------------------*/ -void enc_prm_rf_ivas_fx( Encoder_State *st, - const Word16 rf_frame_type, - const Word16 fec_offset ) +void enc_prm_rf_ivas_fx( + Encoder_State *st, + const Word16 rf_frame_type, /* Q0 */ + const Word16 fec_offset /* Q0 */ +) { Word16 sfr, nb_subfr, n, index; Word16 ltp_mode, ltf_mode, gains_mode; @@ -111,7 +114,7 @@ void enc_prm_rf_ivas_fx( Encoder_State *st, BSTR_ENC_HANDLE hBstr = st->hBstr; - nb_subfr = st->nb_subfr; + nb_subfr = st->nb_subfr; /* Q0 */ move16(); /* partial copy bitstream writing */ test(); @@ -269,9 +272,11 @@ void enc_prm_rf_ivas_fx( Encoder_State *st, /* write RF frame type last in the bitstream */ push_next_indice( hBstr, rf_frame_type, 3 ); } -void enc_prm_rf_fx( Encoder_State *st, - const Word16 rf_frame_type, - const Word16 fec_offset ) +void enc_prm_rf_fx( + Encoder_State *st, + const Word16 rf_frame_type, /* Q0 */ + const Word16 fec_offset /* Q0 */ +) { Word16 sfr, nb_subfr, n, index; Word16 ltp_mode, ltf_mode, gains_mode; @@ -280,7 +285,7 @@ void enc_prm_rf_fx( Encoder_State *st, BSTR_ENC_HANDLE hBstr = st->hBstr; - nb_subfr = st->nb_subfr; + nb_subfr = st->nb_subfr; /* Q0 */ /* partial copy bitstream writing */ test(); @@ -370,9 +375,9 @@ void enc_prm_rf_fx( Encoder_State *st, /* ES pred */ push_next_indice_fx( hBstr, hRF->rf_indx_EsPred[fec_offset], 3 ); - ltp_mode = ACELP_LTP_MODE[1][1][rf_frame_type]; - ltf_mode = ACELP_LTF_MODE[1][1][rf_frame_type]; - gains_mode = ACELP_GAINS_MODE[1][1][rf_frame_type]; + ltp_mode = ACELP_LTP_MODE[1][1][rf_frame_type]; /* Q0 */ + ltf_mode = ACELP_LTF_MODE[1][1][rf_frame_type]; /* Q0 */ + gains_mode = ACELP_GAINS_MODE[1][1][rf_frame_type]; /* Q0 */ /* Subframe parameters */ FOR( sfr = 0; sfr < nb_subfr; sfr++ ) @@ -446,13 +451,14 @@ void enc_prm_rf_fx( Encoder_State *st, void enc_prm_fx( const Word16 coder_type, /* (i) : coding type */ - Word16 param[], /* (i) : parameters */ - Word16 param_lpc[], /* (i) : LPC parameters */ + Word16 param[], /* (i) : parameters Q0*/ + Word16 param_lpc[], /* (i) : LPC parameters Q0*/ Encoder_State *st, /* i/o : quantization Analysis values */ - Word16 L_frame, + Word16 L_frame, /* Q0 */ CONTEXT_HM_CONFIG hm_cfg[], - Word16 *bits_param_lpc, - Word16 no_param_lpc ) + Word16 *bits_param_lpc, /* Q0 */ + Word16 no_param_lpc /* Q0 */ +) { Word16 j, k, n, sfr, core, last_core, *prm, tmp; Word16 nbits_start, total_nbbits; @@ -507,7 +513,7 @@ void enc_prm_fx( move16(); move16(); j = 0; - nbits_start = hBstr->nb_bits_tot; + nbits_start = hBstr->nb_bits_tot; /* Q0 */ /*--------------------------------------------------------------------------------* @@ -517,7 +523,7 @@ void enc_prm_fx( IF( EQ_16( st->mdct_sw, MODE1 ) ) { /* Adjust st->bits_frame_core not to subtract MODE2 bandwidth signaling */ - st->bits_frame_core = add( st->bits_frame_core, FrameSizeConfig[st->frame_size_index].bandwidth_bits ); + st->bits_frame_core = add( st->bits_frame_core, FrameSizeConfig[st->frame_size_index].bandwidth_bits ); /* Q0 */ /* Write MODE1 core mode signaling */ signalling_mode1_tcx20_enc_fx( st, 1 ); @@ -565,19 +571,19 @@ void enc_prm_fx( } /* retrieve the number of bits for signalling */ - nBits = (Word16) acelp_sig_tbl[++idx]; + nBits = (Word16) acelp_sig_tbl[++idx]; /* Q0 */ /* retrieve the signalling index */ - idx = add( idx, 1 ); - start_idx = idx; + idx = add( idx, 1 ); /* Q0 */ + start_idx = idx; /* Q0 */ tmp32 = SIG2IND_fx( coder_type, st->bwidth, st->sharpFlag, st->rf_mode ); WHILE( NE_32( acelp_sig_tbl[idx], tmp32 ) ) { - idx = add( idx, 1 ); + idx = add( idx, 1 ); /* Q0 */ } push_next_indice_fx( hBstr, idx - start_idx, nBits ); push_next_indice_fx( hBstr, 0, 1 ); /* Indicate to the decoder that the core is ACELP*/ - nbits_start = 3; + nbits_start = 3; /* Q0 */ } ELSE { @@ -612,7 +618,7 @@ void enc_prm_fx( } /* retrieve the number of bits for signalling */ - nBits = (Word16) acelp_sig_tbl[++idx]; + nBits = (Word16) acelp_sig_tbl[++idx]; /* Q0 */ test(); test(); @@ -628,8 +634,8 @@ void enc_prm_fx( } /* retrieve the signalling index */ - idx = add( idx, 1 ); - start_idx = idx; + idx = add( idx, 1 ); /* Q0 */ + start_idx = idx; /* Q0 */ tmp32 = SIG2IND_fx( st->hTcxCfg->coder_type, st->bwidth, st->sharpFlag, st->rf_mode ); WHILE( NE_32( acelp_sig_tbl[idx], tmp32 ) ) { @@ -720,7 +726,7 @@ void enc_prm_fx( st->glr_reset = 0; move16(); - nbits_header = sub( hBstr->nb_bits_tot, nbits_start ); + nbits_header = sub( hBstr->nb_bits_tot, nbits_start ); /* Q0 */ /*--------------------------------------------------------------------------------* @@ -730,7 +736,7 @@ void enc_prm_fx( IF( s_and( st->enableTcxLpc != 0, core != ACELP_CORE ) ) { /* Encode the indices */ - nbits_lpc = enc_lsf_tcxlpc_fx( ¶m_lpc, hBstr ); + nbits_lpc = enc_lsf_tcxlpc_fx( ¶m_lpc, hBstr ); /* Q0 */ } ELSE { @@ -745,7 +751,7 @@ void enc_prm_fx( move16(); } - nbits_lpc = encode_lpc_avq_fx( hBstr, numlpc, param_lpc, st->core, st->element_mode ); + nbits_lpc = encode_lpc_avq_fx( hBstr, numlpc, param_lpc, st->core, st->element_mode ); /* Q0 */ } ELSE IF( EQ_16( st->lpcQuantization, 1 ) ) { @@ -753,11 +759,11 @@ void enc_prm_fx( test(); IF( EQ_32( st->sr_core, 16000 ) && EQ_16( coder_type, VOICED ) && EQ_16( core, ACELP_CORE ) ) { - nbits_lpc = lsf_bctcvq_encprm_fx( hBstr, param_lpc, bits_param_lpc, no_param_lpc ); + nbits_lpc = lsf_bctcvq_encprm_fx( hBstr, param_lpc, bits_param_lpc, no_param_lpc ); /* Q0 */ } ELSE { - nbits_lpc = lsf_msvq_ma_encprm_fx( hBstr, param_lpc, core, coder_type, st->acelp_cfg.midLpc, bits_param_lpc, no_param_lpc ); + nbits_lpc = lsf_msvq_ma_encprm_fx( hBstr, param_lpc, core, coder_type, st->acelp_cfg.midLpc, bits_param_lpc, no_param_lpc ); /* Q0 */ } } ELSE @@ -787,7 +793,7 @@ void enc_prm_fx( } /* Mean energy (2 or 3 bits) */ - n = ACELP_NRG_BITS[st->acelp_cfg.nrg_mode]; + n = ACELP_NRG_BITS[st->acelp_cfg.nrg_mode]; /* Q0 */ IF( n != 0 ) { @@ -800,7 +806,7 @@ void enc_prm_fx( { /* Pitch lag (4, 5, 6, 8 or 9 bits) */ move16(); - n = ACELP_LTP_BITS_SFR[st->acelp_cfg.ltp_mode][sfr]; + n = ACELP_LTP_BITS_SFR[st->acelp_cfg.ltp_mode][sfr]; /* Q0 */ IF( n != 0 ) { @@ -841,7 +847,7 @@ void enc_prm_fx( push_next_indice_fx( hBstr, prm[j++], bitcnt ); } - j = add( j_old, 8 ); + j = add( j_old, 8 ); /* Q0 */ } /* Gains (5b, 6b or 7b / subfr) */ @@ -887,9 +893,9 @@ void enc_prm_fx( j = add( j, 3 ); /* TCX spectral data */ - lg = L_frame; + lg = L_frame; /* Q0 */ move16(); - lgFB = st->hTcxCfg->tcx_coded_lines; + lgFB = st->hTcxCfg->tcx_coded_lines; /* Q0 */ move16(); IF( last_core == ACELP_CORE ) @@ -899,7 +905,7 @@ void enc_prm_fx( lgFB = add( lgFB, shr( lgFB, 2 ) ); if ( st->hTcxCfg->lfacNext < 0 ) { - lg = sub( lg, st->hTcxCfg->lfacNext ); + lg = sub( lg, st->hTcxCfg->lfacNext ); /* Q0 */ } } @@ -912,7 +918,7 @@ void enc_prm_fx( IF( st->hTcxCfg->fIsTNSAllowed ) { WriteTnsData_fx( st->hTcxCfg->pCurrentTnsConfig, prm + j, &nTnsParams, st, &nTnsBits ); - j = add( j, nTnsParams ); + j = add( j, nTnsParams ); /* Q0 */ } hm_size = shl( mult( st->hTcxCfg->bandwidth, lg ), 1 ); @@ -950,17 +956,17 @@ void enc_prm_fx( IGFEncWriteBitstream_fx( st->hIGFEnc, hBstr, &st->hIGFEnc->infoTotalBitsPerFrameWritten, IGF_GRID_LB_NORM, 1 ); } } - total_nbbits = sub( hBstr->nb_bits_tot, nbits_start ); + total_nbbits = sub( hBstr->nb_bits_tot, nbits_start ); /* Q0 */ if ( EQ_16( st->rf_mode, 1 ) ) { - total_nbbits = add( total_nbbits, st->rf_target_bits_write ); + total_nbbits = add( total_nbbits, st->rf_target_bits_write ); /* Q0 */ } - nbits_tcx = sub( st->bits_frame_core, total_nbbits ); + nbits_tcx = sub( st->bits_frame_core, total_nbbits ); /* Q0 */ IF( hTcxEnc->tcx_lpc_shaped_ari != 0 ) { push_next_bits_fx( hBstr, &prm[++j], nbits_tcx ); - j = add( j, nbits_tcx ); + j = add( j, nbits_tcx ); /* Q0 */ } ELSE { @@ -990,7 +996,7 @@ void enc_prm_fx( move16(); IF( st->igf ) { - nbits_igf = IGFEncWriteConcatenatedBitstream_fx( st->hIGFEnc, hBstr ); + nbits_igf = IGFEncWriteConcatenatedBitstream_fx( st->hIGFEnc, hBstr ); /* Q0 */ } FOR( k = 0; k < 2; k++ ) { @@ -1004,7 +1010,7 @@ void enc_prm_fx( j = 0; move16(); - nbits_tcx = total_nbbits = sub( hBstr->nb_bits_tot, nbits_start ); + nbits_tcx = total_nbbits = sub( hBstr->nb_bits_tot, nbits_start ); /* Q0 */ test(); IF( st->enablePlcWaveadjust && k ) @@ -1043,11 +1049,11 @@ void enc_prm_fx( IF( s_and( k == 0, last_core == ACELP_CORE ) ) { /* ACE->TCX transition */ - lg = add( lg, st->hTcxCfg->tcx_offset ); + lg = add( lg, st->hTcxCfg->tcx_offset ); /* Q0 */ lgFB = add( lgFB, shr( lgFB, 1 ) ); if ( st->hTcxCfg->lfacNext < 0 ) { - lg = sub( lg, st->hTcxCfg->lfacNext ); + lg = sub( lg, st->hTcxCfg->lfacNext ); /* Q0 */ } } @@ -1084,9 +1090,9 @@ void enc_prm_fx( } j = add( j, NPRM_CTX_HM ); - total_nbbits = sub( hBstr->nb_bits_tot, nbits_start ); + total_nbbits = sub( hBstr->nb_bits_tot, nbits_start ); /* Q0 */ - nbits_tcx = sub( shr( sub( add( sub( sub( sub( st->bits_frame_core, nbits_header ), nbits_lpc ), nbits_igf ), 1 ), k ), 1 ), sub( total_nbbits, nbits_tcx ) ); + nbits_tcx = sub( shr( sub( add( sub( sub( sub( st->bits_frame_core, nbits_header ), nbits_lpc ), nbits_igf ), 1 ), k ), 1 ), sub( total_nbbits, nbits_tcx ) ); /* Q0 */ phm_cfg = NULL; move16(); @@ -1109,7 +1115,7 @@ void enc_prm_fx( *--------------------------------------------------------------------------------*/ - total_nbbits = sub( hBstr->nb_bits_tot, nbits_start ); + total_nbbits = sub( hBstr->nb_bits_tot, nbits_start ); /* Q0 */ /* Check if total encoded bits does not exceed CBR target bits (->this must never happen) */ @@ -1132,10 +1138,10 @@ void enc_prm_fx( void writeLPCparam_fx( Encoder_State *st, /* i/o: encoder state structure */ BSTR_ENC_HANDLE hBstr, /* i/o: bitstream handle */ - const Word16 param_lpc[], /* i : LPC parameters to write */ - const Word16 bits_param_lpc[], /* i : bits per LPC parameter */ - const Word16 no_param_lpc, /* i : number of LPC parameters */ - Word16 *nbits_lpc /* o : LPC bits written */ + const Word16 param_lpc[], /* i : LPC parameters to write Q0*/ + const Word16 bits_param_lpc[], /* i : bits per LPC parameter Q0*/ + const Word16 no_param_lpc, /* i : number of LPC parameters Q0*/ + Word16 *nbits_lpc /* o : LPC bits written Q0*/ ) { Word16 numlpc; @@ -1144,7 +1150,7 @@ void writeLPCparam_fx( IF( st->enableTcxLpc && st->core != ACELP_CORE ) { /* Encode the indices */ - *nbits_lpc = enc_lsf_tcxlpc_ivas_fx( ¶m_lpc, hBstr ); + *nbits_lpc = enc_lsf_tcxlpc_ivas_fx( ¶m_lpc, hBstr ); /* Q0 */ move16(); } ELSE @@ -1163,7 +1169,7 @@ void writeLPCparam_fx( move16(); } - *nbits_lpc = encode_lpc_avq_ivas_fx( hBstr, numlpc, param_lpc, st->core, st->element_mode ); + *nbits_lpc = encode_lpc_avq_ivas_fx( hBstr, numlpc, param_lpc, st->core, st->element_mode ); /* Q0 */ move16(); } ELSE IF( EQ_16( st->lpcQuantization, 1 ) ) @@ -1174,12 +1180,12 @@ void writeLPCparam_fx( { assert( st->element_mode == EVS_MONO ); - *nbits_lpc = lsf_bctcvq_encprm_ivas_fx( hBstr, param_lpc, bits_param_lpc, no_param_lpc ); + *nbits_lpc = lsf_bctcvq_encprm_ivas_fx( hBstr, param_lpc, bits_param_lpc, no_param_lpc ); /* Q0 */ move16(); } ELSE { - *nbits_lpc = lsf_msvq_ma_encprm_ivas_fx( hBstr, param_lpc, st->core, st->coder_type, st->acelp_cfg.midLpc, bits_param_lpc, no_param_lpc ); + *nbits_lpc = lsf_msvq_ma_encprm_ivas_fx( hBstr, param_lpc, st->core, st->coder_type, st->acelp_cfg.midLpc, bits_param_lpc, no_param_lpc ); /* Q0 */ move16(); } } @@ -1199,17 +1205,18 @@ void writeLPCparam_fx( *-------------------------------------------------------------------*/ void writeTCXparam_fx( - Encoder_State *st, /* i/o: Encoder State handle */ - BSTR_ENC_HANDLE hBstr, /* i/o: bitstream handle */ - CONTEXT_HM_CONFIG hm_cfg[], /* i/o: HM config */ - Word16 param[], /* i : parameters */ - const Word16 nbits_header, - const Word16 nbits_start, - const Word16 nbits_lpc, - const Word16 *no_param_tns, /* i : number of TNS parameters per subframe */ - Word16 p_param[2], /* i/o: pointer to parameters from previous bs writing */ - const Word16 target_bitsTCX10[2], - const Word16 pre_past_flag ) + Encoder_State *st, /* i/o: Encoder State handle */ + BSTR_ENC_HANDLE hBstr, /* i/o: bitstream handle */ + CONTEXT_HM_CONFIG hm_cfg[], /* i/o: HM config */ + Word16 param[], /* i : parameters Q0*/ + const Word16 nbits_header, /* Q0 */ + const Word16 nbits_start, /* Q0 */ + const Word16 nbits_lpc, /* Q0 */ + const Word16 *no_param_tns, /* i : number of TNS parameters per subframe Q0*/ + Word16 p_param[2], /* i/o: pointer to parameters from previous bs writing Q0*/ + const Word16 target_bitsTCX10[2], /* Q0 */ + const Word16 pre_past_flag /* Q0 */ +) { Word16 *prm; Word16 j, k, nSubframes, core, last_core; @@ -1264,7 +1271,7 @@ void writeTCXparam_fx( test(); IF( LT_16( st->element_mode, IVAS_CPE_MDCT ) && k == 0 && st->igf && EQ_16( core, TCX_10_CORE ) ) { - nbits_igf = IGFEncWriteConcatenatedBitstream_ivas_fx( st->hIGFEnc, hBstr ); + nbits_igf = IGFEncWriteConcatenatedBitstream_ivas_fx( st->hIGFEnc, hBstr ); /* Q0 */ } flag_ctx_hm = 0; @@ -1274,7 +1281,7 @@ void writeTCXparam_fx( j = 0; move16(); - nbits_tcx = total_nbbits = sub( hBstr->nb_bits_tot, nbits_start ); + nbits_tcx = total_nbbits = sub( hBstr->nb_bits_tot, nbits_start ); /* Q0 */ move16(); test(); @@ -1319,7 +1326,7 @@ void writeTCXparam_fx( } ELSE { - j = add( j, sub( p_param[k], 2 ) ); + j = add( j, sub( p_param[k], 2 ) ); /* Q0 */ } /* TCX spectral data */ @@ -1331,12 +1338,12 @@ void writeTCXparam_fx( IF( post_part && k == 0 && last_core == ACELP_CORE ) { /* ACE->TCX transition */ - lg = add( lg, st->hTcxCfg->tcx_offset ); - lgFB = add( lgFB, shr( lgFB, sub( 3, nSubframes ) ) ); + lg = add( lg, st->hTcxCfg->tcx_offset ); /* Q0 */ + lgFB = add( lgFB, shr( lgFB, sub( 3, nSubframes ) ) ); /* Q0 */ IF( st->hTcxCfg->lfacNext < 0 ) { - lg = sub( lg, st->hTcxCfg->lfacNext ); + lg = sub( lg, st->hTcxCfg->lfacNext ); /* Q0 */ } } @@ -1368,7 +1375,7 @@ void writeTCXparam_fx( IF( no_param_tns && ( st->hTcxEnc->tnsData[k].nFilters < 0 ) ) { /* a negative filter count means that the filters are identical to those in the first channel at the same sub-frame */ - nTnsParams = no_param_tns[k]; + nTnsParams = no_param_tns[k]; /* Q0 */ move16(); } ELSE @@ -1377,14 +1384,14 @@ void writeTCXparam_fx( } IF( no_param_tns ) { - nTnsBits = add( nTnsBits, 1 ); + nTnsBits = add( nTnsBits, 1 ); /* Q0 */ } - j = add( j, nTnsParams ); + j = add( j, nTnsParams ); /* Q0 */ } IF( post_part ) { - hm_size = imult1616( mult( 2, st->hTcxCfg->bandwidth ), lg ); + hm_size = imult1616( mult( 2, st->hTcxCfg->bandwidth ), lg ); /* Q0 */ test(); test(); @@ -1430,35 +1437,35 @@ void writeTCXparam_fx( IGFEncWriteBitstream_ivas_fx( st->hIGFEnc, hBstr, &st->hIGFEnc->infoTotalBitsPerFrameWritten, gridIdx, 1 ); } - total_nbbits = sub( hBstr->nb_bits_tot, nbits_start ); + total_nbbits = sub( hBstr->nb_bits_tot, nbits_start ); /* Q0 */ IF( EQ_16( core, TCX_20_CORE ) ) { IF( st->rf_mode ) { - total_nbbits = add( total_nbbits, st->rf_target_bits_write ); + total_nbbits = add( total_nbbits, st->rf_target_bits_write ); /* Q0 */ } - nbits_tcx = sub( st->bits_frame_core, total_nbbits ); + nbits_tcx = sub( st->bits_frame_core, total_nbbits ); /* Q0 */ } ELSE /* TCX_10_CORE */ { - nbits_tcx = sub( shr( sub( add( sub( sub( sub( st->bits_frame_core, nbits_header ), nbits_lpc ), nbits_igf ), 1 ), k ), 1 ), sub( total_nbbits, nbits_tcx ) ); + nbits_tcx = sub( shr( sub( add( sub( sub( sub( st->bits_frame_core, nbits_header ), nbits_lpc ), nbits_igf ), 1 ), k ), 1 ), sub( total_nbbits, nbits_tcx ) ); /* Q0 */ } } ELSE { /*Context HM flag*/ - p_param[k] = j; + p_param[k] = j; /* Q0 */ move16(); } } ELSE { - nbits_tcx = st->bits_frame_channel; + nbits_tcx = st->bits_frame_channel; /* Q0 */ move16(); IF( EQ_16( core, TCX_10_CORE ) ) { - nbits_tcx = sub( target_bitsTCX10[k], NBITS_TCX_GAIN + NOISE_FILL_RANGES * NBITS_NOISE_FILL_LEVEL ); + nbits_tcx = sub( target_bitsTCX10[k], NBITS_TCX_GAIN + NOISE_FILL_RANGES * NBITS_NOISE_FILL_LEVEL ); /* Q0 */ } } @@ -1468,7 +1475,7 @@ void writeTCXparam_fx( IF( st->hTcxEnc->tcx_lpc_shaped_ari && EQ_16( core, TCX_20_CORE ) ) { push_next_bits( hBstr, (UWord16 *) &prm[++j], nbits_tcx ); - j = add( j, nbits_tcx ); + j = add( j, nbits_tcx ); /* Q0 */ } ELSE { @@ -1504,3 +1511,190 @@ void writeTCXparam_fx( return; } + +/*-------------------------------------------------------------------* + * writeTCXMode_fx() + * + * write TCX mode + *--------------------------------------------------------------------*/ + +void writeTCXMode_fx( + Encoder_State *st, /* i/o: encoder state structure */ + BSTR_ENC_HANDLE hBstr, /* i/o: bitstream handle */ + const Word16 MCT_flag, /* i : hMCT handle allocated (1) or not (0) Q0*/ + Word16 *nbits_start /* o : nbits start Q0*/ +) +{ + UWord16 index; + Word16 idx, start_idx; + Word16 nBits; + + IF( st->tcxonly ) + { + push_next_indice( hBstr, (UWord16) EQ_16( st->core, TCX_10_CORE ), 1 ); + + test(); + IF( EQ_16( st->clas, UNVOICED_CLAS ) ) + { + index = 0; + move16(); + } + ELSE IF( EQ_16( st->clas, VOICED_TRANSITION ) || EQ_16( st->clas, UNVOICED_TRANSITION ) ) + { + index = 1; + move16(); + } + ELSE IF( EQ_16( st->clas, VOICED_CLAS ) ) + { + index = 2; + move16(); + } + ELSE + { + index = 3; + move16(); + } + + push_next_indice( hBstr, index, 2 ); + + test(); + IF( EQ_16( st->element_mode, IVAS_CPE_MDCT ) && !MCT_flag ) + { + push_next_indice( hBstr, st->vad_flag, 1 ); + } + } + ELSE + { + IF( EQ_16( st->core, ACELP_CORE ) ) + { + /* write the RF signaling information */ + IF( EQ_16( st->rf_mode, 1 ) ) + { + /* find the section in the ACELP signaling table corresponding to bitrate */ + idx = 0; + move16(); + WHILE( NE_32( acelp_sig_tbl[idx], st->total_brate ) ) /* total bitrate is kept at 13.2kbps */ + { + idx = add( idx, 1 ); + } + + /* retrieve the number of bits for signaling */ + idx = add( idx, 1 ); /* Q0 */ + nBits = extract_l( acelp_sig_tbl[idx] ); /* Q0 */ + + /* retrieve the signaling index */ + idx = add( idx, 1 ); + start_idx = idx; + move16(); + WHILE( NE_32( acelp_sig_tbl[idx], SIG2IND( st->coder_type, st->bwidth, st->sharpFlag, st->rf_mode ) ) ) + { + idx = add( idx, 1 ); + } + push_next_indice( hBstr, sub( idx, start_idx ), nBits ); + push_next_indice( hBstr, 0, 1 ); /* Indicate to the decoder that the core is ACELP*/ + *nbits_start = 3; + move16(); + } + ELSE + { + push_next_indice( hBstr, st->coder_type, 3 ); + } + } + ELSE + { + IF( EQ_16( st->mdct_sw, MODE1 ) ) + { + /* 2 bits instead of 3 as TCX is already signaled */ + push_next_indice( hBstr, st->hTcxCfg->coder_type, 2 ); + } + ELSE + { + IF( EQ_16( st->mdct_sw_enable, MODE2 ) ) + { + push_next_indice( hBstr, 1, 1 ); /* TCX */ + push_next_indice( hBstr, 0, 1 ); /* not HQ_CORE */ + push_next_indice( hBstr, st->hTcxCfg->coder_type, 2 ); + } + ELSE + { + /*write the RF signaling information*/ + IF( EQ_16( st->rf_mode, 1 ) ) + { + /* find the section in the ACELP signaling table corresponding to bitrate */ + idx = 0; + move16(); + WHILE( NE_32( acelp_sig_tbl[idx], st->total_brate ) ) + { + idx = add( idx, 1 ); + } + + /* retrieve the number of bits for signaling */ + idx = add( idx, 1 ); + nBits = extract_l( acelp_sig_tbl[idx] ); + + test(); + test(); + IF( EQ_16( st->hTcxCfg->coder_type, VOICED ) || EQ_16( st->hTcxCfg->coder_type, GENERIC ) || EQ_16( st->hTcxCfg->coder_type, TRANSITION ) ) + { + st->sharpFlag = 1; + move16(); + } + ELSE + { + st->sharpFlag = 0; + move16(); + } + + /* retrieve the signaling index */ + idx = add( idx, 1 ); + start_idx = idx; + move16(); + WHILE( NE_32( acelp_sig_tbl[idx], SIG2IND( st->hTcxCfg->coder_type, st->bwidth, st->sharpFlag, st->rf_mode ) ) ) + { + idx = add( idx, 1 ); + } + push_next_indice( hBstr, sub( idx, start_idx ), nBits ); + push_next_indice( hBstr, 1, 1 ); /* Indicate to the decoder that the core is TCX*/ + *nbits_start = 3; + move16(); + } + ELSE + { + push_next_indice( hBstr, add( ACELP_MODE_MAX, st->hTcxCfg->coder_type ), 3 ); + } + } + } + } + } + + return; +} + + +/*-------------------------------------------------------------------* + * writeTCXWindowing_fx() + * + * write TCX transform type + *-------------------------------------------------------------------*/ + +void writeTCXWindowing_fx( + BSTR_ENC_HANDLE hBstr, /* i/o: bitstream handle */ + const Word16 overlap_mode /* i : overlap mode Q0*/ +) +{ + + IF( EQ_16( overlap_mode, MIN_OVERLAP ) ) + { + push_next_indice( hBstr, 2, 2 ); + } + ELSE IF( EQ_16( overlap_mode, HALF_OVERLAP ) ) + { + push_next_indice( hBstr, 3, 2 ); + } + ELSE + { + push_next_indice( hBstr, 0, 1 ); + } + + return; +} diff --git a/lib_enc/enc_tran.c b/lib_enc/enc_tran.c deleted file mode 100644 index fc894ba6cc3b0f6891e5522d7bdaa893786ada84..0000000000000000000000000000000000000000 --- a/lib_enc/enc_tran.c +++ /dev/null @@ -1,41 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include "prot.h" -#include "rom_com.h" -#include "wmc_auto.h" diff --git a/lib_enc/enc_tran_fx.c b/lib_enc/enc_tran_fx.c index c7f7bcd51cb5b449143630268e87af0a81a1ac2e..5b9f6750302d8933f8718fd68ec923edc7b20863 100644 --- a/lib_enc/enc_tran_fx.c +++ b/lib_enc/enc_tran_fx.c @@ -4,10 +4,9 @@ #include #include "options.h" /* Compilation switches */ #include "cnst.h" /* Compilation switches */ -//#include "prot_fx.h" /* Function prototypes */ +// #include "prot_fx.h" /* Function prototypes */ #include "rom_com_fx.h" /* Static table prototypes */ #include "rom_com.h" /* Static table prototypes */ -#include "prot.h" /* Function prototypes */ #include "prot_fx.h" /* Function prototypes */ #include "prot_fx_enc.h" /* Function prototypes */ @@ -47,20 +46,20 @@ Word16 encod_tran_fx( Encoder_State *st_fx, /* i/o: state structure */ - const Word16 speech_fx[], /* i : input speech */ - const Word16 Aw_fx[], /* i : weighted A(z) unquantized for subframes */ - const Word16 Aq_fx[], /* i : 12k8 Lp coefficient */ - const Word16 Es_pred_fx, /* i : predicted scaled innov. energy */ - const Word16 *res_fx, /* i : residual signal */ - Word16 *syn_fx, /* i/o: core synthesis */ - Word16 *exc_fx, /* i/o: current non-enhanced excitation */ - Word16 *exc2_fx, /* i/o: current enhanced excitation */ - Word16 *pitch_buf_fx, /* i/o: floating pitch values for each subframe */ - Word16 *voice_factors, /* o : voicing factors */ - Word16 *bwe_exc_fx, /* i/o: excitation for SWB TBE */ - Word16 tc_subfr, /* i/o: TC subframe classification */ - Word16 position, /* i : maximum of residual signal index */ - Word16 *unbits, /* i/o: number of unused bits */ + const Word16 speech_fx[], /* i : input speech Q0*/ + const Word16 Aw_fx[], /* i : weighted A(z) unquantized for subframes Q12*/ + const Word16 Aq_fx[], /* i : 12k8 Lp coefficient Q12*/ + const Word16 Es_pred_fx, /* i : predicted scaled innov. energy Q8*/ + const Word16 *res_fx, /* i : residual signal Q_new*/ + Word16 *syn_fx, /* i/o: core synthesis Q_new*/ + Word16 *exc_fx, /* i/o: current non-enhanced excitation Q0*/ + Word16 *exc2_fx, /* i/o: current enhanced excitation Q0*/ + Word16 *pitch_buf_fx, /* i/o: floating pitch values for each subframe Q6*/ + Word16 *voice_factors, /* o : voicing factors Q15*/ + Word16 *bwe_exc_fx, /* i/o: excitation for SWB TBE Q0*/ + Word16 tc_subfr, /* i/o: TC subframe classification Q0*/ + Word16 position, /* i : maximum of residual signal index Q0*/ + Word16 *unbits, /* i/o: number of unused bits Q0*/ const Word16 shift, /* i : Scaling to get 12 bits */ const Word16 Q_new /* i : Input scaling */ ) @@ -96,6 +95,7 @@ Word16 encod_tran_fx( Word32 L_tmp; #ifdef BASOP_NOGLOB_DECLARE_LOCAL Flag Overflow = 0; + move32(); #endif BSTR_ENC_HANDLE hBstr = st_fx->hBstr; SC_VBR_ENC_HANDLE hSC_VBR = st_fx->hSC_VBR; @@ -131,14 +131,14 @@ Word16 encod_tran_fx( /**unbits = 0;move16();*/ Jopt_flag = 0; move16(); - unbits_ACELP = *unbits; + unbits_ACELP = *unbits; /* Q0 */ move16(); *unbits = 0; move16(); - p_Aw = Aw_fx; - p_Aq = Aq_fx; - pt_pitch = pitch_buf_fx; + p_Aw = Aw_fx; /* Q12 */ + p_Aq = Aq_fx; /* Q12 */ + pt_pitch = pitch_buf_fx; /* Q6 */ gain_preQ = 0; move16(); set16_fx( code_preQ, 0, L_SUBFR ); @@ -156,7 +156,7 @@ Word16 encod_tran_fx( * Compute impulse response, h1[], of weighted synthesis filter *----------------------------------------------------------------*/ - Copy( &res_fx[i_subfr], &exc_fx[i_subfr], L_SUBFR ); + Copy( &res_fx[i_subfr], &exc_fx[i_subfr], L_SUBFR ); /* Q_new */ find_targets_fx( speech_fx, hLPDmem->mem_syn, i_subfr, &hLPDmem->mem_w0, p_Aq, res_fx, L_SUBFR, p_Aw, st_fx->preemph_fac, xn, cn, h1 ); @@ -228,31 +228,21 @@ Word16 encod_tran_fx( } gp_clip_test_gain_pit_fx( st_fx->element_mode, st_fx->core_brate, gain_pit, st_fx->clip_var_fx ); -#ifdef BASOP_NOGLOB Lgcode = L_shl_o( gain_code, Q_new, &Overflow ); /* scaled gain_code with Qnew -> Q16*/ gcode16 = round_fx_o( Lgcode, &Overflow ); -#else - Lgcode = L_shl( gain_code, Q_new ); /* scaled gain_code with Qnew -> Q16*/ - gcode16 = round_fx( Lgcode ); -#endif - hLPDmem->tilt_code = Est_tilt2( &exc_fx[i_subfr], gain_pit, code, Lgcode, &voice_fac, shift ); + hLPDmem->tilt_code = Est_tilt2( &exc_fx[i_subfr], gain_pit, code, Lgcode, &voice_fac, shift ); /* Q15 */ /*-----------------------------------------------------------------* * Update memory of the weighting filter *-----------------------------------------------------------------*/ /*st->mem_w0 = xn[L_SUBFR-1] - (gain_pit*y1[L_SUBFR-1]) - (gain_code*y2[L_SUBFR-1]);*/ - L_tmp = L_mult( gcode16, y2[L_SUBFR - 1] ); - L_tmp = L_shl( L_tmp, add( 5, shift ) ); + L_tmp = L_mult( gcode16, y2[L_SUBFR - 1] ); /* Q10 + Q_new */ + L_tmp = L_shl( L_tmp, add( 5, shift ) ); /* Q15 + Q_new + shift */ L_tmp = L_negate( L_tmp ); L_tmp = L_mac( L_tmp, xn[L_SUBFR - 1], 16384 ); L_tmp = L_msu( L_tmp, y1[L_SUBFR - 1], gain_pit ); -#ifdef BASOP_NOGLOB - L_tmp = L_shl_sat( L_tmp, sub( 1, shift ) ); - hLPDmem->mem_w0 = round_fx_sat( L_tmp ); /*Q_new-1*/ -#else - L_tmp = L_shl( L_tmp, sub( 1, shift ) ); - hLPDmem->mem_w0 = round_fx( L_tmp ); /*Q_new-1*/ -#endif + L_tmp = L_shl_sat( L_tmp, sub( 1, shift ) ); /* Q_new + 15 */ + hLPDmem->mem_w0 = round_fx_sat( L_tmp ); /*Q_new-1*/ /*-----------------------------------------------------------------* * Construct adaptive part of the excitation * Save the non-enhanced excitation for FEC_exc @@ -268,19 +258,15 @@ Word16 encod_tran_fx( { FOR( i = 0; i < L_SUBFR; i++ ) { -#ifdef BASOP_NOGLOB - exc2_fx[i + i_subfr] = round_fx_sat( L_shl_sat( L_mult_sat( gain_pit, exc_fx[i + i_subfr] ), 1 ) ); -#else - exc2_fx[i + i_subfr] = round_fx( L_shl( L_mult( gain_pit, exc_fx[i + i_subfr] ), 1 ) ); -#endif + exc2_fx[i + i_subfr] = round_fx_sat( L_shl_sat( L_mult_sat( gain_pit, exc_fx[i + i_subfr] ), 1 ) ); /* Q_new */ } } ELSE { - Gain_pitX2 = shl( gain_pit, 1 ); + Gain_pitX2 = shl( gain_pit, 1 ); /* Q15 */ FOR( i = 0; i < L_SUBFR; i++ ) { - exc2_fx[i + i_subfr] = mult_r( Gain_pitX2, exc_fx[i + i_subfr] ); + exc2_fx[i + i_subfr] = mult_r( Gain_pitX2, exc_fx[i + i_subfr] ); /* Q_new */ } } @@ -291,18 +277,11 @@ Word16 encod_tran_fx( FOR( i = 0; i < L_SUBFR; i++ ) { /* code in Q9, gain_pit in Q14 */ - L_tmp = L_mult( gcode16, code[i] ); -#ifdef BASOP_NOGLOB - L_tmp = L_shl_o( L_tmp, 5, &Overflow ); - L_tmp = L_mac_o( L_tmp, exc_fx[i + i_subfr], gain_pit, &Overflow ); - L_tmp = L_shl_o( L_tmp, 1, &Overflow ); /* saturation can occur here */ - exc_fx[i + i_subfr] = round_fx_o( L_tmp, &Overflow ); -#else - L_tmp = L_shl( L_tmp, 5 ); - L_tmp = L_mac( L_tmp, exc_fx[i + i_subfr], gain_pit ); - L_tmp = L_shl( L_tmp, 1 ); /* saturation can occur here */ - exc_fx[i + i_subfr] = round_fx( L_tmp ); -#endif + L_tmp = L_mult( gcode16, code[i] ); /* Q10 + Q_new */ + L_tmp = L_shl_o( L_tmp, 5, &Overflow ); /* Q15 + Q_new */ + L_tmp = L_mac_o( L_tmp, exc_fx[i + i_subfr], gain_pit, &Overflow ); /* Q15 + Q_new */ + L_tmp = L_shl_o( L_tmp, 1, &Overflow ); /* saturation can occur here Q16 + Q_new */ + exc_fx[i + i_subfr] = round_fx_o( L_tmp, &Overflow ); /* Q_new */ } /*-----------------------------------------------------------------* @@ -314,24 +293,14 @@ Word16 encod_tran_fx( tmp1_fx = add( 16 - ( 2 + Q_AVQ_OUT_DEC + 1 ), Q_new ); FOR( i = 0; i < L_SUBFR; i++ ) { - L_tmp = L_mult( gain_preQ, code_preQ[i] ); /* Q2 + Q10 -> Q13*/ -#ifdef BASOP_NOGLOB + L_tmp = L_mult( gain_preQ, code_preQ[i] ); /* Q2 + Q10 -> Q13*/ L_tmp = L_shl_o( L_tmp, tmp1_fx, &Overflow ); /* Q16 + Q_exc */ tmp_fx = round_fx_o( L_tmp, &Overflow ); - exc2_fx[i + i_subfr] = add_o( exc2_fx[i + i_subfr], tmp_fx, &Overflow ); + exc2_fx[i + i_subfr] = add_o( exc2_fx[i + i_subfr], tmp_fx, &Overflow ); /* Q_exc */ move16(); - exc_fx[i + i_subfr] = add_o( exc_fx[i + i_subfr], tmp_fx, &Overflow ); + exc_fx[i + i_subfr] = add_o( exc_fx[i + i_subfr], tmp_fx, &Overflow ); /* Q_exc */ move16(); -#else - L_tmp = L_shl( L_tmp, tmp1_fx ); /* Q16 + Q_exc */ - tmp_fx = round_fx( L_tmp ); - - exc2_fx[i + i_subfr] = add( exc2_fx[i + i_subfr], tmp_fx ); - move16(); - exc_fx[i + i_subfr] = add( exc_fx[i + i_subfr], tmp_fx ); - move16(); -#endif } } @@ -439,9 +408,9 @@ Word16 encod_tran_fx( IF( st_fx->Opt_SC_VBR ) { /* SC-VBR */ - hSC_VBR->prev_ppp_gain_pit_fx = gain_pit; + hSC_VBR->prev_ppp_gain_pit_fx = gain_pit; /* Q14 */ move16(); - hSC_VBR->prev_tilt_code_fx = hLPDmem->tilt_code; + hSC_VBR->prev_tilt_code_fx = hLPDmem->tilt_code; /* Q15 */ move16(); } @@ -450,20 +419,20 @@ Word16 encod_tran_fx( Word16 encod_tran_ivas_fx( Encoder_State *st_fx, /* i/o: state structure */ - const Word16 speech_fx[], /* i : input speech */ - const Word16 Aw_fx[], /* i : weighted A(z) unquantized for subframes */ - const Word16 Aq_fx[], /* i : 12k8 Lp coefficient */ - const Word16 Es_pred_fx, /* i : predicted scaled innov. energy */ - const Word16 *res_fx, /* i : residual signal */ - Word16 *syn_fx, /* i/o: core synthesis */ - Word16 *exc_fx, /* i/o: current non-enhanced excitation */ - Word16 *exc2_fx, /* i/o: current enhanced excitation */ - Word16 *pitch_buf_fx, /* i/o: floating pitch values for each subframe */ - Word16 *voice_factors, /* o : voicing factors */ - Word16 *bwe_exc_fx, /* i/o: excitation for SWB TBE */ - Word16 tc_subfr, /* i/o: TC subframe classification */ - Word16 position, /* i : maximum of residual signal index */ - Word16 *unbits, /* i/o: number of unused bits */ + const Word16 speech_fx[], /* i : input speech Q0*/ + const Word16 Aw_fx[], /* i : weighted A(z) unquantized for subframes Q12*/ + const Word16 Aq_fx[], /* i : 12k8 Lp coefficient Q12*/ + const Word16 Es_pred_fx, /* i : predicted scaled innov. energy Q8*/ + const Word16 *res_fx, /* i : residual signal Q_new*/ + Word16 *syn_fx, /* i/o: core synthesis Q_new*/ + Word16 *exc_fx, /* i/o: current non-enhanced excitation Q0*/ + Word16 *exc2_fx, /* i/o: current enhanced excitation Q0*/ + Word16 *pitch_buf_fx, /* i/o: floating pitch values for each subframe Q6*/ + Word16 *voice_factors, /* o : voicing factors Q15*/ + Word16 *bwe_exc_fx, /* i/o: excitation for SWB TBE Q0*/ + Word16 tc_subfr, /* i/o: TC subframe classification Q0*/ + Word16 position, /* i : maximum of residual signal index Q0*/ + Word16 *unbits, /* i/o: number of unused bits Q0*/ const Word16 shift, /* i : Scaling to get 12 bits */ const Word16 Q_new /* i : Input scaling */ ) @@ -497,8 +466,10 @@ Word16 encod_tran_ivas_fx( Word16 L_frame_fx; Word16 shift_wsp; Word32 L_tmp; + Word16 q_h1; #ifdef BASOP_NOGLOB_DECLARE_LOCAL Flag Overflow = 0; + move32(); #endif BSTR_ENC_HANDLE hBstr = st_fx->hBstr; SC_VBR_ENC_HANDLE hSC_VBR = st_fx->hSC_VBR; @@ -506,6 +477,11 @@ Word16 encod_tran_ivas_fx( L_frame_fx = st_fx->L_frame; move16(); + +#ifdef MSAN_FIX + set16_fx( h1, 0, L_SUBFR + ( M + 1 ) ); +#endif + /*------------------------------------------------------------------* * Initializations *------------------------------------------------------------------*/ @@ -534,13 +510,13 @@ Word16 encod_tran_ivas_fx( /**unbits = 0;move16();*/ Jopt_flag = 0; move16(); - unbits_ACELP = *unbits; + unbits_ACELP = *unbits; /* Q0 */ move16(); *unbits = 0; move16(); - p_Aw = Aw_fx; - p_Aq = Aq_fx; + p_Aw = Aw_fx; /* Q12 */ + p_Aq = Aq_fx; /* Q12 */ pt_pitch = pitch_buf_fx; gain_preQ = 0; move16(); @@ -559,13 +535,14 @@ Word16 encod_tran_ivas_fx( * Compute impulse response, h1[], of weighted synthesis filter *----------------------------------------------------------------*/ - Copy( &res_fx[i_subfr], &exc_fx[i_subfr], L_SUBFR ); + Copy( &res_fx[i_subfr], &exc_fx[i_subfr], L_SUBFR ); /* Q_new */ find_targets_ivas_fx( speech_fx, hLPDmem->mem_syn, i_subfr, &hLPDmem->mem_w0, p_Aq, res_fx, L_SUBFR, p_Aw, st_fx->preemph_fac, xn, cn, h1 ); - Copy_Scale_sig( h1, h2_fx, L_SUBFR, -2 ); - Scale_sig( h1, L_SUBFR, add( 1, shift ) ); /* set h1[] in Q14 with scaling for convolution */ + q_h1 = sub( 14, norm_s( h1[0] ) ); + Copy_Scale_sig( h1, h2_fx, L_SUBFR, sub( 11, q_h1 ) ); /*Q11*/ + Scale_sig( h1, L_SUBFR, sub( 13, q_h1 ) ); /* scaling of xn[] to limit dynamic at 12 bits */ Scale_sig( xn, L_SUBFR, shift ); @@ -584,6 +561,7 @@ Word16 encod_tran_ivas_fx( IF( GE_32( st_fx->core_brate, MIN_BRATE_AVQ_EXC ) ) { + Scale_sig( h1, L_SUBFR, add( 1, shift ) ); /* set h1[] in Q14 with scaling for convolution */ transf_cdbk_enc_ivas_fx( st_fx, 0, i_subfr, cn, exc_fx, p_Aq, Aw_fx, h1, xn, xn2, y1, y2, Es_pred_fx, &gain_pit, gain_code, g_corr, clip_gain, &gain_preQ, code_preQ, unbits, Q_new, shift ); } @@ -631,14 +609,9 @@ Word16 encod_tran_ivas_fx( } gp_clip_test_gain_pit_fx( st_fx->element_mode, st_fx->core_brate, gain_pit, st_fx->clip_var_fx ); -#ifdef BASOP_NOGLOB Lgcode = L_shl_o( gain_code, Q_new, &Overflow ); /* scaled gain_code with Qnew -> Q16*/ gcode16 = round_fx_o( Lgcode, &Overflow ); -#else - Lgcode = L_shl( gain_code, Q_new ); /* scaled gain_code with Qnew -> Q16*/ - gcode16 = round_fx( Lgcode ); -#endif - hLPDmem->tilt_code = Est_tilt2( &exc_fx[i_subfr], gain_pit, code, Lgcode, &voice_fac, shift ); + hLPDmem->tilt_code = est_tilt_ivas_fx( &exc_fx[i_subfr], gain_pit, code, gain_code, &voice_fac, Q_new, L_SUBFR, 0 ); // Q15 /*-----------------------------------------------------------------* * Update memory of the weighting filter *-----------------------------------------------------------------*/ @@ -649,13 +622,8 @@ Word16 encod_tran_ivas_fx( L_tmp = L_negate( L_tmp ); L_tmp = L_mac( L_tmp, xn[L_SUBFR - 1], 16384 ); // Q_new-1+15+shift L_tmp = L_msu( L_tmp, y1[L_SUBFR - 1], gain_pit ); // Q_new-1+15+shift -#ifdef BASOP_NOGLOB - L_tmp = L_shl_sat( L_tmp, sub( 1, shift ) ); // Q_new+15 - hLPDmem->mem_w0 = round_fx_sat( L_tmp ); /*Q_new-1*/ -#else - L_tmp = L_shl( L_tmp, sub( 1, shift ) ); - hLPDmem->mem_w0 = round_fx( L_tmp ); /*Q_new-1*/ -#endif + L_tmp = L_shl_sat( L_tmp, sub( 1, shift ) ); // Q_new+15 + hLPDmem->mem_w0 = round_fx_sat( L_tmp ); /*Q_new-1*/ /*-----------------------------------------------------------------* * Construct adaptive part of the excitation * Save the non-enhanced excitation for FEC_exc @@ -671,11 +639,7 @@ Word16 encod_tran_ivas_fx( { FOR( i = 0; i < L_SUBFR; i++ ) { -#ifdef BASOP_NOGLOB - exc2_fx[i + i_subfr] = round_fx_sat( L_shl_sat( L_mult_sat( gain_pit, exc_fx[i + i_subfr] ), 1 ) ); -#else - exc2_fx[i + i_subfr] = round_fx( L_shl( L_mult( gain_pit, exc_fx[i + i_subfr] ), 1 ) ); -#endif + exc2_fx[i + i_subfr] = round_fx_sat( L_shl_sat( L_mult_sat( gain_pit, exc_fx[i + i_subfr] ), 1 ) ); /* Q_exc */ } } ELSE @@ -683,7 +647,7 @@ Word16 encod_tran_ivas_fx( Gain_pitX2 = shl( gain_pit, 1 ); FOR( i = 0; i < L_SUBFR; i++ ) { - exc2_fx[i + i_subfr] = mult_r( Gain_pitX2, exc_fx[i + i_subfr] ); + exc2_fx[i + i_subfr] = mult_r( Gain_pitX2, exc_fx[i + i_subfr] ); /* Q_exc */ } } @@ -694,18 +658,11 @@ Word16 encod_tran_ivas_fx( FOR( i = 0; i < L_SUBFR; i++ ) { /* code in Q9, gain_pit in Q14 */ - L_tmp = L_mult( gcode16, code[i] ); -#ifdef BASOP_NOGLOB - L_tmp = L_shl_o( L_tmp, 5, &Overflow ); - L_tmp = L_mac_o( L_tmp, exc_fx[i + i_subfr], gain_pit, &Overflow ); - L_tmp = L_shl_o( L_tmp, 1, &Overflow ); /* saturation can occur here */ - exc_fx[i + i_subfr] = round_fx_o( L_tmp, &Overflow ); -#else - L_tmp = L_shl( L_tmp, 5 ); - L_tmp = L_mac( L_tmp, exc_fx[i + i_subfr], gain_pit ); - L_tmp = L_shl( L_tmp, 1 ); /* saturation can occur here */ - exc_fx[i + i_subfr] = round_fx( L_tmp ); -#endif + L_tmp = L_mult( gcode16, code[i] ); /* Q10 + Q_new */ + L_tmp = L_shl_o( L_tmp, 5, &Overflow ); /* Q15 + Q_new */ + L_tmp = L_mac_o( L_tmp, exc_fx[i + i_subfr], gain_pit, &Overflow ); /* Q15 + Q_new */ + L_tmp = L_shl_o( L_tmp, 1, &Overflow ); /* saturation can occur here Q16 + Q_new */ + exc_fx[i + i_subfr] = round_fx_o( L_tmp, &Overflow ); /* Q_new */ } /*-----------------------------------------------------------------* @@ -717,24 +674,14 @@ Word16 encod_tran_ivas_fx( tmp1_fx = add( 16 - ( 2 + Q_AVQ_OUT_DEC + 1 ), Q_new ); FOR( i = 0; i < L_SUBFR; i++ ) { - L_tmp = L_mult( gain_preQ, code_preQ[i] ); /* Q2 + Q10 -> Q13*/ -#ifdef BASOP_NOGLOB + L_tmp = L_mult( gain_preQ, code_preQ[i] ); /* Q2 + Q10 -> Q13*/ L_tmp = L_shl_o( L_tmp, tmp1_fx, &Overflow ); /* Q16 + Q_exc */ tmp_fx = round_fx_o( L_tmp, &Overflow ); - exc2_fx[i + i_subfr] = add_o( exc2_fx[i + i_subfr], tmp_fx, &Overflow ); - move16(); - exc_fx[i + i_subfr] = add_o( exc_fx[i + i_subfr], tmp_fx, &Overflow ); - move16(); -#else - L_tmp = L_shl( L_tmp, tmp1_fx ); /* Q16 + Q_exc */ - tmp_fx = round_fx( L_tmp ); - - exc2_fx[i + i_subfr] = add( exc2_fx[i + i_subfr], tmp_fx ); + exc2_fx[i + i_subfr] = add_o( exc2_fx[i + i_subfr], tmp_fx, &Overflow ); /* Q_exc */ move16(); - exc_fx[i + i_subfr] = add( exc_fx[i + i_subfr], tmp_fx ); + exc_fx[i + i_subfr] = add_o( exc_fx[i + i_subfr], tmp_fx, &Overflow ); /* Q_exc */ move16(); -#endif } } @@ -843,9 +790,9 @@ Word16 encod_tran_ivas_fx( IF( st_fx->Opt_SC_VBR ) { /* SC-VBR */ - hSC_VBR->prev_ppp_gain_pit_fx = gain_pit; + hSC_VBR->prev_ppp_gain_pit_fx = gain_pit; /* Q14 */ move16(); - hSC_VBR->prev_tilt_code_fx = hLPDmem->tilt_code; + hSC_VBR->prev_tilt_code_fx = hLPDmem->tilt_code; /* Q15 */ move16(); } diff --git a/lib_enc/enc_uv.c b/lib_enc/enc_uv.c deleted file mode 100644 index ccdf49ed34f76e6fc8e0305d1de54cbdde0ce8fa..0000000000000000000000000000000000000000 --- a/lib_enc/enc_uv.c +++ /dev/null @@ -1,43 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include -#include "options.h" -#include -#include "cnst.h" -#include "prot.h" -#include "wmc_auto.h" diff --git a/lib_enc/enc_uv_fx.c b/lib_enc/enc_uv_fx.c index ea88f28b5eff44a563723987895777f3666759dd..cd23c1a6f4035e6a60218dc53dbfe5b06ba74467 100644 --- a/lib_enc/enc_uv_fx.c +++ b/lib_enc/enc_uv_fx.c @@ -5,9 +5,8 @@ #include #include "options.h" /* Compilation switches */ #include "cnst.h" /* Common constants */ -#include "prot.h" /* Function prototypes */ +#include "prot_fx.h" /* Function prototypes */ #include "rom_com.h" -#include "prot_fx.h" /* Function prototypes */ #include "prot_fx_enc.h" /* Function prototypes */ /*-------------------------------------------------------------------* @@ -18,18 +17,18 @@ /*fixed point implementation of unvoiced_encoder*/ void encod_unvoiced_fx( Encoder_State *st_fx, /* i/o: state structure */ - const Word16 *speech_fx, /* i : Input speech */ - const Word16 Aw_fx[], /* i : weighted A(z) unquantized for subframes */ - const Word16 *Aq_fx, /* i : 12k8 Lp coefficient */ - const Word16 Es_pred, /* i : predicted scaled innov. energy */ - const Word16 uc_two_stage_flag, /* i : flag indicating two-stage UC */ - const Word16 *res_fx, /* i : residual signal */ - Word16 *syn_fx, /* o : core synthesis */ - Word16 *tmp_noise_fx, /* o : long-term noise energy */ - Word16 *exc_fx, /* i/o: current non-enhanced excitation */ - Word16 *pitch_buf_fx, /* o : floating pitch values for each subframe */ - Word16 *voice_factors_fx, /* o : voicing factors */ - Word16 *bwe_exc_fx, /* i/o: excitation for SWB TBE */ + const Word16 *speech_fx, /* i : Input speech Q_new*/ + const Word16 Aw_fx[], /* i : weighted A(z) unquantized for subframes Q12*/ + const Word16 *Aq_fx, /* i : 12k8 Lp coefficient Q12*/ + const Word16 Es_pred, /* i : predicted scaled innov. energy Q8*/ + const Word16 uc_two_stage_flag, /* i : flag indicating two-stage UC Q0*/ + const Word16 *res_fx, /* i : residual signal Q_new*/ + Word16 *syn_fx, /* o : core synthesis Q_new*/ + Word16 *tmp_noise_fx, /* o : long-term noise energy Q0*/ + Word16 *exc_fx, /* i/o: current non-enhanced excitation Q_new*/ + Word16 *pitch_buf_fx, /* o : floating pitch values for each subframe Q6*/ + Word16 *voice_factors_fx, /* o : voicing factors Q15*/ + Word16 *bwe_exc_fx, /* i/o: excitation for SWB TBE Q_exc*/ const Word16 Q_new, const Word16 shift ) { @@ -91,10 +90,10 @@ void encod_unvoiced_fx( * Compute impulse response, h1[], of weighted synthesis filter *----------------------------------------------------------------*/ i_subfr_idx = shr( i_subfr, 6 ); - Copy( &res_fx[i_subfr], &exc_fx[i_subfr], L_SUBFR ); + Copy( &res_fx[i_subfr], &exc_fx[i_subfr], L_SUBFR ); /* Q_new */ - find_targets_ivas_fx( speech_fx, hLPDmem->mem_syn, i_subfr, &hLPDmem->mem_w0, p_Aq_fx, - res_fx, L_SUBFR, p_Aw_fx, st_fx->preemph_fac, xn_fx, cn_fx, h1_fx ); + find_targets_fx( speech_fx, hLPDmem->mem_syn, i_subfr, &hLPDmem->mem_w0, p_Aq_fx, + res_fx, L_SUBFR, p_Aw_fx, st_fx->preemph_fac, xn_fx, cn_fx, h1_fx ); /*Copy_Scale_sig(h1_fx, h2_fx, L_SUBFR, -2);*/ Scale_sig( h1_fx, L_SUBFR, add( 1, shift ) ); /* set h1[] in Q14 with scaling for convolution */ @@ -108,22 +107,23 @@ void encod_unvoiced_fx( { *pt_pitch_fx = gaus_encode_fx( st_fx, i_subfr, h1_fx, xn_fx, exc_fx, &hLPDmem->mem_w0, st_fx->clip_var_fx, &hLPDmem->tilt_code, code_fx, &L_gain_code_fx, y2_fx, &gain_inov_fx, - &voice_fac_fx, &gain_pit_fx, Q_new, shift, &norm_gain_code_fx ); + &voice_fac_fx, &gain_pit_fx, Q_new, shift, &norm_gain_code_fx ); /* Q0 */ } ELSE { /*----------------------------------------------------------------* * Unvoiced subframe processing in two stages *----------------------------------------------------------------*/ - // PMT("The code below needs validation, never been tested") + /* No adaptive codebook (UC) */ set16_fx( y1, 0, L_SUBFR ); set16_fx( exc_fx + i_subfr, 0, L_SUBFR ); + /*-----------------------------------------------------------------* * Gain clipping test to avoid unstable synthesis on frame erasure * or in case of floating point encoder & fixed p. decoder *-----------------------------------------------------------------*/ - Mode2_gp_clip( st_fx->voicing_fx, i_subfr, st_fx->coder_type, xn_fx, st_fx->clip_var_fx, L_SUBFR, Q_xn ); + Mode2_gp_clip_fx( st_fx->voicing_fx, i_subfr, st_fx->coder_type, xn_fx, st_fx->clip_var_fx, L_SUBFR, Q_xn ); *pt_pitch_fx = L_SUBFR; move16(); /*----------------------------------------------------------------------* @@ -148,7 +148,7 @@ void encod_unvoiced_fx( *----------------------------------------------------------*/ index = gain_enc_uv_fx( code_fx, code2, L_SUBFR, &gain_pit_fx, &L_gain_code_fx, &gain_code2, - st_fx->flag_noisy_speech_snr, &g_corr, Es_pred, &norm_gain_code_fx, &gain_inov_fx, FUNC_GAIN_ENC_GACELP_UV ); + st_fx->flag_noisy_speech_snr, &g_corr, Es_pred, &norm_gain_code_fx, &gain_inov_fx, FUNC_GAIN_ENC_GACELP_UV ); /* Q0 */ #ifdef DEBUGGING assert( st_fx->acelp_cfg.gains_mode[i_subfr_idx] == 7 && "Error: UC two-stage, only 5+2 gain Q is supported" ); @@ -175,21 +175,17 @@ void encod_unvoiced_fx( * Update memory of the weighting filter *-----------------------------------------------------------------*/ /* st_fx->mem_w0 = xn[L_SUBFR-1] - (gain_pit*y1[L_SUBFR-1]) - (gain_code*y2[L_SUBFR-1]); */ - Ltmp = Mpy_32_16_1( L_gain_code_fx, y2_fx[L_SUBFR - 1] ); - Ltmp = L_shl( Ltmp, add( 5, Q_xn ) ); - Ltmp = L_mac( Ltmp, y1[L_SUBFR - 1], gain_pit_fx ); + Ltmp = Mpy_32_16_1( L_gain_code_fx, y2_fx[L_SUBFR - 1] ); /* Q10 */ + Ltmp = L_shl( Ltmp, add( 5, Q_xn ) ); /* Q15 + Q_xn */ + Ltmp = L_mac( Ltmp, y1[L_SUBFR - 1], gain_pit_fx ); /* Q15 + Q_xn */ /* Add Gaussian contribution*/ - Ltmp2 = Mpy_32_16_1( gain_code2, y22[L_SUBFR - 1] ); - Ltmp2 = L_shl( Ltmp2, add( 5, Q_xn ) ); - Ltmp = L_add( Ltmp, Ltmp2 ); - hLPDmem->mem_w0 = sub( xn_fx[L_SUBFR - 1], round_fx( L_shl( Ltmp, 1 ) ) ); + Ltmp2 = Mpy_32_16_1( gain_code2, y22[L_SUBFR - 1] ); /* Q10 */ + Ltmp2 = L_shl( Ltmp2, add( 5, Q_xn ) ); /* Q15 + Q_xn */ + Ltmp = L_add( Ltmp, Ltmp2 ); /* Q15 + Q_xn */ + hLPDmem->mem_w0 = sub( xn_fx[L_SUBFR - 1], round_fx( L_shl( Ltmp, 1 ) ) ); /* Q_xn */ move16(); BASOP_SATURATE_WARNING_OFF_EVS; -#ifdef BASOP_NOGLOB hLPDmem->mem_w0 = shr_sat( hLPDmem->mem_w0, shift ); /*Qnew-1*/ -#else - hLPDmem->mem_w0 = shr( hLPDmem->mem_w0, shift ); /*Qnew-1*/ -#endif BASOP_SATURATE_WARNING_ON_EVS; /*-------------------------------------------------------* @@ -202,28 +198,21 @@ void encod_unvoiced_fx( FOR( i = sub( tmp2, shr( L_SUBFR, 1 ) ); i < tmp2; i++ ) { /* code in Q9, gain_pit in Q14; exc Q_new */ - Ltmp = Mpy_32_16_1( gain_code2, code2[i] ); - Ltmp = L_shl( Ltmp, Q_new_p5 ); - Ltmp = L_mac( Ltmp, gain_pit_fx, exc_fx[i + i_subfr] ); - Ltmp2 = Mpy_32_16_1( gain_code_vect[j], code_fx[i] ); - Ltmp2 = L_shl( Ltmp2, Q_new_p5 ); - Ltmp = L_add( Ltmp, Ltmp2 ); -#ifdef BASOP_NOGLOB - Ltmp = L_shl_sat( Ltmp, 1 ); /* saturation can occur here */ - exc_fx[i + i_subfr] = round_fx_sat( Ltmp ); -#else - BASOP_SATURATE_WARNING_OFF_EVS - Ltmp = L_shl( Ltmp, 1 ); /* saturation can occur here */ - BASOP_SATURATE_WARNING_ON_EVS - exc_fx[i + i_subfr] = round_fx( Ltmp ); -#endif + Ltmp = Mpy_32_16_1( gain_code2, code2[i] ); /* Q10 */ + Ltmp = L_shl( Ltmp, Q_new_p5 ); /* Q15 + Q_new */ + Ltmp = L_mac( Ltmp, gain_pit_fx, exc_fx[i + i_subfr] ); /* Q_new + Q15 */ + Ltmp2 = Mpy_32_16_1( gain_code_vect[j], code_fx[i] ); /* Q10 */ + Ltmp2 = L_shl( Ltmp2, Q_new_p5 ); /* Q15 + Q_new */ + Ltmp = L_add( Ltmp, Ltmp2 ); /* Q15 + Q_new */ + Ltmp = L_shl_sat( Ltmp, 1 ); /* saturation can occur here Q16 + Q_new */ + exc_fx[i + i_subfr] = round_fx_sat( Ltmp ); /* Q_new */ } tmp2 = L_SUBFR; move16(); } } - *tmp_noise_fx = extract_h( norm_gain_code_fx ); + *tmp_noise_fx = extract_h( norm_gain_code_fx ); /* Q0 */ voice_factors_fx[i_subfr / L_SUBFR] = 0; move16(); @@ -241,9 +230,9 @@ void encod_unvoiced_fx( } /* SC-VBR */ - hSC_VBR->prev_ppp_gain_pit_fx = gain_pit_fx; + hSC_VBR->prev_ppp_gain_pit_fx = gain_pit_fx; /* Q14 */ move16(); - hSC_VBR->prev_tilt_code_fx = hLPDmem->tilt_code; + hSC_VBR->prev_tilt_code_fx = hLPDmem->tilt_code; /* Q15 */ move16(); return; @@ -251,18 +240,18 @@ void encod_unvoiced_fx( void encod_unvoiced_ivas_fx( Encoder_State *st_fx, /* i/o: state structure */ - const Word16 *speech_fx, /* i : Input speech */ - const Word16 Aw_fx[], /* i : weighted A(z) unquantized for subframes */ - const Word16 *Aq_fx, /* i : 12k8 Lp coefficient */ - const Word16 Es_pred, /* i : predicted scaled innov. energy */ - const Word16 uc_two_stage_flag, /* i : flag indicating two-stage UC */ - const Word16 *res_fx, /* i : residual signal */ - Word16 *syn_fx, /* o : core synthesis */ - Word16 *tmp_noise_fx, /* o : long-term noise energy */ - Word16 *exc_fx, /* i/o: current non-enhanced excitation */ - Word16 *pitch_buf_fx, /* o : floating pitch values for each subframe */ - Word16 *voice_factors_fx, /* o : voicing factors */ - Word16 *bwe_exc_fx, /* i/o: excitation for SWB TBE */ + const Word16 *speech_fx, /* i : Input speech Q_new*/ + const Word16 Aw_fx[], /* i : weighted A(z) unquantized for subframes Q12*/ + const Word16 *Aq_fx, /* i : 12k8 Lp coefficient Q12*/ + const Word16 Es_pred, /* i : predicted scaled innov. energy Q8*/ + const Word16 uc_two_stage_flag, /* i : flag indicating two-stage UC Q0*/ + const Word16 *res_fx, /* i : residual signal Q_new*/ + Word16 *syn_fx, /* o : core synthesis Q_new*/ + Word16 *tmp_noise_fx, /* o : long-term noise energy Q0*/ + Word16 *exc_fx, /* i/o: current non-enhanced excitation Q_new*/ + Word16 *pitch_buf_fx, /* o : floating pitch values for each subframe Q6*/ + Word16 *voice_factors_fx, /* o : voicing factors Q15*/ + Word16 *bwe_exc_fx, /* i/o: excitation for SWB TBE Q_exc*/ const Word16 Q_new, const Word16 shift ) { @@ -290,6 +279,7 @@ void encod_unvoiced_ivas_fx( Word16 i_subfr, Q_xn, Q_new_p5, tmp2, j, i; Word16 index, i_subfr_idx; Word16 unbits_PI; + Word16 q_h1; acelp_cfg = &( st_fx->acelp_cfg ); SC_VBR_ENC_HANDLE hSC_VBR = st_fx->hSC_VBR; LPD_state_HANDLE hLPDmem = st_fx->hLPDmem; @@ -325,13 +315,14 @@ void encod_unvoiced_ivas_fx( * Compute impulse response, h1[], of weighted synthesis filter *----------------------------------------------------------------*/ i_subfr_idx = shr( i_subfr, 6 ); - Copy( &res_fx[i_subfr], &exc_fx[i_subfr], L_SUBFR ); + Copy( &res_fx[i_subfr], &exc_fx[i_subfr], L_SUBFR ); /* Q_new */ find_targets_ivas_fx( speech_fx, hLPDmem->mem_syn, i_subfr, &hLPDmem->mem_w0, p_Aq_fx, res_fx, L_SUBFR, p_Aw_fx, st_fx->preemph_fac, xn_fx, cn_fx, h1_fx ); - Copy_Scale_sig( h1_fx, h2_fx, L_SUBFR, -2 ); - Scale_sig( h1_fx, L_SUBFR, add( 1, shift ) ); /* set h1[] in Q14 with scaling for convolution */ + q_h1 = sub( 14, norm_s( h1_fx[0] ) ); + Copy_Scale_sig( h1_fx, h2_fx, L_SUBFR, sub( 11, q_h1 ) ); + Scale_sig( h1_fx, L_SUBFR, sub( 14, q_h1 ) ); /* scaling of xn[] to limit dynamic at 12 bits */ Scale_sig( xn_fx, L_SUBFR, shift ); // Q_new - 1 + shift @@ -342,7 +333,7 @@ void encod_unvoiced_ivas_fx( { *pt_pitch_fx = gaus_encode_ivas_fx( st_fx, i_subfr, h1_fx, xn_fx, exc_fx, &hLPDmem->mem_w0, st_fx->clip_var_fx, &hLPDmem->tilt_code, code_fx, &L_gain_code_fx, y2_fx, &gain_inov_fx, - &voice_fac_fx, &gain_pit_fx, Q_new, shift, &norm_gain_code_fx ); + &voice_fac_fx, &gain_pit_fx, Q_new, shift, &norm_gain_code_fx ); /* Q0 */ move16(); } ELSE @@ -358,7 +349,7 @@ void encod_unvoiced_ivas_fx( * Gain clipping test to avoid unstable synthesis on frame erasure * or in case of floating point encoder & fixed p. decoder *-----------------------------------------------------------------*/ - Mode2_gp_clip( st_fx->voicing_fx, i_subfr, st_fx->coder_type, xn_fx, st_fx->clip_var_fx, L_SUBFR, Q_xn ); + Mode2_gp_clip_fx( st_fx->voicing_fx, i_subfr, st_fx->coder_type, xn_fx, st_fx->clip_var_fx, L_SUBFR, Q_xn ); *pt_pitch_fx = L_SUBFR << 6; move16(); /*----------------------------------------------------------------------* @@ -390,7 +381,7 @@ void encod_unvoiced_ivas_fx( *----------------------------------------------------------*/ index = gain_enc_uv_fx( code_fx, code2, L_SUBFR, &gain_pit_fx, &L_gain_code_fx, &gain_code2, - st_fx->flag_noisy_speech_snr, &g_corr, Es_pred, &norm_gain_code_fx, &gain_inov_fx, FUNC_GAIN_ENC_GACELP_UV ); + st_fx->flag_noisy_speech_snr, &g_corr, Es_pred, &norm_gain_code_fx, &gain_inov_fx, FUNC_GAIN_ENC_GACELP_UV ); /* Q0 */ #ifdef DEBUGGING assert( st_fx->acelp_cfg.gains_mode[i_subfr_idx] == 7 && "Error: UC two-stage, only 5+2 gain Q is supported" ); @@ -418,21 +409,17 @@ void encod_unvoiced_ivas_fx( * Update memory of the weighting filter *-----------------------------------------------------------------*/ /* st_fx->mem_w0 = xn[L_SUBFR-1] - (gain_pit*y1[L_SUBFR-1]) - (gain_code*y2[L_SUBFR-1]); */ - Ltmp = Mpy_32_16_1( L_gain_code_fx, y2_fx[L_SUBFR - 1] ); - Ltmp = L_shl( Ltmp, add( 5, Q_xn ) ); // Qxn+15 - Ltmp = L_mac( Ltmp, y1[L_SUBFR - 1], gain_pit_fx ); + Ltmp = Mpy_32_16_1( L_gain_code_fx, y2_fx[L_SUBFR - 1] ); /* Q10 */ + Ltmp = L_shl( Ltmp, add( 5, Q_xn ) ); // Qxn+15 + Ltmp = L_mac( Ltmp, y1[L_SUBFR - 1], gain_pit_fx ); /* Qxn + Q15 */ /* Add Gaussian contribution*/ - Ltmp2 = Mpy_32_16_1( gain_code2, y22[L_SUBFR - 1] ); - Ltmp2 = L_shl( Ltmp2, add( 5, Q_xn ) ); // Q_xn+15 - Ltmp = L_add( Ltmp, Ltmp2 ); + Ltmp2 = Mpy_32_16_1( gain_code2, y22[L_SUBFR - 1] ); /* Q10 */ + Ltmp2 = L_shl( Ltmp2, add( 5, Q_xn ) ); // Q_xn+15 + Ltmp = L_add( Ltmp, Ltmp2 ); /* Qxn + Q15 */ hLPDmem->mem_w0 = sub( xn_fx[L_SUBFR - 1], round_fx( L_shl( Ltmp, 1 ) ) ); // Q_xn move16(); BASOP_SATURATE_WARNING_OFF_EVS; -#ifdef BASOP_NOGLOB hLPDmem->mem_w0 = shr_sat( hLPDmem->mem_w0, shift ); /*Qnew-1*/ -#else - hLPDmem->mem_w0 = shr( hLPDmem->mem_w0, shift ); /*Qnew-1*/ -#endif move16(); BASOP_SATURATE_WARNING_ON_EVS; @@ -446,28 +433,14 @@ void encod_unvoiced_ivas_fx( FOR( i = sub( tmp2, shr( L_SUBFR, 1 ) ); i < tmp2; i++ ) { /* code in Q9, gain_pit in Q14; exc Q_new */ - Ltmp = Mpy_32_16_1( gain_code2, code2[i] ); -#ifdef BASOP_NOGLOB - Ltmp = L_shl_sat( Ltmp, Q_new_p5 ); - Ltmp = L_mac_sat( Ltmp, gain_pit_fx, exc_fx[i + i_subfr] ); -#else - Ltmp = L_shl( Ltmp, Q_new_p5 ); - Ltmp = L_mac( Ltmp, gain_pit_fx, exc_fx[i + i_subfr] ); -#endif - Ltmp2 = Mpy_32_16_1( gain_code_vect[j], code_fx[i] ); -#ifdef BASOP_NOGLOB - Ltmp2 = L_shl_sat( Ltmp2, Q_new_p5 ); - Ltmp = L_add_sat( Ltmp, Ltmp2 ); - Ltmp = L_shl_sat( Ltmp, 1 ); /* saturation can occur here */ - exc_fx[i + i_subfr] = round_fx_sat( Ltmp ); -#else - BASOP_SATURATE_WARNING_OFF_EVS - Ltmp2 = L_shl( Ltmp2, Q_new_p5 ); - Ltmp = L_add( Ltmp, Ltmp2 ); - Ltmp = L_shl( Ltmp, 1 ); /* saturation can occur here */ - BASOP_SATURATE_WARNING_ON_EVS - exc_fx[i + i_subfr] = round_fx( Ltmp ); -#endif + Ltmp = Mpy_32_16_1( gain_code2, code2[i] ); /* Q10 */ + Ltmp = L_shl_sat( Ltmp, Q_new_p5 ); /* Q15 + Q_new */ + Ltmp = L_mac_sat( Ltmp, gain_pit_fx, exc_fx[i + i_subfr] ); /* Q15 + Q_new */ + Ltmp2 = Mpy_32_16_1( gain_code_vect[j], code_fx[i] ); /* Q10 */ + Ltmp2 = L_shl_sat( Ltmp2, Q_new_p5 ); /* Q15 + Q_new */ + Ltmp = L_add_sat( Ltmp, Ltmp2 ); /* Q15 + Q_new */ + Ltmp = L_shl_sat( Ltmp, 1 ); /* saturation can occur here Q16 + Q_new */ + exc_fx[i + i_subfr] = round_fx_sat( Ltmp ); /* Q_new */ move16(); } tmp2 = L_SUBFR; @@ -480,7 +453,14 @@ void encod_unvoiced_ivas_fx( voice_factors_fx[i_subfr / L_SUBFR] = 0; move16(); +#ifdef FIX_ISSUE_1148 + if ( st_fx->hBWE_TD != NULL ) + { + interp_code_5over2_fx( &exc_fx[i_subfr], &bwe_exc_fx[i_subfr * HIBND_ACB_L_FAC], L_SUBFR ); + } +#else interp_code_5over2_fx( &exc_fx[i_subfr], &bwe_exc_fx[i_subfr * HIBND_ACB_L_FAC], L_SUBFR ); +#endif /*-----------------------------------------------------------------* * Synthesize speech to update mem_syn[]. @@ -496,9 +476,9 @@ void encod_unvoiced_ivas_fx( /* SC-VBR */ IF( hSC_VBR ) { - hSC_VBR->prev_ppp_gain_pit_fx = gain_pit_fx; + hSC_VBR->prev_ppp_gain_pit_fx = gain_pit_fx; /* Q14 */ move16(); - hSC_VBR->prev_tilt_code_fx = hLPDmem->tilt_code; + hSC_VBR->prev_tilt_code_fx = hLPDmem->tilt_code; /* Q15 */ move16(); } diff --git a/lib_enc/energy.c b/lib_enc/energy.c deleted file mode 100644 index 59a3eb11a82f687754109ba17252b6dfe625aca8..0000000000000000000000000000000000000000 --- a/lib_enc/energy.c +++ /dev/null @@ -1,42 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include "prot.h" -#include "cnst.h" -#include "rom_enc.h" -#include "wmc_auto.h" diff --git a/lib_enc/energy_fx.c b/lib_enc/energy_fx.c index 054245a6d288b432c1c5b5107d52f713ce9ed4d6..7dc96a4e31a73fa401bb5170f05035510b58de02 100644 --- a/lib_enc/energy_fx.c +++ b/lib_enc/energy_fx.c @@ -17,18 +17,18 @@ * *-------------------------------------------------------------------*/ void est_energy_fx( - Word32 enerBuffer[CLDFB_NO_CHANNELS_MAX], /* i : energy vector per band */ - Word16 enerBuffer_exp, /* i : exponent of energy vector */ - Word32 *frame_sb_energy, /* o : energy of sub-band divided non-uniformly*/ - Word32 *frame_energy2_p, /* o : frame energy 2*/ - Word32 *HB_Power_p, /* o : high frequency energy*/ - Word32 *frame_energy_p, /* o : frame energy 1*/ - Word16 *sb_power_Q, /* o : the scaling of sb_power*/ - Word16 *frame_energy2_Q, /* o : the scaling of frame_energy*/ - Word16 *HB_Power_Q, /* o : the scaling of HB_Power*/ - Word16 *frame_energy_Q, /* o : the Scaling of frame_energy*/ - Word16 *frame_sb_energy_scale, /* o : the Scaling of frame_sb_energy[]*/ - const Word32 bandwidth /* i : band width*/ + Word32 enerBuffer[CLDFB_NO_CHANNELS_MAX], /* i : energy vector per band enerBuffer_exp*/ + Word16 enerBuffer_exp, /* i : exponent of energy vector */ + Word32 *frame_sb_energy, /* o : energy of sub-band divided non-uniformly frame_sb_energy_scale*/ + Word32 *frame_energy2_p, /* o : frame energy 2 frame_energy2_Q*/ + Word32 *HB_Power_p, /* o : high frequency energy HB_Power_Q*/ + Word32 *frame_energy_p, /* o : frame energy 1 frame_energy_Q*/ + Word16 *sb_power_Q, /* o : the scaling of sb_power */ + Word16 *frame_energy2_Q, /* o : the scaling of frame_energy */ + Word16 *HB_Power_Q, /* o : the scaling of HB_Power */ + Word16 *frame_energy_Q, /* o : the Scaling of frame_energy */ + Word16 *frame_sb_energy_scale, /* o : the Scaling of frame_sb_energy[] */ + const Word32 bandwidth /* i : band width Q0*/ ) { Word32 i, j; @@ -56,44 +56,38 @@ void est_energy_fx( BandNum = BAND_NUM_TAB[bandwidth]; move16(); - frame_energy2 = L_shr( sb_power[1], shr_tmp ); - HB_Power = L_shr( sb_power[6], shr_tmp ); + frame_energy2 = L_shr( sb_power[1], shr_tmp ); /* 31 - enerBuffer_exp - shr_tmp */ + HB_Power = L_shr( sb_power[6], shr_tmp ); /* 31 - enerBuffer_exp - shr_tmp */ FOR( i = 2; i < BandNum; i++ ) { - Ltmp32 = L_shr( sb_power[i], shr_tmp ); -#ifdef BASOP_NOGLOB - frame_energy2 = L_add_sat( frame_energy2, Ltmp32 ); + Ltmp32 = L_shr( sb_power[i], shr_tmp ); /* 31 - enerBuffer_exp - shr_tmp */ + frame_energy2 = L_add_sat( frame_energy2, Ltmp32 ); /* 31 - enerBuffer_exp - shr_tmp */ if ( i > 6 ) HB_Power = L_add_sat( HB_Power, Ltmp32 ); -#else - frame_energy2 = L_add( frame_energy2, Ltmp32 ); - if ( i > 6 ) - HB_Power = L_add( HB_Power, Ltmp32 ); -#endif } - frame_energy2 = L_sub( frame_energy2, Ltmp32 ); + frame_energy2 = L_sub( frame_energy2, Ltmp32 ); /* 31 - enerBuffer_exp - shr_tmp */ - sb_power_tmp = L_shr( sb_power[0], shr_tmp ); + sb_power_tmp = L_shr( sb_power[0], shr_tmp ); /* 31 - enerBuffer_exp - shr_tmp */ IF( EQ_32( bandwidth, 1 ) ) { - frame_energy = L_add( frame_energy2, MUL_F( sb_power_tmp, 0x147a ) ); + frame_energy = L_add( frame_energy2, MUL_F( sb_power_tmp, 0x147a /* 0.16 in Q15 */ ) ); } ELSE IF( EQ_32( bandwidth, 2 ) ) { - frame_energy = L_add( frame_energy2, MUL_F( sb_power_tmp, 0x1eb8 ) ); + frame_energy = L_add( frame_energy2, MUL_F( sb_power_tmp, 0x1eb8 /* 0.24 in Q15 */ ) ); } ELSE IF( EQ_32( bandwidth, 3 ) ) { - frame_energy = L_add( frame_energy2, MUL_F( sb_power_tmp, 0x23d7 ) ); + frame_energy = L_add( frame_energy2, MUL_F( sb_power_tmp, 0x23d7 /* 0.28 in Q15 */ ) ); } ELSE IF( EQ_32( bandwidth, 4 ) ) { - frame_energy = L_add( frame_energy2, MUL_F( sb_power_tmp, 0x23d7 ) ); + frame_energy = L_add( frame_energy2, MUL_F( sb_power_tmp, 0x23d7 /* 0.28 in Q15 */ ) ); } ELSE { - frame_energy = L_add( frame_energy2, MUL_F( sb_power_tmp, 0x23d7 ) ); + frame_energy = L_add( frame_energy2, MUL_F( sb_power_tmp, 0x23d7 /* 0.28 in Q15 */ ) ); } *frame_energy2_p = frame_energy2; @@ -115,7 +109,7 @@ void est_energy_fx( FOR( i = 0; i < 6; i++ ) { - frame_sb_energy[i] = sb_power[i]; + frame_sb_energy[i] = sb_power[i]; /* sb_power_Q */ move32(); } @@ -123,19 +117,15 @@ void est_energy_fx( { s32CopyPower = 0; move32(); - widthsb = sub( Nregion_index[i + 1], Nregion_index[i] ); + widthsb = sub( Nregion_index[i + 1], Nregion_index[i] ); /* Q0 */ s16MaxCoefNorm = sub( ffr_getSfWord32( ( sb_power + Nregion_index[i] ), widthsb ), NREGION_PREOFF[i] ); FOR( j = Nregion_index[i]; j < Nregion_index[i + 1]; j++ ) { - tmpspec_amp = L_shl( sb_power[j], s16MaxCoefNorm ); + tmpspec_amp = L_shl( sb_power[j], s16MaxCoefNorm ); /* sb_power_Q + s16MaxCoefNorm */ s32CopyPower = L_add( s32CopyPower, tmpspec_amp ); } -#ifdef BASOP_NOGLOB - frame_sb_energy[i] = L_shr_o( s32CopyPower, s16MaxCoefNorm, &Overflow ); -#else /* BASOP_NOGLOB */ - frame_sb_energy[i] = L_shr( s32CopyPower, s16MaxCoefNorm ); -#endif + frame_sb_energy[i] = L_shr_o( s32CopyPower, s16MaxCoefNorm, &Overflow ); /* sb_power_Q */ move32(); } @@ -180,28 +170,29 @@ static void NormEnergyWord32( * *-------------------------------------------------------------------*/ static void update_sb_bg_energy( - Word32 *sb_bg_energy, - Word16 *tbg_energy_count, + Word32 *sb_bg_energy, /* p_scale_sb_energy */ + Word16 *tbg_energy_count, /* Q0 */ Word16 *p_scale_sb_energy, - const Word32 SNR_sb_num, - const Word32 *frame_sb_energy, + const Word32 SNR_sb_num, /* Q0 */ + const Word32 *frame_sb_energy, /* frame_sb_energy_scale */ const Word16 frame_sb_energy_scale, - const Word16 FAC_16Q15_a, + const Word16 FAC_16Q15_a, /* Q15 */ const Word16 tmp_Q_add, - const Word16 FAC_16Q19_b ) + const Word16 FAC_16Q19_b /* Q19 */ +) { Word32 sb_bg_energy_ti, tmp; Word16 tmpQ, i; - *tbg_energy_count = add( *tbg_energy_count, 1 ); + *tbg_energy_count = add_sat( *tbg_energy_count, 1 ); /* Q0 */ move16(); tmpQ = add( tmp_Q_add, frame_sb_energy_scale ); FOR( i = 0; i < SNR_sb_num; i++ ) { - sb_bg_energy_ti = MUL_F( sb_bg_energy[i], FAC_16Q15_a ); + sb_bg_energy_ti = MUL_F( sb_bg_energy[i], FAC_16Q15_a ); /* p_scale_sb_energy */ tmp = MUL_F( frame_sb_energy[i], FAC_16Q19_b ); - sb_bg_energy[i] = VAD_L_ADD( sb_bg_energy_ti, p_scale_sb_energy[i], tmp, tmpQ, &p_scale_sb_energy[i] ); + sb_bg_energy[i] = VAD_L_ADD( sb_bg_energy_ti, p_scale_sb_energy[i], tmp, tmpQ, &p_scale_sb_energy[i] ); /* p_scale_sb_energy */ move32(); } } @@ -212,12 +203,13 @@ static void update_sb_bg_energy( * *-------------------------------------------------------------------*/ void background_update_fx( - VAD_CLDFB_HANDLE hVAD_CLDFB, /* i/o: CLDFB VAD state */ - Word16 scale, /* i : the scaling of frame energy*/ - Word32 frame_energy, /* i : current frame energy*/ - Word32 update_flag, /* i : update flag*/ - Word16 music_backgound_f, /* i : background music flag*/ - Word32 snr ) + VAD_CLDFB_HANDLE hVAD_CLDFB, /* i/o: CLDFB VAD state */ + Word16 scale, /* i : the scaling of frame energy */ + Word32 frame_energy, /* i : current frame energy scale*/ + Word32 update_flag, /* i : update flag Q0*/ + Word16 music_backgound_f, /* i : background music flag Q0*/ + Word32 snr /* Q25 */ +) { Word32 tmp; Word16 i, tmpQ, cmp_lt_frame, cmp_pre_frame; @@ -279,12 +271,13 @@ void background_update_fx( test(); test(); test(); - IF( ( LT_16( hVAD_CLDFB->frameloop, 60 ) ) && ( GT_16( hVAD_CLDFB->frameloop, 5 ) ) && ( LT_16( f_tonality_rate[0], 9174 /* 0.56 Q14 */ ) ) && ( LT_16( f_tonality_rate[1], 8192 /* 0.5 Q14 */ ) ) && ( LT_16( ltd_stable_rate[1], 1966 /* 0.06 Q15 */ ) ) && LT_32( snr, 83886080 ) ) + IF( ( LT_16( hVAD_CLDFB->frameloop, 60 ) ) && ( GT_16( hVAD_CLDFB->frameloop, 5 ) ) && ( LT_16( f_tonality_rate[0], 9174 /* 0.56 Q14 */ ) ) && ( LT_16( f_tonality_rate[1], 8192 /* 0.5 Q14 */ ) ) && ( LT_16( ltd_stable_rate[1], 1966 /* 0.06 Q15 */ ) ) && LT_32( snr, 83886080 /* 2.5f in Q25 */ ) ) { IF( LT_16( hVAD_CLDFB->frameloop, 50 ) ) { - exp_frame_energy_amendment.s32Mantissa = VAD_L_div( exp_frame_energy.s32Mantissa, 10, exp_frame_energy.s16Exp, 0, &q_divout ); + exp_frame_energy_amendment.s32Mantissa = VAD_L_div( exp_frame_energy.s32Mantissa, 10, exp_frame_energy.s16Exp, 0, &q_divout ); /* exp(divout) */ exp_frame_energy_amendment.s16Exp = q_divout; + move16(); t_bg_energy_sum = VAD_AddExp( t_bg_energy_sum, exp_frame_energy_amendment ); } ELSE @@ -303,8 +296,9 @@ void background_update_fx( { IF( LT_16( hVAD_CLDFB->frameloop, 50 ) ) { - exp_frame_energy_amendment.s32Mantissa = VAD_L_div( exp_frame_energy.s32Mantissa, 10, exp_frame_energy.s16Exp, 0, &q_divout ); + exp_frame_energy_amendment.s32Mantissa = VAD_L_div( exp_frame_energy.s32Mantissa, 10, exp_frame_energy.s16Exp, 0, &q_divout ); /* exp(q_divout) */ exp_frame_energy_amendment.s16Exp = q_divout; + move16(); t_bg_energy_sum = VAD_AddExp( t_bg_energy_sum, exp_frame_energy_amendment ); } ELSE @@ -314,7 +308,8 @@ void background_update_fx( update_sb_bg_energy( sb_bg_energy, &hVAD_CLDFB->tbg_energy_count, p_scale_sb_energy, SNR_sb_num, frame_sb_energy, hVAD_CLDFB->frame_sb_energy_scale, 31456 /* 0.96 Q15 */, 4, 20971 /* 0.04 Q19 */ ); - hVAD_CLDFB->bg_update_count = add( hVAD_CLDFB->bg_update_count, 1 ); + hVAD_CLDFB->bg_update_count = add( hVAD_CLDFB->bg_update_count, 1 ); /* Q0 */ + move16(); } ELSE { @@ -329,9 +324,9 @@ void background_update_fx( tmpQ = add( 9, hVAD_CLDFB->frame_sb_energy_scale ); FOR( i = 0; i < SNR_sb_num; i++ ) { - sb_bg_energy_ti = MUL_F( sb_bg_energy[i], 32734 /* 0.999 Q15 */ ); + sb_bg_energy_ti = MUL_F( sb_bg_energy[i], 32734 /* 0.999 Q15 */ ); /* p_scale_sb_energy */ tmp = MUL_F( frame_sb_energy[i], 16777 /* 0.001 Q24 */ ); - sb_bg_energy[i] = VAD_L_ADD( sb_bg_energy_ti, p_scale_sb_energy[i], tmp, tmpQ, &p_scale_sb_energy[i] ); + sb_bg_energy[i] = VAD_L_ADD( sb_bg_energy_ti, p_scale_sb_energy[i], tmp, tmpQ, &p_scale_sb_energy[i] ); /* p_scale_sb_energy */ move32(); } } @@ -340,8 +335,9 @@ void background_update_fx( { IF( LT_16( hVAD_CLDFB->frameloop, 50 ) ) { - exp_frame_energy_amendment.s32Mantissa = VAD_L_div( exp_frame_energy.s32Mantissa, 10, exp_frame_energy.s16Exp, 0, &q_divout ); + exp_frame_energy_amendment.s32Mantissa = VAD_L_div( exp_frame_energy.s32Mantissa, 10, exp_frame_energy.s16Exp, 0, &q_divout ); /* exp(q_divout) */ exp_frame_energy_amendment.s16Exp = q_divout; + move16(); t_bg_energy_sum = VAD_AddExp( t_bg_energy_sum, exp_frame_energy_amendment ); } ELSE @@ -358,8 +354,9 @@ void background_update_fx( { IF( LT_16( hVAD_CLDFB->frameloop, 50 ) ) { - exp_frame_energy_amendment.s32Mantissa = VAD_L_div( exp_frame_energy.s32Mantissa, 10, exp_frame_energy.s16Exp, 0, &q_divout ); + exp_frame_energy_amendment.s32Mantissa = VAD_L_div( exp_frame_energy.s32Mantissa, 10, exp_frame_energy.s16Exp, 0, &q_divout ); /* exp(q_divout) */ exp_frame_energy_amendment.s16Exp = q_divout; + move16(); t_bg_energy_sum = VAD_AddExp( t_bg_energy_sum, exp_frame_energy_amendment ); } ELSE @@ -373,7 +370,7 @@ void background_update_fx( { IF( LT_16( hVAD_CLDFB->frameloop, 50 ) ) { - exp_frame_energy_amendment.s32Mantissa = VAD_L_div( exp_frame_energy.s32Mantissa, 10, exp_frame_energy.s16Exp, 0, &q_divout ); + exp_frame_energy_amendment.s32Mantissa = VAD_L_div( exp_frame_energy.s32Mantissa, 10, exp_frame_energy.s16Exp, 0, &q_divout ); /* exp(q_divout) */ exp_frame_energy_amendment.s16Exp = q_divout; t_bg_energy_sum = VAD_AddExp( t_bg_energy_sum, exp_frame_energy_amendment ); } @@ -390,7 +387,7 @@ void background_update_fx( ELSE { cmp_pre_frame = VAD_L_CMP( t_bg_energy, hVAD_CLDFB->scale_t_bg_energy, MUL_F( exp_frame_energy.s32Mantissa, 32000 ), sub( exp_frame_energy.s16Exp, 9 ) ); - cmp_lt_frame = VAD_L_CMP( sb_bg_energy[0], scale_sb_energy, MUL_F( frame_sb_energy[0], 20480 ), sub( hVAD_CLDFB->frame_sb_energy_scale, 4 ) ); + cmp_lt_frame = VAD_L_CMP( sb_bg_energy[0], scale_sb_energy, MUL_F( frame_sb_energy[0], 20480 /* 10 in Q11 */ ), sub( hVAD_CLDFB->frame_sb_energy_scale, 4 ) ); test(); IF( ( cmp_pre_frame > 0 ) && ( cmp_lt_frame > 0 ) ) @@ -398,9 +395,9 @@ void background_update_fx( tmpQ = add( 3, hVAD_CLDFB->frame_sb_energy_scale ); FOR( i = 0; i < SNR_sb_num; i++ ) { - sb_bg_energy_ti = MUL_F( sb_bg_energy[i], 29490 /* 0.90 Q15 */ ); + sb_bg_energy_ti = MUL_F( sb_bg_energy[i], 29490 /* 0.90 Q15 */ ); /* p_scale_sb_energy */ tmp = MUL_F( frame_sb_energy[i], 26214 /* 0.10 Q18 */ ); - sb_bg_energy[i] = VAD_L_ADD( sb_bg_energy_ti, p_scale_sb_energy[i], tmp, tmpQ, &p_scale_sb_energy[i] ); + sb_bg_energy[i] = VAD_L_ADD( sb_bg_energy_ti, p_scale_sb_energy[i], tmp, tmpQ, &p_scale_sb_energy[i] ); /* p_scale_sb_energy */ move32(); } } @@ -412,16 +409,16 @@ void background_update_fx( tmpQ = add( 9, hVAD_CLDFB->frame_sb_energy_scale ); FOR( i = 0; i < SNR_sb_num; i++ ) { - sb_bg_energy_ti = MUL_F( sb_bg_energy[i], 32734 /* 0.999 Q15 */ ); + sb_bg_energy_ti = MUL_F( sb_bg_energy[i], 32734 /* 0.999 Q15 */ ); /* exp(p_scale_sb_energy) */ tmp = MUL_F( frame_sb_energy[i], 16777 /* 0.001 Q24 */ ); - sb_bg_energy[i] = VAD_L_ADD( sb_bg_energy_ti, p_scale_sb_energy[i], tmp, tmpQ, &p_scale_sb_energy[i] ); + sb_bg_energy[i] = VAD_L_ADD( sb_bg_energy_ti, p_scale_sb_energy[i], tmp, tmpQ, &p_scale_sb_energy[i] ); /* exp(p_scale_sb_energy) */ move32(); } } } } - tmp = L_mult0( 160, (Word16) hVAD_CLDFB->tbg_energy_count ); + tmp = L_mult0( 160, (Word16) hVAD_CLDFB->tbg_energy_count ); /* Q31 */ cmp_pre_frame = VAD_L_CMP( t_bg_energy_sum.s32Mantissa, t_bg_energy_sum.s16Exp, tmp, 0 ); IF( cmp_pre_frame > 0 ) { @@ -438,10 +435,10 @@ void background_update_fx( test(); IF( ( EQ_16( music_backgound_f, 1 ) ) && ( LT_32( hVAD_CLDFB->lt_snr_org, 107374179 /* 3.2 Q25 */ ) ) && ( cmp_pre_frame > 0 ) && update_flag == 0 ) { - tmp = L_shr( 2147 /* 0.000001 Q31 */, sub( 31, scale_sb_energy ) ); + tmp = L_shr( 2147 /* 0.000001 Q31 */, sub( 31, scale_sb_energy ) ); /* scale_sb_energy */ FOR( i = 0; i < SNR_sb_num; i++ ) { - sb_bg_energy[i] = L_add( MUL_F( sb_bg_energy[i], 32112 /* 0.98 Q15 */ ), tmp ); + sb_bg_energy[i] = L_add( MUL_F( sb_bg_energy[i], 32112 /* 0.98 Q15 */ ), tmp ); /* scale_sb_energy */ move32(); } } @@ -451,10 +448,14 @@ void background_update_fx( cmp_pre_frame = VAD_L_CMP( exp_frame_energy.s32Mantissa, exp_frame_energy.s16Exp, MUL_F( t_bg_energy, 5000 ), sub( hVAD_CLDFB->scale_t_bg_energy, 15 ) ); IF( cmp_pre_frame < 0 ) { - tmp = L_shr( 2147 /* 0.000001 Q31 */, sub( 31, scale_sb_energy ) ); + tmp = L_shr( 2147 /* 0.000001 Q31 */, sub( 31, scale_sb_energy ) ); /* scale_sb_energy */ FOR( i = 0; i < SNR_sb_num; i++ ) { - sb_bg_energy[i] = L_add( MUL_F( sb_bg_energy[i], 32112 /* 0.98 Q15 */ ), tmp ); +#ifdef FIX_ISSUE_1209 + sb_bg_energy[i] = L_add_sat( MUL_F( sb_bg_energy[i], 32112 /* 0.98 Q15 */ ), tmp ); /* scale_sb_energy */ +#else + sb_bg_energy[i] = L_add( MUL_F( sb_bg_energy[i], 32112 /* 0.98 Q15 */ ), tmp ); /* scale_sb_energy */ +#endif move32(); } } @@ -467,7 +468,7 @@ void background_update_fx( t_bg_energy_sum.s32Mantissa = MUL_F( t_bg_energy_sum.s32Mantissa, 24575 /* 0.75 Q15 */ ); } - t_bg_energy = VAD_L_div( t_bg_energy_sum.s32Mantissa, hVAD_CLDFB->tbg_energy_count, t_bg_energy_sum.s16Exp, 0, &q_divout ); + t_bg_energy = VAD_L_div( t_bg_energy_sum.s32Mantissa, hVAD_CLDFB->tbg_energy_count, t_bg_energy_sum.s16Exp, 0, &q_divout ); /* exp(q_divout) */ hVAD_CLDFB->scale_t_bg_energy = q_divout; move16(); hVAD_CLDFB->t_bg_energy = t_bg_energy; diff --git a/lib_enc/eval_pit_contr.c b/lib_enc/eval_pit_contr.c deleted file mode 100644 index d441f6ead49ddcb3a6a1ffab0962633db8157cd0..0000000000000000000000000000000000000000 --- a/lib_enc/eval_pit_contr.c +++ /dev/null @@ -1,43 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include -#include "cnst.h" -#include "rom_com.h" -#include "prot.h" -#include "wmc_auto.h" diff --git a/lib_enc/eval_pit_contr_fx.c b/lib_enc/eval_pit_contr_fx.c index a438b79a69d7c00f4014be221038ba6ef65b1921..d5f832f8ca3b50f161972cbc058cd6ca10479459 100644 --- a/lib_enc/eval_pit_contr_fx.c +++ b/lib_enc/eval_pit_contr_fx.c @@ -6,7 +6,6 @@ #include "cnst.h" /* Common constants */ #include "rom_com_fx.h" /* Static table prototypes */ #include "rom_com.h" /* Static table prototypes */ -#include "prot.h" /* Function prototypes */ #include "prot_fx.h" /* Function prototypes */ #include "prot_fx_enc.h" /* Function prototypes */ @@ -51,11 +50,11 @@ Word16 Pit_exc_contribution_len_fx( /* o : bin where pitch contribution is significant */ Encoder_State *st_fx, /* i/o: state structure */ - const Word16 *dct_res, /* i : DCT of residual */ - Word16 *dct_pitex, /* i/o: DCT of pitch contribution */ - Word16 *pitch_buf, /* i/o: Pitch per subframe */ - const Word16 nb_subfr, /* i : Number of subframe considered */ - Word16 *hangover, /* i : hangover for the time contribution switching */ + const Word16 *dct_res, /* i : DCT of residual Qnew*/ + Word16 *dct_pitex, /* i/o: DCT of pitch contribution Qnew*/ + Word16 *pitch_buf, /* i/o: Pitch per subframe Q6*/ + const Word16 nb_subfr, /* i : Number of subframe considered Q0*/ + Word16 *hangover, /* i : hangover for the time contribution switching Q0*/ Word16 Qnew ) { @@ -80,6 +79,8 @@ Word16 Pit_exc_contribution_len_fx( /* o : bin where pit SP_MUS_CLAS_HANDLE hSpMusClas = st_fx->hSpMusClas; BSTR_ENC_HANDLE hBstr = st_fx->hBstr; GSC_ENC_HANDLE hGSCEnc = st_fx->hGSCEnc; + move16(); + move16(); if ( EQ_16( st_fx->L_frame, L_FRAME16k ) ) { @@ -115,8 +116,8 @@ Word16 Pit_exc_contribution_len_fx( /* o : bin where pit FOR( j = 0; j < mfreq_bindiv_loc[i]; j++ ) /* up to maximum allowed voiced critical band */ { - tmp_ex = mult_r( dct_pitex[j + freq], 8192 ); - tmp_res = mult_r( dct_res[j + freq], 8192 ); + tmp_ex = mult_r( dct_pitex[j + freq], 8192 /* 0.25 in Q15 */ ); + tmp_res = mult_r( dct_res[j + freq], 8192 /* 0.25 in Q15 */ ); corr_tmp = L_mac0( corr_tmp, tmp_res, tmp_ex ); /*2*Qnew*/ ener_res = L_mac0( ener_res, tmp_res, tmp_res ); /*2*Qnew*/ ener_pit = L_mac0( ener_pit, tmp_ex, tmp_ex ); /*2*Qnew*/ @@ -145,10 +146,10 @@ Word16 Pit_exc_contribution_len_fx( /* o : bin where pit FOR( i = 1; i < Mbands_loc - 1; i++ ) /* up to maximum allowed voiced critical band */ { - L_tmp = L_mult( BETA_FX, corr_dct_pit[i - 1] ); - L_tmp = L_mac( L_tmp, BETA_FX, corr_dct_pit[i + 1] ); + L_tmp = L_mult( BETA_FX, corr_dct_pit[i - 1] ); /* Q30 */ + L_tmp = L_mac( L_tmp, BETA_FX, corr_dct_pit[i + 1] ); /* Q30 */ - tmp = mac_r( L_tmp, ALPA_FX, corr_dct_pit[i] ); + tmp = mac_r( L_tmp, ALPA_FX, corr_dct_pit[i] ); /* Q30 */ tmp = s_max( tmp, val_thrs ); corr_dct_pit_tmp[i] = shl( sub( tmp, val_thrs ), 1 ); @@ -176,7 +177,7 @@ Word16 Pit_exc_contribution_len_fx( /* o : bin where pit if ( EQ_16( st_fx->L_frame, L_FRAME16k ) ) { /*av_corr *= 1.25f;*/ - av_corr = add( av_corr, shr( av_corr, 2 ) ); + av_corr = add( av_corr, shr( av_corr, 2 ) ); /* Q2 */ } test(); if ( GE_16( st_fx->GSC_IVAS_mode, 1 ) || LT_32( st_fx->core_brate, ACELP_9k60 ) ) @@ -193,7 +194,7 @@ Word16 Pit_exc_contribution_len_fx( /* o : bin where pit { last_pit_band = i; move16(); - min_corr = ftmp; + min_corr = ftmp; /* Q2 */ move16(); } } @@ -315,13 +316,13 @@ Word16 Pit_exc_contribution_len_fx( /* o : bin where pit { last_pit_band = add( BAND1k2, 1 ); } - last_pit_bin = mfreq_loc_div_25[last_pit_band]; + last_pit_bin = mfreq_loc_div_25[last_pit_band]; /* Q0 */ move16(); st_fx->bpf_off = 0; move16(); - max_len = sub( st_fx->L_frame, last_pit_bin ); + max_len = sub( st_fx->L_frame, last_pit_bin ); /* Q0 */ if ( EQ_16( st_fx->bwidth, NB ) ) { @@ -350,7 +351,7 @@ Word16 Pit_exc_contribution_len_fx( /* o : bin where pit FOR( i = 0; i < Len; i++ ) { - dct_pitex[i + last_pit_bin] = mult_r( dct_pitex[i + last_pit_bin], sm_table_fx[i] ); + dct_pitex[i + last_pit_bin] = mult_r( dct_pitex[i + last_pit_bin], sm_table_fx[i] ); /* Q_new */ } FOR( ; i < max_len; i++ ) { @@ -358,7 +359,7 @@ Word16 Pit_exc_contribution_len_fx( /* o : bin where pit move16(); } } - hGSCEnc->mem_last_pit_band = last_pit_band; + hGSCEnc->mem_last_pit_band = last_pit_band; /* Q0 */ move16(); pit_contr_idx = sub( last_pit_band, BAND1k2 ); } @@ -380,28 +381,21 @@ Word16 Pit_exc_contribution_len_fx( /* o : bin where pit /* pitch contribution useless - delete all previously written indices belonging to pitch contribution */ FOR( i = TAG_ACELP_SUBFR_LOOP_START; i < TAG_ACELP_SUBFR_LOOP_END; i++ ) { -#ifndef IVAS_CODE_BITSTREAM IF( hBstr->ind_list[i].nb_bits != -1 ) { - hBstr->nb_bits_tot = sub( hBstr->nb_bits_tot, hBstr->ind_list[i].nb_bits ); + hBstr->nb_bits_tot = sub( hBstr->nb_bits_tot, hBstr->ind_list[i].nb_bits ); /* Q0 */ hBstr->ind_list[i].nb_bits = -1; move16(); } -#else - delete_indice( hBstr, i ); -#endif } -#ifndef IVAS_CODE_BITSTREAM IF( hBstr->ind_list[IND_ES_PRED].nb_bits != -1 ) { - hBstr->nb_bits_tot = sub( hBstr->nb_bits_tot, hBstr->ind_list[IND_ES_PRED].nb_bits ); + hBstr->nb_bits_tot = sub( hBstr->nb_bits_tot, hBstr->ind_list[IND_ES_PRED].nb_bits ); /* Q0 */ + move16(); hBstr->ind_list[IND_ES_PRED].nb_bits = -1; move16(); } -#else - delete_indice( hBstr, i ); -#endif } IF( LT_32( st_fx->core_brate, CFREQ_BITRATE ) ) { @@ -434,11 +428,11 @@ Word16 Pit_exc_contribution_len_fx( /* o : bin where pit Word16 Pit_exc_contribution_len_ivas_fx( /* o : bin where pitch contribution is significant */ Encoder_State *st_fx, /* i/o: state structure */ - const Word16 *dct_res, /* i : DCT of residual */ - Word16 *dct_pitex, /* i/o: DCT of pitch contribution */ - Word16 *pitch_buf, /* i/o: Pitch per subframe */ - const Word16 nb_subfr, /* i : Number of subframe considered */ - Word16 *hangover, /* i : hangover for the time contribution switching */ + const Word16 *dct_res, /* i : DCT of residual Q_new*/ + Word16 *dct_pitex, /* i/o: DCT of pitch contribution Q_new*/ + Word16 *pitch_buf, /* i/o: Pitch per subframe Q6*/ + const Word16 nb_subfr, /* i : Number of subframe considered Q0*/ + Word16 *hangover, /* i : hangover for the time contribution switching Q0*/ Word16 Qnew ) { @@ -463,6 +457,7 @@ Word16 Pit_exc_contribution_len_ivas_fx( /* o : bin wher SP_MUS_CLAS_HANDLE hSpMusClas = st_fx->hSpMusClas; BSTR_ENC_HANDLE hBstr = st_fx->hBstr; GSC_ENC_HANDLE hGSCEnc = st_fx->hGSCEnc; + move16(); if ( EQ_16( st_fx->L_frame, L_FRAME16k ) ) { @@ -521,33 +516,33 @@ Word16 Pit_exc_contribution_len_ivas_fx( /* o : bin wher move16(); /* 0.5 in Q14*/ /* Smooth the inter-correlation value and skip the last band for the average (since last band is almost always 0)*/ tmp = mac_r( L_mult( ALPA_FX, corr_dct_pit[0] ), ALPAM1_FX, corr_dct_pit[1] ); /*Qnew*/ - tmp = s_max( tmp, val_thrs ); + tmp = s_max( tmp, val_thrs ); /*Qnew */ - corr_dct_pit_tmp[0] = shl( sub( tmp, val_thrs ), 1 ); + corr_dct_pit_tmp[0] = shl( sub( tmp, val_thrs ), 1 ); /* Q_new + 1 */ move16(); FOR( i = 1; i < Mbands_loc - 1; i++ ) /* up to maximum allowed voiced critical band */ { - L_tmp = L_mult( BETA_FX, corr_dct_pit[i - 1] ); - L_tmp = L_mac( L_tmp, BETA_FX, corr_dct_pit[i + 1] ); + L_tmp = L_mult( BETA_FX, corr_dct_pit[i - 1] ); /* Q_new + 16 */ + L_tmp = L_mac( L_tmp, BETA_FX, corr_dct_pit[i + 1] ); /* Q_new + 16 */ - tmp = mac_r( L_tmp, ALPA_FX, corr_dct_pit[i] ); - tmp = s_max( tmp, val_thrs ); + tmp = mac_r( L_tmp, ALPA_FX, corr_dct_pit[i] ); /* Q_new */ + tmp = s_max( tmp, val_thrs ); /* Q_new */ - corr_dct_pit_tmp[i] = shl( sub( tmp, val_thrs ), 1 ); + corr_dct_pit_tmp[i] = shl( sub( tmp, val_thrs ), 1 ); /* Q_new + 1 */ move16(); } tmp = mac_r( L_mult( ALPA_FX, corr_dct_pit[i] ), ALPAM1_FX, corr_dct_pit[i - 1] ); /*Qnew*/ - tmp = s_max( tmp, val_thrs ); - corr_dct_pit_tmp[i] = shl( sub( tmp, val_thrs ), 1 ); + tmp = s_max( tmp, val_thrs ); /* Q_new */ + corr_dct_pit_tmp[i] = shl( sub( tmp, val_thrs ), 1 ); /* Q_new + 1 */ move16(); - Copy( corr_dct_pit_tmp, corr_dct_pit, Mbands_loc ); + Copy( corr_dct_pit_tmp, corr_dct_pit, Mbands_loc ); /* Q_new + 1 */ L_tmp1 = L_mult( DIV_NB_VOIC_FX, corr_dct_pit[0] ); /*Qnew*/ FOR( i = 1; i < NB_VOIC_FX; i++ ) /* up to maximum allowed voiced critical band */ { - L_tmp1 = L_mac( L_tmp1, DIV_NB_VOIC_FX, corr_dct_pit[i] ); + L_tmp1 = L_mac( L_tmp1, DIV_NB_VOIC_FX, corr_dct_pit[i] ); /* Q_new + 16 */ } av_corr = round_fx( L_tmp1 ); /*Qnew*/ @@ -652,7 +647,7 @@ Word16 Pit_exc_contribution_len_ivas_fx( /* o : bin wher move16(); } - ( *hangover ) = sub( ( *hangover ), 1 ); + ( *hangover ) = sub( ( *hangover ), 1 ); /* Q0 */ if ( *hangover < 0 ) { *hangover = 0; @@ -678,7 +673,7 @@ Word16 Pit_exc_contribution_len_ivas_fx( /* o : bin wher test(); test(); /*if(st_fx->core_brate core_brate, ACELP_9k60 ) && LT_16( low_pit, 4096 ) ) + IF( LT_32( st_fx->core_brate, ACELP_9k60 ) && LT_16( low_pit, 4096 /* 64 in Q6 */ ) ) { last_pit_band = add( 9, BAND1k2 ); if ( EQ_16( st_fx->bwidth, NB ) ) @@ -686,7 +681,7 @@ Word16 Pit_exc_contribution_len_ivas_fx( /* o : bin wher last_pit_band = add( 7, BAND1k2 ); } } - ELSE IF( LT_32( st_fx->core_brate, ACELP_9k60 ) && LT_16( low_pit, 8192 ) ) + ELSE IF( LT_32( st_fx->core_brate, ACELP_9k60 ) && LT_16( low_pit, 8192 /* 128 in Q6 */ ) ) { last_pit_band = add( 5, BAND1k2 ); } @@ -698,7 +693,7 @@ Word16 Pit_exc_contribution_len_ivas_fx( /* o : bin wher { last_pit_band = add( BAND1k2, 1 ); } - last_pit_bin = mfreq_loc_div_25[last_pit_band]; + last_pit_bin = mfreq_loc_div_25[last_pit_band]; /* Q15 */ move16(); st_fx->bpf_off = 0; @@ -733,7 +728,7 @@ Word16 Pit_exc_contribution_len_ivas_fx( /* o : bin wher FOR( i = 0; i < Len; i++ ) { - dct_pitex[i + last_pit_bin] = mult_r( dct_pitex[i + last_pit_bin], sm_table_fx[i] ); + dct_pitex[i + last_pit_bin] = mult_r( dct_pitex[i + last_pit_bin], sm_table_fx[i] ); /* Q_new */ } FOR( ; i < max_len; i++ ) { diff --git a/lib_enc/evs_enc.c b/lib_enc/evs_enc.c deleted file mode 100644 index d4fe802221847d9ecedad7d46d88d7aeb2f2d099..0000000000000000000000000000000000000000 --- a/lib_enc/evs_enc.c +++ /dev/null @@ -1,45 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include "cnst.h" -#include "rom_com.h" -#include "prot.h" -#include "wmc_auto.h" -#include "ivas_prot_fx.h" -#include "prot_fx.h" -#include "prot_fx_enc.h" diff --git a/lib_enc/evs_enc_fx.c b/lib_enc/evs_enc_fx.c index 787eb6c68f8cf45fef04ca67e6b8eecba7d44cc1..c86b7e0613bcc737810d7a33d01b17b2d021a76e 100644 --- a/lib_enc/evs_enc_fx.c +++ b/lib_enc/evs_enc_fx.c @@ -5,10 +5,9 @@ #include #include #include "options.h" /* Compilation switches */ -#include "prot.h" +#include "prot_fx.h" #include "cnst.h" /* Common constants */ #include "rom_com.h" /* Common constants */ -#include "prot_fx.h" /* Function prototypes */ #include "basop_util.h" /* Function prototypes */ #include "prot_fx_enc.h" #ifdef DEBUGGING @@ -30,10 +29,10 @@ static void configure_core_coder_loc( Encoder_State *st ); *-------------------------------------------------------------------*/ ivas_error evs_enc_fx( - Encoder_State *st, /* i/o: encoder state structure */ - const Word16 *data, /* i : input signal */ - Word32 *mem_hp20_in_fx, /* i/o: hp20 filter memory */ - const Word16 n_samples /* i : number of input samples */ + Encoder_State *st, /* i/o: encoder state structure */ + const Word16 *data, /* i : input signal Q0*/ + Word32 *mem_hp20_in_fx, /* i/o: hp20 filter memory Qx*/ + const Word16 n_samples /* i : number of input samples Q0*/ ) { Word16 i, input_frame, delay; @@ -144,13 +143,13 @@ ivas_error evs_enc_fx( /* get delay to synchronize ACELP and MDCT frame */ delay = NS2SA_FX2( st->input_Fs, DELAY_FIR_RESAMPL_NS ); - Copy( st->input_fx - delay, st->old_input_signal_fx, input_frame + delay ); + Copy( st->input_fx - delay, st->old_input_signal_fx, input_frame + delay ); /* st->q_inp */ /*----------------------------------------------------------------* * convert 'short' input data to 'float' *----------------------------------------------------------------*/ - Copy( data, st->input_fx, input_frame ); + Copy( data, st->input_fx, input_frame ); /* st-> q_inp */ IF( LT_16( n_samples, input_frame ) ) { set16_fx( st->input_fx + n_samples, 0, sub( input_frame, n_samples ) ); @@ -225,7 +224,7 @@ ivas_error evs_enc_fx( IF( EQ_16( st->last_L_frame, L_FRAME ) && st->ini_frame != 0 ) { /* this is just an approximation, but it is sufficient */ - Copy( st->lsp_old1_fx, st->lspold_enc_fx, M ); + Copy( st->lsp_old1_fx, st->lspold_enc_fx, M ); /* Q15 */ } } ELSE @@ -238,7 +237,7 @@ ivas_error evs_enc_fx( move16(); } - st->sr_core = L_mult0( FRAMES_PER_SEC, st->L_frame ); + st->sr_core = L_mult0( FRAMES_PER_SEC, st->L_frame ); /* Q0 */ st->core_brate = st->total_brate; move32(); @@ -282,12 +281,7 @@ ivas_error evs_enc_fx( IF( EQ_16( st->core, ACELP_CORE ) ) { acelp_core_enc_fx( st, inp, ener, A, Aw, epsP_h, epsP_l, lsp_new, lsp_mid, vad_hover_flag, - attack_flag, bwe_exc_extended, voice_factors, old_syn_12k8_16k, pitch_buf, &unbits, Q_new, shift -#ifdef ADD_LRTD - , - NULL, NULL -#endif - ); + attack_flag, bwe_exc_extended, voice_factors, old_syn_12k8_16k, pitch_buf, &unbits, NULL, NULL, Q_new, shift ); } /*---------------------------------------------------------------------* * HQ core encoding @@ -332,7 +326,7 @@ ivas_error evs_enc_fx( bwe_exc_extended, voice_factors, pitch_buf, vad_hover_flag, &Q_new, &shift ); #ifndef FIX_I4_OL_PITCH - Copy( pitch_orig, st->pitch, 3 ); /* populate the original OL pitch values back */ + Copy( pitch_orig, st->pitch, 3 ); /* populate the original OL pitch values back Q0*/ #endif /*---------------------------------------------------------------------* @@ -393,12 +387,12 @@ ivas_error evs_enc_fx( move32(); } - st->core_brate = L_sub( st->total_brate, st->extl_brate ); + st->core_brate = L_sub( st->total_brate, st->extl_brate ); /* Q0 */ IF( EQ_16( st->tec_tfa, 1 ) ) { - st->core_brate = L_sub( st->core_brate, BITS_TEC ); - st->core_brate = L_sub( st->core_brate, BITS_TFA ); + st->core_brate = L_sub( st->core_brate, BITS_TEC ); /* Q0 */ + st->core_brate = L_sub( st->core_brate, BITS_TFA ); /* Q0 */ } } @@ -413,14 +407,14 @@ ivas_error evs_enc_fx( IF( st->igf != 0 && EQ_16( st->core, ACELP_CORE ) && GT_32( st->core_brate, SID_2k40 ) ) { /* padBits = ((st->bits_frame+7)/8)*8 - (st->nb_bits_tot + (st->rf_target_bits_write - ((st->Opt_RF_ON==1)?1:0) ) + get_tbe_bits(st->total_brate, st->bwidth, st->rf_mode )); */ - tmp = add( get_tbe_bits_fx( st->total_brate, st->bwidth, st->rf_mode ), sub( st->rf_target_bits_write, st->rf_mode ) ); - padBits = sub( sub( shl( shr( add( st->bits_frame, 7 ), 3 ), 3 ), hBstr->nb_bits_tot ), tmp ); + tmp = add( get_tbe_bits_fx( st->total_brate, st->bwidth, st->rf_mode ), sub( st->rf_target_bits_write, st->rf_mode ) ); /* Q0 */ + padBits = sub( sub( shl( shr( add( st->bits_frame, 7 ), 3 ), 3 ), hBstr->nb_bits_tot ), tmp ); /* Q0 */ } ELSE { /* padBits = ((st->bits_frame+7)/8)*8 - (st->nb_bits_tot + (st->rf_target_bits_write - ((st->Opt_RF_ON==1)?1:0) )); */ - tmp = sub( st->rf_target_bits_write, st->rf_mode ); - padBits = sub( shl( shr( add( st->bits_frame, 7 ), 3 ), 3 ), add( hBstr->nb_bits_tot, tmp ) ); + tmp = sub( st->rf_target_bits_write, st->rf_mode ); /* Q0 */ + padBits = sub( shl( shr( add( st->bits_frame, 7 ), 3 ), 3 ), add( hBstr->nb_bits_tot, tmp ) ); /* Q0 */ } FOR( i = 0; i < padBits; i++ ) @@ -517,7 +511,7 @@ ivas_error evs_enc_fx( st->hTECEnc->corrFlag = 0; move16(); } - st->tfa_flag = tfaEnc_TBE_fx( st->tfa_enr, st->last_core, st->voicing_fx, pitch_buf, shl( Q_shb_spch, 1 ) ); + st->tfa_flag = tfaEnc_TBE_fx( st->tfa_enr, st->last_core, st->voicing_fx, pitch_buf, shl( Q_shb_spch, 1 ) ); /* Q0 */ set_TEC_TFA_code_fx( st->hTECEnc->corrFlag, &st->tec_flag, &st->tfa_flag ); } ELSE diff --git a/lib_enc/ext_sig_ana.c b/lib_enc/ext_sig_ana.c deleted file mode 100644 index 9f9fa4c23133239f729cb22721f441ff8c4e71c0..0000000000000000000000000000000000000000 --- a/lib_enc/ext_sig_ana.c +++ /dev/null @@ -1,43 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include -#include "options.h" -#include -#include "prot.h" -#include "rom_com.h" -#include "wmc_auto.h" diff --git a/lib_enc/ext_sig_ana_fx.c b/lib_enc/ext_sig_ana_fx.c index 0ad43487ac788b746cdc6c5dcc23370f05fd86cb..f546c3ef8f6c2edb7eddad5358700447e8efc613 100644 --- a/lib_enc/ext_sig_ana_fx.c +++ b/lib_enc/ext_sig_ana_fx.c @@ -23,19 +23,19 @@ void core_signal_analysis_high_bitrate_fx( const Word16 *new_samples, /*i: 0Q15*/ - const Word16 T_op[3], /* i : open-loop pitch values for quantiz. */ - Word16 lsp_new[], - Word16 lsp_mid[], + const Word16 T_op[3], /* i : open-loop pitch values for quantiz. Q0*/ + Word16 lsp_new[], /* Q15 */ + Word16 lsp_mid[], /* Q15 */ Encoder_State *st, - Word16 pTnsSize[], - Word16 pTnsBits[], - Word16 param_core[], - Word16 *ltpBits, - const Word16 L_frame, - const Word16 L_frameTCX, - const Word16 last_element_mode, - const Word16 vad_hover_flag, /* i : VAD hangover flag */ - Word32 **spectrum, + Word16 pTnsSize[], /* Q0 */ + Word16 pTnsBits[], /* Q0 */ + Word16 param_core[], /* Q0 */ + Word16 *ltpBits, /* Q0 */ + const Word16 L_frame, /* Q0 */ + const Word16 L_frameTCX, /* Q0 */ + const Word16 last_element_mode, /* Q0 */ + const Word16 vad_hover_flag, /* i : VAD hangover flag Q0*/ + Word32 **spectrum, /* spectrum_e */ Word16 *spectrum_e, Word16 *Q_new ) { @@ -93,10 +93,10 @@ void core_signal_analysis_high_bitrate_fx( right_overlap = -1; move16(); - tcx10SizeFB = shl( st->hTcxCfg->tcx5SizeFB, 1 ); - tcx5SizeFB = st->hTcxCfg->tcx5SizeFB; + tcx10SizeFB = shl( st->hTcxCfg->tcx5SizeFB, 1 ); /* Q0 */ + tcx5SizeFB = st->hTcxCfg->tcx5SizeFB; /* Q0 */ move16(); - tcx10Size = shl( st->hTcxCfg->tcx5Size, 1 ); + tcx10Size = shl( st->hTcxCfg->tcx5Size, 1 ); /* Q0 */ /*--------------------------------------------------------------* * Input Signal Processing: copy, HP filter, pre-emphasis @@ -105,8 +105,8 @@ void core_signal_analysis_high_bitrate_fx( /* Copy Samples */ IF( st->tcxonly && NE_16( st->element_mode, IVAS_CPE_MDCT ) ) { - Copy( new_samples, st->new_speech_enc, L_frame ); - Scale_sig( st->new_speech_enc, L_frame, 1 ); + Copy( new_samples, st->new_speech_enc, L_frame ); /* Q0 */ + Scale_sig( st->new_speech_enc, L_frame, 1 ); /* Q1 */ } /*--------------------------------------------------------------* @@ -158,16 +158,16 @@ void core_signal_analysis_high_bitrate_fx( move16(); /* Rescale Memory */ - Scale_sig( st->old_inp_16k_fx, L_INP_MEM, sub( *Q_new, st->Q_old ) ); + Scale_sig( st->old_inp_16k_fx, L_INP_MEM, sub( *Q_new, st->Q_old ) ); /* Q_new */ IF( Q_exp != 0 ) { - Scale_sig( st->buf_speech_enc_pe, st->encoderPastSamples_enc + st->encoderLookahead_enc, Q_exp ); + Scale_sig( st->buf_speech_enc_pe, st->encoderPastSamples_enc + st->encoderLookahead_enc, Q_exp ); /* Q15 - exp_buf_speech_enc_pe + Q_exp */ Scale_sig( &( st->mem_wsp_enc ), 1, Q_exp ); } IF( EQ_16( hTcxEnc->tcxMode, TCX_10 ) ) { - Copy( ¶m_core[1 + NOISE_FILL_RANGES], ¶m_core[NPRM_DIV + 1 + NOISE_FILL_RANGES], LTPSIZE ); + Copy( ¶m_core[1 + NOISE_FILL_RANGES], ¶m_core[NPRM_DIV + 1 + NOISE_FILL_RANGES], LTPSIZE ); /* Q0 */ } @@ -178,19 +178,19 @@ void core_signal_analysis_high_bitrate_fx( { lsp[0] = lsp_new; lsp[1] = lsp_mid; - alw_pitch_lag_12k8[0] = st->pitch[0]; + alw_pitch_lag_12k8[0] = st->pitch[0]; /* Q0 */ move16(); - alw_pitch_lag_12k8[1] = st->pitch[1]; + alw_pitch_lag_12k8[1] = st->pitch[1]; /* Q0 */ move16(); - alw_voicing[0] = st->voicing_fx[0]; + alw_voicing[0] = st->voicing_fx[0]; /* Q15 */ move16(); - alw_voicing[1] = st->voicing_fx[1]; + alw_voicing[1] = st->voicing_fx[1]; /* Q15 */ move16(); - alw_pitch_lag_12k8_wc = s_min( alw_pitch_lag_12k8[0], alw_pitch_lag_12k8[1] ); - alw_voicing_wc = s_max( alw_voicing[0], alw_voicing[1] ); + alw_pitch_lag_12k8_wc = s_min( alw_pitch_lag_12k8[0], alw_pitch_lag_12k8[1] ); /* Q0 */ + alw_voicing_wc = s_max( alw_voicing[0], alw_voicing[1] ); /* Q15 */ } - overlap_mode[0] = last_overlap; /* Overlap between the last and the current frame */ + overlap_mode[0] = last_overlap; /* Overlap between the last and the current frame Q0*/ move16(); IF( EQ_16( hTcxEnc->tcxMode, TCX_20 ) ) @@ -200,14 +200,14 @@ void core_signal_analysis_high_bitrate_fx( transform_type[0] = TCX_20; transform_type[1] = TCX_20; move16(); - overlap_mode[1] = curr_overlap; /* Overlap between the current and the next frame */ + overlap_mode[1] = curr_overlap; /* Overlap between the current and the next frame Q0*/ move16(); IF( NE_16( st->element_mode, IVAS_CPE_MDCT ) ) { - alw_pitch_lag_12k8[0] = alw_pitch_lag_12k8_wc; + alw_pitch_lag_12k8[0] = alw_pitch_lag_12k8_wc; /* Q0 */ move16(); - alw_voicing[0] = alw_voicing_wc; + alw_voicing[0] = alw_voicing_wc; /* Q15 */ move16(); } } @@ -260,7 +260,7 @@ void core_signal_analysis_high_bitrate_fx( move16(); } } - overlap_mode[2] = curr_overlap; /* Overlap between the current and the next frame */ + overlap_mode[2] = curr_overlap; /* Overlap between the current and the next frame Q0*/ move16(); } IF( NE_16( transform_type[0], TCX_20 ) ) @@ -273,14 +273,14 @@ void core_signal_analysis_high_bitrate_fx( FOR( frameno = 0; frameno < nSubframes; frameno++ ) { - L_subframe = L_frameTCX; + L_subframe = L_frameTCX; /* Q0 */ move16(); if ( NE_16( nSubframes, 1 ) ) L_subframe = shr( L_frameTCX, 1 ); - lpc_left_overlap_mode = overlap_mode[frameno]; + lpc_left_overlap_mode = overlap_mode[frameno]; /* Q0 */ move16(); - lpc_right_overlap_mode = overlap_mode[frameno + 1]; + lpc_right_overlap_mode = overlap_mode[frameno + 1]; /* Q0 */ move16(); if ( EQ_16( lpc_left_overlap_mode, ALDO_WINDOW ) ) { @@ -318,11 +318,7 @@ void core_signal_analysis_high_bitrate_fx( /* Outter left folding */ FOR( i = 0; i < folding_offset; i++ ) { -#ifdef BASOP_NOGLOB - tcx20Win[folding_offset + i] = sub_sat( tcx20Win[folding_offset + i], tcx20Win[folding_offset - 1 - i] ); -#else - tcx20Win[folding_offset + i] = sub( tcx20Win[folding_offset + i], tcx20Win[folding_offset - 1 - i] ); -#endif + tcx20Win[folding_offset + i] = sub_sat( tcx20Win[folding_offset + i], tcx20Win[folding_offset - 1 - i] ); // Q0 move16(); } #ifdef IVAS_CODE @@ -338,19 +334,15 @@ void core_signal_analysis_high_bitrate_fx( tmp = shr( right_overlap, 1 ); FOR( i = 0; i < tmp; i++ ) { -#ifdef BASOP_NOGLOB - tcx20Win[L_subframe + folding_offset - 1 - i] = add_sat( tcx20Win[L_subframe + folding_offset - 1 - i], tcx20Win[L_subframe + folding_offset + i] ); -#else - tcx20Win[L_subframe + folding_offset - 1 - i] = add( tcx20Win[L_subframe + folding_offset - 1 - i], tcx20Win[L_subframe + folding_offset + i] ); -#endif + tcx20Win[L_subframe + folding_offset - 1 - i] = add_sat( tcx20Win[L_subframe + folding_offset - 1 - i], tcx20Win[L_subframe + folding_offset + i] ); // Q0 move16(); } /* 2xTCX5 */ - L_subframe = tcx5SizeFB; + L_subframe = tcx5SizeFB; /* Q0 */ move16(); tmpP16 = tcx20Win; - tmpP32 = spectrum[frameno]; + tmpP32 = spectrum[frameno]; /* exp(spectrum) */ assert( st->mct_chan_mode != MCT_CHAN_MODE_LFE ); FOR( i = 0; i < 2; i++ ) { @@ -411,7 +403,7 @@ void core_signal_analysis_high_bitrate_fx( FOR( i = 0; i < L_subframe; i++ ) { - tmp_buf[i] = Mpy_32_16_1( tmp_buf[i], tmp1 ); + tmp_buf[i] = Mpy_32_16_1( tmp_buf[i], tmp1 ); /* Q - 4 */ move32(); } Q = sub( Q, tmp2 ); @@ -579,9 +571,9 @@ void core_signal_analysis_high_bitrate_fx( /* group sub-windows: interleave bins according to their frequencies */ FOR( i = 0; i < tcx5SizeFB; i++ ) { - interleaveBuf[2 * i] = spectrum[frameno][i]; + interleaveBuf[2 * i] = spectrum[frameno][i]; /* exp(spectrum_e) */ move32(); - interleaveBuf[2 * i + 1] = spectrum[frameno][tcx5SizeFB + i]; + interleaveBuf[2 * i + 1] = spectrum[frameno][tcx5SizeFB + i]; /* exp(spectrum_e) */ move32(); } MVR2R_WORD32( interleaveBuf, spectrum[frameno], tcx10SizeFB ); @@ -617,7 +609,7 @@ void core_signal_analysis_high_bitrate_fx( } /* Copy memory */ - MVR2R_WORD16( lsp_new, st->lspold_enc_fx, M ); + MVR2R_WORD16( lsp_new, st->lspold_enc_fx, M ); /* Q15 */ } } @@ -632,20 +624,20 @@ void core_signal_analysis_high_bitrate_fx( void core_signal_analysis_high_bitrate_ivas_fx( const Word16 *new_samples, /*i: Q0 */ - const Word16 T_op[3], /* i : open-loop pitch values for quantiz. */ + const Word16 T_op[3], /* i : open-loop pitch values for quantiz. Q0*/ Word16 lsp_new[], /* Q15 */ Word16 lsp_mid[], /* Q15 */ Encoder_State *st, - Word16 pTnsSize[], - Word16 pTnsBits[], - Word16 param_core[], - Word16 *ltpBits, - Word32 *windowed_samples, - const Word16 L_frame, - const Word16 L_frameTCX, - const Word16 last_element_mode, - const Word16 vad_hover_flag, /* i : VAD hangover flag */ - Word32 **spectrum, + Word16 pTnsSize[], /* Q0 */ + Word16 pTnsBits[], /* Q0 */ + Word16 param_core[], /* Q0 */ + Word16 *ltpBits, /* Q0 */ + Word32 *windowed_samples, /* q_win */ + const Word16 L_frame, /* Q0 */ + const Word16 L_frameTCX, /* Q0 */ + const Word16 last_element_mode, /* Q0 */ + const Word16 vad_hover_flag, /* i : VAD hangover flag Q0*/ + Word32 **spectrum, /* exp(spectrum_e) */ Word16 *spectrum_e, Word16 *Q_new, Word16 *q_win ) @@ -657,13 +649,14 @@ void core_signal_analysis_high_bitrate_ivas_fx( Word16 i, frameno; Word16 L_subframe; Word16 left_overlap = -1, right_overlap = -1, folding_offset; - Word32 buf[N_MAX + L_MDCT_OVLP_MAX]; /* Buffer for TCX20/TCX10 windowing */ - Word32 buf_powerSPec[N_MAX + L_MDCT_OVLP_MAX]; /* Buffer for TCX20/TCX10 windowing */ - Word16 mdstWin[N_MAX + L_MDCT_OVLP_MAX]; /* Buffer for MDST windowing */ + Word32 buf[N_MAX + L_MDCT_OVLP_MAX]; /* Buffer for TCX20/TCX10 windowing */ + Word32 buf_powerSPec[N_MAX + L_MDCT_OVLP_MAX]; /* Buffer for TCX20/TCX10 windowing */ + Word16 buf_powerSPec_exp[N_MAX + L_MDCT_OVLP_MAX]; /* Buffer for TCX20/TCX10 windowing */ + Word16 mdstWin[N_MAX + L_MDCT_OVLP_MAX]; /* Buffer for MDST windowing */ Word16 *pMdstWin; Word16 lpc_left_overlap_mode, lpc_right_overlap_mode; Word32 *powerSpec = buf_powerSPec; - Word16 powerSpec_e; + Word16 *powerSpec_e = buf_powerSPec_exp; Word16 *tcx20Win = (Word16 *) buf; Word32 *tcx20Win_32 = buf; Word32 interleaveBuf[N_TCX10_MAX]; @@ -692,16 +685,16 @@ void core_signal_analysis_high_bitrate_ivas_fx( move16(); move16(); (void) vad_hover_flag; - powerSpec_e = 0; - move16(); - + Word16 Q_win_temp[2]; Word16 *speech_ltp_fx = NULL; Word16 *wspeech_fx = NULL; Word16 *speech_fx = NULL; Word16 q_out_wtda = 0; move16(); - Word16 win_len = 0; + Word16 win_len[2]; move16(); + set32_fx( buf_powerSPec, 0, N_MAX + L_MDCT_OVLP_MAX ); + set16_fx( buf_powerSPec_exp, 0, N_MAX + L_MDCT_OVLP_MAX ); if ( NE_16( last_element_mode, st->element_mode ) ) { @@ -717,15 +710,16 @@ void core_signal_analysis_high_bitrate_ivas_fx( test(); IF( st->tcxonly && NE_16( st->element_mode, IVAS_CPE_MDCT ) ) { - Copy( new_samples, st->new_speech_enc, L_frame ); - Scale_sig( st->new_speech_enc, L_frame, 1 ); // Q1 + Copy_Scale_sig( new_samples, st->new_speech_enc, L_frame, sub( 15, st->exp_buf_speech_enc ) ); + /* st->new_speech_enc copied from new_samples in Q st->exp_buf_speech_enc + This is considering new_samples is in q 0 in current code*/ } /*--------------------------------------------------------------* * TCX-LTP *---------------------------------------------------------------*/ - if ( st->element_mode == IVAS_CPE_DFT ) + if ( EQ_16( st->element_mode, IVAS_CPE_DFT ) ) { if ( st->element_mode > EVS_MONO ) { @@ -736,9 +730,9 @@ void core_signal_analysis_high_bitrate_ivas_fx( wspeech_fx = st->buf_wspeech_enc + st->L_frame + idiv1616( st->L_frame, st->nb_subfr ); } } - else if ( st->element_mode != IVAS_CPE_MDCT ) + else if ( NE_16( st->element_mode, IVAS_CPE_MDCT ) ) { - speech_fx = st->buf_speech_enc + +st->encoderPastSamples_enc; + speech_fx = st->buf_speech_enc + st->encoderPastSamples_enc; speech_ltp_fx = st->hTcxEnc->buf_speech_ltp + st->encoderPastSamples_enc; } @@ -746,7 +740,7 @@ void core_signal_analysis_high_bitrate_ivas_fx( { tcx_ltp_encode_ivas_fx( st, hTcxEnc->tcxMode, L_frame, wspeech_fx, NULL, wspeech_fx, T_op, ¶m_core[1 + NOISE_FILL_RANGES], ltpBits, NULL, disable_ltp, st->element_mode ); } - ELSE IF( st->element_mode != IVAS_CPE_MDCT ) + ELSE IF( NE_16( st->element_mode, IVAS_CPE_MDCT ) ) { tcx_ltp_encode_ivas_fx( st, hTcxEnc->tcxMode, L_frame, speech_fx + st->encoderLookahead_enc, speech_ltp_fx + st->encoderLookahead_enc, speech_fx + st->encoderLookahead_enc, T_op, ¶m_core[1 + NOISE_FILL_RANGES], ltpBits, NULL, disable_ltp, st->element_mode ); } @@ -754,10 +748,9 @@ void core_signal_analysis_high_bitrate_ivas_fx( test(); IF( st->tcxonly && NE_16( st->element_mode, IVAS_CPE_MDCT ) ) { - Copy( st->speech_enc + st->encoderLookahead_enc, st->new_speech_enc_pe, L_frame ); + Copy( st->speech_enc + st->encoderLookahead_enc, st->new_speech_enc_pe, L_frame ); // Assuming both exp_buf_speech_enc_pe and exp_buf_speech_enc are same - Preemph_scaled( st->new_speech_enc_pe, Q_new, &( st->mem_preemph_enc ), - st->Q_max_enc, st->preemph_fac, 1, 0, 2, L_frame, st->coder_type_raw, 1 ); + PREEMPH_FX( st->new_speech_enc_pe, st->preemph_fac, L_frame, &( st->mem_preemph_enc ) ); // using this to keep values alligned in Q-1 } /* Rescale Memory */ @@ -769,20 +762,22 @@ void core_signal_analysis_high_bitrate_ivas_fx( move16(); IF( Q_exp != 0 ) { - Scale_sig( st->buf_speech_enc_pe, st->encoderPastSamples_enc + st->encoderLookahead_enc, Q_exp ); // *Q_new - Scale_sig( &( st->mem_wsp_enc ), 1, Q_exp ); // *Q_new + Scale_sig( st->buf_speech_enc_pe, st->encoderPastSamples_enc + st->encoderLookahead_enc, sub( Q_exp, sub( Q15, st->exp_buf_speech_enc_pe ) ) ); // *Q_new + st->exp_buf_speech_enc_pe = sub( Q15, Q_exp ); + move16(); + Scale_sig( &( st->mem_wsp_enc ), 1, Q_exp ); // *Q_new } IF( EQ_16( hTcxEnc->tcxMode, TCX_10 ) ) { - Copy( ¶m_core[1 + NOISE_FILL_RANGES], ¶m_core[NPRM_DIV + 1 + NOISE_FILL_RANGES], LTPSIZE ); + Copy( ¶m_core[1 + NOISE_FILL_RANGES], ¶m_core[NPRM_DIV + 1 + NOISE_FILL_RANGES], LTPSIZE ); // Q0 } IF( NE_16( st->element_mode, IVAS_CPE_MDCT ) ) { - lsp[0] = lsp_new; + lsp[0] = lsp_new; // Q15 move16(); - lsp[1] = lsp_mid; + lsp[1] = lsp_mid; // Q15 move16(); } @@ -792,19 +787,19 @@ void core_signal_analysis_high_bitrate_ivas_fx( IF( NE_16( st->element_mode, IVAS_CPE_MDCT ) ) { - alw_pitch_lag_12k8[0] = st->pitch[0]; + alw_pitch_lag_12k8[0] = st->pitch[0]; // Q0 move16(); - alw_pitch_lag_12k8[1] = st->pitch[1]; + alw_pitch_lag_12k8[1] = st->pitch[1]; // Q0 move16(); - alw_voicing[0] = st->voicing_fx[0]; + alw_voicing[0] = st->voicing_fx[0]; // Q15 move16(); - alw_voicing[1] = st->voicing_fx[1]; + alw_voicing[1] = st->voicing_fx[1]; // Q15 move16(); - alw_pitch_lag_12k8_wc = s_min( alw_pitch_lag_12k8[0], alw_pitch_lag_12k8[1] ); - alw_voicing_wc = s_max( alw_voicing[0], alw_voicing[1] ); + alw_pitch_lag_12k8_wc = s_min( alw_pitch_lag_12k8[0], alw_pitch_lag_12k8[1] ); // Q0 + alw_voicing_wc = s_max( alw_voicing[0], alw_voicing[1] ); // Q15 } - overlap_mode[0] = last_overlap; /* Overlap between the last and the current frame */ + overlap_mode[0] = last_overlap; /* Overlap between the last and the current frame Q0*/ move16(); IF( EQ_16( hTcxEnc->tcxMode, TCX_20 ) ) @@ -815,14 +810,14 @@ void core_signal_analysis_high_bitrate_ivas_fx( move16(); transform_type[1] = TCX_20; move16(); - overlap_mode[1] = curr_overlap; /* Overlap between the current and the next frame */ + overlap_mode[1] = curr_overlap; /* Overlap between the current and the next frame Q0*/ move16(); IF( NE_16( st->element_mode, IVAS_CPE_MDCT ) ) { - alw_pitch_lag_12k8[0] = alw_pitch_lag_12k8_wc; + alw_pitch_lag_12k8[0] = alw_pitch_lag_12k8_wc; // Q0 move16(); - alw_voicing[0] = alw_voicing_wc; + alw_voicing[0] = alw_voicing_wc; // Q15 move16(); } } @@ -875,7 +870,7 @@ void core_signal_analysis_high_bitrate_ivas_fx( move16(); } } - overlap_mode[2] = curr_overlap; /* Overlap between the current and the next frame */ + overlap_mode[2] = curr_overlap; /* Overlap between the current and the next frame Q0*/ move16(); } @@ -891,16 +886,16 @@ void core_signal_analysis_high_bitrate_ivas_fx( FOR( frameno = 0; frameno < nSubframes; frameno++ ) { - L_subframe = L_frameTCX; + L_subframe = L_frameTCX; // Q0 move16(); IF( NE_16( nSubframes, 1 ) ) { L_subframe = shr( L_frameTCX, 1 ); } - lpc_left_overlap_mode = overlap_mode[frameno]; + lpc_left_overlap_mode = overlap_mode[frameno]; // Q0 move16(); - lpc_right_overlap_mode = overlap_mode[frameno + 1]; + lpc_right_overlap_mode = overlap_mode[frameno + 1]; // Q0 move16(); if ( EQ_16( lpc_left_overlap_mode, ALDO_WINDOW ) ) { @@ -921,13 +916,33 @@ void core_signal_analysis_high_bitrate_ivas_fx( IF( windowed_samples != NULL ) /* store overlap data for later */ { assert( frameno == 0 ); - windowed_samples[0] = L_deposit_l( overlap_mode[frameno] ); - windowed_samples[1] = L_deposit_l( overlap_mode[frameno + 1] ); + windowed_samples[0] = L_deposit_l( overlap_mode[frameno] ); // Q0 + windowed_samples[1] = L_deposit_l( overlap_mode[frameno + 1] ); // Q0 + *q_win = 0; + move16(); } IF( NE_16( st->element_mode, IVAS_CPE_MDCT ) ) { + Word16 left_overlap_mode, right_overlap_mode; + if ( EQ_16( overlap_mode[frameno], ALDO_WINDOW ) ) + { + left_overlap_mode = FULL_OVERLAP; + } + else + { + left_overlap_mode = overlap_mode[frameno]; // Q0 + } + + if ( EQ_16( overlap_mode[frameno + 1], ALDO_WINDOW ) ) + { + right_overlap_mode = FULL_OVERLAP; + } + else + { + right_overlap_mode = overlap_mode[frameno + 1]; // Q0 + } /* Windowing of the 2xTCX5 subframes or 1xTCX10 or 1xTCX20 */ - WindowSignal( st->hTcxCfg, st->hTcxCfg->tcx_offsetFB, overlap_mode[frameno] == ALDO_WINDOW ? FULL_OVERLAP : overlap_mode[frameno], overlap_mode[frameno + 1] == ALDO_WINDOW ? FULL_OVERLAP : overlap_mode[frameno + 1], &left_overlap, &right_overlap, &hTcxEnc->speech_TCX[frameno * tcx10SizeFB], &L_subframe, mdstWin, 1, 1 ); + WindowSignal( st->hTcxCfg, st->hTcxCfg->tcx_offsetFB, left_overlap_mode, right_overlap_mode, &left_overlap, &right_overlap, &hTcxEnc->speech_TCX[frameno * tcx10SizeFB], &L_subframe, mdstWin, 1, 1 ); } } ELSE @@ -940,15 +955,26 @@ void core_signal_analysis_high_bitrate_ivas_fx( IF( windowed_samples != NULL ) /* save windowed speech_TCX samples */ { assert( L_subframe + ( left_overlap + right_overlap ) / 2 < 2 * L_FRAME_MAX / nSubframes - L_FRAME_MAX / 8 ); - win_len = add( L_subframe, shr( add( left_overlap, right_overlap ), 1 ) ); - windowed_samples[frameno * L_FRAME_MAX + 0] = L_deposit_l( overlap_mode[frameno] ); - windowed_samples[frameno * L_FRAME_MAX + 1] = L_deposit_l( overlap_mode[frameno + 1] ); - Copy_Scale_sig_16_32( tcx20Win, windowed_samples + frameno * L_FRAME_MAX + 2, L_subframe + ( left_overlap + right_overlap ) / 2, 0 ); - *q_win = s_min( *q_win, sub( L_norm_arr( windowed_samples + frameno * L_FRAME_MAX + 2, L_subframe + ( left_overlap + right_overlap ) / 2 ), 1 ) ); + win_len[frameno] = add( L_subframe, shr( add( left_overlap, right_overlap ), 1 ) ); + move16(); + windowed_samples[frameno * L_FRAME_MAX + 0] = L_deposit_l( overlap_mode[frameno] ); // Q0 + move32(); + windowed_samples[frameno * L_FRAME_MAX + 1] = L_deposit_l( overlap_mode[frameno + 1] ); // Q0 + move32(); + Copy_Scale_sig_16_32_DEPREC( tcx20Win, windowed_samples + add( imult1616( frameno, L_FRAME_MAX ), 2 ), add( L_subframe, shr( add( left_overlap, right_overlap ), 1 ) ), 0 ); + *q_win = s_min( *q_win, sub( L_norm_arr( windowed_samples + add( imult1616( frameno, L_FRAME_MAX ), 2 ), add( L_subframe, shr( add( left_overlap, right_overlap ), 1 ) ) ), 1 ) ); move16(); + Q_win_temp[frameno] = *q_win; + move16(); + #ifdef MSAN_FIX - Scale_sig32( windowed_samples + frameno * L_FRAME_MAX + 2, win_len, *q_win ); + Scale_sig32( windowed_samples + frameno * L_FRAME_MAX + 2, win_len[frameno], *q_win ); // q_win + #endif + IF( EQ_16( frameno, 1 ) ) + { + Scale_sig32( windowed_samples + 2, win_len[0], sub( *q_win, Q_win_temp[0] ) ); // q_win + } } } @@ -959,11 +985,7 @@ void core_signal_analysis_high_bitrate_ivas_fx( /* Outter left folding */ FOR( i = 0; i < folding_offset; i++ ) { -#ifdef BASOP_NOGLOB - tcx20Win[folding_offset + i] = sub_sat( tcx20Win[folding_offset + i], tcx20Win[folding_offset - 1 - i] ); -#else - tcx20Win[folding_offset + i] = sub( tcx20Win[folding_offset + i], tcx20Win[folding_offset - 1 - i] ); -#endif + tcx20Win[folding_offset + i] = sub_sat( tcx20Win[folding_offset + i], tcx20Win[folding_offset - 1 - i] ); // Q0 move16(); } @@ -979,11 +1001,7 @@ void core_signal_analysis_high_bitrate_ivas_fx( L_tmp = L_mult( hTcxEnc->speech_TCX[-1 - i], st->hTcxCfg->tcx_aldo_window_1_FB[left_overlap / 2 + minWindowLen - i] ); // (Q0, Q15) -> Q16 L_tmp = Mpy_32_16_1( L_tmp, st->hTcxCfg->tcx_mdct_window_minimumFB[minWindowLen - i].v.im ); // (Q16, Q15) -> Q16 L_tmp = L_shl( L_tmp, sub( 0, Q16 ) ); // Q0 -#ifdef BASOP_NOGLOB - tcx20Win[left_overlap + i] = sub_sat( tcx20Win[left_overlap + i], extract_l( L_tmp ) ); // Q0 -#else - tcx20Win[left_overlap + i] = sub( tcx20Win[left_overlap + i], extract_l( L_tmp ) ); // Q0 -#endif + tcx20Win[left_overlap + i] = sub_sat( tcx20Win[left_overlap + i], extract_l( L_tmp ) ); // Q0 move32(); } FOR( i = tmp - 1; i >= 0; i-- ) /* outer left folding of shortened long ALDO slope */ @@ -991,11 +1009,7 @@ void core_signal_analysis_high_bitrate_ivas_fx( L_tmp = L_mult( hTcxEnc->speech_TCX[-1 - i], st->hTcxCfg->tcx_aldo_window_1_FB[left_overlap / 2 + minWindowLen - i] ); // (Q0, Q15) -> Q16 L_tmp = Mpy_32_16_1( L_tmp, st->hTcxCfg->tcx_mdct_window_minimumFB[i].v.re ); // (Q16, Q15) -> Q16 L_tmp = L_shl( L_tmp, sub( 0, Q16 ) ); // Q0 -#ifdef BASOP_NOGLOB - tcx20Win[left_overlap + i] = sub_sat( tcx20Win[left_overlap + i], extract_l( L_tmp ) ); // Q0 -#else - tcx20Win[left_overlap + i] = sub( tcx20Win[left_overlap + i], extract_l( L_tmp ) ); // Q0 -#endif + tcx20Win[left_overlap + i] = sub_sat( tcx20Win[left_overlap + i], extract_l( L_tmp ) ); // Q0 move32(); } } @@ -1004,11 +1018,7 @@ void core_signal_analysis_high_bitrate_ivas_fx( tmp = shr( right_overlap, 1 ); FOR( i = 0; i < tmp; i++ ) { -#ifdef BASOP_NOGLOB - tcx20Win[L_subframe + folding_offset - 1 - i] = add_sat( tcx20Win[L_subframe + folding_offset - 1 - i], tcx20Win[L_subframe + folding_offset + i] ); -#else - tcx20Win[L_subframe + folding_offset - 1 - i] = add( tcx20Win[L_subframe + folding_offset - 1 - i], tcx20Win[L_subframe + folding_offset + i] ); -#endif + tcx20Win[L_subframe + folding_offset - 1 - i] = add_sat( tcx20Win[L_subframe + folding_offset - 1 - i], tcx20Win[L_subframe + folding_offset + i] ); // Q0 move16(); } @@ -1072,7 +1082,7 @@ void core_signal_analysis_high_bitrate_ivas_fx( Word16 Q; Q = q_out_wtda; - edct_fx( tcx20Win_32, hTcxEnc->spectrum_fx[frameno], L_subframe, &Q ); + edct_ivas_fx( tcx20Win_32, hTcxEnc->spectrum_fx[frameno], L_subframe, &Q ); hTcxEnc->spectrum_e[frameno] = sub( 31, Q ); move16(); @@ -1100,11 +1110,7 @@ void core_signal_analysis_high_bitrate_ivas_fx( L_tmp = L_mult( hTcxEnc->speech_TCX[-1 - i], st->hTcxCfg->tcx_aldo_window_1_FB[left_overlap / 2 + minWindowLen - i] ); // (Q0, Q15) -> Q16 L_tmp = Mpy_32_16_1( L_tmp, st->hTcxCfg->tcx_mdct_window_minimumFB[minWindowLen - i].v.im ); // (Q16, Q15) -> Q16 L_tmp = L_shl( L_tmp, sub( 0, Q16 ) ); // Q0 -#ifdef BASOP_NOGLOB - tcx20Win[left_overlap + i] = sub_sat( tcx20Win[left_overlap + i], extract_l( L_tmp ) ); // Q0 -#else - tcx20Win[left_overlap + i] = sub( tcx20Win[left_overlap + i], extract_l( L_tmp ) ); // Q0 -#endif + tcx20Win[left_overlap + i] = sub_sat( tcx20Win[left_overlap + i], extract_l( L_tmp ) ); // Q0 move32(); } FOR( i = tmp - 1; i >= 0; i-- ) /* outer left folding of shortened long ALDO slope */ @@ -1112,11 +1118,7 @@ void core_signal_analysis_high_bitrate_ivas_fx( L_tmp = L_mult( hTcxEnc->speech_TCX[-1 - i], st->hTcxCfg->tcx_aldo_window_1_FB[left_overlap / 2 + minWindowLen - i] ); // (Q0, Q15) -> Q16 L_tmp = Mpy_32_16_1( L_tmp, st->hTcxCfg->tcx_mdct_window_minimumFB[i].v.re ); // (Q16, Q15) -> Q16 L_tmp = L_shl( L_tmp, sub( 0, Q16 ) ); // Q0 -#ifdef BASOP_NOGLOB - tcx20Win[left_overlap + i] = sub_sat( tcx20Win[left_overlap + i], extract_l( L_tmp ) ); // Q0 -#else - tcx20Win[left_overlap + i] = sub( tcx20Win[left_overlap + i], extract_l( L_tmp ) ); // Q0 -#endif + tcx20Win[left_overlap + i] = sub_sat( tcx20Win[left_overlap + i], extract_l( L_tmp ) ); // Q0 move32(); } } @@ -1154,27 +1156,39 @@ void core_signal_analysis_high_bitrate_ivas_fx( } /* Compute noise-measure flags for spectrum filling and quantization */ - AnalyzePowerSpectrum_fx( st, div_l( L_mult( L_subframe, st->L_frame ), hTcxEnc->L_frameTCX ), - L_subframe, left_overlap, right_overlap, hTcxEnc->spectrum_fx[frameno], hTcxEnc->spectrum_e[frameno], - pMdstWin, powerSpec, &powerSpec_e ); + AnalyzePowerSpectrum_ivas_fx( st, div_l( L_mult( L_subframe, st->L_frame ), hTcxEnc->L_frameTCX ), + L_subframe, left_overlap, right_overlap, hTcxEnc->spectrum_fx[frameno], hTcxEnc->spectrum_e[frameno], + pMdstWin, powerSpec, powerSpec_e ); } } } IF( EQ_16( st->element_mode, IVAS_CPE_MDCT ) ) { - L_subframe = idiv1616( L_frameTCX, nSubframes ); + Word16 q_mdstWin, scale; + L_subframe = idiv1616( L_frameTCX, nSubframes ); /* Q0 */ test(); IF( EQ_16( transform_type[frameno], TCX_20 ) && NE_16( st->hTcxCfg->tcx_last_overlap_mode, TRANSITION_OVERLAP ) ) { wtda_ext_fx( hTcxEnc->new_speech_TCX, mdstWin, overlap_mode[frameno], overlap_mode[frameno + 1], L_frameTCX, 3 ); - Scale_sig( mdstWin, L_frameTCX, 1 ); + scale = sub( norm_arr( mdstWin, L_frameTCX ), 1 ); + scale = s_min( 1, scale ); // restricting the Q to zero or less + scale_sig( mdstWin, L_frameTCX, scale ); + q_mdstWin = add( -1, scale ); + move16(); } ELSE { + Word16 sig_len; /* Windowing for the MDST */ WindowSignal( st->hTcxCfg, st->hTcxCfg->tcx_offsetFB, overlap_mode[frameno] == ALDO_WINDOW ? FULL_OVERLAP : overlap_mode[frameno], overlap_mode[frameno + 1] == ALDO_WINDOW ? FULL_OVERLAP : overlap_mode[frameno + 1], &left_overlap, &right_overlap, &hTcxEnc->speech_TCX[frameno * tcx10SizeFB], &L_subframe, mdstWin, 0, 1 ); + sig_len = add( L_subframe, shr( add( left_overlap, right_overlap ), 1 ) ); + scale = sub( norm_arr( mdstWin, sig_len ), 1 ); + scale = s_min( 0, scale ); // restricting the Q to zero or less + scale_sig( mdstWin, sig_len, scale ); + q_mdstWin = scale; + move16(); } IF( EQ_16( transform_type[frameno], TCX_5 ) ) @@ -1182,11 +1196,7 @@ void core_signal_analysis_high_bitrate_ivas_fx( /* Outer left folding */ FOR( i = 0; i < left_overlap / 2; i++ ) { -#ifdef BASOP_NOGLOB - mdstWin[left_overlap / 2 + i] = add_sat( mdstWin[left_overlap / 2 + i], mdstWin[left_overlap / 2 - 1 - i] ); -#else - mdstWin[left_overlap / 2 + i] = add( mdstWin[left_overlap / 2 + i], mdstWin[left_overlap / 2 - 1 - i] ); -#endif + mdstWin[left_overlap / 2 + i] = add( mdstWin[left_overlap / 2 + i], mdstWin[left_overlap / 2 - 1 - i] ); // q_mdstWin } test(); @@ -1199,24 +1209,16 @@ void core_signal_analysis_high_bitrate_ivas_fx( { L_tmp = L_mult( hTcxEnc->speech_TCX[-1 - i], st->hTcxCfg->tcx_aldo_window_1_FB[left_overlap / 2 + minWindowLen - i] ); // (Q0, Q15) -> Q16 L_tmp = Mpy_32_16_1( L_tmp, st->hTcxCfg->tcx_mdct_window_minimumFB[minWindowLen - i].v.im ); // (Q16, Q15) -> Q16 - L_tmp = L_shl( L_tmp, sub( 0, Q16 ) ); // Q0 -#ifdef BASOP_NOGLOB - mdstWin[left_overlap + i] = add_sat( mdstWin[left_overlap + i], extract_l( L_tmp ) ); // Q0 -#else - mdstWin[left_overlap + i] = add( mdstWin[left_overlap + i], extract_l( L_tmp ) ); // Q0 -#endif + L_tmp = L_shl( L_tmp, sub( q_mdstWin, Q16 ) ); // q_mdstWin + mdstWin[left_overlap + i] = add( mdstWin[left_overlap + i], extract_l( L_tmp ) ); // q_mdstWin move32(); } FOR( i = tmp - 1; i >= 0; i-- ) /* outer left folding of shortened long ALDO slope */ { L_tmp = L_mult( hTcxEnc->speech_TCX[-1 - i], st->hTcxCfg->tcx_aldo_window_1_FB[left_overlap / 2 + minWindowLen - i] ); // (Q0, Q15) -> Q16 L_tmp = Mpy_32_16_1( L_tmp, st->hTcxCfg->tcx_mdct_window_minimumFB[i].v.re ); // (Q16, Q15) -> Q16 - L_tmp = L_shl( L_tmp, sub( 0, Q16 ) ); // Q0 -#ifdef BASOP_NOGLOB - mdstWin[left_overlap + i] = add_sat( mdstWin[left_overlap + i], extract_l( L_tmp ) ); // Q0 -#else - mdstWin[left_overlap + i] = add( mdstWin[left_overlap + i], extract_l( L_tmp ) ); // Q0 -#endif + L_tmp = L_shl( L_tmp, sub( q_mdstWin, Q16 ) ); // q_mdstWin + mdstWin[left_overlap + i] = add( mdstWin[left_overlap + i], extract_l( L_tmp ) ); // q_mdstWin move32(); } } @@ -1224,11 +1226,7 @@ void core_signal_analysis_high_bitrate_ivas_fx( /* Outer right folding */ FOR( i = 0; i < right_overlap / 2; i++ ) { -#ifdef BASOP_NOGLOB - mdstWin[L_subframe + left_overlap / 2 - 1 - i] = sub_sat( mdstWin[L_subframe + left_overlap / 2 - 1 - i], mdstWin[L_subframe + left_overlap / 2 + i] ); -#else - mdstWin[L_subframe + left_overlap / 2 - 1 - i] = sub( mdstWin[L_subframe + left_overlap / 2 - 1 - i], mdstWin[L_subframe + left_overlap / 2 + i] ); -#endif + mdstWin[L_subframe + left_overlap / 2 - 1 - i] = sub( mdstWin[L_subframe + left_overlap / 2 - 1 - i], mdstWin[L_subframe + left_overlap / 2 + i] ); // q_mdstWin move16(); } @@ -1243,7 +1241,7 @@ void core_signal_analysis_high_bitrate_ivas_fx( assert( st->mct_chan_mode != MCT_CHAN_MODE_LFE ); WindowSignal( st->hTcxCfg, folding_offset, i == 0 ? RECTANGULAR_OVERLAP : MIN_OVERLAP, i == 1 ? RECTANGULAR_OVERLAP : MIN_OVERLAP, &left_overlap, &right_overlap, mdstWin + i * tcx5SizeFB, &L_subframe, tcx5Win, 0, 1 ); - spectrum_e[frameno] = 16; + spectrum_e[frameno] = sub( 16, q_mdstWin ); move16(); TCX_MDST( tcx5Win, spectrum[frameno] + i * tcx5SizeFB, &spectrum_e[frameno], left_overlap, L_subframe - ( left_overlap + right_overlap ) / 2, right_overlap, st->element_mode ); /* high-band gain control in case of BWS */ @@ -1264,14 +1262,14 @@ void core_signal_analysis_high_bitrate_ivas_fx( } ELSE /* transform_type[frameno] != TCX_5 */ { - spectrum_e[frameno] = 16; + spectrum_e[frameno] = sub( 16, q_mdstWin ); test(); IF( EQ_16( transform_type[frameno], TCX_20 ) && NE_16( st->hTcxCfg->tcx_last_overlap_mode, TRANSITION_OVERLAP ) ) { Word16 Q; Copy_Scale_sig_16_32_no_sat( mdstWin, L_tmpbuf, N_MAX + L_MDCT_OVLP_MAX, 16 ); - Q = 16; + Q = add( q_mdstWin, 16 ); move16(); edst_fx( L_tmpbuf, spectrum[frameno], L_subframe, &Q ); spectrum_e[frameno] = 31 - Q; @@ -1298,24 +1296,16 @@ void core_signal_analysis_high_bitrate_ivas_fx( { L_tmp = L_mult( hTcxEnc->speech_TCX[-1 - i], st->hTcxCfg->tcx_aldo_window_1_FB[left_overlap / 2 + minWindowLen - i] ); // (Q0, Q15) -> Q16 L_tmp = Mpy_32_16_1( L_tmp, st->hTcxCfg->tcx_mdct_window_minimumFB[minWindowLen - i].v.im ); // (Q16, Q15) -> Q16 - L_tmp = L_shl( L_tmp, sub( 0, Q16 ) ); // Q0 -#ifdef BASOP_NOGLOB - mdstWin[left_overlap + i] = add_sat( mdstWin[left_overlap + i], extract_l( L_tmp ) ); // Q0 -#else - mdstWin[left_overlap + i] = add( mdstWin[left_overlap + i], extract_l( L_tmp ) ); // Q0 -#endif + L_tmp = L_shl( L_tmp, sub( q_mdstWin, Q16 ) ); // q_mdstWin + mdstWin[left_overlap + i] = add( mdstWin[left_overlap + i], extract_l( L_tmp ) ); // q_mdstWin move32(); } FOR( i = tmp - 1; i >= 0; i-- ) /* outer left folding of shortened long ALDO slope */ { L_tmp = L_mult( hTcxEnc->speech_TCX[-1 - i], st->hTcxCfg->tcx_aldo_window_1_FB[left_overlap / 2 + minWindowLen - i] ); // (Q0, Q15) -> Q16 L_tmp = Mpy_32_16_1( L_tmp, st->hTcxCfg->tcx_mdct_window_minimumFB[i].v.re ); // (Q16, Q15) -> Q16 - L_tmp = L_shl( L_tmp, sub( 0, Q16 ) ); // Q0 -#ifdef BASOP_NOGLOB - mdstWin[left_overlap + i] = add_sat( mdstWin[left_overlap + i], extract_l( L_tmp ) ); // Q0 -#else - mdstWin[left_overlap + i] = add( mdstWin[left_overlap + i], extract_l( L_tmp ) ); // Q0 -#endif + L_tmp = L_shl( L_tmp, sub( q_mdstWin, Q16 ) ); // q_mdstWin + mdstWin[left_overlap + i] = add( mdstWin[left_overlap + i], extract_l( L_tmp ) ); // q_mdstWin move32(); } } @@ -1360,9 +1350,9 @@ void core_signal_analysis_high_bitrate_ivas_fx( /* group sub-windows: interleave bins according to their frequencies */ FOR( i = 0; i < tcx5SizeFB; i++ ) { - interleaveBuf[2 * i] = hTcxEnc->spectrum_fx[frameno][i]; + interleaveBuf[2 * i] = hTcxEnc->spectrum_fx[frameno][i]; /* hTcxEnc->spectrum_e */ move32(); - interleaveBuf[2 * i + 1] = hTcxEnc->spectrum_fx[frameno][tcx5SizeFB + i]; + interleaveBuf[2 * i + 1] = hTcxEnc->spectrum_fx[frameno][tcx5SizeFB + i]; /* hTcxEnc->spectrum_e */ move32(); } MVR2R_WORD32( interleaveBuf, hTcxEnc->spectrum_fx[frameno], tcx10SizeFB ); @@ -1394,10 +1384,11 @@ void core_signal_analysis_high_bitrate_ivas_fx( IF( st->igf ) { Word16 q_spectrum = sub( Q31, hTcxEnc->spectrum_e[frameno] ); - Word16 q_powerSpec = sub( Q31, powerSpec_e ); - st->hIGFEnc->spec_be_igf_e = hTcxEnc->spectrum_e[frameno]; - move16(); - ProcessIGF_ivas_fx( st, hTcxEnc->spectrum_fx[frameno], hTcxEnc->spectrum_fx[frameno], &q_spectrum, powerSpec, &q_powerSpec, transform_type[frameno] == TCX_20, frameno, 0, vad_hover_flag ); +#ifndef MSAN_FIX + ProcessIGF_ivas_fx( st, hTcxEnc->spectrum_fx[frameno], hTcxEnc->spectrum_fx[frameno], &q_spectrum, powerSpec, powerSpec_e, transform_type[frameno] == TCX_20, frameno, 0, vad_hover_flag ); +#else + ProcessIGF_ivas_fx( st, N_MAX + L_MDCT_OVLP_MAX, hTcxEnc->spectrum_fx[frameno], hTcxEnc->spectrum_fx[frameno], &q_spectrum, powerSpec, powerSpec_e, transform_type[frameno] == TCX_20, frameno, 0, vad_hover_flag ); +#endif } } } diff --git a/lib_enc/fd_cng_enc.c b/lib_enc/fd_cng_enc.c deleted file mode 100644 index 47408845100650353abdfd4e1c633078c2dfd84a..0000000000000000000000000000000000000000 --- a/lib_enc/fd_cng_enc.c +++ /dev/null @@ -1,1154 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include -#include "options.h" -#include -#include "rom_enc.h" -#include "rom_com.h" -#include "prot.h" -#include "prot_fx.h" -#include "prot_fx_enc.h" -#include "ivas_prot.h" -#include "ivas_prot_fx.h" -#include "stat_enc.h" -#include "wmc_auto.h" - -#include "prot_fx.h" - -/*-------------------------------------------------------------------* - * initFdCngEnc() - * - * Initialize FD_CNG - *-------------------------------------------------------------------*/ - -/*-------------------------------------------------------------------* - * deleteFdCngEnc() - * - * Delete the instance of type FD_CNG - *-------------------------------------------------------------------*/ - -/*-------------------------------------------------------------------* - * resetFdCngEnc() - * - * Reset the instance of type FD_CNG - *-------------------------------------------------------------------*/ -/*-------------------------------------------------------------------* - * perform_noise_estimation_enc() - * - * Perform noise estimation - *-------------------------------------------------------------------*/ -void perform_noise_estimation_enc_ivas_fx( - Word32 *band_energies, /* i: energy in critical bands without minimum noise floor MODE2_E_MIN */ - Word16 band_energies_exp, - Word32 *enerBuffer, - Word16 enerBuffer_exp, - HANDLE_FD_CNG_ENC hFdCngEnc, /* i/o: CNG structure containing all buffers and variables */ - const Word32 input_Fs, /* i : input sampling rate */ - CPE_ENC_HANDLE hCPE /* i : CPE encoder structure */ -) -{ - Word16 i, j, s, s1, s2; - Word16 numBands; - Word16 numCoreBands = hFdCngEnc->hFdCngCom->numCoreBands; - move16(); - Word16 regularStopBand = hFdCngEnc->hFdCngCom->regularStopBand; - move16(); - Word16 numSlots = hFdCngEnc->hFdCngCom->numSlots; - move16(); - assert( numSlots == 16 ); - - Word32 numSlots_inv_fx = 134217728; - move32(); - Word32 *periodog = hFdCngEnc->hFdCngCom->periodog; - Word32 *ptr_per_fx = periodog; - Word16 npart = hFdCngEnc->hFdCngCom->npart; - move16(); - Word16 nFFTpart = hFdCngEnc->hFdCngCom->nFFTpart; - move16(); - Word16 nCLDFBpart = hFdCngEnc->hFdCngCom->nCLDFBpart; - move16(); - - Word16 *psize = hFdCngEnc->hFdCngCom->psize; - Word32 *msPeriodog_fx = hFdCngEnc->msPeriodog_fx; - Word32 *msNoiseEst_fx = hFdCngEnc->msNoiseEst_fx; - - Word16 *msLogPeriodog_fx = hFdCngEnc->msLogPeriodog_fx; - Word16 *msLogNoiseEst_fx = hFdCngEnc->msLogNoiseEst_fx; - - Word32 scaleEB_fx = 0; - move32(); - Word32 tmp; - - test(); - IF( hCPE != NULL && hCPE->hStereoDft != NULL ) - { - // band_res_dft = ( (float) input_Fs ) / hCPE->hStereoDft->NFFT; - // chan_width_f = 24000.f / CLDFB_NO_CHANNELS_MAX; - // chan_width_bins = chan_width_f / band_res_dft; - - ///* Scaling of Energy buffer to get energy per sample, same scaling as for band_energies, 3 is to compensate for the 1/3 scaling in calculate_energy_buffer */ - // scaleEB = 3 * 4.0f / ( hCPE->hStereoDft->NFFT * hCPE->hStereoDft->NFFT ); - - ///* Scale with number of bins in one band */ - // scaleEB = scaleEB / chan_width_bins; - - SWITCH( input_Fs ) - { - case 8000: - scaleEB_fx = 62912; - move32(); - BREAK; - case 16000: - scaleEB_fx = 15728; - move32(); - BREAK; - case 32000: - scaleEB_fx = 3928; - move32(); - BREAK; - case 48000: - scaleEB_fx = 1744; - move32(); - BREAK; - default: - assert( 0 && "invalid sample rate" ); - } - } - ELSE - { - scaleEB_fx = Mpy_32_16_1( numSlots_inv_fx, hFdCngEnc->hFdCngCom->scalingFactor ); - scaleEB_fx = L_shl( scaleEB_fx, 4 ); - } - - /* preemphasis compensation and grouping of per bin energies into msPeriodog */ - FOR( i = 0; i < nFFTpart; i++ ) - { - tmp = L_add( L_shr( band_energies[i], 1 ), L_shr( band_energies[i + NB_BANDS], 1 ) ); - msPeriodog_fx[i] = Mpy_32_16_1( tmp, preemphCompensation_fx[i] ); - move32(); - } - - /* exponent for fft part of msPeriodog */ - hFdCngEnc->msPeriodog_fx_exp_fft = add( band_energies_exp, PREEMPH_COMPENSATION_EXP ); - move16(); - - /* Adjust to the desired time resolution by averaging the periodograms over the time slots */ - FOR( j = numCoreBands; j < regularStopBand; j++ ) - { - *ptr_per_fx = Mpy_32_32( enerBuffer[j], scaleEB_fx ); - move32(); - - ptr_per_fx++; - move16(); - } - - /* exponent for cldfb part of msPeriodog */ - hFdCngEnc->hFdCngCom->exp_cldfb_periodog = add( sub( enerBuffer_exp, 4 ), CLDFBscalingFactor_EXP ); - move16(); - - numBands = sub( regularStopBand, numCoreBands ); - - IF( numBands > 0 ) - { - ///* Adjust CLDFB filterbank to the desired frequency resolution by averaging over spectral partitions for SID transmission */ - bandcombinepow( - periodog, - hFdCngEnc->hFdCngCom->exp_cldfb_periodog, - numBands, - hFdCngEnc->hFdCngCom->CLDFBpart, - nCLDFBpart, - hFdCngEnc->hFdCngCom->CLDFBpsize_inv, - &msPeriodog_fx[nFFTpart], - &hFdCngEnc->msPeriodog_fx_exp_cldfb ); - - ///* find common exponent for fft part and cldfb part of msperiodog */ - s1 = getScaleFactor32( msPeriodog_fx, nFFTpart ); - s2 = getScaleFactor32( &msPeriodog_fx[nFFTpart], nCLDFBpart ); - - s = s_max( sub( hFdCngEnc->msPeriodog_fx_exp_fft, s1 ), sub( hFdCngEnc->msPeriodog_fx_exp_cldfb, s2 ) ); - s1 = sub( s, hFdCngEnc->msPeriodog_fx_exp_fft ); - s2 = sub( s, hFdCngEnc->msPeriodog_fx_exp_cldfb ); - - hFdCngEnc->msPeriodog_fx_exp_fft = s; - move16(); - hFdCngEnc->msPeriodog_fx_exp_cldfb = s; - move16(); - - FOR( i = 0; i < nFFTpart; i++ ) - { - msPeriodog_fx[i] = L_shr( msPeriodog_fx[i], s1 ); - move32(); - } - - FOR( i = 0; i < nCLDFBpart; i++ ) - { - msPeriodog_fx[nFFTpart + i] = L_shr( msPeriodog_fx[nFFTpart + i], s_min( 31, s2 ) ); - move32(); - } - } - /* exponent for entire msPeriodog vector */ - hFdCngEnc->msPeriodog_fx_exp = hFdCngEnc->msPeriodog_fx_exp_fft; - move16(); - - /* Compress MS inputs */ - // compress_range_flt( msPeriodog, msLogPeriodog, npart ); - compress_range( msPeriodog_fx, hFdCngEnc->msPeriodog_fx_exp, msLogPeriodog_fx, npart ); - - - /* Call the minimum statistics routine for noise estimation */ - - minimum_statistics_fx( npart, nFFTpart, psize, msLogPeriodog_fx, hFdCngEnc->msNoiseFloor_fx, msLogNoiseEst_fx, hFdCngEnc->msAlpha_fx, hFdCngEnc->msPsd_fx, hFdCngEnc->msPsdFirstMoment_fx, - hFdCngEnc->msPsdSecondMoment_fx, hFdCngEnc->msMinBuf_fx, hFdCngEnc->msBminWin_fx, hFdCngEnc->msBminSubWin_fx, hFdCngEnc->msCurrentMin_fx, hFdCngEnc->msCurrentMinOut_fx, hFdCngEnc->msCurrentMinSubWindow_fx, hFdCngEnc->msLocalMinFlag, hFdCngEnc->msNewMinFlag, hFdCngEnc->msPeriodogBuf_fx, &( hFdCngEnc->msPeriodogBufPtr ), hFdCngEnc->hFdCngCom, - ENC, ( hCPE == NULL ) ? 0 : hCPE->element_mode ); - - /* Expand MS outputs */ - expand_range( msLogNoiseEst_fx, msNoiseEst_fx, &hFdCngEnc->msNoiseEst_fx_exp, hFdCngEnc->hFdCngCom->npart ); - - return; -} - - -/*-------------------------------------------------------------------* - * FdCng_encodeSID() - * - * Generate a bitstream out of the partition levels - *-------------------------------------------------------------------*/ -void FdCng_encodeSID_ivas_fx( - Encoder_State *st /* i/o: encoder state structure */ -) -{ - Word16 N; - HANDLE_FD_CNG_ENC hFdCngEnc = st->hFdCngEnc; - HANDLE_FD_CNG_COM hFdCngCom = hFdCngEnc->hFdCngCom; - BSTR_ENC_HANDLE hBstr = st->hBstr; - - Word32 *invTrfMatrix_fx, *E_fx; - Word32 tmpRAM_fx[FDCNG_VQ_MAX_LEN][FDCNG_VQ_DCT_MAXTRUNC]; - Word32 v_fx[32], gain_fx, e_fx, temp; - Word16 w_fx[32], indices[32], exp[32]; - Word32 dct_target_fx[FDCNG_VQ_DCT_MAXTRUNC]; - Word32 tot_sig_ext_fx[FDCNG_VQ_MAX_LEN]; - Word16 v_e, gain_q_offset, preemph_fac; - Word16 i, index; - - gain_q_offset = GAIN_Q_OFFSET_IVAS_FX_Q0; - move16(); - - if ( st->element_mode == EVS_MONO ) - { - gain_q_offset = GAIN_Q_OFFSET_EVS_FX_Q0; - move16(); - } - - preemph_fac = st->preemph_fac; // Q15 - move16(); - - /* Init */ - N = hFdCngEnc->npartDec; - move16(); - - E_fx = hFdCngEnc->msNoiseEst_fx; - - invTrfMatrix_fx = (Word32 *) tmpRAM_fx; /* dynamically filled */ - - set_zero_fx( v_fx, FDCNG_VQ_MAX_LEN ); - - /* Convert to LOG */ - e_fx = 0; - move32(); - FOR( i = 0; i < N; i++ ) - { - IF( E_fx[i] == 0 ) - { - /* 10 * log(1e-4) = 10 * (-4) = -40 */ - v_fx[i] = -41943040; // -40.0 in Q20 - move32(); - } - ELSE - { - v_fx[i] = Mpy_32_32( 671088640 /*10 in Q26*/, BASOP_Util_Log10( E_fx[i], hFdCngEnc->msNoiseEst_fx_exp ) ); // Q20 = 26+25-31 - move32(); - } - e_fx = L_add( e_fx, v_fx[i] ); // Q20 - } - - /* Normalize MSVQ input */ - gain_fx = 0; - move32(); - FOR( i = N_GAIN_MIN; i < N_GAIN_MAX; i++ ) - { - gain_fx = L_add( gain_fx, v_fx[i] ); // Q20 - } - - /*gain /= (float) ( N_GAIN_MAX - N_GAIN_MIN );*/ - gain_fx = Mpy_32_32( gain_fx, 165191050 /* 1/13 in Q31*/ ); // Q20 - - FOR( i = 0; i < N; i++ ) - { - v_fx[i] = L_sub( v_fx[i], gain_fx ); // Q20 - move32(); - } - - v_e = 11; // Q20 - move16(); - - /* MSVQ encoder */ - set_val_Word16( w_fx, ONE_IN_Q8, N ); - - IF( st->element_mode != EVS_MONO ) - { - /* DCT domain compressed/truncated indices used for first stage */ - /* quantization with stage1 stored in DCT24 domain, stages 2 through 6 directly dearched - in FDCNG band domain - */ - IF( EQ_16( N, FDCNG_VQ_MAX_LEN_WB ) ) - { - /* truncated DCT21 analysis */ - create_IDCT_N_Matrix_fx( invTrfMatrix_fx, N, FDCNG_VQ_DCT_MAXTRUNC, sizeof( tmpRAM_fx ) / ( sizeof( Word32 ) ) ); // Q31 - - dctT2_N_apply_matrix_fx( v_fx /*Q20*/, dct_target_fx, FDCNG_VQ_DCT_MAXTRUNC, N, invTrfMatrix_fx, FDCNG_VQ_DCT_MAXTRUNC, DCT_T2_21_XX ); // Q20 - - /* truncated IDCT21 extension to 24 bands */ - extend_dctN_input_fx( v_fx, dct_target_fx, N, tot_sig_ext_fx, FDCNG_VQ_MAX_LEN, invTrfMatrix_fx, FDCNG_VQ_DCT_MAXTRUNC, IDCT_T2_XX_21 ); // Q20 - - Copy32( tot_sig_ext_fx, v_fx, FDCNG_VQ_MAX_LEN ); /* write extended result as input to VQ stage #1 */ // Q20 - } - - create_IDCT_N_Matrix_fx( invTrfMatrix_fx, FDCNG_VQ_MAX_LEN, FDCNG_VQ_DCT_MAXTRUNC, sizeof( tmpRAM_fx ) / ( sizeof( Word32 ) ) ); // Q31 - - msvq_enc_ivas_fx( ivas_cdk_37bits_fx, Q7, NULL, NULL, v_fx, v_e, levels_37bits, FD_CNG_maxC_37bits, FD_CNG_stages_37bits, w_fx, N, FD_CNG_maxN_37bits, 1, invTrfMatrix_fx, indices ); - - msvq_dec_fx( ivas_cdk_37bits_fx, NULL, NULL, FD_CNG_stages_37bits, N, FD_CNG_maxN_37bits, indices, 1, invTrfMatrix_fx, v_fx, NULL, 7 ); - - v_e = sub( 31, sub( 20, find_guarded_bits_fx( N ) ) ); - } - ELSE - { /* EVS_MONO tables */ - msvq_enc_ivas_fx( ivas_cdk_37bits_fx, Q7, NULL, NULL, v_fx, v_e, levels_37bits, FD_CNG_maxC_37bits, FD_CNG_stages_37bits, w_fx, N, FD_CNG_maxN_37bits, 0, NULL, indices ); - - msvq_dec_fx( ivas_cdk_37bits_fx, NULL, NULL, FD_CNG_stages_37bits, N, FD_CNG_maxN_37bits, indices, 0, NULL, v_fx, NULL, 7 ); - - v_e = sub( 31, sub( 20, find_guarded_bits_fx( N ) ) ); - } - - /* Compute gain */ - gain_fx = 0; - move32(); - FOR( i = 0; i < N; i++ ) - { - gain_fx = L_add( gain_fx, v_fx[i] ); // Q = 31 - v_e - } - - e_fx = L_shl( e_fx, sub( 11, v_e ) ); // Q = 31 - v_e - gain_fx = Mpy_32_16_1( L_sub( e_fx, gain_fx ), div_s( 1, N ) ); // Q = 31 - v_e - gain_fx = L_shl( gain_fx, sub( v_e, 8 ) ); // Q23 - - /* Apply bitrate-dependant scale */ - IF( st->element_mode > EVS_MONO ) - { - apply_scale( &gain_fx, hFdCngCom->CngBandwidth, hFdCngCom->CngBitrate, scaleTableStereo, SIZE_SCALE_TABLE_STEREO ); - } - ELSE - { - apply_scale( &gain_fx, hFdCngCom->CngBandwidth, hFdCngCom->CngBitrate, scaleTableMono, SIZE_SCALE_TABLE_MONO ); - } - - /* Quantize gain */ - temp = Madd_32_32( L_shl( gain_q_offset, 22 ), gain_fx, 1610612736 /*1.5 in Q30*/ ); // Q22 - index = extract_l( L_shr( L_add( temp, ONE_IN_Q21 ), 22 ) ); // Q0 - - if ( index < 0 ) - { - index = 0; - move16(); - } - - if ( GT_16( index, 127 ) ) - { - index = 127; - move16(); - } - - gain_fx = L_shl( L_mult0( sub( index, gain_q_offset ), 21845 /*1.5 in Q15*/ ), sub( 16, v_e ) ); // Q = 31-v_e - - /* Apply gain and undo log */ - FOR( i = 0; i < N; i++ ) - { - temp = Mpy_32_32( L_add( v_fx[i], gain_fx ), 214748365 /* 0.1 in Q31*/ ); // Q = 31-v_e - hFdCngCom->sidNoiseEst[i] = BASOP_Util_fPow( 10, 31, temp, v_e, &exp[i] ); - move32(); - } - - maximum_s( exp, N, &hFdCngCom->sidNoiseEstExp ); - - FOR( i = 0; i < N; i++ ) - { - hFdCngCom->sidNoiseEst[i] = L_shr( hFdCngCom->sidNoiseEst[i], sub( hFdCngCom->sidNoiseEstExp, exp[i] ) ); // exp = hFdCngCom->sidNoiseEstExp - move32(); - } - - /* NB last band energy compensation */ - IF( hFdCngCom->CngBandwidth == NB ) - { - hFdCngCom->sidNoiseEst[N - 1] = Mpy_32_16_1( hFdCngCom->sidNoiseEst[N - 1], NB_LAST_BAND_SCALE ); - move32(); - } - - test(); - IF( EQ_16( hFdCngCom->CngBandwidth, SWB ) && LE_32( hFdCngCom->CngBitrate, ACELP_13k20 ) ) - { - hFdCngCom->sidNoiseEst[N - 1] = Mpy_32_16_1( hFdCngCom->sidNoiseEst[N - 1], SWB_13k2_LAST_BAND_SCALE ); - move32(); - } - - /* Write bitstream */ - IF( EQ_16( st->codec_mode, MODE2 ) ) - { - FOR( i = 0; i < FD_CNG_stages_37bits; i++ ) - { - push_next_indice( hBstr, indices[i], bits_37bits[i] ); - } - - push_next_indice( hBstr, index, 7 ); - } - ELSE - { - Word16 is_frame_len_16k = 0; - move16(); - if ( EQ_16( st->L_frame, L_FRAME16k ) ) - { - is_frame_len_16k = 1; - move16(); - } - push_indice( hBstr, IND_SID_TYPE, 1, 1 ); - push_indice( hBstr, IND_BWIDTH, st->bwidth, 2 ); - push_indice( hBstr, IND_ACELP_16KHZ, is_frame_len_16k, 1 ); - - FOR( i = 0; i < FD_CNG_stages_37bits; i++ ) - { - push_indice( hBstr, IND_LSF, indices[i], bits_37bits[i] ); - } - - push_indice( hBstr, IND_ENERGY, index, 7 ); - } - - /* Interpolate the bin/band-wise levels from the partition levels */ - scalebands( hFdCngCom->sidNoiseEst, hFdCngEnc->partDec, hFdCngEnc->npartDec, hFdCngEnc->midbandDec, hFdCngEnc->nFFTpartDec, sub( hFdCngEnc->stopBandDec, hFdCngEnc->startBandDec ), hFdCngCom->cngNoiseLevel, 1 ); - hFdCngCom->cngNoiseLevelExp = hFdCngCom->sidNoiseEstExp; - move16(); - - lpc_from_spectrum( hFdCngCom, hFdCngEnc->startBandDec, hFdCngEnc->stopFFTbinDec, preemph_fac ); - - return; -} - - -/*-------------------------------------------------------------------* - * stereoFdCngCoherence() - * - * compute coherence of channels for use in FD-CNG - *-------------------------------------------------------------------*/ -void stereoFdCngCoherence_fx( - Encoder_State **sts, /* i/o: core encoder structures */ - const Word16 last_element_mode, /* i : last element mode */ - Word16 fft_buf_fx[CPE_CHANNELS][2 * L_FFT], /* i : fft buffers for L and R channels fft_exp*/ - Word16 fft_exp ) -{ - const Word16 *pt_fftL, *pt_fftR; - Word16 i_subfr, i; - Word32 cr, ci, eL, eR; - Word16 cr_exp, ci_exp, eL_exp, eR_exp; - Word32 *mem; - Word16 *mem_exp; - - IF( NE_16( last_element_mode, IVAS_CPE_MDCT ) ) - { - set32_fx( sts[0]->hFdCngEnc->mem_coherence_fx, EPSILON_FX, 4 ); - set16_fx( sts[0]->hFdCngEnc->mem_coherence_exp, 0, 4 ); - } - test(); - test(); - IF( EQ_32( sts[0]->core_brate, -1 ) || EQ_32( sts[1]->core_brate, -1 ) ) - { - /* case: at least one channel has triggered VAD -> ACTIVE FRAME */ - IF( EQ_32( sts[0]->core_brate, -1 ) ) - { - sts[1]->total_brate = sts[0]->total_brate; - move32(); - sts[1]->active_cnt = sts[0]->active_cnt; - move16(); - if ( GE_32( sts[1]->active_cnt, CNG_TYPE_HO ) ) - { - sts[1]->last_total_brate_cng = -1; - move16(); - } - } - IF( EQ_32( sts[1]->core_brate, -1 ) ) - { - sts[0]->total_brate = sts[1]->total_brate; - move32(); - sts[0]->active_cnt = sts[1]->active_cnt; - move16(); - if ( GE_16( sts[0]->active_cnt, CNG_TYPE_HO ) ) - { - sts[0]->last_total_brate_cng = -1; - move16(); - } - } - sts[0]->core_brate = -1; - move32(); - sts[1]->core_brate = -1; - move32(); - sts[0]->hDtxEnc->cnt_SID = 0; - move16(); - sts[1]->hDtxEnc->cnt_SID = 0; - move16(); - } - ELSE IF( LE_32( sts[0]->core_brate, SID_2k40 ) && LE_32( sts[1]->core_brate, SID_2k40 ) ) - { - /* case: no VAD for both channels -> INACTIVE FRAME */ - reset_indices_enc( sts[0]->hBstr, sts[0]->hBstr->nb_ind_tot ); - - reset_indices_enc( sts[1]->hBstr, sts[1]->hBstr->nb_ind_tot ); - - /* synchronize SID sending for variable SID rate */ - IF( EQ_32( sts[0]->core_brate, sts[1]->core_brate ) ) - { - sts[0]->core_brate = SID_2k40; - move32(); - sts[1]->core_brate = SID_2k40; - move32(); - } - - /* synchronize SID counters */ - sts[0]->hDtxEnc->cnt_SID = s_min( sts[0]->hDtxEnc->cnt_SID, sts[1]->hDtxEnc->cnt_SID ); - sts[1]->hDtxEnc->cnt_SID = sts[0]->hDtxEnc->cnt_SID; - move16(); - move16(); - } - - pt_fftL = fft_buf_fx[0]; - pt_fftR = fft_buf_fx[1]; - mem = sts[0]->hFdCngEnc->mem_coherence_fx; - mem_exp = sts[0]->hFdCngEnc->mem_coherence_exp; - FOR( i_subfr = 0; i_subfr < 2; i_subfr++ ) - { - cr = ci = eL = eR = EPSILON_FX; - move32(); - move32(); - move32(); - move32(); - cr_exp = ci_exp = eL_exp = eR_exp = 0; - move16(); - move16(); - move16(); - move16(); - - cr = BASOP_Util_Add_Mant32Exp( cr, cr_exp, L_add( L_mult( pt_fftL[0], pt_fftR[0] ), L_mult( pt_fftL[L_FFT / 2], pt_fftR[L_FFT / 2] ) ), shl( fft_exp, 1 ), &cr_exp ); - eL = BASOP_Util_Add_Mant32Exp( eL, eL_exp, L_add( L_mult( pt_fftL[0], pt_fftL[0] ), L_mult( pt_fftL[L_FFT / 2], pt_fftL[L_FFT / 2] ) ), shl( fft_exp, 1 ), &eL_exp ); - eR = BASOP_Util_Add_Mant32Exp( eR, eR_exp, L_add( L_mult( pt_fftR[0], pt_fftR[0] ), L_mult( pt_fftR[L_FFT / 2], pt_fftR[L_FFT / 2] ) ), shl( fft_exp, 1 ), &eR_exp ); - - FOR( i = 1; i < L_FFT / 2; i++ ) - { - cr = BASOP_Util_Add_Mant32Exp( cr, cr_exp, L_add( L_mult( pt_fftL[i], pt_fftR[i] ), L_mult( pt_fftL[L_FFT - i], pt_fftR[L_FFT - i] ) ), shl( fft_exp, 1 ), &cr_exp ); - ci = BASOP_Util_Add_Mant32Exp( ci, ci_exp, L_add( L_mult( -pt_fftL[i], pt_fftR[L_FFT - i] ), L_mult( pt_fftL[L_FFT - i], pt_fftR[i] ) ), shl( fft_exp, 1 ), &ci_exp ); - eL = BASOP_Util_Add_Mant32Exp( eL, eL_exp, L_add( L_mult( pt_fftL[i], pt_fftL[i] ), L_mult( pt_fftL[L_FFT - i], pt_fftL[L_FFT - i] ) ), shl( fft_exp, 1 ), &eL_exp ); - eR = BASOP_Util_Add_Mant32Exp( eR, eR_exp, L_add( L_mult( pt_fftR[i], pt_fftR[i] ), L_mult( pt_fftR[L_FFT - i], pt_fftR[L_FFT - i] ) ), shl( fft_exp, 1 ), &eR_exp ); - } - test(); - test(); - IF( LE_32( sts[0]->ini_frame, 50 ) || ( sts[0]->vad_flag == 0 && sts[1]->vad_flag == 0 ) ) - { - mem[0] = BASOP_Util_Add_Mant32Exp( Mpy_32_16_1( mem[0], 31129 /*0.95f*/ ), mem_exp[0], Mpy_32_16_1( cr, 1638 /*0.05f*/ ), cr_exp, &mem_exp[0] ); - move32(); - mem[1] = BASOP_Util_Add_Mant32Exp( Mpy_32_16_1( mem[1], 31129 /*0.95f*/ ), mem_exp[1], Mpy_32_16_1( ci, 1638 /*0.05f*/ ), ci_exp, &mem_exp[1] ); - move32(); - mem[2] = BASOP_Util_Add_Mant32Exp( Mpy_32_16_1( mem[2], 31129 /*0.95f*/ ), mem_exp[2], Mpy_32_16_1( eL, 1638 /*0.05f*/ ), eL_exp, &mem_exp[2] ); - move32(); - mem[3] = BASOP_Util_Add_Mant32Exp( Mpy_32_16_1( mem[3], 31129 /*0.95f*/ ), mem_exp[3], Mpy_32_16_1( eR, 1638 /*0.05f*/ ), eR_exp, &mem_exp[3] ); - move32(); - } - - pt_fftL += L_FFT; - pt_fftR += L_FFT; - } - - Word16 sqr_inp, temp, sqr_out, sqr_inp_exp; - Word32 sqr_inp32 = BASOP_Util_Add_Mant32Exp( Mpy_32_32( mem[0], mem[0] ), shl( mem_exp[0], 1 ), Mpy_32_32( mem[1], mem[1] ), shl( mem_exp[1], 1 ), &sqr_inp_exp ); - sqr_inp = BASOP_Util_Divide3232_Scale( sqr_inp32, Mpy_32_32( mem[2], mem[3] ), &temp ); - sqr_inp_exp = add( temp, sub( sqr_inp_exp, add( mem_exp[2], mem_exp[3] ) ) ); - sqr_out = Sqrt16( sqr_inp, &sqr_inp_exp ); - sts[0]->hFdCngEnc->hFdCngCom->coherence_fx = shl_sat( sqr_out, sqr_inp_exp ); // Q15 expected. - move16(); - return; -} - -/*-------------------------------------------------------------------* - * FdCngEncodeMDCTStereoSID() - * - * Encode DTX parameters and noise shapes into SID for MDCT-Stereo DTX - *-------------------------------------------------------------------*/ - -void FdCngEncodeMDCTStereoSID_fx( - CPE_ENC_HANDLE hCPE /* i/o: CPE encoder state structure */ -) -{ - ENC_CORE_HANDLE sts[CPE_CHANNELS]; - Word16 indices[CPE_CHANNELS][FD_CNG_stages_37bits]; - Word16 gain_idx[CPE_CHANNELS]; - Word16 N, stages, ch, p, coh_idx; - Word32 *lr_in_ptr_fx[CPE_CHANNELS]; - Word16 lr_in_ptr_e[CPE_CHANNELS]; - Word32 *ms_ptr_fx[CPE_CHANNELS]; - Word16 ms_ptr_e; - Word32 *lr_out_ptr_fx[CPE_CHANNELS]; - Word16 lr_out_ptr_e[CPE_CHANNELS]; - Word32 logNoiseEst_fx[CPE_CHANNELS][NPART]; - Word32 E_fx[CPE_CHANNELS]; - Word32 gain_fx[CPE_CHANNELS]; - Word16 weights_fx[NPART]; - Word32 side_energy_fx; - Word16 Qside_energy; - Word32 *invTrfMatrix_fx; - Word32 tmpRAM_fx[FDCNG_VQ_MAX_LEN][FDCNG_VQ_DCT_MAXTRUNC]; /*24*18*/ - invTrfMatrix_fx = (Word32 *) tmpRAM_fx; /* dynamically filled */ - Word32 tot_sig_ext_fx[FDCNG_VQ_MAX_LEN], dct_target_fx[CPE_CHANNELS][FDCNG_VQ_DCT_MAXTRUNC]; /* 24 +2*18*/ - Word16 tmp, tmp_e; - Word16 no_side_flag; - Word16 is_inp_ms; - Word16 size_value, temp_e, gb, shift; - Word32 tmp32, t1, t2; - - is_inp_ms = 0; - move16(); - IF( EQ_16( hCPE->hCoreCoder[0]->cng_sba_flag, 1 ) ) - { - is_inp_ms = 1; - move16(); - } - - /* set pointers and initialize */ - FOR( ch = 0; ch < CPE_CHANNELS; ch++ ) - { - sts[ch] = hCPE->hCoreCoder[ch]; - lr_in_ptr_fx[ch] = &sts[ch]->hFdCngEnc->msNoiseEst_fx[0]; - lr_in_ptr_e[ch] = sts[ch]->hFdCngEnc->msNoiseEst_fx_exp; - ms_ptr_fx[ch] = &logNoiseEst_fx[ch][0]; - lr_out_ptr_fx[ch] = &sts[ch]->hFdCngEnc->hFdCngCom->sidNoiseEst[0]; - lr_out_ptr_e[ch] = sts[ch]->hFdCngEnc->hFdCngCom->sidNoiseEstExp; - } - N = sts[0]->hFdCngEnc->npartDec; - move16(); - set16_fx( weights_fx, ONE_IN_Q8, NPART ); - - /* apply log and save energy of original left and right channels */ - FOR( ch = 0; ch < CPE_CHANNELS; ch++ ) - { - // E[ch] = 0.0f; - E_fx[ch] = 0; - move32(); - FOR( p = 0; p < N; p++ ) - { - IF( lr_in_ptr_fx[ch][p] ) - { - t1 = BASOP_Util_Log2( lr_in_ptr_fx[ch][p] ); // Q25 - t2 = L_add( t1, L_shl( lr_in_ptr_e[ch], Q25 ) ); // Q25 - } - ELSE - { - t2 = 0; - move32(); - } - ms_ptr_fx[ch][p] = Mpy_32_32( t2, TEN_MULT_LOG10_2_IN_Q29 ); // Q23 - move32(); - E_fx[ch] = L_add( E_fx[ch], L_shr( ms_ptr_fx[ch][p], 4 ) ); // Q19 - move32(); - } - } - ms_ptr_e = Q31 - Q23; - move16(); - - /* M/S transform on log envelopes */ - IF( is_inp_ms == 0 ) - { - convertToMS_fx( N, ms_ptr_fx[0], ms_ptr_fx[1], ONE_IN_Q30 ); // ms_ptr_e = Q23; - } - - gb = find_guarded_bits_fx( N ); - side_energy_fx = sum2_f_32_fx( ms_ptr_fx[1], N, gb ); - Qside_energy = sub( sub( shl( sub( 31, ms_ptr_e ), 1 ), 31 ), gb ); - - /* do not transmit side shape if initial noise shapes are very similar */ - IF( LE_32( side_energy_fx, L_shl( 214748365, sub( Qside_energy, Q31 ) ) ) ) - { - no_side_flag = 1; - move16(); - } - ELSE - { - no_side_flag = 0; - move16(); - } - - /* Quantize noise shapes */ - FOR( ch = 0; ch < CPE_CHANNELS; ch++ ) - { - /* Normalize MSVQ input */ - gain_fx[ch] = 0; - move32(); - FOR( p = N_GAIN_MIN; p < N_GAIN_MAX; p++ ) - { - tmp32 = Mpy_32_32( ms_ptr_fx[ch][p], 165191050 ); // Q23 - gain_fx[ch] = L_add( gain_fx[ch], tmp32 ); // Q23 - move32(); - } - - FOR( p = 0; p < N; p++ ) - { - ms_ptr_fx[ch][p] = L_sub( ms_ptr_fx[ch][p], gain_fx[ch] ); - move32(); - } - } - - /* always split channel targetloop */ - - /* extend fdcng envelope from length 21 to a 24 length fdncg domain envelope signal */ - /* High quality cosine smooth basis extension used to not introduce noise in stage#1 DCT24 analysis and subsequent VQ-steps */ - IF( EQ_16( N, FDCNG_VQ_MAX_LEN_WB ) ) - { - size_value = BASOP_Util_Divide1616_Scale( sizeof( tmpRAM_fx ), ( sizeof( Word32 ) ), &temp_e ); /*Q15*/ - size_value = shr( size_value, sub( 15, temp_e ) ); - create_IDCT_N_Matrix_fx( invTrfMatrix_fx, N, FDCNG_VQ_DCT_MAXTRUNC, size_value ); // Q31 /*WB: create truncated IDCT21 matrix */ - for ( ch = 0; ch < CPE_CHANNELS; ch++ ) - { - /* run DCT_N N==21 , truncated at 18/21 ~= 86% , i.e use a bit better better quality in extrapolation , than subsequent DCT24 analysis which is truncated at 75%*/ - /* truncated DCT 21 analysis */ - dctT2_N_apply_matrix_fx( (const Word32 *) ms_ptr_fx[ch], dct_target_fx[ch], FDCNG_VQ_DCT_MAXTRUNC, N, invTrfMatrix_fx, FDCNG_VQ_DCT_MAXTRUNC, DCT_T2_21_XX ); - /* extrapolate extend fdcng envelope signal in the fdncg ienvelope/"time" domain using DCT21 basis vectors, - estimated DCT21 coeffs scaling extended basis vectors are used to create extrapolated length 24 input target envelope signal */ - /* this DCT21 extension does not introduce DCT24 coefficient noise for the subsequent dct24 target analysis, and later in IDCT24 synthesis */ - - /* truncated IDCT 21 extension synthesis */ - extend_dctN_input_fx( ms_ptr_fx[ch], dct_target_fx[ch], N, tot_sig_ext_fx, FDCNG_VQ_MAX_LEN, invTrfMatrix_fx /* DCT_N basis vectors */, FDCNG_VQ_DCT_MAXTRUNC, IDCT_T2_XX_21 ); /* use 18 basis vectors*/ - - Copy32( tot_sig_ext_fx, ms_ptr_fx[ch], FDCNG_VQ_MAX_LEN ); /* write extended result as input to VQ */ - } - } - - size_value = BASOP_Util_Divide1616_Scale( sizeof( tmpRAM_fx ), ( sizeof( Word32 ) ), &temp_e ); /*Q15*/ - size_value = shr( size_value, sub( 15, temp_e ) ); - create_IDCT_N_Matrix_fx( invTrfMatrix_fx, FDCNG_VQ_MAX_LEN, FDCNG_VQ_DCT_MAXTRUNC, size_value ); /*always create/set up IDCT24 matrix in RAM */ - - /* end split */ - FOR( ch = 0; ch < CPE_CHANNELS; ch++ ) - { - /* MSVQ */ - IF( ch ) - { - stages = FD_CNG_JOINT_stages_25bits; - move16(); - } - ELSE - { - stages = FD_CNG_stages_37bits; - move16(); - } - - /* DCT24 domain compressed/truncated indices used for first stage */ - /* mid channel quantization using stages 1 through 6 */ - /* & side channel quantization using stages 1 through 4 */ - - { - msvq_enc_ivas_fx( ivas_cdk_37bits_fx, Q7, NULL, NULL, ms_ptr_fx[ch], ms_ptr_e, levels_37bits, FD_CNG_maxC_37bits, stages, weights_fx, N, FD_CNG_maxN_37bits, 1, invTrfMatrix_fx, indices[ch] ); - msvq_dec_fx( ivas_cdk_37bits_fx, NULL, NULL, stages, N, FD_CNG_maxN_37bits, indices[ch], 1, invTrfMatrix_fx, ms_ptr_fx[ch], NULL, 7 ); - } - } - shift = find_guarded_bits_fx( N ); - ms_ptr_e = sub( 31, sub( 20, shift ) ); - - IF( no_side_flag ) - { - set32_fx( ms_ptr_fx[1], 0, N ); - } - - /* undo M/S */ - IF( is_inp_ms == 0 ) - { - convertToMS_fx( N, ms_ptr_fx[0], ms_ptr_fx[1], ONE_IN_Q31 ); - } - - /* Compute gain against original left and right channels */ - FOR( ch = 0; ch < CPE_CHANNELS; ch++ ) - { - gain_fx[ch] = 0; - move32(); - - tmp_e = 15; - move16(); - tmp = Inv16( N, &tmp_e ); - FOR( p = 0; p < N; p++ ) - { - gain_fx[ch] = L_add( gain_fx[ch], Mpy_32_16_1( ms_ptr_fx[ch][p], shl( tmp, tmp_e ) ) ); - move32(); - } - gain_fx[ch] = L_sub( L_shl( Mpy_32_16_1( E_fx[ch], shl( tmp, tmp_e ) ), Q23 - Q19 ), L_shl( gain_fx[ch], sub( ms_ptr_e, 8 ) ) ); // Q23 - move32(); - - apply_scale( &gain_fx[ch], sts[ch]->hFdCngEnc->hFdCngCom->CngBandwidth, sts[ch]->element_brate, scaleTableStereo, SIZE_SCALE_TABLE_STEREO ); - - /* quantize gain */ - gain_idx[ch] = (Word16) Mpy_32_32_r( L_add( gain_fx[ch], 251658240 ), 384 ); - move16(); - gain_idx[ch] = s_max( 0, s_min( 127, gain_idx[ch] ) ); - move16(); - - gain_fx[ch] = Mpy_32_16_1( L_shl( sub( gain_idx[ch], GAIN_Q_OFFSET_IVAS_FX_Q0 ), 23 ), 21845 ); // Q23 - move32(); - } - - /* restore channel noise envelopes */ - FOR( ch = 0; ch < CPE_CHANNELS; ch++ ) - { - HANDLE_FD_CNG_ENC hFdCngEnc = sts[ch]->hFdCngEnc; - HANDLE_FD_CNG_COM hFdCngCom = hFdCngEnc->hFdCngCom; - - tmp_e = 0; - move16(); - Word32 pow; - - Word16 e_lr_out[NPART]; - - FOR( p = 0; p < N; p++ ) - { - pow = L_shl( gain_fx[ch], 8 - ms_ptr_e ); - pow = L_add( ms_ptr_fx[ch][p], pow ); - pow = Mpy_32_32( pow, 214748365 ); /*pow = 0.1*/ - lr_out_ptr_fx[ch][p] = BASOP_Util_fPow( 10, 31, pow, ms_ptr_e, &e_lr_out[p] ); - move32(); - tmp_e = s_max( tmp_e, e_lr_out[p] ); - } - - FOR( p = 0; p < N; p++ ) - { - lr_out_ptr_fx[ch][p] = L_shl( lr_out_ptr_fx[ch][p], e_lr_out[p] - tmp_e ); - move32(); - } - lr_out_ptr_e[ch] = tmp_e; - move32(); - - sts[ch]->hFdCngEnc->hFdCngCom->sidNoiseEstExp = tmp_e; - move16(); - - /* scale bands and get scalefactors */ - scalebands( lr_out_ptr_fx[ch], hFdCngEnc->partDec, N, hFdCngEnc->midbandDec, hFdCngEnc->nFFTpartDec, sub( hFdCngEnc->stopBandDec, hFdCngEnc->startBandDec ), hFdCngCom->cngNoiseLevel, 1 ); - hFdCngCom->cngNoiseLevelExp = lr_out_ptr_e[ch]; - move16(); - - lpc_from_spectrum( hFdCngCom, hFdCngEnc->startBandDec, hFdCngEnc->stopFFTbinDec, sts[ch]->preemph_fac ); - - sts[ch]->hDtxEnc->last_CNG_L_frame = sts[ch]->L_frame; - } - - /* quantize channel coherence */ - coh_idx = mult_r( sts[0]->hFdCngEnc->hFdCngCom->coherence_fx, 15 ); - coh_idx = max( 0, min( coh_idx, 15 ) ); - - /* ---- Write SID bitstream ---- */ - - - /* noise shapes and channel gains */ - FOR( ch = 0; ch < CPE_CHANNELS; ch++ ) - { - IF( ch ) - { - stages = FD_CNG_JOINT_stages_25bits; - sts[ch]->hBstr->ind_list = sts[0]->hBstr->ind_list + sts[0]->hBstr->nb_ind_tot; - - /* side info */ - push_indice( sts[ch]->hBstr, IND_SID_TYPE, coh_idx, 4 ); - push_indice( sts[ch]->hBstr, IND_SID_TYPE, no_side_flag, 1 ); - } - ELSE - { - stages = FD_CNG_stages_37bits; - /* side info */ - push_indice( sts[ch]->hBstr, IND_SID_TYPE, 1, 1 ); - push_indice( sts[ch]->hBstr, IND_BWIDTH, sts[0]->bwidth, 2 ); - push_indice( sts[ch]->hBstr, IND_ACELP_16KHZ, sts[0]->L_frame == L_FRAME16k ? 1 : 0, 1 ); - } - - FOR( Word16 i = 0; i < stages; i++ ) - { - push_indice( sts[ch]->hBstr, IND_LSF, indices[ch][i], bits_37bits[i] ); - } - push_indice( sts[ch]->hBstr, IND_ENERGY, gain_idx[ch], 7 ); - } - - /* pad with zeros to reach common SID frame size */ - push_indice( sts[1]->hBstr, IND_ENERGY, 0, ( IVAS_SID_5k2 - 4400 ) / FRAMES_PER_SEC ); - - return; -} - -/*-------------------------------------------------------------------* - * FdCngEncodeDiracMDCTStereoSID() - * - * Encode DTX parameters and noise shapes into SID for MDCT-Stereo DTX - * together with Dirac - *-------------------------------------------------------------------*/ - -void FdCngEncodeDiracMDCTStereoSID_fx( - CPE_ENC_HANDLE hCPE /* i/o: CPE encoder state structure */ -) -{ - ENC_CORE_HANDLE sts[CPE_CHANNELS]; - Word32 *lr_in_ptr_fx[CPE_CHANNELS]; - Word16 lr_in_ptr_e[CPE_CHANNELS]; - Word32 *ms_ptr_fx[CPE_CHANNELS]; - Word16 ms_ptr_e; - Word32 *lr_out_ptr_fx[CPE_CHANNELS]; - Word16 lr_out_ptr_e[CPE_CHANNELS]; - Word32 logNoiseEst_fx[CPE_CHANNELS][NPART]; - Word32 E_fx[CPE_CHANNELS]; - Word32 gain_fx[CPE_CHANNELS]; - Word16 weights_fx[NPART]; - Word16 N[CPE_CHANNELS]; - Word16 indices[CPE_CHANNELS][FD_CNG_stages_37bits]; - Word16 gain_idx[CPE_CHANNELS]; - Word16 ch, p; - Word16 tmp, tmp_e, shift; - Word32 *invTrfMatrix_fx; - Word32 tmpRAM_fx[FDCNG_VQ_MAX_LEN][FDCNG_VQ_DCT_MAXTRUNC]; - Word32 dct_target_fx[FDCNG_VQ_DCT_MAXTRUNC]; - Word32 tot_sig_ext_fx[FDCNG_VQ_MAX_LEN]; - invTrfMatrix_fx = (Word32 *) tmpRAM_fx; /* dynamically filled */ - Word32 t1, t2, tmp32; - /* set pointers and initialize */ - - FOR( ch = 0; ch < CPE_CHANNELS; ch++ ) - { - sts[ch] = hCPE->hCoreCoder[ch]; - N[ch] = sts[ch]->hFdCngEnc->npartDec; - lr_in_ptr_fx[ch] = &sts[ch]->hFdCngEnc->msNoiseEst_fx[0]; - lr_in_ptr_e[ch] = sts[ch]->hFdCngEnc->msNoiseEst_fx_exp; - ms_ptr_fx[ch] = &logNoiseEst_fx[ch][0]; - lr_out_ptr_fx[ch] = &sts[ch]->hFdCngEnc->hFdCngCom->sidNoiseEst[0]; - lr_out_ptr_e[ch] = sts[ch]->hFdCngEnc->hFdCngCom->sidNoiseEstExp; - move16(); - } - set16_fx( weights_fx, ONE_IN_Q8, NPART ); - - /* apply log and save energy of original left and right channels */ - FOR( ch = 0; ch < CPE_CHANNELS; ch++ ) - { - // E[ch] = 0.0f; - E_fx[ch] = 0; - move32(); - FOR( p = 0; p < N[ch]; p++ ) - { - t1 = BASOP_Util_Log2( lr_in_ptr_fx[ch][p] + EPSILLON_FX ); // Q25 - t2 = L_add( t1, L_shl( lr_in_ptr_e[ch], Q25 ) ); // Q25 - ms_ptr_fx[ch][p] = Mpy_32_32( t2, TEN_MULT_LOG10_2_IN_Q29 ); // Q23 - move32(); - E_fx[ch] = L_add( E_fx[ch], L_shr( ms_ptr_fx[ch][p], 5 ) ); // Q18 - move32(); - } - } - ms_ptr_e = Q31 - Q23; - move16(); - - /* M/S transform on log envelopes */ - convertToMS_fx( N[0], ms_ptr_fx[0], ms_ptr_fx[1], ONE_IN_Q30 ); - E_fx[0] = 0; - move32(); - FOR( p = 0; p < N[0]; p++ ) - { - E_fx[0] = L_add( E_fx[0], L_shr( ms_ptr_fx[0][p], 5 ) ); // Q18 - move32(); - } - - /* Quantize M noise shape */ - /* Normalize MSVQ input */ - gain_fx[0] = 0; - move16(); - FOR( p = N_GAIN_MIN; p < N_GAIN_MAX; p++ ) - { - tmp32 = Mpy_32_32( ms_ptr_fx[0][p], 165191050 ); // Q23 - gain_fx[0] = L_add( gain_fx[0], tmp32 ); // Q23 - move32(); - } - - FOR( p = 0; p < N[0]; p++ ) - { - ms_ptr_fx[0][p] = L_sub( ms_ptr_fx[0][p], gain_fx[0] ); - move32(); - } - - - /* MSVQ */ - /* DCT domain compressed/truncated indices used for first stage */ - /* mid quantization using stages #1 through 6 */ - scale_sig32( ms_ptr_fx[0], N[0], -6 ); - ms_ptr_e = add( ms_ptr_e, 6 ); - move16(); - IF( EQ_16( N[0], FDCNG_VQ_MAX_LEN_WB ) ) - { - create_IDCT_N_Matrix_fx( invTrfMatrix_fx, N[0], FDCNG_VQ_DCT_MAXTRUNC, sizeof( tmpRAM_fx ) / ( sizeof( Word32 ) ) ); - /* truncated DCT 21 analysis */ - dctT2_N_apply_matrix_fx( (const Word32 *) ms_ptr_fx[0], dct_target_fx, FDCNG_VQ_DCT_MAXTRUNC, N[0], invTrfMatrix_fx, FDCNG_VQ_DCT_MAXTRUNC, DCT_T2_21_XX ); - /* truncated IDCT21 extension to 24 synthesis */ - - extend_dctN_input_fx( ms_ptr_fx[0], dct_target_fx, N[0], tot_sig_ext_fx, FDCNG_VQ_MAX_LEN, invTrfMatrix_fx, FDCNG_VQ_DCT_MAXTRUNC, IDCT_T2_XX_21 ); /* use 18 basis vectors*/ - - Copy32( tot_sig_ext_fx, ms_ptr_fx[0], FDCNG_VQ_MAX_LEN ); /* write extended result as input to VQ stage #1 */ - } - create_IDCT_N_Matrix_fx( invTrfMatrix_fx, FDCNG_VQ_MAX_LEN, FDCNG_VQ_DCT_MAXTRUNC, sizeof( tmpRAM_fx ) / ( sizeof( Word32 ) ) ); - - msvq_enc_ivas_fx( ivas_cdk_37bits_fx, Q7, NULL, NULL, ms_ptr_fx[0], ms_ptr_e, levels_37bits, FD_CNG_maxC_37bits, FD_CNG_stages_37bits, weights_fx, N[0], FD_CNG_maxN_37bits, 1, invTrfMatrix_fx, indices[0] ); - msvq_dec_fx( ivas_cdk_37bits_fx, NULL, NULL, FD_CNG_stages_37bits, N[0], FD_CNG_maxN_37bits, indices[0], 1, invTrfMatrix_fx, ms_ptr_fx[0], NULL, 7 ); - shift = find_guarded_bits_fx( N[0] ); - ms_ptr_e = sub( 31, sub( 20, shift ) ); - scale_sig32( ms_ptr_fx[1], N[1], sub( 8, ms_ptr_e ) ); - - /* set S to zero */ - set32_fx( ms_ptr_fx[1], 0, NPART ); - - /* compute M gain */ - gain_fx[0] = 0; - move32(); - tmp_e = 15; - move16(); - tmp = Inv16( N[0], &tmp_e ); - FOR( p = 0; p < N[0]; p++ ) - { - gain_fx[0] = L_add( gain_fx[0], Mpy_32_16_1( ms_ptr_fx[0][p], shl( tmp, tmp_e ) ) ); - move32(); - } - gain_fx[0] = L_sub( L_shl( Mpy_32_16_1( E_fx[0], shl( tmp, tmp_e ) ), Q23 - Q18 ), L_shl( gain_fx[0], ms_ptr_e - 8 ) ); // Q23 - move32(); - - apply_scale( &gain_fx[0], sts[0]->hFdCngEnc->hFdCngCom->CngBandwidth, sts[0]->hDtxEnc->last_active_brate, scaleTableStereo, SIZE_SCALE_TABLE_STEREO ); - - /* quantize gain */ - gain_idx[0] = extract_l( Mpy_32_32_r( L_add( gain_fx[0], 251658240 ), 384 ) ); - move16(); - gain_idx[0] = s_max( 0, s_min( 127, gain_idx[0] ) ); - move16(); - - gain_fx[0] = Mpy_32_16_1( L_shl( sub( gain_idx[0], GAIN_Q_OFFSET_IVAS_FX_Q0 ), 23 ), 21845 ); // Q23 - move32(); - gain_fx[1] = gain_fx[0]; // Q23 - move32(); - - /* undo M/S */ - convertToMS_fx( NPART, ms_ptr_fx[0], ms_ptr_fx[1], ONE_IN_Q31 ); - - /* restore channel noise envelopes */ - FOR( ch = 0; ch < CPE_CHANNELS; ch++ ) - { - HANDLE_FD_CNG_ENC hFdCngEnc = sts[ch]->hFdCngEnc; - HANDLE_FD_CNG_COM hFdCngCom = hFdCngEnc->hFdCngCom; - - Word32 pow; - Word16 e_lr_out[NPART]; - tmp_e = -MAX_16; - FOR( p = 0; p < N[ch]; p++ ) - { - pow = L_shl( gain_fx[ch], sub( 8, ms_ptr_e ) ); - pow = L_add( ms_ptr_fx[ch][p], pow ); - pow = Mpy_32_32( pow, 214748365 ); /*pow = 0.1*/ - lr_out_ptr_fx[ch][p] = BASOP_Util_fPow( 10, 31, pow, ms_ptr_e, &e_lr_out[p] ); - tmp_e = s_max( tmp_e, e_lr_out[p] ); - } - - FOR( p = 0; p < N[ch]; p++ ) - { - lr_out_ptr_fx[ch][p] = L_shl( lr_out_ptr_fx[ch][p], sub( e_lr_out[p], tmp_e ) ); // Q(31 - tmp_e) - } - - sts[ch]->hFdCngEnc->hFdCngCom->sidNoiseEstExp = tmp_e; - move16(); - lr_out_ptr_e[ch] = tmp_e; - move16(); - - /* NB last band energy compensation */ - IF( hFdCngCom->CngBandwidth == NB ) - { - lr_out_ptr_fx[ch][N[ch] - 1] = Mpy_32_16_1( lr_out_ptr_fx[ch][N[ch] - 1], NB_LAST_BAND_SCALE ); - move32(); - } - ELSE IF( hFdCngCom->CngBandwidth == SWB && LE_32( hFdCngCom->CngBitrate, ACELP_13k20 ) ) - { - lr_out_ptr_fx[ch][N[ch] - 1] = Mpy_32_16_1( lr_out_ptr_fx[ch][N[ch] - 1], SWB_13k2_LAST_BAND_SCALE ); - move32(); - } - /* scale bands and get scalefactors */ - scalebands( lr_out_ptr_fx[ch], hFdCngEnc->partDec, N[ch], hFdCngEnc->midbandDec, hFdCngEnc->nFFTpartDec, sub( hFdCngEnc->stopBandDec, hFdCngEnc->startBandDec ), hFdCngCom->cngNoiseLevel, 1 ); - hFdCngCom->cngNoiseLevelExp = lr_out_ptr_e[ch]; - move16(); - lpc_from_spectrum( hFdCngCom, hFdCngEnc->startBandDec, hFdCngEnc->stopFFTbinDec, sts[ch]->preemph_fac ); - sts[ch]->hDtxEnc->last_CNG_L_frame = sts[ch]->L_frame; - } - sts[0]->hFdCngEnc->hFdCngCom->coherence_fx = 0; - move16(); - sts[1]->hFdCngEnc->hFdCngCom->coherence_fx = 0; - move16(); - - /* ---- Write SID bitstream ---- */ - - /* side info */ - push_indice( sts[0]->hBstr, IND_SID_TYPE, 1, 1 ); - push_indice( sts[0]->hBstr, IND_BWIDTH, sts[0]->bwidth, 2 ); - IF( EQ_16( sts[0]->L_frame, L_FRAME16k ) ) - { - push_indice( sts[0]->hBstr, IND_ACELP_16KHZ, 1, 1 ); - } - ELSE - { - push_indice( sts[0]->hBstr, IND_ACELP_16KHZ, 0, 1 ); - } - - /* noise shapes and channel gains */ - FOR( Word16 i = 0; i < FD_CNG_stages_37bits; i++ ) - { - push_indice( sts[0]->hBstr, IND_LSF, indices[0][i], bits_37bits[i] ); - } - push_indice( sts[0]->hBstr, IND_ENERGY, gain_idx[0], 7 ); - - return; -} diff --git a/lib_enc/fd_cng_enc_fx.c b/lib_enc/fd_cng_enc_fx.c index 34b67b2ff575ffc52bfd6e7505d1a74921c26d89..757a6951821590eaf1aa615ddaadbb8d7e6928c5 100644 --- a/lib_enc/fd_cng_enc_fx.c +++ b/lib_enc/fd_cng_enc_fx.c @@ -11,9 +11,9 @@ #include "rom_com_fx.h" #include "rom_com.h" #include "rom_enc.h" -#include "prot.h" #include "prot_fx.h" #include "prot_fx_enc.h" +#include "ivas_prot_fx.h" #include "basop_util.h" #include "rom_basop_util.h" @@ -51,7 +51,10 @@ void createFdCngEnc_fx( HANDLE_FD_CNG_ENC *hFdCngEnc ) return; } -void initFdCngEnc_fx( HANDLE_FD_CNG_ENC hsEnc, Word32 input_Fs, Word16 scale ) +void initFdCngEnc_fx( + HANDLE_FD_CNG_ENC hsEnc, + Word32 input_Fs, /* Q0 */ + Word16 scale ) { Word16 j; HANDLE_FD_CNG_COM hsCom = hsEnc->hFdCngCom; @@ -65,7 +68,7 @@ void initFdCngEnc_fx( HANDLE_FD_CNG_ENC hsEnc, Word32 input_Fs, Word16 scale ) move16(); hsCom->numCoreBands = 16; move16(); - hsCom->regularStopBand = idiv1616U( extract_l( L_shr( input_Fs, 5 ) ), 25 ); + hsCom->regularStopBand = idiv1616U( extract_l( L_shr( input_Fs, 5 ) ), 25 ); /* Q0 */ move16(); if ( GT_16( hsCom->regularStopBand, 40 ) ) { @@ -88,7 +91,7 @@ void initFdCngEnc_fx( HANDLE_FD_CNG_ENC hsEnc, Word32 input_Fs, Word16 scale ) { hsCom->stopFFTbin = 256; move16(); - hsCom->stopBand = add( sub( hsCom->regularStopBand, hsCom->numCoreBands ), hsCom->stopFFTbin ); + hsCom->stopBand = add( sub( hsCom->regularStopBand, hsCom->numCoreBands ), hsCom->stopFFTbin ); /* Q0 */ move16(); hsCom->nFFTpart = 20; move16(); @@ -96,12 +99,12 @@ void initFdCngEnc_fx( HANDLE_FD_CNG_ENC hsEnc, Word32 input_Fs, Word16 scale ) initPartitions( sidparts_encoder_noise_est, SIZE_SIDPARTS_ENC_NOISE_EST, hsCom->startBand, hsCom->stopBand, hsCom->part, &hsCom->npart, hsCom->midband, hsCom->psize, hsCom->psize_norm, &hsCom->psize_norm_exp, hsCom->psize_inv, 0 ); - hsCom->nCLDFBpart = sub( hsCom->npart, hsCom->nFFTpart ); + hsCom->nCLDFBpart = sub( hsCom->npart, hsCom->nFFTpart ); /* Q0 */ move16(); FOR( j = 0; j < hsCom->nCLDFBpart; j++ ) { - hsCom->CLDFBpart[j] = sub( hsCom->part[j + hsCom->nFFTpart], sub( 256, hsCom->startBand ) ); - hsCom->CLDFBpsize_inv[j] = hsCom->psize_inv[j + hsCom->nFFTpart]; + hsCom->CLDFBpart[j] = sub( hsCom->part[j + hsCom->nFFTpart], sub( 256, hsCom->startBand ) ); /* Q0 */ + hsCom->CLDFBpsize_inv[j] = hsCom->psize_inv[j + hsCom->nFFTpart]; /* Q15 */ move16(); move16(); } @@ -151,8 +154,9 @@ void initFdCngEnc_fx( HANDLE_FD_CNG_ENC hsEnc, Word32 input_Fs, Word16 scale ) * Configure FD_CNG * ************************************/ void configureFdCngEnc_fx( HANDLE_FD_CNG_ENC hsEnc, /* i/o: Contains the variables related to the FD-based CNG process */ - Word16 bandwidth, /* i: bandwidth */ - Word32 bitrate ) + Word16 bandwidth, /* i: bandwidth Q0*/ + Word32 bitrate /* Q0 */ +) { HANDLE_FD_CNG_COM hsCom = hsEnc->hFdCngCom; Word16 psizeDec[NPART]; @@ -169,7 +173,7 @@ void configureFdCngEnc_fx( HANDLE_FD_CNG_ENC hsEnc, /* i/o: Contains the variabl hsCom->CngBandwidth = SWB; move16(); } - hsCom->CngBitrate = bitrate; + hsCom->CngBitrate = bitrate; /* Q0 */ move32(); /* NB configuration */ @@ -212,16 +216,16 @@ void configureFdCngEnc_fx( HANDLE_FD_CNG_ENC hsEnc, /* i/o: Contains the variabl hsCom->FdCngSetup = FdCngSetup_swb2; } } - hsCom->fftlen = hsCom->FdCngSetup.fftlen; + hsCom->fftlen = hsCom->FdCngSetup.fftlen; /* Q0 */ move16(); - hsEnc->stopFFTbinDec = hsCom->FdCngSetup.stopFFTbin; + hsEnc->stopFFTbinDec = hsCom->FdCngSetup.stopFFTbin; /* Q0 */ move16(); /* Configure the SID quantizer and the Confort Noise Generator */ - hsEnc->startBandDec = hsCom->startBand; + hsEnc->startBandDec = hsCom->startBand; /* Q0 */ move16(); - hsEnc->stopBandDec = add( hsCom->FdCngSetup.sidPartitions[hsCom->FdCngSetup.numPartitions - 1], 1 ); + hsEnc->stopBandDec = add( hsCom->FdCngSetup.sidPartitions[hsCom->FdCngSetup.numPartitions - 1], 1 ); /* Q0 */ move16(); initPartitions( hsCom->FdCngSetup.sidPartitions, hsCom->FdCngSetup.numPartitions, @@ -277,8 +281,9 @@ void configureFdCngEnc_fx( HANDLE_FD_CNG_ENC hsEnc, /* i/o: Contains the variabl void configureFdCngEnc_ivas_fx( HANDLE_FD_CNG_ENC hFdCngEnc, /* i/o: Contains the variables related to the FD-based CNG process */ - const Word16 bwidth, - const Word32 total_brate ) + const Word16 bwidth, /* Q0 */ + const Word32 total_brate /* Q0 */ +) { HANDLE_FD_CNG_COM hsCom = hFdCngEnc->hFdCngCom; Word16 psizeDec[NPART]; @@ -288,14 +293,14 @@ void configureFdCngEnc_ivas_fx( set16_fx( psizeDec, 0, NPART ); - hsCom->CngBandwidth = bwidth; + hsCom->CngBandwidth = bwidth; /* Q0 */ move16(); IF( EQ_16( hsCom->CngBandwidth, FB ) ) { hsCom->CngBandwidth = SWB; move16(); } - hsCom->CngBitrate = total_brate; + hsCom->CngBitrate = total_brate; /* Q0 */ move32(); /* NB configuration */ @@ -338,16 +343,16 @@ void configureFdCngEnc_ivas_fx( hsCom->FdCngSetup = FdCngSetup_swb2; } } - hsCom->fftlen = hsCom->FdCngSetup.fftlen; + hsCom->fftlen = hsCom->FdCngSetup.fftlen; /* Q0 */ move16(); - hFdCngEnc->stopFFTbinDec = hsCom->FdCngSetup.stopFFTbin; + hFdCngEnc->stopFFTbinDec = hsCom->FdCngSetup.stopFFTbin; /* Q0 */ move16(); /* Configure the SID quantizer and the Confort Noise Generator */ - hFdCngEnc->startBandDec = hsCom->startBand; + hFdCngEnc->startBandDec = hsCom->startBand; /* Q0 */ move16(); - hFdCngEnc->stopBandDec = add( hsCom->FdCngSetup.sidPartitions[hsCom->FdCngSetup.numPartitions - 1], 1 ); + hFdCngEnc->stopBandDec = add( hsCom->FdCngSetup.sidPartitions[hsCom->FdCngSetup.numPartitions - 1], 1 ); /* Q0 */ move16(); initPartitions( hsCom->FdCngSetup.sidPartitions, hsCom->FdCngSetup.numPartitions, @@ -381,17 +386,17 @@ void configureFdCngEnc_ivas_fx( { case 512: hsCom->fftSineTab_fx = NULL; - hsCom->olapWinAna_fx = olapWinAna512_fx; - hsCom->olapWinSyn_fx = olapWinSyn256_fx; + hsCom->olapWinAna_fx = olapWinAna512_fx; /* Q30 */ + hsCom->olapWinSyn_fx = olapWinSyn256_fx; /* Q15 */ hsCom->fftlenShift = 8; move16(); hsCom->fftlenFac = 32767 /*1.0 Q15*/; move16(); BREAK; case 640: - hsCom->fftSineTab_fx = fftSineTab640_fx; - hsCom->olapWinAna_fx = olapWinAna640_fx; - hsCom->olapWinSyn_fx = olapWinSyn320_fx; + hsCom->fftSineTab_fx = fftSineTab640_fx; /* Q15 */ + hsCom->olapWinAna_fx = olapWinAna640_fx; /* Q30 */ + hsCom->olapWinSyn_fx = olapWinSyn320_fx; /* Q15 */ hsCom->fftlenShift = 9; move16(); hsCom->fftlenFac = 20480 /*0.625 Q15*/; @@ -440,8 +445,8 @@ void resetFdCngEnc_fx( /* st->totalNoise_fx; Q8 Noise estimator - total noise energy */ /* Detect fast increase of totalNoise */ - totalNoiseIncrease = sub( hNoiseEst->totalNoise_fx, st->last_totalNoise_fx ); - st->last_totalNoise_fx = hNoiseEst->totalNoise_fx; + totalNoiseIncrease = sub( hNoiseEst->totalNoise_fx, st->last_totalNoise_fx ); // Q8 + st->last_totalNoise_fx = hNoiseEst->totalNoise_fx; // Q8 move16(); IF( totalNoiseIncrease > 0 ) { @@ -449,17 +454,17 @@ void resetFdCngEnc_fx( { FOR( n = 0; n < TOTALNOISE_HIST_SIZE - 1; n++ ) { - st->totalNoise_increase_hist_fx[n] = st->totalNoise_increase_hist_fx[n + 1]; + st->totalNoise_increase_hist_fx[n] = st->totalNoise_increase_hist_fx[n + 1]; // Q8 move16(); } - st->totalNoise_increase_hist_fx[TOTALNOISE_HIST_SIZE - 1] = totalNoiseIncrease; + st->totalNoise_increase_hist_fx[TOTALNOISE_HIST_SIZE - 1] = totalNoiseIncrease; // Q8 move16(); } ELSE { - st->totalNoise_increase_hist_fx[st->totalNoise_increase_len] = totalNoiseIncrease; + st->totalNoise_increase_hist_fx[st->totalNoise_increase_len] = totalNoiseIncrease; // Q8 move16(); - st->totalNoise_increase_len = add( st->totalNoise_increase_len, 1 ); + st->totalNoise_increase_len = add( st->totalNoise_increase_len, 1 ); // Q0 } } ELSE @@ -471,7 +476,7 @@ void resetFdCngEnc_fx( move16(); FOR( n = 0; n < st->totalNoise_increase_len; n++ ) { - totalNoiseIncrease = add( totalNoiseIncrease, st->totalNoise_increase_hist_fx[n] ); + totalNoiseIncrease = add( totalNoiseIncrease, st->totalNoise_increase_hist_fx[n] ); // Q8 } test(); @@ -518,9 +523,9 @@ void resetFdCngEnc_fx( Returns: void */ -void perform_noise_estimation_enc_fx( Word32 *band_energies, /* i: energy in critical bands without minimum noise floor MODE2_E_MIN */ +void perform_noise_estimation_enc_fx( Word32 *band_energies, /* i: energy in critical bands without minimum noise floor MODE2_E_MIN band_energies_exp*/ Word16 band_energies_exp, /* i: exponent for energy in critical bands without minimum noise floor MODE2_E_MIN */ - Word32 *enerBuffer, + Word32 *enerBuffer, /* enerBuffer_exp */ Word16 enerBuffer_exp, HANDLE_FD_CNG_ENC st /* i/o: FD_CNG structure containing all buffers and variables */ ) @@ -560,8 +565,8 @@ void perform_noise_estimation_enc_fx( Word32 *band_energies, /* i: energy in /* preemphasis compensation and grouping of per bin energies into msPeriodog */ FOR( i = 0; i < nFFTpart; i++ ) { - tmp = L_add( L_shr( band_energies[i], 1 ), L_shr( band_energies[i + NB_BANDS], 1 ) ); - msPeriodog[i] = Mpy_32_16_1( tmp, preemphCompensation_fx[i] ); + tmp = L_add( L_shr( band_energies[i], 1 ), L_shr( band_energies[i + NB_BANDS], 1 ) ); /* exp(band_energies_exp) */ + msPeriodog[i] = Mpy_32_16_1( tmp, preemphCompensation_fx[i] ); /* exp(band_energies_exp + 4) */ move32(); } @@ -569,7 +574,7 @@ void perform_noise_estimation_enc_fx( Word32 *band_energies, /* i: energy in st->msPeriodog_fx_exp_fft = add( band_energies_exp, PREEMPH_COMPENSATION_EXP ); move16(); - numBands = sub( regularStopBand, numCoreBands ); + numBands = sub( regularStopBand, numCoreBands ); /* Q0 */ IF( numBands > 0 ) { @@ -577,7 +582,7 @@ void perform_noise_estimation_enc_fx( Word32 *band_energies, /* i: energy in FOR( j = numCoreBands; j < regularStopBand; j++ ) { - *ptr_per = Mpy_32_16_1( enerBuffer[j], st->hFdCngCom->scalingFactor ); + *ptr_per = Mpy_32_16_1( enerBuffer[j], st->hFdCngCom->scalingFactor ); /* exp(enerBuffer_exp) */ move32(); ptr_per++; @@ -612,13 +617,13 @@ void perform_noise_estimation_enc_fx( Word32 *band_energies, /* i: energy in FOR( i = 0; i < nFFTpart; i++ ) { - msPeriodog[i] = L_shr( msPeriodog[i], s1 ); + msPeriodog[i] = L_shr( msPeriodog[i], s1 ); // st->msPeriodog_fx_exp_fft move32(); } FOR( i = 0; i < nCLDFBpart; i++ ) { - msPeriodog[nFFTpart + i] = L_shr( msPeriodog[nFFTpart + i], s_min( 31, s2 ) ); + msPeriodog[nFFTpart + i] = L_shr( msPeriodog[nFFTpart + i], s_min( 31, s2 ) ); // st->msPeriodog_fx_exp_fft move32(); } } @@ -681,19 +686,18 @@ void perform_noise_estimation_enc_fx( Word32 *band_energies, /* i: energy in Returns: void */ -Word16 -AdjustFirstSID_fx( - Word16 npart, /* i : number of parts */ - Word32 *msPeriodog, /* i : pointer to periodog vector */ - Word16 msPeriodog_exp, /* i : exponent of periodog vector */ - Word32 *energy_ho, /* i/o : pointer to energy */ - Word16 *energy_ho_exp, /* i/o : pointer to exponent of energy */ - Word32 *msNoiseEst, /* i/o : pointer to estimated noise */ - Word16 *msNoiseEst_exp, /* i/o : pointer to exponent of estimated noise */ - Word32 *msNoiseEst_old, /* i/o : pointer to old estimated noise */ - Word16 *msNoiseEst_old_exp, /* i/o : pointer to exponent of old estimated noise */ - Word16 *active_frame_counter, /* i/o : pointer to active frame counter */ - Encoder_State *stcod /* i : pointer to Coder_State_Plus structure */ +Word16 AdjustFirstSID_fx( + Word16 npart, /* i : number of parts Q0*/ + Word32 *msPeriodog, /* i : pointer to periodog vector msPeriodog_exp */ + Word16 msPeriodog_exp, /* i : exponent of periodog vector */ + Word32 *energy_ho, /* i/o : pointer to energy energy_ho_exp*/ + Word16 *energy_ho_exp, /* i/o : pointer to exponent of energy */ + Word32 *msNoiseEst, /* i/o : pointer to estimated noise msNoiseEst_exp*/ + Word16 *msNoiseEst_exp, /* i/o : pointer to exponent of estimated noise */ + Word32 *msNoiseEst_old, /* i/o : pointer to old estimated noise msNoiseEst_old_exp*/ + Word16 *msNoiseEst_old_exp, /* i/o : pointer to exponent of old estimated noise */ + Word16 *active_frame_counter, /* i/o : pointer to active frame counter Q0*/ + Encoder_State *stcod /* i : pointer to Coder_State_Plus structure */ ) { Word16 i, sc, s1, s2, lambda, lambdaM1, invFac; @@ -706,7 +710,7 @@ AdjustFirstSID_fx( /* Detect the hangover period and the first SID frame at the beginning of each CNG phase */ /* First hangover frame */ - Copy32( msPeriodog, energy_ho, npart ); + Copy32( msPeriodog, energy_ho, npart ); /* exp(msPeriodog_exp) */ *energy_ho_exp = msPeriodog_exp; move16(); @@ -724,8 +728,8 @@ AdjustFirstSID_fx( /* active_frame_counter scaled by (1/1024.0) for compensation */ tmp32 = L_shl( L_deposit_l( add( *active_frame_counter, 1 ) ), WORD32_BITS - 1 - 10 ); tmp32 = BASOP_Util_InvLog2( Mpy_32_16_1( tmp32, -30877 /*-0.94229902485 Q15*/ ) ); - lambda = extract_h( tmp32 ); - lambdaM1 = extract_h( L_sub( 0x7FFFFFFF, tmp32 ) ); + lambda = extract_h( tmp32 ); /* Q15 */ + lambdaM1 = extract_h( L_sub( 0x7FFFFFFF /* 1.0f in Q31*/, tmp32 ) ); } invFac = getNormReciprocalWord16( 1 ); @@ -739,7 +743,7 @@ AdjustFirstSID_fx( FOR( i = 0; i < npart; i++ ) { - msNoiseEst_old[i] = Mpy_32_16_1( msNoiseEst_old[i], lambda ); + msNoiseEst_old[i] = Mpy_32_16_1( msNoiseEst_old[i], lambda ); /* exp(msNoiseEst_old) */ move32(); tmp32 = Mpy_32_16_1( Mpy_32_16_1( energy_ho[i], invFac ), lambdaM1 ); energy_ho[i] = L_add( L_shr( msNoiseEst_old[i], s1 ), L_shr( tmp32, s2 ) ); @@ -756,16 +760,16 @@ AdjustFirstSID_fx( move32(); FOR( i = 0; i < npart; i++ ) { - msNoiseEst_local = L_shr( msNoiseEst[i], s1 ); - energy_ho_local = L_shr( energy_ho[i], s2 ); + msNoiseEst_local = L_shr( msNoiseEst[i], s1 ); /* exp(msNoiseEst + s1) */ + energy_ho_local = L_shr( energy_ho[i], s2 ); /* exp(energy_ho_exp + s2) */ IF( GT_32( msNoiseEst_local, energy_ho_local ) ) { - msNoiseEst[i] = energy_ho_local; + msNoiseEst[i] = energy_ho_local; /* exp(energy_ho_exp + s2) */ move32(); } ELSE { - msNoiseEst[i] = msNoiseEst_local; + msNoiseEst[i] = msNoiseEst_local; /* exp(energy_ho_exp + s2) */ move32(); } if ( msNoiseEst[i] > 0 ) @@ -788,13 +792,13 @@ AdjustFirstSID_fx( IF( NE_32( stcod->core_brate, SID_2k40 ) && NE_32( stcod->core_brate, FRAME_NO_DATA ) ) { /* Count the number of active frames in a row */ - *active_frame_counter = add( *active_frame_counter, 1 ); + *active_frame_counter = add( *active_frame_counter, 1 ); /* Q0 */ move16(); } ELSE { /* Store the noise estimate obtained in the CNG phases */ - Copy32( msNoiseEst, msNoiseEst_old, npart ); + Copy32( msNoiseEst, msNoiseEst_old, npart ); /* exp(msNoiseEst_exp) */ *msNoiseEst_old_exp = *msNoiseEst_exp; move16(); } @@ -825,14 +829,14 @@ AdjustFirstSID_fx( Returns: void */ -static void msvq_encoder( const Word16 *const cb[], /* i : Codebook (indexed cb[*stages][levels][p]) scaled with 8 bits */ - Word16 u[], /* i : Vector to be encoded (prediction and mean removed) */ - const Word16 levels[], /* i : Number of levels in each stage */ - Word16 maxC, /* i : Tree search size */ - Word16 stages, /* i : Number of stages */ - Word16 N, /* i : Vector dimension */ - Word16 maxN, /* i : Codebook vector dimension */ - Word16 Idx[] /* o : Indices */ +static void msvq_encoder( const Word16 *const cb[], /* i : Codebook (indexed cb[*stages][levels][p]) scaled with 8 bits Q9.7*/ + Word16 u[], /* i : Vector to be encoded (prediction and mean removed) Q9.7*/ + const Word16 levels[], /* i : Number of levels in each stage Q0*/ + Word16 maxC, /* i : Tree search size Q0*/ + Word16 stages, /* i : Number of stages Q0*/ + Word16 N, /* i : Vector dimension Q0*/ + Word16 maxN, /* i : Codebook vector dimension Q0*/ + Word16 Idx[] /* o : Indices Q0*/ ) { Word32 *dist[2]; @@ -947,11 +951,7 @@ static void msvq_encoder( const Word16 *const cb[], /* i : Codebook (indexed cb tmp = L_add( dist[0][c], L_sub( en, L_shl( t1, 1 ) ) ); BASOP_SATURATE_WARNING_OFF_EVS -#ifdef BASOP_NOGLOB t1 = L_sub_sat( tmp, dist[1][p_max] ); -#else - t1 = L_sub( tmp, dist[1][p_max] ); -#endif BASOP_SATURATE_WARNING_ON_EVS IF( t1 <= 0 ) /* IF (L_sub(L_shr(tmp,1), L_shr(dist[1][p_max],1) ) <= 0 ) */ @@ -998,7 +998,7 @@ static void msvq_encoder( const Word16 *const cb[], /* i : Codebook (indexed cb pTmp += N; /* Get indices that were used for parent node */ - Copy( indices[0] + parents[c] * stages, indices[1] + c * stages, s ); + Copy( indices[0] + parents[c] * stages, indices[1] + c * stages, s ); // Q0 } m = maxC; move16(); @@ -1057,19 +1057,6 @@ void FdCng_encodeSID_fx( HANDLE_FD_CNG_ENC stenc, /* i/o: pointer to FD_CNG stru BSTR_ENC_HANDLE hBstr = corest->hBstr; HANDLE_FD_CNG_COM st; Word16 maxC_37bits = FD_CNG_maxC_37bits, stages_37bits = FD_CNG_stages_37bits, maxN_37bits = FD_CNG_maxN_37bits; -#ifdef IVAS_CODE_CNG - float *invTrfMatrix; - float tmpRAM[FDCNG_VQ_MAX_LEN][FDCNG_VQ_DCT_MAXTRUNC]; - float dct_target[FDCNG_VQ_DCT_MAXTRUNC]; - float tot_sig_ext[FDCNG_VQ_MAX_LEN]; - const float gain_q_offset = ( st->element_mode == EVS_MONO ) ? GAIN_Q_OFFSET_EVS : GAIN_Q_OFFSET_IVAS; - /* Init */ - N = hFdCngEnc->npartDec; - - invTrfMatrix = (float *) tmpRAM; /* dynamically filled */ - set_zero( v, FDCNG_VQ_MAX_LEN ); -#endif - /* Init */ st = stenc->hFdCngCom; @@ -1119,29 +1106,6 @@ void FdCng_encodeSID_fx( HANDLE_FD_CNG_ENC stenc, /* i/o: pointer to FD_CNG stru v16[i] = extract_h( L_sub( v[i], gain ) ); } -#ifdef IVAS_CODE_CNG - IF( st->element_mode != EVS_MONO ) - { - /* DCT domain compressed/truncated indices used for first stage */ - /* quantization with stage1 stored in DCT24 domain, stages 2 through 6 directly dearched - in FDCNG band domain - */ - if ( N == FDCNG_VQ_MAX_LEN_WB ) - { - create_IDCT_N_Matrix( invTrfMatrix, N, FDCNG_VQ_DCT_MAXTRUNC, sizeof( tmpRAM ) / ( sizeof( float ) ) ); - /* truncated DCT21 analysis */ - dctT2_N_apply_matrix( (const float *) v, dct_target, FDCNG_VQ_DCT_MAXTRUNC, N, invTrfMatrix, FDCNG_VQ_DCT_MAXTRUNC, DCT_T2_21_XX ); - /* truncated IDCT21 extension to 24 bands */ - extend_dctN_input( v, dct_target, N, tot_sig_ext, FDCNG_VQ_MAX_LEN, invTrfMatrix, FDCNG_VQ_DCT_MAXTRUNC, IDCT_T2_XX_21 ); - - mvr2r( tot_sig_ext, v, FDCNG_VQ_MAX_LEN ); /* write extended result as input to VQ stage #1 */ - } - create_IDCT_N_Matrix( invTrfMatrix, FDCNG_VQ_MAX_LEN, FDCNG_VQ_DCT_MAXTRUNC, sizeof( tmpRAM ) / ( sizeof( float ) ) ); - msvq_enc_fx( cdk_37bits_ivas, NULL, NULL, v, levels_37bits, FD_CNG_maxC_37bits, FD_CNG_stages_37bits, w, N, FD_CNG_maxN_37bits, 1, invTrfMatrix, indices ); - msvq_dec( cdk_37bits_ivas, NULL, NULL, FD_CNG_stages_37bits, N, FD_CNG_maxN_37bits, indices, 1, invTrfMatrix, v, NULL ); - } - ELSE -#endif { /* MSVQ encoder */ msvq_encoder( cdk_37bits, v16, levels_37bits, maxC_37bits, stages_37bits, N, maxN_37bits, indices ); @@ -1165,28 +1129,14 @@ void FdCng_encodeSID_fx( HANDLE_FD_CNG_ENC stenc, /* i/o: pointer to FD_CNG stru /* Apply bitrate-dependant scale */ -#ifdef IVAS_CODE_CNG - if ( st->element_mode > EVS_MONO ) - { - apply_scale( &gain, hFdCngCom->CngBandwidth, hFdCngCom->CngBitrate, scaleTableStereo, SIZE_SCALE_TABLE_STEREO ); - } - else -#endif { apply_scale( &gain, st->CngBandwidth, st->CngBitrate, scaleTableMono, SIZE_SCALE_TABLE_MONO ); } -#ifdef IVAS_CODE_CNG - /* Quantize gain, Q14.23 format */ - gain = L_add( gain, L_shr( gain, 1 ) ); - gain = L_add( gain, gain_q_offset /*gain_q_offset+.5 Q23*/ ); - index = extract_l( L_shr( gain, WORD32_BITS - 1 - 8 ) ); -#else /* Quantize gain, Q14.23 format */ gain = L_add( gain, L_shr( gain, 1 ) ); gain = L_add( gain, 507510784l /*60.5 Q23*/ ); index = extract_l( L_shr( gain, WORD32_BITS - 1 - 8 ) ); -#endif if ( index < 0 ) { @@ -1199,17 +1149,11 @@ void FdCng_encodeSID_fx( HANDLE_FD_CNG_ENC stenc, /* i/o: pointer to FD_CNG stru index = 127; move16(); } -#ifndef IVAS_CODE_CNG + /* gain Q14.23 format */ gain = L_shl( L_deposit_l( index ), WORD32_BITS - 1 - 8 ); gain = L_sub( gain, 503316480l /*60.0 Q23*/ ); gain = Mpy_32_16_1( gain, 21845 /*2.0f/3.0f Q15*/ ); -#else - /* gain Q14.23 format */ - gain = L_shl( L_deposit_l( index ), WORD32_BITS - 1 - 8 ); - gain = L_sub( gain, gain_q_offset /*60.0 Q23*/ ); - gain = Mpy_32_16_1( gain, 21845 /*2.0f/3.0f Q15*/ ); -#endif /* Apply gain and undo log */ @@ -1531,7 +1475,7 @@ void generate_comfort_noise_enc_fx( Encoder_State *stcod, { FOR( i = 0; i < st->frameSize; i++ ) { - timeDomainOutput[i] = add( timeDomainOutput[i], shr_r( hTcxEnc->old_out_fx[i + NS2SA( stcod->sr_core, N_ZERO_MDCT_NS )], hTcxEnc->Q_old_out ) ); + timeDomainOutput[i] = add( timeDomainOutput[i], shr_r( hTcxEnc->old_out_fx[i + NS2SA_FX2( stcod->sr_core, N_ZERO_MDCT_NS )], hTcxEnc->Q_old_out ) ); move16(); } } @@ -1634,11 +1578,7 @@ void generate_comfort_noise_enc_fx( Encoder_State *stcod, s = sub( 15 - NOISE_HEADROOM, noiseExp ); FOR( i = 0; i < N; i++ ) { -#ifdef BASOP_NOGLOB noise[i] = shr_sat( mult( noise[i], gain16 ), s ); -#else - noise[i] = shr( mult( noise[i], gain16 ), s ); -#endif move16(); } @@ -1647,11 +1587,7 @@ void generate_comfort_noise_enc_fx( Encoder_State *stcod, s = sub( 15 - NOISE_HEADROOM, ( sub( 15, Q_syn ) ) ); FOR( i = 0; i < lpcorder; i++ ) { -#ifdef BASOP_NOGLOB old_syn_pe_tmp[i] = shr_sat( old_syn_pe[i], s ); -#else - old_syn_pe_tmp[i] = shr( old_syn_pe[i], s ); -#endif move16(); } @@ -1728,10 +1664,10 @@ void generate_comfort_noise_enc_ivas_fx( Encoder_State *stcod, cngNoiseLevel = st->cngNoiseLevel; cngNoiseLevelExp = st->cngNoiseLevelExp; move16(); - ptr_level = cngNoiseLevel; + ptr_level = cngNoiseLevel; // cngNoiseLevelExp seed = &( st->seed ); - fftBuffer = st->fftBuffer; - timeDomainOutput = st->timeDomainBuffer; + fftBuffer = st->fftBuffer; // st->fftBuffer_exp + timeDomainOutput = st->timeDomainBuffer; // Q15 /* Generate Gaussian random noise in real and imaginary parts of the FFT bins @@ -1748,7 +1684,7 @@ void generate_comfort_noise_enc_ivas_fx( Encoder_State *stcod, randGaussExp = CNG_RAND_GAUSS_SHIFT; move16(); - cnt = sub( stenc->stopFFTbinDec, stenc->startBandDec ); + cnt = sub( stenc->stopFFTbinDec, stenc->startBandDec ); // Q)=0 IF( stenc->startBandDec == 0 ) { /* DC component in FFT */ @@ -1886,7 +1822,7 @@ void generate_comfort_noise_enc_ivas_fx( Encoder_State *stcod, seed_loc = st->seed; move16(); - N = st->frameSize; + N = st->frameSize; // Q0 move16(); N2 = shr( st->frameSize, 1 ); @@ -1925,7 +1861,7 @@ void generate_comfort_noise_enc_ivas_fx( Encoder_State *stcod, { FOR( i = 0; i < st->frameSize; i++ ) { - timeDomainOutput[i] = add( timeDomainOutput[i], shr_r( hTcxEnc->old_out_fx[i + NS2SA( stcod->sr_core, N_ZERO_MDCT_NS )], hTcxEnc->Q_old_out ) ); + timeDomainOutput[i] = add( timeDomainOutput[i], shr_r( hTcxEnc->old_out_fx[i + NS2SA_FX2( stcod->sr_core, N_ZERO_MDCT_NS )], hTcxEnc->Q_old_out ) ); move16(); } } @@ -1942,7 +1878,7 @@ void generate_comfort_noise_enc_ivas_fx( Encoder_State *stcod, FOR( i = 0; i < N2; i++ ) { - timeDomainOutput[i] = add( timeDomainOutput[i], shl( hTcxEnc->Txnq[i], TCX_IMDCT_HEADROOM ) ); + timeDomainOutput[i] = add( timeDomainOutput[i], shl( hTcxEnc->Txnq[i], TCX_IMDCT_HEADROOM ) ); // Q15 move16(); } } @@ -1972,6 +1908,7 @@ void generate_comfort_noise_enc_ivas_fx( Encoder_State *stcod, preemph_fac = stcod->preemph_fac; move16(); Q_exc = Q_new; + move16(); Q_syn = sub( Q_new, 1 ); /* shift to be in the range of values supported by getNormReciprocalWord16() */ @@ -2029,11 +1966,7 @@ void generate_comfort_noise_enc_ivas_fx( Encoder_State *stcod, s = sub( 15 - NOISE_HEADROOM, noiseExp ); FOR( i = 0; i < N; i++ ) { -#ifdef BASOP_NOGLOB noise[i] = shr_sat( mult( noise[i], gain16 ), s ); -#else - noise[i] = shr( mult( noise[i], gain16 ), s ); -#endif move16(); } @@ -2042,11 +1975,7 @@ void generate_comfort_noise_enc_ivas_fx( Encoder_State *stcod, s = sub( 15 - NOISE_HEADROOM, ( sub( 15, Q_syn ) ) ); FOR( i = 0; i < lpcorder; i++ ) { -#ifdef BASOP_NOGLOB old_syn_pe_tmp[i] = shr_sat( old_syn_pe[i], s ); -#else - old_syn_pe_tmp[i] = shr( old_syn_pe[i], s ); -#endif move16(); } @@ -2093,12 +2022,12 @@ void generate_comfort_noise_enc_ivas_fx( Encoder_State *stcod, /*! r: CNG energy */ Word16 cng_energy_fx( - const Word16 element_mode, /* i : element mode */ - const Word16 bwidth, /* i : audio bandwidh */ - const Word16 CNG_mode, /* i : mode for DTX configuration */ - const Word16 CNG_att, /* i : attenuation factor for CNG */ - const Word16 *exc, /* i : input signal */ - const Word16 len, /* i : vector length */ + const Word16 element_mode, /* i : element mode Q0*/ + const Word16 bwidth, /* i : audio bandwidh Q0*/ + const Word16 CNG_mode, /* i : mode for DTX configuration Q0*/ + const Word16 CNG_att, /* i : attenuation factor for CNG Q7*/ + const Word16 *exc, /* i : input signal Q_new*/ + const Word16 len, /* i : vector length Q0*/ const Word16 Q_new /* i : Input scaling */ ) { @@ -2153,12 +2082,7 @@ Word16 cng_energy_fx( test(); IF( EQ_16( element_mode, IVAS_CPE_DFT ) || EQ_16( element_mode, IVAS_CPE_TD ) ) { - // PMT(" IVAS CNG ener computing is missing") -#ifdef IVAS_CODE - enr += CNG_att * FAC_LOG2 / 10.0f; -#else (void) CNG_att; -#endif } ELSE IF( NE_16( bwidth, NB ) ) { @@ -2193,11 +2117,11 @@ Word16 cng_energy_fx( /*! r: CNG energy */ Word16 cng_energy_ivas_fx( - const Word16 element_mode, /* i : element mode */ - const Word16 bwidth, /* i : audio bandwidh */ - const Word16 CNG_mode, /* i : mode for DTX configuration */ - const Word16 CNG_att, /* i : attenuation factor for CNG Q7 */ - const Word16 *exc, /* i : input signal */ + const Word16 element_mode, /* i : element mode Q0*/ + const Word16 bwidth, /* i : audio bandwidh Q0*/ + const Word16 CNG_mode, /* i : mode for DTX configuration Q0*/ + const Word16 CNG_att, /* i : attenuation factor for CNG Q7*/ + const Word16 *exc, /* i : input signal Q_new*/ const Word16 len, /* i : vector length */ const Word16 Q_new /* i : Input scaling */ ) @@ -2264,11 +2188,13 @@ Word16 cng_energy_ivas_fx( { /* Bitrate adapted attenuation */ att = ENR_ATT_fx[CNG_mode]; + move16(); } ELSE { /* Use least attenuation for higher bitrates */ att = ENR_ATT_fx[4]; + move16(); } } ELSE @@ -2280,3 +2206,1102 @@ Word16 cng_energy_ivas_fx( } return enr; } + +void perform_noise_estimation_enc_ivas_fx( + Word32 *band_energies, /* i: energy in critical bands without minimum noise floor MODE2_E_MIN band_energies_exp*/ + Word16 band_energies_exp, + Word32 *enerBuffer, /* enerBuffer_exp */ + Word16 enerBuffer_exp, + HANDLE_FD_CNG_ENC hFdCngEnc, /* i/o: CNG structure containing all buffers and variables */ + const Word32 input_Fs, /* i : input sampling rate Q0*/ + CPE_ENC_HANDLE hCPE /* i : CPE encoder structure */ +) +{ + Word16 i, j, s, s1, s2; + Word16 numBands; + Word16 numCoreBands = hFdCngEnc->hFdCngCom->numCoreBands; /* Q0 */ + move16(); + Word16 regularStopBand = hFdCngEnc->hFdCngCom->regularStopBand; /* Q0 */ + move16(); + Word16 numSlots = hFdCngEnc->hFdCngCom->numSlots; /* Q0 */ + move16(); + assert( numSlots == 16 ); + + Word32 numSlots_inv_fx = 1073741824; // Q34 of .0625 + move32(); + Word32 *periodog = hFdCngEnc->hFdCngCom->periodog; /* exp(peridog_exp) */ + Word32 *ptr_per_fx = periodog; + Word64 periodog_64; + Word16 periodog_exp[PERIODOGLEN]; + Word16 npart = hFdCngEnc->hFdCngCom->npart; /* Q0 */ + move16(); + Word16 nFFTpart = hFdCngEnc->hFdCngCom->nFFTpart; /* Q0 */ + move16(); + Word16 nCLDFBpart = hFdCngEnc->hFdCngCom->nCLDFBpart; /* Q0 */ + move16(); + + Word16 *psize = hFdCngEnc->hFdCngCom->psize; // 6Q9 + Word32 *msPeriodog_fx = hFdCngEnc->msPeriodog_fx; + Word32 *msNoiseEst_fx = hFdCngEnc->msNoiseEst_fx; /* exp(msNoiseEst_fx_exp) */ + + Word16 *msLogPeriodog_fx = hFdCngEnc->msLogPeriodog_fx; + Word16 *msLogNoiseEst_fx = hFdCngEnc->msLogNoiseEst_fx; + + Word32 scaleEB_fx = 0; + move32(); + Word32 tmp; + + test(); + IF( hCPE != NULL && hCPE->hStereoDft != NULL ) + { + // band_res_dft = ( (float) input_Fs ) / hCPE->hStereoDft->NFFT; + // chan_width_f = 24000.f / CLDFB_NO_CHANNELS_MAX; + // chan_width_bins = chan_width_f / band_res_dft; + + ///* Scaling of Energy buffer to get energy per sample, same scaling as for band_energies, 3 is to compensate for the 1/3 scaling in calculate_energy_buffer */ + // scaleEB = 3 * 4.0f / ( hCPE->hStereoDft->NFFT * hCPE->hStereoDft->NFFT ); + + ///* Scale with number of bins in one band */ + // scaleEB = scaleEB / chan_width_bins; + + SWITCH( input_Fs ) + { + case 8000: + scaleEB_fx = 251648; // Q35 + move32(); + BREAK; + case 16000: + scaleEB_fx = 62912; // Q35 + move32(); + BREAK; + case 32000: + scaleEB_fx = 15728; // Q35 + move32(); + BREAK; + case 48000: + scaleEB_fx = 6991; // Q35 + move32(); + BREAK; + default: + assert( 0 && "invalid sample rate" ); + } + } + ELSE + { + scaleEB_fx = Mpy_32_32( numSlots_inv_fx, L_deposit_l( hFdCngEnc->hFdCngCom->scalingFactor ) ); // Q34 + Q30 - Q31 = Q33 + scaleEB_fx = L_shl( scaleEB_fx, 2 ); // Q35 + } + + /* preemphasis compensation and grouping of per bin energies into msPeriodog */ + FOR( i = 0; i < nFFTpart; i++ ) + { + tmp = L_add( L_shr( band_energies[i], 1 ), L_shr( band_energies[i + NB_BANDS], 1 ) ); + msPeriodog_fx[i] = Mpy_32_16_1( tmp, preemphCompensation_fx[i] ); + move32(); + } + + /* exponent for fft part of msPeriodog */ + hFdCngEnc->msPeriodog_fx_exp_fft = add( band_energies_exp, PREEMPH_COMPENSATION_EXP ); + move16(); + + Word16 max_exp = -31; + move16(); + i = 0; + move16(); + /* Adjust to the desired time resolution by averaging the periodograms over the time slots */ + FOR( j = numCoreBands; j < regularStopBand; j++ ) + { + periodog_64 = W_mult_32_32( enerBuffer[j], scaleEB_fx ); + Word16 scale = W_norm( periodog_64 ); + *ptr_per_fx = W_extract_h( W_shl( periodog_64, scale ) ); + move32(); + periodog_exp[i] = sub( Q31, add( add( sub( Q31, enerBuffer_exp ), 35 - 31 ), scale ) ); + move16(); + max_exp = s_max( max_exp, periodog_exp[i] ); + + ptr_per_fx++; + i++; + } + /* exponent for cldfb part of msPeriodog */ + // hFdCngEnc->hFdCngCom->exp_cldfb_periodog = add( sub( enerBuffer_exp, 4 ), CLDFBscalingFactor_EXP ); + // move16(); + + numBands = sub( regularStopBand, numCoreBands ); /* Q0 */ + FOR( i = 0; i < numBands; i++ ) + { + + periodog[i] = L_shr( periodog[i], sub( max_exp, periodog_exp[i] ) ); + + move16(); + } + hFdCngEnc->hFdCngCom->exp_cldfb_periodog = max_exp; + move16(); + IF( numBands > 0 ) + { + ///* Adjust CLDFB filterbank to the desired frequency resolution by averaging over spectral partitions for SID transmission */ + bandcombinepow( + periodog, + hFdCngEnc->hFdCngCom->exp_cldfb_periodog, + numBands, + hFdCngEnc->hFdCngCom->CLDFBpart, + nCLDFBpart, + hFdCngEnc->hFdCngCom->CLDFBpsize_inv, + &msPeriodog_fx[nFFTpart], + &hFdCngEnc->msPeriodog_fx_exp_cldfb ); + + ///* find common exponent for fft part and cldfb part of msperiodog */ + s1 = getScaleFactor32( msPeriodog_fx, nFFTpart ); + s2 = getScaleFactor32( &msPeriodog_fx[nFFTpart], nCLDFBpart ); + + s = s_max( sub( hFdCngEnc->msPeriodog_fx_exp_fft, s1 ), sub( hFdCngEnc->msPeriodog_fx_exp_cldfb, s2 ) ); + s1 = sub( s, hFdCngEnc->msPeriodog_fx_exp_fft ); + s2 = sub( s, hFdCngEnc->msPeriodog_fx_exp_cldfb ); + + hFdCngEnc->msPeriodog_fx_exp_fft = s; + move16(); + hFdCngEnc->msPeriodog_fx_exp_cldfb = s; + move16(); + + FOR( i = 0; i < nFFTpart; i++ ) + { + msPeriodog_fx[i] = L_shr( msPeriodog_fx[i], s1 ); /* hFdCngEnc->msPeriodog_fx_exp_fft */ + move32(); + } + + FOR( i = 0; i < nCLDFBpart; i++ ) + { + msPeriodog_fx[nFFTpart + i] = L_shr( msPeriodog_fx[nFFTpart + i], s_min( 31, s2 ) ); /* hFdCngEnc->msPeriodog_fx_exp_fft */ + move32(); + } + } + /* exponent for entire msPeriodog vector */ + hFdCngEnc->msPeriodog_fx_exp = hFdCngEnc->msPeriodog_fx_exp_fft; + move16(); + + /* Compress MS inputs */ + // compress_range_flt( msPeriodog, msLogPeriodog, npart ); + compress_range( msPeriodog_fx, hFdCngEnc->msPeriodog_fx_exp, msLogPeriodog_fx, npart ); + + + /* Call the minimum statistics routine for noise estimation */ + + minimum_statistics_fx( npart, nFFTpart, psize, msLogPeriodog_fx, hFdCngEnc->msNoiseFloor_fx, msLogNoiseEst_fx, hFdCngEnc->msAlpha_fx, hFdCngEnc->msPsd_fx, hFdCngEnc->msPsdFirstMoment_fx, + hFdCngEnc->msPsdSecondMoment_fx, hFdCngEnc->msMinBuf_fx, hFdCngEnc->msBminWin_fx, hFdCngEnc->msBminSubWin_fx, hFdCngEnc->msCurrentMin_fx, hFdCngEnc->msCurrentMinOut_fx, hFdCngEnc->msCurrentMinSubWindow_fx, hFdCngEnc->msLocalMinFlag, hFdCngEnc->msNewMinFlag, hFdCngEnc->msPeriodogBuf_fx, &( hFdCngEnc->msPeriodogBufPtr ), hFdCngEnc->hFdCngCom, + ENC, ( hCPE == NULL ) ? 0 : hCPE->element_mode ); + + /* Expand MS outputs */ + expand_range( msLogNoiseEst_fx, msNoiseEst_fx, &hFdCngEnc->msNoiseEst_fx_exp, hFdCngEnc->hFdCngCom->npart ); + + return; +} + + +/*-------------------------------------------------------------------* + * FdCng_encodeSID() + * + * Generate a bitstream out of the partition levels + *-------------------------------------------------------------------*/ +void FdCng_encodeSID_ivas_fx( + Encoder_State *st /* i/o: encoder state structure */ +) +{ + Word16 N; + HANDLE_FD_CNG_ENC hFdCngEnc = st->hFdCngEnc; + HANDLE_FD_CNG_COM hFdCngCom = hFdCngEnc->hFdCngCom; + BSTR_ENC_HANDLE hBstr = st->hBstr; + + Word32 *invTrfMatrix_fx, *E_fx; + Word32 tmpRAM_fx[FDCNG_VQ_MAX_LEN][FDCNG_VQ_DCT_MAXTRUNC]; + Word32 v_fx[32], gain_fx, e_fx, temp; + Word16 w_fx[32], indices[32], exp[32]; + Word32 dct_target_fx[FDCNG_VQ_DCT_MAXTRUNC]; + Word32 tot_sig_ext_fx[FDCNG_VQ_MAX_LEN]; + Word16 v_e, gain_q_offset, preemph_fac; + Word16 i, index; + + gain_q_offset = GAIN_Q_OFFSET_IVAS_FX_Q0; + move16(); + + if ( st->element_mode == EVS_MONO ) + { + gain_q_offset = GAIN_Q_OFFSET_EVS_FX_Q0; + move16(); + } + + preemph_fac = st->preemph_fac; // Q15 + move16(); + + /* Init */ + N = hFdCngEnc->npartDec; + move16(); + + E_fx = hFdCngEnc->msNoiseEst_fx; + + invTrfMatrix_fx = (Word32 *) tmpRAM_fx; /* dynamically filled */ + + set_zero_fx( v_fx, FDCNG_VQ_MAX_LEN ); + + /* Convert to LOG */ + e_fx = 0; + move32(); + FOR( i = 0; i < N; i++ ) + { + IF( E_fx[i] == 0 ) + { + /* 10 * log(1e-4) = 10 * (-4) = -40 */ + v_fx[i] = -41943040; // -40.0 in Q20 + move32(); + } + ELSE + { + v_fx[i] = Mpy_32_32( 671088640 /*10 in Q26*/, BASOP_Util_Log10( E_fx[i], hFdCngEnc->msNoiseEst_fx_exp ) ); // Q20 = 26+25-31 + move32(); + } + e_fx = L_add( e_fx, v_fx[i] ); // Q20 + } + + /* Normalize MSVQ input */ + gain_fx = 0; + move32(); + FOR( i = N_GAIN_MIN; i < N_GAIN_MAX; i++ ) + { + gain_fx = L_add( gain_fx, v_fx[i] ); // Q20 + } + + /*gain /= (float) ( N_GAIN_MAX - N_GAIN_MIN );*/ + gain_fx = Mpy_32_32( gain_fx, 165191050 /* 1/13 in Q31*/ ); // Q20 + + FOR( i = 0; i < N; i++ ) + { + v_fx[i] = L_sub( v_fx[i], gain_fx ); // Q20 + move32(); + } + + v_e = 11; // Q20 + move16(); + + /* MSVQ encoder */ + set_val_Word16( w_fx, ONE_IN_Q8, N ); + + IF( st->element_mode != EVS_MONO ) + { + /* DCT domain compressed/truncated indices used for first stage */ + /* quantization with stage1 stored in DCT24 domain, stages 2 through 6 directly dearched + in FDCNG band domain + */ + IF( EQ_16( N, FDCNG_VQ_MAX_LEN_WB ) ) + { + /* truncated DCT21 analysis */ + create_IDCT_N_Matrix_fx( invTrfMatrix_fx, N, FDCNG_VQ_DCT_MAXTRUNC, sizeof( tmpRAM_fx ) / ( sizeof( Word32 ) ) ); // Q31 + + dctT2_N_apply_matrix_fx( v_fx /*Q20*/, dct_target_fx, FDCNG_VQ_DCT_MAXTRUNC, N, invTrfMatrix_fx, FDCNG_VQ_DCT_MAXTRUNC, DCT_T2_21_XX ); // Q20 + + /* truncated IDCT21 extension to 24 bands */ + extend_dctN_input_fx( v_fx, dct_target_fx, N, tot_sig_ext_fx, FDCNG_VQ_MAX_LEN, invTrfMatrix_fx, FDCNG_VQ_DCT_MAXTRUNC, IDCT_T2_XX_21 ); // Q20 + + Copy32( tot_sig_ext_fx, v_fx, FDCNG_VQ_MAX_LEN ); /* write extended result as input to VQ stage #1 */ // Q20 + } + + create_IDCT_N_Matrix_fx( invTrfMatrix_fx, FDCNG_VQ_MAX_LEN, FDCNG_VQ_DCT_MAXTRUNC, sizeof( tmpRAM_fx ) / ( sizeof( Word32 ) ) ); // Q31 + + msvq_enc_ivas_fx( ivas_cdk_37bits_fx, Q7, NULL, NULL, v_fx, v_e, levels_37bits, FD_CNG_maxC_37bits, FD_CNG_stages_37bits, w_fx, N, FD_CNG_maxN_37bits, 1, invTrfMatrix_fx, indices ); + + msvq_dec_fx( ivas_cdk_37bits_fx, NULL, NULL, FD_CNG_stages_37bits, N, FD_CNG_maxN_37bits, indices, 1, invTrfMatrix_fx, v_fx, NULL, 7 ); + + v_e = sub( 31, sub( 20, find_guarded_bits_fx( N ) ) ); + } + ELSE + { /* EVS_MONO tables */ + msvq_enc_ivas_fx( ivas_cdk_37bits_fx, Q7, NULL, NULL, v_fx, v_e, levels_37bits, FD_CNG_maxC_37bits, FD_CNG_stages_37bits, w_fx, N, FD_CNG_maxN_37bits, 0, NULL, indices ); + + msvq_dec_fx( ivas_cdk_37bits_fx, NULL, NULL, FD_CNG_stages_37bits, N, FD_CNG_maxN_37bits, indices, 0, NULL, v_fx, NULL, 7 ); + + v_e = sub( 31, sub( 20, find_guarded_bits_fx( N ) ) ); + } + + /* Compute gain */ + gain_fx = 0; + move32(); + FOR( i = 0; i < N; i++ ) + { + gain_fx = L_add( gain_fx, v_fx[i] ); // Q = 31 - v_e + } + + e_fx = L_shl( e_fx, sub( 11, v_e ) ); // Q = 31 - v_e + gain_fx = Mpy_32_16_1( L_sub( e_fx, gain_fx ), div_s( 1, N ) ); // Q = 31 - v_e + gain_fx = L_shl( gain_fx, sub( v_e, 8 ) ); // Q23 + + /* Apply bitrate-dependant scale */ + IF( st->element_mode > EVS_MONO ) + { + apply_scale( &gain_fx, hFdCngCom->CngBandwidth, hFdCngCom->CngBitrate, scaleTableStereo, SIZE_SCALE_TABLE_STEREO ); + } + ELSE + { + apply_scale( &gain_fx, hFdCngCom->CngBandwidth, hFdCngCom->CngBitrate, scaleTableMono, SIZE_SCALE_TABLE_MONO ); + } + + /* Quantize gain */ + temp = Madd_32_32( L_shl( gain_q_offset, 22 ), gain_fx, 1610612736 /*1.5 in Q30*/ ); // Q22 + index = extract_l( L_shr( L_add( temp, ONE_IN_Q21 ), 22 ) ); // Q0 + + if ( index < 0 ) + { + index = 0; + move16(); + } + + if ( GT_16( index, 127 ) ) + { + index = 127; + move16(); + } + + gain_fx = L_shl( L_mult0( sub( index, gain_q_offset ), 21845 /*1.5 in Q15*/ ), sub( 16, v_e ) ); // Q = 31-v_e + + /* Apply gain and undo log */ + FOR( i = 0; i < N; i++ ) + { + temp = Mpy_32_32( L_add( v_fx[i], gain_fx ), 214748365 /* 0.1 in Q31*/ ); // Q = 31-v_e + hFdCngCom->sidNoiseEst[i] = BASOP_Util_fPow( 10, 31, temp, v_e, &exp[i] ); + move32(); + } + + maximum_s( exp, N, &hFdCngCom->sidNoiseEstExp ); + + FOR( i = 0; i < N; i++ ) + { + hFdCngCom->sidNoiseEst[i] = L_shr( hFdCngCom->sidNoiseEst[i], sub( hFdCngCom->sidNoiseEstExp, exp[i] ) ); // exp = hFdCngCom->sidNoiseEstExp + move32(); + } + + /* NB last band energy compensation */ + IF( hFdCngCom->CngBandwidth == NB ) + { + hFdCngCom->sidNoiseEst[N - 1] = Mpy_32_16_1( hFdCngCom->sidNoiseEst[N - 1], NB_LAST_BAND_SCALE ); // exp(hFdCngCom->sidNoiseEstExp) + move32(); + } + + test(); + IF( EQ_16( hFdCngCom->CngBandwidth, SWB ) && LE_32( hFdCngCom->CngBitrate, ACELP_13k20 ) ) + { + hFdCngCom->sidNoiseEst[N - 1] = Mpy_32_16_1( hFdCngCom->sidNoiseEst[N - 1], SWB_13k2_LAST_BAND_SCALE ); // exp(hFdCngCom->sidNoiseEstExp) + move32(); + } + + /* Write bitstream */ + IF( EQ_16( st->codec_mode, MODE2 ) ) + { + FOR( i = 0; i < FD_CNG_stages_37bits; i++ ) + { + push_next_indice( hBstr, indices[i], bits_37bits[i] ); + } + + push_next_indice( hBstr, index, 7 ); + } + ELSE + { + Word16 is_frame_len_16k = 0; + move16(); + if ( EQ_16( st->L_frame, L_FRAME16k ) ) + { + is_frame_len_16k = 1; + move16(); + } + push_indice( hBstr, IND_SID_TYPE, 1, 1 ); + push_indice( hBstr, IND_BWIDTH, st->bwidth, 2 ); + push_indice( hBstr, IND_ACELP_16KHZ, is_frame_len_16k, 1 ); + + FOR( i = 0; i < FD_CNG_stages_37bits; i++ ) + { + push_indice( hBstr, IND_LSF, indices[i], bits_37bits[i] ); + } + + push_indice( hBstr, IND_ENERGY, index, 7 ); + } + + /* Interpolate the bin/band-wise levels from the partition levels */ + scalebands( hFdCngCom->sidNoiseEst, hFdCngEnc->partDec, hFdCngEnc->npartDec, hFdCngEnc->midbandDec, hFdCngEnc->nFFTpartDec, sub( hFdCngEnc->stopBandDec, hFdCngEnc->startBandDec ), hFdCngCom->cngNoiseLevel, 1 ); + hFdCngCom->cngNoiseLevelExp = hFdCngCom->sidNoiseEstExp; + move16(); + + lpc_from_spectrum( hFdCngCom, hFdCngEnc->startBandDec, hFdCngEnc->stopFFTbinDec, preemph_fac ); + + return; +} + + +/*-------------------------------------------------------------------* + * stereoFdCngCoherence() + * + * compute coherence of channels for use in FD-CNG + *-------------------------------------------------------------------*/ +void stereoFdCngCoherence_fx( + Encoder_State **sts, /* i/o: core encoder structures */ + const Word16 last_element_mode, /* i : last element mode Q0*/ + Word16 fft_buf_fx[CPE_CHANNELS][2 * L_FFT], /* i : fft buffers for L and R channels fft_exp*/ + Word16 fft_exp ) +{ + const Word16 *pt_fftL, *pt_fftR; + Word16 i_subfr, i; + Word32 cr, ci, eL, eR; + Word16 cr_exp, ci_exp, eL_exp, eR_exp; + Word32 *mem; + Word16 *mem_exp; + + IF( NE_16( last_element_mode, IVAS_CPE_MDCT ) ) + { + set32_fx( sts[0]->hFdCngEnc->mem_coherence_fx, EPSILON_FX, 4 ); + set16_fx( sts[0]->hFdCngEnc->mem_coherence_exp, 0, 4 ); + } + test(); + test(); + IF( EQ_32( sts[0]->core_brate, -1 ) || EQ_32( sts[1]->core_brate, -1 ) ) + { + /* case: at least one channel has triggered VAD -> ACTIVE FRAME */ + IF( EQ_32( sts[0]->core_brate, -1 ) ) + { + sts[1]->total_brate = sts[0]->total_brate; /* Q0 */ + move32(); + sts[1]->active_cnt = sts[0]->active_cnt; /* Q0 */ + move16(); + if ( GE_32( sts[1]->active_cnt, CNG_TYPE_HO ) ) + { + sts[1]->last_total_brate_cng = -1; + move16(); + } + } + IF( EQ_32( sts[1]->core_brate, -1 ) ) + { + sts[0]->total_brate = sts[1]->total_brate; /* Q0 */ + move32(); + sts[0]->active_cnt = sts[1]->active_cnt; /* Q0 */ + move16(); + if ( GE_16( sts[0]->active_cnt, CNG_TYPE_HO ) ) + { + sts[0]->last_total_brate_cng = -1; + move16(); + } + } + sts[0]->core_brate = -1; + move32(); + sts[1]->core_brate = -1; + move32(); + sts[0]->hDtxEnc->cnt_SID = 0; + move16(); + sts[1]->hDtxEnc->cnt_SID = 0; + move16(); + } + ELSE IF( LE_32( sts[0]->core_brate, SID_2k40 ) && LE_32( sts[1]->core_brate, SID_2k40 ) ) + { + /* case: no VAD for both channels -> INACTIVE FRAME */ + reset_indices_enc_fx( sts[0]->hBstr, sts[0]->hBstr->nb_ind_tot ); + + reset_indices_enc_fx( sts[1]->hBstr, sts[1]->hBstr->nb_ind_tot ); + + /* synchronize SID sending for variable SID rate */ + IF( EQ_32( sts[0]->core_brate, sts[1]->core_brate ) ) + { + sts[0]->core_brate = SID_2k40; + move32(); + sts[1]->core_brate = SID_2k40; + move32(); + } + + /* synchronize SID counters */ + sts[0]->hDtxEnc->cnt_SID = s_min( sts[0]->hDtxEnc->cnt_SID, sts[1]->hDtxEnc->cnt_SID ); /* Q0 */ + sts[1]->hDtxEnc->cnt_SID = sts[0]->hDtxEnc->cnt_SID; /* Q0 */ + move16(); + move16(); + } + + pt_fftL = fft_buf_fx[0]; + pt_fftR = fft_buf_fx[1]; + mem = sts[0]->hFdCngEnc->mem_coherence_fx; /* exp(sts[0]->hFdCngEnc->mem_coherence_exp) */ + mem_exp = sts[0]->hFdCngEnc->mem_coherence_exp; + FOR( i_subfr = 0; i_subfr < 2; i_subfr++ ) + { + cr = ci = eL = eR = EPSILON_FX; + move32(); + move32(); + move32(); + move32(); + cr_exp = ci_exp = eL_exp = eR_exp = 0; + move16(); + move16(); + move16(); + move16(); + + cr = BASOP_Util_Add_Mant32Exp( cr, cr_exp, L_add( L_mult( pt_fftL[0], pt_fftR[0] ), L_mult( pt_fftL[L_FFT / 2], pt_fftR[L_FFT / 2] ) ), shl( fft_exp, 1 ), &cr_exp ); /* exp(cr_exp) */ + eL = BASOP_Util_Add_Mant32Exp( eL, eL_exp, L_add( L_mult( pt_fftL[0], pt_fftL[0] ), L_mult( pt_fftL[L_FFT / 2], pt_fftL[L_FFT / 2] ) ), shl( fft_exp, 1 ), &eL_exp ); /* exp(eL_exp) */ + eR = BASOP_Util_Add_Mant32Exp( eR, eR_exp, L_add( L_mult( pt_fftR[0], pt_fftR[0] ), L_mult( pt_fftR[L_FFT / 2], pt_fftR[L_FFT / 2] ) ), shl( fft_exp, 1 ), &eR_exp ); /* exp(eR_exp) */ + + FOR( i = 1; i < L_FFT / 2; i++ ) + { + cr = BASOP_Util_Add_Mant32Exp( cr, cr_exp, L_add( L_mult( pt_fftL[i], pt_fftR[i] ), L_mult( pt_fftL[L_FFT - i], pt_fftR[L_FFT - i] ) ), shl( fft_exp, 1 ), &cr_exp ); /* exp(cr_exp) */ + ci = BASOP_Util_Add_Mant32Exp( ci, ci_exp, L_add( L_mult( -pt_fftL[i], pt_fftR[L_FFT - i] ), L_mult( pt_fftL[L_FFT - i], pt_fftR[i] ) ), shl( fft_exp, 1 ), &ci_exp ); /* exp(ci_exp) */ + eL = BASOP_Util_Add_Mant32Exp( eL, eL_exp, L_add( L_mult( pt_fftL[i], pt_fftL[i] ), L_mult( pt_fftL[L_FFT - i], pt_fftL[L_FFT - i] ) ), shl( fft_exp, 1 ), &eL_exp ); /* exp(eL_exp) */ + eR = BASOP_Util_Add_Mant32Exp( eR, eR_exp, L_add( L_mult( pt_fftR[i], pt_fftR[i] ), L_mult( pt_fftR[L_FFT - i], pt_fftR[L_FFT - i] ) ), shl( fft_exp, 1 ), &eR_exp ); /* exp(eR_exp) */ + } + test(); + test(); + IF( LE_32( sts[0]->ini_frame, 50 ) || ( sts[0]->vad_flag == 0 && sts[1]->vad_flag == 0 ) ) + { + mem[0] = BASOP_Util_Add_Mant32Exp( Mpy_32_16_1( mem[0], 31129 /*0.95f*/ ), mem_exp[0], Mpy_32_16_1( cr, 1638 /*0.05f*/ ), cr_exp, &mem_exp[0] ); /* exp(mem_exp[0]) */ + move32(); + mem[1] = BASOP_Util_Add_Mant32Exp( Mpy_32_16_1( mem[1], 31129 /*0.95f*/ ), mem_exp[1], Mpy_32_16_1( ci, 1638 /*0.05f*/ ), ci_exp, &mem_exp[1] ); /* exp(mem_exp[1]) */ + move32(); + mem[2] = BASOP_Util_Add_Mant32Exp( Mpy_32_16_1( mem[2], 31129 /*0.95f*/ ), mem_exp[2], Mpy_32_16_1( eL, 1638 /*0.05f*/ ), eL_exp, &mem_exp[2] ); /* exp(mem_exp[2]) */ + move32(); + mem[3] = BASOP_Util_Add_Mant32Exp( Mpy_32_16_1( mem[3], 31129 /*0.95f*/ ), mem_exp[3], Mpy_32_16_1( eR, 1638 /*0.05f*/ ), eR_exp, &mem_exp[3] ); /* exp(mem_exp[3]) */ + move32(); + } + + pt_fftL += L_FFT; + pt_fftR += L_FFT; + } + + Word16 sqr_inp, temp, sqr_out, sqr_inp_exp; + Word32 sqr_inp32 = BASOP_Util_Add_Mant32Exp( Mpy_32_32( mem[0], mem[0] ), shl( mem_exp[0], 1 ), Mpy_32_32( mem[1], mem[1] ), shl( mem_exp[1], 1 ), &sqr_inp_exp ); /* exp(sqr_inp_exp) */ + sqr_inp = BASOP_Util_Divide3232_Scale( sqr_inp32, Mpy_32_32( mem[2], mem[3] ), &temp ); + sqr_inp_exp = add( temp, sub( sqr_inp_exp, add( mem_exp[2], mem_exp[3] ) ) ); + sqr_out = Sqrt16( sqr_inp, &sqr_inp_exp ); + sts[0]->hFdCngEnc->hFdCngCom->coherence_fx = shl_sat( sqr_out, sqr_inp_exp ); // Q15 expected. + move16(); + return; +} + +/*-------------------------------------------------------------------* + * FdCngEncodeMDCTStereoSID() + * + * Encode DTX parameters and noise shapes into SID for MDCT-Stereo DTX + *-------------------------------------------------------------------*/ + +void FdCngEncodeMDCTStereoSID_fx( + CPE_ENC_HANDLE hCPE /* i/o: CPE encoder state structure */ +) +{ + ENC_CORE_HANDLE sts[CPE_CHANNELS]; + Word16 indices[CPE_CHANNELS][FD_CNG_stages_37bits]; + Word16 gain_idx[CPE_CHANNELS]; + Word16 N, stages, ch, p, coh_idx; + Word32 *lr_in_ptr_fx[CPE_CHANNELS]; + Word16 lr_in_ptr_e[CPE_CHANNELS]; + Word32 *ms_ptr_fx[CPE_CHANNELS]; + Word16 ms_ptr_e; + Word32 *lr_out_ptr_fx[CPE_CHANNELS]; + Word16 lr_out_ptr_e[CPE_CHANNELS]; + Word32 logNoiseEst_fx[CPE_CHANNELS][NPART]; + Word32 E_fx[CPE_CHANNELS]; + Word32 gain_fx[CPE_CHANNELS]; + Word16 weights_fx[NPART]; + Word32 side_energy_fx; + Word16 Qside_energy; + Word32 *invTrfMatrix_fx; + Word32 tmpRAM_fx[FDCNG_VQ_MAX_LEN][FDCNG_VQ_DCT_MAXTRUNC]; /*24*18*/ + invTrfMatrix_fx = (Word32 *) tmpRAM_fx; /* dynamically filled */ + Word32 tot_sig_ext_fx[FDCNG_VQ_MAX_LEN], dct_target_fx[CPE_CHANNELS][FDCNG_VQ_DCT_MAXTRUNC]; /* 24 +2*18*/ + Word16 tmp, tmp_e; + Word16 no_side_flag; + Word16 is_inp_ms; + Word16 size_value, temp_e, gb, shift; + Word32 tmp32, t1, t2; + + is_inp_ms = 0; + move16(); + IF( EQ_16( hCPE->hCoreCoder[0]->cng_sba_flag, 1 ) ) + { + is_inp_ms = 1; + move16(); + } + + /* set pointers and initialize */ + FOR( ch = 0; ch < CPE_CHANNELS; ch++ ) + { + sts[ch] = hCPE->hCoreCoder[ch]; + lr_in_ptr_fx[ch] = &sts[ch]->hFdCngEnc->msNoiseEst_fx[0]; /* exp(sts[ch]->hFdCngEnc->msNoiseEst_fx_exp) */ + lr_in_ptr_e[ch] = sts[ch]->hFdCngEnc->msNoiseEst_fx_exp; + ms_ptr_fx[ch] = &logNoiseEst_fx[ch][0]; + lr_out_ptr_fx[ch] = &sts[ch]->hFdCngEnc->hFdCngCom->sidNoiseEst[0]; /* exp(sts[ch]->hFdCngEnc->hFdCngCom->sidNoiseEstExp) */ + lr_out_ptr_e[ch] = sts[ch]->hFdCngEnc->hFdCngCom->sidNoiseEstExp; + } + N = sts[0]->hFdCngEnc->npartDec; /* Q0 */ + move16(); + set16_fx( weights_fx, ONE_IN_Q8, NPART ); + + /* apply log and save energy of original left and right channels */ + FOR( ch = 0; ch < CPE_CHANNELS; ch++ ) + { + // E[ch] = 0.0f; + E_fx[ch] = 0; + move32(); + FOR( p = 0; p < N; p++ ) + { + IF( lr_in_ptr_fx[ch][p] ) + { + t1 = BASOP_Util_Log2( lr_in_ptr_fx[ch][p] ); // Q25 + t2 = L_add( t1, L_shl( lr_in_ptr_e[ch], Q25 ) ); // Q25 + } + ELSE + { + t2 = 0; + move32(); + } + ms_ptr_fx[ch][p] = Mpy_32_32( t2, TEN_MULT_LOG10_2_IN_Q29 ); // Q23 + move32(); + E_fx[ch] = L_add( E_fx[ch], L_shr( ms_ptr_fx[ch][p], 4 ) ); // Q19 + move32(); + } + } + ms_ptr_e = Q31 - Q23; + move16(); + + /* M/S transform on log envelopes */ + IF( is_inp_ms == 0 ) + { + convertToMS_fx( N, ms_ptr_fx[0], ms_ptr_fx[1], ONE_IN_Q30 ); // ms_ptr_e = Q23; + } + + gb = find_guarded_bits_fx( N ); + side_energy_fx = sum2_f_32_fx( ms_ptr_fx[1], N, gb ); + Qside_energy = sub( sub( shl( sub( 31, ms_ptr_e ), 1 ), 31 ), gb ); + + /* do not transmit side shape if initial noise shapes are very similar */ + IF( LE_32( side_energy_fx, L_shl( 214748365, sub( Qside_energy, Q31 ) ) ) ) + { + no_side_flag = 1; + move16(); + } + ELSE + { + no_side_flag = 0; + move16(); + } + + /* Quantize noise shapes */ + FOR( ch = 0; ch < CPE_CHANNELS; ch++ ) + { + /* Normalize MSVQ input */ + gain_fx[ch] = 0; + move32(); + FOR( p = N_GAIN_MIN; p < N_GAIN_MAX; p++ ) + { + tmp32 = Mpy_32_32( ms_ptr_fx[ch][p], 165191050 /* 0.07 in Q31*/ ); // Q23 + gain_fx[ch] = L_add( gain_fx[ch], tmp32 ); // Q23 + move32(); + } + + FOR( p = 0; p < N; p++ ) + { + ms_ptr_fx[ch][p] = L_sub( ms_ptr_fx[ch][p], gain_fx[ch] ); // Q23 + move32(); + } + } + + /* always split channel targetloop */ + + /* extend fdcng envelope from length 21 to a 24 length fdncg domain envelope signal */ + /* High quality cosine smooth basis extension used to not introduce noise in stage#1 DCT24 analysis and subsequent VQ-steps */ + IF( EQ_16( N, FDCNG_VQ_MAX_LEN_WB ) ) + { + size_value = BASOP_Util_Divide1616_Scale( sizeof( tmpRAM_fx ), ( sizeof( Word32 ) ), &temp_e ); /*Q15*/ + size_value = shr( size_value, sub( 15, temp_e ) ); + create_IDCT_N_Matrix_fx( invTrfMatrix_fx, N, FDCNG_VQ_DCT_MAXTRUNC, size_value ); // Q31 /*WB: create truncated IDCT21 matrix */ + for ( ch = 0; ch < CPE_CHANNELS; ch++ ) + { + /* run DCT_N N==21 , truncated at 18/21 ~= 86% , i.e use a bit better better quality in extrapolation , than subsequent DCT24 analysis which is truncated at 75%*/ + /* truncated DCT 21 analysis */ + dctT2_N_apply_matrix_fx( (const Word32 *) ms_ptr_fx[ch], dct_target_fx[ch], FDCNG_VQ_DCT_MAXTRUNC, N, invTrfMatrix_fx, FDCNG_VQ_DCT_MAXTRUNC, DCT_T2_21_XX ); + /* extrapolate extend fdcng envelope signal in the fdncg ienvelope/"time" domain using DCT21 basis vectors, + estimated DCT21 coeffs scaling extended basis vectors are used to create extrapolated length 24 input target envelope signal */ + /* this DCT21 extension does not introduce DCT24 coefficient noise for the subsequent dct24 target analysis, and later in IDCT24 synthesis */ + + /* truncated IDCT 21 extension synthesis */ + extend_dctN_input_fx( ms_ptr_fx[ch], dct_target_fx[ch], N, tot_sig_ext_fx, FDCNG_VQ_MAX_LEN, invTrfMatrix_fx /* DCT_N basis vectors */, FDCNG_VQ_DCT_MAXTRUNC, IDCT_T2_XX_21 ); /* use 18 basis vectors*/ + + Copy32( tot_sig_ext_fx, ms_ptr_fx[ch], FDCNG_VQ_MAX_LEN ); /* write extended result as input to VQ */ + } + } + + size_value = BASOP_Util_Divide1616_Scale( sizeof( tmpRAM_fx ), ( sizeof( Word32 ) ), &temp_e ); /*Q15*/ + size_value = shr( size_value, sub( 15, temp_e ) ); + create_IDCT_N_Matrix_fx( invTrfMatrix_fx, FDCNG_VQ_MAX_LEN, FDCNG_VQ_DCT_MAXTRUNC, size_value ); /*always create/set up IDCT24 matrix in RAM */ + + /* end split */ + FOR( ch = 0; ch < CPE_CHANNELS; ch++ ) + { + /* MSVQ */ + IF( ch ) + { + stages = FD_CNG_JOINT_stages_25bits; + move16(); + } + ELSE + { + stages = FD_CNG_stages_37bits; + move16(); + } + + /* DCT24 domain compressed/truncated indices used for first stage */ + /* mid channel quantization using stages 1 through 6 */ + /* & side channel quantization using stages 1 through 4 */ + + { + msvq_enc_ivas_fx( ivas_cdk_37bits_fx, Q7, NULL, NULL, ms_ptr_fx[ch], ms_ptr_e, levels_37bits, FD_CNG_maxC_37bits, stages, weights_fx, N, FD_CNG_maxN_37bits, 1, invTrfMatrix_fx, indices[ch] ); + msvq_dec_fx( ivas_cdk_37bits_fx, NULL, NULL, stages, N, FD_CNG_maxN_37bits, indices[ch], 1, invTrfMatrix_fx, ms_ptr_fx[ch], NULL, 7 ); + } + } + shift = find_guarded_bits_fx( N ); + ms_ptr_e = sub( 31, sub( 20, shift ) ); + + IF( no_side_flag ) + { + set32_fx( ms_ptr_fx[1], 0, N ); + } + + /* undo M/S */ + IF( is_inp_ms == 0 ) + { + convertToMS_fx( N, ms_ptr_fx[0], ms_ptr_fx[1], ONE_IN_Q31 ); + } + + /* Compute gain against original left and right channels */ + FOR( ch = 0; ch < CPE_CHANNELS; ch++ ) + { + gain_fx[ch] = 0; + move32(); + + tmp_e = 15; + move16(); + tmp = Inv16( N, &tmp_e ); + FOR( p = 0; p < N; p++ ) + { + gain_fx[ch] = L_add( gain_fx[ch], Mpy_32_16_1( ms_ptr_fx[ch][p], shl( tmp, tmp_e ) ) ); // Q23 + move32(); + } + gain_fx[ch] = L_sub( L_shl( Mpy_32_16_1( E_fx[ch], shl( tmp, tmp_e ) ), Q23 - Q19 ), L_shl( gain_fx[ch], sub( ms_ptr_e, 8 ) ) ); // Q23 + move32(); + + apply_scale( &gain_fx[ch], sts[ch]->hFdCngEnc->hFdCngCom->CngBandwidth, sts[ch]->element_brate, scaleTableStereo, SIZE_SCALE_TABLE_STEREO ); + + /* quantize gain */ + gain_idx[ch] = (Word16) Mpy_32_32_r( L_add( gain_fx[ch], 251658240 ), 384 ); // Q23 + move16(); + gain_idx[ch] = s_max( 0, s_min( 127, gain_idx[ch] ) ); + move16(); + + gain_fx[ch] = Mpy_32_16_1( L_shl( sub( gain_idx[ch], GAIN_Q_OFFSET_IVAS_FX_Q0 ), 23 ), 21845 ); // Q23 + move32(); + } + + /* restore channel noise envelopes */ + FOR( ch = 0; ch < CPE_CHANNELS; ch++ ) + { + HANDLE_FD_CNG_ENC hFdCngEnc = sts[ch]->hFdCngEnc; + HANDLE_FD_CNG_COM hFdCngCom = hFdCngEnc->hFdCngCom; + + tmp_e = 0; + move16(); + Word32 pow; + + Word16 e_lr_out[NPART]; + + FOR( p = 0; p < N; p++ ) + { + pow = L_shl( gain_fx[ch], 8 - ms_ptr_e ); + pow = L_add( ms_ptr_fx[ch][p], pow ); + pow = Mpy_32_32( pow, 214748365 ); /*pow = 0.1*/ + lr_out_ptr_fx[ch][p] = BASOP_Util_fPow( 10, 31, pow, ms_ptr_e, &e_lr_out[p] ); + move32(); + tmp_e = s_max( tmp_e, e_lr_out[p] ); + } + + FOR( p = 0; p < N; p++ ) + { + lr_out_ptr_fx[ch][p] = L_shl( lr_out_ptr_fx[ch][p], e_lr_out[p] - tmp_e ); + move32(); + } + lr_out_ptr_e[ch] = tmp_e; + move32(); + + sts[ch]->hFdCngEnc->hFdCngCom->sidNoiseEstExp = tmp_e; + move16(); + + /* scale bands and get scalefactors */ + scalebands( lr_out_ptr_fx[ch], hFdCngEnc->partDec, N, hFdCngEnc->midbandDec, hFdCngEnc->nFFTpartDec, sub( hFdCngEnc->stopBandDec, hFdCngEnc->startBandDec ), hFdCngCom->cngNoiseLevel, 1 ); + hFdCngCom->cngNoiseLevelExp = lr_out_ptr_e[ch]; + move16(); + + lpc_from_spectrum( hFdCngCom, hFdCngEnc->startBandDec, hFdCngEnc->stopFFTbinDec, sts[ch]->preemph_fac ); + + sts[ch]->hDtxEnc->last_CNG_L_frame = sts[ch]->L_frame; + } + + /* quantize channel coherence */ + coh_idx = mult_r( sts[0]->hFdCngEnc->hFdCngCom->coherence_fx, 15 ); + coh_idx = s_max( 0, s_min( coh_idx, 15 ) ); + + /* ---- Write SID bitstream ---- */ + + + /* noise shapes and channel gains */ + FOR( ch = 0; ch < CPE_CHANNELS; ch++ ) + { + IF( ch ) + { + stages = FD_CNG_JOINT_stages_25bits; + sts[ch]->hBstr->ind_list = sts[0]->hBstr->ind_list + sts[0]->hBstr->nb_ind_tot; + + /* side info */ + push_indice( sts[ch]->hBstr, IND_SID_TYPE, coh_idx, 4 ); + push_indice( sts[ch]->hBstr, IND_SID_TYPE, no_side_flag, 1 ); + } + ELSE + { + stages = FD_CNG_stages_37bits; + /* side info */ + push_indice( sts[ch]->hBstr, IND_SID_TYPE, 1, 1 ); + push_indice( sts[ch]->hBstr, IND_BWIDTH, sts[0]->bwidth, 2 ); + push_indice( sts[ch]->hBstr, IND_ACELP_16KHZ, sts[0]->L_frame == L_FRAME16k ? 1 : 0, 1 ); + } + + FOR( Word16 i = 0; i < stages; i++ ) + { + push_indice( sts[ch]->hBstr, IND_LSF, indices[ch][i], bits_37bits[i] ); + } + push_indice( sts[ch]->hBstr, IND_ENERGY, gain_idx[ch], 7 ); + } + + /* pad with zeros to reach common SID frame size */ + push_indice( sts[1]->hBstr, IND_ENERGY, 0, ( IVAS_SID_5k2 - 4400 ) / FRAMES_PER_SEC ); + + return; +} + +/*-------------------------------------------------------------------* + * FdCngEncodeDiracMDCTStereoSID() + * + * Encode DTX parameters and noise shapes into SID for MDCT-Stereo DTX + * together with Dirac + *-------------------------------------------------------------------*/ + +void FdCngEncodeDiracMDCTStereoSID_fx( + CPE_ENC_HANDLE hCPE /* i/o: CPE encoder state structure */ +) +{ + ENC_CORE_HANDLE sts[CPE_CHANNELS]; + Word32 *lr_in_ptr_fx[CPE_CHANNELS]; + Word16 lr_in_ptr_e[CPE_CHANNELS]; + Word32 *ms_ptr_fx[CPE_CHANNELS]; + Word16 ms_ptr_e; + Word32 *lr_out_ptr_fx[CPE_CHANNELS]; + Word16 lr_out_ptr_e[CPE_CHANNELS]; + Word32 logNoiseEst_fx[CPE_CHANNELS][NPART]; + Word32 E_fx[CPE_CHANNELS]; + Word32 gain_fx[CPE_CHANNELS]; + Word16 weights_fx[NPART]; + Word16 N[CPE_CHANNELS]; + Word16 indices[CPE_CHANNELS][FD_CNG_stages_37bits]; + Word16 gain_idx[CPE_CHANNELS]; + Word16 ch, p; + Word16 tmp, tmp_e, shift; + Word32 *invTrfMatrix_fx; + Word32 tmpRAM_fx[FDCNG_VQ_MAX_LEN][FDCNG_VQ_DCT_MAXTRUNC]; + Word32 dct_target_fx[FDCNG_VQ_DCT_MAXTRUNC]; + Word32 tot_sig_ext_fx[FDCNG_VQ_MAX_LEN]; + invTrfMatrix_fx = (Word32 *) tmpRAM_fx; /* dynamically filled */ + Word32 t1, t2, tmp32; + /* set pointers and initialize */ + + FOR( ch = 0; ch < CPE_CHANNELS; ch++ ) + { + sts[ch] = hCPE->hCoreCoder[ch]; + N[ch] = sts[ch]->hFdCngEnc->npartDec; + lr_in_ptr_fx[ch] = &sts[ch]->hFdCngEnc->msNoiseEst_fx[0]; + lr_in_ptr_e[ch] = sts[ch]->hFdCngEnc->msNoiseEst_fx_exp; + ms_ptr_fx[ch] = &logNoiseEst_fx[ch][0]; + lr_out_ptr_fx[ch] = &sts[ch]->hFdCngEnc->hFdCngCom->sidNoiseEst[0]; + lr_out_ptr_e[ch] = sts[ch]->hFdCngEnc->hFdCngCom->sidNoiseEstExp; + move16(); + } + set16_fx( weights_fx, ONE_IN_Q8, NPART ); + + /* apply log and save energy of original left and right channels */ + FOR( ch = 0; ch < CPE_CHANNELS; ch++ ) + { + // E[ch] = 0.0f; + E_fx[ch] = 0; + move32(); + FOR( p = 0; p < N[ch]; p++ ) + { + t1 = BASOP_Util_Log2( lr_in_ptr_fx[ch][p] + EPSILLON_FX ); // Q25 + t2 = L_add( t1, L_shl( lr_in_ptr_e[ch], Q25 ) ); // Q25 + ms_ptr_fx[ch][p] = Mpy_32_32( t2, TEN_MULT_LOG10_2_IN_Q29 ); // Q23 + move32(); + E_fx[ch] = L_add( E_fx[ch], L_shr( ms_ptr_fx[ch][p], 5 ) ); // Q18 + move32(); + } + } + ms_ptr_e = Q31 - Q23; + move16(); + + /* M/S transform on log envelopes */ + convertToMS_fx( N[0], ms_ptr_fx[0], ms_ptr_fx[1], ONE_IN_Q30 ); + E_fx[0] = 0; + move32(); + FOR( p = 0; p < N[0]; p++ ) + { + E_fx[0] = L_add( E_fx[0], L_shr( ms_ptr_fx[0][p], 5 ) ); // Q18 + move32(); + } + + /* Quantize M noise shape */ + /* Normalize MSVQ input */ + gain_fx[0] = 0; + move16(); + FOR( p = N_GAIN_MIN; p < N_GAIN_MAX; p++ ) + { + tmp32 = Mpy_32_32( ms_ptr_fx[0][p], 165191050 /* 0.07 in Q31 */ ); // Q23 + gain_fx[0] = L_add( gain_fx[0], tmp32 ); // Q23 + move32(); + } + + FOR( p = 0; p < N[0]; p++ ) + { + ms_ptr_fx[0][p] = L_sub( ms_ptr_fx[0][p], gain_fx[0] ); // Q23 + move32(); + } + + + /* MSVQ */ + /* DCT domain compressed/truncated indices used for first stage */ + /* mid quantization using stages #1 through 6 */ + scale_sig32( ms_ptr_fx[0], N[0], -6 ); + ms_ptr_e = add( ms_ptr_e, 6 ); + move16(); + IF( EQ_16( N[0], FDCNG_VQ_MAX_LEN_WB ) ) + { + create_IDCT_N_Matrix_fx( invTrfMatrix_fx, N[0], FDCNG_VQ_DCT_MAXTRUNC, sizeof( tmpRAM_fx ) / ( sizeof( Word32 ) ) ); + /* truncated DCT 21 analysis */ + dctT2_N_apply_matrix_fx( (const Word32 *) ms_ptr_fx[0], dct_target_fx, FDCNG_VQ_DCT_MAXTRUNC, N[0], invTrfMatrix_fx, FDCNG_VQ_DCT_MAXTRUNC, DCT_T2_21_XX ); + /* truncated IDCT21 extension to 24 synthesis */ + + extend_dctN_input_fx( ms_ptr_fx[0], dct_target_fx, N[0], tot_sig_ext_fx, FDCNG_VQ_MAX_LEN, invTrfMatrix_fx, FDCNG_VQ_DCT_MAXTRUNC, IDCT_T2_XX_21 ); /* use 18 basis vectors*/ + + Copy32( tot_sig_ext_fx, ms_ptr_fx[0], FDCNG_VQ_MAX_LEN ); /* write extended result as input to VQ stage #1 Q23*/ + } + create_IDCT_N_Matrix_fx( invTrfMatrix_fx, FDCNG_VQ_MAX_LEN, FDCNG_VQ_DCT_MAXTRUNC, sizeof( tmpRAM_fx ) / ( sizeof( Word32 ) ) ); + + msvq_enc_ivas_fx( ivas_cdk_37bits_fx, Q7, NULL, NULL, ms_ptr_fx[0], ms_ptr_e, levels_37bits, FD_CNG_maxC_37bits, FD_CNG_stages_37bits, weights_fx, N[0], FD_CNG_maxN_37bits, 1, invTrfMatrix_fx, indices[0] ); + msvq_dec_fx( ivas_cdk_37bits_fx, NULL, NULL, FD_CNG_stages_37bits, N[0], FD_CNG_maxN_37bits, indices[0], 1, invTrfMatrix_fx, ms_ptr_fx[0], NULL, 7 ); + shift = find_guarded_bits_fx( N[0] ); + ms_ptr_e = sub( 31, sub( 20, shift ) ); + scale_sig32( ms_ptr_fx[1], N[1], sub( 8, ms_ptr_e ) ); /* Q31 - ms_ptr_e */ + + /* set S to zero */ + set32_fx( ms_ptr_fx[1], 0, NPART ); + + /* compute M gain */ + gain_fx[0] = 0; + move32(); + tmp_e = 15; + move16(); + tmp = Inv16( N[0], &tmp_e ); + FOR( p = 0; p < N[0]; p++ ) + { + gain_fx[0] = L_add( gain_fx[0], Mpy_32_16_1( ms_ptr_fx[0][p], shl( tmp, tmp_e ) ) ); // Q23 + move32(); + } + gain_fx[0] = L_sub( L_shl( Mpy_32_16_1( E_fx[0], shl( tmp, tmp_e ) ), Q23 - Q18 ), L_shl( gain_fx[0], ms_ptr_e - 8 ) ); // Q23 + move32(); + + apply_scale( &gain_fx[0], sts[0]->hFdCngEnc->hFdCngCom->CngBandwidth, sts[0]->hDtxEnc->last_active_brate, scaleTableStereo, SIZE_SCALE_TABLE_STEREO ); + + /* quantize gain */ + gain_idx[0] = extract_l( Mpy_32_32_r( L_add( gain_fx[0], 251658240 ), 384 ) ); + move16(); + gain_idx[0] = s_max( 0, s_min( 127, gain_idx[0] ) ); + move16(); + + gain_fx[0] = Mpy_32_16_1( L_shl( sub( gain_idx[0], GAIN_Q_OFFSET_IVAS_FX_Q0 ), 23 ), 21845 /* 0.66 in Q15 */ ); // Q23 + move32(); + gain_fx[1] = gain_fx[0]; // Q23 + move32(); + + /* undo M/S */ + convertToMS_fx( NPART, ms_ptr_fx[0], ms_ptr_fx[1], ONE_IN_Q31 ); + + /* restore channel noise envelopes */ + FOR( ch = 0; ch < CPE_CHANNELS; ch++ ) + { + HANDLE_FD_CNG_ENC hFdCngEnc = sts[ch]->hFdCngEnc; + HANDLE_FD_CNG_COM hFdCngCom = hFdCngEnc->hFdCngCom; + + Word32 pow; + Word16 e_lr_out[NPART]; + tmp_e = -MAX_16; + FOR( p = 0; p < N[ch]; p++ ) + { + pow = L_shl( gain_fx[ch], sub( 8, ms_ptr_e ) ); /* Q31 - ms_ptr_e */ + pow = L_add( ms_ptr_fx[ch][p], pow ); /* Q31 - ms_ptr_e */ + pow = Mpy_32_32( pow, 214748365 /* 0.1 in Q31 */ ); /*pow = 0.1 Q31 - ms_ptr_e*/ + lr_out_ptr_fx[ch][p] = BASOP_Util_fPow( 10, 31, pow, ms_ptr_e, &e_lr_out[p] ); + tmp_e = s_max( tmp_e, e_lr_out[p] ); + } + + FOR( p = 0; p < N[ch]; p++ ) + { + lr_out_ptr_fx[ch][p] = L_shl( lr_out_ptr_fx[ch][p], sub( e_lr_out[p], tmp_e ) ); // Q(31 - tmp_e) + } + + sts[ch]->hFdCngEnc->hFdCngCom->sidNoiseEstExp = tmp_e; + move16(); + lr_out_ptr_e[ch] = tmp_e; + move16(); + + /* NB last band energy compensation */ + IF( hFdCngCom->CngBandwidth == NB ) + { + lr_out_ptr_fx[ch][N[ch] - 1] = Mpy_32_16_1( lr_out_ptr_fx[ch][N[ch] - 1], NB_LAST_BAND_SCALE ); // Q(31 - tmp_e) + move32(); + } + ELSE IF( hFdCngCom->CngBandwidth == SWB && LE_32( hFdCngCom->CngBitrate, ACELP_13k20 ) ) + { + lr_out_ptr_fx[ch][N[ch] - 1] = Mpy_32_16_1( lr_out_ptr_fx[ch][N[ch] - 1], SWB_13k2_LAST_BAND_SCALE ); // Q(31 - tmp_e) + move32(); + } + /* scale bands and get scalefactors */ + scalebands( lr_out_ptr_fx[ch], hFdCngEnc->partDec, N[ch], hFdCngEnc->midbandDec, hFdCngEnc->nFFTpartDec, sub( hFdCngEnc->stopBandDec, hFdCngEnc->startBandDec ), hFdCngCom->cngNoiseLevel, 1 ); + hFdCngCom->cngNoiseLevelExp = lr_out_ptr_e[ch]; + move16(); + lpc_from_spectrum( hFdCngCom, hFdCngEnc->startBandDec, hFdCngEnc->stopFFTbinDec, sts[ch]->preemph_fac ); + sts[ch]->hDtxEnc->last_CNG_L_frame = sts[ch]->L_frame; + } + sts[0]->hFdCngEnc->hFdCngCom->coherence_fx = 0; + move16(); + sts[1]->hFdCngEnc->hFdCngCom->coherence_fx = 0; + move16(); + + /* ---- Write SID bitstream ---- */ + + /* side info */ + push_indice( sts[0]->hBstr, IND_SID_TYPE, 1, 1 ); + push_indice( sts[0]->hBstr, IND_BWIDTH, sts[0]->bwidth, 2 ); + IF( EQ_16( sts[0]->L_frame, L_FRAME16k ) ) + { + push_indice( sts[0]->hBstr, IND_ACELP_16KHZ, 1, 1 ); + } + ELSE + { + push_indice( sts[0]->hBstr, IND_ACELP_16KHZ, 0, 1 ); + } + + /* noise shapes and channel gains */ + FOR( Word16 i = 0; i < FD_CNG_stages_37bits; i++ ) + { + push_indice( sts[0]->hBstr, IND_LSF, indices[0][i], bits_37bits[i] ); + } + push_indice( sts[0]->hBstr, IND_ENERGY, gain_idx[0], 7 ); + + return; +} diff --git a/lib_enc/find_tar.c b/lib_enc/find_tar.c deleted file mode 100644 index e7a8ca967132cf8896fc4a231dbaf74eed596840..0000000000000000000000000000000000000000 --- a/lib_enc/find_tar.c +++ /dev/null @@ -1,41 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include "cnst.h" -#include "prot.h" -#include "wmc_auto.h" diff --git a/lib_enc/find_tar_fx.c b/lib_enc/find_tar_fx.c index dc8477fc42db2aab8e4093e9f80a49bddde323a6..4e15bc82820dbe3f6de8055ff78d911f814b63e9 100644 --- a/lib_enc/find_tar_fx.c +++ b/lib_enc/find_tar_fx.c @@ -14,16 +14,16 @@ void find_targets_fx( const Word16 *speech, /* i : pointer to the speech frame Q_new-1*/ const Word16 *mem_syn, /* i : memory of the synthesis filter Q_new-1*/ - const Word16 i_subfr, /* i : subframe index */ + const Word16 i_subfr, /* i : subframe index Q0*/ Word16 *mem_w0, /* i/o: weighting filter denominator memory Q_new-1*/ const Word16 *p_Aq, /* i : interpolated quantized A(z) filter Q12*/ const Word16 *res, /* i : residual signal Q_new*/ - const Word16 L_subfr, /* i : length of vectors for gain quantization */ + const Word16 L_subfr, /* i : length of vectors for gain quantization Q0*/ const Word16 *Ap, /* i : unquantized A(z) filter with bandwidth expansion Q12*/ - Word16 tilt_fac, /* i : tilt factor Q15 */ + Word16 tilt_fac, /* i : tilt factor Q15*/ Word16 *xn, /* o : Close-loop Pitch search target vector Q_new-1*/ Word16 *cn, /* o : target vector in residual domain Q_new*/ - Word16 *h1 /* o : impulse response of weighted synthesis filter */ + Word16 *h1 /* o : impulse response of weighted synthesis filter Q14*/ ) { Word16 i; @@ -33,6 +33,7 @@ void find_targets_fx( Word32 Ltmp; #ifdef BASOP_NOGLOB_DECLARE_LOCAL Flag Overflow = 0; + move32(); #endif /*------------------------------------------------------------------------* * Find the target vector for excitation search: @@ -49,11 +50,7 @@ void find_targets_fx( *-----------------------------------------------------------------------*/ FOR( i = 0; i < M; i++ ) { -#ifdef BASOP_NOGLOB - temp[i] = sub_sat( speech[i + i_subfr - M], mem_syn[i] ); -#else - temp[i] = sub( speech[i + i_subfr - M], mem_syn[i] ); -#endif + temp[i] = sub_sat( speech[i + i_subfr - M], mem_syn[i] ); /* Q_new - 1 */ move16(); } Syn_filt_s( 1, p_Aq, M, &res[i_subfr], temp + M, L_subfr, temp, 0 ); /* error in Q_new -1 */ @@ -77,7 +74,7 @@ void find_targets_fx( Scale_sig( cn, L_SUBFR / 2, 1 ); /* second half: res[] --> cn[] (approximated and faster) */ - Copy( &res[i_subfr + ( L_SUBFR / 2 )], cn + ( L_SUBFR / 2 ), L_SUBFR / 2 ); + Copy( &res[i_subfr + ( L_SUBFR / 2 )], cn + ( L_SUBFR / 2 ), L_SUBFR / 2 ); /* Q_new */ } /*---------------------------------------------------------------* @@ -89,13 +86,13 @@ void find_targets_fx( d = sub( scaleq, scale ); IF( d >= 0 ) { - Copy( p_Aq, Aqs, M + 1 ); + Copy( p_Aq, Aqs, M + 1 ); /* Q12 */ s = add( scaleq, 1 ); s2 = shr( 16384, d ); } ELSE { - Copy_Scale_sig( p_Aq, Aqs, M + 1, d ); + Copy_Scale_sig( p_Aq, Aqs, M + 1, d ); /* Q12 */ s = add( scale, 1 ); s2 = 16384; } @@ -103,84 +100,56 @@ void find_targets_fx( move16(); FOR( i = 0; i < M; i++ ) { - Ltmp = L_mult( Ap[i], s2 ); + Ltmp = L_mult( Ap[i], s2 ); /* Q27 */ FOR( j = 1; j <= i; j++ ) { -#ifdef BASOP_NOGLOB /* Critical Overflow , as well as those below*/ - Ltmp = L_msu_o( Ltmp, Aqs[j], h1[i - j], &Overflow ); -#else - Ltmp = L_msu( Ltmp, Aqs[j], h1[i - j] ); -#endif + Ltmp = L_msu_o( Ltmp, Aqs[j], h1[i - j], &Overflow ); /* Q27 */ } -#ifdef BASOP_NOGLOB /* Critical Overflow */ - h1[i] = round_fx_o( L_shl_o( Ltmp, s, &Overflow ), &Overflow ); -#else - h1[i] = round_fx( L_shl( Ltmp, s ) ); -#endif + h1[i] = round_fx_o( L_shl_o( Ltmp, s, &Overflow ), &Overflow ); /* Q11 + s */ } - Ltmp = L_mult( Ap[i], s2 ); + Ltmp = L_mult( Ap[i], s2 ); /* Q27 */ FOR( j = 1; j <= M; j++ ) { -#ifdef BASOP_NOGLOB /* Critical Overflow */ - Ltmp = L_msu_o( Ltmp, Aqs[j], h1[i - j], &Overflow ); -#else - Ltmp = L_msu( Ltmp, Aqs[j], h1[i - j] ); -#endif + Ltmp = L_msu_o( Ltmp, Aqs[j], h1[i - j], &Overflow ); /* Q27 */ } -#ifdef BASOP_NOGLOB /* Critical Overflow */ - h1[M] = round_fx_o( L_shl_o( Ltmp, s, &Overflow ), &Overflow ); -#else - h1[M] = round_fx( L_shl( Ltmp, s ) ); -#endif + h1[M] = round_fx_o( L_shl_o( Ltmp, s, &Overflow ), &Overflow ); /* Q11 + s */ // PMT("should we used extended basop here for when the L_subfr > L_SUBFR, to prevent saturation/overflow and the subsequent loop\n") FOR( i = M + 1; i < L_subfr; i++ ) { - Ltmp = L_msu( 0, Aqs[1], h1[i - 1] ); + Ltmp = L_msu( 0, Aqs[1], h1[i - 1] ); /* Q27 */ FOR( j = 2; j <= M; j++ ) { -#ifdef BASOP_NOGLOB /* Critical Overflow */ - Ltmp = L_msu_o( Ltmp, Aqs[j], h1[i - j], &Overflow ); -#else - Ltmp = L_msu( Ltmp, Aqs[j], h1[i - j] ); -#endif + Ltmp = L_msu_o( Ltmp, Aqs[j], h1[i - j], &Overflow ); /* Q27 */ } -#ifdef BASOP_NOGLOB /* Critical Overflow */ - h1[i] = round_fx_o( L_shl_o( Ltmp, s, &Overflow ), &Overflow ); -#else - h1[i] = round_fx( L_shl( Ltmp, s ) ); -#endif + h1[i] = round_fx_o( L_shl_o( Ltmp, s, &Overflow ), &Overflow ); /* Q11 + s */ } IF( Overflow ) { s2 = shr( s2, 1 ); FOR( i = 0; i < M; i++ ) { - Ltmp = L_mult( Ap[i], s2 ); + Ltmp = L_mult( Ap[i], s2 ); /* Q27 */ FOR( j = 1; j <= i; j++ ) { - Ltmp = L_msu( Ltmp, Aqs[j], h1[i - j] ); + Ltmp = L_msu( Ltmp, Aqs[j], h1[i - j] ); /* Q27 */ } -#ifdef BASOP_NOGLOB - h1[i] = round_fx( L_shl_o( Ltmp, s, &Overflow ) ); -#else - h1[i] = round_fx( L_shl( Ltmp, s ) ); -#endif + h1[i] = round_fx( L_shl_o( Ltmp, s, &Overflow ) ); /* Q11 + s */ } - Ltmp = L_mult( Ap[i], s2 ); + Ltmp = L_mult( Ap[i], s2 ); /* Q27 */ FOR( j = 1; j <= M; j++ ) { - Ltmp = L_msu( Ltmp, Aqs[j], h1[i - j] ); + Ltmp = L_msu( Ltmp, Aqs[j], h1[i - j] ); /* Q27 */ } - h1[M] = round_fx( L_shl( Ltmp, s ) ); + h1[M] = round_fx( L_shl( Ltmp, s ) ); /* Q11 + s */ FOR( i = M + 1; i < L_subfr; i++ ) { - Ltmp = L_msu( 0, Aqs[1], h1[i - 1] ); + Ltmp = L_msu( 0, Aqs[1], h1[i - 1] ); /* Q27 */ FOR( j = 2; j <= M; j++ ) { - Ltmp = L_msu( Ltmp, Aqs[j], h1[i - j] ); + Ltmp = L_msu( Ltmp, Aqs[j], h1[i - j] ); /* Q27 */ } - h1[i] = round_fx( L_shl( Ltmp, s ) ); + h1[i] = round_fx( L_shl( Ltmp, s ) ); /* Q11 + s */ } } @@ -193,25 +162,28 @@ void find_targets_fx( void find_targets_ivas_fx( const Word16 *speech, /* i : pointer to the speech frame Q_new-1*/ const Word16 *mem_syn, /* i : memory of the synthesis filter Q_new-1*/ - const Word16 i_subfr, /* i : subframe index */ + const Word16 i_subfr, /* i : subframe index Q0*/ Word16 *mem_w0, /* i/o: weighting filter denominator memory Q_new-1*/ const Word16 *p_Aq, /* i : interpolated quantized A(z) filter Q12*/ const Word16 *res, /* i : residual signal Q_new*/ - const Word16 L_subfr, /* i : length of vectors for gain quantization */ + const Word16 L_subfr, /* i : length of vectors for gain quantization Q0*/ const Word16 *Ap, /* i : unquantized A(z) filter with bandwidth expansion Q12*/ - Word16 tilt_fac, /* i : tilt factor Q15 */ + Word16 tilt_fac, /* i : tilt factor Q15*/ Word16 *xn, /* o : Close-loop Pitch search target vector Q_new-1*/ Word16 *cn, /* o : target vector in residual domain Q_new*/ - Word16 *h1 /* o : impulse response of weighted synthesis filter */ + Word16 *h1 /* o : impulse response of weighted synthesis filter Q(14 - norm_s(h1[0]))*/ ) { Word16 i; Word16 temp[M + 6 * L_SUBFR]; /* error of quantization */ Word16 scale, scaleq, j, d, s, s2, tmp; Word16 Aqs[M + 1]; - Word32 Ltmp; + Word32 h1_32[6 * L_SUBFR]; + Word16 sf; + Word64 Ltmp64; #ifdef BASOP_NOGLOB_DECLARE_LOCAL Flag Overflow = 0; + move16(); #endif /*------------------------------------------------------------------------* * Find the target vector for excitation search: @@ -228,19 +200,17 @@ void find_targets_ivas_fx( *-----------------------------------------------------------------------*/ FOR( i = 0; i < M; i++ ) { -#ifdef BASOP_NOGLOB - temp[i] = sub_sat( speech[i + i_subfr - M], mem_syn[i] ); -#else - temp[i] = sub( speech[i + i_subfr - M], mem_syn[i] ); -#endif + temp[i] = sub_sat( speech[i + i_subfr - M], mem_syn[i] ); /* Q_new - 1 */ move16(); } - Syn_filt_s( 1, p_Aq, M, &res[i_subfr], temp + M, L_subfr, temp, 0 ); - Residu3_fx( Ap, temp + M, xn, L_subfr, 0 ); /* xn in Q_new -1*/ + syn_filt_fx( 0, p_Aq, M, &res[i_subfr], temp + M, L_subfr, temp, 0 ); - deemph_fx( xn, tilt_fac, L_subfr, mem_w0 ); /* xn in Q_new -1 */ + Residu3_fx( Ap, temp + M, xn, L_subfr, 0 ); /* xn in Q_new */ + + deemph_fx( xn, tilt_fac, L_subfr, mem_w0 ); /* xn in Q_new */ + *mem_w0 = shr( *mem_w0, 1 ); // Q_new - 1 /*-----------------------------------------------------------------* * Find target in residual domain (cn[]) for innovation search @@ -251,13 +221,13 @@ void find_targets_ivas_fx( temp[0] = 0; move16(); preemph_copy_fx( xn, cn, tilt_fac, shr( L_subfr, 1 ), temp ); - syn_filt_s_lc_fx( 1, Ap, cn, temp, shr( L_subfr, 1 ) ); /* Q-1 -> Q-2 */ - Residu3_lc_fx( p_Aq, M, temp, cn, shr( L_subfr, 1 ), 1 ); /* Q-2 -> Q-1 */ - Scale_sig( cn, shr( L_subfr, 1 ), 1 ); + syn_filt_s_lc_fx( 1, Ap, cn, temp, shr( L_subfr, 1 ) ); /* Q_new -> Q_new - 1 */ + Residu3_lc_fx( p_Aq, M, temp, cn, shr( L_subfr, 1 ), 1 ); /* Q_new - 1 -> Q_new */ /* second half: res[] --> cn[] (approximated and faster) */ - Copy( &res[i_subfr + shr( L_subfr, 1 )], cn + shr( L_subfr, 1 ), shr( L_subfr, 1 ) ); + Copy( &res[i_subfr + shr( L_subfr, 1 )], cn + shr( L_subfr, 1 ), shr( L_subfr, 1 ) ); /* Q_new */ } + scale_sig( xn, L_subfr, -1 ); // Q_new - 1 /*---------------------------------------------------------------* * Compute impulse response, h1[], of weighted synthesis filter * @@ -268,104 +238,57 @@ void find_targets_ivas_fx( d = sub( scaleq, scale ); IF( d >= 0 ) { - Copy( p_Aq, Aqs, M + 1 ); + Copy( p_Aq, Aqs, M + 1 ); /* Q12 */ s = add( scaleq, 1 ); s2 = shr( 16384, d ); } ELSE { - Copy_Scale_sig( p_Aq, Aqs, M + 1, d ); + Copy_Scale_sig( p_Aq, Aqs, M + 1, d ); /* Q12 */ s = add( scale, 1 ); s2 = 16384; + move16(); } - set16_fx( h1, 0, L_subfr ); + + set32_fx( h1_32, 0, L_subfr ); Overflow = 0; move16(); FOR( i = 0; i < M; i++ ) { - Ltmp = L_mult( Ap[i], s2 ); + Ltmp64 = W_mult_16_16( Ap[i], s2 ); /* Q27 */ FOR( j = 1; j <= i; j++ ) { -#ifdef BASOP_NOGLOB /* Critical Overflow , as well as those below*/ - Ltmp = L_msu_o( Ltmp, Aqs[j], h1[i - j], &Overflow ); -#else - Ltmp = L_msu( Ltmp, Aqs[j], h1[i - j] ); -#endif + Ltmp64 = W_msu_16_16( Ltmp64, Aqs[j], extract_h( L_shl_o( h1_32[i - j], s, &Overflow ) ) ); /* Q27 */ } -#ifdef BASOP_NOGLOB /* Critical Overflow */ - h1[i] = round_fx_o( L_shl_o( Ltmp, s, &Overflow ), &Overflow ); -#else - h1[i] = round_fx( L_shl( Ltmp, s ) ); -#endif + h1_32[i] = W_extract_l( Ltmp64 ); /* Q27 */ + move32(); } - Ltmp = L_mult( Ap[i], s2 ); + + Ltmp64 = W_mult_16_16( Ap[i], s2 ); /* Q27 */ FOR( j = 1; j <= M; j++ ) { -#ifdef BASOP_NOGLOB /* Critical Overflow */ - Ltmp = L_msu_o( Ltmp, Aqs[j], h1[i - j], &Overflow ); -#else - Ltmp = L_msu( Ltmp, Aqs[j], h1[i - j] ); -#endif + Ltmp64 = W_msu_16_16( Ltmp64, Aqs[j], extract_h( L_shl_o( h1_32[i - j], s, &Overflow ) ) ); /* Q27 */ } -#ifdef BASOP_NOGLOB /* Critical Overflow */ - h1[M] = round_fx_o( L_shl_o( Ltmp, s, &Overflow ), &Overflow ); -#else - h1[M] = round_fx( L_shl( Ltmp, s ) ); -#endif + h1_32[M] = W_extract_l( Ltmp64 ); /* Q27 */ + move32(); - // PMT("should we used extended basop here for when the L_subfr > L_SUBFR, to prevent saturation/overflow and the subsequent loop\n") FOR( i = M + 1; i < L_subfr; i++ ) { - Ltmp = L_msu( 0, Aqs[1], h1[i - 1] ); + Ltmp64 = W_msu_16_16( 0, Aqs[1], extract_h( L_shl_o( h1_32[i - 1], s, &Overflow ) ) ); /* Q27 */ FOR( j = 2; j <= M; j++ ) { -#ifdef BASOP_NOGLOB /* Critical Overflow */ - Ltmp = L_msu_o( Ltmp, Aqs[j], h1[i - j], &Overflow ); -#else - Ltmp = L_msu( Ltmp, Aqs[j], h1[i - j] ); -#endif - } -#ifdef BASOP_NOGLOB /* Critical Overflow */ - h1[i] = round_fx_o( L_shl_o( Ltmp, s, &Overflow ), &Overflow ); -#else - h1[i] = round_fx( L_shl( Ltmp, s ) ); -#endif - } - IF( Overflow ) - { - s2 = shr( s2, 1 ); - FOR( i = 0; i < M; i++ ) - { - Ltmp = L_mult( Ap[i], s2 ); - FOR( j = 1; j <= i; j++ ) - { - Ltmp = L_msu( Ltmp, Aqs[j], h1[i - j] ); - } -#ifdef BASOP_NOGLOB - h1[i] = round_fx( L_shl_o( Ltmp, s, &Overflow ) ); -#else - h1[i] = round_fx( L_shl( Ltmp, s ) ); -#endif - } - Ltmp = L_mult( Ap[i], s2 ); - FOR( j = 1; j <= M; j++ ) - { - Ltmp = L_msu( Ltmp, Aqs[j], h1[i - j] ); - } - h1[M] = round_fx( L_shl( Ltmp, s ) ); - FOR( i = M + 1; i < L_subfr; i++ ) - { - Ltmp = L_msu( 0, Aqs[1], h1[i - 1] ); - FOR( j = 2; j <= M; j++ ) - { - Ltmp = L_msu( Ltmp, Aqs[j], h1[i - j] ); - } - h1[i] = round_fx( L_shl( Ltmp, s ) ); + Ltmp64 = W_msu_16_16( Ltmp64, Aqs[j], extract_h( L_shl_o( h1_32[i - j], s, &Overflow ) ) ); /* Q27 */ } + h1_32[i] = W_extract_l( Ltmp64 ); /* Q27 */ + move32(); } + sf = sub( L_norm_arr( h1_32, L_subfr ), 1 ); + Copy_Scale_sig32_16( h1_32, h1, L_subfr, sf ); // Q11 + sf + tmp = 0; - Deemph2( h1, tilt_fac, L_subfr, &tmp ); + move16(); + Deemph2( h1, tilt_fac, L_subfr, &tmp ); // Q11 + sf - 1 return; } diff --git a/lib_enc/find_tilt.c b/lib_enc/find_tilt.c deleted file mode 100644 index c5e16ed22962d9f18f21f00a79ac9c7b52fa7278..0000000000000000000000000000000000000000 --- a/lib_enc/find_tilt.c +++ /dev/null @@ -1,324 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include -#include "cnst.h" -#include "prot.h" -#include "wmc_auto.h" - -#include "prot_fx.h" /* Function prototypes */ -#include "prot_fx_enc.h" /* Function prototypes */ - - -/*---------------------------------------------------------------------* - * Local constants - *---------------------------------------------------------------------*/ - - -/*-------------------------------------------------------------------* - * find_tilt() - * - * Find LF/HF energy ratio - *-------------------------------------------------------------------*/ -void find_tilt_ivas_fx( - const Word32 fr_bands[], /* i : energy in frequency bands Q_new*/ - const Word32 bckr[], /* i : per band background noise energy estimate Q_new*/ - Word32 ee[2], /* o : lf/hf E ration for present frame Q6*/ - const Word16 pitch[3], /* i : open loop pitch values for 3 half-frames Q0*/ - const Word16 voicing[3], /* i : normalized correlation for 3 half-frames Q15*/ - const Word32 *lf_E, /* i : per bin energy for low frequencies Q_new - 2*/ - const Word16 corr_shift, /* i : normalized correlation correction Q15*/ - const Word16 bwidth, /* i : input signal bandwidth */ - const Word16 max_band, /* i : maximum critical band */ - Word32 hp_E[], /* o : energy in HF Q_new*/ - const Word16 codec_mode, /* i : MODE1 or MODE2 */ - const Word16 Q_new, /* i : scaling factor */ - Word32 *bckr_tilt_lt /* i/o: lf/hf E ratio of background noise Q16 */ - , - Word16 Opt_vbr_mode ) -{ - Word32 lp_bckr = 0, hp_bckr = 0, lp_E, Ltmp; - const Word32 *pt_E, *pt_bands, *pt_bckr, *hf_bands, *tmp_E; - Word16 tmp, freq, f0, f1, f2, mean_voi, bin; - Word16 i, nb_bands; - Word16 e_tmp, m_tmp; - Word16 m_Fs, e_Fs; - Word16 m_cnt, e_cnt; - Word16 m_hpE, e_hpE; -#ifdef BASOP_NOGLOB_DECLARE_LOCAL - Flag Overflow = 0; - move32(); -#endif - move32(); - move32(); - /*-----------------------------------------------------------------* - * Initializations - *-----------------------------------------------------------------*/ - - IF( NE_16( bwidth, NB ) ) - { - /* WB processing */ - bin = BIN4_FX; - move16(); /* First useful frequency bin ~ 50 Hz */ - pt_bands = fr_bands; - tmp_E = lf_E; - pt_bckr = bckr; - nb_bands = 10; - move16(); - } - ELSE - { - /* NB processing */ - bin = add( shl( BIN4_FX, 1 ), BIN4_FX ); /* First useful frequency bin ~ 150 Hz */ - pt_bands = fr_bands + 1; /* Exlcude 1st critical band */ - tmp_E = lf_E + 2; /* Start at the 3rd bin (150 Hz) */ - pt_bckr = bckr + 1; /* Exlcude 1st critical band */ - nb_bands = 9; - move16(); /* Nb. of "low" frequency bands taken into account in NB processing */ - } - - /*-----------------------------------------------------------------* - * Find spectrum tilt - *-----------------------------------------------------------------*/ - - pt_E = tmp_E; /* Point at the 1st useful element of the per-bin energy vector */ - hf_bands = fr_bands; - - /* bckr + voicing */ - /*lp_bckr = mean( pt_bckr, nb_bands );*/ /* estimated noise E in first critical bands, up to 1270 Hz */ - lp_bckr = Mean32( pt_bckr, nb_bands ); - /*hp_bckr = 0.5f * (bckr[max_band-1] + bckr[max_band]);*/ /* estimated noise E in last 2 critical bands */ -#ifdef BASOP_NOGLOB - hp_bckr = L_shr( L_add_sat( bckr[max_band - 1], bckr[max_band] ), 1 ); -#else - hp_bckr = L_shr( L_add( bckr[max_band - 1], bckr[max_band] ), 1 ); -#endif - if ( hp_bckr == 0 ) /* Avoid division by zero. */ - { - hp_bckr = L_deposit_l( 1 ); - } - Ltmp = BASOP_Util_Divide3232_Scale_cadence( lp_bckr, hp_bckr, &e_tmp ); - Ltmp = Mpy_32_16_r( Ltmp, 3277 ); - Ltmp = L_shr_sat( Ltmp, sub( 15, e_tmp ) ); - *bckr_tilt_lt = L_add_sat( Mpy_32_16_r( *bckr_tilt_lt, 29491 ), Ltmp ); - move32(); - - test(); - IF( EQ_16( codec_mode, MODE2 ) || Opt_vbr_mode == 1 ) - { - /*lp_bckr *= FACT;*/ - /*hp_bckr *= FACT;*/ -#ifdef BASOP_NOGLOB - lp_bckr = L_add_sat( L_shl_sat( lp_bckr, 1 ), lp_bckr ); - hp_bckr = L_add_sat( L_shl_sat( hp_bckr, 1 ), hp_bckr ); -#else - lp_bckr = L_add( L_shl( lp_bckr, 1 ), lp_bckr ); - hp_bckr = L_add( L_shl( hp_bckr, 1 ), hp_bckr ); -#endif - } - /*mean_voi = 0.5f * (voicing[1] + voicing[2]) + corr_shift;*/ - Ltmp = L_mult( voicing[1], 16384 ); - Ltmp = L_mac( Ltmp, voicing[2], 16384 ); -#ifdef BASOP_NOGLOB - Ltmp = L_mac_o( Ltmp, corr_shift, 32767, &Overflow ); - mean_voi = round_fx_o( Ltmp, &Overflow ); -#else - Ltmp = L_mac( Ltmp, corr_shift, 32767 ); - mean_voi = round_fx( Ltmp ); -#endif - - /*f0 = INT_FS_FX / pitch[2];*/ - e_tmp = norm_s( pitch[2] ); - m_tmp = shl( pitch[2], e_tmp ); - - m_Fs = div_s( INT_FS_FX, m_tmp ); - e_Fs = sub( 15, e_tmp ); - f0 = shr( m_Fs, sub( e_Fs, 4 ) ); /* Q4 */ - - FOR( i = 0; i < 2; i++ ) - { - /*hp_E[i] = 0.5f * (hf_bands[max_band-1] + hf_bands[max_band]) - hp_bckr; */ /* averaged E in last 2 critical bands */ - Ltmp = L_add( L_shr( hf_bands[max_band - 1], 1 ), L_shr( hf_bands[max_band], 1 ) ); - hp_E[i] = L_sub( Ltmp, hp_bckr ); - move32(); - IF( Opt_vbr_mode == 0 ) - { - IF( EQ_16( BASOP_Util_Cmp_Mant32Exp( hp_E[i], sub( 31, Q_new ), E_MIN_IVAS_FX, 31 - Q19 ), -1 ) ) - { - hp_E[i] = L_shl( E_MIN_IVAS_FX, sub( Q_new, Q19 ) ); - move32(); - } - } - ELSE - { - hp_E[i] = L_max( hp_E[i], L_shl( 1, Q_new ) ); - move32(); - } - - test(); - IF( GT_16( mean_voi, TH_COR_FX ) && LT_16( pitch[2], TH_PIT_FX ) ) /* High-pitched voiced frames */ - { - freq = bin; - move16(); /* 1st useful frequency bin */ - m_cnt = 0; - move16(); - lp_E = L_deposit_l( 0 ); - - f1 = add( shr( f0, 1 ), f0 ); /* Middle between 2 harmonics */ - f2 = f0; - move16(); - WHILE( LE_16( freq, 20320 ) ) /* End frequency of 10th critical band */ - { - FOR( ; freq <= f1; freq += BIN4_FX ) - { - /* include only bins sufficiently close to harmonics */ - tmp = sub( freq, f2 ); - IF( L_mac0( -(Word32) TH_D_FX * TH_D_FX, tmp, tmp ) < 0 ) - { -#ifdef BASOP_NOGLOB - lp_E = L_add_o( *pt_E, lp_E, &Overflow ); -#else - lp_E = L_add( *pt_E, lp_E ); -#endif - m_cnt = add( m_cnt, 1 ); - } - pt_E++; - } -#ifdef BASOP_NOGLOB - f1 = add_o( f1, f0, &Overflow ); - f2 = add_o( f2, f0, &Overflow ); -#else - f1 = add( f1, f0 ); - f2 = add( f2, f0 ); -#endif - } - /*lp_E = lp_E / (float)cnt - lp_bckr;*/ - e_tmp = sub( norm_l( lp_E ), 1 ); - m_tmp = extract_h( L_shl( lp_E, e_tmp ) ); - - e_tmp = sub( e_tmp, 2 ); /* lf_e divided by 4 in anal_sp */ - - e_cnt = norm_s( m_cnt ); - m_cnt = shl( m_cnt, e_cnt ); - - m_tmp = div_s( m_tmp, m_cnt ); - e_tmp = sub( e_tmp, e_cnt ); - -#ifdef BASOP_NOGLOB - lp_E = L_sub_o( L_shr_o( m_tmp, sub( e_tmp, 1 ), &Overflow ), lp_bckr, &Overflow ); -#else - lp_E = L_sub( L_shr( m_tmp, sub( e_tmp, 1 ) ), lp_bckr ); -#endif - - pt_E = tmp_E + VOIC_BINS; /* Update for next half-frame */ - } - ELSE /* Other than high-pitched voiced frames */ - { - /*lp_E = mean( pt_bands, nb_bands ) - lp_bckr;*/ /* averaged E in first critical bands, up to 1270 Hz */ - lp_E = L_sub( Mean32( pt_bands, nb_bands ), lp_bckr ); - } - IF( Opt_vbr_mode == 0 ) - { - IF( EQ_16( BASOP_Util_Cmp_Mant32Exp( lp_E, sub( 31, Q_new ), E_MIN_IVAS_FX, 31 - Q19 ), -1 ) ) - { - lp_E = L_shl( E_MIN_IVAS_FX, sub( Q_new, Q19 ) ); - } - } - ELSE - { - lp_E = L_max( lp_E, 0 ); - } - /*ee[i] = lp_E / hp_E[i];*/ /* LF/HF ratio */ - test(); - IF( lp_E != 0 && hp_E[i] != 0 ) - { - e_tmp = sub( norm_l( lp_E ), 1 ); - m_tmp = extract_h( L_shl( lp_E, e_tmp ) ); - e_hpE = norm_l( hp_E[i] ); - m_hpE = extract_h( L_shl( hp_E[i], e_hpE ) ); - m_tmp = div_s( m_tmp, m_hpE ); - e_tmp = sub( e_tmp, e_hpE ); - -#ifdef BASOP_NOGLOB - ee[i] = L_shr_o( m_tmp, add( e_tmp, 15 - 6 ), &Overflow ); /* ee in Q6 */ -#else /* BASOP_NOGLOB */ - ee[i] = L_shr( m_tmp, add( e_tmp, 15 - 6 ) ); /* ee in Q6 */ -#endif - move32(); - } - ELSE IF( lp_E == 0 ) - { - ee[i] = L_deposit_l( 0 ); - move32(); - } - ELSE - { - ee[i] = MAX_32; - move32(); - } - - IF( EQ_16( bwidth, NB ) ) /* For NB input, compensate for the missing bands */ - { -#ifdef BASOP_NOGLOB - Ltmp = L_shl_o( ee[i], 3, &Overflow ); -#else - Ltmp = L_shl( ee[i], 3 ); -#endif - IF( EQ_32( Ltmp, MAX_32 ) ) /* if Overflow: Compute with less precision */ - { - Ltmp = Mult_32_16( ee[i], 24576 ); /* 6/8 */ -#ifdef BASOP_NOGLOB - ee[i] = L_shl_sat( Ltmp, 3 ); -#else - ee[i] = L_shl( Ltmp, 3 ); -#endif - move32(); /* x8 */ - } - ELSE - { - ee[i] = Mult_32_16( Ltmp, 24576 ); - move32(); /* 6/8 */ - } - } - - pt_bands += NB_BANDS; /* Update for next half-frame */ - hf_bands += NB_BANDS; - } - - return; -} diff --git a/lib_enc/find_tilt_fx.c b/lib_enc/find_tilt_fx.c index f0c39eee21dafe9fe30de6bee54dbdd2d4a6854c..ea71b09bc9f73f71ada928bed3bd19be2ef090dd 100644 --- a/lib_enc/find_tilt_fx.c +++ b/lib_enc/find_tilt_fx.c @@ -23,14 +23,15 @@ void find_tilt_fx( const Word16 voicing[3], /* i : normalized correlation for 3 half-frames Q15*/ const Word32 *lf_E, /* i : per bin energy for low frequencies Q_new + Q_SCALE - 2*/ const Word16 corr_shift, /* i : normalized correlation correction Q15*/ - const Word16 bwidth, /* i : input signal bandwidth */ - const Word16 max_band, /* i : maximum critical band */ + const Word16 bwidth, /* i : input signal bandwidth Q0*/ + const Word16 max_band, /* i : maximum critical band Q0*/ Word32 hp_E[], /* o : energy in HF Q_new + Q_SCALE*/ - const Word16 codec_mode, /* i : MODE1 or MODE2 */ + const Word16 codec_mode, /* i : MODE1 or MODE2 Q0*/ const Word16 Q_new, /* i : scaling factor */ - Word32 *bckr_tilt_lt /* i/o: lf/hf E ratio of background noise Q16 */ + Word32 *bckr_tilt_lt /* i/o: lf/hf E ratio of background noise Q16*/ , - Word16 Opt_vbr_mode ) + Word16 Opt_vbr_mode /* Q0 */ +) { Word32 lp_bckr = 0, hp_bckr = 0, lp_E, Ltmp; const Word32 *pt_E, *pt_bands, *pt_bckr, *hf_bands, *tmp_E; @@ -41,8 +42,11 @@ void find_tilt_fx( Word16 m_cnt, e_cnt; Word16 m_hpE, e_hpE; Word16 scaling; + move32(); + move32(); #ifdef BASOP_NOGLOB_DECLARE_LOCAL Flag Overflow = 0; + move32(); #endif /*-----------------------------------------------------------------* * Initializations @@ -53,10 +57,10 @@ void find_tilt_fx( { /* WB processing */ bin = BIN4_FX; - move16(); /* First useful frequency bin ~ 50 Hz */ - pt_bands = fr_bands; - tmp_E = lf_E; - pt_bckr = bckr; + move16(); /* First useful frequency bin ~ 50 Hz */ + pt_bands = fr_bands; /* Q_new + QSCALE */ + tmp_E = lf_E; /* Q_new + QSCALE - 2 */ + pt_bckr = bckr; /* Q_new + QSCALE */ nb_bands = 10; move16(); } @@ -64,9 +68,9 @@ void find_tilt_fx( { /* NB processing */ bin = add( shl( BIN4_FX, 1 ), BIN4_FX ); /* First useful frequency bin ~ 150 Hz */ - pt_bands = fr_bands + 1; /* Exlcude 1st critical band */ - tmp_E = lf_E + 2; /* Start at the 3rd bin (150 Hz) */ - pt_bckr = bckr + 1; /* Exlcude 1st critical band */ + pt_bands = fr_bands + 1; /* Exlcude 1st critical band Q_new + QSCALE*/ + tmp_E = lf_E + 2; /* Start at the 3rd bin (150 Hz) Q_new + QSCALE - 2*/ + pt_bckr = bckr + 1; /* Exlcude 1st critical band Q_new + QSCALE*/ nb_bands = 9; move16(); /* Nb. of "low" frequency bands taken into account in NB processing */ } @@ -75,71 +79,63 @@ void find_tilt_fx( * Find spectrum tilt *-----------------------------------------------------------------*/ - pt_E = tmp_E; /* Point at the 1st useful element of the per-bin energy vector */ - hf_bands = fr_bands; + pt_E = tmp_E; /* Point at the 1st useful element of the per-bin energy vector */ + hf_bands = fr_bands; /* Q_new + QSCALE */ /* bckr + voicing */ /*lp_bckr = mean( pt_bckr, nb_bands );*/ /* estimated noise E in first critical bands, up to 1270 Hz */ lp_bckr = Mean32( pt_bckr, nb_bands ); - /*hp_bckr = 0.5f * (bckr[max_band-1] + bckr[max_band]);*/ /* estimated noise E in last 2 critical bands */ -#ifdef BASOP_NOGLOB - hp_bckr = L_shr( L_add_sat( bckr[max_band - 1], bckr[max_band] ), 1 ); -#else - hp_bckr = L_shr( L_add( bckr[max_band - 1], bckr[max_band] ), 1 ); -#endif - if ( hp_bckr == 0 ) /* Avoid division by zero. */ + /*hp_bckr = 0.5f * (bckr[max_band-1] + bckr[max_band]);*/ /* estimated noise E in last 2 critical bands */ + hp_bckr = L_shr( L_add_sat( bckr[max_band - 1], bckr[max_band] ), 1 ); /* Q_new + QSCALE - 1 */ + if ( hp_bckr == 0 ) /* Avoid division by zero. */ { hp_bckr = L_deposit_l( 1 ); } tmp = BASOP_Util_Divide3232_Scale( lp_bckr, hp_bckr, &e_tmp ); + +#ifdef FIX_ISSUE_1152 + Ltmp = L_shr_r_sat( L_deposit_h( tmp ), sub( 15, e_tmp ) ); +#else Ltmp = L_shr_r( L_deposit_h( tmp ), sub( 15, e_tmp ) ); - *bckr_tilt_lt = L_add( Mpy_32_16_r( *bckr_tilt_lt, 29491 ), Mpy_32_16_r( Ltmp, 3277 ) ); +#endif + + *bckr_tilt_lt = L_add( Mpy_32_16_r( *bckr_tilt_lt, 29491 ), Mpy_32_16_r( Ltmp, 3277 ) ); /* Q16 */ test(); IF( EQ_16( codec_mode, MODE2 ) || Opt_vbr_mode == 1 ) { /*lp_bckr *= FACT;*/ /*hp_bckr *= FACT;*/ -#ifdef BASOP_NOGLOB - lp_bckr = L_add_sat( L_shl_sat( lp_bckr, 1 ), lp_bckr ); + lp_bckr = L_add_sat( L_shl_sat( lp_bckr, 1 ), lp_bckr ); /* Q_new + QSCALE */ hp_bckr = L_add_sat( L_shl_sat( hp_bckr, 1 ), hp_bckr ); -#else - lp_bckr = L_add( L_shl( lp_bckr, 1 ), lp_bckr ); - hp_bckr = L_add( L_shl( hp_bckr, 1 ), hp_bckr ); -#endif } /*mean_voi = 0.5f * (voicing[1] + voicing[2]) + corr_shift;*/ - Ltmp = L_mult( voicing[1], 16384 ); - Ltmp = L_mac( Ltmp, voicing[2], 16384 ); -#ifdef BASOP_NOGLOB - Ltmp = L_mac_o( Ltmp, corr_shift, 32767, &Overflow ); - mean_voi = round_fx_o( Ltmp, &Overflow ); -#else - Ltmp = L_mac( Ltmp, corr_shift, 32767 ); - mean_voi = round_fx( Ltmp ); -#endif + Ltmp = L_mult( voicing[1], 16384 /* 0.5 in Q15 */ ); /* Q31 */ + Ltmp = L_mac( Ltmp, voicing[2], 16384 /* 0.5 in Q15 */ ); /* Q31 */ + Ltmp = L_mac_o( Ltmp, corr_shift, 32767, &Overflow ); /* Q31 */ + mean_voi = round_fx_o( Ltmp, &Overflow ); /* Q15 */ /*f0 = INT_FS_FX / pitch[2];*/ e_tmp = norm_s( pitch[2] ); m_tmp = shl( pitch[2], e_tmp ); - m_Fs = div_s( INT_FS_FX, m_tmp ); + m_Fs = div_s( INT_FS_FX, m_tmp ); /* exp(e_tmp) */ e_Fs = sub( 15, e_tmp ); f0 = shr( m_Fs, sub( e_Fs, 4 ) ); /* Q4 */ FOR( i = 0; i < 2; i++ ) { - /*hp_E[i] = 0.5f * (hf_bands[max_band-1] + hf_bands[max_band]) - hp_bckr; */ /* averaged E in last 2 critical bands */ - Ltmp = L_add( L_shr( hf_bands[max_band - 1], 1 ), L_shr( hf_bands[max_band], 1 ) ); - hp_E[i] = L_sub( Ltmp, hp_bckr ); + /*hp_E[i] = 0.5f * (hf_bands[max_band-1] + hf_bands[max_band]) - hp_bckr; */ /* averaged E in last 2 critical bands */ + Ltmp = L_add( L_shr( hf_bands[max_band - 1], 1 ), L_shr( hf_bands[max_band], 1 ) ); /* Q_new + QSCALE */ + hp_E[i] = L_sub( Ltmp, hp_bckr ); /* Q_new + QSCALE */ IF( Opt_vbr_mode == 0 ) { - hp_E[i] = L_max( hp_E[i], L_shl( E_MIN_FX, Q_new ) ); + hp_E[i] = L_max( hp_E[i], L_shl( E_MIN_FX, Q_new ) ); /* Q_new + QSCALE */ move32(); } ELSE { - hp_E[i] = L_max( hp_E[i], L_shl( 1, scaling ) ); + hp_E[i] = L_max( hp_E[i], L_shl( 1, scaling ) ); /* Q_new + QSCALE */ move32(); } @@ -163,22 +159,13 @@ void find_tilt_fx( tmp = sub( freq, f2 ); IF( L_mac0( -(Word32) TH_D_FX * TH_D_FX, tmp, tmp ) < 0 ) { -#ifdef BASOP_NOGLOB - lp_E = L_add_o( *pt_E, lp_E, &Overflow ); -#else - lp_E = L_add( *pt_E, lp_E ); -#endif - m_cnt = add( m_cnt, 1 ); + lp_E = L_add_o( *pt_E, lp_E, &Overflow ); /* Q_new + QSCALE - 2 */ + m_cnt = add( m_cnt, 1 ); /* Q0 */ } pt_E++; } -#ifdef BASOP_NOGLOB f1 = add_o( f1, f0, &Overflow ); f2 = add_o( f2, f0, &Overflow ); -#else - f1 = add( f1, f0 ); - f2 = add( f2, f0 ); -#endif } /*lp_E = lp_E / (float)cnt - lp_bckr;*/ e_tmp = sub( norm_l( lp_E ), 1 ); @@ -189,21 +176,17 @@ void find_tilt_fx( e_cnt = norm_s( m_cnt ); m_cnt = shl( m_cnt, e_cnt ); - m_tmp = div_s( m_tmp, m_cnt ); + m_tmp = div_s( m_tmp, m_cnt ); /* exp(e_tmp + e_cnt) */ e_tmp = sub( e_tmp, e_cnt ); -#ifdef BASOP_NOGLOB - lp_E = L_sub_o( L_shr_o( m_tmp, sub( e_tmp, 1 ), &Overflow ), lp_bckr, &Overflow ); -#else - lp_E = L_sub( L_shr( m_tmp, sub( e_tmp, 1 ) ), lp_bckr ); -#endif + lp_E = L_sub_o( L_shr_o( m_tmp, sub( e_tmp, 1 ), &Overflow ), lp_bckr, &Overflow ); /* Q_new + QSCALE */ pt_E = tmp_E + VOIC_BINS; /* Update for next half-frame */ } ELSE /* Other than high-pitched voiced frames */ { - /*lp_E = mean( pt_bands, nb_bands ) - lp_bckr;*/ /* averaged E in first critical bands, up to 1270 Hz */ - lp_E = L_sub( Mean32( pt_bands, nb_bands ), lp_bckr ); + /*lp_E = mean( pt_bands, nb_bands ) - lp_bckr;*/ /* averaged E in first critical bands, up to 1270 Hz */ + lp_E = L_sub( Mean32( pt_bands, nb_bands ), lp_bckr ); /* Q_new + QSCALE */ } IF( Opt_vbr_mode == 0 ) { @@ -221,14 +204,10 @@ void find_tilt_fx( m_tmp = extract_h( L_shl( lp_E, e_tmp ) ); e_hpE = norm_l( hp_E[i] ); m_hpE = extract_h( L_shl( hp_E[i], e_hpE ) ); - m_tmp = div_s( m_tmp, m_hpE ); + m_tmp = div_s( m_tmp, m_hpE ); /* exp(e_tmp + e_hpE) */ e_tmp = sub( e_tmp, e_hpE ); -#ifdef BASOP_NOGLOB ee[i] = L_shr_o( m_tmp, add( e_tmp, 15 - 6 ), &Overflow ); /* ee in Q6 */ -#else /* BASOP_NOGLOB */ - ee[i] = L_shr( m_tmp, add( e_tmp, 15 - 6 ) ); /* ee in Q6 */ -#endif } ELSE IF( lp_E == 0 ) { @@ -241,24 +220,268 @@ void find_tilt_fx( IF( EQ_16( bwidth, NB ) ) /* For NB input, compensate for the missing bands */ { -#ifdef BASOP_NOGLOB Ltmp = L_shl_o( ee[i], 3, &Overflow ); -#else - Ltmp = L_shl( ee[i], 3 ); -#endif IF( EQ_32( Ltmp, MAX_32 ) ) /* if Overflow: Compute with less precision */ { - Ltmp = Mult_32_16( ee[i], 24576 ); /* 6/8 */ -#ifdef BASOP_NOGLOB + Ltmp = Mult_32_16( ee[i], 24576 /* 0.75 in Q15 */ ); /* 6/8 Q6*/ ee[i] = L_shl_sat( Ltmp, 3 ); -#else - ee[i] = L_shl( Ltmp, 3 ); -#endif move32(); /* x8 */ } ELSE { - ee[i] = Mult_32_16( Ltmp, 24576 ); + ee[i] = Mult_32_16( Ltmp, 24576 /* 0.75 in Q15 */ ); /* Q6 */ + move32(); /* 6/8 */ + } + } + + pt_bands += NB_BANDS; /* Update for next half-frame */ + hf_bands += NB_BANDS; + } + + return; +} + +/*-------------------------------------------------------------------* + * find_tilt() + * + * Find LF/HF energy ratio + *-------------------------------------------------------------------*/ +void find_tilt_ivas_fx( + const Word32 fr_bands[], /* i : energy in frequency bands q_fr_bands*/ + const Word16 q_fr_bands, /* i : Q of fr_bands Q0*/ + const Word32 bckr[], /* i : per band background noise energy estimate q_bckr*/ + const Word16 q_bckr, /* i : Q of bckr Q0*/ + Word32 ee[2], /* o : lf/hf E ration for present frame Q6*/ + const Word16 pitch[3], /* i : open loop pitch values for 3 half-frames Q0*/ + const Word16 voicing[3], /* i : normalized correlation for 3 half-frames Q15*/ + const Word32 *lf_E, /* i : per bin energy for low frequencies q_lf_E*/ + const Word16 q_lf_E, /* i : Q of lf_E */ + const Word16 corr_shift, /* i : normalized correlation correction Q15*/ + const Word16 bwidth, /* i : input signal bandwidth */ + const Word16 max_band, /* i : maximum critical band */ + Word32 hp_E[], /* o : energy in HF Q_new*/ + const Word16 codec_mode, /* i : MODE1 or MODE2 */ + Word32 *bckr_tilt_lt, /* i/o: lf/hf E ratio of background noise Q16 */ + Word16 Opt_vbr_mode ) +{ + Word32 lp_bckr = 0, hp_bckr = 0, lp_E, Ltmp; + const Word32 *pt_E, *pt_bands, *pt_bckr, *hf_bands, *tmp_E; + Word16 tmp, freq, f0, f1, f2, mean_voi, bin; + Word16 i, nb_bands; + Word16 e_tmp, m_tmp; + Word16 m_Fs, e_Fs; + Word16 m_cnt, e_cnt; + Word16 m_hpE, e_hpE; + Word64 sum; + Word16 inv_bands, q_lp_E; + Word32 Le_min_scaled, Ltmp2; +#ifdef BASOP_NOGLOB_DECLARE_LOCAL + Flag Overflow = 0; + move32(); +#endif + move32(); + move32(); + /*-----------------------------------------------------------------* + * Initializations + *-----------------------------------------------------------------*/ + + IF( ( bwidth != NB ) ) + { + /* WB processing */ + bin = BIN4_FX; + move16(); /* First useful frequency bin ~ 50 Hz */ + pt_bands = fr_bands; /* Q_new */ + tmp_E = lf_E; /* Q_new - 2 */ + pt_bckr = bckr; /* Q_new */ + nb_bands = 10; + inv_bands = 3277 /* 1/10 in Q15 */; + move16(); + move16(); + } + ELSE + { + /* NB processing */ + bin = 3 * BIN4_FX; /* First useful frequency bin ~ 150 Hz */ + pt_bands = fr_bands + 1; /* Exlcude 1st critical band */ + tmp_E = lf_E + 2; /* Start at the 3rd bin (150 Hz) */ + pt_bckr = bckr + 1; /* Exlcude 1st critical band */ + nb_bands = 9; + inv_bands = 3641; /* 1/9 in Q15 */ + move16(); + move16(); /* Nb. of "low" frequency bands taken into account in NB processing */ + } + + /*-----------------------------------------------------------------* + * Find spectrum tilt + *-----------------------------------------------------------------*/ + + pt_E = tmp_E; /* Point at the 1st useful element of the per-bin energy vector */ + hf_bands = fr_bands; + + /* bckr + voicing */ + /*lp_bckr = mean( pt_bckr, nb_bands );*/ /* estimated noise E in first critical bands, up to 1270 Hz */ + sum = 0; + move64(); + FOR( i = 0; i < nb_bands; i++ ) + { + sum = W_mac_32_16( sum, pt_bckr[i], inv_bands ); // q_bckr+16 + } + lp_bckr = W_shl_sat_l( sum, -16 ); // q_bckr + /*hp_bckr = 0.5f * (bckr[max_band-1] + bckr[max_band]);*/ /* estimated noise E in last 2 critical bands */ + hp_bckr = W_extract_h( W_mac_32_32( W_mult_32_32( bckr[max_band - 1], ONE_IN_Q30 ), bckr[max_band], ONE_IN_Q30 ) ); // q_bckr + if ( hp_bckr == 0 ) /* Avoid division by zero. */ + { + hp_bckr = L_deposit_l( 1 ); + } + Ltmp = BASOP_Util_Divide3232_Scale_cadence( lp_bckr, hp_bckr, &e_tmp ); + Ltmp = Mpy_32_16_r( Ltmp, 3277 /* 0.1f in Q15 */ ); + Ltmp = L_shr_sat( Ltmp, sub( 15, e_tmp ) ); + *bckr_tilt_lt = L_add_sat( Mpy_32_16_r( *bckr_tilt_lt, 29491 /* 0.9f in Q15 */ ), Ltmp ); // Q16 + move32(); + + test(); + IF( EQ_16( codec_mode, MODE2 ) || EQ_16( Opt_vbr_mode, 1 ) ) + { + /*lp_bckr *= FACT;*/ + /*hp_bckr *= FACT;*/ + lp_bckr = L_add_sat( L_shl_sat( lp_bckr, 1 ), lp_bckr ); /* Q_new */ + hp_bckr = L_add_sat( L_shl_sat( hp_bckr, 1 ), hp_bckr ); /* Q_new */ + } + /*mean_voi = 0.5f * (voicing[1] + voicing[2]) + corr_shift;*/ + Ltmp = L_mult( voicing[1], 16384 /* 0.5 in Q15 */ ); // Q31 + Ltmp = L_mac( Ltmp, voicing[2], 16384 /* 0.5 in Q15 */ ); // Q31 + Ltmp = L_mac_o( Ltmp, corr_shift, 32767 /* 1.0f in Q15 */, &Overflow ); // Q31 + mean_voi = round_fx_o( Ltmp, &Overflow ); // Q15 + + /*f0 = INT_FS_FX / pitch[2];*/ + e_tmp = norm_s( pitch[2] ); + m_tmp = shl( pitch[2], e_tmp ); + + m_Fs = div_s( INT_FS_FX, m_tmp ); /* exp(e_tmp) */ + e_Fs = sub( 15, e_tmp ); + f0 = shr( m_Fs, sub( e_Fs, 4 ) ); /* Q4 */ + + Le_min_scaled = L_shl( E_MIN_FXQ31, sub( q_fr_bands, Q31 ) ); // q_fr_bands=q_bckr + + FOR( i = 0; i < 2; i++ ) + { + /*hp_E[i] = 0.5f * (hf_bands[max_band-1] + hf_bands[max_band]) - hp_bckr; */ /* averaged E in last 2 critical bands */ + Ltmp = W_extract_h( W_mac_32_32( W_mult_32_32( hf_bands[max_band - 1], ONE_IN_Q30 ), hf_bands[max_band], ONE_IN_Q30 ) ); // q_fr_bands + Ltmp = L_sub( Ltmp, hp_bckr ); // q_fr_bands + + Ltmp2 = L_max( Ltmp, L_shl_sat( 1, q_fr_bands ) ); // q_fr_bands, saturation is added because q_fr_bands is limited to 31 + if ( Opt_vbr_mode == 0 ) + { + Ltmp2 = L_max( Ltmp, Le_min_scaled ); // q_fr_bands + } + hp_E[i] = L_max( Ltmp2, 1 ); // to prevent division by zero + move32(); + + test(); + IF( GT_16( mean_voi, TH_COR_FX ) && LT_16( pitch[2], TH_PIT_FX ) ) /* High-pitched voiced frames */ + { + freq = bin; // Q4 + move16(); /* 1st useful frequency bin */ + m_cnt = 0; + move16(); + sum = 0; + move64(); + + f1 = add( shr( f0, 1 ), f0 ); /* Middle between 2 harmonics */ + f2 = f0; + move16(); + WHILE( LE_16( freq, 20320 /* 1270.0f in Q4 */ ) ) /* End frequency of 10th critical band */ + { + FOR( ; freq <= f1; freq += BIN4_FX ) + { + /* include only bins sufficiently close to harmonics */ + tmp = sub( freq, f2 ); + IF( L_mac0( -TH_D_FX * TH_D_FX, tmp, tmp ) < 0 ) + { + sum = W_mac_32_16( sum, *pt_E, 1 ); // q_lf_E+1 + m_cnt = add( m_cnt, 1 ); + } + pt_E++; + } + f1 = add_o( f1, f0, &Overflow ); + f2 = add_o( f2, f0, &Overflow ); + } + /*lp_E = lp_E / (float)cnt - lp_bckr;*/ + e_tmp = sub( W_norm( sum ), 1 ); + m_tmp = extract_h( W_extract_h( W_shl( sum, e_tmp ) ) ); // q_lf_E+1+e_tmp-32-16 + e_tmp = sub( add( q_lf_E, e_tmp ), 47 ); + + e_cnt = norm_s( m_cnt ); + m_cnt = shl( m_cnt, e_cnt ); // e_cnt + + m_tmp = div_s( m_tmp, m_cnt ); // Q15+e_tmp-e_cnt + e_tmp = add( Q15, sub( e_tmp, e_cnt ) ); + sum = W_shl( m_tmp, sub( add( q_bckr, 1 ), e_tmp ) ); // q_bckr+1 + sum = W_msu_32_16( sum, lp_bckr, 1 ); // q_bckr+1 + q_lp_E = W_norm( sum ); + lp_E = W_extract_h( W_shl( sum, q_lp_E ) ); // q_bckr+1+q_lp_E-32 + q_lp_E = sub( add( q_lp_E, q_bckr ), Q31 ); + + pt_E = tmp_E + VOIC_BINS; /* Update for next half-frame Q_new - 1 */ + } + ELSE /* Other than high-pitched voiced frames */ + { + /*lp_E = mean( pt_bands, nb_bands ) - lp_bckr;*/ /* averaged E in first critical bands, up to 1270 Hz */ + sum = 0; + move64(); + FOR( Word16 j = 0; j < nb_bands; j++ ) + { + sum = W_mac_32_16( sum, pt_bands[j], inv_bands ); // q_fr_bands+16 + } + sum = W_mac_32_16( sum, lp_bckr, -ONE_IN_Q15 ); // q_fr_bands+16 + lp_E = W_round48_L( sum ); // q_fr_bands=q_bckr + q_lp_E = q_bckr; // q_fr_bands=q_bckr + move16(); + } + test(); + IF( Opt_vbr_mode == 0 && GT_32( L_shl_sat( Le_min_scaled, sub( q_lp_E, q_bckr ) ), lp_E ) ) + { + lp_E = E_MIN_FXQ31; + q_lp_E = Q31; + move32(); + move16(); + } + if ( Opt_vbr_mode != 0 ) + { + lp_E = L_max( lp_E, 0 ); // q_lp_E + } + /*ee[i] = lp_E / hp_E[i];*/ /* LF/HF ratio */ + + if ( lp_E == 0 ) + { + ee[i] = 0; + move32(); + } + test(); + IF( lp_E != 0 ) + { + e_tmp = sub( norm_l( lp_E ), 1 ); + m_tmp = extract_h( L_shl( lp_E, e_tmp ) ); // e_tmp+q_lp_E-16 + e_hpE = norm_l( hp_E[i] ); + m_hpE = extract_h( L_shl( hp_E[i], e_hpE ) ); // e_hpE+q_bckr-16 + m_tmp = div_s( m_tmp, m_hpE ); // Q15+(e_tmp+q_lp_E)-(e_hpE+q_bckr) + e_tmp = sub( add( e_tmp, q_lp_E ), add( e_hpE, q_bckr ) ); + ee[i] = L_shr_o( m_tmp, add( e_tmp, 15 - 6 ), &Overflow ); /* ee in Q6 */ + move32(); + } + + IF( bwidth == NB ) /* For NB input, compensate for the missing bands */ + { + Ltmp = L_shl_o( ee[i], 3, &Overflow ); /* Q6 */ + IF( EQ_32( Ltmp, MAX_32 ) ) /* if Overflow: Compute with less precision */ + { + Ltmp = Mult_32_16( ee[i], 24576 /* 0.75 in Q15 */ ); /* 6/8 Q6*/ + ee[i] = L_shl_sat( Ltmp, 3 ); /* Q6 */ + move32(); /* x8 */ + } + ELSE + { + ee[i] = Mult_32_16( Ltmp, 24576 /* 0.75 in Q15 */ ); move32(); /* 6/8 */ } } diff --git a/lib_enc/find_uv.c b/lib_enc/find_uv.c deleted file mode 100644 index 972c402426034edf8f20cc593fc90e353a64f29a..0000000000000000000000000000000000000000 --- a/lib_enc/find_uv.c +++ /dev/null @@ -1,724 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include -#include "cnst.h" -#include "prot.h" -#include "wmc_auto.h" - -#include "prot_fx.h" /* Function prototypes */ -#include "prot_fx_enc.h" /* Function prototypes */ - -/*-------------------------------------------------------------------* - * Local constants - *-------------------------------------------------------------------*/ - -#define L_ENR ( NB_SSF + 2 ) - -/*-------------------------------------------------------------------* - * find_ener_decrease() - * - * Find maximum energy ratio between short sub-subframes in case - * energy is trailing off after a spike - *-------------------------------------------------------------------*/ - -/*! r: maximum energy ratio */ -static Word16 find_ener_decrease_fx( /* o : maximum energy ratio Q10 */ - const Word16 ind_deltaMax, /* i : index of the beginning of maximum energy search */ - const Word32 *pt_enr_ssf /* i : Pointer to the energy buffer */ -) -{ - Word16 i, j, end, flag; - Word16 wtmp0, wtmp1; - Word32 maxEnr, minEnr; - Word16 dE2, exp0, exp1; -#ifdef BASOP_NOGLOB_DECLARE_LOCAL - Flag Overflow = 0; - move32(); -#endif - dE2 = 0; - move16(); - - j = ind_deltaMax + 2; - move16(); - end = j + L_ENR; - move16(); - maxEnr = L_add( pt_enr_ssf[j], 0 ); - j = add( j, 1 ); - flag = 0; - move16(); - FOR( i = j; i < end; i++ ) - { - test(); - IF( ( GT_32( pt_enr_ssf[i], maxEnr ) ) && ( flag == 0 ) ) - { - maxEnr = L_add( pt_enr_ssf[i], 0 ); /*Q0*/ - j = add( j, 1 ); - } - ELSE - { - flag = 1; - move16(); - } - } - - minEnr = L_add( maxEnr, 0 ); - FOR( i = j; i < end; i++ ) - { - minEnr = L_min( minEnr, pt_enr_ssf[i] ); - } - - -#ifdef BASOP_NOGLOB - minEnr = L_add_sat( minEnr, 100000 ); -#else - minEnr = L_add( minEnr, 100000 ); -#endif - exp0 = norm_l( minEnr ); - wtmp0 = extract_h( L_shl( minEnr, exp0 ) ); - exp1 = sub( norm_l( maxEnr ), 1 ); - wtmp1 = extract_h( L_shl( maxEnr, exp1 ) ); - wtmp1 = div_s( wtmp1, wtmp0 ); -#ifdef BASOP_NOGLOB - dE2 = shr_ro( wtmp1, add( sub( exp1, exp0 ), 15 - 10 ), &Overflow ); /*Q10*/ -#else - dE2 = shr_r( wtmp1, add( sub( exp1, exp0 ), 15 - 10 ) ); /*Q10*/ -#endif - - return dE2; -} - -/*-------------------------------------------------------------------* - * find_uv() - * - * Decision about coder type - *-------------------------------------------------------------------*/ -Word16 find_uv_ivas_fx( /* o : coding type */ - Encoder_State *st_fx, /* i/o: encoder state structure */ - const Word16 *T_op_fr, /* i : pointer to adjusted fractional pitch (4 val.) Q6 */ - const Word16 *voicing_fr, /* i : refined correlation for each subframes Q15 */ - const Word16 *speech, /* i : pointer to speech signal for E computation Q_new */ - const Word32 *ee, /* i : lf/hf Energy ratio for present frame Q6 */ - Word32 *dE1X, /* o : sudden energy increase for S/M classifier */ - const Word16 corr_shift, /* i : normalized correlation correction in noise Q15 */ - const Word16 relE, /* i : relative frame energy Q8 */ - const Word16 Etot, /* i : total energy Q8 */ - const Word32 hp_E[], /* i : energy in HF q_hp_E */ - Word16 *flag_spitch, /* i/o: flag to indicate very short stable pitch and high correlation */ - const Word16 last_core_orig, /* i : original last core */ - STEREO_CLASSIF_HANDLE hStereoClassif, /* i/o: stereo classifier structure */ - const Word16 Q_new, - const Word16 q_hp_E ) -{ - Word16 coder_type, i; - Word32 mean_ee, dE1, fac_32; - const Word16 *pt_speech; - Word32 L_tmp, enr_ssf[2 * NB_SSF + 2 * NB_SSF + 2], E_min_th; - Word16 dE2; - Word16 ind_deltaMax, tmp_offset_flag; - Word32 Ltmp0, *pt_enr_ssf, *pt_enr_ssf1, dE2_th; - Word16 exp0, exp1; - Word16 wtmp0, wtmp1; - Word16 fac, mean_voi3, dE3; - Word16 relE_thres; - Word16 mean_voi3_offset; - Word16 voicing_m, dpit1, dpit2, dpit3; - Word16 ee0_th, ee1_th, voi_th, nb_cond, flag_low_relE; - NOISE_EST_HANDLE hNoiseEst = st_fx->hNoiseEst; - SC_VBR_ENC_HANDLE hSC_VBR = st_fx->hSC_VBR; -#ifdef BASOP_NOGLOB_DECLARE_LOCAL - Flag Overflow = 0; - move32(); -#endif - Word16 Last_Resort; - Word16 vadnoise; - - IF( hSC_VBR != NULL ) - { - Last_Resort = hSC_VBR->Last_Resort; - move16(); - vadnoise = hSC_VBR->vadnoise_fx; - move16(); - } - ELSE - { - Last_Resort = 0; - move16(); - vadnoise = 0; - move16(); - } - - /*-----------------------------------------------------------------* - * Detect sudden energy increases to catch voice and music - * temporal events (dE1) - * - * - Find maximum energy per short subblocks. - * Two subblock sets are used shifted by half the subblock length - * - Find maximum energy ratio between adjacent subblocks - *-----------------------------------------------------------------*/ - - /* Find maximum energy per short subblocks */ - pt_speech = speech - SSF; - pt_enr_ssf = enr_ssf + 2 * NB_SSF; - FOR( i = 0; i < 2 * ( NB_SSF + 1 ); i++ ) - { - emaximum_fx( Q_new, pt_speech, SSF, pt_enr_ssf ); - pt_speech += ( SSF / 2 ); - pt_enr_ssf++; - } - - dE1 = 0; - move16(); - ind_deltaMax = 0; - move16(); - pt_enr_ssf = enr_ssf + 2 * NB_SSF; - pt_enr_ssf1 = pt_enr_ssf + 2; - - /* Test on energy increase between adjacent sub-subframes */ - exp1 = 0; - move16(); - FOR( i = 0; i < 2 * NB_SSF; i++ ) - { - /*fac = *pt_enr_ssf1 / (*pt_enr_ssf + 1);*/ - Ltmp0 = L_max( *pt_enr_ssf, 1 ); - exp0 = norm_l( Ltmp0 ); - wtmp0 = extract_h( L_shl( Ltmp0, exp0 ) ); - exp1 = sub( norm_l( *pt_enr_ssf1 ), 1 ); - wtmp1 = extract_h( L_shl( *pt_enr_ssf1, exp1 ) ); - fac = div_s( wtmp1, wtmp0 ); -#ifdef BASOP_NOGLOB - fac_32 = L_shr_o( L_deposit_l( fac ), add( sub( exp1, exp0 ), 15 - 13 ), &Overflow ); /* fac32 in Q13*/ -#else /* BASOP_NOGLOB */ - fac_32 = L_shr( L_deposit_l( fac ), add( sub( exp1, exp0 ), 15 - 13 ) ); /* fac32 in Q13*/ -#endif /* BASOP_NOGLOB */ - - if ( GT_32( fac_32, dE1 ) ) - { - ind_deltaMax = i; - move16(); - } - - dE1 = L_max( dE1, fac_32 ); - - pt_enr_ssf++; - pt_enr_ssf1++; - } - - IF( hStereoClassif != NULL ) - { - IF( st_fx->idchan == 0 ) - { - hStereoClassif->dE1_ch1_fx = dE1; - move32(); - hStereoClassif->dE1_ch1_e = 31 - Q13; - move16(); - } - ELSE - { - hStereoClassif->dE1_ch2_fx = dE1; - move32(); - hStereoClassif->dE1_ch2_e = 31 - Q13; - move16(); - } - } - - if ( dE1X != NULL ) - { - *dE1X = dE1; - move32(); - } - - /*-----------------------------------------------------------------* - * Average spectral tilt - * Average voicing (normalized correlation) - *-----------------------------------------------------------------*/ - - /*mean_ee = 1.0f/3.0f * (st->ee_old + ee[0] + ee[1]); */ /* coefficients take into account the position of the window */ -#ifdef BASOP_NOGLOB - mean_ee = L_add_o( L_add_o( st_fx->ee_old_fx, ee[0], &Overflow ), ee[1], &Overflow ); -#else /* BASOP_NOGLOB */ - mean_ee = L_add( L_add( st_fx->ee_old_fx, ee[0] ), ee[1] ); -#endif /* BASOP_NOGLOB */ - mean_ee = Mult_32_16( mean_ee, 10923 ); /*Q6*/ - - /* mean_voi3 = 1.0f/3.0f * (voicing[0] + voicing[1] + voicing[2]);*/ - Ltmp0 = L_mult( st_fx->voicing_fx[0], 10923 ); - Ltmp0 = L_mac( Ltmp0, st_fx->voicing_fx[1], 10923 ); -#ifdef BASOP_NOGLOB // -dtx 12650 amrwb\Dtx3.INP - mean_voi3 = mac_r_sat( Ltmp0, st_fx->voicing_fx[2], 10923 ); /*Q15*/ -#else - mean_voi3 = mac_r( Ltmp0, st_fx->voicing_fx[2], 10923 ); /*Q15*/ -#endif - /*-----------------------------------------------------------------* - * Total frame energy difference (dE3) - *-----------------------------------------------------------------*/ - - dE3 = sub( Etot, hNoiseEst->Etot_last_fx ); /*Q8*/ - - /*-----------------------------------------------------------------* - * Energy decrease after spike (dE2) - *-----------------------------------------------------------------*/ - - /* set different thresholds and conditions for NB and WB input */ - dE2_th = 30 << 10; - move32(); - nb_cond = 1; - move16(); /* no additional condition for WB input */ - IF( EQ_16( st_fx->input_bwidth, NB ) ) - { - dE2_th = 21 << 10; - move32(); -#ifdef BASOP_NOGLOB - if ( GE_16( add_o( mean_voi3, corr_shift, &Overflow ), 22282 ) ) /*( mean_voi3 + corr_shift ) >= 0.68f*/ -#else - if ( GE_16( add( mean_voi3, corr_shift ), 22282 ) ) /*( mean_voi3 + corr_shift ) >= 0.68f*/ -#endif - { - nb_cond = 0; - move16(); - } - } - - /* calcualte maximum energy decrease */ - dE2 = 0; - move16(); /* Test on energy decrease after an energy spike */ - pt_enr_ssf = enr_ssf + 2 * NB_SSF; - - test(); - IF( GT_32( dE1, 30 << 13 ) && nb_cond ) /*>30 Q13*/ - { - IF( LT_16( sub( shl( NB_SSF, 1 ), ind_deltaMax ), L_ENR ) ) - { - st_fx->old_ind_deltaMax = ind_deltaMax; - move16(); - Copy32( pt_enr_ssf, st_fx->old_enr_ssf_fx, 2 * NB_SSF ); - } - ELSE - { - st_fx->old_ind_deltaMax = -1; - move16(); - dE2 = find_ener_decrease_fx( ind_deltaMax, pt_enr_ssf ); /*Q10*/ - - if ( GT_32( dE2, dE2_th ) ) - { - st_fx->spike_hyst = 0; - move16(); - } - } - } - ELSE - { - IF( st_fx->old_ind_deltaMax >= 0 ) - { - Copy32( st_fx->old_enr_ssf_fx, enr_ssf, 2 * NB_SSF ); - dE2 = find_ener_decrease_fx( st_fx->old_ind_deltaMax, enr_ssf ); - - if ( GT_32( dE2, dE2_th ) ) - { - st_fx->spike_hyst = 1; - move16(); - } - } - - st_fx->old_ind_deltaMax = -1; - move16(); - } - - /*-----------------------------------------------------------------* - * Detection of voiced offsets (tmp_offset_flag) - *-----------------------------------------------------------------*/ - - tmp_offset_flag = 1; - move16(); - - IF( NE_16( st_fx->input_bwidth, NB ) ) - { - ee0_th = 154; /*2.4 in Q6 */ - move16(); - voi_th = 24248; /*0.74f Q15 */ - move16(); - } - ELSE - { - ee0_th = 627; /*9.8f Q6 */ - move16(); - voi_th = 24904; /*0.76f Q15*/ - move16(); - } - - E_min_th = L_shl( E_MIN_IVAS_FX, sub( q_hp_E, Q19 ) ); - - test(); - test(); - test(); -#ifdef BASOP_NOGLOB - if ( ( EQ_16( st_fx->last_coder_type_raw, UNVOICED ) ) || /* previous frame was unvoiced */ - ( ( LT_32( ee[0], ee0_th ) ) && ( GT_32( hp_E[0], E_min_th ) ) && /* energy is concentrated in high frequencies provided that some energy is present in HF */ - ( LT_16( add_o( st_fx->voicing_fx[0], corr_shift, &Overflow ), voi_th ) ) ) ) /* normalized correlation is low */ -#else /* BASOP_NOGLOB */ - if ( ( EQ_16( st_fx->last_coder_type_raw, UNVOICED ) ) || /* previous frame was unvoiced */ - ( ( LT_32( ee[0], ee0_th ) ) && ( GT_32( hp_E[0], E_min_th ) ) && /* energy is concentrated in high frequencies provided that some energy is present in HF */ - ( LT_16( add( st_fx->voicing_fx[0], corr_shift ), voi_th ) ) ) ) /* normalized correlation is low */ -#endif /* BASOP_NOGLOB */ - { - tmp_offset_flag = 0; - move16(); - } - - /*-----------------------------------------------------------------* - * Decision about UC - *-----------------------------------------------------------------*/ - - /* SC-VBR - set additional parameters and thresholds for SC-VBR */ - mean_voi3_offset = 0; - move16(); - flag_low_relE = 0; - move16(); - ee1_th = 608; /*9.5 Q6*/ - move16(); - test(); - test(); - IF( st_fx->Opt_SC_VBR || ( EQ_16( st_fx->idchan, 1 ) && EQ_16( st_fx->element_mode, IVAS_CPE_TD ) ) ) /* Allow the low energy flag for the secondary channel */ - { - ee1_th = 544; /*8.5f Q6*/ - move16(); - - /* SC-VBR - determine the threshold on relative energy as a function of lp_noise */ - IF( NE_16( st_fx->input_bwidth, NB ) ) - { - /*relE_thres = 0.700f * st->lp_noise - 33.5f; (lp_noise in Q8, constant Q8<<16) */ - L_tmp = L_mac( -562036736, 22938, st_fx->lp_noise_fx ); - if ( Last_Resort == 0 ) - { - /*relE_thres = 0.650f * st->lp_noise - 33.5f; (lp_noise in Q8, constant Q8<<16)*/ - L_tmp = L_mac( -562036736, 21299, st_fx->lp_noise_fx ); - } - relE_thres = round_fx( L_tmp ); - } - ELSE - { - - /*relE_thres = 0.60f * st->lp_noise - 28.2f; (lp_noise in Q8, constant Q8<<16)*/ - L_tmp = L_mac( -473117491, 19661, st_fx->lp_noise_fx ); - relE_thres = round_fx( L_tmp ); - } - relE_thres = s_max( relE_thres, -6400 ); /* Q8 */ - - /* SC-VBR = set flag on low relative energy */ - if ( LT_16( relE, relE_thres ) ) - { - flag_low_relE = 1; - move16(); - } - - /* SC-VBR - correction of voicing threshold for NB inputs (important only in noisy conditions) */ - test(); - if ( EQ_16( st_fx->input_bwidth, NB ) && LT_16( vadnoise, 20 << 8 ) ) /* vadnoise in Q8, constant Q0<<8 */ - { - mean_voi3_offset = 1638; /*0.05f Q15*/ - move16(); - } - } - - /* make decision whether frame is unvoiced */ - coder_type = GENERIC; - move16(); - IF( EQ_16( st_fx->input_bwidth, NB ) ) - { - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); -#ifdef BASOP_NOGLOB - if ( ( ( LT_16( add_o( mean_voi3, corr_shift, &Overflow ), add( 22282, mean_voi3_offset ) ) ) && /* normalized correlation low */ - ( LT_16( add_o( st_fx->voicing_fx[2], corr_shift, &Overflow ), 25887 ) ) && /* normalized correlation low on look-ahead - onset detection */ - ( LT_32( ee[0], 640 ) ) && ( GT_32( hp_E[0], E_min_th ) ) && /* energy concentrated in high frequencies provided that some energy is present in HF... */ - ( LT_32( ee[1], ee1_th ) ) && ( GT_32( hp_E[1], E_min_th ) ) && /* ... biased towards look-ahead to detect onsets */ - ( tmp_offset_flag == 0 ) && /* Take care of voiced offsets */ - /*( st_fx->music_hysteresis_fx == 0 ) &&*/ /* ... and in segment after AUDIO frames */ - ( LE_32( dE1, 237568 ) ) && /* Avoid on sharp energy spikes */ - ( LE_32( st_fx->old_dE1_fx, 237568 ) ) && /* + one frame hysteresis */ - ( st_fx->spike_hyst < 0 ) ) || /* Avoid after sharp energy spikes followed by decay (e.g. castanets) */ - flag_low_relE ) /* low relative frame energy (only for SC-VBR) */ -#else - if ( ( ( LT_16( add( mean_voi3, corr_shift ), add( 22282, mean_voi3_offset ) ) ) && /* normalized correlation low */ - ( LT_16( add( st_fx->voicing_fx[2], corr_shift ), 25887 ) ) && /* normalized correlation low on look-ahead - onset detection */ - ( LT_32( ee[0], 640 ) ) && ( GT_32( hp_E[0], E_min_th ) ) && /* energy concentrated in high frequencies provided that some energy is present in HF... */ - ( LT_32( ee[1], ee1_th ) ) && ( GT_32( hp_E[1], E_min_th ) ) && /* ... biased towards look-ahead to detect onsets */ - ( tmp_offset_flag == 0 ) && /* Take care of voiced offsets */ - /*( st_fx->music_hysteresis_fx == 0 ) &&*/ /* ... and in segment after AUDIO frames */ - ( LE_32( dE1, 237568 ) ) && /* Avoid on sharp energy spikes */ - ( LE_32( st_fx->old_dE1_fx, 237568 ) ) && /* + one frame hysteresis */ - ( st_fx->spike_hyst < 0 ) ) || /* Avoid after sharp energy spikes followed by decay (e.g. castanets) */ - flag_low_relE ) /* low relative frame energy (only for SC-VBR) */ -#endif - { - coder_type = UNVOICED; - move16(); - } - } - ELSE - { - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); -#ifdef BASOP_NOGLOB - if ( ( ( LT_16( add_o( mean_voi3, corr_shift, &Overflow ), add( 22774, mean_voi3_offset ) ) ) && /* normalized correlation low */ - ( LT_16( add_o( st_fx->voicing_fx[2], corr_shift, &Overflow ), 25887 ) ) && /* normalized correlation low on look-ahead - onset detection */ - ( LT_32( ee[0], 397 ) ) && ( GT_32( hp_E[0], E_min_th ) ) && /* energy concentrated in high frequencies provided that some energy is present in HF... */ - ( LT_32( ee[1], 397 ) ) && ( GT_32( hp_E[1], E_min_th ) ) && /* ... biased towards look-ahead to detect onsets */ - ( tmp_offset_flag == 0 ) && /* Take care of voiced offsets */ - /*( st_fx->music_hysteresis_fx == 0 ) && */ /* ... and in segment after AUDIO frames */ - ( LE_32( dE1, 245760 ) ) && /* Avoid on sharp energy spikes */ - ( LE_32( st_fx->old_dE1_fx, 245760 ) ) && /* + one frame hysteresis */ - ( st_fx->spike_hyst < 0 ) ) /* Avoid after sharp energy spikes followed by decay (e.g. castanets) */ - || ( flag_low_relE && ( LE_32( st_fx->old_dE1_fx, 245760 ) ) ) ) /* low relative frame energy (only for SC-VBR) */ -#else - if ( ( ( LT_16( add( mean_voi3, corr_shift ), add( 22774, mean_voi3_offset ) ) ) && /* normalized correlation low */ - ( LT_16( add( st_fx->voicing_fx[2], corr_shift ), 25887 ) ) && /* normalized correlation low on look-ahead - onset detection */ - ( LT_32( ee[0], 397 ) ) && ( GT_32( hp_E[0], E_min_th ) ) && /* energy concentrated in high frequencies provided that some energy is present in HF... */ - ( LT_32( ee[1], 397 ) ) && ( GT_32( hp_E[1], E_min_th ) ) && /* ... biased towards look-ahead to detect onsets */ - ( tmp_offset_flag == 0 ) && /* Take care of voiced offsets */ - /*( st_fx->music_hysteresis_fx == 0 ) && */ /* ... and in segment after AUDIO frames */ - ( LE_32( dE1, 245760 ) ) && /* Avoid on sharp energy spikes */ - ( LE_32( st_fx->old_dE1_fx, 245760 ) ) && /* + one frame hysteresis */ - ( st_fx->spike_hyst < 0 ) ) /* Avoid after sharp energy spikes followed by decay (e.g. castanets) */ - || ( flag_low_relE && ( LE_32( st_fx->old_dE1_fx, 245760 ) ) ) ) /* low relative frame energy (only for SC-VBR) */ -#endif - { - coder_type = UNVOICED; - move16(); - } - } - - /*-----------------------------------------------------------------* - * Decision about VC - *-----------------------------------------------------------------*/ - if ( st_fx->Opt_SC_VBR ) - { - hSC_VBR->set_ppp_generic = 0; - } - move16(); - - test(); - test(); - IF( EQ_16( st_fx->localVAD, 1 ) && EQ_16( coder_type, GENERIC ) && NE_16( last_core_orig, AMR_WB_CORE ) ) - { - dpit1 = abs_s( sub( T_op_fr[1], T_op_fr[0] ) ); - dpit2 = abs_s( sub( T_op_fr[2], T_op_fr[1] ) ); - dpit3 = abs_s( sub( T_op_fr[3], T_op_fr[2] ) ); - - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - IF( ( GT_16( voicing_fr[0], 19825 ) ) && /* normalized correlation high in 1st sf. */ - ( GT_16( voicing_fr[1], 19825 ) ) && /* normalized correlation high in 2st sf. */ - ( GT_16( voicing_fr[2], 19825 ) ) && /* normalized correlation high in 3st sf. */ - ( GT_16( voicing_fr[3], 19825 ) ) && /* normalized correlation high in 4st sf. */ - ( GT_32( mean_ee, 256 ) ) && /* energy concentrated in low frequencies */ - ( LT_16( dpit1, 3 << 6 ) ) && - ( LT_16( dpit2, 3 << 6 ) ) && - ( LT_16( dpit3, 3 << 6 ) ) ) - { - coder_type = VOICED; - move16(); - } - ELSE IF( st_fx->Opt_SC_VBR && EQ_16( st_fx->input_bwidth, NB ) && LT_16( vadnoise, 20 << 8 ) ) - { - test(); - test(); - test(); - test(); - test(); - test(); - test(); - IF( GT_16( voicing_fr[0], 8192 ) && /* normalized correlation high in 1st sf. */ - ( GT_16( voicing_fr[1], 8192 ) ) && /* normalized correlation high in 2st sf. */ - ( GT_16( voicing_fr[2], 8192 ) ) && /* normalized correlation high in 3st sf. */ - ( GT_16( voicing_fr[3], 8192 ) ) && /* normalized correlation high in 4st sf. */ - ( GT_32( mean_ee, 64 ) ) && /* energy concentrated in low frequencies */ - ( LT_16( dpit1, 5 << 6 ) ) && - ( LT_16( dpit2, 5 << 6 ) ) && - ( LT_16( dpit3, 5 << 6 ) ) ) - { - hSC_VBR->set_ppp_generic = 1; - move16(); - coder_type = VOICED; - move16(); - } - } - - /* set VOICED mode for frames with very stable pitch and high correlation - and avoid to switch to AUDIO/MUSIC later */ - voicing_m = mac_r( L_mac( L_mac( L_mult( voicing_fr[3], 8192 ), voicing_fr[2], 8192 ), voicing_fr[1], 8192 ), voicing_fr[0], 8192 ); - test(); - test(); - test(); - test(); - test(); - IF( *flag_spitch || ( LE_16( dpit1, 3 << 6 ) && LE_16( dpit2, 3 << 6 ) && LE_16( dpit3, 3 << 6 ) && - GT_16( voicing_m, 31130 ) && GT_16( st_fx->voicing_sm_fx, 31785 ) ) ) - { - coder_type = VOICED; - move16(); - *flag_spitch = 1; - move16(); /*to avoid switch to AUDIO/MUSIC later*/ - } - } - - /*-----------------------------------------------------------------* - * Channel-aware mode - set RF mode and total bitrate - *-----------------------------------------------------------------*/ - - st_fx->rf_mode = st_fx->Opt_RF_ON; - move16(); - - IF( EQ_16( coder_type, GENERIC ) ) - { - test(); - test(); - test(); - test(); - IF( ( LT_16( voicing_fr[0], 6554 ) ) && /* normalized correlation high in 2st sf. */ - ( LT_16( voicing_fr[1], 6554 ) ) && /* normalized correlation high in 2st sf. */ - ( LT_16( voicing_fr[2], 6554 ) ) && /* normalized correlation high in 3rd sf. */ - ( LT_16( voicing_fr[3], 6554 ) ) && /* normalized correlation high in 4th sf. */ - ( GT_16( vadnoise, 25 << 8 ) ) ) /* when speech is clean */ - - { - st_fx->rf_mode = 0; - move16(); - /* Current frame cannot be compressed to pack the partial redundancy;*/ - - IF( NE_16( st_fx->rf_mode, st_fx->Opt_RF_ON ) ) - { - core_coder_mode_switch_ivas_fx( st_fx, st_fx->last_total_brate, 0 ); - } - } - } - - /*-----------------------------------------------------------------* - * UNCLR classifier - *-----------------------------------------------------------------*/ - - IF( hStereoClassif != NULL ) - { - test(); - test(); - test(); - test(); - test(); - IF( st_fx->element_mode > EVS_MONO && ( EQ_16( coder_type, GENERIC ) || EQ_16( coder_type, UNVOICED ) || coder_type == INACTIVE || st_fx->localVAD == 0 ) && LT_16( hStereoClassif->unclr_sw_enable_cnt[st_fx->idchan], MAX_UV_CNT ) ) - { - hStereoClassif->unclr_sw_enable_cnt[st_fx->idchan] = add( hStereoClassif->unclr_sw_enable_cnt[st_fx->idchan], 1 ); - move16(); - } - ELSE - { - hStereoClassif->unclr_sw_enable_cnt[st_fx->idchan] = 0; - move16(); - } - } - - /*-----------------------------------------------------------------* - * Updates - *-----------------------------------------------------------------*/ - - /* update spike hysteresis parameters */ - test(); - if ( st_fx->spike_hyst >= 0 && LT_16( st_fx->spike_hyst, 2 ) ) - { - st_fx->spike_hyst = add( st_fx->spike_hyst, 1 ); - move16(); - } - - /* reset spike hysteresis */ - test(); - test(); - test(); - if ( ( GT_16( st_fx->spike_hyst, 1 ) ) && - ( GT_16( dE3, 5 << 8 ) || /* energy increases */ -#ifdef BASOP_NOGLOB - ( GT_16( relE, -3328 ) && ( GT_16( add_sat( mean_voi3, corr_shift ), 22774 ) ) ) ) ) /* normalized correlation is high */ -#else - ( GT_16( relE, -3328 ) && ( GT_16( add( mean_voi3, corr_shift ), 22774 ) ) ) ) ) /* normalized correlation is high */ -#endif - { - st_fx->spike_hyst = -1; - move16(); - } - - /* update tilt parameters */ - st_fx->ee_old_fx = ee[1]; - move32(); /*Q6*/ - st_fx->old_dE1_fx = dE1; - move32(); /*Q13*/ - - /* save the raw coder_type for various modules later in the codec (the reason is that e.g. UNVOICED is lost at higher rates) */ - st_fx->coder_type_raw = coder_type; - move16(); - - return coder_type; -} -/*-------------------------------------------------------------------* - * find_uv() - * - * Decision about coder type - *-------------------------------------------------------------------*/ diff --git a/lib_enc/find_uv_fx.c b/lib_enc/find_uv_fx.c index 778e7b51a80dbabf5cc77cdc978df6cfbed03b26..79dc78c6d31dc23cf4e86ffa62c9fbd78f63a9e2 100644 --- a/lib_enc/find_uv_fx.c +++ b/lib_enc/find_uv_fx.c @@ -23,9 +23,9 @@ * energy is trailing off after a spike *-------------------------------------------------------------------*/ -static Word16 find_ener_decrease_fx( /* o : maximum energy ratio Q10 */ - const Word16 ind_deltaMax, /* i : index of the beginning of maximum energy search */ - const Word32 *pt_enr_ssf /* i : Pointer to the energy buffer */ +static Word16 find_ener_decrease_fx( /* o : maximum energy ratio Q10*/ + const Word16 ind_deltaMax, /* i : index of the beginning of maximum energy search Q0*/ + const Word32 *pt_enr_ssf /* i : Pointer to the energy buffer Qx*/ ) { Word16 i, j, end, flag; @@ -34,6 +34,7 @@ static Word16 find_ener_decrease_fx( /* o : maximum Word16 dE2, exp0, exp1; #ifdef BASOP_NOGLOB_DECLARE_LOCAL Flag Overflow = 0; + move32(); #endif dE2 = 0; @@ -52,7 +53,7 @@ static Word16 find_ener_decrease_fx( /* o : maximum test(); IF( ( GT_32( pt_enr_ssf[i], maxEnr ) ) && ( flag == 0 ) ) { - maxEnr = L_add( pt_enr_ssf[i], 0 ); /*Q0*/ + maxEnr = L_add( pt_enr_ssf[i], 0 ); /*Qx*/ j = add( j, 1 ); } ELSE @@ -65,25 +66,17 @@ static Word16 find_ener_decrease_fx( /* o : maximum minEnr = L_add( maxEnr, 0 ); FOR( i = j; i < end; i++ ) { - minEnr = L_min( minEnr, pt_enr_ssf[i] ); + minEnr = L_min( minEnr, pt_enr_ssf[i] ); /* Qx */ } -#ifdef BASOP_NOGLOB minEnr = L_add_sat( minEnr, 100000 ); -#else - minEnr = L_add( minEnr, 100000 ); -#endif exp0 = norm_l( minEnr ); wtmp0 = extract_h( L_shl( minEnr, exp0 ) ); exp1 = sub( norm_l( maxEnr ), 1 ); wtmp1 = extract_h( L_shl( maxEnr, exp1 ) ); wtmp1 = div_s( wtmp1, wtmp0 ); -#ifdef BASOP_NOGLOB dE2 = shr_ro( wtmp1, add( sub( exp1, exp0 ), 15 - 10 ), &Overflow ); /*Q10*/ -#else - dE2 = shr_r( wtmp1, add( sub( exp1, exp0 ), 15 - 10 ) ); /*Q10*/ -#endif return dE2; } @@ -94,27 +87,20 @@ static Word16 find_ener_decrease_fx( /* o : maximum * Decision about coder type *-------------------------------------------------------------------*/ -Word16 find_uv_fx( /* o : coding type */ - Encoder_State *st_fx, /* i/o: encoder state structure */ - const Word16 *T_op_fr, /* i : pointer to adjusted fractional pitch (4 val.) Q6*/ - const Word16 *voicing_fr, /* i : refined correlation for each subframes Q15*/ - const Word16 *speech, /* i : pointer to speech signal for E computation Q_new*/ - const Word32 *ee, /* i : lf/hf Energy ratio for present frame Q6*/ -#ifdef IVAS_CODE - Word32 *dE1X, /* o : sudden energy increase for S/M classifier */ -#endif - const Word16 corr_shift, /* i : normalized correlation correction in noise Q15*/ - const Word16 relE, /* i : relative frame energy Q8*/ - const Word16 Etot, /* i : total energy Q8*/ - const Word32 hp_E[], /* i : energy in HF Q_new + Q_SCALE*/ +Word16 find_uv_fx( /* o : coding type */ + Encoder_State *st_fx, /* i/o: encoder state structure */ + const Word16 *T_op_fr, /* i : pointer to adjusted fractional pitch (4 val.) Q6*/ + const Word16 *voicing_fr, /* i : refined correlation for each subframes Q15*/ + const Word16 *speech, /* i : pointer to speech signal for E computation Q_new*/ + const Word32 *ee, /* i : lf/hf Energy ratio for present frame Q6*/ + const Word16 corr_shift, /* i : normalized correlation correction in noise Q15*/ + const Word16 relE, /* i : relative frame energy Q8*/ + const Word16 Etot, /* i : total energy Q8*/ + const Word32 hp_E[], /* i : energy in HF Q_new + Q_SCALE*/ const Word16 Q_new, - Word16 *flag_spitch, /* i/o: flag to indicate very short stable pitch and high correlation */ + Word16 *flag_spitch, /* i/o: flag to indicate very short stable pitch and high correlation Q0*/ const Word16 shift, - const Word16 last_core_orig /* i : original last core */ -#ifdef IVAS_CODE - , - STEREO_CLASSIF_HANDLE hStereoClassif /* i/o: stereo classifier structure */ -#endif + const Word16 last_core_orig /* i : original last core Q0*/ ) { Word16 coder_type, i; @@ -135,6 +121,7 @@ Word16 find_uv_fx( /* o : coding type SC_VBR_ENC_HANDLE hSC_VBR = st_fx->hSC_VBR; #ifdef BASOP_NOGLOB_DECLARE_LOCAL Flag Overflow = 0; + move32(); #endif Word16 Last_Resort; @@ -142,13 +129,17 @@ Word16 find_uv_fx( /* o : coding type IF( hSC_VBR != NULL ) { - Last_Resort = hSC_VBR->Last_Resort; + Last_Resort = hSC_VBR->Last_Resort; /* Q0 */ vadnoise = hSC_VBR->vadnoise_fx; + move16(); + move16(); } ELSE { Last_Resort = 0; vadnoise = 0; + move16(); + move16(); } Q_in = sub( Q_new, 1 ); @@ -163,7 +154,7 @@ Word16 find_uv_fx( /* o : coding type *-----------------------------------------------------------------*/ /* Find maximum energy per short subblocks */ - pt_speech = speech - SSF; + pt_speech = speech - SSF; /* Q_new */ pt_enr_ssf = enr_ssf + 2 * NB_SSF; FOR( i = 0; i < 2 * ( NB_SSF + 1 ); i++ ) { @@ -191,11 +182,7 @@ Word16 find_uv_fx( /* o : coding type exp1 = sub( norm_l( *pt_enr_ssf1 ), 1 ); wtmp1 = extract_h( L_shl( *pt_enr_ssf1, exp1 ) ); fac = div_s( wtmp1, wtmp0 ); -#ifdef BASOP_NOGLOB fac_32 = L_shr_o( L_deposit_l( fac ), add( sub( exp1, exp0 ), 15 - 13 ), &Overflow ); /* fac32 in Q13*/ -#else /* BASOP_NOGLOB */ - fac_32 = L_shr( L_deposit_l( fac ), add( sub( exp1, exp0 ), 15 - 13 ) ); /* fac32 in Q13*/ -#endif /* BASOP_NOGLOB */ if ( GT_32( fac_32, dE1 ) ) { @@ -203,51 +190,25 @@ Word16 find_uv_fx( /* o : coding type move16(); } - dE1 = L_max( dE1, fac_32 ); + dE1 = L_max( dE1, fac_32 ); /* Q13 */ pt_enr_ssf++; pt_enr_ssf1++; } -#ifdef IVAS_CODE - IF( hStereoClassif != NULL ) - { - IF( st_fx->idchan == 0 ) - { - hStereoClassif->dE1_ch1 = dE1; - } - ELSE - { - hStereoClassif->dE1_ch2 = dE1; - } - } - if ( dE1X != NULL ) - { - *dE1X = dE1; - move32(); - } -#endif /*-----------------------------------------------------------------* * Average spectral tilt * Average voicing (normalized correlation) *-----------------------------------------------------------------*/ - /*mean_ee = 1.0f/3.0f * (st->ee_old + ee[0] + ee[1]); */ /* coefficients take into account the position of the window */ -#ifdef BASOP_NOGLOB - mean_ee = L_add_o( L_add_o( st_fx->ee_old_fx, ee[0], &Overflow ), ee[1], &Overflow ); -#else /* BASOP_NOGLOB */ - mean_ee = L_add( L_add( st_fx->ee_old_fx, ee[0] ), ee[1] ); -#endif /* BASOP_NOGLOB */ - mean_ee = Mult_32_16( mean_ee, 10923 ); /*Q6*/ + /*mean_ee = 1.0f/3.0f * (st->ee_old + ee[0] + ee[1]); */ /* coefficients take into account the position of the window */ + mean_ee = L_add_o( L_add_o( st_fx->ee_old_fx, ee[0], &Overflow ), ee[1], &Overflow ); /* Q6 */ + mean_ee = Mult_32_16( mean_ee, 10923 /* 1/3 in Q15 */ ); /*Q6*/ /* mean_voi3 = 1.0f/3.0f * (voicing[0] + voicing[1] + voicing[2]);*/ - Ltmp0 = L_mult( st_fx->voicing_fx[0], 10923 ); - Ltmp0 = L_mac( Ltmp0, st_fx->voicing_fx[1], 10923 ); -#ifdef BASOP_NOGLOB // -dtx 12650 amrwb\Dtx3.INP - mean_voi3 = mac_r_sat( Ltmp0, st_fx->voicing_fx[2], 10923 ); /*Q15*/ -#else - mean_voi3 = mac_r( Ltmp0, st_fx->voicing_fx[2], 10923 ); /*Q15*/ -#endif + Ltmp0 = L_mult( st_fx->voicing_fx[0], 10923 /* 1/3 in Q15 */ ); /* Q31 */ + Ltmp0 = L_mac( Ltmp0, st_fx->voicing_fx[1], 10923 /* 1/3 in Q15 */ ); /* Q31 */ + mean_voi3 = mac_r_sat( Ltmp0, st_fx->voicing_fx[2], 10923 /* 1/3 in Q15 */ ); /*Q15*/ /*-----------------------------------------------------------------* * Total frame energy difference (dE3) *-----------------------------------------------------------------*/ @@ -267,11 +228,7 @@ Word16 find_uv_fx( /* o : coding type { dE2_th = 21 << 10; move32(); -#ifdef BASOP_NOGLOB - if ( GE_16( add_o( mean_voi3, corr_shift, &Overflow ), 22282 ) ) /*( mean_voi3 + corr_shift ) >= 0.68f*/ -#else - if ( GE_16( add( mean_voi3, corr_shift ), 22282 ) ) /*( mean_voi3 + corr_shift ) >= 0.68f*/ -#endif + if ( GE_16( add_o( mean_voi3, corr_shift, &Overflow ), 22282 /* 0.68 in Q15 */ ) ) /*( mean_voi3 + corr_shift ) >= 0.68f*/ { nb_cond = 0; move16(); @@ -288,9 +245,9 @@ Word16 find_uv_fx( /* o : coding type { IF( LT_16( sub( shl( NB_SSF, 1 ), ind_deltaMax ), L_ENR ) ) { - st_fx->old_ind_deltaMax = ind_deltaMax; + st_fx->old_ind_deltaMax = ind_deltaMax; /* Q0 */ move16(); - Copy32( pt_enr_ssf, st_fx->old_enr_ssf_fx, 2 * NB_SSF ); + Copy32( pt_enr_ssf, st_fx->old_enr_ssf_fx, 2 * NB_SSF ); /* Qx */ } ELSE { @@ -309,8 +266,8 @@ Word16 find_uv_fx( /* o : coding type { IF( st_fx->old_ind_deltaMax >= 0 ) { - Copy32( st_fx->old_enr_ssf_fx, enr_ssf, 2 * NB_SSF ); - dE2 = find_ener_decrease_fx( st_fx->old_ind_deltaMax, enr_ssf ); + Copy32( st_fx->old_enr_ssf_fx, enr_ssf, 2 * NB_SSF ); /* Qx */ + dE2 = find_ener_decrease_fx( st_fx->old_ind_deltaMax, enr_ssf ); /* Q10 */ if ( GT_32( dE2, dE2_th ) ) { @@ -348,15 +305,9 @@ Word16 find_uv_fx( /* o : coding type test(); test(); test(); -#ifdef BASOP_NOGLOB if ( ( EQ_16( st_fx->last_coder_type_raw, UNVOICED ) ) || /* previous frame was unvoiced */ ( ( LT_32( ee[0], ee0_th ) ) && ( GT_32( hp_E[0], L_shl( E_MIN_FX, Q_new ) ) ) && /* energy is concentrated in high frequencies provided that some energy is present in HF */ ( LT_16( add_o( st_fx->voicing_fx[0], corr_shift, &Overflow ), voi_th ) ) ) ) /* normalized correlation is low */ -#else /* BASOP_NOGLOB */ - if ( ( EQ_16( st_fx->last_coder_type_raw, UNVOICED ) ) || /* previous frame was unvoiced */ - ( ( LT_32( ee[0], ee0_th ) ) && ( GT_32( hp_E[0], L_shl( E_MIN_FX, Q_new ) ) ) && /* energy is concentrated in high frequencies provided that some energy is present in HF */ - ( LT_16( add( st_fx->voicing_fx[0], corr_shift ), voi_th ) ) ) ) /* normalized correlation is low */ -#endif /* BASOP_NOGLOB */ { tmp_offset_flag = 0; move16(); @@ -382,11 +333,11 @@ Word16 find_uv_fx( /* o : coding type IF( NE_16( st_fx->input_bwidth, NB ) ) { /*relE_thres = 0.700f * st->lp_noise - 33.5f; (lp_noise in Q8, constant Q8<<16) */ - L_tmp = L_mac( -562036736, 22938, st_fx->lp_noise_fx ); + L_tmp = L_mac( -562036736 /* 33.5f in Q24 */, 22938 /* 0.7 in Q15 */, st_fx->lp_noise_fx ); // Q24 if ( Last_Resort == 0 ) { /*relE_thres = 0.650f * st->lp_noise - 33.5f; (lp_noise in Q8, constant Q8<<16)*/ - L_tmp = L_mac( -562036736, 21299, st_fx->lp_noise_fx ); + L_tmp = L_mac( -562036736 /* 33.5f in Q24 */, 21299 /* 0.650f in Q15 */, st_fx->lp_noise_fx ); // Q24 } relE_thres = round_fx( L_tmp ); } @@ -394,10 +345,10 @@ Word16 find_uv_fx( /* o : coding type { /*relE_thres = 0.60f * st->lp_noise - 28.2f; (lp_noise in Q8, constant Q8<<16)*/ - L_tmp = L_mac( -473117491, 19661, st_fx->lp_noise_fx ); + L_tmp = L_mac( -473117491 /* 28.2f in Q24 */, 19661 /* 0.6f in Q15 */, st_fx->lp_noise_fx ); // Q24 relE_thres = round_fx( L_tmp ); } - relE_thres = s_max( relE_thres, -6400 ); /* Q8 */ + relE_thres = s_max( relE_thres, -6400 /* -25.0f in Q8 */ ); /* Q8 */ /* SC-VBR = set flag on low relative energy */ if ( LT_16( relE, relE_thres ) ) @@ -432,29 +383,16 @@ Word16 find_uv_fx( /* o : coding type test(); test(); test(); -#ifdef BASOP_NOGLOB - if ( ( ( LT_16( add_o( mean_voi3, corr_shift, &Overflow ), add( 22282, mean_voi3_offset ) ) ) && /* normalized correlation low */ - ( LT_16( add_o( st_fx->voicing_fx[2], corr_shift, &Overflow ), 25887 ) ) && /* normalized correlation low on look-ahead - onset detection */ - ( LT_32( ee[0], 640 ) ) && ( GT_32( hp_E[0], E_min_th ) ) && /* energy concentrated in high frequencies provided that some energy is present in HF... */ - ( LT_32( ee[1], ee1_th ) ) && ( GT_32( hp_E[1], E_min_th ) ) && /* ... biased towards look-ahead to detect onsets */ - ( tmp_offset_flag == 0 ) && /* Take care of voiced offsets */ - /*( st_fx->music_hysteresis_fx == 0 ) &&*/ /* ... and in segment after AUDIO frames */ - ( LE_32( dE1, 237568 ) ) && /* Avoid on sharp energy spikes */ - ( LE_32( st_fx->old_dE1_fx, 237568 ) ) && /* + one frame hysteresis */ - ( st_fx->spike_hyst < 0 ) ) || /* Avoid after sharp energy spikes followed by decay (e.g. castanets) */ - flag_low_relE ) /* low relative frame energy (only for SC-VBR) */ -#else - if ( ( ( LT_16( add( mean_voi3, corr_shift ), add( 22282, mean_voi3_offset ) ) ) && /* normalized correlation low */ - ( LT_16( add( st_fx->voicing_fx[2], corr_shift ), 25887 ) ) && /* normalized correlation low on look-ahead - onset detection */ - ( LT_32( ee[0], 640 ) ) && ( GT_32( hp_E[0], E_min_th ) ) && /* energy concentrated in high frequencies provided that some energy is present in HF... */ - ( LT_32( ee[1], ee1_th ) ) && ( GT_32( hp_E[1], E_min_th ) ) && /* ... biased towards look-ahead to detect onsets */ - ( tmp_offset_flag == 0 ) && /* Take care of voiced offsets */ - /*( st_fx->music_hysteresis_fx == 0 ) &&*/ /* ... and in segment after AUDIO frames */ - ( LE_32( dE1, 237568 ) ) && /* Avoid on sharp energy spikes */ - ( LE_32( st_fx->old_dE1_fx, 237568 ) ) && /* + one frame hysteresis */ - ( st_fx->spike_hyst < 0 ) ) || /* Avoid after sharp energy spikes followed by decay (e.g. castanets) */ - flag_low_relE ) /* low relative frame energy (only for SC-VBR) */ -#endif + if ( ( ( LT_16( add_o( mean_voi3, corr_shift, &Overflow ), add( 22282 /* 0.68 in Q15 */, mean_voi3_offset ) ) ) && /* normalized correlation low */ + ( LT_16( add_o( st_fx->voicing_fx[2], corr_shift, &Overflow ), 25887 /* 0.79 in Q15 */ ) ) && /* normalized correlation low on look-ahead - onset detection */ + ( LT_32( ee[0], 640 /* 10.0f in Q6 */ ) ) && ( GT_32( hp_E[0], E_min_th ) ) && /* energy concentrated in high frequencies provided that some energy is present in HF... */ + ( LT_32( ee[1], ee1_th ) ) && ( GT_32( hp_E[1], E_min_th ) ) && /* ... biased towards look-ahead to detect onsets */ + ( tmp_offset_flag == 0 ) && /* Take care of voiced offsets */ + /*( st_fx->music_hysteresis_fx == 0 ) &&*/ /* ... and in segment after AUDIO frames */ + ( LE_32( dE1, 237568 /* 29.0f in Q13 */ ) ) && /* Avoid on sharp energy spikes */ + ( LE_32( st_fx->old_dE1_fx, 237568 /* 29.0f in Q13 */ ) ) && /* + one frame hysteresis */ + ( st_fx->spike_hyst < 0 ) ) || /* Avoid after sharp energy spikes followed by decay (e.g. castanets) */ + flag_low_relE ) /* low relative frame energy (only for SC-VBR) */ { coder_type = UNVOICED; move16(); @@ -474,29 +412,16 @@ Word16 find_uv_fx( /* o : coding type test(); test(); test(); -#ifdef BASOP_NOGLOB - if ( ( ( LT_16( add_o( mean_voi3, corr_shift, &Overflow ), add( 22774, mean_voi3_offset ) ) ) && /* normalized correlation low */ - ( LT_16( add_sat( st_fx->voicing_fx[2], corr_shift ), 25887 ) ) && /* normalized correlation low on look-ahead - onset detection */ - ( LT_32( ee[0], 397 ) ) && ( GT_32( hp_E[0], E_min_th ) ) && /* energy concentrated in high frequencies provided that some energy is present in HF... */ - ( LT_32( ee[1], 397 ) ) && ( GT_32( hp_E[1], E_min_th ) ) && /* ... biased towards look-ahead to detect onsets */ - ( tmp_offset_flag == 0 ) && /* Take care of voiced offsets */ - /*( st_fx->music_hysteresis_fx == 0 ) && */ /* ... and in segment after AUDIO frames */ - ( LE_32( dE1, 245760 ) ) && /* Avoid on sharp energy spikes */ - ( LE_32( st_fx->old_dE1_fx, 245760 ) ) && /* + one frame hysteresis */ - ( st_fx->spike_hyst < 0 ) ) /* Avoid after sharp energy spikes followed by decay (e.g. castanets) */ - || ( flag_low_relE && ( LE_32( st_fx->old_dE1_fx, 245760 ) ) ) ) /* low relative frame energy (only for SC-VBR) */ -#else - if ( ( ( LT_16( add( mean_voi3, corr_shift ), add( 22774, mean_voi3_offset ) ) ) && /* normalized correlation low */ - ( LT_16( add( st_fx->voicing_fx[2], corr_shift ), 25887 ) ) && /* normalized correlation low on look-ahead - onset detection */ - ( LT_32( ee[0], 397 ) ) && ( GT_32( hp_E[0], E_min_th ) ) && /* energy concentrated in high frequencies provided that some energy is present in HF... */ - ( LT_32( ee[1], 397 ) ) && ( GT_32( hp_E[1], E_min_th ) ) && /* ... biased towards look-ahead to detect onsets */ - ( tmp_offset_flag == 0 ) && /* Take care of voiced offsets */ - /*( st_fx->music_hysteresis_fx == 0 ) && */ /* ... and in segment after AUDIO frames */ - ( LE_32( dE1, 245760 ) ) && /* Avoid on sharp energy spikes */ - ( LE_32( st_fx->old_dE1_fx, 245760 ) ) && /* + one frame hysteresis */ - ( st_fx->spike_hyst < 0 ) ) /* Avoid after sharp energy spikes followed by decay (e.g. castanets) */ - || ( flag_low_relE && ( LE_32( st_fx->old_dE1_fx, 245760 ) ) ) ) /* low relative frame energy (only for SC-VBR) */ -#endif + if ( ( ( LT_16( add_o( mean_voi3, corr_shift, &Overflow ), add( 22774 /* 0.695f in Q15 */, mean_voi3_offset ) ) ) && /* normalized correlation low */ + ( LT_16( add_sat( st_fx->voicing_fx[2], corr_shift ), 25887 /* 0.8 in Q15 */ ) ) && /* normalized correlation low on look-ahead - onset detection */ + ( LT_32( ee[0], 397 /* 6.2f in Q6 */ ) ) && ( GT_32( hp_E[0], E_min_th ) ) && /* energy concentrated in high frequencies provided that some energy is present in HF... */ + ( LT_32( ee[1], 397 /* 6.2f in Q6 */ ) ) && ( GT_32( hp_E[1], E_min_th ) ) && /* ... biased towards look-ahead to detect onsets */ + ( tmp_offset_flag == 0 ) && /* Take care of voiced offsets */ + /*( st_fx->music_hysteresis_fx == 0 ) && */ /* ... and in segment after AUDIO frames */ + ( LE_32( dE1, 245760 /* 30.0f in Q13 */ ) ) && /* Avoid on sharp energy spikes */ + ( LE_32( st_fx->old_dE1_fx, 245760 /* 30.0f in Q13 */ ) ) && /* + one frame hysteresis */ + ( st_fx->spike_hyst < 0 ) ) /* Avoid after sharp energy spikes followed by decay (e.g. castanets) */ + || ( flag_low_relE && ( LE_32( st_fx->old_dE1_fx, 245760 /* 30.0f in Q13 */ ) ) ) ) /* low relative frame energy (only for SC-VBR) */ { coder_type = UNVOICED; move16(); @@ -516,9 +441,9 @@ Word16 find_uv_fx( /* o : coding type test(); IF( EQ_16( st_fx->localVAD, 1 ) && EQ_16( coder_type, GENERIC ) && NE_16( last_core_orig, AMR_WB_CORE ) ) { - dpit1 = abs_s( sub( T_op_fr[1], T_op_fr[0] ) ); - dpit2 = abs_s( sub( T_op_fr[2], T_op_fr[1] ) ); - dpit3 = abs_s( sub( T_op_fr[3], T_op_fr[2] ) ); + dpit1 = abs_s( sub( T_op_fr[1], T_op_fr[0] ) ); // Q6 + dpit2 = abs_s( sub( T_op_fr[2], T_op_fr[1] ) ); // Q6 + dpit3 = abs_s( sub( T_op_fr[3], T_op_fr[2] ) ); // Q6 test(); test(); @@ -529,11 +454,11 @@ Word16 find_uv_fx( /* o : coding type test(); test(); test(); - IF( ( GT_16( voicing_fr[0], 19825 ) ) && /* normalized correlation high in 1st sf. */ - ( GT_16( voicing_fr[1], 19825 ) ) && /* normalized correlation high in 2st sf. */ - ( GT_16( voicing_fr[2], 19825 ) ) && /* normalized correlation high in 3st sf. */ - ( GT_16( voicing_fr[3], 19825 ) ) && /* normalized correlation high in 4st sf. */ - ( GT_32( mean_ee, 256 ) ) && /* energy concentrated in low frequencies */ + IF( ( GT_16( voicing_fr[0], 19825 /* 0.605 in Q15 */ ) ) && /* normalized correlation high in 1st sf. */ + ( GT_16( voicing_fr[1], 19825 /* 0.605 in Q15 */ ) ) && /* normalized correlation high in 2st sf. */ + ( GT_16( voicing_fr[2], 19825 /* 0.605 in Q15 */ ) ) && /* normalized correlation high in 3st sf. */ + ( GT_16( voicing_fr[3], 19825 /* 0.605 in Q15 */ ) ) && /* normalized correlation high in 4st sf. */ + ( GT_32( mean_ee, 256 /* 4.0f in Q6 */ ) ) && /* energy concentrated in low frequencies */ ( LT_16( dpit1, 3 << 6 ) ) && ( LT_16( dpit2, 3 << 6 ) ) && ( LT_16( dpit3, 3 << 6 ) ) ) @@ -550,11 +475,11 @@ Word16 find_uv_fx( /* o : coding type test(); test(); test(); - IF( GT_16( voicing_fr[0], 8192 ) && /* normalized correlation high in 1st sf. */ - ( GT_16( voicing_fr[1], 8192 ) ) && /* normalized correlation high in 2st sf. */ - ( GT_16( voicing_fr[2], 8192 ) ) && /* normalized correlation high in 3st sf. */ - ( GT_16( voicing_fr[3], 8192 ) ) && /* normalized correlation high in 4st sf. */ - ( GT_32( mean_ee, 64 ) ) && /* energy concentrated in low frequencies */ + IF( GT_16( voicing_fr[0], 8192 /* 0.25 in Q15 */ ) && /* normalized correlation high in 1st sf. */ + ( GT_16( voicing_fr[1], 8192 /* 0.25 in Q15 */ ) ) && /* normalized correlation high in 2st sf. */ + ( GT_16( voicing_fr[2], 8192 /* 0.25 in Q15 */ ) ) && /* normalized correlation high in 3st sf. */ + ( GT_16( voicing_fr[3], 8192 /* 0.25 in Q15 */ ) ) && /* normalized correlation high in 4st sf. */ + ( GT_32( mean_ee, 64 ) ) && /* energy concentrated in low frequencies */ ( LT_16( dpit1, 5 << 6 ) ) && ( LT_16( dpit2, 5 << 6 ) ) && ( LT_16( dpit3, 5 << 6 ) ) ) @@ -568,14 +493,14 @@ Word16 find_uv_fx( /* o : coding type /* set VOICED mode for frames with very stable pitch and high correlation and avoid to switch to AUDIO/MUSIC later */ - voicing_m = mac_r( L_mac( L_mac( L_mult( voicing_fr[3], 8192 ), voicing_fr[2], 8192 ), voicing_fr[1], 8192 ), voicing_fr[0], 8192 ); + voicing_m = mac_r( L_mac( L_mac( L_mult( voicing_fr[3], 8192 /* 0.25 in Q15 */ ), voicing_fr[2], 8192 /* 0.25 in Q15 */ ), voicing_fr[1], 8192 /* 0.25 in Q15 */ ), voicing_fr[0], 8192 /* 0.25 in Q15 */ ); test(); test(); test(); test(); test(); IF( *flag_spitch || ( LE_16( dpit1, 3 << 6 ) && LE_16( dpit2, 3 << 6 ) && LE_16( dpit3, 3 << 6 ) && - GT_16( voicing_m, 31130 ) && GT_16( st_fx->voicing_sm_fx, 31785 ) ) ) + GT_16( voicing_m, 31130 /* 0.95f in Q15 */ ) && GT_16( st_fx->voicing_sm_fx, 31785 /* 0.97f in Q15 */ ) ) ) { coder_type = VOICED; move16(); @@ -588,7 +513,7 @@ Word16 find_uv_fx( /* o : coding type * Channel-aware mode - set RF mode and total bitrate *-----------------------------------------------------------------*/ - st_fx->rf_mode = st_fx->Opt_RF_ON; + st_fx->rf_mode = st_fx->Opt_RF_ON; /* Q0 */ move16(); IF( EQ_16( coder_type, GENERIC ) ) @@ -597,11 +522,11 @@ Word16 find_uv_fx( /* o : coding type test(); test(); test(); - IF( ( LT_16( voicing_fr[0], 6554 ) ) && /* normalized correlation high in 2st sf. */ - ( LT_16( voicing_fr[1], 6554 ) ) && /* normalized correlation high in 2st sf. */ - ( LT_16( voicing_fr[2], 6554 ) ) && /* normalized correlation high in 3rd sf. */ - ( LT_16( voicing_fr[3], 6554 ) ) && /* normalized correlation high in 4th sf. */ - ( GT_16( vadnoise, 25 << 8 ) ) ) /* when speech is clean */ + IF( ( LT_16( voicing_fr[0], 6554 /* 0.2f in Q15 */ ) ) && /* normalized correlation high in 2st sf. */ + ( LT_16( voicing_fr[1], 6554 /* 0.2f in Q15 */ ) ) && /* normalized correlation high in 2st sf. */ + ( LT_16( voicing_fr[2], 6554 /* 0.2f in Q15 */ ) ) && /* normalized correlation high in 3rd sf. */ + ( LT_16( voicing_fr[3], 6554 /* 0.2f in Q15 */ ) ) && /* normalized correlation high in 4th sf. */ + ( GT_16( vadnoise, 25 << 8 ) ) ) /* when speech is clean */ { st_fx->rf_mode = 0; @@ -614,24 +539,544 @@ Word16 find_uv_fx( /* o : coding type } } } -#ifdef IVAS_CODE + /*-----------------------------------------------------------------* - * UNCLR classifier + * Updates + *-----------------------------------------------------------------*/ + + /* update spike hysteresis parameters */ + test(); + if ( st_fx->spike_hyst >= 0 && LT_16( st_fx->spike_hyst, 2 ) ) + { + st_fx->spike_hyst = add( st_fx->spike_hyst, 1 ); /* Q0 */ + } + + /* reset spike hysteresis */ + test(); + test(); + test(); + if ( ( GT_16( st_fx->spike_hyst, 1 ) ) && + ( GT_16( dE3, 5 << 8 ) || /* energy increases */ + ( GT_16( relE, -3328 ) && ( GT_16( add_sat( mean_voi3, corr_shift ), 22774 ) ) ) ) ) /* normalized correlation is high */ + { + st_fx->spike_hyst = -1; + move16(); + } + + /* update tilt parameters */ + st_fx->ee_old_fx = ee[1]; + move32(); /*Q6*/ + st_fx->old_dE1_fx = dE1; + move32(); /*Q13*/ + + /* save the raw coder_type for various modules later in the codec (the reason is that e.g. UNVOICED is lost at higher rates) */ + st_fx->coder_type_raw = coder_type; + move16(); + + return coder_type; +} + +/*-------------------------------------------------------------------* + * find_uv() + * + * Decision about coder type + *-------------------------------------------------------------------*/ +Word16 find_uv_ivas_fx( /* o : coding type */ + Encoder_State *st_fx, /* i/o: encoder state structure */ + const Word16 *T_op_fr, /* i : pointer to adjusted fractional pitch (4 val.) Q6*/ + const Word16 *voicing_fr, /* i : refined correlation for each subframes Q15*/ + const Word16 *speech, /* i : pointer to speech signal for E computation Q_new*/ + const Word32 *ee, /* i : lf/hf Energy ratio for present frame Q6*/ + Word32 *dE1X, /* o : sudden energy increase for S/M classifier Q13*/ + const Word16 corr_shift, /* i : normalized correlation correction in noise Q15*/ + const Word16 relE, /* i : relative frame energy Q8*/ + const Word16 Etot, /* i : total energy Q8*/ + const Word32 hp_E[], /* i : energy in HF q_hp_E*/ + Word16 *flag_spitch, /* i/o: flag to indicate very short stable pitch and high correlation Q0*/ + const Word16 last_core_orig, /* i : original last core Q0*/ + STEREO_CLASSIF_HANDLE hStereoClassif, /* i/o: stereo classifier structure */ + const Word16 Q_new, + const Word16 q_hp_E ) +{ + Word16 coder_type, i; + Word32 mean_ee, dE1, fac_32; + const Word16 *pt_speech; + Word32 L_tmp, enr_ssf[2 * NB_SSF + 2 * NB_SSF + 2], E_min_th; + Word16 dE2; + Word16 ind_deltaMax, tmp_offset_flag; + Word32 Ltmp0, *pt_enr_ssf, *pt_enr_ssf1, dE2_th; + Word16 exp0, exp1; + Word16 wtmp0, wtmp1; + Word16 fac, mean_voi3, dE3; + Word16 relE_thres; + Word16 mean_voi3_offset; + Word16 voicing_m, dpit1, dpit2, dpit3; + Word16 ee0_th, ee1_th, voi_th, nb_cond, flag_low_relE; + NOISE_EST_HANDLE hNoiseEst = st_fx->hNoiseEst; + SC_VBR_ENC_HANDLE hSC_VBR = st_fx->hSC_VBR; +#ifdef BASOP_NOGLOB_DECLARE_LOCAL + Flag Overflow = 0; + move32(); +#endif + Word16 Last_Resort; + Word16 vadnoise; + + IF( hSC_VBR != NULL ) + { + Last_Resort = hSC_VBR->Last_Resort; /* Q0 */ + move16(); + vadnoise = hSC_VBR->vadnoise_fx; /* Q8 */ + move16(); + } + ELSE + { + Last_Resort = 0; + move16(); + vadnoise = 0; + move16(); + } + + /*-----------------------------------------------------------------* + * Detect sudden energy increases to catch voice and music + * temporal events (dE1) + * + * - Find maximum energy per short subblocks. + * Two subblock sets are used shifted by half the subblock length + * - Find maximum energy ratio between adjacent subblocks *-----------------------------------------------------------------*/ - if ( hStereoClassif != NULL ) + /* Find maximum energy per short subblocks */ + pt_speech = speech - SSF; + pt_enr_ssf = enr_ssf + 2 * NB_SSF; + FOR( i = 0; i < 2 * ( NB_SSF + 1 ); i++ ) { - if ( st->element_mode > EVS_MONO && ( coder_type == GENERIC || coder_type == UNVOICED || coder_type == INACTIVE || st->localVAD == 0 ) && hStereoClassif->unclr_sw_enable_cnt[st->idchan] < MAX_UV_CNT ) + emaximum_fx( Q_new, pt_speech, SSF, pt_enr_ssf ); + pt_speech += ( SSF / 2 ); + pt_enr_ssf++; + } + + dE1 = 0; + move16(); + ind_deltaMax = 0; + move16(); + pt_enr_ssf = enr_ssf + 2 * NB_SSF; + pt_enr_ssf1 = pt_enr_ssf + 2; + + /* Test on energy increase between adjacent sub-subframes */ + exp1 = 0; + move16(); + FOR( i = 0; i < 2 * NB_SSF; i++ ) + { + /*fac = *pt_enr_ssf1 / (*pt_enr_ssf + 1);*/ + Ltmp0 = L_max( *pt_enr_ssf, 1 ); + exp0 = norm_l( Ltmp0 ); + wtmp0 = extract_h( L_shl( Ltmp0, exp0 ) ); + exp1 = sub( norm_l( *pt_enr_ssf1 ), 1 ); + wtmp1 = extract_h( L_shl( *pt_enr_ssf1, exp1 ) ); + fac = div_s( wtmp1, wtmp0 ); + fac_32 = L_shr_o( L_deposit_l( fac ), add( sub( exp1, exp0 ), 15 - 13 ), &Overflow ); /* fac32 in Q13*/ + + if ( GT_32( fac_32, dE1 ) ) + { + ind_deltaMax = i; + move16(); + } + + dE1 = L_max( dE1, fac_32 ); /* Q13 */ + + pt_enr_ssf++; + pt_enr_ssf1++; + } + + IF( hStereoClassif != NULL ) + { + IF( st_fx->idchan == 0 ) { - hStereoClassif->unclr_sw_enable_cnt[st->idchan]++; + hStereoClassif->dE1_ch1_fx = dE1; /* Q13 */ + move32(); + hStereoClassif->dE1_ch1_e = 31 - Q13; + move16(); } - else + ELSE { - hStereoClassif->unclr_sw_enable_cnt[st->idchan] = 0; + hStereoClassif->dE1_ch2_fx = dE1; /* Q13 */ + move32(); + hStereoClassif->dE1_ch2_e = 31 - Q13; + move16(); } } -#endif + if ( dE1X != NULL ) + { + *dE1X = dE1; /* Q13 */ + move32(); + } + + /*-----------------------------------------------------------------* + * Average spectral tilt + * Average voicing (normalized correlation) + *-----------------------------------------------------------------*/ + + /*mean_ee = 1.0f/3.0f * (st->ee_old + ee[0] + ee[1]); */ /* coefficients take into account the position of the window */ + mean_ee = L_add_o( L_add_o( st_fx->ee_old_fx, ee[0], &Overflow ), ee[1], &Overflow ); /* Q6 */ + mean_ee = Mult_32_16( mean_ee, 10923 ); /*Q6*/ + + /* mean_voi3 = 1.0f/3.0f * (voicing[0] + voicing[1] + voicing[2]);*/ + Ltmp0 = L_mult( st_fx->voicing_fx[0], 10923 /* 1/3 in Q15 */ ); /* Q31 */ + Ltmp0 = L_mac( Ltmp0, st_fx->voicing_fx[1], 10923 /* 1/3 in Q15 */ ); /* Q31 */ + mean_voi3 = mac_r_sat( Ltmp0, st_fx->voicing_fx[2], 10923 /* 1/3 in Q15 */ ); /*Q15*/ + /*-----------------------------------------------------------------* + * Total frame energy difference (dE3) + *-----------------------------------------------------------------*/ + + dE3 = sub( Etot, hNoiseEst->Etot_last_fx ); /*Q8*/ + + /*-----------------------------------------------------------------* + * Energy decrease after spike (dE2) + *-----------------------------------------------------------------*/ + + /* set different thresholds and conditions for NB and WB input */ + dE2_th = 30 << 10; + move32(); + nb_cond = 1; + move16(); /* no additional condition for WB input */ + IF( st_fx->input_bwidth == NB ) + { + dE2_th = 21 << 10; + move32(); + if ( GE_16( add_o( mean_voi3, corr_shift, &Overflow ), 22282 ) ) /*( mean_voi3 + corr_shift ) >= 0.68f*/ + { + nb_cond = 0; + move16(); + } + } + + /* calcualte maximum energy decrease */ + dE2 = 0; + move16(); /* Test on energy decrease after an energy spike */ + pt_enr_ssf = enr_ssf + 2 * NB_SSF; + + test(); + IF( GT_32( dE1, 30 << 13 ) && nb_cond ) /*>30 Q13*/ + { + IF( LT_16( sub( shl( NB_SSF, 1 ), ind_deltaMax ), L_ENR ) ) + { + st_fx->old_ind_deltaMax = ind_deltaMax; /* Q0 */ + move16(); + Copy32( pt_enr_ssf, st_fx->old_enr_ssf_fx, 2 * NB_SSF ); /* Qx */ + } + ELSE + { + st_fx->old_ind_deltaMax = -1; + move16(); + dE2 = find_ener_decrease_fx( ind_deltaMax, pt_enr_ssf ); /*Q10*/ + + if ( GT_32( dE2, dE2_th ) ) + { + st_fx->spike_hyst = 0; + move16(); + } + } + } + ELSE + { + IF( st_fx->old_ind_deltaMax >= 0 ) + { + Copy32( st_fx->old_enr_ssf_fx, enr_ssf, 2 * NB_SSF ); /* Qx */ + dE2 = find_ener_decrease_fx( st_fx->old_ind_deltaMax, enr_ssf ); /* Q10 */ + + if ( GT_32( dE2, dE2_th ) ) + { + st_fx->spike_hyst = 1; + move16(); + } + } + + st_fx->old_ind_deltaMax = -1; + move16(); + } + + /*-----------------------------------------------------------------* + * Detection of voiced offsets (tmp_offset_flag) + *-----------------------------------------------------------------*/ + + tmp_offset_flag = 1; + move16(); + + IF( st_fx->input_bwidth != NB ) + { + ee0_th = 154; /*2.4 in Q6 */ + move16(); + voi_th = 24248; /*0.74f Q15 */ + move16(); + } + ELSE + { + ee0_th = 627; /*9.8f Q6 */ + move16(); + voi_th = 24904; /*0.76f Q15*/ + move16(); + } + + E_min_th = L_shl( E_MIN_IVAS_FX_Q31, sub( q_hp_E, Q31 ) ); + + test(); + test(); + test(); + IF( ( EQ_16( st_fx->last_coder_type_raw, UNVOICED ) ) || /* previous frame was unvoiced */ + ( ( LT_32( ee[0], ee0_th ) ) && ( GT_32( hp_E[0], E_min_th ) ) && /* energy is concentrated in high frequencies provided that some energy is present in HF */ + ( LT_16( add_o( st_fx->voicing_fx[0], corr_shift, &Overflow ), voi_th ) ) ) ) /* normalized correlation is low */ + { + tmp_offset_flag = 0; + move16(); + } + + /*-----------------------------------------------------------------* + * Decision about UC + *-----------------------------------------------------------------*/ + + /* SC-VBR - set additional parameters and thresholds for SC-VBR */ + mean_voi3_offset = 0; + move16(); + flag_low_relE = 0; + move16(); + ee1_th = 608; /*9.5 Q6*/ + move16(); + test(); + test(); + IF( st_fx->Opt_SC_VBR || ( EQ_16( st_fx->idchan, 1 ) && EQ_16( st_fx->element_mode, IVAS_CPE_TD ) ) ) /* Allow the low energy flag for the secondary channel */ + { + ee1_th = 544; /*8.5f Q6*/ + move16(); + + /* SC-VBR - determine the threshold on relative energy as a function of lp_noise */ + IF( st_fx->input_bwidth != NB ) + { + /*relE_thres = 0.700f * st->lp_noise - 33.5f; (lp_noise in Q8, constant Q8<<16) */ + L_tmp = L_mac( -562036736 /* 33.5f in Q24 */, 22938 /* 0.7 in Q15 */, st_fx->lp_noise_fx ); // Q24 + IF( Last_Resort == 0 ) + { + /*relE_thres = 0.650f * st->lp_noise - 33.5f; (lp_noise in Q8, constant Q8<<16)*/ + L_tmp = L_mac( -562036736 /* 33.5f in Q24 */, 21299 /* 0.650f in Q15 */, st_fx->lp_noise_fx ); // Q24 + } + relE_thres = round_fx( L_tmp ); + } + ELSE + { + + /*relE_thres = 0.60f * st->lp_noise - 28.2f; (lp_noise in Q8, constant Q8<<16)*/ + L_tmp = L_mac( -473117491 /* 28.2f in Q24 */, 19661 /* 0.6f in Q15 */, st_fx->lp_noise_fx ); // Q24 + relE_thres = round_fx( L_tmp ); + } + relE_thres = s_max( relE_thres, -6400 /* -25.0f in Q8 */ ); /* Q8 */ + + /* SC-VBR = set flag on low relative energy */ + if ( LT_16( relE, relE_thres ) ) + { + flag_low_relE = 1; + move16(); + } + + /* SC-VBR - correction of voicing threshold for NB inputs (important only in noisy conditions) */ + test(); + if ( st_fx->input_bwidth == NB && LT_16( vadnoise, 20 << 8 ) ) /* vadnoise in Q8, constant Q0<<8 */ + { + mean_voi3_offset = 1638; /*0.05f Q15*/ + move16(); + } + } + + /* make decision whether frame is unvoiced */ + coder_type = GENERIC; + move16(); + IF( st_fx->input_bwidth == NB ) + { + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + IF( ( ( LT_16( add_o( mean_voi3, corr_shift, &Overflow ), add( 22282 /* 0.68 in Q15 */, mean_voi3_offset ) ) ) && /* normalized correlation low */ + ( LT_16( add_o( st_fx->voicing_fx[2], corr_shift, &Overflow ), 25887 /* 0.79 in Q15 */ ) ) && /* normalized correlation low on look-ahead - onset detection */ + ( LT_32( ee[0], 640 /* 10.0f in Q6 */ ) ) && ( GT_32( hp_E[0], E_min_th ) ) && /* energy concentrated in high frequencies provided that some energy is present in HF... */ + ( LT_32( ee[1], ee1_th ) ) && ( GT_32( hp_E[1], E_min_th ) ) && /* ... biased towards look-ahead to detect onsets */ + ( tmp_offset_flag == 0 ) && /* Take care of voiced offsets */ + /*( st_fx->music_hysteresis_fx == 0 ) &&*/ /* ... and in segment after AUDIO frames */ + ( LE_32( dE1, 237568 /* 29.0f in Q13 */ ) ) && /* Avoid on sharp energy spikes */ + ( LE_32( st_fx->old_dE1_fx, 237568 /* 29.0f in Q13 */ ) ) && /* + one frame hysteresis */ + ( st_fx->spike_hyst < 0 ) ) || /* Avoid after sharp energy spikes followed by decay (e.g. castanets) */ + flag_low_relE ) /* low relative frame energy (only for SC-VBR) */ + { + coder_type = UNVOICED; + move16(); + } + } + ELSE + { + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + if ( ( ( LT_16( add_o( mean_voi3, corr_shift, &Overflow ), add( 22774 /* 0.695f in Q15 */, mean_voi3_offset ) ) ) && /* normalized correlation low */ + /*( LT_16( add_o( st_fx->voicing_fx[2], corr_shift, &Overflow ), 25887 ) ) && */ /* normalized correlation low on look-ahead - onset detection */ + ( LT_32( ee[0], 397 /* 6.2f in Q6 */ ) ) && ( GT_32( hp_E[0], E_min_th ) ) && /* energy concentrated in high frequencies provided that some energy is present in HF... */ + ( LT_32( ee[1], 397 /* 6.2f in Q16 */ ) ) && ( GT_32( hp_E[1], E_min_th ) ) && /* ... biased towards look-ahead to detect onsets */ + ( tmp_offset_flag == 0 ) && /* Take care of voiced offsets */ + /*( st_fx->music_hysteresis_fx == 0 ) && */ /* ... and in segment after AUDIO frames */ + ( LE_32( dE1, 245760 /* 30.0f in Q13 */ ) ) && /* Avoid on sharp energy spikes */ + ( LE_32( st_fx->old_dE1_fx, 245760 /* 30.0f in Q13 */ ) ) && /* + one frame hysteresis */ + ( st_fx->spike_hyst < 0 ) ) /* Avoid after sharp energy spikes followed by decay (e.g. castanets) */ + || ( flag_low_relE && ( LE_32( st_fx->old_dE1_fx, 245760 /* 30.0f in Q13 */ ) ) ) ) /* low relative frame energy (only for SC-VBR) */ + { + coder_type = UNVOICED; + move16(); + } + } + + /*-----------------------------------------------------------------* + * Decision about VC + *-----------------------------------------------------------------*/ + if ( st_fx->Opt_SC_VBR ) + { + hSC_VBR->set_ppp_generic = 0; + } + move16(); + + test(); + test(); + IF( EQ_16( st_fx->localVAD, 1 ) && EQ_16( coder_type, GENERIC ) && NE_16( last_core_orig, AMR_WB_CORE ) ) + { + dpit1 = abs_s( sub( T_op_fr[1], T_op_fr[0] ) ); /* Q6 */ + dpit2 = abs_s( sub( T_op_fr[2], T_op_fr[1] ) ); /* Q6 */ + dpit3 = abs_s( sub( T_op_fr[3], T_op_fr[2] ) ); /* Q6 */ + + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + IF( ( GT_16( voicing_fr[0], 19825 /* 0.605 in Q15 */ ) ) && /* normalized correlation high in 1st sf. */ + ( GT_16( voicing_fr[1], 19825 /* 0.605 in Q15 */ ) ) && /* normalized correlation high in 2st sf. */ + ( GT_16( voicing_fr[2], 19825 /* 0.605 in Q15 */ ) ) && /* normalized correlation high in 3st sf. */ + ( GT_16( voicing_fr[3], 19825 /* 0.605 in Q15 */ ) ) && /* normalized correlation high in 4st sf. */ + ( GT_32( mean_ee, 256 /* 4.0f in Q6 */ ) ) && /* energy concentrated in low frequencies */ + ( LT_16( dpit1, 3 << 6 ) ) && + ( LT_16( dpit2, 3 << 6 ) ) && + ( LT_16( dpit3, 3 << 6 ) ) ) + { + coder_type = VOICED; + move16(); + } + ELSE IF( st_fx->Opt_SC_VBR && st_fx->input_bwidth == NB && LT_16( vadnoise, 20 << 8 ) ) + { + test(); + test(); + test(); + test(); + test(); + test(); + test(); + IF( GT_16( voicing_fr[0], 8192 /* 0.25 in Q15 */ ) && /* normalized correlation high in 1st sf. */ + ( GT_16( voicing_fr[1], 8192 /* 0.25 in Q15 */ ) ) && /* normalized correlation high in 2st sf. */ + ( GT_16( voicing_fr[2], 8192 /* 0.25 in Q15 */ ) ) && /* normalized correlation high in 3st sf. */ + ( GT_16( voicing_fr[3], 8192 /* 0.25 in Q15 */ ) ) && /* normalized correlation high in 4st sf. */ + ( GT_32( mean_ee, 64 /* 1.0f in Q6 */ ) ) && /* energy concentrated in low frequencies */ + ( LT_16( dpit1, 5 << 6 ) ) && + ( LT_16( dpit2, 5 << 6 ) ) && + ( LT_16( dpit3, 5 << 6 ) ) ) + { + hSC_VBR->set_ppp_generic = 1; + move16(); + coder_type = VOICED; + move16(); + } + } + + /* set VOICED mode for frames with very stable pitch and high correlation + and avoid to switch to AUDIO/MUSIC later */ + voicing_m = mac_r( L_mac( L_mac( L_mult( voicing_fr[3], 8192 /* 0.25 in Q15 */ ), voicing_fr[2], 8192 /* 0.25 in Q15 */ ), voicing_fr[1], 8192 /* 0.25 in Q15 */ ), voicing_fr[0], 8192 /* 0.25 in Q15 */ ); /* Q15 */ + test(); + test(); + test(); + test(); + test(); + IF( *flag_spitch || ( LE_16( dpit1, 3 << 6 ) && LE_16( dpit2, 3 << 6 ) && LE_16( dpit3, 3 << 6 ) && + GT_16( voicing_m, 31130 /* 0.95f in Q15 */ ) && GT_16( st_fx->voicing_sm_fx, 31785 /* 0.97f in Q15 */ ) ) ) + { + coder_type = VOICED; + move16(); + *flag_spitch = 1; + move16(); /*to avoid switch to AUDIO/MUSIC later*/ + } + } + + /*-----------------------------------------------------------------* + * Channel-aware mode - set RF mode and total bitrate + *-----------------------------------------------------------------*/ + + st_fx->rf_mode = st_fx->Opt_RF_ON; /* Q0 */ + move16(); + + IF( EQ_16( coder_type, GENERIC ) ) + { + test(); + test(); + test(); + test(); + IF( ( LT_16( voicing_fr[0], 6554 /* 0.2f in Q15 */ ) ) && /* normalized correlation high in 2st sf. */ + ( LT_16( voicing_fr[1], 6554 /* 0.2f in Q15 */ ) ) && /* normalized correlation high in 2st sf. */ + ( LT_16( voicing_fr[2], 6554 /* 0.2f in Q15 */ ) ) && /* normalized correlation high in 3rd sf. */ + ( LT_16( voicing_fr[3], 6554 /* 0.2f in Q15 */ ) ) && /* normalized correlation high in 4th sf. */ + ( GT_16( vadnoise, 25 << 8 ) ) ) /* when speech is clean */ + + { + st_fx->rf_mode = 0; + move16(); + /* Current frame cannot be compressed to pack the partial redundancy;*/ + + IF( NE_16( st_fx->rf_mode, st_fx->Opt_RF_ON ) ) + { + core_coder_mode_switch_ivas_fx( st_fx, st_fx->last_total_brate, 0 ); + } + } + } + + /*-----------------------------------------------------------------* + * UNCLR classifier + *-----------------------------------------------------------------*/ + + IF( hStereoClassif != NULL ) + { + test(); + test(); + test(); + test(); + test(); + IF( st_fx->element_mode > EVS_MONO && ( EQ_16( coder_type, GENERIC ) || EQ_16( coder_type, UNVOICED ) || coder_type == INACTIVE || st_fx->localVAD == 0 ) && LT_16( hStereoClassif->unclr_sw_enable_cnt[st_fx->idchan], MAX_UV_CNT ) ) + { + hStereoClassif->unclr_sw_enable_cnt[st_fx->idchan] = add( hStereoClassif->unclr_sw_enable_cnt[st_fx->idchan], 1 ); + move16(); + } + ELSE + { + hStereoClassif->unclr_sw_enable_cnt[st_fx->idchan] = 0; + move16(); + } + } /*-----------------------------------------------------------------* * Updates @@ -641,7 +1086,8 @@ Word16 find_uv_fx( /* o : coding type test(); if ( st_fx->spike_hyst >= 0 && LT_16( st_fx->spike_hyst, 2 ) ) { - st_fx->spike_hyst = add( st_fx->spike_hyst, 1 ); + st_fx->spike_hyst = add( st_fx->spike_hyst, 1 ); /* Q0 */ + move16(); } /* reset spike hysteresis */ @@ -649,12 +1095,8 @@ Word16 find_uv_fx( /* o : coding type test(); test(); if ( ( GT_16( st_fx->spike_hyst, 1 ) ) && - ( GT_16( dE3, 5 << 8 ) || /* energy increases */ -#ifdef BASOP_NOGLOB - ( GT_16( relE, -3328 ) && ( GT_16( add_sat( mean_voi3, corr_shift ), 22774 ) ) ) ) ) /* normalized correlation is high */ -#else - ( GT_16( relE, -3328 ) && ( GT_16( add( mean_voi3, corr_shift ), 22774 ) ) ) ) ) /* normalized correlation is high */ -#endif + ( GT_16( dE3, 5 << 8 ) || /* energy increases */ + ( GT_16( relE, -3328 /* 13 in Q8 */ ) && ( GT_16( add_sat( mean_voi3, corr_shift ), 22774 /* 0.695 in Q15 */ ) ) ) ) ) /* normalized correlation is high */ { st_fx->spike_hyst = -1; move16(); @@ -667,7 +1109,7 @@ Word16 find_uv_fx( /* o : coding type move32(); /*Q13*/ /* save the raw coder_type for various modules later in the codec (the reason is that e.g. UNVOICED is lost at higher rates) */ - st_fx->coder_type_raw = coder_type; + st_fx->coder_type_raw = coder_type; /* Q0 */ move16(); return coder_type; diff --git a/lib_enc/find_wsp.c b/lib_enc/find_wsp.c deleted file mode 100644 index 9ba0a3c0764e86263dd28cebfe9af965e82e59a4..0000000000000000000000000000000000000000 --- a/lib_enc/find_wsp.c +++ /dev/null @@ -1,98 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include "cnst.h" -#include "prot.h" -#include "wmc_auto.h" -#include "prot_fx.h" -/*-------------------------------------------------------------------* - * find_wsp() - * - * Compute weighted speech used in open-loop pitch search - *-------------------------------------------------------------------*/ -void ivas_find_wsp( - const Word16 L_frame, /* i : length of the frame */ - const Word16 L_subfr, /* i : length of subframe */ - const Word16 nb_subfr, /* i : number of subframes */ - const Word16 *A_fx, - /* i : A(z) filter coefficients */ // Q12 - Word16 *Aw_fx, - /* o : weighted A(z) filter coefficients */ // Q12 - const Word16 *speech_fx, - /* i : pointer to the denoised speech frame */ // Q_new - const Word16 tilt_fact, - /* i : tilt factor */ // Q15 - Word16 *wsp_fx, - /* o : poitnter to the weighted speech frame */ // Q_new - Word16 *mem_wsp_fx, - /* i/o: W(Z) denominator memory */ // Q_new - const Word16 gamma, - /* i : weighting factor */ // Q15 - const Word16 L_look /* i : look-ahead */ -) -{ - Word16 *p_Aw_fx, tmp_fx; - Word16 i_subfr; - - - /*-----------------------------------------------------------------* - * Compute weighted A(z) unquantized for subframes - *-----------------------------------------------------------------*/ - weight_a_subfr_fx( nb_subfr, A_fx, Aw_fx, gamma, M ); - - /*-----------------------------------------------------------------* - * Compute weighted speech for all subframes - *-----------------------------------------------------------------*/ - p_Aw_fx = Aw_fx; - for ( i_subfr = 0; i_subfr < L_frame; i_subfr += L_subfr ) - { - Residu3_fx( p_Aw_fx, &speech_fx[i_subfr], &wsp_fx[i_subfr], L_subfr, 0 ); - p_Aw_fx += ( M + 1 ); - } - p_Aw_fx -= ( M + 1 ); - - /*-----------------------------------------------------------------* - * Weighted speech computation is extended on look-ahead - *-----------------------------------------------------------------*/ - - deemph_fx( wsp_fx, tilt_fact, L_frame, mem_wsp_fx ); - Residu3_fx( p_Aw_fx, &speech_fx[L_frame], &wsp_fx[L_frame], L_look, 0 ); - tmp_fx = *mem_wsp_fx; - deemph_fx( &wsp_fx[L_frame], tilt_fact, L_look, &tmp_fx ); - return; -} diff --git a/lib_enc/find_wsp_fx.c b/lib_enc/find_wsp_fx.c index de81f19214e626801376295422c993120a79672c..155e499046dd1ead55fbc5fc7bf4f87eb4edd434 100644 --- a/lib_enc/find_wsp_fx.c +++ b/lib_enc/find_wsp_fx.c @@ -6,8 +6,7 @@ #include #include "options.h" #include "cnst.h" -//#include "prot_fx.h" -#include "prot_fx.h" /* Function prototypes */ +#include "prot_fx.h" #include "prot_fx_enc.h" /* Function prototypes */ @@ -31,17 +30,17 @@ * void */ void find_wsp_fx( - const Word16 Az[], /* i : A(z) filter coefficients */ - const Word16 speech[], /* i : pointer to the denoised speech frame */ - Word16 wsp[], /* o : poitnter to the weighted speech frame */ - Word16 *mem_wsp, /* i/o: W(Z) denominator memory */ - const Word16 preemph_fac, /* i : pre - emphasis factor Q15 */ - const Word16 L_frame, /* i : length of the frame */ - const Word16 lookahead, /* i : look-ahead */ - const Word16 L_subfr, /* i : length of subframe */ - Word16 *Aw, /* o : weighted A(z) filter coefficients */ - const Word16 gamma, /* i : weighting factor */ - const Word16 nb_subfr /* i : number of subframes */ + const Word16 Az[], /* i : A(z) filter coefficients Q12*/ + const Word16 speech[], /* i : pointer to the denoised speech frame Q_new-preemph_bits*/ + Word16 wsp[], /* o : poitnter to the weighted speech frame Q_new-preemph_bits*/ + Word16 *mem_wsp, /* i/o: W(Z) denominator memory Q_new-preemph_bits*/ + const Word16 preemph_fac, /* i : pre - emphasis factor Q15*/ + const Word16 L_frame, /* i : length of the frame Q0*/ + const Word16 lookahead, /* i : look-ahead Q0*/ + const Word16 L_subfr, /* i : length of subframe Q0*/ + Word16 *Aw, /* o : weighted A(z) filter coefficients Q12*/ + const Word16 gamma, /* i : weighting factor Q15*/ + const Word16 nb_subfr /* i : number of subframes Q0*/ ) { Word16 i_subfr, wtmp; @@ -78,3 +77,60 @@ void find_wsp_fx( deemph_fx( &wsp[L_frame], preemph_fac, lookahead, &wtmp ); } } + +/*-------------------------------------------------------------------* + * ivas_find_wsp_fx() + * + * Compute weighted speech used in open-loop pitch search + *-------------------------------------------------------------------*/ +void ivas_find_wsp_fx( + const Word16 L_frame, /* i : length of the frame Q0*/ + const Word16 L_subfr, /* i : length of subframe Q0*/ + const Word16 nb_subfr, /* i : number of subframes Q0*/ + const Word16 *A_fx, + /* i : A(z) filter coefficients */ // Q12 + Word16 *Aw_fx, + /* o : weighted A(z) filter coefficients */ // Q12 + const Word16 *speech_fx, + /* i : pointer to the denoised speech frame */ // Q_new + const Word16 tilt_fact, + /* i : tilt factor */ // Q15 + Word16 *wsp_fx, + /* o : poitnter to the weighted speech frame */ // Q_new + Word16 *mem_wsp_fx, + /* i/o: W(Z) denominator memory */ // Q_new + const Word16 gamma, + /* i : weighting factor */ // Q15 + const Word16 L_look /* i : look-ahead Q0*/ +) +{ + Word16 *p_Aw_fx, tmp_fx; + Word16 i_subfr; + + + /*-----------------------------------------------------------------* + * Compute weighted A(z) unquantized for subframes + *-----------------------------------------------------------------*/ + weight_a_subfr_fx( nb_subfr, A_fx, Aw_fx, gamma, M ); + + /*-----------------------------------------------------------------* + * Compute weighted speech for all subframes + *-----------------------------------------------------------------*/ + p_Aw_fx = Aw_fx; + FOR( i_subfr = 0; i_subfr < L_frame; i_subfr += L_subfr ) + { + Residu3_fx( p_Aw_fx, &speech_fx[i_subfr], &wsp_fx[i_subfr], L_subfr, 0 ); + p_Aw_fx += ( M + 1 ); + } + p_Aw_fx -= ( M + 1 ); + + /*-----------------------------------------------------------------* + * Weighted speech computation is extended on look-ahead + *-----------------------------------------------------------------*/ + + deemph_fx( wsp_fx, tilt_fact, L_frame, mem_wsp_fx ); + Residu3_fx( p_Aw_fx, &speech_fx[L_frame], &wsp_fx[L_frame], L_look, 0 ); + tmp_fx = *mem_wsp_fx; + deemph_fx( &wsp_fx[L_frame], tilt_fact, L_look, &tmp_fx ); + return; +} diff --git a/lib_enc/frame_spec_dif_cor_rate.c b/lib_enc/frame_spec_dif_cor_rate.c deleted file mode 100644 index 09ecb0cc8da1fd61600761850fcaf7872e0239fa..0000000000000000000000000000000000000000 --- a/lib_enc/frame_spec_dif_cor_rate.c +++ /dev/null @@ -1,47 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include -#include "prot.h" -#include "wmc_auto.h" - -/*-------------------------------------------------------------------* - * frame_spec_dif_cor_rate() - * - * - *-------------------------------------------------------------------*/ diff --git a/lib_enc/frame_spec_dif_cor_rate_fx.c b/lib_enc/frame_spec_dif_cor_rate_fx.c index 117ced6baf87ef4209f4d88104b659e4b4c84856..3e2eb40155f5e006eda820818db061688d9d2299 100644 --- a/lib_enc/frame_spec_dif_cor_rate_fx.c +++ b/lib_enc/frame_spec_dif_cor_rate_fx.c @@ -20,10 +20,10 @@ * *-------------------------------------------------------------------*/ void frame_spec_dif_cor_rate_fx( - VAD_CLDFB_HANDLE hVAD_CLDFB, /* i/o: CLDFB VAD state */ - Word32 *spec_amp, /* i : spectral amplitude*/ - Word16 sacle, /* i : the scaling of spec_amp*/ - Word16 f_tonality_rate[3] /* o : tonality rate*/ + VAD_CLDFB_HANDLE hVAD_CLDFB, /* i/o: CLDFB VAD state */ + Word32 *spec_amp, /* i : spectral amplitude scale*/ + Word16 sacle, /* i : the scaling of spec_amp */ + Word16 f_tonality_rate[3] /* o : tonality rate Qx*/ ) { @@ -36,22 +36,23 @@ void frame_spec_dif_cor_rate_fx( Word32 m, dx, dy; Word16 *pre_spec_low_dif = hVAD_CLDFB->pre_spec_low_dif; const Word32 FIX_cost1 = 2147484 /* 0.001f Q31 */; - + move16(); + move32(); p_dx_Q = &dx_Q; maxVal = 0; move32(); FOR( i = 0; i < PRE_SPEC_DIF_NUM; i++ ) { - tmp = L_sub( spec_amp[i + 6], spec_amp[i + 5] ); + tmp = L_sub( spec_amp[i + 6], spec_amp[i + 5] ); /* scale */ if ( tmp < 0 ) { tmp = 0; move32(); } - tmpspec_low_dif[i] = tmp; + tmpspec_low_dif[i] = tmp; /* scale */ move32(); - maxVal = L_max( maxVal, tmp ); + maxVal = L_max( maxVal, tmp ); /* scale */ } resu = 31; move16(); @@ -71,14 +72,14 @@ void frame_spec_dif_cor_rate_fx( FOR( i = 0; i < PRE_SPEC_DIF_NUM; i++ ) { - spec_low_dif_tmp = round_fx( L_shl( tmpspec_low_dif[i], scalefactor ) ); - m = L_mac0( m, spec_low_dif_tmp, pre_spec_low_dif[i] ); - dx = L_mac0( dx, spec_low_dif_tmp, spec_low_dif_tmp ); - dy = L_mac0( dy, pre_spec_low_dif[i], pre_spec_low_dif[i] ); + spec_low_dif_tmp = round_fx( L_shl( tmpspec_low_dif[i], scalefactor ) ); /* scale + scalefactor - 16 */ + m = L_mac0( m, spec_low_dif_tmp, pre_spec_low_dif[i] ); /* scale + scalefactor - 16 + hVAD_CLDFB->scale_spec_low_dif */ + dx = L_mac0( dx, spec_low_dif_tmp, spec_low_dif_tmp ); /* scale + scalefactor - 16 + hVAD_CLDFB->scale_spec_low_dif */ + dy = L_mac0( dy, pre_spec_low_dif[i], pre_spec_low_dif[i] ); /* scale + scalefactor - 16 */ pre_spec_low_dif[i] = spec_low_dif_tmp; move16(); } - dx = L_mult0( round_fx( dx ), round_fx( dy ) ); + dx = L_mult0( round_fx( dx ), round_fx( dy ) ); /* 2 * (scale + scalefactor - 16 + hVAD_CLDFB->scale_spec_low_dif) - 32 */ tmpq = add( sacle, scalefactor ); tmpq = sub( tmpq, 16 ); tmpq2 = add( tmpq, hVAD_CLDFB->scale_spec_low_dif ); @@ -88,11 +89,11 @@ void frame_spec_dif_cor_rate_fx( move16(); IF( LT_16( *p_dx_Q, 31 ) ) { - dx = L_add( dx, L_shr( FIX_cost1, limitScale32( sub( 31, *p_dx_Q ) ) ) ); + dx = L_add( dx, L_shr( FIX_cost1, limitScale32( sub( 31, *p_dx_Q ) ) ) ); /* 2 * (scale + scalefactor - 16 + hVAD_CLDFB->scale_spec_low_dif) - 32 */ } ELSE { - dx = L_add( L_shr( dx, limitScale32( sub( *p_dx_Q, 31 ) ) ), FIX_cost1 ); + dx = L_add( L_shr( dx, limitScale32( sub( *p_dx_Q, 31 ) ) ), FIX_cost1 ); /* Q31 */ *p_dx_Q = 31; move16(); } @@ -110,10 +111,10 @@ void frame_spec_dif_cor_rate_fx( f_tonality_rate[0] = spec_dif_cor_rate; move16(); - tmp = L_mac0( L_mult0( f_tonality_rate[1], 31456 /* 0.96 Q15 */ ), spec_dif_cor_rate, 1311 /* 0.04 Q15 */ ); + tmp = L_mac0( L_mult0( f_tonality_rate[1], 31456 /* 0.96 Q15 */ ), spec_dif_cor_rate, 1311 /* 0.04 Q15 */ ); /* tmpq */ f_tonality_rate[1] = shl( round_fx( tmp ), 1 ); move16(); - tmp = L_mac0( L_mult0( f_tonality_rate[2], 29490 /* 0.90 Q15 */ ), spec_dif_cor_rate, 3277 /* 0.1 Q15 */ ); + tmp = L_mac0( L_mult0( f_tonality_rate[2], 29490 /* 0.90 Q15 */ ), spec_dif_cor_rate, 3277 /* 0.1 Q15 */ ); /* tmpq */ f_tonality_rate[2] = shl( round_fx( tmp ), 1 ); move16(); hVAD_CLDFB->scale_spec_low_dif = tmpq; diff --git a/lib_enc/gain_enc.c b/lib_enc/gain_enc.c deleted file mode 100644 index bd3da322af1606439586ba9acb92de4c09a4158e..0000000000000000000000000000000000000000 --- a/lib_enc/gain_enc.c +++ /dev/null @@ -1,55 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include -#include "cnst.h" -#include "rom_com.h" -#include "prot.h" -#include "wmc_auto.h" - -/*-------------------------------------------------------------------* - * Local constants - *-------------------------------------------------------------------*/ - -#define RANGE 64 - -/*---------------------------------------------------------------------* - * Es_pred_enc() - * - * Calculation and quantization of average predicted innovation energy to be - *---------------------------------------------------------------------*/ diff --git a/lib_enc/gain_enc_fx.c b/lib_enc/gain_enc_fx.c index 30caee67e01193ed958623185ab36ec51ea19e42..0321cd763496bed2b50533c25200944947315a6d 100644 --- a/lib_enc/gain_enc_fx.c +++ b/lib_enc/gain_enc_fx.c @@ -7,7 +7,6 @@ #include "rom_com_fx.h" /* Static table prototypes */ #include "rom_com.h" /* Static table prototypes */ //#include "prot_fx.h" /* Function prototypes */ -#include "prot.h" /* Function prototypes */ #include "prot_fx.h" /* Function prototypes */ #include "prot_fx_enc.h" /* Function prototypes */ @@ -50,14 +49,14 @@ static Word16 Find_Opt_gainQ_fx( Word16 *coeff, Word16 *exp_coeff, Word16 *gain_ /*==========================================================================*/ void Es_pred_enc_fx( - Word16 *Es_pred, /* o : predicited scaled innovation energy Q8 */ - Word16 *indice, /* o : indice of quantization */ - const Word16 L_frame, /* i : length of the frame */ - const Word16 *res, /* i : residual signal */ - const Word16 *voicing, /* i : normalized correlation in three 1/2frames */ - const Word16 nb_bits, /* i : allocated number of bits */ - const Word16 no_ltp, /* i : no_ltp flag */ - Word16 Q_new /* i : Scaling in speech Q0 */ + Word16 *Es_pred, /* o : predicited scaled innovation energy Q8*/ + Word16 *indice, /* o : indice of quantization Q0*/ + const Word16 L_frame, /* i : length of the frame Q0*/ + const Word16 *res, /* i : residual signal Q_new*/ + const Word16 *voicing, /* i : normalized correlation in three 1/2frames Q15*/ + const Word16 nb_bits, /* i : allocated number of bits Q0*/ + const Word16 no_ltp, /* i : no_ltp flag Q0*/ + Word16 Q_new /* i : Scaling in speech Q0*/ ) { Word16 i, i_subfr, size, tmp16, tmp16_2, Q_res; @@ -67,6 +66,7 @@ void Es_pred_enc_fx( Word32 ener_fx, Lmean_ener_code, Ltmp; #ifdef BASOP_NOGLOB_DECLARE_LOCAL Flag Overflow = 0; + move32(); #endif Lmean_ener_code = L_deposit_l( 0 ); @@ -90,16 +90,12 @@ void Es_pred_enc_fx( FOR( i_subfr = 0; i_subfr < L_frame; i_subfr += L_SUBFR ) { /* calculate the energy of residual signal */ - tmp16 = mult_r( res[i_subfr + 0], 8192 ); /* remove 2bits */ + tmp16 = mult_r( res[i_subfr + 0], 8192 /* 1 in Q13 */ ); /* remove 2bits Q_new - 2*/ ener_fx = L_mult( tmp16, tmp16 ); FOR( i = 1; i < L_SUBFR; i++ ) { - tmp16 = mult_r( res[i_subfr + i], 8192 ); /* remove 2bits */ -#ifdef BASOP_NOGLOB + tmp16 = mult_r( res[i_subfr + i], 8192 /* 1 in Q13 */ ); /* remove 2bits Q_new - 2*/ ener_fx = L_mac_o( ener_fx, tmp16, tmp16, &Overflow ); -#else - ener_fx = L_mac( ener_fx, tmp16, tmp16 ); -#endif } /* ener = 10 * (float)log10(ener / (float)L_SUBFR) */ @@ -119,6 +115,7 @@ void Es_pred_enc_fx( if ( ( ener_dB < 0 ) && ( no_ltp == 0 ) ) { ener_dB = 0; + move16(); } /* update the average energy of residual signal */ @@ -142,22 +139,22 @@ void Es_pred_enc_fx( { case 5: { - qua_table = Es_pred_qua_5b_fx; + qua_table = Es_pred_qua_5b_fx; // Q8 BREAK; } case 4: { - qua_table = Es_pred_qua_4b_fx; + qua_table = Es_pred_qua_4b_fx; // Q8 BREAK; } case 3: { - qua_table = Es_pred_qua_3b_fx; + qua_table = Es_pred_qua_3b_fx; // Q8 BREAK; } default: { - qua_table = Es_pred_qua_5b_fx; + qua_table = Es_pred_qua_5b_fx; // Q8 BREAK; } } @@ -166,13 +163,13 @@ void Es_pred_enc_fx( { mean_ener_code16 = extract_h( Lmean_ener_code ); /*Q8*/ - qua_table = Es_pred_qua_4b_no_ltp_fx; + qua_table = Es_pred_qua_4b_no_ltp_fx; // Q8 } /*size = extract_l(pow2_fx[nb_bits]); */ /*maximum number of bit is 6 */ size = shl( 1, nb_bits ); /*maximum number of bit is 6 */ /* find the nearest neighbour (codevector) */ - *Es_pred = qua_table[0]; + *Es_pred = qua_table[0]; // Q8 move16(); tmp16 = abs_s( sub( mean_ener_code16, qua_table[0] ) ); *indice = 0; @@ -180,18 +177,14 @@ void Es_pred_enc_fx( FOR( i = 1; i < size; i++ ) { -#ifdef BASOP_NOGLOB tmp16_2 = abs_s( sub_o( mean_ener_code16, qua_table[i], &Overflow ) ); -#else /* BASOP_NOGLOB */ - tmp16_2 = abs_s( sub( mean_ener_code16, qua_table[i] ) ); -#endif /* BASOP_NOGLOB */ IF( LT_16( tmp16_2, tmp16 ) ) { tmp16 = tmp16_2; move16(); *indice = i; move16(); - *Es_pred = qua_table[i]; + *Es_pred = qua_table[i]; // Q8 move16(); } } @@ -209,24 +202,24 @@ void Es_pred_enc_fx( * - the mean-squared weighted error criterion is used for codebook search *---------------------------------------------------------------------*/ void gain_enc_mless_fx( - BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ - const Word16 gains_mode[], /* i : gain bits */ - const Word16 element_mode, /* i : element mode */ - const Word16 L_frame, /* i : length of the frame */ - const Word16 i_subfr, /* i : subframe index */ - const Word16 tc_subfr, /* i : TC subframe index */ - const Word16 *xn, /* i : target vector */ - const Word16 *y1, /* i : zero-memory filtered adaptive excitation */ - const Word16 Q_xn, /* i : xn and y1 scaling */ - const Word16 *y2, /* i : zero-memory filtered algebraic codebook excitation */ - const Word16 *code, /* i : algebraic excitation */ - const Word16 Es_pred, /* i : predicted scaled innovation energy */ - Word16 *gain_pit, /* o : quantized pitch gain */ - Word32 *gain_code, /* o : quantized codebook gain */ - Word16 *gain_inov, /* o : gain of the innovation (used for normalization) */ - Word32 *norm_gain_code, /* o : norm. gain of the codebook excitation */ - Word16 *g_corr, /* i/o: correlations , -2,, -2 and 2 */ - const Word16 clip_gain /* i : gain pitch clipping flag (1 = clipping) */ + BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ + const Word16 gains_mode[], /* i : gain bits Q0*/ + const Word16 element_mode, /* i : element mode Q0*/ + const Word16 L_frame, /* i : length of the frame Q0*/ + const Word16 i_subfr, /* i : subframe index Q0*/ + const Word16 tc_subfr, /* i : TC subframe index Q0*/ + const Word16 *xn, /* i : target vector Q_xn*/ + const Word16 *y1, /* i : zero-memory filtered adaptive excitation Q_xn*/ + const Word16 Q_xn, /* i : xn and y1 scaling */ + const Word16 *y2, /* i : zero-memory filtered algebraic codebook excitation Q9*/ + const Word16 *code, /* i : algebraic excitation Q9*/ + const Word16 Es_pred, /* i : predicted scaled innovation energy Q8*/ + Word16 *gain_pit, /* o : quantized pitch gain Q14*/ + Word32 *gain_code, /* o : quantized codebook gain Q16*/ + Word16 *gain_inov, /* o : gain of the innovation (used for normalization) Q12*/ + Word32 *norm_gain_code, /* o : norm. gain of the codebook excitation Q16*/ + Word16 *g_corr, /* i/o: correlations , -2,, -2 and 2 Qx*/ + const Word16 clip_gain /* i : gain pitch clipping flag (1 = clipping) Q0*/ ) { @@ -242,6 +235,7 @@ void gain_enc_mless_fx( Word32 L_frac_num, L_frac_den, L_div; #ifdef BASOP_NOGLOB_DECLARE_LOCAL Flag Overflow = 0; + move32(); #endif /*-----------------------------------------------------------------* @@ -304,6 +298,7 @@ void gain_enc_mless_fx( /* gain_inov = 1.0f / sqrt((dot_product(code, code, L_SUBFR) + 0.01) / L_SUBFR) */ L_tmp = Isqrt_lc( L_tmp, &exp_inov ); *gain_inov = extract_h( L_shl( L_tmp, sub( exp_inov, 3 ) ) ); /* gain_inov in Q12 */ + move16(); /* gcode0 = pow(10, 0.05 * (Es_pred - Ei)) */ /*----------------------------------------------------------------* @@ -325,7 +320,7 @@ void gain_enc_mless_fx( * select the codebook, size and number of bits * set the gains searching range *-----------------------------------------------------------------*/ - nBits = gains_mode[shr( i_subfr, 6 )]; + nBits = gains_mode[i_subfr >> 6]; move16(); test(); @@ -364,9 +359,9 @@ void gain_enc_mless_fx( } L_frac_den = L_sub( L_tmp1, L_tmp2 ); /*Q31*/ - frac_den = extract_h( L_frac_den ); - frac_den = s_max( frac_den, 1 ); - L_frac_den = L_max( L_frac_den, 1 ); + frac_den = extract_h( L_frac_den ); /* Q15 */ + frac_den = s_max( frac_den, 1 ); /* Q15 */ + L_frac_den = L_max( L_frac_den, 1 ); /* Q31 */ exp = norm_l( L_frac_den ); tmp = div_s( shl( 1, sub( 14, exp ) ), frac_den ); /*Q(14-exp)*/ @@ -393,11 +388,7 @@ void gain_enc_mless_fx( L_div = Mult_32_16( L_frac_num, tmp ); /*Q(30-exp)*/ exp_div = sub( exp_num, exp_den ); -#ifdef BASOP_NOGLOB *gain_pit = round_fx_o( L_shl_o( L_div, add( exp, exp_div ), &Overflow ), &Overflow ); /*Q14*/ -#else - *gain_pit = round_fx( L_shl( L_div, add( exp, exp_div ) ) ); /*Q14*/ -#endif L_tmp1 = L_shr( L_mult( coeff[1], coeff[4] ), 2 ); /*Q31*/ exp1 = add( exp_coeff[1], exp_coeff[4] ); @@ -409,25 +400,24 @@ void gain_enc_mless_fx( { L_tmp2 = L_shr( L_tmp2, sub( exp1, exp2 ) ); /*Q31*/ exp_num = exp1; + move16(); } ELSE { L_tmp1 = L_shr( L_tmp1, sub( exp2, exp1 ) ); /*Q31*/ exp_num = exp2; + move16(); } L_frac_num = L_sub( L_tmp1, L_tmp2 ); /*Q31*/ L_div = Mult_32_16( L_frac_num, tmp ); /*Q(30-exp)*/ exp_div = sub( exp_num, exp_den ); -#ifdef BASOP_NOGLOB *gain_code = L_shl_o( L_div, sub( add( exp, exp_div ), 14 ), &Overflow ); -#else - *gain_code = L_shl( L_div, sub( add( exp, exp_div ), 14 ) ); -#endif move32(); /*Q16*/ *gain_pit = s_max( G_PITCH_MIN_TC192_Q14, s_min( *gain_pit, G_PITCH_MAX_TC192_Q14 ) ); + move16(); /* set number of bits for two SQs */ nBits2 = shr( add( nBits, 1 ), 1 ); @@ -447,16 +437,13 @@ void gain_enc_mless_fx( tmp = div_s( 16384, gcode0 ); /*Q15*/ L_tmp = Mult_32_16( *gain_code, tmp ); /*Q16*/ *gain_code = L_shr( L_tmp, add( 14, exp_gcode0 ) ); /*Q16*/ + move32(); } index = gain_quant_fx( gain_code, &gain_code16, LG10_G_CODE_MIN_TC192_Q14, LG10_G_CODE_MAX_TC192_Q13, nBits2, &expg ); push_indice_fx( hBstr, IND_GAIN_CODE, index, nBits2 ); - L_tmp = L_mult( gain_code16, gcode0 ); /*Q0*Q0 -> Q1*/ -#ifdef BASOP_NOGLOB + L_tmp = L_mult( gain_code16, gcode0 ); /*Q0*Q0 -> Q1*/ *gain_code = L_shl_o( L_tmp, add( add( expg, exp_gcode0 ), 15 ), &Overflow ); /*Q16*/ -#else - *gain_code = L_shl( L_tmp, add( add( expg, exp_gcode0 ), 15 ) ); /*Q16*/ -#endif } ELSE { @@ -477,13 +464,8 @@ void gain_enc_mless_fx( case 6: { qua_table = gain_qua_mless_6b_fx; - if ( GT_16( element_mode, EVS_MONO ) ) + if ( element_mode > EVS_MONO ) { -#ifdef IVAS_CODE - qua_table = gain_qua_mless_6b_stereo; -#else - // PMTE() -#endif } move16(); if ( EQ_16( clip_gain, 1 ) ) @@ -494,7 +476,7 @@ void gain_enc_mless_fx( } case 5: { - qua_table = gain_qua_mless_5b_fx; + qua_table = gain_qua_mless_5b_fx; // Q14 move16(); if ( EQ_16( clip_gain, 1 ) ) { @@ -504,7 +486,7 @@ void gain_enc_mless_fx( } default: { - qua_table = gain_qua_mless_6b_fx; + qua_table = gain_qua_mless_6b_fx; // Q14 move16(); if ( EQ_16( clip_gain, 1 ) ) { @@ -525,7 +507,7 @@ void gain_enc_mless_fx( /*-----------------------------------------------------------------* * search for the best quantizer *-----------------------------------------------------------------*/ - index = Find_Opt_gainQ_fx( coeff, exp_coeff, gain_pit, gain_code, gcode0, exp_gcode0, qua_table, size ); + index = Find_Opt_gainQ_fx( coeff, exp_coeff, gain_pit, gain_code, gcode0, exp_gcode0, qua_table, size ); // Q0 push_indice_fx( hBstr, IND_GAIN, index, nBits ); } @@ -541,24 +523,24 @@ void gain_enc_mless_fx( } void gain_enc_mless_ivas_fx( - BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ - const Word16 gains_mode[], /* i : gain bits */ - const Word16 element_mode, /* i : element mode */ - const Word16 L_frame, /* i : length of the frame */ - const Word16 i_subfr, /* i : subframe index */ - const Word16 tc_subfr, /* i : TC subframe index */ - const Word16 *xn, /* i : target vector */ - const Word16 *y1, /* i : zero-memory filtered adaptive excitation */ - const Word16 Q_xn, /* i : xn and y1 scaling */ - const Word16 *y2, /* i : zero-memory filtered algebraic codebook excitation */ - const Word16 *code, /* i : algebraic excitation */ - const Word16 Es_pred, /* i : predicted scaled innovation energy */ - Word16 *gain_pit, /* o : quantized pitch gain */ - Word32 *gain_code, /* o : quantized codebook gain */ - Word16 *gain_inov, /* o : gain of the innovation (used for normalization) */ - Word32 *norm_gain_code, /* o : norm. gain of the codebook excitation */ - Word16 *g_corr, /* i/o: correlations , -2,, -2 and 2 */ - const Word16 clip_gain /* i : gain pitch clipping flag (1 = clipping) */ + BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ + const Word16 gains_mode[], /* i : gain bits Q0*/ + const Word16 element_mode, /* i : element mode Q0*/ + const Word16 L_frame, /* i : length of the frame Q0*/ + const Word16 i_subfr, /* i : subframe index Q0*/ + const Word16 tc_subfr, /* i : TC subframe index Q0*/ + const Word16 *xn, /* i : target vector Q_xn*/ + const Word16 *y1, /* i : zero-memory filtered adaptive excitation Q_xn*/ + const Word16 Q_xn, /* i : xn and y1 scaling */ + const Word16 *y2, /* i : zero-memory filtered algebraic codebook excitation Q9*/ + const Word16 *code, /* i : algebraic excitation Q9*/ + const Word16 Es_pred, /* i : predicted scaled innovation energy Q8*/ + Word16 *gain_pit, /* o : quantized pitch gain Q14*/ + Word32 *gain_code, /* o : quantized codebook gain Q16*/ + Word16 *gain_inov, /* o : gain of the innovation (used for normalization) Q12*/ + Word32 *norm_gain_code, /* o : norm. gain of the codebook excitation Q16*/ + Word16 *g_corr, /* i/o: correlations , -2,, -2 and 2 Qx*/ + const Word16 clip_gain /* i : gain pitch clipping flag (1 = clipping) Q0*/ ) { @@ -574,6 +556,7 @@ void gain_enc_mless_ivas_fx( Word32 L_frac_num, L_frac_den, L_div; #ifdef BASOP_NOGLOB_DECLARE_LOCAL Flag Overflow = 0; + move32(); #endif /*-----------------------------------------------------------------* @@ -613,30 +596,44 @@ void gain_enc_mless_ivas_fx( /* gain_inov = 1.0f / sqrt((dot_product(code, code, L_SUBFR) + 0.01) / L_SUBFR) */ L_tmp = Dot_product12( code, code, L_SUBFR, &exp_code ); exp_inov = sub( exp_code, 18 + 6 ); - exp_code = sub( exp_code, 30 ); - /*Ei = 10 * log10((dot_product(code, code, L_SUBFR) + 0.01) / L_SUBFR) */ + // To avoid crash in case code value is 0, + IF( EQ_16( BASOP_Util_Cmp_Mant32Exp( L_tmp, exp_inov, 21474836, 0 ), -1 ) ) + { + // setting values to avoid extra computation + *gain_inov = 32767; /*8(max value gain_inov can hold) in Q12*/ + Ei = -9743; /* -38 in Q8*/ + move16(); + move16(); + } + ELSE + { + exp_code = sub( exp_code, 30 ); - /*----------------------------------------------------------------* - * calculate the predicted gain code - *----------------------------------------------------------------*/ - tmp = norm_l( L_tmp ); - frac = Log2_norm_lc( L_shl( L_tmp, tmp ) ); - tmp = add( 30 - 18 - 6 - 1, sub( exp_code, tmp ) ); /* exp: -18 (code in Q9), -6 (/L_SUBFR) */ - L_tmp1 = Mpy_32_16( tmp, frac, 12330 ); /* Q13 */ - Ei = round_fx( L_shl( L_tmp1, 11 ) ); /* Q8 */ + /*Ei = 10 * log10((dot_product(code, code, L_SUBFR) + 0.01) / L_SUBFR) */ + + /*----------------------------------------------------------------* + * calculate the predicted gain code + *----------------------------------------------------------------*/ + tmp = norm_l( L_tmp ); + frac = Log2_norm_lc( L_shl( L_tmp, tmp ) ); + tmp = add( 30 - 18 - 6 - 1, sub( exp_code, tmp ) ); /* exp: -18 (code in Q9), -6 (/L_SUBFR) */ + L_tmp1 = Mpy_32_16( tmp, frac, 12330 ); /* Q13 */ + Ei = round_fx( L_shl( L_tmp1, 11 ) ); /* Q8 */ + + /*---------------------------------------------------------------* + * Decode codebook gain and the adaptive excitation low-pass + * filtering factor (Finalize computation ) + *---------------------------------------------------------------*/ + /* gain_inov = 1.0f / sqrt((dot_product(code, code, L_SUBFR) + 0.01) / L_SUBFR) */ + L_tmp = Isqrt_lc( L_tmp, &exp_inov ); + *gain_inov = extract_h( L_shl( L_tmp, sub( exp_inov, 3 ) ) ); /* gain_inov in Q12 */ + move16(); + } /* predicted codebook gain */ gcode0 = sub( Es_pred, Ei ); /* Q8 */ - /*---------------------------------------------------------------* - * Decode codebook gain and the adaptive excitation low-pass - * filtering factor (Finalize computation ) - *---------------------------------------------------------------*/ - /* gain_inov = 1.0f / sqrt((dot_product(code, code, L_SUBFR) + 0.01) / L_SUBFR) */ - L_tmp = Isqrt_lc( L_tmp, &exp_inov ); - *gain_inov = extract_h( L_shl( L_tmp, sub( exp_inov, 3 ) ) ); /* gain_inov in Q12 */ - /* gcode0 = pow(10, 0.05 * (Es_pred - Ei)) */ /*----------------------------------------------------------------* * gcode0 = pow(10.0, gcode0/20) @@ -657,7 +654,7 @@ void gain_enc_mless_ivas_fx( * select the codebook, size and number of bits * set the gains searching range *-----------------------------------------------------------------*/ - nBits = gains_mode[shr( i_subfr, 6 )]; + nBits = gains_mode[i_subfr >> 6]; move16(); test(); @@ -696,9 +693,9 @@ void gain_enc_mless_ivas_fx( } L_frac_den = L_sub( L_tmp1, L_tmp2 ); /*Q31*/ - frac_den = extract_h( L_frac_den ); - frac_den = s_max( frac_den, 1 ); - L_frac_den = L_max( L_frac_den, 1 ); + frac_den = extract_h( L_frac_den ); /* Q15 */ + frac_den = s_max( frac_den, 1 ); /* Q15 */ + L_frac_den = L_max( L_frac_den, 1 ); /* Q31 */ exp = norm_l( L_frac_den ); tmp = div_s( shl( 1, sub( 14, exp ) ), frac_den ); /*Q(14-exp)*/ @@ -725,11 +722,7 @@ void gain_enc_mless_ivas_fx( L_div = Mult_32_16( L_frac_num, tmp ); /*Q(30-exp)*/ exp_div = sub( exp_num, exp_den ); -#ifdef BASOP_NOGLOB *gain_pit = round_fx_o( L_shl_o( L_div, add( exp, exp_div ), &Overflow ), &Overflow ); /*Q14*/ -#else - *gain_pit = round_fx( L_shl( L_div, add( exp, exp_div ) ) ); /*Q14*/ -#endif L_tmp1 = L_shr( L_mult( coeff[1], coeff[4] ), 2 ); /*Q31*/ exp1 = add( exp_coeff[1], exp_coeff[4] ); @@ -741,22 +734,20 @@ void gain_enc_mless_ivas_fx( { L_tmp2 = L_shr( L_tmp2, sub( exp1, exp2 ) ); /*Q31*/ exp_num = exp1; + move16(); } ELSE { L_tmp1 = L_shr( L_tmp1, sub( exp2, exp1 ) ); /*Q31*/ exp_num = exp2; + move16(); } L_frac_num = L_sub( L_tmp1, L_tmp2 ); /*Q31*/ L_div = Mult_32_16( L_frac_num, tmp ); /*Q(30-exp)*/ exp_div = sub( exp_num, exp_den ); -#ifdef BASOP_NOGLOB *gain_code = L_shl_o( L_div, sub( add( exp, exp_div ), 14 ), &Overflow ); -#else - *gain_code = L_shl( L_div, sub( add( exp, exp_div ), 14 ) ); -#endif move32(); /*Q16*/ *gain_pit = s_max( G_PITCH_MIN_TC192_Q14, s_min( *gain_pit, G_PITCH_MAX_TC192_Q14 ) ); @@ -779,16 +770,13 @@ void gain_enc_mless_ivas_fx( tmp = div_s( 16384, gcode0 ); /*Q15*/ L_tmp = Mult_32_16( *gain_code, tmp ); /*Q16*/ *gain_code = L_shr( L_tmp, add( 14, exp_gcode0 ) ); /*Q16*/ + move32(); } index = gain_quant_fx( gain_code, &gain_code16, LG10_G_CODE_MIN_TC192_Q14, LG10_G_CODE_MAX_TC192_Q13, nBits2, &expg ); push_indice( hBstr, IND_GAIN_CODE, index, nBits2 ); - L_tmp = L_mult( gain_code16, gcode0 ); /*Q0*Q0 -> Q1*/ -#ifdef BASOP_NOGLOB + L_tmp = L_mult( gain_code16, gcode0 ); /*Q0*Q0 -> Q1*/ *gain_code = L_shl_o( L_tmp, add( add( expg, exp_gcode0 ), 15 ), &Overflow ); /*Q16*/ -#else - *gain_code = L_shl( L_tmp, add( add( expg, exp_gcode0 ), 15 ) ); /*Q16*/ -#endif } ELSE { @@ -798,8 +786,7 @@ void gain_enc_mless_ivas_fx( { case 7: { - qua_table = gain_qua_mless_7b_fx; - move16(); + qua_table = gain_qua_mless_7b_fx; // Q14 if ( EQ_16( clip_gain, 1 ) ) { size = sub( size, 30 ); @@ -808,12 +795,11 @@ void gain_enc_mless_ivas_fx( } case 6: { - qua_table = gain_qua_mless_6b_fx; - if ( GT_16( element_mode, EVS_MONO ) ) + qua_table = gain_qua_mless_6b_fx; // Q14 + if ( element_mode > EVS_MONO ) { qua_table = gain_qua_mless_6b_stereo_fx; } - move16(); if ( EQ_16( clip_gain, 1 ) ) { size = sub( size, 14 ); @@ -822,8 +808,7 @@ void gain_enc_mless_ivas_fx( } case 5: { - qua_table = gain_qua_mless_5b_fx; - move16(); + qua_table = gain_qua_mless_5b_fx; // Q14 if ( EQ_16( clip_gain, 1 ) ) { size = sub( size, 6 ); @@ -832,8 +817,7 @@ void gain_enc_mless_ivas_fx( } default: { - qua_table = gain_qua_mless_6b_fx; - move16(); + qua_table = gain_qua_mless_6b_fx; // Q14 if ( EQ_16( clip_gain, 1 ) ) { size = sub( size, 14 ); @@ -862,7 +846,7 @@ void gain_enc_mless_ivas_fx( exp = s_max( exp, 0 ); tmp = div_s( shr( 8192, exp ), *gain_inov ); - *norm_gain_code = L_shr( Mult_32_16( *gain_code, tmp ), sub( 1, exp ) ); + *norm_gain_code = L_shr( Mult_32_16( *gain_code, tmp ), sub( 1, exp ) ); // Q16 move32(); return; @@ -880,21 +864,21 @@ void gain_enc_mless_ivas_fx( *---------------------------------------------------------------------*/ void gain_enc_SQ_fx( - BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ - const Word16 gains_mode[], /* i : gain bits */ - const Word16 i_subfr, /* i : subframe index */ - const Word16 *xn, /* i : target vector Q_xn */ - const Word16 *yy1, /* i : zero-memory filtered adaptive excitation Q_xn */ - const Word16 *y2, /* i : zero-memory filtered algebraic codebook excitation Q9 */ - const Word16 *code, /* i : algebraic excitation Q9 */ - const Word16 Es_pred, /* i : predicted scaled innovation energy Q8 */ - Word16 *gain_pit, /* o : quantized pitch gain Q14 */ - Word32 *gain_code, /* o : quantized codebook gain Q16 */ - Word16 *gain_inov, /* o : gain of the innovation (used for normalization) Q12 */ - Word32 *norm_gain_code, /* o : norm. gain of the codebook excitation Q16 */ - Word16 *g_corr, /* i/o: correlations , ,, -2 and 2 */ - const Word16 clip_gain, /* i : gain pitch clipping flag (1 = clipping) */ - const Word16 Q_xn /* i : xn and y1 scaling */ + BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ + const Word16 gains_mode[], /* i : gain bits Q0*/ + const Word16 i_subfr, /* i : subframe index Q0*/ + const Word16 *xn, /* i : target vector Q_xn*/ + const Word16 *yy1, /* i : zero-memory filtered adaptive excitation Q_xn*/ + const Word16 *y2, /* i : zero-memory filtered algebraic codebook excitation Q9*/ + const Word16 *code, /* i : algebraic excitation Q9*/ + const Word16 Es_pred, /* i : predicted scaled innovation energy Q8*/ + Word16 *gain_pit, /* o : quantized pitch gain Q14*/ + Word32 *gain_code, /* o : quantized codebook gain Q16*/ + Word16 *gain_inov, /* o : gain of the innovation (used for normalization) Q12*/ + Word32 *norm_gain_code, /* o : norm. gain of the codebook excitation Q16*/ + Word16 *g_corr, /* i/o: correlations , ,, -2 and 2 Qx*/ + const Word16 clip_gain, /* i : gain pitch clipping flag (1 = clipping) Q0*/ + const Word16 Q_xn /* i : xn and y1 scaling */ ) { Word16 index, nBits_pitch, nBits_code; @@ -909,6 +893,7 @@ void gain_enc_SQ_fx( Word32 L_frac_num, L_frac_den, L_div; #ifdef BASOP_NOGLOB_DECLARE_LOCAL Flag Overflow = 0; + move32(); #endif /*-----------------------------------------------------------------* @@ -931,16 +916,19 @@ void gain_enc_SQ_fx( /* Compute scalar product */ coeff[2] = extract_h( Dot_product12( y2, y2, L_SUBFR, &exp ) ); + move16(); exp_coeff[2] = add( sub( exp, 18 ), shl( Q_xn, 1 ) ); move16(); /* -18 (y2 Q9) */ /* Compute scalar product */ coeff[3] = extract_h( Dot_product12( xn, y2, L_SUBFR, &exp ) ); + move16(); exp_coeff[3] = add( sub( exp, 9 ), Q_xn ); move16(); /* -9 (y2 Q9), (xn y2) */ /* Compute scalar product */ coeff[4] = extract_h( Dot_product12( yy1, y2, L_SUBFR, &exp ) ); + move16(); exp_coeff[4] = add( sub( exp, 9 ), Q_xn ); move16(); /* -9 (y2 Q9), (y1 y2) */ @@ -1010,11 +998,7 @@ void gain_enc_SQ_fx( L_tmp1 = L_mult( coeff[0], coeff[2] ); /*Q31*/ exp1 = add( exp_coeff[0], exp_coeff[2] ); -#ifdef BASOP_NOGLOB L_tmp2 = L_mult_o( coeff[4], coeff[4], &Overflow ); /*Q31*/ -#else - L_tmp2 = L_mult( coeff[4], coeff[4] ); /*Q31*/ -#endif exp2 = add( exp_coeff[4], exp_coeff[4] ); IF( GT_16( exp1, exp2 ) ) @@ -1031,9 +1015,9 @@ void gain_enc_SQ_fx( } L_frac_den = L_sub( L_tmp1, L_tmp2 ); /*Q31*/ - frac_den = extract_h( L_frac_den ); - frac_den = s_max( frac_den, 1 ); - L_frac_den = L_max( L_frac_den, 1 ); + frac_den = extract_h( L_frac_den ); /* Q15 */ + frac_den = s_max( frac_den, 1 ); /* Q15 */ + L_frac_den = L_max( L_frac_den, 1 ); /* Q31 */ exp = norm_l( L_frac_den ); tmp = div_s( shl( 1, sub( 14, exp ) ), frac_den ); /*Q(14-exp)*/ @@ -1056,20 +1040,12 @@ void gain_enc_SQ_fx( exp_num = exp2; move16(); } -#ifdef BASOP_NOGLOB L_frac_num = L_sub_o( L_tmp2, L_tmp1, &Overflow ); /*Q31*/ -#else /* BASOP_NOGLOB */ - L_frac_num = L_sub( L_tmp2, L_tmp1 ); /*Q31*/ -#endif /* BASOP_NOGLOB */ L_div = Mult_32_16( L_frac_num, tmp ); /*Q(30-exp)*/ exp_div = sub( exp_num, exp_den ); -#ifdef BASOP_NOGLOB *gain_pit = round_fx_o( L_shl_o( L_div, add( exp, exp_div ), &Overflow ), &Overflow ); /*Q14*/ -#else /* BASOP_NOGLOB */ - *gain_pit = round_fx( L_shl( L_div, add( exp, exp_div ) ) ); /*Q14*/ -#endif /* BASOP_NOGLOB */ L_tmp1 = L_mult( coeff[1], coeff[4] ); /*Q31*/ exp1 = add( exp_coeff[1], exp_coeff[4] ); @@ -1081,26 +1057,20 @@ void gain_enc_SQ_fx( { L_tmp2 = L_shr( L_tmp2, sub( exp1, exp2 ) ); /*Q31*/ exp_num = exp1; + move16(); } ELSE { L_tmp1 = L_shr( L_tmp1, sub( exp2, exp1 ) ); /*Q31*/ exp_num = exp2; + move16(); } -#ifdef BASOP_NOGLOB L_frac_num = L_sub_o( L_tmp2, L_tmp1, &Overflow ); /*Q31*/ -#else /* BASOP_NOGLOB */ - L_frac_num = L_sub( L_tmp2, L_tmp1 ); /*Q31*/ -#endif /* BASOP_NOGLOB */ L_div = Mult_32_16( L_frac_num, tmp ); /*Q(30-exp)*/ exp_div = sub( exp_num, exp_den ); -#ifdef BASOP_NOGLOB *gain_code = L_shl_sat( L_div, s_max( -31, sub( add( exp, exp_div ), 14 ) ) ); -#else - *gain_code = L_shl( L_div, s_max( -31, sub( add( exp, exp_div ), 14 ) ) ); -#endif move32(); /*Q16*/ *gain_pit = s_max( G_PITCH_MIN_Q14, s_min( *gain_pit, G_PITCH_MAX_Q14 ) ); @@ -1111,14 +1081,14 @@ void gain_enc_SQ_fx( test(); test(); - IF( EQ_16( clip_gain, 1 ) && GT_16( *gain_pit, 15565 ) ) + IF( EQ_16( clip_gain, 1 ) && GT_16( *gain_pit, 15565 /* 0.95 in Q14 */ ) ) { - *gain_pit = 15565; + *gain_pit = 15565; /* 0.95 in Q14 */ move16(); } - ELSE IF( EQ_16( clip_gain, 2 ) && GT_16( *gain_pit, 10650 ) ) + ELSE IF( EQ_16( clip_gain, 2 ) && GT_16( *gain_pit, 10650 /* 0.65 in Q14 */ ) ) { - *gain_pit = 10650; + *gain_pit = 10650; /* 0.65 in Q14 */ move16(); } @@ -1126,7 +1096,8 @@ void gain_enc_SQ_fx( * search for the best quantized values *-----------------------------------------------------------------*/ - nBits_pitch = gains_mode[shr( i_subfr, 6 )]; + nBits_pitch = gains_mode[i_subfr >> 6]; + move16(); /* set number of bits for two SQs */ nBits_code = shr( add( nBits_pitch, 1 ), 1 ); @@ -1136,8 +1107,7 @@ void gain_enc_SQ_fx( /*tmp1 = (G_PITCH_MAX - G_PITCH_MIN) / ((1 << nBits_pitch) - 1);*/ /* set quantization step */ tmp1 = mult_r( G_PITCH_MAX_Q13, div_s( 1, sub( shl( 1, nBits_pitch ), 1 ) ) ); /*Q13*/ /* set quantization step */ - index = usquant_fx( *gain_pit, gain_pit, G_PITCH_MIN_Q14, tmp1, shl( 1, nBits_pitch ) ); - move16(); + index = usquant_fx( *gain_pit, gain_pit, G_PITCH_MIN_Q14, tmp1, shl( 1, nBits_pitch ) ); // Q0 push_indice_fx( hBstr, IND_GAIN_PIT, index, nBits_pitch ); /* gain_code Q */ @@ -1147,16 +1117,13 @@ void gain_enc_SQ_fx( tmp = div_s( 16384, gcode0 ); /*Q15*/ L_tmp = Mult_32_16( *gain_code, tmp ); /*Q16*/ *gain_code = L_shr( L_tmp, add( 14, exp_gcode0 ) ); /*Q16*/ + move32(); } index = gain_quant_fx( gain_code, &gain_code16, LG10_G_CODE_MIN_Q14, LG10_G_CODE_MAX_Q13, nBits_code, &expg ); push_indice_fx( hBstr, IND_GAIN_CODE, index, nBits_code ); L_tmp = L_mult( gain_code16, gcode0 ); /*Q0*Q0 -> Q1*/ -#ifdef BASOP_NOGLOB *gain_code = L_shl_sat( L_tmp, add( add( expg, exp_gcode0 ), 15 ) ); -#else - *gain_code = L_shl( L_tmp, add( add( expg, exp_gcode0 ), 15 ) ); -#endif move32(); /*Q16*/ /* *norm_gain_code = *gain_code / *gain_inov; */ @@ -1164,28 +1131,28 @@ void gain_enc_SQ_fx( exp = s_max( exp, 0 ); tmp = div_s( shr( 8192, exp ), *gain_inov ); - *norm_gain_code = L_shr( Mult_32_16( *gain_code, tmp ), sub( 1, exp ) ); + *norm_gain_code = L_shr( Mult_32_16( *gain_code, tmp ), sub( 1, exp ) ); // Q16 move32(); return; } void gain_enc_SQ_ivas_fx( - BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ - const Word16 gains_mode[], /* i : gain bits */ - const Word16 i_subfr, /* i : subframe index */ - const Word16 *xn, /* i : target vector Q_xn */ - const Word16 *yy1, /* i : zero-memory filtered adaptive excitation Q_xn */ - const Word16 *y2, /* i : zero-memory filtered algebraic codebook excitation Q9 */ - const Word16 *code, /* i : algebraic excitation Q9 */ - const Word16 Es_pred, /* i : predicted scaled innovation energy Q8 */ - Word16 *gain_pit, /* o : quantized pitch gain Q14 */ - Word32 *gain_code, /* o : quantized codebook gain Q16 */ - Word16 *gain_inov, /* o : gain of the innovation (used for normalization) Q12 */ - Word32 *norm_gain_code, /* o : norm. gain of the codebook excitation Q16 */ - Word16 *g_corr, /* i/o: correlations , ,, -2 and 2 */ - const Word16 clip_gain, /* i : gain pitch clipping flag (1 = clipping) */ - const Word16 Q_xn /* i : xn and y1 scaling */ + BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ + const Word16 gains_mode[], /* i : gain bits Q0*/ + const Word16 i_subfr, /* i : subframe index Q0*/ + const Word16 *xn, /* i : target vector Q_xn*/ + const Word16 *yy1, /* i : zero-memory filtered adaptive excitation Q_xn*/ + const Word16 *y2, /* i : zero-memory filtered algebraic codebook excitation Q9*/ + const Word16 *code, /* i : algebraic excitation Q9*/ + const Word16 Es_pred, /* i : predicted scaled innovation energy Q8*/ + Word16 *gain_pit, /* o : quantized pitch gain Q14*/ + Word32 *gain_code, /* o : quantized codebook gain Q16*/ + Word16 *gain_inov, /* o : gain of the innovation (used for normalization) Q12*/ + Word32 *norm_gain_code, /* o : norm. gain of the codebook excitation Q16*/ + Word16 *g_corr, /* i/o: correlations , ,, -2 and 2 Qx*/ + const Word16 clip_gain, /* i : gain pitch clipping flag (1 = clipping) Q0*/ + const Word16 Q_xn /* i : xn and y1 scaling */ ) { Word16 index, nBits_pitch, nBits_code; @@ -1200,6 +1167,7 @@ void gain_enc_SQ_ivas_fx( Word32 L_frac_num, L_frac_den, L_div; #ifdef BASOP_NOGLOB_DECLARE_LOCAL Flag Overflow = 0; + move32(); #endif /*-----------------------------------------------------------------* @@ -1222,16 +1190,19 @@ void gain_enc_SQ_ivas_fx( /* Compute scalar product */ coeff[2] = extract_h( Dot_product12( y2, y2, L_SUBFR, &exp ) ); + move16(); exp_coeff[2] = add( sub( exp, 18 ), shl( Q_xn, 1 ) ); move16(); /* -18 (y2 Q9) */ /* Compute scalar product */ coeff[3] = extract_h( Dot_product12( xn, y2, L_SUBFR, &exp ) ); + move16(); exp_coeff[3] = add( sub( exp, 9 ), Q_xn ); move16(); /* -9 (y2 Q9), (xn y2) */ /* Compute scalar product */ coeff[4] = extract_h( Dot_product12( yy1, y2, L_SUBFR, &exp ) ); + move16(); exp_coeff[4] = add( sub( exp, 9 ), Q_xn ); move16(); /* -9 (y2 Q9), (y1 y2) */ @@ -1301,11 +1272,7 @@ void gain_enc_SQ_ivas_fx( L_tmp1 = L_mult( coeff[0], coeff[2] ); /*Q31*/ exp1 = add( exp_coeff[0], exp_coeff[2] ); -#ifdef BASOP_NOGLOB L_tmp2 = L_mult_o( coeff[4], coeff[4], &Overflow ); /*Q31*/ -#else - L_tmp2 = L_mult( coeff[4], coeff[4] ); /*Q31*/ -#endif exp2 = add( exp_coeff[4], exp_coeff[4] ); IF( GT_16( exp1, exp2 ) ) @@ -1322,9 +1289,9 @@ void gain_enc_SQ_ivas_fx( } L_frac_den = L_sub( L_tmp1, L_tmp2 ); /*Q31*/ - frac_den = extract_h( L_frac_den ); - frac_den = s_max( frac_den, 1 ); - L_frac_den = L_max( L_frac_den, 1 ); + frac_den = extract_h( L_frac_den ); /* Q15 */ + frac_den = s_max( frac_den, 1 ); /* Q15 */ + L_frac_den = L_max( L_frac_den, 1 ); /* Q31 */ exp = norm_l( L_frac_den ); tmp = div_s( shl( 1, sub( 14, exp ) ), frac_den ); /*Q(14-exp)*/ @@ -1347,27 +1314,16 @@ void gain_enc_SQ_ivas_fx( exp_num = exp2; move16(); } -#ifdef BASOP_NOGLOB L_frac_num = L_sub_o( L_tmp2, L_tmp1, &Overflow ); /*Q31*/ -#else /* BASOP_NOGLOB */ - L_frac_num = L_sub( L_tmp2, L_tmp1 ); /*Q31*/ -#endif /* BASOP_NOGLOB */ L_div = Mult_32_16( L_frac_num, tmp ); /*Q(30-exp)*/ exp_div = sub( exp_num, exp_den ); -#ifdef BASOP_NOGLOB *gain_pit = round_fx_o( L_shl_o( L_div, add( exp, exp_div ), &Overflow ), &Overflow ); /*Q14*/ -#else /* BASOP_NOGLOB */ - *gain_pit = round_fx( L_shl( L_div, add( exp, exp_div ) ) ); /*Q14*/ -#endif /* BASOP_NOGLOB */ + move16(); // To be checked -#ifdef BASOP_NOGLOB L_tmp1 = L_mult_o( coeff[1], coeff[4], &Overflow ); /*Q31*/ -#else /* BASOP_NOGLOB */ - L_tmp1 = L_mult( coeff[1], coeff[4] ); /*Q31*/ -#endif /* BASOP_NOGLOB */ exp1 = add( exp_coeff[1], exp_coeff[4] ); L_tmp2 = L_mult( coeff[0], coeff[3] ); /*Q31*/ @@ -1377,26 +1333,20 @@ void gain_enc_SQ_ivas_fx( { L_tmp2 = L_shr( L_tmp2, sub( exp1, exp2 ) ); /*Q31*/ exp_num = exp1; + move16(); } ELSE { L_tmp1 = L_shr( L_tmp1, sub( exp2, exp1 ) ); /*Q31*/ exp_num = exp2; + move16(); } -#ifdef BASOP_NOGLOB L_frac_num = L_sub_o( L_tmp2, L_tmp1, &Overflow ); /*Q31*/ -#else /* BASOP_NOGLOB */ - L_frac_num = L_sub( L_tmp2, L_tmp1 ); /*Q31*/ -#endif /* BASOP_NOGLOB */ L_div = Mult_32_16( L_frac_num, tmp ); /*Q(30-exp)*/ exp_div = sub( exp_num, exp_den ); -#ifdef BASOP_NOGLOB *gain_code = L_shl_sat( L_div, s_max( -31, sub( add( exp, exp_div ), 14 ) ) ); -#else - *gain_code = L_shl( L_div, s_max( -31, sub( add( exp, exp_div ), 14 ) ) ); -#endif move32(); /*Q16*/ *gain_pit = s_max( G_PITCH_MIN_Q14, s_min( *gain_pit, G_PITCH_MAX_Q14 ) ); @@ -1407,14 +1357,14 @@ void gain_enc_SQ_ivas_fx( test(); test(); - IF( EQ_16( clip_gain, 1 ) && GT_16( *gain_pit, 15565 ) ) + IF( EQ_16( clip_gain, 1 ) && GT_16( *gain_pit, 15565 /* 0.95 in Q14 */ ) ) { - *gain_pit = 15565; + *gain_pit = 15565; /* 0.95 in Q14 */ move16(); } - ELSE IF( EQ_16( clip_gain, 2 ) && GT_16( *gain_pit, 10650 ) ) + ELSE IF( EQ_16( clip_gain, 2 ) && GT_16( *gain_pit, 10650 /* 0.65 in Q14 */ ) ) { - *gain_pit = 10650; + *gain_pit = 10650; /* 0.65 in Q14 */ move16(); } @@ -1422,7 +1372,8 @@ void gain_enc_SQ_ivas_fx( * search for the best quantized values *-----------------------------------------------------------------*/ - nBits_pitch = gains_mode[shr( i_subfr, 6 )]; + nBits_pitch = gains_mode[i_subfr >> 6]; + move16(); /* set number of bits for two SQs */ nBits_code = shr( add( nBits_pitch, 1 ), 1 ); @@ -1433,7 +1384,6 @@ void gain_enc_SQ_ivas_fx( tmp1 = mult_r( G_PITCH_MAX_Q13, div_s( 1, sub( shl( 1, nBits_pitch ), 1 ) ) ); /*Q13*/ /* set quantization step */ index = usquant_fx( *gain_pit, gain_pit, G_PITCH_MIN_Q14, tmp1, shl( 1, nBits_pitch ) ); - move16(); push_indice( hBstr, IND_GAIN_PIT, index, nBits_pitch ); /* gain_code Q */ @@ -1443,16 +1393,13 @@ void gain_enc_SQ_ivas_fx( tmp = div_s( 16384, gcode0 ); /*Q15*/ L_tmp = Mult_32_16( *gain_code, tmp ); /*Q16*/ *gain_code = L_shr( L_tmp, add( 14, exp_gcode0 ) ); /*Q16*/ + move32(); } index = gain_quant_fx( gain_code, &gain_code16, LG10_G_CODE_MIN_Q14, LG10_G_CODE_MAX_Q13, nBits_code, &expg ); push_indice( hBstr, IND_GAIN_CODE, index, nBits_code ); L_tmp = L_mult( gain_code16, gcode0 ); /*Q0*Q0 -> Q1*/ -#ifdef BASOP_NOGLOB *gain_code = L_shl_sat( L_tmp, add( add( expg, exp_gcode0 ), 15 ) ); -#else - *gain_code = L_shl( L_tmp, add( add( expg, exp_gcode0 ), 15 ) ); -#endif move32(); /*Q16*/ /* *norm_gain_code = *gain_code / *gain_inov; */ @@ -1460,7 +1407,7 @@ void gain_enc_SQ_ivas_fx( exp = s_max( exp, 0 ); tmp = div_s( shr( 8192, exp ), *gain_inov ); - *norm_gain_code = L_shr( Mult_32_16( *gain_code, tmp ), sub( 1, exp ) ); + *norm_gain_code = L_shr( Mult_32_16( *gain_code, tmp ), sub( 1, exp ) ); // Q16 move32(); return; @@ -1471,12 +1418,12 @@ void gain_enc_SQ_ivas_fx( * * Quantization of gain for Gaussian codebook *-------------------------------------------------------------------*/ -Word16 gain_enc_gaus_fx( /* o : Return index of quantization */ - Word32 *gain, /* i/o: Code gain to quantize */ - const Word16 bits, /* i : number of bits to quantize */ - const Word16 lowBound, /* i : lower bound of quantizer (dB) Q8 */ - const Word16 stepSize, /* i : Step size choice Q14 */ - const Word16 inv_stepSize /* i : Step size choice Q15 */ +Word16 gain_enc_gaus_fx( /* o : Return index of quantization */ + Word32 *gain, /* i/o: Code gain to quantize Q16*/ + const Word16 bits, /* i : number of bits to quantize Q0*/ + const Word16 lowBound, /* i : lower bound of quantizer (dB) Q8*/ + const Word16 stepSize, /* i : Step size choice Q14*/ + const Word16 inv_stepSize /* i : Step size choice Q15*/ ) { Word16 index, exp_gain, frac_gain, wtmp; @@ -1484,6 +1431,7 @@ Word16 gain_enc_gaus_fx( /* o : Return index of quant Word32 Ltmp, enr; #ifdef BASOP_NOGLOB_DECLARE_LOCAL Flag Overflow = 0; + move32(); #endif /*enr = 20.0 * log10(*gain + 0.001) codebook gain in dB */ exp_gain = norm_l( *gain ); @@ -1499,10 +1447,10 @@ Word16 gain_enc_gaus_fx( /* o : Return index of quant wtmp = sub( wenr, lowBound ); /* Q8 */ - index = extract_l( L_shr( L_mac( 8388608, wtmp, inv_stepSize ), 16 + 8 ) ); + index = extract_l( L_shr( L_mac( 8388608, wtmp, inv_stepSize ), 16 + 8 ) ); // Q0 /* index [0 (1< Q14 */ -#ifdef BASOP_NOGLOB *gain_code_fx = L_shl_sat( L_tmp, add( exp_gcode0, 2 ) ); -#else - *gain_code_fx = L_shl( L_tmp, add( exp_gcode0, 2 ) ); -#endif move32(); /* Q14 -> Q16 */ push_indice_fx( hBstr, IND_GAIN_CODE, index, nBits ); } @@ -1714,24 +1654,24 @@ void gain_enc_tc_fx( expg = s_max( expg, 0 ); tmp_fx = div_s( shr( 8192, expg ), *gain_inov_fx ); - *norm_gain_code_fx = L_shr( Mult_32_16( *gain_code_fx, tmp_fx ), sub( 1, expg ) ); + *norm_gain_code_fx = L_shr( Mult_32_16( *gain_code_fx, tmp_fx ), sub( 1, expg ) ); // Q16 move32(); return; } void gain_enc_tc_ivas_fx( - BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ - const Word16 gains_mode[], /* i : gain bits */ - const Word16 i_subfr, /* i : subframe index */ - const Word16 xn_fx[], /* i : target vector */ - const Word16 y2_fx[], /* i : zero-memory filtered algebraic codebook excitation */ - const Word16 code_fx[], /* i : algebraic excitation */ - const Word16 Es_pred_fx, /* i : predicted scaled innovation energy */ - Word16 *gain_pit_fx, /* o : Pitch gain / Quantized pitch gain */ - Word32 *gain_code_fx, /* o : quantized codebook gain */ - Word16 *gain_inov_fx, /* o : innovation gain */ - Word32 *norm_gain_code_fx, /* o : norm. gain of the codebook excitation */ - const Word16 Q_xn /* i : xn and y1 scaling Q0 */ + BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ + const Word16 gains_mode[], /* i : gain bits Q0*/ + const Word16 i_subfr, /* i : subframe index Q0*/ + const Word16 xn_fx[], /* i : target vector Q_xn*/ + const Word16 y2_fx[], /* i : zero-memory filtered algebraic codebook excitation Q_xn*/ + const Word16 code_fx[], /* i : algebraic excitation Q9*/ + const Word16 Es_pred_fx, /* i : predicted scaled innovation energy Q8*/ + Word16 *gain_pit_fx, /* o : Pitch gain / Quantized pitch gain Q14*/ + Word32 *gain_code_fx, /* o : quantized codebook gain Q16*/ + Word16 *gain_inov_fx, /* o : innovation gain Q12*/ + Word32 *norm_gain_code_fx, /* o : norm. gain of the codebook excitation Q6*/ + const Word16 Q_xn /* i : xn and y1 scaling */ ) { Word16 i, index = 0, nBits, num, den, exp_num, exp_den; @@ -1741,10 +1681,14 @@ void gain_enc_tc_ivas_fx( Word16 wgain_code = 0, gain_code16; *gain_pit_fx = 0; move16(); + move16(); + move16(); + /*----------------------------------------------------------------* * get number of bits for gain quantization *----------------------------------------------------------------*/ - nBits = gains_mode[shr( i_subfr, 6 )]; + nBits = gains_mode[i_subfr >> 6]; // Q0 + move16(); /*----------------------------------------------------------------* * find the code pitch (for current subframe) @@ -1771,13 +1715,9 @@ void gain_enc_tc_ivas_fx( *----------------------------------------------------------------*/ g_code_fx = div_s( num, den ); - i = sub( exp_num, exp_den ); /* Gain_trans in Q7 */ - g_code_fx = i_mult2( g_code_fx, tmp16 ); /* apply sign */ -#ifdef BASOP_NOGLOB - *gain_code_fx = L_shr_sat( L_deposit_l( g_code_fx ), i ); -#else - *gain_code_fx = L_shr( L_deposit_l( g_code_fx ), i ); -#endif + i = sub( exp_num, exp_den ); /* Gain_trans in Q7 */ + g_code_fx = i_mult2( g_code_fx, tmp16 ); /* apply sign */ + *gain_code_fx = L_shr_sat( L_deposit_l( g_code_fx ), i ); /* Q16 */ move32(); /*----------------------------------------------------------------* @@ -1828,6 +1768,7 @@ void gain_enc_tc_ivas_fx( tmp16 = div_s( 16384, gcode0_fx ); /*Q15*/ L_tmp = Mult_32_16( *gain_code_fx, tmp16 ); /*Q16*/ *gain_code_fx = L_shr( L_tmp, add( 14, exp_gcode0 ) ); /*Q16*/ + move32(); } ELSE { @@ -1868,7 +1809,7 @@ void gain_enc_tc_ivas_fx( { /* 2-bit -> 3-bit decoding */ index = shr( index, 1 ); - wgain_code = tbl_gain_code_tc_fx[shl( index, 1 )]; + wgain_code = tbl_gain_code_tc_fx[index * 2]; // Q13 move16(); /**gain_code *= gcode0;*/ L_tmp = L_mult( wgain_code, gcode0_fx ); /* Q13*Q0 -> Q14 */ @@ -1878,15 +1819,11 @@ void gain_enc_tc_ivas_fx( } ELSE /* nBits == 3 */ { - wgain_code = tbl_gain_code_tc_fx[index]; + wgain_code = tbl_gain_code_tc_fx[index]; // Q13 move16(); /**gain_code *= gcode0;*/ L_tmp = L_mult( wgain_code, gcode0_fx ); /* Q13*Q0 -> Q14 */ -#ifdef BASOP_NOGLOB *gain_code_fx = L_shl_sat( L_tmp, add( exp_gcode0, 2 ) ); -#else - *gain_code_fx = L_shl( L_tmp, add( exp_gcode0, 2 ) ); -#endif move32(); /* Q14 -> Q16 */ push_indice( hBstr, IND_GAIN_CODE, index, nBits ); } @@ -1900,7 +1837,7 @@ void gain_enc_tc_ivas_fx( expg = s_max( expg, 0 ); tmp_fx = div_s( shr( 8192, expg ), *gain_inov_fx ); - *norm_gain_code_fx = L_shr( Mult_32_16( *gain_code_fx, tmp_fx ), sub( 1, expg ) ); + *norm_gain_code_fx = L_shr( Mult_32_16( *gain_code_fx, tmp_fx ), sub( 1, expg ) ); // Q6 move32(); return; } @@ -1910,14 +1847,14 @@ void gain_enc_tc_ivas_fx( * Find the best quantizer *-----------------------------------------------------------------*/ static Word16 Find_Opt_gainQ_fx( - Word16 *coeff, + Word16 *coeff, /* exp(exp_coeff) */ Word16 *exp_coeff, - Word16 *gain_pit, - Word32 *gain_code, - Word16 gcode0, + Word16 *gain_pit, /* Q14 */ + Word32 *gain_code, /* Q16 */ + Word16 gcode0, /* exp(exp_gcode0) */ Word16 exp_gcode0, - const Word16 *cdbk, /* i : Codebook used */ - const Word16 size /* i : size of Codebook used */ + const Word16 *cdbk, /* i : Codebook used Q14*/ + const Word16 size /* i : size of Codebook used Q0*/ ) { Word16 index, i, j; @@ -1930,6 +1867,7 @@ static Word16 Find_Opt_gainQ_fx( Word32 L_tmp, L_tmp1; #ifdef BASOP_NOGLOB_DECLARE_LOCAL Flag Overflow = 0; + move32(); #endif @@ -1993,7 +1931,7 @@ static Word16 Find_Opt_gainQ_fx( } /* searching of codebook */ - p = cdbk; + p = cdbk; // Q14 move16(); dist_min = L_deposit_h( MAX_16 ); index = 0; @@ -2005,8 +1943,8 @@ static Word16 Find_Opt_gainQ_fx( g_code = *p++; move16(); - g_code = mult_r( g_code, gcode0 ); - g2_pitch = mult_r( g_pitch, g_pitch ); + g_code = mult_r( g_code, gcode0 ); // exp_gcode - 1 + g2_pitch = mult_r( g_pitch, g_pitch ); // Q13 g_pit_cod = mult_r( g_code, g_pitch ); L_tmp = L_mult( g_code, g_code ); g2_code_lo = L_Extract_lc( L_tmp, &g2_code ); @@ -2019,17 +1957,13 @@ static Word16 Find_Opt_gainQ_fx( L_tmp = L_mac( L_tmp, coeff_lo[3], g_code ); L_tmp = L_mac( L_tmp, coeff_lo[4], g_pit_cod ); L_tmp = L_shr( L_tmp, 12 ); - L_tmp = L_mac( L_tmp, coeff[0], g2_pitch ); - L_tmp = L_mac( L_tmp, coeff[1], g_pitch ); - L_tmp = L_mac( L_tmp, coeff[2], g2_code ); - L_tmp = L_mac( L_tmp, coeff[3], g_code ); - L_tmp = L_mac( L_tmp, coeff[4], g_pit_cod ); + L_tmp = L_mac( L_tmp, coeff[0], g2_pitch ); /* 15 - coeff_exp + 13 - 1 */ + L_tmp = L_mac( L_tmp, coeff[1], g_pitch ); /* 15 - coeff_exp + 13 - 1 */ + L_tmp = L_mac( L_tmp, coeff[2], g2_code ); /* 15 - coeff_exp + 13 - 1 */ + L_tmp = L_mac( L_tmp, coeff[3], g_code ); /* 15 - coeff_exp + 13 - 1 */ + L_tmp = L_mac( L_tmp, coeff[4], g_pit_cod ); /* 15 - coeff_exp + 13 - 1 */ -#ifdef BASOP_NOGLOB L_tmp1 = L_sub_o( L_tmp, dist_min, &Overflow ); -#else /* BASOP_NOGLOB */ - L_tmp1 = L_sub( L_tmp, dist_min ); -#endif /* BASOP_NOGLOB */ if ( L_tmp1 < 0 ) { index = i; @@ -2038,7 +1972,7 @@ static Word16 Find_Opt_gainQ_fx( dist_min = L_min( L_tmp, dist_min ); } - p = &cdbk[add( index, index )]; + p = &cdbk[add( index, index )]; // Q14 move16(); *gain_pit = *p++; /* selected pitch gain in Q14 */ @@ -2046,13 +1980,9 @@ static Word16 Find_Opt_gainQ_fx( g_code = *p++; /* selected code gain in Q9 */ move16(); - L_tmp = L_mult( g_code, gcode0 ); /* Q9*Q0 -> Q10 */ -#ifdef BASOP_NOGLOB + L_tmp = L_mult( g_code, gcode0 ); /* Q9*Q0 -> Q10 */ L_tmp = L_shl_sat( L_tmp, add( exp_gcode0, 6 ) ); /* Q10 -> Q16 */ -#else - L_tmp = L_shl( L_tmp, add( exp_gcode0, 6 ) ); /* Q10 -> Q16 */ -#endif - *gain_code = L_tmp; /* gain of code in Q16 */ + *gain_code = L_tmp; /* gain of code in Q16 */ move16(); return index; } @@ -2070,10 +2000,10 @@ static Word16 Find_Opt_gainQ_fx( *---------------------------------------------------------------------*/ void gain_enc_lbr_fx( - BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ - const Word16 gains_mode[], /* i : gain bits */ - const Word16 coder_type, /* i : coding type */ - const Word16 i_subfr, /* i : subframe index */ + BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ + const Word16 gains_mode[], /* i : gain bits Q0*/ + const Word16 coder_type, /* i : coding type Q0*/ + const Word16 i_subfr, /* i : subframe index Q0*/ const Word16 *xn, /* i : target vector Q_xn*/ const Word16 *y1, /* i : zero-memory filtered adaptive excitation Q_xn*/ const Word16 Q_xn, /* i : xn and y1 format */ @@ -2084,10 +2014,10 @@ void gain_enc_lbr_fx( Word16 *gain_inov, /* o : gain of the innovation (used for normalization) Q12*/ Word32 *norm_gain_code, /* o : norm. gain of the codebook excitation Q16*/ Word16 *g_corr, /* i/o: correlations , -2,, -2 and 2 mant/exp*/ - Word32 gc_mem[], /* i/o: gain_code from previous subframes */ - Word16 gp_mem[], /* i/o: gain_pitch from previous subframes */ - const Word16 clip_gain, /* i : gain pitch clipping flag (1 = clipping) */ - const int16_t L_subfr /* i : subframe length */ + Word32 gc_mem[], /* i/o: gain_code from previous subframes Q16*/ + Word16 gp_mem[], /* i/o: gain_pitch from previous subframes Q14*/ + const Word16 clip_gain, /* i : gain pitch clipping flag (1 = clipping) Q0*/ + const Word16 L_subfr /* i : subframe length Q0*/ ) { @@ -2097,6 +2027,8 @@ void gain_enc_lbr_fx( Word16 coeff[5], exp_coeff[5]; Word16 exp, exp_code, exp_inov, exp_gcode0, frac, tmp, L_subfr_sf; Word32 L_tmp, L_tmp1, L_inov; + move16(); + move16(); L_subfr_sf = 6; move16(); @@ -2121,25 +2053,22 @@ void gain_enc_lbr_fx( move16(); /* Compute scalar product */ -#ifdef DEBUG - if ( L_subfr != L_SUBFR ) - { - PMT( "Entire function needs review to accommode for L_subfr > L_SUBFR" ); - } -#endif coeff[2] = extract_h( Dot_product12( y2, y2, L_subfr, &exp ) ); + move16(); exp_coeff[2] = add( sub( exp, 18 ), shl( Q_xn, 1 ) ); /* -18 (y2 Q9) */ move16(); /* Compute scalar product -2* */ coeff[3] = extract_h( L_negate( Dot_product12( xn, y2, L_subfr, &exp ) ) ); + move16(); exp_coeff[3] = add( sub( exp, 9 - 1 ), Q_xn ); /* -9 (y2 Q9), +1 (2 xn y2) */ move16(); /* Compute scalar product 2* */ coeff[4] = extract_h( Dot_product12( y1, y2, L_subfr, &exp ) ); + move16(); exp_coeff[4] = add( sub( exp, 9 - 1 ), Q_xn ); /* -9 (y2 Q9), +1 (2 yy1 y2) */ move16(); @@ -2155,6 +2084,7 @@ void gain_enc_lbr_fx( exp_inov = sub( exp_code, add( 18, L_subfr_sf ) ); L_inov = Isqrt_lc( L_inov, &exp_inov ); *gain_inov = extract_h( L_shl( L_inov, sub( exp_inov, 3 ) ) ); /* gain_inov in Q12 */ + move16(); /*-----------------------------------------------------------------* @@ -2172,9 +2102,10 @@ void gain_enc_lbr_fx( * calculate prediction of gcode * search for the best codeword *-----------------------------------------------------------------*/ + test(); IF( i_subfr == 0 ) { - b = b_1sfr_fx; + b = b_1sfr_fx; // Q12 move16(); n_pred = 2; move16(); @@ -2183,43 +2114,38 @@ void gain_enc_lbr_fx( { case 8: { - cdbk = gp_gamma_1sfr_8b_fx; - move16(); + cdbk = gp_gamma_1sfr_8b_fx; /* Q14 / Q9 */ if ( EQ_16( clip_gain, 1 ) ) { size = sub( size, 60 ); } - move16(); BREAK; } case 7: { - cdbk = gp_gamma_1sfr_7b_fx; - move16(); + cdbk = gp_gamma_1sfr_7b_fx; /* Q14 / Q9 */ if ( EQ_16( clip_gain, 1 ) ) { size = sub( size, 27 ); } - move16(); BREAK; } case 6: { - cdbk = gp_gamma_1sfr_6b_fx; - move16(); + cdbk = gp_gamma_1sfr_6b_fx; /* Q14 / Q9 */ if ( EQ_16( clip_gain, 1 ) ) { size = sub( size, 10 ); } - move16(); BREAK; } } /* calculate predicted gain */ - aux[0] = 4096; + aux[0] = 4096; /* 1 in Q12 */ move16(); aux[1] = shl( ctype, 12 ); + move16(); /* gcode0 = (float)pow(10, dotp(b, aux, n_pred) - 0.5f * (float)log10(Ecode)); gcode0 = (float)pow(10, dotp(b, aux, n_pred) - 0.05f * 10 * (float)log10(Ecode)); @@ -2251,7 +2177,7 @@ void gain_enc_lbr_fx( /* output of Pow2() will be: */ /* 16384 < Pow2() <= 32767 */ exp_gcode0 = sub( exp_gcode0, 14 ); - index = Find_Opt_gainQ_fx( coeff, exp_coeff, gain_pit, gain_code, gcode0, exp_gcode0, cdbk, size ); + index = Find_Opt_gainQ_fx( coeff, exp_coeff, gain_pit, gain_code, gcode0, exp_gcode0, cdbk, size ); // Q0 gc_mem[0] = *gain_code; move16(); /*Q16*/ @@ -2269,30 +2195,26 @@ void gain_enc_lbr_fx( { case 7: { - cdbk = gp_gamma_2sfr_7b_fx; - move16(); + cdbk = gp_gamma_2sfr_7b_fx; /* Q14/Q9 */ if ( EQ_16( clip_gain, 1 ) ) { size = sub( size, 30 ); } - move16(); BREAK; } case 6: { - cdbk = gp_gamma_2sfr_6b_fx; - move16(); + cdbk = gp_gamma_2sfr_6b_fx; /* Q14/Q9 */ if ( EQ_16( clip_gain, 1 ) ) { size = sub( size, 12 ); } - move16(); BREAK; } } /* calculate predicted gain */ - aux[0] = 4096; + aux[0] = 4096; /* 1 in Q12 */ move16(); aux[1] = shl( ctype, 12 ); move16(); @@ -2305,6 +2227,7 @@ void gain_enc_lbr_fx( L_tmp1 = Mpy_32_16( exp, frac, 9864 ); move16(); /* Q16 */ aux[2] = round_fx( L_shl( L_tmp1, 12 ) ); /* Q12 */ + move16(); aux[3] = shr( gp_mem[0], 2 ); move16(); /*Q12*/ @@ -2323,41 +2246,36 @@ void gain_enc_lbr_fx( /* 16384 < Pow2() <= 32767 */ exp_gcode0 = sub( exp_gcode0, 14 ); - index = Find_Opt_gainQ_fx( coeff, exp_coeff, gain_pit, gain_code, gcode0, exp_gcode0, cdbk, size ); - gc_mem[1] = *gain_code; + index = Find_Opt_gainQ_fx( coeff, exp_coeff, gain_pit, gain_code, gcode0, exp_gcode0, cdbk, size ); // Q0 + gc_mem[1] = *gain_code; // Q16 move32(); - gp_mem[1] = *gain_pit; + gp_mem[1] = *gain_pit; // Q14 move16(); } ELSE IF( EQ_16( i_subfr, 2 * L_SUBFR ) ) { - b = b_3sfr_fx; + b = b_3sfr_fx; // Q12 move16(); n_pred = 6; move16(); IF( EQ_16( nBits, 7 ) ) { -#ifdef IVAS_CODE cdbk = gp_gamma_3sfr_7b_fx; if ( clip_gain == 1 ) { size -= 28; } -#else - // PMT("gp_gamma_3sfr_7b_fx is missing") -#endif } ELSE { - cdbk = gp_gamma_3sfr_6b_fx; - move16(); + cdbk = gp_gamma_3sfr_6b_fx; /* Q14 / Q9 */ if ( EQ_16( clip_gain, 1 ) ) { size = sub( size, 11 ); } } /* calculate predicted gain */ - aux[0] = 4096; + aux[0] = 4096; /* 1 in Q12 */ move16(); aux[1] = shl( ctype, 12 ); move16(); @@ -2369,6 +2287,7 @@ void gain_enc_lbr_fx( exp = sub( sub( 30, exp ), 16 ); /*Q_format(gc_mem[0])=16*/ L_tmp1 = Mpy_32_16( exp, frac, 9864 ); /* Q16 */ aux[2] = round_fx( L_shl( L_tmp1, 12 ) ); /* Q12 */ + move16(); /*aux[3] = (float)log10(gc_mem[1]); = log2(gc_mem[1])*log10(2);*/ @@ -2377,6 +2296,7 @@ void gain_enc_lbr_fx( exp = sub( sub( 30, exp ), 16 ); /*Q_format(gc_mem[1])=16*/ L_tmp1 = Mpy_32_16( exp, frac, 9864 ); /* Q16 */ aux[3] = round_fx( L_shl( L_tmp1, 12 ) ); /* Q12 */ + move16(); aux[4] = shr( gp_mem[0], 2 ); move16(); /*Q12*/ @@ -2426,41 +2346,35 @@ void gain_enc_lbr_fx( index = Find_Opt_gainQ_fx( coeff, exp_coeff, gain_pit, gain_code, gcode0, exp_gcode0, cdbk, size ); - gc_mem[2] = *gain_code; + gc_mem[2] = *gain_code; // Q16 move32(); - gp_mem[2] = *gain_pit; + gp_mem[2] = *gain_pit; // Q14 move16(); } ELSE IF( EQ_16( i_subfr, 3 * L_SUBFR ) ) { - b = b_4sfr_fx; + b = b_4sfr_fx; // Q12 move16(); n_pred = 8; move16(); IF( EQ_16( nBits, 7 ) ) { -#ifdef IVAS_CODE cdbk = gp_gamma_4sfr_7b_fx; if ( clip_gain == 1 ) { size -= 25; } -#else - // PMT("gp_gamma_4sfr_7b_fx is missing") -#endif } ELSE { - cdbk = gp_gamma_4sfr_6b_fx; - move16(); + cdbk = gp_gamma_4sfr_6b_fx; /* Q14 / Q9 */ if ( EQ_16( clip_gain, 1 ) ) { size = sub( size, 11 ); - move16(); } } /* calculate predicted gain */ - aux[0] = 4096; + aux[0] = 4096; /* 1 in Q12 */ move16(); aux[1] = shl( ctype, 12 ); move16(); @@ -2472,6 +2386,7 @@ void gain_enc_lbr_fx( exp = sub( sub( 30, exp ), 16 ); /*Q_format(gc_mem[0])=16*/ L_tmp1 = Mpy_32_16( exp, frac, 9864 ); /* Q16 */ aux[2] = round_fx( L_shl( L_tmp1, 12 ) ); /* Q12 */ + move16(); /*aux[3] = (float)log10(gc_mem[1]); = log2(gc_mem[1])*log10(2);*/ @@ -2480,6 +2395,7 @@ void gain_enc_lbr_fx( exp = sub( sub( 30, exp ), 16 ); /*Q_format(gc_mem[1])=16*/ L_tmp1 = Mpy_32_16( exp, frac, 9864 ); /* Q16 */ aux[3] = round_fx( L_shl( L_tmp1, 12 ) ); /* Q12 */ + move16(); /*aux[4] = (float)log10(gc_mem[2]); @@ -2489,6 +2405,7 @@ void gain_enc_lbr_fx( exp = sub( sub( 30, exp ), 16 ); /*Q_format(gc_mem[2])=16*/ L_tmp1 = Mpy_32_16( exp, frac, 9864 ); /* Q16 */ aux[4] = round_fx( L_shl( L_tmp1, 12 ) ); /* Q12 */ + move16(); aux[5] = shr( gp_mem[0], 2 ); move16(); /*Q12*/ @@ -2510,7 +2427,7 @@ void gain_enc_lbr_fx( /* 16384 < Pow2() <= 32767 */ exp_gcode0 = sub( exp_gcode0, 14 ); - index = Find_Opt_gainQ_fx( coeff, exp_coeff, gain_pit, gain_code, gcode0, exp_gcode0, cdbk, size ); + index = Find_Opt_gainQ_fx( coeff, exp_coeff, gain_pit, gain_code, gcode0, exp_gcode0, cdbk, size ); // Q0 } /* *norm_gain_code = *gain_code / *gain_inov; */ @@ -2518,7 +2435,7 @@ void gain_enc_lbr_fx( exp = s_max( exp, 0 ); tmp = div_s( shr( 8192, exp ), *gain_inov ); - *norm_gain_code = L_shr( Mult_32_16( *gain_code, tmp ), sub( 1, exp ) ); + *norm_gain_code = L_shr( Mult_32_16( *gain_code, tmp ), sub( 1, exp ) ); // Q16 move32(); { push_indice_fx( hBstr, IND_GAIN, index, nBits ); @@ -2527,10 +2444,10 @@ void gain_enc_lbr_fx( } void gain_enc_lbr_ivas_fx( - BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ - const Word16 gains_mode[], /* i : gain bits */ - const Word16 coder_type, /* i : coding type */ - const Word16 i_subfr, /* i : subframe index */ + BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ + const Word16 gains_mode[], /* i : gain bits Q0*/ + const Word16 coder_type, /* i : coding type Q0*/ + const Word16 i_subfr, /* i : subframe index Q0*/ const Word16 *xn, /* i : target vector Q_xn*/ const Word16 *y1, /* i : zero-memory filtered adaptive excitation Q_xn*/ const Word16 Q_xn, /* i : xn and y1 format */ @@ -2541,10 +2458,10 @@ void gain_enc_lbr_ivas_fx( Word16 *gain_inov, /* o : gain of the innovation (used for normalization) Q12*/ Word32 *norm_gain_code, /* o : norm. gain of the codebook excitation Q16*/ Word16 *g_corr, /* i/o: correlations , -2,, -2 and 2 mant/exp*/ - Word32 gc_mem[], /* i/o: gain_code from previous subframes Q16*/ - Word16 gp_mem[], /* i/o: gain_pitch from previous subframes Q14*/ - const Word16 clip_gain, /* i : gain pitch clipping flag (1 = clipping) */ - const int16_t L_subfr /* i : subframe length */ + Word32 gc_mem[], /* i/o: gain_code from previous subframes Q16*/ + Word16 gp_mem[], /* i/o: gain_pitch from previous subframes Q14*/ + const Word16 clip_gain, /* i : gain pitch clipping flag (1 = clipping) Q0*/ + const Word16 L_subfr /* i : subframe length Q0*/ ) { @@ -2554,6 +2471,7 @@ void gain_enc_lbr_ivas_fx( Word16 coeff[5], exp_coeff[5]; Word16 exp, exp_code, exp_inov, exp_gcode0, frac, tmp, L_subfr_sf; Word32 L_tmp, L_tmp1, L_inov; + move16(); L_subfr_sf = 6; move16(); @@ -2585,18 +2503,21 @@ void gain_enc_lbr_ivas_fx( } #endif coeff[2] = extract_h( Dot_product12( y2, y2, L_subfr, &exp ) ); + move16(); exp_coeff[2] = add( sub( exp, 18 ), shl( Q_xn, 1 ) ); /* -18 (y2 Q9) */ move16(); /* Compute scalar product -2* */ coeff[3] = extract_h( L_negate( Dot_product12( xn, y2, L_subfr, &exp ) ) ); + move16(); exp_coeff[3] = add( sub( exp, 9 - 1 ), Q_xn ); /* -9 (y2 Q9), +1 (2 xn y2) */ move16(); /* Compute scalar product 2* */ coeff[4] = extract_h( Dot_product12( y1, y2, L_subfr, &exp ) ); + move16(); exp_coeff[4] = add( sub( exp, 9 - 1 ), Q_xn ); /* -9 (y2 Q9), +1 (2 yy1 y2) */ move16(); @@ -2612,6 +2533,7 @@ void gain_enc_lbr_ivas_fx( exp_inov = sub( exp_code, add( 18, L_subfr_sf ) ); L_inov = Isqrt_lc( L_inov, &exp_inov ); *gain_inov = extract_h( L_shl_sat( L_inov, sub( exp_inov, 3 ) ) ); /* gain_inov in Q12 */ + move16(); /*-----------------------------------------------------------------* @@ -2629,9 +2551,10 @@ void gain_enc_lbr_ivas_fx( * calculate prediction of gcode * search for the best codeword *-----------------------------------------------------------------*/ + test(); IF( i_subfr == 0 ) { - b = b_1sfr_fx; + b = b_1sfr_fx; // Q12 move16(); n_pred = 2; move16(); @@ -2640,43 +2563,38 @@ void gain_enc_lbr_ivas_fx( { case 8: { - cdbk = gp_gamma_1sfr_8b_fx; - move16(); + cdbk = gp_gamma_1sfr_8b_fx; /* Q14 / Q9 */ if ( EQ_16( clip_gain, 1 ) ) { size = sub( size, 60 ); } - move16(); BREAK; } case 7: { - cdbk = gp_gamma_1sfr_7b_fx; - move16(); + cdbk = gp_gamma_1sfr_7b_fx; /* Q14 / Q9 */ if ( EQ_16( clip_gain, 1 ) ) { size = sub( size, 27 ); } - move16(); BREAK; } case 6: { - cdbk = gp_gamma_1sfr_6b_fx; - move16(); + cdbk = gp_gamma_1sfr_6b_fx; /* Q14 / Q9 */ if ( EQ_16( clip_gain, 1 ) ) { size = sub( size, 10 ); } - move16(); BREAK; } } /* calculate predicted gain */ - aux[0] = 4096; + aux[0] = 4096; /* 1 in Q12 */ move16(); aux[1] = shl( ctype, 12 ); + move16(); /* gcode0 = (float)pow(10, dotp(b, aux, n_pred) - 0.5f * (float)log10(Ecode)); gcode0 = (float)pow(10, dotp(b, aux, n_pred) - 0.05f * 10 * (float)log10(Ecode)); @@ -2717,7 +2635,7 @@ void gain_enc_lbr_ivas_fx( } ELSE IF( EQ_16( i_subfr, L_SUBFR ) || EQ_16( L_subfr, 2 * L_SUBFR ) ) { - b = b_2sfr_fx; + b = b_2sfr_fx; // Q12 move16(); n_pred = 4; move16(); @@ -2726,8 +2644,7 @@ void gain_enc_lbr_ivas_fx( { case 7: { - cdbk = gp_gamma_2sfr_7b_fx; - move16(); + cdbk = gp_gamma_2sfr_7b_fx; /* Q14 / Q9 */ if ( EQ_16( clip_gain, 1 ) ) { size = sub( size, 30 ); @@ -2736,8 +2653,7 @@ void gain_enc_lbr_ivas_fx( } case 6: { - cdbk = gp_gamma_2sfr_6b_fx; - move16(); + cdbk = gp_gamma_2sfr_6b_fx; /* Q14 / Q9 */ if ( EQ_16( clip_gain, 1 ) ) { size = sub( size, 12 ); @@ -2747,7 +2663,7 @@ void gain_enc_lbr_ivas_fx( } /* calculate predicted gain */ - aux[0] = 4096; + aux[0] = 4096; /* 1 in Q12 */ move16(); aux[1] = shl( ctype, 12 ); move16(); @@ -2778,21 +2694,21 @@ void gain_enc_lbr_ivas_fx( /* 16384 < Pow2() <= 32767 */ exp_gcode0 = sub( exp_gcode0, 14 ); - index = Find_Opt_gainQ_fx( coeff, exp_coeff, gain_pit, gain_code, gcode0, exp_gcode0, cdbk, size ); - gc_mem[1] = *gain_code; + index = Find_Opt_gainQ_fx( coeff, exp_coeff, gain_pit, gain_code, gcode0, exp_gcode0, cdbk, size ); // Q0 + gc_mem[1] = *gain_code; // Q16 move32(); - gp_mem[1] = *gain_pit; + gp_mem[1] = *gain_pit; // Q14 move16(); } ELSE IF( EQ_16( i_subfr, 2 * L_SUBFR ) ) { - b = b_3sfr_fx; + b = b_3sfr_fx; // Q12 move16(); n_pred = 6; move16(); IF( EQ_16( nBits, 7 ) ) { - cdbk = gp_gamma_3sfr_7b_fx; + cdbk = gp_gamma_3sfr_7b_fx; /* Q14 / Q9 */ if ( EQ_16( clip_gain, 1 ) ) { size = sub( size, 28 ); @@ -2800,15 +2716,14 @@ void gain_enc_lbr_ivas_fx( } ELSE { - cdbk = gp_gamma_3sfr_6b_fx; - move16(); + cdbk = gp_gamma_3sfr_6b_fx; /* Q14 / Q9 */ if ( EQ_16( clip_gain, 1 ) ) { size = sub( size, 11 ); } } /* calculate predicted gain */ - aux[0] = 4096; + aux[0] = 4096; // Q12 move16(); aux[1] = shl( ctype, 12 ); move16(); @@ -2820,6 +2735,7 @@ void gain_enc_lbr_ivas_fx( exp = sub( sub( 30, exp ), 16 ); /*Q_format(gc_mem[0])=16*/ L_tmp1 = Mpy_32_16( exp, frac, 9864 ); /* Q16 */ aux[2] = round_fx( L_shl( L_tmp1, 12 ) ); /* Q12 */ + move16(); /*aux[3] = (float)log10(gc_mem[1]); = log2(gc_mem[1])*log10(2);*/ @@ -2878,21 +2794,20 @@ void gain_enc_lbr_ivas_fx( index = Find_Opt_gainQ_fx( coeff, exp_coeff, gain_pit, gain_code, gcode0, exp_gcode0, cdbk, size ); - gc_mem[2] = *gain_code; + gc_mem[2] = *gain_code; /* Q16 */ move32(); - gp_mem[2] = *gain_pit; + gp_mem[2] = *gain_pit; /* Q14 */ move16(); } ELSE IF( EQ_16( i_subfr, 3 * L_SUBFR ) ) { - b = b_4sfr_fx; + b = b_4sfr_fx; /* Q12 */ move16(); n_pred = 8; move16(); IF( EQ_16( nBits, 7 ) ) { - cdbk = gp_gamma_4sfr_7b_fx; - move16(); + cdbk = gp_gamma_4sfr_7b_fx; /* Q14 / Q9 */ if ( EQ_16( clip_gain, 1 ) ) { size = sub( size, 25 ); @@ -2900,15 +2815,14 @@ void gain_enc_lbr_ivas_fx( } ELSE { - cdbk = gp_gamma_4sfr_6b_fx; - move16(); + cdbk = gp_gamma_4sfr_6b_fx; /* Q14 / Q9 */ if ( EQ_16( clip_gain, 1 ) ) { size = sub( size, 11 ); } } /* calculate predicted gain */ - aux[0] = 4096; + aux[0] = 4096; // Q12 move16(); aux[1] = shl( ctype, 12 ); move16(); @@ -2960,7 +2874,7 @@ void gain_enc_lbr_ivas_fx( /* 16384 < Pow2() <= 32767 */ exp_gcode0 = sub( exp_gcode0, 14 ); - index = Find_Opt_gainQ_fx( coeff, exp_coeff, gain_pit, gain_code, gcode0, exp_gcode0, cdbk, size ); + index = Find_Opt_gainQ_fx( coeff, exp_coeff, gain_pit, gain_code, gcode0, exp_gcode0, cdbk, size ); // Q0 } /* *norm_gain_code = *gain_code / *gain_inov; */ @@ -2968,7 +2882,7 @@ void gain_enc_lbr_ivas_fx( exp = s_max( exp, 0 ); tmp = div_s( shr( 8192, exp ), *gain_inov ); - *norm_gain_code = L_shr( Mult_32_16( *gain_code, tmp ), sub( 1, exp ) ); + *norm_gain_code = L_shr( Mult_32_16( *gain_code, tmp ), sub( 1, exp ) ); // Q16 move32(); { push_indice( hBstr, IND_GAIN, index, nBits ); @@ -2989,20 +2903,20 @@ void gain_enc_lbr_ivas_fx( void gain_enc_amr_wb_fx( - BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ - const Word16 *xn, /* i : target vector */ - const Word16 Q_xn, /* i : xn and yy1 format Q0 */ - const Word16 *yy1, /* i : zero-memory filtered adaptive excitation */ - const Word16 *y2, /* i : zero-memory filtered algebraic codebook excitation */ - const Word16 *code, /* i : algebraic excitation */ - const Word32 core_brate, /* i : core bitrate */ - Word16 *gain_pit, /* i/o: pitch gain / Quantized pitch gain */ - Word32 *gain_code, /* o : quantized codebook gain */ - Word16 *gain_inov, /* o : gain of the innovation (used for normalization) */ - Word32 *norm_gain_code, /* o : norm. gain of the codebook excitation */ - Word16 *g_coeff, /* i/o: correlations , -2,, -2 and 2 */ - const Word16 clip_gain, /* i : gain pitch clipping flag (1 = clipping) */ - Word16 *past_qua_en /* i/o: gain quantization memory (4 words) */ + BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ + const Word16 *xn, /* i : target vector Q_xn*/ + const Word16 Q_xn, /* i : xn and yy1 format */ + const Word16 *yy1, /* i : zero-memory filtered adaptive excitation Q_xn*/ + const Word16 *y2, /* i : zero-memory filtered algebraic codebook excitation Q9*/ + const Word16 *code, /* i : algebraic excitation Q9*/ + const Word32 core_brate, /* i : core bitrate Q0*/ + Word16 *gain_pit, /* i/o: pitch gain / Quantized pitch gain Q14*/ + Word32 *gain_code, /* o : quantized codebook gain Q16*/ + Word16 *gain_inov, /* o : gain of the innovation (used for normalization) Q12*/ + Word32 *norm_gain_code, /* o : norm. gain of the codebook excitation Q16*/ + Word16 *g_coeff, /* i/o: correlations , -2,, -2 and 2 Qx*/ + const Word16 clip_gain, /* i : gain pitch clipping flag (1 = clipping) Q0*/ + Word16 *past_qua_en /* i/o: gain quantization memory (4 words) Q10*/ ) { @@ -3015,15 +2929,16 @@ void gain_enc_amr_wb_fx( const Word16 *t_qua_gain, *p; #ifdef BASOP_NOGLOB_DECLARE_LOCAL Flag Overflow = 0; + move32(); #endif /*----------------------------------------------------------------* * Find the initial quantization pitch index * Set gains search range *----------------------------------------------------------------*/ - IF( core_brate >= ACELP_12k65 ) + IF( GE_32( core_brate, ACELP_12k65 ) ) { - t_qua_gain = t_qua_gain7b_fx; + t_qua_gain = t_qua_gain7b_fx; // Q14 move16(); /* pt at 1/4th of table */ p = t_qua_gain7b_fx + RANGE; @@ -3038,14 +2953,14 @@ void gain_enc_amr_wb_fx( } min_ind = 0; move16(); - g_pitch = *gain_pit; + g_pitch = *gain_pit; // Q14 move16(); FOR( i = 0; i < j; i++ ) { if ( GT_16( g_pitch, *p ) ) { - min_ind = add( min_ind, 1 ); + min_ind = add( min_ind, 1 ); // Q0 } p += 2; } @@ -3055,7 +2970,7 @@ void gain_enc_amr_wb_fx( } ELSE { - t_qua_gain = t_qua_gain6b_fx; + t_qua_gain = t_qua_gain6b_fx; // Q14 min_ind = 0; move16(); size = RANGE; @@ -3090,14 +3005,20 @@ void gain_enc_amr_wb_fx( /* Compute scalar product */ coeff[2] = extract_h( Dot_product12( y2, y2, L_SUBFR, &exp ) ); exp_coeff[2] = add( sub( exp, 18 ), shl( Q_xn, 1 ) ); /* -18 (y2 Q9) */ + move16(); + move16(); /* Compute scalar product -2* */ coeff[3] = extract_h( L_negate( Dot_product12( xn, y2, L_SUBFR, &exp ) ) ); exp_coeff[3] = add( sub( exp, 9 - 1 ), Q_xn ); /* -9 (y2 Q9), +1 (2 xn y2) */ + move16(); + move16(); /* Compute scalar product 2* */ coeff[4] = extract_h( Dot_product12( yy1, y2, L_SUBFR, &exp ) ); exp_coeff[4] = add( sub( exp, 9 - 1 ), Q_xn ); /* -9 (y2 Q9), +1 (2 yy1 y2) */ + move16(); + move16(); /*----------------------------------------------------------------* * Find energy of code and compute: @@ -3112,6 +3033,7 @@ void gain_enc_amr_wb_fx( exp_inov = sub( exp_code, 18 + 6 ); L_inov = Isqrt_lc( L_inov, &exp_inov ); *gain_inov = extract_h( L_shl( L_inov, sub( exp_inov, 3 ) ) ); /* gain_inov in Q12 */ + move16(); exp_code = sub( exp_code, 18 + 6 + 31 ); frac = Log2_lc( L_tmp, &exp ); @@ -3208,7 +3130,7 @@ void gain_enc_amr_wb_fx( /* Codebook search */ dist_min = L_add( MAX_32, 0 ); - p = &t_qua_gain[shl( min_ind, 1 )]; + p = &t_qua_gain[shl( min_ind, 1 )]; // Q14 move16(); index = 0; @@ -3220,8 +3142,8 @@ void gain_enc_amr_wb_fx( g_code = *p++; move16(); - g_code = mult_r( g_code, gcode0 ); - g2_pitch = mult_r( g_pitch, g_pitch ); + g_code = mult_r( g_code, gcode0 ); // exp(gcode) - 1 + g2_pitch = mult_r( g_pitch, g_pitch ); // Q13 g_pit_cod = mult_r( g_code, g_pitch ); L_tmp = L_mult( g_code, g_code ); L_Extract( L_tmp, &g2_code, &g2_code_lo ); @@ -3234,17 +3156,13 @@ void gain_enc_amr_wb_fx( L_tmp = L_mac( L_tmp, coeff_lo[3], g_code ); L_tmp = L_mac( L_tmp, coeff_lo[4], g_pit_cod ); L_tmp = L_shr( L_tmp, 12 ); - L_tmp = L_mac( L_tmp, coeff[0], g2_pitch ); - L_tmp = L_mac( L_tmp, coeff[1], g_pitch ); - L_tmp = L_mac( L_tmp, coeff[2], g2_code ); - L_tmp = L_mac( L_tmp, coeff[3], g_code ); - L_tmp = L_mac( L_tmp, coeff[4], g_pit_cod ); + L_tmp = L_mac( L_tmp, coeff[0], g2_pitch ); /* 15 - coeff_exp + 13 - 1 */ + L_tmp = L_mac( L_tmp, coeff[1], g_pitch ); /* 15 - coeff_exp + 13 - 1 */ + L_tmp = L_mac( L_tmp, coeff[2], g2_code ); /* 15 - coeff_exp + 13 - 1 */ + L_tmp = L_mac( L_tmp, coeff[3], g_code ); /* 15 - coeff_exp + 13 - 1 */ + L_tmp = L_mac( L_tmp, coeff[4], g_pit_cod ); /* 15 - coeff_exp + 13 - 1 */ -#ifdef BASOP_NOGLOB L_tmp1 = L_sub_o( L_tmp, dist_min, &Overflow ); -#else /* BASOP_NOGLOB */ - L_tmp1 = L_sub( L_tmp, dist_min ); -#endif /* BASOP_NOGLOB */ /* splitting the if cost half the complexity of using IF macro */ if ( L_tmp1 < 0 ) { @@ -3266,12 +3184,8 @@ void gain_enc_amr_wb_fx( g_code = *p++; /* selected code gain in Q11 */ move16(); - L_tmp = L_mult( g_code, gcode0 ); /* Q11*Q0 -> Q12 */ -#ifdef BASOP_NOGLOB + L_tmp = L_mult( g_code, gcode0 ); /* Q11*Q0 -> Q12 */ L_tmp = L_shl_o( L_tmp, add( exp_gcode0, 4 ), &Overflow ); /* Q12 -> Q16 */ -#else /* BASOP_NOGLOB */ - L_tmp = L_shl( L_tmp, add( exp_gcode0, 4 ) ); /* Q12 -> Q16 */ -#endif *gain_code = L_tmp; /* gain of code in Q16 */ move16(); @@ -3292,13 +3206,13 @@ void gain_enc_amr_wb_fx( * update table of past quantized energies *----------------------------------------------------------------*/ - past_qua_en[3] = past_qua_en[2]; + past_qua_en[3] = past_qua_en[2]; // Q10 move16(); - past_qua_en[2] = past_qua_en[1]; + past_qua_en[2] = past_qua_en[1]; // Q10 move16(); - past_qua_en[1] = past_qua_en[0]; + past_qua_en[1] = past_qua_en[0]; // Q10 move16(); - past_qua_en[0] = qua_ener; + past_qua_en[0] = qua_ener; // Q10 move16(); @@ -3306,7 +3220,7 @@ void gain_enc_amr_wb_fx( exp = s_max( exp, 0 ); tmp = div_s( shr( 8192, exp ), *gain_inov ); - *norm_gain_code = L_shr( Mult_32_16( *gain_code, tmp ), sub( 1, exp ) ); + *norm_gain_code = L_shr( Mult_32_16( *gain_code, tmp ), sub( 1, exp ) ); // Q16 move32(); push_indice_fx( hBstr, IND_GAIN, index, nBits ); diff --git a/lib_enc/gaus_enc.c b/lib_enc/gaus_enc.c deleted file mode 100644 index d441f6ead49ddcb3a6a1ffab0962633db8157cd0..0000000000000000000000000000000000000000 --- a/lib_enc/gaus_enc.c +++ /dev/null @@ -1,43 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include -#include "cnst.h" -#include "rom_com.h" -#include "prot.h" -#include "wmc_auto.h" diff --git a/lib_enc/gaus_enc_fx.c b/lib_enc/gaus_enc_fx.c index 9b91bd505c9273da79cb65a2f25c626463fc1f98..f943b104d5ba4e27f3e0b7bbac7061463fd111f4 100644 --- a/lib_enc/gaus_enc_fx.c +++ b/lib_enc/gaus_enc_fx.c @@ -7,7 +7,6 @@ #include "rom_com_fx.h" /* Static table prototypes */ #include "rom_com.h" /* Static table prototypes */ #include "rom_enc.h" /* Static table prototypes */ -#include "prot.h" /* Function prototypes */ #include "prot_fx.h" /* Function prototypes */ #include "prot_fx_enc.h" /* Function prototypes */ //#include "basop_mpy.h" @@ -28,6 +27,8 @@ static Word16 cod_2pos_fx( const Word16 ind1, const Word16 ind2, const Word16 si static void gauss2v_fx( BSTR_ENC_HANDLE hBstr, const Word16 h[], const Word16 xn[], const Word16 dn[], Word16 code[], Word16 y1[], Word32 *gain, const Word16 lg, const Word16 shift, const Word16 Q_new, const Word16 nb_bits ); +static void gauss2v_ivas_fx( BSTR_ENC_HANDLE hBstr, const Word16 h[], const Word16 xn[], const Word16 dn[], Word16 code[], Word16 y1[], Word32 *gain, const Word16 lg, const Word16 shift, const Word16 Q_new, const Word16 nb_bits ); + /*-------------------------------------------------------------------* * Gaus_encode * @@ -39,22 +40,22 @@ static void gauss2v_fx( BSTR_ENC_HANDLE hBstr, const Word16 h[], const Word16 xn *-------------------------------------------------------------------*/ Word16 gaus_encode_fx( Encoder_State *st_fx, /* i/o: encoder state structure */ - const Word16 i_subfr, /* i : subframe index */ - const Word16 *h1, /* i : weighted filter input response */ - const Word16 *xn, /* i : target vector */ - Word16 *exc, /* o : pointer to excitation signal frame */ - Word16 *mem_w0, /* o : weighting filter denominator memory */ - Word16 *clip_gain, /* o : memory of gain of pitch clipping algorithm */ - Word16 *tilt_code, /* o : synthesis excitation spectrum tilt */ - Word16 *code, /* o : algebraic excitation Q9 */ - Word32 *gain_code, /* o : Code gain. Q16 */ - Word16 *y2, /* o : zero-memory filtered adaptive excitation Q9 */ - Word16 *gain_inov, /* o : innovation gain Q12 */ - Word16 *voice_fac, /* o : voicing factor Q15 */ - Word16 *gain_pit, /* o : adaptive excitation gain Q14 */ - const Word16 Q_new, /* i : scaling factor */ - const Word16 shift, /* i : scaling factor */ - Word32 *norm_gain_code /* o : normalized innovative cb. gain Q16 */ + const Word16 i_subfr, /* i : subframe index Q0*/ + const Word16 *h1, /* i : weighted filter input response Q14*/ + const Word16 *xn, /* i : target vector Q12*/ + Word16 *exc, /* o : pointer to excitation signal frame Q_new*/ + Word16 *mem_w0, /* o : weighting filter denominator memory Q_new*/ + Word16 *clip_gain, /* o : memory of gain of pitch clipping algorithm [2.56x,Q14,Q8,Q0,Q14,Q14]*/ + Word16 *tilt_code, /* o : synthesis excitation spectrum tilt Q15*/ + Word16 *code, /* o : algebraic excitation Q9*/ + Word32 *gain_code, /* o : Code gain. Q16*/ + Word16 *y2, /* o : zero-memory filtered adaptive excitation Q9*/ + Word16 *gain_inov, /* o : innovation gain Q12*/ + Word16 *voice_fac, /* o : voicing factor Q15*/ + Word16 *gain_pit, /* o : adaptive excitation gain Q14*/ + const Word16 Q_new, /* i : scaling factor */ + const Word16 shift, /* i : scaling factor */ + Word32 *norm_gain_code /* o : normalized innovative cb. gain Q16*/ ) { Word16 nb_bits, idx; @@ -64,6 +65,7 @@ Word16 gaus_encode_fx( Word16 exp, tmp, tmp_idx; #ifdef BASOP_NOGLOB_DECLARE_LOCAL Flag Overflow = 0; + move32(); #endif /*----------------------------------------------------------------* @@ -74,7 +76,7 @@ Word16 gaus_encode_fx( corr_xh_fx( xn, dn, h1 ); tmp_idx = shr( i_subfr, 6 ); - nb_bits = st_fx->acelp_cfg.fixed_cdk_index[tmp_idx]; + nb_bits = st_fx->acelp_cfg.fixed_cdk_index[tmp_idx]; /* Q0 */ move16(); gauss2v_fx( st_fx->hBstr, h1, xn, dn, code, y2, gain_code, L_SUBFR, shift, Q_new, shr( nb_bits, 1 ) ); @@ -90,52 +92,44 @@ Word16 gaus_encode_fx( Ltmp = Isqrt_lc( Ltmp, &exp_code ); *gain_inov = extract_h( L_shl( Ltmp, sub( exp_code, 3 ) ) ); /* g_code_inov in Q12 */ - nb_bits = st_fx->acelp_cfg.gains_mode[tmp_idx]; + nb_bits = st_fx->acelp_cfg.gains_mode[tmp_idx]; /* Q0 */ move16(); /* low bound = -30; stepSize = 1.71875; inv_stepSize = 0.5818181 */ - idx = gain_enc_gaus_fx( gain_code, nb_bits, -7680, 28160, 19065 ); + idx = gain_enc_gaus_fx( gain_code, nb_bits, -7680, 28160, 19065 ); /* Q0 */ push_indice_fx( st_fx->hBstr, IND_GAIN, idx, nb_bits ); /*----------------------------------------------------------------* * Total excitation for Unvoiced coders *----------------------------------------------------------------*/ -#ifdef BASOP_NOGLOB gcode = round_fx_o( L_shl_o( *gain_code, Q_new, &Overflow ), &Overflow ); /* scaled gain_code with Qnew */ -#else /* BASOP_NOGLOB */ - gcode = round_fx( L_shl( *gain_code, Q_new ) ); /* scaled gain_code with Qnew */ -#endif /* BASOP_NOGLOB */ FOR( i = 0; i < L_SUBFR; i++ ) { - exc[i + i_subfr] = round_fx( L_shl( L_mult( gcode, code[i] ), 15 - 9 ) ); + exc[i + i_subfr] = round_fx( L_shl( L_mult( gcode, code[i] ), 15 - 9 ) ); /* Q_new */ } /*----------------------------------------------------------------* * Updates: last value of new target is stored in mem_w0 *----------------------------------------------------------------*/ - Ltmp = L_mult( gcode, y2[L_SUBFR - 1] ); - Ltmp = L_shl( Ltmp, add( 5, shift ) ); + Ltmp = L_mult( gcode, y2[L_SUBFR - 1] ); /* Q_new + 10 */ + Ltmp = L_shl( Ltmp, add( 5, shift ) ); /* Q_new + 15 + shift */ Ltmp = L_negate( Ltmp ); - Ltmp = L_mac( Ltmp, xn[L_SUBFR - 1], 16384 ); -#ifdef BASOP_NOGLOB - Ltmp = L_shl_sat( Ltmp, sub( 1, shift ) ); - *mem_w0 = round_fx_sat( Ltmp ); -#else - Ltmp = L_shl( Ltmp, sub( 1, shift ) ); - *mem_w0 = round_fx( Ltmp ); -#endif + Ltmp = L_mac( Ltmp, xn[L_SUBFR - 1], 16384 ); /* Q_new + 15 + shift */ + Ltmp = L_shl_sat( Ltmp, sub( 1, shift ) ); /* Q_new + 16 */ + *mem_w0 = round_fx_sat( Ltmp ); /* Q_new */ + move16(); init_gp_clip_fx( clip_gain ); /* reset pitch clipping parameters */ *gain_pit = 0; *tilt_code = 0; - move16(); /* purely unvoiced */ - *voice_fac = -32768; - move16(); /* purely unvoiced */ + move16(); /* purely unvoiced */ + *voice_fac = -32768; /* -1 in Q31 */ + move16(); /* purely unvoiced */ exp = sub( norm_s( *gain_inov ), 1 ); exp = s_max( exp, 0 ); tmp = div_s( shr( 8192, exp ), *gain_inov ); - *norm_gain_code = L_shr( Mult_32_16( *gain_code, tmp ), sub( 1, exp ) ); + *norm_gain_code = L_shr( Mult_32_16( *gain_code, tmp ), sub( 1, exp ) ); /* Q16 */ move16(); return ( L_SUBFR << 6 ); @@ -143,31 +137,33 @@ Word16 gaus_encode_fx( Word16 gaus_encode_ivas_fx( Encoder_State *st_fx, /* i/o: encoder state structure */ - const Word16 i_subfr, /* i : subframe index */ - const Word16 *h1, /* i : weighted filter input response */ - const Word16 *xn, /* i : target vector */ - Word16 *exc, /* o : pointer to excitation signal frame */ - Word16 *mem_w0, /* o : weighting filter denominator memory */ - Word16 *clip_gain, /* o : memory of gain of pitch clipping algorithm */ - Word16 *tilt_code, /* o : synthesis excitation spectrum tilt */ - Word16 *code, /* o : algebraic excitation Q9 */ - Word32 *gain_code, /* o : Code gain. Q16 */ - Word16 *y2, /* o : zero-memory filtered adaptive excitation Q9 */ - Word16 *gain_inov, /* o : innovation gain Q12 */ - Word16 *voice_fac, /* o : voicing factor Q15 */ - Word16 *gain_pit, /* o : adaptive excitation gain Q14 */ - const Word16 Q_new, /* i : scaling factor */ - const Word16 shift, /* i : scaling factor */ - Word32 *norm_gain_code /* o : normalized innovative cb. gain Q16 */ + const Word16 i_subfr, /* i : subframe index Q0*/ + const Word16 *h1, /* i : weighted filter input response Q14*/ + const Word16 *xn, /* i : target vector Q12*/ + Word16 *exc, /* o : pointer to excitation signal frame Q_new*/ + Word16 *mem_w0, /* o : weighting filter denominator memory Q_new*/ + Word16 *clip_gain, /* o : memory of gain of pitch clipping algorithm [2.56x,Q14,Q8,Q0,Q14,Q14]*/ + Word16 *tilt_code, /* o : synthesis excitation spectrum tilt Q15*/ + Word16 *code, /* o : algebraic excitation Q9*/ + Word32 *gain_code, /* o : Code gain. Q16*/ + Word16 *y2, /* o : zero-memory filtered adaptive excitation Q9*/ + Word16 *gain_inov, /* o : innovation gain Q12*/ + Word16 *voice_fac, /* o : voicing factor Q15*/ + Word16 *gain_pit, /* o : adaptive excitation gain Q14*/ + const Word16 Q_new, /* i : scaling factor */ + const Word16 shift, /* i : scaling factor */ + Word32 *norm_gain_code /* o : normalized innovative cb. gain Q16*/ ) { Word16 nb_bits, idx; Word16 i = 0; + move16(); Word32 Ltmp; Word16 dn[L_SUBFR], exp_code, gcode; /* Correlation between xn and h1 */ Word16 exp, tmp, tmp_idx; #ifdef BASOP_NOGLOB_DECLARE_LOCAL Flag Overflow = 0; + move32(); #endif /*----------------------------------------------------------------* @@ -178,10 +174,10 @@ Word16 gaus_encode_ivas_fx( corr_xh_fx( xn, dn, h1 ); tmp_idx = shr( i_subfr, 6 ); - nb_bits = st_fx->acelp_cfg.fixed_cdk_index[tmp_idx]; + nb_bits = st_fx->acelp_cfg.fixed_cdk_index[tmp_idx]; /* Q0 */ move16(); - gauss2v_fx( st_fx->hBstr, h1, xn, dn, code, y2, gain_code, L_SUBFR, shift, Q_new, shr( nb_bits, 1 ) ); + gauss2v_ivas_fx( st_fx->hBstr, h1, xn, dn, code, y2, gain_code, L_SUBFR, shift, Q_new, shr( nb_bits, 1 ) ); /*----------------------------------------------------------------* * Encode gaussian gain @@ -194,52 +190,44 @@ Word16 gaus_encode_ivas_fx( Ltmp = Isqrt_lc( Ltmp, &exp_code ); *gain_inov = extract_h( L_shl( Ltmp, sub( exp_code, 3 ) ) ); /* g_code_inov in Q12 */ - nb_bits = st_fx->acelp_cfg.gains_mode[tmp_idx]; + nb_bits = st_fx->acelp_cfg.gains_mode[tmp_idx]; /* Q0 */ move16(); /* low bound = -30; stepSize = 1.71875; inv_stepSize = 0.5818181 */ - idx = gain_enc_gaus_fx( gain_code, nb_bits, -7680, 28160, 19065 ); + idx = gain_enc_gaus_fx( gain_code, nb_bits, -7680, 28160, 19065 ); /* Q0 */ push_indice( st_fx->hBstr, IND_GAIN, idx, nb_bits ); /*----------------------------------------------------------------* * Total excitation for Unvoiced coders *----------------------------------------------------------------*/ -#ifdef BASOP_NOGLOB gcode = round_fx_o( L_shl_o( *gain_code, Q_new, &Overflow ), &Overflow ); /* scaled gain_code with Qnew */ -#else /* BASOP_NOGLOB */ - gcode = round_fx( L_shl( *gain_code, Q_new ) ); /* scaled gain_code with Qnew */ -#endif /* BASOP_NOGLOB */ FOR( i = 0; i < L_SUBFR; i++ ) { - exc[i + i_subfr] = round_fx( L_shl( L_mult( gcode, code[i] ), 15 - 9 ) ); + exc[i + i_subfr] = round_fx( L_shl( L_mult( gcode, code[i] ), 15 - 9 ) ); /* Q_new */ } /*----------------------------------------------------------------* * Updates: last value of new target is stored in mem_w0 *----------------------------------------------------------------*/ - Ltmp = L_mult( gcode, y2[L_SUBFR - 1] ); - Ltmp = L_shl( Ltmp, add( 5, shift ) ); + Ltmp = L_mult( gcode, y2[L_SUBFR - 1] ); /* Q_new + 10 */ + Ltmp = L_shl( Ltmp, add( 5, shift ) ); /* Q_new + 15 + shift */ Ltmp = L_negate( Ltmp ); - Ltmp = L_mac( Ltmp, xn[L_SUBFR - 1], 16384 ); -#ifdef BASOP_NOGLOB - Ltmp = L_shl_sat( Ltmp, sub( 1, shift ) ); - *mem_w0 = round_fx_sat( Ltmp ); -#else - Ltmp = L_shl( Ltmp, sub( 1, shift ) ); - *mem_w0 = round_fx( Ltmp ); -#endif + Ltmp = L_mac( Ltmp, xn[L_SUBFR - 1], 16384 ); /* Q_new + 15 + shift */ + Ltmp = L_shl_sat( Ltmp, sub( 1, shift ) ); /* Q_new + 16 */ + *mem_w0 = round_fx_sat( Ltmp ); /* Q_new */ + move16(); init_gp_clip_fx( clip_gain ); /* reset pitch clipping parameters */ *gain_pit = 0; *tilt_code = 0; - move16(); /* purely unvoiced */ - *voice_fac = -32768; - move16(); /* purely unvoiced */ + move16(); /* purely unvoiced */ + *voice_fac = -32768; /* -1 in Q15 */ + move16(); /* purely unvoiced */ exp = sub( norm_s( *gain_inov ), 1 ); exp = s_max( exp, 0 ); tmp = div_s( shr( 8192, exp ), *gain_inov ); - *norm_gain_code = L_shr( Mult_32_16( *gain_code, tmp ), sub( 1, exp ) ); + *norm_gain_code = L_shr( Mult_32_16( *gain_code, tmp ), sub( 1, exp ) ); /* Q16 */ move16(); return ( L_SUBFR << 6 ); @@ -253,6 +241,467 @@ Word16 gaus_encode_ivas_fx( * One Gaussian vector of 192 values vectors delayed by 2 *-------------------------------------------------------------------*/ void gauss2v_fx( + BSTR_ENC_HANDLE hBstr, /* i/o: encoder state structure */ + const Word16 h[], /* i : weighted LP filter impulse response Q15 */ + const Word16 xn[], /* i : target signal Q12 */ + const Word16 dn[], /* i : backward filtered target Q12 */ + Word16 code[], /* o : gaussian excitation Q9 */ + Word16 y1[], /* o : zero-memory filtered gauss. excitation Q8 */ + Word32 *gain, /* o : excitation gain. 32-bit number in Q16 */ + const Word16 lg, /* i : subframe size Q0 */ + const Word16 shift, /* i : Scaling factor Q0 */ + const Word16 Q_new, /* i : Scaling factor Q0 */ + const Word16 nb_bits /* i : nb ob bits per track (max 6) Q0 */ +) +{ + Word16 i, j, ind1, ind2; + Word16 nvec, step; + Word32 cor, cora, dotprod; + Word16 enerw; + Word32 eneri, cor2; + Word32 enerw32, cor2w32; + Word16 *cpt1; + Word16 *pt1, *pt2; + Word32 max_val[NMAX + 1]; + Word16 *pos[NMAX + 1]; + Word32 sign[NMAX + 1]; + Word32 ener[NMAX + 1], corr[NMAX + 1], ener1; + Word16 dico2[L_SUBFR * NMAX]; + Word16 exp_num; + Word16 exp_den; + Word16 Num; + Word16 Den; + Word32 GainPortion1; + Word32 GainPortion2; + Word32 cor_abs; + Word16 cor_neg; + Word16 div_result; + Word32 ener_sqrt; + Word32 Portion; + Word16 sign1, sign2; + Word16 enerw_norm, enerw_mantissa; + Word16 cor2w_norm, cor2w_mantissa; + Word16 eneri_norm, eneri_mantissa; + Word16 cor2_norm, cor2_mantissa; + Word16 difference_norm; + Word32 cor32; /* 32-bit intermediate value*/ + Word16 hi1, lo1; + Word16 update_best; + Word16 idx; + Word32 Lc0, Lc1, Lnum, Lden; + Word16 gxx, gcc, index_delta, delta, m_sign, inv_delta; + Word16 hg[190], Gaus_dico2[190]; + Word16 shiftP3; +#ifdef BASOP_NOGLOB_DECLARE_LOCAL + Flag Overflow = 0; + move32(); +#endif + + /*----------------------------------------------------------------* + * Encode the tilt of gaussian excitation + *----------------------------------------------------------------*/ + + /* Compute spectral tilt of target */ + Lc0 = L_mult( xn[1], xn[1] ); /* Q25 */ + Lc1 = L_mult( xn[1], xn[0] ); /* Q25 */ + FOR( i = 2; i < L_SUBFR; i++ ) + { + /* fc0 += xn[i]*xn[i] */ + /* fc1 += xn[i]*xn[i-1] */ + Lc0 = L_mac_sat( Lc0, xn[i], xn[i] ); /* Q25 */ + Lc1 = L_mac_sat( Lc1, xn[i], xn[i - 1] ); /* Q25 */ + } + /* fgxx = fc1/fc0 */ + exp_num = sub( norm_l( Lc1 ), 1 ); + Num = extract_h( L_shl( Lc1, exp_num ) ); + m_sign = s_or( shr( Num, 16 ), 1 ); /* Remove sign */ + Num = abs_s( Num ); + Lc0 = L_max( Lc0, 1 ); + exp_den = norm_l( Lc0 ); + Den = extract_h( L_shl( Lc0, exp_den ) ); /* Q9 + exp_den */ + gxx = shr( div_s( Num, Den ), sub( exp_num, sub( exp_den, 2 ) ) ); /* Q13 */ + gxx = i_mult2( gxx, m_sign ); /* Apply sign */ + + set16_fx( hg, 0, 190 ); /* Compute spectral tilt of filtered codebook */ + Copy( h, hg, L_SUBFR ); // Q15 + conv_fx( gaus_dico_fx, hg, Gaus_dico2, 190 ); // Q12 + + Lc0 = L_mult( Gaus_dico2[1], Gaus_dico2[1] ); /* Q25 */ + Lc1 = L_mult( Gaus_dico2[1], Gaus_dico2[0] ); /* Q25 */ + FOR( i = 2; i < 190; i++ ) + { + /* fc0 += fgaus_dico2[i]*fgaus_dico2[i] */ + /* fc1 += fgaus_dico2[i]*fgaus_dico2[i-1] */ + Lc0 = L_mac( Lc0, Gaus_dico2[i], Gaus_dico2[i] ); /* Q25 */ + Lc1 = L_mac( Lc1, Gaus_dico2[i], Gaus_dico2[i - 1] ); /* Q25 */ + } + + /* fgcc = fc1/fc0 */ + + exp_num = sub( norm_l( Lc1 ), 1 ); + Num = extract_h( L_shl( Lc1, exp_num ) ); + m_sign = s_or( shr( Num, 16 ), 1 ); /* Remove sign */ + Num = abs_s( Num ); + + Lc0 = L_max( Lc0, 1 ); + exp_den = norm_l( Lc0 ); + Den = extract_h( L_shl( Lc0, exp_den ) ); + gcc = shr( div_s( Num, Den ), sub( exp_num, sub( exp_den, 2 ) ) ); /* Q13 */ + gcc = i_mult2( gcc, m_sign ); /* Apply sign */ + + /* fdelta = (1-fgcc*fgxx) / (2*fgcc+fgxx) Compute and quantize spectral tilt modification factor */ + Lnum = L_sub( 134217728L, L_mult( gcc, gxx ) ); /* Q30 */ + Lden = L_mac( L_mult( gxx, 8192 ), gcc, 16384 ); /* Q30 */ + + exp_num = sub( norm_l( Lnum ), 1 ); + Num = extract_h( L_shl( Lnum, exp_num ) ); /* Q14 + exp_den */ + m_sign = s_or( shr( Num, 16 ), 1 ); /* Remove sign */ + Num = abs_s( Num ); + + Lden = L_max( Lden, 1 ); + exp_den = norm_l( Lden ); + Den = extract_h( L_shl( Lden, exp_den ) ); + + delta = shr_o( div_s( Num, Den ), sub( exp_num, exp_den ), &Overflow ); /* Q15 */ + delta = i_mult2( delta, m_sign ); /* Apply sign Q0*/ + /* index_delta = (short)(FAC_DELTA * fdelta) */ + index_delta = shr( delta, SFAC_DELTA ); + + /* index_delta [0,7] */ + index_delta = s_max( index_delta, 0 ); + index_delta = s_min( index_delta, 7 ); + + /* fdelta = STEP_DELTA * (float)index_delta */ + delta = shl( index_delta, 11 ); /* delta in Q15 */ + + IF( delta > 0 ) /* Adapt spectral tilt of initial codebook */ + { + /* Computation of 1 / (1+fdelta*fdelta) */ + inv_delta = inv_delta_tab[sub( index_delta, 1 )]; + move16(); /* Q15 */ + + /* fgaus_dico2[0] = gaus_dico[0] */ + Gaus_dico2[0] = gaus_dico_fx[0]; /* Q12 */ + move16(); + FOR( i = 1; i < 190; i++ ) + { + /* fgaus_dico2[i] = (gaus_dico[i] - fdelta*gaus_dico[i-1]) / (1 + fdelta*fdelta) */ + Lnum = L_msu( L_deposit_h( gaus_dico_fx[i] ), delta, gaus_dico_fx[i - 1] ); + Gaus_dico2[i] = round_fx( Mpy_32_16_1( Lnum, inv_delta ) ); + } + } + ELSE + { + FOR( i = 0; i < 190; i++ ) + { + /* fgaus_dico2[i] = gaus_dico[i] */ + Gaus_dico2[i] = gaus_dico_fx[i]; /* Q12 */ + move16(); + } + } + + /*----------------------------------------------------------------* + * Initializations + *----------------------------------------------------------------*/ + + ind1 = 0; + move16(); + ind2 = 0; + move16(); + + nvec = shl( 1, nb_bits ); + step = shr( 0x80, nb_bits ); + + /*----------------------------------------------------------------* + * dot product between dn and gaussian codevectors, + * keep NMAX best vectors + *----------------------------------------------------------------*/ + + set32_fx( max_val, 0, NMAX + 1 ); + set32_fx( sign, 0, NMAX + 1 ); + + FOR( i = 0; i < NMAX + 1; i++ ) + { + pos[i] = (Word16 *) Gaus_dico2; + } + + cpt1 = Gaus_dico2; + move16(); + + FOR( i = 0; i < nvec; i++ ) + { + /* Dot product without normalization, because values are compared with each other afterwards. */ + cor = Dot_product( cpt1, dn, lg ); /* Q12 * Q12 * length of 64 + 1 left shift ==> Q31*/ + cora = L_abs( cor ); + j = NMAX - 1; + move16(); + + DO + { + IF( GE_32( cora, max_val[j] ) ) + { + max_val[j + 1] = max_val[j]; + move32(); /*Q31*/ + pos[j + 1] = pos[j]; + move16(); /*Pointer*/ + sign[j + 1] = sign[j]; + move32(); /*Q31*/ + max_val[j] = cora; + move32(); /*Q31*/ + pos[j] = cpt1; + move16(); /*Pointer*/ + sign[j] = cor; + move32(); /*Q31*/ + } + j--; + } + WHILE( j >= 0 ); + cpt1 += step; + } + + /*----------------------------------------------------------------* + * filter selected vectors + * put sign + * compute energy + *----------------------------------------------------------------*/ + + pt1 = dico2; + move16(); + FOR( i = 0; i < NMAX; i++ ) + { + /* Input vector (pos) Q12, filter coefs in Q15, result in same format as input vector (Q12) */ + conv_fx( pos[i], h, pt1, lg ); + + /* put sign and compute energy */ + IF( sign[i] < 0 ) + { + FOR( j = 0; j < lg; j++ ) + { + pt1[j] = negate( pt1[j] ); + move16(); /*Store into dico2*/ + } + } + ener[i] = Dot_product( pt1, pt1, lg ); /* pt1 points to filtered vector in dico2, in Q12 */ + move32(); /* Result is for Q12 * Q12 with length of 64 (6 bits) + 1 left shift => Q31 */ + corr[i] = Dot_product( pt1, xn, lg ); /* must be equal to sign[i] !! */ + move32(); /* pt1 points into dico2, in Q12. xn is in Q12 */ + /* Result is for Q12 * Q12 with length of 64 (6 bits) + 1 left shift => Q31 */ + pt1 += L_SUBFR; + } + + /*------------------------------------------------------------------------* + * try all combinations of NMAX best vectors + *------------------------------------------------------------------------*/ + + pt1 = dico2; + move16(); + + /* Initial values for search algorithm */ + enerw32 = L_deposit_h( 0x80 ); + cor2w32 = L_deposit_l( -2 ); + enerw_norm = norm_l( enerw32 ); + cor2w_norm = norm_l( cor2w32 ); + cor2w_mantissa = round_fx( L_shl( cor2w32, cor2w_norm ) ); + enerw_mantissa = round_fx( L_shl( enerw32, enerw_norm ) ); + + FOR( i = 0; i < NMAX; i++ ) + { + pt2 = pt1; + move16(); + FOR( j = i; j < NMAX; j++ ) + { + cor32 = L_add( corr[i], corr[j] ); /* Q31 */ + + dotprod = Dot_product( pt1, pt2, lg ); /* Q12 * Q12 * length of 64 + 1 left shift ==> Q31 */ + + /* eneri = round_fx(ener[i]) + round_fx(ener[j]) + 2*round_fx(dotprod) */ + /* Use ScalingShift to stay aligned with ener[] */ + eneri = L_shl( dotprod, 1 ); /* One left shift added for factor of 2 */ + eneri = L_add( ener[i], eneri ); + eneri = L_add( ener[j], eneri ); /* Q31 */ + + lo1 = L_Extract_lc( cor32, &hi1 ); + cor2 = Sad_32( 0, hi1, lo1 ); /* Square + Add */ + + cor2_norm = norm_l( cor2 ); + eneri_norm = norm_l( eneri ); + cor2_mantissa = round_fx_o( L_shl_o( cor2, cor2_norm, &Overflow ), &Overflow ); + eneri_mantissa = round_fx_o( L_shl_o( eneri, eneri_norm, &Overflow ), &Overflow ); + difference_norm = sub( add( cor2_norm, enerw_norm ), add( cor2w_norm, eneri_norm ) ); + + update_best = 0; + move16(); + + IF( difference_norm > 0 ) + { + if ( GT_32( L_shr( L_mult( cor2_mantissa, enerw_mantissa ), difference_norm ), + L_mult( cor2w_mantissa, eneri_mantissa ) ) ) + { + update_best = 1; + move16(); + } + } + ELSE + { + if ( L_msu_sat( L_shl( L_mult( cor2w_mantissa, eneri_mantissa ), difference_norm ), cor2_mantissa, enerw_mantissa ) < 0 ) // Saturation to be revisited + { + update_best = 1; + move16(); + } + } + IF( update_best != 0 ) + { + cor2w_mantissa = cor2_mantissa; + move16(); + cor2w_norm = cor2_norm; + move16(); + enerw_mantissa = eneri_mantissa; + move16(); + enerw_norm = eneri_norm; + move16(); + ind1 = i; + move16(); + ind2 = j; + move16(); + } + pt2 += L_SUBFR; + } + pt1 += L_SUBFR; + } + + enerw = round_fx( L_shr( L_deposit_h( enerw_mantissa ), enerw_norm ) ); + + /*----------------------------------------------------------------* + * Compute zero-memory filtered gauss. excitation y + *----------------------------------------------------------------*/ + + pt1 = dico2 + ind1 * L_SUBFR; + move16(); /*Pointer arithmetic*/ + pt2 = dico2 + ind2 * L_SUBFR; + move16(); + + shiftP3 = add( shift, 3 ); + FOR( i = 0; i < lg; i++ ) + { + /* Sum of 2 Q12 values, must give a Q1.8 */ + y1[i] = shr( add( pt1[i], pt2[i] ), shiftP3 ); + move16(); /* Compensate for "shift" */ + } + + /*----------------------------------------------------------------* + * signs of vectors + *----------------------------------------------------------------*/ + + sign1 = ( -32768 ); + move16(); + if ( sign[ind1] >= 0 ) + { + sign1 = 32767; + move16(); + } + + sign2 = ( -32768 ); + move16(); + if ( sign[ind2] >= 0 ) + { + sign2 = 32767; + move16(); + } + + /*----------------------------------------------------------------* + * Compute code + *----------------------------------------------------------------*/ + + pt1 = pos[ind1]; + move16(); /* Points to gaussian vector (gaus_dico_fx) in Q12 */ + pt2 = pos[ind2]; + move16(); /* Points to gaussian vector (gaus_dico_fx) in Q12 */ + + /* sign[ind1] and sign[ind2] */ + FOR( i = 0; i < lg; i++ ) + { + /* code[i]=(pt1[i]*sign1 + pt2[i]*sign2) /8 */ + /* Division by 8 (shift by 3) is for scaling (Q12 to Q0.9 output) */ + code[i] = shr( add( mult( pt1[i], sign1 ), mult( pt2[i], sign2 ) ), 3 ); + move16(); + } + + cor = L_add( corr[ind1], corr[ind2] ); + + /*----------------------------------------------------------------* + * Compute index + *----------------------------------------------------------------*/ + + i = (Word16) ( ( pos[ind1] - Gaus_dico2 ) / step ); /* Division by step can be replaced by shift. Pointer arithmetic */ + j = (Word16) ( ( pos[ind2] - Gaus_dico2 ) / step ); /* Division by step can be replaced by shift. Pointer arithmetic */ + + idx = cod_2pos_fx( i, j, sign1, sign2, nvec ); /* Q0 */ + move16(); + + push_indice_fx( hBstr, IND_GAUS_CDBK_INDEX, idx, 2 * nb_bits + 1 ); + push_indice_fx( hBstr, IND_TILT_FACTOR, index_delta, 3 ); + + /*----------------------------------------------------------------* + * Find quantized gain + *----------------------------------------------------------------*/ + + /* Divide cor/enerw: intermediate result stored into GainPortion1 */ + cor_neg = 0; + move16(); + if ( cor < 0 ) /* Make Num positive. */ + { + cor_neg = 1; + move16(); + } + cor_abs = L_abs( cor ); + + exp_num = sub( norm_l( cor_abs ), 1 ); + exp_den = norm_s( enerw ); + Num = round_fx( L_shl( cor_abs, exp_num ) ); + Den = shl( enerw, exp_den ); + + GainPortion1 = L_deposit_l( 0 ); /* Unexpected division by zero. Eliminate this gain contribution */ + IF( Den != 0 ) /* Protection against division by zero */ + { + div_result = div_s( Num, Den ); /* Q15 */ + IF( cor_neg != 0 ) + { + div_result = negate( div_result ); /* Retrieve sign */ + } + /* Re-scale to compensate for normalization*/ + GainPortion1 = L_shr( L_deposit_l( div_result ), sub( exp_num, exp_den ) ); + } + + ener1 = Dot_product( xn, xn, lg ); /* Q12 * Q12 * length of 64 + 1 left shift ==> Q31 */ + + exp_num = sub( norm_s( enerw ), 1 ); + exp_den = norm_l( ener1 ); + Num = shl( enerw, exp_num ); + Den = round_fx_sat( L_shl_sat( ener1, exp_den ) ); + GainPortion2 = L_deposit_l( 0 ); /* Unexpected division by zero. Eliminate this gain contribution */ + IF( Den != 0 ) /* Protection against division by zero */ + { + div_result = div_s( Num, Den ); /* Q15 */ + + /* Re-scale to compensate for normalization*/ + GainPortion2 = L_shr_sat( L_deposit_l( div_result ), sub( exp_num, exp_den ) ); + } + + ener_sqrt = Isqrt( L_shl_sat( GainPortion2, 1 ) ); /* Make value a Q16 prior to division (align on power of 4) */ + ener_sqrt = L_shr( ener_sqrt, 8 ); /* Left-shift Q23 result to make a Q15 result */ + + Portion = Mult_32_16( GainPortion1, 19661 ); /* Performs GainPortion1*.6 */ + Portion = Madd_32_16( Portion, ener_sqrt, 13107 ); /* Performs ener_sqrt*.4 */ + + /* Gain must be output in a 32-bit variable as a Q16 */ + /* Compensate for Q_new */ + *gain = L_shl_o( Portion, sub( 13, Q_new ), &Overflow ); /* Q16 */ + move32(); + + return; +} + +void gauss2v_ivas_fx( BSTR_ENC_HANDLE hBstr, /* i/o: encoder state structure */ const Word16 h[], /* i : weighted LP filter impulse response Q15 */ const Word16 xn[], /* i : target signal Q12 */ @@ -306,6 +755,7 @@ void gauss2v_fx( Word16 shiftP3; #ifdef BASOP_NOGLOB_DECLARE_LOCAL Flag Overflow = 0; + move32(); #endif /*----------------------------------------------------------------* @@ -319,13 +769,8 @@ void gauss2v_fx( { /* fc0 += xn[i]*xn[i] */ /* fc1 += xn[i]*xn[i-1] */ -#ifdef BASOP_NOGLOB Lc0 = L_mac_sat( Lc0, xn[i], xn[i] ); Lc1 = L_mac_sat( Lc1, xn[i], xn[i - 1] ); -#else - Lc0 = L_mac( Lc0, xn[i], xn[i] ); - Lc1 = L_mac( Lc1, xn[i], xn[i - 1] ); -#endif } /* fgxx = fc1/fc0 */ exp_num = sub( norm_l( Lc1 ), 1 ); @@ -378,12 +823,8 @@ void gauss2v_fx( exp_den = norm_l( Lden ); Den = extract_h( L_shl( Lden, exp_den ) ); -#ifdef BASOP_NOGLOB delta = shr_o( div_s( Num, Den ), sub( exp_num, exp_den ), &Overflow ); /* Q15 */ -#else /* BASOP_NOGLOB */ - delta = shr( div_s( Num, Den ), sub( exp_num, exp_den ) ); /* Q15 */ -#endif - delta = i_mult2( delta, m_sign ); /* Apply sign */ + delta = i_mult2( delta, m_sign ); /* Apply sign */ /* index_delta = (short)(FAC_DELTA * fdelta) */ index_delta = shr( delta, SFAC_DELTA ); @@ -402,11 +843,13 @@ void gauss2v_fx( /* fgaus_dico2[0] = gaus_dico[0] */ Gaus_dico2[0] = gaus_dico_fx[0]; + move16(); FOR( i = 1; i < 190; i++ ) { /* fgaus_dico2[i] = (gaus_dico[i] - fdelta*gaus_dico[i-1]) / (1 + fdelta*fdelta) */ Lnum = L_msu( L_deposit_h( gaus_dico_fx[i] ), delta, gaus_dico_fx[i - 1] ); Gaus_dico2[i] = round_fx( Mpy_32_16_1( Lnum, inv_delta ) ); + move16(); } } ELSE @@ -536,21 +979,20 @@ void gauss2v_fx( /* eneri = round_fx(ener[i]) + round_fx(ener[j]) + 2*round_fx(dotprod) */ /* Use ScalingShift to stay aligned with ener[] */ eneri = L_shl( dotprod, 1 ); /* One left shift added for factor of 2 */ +#ifndef FIX_1298 eneri = L_add( ener[i], eneri ); eneri = L_add( ener[j], eneri ); /* Q31 */ - +#else + eneri = L_add_sat( ener[i], eneri ); + eneri = L_add_sat( ener[j], eneri ); /* Q31 */ +#endif lo1 = L_Extract_lc( cor32, &hi1 ); cor2 = Sad_32( 0, hi1, lo1 ); /* Square + Add */ cor2_norm = norm_l( cor2 ); eneri_norm = norm_l( eneri ); -#ifdef BASOP_NOGLOB cor2_mantissa = round_fx_o( L_shl_o( cor2, cor2_norm, &Overflow ), &Overflow ); eneri_mantissa = round_fx_o( L_shl_o( eneri, eneri_norm, &Overflow ), &Overflow ); -#else - cor2_mantissa = round_fx( L_shl( cor2, cor2_norm ) ); - eneri_mantissa = round_fx( L_shl( eneri, eneri_norm ) ); -#endif difference_norm = sub( add( cor2_norm, enerw_norm ), add( cor2w_norm, eneri_norm ) ); update_best = 0; @@ -662,8 +1104,8 @@ void gauss2v_fx( idx = cod_2pos_fx( i, j, sign1, sign2, nvec ); move16(); - push_indice_fx( hBstr, IND_GAUS_CDBK_INDEX, idx, 2 * nb_bits + 1 ); - push_indice_fx( hBstr, IND_TILT_FACTOR, index_delta, 3 ); + push_indice( hBstr, IND_GAUS_CDBK_INDEX, idx, 2 * nb_bits + 1 ); + push_indice( hBstr, IND_TILT_FACTOR, index_delta, 3 ); /*----------------------------------------------------------------* * Find quantized gain @@ -701,56 +1143,39 @@ void gauss2v_fx( exp_num = sub( norm_s( enerw ), 1 ); exp_den = norm_l( ener1 ); Num = shl( enerw, exp_num ); -#ifdef BASOP_NOGLOB Den = round_fx_sat( L_shl_sat( ener1, exp_den ) ); -#else - Den = round_fx( L_shl( ener1, exp_den ) ); -#endif GainPortion2 = L_deposit_l( 0 ); /* Unexpected division by zero. Eliminate this gain contribution */ IF( Den != 0 ) /* Protection against division by zero */ { div_result = div_s( Num, Den ); /* Q15 */ /* Re-scale to compensate for normalization*/ -#ifdef BASOP_NOGLOB GainPortion2 = L_shr_sat( L_deposit_l( div_result ), sub( exp_num, exp_den ) ); -#else - GainPortion2 = L_shr( L_deposit_l( div_result ), sub( exp_num, exp_den ) ); -#endif } -#ifdef BASOP_NOGLOB ener_sqrt = Isqrt( L_shl_sat( GainPortion2, 1 ) ); /* Make value a Q16 prior to division (align on power of 4) */ -#else - ener_sqrt = Isqrt( L_shl( GainPortion2, 1 ) ); /* Make value a Q16 prior to division (align on power of 4) */ -#endif - ener_sqrt = L_shr( ener_sqrt, 8 ); /* Left-shift Q23 result to make a Q15 result */ + ener_sqrt = L_shr( ener_sqrt, 8 ); /* Left-shift Q23 result to make a Q15 result */ Portion = Mult_32_16( GainPortion1, 19661 ); /* Performs GainPortion1*.6 */ Portion = Madd_32_16( Portion, ener_sqrt, 13107 ); /* Performs ener_sqrt*.4 */ /* Gain must be output in a 32-bit variable as a Q16 */ /* Compensate for Q_new */ -#ifdef BASOP_NOGLOB *gain = L_shl_o( Portion, sub( 13, Q_new ), &Overflow ); -#else - *gain = L_shl( Portion, sub( 13, Q_new ) ); -#endif move32(); return; } - /*---------------------------------------------------------------------* * Put selected codevector positions and signs into quantization index *---------------------------------------------------------------------*/ -static Word16 cod_2pos_fx( /* o : codebook quantization index */ - const Word16 ind1, /* i : index of 1st gaussian vector */ - const Word16 ind2, /* i : index of 2nd gaussian vector */ - const Word16 sign1, /* i : sign of 1st gaussian vector */ - const Word16 sign2, /* i : sign of 2nd gaussian vector */ - const Word16 n /* i : nb. of codebook vectors */ +static Word16 cod_2pos_fx( /* o : codebook quantization index */ + const Word16 ind1, /* i : index of 1st gaussian vector Q0*/ + const Word16 ind2, /* i : index of 2nd gaussian vector Q0*/ + const Word16 sign1, /* i : sign of 1st gaussian vector Qx*/ + const Word16 sign2, /* i : sign of 2nd gaussian vector Qx*/ + const Word16 n /* i : nb. of codebook vectors Q0*/ ) { Word16 i1, i2, index, s1, s2; @@ -774,16 +1199,16 @@ static Word16 cod_2pos_fx( /* o : codebook quantization in { IF( LE_16( ind1, ind2 ) ) { - i1 = ind1; + i1 = ind1; /* Q0 */ move16(); - i2 = ind2; + i2 = ind2; /* Q0 */ move16(); } ELSE { - i1 = ind2; + i1 = ind2; /* Q0 */ move16(); - i2 = ind1; + i2 = ind1; /* Q0 */ move16(); } } @@ -791,16 +1216,16 @@ static Word16 cod_2pos_fx( /* o : codebook quantization in { IF( GT_16( ind1, ind2 ) ) { - i1 = ind1; + i1 = ind1; /* Q0 */ move16(); - i2 = ind2; + i2 = ind2; /* Q0 */ move16(); } ELSE { - i1 = ind2; + i1 = ind2; /* Q0 */ move16(); - i2 = ind1; + i2 = ind1; /* Q0 */ move16(); s1 = s2; move16(); diff --git a/lib_enc/gp_clip.c b/lib_enc/gp_clip.c deleted file mode 100644 index 7dd2c1f21169fdc182f70f2f4e86aa4bb3106165..0000000000000000000000000000000000000000 --- a/lib_enc/gp_clip.c +++ /dev/null @@ -1,42 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include -#include "prot.h" -#include "cnst.h" -#include "wmc_auto.h" diff --git a/lib_enc/gp_clip_fx.c b/lib_enc/gp_clip_fx.c index bf532a085cf9fc3164f867f3c3e3db1a1de82d13..d7614473b32a086f9d0171d2ae510f9d5f941316 100644 --- a/lib_enc/gp_clip_fx.c +++ b/lib_enc/gp_clip_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other @@ -68,7 +68,7 @@ * Pitch Gain clipping initializations *-------------------------------------------------------------------*/ void init_gp_clip_fx( - Word16 mem[] /* o : memory of gain of pitch clipping algorithm */ + Word16 mem[] /* o : memory of gain of pitch clipping algorithm [2.56x,Q14,Q8,Q0,Q14,Q14]*/ ) { mem[0] = DIST_ISF_MAX; @@ -98,13 +98,13 @@ void init_gp_clip_fx( *-------------------------------------------------------------------*/ Word16 gp_clip_fx( - const Word16 element_mode, /* i : element mode */ - const Word32 core_brate, /* i : core bitrate */ - const Word16 *voicing, /* i : normalized correlations (from OL pitch) */ - const Word16 i_subfr, /* i : subframe index */ - const Word16 coder_type, /* i : type of coder */ - const Word16 xn[], /* i : target vector */ - Word16 mem[], /* i/o: memory of gain of pitch clipping algorithm */ + const Word16 element_mode, /* i : element mode Q0*/ + const Word32 core_brate, /* i : core bitrate Q0*/ + const Word16 *voicing, /* i : normalized correlations (from OL pitch) Q15*/ + const Word16 i_subfr, /* i : subframe index Q0*/ + const Word16 coder_type, /* i : type of coder Q0*/ + const Word16 xn[], /* i : target vector Q_new*/ + Word16 mem[], /* i/o: memory of gain of pitch clipping algorithm [2.56x,Q14,Q8,Q0,Q14,Q14]*/ const Word16 Q_new /* i : scaling factor */ ) { @@ -116,16 +116,16 @@ Word16 gp_clip_fx( Word16 thres; #ifdef BASOP_NOGLOB_DECLARE_LOCAL Flag Overflow = 0; + move32(); #endif clip = 0; move16(); test(); test(); - IF( EQ_32( core_brate, ACELP_6k60 ) || EQ_32( core_brate, ACELP_8k85 ) || GT_16( element_mode, EVS_MONO ) ) + IF( EQ_32( core_brate, ACELP_6k60 ) || EQ_32( core_brate, ACELP_8k85 ) || element_mode > EVS_MONO ) { - thres = add( 14746, mult( 1638, extract_l( L_mult( mem[0], (Word16) ( 16384 / DIST_ISF_MAX_IO ) ) ) ) ); /* clipping is activated when filtered pitch gain > threshold (0.94 to 1 in Q14) */ - test(); + thres = add( 14746 /* 0.9 in Q14 */, mult( 1638 /* 0.1 in Q14 */, extract_l( L_mult( mem[0], (Word16) ( 16384 / DIST_ISF_MAX_IO ) ) ) ) ); /* clipping is activated when filtered pitch gain > threshold (0.94 to 1 in Q14) */ if ( GT_16( mem[1], thres ) ) { clip = 1; @@ -142,25 +142,17 @@ Word16 gp_clip_fx( } } -#ifdef BASOP_NOGLOB ener = L_mac_o( 1L, xn[0], xn[0], &Overflow ); -#else - ener = L_mac( 1L, xn[0], xn[0] ); -#endif FOR( i = 1; i < L_SUBFR; i++ ) { -#ifdef BASOP_NOGLOB ener = L_mac_o( ener, xn[i], xn[i], &Overflow ); -#else /* BASOP_NOGLOB */ - ener = L_mac( ener, xn[i], xn[i] ); -#endif } /* ener = 10.0f*(float)log10(ener) */ e_ener = norm_l( ener ); f_ener = Log2_norm_lc( L_shl( ener, e_ener ) ); e_ener = sub( 30, e_ener ); - IF( GT_16( element_mode, EVS_MONO ) ) + IF( element_mode > EVS_MONO ) { e_ener = sub( e_ener, Q_new * 2 + 1 ); } @@ -168,20 +160,20 @@ Word16 gp_clip_fx( { e_ener = sub( e_ener, Q_new ); } - ener = Mpy_32_16( e_ener, f_ener, LG10 ); - wener = round_fx( L_shl( ener, 10 ) ); + ener = Mpy_32_16( e_ener, f_ener, LG10 ); /* Q14 */ + wener = round_fx( L_shl( ener, 10 ) ); /* Q8 */ test(); - if ( LT_16( wener, sub( mem[2], 1536 ) ) && GT_16( mem[1], 16384 ) ) + if ( LT_16( wener, sub( mem[2], 1536 /* 6.0f in Q8 */ ) ) && GT_16( mem[1], 16384 /* 1 in Q14 */ ) ) { clip = 1; move16(); } - mem[2] = wener; + mem[2] = wener; /* Q8 */ move16(); - L_tmp = L_mult( ALPHA1, mem[4] ); + L_tmp = L_mult( ALPHA1, mem[4] ); /* Q30 */ test(); test(); @@ -189,19 +181,19 @@ Word16 gp_clip_fx( { /* mem[4] = (1-ALPHA1) + ALPHA1 * mem[4], if branch taken */ /* mem[4] = ALPHA1 * mem[4], otherwise */ - L_tmp = L_add( L_tmp, 32768L * ( 32768 - ALPHA1 ) ); + L_tmp = L_add( L_tmp, 32768L * ( 32768 - ALPHA1 ) ); /* Q30 */ } - mem[4] = round_fx( L_tmp ); + mem[4] = round_fx( L_tmp ); /* Q14 */ L_tmp = L_mult( ALPHA4, mem[5] ); - if ( i_subfr == 0 ) + IF( i_subfr == 0 ) { /* mem[5] = (1-ALPHA4) * voicing[0] + ALPHA4 * mem[5] */ mem[5] = mac_r( L_tmp, ( 32768 - ALPHA4 ) / 2, voicing[0] ); move16(); /* /2 to put voicing from Q15 to Q14 */ } - if ( EQ_16( i_subfr, 2 * L_SUBFR ) ) + IF( EQ_16( i_subfr, 2 * L_SUBFR ) ) { /* mem[5] = (1-ALPHA4) * voicing[1] + ALPHA4 * mem[5] */ mem[5] = mac_r( L_tmp, ( 32768 - ALPHA4 ) / 2, voicing[1] ); @@ -219,7 +211,7 @@ Word16 gp_clip_fx( } ELSE { - mem[3] = add( mem[3], 1 ); + mem[3] = add( mem[3], 1 ); /* Q0 */ move16(); } @@ -233,16 +225,16 @@ Word16 gp_clip_fx( *-------------------------------------------------------------------*/ void gp_clip_test_isf_fx( - const Word16 element_mode, /* i : element mode */ - const Word32 core_brate, /* i : core bitrate */ - const Word16 isf[], /* i : isf values (in frequency domain) */ - Word16 mem[], /* i/o: memory of gain of pitch clipping algorithm */ - const Word16 Opt_AMR_WB /* i : flag indicating AMR-WB IO mode */ + const Word16 element_mode, /* i : element mode Q0*/ + const Word32 core_brate, /* i : core bitrate Q0*/ + const Word16 isf[], /* i : isf values (in frequency domain) Q2.56*/ + Word16 mem[], /* i/o: memory of gain of pitch clipping algorithm Q15*/ + const Word16 Opt_AMR_WB /* i : flag indicating AMR-WB IO mode Q0*/ ) { Word16 i, dist, dist_min, m; - dist_min = sub( isf[1], isf[0] ); + dist_min = sub( isf[1], isf[0] ); /* Q2.56 */ m = M; move16(); @@ -255,15 +247,15 @@ void gp_clip_test_isf_fx( move16(); /* ptr init*/ FOR( i = 2; i < m; i++ ) { - dist = sub( isf[i], isf[i - 1] ); - dist_min = s_min( dist, dist_min ); + dist = sub( isf[i], isf[i - 1] ); /* Q2.56 */ + dist_min = s_min( dist, dist_min ); /* Q2.56 */ } - dist = extract_h( L_mac( L_mult( 26214, mem[0] ), 6554, dist_min ) ); + dist = extract_h( L_mac( L_mult( 26214 /* 0.8f in Q15 */, mem[0] ), 6554 /* 0.2f in Q15 */, dist_min ) ); /* Q15 */ test(); test(); - IF( EQ_32( core_brate, ACELP_6k60 ) || EQ_32( core_brate, ACELP_8k85 ) || GT_16( element_mode, EVS_MONO ) ) + IF( EQ_32( core_brate, ACELP_6k60 ) || EQ_32( core_brate, ACELP_8k85 ) || element_mode > EVS_MONO ) { dist = s_min( dist, DIST_ISF_MAX_IO ); } @@ -271,7 +263,7 @@ void gp_clip_test_isf_fx( { dist = s_min( dist, DIST_ISF_MAX ); } - mem[0] = dist; + mem[0] = dist; /* Q15 */ move16(); return; @@ -284,10 +276,10 @@ void gp_clip_test_isf_fx( *-------------------------------------------------------------------*/ void gp_clip_test_gain_pit_fx( - const Word16 element_mode, /* i : element mode */ - const Word32 core_brate, /* i : core bitrate */ - const Word16 gain_pit, /* i : gain of quantized pitch Q14 */ - Word16 mem[] /* i/o: memory of gain of pitch clipping algorithm 1Q14 */ + const Word16 element_mode, /* i : element mode Q0*/ + const Word32 core_brate, /* i : core bitrate Q0*/ + const Word16 gain_pit, /* i : gain of quantized pitch Q14*/ + Word16 mem[] /* i/o: memory of gain of pitch clipping algorithm 1Q14*/ ) { Word16 gain; @@ -295,19 +287,19 @@ void gp_clip_test_gain_pit_fx( test(); test(); - IF( EQ_32( core_brate, ACELP_6k60 ) || EQ_32( core_brate, ACELP_8k85 ) || GT_16( element_mode, EVS_MONO ) ) + IF( EQ_32( core_brate, ACELP_6k60 ) || EQ_32( core_brate, ACELP_8k85 ) || element_mode > EVS_MONO ) { - L_tmp = L_mult( 32113, mem[1] ); /* long term LTP gain average (>250ms) */ - L_tmp = L_mac( L_tmp, 655, gain_pit ); + L_tmp = L_mult( 32113 /* 0.98 in Q15 */, mem[1] ); /* long term LTP gain average (>250ms) */ + L_tmp = L_mac( L_tmp, 655 /* 0.02 in Q15 */, gain_pit ); } ELSE { - L_tmp = L_mult( 29491, mem[1] ); - L_tmp = L_mac( L_tmp, 3277, gain_pit ); + L_tmp = L_mult( 29491 /* 0.9 in Q15 */, mem[1] ); + L_tmp = L_mac( L_tmp, 3277 /* 0.1 in Q15 */, gain_pit ); } gain = extract_h( L_tmp ); gain = s_max( gain, GAIN_PIT_MIN ); - mem[1] = gain; + mem[1] = gain; /* Q14 */ move16(); return; @@ -323,10 +315,10 @@ void gp_clip_test_gain_pit_fx( * prediction (lp_gp > 0.9) * - target energy drops by 6 dB AND a good pitch prediction (lp_gp>1.0) *-------------------------------------------------------------------*/ -Word16 Mode2_gp_clip( +Word16 Mode2_gp_clip_fx( const Word16 *voicing, /* i : normalized correlations from OL pitch Q15 */ - const Word16 i_subfr, /* i : subframe index */ - const Word16 coder_type, /* i : type of coder */ + const Word16 i_subfr, /* i : subframe index Q0 */ + const Word16 coder_type, /* i : type of coder Q0 */ const Word16 xn[], /* i : target vector Q_xn */ Word16 mem[], /* i/o: memory of gain of pitch clipping algorithm */ /* mem[0]: Q0 */ @@ -335,8 +327,8 @@ Word16 Mode2_gp_clip( /* mem[3]: Q0 (integer) */ /* mem[4]: Q14 */ /* mem[5]: Q14 */ - const Word16 L_subfr, - const Word16 Q_xn /* i : scaling factor of vector xn[] */ + const Word16 L_subfr, /* Q0 */ + const Word16 Q_xn /* i : scaling factor of vector xn[] */ ) { Word16 clip, tmp, exp_xn; @@ -344,6 +336,7 @@ Word16 Mode2_gp_clip( Word32 wener, Ltmp; #ifdef BASOP_NOGLOB_DECLARE_LOCAL Flag Overflow = 0; + move32(); #endif move16(); clip = 0; @@ -362,11 +355,7 @@ Word16 Mode2_gp_clip( FOR( i = 0; i < L_subfr; i++ ) { -#ifdef BASOP_NOGLOB wener = L_mac0_o( wener, xn[i], xn[i], &Overflow ); -#else - wener = L_mac0( wener, xn[i], xn[i] ); -#endif } /*wener = 10.0f*(float)log10(wener);*/ @@ -393,20 +382,20 @@ Word16 Mode2_gp_clip( if ( s_or( (Word16) EQ_16( coder_type, GENERIC ), (Word16) EQ_16( coder_type, TRANSITION ) ) ) { - Ltmp = L_add( Ltmp, ALPHA1_M1 ); + Ltmp = L_add( Ltmp, ALPHA1_M1 ); /* Q30 */ } - mem[4] = round_fx( Ltmp ); + mem[4] = round_fx( Ltmp ); /* Q14 */ Ltmp = Mpy_32_16_1( ALPHA4, mem[5] ); /* mem[5] in Q14 format, Ltmp in Q14 */ IF( i_subfr == 0 ) { - move16(); /* voicing: Q15 */ - mem[5] = round_fx( L_add( Mpy_32_16_1( ALPHA4_M1, voicing[0] ), Ltmp ) ); + move16(); /* voicing: Q15 */ + mem[5] = round_fx( L_add( Mpy_32_16_1( ALPHA4_M1, voicing[0] ), Ltmp ) ); /* Q14 */ } ELSE IF( EQ_16( i_subfr, shl( L_subfr, 1 ) ) ) { move16(); - mem[5] = round_fx( L_add( Mpy_32_16_1( ALPHA4_M1, voicing[1] ), Ltmp ) ); + mem[5] = round_fx( L_add( Mpy_32_16_1( ALPHA4_M1, voicing[1] ), Ltmp ) ); /* Q14 */ } IF( GT_16( mem[3], WINDOW_SIZE ) ) @@ -421,7 +410,7 @@ Word16 Mode2_gp_clip( ELSE { move16(); - mem[3] = add( mem[3], 1 ); + mem[3] = add( mem[3], 1 ); /* Q0 */ } @@ -434,10 +423,10 @@ Word16 Mode2_gp_clip( * check the minimum distance of LSFs for pitch gain clipping flag *-------------------------------------------------------------------*/ void gp_clip_test_lsf_fx( - const Word16 element_mode, /* i : element mode */ - const Word16 lsf[], /* i : lsf values (in frequency domain) 14Q1*1.28 */ - Word16 mem[], /* i/o: memory of gain of pitch clipping algorithm */ - const Word16 m /* i : dimension of lsf */ + const Word16 element_mode, /* i : element mode Q0*/ + const Word16 lsf[], /* i : lsf values (in frequency domain) 14Q1*1.28*/ + Word16 mem[], /* i/o: memory of gain of pitch clipping algorithm [2.56x,Q14,Q8,Q0,Q14,Q14]*/ + const Word16 m /* i : dimension of lsf Q0*/ ) { Word16 i; @@ -445,22 +434,22 @@ void gp_clip_test_lsf_fx( dist_max = DIST_ISF_MAX; move16(); - if ( GT_16( element_mode, EVS_MONO ) ) + if ( element_mode > EVS_MONO ) { dist_max = DIST_ISF_MAX_IO; move16(); } - dist_min = sub( lsf[1], lsf[0] ); + dist_min = sub( lsf[1], lsf[0] ); /* 14Q1*1.28 */ FOR( i = 2; i < m - 1; i++ ) { - dist = sub( lsf[i], lsf[i - 1] ); + dist = sub( lsf[i], lsf[i - 1] ); /* 14Q1*1.28 */ dist_min = s_min( dist, dist_min ); } /*dist = 0.8f*mem[0] + 0.2f*dist_min;*/ - dist = s_min( dist_max, mac_r( L_mult( 26214 /*0.8f Q15*/, mem[0] ), 6554 /*0.2f Q15*/, dist_min ) ); + dist = s_min( dist_max, mac_r( L_mult( 26214 /*0.8f Q15*/, mem[0] ), 6554 /*0.2f Q15*/, dist_min ) ); /* x2.56 */ - mem[0] = dist; + mem[0] = dist; /* x2.56 */ move16(); @@ -468,18 +457,18 @@ void gp_clip_test_lsf_fx( } void gp_clip_test_lsf_ivas_fx( - const Word16 element_mode, /* i : element mode */ - const Word32 core_brate, /* i : core bitrate */ - const Word16 lsf[], /* i : LSF vector */ - Word16 mem[], /* i/o: memory of gain of pitch clipping algorithm */ - const Word16 Opt_AMR_WB /* i : flag indicating AMR-WB IO mode */ + const Word16 element_mode, /* i : element mode Q0*/ + const Word32 core_brate, /* i : core bitrate Q0*/ + const Word16 lsf[], /* i : LSF vector 14Q1*1.28*/ + Word16 mem[], /* i/o: memory of gain of pitch clipping algorithm [2.56x,Q14,Q8,Q0,Q14,Q14]*/ + const Word16 Opt_AMR_WB /* i : flag indicating AMR-WB IO mode Q0*/ ) { Word16 i; Word16 m; Word16 dist, dist_min; - dist_min = sub( lsf[1], lsf[0] ); + dist_min = sub( lsf[1], lsf[0] ); /* 14Q1*1.28 */ IF( Opt_AMR_WB ) { @@ -494,12 +483,12 @@ void gp_clip_test_lsf_ivas_fx( FOR( i = 2; i < m; i++ ) { - dist = sub( lsf[i], lsf[i - 1] ); + dist = sub( lsf[i], lsf[i - 1] ); /* 14Q1*1.28 */ dist_min = s_min( dist, dist_min ); } // dist = 0.8f * mem[0] + 0.2f * dist_min; - dist = mac_r( L_mult( 26214 /*0.8f Q15*/, mem[0] ), 6554 /*0.2f Q15*/, dist_min ); + dist = mac_r( L_mult( 26214 /*0.8f Q15*/, mem[0] ), 6554 /*0.2f Q15*/, dist_min ); /* 2.56x */ test(); test(); @@ -517,7 +506,7 @@ void gp_clip_test_lsf_ivas_fx( move16(); } - mem[0] = dist; + mem[0] = dist; /* 2.56x */ move16(); return; diff --git a/lib_enc/gs_enc.c b/lib_enc/gs_enc.c deleted file mode 100644 index 4468194bed6aad608dafe247b2c6535e8bbd4593..0000000000000000000000000000000000000000 --- a/lib_enc/gs_enc.c +++ /dev/null @@ -1,56 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include -#include "cnst.h" -#include "rom_com.h" -#include "prot.h" -#include "ivas_prot.h" -#include "wmc_auto.h" -#include "prot_fx.h" - -/*-------------------------------------------------------------------* - * Local function prototypes - *-------------------------------------------------------------------*/ - - -/*-------------------------------------------------------------------* - * GSC_enc_init() - * - * Initialize GSC encoder state structure - *-------------------------------------------------------------------*/ diff --git a/lib_enc/gs_enc_fx.c b/lib_enc/gs_enc_fx.c index bc2e2a09108b62e5bfc391af6cc99c5f14dd5ffe..375d4c2cf3dbf9bbc092a1ee3e0a523d3ea480f3 100644 --- a/lib_enc/gs_enc_fx.c +++ b/lib_enc/gs_enc_fx.c @@ -6,8 +6,6 @@ #include "cnst.h" #include "rom_com_fx.h" #include "rom_com.h" -//#include "prot_fx.h" -#include "prot.h" /* Function prototypes */ #include "prot_fx.h" /* Function prototypes */ #include "prot_fx_enc.h" /* Function prototypes */ @@ -679,7 +677,11 @@ void encod_audio_ivas_fx( *--------------------------------------------------------------------------------------*/ edct_16fx( dct_epit, exc, st_fx->L_frame, 7, st_fx->element_mode ); + Scale_sig( exc, st_fx->L_frame, sub( Q_new, Q_exc ) ); edct_16fx( exc_wo_nf, exc_wo_nf, st_fx->L_frame, 7, st_fx->element_mode ); + Scale_sig( exc_wo_nf, st_fx->L_frame, sub( Q_new, Q_exc ) ); + Q_exc = Q_new; + move16(); /*--------------------------------------------------------------------------------------* * Remove potential pre-echo in case an onset has been detected *--------------------------------------------------------------------------------------*/ @@ -781,10 +783,6 @@ void gsc_enc_fx( Word16 imaxpulse_fx[NB_SFM]; Word16 Q_tmp; Word16 seed_init; -#ifdef ADD_LRTD - Word16 max_eq_val; - Word32 max_eq; -#endif GSC_ENC_HANDLE hGSCEnc = st_fx->hGSCEnc; BSTR_ENC_HANDLE hBstr = st_fx->hBstr; @@ -892,18 +890,6 @@ void gsc_enc_fx( move16(); set16_fx( bitallocation_band, 0, MBANDS_GN_BITALLOC16k ); -#ifdef ADD_LRTD - max_eq = 0; - max_eq_val = 1.0f; - - IF( ( ( ( LT_32( st_fx->core_brate, ACELP_7k20 ) && EQ_16( st_fx->GSC_noisy_speech, 1 ) ) || LT_32( st_fx->core_brate, 6000 ) ) && LE_16( st_fx->coder_type, UNVOICED ) ) || GE_16( st_fx->GSC_IVAS_mode, 1 ) ) - { - j = emaximum( concat_out, nb_subbands * 16, &max_eq ); - max_eq = max_eq_val / ( fabsf( concat_out[j] ) + 0.01f ); - max_eq = min( max_eq_val, max_eq ); - } -#endif - FOR( j = 0; j < nb_subbands; j++ ) { Copy( concat_out + j * 16, exc_diffQ + max_ener_band[j] * 16, 16 ); /*Q12*/ @@ -959,26 +945,7 @@ void gsc_enc_fx( * Find x pulses between 1.6-3.2kHz to code in the spectrum of the residual signal * Gain is based on the inter-correlation gain between the pulses found and residual signal *--------------------------------------------------------------------------------------*/ -#ifdef ADD_LRTD - test(); - test(); - test(); - IF( GE_16( st_fx->GSC_IVAS_mode, 1 ) && EQ_16( st_fx->GSC_noisy_speech, 1 ) ) - { - FOR( i = 64; i < st->L_frame; i++ ) - { - exc_diffQ[i] *= max_eq; - } - } - ELSE IF( LT_32( st_fx->core_brate, ACELP_7k20 ) && EQ_16( st_fx->GSC_noisy_speech, 1 ) && LE_16( st_fx->coder_type, UNVOICED ) ) - { - FOR( i = 0; i < L_FRAME; i++ ) - { - exc_diffQ[i] *= max_eq; - } - } - else -#endif + { freq_dnw_scaling_fx( hGSCEnc->cor_strong_limit, st_fx->coder_type, hGSCEnc->noise_lev, st_fx->core_brate, exc_diffQ, Q_PVQ_OUT, st_fx->L_frame ); } @@ -1328,11 +1295,7 @@ static Word16 edyn_fx( /* o : ratio of max to mean */ { L_tmp = L_mult0( vec[j], vec[j] ); /*2*Qnew*/ ener_max = L_max( ener_max, L_tmp ); -#ifdef BASOP_NOGLOB ener_mean = L_add_o( ener_mean, L_tmp, &Overflow ); -#else /* BASOP_NOGLOB */ - ener_mean = L_add( ener_mean, L_tmp ); -#endif /* BASOP_NOGLOB */ } /*dyn = 10.0f * (ener_max / ener_mean);*/ ener_mean = Mult_32_16( ener_mean, div_s( 1, lvec ) ); /*2*Qnew*/ @@ -1340,11 +1303,7 @@ static Word16 edyn_fx( /* o : ratio of max to mean */ IF( ener_mean > 0 ) { exp1 = norm_l( ener_mean ); -#ifdef BASOP_NOGLOB tmp1 = round_fx_o( L_shl( ener_mean, exp1 ), &Overflow ); -#else /* BASOP_NOGLOB */ - tmp1 = round_fx( L_shl( ener_mean, exp1 ) ); -#endif exp1 = sub( 30, exp1 ); exp2 = norm_l( ener_max ); diff --git a/lib_enc/guided_plc_enc.c b/lib_enc/guided_plc_enc.c deleted file mode 100644 index c10866a4954c952ac75b79ee1c5b5e68842161ae..0000000000000000000000000000000000000000 --- a/lib_enc/guided_plc_enc.c +++ /dev/null @@ -1,42 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include -#include "prot.h" -#include "stat_enc.h" -#include "wmc_auto.h" diff --git a/lib_enc/guided_plc_enc_fx.c b/lib_enc/guided_plc_enc_fx.c index 6470e0a3c88fa8bcf420af79d496ecb0f73d570b..9aa2ecb65550f4be98ba9615395e56d73888cd2b 100644 --- a/lib_enc/guided_plc_enc_fx.c +++ b/lib_enc/guided_plc_enc_fx.c @@ -161,11 +161,7 @@ static void coderLookAheadInnovation( ps_e = add( alp_e, ps_e ); BASOP_SATURATE_WARNING_OFF_EVS -#ifdef BASOP_NOGLOB max_ps_tmp = L_shl_o( max_ps, sub( max_ps_e, ps_e ), &Overflow ); -#else /* BASOP_NOGLOB */ - max_ps_tmp = L_shl( max_ps, sub( max_ps_e, ps_e ) ); -#endif /* BASOP_NOGLOB */ BASOP_SATURATE_WARNING_ON_EVS @@ -452,21 +448,13 @@ void updateSpecPowDiffuseIdx_fx( FOR( k = 1; k < 4; k++ ) { -#ifdef BASOP_NOGLOB st->mean_gc[1] = L_add_o( st->mean_gc[1], st->gain_code[k], &Overflow ); -#else /* BASOP_NOGLOB */ - st->mean_gc[1] = L_add( st->mean_gc[1], st->gain_code[k] ); -#endif min_gp = s_min( min_gp, st->bpf_gainT[k] ); } /* Suppress saturation warning in threshold comparison. */ test(); -#ifdef BASOP_NOGLOB if ( LT_32( st->mean_gc[1], L_add_o( st->mean_gc[0], Mpy_32_16_r( st->mean_gc[0], 3211 /*0.098 Q15*/ ), &Overflow ) ) || GT_16( min_gp, 13435 /*0.82 Q14*/ ) ) -#else - if ( LT_32( st->mean_gc[1], L_add( st->mean_gc[0], Mpy_32_16_r( st->mean_gc[0], 3211 /*0.098 Q15*/ ) ) ) || GT_16( min_gp, 13435 /*0.82 Q14*/ ) ) -#endif { move16(); st->glr_idx[0] = 0; diff --git a/lib_enc/hf_cod_amrwb.c b/lib_enc/hf_cod_amrwb.c deleted file mode 100644 index d1de09bc73bcde0f9193c0b1d468183cb122cda9..0000000000000000000000000000000000000000 --- a/lib_enc/hf_cod_amrwb.c +++ /dev/null @@ -1,43 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include -#include "cnst.h" -#include "prot.h" -#include "rom_com.h" -#include "wmc_auto.h" diff --git a/lib_enc/hf_cod_amrwb_fx.c b/lib_enc/hf_cod_amrwb_fx.c index 7c2060fa8663df927207db78e0a59227df997424..e21a8bd677e665f1e9d36c61d1311074ee56c165 100644 --- a/lib_enc/hf_cod_amrwb_fx.c +++ b/lib_enc/hf_cod_amrwb_fx.c @@ -107,14 +107,10 @@ void hf_cod_fx( ener_exc_fx = dot_prod_satcontr( exc_fx, exc_fx, Q_exc, Q_exc, &q1, L_SUBFR ); ener_hf_fx = dot_prod_satcontr( HF_fx, HF_fx, -3, -3, &q2, L_SUBFR16k ); - scale_fx = div_s( shl( 1, 14 ), ener_exc_fx ); /*Q(29-q1) */ - L_tmp = L_mult( ener_hf_fx, scale_fx ); /*30-q1+q2 */ - q2 = sub( q1, q2 ); /*30-q2 */ -#ifdef BASOP_NOGLOB + scale_fx = div_s( shl( 1, 14 ), ener_exc_fx ); /*Q(29-q1) */ + L_tmp = L_mult( ener_hf_fx, scale_fx ); /*30-q1+q2 */ + q2 = sub( q1, q2 ); /*30-q2 */ scale_fx = round_fx( Isqrt( L_shl_o( L_tmp, sub( q2, 26 ), &Overflow ) ) ); /*Q13 */ -#else /* BASOP_NOGLOB */ - scale_fx = round_fx( Isqrt( L_shl( L_tmp, sub( q2, 26 ) ) ) ); /*Q13 */ -#endif /* BASOP_NOGLOB */ pt1 = HF_fx; @@ -187,14 +183,10 @@ void hf_cod_fx( ener_hf_fx = dot_prod_satcontr( HF_syn_fx, HF_syn_fx, 0, 0, &q2, L_SUBFR16k ); ener_input_fx = dot_prod_satcontr( HF_SP_fx, HF_SP_fx, 0, 0, &q1, L_SUBFR16k ); - HF_calc_gain_fx = div_s( shl( 1, 14 ), ener_input_fx ); /*Q(29-q1) */ - L_tmp = L_mult( ener_hf_fx, HF_calc_gain_fx ); /*30-q1+q2 */ - q2 = sub( q1, q2 ); /*30-q2 */ -#ifdef BASOP_NOGLOB + HF_calc_gain_fx = div_s( shl( 1, 14 ), ener_input_fx ); /*Q(29-q1) */ + L_tmp = L_mult( ener_hf_fx, HF_calc_gain_fx ); /*30-q1+q2 */ + q2 = sub( q1, q2 ); /*30-q2 */ HF_calc_gain_fx = round_fx_o( Isqrt( L_shl_sat( L_tmp, sub( q2, 20 ) ) ), &Overflow ); /*Q10 */ -#else /* BASOP_NOGLOB */ - HF_calc_gain_fx = round_fx( Isqrt( L_shl( L_tmp, sub( q2, 20 ) ) ) ); /*Q10 */ -#endif /* set energy of HF synthesis to energy of original HF: diff --git a/lib_enc/hq_classifier_enc.c b/lib_enc/hq_classifier_enc.c deleted file mode 100644 index 273cba75c8c048ceec04ae71f9440227c1995d90..0000000000000000000000000000000000000000 --- a/lib_enc/hq_classifier_enc.c +++ /dev/null @@ -1,52 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include -#include "cnst.h" -#include "prot.h" -#include "rom_com.h" -#include "wmc_auto.h" -#include "prot_fx.h" -#include "prot_fx_enc.h" -/*-----------------------------------------------------------------* - * Local constants - *-----------------------------------------------------------------*/ - -/*-----------------------------------------------------------------* - * Local function prototypes - *-----------------------------------------------------------------*/ diff --git a/lib_enc/hq_classifier_enc_fx.c b/lib_enc/hq_classifier_enc_fx.c index b63ebeb3af9c631cb03c53907e5d3824c2a4b17b..944cb26491e4e19ddd932fa474b2991618e7878e 100644 --- a/lib_enc/hq_classifier_enc_fx.c +++ b/lib_enc/hq_classifier_enc_fx.c @@ -8,7 +8,6 @@ #include "rom_com_fx.h" /* Static table prototypes */ #include "rom_com.h" /* Static table prototypes */ #include "prot_fx.h" /* Function prototypes */ -#include "prot.h" /* Function prototypes */ #include "prot_fx_enc.h" /* Function prototypes */ /*-----------------------------------------------------------------* @@ -28,10 +27,10 @@ * Local functions *-----------------------------------------------------------------*/ -void hvq_classifier_fx( const Word32 *input, Word16 *prev_Npeaks, Word16 *prev_peaks, Word16 *hqswb_clas, Word16 *Npeaks, Word16 *peaks, const Word32 L_core_brate, const Word16 last_core, Word32 *L_nf_gains, Word16 *hvq_hangover, Word32 *L_pe_gains ); +void hvq_classifier_fx( const Word32 *input /*Q12*/, Word16 *prev_Npeaks, Word16 *prev_peaks, Word16 *hqswb_clas, Word16 *Npeaks, Word16 *peaks, const Word32 L_core_brate, const Word16 last_core, Word32 *L_nf_gains /*Q12*/, Word16 *hvq_hangover, Word32 *L_pe_gains /*Q12*/ ); static Word16 hf_spectrum_sparseness_fx( Encoder_State *st, /* i/o: encoder state structure */ - const Word32 *coefs_fx /* i : MDCT spectrum */ + const Word32 *coefs_fx /* i : MDCT spectrum Q12*/ ); /*--------------------------------------------------------------------------* * hf_spectrum_sparseness() @@ -64,8 +63,8 @@ static Word16 hf_spectrum_sparseness_fx( Word16 inv_rms32_e = 0; move16(); - crest_lp_fx = &st->hHQ_core->crest_lp_fx; - crest_mod_lp_fx = &st->hHQ_core->crest_mod_lp_fx; + crest_lp_fx = &st->hHQ_core->crest_lp_fx; /* &st->hHQ_core->crest_lp_q */ + crest_mod_lp_fx = &st->hHQ_core->crest_mod_lp_fx; /* &st->hHQ_core->crest_mod_lp_q */ result = TRUE; move16(); @@ -74,7 +73,7 @@ static Word16 hf_spectrum_sparseness_fx( FOR( i = 0; i < L_SPEC_HB; i++ ) { - A_fx[i] = L_abs( coefs_fx[i + L_SPEC_HB] ); + A_fx[i] = L_abs( coefs_fx[i + L_SPEC_HB] ); /* Q12 */ move32(); } low_count_fx = 0; @@ -88,24 +87,25 @@ static Word16 hf_spectrum_sparseness_fx( IF( Amax_fx == 0 ) { /* For all-zero input the crest is 1.0 */ - crest_fx = L_shl( 1, st->hHQ_core->crest_lp_q ); - crest_mod_fx = L_shl( 1, st->hHQ_core->crest_mod_lp_q ); + crest_fx = L_shl( 1, st->hHQ_core->crest_lp_q ); /* &st->hHQ_core->crest_lp_q */ + crest_mod_fx = L_shl( 1, st->hHQ_core->crest_mod_lp_q ); /* &st->hHQ_core->crest_mod_lp_q */ low_count_fx = 0; move16(); } ELSE { #endif - thr_fx = Mpy_32_32( Amax_fx, PEAK_THRESHOLD_FX ); - movmean_fx = 0; /* avoid uninitialized warning */ - // p_num = &inv_tbl[HALF_WIN_LENGTH + 1]; /* Table for division 1./(11:21) */ - p_num_fx = &inv_tbl_fx[HALF_WIN_LENGTH + 1]; /* Table for division 1./(11:21) */ + thr_fx = Mpy_32_32( Amax_fx, PEAK_THRESHOLD_FX ); /* Q12 */ + movmean_fx = 0; /* avoid uninitialized warning */ + move32(); + // p_num = &inv_tbl[HALF_WIN_LENGTH + 1]; /* Table for division 1./(11:21) */ + p_num_fx = &inv_tbl_fx[HALF_WIN_LENGTH + 1]; /* Table for division 1./(11:21) Q15*/ FOR( i = 0; i < L_SPEC_HB; i++ ) { // inv_rms += A[i] * A[i]; - inv_rms_fx = W_add( inv_rms_fx, W_shr( W_mult0_32_32( A_fx[i], A_fx[i] ), Q9 ) ); // 2*Q12 -Q9 (Q9 for guard bits + inv_rms_fx = W_add( inv_rms_fx, W_shr( W_mult0_32_32( A_fx[i], A_fx[i] ), Q9 ) ); // 2*Q12 -Q9 (Q9 for guard bits) Q15 - if ( LT_32( A_fx[i], thr_fx ) ) + IF( LT_32( A_fx[i], thr_fx ) ) { low_count_fx = add( low_count_fx, 1 ); } @@ -136,27 +136,27 @@ static Word16 hf_spectrum_sparseness_fx( } } - if ( LT_32( crest_mod_fx, movmean_fx ) ) + IF( LT_32( crest_mod_fx, movmean_fx ) ) { crest_mod_fx = movmean_fx; // Q12 move32(); } } Word16 l_shift = W_norm( inv_rms_fx ); - inv_rms32_fx = W_extract_h( W_shl( inv_rms_fx, l_shift ) ); // Q15+l_shift-32 - Word16 q_rms = sub( add( Q15, l_shift ), 32 ); // q_rms - inv_rms32_div_fx = BASOP_Util_Divide3232_Scale_cadence( inv_rms32_fx, L_SPEC_HB, &inv_rms32_e ); + inv_rms32_fx = W_extract_h( W_shl( inv_rms_fx, l_shift ) ); // Q15+l_shift-32 + Word16 q_rms = sub( add( Q15, l_shift ), 32 ); // q_rms + inv_rms32_div_fx = BASOP_Util_Divide3232_Scale_cadence( inv_rms32_fx, L_SPEC_HB, &inv_rms32_e ); /* Q31-inv_rms32_e */ inv_rms32_e = sub( 31, add( sub( Q31, inv_rms32_e ), q_rms ) ); // inv_rms = 1.0f / (float) sqrtf( inv_rms / L_SPEC_HB ); - inv_rms32_fx = ISqrt32( inv_rms32_div_fx, &inv_rms32_e ); + inv_rms32_fx = ISqrt32( inv_rms32_div_fx, &inv_rms32_e ); /* Q31-inv_rms32_e */ - crest_fx = Mpy_32_32( Amax_fx, inv_rms32_fx ); // Q12 + (Q31-inv_rms32_e) -Q31 = Q12 - inv_rms32_e - crest_mod_fx = Mpy_32_32( crest_mod_fx, inv_rms32_fx ); // Q12 + (Q31-inv_rms32_e) -Q31 = Q12 - inv_rms32_e - *crest_lp_fx = L_shr( *crest_lp_fx, sub( st->hHQ_core->crest_lp_q, sub( Q12, inv_rms32_e ) ) ); + crest_fx = Mpy_32_32( Amax_fx, inv_rms32_fx ); // Q12 + (Q31-inv_rms32_e) -Q31 = Q12 - inv_rms32_e + crest_mod_fx = Mpy_32_32( crest_mod_fx, inv_rms32_fx ); // Q12 + (Q31-inv_rms32_e) -Q31 = Q12 - inv_rms32_e + *crest_lp_fx = L_shr( *crest_lp_fx, sub( st->hHQ_core->crest_lp_q, sub( Q12, inv_rms32_e ) ) ); /* Q12-inv_rms32_e */ move32(); st->hHQ_core->crest_lp_q = sub( Q12, inv_rms32_e ); move16(); - *crest_mod_lp_fx = L_shr( *crest_mod_lp_fx, sub( st->hHQ_core->crest_mod_lp_q, sub( Q12, inv_rms32_e ) ) ); + *crest_mod_lp_fx = L_shr( *crest_mod_lp_fx, sub( st->hHQ_core->crest_mod_lp_q, sub( Q12, inv_rms32_e ) ) ); /* Q12-inv_rms32_e */ move32(); st->hHQ_core->crest_mod_lp_q = sub( Q12, inv_rms32_e ); move16(); @@ -179,7 +179,7 @@ static Word16 hf_spectrum_sparseness_fx( } } - return result; + return result; /* Q0 */ } /*--------------------------------------------------------------------------* * hq_classifier_enc_fx() @@ -216,7 +216,8 @@ Word16 hq_classifier_enc_fx( /* o : Consumed bits IF( EQ_16( length, L_FRAME32k ) && NE_16( is_transient, 1 ) && LE_32( st_fx->core_brate, HQ_32k ) && EQ_16( st_fx->bwidth, st_fx->last_bwidth ) ) { /* Detect HQ_HARMONIC mode */ - *hqswb_clas = peak_avrg_ratio_fx( st_fx->total_brate, coefs, NUMC_N + 96, &hHQ_core->mode_count, &hHQ_core->mode_count1, 12 ); + *hqswb_clas = peak_avrg_ratio_fx( st_fx->total_brate, coefs, NUMC_N + 96, &hHQ_core->mode_count, &hHQ_core->mode_count1, 12 ); /* Q0 */ + move16(); /* Detect harmonic VQ mode HQ_HVQ */ hvq_classifier_fx( coefs, &hHQ_core->prev_Npeaks, hHQ_core->prev_peaks, hqswb_clas, Npeaks, peaks, st_fx->core_brate, st_fx->last_core, @@ -229,7 +230,8 @@ Word16 hq_classifier_enc_fx( /* o : Consumed bits IF( EQ_16( length, L_FRAME48k ) && NE_16( is_transient, 1 ) && LE_32( st_fx->core_brate, HQ_32k ) && EQ_16( st_fx->bwidth, st_fx->last_bwidth ) ) { /* Detect HQ_HARMONIC mode */ - *hqswb_clas = peak_avrg_ratio_fx( st_fx->total_brate, coefs, NUMC_N + 96, &hHQ_core->mode_count, &hHQ_core->mode_count1, 12 ); + *hqswb_clas = peak_avrg_ratio_fx( st_fx->total_brate, coefs, NUMC_N + 96, &hHQ_core->mode_count, &hHQ_core->mode_count1, 12 ); /* Q0 */ + move16(); /* Detect harmonic VQ mode HQ_HVQ */ hvq_classifier_fx( coefs, &hHQ_core->prev_Npeaks, hHQ_core->prev_peaks, hqswb_clas, Npeaks, peaks, st_fx->core_brate, st_fx->last_core, nf_gains, &hHQ_core->hvq_hangover, pe_gains ); @@ -239,7 +241,7 @@ Word16 hq_classifier_enc_fx( /* o : Consumed bits test(); IF( EQ_16( length, L_FRAME48k ) && LE_32( st_fx->core_brate, HQ_32k ) && EQ_16( *hqswb_clas, HQ_NORMAL ) ) { - *hqswb_clas = HQ_GEN_FB; + *hqswb_clas = HQ_GEN_FB; /* Q0 */ move16(); } @@ -276,7 +278,7 @@ Word16 hq_classifier_enc_fx( /* o : Consumed bits test(); IF( EQ_16( *hqswb_clas, HQ_NORMAL ) && EQ_16( length, L_FRAME32k ) && LE_32( st_fx->core_brate, HQ_32k ) ) { - *hqswb_clas = HQ_GEN_SWB; + *hqswb_clas = HQ_GEN_SWB; /* Q0 */ move16(); } #else @@ -289,7 +291,7 @@ Word16 hq_classifier_enc_fx( /* o : Consumed bits max_brate = HQ_32k; move32(); - if ( GT_16( st_fx->element_mode, EVS_MONO ) ) + if ( st_fx->element_mode > EVS_MONO ) { max_brate = HQ_48k; move32(); @@ -320,6 +322,7 @@ Word16 hq_classifier_enc_fx( /* o : Consumed bits harmonic_decision = hf_spectrum_sparseness( st, coefs ); #else harmonic_decision = 0; + move16(); #endif test(); IF( EQ_16( *hqswb_clas, HQ_HARMONIC ) && !harmonic_decision ) @@ -391,12 +394,12 @@ Word16 hq_classifier_enc_ivas_fx( /* o : Consumed bi move32(); } - *hqswb_clas = HQ_NORMAL; + *hqswb_clas = HQ_NORMAL; /* Q0 */ bits = 1; move16(); IF( EQ_16( is_transient, 1 ) ) { - *hqswb_clas = HQ_TRANSIENT; + *hqswb_clas = HQ_TRANSIENT; /* Q0 */ move16(); } @@ -410,7 +413,7 @@ Word16 hq_classifier_enc_ivas_fx( /* o : Consumed bi IF( !is_transient && EQ_16( st_fx->bwidth, st_fx->last_bwidth ) ) { /* Detect HQ_HARMONIC mode */ - *hqswb_clas = peak_avrg_ratio_ivas_fx( st_fx->total_brate, coefs, NUMC_N + 96, &hHQ_core->mode_count, &hHQ_core->mode_count1, 12 ); + *hqswb_clas = peak_avrg_ratio_ivas_fx( st_fx->total_brate, coefs, NUMC_N + 96, &hHQ_core->mode_count, &hHQ_core->mode_count1, 12 ); /* Q0 */ harmonic_decision = hf_spectrum_sparseness_fx( st_fx, coefs ); @@ -418,7 +421,7 @@ Word16 hq_classifier_enc_ivas_fx( /* o : Consumed bi test(); IF( EQ_16( *hqswb_clas, HQ_HARMONIC ) && !harmonic_decision ) { - *hqswb_clas = HQ_NORMAL; + *hqswb_clas = HQ_NORMAL; /* Q0 */ move16(); } ELSE @@ -443,17 +446,17 @@ Word16 hq_classifier_enc_ivas_fx( /* o : Consumed bi { IF( EQ_16( length, L_SPEC32k ) ) { - *hqswb_clas = HQ_GEN_SWB; + *hqswb_clas = HQ_GEN_SWB; /* Q0 */ move16(); } ELSE IF( EQ_16( length, L_SPEC48k ) ) { - *hqswb_clas = HQ_GEN_FB; + *hqswb_clas = HQ_GEN_FB; /* Q0 */ move16(); } } - return bits; + return bits; /* Q0 */ } /*--------------------------------------------------------------------------* * peak_avrg_ratio() @@ -461,9 +464,9 @@ Word16 hq_classifier_enc_ivas_fx( /* o : Consumed bi * Classify the input signal and decide if it has a harmonic structure *--------------------------------------------------------------------------*/ Word16 peak_avrg_ratio_ivas_fx( - const Word32 total_brate, /* i : total bitrate */ + const Word32 total_brate, /* i : total bitrate Q0*/ const Word32 *input_hi_fx, /* i : input signal Q_coeff */ - const Word16 length, /* i : number of coefficients */ + const Word16 length, /* i : number of coefficients Q0*/ Word16 *mode_count, /* i/o: HQ_HARMONIC mode count Q0*/ Word16 *mode_count1, /* i/o: HQ_NORMAL mode count Q0*/ Word16 Q_coeff ) @@ -488,6 +491,7 @@ Word16 peak_avrg_ratio_ivas_fx( k1 = 0; move16(); q = 96; /* q used for indexing */ + move16(); FOR( i = 3; i < 17; i++ ) { @@ -500,11 +504,12 @@ Word16 peak_avrg_ratio_ivas_fx( input_abs_fx[q] = L_shr( input_abs_fx[q], 5 ); /*Q_coeff-5 */ move32(); mean_fx = L_add( mean_fx, input_abs_fx[q] ); /*Q_coeff-5 */ - IF( GT_32( input_abs_fx[q], peak_fx ) ) + if ( GT_32( input_abs_fx[q], peak_fx ) ) { peak_fx = input_abs_fx[q]; /*Q_coeff-5 */ + move32(); } - q = add( q, 1 ); + q += 1; } IF( LT_16( i, 8 ) ) @@ -528,26 +533,30 @@ Word16 peak_avrg_ratio_ivas_fx( test(); IF( GE_16( add( k, k1 ), 10 ) && GT_16( k1, 5 ) ) { - if ( LT_16( *mode_count, 8 ) ) + IF( LT_16( *mode_count, 8 ) ) { *mode_count = add( *mode_count, 1 ); + move16(); } - if ( *mode_count1 > 0 ) + IF( *mode_count1 > 0 ) { *mode_count1 = sub( *mode_count1, 1 ); + move16(); } } ELSE { - if ( LT_16( *mode_count1, 8 ) ) + IF( LT_16( *mode_count1, 8 ) ) { *mode_count1 = add( *mode_count1, 1 ); + move16(); } - if ( *mode_count > 0 ) + IF( *mode_count > 0 ) { *mode_count = sub( *mode_count, 1 ); + move16(); } } @@ -558,12 +567,12 @@ Word16 peak_avrg_ratio_ivas_fx( test(); test(); - if ( ( GE_16( add( k, k1 ), 5 ) && GT_16( k1, 2 ) && LT_32( total_brate, HQ_BWE_CROSSOVER_BRATE ) ) || ( ( ( GE_16( add( k, k1 ), 10 ) && GT_16( k1, 5 ) ) || GE_16( *mode_count, 5 ) ) && LT_16( *mode_count1, 5 ) ) ) + IF( ( GE_16( add( k, k1 ), 5 ) && GT_16( k1, 2 ) && LT_32( total_brate, HQ_BWE_CROSSOVER_BRATE ) ) || ( ( ( GE_16( add( k, k1 ), 10 ) && GT_16( k1, 5 ) ) || GE_16( *mode_count, 5 ) ) && LT_16( *mode_count1, 5 ) ) ) { hqswb_clas = HQ_HARMONIC; move16(); } - return hqswb_clas; + return hqswb_clas; /* Q0 */ } /*--------------------------------------------------------------------------* * peak_avrg_ratio() @@ -571,11 +580,11 @@ Word16 peak_avrg_ratio_ivas_fx( * Classify the input signal and decide if it has a harmonic structure *--------------------------------------------------------------------------*/ Word16 peak_avrg_ratio_fx( - const Word32 total_brate, /* i : total bitrate */ - const Word32 *input_hi_fx, /* i : input signal */ - const Word16 length, /* i : number of coefficients */ - Word16 *mode_count, /* i/o: HQ_HARMONIC mode count */ - Word16 *mode_count1, /* i/o: HQ_NORMAL mode count */ + const Word32 total_brate, /* i : total bitrate Q0*/ + const Word32 *input_hi_fx, /* i : input signal Q_coeff*/ + const Word16 length, /* i : number of coefficients Q0*/ + Word16 *mode_count, /* i/o: HQ_HARMONIC mode count Q0*/ + Word16 *mode_count1, /* i/o: HQ_NORMAL mode count Q0*/ Word16 Q_coeff ) { Word16 i, j, q, k, k1, hqswb_clas; @@ -585,7 +594,7 @@ Word16 peak_avrg_ratio_fx( FOR( i = 96; i < length; i++ ) { - input_abs_fx[i] = L_abs( input_hi_fx[i] ); + input_abs_fx[i] = L_abs( input_hi_fx[i] ); /* Q_coeff */ } hqswb_clas = HQ_NORMAL; @@ -597,6 +606,7 @@ Word16 peak_avrg_ratio_fx( k1 = 0; move16(); q = 96; /* q used for indexing */ + move16(); FOR( i = 3; i < 17; i++ ) { @@ -607,12 +617,14 @@ Word16 peak_avrg_ratio_fx( FOR( j = 0; j < 32; j++ ) { input_abs_fx[q] = L_shr( input_abs_fx[q], 5 ); /*Q_coeff-5 */ - mean_fx = L_add( mean_fx, input_abs_fx[q] ); /*Q_coeff-5 */ - IF( GT_32( input_abs_fx[q], peak_fx ) ) + move32(); + mean_fx = L_add( mean_fx, input_abs_fx[q] ); /*Q_coeff-5 */ + if ( GT_32( input_abs_fx[q], peak_fx ) ) { peak_fx = input_abs_fx[q]; /*Q_coeff-5 */ + move32(); } - q++; + q += 1; } IF( LT_16( i, 8 ) ) @@ -636,26 +648,30 @@ Word16 peak_avrg_ratio_fx( test(); IF( GE_16( add( k, k1 ), 10 ) && GT_16( k1, 5 ) ) { - if ( LT_16( *mode_count, 8 ) ) + IF( LT_16( *mode_count, 8 ) ) { *mode_count = add( *mode_count, 1 ); + move16(); } - if ( *mode_count1 > 0 ) + IF( *mode_count1 > 0 ) { *mode_count1 = sub( *mode_count1, 1 ); + move16(); } } ELSE { - if ( LT_16( *mode_count1, 8 ) ) + IF( LT_16( *mode_count1, 8 ) ) { *mode_count1 = add( *mode_count1, 1 ); + move16(); } - if ( *mode_count > 0 ) + IF( *mode_count > 0 ) { *mode_count = sub( *mode_count, 1 ); + move16(); } } @@ -666,7 +682,7 @@ Word16 peak_avrg_ratio_fx( test(); test(); #ifndef SOLVED_COMP_ENC_DEC /*This affect BE even if it shouldn't*/ - if ( ( GE_16( add( k, k1 ), 5 ) && GT_16( k1, 2 ) && EQ_32( total_brate, HQ_24k40 ) ) || ( ( ( GE_16( add( k, k1 ), 10 ) && GT_16( k1, 5 ) ) || GE_16( *mode_count, 5 ) ) && LT_16( *mode_count1, 5 ) ) ) + IF( ( GE_16( add( k, k1 ), 5 ) && GT_16( k1, 2 ) && EQ_32( total_brate, HQ_24k40 ) ) || ( ( ( GE_16( add( k, k1 ), 10 ) && GT_16( k1, 5 ) ) || GE_16( *mode_count, 5 ) ) && LT_16( *mode_count1, 5 ) ) ) #else if ( ( GE_16( add( k, k1 ), 5 ) && GT_16( k1, 2 ) && LT_32( total_brate, HQ_BWE_CROSSOVER_BRATE ) ) || ( ( ( GE_16( add( k, k1 ), 10 ) && GT_16( k1, 5 ) ) || GE_16( *mode_count, 5 ) ) && LT_16( *mode_count1, 5 ) ) ) #endif @@ -675,7 +691,7 @@ Word16 peak_avrg_ratio_fx( move16(); } - return hqswb_clas; + return hqswb_clas; /* Q0 */ } /*--------------------------------------------------------------------------* @@ -738,19 +754,19 @@ void hvq_classifier_ivas_fx( { nsub = HVQ_NSUB_24k; move16(); - inv_nsub = 4681; - move16(); /* 1/7 in Q15 */ - inv_gains_nsub = 10923; - move16(); /* 1/3 in Q15 */ + inv_nsub = 4681; /* 1/7 in Q15 */ + move16(); + inv_gains_nsub = 10923; /* 1/3 in Q15 */ + move16(); } ELSE { nsub = HVQ_NSUB_32k; move16(); - inv_nsub = 3277; - move16(); /* 1/10 in Q15 */ - inv_gains_nsub = 6554; - move16(); /* 1/5 in Q15 */ + inv_nsub = 3277; /* 1/10 in Q15 */ + move16(); + inv_gains_nsub = 6554; /* 1/5 in Q15 */ + move16(); } N = shl( nsub, 5 ); /* Mult by 32 (HVQ_BW) */ @@ -761,10 +777,11 @@ void hvq_classifier_ivas_fx( { FOR( i = 0; i < N; i++ ) { - L_input_abs[i] = L_abs( input[i] ); - if ( L_input_abs[i] > L_input_max ) + L_input_abs[i] = L_abs( input[i] ); /* Q12 */ + move16(); + IF( GT_32( L_input_abs[i], L_input_max ) ) { - L_input_max = L_input_abs[i]; + L_input_max = L_input_abs[i]; /* Q12 */ move16(); } } @@ -773,10 +790,10 @@ void hvq_classifier_ivas_fx( *Npeaks = 0; move16(); - L_nf = 3276800; - move32(); /* 800 in Q12 */ - L_pe = 3276800; - move32(); /* 800 in Q12 */ + L_nf = 3276800; /* 800 in Q12 */ + move32(); + L_pe = 3276800; /* 800 in Q12 */ + move32(); num_sharp_bands = 0; move16(); k = 0; @@ -798,7 +815,7 @@ void hvq_classifier_ivas_fx( FOR( j = 0; j < HVQ_BW; j++ ) { - L_d = L_input_abs[q]; + L_d = L_input_abs[q]; /* Q12 */ IF( GT_32( L_d, L_nf ) ) { /*nf = HVQ_NF_WEIGHT1 * nf + (1 - HVQ_NF_WEIGHT1) * d; */ @@ -829,13 +846,8 @@ void hvq_classifier_ivas_fx( L_pe = L_add( L_pe, L_tmp ); /*Q12 */ } -#ifdef BASOP_NOGLOB - L_nf_mean[i] = L_add_sat( L_nf_mean[i], L_nf ); - L_pe_mean[i] = L_add_sat( L_pe_mean[i], L_pe ); -#else - L_nf_mean[i] = L_add( L_nf_mean[i], L_nf ); - L_pe_mean[i] = L_add( L_pe_mean[i], L_pe ); -#endif + L_nf_mean[i] = L_add_sat( L_nf_mean[i], L_nf ); /*Q12 */ + L_pe_mean[i] = L_add_sat( L_pe_mean[i], L_pe ); /*Q12 */ move32(); move32(); IF( GT_32( L_d, L_peak ) ) @@ -843,7 +855,7 @@ void hvq_classifier_ivas_fx( L_peak = L_add( L_d, 0 ); } - q = add( q, 1 ); + q += 1; } L_nf_mean[i] = L_shr( L_nf_mean[i], 5 ); /* Divide by 5 (HVQ_BW) */ L_pe_mean[i] = L_shr( L_pe_mean[i], 5 ); /* Divide by 5 (HVQ_BW) */ @@ -885,11 +897,7 @@ void hvq_classifier_ivas_fx( sharp[i] = extract_h( L_shl( L_tmp, shift ) ); /* 30-s+s-8-16 -> Q6 */ move16(); /*sharp_dist += (sharp[i]-HVQ_SHARP_THRES); */ -#ifdef BASOP_NOGLOB - sharp_dist = add_o( sharp_dist, sub( sharp[i], HVQ_SHARP_THRES_FX ), &Overflow ); -#else - sharp_dist = add( sharp_dist, sub( sharp[i], HVQ_SHARP_THRES_FX ) ); -#endif + sharp_dist = add_o( sharp_dist, sub( sharp[i], HVQ_SHARP_THRES_FX ), &Overflow ); /* Q6 */ if ( GT_16( sharp[i], HVQ_SHARP_THRES_FX ) ) { num_sharp_bands = add( num_sharp_bands, 1 ); @@ -898,12 +906,12 @@ void hvq_classifier_ivas_fx( /* Estimate noise floor gains */ offset = s_and( nsub, 1 ); - FOR( i = 0; i < s_and( nsub, (Word16) 0xFFFE ); i++ ) + FOR( i = 0; i < ( nsub & (Word16) 0xFFFE ); i++ ) { /*(2*i+1)/nsub */ - idx = mult( add( shl( i, 1 ), 1 ), add( inv_nsub, 1 ) ); /*0+15-15 = 0 */ - L_nf_gains[idx] = L_add( L_nf_gains[idx], L_nf_mean[i + offset] ); - L_pe_gains[idx] = L_add( L_pe_gains[idx], L_pe_mean[i + offset] ); + idx = mult( add( shl( i, 1 ), 1 ), add( inv_nsub, 1 ) ); /*0+15-15 = 0 */ + L_nf_gains[idx] = L_add( L_nf_gains[idx], L_nf_mean[i + offset] ); /* Q12 */ + L_pe_gains[idx] = L_add( L_pe_gains[idx], L_pe_mean[i + offset] ); /* Q12 */ move32(); move32(); } @@ -917,7 +925,7 @@ void hvq_classifier_ivas_fx( /* Allocate available peaks */ FOR( i = 0; i < nsub; i++ ) { - avail_peaks[i] = HVQ_PA_PEAKS_SHARP1; + avail_peaks[i] = HVQ_PA_PEAKS_SHARP1; /* Q0 */ move16(); idx = mult( add( shl( i, 1 ), 1 ), add( inv_nsub, 1 ) ); /*0+15-15 = 0 */ Mpy_32_16_ss( L_nf_gains[idx], HVQ_PA_FAC_FX, &L_tmp, &lsb ); /* 12+15-15 -> Q12 */ @@ -925,12 +933,12 @@ void hvq_classifier_ivas_fx( { IF( LT_16( sharp[i], HVQ_PA_SHARP_THRES3_FX ) ) { - avail_peaks[i] = HVQ_PA_PEAKS_SHARP3; + avail_peaks[i] = HVQ_PA_PEAKS_SHARP3; /* Q0 */ move16(); } ELSE IF( LT_16( sharp[i], HVQ_PA_SHARP_THRES2_FX ) ) { - avail_peaks[i] = HVQ_PA_PEAKS_SHARP2; + avail_peaks[i] = HVQ_PA_PEAKS_SHARP2; /* Q0 */ move16(); } } @@ -940,9 +948,9 @@ void hvq_classifier_ivas_fx( /* Adjust threshold around previous peaks */ FOR( i = 0; i < *prev_Npeaks; i++ ) { - j = sub( prev_peaks[i], 2 ); - k = add( prev_peaks[i], 2 ); - p_adj = hvq_thr_adj_fx; + j = sub( prev_peaks[i], 2 ); /* Q0 */ + k = add( prev_peaks[i], 2 ); /* Q0 */ + p_adj = hvq_thr_adj_fx; /* Q15 */ FOR( q = j; q < k; q++ ) { @@ -973,16 +981,16 @@ void hvq_classifier_ivas_fx( } ELSE { - L_input_abs[num_peak_cands] = L_input_abs[i]; + L_input_abs[num_peak_cands] = L_input_abs[i]; /* Q12 */ move32(); - peak_cand_idx[num_peak_cands] = i; + peak_cand_idx[num_peak_cands] = i; /* Q0 */ move16(); num_peak_cands = add( num_peak_cands, 1 ); } } - peak_th = (Word16) BASOP_Util_Divide3232_Scale( L_add( W_extract_l( W_mult0_32_32( L_core_brate, HVQ_PEAKS_PER_DELTA_THR ) ), HVQ_PEAKS_PER_DELTA_THR_OFFS ), HVQ_PEAKS_BPS_DELTA, &temp_e ); + peak_th = extract_l( BASOP_Util_Divide3232_Scale( L_add( W_extract_l( W_mult0_32_32( L_core_brate, HVQ_PEAKS_PER_DELTA_THR ) ), HVQ_PEAKS_PER_DELTA_THR_OFFS ), HVQ_PEAKS_BPS_DELTA, &temp_e ) ); peak_th = shr( peak_th, sub( 15, temp_e ) ); /* Find peaks */ pindx = maximum_32_fx( L_input_abs, num_peak_cands, &L_m ); @@ -994,7 +1002,7 @@ void hvq_classifier_ivas_fx( idx = mult( peak_cand_idx[pindx], INV_HVQ_BW ); /* 0+15-15=0 */ IF( avail_peaks[idx] > 0 ) { - peaks[i++] = peak_cand_idx[pindx]; + peaks[i++] = peak_cand_idx[pindx]; /* Q0 */ avail_peaks[idx]--; } @@ -1055,7 +1063,7 @@ void hvq_classifier_ivas_fx( pindx = maximum_32_fx( L_input_abs, num_peak_cands, &L_m ); } - *Npeaks = i; + *Npeaks = i; /* Q0 */ move16(); IF( GT_16( *Npeaks, HVQ_MIN_PEAKS ) ) { @@ -1066,28 +1074,28 @@ void hvq_classifier_ivas_fx( test(); IF( LE_16( sharp_dist, SHARP_DIST_THRES_FX ) && *hvq_hangover < 0 ) { - *hvq_hangover = add( *hvq_hangover, 1 ); + *hvq_hangover = add( *hvq_hangover, 1 ); /* Q0 */ } ELSE { - *hqswb_clas = HQ_HVQ; + *hqswb_clas = HQ_HVQ; /* Q0 */ move16(); - *hvq_hangover = 2; + *hvq_hangover = 2; /* Q0 */ move16(); } /* update memory */ - *prev_Npeaks = *Npeaks; + *prev_Npeaks = *Npeaks; /* Q0 */ move16(); - Copy( peaks, prev_peaks, *Npeaks ); + Copy( peaks, prev_peaks, *Npeaks ); /* Q0 */ } ELSE { IF( *hvq_hangover > 0 ) { - *hqswb_clas = HQ_HVQ; + *hqswb_clas = HQ_HVQ; /* Q0 */ move16(); - *hvq_hangover = sub( *hvq_hangover, 1 ); + *hvq_hangover = sub( *hvq_hangover, 1 ); /* Q0 */ move16(); } ELSE @@ -1110,6 +1118,7 @@ void hvq_classifier_ivas_fx( Word16 Npeaks_temp = *Npeaks; *Npeaks = BASOP_Util_Divide3232_Scale( L_add( W_extract_l( W_mult0_32_32( L_core_brate, HVQ_PEAKS_PER_DELTA ) ), HVQ_PEAKS_PER_DELTA_OFFS ), HVQ_PEAKS_BPS_DELTA, &temp_e ); *Npeaks = s_min( shr( *Npeaks, sub( 15, temp_e ) ), Npeaks_temp ); + move16(); } ELSE { @@ -1167,6 +1176,7 @@ void hvq_classifier_fx( Word16 peak_cand_idx[HVQ_THRES_BIN_32k], avail_peaks[HVQ_NSUB_32k]; #ifdef BASOP_NOGLOB_DECLARE_LOCAL Flag Overflow = 0; + move32(); #endif L_input_max = L_deposit_l( 0 ); set32_fx( L_thr, 0, L_FRAME16k ); @@ -1179,19 +1189,19 @@ void hvq_classifier_fx( { nsub = HVQ_NSUB_24k; move16(); - inv_nsub = 4681; - move16(); /* 1/7 in Q15 */ - inv_gains_nsub = 10923; - move16(); /* 1/3 in Q15 */ + inv_nsub = 4681; /* 1/7 in Q15 */ + move16(); + inv_gains_nsub = 10923; /* 1/3 in Q15 */ + move16(); } ELSE { nsub = HVQ_NSUB_32k; move16(); - inv_nsub = 3277; - move16(); /* 1/10 in Q15 */ - inv_gains_nsub = 6554; - move16(); /* 1/5 in Q15 */ + inv_nsub = 3277; /* 1/10 in Q15 */ + move16(); + inv_gains_nsub = 6554; /* 1/5 in Q15 */ + move16(); } N = shl( nsub, 5 ); /* Mult by 32 (HVQ_BW) */ @@ -1202,10 +1212,10 @@ void hvq_classifier_fx( { FOR( i = 0; i < N; i++ ) { - L_input_abs[i] = L_abs( input[i] ); - if ( L_input_abs[i] > L_input_max ) + L_input_abs[i] = L_abs( input[i] ); /* Q12 */ + IF( GT_32( L_input_abs[i], L_input_max ) ) { - L_input_max = L_input_abs[i]; + L_input_max = L_input_abs[i]; /* Q12 */ move16(); } } @@ -1214,10 +1224,10 @@ void hvq_classifier_fx( *Npeaks = 0; move16(); - L_nf = 3276800; - move32(); /* 800 in Q12 */ - L_pe = 3276800; - move32(); /* 800 in Q12 */ + L_nf = 3276800; /* 800 in Q12 */ + move32(); + L_pe = 3276800; /* 800 in Q12 */ + move32(); num_sharp_bands = 0; move16(); k = 0; @@ -1233,9 +1243,13 @@ void hvq_classifier_fx( L_peak = 0; L_nf_mean[i] = 0; L_pe_mean[i] = 0; + move32(); + move32(); + move32(); FOR( j = 0; j < HVQ_BW; j++ ) { - L_d = L_input_abs[q]; + L_d = L_input_abs[q]; /* Q12 */ + move32(); IF( GT_32( L_d, L_nf ) ) { /*nf = HVQ_NF_WEIGHT1 * nf + (1 - HVQ_NF_WEIGHT1) * d; */ @@ -1266,22 +1280,21 @@ void hvq_classifier_fx( L_pe = L_add( L_pe, L_tmp ); /*Q12 */ } -#ifdef BASOP_NOGLOB - L_nf_mean[i] = L_add_sat( L_nf_mean[i], L_nf ); - L_pe_mean[i] = L_add_sat( L_pe_mean[i], L_pe ); -#else - L_nf_mean[i] = L_add( L_nf_mean[i], L_nf ); - L_pe_mean[i] = L_add( L_pe_mean[i], L_pe ); -#endif + L_nf_mean[i] = L_add_sat( L_nf_mean[i], L_nf ); /*Q12 */ + L_pe_mean[i] = L_add_sat( L_pe_mean[i], L_pe ); /*Q12 */ + move32(); + move32(); IF( GT_32( L_d, L_peak ) ) { L_peak = L_add( L_d, 0 ); } - q = add( q, 1 ); + q += 1; } L_nf_mean[i] = L_shr( L_nf_mean[i], 5 ); /* Divide by 5 (HVQ_BW) */ L_pe_mean[i] = L_shr( L_pe_mean[i], 5 ); /* Divide by 5 (HVQ_BW) */ + move32(); + move32(); /*thr_tmp = (float)pow( pe_mean[i]/nf_mean[i], HVQ_THR_POW ) * nf_mean[i]; */ exp1 = norm_l( L_nf_mean[i] ); @@ -1317,14 +1330,11 @@ void hvq_classifier_fx( Mpy_32_16_ss( L_peak, inv_nf_mean, &L_tmp, &lsb ); /* 12+33-s-15=30-s */ shift = sub( exp1, 8 ); sharp[i] = extract_h( L_shl( L_tmp, shift ) ); /* 30-s+s-8-16 -> Q6 */ + move16(); /*sharp_dist += (sharp[i]-HVQ_SHARP_THRES); */ -#ifdef BASOP_NOGLOB sharp_dist = add_o( sharp_dist, sub( sharp[i], HVQ_SHARP_THRES_FX ), &Overflow ); -#else - sharp_dist = add( sharp_dist, sub( sharp[i], HVQ_SHARP_THRES_FX ) ); -#endif - if ( GT_16( sharp[i], HVQ_SHARP_THRES_FX ) ) + IF( GT_16( sharp[i], HVQ_SHARP_THRES_FX ) ) { num_sharp_bands = add( num_sharp_bands, 1 ); } @@ -1332,12 +1342,14 @@ void hvq_classifier_fx( /* Estimate noise floor gains */ offset = s_and( nsub, 1 ); - FOR( i = 0; i < s_and( nsub, (Word16) 0xFFFE ); i++ ) + FOR( i = 0; i < ( nsub & (Word16) 0xFFFE ); i++ ) { /*(2*i+1)/nsub */ idx = mult( add( shl( i, 1 ), 1 ), add( inv_nsub, 1 ) ); /*0+15-15 = 0 */ L_nf_gains[idx] = L_add( L_nf_gains[idx], L_nf_mean[i + offset] ); L_pe_gains[idx] = L_add( L_pe_gains[idx], L_pe_mean[i + offset] ); + move32(); + move32(); } FOR( i = 0; i < HVQ_NF_GROUPS; i++ ) @@ -1372,9 +1384,10 @@ void hvq_classifier_fx( /* Adjust threshold around previous peaks */ FOR( i = 0; i < *prev_Npeaks; i++ ) { - j = sub( prev_peaks[i], 2 ); - k = add( prev_peaks[i], 2 ); - p_adj = hvq_thr_adj_fx; + j = sub( prev_peaks[i], 2 ); /* Q0 */ + k = add( prev_peaks[i], 2 ); /* Q0 */ + p_adj = hvq_thr_adj_fx; /* Q15 */ + move16(); FOR( q = j; q < k; q++ ) { @@ -1391,17 +1404,22 @@ void hvq_classifier_fx( L_input_abs[1] = L_deposit_l( 0 ); L_input_abs[N - 2] = L_deposit_l( 0 ); L_input_abs[N - 1] = L_deposit_l( 0 ); + move32(); + move32(); + move32(); + move32(); FOR( i = 0; i < N - 2; i++ ) { IF( LT_32( L_input_abs[i], L_thr[i] ) ) { L_input_abs[i] = L_deposit_l( 0 ); + move32(); } ELSE { - L_input_abs[num_peak_cands] = L_input_abs[i]; + L_input_abs[num_peak_cands] = L_input_abs[i]; /* Q12 */ move32(); - peak_cand_idx[num_peak_cands] = i; + peak_cand_idx[num_peak_cands] = i; /* Q0 */ move16(); num_peak_cands = add( num_peak_cands, 1 ); } @@ -1430,7 +1448,8 @@ void hvq_classifier_fx( idx = mult( peak_cand_idx[pindx], INV_HVQ_BW ); /* 0+15-15=0 */ IF( avail_peaks[idx] > 0 ) { - peaks[i++] = peak_cand_idx[pindx]; + peaks[i++] = peak_cand_idx[pindx]; /* Q0 */ + move16(); avail_peaks[idx]--; } @@ -1460,7 +1479,7 @@ void hvq_classifier_fx( } tmp = sub( N, 1 ); - if ( GT_16( high, tmp ) ) + IF( GT_16( high, tmp ) ) { high = tmp; move16(); @@ -1488,7 +1507,7 @@ void hvq_classifier_fx( } } - pindx = maximum_32_fx( L_input_abs, num_peak_cands, &L_m ); + pindx = maximum_32_fx( L_input_abs, num_peak_cands, &L_m ); /* Q0 */ } *Npeaks = i; @@ -1506,24 +1525,24 @@ void hvq_classifier_fx( } ELSE { - *hqswb_clas = HQ_HVQ; + *hqswb_clas = HQ_HVQ; /* Q0 */ move16(); - *hvq_hangover = 2; + *hvq_hangover = 2; /* Q0 */ move16(); } /* update memory */ - *prev_Npeaks = *Npeaks; + *prev_Npeaks = *Npeaks; /* Q0 */ move16(); - Copy( peaks, prev_peaks, *Npeaks ); + Copy( peaks, prev_peaks, *Npeaks ); /* Q0 */ } ELSE { IF( *hvq_hangover > 0 ) { - *hqswb_clas = HQ_HVQ; + *hqswb_clas = HQ_HVQ; /* Q0 */ move16(); - *hvq_hangover = sub( *hvq_hangover, 1 ); + *hvq_hangover = sub( *hvq_hangover, 1 ); /* Q0 */ move16(); } ELSE @@ -1543,12 +1562,12 @@ void hvq_classifier_fx( #ifndef ADD_IVAS_HQ_CODE IF( EQ_32( L_core_brate, HQ_24k40 ) ) { - *Npeaks = s_min( HVQ_MAX_PEAKS_24k, *Npeaks ); + *Npeaks = s_min( HVQ_MAX_PEAKS_24k, *Npeaks ); /* Q0 */ move16(); } ELSE { - *Npeaks = s_min( HVQ_MAX_PEAKS_32k, *Npeaks ); + *Npeaks = s_min( HVQ_MAX_PEAKS_32k, *Npeaks ); /* Q0 */ move16(); } #else diff --git a/lib_enc/hq_core_enc.c b/lib_enc/hq_core_enc.c deleted file mode 100644 index 91701fd7f73a18ba66e3b3a3e4cd3205c7151c67..0000000000000000000000000000000000000000 --- a/lib_enc/hq_core_enc.c +++ /dev/null @@ -1,403 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include -#include "cnst.h" -#include "prot.h" -#include "rom_com.h" -#include "wmc_auto.h" - -#include "prot_fx.h" -#include "prot_fx_enc.h" - -/*-------------------------------------------------------------------------- - * hq_core_enc() - * - * HQ core encoder - *--------------------------------------------------------------------------*/ - -void hq_core_enc_ivas_fx( - Encoder_State *st, /* i/o: encoder state structure */ - const Word16 *audio_fx, /* i : input audio signal Q0 */ - const Word16 input_frame_orig, /* i : frame length */ - const Word16 hq_core_type, /* i : HQ core type */ - const Word16 Voicing_flag, /* i : Voicing flag for FER method selection */ - const Word16 vad_hover_flag /* i : VAD hangover flag */ -) -{ - Word16 i, is_transient, num_bits, extra_unused; - - Word32 t_audio_fx[L_FRAME48k_EXT]; - Word16 wtda_audio_fx16[2 * L_FRAME48k]; - Word32 wtda_audio_fx32[2 * L_FRAME48k]; - Word16 two_frames_buffer[2 * L_FRAME48k]; - Word16 tmp; - Word16 Aq_old_fx[M + 1]; - Word16 output_fx[L_FRAME16k]; - Word16 Q_audio; - Word16 out_q = 0, old_q = 0; - move16(); - move16(); - Word16 inner_frame, input_frame, L_frame; - Word16 L_spec, overlap, nz, tcx_offset; - Word16 left_overlap, right_overlap; - BSTR_ENC_HANDLE hBstr = st->hBstr; - Word16 q = 0; - Word16 exp; - move16(); - - push_wmops( "hq_core_enc" ); - - set16_fx( wtda_audio_fx16, 0, 2 * L_FRAME48k ); - set32_fx( wtda_audio_fx32, 0, 2 * L_FRAME48k ); - st->Nb_ACELP_frames = 0; - move16(); - set_zero_fx( t_audio_fx, L_FRAME48k ); - /* set input_frame length */ - input_frame = input_frame_orig; - - /* Sanity check, it should never happen at the encoder side (no BFI) */ - IF( st->hTcxCfg->tcx_curr_overlap_mode == FULL_OVERLAP ) - { - st->hTcxCfg->tcx_last_overlap_mode = ALDO_WINDOW; - } - ELSE - { - st->hTcxCfg->tcx_last_overlap_mode = st->hTcxCfg->tcx_curr_overlap_mode; - } - move16(); - st->hTcxCfg->tcx_curr_overlap_mode = ALDO_WINDOW; - move16(); - - /*-------------------------------------------------------------------------- - * Preprocessing in the first HQ frame after ACELP frame - * Find the number of bits for PVQ coding - * Write signaling information - *--------------------------------------------------------------------------*/ - - num_bits = BASOP_Util_Divide3232_Scale( st->total_brate, FRAMES_PER_SEC, &exp ); - num_bits = shr( num_bits, sub( 15, exp ) ); - extra_unused = 0; - move16(); - - /*-------------------------------------------------------------------------- - * Detect signal transition - *--------------------------------------------------------------------------*/ - - is_transient = detect_transient_fx( audio_fx, input_frame, 0, st ); - move16(); - - test(); - test(); - IF( st->element_mode > EVS_MONO && ( st->last_core == ACELP_CORE || EQ_16( st->last_core, AMR_WB_CORE ) ) ) - { - /*-------------------------------------------------------------------------- - * IVAS switching frame - *--------------------------------------------------------------------------*/ - - L_spec = input_frame; - left_overlap = -1; - right_overlap = -1; - move16(); - move16(); - move16(); - - WindowSignal( st->hTcxCfg, st->hTcxCfg->tcx_offsetFB, TRANSITION_OVERLAP, FULL_OVERLAP, &left_overlap, &right_overlap, st->hTcxEnc->speech_TCX, &L_spec, wtda_audio_fx16, 1, 1 ); - - q = 0; - move16(); - Q_audio = sub( Q16, q ); - TCX_MDCT( wtda_audio_fx16, t_audio_fx, &Q_audio, left_overlap, sub( L_spec, shr( add( left_overlap, right_overlap ), 1 ) ), right_overlap, st->element_mode ); - Q_audio = sub( Q31, Q_audio ); - Copy_Scale_sig_16_32( wtda_audio_fx16, wtda_audio_fx32, 2 * L_FRAME48k, sub( Q_audio, q ) ); - - inner_frame = inner_frame_tbl[st->bwidth]; - L_spec = l_spec_ext_tbl[st->bwidth]; - is_transient = 0; - move16(); - move16(); - move16(); - } - ELSE - { - /*-------------------------------------------------------------------------- - * Windowing and time-domain aliasing - * DCT transform - *--------------------------------------------------------------------------*/ - Q_audio = 0; - move16(); - Scale_sig( st->old_input_signal_fx, input_frame, negate( st->q_old_inp ) ); - Scale_sig( st->input_fx, add( input_frame, NS2SA( 48000, DELAY_FIR_RESAMPL_NS ) ), negate( st->q_inp ) ); - st->q_old_inp = 0; - move16(); - st->q_inp = 0; - move16(); - Copy( st->old_input_signal_fx, two_frames_buffer, input_frame ); - Copy( audio_fx, two_frames_buffer + input_frame, input_frame ); - - wtda_fx( two_frames_buffer + input_frame, &Q_audio, wtda_audio_fx32, NULL, 0, - st->hTcxCfg->tcx_last_overlap_mode, st->hTcxCfg->tcx_curr_overlap_mode, input_frame ); - - test(); - IF( st->last_core == ACELP_CORE || EQ_16( st->last_core, AMR_WB_CORE ) ) - { - /* Preprocessing in the first HQ frame after ACELP frame */ - core_switching_hq_prepare_enc_fx( st, &num_bits, input_frame, wtda_audio_fx32, two_frames_buffer + input_frame ); - - /* During ACELP->HQ core switching, limit the HQ core bitrate to 48kbps */ - IF( GT_16( num_bits, ACELP_48k_BITS ) ) - { - extra_unused = sub( num_bits, ACELP_48k_BITS ); - num_bits = ACELP_48k_BITS; - move16(); - } - } - - Word16 tmp_q = Q_audio; - move16(); - direct_transform_fx( wtda_audio_fx32, t_audio_fx, is_transient, input_frame, &Q_audio, st->element_mode ); - scale_sig32( wtda_audio_fx32, L_FRAME48k_EXT, sub( Q_audio, tmp_q ) ); - - /* scale coefficients to their nominal level (8kHz) */ - IF( NE_16( input_frame, NORM_MDCT_FACTOR ) ) - { - UWord16 lsb; - tmp = mult_r( input_frame, 410 / 2 ); /* 1/8000 in Q15 */ - Word16 ener_match_fx = hq_nominal_scaling[tmp]; - FOR( i = 0; i < input_frame; i++ ) - { - /*t_audio_q[i] *= ener_match; */ - Mpy_32_16_ss( t_audio_fx[i], ener_match_fx, &t_audio_fx[i], &lsb ); - move16(); /* Q12 */ - } - } - - /* limit encoded band-width according to the command-line OR BWD limitation */ - inner_frame = inner_frame_tbl[st->bwidth]; - L_spec = l_spec_tbl[st->bwidth]; - - move16(); - move16(); - - - IF( GT_16( input_frame, inner_frame ) ) - { - IF( EQ_16( is_transient, 1 ) ) - { - FOR( i = 1; i < NUM_TIME_SWITCHING_BLOCKS; i++ ) - { - tmp = shr( inner_frame, 2 ); - Copy32( t_audio_fx + i_mult2( i, shr( input_frame, 2 ) ), t_audio_fx + i_mult2( i, tmp ), tmp ); - } - } - - set32_fx( t_audio_fx + inner_frame, 0, sub( input_frame, inner_frame ) ); - } - } - - - /* subtract signaling bits */ - num_bits = sub( num_bits, hBstr->nb_bits_tot ); - - /*-------------------------------------------------------------------------- - * High-band gain control in case of BWS - *--------------------------------------------------------------------------*/ - - IF( st->bwidth_sw_cnt > 0 ) - { - Word32 L_tmp; - tmp = BASOP_Util_Divide1616_Scale( 3, BWS_TRAN_PERIOD, &exp ); - shr( tmp, exp ); - L_tmp = L_deposit_h( tmp ); - IF( is_transient ) - { - FOR( i = 0; i < NUM_TIME_SWITCHING_BLOCKS; i++ ) - { - v_multc_fixed( t_audio_fx + add( i_mult2( i, shr( inner_frame, 2 ) ), L_FRAME16k / NUM_TIME_SWITCHING_BLOCKS ), L_tmp, t_audio_fx + add( i_mult2( i, shr( inner_frame, 2 ) ), L_FRAME16k / NUM_TIME_SWITCHING_BLOCKS ), sub( shr( inner_frame, 2 ), L_FRAME16k / NUM_TIME_SWITCHING_BLOCKS ) ); // Q_audio + Q31 - Q31 -> Q_audio - } - } - ELSE - { - v_multc_fixed( t_audio_fx + L_FRAME16k, L_tmp, t_audio_fx + L_FRAME16k, L_spec - L_FRAME16k ); // Q_audio + Q31 - Q31 -> Q_audio - } - } - - /*-------------------------------------------------------------------------- - * Classify whether to put extra bits for FER mitigation - *--------------------------------------------------------------------------*/ - - test(); - test(); - test(); - IF( ( EQ_16( st->last_core, TCX_20_CORE ) || EQ_16( st->last_core, TCX_10_CORE ) || EQ_16( st->last_core, HQ_CORE ) ) && GT_32( st->core_brate, MINIMUM_RATE_TO_ENCODE_VOICING_FLAG ) ) - { - IF( Voicing_flag > 0 ) - { - push_indice( hBstr, IND_HQ_VOICING_FLAG, 1, 1 ); - num_bits = sub( num_bits, 1 ); - } - ELSE - { - push_indice( hBstr, IND_HQ_VOICING_FLAG, 0, 1 ); - num_bits = sub( num_bits, 1 ); - } - } - - /*-------------------------------------------------------------------------- - * Transform-domain encoding - *--------------------------------------------------------------------------*/ - - scale_sig32( t_audio_fx, L_FRAME48k, sub( Q12, Q_audio ) ); - scale_sig32( wtda_audio_fx32, 2 * L_FRAME48k, sub( Q12, Q_audio ) ); - Q_audio = 12; - move16(); - IF( EQ_16( hq_core_type, LOW_RATE_HQ_CORE ) ) - { - - hq_lr_enc_ivas_fx( st, t_audio_fx, inner_frame, &num_bits, is_transient ); - } - ELSE - { - /* HQ high rate encoder */ - hq_hr_enc_ivas_fx( st, t_audio_fx, L_spec, &num_bits, is_transient, vad_hover_flag ); - } - - /* write all unused bits to the bitstream */ - num_bits = add( num_bits, extra_unused ); - - WHILE( GT_16( num_bits, 16 ) ) - { - push_indice( hBstr, IND_UNUSED, 0, 16 ); - num_bits = sub( num_bits, 16 ); - } - - IF( num_bits != 0 ) - { - push_indice( hBstr, IND_UNUSED, 0, num_bits ); - } - - test(); - test(); - IF( st->element_mode > EVS_MONO && ( st->last_core == ACELP_CORE || EQ_16( st->last_core, AMR_WB_CORE ) ) ) - { - overlap = st->hTcxCfg->tcx_mdct_window_length; - move16(); - - nz = NS2SA( st->sr_core, N_ZERO_MDCT_NS ); - move16(); - L_frame = sub( st->L_frame + st->hTcxCfg->tcx_offset, st->hTcxCfg->lfacNext ); - tcx_offset = st->hTcxCfg->lfacNext; - move16(); - - set16_fx( Aq_old_fx, 0, M + 1 ); /* Dummy filter */ - Aq_old_fx[0] = 1; - move16(); - - /* Code taken from InternalTCXDecoder() */ - Copy_Scale_sig_32_16( wtda_audio_fx32, wtda_audio_fx16, 2 * L_FRAME48k, negate( Q_audio ) ); // Q0 - TCX_MDCT_Inverse( t_audio_fx, sub( sub( 31, Q_audio ), 15 ), wtda_audio_fx16, overlap, sub( L_frame, overlap ), overlap, st->element_mode ); - - - /* Window current frame */ - Word16 tcx_offset_tmp; - - IF( tcx_offset < 0 ) - { - tcx_offset_tmp = negate( tcx_offset ); - } - ELSE - { - tcx_offset_tmp = 0; - move16(); - } - tcx_windowing_synthesis_current_frame( wtda_audio_fx16, st->hTcxCfg->tcx_aldo_window_2, st->hTcxCfg->tcx_mdct_window_half, st->hTcxCfg->tcx_mdct_window_minimum, overlap, /*st->hTcxCfg->tcx_mdct_window_length*/ st->hTcxCfg->tcx_mdct_window_half_length, st->hTcxCfg->tcx_mdct_window_min_length, st->last_core == ACELP_CORE, st->hTcxCfg->tcx_last_overlap_mode, /*left mode*/ st->hTcxEnc->acelp_zir, st->hTcxEnc->Txnq, NULL, Aq_old_fx, st->hTcxCfg->tcx_mdct_window_trans, shr( st->L_frame, 1 ), tcx_offset_tmp, st->last_core, 0, 0 ); - - - /*Compute windowed synthesis in case of switching to ALDO windows in next frame*/ - Copy( wtda_audio_fx16 + sub( L_frame, nz ), st->hTcxEnc->old_out_fx, nz + overlap ); - set16_fx( st->hTcxEnc->old_out_fx + add( nz, overlap ), 0, nz ); - - tcx_windowing_synthesis_past_frame( st->hTcxEnc->old_out_fx + nz, st->hTcxCfg->tcx_aldo_window_1_trunc, st->hTcxCfg->tcx_mdct_window_half, st->hTcxCfg->tcx_mdct_window_minimum, overlap, st->hTcxCfg->tcx_mdct_window_half_length, st->hTcxCfg->tcx_mdct_window_min_length, FULL_OVERLAP ); - - FOR( i = 0; i < nz / 2; i++ ) - { - // This implementation is diffrent in float code need to revisit to check its correctness. - st->hTcxEnc->old_out_fx[nz + overlap + i] = mult( wtda_audio_fx16[L_frame - 1 - i], st->hTcxCfg->tcx_aldo_window_1_trunc[i].v.re ); // Q0 + Q15 - Q15 -> Q0; - st->hTcxEnc->old_out_fx[nz / 2 + ( nz + overlap + i )] = mult( wtda_audio_fx16[nz / 2 + ( L_frame - 1 - i )], st->hTcxCfg->tcx_aldo_window_1_trunc[nz / 2 - 1 - i].v.im ); // Q0 + Q15 - Q15 -> Q0; - } - - Copy( wtda_audio_fx16 + sub( shr( overlap, 1 ), tcx_offset ), output_fx, st->L_frame ); - } - ELSE - { - Word16 tmp_q = Q_audio; - move16(); - Word32 ener_match_fx = SQRT2_FIXED; - move32(); - FOR( i = 0; i < input_frame; i++ ) - { - t_audio_fx[i] = Mpy_32_32( t_audio_fx[i], ener_match_fx ); - move32(); /* Q12 - 1 -> Q11 */ - } - - Q_audio = sub( Q_audio, 1 ); - scale_sig32( wtda_audio_fx32, 2 * L_FRAME48k, sub( Q_audio, tmp_q ) ); - Inverse_Transform( t_audio_fx, &Q_audio, wtda_audio_fx32, is_transient, L_FRAME16k, inner_frame, st->element_mode ); - - - out_q = Q_audio; - move16(); - window_ola_fx( wtda_audio_fx32, output_fx, &out_q, st->hTcxEnc->old_out_fx, &old_q, L_FRAME16k, st->hTcxCfg->tcx_last_overlap_mode, st->hTcxCfg->tcx_curr_overlap_mode, 0, 0, NULL ); - - Scale_sig( output_fx, L_FRAME16k, negate( out_q ) ); - Scale_sig( st->hTcxEnc->old_out_fx, L_FRAME32k, negate( old_q ) ); - st->hTcxEnc->Q_old_out = 0; - move16(); - } - - IF( st->element_mode > EVS_MONO ) - { - /* Store LB synthesis in case of switch to ACELP */ - Copy( output_fx, st->hLPDmem->old_exc, L_FRAME16k ); - st->hLPDmem->q_lpd_old_exc = 15; - move16(); - } - pop_wmops(); - - return; -} diff --git a/lib_enc/hq_core_enc_fx.c b/lib_enc/hq_core_enc_fx.c index faef4c1e0e99888c1480cef1ffcdd8d4ade86135..f22218d13675013ebf72419bf23980144ac8e4fb 100644 --- a/lib_enc/hq_core_enc_fx.c +++ b/lib_enc/hq_core_enc_fx.c @@ -2,11 +2,10 @@ EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0 ====================================================================================*/ #include -#include "options.h" /* Compilation switches */ -#include "cnst.h" /* Common constants */ -#include "rom_com_fx.h" /* Static table prototypes */ -#include "rom_com.h" /* Static table prototypes */ -//#include "prot_fx.h" /* Function prototypes */ +#include "options.h" /* Compilation switches */ +#include "cnst.h" /* Common constants */ +#include "rom_com_fx.h" /* Static table prototypes */ +#include "rom_com.h" /* Static table prototypes */ #include "prot_fx.h" /* Function prototypes */ #include "prot_fx_enc.h" /* Function prototypes */ @@ -19,10 +18,10 @@ void hq_core_enc_fx( Encoder_State *st_fx, const Word16 *audio, /* i : input audio signal Q0 */ - const Word16 input_frame_orig, /* i : frame length */ - const Word16 hq_core_type, /* i : HQ core type */ - const Word16 Voicing_flag, /* i : Voicing flag for FER method selection */ - const Word16 vad_hover_flag /* i : VAD hangover flag */ + const Word16 input_frame_orig, /* i : frame length Q0*/ + const Word16 hq_core_type, /* i : HQ core type Q0*/ + const Word16 Voicing_flag, /* i : Voicing flag for FER method selection Q0*/ + const Word16 vad_hover_flag /* i : VAD hangover flag Q0*/ ) { Word16 i, is_transient, num_bits, extra_unused; @@ -31,6 +30,7 @@ void hq_core_enc_fx( Word16 Q_audio = 0; Word16 inner_frame, input_frame; Word16 ener_match; /* Q13/Q15 */ + move16(); Word16 tmp; Word32 L_tmp; @@ -52,7 +52,7 @@ void hq_core_enc_fx( move16(); /* set input_frame length */ - input_frame = input_frame_orig; + input_frame = input_frame_orig; /* Q0 */ move16(); /* Sanity check, it should never happen at the encoder side (no BFI) */ IF( EQ_16( st_fx->hTcxCfg->tcx_curr_overlap_mode, FULL_OVERLAP ) ) @@ -85,13 +85,13 @@ void hq_core_enc_fx( * Detect signal transition *--------------------------------------------------------------------------*/ - is_transient = detect_transient_fx( audio, input_frame, 0, st_fx ); + is_transient = detect_transient_fx( audio, input_frame, 0, st_fx ); /* Q0 */ #ifdef ADD_IVAS_HQ_CODE test(); test(); test(); - IF( GT_16( st_fx->element_mode, EVS_MONO ) && ( EQ_16( st_fx->last_core, ACELP_CORE ) || EQ_16( st_fx->last_core, AMR_WB_CORE ) ) ) + IF( ( st_fx->element_mode > EVS_MONO ) && ( ( st_fx->last_core == ACELP_CORE ) || EQ_16( st_fx->last_core, AMR_WB_CORE ) ) ) { /*-------------------------------------------------------------------------- * IVAS switching frame @@ -124,8 +124,8 @@ void hq_core_enc_fx( * DCT transform *--------------------------------------------------------------------------*/ - Copy( st_fx->old_input_signal_fx, two_frames_buffer, input_frame ); - Copy( audio, two_frames_buffer + input_frame, input_frame ); + Copy( st_fx->old_input_signal_fx, two_frames_buffer, input_frame ); /* st_fx->q_old_inp */ + Copy( audio, two_frames_buffer + input_frame, input_frame ); /* Q0 */ wtda_fx( two_frames_buffer + input_frame, &Q_audio, wtda_audio, NULL, 0, st_fx->hTcxCfg->tcx_last_overlap_mode, st_fx->hTcxCfg->tcx_curr_overlap_mode, input_frame ); @@ -146,7 +146,7 @@ void hq_core_enc_fx( } #ifndef ADD_IVAS_HQ_CODE /* subtract signalling bits */ - num_bits = sub( num_bits, hBstr->nb_bits_tot ); + num_bits = sub( num_bits, hBstr->nb_bits_tot ); /* Q0 */ #endif direct_transform_fx( wtda_audio, t_audio, is_transient, input_frame, &Q_audio, st_fx->element_mode ); @@ -161,17 +161,18 @@ void hq_core_enc_fx( { tmp = mult_r( input_frame, 410 / 2 ); /* 1/8000 in Q15 */ ener_match = hq_nominal_scaling[tmp]; + move16(); FOR( i = 0; i < input_frame; i++ ) { /*t_audio_q[i] *= ener_match; */ - Mpy_32_16_ss( t_audio[i], ener_match, &t_audio[i], &lsb ); - move16(); /* Q12 */ + Mpy_32_16_ss( t_audio[i], ener_match, &t_audio[i], &lsb ); /* Q12 */ + move16(); } } } /* limit encoded band-width according to the command-line OR BWD limitation */ - inner_frame = inner_frame_tbl[st_fx->bwidth]; + inner_frame = inner_frame_tbl[st_fx->bwidth]; /* Q0 */ move16(); #ifdef ADD_IVAS_HQ_CODE_L_SPEC L_spec = l_spec_tbl[st_fx->bwidth]; @@ -185,7 +186,7 @@ void hq_core_enc_fx( { tmp = i_mult2( i, shr( input_frame, 2 ) ); tmp = shr( inner_frame, 2 ); - Copy32( t_audio + i_mult2( i, shr( input_frame, 2 ) ), t_audio + i_mult2( i, tmp ), tmp ); + Copy32( t_audio + i_mult2( i, shr( input_frame, 2 ) ), t_audio + i_mult2( i, tmp ), tmp ); /* Q12 */ } } @@ -221,6 +222,8 @@ void hq_core_enc_fx( * Classify whether to put extra bits for FER mitigation *--------------------------------------------------------------------------*/ + test(); + test(); test(); IF( ( EQ_16( st_fx->last_core, TCX_20_CORE ) || EQ_16( st_fx->last_core, TCX_10_CORE ) || EQ_16( st_fx->last_core, HQ_CORE ) ) && GT_32( st_fx->core_brate, MINIMUM_RATE_TO_ENCODE_VOICING_FLAG ) ) { @@ -246,6 +249,7 @@ void hq_core_enc_fx( FOR( i = 0; i < inner_frame; i++ ) { t_audio[i] = L_shr( t_audio[i], sub( Q_audio, 12 ) ); /* Q12 */ + move32(); } hq_lr_enc_fx( st_fx, t_audio, inner_frame, &num_bits, is_transient ); Q_audio = 12; @@ -257,6 +261,7 @@ void hq_core_enc_fx( FOR( i = 0; i < inner_frame; i++ ) { t_audio[i] = L_shr( t_audio[i], sub( Q_audio, 12 ) ); /* Q12 */ + move32(); } #ifdef ADD_IVAS_HQ_CODE_L_SPEC @@ -360,8 +365,8 @@ void HQ_core_enc_init_fx( move16(); hHQ_core->prev_stab_hfe2 = 0; move16(); - hHQ_core->prev_ni_ratio_fx = 16384; - move16(); /* 0.5 */ + hHQ_core->prev_ni_ratio_fx = 16384; /* Q15 */ + move16(); /* 0.5 */ set16_fx( hHQ_core->prev_En_sb_fx, 0, NB_SWB_SUBBANDS ); set16_fx( hHQ_core->last_bitalloc_max_band, 0, 2 ); set32_fx( hHQ_core->last_ni_gain_fx, 0, BANDS_MAX ); @@ -370,11 +375,11 @@ void HQ_core_enc_init_fx( move16(); #ifdef MSAN_FIX - hHQ_core->crest_lp_fx = HQ_CREST_THRESHOLD_FX; + hHQ_core->crest_lp_fx = HQ_CREST_THRESHOLD_FX; /* Q28 */ move32(); hHQ_core->crest_lp_q = Q28; move16(); - hHQ_core->crest_mod_lp_fx = HQ_CREST_MOD_THRESHOLD_FX; + hHQ_core->crest_mod_lp_fx = HQ_CREST_MOD_THRESHOLD_FX; /* Q29 */ move32(); hHQ_core->crest_mod_lp_q = Q29; move16(); @@ -382,3 +387,361 @@ void HQ_core_enc_init_fx( return; } + +void hq_core_enc_ivas_fx( + Encoder_State *st, /* i/o: encoder state structure */ + const Word16 *audio_fx, /* i : input audio signal Q0 */ + const Word16 input_frame_orig, /* i : frame length Q0*/ + const Word16 hq_core_type, /* i : HQ core type Q0*/ + const Word16 Voicing_flag, /* i : Voicing flag for FER method selection Q0*/ + const Word16 vad_hover_flag /* i : VAD hangover flag Q0*/ +) +{ + Word16 i, is_transient, num_bits, extra_unused; + + Word32 t_audio_fx[L_FRAME48k_EXT]; + Word16 wtda_audio_fx16[2 * L_FRAME48k]; + Word32 wtda_audio_fx32[2 * L_FRAME48k]; + Word16 two_frames_buffer[2 * L_FRAME48k]; + Word16 tmp; + Word16 Aq_old_fx[M + 1]; + Word16 output_fx[L_FRAME48k]; + Word16 Q_audio; + Word16 out_q = 0, old_q = 0; + move16(); + move16(); + Word16 inner_frame, input_frame, L_frame; + Word16 L_spec, overlap, nz, tcx_offset; + Word16 left_overlap, right_overlap; + BSTR_ENC_HANDLE hBstr = st->hBstr; + Word16 q = 0; + Word16 exp; + move16(); + + push_wmops( "hq_core_enc" ); + + set16_fx( wtda_audio_fx16, 0, 2 * L_FRAME48k ); + set32_fx( wtda_audio_fx32, 0, 2 * L_FRAME48k ); + st->Nb_ACELP_frames = 0; + move16(); + set_zero_fx( t_audio_fx, L_FRAME48k_EXT ); + /* set input_frame length */ + input_frame = input_frame_orig; /* Q0 */ + + /* Sanity check, it should never happen at the encoder side (no BFI) */ + IF( st->hTcxCfg->tcx_curr_overlap_mode == FULL_OVERLAP ) + { + st->hTcxCfg->tcx_last_overlap_mode = ALDO_WINDOW; + move16(); + } + ELSE + { + st->hTcxCfg->tcx_last_overlap_mode = st->hTcxCfg->tcx_curr_overlap_mode; + move16(); + } + st->hTcxCfg->tcx_curr_overlap_mode = ALDO_WINDOW; + move16(); + + /*-------------------------------------------------------------------------- + * Preprocessing in the first HQ frame after ACELP frame + * Find the number of bits for PVQ coding + * Write signaling information + *--------------------------------------------------------------------------*/ + + num_bits = BASOP_Util_Divide3232_Scale( st->total_brate, FRAMES_PER_SEC, &exp ); /* Q15-exp */ + num_bits = shr( num_bits, sub( 15, exp ) ); /* Q0 */ + extra_unused = 0; + move16(); + + /*-------------------------------------------------------------------------- + * Detect signal transition + *--------------------------------------------------------------------------*/ + + is_transient = detect_transient_fx( audio_fx, input_frame, 0, st ); /* Q0 */ + move16(); + + test(); + test(); + IF( st->element_mode > EVS_MONO && ( st->last_core == ACELP_CORE || EQ_16( st->last_core, AMR_WB_CORE ) ) ) + { + /*-------------------------------------------------------------------------- + * IVAS switching frame + *--------------------------------------------------------------------------*/ + + L_spec = input_frame; + left_overlap = -1; + right_overlap = -1; + move16(); + move16(); + move16(); + + WindowSignal( st->hTcxCfg, st->hTcxCfg->tcx_offsetFB, TRANSITION_OVERLAP, FULL_OVERLAP, &left_overlap, &right_overlap, st->hTcxEnc->speech_TCX, &L_spec, wtda_audio_fx16, 1, 1 ); + + q = 0; + move16(); + Q_audio = sub( Q16, q ); + TCX_MDCT( wtda_audio_fx16, t_audio_fx, &Q_audio, left_overlap, sub( L_spec, shr( add( left_overlap, right_overlap ), 1 ) ), right_overlap, st->element_mode ); + Q_audio = sub( Q31, Q_audio ); +#ifdef FIX_ISSUE_1237 + Copy_Scale_sig_16_32_no_sat( wtda_audio_fx16, wtda_audio_fx32, 2 * L_FRAME48k, sub( Q_audio, q ) ); /* Q_audio */ +#else + Copy_Scale_sig_16_32_DEPREC( wtda_audio_fx16, wtda_audio_fx32, 2 * L_FRAME48k, sub( Q_audio, q ) ); /* Q_audio */ +#endif + inner_frame = inner_frame_tbl[st->bwidth]; /* Q0 */ + L_spec = l_spec_ext_tbl[st->bwidth]; /* Q0 */ + is_transient = 0; + move16(); + move16(); + move16(); + } + ELSE + { + /*-------------------------------------------------------------------------- + * Windowing and time-domain aliasing + * DCT transform + *--------------------------------------------------------------------------*/ + Q_audio = 0; + move16(); + Scale_sig( st->old_input_signal_fx, input_frame, negate( st->q_old_inp ) ); /* Q0 */ + Scale_sig( st->input_fx, add( input_frame, NS2SA( 48000, DELAY_FIR_RESAMPL_NS ) ), negate( st->q_inp ) ); /* Q0 */ + st->q_old_inp = 0; + move16(); + st->q_inp = 0; + move16(); + Copy( st->old_input_signal_fx, two_frames_buffer, input_frame ); /* Q0 */ + Copy( audio_fx, two_frames_buffer + input_frame, input_frame ); /* Q0 */ + + wtda_fx( two_frames_buffer + input_frame, &Q_audio, wtda_audio_fx32, NULL, 0, + st->hTcxCfg->tcx_last_overlap_mode, st->hTcxCfg->tcx_curr_overlap_mode, input_frame ); + + test(); + IF( st->last_core == ACELP_CORE || EQ_16( st->last_core, AMR_WB_CORE ) ) + { + /* Preprocessing in the first HQ frame after ACELP frame */ + core_switching_hq_prepare_enc_fx( st, &num_bits, input_frame, wtda_audio_fx32, two_frames_buffer + input_frame ); + + /* During ACELP->HQ core switching, limit the HQ core bitrate to 48kbps */ + IF( GT_16( num_bits, ACELP_48k_BITS ) ) + { + extra_unused = sub( num_bits, ACELP_48k_BITS ); + num_bits = ACELP_48k_BITS; + move16(); + } + } + + Word16 tmp_q = Q_audio; + move16(); + direct_transform_fx( wtda_audio_fx32, t_audio_fx, is_transient, input_frame, &Q_audio, st->element_mode ); + scale_sig32( wtda_audio_fx32, L_FRAME48k_EXT, sub( Q_audio, tmp_q ) ); /* Q_audio */ + + /* scale coefficients to their nominal level (8kHz) */ + IF( NE_16( input_frame, NORM_MDCT_FACTOR ) ) + { + UWord16 lsb; + tmp = mult_r( input_frame, 410 / 2 ); /* 1/8000 in Q15 */ + Word16 ener_match_fx = hq_nominal_scaling[tmp]; + move16(); + FOR( i = 0; i < input_frame; i++ ) + { + /*t_audio_q[i] *= ener_match; */ + Mpy_32_16_ss( t_audio_fx[i], ener_match_fx, &t_audio_fx[i], &lsb ); /* Q12 */ + move16(); + } + } + + /* limit encoded band-width according to the command-line OR BWD limitation */ + inner_frame = inner_frame_tbl[st->bwidth]; /* Q0 */ + L_spec = l_spec_tbl[st->bwidth]; /* Q0 */ + + move16(); + move16(); + + + IF( GT_16( input_frame, inner_frame ) ) + { + IF( EQ_16( is_transient, 1 ) ) + { + FOR( i = 1; i < NUM_TIME_SWITCHING_BLOCKS; i++ ) + { + tmp = shr( inner_frame, 2 ); + Copy32( t_audio_fx + i_mult2( i, shr( input_frame, 2 ) ), t_audio_fx + i_mult2( i, tmp ), tmp ); /* Q_audio */ + } + } + + set32_fx( t_audio_fx + inner_frame, 0, sub( input_frame, inner_frame ) ); + } + } + + + /* subtract signaling bits */ + num_bits = sub( num_bits, hBstr->nb_bits_tot ); /* Q0 */ + + /*-------------------------------------------------------------------------- + * High-band gain control in case of BWS + *--------------------------------------------------------------------------*/ + + IF( st->bwidth_sw_cnt > 0 ) + { + Word32 L_tmp; + tmp = BASOP_Util_Divide1616_Scale( 3, BWS_TRAN_PERIOD, &exp ); /* Q15-exp */ + shr( tmp, exp ); + L_tmp = L_deposit_h( tmp ); /* Q31-exp */ + IF( is_transient ) + { + FOR( i = 0; i < NUM_TIME_SWITCHING_BLOCKS; i++ ) + { + v_multc_fixed( t_audio_fx + add( i_mult2( i, shr( inner_frame, 2 ) ), L_FRAME16k / NUM_TIME_SWITCHING_BLOCKS ), L_tmp, t_audio_fx + add( i_mult2( i, shr( inner_frame, 2 ) ), L_FRAME16k / NUM_TIME_SWITCHING_BLOCKS ), sub( shr( inner_frame, 2 ), L_FRAME16k / NUM_TIME_SWITCHING_BLOCKS ) ); // Q_audio + Q31 - Q31 -> Q_audio + } + } + ELSE + { + v_multc_fixed( t_audio_fx + L_FRAME16k, L_tmp, t_audio_fx + L_FRAME16k, L_spec - L_FRAME16k ); // Q_audio + Q31 - Q31 -> Q_audio + } + } + + /*-------------------------------------------------------------------------- + * Classify whether to put extra bits for FER mitigation + *--------------------------------------------------------------------------*/ + + test(); + test(); + test(); + IF( ( EQ_16( st->last_core, TCX_20_CORE ) || EQ_16( st->last_core, TCX_10_CORE ) || EQ_16( st->last_core, HQ_CORE ) ) && GT_32( st->core_brate, MINIMUM_RATE_TO_ENCODE_VOICING_FLAG ) ) + { + IF( Voicing_flag > 0 ) + { + push_indice( hBstr, IND_HQ_VOICING_FLAG, 1, 1 ); + num_bits = sub( num_bits, 1 ); + } + ELSE + { + push_indice( hBstr, IND_HQ_VOICING_FLAG, 0, 1 ); + num_bits = sub( num_bits, 1 ); + } + } + + /*-------------------------------------------------------------------------- + * Transform-domain encoding + *--------------------------------------------------------------------------*/ + + scale_sig32( t_audio_fx, L_FRAME48k_EXT, sub( Q12, Q_audio ) ); + scale_sig32( wtda_audio_fx32, 2 * L_FRAME48k, sub( Q12, Q_audio ) ); + Q_audio = 12; + move16(); + IF( EQ_16( hq_core_type, LOW_RATE_HQ_CORE ) ) + { + + hq_lr_enc_ivas_fx( st, t_audio_fx, inner_frame, &num_bits, is_transient ); + } + ELSE + { + /* HQ high rate encoder */ + hq_hr_enc_ivas_fx( st, t_audio_fx, L_spec, &num_bits, is_transient, vad_hover_flag ); + } + + /* write all unused bits to the bitstream */ + num_bits = add( num_bits, extra_unused ); + + WHILE( GT_16( num_bits, 16 ) ) + { + push_indice( hBstr, IND_UNUSED, 0, 16 ); + num_bits = sub( num_bits, 16 ); + } + + IF( num_bits != 0 ) + { + push_indice( hBstr, IND_UNUSED, 0, num_bits ); + } + + test(); + test(); + IF( st->element_mode > EVS_MONO && ( st->last_core == ACELP_CORE || EQ_16( st->last_core, AMR_WB_CORE ) ) ) + { + overlap = st->hTcxCfg->tcx_mdct_window_length; /* Q0 */ + move16(); + + nz = NS2SA( st->sr_core, N_ZERO_MDCT_NS ); + move16(); + L_frame = sub( st->L_frame + st->hTcxCfg->tcx_offset, st->hTcxCfg->lfacNext ); + tcx_offset = st->hTcxCfg->lfacNext; + move16(); + + set16_fx( Aq_old_fx, 0, M + 1 ); /* Dummy filter */ + Aq_old_fx[0] = 1; + move16(); + + /* Code taken from InternalTCXDecoder() */ + Copy_Scale_sig_32_16( wtda_audio_fx32, wtda_audio_fx16, 2 * L_FRAME48k, negate( Q_audio ) ); // Q0 + TCX_MDCT_Inverse( t_audio_fx, sub( sub( 31, Q_audio ), 15 ), wtda_audio_fx16, overlap, sub( L_frame, overlap ), overlap, st->element_mode ); + + + /* Window current frame */ + Word16 tcx_offset_tmp; + + IF( tcx_offset < 0 ) + { + tcx_offset_tmp = negate( tcx_offset ); + } + ELSE + { + tcx_offset_tmp = 0; + move16(); + } + tcx_windowing_synthesis_current_frame( wtda_audio_fx16, st->hTcxCfg->tcx_aldo_window_2, st->hTcxCfg->tcx_mdct_window_half, st->hTcxCfg->tcx_mdct_window_minimum, overlap, /*st->hTcxCfg->tcx_mdct_window_length*/ st->hTcxCfg->tcx_mdct_window_half_length, st->hTcxCfg->tcx_mdct_window_min_length, st->last_core == ACELP_CORE, st->hTcxCfg->tcx_last_overlap_mode, /*left mode*/ st->hTcxEnc->acelp_zir, st->hTcxEnc->Txnq, NULL, Aq_old_fx, st->hTcxCfg->tcx_mdct_window_trans, shr( st->L_frame, 1 ), tcx_offset_tmp, st->last_core, 0, 0 ); + + + /*Compute windowed synthesis in case of switching to ALDO windows in next frame*/ + Copy( wtda_audio_fx16 + sub( L_frame, nz ), st->hTcxEnc->old_out_fx, nz + overlap ); /* Q0 */ + set16_fx( st->hTcxEnc->old_out_fx + add( nz, overlap ), 0, nz ); + + tcx_windowing_synthesis_past_frame( st->hTcxEnc->old_out_fx + nz, st->hTcxCfg->tcx_aldo_window_1_trunc, st->hTcxCfg->tcx_mdct_window_half, st->hTcxCfg->tcx_mdct_window_minimum, overlap, st->hTcxCfg->tcx_mdct_window_half_length, st->hTcxCfg->tcx_mdct_window_min_length, FULL_OVERLAP ); + + FOR( i = 0; i < nz / 2; i++ ) + { + // This implementation is diffrent in float code need to revisit to check its correctness. + st->hTcxEnc->old_out_fx[nz + overlap + i] = mult( wtda_audio_fx16[L_frame - 1 - i], st->hTcxCfg->tcx_aldo_window_1_trunc[i].v.re ); // Q0 + Q15 - Q15 -> Q0; + st->hTcxEnc->old_out_fx[nz / 2 + ( nz + overlap + i )] = mult( wtda_audio_fx16[nz / 2 + ( L_frame - 1 - i )], st->hTcxCfg->tcx_aldo_window_1_trunc[nz / 2 - 1 - i].v.im ); // Q0 + Q15 - Q15 -> Q0; + move16(); + move16(); + } + + Copy( wtda_audio_fx16 + sub( shr( overlap, 1 ), tcx_offset ), output_fx, st->L_frame ); /* Q0 */ + } + ELSE + { + Word16 tmp_q = Q_audio; + move16(); + Word32 ener_match_fx = SQRT2_FIXED; + move32(); + FOR( i = 0; i < input_frame; i++ ) + { + t_audio_fx[i] = Mpy_32_32( t_audio_fx[i], ener_match_fx ); /* Q12 - 1 -> Q11 */ + move32(); + } + + Q_audio = sub( Q_audio, 1 ); + scale_sig32( wtda_audio_fx32, 2 * L_FRAME48k, sub( Q_audio, tmp_q ) ); /* Q_audio */ + Inverse_Transform( t_audio_fx, &Q_audio, wtda_audio_fx32, is_transient, L_FRAME16k, inner_frame, st->element_mode ); + + + out_q = Q_audio; + move16(); + window_ola_fx( wtda_audio_fx32, output_fx, &out_q, st->hTcxEnc->old_out_fx, &old_q, L_FRAME16k, st->hTcxCfg->tcx_last_overlap_mode, st->hTcxCfg->tcx_curr_overlap_mode, 0, 0, NULL ); + + Scale_sig( output_fx, L_FRAME16k, negate( out_q ) ); /* Q0 */ + Scale_sig( st->hTcxEnc->old_out_fx, L_FRAME32k, negate( old_q ) ); /* Q0 */ + st->hTcxEnc->Q_old_out = 0; + move16(); + } + + IF( st->element_mode > EVS_MONO ) + { + /* Store LB synthesis in case of switch to ACELP */ + Copy( output_fx, st->hLPDmem->old_exc, L_FRAME16k ); + st->hLPDmem->q_lpd_old_exc = 0; + move16(); + } + pop_wmops(); + + return; +} diff --git a/lib_enc/hq_env_enc.c b/lib_enc/hq_env_enc.c deleted file mode 100644 index 4e446e1c5a57ada7a8af2fc99cc725b46226a312..0000000000000000000000000000000000000000 --- a/lib_enc/hq_env_enc.c +++ /dev/null @@ -1,42 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include "prot.h" -#include "rom_com.h" -#include "rom_enc.h" -#include "wmc_auto.h" diff --git a/lib_enc/hq_env_enc_fx.c b/lib_enc/hq_env_enc_fx.c index e04489b18341d3125b69ab673755a46dc39983eb..5d47710ed9fe68624d4a61c83d4b9ed99b03a942 100644 --- a/lib_enc/hq_env_enc_fx.c +++ b/lib_enc/hq_env_enc_fx.c @@ -10,7 +10,6 @@ #include "stl.h" #include "prot_fx.h" /* Function prototypes */ #include "prot_fx_enc.h" /* Function prototypes */ -#include "prot.h" /* Function prototypes */ /*--------------------------------------------------------------------------------------* * encode_envelope_indices_fx() @@ -19,7 +18,7 @@ *--------------------------------------------------------------------------------------*/ Word16 encode_envelope_indices_fx( /* o : Number of bits if flag_pack=0,0 if flag_pack=1 Q0 */ - BSTR_ENC_HANDLE hBstr, /* i : handle to the bitstream */ + BSTR_ENC_HANDLE hBstr, /* i : handle to the bitstream Q0 */ const Word16 num_sfm, /* i : Number of subbands Q0 */ const Word16 numnrmibits, /* i : Bitrate of fall-back coding mode Q0 */ Word16 *difidx, /* i/o: Diff indices/encoded diff indices Q0 */ @@ -68,12 +67,12 @@ Word16 encode_envelope_indices_fx( /* o : Number of b { IF( GT_16( difidx[i], index_max ) ) { - index_max = difidx[i]; + index_max = difidx[i]; /* Q0 */ move16(); } IF( LT_16( difidx[i], index_min ) ) { - index_min = difidx[i]; + index_min = difidx[i]; /* Q0 */ move16(); } } @@ -82,7 +81,7 @@ Word16 encode_envelope_indices_fx( /* o : Number of b { FOR( i = 1; i < num_sfm; i++ ) { - j = difidx[i]; + j = difidx[i]; /* Q0 */ move16(); bits = add( bits, huffsizn_tran[j] ); } @@ -95,24 +94,24 @@ Word16 encode_envelope_indices_fx( /* o : Number of b /* LC mode 0 = Context based coding */ FOR( i = 1; i < num_sfm; i++ ) { - j = difidx[i]; + j = difidx[i]; /* Q0 */ move16(); IF( GT_16( prevj, HTH_NORM ) ) { /* above */ - hcode_l = add( hcode_l, huffsizn_n[31 - j] ); + hcode_l = add( hcode_l, huffsizn_n[31 - j] ); /* Q0 */ } ELSE { IF( LT_16( prevj, LTH_NORM ) ) { /* less */ - hcode_l = add( hcode_l, huffsizn_n[j] ); + hcode_l = add( hcode_l, huffsizn_n[j] ); /* Q0 */ } ELSE { /* equal */ - hcode_l = add( hcode_l, huffsizn_e[j] ); + hcode_l = add( hcode_l, huffsizn_e[j] ); /* Q0 */ } } prevj = j; @@ -136,24 +135,24 @@ Word16 encode_envelope_indices_fx( /* o : Number of b prevj = add( difidx[0], OFFSET_NORM ); FOR( i = 1; i < num_sfm; i++ ) { - j = difidx[i]; + j = difidx[i]; /* Q0 */ move16(); IF( GT_16( prevj, HTH_NORM ) ) { /* above */ - hcode_l = add( hcode_l, huffsizn_n[sub( 31, j )] ); + hcode_l = add( hcode_l, huffsizn_n[( 31 - j )] ); /* Q0 */ } ELSE { IF( LT_16( prevj, LTH_NORM ) ) { /* less */ - hcode_l = add( hcode_l, huffsizn_n[j] ); + hcode_l = add( hcode_l, huffsizn_n[j] ); /* Q0 */ } ELSE { /* equal */ - hcode_l = add( hcode_l, huffsizn_e[j] ); + hcode_l = add( hcode_l, huffsizn_e[j] ); /* Q0 */ } } prevj = j; @@ -171,16 +170,16 @@ Word16 encode_envelope_indices_fx( /* o : Number of b move16(); FOR( i = 1; i < num_sfm; i++ ) { - j = difidx[i]; + j = difidx[i]; /* Q0 */ move16(); - bits = add( bits, huffsizn[j] ); + bits = add( bits, huffsizn[j] ); /* Q0 */ } /*------------------------------------------------------------------------------* * comparing bit expenses of coding mode 2 with that of the optimal coding mode *------------------------------------------------------------------------------*/ - if ( GT_16( hcode_l, bits ) ) + IF( GT_16( hcode_l, bits ) ) { *LCmode = 2; move16(); @@ -197,7 +196,7 @@ Word16 encode_envelope_indices_fx( /* o : Number of b move16(); FOR( i = 1; i < num_sfm; i++ ) { - difidx_org[i] = difidx[i]; + difidx_org[i] = difidx[i]; /* Q0 */ move16(); } @@ -207,7 +206,7 @@ Word16 encode_envelope_indices_fx( /* o : Number of b { IF( GT_16( difidx_org[i - 1], 17 ) ) { - difidx[i] = add( difidx_org[i], s_min( sub( difidx_org[i - 1], 17 ), 3 ) ); + difidx[i] = add( difidx_org[i], s_min( sub( difidx_org[i - 1], 17 ), 3 ) ); /* Q0 */ move16(); IF( GT_16( difidx[i], 31 ) ) { @@ -219,7 +218,7 @@ Word16 encode_envelope_indices_fx( /* o : Number of b IF( LT_16( difidx_org[i - 1], 13 ) ) { - difidx[i] = add( difidx_org[i], s_max( sub( difidx_org[i - 1], 13 ), -3 ) ); + difidx[i] = add( difidx_org[i], s_max( sub( difidx_org[i - 1], 13 ), -3 ) ); /* Q0 */ move16(); IF( difidx[i] < 0 ) { @@ -246,7 +245,7 @@ Word16 encode_envelope_indices_fx( /* o : Number of b { FOR( i = 1; i < num_sfm; i++ ) { - j = difidx[i]; + j = difidx[i]; /* Q0 */ move16(); bits = add( bits, resize_huffsizn[j] ); } @@ -255,7 +254,7 @@ Word16 encode_envelope_indices_fx( /* o : Number of b * comparing bit expenses of coding mode 1 with that of coding mode 0 *------------------------------------------------------------------*/ - if ( GT_16( hcode_l, bits ) ) + IF( GT_16( hcode_l, bits ) ) { *LCmode = 1; move16(); @@ -271,7 +270,7 @@ Word16 encode_envelope_indices_fx( /* o : Number of b * comparing bit expenses of coding mode 3 with that of the optimal coding mode *------------------------------------------------------------------------------*/ - if ( GE_16( hcode_l, numnrmibits ) ) + IF( GE_16( hcode_l, numnrmibits ) ) { *LCmode = 3; move16(); @@ -285,7 +284,7 @@ Word16 encode_envelope_indices_fx( /* o : Number of b { FOR( i = 2; i < num_sfm; i++ ) { - difidx[i] = difidx_org[i]; + difidx[i] = difidx_org[i]; /* Q0 */ move16(); } } @@ -315,11 +314,11 @@ Word16 encode_envelope_indices_fx( /* o : Number of b /* LC mode 0 Transient Huffman Coding */ FOR( i = 1; i < num_sfm; i++ ) { - j = difidx[i]; + j = difidx[i]; /* Q0 */ move16(); - m = huffnorm_tran[j]; + m = huffnorm_tran[j]; /* Q0 */ move16(); - r = huffsizn_tran[j]; + r = huffsizn_tran[j]; /* Q0 */ move16(); v = 0; move16(); @@ -327,9 +326,9 @@ Word16 encode_envelope_indices_fx( /* o : Number of b /* Bit reverse */ FOR( k = 0; k < r; k++ ) { - v = lshl( v, 1 ); - v = s_or( v, s_and( m, 1 ) ); - m = lshr( m, 1 ); + v = lshl( v, 1 ); /* Q0 */ + v = s_or( v, s_and( m, 1 ) ); /* Q0 */ + m = lshr( m, 1 ); /* Q0 */ } push_indice_fx( hBstr, IND_HQ2_DIFF_ENERGY, v, r ); @@ -341,15 +340,15 @@ Word16 encode_envelope_indices_fx( /* o : Number of b prevj = add( difidx[0], OFFSET_NORM ); FOR( i = 1; i < num_sfm; i++ ) { - j = difidx[i]; + j = difidx[i]; /* Q0 */ move16(); IF( GT_16( prevj, HTH_NORM ) ) { /* above */ - r = huffsizn_n[sub( 31, j )]; + r = huffsizn_n[( 31 - j )]; /* Q0 */ move16(); - m = huffnorm_n[sub( 31, j )]; + m = huffnorm_n[( 31 - j )]; /* Q0 */ move16(); } ELSE @@ -357,17 +356,17 @@ Word16 encode_envelope_indices_fx( /* o : Number of b IF( LT_16( prevj, LTH_NORM ) ) { /* less */ - r = huffsizn_n[j]; + r = huffsizn_n[j]; /* Q0 */ move16(); - m = huffnorm_n[j]; + m = huffnorm_n[j]; /* Q0 */ move16(); } ELSE { /* equal */ - r = huffsizn_e[j]; + r = huffsizn_e[j]; /* Q0 */ move16(); - m = huffnorm_e[j]; + m = huffnorm_e[j]; /* Q0 */ move16(); } } @@ -387,15 +386,15 @@ Word16 encode_envelope_indices_fx( /* o : Number of b prevj = add( difidx[0], OFFSET_NORM ); FOR( i = 1; i < num_sfm; i++ ) { - j = difidx[i]; + j = difidx[i]; /* Q0 */ move16(); IF( GT_16( prevj, HTH_NORM ) ) { /* above */ - r = huffsizn_n[sub( 31, j )]; + r = huffsizn_n[( 31 - j )]; /* Q0 */ move16(); - m = huffnorm_n[sub( 31, j )]; + m = huffnorm_n[( 31 - j )]; /* Q0 */ move16(); } ELSE @@ -403,17 +402,17 @@ Word16 encode_envelope_indices_fx( /* o : Number of b IF( LT_16( prevj, LTH_NORM ) ) { /* less */ - r = huffsizn_n[j]; + r = huffsizn_n[j]; /* Q0 */ move16(); - m = huffnorm_n[j]; + m = huffnorm_n[j]; /* Q0 */ move16(); } ELSE { /* equal */ - r = huffsizn_e[j]; + r = huffsizn_e[j]; /* Q0 */ move16(); - m = huffnorm_e[j]; + m = huffnorm_e[j]; /* Q0 */ move16(); } } @@ -441,7 +440,7 @@ Word16 encode_envelope_indices_fx( /* o : Number of b move16(); FOR( i = 1; i < num_sfm; i++ ) { - difidx_org[i] = difidx[i]; + difidx_org[i] = difidx[i]; /* Q0 */ move16(); } @@ -449,7 +448,7 @@ Word16 encode_envelope_indices_fx( /* o : Number of b { IF( GT_16( difidx_org[i - 1], 17 ) ) { - difidx[i] = add( difidx_org[i], s_min( sub( difidx_org[i - 1], 17 ), 3 ) ); + difidx[i] = add( difidx_org[i], s_min( sub( difidx_org[i - 1], 17 ), 3 ) ); /* Q0 */ move16(); IF( GT_16( difidx[i], 31 ) ) { @@ -461,7 +460,7 @@ Word16 encode_envelope_indices_fx( /* o : Number of b IF( LT_16( difidx_org[i - 1], 13 ) ) { - difidx[i] = add( difidx_org[i], s_max( sub( difidx_org[i - 1], 13 ), -3 ) ); + difidx[i] = add( difidx_org[i], s_max( sub( difidx_org[i - 1], 13 ), -3 ) ); /* Q0 */ move16(); IF( difidx[i] < 0 ) { @@ -486,7 +485,7 @@ Word16 encode_envelope_indices_fx( /* o : Number of b { FOR( i = 1; i < num_sfm; i++ ) { - j = difidx[i]; + j = difidx[i]; /* Q0 */ move16(); } } @@ -496,12 +495,12 @@ Word16 encode_envelope_indices_fx( /* o : Number of b /* LC mode 2 -> LC mode 1 */ FOR( i = 1; i < num_sfm; i++ ) { - j = difidx[i]; + j = difidx[i]; /* Q0 */ move16(); - m = resize_huffnorm[j]; + m = resize_huffnorm[j]; /* Q0 */ move16(); - r = resize_huffsizn[j]; + r = resize_huffsizn[j]; /* Q0 */ move16(); v = 0; move16(); @@ -509,9 +508,9 @@ Word16 encode_envelope_indices_fx( /* o : Number of b /* Bit reverse */ FOR( k = 0; k < r; k++ ) { - v = lshl( v, 1 ); - v = s_or( v, s_and( m, 1 ) ); - m = lshr( m, 1 ); + v = lshl( v, 1 ); /* Q0 */ + v = s_or( v, s_and( m, 1 ) ); /* Q0 */ + m = lshr( m, 1 ); /* Q0 */ } IF( flag_HQ2 == 0 ) @@ -529,12 +528,12 @@ Word16 encode_envelope_indices_fx( /* o : Number of b /* LC mode 1 -> LC mode 2 */ FOR( i = 1; i < num_sfm; i++ ) { - j = difidx[i]; + j = difidx[i]; /* Q0 */ move16(); - m = huffnorm[j]; + m = huffnorm[j]; /* Q0 */ move16(); - r = huffsizn[j]; + r = huffsizn[j]; /* Q0 */ move16(); push_indice_fx( hBstr, IND_YNRM, m, r ); @@ -554,7 +553,7 @@ Word16 encode_envelope_indices_fx( /* o : Number of b } Word16 encode_envelope_indices_ivas_fx( /* o : Number of bits if flag_pack=0,0 if flag_pack=1 Q0 */ - BSTR_ENC_HANDLE hBstr, /* i : handle to the bitstream */ + BSTR_ENC_HANDLE hBstr, /* i : handle to the bitstream Q0 */ const Word16 num_sfm, /* i : Number of subbands Q0 */ const Word16 numnrmibits, /* i : Bitrate of fall-back coding mode Q0 */ Word16 *difidx, /* i/o: Diff indices/encoded diff indices Q0 */ @@ -603,12 +602,12 @@ Word16 encode_envelope_indices_ivas_fx( /* o : Number { IF( GT_16( difidx[i], index_max ) ) { - index_max = difidx[i]; + index_max = difidx[i]; /* Q0 */ move16(); } IF( LT_16( difidx[i], index_min ) ) { - index_min = difidx[i]; + index_min = difidx[i]; /* Q0 */ move16(); } } @@ -617,7 +616,7 @@ Word16 encode_envelope_indices_ivas_fx( /* o : Number { FOR( i = 1; i < num_sfm; i++ ) { - j = difidx[i]; + j = difidx[i]; /* Q0 */ move16(); bits = add( bits, huffsizn_tran[j] ); } @@ -630,24 +629,24 @@ Word16 encode_envelope_indices_ivas_fx( /* o : Number /* LC mode 0 = Context based coding */ FOR( i = 1; i < num_sfm; i++ ) { - j = difidx[i]; + j = difidx[i]; /* Q0 */ move16(); IF( GT_16( prevj, HTH_NORM ) ) { /* above */ - hcode_l = add( hcode_l, huffsizn_n[31 - j] ); + hcode_l = add( hcode_l, huffsizn_n[31 - j] ); /* Q0 */ } ELSE { IF( LT_16( prevj, LTH_NORM ) ) { /* less */ - hcode_l = add( hcode_l, huffsizn_n[j] ); + hcode_l = add( hcode_l, huffsizn_n[j] ); /* Q0 */ } ELSE { /* equal */ - hcode_l = add( hcode_l, huffsizn_e[j] ); + hcode_l = add( hcode_l, huffsizn_e[j] ); /* Q0 */ } } prevj = j; @@ -671,24 +670,24 @@ Word16 encode_envelope_indices_ivas_fx( /* o : Number prevj = add( difidx[0], OFFSET_NORM ); FOR( i = 1; i < num_sfm; i++ ) { - j = difidx[i]; + j = difidx[i]; /* Q0 */ move16(); IF( GT_16( prevj, HTH_NORM ) ) { /* above */ - hcode_l = add( hcode_l, huffsizn_n[sub( 31, j )] ); + hcode_l = add( hcode_l, huffsizn_n[( 31 - j )] ); /* Q0 */ } ELSE { IF( LT_16( prevj, LTH_NORM ) ) { /* less */ - hcode_l = add( hcode_l, huffsizn_n[j] ); + hcode_l = add( hcode_l, huffsizn_n[j] ); /* Q0 */ } ELSE { /* equal */ - hcode_l = add( hcode_l, huffsizn_e[j] ); + hcode_l = add( hcode_l, huffsizn_e[j] ); /* Q0 */ } } prevj = j; @@ -706,7 +705,7 @@ Word16 encode_envelope_indices_ivas_fx( /* o : Number move16(); FOR( i = 1; i < num_sfm; i++ ) { - j = difidx[i]; + j = difidx[i]; /* Q0 */ move16(); bits = add( bits, huffsizn[j] ); } @@ -715,7 +714,7 @@ Word16 encode_envelope_indices_ivas_fx( /* o : Number * comparing bit expenses of coding mode 2 with that of the optimal coding mode *------------------------------------------------------------------------------*/ - if ( GT_16( hcode_l, bits ) ) + IF( GT_16( hcode_l, bits ) ) { *LCmode = 2; move16(); @@ -732,7 +731,7 @@ Word16 encode_envelope_indices_ivas_fx( /* o : Number move16(); FOR( i = 1; i < num_sfm; i++ ) { - difidx_org[i] = difidx[i]; + difidx_org[i] = difidx[i]; /* Q0 */ move16(); } @@ -742,7 +741,7 @@ Word16 encode_envelope_indices_ivas_fx( /* o : Number { IF( GT_16( difidx_org[i - 1], 17 ) ) { - difidx[i] = add( difidx_org[i], s_min( sub( difidx_org[i - 1], 17 ), 3 ) ); + difidx[i] = add( difidx_org[i], s_min( sub( difidx_org[i - 1], 17 ), 3 ) ); /* Q0 */ move16(); IF( GT_16( difidx[i], 31 ) ) { @@ -754,7 +753,7 @@ Word16 encode_envelope_indices_ivas_fx( /* o : Number IF( LT_16( difidx_org[i - 1], 13 ) ) { - difidx[i] = add( difidx_org[i], s_max( sub( difidx_org[i - 1], 13 ), -3 ) ); + difidx[i] = add( difidx_org[i], s_max( sub( difidx_org[i - 1], 13 ), -3 ) ); /* Q0 */ move16(); IF( difidx[i] < 0 ) { @@ -781,7 +780,7 @@ Word16 encode_envelope_indices_ivas_fx( /* o : Number { FOR( i = 1; i < num_sfm; i++ ) { - j = difidx[i]; + j = difidx[i]; /* Q0 */ move16(); bits = add( bits, resize_huffsizn[j] ); } @@ -790,7 +789,7 @@ Word16 encode_envelope_indices_ivas_fx( /* o : Number * comparing bit expenses of coding mode 1 with that of coding mode 0 *------------------------------------------------------------------*/ - if ( GT_16( hcode_l, bits ) ) + IF( GT_16( hcode_l, bits ) ) { *LCmode = 1; move16(); @@ -806,7 +805,7 @@ Word16 encode_envelope_indices_ivas_fx( /* o : Number * comparing bit expenses of coding mode 3 with that of the optimal coding mode *------------------------------------------------------------------------------*/ - if ( GE_16( hcode_l, numnrmibits ) ) + IF( GE_16( hcode_l, numnrmibits ) ) { *LCmode = 3; move16(); @@ -820,7 +819,7 @@ Word16 encode_envelope_indices_ivas_fx( /* o : Number { FOR( i = 2; i < num_sfm; i++ ) { - difidx[i] = difidx_org[i]; + difidx[i] = difidx_org[i]; /* Q0 */ move16(); } } @@ -850,11 +849,11 @@ Word16 encode_envelope_indices_ivas_fx( /* o : Number /* LC mode 0 Transient Huffman Coding */ FOR( i = 1; i < num_sfm; i++ ) { - j = difidx[i]; + j = difidx[i]; /* Q0 */ move16(); - m = huffnorm_tran[j]; + m = huffnorm_tran[j]; /* Q0 */ move16(); - r = huffsizn_tran[j]; + r = huffsizn_tran[j]; /* Q0 */ move16(); v = 0; move16(); @@ -862,9 +861,9 @@ Word16 encode_envelope_indices_ivas_fx( /* o : Number /* Bit reverse */ FOR( k = 0; k < r; k++ ) { - v = lshl( v, 1 ); - v = s_or( v, s_and( m, 1 ) ); - m = lshr( m, 1 ); + v = lshl( v, 1 ); /* Q0 */ + v = s_or( v, s_and( m, 1 ) ); /* Q0 */ + m = lshr( m, 1 ); /* Q0 */ } push_indice( hBstr, IND_HQ2_DIFF_ENERGY, v, r ); @@ -876,15 +875,15 @@ Word16 encode_envelope_indices_ivas_fx( /* o : Number prevj = add( difidx[0], OFFSET_NORM ); FOR( i = 1; i < num_sfm; i++ ) { - j = difidx[i]; + j = difidx[i]; /* Q0 */ move16(); IF( GT_16( prevj, HTH_NORM ) ) { /* above */ - r = huffsizn_n[sub( 31, j )]; + r = huffsizn_n[( 31 - j )]; /* Q0 */ move16(); - m = huffnorm_n[sub( 31, j )]; + m = huffnorm_n[( 31 - j )]; /* Q0 */ move16(); } ELSE @@ -892,17 +891,17 @@ Word16 encode_envelope_indices_ivas_fx( /* o : Number IF( LT_16( prevj, LTH_NORM ) ) { /* less */ - r = huffsizn_n[j]; + r = huffsizn_n[j]; /* Q0 */ move16(); - m = huffnorm_n[j]; + m = huffnorm_n[j]; /* Q0 */ move16(); } ELSE { /* equal */ - r = huffsizn_e[j]; + r = huffsizn_e[j]; /* Q0 */ move16(); - m = huffnorm_e[j]; + m = huffnorm_e[j]; /* Q0 */ move16(); } } @@ -922,15 +921,15 @@ Word16 encode_envelope_indices_ivas_fx( /* o : Number prevj = add( difidx[0], OFFSET_NORM ); FOR( i = 1; i < num_sfm; i++ ) { - j = difidx[i]; + j = difidx[i]; /* Q0 */ move16(); IF( GT_16( prevj, HTH_NORM ) ) { /* above */ - r = huffsizn_n[sub( 31, j )]; + r = huffsizn_n[( 31 - j )]; /* Q0 */ move16(); - m = huffnorm_n[sub( 31, j )]; + m = huffnorm_n[( 31 - j )]; /* Q0 */ move16(); } ELSE @@ -938,17 +937,17 @@ Word16 encode_envelope_indices_ivas_fx( /* o : Number IF( LT_16( prevj, LTH_NORM ) ) { /* less */ - r = huffsizn_n[j]; + r = huffsizn_n[j]; /* Q0 */ move16(); - m = huffnorm_n[j]; + m = huffnorm_n[j]; /* Q0 */ move16(); } ELSE { /* equal */ - r = huffsizn_e[j]; + r = huffsizn_e[j]; /* Q0 */ move16(); - m = huffnorm_e[j]; + m = huffnorm_e[j]; /* Q0 */ move16(); } } @@ -976,7 +975,7 @@ Word16 encode_envelope_indices_ivas_fx( /* o : Number move16(); FOR( i = 1; i < num_sfm; i++ ) { - difidx_org[i] = difidx[i]; + difidx_org[i] = difidx[i]; /* Q0 */ move16(); } @@ -984,7 +983,7 @@ Word16 encode_envelope_indices_ivas_fx( /* o : Number { IF( GT_16( difidx_org[i - 1], 17 ) ) { - difidx[i] = add( difidx_org[i], s_min( sub( difidx_org[i - 1], 17 ), 3 ) ); + difidx[i] = add( difidx_org[i], s_min( sub( difidx_org[i - 1], 17 ), 3 ) ); /* Q0 */ move16(); IF( GT_16( difidx[i], 31 ) ) { @@ -996,7 +995,7 @@ Word16 encode_envelope_indices_ivas_fx( /* o : Number IF( LT_16( difidx_org[i - 1], 13 ) ) { - difidx[i] = add( difidx_org[i], s_max( sub( difidx_org[i - 1], 13 ), -3 ) ); + difidx[i] = add( difidx_org[i], s_max( sub( difidx_org[i - 1], 13 ), -3 ) ); /* Q0 */ move16(); IF( difidx[i] < 0 ) { @@ -1021,7 +1020,7 @@ Word16 encode_envelope_indices_ivas_fx( /* o : Number { FOR( i = 1; i < num_sfm; i++ ) { - j = difidx[i]; + j = difidx[i]; /* Q0 */ move16(); } } @@ -1031,12 +1030,12 @@ Word16 encode_envelope_indices_ivas_fx( /* o : Number /* LC mode 2 -> LC mode 1 */ FOR( i = 1; i < num_sfm; i++ ) { - j = difidx[i]; + j = difidx[i]; /* Q0 */ move16(); - m = resize_huffnorm[j]; + m = resize_huffnorm[j]; /* Q0 */ move16(); - r = resize_huffsizn[j]; + r = resize_huffsizn[j]; /* Q0 */ move16(); v = 0; move16(); @@ -1044,9 +1043,9 @@ Word16 encode_envelope_indices_ivas_fx( /* o : Number /* Bit reverse */ FOR( k = 0; k < r; k++ ) { - v = lshl( v, 1 ); - v = s_or( v, s_and( m, 1 ) ); - m = lshr( m, 1 ); + v = lshl( v, 1 ); /* Q0 */ + v = s_or( v, s_and( m, 1 ) ); /* Q0 */ + m = lshr( m, 1 ); /* Q0 */ } IF( flag_HQ2 == 0 ) @@ -1064,12 +1063,12 @@ Word16 encode_envelope_indices_ivas_fx( /* o : Number /* LC mode 1 -> LC mode 2 */ FOR( i = 1; i < num_sfm; i++ ) { - j = difidx[i]; + j = difidx[i]; /* Q0 */ move16(); - m = huffnorm[j]; + m = huffnorm[j]; /* Q0 */ move16(); - r = huffsizn[j]; + r = huffsizn[j]; /* Q0 */ move16(); push_indice( hBstr, IND_YNRM, m, r ); @@ -1113,20 +1112,20 @@ void diff_envelope_coding_fx( /* Reorder quantization indices and quantized norms */ reordernorm_fx( ynrm, normqlg2, idxbuf, normbuf, num_env_bands ); diffcod_fx( num_env_bands, idxbuf, &difidx[1] ); - difidx[0] = idxbuf[0]; + difidx[0] = idxbuf[0]; /* Q0 */ move16(); recovernorm_fx( idxbuf, ynrm, normqlg2, num_env_bands ); } ELSE { diffcod_fx( num_env_bands, &ynrm[start_norm], &difidx[1] ); - difidx[0] = ynrm[start_norm]; + difidx[0] = ynrm[start_norm]; /* Q0 */ move16(); tmp = add( start_norm, num_env_bands ); FOR( i = start_norm; i < tmp; i++ ) { - normqlg2[i] = dicnlg2[ynrm[i]]; + normqlg2[i] = dicnlg2[ynrm[i]]; /* Q0 */ move16(); move16(); } diff --git a/lib_enc/hq_hr_enc.c b/lib_enc/hq_hr_enc.c deleted file mode 100644 index 07080804eb0063c217028438ad92480e21232fde..0000000000000000000000000000000000000000 --- a/lib_enc/hq_hr_enc.c +++ /dev/null @@ -1,278 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include "cnst.h" -#include "prot.h" -#include "prot_fx.h" -#include "ivas_prot_fx.h" -#include "prot_fx_enc.h" -#include "rom_enc.h" -#include "rom_com.h" -#include "wmc_auto.h" - -/*--------------------------------------------------------------------------* - * hq_hr_enc() - * - * HQ high rate encoding routine - *--------------------------------------------------------------------------*/ - -void hq_hr_enc_ivas_fx( - Encoder_State *st, /* i/o: encoder state structure */ - Word32 *t_audio_fx, /* i/o: transform-domain coefficients */ - const Word16 length, /* i : length of spectrum */ - Word16 *num_bits, /* i/o: number of available bits */ - const Word16 is_transient, /* i : transient flag */ - const Word16 vad_hover_flag /* i : VAD hangover flag */ -) -{ - Word16 nb_sfm; - Word16 sum, hcode_l; - Word16 difidx[NB_SFM]; - Word16 normqlg2[NB_SFM], ynrm[NB_SFM]; - Word16 nf_idx; - Word16 bits; - Word16 LCmode; - Word16 shape_bits, num_sfm, numnrmibits; - Word16 hqswb_clas; - Word16 num_env_bands; - Word16 Npeaks, start_norm; - Word16 difidx_org[NB_SFM]; - Word16 R[NB_SFM]; - Word16 peaks[HVQ_MAX_PEAKS]; - Word16 sfmsize[NB_SFM], sfm_start[NB_SFM], sfm_end[NB_SFM]; - Word16 npulses[NB_SFM], maxpulse[NB_SFM]; - Word16 Rsubband[NB_SFM]; /* Q3 */ - Word32 t_audio_q_fx[L_SPEC48k_EXT]; - Word16 noise_level_fx[HVQ_BWE_NOISE_BANDS]; - Word16 hq_generic_offset; - Word16 hq_generic_exc_clas = 0; - move16(); - Word16 core_sfm; - Word16 har_freq_est1 = 0, har_freq_est2 = 0; - move16(); - move16(); - Word16 flag_dis = 1; - move16(); - const Word16 *subband_search_offset; - Word16 wBands[2]; - Word16 b_delta_env; - HQ_ENC_HANDLE hHQ_core = st->hHQ_core; - BSTR_ENC_HANDLE hBstr = st->hBstr; - Word16 att_fx; - Word16 t_audio_norm[L_FRAME48k_EXT]; - Word16 t_audio_q_norm[L_FRAME48k_EXT]; - Word32 nf_gains_fx[HVQ_NF_GROUPS], pe_gains_fx[HVQ_NF_GROUPS]; - Word16 hq_generic_fenv_fx[HQ_FB_FENV]; - /*------------------------------------------------------------------* - * Initializations - *------------------------------------------------------------------*/ - - Npeaks = 0; - move16(); - set16_fx( npulses, 0, NB_SFM ); - set16_fx( maxpulse, 0, NB_SFM ); - set16_fx( difidx_org, 0, NB_SFM ); - set32_fx( t_audio_q_fx, 0, L_FRAME48k ); - set32_fx( nf_gains_fx, 0, HVQ_NF_GROUPS ); - set32_fx( pe_gains_fx, 0, HVQ_NF_GROUPS ); - /*------------------------------------------------------------------* - * Classification - *------------------------------------------------------------------*/ - bits = hq_classifier_enc_ivas_fx( st, length, t_audio_fx, is_transient, &Npeaks, peaks, pe_gains_fx, nf_gains_fx, &hqswb_clas ); - *num_bits = sub( *num_bits, bits ); - move16(); - - /*------------------------------------------------------------------* - * Set quantization parameters - *------------------------------------------------------------------*/ - - hq_configure_fx( length, hqswb_clas, st->core_brate, &num_sfm, &nb_sfm, &start_norm, &num_env_bands, &numnrmibits, &hq_generic_offset, sfmsize, sfm_start, sfm_end ); - - /*------------------------------------------------------------------* - * Transient frame handling - *------------------------------------------------------------------*/ - /* Interleave MLT coefficients of 4 sub-vectors in case of transient frame */ - IF( is_transient ) - { - interleave_spectrum_ivas_fx( t_audio_fx, length ); - } - test(); - IF( EQ_16( st->element_mode, IVAS_CPE_DFT ) || EQ_16( st->element_mode, IVAS_CPE_TD ) ) - { - calculate_hangover_attenuation_gain_ivas_fx( st, &att_fx, vad_hover_flag ); - v_multc_att32( t_audio_fx, att_fx, t_audio_fx, sfm_end[sub( num_sfm, 1 )] ); - } - - /*------------------------------------------------------------------* - * Scalar quantization of norms - * Encode norm indices - *------------------------------------------------------------------*/ - - /* calculate and quantize norms */ - calc_norm_ivas_fx( t_audio_fx, ynrm, normqlg2, start_norm, num_env_bands, sfmsize, sfm_start ); - /* create differential code of quantized norm indices */ - diff_envelope_coding_fx( is_transient, num_env_bands, start_norm, ynrm, normqlg2, difidx ); - - /* Find norm coding mode and calculate number of bits */ - hcode_l = encode_envelope_indices_ivas_fx( hBstr, num_env_bands, numnrmibits, difidx, &LCmode, 0, NORMAL_HQ_CORE, is_transient ); - - *num_bits = sub( *num_bits, add( hcode_l, NORM0_BITS + FLAGS_BITS ) ); - move16(); - /* Encode norm indices */ - encode_envelope_indices_ivas_fx( hBstr, num_env_bands, numnrmibits, difidx, &LCmode, 1, NORMAL_HQ_CORE, is_transient ); - - /*------------------------------------------------------------------* - * HQ GENERIC BWE encoding - *------------------------------------------------------------------*/ - - test(); - IF( EQ_16( hqswb_clas, HQ_GEN_SWB ) || EQ_16( hqswb_clas, HQ_GEN_FB ) ) - { - hq_generic_hf_encoding_fx( t_audio_fx, hq_generic_fenv_fx, hq_generic_offset, st, &hq_generic_exc_clas, length ); - - IF( EQ_16( hq_generic_exc_clas, HQ_GENERIC_SP_EXC ) ) - { - *num_bits = add( *num_bits, 1 ); /* conditional 1 bit saving for representing FD3 BWE excitation class */ - move16(); - } - map_hq_generic_fenv_norm_fx( hqswb_clas, hq_generic_fenv_fx, ynrm, normqlg2, num_env_bands, nb_sfm, hq_generic_offset ); - } - - /*------------------------------------------------------------------* - * Bit allocation - *------------------------------------------------------------------*/ - - ivas_hq_bit_allocation_fx( st->core_brate, length, hqswb_clas, num_bits, normqlg2, nb_sfm, sfmsize, noise_level_fx, R, Rsubband, &sum, &core_sfm, num_env_bands ); - - /*------------------------------------------------------------------* - * Normalize coefficients with quantized norms - *------------------------------------------------------------------*/ - IF( NE_16( hqswb_clas, HQ_HVQ ) ) - { - test(); - IF( EQ_16( hqswb_clas, HQ_GEN_SWB ) || EQ_16( hqswb_clas, HQ_GEN_FB ) ) - { - b_delta_env = calc_nor_delta_hf_ivas_fx( hBstr, t_audio_fx, ynrm, Rsubband, num_env_bands, nb_sfm, sfmsize, sfm_start, core_sfm ); - sum = sub( sum, b_delta_env ); - } - normalizecoefs_fx( t_audio_fx, ynrm, nb_sfm, sfm_start, sfm_end, t_audio_norm ); - } - Word16 Q_audio = 12, Q_shift; - /*------------------------------------------------------------------* - * Quantize/code spectral fine structure using PVQ or HVQ - *------------------------------------------------------------------*/ - IF( EQ_16( hqswb_clas, HQ_HVQ ) ) - { - sum = hvq_enc_ivas_fx( st, st->core_brate, *num_bits, Npeaks, ynrm, R, peaks, nf_gains_fx, noise_level_fx, pe_gains_fx, t_audio_fx, t_audio_q_fx ); - *num_bits = sub( *num_bits, sum ); - move16(); - } - ELSE - { - shape_bits = pvq_core_enc_ivas_fx( hBstr, t_audio_norm, t_audio_q_norm, &Q_audio, sum, nb_sfm, sfm_start, sfm_end, sfmsize, Rsubband, R, npulses, maxpulse, HQ_CORE ); - *num_bits = add( *num_bits, sub( sum, shape_bits ) ); - move16(); - } - - test(); - IF( EQ_16( hqswb_clas, HQ_HVQ ) || EQ_16( hqswb_clas, HQ_HARMONIC ) ) - { - subband_search_offset = subband_search_offsets_13p2kbps_Har; - wBands[0] = SWB_SB_BW_LEN0_16KBPS_HAR; - wBands[1] = SWB_SB_BW_LEN1_16KBPS_HAR; - move16(); - move16(); - IF( EQ_16( hqswb_clas, HQ_HARMONIC ) ) - { - Q_shift = sub( SWB_BWE_LR_Qs, Q_audio ); - FOR( Word16 i = 0; i < 300; i++ ) - { - t_audio_q_fx[i] = L_shl( L_deposit_l( t_audio_q_norm[i] ), Q_shift ); /* Q12 */ - move32(); - } - } - har_est_fx( t_audio_q_fx, 300, &har_freq_est1, &har_freq_est2, &flag_dis, &hHQ_core->prev_frm_hfe2, subband_search_offset, wBands, &hHQ_core->prev_stab_hfe2 ); - - hHQ_core->prev_frm_hfe2 = har_freq_est2; - move16(); - } - - /* reset LR-HQ memories */ - hHQ_core->prev_frm_hfe2 = 0; /*reset*/ - hHQ_core->prev_stab_hfe2 = 0; - move16(); - move16(); - nf_idx = 0; - move16(); - test(); - test(); - test(); - IF( NE_16( is_transient, 1 ) && NE_16( hqswb_clas, HQ_HVQ ) && !( EQ_16( length, L_FRAME16k ) && LE_32( st->core_brate, HQ_32k ) ) ) - { - test(); - IF( EQ_16( hqswb_clas, HQ_GEN_SWB ) || EQ_16( hqswb_clas, HQ_GEN_FB ) ) - { - nf_idx = noise_adjust_fx( t_audio_norm, 12, R, sfm_start, sfm_end, s_max( core_sfm, sub( num_env_bands, 1 ) ) ); - push_indice( hBstr, IND_NF_IDX, nf_idx, 2 ); - } - ELSE - { - nf_idx = noise_adjust_fx( t_audio_norm, 12, R, sfm_start, sfm_end, core_sfm ); - push_indice( hBstr, IND_NF_IDX, nf_idx, 2 ); - } - } - - - /* updates */ - hHQ_core->prev_hqswb_clas = hqswb_clas; - move16(); - /* Prepare synthesis for LB generation in case of switch to ACELP */ - IF( NE_16( hqswb_clas, HQ_HVQ ) ) - { - apply_envelope_enc_ivas_fx( t_audio_q_norm, ynrm, num_sfm, sfm_start, sfm_end, t_audio_q_fx ); - } - - IF( is_transient ) - { - ivas_de_interleave_spectrum_fx( t_audio_q_fx, length ); - } - - MVR2R_WORD32( t_audio_q_fx, t_audio_fx, length ); - - return; -} diff --git a/lib_enc/hq_hr_enc_fx.c b/lib_enc/hq_hr_enc_fx.c index f1ff0d62f5911f289b84cce3a05e244c8dce6e84..1cd516b43ede33b5bb2659fe020e73be8976338e 100644 --- a/lib_enc/hq_hr_enc_fx.c +++ b/lib_enc/hq_hr_enc_fx.c @@ -5,9 +5,10 @@ #include "options.h" /* Compilation switches */ #include "cnst.h" /* Common constants */ //#include "prot_fx.h" /* Function prototypes */ -#include "rom_com_fx.h" /* Static table prototypes */ -#include "rom_com.h" /* Static table prototypes */ -#include "prot_fx.h" /* Function prototypes */ +#include "rom_com_fx.h" /* Static table prototypes */ +#include "rom_com.h" /* Static table prototypes */ +#include "prot_fx.h" /* Function prototypes */ +#include "ivas_prot_fx.h" #include "prot_fx_enc.h" /* Function prototypes */ /*--------------------------------------------------------------------------* * hq_hr_enc_fx() @@ -20,7 +21,7 @@ void hq_hr_enc_fx( const Word16 length, /* i : length of spectrum Q0 */ Word16 *num_bits, /* i : number of available bits Q0 */ const Word16 is_transient, /* i : transient flag Q0 */ - const Word16 vad_hover_flag /* i : VAD hangover flag */ + const Word16 vad_hover_flag /* i : VAD hangover flag Q0 */ ) { Word16 nb_sfm; /* Q0 */ @@ -47,7 +48,8 @@ void hq_hr_enc_fx( Word16 hq_generic_offset; /* Q0 */ Word16 hq_generic_fenv[HQ_FB_FENV]; /* Q1 */ Word16 hq_generic_exc_clas = 0; /* Q0 */ - Word16 core_sfm; /* Q0 */ + move16(); + Word16 core_sfm; /* Q0 */ Word16 har_freq_est1, har_freq_est2; Word16 flag_dis; const Word16 *subband_search_offset; @@ -68,6 +70,8 @@ void hq_hr_enc_fx( Npeaks = 0; Q_audio = 0; /* to avoid compilation warnings */ + move16(); + move16(); set16_fx( npulses, 0, NB_SFM ); set16_fx( maxpulse, 0, NB_SFM ); @@ -86,9 +90,10 @@ void hq_hr_enc_fx( * Classification *------------------------------------------------------------------*/ - bits = hq_classifier_enc_fx( st_fx, length, t_audio, is_transient, &Npeaks, peaks, pe_gains, nf_gains, &hqswb_clas ); + bits = hq_classifier_enc_fx( st_fx, length, t_audio, is_transient, &Npeaks, peaks, pe_gains, nf_gains, &hqswb_clas ); /* Q0 */ - *num_bits = sub( *num_bits, bits ); + *num_bits = sub( *num_bits, bits ); /* Q0 */ + move16(); /*------------------------------------------------------------------* * set quantization parameters @@ -111,7 +116,7 @@ void hq_hr_enc_fx( IF( EQ_16( st_fx->element_mode, IVAS_CPE_DFT ) || EQ_16( st_fx->element_mode, IVAS_CPE_TD ) ) { calculate_hangover_attenuation_gain_fx( st_fx, &att, vad_hover_flag ); - v_multc_att32( t_audio, att, t_audio, sfm_end[sub( num_sfm, 1 )] ); + v_multc_att32( t_audio, att, t_audio, sfm_end[( num_sfm - 1 )] ); /* Q12 */ } /*------------------------------------------------------------------* * Scalar quantization of norms @@ -125,8 +130,9 @@ void hq_hr_enc_fx( diff_envelope_coding_fx( is_transient, num_env_bands, start_norm, ynrm, normqlg2, difidx ); /* Find coding mode and calculate bit rate */ - hcode_l = encode_envelope_indices_fx( st_fx->hBstr, num_env_bands, numnrmibits, difidx, &LCmode, 0, NORMAL_HQ_CORE, is_transient ); - *num_bits = sub( *num_bits, add( hcode_l, NORM0_BITS + FLAGS_BITS ) ); + hcode_l = encode_envelope_indices_fx( st_fx->hBstr, num_env_bands, numnrmibits, difidx, &LCmode, 0, NORMAL_HQ_CORE, is_transient ); /* Q0 */ + *num_bits = sub( *num_bits, add( hcode_l, NORM0_BITS + FLAGS_BITS ) ); /* Q0 */ + move16(); /* Encode norm indices */ encode_envelope_indices_fx( st_fx->hBstr, num_env_bands, numnrmibits, difidx, &LCmode, 1, NORMAL_HQ_CORE, is_transient ); @@ -141,7 +147,8 @@ void hq_hr_enc_fx( hq_generic_encoding_fx( t_audio, hq_generic_fenv, hq_generic_offset, st_fx, &hq_generic_exc_clas /*, length*/ ); IF( EQ_16( hq_generic_exc_clas, HQ_GENERIC_SP_EXC ) ) { - *num_bits = add( *num_bits, 1 ); /* conditional 1 bit saving for representing FD3 BWE excitation class */ + *num_bits = add( *num_bits, 1 ); /* conditional 1 bit saving for representing FD3 BWE excitation class Q0*/ + move16(); } map_hq_generic_fenv_norm_fx( hqswb_clas, hq_generic_fenv, ynrm, normqlg2, num_env_bands, nb_sfm, hq_generic_offset ); } @@ -161,11 +168,12 @@ void hq_hr_enc_fx( test(); IF( hqswb_clas == HQ_GEN_SWB || hqswb_clas == HQ_GEN_FB ) { - b_delta_env = calc_nor_delta_hf_fx( st_fx->hBstr, t_audio, ynrm, Rsubband, num_env_bands, nb_sfm, sfmsize, sfm_start, core_sfm ); - sum -= b_delta_env; + b_delta_env = calc_nor_delta_hf_fx( st_fx->hBstr, t_audio, ynrm, Rsubband, num_env_bands, nb_sfm, sfmsize, sfm_start, core_sfm ); /* Q0 */ + sum = sub( sum, b_delta_env ); } normalizecoefs_fx( t_audio, ynrm, nb_sfm, sfm_start, sfm_end, t_audio_norm ); Q_audio = 12; + move16(); } /*------------------------------------------------------------------* @@ -174,22 +182,24 @@ void hq_hr_enc_fx( IF( EQ_16( hqswb_clas, HQ_HVQ ) ) { sum = hvq_enc_fx( st_fx, st_fx->core_brate, *num_bits, Npeaks, ynrm, R, peaks, nf_gains, noise_level, pe_gains, t_audio, t_audio_q ); - *num_bits = sub( *num_bits, sum ); + *num_bits = sub( *num_bits, sum ); /* Q0 */ + move16(); } ELSE { shape_bits = pvq_core_enc_fx( st_fx->hBstr, t_audio_norm, t_audio_q_norm, &Q_audio, sum, nb_sfm, sfm_start, sfm_end, sfmsize, Rsubband, R, npulses, maxpulse, HQ_CORE ); - *num_bits = add( *num_bits, sub( sum, shape_bits ) ); + *num_bits = add( *num_bits, sub( sum, shape_bits ) ); /* Q0 */ + move16(); } test(); IF( EQ_16( hqswb_clas, HQ_HVQ ) || EQ_16( hqswb_clas, HQ_HARMONIC ) ) { - subband_search_offset = subband_search_offsets_13p2kbps_Har; - wBands[0] = SWB_SB_BW_LEN0_16KBPS_HAR; + subband_search_offset = subband_search_offsets_13p2kbps_Har; /* Q0 */ + wBands[0] = SWB_SB_BW_LEN0_16KBPS_HAR; /* Q0 */ move16(); - wBands[1] = SWB_SB_BW_LEN1_16KBPS_HAR; + wBands[1] = SWB_SB_BW_LEN1_16KBPS_HAR; /* Q0 */ move16(); IF( EQ_16( hqswb_clas, HQ_HARMONIC ) ) @@ -198,12 +208,13 @@ void hq_hr_enc_fx( FOR( i = 0; i < 300; i++ ) { t_audio_q[i] = L_shl( L_deposit_l( t_audio_q_norm[i] ), Q_shift ); /* Q12 */ + move32(); } } har_est_fx( t_audio_q, 300, &har_freq_est1, &har_freq_est2, &flag_dis, &hHQ_core->prev_frm_hfe2, subband_search_offset, wBands, &hHQ_core->prev_stab_hfe2 ); - hHQ_core->prev_frm_hfe2 = har_freq_est2; + hHQ_core->prev_frm_hfe2 = har_freq_est2; /* Q0 */ move16(); } @@ -224,17 +235,17 @@ void hq_hr_enc_fx( test(); IF( EQ_16( hqswb_clas, HQ_GEN_SWB ) || EQ_16( hqswb_clas, HQ_GEN_FB ) ) { - nf_idx = noise_adjust_fx( t_audio_norm, 12, R, sfm_start, sfm_end, s_max( core_sfm, sub( num_env_bands, 1 ) ) ); + nf_idx = noise_adjust_fx( t_audio_norm, 12, R, sfm_start, sfm_end, s_max( core_sfm, sub( num_env_bands, 1 ) ) ); /* Q0 */ push_indice_fx( st_fx->hBstr, IND_NF_IDX, nf_idx, 2 ); } ELSE { - nf_idx = noise_adjust_fx( t_audio_norm, 12, R, sfm_start, sfm_end, core_sfm ); + nf_idx = noise_adjust_fx( t_audio_norm, 12, R, sfm_start, sfm_end, core_sfm ); /* Q0 */ push_indice_fx( st_fx->hBstr, IND_NF_IDX, nf_idx, 2 ); } } /* updates */ - hHQ_core->prev_hqswb_clas = hqswb_clas; + hHQ_core->prev_hqswb_clas = hqswb_clas; /* Q0 */ move16(); /* Prepare synthesis for LB generation in case of switch to ACELP */ @@ -254,3 +265,231 @@ void hq_hr_enc_fx( return; } + +void hq_hr_enc_ivas_fx( + Encoder_State *st, /* i/o: encoder state structure */ + Word32 *t_audio_fx, /* i/o: transform-domain coefficients Q12*/ + const Word16 length, /* i : length of spectrum Q0*/ + Word16 *num_bits, /* i/o: number of available bits Q0*/ + const Word16 is_transient, /* i : transient flag Q0*/ + const Word16 vad_hover_flag /* i : VAD hangover flag Q0*/ +) +{ + Word16 nb_sfm; + Word16 sum, hcode_l; + Word16 difidx[NB_SFM]; + Word16 normqlg2[NB_SFM], ynrm[NB_SFM]; + Word16 nf_idx; + Word16 bits; + Word16 LCmode; + Word16 shape_bits, num_sfm, numnrmibits; + Word16 hqswb_clas; + Word16 num_env_bands; + Word16 Npeaks, start_norm; + Word16 difidx_org[NB_SFM]; + Word16 R[NB_SFM]; + Word16 peaks[HVQ_MAX_PEAKS]; + Word16 sfmsize[NB_SFM], sfm_start[NB_SFM], sfm_end[NB_SFM]; + Word16 npulses[NB_SFM], maxpulse[NB_SFM]; + Word16 Rsubband[NB_SFM]; /* Q3 */ + Word32 t_audio_q_fx[L_SPEC48k_EXT]; + Word16 noise_level_fx[HVQ_BWE_NOISE_BANDS]; + Word16 hq_generic_offset; + Word16 hq_generic_exc_clas = 0; + move16(); + Word16 core_sfm; + Word16 har_freq_est1 = 0, har_freq_est2 = 0; + move16(); + move16(); + Word16 flag_dis = 1; + move16(); + const Word16 *subband_search_offset; + Word16 wBands[2]; + Word16 b_delta_env; + HQ_ENC_HANDLE hHQ_core = st->hHQ_core; + BSTR_ENC_HANDLE hBstr = st->hBstr; + Word16 att_fx; + Word16 t_audio_norm[L_FRAME48k_EXT]; + Word16 t_audio_q_norm[L_FRAME48k_EXT]; + Word32 nf_gains_fx[HVQ_NF_GROUPS], pe_gains_fx[HVQ_NF_GROUPS]; + Word16 hq_generic_fenv_fx[HQ_FB_FENV]; + /*------------------------------------------------------------------* + * Initializations + *------------------------------------------------------------------*/ + + Npeaks = 0; + move16(); + set16_fx( npulses, 0, NB_SFM ); + set16_fx( maxpulse, 0, NB_SFM ); + set16_fx( difidx_org, 0, NB_SFM ); + set32_fx( t_audio_q_fx, 0, L_FRAME48k ); + set32_fx( nf_gains_fx, 0, HVQ_NF_GROUPS ); + set32_fx( pe_gains_fx, 0, HVQ_NF_GROUPS ); + /*------------------------------------------------------------------* + * Classification + *------------------------------------------------------------------*/ + bits = hq_classifier_enc_ivas_fx( st, length, t_audio_fx, is_transient, &Npeaks, peaks, pe_gains_fx, nf_gains_fx, &hqswb_clas ); /* Q0 */ + *num_bits = sub( *num_bits, bits ); + move16(); + + /*------------------------------------------------------------------* + * Set quantization parameters + *------------------------------------------------------------------*/ + + hq_configure_fx( length, hqswb_clas, st->core_brate, &num_sfm, &nb_sfm, &start_norm, &num_env_bands, &numnrmibits, &hq_generic_offset, sfmsize, sfm_start, sfm_end ); + + /*------------------------------------------------------------------* + * Transient frame handling + *------------------------------------------------------------------*/ + /* Interleave MLT coefficients of 4 sub-vectors in case of transient frame */ + IF( is_transient ) + { + interleave_spectrum_ivas_fx( t_audio_fx, length ); + } + test(); + IF( EQ_16( st->element_mode, IVAS_CPE_DFT ) || EQ_16( st->element_mode, IVAS_CPE_TD ) ) + { + calculate_hangover_attenuation_gain_ivas_fx( st, &att_fx, vad_hover_flag ); + v_multc_att32( t_audio_fx, att_fx, t_audio_fx, sfm_end[( num_sfm - 1 )] ); /* Q12 */ + } + + /*------------------------------------------------------------------* + * Scalar quantization of norms + * Encode norm indices + *------------------------------------------------------------------*/ + + /* calculate and quantize norms */ + calc_norm_ivas_fx( t_audio_fx, ynrm, normqlg2, start_norm, num_env_bands, sfmsize, sfm_start ); + /* create differential code of quantized norm indices */ + diff_envelope_coding_fx( is_transient, num_env_bands, start_norm, ynrm, normqlg2, difidx ); + + /* Find norm coding mode and calculate number of bits */ + hcode_l = encode_envelope_indices_ivas_fx( hBstr, num_env_bands, numnrmibits, difidx, &LCmode, 0, NORMAL_HQ_CORE, is_transient ); /* Q0 */ + + *num_bits = sub( *num_bits, add( hcode_l, NORM0_BITS + FLAGS_BITS ) ); + move16(); + /* Encode norm indices */ + encode_envelope_indices_ivas_fx( hBstr, num_env_bands, numnrmibits, difidx, &LCmode, 1, NORMAL_HQ_CORE, is_transient ); + + /*------------------------------------------------------------------* + * HQ GENERIC BWE encoding + *------------------------------------------------------------------*/ + + test(); + IF( EQ_16( hqswb_clas, HQ_GEN_SWB ) || EQ_16( hqswb_clas, HQ_GEN_FB ) ) + { + hq_generic_hf_encoding_fx( t_audio_fx, hq_generic_fenv_fx, hq_generic_offset, st, &hq_generic_exc_clas, length ); + + IF( EQ_16( hq_generic_exc_clas, HQ_GENERIC_SP_EXC ) ) + { + *num_bits = add( *num_bits, 1 ); /* conditional 1 bit saving for representing FD3 BWE excitation class */ + move16(); + } + map_hq_generic_fenv_norm_fx( hqswb_clas, hq_generic_fenv_fx, ynrm, normqlg2, num_env_bands, nb_sfm, hq_generic_offset ); + } + + /*------------------------------------------------------------------* + * Bit allocation + *------------------------------------------------------------------*/ + + ivas_hq_bit_allocation_fx( st->core_brate, length, hqswb_clas, num_bits, normqlg2, nb_sfm, sfmsize, noise_level_fx, R, Rsubband, &sum, &core_sfm, num_env_bands ); + + /*------------------------------------------------------------------* + * Normalize coefficients with quantized norms + *------------------------------------------------------------------*/ + IF( NE_16( hqswb_clas, HQ_HVQ ) ) + { + test(); + IF( EQ_16( hqswb_clas, HQ_GEN_SWB ) || EQ_16( hqswb_clas, HQ_GEN_FB ) ) + { + b_delta_env = calc_nor_delta_hf_ivas_fx( hBstr, t_audio_fx, ynrm, Rsubband, num_env_bands, nb_sfm, sfmsize, sfm_start, core_sfm ); /* Q0 */ + sum = sub( sum, b_delta_env ); + } + normalizecoefs_fx( t_audio_fx, ynrm, nb_sfm, sfm_start, sfm_end, t_audio_norm ); + } + Word16 Q_audio = 12, Q_shift; + move16(); + /*------------------------------------------------------------------* + * Quantize/code spectral fine structure using PVQ or HVQ + *------------------------------------------------------------------*/ + IF( EQ_16( hqswb_clas, HQ_HVQ ) ) + { + sum = hvq_enc_ivas_fx( st, st->core_brate, *num_bits, Npeaks, ynrm, R, peaks, nf_gains_fx, noise_level_fx, pe_gains_fx, t_audio_fx, t_audio_q_fx ); + *num_bits = sub( *num_bits, sum ); + move16(); + } + ELSE + { + shape_bits = pvq_core_enc_ivas_fx( hBstr, t_audio_norm, t_audio_q_norm, &Q_audio, sum, nb_sfm, sfm_start, sfm_end, sfmsize, Rsubband, R, npulses, maxpulse, HQ_CORE ); /* Q0 */ + *num_bits = add( *num_bits, sub( sum, shape_bits ) ); + move16(); + } + + test(); + IF( EQ_16( hqswb_clas, HQ_HVQ ) || EQ_16( hqswb_clas, HQ_HARMONIC ) ) + { + subband_search_offset = subband_search_offsets_13p2kbps_Har; /* Q0 */ + wBands[0] = SWB_SB_BW_LEN0_16KBPS_HAR; /* Q0 */ + wBands[1] = SWB_SB_BW_LEN1_16KBPS_HAR; /* Q0 */ + move16(); + move16(); + IF( EQ_16( hqswb_clas, HQ_HARMONIC ) ) + { + Q_shift = sub( SWB_BWE_LR_Qs, Q_audio ); + FOR( Word16 i = 0; i < 300; i++ ) + { + t_audio_q_fx[i] = L_shl( L_deposit_l( t_audio_q_norm[i] ), Q_shift ); /* Q12 */ + move32(); + } + } + har_est_fx( t_audio_q_fx, 300, &har_freq_est1, &har_freq_est2, &flag_dis, &hHQ_core->prev_frm_hfe2, subband_search_offset, wBands, &hHQ_core->prev_stab_hfe2 ); + + hHQ_core->prev_frm_hfe2 = har_freq_est2; + move16(); + } + + /* reset LR-HQ memories */ + hHQ_core->prev_frm_hfe2 = 0; /*reset*/ + hHQ_core->prev_stab_hfe2 = 0; + move16(); + move16(); + nf_idx = 0; + move16(); + test(); + test(); + test(); + IF( NE_16( is_transient, 1 ) && NE_16( hqswb_clas, HQ_HVQ ) && !( EQ_16( length, L_FRAME16k ) && LE_32( st->core_brate, HQ_32k ) ) ) + { + test(); + IF( EQ_16( hqswb_clas, HQ_GEN_SWB ) || EQ_16( hqswb_clas, HQ_GEN_FB ) ) + { + nf_idx = noise_adjust_fx( t_audio_norm, 12, R, sfm_start, sfm_end, s_max( core_sfm, sub( num_env_bands, 1 ) ) ); /* Q0 */ + push_indice( hBstr, IND_NF_IDX, nf_idx, 2 ); + } + ELSE + { + nf_idx = noise_adjust_fx( t_audio_norm, 12, R, sfm_start, sfm_end, core_sfm ); /* Q0 */ + push_indice( hBstr, IND_NF_IDX, nf_idx, 2 ); + } + } + + + /* updates */ + hHQ_core->prev_hqswb_clas = hqswb_clas; /* Q0 */ + move16(); + /* Prepare synthesis for LB generation in case of switch to ACELP */ + IF( NE_16( hqswb_clas, HQ_HVQ ) ) + { + apply_envelope_enc_ivas_fx( t_audio_q_norm, ynrm, num_sfm, sfm_start, sfm_end, t_audio_q_fx ); + scale_sig32( t_audio_q_fx, length, sub( Q12, Q_audio ) ); // Q12 + } + + IF( is_transient ) + { + ivas_de_interleave_spectrum_fx( t_audio_q_fx, length ); + } + + MVR2R_WORD32( t_audio_q_fx, t_audio_fx, length ); + + return; +} diff --git a/lib_enc/hq_lr_enc.c b/lib_enc/hq_lr_enc.c deleted file mode 100644 index b184c5ac6e19640a4c4dbf55a212d7de805f866f..0000000000000000000000000000000000000000 --- a/lib_enc/hq_lr_enc.c +++ /dev/null @@ -1,46 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include -#include "cnst.h" -#include "rom_enc.h" -#include "rom_com.h" -#include "prot.h" -#include "stl.h" -#include "basop_util.h" -#include "wmc_auto.h" diff --git a/lib_enc/hq_lr_enc_fx.c b/lib_enc/hq_lr_enc_fx.c index e602d28b36257214b18b592633dbc60b98ccb8db..9aca0f6465fd0e06e899334619e5504490d4a930 100644 --- a/lib_enc/hq_lr_enc_fx.c +++ b/lib_enc/hq_lr_enc_fx.c @@ -12,20 +12,19 @@ #include "prot_fx.h" /* Function prototypes */ #include "prot_fx_enc.h" /* Function prototypes */ #include "basop_util.h" /* Function prototypes */ -#include "prot.h" /*--------------------------------------------------------------------------* * Local function prototypes *--------------------------------------------------------------------------*/ -static Word16 band_energy_quant_fx( BSTR_ENC_HANDLE hBstr, const Word32 *L_t_audio, const Word16 band_start_fx[], const Word16 band_end_fx[], Word32 L_band_energy[], const Word16 bands_fx, const Word32 L_qint, const Word16 eref_fx, const Word16 is_transient_fx ); +static Word16 band_energy_quant_fx( BSTR_ENC_HANDLE hBstr, const Word32 *L_t_audio /*Q12*/, const Word16 band_start_fx[], const Word16 band_end_fx[], Word32 L_band_energy[] /*Q14*/, const Word16 bands_fx, const Word32 L_qint /*Q29*/, const Word16 eref_fx /*Q10*/, const Word16 is_transient_fx ); -static Word16 p2a_threshold_quant_fx( BSTR_ENC_HANDLE hBstr, const Word32 *L_t_audio, const Word16 band_start[], const Word16 band_end[], const Word16 band_width[], const Word16 bands, const Word16 p2a_bands, const Word16 p2a_th, Word16 *p2a_flags ); +static Word16 p2a_threshold_quant_fx( BSTR_ENC_HANDLE hBstr, const Word32 *L_t_audio /*Q12*/, const Word16 band_start[], const Word16 band_end[], const Word16 band_width[], const Word16 bands, const Word16 p2a_bands, const Word16 p2a_th /*Q11*/, Word16 *p2a_flags ); -static void mdct_spectrum_fine_gain_enc_fx( Encoder_State *st_fx, const Word32 L_ybuf[], Word32 L_y2[], const Word16 band_start[], const Word16 band_end[], const Word16 k_sort[], const Word16 bands, const Word32 L_qint, const Word16 Ngq, const Word16 gqlevs, const Word16 gqbits ); +static void mdct_spectrum_fine_gain_enc_fx( Encoder_State *st_fx, const Word32 L_ybuf[] /*Q12*/, Word32 L_y2[] /*Q12*/, const Word16 band_start[], const Word16 band_end[], const Word16 k_sort[], const Word16 bands, const Word32 L_qint /*Q29*/, const Word16 Ngq, const Word16 gqlevs, const Word16 gqbits ); -static Word16 p2a_threshold_quant_ivas_fx( BSTR_ENC_HANDLE hBstr, const Word32 *L_t_audio, const Word16 band_start[], const Word16 band_end[], const Word16 band_width[], const Word16 bands, const Word16 p2a_bands, const Word16 p2a_th, Word16 *p2a_flags ); +static Word16 p2a_threshold_quant_ivas_fx( BSTR_ENC_HANDLE hBstr, const Word32 *L_t_audio /*Q12*/, const Word16 band_start[], const Word16 band_end[], const Word16 band_width[], const Word16 bands, const Word16 p2a_bands, const Word16 p2a_th /*Q11*/, Word16 *p2a_flags ); static void mdct_spectrum_fine_gain_enc_ivas_fx( Encoder_State *st_fx, /* i/o: encoder state structure */ const Word32 L_ybuf[], /* i : Q12 : input spectrum */ @@ -41,15 +40,15 @@ static void mdct_spectrum_fine_gain_enc_ivas_fx( ); static Word16 band_energy_quant_ivas_fx( - BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ - const Word32 *L_t_audio, - const Word16 band_start[], - const Word16 band_end[], - Word32 L_band_energy[], - const Word16 bands_fx, - const Word32 L_qint, /* Q29 */ - const Word16 eref_fx, /* Q10 */ - const Word16 is_transient ); + BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ + const Word32 *L_t_audio, /* Q12 */ + const Word16 band_start[], /* Q0 */ + const Word16 band_end[], /* Q0 */ + Word32 L_band_energy[], /* Q14 */ + const Word16 bands_fx, /* Q0 */ + const Word32 L_qint, /* Q29 */ + const Word16 eref_fx, /* Q10 */ + const Word16 is_transient /* Q0 */ ); /*--------------------------------------------------------------------------* * spt_shorten_domain_set() @@ -59,16 +58,16 @@ static Word16 band_energy_quant_ivas_fx( static void spt_shorten_domain_set_fx( Encoder_State *st_fx, /* i: encoder state structure */ - const Word32 L_t_audio[], /* i: input spectrum */ - const Word16 p2a_flags[], /* i: p2a anlysis information */ - const Word16 new_band_start[], /* i: new band start position */ - const Word16 new_band_end[], /* i: new band end position */ - const Word16 new_band_width[], /* i: new subband band width */ - const Word16 bands, /* i: total number of subbands */ - Word16 band_start[], /* i/o: band start position */ - Word16 band_end[], /* i/o: band end position */ - Word16 band_width[], /* i: sub band band width */ - Word16 *bit_budget /* i/o: bit budget */ + const Word32 L_t_audio[], /* i: input spectrum Q12*/ + const Word16 p2a_flags[], /* i: p2a anlysis information Q0*/ + const Word16 new_band_start[], /* i: new band start position Q0*/ + const Word16 new_band_end[], /* i: new band end position Q0*/ + const Word16 new_band_width[], /* i: new subband band width Q0*/ + const Word16 bands, /* i: total number of subbands Q0*/ + Word16 band_start[], /* i/o: band start position Q0*/ + Word16 band_end[], /* i/o: band end position Q0*/ + Word16 band_width[], /* i: sub band band width Q0*/ + Word16 *bit_budget /* i/o: bit budget Q0*/ ) { Word16 i, j, k; @@ -81,7 +80,8 @@ static void spt_shorten_domain_set_fx( kpos = 0; j = 0; move16(); - FOR( k = sub( bands, SPT_SHORTEN_SBNUM ); k < bands; k++ ) + move16(); + FOR( k = ( bands - SPT_SHORTEN_SBNUM ); k < bands; k++ ) { IF( EQ_16( p2a_flags[k], 1 ) ) { @@ -96,7 +96,8 @@ static void spt_shorten_domain_set_fx( { IF( LT_32( L_max_y2, L_abs( L_t_audio[i] ) ) ) { - L_max_y2 = L_abs( L_t_audio[i] ); + L_max_y2 = L_abs( L_t_audio[i] ); /* Q12 */ + move32(); max_y2_pos = i; move16(); } @@ -104,22 +105,23 @@ static void spt_shorten_domain_set_fx( test(); IF( GE_16( max_y2_pos, new_band_start[j] ) && LE_16( max_y2_pos, new_band_end[j] ) ) { - band_start[k] = new_band_start[j]; + band_start[k] = new_band_start[j]; /* Q0 */ move16(); - band_end[k] = new_band_end[j]; + band_end[k] = new_band_end[j]; /* Q0 */ move16(); - band_width[k] = new_band_width[j]; + band_width[k] = new_band_width[j]; /* Q0 */ move16(); spt_shorten_flag[j] = 1; move16(); } } push_indice_fx( st_fx->hBstr, IND_HQ2_SPT_SHORTEN, spt_shorten_flag[j], 1 ); - *bit_budget = sub( *bit_budget, 1 ); + *bit_budget = sub( *bit_budget, 1 ); /* Q0 */ + move16(); } - kpos = add( kpos, 1 ); - j = add( j, 1 ); + kpos += 1; + j += 1; } return; @@ -127,16 +129,16 @@ static void spt_shorten_domain_set_fx( static void spt_shorten_domain_set_ivas_fx( Encoder_State *st_fx, /* i: encoder state structure */ - const Word32 L_t_audio[], /* i: input spectrum */ - const Word16 p2a_flags[], /* i: p2a anlysis information */ - const Word16 new_band_start[], /* i: new band start position */ - const Word16 new_band_end[], /* i: new band end position */ - const Word16 new_band_width[], /* i: new subband band width */ - const Word16 bands, /* i: total number of subbands */ - Word16 band_start[], /* i/o: band start position */ - Word16 band_end[], /* i/o: band end position */ - Word16 band_width[], /* i: sub band band width */ - Word16 *bit_budget /* i/o: bit budget */ + const Word32 L_t_audio[], /* i: input spectrum Q12*/ + const Word16 p2a_flags[], /* i: p2a anlysis information Q0*/ + const Word16 new_band_start[], /* i: new band start position Q0*/ + const Word16 new_band_end[], /* i: new band end position Q0*/ + const Word16 new_band_width[], /* i: new subband band width Q0*/ + const Word16 bands, /* i: total number of subbands Q0*/ + Word16 band_start[], /* i/o: band start position Q0*/ + Word16 band_end[], /* i/o: band end position Q0*/ + Word16 band_width[], /* i: sub band band width Q0*/ + Word16 *bit_budget /* i/o: bit budget Q0*/ ) { Word16 i, j, k; @@ -150,7 +152,7 @@ static void spt_shorten_domain_set_ivas_fx( j = 0; move16(); move16(); - FOR( k = sub( bands, SPT_SHORTEN_SBNUM ); k < bands; k++ ) + FOR( k = ( bands - SPT_SHORTEN_SBNUM ); k < bands; k++ ) { IF( EQ_16( p2a_flags[k], 1 ) ) { @@ -165,7 +167,8 @@ static void spt_shorten_domain_set_ivas_fx( { IF( LT_32( L_max_y2, L_abs( L_t_audio[i] ) ) ) { - L_max_y2 = L_abs( L_t_audio[i] ); + L_max_y2 = L_abs( L_t_audio[i] ); /* Q12 */ + move32(); max_y2_pos = i; move16(); } @@ -173,22 +176,23 @@ static void spt_shorten_domain_set_ivas_fx( test(); IF( GE_16( max_y2_pos, new_band_start[j] ) && LE_16( max_y2_pos, new_band_end[j] ) ) { - band_start[k] = new_band_start[j]; + band_start[k] = new_band_start[j]; /* Q0 */ move16(); - band_end[k] = new_band_end[j]; + band_end[k] = new_band_end[j]; /* Q0 */ move16(); - band_width[k] = new_band_width[j]; + band_width[k] = new_band_width[j]; /* Q0 */ move16(); spt_shorten_flag[j] = 1; move16(); } } push_indice( st_fx->hBstr, IND_HQ2_SPT_SHORTEN, spt_shorten_flag[j], 1 ); - *bit_budget = sub( *bit_budget, 1 ); + *bit_budget = sub( *bit_budget, 1 ); /* Q0 */ + move16(); } - kpos = add( kpos, 1 ); - j = add( j, 1 ); + kpos += 1; + j += 1; } return; @@ -270,6 +274,7 @@ void hq_lr_enc_fx( BSTR_ENC_HANDLE hBstr = st_fx->hBstr; #ifdef BASOP_NOGLOB_DECLARE_LOCAL Flag Overflow = 0; + move32(); #endif @@ -288,6 +293,7 @@ void hq_lr_enc_fx( enerH_fx = L_deposit_l( 0 ); tmp2 = 0; /* to avoid compilation warnings */ + move16(); L_bwe_br = L_add( st_fx->core_brate, 0 ); hqswb_clas_fx = HQ_NORMAL; @@ -303,13 +309,14 @@ void hq_lr_enc_fx( } ELSE { - hqswb_clas_fx = peak_avrg_ratio_fx( st_fx->total_brate, L_t_audio, NUMC_N, &hHQ_core->mode_count, &hHQ_core->mode_count1, SWB_BWE_LR_Qs ); + hqswb_clas_fx = peak_avrg_ratio_fx( st_fx->total_brate, L_t_audio, NUMC_N, &hHQ_core->mode_count, &hHQ_core->mode_count1, SWB_BWE_LR_Qs ); /* Q0 */ } /* write the classification information into the bitstream */ push_indice_fx( hBstr, IND_HQ2_SWB_CLAS, hqswb_clas_fx, 2 ); ( *num_bits_fx ) = sub( *num_bits_fx, 2 ); - if ( EQ_16( hqswb_clas_fx, HQ_NORMAL ) ) + move16(); + IF( EQ_16( hqswb_clas_fx, HQ_NORMAL ) ) { flag_spt_fx = 1; move16(); @@ -321,15 +328,16 @@ void hq_lr_enc_fx( push_indice_fx( st_fx->hBstr, IND_HQ2_SWB_CLAS, is_transient_fx, 1 ); /* subtract one bit for the transient flag */ - ( *num_bits_fx )--; + ( *num_bits_fx ) = sub( ( *num_bits_fx ), 1 ); + move16(); } hq2_core_configure_fx( inner_frame_fx, *num_bits_fx, is_transient_fx, &bands_fx, &length_fx, band_width, band_start, band_end, &L_qint, &eref_fx, &bit_alloc_weight_fx, &gqlevs_fx, &Ngq_fx, &p2a_bands_fx, &p2a_th_fx, &pd_thresh_fx, &ld_slope_fx, &ni_coef_fx, L_bwe_br ); - highlength_fx = band_end[sub( bands_fx, 1 )]; + highlength_fx = band_end[( bands_fx - 1 )]; /* Q0 */ move16(); - har_bands_fx = bands_fx; + har_bands_fx = bands_fx; /* Q0 */ move16(); test(); @@ -342,6 +350,7 @@ void hq_lr_enc_fx( IF( EQ_16( hqswb_clas_fx, HQ_NORMAL ) || EQ_16( hqswb_clas_fx, HQ_HARMONIC ) ) { ( *num_bits_fx ) = sub( *num_bits_fx, get_usebit_npswb_fx( hqswb_clas_fx ) ); + move16(); } } @@ -353,7 +362,7 @@ void hq_lr_enc_fx( { j = 0; move16(); - FOR( k = sub( bands_fx, SPT_SHORTEN_SBNUM ); k < bands_fx; k++ ) + FOR( k = ( bands_fx - SPT_SHORTEN_SBNUM ); k < bands_fx; k++ ) { hHQ_core->prev_SWB_peak_pos[j] = 0; move16(); @@ -368,16 +377,18 @@ void hq_lr_enc_fx( { /* If so, collapse transient frame (4 short transforms) to remove uncoded coefficients */ - k1_step_fx = shr( length_fx, 2 ); /* k1 = length/NUM_TIME_SWITCHING_BLOCKS */ - k2_step_fx = shr( inner_frame_fx, 2 ); /* k2 = inner_frame/NUM_TIME_SWITCHING_BLOCKS */ - k1_fx = k1_step_fx; - k2_fx = k2_step_fx; + k1_step_fx = shr( length_fx, 2 ); /* k1 = length/NUM_TIME_SWITCHING_BLOCKS Q0*/ + k2_step_fx = shr( inner_frame_fx, 2 ); /* k2 = inner_frame/NUM_TIME_SWITCHING_BLOCKS Q0*/ + k1_fx = k1_step_fx; /* Q0 */ + k2_fx = k2_step_fx; /* Q0 */ + move16(); + move16(); FOR( i = 1; i < NUM_TIME_SWITCHING_BLOCKS; i++ ) { /*k1 = i*length/NUM_TIME_SWITCHING_BLOCKS; */ /*k2 = i*inner_frame/NUM_TIME_SWITCHING_BLOCKS; */ - Copy32( &L_t_audio[k2_fx], &L_t_audio[k1_fx], k1_step_fx ); + Copy32( &L_t_audio[k2_fx], &L_t_audio[k1_fx], k1_step_fx ); /* Q12 */ k1_fx = add( k1_fx, k1_step_fx ); k2_fx = add( k2_fx, k2_step_fx ); @@ -386,13 +397,13 @@ void hq_lr_enc_fx( /* Spectral energy calculation/quantization */ ebits_fx = band_energy_quant_fx( hBstr, L_t_audio, band_start, band_end, L_band_energy, bands_fx, - L_qint, eref_fx, is_transient_fx ); + L_qint, eref_fx, is_transient_fx ); /* Q0 */ /* First pass bit budget for TCQ of spectral band information */ exp_norm = norm_s( gqlevs_fx ); /* gqbits_fx = (short int) log2_f ((float) gqlevs_fx); */ gqbits_fx = sub( 14, exp_norm ); - bit_budget_fx = sub( sub( *num_bits_fx, ebits_fx ), round_fx( L_shl( L_mult( Ngq_fx, gqbits_fx ), 15 ) ) ); /* (*num_bits) - (short) ceil (ebits) - Ngq * gqbits; */ + bit_budget_fx = sub( sub( *num_bits_fx, ebits_fx ), round_fx( L_shl( L_mult( Ngq_fx, gqbits_fx ), 15 ) ) ); /* (*num_bits) - (short) ceil (ebits) - Ngq * gqbits; Q0*/ pbits_fx = 0; @@ -409,7 +420,7 @@ void hq_lr_enc_fx( ELSE { /* High band tonality detector based on per band peak-to-average ratio */ - pbits_fx = p2a_threshold_quant_fx( hBstr, L_t_audio, band_start, band_end, band_width, bands_fx, p2a_bands_fx, p2a_th_fx, p2a_flags_fx ); + pbits_fx = p2a_threshold_quant_fx( hBstr, L_t_audio, band_start, band_end, band_width, bands_fx, p2a_bands_fx, p2a_th_fx, p2a_flags_fx ); /* Q0 */ bit_budget_fx = sub( bit_budget_fx, pbits_fx ); IF( EQ_16( hqswb_clas_fx, HQ_NORMAL ) ) @@ -421,7 +432,7 @@ void hq_lr_enc_fx( ELSE { /* High band tonality detector based on per band peak-to-average ratio */ - pbits_fx = p2a_threshold_quant_fx( hBstr, L_t_audio, band_start, band_end, band_width, bands_fx, p2a_bands_fx, p2a_th_fx, p2a_flags_fx ); + pbits_fx = p2a_threshold_quant_fx( hBstr, L_t_audio, band_start, band_end, band_width, bands_fx, p2a_bands_fx, p2a_th_fx, p2a_flags_fx ); /* Q0 */ bit_budget_fx = sub( bit_budget_fx, pbits_fx ); } @@ -434,6 +445,7 @@ void hq_lr_enc_fx( /* Estimate number of bits per band */ Q_band_energy = SWB_BWE_LR_Qbe; + move16(); FOR( i = 0; i < bands_fx; i++ ) { @@ -442,32 +454,28 @@ void hq_lr_enc_fx( frac1 = L_Extract_lc( L_tmp, &exp ); /* Extract exponent of L_tmp */ L_tmp = Pow2( 30, frac1 ); exp = sub( exp, 30 ); -#ifdef BASOP_NOGLOB Ep_fx[i] = L_shl_sat( L_tmp, s_max( sub( exp, 6 ), -31 ) ); /* Q -6 */ -#else - Ep_fx[i] = L_shl( L_tmp, s_max( sub( exp, 6 ), -31 ) ); /* Q -6 */ -#endif } FOR( i = 0; i < bands_fx; i++ ) { - L_tmp2 = Ep_fx[i]; - L_tmp = L_max( 1, L_tmp2 ); + L_tmp2 = Ep_fx[i]; /* Q -6 */ + L_tmp = L_max( 1, L_tmp2 ); /* Q -6 */ exp = norm_l( L_tmp ); - tmp = extract_h( L_shl( L_tmp, exp ) ); + tmp = extract_h( L_shl( L_tmp, exp ) ); /* Q -6 + exp - 16 */ - L_tmp3 = (Word32) band_width[i]; + L_tmp3 = L_deposit_l( band_width[i] ); /* Q0 */ exp2 = norm_l( L_tmp3 ); - tmp2 = extract_h( L_shl( L_tmp3, exp2 ) ); + tmp2 = extract_h( L_shl( L_tmp3, exp2 ) ); /* exp2 - 16 */ exp2 = sub( exp, exp2 ); /* Denormalize and substract */ tmp3 = sub( tmp2, tmp ); - if ( tmp3 > 0 ) + IF( tmp3 > 0 ) { tmp2 = shr( tmp2, 1 ); } - if ( tmp3 > 0 ) + IF( tmp3 > 0 ) { exp2 = add( exp2, 1 ); } @@ -475,6 +483,7 @@ void hq_lr_enc_fx( L_tmp = L_deposit_h( tmp ); L_tmp = Isqrt_lc( L_tmp, &exp2 ); /*Q(31-exp2) */ Ep_tmp_fx[i] = L_shr( L_tmp, sub( 15, exp2 ) ); /*Q13 */ + move32(); } test(); @@ -491,18 +500,19 @@ void hq_lr_enc_fx( move16(); bit_budget_fx = sub( bit_budget_fx, trans_bit ); gama_fx = 27852; /*Q15 0.85f;// */ - beta_fx = 17203; - move16(); /*Q14 1.05f; */ + beta_fx = 17203; /*Q14 1.05f; */ + move16(); + move16(); - set16_fx( &p2a_flags_tmp[sub( bands_fx, trans_bit )], 0, 2 ); + set16_fx( &p2a_flags_tmp[( bands_fx - trans_bit )], 0, 2 ); IF( EQ_32( st_fx->core_brate, ACELP_13k20 ) ) { - beta_fx = 13107; - move16(); /*14 1.25f; */ - gama_fx = 31130; - move16(); /*0.95f; */ - Copy( &p2a_flags_fx[sub( bands_fx, trans_bit )], &p2a_flags_tmp[sub( bands_fx, trans_bit )], trans_bit ); + beta_fx = 13107; /*14 1.25f; */ + move16(); + gama_fx = 31130; /*0.95f; */ + move16(); + Copy( &p2a_flags_fx[( bands_fx - trans_bit )], &p2a_flags_tmp[( bands_fx - trans_bit )], trans_bit ); /* Q0 */ } /* calculate the the low band/high band energy and the variance/avrage of the envelopes */ Ep_vari_fx = L_deposit_l( 0 ); @@ -513,21 +523,13 @@ void hq_lr_enc_fx( { IF( GE_16( i, lowband ) ) { -#ifdef BASOP_NOGLOB Ep_vari_fx = L_add_sat( Ep_vari_fx, L_abs( L_sub( Ep_tmp_fx[i], Ep_tmp_fx[sub( i, 1 )] ) ) ); /*Q15 */ Ep_avrg_fx = L_add_sat( Ep_avrg_fx, Ep_tmp_fx[i] ); /*Q15 */ -#else - Ep_vari_fx = L_add( Ep_vari_fx, L_abs( L_sub( Ep_tmp_fx[i], Ep_tmp_fx[sub( i, 1 )] ) ) ); /*Q15 */ - Ep_avrg_fx = L_add( Ep_avrg_fx, Ep_tmp_fx[i] ); /*Q15 */ -#endif + move32(); } ELSE { -#ifdef BASOP_NOGLOB Ep_avrgL_fx = L_add_sat( Ep_avrgL_fx, Ep_tmp_fx[i] ); /*Q15 */ -#else - Ep_avrgL_fx = L_add( Ep_avrgL_fx, Ep_tmp_fx[i] ); /*Q15 */ -#endif IF( GT_32( Ep_tmp_fx[i], Ep_peak_fx ) ) { Ep_peak_fx = L_add( Ep_tmp_fx[i], 0 ); /*Q15 */ @@ -573,16 +575,18 @@ void hq_lr_enc_fx( L_tmp2 = L_add( L_tmp, 13107 ); /*15 */ tmp2 = extract_l( L_min( L_max( L_tmp2, 16384 ), gama_fx ) ); /*15 = 15 */ L_band_energy_tmp[i] = Mult_32_16( L_band_energy_tmp[i], tmp2 ); /*Q(Q_band_energy+15-15 = Q_band_energy) */ + move32(); } } } ELSE { j = 0; - FOR( i = sub( bands_fx, trans_bit ); i < bands_fx; i++ ) + move16(); + FOR( i = ( bands_fx - trans_bit ); i < bands_fx; i++ ) { - alpha_fx = 16384; - move16(); /*Q14 */ + alpha_fx = 16384; /*Q14 */ + move16(); IF( EQ_16( p2a_flags_tmp[i], 1 ) ) { L_tmp = Mult_32_16( Ep_tmp_fx[i], sub( bands_fx, lowband ) ); /*Q(13+0-15 = -2) */ @@ -602,13 +606,9 @@ void hq_lr_enc_fx( exp = 0; move16(); } - L_tmp = Mult_32_16( Ep_vari_fx, 3277 ); /*13+15-15=13 */ -#ifdef BASOP_NOGLOB + L_tmp = Mult_32_16( Ep_vari_fx, 3277 ); /*13+15-15=13 */ L_tmp = L_shl_o( Mult_32_16( L_tmp, tmp ), sub( 12, exp ), &Overflow ); /*Q(13+exp-15 +12-exp +4 = 14) */ -#else - L_tmp = L_shl( Mult_32_16( L_tmp, tmp ), sub( 12, exp ) ); /*Q(13+exp-15 +12-exp +4 = 14) */ -#endif - tmp2 = extract_h( Ep_avrg_fx ); /*Q13-16=-3 */ + tmp2 = extract_h( Ep_avrg_fx ); /*Q13-16=-3 */ IF( tmp2 != 0 ) { exp = norm_s( tmp2 ); @@ -623,24 +623,16 @@ void hq_lr_enc_fx( exp = 0; move16(); } - L_tmp2 = Mult_32_16( Ep_vari_fx, 6554 ); /*13+15-15=13 */ -#ifdef BASOP_NOGLOB + L_tmp2 = Mult_32_16( Ep_vari_fx, 6554 ); /*13+15-15=13 */ L_tmp2 = L_shl_o( Mult_32_16( L_tmp2, tmp2 ), sub( 13, exp ), &Overflow ); /*Q(13+exp-15 +13-exp +3 = 14) */ -#else - L_tmp2 = L_shl( Mult_32_16( L_tmp2, tmp2 ), sub( 13, exp ) ); /*Q(13+exp-15 +13-exp +3 = 14) */ -#endif - L_tmp = L_min( L_tmp, L_tmp2 ); /*14 */ - tmp = extract_l( L_min( L_tmp, 13107 ) ); /*14 */ + L_tmp = L_min( L_tmp, L_tmp2 ); /*Q14 */ + tmp = extract_l( L_min( L_tmp, 13107 ) ); /*Q14 */ alpha_fx = add( 16384, tmp ); } IF( EQ_16( hHQ_core->last_bitalloc_max_band[j++], 1 ) ) { L_tmp = Mult_32_16( Ep_tmp_fx[i], sub( bands_fx, lowband ) ); /*Q(13+0-15 = -2) */ -#ifdef BASOP_NOGLOB - tmp = extract_h( L_shl_sat( L_tmp, 14 ) ); /*Q-2 */ -#else - tmp = extract_h( L_shl( L_tmp, 14 ) ); /*Q-2 */ -#endif + tmp = extract_h( L_shl_sat( L_tmp, 14 ) ); /*Q-4 */ IF( tmp != 0 ) { exp = norm_s( tmp ); @@ -655,14 +647,10 @@ void hq_lr_enc_fx( exp = 0; move16(); } -#ifdef BASOP_NOGLOB L_tmp = L_shl_o( Mult_32_16( Ep_avrg_fx, tmp ), sub( 14, exp ), &Overflow ); /*Q(13+exp-15 +14-exp+2 = 14) */ -#else - L_tmp = L_shl( Mult_32_16( Ep_avrg_fx, tmp ), sub( 14, exp ) ); /*Q(13+exp-15 +14-exp+2 = 14) */ -#endif - L_tmp = L_max( L_tmp, 16384 ); /*14 */ - tmp = extract_l( L_min( L_tmp, beta_fx ) ); /*14 */ - alpha_fx = shl( mult( alpha_fx, tmp ), 1 ); /*14+14-15 +1=14 */ + L_tmp = L_max( L_tmp, 16384 ); /*Q14 */ + tmp = extract_l( L_min( L_tmp, beta_fx ) ); /*Q14 */ + alpha_fx = shl( mult( alpha_fx, tmp ), 1 ); /*14+14-15 +1=Q14 */ } ELSE { @@ -682,17 +670,14 @@ void hq_lr_enc_fx( exp = 0; move16(); } -#ifdef BASOP_NOGLOB L_tmp = L_shl_o( Mult_32_16( Ep_tmp_fx[i], tmp2 ), sub( 19, exp ), &Overflow ); /*Q(13+exp-15 +19-exp +3 = 20) */ -#else - L_tmp = L_shl( Mult_32_16( Ep_tmp_fx[i], tmp2 ), sub( 19, exp ) ); /*Q(13+exp-15 +19-exp +3 = 20) */ -#endif - L_tmp = Mult_32_16( L_tmp, shl( sub( bands_fx, lowband ), 9 ) ); /*20 +9 -15 =14 */ - L_tmp = L_max( L_tmp, 13926 ); /*14 */ - tmp2 = extract_l( L_min( L_tmp, 16384 ) ); /*14 */ - alpha_fx = shl( mult( alpha_fx, tmp2 ), 1 ); /*14+14-15+1 =14 */ + L_tmp = Mult_32_16( L_tmp, shl( sub( bands_fx, lowband ), 9 ) ); /*20 +9 -15 =Q14 */ + L_tmp = L_max( L_tmp, 13926 ); /*Q14 */ + tmp2 = extract_l( L_min( L_tmp, 16384 ) ); /*Q14 */ + alpha_fx = shl( mult( alpha_fx, tmp2 ), 1 ); /*14+14-15+1 =Q14 */ } L_band_energy_tmp[i] = L_shl( Mult_32_16( L_band_energy_tmp[i], alpha_fx ), 1 ); /*Q(Q_band_energy+14-15 +1= Q_band_energy) */ + move32(); } } lowband = 3; @@ -704,19 +689,11 @@ void hq_lr_enc_fx( { IF( GE_16( i, lowband ) ) { -#ifdef BASOP_NOGLOB Ep_avrg_fx = L_add_sat( Ep_avrg_fx, Ep_tmp_fx[i] ); /*Q15 */ -#else - Ep_avrg_fx = L_add( Ep_avrg_fx, Ep_tmp_fx[i] ); /*Q15 */ -#endif } ELSE { -#ifdef BASOP_NOGLOB Ep_avrgL_fx = L_add_sat( Ep_avrgL_fx, L_shr( Ep_tmp_fx[i], 1 ) ); /*Q12 */ -#else - Ep_avrgL_fx = L_add( Ep_avrgL_fx, L_shr( Ep_tmp_fx[i], 1 ) ); /*Q12 */ -#endif IF( GT_32( Ep_tmp_fx[i], Ep_peak_fx ) ) { Ep_peak_fx = L_add( Ep_tmp_fx[i], 0 ); /*Q13 */ @@ -753,7 +730,7 @@ void hq_lr_enc_fx( L_tmp = Mult_32_16( L_tmp, lowband ); /*Q(exp+2+0-15 = exp-13) */ L_tmp = Mult_32_16( L_tmp, 18842 ); /*Q(exp-13+16-16 = exp-13) */ L_tmp = L_shl( L_tmp, sub( 27, exp ) ); /*Q14 0.5 */ - tmp2 = extract_l( L_min( L_tmp, 19661 ) ); /*14 */ + tmp2 = extract_l( L_min( L_tmp, 19661 ) ); /*Q14 */ L_tmp = Mult_32_16( L_band_energy_tmp[i], tmp2 ); /*Q(Q_band_energy+14-15 = Q_band_energy-1) */ L_band_energy_tmp[i] = L_shl( L_tmp, 1 ); /*Q_band_energy */ } @@ -769,14 +746,11 @@ void hq_lr_enc_fx( } ELSE IF( is_transient_fx == 0 && EQ_16( inner_frame_fx, L_FRAME16k ) ) { - bit_budget_fx = sub( bit_budget_fx, 2 ); /* bits in high bands to indicate the last 2 subbands is allocated bits or not */ + bit_budget_fx = sub( bit_budget_fx, 2 ); /* bits in high bands to indicate the last 2 subbands is allocated bits or not Q0*/ FOR( i = 0; i < bands_fx; i++ ) { -#ifdef BASOP_NOGLOB - Ep_tmp_fx[i] = L_shl_o( Ep_tmp_fx[i], 2, &Overflow ); -#else /* BASOP_NOGLOB */ - Ep_tmp_fx[i] = L_shl( Ep_tmp_fx[i], 2 ); -#endif /* BASOP_NOGLOB */ + Ep_tmp_fx[i] = L_shl_o( Ep_tmp_fx[i], 2, &Overflow ); /* Q15 */ + move32(); } IF( EQ_32( st_fx->core_brate, ACELP_13k20 ) ) { @@ -784,8 +758,8 @@ void hq_lr_enc_fx( move16(); highband = 15; move16(); - bw_low = sub( band_start[highband], band_start[lowband] ); - bw_high = sub( add( band_end[sub( bands_fx, 1 )], 1 ), band_start[highband] ); + bw_low = sub( band_start[highband], band_start[lowband] ); /* Q0 */ + bw_high = sub( add( band_end[( bands_fx - 1 )], 1 ), band_start[highband] ); /* Q0 */ } ELSE { @@ -793,8 +767,8 @@ void hq_lr_enc_fx( move16(); highband = 16; move16(); - bw_low = sub( band_start[highband], band_start[lowband] ); - bw_high = sub( add( band_end[sub( bands_fx, 1 )], 1 ), band_start[highband] ); + bw_low = sub( band_start[highband], band_start[lowband] ); /* Q0 */ + bw_high = sub( add( band_end[( bands_fx - 1 )], 1 ), band_start[highband] ); /* Q0 */ } /* calculate the the low band/high band energy and the variance/avrage of the envelopes */ enerL_fx = L_deposit_l( 0 ); @@ -806,33 +780,17 @@ void hq_lr_enc_fx( test(); IF( GE_16( i, lowband ) && add( sub( i, bands_fx ), p2a_bands_fx ) < 0 ) { -#ifdef BASOP_NOGLOB - Ep_vari_fx = L_add_sat( Ep_vari_fx, L_abs( L_sub_sat( Ep_tmp_fx[i], Ep_tmp_fx[sub( i, 1 )] ) ) ); /*Q15 */ -#else - Ep_vari_fx = L_add( Ep_vari_fx, L_abs( L_sub( Ep_tmp_fx[i], Ep_tmp_fx[sub( i, 1 )] ) ) ); /*Q15 */ -#endif -#ifdef BASOP_NOGLOB - Ep_avrg_fx = L_add_o( Ep_avrg_fx, Ep_tmp_fx[i], &Overflow ); /*Q15 */ -#else /* BASOP_NOGLOB */ - Ep_avrg_fx = L_add( Ep_avrg_fx, Ep_tmp_fx[i] ); /*Q15 */ -#endif /* BASOP_NOGLOB */ + Ep_vari_fx = L_add_sat( Ep_vari_fx, L_abs( L_sub_sat( Ep_tmp_fx[i], Ep_tmp_fx[( i - 1 )] ) ) ); /*Q15 */ + Ep_avrg_fx = L_add_o( Ep_avrg_fx, Ep_tmp_fx[i], &Overflow ); /*Q15 */ } IF( GE_16( i, highband ) ) { -#ifdef BASOP_NOGLOB enerH_fx = L_add_sat( enerH_fx, L_shl_sat( Ep_fx[i], 2 ) ); /*Q0 */ -#else - enerH_fx = L_add( enerH_fx, L_shl( Ep_fx[i], 2 ) ); /*Q0 */ -#endif } ELSE IF( GE_16( i, lowband ) ) { -#ifdef BASOP_NOGLOB enerL_fx = L_add_sat( enerL_fx, L_shl_sat( Ep_fx[i], 2 ) ); /*Q0 */ -#else - enerL_fx = L_add( enerL_fx, L_shl( Ep_fx[i], 2 ) ); /*Q0 */ -#endif } } @@ -845,7 +803,7 @@ void hq_lr_enc_fx( L_tmp = Mult_32_16( L_shl( enerH_fx, i ), shl( bw_low, j ) ); /* i + j -15 */ L_tmp2 = Mult_32_16( L_shl( enerL_fx, i ), shl( bw_high, j ) ); /*i + j -15 */ L_tmp2 = L_sub( L_tmp, L_tmp2 ); - FOR( i = sub( bands_fx, p2a_bands_fx ); i < bands_fx; i++ ) + FOR( i = ( bands_fx - p2a_bands_fx ); i < bands_fx; i++ ) { test(); IF( EQ_16( p2a_flags_fx[i], 1 ) || L_tmp2 > 0 ) @@ -853,11 +811,7 @@ void hq_lr_enc_fx( tmp = sub( bands_fx, p2a_bands_fx ); tmp = sub( tmp, lowband ); /*Q0 */ -#ifdef BASOP_NOGLOB tmp1 = extract_h( L_shl_sat( Ep_avrg_fx, 1 ) ); /*Q0 */ -#else - tmp1 = extract_h( L_shl( Ep_avrg_fx, 1 ) ); /*Q0 */ -#endif IF( tmp1 != 0 ) { exp = norm_s( tmp1 ); @@ -885,8 +839,8 @@ void hq_lr_enc_fx( } ELSE { - alpha_fx = 16384; - move16(); /*Q14 */ + alpha_fx = 16384; /*Q14 */ + move16(); } IF( add( sub( i, bands_fx ), p2a_bands_fx ) > 0 ) @@ -895,12 +849,8 @@ void hq_lr_enc_fx( IF( EQ_16( hHQ_core->last_bitalloc_max_band[sub( i, add( tmp, 1 ) )], 1 ) ) { tmp = sub( tmp, lowband ); - L_tmp = Mult_32_16( Ep_tmp_fx[i], tmp ); /*Q(15+0-15 = 0) */ -#ifdef BASOP_NOGLOB + L_tmp = Mult_32_16( Ep_tmp_fx[i], tmp ); /*Q(15+0-15 = 0) */ tmp = extract_h( L_shl_o( L_tmp, 16, &Overflow ) ); /*Q0 */ -#else /* BASOP_NOGLOB */ - tmp = extract_h( L_shl( L_tmp, 16 ) ); /*Q0 */ -#endif /* BASOP_NOGLOB */ IF( tmp != 0 ) { exp = norm_s( tmp ); @@ -925,11 +875,7 @@ void hq_lr_enc_fx( { tmp = sub( tmp, lowband ); -#ifdef BASOP_NOGLOB tmp1 = extract_h( L_shl_sat( Ep_avrg_fx, 1 ) ); /*Q0 */ -#else - tmp1 = extract_h( L_shl( Ep_avrg_fx, 1 ) ); /*Q0 */ -#endif IF( tmp1 != 0 ) { exp = norm_s( tmp1 ); @@ -954,6 +900,7 @@ void hq_lr_enc_fx( } L_tmp = Mult_32_16( L_band_energy_tmp[i], alpha_fx ); /*Q(Q_band_energy+14-15=Q_band_energy-1) */ L_band_energy_tmp[i] = L_shl( L_tmp, 1 ); /*Q Q_band_energy */ + move32(); } lowband = 6; move16(); @@ -964,19 +911,11 @@ void hq_lr_enc_fx( { IF( GE_16( i, lowband ) ) { -#ifdef BASOP_NOGLOB Ep_avrg_fx = L_add_o( Ep_avrg_fx, Ep_tmp_fx[i], &Overflow ); /*Q15 */ -#else /* BASOP_NOGLOB */ - Ep_avrg_fx = L_add( Ep_avrg_fx, Ep_tmp_fx[i] ); /*Q15 */ -#endif /* BASOP_NOGLOB */ } ELSE { -#ifdef BASOP_NOGLOB Ep_avrgL_fx = L_add_o( Ep_avrgL_fx, Ep_tmp_fx[i], &Overflow ); /*Q15 */ -#else /* BASOP_NOGLOB */ - Ep_avrgL_fx = L_add( Ep_avrgL_fx, Ep_tmp_fx[i] ); /*Q15 */ -#endif IF( GT_32( Ep_tmp_fx[i], Ep_peak_fx ) ) { Ep_peak_fx = L_add( Ep_tmp_fx[i], 0 ); /*Q15 */ @@ -1000,11 +939,7 @@ void hq_lr_enc_fx( move16(); FOR( i = 0; i < lowband; i++ ) { -#ifdef BASOP_NOGLOB tmp = extract_h( L_shl_sat( Ep_avrgL_fx, 1 ) ); /*Q0 */ -#else - tmp = extract_h( L_shl( Ep_avrgL_fx, 1 ) ); /*Q0 */ -#endif IF( tmp != 0 ) { exp = norm_s( tmp ); @@ -1025,6 +960,7 @@ void hq_lr_enc_fx( tmp = extract_l( L_min( L_tmp, 19661 ) ); /*//Q14 */ L_tmp = Mult_32_16( L_band_energy_tmp[i], tmp ); /*Q(Q_band_energy+14-15 = Q_band_energy-1) */ L_band_energy_tmp[i] = L_shl( L_tmp, 1 ); /*Q_band_energy */ + move32(); } } @@ -1054,20 +990,25 @@ void hq_lr_enc_fx( tcq_core_LR_enc_fx( hBstr, /*st_fx->idchan, */ inp_vector_fx, /*t_audio, */ L_t_audio, /*y2, */ L_y2, bit_budget_fx, bands_fx, band_start, band_end, band_width, /*Rk*/ L_Rk, npulses_fx, k_sort_fx, p2a_flags_fx, p2a_bands_fx, hHQ_core->last_bitalloc_max_band, inner_frame_fx, adjustFlag, is_transient_fx ); + test(); + test(); IF( ( EQ_16( inner_frame_fx, L_FRAME8k ) && LE_32( st_fx->core_brate, ACELP_13k20 ) ) || EQ_16( inner_frame_fx, L_FRAME16k ) ) { j = 0; + move16(); FOR( i = 2; i > 0; i-- ) { IF( npulses_fx[bands_fx - i] > 0 ) { - hHQ_core->last_bitalloc_max_band[j] = 1; + hHQ_core->last_bitalloc_max_band[j] = 1; /* Q0 */ + move16(); } ELSE { - hHQ_core->last_bitalloc_max_band[j] = 0; + hHQ_core->last_bitalloc_max_band[j] = 0; /* Q0 */ + move16(); } - j++; + j += 1; } } @@ -1088,7 +1029,7 @@ void hq_lr_enc_fx( /* Inject noise into components having relatively low pulse energy per band */ ni_seed_fx = add( add( add( npulses_fx[0], npulses_fx[1] ), npulses_fx[2] ), npulses_fx[3] ); - Copy32( L_y2, L_y2_ni, band_end[bands_fx - 1] + 1 ); + Copy32( L_y2, L_y2_ni, band_end[bands_fx - 1] + 1 ); /* Q12 */ hq2_noise_inject_fx( L_y2_ni, band_start, band_end, band_width, Ep_fx, L_Rk, npulses_fx, ni_seed_fx, bands_fx, 0, bw_low, bw_high, enerL_fx, enerH_fx, hHQ_core->last_ni_gain_fx, hHQ_core->last_env_fx, &hHQ_core->last_max_pos_pulse, p2a_flags_fx, p2a_bands_fx, hqswb_clas_fx, st_fx->bwidth, L_bwe_br ); @@ -1121,11 +1062,11 @@ void hq_lr_enc_fx( } } } - Copy32( L_y2_ni, L_y2, lowlength_fx ); + Copy32( L_y2_ni, L_y2, lowlength_fx ); /* Q12 */ } ELSE { - Copy32( L_y2_ni, L_y2, add( band_end[bands_fx - 1], 1 ) ); /* HQ_TRANSIENT */ + Copy32( L_y2_ni, L_y2, add( band_end[bands_fx - 1], 1 ) ); /* HQ_TRANSIENT Q12*/ } } @@ -1164,10 +1105,10 @@ void hq_lr_enc_fx( void hq_lr_enc_ivas_fx( Encoder_State *st, /* i/o: encoder state structure */ - Word32 L_t_audio[], /* i/o: transform-domain coefs. */ - const Word16 inner_frame, /* i : inner frame length */ - Word16 *num_bits, /* i/o: number of available bits */ - const Word16 is_transient /* i : transient flag */ + Word32 L_t_audio[], /* i/o: transform-domain coefs. Q12*/ + const Word16 inner_frame, /* i : inner frame length Q0*/ + Word16 *num_bits, /* i/o: number of available bits Q0*/ + const Word16 is_transient /* i : transient flag Q0*/ ) { Word16 i; @@ -1238,9 +1179,8 @@ void hq_lr_enc_ivas_fx( Word32 L_band_energy_tmp[BANDS_MAX]; UWord16 lo; Word16 Q_band_energy; -#ifdef BASOP_NOGLOB Flag Overflow; -#endif /* BASOP_NOGLOB */ + move32(); BSTR_ENC_HANDLE hBstr = st->hBstr; HQ_ENC_HANDLE hHQ_core = st->hHQ_core; @@ -1271,19 +1211,19 @@ void hq_lr_enc_ivas_fx( { IF( EQ_16( is_transient, 1 ) ) { - hqswb_clas = HQ_TRANSIENT; + hqswb_clas = HQ_TRANSIENT; /* Q0 */ move16(); } ELSE { - hqswb_clas = peak_avrg_ratio_fx( st->total_brate, L_t_audio, NUMC_N, &hHQ_core->mode_count, &hHQ_core->mode_count1, SWB_BWE_LR_Qs ); + hqswb_clas = peak_avrg_ratio_fx( st->total_brate, L_t_audio, NUMC_N, &hHQ_core->mode_count, &hHQ_core->mode_count1, SWB_BWE_LR_Qs ); /* Q0 */ } /* write the classification information into the bitstream */ push_indice( hBstr, IND_HQ2_SWB_CLAS, hqswb_clas, 2 ); ( *num_bits ) = sub( *num_bits, 2 ); move16(); - if ( EQ_16( hqswb_clas, HQ_NORMAL ) ) + IF( EQ_16( hqswb_clas, HQ_NORMAL ) ) { flag_spt = 1; move16(); @@ -1305,9 +1245,9 @@ void hq_lr_enc_ivas_fx( &L_qint, &eref_fx, &bit_alloc_weight_fx, &gqlevs, &Ngq, &p2a_bands, &p2a_th_fx, &pd_thresh_fx, &ld_slope_fx, &ni_coef_fx, bwe_br ); - highlength = band_end[sub( bands, 1 )]; + highlength = band_end[( bands - 1 )]; /* Q0 */ move16(); - har_bands = bands; + har_bands = bands; /* Q0 */ move16(); @@ -1333,11 +1273,11 @@ void hq_lr_enc_ivas_fx( { j = 0; move16(); - FOR( k = sub( bands, SPT_SHORTEN_SBNUM ); k < bands; k++ ) + FOR( k = ( bands - SPT_SHORTEN_SBNUM ); k < bands; k++ ) { hHQ_core->prev_SWB_peak_pos[j] = 0; move16(); - j = add( j, 1 ); + j += 1; } } } @@ -1347,10 +1287,10 @@ void hq_lr_enc_ivas_fx( { /* If so, collapse transient frame (4 short transforms) to remove uncoded coefficients */ - k1_step_fx = shr( length, 2 ); /* k1 = length/NUM_TIME_SWITCHING_BLOCKS */ - k2_step_fx = shr( inner_frame, 2 ); /* k2 = inner_frame/NUM_TIME_SWITCHING_BLOCKS */ - k1_fx = k1_step_fx; - k2_fx = k2_step_fx; + k1_step_fx = shr( length, 2 ); /* k1 = length/NUM_TIME_SWITCHING_BLOCKS Q0*/ + k2_step_fx = shr( inner_frame, 2 ); /* k2 = inner_frame/NUM_TIME_SWITCHING_BLOCKS Q0*/ + k1_fx = k1_step_fx; /* Q0 */ + k2_fx = k2_step_fx; /* Q0 */ move16(); move16(); FOR( i = 1; i < NUM_TIME_SWITCHING_BLOCKS; i++ ) @@ -1358,7 +1298,7 @@ void hq_lr_enc_ivas_fx( /*k1 = i*length/NUM_TIME_SWITCHING_BLOCKS; */ /*k2 = i*inner_frame/NUM_TIME_SWITCHING_BLOCKS; */ - Copy32( &L_t_audio[k2_fx], &L_t_audio[k1_fx], k1_step_fx ); + Copy32( &L_t_audio[k2_fx], &L_t_audio[k1_fx], k1_step_fx ); /* Q12 */ k1_fx = add( k1_fx, k1_step_fx ); k2_fx = add( k2_fx, k2_step_fx ); @@ -1368,13 +1308,13 @@ void hq_lr_enc_ivas_fx( /* Spectral energy calculation/quantization */ ebits_fx = band_energy_quant_ivas_fx( hBstr, L_t_audio, band_start, band_end, L_band_energy, bands, - L_qint, eref_fx, is_transient ); + L_qint, eref_fx, is_transient ); /* Q0 */ /* First pass bit budget for TCQ of spectral band information */ exp_norm = norm_s( gqlevs ); /* gqbits_fx = (short int) log2_f ((float) gqlevs_fx); */ gqbits = sub( 14, exp_norm ); - bit_budget = sub( sub( *num_bits, ebits_fx ), round_fx( L_shl( L_mult( Ngq, gqbits ), 15 ) ) ); /* (*num_bits) - (short) ceil (ebits) - Ngq * gqbits; */ + bit_budget = sub( sub( *num_bits, ebits_fx ), round_fx( L_shl( L_mult( Ngq, gqbits ), 15 ) ) ); /* (*num_bits) - (short) ceil (ebits) - Ngq * gqbits; Q0*/ pbits = 0; @@ -1391,7 +1331,7 @@ void hq_lr_enc_ivas_fx( ELSE { /* High band tonality detector based on per band peak-to-average ratio */ - pbits = p2a_threshold_quant_ivas_fx( hBstr, L_t_audio, band_start, band_end, band_width, bands, p2a_bands, p2a_th_fx, p2a_flags ); + pbits = p2a_threshold_quant_ivas_fx( hBstr, L_t_audio, band_start, band_end, band_width, bands, p2a_bands, p2a_th_fx, p2a_flags ); /* Q0 */ bit_budget = sub( bit_budget, pbits ); IF( EQ_16( hqswb_clas, HQ_NORMAL ) ) @@ -1403,7 +1343,7 @@ void hq_lr_enc_ivas_fx( ELSE { /* High band tonality detector based on per band peak-to-average ratio */ - pbits = p2a_threshold_quant_ivas_fx( hBstr, L_t_audio, band_start, band_end, band_width, bands, p2a_bands, p2a_th_fx, p2a_flags ); + pbits = p2a_threshold_quant_ivas_fx( hBstr, L_t_audio, band_start, band_end, band_width, bands, p2a_bands, p2a_th_fx, p2a_flags ); /* Q0 */ bit_budget = sub( bit_budget, pbits ); } @@ -1427,18 +1367,19 @@ void hq_lr_enc_ivas_fx( L_tmp = Pow2( 30, frac1 ); exp = sub( exp, 30 ); Ep_fx[i] = L_shl( L_tmp, sub( exp, 6 ) ); /* Q -6 */ + move32(); } FOR( i = 0; i < bands; i++ ) { - L_tmp2 = Ep_fx[i]; + L_tmp2 = Ep_fx[i]; /* Q -6 */ L_tmp = L_max( 1, L_tmp2 ); exp = norm_l( L_tmp ); - tmp = extract_h( L_shl( L_tmp, exp ) ); + tmp = extract_h( L_shl( L_tmp, exp ) ); /* Q -6 + exp - 16 */ - L_tmp3 = (Word32) band_width[i]; + L_tmp3 = L_deposit_l( band_width[i] ); /* Q0 */ exp2 = norm_l( L_tmp3 ); - tmp2 = extract_h( L_shl( L_tmp3, exp2 ) ); + tmp2 = extract_h( L_shl( L_tmp3, exp2 ) ); /* exp2 - 16 */ exp2 = sub( exp, exp2 ); /* Denormalize and substract */ @@ -1451,11 +1392,12 @@ void hq_lr_enc_ivas_fx( { exp2 = add( exp2, 1 ); } - tmp = div_s( tmp2, tmp ); - L_tmp = L_deposit_h( tmp ); - L_tmp = Isqrt_lc1( L_tmp, &exp2 ); - move32(); /*Q(31-exp2) */ - Ep_tmp_fx[i] = L_shr( L_tmp, sub( 15, exp2 ) ); /*Q13 */ + tmp = div_s( tmp2, tmp ); /* Q15 */ + L_tmp = L_deposit_h( tmp ); /* Q31 */ + L_tmp = Isqrt_lc1( L_tmp, &exp2 ); /*Q(31-exp2) */ + move32(); + Ep_tmp_fx[i] = L_shr( L_tmp, sub( 15, exp2 ) ); /*Q16 */ + move32(); } #undef WMC_TOOL_SKIP @@ -1473,19 +1415,19 @@ void hq_lr_enc_ivas_fx( trans_bit = 2; move16(); bit_budget = sub( bit_budget, trans_bit ); - gama_fx = 27852; /*Q15 0.85f; */ - beta_fx = 17203; + gama_fx = 27852; /*Q15 0.85f */ + beta_fx = 17203; /*Q14 1.05f */ + move16(); move16(); - move16(); /*Q14 1.05f; */ set_s( &p2a_flags_tmp[bands - trans_bit], 0, 2 ); IF( EQ_32( st->core_brate, ACELP_13k20 ) ) { - beta_fx = 13107; - move16(); /*14 1.25f; */ - gama_fx = 31130; - move16(); /*0.95f; */ - mvs2s( &p2a_flags[sub( bands, trans_bit )], &p2a_flags_tmp[sub( bands, trans_bit )], trans_bit ); + beta_fx = 13107; /* Q14 1.25f */ + move16(); + gama_fx = 31130; /* 0.95f Q15 */ + move16(); + mvs2s( &p2a_flags[( bands - trans_bit )], &p2a_flags_tmp[( bands - trans_bit )], trans_bit ); } /* calculate the the low band/high band energy and the variance/avrage of the envelopes */ @@ -1501,31 +1443,31 @@ void hq_lr_enc_ivas_fx( { IF( sub( i, lowband ) >= 0 ) { - Ep_vari_fx = L_add( Ep_vari_fx, L_abs( L_sub( Ep_tmp_fx[i], Ep_tmp_fx[sub( i, 1 )] ) ) ); /*Q15 */ - Ep_avrg_fx = L_add( Ep_avrg_fx, Ep_tmp_fx[i] ); /*Q15 */ + Ep_vari_fx = L_add( Ep_vari_fx, L_abs( L_sub( Ep_tmp_fx[i], Ep_tmp_fx[( i - 1 )] ) ) ); /*Q15 */ + Ep_avrg_fx = L_add( Ep_avrg_fx, Ep_tmp_fx[i] ); /*Q15 */ } ELSE { -#ifdef BASOP_NOGLOB Ep_avrgL_fx = L_add_o( Ep_avrgL_fx, Ep_tmp_fx[i], &Overflow ); /*Q15 */ -#else - Ep_avrgL_fx = L_add( Ep_avrgL_fx, Ep_tmp_fx[i] ); /*Q15 */ -#endif IF( L_sub( Ep_tmp_fx[i], Ep_peak_fx ) > 0 ) { - Ep_peak_fx = Ep_tmp_fx[i]; - move32(); /*Q15 */ + Ep_peak_fx = Ep_tmp_fx[i]; /*Q15 */ + move32(); } } } /* modify the last p2a_bands subbands band_energies */ k = bands; + move16(); mvl2l( L_band_energy, L_band_energy_tmp, k ); /*Q_band_energy */ Mpy_32_16_ss( Ep_peak_fx, 24576, &L_tmp, &lo ); Mpy_32_16_ss( Ep_peak_fx, shl( sub( bands, lowband ), 9 ), &L_tmp2, &lo ); Mpy_32_16_ss( Ep_avrg_fx, 1126, &L_tmp3, &lo ); - IF( ( ( L_sub( L_tmp, L_shr( Ep_avrgL_fx, 1 ) ) < 0 && st->core_brate == ACELP_13k20 ) || st->core_brate < ACELP_13k20 ) && + test(); + test(); + test(); + IF( ( ( L_sub( L_tmp, L_shr( Ep_avrgL_fx, 1 ) ) < 0 && EQ_32( st->core_brate, ACELP_13k20 ) ) || LT_32( st->core_brate, ACELP_13k20 ) ) && L_sub( L_tmp2, L_tmp3 ) < 0 && L_sub( L_tmp2, L_shr( Ep_avrg_fx, 7 ) ) > 0 ) { FOR( i = lowband; i < bands; i++ ) @@ -1562,10 +1504,10 @@ void hq_lr_enc_ivas_fx( { j = 0; move16(); - FOR( i = sub( bands, trans_bit ); i < bands; i++ ) + FOR( i = ( bands - trans_bit ); i < bands; i++ ) { - alpha_fx = 16384; - move16(); /*Q14 */ + alpha_fx = 16384; /*Q14 */ + move16(); IF( sub( p2a_flags_tmp[i], 1 ) == 0 ) { Mpy_32_16_ss( Ep_tmp_fx[i], sub( bands, lowband ), &L_tmp, &lo ); @@ -1609,7 +1551,7 @@ void hq_lr_enc_ivas_fx( L_tmp2 = L_shl( L_tmp2, sub( 13, exp ) ); /*Q(13+exp-15 +13-exp +3 = 14) */ L_tmp = L_min( L_tmp, L_tmp2 ); /*14 */ tmp = extract_l( L_min( L_tmp, 13107 ) ); /*14 */ - alpha_fx = add( 16384, tmp ); + alpha_fx = add( 16384, tmp ); /* Q14 */ } IF( sub( hHQ_core->last_bitalloc_max_band[j++], 1 ) == 0 ) { @@ -1630,17 +1572,10 @@ void hq_lr_enc_ivas_fx( move16(); } Mpy_32_16_ss( Ep_avrg_fx, tmp, &L_tmp, &lo ); -#ifndef BASOP_NOGLOB - L_tmp = L_shl( L_tmp, sub( 14, exp ) ); /*Q(13+exp-15 +14-exp+2 = 14) */ - L_tmp = L_max( L_tmp, 16384 ); /*14 */ - tmp = extract_l( L_min( L_tmp, beta_fx ) ); /*14 */ - alpha_fx = shl( mult( alpha_fx, tmp ), 1 ); /*14+14-15 +1=14 */ -#else /* BASOP_NOGLOB */ - L_tmp = L_shl_o( L_tmp, sub( 14, exp ), &Overflow ); /*Q(13+exp-15 +14-exp+2 = 14) */ - L_tmp = L_max( L_tmp, 16384 ); /*14 */ - tmp = extract_l( L_min( L_tmp, beta_fx ) ); /*14 */ - alpha_fx = shl( mult( alpha_fx, tmp ), 1 ); /*14+14-15 +1=14 */ -#endif /* BASOP_NOGLOB */ + L_tmp = L_shl_o( L_tmp, sub( 14, exp ), &Overflow ); /*Q(13+exp-15 +14-exp+2 = 14) */ + L_tmp = L_max( L_tmp, 16384 ); /*14 */ + tmp = extract_l( L_min( L_tmp, beta_fx ) ); /*14 */ + alpha_fx = shl( mult( alpha_fx, tmp ), 1 ); /*14+14-15 +1=14 */ } ELSE { @@ -1669,6 +1604,7 @@ void hq_lr_enc_ivas_fx( } Mpy_32_16_ss( L_band_energy_tmp[i], alpha_fx, &L_tmp, &lo ); L_band_energy_tmp[i] = L_shl( L_tmp, 1 ); /*Q(Q_band_energy+14-15 +1= Q_band_energy) */ + move32(); } } lowband = 3; @@ -1683,24 +1619,23 @@ void hq_lr_enc_ivas_fx( { IF( sub( i, lowband ) >= 0 ) { -#ifdef BASOP_NOGLOB Ep_avrg_fx = L_add_o( Ep_avrg_fx, Ep_tmp_fx[i], &Overflow ); /*Q15 */ -#else - Ep_avrg_fx = L_add( Ep_avrg_fx, Ep_tmp_fx[i] ); /*Q15 */ -#endif } ELSE { Ep_avrgL_fx = L_add( Ep_avrgL_fx, L_shr( Ep_tmp_fx[i], 1 ) ); /*Q12 */ IF( L_sub( Ep_tmp_fx[i], Ep_peak_fx ) > 0 ) { - Ep_peak_fx = Ep_tmp_fx[i]; - move32(); /*Q13 */ + Ep_peak_fx = Ep_tmp_fx[i]; /*Q13 */ + move32(); } } } Mpy_32_16_ss( Ep_peak_fx, 28262, &L_tmp, &lo ); Mpy_32_16_ss( Ep_avrgL_fx, 24576, &L_tmp2, &lo ); + + test(); + test(); IF( L_sub( L_shr( Ep_avrg_fx, 2 ), L_tmp2 ) > 0 && L_sub( L_shr( Ep_avrg_fx, 4 ), L_tmp2 ) < 0 && L_sub( L_tmp, Ep_avrgL_fx ) > 0 ) { adjustFlag = 1; @@ -1726,15 +1661,11 @@ void hq_lr_enc_ivas_fx( Mpy_32_16_ss( Ep_peak_fx, tmp, &L_tmp, &lo ); Mpy_32_16_ss( L_tmp, lowband, &L_tmp, &lo ); Mpy_32_16_ss( L_tmp, 18842, &L_tmp, &lo ); -#ifndef BASOP_NOGLOB - L_tmp = L_shl( L_tmp, sub( 27, exp ) ); /*Q14 0.5 */ - tmp2 = extract_l( L_min( L_tmp, 19661 ) ); /*14 */ -#else /* BASOP_NOGLOB */ - L_tmp = L_shl_o( L_tmp, sub( 27, exp ), &Overflow ); /*Q14 0.5 */ - tmp2 = extract_l( L_min( L_tmp, 19661 ) ); /*14 */ -#endif /* BASOP_NOGLOB */ + L_tmp = L_shl_o( L_tmp, sub( 27, exp ), &Overflow ); /*Q14 0.5 */ + tmp2 = extract_l( L_min( L_tmp, 19661 ) ); /*14 */ Mpy_32_16_ss( L_band_energy_tmp[i], tmp2, &L_tmp, &lo ); L_band_energy_tmp[i] = L_shl( L_tmp, 1 ); /*Q_band_energy */ + move32(); } } #undef WMC_TOOL_SKIP @@ -1754,12 +1685,8 @@ void hq_lr_enc_ivas_fx( bit_budget = sub( bit_budget, 2 ); /* bits in high bands to indicate the last 2 subbands is allocated bits or not */ FOR( i = 0; i < bands; i++ ) { -#ifndef BASOP_NOGLOB - Ep_tmp_fx[i] = L_shl( Ep_tmp_fx[i], 2 ); -#else /* BASOP_NOGLOB */ - Ep_tmp_fx[i] = L_shl_o( Ep_tmp_fx[i], 2, &Overflow ); + Ep_tmp_fx[i] = L_shl_o( Ep_tmp_fx[i], 2, &Overflow ); /* Q15 */ move32(); -#endif /* BASOP_NOGLOB */ } IF( EQ_32( st->core_brate, ACELP_13k20 ) ) { @@ -1767,8 +1694,8 @@ void hq_lr_enc_ivas_fx( move16(); highband = 15; move16(); - bw_low = sub( band_start[highband], band_start[lowband] ); - bw_high = sub( add( band_end[sub( bands, 1 )], 1 ), band_start[highband] ); + bw_low = sub( band_start[highband], band_start[lowband] ); /* Q0 */ + bw_high = sub( add( band_end[( bands - 1 )], 1 ), band_start[highband] ); /* Q0 */ } ELSE { @@ -1776,8 +1703,8 @@ void hq_lr_enc_ivas_fx( move16(); highband = 16; move16(); - bw_low = sub( band_start[highband], band_start[lowband] ); - bw_high = sub( add( band_end[sub( bands, 1 )], 1 ), band_start[highband] ); + bw_low = sub( band_start[highband], band_start[lowband] ); /* Q0 */ + bw_high = sub( add( band_end[( bands - 1 )], 1 ), band_start[highband] ); /* Q0 */ } /* calculate the the low band/high band energy and the variance/avrage of the envelopes */ enerL_fx = 0; @@ -1790,14 +1717,11 @@ void hq_lr_enc_ivas_fx( move32(); FOR( i = 0; i < bands; i++ ) { + test(); IF( sub( i, lowband ) >= 0 && add( sub( i, bands ), p2a_bands ) < 0 ) { Ep_vari_fx = L_add( Ep_vari_fx, L_abs( L_sub( Ep_tmp_fx[i], Ep_tmp_fx[sub( i, 1 )] ) ) ); /*Q15 */ -#ifndef BASOP_NOGLOB - Ep_avrg_fx = L_add( Ep_avrg_fx, Ep_tmp_fx[i] ); /*Q15 */ -#else /* BASOP_NOGLOB */ - Ep_avrg_fx = L_add_o( Ep_avrg_fx, Ep_tmp_fx[i], &Overflow ); /*Q15 */ -#endif /* BASOP_NOGLOB */ + Ep_avrg_fx = L_add_o( Ep_avrg_fx, Ep_tmp_fx[i], &Overflow ); /*Q15 */ } IF( sub( i, highband ) >= 0 ) @@ -1811,6 +1735,7 @@ void hq_lr_enc_ivas_fx( } /* modify the last p2a_bands subbands band_energies */ k = bands; + move16(); mvl2l( L_band_energy, L_band_energy_tmp, k ); /*Q_band_energy */ L_tmp = L_max( enerH_fx, enerL_fx ); @@ -1821,7 +1746,7 @@ void hq_lr_enc_ivas_fx( Mpy_32_16_ss( L_shl( enerL_fx, i ), shl( bw_high, j ), &L_tmp2, &lo ); L_tmp2 = L_sub( L_tmp, L_tmp2 ); - FOR( i = sub( bands, p2a_bands ); i < bands; i++ ) + FOR( i = ( bands - p2a_bands ); i < bands; i++ ) { test(); IF( sub( p2a_flags[i], 1 ) == 0 || L_tmp2 > 0 ) @@ -1829,11 +1754,7 @@ void hq_lr_enc_ivas_fx( tmp = sub( bands, p2a_bands ); tmp = sub( tmp, lowband ); /*Q0 */ -#ifndef BASOP_NOGLOB - tmp1 = extract_h( L_shl( Ep_avrg_fx, 1 ) ); /*Q0 */ -#else - tmp1 = extract_h( L_shl_o( Ep_avrg_fx, 1, &Overflow ) ); /*Q0 */ -#endif + tmp1 = extract_h( L_shl_o( Ep_avrg_fx, 1, &Overflow ) ); /*Q0 */ IF( tmp1 != 0 ) { exp = norm_s( tmp1 ); @@ -1861,22 +1782,18 @@ void hq_lr_enc_ivas_fx( } ELSE { - alpha_fx = 16384; - move16(); /*Q14 */ + alpha_fx = 16384; /* Q14 */ + move16(); } IF( add( sub( i, bands ), p2a_bands ) > 0 ) { tmp = sub( bands, p2a_bands ); - IF( sub( hHQ_core->last_bitalloc_max_band[sub( i, add( tmp, 1 ) )], 1 ) == 0 ) + IF( sub( hHQ_core->last_bitalloc_max_band[( i - ( tmp + 1 ) )], 1 ) == 0 ) { tmp = sub( tmp, lowband ); Mpy_32_16_ss( Ep_tmp_fx[i], tmp, &L_tmp, &lo ); -#ifndef BASOP_NOGLOB - tmp = extract_h( L_shl( L_tmp, 16 ) ); /*Q0 */ -#else /* BASOP_NOGLOB */ - tmp = extract_h( L_shl_o( L_tmp, 16, &Overflow ) ); /*Q0 */ -#endif /* BASOP_NOGLOB */ + tmp = extract_h( L_shl_o( L_tmp, 16, &Overflow ) ); /*Q0 */ IF( tmp != 0 ) { exp = norm_s( tmp ); @@ -1901,11 +1818,7 @@ void hq_lr_enc_ivas_fx( { tmp = sub( tmp, lowband ); -#ifndef BASOP_NOGLOB - tmp1 = extract_h( L_shl( Ep_avrg_fx, 1 ) ); /*Q0 */ -#else - tmp1 = extract_h( L_shl_o( Ep_avrg_fx, 1, &Overflow ) ); /*Q0 */ -#endif + tmp1 = extract_h( L_shl_o( Ep_avrg_fx, 1, &Overflow ) ); /*Q0 */ IF( tmp1 != 0 ) { exp = norm_s( tmp1 ); @@ -1930,6 +1843,7 @@ void hq_lr_enc_ivas_fx( } Mpy_32_16_ss( L_band_energy_tmp[i], alpha_fx, &L_tmp, &lo ); L_band_energy_tmp[i] = L_shl( L_tmp, 1 ); /*Q Q_band_energy */ + move32(); } lowband = 6; move16(); @@ -1943,23 +1857,15 @@ void hq_lr_enc_ivas_fx( { IF( sub( i, lowband ) >= 0 ) { -#ifndef BASOP_NOGLOB - Ep_avrg_fx = L_add( Ep_avrg_fx, Ep_tmp_fx[i] ); /*Q15 */ -#else /* BASOP_NOGLOB */ - Ep_avrg_fx = L_add_o( Ep_avrg_fx, Ep_tmp_fx[i], &Overflow ); /*Q15 */ -#endif /* BASOP_NOGLOB */ + Ep_avrg_fx = L_add_o( Ep_avrg_fx, Ep_tmp_fx[i], &Overflow ); /*Q15 */ } ELSE { -#ifndef BASOP_NOGLOB - Ep_avrgL_fx = L_add( Ep_avrgL_fx, Ep_tmp_fx[i] ); /*Q15 */ -#else /* BASOP_NOGLOB */ Ep_avrgL_fx = L_add_o( Ep_avrgL_fx, Ep_tmp_fx[i], &Overflow ); /*Q15 */ -#endif /* BASOP_NOGLOB */ IF( L_sub( Ep_tmp_fx[i], Ep_peak_fx ) > 0 ) { - Ep_peak_fx = Ep_tmp_fx[i]; - move32(); /*Q15 */ + Ep_peak_fx = Ep_tmp_fx[i]; /* Q15 */ + move32(); } } } @@ -1980,11 +1886,7 @@ void hq_lr_enc_ivas_fx( move16(); FOR( i = 0; i < lowband; i++ ) { -#ifndef BASOP_NOGLOB - tmp = extract_h( L_shl( Ep_avrgL_fx, 1 ) ); /*Q0 */ -#else - tmp = extract_h( L_shl_o( Ep_avrgL_fx, 1, &Overflow ) ); /*Q0 */ -#endif + tmp = extract_h( L_shl_o( Ep_avrgL_fx, 1, &Overflow ) ); /*Q0 */ IF( tmp != 0 ) { exp = norm_s( tmp ); @@ -2005,6 +1907,7 @@ void hq_lr_enc_ivas_fx( tmp = extract_l( L_min( L_tmp, 19661 ) ); /*Q14 */ Mpy_32_16_ss( L_band_energy_tmp[i], tmp, &L_tmp, &lo ); L_band_energy_tmp[i] = L_shl( L_tmp, 1 ); /*Q_band_energy */ + move32(); } } #undef WMC_TOOL_SKIP @@ -2065,9 +1968,9 @@ void hq_lr_enc_ivas_fx( } /* Inject noise into components having relatively low pulse energy per band */ - ni_seed = add( add( add( npulses[0], npulses[1] ), npulses[2] ), npulses[3] ); + ni_seed = add( add( add( npulses[0], npulses[1] ), npulses[2] ), npulses[3] ); /* Q0 */ - Copy32( L_y2, L_y2_ni, band_end[bands - 1] + 1 ); + Copy32( L_y2, L_y2_ni, band_end[bands - 1] + 1 ); /* Q12 */ test(); test(); IF( EQ_16( st->bwidth, SWB ) && ( EQ_32( bwe_br, HQ_16k40 ) || EQ_32( bwe_br, HQ_13k20 ) ) ) @@ -2096,16 +1999,16 @@ void hq_lr_enc_ivas_fx( } } } - Copy32( L_y2_ni, L_y2, lowlength ); + Copy32( L_y2_ni, L_y2, lowlength ); /* Q12 */ } ELSE { - Copy32( L_y2_ni, L_y2, band_end[bands - 1] + 1 ); /* HQ_TRANSIENT */ + Copy32( L_y2_ni, L_y2, band_end[bands - 1] + 1 ); /* HQ_TRANSIENT Q12*/ } } ELSE { - Copy32( L_y2_ni, L_y2, band_end[bands - 1] + 1 ); /* NB, WB */ + Copy32( L_y2_ni, L_y2, band_end[bands - 1] + 1 ); /* NB, WB Q12*/ } updat_prev_frm_fx( L_y2, L_t_audio, bwe_br, length, inner_frame, bands, st->bwidth, is_transient, hqswb_clas, &hHQ_core->prev_hqswb_clas, hHQ_core->prev_SWB_peak_pos, prev_SWB_peak_pos_tmp, &hHQ_core->prev_frm_hfe2, &hHQ_core->prev_stab_hfe2, bws_cnt ); @@ -2152,18 +2055,18 @@ void hq_lr_enc_ivas_fx( static Word16 small_symbol_enc_tran_fx( /* o : bits */ BSTR_ENC_HANDLE hBstr, /* i : handle to the bitstream */ - const Word16 *qbidx, /* i : input of dequantized differential energy */ - const Word16 BANDS, /* i : number of bands */ - Word16 *hLCmode, /* i/o: LC mode info */ - const Word16 flag_pack, /* i : indicator of packing or estimating bits */ - const Word16 is_transient ) + const Word16 *qbidx, /* i : input of dequantized differential energy Q0*/ + const Word16 BANDS, /* i : number of bands Q0*/ + Word16 *hLCmode, /* i/o: LC mode info Q0*/ + const Word16 flag_pack, /* i : indicator of packing or estimating bits Q0*/ + const Word16 is_transient /* Q0 */ ) { Word16 i, bits; Word16 difidx[BANDS_MAX]; FOR( i = 0; i < BANDS; i++ ) { - difidx[i] = add( qbidx[i], LRMDCT_BE_OFFSET ); + difidx[i] = add( qbidx[i], LRMDCT_BE_OFFSET ); /* Q0 */ move16(); } @@ -2181,8 +2084,8 @@ static Word16 small_symbol_enc_tran_fx( /* o : bits IF( flag_pack == 0 ) { /* estimating # of bits */ - bits = encode_envelope_indices_fx( hBstr, BANDS, -1, difidx, hLCmode, flag_pack, LOW_RATE_HQ_CORE_TRAN, is_transient ); - bits = add( bits, BITS_DE_FCOMP ); /* xx bits for diff. energies + BITS_DE_FCOMP bits for first energies */ + bits = encode_envelope_indices_fx( hBstr, BANDS, -1, difidx, hLCmode, flag_pack, LOW_RATE_HQ_CORE_TRAN, is_transient ); /* Q0 */ + bits = add( bits, BITS_DE_FCOMP ); /* xx bits for diff. energies + BITS_DE_FCOMP bits for first energies */ } ELSE { @@ -2191,24 +2094,24 @@ static Word16 small_symbol_enc_tran_fx( /* o : bits encode_envelope_indices_fx( hBstr, BANDS, -1, difidx, hLCmode, flag_pack, LOW_RATE_HQ_CORE_TRAN, is_transient ); } - return add( bits, BITS_DE_HMODE ); /* xx bits for diff. energies + 1 bit for LC coding mode */ + return add( bits, BITS_DE_HMODE ); /* xx bits for diff. energies + 1 bit for LC coding mode Q0*/ } static Word16 small_symbol_enc_tran_ivas_fx( /* o : bits */ BSTR_ENC_HANDLE hBstr, /* i : handle to the bitstream */ - const Word16 *qbidx, /* i : input of dequantized differential energy */ - const Word16 BANDS, /* i : number of bands */ - Word16 *hLCmode, /* i/o: LC mode info */ - const Word16 flag_pack, /* i : indicator of packing or estimating bits */ - const Word16 is_transient ) + const Word16 *qbidx, /* i : input of dequantized differential energy Q0*/ + const Word16 BANDS, /* i : number of bands Q0*/ + Word16 *hLCmode, /* i/o: LC mode info Q0*/ + const Word16 flag_pack, /* i : indicator of packing or estimating bits Q0*/ + const Word16 is_transient /* Q0 */ ) { Word16 i, bits; Word16 difidx[BANDS_MAX]; FOR( i = 0; i < BANDS; i++ ) { - difidx[i] = add( qbidx[i], LRMDCT_BE_OFFSET ); + difidx[i] = add( qbidx[i], LRMDCT_BE_OFFSET ); /* Q0 */ move16(); } @@ -2226,8 +2129,8 @@ static Word16 small_symbol_enc_tran_ivas_fx( /* o : bit IF( flag_pack == 0 ) { /* estimating # of bits */ - bits = encode_envelope_indices_ivas_fx( hBstr, BANDS, -1, difidx, hLCmode, flag_pack, LOW_RATE_HQ_CORE_TRAN, is_transient ); - bits = add( bits, BITS_DE_FCOMP ); /* xx bits for diff. energies + BITS_DE_FCOMP bits for first energies */ + bits = encode_envelope_indices_ivas_fx( hBstr, BANDS, -1, difidx, hLCmode, flag_pack, LOW_RATE_HQ_CORE_TRAN, is_transient ); /* Q0 */ + bits = add( bits, BITS_DE_FCOMP ); /* xx bits for diff. energies + BITS_DE_FCOMP bits for first energies */ } ELSE { @@ -2236,7 +2139,7 @@ static Word16 small_symbol_enc_tran_ivas_fx( /* o : bit encode_envelope_indices_ivas_fx( hBstr, BANDS, -1, difidx, hLCmode, flag_pack, LOW_RATE_HQ_CORE_TRAN, is_transient ); } - return add( bits, BITS_DE_HMODE ); /* xx bits for diff. energies + 1 bit for LC coding mode */ + return add( bits, BITS_DE_HMODE ); /* xx bits for diff. energies + 1 bit for LC coding mode Q0*/ } @@ -2250,23 +2153,23 @@ static Word16 small_symbol_enc_tran_ivas_fx( /* o : bit static Word16 small_symbol_enc_fx( /* o : bits */ BSTR_ENC_HANDLE hBstr, /* i : handle to the bitstream */ - const Word16 *qbidx, /* i : input of dequantized differential energy */ - const Word16 BANDS, /* i : number of bands */ - Word16 *hLCmode, /* i/o: LC mode info */ - const Word16 flag_pack /* i : indicator of packing or estimating bits */ + const Word16 *qbidx, /* i : input of dequantized differential energy Q0*/ + const Word16 BANDS, /* i : number of bands Q0*/ + Word16 *hLCmode, /* i/o: LC mode info Q0*/ + const Word16 flag_pack /* i : indicator of packing or estimating bits Q0*/ , - const Word16 is_transient ) + const Word16 is_transient /* Q0 */ ) { Word16 i, bits; Word16 difidx[BANDS_MAX], LSB[BANDS_MAX]; /* Preparing lossless coding input */ - difidx[0] = add( qbidx[0], DE_OFFSET0 ); + difidx[0] = add( qbidx[0], DE_OFFSET0 ); /* Q0 */ move16(); FOR( i = 1; i < BANDS; ++i ) { - difidx[i] = add( qbidx[i], DE_OFFSET1 ); + difidx[i] = add( qbidx[i], DE_OFFSET1 ); /* Q0 */ move16(); } @@ -2283,9 +2186,9 @@ static Word16 small_symbol_enc_fx( /* o : bits /* splitting MSB and LSB */ FOR( i = 0; i < BANDS; ++i ) { - LSB[i] = s_and( difidx[i], 1 ); + LSB[i] = s_and( difidx[i], 1 ); /* Q0 */ move16(); - difidx[i] = shr( difidx[i], 1 ); + difidx[i] = shr( difidx[i], 1 ); /* Q0 */ move16(); } @@ -2294,11 +2197,11 @@ static Word16 small_symbol_enc_fx( /* o : bits { /* estimating # of bits */ /* Encoding MSB bits */ - bits = encode_envelope_indices_fx( hBstr, BANDS, -1, difidx, hLCmode, flag_pack, LOW_RATE_HQ_CORE, is_transient ); - bits = add( bits, BITS_DE_FCOMP ); /* xx bits for diff. energies + BITS_DE_FCOMP bits for first energies */ + bits = encode_envelope_indices_fx( hBstr, BANDS, -1, difidx, hLCmode, flag_pack, LOW_RATE_HQ_CORE, is_transient ); /* Q0 */ + bits = add( bits, BITS_DE_FCOMP ); /* xx bits for diff. energies + BITS_DE_FCOMP bits for first energies */ /* Encoding LSB bit packing */ - bits = add( bits, BANDS ); + bits = add( bits, BANDS ); /* Q0 */ } ELSE { @@ -2314,27 +2217,27 @@ static Word16 small_symbol_enc_fx( /* o : bits } } - return add( bits, BITS_DE_HMODE ); /* xx bits for diff. energies + 1 bit for LC coding mode */ + return add( bits, BITS_DE_HMODE ); /* xx bits for diff. energies + 1 bit for LC coding mode Q0*/ } static Word16 small_symbol_enc_ivas_fx( BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ - const Word16 *qbidx, /* i : input of dequantized differential energy */ - const Word16 BANDS, /* i : number of bands */ - Word16 *hLCmode, /* i/o: LC mode info */ - const Word16 flag_pack, /* i : indicator of packing or estimating bits */ - const Word16 is_transient ) + const Word16 *qbidx, /* i : input of dequantized differential energy Q0*/ + const Word16 BANDS, /* i : number of bands Q0*/ + Word16 *hLCmode, /* i/o: LC mode info Q0*/ + const Word16 flag_pack, /* i : indicator of packing or estimating bits Q0*/ + const Word16 is_transient /* Q0 */ ) { Word16 i, bits; Word16 difidx[BANDS_MAX], LSB[BANDS_MAX]; /* Preparing lossless coding input */ - difidx[0] = add( qbidx[0], DE_OFFSET0 ); + difidx[0] = add( qbidx[0], DE_OFFSET0 ); /* Q0 */ move16(); FOR( i = 1; i < BANDS; ++i ) { - difidx[i] = add( qbidx[i], DE_OFFSET1 ); + difidx[i] = add( qbidx[i], DE_OFFSET1 ); /* Q0 */ move16(); } @@ -2351,9 +2254,9 @@ static Word16 small_symbol_enc_ivas_fx( /* splitting MSB and LSB */ FOR( i = 0; i < BANDS; ++i ) { - LSB[i] = s_and( difidx[i], 1 ); + LSB[i] = s_and( difidx[i], 1 ); /* Q0 */ move16(); - difidx[i] = shr( difidx[i], 1 ); + difidx[i] = shr( difidx[i], 1 ); /* Q0 */ move16(); } @@ -2362,11 +2265,11 @@ static Word16 small_symbol_enc_ivas_fx( { /* estimating # of bits */ /* Encoding MSB bits */ - bits = encode_envelope_indices_ivas_fx( hBstr, BANDS, -1, difidx, hLCmode, flag_pack, LOW_RATE_HQ_CORE, is_transient ); - bits = add( bits, BITS_DE_FCOMP ); /* xx bits for diff. energies + BITS_DE_FCOMP bits for first energies */ + bits = encode_envelope_indices_ivas_fx( hBstr, BANDS, -1, difidx, hLCmode, flag_pack, LOW_RATE_HQ_CORE, is_transient ); /* Q0 */ + bits = add( bits, BITS_DE_FCOMP ); /* xx bits for diff. energies + BITS_DE_FCOMP bits for first energies Q0*/ /* Encoding LSB bit packing */ - bits = add( bits, BANDS ); + bits = add( bits, BANDS ); /* Q0 */ } ELSE { @@ -2382,16 +2285,16 @@ static Word16 small_symbol_enc_ivas_fx( } } - return add( bits, BITS_DE_HMODE ); /* xx bits for diff. energies + 1 bit for LC coding mode */ + return add( bits, BITS_DE_HMODE ); /* xx bits for diff. energies + 1 bit for LC coding mode Q0*/ } -static Word16 large_symbol_enc_fx( /* o : bits */ +static Word16 large_symbol_enc_fx( /* o : bits Q0*/ BSTR_ENC_HANDLE hBstr, /* i : handle to the bitstream */ - Word16 *qbidx, /* i : input of dequantized differential energy */ - const Word16 BANDS, /* i : number of bands */ - Word16 *hLCmode0, /* i/o: LC mode info */ - const Word16 flag_pack /* i : indicator of packing or estimating bits */ + Word16 *qbidx, /* i : input of dequantized differential energy Q0*/ + const Word16 BANDS, /* i : number of bands Q0*/ + Word16 *hLCmode0, /* i/o: LC mode info Q0*/ + const Word16 flag_pack /* i : indicator of packing or estimating bits Q0*/ ) { Word16 i, bits, tmp; @@ -2404,7 +2307,7 @@ static Word16 large_symbol_enc_fx( /* o : bits Word16 lsbdepth1; Word16 cnt_outlyer, pos_outlyer, cnt_outlyer0; - min_q = 513; + min_q = 513; /* Q0 */ move16(); max_q = -1; move16(); @@ -2453,15 +2356,15 @@ static Word16 large_symbol_enc_fx( /* o : bits test(); IF( GT_16( qbidx[i], 3 ) || LT_16( qbidx[i], -4 ) ) { - cnt_outlyer = add( cnt_outlyer, 1 ); + cnt_outlyer = add( cnt_outlyer, 1 ); /* Q0 */ pos_outlyer = i; move16(); } test(); - if ( GT_16( qbidx[i], sub( ABS_ENG_OFFSET, 1 ) ) || LT_16( qbidx[i], -ABS_ENG_OFFSET ) ) + IF( GT_16( qbidx[i], ( ABS_ENG_OFFSET - 1 ) ) || LT_16( qbidx[i], -ABS_ENG_OFFSET ) ) { - cnt_outlyer = add( cnt_outlyer, 1 ); + cnt_outlyer = add( cnt_outlyer, 1 ); /* Q0 */ } } @@ -2469,37 +2372,39 @@ static Word16 large_symbol_enc_fx( /* o : bits test(); IF( cnt_outlyer0 == 0 && LE_16( cnt_outlyer, 1 ) ) { - bitsmode0 = add( add( BITS_DE_8SMODE, BITS_DE_8SMODE_N0 ), BITS_DE_8SMODE_N1 ); + bitsmode0 = ( BITS_DE_8SMODE + BITS_DE_8SMODE_N0 ) + BITS_DE_8SMODE_N1; /* Q0 */ + move16(); IF( EQ_16( cnt_outlyer, 1 ) ) { /* 01 */ - bitsmode0 = add( bitsmode0, add( BITS_DE_8SPOS, BITS_ABS_ENG ) ); + bitsmode0 = add( bitsmode0, ( BITS_DE_8SPOS + BITS_ABS_ENG ) ); /* Q0 */ } FOR( i = 0; i < pos_outlyer; ++i ) { - tdifidx0[i] = qbidx[i]; + tdifidx0[i] = qbidx[i]; /* Q0 */ move16(); - bitsmode0 = add( bitsmode0, hessize[tdifidx0[i] + 4] ); + bitsmode0 = add( bitsmode0, hessize[tdifidx0[i] + 4] ); /* Q0 */ } FOR( i = add( pos_outlyer, 1 ); i < BANDS; ++i ) { - tdifidx0[i] = qbidx[i]; + tdifidx0[i] = qbidx[i]; /* Q0 */ move16(); - bitsmode0 = add( bitsmode0, hessize[tdifidx0[i] + 4] ); + bitsmode0 = add( bitsmode0, hessize[tdifidx0[i] + 4] ); /* Q0 */ } } ELSE IF( EQ_16( cnt_outlyer0, 1 ) && LE_16( cnt_outlyer, 1 ) ) { - bitsmode0 = add( add( BITS_DE_8SMODE, BITS_DE_8SMODE_N0 ), BITS_DE_8SMODE_N1 ); - tdifidx0[0] = qbidx[0]; + bitsmode0 = ( BITS_DE_8SMODE + BITS_DE_8SMODE_N0 ) + BITS_DE_8SMODE_N1; /* Q0 */ + move16(); + tdifidx0[0] = qbidx[0]; /* Q0 */ move16(); bitsmode0 = add( bitsmode0, BITS_ABS_ENG ); IF( EQ_16( cnt_outlyer, 1 ) ) { /* 11 */ - bitsmode0 = add( bitsmode0, add( BITS_DE_8SPOS, BITS_ABS_ENG ) ); + bitsmode0 = add( bitsmode0, ( BITS_DE_8SPOS + BITS_ABS_ENG ) ); /* Q0 */ } ELSE { @@ -2509,16 +2414,16 @@ static Word16 large_symbol_enc_fx( /* o : bits FOR( i = 1; i < pos_outlyer; ++i ) { - tdifidx0[i] = qbidx[i]; + tdifidx0[i] = qbidx[i]; /* Q0 */ move16(); - bitsmode0 = add( bitsmode0, hessize[tdifidx0[i] + 4] ); + bitsmode0 = add( bitsmode0, hessize[tdifidx0[i] + 4] ); /* Q0 */ } FOR( i = add( pos_outlyer, 1 ); i < BANDS; ++i ) { - tdifidx0[i] = qbidx[i]; + tdifidx0[i] = qbidx[i]; /* Q0 */ move16(); - bitsmode0 = add( bitsmode0, hessize[tdifidx0[i] + 4] ); + bitsmode0 = add( bitsmode0, hessize[tdifidx0[i] + 4] ); /* Q0 */ } } ELSE @@ -2555,9 +2460,9 @@ static Word16 large_symbol_enc_fx( /* o : bits basic_shift = i; move16(); - min_bits = 1000; + min_bits = 1000; /* Q0 */ move16(); - min_bits_pos = basic_shift; + min_bits_pos = basic_shift; /* Q0 */ move16(); tmp = add( basic_shift, 3 ); FOR( offset0 = basic_shift; offset0 < tmp; offset0++ ) @@ -2567,17 +2472,17 @@ static Word16 large_symbol_enc_fx( /* o : bits min_q = MAXIMUM_ENERGY_LOWBRATE; move16(); - bitsmode1 = add( BITS_DE_8SMODE, BITS_MAX_DEPTH ); + bitsmode1 = add( BITS_DE_8SMODE, BITS_MAX_DEPTH ); /* Q0 */ FOR( i = 0; i < BANDS; ++i ) { - bitsmode1 = add( bitsmode1, add( hessize[add( shr( qbidx[i], offset0 ), 4 )], offset0 ) ); + bitsmode1 = add( bitsmode1, add( hessize[( ( qbidx[i] >> offset0 ) + 4 )], offset0 ) ); } IF( GT_16( min_bits, bitsmode1 ) ) { - min_bits_pos = offset0; + min_bits_pos = offset0; /* Q0 */ move16(); - min_bits = bitsmode1; + min_bits = bitsmode1; /* Q0 */ move16(); } } @@ -2591,6 +2496,8 @@ static Word16 large_symbol_enc_fx( /* o : bits { LSB1[i] = s_and( qbidx[i], sub( shl( 1, lsbdepth1 ), 1 ) ); tdifidx1[i] = shr( qbidx[i], lsbdepth1 ); + move16(); + move16(); } } @@ -2601,14 +2508,14 @@ static Word16 large_symbol_enc_fx( /* o : bits /* Encoding MSB bits */ IF( LT_16( bitsmode0, bitsmode1 ) ) { - bits = bitsmode0; + bits = bitsmode0; /* Q0 */ move16(); *hLCmode0 = 0; move16(); } ELSE { - bits = bitsmode1; + bits = bitsmode1; /* Q0 */ move16(); *hLCmode0 = 1; move16(); @@ -2630,7 +2537,7 @@ static Word16 large_symbol_enc_fx( /* o : bits { /* 01 */ push_indice_fx( hBstr, IND_HQ2_DENG_8SMODE_N1, 1, BITS_DE_8SMODE_N1 ); - bits = add( bits, BITS_DE_8SMODE_N1 ); + bits = add( bits, BITS_DE_8SMODE_N1 ); /* Q0 */ push_indice_fx( hBstr, IND_HQ2_DENG_8SPOS, pos_outlyer, BITS_DE_8SPOS ); bits = add( bits, BITS_DE_8SPOS ); push_indice_fx( hBstr, IND_HQ2_DIFF_ENERGY, qbidx[pos_outlyer] + ABS_ENG_OFFSET, BITS_ABS_ENG ); @@ -2640,19 +2547,19 @@ static Word16 large_symbol_enc_fx( /* o : bits { /* 00 */ push_indice_fx( hBstr, IND_HQ2_DENG_8SMODE_N1, 0, BITS_DE_8SMODE_N1 ); - bits = add( bits, BITS_DE_8SMODE_N1 ); + bits = add( bits, BITS_DE_8SMODE_N1 ); /* Q0 */ } FOR( i = 0; i < pos_outlyer; ++i ) { push_indice_fx( hBstr, IND_HQ2_DIFF_ENERGY, hescode[tdifidx0[i] + 4], hessize[tdifidx0[i] + 4] ); - bitsmode0 = add( bitsmode0, hessize[tdifidx0[i] + 4] ); + bitsmode0 = add( bitsmode0, hessize[tdifidx0[i] + 4] ); /* Q0 */ } - FOR( i = add( pos_outlyer, 1 ); i < BANDS; ++i ) + FOR( i = ( pos_outlyer + 1 ); i < BANDS; ++i ) { push_indice_fx( hBstr, IND_HQ2_DIFF_ENERGY, hescode[tdifidx0[i] + 4], hessize[tdifidx0[i] + 4] ); - bitsmode0 = add( bitsmode0, hessize[tdifidx0[i] + 4] ); + bitsmode0 = add( bitsmode0, hessize[tdifidx0[i] + 4] ); /* Q0 */ } } ELSE IF( EQ_16( cnt_outlyer0, 1 ) ) @@ -2662,7 +2569,7 @@ static Word16 large_symbol_enc_fx( /* o : bits IF( EQ_16( cnt_outlyer, 1 ) ) { push_indice_fx( hBstr, IND_HQ2_DENG_8SMODE_N1, 1, BITS_DE_8SMODE_N1 ); - bits = add( bits, BITS_DE_8SMODE_N1 ); + bits = add( bits, BITS_DE_8SMODE_N1 ); /* Q0 */ push_indice_fx( hBstr, IND_HQ2_DENG_8SPOS, pos_outlyer, BITS_DE_8SPOS ); bits = add( bits, BITS_DE_8SPOS ); push_indice_fx( hBstr, IND_HQ2_DIFF_ENERGY, qbidx[0] + ABS_ENG_OFFSET, BITS_ABS_ENG ); @@ -2673,34 +2580,34 @@ static Word16 large_symbol_enc_fx( /* o : bits ELSE { push_indice_fx( hBstr, IND_HQ2_DENG_8SMODE_N1, 0, BITS_DE_8SMODE_N1 ); - bits = add( bits, BITS_DE_8SMODE_N1 ); + bits = add( bits, BITS_DE_8SMODE_N1 ); /* Q0 */ push_indice_fx( hBstr, IND_HQ2_DIFF_ENERGY, qbidx[0] + ABS_ENG_OFFSET, BITS_ABS_ENG ); - bits = add( bits, BITS_ABS_ENG ); + bits = add( bits, BITS_ABS_ENG ); /* Q0 */ } FOR( i = 1; i < pos_outlyer; ++i ) { push_indice_fx( hBstr, IND_HQ2_DIFF_ENERGY, hescode[tdifidx0[i] + 4], hessize[tdifidx0[i] + 4] ); - bits = add( bits, hessize[tdifidx0[i] + 4] ); + bits = add( bits, hessize[tdifidx0[i] + 4] ); /* Q0 */ } FOR( i = pos_outlyer + 1; i < BANDS; ++i ) { push_indice_fx( hBstr, IND_HQ2_DIFF_ENERGY, hescode[tdifidx0[i] + 4], hessize[tdifidx0[i] + 4] ); - bits = add( bits, hessize[tdifidx0[i] + 4] ); + bits = add( bits, hessize[tdifidx0[i] + 4] ); /* Q0 */ } } } ELSE { - bits = add( BITS_DE_8SMODE, BITS_MAX_DEPTH ); + bits = add( BITS_DE_8SMODE, BITS_MAX_DEPTH ); /* Q0 */ push_indice_fx( hBstr, IND_HQ2_DENG_8SMODE, 1, BITS_DE_8SMODE ); push_indice_fx( hBstr, IND_HQ2_DENG_8SDEPTH, lsbdepth1, BITS_MAX_DEPTH ); FOR( i = 0; i < BANDS; ++i ) { push_indice_fx( hBstr, IND_HQ2_DIFF_ENERGY, hescode[tdifidx1[i] + 4], hessize[tdifidx1[i] + 4] ); - bits = add( bits, hessize[tdifidx1[i] + 4] ); + bits = add( bits, hessize[tdifidx1[i] + 4] ); /* Q0 */ } IF( lsbdepth1 > 0 ) @@ -2710,21 +2617,21 @@ static Word16 large_symbol_enc_fx( /* o : bits push_indice_fx( hBstr, IND_HQ2_DIFF_ENERGY, LSB1[i], lsbdepth1 ); } /*bits += BANDS * lsbdepth1; */ - bits = add( bits, extract_h( L_shl( L_mult( BANDS, lsbdepth1 ), 15 ) ) ); + bits = add( bits, extract_h( L_shl( L_mult( BANDS, lsbdepth1 ), 15 ) ) ); /* Q0 */ } } } - return bits; /* xx bits for diff. energies + 1 bit for LC coding mode */ + return bits; /* xx bits for diff. energies + 1 bit for LC coding mode Q0*/ } static Word16 large_symbol_enc_ivas_fx( BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ - Word16 *qbidx, /* i : input of dequantized differential energy */ - const Word16 BANDS, /* i : number of bands */ - Word16 *hLCmode0, /* i/o: LC mode info */ - const Word16 flag_pack /* i : indicator of packing or estimating bits */ + Word16 *qbidx, /* i : input of dequantized differential energy Q0*/ + const Word16 BANDS, /* i : number of bands Q0*/ + Word16 *hLCmode0, /* i/o: LC mode info Q0*/ + const Word16 flag_pack /* i : indicator of packing or estimating bits Q0*/ ) { Word16 i, bits, tmp; @@ -2737,7 +2644,7 @@ static Word16 large_symbol_enc_ivas_fx( Word16 lsbdepth1; Word16 cnt_outlyer, pos_outlyer, cnt_outlyer0; - min_q = 513; + min_q = 513; /* Q0 */ move16(); max_q = -1; move16(); @@ -2786,15 +2693,15 @@ static Word16 large_symbol_enc_ivas_fx( test(); IF( GT_16( qbidx[i], 3 ) || LT_16( qbidx[i], -4 ) ) { - cnt_outlyer = add( cnt_outlyer, 1 ); + cnt_outlyer = add( cnt_outlyer, 1 ); /* Q0 */ pos_outlyer = i; move16(); } test(); - if ( GT_16( qbidx[i], sub( ABS_ENG_OFFSET, 1 ) ) || LT_16( qbidx[i], -ABS_ENG_OFFSET ) ) + IF( GT_16( qbidx[i], ( ABS_ENG_OFFSET - 1 ) ) || LT_16( qbidx[i], -ABS_ENG_OFFSET ) ) { - cnt_outlyer = add( cnt_outlyer, 1 ); + cnt_outlyer = add( cnt_outlyer, 1 ); /* Q0 */ } } @@ -2802,37 +2709,39 @@ static Word16 large_symbol_enc_ivas_fx( test(); IF( cnt_outlyer0 == 0 && LE_16( cnt_outlyer, 1 ) ) { - bitsmode0 = add( add( BITS_DE_8SMODE, BITS_DE_8SMODE_N0 ), BITS_DE_8SMODE_N1 ); + bitsmode0 = ( BITS_DE_8SMODE + BITS_DE_8SMODE_N0 ) + BITS_DE_8SMODE_N1; /* Q0 */ + move16(); IF( EQ_16( cnt_outlyer, 1 ) ) { /* 01 */ - bitsmode0 = add( bitsmode0, add( BITS_DE_8SPOS, BITS_ABS_ENG ) ); + bitsmode0 = add( bitsmode0, add( BITS_DE_8SPOS, BITS_ABS_ENG ) ); /* Q0 */ } FOR( i = 0; i < pos_outlyer; ++i ) { - tdifidx0[i] = qbidx[i]; + tdifidx0[i] = qbidx[i]; /* Q0 */ move16(); - bitsmode0 = add( bitsmode0, hessize[tdifidx0[i] + 4] ); + bitsmode0 = add( bitsmode0, hessize[tdifidx0[i] + 4] ); /* Q0 */ } - FOR( i = add( pos_outlyer, 1 ); i < BANDS; ++i ) + FOR( i = ( pos_outlyer + 1 ); i < BANDS; ++i ) { - tdifidx0[i] = qbidx[i]; + tdifidx0[i] = qbidx[i]; /* Q0 */ move16(); - bitsmode0 = add( bitsmode0, hessize[tdifidx0[i] + 4] ); + bitsmode0 = add( bitsmode0, hessize[tdifidx0[i] + 4] ); /* Q0 */ } } ELSE IF( EQ_16( cnt_outlyer0, 1 ) && LE_16( cnt_outlyer, 1 ) ) { - bitsmode0 = add( add( BITS_DE_8SMODE, BITS_DE_8SMODE_N0 ), BITS_DE_8SMODE_N1 ); - tdifidx0[0] = qbidx[0]; + bitsmode0 = ( BITS_DE_8SMODE + BITS_DE_8SMODE_N0 ) + BITS_DE_8SMODE_N1; /* Q0 */ move16(); - bitsmode0 = add( bitsmode0, BITS_ABS_ENG ); + tdifidx0[0] = qbidx[0]; /* Q0 */ + move16(); + bitsmode0 = add( bitsmode0, BITS_ABS_ENG ); /* Q0 */ IF( EQ_16( cnt_outlyer, 1 ) ) { /* 11 */ - bitsmode0 = add( bitsmode0, add( BITS_DE_8SPOS, BITS_ABS_ENG ) ); + bitsmode0 = add( bitsmode0, ( BITS_DE_8SPOS + BITS_ABS_ENG ) ); /* Q0 */ } ELSE { @@ -2842,27 +2751,27 @@ static Word16 large_symbol_enc_ivas_fx( FOR( i = 1; i < pos_outlyer; ++i ) { - tdifidx0[i] = qbidx[i]; + tdifidx0[i] = qbidx[i]; /* Q0 */ move16(); - bitsmode0 = add( bitsmode0, hessize[tdifidx0[i] + 4] ); + bitsmode0 = add( bitsmode0, hessize[tdifidx0[i] + 4] ); /* Q0 */ } - FOR( i = add( pos_outlyer, 1 ); i < BANDS; ++i ) + FOR( i = ( pos_outlyer + 1 ); i < BANDS; ++i ) { - tdifidx0[i] = qbidx[i]; + tdifidx0[i] = qbidx[i]; /* Q0 */ move16(); - bitsmode0 = add( bitsmode0, hessize[tdifidx0[i] + 4] ); + bitsmode0 = add( bitsmode0, hessize[tdifidx0[i] + 4] ); /* Q0 */ } } ELSE { - bitsmode0 = 20000; + bitsmode0 = 20000; /* Q0 */ move16(); } } test(); - IF( flag_pack == 0 || *hLCmode0 == 1 ) + IF( flag_pack == 0 || EQ_16( *hLCmode0, 1 ) ) { /* components 0 range : -256~255 */ max_q = MINIMUM_ENERGY_LOWBRATE; @@ -2888,9 +2797,9 @@ static Word16 large_symbol_enc_ivas_fx( basic_shift = i; move16(); - min_bits = 1000; + min_bits = 1000; /* Q0 */ move16(); - min_bits_pos = basic_shift; + min_bits_pos = basic_shift; /* Q0 */ move16(); tmp = add( basic_shift, 3 ); FOR( offset0 = basic_shift; offset0 < tmp; offset0++ ) @@ -2900,30 +2809,33 @@ static Word16 large_symbol_enc_ivas_fx( min_q = MAXIMUM_ENERGY_LOWBRATE; move16(); - bitsmode1 = add( BITS_DE_8SMODE, BITS_MAX_DEPTH ); + bitsmode1 = ( BITS_DE_8SMODE + BITS_MAX_DEPTH ); /* Q0 */ + move16(); FOR( i = 0; i < BANDS; ++i ) { - bitsmode1 = add( bitsmode1, add( hessize[add( shr( qbidx[i], offset0 ), 4 )], offset0 ) ); + bitsmode1 = add( bitsmode1, add( hessize[( ( qbidx[i] >> offset0 ) + 4 )], offset0 ) ); /* Q0 */ } IF( GT_16( min_bits, bitsmode1 ) ) { - min_bits_pos = offset0; + min_bits_pos = offset0; /* Q0 */ move16(); - min_bits = bitsmode1; + min_bits = bitsmode1; /* Q0 */ move16(); } } - bitsmode1 = min_bits; + bitsmode1 = min_bits; /* Q0 */ move16(); - lsbdepth1 = min_bits_pos; + lsbdepth1 = min_bits_pos; /* Q0 */ move16(); FOR( i = 0; i < BANDS; ++i ) { LSB1[i] = s_and( qbidx[i], sub( shl( 1, lsbdepth1 ), 1 ) ); tdifidx1[i] = shr( qbidx[i], lsbdepth1 ); + move16(); + move16(); } } @@ -2934,14 +2846,14 @@ static Word16 large_symbol_enc_ivas_fx( /* Encoding MSB bits */ IF( LT_16( bitsmode0, bitsmode1 ) ) { - bits = bitsmode0; + bits = bitsmode0; /* Q0 */ move16(); *hLCmode0 = 0; move16(); } ELSE { - bits = bitsmode1; + bits = bitsmode1; /* Q0 */ move16(); *hLCmode0 = 1; move16(); @@ -2963,7 +2875,7 @@ static Word16 large_symbol_enc_ivas_fx( { /* 01 */ push_indice( hBstr, IND_HQ2_DENG_8SMODE_N1, 1, BITS_DE_8SMODE_N1 ); - bits = add( bits, BITS_DE_8SMODE_N1 ); + bits = add( bits, BITS_DE_8SMODE_N1 ); /* Q0 */ push_indice( hBstr, IND_HQ2_DENG_8SPOS, pos_outlyer, BITS_DE_8SPOS ); bits = add( bits, BITS_DE_8SPOS ); push_indice( hBstr, IND_HQ2_DIFF_ENERGY, qbidx[pos_outlyer] + ABS_ENG_OFFSET, BITS_ABS_ENG ); @@ -2973,29 +2885,29 @@ static Word16 large_symbol_enc_ivas_fx( { /* 00 */ push_indice( hBstr, IND_HQ2_DENG_8SMODE_N1, 0, BITS_DE_8SMODE_N1 ); - bits = add( bits, BITS_DE_8SMODE_N1 ); + bits = add( bits, BITS_DE_8SMODE_N1 ); /* Q0 */ } FOR( i = 0; i < pos_outlyer; ++i ) { push_indice( hBstr, IND_HQ2_DIFF_ENERGY, hescode[tdifidx0[i] + 4], hessize[tdifidx0[i] + 4] ); - bitsmode0 = add( bitsmode0, hessize[tdifidx0[i] + 4] ); + bitsmode0 = add( bitsmode0, hessize[tdifidx0[i] + 4] ); /* Q0 */ } - FOR( i = add( pos_outlyer, 1 ); i < BANDS; ++i ) + FOR( i = ( pos_outlyer + 1 ); i < BANDS; ++i ) { push_indice( hBstr, IND_HQ2_DIFF_ENERGY, hescode[tdifidx0[i] + 4], hessize[tdifidx0[i] + 4] ); - bitsmode0 = add( bitsmode0, hessize[tdifidx0[i] + 4] ); + bitsmode0 = add( bitsmode0, hessize[tdifidx0[i] + 4] ); /* Q0 */ } } ELSE IF( EQ_16( cnt_outlyer0, 1 ) ) { push_indice( hBstr, IND_HQ2_DENG_8SMODE_N0, 1, BITS_DE_8SMODE_N0 ); - bits = add( bits, BITS_DE_8SMODE_N0 ); + bits = add( bits, BITS_DE_8SMODE_N0 ); /* Q0 */ IF( EQ_16( cnt_outlyer, 1 ) ) { push_indice( hBstr, IND_HQ2_DENG_8SMODE_N1, 1, BITS_DE_8SMODE_N1 ); - bits = add( bits, BITS_DE_8SMODE_N1 ); + bits = add( bits, BITS_DE_8SMODE_N1 ); /* Q0 */ push_indice( hBstr, IND_HQ2_DENG_8SPOS, pos_outlyer, BITS_DE_8SPOS ); bits = add( bits, BITS_DE_8SPOS ); push_indice( hBstr, IND_HQ2_DIFF_ENERGY, qbidx[0] + ABS_ENG_OFFSET, BITS_ABS_ENG ); @@ -3006,21 +2918,21 @@ static Word16 large_symbol_enc_ivas_fx( ELSE { push_indice( hBstr, IND_HQ2_DENG_8SMODE_N1, 0, BITS_DE_8SMODE_N1 ); - bits = add( bits, BITS_DE_8SMODE_N1 ); + bits = add( bits, BITS_DE_8SMODE_N1 ); /* Q0 */ push_indice( hBstr, IND_HQ2_DIFF_ENERGY, qbidx[0] + ABS_ENG_OFFSET, BITS_ABS_ENG ); - bits = add( bits, BITS_ABS_ENG ); + bits = add( bits, BITS_ABS_ENG ); /* Q0 */ } FOR( i = 1; i < pos_outlyer; ++i ) { push_indice( hBstr, IND_HQ2_DIFF_ENERGY, hescode[tdifidx0[i] + 4], hessize[tdifidx0[i] + 4] ); - bits = add( bits, hessize[tdifidx0[i] + 4] ); + bits = add( bits, hessize[tdifidx0[i] + 4] ); /* Q0 */ } FOR( i = pos_outlyer + 1; i < BANDS; ++i ) { push_indice( hBstr, IND_HQ2_DIFF_ENERGY, hescode[tdifidx0[i] + 4], hessize[tdifidx0[i] + 4] ); - bits = add( bits, hessize[tdifidx0[i] + 4] ); + bits = add( bits, hessize[tdifidx0[i] + 4] ); /* Q0 */ } } } @@ -3033,7 +2945,7 @@ static Word16 large_symbol_enc_ivas_fx( FOR( i = 0; i < BANDS; ++i ) { push_indice( hBstr, IND_HQ2_DIFF_ENERGY, hescode[tdifidx1[i] + 4], hessize[tdifidx1[i] + 4] ); - bits = add( bits, hessize[tdifidx1[i] + 4] ); + bits = add( bits, hessize[tdifidx1[i] + 4] ); /* Q0 */ } IF( lsbdepth1 > 0 ) @@ -3043,12 +2955,12 @@ static Word16 large_symbol_enc_ivas_fx( push_indice( hBstr, IND_HQ2_DIFF_ENERGY, LSB1[i], lsbdepth1 ); } /*bits += BANDS * lsbdepth1; */ - bits = add( bits, extract_h( L_shl( L_mult( BANDS, lsbdepth1 ), 15 ) ) ); + bits = add( bits, extract_h( L_shl( L_mult( BANDS, lsbdepth1 ), 15 ) ) ); /* Q0 */ } } } - return bits; /* xx bits for diff. energies + 1 bit for LC coding mode */ + return bits; /* xx bits for diff. energies + 1 bit for LC coding mode Q0*/ } /*-------------------------------------------------------------------* @@ -3074,6 +2986,7 @@ static Word16 band_energy_quant_fx( Word16 hLCmode0, hLCmode1, deng_bits; Word16 deng_cmode = 0; Word16 hbits; + move16(); Word32 L_E; Word16 QE; @@ -3104,7 +3017,7 @@ static Word16 band_energy_quant_fx( L_tmp = L_deposit_l( 1295 ); /* 1295 = sqrt(0.1) (Qs) */ FOR( i = band_start[k]; i <= band_end[k]; i++ ) { - L_tmp = L_or( L_tmp, L_abs( L_t_audio[i] ) ); + L_tmp = L_or( L_tmp, L_abs( L_t_audio[i] ) ); /* Qs */ } exp_norm = norm_l( L_tmp ); exp_norm = sub( exp_norm, exp_safe ); /* safe_shift */ @@ -3114,18 +3027,19 @@ static Word16 band_energy_quant_fx( FOR( i = band_start[k]; i <= band_end[k]; i++ ) { /*E += yos[i] * yos[i]; */ - temp_fx = round_fx( L_shl( L_t_audio[i], exp_norm ) ); - L_E = L_mac( L_E, temp_fx, temp_fx ); /* (Qs+exp_norm-16)*2+1 */ + temp_fx = round_fx( L_shl( L_t_audio[i], exp_norm ) ); /* Qs+exp_norm-16 */ + L_E = L_mac( L_E, temp_fx, temp_fx ); /* (Qs+exp_norm-16)*2+1 */ } /*band_energy[k] = (float) log2_f (E + 1.0e-1f); */ exp_norm2 = norm_l( L_E ); exp = add( add( shl( sub( add( SWB_BWE_LR_Qs, exp_norm ), 16 ), 1 ), 1 ), exp_norm2 ); - L_E = L_shl( L_E, exp_norm2 ); + L_E = L_shl( L_E, exp_norm2 ); /* (Qs+exp_norm-16)*2 + 1 + exp_norm2 */ frac = Log2_norm_lc( L_E ); exp = sub( 30, exp ); L_tmp = L_Comp( exp, frac ); L_band_energy[k] = L_shr( L_tmp, 2 ); /* Q16->Qbe(Q14) */ + move32(); } IF( is_transient_fx ) @@ -3144,53 +3058,55 @@ static Word16 band_energy_quant_fx( { /*bq1[k] = round_f (band_energy[k] / qint); */ L_tmp = Mpy_32_16_1( L_band_energy[k], rev_qint_fx ); /* Q14+Qrev_qint-15 */ - bq1_fx[k] = round_fx( L_shl( L_tmp, sub( 17, Qrev_qint ) ) ); /* 16-(14+Qrev_qint-15) */ + bq1_fx[k] = round_fx( L_shl( L_tmp, sub( 17, Qrev_qint ) ) ); /* Q0 */ + move16(); } IF( is_transient_fx ) { - Copy( bq1_fx, bq1_temp_fx, bands_fx ); + Copy( bq1_fx, bq1_temp_fx, bands_fx ); /* Q0 */ /* Calculate the differential energies */ diffcod_lrmdct_fx( bands_fx, bq0_fx, bq1_temp_fx, bq2_temp_fx, is_transient_fx ); } /* Calculate the differential energies */ - bq2_fx[0] = sub( bq1_fx[0], bq0_fx ); + bq2_fx[0] = sub( bq1_fx[0], bq0_fx ); /* Q0 */ + move16(); FOR( k = 1; k < bands_fx; k++ ) { - bq2_fx[k] = sub( bq1_fx[k], bq1_fx[k - 1] ); + bq2_fx[k] = sub( bq1_fx[k], bq1_fx[k - 1] ); /* Q0 */ move16(); } /* Modifying qbidx to be located in the range -256~255 */ FOR( i = 0; i < bands_fx; ++i ) { - if ( GT_16( bq2_fx[i], MAXIMUM_ENERGY_LOWBRATE ) ) + IF( GT_16( bq2_fx[i], MAXIMUM_ENERGY_LOWBRATE ) ) { - bq2_fx[i] = MAXIMUM_ENERGY_LOWBRATE; + bq2_fx[i] = MAXIMUM_ENERGY_LOWBRATE; /* Q0 */ move16(); } - if ( LT_16( bq2_fx[i], MINIMUM_ENERGY_LOWBRATE ) ) + IF( LT_16( bq2_fx[i], MINIMUM_ENERGY_LOWBRATE ) ) { - bq2_fx[i] = MINIMUM_ENERGY_LOWBRATE; + bq2_fx[i] = MINIMUM_ENERGY_LOWBRATE; /* Q0 */ move16(); } } /* Get number of bits by Huffman0 coding */ - ebits = large_symbol_enc_fx( hBstr, bq2_fx, bands_fx, &hLCmode0, 0 ); + ebits = large_symbol_enc_fx( hBstr, bq2_fx, bands_fx, &hLCmode0, 0 ); /* Q0 */ IF( is_transient_fx ) { /* Get number of bits by Huffman coding */ - hbits = small_symbol_enc_tran_fx( hBstr, bq2_temp_fx, bands_fx, &hLCmode1, 0, is_transient_fx ); + hbits = small_symbol_enc_tran_fx( hBstr, bq2_temp_fx, bands_fx, &hLCmode1, 0, is_transient_fx ); /* Q0 */ } ELSE { /* Get number of bits by Huffman coding */ - hbits = small_symbol_enc_fx( hBstr, bq2_fx, bands_fx, &hLCmode1, 0, is_transient_fx ); + hbits = small_symbol_enc_fx( hBstr, bq2_fx, bands_fx, &hLCmode1, 0, is_transient_fx ); /* Q0 */ } /* comparing used bits */ @@ -3201,7 +3117,7 @@ static Word16 band_energy_quant_fx( move16(); push_indice_fx( hBstr, IND_HQ2_DENG_MODE, deng_cmode, BITS_DE_CMODE ); large_symbol_enc_fx( hBstr, bq2_fx, bands_fx, &hLCmode0, 1 ); - deng_bits = add( ebits, BITS_DE_CMODE ); + deng_bits = add( ebits, BITS_DE_CMODE ); /* Q0 */ } ELSE { @@ -3210,12 +3126,12 @@ static Word16 band_energy_quant_fx( move16(); push_indice_fx( hBstr, IND_HQ2_DENG_MODE, deng_cmode, BITS_DE_CMODE ); - deng_bits = add( hbits, BITS_DE_CMODE ); + deng_bits = add( hbits, BITS_DE_CMODE ); /* Q0 */ /* packing indice */ IF( is_transient_fx ) { - Copy( bq2_temp_fx, bq2_fx, bands_fx ); + Copy( bq2_temp_fx, bq2_fx, bands_fx ); /* Q0 */ small_symbol_enc_tran_fx( hBstr, bq2_fx, bands_fx, &hLCmode1, 1, is_transient_fx ); } ELSE @@ -3225,17 +3141,18 @@ static Word16 band_energy_quant_fx( } /* Reconstruct quantized spectrum */ - bq1_fx[0] = add( bq2_fx[0], bq0_fx ); + bq1_fx[0] = add( bq2_fx[0], bq0_fx ); /* Q0 */ move16(); FOR( k = 1; k < bands_fx; k++ ) { - bq1_fx[k] = add( bq2_fx[k], bq1_fx[k - 1] ); + bq1_fx[k] = add( bq2_fx[k], bq1_fx[k - 1] ); /* Q0 */ move16(); } FOR( k = 0; k < bands_fx; k++ ) { L_band_energy[k] = Mpy_32_16_1( L_qint, bq1_fx[k] ); /* 29+0-15 -> Qbe(Q14) */ + move32(); } IF( is_transient_fx ) @@ -3243,7 +3160,7 @@ static Word16 band_energy_quant_fx( reverse_transient_frame_energies_fx( L_band_energy, bands_fx ); } - return ( deng_bits ); + return ( deng_bits ); /* Q0 */ } @@ -3294,7 +3211,7 @@ static Word16 band_energy_quant_ivas_fx( L_tmp = L_deposit_l( 1295 ); /* 1295 = sqrt(0.1) (Qs) */ FOR( i = band_start[k]; i <= band_end[k]; i++ ) { - L_tmp = L_or( L_tmp, L_abs( L_t_audio[i] ) ); + L_tmp = L_or( L_tmp, L_abs( L_t_audio[i] ) ); /* Qs */ } exp_norm = norm_l( L_tmp ); exp_norm = sub( exp_norm, exp_safe ); /* safe_shift */ @@ -3304,18 +3221,19 @@ static Word16 band_energy_quant_ivas_fx( FOR( i = band_start[k]; i <= band_end[k]; i++ ) { /*E += yos[i] * yos[i]; */ - temp_fx = round_fx( L_shl( L_t_audio[i], exp_norm ) ); - L_E = L_mac( L_E, temp_fx, temp_fx ); /* (Qs+exp_norm-16)*2+1 */ + temp_fx = round_fx( L_shl( L_t_audio[i], exp_norm ) ); /* Qs+exp_norm-16 */ + L_E = L_mac( L_E, temp_fx, temp_fx ); /* (Qs+exp_norm-16)*2+1 */ } /*band_energy[k] = (float) log2_f (E + 1.0e-1f); */ exp_norm2 = norm_l( L_E ); exp = add( add( shl( sub( add( SWB_BWE_LR_Qs, exp_norm ), 16 ), 1 ), 1 ), exp_norm2 ); - L_E = L_shl( L_E, exp_norm2 ); + L_E = L_shl( L_E, exp_norm2 ); /* (Qs+exp_norm-16)*2 + 1 + exp_norm2 */ frac = Log2_norm_lc( L_E ); exp = sub( 30, exp ); L_tmp = L_Comp( exp, frac ); L_band_energy[k] = L_shr( L_tmp, 2 ); /* Q16->Qbe(Q14) */ + move32(); } IF( is_transient ) @@ -3333,24 +3251,26 @@ static Word16 band_energy_quant_ivas_fx( { /*bq1[k] = round_f (band_energy[k] / qint); */ L_tmp = L_mls( L_band_energy[k], rev_qint_fx ); /* Q14+Qrev_qint-15 */ - bq1_fx[k] = round_fx( L_shl( L_tmp, sub( 17, Qrev_qint ) ) ); /* 16-(14+Qrev_qint-15) */ + bq1_fx[k] = round_fx( L_shl( L_tmp, sub( 17, Qrev_qint ) ) ); /* Q0 */ + move16(); } #undef WMC_TOOL_SKIP IF( is_transient ) { - Copy( bq1_fx, bq1_temp_fx, bands ); + Copy( bq1_fx, bq1_temp_fx, bands ); /* Q0 */ /* Calculate the differential energies */ - diffcod_lrmdct_fx( bands, bq0_fx, bq1_temp_fx, bq2_temp_fx, is_transient ); + diffcod_lrmdct_fx( bands, bq0_fx, bq1_temp_fx, bq2_temp_fx, is_transient ); /* Q0 */ } /* Calculate the differential energies */ - bq2_fx[0] = sub( bq1_fx[0], bq0_fx ); + bq2_fx[0] = sub( bq1_fx[0], bq0_fx ); /* Q0 */ + move16(); FOR( k = 1; k < bands; k++ ) { - bq2_fx[k] = sub( bq1_fx[k], bq1_fx[k - 1] ); + bq2_fx[k] = sub( bq1_fx[k], bq1_fx[k - 1] ); /* Q0 */ move16(); } @@ -3358,30 +3278,30 @@ static Word16 band_energy_quant_ivas_fx( /* Modifying qbidx to be located in the range -256~255 */ FOR( i = 0; i < bands; ++i ) { - if ( bq2_fx[i] > MAXIMUM_ENERGY_LOWBRATE ) + IF( GT_16( bq2_fx[i], MAXIMUM_ENERGY_LOWBRATE ) ) { - bq2_fx[i] = MAXIMUM_ENERGY_LOWBRATE; + bq2_fx[i] = MAXIMUM_ENERGY_LOWBRATE; /* Q0 */ move16(); } - if ( bq2_fx[i] < MINIMUM_ENERGY_LOWBRATE ) + IF( LT_16( bq2_fx[i], MINIMUM_ENERGY_LOWBRATE ) ) { - bq2_fx[i] = MINIMUM_ENERGY_LOWBRATE; + bq2_fx[i] = MINIMUM_ENERGY_LOWBRATE; /* Q0 */ move16(); } } /* Get number of bits by Huffman0 coding */ - ebits = large_symbol_enc_ivas_fx( hBstr, bq2_fx, bands, &hLCmode0, 0 ); + ebits = large_symbol_enc_ivas_fx( hBstr, bq2_fx, bands, &hLCmode0, 0 ); /* Q0 */ IF( is_transient ) { /* Get number of bits by Huffman coding */ - hbits = small_symbol_enc_tran_ivas_fx( hBstr, bq2_temp_fx, bands, &hLCmode1, 0, is_transient ); + hbits = small_symbol_enc_tran_ivas_fx( hBstr, bq2_temp_fx, bands, &hLCmode1, 0, is_transient ); /* Q0 */ } ELSE { /* Get number of bits by Huffman coding */ - hbits = small_symbol_enc_ivas_fx( hBstr, bq2_fx, bands, &hLCmode1, 0, is_transient ); + hbits = small_symbol_enc_ivas_fx( hBstr, bq2_fx, bands, &hLCmode1, 0, is_transient ); /* Q0 */ } test(); @@ -3391,7 +3311,7 @@ static Word16 band_energy_quant_ivas_fx( move16(); push_indice( hBstr, IND_HQ2_DENG_MODE, deng_cmode, BITS_DE_CMODE ); large_symbol_enc_ivas_fx( hBstr, bq2_fx, bands, &hLCmode0, 1 ); - deng_bits = add( ebits, BITS_DE_CMODE ); + deng_bits = add( ebits, BITS_DE_CMODE ); /* Q0 */ } ELSE { @@ -3400,12 +3320,12 @@ static Word16 band_energy_quant_ivas_fx( move16(); push_indice( hBstr, IND_HQ2_DENG_MODE, deng_cmode, BITS_DE_CMODE ); - deng_bits = add( hbits, BITS_DE_CMODE ); + deng_bits = add( hbits, BITS_DE_CMODE ); /* Q0 */ /* packing indice */ IF( is_transient ) { - Copy( bq2_temp_fx, bq2_fx, bands ); + Copy( bq2_temp_fx, bq2_fx, bands ); /* Q0 */ small_symbol_enc_tran_ivas_fx( hBstr, bq2_fx, bands, &hLCmode1, 1, is_transient ); } ELSE @@ -3415,17 +3335,19 @@ static Word16 band_energy_quant_ivas_fx( } /* Reconstruct quantized spectrum */ - bq1_fx[0] = add( bq2_fx[0], bq0_fx ); + bq1_fx[0] = add( bq2_fx[0], bq0_fx ); /* Q0 */ + move16(); FOR( k = 1; k < bands; k++ ) { - bq1_fx[k] = add( bq2_fx[k], bq1_fx[k - 1] ); + bq1_fx[k] = add( bq2_fx[k], bq1_fx[k - 1] ); /* Q0 */ + move16(); } FOR( k = 0; k < bands; k++ ) { #define WMC_TOOL_SKIP - L_band_energy[k] = L_mls( L_qint, (Word16) bq1_fx[k] ); - move32(); /* 29+0-15 -> Qbe(Q14) */ + L_band_energy[k] = L_mls( L_qint, (Word16) bq1_fx[k] ); /* 29+0-15 -> Qbe(Q14) */ + move32(); #undef WMC_TOOL_SKIP } @@ -3434,7 +3356,7 @@ static Word16 band_energy_quant_ivas_fx( reverse_transient_frame_energies_fx( L_band_energy, bands ); } - return ( deng_bits ); + return ( deng_bits ); /* Q0 */ } @@ -3474,16 +3396,18 @@ static Word16 p2a_threshold_quant_fx( Word16 p2a_fx; #ifdef BASOP_NOGLOB_DECLARE_LOCAL Flag Overflow = 0; + move32(); #endif exp_safe = 4; /* never happen overflow. */ + move16(); set16_fx( p2a_flags_fx, 1, bands ); move16(); j = 0; move16(); - FOR( k = sub( bands, p2a_bands ); k < bands; k++ ) + FOR( k = ( bands - p2a_bands ); k < bands; k++ ) { L_a = L_deposit_l( 0 ); L_p = L_deposit_l( 0 ); @@ -3491,7 +3415,7 @@ static Word16 p2a_threshold_quant_fx( L_tmp = L_deposit_l( 0 ); FOR( i = band_start[k]; i <= band_end[k]; i++ ) { - L_tmp = L_or( L_tmp, L_abs( L_t_audio[i] ) ); + L_tmp = L_or( L_tmp, L_abs( L_t_audio[i] ) ); /* Q12 */ } exp_norm = norm_l( L_tmp ); exp_norm = sub( exp_norm, exp_safe ); @@ -3499,9 +3423,9 @@ static Word16 p2a_threshold_quant_fx( FOR( i = band_start[k]; i <= band_end[k]; i++ ) { temp_fx = round_fx( L_shl( L_t_audio[i], exp_norm ) ); /* Q12+exp_norm-16 -> exp_norm-4 */ - L_e = L_mult( temp_fx, temp_fx ); + L_e = L_mult( temp_fx, temp_fx ); /* 2*(exp_norm-4)+1 */ - if ( GT_32( L_e, L_p ) ) + IF( GT_32( L_e, L_p ) ) { L_p = L_add( L_e, 0 ); } @@ -3515,8 +3439,8 @@ static Word16 p2a_threshold_quant_fx( exp_normn = norm_l( L_a ); exp_normn = sub( exp_normn, 1 ); exp_normd = norm_s( band_width[k] ); - norm_a_fx = div_l( L_shl( L_a, exp_normn ), shl( band_width[k], exp_normd ) ); - Qnorm_a = sub( sub( add( Qa, exp_normn ), exp_normd ), 1 ); /* (Qa+exp_normn)-exp_normd-1); */ + norm_a_fx = div_l( L_shl( L_a, exp_normn ), shl( band_width[k], exp_normd ) ); /* (Qa+exp_normn)-exp_normd-1); */ + Qnorm_a = sub( sub( add( Qa, exp_normn ), exp_normd ), 1 ); /*p2a = 10.0f * (float) log10 (p / a); */ p2a_fx = 0; @@ -3526,7 +3450,7 @@ static Word16 p2a_threshold_quant_fx( exp_normn = norm_l( L_p ); exp_normn = sub( exp_normn, 1 ); exp_normd = norm_s( norm_a_fx ); - pa_fx = div_l( L_shl( L_p, exp_normn ), shl( norm_a_fx, exp_normd ) ); + pa_fx = div_l( L_shl( L_p, exp_normn ), shl( norm_a_fx, exp_normd ) ); /* Qpa + exp_normn + Qnorm_a + exp_normd - 1 */ Qpa = sub( sub( add( Qa, exp_normn ), add( Qnorm_a, exp_normd ) ), 1 ); L_tmp = L_deposit_h( pa_fx ); @@ -3540,14 +3464,10 @@ static Word16 p2a_threshold_quant_fx( /* 10/( log(10)/log(2) ) = 3.01029995663981195211 24660(Q13) */ L_p2a = Mpy_32_16_1( L_tmp, 24660 ); /* 16+13-15 -> Q14 */ -#ifdef BASOP_NOGLOB p2a_fx = round_fx_o( L_shl_o( L_p2a, 13, &Overflow ), &Overflow ); /* 27 -16 -> 11 */ -#else - p2a_fx = round_fx( L_shl( L_p2a, 13 ) ); /* 27 -16 -> 11 */ -#endif } - if ( LE_16( p2a_fx, p2a_th_fx ) ) + IF( LE_16( p2a_fx, p2a_th_fx ) ) { p2a_flags_fx[k] = 0; move16(); @@ -3563,7 +3483,7 @@ static Word16 p2a_threshold_quant_fx( j = add( j, 1 ); } - return ( j ); + return ( j ); /* Q0 */ } static Word16 p2a_threshold_quant_ivas_fx( @@ -3596,6 +3516,7 @@ static Word16 p2a_threshold_quant_ivas_fx( Word16 p2a_fx; #ifdef BASOP_NOGLOB_DECLARE_LOCAL Flag Overflow = 0; + move32(); #endif exp_safe = 4; /* never happen overflow. */ @@ -3605,7 +3526,7 @@ static Word16 p2a_threshold_quant_ivas_fx( j = 0; move16(); - FOR( k = sub( bands, p2a_bands ); k < bands; k++ ) + FOR( k = ( bands - p2a_bands ); k < bands; k++ ) { L_a = L_deposit_l( 0 ); L_p = L_deposit_l( 0 ); @@ -3613,7 +3534,7 @@ static Word16 p2a_threshold_quant_ivas_fx( L_tmp = L_deposit_l( 0 ); FOR( i = band_start[k]; i <= band_end[k]; i++ ) { - L_tmp = L_or( L_tmp, L_abs( L_t_audio[i] ) ); + L_tmp = L_or( L_tmp, L_abs( L_t_audio[i] ) ); /* Q12 */ } exp_norm = norm_l( L_tmp ); exp_norm = sub( exp_norm, exp_safe ); @@ -3621,9 +3542,9 @@ static Word16 p2a_threshold_quant_ivas_fx( FOR( i = band_start[k]; i <= band_end[k]; i++ ) { temp_fx = round_fx( L_shl( L_t_audio[i], exp_norm ) ); /* Q12+exp_norm-16 -> exp_norm-4 */ - L_e = L_mult( temp_fx, temp_fx ); + L_e = L_mult( temp_fx, temp_fx ); /* (exp_norm-4)*2 + 1 */ - if ( GT_32( L_e, L_p ) ) + IF( GT_32( L_e, L_p ) ) { L_p = L_add( L_e, 0 ); } @@ -3637,8 +3558,8 @@ static Word16 p2a_threshold_quant_ivas_fx( exp_normn = norm_l( L_a ); exp_normn = sub( exp_normn, 1 ); exp_normd = norm_s( band_width[k] ); - norm_a_fx = div_l( L_shl( L_a, exp_normn ), shl( band_width[k], exp_normd ) ); - Qnorm_a = sub( sub( add( Qa, exp_normn ), exp_normd ), 1 ); /* (Qa+exp_normn)-exp_normd-1); */ + norm_a_fx = div_l( L_shl( L_a, exp_normn ), shl( band_width[k], exp_normd ) ); /* (Qa+exp_normn)-exp_normd-1); */ + Qnorm_a = sub( sub( add( Qa, exp_normn ), exp_normd ), 1 ); /*p2a = 10.0f * (float) log10 (p / a); */ p2a_fx = 0; @@ -3648,7 +3569,7 @@ static Word16 p2a_threshold_quant_ivas_fx( exp_normn = norm_l( L_p ); exp_normn = sub( exp_normn, 1 ); exp_normd = norm_s( norm_a_fx ); - pa_fx = div_l( L_shl( L_p, exp_normn ), shl( norm_a_fx, exp_normd ) ); + pa_fx = div_l( L_shl( L_p, exp_normn ), shl( norm_a_fx, exp_normd ) ); /* Qpa + exp_normn + Qnorm_a + exp_normd - 1 */ Qpa = sub( sub( add( Qa, exp_normn ), add( Qnorm_a, exp_normd ) ), 1 ); L_tmp = L_deposit_h( pa_fx ); @@ -3662,14 +3583,10 @@ static Word16 p2a_threshold_quant_ivas_fx( /* 10/( log(10)/log(2) ) = 3.01029995663981195211 24660(Q13) */ L_p2a = Mpy_32_16_1( L_tmp, 24660 ); /* 16+13-15 -> Q14 */ -#ifdef BASOP_NOGLOB p2a_fx = round_fx_o( L_shl_o( L_p2a, 13, &Overflow ), &Overflow ); /* 27 -16 -> 11 */ -#else - p2a_fx = round_fx( L_shl( L_p2a, 13 ) ); /* 27 -16 -> 11 */ -#endif } - if ( LE_16( p2a_fx, p2a_th_fx ) ) + IF( LE_16( p2a_fx, p2a_th_fx ) ) { p2a_flags_fx[k] = 0; move16(); @@ -3685,7 +3602,7 @@ static Word16 p2a_threshold_quant_ivas_fx( j = add( j, 1 ); } - return ( j ); + return ( j ); /* Q0 */ } @@ -3735,6 +3652,7 @@ static void mdct_spectrum_fine_gain_enc_fx( Word16 imin_fx; #ifdef BASOP_NOGLOB_DECLARE_LOCAL Flag Overflow = 0; + move32(); #endif /* Fine gain quantization on only the most significant energy bands */ @@ -3743,23 +3661,25 @@ static void mdct_spectrum_fine_gain_enc_fx( exp_normn = norm_l( L_qint ); exp_normn = sub( exp_normn, 1 ); exp_normd = norm_s( gqlevs ); - delta_fx = div_l( L_shl( L_qint, exp_normn ), shl( gqlevs, exp_normd ) ); - Qdelta = add( sub( exp_normn, exp_normd ), 28 ); /* 29+exp_normn-(exp_normd)-1; */ - L_delta = L_shl( L_deposit_h( delta_fx ), sub( 13, Qdelta ) ); + delta_fx = div_l( L_shl( L_qint, exp_normn ), shl( gqlevs, exp_normd ) ); /* 29+exp_normn-(exp_normd)-1; */ + Qdelta = add( sub( exp_normn, exp_normd ), 28 ); + L_delta = L_shl( L_deposit_h( delta_fx ), sub( 13, Qdelta ) ); /* Q29 */ /*q = (-qint + delta) / 2.0f; */ - L_q = L_shr( L_sub( L_delta, L_qint ), 1 ); + L_q = L_shr( L_sub( L_delta, L_qint ), 1 ); /* Q29 */ FOR( i = 0; i < gqlevs; i++ ) { /*gain_table[i] = (float) pow (2.0f, q * 0.5f); */ - L_temp = L_shr( L_shr( L_q, 1 ), sub( 29, 16 ) ); + L_temp = L_shr( L_shr( L_q, 1 ), sub( 29, 16 ) ); /* Q16 */ temp_lo_fx = L_Extract_lc( L_temp, &temp_hi_fx ); Qgt = sub( 14, temp_hi_fx ); gain_table_fx[i] = extract_l( Pow2( 14, temp_lo_fx ) ); /* Qgt */ + move16(); /*q += delta; */ L_q = L_add( L_q, L_delta ); gain_table_fx[i] = shl( gain_table_fx[i], sub( 14, Qgt ) ); /* Qgt -> Q14 */ + move16(); } FOR( k = sub( bands, Ngq ); k < bands; k++ ) @@ -3776,8 +3696,8 @@ static void mdct_spectrum_fine_gain_enc_fx( L_temp = L_deposit_l( 0 ); FOR( i = band_start[k_sort[k]]; i <= band_end[k_sort[k]]; i++ ) { - L_temp = L_or( L_temp, L_abs( L_y2[i] ) ); - L_temp = L_or( L_temp, L_abs( L_ybuf[i] ) ); + L_temp = L_or( L_temp, L_abs( L_y2[i] ) ); /* Q12 */ + L_temp = L_or( L_temp, L_abs( L_ybuf[i] ) ); /* Q12 */ } exp_norm = norm_l( L_temp ); exp_norm = sub( exp_norm, exp_safe ); /* safe_shift */ @@ -3788,12 +3708,12 @@ static void mdct_spectrum_fine_gain_enc_fx( FOR( i = band_start[k_sort[k]]; i <= band_end[k_sort[k]]; i++ ) { /*Eyy += y2[i] * y2[i]; */ - temp_fx = round_fx( L_shl( L_y2[i], exp_norm ) ); - L_Eyy = L_mac( L_Eyy, temp_fx, temp_fx ); + temp_fx = round_fx( L_shl( L_y2[i], exp_norm ) ); /* Q12 + exp_norm - 16 */ + L_Eyy = L_mac( L_Eyy, temp_fx, temp_fx ); /* (Q12 + exp_norm - 16)*2 + 1 */ /*Exy += ybuf[i] * y2[i]; */ - temp2_fx = round_fx( L_shl( L_ybuf[i], exp_norm ) ); - L_Exy = L_mac( L_Exy, temp2_fx, temp_fx ); + temp2_fx = round_fx( L_shl( L_ybuf[i], exp_norm ) ); /* Q12 + exp_norm - 16 */ + L_Exy = L_mac( L_Exy, temp2_fx, temp_fx ); /* (Q12 + exp_norm - 16)*2 + 1 */ } test(); @@ -3803,13 +3723,9 @@ static void mdct_spectrum_fine_gain_enc_fx( exp_normn = norm_l( L_Exy ); exp_normn = sub( exp_normn, 1 ); exp_normd = norm_l( L_Eyy ); -#ifdef BASOP_NOGLOB - gamma_fx = div_l( L_shl_o( L_Exy, exp_normn, &Overflow ), round_fx_o( L_shl_o( L_Eyy, exp_normd, &Overflow ), &Overflow ) ); -#else - gamma_fx = div_l( L_shl( L_Exy, exp_normn ), round_fx( L_shl( L_Eyy, exp_normd ) ) ); -#endif - Qgamma = add( sub( exp_normn, exp_normd ), 15 ); /* exp_normn - (exp_normd-16) - 1; */ - gamma_fx = shl( gamma_fx, sub( 14, Qgamma ) ); /* Qgamma -> Q14 */ + gamma_fx = div_l( L_shl_o( L_Exy, exp_normn, &Overflow ), round_fx_o( L_shl_o( L_Eyy, exp_normd, &Overflow ), &Overflow ) ); /* Qgamma */ + Qgamma = add( sub( exp_normn, exp_normd ), 15 ); /* exp_normn - (exp_normd-16) - 1; */ + gamma_fx = shl( gamma_fx, sub( 14, Qgamma ) ); /* Qgamma -> Q14 */ dmin_fx = 32767; move16(); @@ -3817,18 +3733,18 @@ static void mdct_spectrum_fine_gain_enc_fx( move16(); FOR( i = 0; i < gqlevs; i++ ) { - d_fx = abs_s( sub( gamma_fx, gain_table_fx[i] ) ); + d_fx = abs_s( sub( gamma_fx, gain_table_fx[i] ) ); /* Q14 */ IF( LT_16( d_fx, dmin_fx ) ) { - dmin_fx = d_fx; + dmin_fx = d_fx; /* Q14 */ move16(); imin_fx = i; move16(); } } - gamma_fx = gain_table_fx[imin_fx]; - move16(); /* Q14 */ + gamma_fx = gain_table_fx[imin_fx]; /* Q14 */ + move16(); FOR( i = band_start[k_sort[k]]; i <= band_end[k_sort[k]]; i++ ) { @@ -3836,11 +3752,13 @@ static void mdct_spectrum_fine_gain_enc_fx( /* This IF statement for keeping same mantissa evenif y2 is plus or minus */ IF( L_y2[i] >= 0x0 ) { - L_y2[i] = L_shl( Mpy_32_16_1( L_y2[i], gamma_fx ), 1 ); + L_y2[i] = L_shl( Mpy_32_16_1( L_y2[i], gamma_fx ), 1 ); /* Q12 */ + move32(); } ELSE { - L_y2[i] = L_negate( L_shl( Mpy_32_16_1( L_abs( L_y2[i] ), gamma_fx ), 1 ) ); + L_y2[i] = L_negate( L_shl( Mpy_32_16_1( L_abs( L_y2[i] ), gamma_fx ), 1 ) ); /* Q12 */ + move32(); } } } @@ -3896,6 +3814,7 @@ static void mdct_spectrum_fine_gain_enc_ivas_fx( Word16 imin_fx; #ifdef BASOP_NOGLOB_DECLARE_LOCAL Flag Overflow = 0; + move32(); #endif /* Fine gain quantization on only the most significant energy bands */ @@ -3905,22 +3824,24 @@ static void mdct_spectrum_fine_gain_enc_ivas_fx( exp_normn = sub( exp_normn, 1 ); exp_normd = norm_s( gqlevs ); delta_fx = div_l( L_shl( L_qint, exp_normn ), shl( gqlevs, exp_normd ) ); - Qdelta = add( sub( exp_normn, exp_normd ), 28 ); /* 29+exp_normn-(exp_normd)-1; */ - L_delta = L_shl( L_deposit_h( delta_fx ), sub( 13, Qdelta ) ); + Qdelta = add( sub( exp_normn, exp_normd ), 28 ); /* 29+exp_normn-(exp_normd)-1; */ + L_delta = L_shl( L_deposit_h( delta_fx ), sub( 13, Qdelta ) ); /* Q29 */ /*q = (-qint + delta) / 2.0f; */ - L_q = L_shr( L_sub( L_delta, L_qint ), 1 ); + L_q = L_shr( L_sub( L_delta, L_qint ), 1 ); /* Q29 */ FOR( i = 0; i < gqlevs; i++ ) { /*gain_table[i] = (float) pow (2.0f, q * 0.5f); */ - L_temp = L_shr( L_shr( L_q, 1 ), sub( 29, 16 ) ); + L_temp = L_shr( L_shr( L_q, 1 ), sub( 29, 16 ) ); /* Q16 */ temp_lo_fx = L_Extract_lc( L_temp, &temp_hi_fx ); Qgt = sub( 14, temp_hi_fx ); gain_table_fx[i] = extract_l( Pow2( 14, temp_lo_fx ) ); /* Qgt */ + move16(); /*q += delta; */ L_q = L_add( L_q, L_delta ); gain_table_fx[i] = shl( gain_table_fx[i], sub( 14, Qgt ) ); /* Qgt -> Q14 */ + move16(); } FOR( k = sub( bands, Ngq ); k < bands; k++ ) @@ -3937,8 +3858,8 @@ static void mdct_spectrum_fine_gain_enc_ivas_fx( L_temp = L_deposit_l( 0 ); FOR( i = band_start[k_sort[k]]; i <= band_end[k_sort[k]]; i++ ) { - L_temp = L_or( L_temp, L_abs( L_y2[i] ) ); - L_temp = L_or( L_temp, L_abs( L_ybuf[i] ) ); + L_temp = L_or( L_temp, L_abs( L_y2[i] ) ); /* Q12 */ + L_temp = L_or( L_temp, L_abs( L_ybuf[i] ) ); /* Q12 */ } exp_norm = norm_l( L_temp ); exp_norm = sub( exp_norm, exp_safe ); /* safe_shift */ @@ -3949,12 +3870,12 @@ static void mdct_spectrum_fine_gain_enc_ivas_fx( FOR( i = band_start[k_sort[k]]; i <= band_end[k_sort[k]]; i++ ) { /*Eyy += y2[i] * y2[i]; */ - temp_fx = round_fx( L_shl( L_y2[i], exp_norm ) ); - L_Eyy = L_mac( L_Eyy, temp_fx, temp_fx ); + temp_fx = round_fx( L_shl( L_y2[i], exp_norm ) ); /* Q12 + exp_norm - 16 */ + L_Eyy = L_mac( L_Eyy, temp_fx, temp_fx ); /* (Q12 + exp_norm - 16)*2 + 1 */ /*Exy += ybuf[i] * y2[i]; */ - temp2_fx = round_fx( L_shl( L_ybuf[i], exp_norm ) ); - L_Exy = L_mac( L_Exy, temp2_fx, temp_fx ); + temp2_fx = round_fx( L_shl( L_ybuf[i], exp_norm ) ); /* Q12 + exp_norm - 16 */ + L_Exy = L_mac( L_Exy, temp2_fx, temp_fx ); /* (Q12 + exp_norm - 16)*2 + 1 */ } test(); @@ -3964,13 +3885,9 @@ static void mdct_spectrum_fine_gain_enc_ivas_fx( exp_normn = norm_l( L_Exy ); exp_normn = sub( exp_normn, 1 ); exp_normd = norm_l( L_Eyy ); -#ifdef BASOP_NOGLOB - gamma_fx = div_l( L_shl_o( L_Exy, exp_normn, &Overflow ), round_fx_o( L_shl_o( L_Eyy, exp_normd, &Overflow ), &Overflow ) ); -#else - gamma_fx = div_l( L_shl( L_Exy, exp_normn ), round_fx( L_shl( L_Eyy, exp_normd ) ) ); -#endif - Qgamma = add( sub( exp_normn, exp_normd ), 15 ); /* exp_normn - (exp_normd-16) - 1; */ - gamma_fx = shl( gamma_fx, sub( 14, Qgamma ) ); /* Qgamma -> Q14 */ + gamma_fx = div_l( L_shl_o( L_Exy, exp_normn, &Overflow ), round_fx_o( L_shl_o( L_Eyy, exp_normd, &Overflow ), &Overflow ) ); /* Qgamma */ + Qgamma = add( sub( exp_normn, exp_normd ), 15 ); /* exp_normn - (exp_normd-16) - 1; */ + gamma_fx = shl( gamma_fx, sub( 14, Qgamma ) ); /* Qgamma -> Q14 */ dmin_fx = 32767; move16(); @@ -3978,18 +3895,18 @@ static void mdct_spectrum_fine_gain_enc_ivas_fx( move16(); FOR( i = 0; i < gqlevs; i++ ) { - d_fx = abs_s( sub( gamma_fx, gain_table_fx[i] ) ); + d_fx = abs_s( sub( gamma_fx, gain_table_fx[i] ) ); /* Q14 */ IF( LT_16( d_fx, dmin_fx ) ) { - dmin_fx = d_fx; + dmin_fx = d_fx; /* Q14 */ move16(); - imin_fx = i; + imin_fx = i; /* Q0 */ move16(); } } - gamma_fx = gain_table_fx[imin_fx]; - move16(); /* Q14 */ + gamma_fx = gain_table_fx[imin_fx]; /* Q14 */ + move16(); FOR( i = band_start[k_sort[k]]; i <= band_end[k_sort[k]]; i++ ) { @@ -3997,11 +3914,13 @@ static void mdct_spectrum_fine_gain_enc_ivas_fx( /* This IF statement for keeping same mantissa evenif y2 is plus or minus */ IF( L_y2[i] >= 0x0 ) { - L_y2[i] = L_shl( Mpy_32_16_1( L_y2[i], gamma_fx ), 1 ); + L_y2[i] = L_shl( Mpy_32_16_1( L_y2[i], gamma_fx ), 1 ); /* Q12 */ + move32(); } ELSE { - L_y2[i] = L_negate( L_shl( Mpy_32_16_1( L_abs( L_y2[i] ), gamma_fx ), 1 ) ); + L_y2[i] = L_negate( L_shl( Mpy_32_16_1( L_abs( L_y2[i] ), gamma_fx ), 1 ) ); /* Q12 */ + move32(); } } } diff --git a/lib_enc/hvq_enc.c b/lib_enc/hvq_enc.c deleted file mode 100644 index b693d838b6259978caa3f7b2a83451fef372455d..0000000000000000000000000000000000000000 --- a/lib_enc/hvq_enc.c +++ /dev/null @@ -1,44 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include -#include "cnst.h" -#include "prot.h" -#include "rom_enc.h" -#include "rom_com.h" -#include "wmc_auto.h" diff --git a/lib_enc/hvq_enc_fx.c b/lib_enc/hvq_enc_fx.c index aae437c01c68bfdc0b68272e2d7a9c66da6077cb..b06a1734dd6e65a8e17e029efdc5d5bb6a1f0347 100644 --- a/lib_enc/hvq_enc_fx.c +++ b/lib_enc/hvq_enc_fx.c @@ -8,12 +8,11 @@ //#include "prot_fx.h" #include "rom_com.h" #include "prot_fx.h" /* Function prototypes */ -#include "prot.h" /* Function prototypes */ #include "prot_fx_enc.h" /* Function prototypes */ #define HVQ_ENC_NOISE_DELTA ( (Word16) 3277 ) /* 0.1 in Q15 */ -static Word16 quant_lc( const Word16, Word16 * ); +static Word16 quant_lc_fx( const Word16, Word16 * ); /*--------------------------------------------------------------------------* @@ -119,11 +118,7 @@ Word16 hvq_enc_ivas_fx( /*o : Consumed bits nf_cnt = add( nf_cnt, 1 ); /* Q0 */ } -#ifdef BASOP_NOGLOB pe_mean = L_add_o( pe_mean, pe, &Overflow ); /* in Q12 and always positive */ -#else - pe_mean = L_add( pe_mean, pe ); /* in Q12 and always positive */ -#endif } IF( pe_mean > 0 ) @@ -150,14 +145,10 @@ Word16 hvq_enc_ivas_fx( /*o : Consumed bits acc = L_mult( tmp16, HVQ_NFPE_FACTOR_CUBE_FX ); /* in Q(12+6+1) = Q19 */ expNfpe3 = extract_l( L_mult0( expNfpe, 3 ) ); /* Cube operation */ /* Number of bits required to adjust to Q15 */ - adjust = add( 19 - ( 15 + 16 ), expNfpe3 ); /* +16 is due to the following extract_h(). */ -#ifdef BASOP_NOGLOB + adjust = add( 19 - ( 15 + 16 ), expNfpe3 ); /* +16 is due to the following extract_h(). */ noise_level[i] = extract_h( L_shr_o( acc, adjust, &Overflow ) ); /* noise_level[] in Q15 */ move16(); -#else - noise_level[i] = extract_h( L_shr( acc, adjust ) ); /* noise_level[] in Q15 */ -#endif - q_noise_level_idx[i] = quant_lc( noise_level[i], &q_noise_level[i] ); + q_noise_level_idx[i] = quant_lc_fx( noise_level[i], &q_noise_level[i] ); move16(); } ELSE @@ -185,22 +176,14 @@ Word16 hvq_enc_ivas_fx( /*o : Consumed bits acc = L_mult( tmp16, HVQ_LB_NFPE_FACTOR_CUBE_FX ); /* in Q(12+9+1) = Q22 */ expo3 = extract_l( L_mult0( expo, 3 ) ); /* Cube operation. */ /* Number of bits required to adjust to Q15 */ - adjust = add( 22 - ( 15 + 16 ), expo3 ); /* +16 is due to the following extract_h(). */ -#ifdef BASOP_NOGLOB + adjust = add( 22 - ( 15 + 16 ), expo3 ); /* +16 is due to the following extract_h(). */ lb_nfpe = extract_h( L_shr_o( acc, adjust, &Overflow ) ); /* noise_level[] in Q15 */ -#else - lb_nfpe = extract_h( L_shr( acc, adjust ) ); /* noise_level[] in Q15 */ -#endif - IF( GT_16( lb_nfpe, 16384 ) ) /* in Q15 */ + IF( GT_16( lb_nfpe, 16384 ) ) /* in Q15 */ { lb_nfpe = 16384; move16(); } -#ifdef BASOP_NOGLOB Mpy_32_16_ss( nf_gains[i], shl_o( lb_nfpe, 1, &Overflow ), &nf_gains[i], &dontCare ); /* nf_gains[] in Q12 */ -#else - Mpy_32_16_ss( nf_gains[i], shl( lb_nfpe, 1 ), &nf_gains[i], &dontCare ); /* nf_gains[] in Q12 */ -#endif } ELSE { @@ -245,6 +228,7 @@ Word16 hvq_enc_fx( /*o : Consumed bits Word16 tmp16, adjust; #ifdef BASOP_NOGLOB_DECLARE_LOCAL Flag Overflow = 0; + move32(); #endif bits_used = 0; move16(); @@ -311,11 +295,7 @@ Word16 hvq_enc_fx( /*o : Consumed bits nf_cnt = add( nf_cnt, 1 ); /* Q0 */ } -#ifdef BASOP_NOGLOB pe_mean = L_add_o( pe_mean, pe, &Overflow ); /* in Q12 and always positive */ -#else - pe_mean = L_add( pe_mean, pe ); /* in Q12 and always positive */ -#endif } IF( pe_mean > 0 ) @@ -342,13 +322,11 @@ Word16 hvq_enc_fx( /*o : Consumed bits acc = L_mult( tmp16, HVQ_NFPE_FACTOR_CUBE_FX ); /* in Q(12+6+1) = Q19 */ expNfpe3 = extract_l( L_mult0( expNfpe, 3 ) ); /* Cube operation */ /* Number of bits required to adjust to Q15 */ - adjust = add( 19 - ( 15 + 16 ), expNfpe3 ); /* +16 is due to the following extract_h(). */ -#ifdef BASOP_NOGLOB + adjust = add( 19 - ( 15 + 16 ), expNfpe3 ); /* +16 is due to the following extract_h(). */ noise_level[i] = extract_h( L_shr_o( acc, adjust, &Overflow ) ); /* noise_level[] in Q15 */ -#else - noise_level[i] = extract_h( L_shr( acc, adjust ) ); /* noise_level[] in Q15 */ -#endif - q_noise_level_idx[i] = quant_lc( noise_level[i], &q_noise_level[i] ); + move16(); + q_noise_level_idx[i] = quant_lc_fx( noise_level[i], &q_noise_level[i] ); + move16(); } ELSE { @@ -361,6 +339,7 @@ Word16 hvq_enc_fx( /*o : Consumed bits bits_used = add( bits_used, 2 ); noise_level[i] = q_noise_level[i]; /* in Q15 */ + move16(); } FOR( i = 0; i < HVQ_NF_GROUPS; i++ ) @@ -374,22 +353,14 @@ Word16 hvq_enc_fx( /*o : Consumed bits acc = L_mult( tmp16, HVQ_LB_NFPE_FACTOR_CUBE_FX ); /* in Q(12+9+1) = Q22 */ expo3 = extract_l( L_mult0( expo, 3 ) ); /* Cube operation. */ /* Number of bits required to adjust to Q15 */ - adjust = add( 22 - ( 15 + 16 ), expo3 ); /* +16 is due to the following extract_h(). */ -#ifdef BASOP_NOGLOB + adjust = add( 22 - ( 15 + 16 ), expo3 ); /* +16 is due to the following extract_h(). */ lb_nfpe = extract_h( L_shr_o( acc, adjust, &Overflow ) ); /* noise_level[] in Q15 */ -#else - lb_nfpe = extract_h( L_shr( acc, adjust ) ); /* noise_level[] in Q15 */ -#endif - IF( lb_nfpe > 16384 ) /* in Q15 */ + IF( lb_nfpe > 16384 ) /* in Q15 */ { lb_nfpe = 16384; move16(); } -#ifdef BASOP_NOGLOB Mpy_32_16_ss( nf_gains[i], shl_o( lb_nfpe, 1, &Overflow ), &nf_gains[i], &dontCare ); /* nf_gains[] in Q12 */ -#else - Mpy_32_16_ss( nf_gains[i], shl( lb_nfpe, 1 ), &nf_gains[i], &dontCare ); /* nf_gains[] in Q12 */ -#endif } ELSE { @@ -399,6 +370,7 @@ Word16 hvq_enc_fx( /*o : Consumed bits } nBits = peak_vq_enc_fx( st_fx->hBstr, st_fx->bwidth, coefs, coefs_out, core_brate, sub( hvq_bits, bits_used ), Npeaks, ynrm, R, peaks, &nf_gains[0] ); + move16(); bits_used = add( bits_used, nBits ); return bits_used; } @@ -408,7 +380,7 @@ Word16 hvq_enc_fx( /*o : Consumed bits * * Quantize the noise to one of the levels in {0, 0.1, 0.2, 0.3} *----------------------------------------------------------------------------*/ -static Word16 quant_lc( const Word16 x, Word16 *qx ) +static Word16 quant_lc_fx( const Word16 x, Word16 *qx ) { Word16 indx; diff --git a/lib_enc/igf_enc.c b/lib_enc/igf_enc.c index 4fa98f20bfbd8f3c6339e546163407e4005a3762..fc7c32fdbd7119867a844145f82b2c742ab98662 100644 --- a/lib_enc/igf_enc.c +++ b/lib_enc/igf_enc.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other @@ -38,24 +38,22 @@ #include #include "options.h" #include -#include "prot.h" -#include "ivas_prot.h" +#include "prot_fx.h" #include "cnst.h" #include "stat_enc.h" #include "wmc_auto.h" #include "prot_fx_enc.h" -#include "prot_fx.h" #define INV_Log2_10_Q15 9864 /*1/log2(10) in Q15*/ #define INV_Log2_10_Q12 1233 /*1/log2(10) in Q12*/ #define INV_Log2_e_Q15 22713 /*1/log2(e) in Q15*/ /*-------------------------------------------------------------------* - * IGF_write_bit() + * IGF_write_bit_fx() * * write single bit to stream *-------------------------------------------------------------------*/ -static void IGF_write_bit( +static void IGF_write_bit_fx( BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ Word16 *bitCount, /* i/o: bit counter */ const Word16 value /* i : value */ @@ -88,11 +86,11 @@ static void IGF_write_bits( { IF( s_and( value, shl( 1, bits ) ) == 0 ) { - IGF_write_bit( hBstr, bitCount, 0 ); + IGF_write_bit_fx( hBstr, bitCount, 0 ); } ELSE { - IGF_write_bit( hBstr, bitCount, 1 ); + IGF_write_bit_fx( hBstr, bitCount, 1 ); } } @@ -184,7 +182,7 @@ static Word16 IGF_getSFM_new_fx( const Word16 *logSpec, /* i : log of power spectrum */ const Word16 start, /* i : start subband index */ const Word16 stop, /* i : stop subband index */ - Word16 e_ps /*Stores exp related to power spectrum*/ + Word16 *e_ps /*Stores exp related to power spectrum*/ ) { Word16 n; @@ -215,7 +213,7 @@ static Word16 IGF_getSFM_new_fx( move32(); move16(); num = add( num, n ); - denom = BASOP_Util_Add_Mant32Exp( tmp, e_ps, denom, denom_e, &denom_e ); + denom = BASOP_Util_Add_Mant32Exp( tmp, e_ps[i], denom, denom_e, &denom_e ); } numf = BASOP_Util_Divide1616_Scale( num, sub( stop, start ), &numf_e ); @@ -232,8 +230,6 @@ static Word16 IGF_getSFM_new_fx( return sfm; } - - /*-------------------------------------------------------------------* * IGF_getTilt() * @@ -292,27 +288,27 @@ static Word32 IGF_getTNR_fx( width = sub( stop, start ); FOR( i = start; i < stop; i++ ) { - rootSpec_e[sub( i, start )] = e_ps; + rootSpec_e[i - start] = e_ps; move16(); - rootSpec[sub( i, start )] = Sqrt32( powerSpectrum[i], &rootSpec_e[sub( i, start )] ); /*rootSpec[i - start] = sqrtf( powerSpectrum[i] );*/ + rootSpec[i - start] = Sqrt32( powerSpectrum[i], &rootSpec_e[i - start] ); /*rootSpec[i - start] = sqrtf( powerSpectrum[i] );*/ move32(); - avg = BASOP_Util_Add_Mant32Exp( avg, avg_e, rootSpec[sub( i, start )], rootSpec_e[sub( i, start )], &avg_e ); /*avg += rootSpec[i - start];resultant exponent is avg_e*/ + avg = BASOP_Util_Add_Mant32Exp( avg, avg_e, rootSpec[i - start], rootSpec_e[i - start], &avg_e ); /*avg += rootSpec[i - start];resultant exponent is avg_e*/ } avg = BASOP_Util_Divide3216_Scale( avg, width, &tmp_e ); /*avg /= width;*/ avg_e = add( 16, sub( add( avg_e, tmp_e ), 15 ) ); FOR( i = start; i < stop; i++ ) { - Word16 normSpec_e; /*stores resultant exponent for normSpec*/ - Word16 normSpec = BASOP_Util_Divide3232_Scale( rootSpec[sub( i, start )], avg, &normSpec_e ); /*rootSpec[i - start] / avg;*/ - normSpec_e = add( normSpec_e, sub( rootSpec_e[sub( i, start )], avg_e ) ); + Word16 normSpec_e; /*stores resultant exponent for normSpec*/ + Word16 normSpec = BASOP_Util_Divide3232_Scale( rootSpec[i - start], avg, &normSpec_e ); /*rootSpec[i - start] / avg;*/ + normSpec_e = add( normSpec_e, sub( rootSpec_e[i - start], avg_e ) ); IF( GT_32( normSpec, L_add( L_shl( 1, sub( 15, normSpec_e ) ), L_shl( adap, sub( e_adap, normSpec_e ) ) ) ) ) { - tonal = BASOP_Util_Add_Mant32Exp( tonal, tonal_e, rootSpec[sub( i, start )], rootSpec_e[sub( i, start )], &tonal_e ); /*tonal += rootSpec[i - start];*/ + tonal = BASOP_Util_Add_Mant32Exp( tonal, tonal_e, rootSpec[i - start], rootSpec_e[i - start], &tonal_e ); /*tonal += rootSpec[i - start];*/ } ELSE IF( LT_32( normSpec, L_shl( 1, sub( 15, normSpec_e ) ) ) ) { - noise = BASOP_Util_Add_Mant32Exp( noise, noise_e, rootSpec[sub( i, start )], rootSpec_e[sub( i, start )], &noise_e ); /*noise += rootSpec[i - start];*/ + noise = BASOP_Util_Add_Mant32Exp( noise, noise_e, rootSpec[i - start], rootSpec_e[i - start], &noise_e ); /*noise += rootSpec[i - start];*/ } } @@ -320,7 +316,6 @@ static Word32 IGF_getTNR_fx( IF( noise == 0 ) // To handle condition if denom = 0 { tonalToNoise = imult3216( L_shr( L_add( L_shl( 18 /* log10f(1e-018f) */, Q25 ), Mpy_32_16_1( L_add( BASOP_Util_Log2( tonal ), L_shl( tonal_e, Q25 ) ) /*Q25*/, INV_Log2_10_Q15 ) /*25+15-15*/ ), 3 ) /*Q22*/, 20 ); - move32(); } ELSE { @@ -340,6 +335,94 @@ static Word32 IGF_getTNR_fx( return tonalToNoise; } +static Word32 IGF_getTNR_ivas_fx( + const Word32 *powerSpectrum, /* i : energies */ + const Word16 start, /* i : start subband index */ + const Word16 stop, /* i : stop subband index */ + const Word16 adap, /* i : SFB width adaptation */ + Word16 *e_ps, /*Stores exponent for powerSpectrum*/ + Word16 e_adap /*Stores exponent for adap*/ +) +{ + Word16 i; + Word16 width; + Word32 avg; + Word32 tonal; + Word16 tonal_e; /* holds exp for tonal*/ + Word32 noise; + Word16 noise_e; /* holds exp for noise*/ + Word32 tonalToNoise; + Word32 rootSpec[300]; + Word16 rootSpec_e[300]; /*rootSpec_e[i] holds exp for rootSpec[i]*/ + Word16 avg_e; /* holds exp for avg*/ + Word16 tmp_e; + avg = 0; + tonal = 0; + noise = EPSILON_FX; + tonal_e = 0; + noise_e = 0; + avg_e = 0; + tmp_e = 0; + move32(); + move32(); + move32(); + move16(); + move16(); + move16(); + move16(); + + set32_fx( rootSpec, 0, 300 ); + set16_fx( rootSpec_e, 0, 300 ); + + width = sub( stop, start ); + FOR( i = start; i < stop; i++ ) + { + rootSpec_e[( i - start )] = e_ps[i]; + move16(); + rootSpec[( i - start )] = Sqrt32( powerSpectrum[i], &rootSpec_e[( i - start )] ); /*rootSpec[i - start] = sqrtf( powerSpectrum[i] );*/ + move32(); + avg = BASOP_Util_Add_Mant32Exp( avg, avg_e, rootSpec[( i - start )], rootSpec_e[( i - start )], &avg_e ); /*avg += rootSpec[i - start];resultant exponent is avg_e*/ + } + avg = BASOP_Util_Divide3216_Scale( avg, width, &tmp_e ); /*avg /= width;*/ + avg_e = add( 16, sub( add( avg_e, tmp_e ), 15 ) ); + + FOR( i = start; i < stop; i++ ) + { + Word16 normSpec_e; /*stores resultant exponent for normSpec*/ + Word16 normSpec = BASOP_Util_Divide3232_Scale( rootSpec[i - start], avg, &normSpec_e ); /*rootSpec[i - start] / avg;*/ + normSpec_e = add( normSpec_e, sub( rootSpec_e[i - start], avg_e ) ); + IF( GT_32( normSpec, L_add_sat( L_shl_sat( 1, sub( 15, normSpec_e ) ), L_shl_sat( adap, sub( e_adap, normSpec_e ) ) ) ) ) + { + tonal = BASOP_Util_Add_Mant32Exp( tonal, tonal_e, rootSpec[( i - start )], rootSpec_e[( i - start )], &tonal_e ); /*tonal += rootSpec[i - start];*/ + } + ELSE IF( LT_32( normSpec, L_shl_sat( 1, sub( 15, normSpec_e ) ) ) ) + { + noise = BASOP_Util_Add_Mant32Exp( noise, noise_e, rootSpec[( i - start )], rootSpec_e[( i - start )], &noise_e ); /*noise += rootSpec[i - start];*/ + } + } + + /*tonalToNoise = 20.f * log10f( max( 1e-018f, tonal / noise ) )*/ + IF( noise == 0 ) // To handle condition if denom = 0 + { + tonalToNoise = imult3216( L_shr( L_add( L_shl( 18 /* log10f(1e-018f) */, Q25 ), Mpy_32_16_1( L_add( BASOP_Util_Log2( tonal ), L_shl( tonal_e, Q25 ) ) /*Q25*/, INV_Log2_10_Q15 ) /*25+15-15*/ ), 3 ) /*Q22*/, 20 ); + } + ELSE + { + Word16 temp = BASOP_Util_Divide3232_Scale( tonal, noise, &tmp_e ); /*tonal / noise*/ + tmp_e = add( tmp_e, sub( tonal_e, noise_e ) ); + IF( GE_16( temp, 1 ) ) + { + tonalToNoise = imult3216( Mult_32_16( L_add( BASOP_Util_Log2( temp ), L_shl( add( 16, tmp_e ), Q25 ) ) /*Q25*/, INV_Log2_10_Q12 ) /*25+12-15*/, 20 ); /*Q22*/ + } + ELSE + { + tonalToNoise = -1509949440; /*-360.f Q22*/ + move32(); + } + } + + return tonalToNoise; +} /*-------------------------------------------------------------------* * IGF_CalculateEnvelope() @@ -352,7 +435,7 @@ static void IGF_CalculateEnvelope_ivas_fx( Word32 *pMDCTSpectrum_fx, /* i : MDCT spectrum */ Word16 e_mdct, /* i : exp of MDCT spectrum */ Word32 *pPowerSpectrum_fx, /* i : MDCT^2 + MDST^2 spectrum, or estimate */ - Word16 e_ps, /* i : exp of power spectrum */ + Word16 *e_ps, /* i : exp of power spectrum */ const Word16 igfGridIdx, /* i : IGF grid index */ const Word16 isTransient, /* i : flag indicating if transient is detected */ const Word16 last_core_acelp, /* i : indicator if last frame was ACELP core */ @@ -396,7 +479,7 @@ static void IGF_CalculateEnvelope_ivas_fx( Word16 tmp_e; hPrivateData = &hIGFEnc->igfData; - hGrid = &hPrivateData->igfInfo.grid[(int16_t) igfGridIdx]; + hGrid = &hPrivateData->igfInfo.grid[(Word16) igfGridIdx]; swb_offset = hGrid->swb_offset; IF( element_mode > EVS_MONO ) @@ -438,7 +521,7 @@ static void IGF_CalculateEnvelope_ivas_fx( { IF( LT_32( 1, pPowerSpectrum_fx[sb] ) ) { - hPrivateData->logSpec[sb] = s_max( 0, (Word16) L_shr( L_add( BASOP_Util_Log2( pPowerSpectrum_fx[sb] ), L_shl( e_ps, Q25 ) ), Q25 ) ); + hPrivateData->logSpec[sb] = s_max( 0, (Word16) L_shr( L_add( BASOP_Util_Log2( pPowerSpectrum_fx[sb] ), L_shl( e_ps[sb], Q25 ) ), Q25 ) ); move16(); } ELSE @@ -469,7 +552,6 @@ static void IGF_CalculateEnvelope_ivas_fx( move16(); move16(); move16(); - move16(); IF( pPowerSpectrum_fx != NULL ) { @@ -477,20 +559,22 @@ static void IGF_CalculateEnvelope_ivas_fx( move16(); FOR( sb = swb_offset[sfb]; sb < swb_offset[sfb + 1]; sb++ ) { - sfbEnergyC = BASOP_Util_Add_Mant32Exp( sfbEnergyC, sfbEnergyC_e, pPowerSpectrum_fx[sb], e_ps, &sfbEnergyC_e ); + Word16 shift = norm_l( pPowerSpectrum_fx[sb] ); + sfbEnergyC = BASOP_Util_Add_Mant32Exp( sfbEnergyC, sfbEnergyC_e, L_shl( pPowerSpectrum_fx[sb], shift ), sub( e_ps[sb], shift ), &sfbEnergyC_e ); // sfbEnergyTileR = BASOP_Util_Add_Mant32Exp( sfbEnergyTileR, sfbEnergyTileR_e, Mult_32_32( pMDCTSpectrum_fx[strt_cpy], pMDCTSpectrum_fx[strt_cpy] ), shl( e_mdct, 1 ), &sfbEnergyTileR_e ); Word64 tmp64 = W_mult_32_32( pMDCTSpectrum_fx[strt_cpy], pMDCTSpectrum_fx[strt_cpy] ); Word16 tmp64_e = W_norm( tmp64 ); tmp64 = W_shl( tmp64, tmp64_e ); sfbEnergyTileR = BASOP_Util_Add_Mant32Exp( sfbEnergyTileR, sfbEnergyTileR_e, W_extract_h( tmp64 ), shl( e_mdct, 1 ) - tmp64_e, &sfbEnergyTileR_e ); - sfbEnergyTileC = BASOP_Util_Add_Mant32Exp( sfbEnergyTileC, sfbEnergyTileC_e, pPowerSpectrum_fx[strt_cpy], e_ps, &sfbEnergyTileC_e ); + shift = norm_l( pPowerSpectrum_fx[strt_cpy] ); + sfbEnergyTileC = BASOP_Util_Add_Mant32Exp( sfbEnergyTileC, sfbEnergyTileC_e, L_shl( pPowerSpectrum_fx[strt_cpy], shift ), sub( e_ps[strt_cpy], shift ), &sfbEnergyTileC_e ); strt_cpy = add( strt_cpy, 1 ); } - sfbEnergyTileR = L_deposit_l( BASOP_Util_Divide3232_Scale( sfbEnergyTileR, width, &tmp_e ) ); - sfbEnergyTileR_e = add( sub( sfbEnergyTileR_e, Q15 ), tmp_e ); + sfbEnergyTileR = L_deposit_h( BASOP_Util_Divide3232_Scale( sfbEnergyTileR, width, &tmp_e ) ); + sfbEnergyTileR_e = add( sub( sfbEnergyTileR_e, Q31 ), tmp_e ); IF( sfbEnergyTileR == 0 ) { @@ -525,7 +609,6 @@ static void IGF_CalculateEnvelope_ivas_fx( gain = Mult_32_16( sfbEnergyTileR, temp ); // gain_e gain_e = add( tmp_e, sfbEnergyTileR_e ); - test(); IF( element_mode > EVS_MONO ) { test(); @@ -576,14 +659,17 @@ static void IGF_CalculateEnvelope_ivas_fx( Word16 tmp0, tmp2, tmp3, tmp4; Word16 tmp0_e, tmp2_e, tmp3_e, tmp4_e; tmp0 = shr( hPrivateData->prevSFM_FIR_SFB_TB_fx[sfb], 2 ); - tmp0_e = hPrivateData->prevSFB_FIR_TB_e[sfb] + 2; + tmp0_e = add( hPrivateData->prevSFB_FIR_TB_e[sfb], 2 ); + move16(); tmp2 = shr( hPrivateData->prevSFM_IIR_SFB_TB_fx[sfb], 2 ); - tmp2_e = hPrivateData->prevSFB_IIR_TB_e[sfb] + 2; + tmp2_e = add( hPrivateData->prevSFB_IIR_TB_e[sfb], 2 ); + move16(); tmp3 = shr( hPrivateData->prevSFM_FIR_SFB_SB_fx[sfb], 2 ); - tmp3_e = hPrivateData->prevSFB_FIR_SB_e[sfb] + 2; + tmp3_e = add( hPrivateData->prevSFB_FIR_SB_e[sfb], 2 ); + move16(); tmp4 = shr( hPrivateData->prevSFM_IIR_SFB_SB_fx[sfb], 2 ); - tmp4_e = hPrivateData->prevSFB_IIR_SB_e[sfb] + 2; - + tmp4_e = add( hPrivateData->prevSFB_IIR_SB_e[sfb], 2 ); + move16(); Word16 x1, x2; Word16 x1_e = BASOP_Util_Add_MantExp( tmp0, tmp0_e, tmp2, tmp2_e - 1, &x1 ); @@ -615,7 +701,7 @@ static void IGF_CalculateEnvelope_ivas_fx( BASOP_Util_Add_MantExp( hPrivateData->SFM_sb_fx[sfb], hPrivateData->sfb_sb_e[sfb], negate( hPrivateData->SFM_tb_fx[sfb] ), hPrivateData->sfb_tb_e[sfb], &diffSFM ); test(); - IF( diffSFM > 0 && LT_32( hPrivateData->SFM_tb_fx[sfb], L_shr( 3277 /*0.1 Q15*/, tmp_tb_e ) ) ) /* check whether target SFB is more tonal than source SFB */ + IF( diffSFM > 0 && LT_32( hPrivateData->SFM_tb_fx[sfb], L_shr( 3277 /*0.1 Q15*/, hPrivateData->sfb_tb_e[sfb] ) ) ) /* check whether target SFB is more tonal than source SFB */ { Word16 currDampingFactor, dampingFactor; Word16 slope, threshold; @@ -630,8 +716,13 @@ static void IGF_CalculateEnvelope_ivas_fx( Word32 mean_y_fx_tmp = 0; move32(); mean_xy_fx = mean_x2_fx = 0; +#ifdef FIX_ISSUE_1214 + mean_x_e = 15; + mean_xy_e = mean_y_e = mean_x2_e = 31; +#else mean_x_e = mean_y_e = 15; mean_xy_e = mean_x2_e = 31; +#endif move16(); move16(); move16(); @@ -642,21 +733,29 @@ static void IGF_CalculateEnvelope_ivas_fx( move16(); move16(); - test(); FOR( sb = swb_offset[sfb]; sb < swb_offset[sfb + 1]; sb++ ) { mean_x_fx = add( mean_x_fx, x ); /*Q0*/ mean_x2_fx = L_add( mean_x2_fx, L_mult0( x, x ) ); /*Q0*/ - test(); +#ifdef FIX_ISSUE_1214 + /*y = 20.f * log10f( max( 1.f, powerSpectrum[i] ) );*/ + IF( LE_64( W_deposit32_l( pPowerSpectrum_fx[sb] ), W_shl( 1, ( sub( 31, e_ps[sb] ) ) ) ) ) + { + y = 0; + move16(); + } +#else + /*y = 20 * (int16_t) log10f( max( 1e-018f, pPowerSpectrum[sb] ) );*/ IF( LT_32( pPowerSpectrum_fx[sb], 1 ) ) { y = imult1616( 20, ( -18 /* log10f(1e-018f) */ ) ); } +#endif ELSE { - y = imult1616( 20, extract_l( L_shr( Mult_32_16( ( L_add( BASOP_Util_Log2( pPowerSpectrum_fx[sb] ), L_shl( e_ps, Q25 ) ) ), INV_Log2_10_Q15 ), Q25 ) ) ); /*Q0*/ + y = imult1616( 20, extract_l( L_shr( Mult_32_16( ( L_add( BASOP_Util_Log2( pPowerSpectrum_fx[sb] ), L_shl( e_ps[sb], Q25 ) ) ), INV_Log2_10_Q15 ), Q25 ) ) ); /*Q0*/ } mean_y_fx_tmp = L_mac0( mean_y_fx_tmp, y, 1 ); /*Q0*/ mean_xy_fx = L_add( mean_xy_fx, L_mult0( y, x ) ); /*Q0*/ @@ -728,7 +827,7 @@ static void IGF_CalculateEnvelope_ivas_fx( tonalToNoise_e = 9; move16(); adap = BASOP_Util_Divide1616_Scale( width, 40, &adap_e ); - tonalToNoise = IGF_getTNR_fx( pPowerSpectrum_fx, swb_offset[sfb], swb_offset[sfb + 1], adap, e_ps, adap_e ); /*Q22*/ + tonalToNoise = IGF_getTNR_ivas_fx( pPowerSpectrum_fx, swb_offset[sfb], swb_offset[sfb + 1], adap, e_ps, adap_e ); /*Q22*/ IF( EQ_16( BASOP_Util_Cmp_Mant32Exp( tonalToNoise, tonalToNoise_e, L_add( L_shl( 10, sub( 15, adap_e ) ), adap ), add( 16, adap_e ) ), -1 ) ) { @@ -776,8 +875,7 @@ static void IGF_CalculateEnvelope_ivas_fx( move16(); hPrivateData->prevDampingFactor_IIR_e[sfb] = dampingFactor_e; move16(); - test(); - IF( hPrivateData->dampingFactorSmoothing[sfb] > 0 ) + if ( hPrivateData->dampingFactorSmoothing[sfb] > 0 ) { hPrivateData->dampingFactorSmoothing[sfb] = sub( hPrivateData->dampingFactorSmoothing[sfb], 1 ); move16(); @@ -840,11 +938,12 @@ static void IGF_CalculateEnvelope_ivas_fx( ELSE { tmp_e = e_mdct; + move16(); sfbEnergyR = add_sat( EPSILON_FX, BASOP_Util_Divide3216_Scale( sum2_32_fx( pMDCTSpectrum_fx + swb_offset[sfb], width, &tmp_e ) /*exp: tmp_e*/, width, &sfbEnergyR_e ) ); // sfbEnergyR_e sfbEnergyR_e = add( sfbEnergyR_e, add( tmp_e, -15 ) ); - gain = sfbEnergyR; // gain_e + gain = L_shl( sfbEnergyR, 16 ); // gain_e move32(); - gain_e = add( sfbEnergyR_e, 16 ); + gain_e = sfbEnergyR_e; IF( element_mode > EVS_MONO ) { @@ -968,7 +1067,7 @@ static void IGF_CalculateStereoEnvelope_fx( swb_offset = hGrid->swb_offset; move16(); - IF( NE_16( igfGridIdx, IGF_GRID_LB_NORM ) ) + IF( igfGridIdx != IGF_GRID_LB_NORM ) { FOR( sfbCnt = 0; sfbCnt < sub( hGrid->sfbWrap[hGrid->nTiles], hGrid->sfbWrap[0] ); sfbCnt++ ) { @@ -996,7 +1095,7 @@ static void IGF_CalculateStereoEnvelope_fx( { FOR( sb = hGrid->sbWrap[0]; sb < swb_offset[hGrid->sfbWrap[hGrid->nTiles]]; sb++ ) { - /*hPrivateData->logSpec[sb] = max( 0, (int16_t) ( logf( max( FLT_MIN, pPowerSpectrum[sb] ) ) * INV_LOG_2 ) );*/ + /*hPrivateData->logSpec[sb] = max( 0, (Word16) ( logf( max( FLT_MIN, pPowerSpectrum[sb] ) ) * INV_LOG_2 ) );*/ IF( LE_32( 1, pPowerSpectrum_fx[sb] ) ) { hPrivateData->logSpec[sb] = s_max( 0, (Word16) L_shr( L_add( BASOP_Util_Log2( pPowerSpectrum_fx[sb] ), L_shl( pPowerSpectrum_e, Q25 ) ), 25 ) ); @@ -1062,6 +1161,7 @@ static void IGF_CalculateStereoEnvelope_fx( tileSrcSpec_e = pPowerSpectrum_e; } move32(); + move16(); strt_cpy = add( strt_cpy, 1 ); } @@ -1133,10 +1233,10 @@ static void IGF_CalculateStereoEnvelope_fx( { hPrivateData->prevSFM_FIR_SFB_TB_fx[sfb] = shr( hPrivateData->prevSFM_FIR_SFB_TB_fx[sfb], diff_tb_e ); hPrivateData->prevSFM_IIR_SFB_TB_fx[sfb] = shr( hPrivateData->prevSFM_IIR_SFB_TB_fx[sfb], diff_tb_e ); - hPrivateData->prevSFB_FIR_TB_e[sfb] = tmp_tb_e; - hPrivateData->prevSFB_IIR_TB_e[sfb] = tmp_tb_e; move16(); move16(); + hPrivateData->prevSFB_FIR_TB_e[sfb] = tmp_tb_e; + hPrivateData->prevSFB_IIR_TB_e[sfb] = tmp_tb_e; move16(); move16(); } @@ -1150,35 +1250,42 @@ static void IGF_CalculateStereoEnvelope_fx( { hPrivateData->prevSFM_FIR_SFB_SB_fx[sfb] = shr( hPrivateData->prevSFM_FIR_SFB_SB_fx[sfb], diff_sb_e ); hPrivateData->prevSFM_IIR_SFB_SB_fx[sfb] = shr( hPrivateData->prevSFM_IIR_SFB_SB_fx[sfb], diff_sb_e ); - hPrivateData->prevSFB_FIR_SB_e[sfb] = tmp_sb_e; - hPrivateData->prevSFB_IIR_SB_e[sfb] = tmp_sb_e; move16(); move16(); + hPrivateData->prevSFB_FIR_SB_e[sfb] = tmp_sb_e; + hPrivateData->prevSFB_IIR_SB_e[sfb] = tmp_sb_e; move16(); move16(); } } - tmp_tb_fx = shl_sat( tmp_tb_fx, sub( 2, tmp_tb_e ) ); /* Since we're limiting max value to 2.7f we can saturate to Q13 */ - tmp_sb_fx = shl_sat( tmp_sb_fx, sub( 2, tmp_sb_e ) ); /* Since we're limiting max value to 2.7f we can saturate to Q13 */ - +#ifdef FIX_ISSUE_1214 + tmp_tb_fx = shr_sat( tmp_tb_fx, sub( 2, tmp_tb_e ) ); /* Since we're limiting max value to 2.7f we can saturate to Q13 */ + tmp_sb_fx = shr_sat( tmp_sb_fx, sub( 2, tmp_sb_e ) ); /* Since we're limiting max value to 2.7f we can saturate to Q13 */ + hPrivateData->SFM_tb_fx[sfb] = add_sat( tmp_tb_fx, add_sat( shr( hPrivateData->prevSFM_FIR_SFB_TB_fx[sfb], sub( 2, hPrivateData->prevSFB_FIR_TB_e[sfb] ) ), shr( hPrivateData->prevSFM_IIR_SFB_TB_fx[sfb], sub( 3, hPrivateData->prevSFB_IIR_TB_e[sfb] ) ) ) ); /* Since we're limiting max value to 2.7f we can saturate to Q13 */ + hPrivateData->SFM_tb_fx[sfb] = s_min( 22118 /*2.7f Q13*/, hPrivateData->SFM_tb_fx[sfb] ); /* resultant exponent stored in hPrivateData->sfb_sb_e[sfb]*/ + hPrivateData->SFM_sb_fx[sfb] = add_sat( tmp_sb_fx, add_sat( shr( hPrivateData->prevSFM_FIR_SFB_SB_fx[sfb], sub( 2, hPrivateData->prevSFB_FIR_SB_e[sfb] ) ), shr( hPrivateData->prevSFM_IIR_SFB_SB_fx[sfb], sub( 3, hPrivateData->prevSFB_IIR_SB_e[sfb] ) ) ) ); /* Since we're limiting max value to 2.7f we can saturate to Q13 */ + hPrivateData->SFM_sb_fx[sfb] = s_min( 22118 /*2.7f Q13*/, hPrivateData->SFM_sb_fx[sfb] ); /*resultant exponent stores in hPrivateData->sfb_tb_e[sfb]*/ +#else + tmp_tb_fx = shl_sat( tmp_tb_fx, sub( 2, tmp_tb_e ) ); /* Since we're limiting max value to 2.7f we can saturate to Q13 */ + tmp_sb_fx = shl_sat( tmp_sb_fx, sub( 2, tmp_sb_e ) ); /* Since we're limiting max value to 2.7f we can saturate to Q13 */ hPrivateData->SFM_tb_fx[sfb] = add_sat( tmp_tb_fx, add_sat( shr( hPrivateData->prevSFM_FIR_SFB_TB_fx[sfb], sub( 2, tmp_tb_e ) ), shr( hPrivateData->prevSFM_IIR_SFB_TB_fx[sfb], sub( 3, tmp_tb_e ) ) ) ); /* Since we're limiting max value to 2.7f we can saturate to Q13 */ hPrivateData->SFM_tb_fx[sfb] = s_min( 22118 /*2.7f Q13*/, hPrivateData->SFM_tb_fx[sfb] ); /* resultant exponent stored in hPrivateData->sfb_sb_e[sfb]*/ hPrivateData->SFM_sb_fx[sfb] = add_sat( tmp_sb_fx, add_sat( shr( hPrivateData->prevSFM_FIR_SFB_SB_fx[sfb], sub( 2, tmp_sb_e ) ), shr( hPrivateData->prevSFM_IIR_SFB_SB_fx[sfb], sub( 3, tmp_sb_e ) ) ) ); /* Since we're limiting max value to 2.7f we can saturate to Q13 */ hPrivateData->SFM_sb_fx[sfb] = s_min( 22118 /*2.7f Q13*/, hPrivateData->SFM_sb_fx[sfb] ); /*resultant exponent stores in hPrivateData->sfb_tb_e[sfb]*/ - hPrivateData->sfb_sb_e[sfb] = 2; - hPrivateData->sfb_tb_e[sfb] = 2; - move16(); - move16(); +#endif move16(); move16(); move16(); move16(); + hPrivateData->sfb_sb_e[sfb] = 2; + hPrivateData->sfb_tb_e[sfb] = 2; move16(); move16(); - BASOP_Util_Add_MantExp( hPrivateData->SFM_sb_fx[sfb], tmp_sb_e, negate( hPrivateData->SFM_tb_fx[sfb] ), tmp_tb_e, &diffSFM_fx ); /*stores the resultant exponent for diffSFM_fx*/ + diffSFM_fx = sub( hPrivateData->SFM_sb_fx[sfb], hPrivateData->SFM_tb_fx[sfb] ); /*Q13*/ - IF( diffSFM_fx > 0 && LT_32( hPrivateData->SFM_tb_fx[sfb], L_shr( 3277 /*0.1 Q15*/, tmp_tb_e ) ) ) /* check whether target SFB is more tonal than source SFB */ + test(); + IF( diffSFM_fx > 0 && LT_16( hPrivateData->SFM_tb_fx[sfb], 819 /*0.1 Q13*/ ) ) /* check whether target SFB is more tonal than source SFB */ { Word16 currDampingFactor_fx, dampingFactor_fx, alpha_fx; Word16 threshold_e, threshold_fx, alpha_e, currDampingFactor_e, dampingFactor_e; @@ -1202,10 +1309,11 @@ static void IGF_CalculateStereoEnvelope_fx( mean_x_fx = add( mean_x_fx, x ); /*Q0*/ mean_x2_fx = L_add( mean_x2_fx, L_mult0( x, x ) ); /*Q0*/ - /*y = 20 * (int16_t) log10f( max( 1e-018f, pPowerSpectrum[sb] ) );*/ + /*y = 20 * (Word16) log10f( max( 1e-018f, pPowerSpectrum[sb] ) );*/ IF( LT_32( pPowerSpectrum_fx[sb], 1 ) ) { y = 20 * ( -18 ); + move16(); } ELSE { @@ -1232,7 +1340,7 @@ static void IGF_CalculateStereoEnvelope_fx( /* determine whether strong tilt is due to a step in the spectrum (e.g. band limitation, no damping) or a tonal component close the band border (apply damping) by calculating SFM for a shift of 1/2 SFB width*/ threshold_fx = BASOP_Util_Divide1616_Scale( 60, width, &threshold_e ); /*stores resultant exponent for threshold_fx*/ - + test(); IF( EQ_16( BASOP_Util_Cmp_Mant32Exp( slope_fx, add( slope_e, 16 ), negate( threshold_fx ), add( threshold_e, 16 ) ), -1 ) ) { Word16 shift = shr( width, 1 ); @@ -1250,7 +1358,10 @@ static void IGF_CalculateStereoEnvelope_fx( crest = IGF_getCrest( &crest_exp, pPowerSpectrum_fx, pPowerSpectrum_e, add( swb_offset[sfb], shift ), add( swb_offset[sfb + 1], shift ) ); shiftedSFM_fx = BASOP_Util_Divide1616_Scale( sfm, crest, &shiftedSFM_e ); } - shiftedSFM_e = add( shiftedSFM_e, sub( sfm_exp, crest_exp ) ); /* stores resultant exponent for shiftedSFM_fx*/ + IF( shiftedSFM_fx ) + { + shiftedSFM_e = add( shiftedSFM_e, sub( sfm_exp, crest_exp ) ); /* stores resultant exponent for shiftedSFM_fx*/ + } // alpha = min( 320.f / (float) swb_offset[sfb + 1], 1.25f ); temp = BASOP_Util_Divide1616_Scale( 320, swb_offset[sfb + 1], &alpha_e ); @@ -1268,7 +1379,8 @@ static void IGF_CalculateStereoEnvelope_fx( move16(); move16(); } - + test(); + test(); IF( last_core_acelp || hPrivateData->wasTransient || EQ_32( hPrivateData->prevDampingFactor_IIR_fx[sfb], L_shl( -1, sub( 15, hPrivateData->prevDampingFactor_IIR_e[sfb] ) ) ) ) { tmp = BASOP_Util_Cmp_Mant32Exp( currDampingFactor_fx, currDampingFactor_e, 3277, 0 ); @@ -1300,7 +1412,7 @@ static void IGF_CalculateStereoEnvelope_fx( { // currDampingFactor += 0.1f * ( ( 10 + adap ) - tonalToNoise ); Word32 temp2 = BASOP_Util_Add_Mant32Exp( L_add( L_shl( 10, sub( 15, adap_e ) ) /*exp:adap_e*/, adap ), add( adap_e, 16 ), L_negate( tonalToNoise ), tonalToNoise_e, &tmp_e ); /* resultant exp is tmp_e*/ - currDampingFactor_e = BASOP_Util_Add_MantExp( currDampingFactor_fx, currDampingFactor_e, extract_l( Mult_32_32( 3277 /*0.1f Q15*/, temp2 ) ), tmp_e, &currDampingFactor_fx ); /*stores resultant exp for currDampingFactor_fx*/ + currDampingFactor_e = BASOP_Util_Add_MantExp( currDampingFactor_fx, currDampingFactor_e, extract_l( Mult_32_16( temp2, 3277 /*0.1f Q15*/ ) ), tmp_e, &currDampingFactor_fx ); /*stores resultant exp for currDampingFactor_fx*/ } } @@ -1412,11 +1524,15 @@ static void IGF_CalculateStereoEnvelope_fx( } /*gain=0.5f+log2f(gain)*2+16 becuase 2.885390081777927f=2*1/loge(2) so 2*1/loge(2)*loge(x) can be written as 2*log2(x)*/ gain_fx = L_add( ONE_IN_Q22, L_add( L_add( L_shr( BASOP_Util_Log2( gain_fx ), 1 ), L_shl( gain_e, Q24 ) ), L_shl( 16, Q23 ) ) ); /*Q23*/ - IF( !isTransient && ( EQ_16( hPrivateData->igfInfo.bitRateIndex, IGF_BITRATE_SWB_48000_CPE ) || EQ_16( hPrivateData->igfInfo.bitRateIndex, IGF_BITRATE_FB_48000_CPE ) ) ) + test(); + test(); + if ( !isTransient && ( EQ_16( hPrivateData->igfInfo.bitRateIndex, IGF_BITRATE_SWB_48000_CPE ) || EQ_16( hPrivateData->igfInfo.bitRateIndex, IGF_BITRATE_FB_48000_CPE ) ) ) { gain_fx = L_add( gain_fx, ONE_IN_Q21 ); /* better preservation of original HF band energy */ } - IF( !isTransient && ( EQ_16( hPrivateData->igfInfo.bitRateIndex, IGF_BITRATE_SWB_64000_CPE ) || EQ_16( hPrivateData->igfInfo.bitRateIndex, IGF_BITRATE_FB_64000_CPE ) ) ) + test(); + test(); + if ( !isTransient && ( EQ_16( hPrivateData->igfInfo.bitRateIndex, IGF_BITRATE_SWB_64000_CPE ) || EQ_16( hPrivateData->igfInfo.bitRateIndex, IGF_BITRATE_FB_64000_CPE ) ) ) { gain_fx = L_add( gain_fx, ONE_IN_Q20 ); } @@ -1475,33 +1591,33 @@ static Word16 IGF_WriteEnvelope( IF( *igfAllZero != 0 ) { - IGF_write_bit( hBstr, pBitOffset, 1 ); + IGF_write_bit_fx( hBstr, pBitOffset, 1 ); - IF( NULL == hBstr ) + if ( NULL == hBstr ) { IGFSCFEncoderSaveContextState_fx( &hPrivateData->hIGFSCFArithEnc, igfGridIdx ); } IGFSCFEncoderReset_fx( &hPrivateData->hIGFSCFArithEnc ); - IF( NULL == hBstr ) + if ( NULL == hBstr ) { IGFSCFEncoderRestoreContextState_fx( &hPrivateData->hIGFSCFArithEnc, igfGridIdx ); } } ELSE { - IGF_write_bit( hBstr, pBitOffset, 0 ); + IGF_write_bit_fx( hBstr, pBitOffset, 0 ); - IF( NULL == hBstr ) + if ( NULL == hBstr ) { IGFSCFEncoderSaveContextState_fx( &hPrivateData->hIGFSCFArithEnc, igfGridIdx ); } - *pBitOffset = IGFSCFEncoderEncode( &hPrivateData->hIGFSCFArithEnc, hBstr, *pBitOffset, &hPrivateData->igfScfQuantized[hGrid->startSfb], igfGridIdx, isIndepFlag ); + *pBitOffset = IGFSCFEncoderEncode_ivas_fx( &hPrivateData->hIGFSCFArithEnc, hBstr, *pBitOffset, &hPrivateData->igfScfQuantized[hGrid->startSfb], igfGridIdx, isIndepFlag ); move16(); - IF( NULL == hBstr ) + if ( NULL == hBstr ) { IGFSCFEncoderRestoreContextState_fx( &hPrivateData->hIGFSCFArithEnc, igfGridIdx ); } @@ -1590,14 +1706,14 @@ static void IGF_Whitening_ivas_fx( IF( LT_32( powerSpectrum[sb], 1 ) ) hPrivateData->logSpec[sb] = 0; /* max(0,FLT_MIN_EXP )*/ ELSE - hPrivateData->logSpec[sb] = extract_l( L_max( 0, L_shr( L_add( BASOP_Util_Log2( powerSpectrum[sb] ), L_shl( *powerSpectrum_e, Q25 ) ), Q25 ) ) ); + hPrivateData->logSpec[sb] = extract_l( L_max( 0, L_shr( L_add( BASOP_Util_Log2( powerSpectrum[sb] ), L_shl( powerSpectrum_e[sb], Q25 ) ), Q25 ) ) ); move16(); } } /* if current tile contains only a single SFB, reuse already computed SFM values */ test(); - IF( GT_16( element_mode, EVS_MONO ) && EQ_16( sub( hGrid->sfbWrap[p + 1], hGrid->sfbWrap[p] ), 1 ) ) + IF( element_mode > EVS_MONO && EQ_16( sub( hGrid->sfbWrap[p + 1], hGrid->sfbWrap[p] ), 1 ) ) { tmp = hPrivateData->SFM_tb_fx[p]; tmp_e = hPrivateData->sfb_tb_e[p]; @@ -1606,7 +1722,7 @@ static void IGF_Whitening_ivas_fx( } ELSE { - tmp = BASOP_Util_Divide1616_Scale( IGF_getSFM_new_fx( powerSpectrum, hPrivateData->logSpec, hGrid->tile[p], hGrid->tile[p + 1], *powerSpectrum_e ), IGF_getCrest_new_fx( hPrivateData->logSpec, hGrid->tile[p], hGrid->tile[p + 1], &crest_e ), &tmp_e ); + tmp = BASOP_Util_Divide1616_Scale( IGF_getSFM_new_fx( powerSpectrum, hPrivateData->logSpec, hGrid->tile[p], hGrid->tile[p + 1], powerSpectrum_e ), IGF_getCrest_new_fx( hPrivateData->logSpec, hGrid->tile[p], hGrid->tile[p + 1], &crest_e ), &tmp_e ); tmp_e = sub( tmp_e, crest_e ); } @@ -1730,7 +1846,7 @@ static void IGF_Whitening_ivas_fx( ELSE { test(); - IF( GT_16( element_mode, EVS_MONO ) && EQ_16( sub( hGrid->sfbWrap[p + 1], hGrid->sfbWrap[p] ), 1 ) ) + IF( element_mode > EVS_MONO && EQ_16( sub( hGrid->sfbWrap[p + 1], hGrid->sfbWrap[p] ), 1 ) ) { SFM = shl( tmp, sub( tmp_e, 2 ) ); /*2Q13*/ } @@ -1762,7 +1878,7 @@ static void IGF_Whitening_ivas_fx( } } - IF( GT_16( element_mode, EVS_MONO ) ) + IF( element_mode > EVS_MONO ) { IF( last_core_acelp ) /* reset */ { @@ -1869,7 +1985,7 @@ static void IGF_Whitening_ivas_fx( } } - IF( GT_16( element_mode, EVS_MONO ) ) + IF( element_mode > EVS_MONO ) { IF( EQ_16( SFM, -ONE_IN_Q13 /*1.0f 2Q13*/ ) ) /* reset */ { @@ -1916,7 +2032,10 @@ static void IGF_Whitening_ivas_fx( break; } } - + test(); + test(); + test(); + test(); /* if tonality oscillates between two tiles, turn whitening off in both */ IF( ( ( pastSfmDiffSum_a > 0 && pastSfmDiffSum_b < 0 ) || ( pastSfmDiffSum_a < 0 && pastSfmDiffSum_b > 0 ) ) && @@ -1965,16 +2084,16 @@ static void IGF_Whitening_ivas_fx( /*-------------------------------------------------------------------* - * IGF_WriteWhiteningTile() + * IGF_WriteWhiteningTile_fx() * * write whitening levels into bitstream *-------------------------------------------------------------------*/ /*! r: number of bits written */ -static Word16 IGF_WriteWhiteningTile( /**< out: Q0 | number of bits written */ - BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ - Word16 *pBitOffset, /**< in: | ptr to bitOffset counter */ - Word16 whiteningLevel /**< in: Q0 | whitening levels to write */ +static Word16 IGF_WriteWhiteningTile_fx( /**< out: Q0 | number of bits written */ + BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ + Word16 *pBitOffset, /**< in: | ptr to bitOffset counter */ + Word16 whiteningLevel /**< in: Q0 | whitening levels to write */ ) { Word16 totBitCount; @@ -2008,17 +2127,17 @@ static Word16 IGF_WriteWhiteningTile( /**< out: Q0 | numb /*-------------------------------------------------------------------* - * IGF_WriteWhiteningLevels() + * IGF_WriteWhiteningLevels_fx() * * writes the whitening levels *-------------------------------------------------------------------*/ -static Word16 IGF_WriteWhiteningLevels( /**< out: Q0 | total number of bits written */ - const IGF_ENC_INSTANCE_HANDLE hInstance, /**< in: | instance handle of IGF encoder */ - BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ - Word16 *pBitOffset, /**< in: | ptr to bitOffset counter */ - const Word16 igfGridIdx, /**< in: Q0 | igf grid index see declaration of IGF_GRID_IDX for details */ - const Word16 isIndepFlag /**< in: Q0 | if 1 frame is independent, 0 = frame is coded with data from previous frame */ +static Word16 IGF_WriteWhiteningLevels_fx( /**< out: Q0 | total number of bits written */ + const IGF_ENC_INSTANCE_HANDLE hInstance, /**< in: | instance handle of IGF encoder */ + BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ + Word16 *pBitOffset, /**< in: | ptr to bitOffset counter */ + const Word16 igfGridIdx, /**< in: Q0 | igf grid index see declaration of IGF_GRID_IDX for details */ + const Word16 isIndepFlag /**< in: Q0 | if 1 frame is independent, 0 = frame is coded with data from previous frame */ ) { IGF_ENC_PRIVATE_DATA_HANDLE hPrivateData; @@ -2052,7 +2171,7 @@ static Word16 IGF_WriteWhiteningLevels( move16(); tmp32 = 0; move32(); - + test(); WHILE( ( LT_16( p, nTiles ) ) && ( tmp32 == 0 ) ) { test(); @@ -2075,11 +2194,12 @@ static Word16 IGF_WriteWhiteningLevels( { IGF_write_bits( hBstr, pBitOffset, 0, 1 ); } - IGF_WriteWhiteningTile( hBstr, pBitOffset, hPrivateData->igfCurrWhiteningLevel[0] ); + IGF_WriteWhiteningTile_fx( hBstr, pBitOffset, hPrivateData->igfCurrWhiteningLevel[0] ); p = 1; move16(); tmp32 = 0; move32(); + test(); IF( EQ_16( hPrivateData->igfInfo.bitRateIndex, IGF_BITRATE_SWB_48000_CPE ) || EQ_16( hPrivateData->igfInfo.bitRateIndex, IGF_BITRATE_FB_48000_CPE ) ) { isSame = 1; @@ -2092,7 +2212,7 @@ static Word16 IGF_WriteWhiteningLevels( isSame = 1; move16(); } - + test(); WHILE( ( LT_16( p, nTiles ) ) && ( tmp32 == 0 ) ) { test(); @@ -2111,7 +2231,7 @@ static Word16 IGF_WriteWhiteningLevels( IGF_write_bits( hBstr, pBitOffset, 1, 1 ); FOR( p = 1; p < nTiles; p++ ) { - IGF_WriteWhiteningTile( hBstr, pBitOffset, hPrivateData->igfCurrWhiteningLevel[p] ); + IGF_WriteWhiteningTile_fx( hBstr, pBitOffset, hPrivateData->igfCurrWhiteningLevel[p] ); } } ELSE IF( NE_16( hPrivateData->igfInfo.bitRateIndex, IGF_BITRATE_SWB_48000_CPE ) && NE_16( hPrivateData->igfInfo.bitRateIndex, IGF_BITRATE_FB_48000_CPE ) ) @@ -2127,16 +2247,16 @@ static Word16 IGF_WriteWhiteningLevels( /*-------------------------------------------------------------------* - * IGF_WriteFlatteningTrigger() + * IGF_WriteFlatteningTrigger_fx() * * write flattening trigger *-------------------------------------------------------------------*/ /*! r: number of bits written */ -static Word16 IGF_WriteFlatteningTrigger( /**< out: | number of bits written */ - const IGF_ENC_INSTANCE_HANDLE hInstance, /**< in: | instance handle of IGF Encoder */ - BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ - Word16 *pBitOffset /**< in: | ptr to bitOffset counter */ +static Word16 IGF_WriteFlatteningTrigger_fx( /**< out: | number of bits written */ + const IGF_ENC_INSTANCE_HANDLE hInstance, /**< in: | instance handle of IGF Encoder */ + BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ + Word16 *pBitOffset /**< in: | ptr to bitOffset counter */ ) { Word16 flatteningTrigger; @@ -2199,15 +2319,15 @@ Word16 IGFEncWriteBitstream_ivas_fx( isIndepFlag, /* i: if 1 frame is independent, 0 = frame is coded with data from previous frame */ &igfAllZero ); /* o: *igfAllZero */ - IGF_WriteWhiteningLevels( hIGFEnc, /* i: instance handle of IGF Encoder */ - hBstr, /* i: encoder state */ - pBitOffset, /* i: ptr to bitOffset counter */ - igfGridIdx, /* i: igf grid index see definition of IGF_GRID_IDX for details */ - isIndepFlag ); /* i: if 1 frame is independent, 0 = frame is coded with data from previous frame */ + IGF_WriteWhiteningLevels_fx( hIGFEnc, /* i: instance handle of IGF Encoder */ + hBstr, /* i: encoder state */ + pBitOffset, /* i: ptr to bitOffset counter */ + igfGridIdx, /* i: igf grid index see definition of IGF_GRID_IDX for details */ + isIndepFlag ); /* i: if 1 frame is independent, 0 = frame is coded with data from previous frame */ - IGF_WriteFlatteningTrigger( hIGFEnc, /* i: instance handle of IGF Encoder */ - hBstr, /* i: encoder state */ - pBitOffset ); /* i: ptr to bitOffset counter */ + IGF_WriteFlatteningTrigger_fx( hIGFEnc, /* i: instance handle of IGF Encoder */ + hBstr, /* i: encoder state */ + pBitOffset ); /* i: ptr to bitOffset counter */ hIGFEnc->infoTotalBitsPerFrameWritten = sub( *pBitOffset, startBitCount ); hIGFEnc->infoTotalBitsWritten = add( hIGFEnc->infoTotalBitsWritten, hIGFEnc->infoTotalBitsPerFrameWritten ); @@ -2216,34 +2336,6 @@ Word16 IGFEncWriteBitstream_ivas_fx( return hIGFEnc->infoTotalBitsPerFrameWritten; } -int16_t IGFEncWriteBitstream( - const IGF_ENC_INSTANCE_HANDLE hIGFEnc, /* i : instance handle of IGF Encoder */ - BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ - int16_t *pBitOffset, /* i : ptr to bitOffset counter */ - const int16_t igfGridIdx, /* i : igf grid index see declaration of IGF_GRID_IDX for details */ - const int16_t isIndepFlag /* i : if 1 frame is independent, 0 = frame is coded with data from previous frame */ -) -{ - int16_t igfAllZero; - int16_t startBitCount = *pBitOffset; - - hIGFEnc->infoTotalBitsPerFrameWritten = 0; - if ( isIndepFlag ) - { - hIGFEnc->infoTotalBitsWritten = 0; - } - - IGF_WriteEnvelope( hIGFEnc, hBstr, pBitOffset, igfGridIdx, isIndepFlag, &igfAllZero ); - - IGF_WriteWhiteningLevels( hIGFEnc, hBstr, pBitOffset, igfGridIdx, isIndepFlag ); - - IGF_WriteFlatteningTrigger( hIGFEnc, hBstr, pBitOffset ); - - hIGFEnc->infoTotalBitsPerFrameWritten = ( *pBitOffset - startBitCount ); - hIGFEnc->infoTotalBitsWritten += hIGFEnc->infoTotalBitsPerFrameWritten; - - return hIGFEnc->infoTotalBitsPerFrameWritten; -} /*-------------------------------------------------------------------* @@ -2421,12 +2513,12 @@ return; /*-------------------------------------------------------------------* - * IGFEncResetTCX10BitCounter() + * IGFEncResetTCX10BitCounter_ivas_fx() * * IGF reset bitstream bit counter for TCX10 modes *-------------------------------------------------------------------*/ -void IGFEncResetTCX10BitCounter( +void IGFEncResetTCX10BitCounter_ivas_fx( const IGF_ENC_INSTANCE_HANDLE hIGFEnc /* i : instance handle of IGF Encoder */ ) { @@ -2435,46 +2527,12 @@ void IGFEncResetTCX10BitCounter( hPrivateData = &hIGFEnc->igfData; hPrivateData->igfBitstreamBits = 0; hIGFEnc->infoTotalBitsWritten = 0; - + move16(); + move16(); return; } -/*-------------------------------------------------------------------* - * IGFEncWriteConcatenatedBitstream() - * - * - *-------------------------------------------------------------------*/ - -/*! r: total number of bits written */ -int16_t IGFEncWriteConcatenatedBitstream( - const IGF_ENC_INSTANCE_HANDLE hIGFEnc, /* i : instance handle of IGF Encoder */ - BSTR_ENC_HANDLE hBstr /* i/o: encoder bitstream handle */ -) -{ - IGF_ENC_PRIVATE_DATA_HANDLE hPrivateData; - int16_t i; - int16_t bitsLeft; - UWord8 *pBitstream; - - hPrivateData = &hIGFEnc->igfData; - pBitstream = hPrivateData->igfBitstream; - - for ( i = 0; i < ( hPrivateData->igfBitstreamBits >> 3 ); i++ ) - { - push_next_indice( hBstr, pBitstream[i], 8 ); - } - - bitsLeft = hPrivateData->igfBitstreamBits & 0x7; - if ( bitsLeft > 0 ) - { - push_next_indice( hBstr, pBitstream[i] >> ( 8 - bitsLeft ), bitsLeft ); - } - - return hIGFEnc->infoTotalBitsWritten; -} - - /*-------------------------------------------------------------------* * IGFEncApplyMono() * @@ -2482,12 +2540,15 @@ int16_t IGFEncWriteConcatenatedBitstream( *-------------------------------------------------------------------*/ void IGFEncApplyMono_ivas_fx( - Encoder_State *st, /* i : Encoder state */ + Encoder_State *st, /* i : Encoder state */ +#ifdef MSAN_FIX + Word16 powerSpectrum_len, /* i: length of pPowerSpectrum_fx buffer */ +#endif const Word16 igfGridIdx, /* i : IGF grid index */ Word32 *pMDCTSpectrum_fx, /* i/o: MDCT spectrum */ Word16 e_mdct, /* i : exponent of pMDCTspectrum */ Word32 *pPowerSpectrum_fx, /* i/o: MDCT^2 + MDST^2 spectrum, or estimate */ - Word16 e_ps, /* i : exponent of pPowerSpectrum */ + Word16 *e_ps, /* i : exponent of pPowerSpectrum */ const Word16 isTCX20, /* i : flag indicating if the input is TCX20 or TCX10/2xTCX5 */ const Word8 isTNSActive, /* i : flag indicating if the TNS is active */ const Word16 sp_aud_decision0, /* i : first stage switching decision */ @@ -2495,12 +2556,19 @@ void IGFEncApplyMono_ivas_fx( ) { Word32 *pPowerSpectrumParameter_fx; + Word16 *pPowerSpectrumParameter_exp; Word16 att_fx = MAX16B; Word16 last_core_acelp; - Word16 highPassEner_exp; move16(); - test(); + Word32 common_pPowerSpectrum_fx[N_MAX + L_MDCT_OVLP_MAX]; + +#ifdef MSAN_FIX + set32_fx( common_pPowerSpectrum_fx, 0, N_MAX + L_MDCT_OVLP_MAX ); +#endif + + Word16 common_pPowerSpectrum_exp = MIN16B; + move16(); IF( st->last_core == ACELP_CORE ) { last_core_acelp = 1; @@ -2516,10 +2584,12 @@ void IGFEncApplyMono_ivas_fx( IF( !isTNSActive && isTCX20 ) { pPowerSpectrumParameter_fx = pPowerSpectrum_fx; + pPowerSpectrumParameter_exp = e_ps; } ELSE { pPowerSpectrumParameter_fx = NULL; + pPowerSpectrumParameter_exp = NULL; } IGF_UpdateInfo( st->hIGFEnc, igfGridIdx ); @@ -2530,28 +2600,51 @@ void IGFEncApplyMono_ivas_fx( calculate_hangover_attenuation_gain_ivas_fx( st, &att_fx, vad_hover_flag ); } - IGF_CalculateEnvelope_ivas_fx( st->hIGFEnc, pMDCTSpectrum_fx, e_mdct, pPowerSpectrumParameter_fx, e_ps, igfGridIdx, st->hTranDet->transientDetector.bIsAttackPresent, last_core_acelp, st->element_mode, att_fx ); + IGF_CalculateEnvelope_ivas_fx( st->hIGFEnc, pMDCTSpectrum_fx, e_mdct, pPowerSpectrumParameter_fx, pPowerSpectrumParameter_exp, igfGridIdx, st->hTranDet->transientDetector.bIsAttackPresent, last_core_acelp, st->element_mode, att_fx ); - test(); IF( isTCX20 ) { pPowerSpectrumParameter_fx = pPowerSpectrum_fx; + pPowerSpectrumParameter_exp = e_ps; } ELSE { pPowerSpectrumParameter_fx = NULL; + pPowerSpectrumParameter_exp = NULL; } IF( EQ_16( st->element_mode, IVAS_CPE_MDCT ) ) { - IGF_Whitening_ivas_fx( st->hIGFEnc, pPowerSpectrumParameter_fx, &e_ps, igfGridIdx, st->hTranDet->transientDetector.bIsAttackPresent, last_core_acelp, isTNSActive, sp_aud_decision0, st->element_brate, st->element_mode ); + IGF_Whitening_ivas_fx( st->hIGFEnc, pPowerSpectrumParameter_fx, pPowerSpectrumParameter_exp, igfGridIdx, st->hTranDet->transientDetector.bIsAttackPresent, last_core_acelp, isTNSActive, sp_aud_decision0, st->element_brate, st->element_mode ); } ELSE { - IGF_Whitening_ivas_fx( st->hIGFEnc, pPowerSpectrumParameter_fx, &e_ps, igfGridIdx, st->hTranDet->transientDetector.bIsAttackPresent, last_core_acelp, isTNSActive, sp_aud_decision0, st->total_brate, st->element_mode ); + IGF_Whitening_ivas_fx( st->hIGFEnc, pPowerSpectrumParameter_fx, pPowerSpectrumParameter_exp, igfGridIdx, st->hTranDet->transientDetector.bIsAttackPresent, last_core_acelp, isTNSActive, sp_aud_decision0, st->total_brate, st->element_mode ); } - IGF_ErodeSpectrum( &highPassEner_exp, st->hIGFEnc, pMDCTSpectrum_fx, pPowerSpectrumParameter_fx, e_ps, igfGridIdx ); + IF( pPowerSpectrumParameter_fx ) + { +#ifndef MSAN_FIX + FOR( Word16 i = 0; i < N_MAX + L_MDCT_OVLP_MAX; i++ ) +#else + FOR( Word16 i = 0; i < powerSpectrum_len; i++ ) +#endif + { + common_pPowerSpectrum_exp = s_max( common_pPowerSpectrum_exp, pPowerSpectrumParameter_exp[i] ); + } + +#ifndef MSAN_FIX + FOR( Word16 i = 0; i < N_MAX + L_MDCT_OVLP_MAX; i++ ) +#else + FOR( Word16 i = 0; i < powerSpectrum_len; i++ ) +#endif + { + common_pPowerSpectrum_fx[i] = L_shl( pPowerSpectrumParameter_fx[i], sub( pPowerSpectrumParameter_exp[i], common_pPowerSpectrum_exp ) ); + move16(); + } + pPowerSpectrumParameter_fx = common_pPowerSpectrum_fx; + } + IGF_ErodeSpectrum_ivas_fx( st->hIGFEnc, pMDCTSpectrum_fx, pPowerSpectrumParameter_fx, common_pPowerSpectrum_exp, igfGridIdx, 0 ); } @@ -2572,15 +2665,15 @@ void IGFEncApplyStereo_fx( Word32 *inv_spectrum_fx[CPE_CHANNELS][NB_DIV], /* i : inverse spectrum */ const Word16 frameno, /* i : flag indicating index of current subfr. */ const Word16 sp_aud_decision0, /* i : sp_aud_decision0 */ - const Word32 element_brate /* i : element bitrate */ -) + const Word32 element_brate, /* i : element bitrate */ + const Word16 mct_on ) { - Word16 highPassEner_exp; Word32 *pPowerSpectrumParameter_fx[NB_DIV]; /* If it is NULL it informs a function that specific handling is needed */ Word32 *pPowerSpectrumParameterMsInv_fx[NB_DIV]; Word16 coreMsMask[N_MAX]; Word16 sfb, ch, last_core_acelp; STEREO_MDCT_BAND_PARAMETERS *sfbConf; + Word16 exp_pPowerSpectrum[L_FRAME48k]; /* assumptions: stereo filling was already done on the flattened spectra * IGF region is always coded M/S, never L/R (to be done in the encoder) @@ -2600,7 +2693,7 @@ void IGFEncApplyStereo_fx( { sfbConf = &hStereoMdct->stbParamsTCX10; } - if ( EQ_16( sts[0]->last_core, ACELP_CORE ) ) + if ( sts[0]->last_core == ACELP_CORE ) { sfbConf = &hStereoMdct->stbParamsTCX20afterACELP; } @@ -2644,9 +2737,11 @@ void IGFEncApplyStereo_fx( pPowerSpectrumParameter_fx[ch] = NULL; } - IGF_Whitening_ivas_fx( hIGFEnc[ch], pPowerSpectrumParameter_fx[ch], &sts[ch]->hTcxEnc->spectrum_e[frameno], igfGridIdx, sts[ch]->hTranDet->transientDetector.bIsAttackPresent, last_core_acelp, ( sts[0]->hTcxEnc->fUseTns[frameno] || sts[1]->hTcxEnc->fUseTns[frameno] ), sp_aud_decision0, element_brate, sts[ch]->element_mode ); + set16_fx( exp_pPowerSpectrum, sts[ch]->hTcxEnc->spectrum_e[frameno], L_FRAME48k ); + + IGF_Whitening_ivas_fx( hIGFEnc[ch], pPowerSpectrumParameter_fx[ch], &exp_pPowerSpectrum[0], igfGridIdx, sts[ch]->hTranDet->transientDetector.bIsAttackPresent, last_core_acelp, ( sts[0]->hTcxEnc->fUseTns[frameno] || sts[1]->hTcxEnc->fUseTns[frameno] ), sp_aud_decision0, element_brate, sts[ch]->element_mode ); - IGF_ErodeSpectrum( &highPassEner_exp, hIGFEnc[ch], sts[ch]->hTcxEnc->spectrum_fx[frameno], pPowerSpectrumParameter_fx[ch], sts[ch]->hTcxEnc->spectrum_e[frameno], igfGridIdx ); + IGF_ErodeSpectrum_ivas_fx( hIGFEnc[ch], sts[ch]->hTcxEnc->spectrum_fx[frameno], pPowerSpectrumParameter_fx[ch], sts[ch]->hTcxEnc->spectrum_e[frameno], igfGridIdx, mct_on ); } return; } @@ -2661,13 +2756,18 @@ void IGFEncApplyStereo_fx( void IGFSaveSpectrumForITF_ivas_fx( IGF_ENC_INSTANCE_HANDLE hIGFEnc, /* i/o: instance handle of IGF Encoder */ const Word16 igfGridIdx, /* i : IGF grid index */ - const Word32 *pITFSpectrum /* i : MDCT spectrum */ -) + const Word32 *pITFSpectrum, /* i : MDCT spectrum */ + Word16 exp_pITFSpectrum ) { IGF_UpdateInfo( hIGFEnc, igfGridIdx ); Copy32( pITFSpectrum + IGF_START_MN, hIGFEnc->spec_be_igf, sub( hIGFEnc->infoStopLine, IGF_START_MN ) ); + scale_sig32( hIGFEnc->spec_be_igf, sub( hIGFEnc->infoStopLine, IGF_START_MN ), sub( exp_pITFSpectrum, s_max( exp_pITFSpectrum, hIGFEnc->spec_be_igf_e ) ) ); + scale_sig32( hIGFEnc->spec_be_igf + sub( hIGFEnc->infoStopLine, IGF_START_MN ), sub( N_MAX_TCX - IGF_START_MN, sub( hIGFEnc->infoStopLine, IGF_START_MN ) ), sub( hIGFEnc->spec_be_igf_e, s_max( exp_pITFSpectrum, hIGFEnc->spec_be_igf_e ) ) ); + hIGFEnc->spec_be_igf_e = s_max( exp_pITFSpectrum, hIGFEnc->spec_be_igf_e ); + move16(); + return; } diff --git a/lib_enc/igf_enc_fx.c b/lib_enc/igf_enc_fx.c index f0d83e41638f29ab714154ca905d259a68a90acf..cc48408763babac36e5f43a16ffc5c3777a222a1 100644 --- a/lib_enc/igf_enc_fx.c +++ b/lib_enc/igf_enc_fx.c @@ -8,8 +8,7 @@ #include "options.h" #include "cnst.h" #include "stl.h" -#include "prot.h" -#include "prot_fx.h" /* Function prototypes */ +#include "prot_fx.h" #include "prot_fx_enc.h" /* Function prototypes */ #include "stat_enc.h" #include "basop_util.h" @@ -17,7 +16,7 @@ /**********************************************************************/ /* write single bit to stream **************************************************************************/ -static void IGF_write_bit( +static void IGF_write_bit_fx( BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ Word16 *bitCount, /**< in/out: | bit counter */ Word16 bit /**< in: | value of bit */ @@ -44,11 +43,11 @@ static void IGF_write_bits( tmp = s_and( value, shl( 1, bits ) ); IF( tmp == 0 ) { - IGF_write_bit( hBstr, bitCount, 0 ); + IGF_write_bit_fx( hBstr, bitCount, 0 ); } ELSE { - IGF_write_bit( hBstr, bitCount, 1 ); + IGF_write_bit_fx( hBstr, bitCount, 1 ); } } @@ -96,6 +95,7 @@ static void IGF_CalculateEnvelope( const IGF_ENC_INSTANCE_HANDLE hInstance, /**< Word16 shift; #ifdef BASOP_NOGLOB_DECLARE_LOCAL Flag Overflow = 0; + move32(); #endif /* initialize variables */ @@ -218,23 +218,8 @@ static void IGF_CalculateEnvelope( const IGF_ENC_INSTANCE_HANDLE hInstance, /**< move16(); } -#ifdef BASOP_NOGLOB BASOP_Util_Divide_MantExp( round_fx_o( sfbEnergyTileR[sfb], &Overflow ), sfbEnergyTileR_exp[sfb], width, 15, &gain, &gain_exp ); BASOP_Util_Divide_MantExp( round_fx_o( sfbEnergyC[sfb], &Overflow ), sfbEnergyC_exp[sfb], round_fx_o( sfbEnergyTileC[sfb], &Overflow ), sfbEnergyTileC_exp[sfb], &tmp, &tmp_exp ); -#else - BASOP_Util_Divide_MantExp( round_fx( sfbEnergyTileR[sfb] ), - sfbEnergyTileR_exp[sfb], - width, - 15, - &gain, - &gain_exp ); - BASOP_Util_Divide_MantExp( round_fx( sfbEnergyC[sfb] ), - sfbEnergyC_exp[sfb], - round_fx( sfbEnergyTileC[sfb] ), - sfbEnergyTileC_exp[sfb], - &tmp, - &tmp_exp ); -#endif L_tmp = L_mult( gain, tmp ); gain_exp = add( gain_exp, tmp_exp ); } @@ -249,21 +234,12 @@ static void IGF_CalculateEnvelope( const IGF_ENC_INSTANCE_HANDLE hInstance, /**< zeroNrg = 1; move16(); } -#ifdef BASOP_NOGLOB BASOP_Util_Divide_MantExp( round_fx_sat( sfbEnergyR[sfb] ), sfbEnergyR_exp[sfb], width, 15, &gain, &gain_exp ); -#else - BASOP_Util_Divide_MantExp( round_fx( sfbEnergyR[sfb] ), - sfbEnergyR_exp[sfb], - width, - 15, - &gain, - &gain_exp ); -#endif L_tmp = L_deposit_h( gain ); } @@ -271,11 +247,7 @@ static void IGF_CalculateEnvelope( const IGF_ENC_INSTANCE_HANDLE hInstance, /**< L_tmp = BASOP_Util_Log2( L_tmp ); L_tmp = L_add( L_tmp, L_deposit_h( shl( gain_exp, 15 - 6 ) ) ); shift = norm_l( L_tmp ); -#ifdef BASOP_NOGLOB gain = round_fx_o( L_shl_o( L_tmp, shift, &Overflow ), &Overflow ); -#else - gain = round_fx( L_shl( L_tmp, shift ) ); -#endif gain_exp = sub( 7, shift ); gain_exp = BASOP_Util_Add_MantExp( gain, gain_exp, 32767 /*16 Q11*/, 4, &gain ); gain_exp = BASOP_Util_Add_MantExp( gain, gain_exp, 0x4000, 0, &gain ); @@ -338,21 +310,21 @@ static void IGF_WriteEnvelope( /**< ou IF( *igfAllZero != 0 ) { - IGF_write_bit( hBstr, pBitOffset, 1 ); - IF( NULL == hBstr ) + IGF_write_bit_fx( hBstr, pBitOffset, 1 ); + if ( NULL == hBstr ) { IGFSCFEncoderSaveContextState_fx( &hPrivateData->hIGFSCFArithEnc, igfGridIdx ); } IGFSCFEncoderReset_fx( &hPrivateData->hIGFSCFArithEnc ); - IF( NULL == hBstr ) + if ( NULL == hBstr ) { IGFSCFEncoderRestoreContextState_fx( &hPrivateData->hIGFSCFArithEnc, igfGridIdx ); } } ELSE { - IGF_write_bit( hBstr, pBitOffset, 0 ); - IF( NULL == hBstr ) + IGF_write_bit_fx( hBstr, pBitOffset, 0 ); + if ( NULL == hBstr ) { IGFSCFEncoderSaveContextState_fx( &hPrivateData->hIGFSCFArithEnc, igfGridIdx ); } @@ -360,7 +332,7 @@ static void IGF_WriteEnvelope( /**< ou *pBitOffset = IGFSCFEncoderEncode_fx( &hPrivateData->hIGFSCFArithEnc, hBstr, *pBitOffset, &hPrivateData->igfScfQuantized[hGrid->startSfb], igfGridIdx, isIndepFlag ); move16(); - IF( NULL == hBstr ) + if ( NULL == hBstr ) { IGFSCFEncoderRestoreContextState_fx( &hPrivateData->hIGFSCFArithEnc, igfGridIdx ); } @@ -403,6 +375,8 @@ void IGF_ErodeSpectrum( Word16 *highPassEner_exp, /**< ou #ifdef BASOP_NOGLOB_DECLARE_LOCAL Flag Overflow = 0; Flag Carry = 0; + move32(); + move32(); #endif hPrivateData = &hInstance->igfData; @@ -440,21 +414,16 @@ void IGF_ErodeSpectrum( Word16 *highPassEner_exp, /**< ou FOR( i = 0; i < igfBgn; i++ ) { Carry = 0; -#ifdef BASOP_NOGLOB + move32(); highPassEner = L_add_co( highPassEner, Mpy_32_16_1( pPowerSpectrum[i], shl( i, 4 ) /*Q4*/ ) /*Q20, pPowerSpectrum_exp*/, &Carry, &Overflow ); -#else /* BASOP_NOGLOB */ - highPassEner = L_add_c( highPassEner, Mpy_32_16_1( pPowerSpectrum[i], shl( i, 4 ) /*Q4*/ ) /*Q20, pPowerSpectrum_exp*/ ); -#endif /* BASOP_NOGLOB */ Overflow = 0; -#ifdef BASOP_NOGLOB + move32(); L_c = L_macNs_co( L_c, 0, 0, &Carry, &Overflow ); -#else /* BASOP_NOGLOB */ - L_c = L_macNs( L_c, 0, 0 ); -#endif /* BASOP_NOGLOB */ } highPassEner = norm_llQ31( L_c, highPassEner, highPassEner_exp ); /*Q20, highPassEner_exp*/ *highPassEner_exp = add( *highPassEner_exp, pPowerSpectrum_exp ); + move16(); test(); test(); if ( NE_16( hPrivateData->igfInfo.bitRateIndex, IGF_BITRATE_SWB_9600 ) && @@ -473,15 +442,8 @@ void IGF_ErodeSpectrum( Word16 *highPassEner_exp, /**< ou /* May overflow - just for threshold comparison */ /* negate because the negated may be 1 larger in abs, */ /* so whenever compared to the negation of a maximum possible pPowerspectrum, it is still larger */ -#ifdef BASOP_NOGLOB highPassEner_Ovfl = L_shl_o( L_negate( highPassEner ), sub( *highPassEner_exp, pPowerSpectrum_exp ), &Overflow ); L_tmp = L_add_o( pPowerSpectrum[i - 1], highPassEner_Ovfl, &Overflow ); -#else - BASOP_SATURATE_WARNING_OFF_EVS - highPassEner_Ovfl = L_shl( L_negate( highPassEner ), sub( *highPassEner_exp, pPowerSpectrum_exp ) ); - L_tmp = L_add( pPowerSpectrum[i - 1], highPassEner_Ovfl ); - BASOP_SATURATE_WARNING_ON_EVS -#endif if ( L_tmp >= 0 ) { @@ -493,11 +455,7 @@ void IGF_ErodeSpectrum( Word16 *highPassEner_exp, /**< ou { /* May overflow - just for threshold comparison */ BASOP_SATURATE_WARNING_OFF_EVS -#ifdef BASOP_NOGLOB L_tmp = L_add_sat( pPowerSpectrum[i], highPassEner_Ovfl ); -#else - L_tmp = L_add( pPowerSpectrum[i], highPassEner_Ovfl ); -#endif BASOP_SATURATE_WARNING_ON_EVS; IF( L_tmp < 0 ) @@ -522,15 +480,12 @@ void IGF_ErodeSpectrum( Word16 *highPassEner_exp, /**< ou /* May overflow - just for threshold comparison */ BASOP_SATURATE_WARNING_OFF_EVS -#ifdef BASOP_NOGLOB L_tmp = L_add_sat( pPowerSpectrum[i], highPassEner_Ovfl ); -#else - L_tmp = L_add( pPowerSpectrum[i], highPassEner_Ovfl ); -#endif BASOP_SATURATE_WARNING_ON_EVS - IF( L_tmp < 0 ) + if ( L_tmp < 0 ) { pSpectrum[i] = L_deposit_l( 0 ); + move32(); } } @@ -538,7 +493,9 @@ void IGF_ErodeSpectrum( Word16 *highPassEner_exp, /**< ou FOR( i = igfEnd; i < hGrid->infoGranuleLen; i++ ) { pSpectrum[i] = L_deposit_l( 0 ); + move32(); pPowerSpectrum[i] = L_deposit_l( 0 ); + move32(); } FOR( sfb = startSfb; sfb < stopSfb; sfb++ ) @@ -567,6 +524,179 @@ void IGF_ErodeSpectrum( Word16 *highPassEner_exp, /**< ou } } +void IGF_ErodeSpectrum_ivas_fx( const IGF_ENC_INSTANCE_HANDLE hInstance, /**< in: | instance handle of IGF Encoder */ + Word32 *pSpectrum, /**< in/out: | MDCT spectrum Qx*/ + Word32 *pPowerSpectrum, /**< in/out: | power spectrum */ + Word16 pPowerSpectrum_exp, /**< in: | exponent of power spectrum */ + const Word16 igfGridIdx, /**< in: Q0 | IGF grid index */ + const Word16 mct_on ) +{ + IGF_ENC_PRIVATE_DATA_HANDLE hPrivateData; + H_IGF_GRID hGrid; + Word16 i; + Word16 igfBgn; + Word16 igfEnd; + Word32 highPassEner; /* Q31 */ + Word32 lastLine; + Word32 nextLine; + Word16 *swb_offset; + Word16 sfb; + Word16 startSfb; + Word16 stopSfb; + Word16 line; + Word16 *igfScaleF; + Word16 tmp; + Word16 factor; + Word16 exp1, exp2; + Word16 num, den; + Word32 temp; + + hPrivateData = &hInstance->igfData; + hGrid = &hPrivateData->igfInfo.grid[igfGridIdx]; + igfBgn = hGrid->startLine; + move16(); + igfEnd = hGrid->stopLine; + move16(); + swb_offset = hGrid->swb_offset; + move16(); + startSfb = hGrid->startSfb; + move16(); + stopSfb = hGrid->stopSfb; + move16(); + igfScaleF = hPrivateData->igfScfQuantized; + move16(); + + IF( NULL == pPowerSpectrum ) + { + FOR( i = igfBgn; i < hGrid->infoGranuleLen; i++ ) + { + pSpectrum[i] = 0; + move32(); + } + return; + } + + IF( igfBgn > 0 ) + { + Word64 sum = 0; + move64(); + FOR( i = 0; i < igfBgn; i++ ) + { + sum = W_mac_32_16( sum, pPowerSpectrum[i], i ); // Q: 31-pPowerSpectrum_exp+1 + } + exp1 = W_norm( sum ); + sum = W_shl( sum, sub( exp1, 1 ) ); // Q: 31-pPowerSpectrum_exp+1+exp1-1 + num = extract_h( W_extract_h( sum ) ); // Q: 31-pPowerSpectrum_exp+exp1-48 = -pPowerSpectrum_exp+exp1-17 + exp1 = add( 32, sub( pPowerSpectrum_exp, exp1 ) ); // exp: 32+pPowerSpectrum_exp-exp1 + + IF( EQ_16( hPrivateData->igfInfo.bitRateIndex, IGF_BITRATE_SWB_9600 ) || + EQ_16( hPrivateData->igfInfo.bitRateIndex, IGF_BITRATE_RF_SWB_13200 ) || + EQ_16( hPrivateData->igfInfo.bitRateIndex, IGF_BITRATE_SWB_13200 ) || + EQ_16( hPrivateData->igfInfo.bitRateIndex, IGF_BITRATE_SWB_16400_CPE ) ) + { + factor = ONE_IN_Q14; // Q14 + move16(); + } + ELSE IF( mct_on && ( EQ_16( hPrivateData->igfInfo.bitRateIndex, IGF_BITRATE_SWB_48000_CPE ) || EQ_16( hPrivateData->igfInfo.bitRateIndex, IGF_BITRATE_SWB_64000_CPE ) ) ) + { + factor = 11469; // 0.7f in Q14 + move16(); + } + ELSE + { + factor = 32767; // 2.f in Q14 + move16(); + } + + temp = L_mult( igfBgn, factor ); // exp: 16 + exp2 = norm_l( temp ); + den = extract_h( L_shl( temp, exp2 ) ); // exp: 16-exp2 + exp2 = sub( 16, exp2 ); + + highPassEner = L_deposit_h( div_s( num, den ) ); // exp: exp1-exp2 + + /* highPassEner is used only for comparison, saturation doesn't effect the outcome */ + highPassEner = L_shl_sat( highPassEner, sub( sub( exp1, exp2 ), pPowerSpectrum_exp ) ); // exp: pPowerSpectrum_exp + + lastLine = pSpectrum[i - 1]; // Qx + move32(); + nextLine = pSpectrum[i]; // Qx + move32(); + + if ( LT_32( pPowerSpectrum[i - 1], highPassEner ) ) + { + nextLine = 0; + move32(); + } + + FOR( /*i*/; i < igfEnd - 1; i++ ) + { + /* May overflow - just for threshold comparison */ + IF( LT_32( pPowerSpectrum[i], highPassEner ) ) + { + lastLine = pSpectrum[i]; // Qx + move32(); + pSpectrum[i] = nextLine; // Qx + move32(); + nextLine = 0; + move32(); + } + ELSE + { + pSpectrum[i - 1] = lastLine; // Qx + move32(); + lastLine = pSpectrum[i]; // Qx + move32(); + nextLine = pSpectrum[i + 1]; // Qx + move32(); + } + } + + /* May overflow - just for threshold comparison */ + if ( LT_32( pPowerSpectrum[i], highPassEner ) ) + { + pSpectrum[i] = 0; + move32(); + } + } + + /* delete spectrum above igfEnd: */ + FOR( i = igfEnd; i < hGrid->infoGranuleLen; i++ ) + { + pSpectrum[i] = 0; + pPowerSpectrum[i] = 0; + move32(); + move32(); + } + + // Below check is present at the beginning of the function and is not required here + /* IF( NULL != pPowerSpectrum ) */ + { + FOR( sfb = startSfb; sfb < stopSfb; sfb++ ) + { + tmp = 0; + move16(); + FOR( line = swb_offset[sfb]; line < swb_offset[sfb + 1]; line++ ) + { + if ( pSpectrum[line] != 0 ) + { + tmp = add( tmp, 1 ); + } + } + + Word16 igfScaleF_cnt = igfScaleF[sfb]; + move16(); + test(); + if ( tmp && igfScaleF[sfb] ) + { + igfScaleF_cnt = sub( igfScaleF[sfb], 1 ); + } + igfScaleF[sfb] = igfScaleF_cnt; + move16(); + } + } +} + /**********************************************************************/ /* crest factor calculation **************************************************************************/ @@ -630,16 +760,11 @@ Word16 IGF_getCrest( /**< ou tmp32 = L_shl( tmp32, i ); /*Q31, s-i+15*/ crest = extract_h( tmp32 ); *crest_exp = add( sub( s, i ), 15 ); - + move16(); /* limit crest factor to a lower bound of 1, may overflow */ BASOP_SATURATE_WARNING_OFF_EVS -#ifdef BASOP_NOGLOB tmp = shl_sat( -1, sub( 15, *crest_exp ) ); /* build negative threshold */ tmp = add_sat( crest, tmp ); -#else - tmp = shl( -1, sub( 15, *crest_exp ) ); /* build negative threshold */ - tmp = add( crest, tmp ); -#endif BASOP_SATURATE_WARNING_ON_EVS if ( tmp < 0 ) { @@ -679,6 +804,8 @@ Word16 IGF_getSFM( /**< out: Q15| SFM value #ifdef BASOP_NOGLOB_DECLARE_LOCAL Flag Overflow = 0; Flag Carry = 0; + move32(); + move32(); #endif L_c = 0; @@ -712,18 +839,11 @@ Word16 IGF_getSFM( /**< out: Q15| SFM value num = L_add( num, L_deposit_l( n ) ); /*Q0*/ Carry = 0; -#ifdef BASOP_NOGLOB + move32(); denom = L_add_co( energy[i], denom, &Carry, &Overflow ); -#else /* BASOP_NOGLOB */ - denom = L_add_c( energy[i], denom ); -#endif /* BASOP_NOGLOB */ Overflow = 0; - -#ifdef BASOP_NOGLOB + move32(); L_c = L_macNs_co( L_c, 0, 0, &Carry, &Overflow ); -#else /* BASOP_NOGLOB */ - L_c = L_macNs( L_c, 0, 0 ); -#endif } denom = norm_llQ31( L_c, denom, &denom_exp ); /*Q31*/ @@ -759,13 +879,9 @@ Word16 IGF_getSFM( /**< out: Q15| SFM value /*Transform to Q15*/ s = norm_l( SFM32 ); -#ifdef BASOP_NOGLOB SFM = round_fx_sat( L_shl_sat( SFM32, s ) ); -#else - SFM = round_fx( L_shl( SFM32, s ) ); -#endif *SFM_exp = sub( *SFM_exp, s ); - + move16(); /**SFM_exp = s_min(*SFM_exp, 0);*/ IF( *SFM_exp > 0 ) { @@ -811,6 +927,7 @@ static void IGF_Whitening( const IGF_ENC_INSTANCE_HANDLE hInstance, /**< in { /* reset filter */ hPrivateData->prevSFM_FIR[p] = L_deposit_l( 0 ); + move32(); hPrivateData->prevSFM_IIR[p] = 0; move16(); @@ -834,6 +951,7 @@ static void IGF_Whitening( const IGF_ENC_INSTANCE_HANDLE hInstance, /**< in IF( powerSpectrum ) { Word16 nT = hGrid->nTiles; + move16(); SWITCH( hPrivateData->igfInfo.bitRateIndex ) { case IGF_BITRATE_WB_9600: @@ -875,13 +993,8 @@ static void IGF_Whitening( const IGF_ENC_INSTANCE_HANDLE hInstance, /**< in BASOP_SATURATE_WARNING_OFF_EVS /*SFM = min(2.7f, SFM);*/ /*Overflow possible in shift, intended*/ -#ifdef BASOP_NOGLOB tmp = add_sat( crest, tmp ); SFM = s_min( 22118 /*2.7f Q13*/, extract_h( L_shr_sat( SFM32, 16 - 29 ) /*->Q29*/ ) /*->Q13*/ ); -#else - tmp = add( crest, tmp ); - SFM = s_min( 22118 /*2.7f Q13*/, extract_h( L_shr( SFM32, 16 - 29 ) /*->Q29*/ ) /*->Q13*/ ); -#endif BASOP_SATURATE_WARNING_ON_EVS hPrivateData->prevSFM_FIR[p] = tmp32; /*15Q16*/ @@ -934,6 +1047,7 @@ static void IGF_Whitening( const IGF_ENC_INSTANCE_HANDLE hInstance, /**< in FOR( p = 0; p < IGF_MAX_TILES; p++ ) { hPrivateData->prevSFM_FIR[p] = L_deposit_l( 0 ); + move32(); hPrivateData->prevSFM_IIR[p] = 0; move16(); } @@ -945,10 +1059,10 @@ static void IGF_Whitening( const IGF_ENC_INSTANCE_HANDLE hInstance, /**< in /**********************************************************************/ /* write whitening levels into bitstream **************************************************************************/ -static void IGF_WriteWhiteningTile( /**< out: Q0 | number of bits written */ - BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ - Word16 *pBitOffset, /**< in: | ptr to bitOffset counter */ - Word16 whiteningLevel /**< in: Q0 | whitening levels to write */ +static void IGF_WriteWhiteningTile_fx( /**< out: Q0 | number of bits written */ + BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ + Word16 *pBitOffset, /**< in: | ptr to bitOffset counter */ + Word16 whiteningLevel /**< in: Q0 | whitening levels to write */ ) { IF( EQ_32( whiteningLevel, IGF_WHITENING_MID ) ) @@ -969,15 +1083,15 @@ static void IGF_WriteWhiteningTile( /**< ou } } -/**********************************************************************/ /* - writes the whitening levels - **************************************************************************/ -static void IGF_WriteWhiteningLevels( /**< out: Q0 | total number of bits written */ - const IGF_ENC_INSTANCE_HANDLE hInstance, /**< in: | instance handle of IGF encoder */ - BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ - Word16 *pBitOffset, /**< in: | ptr to bitOffset counter */ - const Word16 igfGridIdx, /**< in: Q0 | igf grid index see declaration of IGF_GRID_IDX for details */ - const Word16 isIndepFlag /**< in: Q0 | if 1 frame is independent, 0 = frame is coded with data from previous frame */ +/**********************************************************************/ /* + writes the whitening levels + **************************************************************************/ +static void IGF_WriteWhiteningLevels_fx( /**< out: Q0 | total number of bits written */ + const IGF_ENC_INSTANCE_HANDLE hInstance, /**< in: | instance handle of IGF encoder */ + BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ + Word16 *pBitOffset, /**< in: | ptr to bitOffset counter */ + const Word16 igfGridIdx, /**< in: Q0 | igf grid index see declaration of IGF_GRID_IDX for details */ + const Word16 isIndepFlag /**< in: Q0 | if 1 frame is independent, 0 = frame is coded with data from previous frame */ ) { IGF_ENC_PRIVATE_DATA_HANDLE hPrivateData; @@ -1006,7 +1120,7 @@ static void IGF_WriteWhiteningLevels( / move16(); tmp32 = 0; move32(); - + test(); WHILE( ( LT_16( p, nTiles ) ) && ( tmp32 == 0 ) ) { test(); @@ -1029,7 +1143,7 @@ static void IGF_WriteWhiteningLevels( / { IGF_write_bits( hBstr, pBitOffset, 0, 1 ); } - IGF_WriteWhiteningTile( hBstr, pBitOffset, hPrivateData->igfCurrWhiteningLevel[0] ); + IGF_WriteWhiteningTile_fx( hBstr, pBitOffset, hPrivateData->igfCurrWhiteningLevel[0] ); p = 1; move16(); tmp32 = 0; @@ -1039,7 +1153,7 @@ static void IGF_WriteWhiteningLevels( / isSame = 1; move16(); } - + test(); WHILE( ( LT_16( p, nTiles ) ) && ( tmp32 == 0 ) ) { test(); @@ -1057,7 +1171,7 @@ static void IGF_WriteWhiteningLevels( / IGF_write_bits( hBstr, pBitOffset, 1, 1 ); FOR( p = 1; p < nTiles; p++ ) { - IGF_WriteWhiteningTile( hBstr, pBitOffset, hPrivateData->igfCurrWhiteningLevel[p] ); + IGF_WriteWhiteningTile_fx( hBstr, pBitOffset, hPrivateData->igfCurrWhiteningLevel[p] ); } } ELSE @@ -1067,13 +1181,13 @@ static void IGF_WriteWhiteningLevels( / } } -/**********************************************************************/ /* - write flattening trigger - **************************************************************************/ -static void IGF_WriteFlatteningTrigger( /**< out: | number of bits written */ - const IGF_ENC_INSTANCE_HANDLE hInstance, /**< in: | instance handle of IGF Encoder */ - BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ - Word16 *pBitOffset /**< in: | ptr to bitOffset counter */ +/**********************************************************************/ /* + write flattening trigger + **************************************************************************/ +static void IGF_WriteFlatteningTrigger_fx( /**< out: | number of bits written */ + const IGF_ENC_INSTANCE_HANDLE hInstance, /**< in: | instance handle of IGF Encoder */ + BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ + Word16 *pBitOffset /**< in: | ptr to bitOffset counter */ ) { Word16 flatteningTrigger; @@ -1143,19 +1257,20 @@ Word16 IGFEncWriteBitstream_fx( /**< ou isIndepFlag, /* i: if 1 frame is independent, 0 = frame is coded with data from previous frame */ &igfAllZero ); /* o: *igfAllZero */ - IGF_WriteWhiteningLevels( hInstance, /* i: instance handle of IGF Encoder */ - hBstr, /* i: encoder state */ - pBitOffset, /* i: ptr to bitOffset counter */ - igfGridIdx, /* i: igf grid index see definition of IGF_GRID_IDX for details */ - isIndepFlag ); /* i: if 1 frame is independent, 0 = frame is coded with data from previous frame */ + IGF_WriteWhiteningLevels_fx( hInstance, /* i: instance handle of IGF Encoder */ + hBstr, /* i: encoder state */ + pBitOffset, /* i: ptr to bitOffset counter */ + igfGridIdx, /* i: igf grid index see definition of IGF_GRID_IDX for details */ + isIndepFlag ); /* i: if 1 frame is independent, 0 = frame is coded with data from previous frame */ - IGF_WriteFlatteningTrigger( hInstance, /* i: instance handle of IGF Encoder */ - hBstr, /* i: encoder state */ - pBitOffset ); /* i: ptr to bitOffset counter */ + IGF_WriteFlatteningTrigger_fx( hInstance, /* i: instance handle of IGF Encoder */ + hBstr, /* i: encoder state */ + pBitOffset ); /* i: ptr to bitOffset counter */ hInstance->infoTotalBitsPerFrameWritten = sub( *pBitOffset, startBitCount ); hInstance->infoTotalBitsWritten = add( hInstance->infoTotalBitsWritten, hInstance->infoTotalBitsPerFrameWritten ); - + move16(); + move16(); return hInstance->infoTotalBitsPerFrameWritten; } @@ -1253,7 +1368,7 @@ static void pack_bit_ivas_fx( move16(); } - IF( bit != 0 ) + if ( bit != 0 ) { **pt = (UWord8) s_or( **pt, *omask ); move16(); @@ -1302,6 +1417,7 @@ void IGFEncConcatenateBitstream_ivas_fx( const IGF_ENC_INSTANCE_HANDLE hIGFEnc, move16(); omask = (UWord8) UL_lshr( 0x80, s_and( *pFrame_size, 0x7 ) ); + move16(); pFrame += *pFrame_size >> 3; /* bitstream packing (conversion of individual indices into a serial stream) */ @@ -1348,7 +1464,7 @@ void IGFEncConcatenateBitstream_fx( const IGF_ENC_INSTANCE_HANDLE hInstance, /** hPrivateData = &hInstance->igfData; *next_ind = *next_ind - bsBits; - + move16(); indices_to_serial_generic( &ind_list_fx[*next_ind], bsBits, @@ -1356,7 +1472,7 @@ void IGFEncConcatenateBitstream_fx( const IGF_ENC_INSTANCE_HANDLE hInstance, /** &hPrivateData->igfBitstreamBits ); *nb_bits = sub( *nb_bits, bsBits ); - + move16(); return; } diff --git a/lib_enc/igf_scf_enc.c b/lib_enc/igf_scf_enc.c index 5ac4f4e3e9c278705e73817d0c46402ae38b93bb..2921b58866c86fab78dcf3af0061fa68559cd4ec 100644 --- a/lib_enc/igf_scf_enc.c +++ b/lib_enc/igf_scf_enc.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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,12 +36,11 @@ #include #include "options.h" -#include "prot.h" +#include "prot_fx.h" #include "stat_enc.h" #include "stat_com.h" #include "cnst.h" #include "wmc_auto.h" -#include "prot_fx.h" #include "prot_fx_enc.h" @@ -93,11 +92,12 @@ static void arith_encode_bits( FOR( i = nBits - 1; i >= 0; --i ) /* nBits > 0 */ { bit = s_and( shr( x, i ), 1 ); - hPrivateData->ptrBitIndex = ari_encode_14bits_sign( ptr, - hPrivateData->ptrBitIndex, - 32767, /* disable the bit count limitation */ - &hPrivateData->acState, - bit ); + hPrivateData->ptrBitIndex = ari_encode_14bits_sign_ivas_fx( ptr, + hPrivateData->ptrBitIndex, + 32767, /* disable the bit count limitation */ + &hPrivateData->acState, + bit ); + move16(); } } @@ -128,12 +128,12 @@ static void arith_encode_residual( { x = sub( x, IGF_MIN_ENC_SEPARATE - 1 ); /* (x - IGF_MIN_ENC_SEPARATE) + 1 */ /* encode one of the IGF_SYMBOLS_IN_TABLE == 27 alphabet symbols using the new raw AC function */ - hPrivateData->ptrBitIndex = ari_encode_14bits_ext( ptr, - hPrivateData->ptrBitIndex, - &hPrivateData->acState, - x, - cumulativeFrequencyTable ); - + hPrivateData->ptrBitIndex = ari_encode_14bits_ext_ivas_fx( ptr, + hPrivateData->ptrBitIndex, + &hPrivateData->acState, + x, + cumulativeFrequencyTable ); + move16(); return; } @@ -141,21 +141,23 @@ static void arith_encode_residual( { /* send escape code 0 to indicate x <= IGF_MIN_ENC_SEPARATE - 1 */ extra = sub( IGF_MIN_ENC_SEPARATE - 1, x ); - hPrivateData->ptrBitIndex = ari_encode_14bits_ext( ptr, - hPrivateData->ptrBitIndex, - &hPrivateData->acState, - 0, - cumulativeFrequencyTable ); + hPrivateData->ptrBitIndex = ari_encode_14bits_ext_ivas_fx( ptr, + hPrivateData->ptrBitIndex, + &hPrivateData->acState, + 0, + cumulativeFrequencyTable ); + move16(); } ELSE /* x > IGF_MAX_ENC_SEPARATE */ { /* send escape code (IGF_SYMBOLS_IN_TABLE - 1) to indicate x >= IGF_MAX_ENC_SEPARATE + 1 */ extra = sub( x, IGF_MAX_ENC_SEPARATE + 1 ); - hPrivateData->ptrBitIndex = ari_encode_14bits_ext( ptr, - hPrivateData->ptrBitIndex, - &hPrivateData->acState, - IGF_SYMBOLS_IN_TABLE - 1, - cumulativeFrequencyTable ); + hPrivateData->ptrBitIndex = ari_encode_14bits_ext_ivas_fx( ptr, + hPrivateData->ptrBitIndex, + &hPrivateData->acState, + IGF_SYMBOLS_IN_TABLE - 1, + cumulativeFrequencyTable ); + move16(); } /* encode one of the tails of the distribution */ @@ -221,22 +223,25 @@ static void encode_sfe_vector( { /* (t == 0) && (f == 0) */ /* encode one of the IGF_SYMBOLS_IN_TABLE == 27 alphabet symbols using the new raw AC function */ - hPrivateData->ptrBitIndex = ari_encode_14bits_ext( ptr, - hPrivateData->ptrBitIndex, - &hPrivateData->acState, - shr( x[f], 2 ), - (const UWord16 *) hPrivateData->cf_se00 ); + hPrivateData->ptrBitIndex = ari_encode_14bits_ext_ivas_fx( ptr, + hPrivateData->ptrBitIndex, + &hPrivateData->acState, + shr( x[f], 2 ), + (const UWord16 *) hPrivateData->cf_se00 ); + move16(); arith_encode_bits( hPrivateData, ptr, x[f] & 3, 2 ); /* LSBs as 2 bit raw */ } ELSE IF( EQ_16( f, 1 ) ) { pred = x[f - 1]; /* pred = b */ + move16(); arith_encode_residual( hPrivateData, ptr, x[f] - pred, hPrivateData->cf_se01, hPrivateData->cf_off_se01 ); } ELSE { /* f >= 2 */ - pred = x[f - 1]; /* pred = b */ + pred = x[f - 1]; /* pred = b */ + move16(); ctx = quant_ctx( sub( x[f - 1], x[f - 2] ) ); /* Q(b - e) */ arith_encode_residual( hPrivateData, ptr, sub( x[f], pred ), &hPrivateData->cf_se02[( IGF_SYMBOLS_IN_TABLE + 1 ) * ( IGF_CTX_OFFSET + ctx )], hPrivateData->cf_off_se02[IGF_CTX_OFFSET + ctx] ); } @@ -267,11 +272,11 @@ static void encode_sfe_vector( /*---------------------------------------------------------------------* - * IGFSCFEncoderEncode() + * IGFSCFEncoderEncode_ivas_fx() * * main IGF encoder function *---------------------------------------------------------------------*/ -Word16 IGFSCFEncoderEncode( +Word16 IGFSCFEncoderEncode_ivas_fx( IGFSCFENC_INSTANCE_HANDLE hPublicData, /* i/o: handle to public data or NULL in case there was no instance created */ BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ const Word16 bitCount, /* i : offset to the first bit in bitbuffer which should be readed by iisArithDecoderDecode function */ @@ -298,7 +303,7 @@ Word16 IGFSCFEncoderEncode( encode_sfe_vector( hPublicData, ptr, hPublicData->t, hPublicData->prev, sfe, hPublicData->scfCountLongBlock[igfGridIdx] ); - hPublicData->ptrBitIndex = ari_done_encoding_14bits( ptr, hPublicData->ptrBitIndex, &hPublicData->acState ); /* finish AC encoding */ + hPublicData->ptrBitIndex = ari_done_encoding_14bits_ivas_fx( ptr, hPublicData->ptrBitIndex, &hPublicData->acState ); /* finish AC encoding */ hPublicData->bitCount = add( hPublicData->bitCount, hPublicData->ptrBitIndex ); move16(); move16(); diff --git a/lib_enc/igf_scf_enc_fx.c b/lib_enc/igf_scf_enc_fx.c index b8125cbd6d408bd4de4d065d72e3fb8e5769580f..8659d53a166cb2a6f155bb85c4f3025c780424a7 100644 --- a/lib_enc/igf_scf_enc_fx.c +++ b/lib_enc/igf_scf_enc_fx.c @@ -45,8 +45,11 @@ void IGFSCFEncoderOpen_fx( set16_fx( hPublicData->prevSave, 0, 64 ); hPublicData->scfCountLongBlock[0] = sub( hIgfInfo->grid[0].swb_offset_len, 1 ); + move16(); hPublicData->scfCountLongBlock[1] = sub( hIgfInfo->grid[1].swb_offset_len, 1 ); + move16(); hPublicData->scfCountLongBlock[2] = sub( hIgfInfo->grid[2].swb_offset_len, 1 ); + move16(); hPublicData->t = 0; move16(); /* protect against the invalid request of starting encoding with a dependent block */ @@ -124,7 +127,7 @@ static void arith_encode_residual( &hPrivateData->acState_fx, x, cumulativeFrequencyTable ); - + move16(); return; } @@ -137,6 +140,7 @@ static void arith_encode_residual( &hPrivateData->acState_fx, 0, cumulativeFrequencyTable ); + move16(); } ELSE /* x > IGF_MAX_ENC_SEPARATE */ { @@ -147,6 +151,7 @@ static void arith_encode_residual( &hPrivateData->acState_fx, IGF_SYMBOLS_IN_TABLE - 1, cumulativeFrequencyTable ); + move16(); } /* encode one of the tails of the distribution */ @@ -216,6 +221,7 @@ static void encode_sfe_vector( &hPrivateData->acState_fx, shr( x[f], 2 ), (const UWord16 *) hPrivateData->cf_se00 ); + move16(); arith_encode_bits( hPrivateData, ptr, s_and( x[f], 3 ), 2 ); /* LSBs as 2 bit raw */ } ELSE IF( EQ_16( f, 1 ) ) @@ -233,7 +239,6 @@ static void encode_sfe_vector( /* (t == 0) && (f >= 2) */ prev_offset = sub( f, 1 ); res = sub( x[f], x[prev_offset] ); - move16(); /* pred = b */ ctx = quant_ctx( sub( x[prev_offset], x[sub( prev_offset, 1 )] ) ); /* Q(b - e) */ /* index1 is (IGF_SYMBOLS_IN_TABLE + 1) * (CTX_OFFSET + ctx) */ index1 = L_mac0( ( IGF_SYMBOLS_IN_TABLE + 1 ) * IGF_CTX_OFFSET, ( IGF_SYMBOLS_IN_TABLE + 1 ), ctx ); @@ -340,12 +345,13 @@ Word16 IGFSCFEncoderEncode_fx( hPublicData->ptrBitIndex, &hPublicData->acState_fx ); /* finish AC encoding */ hPublicData->bitCount = add( hPublicData->bitCount, hPublicData->ptrBitIndex ); - + move16(); + move16(); /* advance history */ Copy( sfe, hPublicData->prev, hPublicData->scfCountLongBlock[igfGridIdx] ); hPublicData->t = add( hPublicData->t, 1 ); - + move16(); /* copy the bits from the temporary bit buffer, if doRealEncoding is enabled */ IF( hBstr ) diff --git a/lib_enc/init_enc.c b/lib_enc/init_enc.c deleted file mode 100644 index e7c66738847aeba5512e56f56b3fb895f45af8a3..0000000000000000000000000000000000000000 --- a/lib_enc/init_enc.c +++ /dev/null @@ -1,1206 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include "cnst.h" -#include "rom_com.h" -#include "rom_enc.h" -#include "prot.h" -#include "ivas_prot.h" -#include "prot_fx.h" -#include "ivas_cnst.h" -#include "wmc_auto.h" -#include "ivas_prot_fx.h" -#include "prot_fx_enc.h" -ivas_error init_encoder_ivas_fx( - Encoder_State *st, /* i/o: state structure */ - Encoder_Struct *st_ivas, /* i/o: encoder state structure */ - const Word16 idchan, /* i : channel ID */ - const Word16 var_SID_rate_flag, /* i : flag for variable SID update rate */ - const Word16 interval_SID, /* i : interval for SID update */ - const Word16 vad_only_flag, /* i : flag to indicate front-VAD structure */ - const ISM_MODE ism_mode, /* i : ISM mode */ - const Word32 element_brate /* i : element bitrate */ -) -{ - Word16 i; - ivas_error error; - Word32 igf_brate; - - error = IVAS_ERR_OK; - move32(); - - /*-----------------------------------------------------------------* - * General parameters - *-----------------------------------------------------------------*/ - - IF( st->Opt_AMR_WB ) - { - st->last_core = AMR_WB_CORE; - } - ELSE - { - st->last_core = -1; - } - move16(); - - st->L_frame = L_FRAME; - move16(); - st->last_coder_type = GENERIC; - move16(); - st->coder_type = GENERIC; - move16(); - st->last_total_brate = st->total_brate; - move32(); - st->last_bits_frame_nominal = -1; - move16(); - st->last_total_brate_cng = -1; - move16(); - st->last_core_brate = st->total_brate; - move32(); - st->dtx_sce_sba = 0; - move16(); - st->extl = -1; - move16(); - st->last_extl = -1; - move16(); - st->last_L_frame = L_FRAME; - move16(); - st->rate_switching_reset = 0; - move16(); - st->rate_switching_reset_16kHz = 0; - move16(); - st->clas = UNVOICED_CLAS; - move16(); - st->low_rate_mode = 0; - move16(); - st->ini_frame = 0; - move16(); - st->inactive_coder_type_flag = 0; - move16(); - st->sba_br_sw_while_no_data = 0; - move16(); - - st->coder_type_raw = VOICED; - move16(); - st->last_coder_type_raw = st->coder_type_raw; - move16(); - - st->flag_ACELP16k = set_ACELP_flag_IVAS( st->element_mode, st->total_brate, st->total_brate, idchan, 0, -1, -1 ); - move16(); - - st->is_ism_format = 0; - move16(); - - IF( NE_16( ism_mode, ISM_MODE_NONE ) ) - { - st->is_ism_format = 1; - move16(); - } - - /*-----------------------------------------------------------------* - * Bitstream - *-----------------------------------------------------------------*/ - - IF( !vad_only_flag ) - { - IF( ( st->hBstr = (BSTR_ENC_HANDLE) malloc( sizeof( BSTR_ENC_DATA ) ) ) == NULL ) - { - return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Bitstream structure\n" ) ); - } - - /* set pointer to the buffer of indices */ - st->hBstr->ind_list = st_ivas->ind_list; - st->hBstr->ivas_ind_list_zero = &st_ivas->ind_list; - st->hBstr->ivas_max_num_indices = &st_ivas->ivas_max_num_indices; - st->hBstr->nb_ind_tot = 0; - move16(); - st->hBstr->nb_bits_tot = 0; - move16(); - st->hBstr->st_ivas = st_ivas; - } - ELSE - { - st->hBstr = NULL; - } - - /*-----------------------------------------------------------------* - * Pre-processing and ACELP core parameters - *-----------------------------------------------------------------*/ - - Copy( GEWB_Ave_fx, st->mem_AR_fx, M ); - Copy( GEWB_Ave_fx, st->lsfoldbfi0_fx, M ); - Copy( GEWB_Ave_fx, st->lsfoldbfi1_fx, M ); - Copy( GEWB_Ave_fx, st->lsf_adaptive_mean_fx, M ); - - st->next_force_safety_net = 0; - move16(); - - st->pstreaklen = 0; - move16(); - st->streaklimit_fx = MAX_WORD16; - move16(); - set16_fx( st->mem_MA_fx, 0, M ); - - init_gp_clip_fx( st->clip_var_fx ); - pitch_ol_init_fx( &st->old_thres_fx, &st->old_pitch, &st->delta_pit, &st->old_corr_fx ); - set16_fx( st->old_wsp_fx, 0, L_WSP_MEM ); - st->exp_old_wsp = 0; - move16(); - set16_fx( st->old_wsp2_fx, 0, ( L_WSP_MEM - L_INTERPOL ) / OPL_DECIM ); // Needs to change depending on usage. - st->Q_old_wsp2 = 0; - move16(); - - st->mem_preemph_fx = 0; - move16(); - st->mem_preemph16k_fx = 0; - move16(); - st->mem_preemph_enc = 0; - move16(); - st->exp_mem_preemph_enc = 0; - move16(); - -#if 1 // TODO: Float Initializations. To be removed later - st->active_cnt = 0; -#endif - - st->pst_mem_deemp_err_fx = 0; - move16(); - st->pst_lp_ener_fx = 0; - move16(); - - /* AVQ pre-quantizer memory */ - st->mem_preemp_preQ_fx = 0; - move16(); - st->mem_deemp_preQ_fx = 0; - move16(); - st->last_nq_preQ = 0; - move16(); - st->last_code_preq = 0; - move16(); - st->use_acelp_preq = 0; - move16(); - st->last_harm_flag_acelp = 0; - move16(); - - /* (Decimated) Weighted Speech Memory */ - st->mem_wsp_enc = 0; - move16(); - st->mem_wsp_fx = 0; - move16(); - st->mem_wsp_q = 0; - move16(); - set16_fx( st->mem_decim2_fx, 0, 3 ); - set32_fx( st->Bin_E_fx, 0, L_FFT ); - st->q_Bin_E = Q31; - move16(); - st->ee_old_fx = 640; /* 10.0f in Q6 */ - move16(); - st->Nb_ACELP_frames = 0; - move16(); - st->audio_frame_cnt = AUDIO_COUNTER_INI; /* Initialization of the audio frame counter mildly into the audio mode */ - move16(); - - /* adaptive lag window memory */ - st->old_pitch_la = 0; - move16(); - - st->prev_Q_new = 0; - move16(); - - IF( EQ_32( st->input_Fs, 8000 ) ) - { - st->min_band = 1; - move16(); - st->max_band = 16; - move16(); - } - ELSE - { - st->min_band = 0; - move16(); - st->max_band = 19; - move16(); - } - - IF( st->Opt_AMR_WB ) - { - Copy( mean_isf_amr_wb_fx, st->lsf_old_fx, M ); - E_LPC_isf_isp_conversion( st->lsf_old_fx, st->lsp_old1_fx, M ); - } - ELSE - { - Copy( GEWB_Ave_fx, st->lsf_old_fx, M ); - lsf2lsp_fx( st->lsf_old_fx, st->lsp_old1_fx, M, INT_FS_12k8 ); - } - - Copy( st->lsf_old_fx, st->lsf_old1_fx, M ); - Copy( st->lsp_old1_fx, st->lsp_old_fx, M ); - Copy( st->lsp_old_fx, st->lsp_old16k_fx, M ); - Copy( st->lsp_old_fx, st->lspold_enc_fx, M ); - - st->stab_fac_fx = 0; - move16(); - - /* Bass post-filter memories - encoder side of MODE2 */ - st->bpf_off = 0; - move16(); - st->pst_mem_deemp_err_fx = 0; - move16(); - st->pst_lp_ener_fx = 0; - move16(); - - /* TC coder type */ - st->tc_cnt = 0; - move16(); - - /* find_uv() parameters */ - st->old_dE1_fx = 0; - move16(); - st->old_ind_deltaMax = 0; - move16(); - set32_fx( st->old_enr_ssf_fx, 0, shl( NB_SSF, 1 ) ); - st->spike_hyst = -1; - move16(); - - /* stereo switching memories */ - st->mem_preemph_DFT_fx = 0; - move16(); - set16_fx( st->inp_12k8_mem_stereo_sw_fx, 0, sub( sub( STEREO_DFT_OVL_12k8, L_MEM_RECALC_12K8 ), L_FILT ) ); - st->mem_preemph16k_DFT_fx = 0; - move16(); - set16_fx( st->inp_16k_mem_stereo_sw_fx, 0, sub( sub( STEREO_DFT_OVL_16k, L_MEM_RECALC_16K ), L_FILT16k ) ); - - st->sharpFlag = 0; - move16(); - - /* Stationary noise UV modification */ - st->ge_sm_fx = L_deposit_l( 640 ); /*Q(GE_SHIFT)*/ - move16(); - st->uv_count = 0; - move16(); - st->act_count = 3; - move16(); - Copy( st->lsp_old_fx, st->lspold_s_fx, M ); - st->noimix_seed = RANDOM_INITSEED; - move16(); - st->min_alpha_fx = 32767; - move16(); - st->exc_pe_fx = 0; - move16(); - st->Q_stat_noise = 15; - move16(); - /* FEC */ - st->last_clas = UNVOICED_CLAS; - move16(); - st->prev_fmerit = 0; - move16(); - st->fmerit_dt = 0; - move16(); - st->Last_pulse_pos = 0; - move16(); - - FOR( i = 0; i < shl( NB_SUBFR16k, 1 ); i++ ) - { - st->old_pitch_buf_fx[i] = L_SUBFR_Q6; - move16(); - } - - /* mode1 core switching */ - st->old_Es_pred_fx = 0; - move16(); - set16_fx( st->old_Aq_12_8_fx + 1, 0, M ); - st->old_Aq_12_8_fx[0] = ONE_IN_Q12; - move16(); - - /* stable short pitch detection */ - st->voicing0_sm_fx = 0; - move16(); - st->voicing_sm_fx = 0; - move16(); - st->LF_EnergyRatio_sm_fx = 1; - move16(); - st->predecision_flag = 0; - move16(); - st->diff_sm_fx = 0; - move32(); - st->energy_sm_fx = 0; - move32(); - - set16_fx( st->pitch, L_SUBFR, 3 ); - set16_fx( st->voicing_fx, 0, 3 ); - - /*-----------------------------------------------------------------* - * General signal buffers - *-----------------------------------------------------------------*/ - - IF( !vad_only_flag ) - { - IF( ( st->hSignalBuf = (SIGNAL_BUFFERS_ENC_HANDLE) malloc( sizeof( SIGNAL_BUFFERS_ENC_DATA ) ) ) == NULL ) - { - return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Signal buffers\n" ) ); - } - - st->Bin_E_old_fx = st->hSignalBuf->Bin_E_old_fx; - st->mem_decim_fx = st->hSignalBuf->mem_decim_fx; - st->mem_decim16k_fx = st->hSignalBuf->mem_decim16k_fx; - st->old_inp_12k8_fx = st->hSignalBuf->old_inp_12k8_fx; - st->old_inp_16k_fx = st->hSignalBuf->old_inp_16k_fx; - st->buf_speech_enc_pe = st->hSignalBuf->buf_speech_enc_pe; - st->buf_synth = st->hSignalBuf->buf_synth; - st->buf_speech_enc = st->hSignalBuf->buf_speech_enc; - st->buf_wspeech_enc = st->hSignalBuf->buf_wspeech_enc; - - set32_fx( st->Bin_E_old_fx, 0, L_FFT / 2 ); - st->q_Bin_E_old = Q31; - set16_fx( st->hSignalBuf->buf_speech_enc, 0, L_PAST_MAX_32k + L_FRAME32k + L_NEXT_MAX_32k ); - st->exp_buf_speech_enc = 0; - move16(); - set16_fx( st->hSignalBuf->buf_wspeech_enc, 0, L_FRAME16k + L_SUBFR + L_FRAME16k + L_NEXT_MAX_16k + 320 ); - st->exp_buf_wspeech_enc = 0; - move16(); - /* initializations */ -#ifndef MSAN_FIX - set32_fx( st->Bin_E_old_fx, 0, shr( L_FFT, 2 ) ); -#else - set32_fx( st->Bin_E_old_fx, 0, L_FFT / 2 ); -#endif - st->q_Bin_E_old = Q31; - move16(); - set16_fx( st->mem_decim_fx, 0, shl( L_FILT_MAX, 1 ) ); - set16_fx( st->mem_decim16k_fx, 0, shl( L_FILT_MAX, 1 ) ); - set16_fx( st->old_inp_12k8_fx, 0, L_INP_MEM ); - set16_fx( st->old_inp_16k_fx, 0, L_INP_MEM ); - st->exp_old_inp_16k = 0; - st->exp_old_inp_12k8 = 0; - move16(); - move16(); - - st->input_buff_fx = st->hSignalBuf->input_buff; - st->input_buff32_fx = st->hSignalBuf->input_buff32; - set16_fx( st->input_buff_fx, 0, add( L_FRAME48k, add( L_FRAME48k, NS2SA( 48000, DELAY_FIR_RESAMPL_NS ) ) ) ); - st->q_inp = Q15; - move16(); - st->q_old_inp = Q15; - move16(); - set32_fx( st->input_buff32_fx, 0, add( L_FRAME48k, add( L_FRAME48k, NS2SA( 48000, DELAY_FIR_RESAMPL_NS ) ) ) ); - st->q_inp32 = Q31; - move16(); - st->old_input_signal_fx = st->input_buff_fx; - /* st->input_Fs / FRAMES_PER_SEC */ - Word16 frame_length = extract_l( Mpy_32_32( st->input_Fs, ONE_BY_FRAMES_PER_SEC_Q31 ) ); - - IF( st->element_mode == EVS_MONO ) - { - st->input32_fx = st->input_buff32_fx + st->input_Fs / FRAMES_PER_SEC + NS2SA_FX2( st->input_Fs, DELAY_FIR_RESAMPL_NS ); - st->input_fx = st->input_buff_fx + add( frame_length, (Word16) NS2SA( st->input_Fs, DELAY_FIR_RESAMPL_NS ) ); - } - ELSE - { - st->input32_fx = st->input_buff32_fx + Mpy_32_32( st->input_Fs, 42949673 ) /* 1/50 in Q31*/; // st->input_Fs / FRAMES_PER_SEC - st->input_fx = st->input_buff_fx + frame_length; - } -#if 1 // TODO: To be removed later -#endif - } - ELSE - { - st->hSignalBuf = NULL; - st->Bin_E_old_fx = NULL; - st->mem_decim_fx = NULL; - st->mem_decim16k_fx = NULL; - st->old_inp_12k8_fx = NULL; - st->old_inp_16k_fx = NULL; - st->buf_speech_enc_pe = NULL; - st->buf_synth = NULL; - st->buf_speech_enc = NULL; - st->buf_wspeech_enc = NULL; - st->input_buff_fx = NULL; -#if 1 -#endif - } - - /*-----------------------------------------------------------------* - * Noise estimator - *-----------------------------------------------------------------*/ - - test(); - test(); - test(); - IF( idchan == 0 || EQ_16( st->element_mode, IVAS_CPE_TD ) || EQ_16( st->element_mode, IVAS_CPE_MDCT ) || st->element_mode == EVS_MONO ) - { - IF( ( st->hNoiseEst = (NOISE_EST_HANDLE) malloc( sizeof( NOISE_EST_DATA ) ) ) == NULL ) - { - return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Noise estimation\n" ); - } - - noise_est_init_ivas_fx( st->hNoiseEst ); - } - ELSE - { - st->hNoiseEst = NULL; - } - - /*-----------------------------------------------------------------* - * VAD - *-----------------------------------------------------------------*/ - - st->vad_flag = 1; - move16(); - st->localVAD = 0; - move16(); - - IF( ( idchan == 0 || EQ_16( st->element_mode, IVAS_CPE_TD ) || EQ_16( st->element_mode, IVAS_CPE_MDCT ) || st->element_mode == EVS_MONO ) && ( !vad_only_flag ) ) - { - IF( ( st->hVAD = (VAD_HANDLE) malloc( sizeof( VAD_DATA ) ) ) == NULL ) - { - return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for VAD\n" ) ); - } - - wb_vad_init_ivas_fx( st->hVAD ); - } - ELSE - { - st->hVAD = NULL; - } - st->Pos_relE_cnt = 20; - move16(); - - /* CLDFB-based VAD */ - IF( st->element_mode == EVS_MONO ) - { - /* This is done to as in EVS T_CldfbVadState structure is present in Encoder State */ - /* - if ( ( st->hVAD_CLDFB = (VAD_CLDFB_HANDLE) malloc( sizeof( T_CldfbVadState ) ) ) == NULL ) - { - return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for CLDFB VAD\n" ) ); - } - */ - st->hVAD_CLDFB = &st->vad_st; - - vad_init_fx( st->hVAD_CLDFB ); - } - ELSE - { - st->hVAD_CLDFB = NULL; - } - - /*-----------------------------------------------------------------* - * Speech/music classifier - *-----------------------------------------------------------------*/ - - IF( idchan == 0 || EQ_16( st->element_mode, IVAS_CPE_TD ) || EQ_16( st->element_mode, IVAS_CPE_MDCT ) || st->element_mode == EVS_MONO ) - { - IF( ( st->hSpMusClas = (SP_MUS_CLAS_HANDLE) malloc( sizeof( SP_MUS_CLAS_DATA ) ) ) == NULL ) - { - return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Speech/music classifier\n" ) ); - } - - speech_music_clas_init_ivas_fx( st->hSpMusClas ); - st->sp_aud_decision0 = 0; - move16(); - st->sp_aud_decision1 = 0; - move16(); - st->sp_aud_decision2 = 0; - move16(); - } - ELSE - { - st->hSpMusClas = NULL; - } - - - /*-----------------------------------------------------------------* - * WB, SWB and FB bandwidth detector - *-----------------------------------------------------------------*/ - - st->lt_mean_NB_fx = 0; - move16(); - st->lt_mean_WB_fx = 0; - move16(); - st->lt_mean_SWB_fx = 0; - move16(); - st->count_WB = BWD_COUNT_MAX; - move16(); - st->count_SWB = BWD_COUNT_MAX; - move16(); - st->count_FB = BWD_COUNT_MAX; - move16(); - st->bwidth = st->max_bwidth; - move16(); - st->last_input_bwidth = st->bwidth; - move16(); - st->last_bwidth = st->bwidth; - move16(); - st->last_bwidth_cng = st->bwidth; - move16(); - st->bwidth_sw_cnt = 0; - move16(); - - - /*-----------------------------------------------------------------* - * DTX - *-----------------------------------------------------------------*/ - - st->lp_speech_fx = 11520; /*Q8 (45.0) */ /* Initialize the long-term active speech level in dB */ - move16(); - st->lp_noise_fx = 0; - move16(); - st->flag_noisy_speech_snr = 0; - move16(); - st->fd_cng_reset_flag = 0; - move16(); - st->cng_type = -1; - move16(); - st->bckr_tilt_lt = 0; - move16(); - st->active_cnt = 0; - move16(); - - test(); - test(); - test(); - test(); - IF( ( ( idchan == 0 && st->Opt_DTX_ON ) || st->element_mode == EVS_MONO ) || ( EQ_16( st->element_mode, IVAS_CPE_MDCT ) && st->Opt_DTX_ON ) ) - { - IF( ( st->hDtxEnc = (DTX_ENC_HANDLE) malloc( sizeof( DTX_ENC_DATA ) ) ) == NULL ) - { - return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DTX variables\n" ) ); - } - dtx_enc_init_fx( st, var_SID_rate_flag, interval_SID ); - } - ELSE - { - st->hDtxEnc = NULL; - } - - /*-----------------------------------------------------------------* - * No other handles needed to be allocated for front-VAD structure - *-----------------------------------------------------------------*/ - - IF( vad_only_flag ) - { - st->hTdCngEnc = NULL; - st->cldfbAnaEnc = NULL; - st->hFdCngEnc = NULL; - st->hSC_VBR = NULL; - st->hAmrwb_IO = NULL; - st->hLPDmem = NULL; - st->hGSCEnc = NULL; - st->hBWE_TD = NULL; - st->cldfbSynTd = NULL; - st->hBWE_FD = NULL; - st->hHQ_core = NULL; - st->hRF = NULL; - st->hTECEnc = NULL; - st->hTcxEnc = NULL; - st->hTcxCfg = NULL; - st->hIGFEnc = NULL; - st->hPlcExt = NULL; - st->hTranDet = NULL; - - st->element_mode = IVAS_SCE; - move16(); - st->idchan = 100; /* indicates hCoreCoderVAD */ - move16(); - st->core = -1; - move16(); - st->rf_mode = 0; - move16(); - - return error; - } - - /*-----------------------------------------------------------------* - * LP-CNG - *-----------------------------------------------------------------*/ - - test(); - test(); - test(); - test(); - test(); - IF( ( ( idchan == 0 && st->Opt_DTX_ON && NE_16( st->element_mode, IVAS_CPE_MDCT ) ) || st->element_mode == EVS_MONO ) && !( EQ_16( ism_mode, ISM_MODE_PARAM ) || EQ_16( ism_mode, ISM_MODE_DISC ) ) ) - { - IF( ( st->hTdCngEnc = (TD_CNG_ENC_HANDLE) malloc( sizeof( TD_CNG_ENC_DATA ) ) ) == NULL ) - { - return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DTX/TD CNG\n" ) ); - } - - td_cng_enc_init_ivas_fx( st->hTdCngEnc, st->Opt_DTX_ON, st->max_bwidth ); - } - ELSE - { - st->hTdCngEnc = NULL; - } - - /*-----------------------------------------------------------------* - * CLDFB & resampling tools parameters - *-----------------------------------------------------------------*/ - test(); - test(); - test(); - IF( ( NE_16( st->element_mode, IVAS_CPE_MDCT ) && idchan == 0 ) || ( EQ_16( st->element_mode, IVAS_CPE_MDCT ) && st->Opt_DTX_ON ) ) - { - IF( ( error = openCldfb_ivas_enc( &st->cldfbAnaEnc, CLDFB_ANALYSIS, st->input_Fs, CLDFB_PROTOTYPE_1_25MS ) ) != IVAS_ERR_OK ) - { - return error; - } - } - ELSE - { - st->cldfbAnaEnc = NULL; - } - - st->energyCoreLookahead_Fx = 2; /* 6.1e-5f in Q15 */ - move32(); - st->sf_energyCoreLookahead_Fx = 2; /* 6.1e-5f in Q15 */ - move16(); - - /*-----------------------------------------------------------------* - * SC-VBR parameters - *-----------------------------------------------------------------*/ - - test(); - IF( st->Opt_SC_VBR || st->element_mode == EVS_MONO ) - { - IF( ( st->hSC_VBR = (SC_VBR_ENC_HANDLE) malloc( sizeof( SC_VBR_ENC_DATA ) ) ) == NULL ) - { - return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for SC-VBR\n" ) ); - } - - sc_vbr_enc_init_fx( st->hSC_VBR ); - } - ELSE - { - st->hSC_VBR = NULL; - } - - st->last_Opt_SC_VBR = 0; - move16(); - - - /*-----------------------------------------------------------------* - * AMR-WB IO initialization - *-----------------------------------------------------------------*/ - - test(); - IF( st->Opt_AMR_WB || st->element_mode == EVS_MONO ) - { - IF( ( st->hAmrwb_IO = (AMRWB_IO_ENC_HANDLE) malloc( sizeof( AMRWB_IO_ENC_DATA ) ) ) == NULL ) - { - return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for AMR-WB IO\n" ) ); - } - - amr_wb_enc_init_fx( st->hAmrwb_IO ); - } - ELSE - { - st->hAmrwb_IO = NULL; - } - - /*-----------------------------------------------------------------* - * ACELP LPDmem - *-----------------------------------------------------------------*/ - - test(); - test(); - IF( ( idchan == 0 && NE_16( st->element_mode, IVAS_CPE_MDCT ) ) || EQ_16( st->element_mode, IVAS_CPE_TD ) ) - { - IF( ( st->hLPDmem = (LPD_state_HANDLE) malloc( sizeof( LPD_state ) ) ) == NULL ) - { - return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LPDmem\n" ) ); - } - - LPDmem_enc_init_ivas_fx( st->hLPDmem ); - } - ELSE - { - st->hLPDmem = NULL; - } - - /*-----------------------------------------------------------------* - * parameters for AC coder type (GSC) - *-----------------------------------------------------------------*/ - - st->GSC_noisy_speech = 0; - move16(); - st->GSC_IVAS_mode = 0; - move16(); - - test(); - test(); - IF( ( idchan == 0 && NE_16( st->element_mode, IVAS_CPE_MDCT ) ) || EQ_16( st->element_mode, IVAS_CPE_TD ) ) - { - IF( ( st->hGSCEnc = (GSC_ENC_HANDLE) malloc( sizeof( GSC_ENC_DATA ) ) ) == NULL ) - { - return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for GSC\n" ) ); - } - - GSC_enc_init_fx( st->hGSCEnc ); - } - ELSE - { - st->hGSCEnc = NULL; - } - - /*-----------------------------------------------------------------* - * TBE parameters - *-----------------------------------------------------------------*/ - - test(); - IF( idchan == 0 && NE_16( st->element_mode, IVAS_CPE_MDCT ) ) - { - IF( ( st->hBWE_TD = (TD_BWE_ENC_HANDLE) malloc( sizeof( TD_BWE_ENC_DATA ) ) ) == NULL ) - { - return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for TD BWE\n" ) ); - } - - IF( ( error = openCldfb_ivas_enc( &st->cldfbSynTd, CLDFB_SYNTHESIS, 16000, CLDFB_PROTOTYPE_1_25MS ) ) != IVAS_ERR_OK ) - { - return error; - } - - InitSWBencBuffer_ivas_fx( st ); - ResetSHBbuffer_Enc_fx( st ); - } - ELSE - { - st->hBWE_TD = NULL; - st->cldfbSynTd = NULL; - } - - /*-----------------------------------------------------------------* - * SWB BWE parameters - *-----------------------------------------------------------------*/ - - test(); - IF( idchan == 0 && NE_16( st->element_mode, IVAS_CPE_MDCT ) ) - { - IF( ( st->hBWE_FD = (FD_BWE_ENC_HANDLE) malloc( sizeof( FD_BWE_ENC_DATA ) ) ) == NULL ) - { - return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for FD BWE\n" ) ); - } - - fd_bwe_enc_init_fx( st->hBWE_FD ); -#ifdef MSAN_FIX - st->Q_old_wtda = 0; - move16(); -#endif - } - ELSE - { - st->hBWE_FD = NULL; - } - - /*-----------------------------------------------------------------* - * HQ core parameters - *-----------------------------------------------------------------*/ - - IF( NE_16( st->element_mode, IVAS_CPE_TD ) && NE_16( st->element_mode, IVAS_CPE_MDCT ) && idchan == 0 ) - { - IF( ( st->hHQ_core = (HQ_ENC_HANDLE) malloc( sizeof( HQ_ENC_DATA ) ) ) == NULL ) - { - return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for HQ core\n" ) ); - } - - HQ_core_enc_init_fx( st->hHQ_core ); - } - ELSE - { - st->hHQ_core = NULL; - } - - /* init memory for detect_transient(), used by HQ core and swb_bwe_enc */ - st->old_hpfilt_in_fx = 0; - move16(); - st->old_hpfilt_out_fx = 0; - move16(); - st->EnergyLT_fx = 0; - move32(); - st->Energy_Old_fx = 0; - move32(); - st->TransientHangOver = 0; - move16(); - st->EnergyLT_fx_exp = 30; - move16(); - st->last_enerBuffer_exp = 0; - move16(); - - /*-----------------------------------------------------------------* - * Channel-aware mode - *-----------------------------------------------------------------*/ - - test(); - test(); - test(); - IF( !st->Opt_RF_ON || ( NE_16( st->bwidth, WB ) && NE_16( st->bwidth, SWB ) ) || NE_32( st->total_brate, ACELP_13k20 ) ) - { - st->rf_mode = 0; - move16(); - } - ELSE - { - st->rf_mode = st->Opt_RF_ON; - move16(); - } - - st->rf_mode_last = st->rf_mode; - move16(); - - test(); - IF( st->Opt_RF_ON || st->element_mode == EVS_MONO ) - { - IF( ( st->hRF = (RF_ENC_HANDLE) malloc( sizeof( RF_ENC_DATA ) ) ) == NULL ) - { - return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for RF\n" ) ); - } - - /* initialize RF indice buffers */ - reset_rf_indices_fx( st ); - } - ELSE - { - st->hRF = NULL; - } - - /*-----------------------------------------------------------------* - * Temporal Envelope Coding - *-----------------------------------------------------------------*/ - - IF( st->element_mode == EVS_MONO ) - { - IF( ( st->hTECEnc = (TEC_ENC_HANDLE) malloc( sizeof( TEC_ENC_DATA ) ) ) == NULL ) - { - return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for TEC\n" ) ); - } - } - ELSE - { - st->hTECEnc = NULL; - } - /* note: initialization done later in init_coder_ace_plus() */ - - /*-----------------------------------------------------------------* - * TCX core - *-----------------------------------------------------------------*/ - - // ToDo: reduction possible for MCT_CHAN_MODE_LFE channel - test(); - IF( idchan == 0 || EQ_16( st->element_mode, IVAS_CPE_MDCT ) ) - { - IF( ( st->hTcxEnc = (TCX_ENC_HANDLE) malloc( sizeof( TCX_ENC_DATA ) ) ) == NULL ) - { - return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for hTcxEnc\n" ) ); - } - set32_fx( st->hTcxEnc->spectrum_long_fx, 0, N_MAX ); - st->hTcxEnc->spectrum_long_e = 0; - - /* Share the memories for 2xTCX10/4xTCX5 and for TCX20 */ - st->hTcxEnc->spectrum_fx[0] = st->hTcxEnc->spectrum_long_fx; - st->hTcxEnc->spectrum_fx[1] = st->hTcxEnc->spectrum_long_fx + N_TCX10_MAX; - st->hTcxEnc->spectrum_e[0] = st->hTcxEnc->spectrum_e[1] = 0; - move16(); - move16(); -#if 1 - // set_f( st->hTcxEnc->spectrum_long, 0, N_MAX ); - // st->hTcxEnc->spectrum[0] = st->hTcxEnc->spectrum_long; - // st->hTcxEnc->spectrum[1] = st->hTcxEnc->spectrum_long + N_TCX10_MAX; - // set_f( st->hTcxEnc->old_out, 0, L_FRAME32k ); -#endif - - set16_fx( st->hTcxEnc->old_out_fx, 0, L_FRAME32k ); - st->hTcxEnc->Q_old_out = 0; - move16(); - - /* MDCT selector */ - MDCT_selector_reset_fx( st->hTcxEnc ); - - /* MDCT classifier */ - MDCT_classifier_reset_fx( st->hTcxEnc ); - - IF( ( st->hTcxCfg = (TCX_CONFIG_HANDLE) malloc( sizeof( TCX_config ) ) ) == NULL ) - { - return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for hTcxCfg\n" ) ); - } - } - ELSE - { - st->hTcxEnc = NULL; - st->hTcxCfg = NULL; - } - - /*-----------------------------------------------------------------* - * IGF - *-----------------------------------------------------------------*/ - - igf_brate = st->total_brate; - move32(); - - test(); - test(); - test(); - test(); - test(); - test(); - test(); - IF( EQ_16( st->element_mode, IVAS_SCE ) && ( EQ_16( st_ivas->hEncoderConfig->ivas_format, ISM_FORMAT ) || EQ_16( st_ivas->hEncoderConfig->ivas_format, MASA_ISM_FORMAT ) ) ) - { - igf_brate = L_sub( st->total_brate, i_mult( ISM_NB_BITS_METADATA_NOMINAL, FRAMES_PER_SEC ) ); - } - ELSE IF( EQ_16( st->element_mode, IVAS_CPE_DFT ) || ( EQ_16( st->element_mode, IVAS_SCE ) && ( EQ_16( st_ivas->hEncoderConfig->ivas_format, SBA_FORMAT ) || - EQ_16( st_ivas->hEncoderConfig->ivas_format, SBA_ISM_FORMAT ) || - EQ_16( st_ivas->hEncoderConfig->ivas_format, MC_FORMAT ) || - EQ_16( st_ivas->hEncoderConfig->ivas_format, MASA_FORMAT ) ) ) ) - { - /* use nominal bitrates for DFT Stereo and (O)SBA, same as in stereo_dft_config()/ivas_spar_config() */ - IF( EQ_32( element_brate, IVAS_13k2 ) ) - { - igf_brate = ACELP_9k60; - } - ELSE IF( EQ_32( element_brate, IVAS_16k4 ) ) - { - igf_brate = ACELP_13k20; - } - ELSE IF( EQ_32( element_brate, IVAS_24k4 ) ) - { - igf_brate = ACELP_16k40; - } - ELSE IF( EQ_32( element_brate, IVAS_32k ) ) - { - igf_brate = ACELP_24k40; - } - } - ELSE IF( EQ_16( st->element_mode, IVAS_CPE_MDCT ) ) - { - igf_brate = element_brate; - } - move32(); - - IF( EQ_16( st->codec_mode, MODE2 ) || GT_16( st->element_mode, EVS_MONO ) ) - { - st->igf = getIgfPresent_fx( st->element_mode, igf_brate, st->max_bwidth, st->rf_mode ); - } - ELSE - { - st->igf = 0; - } - move16(); - - test(); - test(); - test(); - IF( ( idchan == 0 || EQ_16( st->element_mode, IVAS_CPE_MDCT ) ) && ( st->igf || st->element_mode == EVS_MONO ) ) - { - IF( ( st->hIGFEnc = (IGF_ENC_INSTANCE_HANDLE) malloc( sizeof( IGF_ENC_INSTANCE ) ) ) == NULL ) - { - return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for hIGFEnc\n" ) ); - } - } - ELSE - { - st->hIGFEnc = NULL; - } - - /*-----------------------------------------------------------------* - * Mode 2 initialization - *-----------------------------------------------------------------*/ - - st->last_sr_core = L_mult0( st->last_L_frame, FRAMES_PER_SEC ); - move32(); - - - /* PLC encoder */ - IF( st->element_mode == EVS_MONO ) - { - IF( ( st->hPlcExt = (PLC_ENC_EVS_HANDLE) malloc( sizeof( PLC_ENC_EVS ) ) ) == NULL ) - { - return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for hPlcExt\n" ) ); - } - } - ELSE - { - st->hPlcExt = NULL; - } - - /* Init Mode 2 core coder */ - st->last_totalNoise_fx = 0; - move16(); - set16_fx( st->totalNoise_increase_hist_fx, 0, TOTALNOISE_HIST_SIZE ); - st->totalNoise_increase_len = 0; - move16(); -#ifdef IVAS_FLOAT_FIXED_CONVERSIONS - TCX_ENC_HANDLE hTcxEnc = st->hTcxEnc; - IF( hTcxEnc != NULL ) - { - hTcxEnc->L_frameTCX = extract_l( Mult_32_16( st->input_Fs, 0x0290 ) ); /* 0x0290 is 1/FRAMES_PER_SEC in Q15*/ - move16(); - } - st->currEnergyHF_fx = 0; - move32(); - -#ifdef MSAN_FIX - st->prevEnergyHF_fx = 0; - move32(); -#endif - - /* Initialize TCX */ - - /* Initialize Signal Buffers */ - Word16 shift = getScaleFactor16( st->old_inp_16k_fx, L_INP_MEM ); - Scale_sig( st->old_inp_16k_fx, L_INP_MEM, shift ); - st->exp_old_inp_16k = sub( st->exp_old_inp_16k, shift ); - move16(); - shift = getScaleFactor16( st->old_inp_12k8_fx, L_INP_MEM ); - Scale_sig( st->old_inp_12k8_fx, L_INP_MEM, shift ); - st->exp_old_inp_12k8 = sub( st->exp_old_inp_12k8, shift ); - move16(); - /* Initialize ACELP */ -#endif - init_coder_ace_plus_ivas_fx( st, st->last_total_brate, 0 ); - - IF( st->hLPDmem != NULL ) - { - st->hLPDmem->q_lpd_old_exc = st->prev_Q_new; - move16(); - } - /*-----------------------------------------------------------------* - * FD-CNG encoder - *-----------------------------------------------------------------*/ - - test(); - test(); - test(); - test(); - IF( ( idchan == 0 && st->Opt_DTX_ON ) || st->element_mode == EVS_MONO || ( EQ_16( st->element_mode, IVAS_CPE_MDCT ) && st->Opt_DTX_ON ) ) - { - createFdCngEnc_fx( &st->hFdCngEnc ); - initFdCngEnc_fx( st->hFdCngEnc, st->input_Fs, st->cldfbAnaEnc->scale ); - /* initialization for IVAS modes happens in first frame pre-processing */ - IF( st->element_mode == EVS_MONO ) - { - Word32 total_brate; - - test(); - IF( st->rf_mode && EQ_32( st->total_brate, ACELP_13k20 ) ) - { - total_brate = ACELP_9k60; - move32(); - } - ELSE - { - total_brate = st->total_brate; - move32(); - } - - configureFdCngEnc_ivas_fx( st->hFdCngEnc, st->bwidth, total_brate ); - } - } - ELSE - { - st->hFdCngEnc = NULL; - } - - /*-----------------------------------------------------------------* - * Transient detector - *-----------------------------------------------------------------*/ - - IF( ( st->hTranDet = (TRAN_DET_HANDLE) malloc( sizeof( TRAN_DET_DATA ) ) ) == NULL ) - { - return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Transient Detection\n" ) ); - } - Word16 temp; - Word16 frame_length = BASOP_Util_Divide3232_Scale( st->input_Fs, FRAMES_PER_SEC, &temp ); - frame_length = shr( frame_length, sub( 15, temp ) ); - - IF( GT_16( st->element_mode, EVS_MONO ) ) - { - InitTransientDetection_ivas_fx( frame_length, 0, st->hTranDet, 1 ); - } - ELSE - { - InitTransientDetection_ivas_fx( frame_length, NS2SA_FX2( st->input_Fs, DELAY_FIR_RESAMPL_NS ), st->hTranDet, 0 ); - } - - /*-----------------------------------------------------------------* - * IVAS parameters - *-----------------------------------------------------------------*/ - - st->tdm_LRTD_flag = 0; - move16(); - st->cng_sba_flag = 0; - move16(); - st->bits_frame_channel = 0; - move16(); - st->side_bits_frame_channel = 0; - move16(); - st->Q_syn2 = 0; - move16(); - st->Q_syn = 0; - move16(); - set16_fx( st->Q_max, Q_MAX, L_Q_MEM ); - set16_fx( st->Q_max_16k, Q_MAX, L_Q_MEM ); - st->Q_old = 15; - move16(); - st->old_wsp_max = 0; - move16(); - st->old_wsp_shift = 0; - move16(); - st->sharpFlag = 0; - move16(); - - return error; -} - - -/*-----------------------------------------------------------------------* - * destroy_cldfb_encoder() - * - * Free memory which was allocated in init_encoder() - *-----------------------------------------------------------------------*/ - -void destroy_cldfb_encoder_fx( - Encoder_State *st /* i/o: Encoder static variables structure */ -) -{ - deleteCldfb_ivas_fx( &st->cldfbSynTd ); - deleteCldfb_ivas_fx( &st->cldfbAnaEnc ); - - deleteFdCngEnc_fx( &st->hFdCngEnc ); - - return; -} diff --git a/lib_enc/init_enc_fx.c b/lib_enc/init_enc_fx.c index 73cade783bee614191653c6063f6cec8754593e6..ebfd9c4a26ea5c93a35999c9c361dceb418f6a25 100644 --- a/lib_enc/init_enc_fx.c +++ b/lib_enc/init_enc_fx.c @@ -1,4 +1,4 @@ -/*==================================================================================== +/*==================================================================================== EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0 ====================================================================================*/ @@ -12,6 +12,7 @@ #include "ivas_error.h" #include "prot_fx.h" /* Function prototypes */ #include "prot_fx_enc.h" /* Function prototypes */ +#include "ivas_prot_fx.h" /*-----------------------------------------------------------------------* @@ -29,11 +30,12 @@ ivas_error init_encoder_fx( Word16 idchan = 0; /* i : channel ID */ Word16 vad_only_flag = 0; /* i : channel ID */ + move16(); + move16(); ISM_MODE ism_mode = ISM_MODE_NONE; ivas_error error; - // PMT("ism_mode, idchan, vad_only_flag to be move to function header") - error = IVAS_ERR_OK; + error = IVAS_ERR_OK; /*-----------------------------------------------------------------* * General signal buffers @@ -69,7 +71,7 @@ ivas_error init_encoder_fx( st_fx->old_input_signal_fx = st_fx->input_buff_fx; IF( EQ_16( st_fx->element_mode, EVS_MONO ) ) { - st_fx->input_fx = st_fx->input_buff_fx + st_fx->input_Fs / FRAMES_PER_SEC + NS2SA( st_fx->input_Fs, DELAY_FIR_RESAMPL_NS ); + st_fx->input_fx = st_fx->input_buff_fx + st_fx->input_Fs / FRAMES_PER_SEC + NS2SA_FX2( st_fx->input_Fs, DELAY_FIR_RESAMPL_NS ); } ELSE { @@ -97,7 +99,7 @@ ivas_error init_encoder_fx( st_fx->last_core = -1; move16(); - IF( st_fx->Opt_AMR_WB ) + if ( st_fx->Opt_AMR_WB ) { st_fx->last_core = AMR_WB_CORE; move16(); @@ -134,16 +136,6 @@ ivas_error init_encoder_fx( { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Bitstream structure\n" ) ); } -#ifdef IVAS_CODE_BITSTREAM - - /* set pointer to the buffer of indices */ - st->hBstr->ind_list = st_ivas->ind_list; - st->hBstr->ivas_ind_list_zero = &st_ivas->ind_list; - st->hBstr->ivas_max_num_indices = &st_ivas->ivas_max_num_indices; - st->hBstr->nb_ind_tot = 0; - st->hBstr->nb_bits_tot = 0; - st->hBstr->st_ivas = st_ivas; -#endif } ELSE { @@ -157,7 +149,7 @@ ivas_error init_encoder_fx( Copy( GEWB_Ave_fx, st_fx->lsf_adaptive_mean_fx, M ); init_lvq_fx( st_fx->offset_scale1_fx, st_fx->offset_scale2_fx, st_fx->offset_scale1_p_fx, st_fx->offset_scale2_p_fx, st_fx->no_scales_fx, st_fx->no_scales_p_fx ); st_fx->next_force_safety_net = 0; - + move16(); st_fx->pstreaklen = 0; move16(); st_fx->streaklimit_fx = 32767; @@ -297,7 +289,7 @@ ivas_error init_encoder_fx( // st_fx->GSC_noisy_speech = 0; st_fx->GSC_IVAS_mode = 0; - + move16(); test(); test(); IF( ( idchan == 0 && NE_16( st_fx->element_mode, IVAS_CPE_MDCT ) ) || EQ_16( st_fx->element_mode, IVAS_CPE_TD ) ) @@ -350,7 +342,7 @@ ivas_error init_encoder_fx( test(); test(); test(); - IF( ( idchan == 0 || EQ_16( st_fx->element_mode, IVAS_CPE_TD ) || EQ_16( st_fx->element_mode, IVAS_CPE_MDCT ) || EQ_16( st_fx->element_mode, EVS_MONO ) ) && ( !vad_only_flag ) ) + IF( ( idchan == 0 || EQ_16( st_fx->element_mode, IVAS_CPE_TD ) || EQ_16( st_fx->element_mode, IVAS_CPE_MDCT ) || st_fx->element_mode == EVS_MONO ) && ( !vad_only_flag ) ) { if ( ( st_fx->hVAD = (VAD_HANDLE) malloc( sizeof( VAD_DATA ) ) ) == NULL ) { @@ -386,7 +378,7 @@ ivas_error init_encoder_fx( st_fx->hVAD->L_snr_sum_vad_fx = 0; move32(); } - else + ELSE { st_fx->hVAD = NULL; } @@ -403,8 +395,10 @@ ivas_error init_encoder_fx( /*-----------------------------------------------------------------* * Noise estimator *-----------------------------------------------------------------*/ - // PMT("deal with idchan ") - IF( /*idchan == 0 ||*/ EQ_16( st_fx->element_mode, IVAS_CPE_TD ) || EQ_16( st_fx->element_mode, IVAS_CPE_MDCT ) || EQ_16( st_fx->element_mode, EVS_MONO ) ) + + test(); + test(); + IF( /*idchan == 0 ||*/ EQ_16( st_fx->element_mode, IVAS_CPE_TD ) || EQ_16( st_fx->element_mode, IVAS_CPE_MDCT ) || st_fx->element_mode == EVS_MONO ) { if ( ( st_fx->hNoiseEst = (NOISE_EST_HANDLE) malloc( sizeof( NOISE_EST_DATA ) ) ) == NULL ) { @@ -422,7 +416,8 @@ ivas_error init_encoder_fx( *-----------------------------------------------------------------*/ test(); test(); - IF( idchan == 0 || EQ_16( st_fx->element_mode, IVAS_CPE_TD ) || EQ_16( st_fx->element_mode, IVAS_CPE_MDCT ) || EQ_16( st_fx->element_mode, EVS_MONO ) ) + test(); + IF( idchan == 0 || EQ_16( st_fx->element_mode, IVAS_CPE_TD ) || EQ_16( st_fx->element_mode, IVAS_CPE_MDCT ) || st_fx->element_mode == EVS_MONO ) { IF( ( st_fx->hSpMusClas = (SP_MUS_CLAS_HANDLE) malloc( sizeof( SP_MUS_CLAS_DATA ) ) ) == NULL ) { @@ -472,7 +467,7 @@ ivas_error init_encoder_fx( move16(); st_fx->coder_type_raw = VOICED; st_fx->last_coder_type_raw = st_fx->coder_type_raw; - + move16(); st_fx->is_ism_format = 0; move16(); if ( NE_16( ism_mode, ISM_MODE_NONE ) ) @@ -531,6 +526,8 @@ ivas_error init_encoder_fx( * LP-CNG *-----------------------------------------------------------------*/ + test(); + test(); test(); test(); test(); @@ -622,7 +619,7 @@ ivas_error init_encoder_fx( * SC-VBR parameters *-----------------------------------------------------------------*/ test(); - IF( st_fx->Opt_SC_VBR || EQ_16( st_fx->element_mode, EVS_MONO ) ) + IF( st_fx->Opt_SC_VBR || st_fx->element_mode == EVS_MONO ) { IF( ( st_fx->hSC_VBR = (SC_VBR_ENC_HANDLE) malloc( sizeof( SC_VBR_ENC_DATA ) ) ) == NULL ) { @@ -636,7 +633,7 @@ ivas_error init_encoder_fx( st_fx->hSC_VBR = NULL; } /* PLC encoder */ - IF( EQ_16( st_fx->element_mode, EVS_MONO ) ) + IF( st_fx->element_mode == EVS_MONO ) { IF( ( st_fx->hPlcExt = (PLC_ENC_EVS_HANDLE) malloc( sizeof( PLC_ENC_EVS ) ) ) == NULL ) { @@ -710,8 +707,8 @@ ivas_error init_encoder_fx( // st_fx->cldfbSynTd = NULL; } - - IF( st_fx->Opt_RF_ON || EQ_16( st_fx->element_mode, EVS_MONO ) ) + test(); + IF( st_fx->Opt_RF_ON || st_fx->element_mode == EVS_MONO ) { IF( ( st_fx->hRF = (RF_ENC_HANDLE) malloc( sizeof( RF_ENC_DATA ) ) ) == NULL ) { @@ -752,6 +749,7 @@ ivas_error init_encoder_fx( *-----------------------------------------------------------------*/ // VE: reduction possible for MCT_CHAN_MODE_LFE channel - see I1-172 + test(); IF( idchan == 0 || EQ_16( st_fx->element_mode, IVAS_CPE_MDCT ) ) { IF( ( st_fx->hTcxEnc = (TCX_ENC_HANDLE) malloc( sizeof( TCX_ENC_DATA ) ) ) == NULL ) @@ -768,7 +766,7 @@ ivas_error init_encoder_fx( set16_fx( st_fx->hTcxEnc->old_out_fx, 0, L_FRAME32k ); st_fx->hTcxEnc->Q_old_out = 0; - + move16(); /* MDCT selector */ MDCT_selector_reset_fx( st_fx->hTcxEnc ); st_fx->hTcxEnc->Q_old_out = 0; @@ -782,7 +780,7 @@ ivas_error init_encoder_fx( return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for hTcxCfg\n" ) ); } } - else + ELSE { st_fx->hTcxEnc = NULL; // st_fx->hTcxCfg = NULL; @@ -838,7 +836,7 @@ ivas_error init_encoder_fx( move16(); } st_fx->rf_mode_last = st_fx->rf_mode; - + move16(); /* initialize RF indice buffers */ reset_rf_indices_fx( st_fx ); @@ -847,12 +845,11 @@ ivas_error init_encoder_fx( *-----------------------------------------------------------------*/ st_fx->last_sr_core = i_mult2( st_fx->last_L_frame, 50 ); - + move16(); /*-----------------------------------------------------------------* * IGF *-----------------------------------------------------------------*/ - test(); test(); IF( idchan == 0 || EQ_16( st_fx->element_mode, IVAS_CPE_MDCT ) ) { @@ -901,9 +898,6 @@ ivas_error init_encoder_fx( NS2SA_FX2( st_fx->input_Fs, DELAY_FIR_RESAMPL_NS ), &st_fx->transientDetection ); - // reset_indices_enc_fx( st_fx->hBstr); - - st_fx->Q_syn2 = 0; move16(); st_fx->Q_syn = 0; @@ -919,15 +913,23 @@ ivas_error init_encoder_fx( st_fx->sharpFlag = 0; move16(); - st_fx->tdm_LRTD_flag = 0; /* LRTD stereo mode flag */ - st_fx->cna_dirac_flag = 0; /* CNA in DirAC flag */ - st_fx->cng_sba_flag = 0; /* CNG in SBA flag */ - st_fx->GSC_IVAS_mode = 0; /* CNG in SBA flag */ - st_fx->element_mode = EVS_MONO; /* element mode */ + st_fx->tdm_LRTD_flag = 0; /* LRTD stereo mode flag */ + move16(); + st_fx->cna_dirac_flag = 0; /* CNA in DirAC flag */ + move16(); + st_fx->cng_sba_flag = 0; /* CNG in SBA flag */ + move16(); + st_fx->GSC_IVAS_mode = 0; /* CNG in SBA flag */ + move16(); + st_fx->element_mode = EVS_MONO; /* element mode */ + move16(); st_fx->last_element_mode = st_fx->element_mode; /* element mode */ - st_fx->element_brate = -1; /* element bitrate */ - // PMT("element_mode and element_brate should be initialized at a proper place in ivas_dec_init eventually") - st_fx->low_rate_mode = 0; /* low-rate mode flag */ + move16(); + st_fx->element_brate = -1; /* element bitrate */ + move32(); + // PMT("element_mode and element_brate should be initialized at a proper place in ivas_dec_init eventually") + st_fx->low_rate_mode = 0; /* low-rate mode flag */ + move16(); // st_fx->coder_type = GENERIC; /* low-rate mode flag */ set16_fx( st_fx->pitch, L_SUBFR, 3 ); @@ -936,10 +938,12 @@ ivas_error init_encoder_fx( #ifdef DEBUGGING st_fx->id_element = -1; /* element ID */ + move16(); #endif - st_fx->extl_orig = -1; /* extension layer */ + st_fx->extl_orig = -1; /* extension layer */ + move16(); st_fx->extl_brate_orig = 0; /* extension layer bitrate */ - + move32(); return error; } /*-----------------------------------------------------------------------* @@ -1043,3 +1047,1171 @@ void destroy_encoder_fx( return; } + +ivas_error init_encoder_ivas_fx( + Encoder_State *st, /* i/o: state structure */ + Encoder_Struct *st_ivas, /* i/o: encoder state structure */ + const Word16 idchan, /* i : channel ID */ + const Word16 var_SID_rate_flag, /* i : flag for variable SID update rate */ + const Word16 interval_SID, /* i : interval for SID update */ + const Word16 vad_only_flag, /* i : flag to indicate front-VAD structure */ + const ISM_MODE ism_mode, /* i : ISM mode */ + const Word32 element_brate /* i : element bitrate */ +) +{ + Word16 i; + ivas_error error; + Word32 igf_brate; + + error = IVAS_ERR_OK; + move32(); + + /*-----------------------------------------------------------------* + * General parameters + *-----------------------------------------------------------------*/ + + IF( st->Opt_AMR_WB ) + { + st->last_core = AMR_WB_CORE; + } + ELSE + { + st->last_core = -1; + } + move16(); + + st->L_frame = L_FRAME; + move16(); + st->last_coder_type = GENERIC; + move16(); + st->coder_type = GENERIC; + move16(); + st->last_total_brate = st->total_brate; + move32(); + st->last_bits_frame_nominal = -1; + move16(); + st->last_total_brate_cng = -1; + move16(); + st->last_core_brate = st->total_brate; + move32(); + st->dtx_sce_sba = 0; + move16(); + st->extl = -1; + move16(); + st->last_extl = -1; + move16(); + st->last_L_frame = L_FRAME; + move16(); + st->rate_switching_reset = 0; + move16(); + st->rate_switching_reset_16kHz = 0; + move16(); + st->clas = UNVOICED_CLAS; + move16(); + st->low_rate_mode = 0; + move16(); + st->ini_frame = 0; + move16(); + st->inactive_coder_type_flag = 0; + move16(); + st->sba_br_sw_while_no_data = 0; + move16(); + + st->coder_type_raw = VOICED; + move16(); + st->last_coder_type_raw = st->coder_type_raw; + move16(); + + st->flag_ACELP16k = set_ACELP_flag_IVAS( st->element_mode, st->total_brate, st->total_brate, idchan, 0, -1, -1 ); + move16(); + + st->is_ism_format = 0; + move16(); + + IF( NE_16( ism_mode, ISM_MODE_NONE ) ) + { + st->is_ism_format = 1; + move16(); + } + + /*-----------------------------------------------------------------* + * Bitstream + *-----------------------------------------------------------------*/ + + IF( !vad_only_flag ) + { + IF( ( st->hBstr = (BSTR_ENC_HANDLE) malloc( sizeof( BSTR_ENC_DATA ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Bitstream structure\n" ) ); + } + + /* set pointer to the buffer of indices */ + st->hBstr->ind_list = st_ivas->ind_list; + st->hBstr->ivas_ind_list_zero = &st_ivas->ind_list; + st->hBstr->ivas_max_num_indices = &st_ivas->ivas_max_num_indices; + st->hBstr->nb_ind_tot = 0; + move16(); + st->hBstr->nb_bits_tot = 0; + move16(); + st->hBstr->st_ivas = st_ivas; + } + ELSE + { + st->hBstr = NULL; + } + + /*-----------------------------------------------------------------* + * Pre-processing and ACELP core parameters + *-----------------------------------------------------------------*/ + + Copy( GEWB_Ave_fx, st->mem_AR_fx, M ); + Copy( GEWB_Ave_fx, st->lsfoldbfi0_fx, M ); + Copy( GEWB_Ave_fx, st->lsfoldbfi1_fx, M ); + Copy( GEWB_Ave_fx, st->lsf_adaptive_mean_fx, M ); + + st->next_force_safety_net = 0; + move16(); + + st->pstreaklen = 0; + move16(); + st->streaklimit_fx = MAX_WORD16; + move16(); + set16_fx( st->mem_MA_fx, 0, M ); + + init_gp_clip_fx( st->clip_var_fx ); + pitch_ol_init_fx( &st->old_thres_fx, &st->old_pitch, &st->delta_pit, &st->old_corr_fx ); + set16_fx( st->old_wsp_fx, 0, L_WSP_MEM ); + st->exp_old_wsp = 0; + move16(); + set16_fx( st->old_wsp2_fx, 0, ( L_WSP_MEM - L_INTERPOL ) / OPL_DECIM ); // Needs to change depending on usage. + st->Q_old_wsp2 = 0; + move16(); + + st->mem_preemph_fx = 0; + move16(); + st->mem_preemph16k_fx = 0; + move16(); + st->mem_preemph_enc = 0; + move16(); + st->exp_mem_preemph_enc = 0; + move16(); + +#if 1 // TODO: Float Initializations. To be removed later + st->active_cnt = 0; + move16(); +#endif + + st->pst_mem_deemp_err_fx = 0; + move16(); + st->pst_lp_ener_fx = 0; + move16(); + + /* AVQ pre-quantizer memory */ + st->mem_preemp_preQ_fx = 0; + move16(); + st->mem_deemp_preQ_fx = 0; + move16(); + st->last_nq_preQ = 0; + move16(); + st->last_code_preq = 0; + move16(); + st->use_acelp_preq = 0; + move16(); + st->last_harm_flag_acelp = 0; + move16(); + + /* (Decimated) Weighted Speech Memory */ + st->mem_wsp_enc = 0; + move16(); + st->mem_wsp_fx = 0; + move16(); + st->mem_wsp_q = 0; + move16(); + set16_fx( st->mem_decim2_fx, 0, 3 ); + set32_fx( st->Bin_E_fx, 0, L_FFT ); + st->q_Bin_E = Q31; + move16(); + st->ee_old_fx = 640; /* 10.0f in Q6 */ + move16(); + st->Nb_ACELP_frames = 0; + move16(); + st->audio_frame_cnt = AUDIO_COUNTER_INI; /* Initialization of the audio frame counter mildly into the audio mode */ + move16(); + + /* adaptive lag window memory */ + st->old_pitch_la = 0; + move16(); + + st->prev_Q_new = 0; + move16(); + + IF( EQ_32( st->input_Fs, 8000 ) ) + { + st->min_band = 1; + move16(); + st->max_band = 16; + move16(); + } + ELSE + { + st->min_band = 0; + move16(); + st->max_band = 19; + move16(); + } + + IF( st->Opt_AMR_WB ) + { + Copy( mean_isf_amr_wb_fx, st->lsf_old_fx, M ); + E_LPC_isf_isp_conversion( st->lsf_old_fx, st->lsp_old1_fx, M ); + } + ELSE + { + Copy( GEWB_Ave_fx, st->lsf_old_fx, M ); + lsf2lsp_fx( st->lsf_old_fx, st->lsp_old1_fx, M, INT_FS_12k8 ); + } + + Copy( st->lsf_old_fx, st->lsf_old1_fx, M ); + Copy( st->lsp_old1_fx, st->lsp_old_fx, M ); + Copy( st->lsp_old_fx, st->lsp_old16k_fx, M ); + Copy( st->lsp_old_fx, st->lspold_enc_fx, M ); + + st->stab_fac_fx = 0; + move16(); + + /* Bass post-filter memories - encoder side of MODE2 */ + st->bpf_off = 0; + move16(); + st->pst_mem_deemp_err_fx = 0; + move16(); + st->pst_lp_ener_fx = 0; + move16(); + + /* TC coder type */ + st->tc_cnt = 0; + move16(); + + /* find_uv() parameters */ + st->old_dE1_fx = 0; + move16(); + st->old_ind_deltaMax = 0; + move16(); + set32_fx( st->old_enr_ssf_fx, 0, shl( NB_SSF, 1 ) ); + st->spike_hyst = -1; + move16(); + + /* stereo switching memories */ + st->mem_preemph_DFT_fx = 0; + move16(); + set16_fx( st->inp_12k8_mem_stereo_sw_fx, 0, sub( sub( STEREO_DFT_OVL_12k8, L_MEM_RECALC_12K8 ), L_FILT ) ); + st->mem_preemph16k_DFT_fx = 0; + move16(); + set16_fx( st->inp_16k_mem_stereo_sw_fx, 0, sub( sub( STEREO_DFT_OVL_16k, L_MEM_RECALC_16K ), L_FILT16k ) ); + + st->sharpFlag = 0; + move16(); + + /* Stationary noise UV modification */ + st->ge_sm_fx = L_deposit_l( 640 ); /*Q(GE_SHIFT)*/ + move16(); + st->uv_count = 0; + move16(); + st->act_count = 3; + move16(); + Copy( st->lsp_old_fx, st->lspold_s_fx, M ); + st->noimix_seed = RANDOM_INITSEED; + move16(); + st->min_alpha_fx = 32767; + move16(); + st->exc_pe_fx = 0; + move16(); + st->Q_stat_noise = 15; + move16(); + /* FEC */ + st->last_clas = UNVOICED_CLAS; + move16(); + st->prev_fmerit = 0; + move16(); + st->fmerit_dt = 0; + move16(); + st->Last_pulse_pos = 0; + move16(); + + FOR( i = 0; i < shl( NB_SUBFR16k, 1 ); i++ ) + { + st->old_pitch_buf_fx[i] = L_SUBFR_Q6; + move16(); + } + + /* mode1 core switching */ + st->old_Es_pred_fx = 0; + move16(); + set16_fx( st->old_Aq_12_8_fx + 1, 0, M ); + st->old_Aq_12_8_fx[0] = ONE_IN_Q12; + move16(); + + /* stable short pitch detection */ + st->voicing0_sm_fx = 0; + move16(); + st->voicing_sm_fx = 0; + move16(); + st->LF_EnergyRatio_sm_fx = 1; + move16(); + st->predecision_flag = 0; + move16(); + st->diff_sm_fx = 0; + move32(); + st->energy_sm_fx = 0; + move32(); + + set16_fx( st->pitch, L_SUBFR, 3 ); + set16_fx( st->voicing_fx, 0, 3 ); + + /*-----------------------------------------------------------------* + * General signal buffers + *-----------------------------------------------------------------*/ + + IF( !vad_only_flag ) + { + IF( ( st->hSignalBuf = (SIGNAL_BUFFERS_ENC_HANDLE) malloc( sizeof( SIGNAL_BUFFERS_ENC_DATA ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Signal buffers\n" ) ); + } + + st->Bin_E_old_fx = st->hSignalBuf->Bin_E_old_fx; + st->mem_decim_fx = st->hSignalBuf->mem_decim_fx; + st->mem_decim16k_fx = st->hSignalBuf->mem_decim16k_fx; + st->old_inp_12k8_fx = st->hSignalBuf->old_inp_12k8_fx; + st->old_inp_16k_fx = st->hSignalBuf->old_inp_16k_fx; + st->buf_speech_enc_pe = st->hSignalBuf->buf_speech_enc_pe; + st->buf_synth = st->hSignalBuf->buf_synth; + st->buf_speech_enc = st->hSignalBuf->buf_speech_enc; + st->buf_wspeech_enc = st->hSignalBuf->buf_wspeech_enc; + + set32_fx( st->Bin_E_old_fx, 0, L_FFT / 2 ); + st->q_Bin_E_old = Q31; + move16(); + set16_fx( st->hSignalBuf->buf_speech_enc, 0, L_PAST_MAX_32k + L_FRAME32k + L_NEXT_MAX_32k ); + st->exp_buf_speech_enc = 0; + move16(); + set16_fx( st->hSignalBuf->buf_wspeech_enc, 0, L_FRAME16k + L_SUBFR + L_FRAME16k + L_NEXT_MAX_16k + 320 ); + st->exp_buf_wspeech_enc = 0; + move16(); + /* initializations */ +#ifndef MSAN_FIX + set32_fx( st->Bin_E_old_fx, 0, shr( L_FFT, 2 ) ); +#else + set32_fx( st->Bin_E_old_fx, 0, L_FFT / 2 ); +#endif + st->q_Bin_E_old = Q31; + move16(); + set16_fx( st->mem_decim_fx, 0, shl( L_FILT_MAX, 1 ) ); + set16_fx( st->mem_decim16k_fx, 0, shl( L_FILT_MAX, 1 ) ); + set16_fx( st->old_inp_12k8_fx, 0, L_INP_MEM ); + set16_fx( st->old_inp_16k_fx, 0, L_INP_MEM ); + st->exp_old_inp_16k = 0; + st->exp_old_inp_12k8 = 0; + move16(); + move16(); + + st->input_buff_fx = st->hSignalBuf->input_buff; + st->input_buff32_fx = st->hSignalBuf->input_buff32; + set16_fx( st->input_buff_fx, 0, add( L_FRAME48k, add( L_FRAME48k, NS2SA( 48000, DELAY_FIR_RESAMPL_NS ) ) ) ); + st->q_inp = Q15; + move16(); + st->q_old_inp = Q15; + move16(); + set32_fx( st->input_buff32_fx, 0, add( L_FRAME48k, add( L_FRAME48k, NS2SA( 48000, DELAY_FIR_RESAMPL_NS ) ) ) ); + st->q_inp32 = Q31; + move16(); + st->old_input_signal_fx = st->input_buff_fx; + /* st->input_Fs / FRAMES_PER_SEC */ + Word16 frame_length = extract_l( Mpy_32_32( st->input_Fs, ONE_BY_FRAMES_PER_SEC_Q31 ) ); + + IF( st->element_mode == EVS_MONO ) + { + st->input32_fx = st->input_buff32_fx + st->input_Fs / FRAMES_PER_SEC + NS2SA_FX2( st->input_Fs, DELAY_FIR_RESAMPL_NS ); + st->input_fx = st->input_buff_fx + add( frame_length, (Word16) NS2SA( st->input_Fs, DELAY_FIR_RESAMPL_NS ) ); + } + ELSE + { + st->input32_fx = st->input_buff32_fx + Mpy_32_32( st->input_Fs, 42949673 ) /* 1/50 in Q31*/; // st->input_Fs / FRAMES_PER_SEC + st->input_fx = st->input_buff_fx + frame_length; + } +#if 1 // TODO: To be removed later +#endif + } + ELSE + { + st->hSignalBuf = NULL; + st->Bin_E_old_fx = NULL; + st->mem_decim_fx = NULL; + st->mem_decim16k_fx = NULL; + st->old_inp_12k8_fx = NULL; + st->old_inp_16k_fx = NULL; + st->buf_speech_enc_pe = NULL; + st->buf_synth = NULL; + st->buf_speech_enc = NULL; + st->buf_wspeech_enc = NULL; + st->input_buff_fx = NULL; +#if 1 +#endif + } + + /*-----------------------------------------------------------------* + * Noise estimator + *-----------------------------------------------------------------*/ + + test(); + test(); + test(); + IF( idchan == 0 || EQ_16( st->element_mode, IVAS_CPE_TD ) || EQ_16( st->element_mode, IVAS_CPE_MDCT ) || st->element_mode == EVS_MONO ) + { + IF( ( st->hNoiseEst = (NOISE_EST_HANDLE) malloc( sizeof( NOISE_EST_DATA ) ) ) == NULL ) + { + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Noise estimation\n" ); + } + + noise_est_init_ivas_fx( st->hNoiseEst ); + } + ELSE + { + st->hNoiseEst = NULL; + } + + /*-----------------------------------------------------------------* + * VAD + *-----------------------------------------------------------------*/ + + st->vad_flag = 1; + move16(); + st->localVAD = 0; + move16(); + + IF( ( idchan == 0 || EQ_16( st->element_mode, IVAS_CPE_TD ) || EQ_16( st->element_mode, IVAS_CPE_MDCT ) || st->element_mode == EVS_MONO ) && ( !vad_only_flag ) ) + { + IF( ( st->hVAD = (VAD_HANDLE) malloc( sizeof( VAD_DATA ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for VAD\n" ) ); + } + + wb_vad_init_ivas_fx( st->hVAD ); + } + ELSE + { + st->hVAD = NULL; + } + st->Pos_relE_cnt = 20; + move16(); + + /* CLDFB-based VAD */ + IF( st->element_mode == EVS_MONO ) + { + /* This is done to as in EVS T_CldfbVadState structure is present in Encoder State */ + /* + if ( ( st->hVAD_CLDFB = (VAD_CLDFB_HANDLE) malloc( sizeof( T_CldfbVadState ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for CLDFB VAD\n" ) ); + } + */ + st->hVAD_CLDFB = &st->vad_st; + + vad_init_fx( st->hVAD_CLDFB ); + } + ELSE + { + st->hVAD_CLDFB = NULL; + } + + /*-----------------------------------------------------------------* + * Speech/music classifier + *-----------------------------------------------------------------*/ + + IF( idchan == 0 || EQ_16( st->element_mode, IVAS_CPE_TD ) || EQ_16( st->element_mode, IVAS_CPE_MDCT ) || st->element_mode == EVS_MONO ) + { + IF( ( st->hSpMusClas = (SP_MUS_CLAS_HANDLE) malloc( sizeof( SP_MUS_CLAS_DATA ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Speech/music classifier\n" ) ); + } + + speech_music_clas_init_ivas_fx( st->hSpMusClas ); + st->sp_aud_decision0 = 0; + move16(); + st->sp_aud_decision1 = 0; + move16(); + st->sp_aud_decision2 = 0; + move16(); + } + ELSE + { + st->hSpMusClas = NULL; + } + + + /*-----------------------------------------------------------------* + * WB, SWB and FB bandwidth detector + *-----------------------------------------------------------------*/ + + st->lt_mean_NB_fx = 0; + move16(); + st->lt_mean_WB_fx = 0; + move16(); + st->lt_mean_SWB_fx = 0; + move16(); + st->count_WB = BWD_COUNT_MAX; + move16(); + st->count_SWB = BWD_COUNT_MAX; + move16(); + st->count_FB = BWD_COUNT_MAX; + move16(); + st->bwidth = st->max_bwidth; + move16(); + st->last_input_bwidth = st->bwidth; + move16(); + st->last_bwidth = st->bwidth; + move16(); + st->last_bwidth_cng = st->bwidth; + move16(); + st->bwidth_sw_cnt = 0; + move16(); + + + /*-----------------------------------------------------------------* + * DTX + *-----------------------------------------------------------------*/ + + st->lp_speech_fx = 11520; /*Q8 (45.0) */ /* Initialize the long-term active speech level in dB */ + move16(); + st->lp_noise_fx = 0; + move16(); + st->flag_noisy_speech_snr = 0; + move16(); + st->fd_cng_reset_flag = 0; + move16(); + st->cng_type = -1; + move16(); + st->bckr_tilt_lt = 0; + move16(); + st->active_cnt = 0; + move16(); + + test(); + test(); + test(); + test(); + IF( ( ( idchan == 0 && st->Opt_DTX_ON ) || st->element_mode == EVS_MONO ) || ( EQ_16( st->element_mode, IVAS_CPE_MDCT ) && st->Opt_DTX_ON ) ) + { + IF( ( st->hDtxEnc = (DTX_ENC_HANDLE) malloc( sizeof( DTX_ENC_DATA ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DTX variables\n" ) ); + } + dtx_enc_init_fx( st, var_SID_rate_flag, interval_SID ); + } + ELSE + { + st->hDtxEnc = NULL; + } + + /*-----------------------------------------------------------------* + * No other handles needed to be allocated for front-VAD structure + *-----------------------------------------------------------------*/ + + IF( vad_only_flag ) + { + st->hTdCngEnc = NULL; + st->cldfbAnaEnc = NULL; + st->hFdCngEnc = NULL; + st->hSC_VBR = NULL; + st->hAmrwb_IO = NULL; + st->hLPDmem = NULL; + st->hGSCEnc = NULL; + st->hBWE_TD = NULL; + st->cldfbSynTd = NULL; + st->hBWE_FD = NULL; + st->hHQ_core = NULL; + st->hRF = NULL; + st->hTECEnc = NULL; + st->hTcxEnc = NULL; + st->hTcxCfg = NULL; + st->hIGFEnc = NULL; + st->hPlcExt = NULL; + st->hTranDet = NULL; + + st->element_mode = IVAS_SCE; + move16(); + st->idchan = 100; /* indicates hCoreCoderVAD */ + move16(); + st->core = -1; + move16(); + st->rf_mode = 0; + move16(); + + return error; + } + + /*-----------------------------------------------------------------* + * LP-CNG + *-----------------------------------------------------------------*/ + + test(); + test(); + test(); + test(); + test(); + IF( ( ( idchan == 0 && st->Opt_DTX_ON && NE_16( st->element_mode, IVAS_CPE_MDCT ) ) || st->element_mode == EVS_MONO ) && !( EQ_16( ism_mode, ISM_MODE_PARAM ) || EQ_16( ism_mode, ISM_MODE_DISC ) ) ) + { + IF( ( st->hTdCngEnc = (TD_CNG_ENC_HANDLE) malloc( sizeof( TD_CNG_ENC_DATA ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DTX/TD CNG\n" ) ); + } + + td_cng_enc_init_ivas_fx( st->hTdCngEnc, st->Opt_DTX_ON, st->max_bwidth ); + } + ELSE + { + st->hTdCngEnc = NULL; + } + + /*-----------------------------------------------------------------* + * CLDFB & resampling tools parameters + *-----------------------------------------------------------------*/ + test(); + test(); + test(); + IF( ( NE_16( st->element_mode, IVAS_CPE_MDCT ) && idchan == 0 ) || ( EQ_16( st->element_mode, IVAS_CPE_MDCT ) && st->Opt_DTX_ON ) ) + { + IF( ( error = openCldfb_ivas_fx( &st->cldfbAnaEnc, CLDFB_ANALYSIS, st->input_Fs, CLDFB_PROTOTYPE_1_25MS, ENC ) ) != IVAS_ERR_OK ) + { + return error; + } + } + ELSE + { + st->cldfbAnaEnc = NULL; + } + + st->energyCoreLookahead_Fx = 2; /* 6.1e-5f in Q15 */ + move32(); + st->sf_energyCoreLookahead_Fx = 2; /* 6.1e-5f in Q15 */ + move16(); + + /*-----------------------------------------------------------------* + * SC-VBR parameters + *-----------------------------------------------------------------*/ + + test(); + IF( st->Opt_SC_VBR || st->element_mode == EVS_MONO ) + { + IF( ( st->hSC_VBR = (SC_VBR_ENC_HANDLE) malloc( sizeof( SC_VBR_ENC_DATA ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for SC-VBR\n" ) ); + } + + sc_vbr_enc_init_fx( st->hSC_VBR ); + } + ELSE + { + st->hSC_VBR = NULL; + } + + st->last_Opt_SC_VBR = 0; + move16(); + + + /*-----------------------------------------------------------------* + * AMR-WB IO initialization + *-----------------------------------------------------------------*/ + + test(); + IF( st->Opt_AMR_WB || st->element_mode == EVS_MONO ) + { + IF( ( st->hAmrwb_IO = (AMRWB_IO_ENC_HANDLE) malloc( sizeof( AMRWB_IO_ENC_DATA ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for AMR-WB IO\n" ) ); + } + + amr_wb_enc_init_fx( st->hAmrwb_IO ); + } + ELSE + { + st->hAmrwb_IO = NULL; + } + + /*-----------------------------------------------------------------* + * ACELP LPDmem + *-----------------------------------------------------------------*/ + + test(); + test(); + IF( ( idchan == 0 && NE_16( st->element_mode, IVAS_CPE_MDCT ) ) || EQ_16( st->element_mode, IVAS_CPE_TD ) ) + { + IF( ( st->hLPDmem = (LPD_state_HANDLE) malloc( sizeof( LPD_state ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LPDmem\n" ) ); + } + + LPDmem_enc_init_ivas_fx( st->hLPDmem ); + } + ELSE + { + st->hLPDmem = NULL; + } + + /*-----------------------------------------------------------------* + * parameters for AC coder type (GSC) + *-----------------------------------------------------------------*/ + + st->GSC_noisy_speech = 0; + move16(); + st->GSC_IVAS_mode = 0; + move16(); + + test(); + test(); + IF( ( idchan == 0 && NE_16( st->element_mode, IVAS_CPE_MDCT ) ) || EQ_16( st->element_mode, IVAS_CPE_TD ) ) + { + IF( ( st->hGSCEnc = (GSC_ENC_HANDLE) malloc( sizeof( GSC_ENC_DATA ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for GSC\n" ) ); + } + + GSC_enc_init_fx( st->hGSCEnc ); + } + ELSE + { + st->hGSCEnc = NULL; + } + + /*-----------------------------------------------------------------* + * TBE parameters + *-----------------------------------------------------------------*/ + + test(); + IF( idchan == 0 && NE_16( st->element_mode, IVAS_CPE_MDCT ) ) + { + IF( ( st->hBWE_TD = (TD_BWE_ENC_HANDLE) malloc( sizeof( TD_BWE_ENC_DATA ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for TD BWE\n" ) ); + } + + IF( ( error = openCldfb_ivas_fx( &st->cldfbSynTd, CLDFB_SYNTHESIS, 16000, CLDFB_PROTOTYPE_1_25MS, ENC ) ) != IVAS_ERR_OK ) + { + return error; + } + + InitSWBencBuffer_ivas_fx( st ); + ResetSHBbuffer_Enc_fx( st ); + } + ELSE + { + st->hBWE_TD = NULL; + st->cldfbSynTd = NULL; + } + + /*-----------------------------------------------------------------* + * SWB BWE parameters + *-----------------------------------------------------------------*/ + + test(); + IF( idchan == 0 && NE_16( st->element_mode, IVAS_CPE_MDCT ) ) + { + IF( ( st->hBWE_FD = (FD_BWE_ENC_HANDLE) malloc( sizeof( FD_BWE_ENC_DATA ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for FD BWE\n" ) ); + } + + fd_bwe_enc_init_fx( st->hBWE_FD ); +#ifdef MSAN_FIX + st->Q_old_wtda = 0; + move16(); +#endif + } + ELSE + { + st->hBWE_FD = NULL; + } + + /*-----------------------------------------------------------------* + * HQ core parameters + *-----------------------------------------------------------------*/ + + IF( NE_16( st->element_mode, IVAS_CPE_TD ) && NE_16( st->element_mode, IVAS_CPE_MDCT ) && idchan == 0 ) + { + IF( ( st->hHQ_core = (HQ_ENC_HANDLE) malloc( sizeof( HQ_ENC_DATA ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for HQ core\n" ) ); + } + + HQ_core_enc_init_fx( st->hHQ_core ); + } + ELSE + { + st->hHQ_core = NULL; + } + + /* init memory for detect_transient(), used by HQ core and swb_bwe_enc */ + st->old_hpfilt_in_fx = 0; + move16(); + st->old_hpfilt_out_fx = 0; + move16(); + st->EnergyLT_fx = 0; + move32(); + st->Energy_Old_fx = 0; + move32(); + st->TransientHangOver = 0; + move16(); + st->EnergyLT_fx_exp = 30; + move16(); + st->last_enerBuffer_exp = 0; + move16(); + + /*-----------------------------------------------------------------* + * Channel-aware mode + *-----------------------------------------------------------------*/ + + test(); + test(); + test(); + IF( !st->Opt_RF_ON || ( NE_16( st->bwidth, WB ) && NE_16( st->bwidth, SWB ) ) || NE_32( st->total_brate, ACELP_13k20 ) ) + { + st->rf_mode = 0; + move16(); + } + ELSE + { + st->rf_mode = st->Opt_RF_ON; + move16(); + } + + st->rf_mode_last = st->rf_mode; + move16(); + + test(); + IF( st->Opt_RF_ON || st->element_mode == EVS_MONO ) + { + IF( ( st->hRF = (RF_ENC_HANDLE) malloc( sizeof( RF_ENC_DATA ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for RF\n" ) ); + } + + /* initialize RF indice buffers */ + reset_rf_indices_fx( st ); + } + ELSE + { + st->hRF = NULL; + } + + /*-----------------------------------------------------------------* + * Temporal Envelope Coding + *-----------------------------------------------------------------*/ + + IF( st->element_mode == EVS_MONO ) + { + IF( ( st->hTECEnc = (TEC_ENC_HANDLE) malloc( sizeof( TEC_ENC_DATA ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for TEC\n" ) ); + } + } + ELSE + { + st->hTECEnc = NULL; + } + /* note: initialization done later in init_coder_ace_plus() */ + + /*-----------------------------------------------------------------* + * TCX core + *-----------------------------------------------------------------*/ + + // ToDo: reduction possible for MCT_CHAN_MODE_LFE channel + test(); + IF( idchan == 0 || EQ_16( st->element_mode, IVAS_CPE_MDCT ) ) + { + IF( ( st->hTcxEnc = (TCX_ENC_HANDLE) malloc( sizeof( TCX_ENC_DATA ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for hTcxEnc\n" ) ); + } + set32_fx( st->hTcxEnc->spectrum_long_fx, 0, N_MAX ); + st->hTcxEnc->spectrum_long_e = 0; + move16(); + /* Share the memories for 2xTCX10/4xTCX5 and for TCX20 */ + st->hTcxEnc->spectrum_fx[0] = st->hTcxEnc->spectrum_long_fx; + st->hTcxEnc->spectrum_fx[1] = st->hTcxEnc->spectrum_long_fx + N_TCX10_MAX; + move32(); + move32(); + st->hTcxEnc->spectrum_e[0] = st->hTcxEnc->spectrum_e[1] = 0; + move16(); + move16(); +#if 1 + // set_f( st->hTcxEnc->spectrum_long, 0, N_MAX ); + // st->hTcxEnc->spectrum[0] = st->hTcxEnc->spectrum_long; + // st->hTcxEnc->spectrum[1] = st->hTcxEnc->spectrum_long + N_TCX10_MAX; + // set_f( st->hTcxEnc->old_out, 0, L_FRAME32k ); +#endif + + set16_fx( st->hTcxEnc->old_out_fx, 0, L_FRAME32k ); + st->hTcxEnc->Q_old_out = 0; + move16(); + + /* MDCT selector */ + MDCT_selector_reset_fx( st->hTcxEnc ); + + /* MDCT classifier */ + MDCT_classifier_reset_fx( st->hTcxEnc ); + + IF( ( st->hTcxCfg = (TCX_CONFIG_HANDLE) malloc( sizeof( TCX_config ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for hTcxCfg\n" ) ); + } + } + ELSE + { + st->hTcxEnc = NULL; + st->hTcxCfg = NULL; + } + + /*-----------------------------------------------------------------* + * IGF + *-----------------------------------------------------------------*/ + + igf_brate = st->total_brate; + move32(); + + test(); + test(); + test(); + test(); + test(); + test(); + test(); + IF( EQ_16( st->element_mode, IVAS_SCE ) && ( EQ_16( st_ivas->hEncoderConfig->ivas_format, ISM_FORMAT ) || EQ_16( st_ivas->hEncoderConfig->ivas_format, MASA_ISM_FORMAT ) ) ) + { + igf_brate = L_sub( st->total_brate, i_mult( ISM_NB_BITS_METADATA_NOMINAL, FRAMES_PER_SEC ) ); + } + ELSE IF( EQ_16( st->element_mode, IVAS_CPE_DFT ) || ( EQ_16( st->element_mode, IVAS_SCE ) && ( EQ_16( st_ivas->hEncoderConfig->ivas_format, SBA_FORMAT ) || + EQ_16( st_ivas->hEncoderConfig->ivas_format, SBA_ISM_FORMAT ) || + EQ_16( st_ivas->hEncoderConfig->ivas_format, MC_FORMAT ) || + EQ_16( st_ivas->hEncoderConfig->ivas_format, MASA_FORMAT ) ) ) ) + { + /* use nominal bitrates for DFT Stereo and (O)SBA, same as in stereo_dft_config()/ivas_spar_config() */ + IF( EQ_32( element_brate, IVAS_13k2 ) ) + { + igf_brate = ACELP_9k60; + } + ELSE IF( EQ_32( element_brate, IVAS_16k4 ) ) + { + igf_brate = ACELP_13k20; + } + ELSE IF( EQ_32( element_brate, IVAS_24k4 ) ) + { + igf_brate = ACELP_16k40; + } + ELSE IF( EQ_32( element_brate, IVAS_32k ) ) + { + igf_brate = ACELP_24k40; + } + } + ELSE IF( EQ_16( st->element_mode, IVAS_CPE_MDCT ) ) + { + igf_brate = element_brate; + } + move32(); + test(); + IF( EQ_16( st->codec_mode, MODE2 ) || GT_16( st->element_mode, EVS_MONO ) ) + { + st->igf = getIgfPresent_fx( st->element_mode, igf_brate, st->max_bwidth, st->rf_mode ); + } + ELSE + { + st->igf = 0; + } + move16(); + + test(); + test(); + test(); + IF( ( idchan == 0 || EQ_16( st->element_mode, IVAS_CPE_MDCT ) ) && ( st->igf || st->element_mode == EVS_MONO ) ) + { + IF( ( st->hIGFEnc = (IGF_ENC_INSTANCE_HANDLE) malloc( sizeof( IGF_ENC_INSTANCE ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for hIGFEnc\n" ) ); + } + } + ELSE + { + st->hIGFEnc = NULL; + } + + /*-----------------------------------------------------------------* + * Mode 2 initialization + *-----------------------------------------------------------------*/ + + st->last_sr_core = L_mult0( st->last_L_frame, FRAMES_PER_SEC ); + move32(); + + + /* PLC encoder */ + IF( st->element_mode == EVS_MONO ) + { + IF( ( st->hPlcExt = (PLC_ENC_EVS_HANDLE) malloc( sizeof( PLC_ENC_EVS ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for hPlcExt\n" ) ); + } + } + ELSE + { + st->hPlcExt = NULL; + } + + /* Init Mode 2 core coder */ + st->last_totalNoise_fx = 0; + move16(); + set16_fx( st->totalNoise_increase_hist_fx, 0, TOTALNOISE_HIST_SIZE ); + st->totalNoise_increase_len = 0; + move16(); +#ifdef IVAS_FLOAT_FIXED_CONVERSIONS + TCX_ENC_HANDLE hTcxEnc = st->hTcxEnc; + IF( hTcxEnc != NULL ) + { + hTcxEnc->L_frameTCX = extract_l( Mult_32_16( st->input_Fs, 0x0290 ) ); /* 0x0290 is 1/FRAMES_PER_SEC in Q15*/ + move16(); + } + st->currEnergyHF_fx = 0; + move32(); + st->currEnergyHF_e_fx = 0; + move16(); +#ifdef MSAN_FIX + st->prevEnergyHF_fx = 0; + move32(); +#endif + + /* Initialize TCX */ + + /* Initialize Signal Buffers */ + Word16 shift = getScaleFactor16( st->old_inp_16k_fx, L_INP_MEM ); + Scale_sig( st->old_inp_16k_fx, L_INP_MEM, shift ); + st->exp_old_inp_16k = sub( st->exp_old_inp_16k, shift ); + move16(); + shift = getScaleFactor16( st->old_inp_12k8_fx, L_INP_MEM ); + Scale_sig( st->old_inp_12k8_fx, L_INP_MEM, shift ); + st->exp_old_inp_12k8 = sub( st->exp_old_inp_12k8, shift ); + move16(); + /* Initialize ACELP */ +#endif +#ifdef FIX_920_IGF_INIT_ERROR + init_coder_ace_plus_ivas_fx( st, st->last_total_brate, igf_brate, 0 ); +#else + init_coder_ace_plus_ivas_fx( st, st->last_total_brate, 0 ); +#endif + + IF( st->hLPDmem != NULL ) + { + st->hLPDmem->q_lpd_old_exc = st->prev_Q_new; + move16(); + } + /*-----------------------------------------------------------------* + * FD-CNG encoder + *-----------------------------------------------------------------*/ + + test(); + test(); + test(); + test(); + IF( ( idchan == 0 && st->Opt_DTX_ON ) || st->element_mode == EVS_MONO || ( EQ_16( st->element_mode, IVAS_CPE_MDCT ) && st->Opt_DTX_ON ) ) + { + createFdCngEnc_fx( &st->hFdCngEnc ); + initFdCngEnc_fx( st->hFdCngEnc, st->input_Fs, st->cldfbAnaEnc->scale ); + /* initialization for IVAS modes happens in first frame pre-processing */ + IF( st->element_mode == EVS_MONO ) + { + Word32 total_brate; + + test(); + IF( st->rf_mode && EQ_32( st->total_brate, ACELP_13k20 ) ) + { + total_brate = ACELP_9k60; + move32(); + } + ELSE + { + total_brate = st->total_brate; + move32(); + } + + configureFdCngEnc_ivas_fx( st->hFdCngEnc, st->bwidth, total_brate ); + } + } + ELSE + { + st->hFdCngEnc = NULL; + } + + /*-----------------------------------------------------------------* + * Transient detector + *-----------------------------------------------------------------*/ + + IF( ( st->hTranDet = (TRAN_DET_HANDLE) malloc( sizeof( TRAN_DET_DATA ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Transient Detection\n" ) ); + } + Word16 temp; + Word16 frame_length = BASOP_Util_Divide3232_Scale( st->input_Fs, FRAMES_PER_SEC, &temp ); + frame_length = shr( frame_length, sub( 15, temp ) ); + + IF( GT_16( st->element_mode, EVS_MONO ) ) + { + InitTransientDetection_ivas_fx( frame_length, 0, st->hTranDet, 1 ); + } + ELSE + { + InitTransientDetection_ivas_fx( frame_length, NS2SA_FX2( st->input_Fs, DELAY_FIR_RESAMPL_NS ), st->hTranDet, 0 ); + } + + /*-----------------------------------------------------------------* + * IVAS parameters + *-----------------------------------------------------------------*/ + + st->tdm_LRTD_flag = 0; + move16(); + st->cng_sba_flag = 0; + move16(); + st->bits_frame_channel = 0; + move16(); + st->side_bits_frame_channel = 0; + move16(); + st->Q_syn2 = 0; + move16(); + st->Q_syn = 0; + move16(); + set16_fx( st->Q_max, Q_MAX, L_Q_MEM ); + set16_fx( st->Q_max_16k, Q_MAX, L_Q_MEM ); + st->Q_old = 15; + move16(); + st->old_wsp_max = 0; + move16(); + st->old_wsp_shift = 0; + move16(); + st->sharpFlag = 0; + move16(); + + return error; +} + + +/*-----------------------------------------------------------------------* + * destroy_cldfb_encoder() + * + * Free memory which was allocated in init_encoder() + *-----------------------------------------------------------------------*/ + +void destroy_cldfb_encoder_fx( + Encoder_State *st /* i/o: Encoder static variables structure */ +) +{ + deleteCldfb_ivas_fx( &st->cldfbSynTd ); + deleteCldfb_ivas_fx( &st->cldfbAnaEnc ); + + deleteFdCngEnc_fx( &st->hFdCngEnc ); + + return; +} diff --git a/lib_enc/inov_enc.c b/lib_enc/inov_enc.c deleted file mode 100644 index 754e202e581cd3910afbe959e11d280a96108ccb..0000000000000000000000000000000000000000 --- a/lib_enc/inov_enc.c +++ /dev/null @@ -1,49 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include "cnst.h" -#include "prot.h" -#include "ivas_prot.h" -#include "rom_com.h" -#include "wmc_auto.h" - -/*---------------------------------------------------------------------* - * inov_encode() - * - * Encode the algebraic innovation - *---------------------------------------------------------------------*/ diff --git a/lib_enc/inov_enc_fx.c b/lib_enc/inov_enc_fx.c index 725cad9132e818521df6c8cc3e363bcd326227ae..46bec5f4d9e8b41563b4ab1ca6246fdf2dd54249 100644 --- a/lib_enc/inov_enc_fx.c +++ b/lib_enc/inov_enc_fx.c @@ -10,7 +10,6 @@ #include "rom_com.h" /* Static table prototypes */ #include "prot_fx.h" /* Function prototypes */ #include "ivas_prot_fx.h" /* Function prototypes */ -#include "prot.h" /* Function prototypes */ #include "prot_fx_enc.h" /* Function prototypes */ @@ -155,6 +154,7 @@ Word16 inov_encode_fx( IF( st_fx->acelp_cfg.fcb_mode ) { /* set number of iterations in TD stereo, secondary channel */ + test(); if ( EQ_16( st_fx->element_mode, IVAS_CPE_TD ) && EQ_16( st_fx->idchan, 1 ) ) { cmpl_flag = 1; @@ -245,7 +245,7 @@ Word16 inov_encode_fx( } } - if ( EQ_16( coder_type, INACTIVE ) ) + if ( coder_type == INACTIVE ) { cmpl_flag = 4; move16(); @@ -273,83 +273,7 @@ Word16 inov_encode_fx( IF( !Opt_AMR_WB ) { IF( st_fx->acelp_cfg.fcb_mode ) - { // PMTE() -#ifdef IVAS_CODE - if ( st->acelp_cfg.fixed_cdk_index[i_subfr / L_subfr] < ACELP_FIXED_CDK_NB ) - { - int16_t wordcnt, bitcnt; - int16_t prm[8]; - - if ( st->acelp_cfg.fixed_cdk_index[i_subfr / L_subfr] >= 0 ) - { - if ( L_subfr == 2 * L_SUBFR ) - { - nBits = st->acelp_cfg.fixed_cdk_index[i_subfr / L_subfr]; - - if ( nBits == 8 ) - { - acelp_1t64( hBstr, dn, h1, code, y2, L_subfr ); - } - else - { - acelp_fast( hBstr, nBits, dn, cn, h1, code, y2, L_subfr ); - } - } - else if ( ( st->idchan == 1 && st->acelp_cfg.fixed_cdk_index[i_subfr / L_SUBFR] <= 7 ) || ( st->idchan == 0 && st->acelp_cfg.fixed_cdk_index[i_subfr / L_SUBFR] <= 3 ) ) - { - if ( st->acelp_cfg.fixed_cdk_index[i_subfr / L_SUBFR] == 0 ) - { - acelp_1t64( hBstr, dn, h1, code, y2, L_subfr ); - } - else - { - acelp_fast( hBstr, st->acelp_cfg.fixed_cdk_index[i_subfr / L_SUBFR], dn, cn, h1, code, y2, L_SUBFR ); - } - } - else - { - E_ACELP_4t( dn, cn, h1, Rw, acelpautoc, code, st->acelp_cfg.fixed_cdk_index[i_subfr / L_SUBFR], prm, L_frame, last_L_frame, st->total_brate, i_subfr, cmpl_flag ); - - wordcnt = ACELP_FIXED_CDK_BITS( st->acelp_cfg.fixed_cdk_index[i_subfr / L_SUBFR] ) >> 4; - bitcnt = ACELP_FIXED_CDK_BITS( st->acelp_cfg.fixed_cdk_index[i_subfr / L_SUBFR] ) & 15; - - for ( i = 0; i < wordcnt; i++ ) - { - push_indice( hBstr, IND_ALG_CDBK_4T64, prm[i], 16 ); - } - if ( bitcnt ) - { - push_indice( hBstr, IND_ALG_CDBK_4T64, prm[i], bitcnt ); - } - - /* Generate weighted code */ - set_f( y2, 0.0f, L_SUBFR ); - for ( i = 0; i < L_SUBFR; i++ ) - { - /* Code is sparse, so check which samples are non-zero */ - if ( code[i] != 0 ) - { - for ( k = 0; k < L_SUBFR - i; k++ ) - { - y2[i + k] += code[i] * h1[k]; - } - } - } - } - } - else - { - set_f( code, 0.0f, L_SUBFR ); - set_f( y2, 0.0f, L_SUBFR ); - } - } -#ifdef DEBUGGING - else - { - IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "invalid mode for acelp frame!\n" ); - } -#endif -#endif + { } ELSE { @@ -504,7 +428,7 @@ Word16 inov_encode_ivas_fx( // Word16 Rw_e = E_ACELP_hh_corr( h2, Rw, L_SUBFR, 3 ); corr_hh_ivas_fx( h2, Rw, &Rw_q, L_subfr ); // Q(Rw) = Q11-2 - E_ACELP_conv_ivas( xn2, h2, cn ); // Qcn = Qxn2 + E_ACELP_conv_ivas_fx( xn2, h2, cn ); // Qcn = Qxn2 /* dn_e -> Rw_e*Q_xn */ // Scale_sig(Rw, L_SUBFR, sub(5, Rw_e)); //Q9 @@ -655,9 +579,7 @@ Word16 inov_encode_ivas_fx( IF( !Opt_AMR_WB ) { IF( st_fx->acelp_cfg.fcb_mode ) - { // PMTE() -#if 1 - //#ifdef IVAS_CODE + { Word16 idx = 0, idx2 = 0; move16(); move16(); @@ -708,9 +630,7 @@ Word16 inov_encode_ivas_fx( E_ACELP_4t_ivas_fx( dn, cn, h2, Rw, (Word8) acelpautoc, code, st_fx->acelp_cfg.fixed_cdk_index[idx2], prm, L_frame, last_L_frame, st_fx->total_brate, i_subfr, cmpl_flag, st_fx->element_mode ); wordcnt = shr( ACELP_FIXED_CDK_BITS( st_fx->acelp_cfg.fixed_cdk_index[idx2] ), 4 ); - move16(); bitcnt = s_and( ACELP_FIXED_CDK_BITS( st_fx->acelp_cfg.fixed_cdk_index[idx2] ), 15 ); - move16(); FOR( i = 0; i < wordcnt; i++ ) { @@ -749,7 +669,6 @@ Word16 inov_encode_ivas_fx( { IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "invalid mode for acelp frame!\n" ); } -#endif #endif } ELSE diff --git a/lib_enc/isf_enc_amr_wb.c b/lib_enc/isf_enc_amr_wb.c deleted file mode 100644 index 08af81cf8fe7c541e542f456d7b5e0ff6684043c..0000000000000000000000000000000000000000 --- a/lib_enc/isf_enc_amr_wb.c +++ /dev/null @@ -1,43 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include "cnst.h" -#include "rom_enc.h" -#include "rom_com.h" -#include "prot.h" -#include "wmc_auto.h" diff --git a/lib_enc/isf_enc_amr_wb_fx.c b/lib_enc/isf_enc_amr_wb_fx.c index 505d3f2903eb9f1ea7156dc154357103dd07d8be..4851ed15552285743d2dcc88e6dda9ba61a7a2be 100644 --- a/lib_enc/isf_enc_amr_wb_fx.c +++ b/lib_enc/isf_enc_amr_wb_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other @@ -122,7 +122,7 @@ void isf_enc_amr_wb_fx( * A(z) calculation *-------------------------------------------------------------------------------------*/ - if ( st->rate_switching_reset ) + IF( st->rate_switching_reset ) { Copy( isf_new, st->lsf_old_fx, M ); Copy( isp_new, st->lsp_old_fx, M ); @@ -171,7 +171,7 @@ static void qisf_ns_28b_fx( indice[3] = sub_VQ_fx( &isf[8], dico4_ns_28b_fx, 4, DICO4_NS_28b, &tmp ); move16(); indice[4] = add( sub_VQ_fx( &isf[12], dico5_ns_28b_fx + 4, 4, DICO5_NS_28b - 1, &tmp ), 1 ); /* First vector has a problem -> do not allow */ - + move16(); /* write indices to array */ push_indice_fx( hBstr, IND_ISF_0_0, indice[0], 6 ); push_indice_fx( hBstr, IND_ISF_0_1, indice[1], 6 ); @@ -241,9 +241,11 @@ static void qisf_2s_36b_fx( } tmp_ind[0] = sub_VQ_fx( &isf2[0], dico21_isf_36b_fx, 5, SIZE_BK21_36b, &min_err ); + move16(); temp = L_add( min_err, 0 ); tmp_ind[1] = sub_VQ_fx( &isf2[5], dico22_isf_36b_fx, 4, SIZE_BK22_36b, &min_err ); + move16(); temp = L_add( temp, min_err ); IF( LT_32( temp, distance ) ) @@ -369,10 +371,13 @@ static void qisf_2s_46b_fx( } tmp_ind[0] = sub_VQ_fx( &isf2[0], dico21_isf_46b_fx, 3, SIZE_BK21, &min_err ); + move16(); temp = L_add( min_err, 0 ); tmp_ind[1] = sub_VQ_fx( &isf2[3], dico22_isf_46b_fx, 3, SIZE_BK22, &min_err ); + move16(); temp = L_add( temp, min_err ); tmp_ind[2] = sub_VQ_fx( &isf2[6], dico23_isf_46b_fx, 3, SIZE_BK23, &min_err ); + move16(); temp = L_add( temp, min_err ); IF( LT_32( temp, distance ) ) { diff --git a/lib_enc/ivas_agc_enc.c b/lib_enc/ivas_agc_enc_fx.c similarity index 90% rename from lib_enc/ivas_agc_enc.c rename to lib_enc/ivas_agc_enc_fx.c index 5caa4d0b991e9bc7000187791799913c5fb00250..d74e10bdaf25ea124ae9326ad807ac835e6e6e97 100644 --- a/lib_enc/ivas_agc_enc.c +++ b/lib_enc/ivas_agc_enc_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other @@ -35,11 +35,9 @@ #include #include #include "options.h" -#include "ivas_prot.h" -#include "prot.h" +#include "prot_fx.h" #include "rom_com.h" #include "wmc_auto.h" -#include "prot_fx.h" #include "ivas_prot_fx.h" #include "basop_util.h" @@ -210,7 +208,7 @@ Word32 pow32_fx( Word16 inp, Word16 indx ) /*! r: AGC enable flag */ Word16 ivas_agc_enc_get_flag( - const Word16 nchan_transport /* i : number of transport channels */ + const Word16 nchan_transport /* i : number of transport channels Q0*/ ) { Word16 agc_flag; @@ -236,15 +234,16 @@ Word16 ivas_agc_enc_get_flag( static void ivas_agc_enc_init_fx( ivas_agc_enc_state_t *hAgcEnc, - const Word16 input_frame, - const Word16 nchan_inp, - const Word16 delay ) + const Word16 input_frame, /* Q0 */ + const Word16 nchan_inp, /* Q0 */ + const Word16 delay /* Q0 */ +) { Word16 i; ivas_agc_enc_chan_state_t *ptrG = hAgcEnc->gain_state; ivas_agc_chan_data_t *ptr = hAgcEnc->gain_data; - hAgcEnc->agc_com.in_delay = delay; + hAgcEnc->agc_com.in_delay = delay; /* Q0 */ move16(); hAgcEnc->agc_com.num_coeff = FOA_CHANNELS; move16(); @@ -284,9 +283,9 @@ static void ivas_agc_enc_init_fx( ptrG++; /* gain_data */ - ptr->absGainExp = hAgcEnc->agc_com.absEmin; + ptr->absGainExp = hAgcEnc->agc_com.absEmin; /* Q0 */ move16(); - ptr->absGainExpCurr = hAgcEnc->agc_com.absEmin; + ptr->absGainExpCurr = hAgcEnc->agc_com.absEmin; /* Q0 */ move16(); ptr++; } @@ -303,8 +302,8 @@ static void ivas_agc_enc_init_fx( ivas_error ivas_spar_agc_enc_open_fx( ivas_agc_enc_state_t **hAgcEnc, /* i/o: SPAR AGC encoder handle */ - const Word32 input_Fs, /* i : input sampling rate */ - const Word16 nchan_inp /* i : number of input channels */ + const Word32 input_Fs, /* i : input sampling rate Q0*/ + const Word16 nchan_inp /* i : number of input channels Q0*/ ) { ivas_agc_enc_state_t *hAgc; @@ -315,7 +314,7 @@ ivas_error ivas_spar_agc_enc_open_fx( return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for SPAR AGC encoder" ); } - input_frame = extract_l( Mpy_32_16_1( input_Fs, INV_FRAME_PER_SEC_Q15 ) ); + input_frame = extract_l( Mpy_32_16_1( input_Fs, INV_FRAME_PER_SEC_Q15 ) ); /* Q0 */ delay = NS2SA_FX2( input_Fs, ( IVAS_ENC_DELAY_NS + IVAS_DEC_DELAY_NS ) ); IF( ( hAgc->agc_com.winFunc_fx = (Word16 *) malloc( sizeof( Word16 ) * ( input_frame - delay ) ) ) == NULL ) @@ -386,9 +385,9 @@ void ivas_spar_agc_enc_close_fx( void ivas_agc_enc_process_fx( ivas_agc_enc_state_t *hAgcEnc, /* i/o: AGC encoder handle */ BSTR_ENC_HANDLE hMetaData, /* i/o: MetaData handle */ - Word32 **ppPcm_in, /* i : input audio channels */ - Word32 **ppPcm_out, /* o : output audio channels */ - const Word16 n_channels, /* i : number of channels */ + Word32 **ppPcm_in, /* i : input audio channels q_ppPcm*/ + Word32 **ppPcm_out, /* o : output audio channels q_ppPcm*/ + const Word16 n_channels, /* i : number of channels Q0*/ const ENCODER_CONFIG_HANDLE hEncoderConfig, /* i : configuration structure */ Word16 *q_ppPcm ) { @@ -400,8 +399,8 @@ void ivas_agc_enc_process_fx( Word16 q_predMaxAbsVal, q_MaxAbsVal; ivas_agc_enc_state_t *pState = hAgcEnc; - input_frame = extract_l( Mpy_32_16_1( hEncoderConfig->input_Fs, INV_FRAME_PER_SEC_Q15 ) ); - offset = sub( input_frame, pState->agc_com.in_delay ); + input_frame = extract_l( Mpy_32_16_1( hEncoderConfig->input_Fs, INV_FRAME_PER_SEC_Q15 ) ); /* Q0 */ + offset = sub( input_frame, pState->agc_com.in_delay ); /* Q0 */ AGC_flag = 0; move16(); @@ -429,20 +428,20 @@ void ivas_agc_enc_process_fx( IF( LT_16( pState->gain_state[i].q_lastGain_fx, Q31 ) ) { gain_norm = norm_l( L_abs( pState->gain_state[i].lastGain_fx ) ); - pState->gain_state[i].lastGain_fx = L_shl( pState->gain_state[i].lastGain_fx, gain_norm ); + pState->gain_state[i].lastGain_fx = L_shl( pState->gain_state[i].lastGain_fx, gain_norm ); /* pState->gain_state[i].q_lastGain_fx + gain_norm */ move32(); pState->gain_state[i].q_lastGain_fx = add( pState->gain_state[i].q_lastGain_fx, gain_norm ); move16(); } FOR( j = 0; j < input_frame; j++ ) { - sampleAbsVal = L_abs( ppPcm_in[i][j] ); + sampleAbsVal = L_abs( ppPcm_in[i][j] ); /* q_ppPcm */ q_sampleAbsVal = q_ppPcm[i]; move16(); IF( EQ_16( BASOP_Util_Cmp_Mant32Exp_sat( sampleAbsVal, sub( Q31, q_sampleAbsVal ), MaxAbsVal, sub( Q31, q_MaxAbsVal ) ), 1 ) ) { - MaxAbsVal = sampleAbsVal; + MaxAbsVal = sampleAbsVal; /* q_sampleAbsVal */ move32(); q_MaxAbsVal = q_sampleAbsVal; move16(); @@ -454,14 +453,14 @@ void ivas_agc_enc_process_fx( { IF( EQ_16( BASOP_Util_Cmp_Mant32Exp_sat( sampleAbsVal, sub( Q31, q_sampleAbsVal ), predMaxAbsVal, sub( Q31, q_predMaxAbsVal ) ), 1 ) ) { - predMaxAbsVal = sampleAbsVal; + predMaxAbsVal = sampleAbsVal; /* q_sampleAbsVal */ move32(); q_predMaxAbsVal = q_sampleAbsVal; move16(); } } - ppPcm_out[i][j] = Mpy_32_32( ppPcm_in[i][j], pState->gain_state[i].lastGain_fx ); + ppPcm_out[i][j] = Mpy_32_32( ppPcm_in[i][j], pState->gain_state[i].lastGain_fx ); /* q_ppPcm + State->gain_state[i].q_lastGain_fx - 31 */ move32(); q_pcm = add( q_ppPcm[i], sub( pState->gain_state[i].q_lastGain_fx, Q31 ) ); IF( !isClipped ) @@ -501,7 +500,7 @@ void ivas_agc_enc_process_fx( } } - pState->gain_state[i].MaxAbsVal_del_fx = predMaxAbsVal; + pState->gain_state[i].MaxAbsVal_del_fx = predMaxAbsVal; /* q_predMaxAbsVal */ move32(); pState->gain_state[i].q_MaxAbsVal_del_fx = q_predMaxAbsVal; move16(); @@ -537,10 +536,10 @@ void ivas_agc_enc_process_fx( temp1 = Mpy_32_32( pState->smFact_fx, MaxAbsVal ); // q_MaxAbsVal temp2 = Mpy_32_32( ( L_sub( ONE_IN_Q31, pState->smFact_fx ) ), pState->gain_state[i].lastMaxAbs_fx ); // q_lastMaxAbs_fx - smoothedMaxAbsVal = BASOP_Util_Add_Mant32Exp( temp1, sub( Q31, q_MaxAbsVal ), temp2, sub( Q31, pState->gain_state[i].q_lastMaxAbs_fx ), &e_result ); + smoothedMaxAbsVal = BASOP_Util_Add_Mant32Exp( temp1, sub( Q31, q_MaxAbsVal ), temp2, sub( Q31, pState->gain_state[i].q_lastMaxAbs_fx ), &e_result ); /* exp(e_result) */ q_smoothedMaxAbsVal = sub( Q31, e_result ); - pState->gain_state[i].lastMaxAbs_fx = smoothedMaxAbsVal; + pState->gain_state[i].lastMaxAbs_fx = smoothedMaxAbsVal; /* q_smoothedMaxAbsVal */ move32(); pState->gain_state[i].q_lastMaxAbs_fx = q_smoothedMaxAbsVal; move16(); @@ -548,7 +547,7 @@ void ivas_agc_enc_process_fx( Comp_flag = BASOP_Util_Cmp_Mant32Exp_sat( smoothedMaxAbsVal, sub( Q31, q_smoothedMaxAbsVal ), MaxAbsVal, sub( Q31, q_MaxAbsVal ) ); IF( EQ_16( Comp_flag, 1 ) ) { - temp1 = smoothedMaxAbsVal; + temp1 = smoothedMaxAbsVal; /* q_smoothedMaxAbsVal */ move32(); q_temp = q_smoothedMaxAbsVal; move16(); @@ -560,9 +559,9 @@ void ivas_agc_enc_process_fx( q_temp = q_MaxAbsVal; move16(); } - temp1 = Mpy_32_32( temp1, TWO_IN_Q29 ); + temp1 = Mpy_32_32( temp1, TWO_IN_Q29 ); /* q_temp + 29 - 31 */ q_temp = add( q_temp, Q29 - Q31 ); - maxGain = Mpy_32_32( temp1, pState->gain_state[i].lastGain_fx ); + maxGain = Mpy_32_32( temp1, pState->gain_state[i].lastGain_fx ); /* q_temp + pState->gain_state[i].q_lastGain_fx - 31 */ q_maxGain = add( q_temp, sub( pState->gain_state[i].q_lastGain_fx, Q31 ) ); temp2 = ONE_MINUS_M_DELTA_PROD_FLT_FC; // Q15 @@ -582,7 +581,7 @@ void ivas_agc_enc_process_fx( } ELSE { - pState->gain_state[i].lastMaxAbs_fx = MaxAbsVal; + pState->gain_state[i].lastMaxAbs_fx = MaxAbsVal; /* q_MaxAbsVal */ move32(); pState->gain_state[i].q_lastMaxAbs_fx = q_MaxAbsVal; move16(); @@ -604,7 +603,7 @@ void ivas_agc_enc_process_fx( Word32 temp1, temp2; actualMaxAbsVal = Mpy_32_32( pState->gain_state[i].lastMaxAbs_fx, pState->gain_state[i].lastGain_fx ); // QlastGain_fx q_actualMaxAbsVal = add( pState->gain_state[i].q_lastMaxAbs_fx, sub( pState->gain_state[i].q_lastGain_fx, Q31 ) ); - idx = s_min( sub( offset, 1 ), MaxAbsValIdx ); + idx = s_min( sub( offset, 1 ), MaxAbsValIdx ); /* Q0 */ q_actualMaxAbsVal = add( q_actualMaxAbsVal, norm_l( actualMaxAbsVal ) ); temp1 = L_shl( actualMaxAbsVal, norm_l( actualMaxAbsVal ) ); @@ -620,16 +619,16 @@ void ivas_agc_enc_process_fx( } ELSE { - temp_16 = BASOP_Util_Divide3232_Scale( temp1, temp2, &div_e ); + temp_16 = BASOP_Util_Divide3232_Scale( temp1, temp2, &div_e ); /* exp(div_e) */ IF( div_e < 0 ) { - temp_16 = shr( temp_16, (Word16) abs( div_e ) ); + temp_16 = shr( temp_16, abs_s( div_e ) ); div_e = 0; move16(); } - temp_16 = ceil_fx( temp_16, sub( Q15, div_e ) ); + temp_16 = ceil_fx( temp_16, sub( Q15, div_e ) ); /* Q0 */ } - pState->gain_state[i].gainExpVal = temp_16; + pState->gain_state[i].gainExpVal = temp_16; /* Q0 */ move16(); WHILE( !isCompensated ) @@ -641,7 +640,7 @@ void ivas_agc_enc_process_fx( move16(); Word32 tmp_2 = ONE_IN_Q31; move16(); - tmp_1 = pState->gain_state[i].gainExpVal; + tmp_1 = pState->gain_state[i].gainExpVal; /* Q0 */ move16(); FOR( idx = clippedIdx; idx <= MaxAbsValIdx; idx++ ) { @@ -651,21 +650,21 @@ void ivas_agc_enc_process_fx( move16(); IF( tmp_1 < 0 ) { - tmp_2 = pow32_fx( pState->agc_com.winFunc_fx[offset - 1], ( negate( tmp_1 ) ) ); + tmp_2 = pow32_fx( pState->agc_com.winFunc_fx[offset - 1], ( negate( tmp_1 ) ) ); /* Q31 */ IF( tmp_2 < 0 ) { - tmp_2 = L_deposit_h( BASOP_Util_Divide3232_Scale( ONE_IN_Q31, L_negate( tmp_2 ), &e_div ) ); + tmp_2 = L_deposit_h( BASOP_Util_Divide3232_Scale( ONE_IN_Q31, L_negate( tmp_2 ), &e_div ) ); /* exp(e_div) */ tmp_2 = L_negate( tmp_2 ); } ELSE { - tmp_2 = L_deposit_h( BASOP_Util_Divide3232_Scale( ONE_IN_Q31, tmp_2, &e_div ) ); + tmp_2 = L_deposit_h( BASOP_Util_Divide3232_Scale( ONE_IN_Q31, tmp_2, &e_div ) ); /* exp(e_div) */ } q_tmp_2 = sub( Q31, e_div ); } ELSE { - tmp_2 = pow32_fx( pState->agc_com.winFunc_fx[offset - 1], tmp_1 ); + tmp_2 = pow32_fx( pState->agc_com.winFunc_fx[offset - 1], tmp_1 ); /* Q31 */ q_tmp_2 = Q31; move16(); } @@ -674,15 +673,15 @@ void ivas_agc_enc_process_fx( { IF( tmp_1 < 0 ) { - tmp_2 = pow32_fx( pState->agc_com.winFunc_fx[idx], ( negate( tmp_1 ) ) ); + tmp_2 = pow32_fx( pState->agc_com.winFunc_fx[idx], ( negate( tmp_1 ) ) ); /* Q31 */ IF( tmp_2 < 0 ) { - tmp_2 = L_deposit_h( BASOP_Util_Divide3232_Scale( ONE_IN_Q31, L_negate( tmp_2 ), &e_div ) ); + tmp_2 = L_deposit_h( BASOP_Util_Divide3232_Scale( ONE_IN_Q31, L_negate( tmp_2 ), &e_div ) ); /* exp(e_div) */ tmp_2 = L_negate( tmp_2 ); } ELSE { - tmp_2 = L_deposit_h( BASOP_Util_Divide3232_Scale( ONE_IN_Q31, tmp_2, &e_div ) ); + tmp_2 = L_deposit_h( BASOP_Util_Divide3232_Scale( ONE_IN_Q31, tmp_2, &e_div ) ); /* exp(e_div) */ } q_tmp_2 = sub( Q31, e_div ); } @@ -694,7 +693,7 @@ void ivas_agc_enc_process_fx( } } - tmpSignal = Mpy_32_32( ppPcm_out[i][idx], tmp_2 ); + tmpSignal = Mpy_32_32( ppPcm_out[i][idx], tmp_2 ); /* q_pcm + q_tmp_2 - 31 */ q_tmpSignal = add( q_pcm, sub( q_tmp_2, 31 ) ); Word16 comp_flag_1 = BASOP_Util_Cmp_Mant32Exp_sat( tmpSignal, sub( Q31, q_tmpSignal ), ONE_MINUS_M_DELTA_PROD_FLT_FC, Q16 ); @@ -730,13 +729,13 @@ void ivas_agc_enc_process_fx( } IF( !isCompensated ) { - pState->gain_state[i].gainExpVal = add( pState->gain_state[i].gainExpVal, 1 ); + pState->gain_state[i].gainExpVal = add( pState->gain_state[i].gainExpVal, 1 ); /* Q0 */ move16(); } IF( GT_16( pState->gain_state[i].gainExpVal, currMaxAttExp ) ) { - pState->gain_state[i].gainExpVal = s_min( pState->gain_state[i].gainExpVal, currMaxAttExp ); + pState->gain_state[i].gainExpVal = s_min( pState->gain_state[i].gainExpVal, currMaxAttExp ); /* Q0 */ move16(); BREAK; } @@ -748,7 +747,7 @@ void ivas_agc_enc_process_fx( { Word16 tmp_1, q_tmp_2, e_div; Word32 tmp_2; - tmp_1 = pState->gain_state[i].gainExpVal; + tmp_1 = pState->gain_state[i].gainExpVal; /* Q0 */ move16(); IF( GT_16( offset, idx ) ) @@ -758,18 +757,18 @@ void ivas_agc_enc_process_fx( tmp_2 = pow32_fx( pState->agc_com.winFunc_fx[idx], ( negate( tmp_1 ) ) ); IF( tmp_2 < 0 ) { - tmp_2 = L_deposit_h( BASOP_Util_Divide3232_Scale( ONE_IN_Q31, L_negate( tmp_2 ), &e_div ) ); + tmp_2 = L_deposit_h( BASOP_Util_Divide3232_Scale( ONE_IN_Q31, L_negate( tmp_2 ), &e_div ) ); /* exp(e_div) */ tmp_2 = L_negate( tmp_2 ); } ELSE { - tmp_2 = L_deposit_h( BASOP_Util_Divide3232_Scale( ONE_IN_Q31, tmp_2, &e_div ) ); + tmp_2 = L_deposit_h( BASOP_Util_Divide3232_Scale( ONE_IN_Q31, tmp_2, &e_div ) ); /* exp(e_div) */ } q_tmp_2 = sub( Q31, e_div ); } ELSE { - tmp_2 = pow32_fx( pState->agc_com.winFunc_fx[idx], tmp_1 ); + tmp_2 = pow32_fx( pState->agc_com.winFunc_fx[idx], tmp_1 ); /* Q31 */ q_tmp_2 = Q31; move16(); } @@ -778,21 +777,21 @@ void ivas_agc_enc_process_fx( { IF( tmp_1 < 0 ) { - tmp_2 = pow32_fx( pState->agc_com.winFunc_fx[offset - 1], ( negate( tmp_1 ) ) ); + tmp_2 = pow32_fx( pState->agc_com.winFunc_fx[offset - 1], ( negate( tmp_1 ) ) ); /* Q31 */ IF( tmp_2 < 0 ) { - tmp_2 = L_deposit_h( BASOP_Util_Divide3232_Scale( ONE_IN_Q31, L_negate( tmp_2 ), &e_div ) ); + tmp_2 = L_deposit_h( BASOP_Util_Divide3232_Scale( ONE_IN_Q31, L_negate( tmp_2 ), &e_div ) ); /* exp(e_div) */ tmp_2 = L_negate( tmp_2 ); } ELSE { - tmp_2 = L_deposit_h( BASOP_Util_Divide3232_Scale( ONE_IN_Q31, tmp_2, &e_div ) ); + tmp_2 = L_deposit_h( BASOP_Util_Divide3232_Scale( ONE_IN_Q31, tmp_2, &e_div ) ); /* exp(e_div) */ } q_tmp_2 = sub( Q31, e_div ); } ELSE { - tmp_2 = pow32_fx( pState->agc_com.winFunc_fx[offset - 1], tmp_1 ); + tmp_2 = pow32_fx( pState->agc_com.winFunc_fx[offset - 1], tmp_1 ); /* Q31 */ q_tmp_2 = Q31; move16(); } @@ -806,29 +805,29 @@ void ivas_agc_enc_process_fx( Word16 tmp_1, q_tmp_2, e_div; Word32 tmp_2; - tmp_1 = pState->gain_state[i].gainExpVal; + tmp_1 = pState->gain_state[i].gainExpVal; /* Q0 */ move16(); IF( tmp_1 < 0 ) { - tmp_2 = pow32_fx( pState->agc_com.winFunc_fx[offset - 1], ( negate( tmp_1 ) ) ); + tmp_2 = pow32_fx( pState->agc_com.winFunc_fx[offset - 1], ( negate( tmp_1 ) ) ); /* Q31 */ IF( tmp_2 < 0 ) { - tmp_2 = L_deposit_h( BASOP_Util_Divide3232_Scale( ONE_IN_Q31, L_negate( tmp_2 ), &e_div ) ); + tmp_2 = L_deposit_h( BASOP_Util_Divide3232_Scale( ONE_IN_Q31, L_negate( tmp_2 ), &e_div ) ); /* exp(e_div) */ tmp_2 = L_negate( tmp_2 ); } ELSE { - tmp_2 = L_deposit_h( BASOP_Util_Divide3232_Scale( ONE_IN_Q31, tmp_2, &e_div ) ); + tmp_2 = L_deposit_h( BASOP_Util_Divide3232_Scale( ONE_IN_Q31, tmp_2, &e_div ) ); /* exp(e_div) */ } q_tmp_2 = sub( Q31, e_div ); } ELSE { - tmp_2 = pow32_fx( pState->agc_com.winFunc_fx[offset - 1], tmp_1 ); + tmp_2 = pow32_fx( pState->agc_com.winFunc_fx[offset - 1], tmp_1 ); /* Q31 */ q_tmp_2 = Q31; move16(); } - pState->gain_state[i].lastGain_fx = Mpy_32_32( pState->gain_state[i].lastGain_fx, tmp_2 ); + pState->gain_state[i].lastGain_fx = Mpy_32_32( pState->gain_state[i].lastGain_fx, tmp_2 ); /* pState->gain_state[i].q_lastGain_fx + q_tmp_2 - 31 */ move32(); pState->gain_state[i].q_lastGain_fx = add( pState->gain_state[i].q_lastGain_fx, sub( q_tmp_2, Q31 ) ); move16(); @@ -860,11 +859,11 @@ void ivas_agc_enc_process_fx( { IF( pState->gain_state[i].gainExpVal <= 0 ) { - pState->gain_state[i].gainExpVal = add( pState->agc_com.maxAttExp, 1 ); + pState->gain_state[i].gainExpVal = add( pState->agc_com.maxAttExp, 1 ); /* Q0 */ move16(); } } - pState->gain_data[i].absGainExpCurr = sub( pState->gain_data[i].absGainExp, pState->gain_state[i].gainExpVal ); + pState->gain_data[i].absGainExpCurr = sub( pState->gain_data[i].absGainExp, pState->gain_state[i].gainExpVal ); /* Q0 */ move16(); test(); diff --git a/lib_enc/ivas_core_enc.c b/lib_enc/ivas_core_enc_fx.c similarity index 89% rename from lib_enc/ivas_core_enc.c rename to lib_enc/ivas_core_enc_fx.c index a2a87bacc5234fd072009af9a79a19c6798ec827..cacbcabd36f4c3d36cc52d6c3bcd4ddf9c6daab4 100644 --- a/lib_enc/ivas_core_enc.c +++ b/lib_enc/ivas_core_enc_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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,12 +34,10 @@ #include "options.h" #include "cnst.h" #include "rom_com.h" -#include "prot.h" +#include "prot_fx.h" #include "ivas_cnst.h" -#include "ivas_prot.h" #include "wmc_auto.h" #include -#include "prot_fx.h" #include "prot_fx_enc.h" #include "ivas_prot_fx.h" #include "prot_fx_enc.h" @@ -49,41 +47,41 @@ /*-------------------------------------------------------------------* - * ivas_core_enc() + * ivas_core_enc_fx() * * Principal IVAS core coder routine, where number of core channels is 1 or 2 *-------------------------------------------------------------------*/ -ivas_error ivas_core_enc( +ivas_error ivas_core_enc_fx( SCE_ENC_HANDLE hSCE, /* i/o: SCE encoder structure */ CPE_ENC_HANDLE hCPE, /* i/o: CPE encoder structure */ MCT_ENC_HANDLE hMCT, /* i/o: MCT encoder structure */ - const Word16 n_CoreChannels, /* i : number of core channels to be coded */ - Word16 old_inp_12k8_fx[][L_INP_12k8], /* i : buffer of old input signal */ - Word16 old_inp_16k_fx[][L_INP], /* i : buffer of old input signal */ + const Word16 n_CoreChannels, /* i : number of core channels to be coded Q0*/ + Word16 old_inp_12k8_fx[][L_INP_12k8], /* i : buffer of old input signal Q_new-1*/ + Word16 old_inp_16k_fx[][L_INP], /* i : buffer of old input signal Q_new-1*/ Word16 Q_new[], - Word32 ener_fx[], /* i : residual energy from Levinson-Durbin epsP_fx_q */ - Word16 A_fx[][NB_SUBFR16k * ( M + 1 )], /* i : A(z) unquantized for the 4 subframes */ - Word16 Aw_fx[][NB_SUBFR16k * ( M + 1 )], /* i : weighted A(z) unquantized for subframes */ - Word32 epsP_fx[][M + 1], /* i : LP prediction errors epsP_fx_q */ + Word32 ener_fx[], /* i : residual energy from Levinson-Durbin epsP_fx_q*/ + Word16 A_fx[][NB_SUBFR16k * ( M + 1 )], /* i : A(z) unquantized for the 4 subframes Q12*/ + Word16 Aw_fx[][NB_SUBFR16k * ( M + 1 )], /* i : weighted A(z) unquantized for subframes Q12*/ + Word32 epsP_fx[][M + 1], /* i : LP prediction errors epsP_fx_q*/ Word16 epsP_fx_q[], /* i : LP prediction errors */ - Word16 lsp_new_fx[][M], /* i : LSPs at the end of the frame Q15 */ - Word16 lsp_mid_fx[][M], /* i : LSPs in the middle of the frame Q15 */ - const Word16 vad_hover_flag[], /* i : VAD hanglover flag */ - Word16 attack_flag[], /* i : attack flag (GSC or TC) */ - Word32 realBuffer_fx[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], /* i/o: real buffer */ - Word32 imagBuffer_fx[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], /* i/o: imag buffer */ + Word16 lsp_new_fx[][M], /* i : LSPs at the end of the frame Q15*/ + Word16 lsp_mid_fx[][M], /* i : LSPs in the middle of the frame Q15*/ + const Word16 vad_hover_flag[], /* i : VAD hanglover flag Q0*/ + Word16 attack_flag[], /* i : attack flag (GSC or TC) Q0*/ + Word32 realBuffer_fx[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], /* i/o: real buffer q_re_im_buf*/ + Word32 imagBuffer_fx[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], /* i/o: imag buffer q_re_im_buf*/ Word16 *q_re_im_buf, - Word16 old_wsp_fx[][L_WSP], /* i : weighted input signal buffer */ + Word16 old_wsp_fx[][L_WSP], /* i : weighted input signal buffer e_old_wsp*/ Word16 e_old_wsp[], - const Word16 loc_harm[], /* i : harmonicity flag */ - const Word16 cor_map_sum_fx[], /* i : speech/music clasif. parameter Q8 */ - const Word16 vad_flag_dtx[], /* i : HE-SAD flag with additional DTX HO */ - Word32 enerBuffer_fx[][CLDFB_NO_CHANNELS_MAX], /* o : energy buffer */ - Word16 enerBuffer_fx_exp[], /* o : energy buffer */ - Word16 fft_buff_fx[][2 * L_FFT], /* i : FFT buffer */ - const Word16 tdm_SM_or_LRTD_Pri, /* i : channel combination scheme flag */ - const Word16 ivas_format, /* i : IVAS format */ - const Word16 flag_16k_smc /* i : flag to indicate if the OL SMC is run at 16 kHz */ + const Word16 loc_harm[], /* i : harmonicity flag Q0*/ + const Word16 cor_map_sum_fx[], /* i : speech/music clasif. parameter Q8*/ + const Word16 vad_flag_dtx[], /* i : HE-SAD flag with additional DTX HO Q0*/ + Word32 enerBuffer_fx[][CLDFB_NO_CHANNELS_MAX], /* o : energy buffer enerBuffer_fx_exp*/ + Word16 enerBuffer_fx_exp[], /* o : energy buffer */ + Word16 fft_buff_fx[][2 * L_FFT], /* i : FFT buffer Qx*/ + const Word16 tdm_SM_or_LRTD_Pri, /* i : channel combination scheme flag Q0*/ + const Word16 ivas_format, /* i : IVAS format Q0*/ + const Word16 flag_16k_smc /* i : flag to indicate if the OL SMC is run at 16 kHz Q0*/ ) { Word16 n, input_frame; @@ -150,9 +148,9 @@ ivas_error ivas_core_enc( sts = hSCE->hCoreCoder; hStereoTD = NULL; hStereoICBWE = NULL; - element_brate = hSCE->element_brate; + element_brate = hSCE->element_brate; /* Q0 */ move32(); - last_element_brate = hSCE->last_element_brate; + last_element_brate = hSCE->last_element_brate; /* Q0 */ move32(); last_element_mode = IVAS_SCE; move16(); @@ -161,7 +159,7 @@ ivas_error ivas_core_enc( } ELSE { - cpe_id = hCPE->cpe_id; + cpe_id = hCPE->cpe_id; /* Q0 */ move16(); MCT_flag = 0; move16(); @@ -172,17 +170,17 @@ ivas_error ivas_core_enc( } sts = hCPE->hCoreCoder; hStereoICBWE = hCPE->hStereoICBWE; - element_brate = hCPE->element_brate; + element_brate = hCPE->element_brate; /* Q0 */ move32(); - last_element_brate = hCPE->last_element_brate; + last_element_brate = hCPE->last_element_brate; /* Q0 */ move32(); - last_element_mode = hCPE->last_element_mode; + last_element_mode = hCPE->last_element_mode; /* Q0 */ move16(); IF( hCPE->hStereoTD != NULL ) { hStereoTD = hCPE->hStereoTD; - tdm_Pitch_reuse_flag = hCPE->hStereoTD->tdm_Pitch_reuse_flag; + tdm_Pitch_reuse_flag = hCPE->hStereoTD->tdm_Pitch_reuse_flag; /* Q0 */ move16(); } ELSE @@ -211,7 +209,7 @@ ivas_error ivas_core_enc( unbits[n] = 0; move16(); - st->element_brate = element_brate; + st->element_brate = element_brate; /* Q0 */ move32(); /*---------------------------------------------------------------------* @@ -224,7 +222,7 @@ ivas_error ivas_core_enc( tmp_shift = sub( tmp_shift, 5 ); IF( tmp_shift < 0 ) { - scale_sig32( enerBuffer_fx[n], st->cldfbAnaEnc->no_channels, tmp_shift ); + scale_sig32( enerBuffer_fx[n], st->cldfbAnaEnc->no_channels, tmp_shift ); /* enerBuffer_fx_exp[n] - tmp_shift */ enerBuffer_fx_exp[n] = sub( enerBuffer_fx_exp[n], tmp_shift ); move16(); } @@ -250,9 +248,9 @@ ivas_error ivas_core_enc( } IF( EQ_32( ivas_format, SBA_FORMAT ) ) { - IF( NE_32( ( error = pre_proc_ivas( st, last_element_mode, element_brate, last_element_brate, input_frame, old_inp_12k8_fx[n] /* i: -1, o: Q_new - 1 */, old_inp_16k_fx[n] /* i: -1, o: Q_new - 1 */, - &inp_fx[n], &ener_fx[n], A_fx[n], Aw_fx[n], epsP_fx[n], &epsP_fx_q[n], lsp_new_fx[n], lsp_mid_fx[n], new_inp_resamp16k_fx[n], &Voicing_flag[n], old_wsp_fx[n], e_old_wsp[n], loc_harm[n], - vad_flag_dtx[n], MCT_flag, vad_hover_flag[n], flag_16k_smc, enerBuffer_fx[n], enerBuffer_fx_exp[n], fft_buff_fx[n], cor_map_sum_fx[n], &Q_new[n] ) ), + IF( NE_32( ( error = pre_proc_ivas_fx( st, last_element_mode, element_brate, last_element_brate, input_frame, old_inp_12k8_fx[n] /* i: -1, o: Q_new - 1 */, old_inp_16k_fx[n] /* i: -1, o: Q_new - 1 */, + &inp_fx[n], &ener_fx[n], A_fx[n], Aw_fx[n], epsP_fx[n], &epsP_fx_q[n], lsp_new_fx[n], lsp_mid_fx[n], new_inp_resamp16k_fx[n], &Voicing_flag[n], old_wsp_fx[n], e_old_wsp[n], loc_harm[n], + vad_flag_dtx[n], MCT_flag, vad_hover_flag[n], flag_16k_smc, enerBuffer_fx[n], enerBuffer_fx_exp[n], fft_buff_fx[n], cor_map_sum_fx[n], &Q_new[n] ) ), IVAS_ERR_OK ) ) { return error; @@ -260,9 +258,9 @@ ivas_error ivas_core_enc( } ELSE { - IF( NE_32( ( error = pre_proc_ivas( st, last_element_mode, element_brate, element_brate, input_frame, old_inp_12k8_fx[n] /* i: -1, o: Q_new - 1 */, old_inp_16k_fx[n] /* i: -1, o: Q_new - 1 */, - &inp_fx[n], &ener_fx[n], A_fx[n], Aw_fx[n], epsP_fx[n], &epsP_fx_q[n], lsp_new_fx[n], lsp_mid_fx[n], new_inp_resamp16k_fx[n], &Voicing_flag[n], old_wsp_fx[n], e_old_wsp[n], loc_harm[n], - vad_flag_dtx[n], MCT_flag, vad_hover_flag[n], flag_16k_smc, enerBuffer_fx[n], enerBuffer_fx_exp[n], fft_buff_fx[n], cor_map_sum_fx[n], &Q_new[n] ) ), + IF( NE_32( ( error = pre_proc_ivas_fx( st, last_element_mode, element_brate, element_brate, input_frame, old_inp_12k8_fx[n] /* i: -1, o: Q_new - 1 */, old_inp_16k_fx[n] /* i: -1, o: Q_new - 1 */, + &inp_fx[n], &ener_fx[n], A_fx[n], Aw_fx[n], epsP_fx[n], &epsP_fx_q[n], lsp_new_fx[n], lsp_mid_fx[n], new_inp_resamp16k_fx[n], &Voicing_flag[n], old_wsp_fx[n], e_old_wsp[n], loc_harm[n], + vad_flag_dtx[n], MCT_flag, vad_hover_flag[n], flag_16k_smc, enerBuffer_fx[n], enerBuffer_fx_exp[n], fft_buff_fx[n], cor_map_sum_fx[n], &Q_new[n] ) ), IVAS_ERR_OK ) ) { return error; @@ -308,10 +306,10 @@ ivas_error ivas_core_enc( /* write TD stereo spatial parameters */ move_indices( hStereoTD->tdm_hBstr_tmp.ind_list, st->hBstr->ind_list, hStereoTD->tdm_hBstr_tmp.nb_ind_tot ); - st->hBstr->nb_ind_tot = add( st->hBstr->nb_ind_tot, hStereoTD->tdm_hBstr_tmp.nb_ind_tot ); - st->hBstr->nb_bits_tot = add( st->hBstr->nb_bits_tot, hStereoTD->tdm_hBstr_tmp.nb_bits_tot ); + st->hBstr->nb_ind_tot = add( st->hBstr->nb_ind_tot, hStereoTD->tdm_hBstr_tmp.nb_ind_tot ); /* Q0 */ + st->hBstr->nb_bits_tot = add( st->hBstr->nb_bits_tot, hStereoTD->tdm_hBstr_tmp.nb_bits_tot ); /* Q0 */ - reset_indices_enc( &hStereoTD->tdm_hBstr_tmp, MAX_IND_TDM_TMP ); + reset_indices_enc_fx( &hStereoTD->tdm_hBstr_tmp, MAX_IND_TDM_TMP ); } /*---------------------------------------------------------------------* @@ -328,7 +326,6 @@ ivas_error ivas_core_enc( /*---------------------------------------------------------------------* * Preprocessing (preparing) for ACELP/HQ core switching *---------------------------------------------------------------------*/ - core_switching_pre_enc_ivas_fx( st, old_inp_12k8_fx[n], sub( Q_new[n], 1 ), old_inp_16k_fx[n], sub( Q_new[n], 1 ), sts[0]->active_cnt, last_element_mode ); /*---------------------------------------------------------------------* @@ -342,7 +339,7 @@ ivas_error ivas_core_enc( /* ACELP core encoder */ Word16 Q_old_syn_12k8_16k = 0; move16(); - IF( NE_32( ( error = acelp_core_enc( st, inp_fx[n], /*ener[n],*/ A_fx[n], Aw_fx[n], epsP_fx[n], lsp_new_fx[n], lsp_mid_fx[n], vad_hover_flag[0], attack_flag[n], bwe_exc_extended_fx[n], voice_factors_fx[n], old_syn_12k8_16k_fx[n], &Q_old_syn_12k8_16k, pitch_buf_fx[n], &unbits[n], hStereoTD, tdm_lsfQ_PCh_fx, Q_new[n] ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = acelp_core_enc_ivas_fx( st, inp_fx[n], /*ener[n],*/ A_fx[n], Aw_fx[n], epsP_fx[n], lsp_new_fx[n], lsp_mid_fx[n], vad_hover_flag[0], attack_flag[n], bwe_exc_extended_fx[n], voice_factors_fx[n], old_syn_12k8_16k_fx[n], &Q_old_syn_12k8_16k, pitch_buf_fx[n], &unbits[n], hStereoTD, tdm_lsfQ_PCh_fx, Q_new[n] ) ), IVAS_ERR_OK ) ) { return error; } @@ -363,10 +360,9 @@ ivas_error ivas_core_enc( Scale_sig( old_inp_12k8_fx[n], L_INP_12k8, sub( Q1, Q_new[n] ) ); // Q0 Scale_sig( old_inp_16k_fx[n], L_INP, sub( Q1, Q_new[n] ) ); // Q0 - Scale_sig( st->hTcxEnc->Txnq, L_FRAME32k / 2 + 64, sub( -1, st->hTcxEnc->q_Txnq ) ); + Scale_sig( st->hTcxEnc->Txnq, L_FRAME32k / 2 + 64, sub( negate( 1 ), st->hTcxEnc->q_Txnq ) ); /* Q(-1) */ st->hTcxEnc->q_Txnq = -Q1; move16(); - Q_spec_old = hTcxEnc->spectrum_long_e; move16(); /* TCX core encoder */ @@ -500,14 +496,14 @@ ivas_error ivas_core_enc( IF( EQ_16( nSubframes, NB_DIV ) ) { Word16 max_e = s_max( orig_spectrum_e[i][0], orig_spectrum_e[i][1] ); - Scale_sig32( hMCT->p_orig_spectrum_long_fx[cpe_id][i], N_TCX10_MAX, sub( orig_spectrum_e[i][0], max_e ) ); // exp(max_e) - Scale_sig32( hMCT->p_orig_spectrum_long_fx[cpe_id][i] + N_TCX10_MAX, N_TCX10_MAX, sub( orig_spectrum_e[i][1], max_e ) ); // exp(max_e) - hMCT->q_orig_spectrum_long_fx[cpe_id][i] = max_e; + scale_sig32( hMCT->p_orig_spectrum_long_fx[cpe_id][i], N_TCX10_MAX, sub( orig_spectrum_e[i][0], max_e ) ); // exp(max_e) + scale_sig32( hMCT->p_orig_spectrum_long_fx[cpe_id][i] + N_TCX10_MAX, N_TCX10_MAX, sub( orig_spectrum_e[i][1], max_e ) ); // exp(max_e) + hMCT->q_orig_spectrum_long_fx[cpe_id][i] = sub( Q31, max_e ); move16(); } ELSE { - hMCT->q_orig_spectrum_long_fx[cpe_id][i] = orig_spectrum_e[i][0]; + hMCT->q_orig_spectrum_long_fx[cpe_id][i] = sub( Q31, orig_spectrum_e[i][0] ); move16(); } @@ -645,18 +641,12 @@ ivas_error ivas_core_enc( st->q_old_inp = st->q_inp = 0; move16(); move16(); - - if ( st->hTcxEnc != NULL ) - { - st->hTcxEnc->exp_buf_speech_ltp = 31; // Q0 - move16(); - } IF( st->hBWE_FD != NULL ) { - Scale_sig( st->hBWE_FD->L_old_wtda_swb_fx, L_FRAME48k, sub( -1, st->Q_old_wtda ) ); - st->Q_old_wtda = -1; // This reset is required for resolving crash issue. Needs to be looked into further + Scale_sig( st->hBWE_FD->L_old_wtda_swb_fx, L_FRAME48k, sub( negate( 1 ), st->Q_old_wtda ) ); // Q(-1) + st->Q_old_wtda = -1; // This reset is required for resolving crash issue. Needs to be looked into further move16(); - Scale_sig( st->hBWE_FD->old_input_lp_fx, NS2SA( 16000, ACELP_LOOK_NS + DELAY_FD_BWE_ENC_NS ), sub( sub( Q_new[n], 1 ), st->hBWE_FD->prev_Q_input_lp ) ); + Scale_sig( st->hBWE_FD->old_input_lp_fx, NS2SA( 16000, ACELP_LOOK_NS + DELAY_FD_BWE_ENC_NS ), sub( sub( Q_new[n], 1 ), st->hBWE_FD->prev_Q_input_lp ) ); /* Q_new[n] - 1 */ st->hBWE_FD->prev_Q_input_lp = sub( Q_new[n], 1 ); move16(); } @@ -742,8 +732,8 @@ ivas_error ivas_core_enc( Scale_sig( st->hBWE_FD->L_old_wtda_swb_fx, L_FRAME48k, shift ); // st->Q_old_wtda } - Word16 q_new_swb_speech_buffer = getScaleFactor16( new_swb_speech_buffer_fx_16, input_frame ); - Scale_sig( new_swb_speech_buffer_fx_16, q_new_swb_speech_buffer, input_frame ); // Q0->q_new_swb_speech_buffer + Word16 q_new_swb_speech_buffer = getScaleFactor16( new_swb_speech_buffer_fx_16, L_FRAME48k + STEREO_DFT_OVL_MAX ); + Scale_sig( new_swb_speech_buffer_fx_16, L_FRAME48k + STEREO_DFT_OVL_MAX, q_new_swb_speech_buffer ); // Q0->q_new_swb_speech_buffer /* SWB TBE encoder */ test(); @@ -767,11 +757,11 @@ ivas_error ivas_core_enc( } ELSE IF( EQ_16( st->extl, SWB_BWE ) || EQ_16( st->extl, FB_BWE ) ) { - Copy_Scale_sig_32_16( shb_speech_fx32, shb_speech_fx, L_FRAME16k, -Q16 ); // Q_shb_spch - 16 - Scale_sig( new_swb_speech_fx_16, input_frame, negate( q_new_swb_speech_buffer ) ); // Q0 + Copy_Scale_sig_32_16( shb_speech_fx32, shb_speech_fx, L_FRAME16k, -Q16 ); // Q_shb_spch - 16 + Scale_sig( new_swb_speech_buffer_fx_16, L_FRAME48k + STEREO_DFT_OVL_MAX, negate( q_new_swb_speech_buffer ) ); // q_new_swb_speech_buffer -> Q0 /* SWB(FB) BWE encoder */ swb_bwe_enc_ivas_fx( st, last_element_mode, old_inp_12k8_fx[n], old_inp_16k_fx[n], old_syn_12k8_16k_fx[n], new_swb_speech_fx_16, shb_speech_fx, sub( Q_shb_spch, Q16 ), sub( Q_new[n], 1 ) ); - Scale_sig( new_swb_speech_fx_16, input_frame, q_new_swb_speech_buffer ); // q_new_swb_speech_buffer + Scale_sig( new_swb_speech_buffer_fx_16, L_FRAME48k + STEREO_DFT_OVL_MAX, q_new_swb_speech_buffer ); // Q0 -> q_new_swb_speech_buffer } Scale_sig( old_syn_12k8_16k_fx[n], L_FRAME16k, sub( Q1, Q_new[n] ) ); // Q0 @@ -801,8 +791,8 @@ ivas_error ivas_core_enc( stereo_icBWE_preproc_fx( hCPE, input_frame, new_swb_speech_buffer_fx_16 /*tmp buffer*/, q_new_swb_speech_buffer ); q_new_swb_speech_buffer = add( q_new_swb_speech_buffer, 16 ); - Copy_Scale_sig_16_32( new_swb_speech_buffer_fx_16, new_swb_speech_buffer_fx, input_frame, Q16 ); // q_new_swb_speech_buffer - Copy_Scale_sig_16_32( voice_factors_fx[0], voice_factors_fx32[0], NB_SUBFR16k, Q16 ); // Q31 + Copy_Scale_sig_16_32_no_sat( new_swb_speech_buffer_fx_16, new_swb_speech_buffer_fx, L_FRAME48k + STEREO_DFT_OVL_MAX, Q16 ); // q_new_swb_speech_buffer - 16 - > q_new_swb_speech_buffer + Copy_Scale_sig_16_32_no_sat( voice_factors_fx[0], voice_factors_fx32[0], NB_SUBFR16k, Q16 ); // Q31 stereo_icBWE_enc_ivas_fx( hCPE, shb_speech_fx32, sub( Q31, Q_shb_spch ), new_swb_speech_buffer_fx, sub( Q31, q_new_swb_speech_buffer ), voice_factors_fx32[0] ); @@ -842,10 +832,6 @@ ivas_error ivas_core_enc( st->hBWE_FD->prev_Q_input_lp = sub( Q_new[n], 1 ); move16(); } - IF( st->hTcxEnc != NULL ) - { - Scale_sig( st->hTcxEnc->buf_speech_ltp, L_PAST_MAX_32k + L_FRAME32k + L_NEXT_MAX_32k, negate( st->hTcxEnc->exp_buf_speech_ltp ) ); // Q0 - } } /*------------------------------------------------------------------* diff --git a/lib_enc/ivas_core_pre_proc_front.c b/lib_enc/ivas_core_pre_proc_front_fx.c similarity index 70% rename from lib_enc/ivas_core_pre_proc_front.c rename to lib_enc/ivas_core_pre_proc_front_fx.c index 66e8b9fcf91ad2e9e0cc7e83cb8ec8f985cfaa21..42920a46a17d78e32195459a41e82ee68554cc75 100644 --- a/lib_enc/ivas_core_pre_proc_front.c +++ b/lib_enc/ivas_core_pre_proc_front_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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,10 +36,8 @@ #include "ivas_cnst.h" #include "rom_enc.h" #include "rom_com.h" -#include "prot.h" #include "prot_fx.h" #include "prot_fx_enc.h" -#include "ivas_prot.h" #include "ivas_prot_fx.h" #include "wmc_auto.h" #include @@ -50,7 +48,6 @@ #include "prot_fx_enc.h" #include "ivas_prot_fx.h" -#include "prot_fx.h" /*---------------------------------------------------------------* * Local constants @@ -84,57 +81,60 @@ static Word16 get_zero_flag( Word32 arr[], Word16 len ) } ivas_error pre_proc_front_ivas_fx( - SCE_ENC_HANDLE hSCE, /* i/o: SCE encoder structure */ - CPE_ENC_HANDLE hCPE, /* i/o: CPE encoder structure */ - const Word32 element_brate, /* i : SCE/CPE element bitrate */ - const Word16 nb_bits_metadata, /* i : number of metadata bits */ - const Word16 input_frame, /* i : frame length */ - const Word16 n, /* i : channel number */ - Word16 old_inp_12k8_fx[], /* o : buffer of old input signal Q_new-1 */ - Word16 old_inp_16k_fx[], /* o : buffer of old input signal @16kHz Q_new-1 */ - Word32 *ener_fx, /* o : residual energy from Levinson-Durbin epsP_fx_q */ - Word16 *relE_fx, /* o : frame relative energy Q8 */ - Word16 A_fx[NB_SUBFR16k * ( M + 1 )], /* o : A(z) unquantized for the 4 subframes Q12 */ - Word16 Aw_fx[NB_SUBFR16k * ( M + 1 )], /* o : weighted A(z) unquantized for subframes Q12 */ - Word32 epsP_fx[M + 1], /* o : LP prediction errors */ + SCE_ENC_HANDLE hSCE, /* i/o: SCE encoder structure */ + CPE_ENC_HANDLE hCPE, /* i/o: CPE encoder structure */ + const Word32 element_brate, /* i : SCE/CPE element bitrate Q0*/ + const Word16 nb_bits_metadata, /* i : number of metadata bits Q0*/ + const Word16 input_frame, /* i : frame length Q0*/ + const Word16 n, /* i : channel number Q0*/ + Word16 old_inp_12k8_fx[], /* o : buffer of old input signal Q_new-1*/ + Word16 old_inp_16k_fx[], /* o : buffer of old input signal @16kHz Q_new-1*/ + Word32 *ener_fx, /* o : residual energy from Levinson-Durbin epsP_fx_q*/ + Word16 *relE_fx, /* o : frame relative energy Q8*/ + Word16 A_fx[NB_SUBFR16k * ( M + 1 )], /* o : A(z) unquantized for the 4 subframes Q12*/ + Word16 Aw_fx[NB_SUBFR16k * ( M + 1 )], /* o : weighted A(z) unquantized for subframes Q12*/ + Word32 epsP_fx[M + 1], /* o : LP prediction errors epsP_fx_q*/ Word16 *epsP_fx_q, - Word16 lsp_new_fx[M], /* o : LSPs at the end of the frame Q15 */ - Word16 lsp_mid_fx[M], /* o : LSPs in the middle of the frame Q15 */ - Word16 *vad_hover_flag, /* o : VAD hangover flag */ - Word16 *attack_flag, /* o : flag signaling attack */ - Word32 realBuffer_fx[CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], /* i/o: real buffer Q(q_re_im_buf) */ - Word32 imagBuffer_fx[CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], /* i/o: imag buffer Q(q_re_im_buf) */ - Word16 *q_re_im_buf, /* i/o: Q-factor of real and imag buffer */ - Word16 old_wsp_fx[], /* o : weighted input signal buffer q_old_wsp*/ + Word16 lsp_new_fx[M], /* o : LSPs at the end of the frame Q15*/ + Word16 lsp_mid_fx[M], /* o : LSPs in the middle of the frame Q15*/ + Word16 *vad_hover_flag, /* o : VAD hangover flag Q0*/ + Word16 *attack_flag, /* o : flag signaling attack Q0*/ + Word32 realBuffer_fx[CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], /* i/o: real buffer Q(q_re_im_buf)*/ + Word32 imagBuffer_fx[CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], /* i/o: imag buffer Q(q_re_im_buf)*/ + Word16 *q_re_im_buf, /* i/o: Q-factor of real and imag buffer */ + Word16 old_wsp_fx[], /* o : weighted input signal buffer q_old_wsp*/ Word16 *q_old_wsp, - Word16 pitch_fr_fx[NB_SUBFR], /* o : fractional pitch values Q6 */ - Word16 voicing_fr_fx[NB_SUBFR], /* o : fractional pitch gains Q15 */ - Word16 *loc_harm, /* o : harmonicity flag */ - Word16 *cor_map_sum_fx, /* o : speech/music clasif. parameter Q8 */ - Word16 *vad_flag_dtx, /* o : HE-SAD flag with additional DTX HO */ - Word32 enerBuffer_fx[CLDFB_NO_CHANNELS_MAX], /* o : energy buffer */ - Word16 *enerBuffer_fx_exp, /* o : energy buffer */ - Word16 fft_buff_fx[2 * L_FFT], /* o : FFT buffer */ - Word16 *fft_buff_fx_q, /* o : FFT buffer */ - const Word16 tdm_A_PCh_fx[M + 1], /* i : unq. LP coeff. of primary channel Q12 */ - const Word16 tdm_lsp_new_PCh_fx[M], /* i : unq. LSPs of primary channel Q15 */ - const Word16 currFlatness_fx, /* i : flatness parameter Q7 */ - const Word16 tdm_ratio_idx, /* i : Current Ratio_L index */ - Word32 fr_bands_LR_fx[][2 * NB_BANDS], /* i : energy in frequency bands (fr_bands_LR_fx_q) */ - Word16 fr_bands_LR_fx_q, - const Word16 Etot_LR_fx[], /* i : total energy Left & Right channel Q8*/ - Word32 lf_E_LR_fx[][2 * VOIC_BINS], /* i : per bin spectrum energy in lf, LR channels (lf_E_LR_fx_q) */ + Word16 pitch_fr_fx[NB_SUBFR], /* o : fractional pitch values Q6*/ + Word16 voicing_fr_fx[NB_SUBFR], /* o : fractional pitch gains Q15*/ + Word16 *loc_harm, /* o : harmonicity flag Q0*/ + Word16 *cor_map_sum_fx, /* o : speech/music clasif. parameter Q8*/ + Word16 *vad_flag_dtx, /* o : HE-SAD flag with additional DTX HO Q0*/ + Word32 enerBuffer_fx[CLDFB_NO_CHANNELS_MAX], /* o : energy buffer enerBuffer_fx_exp*/ + Word16 *enerBuffer_fx_exp, /* o : energy buffer */ + Word16 fft_buff_fx[2 * L_FFT], /* o : FFT buffer fft_buff_fx_q*/ + Word16 *fft_buff_fx_q, /* o : FFT buffer */ + const Word16 tdm_A_PCh_fx[M + 1], /* i : unq. LP coeff. of primary channel Q12*/ + const Word16 tdm_lsp_new_PCh_fx[M], /* i : unq. LSPs of primary channel Q15*/ + const Word16 currFlatness_fx, /* i : flatness parameter Q7*/ + const Word16 tdm_ratio_idx, /* i : Current Ratio_L index Q0*/ + Word32 fr_bands_LR_fx[][2 * NB_BANDS], /* i : energy in frequency bands (fr_bands_LR_fx_q) fr_bands_LR_fx_q*/ + Word16 fr_bands_LR_fx_q[CPE_CHANNELS], + const Word16 Etot_LR_fx[], /* i : total energy Left & Right channel Q8*/ + Word32 lf_E_LR_fx[][2 * VOIC_BINS], /* i : per bin spectrum energy in lf, LR channels (lf_E_LR_fx_q)*/ Word16 lf_E_LR_fx_q, - const Word16 localVAD_HE_SAD_LR[], /* i : HE-SAD flag without hangover, LR channels */ - Word32 band_energies_LR_fx[2 * NB_BANDS], /* o : energy in critical bands without minimum noise floor E_MIN (band_energies_LR_fx_q) */ + const Word16 localVAD_HE_SAD_LR[], /* i : HE-SAD flag without hangover, LR channels Q0*/ + Word32 band_energies_LR_fx[2 * NB_BANDS], /* o : energy in critical bands without minimum noise floor E_MIN (band_energies_LR_fx_q)*/ Word16 band_energies_LR_fx_q, - const Word16 flag_16k_smc, /* i : flag to indicate if the OL SMC is run at 16 kHz */ - const Word16 front_vad_flag, /* i : front-VAD flag to overwrite VAD decision */ - const Word16 force_front_vad, /* i : flag to force VAD decision */ - const Word16 front_vad_dtx_flag, /* i : front-VAD DTX flag to overwrite VAD decision*/ - const IVAS_FORMAT ivas_format, /* i : IVAS format */ - const Word16 MCT_flag, /* i : hMCT handle allocated (1) or not (0) */ - const Word32 ivas_total_brate, /* i : IVAS total bitrate - for setting the DTX */ + const Word16 flag_16k_smc, /* i : flag to indicate if the OL SMC is run at 16 kHz Q0*/ + const Word16 front_vad_flag, /* i : front-VAD flag to overwrite VAD decision Q0*/ + const Word16 force_front_vad, /* i : flag to force VAD decision Q0*/ + const Word16 front_vad_dtx_flag, /* i : front-VAD DTX flag to overwrite VAD decision Q0*/ + const IVAS_FORMAT ivas_format, /* i : IVAS format */ + const Word16 MCT_flag, /* i : hMCT handle allocated (1) or not (0) Q0*/ +#ifdef NONBE_1211_DTX_BR_SWITCHING + const Word32 last_ivas_total_brate, /* i : last IVAS total bitrate Q0*/ +#endif + const Word32 ivas_total_brate, /* i : IVAS total bitrate - for setting the DTX Q0*/ Word16 *Q_new #ifdef DEBUG_MODE_INFO , @@ -153,21 +153,21 @@ ivas_error pre_proc_front_ivas_fx( } Word16 old_inp_12k8_e; Word16 shift = getScaleFactor16( st->old_inp_12k8_fx, 240 ); - Scale_sig( st->old_inp_12k8_fx, 240, shift ); + Scale_sig( st->old_inp_12k8_fx, 240, shift ); /* exp(st->exp_old_inp_12k8 - shift) */ st->exp_old_inp_12k8 = sub( st->exp_old_inp_12k8, shift ); move16(); shift = getScaleFactor16( old_inp_12k8_fx, 496 ); - Scale_sig( old_inp_12k8_fx, 496, shift ); + Scale_sig( old_inp_12k8_fx, 496, shift ); /* exp(16 - shift) */ old_inp_12k8_e = sub( Q16, shift ); IF( GT_16( old_inp_12k8_e, st->exp_old_inp_12k8 ) ) { - Scale_sig( st->old_inp_12k8_fx, 240, sub( st->exp_old_inp_12k8, old_inp_12k8_e ) ); + Scale_sig( st->old_inp_12k8_fx, 240, sub( st->exp_old_inp_12k8, old_inp_12k8_e ) ); /* exp(old_inp_12k8_e) */ st->exp_old_inp_12k8 = old_inp_12k8_e; move16(); } ELSE { - Scale_sig( old_inp_12k8_fx, 496, sub( old_inp_12k8_e, st->exp_old_inp_12k8 ) ); + Scale_sig( old_inp_12k8_fx, 496, sub( old_inp_12k8_e, st->exp_old_inp_12k8 ) ); /* exp(st->exp_old_inp_12k8) */ old_inp_12k8_e = st->exp_old_inp_12k8; move16(); } @@ -247,7 +247,7 @@ ivas_error pre_proc_front_ivas_fx( Word16 realBuffer16[CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX]; Word16 imagBuffer16[CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX]; Word16 res_cod_SNR_M_fx_e[STEREO_DFT_BAND_MAX]; - Word16 band_energies_fx_exp, Qfact_PS, q_lf_E_fx; + Word16 Qfact_PS, q_lf_E_fx; #ifdef DEBUG_MODE_INFO Word32 *in_buff_temp; Word16 in_q_temp; @@ -259,14 +259,19 @@ ivas_error pre_proc_front_ivas_fx( IF( hSCE != NULL ) { - Copy_Scale_sig_16_32( hSCE->hCoreCoder[n]->input_fx, hSCE->hCoreCoder[n]->input32_fx, input_frame, sub( Q11, hSCE->hCoreCoder[n]->q_inp ) ); - Copy_Scale_sig_16_32( hSCE->hCoreCoder[n]->input_fx - input_frame, hSCE->hCoreCoder[n]->input32_fx - input_frame, input_frame, sub( Q11, hSCE->hCoreCoder[n]->q_old_inp ) ); +#ifdef FIX_ISSUE_1237 + Copy_Scale_sig_16_32_no_sat( hSCE->hCoreCoder[n]->input_fx, hSCE->hCoreCoder[n]->input32_fx, input_frame, sub( Q11, hSCE->hCoreCoder[n]->q_inp ) ); /* Q11 */ + Copy_Scale_sig_16_32_no_sat( hSCE->hCoreCoder[n]->input_fx - input_frame, hSCE->hCoreCoder[n]->input32_fx - input_frame, input_frame, sub( Q11, hSCE->hCoreCoder[n]->q_old_inp ) ); /* Q11 */ +#else + Copy_Scale_sig_16_32_DEPREC( hSCE->hCoreCoder[n]->input_fx, hSCE->hCoreCoder[n]->input32_fx, input_frame, sub( Q11, hSCE->hCoreCoder[n]->q_inp ) ); /* Q11 */ + Copy_Scale_sig_16_32_DEPREC( hSCE->hCoreCoder[n]->input_fx - input_frame, hSCE->hCoreCoder[n]->input32_fx - input_frame, input_frame, sub( Q11, hSCE->hCoreCoder[n]->q_old_inp ) ); /* Q11 */ +#endif hSCE->hCoreCoder[n]->q_inp32 = Q11; move16(); - Scale_sig( hSCE->hCoreCoder[n]->input_fx, input_frame, sub( -1, hSCE->hCoreCoder[n]->q_inp ) ); + Scale_sig( hSCE->hCoreCoder[n]->input_fx, input_frame, sub( -1, hSCE->hCoreCoder[n]->q_inp ) ); /* Q(-1) */ hSCE->hCoreCoder[n]->q_inp = -1; move16(); - Scale_sig( hSCE->hCoreCoder[n]->old_input_signal_fx, input_frame, sub( -1, hSCE->hCoreCoder[n]->q_old_inp ) ); + Scale_sig( hSCE->hCoreCoder[n]->old_input_signal_fx, input_frame, sub( -1, hSCE->hCoreCoder[n]->q_old_inp ) ); /* Q(-1) */ hSCE->hCoreCoder[n]->q_old_inp = -1; move16(); @@ -277,14 +282,19 @@ ivas_error pre_proc_front_ivas_fx( } ELSE { - Copy_Scale_sig_16_32( hCPE->hCoreCoder[n]->input_fx, hCPE->hCoreCoder[n]->input32_fx, input_frame, sub( Q11, hCPE->hCoreCoder[n]->q_inp ) ); - Copy_Scale_sig_16_32( hCPE->hCoreCoder[n]->input_fx - input_frame, hCPE->hCoreCoder[n]->input32_fx - input_frame, input_frame, sub( Q11, hCPE->hCoreCoder[n]->q_old_inp ) ); +#ifdef FIX_ISSUE_1237 + Copy_Scale_sig_16_32_no_sat( hCPE->hCoreCoder[n]->input_fx, hCPE->hCoreCoder[n]->input32_fx, input_frame, sub( Q11, hCPE->hCoreCoder[n]->q_inp ) ); /* Q11 */ + Copy_Scale_sig_16_32_no_sat( hCPE->hCoreCoder[n]->input_fx - input_frame, hCPE->hCoreCoder[n]->input32_fx - input_frame, input_frame, sub( Q11, hCPE->hCoreCoder[n]->q_old_inp ) ); /* Q11 */ +#else + Copy_Scale_sig_16_32_DEPREC( hCPE->hCoreCoder[n]->input_fx, hCPE->hCoreCoder[n]->input32_fx, input_frame, sub( Q11, hCPE->hCoreCoder[n]->q_inp ) ); /* Q11 */ + Copy_Scale_sig_16_32_DEPREC( hCPE->hCoreCoder[n]->input_fx - input_frame, hCPE->hCoreCoder[n]->input32_fx - input_frame, input_frame, sub( Q11, hCPE->hCoreCoder[n]->q_old_inp ) ); /* Q11 */ +#endif hCPE->hCoreCoder[n]->q_inp32 = Q11; move16(); - Scale_sig( hCPE->hCoreCoder[n]->input_fx, input_frame, sub( -1, hCPE->hCoreCoder[n]->q_inp ) ); + Scale_sig( hCPE->hCoreCoder[n]->input_fx, input_frame, sub( -1, hCPE->hCoreCoder[n]->q_inp ) ); /* Q(-1) */ hCPE->hCoreCoder[n]->q_inp = -1; move16(); - Scale_sig( hCPE->hCoreCoder[n]->old_input_signal_fx, input_frame, sub( -1, hCPE->hCoreCoder[n]->q_old_inp ) ); + Scale_sig( hCPE->hCoreCoder[n]->old_input_signal_fx, input_frame, sub( -1, hCPE->hCoreCoder[n]->q_old_inp ) ); /* Q(-1) */ hCPE->hCoreCoder[n]->q_old_inp = -1; move16(); #ifdef DEBUG_MODE_INFO @@ -294,7 +304,9 @@ ivas_error pre_proc_front_ivas_fx( } #ifdef DEBUG_MODE_INFO + if ( !( hCPE != NULL && hCPE->hStereoTD != NULL && ch_idx > 0 ) ) { + /* for TD stereo only write out first channel. The existence of a second channel can vary, this is just easier to handle */ int16_t tmpF[L_FRAME48k]; for ( int16_t isample = 0; isample < input_frame; isample++ ) { @@ -345,7 +357,7 @@ ivas_error pre_proc_front_ivas_fx( move16(); IF( st->cldfbAnaEnc != NULL ) { - scale_sig32( st->cldfbAnaEnc->cldfb_state_fx, sub( sub( st->cldfbAnaEnc->p_filter_length, st->cldfbAnaEnc->no_channels ), st->cldfbAnaEnc->zeros ), sub( Q11, st->cldfbAnaEnc->Q_cldfb_state ) ); + scale_sig32( st->cldfbAnaEnc->cldfb_state_fx, sub( sub( st->cldfbAnaEnc->p_filter_length, st->cldfbAnaEnc->no_channels ), st->cldfbAnaEnc->zeros ), sub( Q11, st->cldfbAnaEnc->Q_cldfb_state ) ); /* Q11 */ st->cldfbAnaEnc->Q_cldfb_state = Q11; move16(); } @@ -356,10 +368,10 @@ ivas_error pre_proc_front_ivas_fx( #ifndef REMOVE_IVAS_UNUSED_PARAMETERS_WARNING signal_in = hSCE->hCoreCoder[n]->input; #endif - signal_in_fx = hSCE->hCoreCoder[n]->input_fx; - signal32_in_fx = hSCE->hCoreCoder[n]->input32_fx; + signal_in_fx = hSCE->hCoreCoder[n]->input_fx; /* hSCE->hCoreCoder[n]->q_inp */ + signal32_in_fx = hSCE->hCoreCoder[n]->input32_fx; /* hSCE->hCoreCoder[n]->q_inp32 */ element_mode = IVAS_SCE; - last_element_brate = hSCE->last_element_brate; + last_element_brate = hSCE->last_element_brate; /* Q0 */ hStereoClassif = NULL; lr_vad_enabled = 0; move16(); @@ -372,10 +384,10 @@ ivas_error pre_proc_front_ivas_fx( #ifndef REMOVE_IVAS_UNUSED_PARAMETERS_WARNING signal_in = hCPE->hCoreCoder[n]->input; #endif - signal_in_fx = hCPE->hCoreCoder[n]->input_fx; - signal32_in_fx = hCPE->hCoreCoder[n]->input32_fx; + signal_in_fx = hCPE->hCoreCoder[n]->input_fx; /* hSCE->hCoreCoder[n]->q_inp */ + signal32_in_fx = hCPE->hCoreCoder[n]->input32_fx; /* hSCE->hCoreCoder[n]->q_inp32 */ element_mode = hCPE->element_mode; - last_element_brate = hCPE->last_element_brate; + last_element_brate = hCPE->last_element_brate; /* Q0 */ hStereoClassif = hCPE->hStereoClassif; lr_vad_enabled = 0; move16(); @@ -399,13 +411,13 @@ ivas_error pre_proc_front_ivas_fx( IF( hCPE->hStereoTD != NULL ) { - tdm_SM_last_clas = &hCPE->hStereoTD->tdm_SM_last_clas[n]; - Copy( hCPE->hStereoTD->tdm_SM_last_clas, hCPE->hStereoTD->tdm_SM_last2_clas, CPE_CHANNELS ); + tdm_SM_last_clas = &hCPE->hStereoTD->tdm_SM_last_clas[n]; /* Q0 */ + Copy( hCPE->hStereoTD->tdm_SM_last_clas, hCPE->hStereoTD->tdm_SM_last2_clas, CPE_CHANNELS ); /* Q0 */ } IF( hCPE->hStereoDft != NULL ) { - res_cod_SNR_M_fx = hCPE->hStereoDft->res_cod_SNR_M_fx; + res_cod_SNR_M_fx = hCPE->hStereoDft->res_cod_SNR_M_fx; /* Q(31 - res_cod_SNR_M_fx_e[]) */ } } @@ -417,10 +429,10 @@ ivas_error pre_proc_front_ivas_fx( IF( EQ_16( element_mode, IVAS_CPE_TD ) || EQ_16( element_mode, IVAS_CPE_MDCT ) ) { lMemRecalc = NS2SA_FX2( st->input_Fs, L_MEM_RECALC_NS ); - lMemRecalc_12k8 = NS2SA_FX2( INT_FS_12k8, L_MEM_RECALC_NS ); + lMemRecalc_12k8 = NS2SA( INT_FS_12k8, L_MEM_RECALC_NS ); } - input_Fs = st->input_Fs; + input_Fs = st->input_Fs; /* Q0 */ move32(); localVAD_HE_SAD = 0; @@ -468,9 +480,9 @@ ivas_error pre_proc_front_ivas_fx( L_look = L_LOOK_12k8; /* lookahead at 12.8kHz */ move16(); - Scale_sig( old_inp_12k8_fx, L_INP_12k8, sub( Q_to_be_looked_into, sub( Q15, old_inp_12k8_e ) ) ); + Scale_sig( old_inp_12k8_fx, L_INP_12k8, sub( Q_to_be_looked_into, sub( Q15, old_inp_12k8_e ) ) ); /* Q_to_be_looked_into*/ old_inp_12k8_e = sub( Q15, Q_to_be_looked_into ); - Scale_sig( st->old_inp_12k8_fx, 240, sub( Q_to_be_looked_into, sub( Q15, st->exp_old_inp_12k8 ) ) ); + Scale_sig( st->old_inp_12k8_fx, 240, sub( Q_to_be_looked_into, sub( Q15, st->exp_old_inp_12k8 ) ) ); /* Q_to_be_looked_into */ st->exp_old_inp_12k8 = sub( Q15, Q_to_be_looked_into ); move16(); new_inp_12k8_fx = old_inp_12k8_fx + L_INP_MEM; /* pointer to new samples of the input signal in 12.8kHz core */ @@ -483,26 +495,26 @@ ivas_error pre_proc_front_ivas_fx( IF( EQ_16( element_mode, IVAS_CPE_DFT ) ) { - Copy( st->old_inp_12k8_fx, old_inp_12k8_fx, L_INP_MEM - STEREO_DFT_OVL_12k8 ); + Copy( st->old_inp_12k8_fx, old_inp_12k8_fx, L_INP_MEM - STEREO_DFT_OVL_12k8 ); /* exp(st->exp_old_inp_12k8) */ } ELSE IF( EQ_16( element_mode, IVAS_CPE_TD ) ) { - Copy( st->old_inp_12k8_fx, old_inp_12k8_fx, sub( L_INP_MEM - L_FILT, lMemRecalc_12k8 ) ); + Copy( st->old_inp_12k8_fx, old_inp_12k8_fx, sub( L_INP_MEM - L_FILT, lMemRecalc_12k8 ) ); /* exp(st->exp_old_inp_12k8) */ } ELSE { - Copy( st->old_inp_12k8_fx, old_inp_12k8_fx, L_INP_MEM - L_FILT ); + Copy( st->old_inp_12k8_fx, old_inp_12k8_fx, L_INP_MEM - L_FILT ); /* exp(st->exp_old_inp_12k8) */ } - Copy( st->old_wsp_fx, old_wsp_fx, L_WSP_MEM ); + Copy( st->old_wsp_fx, old_wsp_fx, L_WSP_MEM ); /* exp(st->exp_old_wsp) */ *q_old_wsp = sub( Q15, st->exp_old_wsp ); move16(); wsp_fx = old_wsp_fx + L_WSP_MEM; /* pointer to the current frame of weighted signal in 12.8kHz core */ - st->rf_mode = st->Opt_RF_ON; + st->rf_mode = st->Opt_RF_ON; /* Q0 */ move16(); - last_core_orig = st->last_core; + last_core_orig = st->last_core; /* Q0 */ move16(); /*--------------------------------------------------------------* @@ -545,13 +557,13 @@ ivas_error pre_proc_front_ivas_fx( test(); IF( EQ_16( element_mode, IVAS_SCE ) ) { - new_inp_out_size = modify_Fs_ivas_fx( signal_in_fx, input_frame, input_Fs, new_inp_12k8_fx, INT_FS_12k8, st->mem_decim_fx, ( st->max_bwidth == NB ), &Q_new_inp, &mem_decim_size ); - Scale_sig( new_inp_12k8_fx, new_inp_out_size, negate( Q_new_inp ) ); /* scaling back to Q_to_be_looked_into*/ + new_inp_out_size = modify_Fs_ivas_fx( signal_in_fx, input_frame, input_Fs, new_inp_12k8_fx, INT_FS_12k8, st->mem_decim_fx, ( st->max_bwidth == NB ), &Q_new_inp, &mem_decim_size ); /* Q0 */ + Scale_sig( new_inp_12k8_fx, new_inp_out_size, negate( Q_new_inp ) ); /* scaling back to Q_to_be_looked_into*/ - Copy( st->mem_decim_fx, mem_decim_dummy_fx, 2 * L_FILT_MAX ); + Copy( st->mem_decim_fx, mem_decim_dummy_fx, 2 * L_FILT_MAX ); /* Q(-1) */ set16_fx( temp1F_icatdmResampBuf_fx, 0, L_FILT_MAX ); - new_inp_out_size = modify_Fs_ivas_fx( temp1F_icatdmResampBuf_fx, NS2SA_FX2( st->input_Fs, DELAY_FIR_RESAMPL_NS ), input_Fs, new_inp_12k8_fx + L_FRAME, INT_FS_12k8, mem_decim_dummy_fx, 0, &Q_new_inp, &mem_decim_size ); - Scale_sig( new_inp_12k8_fx + L_FRAME, new_inp_out_size, negate( Q_new_inp ) ); /* scaling back to Q_to_be_looked_into*/ + new_inp_out_size = modify_Fs_ivas_fx( temp1F_icatdmResampBuf_fx, NS2SA_FX2( st->input_Fs, DELAY_FIR_RESAMPL_NS ), input_Fs, new_inp_12k8_fx + L_FRAME, INT_FS_12k8, mem_decim_dummy_fx, 0, &Q_new_inp, &mem_decim_size ); /* Q0 */ + Scale_sig( new_inp_12k8_fx + L_FRAME, new_inp_out_size, negate( Q_new_inp ) ); /* scaling back to Q_to_be_looked_into*/ } ELSE IF( EQ_16( element_mode, IVAS_CPE_TD ) || EQ_16( element_mode, IVAS_CPE_MDCT ) ) { @@ -560,32 +572,32 @@ ivas_error pre_proc_front_ivas_fx( IF( EQ_16( hCPE->last_element_mode, IVAS_CPE_DFT ) && EQ_16( st->idchan, 1 ) ) { Word16 length_inp = NS2SA_FX2( input_Fs, L_MEM_RECALC_SCH_NS ); - Word16 length_12k8 = NS2SA_FX2( INT_FS_12k8, L_MEM_RECALC_SCH_NS ); + Word16 length_12k8 = NS2SA( INT_FS_12k8, L_MEM_RECALC_SCH_NS ); - new_inp_out_size = modify_Fs_ivas_fx( signal_in_fx - lMemRecalc - length_inp, length_inp, input_Fs, new_inp_12k8_fx - lMemRecalc_12k8 - length_12k8, INT_FS_12k8, st->mem_decim_fx, 0, &Q_new_inp, &mem_decim_size ); - Scale_sig( new_inp_12k8_fx - lMemRecalc_12k8 - length_12k8, new_inp_out_size, negate( Q_new_inp ) ); /* scaling back to Q_to_be_looked_into*/ + new_inp_out_size = modify_Fs_ivas_fx( signal_in_fx - lMemRecalc - length_inp, length_inp, input_Fs, new_inp_12k8_fx - lMemRecalc_12k8 - length_12k8, INT_FS_12k8, st->mem_decim_fx, 0, &Q_new_inp, &mem_decim_size ); /* Q0 */ + Scale_sig( new_inp_12k8_fx - lMemRecalc_12k8 - length_12k8, new_inp_out_size, negate( Q_new_inp ) ); /* scaling back to Q_to_be_looked_into*/ } - new_inp_out_size = modify_Fs_ivas_fx( signal_in_fx - lMemRecalc, input_frame, input_Fs, new_inp_12k8_fx - lMemRecalc_12k8, INT_FS_12k8, st->mem_decim_fx, ( st->max_bwidth == NB ), &Q_new_inp, &mem_decim_size ); - Copy( st->mem_decim_fx, mem_decim_dummy_fx, 2 * L_FILT_MAX ); - Scale_sig( new_inp_12k8_fx - lMemRecalc_12k8, new_inp_out_size, negate( Q_new_inp ) ); /* scaling back to Q_to_be_looked_into*/ + new_inp_out_size = modify_Fs_ivas_fx( signal_in_fx - lMemRecalc, input_frame, input_Fs, new_inp_12k8_fx - lMemRecalc_12k8, INT_FS_12k8, st->mem_decim_fx, ( st->max_bwidth == NB ), &Q_new_inp, &mem_decim_size ); /* Q0 */ + Copy( st->mem_decim_fx, mem_decim_dummy_fx, 2 * L_FILT_MAX ); /* Q(-1) */ + Scale_sig( new_inp_12k8_fx - lMemRecalc_12k8, new_inp_out_size, negate( Q_new_inp ) ); /* scaling back to Q_to_be_looked_into*/ IF( lMemRecalc > 0 ) { - new_inp_out_size = modify_Fs_ivas_fx( signal_in_fx + sub( input_frame, lMemRecalc ), lMemRecalc, input_Fs, new_inp_12k8_fx + sub( L_FRAME, lMemRecalc_12k8 ), INT_FS_12k8, mem_decim_dummy_fx, ( st->max_bwidth == NB ), &Q_new_inp, &mem_decim_size ); - Scale_sig( new_inp_12k8_fx + sub( L_FRAME, lMemRecalc_12k8 ), new_inp_out_size, negate( Q_new_inp ) ); /* scaling back to Q_to_be_looked_into*/ + new_inp_out_size = modify_Fs_ivas_fx( signal_in_fx + sub( input_frame, lMemRecalc ), lMemRecalc, input_Fs, new_inp_12k8_fx + sub( L_FRAME, lMemRecalc_12k8 ), INT_FS_12k8, mem_decim_dummy_fx, ( st->max_bwidth == NB ), &Q_new_inp, &mem_decim_size ); /* Q0 */ + Scale_sig( new_inp_12k8_fx + L_FRAME - lMemRecalc_12k8, new_inp_out_size, negate( Q_new_inp ) ); /* scaling back to Q_to_be_looked_into*/ } set16_fx( temp1F_icatdmResampBuf_fx, 0, L_FILT_MAX ); - new_inp_out_size = modify_Fs_ivas_fx( temp1F_icatdmResampBuf_fx, NS2SA_FX2( input_Fs, DELAY_FIR_RESAMPL_NS ), input_Fs, new_inp_12k8_fx + L_FRAME, INT_FS_12k8, mem_decim_dummy_fx, 0, &Q_new_inp, &mem_decim_size ); - Scale_sig( new_inp_12k8_fx + L_FRAME, new_inp_out_size, negate( Q_new_inp ) ); /* scaling back to Q_to_be_looked_into*/ + new_inp_out_size = modify_Fs_ivas_fx( temp1F_icatdmResampBuf_fx, NS2SA_FX2( input_Fs, DELAY_FIR_RESAMPL_NS ), input_Fs, new_inp_12k8_fx + L_FRAME, INT_FS_12k8, mem_decim_dummy_fx, 0, &Q_new_inp, &mem_decim_size ); /* Q0 */ + Scale_sig( new_inp_12k8_fx + L_FRAME, new_inp_out_size, negate( Q_new_inp ) ); /* scaling back to Q_to_be_looked_into*/ } ELSE /* DFT stereo */ { /* update the FIR resampling filter memory, needed for switching to time-domain (FIR) resampling */ - Copy( signal_in_fx + sub( input_frame, add( NS2SA_FX2( input_Fs, L_MEM_RECALC_NS ), 2 * NS2SA( input_Fs, DELAY_FIR_RESAMPL_NS ) ) ), st->mem_decim_fx, 2 * NS2SA_FX2( input_Fs, DELAY_FIR_RESAMPL_NS ) ); + Copy( signal_in_fx + sub( input_frame, add( NS2SA_FX2( input_Fs, L_MEM_RECALC_NS ), 2 * NS2SA_FX2( input_Fs, DELAY_FIR_RESAMPL_NS ) ) ), st->mem_decim_fx, 2 * NS2SA_FX2( input_Fs, DELAY_FIR_RESAMPL_NS ) ); /* hSCE->hCoreCoder[n]->q_inp */ } - Scale_sig( st->buf_speech_enc, L_PAST_MAX_32k + L_FRAME32k + L_NEXT_MAX_32k, sub( -1, sub( 15, st->exp_buf_speech_enc ) ) ); + Scale_sig( st->buf_speech_enc, L_PAST_MAX_32k + L_FRAME32k + L_NEXT_MAX_32k, sub( -1, sub( 15, st->exp_buf_speech_enc ) ) ); /* Q(-1) */ st->exp_buf_speech_enc = 16; move16(); @@ -593,15 +605,15 @@ ivas_error pre_proc_front_ivas_fx( test(); IF( EQ_16( element_mode, IVAS_CPE_DFT ) ) { - Copy( new_inp_12k8_fx - STEREO_DFT_OVL_12k8, st->buf_speech_enc + L_FRAME32k - STEREO_DFT_OVL_12k8, L_FRAME + STEREO_DFT_OVL_12k8 ); + Copy( new_inp_12k8_fx - STEREO_DFT_OVL_12k8, st->buf_speech_enc + L_FRAME32k - STEREO_DFT_OVL_12k8, L_FRAME + STEREO_DFT_OVL_12k8 ); /* Q_to_be_looked_into */ } ELSE IF( EQ_16( element_mode, IVAS_CPE_TD ) || EQ_16( element_mode, IVAS_CPE_MDCT ) ) { - Copy( new_inp_12k8_fx - lMemRecalc_12k8, st->buf_speech_enc + L_FRAME32k - lMemRecalc_12k8 - L_FILT, add( L_FRAME + L_FILT, lMemRecalc_12k8 ) ); + Copy( new_inp_12k8_fx - lMemRecalc_12k8, st->buf_speech_enc + L_FRAME32k - lMemRecalc_12k8 - L_FILT, add( L_FRAME + L_FILT, lMemRecalc_12k8 ) ); /* Q_to_be_looked_into */ } ELSE { - Copy( new_inp_12k8_fx, st->buf_speech_enc + L_FRAME32k, L_FRAME ); + Copy( new_inp_12k8_fx, st->buf_speech_enc + L_FRAME32k, L_FRAME ); /* Q_to_be_looked_into */ } /*------------------------------------------------------------------* @@ -612,24 +624,18 @@ ivas_error pre_proc_front_ivas_fx( move16(); set32_fx( sig_out, 0, 960 ); - headroom = 1; + headroom = 2; move16(); - test(); - test(); - IF( ( st->bwidth == NB || st->max_bwidth == NB ) && GT_32( st->input_Fs, 8000 ) ) - { - headroom = add( headroom, 1 ); - } test(); IF( EQ_16( element_mode, IVAS_CPE_DFT ) ) { - Copy( new_inp_12k8_fx - STEREO_DFT_OVL_12k8 + L_FRAME, st->inp_12k8_mem_stereo_sw_fx, STEREO_DFT_OVL_12k8 - L_MEM_RECALC_12K8 - L_FILT ); /* memory for TD/DFT stereo switching */ + Copy( new_inp_12k8_fx - STEREO_DFT_OVL_12k8 + L_FRAME, st->inp_12k8_mem_stereo_sw_fx, STEREO_DFT_OVL_12k8 - L_MEM_RECALC_12K8 - L_FILT ); /* memory for TD/DFT stereo switching Q_to_be_looked_into*/ - st->mem_preemph_fx = st->mem_preemph_DFT_fx; + st->mem_preemph_fx = st->mem_preemph_DFT_fx; /* Q(-1) */ move16(); - st->mem_preemph_DFT_fx = old_inp_12k8_fx[L_INP_MEM - STEREO_DFT_OVL_12k8 + L_FRAME - 1]; + st->mem_preemph_DFT_fx = old_inp_12k8_fx[L_INP_MEM - STEREO_DFT_OVL_12k8 + L_FRAME - 1]; /* Q_new - 1 */ move16(); // PREEMPH_FX( new_inp_12k8_fx - STEREO_DFT_OVL_12k8, PREEMPH_FAC, L_FRAME, &st->mem_preemph_fx ); @@ -652,7 +658,7 @@ ivas_error pre_proc_front_ivas_fx( { st->mem_preemph_fx = st->mem_preemph_DFT_fx; move16(); - Copy( st->inp_12k8_mem_stereo_sw_fx, new_inp_12k8_fx - L_MEM_RECALC_12K8 - ( STEREO_DFT_OVL_12k8 - L_MEM_RECALC_12K8 - L_FILT ), STEREO_DFT_OVL_12k8 - L_MEM_RECALC_12K8 - L_FILT ); + Copy( st->inp_12k8_mem_stereo_sw_fx, new_inp_12k8_fx - L_MEM_RECALC_12K8 - ( STEREO_DFT_OVL_12k8 - L_MEM_RECALC_12K8 - L_FILT ), STEREO_DFT_OVL_12k8 - L_MEM_RECALC_12K8 - L_FILT ); /* Q(-1) */ // PREEMPH_FX( new_inp_12k8_fx - L_MEM_RECALC_12K8 - ( STEREO_DFT_OVL_12k8 - L_MEM_RECALC_12K8 - L_FILT ), PREEMPH_FAC, STEREO_DFT_OVL_12k8 - L_MEM_RECALC_12K8 - L_FILT, &st->mem_preemph_fx ); PREEMPH_32FX( new_inp_12k8_fx - L_MEM_RECALC_12K8 - ( STEREO_DFT_OVL_12k8 - L_MEM_RECALC_12K8 - L_FILT ), sig_out, PREEMPH_FAC, STEREO_DFT_OVL_12k8 - L_MEM_RECALC_12K8 - L_FILT, &st->mem_preemph_fx ); preemp_start_idx = new_inp_12k8_fx - L_MEM_RECALC_12K8 - ( STEREO_DFT_OVL_12k8 - L_MEM_RECALC_12K8 - L_FILT ); @@ -661,7 +667,7 @@ ivas_error pre_proc_front_ivas_fx( move16(); } - st->mem_preemph_DFT_fx = old_inp_12k8_fx[L_INP_MEM - STEREO_DFT_OVL_12k8 + L_FRAME - 1]; /* == inp_12k8[L_FRAME-1] */ + st->mem_preemph_DFT_fx = old_inp_12k8_fx[L_INP_MEM - STEREO_DFT_OVL_12k8 + L_FRAME - 1]; /* == inp_12k8[L_FRAME-1] Q_new - 1 */ move16(); } @@ -669,7 +675,7 @@ ivas_error pre_proc_front_ivas_fx( test(); IF( EQ_16( hCPE->last_element_mode, IVAS_CPE_DFT ) && EQ_16( st->idchan, 1 ) ) { - Word16 length_12k8 = NS2SA_FX2( INT_FS_12k8, L_MEM_RECALC_SCH_NS ); + Word16 length_12k8 = NS2SA( INT_FS_12k8, L_MEM_RECALC_SCH_NS ); move16(); // PREEMPH_FX( new_inp_12k8_fx - lMemRecalc_12k8 - length_12k8, PREEMPH_FAC, length_12k8, &st->mem_preemph_fx ); PREEMPH_32FX( new_inp_12k8_fx - lMemRecalc_12k8 - length_12k8, sig_out, PREEMPH_FAC, length_12k8, &st->mem_preemph_fx ); @@ -680,7 +686,7 @@ ivas_error pre_proc_front_ivas_fx( // PREEMPH_FX( new_inp_12k8_fx - lMemRecalc_12k8, PREEMPH_FAC, L_FRAME, &st->mem_preemph_fx ); PREEMPH_32FX( new_inp_12k8_fx - lMemRecalc_12k8, sig_out + preemp_len, PREEMPH_FAC, L_FRAME, &st->mem_preemph_fx ); - dummy_fx = st->mem_preemph_fx; + dummy_fx = st->mem_preemph_fx; /* Q(-1) */ move16(); // PREEMPH_FX( new_inp_12k8_fx - lMemRecalc_12k8 + L_FRAME, PREEMPH_FAC, lMemRecalc_12k8 + L_FILT, &dummy_fx ); PREEMPH_32FX( new_inp_12k8_fx - lMemRecalc_12k8 + L_FRAME, sig_out + preemp_len + L_FRAME, PREEMPH_FAC, lMemRecalc_12k8 + L_FILT, &dummy_fx ); @@ -688,13 +694,13 @@ ivas_error pre_proc_front_ivas_fx( test(); IF( preemp_start_idx && preemp_len ) { - preemp_len = add( preemp_len, add( L_FRAME + L_FILT, lMemRecalc_12k8 ) ); + preemp_len = add( preemp_len, add( L_FRAME + L_FILT, lMemRecalc_12k8 ) ); /* Q0 */ move16(); } ELSE { preemp_start_idx = new_inp_12k8_fx - lMemRecalc_12k8; - preemp_len = add( L_FRAME + L_FILT, lMemRecalc_12k8 ); + preemp_len = add( L_FRAME + L_FILT, lMemRecalc_12k8 ); /* Q) */ move16(); } } @@ -738,9 +744,9 @@ ivas_error pre_proc_front_ivas_fx( st->Q_max[i] = shift; move16(); - Copy_Scale_sig32_16( sig_out, preemp_start_idx, preemp_len, *Q_new ); + Copy_Scale_sig32_16( sig_out, preemp_start_idx, preemp_len, *Q_new ); /* Q_to_be_looked_into + Q_new */ - Scale_sig( old_inp_12k8_fx, (Word16) ( preemp_start_idx - old_inp_12k8_fx ), *Q_new ); + Scale_sig( old_inp_12k8_fx, (Word16) ( preemp_start_idx - old_inp_12k8_fx ), *Q_new ); /* Q(-1) */ *Q_new = add( *Q_new, Q_to_be_looked_into ); move16(); @@ -755,68 +761,16 @@ ivas_error pre_proc_front_ivas_fx( Word16 *lgBin_E_fx; Word32 PS_fx[128]; Word32 band_energies_fx[2 * NB_BANDS]; + Word16 q_band_energies; lgBin_E_fx = NULL; if ( st != NULL ) { lgBin_E_fx = &st->lgBin_E_fx[0]; } - Word16 Scale_fac[2] = { 0 }; - move16(); - move16(); - Scale_sig32( st->Bin_E_fx, L_FFT, sub( add( *Q_new, Q_SCALE - 2 ), st->q_Bin_E ) ); - st->q_Bin_E = add( *Q_new, Q_SCALE - 2 ); - move16(); - Word32 Le_min_scaled = L_shr_r( L_add( L_shr( E_MIN_FXQ15, sub( 14, add( *Q_new, QSCALE - 2 ) ) ), 1 ), 1 ); - ivas_analy_sp_fx_front( element_mode, hCPE, input_Fs, inp_12k8_fx /*old_inp_12k8_e*/, *Q_new, fr_bands_fx, lf_E_fx, &Etot_fx, st->min_band, st->max_band, Le_min_scaled, Scale_fac, st->Bin_E_fx, st->Bin_E_old_fx, PS_fx, lgBin_E_fx, band_energies_fx, fft_buff_fx /*, Q_inp_dmx*/ ); - st->q_Bin_E_old = add( *Q_new, Q_SCALE - 2 ); - move16(); - fr_bands_fx_q = add( *Q_new, QSCALE - 2 ); - band_energies_fx_exp = sub( 31, add( *Q_new, QSCALE - 2 ) ); - Word16 tmp_norm = L_norm_arr( fr_bands_fx, 2 * NB_BANDS ); - IF( GE_16( tmp_norm, 2 ) ) - { - scale_sig32( fr_bands_fx, 2 * NB_BANDS, 2 ); - fr_bands_fx_q = add( fr_bands_fx_q, 2 ); - } - tmp_norm = L_norm_arr( band_energies_fx, 2 * NB_BANDS ); - IF( GE_16( tmp_norm, 2 ) ) - { - scale_sig32( band_energies_fx, 2 * NB_BANDS, 2 ); - band_energies_fx_exp = sub( band_energies_fx_exp, 2 ); - } - Qfact_PS = add( *Q_new, QSCALE - 2 ); - q_lf_E_fx = add( *Q_new, QSCALE - 2 ); - IF( lgBin_E_fx != NULL ) - { - Copy_Scale_sig_16_32( st->lgBin_E_fx, st->Bin_E_fx, L_FFT / 2, sub( st->q_Bin_E, Q7 ) ); - } - - Word16 min_q = MAX_16, fft_q[2]; - Word16 i_sbfr; - FOR( i_sbfr = 0; i_sbfr < 2; i_sbfr++ ) - { - fft_q[i_sbfr] = add( *Q_new, Scale_fac[i_sbfr] ); - move16(); - min_q = s_min( min_q, fft_q[i_sbfr] ); - } - FOR( i_sbfr = 0; i_sbfr < 2; i_sbfr++ ) - { - Scale_sig( fft_buff_fx + i_sbfr * L_FFT, L_FFT, sub( min_q, fft_q[i_sbfr] ) ); - } - *fft_buff_fx_q = min_q; - move16(); - - Word16 Q_bands0 = 0, Q_bands1 = 0; - move16(); - move16(); - - Scale_sig32( st->hNoiseEst->bckr_fx, NB_BANDS, sub( add( *Q_new, QSCALE ), st->hNoiseEst->q_bckr ) ); - st->hNoiseEst->q_bckr = add( *Q_new, QSCALE ); - move16(); - Scale_sig32( st->hNoiseEst->enrO_fx, NB_BANDS, sub( add( *Q_new, QSCALE ), st->hNoiseEst->q_enrO ) ); - st->hNoiseEst->q_enrO = add( *Q_new, QSCALE ); - move16(); + ivas_analy_sp_fx( element_mode, hCPE, input_Fs, inp_12k8_fx /*old_inp_12k8_e*/, *Q_new, fr_bands_fx, &fr_bands_fx_q, lf_E_fx, &q_lf_E_fx, + &Etot_fx, st->min_band, st->max_band, st->Bin_E_fx, &st->q_Bin_E, st->Bin_E_old_fx, &st->q_Bin_E_old, PS_fx, &Qfact_PS, + lgBin_E_fx, band_energies_fx, &q_band_energies, fft_buff_fx, fft_buff_fx_q ); IF( hStereoClassif != NULL ) { @@ -827,10 +781,10 @@ ivas_error pre_proc_front_ivas_fx( } ELSE { - hStereoClassif->silence_flag = sub( hStereoClassif->silence_flag, 1 ); + hStereoClassif->silence_flag = sub( hStereoClassif->silence_flag, 1 ); /* Q0 */ move16(); } - hStereoClassif->silence_flag = s_max( 0, hStereoClassif->silence_flag ); + hStereoClassif->silence_flag = s_max( 0, hStereoClassif->silence_flag ); /* Q0 */ move16(); } @@ -856,15 +810,43 @@ ivas_error pre_proc_front_ivas_fx( move16(); } - st->vad_flag = wb_vad_ivas_fx( st, fr_bands_fx, &i, &i, &i, &snr_sum_he_fx, &localVAD_HE_SAD, &( st->flag_noisy_speech_snr ), *Q_new, NULL, NULL, -MAX_16, -MAX_16 ); //-100000f == max 16bit float + Word16 scale = add( L_norm_arr( st->hNoiseEst->bckr_fx, NB_BANDS ), st->hNoiseEst->q_bckr ); + scale = s_min( scale, add( L_norm_arr( st->hNoiseEst->enrO_fx, NB_BANDS ), st->hNoiseEst->q_enrO ) ); + scale = s_min( scale, fr_bands_fx_q ); + + scale_sig32( st->hNoiseEst->bckr_fx, NB_BANDS, sub( scale, st->hNoiseEst->q_bckr ) ); + st->hNoiseEst->q_bckr = scale; + move16(); + + scale_sig32( st->hNoiseEst->enrO_fx, NB_BANDS, sub( scale, st->hNoiseEst->q_enrO ) ); + st->hNoiseEst->q_enrO = scale; + move16(); + + scale_sig32( fr_bands_fx, 2 * NB_BANDS, sub( scale, fr_bands_fx_q ) ); + fr_bands_fx_q = scale; + move16(); + + st->vad_flag = wb_vad_ivas_fx( st, fr_bands_fx, fr_bands_fx_q, &i, &i, &i, &snr_sum_he_fx, &localVAD_HE_SAD, + &( st->flag_noisy_speech_snr ), NULL, NULL, -MAX_16, -MAX_16 ); //-100000f == max 16bit float move16(); +#ifdef DEBUG_FORCE_DIR + if ( st->force_dir[0] != '\0' ) + { + dbgread( &st->vad_flag, sizeof( int16_t ), 1, fname( st->force_dir, "force_vad_flag.enf", -1, -1, -1 ) ); + } + else + { + dbgwrite( &st->vad_flag, sizeof( int16_t ), 1, 1, "res/force_vad_flag.enf" ); + } +#endif + test(); IF( EQ_16( force_front_vad, 1 ) || EQ_16( front_vad_flag, 1 ) ) { /* overwrite VAD decision with front-VAD decision if external VAD is set to 1*/ - st->vad_flag = front_vad_flag; - st->localVAD = front_vad_flag; + st->vad_flag = front_vad_flag; /* Q0 */ + st->localVAD = front_vad_flag; /* Q0 */ move16(); move16(); } @@ -873,7 +855,7 @@ ivas_error pre_proc_front_ivas_fx( test(); IF( ( hCPE != NULL && !( lr_vad_enabled && st->idchan == 0 ) ) || hSCE != NULL ) { - *vad_flag_dtx = dtx_hangover_addition_fx( st, st->vad_flag, sub( st->lp_speech_fx, st->lp_noise_fx ), 0, vad_hover_flag, NULL, NULL ); + *vad_flag_dtx = ivas_dtx_hangover_addition_fx( st, st->vad_flag, sub( st->lp_speech_fx, st->lp_noise_fx ), 0, vad_hover_flag, NULL, NULL, NULL ); /* Q0 */ move16(); } ELSE @@ -881,14 +863,14 @@ ivas_error pre_proc_front_ivas_fx( /* This only applies to st->idchan==0 now */ /* Add down mix stereo activity to LR vad_flag_dtx */ test(); - *vad_flag_dtx = *vad_flag_dtx || st->vad_flag; + *vad_flag_dtx = *vad_flag_dtx || st->vad_flag; /* Q0 */ move16(); /* Determine hangover flag status based on LR localVAD and downmix localVAD */ test(); test(); - *vad_hover_flag = *vad_flag_dtx && !( LR_localVAD || st->localVAD ); + *vad_hover_flag = *vad_flag_dtx && !( LR_localVAD || st->localVAD ); /* Q0 */ move16(); } @@ -896,7 +878,7 @@ ivas_error pre_proc_front_ivas_fx( if ( EQ_16( force_front_vad, 1 ) || EQ_16( front_vad_dtx_flag, 1 ) ) { /* overwrite VAD decision with front-VAD decision if external VAD is set to 1*/ - *vad_flag_dtx = front_vad_dtx_flag; + *vad_flag_dtx = front_vad_dtx_flag; /* Q0 */ move16(); } @@ -932,53 +914,74 @@ ivas_error pre_proc_front_ivas_fx( test(); if ( EQ_16( st->idchan, 1 ) && EQ_16( element_mode, IVAS_CPE_TD ) && EQ_16( st->tdm_LRTD_flag, 1 ) && GE_16( st->bits_frame_channel, IVAS_16k4 / FRAMES_PER_SEC ) ) { - st->bwidth = hCPE->hCoreCoder[0]->bwidth; + st->bwidth = hCPE->hCoreCoder[0]->bwidth; /* Q0 */ move16(); } +#ifdef DEBUG_FORCE_DIR + if ( st->force_dir[0] != '\0' ) + { + dbgread( &st->bwidth, sizeof( int16_t ), 1, fname( st->force_dir, "force_bwidth.enf", -1, -1, -1 ) ); + } + else + { + dbgwrite( &st->bwidth, sizeof( int16_t ), 1, 1, "res/force_bwidth.enf" ); + } +#endif + + /*----------------------------------------------------------------* * Noise energy down-ward update and total noise energy estimation * Long-term energies and relative frame energy updates * Correlation correction as a function of total noise level *----------------------------------------------------------------*/ - Le_min_scaled = L_shr_r( L_add( L_shr( E_MIN_FXQ15, sub( 14, add( *Q_new, QSCALE ) ) ), 1 ), 1 ); - - noise_est_down_fx( fr_bands_fx, st->hNoiseEst->bckr_fx, tmpN_fx, tmpE_fx, st->min_band, st->max_band, &st->hNoiseEst->totalNoise_fx, Etot_fx, &st->hNoiseEst->Etot_last_fx, &st->hNoiseEst->Etot_v_h2_fx, *Q_new, Le_min_scaled ); - st->hNoiseEst->q_bckr = add( *Q_new, QSCALE ); + noise_est_down_ivas_fx( fr_bands_fx, fr_bands_fx_q, st->hNoiseEst->bckr_fx, tmpN_fx, tmpE_fx, st->min_band, st->max_band, + &st->hNoiseEst->totalNoise_fx, Etot_fx, &st->hNoiseEst->Etot_last_fx, &st->hNoiseEst->Etot_v_h2_fx ); + q_tmpN = fr_bands_fx_q; + q_tmpE = fr_bands_fx_q; + move16(); move16(); test(); IF( lr_vad_enabled && st->idchan == 0 ) { - Scale_sig32( hCPE->hFrontVad[0]->hNoiseEst->bckr_fx, NB_BANDS, sub( add( fr_bands_LR_fx_q, Q_SCALE ), hCPE->hFrontVad[0]->hNoiseEst->q_bckr ) ); - Scale_sig32( hCPE->hFrontVad[1]->hNoiseEst->bckr_fx, NB_BANDS, sub( add( fr_bands_LR_fx_q, Q_SCALE ), hCPE->hFrontVad[1]->hNoiseEst->q_bckr ) ); + scale = add( L_norm_arr( hCPE->hFrontVad[0]->hNoiseEst->bckr_fx, NB_BANDS ), hCPE->hFrontVad[0]->hNoiseEst->q_bckr ); + scale = s_min( scale, add( L_norm_arr( hCPE->hFrontVad[1]->hNoiseEst->bckr_fx, NB_BANDS ), hCPE->hFrontVad[1]->hNoiseEst->q_bckr ) ); + scale = s_min( scale, add( L_norm_arr( fr_bands_LR_fx[0], 2 * NB_BANDS ), fr_bands_LR_fx_q[0] ) ); + scale = s_min( scale, add( L_norm_arr( fr_bands_LR_fx[1], 2 * NB_BANDS ), fr_bands_LR_fx_q[1] ) ); - Word32 Le_min_scaled0, Le_min_scaled1; - Le_min_scaled0 = L_shr_r( L_add( L_shr( E_MIN_FXQ15, sub( 14, add( Q_bands0, QSCALE ) ) ), 1 ), 1 ); - noise_est_down_fx( fr_bands_LR_fx[0], hCPE->hFrontVad[0]->hNoiseEst->bckr_fx, tmpN_LR_fx[0], tmpE_LR_fx[0], st->min_band, st->max_band, &hCPE->hFrontVad[0]->hNoiseEst->totalNoise_fx, Etot_LR_fx[0], &hCPE->hFrontVad[0]->hNoiseEst->Etot_last_fx, &hCPE->hFrontVad[0]->hNoiseEst->Etot_v_h2_fx, Q_bands0, Le_min_scaled0 ); - hCPE->hFrontVad[0]->hNoiseEst->q_bckr = add( Q_bands0, QSCALE ); + scale_sig32( fr_bands_LR_fx[0], 2 * NB_BANDS, sub( scale, fr_bands_LR_fx_q[0] ) ); + fr_bands_LR_fx_q[0] = scale; move16(); - Le_min_scaled1 = L_shr_r( L_add( L_shr( E_MIN_FXQ15, sub( 14, add( Q_bands1, QSCALE ) ) ), 1 ), 1 ); - noise_est_down_fx( fr_bands_LR_fx[1], hCPE->hFrontVad[1]->hNoiseEst->bckr_fx, tmpN_LR_fx[1], tmpE_LR_fx[1], st->min_band, st->max_band, &hCPE->hFrontVad[1]->hNoiseEst->totalNoise_fx, Etot_LR_fx[1], &hCPE->hFrontVad[1]->hNoiseEst->Etot_last_fx, &hCPE->hFrontVad[1]->hNoiseEst->Etot_v_h2_fx, Q_bands1, Le_min_scaled1 ); - hCPE->hFrontVad[1]->hNoiseEst->q_bckr = add( Q_bands1, QSCALE ); + scale_sig32( fr_bands_LR_fx[1], 2 * NB_BANDS, sub( scale, fr_bands_LR_fx_q[1] ) ); + fr_bands_LR_fx_q[1] = scale; move16(); - corr_shiftL_fx = correlation_shift_fx( hCPE->hFrontVad[0]->hNoiseEst->totalNoise_fx ); - corr_shiftR_fx = correlation_shift_fx( hCPE->hFrontVad[1]->hNoiseEst->totalNoise_fx ); - q_tmpN_LR[0] = q_tmpE_LR[0] = add( Q_bands0, QSCALE ); + scale_sig32( hCPE->hFrontVad[0]->hNoiseEst->bckr_fx, NB_BANDS, sub( scale, hCPE->hFrontVad[0]->hNoiseEst->q_bckr ) ); + hCPE->hFrontVad[0]->hNoiseEst->q_bckr = scale; move16(); + scale_sig32( hCPE->hFrontVad[1]->hNoiseEst->bckr_fx, NB_BANDS, sub( scale, hCPE->hFrontVad[1]->hNoiseEst->q_bckr ) ); + hCPE->hFrontVad[1]->hNoiseEst->q_bckr = scale; + move16(); + + noise_est_down_ivas_fx( fr_bands_LR_fx[0], fr_bands_LR_fx_q[0], hCPE->hFrontVad[0]->hNoiseEst->bckr_fx, tmpN_LR_fx[0], tmpE_LR_fx[0], st->min_band, st->max_band, &hCPE->hFrontVad[0]->hNoiseEst->totalNoise_fx, Etot_LR_fx[0], &hCPE->hFrontVad[0]->hNoiseEst->Etot_last_fx, &hCPE->hFrontVad[0]->hNoiseEst->Etot_v_h2_fx ); + noise_est_down_ivas_fx( fr_bands_LR_fx[1], fr_bands_LR_fx_q[1], hCPE->hFrontVad[1]->hNoiseEst->bckr_fx, tmpN_LR_fx[1], tmpE_LR_fx[1], st->min_band, st->max_band, &hCPE->hFrontVad[1]->hNoiseEst->totalNoise_fx, Etot_LR_fx[1], &hCPE->hFrontVad[1]->hNoiseEst->Etot_last_fx, &hCPE->hFrontVad[1]->hNoiseEst->Etot_v_h2_fx ); + + q_tmpN_LR[0] = q_tmpE_LR[0] = scale; move16(); - q_tmpN_LR[1] = q_tmpE_LR[1] = add( Q_bands1, QSCALE ); move16(); + q_tmpN_LR[1] = q_tmpE_LR[1] = scale; move16(); + move16(); + + corr_shiftL_fx = correlation_shift_fx( hCPE->hFrontVad[0]->hNoiseEst->totalNoise_fx ); // Q15 + corr_shiftR_fx = correlation_shift_fx( hCPE->hFrontVad[1]->hNoiseEst->totalNoise_fx ); // Q15 } - q_tmpN = q_tmpE = add( *Q_new, QSCALE ); - move16(); - *relE_fx = sub( Etot_fx, st->lp_speech_fx ); + *relE_fx = sub( Etot_fx, st->lp_speech_fx ); // Q8 move16(); - corr_shift_fx = correlation_shift_fx( st->hNoiseEst->totalNoise_fx ); + corr_shift_fx = correlation_shift_fx( st->hNoiseEst->totalNoise_fx ); /* Q15 */ /*----------------------------------------------------------------* * FD-CNG Noise Estimator @@ -1007,19 +1010,19 @@ ivas_error pre_proc_front_ivas_fx( st->hFdCngEnc->msPeriodog_fx_exp_fft = sub( 31, normmsPeriodog_fx ); move16(); move16(); - Scale_sig32( st->hFdCngEnc->msPeriodog_fx, NPART, normmsPeriodog_fx ); + Scale_sig32( st->hFdCngEnc->msPeriodog_fx, NPART, normmsPeriodog_fx ); /* exp(st->hFdCngEnc->msPeriodog_fx_exp - normmsPeriodog_fx) */ st->hFdCngEnc->msPeriodog_fx_exp = sub( st->hFdCngEnc->msPeriodog_fx_exp, normmsPeriodog_fx ); Word16 msNoiseEst_Q = Q31; move16(); move16(); - zero_flag = get_zero_flag( st->hFdCngEnc->msNoiseEst_fx, NPART ); + zero_flag = get_zero_flag( st->hFdCngEnc->msNoiseEst_old_fx, NPART ); IF( zero_flag ) { - msNoiseEst_Q = getScaleFactor32( st->hFdCngEnc->msNoiseEst_fx, NPART ); + msNoiseEst_Q = getScaleFactor32( st->hFdCngEnc->msNoiseEst_old_fx, NPART ); + scale_sig32( st->hFdCngEnc->msNoiseEst_old_fx, NPART, msNoiseEst_Q ); /* exp(st->hFdCngEnc->msNoiseEst_old_fx_exp - msNoiseEst_Q) */ + st->hFdCngEnc->msNoiseEst_old_fx_exp = sub( st->hFdCngEnc->msNoiseEst_old_fx_exp, msNoiseEst_Q ); + move16(); } - Scale_sig32( st->hFdCngEnc->msNoiseEst_old_fx, NPART, msNoiseEst_Q ); - st->hFdCngEnc->msNoiseEst_fx_exp = sub( st->hFdCngEnc->msNoiseEst_old_fx_exp, msNoiseEst_Q ); - move16(); perform_noise_estimation_enc_ivas_fx( band_energies_LR_fx, sub( Q31, band_energies_LR_fx_q ), enerBuffer_fx, *enerBuffer_fx_exp, st->hFdCngEnc, input_Fs, hCPE ); } ELSE @@ -1029,9 +1032,9 @@ ivas_error pre_proc_front_ivas_fx( move16(); shift = getScaleFactor32( band_energies_fx, 2 * NB_BANDS ); scale_sig32( band_energies_fx, 2 * NB_BANDS, shift ); - band_energies_fx_exp = sub( band_energies_fx_exp, shift ); + q_band_energies = add( q_band_energies, shift ); - zero_flag = get_zero_flag( st->hFdCngEnc->msPeriodog_fx, NPART ); + zero_flag = get_zero_flag( st->hFdCngEnc->msPeriodog_fx, NPART ); /* Q0 */ IF( zero_flag ) { normmsPeriodog_fx = getScaleFactor32( st->hFdCngEnc->msPeriodog_fx, NPART ); @@ -1040,20 +1043,20 @@ ivas_error pre_proc_front_ivas_fx( st->hFdCngEnc->msPeriodog_fx_exp_fft = sub( 31, normmsPeriodog_fx ); move16(); move16(); - Scale_sig32( st->hFdCngEnc->msPeriodog_fx, NPART, normmsPeriodog_fx ); - st->hFdCngEnc->msPeriodog_fx_exp = st->hFdCngEnc->msPeriodog_fx_exp - normmsPeriodog_fx; + Scale_sig32( st->hFdCngEnc->msPeriodog_fx, NPART, normmsPeriodog_fx ); /* exp(st->hFdCngEnc->msPeriodog_fx_exp - normmsPeriodog_fx)*/ + st->hFdCngEnc->msPeriodog_fx_exp = sub( st->hFdCngEnc->msPeriodog_fx_exp, normmsPeriodog_fx ); move16(); Word16 msNoiseEst_Q = Q31; move16(); - zero_flag = get_zero_flag( st->hFdCngEnc->msNoiseEst_fx, NPART ); + zero_flag = get_zero_flag( st->hFdCngEnc->msNoiseEst_old_fx, NPART ); /* Q0 */ IF( zero_flag ) { - msNoiseEst_Q = getScaleFactor32( st->hFdCngEnc->msNoiseEst_fx, NPART ); + msNoiseEst_Q = getScaleFactor32( st->hFdCngEnc->msNoiseEst_old_fx, NPART ); + scale_sig32( st->hFdCngEnc->msNoiseEst_old_fx, NPART, msNoiseEst_Q ); /* exp(st->hFdCngEnc->msNoiseEst_old_fx_exp - msNoiseEst_Q) */ + st->hFdCngEnc->msNoiseEst_old_fx_exp = sub( st->hFdCngEnc->msNoiseEst_old_fx_exp, msNoiseEst_Q ); + move16(); } - Scale_sig32( st->hFdCngEnc->msNoiseEst_old_fx, NPART, msNoiseEst_Q ); - st->hFdCngEnc->msNoiseEst_fx_exp = st->hFdCngEnc->msNoiseEst_old_fx_exp - msNoiseEst_Q; - move16(); - zero_flag = get_zero_flag( st->hFdCngEnc->hFdCngCom->periodog, PERIODOGLEN ); + zero_flag = get_zero_flag( st->hFdCngEnc->hFdCngCom->periodog, PERIODOGLEN ); /* Q0 */ Word16 normmsperiodog = 31; move16(); IF( zero_flag ) @@ -1063,7 +1066,7 @@ ivas_error pre_proc_front_ivas_fx( st->hFdCngEnc->hFdCngCom->exp_cldfb_periodog = sub( 31, normmsperiodog ); move16(); - perform_noise_estimation_enc_ivas_fx( band_energies_fx, band_energies_fx_exp, enerBuffer_fx, *enerBuffer_fx_exp, st->hFdCngEnc, input_Fs, hCPE ); + perform_noise_estimation_enc_ivas_fx( band_energies_fx, sub( Q31, q_band_energies ), enerBuffer_fx, *enerBuffer_fx_exp, st->hFdCngEnc, input_Fs, hCPE ); } } } @@ -1088,14 +1091,19 @@ ivas_error pre_proc_front_ivas_fx( st->cng_type = LP_CNG; move16(); } + +#ifdef NONBE_1211_DTX_BR_SWITCHING + dtx_ivas_fx( st, last_ivas_total_brate, ivas_total_brate, *vad_flag_dtx, inp_12k8_fx, *Q_new ); +#else dtx_ivas_fx( st, ivas_total_brate, *vad_flag_dtx, inp_12k8_fx, *Q_new ); +#endif test(); test(); IF( hCPE != NULL && hCPE->hStereoDft != NULL && EQ_32( st->core_brate, SID_2k40 ) ) { /* Add another period of expected xcorr updates */ - hCPE->hStereoDft->expectedNumUpdates = add( hCPE->hStereoDft->expectedNumUpdates, st->hDtxEnc->max_SID ); + hCPE->hStereoDft->expectedNumUpdates = add( hCPE->hStereoDft->expectedNumUpdates, st->hDtxEnc->max_SID ); /* Q0 */ move16(); } @@ -1111,17 +1119,17 @@ ivas_error pre_proc_front_ivas_fx( IF( EQ_16( element_mode, IVAS_SCE ) ) { - total_brate = st->total_brate; + total_brate = st->total_brate; /* Q0 */ move32(); } ELSE { - total_brate = imult3216( FRAMES_PER_SEC, st->bits_frame_nominal ); + total_brate = imult3216( FRAMES_PER_SEC, st->bits_frame_nominal ); /* Q0 */ } configureFdCngEnc_ivas_fx( st->hFdCngEnc, s_max( st->input_bwidth, WB ), total_brate ); IF( hCPE != NULL ) { - st->hFdCngEnc->hFdCngCom->CngBitrate = L_sub( hCPE->element_brate, 1 ); + st->hFdCngEnc->hFdCngCom->CngBitrate = L_sub( hCPE->element_brate, 1 ); /* Q0 */ move32(); } } @@ -1136,29 +1144,29 @@ ivas_error pre_proc_front_ivas_fx( IF( zero_flag ) { msPeriodog_fx_Q = getScaleFactor32( st->hFdCngEnc->msPeriodog_fx, NPART ); - scale_sig32( st->hFdCngEnc->msPeriodog_fx, NPART, msPeriodog_fx_Q ); + scale_sig32( st->hFdCngEnc->msPeriodog_fx, NPART, msPeriodog_fx_Q ); /* exp(st->hFdCngEnc->msPeriodog_fx_exp - msPeriodog_fx_Q) */ st->hFdCngEnc->msPeriodog_fx_exp = sub( st->hFdCngEnc->msPeriodog_fx_exp, msPeriodog_fx_Q ); move16(); } Word16 energy_ho_fx_Q = Q31; move16(); - zero_flag = get_zero_flag( st->hFdCngEnc->energy_ho_fx, NPART ); + zero_flag = get_zero_flag( st->hFdCngEnc->energy_ho_fx, NPART ); /* Q0 */ IF( zero_flag ) { energy_ho_fx_Q = getScaleFactor32( st->hFdCngEnc->energy_ho_fx, NPART ); - scale_sig32( st->hFdCngEnc->energy_ho_fx, NPART, energy_ho_fx_Q ); + scale_sig32( st->hFdCngEnc->energy_ho_fx, NPART, energy_ho_fx_Q ); /* exp(st->hFdCngEnc->energy_ho_fx_exp - energy_ho_fx_Q) */ st->hFdCngEnc->energy_ho_fx_exp = sub( st->hFdCngEnc->energy_ho_fx_exp, energy_ho_fx_Q ); move16(); } Word16 msNoiseEst_old_Q = Q31; move16(); - zero_flag = get_zero_flag( st->hFdCngEnc->msNoiseEst_old_fx, NPART ); + zero_flag = get_zero_flag( st->hFdCngEnc->msNoiseEst_old_fx, NPART ); /* Q0 */ IF( zero_flag ) { msNoiseEst_old_Q = getScaleFactor32( st->hFdCngEnc->msNoiseEst_old_fx, NPART ); - scale_sig32( st->hFdCngEnc->msNoiseEst_old_fx, NPART, msNoiseEst_old_Q ); + scale_sig32( st->hFdCngEnc->msNoiseEst_old_fx, NPART, msNoiseEst_old_Q ); /* exp(st->hFdCngEnc->msNoiseEst_old_fx_exp - msNoiseEst_old_Q) */ st->hFdCngEnc->msNoiseEst_old_fx_exp = sub( st->hFdCngEnc->msNoiseEst_old_fx_exp, msNoiseEst_old_Q ); move16(); } @@ -1182,13 +1190,13 @@ ivas_error pre_proc_front_ivas_fx( Q_new_loc = *Q_new; move16(); - alw_pitch_lag_12k8[0] = st->old_pitch_la; + alw_pitch_lag_12k8[0] = st->old_pitch_la; /* Q0 */ move16(); - alw_pitch_lag_12k8[1] = st->old_pitch_la; + alw_pitch_lag_12k8[1] = st->old_pitch_la; /* Q0 */ move16(); - alw_voicing_fx[0] = st->voicing_fx[2]; + alw_voicing_fx[0] = st->voicing_fx[2]; /* Q15 */ move16(); - alw_voicing_fx[1] = st->voicing_fx[2]; + alw_voicing_fx[1] = st->voicing_fx[2]; /* Q15 */ move16(); i = 0; @@ -1215,9 +1223,9 @@ ivas_error pre_proc_front_ivas_fx( lsp2lsf_fx( lsp_new_fx, lsf_new_fx, M, INT_FS_12k8 ); - stab_fac_fx = lsf_stab_fx( lsf_new_fx, st->lsf_old1_fx, 0, L_FRAME ); + stab_fac_fx = lsf_stab_fx( lsf_new_fx, st->lsf_old1_fx, 0, L_FRAME ); /* Q15 */ - Copy( lsf_new_fx, st->lsf_old1_fx, M ); + Copy( lsf_new_fx, st->lsf_old1_fx, M ); /* Q2.56 */ test(); IF( EQ_16( element_mode, IVAS_CPE_TD ) && EQ_16( st->idchan, 1 ) ) @@ -1227,8 +1235,8 @@ ivas_error pre_proc_front_ivas_fx( * to reuse the primary channel LP coefficients in the secondary channel *----------------------------------------------------------------*/ Word32 speech_buff[L_FRAME + M]; - Copy_Scale_sig_16_32( inp_12k8_fx - M, speech_buff, L_FRAME + M, Q12 ); - hCPE->hStereoTD->tdm_lp_reuse_flag = tdm_lp_comparison_fx( hCPE->hStereoTD, hCPE->hStereoClassif, st, &speech_buff[0], tdm_A_PCh_fx, A_fx, M, tdm_lsp_new_PCh_fx, lsp_new_fx, L_FRAME, L_sub( element_brate, imult3216( FRAMES_PER_SEC, nb_bits_metadata ) ), add( *Q_new, 12 ) ); + Copy_Scale_sig_16_32_DEPREC( inp_12k8_fx - M, speech_buff, L_FRAME + M, Q12 ); /* Q_new + 12 */ + hCPE->hStereoTD->tdm_lp_reuse_flag = tdm_lp_comparison_fx( hCPE->hStereoTD, hCPE->hStereoClassif, st, &speech_buff[0], tdm_A_PCh_fx, A_fx, M, tdm_lsp_new_PCh_fx, lsp_new_fx, L_FRAME, L_sub( element_brate, imult3216( FRAMES_PER_SEC, nb_bits_metadata ) ), add( *Q_new, 12 ) ); /* Q0 */ move16(); } @@ -1239,12 +1247,12 @@ ivas_error pre_proc_front_ivas_fx( * 1/4 pitch precision improvement *----------------------------------------------------------------*/ - st->mem_wsp_fx = shl( st->mem_wsp_fx, sub( *Q_new, st->mem_wsp_q ) ); + st->mem_wsp_fx = shl( st->mem_wsp_fx, sub( *Q_new, st->mem_wsp_q ) ); /* Q_new */ st->mem_wsp_q = *Q_new; move16(); move16(); - ivas_find_wsp( L_FRAME, L_SUBFR, NB_SUBFR, A_fx, Aw_fx, inp_12k8_fx, TILT_FAC_FX, wsp_fx, &st->mem_wsp_fx, GAMMA1, L_LOOK_12k8 ); + ivas_find_wsp_fx( L_FRAME, L_SUBFR, NB_SUBFR, A_fx, Aw_fx, inp_12k8_fx, TILT_FAC_FX, wsp_fx, &st->mem_wsp_fx, GAMMA1, L_LOOK_12k8 ); Word16 Q_wsp = *Q_new; move16(); @@ -1256,8 +1264,8 @@ ivas_error pre_proc_front_ivas_fx( old_pitch1 = st->pitch[1]; move16(); - Word16 shift1 = getScaleFactor16( old_wsp_fx, L_WSP_MEM ); - Word16 shift2 = getScaleFactor16( wsp_fx, L_WSP - L_WSP_MEM ); + Word16 shift1 = norm_arr( old_wsp_fx, L_WSP_MEM ); + Word16 shift2 = norm_arr( wsp_fx, L_WSP - L_WSP_MEM ); maximum_abs_16_fx( old_wsp_fx, L_WSP_MEM, &shift ); if ( !shift ) { @@ -1271,111 +1279,37 @@ ivas_error pre_proc_front_ivas_fx( move16(); } shift = s_min( add( *q_old_wsp, shift1 ), add( Q_wsp, shift2 ) ); - Scale_sig( old_wsp_fx, L_WSP_MEM, sub( shift, *q_old_wsp ) ); - Scale_sig( wsp_fx, L_WSP - L_WSP_MEM, sub( shift, Q_wsp ) ); + shift = s_min( shift, add( norm_arr( st->mem_decim2_fx, 3 ), st->Q_old_wsp2 ) ); + shift = s_min( shift, add( norm_arr( st->old_wsp2_fx, ( L_WSP_MEM - L_INTERPOL ) / OPL_DECIM ), st->Q_old_wsp2 ) ); + scale_sig( old_wsp_fx, L_WSP_MEM, sub( shift, *q_old_wsp ) ); + scale_sig( wsp_fx, L_WSP - L_WSP_MEM, sub( shift, Q_wsp ) ); + *q_old_wsp = shift; move16(); Q_wsp = shift; move16(); - Scale_sig( st->mem_decim2_fx, 3, sub( Q_wsp, st->Q_old_wsp2 ) ); // Q( mem_decim ) = Q( old_wsp2 ) - Scale_sig( st->old_wsp2_fx, ( L_WSP_MEM - L_INTERPOL ) / OPL_DECIM, sub( Q_wsp, st->Q_old_wsp2 ) ); + scale_sig( st->mem_decim2_fx, 3, sub( Q_wsp, st->Q_old_wsp2 ) ); // Q( mem_decim ) = Q( old_wsp2 ) + scale_sig( st->old_wsp2_fx, ( L_WSP_MEM - L_INTERPOL ) / OPL_DECIM, sub( Q_wsp, st->Q_old_wsp2 ) ); // Q_wsp + st->Q_old_wsp2 = Q_wsp; move16(); pitch_ol_ivas_fx( st->pitch, st->voicing_fx, &st->old_pitch, &st->old_corr_fx, corr_shift_fx, &st->old_thres_fx, - &st->delta_pit, st->old_wsp2_fx, wsp_fx, st->mem_decim2_fx, *relE_fx, st->clas, st->input_bwidth, st->Opt_SC_VBR ); + &st->delta_pit, st->old_wsp2_fx, wsp_fx, st->mem_decim2_fx, *relE_fx, st->clas, st->input_bwidth, st->Opt_SC_VBR, Q_wsp ); /* Updates for adaptive lag window memory */ - st->old_pitch_la = st->pitch[2]; + st->old_pitch_la = st->pitch[2]; /* Q0 */ move16(); - test(); - IF( lr_vad_enabled && st->idchan == 0 ) - { - FOR( i = 0; i < 2; i++ ) - { - shift = getScaleFactor32( tmpN_LR_fx[i], NB_BANDS ); - scale_sig32( tmpN_LR_fx[i], NB_BANDS, shift ); - q_tmpN_LR[i] = add( q_tmpN_LR[i], shift ); - move16(); + shift = sub( norm_arr( old_wsp_fx, L_WSP ), 3 ); + scale_sig( old_wsp_fx, L_WSP, shift ); - shift = getScaleFactor32( tmpE_LR_fx[i], NB_BANDS ); - scale_sig32( tmpE_LR_fx[i], NB_BANDS, shift ); - q_tmpE_LR[i] = add( q_tmpE_LR[i], shift ); - move16(); - } - } - shift = getScaleFactor32( tmpN_fx, NB_BANDS ); - scale_sig32( tmpN_fx, NB_BANDS, shift ); - q_tmpN = add( q_tmpN, shift ); - shift = getScaleFactor32( tmpE_fx, NB_BANDS ); - scale_sig32( tmpE_fx, NB_BANDS, shift ); - q_tmpE = add( q_tmpE, shift ); - - shift = getScaleFactor32( lf_E_fx, 2 * VOIC_BINS ); - scale_sig32( lf_E_fx, 2 * VOIC_BINS, shift ); - q_lf_E_fx = add( q_lf_E_fx, shift ); - - shift = sub( getScaleFactor16( old_wsp_fx, L_WSP ), 3 ); - Scale_sig( old_wsp_fx, L_WSP, shift ); *q_old_wsp = add( *q_old_wsp, shift ); move16(); Q_wsp = *q_old_wsp; move16(); - Word16 q_fr_bands = Q30; - move16(); - q_fr_bands = s_min( q_fr_bands, q_tmpN ); - q_fr_bands = s_min( q_fr_bands, q_tmpE ); - q_fr_bands = s_min( q_fr_bands, sub( fr_bands_fx_q, 4 ) /* needs 4 gaurd bits for summation */ ); - q_fr_bands = s_min( q_fr_bands, st->hNoiseEst->q_bckr ); - q_fr_bands = s_min( q_fr_bands, st->hNoiseEst->fr_bands_fx_q ); - q_fr_bands = s_min( q_fr_bands, st->hNoiseEst->ave_enr_q ); - q_fr_bands = s_min( q_fr_bands, add( q_lf_E_fx, 2 ) ); - - test(); - IF( lr_vad_enabled && st->idchan == 0 ) - { - FOR( Word16 j = 0; j < 2; j++ ) - { - q_fr_bands = s_min( q_fr_bands, add( lf_E_LR_fx_q, 2 ) ); - q_fr_bands = s_min( q_fr_bands, q_tmpN_LR[j] ); - q_fr_bands = s_min( q_fr_bands, q_tmpE_LR[j] ); - q_fr_bands = s_min( q_fr_bands, fr_bands_LR_fx_q ); - q_fr_bands = s_min( q_fr_bands, hCPE->hFrontVad[j]->hNoiseEst->q_bckr ); - q_fr_bands = s_min( q_fr_bands, hCPE->hFrontVad[j]->hNoiseEst->fr_bands_fx_q ); - q_fr_bands = s_min( q_fr_bands, hCPE->hFrontVad[j]->hNoiseEst->ave_enr_q ); - } - } - Word16 q_inp_12k8 = *Q_new; // inp_12k8_fx - move16(); - - scale_sig32( lf_E_fx, 2 * VOIC_BINS, sub( sub( q_fr_bands, 2 ), q_lf_E_fx ) ); - q_lf_E_fx = sub( q_fr_bands, 2 ); - scale_sig32( tmpN_fx, NB_BANDS, sub( q_fr_bands, q_tmpN ) ); - q_tmpN = q_fr_bands; - - scale_sig32( tmpE_fx, NB_BANDS, sub( q_fr_bands, q_tmpE ) ); - q_tmpE = q_fr_bands; - - test(); - IF( lr_vad_enabled && st->idchan == 0 ) - { - FOR( i = 0; i < 2; i++ ) - { - scale_sig32( tmpN_LR_fx[i], NB_BANDS, sub( q_fr_bands, q_tmpN_LR[i] ) ); - q_tmpN_LR[i] = q_fr_bands; - move16(); - scale_sig32( tmpE_LR_fx[i], NB_BANDS, sub( q_fr_bands, q_tmpE_LR[i] ) ); - q_tmpE_LR[i] = q_fr_bands; - move16(); - } - } - scale_sig32( fr_bands_fx, 2 * NB_BANDS, sub( q_fr_bands, fr_bands_fx_q ) ); - fr_bands_fx_q = q_fr_bands; - move16(); - - Copy_Scale_sig_32_16( st->Bin_E_fx, st->lgBin_E_fx, L_FFT / 2, sub( Q7, st->q_Bin_E ) ); + Copy_Scale_sig_32_16( st->Bin_E_fx, st->lgBin_E_fx, L_FFT / 2, sub( Q7, st->q_Bin_E ) ); /* Q7 */ /* Detection of very short stable pitch period */ StableHighPitchDetect_ivas_fx( &flag_spitch, st->pitch, st->voicing_fx, wsp_fx, st->localVAD, &st->voicing_sm_fx, &st->voicing0_sm_fx, &st->LF_EnergyRatio_sm_fx, &st->predecision_flag, &st->diff_sm_fx, &st->energy_sm_fx, *q_old_wsp, st->lgBin_E_fx ); @@ -1412,104 +1346,96 @@ ivas_error pre_proc_front_ivas_fx( /*------------------------------------------------------------------* * Update estimated noise energy and voicing cut-off frequency *-----------------------------------------------------------------*/ - - scale_sig32( st->hNoiseEst->bckr_fx, NB_BANDS, sub( q_fr_bands, st->hNoiseEst->q_bckr ) ); - st->hNoiseEst->q_bckr = q_fr_bands; - move16(); - scale_sig32( st->hNoiseEst->fr_bands1_fx, NB_BANDS, sub( q_fr_bands, st->hNoiseEst->fr_bands_fx_q ) ); - scale_sig32( st->hNoiseEst->fr_bands2_fx, NB_BANDS, sub( q_fr_bands, st->hNoiseEst->fr_bands_fx_q ) ); - st->hNoiseEst->fr_bands_fx_q = q_fr_bands; - move16(); - scale_sig32( st->hNoiseEst->ave_enr_fx, NB_BANDS, sub( q_fr_bands, st->hNoiseEst->ave_enr_q ) ); - scale_sig32( st->hNoiseEst->ave_enr2_fx, NB_BANDS, sub( q_fr_bands, st->hNoiseEst->ave_enr_q ) ); - st->hNoiseEst->ave_enr_q = q_fr_bands; - move16(); - - FOR( Word16 k = 0; k < NB_BANDS; k++ ) { - fr_bands_fx[k] = L_max( 1, fr_bands_fx[k] ); - move32(); + // TODO: this scalings to be checked + scale = s_min( Q30, add( st->hNoiseEst->q_bckr, L_norm_arr( st->hNoiseEst->bckr_fx, NB_BANDS ) ) ); + scale = s_min( scale, sub( add( fr_bands_fx_q, L_norm_arr( fr_bands_fx, 2 * NB_BANDS ) ), 4 ) ); + scale_sig32( st->hNoiseEst->bckr_fx, NB_BANDS, sub( scale, st->hNoiseEst->q_bckr ) ); + scale_sig32( fr_bands_fx, 2 * NB_BANDS, sub( scale, fr_bands_fx_q ) ); + st->hNoiseEst->q_bckr = fr_bands_fx_q = scale; } - noise_est_ivas_fx( st, old_pitch1, tmpN_fx, epsP_h, epsP_l, Etot_fx, *relE_fx, corr_shift_fx, tmpE_fx, fr_bands_fx, cor_map_sum_fx, &ncharX_fx, &sp_div_fx, &q_sp_div, - &non_staX_fx, loc_harm, lf_E_fx, &st->hNoiseEst->harm_cor_cnt, st->hNoiseEst->Etot_l_lp_fx, st->hNoiseEst->Etot_v_h2_fx, &st->hNoiseEst->bg_cnt, st->lgBin_E_fx, sub( q_fr_bands, QSCALE ), L_shl( E_MIN_IVAS_FX, sub( q_fr_bands, Q19 ) ), &dummy_fx, S_map_fx, hStereoClassif, NULL, st->ini_frame ); + scale = s_min( Q31, s_min( add( q_tmpN, L_norm_arr( tmpN_fx, NB_BANDS ) ), add( st->hNoiseEst->q_bckr, L_norm_arr( st->hNoiseEst->bckr_fx, NB_BANDS ) ) ) ); + scale = sub( scale, 1 ); // guard bits + scale_sig32( st->hNoiseEst->bckr_fx, NB_BANDS, sub( scale, st->hNoiseEst->q_bckr ) ); + scale_sig32( tmpN_fx, NB_BANDS, sub( scale, q_tmpN ) ); + st->hNoiseEst->q_bckr = q_tmpN = scale; + move16(); + move16(); - /*Scaling to avoid 0 values*/ - shift = s_min( L_norm_arr( st->hNoiseEst->fr_bands1_fx, NB_BANDS ), L_norm_arr( st->hNoiseEst->fr_bands2_fx, NB_BANDS ) ); - scale_sig32( st->hNoiseEst->fr_bands1_fx, NB_BANDS, shift ); - scale_sig32( st->hNoiseEst->fr_bands2_fx, NB_BANDS, shift ); - st->hNoiseEst->fr_bands_fx_q = add( st->hNoiseEst->fr_bands_fx_q, shift ); + scale = s_min( Q31, add( st->hNoiseEst->ave_enr_q, s_min( L_norm_arr( st->hNoiseEst->ave_enr_fx, NB_BANDS ), L_norm_arr( st->hNoiseEst->ave_enr2_fx, NB_BANDS ) ) ) ); + scale = s_min( scale, add( q_tmpE, L_norm_arr( tmpE_fx, NB_BANDS ) ) ); + scale = sub( scale, 1 ); // guard bits + scale_sig32( tmpE_fx, NB_BANDS, sub( scale, q_tmpE ) ); + scale_sig32( st->hNoiseEst->ave_enr_fx, NB_BANDS, sub( scale, st->hNoiseEst->ave_enr_q ) ); + scale_sig32( st->hNoiseEst->ave_enr2_fx, NB_BANDS, sub( scale, st->hNoiseEst->ave_enr_q ) ); + st->hNoiseEst->ave_enr_q = q_tmpE = scale; move16(); - shift = s_min( L_norm_arr( st->hNoiseEst->ave_enr_fx, NB_BANDS ), L_norm_arr( st->hNoiseEst->ave_enr2_fx, NB_BANDS ) ); - scale_sig32( st->hNoiseEst->ave_enr_fx, NB_BANDS, shift ); - scale_sig32( st->hNoiseEst->ave_enr2_fx, NB_BANDS, shift ); - st->hNoiseEst->ave_enr_q = add( st->hNoiseEst->ave_enr_q, shift ); move16(); - shift = L_norm_arr( st->hNoiseEst->bckr_fx, NB_BANDS ); - scale_sig32( st->hNoiseEst->bckr_fx, NB_BANDS, shift ); - st->hNoiseEst->q_bckr = add( st->hNoiseEst->q_bckr, shift ); + + scale = add( st->hNoiseEst->fr_bands_fx_q, s_min( L_norm_arr( st->hNoiseEst->fr_bands1_fx, NB_BANDS ), L_norm_arr( st->hNoiseEst->fr_bands2_fx, NB_BANDS ) ) ); + scale = s_min( scale, add( fr_bands_fx_q, L_norm_arr( fr_bands_fx, 2 * NB_BANDS ) ) ); + scale_sig32( fr_bands_fx, 2 * NB_BANDS, sub( scale, fr_bands_fx_q ) ); + scale_sig32( st->hNoiseEst->fr_bands1_fx, NB_BANDS, sub( scale, st->hNoiseEst->fr_bands_fx_q ) ); + scale_sig32( st->hNoiseEst->fr_bands2_fx, NB_BANDS, sub( scale, st->hNoiseEst->fr_bands_fx_q ) ); + st->hNoiseEst->fr_bands_fx_q = fr_bands_fx_q = scale; move16(); - shift = L_norm_arr( st->hNoiseEst->enrO_fx, NB_BANDS ); - scale_sig32( st->hNoiseEst->enrO_fx, NB_BANDS, shift ); - st->hNoiseEst->q_enrO = add( st->hNoiseEst->q_enrO, shift ); move16(); + noise_est_ivas_fx( st, old_pitch1, tmpN_fx, epsP_fx, Etot_fx, *relE_fx, corr_shift_fx, tmpE_fx, q_tmpE, fr_bands_fx, fr_bands_fx_q, cor_map_sum_fx, + &ncharX_fx, &sp_div_fx, &q_sp_div, &non_staX_fx, loc_harm, lf_E_fx, q_lf_E_fx, &st->hNoiseEst->harm_cor_cnt, st->hNoiseEst->Etot_l_lp_fx, + st->hNoiseEst->Etot_v_h2_fx, &st->hNoiseEst->bg_cnt, st->lgBin_E_fx, &dummy_fx, S_map_fx, + hStereoClassif, NULL, st->ini_frame ); + test(); IF( lr_vad_enabled && st->idchan == 0 ) { FOR( Word16 j = 0; j < 2; j++ ) { - scale_sig32( hCPE->hFrontVad[j]->hNoiseEst->bckr_fx, NB_BANDS, sub( q_fr_bands, hCPE->hFrontVad[j]->hNoiseEst->q_bckr ) ); - hCPE->hFrontVad[j]->hNoiseEst->q_bckr = q_fr_bands; + scale = s_min( add( q_tmpN_LR[j], L_norm_arr( tmpN_LR_fx[j], NB_BANDS ) ), add( hCPE->hFrontVad[j]->hNoiseEst->q_bckr, L_norm_arr( hCPE->hFrontVad[j]->hNoiseEst->bckr_fx, NB_BANDS ) ) ); + scale = sub( s_min( Q31, scale ), 1 ); + scale_sig32( hCPE->hFrontVad[j]->hNoiseEst->bckr_fx, NB_BANDS, sub( scale, hCPE->hFrontVad[j]->hNoiseEst->q_bckr ) ); + scale_sig32( tmpN_LR_fx[j], NB_BANDS, sub( scale, q_tmpN_LR[j] ) ); + hCPE->hFrontVad[j]->hNoiseEst->q_bckr = q_tmpN_LR[j] = scale; move16(); - scale_sig32( hCPE->hFrontVad[j]->hNoiseEst->fr_bands1_fx, NB_BANDS, sub( q_fr_bands, hCPE->hFrontVad[j]->hNoiseEst->fr_bands_fx_q ) ); - scale_sig32( hCPE->hFrontVad[j]->hNoiseEst->fr_bands2_fx, NB_BANDS, sub( q_fr_bands, hCPE->hFrontVad[j]->hNoiseEst->fr_bands_fx_q ) ); - hCPE->hFrontVad[j]->hNoiseEst->fr_bands_fx_q = q_fr_bands; move16(); - scale_sig32( hCPE->hFrontVad[j]->hNoiseEst->ave_enr_fx, NB_BANDS, sub( q_fr_bands, hCPE->hFrontVad[j]->hNoiseEst->ave_enr_q ) ); - scale_sig32( hCPE->hFrontVad[j]->hNoiseEst->ave_enr2_fx, NB_BANDS, sub( q_fr_bands, hCPE->hFrontVad[j]->hNoiseEst->ave_enr_q ) ); - hCPE->hFrontVad[j]->hNoiseEst->ave_enr_q = q_fr_bands; - move16(); - shift = L_norm_arr( hCPE->hFrontVad[j]->hNoiseEst->bckr_fx, NB_BANDS ); - scale_sig32( hCPE->hFrontVad[j]->hNoiseEst->bckr_fx, NB_BANDS, shift ); - hCPE->hFrontVad[j]->hNoiseEst->q_bckr = add( hCPE->hFrontVad[j]->hNoiseEst->q_bckr, shift ); + + scale = add( hCPE->hFrontVad[j]->hNoiseEst->ave_enr_q, s_min( L_norm_arr( hCPE->hFrontVad[j]->hNoiseEst->ave_enr_fx, NB_BANDS ), L_norm_arr( hCPE->hFrontVad[j]->hNoiseEst->ave_enr2_fx, NB_BANDS ) ) ); + scale = s_min( scale, add( q_tmpE_LR[j], L_norm_arr( tmpE_LR_fx[j], NB_BANDS ) ) ); + scale = sub( s_min( Q31, scale ), 1 ); + scale_sig32( tmpE_LR_fx[j], NB_BANDS, sub( scale, q_tmpE_LR[j] ) ); + scale_sig32( hCPE->hFrontVad[j]->hNoiseEst->ave_enr_fx, NB_BANDS, sub( scale, hCPE->hFrontVad[j]->hNoiseEst->ave_enr_q ) ); + scale_sig32( hCPE->hFrontVad[j]->hNoiseEst->ave_enr2_fx, NB_BANDS, sub( scale, hCPE->hFrontVad[j]->hNoiseEst->ave_enr_q ) ); + hCPE->hFrontVad[j]->hNoiseEst->ave_enr_q = q_tmpE_LR[j] = scale; move16(); - shift = L_norm_arr( hCPE->hFrontVad[j]->hNoiseEst->enrO_fx, NB_BANDS ); - scale_sig32( hCPE->hFrontVad[j]->hNoiseEst->enrO_fx, NB_BANDS, shift ); - hCPE->hFrontVad[j]->hNoiseEst->q_enrO = add( hCPE->hFrontVad[j]->hNoiseEst->q_enrO, shift ); move16(); - FOR( Word16 k = 0; k < NB_BANDS; k++ ) - { - hCPE->hFrontVad[j]->hNoiseEst->fr_bands1_fx[k] = L_max( 1, hCPE->hFrontVad[j]->hNoiseEst->fr_bands1_fx[k] ); - move32(); - hCPE->hFrontVad[j]->hNoiseEst->fr_bands2_fx[k] = L_max( 1, hCPE->hFrontVad[j]->hNoiseEst->fr_bands2_fx[k] ); - move32(); - } + scale = add( hCPE->hFrontVad[j]->hNoiseEst->fr_bands_fx_q, s_min( L_norm_arr( hCPE->hFrontVad[j]->hNoiseEst->fr_bands1_fx, NB_BANDS ), L_norm_arr( hCPE->hFrontVad[j]->hNoiseEst->fr_bands2_fx, NB_BANDS ) ) ); + scale = s_min( scale, add( fr_bands_LR_fx_q[j], L_norm_arr( fr_bands_LR_fx[j], 2 * NB_BANDS ) ) ); + scale_sig32( fr_bands_LR_fx[j], 2 * NB_BANDS, sub( scale, fr_bands_LR_fx_q[j] ) ); + scale_sig32( hCPE->hFrontVad[j]->hNoiseEst->fr_bands1_fx, NB_BANDS, sub( scale, hCPE->hFrontVad[j]->hNoiseEst->fr_bands_fx_q ) ); + scale_sig32( hCPE->hFrontVad[j]->hNoiseEst->fr_bands2_fx, NB_BANDS, sub( scale, hCPE->hFrontVad[j]->hNoiseEst->fr_bands_fx_q ) ); + hCPE->hFrontVad[j]->hNoiseEst->fr_bands_fx_q = fr_bands_LR_fx_q[j] = scale; + move16(); + move16(); } - /* Run noise_est for Left and Right channel */ *loc_harmLR_fx = *loc_harm; - noise_est_ivas_fx( st, old_pitch1, tmpN_LR_fx[0], epsP_h, epsP_l, Etot_LR_fx[0], sub( Etot_LR_fx[0], hCPE->hFrontVad[0]->lp_speech_fx ), corr_shiftL_fx, tmpE_LR_fx[0], fr_bands_LR_fx[0], &cor_map_sum_LR_fx[0], &ncharX_LR_fx, &sp_div_LR_fx, &q_sp_div_LR, - &non_staX_LR_fx, loc_harmLR_fx, lf_E_LR_fx[0], &hCPE->hFrontVad[0]->hNoiseEst->harm_cor_cnt, hCPE->hFrontVad[0]->hNoiseEst->Etot_l_lp_fx, hCPE->hFrontVad[0]->hNoiseEst->Etot_v_h2_fx, &hCPE->hFrontVad[0]->hNoiseEst->bg_cnt, st->lgBin_E_fx, sub( q_fr_bands, QSCALE ), L_shl( E_MIN_IVAS_FX, sub( q_fr_bands, Q19 ) ), &dummy_fx, S_map_LR_fx, NULL, hCPE->hFrontVad[0], hCPE->hFrontVad[0]->ini_frame ); - - /* Note: the index [0] in the last argument is intended, the ini_frame counter is only maintained in the zero-th channel's VAD handle */ - noise_est_ivas_fx( st, old_pitch1, tmpN_LR_fx[1], epsP_h, epsP_l, Etot_LR_fx[1], sub( Etot_LR_fx[1], hCPE->hFrontVad[1]->lp_speech_fx ), corr_shiftR_fx, tmpE_LR_fx[1], fr_bands_LR_fx[1], &cor_map_sum_LR_fx[1], &ncharX_LR_fx, &sp_div_LR_fx, &q_sp_div_LR, - &non_staX_LR_fx, loc_harmLR_fx, lf_E_LR_fx[1], &hCPE->hFrontVad[1]->hNoiseEst->harm_cor_cnt, hCPE->hFrontVad[1]->hNoiseEst->Etot_l_lp_fx, hCPE->hFrontVad[1]->hNoiseEst->Etot_v_h2_fx, &hCPE->hFrontVad[1]->hNoiseEst->bg_cnt, st->lgBin_E_fx, sub( q_fr_bands, QSCALE ), L_shl( E_MIN_IVAS_FX, sub( q_fr_bands, Q19 ) ), &dummy_fx, S_map_LR_fx, NULL, hCPE->hFrontVad[1], hCPE->hFrontVad[0]->ini_frame ); + move16(); + /* Run noise_est for Left and Right channel */ + noise_est_ivas_fx( st, old_pitch1, tmpN_LR_fx[0], epsP_fx, Etot_LR_fx[0], sub( Etot_LR_fx[0], hCPE->hFrontVad[0]->lp_speech_fx ), corr_shiftL_fx, + tmpE_LR_fx[0], q_tmpE_LR[0], fr_bands_LR_fx[0], fr_bands_LR_fx_q[0], &cor_map_sum_LR_fx[0], &ncharX_LR_fx, &sp_div_LR_fx, &q_sp_div_LR, + &non_staX_LR_fx, loc_harmLR_fx, lf_E_LR_fx[0], lf_E_LR_fx_q, &hCPE->hFrontVad[0]->hNoiseEst->harm_cor_cnt, + hCPE->hFrontVad[0]->hNoiseEst->Etot_l_lp_fx, hCPE->hFrontVad[0]->hNoiseEst->Etot_v_h2_fx, &hCPE->hFrontVad[0]->hNoiseEst->bg_cnt, + st->lgBin_E_fx, &dummy_fx, S_map_LR_fx, NULL, hCPE->hFrontVad[0], hCPE->hFrontVad[0]->ini_frame ); - /*Scaling to avoid 0 values*/ - FOR( Word16 j = 0; j < 2; j++ ) - { - shift = s_min( L_norm_arr( hCPE->hFrontVad[j]->hNoiseEst->fr_bands1_fx, NB_BANDS ), L_norm_arr( hCPE->hFrontVad[j]->hNoiseEst->fr_bands2_fx, NB_BANDS ) ); - scale_sig32( hCPE->hFrontVad[j]->hNoiseEst->fr_bands1_fx, NB_BANDS, shift ); - scale_sig32( hCPE->hFrontVad[j]->hNoiseEst->fr_bands2_fx, NB_BANDS, shift ); - hCPE->hFrontVad[j]->hNoiseEst->fr_bands_fx_q = add( hCPE->hFrontVad[j]->hNoiseEst->fr_bands_fx_q, shift ); - shift = s_min( L_norm_arr( hCPE->hFrontVad[j]->hNoiseEst->ave_enr_fx, NB_BANDS ), L_norm_arr( hCPE->hFrontVad[j]->hNoiseEst->ave_enr2_fx, NB_BANDS ) ); - scale_sig32( hCPE->hFrontVad[j]->hNoiseEst->ave_enr_fx, NB_BANDS, shift ); - scale_sig32( hCPE->hFrontVad[j]->hNoiseEst->ave_enr2_fx, NB_BANDS, shift ); - hCPE->hFrontVad[j]->hNoiseEst->ave_enr_q = add( hCPE->hFrontVad[j]->hNoiseEst->ave_enr_q, shift ); - } + /* Note: the index [0] in the last argument is intended, the ini_frame counter is only maintained in the zero-th channel's VAD handle */ + noise_est_ivas_fx( st, old_pitch1, tmpN_LR_fx[1], epsP_fx, Etot_LR_fx[1], sub( Etot_LR_fx[1], hCPE->hFrontVad[1]->lp_speech_fx ), corr_shiftR_fx, + tmpE_LR_fx[1], q_tmpE_LR[1], fr_bands_LR_fx[1], fr_bands_LR_fx_q[1], &cor_map_sum_LR_fx[1], &ncharX_LR_fx, &sp_div_LR_fx, &q_sp_div_LR, + &non_staX_LR_fx, loc_harmLR_fx, lf_E_LR_fx[1], lf_E_LR_fx_q, &hCPE->hFrontVad[1]->hNoiseEst->harm_cor_cnt, + hCPE->hFrontVad[1]->hNoiseEst->Etot_l_lp_fx, hCPE->hFrontVad[1]->hNoiseEst->Etot_v_h2_fx, &hCPE->hFrontVad[1]->hNoiseEst->bg_cnt, + st->lgBin_E_fx, &dummy_fx, S_map_LR_fx, NULL, hCPE->hFrontVad[1], hCPE->hFrontVad[0]->ini_frame ); } /*------------------------------------------------------------------* @@ -1526,11 +1452,37 @@ ivas_error pre_proc_front_ivas_fx( * Find spectral tilt * UC and VC frame selection *-----------------------------------------------------------------*/ - find_tilt_ivas_fx( fr_bands_fx, st->hNoiseEst->bckr_fx, ee_fx, st->pitch, st->voicing_fx, lf_E_fx, corr_shift_fx, st->input_bwidth, st->max_band, hp_E_fx, MODE1, q_fr_bands, &( st->bckr_tilt_lt ), st->Opt_SC_VBR ); + scale = s_min( Q31, s_min( add( st->hNoiseEst->q_bckr, L_norm_arr( st->hNoiseEst->bckr_fx, NB_BANDS ) ), add( fr_bands_fx_q, L_norm_arr( fr_bands_fx, 2 * NB_BANDS ) ) ) ); + scale_sig32( fr_bands_fx, 2 * NB_BANDS, sub( scale, fr_bands_fx_q ) ); + scale_sig32( st->hNoiseEst->bckr_fx, NB_BANDS, sub( scale, st->hNoiseEst->q_bckr ) ); + st->hNoiseEst->q_bckr = fr_bands_fx_q = scale; + move16(); + move16(); - st->coder_type = find_uv_ivas_fx( st, pitch_fr_fx, voicing_fr_fx, inp_12k8_fx, ee_fx, &dE1X_fx, corr_shift_fx, *relE_fx, Etot_fx, hp_E_fx, &flag_spitch, last_core_orig, hStereoClassif, q_inp_12k8, q_fr_bands ); + find_tilt_ivas_fx( fr_bands_fx, fr_bands_fx_q, st->hNoiseEst->bckr_fx, st->hNoiseEst->q_bckr, ee_fx, st->pitch, st->voicing_fx, lf_E_fx, q_lf_E_fx, + corr_shift_fx, st->input_bwidth, st->max_band, hp_E_fx, MODE1, &( st->bckr_tilt_lt ), st->Opt_SC_VBR ); + + st->coder_type = find_uv_ivas_fx( st, pitch_fr_fx, voicing_fr_fx, inp_12k8_fx, ee_fx, &dE1X_fx, corr_shift_fx, *relE_fx, Etot_fx, hp_E_fx, + &flag_spitch, last_core_orig, hStereoClassif, *Q_new /*q_inp_12k8*/, fr_bands_fx_q ); // Q0 +#ifdef FIX_ISSUE_1237 + Copy_Scale_sig_16_32_no_sat( st->lgBin_E_fx, st->Bin_E_fx, L_FFT / 2, sub( st->q_Bin_E, Q7 ) ); +#else + Copy_Scale_sig_16_32_DEPREC( st->lgBin_E_fx, st->Bin_E_fx, L_FFT / 2, sub( st->q_Bin_E, Q7 ) ); +#endif + +#ifdef DEBUG_FORCE_DIR + if ( st->force_dir[0] != '\0' ) + { + dbgread( &st->coder_type, sizeof( int16_t ), 1, fname( st->force_dir, "force_coder_type.enf", -1, -1, -1 ) ); + dbgread( &st->coder_type_raw, sizeof( int16_t ), 1, fname( st->force_dir, "force_coder_type_raw.enf", -1, -1, -1 ) ); + } + else + { + dbgwrite( &st->coder_type, sizeof( int16_t ), 1, 1, "res/force_coder_type.enf" ); + dbgwrite( &st->coder_type_raw, sizeof( int16_t ), 1, 1, "res/force_coder_type_raw.enf" ); + } +#endif - Copy_Scale_sig_16_32( st->lgBin_E_fx, st->Bin_E_fx, L_FFT / 2, sub( st->q_Bin_E, Q7 ) ); /*-----------------------------------------------------------------* * channel aware mode configuration * @@ -1546,13 +1498,14 @@ ivas_error pre_proc_front_ivas_fx( * TC frame selection *-----------------------------------------------------------------*/ - st->clas = signal_clas_fx( st, inp_12k8_fx, ee_fx, *relE_fx, L_look, tdm_SM_last_clas ); + st->clas = signal_clas_fx( st, inp_12k8_fx, ee_fx, *relE_fx, L_look, tdm_SM_last_clas ); /* Q0 */ + move16(); select_TC_fx( MODE1, st->tc_cnt, &st->coder_type, st->localVAD ); if ( st->Opt_SC_VBR ) { - st->hSC_VBR->Local_VAD = st->localVAD; + st->hSC_VBR->Local_VAD = st->localVAD; /* Q0 */ move16(); } @@ -1564,10 +1517,10 @@ ivas_error pre_proc_front_ivas_fx( Word16 max_e_Etot; max_e_Etot = s_max( hStereoClassif->e_Etot_buf_fx, s_max( hStereoClassif->Etot_up_e, hStereoClassif->Etot_dn_e ) ); - scale_sig32( hStereoClassif->Etot_buf_fx, 3, sub( hStereoClassif->e_Etot_buf_fx, max_e_Etot ) ); - hStereoClassif->Etot_up_fx = L_shr( hStereoClassif->Etot_up_fx, sub( max_e_Etot, hStereoClassif->Etot_up_e ) ); + scale_sig32( hStereoClassif->Etot_buf_fx, 3, sub( hStereoClassif->e_Etot_buf_fx, max_e_Etot ) ); /* exp(max_e_Etot) */ + hStereoClassif->Etot_up_fx = L_shr( hStereoClassif->Etot_up_fx, sub( max_e_Etot, hStereoClassif->Etot_up_e ) ); /* exp(max_e_Etot) */ move32(); - hStereoClassif->Etot_dn_fx = L_shr( hStereoClassif->Etot_dn_fx, sub( max_e_Etot, hStereoClassif->Etot_dn_e ) ); + hStereoClassif->Etot_dn_fx = L_shr( hStereoClassif->Etot_dn_fx, sub( max_e_Etot, hStereoClassif->Etot_dn_e ) ); /* exp(max_e_Etot) */ move32(); hStereoClassif->Etot_up_e = hStereoClassif->Etot_dn_e = hStereoClassif->e_Etot_buf_fx = max_e_Etot; move16(); @@ -1575,7 +1528,7 @@ ivas_error pre_proc_front_ivas_fx( move16(); stereo_classifier_features_ivas_fx( hStereoClassif, st->idchan, element_mode, localVAD_HE_SAD, lsf_new_fx, epsP_fx, st->pitch, st->voicing_fx, *cor_map_sum_fx, non_staX_fx, sp_div_fx, - st->clas, sub( 31, *epsP_fx_q ), ( 15 - Q8 ) /* exp of cor_map_sum */, ( 15 - Q8 ) /* exp of non_staX_fx */, sub( 15, q_sp_div ) ); + st->clas, sub( 31, *epsP_fx_q ), ( 31 - Q8 ) /* exp of cor_map_sum */, ( 31 - Q8 ) /* exp of non_staX_fx */, sub( 15, q_sp_div ) ); } /*----------------------------------------------------------------* @@ -1587,7 +1540,18 @@ ivas_error pre_proc_front_ivas_fx( scale_sig32( PS_fx, 128, shift ); Qfact_PS = add( Qfact_PS, shift ); - smc_dec = ivas_smc_gmm_fx( st, hStereoClassif, localVAD_HE_SAD, Etot_fx, lsp_new_fx, *cor_map_sum_fx /*Q8*/, epsP_fx, PS_fx, non_staX_fx, *relE_fx, &high_lpn_flag, flag_spitch, Qfact_PS, *epsP_fx_q, hSpMusClas->past_PS_Q ); + smc_dec = ivas_smc_gmm_fx( st, hStereoClassif, localVAD_HE_SAD, Etot_fx, lsp_new_fx, *cor_map_sum_fx /*Q8*/, epsP_fx, PS_fx, non_staX_fx, *relE_fx, &high_lpn_flag, flag_spitch, Qfact_PS, *epsP_fx_q, hSpMusClas->past_PS_Q ); /* Q0 */ + +#ifdef DEBUG_FORCE_DIR + if ( st->force_dir[0] != '\0' ) + { + dbgread( &smc_dec, sizeof( int16_t ), 1, fname( st->force_dir, "force_smc_dec_loc1.enf", -1, -1, -1 ) ); + } + else + { + dbgwrite( &smc_dec, sizeof( int16_t ), 1, 1, "res/force_smc_dec_loc1.enf" ); + } +#endif #ifdef DEBUGGING if ( st->idchan == 0 ) @@ -1612,7 +1576,7 @@ ivas_error pre_proc_front_ivas_fx( ivas_long_enr_fx( st, Etot_fx, localVAD_HE_SAD, high_lpn_flag, NULL, 1, NULL, NULL ); - Copy32( fr_bands_fx + NB_BANDS, st->hNoiseEst->enrO_fx, NB_BANDS ); + Copy32( fr_bands_fx + NB_BANDS, st->hNoiseEst->enrO_fx, NB_BANDS ); /* fr_bands_fx_q */ st->hNoiseEst->q_enrO = fr_bands_fx_q; move16(); @@ -1621,11 +1585,11 @@ ivas_error pre_proc_front_ivas_fx( { ivas_long_enr_fx( st, -1, localVAD_HE_SAD, high_lpn_flag, hCPE->hFrontVad, CPE_CHANNELS, localVAD_HE_SAD_LR, Etot_LR_fx ); - Copy32( fr_bands_LR_fx[0] + NB_BANDS, hCPE->hFrontVad[0]->hNoiseEst->enrO_fx, NB_BANDS ); - hCPE->hFrontVad[0]->hNoiseEst->q_enrO = fr_bands_LR_fx_q; + Copy32( fr_bands_LR_fx[0] + NB_BANDS, hCPE->hFrontVad[0]->hNoiseEst->enrO_fx, NB_BANDS ); // fr_bands_LR_fx_q + hCPE->hFrontVad[0]->hNoiseEst->q_enrO = fr_bands_LR_fx_q[0]; move16(); - Copy32( fr_bands_LR_fx[1] + NB_BANDS, hCPE->hFrontVad[1]->hNoiseEst->enrO_fx, NB_BANDS ); - hCPE->hFrontVad[1]->hNoiseEst->q_enrO = fr_bands_LR_fx_q; + Copy32( fr_bands_LR_fx[1] + NB_BANDS, hCPE->hFrontVad[1]->hNoiseEst->enrO_fx, NB_BANDS ); // fr_bands_LR_fx_q + hCPE->hFrontVad[1]->hNoiseEst->q_enrO = fr_bands_LR_fx_q[1]; move16(); } @@ -1671,14 +1635,14 @@ ivas_error pre_proc_front_ivas_fx( test(); test(); test(); - IF( EQ_32( ivas_format, SBA_FORMAT ) && NE_32( st->core_brate, FRAME_NO_DATA ) && EQ_32( st->last_core_brate, FRAME_NO_DATA ) && st->sba_br_sw_while_no_data ) + IF( EQ_32( ivas_format, SBA_FORMAT ) && st->core_brate != FRAME_NO_DATA && st->last_core_brate == FRAME_NO_DATA && st->sba_br_sw_while_no_data ) { SetModeIndex_ivas_fx( st, L_mult0( st->bits_frame_nominal, FRAMES_PER_SEC ), element_mode, MCT_flag ); st->sba_br_sw_while_no_data = 0; move16(); } - ELSE IF( EQ_32( ivas_format, SBA_FORMAT ) && EQ_32( st->core_brate, FRAME_NO_DATA ) && NE_32( element_brate, last_element_brate ) ) + ELSE IF( EQ_32( ivas_format, SBA_FORMAT ) && st->core_brate == FRAME_NO_DATA && NE_32( element_brate, last_element_brate ) ) { st->sba_br_sw_while_no_data = 1; move16(); @@ -1686,12 +1650,12 @@ ivas_error pre_proc_front_ivas_fx( IF( flag_16k_smc ) { - Scale_sig( st->input_fx, input_frame, sub( -1, st->q_inp ) ); + Scale_sig( st->input_fx, input_frame, sub( -1, st->q_inp ) ); /* Q(-1) */ st->q_inp = -1; move16(); } /* these are for ivas_acelp_tcx20_switching_fx */ - Scale_sig32( st->hTcxEnc->spectrum_long_fx, N_MAX, sub( st->hTcxEnc->spectrum_long_e, 16 ) ); + Scale_sig32( st->hTcxEnc->spectrum_long_fx, N_MAX, sub( st->hTcxEnc->spectrum_long_e, 16 ) ); /* Q(-1) */ st->hTcxEnc->spectrum_long_e = 16; move16(); st->hTcxEnc->spectrum_e[0] = 16; @@ -1703,27 +1667,29 @@ ivas_error pre_proc_front_ivas_fx( Word16 Q_old_inp_16k = -1; move16(); - Scale_sig( st->old_inp_16k_fx, L_INP_MEM, sub( Q_old_inp_16k, sub( Q15, st->exp_old_inp_16k ) ) ); + Scale_sig( st->old_inp_16k_fx, L_INP_MEM, sub( Q_old_inp_16k, sub( Q15, st->exp_old_inp_16k ) ) ); /* Q15 - Q_old_inp_16k */ st->exp_old_inp_16k = sub( Q15, Q_old_inp_16k ); move16(); IF( st->hBWE_FD != NULL ) { - Scale_sig( st->hBWE_FD->L_old_wtda_swb_fx, L_FRAME48k, sub( -1, st->Q_old_wtda ) ); - st->Q_old_wtda = -1; // This reset needs to be looked into + Scale_sig( st->hBWE_FD->L_old_wtda_swb_fx, L_FRAME48k, sub( -1, st->Q_old_wtda ) ); /* Q(-1) */ + st->Q_old_wtda = -1; // This reset needs to be looked into move16(); } - st->mem_preemph_enc = shl( st->mem_preemph_enc, sub( Q_old_inp_16k, sub( Q15, st->exp_mem_preemph_enc ) ) ); + st->mem_preemph_enc = shl( st->mem_preemph_enc, sub( Q_old_inp_16k, sub( Q15, st->exp_mem_preemph_enc ) ) ); /* Q15 - Q_old_inp_16k */ move16(); st->exp_mem_preemph_enc = sub( Q15, Q_old_inp_16k ); move16(); - Scale_sig( st->buf_wspeech_enc, L_FRAME16k + L_SUBFR + L_FRAME16k + L_NEXT_MAX_16k + 320, sub( Q_old_inp_16k, sub( Q15, st->exp_buf_wspeech_enc ) ) ); + Scale_sig( st->buf_wspeech_enc, L_FRAME16k + L_SUBFR + L_FRAME16k + L_NEXT_MAX_16k + 320, sub( Q_old_inp_16k, sub( Q15, st->exp_buf_wspeech_enc ) ) ); /* Q15 - Q_old_inp_16k */ + st->mem_wsp_enc = shl( st->mem_wsp_enc, sub( Q_old_inp_16k, sub( Q15, st->exp_buf_wspeech_enc ) ) ); // Q_old_inp_16k + move16(); st->exp_buf_wspeech_enc = sub( Q15, Q_old_inp_16k ); move16(); - Scale_sig( st->buf_speech_enc_pe, L_PAST_MAX_32k + L_FRAME32k + L_NEXT_MAX_32k, sub( Q_old_inp_16k, sub( Q15, st->exp_buf_speech_enc_pe ) ) ); + Scale_sig( st->buf_speech_enc_pe, L_PAST_MAX_32k + L_FRAME32k + L_NEXT_MAX_32k, sub( Q_old_inp_16k, sub( Q15, st->exp_buf_speech_enc_pe ) ) ); /* Q15 - Q_old_inp_16k */ st->exp_buf_speech_enc_pe = sub( Q15, Q_old_inp_16k ); move16(); - Scale_sig( st->buf_speech_enc, L_PAST_MAX_32k + L_FRAME32k + L_NEXT_MAX_32k, sub( Q_old_inp_16k, sub( Q15, st->exp_buf_speech_enc ) ) ); + Scale_sig( st->buf_speech_enc, L_PAST_MAX_32k + L_FRAME32k + L_NEXT_MAX_32k, sub( Q_old_inp_16k, sub( Q15, st->exp_buf_speech_enc ) ) ); /* Q15 - Q_old_inp_16k */ st->exp_buf_speech_enc = sub( Q15, Q_old_inp_16k ); move16(); @@ -1733,34 +1699,37 @@ ivas_error pre_proc_front_ivas_fx( error = ivas_compute_core_buffers_fx( st, NULL, old_inp_16k_fx, NULL, input_frame, IVAS_SCE /*last_element_mode*/, INT_FS_16k /*sr_core_tmp*/, ener_fx, A_fx, Aw_fx, epsP_fx, - lsp_new_fx, lsp_mid_fx, Q_old_inp_16k, Q_r, Q_new, 1 ); - IF( error != IVAS_ERR_OK ) + lsp_new_fx, lsp_mid_fx, Q_old_inp_16k, Q_r, Q_new ); + IF( NE_32( error, IVAS_ERR_OK ) ) { return error; } *epsP_fx_q = add( Q_r[0], 1 ); move16(); - st->mem_wsp_enc = shr_r( st->mem_wsp_enc, *Q_new ); // Q_new - 1 -> Q-1 + st->mem_wsp_enc = shl( st->mem_wsp_enc, sub( 0, sub( Q15, st->exp_buf_wspeech_enc ) ) ); // Q0 move16(); *Q_new = add( *Q_new, Q_to_be_looked_into ); // actual Q_new move16(); - Scale_sig( old_inp_12k8_fx, L_INP_12k8, sub( *Q_new, Q_old_inp_12k8 ) ); + Scale_sig( old_inp_12k8_fx, L_INP_12k8, sub( *Q_new, Q_old_inp_12k8 ) ); /* Q_new */ - Scale_sig( st->buf_speech_enc, L_PAST_MAX_32k + L_FRAME32k + L_NEXT_MAX_32k, sub( 0, sub( Q15, st->exp_buf_speech_enc ) ) ); + Scale_sig( st->buf_speech_enc, L_PAST_MAX_32k + L_FRAME32k + L_NEXT_MAX_32k, sub( 0, sub( Q15, st->exp_buf_speech_enc ) ) ); /* Q0 */ st->exp_buf_speech_enc = Q15; move16(); - smc_dec = ivas_acelp_tcx20_switching_fx( st, st->speech_enc, 0, st->wspeech_enc, non_staX_fx, pitch_fr_fx, voicing_fr_fx, currFlatness_fx, lsp_mid_fx, stab_fac_fx, res_cod_SNR_M_fx, res_cod_SNR_M_fx_e, flag_16k_smc ); + Scale_sig( st->buf_wspeech_enc, L_FRAME16k + L_SUBFR + L_FRAME16k + L_NEXT_MAX_16k + 320, sub( 0, sub( Q15, st->exp_buf_wspeech_enc ) ) ); /* Q0 */ + st->exp_buf_wspeech_enc = Q15; + move16(); + smc_dec = ivas_acelp_tcx20_switching_fx( st, st->speech_enc, 0, st->wspeech_enc, non_staX_fx, pitch_fr_fx, voicing_fr_fx, currFlatness_fx, lsp_mid_fx, stab_fac_fx, res_cod_SNR_M_fx, res_cod_SNR_M_fx_e, flag_16k_smc ); /* Q0 */ } ELSE { - Scale_sig( old_wsp_fx, L_WSP, sub( *Q_new, *q_old_wsp ) ); + Scale_sig( old_wsp_fx, L_WSP, sub( *Q_new, *q_old_wsp ) ); /* Q_new */ *q_old_wsp = *Q_new; move16(); Q_wsp = *Q_new; move16(); - smc_dec = ivas_acelp_tcx20_switching_fx( st, inp_12k8_fx, *Q_new, wsp_fx, non_staX_fx, pitch_fr_fx, voicing_fr_fx, currFlatness_fx, lsp_mid_fx, stab_fac_fx, res_cod_SNR_M_fx, res_cod_SNR_M_fx_e, flag_16k_smc ); + smc_dec = ivas_acelp_tcx20_switching_fx( st, inp_12k8_fx, *Q_new, wsp_fx, non_staX_fx, pitch_fr_fx, voicing_fr_fx, currFlatness_fx, lsp_mid_fx, stab_fac_fx, res_cod_SNR_M_fx, res_cod_SNR_M_fx_e, flag_16k_smc ); /* Q0 */ } } /* Switch to ACELP for non-harmonic transient signals */ @@ -1788,13 +1757,30 @@ ivas_error pre_proc_front_ivas_fx( } } - Scale_sig32( st->Bin_E_fx, L_FFT, sub( add( *Q_new, Q_SCALE - 2 ), st->q_Bin_E ) ); + Scale_sig32( st->Bin_E_fx, L_FFT, sub( add( *Q_new, Q_SCALE - 2 ), st->q_Bin_E ) ); /* Q_new + Q_SCALE - 2 */ st->q_Bin_E = add( *Q_new, Q_SCALE - 2 ); move16(); /* 2nd stage speech/music classification (ACELP/GSC/TCX core selection) */ ivas_smc_mode_selection_fx( st, element_brate, smc_dec, *relE_fx, Etot_fx, attack_flag, inp_12k8_fx, *Q_new, S_map_fx, flag_spitch ); } +#ifdef DEBUG_FORCE_DIR + if ( st->force_dir[0] != '\0' ) + { + dbgread( &smc_dec, sizeof( int16_t ), 1, fname( st->force_dir, "force_smc_dec_loc2.enf", -1, -1, -1 ) ); + dbgread( &st->sp_aud_decision0, sizeof( int16_t ), 1, fname( st->force_dir, "force_sp_aud_decision0.enf", -1, -1, -1 ) ); + dbgread( &st->sp_aud_decision1, sizeof( int16_t ), 1, fname( st->force_dir, "force_sp_aud_decision1.enf", -1, -1, -1 ) ); + dbgread( &st->sp_aud_decision2, sizeof( int16_t ), 1, fname( st->force_dir, "force_sp_aud_decision2.enf", -1, -1, -1 ) ); + } + else + { + dbgwrite( &smc_dec, sizeof( int16_t ), 1, 1, "res/force_smc_dec_loc2.enf" ); + dbgwrite( &st->sp_aud_decision0, sizeof( int16_t ), 1, 1, "res/force_sp_aud_decision0.enf" ); + dbgwrite( &st->sp_aud_decision1, sizeof( int16_t ), 1, 1, "res/force_sp_aud_decision1.enf" ); + dbgwrite( &st->sp_aud_decision2, sizeof( int16_t ), 1, 1, "res/force_sp_aud_decision2.enf" ); + } +#endif + /*----------------------------------------------------------------* * Final VAD correction (when HE-SAD is used instead of the normal VAD, * rewrite the VAD flag by VAD flag with DTX hangover for further processing) @@ -1803,7 +1789,7 @@ ivas_error pre_proc_front_ivas_fx( test(); if ( st->Opt_DTX_ON && NE_16( element_mode, IVAS_CPE_DFT ) ) { - st->vad_flag = *vad_flag_dtx; + st->vad_flag = *vad_flag_dtx; /* Q0 */ move16(); } @@ -1811,7 +1797,7 @@ ivas_error pre_proc_front_ivas_fx( * Update old input signal buffer *-----------------------------------------------------------------*/ shift = getScaleFactor16( &old_inp_12k8_fx[L_FRAME], L_INP_MEM ); - Copy_Scale_sig( &old_inp_12k8_fx[L_FRAME], st->old_inp_12k8_fx, L_INP_MEM, shift ); + Copy_Scale_sig( &old_inp_12k8_fx[L_FRAME], st->old_inp_12k8_fx, L_INP_MEM, shift ); /* Q_new + shift */ st->exp_old_inp_12k8 = sub( Q15, add( *Q_new, shift ) ); move16(); @@ -1896,9 +1882,9 @@ static void calculate_energy_buffer_fx( *--------------------------------------------------------------------*/ static void calculate_energy_buffer_ivas_fx( CPE_ENC_HANDLE hCPE, /* i : CPE encoder structure */ - Word32 enerBuffer_dft_fx[], /* o : energy buffer() */ - const Word16 no_channels, /* i : no. of used CLDFB channels */ - const Word32 input_Fs, /* i : input sampling rate */ + Word32 enerBuffer_dft_fx[], /* o : energy buffer() exp(enerBuffer_dft_e)*/ + const Word16 no_channels, /* i : no. of used CLDFB channels Q0*/ + const Word32 input_Fs, /* i : input sampling rate Q0*/ Word16 *enerBuffer_dft_e ) { Word16 i, j; @@ -1910,13 +1896,14 @@ static void calculate_energy_buffer_ivas_fx( Word16 norm_nrg_DMX_fx; Word64 max_abs_nrg_DMX_fx; Flag overflow = 0; + move32(); max_abs_nrg_DMX_fx = 0; move64(); Word16 temp_q1 = sub( norm_l( input_Fs ), 1 ); Word16 temp_q2 = norm_s( hCPE->hStereoDft->NFFT ); - band_res_dft_fx = div_l( L_shl( input_Fs, temp_q1 ), shl( hCPE->hStereoDft->NFFT, temp_q2 ) ); + band_res_dft_fx = div_l( L_shl( input_Fs, temp_q1 ), shl( hCPE->hStereoDft->NFFT, temp_q2 ) ); /* Q0 */ /* chan_width_f = 24000.f / CLDFB_NO_CHANNELS_MAX; */ chan_width_f_fx = 24000 / CLDFB_NO_CHANNELS_MAX; move16(); diff --git a/lib_enc/ivas_core_pre_proc.c b/lib_enc/ivas_core_pre_proc_fx.c similarity index 78% rename from lib_enc/ivas_core_pre_proc.c rename to lib_enc/ivas_core_pre_proc_fx.c index edef59ba2c0009b043ca84beb1f0eca704c3d283..8d00e608c083a3d89eada175ce3256e9fd6cf4e2 100644 --- a/lib_enc/ivas_core_pre_proc.c +++ b/lib_enc/ivas_core_pre_proc_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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,51 +34,49 @@ #include "options.h" #include "cnst.h" #include "ivas_cnst.h" -#include "ivas_prot.h" #include "rom_enc.h" #include "rom_com.h" -#include "prot.h" -#include "wmc_auto.h" #include "prot_fx.h" +#include "wmc_auto.h" #include "ivas_prot_fx.h" #include "prot_fx_enc.h" #include "basop_util.h" /*-------------------------------------------------------------------* - * pre_proc_ivas() + * pre_proc_ivas_fx() * * Pre-processing (Selection of internal Fs, classification, SC VBR decision, * Decision matrix, Preprocessing at other Fs, core switching decision, ...) *--------------------------------------------------------------------*/ -ivas_error pre_proc_ivas( - Encoder_State *st, /* i/o: encoder state structure */ - const Word16 last_element_mode, /* i : last element mode */ - const Word32 element_brate, /* i : element bitrate */ - const Word32 last_element_brate, /* i : last element bitrate */ - const Word16 input_frame, /* i : frame length */ - Word16 old_inp_12k8_fx[], /* i/o: buffer of old input signal Q_new-1 */ - Word16 old_inp_16k_fx[], /* i/o: buffer of old input signal @ 16kHz Q_new-1 */ - Word16 **inp_fx, /* o : ptr. to inp. signal in the current frame*/ - Word32 *ener_fx, /* o : residual energy from Levinson-Durbin epsP_fx_q */ - Word16 A_fx[NB_SUBFR16k * ( M + 1 )], /* i/o: A(z) unquantized for the 4 subframes */ - Word16 Aw_fx[NB_SUBFR16k * ( M + 1 )], /* i/o: weighted A(z) unquantized for subframes */ - Word32 epsP_fx[M + 1], /* i : LP prediction errors epsP_fx_q */ - Word16 *epsP_fx_q, /* i : LP prediction errors */ - Word16 lsp_new_fx[M], /* i/o: LSPs at the end of the frame */ - Word16 lsp_mid_fx[M], /* i/o: LSPs in the middle of the frame */ - Word16 *new_inp_resamp16k_fx, /* o : new input signal @16kHz, non pre-emphasised, used by the WB TBE/BWE */ - Word16 *Voicing_flag, /* o : voicing flag for HQ FEC */ - Word16 old_wsp_fx[], /* i : weighted input signal buffer */ +ivas_error pre_proc_ivas_fx( + Encoder_State *st, /* i/o: encoder state structure */ + const Word16 last_element_mode, /* i : last element mode Q0*/ + const Word32 element_brate, /* i : element bitrate Q0*/ + const Word32 last_element_brate, /* i : last element bitrate Q0*/ + const Word16 input_frame, /* i : frame length Q0*/ + Word16 old_inp_12k8_fx[], /* i/o: buffer of old input signal Q_new-1 */ + Word16 old_inp_16k_fx[], /* i/o: buffer of old input signal @ 16kHz Q_new-1 */ + Word16 **inp_fx, /* o : ptr. to inp. signal in the current frame Q_new*/ + Word32 *ener_fx, /* o : residual energy from Levinson-Durbin epsP_fx_q*/ + Word16 A_fx[NB_SUBFR16k * ( M + 1 )], /* i/o: A(z) unquantized for the 4 subframes Q12*/ + Word16 Aw_fx[NB_SUBFR16k * ( M + 1 )], /* i/o: weighted A(z) unquantized for subframes Q14*/ + Word32 epsP_fx[M + 1], /* i : LP prediction errors epsP_fx_q*/ + Word16 *epsP_fx_q, /* i : LP prediction errors */ + Word16 lsp_new_fx[M], /* i/o: LSPs at the end of the frame Q15*/ + Word16 lsp_mid_fx[M], /* i/o: LSPs in the middle of the frame Q15*/ + Word16 *new_inp_resamp16k_fx, /* o : new input signal @16kHz, non pre-emphasised, used by the WB TBE/BWE Q_new-1*/ + Word16 *Voicing_flag, /* o : voicing flag for HQ FEC Q0*/ + Word16 old_wsp_fx[], /* i : weighted input signal buffer e_old_wsp*/ Word16 e_old_wsp, - const Word16 loc_harm, /* i : harmonicity flag */ - const Word16 vad_flag_dtx, /* i : HE-SAD flag with additional DTX HO */ - const Word16 MCT_flag, /* i : hMCT handle allocated (1) or not (0) */ - const Word16 vad_hover_flag, /* i : VAD hangover flag */ - const Word16 flag_16k_smc, /* i : flag to indicate if the OL SMC is run at 16 kHz */ - Word32 enerBuffer_fx[CLDFB_NO_CHANNELS_MAX], + const Word16 loc_harm, /* i : harmonicity flag Q0*/ + const Word16 vad_flag_dtx, /* i : HE-SAD flag with additional DTX HO Q0*/ + const Word16 MCT_flag, /* i : hMCT handle allocated (1) or not (0) Q0*/ + const Word16 vad_hover_flag, /* i : VAD hangover flag Q0*/ + const Word16 flag_16k_smc, /* i : flag to indicate if the OL SMC is run at 16 kHz Q0*/ + Word32 enerBuffer_fx[CLDFB_NO_CHANNELS_MAX], /* e_enerBuffer */ Word16 e_enerBuffer, - Word16 fft_buff_fx[2 * L_FFT], - Word16 cor_map_sum_fx, // Q8 + Word16 fft_buff_fx[2 * L_FFT], /* Qx */ + Word16 cor_map_sum_fx, /* Q8 */ Word16 *Q_new ) { Word16 L_look, element_mode, lMemRecalc_12k8; @@ -138,13 +136,13 @@ ivas_error pre_proc_ivas( IF( st->core_brate == FRAME_NO_DATA ) { /* prevent "L_frame" changes in CNG segments */ - st->L_frame = st->last_L_frame; + st->L_frame = st->last_L_frame; /* Q0 */ move16(); } ELSE IF( EQ_32( st->core_brate, SID_2k40 ) && GE_16( st->bwidth, WB ) && st->hDtxEnc->first_CNG && ( st->hTdCngEnc != NULL && LT_16( st->hTdCngEnc->act_cnt2, MIN_ACT_CNG_UPD ) ) ) { /* prevent "L_frame" changes in SID frame after short segment of active frames */ - st->L_frame = st->hDtxEnc->last_CNG_L_frame; + st->L_frame = st->hDtxEnc->last_CNG_L_frame; /* Q0 */ move16(); } ELSE IF( ( ( EQ_16( st->element_mode, IVAS_CPE_MDCT ) && GE_32( st->element_brate, IVAS_64k ) && GE_16( st->bwidth, SWB ) ) || ( EQ_16( element_mode, IVAS_SCE ) && GT_32( st->total_brate, MAX_ACELP_BRATE ) && GE_16( st->bwidth, SWB ) ) ) && NE_32( st->core_brate, SID_2k40 ) ) @@ -185,13 +183,13 @@ ivas_error pre_proc_ivas( } IF( st->hFdCngEnc != NULL && NE_16( st->element_mode, IVAS_CPE_MDCT ) && ( ( NE_16( st->hFdCngEnc->hFdCngCom->frameSize, st->L_frame ) ) || ( NE_16( st->hFdCngEnc->hFdCngCom->CngBandwidth, st->input_bwidth ) ) ) ) { - configureFdCngEnc_ivas_fx( st->hFdCngEnc, max( st->input_bwidth, WB ), flag_1 ); + configureFdCngEnc_ivas_fx( st->hFdCngEnc, s_max( st->input_bwidth, WB ), flag_1 ); } if ( st->ini_frame == 0 ) { /* avoid switching of internal ACELP Fs in the very first frame */ - st->last_L_frame = st->L_frame; + st->last_L_frame = st->L_frame; /* Q0 */ move16(); } @@ -217,9 +215,9 @@ ivas_error pre_proc_ivas( move16(); } - st->sr_core = L_mult0( st->L_frame, FRAMES_PER_SEC ); - st->encoderLookahead_enc = NS2SA_FX2( st->sr_core, ACELP_LOOK_NS ); - st->encoderPastSamples_enc = shr( ( imult1616( st->L_frame, 9 ) ), 4 ); + st->sr_core = L_mult0( st->L_frame, FRAMES_PER_SEC ); /* Q0 */ + st->encoderLookahead_enc = NS2SA_FX2( st->sr_core, ACELP_LOOK_NS ); /* Q0 */ + st->encoderPastSamples_enc = shr( ( imult1616( st->L_frame, 9 ) ), 4 ); /* Q0 */ move32(); move16(); move16(); @@ -248,7 +246,7 @@ ivas_error pre_proc_ivas( test(); test(); /* enforce TRANSITION frames */ - IF( !( EQ_16( st->element_mode, IVAS_CPE_TD ) && EQ_16( st->idchan, 1 ) ) && NE_16( st->last_L_frame, st->L_frame ) && NE_32( st->core_brate, FRAME_NO_DATA ) && NE_32( st->core_brate, SID_2k40 ) && NE_32( st->last_core_brate, FRAME_NO_DATA ) && NE_32( st->last_core_brate, SID_2k40 ) && NE_16( st->coder_type_raw, VOICED ) ) + IF( !( EQ_16( st->element_mode, IVAS_CPE_TD ) && EQ_16( st->idchan, 1 ) ) && NE_16( st->last_L_frame, st->L_frame ) && st->core_brate != FRAME_NO_DATA && NE_32( st->core_brate, SID_2k40 ) && st->last_core_brate != FRAME_NO_DATA && NE_32( st->last_core_brate, SID_2k40 ) && NE_16( st->coder_type_raw, VOICED ) ) { /* enforce TC frame in case of ACELP@12k8 <-> ACELP@16k core switching */ st->coder_type = TRANSITION; @@ -284,7 +282,11 @@ ivas_error pre_proc_ivas( } ELSE IF( GT_32( st->total_brate, MAX_GSC_INACTIVE_BRATE ) && ( ( st->vad_flag == 0 && GE_16( st->bwidth, SWB ) && GE_16( st->max_bwidth, SWB ) ) || ( st->localVAD == 0 && ( LE_16( st->bwidth, WB ) || LE_16( st->max_bwidth, WB ) ) ) ) ) { +#ifdef NONBE_FIX_GSC_BSTR + /* inactive frames will be coded by AVQ technology (exceptionally it can be later rewritten to GSC technology in ivas_combined_format_brate_sanity()) */ +#else /* inactive frames will be coded by AVQ technology */ +#endif st->coder_type = INACTIVE; move16(); } @@ -298,10 +300,11 @@ ivas_error pre_proc_ivas( st->mdct_sw_enable = MODE1; move16(); move16(); + test(); test(); test(); - IF( ( LE_32( st->total_brate, MIN_BRATE_GSC_NOISY_FLAG ) || LT_16( st->bwidth, SWB ) || st->flag_ACELP16k ) && st->GSC_IVAS_mode == 0 ) + if ( ( LE_32( st->total_brate, MIN_BRATE_GSC_NOISY_FLAG ) || LT_16( st->bwidth, SWB ) || st->flag_ACELP16k ) && st->GSC_IVAS_mode == 0 ) { st->GSC_noisy_speech = 0; move16(); @@ -311,7 +314,7 @@ ivas_error pre_proc_ivas( ivas_decision_matrix_enc_fx( st, element_brate, fft_buff_fx, enerBuffer_fx, e_enerBuffer, last_element_mode ); test(); test(); - IF( EQ_16( st->L_frame, L_FRAME16k ) && ( EQ_16( st->coder_type, VOICED ) || EQ_16( st->coder_type, UNVOICED ) ) ) /* VOICED and UNVOICED are not supported in ACELP@16k */ + if ( EQ_16( st->L_frame, L_FRAME16k ) && ( EQ_16( st->coder_type, VOICED ) || EQ_16( st->coder_type, UNVOICED ) ) ) /* VOICED and UNVOICED are not supported in ACELP@16k */ { st->coder_type = GENERIC; move16(); @@ -323,22 +326,22 @@ ivas_error pre_proc_ivas( st->Nb_ACELP_frames = 0; move16(); /* Configure TCX with the same bitrate as given when (re-)initializing TCX */ - total_brate_tmp = st->total_brate; + total_brate_tmp = st->total_brate; /* Q0 */ move32(); - st->total_brate = L_mult0( st->bits_frame_nominal, FRAMES_PER_SEC ); + st->total_brate = L_mult0( st->bits_frame_nominal, FRAMES_PER_SEC ); /* Q0 */ move32(); - SetModeIndex_ivas_fx( st, st->last_bits_frame_nominal * FRAMES_PER_SEC, last_element_mode, MCT_flag ); + SetModeIndex_ivas_fx( st, imult3216( st->last_bits_frame_nominal, FRAMES_PER_SEC ), last_element_mode, MCT_flag ); - st->sr_core = getCoreSamplerateMode2( element_mode, st->total_brate, st->bwidth, st->flag_ACELP16k, st->rf_mode, st->is_ism_format ); + st->sr_core = getCoreSamplerateMode2( element_mode, st->total_brate, st->bwidth, st->flag_ACELP16k, st->rf_mode, st->is_ism_format ); /* Q0 */ move16(); - st->total_brate = total_brate_tmp; + st->total_brate = total_brate_tmp; /* Q0 */ move32(); - st->L_frame = extract_l( Mpy_32_32( st->sr_core, ONE_BY_FRAMES_PER_SEC_Q31 ) ); + st->L_frame = extract_l( Mpy_32_32( st->sr_core, ONE_BY_FRAMES_PER_SEC_Q31 ) ); /* Q0 */ move16(); - st->encoderLookahead_enc = NS2SA_FX2( st->sr_core, ACELP_LOOK_NS ); - st->encoderPastSamples_enc = shr( ( imult1616( st->L_frame, 9 ) ), 4 ); + st->encoderLookahead_enc = NS2SA_FX2( st->sr_core, ACELP_LOOK_NS ); /* Q0 */ + st->encoderPastSamples_enc = shr( ( imult1616( st->L_frame, 9 ) ), 4 ); /* Q0 */ move16(); move16(); @@ -393,7 +396,7 @@ ivas_error pre_proc_ivas( test(); test(); - IF( NE_16( st->extl, -1 ) && NE_16( st->extl, IGF_BWE ) && EQ_16( st->igf, 1 ) ) + if ( NE_16( st->extl, -1 ) && NE_16( st->extl, IGF_BWE ) && EQ_16( st->igf, 1 ) ) { st->igf = 0; move16(); @@ -409,12 +412,12 @@ ivas_error pre_proc_ivas( test(); IF( EQ_16( loc_harm, 1 ) && GT_16( cor_map_sum_fx, 50 << 8 ) && EQ_16( st->clas, VOICED_CLAS ) && EQ_16( st->coder_type, GENERIC ) ) { - st->last_harm_flag_acelp = add( st->last_harm_flag_acelp, 1 ); + st->last_harm_flag_acelp = add( st->last_harm_flag_acelp, 1 ); /* Q0 */ move16(); IF( GT_16( st->last_harm_flag_acelp, 10 ) ) { - st->last_harm_flag_acelp = 10; + st->last_harm_flag_acelp = 10; /* Q0 */ move16(); } } @@ -430,22 +433,22 @@ ivas_error pre_proc_ivas( IF( EQ_16( st->coder_type, AUDIO ) ) { - st->audio_frame_cnt = add( st->audio_frame_cnt, AUDIO_COUNTER_STEP ); + st->audio_frame_cnt = add( st->audio_frame_cnt, AUDIO_COUNTER_STEP ); /* Q0 */ move16(); } - ELSE IF( NE_16( st->coder_type, INACTIVE ) ) + ELSE IF( st->coder_type != INACTIVE ) { - st->audio_frame_cnt = sub( st->audio_frame_cnt, 1 ); + st->audio_frame_cnt = sub( st->audio_frame_cnt, 1 ); /* Q0 */ move16(); } - IF( GT_16( st->audio_frame_cnt, AUDIO_COUNTER_MAX ) ) + if ( GT_16( st->audio_frame_cnt, AUDIO_COUNTER_MAX ) ) { - st->audio_frame_cnt = AUDIO_COUNTER_MAX; + st->audio_frame_cnt = AUDIO_COUNTER_MAX; /* Q0 */ move16(); } - IF( st->audio_frame_cnt < 0 ) + if ( st->audio_frame_cnt < 0 ) { st->audio_frame_cnt = 0; move16(); @@ -478,7 +481,7 @@ ivas_error pre_proc_ivas( /* channel-aware mode - due to lack of signaling bit, sharpFlag is 1 always in RF mode */ test(); test(); - IF( st->rf_mode && ( EQ_16( st->coder_type, VOICED ) || EQ_16( st->coder_type, GENERIC ) ) ) + if ( st->rf_mode && ( EQ_16( st->coder_type, VOICED ) || EQ_16( st->coder_type, GENERIC ) ) ) { st->sharpFlag = 1; move16(); @@ -491,7 +494,7 @@ ivas_error pre_proc_ivas( st->sharpFlag = 0; move16(); test(); - IF( EQ_16( st->coder_type, GENERIC ) || EQ_16( st->coder_type, VOICED ) ) + if ( EQ_16( st->coder_type, GENERIC ) || EQ_16( st->coder_type, VOICED ) ) { st->sharpFlag = 1; move16(); @@ -528,7 +531,7 @@ ivas_error pre_proc_ivas( sr_core_tmp = L_max( INT_FS_16k, st->sr_core ); } - L_look = NS2SA( sr_core_tmp, ACELP_LOOK_NS ); /* lookahead at other sampling rate (16kHz, 25.6kHz, 32kHz) */ + L_look = NS2SA_FX2( sr_core_tmp, ACELP_LOOK_NS ); /* lookahead at other sampling rate (16kHz, 25.6kHz, 32kHz) Q0*/ move16(); inp_16k_fx = old_inp_16k_fx + L_INP_MEM - L_look; @@ -541,70 +544,92 @@ ivas_error pre_proc_ivas( inp_16k_fx = old_inp_16k_fx + L_INP_MEM - L_look; Word16 shift = getScaleFactor16( st->old_inp_12k8_fx, L_INP_MEM ); - Scale_sig( st->old_inp_12k8_fx, L_INP_MEM, shift ); + Scale_sig( st->old_inp_12k8_fx, L_INP_MEM, shift ); /* exp(st->exp_old_inp_12k8 - shift) */ st->exp_old_inp_12k8 = sub( st->exp_old_inp_12k8, shift ); move16(); - Scale_sig( st->old_inp_16k_fx, L_INP_MEM, sub( Q_old_inp_16k, sub( Q15, st->exp_old_inp_16k ) ) ); + Scale_sig( st->old_inp_16k_fx, L_INP_MEM, sub( Q_old_inp_16k, sub( Q15, st->exp_old_inp_16k ) ) ); /* Q15 - st->exp_old_inp_16k */ st->exp_old_inp_16k = sub( Q15, Q_old_inp_16k ); move16(); IF( st->hBWE_FD != NULL ) { - Scale_sig( st->hBWE_FD->L_old_wtda_swb_fx, L_FRAME48k, sub( -1, st->Q_old_wtda ) ); - st->Q_old_wtda = -1; // This reset needs to be looked into + Scale_sig( st->hBWE_FD->L_old_wtda_swb_fx, L_FRAME48k, sub( -1, st->Q_old_wtda ) ); /* -1Q */ + st->Q_old_wtda = -1; // This reset needs to be looked into move16(); } - st->mem_preemph_enc = shl( st->mem_preemph_enc, sub( Q_old_inp_16k, sub( Q15, st->exp_mem_preemph_enc ) ) ); + st->mem_preemph_enc = shl( st->mem_preemph_enc, sub( Q_old_inp_16k, sub( Q15, st->exp_mem_preemph_enc ) ) ); /* Q15 - Q_old_inp_16k */ move16(); st->exp_mem_preemph_enc = sub( Q15, Q_old_inp_16k ); move16(); - Scale_sig( st->buf_speech_enc, L_PAST_MAX_32k + L_FRAME32k + L_NEXT_MAX_32k, sub( Q_old_inp_16k, sub( Q15, st->exp_buf_speech_enc ) ) ); + Scale_sig( st->buf_speech_enc, L_PAST_MAX_32k + L_FRAME32k + L_NEXT_MAX_32k, sub( Q_old_inp_16k, sub( Q15, st->exp_buf_speech_enc ) ) ); /* Q15 - Q_old_inp_16k */ st->exp_buf_speech_enc = sub( Q15, Q_old_inp_16k ); move16(); - Scale_sig( st->buf_speech_enc_pe, L_PAST_MAX_32k + L_FRAME32k + L_NEXT_MAX_32k, sub( Q_old_inp_16k, sub( Q15, st->exp_buf_speech_enc_pe ) ) ); + Scale_sig( st->buf_speech_enc_pe, L_PAST_MAX_32k + L_FRAME32k + L_NEXT_MAX_32k, sub( Q_old_inp_16k, sub( Q15, st->exp_buf_speech_enc_pe ) ) ); /* Q15 - Q_old_inp_16k */ st->exp_buf_speech_enc_pe = sub( Q15, Q_old_inp_16k ); move16(); Scale_sig( st->input_fx, input_frame, sub( -1, st->q_inp ) ); st->q_inp = -1; - Scale_sig( st->buf_wspeech_enc, L_FRAME16k + L_SUBFR + L_FRAME16k + L_NEXT_MAX_16k + 320, sub( Q_old_inp_16k, sub( Q15, st->exp_buf_wspeech_enc ) ) ); + move16(); + Scale_sig( st->buf_wspeech_enc, L_FRAME16k + L_SUBFR + L_FRAME16k + L_NEXT_MAX_16k + 320, sub( Q_old_inp_16k, sub( Q15, st->exp_buf_wspeech_enc ) ) ); /* Q15 - Q_old_inp_16k */ + st->mem_wsp_enc = shl( st->mem_wsp_enc, sub( Q_old_inp_16k, sub( Q15, st->exp_buf_wspeech_enc ) ) ); // Q_old_inp_16k + move16(); st->exp_buf_wspeech_enc = sub( Q15, Q_old_inp_16k ); move16(); - Word16 Q_old_inp_128k = *Q_new; + Word16 Q_inp_12k8 = *Q_new; + move16(); + Word16 Q_inp_16k = *Q_new; move16(); IF( !flag_16k_smc ) { error = ivas_compute_core_buffers_fx( st, &inp_16k_fx, old_inp_16k_fx, new_inp_resamp16k_fx, input_frame, last_element_mode, sr_core_tmp, ener_fx, A_fx, Aw_fx, epsP_fx, - lsp_new_fx, lsp_mid_fx, Q_old_inp_16k, Q_r, Q_new, 0 ); - IF( NE_32( error, IVAS_ERR_OK ) ) + lsp_new_fx, lsp_mid_fx, Q_old_inp_16k, Q_r, &Q_inp_16k ); + IF( GT_16( Q_inp_16k, Q_inp_12k8 ) ) { - return error; + Scale_sig( old_inp_16k_fx, L_INP, sub( Q_inp_12k8, Q_inp_16k ) ); + *Q_new = Q_inp_12k8; + } + ELSE + { + Scale_sig( old_inp_12k8_fx, L_INP_12k8, sub( Q_inp_16k, Q_inp_12k8 ) ); + *Q_new = Q_inp_16k; } - *epsP_fx_q = add( Q_r[0], 1 ); move16(); + + IF( error != IVAS_ERR_OK ) + { + return error; + } + + test(); + IF( EQ_16( st->L_frame, L_FRAME16k ) && NE_16( element_mode, IVAS_CPE_MDCT ) ) + { + *epsP_fx_q = add( Q_r[0], 1 ); + move16(); + } } test(); IF( !( EQ_16( st->L_frame, L_FRAME16k ) && NE_16( element_mode, IVAS_CPE_MDCT ) ) ) { /* update signal buffers */ - Copy( new_inp_12k8_fx, st->buf_speech_enc_pe + st->L_frame, L_FRAME ); + Copy_Scale_sig( new_inp_12k8_fx, st->buf_speech_enc_pe + st->L_frame, L_FRAME, sub( sub( Q15, st->exp_buf_speech_enc_pe ), sub( *Q_new, Q1 ) ) ); Copy( st->buf_speech_enc + L_FRAME32k, st->buf_speech_enc + st->L_frame, L_FRAME ); test(); IF( EQ_16( element_mode, IVAS_CPE_DFT ) ) { - Copy( st->buf_speech_enc + L_FRAME32k - STEREO_DFT_OVL_12k8, st->buf_speech_enc + st->L_frame - STEREO_DFT_OVL_12k8, STEREO_DFT_OVL_12k8 ); + Copy( st->buf_speech_enc + L_FRAME32k - STEREO_DFT_OVL_12k8, st->buf_speech_enc + st->L_frame - STEREO_DFT_OVL_12k8, STEREO_DFT_OVL_12k8 ); /* Q_new - 1 */ } ELSE IF( EQ_16( element_mode, IVAS_CPE_TD ) || EQ_16( element_mode, IVAS_CPE_MDCT ) ) { - Copy( st->buf_speech_enc + L_FRAME32k - lMemRecalc_12k8 - L_FILT, st->buf_speech_enc + st->L_frame - lMemRecalc_12k8 - L_FILT, lMemRecalc_12k8 + L_FILT ); + Copy( st->buf_speech_enc + L_FRAME32k - lMemRecalc_12k8 - L_FILT, st->buf_speech_enc + st->L_frame - lMemRecalc_12k8 - L_FILT, lMemRecalc_12k8 + L_FILT ); /* Q_new - 1 */ } ELSE IF( EQ_16( element_mode, IVAS_SCE ) ) { - Copy( st->buf_speech_enc + L_FRAME32k - L_FILT, st->buf_speech_enc + st->L_frame - L_FILT, L_FILT ); + Copy( st->buf_speech_enc + L_FRAME32k - L_FILT, st->buf_speech_enc + st->L_frame - L_FILT, L_FILT ); /* Q_new - 1 */ } IF( st->tcxonly == 0 ) @@ -615,7 +640,7 @@ ivas_error pre_proc_ivas( IF( flag_16k_smc ) { - Copy( st->buf_speech_enc + L_FRAME16k, new_inp_resamp16k_fx, L_FRAME16k ); + Copy( st->buf_speech_enc + L_FRAME16k, new_inp_resamp16k_fx, L_FRAME16k ); /* Q_old_inp_16k */ } /*-----------------------------------------------------------------* @@ -623,18 +648,14 @@ ivas_error pre_proc_ivas( *-----------------------------------------------------------------*/ /* update old weighted speech buffer - for OL pitch analysis */ - Copy( &old_wsp_fx[L_FRAME], st->old_wsp_fx, L_WSP_MEM ); + Copy( &old_wsp_fx[L_FRAME], st->old_wsp_fx, L_WSP_MEM ); /* exp(e_old_wsp) */ st->exp_old_wsp = e_old_wsp; move16(); - st->exp_buf_speech_enc_pe = sub( Q15, *Q_new - 1 ); - move16(); /* set the pointer of the current frame for the ACELP core */ IF( EQ_16( st->L_frame, L_FRAME ) ) { - *inp_fx = inp_12k8_fx; - *Q_new = Q_old_inp_128k; - move16(); + *inp_fx = inp_12k8_fx; /* Q_old_inp_12k8 */ } ELSE { @@ -651,7 +672,7 @@ ivas_error pre_proc_ivas( test(); IF( st->hTdCngEnc != NULL && st->Opt_DTX_ON && vad_hover_flag ) { - st->hTdCngEnc->burst_ho_cnt = add( st->hTdCngEnc->burst_ho_cnt, 1 ); + st->hTdCngEnc->burst_ho_cnt = add( st->hTdCngEnc->burst_ho_cnt, 1 ); /* Q0 */ move16(); if ( GT_16( st->hTdCngEnc->burst_ho_cnt, HO_HIST_SIZE ) ) { @@ -677,22 +698,21 @@ ivas_error pre_proc_ivas( *--------------------------------------------------------------------*/ ivas_error ivas_compute_core_buffers_fx( Encoder_State *st, /* i/o: encoder state structure */ - Word16 **inp16k_out_fx, /* o : ptr. to inp. signal in the current frame */ - Word16 *old_inp_16k_fx, /* i/o: buffer of old input signal @ 16kHz */ - Word16 new_inp_resamp16k_out_fx[], /* o : new input signal @16kHz, non pre-emphasised, used by the WB TBE/BWE */ - const Word16 input_frame, /* i : frame length */ - const Word16 last_element_mode, /* i : last element mode */ - const Word32 sr_core, /* i : core-coder sampling rate */ - Word32 *ener_fx, /* o : residual energy from Levinson-Durbin Q_r */ - Word16 A_fx[NB_SUBFR16k * ( M + 1 )], /* i/o: A(z) unquantized for the 4 subframes */ - Word16 Aw_fx[NB_SUBFR16k * ( M + 1 )], /* i/o: weighted A(z) unquantized for subframes */ - Word32 epsP_fx[M + 1], /* i/o: LP prediction errors */ - Word16 lsp_new_fx[M], /* i/o: LSPs at the end of the frame */ - Word16 lsp_mid_fx[M], /* i/o: LSPs in the middle of the frame */ + Word16 **inp16k_out_fx, /* o : ptr. to inp. signal in the current frame Q_new-1*/ + Word16 *old_inp_16k_fx, /* i/o: buffer of old input signal @ 16kHz Q_new-1*/ + Word16 new_inp_resamp16k_out_fx[], /* o : new input signal @16kHz, non pre-emphasised, used by the WB TBE/BWE Q_old_inp_16k*/ + const Word16 input_frame, /* i : frame length Q0*/ + const Word16 last_element_mode, /* i : last element mode Q0*/ + const Word32 sr_core, /* i : core-coder sampling rate Q0*/ + Word32 *ener_fx, /* o : residual energy from Levinson-Durbin Q_r*/ + Word16 A_fx[NB_SUBFR16k * ( M + 1 )], /* i/o: A(z) unquantized for the 4 subframes Q14*/ + Word16 Aw_fx[NB_SUBFR16k * ( M + 1 )], /* i/o: weighted A(z) unquantized for subframes Q14*/ + Word32 epsP_fx[M + 1], /* i/o: LP prediction errors Q_r*/ + Word16 lsp_new_fx[M], /* i/o: LSPs at the end of the frame Q15*/ + Word16 lsp_mid_fx[M], /* i/o: LSPs in the middle of the frame Q15*/ Word16 Q_old_inp_16k, Word16 Q_r[2], - Word16 *Q_new, - Word16 downscale_buf_speech_enc_pe ) + Word16 *Q_new ) { Word16 *inp_16k_fx, *new_inp_16k_fx; Word16 delay, element_mode; @@ -719,11 +739,11 @@ ivas_error ivas_compute_core_buffers_fx( #endif set16_fx( epsP_h, 0, M + 1 ); set16_fx( epsP_l, 0, M + 1 ); - signal_in_fx = st->input_fx; + signal_in_fx = st->input_fx; /* st->q_inp */ - input_Fs = st->input_Fs; + input_Fs = st->input_Fs; /* Q0 */ move32(); - element_mode = st->element_mode; + element_mode = st->element_mode; /* Q0 */ move16(); lMemRecalc_16k = 0; @@ -734,7 +754,7 @@ ivas_error ivas_compute_core_buffers_fx( { lMemRecalc_16k = NS2SA( INT_FS_16k, L_MEM_RECALC_NS ); move16(); - lMemRecalc = NS2SA( input_Fs, L_MEM_RECALC_NS ); + lMemRecalc = NS2SA_FX2( input_Fs, L_MEM_RECALC_NS ); move16(); } @@ -752,7 +772,7 @@ ivas_error ivas_compute_core_buffers_fx( L_frame_tmp = s_max( L_FRAME16k, st->L_frame ); } - L_look = NS2SA( sr_core, ACELP_LOOK_NS ); /* lookahead at other sampling rate (16kHz, 25.6kHz, 32kHz) */ + L_look = NS2SA_FX2( sr_core, ACELP_LOOK_NS ); /* lookahead at other sampling rate (16kHz, 25.6kHz, 32kHz) */ move16(); new_inp_16k_fx = old_inp_16k_fx + L_INP_MEM; /* pointer to new samples of the input signal in 16kHz core */ @@ -762,20 +782,20 @@ ivas_error ivas_compute_core_buffers_fx( test(); IF( EQ_16( element_mode, IVAS_CPE_TD ) || EQ_16( element_mode, IVAS_SCE ) ) { - new_inp_16k_fx -= NS2SA( sr_core, DELAY_FIR_RESAMPL_NS ); + new_inp_16k_fx -= NS2SA_FX2( sr_core, DELAY_FIR_RESAMPL_NS ); } IF( EQ_16( element_mode, IVAS_CPE_DFT ) ) { - Copy( st->old_inp_16k_fx, old_inp_16k_fx, L_INP_MEM - STEREO_DFT_OVL_16k ); + Copy( st->old_inp_16k_fx, old_inp_16k_fx, L_INP_MEM - STEREO_DFT_OVL_16k ); /* Q_new - 1 */ } ELSE IF( EQ_16( element_mode, IVAS_CPE_TD ) ) { - Copy( st->old_inp_16k_fx, old_inp_16k_fx, L_INP_MEM - L_MEM_RECALC_16K - L_FILT16k ); + Copy( st->old_inp_16k_fx, old_inp_16k_fx, L_INP_MEM - L_MEM_RECALC_16K - L_FILT16k ); /* Q_new - 1 */ } ELSE { - Copy( st->old_inp_16k_fx, old_inp_16k_fx, L_INP_MEM - L_FILT16k ); + Copy( st->old_inp_16k_fx, old_inp_16k_fx, L_INP_MEM - L_FILT16k ); /* Q_new - 1 */ } /*---------------------------------------------------------------* @@ -791,18 +811,18 @@ ivas_error ivas_compute_core_buffers_fx( delay = NS2SA_FX2( input_Fs, DELAY_FIR_RESAMPL_NS ); move16(); Copy( st->mem_decim16k_fx + delay, new_inp_16k_fx, delay ); - Copy( signal_in_fx, new_inp_16k_fx + delay, input_frame ); - Copy( signal_in_fx + input_frame - shl( delay, 1 ), st->mem_decim16k_fx, shl( delay, 1 ) ); + Copy( signal_in_fx, new_inp_16k_fx + delay, input_frame ); /* st->q_inp */ + Copy( signal_in_fx + input_frame - shl( delay, 1 ), st->mem_decim16k_fx, shl( delay, 1 ) ); /* st->q_inp */ } ELSE IF( EQ_32( input_Fs, 32000 ) || EQ_32( input_Fs, 48000 ) ) { - size_modified = modify_Fs_ivas_fx( signal_in_fx, input_frame, input_Fs, new_inp_16k_fx, sr_core, st->mem_decim16k_fx, 0, &Q_tmp, &mem_decim16k_size ); - Scale_sig( new_inp_16k_fx, size_modified, negate( Q_tmp ) ); /* scaling back to Q_old_inp_16k */ + size_modified = modify_Fs_ivas_fx( signal_in_fx, input_frame, input_Fs, new_inp_16k_fx, sr_core, st->mem_decim16k_fx, 0, &Q_tmp, &mem_decim16k_size ); /* Q0 */ + Scale_sig( new_inp_16k_fx, size_modified, negate( Q_tmp ) ); /* scaling back to Q_old_inp_16k */ - Copy( st->mem_decim16k_fx, mem_decim16k_dummy_fx, 2 * L_FILT_MAX ); + Copy( st->mem_decim16k_fx, mem_decim16k_dummy_fx, 2 * L_FILT_MAX ); /* Q(-1) */ set16_fx( temp1F_icatdmResampBuf_fx, 0, L_FILT_MAX ); - size_modified = modify_Fs_ivas_fx( temp1F_icatdmResampBuf_fx, NS2SA( input_Fs, DELAY_FIR_RESAMPL_NS ), input_Fs, new_inp_16k_fx + NS2SA( sr_core, FRAME_SIZE_NS ), sr_core, mem_decim16k_dummy_fx, 0, &Q_tmp, &mem_decim16k_size ); - Scale_sig( new_inp_16k_fx + NS2SA( sr_core, FRAME_SIZE_NS ), size_modified, negate( Q_tmp ) ); /* scaling back to Q_old_inp_16k */ + size_modified = modify_Fs_ivas_fx( temp1F_icatdmResampBuf_fx, NS2SA_FX2( input_Fs, DELAY_FIR_RESAMPL_NS ), input_Fs, new_inp_16k_fx + NS2SA_FX2( sr_core, FRAME_SIZE_NS ), sr_core, mem_decim16k_dummy_fx, 0, &Q_tmp, &mem_decim16k_size ); /* Q0 */ + Scale_sig( new_inp_16k_fx + NS2SA_FX2( sr_core, FRAME_SIZE_NS ), size_modified, negate( Q_tmp ) ); /* scaling back to Q_old_inp_16k */ } } ELSE IF( EQ_16( element_mode, IVAS_CPE_TD ) ) @@ -813,9 +833,9 @@ ivas_error ivas_compute_core_buffers_fx( /* no resampling needed, only delay adjustment to account for the FIR resampling delay */ delay = NS2SA_FX2( input_Fs, DELAY_FIR_RESAMPL_NS ); move16(); - Copy( st->mem_decim16k_fx + delay, new_inp_16k_fx - sub( lMemRecalc, add( delay, L_FILT16k ) ), delay ); - Copy( signal_in_fx - lMemRecalc, new_inp_16k_fx - add( lMemRecalc, L_FILT16k ), add( input_frame, lMemRecalc ) ); - Copy( signal_in_fx + sub( sub( input_frame, lMemRecalc ), shl( delay, 1 ) ), st->mem_decim16k_fx, shl( delay, 1 ) ); + Copy( st->mem_decim16k_fx + delay, new_inp_16k_fx - sub( lMemRecalc, add( delay, L_FILT16k ) ), delay ); /* Q(-1) */ + Copy( signal_in_fx - lMemRecalc, new_inp_16k_fx - add( lMemRecalc, L_FILT16k ), add( input_frame, lMemRecalc ) ); /* st->q_inp */ + Copy( signal_in_fx + sub( sub( input_frame, lMemRecalc ), shl( delay, 1 ) ), st->mem_decim16k_fx, shl( delay, 1 ) ); /* st->q_inp */ } ELSE IF( EQ_32( input_Fs, 32000 ) || EQ_32( input_Fs, 48000 ) ) { @@ -827,30 +847,30 @@ ivas_error ivas_compute_core_buffers_fx( Word16 length_16k = NS2SA_FX2( INT_FS_16k, L_MEM_RECALC_SCH_NS - DELAY_FIR_RESAMPL_NS ); move16(); - Copy( signal_in_fx - lMemRecalc - length_inp - 2 * NS2SA( input_Fs, DELAY_FIR_RESAMPL_NS ), st->mem_decim16k_fx, 2 * NS2SA( input_Fs, DELAY_FIR_RESAMPL_NS ) ); - size_modified = modify_Fs_ivas_fx( signal_in_fx - lMemRecalc - length_inp, length_inp, input_Fs, new_inp_16k_fx - lMemRecalc_16k - length_16k, sr_core, st->mem_decim16k_fx, 0, &Q_tmp, &mem_decim16k_size ); - Scale_sig( new_inp_16k_fx - lMemRecalc_16k - length_16k, size_modified, negate( Q_tmp ) ); /* scaling back to Q_old_inp_16k */ + Copy( signal_in_fx - lMemRecalc - length_inp - 2 * NS2SA_FX2( input_Fs, DELAY_FIR_RESAMPL_NS ), st->mem_decim16k_fx, 2 * NS2SA_FX2( input_Fs, DELAY_FIR_RESAMPL_NS ) ); /* st->q_inp */ + size_modified = modify_Fs_ivas_fx( signal_in_fx - lMemRecalc - length_inp, length_inp, input_Fs, new_inp_16k_fx - lMemRecalc_16k - length_16k, sr_core, st->mem_decim16k_fx, 0, &Q_tmp, &mem_decim16k_size ); /* Q0 */ + Scale_sig( new_inp_16k_fx - lMemRecalc_16k - length_16k, size_modified, negate( Q_tmp ) ); /* scaling back to Q_old_inp_16k */ } - size_modified = modify_Fs_ivas_fx( signal_in_fx - lMemRecalc, input_frame, input_Fs, new_inp_16k_fx - ( lMemRecalc * sr_core ) / st->input_Fs, sr_core, st->mem_decim16k_fx, 0, &Q_tmp, &mem_decim16k_size ); - Scale_sig( new_inp_16k_fx - ( lMemRecalc * sr_core ) / st->input_Fs, size_modified, negate( Q_tmp ) ); /* scaling back to Q_old_inp_16k */ + size_modified = modify_Fs_ivas_fx( signal_in_fx - lMemRecalc, input_frame, input_Fs, new_inp_16k_fx - ( lMemRecalc * sr_core ) / st->input_Fs, sr_core, st->mem_decim16k_fx, 0, &Q_tmp, &mem_decim16k_size ); /* Q0 */ + Scale_sig( new_inp_16k_fx - ( lMemRecalc * sr_core ) / st->input_Fs, size_modified, negate( Q_tmp ) ); /* scaling back to Q_old_inp_16k */ Copy( st->mem_decim16k_fx, mem_decim16k_dummy_fx, 2 * L_FILT_MAX ); IF( lMemRecalc > 0 ) { - size_modified = modify_Fs_ivas_fx( signal_in_fx - lMemRecalc + input_frame, lMemRecalc, input_Fs, new_inp_16k_fx + NS2SA( sr_core, FRAME_SIZE_NS ) - ( lMemRecalc * sr_core ) / st->input_Fs, sr_core, mem_decim16k_dummy_fx, 0, &Q_tmp, &mem_decim16k_size ); - Scale_sig( new_inp_16k_fx + NS2SA( sr_core, FRAME_SIZE_NS ) - ( lMemRecalc * sr_core ) / st->input_Fs, size_modified, negate( Q_tmp ) ); /* scaling back to Q_old_inp_16k */ + size_modified = modify_Fs_ivas_fx( signal_in_fx - lMemRecalc + input_frame, lMemRecalc, input_Fs, new_inp_16k_fx + NS2SA_FX2( sr_core, FRAME_SIZE_NS ) - ( lMemRecalc * sr_core ) / st->input_Fs, sr_core, mem_decim16k_dummy_fx, 0, &Q_tmp, &mem_decim16k_size ); /* Q0 */ + Scale_sig( new_inp_16k_fx + NS2SA_FX2( sr_core, FRAME_SIZE_NS ) - ( lMemRecalc * sr_core ) / st->input_Fs, size_modified, negate( Q_tmp ) ); /* scaling back to Q_old_inp_16k */ } set16_fx( temp1F_icatdmResampBuf_fx, 0, L_FILT_MAX ); - size_modified = modify_Fs_ivas_fx( temp1F_icatdmResampBuf_fx, NS2SA( input_Fs, DELAY_FIR_RESAMPL_NS ), input_Fs, new_inp_16k_fx + NS2SA( sr_core, FRAME_SIZE_NS ), sr_core, mem_decim16k_dummy_fx, 0, &Q_tmp, &mem_decim16k_size ); - Scale_sig( new_inp_16k_fx + NS2SA( sr_core, FRAME_SIZE_NS ), size_modified, negate( Q_tmp ) ); /* scaling back to Q_old_inp_16k */ + size_modified = modify_Fs_ivas_fx( temp1F_icatdmResampBuf_fx, NS2SA_FX2( input_Fs, DELAY_FIR_RESAMPL_NS ), input_Fs, new_inp_16k_fx + NS2SA_FX2( sr_core, FRAME_SIZE_NS ), sr_core, mem_decim16k_dummy_fx, 0, &Q_tmp, &mem_decim16k_size ); /* Q0 */ + Scale_sig( new_inp_16k_fx + NS2SA_FX2( sr_core, FRAME_SIZE_NS ), size_modified, negate( Q_tmp ) ); /* scaling back to Q_old_inp_16k */ } } ELSE IF( st->idchan == 0 ) { /* update the FIR resampling filter memory, needed for switching to time-domain (FIR) resampling */ - Copy( signal_in_fx + input_frame - NS2SA( input_Fs, L_MEM_RECALC_NS ) - 2 * NS2SA( input_Fs, DELAY_FIR_RESAMPL_NS ), st->mem_decim16k_fx, 2 * NS2SA( input_Fs, DELAY_FIR_RESAMPL_NS ) ); + Copy( signal_in_fx + input_frame - NS2SA_FX2( input_Fs, L_MEM_RECALC_NS ) - 2 * NS2SA_FX2( input_Fs, DELAY_FIR_RESAMPL_NS ), st->mem_decim16k_fx, 2 * NS2SA_FX2( input_Fs, DELAY_FIR_RESAMPL_NS ) ); /* st->q_inp */ } /*------------------------------------------------* @@ -866,12 +886,12 @@ ivas_error ivas_compute_core_buffers_fx( IF( EQ_16( element_mode, IVAS_CPE_DFT ) ) { /* save input resampled at 16kHz, non-preemphasised.*/ - Copy( new_inp_16k_fx, new_inp_resamp16k_fx, L_FRAME16k ); + Copy( new_inp_16k_fx, new_inp_resamp16k_fx, L_FRAME16k ); /* Q_old_inp_16k */ IF( EQ_16( st->bwidth, WB ) ) { - Copy_Scale_sig( new_inp_16k_fx - delay, st->hBWE_FD->old_input_wb_fx, delay, -( Q_old_inp_16k + 1 ) ); /* Scaling to Q(-1) */ - Copy( new_inp_16k_fx - STEREO_DFT_OVL_16k, st->hBWE_FD->L_old_wtda_swb_fx + L_FRAME16k - STEREO_DFT_OVL_16k + delay, STEREO_DFT_OVL_16k - delay ); /* Check Q here once. Q should be Q_old_wtda */ + Copy_Scale_sig( new_inp_16k_fx - delay, st->hBWE_FD->old_input_wb_fx, delay, negate( add( Q_old_inp_16k, 1 ) ) ); /* Scaling to Q(-1) */ + Copy( new_inp_16k_fx - STEREO_DFT_OVL_16k, st->hBWE_FD->L_old_wtda_swb_fx + L_FRAME16k - STEREO_DFT_OVL_16k + delay, sub( STEREO_DFT_OVL_16k, delay ) ); /* Check Q here once. Q should be Q_old_wtda */ } } ELSE IF( EQ_16( element_mode, IVAS_CPE_TD ) ) @@ -882,18 +902,18 @@ ivas_error ivas_compute_core_buffers_fx( test(); IF( EQ_16( st->bwidth, WB ) && st->hBWE_FD != NULL ) { - Copy_Scale_sig( new_inp_16k_fx + L_FILT16k - delay, st->hBWE_FD->old_input_wb_fx, delay, -( Q_old_inp_16k + 1 ) ); /* Scaling to Q(-1) */ - Copy( new_inp_16k_fx - L_MEM_RECALC_16K, st->hBWE_FD->L_old_wtda_swb_fx + L_FRAME16k - L_MEM_RECALC_16K - L_FILT16k + delay, L_MEM_RECALC_16K + L_FILT16k - delay ); /* Check Q here once. Q should be Q_old_wtda */ + Copy_Scale_sig( new_inp_16k_fx + L_FILT16k - delay, st->hBWE_FD->old_input_wb_fx, delay, negate( add( Q_old_inp_16k, 1 ) ) ); /* Scaling to Q(-1) */ + Copy( new_inp_16k_fx - L_MEM_RECALC_16K, st->hBWE_FD->L_old_wtda_swb_fx + L_FRAME16k - L_MEM_RECALC_16K - L_FILT16k + delay, sub( L_MEM_RECALC_16K + L_FILT16k, delay ) ); /* Check Q here once. Q should be Q_old_wtda */ } } ELSE IF( element_mode == IVAS_SCE ) { /* save input resampled at 16kHz, non-preemphasised */ - Copy( new_inp_16k_fx + L_FILT16k, new_inp_resamp16k_fx, L_FRAME16k ); + Copy( new_inp_16k_fx + L_FILT16k, new_inp_resamp16k_fx, L_FRAME16k ); /* Q_old_inp_16k */ IF( EQ_16( st->bwidth, WB ) ) { - Copy_Scale_sig( new_inp_16k_fx, st->hBWE_FD->old_input_wb_fx + delay - L_FILT16k, L_FILT16k, -( Q_old_inp_16k + 1 ) ); /* Scaling to Q(-1) */ + Copy_Scale_sig( new_inp_16k_fx, st->hBWE_FD->old_input_wb_fx + delay - L_FILT16k, L_FILT16k, negate( add( Q_old_inp_16k, 1 ) ) ); /* Scaling to Q(-1) */ /* all buffer st->hBWE_FD->old_wtda_swb is correct and does not need to be updated */ } } @@ -913,7 +933,7 @@ ivas_error ivas_compute_core_buffers_fx( test(); if ( st->tcxonly == 0 && !( ( EQ_16( element_mode, IVAS_CPE_TD ) && EQ_16( st->idchan, 1 ) ) || EQ_16( element_mode, IVAS_CPE_MDCT ) ) ) { - st->mem_preemph_enc = new_inp_16k_fx[L_frame_tmp - 1]; + st->mem_preemph_enc = new_inp_16k_fx[L_frame_tmp - 1]; /* Q(-1) */ move16(); } @@ -925,7 +945,7 @@ ivas_error ivas_compute_core_buffers_fx( set32_fx( sig_out, 0, 960 ); test(); test(); - if ( ( ( EQ_16( st->bwidth, NB ) ) || ( EQ_16( st->max_bwidth, NB ) ) ) && ( GT_32( st->input_Fs, 8000 ) ) ) + if ( ( ( st->bwidth == NB ) || ( st->max_bwidth == NB ) ) && ( GT_32( st->input_Fs, 8000 ) ) ) { headroom = add( headroom, 1 ); } @@ -935,24 +955,24 @@ ivas_error ivas_compute_core_buffers_fx( { IF( EQ_16( element_mode, IVAS_CPE_DFT ) ) { - Copy( new_inp_16k_fx - STEREO_DFT_OVL_16k + L_FRAME16k, st->inp_16k_mem_stereo_sw_fx, STEREO_DFT_OVL_16k - L_MEM_RECALC_16K - L_FILT16k ); /* update for TD/DFT stereo switching */ + Copy( new_inp_16k_fx - STEREO_DFT_OVL_16k + L_FRAME16k, st->inp_16k_mem_stereo_sw_fx, STEREO_DFT_OVL_16k - L_MEM_RECALC_16K - L_FILT16k ); /* update for TD/DFT stereo switching Q(-1) */ - st->mem_preemph16k_fx = st->mem_preemph16k_DFT_fx; + st->mem_preemph16k_fx = st->mem_preemph16k_DFT_fx; /* Q(-1) */ move16(); - st->mem_preemph16k_DFT_fx = old_inp_16k_fx[L_INP_MEM - STEREO_DFT_OVL_16k + L_FRAME16k - 1]; + st->mem_preemph16k_DFT_fx = old_inp_16k_fx[L_INP_MEM - STEREO_DFT_OVL_16k + L_FRAME16k - 1]; /* Q_new - 1 */ move16(); IF( EQ_16( st->L_frame, L_FRAME16k ) ) { - Copy( new_inp_16k_fx - STEREO_DFT_OVL_16k, st->buf_speech_enc + L_FRAME16k - STEREO_DFT_OVL_16k, L_FRAME16k + STEREO_DFT_OVL_16k ); + Copy( new_inp_16k_fx - STEREO_DFT_OVL_16k, st->buf_speech_enc + L_FRAME16k - STEREO_DFT_OVL_16k, L_FRAME16k + STEREO_DFT_OVL_16k ); /* Q(-1) */ } // PREEMPH_FX(new_inp_16k_fx - STEREO_DFT_OVL_16k, PREEMPH_FAC_16k, L_FRAME16k, &(st->mem_preemph16k_fx)); - PREEMPH_32FX( new_inp_16k_fx - STEREO_DFT_OVL_16k, sig_out, PREEMPH_FAC_16k, L_FRAME16k, &( st->mem_preemph16k_fx ) ); + PREEMPH_32FX( new_inp_16k_fx - STEREO_DFT_OVL_16k, sig_out, PREEMPH_FAC_16k, L_FRAME16k, &( st->mem_preemph16k_fx ) ); /* Q(-1) */ tmp_fx = st->mem_preemph16k_fx; move16(); // PREEMPH_FX(new_inp_16k_fx - STEREO_DFT_OVL_16k + L_FRAME16k, PREEMPH_FAC_16k, STEREO_DFT_OVL_16k, &tmp_fx); - PREEMPH_32FX( new_inp_16k_fx - STEREO_DFT_OVL_16k + L_FRAME16k, sig_out + L_FRAME16k, PREEMPH_FAC_16k, STEREO_DFT_OVL_16k, &tmp_fx ); + PREEMPH_32FX( new_inp_16k_fx - STEREO_DFT_OVL_16k + L_FRAME16k, sig_out + L_FRAME16k, PREEMPH_FAC_16k, STEREO_DFT_OVL_16k, &tmp_fx ); /* Q(-1) */ preemp_start_idx = new_inp_16k_fx - STEREO_DFT_OVL_16k; move16(); preemp_len = STEREO_DFT_OVL_16k + L_FRAME16k; @@ -964,16 +984,16 @@ ivas_error ivas_compute_core_buffers_fx( { st->mem_preemph16k_fx = st->mem_preemph16k_DFT_fx; move16(); - Copy( st->inp_16k_mem_stereo_sw_fx, new_inp_16k_fx - L_MEM_RECALC_16K - ( STEREO_DFT_OVL_16k - L_MEM_RECALC_16K - L_FILT16k ), STEREO_DFT_OVL_16k - L_MEM_RECALC_16K - L_FILT16k ); + Copy( st->inp_16k_mem_stereo_sw_fx, new_inp_16k_fx - L_MEM_RECALC_16K - ( STEREO_DFT_OVL_16k - L_MEM_RECALC_16K - L_FILT16k ), STEREO_DFT_OVL_16k - L_MEM_RECALC_16K - L_FILT16k ); /* Q(-1) */ // PREEMPH_FX(new_inp_16k_fx - L_MEM_RECALC_16K - (STEREO_DFT_OVL_16k - L_MEM_RECALC_16K - L_FILT16k), PREEMPH_FAC_16k, STEREO_DFT_OVL_16k - L_MEM_RECALC_16K - L_FILT16k, &st->mem_preemph16k_fx); - PREEMPH_32FX( new_inp_16k_fx - L_MEM_RECALC_16K - ( STEREO_DFT_OVL_16k - L_MEM_RECALC_16K - L_FILT16k ), sig_out, PREEMPH_FAC_16k, STEREO_DFT_OVL_16k - L_MEM_RECALC_16K - L_FILT16k, &st->mem_preemph16k_fx ); + PREEMPH_32FX( new_inp_16k_fx - L_MEM_RECALC_16K - ( STEREO_DFT_OVL_16k - L_MEM_RECALC_16K - L_FILT16k ), sig_out, PREEMPH_FAC_16k, STEREO_DFT_OVL_16k - L_MEM_RECALC_16K - L_FILT16k, &st->mem_preemph16k_fx ); /* Q(-1) */ preemp_start_idx = new_inp_16k_fx - L_MEM_RECALC_16K - ( STEREO_DFT_OVL_16k - L_MEM_RECALC_16K - L_FILT16k ); move16(); preemp_len = STEREO_DFT_OVL_16k - L_MEM_RECALC_16K - L_FILT16k; move16(); } - st->mem_preemph16k_DFT_fx = old_inp_16k_fx[L_INP_MEM - STEREO_DFT_OVL_16k + L_FRAME16k - 1]; + st->mem_preemph16k_DFT_fx = old_inp_16k_fx[L_INP_MEM - STEREO_DFT_OVL_16k + L_FRAME16k - 1]; /* Q_new - 1 */ move16(); /* preemphasise past segment of input signal when switching from MDCT stereo */ @@ -983,7 +1003,7 @@ ivas_error ivas_compute_core_buffers_fx( move16(); // PREEMPH_FX(new_inp_16k_fx - lMemRecalc_16k - length_16k, PREEMPH_FAC, length_16k, &st->mem_preemph16k_fx); - PREEMPH_32FX( new_inp_16k_fx - lMemRecalc_16k - length_16k, sig_out, PREEMPH_FAC, length_16k, &st->mem_preemph16k_fx ); + PREEMPH_32FX( new_inp_16k_fx - lMemRecalc_16k - length_16k, sig_out, PREEMPH_FAC, length_16k, &st->mem_preemph16k_fx ); /* Q(-1) */ preemp_start_idx = new_inp_16k_fx - lMemRecalc_16k - length_16k; preemp_len = length_16k; move16(); @@ -991,14 +1011,14 @@ ivas_error ivas_compute_core_buffers_fx( IF( EQ_16( st->L_frame, L_FRAME16k ) ) { - Copy( new_inp_16k_fx - lMemRecalc_16k, st->buf_speech_enc + sub( L_FRAME16k - L_FILT16k, lMemRecalc_16k ), add( lMemRecalc_16k, L_FRAME16k + L_FILT16k ) ); + Copy( new_inp_16k_fx - lMemRecalc_16k, st->buf_speech_enc + sub( L_FRAME16k - L_FILT16k, lMemRecalc_16k ), add( lMemRecalc_16k, L_FRAME16k + L_FILT16k ) ); /* Q_new - 1 */ } // PREEMPH_FX(new_inp_16k_fx - lMemRecalc_16k, PREEMPH_FAC_16k, L_FRAME16k, &(st->mem_preemph16k_fx)); - PREEMPH_32FX( new_inp_16k_fx - lMemRecalc_16k, sig_out + preemp_len, PREEMPH_FAC_16k, L_FRAME16k, &( st->mem_preemph16k_fx ) ); + PREEMPH_32FX( new_inp_16k_fx - lMemRecalc_16k, sig_out + preemp_len, PREEMPH_FAC_16k, L_FRAME16k, &( st->mem_preemph16k_fx ) ); /* Q(-1) */ tmp_fx = st->mem_preemph16k_fx; move16(); // PREEMPH_FX(new_inp_16k_fx - lMemRecalc_16k + L_FRAME16k, PREEMPH_FAC_16k, lMemRecalc_16k + L_FILT16k, &tmp_fx); - PREEMPH_32FX( new_inp_16k_fx - lMemRecalc_16k + L_FRAME16k, sig_out + preemp_len + L_FRAME16k, PREEMPH_FAC_16k, lMemRecalc_16k + L_FILT16k, &tmp_fx ); + PREEMPH_32FX( new_inp_16k_fx - lMemRecalc_16k + L_FRAME16k, sig_out + preemp_len + L_FRAME16k, PREEMPH_FAC_16k, lMemRecalc_16k + L_FILT16k, &tmp_fx ); /* Q(-1) */ IF( preemp_start_idx && preemp_len ) { preemp_len = add( preemp_len, add( L_FRAME16k + L_FILT16k, lMemRecalc_16k ) ); @@ -1014,11 +1034,11 @@ ivas_error ivas_compute_core_buffers_fx( ELSE IF( EQ_16( element_mode, IVAS_SCE ) ) { // PREEMPH_FX(new_inp_16k_fx, PREEMPH_FAC_16k, L_FRAME16k, &(st->mem_preemph16k_fx)); - PREEMPH_32FX( new_inp_16k_fx, sig_out, PREEMPH_FAC_16k, L_FRAME16k, &( st->mem_preemph16k_fx ) ); + PREEMPH_32FX( new_inp_16k_fx, sig_out, PREEMPH_FAC_16k, L_FRAME16k, &( st->mem_preemph16k_fx ) ); /* Q(-1) */ tmp_fx = st->mem_preemph16k_fx; move16(); // PREEMPH_FX(new_inp_16k_fx + L_FRAME16k, PREEMPH_FAC_16k, L_FILT16k, &tmp_fx); - PREEMPH_32FX( new_inp_16k_fx + L_FRAME16k, sig_out + L_FRAME16k, PREEMPH_FAC_16k, L_FILT16k, &tmp_fx ); + PREEMPH_32FX( new_inp_16k_fx + L_FRAME16k, sig_out + L_FRAME16k, PREEMPH_FAC_16k, L_FILT16k, &tmp_fx ); /* Q(-1) */ preemp_start_idx = new_inp_16k_fx; preemp_len = L_FRAME16k + L_FILT16k; move16(); @@ -1058,12 +1078,12 @@ ivas_error ivas_compute_core_buffers_fx( { IF( EQ_16( element_mode, IVAS_CPE_DFT ) ) { - st->mem_preemph16k_fx = new_inp_16k_fx[L_frame_tmp - STEREO_DFT_OVL_16k - 1]; + st->mem_preemph16k_fx = new_inp_16k_fx[L_frame_tmp - STEREO_DFT_OVL_16k - 1]; /* Q_new - 1 */ move16(); } ELSE IF( EQ_16( element_mode, IVAS_CPE_TD ) ) { - st->mem_preemph16k_fx = new_inp_16k_fx[L_frame_tmp - lMemRecalc_16k - 1]; + st->mem_preemph16k_fx = new_inp_16k_fx[L_frame_tmp - lMemRecalc_16k - 1]; /* Q_new - 1 */ move16(); } ELSE IF( EQ_16( element_mode, IVAS_CPE_MDCT ) ) @@ -1073,10 +1093,10 @@ ivas_error ivas_compute_core_buffers_fx( } ELSE /* SCE */ { - st->mem_preemph16k_fx = new_inp_16k_fx[L_frame_tmp - 1]; + st->mem_preemph16k_fx = new_inp_16k_fx[L_frame_tmp - 1]; /* Q_new - 1 */ move16(); } - st->mem_preemph16k_DFT_fx = st->mem_preemph16k_fx; + st->mem_preemph16k_DFT_fx = st->mem_preemph16k_fx; /* Q_new - 1 */ move16(); } @@ -1090,14 +1110,7 @@ ivas_error ivas_compute_core_buffers_fx( { /* update signal buffers */ Word16 shift; - IF( downscale_buf_speech_enc_pe ) - { - shift = negate( *Q_new ); - } - ELSE - { - shift = 0; - } + shift = negate( *Q_new ); move16(); IF( EQ_16( element_mode, IVAS_CPE_DFT ) ) { @@ -1120,7 +1133,7 @@ ivas_error ivas_compute_core_buffers_fx( IF( EQ_16( st->last_L_frame, L_FRAME ) ) { /* this is just an approximation, but it is sufficient */ - Copy( st->lsp_old1_fx, st->lspold_enc_fx, M ); + Copy( st->lsp_old1_fx, st->lspold_enc_fx, M ); /* Q15 */ } IF( Q_new ) @@ -1136,7 +1149,7 @@ ivas_error ivas_compute_core_buffers_fx( * Compute Weighted Input *---------------------------------------------------------------*/ - ivas_find_wsp( L_FRAME16k, L_SUBFR, NB_SUBFR16k, A_fx, Aw_fx, st->speech_enc_pe, PREEMPH_FAC_16k, st->wspeech_enc, &st->mem_wsp_enc, st->gamma, L_LOOK_16k ); + ivas_find_wsp_fx( L_FRAME16k, L_SUBFR, NB_SUBFR16k, A_fx, Aw_fx, st->speech_enc_pe, PREEMPH_FAC_16k, st->wspeech_enc, &st->mem_wsp_enc, st->gamma, L_LOOK_16k ); } /*-----------------------------------------------------------------* @@ -1165,14 +1178,14 @@ ivas_error ivas_compute_core_buffers_fx( ELSE IF( GT_32( input_Fs, 8000 ) ) { lerp( st->old_inp_12k8_fx + L_INP_MEM - L_INP_MEM * 4 / 5, st->old_inp_16k_fx, L_INP_MEM, L_INP_MEM * 4 / 5 ); - Scale_sig( st->old_inp_16k_fx, L_INP_MEM, sub( -1 /* Q st->old_inp_16k_fx = -1 */, sub( 15, st->exp_old_inp_16k ) ) ); + Scale_sig( st->old_inp_16k_fx, L_INP_MEM, sub( -1 /* Q st->old_inp_16k_fx = -1 */, sub( 15, st->exp_old_inp_12k8 ) ) ); st->exp_old_inp_16k = Q16; // Q-1 move16(); } IF( inp16k_out_fx != NULL ) { - *inp16k_out_fx = inp_16k_fx; + *inp16k_out_fx = inp_16k_fx; /* Q_new - 1 */ } IF( new_inp_resamp16k_out_fx != NULL ) diff --git a/lib_enc/ivas_corecoder_enc_reconfig.c b/lib_enc/ivas_corecoder_enc_reconfig_fx.c similarity index 82% rename from lib_enc/ivas_corecoder_enc_reconfig.c rename to lib_enc/ivas_corecoder_enc_reconfig_fx.c index ea5676d5f909e31d496b472b0ad51108cc8848bf..a1f2196fb0af3dfb3311509761c86508740f644a 100644 --- a/lib_enc/ivas_corecoder_enc_reconfig.c +++ b/lib_enc/ivas_corecoder_enc_reconfig_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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,8 @@ #include #include "options.h" #include "ivas_cnst.h" -#include "prot.h" #include "prot_fx.h" #include "prot_fx_enc.h" -#include "ivas_prot.h" #include "wmc_auto.h" #include "ivas_prot_fx.h" #include "math.h" @@ -48,11 +46,11 @@ /* Some float operations are still pending */ ivas_error ivas_corecoder_enc_reconfig_fx( Encoder_Struct *st_ivas, /* i/o: IVAS encoder structure */ - const Word16 nSCE_old, /* i : number of SCEs in previous frame */ - const Word16 nCPE_old, /* i : number of CPEs in previous frame */ - const Word16 nchan_transport_old, /* i : number of TCs in previous frame */ - const Word32 brate_SCE, /* i : bitrate to be set for the SCEs */ - const Word32 brate_CPE, /* i : bitrate to be set for the CPEs */ + const Word16 nSCE_old, /* i : number of SCEs in previous frame Q0*/ + const Word16 nCPE_old, /* i : number of CPEs in previous frame Q0*/ + const Word16 nchan_transport_old, /* i : number of TCs in previous frame Q0*/ + const Word32 brate_SCE, /* i : bitrate to be set for the SCEs Q0*/ + const Word32 brate_CPE, /* i : bitrate to be set for the CPEs Q0*/ const MC_MODE last_mc_mode /* i : switching between MC modes: last mode */ ) { @@ -81,22 +79,22 @@ ivas_error ivas_corecoder_enc_reconfig_fx( move32(); set16_fx( q_input_buff, Q31, MCT_MAX_BLOCKS ); - input_frame = idiv1616U( extract_l( L_shr( hEncoderConfig->input_Fs, 1 ) ), FRAMES_PER_SEC / 2 ); - len_inp_memory = input_frame; + input_frame = idiv1616U( extract_l( L_shr( hEncoderConfig->input_Fs, 1 ) ), FRAMES_PER_SEC / 2 ); /* Q0 */ + len_inp_memory = input_frame; /* Q0 */ move16(); IF( EQ_16( hEncoderConfig->ivas_format, SBA_FORMAT ) ) { - len_inp_memory = add( len_inp_memory, NS2SA( hEncoderConfig->input_Fs, IVAS_FB_ENC_DELAY_NS ) ); + len_inp_memory = add( len_inp_memory, NS2SA_FX2( hEncoderConfig->input_Fs, IVAS_FB_ENC_DELAY_NS ) ); /* Q0 */ } - nchan_transport_old_real = nchan_transport_old; + nchan_transport_old_real = nchan_transport_old; /* Q0 */ move16(); - nchan_transport_real = st_ivas->nchan_transport; + nchan_transport_real = st_ivas->nchan_transport; /* Q0 */ move16(); IF( EQ_16( st_ivas->ism_mode, ISM_SBA_MODE_DISC ) ) { - nchan_transport_real = add( nchan_transport_real, st_ivas->hEncoderConfig->nchan_ism ); + nchan_transport_real = add( nchan_transport_real, st_ivas->hEncoderConfig->nchan_ism ); /* Q0 */ } /*-----------------------------------------------------------------* @@ -110,15 +108,15 @@ ivas_error ivas_corecoder_enc_reconfig_fx( FOR( sce_id = 0; sce_id < st_ivas->nSCE; sce_id++ ) { copy_encoder_config_fx( st_ivas, st_ivas->hSCE[sce_id]->hCoreCoder[0], 0 ); - st_ivas->hSCE[sce_id]->element_brate = brate_SCE; + st_ivas->hSCE[sce_id]->element_brate = brate_SCE; /* Q0 */ move32(); - st_ivas->hSCE[sce_id]->hCoreCoder[0]->total_brate = st_ivas->hSCE[sce_id]->element_brate; /* dummy initialization for getting right pointers initialization of input buffers in init_coder_ace_plus() */ + st_ivas->hSCE[sce_id]->hCoreCoder[0]->total_brate = st_ivas->hSCE[sce_id]->element_brate; /* dummy initialization for getting right pointers initialization of input buffers in init_coder_ace_plus() Q0*/ move32(); } FOR( cpe_id = 0; cpe_id < st_ivas->nCPE; cpe_id++ ) { - st_ivas->hCPE[cpe_id]->element_brate = brate_CPE; + st_ivas->hCPE[cpe_id]->element_brate = brate_CPE; /* Q0 */ move32(); /* prepare bitstream buffers */ @@ -133,14 +131,14 @@ ivas_error ivas_corecoder_enc_reconfig_fx( tmp = 0; move16(); } - st_ivas->hCPE[cpe_id]->hCoreCoder[n]->total_brate = L_shr( st_ivas->hCPE[cpe_id]->element_brate, tmp ); /* dummy initialization for getting right pointers initialization of input buffers in init_coder_ace_plus() */ + st_ivas->hCPE[cpe_id]->hCoreCoder[n]->total_brate = L_shr( st_ivas->hCPE[cpe_id]->element_brate, tmp ); /* dummy initialization for getting right pointers initialization of input buffers in init_coder_ace_plus() Q0*/ move32(); } } IF( GT_16( st_ivas->nCPE, 1 ) ) { - IF( NE_32( ( error = mct_enc_reconfigure_fx( st_ivas, 0 ) ), IVAS_ERR_OK ) ) + IF( ( error = mct_enc_reconfigure_fx( st_ivas, 0 ) ) != IVAS_ERR_OK ) { return error; } @@ -153,13 +151,13 @@ ivas_error ivas_corecoder_enc_reconfig_fx( test(); IF( EQ_16( hEncoderConfig->ivas_format, MC_FORMAT ) && EQ_16( last_mc_mode, MC_MODE_MCMASA ) ) { - nchan_transport_old_real = add( nSCE_old, i_mult( CPE_CHANNELS, nCPE_old ) ); + nchan_transport_old_real = add( nSCE_old, i_mult( CPE_CHANNELS, nCPE_old ) ); /* Q0 */ } test(); IF( EQ_16( hEncoderConfig->ivas_format, MC_FORMAT ) && EQ_16( st_ivas->mc_mode, MC_MODE_MCMASA ) ) { - nchan_transport_real = add( st_ivas->nSCE, i_mult( CPE_CHANNELS, st_ivas->nCPE ) ); + nchan_transport_real = add( st_ivas->nSCE, i_mult( CPE_CHANNELS, st_ivas->nCPE ) ); /* Q0 */ } /* something in transport changes */ @@ -176,7 +174,7 @@ ivas_error ivas_corecoder_enc_reconfig_fx( } /* save bitstream information */ - nb_bits_tot = hBstr->nb_bits_tot; + nb_bits_tot = hBstr->nb_bits_tot; /* Q0 */ move16(); i = 0; move16(); @@ -188,13 +186,13 @@ ivas_error ivas_corecoder_enc_reconfig_fx( { IF( hBstr->ind_list[i].nb_bits > 0 ) { - temp_ind_list[i].id = hBstr->ind_list[i].id; + temp_ind_list[i].id = hBstr->ind_list[i].id; /* Q0 */ move16(); - temp_ind_list[i].value = hBstr->ind_list[i].value; + temp_ind_list[i].value = hBstr->ind_list[i].value; /* Q0 */ move16(); - temp_ind_list[i].nb_bits = hBstr->ind_list[i].nb_bits; + temp_ind_list[i].nb_bits = hBstr->ind_list[i].nb_bits; /* Q0 */ move16(); - hBstr->ind_list[i].nb_bits = -1; + hBstr->ind_list[i].nb_bits = -1; /* Q0 */ move16(); } @@ -203,7 +201,7 @@ ivas_error ivas_corecoder_enc_reconfig_fx( hBstr->nb_ind_tot = 0; move16(); - nb_bits = add( nb_bits, temp_ind_list[i].nb_bits ); + nb_bits = add( nb_bits, temp_ind_list[i].nb_bits ); /* Q0 */ i = add( i, 1 ); test(); } @@ -224,12 +222,12 @@ ivas_error ivas_corecoder_enc_reconfig_fx( FOR( k = 0; k < nSCE_old; k++ ) { shift = getScaleFactor16( st_ivas->hSCE[k]->hCoreCoder[0]->old_input_signal_fx, input_frame ); - Scale_sig( st_ivas->hSCE[k]->hCoreCoder[0]->old_input_signal_fx, input_frame, shift ); + Scale_sig( st_ivas->hSCE[k]->hCoreCoder[0]->old_input_signal_fx, input_frame, shift ); /* st_ivas->hSCE[k]->hCoreCoder[0]->q_old_inp + shift */ st_ivas->hSCE[k]->hCoreCoder[0]->q_old_inp = add( st_ivas->hSCE[k]->hCoreCoder[0]->q_old_inp, shift ); move16(); q_com_sce = s_min( q_com_sce, st_ivas->hSCE[k]->hCoreCoder[0]->q_old_inp ); shift = getScaleFactor16( st_ivas->hSCE[k]->hCoreCoder[0]->input_fx, sub( L_FRAME48k + L_FRAME48k + NS2SA( 48000, DELAY_FIR_RESAMPL_NS ), input_frame ) ); - Scale_sig( st_ivas->hSCE[k]->hCoreCoder[0]->input_fx, sub( L_FRAME48k + L_FRAME48k + NS2SA( 48000, DELAY_FIR_RESAMPL_NS ), input_frame ), shift ); + Scale_sig( st_ivas->hSCE[k]->hCoreCoder[0]->input_fx, sub( L_FRAME48k + L_FRAME48k + NS2SA( 48000, DELAY_FIR_RESAMPL_NS ), input_frame ), shift ); /* st_ivas->hSCE[k]->hCoreCoder[0]->q_inp + shift */ st_ivas->hSCE[k]->hCoreCoder[0]->q_inp = add( st_ivas->hSCE[k]->hCoreCoder[0]->q_inp, shift ); move16(); q_com_sce = s_min( q_com_sce, st_ivas->hSCE[k]->hCoreCoder[0]->q_inp ); @@ -244,12 +242,12 @@ ivas_error ivas_corecoder_enc_reconfig_fx( FOR( n = 0; n < CPE_CHANNELS; n++ ) { shift = getScaleFactor16( st_ivas->hCPE[cpe_id]->hCoreCoder[n]->old_input_signal_fx, input_frame ); - Scale_sig( st_ivas->hCPE[cpe_id]->hCoreCoder[n]->old_input_signal_fx, input_frame, shift ); + Scale_sig( st_ivas->hCPE[cpe_id]->hCoreCoder[n]->old_input_signal_fx, input_frame, shift ); /* st_ivas->hCPE[cpe_id]->hCoreCoder[n]->q_old_inp + shift */ st_ivas->hCPE[cpe_id]->hCoreCoder[n]->q_old_inp = add( st_ivas->hCPE[cpe_id]->hCoreCoder[n]->q_old_inp, shift ); move16(); q_com_cpe = s_min( q_com_cpe, st_ivas->hCPE[cpe_id]->hCoreCoder[n]->q_old_inp ); shift = getScaleFactor16( st_ivas->hCPE[cpe_id]->hCoreCoder[n]->input_fx, sub( L_FRAME48k + L_FRAME48k + NS2SA( 48000, DELAY_FIR_RESAMPL_NS ), input_frame ) ); - Scale_sig( st_ivas->hCPE[cpe_id]->hCoreCoder[n]->input_fx, sub( L_FRAME48k + L_FRAME48k + NS2SA( 48000, DELAY_FIR_RESAMPL_NS ), input_frame ), shift ); + Scale_sig( st_ivas->hCPE[cpe_id]->hCoreCoder[n]->input_fx, sub( L_FRAME48k + L_FRAME48k + NS2SA( 48000, DELAY_FIR_RESAMPL_NS ), input_frame ), shift ); /* st_ivas->hCPE[cpe_id]->hCoreCoder[n]->q_inp + shift */ st_ivas->hCPE[cpe_id]->hCoreCoder[n]->q_inp = add( st_ivas->hCPE[cpe_id]->hCoreCoder[n]->q_inp, shift ); move16(); q_com_cpe = s_min( q_com_cpe, st_ivas->hCPE[cpe_id]->hCoreCoder[n]->q_inp ); @@ -261,13 +259,13 @@ ivas_error ivas_corecoder_enc_reconfig_fx( { FOR( k = 0; k < nSCE_old; k++ ) { - Scale_sig( st_ivas->hSCE[k]->hCoreCoder[0]->old_input_signal_fx, input_frame, sub( q_com, st_ivas->hSCE[k]->hCoreCoder[0]->q_old_inp ) ); + Scale_sig( st_ivas->hSCE[k]->hCoreCoder[0]->old_input_signal_fx, input_frame, sub( q_com, st_ivas->hSCE[k]->hCoreCoder[0]->q_old_inp ) ); /* q_com */ st_ivas->hSCE[k]->hCoreCoder[0]->q_old_inp = q_com; move16(); - Scale_sig( st_ivas->hSCE[k]->hCoreCoder[0]->input_fx, sub( L_FRAME48k + L_FRAME48k + NS2SA( 48000, DELAY_FIR_RESAMPL_NS ), input_frame ), sub( q_com, st_ivas->hSCE[k]->hCoreCoder[0]->q_inp ) ); + Scale_sig( st_ivas->hSCE[k]->hCoreCoder[0]->input_fx, sub( L_FRAME48k + L_FRAME48k + NS2SA( 48000, DELAY_FIR_RESAMPL_NS ), input_frame ), sub( q_com, st_ivas->hSCE[k]->hCoreCoder[0]->q_inp ) ); /* q_com */ st_ivas->hSCE[k]->hCoreCoder[0]->q_inp = q_com; move16(); - Copy_Scale_sig_16_32( st_ivas->hSCE[k]->hCoreCoder[0]->input_buff_fx, st_ivas->hSCE[k]->hCoreCoder[0]->input_buff32_fx, L_FRAME48k + NS2SA( 48000, IVAS_FB_ENC_DELAY_NS ) + L_FRAME48k, Q6 ); + Copy_Scale_sig_16_32_DEPREC( st_ivas->hSCE[k]->hCoreCoder[0]->input_buff_fx, st_ivas->hSCE[k]->hCoreCoder[0]->input_buff32_fx, L_FRAME48k + NS2SA( 48000, IVAS_FB_ENC_DELAY_NS ) + L_FRAME48k, Q6 ); /* Q6 + q_com */ st_ivas->hSCE[k]->hCoreCoder[0]->q_inp32 = add( Q6, q_com ); move16(); } @@ -279,13 +277,13 @@ ivas_error ivas_corecoder_enc_reconfig_fx( { FOR( n = 0; n < CPE_CHANNELS; n++ ) { - Scale_sig( st_ivas->hCPE[cpe_id]->hCoreCoder[n]->old_input_signal_fx, input_frame, sub( q_com, st_ivas->hCPE[cpe_id]->hCoreCoder[n]->q_old_inp ) ); + Scale_sig( st_ivas->hCPE[cpe_id]->hCoreCoder[n]->old_input_signal_fx, input_frame, sub( q_com, st_ivas->hCPE[cpe_id]->hCoreCoder[n]->q_old_inp ) ); /* q_com */ st_ivas->hCPE[cpe_id]->hCoreCoder[n]->q_old_inp = q_com; move16(); - Scale_sig( st_ivas->hCPE[cpe_id]->hCoreCoder[n]->input_fx, sub( L_FRAME48k + L_FRAME48k + NS2SA( 48000, DELAY_FIR_RESAMPL_NS ), input_frame ), sub( q_com, st_ivas->hCPE[cpe_id]->hCoreCoder[n]->q_inp ) ); + Scale_sig( st_ivas->hCPE[cpe_id]->hCoreCoder[n]->input_fx, sub( L_FRAME48k + L_FRAME48k + NS2SA( 48000, DELAY_FIR_RESAMPL_NS ), input_frame ), sub( q_com, st_ivas->hCPE[cpe_id]->hCoreCoder[n]->q_inp ) ); /* q_com */ st_ivas->hCPE[cpe_id]->hCoreCoder[n]->q_inp = q_com; move16(); - Copy_Scale_sig_16_32( st_ivas->hCPE[cpe_id]->hCoreCoder[n]->input_buff_fx, st_ivas->hCPE[cpe_id]->hCoreCoder[n]->input_buff32_fx, L_FRAME48k + NS2SA( 48000, IVAS_FB_ENC_DELAY_NS ) + L_FRAME48k, Q6 ); + Copy_Scale_sig_16_32_DEPREC( st_ivas->hCPE[cpe_id]->hCoreCoder[n]->input_buff_fx, st_ivas->hCPE[cpe_id]->hCoreCoder[n]->input_buff32_fx, L_FRAME48k + NS2SA( 48000, IVAS_FB_ENC_DELAY_NS ) + L_FRAME48k, Q6 ); /* Q6 + q_com */ st_ivas->hCPE[cpe_id]->hCoreCoder[n]->q_inp32 = add( Q6, q_com ); move16(); } @@ -302,7 +300,7 @@ ivas_error ivas_corecoder_enc_reconfig_fx( IF( nSCE_old > 0 ) { set32_fx( input_buff_fx[0], 0, len_inp_memory ); - Copy32( st_ivas->hSCE[0]->hCoreCoder[0]->input_buff32_fx, input_buff_fx[0], len_inp_memory ); + Copy32( st_ivas->hSCE[0]->hCoreCoder[0]->input_buff32_fx, input_buff_fx[0], len_inp_memory ); /* st_ivas->hSCE[0]->hCoreCoder[0]->q_inp32 */ q_input_buff[0] = st_ivas->hSCE[0]->hCoreCoder[0]->q_inp32; move16(); } @@ -312,20 +310,21 @@ ivas_error ivas_corecoder_enc_reconfig_fx( set32_fx( input_buff_fx[n + 1], 0, len_inp_memory ); IF( nCPE_old > 0 ) { - Copy32( st_ivas->hCPE[0]->hCoreCoder[n]->input_buff32_fx, input_buff_fx[n + 1], len_inp_memory ); + Copy32( st_ivas->hCPE[0]->hCoreCoder[n]->input_buff32_fx, input_buff_fx[n + 1], len_inp_memory ); /* st_ivas->hCPE[0]->hCoreCoder[n]->q_inp32 */ q_input_buff[n + 1] = st_ivas->hCPE[0]->hCoreCoder[n]->q_inp32; move16(); } } - ivas_mcmasa_dmx_modify_fx( len_inp_memory, input_buff_fx, nSCE_old + CPE_CHANNELS * nCPE_old, st_ivas->nSCE + CPE_CHANNELS * st_ivas->nCPE ); + ivas_mcmasa_dmx_modify_fx( len_inp_memory, input_buff_fx, q_input_buff, nSCE_old + CPE_CHANNELS * nCPE_old, st_ivas->nSCE + CPE_CHANNELS * st_ivas->nCPE ); + n_CoreCoder_existing = 0; move16(); } ELSE { - n_CoreCoder_existing = s_min( nchan_transport_real, nchan_transport_old_real ); + n_CoreCoder_existing = s_min( nchan_transport_real, nchan_transport_old_real ); /* Q0 */ } /* destroy superfluous core-coder elements */ @@ -334,11 +333,11 @@ ivas_error ivas_corecoder_enc_reconfig_fx( /* save input audio buffers */ IF( GT_16( n_CoreCoder_existing, sce_id ) ) { - Copy32( st_ivas->hSCE[sce_id]->hCoreCoder[0]->input_buff32_fx, input_buff_fx[sce_id], len_inp_memory ); + Copy32( st_ivas->hSCE[sce_id]->hCoreCoder[0]->input_buff32_fx, input_buff_fx[sce_id], len_inp_memory ); /* st_ivas->hSCE[sce_id]->hCoreCoder[0]->q_inp32 */ q_input_buff[sce_id] = st_ivas->hSCE[sce_id]->hCoreCoder[0]->q_inp32; move16(); } - destroy_sce_enc( st_ivas->hSCE[sce_id], ( EQ_16( st_ivas->hEncoderConfig->element_mode_init, EVS_MONO ) && !st_ivas->hEncoderConfig->stereo_dmx_evs ) ); + destroy_sce_enc_fx( st_ivas->hSCE[sce_id], ( EQ_16( st_ivas->hEncoderConfig->element_mode_init, EVS_MONO ) && !st_ivas->hEncoderConfig->stereo_dmx_evs ) ); st_ivas->hSCE[sce_id] = NULL; } @@ -349,7 +348,7 @@ ivas_error ivas_corecoder_enc_reconfig_fx( { IF( n_CoreCoder_existing > cpe_id * CPE_CHANNELS + n ) { - Copy32( st_ivas->hCPE[cpe_id]->hCoreCoder[n]->input_buff32_fx, input_buff_fx[( cpe_id - st_ivas->nCPE ) * CPE_CHANNELS + n], len_inp_memory ); + Copy32( st_ivas->hCPE[cpe_id]->hCoreCoder[n]->input_buff32_fx, input_buff_fx[( cpe_id - st_ivas->nCPE ) * CPE_CHANNELS + n], len_inp_memory ); /* st_ivas->hCPE[cpe_id]->hCoreCoder[n]->q_inp32 */ q_input_buff[( cpe_id - st_ivas->nCPE ) * CPE_CHANNELS + n] = st_ivas->hCPE[cpe_id]->hCoreCoder[n]->q_inp32; move16(); } @@ -360,7 +359,7 @@ ivas_error ivas_corecoder_enc_reconfig_fx( test(); IF( LE_16( st_ivas->nCPE, 1 ) && st_ivas->hMCT != NULL ) { - ivas_mct_enc_close( &( st_ivas->hMCT ) ); + ivas_mct_enc_close_fx( &( st_ivas->hMCT ) ); } /* special case, if we have MCT now and had a single CPE before, remove the MDCT Stereo handles */ @@ -379,17 +378,17 @@ ivas_error ivas_corecoder_enc_reconfig_fx( FOR( sce_id = 0; sce_id < nSCE_existing; sce_id++ ) { copy_encoder_config_fx( st_ivas, st_ivas->hSCE[sce_id]->hCoreCoder[0], 0 ); - st_ivas->hSCE[sce_id]->element_brate = brate_SCE; + st_ivas->hSCE[sce_id]->element_brate = brate_SCE; /* Q0 */ move32(); - st_ivas->hSCE[sce_id]->hCoreCoder[0]->total_brate = st_ivas->hSCE[sce_id]->element_brate; /* dummy initialization for getting right pointers initialization of input buffers in init_coder_ace_plus() */ + st_ivas->hSCE[sce_id]->hCoreCoder[0]->total_brate = st_ivas->hSCE[sce_id]->element_brate; /* dummy initialization for getting right pointers initialization of input buffers in init_coder_ace_plus() Q0*/ move32(); - ivas_destroy_MD_bstr_enc( &( st_ivas->hSCE[sce_id]->hMetaData ) ); + ivas_destroy_MD_bstr_enc_fx( &( st_ivas->hSCE[sce_id]->hMetaData ) ); } FOR( sce_id = nSCE_existing; sce_id < st_ivas->nSCE; sce_id++ ) { - IF( NE_32( ( error = create_sce_enc_fx( st_ivas, sce_id, brate_SCE ) ), IVAS_ERR_OK ) ) + IF( ( error = create_sce_enc_fx( st_ivas, sce_id, brate_SCE ) ) != IVAS_ERR_OK ) { return error; } @@ -398,7 +397,7 @@ ivas_error ivas_corecoder_enc_reconfig_fx( test(); IF( GT_16( n_CoreCoder_existing, sce_id ) && NE_16( hEncoderConfig->ivas_format, MASA_ISM_FORMAT ) ) { - Copy32( input_buff_fx[sce_id], st_ivas->hSCE[sce_id]->hCoreCoder[0]->input_buff32_fx, len_inp_memory ); + Copy32( input_buff_fx[sce_id], st_ivas->hSCE[sce_id]->hCoreCoder[0]->input_buff32_fx, len_inp_memory ); /* q_input_buff[sce_id] */ st_ivas->hSCE[sce_id]->hCoreCoder[0]->q_inp32 = q_input_buff[sce_id]; move16(); } @@ -406,13 +405,13 @@ ivas_error ivas_corecoder_enc_reconfig_fx( /* only reset indices if it is not the first index list, this already contains the IVAS format bits */ IF( sce_id > 0 || EQ_16( hEncoderConfig->ivas_format, MASA_ISM_FORMAT ) ) { - reset_indices_enc( st_ivas->hSCE[sce_id]->hCoreCoder[0]->hBstr, st_ivas->hSCE[sce_id]->hCoreCoder[0]->hBstr->nb_ind_tot ); + reset_indices_enc_fx( st_ivas->hSCE[sce_id]->hCoreCoder[0]->hBstr, st_ivas->hSCE[sce_id]->hCoreCoder[0]->hBstr->nb_ind_tot ); } } IF( st_ivas->hSCE[st_ivas->nSCE - 1]->hMetaData == NULL ) { - IF( NE_32( ( error = ivas_initialize_MD_bstr_enc( &( st_ivas->hSCE[st_ivas->nSCE - 1]->hMetaData ), st_ivas ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = ivas_initialize_MD_bstr_enc_fx( &( st_ivas->hSCE[st_ivas->nSCE - 1]->hMetaData ), st_ivas ) ), IVAS_ERR_OK ) ) { return error; } @@ -425,7 +424,7 @@ ivas_error ivas_corecoder_enc_reconfig_fx( FOR( cpe_id = 0; cpe_id < nCPE_existing; cpe_id++ ) { - st_ivas->hCPE[cpe_id]->element_brate = brate_CPE; + st_ivas->hCPE[cpe_id]->element_brate = brate_CPE; /* Q0 */ move32(); /* allocate buffer of indices */ @@ -434,7 +433,7 @@ ivas_error ivas_corecoder_enc_reconfig_fx( copy_encoder_config_fx( st_ivas, st_ivas->hCPE[cpe_id]->hCoreCoder[n], 0 ); IF( GT_16( st_ivas->nCPE, 1 ) ) { - st_ivas->hCPE[cpe_id]->hCoreCoder[n]->total_brate = st_ivas->hCPE[cpe_id]->element_brate; + st_ivas->hCPE[cpe_id]->hCoreCoder[n]->total_brate = st_ivas->hCPE[cpe_id]->element_brate; /* Q0 */ } ELSE { @@ -450,7 +449,7 @@ ivas_error ivas_corecoder_enc_reconfig_fx( ( EQ_16( st_ivas->mc_mode, MC_MODE_MCMASA ) && st_ivas->nSCE > 0 ) || ( EQ_16( hEncoderConfig->ivas_format, MASA_ISM_FORMAT ) && st_ivas->nSCE > 0 ) ) { - reset_indices_enc( st_ivas->hCPE[cpe_id]->hCoreCoder[n]->hBstr, st_ivas->hCPE[cpe_id]->hCoreCoder[n]->hBstr->nb_ind_tot ); + reset_indices_enc_fx( st_ivas->hCPE[cpe_id]->hCoreCoder[n]->hBstr, st_ivas->hCPE[cpe_id]->hCoreCoder[n]->hBstr->nb_ind_tot ); } } } @@ -458,13 +457,13 @@ ivas_error ivas_corecoder_enc_reconfig_fx( FOR( cpe_id = nCPE_existing; cpe_id < st_ivas->nCPE; cpe_id++ ) { test(); - IF( EQ_16( st_ivas->mc_mode, MC_MODE_MCMASA ) && st_ivas->hMcMasa->separateChannelEnabled ) + if ( EQ_16( st_ivas->mc_mode, MC_MODE_MCMASA ) && st_ivas->hMcMasa->separateChannelEnabled ) { st_ivas->hEncoderConfig->element_mode_init = IVAS_CPE_MDCT; move16(); } - IF( NE_32( ( error = create_cpe_enc_fx( st_ivas, cpe_id, brate_CPE ) ), IVAS_ERR_OK ) ) + IF( ( error = create_cpe_enc_fx( st_ivas, cpe_id, brate_CPE ) ) != IVAS_ERR_OK ) { return error; } @@ -475,7 +474,7 @@ ivas_error ivas_corecoder_enc_reconfig_fx( IF( GT_16( n_CoreCoder_existing, add( i_mult( cpe_id, CPE_CHANNELS ), n ) ) ) { - Copy32( input_buff_fx[n], st_ivas->hCPE[cpe_id]->hCoreCoder[n]->input_buff32_fx, len_inp_memory ); + Copy32( input_buff_fx[n], st_ivas->hCPE[cpe_id]->hCoreCoder[n]->input_buff32_fx, len_inp_memory ); /* q_input_buff */ st_ivas->hCPE[cpe_id]->hCoreCoder[n]->q_inp32 = q_input_buff[n]; move16(); } @@ -488,7 +487,7 @@ ivas_error ivas_corecoder_enc_reconfig_fx( test(); IF( add( i_mult( cpe_id, CPE_CHANNELS ), n ) > 0 || ( EQ_16( st_ivas->mc_mode, MC_MODE_MCMASA ) && st_ivas->nSCE > 0 ) ) { - reset_indices_enc( st_ivas->hCPE[cpe_id]->hCoreCoder[n]->hBstr, st_ivas->hCPE[cpe_id]->hCoreCoder[n]->hBstr->nb_ind_tot ); + reset_indices_enc_fx( st_ivas->hCPE[cpe_id]->hCoreCoder[n]->hBstr, st_ivas->hCPE[cpe_id]->hCoreCoder[n]->hBstr->nb_ind_tot ); } IF( hEncoderConfig->Opt_DTX_ON ) @@ -512,21 +511,21 @@ ivas_error ivas_corecoder_enc_reconfig_fx( { IF( temp_ind_list[i].nb_bits > 0 ) { - st_ivas->hSCE[0]->hCoreCoder[0]->hBstr->ind_list[i].id = temp_ind_list[i].id; + st_ivas->hSCE[0]->hCoreCoder[0]->hBstr->ind_list[i].id = temp_ind_list[i].id; /* Q0 */ move16(); - st_ivas->hSCE[0]->hCoreCoder[0]->hBstr->ind_list[i].value = temp_ind_list[i].value; + st_ivas->hSCE[0]->hCoreCoder[0]->hBstr->ind_list[i].value = temp_ind_list[i].value; /* Q0 */ move16(); - st_ivas->hSCE[0]->hCoreCoder[0]->hBstr->ind_list[i].nb_bits = temp_ind_list[i].nb_bits; + st_ivas->hSCE[0]->hCoreCoder[0]->hBstr->ind_list[i].nb_bits = temp_ind_list[i].nb_bits; /* Q0 */ move16(); } - nb_bits = add( nb_bits, temp_ind_list[i].nb_bits ); + nb_bits = add( nb_bits, temp_ind_list[i].nb_bits ); /* Q0 */ i = add( i, 1 ); test(); } - st_ivas->hSCE[0]->hCoreCoder[0]->hBstr->nb_ind_tot = i; + st_ivas->hSCE[0]->hCoreCoder[0]->hBstr->nb_ind_tot = i; /* Q0 */ move16(); - st_ivas->hSCE[0]->hCoreCoder[0]->hBstr->nb_bits_tot = nb_bits_tot; + st_ivas->hSCE[0]->hCoreCoder[0]->hBstr->nb_bits_tot = nb_bits_tot; /* Q0 */ move16(); } ELSE IF( st_ivas->nCPE > 0 ) @@ -536,21 +535,21 @@ ivas_error ivas_corecoder_enc_reconfig_fx( { IF( temp_ind_list[i].nb_bits > 0 ) { - st_ivas->hCPE[0]->hCoreCoder[0]->hBstr->ind_list[i].id = temp_ind_list[i].id; + st_ivas->hCPE[0]->hCoreCoder[0]->hBstr->ind_list[i].id = temp_ind_list[i].id; /* Q0 */ move16(); - st_ivas->hCPE[0]->hCoreCoder[0]->hBstr->ind_list[i].value = temp_ind_list[i].value; + st_ivas->hCPE[0]->hCoreCoder[0]->hBstr->ind_list[i].value = temp_ind_list[i].value; /* Q0 */ move16(); - st_ivas->hCPE[0]->hCoreCoder[0]->hBstr->ind_list[i].nb_bits = temp_ind_list[i].nb_bits; + st_ivas->hCPE[0]->hCoreCoder[0]->hBstr->ind_list[i].nb_bits = temp_ind_list[i].nb_bits; /* Q0 */ move16(); } - nb_bits = add( nb_bits, temp_ind_list[i].nb_bits ); + nb_bits = add( nb_bits, temp_ind_list[i].nb_bits ); /* Q0 */ i = add( i, 1 ); test(); } - st_ivas->hCPE[0]->hCoreCoder[0]->hBstr->nb_ind_tot = i; + st_ivas->hCPE[0]->hCoreCoder[0]->hBstr->nb_ind_tot = i; /* Q0 */ move16(); - st_ivas->hCPE[0]->hCoreCoder[0]->hBstr->nb_bits_tot = nb_bits_tot; + st_ivas->hCPE[0]->hCoreCoder[0]->hBstr->nb_bits_tot = nb_bits_tot; /* Q0 */ move16(); } @@ -560,7 +559,7 @@ ivas_error ivas_corecoder_enc_reconfig_fx( /* restore modified transport signal */ IF( st_ivas->nSCE ) { - Copy32( input_buff_fx[0], st_ivas->hSCE[0]->hCoreCoder[0]->input_buff32_fx, len_inp_memory ); + Copy32( input_buff_fx[0], st_ivas->hSCE[0]->hCoreCoder[0]->input_buff32_fx, len_inp_memory ); /* q_input_buff */ st_ivas->hSCE[0]->hCoreCoder[0]->q_inp32 = q_input_buff[0]; move16(); } @@ -569,7 +568,7 @@ ivas_error ivas_corecoder_enc_reconfig_fx( { FOR( n = 0; n < CPE_CHANNELS; n++ ) { - Copy32( input_buff_fx[n + 1], st_ivas->hCPE[0]->hCoreCoder[n]->input_buff32_fx, len_inp_memory ); + Copy32( input_buff_fx[n + 1], st_ivas->hCPE[0]->hCoreCoder[n]->input_buff32_fx, len_inp_memory ); /* q_input_buff */ st_ivas->hCPE[0]->hCoreCoder[n]->q_inp32 = q_input_buff[n + 1]; move16(); } @@ -627,31 +626,31 @@ ivas_error ivas_corecoder_enc_reconfig_fx( /* set correct nominal bitrates and igf config already here, needed for the correct init of the MDCT Stereo handles for MCT */ FOR( n = 0; n < CPE_CHANNELS; n++ ) { - st_ivas->hCPE[0]->hCoreCoder[n]->total_brate = st_ivas->hCPE[0]->element_brate; + st_ivas->hCPE[0]->hCoreCoder[n]->total_brate = st_ivas->hCPE[0]->element_brate; /* Q0 */ move32(); - st_ivas->hCPE[0]->hCoreCoder[n]->bits_frame_nominal = extract_l( Mpy_32_32( st_ivas->hCPE[0]->element_brate, 42949673 ) /* 1/50 in Q31*/ ); + st_ivas->hCPE[0]->hCoreCoder[n]->bits_frame_nominal = extract_l( Mpy_32_32( st_ivas->hCPE[0]->element_brate, 42949673 ) /* 1/50 in Q31*/ ); /* Q0 */ move16(); st_ivas->hCPE[0]->hCoreCoder[n]->igf = getIgfPresent_fx( st_ivas->hCPE[0]->hCoreCoder[n]->element_mode, st_ivas->hCPE[0]->hCoreCoder[n]->bits_frame_nominal * FRAMES_PER_SEC, st_ivas->hCPE[0]->hCoreCoder[n]->bwidth, - st_ivas->hCPE[0]->hCoreCoder[n]->rf_mode ); + st_ivas->hCPE[0]->hCoreCoder[n]->rf_mode ); /* Q0 */ move16(); - IF( NE_32( ( error = IGF_Reconfig( &st_ivas->hCPE[0]->hCoreCoder[n]->hIGFEnc, st_ivas->hCPE[0]->hCoreCoder[n]->igf, 1, st_ivas->hCPE[0]->element_brate, st_ivas->hCPE[0]->hCoreCoder[n]->bwidth, st_ivas->hCPE[0]->hCoreCoder[n]->element_mode, st_ivas->hCPE[0]->hCoreCoder[n]->rf_mode ) ), IVAS_ERR_OK ) ) + IF( ( error = IGF_Reconfig( &st_ivas->hCPE[0]->hCoreCoder[n]->hIGFEnc, st_ivas->hCPE[0]->hCoreCoder[n]->igf, 1, st_ivas->hCPE[0]->element_brate, st_ivas->hCPE[0]->hCoreCoder[n]->bwidth, st_ivas->hCPE[0]->hCoreCoder[n]->element_mode, st_ivas->hCPE[0]->hCoreCoder[n]->rf_mode ) ) != IVAS_ERR_OK ) { return error; } } } - IF( NE_32( ( error = create_mct_enc( st_ivas ) ), IVAS_ERR_OK ) ) + IF( ( error = create_mct_enc_fx( st_ivas ) ) != IVAS_ERR_OK ) { return error; } } ELSE IF( st_ivas->hMCT != NULL && GT_16( st_ivas->nCPE, 1 ) ) { - IF( NE_32( ( error = mct_enc_reconfigure_fx( st_ivas, st_ivas->nchan_transport != nchan_transport_old ) ), IVAS_ERR_OK ) ) + IF( ( error = mct_enc_reconfigure_fx( st_ivas, st_ivas->nchan_transport != nchan_transport_old ) ) != IVAS_ERR_OK ) { return error; } @@ -662,17 +661,17 @@ ivas_error ivas_corecoder_enc_reconfig_fx( { IF( st_ivas->hCPE[st_ivas->nCPE - 1]->hMetaData == NULL ) { - IF( NE_32( ( error = ivas_initialize_MD_bstr_enc( &( st_ivas->hCPE[st_ivas->nCPE - 1]->hMetaData ), st_ivas ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = ivas_initialize_MD_bstr_enc_fx( &( st_ivas->hCPE[st_ivas->nCPE - 1]->hMetaData ), st_ivas ) ), IVAS_ERR_OK ) ) { return error; } } - reset_indices_enc( st_ivas->hCPE[st_ivas->nCPE - 1]->hMetaData, st_ivas->hCPE[st_ivas->nCPE - 1]->hMetaData->nb_ind_tot ); + reset_indices_enc_fx( st_ivas->hCPE[st_ivas->nCPE - 1]->hMetaData, st_ivas->hCPE[st_ivas->nCPE - 1]->hMetaData->nb_ind_tot ); FOR( cpe_id = 0; cpe_id < st_ivas->nCPE - 1; cpe_id++ ) { - ivas_destroy_MD_bstr_enc( &( st_ivas->hCPE[cpe_id]->hMetaData ) ); + ivas_destroy_MD_bstr_enc_fx( &( st_ivas->hCPE[cpe_id]->hMetaData ) ); } } @@ -688,7 +687,7 @@ ivas_error ivas_corecoder_enc_reconfig_fx( /* set correct nominal bitrates and igf config already here, needed for the correct init of the MDCT Stereo handle */ FOR( n = 0; n < CPE_CHANNELS; n++ ) { - st_ivas->hCPE[0]->hCoreCoder[n]->total_brate = st_ivas->hCPE[0]->element_brate; + st_ivas->hCPE[0]->hCoreCoder[n]->total_brate = st_ivas->hCPE[0]->element_brate; /* Q0 */ move32(); st_ivas->hCPE[0]->hCoreCoder[n]->bits_frame_nominal = extract_l( Mpy_32_32( st_ivas->hCPE[0]->element_brate, 42949673 ) ) /* 1/50 in Q31*/; // ( st_ivas->hCPE[0]->element_brate / FRAMES_PER_SEC ); move16(); @@ -696,11 +695,11 @@ ivas_error ivas_corecoder_enc_reconfig_fx( st_ivas->hCPE[0]->hCoreCoder[n]->igf = getIgfPresent_fx( st_ivas->hCPE[0]->hCoreCoder[n]->element_mode, L_mult0( st_ivas->hCPE[0]->hCoreCoder[n]->bits_frame_nominal, FRAMES_PER_SEC ), st_ivas->hCPE[0]->hCoreCoder[n]->bwidth, - st_ivas->hCPE[0]->hCoreCoder[n]->rf_mode ); + st_ivas->hCPE[0]->hCoreCoder[n]->rf_mode ); /* Q0 */ move16(); - IF( NE_32( ( error = IGF_Reconfig( &st_ivas->hCPE[0]->hCoreCoder[n]->hIGFEnc, st_ivas->hCPE[0]->hCoreCoder[n]->igf, 1, st_ivas->hCPE[0]->element_brate, st_ivas->hCPE[0]->hCoreCoder[n]->bwidth, st_ivas->hCPE[0]->hCoreCoder[n]->element_mode, st_ivas->hCPE[0]->hCoreCoder[n]->rf_mode ) ), IVAS_ERR_OK ) ) + IF( ( error = IGF_Reconfig( &st_ivas->hCPE[0]->hCoreCoder[n]->hIGFEnc, st_ivas->hCPE[0]->hCoreCoder[n]->igf, 1, st_ivas->hCPE[0]->element_brate, st_ivas->hCPE[0]->hCoreCoder[n]->bwidth, st_ivas->hCPE[0]->hCoreCoder[n]->element_mode, st_ivas->hCPE[0]->hCoreCoder[n]->rf_mode ) ) != IVAS_ERR_OK ) { return error; } diff --git a/lib_enc/ivas_cpe_enc.c b/lib_enc/ivas_cpe_enc_fx.c similarity index 67% rename from lib_enc/ivas_cpe_enc.c rename to lib_enc/ivas_cpe_enc_fx.c index 630fcf38e43fc41e1fa549834005d23d0247153d..1152736f6ca121133fbe8e86f0584f9a015cba23 100644 --- a/lib_enc/ivas_cpe_enc.c +++ b/lib_enc/ivas_cpe_enc_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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,8 +36,7 @@ #include "cnst.h" #include "ivas_cnst.h" #include "rom_com.h" -#include "prot.h" -#include "ivas_prot.h" +#include "prot_fx.h" #include "prot_fx_enc.h" #include "ivas_rom_com.h" #ifdef DEBUGGING @@ -45,7 +44,6 @@ #endif #include "wmc_auto.h" #include "ivas_prot_fx.h" -#include "prot_fx.h" #include "ivas_rom_enc.h" #include "prot_fx_enc.h" @@ -61,26 +59,30 @@ static void stereo_mode_combined_format_enc_fx( const Encoder_Struct *st_ivas, C * Channel Pair Element (CPE) encoding routine *-------------------------------------------------------------------*/ ivas_error ivas_cpe_enc_fx( - Encoder_Struct *st_ivas, /* i/o: IVAS encoder structure */ - const Word16 cpe_id, /* i : CPE # identifier */ - Word32 data_fx_ch0[], /* i : input signal for channel 0 Q(q_data_fx) */ - Word32 data_fx_ch1[], /* i : input signal for channel 1 Q(q_data_fx) */ - Word16 q_data_fx, /* i : Q-factor of input signal for both channels */ - const Word16 input_frame, /* i : input frame length per channel */ - const Word16 nb_bits_metadata, /* i : number of metadata bits */ + Encoder_Struct *st_ivas, /* i/o: IVAS encoder structure */ + const Word16 cpe_id, /* i : CPE # identifier Q0*/ + Word32 data_fx_ch0[], /* i : input signal for channel 0 Q(q_data_fx)*/ + Word32 data_fx_ch1[], /* i : input signal for channel 1 Q(q_data_fx)*/ + Word16 q_data_fx, /* i : Q-factor of input signal for both channels */ + const Word16 input_frame, /* i : input frame length per channel Q0*/ + const Word16 nb_bits_metadata, /* i : number of metadata bits Q0*/ Word16 Q_new_out[] ) { CPE_ENC_HANDLE hCPE; Encoder_State **sts; Word16 n, n_CoreChannels; - Word32 old_inp_12k8_fx[CPE_CHANNELS][L_INP_12k8]; /* buffer of input signal @ 12k8 Q16 */ + Word32 old_inp_12k8_fx[CPE_CHANNELS][L_INP_12k8]; /* buffer of input signal @ 12k8 Q15 */ Word16 old_inp_12k8_16fx[CPE_CHANNELS][L_INP_12k8]; /* buffer of input signal @ 12k8 Q_new-1 */ - Word32 old_inp_16k_fx[CPE_CHANNELS][L_INP]; /* buffer of input signal @ 16kHz Q16 */ + Word32 old_inp_16k_fx[CPE_CHANNELS][L_INP]; /* buffer of input signal @ 16kHz Q15 */ Word16 old_inp_16k_16fx[CPE_CHANNELS][L_INP]; /* buffer of input signal @ 16kHz Q_new-1 */ Word16 Q_new[CPE_CHANNELS] = { 0 }; Word16 fft_buff_fx[CPE_CHANNELS][2 * L_FFT]; /* FFT buffer */ Word16 fft_buff_fx_q[CPE_CHANNELS]; /* FFT buffer */ +#ifdef MSAN_FIX + set16_fx( fft_buff_fx_q, 0, CPE_CHANNELS ); +#endif Word16 fft_buff_fx_final_q = MAX_16; + move16(); Word32 ener_fx[CPE_CHANNELS]; /* residual energy from Levinson-Durbin Q6 */ Word16 relE_fx[CPE_CHANNELS]; /* frame relative energy Q8 */ Word16 A_fx[CPE_CHANNELS][NB_SUBFR16k * ( M + 1 )] = { 0 }; /* A(z) unquantized for subframes Q12 */ @@ -113,6 +115,7 @@ ivas_error ivas_cpe_enc_fx( Word32 band_energies_LR_fx[2 * NB_BANDS]; /* energy in critical bands without minimum noise floor E_MIN (Q_buffer + QSCALE - band_ener_guardbits) */ Word16 Q_buffer[2]; Word16 orig_input_fx[CPE_CHANNELS][L_FRAME48k]; + Word16 Q_orig_inp[CPE_CHANNELS]; Word16 Etot_last_fx[CPE_CHANNELS]; Word32 tmp, input_Fs; Word16 max_bwidth, ivas_format; @@ -180,6 +183,7 @@ ivas_error ivas_cpe_enc_fx( set16_zero_fx( old_inp_16k_16fx[i], L_INP ); set_zero_fx( old_inp_16k_fx[i], L_INP ); set16_zero_fx( old_inp_12k8_16fx[i], L_INP_12k8 ); + set_zero_fx( old_inp_12k8_fx[i], L_INP_12k8 ); } #endif /*------------------------------------------------------------------* @@ -188,32 +192,58 @@ ivas_error ivas_cpe_enc_fx( FOR( n = 0; n < CPE_CHANNELS; n++ ) { - sts[n]->idchan = n; - sts[n]->core = -1; - sts[n]->core_brate = -1; /* updated in dtx() */ - sts[n]->max_bwidth = max_bwidth; + sts[n]->idchan = n; /* Q0 */ + sts[n]->core = -1; /* Q0 */ + sts[n]->core_brate = -1; /* updated in dtx() Q0*/ + sts[n]->max_bwidth = max_bwidth; /* Q0 */ + move32(); + move16(); + move16(); + move16(); + IF( st_ivas->hMCT == NULL ) /*already updated before CPE call*/ { - sts[n]->input_bwidth = sts[n]->last_input_bwidth; /* updated in BWD */ - sts[n]->bwidth = sts[n]->last_bwidth; /* updated in BWD */ + sts[n]->input_bwidth = sts[n]->last_input_bwidth; /* updated in BWD Q0*/ + sts[n]->bwidth = sts[n]->last_bwidth; /* updated in BWD Q0*/ + move16(); + move16(); } sts[n]->rate_switching_reset = 0; + move16(); #ifdef DEBUGGING sts[n]->force = hEncoderConfig->force; sts[n]->id_element = cpe_id + st_ivas->nSCE; +#ifdef DEBUG_FORCE_DIR + sts[n]->force_dir = hEncoderConfig->force_dir; +#endif #endif } - Copy32( data_fx_ch0, sts[0]->input32_fx, input_frame ); // Q(q_data_fx) - Copy_Scale_sig32_16( sts[0]->input32_fx, sts[0]->input_fx, input_frame, sub( Q16, q_data_fx ) ); // Q(q_data_fx) -> Q0 - sts[0]->q_inp = 0; + Copy32( data_fx_ch0, sts[0]->input32_fx, input_frame ); // Q(q_data_fx) + sts[0]->q_inp32 = q_data_fx; + move16(); + Word16 norm = L_norm_arr( sts[0]->input32_fx, input_frame ); + scale_sig32( sts[0]->input32_fx, input_frame, norm ); + sts[0]->q_inp32 = add( sts[0]->q_inp32, norm ); + move16(); + + Copy_Scale_sig32_16( sts[0]->input32_fx, sts[0]->input_fx, input_frame, 0 ); + sts[0]->q_inp = sub( sts[0]->q_inp32, Q16 ); move16(); IF( data_fx_ch1 != NULL ) /*this may happen for cases with odd number of channels*/ { - Copy32( data_fx_ch1, sts[1]->input32_fx, input_frame ); // Q(q_data_fx) - Copy_Scale_sig32_16( sts[1]->input32_fx, sts[1]->input_fx, input_frame, sub( Q16, q_data_fx ) ); // Q(q_data_fx) -> Q0 - sts[1]->q_inp = 0; + Copy32( data_fx_ch1, sts[1]->input32_fx, input_frame ); // Q(q_data_fx) + sts[1]->q_inp32 = q_data_fx; + move16(); + + norm = L_norm_arr( sts[1]->input32_fx, input_frame ); + scale_sig32( sts[1]->input32_fx, input_frame, norm ); + sts[1]->q_inp32 = add( sts[1]->q_inp32, norm ); + move16(); + + Copy_Scale_sig32_16( sts[1]->input32_fx, sts[1]->input_fx, input_frame, 0 ); + sts[1]->q_inp = sub( sts[1]->q_inp32, Q16 ); move16(); } @@ -233,14 +263,27 @@ ivas_error ivas_cpe_enc_fx( test(); IF( sts[0]->ini_frame > 0 && st_ivas->hMCT == NULL ) { - hCPE->element_mode = select_stereo_mode( hCPE, ivas_format ); + hCPE->element_mode = select_stereo_mode_fx( hCPE, ivas_format ); } +#ifdef DEBUG_FORCE_DIR + else + { + if ( hCPE->hCoreCoder[0]->force_dir[0] != '\0' ) + { + dbgread( &hCPE->element_mode, sizeof( int16_t ), 1, fname( hCPE->hCoreCoder[0]->force_dir, "force_element_mode.enf", -1, -1, -1 ) ); + } + else + { + dbgwrite( &hCPE->element_mode, sizeof( int16_t ), 1, 1, "res/force_element_mode.enf" ); + } + } +#endif stereo_mode_combined_format_enc_fx( st_ivas, hCPE ); Word16 Q_inp = 0; move16(); - Word16 band_ener_guardbits = find_guarded_bits_fx( 2 * NB_BANDS ); + Word16 Q_add = 2; move16(); Word16 front_create_flag = 0; @@ -248,64 +291,82 @@ ivas_error ivas_cpe_enc_fx( #ifdef MSAN_FIX set32_fx( band_energies_LR_fx, 0, 2 * NB_BANDS ); #endif -#ifdef IVAS_FLOAT_FIXED_CONVERSIONS - for ( n = 0; n < CPE_CHANNELS; n++ ) + + IF( hCPE->hFrontVad[0] != NULL && NE_16( hCPE->element_mode, IVAS_CPE_MDCT ) ) + { + Word16 scale_inp = Q15; + Q_add = 0; + move16(); + FOR( n = 0; n < CPE_CHANNELS; n++ ) + { + scale_inp = s_min( scale_inp, s_min( sts[n]->q_inp, hCPE->hFrontVad[n]->q_mem_decim ) ); + } + FOR( n = 0; n < CPE_CHANNELS; n++ ) + { + Scale_sig( sts[n]->input_fx, input_frame, sub( scale_inp, sts[n]->q_inp ) ); + Scale_sig( hCPE->hFrontVad[n]->mem_decim_fx, 2 * L_FILT_MAX, sub( scale_inp, hCPE->hFrontVad[n]->q_mem_decim ) ); + sts[n]->q_inp = scale_inp; + move16(); + hCPE->hFrontVad[n]->q_mem_decim = scale_inp; + } + Q_inp = scale_inp; + move16(); + } + + FOR( n = 0; n < CPE_CHANNELS; n++ ) { Q_buffer[n] = 15; move16(); } -#endif test(); IF( hCPE->hFrontVad[0] != NULL && NE_16( hCPE->element_mode, IVAS_CPE_MDCT ) ) { - Word16 Qband = -1; - move16(); - Word16 Q_new_old = add( add( sub( Q_inp, Qband ), Q_add ), QSCALE ); - FOR( n = 0; n < CPE_CHANNELS; n++ ) { Q_buffer[n] = hCPE->hFrontVad[n]->q_buffer_12k8; move16(); - Scale_sig32( hCPE->hFrontVad[n]->hNoiseEst->bckr_fx, 20, sub( Q_new_old, hCPE->hFrontVad[n]->hNoiseEst->q_bckr ) ); - hCPE->hFrontVad[n]->hNoiseEst->q_bckr = Q_new_old; - move16(); - Scale_sig32( hCPE->hFrontVad[n]->hNoiseEst->enrO_fx, 20, sub( Q_new_old, hCPE->hFrontVad[n]->hNoiseEst->q_enrO ) ); - hCPE->hFrontVad[n]->hNoiseEst->q_enrO = Q_new_old; - move16(); } } - - IF( NE_32( ( error = front_vad_fx( hCPE, NULL, hEncoderConfig, &hCPE->hFrontVad[0], st_ivas->hMCT != NULL, input_frame, vad_flag_dtx, fr_bands_fx, Etot_LR_fx, lf_E_fx, localVAD_HE_SAD, vad_hover_flag, band_energies_LR_fx, NULL, NULL, Q_inp, Q_buffer, Q_add, &front_create_flag ) ), IVAS_ERR_OK ) ) + Word16 q_band_energies_LR; + Word16 q_fr_bands[2], q_lf_E[2]; + IF( NE_32( ( error = front_vad_fx( hCPE, NULL, hEncoderConfig, &hCPE->hFrontVad[0], st_ivas->hMCT != NULL, input_frame, vad_flag_dtx, + fr_bands_fx, q_fr_bands, Etot_LR_fx, lf_E_fx, q_lf_E, localVAD_HE_SAD, vad_hover_flag, band_energies_LR_fx, + &q_band_energies_LR, NULL, NULL, NULL, Q_inp, Q_buffer, Q_add, &front_create_flag ) ), + IVAS_ERR_OK ) ) { return error; } -#ifdef IVAS_FLOAT_FIXED_CONVERSIONS - if ( hCPE->hFrontVad[0] != NULL && hCPE->element_mode != IVAS_CPE_MDCT ) + IF( hCPE->hFrontVad[0] != NULL && NE_16( hCPE->element_mode, IVAS_CPE_MDCT ) ) { - for ( n = 0; n < CPE_CHANNELS; n++ ) + FOR( n = 0; n < CPE_CHANNELS; n++ ) { // Scale_sig( hCPE->hFrontVad[n]->buffer_12k8_fx + 384, 3 * L_FRAME / 2 - 384, sub( Q_buffer[n], hCPE->hFrontVad[n]->q_buffer_12k8 ) ); hCPE->hFrontVad[n]->q_buffer_12k8 = Q_buffer[n]; + move16(); } } -#endif sts[0]->element_mode = hCPE->element_mode; sts[1]->element_mode = hCPE->element_mode; + move16(); + move16(); n_CoreChannels = 2; - if ( hCPE->element_mode == IVAS_CPE_DFT ) + move16(); + IF( EQ_16( hCPE->element_mode, IVAS_CPE_DFT ) ) { n_CoreChannels = 1; /* in DFT stereo, only M channel is coded */ + move16(); sts[1]->vad_flag = 0; + move16(); } /*----------------------------------------------------------------* * dynamically allocate data structures depending on the actual stereo mode *----------------------------------------------------------------*/ - IF( NE_32( ( error = stereo_memory_enc_fx( hCPE, input_Fs, max_bwidth, ivas_format, st_ivas->nchan_transport ) ), IVAS_ERR_OK ) ) + IF( ( error = stereo_memory_enc_fx( hCPE, input_Fs, max_bwidth, ivas_format, st_ivas->nchan_transport ) ) != IVAS_ERR_OK ) { return error; } @@ -314,28 +375,31 @@ ivas_error ivas_cpe_enc_fx( /*----------------------------------------------------------------* * Set TD stereo parameters *----------------------------------------------------------------*/ - - Copy_Scale_sig_16_32( sts[1]->input_fx, sts[1]->input32_fx, input_frame, sub( Q11, sts[1]->q_inp ) ); - Copy_Scale_sig_16_32( sts[0]->input_fx, sts[0]->input32_fx, input_frame, sub( Q11, sts[0]->q_inp ) ); - +#ifdef FIX_ISSUE_1237 + Copy_Scale_sig_16_32_no_sat( sts[1]->input_fx, sts[1]->input32_fx, input_frame, sub( Q11, sts[1]->q_inp ) ); /* Q11 */ + Copy_Scale_sig_16_32_no_sat( sts[0]->input_fx, sts[0]->input32_fx, input_frame, sub( Q11, sts[0]->q_inp ) ); /* Q11 */ +#else + Copy_Scale_sig_16_32_DEPREC( sts[1]->input_fx, sts[1]->input32_fx, input_frame, sub( Q11, sts[1]->q_inp ) ); /* Q11 */ + Copy_Scale_sig_16_32_DEPREC( sts[0]->input_fx, sts[0]->input32_fx, input_frame, sub( Q11, sts[0]->q_inp ) ); /* Q11 */ +#endif Word16 shift = getScaleFactor32( sts[1]->input32_fx, input_frame ); - scale_sig32( sts[1]->input32_fx, input_frame, shift ); + scale_sig32( sts[1]->input32_fx, input_frame, shift ); /* Q11 + shift */ sts[1]->q_inp32 = add( Q11, shift ); move16(); shift = getScaleFactor32( sts[0]->input32_fx, input_frame ); - scale_sig32( sts[0]->input32_fx, input_frame, shift ); + scale_sig32( sts[0]->input32_fx, input_frame, shift ); /* Q11 + shift */ sts[0]->q_inp32 = add( Q11, shift ); move16(); Q_inp = s_min( Q_inp, s_min( sts[0]->q_inp32, sts[1]->q_inp32 ) ); - scale_sig32( sts[0]->input32_fx, input_frame, sub( Q_inp, sts[0]->q_inp32 ) ); - scale_sig32( sts[1]->input32_fx, input_frame, sub( Q_inp, sts[1]->q_inp32 ) ); + scale_sig32( sts[0]->input32_fx, input_frame, sub( Q_inp, sts[0]->q_inp32 ) ); /* Q_inp */ + scale_sig32( sts[1]->input32_fx, input_frame, sub( Q_inp, sts[1]->q_inp32 ) ); /* Q_inp */ sts[1]->q_inp32 = sts[0]->q_inp32 = Q_inp; move16(); move16(); - IF( NE_32( ( error = stereo_set_tdm_fx( hCPE, input_frame, Q_inp ) ), IVAS_ERR_OK ) ) + IF( ( error = stereo_set_tdm_fx( hCPE, input_frame, Q_inp ) ) != IVAS_ERR_OK ) { return error; } @@ -344,57 +408,83 @@ ivas_error ivas_cpe_enc_fx( /*----------------------------------------------------------------* * Resets/updates in case of stereo switching *----------------------------------------------------------------*/ +#ifdef FIX_ISSUE_1247 + shift = norm_arr( sts[1]->old_input_signal_fx, input_frame ); + Scale_sig( sts[1]->old_input_signal_fx, input_frame, shift ); /* sts[1]->q_old_inp + shift */ + sts[1]->q_old_inp = add( sts[1]->q_old_inp, shift ); + move16(); + shift = norm_arr( sts[1]->input_fx, input_frame ); + Scale_sig( sts[1]->input_fx, input_frame, shift ); /* sts[1]->q_inp + shift */ + sts[1]->q_inp = add( sts[1]->q_inp, shift ); + move16(); + + shift = norm_arr( sts[0]->old_input_signal_fx, input_frame ); + Scale_sig( sts[0]->old_input_signal_fx, input_frame, shift ); /* sts[1]->q_old_inp + shift */ + sts[0]->q_old_inp = add( sts[0]->q_old_inp, shift ); + move16(); + shift = norm_arr( sts[0]->input_fx, input_frame ); + Scale_sig( sts[0]->input_fx, input_frame, shift ); /* sts[1]->q_inp, shift */ + sts[0]->q_inp = add( sts[0]->q_inp, shift ); + move16(); +#else shift = getScaleFactor16( sts[1]->old_input_signal_fx, input_frame ); - Scale_sig( sts[1]->old_input_signal_fx, input_frame, shift ); + Scale_sig( sts[1]->old_input_signal_fx, input_frame, shift ); /* sts[1]->q_old_inp + shift */ sts[1]->q_old_inp = add( sts[1]->q_old_inp, shift ); move16(); shift = getScaleFactor16( sts[1]->input_fx, input_frame ); - Scale_sig( sts[1]->input_fx, input_frame, shift ); + Scale_sig( sts[1]->input_fx, input_frame, shift ); /* sts[1]->q_inp + shift */ sts[1]->q_inp = add( sts[1]->q_inp, shift ); move16(); shift = getScaleFactor16( sts[0]->old_input_signal_fx, input_frame ); - Scale_sig( sts[0]->old_input_signal_fx, input_frame, shift ); + Scale_sig( sts[0]->old_input_signal_fx, input_frame, shift ); /* sts[1]->q_old_inp + shift */ sts[0]->q_old_inp = add( sts[0]->q_old_inp, shift ); move16(); shift = getScaleFactor16( sts[0]->input_fx, input_frame ); - Scale_sig( sts[0]->input_fx, input_frame, shift ); + Scale_sig( sts[0]->input_fx, input_frame, shift ); /* sts[1]->q_inp, shift */ sts[0]->q_inp = add( sts[0]->q_inp, shift ); move16(); +#endif Word16 q_inp = s_min( s_min( sts[0]->q_inp, sts[0]->q_old_inp ), s_min( sts[1]->q_inp, sts[1]->q_old_inp ) ); - Scale_sig( sts[1]->input_fx, input_frame, sub( q_inp, sts[1]->q_inp ) ); - Scale_sig( sts[1]->old_input_signal_fx, input_frame, sub( q_inp, sts[1]->q_old_inp ) ); + Scale_sig( sts[1]->input_fx, input_frame, sub( q_inp, sts[1]->q_inp ) ); /* q_inp */ + Scale_sig( sts[1]->old_input_signal_fx, input_frame, sub( q_inp, sts[1]->q_old_inp ) ); /* q_inp */ sts[1]->q_inp = q_inp; sts[1]->q_old_inp = q_inp; - Scale_sig( sts[0]->input_fx, input_frame, sub( q_inp, sts[0]->q_inp ) ); - Scale_sig( sts[0]->old_input_signal_fx, input_frame, sub( q_inp, sts[0]->q_old_inp ) ); + move16(); + move16(); + + Scale_sig( sts[0]->input_fx, input_frame, sub( q_inp, sts[0]->q_inp ) ); /* q_inp */ + Scale_sig( sts[0]->old_input_signal_fx, input_frame, sub( q_inp, sts[0]->q_old_inp ) ); /* q_inp */ sts[0]->q_inp = q_inp; move16(); sts[0]->q_old_inp = q_inp; move16(); - Scale_sig( sts[0]->buf_speech_enc, L_PAST_MAX_32k + L_FRAME32k + L_NEXT_MAX_32k, sub( q_inp, sub( Q15, sts[0]->exp_buf_speech_enc ) ) ); - + Scale_sig( sts[0]->buf_speech_enc, L_PAST_MAX_32k + L_FRAME32k + L_NEXT_MAX_32k, sub( q_inp, sub( Q15, sts[0]->exp_buf_speech_enc ) ) ); // q_inp + sts[0]->exp_buf_speech_enc = sub( Q15, q_inp ); + move16(); stereo_switching_enc_fx( hCPE, sts[0]->old_input_signal_fx, input_frame, q_inp ); /*----------------------------------------------------------------* * Temporal inter-channel alignment, stereo adjustment *----------------------------------------------------------------*/ - Copy_Scale_sig_16_32( sts[0]->input_buff_fx, sts[0]->input_buff32_fx, L_FRAME48k + L_FRAME48k + NS2SA( 48000, DELAY_FIR_RESAMPL_NS ), Q6 ); + Copy_Scale_sig_16_32_DEPREC( sts[0]->input_buff_fx, sts[0]->input_buff32_fx, L_FRAME48k + L_FRAME48k + NS2SA( 48000, DELAY_FIR_RESAMPL_NS ), Q6 ); /* Q6 + sts[0]->q_inp */ sts[0]->q_inp32 = add( Q6, sts[0]->q_inp ); move16(); - Copy_Scale_sig_16_32( sts[1]->input_buff_fx, sts[1]->input_buff32_fx, L_FRAME48k + L_FRAME48k + NS2SA( 48000, DELAY_FIR_RESAMPL_NS ), Q6 ); + Copy_Scale_sig_16_32_DEPREC( sts[1]->input_buff_fx, sts[1]->input_buff32_fx, L_FRAME48k + L_FRAME48k + NS2SA( 48000, DELAY_FIR_RESAMPL_NS ), Q6 ); /* Q6 + sts[0]->q_inp */ sts[1]->q_inp32 = add( Q6, sts[1]->q_inp ); move16(); stereo_tca_enc_fx( hCPE, input_frame ); - Copy_Scale_sig32_16( sts[0]->input_buff32_fx, sts[0]->input_buff_fx, L_FRAME48k + L_FRAME48k + NS2SA( 48000, DELAY_FIR_RESAMPL_NS ), sub( add( Q16, 0 ), sts[0]->q_inp32 ) ); - Copy_Scale_sig32_16( sts[1]->input_buff32_fx, sts[1]->input_buff_fx, L_FRAME48k + L_FRAME48k + NS2SA( 48000, DELAY_FIR_RESAMPL_NS ), sub( add( Q16, 0 ), sts[1]->q_inp32 ) ); + shift = s_min( 0, sub( add( L_norm_arr( sts[0]->input_buff32_fx, L_FRAME48k + L_FRAME48k + NS2SA( 48000, DELAY_FIR_RESAMPL_NS ) ), sts[0]->q_inp32 ), 16 ) ); + shift = s_min( shift, sub( add( L_norm_arr( sts[1]->input_buff32_fx, L_FRAME48k + L_FRAME48k + NS2SA( 48000, DELAY_FIR_RESAMPL_NS ) ), sts[1]->q_inp32 ), 16 ) ); + Copy_Scale_sig32_16( sts[0]->input_buff32_fx, sts[0]->input_buff_fx, L_FRAME48k + L_FRAME48k + NS2SA( 48000, DELAY_FIR_RESAMPL_NS ), sub( add( Q16, shift ), sts[0]->q_inp32 ) ); // shift + Copy_Scale_sig32_16( sts[1]->input_buff32_fx, sts[1]->input_buff_fx, L_FRAME48k + L_FRAME48k + NS2SA( 48000, DELAY_FIR_RESAMPL_NS ), sub( add( Q16, shift ), sts[1]->q_inp32 ) ); // shift - sts[0]->q_inp = sts[1]->q_inp = sts[0]->q_old_inp = sts[1]->q_old_inp = 0; + sts[0]->q_inp = sts[1]->q_inp = sts[0]->q_old_inp = sts[1]->q_old_inp = shift; move16(); move16(); move16(); @@ -405,14 +495,15 @@ ivas_error ivas_cpe_enc_fx( FOR( n = 0; n < CPE_CHANNELS; n++ ) { - Scale_sig( sts[n]->input_fx, input_frame, sub( -1, sts[n]->q_inp ) ); - sts[n]->q_inp = -1; - Copy( sts[n]->input_fx, orig_input_fx[n], input_frame ); + Copy( sts[n]->input_fx, orig_input_fx[n], input_frame ); /* sts->q_inp */ + Scale_sig( orig_input_fx[n], input_frame, sub( -1, sts[n]->q_inp ) ); // Q(-1) + Q_orig_inp[n] = -1; + move16(); IF( hCPE->hStereoICBWE != NULL ) { - hCPE->hStereoICBWE->dataChan_fx[n] = &orig_input_fx[n][0]; - hCPE->hStereoICBWE->q_dataChan_fx = sts[n]->q_inp; + hCPE->hStereoICBWE->dataChan_fx[n] = &orig_input_fx[n][0]; // Q_orig_inp + hCPE->hStereoICBWE->q_dataChan_fx = Q_orig_inp[n]; move16(); } } @@ -470,23 +561,32 @@ ivas_error ivas_cpe_enc_fx( IF( NE_16( hCPE->element_mode, IVAS_CPE_MDCT ) && ( NE_32( hCPE->element_brate, hCPE->last_element_brate ) || NE_16( hCPE->last_element_mode, hCPE->element_mode ) || sts[0]->ini_frame == 0 || ( NE_32( ivas_total_brate, st_ivas->hEncoderConfig->last_ivas_total_brate ) ) || LE_32( sts[0]->last_core_brate, SID_2k40 ) ) ) /* If the last frame was SID or NO_DATA, we need to run stereo_dft_config here since VAD decision is not known yet */ { + STEREO_DFT_CONFIG_DATA_HANDLE hConfig; + IF( hCPE->hStereoDft == NULL ) + { + hConfig = NULL; + } + ELSE + { + hConfig = hCPE->hStereoDft->hConfig; + } IF( st_ivas->hQMetaData != NULL ) { test(); /* No Basop - st_ivas->ism_mode != ISM_MODE_NONE as comparison with 0 */ IF( EQ_16( ivas_format, MASA_ISM_FORMAT ) && st_ivas->ism_mode != ISM_MODE_NONE ) { - stereo_dft_config_fx( hCPE->hStereoDft == NULL ? NULL : hCPE->hStereoDft->hConfig, L_mult0( st_ivas->hQMetaData->bits_frame_nominal, 35 /* 0.70f * FRAMES_PER_SEC */ ), &sts[0]->bits_frame_nominal, &sts[1]->bits_frame_nominal ); + stereo_dft_config_fx( hConfig, L_mult0( st_ivas->hQMetaData->bits_frame_nominal, 35 /* 0.70f * FRAMES_PER_SEC */ ), &sts[0]->bits_frame_nominal, &sts[1]->bits_frame_nominal ); } ELSE { - stereo_dft_config_fx( hCPE->hStereoDft == NULL ? NULL : hCPE->hStereoDft->hConfig, L_mult0( st_ivas->hQMetaData->bits_frame_nominal, FRAMES_PER_SEC ), &sts[0]->bits_frame_nominal, &sts[1]->bits_frame_nominal ); + stereo_dft_config_fx( hConfig, L_mult0( st_ivas->hQMetaData->bits_frame_nominal, FRAMES_PER_SEC ), &sts[0]->bits_frame_nominal, &sts[1]->bits_frame_nominal ); } } ELSE { /* note; "bits_frame_nominal" needed in TD stereo as well */ - stereo_dft_config_fx( hCPE->hStereoDft == NULL ? NULL : hCPE->hStereoDft->hConfig, hCPE->element_brate, &sts[0]->bits_frame_nominal, &sts[1]->bits_frame_nominal ); + stereo_dft_config_fx( hConfig, hCPE->element_brate, &sts[0]->bits_frame_nominal, &sts[1]->bits_frame_nominal ); } } @@ -494,8 +594,8 @@ ivas_error ivas_cpe_enc_fx( { IF( hCPE->hStereoTD->tdm_LRTD_flag ) { - sts[0]->bits_frame_nominal = (int16_t) ( ( hCPE->element_brate >> 1 ) / FRAMES_PER_SEC ); - sts[1]->bits_frame_nominal = (int16_t) ( ( hCPE->element_brate >> 1 ) / FRAMES_PER_SEC ); + sts[0]->bits_frame_nominal = extract_l( Mult_32_32( L_shr( hCPE->element_brate, 1 ), ONE_BY_FRAMES_PER_SEC_Q31 ) ); /* Q0 */ + sts[1]->bits_frame_nominal = extract_l( Mult_32_32( L_shr( hCPE->element_brate, 1 ), ONE_BY_FRAMES_PER_SEC_Q31 ) ); /* Q0 */ } ELSE { @@ -503,50 +603,75 @@ ivas_error ivas_cpe_enc_fx( } } - if ( hCPE->element_mode == IVAS_CPE_MDCT ) + IF( EQ_16( hCPE->element_mode, IVAS_CPE_MDCT ) ) { /* compute bit-rate surplus per channel in combined format coding */ - int32_t brate_surplus[CPE_CHANNELS]; - if ( st_ivas->ism_mode == ISM_MASA_MODE_MASA_ONE_OBJ || st_ivas->ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ || st_ivas->ism_mode == ISM_MASA_MODE_DISC ) + Word32 brate_surplus[CPE_CHANNELS]; + test(); + test(); + IF( EQ_32( st_ivas->ism_mode, ISM_MASA_MODE_MASA_ONE_OBJ ) || EQ_32( st_ivas->ism_mode, ISM_MASA_MODE_PARAM_ONE_OBJ ) || EQ_32( st_ivas->ism_mode, ISM_MASA_MODE_DISC ) ) { - brate_surplus[0] = ( ( hCPE->brate_surplus / FRAMES_PER_SEC ) >> 1 ) * FRAMES_PER_SEC; - brate_surplus[1] = hCPE->brate_surplus - brate_surplus[0]; + brate_surplus[0] = imult3216( L_shr( Mpy_32_32_r( hCPE->brate_surplus, ONE_BY_FRAMES_PER_SEC_Q31 ), 1 ), FRAMES_PER_SEC ); /* Q0 */ + brate_surplus[1] = L_sub( hCPE->brate_surplus, brate_surplus[0] ); /* Q0 */ + move32(); + move32(); } /* this is just for initialization, the true values of "total_brate" and "bits_frame_channel" are set later */ - for ( n = 0; n < n_CoreChannels; n++ ) + FOR( n = 0; n < n_CoreChannels; n++ ) { - if ( st_ivas->hMCT ) + IF( st_ivas->hMCT ) { - int16_t lfe_bits; - lfe_bits = ( ivas_format == MC_FORMAT && st_ivas->mc_mode == MC_MODE_MCT ? st_ivas->hLFE->lfe_bits : 0 ); - sts[n]->total_brate = hCPE->element_brate; - sts[n]->bits_frame_nominal = (int16_t) ( hCPE->element_brate / FRAMES_PER_SEC ); - sts[n]->bits_frame_channel = (int16_t) ( ( ivas_total_brate / FRAMES_PER_SEC - lfe_bits - nb_bits_metadata ) / st_ivas->hMCT->nchan_out_woLFE ); + Word16 lfe_bits; + test(); + IF( EQ_16( ivas_format, MC_FORMAT ) && EQ_16( st_ivas->mc_mode, MC_MODE_MCT ) ) + { + lfe_bits = st_ivas->hLFE->lfe_bits; + move16(); + } + ELSE + { + lfe_bits = 0; + move16(); + } + sts[n]->total_brate = hCPE->element_brate; /* Q0 */ + sts[n]->bits_frame_nominal = extract_l( Mpy_32_32_r( hCPE->element_brate, ONE_BY_FRAMES_PER_SEC_Q31 ) ); /* Q0 */ + sts[n]->bits_frame_channel = ( idiv1616( sub( sub( extract_l( Mpy_32_32_r( ivas_total_brate, ONE_BY_FRAMES_PER_SEC_Q31 ) ), lfe_bits ), nb_bits_metadata ), st_ivas->hMCT->nchan_out_woLFE ) ); /* Q0 */ + move32(); + move16(); + move16(); } - else + ELSE { - sts[n]->bits_frame_nominal = (int16_t) ( hCPE->element_brate / FRAMES_PER_SEC ); - sts[n]->bits_frame_channel = (int16_t) ( ( hCPE->element_brate / FRAMES_PER_SEC ) / n_CoreChannels ); - sts[n]->total_brate = hCPE->element_brate / n_CoreChannels; + sts[n]->bits_frame_nominal = extract_l( Mpy_32_32_r( hCPE->element_brate, ONE_BY_FRAMES_PER_SEC_Q31 ) ); /* Q0 */ + sts[n]->bits_frame_channel = idiv1616( extract_l( Mpy_32_32_r( hCPE->element_brate, ONE_BY_FRAMES_PER_SEC_Q31 ) ), n_CoreChannels ); /* Q0 */ + sts[n]->total_brate = L_shl( div_l( hCPE->element_brate, n_CoreChannels ), 1 ); /* Q0 */ + move32(); + move16(); + move16(); /* subtract bit-rate for combined format coding */ - if ( st_ivas->ism_mode == ISM_MASA_MODE_MASA_ONE_OBJ || st_ivas->ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ || st_ivas->ism_mode == ISM_MASA_MODE_DISC ) + IF( EQ_32( st_ivas->ism_mode, ISM_MASA_MODE_MASA_ONE_OBJ ) || EQ_32( st_ivas->ism_mode, ISM_MASA_MODE_PARAM_ONE_OBJ ) || EQ_32( st_ivas->ism_mode, ISM_MASA_MODE_DISC ) ) { - sts[n]->bits_frame_channel += (int16_t) ( brate_surplus[n] / FRAMES_PER_SEC ); - sts[n]->total_brate += brate_surplus[n]; + sts[n]->bits_frame_channel = add( sts[n]->bits_frame_channel, extract_l( Mpy_32_32_r( brate_surplus[n], ONE_BY_FRAMES_PER_SEC_Q31 ) ) ); /* Q0 */ + sts[n]->total_brate = L_add( sts[n]->total_brate, brate_surplus[n] ); /* Q0 */ + move32(); + move16(); } } } /* reconfiguration in case of bitrate switching */ - if ( hCPE->element_brate != hCPE->last_element_brate && st_ivas->hMCT == NULL ) + IF( NE_32( hCPE->element_brate, hCPE->last_element_brate ) && st_ivas->hMCT == NULL ) { #ifdef DEBUGGING hCPE->hStereoMdct->mdct_stereo_mode_cmdl = hEncoderConfig->mdct_stereo_mode_cmdl; #endif initMdctStereoEncData_fx( hCPE->hStereoMdct, ivas_format, hCPE->element_mode, hCPE->element_brate, max_bwidth, 0, NULL, 0 ); - hCPE->hStereoMdct->isSBAStereoMode = ( ( ivas_format == SBA_FORMAT || ivas_format == SBA_ISM_FORMAT ) && ( st_ivas->nchan_transport == 2 ) ); + test(); + test(); + hCPE->hStereoMdct->isSBAStereoMode = ( ( EQ_16( ivas_format, SBA_FORMAT ) || EQ_16( ivas_format, SBA_ISM_FORMAT ) ) && ( EQ_16( st_ivas->nchan_transport, 2 ) ) ); /* Q0 */ + move16(); } } @@ -555,54 +680,53 @@ ivas_error ivas_cpe_enc_fx( * Stereo down-mix *----------------------------------------------------------------*/ // printf("\n%f %f ", hCPE->hStereoClassif->is_speech, hCPE->hCoreCoder[0]->hSpMusClas->past_dlp[0]); - if ( hCPE->element_mode == IVAS_CPE_DFT ) + IF( EQ_16( hCPE->element_mode, IVAS_CPE_DFT ) ) { -#ifdef IVAS_FLOAT_FIXED_CONVERSIONS - /* flt2fix: to be removed */ #ifndef MSAN_FIX hCPE->hStereoClassif->xtalk_score_fx = floatToFixed( hCPE->hStereoClassif->xtalk_score, 31 ); #endif // !MSAN_FIX /*flt2fix: dft_synthesize*/ - if ( hCPE->element_mode == IVAS_CPE_DFT && hCPE->hStereoDft->res_cod_mode[STEREO_DFT_OFFSET] ) + test(); + if ( EQ_16( hCPE->element_mode, IVAS_CPE_DFT ) && hCPE->hStereoDft->res_cod_mode[STEREO_DFT_OFFSET] ) { sts[1]->exp_old_inp_12k8 = Q15; move16(); } - /*flt2fix end*/ -#endif Word16 temp = getScaleFactor32( hCPE->hStereoDft->Spd_L_smooth_fx, STEREO_DFT_N_32k_ENC / 2 ); - scale_sig32( hCPE->hStereoDft->Spd_L_smooth_fx, STEREO_DFT_N_32k_ENC / 2, temp ); + scale_sig32( hCPE->hStereoDft->Spd_L_smooth_fx, STEREO_DFT_N_32k_ENC / 2, temp ); /* exp(hCPE->hStereoDft->Spd_L_smooth_fx_e - temp)*/ hCPE->hStereoDft->Spd_L_smooth_fx_e = sub( hCPE->hStereoDft->Spd_L_smooth_fx_e, temp ); + move16(); temp = getScaleFactor32( hCPE->hStereoDft->Spd_R_smooth_fx, STEREO_DFT_N_32k_ENC / 2 ); - scale_sig32( hCPE->hStereoDft->Spd_R_smooth_fx, STEREO_DFT_N_32k_ENC / 2, temp ); + scale_sig32( hCPE->hStereoDft->Spd_R_smooth_fx, STEREO_DFT_N_32k_ENC / 2, temp ); /* exp(hCPE->hStereoDft->Spd_R_smooth_fx_e - temp) */ hCPE->hStereoDft->Spd_R_smooth_fx_e = sub( hCPE->hStereoDft->Spd_R_smooth_fx_e, temp ); + move16(); shift = getScaleFactor16( sts[1]->old_input_signal_fx, input_frame ); - Scale_sig( sts[1]->old_input_signal_fx, input_frame, shift ); + Scale_sig( sts[1]->old_input_signal_fx, input_frame, shift ); /* sts[1]->q_old_inp + shift */ sts[1]->q_old_inp = add( sts[1]->q_old_inp, shift ); move16(); shift = getScaleFactor16( sts[1]->input_fx, input_frame ); - Scale_sig( sts[1]->input_fx, input_frame, shift ); + Scale_sig( sts[1]->input_fx, input_frame, shift ); /* sts[1]->q_inp + shift */ sts[1]->q_inp = add( sts[1]->q_inp, shift ); move16(); - Scale_sig( sts[1]->input_fx, input_frame, sub( s_min( sts[1]->q_inp, sts[1]->q_old_inp ), sts[1]->q_inp ) ); - Scale_sig( sts[1]->old_input_signal_fx, input_frame, sub( s_min( sts[1]->q_old_inp, sts[1]->q_inp ), sts[1]->q_old_inp ) ); + Scale_sig( sts[1]->input_fx, input_frame, sub( s_min( sts[1]->q_inp, sts[1]->q_old_inp ), sts[1]->q_inp ) ); /* min( sts[1]->q_inp, sts[1]->q_old_inp) */ + Scale_sig( sts[1]->old_input_signal_fx, input_frame, sub( s_min( sts[1]->q_old_inp, sts[1]->q_inp ), sts[1]->q_old_inp ) ); /* min( sts[1]->q_old_inp, sts[1]->q_inp) */ sts[1]->q_inp = s_min( sts[1]->q_inp, sts[1]->q_old_inp ); move16(); sts[1]->q_old_inp = sts[1]->q_inp; move16(); shift = getScaleFactor16( sts[0]->old_input_signal_fx, input_frame ); - Scale_sig( sts[0]->old_input_signal_fx, input_frame, shift ); + Scale_sig( sts[0]->old_input_signal_fx, input_frame, shift ); /* sts[0]->q_old_inp + shift */ sts[0]->q_old_inp = add( sts[0]->q_old_inp, shift ); move16(); shift = getScaleFactor16( sts[0]->input_fx, input_frame ); - Scale_sig( sts[0]->input_fx, input_frame, shift ); + Scale_sig( sts[0]->input_fx, input_frame, shift ); /* sts[0]->q_inp + shift */ sts[0]->q_inp = add( sts[0]->q_inp, shift ); move16(); - Scale_sig( sts[0]->input_fx, input_frame, sub( s_min( sts[0]->q_inp, sts[0]->q_old_inp ), sts[0]->q_inp ) ); - Scale_sig( sts[0]->old_input_signal_fx, input_frame, sub( s_min( sts[0]->q_old_inp, sts[0]->q_inp ), sts[0]->q_old_inp ) ); + Scale_sig( sts[0]->input_fx, input_frame, sub( s_min( sts[0]->q_inp, sts[0]->q_old_inp ), sts[0]->q_inp ) ); /* min( sts[1]->q_inp, sts[1]->q_old_inp) */ + Scale_sig( sts[0]->old_input_signal_fx, input_frame, sub( s_min( sts[0]->q_old_inp, sts[0]->q_inp ), sts[0]->q_old_inp ) ); /* min( sts[1]->q_old_inp, sts[1]->q_inp) */ sts[0]->q_inp = s_min( sts[0]->q_inp, sts[0]->q_old_inp ); move16(); sts[0]->q_old_inp = sts[0]->q_inp; @@ -615,7 +739,7 @@ ivas_error ivas_cpe_enc_fx( stereo_dft_enc_analyze_fx( sts, CPE_CHANNELS, input_frame, hCPE->hStereoDft, NULL, hCPE->hStereoDft->DFT_fx, hCPE->hStereoDft->DFT_fx_e, hCPE->input_mem_fx, hCPE->q_input_mem ); - sts[0]->total_brate = L_mult0( add( sts[0]->bits_frame_nominal, 10 ), FRAMES_PER_SEC ); /* add small overhead; st[0]->total_brate used in coder_type_modif() */ + sts[0]->total_brate = L_mult0( add( sts[0]->bits_frame_nominal, 10 ), FRAMES_PER_SEC ); /* add small overhead; st[0]->total_brate used in coder_type_modif() Q0*/ /* Update DFT Stereo memories */ stereo_dft_enc_update_fx( hCPE->hStereoDft, sts[0]->max_bwidth ); @@ -623,26 +747,26 @@ ivas_error ivas_cpe_enc_fx( /* DFT stereo processing */ stereo_dft_enc_process_fx( hCPE, vad_flag_dtx, vad_hover_flag, input_frame ); } - else if ( EQ_16( hCPE->element_mode, IVAS_CPE_TD ) ) + ELSE IF( EQ_16( hCPE->element_mode, IVAS_CPE_TD ) ) { - Scale_sig( sts[0]->input_fx, input_frame, negate( sts[0]->q_inp ) ); + Scale_sig( sts[0]->input_fx, input_frame, negate( sts[0]->q_inp ) ); /* Q0 */ sts[0]->q_inp = 0; move16(); - Scale_sig( sts[1]->input_fx, input_frame, negate( sts[1]->q_inp ) ); + Scale_sig( sts[1]->input_fx, input_frame, negate( sts[1]->q_inp ) ); /* Q0 */ sts[1]->q_inp = 0; move16(); /* Determine the energy ratio between the 2 channels */ tdm_ratio_idx = stereo_tdm_ener_analysis_fx( ivas_format, - hCPE, input_frame, &tdm_SM_or_LRTD_Pri, &tdm_ratio_idx_SM ); + hCPE, input_frame, &tdm_SM_or_LRTD_Pri, &tdm_ratio_idx_SM ); /* Q0 */ /* Compute the downmix signal based on the ratio index */ Word16 tdm_SM_flag; IF( hCPE->hStereoTD->tdm_LRTD_flag == 0 ) { - tdm_SM_flag = tdm_SM_or_LRTD_Pri; + tdm_SM_flag = tdm_SM_or_LRTD_Pri; /* Q0 */ move16(); } ELSE @@ -654,68 +778,64 @@ ivas_error ivas_cpe_enc_fx( /* signal the bitrate for BW selection in the SCh */ sts[0]->bits_frame_channel = 0; - sts[1]->bits_frame_channel = extract_l( Mpy_32_32( hCPE->element_brate, ONE_BY_FRAMES_PER_SEC_Q31 ) ); - sts[1]->bits_frame_channel = add( sts[1]->bits_frame_channel, extract_l( Mpy_32_32( hCPE->brate_surplus, ONE_BY_FRAMES_PER_SEC_Q31 ) ) ); + sts[1]->bits_frame_channel = extract_l( Mpy_32_32_r( hCPE->element_brate, ONE_BY_FRAMES_PER_SEC_Q31 ) ); /* Q0 */ + sts[1]->bits_frame_channel = add( sts[1]->bits_frame_channel, extract_l( Mpy_32_32_r( hCPE->brate_surplus, ONE_BY_FRAMES_PER_SEC_Q31 ) ) ); /* Q0 */ move16(); move16(); move16(); - IF( st_ivas->hQMetaData != NULL ) + if ( st_ivas->hQMetaData != NULL ) { - sts[1]->bits_frame_channel = sub( sts[1]->bits_frame_channel, st_ivas->hQMetaData->metadata_max_bits ); + sts[1]->bits_frame_channel = sub( sts[1]->bits_frame_channel, st_ivas->hQMetaData->metadata_max_bits ); /* Q0 */ move16(); } - Etot_last_fx[0] = sts[0]->hNoiseEst->Etot_last_fx; - Etot_last_fx[1] = sts[1]->hNoiseEst->Etot_last_fx; + Etot_last_fx[0] = sts[0]->hNoiseEst->Etot_last_fx; /* Q8 */ + Etot_last_fx[1] = sts[1]->hNoiseEst->Etot_last_fx; /* Q8 */ move16(); move16(); } - else if ( hCPE->element_mode == IVAS_CPE_MDCT ) + ELSE IF( EQ_16( hCPE->element_mode, IVAS_CPE_MDCT ) ) { -#ifdef IVAS_FLOAT_FIXED_CONVERSIONS - if ( hCPE->hStereoMdct != NULL && hCPE->hStereoMdct->hItd != NULL ) + test(); + IF( hCPE->hStereoMdct != NULL && hCPE->hStereoMdct->hItd != NULL ) { - if ( hCPE->element_mode == IVAS_CPE_DFT && hCPE->hStereoDft->res_cod_mode[STEREO_DFT_OFFSET] ) + test(); + if ( EQ_16( hCPE->element_mode, IVAS_CPE_DFT ) && hCPE->hStereoDft->res_cod_mode[STEREO_DFT_OFFSET] ) { sts[1]->exp_old_inp_12k8 = Q15; move16(); } } -#endif test(); IF( hCPE->hStereoMdct != NULL && hCPE->hStereoMdct->hItd != NULL ) { - - shift = getScaleFactor16( sts[1]->old_input_signal_fx, input_frame ); - Scale_sig( sts[1]->old_input_signal_fx, input_frame, shift ); - sts[1]->q_old_inp = add( sts[1]->q_old_inp, shift ); - move16(); - shift = getScaleFactor16( sts[1]->input_fx, input_frame ); - Scale_sig( sts[1]->input_fx, input_frame, shift ); - sts[1]->q_inp = add( sts[1]->q_inp, shift ); + Word16 q_min; + q_min = sts[1]->q_old_inp; move16(); - Scale_sig( sts[1]->input_fx, input_frame, sub( s_min( sts[1]->q_inp, sts[1]->q_old_inp ), sts[1]->q_inp ) ); - Scale_sig( sts[1]->old_input_signal_fx, input_frame, sub( s_min( sts[1]->q_old_inp, sts[1]->q_inp ), sts[1]->q_old_inp ) ); - sts[1]->q_inp = s_min( sts[1]->q_inp, sts[1]->q_old_inp ); + q_min = s_min( q_min, sts[1]->q_inp ); + q_min = s_min( q_min, sts[0]->q_old_inp ); + q_min = s_min( q_min, sts[0]->q_inp ); + + shift = norm_arr( sts[1]->old_input_signal_fx, input_frame ); + shift = s_min( shift, norm_arr( sts[1]->input_fx, input_frame ) ); + shift = s_min( shift, norm_arr( sts[0]->old_input_signal_fx, input_frame ) ); + shift = s_min( shift, norm_arr( sts[0]->input_fx, input_frame ) ); + + q_min = add( q_min, shift ); + + scale_sig( sts[1]->input_fx, input_frame, sub( q_min, sts[1]->q_inp ) ); /* q_min */ + scale_sig( sts[1]->old_input_signal_fx, input_frame, sub( q_min, sts[1]->q_old_inp ) ); /* q_min */ + scale_sig( sts[0]->input_fx, input_frame, sub( q_min, sts[0]->q_inp ) ); /* q_min */ + scale_sig( sts[0]->old_input_signal_fx, input_frame, sub( q_min, sts[0]->q_old_inp ) ); /* q_min */ + + sts[1]->q_old_inp = q_min; + sts[0]->q_old_inp = q_min; + sts[1]->q_inp = q_min; + sts[0]->q_inp = q_min; move16(); - sts[1]->q_old_inp = sts[1]->q_inp; - move16(); - - shift = getScaleFactor16( sts[0]->old_input_signal_fx, input_frame ); - Scale_sig( sts[0]->old_input_signal_fx, input_frame, shift ); - sts[0]->q_old_inp = add( sts[0]->q_old_inp, shift ); move16(); - shift = getScaleFactor16( sts[0]->input_fx, input_frame ); - Scale_sig( sts[0]->input_fx, input_frame, shift ); - sts[0]->q_inp = add( sts[0]->q_inp, shift ); move16(); move16(); - Scale_sig( sts[0]->input_fx, input_frame, sub( s_min( sts[0]->q_inp, sts[0]->q_old_inp ), sts[0]->q_inp ) ); - Scale_sig( sts[0]->old_input_signal_fx, input_frame, sub( s_min( sts[0]->q_old_inp, sts[0]->q_inp ), sts[0]->q_old_inp ) ); - sts[0]->q_inp = s_min( sts[0]->q_inp, sts[0]->q_old_inp ); - move16(); - sts[0]->q_old_inp = sts[0]->q_inp; - move16(); } stereo_td_itd_mdct_stereo_fx( hCPE, vad_flag_dtx, vad_hover_flag, input_frame ); @@ -724,12 +844,19 @@ ivas_error ivas_cpe_enc_fx( /*----------------------------------------------------------------* * DFT stereo: iDFT and resampling on both channels *----------------------------------------------------------------*/ - - if ( hCPE->element_mode == IVAS_CPE_DFT ) + IF( EQ_16( hCPE->element_mode, IVAS_CPE_DFT ) ) { - int32_t internal_Fs; + Word32 internal_Fs; - internal_Fs = getTcxonly_ivas_fx( IVAS_CPE_MDCT, sts[0]->bits_frame_nominal * FRAMES_PER_SEC, 0, sts[0]->is_ism_format ) == 0 ? INT_FS_16k : max( INT_FS_16k, sts[0]->sr_core ); + IF( getTcxonly_ivas_fx( IVAS_CPE_MDCT, imult1616( sts[0]->bits_frame_nominal, FRAMES_PER_SEC ), 0, sts[0]->is_ism_format ) == 0 ) + { + internal_Fs = INT_FS_16k; + move32(); + } + ELSE + { + internal_Fs = L_max( INT_FS_16k, sts[0]->sr_core ); + } /* iDFT at input sampling rate */ Word16 out_start_ind, out_end_ind; @@ -739,46 +866,64 @@ ivas_error ivas_cpe_enc_fx( move16(); stereo_dft_enc_synthesize_fx( hCPE->hStereoDft, sts[0]->input32_fx, &out_start_ind, &out_end_ind, 0, input_Fs, input_Fs, 0, NULL ); +#ifdef FIX_ISSUE_1135 + // Normalise the input buffer from Q15 + Word16 input_norm, q_inp32, common_q, fir_delay_len; + input_norm = L_norm_arr( sts[0]->input32_fx + out_start_ind, sub( out_end_ind, out_start_ind ) ); + q_inp32 = add( Q15, input_norm ); + fir_delay_len = NS2SA_FX2( sts[0]->input_Fs, DELAY_FIR_RESAMPL_NS ); + move16(); + + // Find common Q-factor between { q_inp, q_old_inp and q_inp32-16 } + common_q = s_min( s_min( sub( q_inp32, 16 ), sts[0]->q_inp ), sts[0]->q_old_inp ); + + // Rescale the old input, input and FIR delay section of input buffer + scale_sig( sts[0]->old_input_signal_fx, input_frame, sub( common_q, sts[0]->q_old_inp ) ); // q_old_inp -> common_q + Copy_Scale_sig32_16( sts[0]->input32_fx + out_start_ind, sts[0]->input_fx + out_start_ind, sub( out_end_ind, out_start_ind ), sub( add( Q16, common_q ), Q15 ) ); // Q15 -> common_q + scale_sig( sts[0]->input_fx + out_end_ind, add( sub( input_frame, out_end_ind ), fir_delay_len ), sub( common_q, sts[0]->q_inp ) ); // q_inp -> common_q + + // Update the Q-factors + sts[0]->q_inp = common_q; + move16(); + sts[0]->q_old_inp = common_q; + move16(); +#else + Copy_Scale_sig32_16( sts[0]->input32_fx + out_start_ind, sts[0]->input_fx + out_start_ind, sub( out_end_ind, out_start_ind ), sub( add( Q16, sts[0]->q_inp ), Q15 ) ); // Q15 +#endif + /* iDFT & resampling to 12.8kHz internal sampling rate */ stereo_dft_enc_synthesize_fx( hCPE->hStereoDft, old_inp_12k8_fx[0] + L_INP_MEM, &out_12k8_start_ind[0], &out_12k8_end_ind[0], 0, input_Fs, INT_FS_12k8, 0, NULL ); + Copy_Scale_sig_32_16( old_inp_12k8_fx[0], old_inp_12k8_16fx[0], L_INP_12k8, -Q16 ); // Q-1 /* iDFT & resampling to 16kHz internal sampling rate for M channel */ IF( EQ_32( input_Fs, internal_Fs ) ) { - Copy32( sts[0]->input32_fx - STEREO_DFT_OVL_16k, old_inp_16k_fx[0] + L_INP_MEM - STEREO_DFT_OVL_16k, input_frame + STEREO_DFT_OVL_16k ); + Copy32( sts[0]->input32_fx - STEREO_DFT_OVL_16k, old_inp_16k_fx[0] + L_INP_MEM - STEREO_DFT_OVL_16k, add( input_frame, STEREO_DFT_OVL_16k ) ); /* Q_inp */ out_16k_start_ind = -STEREO_DFT_OVL_16k; - out_16k_end_ind = out_16k_start_ind + input_frame + STEREO_DFT_OVL_16k; + out_16k_end_ind = add( out_16k_start_ind, add( input_frame, STEREO_DFT_OVL_16k ) ); + move16(); + move16(); } ELSE { stereo_dft_enc_synthesize_fx( hCPE->hStereoDft, old_inp_16k_fx[0] + L_INP_MEM, &out_16k_start_ind, &out_16k_end_ind, 0, input_Fs, internal_Fs, 0, NULL ); } + Copy_Scale_sig32_16( old_inp_16k_fx[0], old_inp_16k_16fx[0], L_INP, 0 ); // Q15->Q-1 /* DFT Stereo: iDFT of residual signal at 8kHz sampling rate */ test(); IF( EQ_16( hCPE->element_mode, IVAS_CPE_DFT ) && hCPE->hStereoDft->res_cod_mode[STEREO_DFT_OFFSET] ) { - Copy_Scale_sig_16_32_no_sat( sts[1]->old_inp_12k8_fx, old_inp_12k8_fx[1], L_INP_MEM, 16 - 0 ); + Copy_Scale_sig_16_32_no_sat( sts[1]->old_inp_12k8_fx, old_inp_12k8_fx[1], L_INP_MEM, 15 - 0 ); // Q15 stereo_dft_enc_synthesize_fx( hCPE->hStereoDft, old_inp_12k8_fx[1] + L_INP_MEM, &out_12k8_start_ind[1], &out_12k8_end_ind[1], 1, input_Fs, 8000, 0, NULL ); /* update old input signal buffer */ - Copy_Scale_sig_32_16( old_inp_12k8_fx[1] + L_FRAME8k, sts[1]->old_inp_12k8_fx, L_INP_MEM, 0 - 16 ); - } - Copy_Scale_sig32_16( sts[0]->input32_fx + out_start_ind, sts[0]->input_fx + out_start_ind, sub( out_end_ind, out_start_ind ), sub( add( Q16, sts[0]->q_inp ), Q16 ) ); - - Copy_Scale_sig32_16( old_inp_16k_fx[0], old_inp_16k_16fx[0], L_INP, -1 ); // Q16->Q-1 -#ifdef IVAS_FLOAT_FIXED_CONVERSIONS - /*local fix2flt*/ - /*fix2flt: dft_synthesize*/ - Copy_Scale_sig_32_16( old_inp_12k8_fx[0] + L_INP_MEM + out_12k8_start_ind[0], old_inp_12k8_16fx[0] + L_INP_MEM + out_12k8_start_ind[0], out_12k8_end_ind[0] - out_12k8_start_ind[0], -Q17 ); - if ( hCPE->element_mode == IVAS_CPE_DFT && hCPE->hStereoDft->res_cod_mode[STEREO_DFT_OFFSET] ) - { + Copy_Scale_sig_32_16( old_inp_12k8_fx[1] + L_FRAME8k, sts[1]->old_inp_12k8_fx, L_INP_MEM, 0 - 15 ); // Q0 sts[1]->exp_old_inp_12k8 = Q15; move16(); - Copy_Scale_sig_32_16( old_inp_12k8_fx[1] + L_INP_MEM + out_12k8_start_ind[1], old_inp_12k8_16fx[1] + L_INP_MEM + out_12k8_start_ind[1], out_12k8_end_ind[1] - out_12k8_start_ind[1], -Q17 ); // Q-1 + Copy_Scale_sig_32_16( old_inp_12k8_fx[1], old_inp_12k8_16fx[1], L_INP_12k8, -Q16 ); // Q-1 } - /*fix2flt end*/ -#endif + /* no iDFT at input sampling rate for Side channel -> reset the buffer */ set16_fx( sts[1]->input_fx, 0, input_frame ); sts[1]->q_inp = Q15; @@ -792,21 +937,30 @@ ivas_error ivas_cpe_enc_fx( /*----------------------------------------------------------------* * Front Pre-processing *----------------------------------------------------------------*/ - FOR( n = 0; n < n_CoreChannels; n++ ) { - FOR( Word16 i = 0; i < hCPE->hCoreCoder[n]->nb_subfr; i++ ) - { - Scale_sig( &A_fx[n][i * ( M + 1 )], M + 1, sub( norm_s( A_fx[n][i * ( M + 1 )] ), 2 ) ); // scaling to Q12 - } set16_fx( old_wsp_fx[n], 0, L_WSP ); q_old_wsp = Q15; move16(); + Word16 front_vad_flag; + IF( st_ivas->hSpar != NULL ) + { + front_vad_flag = st_ivas->hSpar->front_vad_flag; + } + ELSE + { + front_vad_flag = 0; + } + error = pre_proc_front_ivas_fx( NULL, hCPE, hCPE->element_brate, nb_bits_metadata, input_frame, n, old_inp_12k8_16fx[n], old_inp_16k_16fx[n], &ener_fx[n], &relE_fx[n], A_fx[n], Aw_fx[n], epsP_fx[n], &epsP_fx_q[n], lsp_new_fx[n], lsp_mid_fx[n], &vad_hover_flag[n], &attack_flag[n], realBuffer_fx[n], imagBuffer_fx[n], &q_re_im_buf[n], old_wsp_fx[n], &q_old_wsp, pitch_fr_fx[n], voicing_fr_fx[n], &loc_harm[n], &cor_map_sum_fx[n], &vad_flag_dtx[n], enerBuffer_fx[n], &enerBuffer_fx_exp[n], - fft_buff_fx[n], &fft_buff_fx_q[n], A_fx[0], lsp_new_fx[0], currFlatness_fx[n], tdm_ratio_idx, fr_bands_fx, add( Q_buffer[n], QSCALE ), Etot_LR_fx, lf_E_fx, add( Q_buffer[n], QSCALE - 2 ), localVAD_HE_SAD, - band_energies_LR_fx, sub( add( Q_buffer[n], QSCALE ), band_ener_guardbits ), 0, st_ivas->hSpar != NULL ? st_ivas->hSpar->front_vad_flag : 0, 0, 0, ivas_format, st_ivas->hMCT != NULL, ivas_total_brate, &Q_new[n] + fft_buff_fx[n], &fft_buff_fx_q[n], A_fx[0], lsp_new_fx[0], currFlatness_fx[n], tdm_ratio_idx, fr_bands_fx, q_fr_bands, Etot_LR_fx, lf_E_fx, q_lf_E[n], localVAD_HE_SAD, +#ifdef NONBE_1211_DTX_BR_SWITCHING + band_energies_LR_fx, q_band_energies_LR, 0, front_vad_flag, 0, 0, ivas_format, st_ivas->hMCT != NULL, st_ivas->hEncoderConfig->last_ivas_total_brate, ivas_total_brate, &Q_new[n] +#else + band_energies_LR_fx, q_band_energies_LR, 0, front_vad_flag, 0, 0, ivas_format, st_ivas->hMCT != NULL, ivas_total_brate, &Q_new[n] +#endif #ifdef DEBUG_MODE_INFO , ( st_ivas->nSCE + ( cpe_id * CPE_CHANNELS ) + n ) @@ -814,7 +968,7 @@ ivas_error ivas_cpe_enc_fx( ); e_old_wsp[n] = sub( Q15, q_old_wsp ); move16(); - if ( error != IVAS_ERR_OK ) + IF( error != IVAS_ERR_OK ) { return error; } @@ -828,33 +982,39 @@ ivas_error ivas_cpe_enc_fx( fft_buff_fx_final_q = sub( fft_buff_fx_final_q, 2 ); // headroom FOR( n = 0; n < n_CoreChannels; n++ ) { - Scale_sig( fft_buff_fx[n], 2 * L_FFT, sub( fft_buff_fx_final_q, fft_buff_fx_q[n] ) ); + Scale_sig( fft_buff_fx[n], 2 * L_FFT, sub( fft_buff_fx_final_q, fft_buff_fx_q[n] ) ); /* fft_buff_fx_final_q */ } /* sanity check -> DTX not supported for more than one SCEs/CPEs */ - if ( st_ivas->nSCE + st_ivas->nCPE > 1 ) + IF( GT_16( add( st_ivas->nSCE, st_ivas->nCPE ), 1 ) ) { - if ( sts[0]->core_brate == SID_2k40 || sts[0]->core_brate == FRAME_NO_DATA ) + test(); + IF( EQ_32( sts[0]->core_brate, SID_2k40 ) || sts[0]->core_brate == FRAME_NO_DATA ) { - sts[0]->core_brate = -1; - sts[0]->total_brate = hCPE->element_brate; + sts[0]->core_brate = -1; /* Q0 */ + sts[0]->total_brate = hCPE->element_brate; /* Q0 */ + move32(); + move32(); } } /*----------------------------------------------------------------* * Stereo DTX updates *----------------------------------------------------------------*/ - - if ( ivas_format == MASA_FORMAT && nb_bits_metadata > 0 && hCPE->hCoreCoder[0]->Opt_DTX_ON ) + test(); + test(); + IF( EQ_16( ivas_format, MASA_FORMAT ) && nb_bits_metadata > 0 && hCPE->hCoreCoder[0]->Opt_DTX_ON ) { - if ( hCPE->element_mode == IVAS_CPE_DFT || hCPE->element_mode == IVAS_CPE_TD ) + test(); + IF( EQ_16( hCPE->element_mode, IVAS_CPE_DFT ) || EQ_16( hCPE->element_mode, IVAS_CPE_TD ) ) { reset_metadata_spatial_fx( ivas_format, hCPE->hMetaData, hCPE->element_brate, &tmp, sts[0]->core_brate, nb_bits_metadata ); } } /* MDCT stereo DTX: active/inactive frame decision; compute FD CNG coherence */ - if ( hCPE->element_mode == IVAS_CPE_MDCT && hEncoderConfig->Opt_DTX_ON ) + test(); + IF( EQ_16( hCPE->element_mode, IVAS_CPE_MDCT ) && hEncoderConfig->Opt_DTX_ON ) { stereoFdCngCoherence_fx( sts, hCPE->last_element_mode, fft_buff_fx, sub( 15, fft_buff_fx_final_q ) /*fft exp*/ ); @@ -881,27 +1041,36 @@ ivas_error ivas_cpe_enc_fx( IF( ( NE_32( hCPE->last_element_brate, hCPE->element_brate ) || NE_16( hCPE->element_mode, hCPE->last_element_mode ) || ( EQ_16( hCPE->element_mode, IVAS_CPE_TD ) && NE_16( sts[0]->bits_frame_nominal, last_bits_frame_nominal ) ) || NE_16( sts[n]->last_bwidth, sts[n]->bwidth ) ) && ( n == 0 || EQ_16( hCPE->element_mode, IVAS_CPE_MDCT ) ) ) { Word16 igf; - igf = getIgfPresent_fx( sts[n]->element_mode, L_mult0( sts[n]->bits_frame_nominal, FRAMES_PER_SEC ), sts[n]->max_bwidth, sts[n]->rf_mode ); - IF( NE_32( ( error = IGF_Reconfig_fx( &sts[n]->hIGFEnc, igf, 0, L_mult0( sts[n]->bits_frame_nominal, FRAMES_PER_SEC ), sts[n]->max_bwidth, sts[n]->element_mode, sts[n]->rf_mode ) ), IVAS_ERR_OK ) ) + igf = getIgfPresent_fx( sts[n]->element_mode, L_mult0( sts[n]->bits_frame_nominal, FRAMES_PER_SEC ), sts[n]->max_bwidth, sts[n]->rf_mode ); /* Q0 */ + IF( ( error = IGF_Reconfig_fx( &sts[n]->hIGFEnc, igf, 0, L_mult0( sts[n]->bits_frame_nominal, FRAMES_PER_SEC ), sts[n]->max_bwidth, sts[n]->element_mode, sts[n]->rf_mode ) ) != IVAS_ERR_OK ) { return error; } } } - if ( hCPE->element_mode == IVAS_CPE_MDCT && st_ivas->hMCT == NULL ) + test(); + IF( EQ_16( hCPE->element_mode, IVAS_CPE_MDCT ) && st_ivas->hMCT == NULL ) { /* set coded BW for MDCT stereo */ set_bw_stereo_fx( hCPE ); /* reconfiguration of MDCT stereo */ - if ( sts[0]->bwidth != sts[0]->last_bwidth || ( ( hCPE->last_element_brate != hCPE->element_brate || hCPE->last_element_mode != hCPE->element_mode ) && sts[0]->bwidth != sts[0]->max_bwidth ) ) + test(); + test(); + test(); + IF( sts[0]->bwidth != sts[0]->last_bwidth || ( ( hCPE->last_element_brate != hCPE->element_brate || hCPE->last_element_mode != hCPE->element_mode ) && sts[0]->bwidth != sts[0]->max_bwidth ) ) { initMdctStereoEncData_fx( hCPE->hStereoMdct, ivas_format, hCPE->element_mode, hCPE->element_brate, sts[0]->bwidth, 0, NULL, 0 ); - hCPE->hStereoMdct->isSBAStereoMode = ( ( ivas_format == SBA_FORMAT || ivas_format == SBA_ISM_FORMAT ) && ( st_ivas->nchan_transport == 2 ) ); - if ( hCPE->element_brate <= MAX_MDCT_ITD_BRATE && ivas_format == STEREO_FORMAT ) + test(); + test(); + test(); + hCPE->hStereoMdct->isSBAStereoMode = ( ( EQ_16( ivas_format, SBA_FORMAT ) || EQ_16( ivas_format, SBA_ISM_FORMAT ) ) && ( EQ_16( st_ivas->nchan_transport, 2 ) ) ); /* Q0 */ + + test(); + IF( LE_32( hCPE->element_brate, MAX_MDCT_ITD_BRATE ) && EQ_16( ivas_format, STEREO_FORMAT ) ) { - IF( NE_32( ( error = initMdctItdHandling_fx( hCPE->hStereoMdct, input_Fs ) ), IVAS_ERR_OK ) ) + IF( ( error = initMdctItdHandling_fx( hCPE->hStereoMdct, input_Fs ) ) != IVAS_ERR_OK ) { return error; } @@ -910,20 +1079,24 @@ ivas_error ivas_cpe_enc_fx( } /* set ACELP@12k8 / ACELP@16k flag for flexible ACELP core */ - for ( n = 0; n < n_CoreChannels; n++ ) + FOR( n = 0; n < n_CoreChannels; n++ ) { - if ( ( sts[0]->core_brate == SID_2k40 || sts[0]->core_brate == FRAME_NO_DATA ) && hCPE->element_mode == IVAS_CPE_DFT ) + test(); + test(); + IF( ( EQ_32( sts[0]->core_brate, SID_2k40 ) || sts[0]->core_brate == FRAME_NO_DATA ) && EQ_16( hCPE->element_mode, IVAS_CPE_DFT ) ) { - sts[n]->flag_ACELP16k = set_ACELP_flag_IVAS( hCPE->element_mode, hCPE->element_brate, sts[n]->core_brate, n, sts[0]->tdm_LRTD_flag, sts[n]->bwidth, sts[n]->cng_type ); + sts[n]->flag_ACELP16k = set_ACELP_flag_IVAS( hCPE->element_mode, hCPE->element_brate, sts[n]->core_brate, n, sts[0]->tdm_LRTD_flag, sts[n]->bwidth, sts[n]->cng_type ); /* Q0 */ + move16(); } - else + ELSE { - sts[n]->flag_ACELP16k = set_ACELP_flag_IVAS( hCPE->element_mode, hCPE->element_brate, sts[n]->total_brate, n, sts[0]->tdm_LRTD_flag, sts[n]->bwidth, sts[n]->cng_type ); + sts[n]->flag_ACELP16k = set_ACELP_flag_IVAS( hCPE->element_mode, hCPE->element_brate, sts[n]->total_brate, n, sts[0]->tdm_LRTD_flag, sts[n]->bwidth, sts[n]->cng_type ); /* Q0 */ + move16(); } } /* configure TD stereo encoder */ - if ( hCPE->element_mode == IVAS_CPE_TD ) + IF( EQ_16( hCPE->element_mode, IVAS_CPE_TD ) ) { tdm_ol_pitch_comparison_fx( hCPE, pitch_fr_fx, voicing_fr_fx ); tdm_configure_enc_fx( ivas_format, st_ivas->ism_mode, hCPE, Etot_last_fx, tdm_SM_or_LRTD_Pri, tdm_ratio_idx, tdm_ratio_idx_SM, attack_flag[0], nb_bits_metadata ); @@ -967,7 +1140,7 @@ ivas_error ivas_cpe_enc_fx( IF( hEncoderConfig->Opt_DTX_ON ) { test(); - IF( EQ_32( sts[0]->core_brate, SID_2k40 ) || EQ_32( sts[0]->core_brate, FRAME_NO_DATA ) ) + IF( EQ_32( sts[0]->core_brate, SID_2k40 ) || sts[0]->core_brate == FRAME_NO_DATA ) { /* Reconfigure DFT Stereo for inactive frames */ IF( EQ_32( sts[0]->core_brate, SID_2k40 ) ) @@ -988,7 +1161,7 @@ ivas_error ivas_cpe_enc_fx( } /* Write stereo bitstream */ - cpe_brate = st_ivas->hCPE[0]->element_brate; + cpe_brate = st_ivas->hCPE[0]->element_brate; /* Q0 */ move16(); /* DFT stereo side bits */ @@ -999,14 +1172,14 @@ ivas_error ivas_cpe_enc_fx( test(); test(); test(); - IF( ( EQ_16( ivas_format, MASA_FORMAT ) || EQ_16( ivas_format, MASA_ISM_FORMAT ) ) && LT_32( cpe_brate, MASA_STEREO_MIN_BITRATE ) && NE_32( sts[0]->core_brate, SID_2k40 ) && NE_32( sts[0]->core_brate, FRAME_NO_DATA ) ) + IF( ( EQ_16( ivas_format, MASA_FORMAT ) || EQ_16( ivas_format, MASA_ISM_FORMAT ) ) && LT_32( cpe_brate, MASA_STEREO_MIN_BITRATE ) && NE_32( sts[0]->core_brate, SID_2k40 ) && sts[0]->core_brate != FRAME_NO_DATA ) { nb_bits = 0; /* Only mono downmix is transmitted in this case */ move16(); } - ELSE IF( ( EQ_16( ivas_format, MASA_FORMAT ) || EQ_16( ivas_format, MASA_ISM_FORMAT ) ) && ( EQ_32( sts[0]->core_brate, SID_2k40 ) || EQ_32( sts[0]->core_brate, FRAME_NO_DATA ) ) ) + ELSE IF( ( EQ_16( ivas_format, MASA_FORMAT ) || EQ_16( ivas_format, MASA_ISM_FORMAT ) ) && ( EQ_32( sts[0]->core_brate, SID_2k40 ) || sts[0]->core_brate == FRAME_NO_DATA ) ) { - nb_bits = hCPE->hMetaData->nb_bits_tot; + nb_bits = hCPE->hMetaData->nb_bits_tot; /* Q0 */ move16(); } ELSE @@ -1015,59 +1188,65 @@ ivas_error ivas_cpe_enc_fx( } /* Residual coding in MDCT domain */ - if ( !( ( ivas_format == MASA_FORMAT || ivas_format == MASA_ISM_FORMAT ) && ( sts[0]->core_brate == SID_2k40 || sts[0]->core_brate == FRAME_NO_DATA ) ) ) + test(); + test(); + IF( !( ( EQ_16( ivas_format, MASA_FORMAT ) || EQ_16( ivas_format, MASA_ISM_FORMAT ) ) && ( EQ_32( sts[0]->core_brate, SID_2k40 ) || sts[0]->core_brate == FRAME_NO_DATA ) ) ) { - int16_t max_bits = (int16_t) ( hCPE->element_brate / FRAMES_PER_SEC - 0.8f * sts[0]->bits_frame_nominal ); - if ( ivas_format == MASA_FORMAT || ivas_format == MASA_ISM_FORMAT ) + Word16 max_bits = extract_l( W_extract_h( W_sub( W_mult_32_32( hCPE->element_brate, ONE_BY_FRAMES_PER_SEC_Q31 ), W_mult_32_32( L_deposit_l( sts[0]->bits_frame_nominal ), 1717986918 /* 0.8f in Q31 */ ) ) ) ); + test(); + IF( EQ_16( ivas_format, MASA_FORMAT ) || EQ_16( ivas_format, MASA_ISM_FORMAT ) ) { - max_bits -= nb_bits_metadata; - if ( hCPE->brate_surplus < 0 ) + max_bits = sub( max_bits, nb_bits_metadata ); + IF( hCPE->brate_surplus < 0 ) { - max_bits += (int16_t) ( hCPE->brate_surplus / FRAMES_PER_SEC ); + max_bits = add( max_bits, extract_l( Mpy_32_32_r( hCPE->brate_surplus, ONE_BY_FRAMES_PER_SEC_Q31 ) ) ); } } -#ifdef IVAS_FLOAT_FIXED_CONVERSIONS - FOR( int i = 0; i < CPE_CHANNELS; i++ ) + FOR( Word16 i = 0; i < CPE_CHANNELS; i++ ) { - Copy_Scale_sig_16_32( old_inp_12k8_16fx[i], old_inp_12k8_fx[i], Q16 + Q1, L_INP_12k8 ); + Copy_Scale_sig_16_32_no_sat( old_inp_12k8_16fx[i], old_inp_12k8_fx[i], L_INP_12k8, Q16 ); // Q(-1) -> Q15 } -#endif stereo_dft_enc_res_fx( hCPE->hStereoDft, old_inp_12k8_fx[1] + L_INP_MEM - STEREO_DFT_OVL_8k, hCPE->hMetaData, &nb_bits, max_bits ); } - if ( sts[0]->core_brate == FRAME_NO_DATA || sts[0]->core_brate == SID_2k40 ) + IF( sts[0]->core_brate == FRAME_NO_DATA || EQ_32( sts[0]->core_brate, SID_2k40 ) ) { assert( ( nb_bits <= ( ( IVAS_SID_5k2 - SID_2k40 ) / FRAMES_PER_SEC - SID_FORMAT_NBITS ) ) && "Stereo DFT CNG: bit budget is violated" ); } - else + ELSE { /* Flexible total bitrate in M channel */ - sts[0]->total_brate = hCPE->element_brate - ( nb_bits * FRAMES_PER_SEC ); + sts[0]->total_brate = L_sub( hCPE->element_brate, L_deposit_l( imult1616( nb_bits, FRAMES_PER_SEC ) ) ); + move32(); } /* subtract metadata bitbudget */ - sts[0]->total_brate -= ( nb_bits_metadata * FRAMES_PER_SEC ); + sts[0]->total_brate = L_sub( sts[0]->total_brate, L_deposit_l( imult1616( nb_bits_metadata, FRAMES_PER_SEC ) ) ); + move32(); /* subtract bit-rate for combined format coding */ - if ( ivas_format == MASA_ISM_FORMAT && ( st_ivas->ism_mode == ISM_MASA_MODE_MASA_ONE_OBJ || st_ivas->ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ || st_ivas->ism_mode == ISM_MASA_MODE_DISC ) ) + test(); + test(); + test(); + if ( EQ_16( ivas_format, MASA_ISM_FORMAT ) && ( EQ_32( st_ivas->ism_mode, ISM_MASA_MODE_MASA_ONE_OBJ ) || EQ_32( st_ivas->ism_mode, ISM_MASA_MODE_PARAM_ONE_OBJ ) || EQ_32( st_ivas->ism_mode, ISM_MASA_MODE_DISC ) ) ) { - sts[0]->total_brate += hCPE->brate_surplus; + sts[0]->total_brate = L_add( sts[0]->total_brate, hCPE->brate_surplus ); + move32(); } } - /*----------------------------------------------------------------* * Core Encoder *----------------------------------------------------------------*/ FOR( n = 0; n < n_CoreChannels; n++ ) { - Scale_sig( old_wsp_fx[n], L_WSP, sub( e_old_wsp[n], Q16 ) ); + Scale_sig( old_wsp_fx[n], L_WSP, sub( e_old_wsp[n], Q16 ) ); /* exp(16) */ e_old_wsp[n] = 16; move16(); } - IF( NE_32( ( error = ivas_core_enc( NULL, hCPE, st_ivas->hMCT, n_CoreChannels, old_inp_12k8_16fx, old_inp_16k_16fx, Q_new, ener_fx, A_fx, Aw_fx, epsP_fx, epsP_fx_q, lsp_new_fx, lsp_mid_fx, vad_hover_flag, attack_flag, realBuffer_fx, imagBuffer_fx, q_re_im_buf, old_wsp_fx, e_old_wsp, loc_harm, cor_map_sum_fx, vad_flag_dtx, enerBuffer_fx, enerBuffer_fx_exp, fft_buff_fx, tdm_SM_or_LRTD_Pri, ivas_format, 0 ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = ivas_core_enc_fx( NULL, hCPE, st_ivas->hMCT, n_CoreChannels, old_inp_12k8_16fx, old_inp_16k_16fx, Q_new, ener_fx, A_fx, Aw_fx, epsP_fx, epsP_fx_q, lsp_new_fx, lsp_mid_fx, vad_hover_flag, attack_flag, realBuffer_fx, imagBuffer_fx, q_re_im_buf, old_wsp_fx, e_old_wsp, loc_harm, cor_map_sum_fx, vad_flag_dtx, enerBuffer_fx, enerBuffer_fx_exp, fft_buff_fx, tdm_SM_or_LRTD_Pri, ivas_format, 0 ) ), IVAS_ERR_OK ) ) { return error; } @@ -1076,48 +1255,57 @@ ivas_error ivas_cpe_enc_fx( * Common updates *----------------------------------------------------------------*/ - hCPE->last_element_brate = hCPE->element_brate; - hCPE->last_element_mode = hCPE->element_mode; + hCPE->last_element_brate = hCPE->element_brate; /* Q0 */ + move32(); + hCPE->last_element_mode = hCPE->element_mode; /* Q0 */ + move16(); - if ( ivas_format == MASA_ISM_FORMAT ) + if ( EQ_16( ivas_format, MASA_ISM_FORMAT ) ) { - hCPE->element_brate = element_brate_ref; + hCPE->element_brate = element_brate_ref; /* Q0 */ + move32(); } - if ( hCPE->element_mode == IVAS_CPE_MDCT && hCPE->hStereoMdct != NULL && hCPE->hStereoMdct->hItd != NULL ) + IF( EQ_16( hCPE->element_mode, IVAS_CPE_MDCT ) && hCPE->hStereoMdct != NULL && hCPE->hStereoMdct->hItd != NULL ) { /* update input samples buffer */ - for ( n = 0; n < CPE_CHANNELS; n++ ) + FOR( n = 0; n < CPE_CHANNELS; n++ ) { - Copy( orig_input_fx[n], sts[n]->old_input_signal_fx, input_frame ); - sts[n]->q_old_inp = sts[n]->q_inp; + Copy( orig_input_fx[n], sts[n]->old_input_signal_fx, input_frame ); /* Q_orig_inp */ + sts[n]->q_old_inp = Q_orig_inp[n]; + move16(); } } - else if ( hCPE->element_mode == IVAS_CPE_DFT ) + ELSE IF( EQ_16( hCPE->element_mode, IVAS_CPE_DFT ) ) { - Copy( sts[0]->input_fx, sts[0]->old_input_signal_fx, input_frame ); + Copy( sts[0]->input_fx, sts[0]->old_input_signal_fx, input_frame ); /* sts[n]->q_inp */ sts[0]->q_old_inp = sts[0]->q_inp; + move16(); } - else if ( st_ivas->hMCT == NULL ) /* note: in MCT, input buffers are updated later in ivas_mct_enc() */ + ELSE IF( st_ivas->hMCT == NULL ) /* note: in MCT, input buffers are updated later in ivas_mct_enc() */ { /* update input samples buffer */ - for ( n = 0; n < CPE_CHANNELS; n++ ) + FOR( n = 0; n < CPE_CHANNELS; n++ ) { - Copy( sts[n]->input_fx, sts[n]->old_input_signal_fx, input_frame ); + Copy( sts[n]->input_fx, sts[n]->old_input_signal_fx, input_frame ); /* sts[n]->q_inp */ sts[n]->q_old_inp = sts[n]->q_inp; + move16(); } } - if ( hCPE->hFrontVad[0] != NULL ) + IF( hCPE->hFrontVad[0] != NULL ) { - hCPE->hFrontVad[0]->ini_frame++; - hCPE->hFrontVad[0]->ini_frame = min( hCPE->hFrontVad[0]->ini_frame, MAX_FRAME_COUNTER ); + hCPE->hFrontVad[0]->ini_frame = add( hCPE->hFrontVad[0]->ini_frame, 1 ); + hCPE->hFrontVad[0]->ini_frame = s_min( hCPE->hFrontVad[0]->ini_frame, MAX_FRAME_COUNTER ); + move16(); + move16(); } /* Store previous attack detection flag */ - for ( n = 0; n < CPE_CHANNELS; n++ ) + FOR( n = 0; n < CPE_CHANNELS; n++ ) { - sts[n]->hTranDet->transientDetector.prev_bIsAttackPresent = sts[n]->hTranDet->transientDetector.bIsAttackPresent; + sts[n]->hTranDet->transientDetector.prev_bIsAttackPresent = sts[n]->hTranDet->transientDetector.bIsAttackPresent; /* Q0 */ + move16(); } IF( Q_new_out ) @@ -1144,8 +1332,8 @@ ivas_error ivas_cpe_enc_fx( *-------------------------------------------------------------------------*/ ivas_error create_cpe_enc_fx( Encoder_Struct *st_ivas, /* i/o: IVAS encoder structure */ - const Word16 cpe_id, /* i : CPE # identifier */ - const Word32 element_brate /* i : element bitrate */ + const Word16 cpe_id, /* i : CPE # identifier Q0*/ + const Word32 element_brate /* i : element bitrate Q0*/ ) { Word16 n; @@ -1162,11 +1350,11 @@ ivas_error create_cpe_enc_fx( ivas_format = hEncoderConfig->ivas_format; move16(); - element_mode_init = hEncoderConfig->element_mode_init; + element_mode_init = hEncoderConfig->element_mode_init; /* Q0 */ move16(); - input_Fs = hEncoderConfig->input_Fs; + input_Fs = hEncoderConfig->input_Fs; /* Q0 */ move16(); - max_bwidth = hEncoderConfig->max_bwidth; + max_bwidth = hEncoderConfig->max_bwidth; /* Q0 */ move16(); /*-----------------------------------------------------------------* @@ -1182,15 +1370,15 @@ ivas_error create_cpe_enc_fx( * Initialization - general parameters *-----------------------------------------------------------------*/ - hCPE->cpe_id = cpe_id; + hCPE->cpe_id = cpe_id; /* Q0 */ move16(); - hCPE->element_brate = element_brate; + hCPE->element_brate = element_brate; /* Q0 */ move16(); - hCPE->last_element_brate = hCPE->element_brate; + hCPE->last_element_brate = hCPE->element_brate; /* Q0 */ move16(); - hCPE->element_mode = element_mode_init; + hCPE->element_mode = element_mode_init; /* Q0 */ move16(); - hCPE->last_element_mode = element_mode_init; + hCPE->last_element_mode = element_mode_init; /* Q0 */ move16(); hCPE->hStereoDft = NULL; @@ -1218,12 +1406,12 @@ ivas_error create_cpe_enc_fx( test(); IF( EQ_16( ivas_format, STEREO_FORMAT ) || EQ_16( ivas_format, MASA_FORMAT ) || ( EQ_16( ivas_format, MC_FORMAT ) && EQ_16( st_ivas->mc_mode, MC_MODE_MCMASA ) ) || EQ_16( ivas_format, MASA_ISM_FORMAT ) ) { - IF( ( hCPE->input_mem_fx[n] = (Word16 *) malloc( sizeof( Word16 ) * NS2SA( input_Fs, STEREO_DFT_OVL_NS ) ) ) == NULL ) + IF( ( hCPE->input_mem_fx[n] = (Word16 *) malloc( sizeof( Word16 ) * NS2SA_FX2( input_Fs, STEREO_DFT_OVL_NS ) ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DFT stereo memory\n" ) ); } - set16_zero_fx( hCPE->input_mem_fx[n], NS2SA( input_Fs, STEREO_DFT_OVL_NS ) ); + set16_zero_fx( hCPE->input_mem_fx[n], NS2SA_FX2( input_Fs, STEREO_DFT_OVL_NS ) ); } ELSE { @@ -1251,7 +1439,7 @@ ivas_error create_cpe_enc_fx( IF( EQ_16( cpe_id, sub( st_ivas->nCPE, 1 ) ) ) { - IF( NE_32( ( error = ivas_initialize_MD_bstr_enc( &( hCPE->hMetaData ), st_ivas ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = ivas_initialize_MD_bstr_enc_fx( &( hCPE->hMetaData ), st_ivas ) ), IVAS_ERR_OK ) ) { return error; } @@ -1272,12 +1460,12 @@ ivas_error create_cpe_enc_fx( IF( GT_16( st_ivas->nCPE, 1 ) ) { - st->total_brate = hCPE->element_brate; /* dummy initialization for getting right pointers initialization of input buffers in init_coder_ace_plus() */ + st->total_brate = hCPE->element_brate; /* dummy initialization for getting right pointers initialization of input buffers in init_coder_ace_plus() Q0*/ move32(); } ELSE { - st->total_brate = L_shr( hCPE->element_brate, 1 ); /* dummy initialization for getting right pointers initialization of input buffers in init_coder_ace_plus() */ + st->total_brate = L_shr( hCPE->element_brate, 1 ); /* dummy initialization for getting right pointers initialization of input buffers in init_coder_ace_plus() Q0*/ move32(); } st->mct_chan_mode = MCT_CHAN_MODE_REGULAR; @@ -1289,7 +1477,8 @@ ivas_error create_cpe_enc_fx( IF( st->hFdCngEnc != NULL ) { - st->hFdCngEnc->hFdCngCom->CngBitrate = L_sub( hCPE->element_brate, 1 ); + st->hFdCngEnc->hFdCngCom->CngBitrate = L_sub( hCPE->element_brate, 1 ); /* Q0 */ + move32(); } hCPE->hCoreCoder[n] = st; @@ -1325,7 +1514,7 @@ ivas_error create_cpe_enc_fx( { FOR( n = 0; n < CPE_CHANNELS; n++ ) { - IF( NE_32( ( error = front_vad_create_fx( &( hCPE->hFrontVad[n] ), hEncoderConfig ) ), IVAS_ERR_OK ) ) + IF( ( error = front_vad_create_fx( &( hCPE->hFrontVad[n] ), hEncoderConfig ) ) != IVAS_ERR_OK ) { return error; } @@ -1345,7 +1534,7 @@ ivas_error create_cpe_enc_fx( IF( EQ_16( hCPE->element_mode, IVAS_CPE_DFT ) ) { - IF( NE_32( ( error = stereo_dft_enc_create_fx( &( hCPE->hStereoDft ), input_Fs, max_bwidth ) ), IVAS_ERR_OK ) ) + IF( ( error = stereo_dft_enc_create_fx( &( hCPE->hStereoDft ), input_Fs, max_bwidth ) ) != IVAS_ERR_OK ) { return error; } @@ -1385,7 +1574,7 @@ ivas_error create_cpe_enc_fx( IF( EQ_16( hCPE->element_mode, IVAS_CPE_TD ) ) { - if ( ( hCPE->hStereoTD = (STEREO_TD_ENC_DATA_HANDLE) malloc( sizeof( STEREO_TD_ENC_DATA ) ) ) == NULL ) + IF( ( hCPE->hStereoTD = (STEREO_TD_ENC_DATA_HANDLE) malloc( sizeof( STEREO_TD_ENC_DATA ) ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for TD Stereo\n" ) ); } @@ -1396,6 +1585,7 @@ ivas_error create_cpe_enc_fx( * MDCT stereo initialization *-----------------------------------------------------------------*/ + test(); IF( EQ_16( hCPE->element_mode, IVAS_CPE_MDCT ) && EQ_16( st_ivas->nCPE, 1 ) ) { IF( ( hCPE->hStereoMdct = (STEREO_MDCT_ENC_DATA_HANDLE) malloc( sizeof( STEREO_MDCT_ENC_DATA ) ) ) == NULL ) @@ -1422,12 +1612,17 @@ ivas_error create_cpe_enc_fx( #endif initMdctStereoEncData_fx( hCPE->hStereoMdct, ivas_format, hCPE->element_mode, hCPE->element_brate, max_bwidth, 0, NULL, 1 ); + + test(); + test(); hCPE->hStereoMdct->isSBAStereoMode = ( ( EQ_16( ivas_format, SBA_FORMAT ) || EQ_16( ivas_format, SBA_ISM_FORMAT ) ) && EQ_16( st_ivas->nchan_transport, 2 ) ); + move16(); + test(); test(); IF( EQ_16( hCPE->element_mode, IVAS_CPE_MDCT ) && LE_32( element_brate, MAX_MDCT_ITD_BRATE ) && EQ_16( ivas_format, STEREO_FORMAT ) ) { - IF( NE_32( ( error = initMdctItdHandling_fx( hCPE->hStereoMdct, input_Fs ) ), IVAS_ERR_OK ) ) + IF( ( error = initMdctItdHandling_fx( hCPE->hStereoMdct, input_Fs ) ) != IVAS_ERR_OK ) { return error; } @@ -1466,7 +1661,7 @@ void destroy_cpe_enc( } } - ivas_destroy_MD_bstr_enc( &( hCPE->hMetaData ) ); + ivas_destroy_MD_bstr_enc_fx( &( hCPE->hMetaData ) ); FOR( n = 0; n < CPE_CHANNELS; n++ ) { @@ -1548,7 +1743,7 @@ static void stereo_mode_combined_format_enc_fx( IF( EQ_16( hEncoderConfig->ivas_format, MASA_ISM_FORMAT ) ) { - element_brate_ref = hCPE->element_brate; + element_brate_ref = hCPE->element_brate; /* Q0 */ move32(); test(); @@ -1566,9 +1761,9 @@ static void stereo_mode_combined_format_enc_fx( } ELSE { - st_ivas->hMasa->data.hOmasaData->omasa_stereo_sw_cnt = add( st_ivas->hMasa->data.hOmasaData->omasa_stereo_sw_cnt, 1 ); + st_ivas->hMasa->data.hOmasaData->omasa_stereo_sw_cnt = add( st_ivas->hMasa->data.hOmasaData->omasa_stereo_sw_cnt, 1 ); /* Q0 */ move16(); - st_ivas->hMasa->data.hOmasaData->omasa_stereo_sw_cnt = s_min( st_ivas->hMasa->data.hOmasaData->omasa_stereo_sw_cnt, OMASA_STEREO_SW_CNT_MAX ); + st_ivas->hMasa->data.hOmasaData->omasa_stereo_sw_cnt = s_min( st_ivas->hMasa->data.hOmasaData->omasa_stereo_sw_cnt, OMASA_STEREO_SW_CNT_MAX ); /* Q0 */ move16(); } @@ -1578,7 +1773,7 @@ static void stereo_mode_combined_format_enc_fx( move16(); hCPE->element_brate = IVAS_64k; move32(); - hCPE->brate_surplus = L_sub( hCPE->brate_surplus, L_sub( hCPE->element_brate, element_brate_ref ) ); + hCPE->brate_surplus = L_sub( hCPE->brate_surplus, L_sub( hCPE->element_brate, element_brate_ref ) ); /* Q0 */ move32(); } @@ -1593,6 +1788,5 @@ static void stereo_mode_combined_format_enc_fx( } } } - return; } diff --git a/lib_enc/ivas_decision_matrix_enc.c b/lib_enc/ivas_decision_matrix_enc_fx.c similarity index 83% rename from lib_enc/ivas_decision_matrix_enc.c rename to lib_enc/ivas_decision_matrix_enc_fx.c index 84939b6024d105b136501dddd94932b742ef7c7d..bd63553bd70f502ee2ad342de594d6ade28caf07 100644 --- a/lib_enc/ivas_decision_matrix_enc.c +++ b/lib_enc/ivas_decision_matrix_enc_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other @@ -35,11 +35,9 @@ #include "cnst.h" #include "ivas_cnst.h" #include "rom_com.h" -#include "prot.h" -#include "ivas_prot.h" +#include "prot_fx.h" #include "ivas_rom_com.h" #include "wmc_auto.h" -#include "prot_fx.h" /* Function prototypes */ #include "ivas_prot_fx.h" /* Function prototypes */ #include "ivas_prot_fx.h" /* Function prototypes */ #include "prot_fx_enc.h" /* Function prototypes */ @@ -74,11 +72,11 @@ void ivas_decision_matrix_enc_fx( Encoder_State *st, /* i : encoder state structure */ - const Word32 element_brate, /* i : element bitrate */ - const Word16 fft_buff[], /* i : FFT buffer */ - const Word32 enerBuffer[], /* i : energy buffer */ + const Word32 element_brate, /* i : element bitrate Q0*/ + const Word16 fft_buff[], /* i : FFT buffer Qx*/ + const Word32 enerBuffer[], /* i : energy buffer enerBuffer_exp*/ Word16 enerBuffer_exp, - const Word16 last_element_mode /* i : last element mode */ + const Word16 last_element_mode /* i : last element mode Q0*/ ) { Word32 icbwe_brate; @@ -96,7 +94,7 @@ void ivas_decision_matrix_enc_fx( st->extl_brate = 0; move16(); - IF( NE_16( st->element_mode, IVAS_CPE_MDCT ) ) + if ( NE_16( st->element_mode, IVAS_CPE_MDCT ) ) { st->igf = 0; move16(); @@ -106,13 +104,13 @@ void ivas_decision_matrix_enc_fx( test(); /* SID and FRAME_NO_DATA frames */ - IF( st->Opt_DTX_ON && ( EQ_32( st->core_brate, SID_2k40 ) || EQ_32( st->core_brate, FRAME_NO_DATA ) ) ) + IF( st->Opt_DTX_ON && ( EQ_32( st->core_brate, SID_2k40 ) || st->core_brate == FRAME_NO_DATA ) ) { st->core = ACELP_CORE; move16(); test(); - IF( GE_32( st->input_Fs, 32000 ) || GE_16( st->bwidth, SWB ) ) + if ( GE_32( st->input_Fs, 32000 ) || GE_16( st->bwidth, SWB ) ) { st->extl = SWB_CNG; move16(); @@ -195,7 +193,7 @@ void ivas_decision_matrix_enc_fx( ELSE { /* select TCX core or HQ core using bits_frame_nominal to match the TCX configuration bitrate */ - st->core = mdct_classifier_ivas_fx( st, fft_buff, enerBuffer, enerBuffer_exp, ( st->bits_frame_nominal * FRAMES_PER_SEC ) ); + st->core = mdct_classifier_ivas_fx( st, fft_buff, enerBuffer, enerBuffer_exp, L_mult0( st->bits_frame_nominal, FRAMES_PER_SEC ) ); /* Q0 */ move16(); } } @@ -207,15 +205,26 @@ void ivas_decision_matrix_enc_fx( test(); test(); +#ifdef DEBUG_FORCE_DIR + if ( st->force_dir[0] != '\0' ) + { + dbgread( &st->core, sizeof( int16_t ), 1, fname( st->force_dir, "force_core_loc1.enf", -1, -1, -1 ) ); + } + else + { + dbgwrite( &st->core, sizeof( int16_t ), 1, 1, "res/force_core_loc1.enf" ); + } +#endif + /* do not allow TD stereo ACELP core -> DFT stereo TCX core switching as it is on the WC complexity path */ - IF( ( ( EQ_16( st->last_core, ACELP_CORE ) && EQ_16( last_element_mode, IVAS_CPE_TD ) && EQ_16( st->element_mode, IVAS_CPE_DFT ) ) || ( EQ_16( st->tdm_LRTD_flag, 1 ) && LE_32( st->total_brate, IVAS_16k4 ) ) ) && EQ_16( st->core, TCX_20_CORE ) && LE_32( st->total_brate, MAX_ACELP_BRATE ) ) /* Override TCX in case of LRTD && primary channel has low bitrate*/ + if ( ( ( st->last_core == ACELP_CORE && EQ_16( last_element_mode, IVAS_CPE_TD ) && EQ_16( st->element_mode, IVAS_CPE_DFT ) ) || ( EQ_16( st->tdm_LRTD_flag, 1 ) && LE_32( st->total_brate, IVAS_16k4 ) ) ) && EQ_16( st->core, TCX_20_CORE ) && LE_32( st->total_brate, MAX_ACELP_BRATE ) ) /* Override TCX in case of LRTD && primary channel has low bitrate*/ { st->core = ACELP_CORE; move16(); } test(); - IF( st->is_ism_format && st->tcxonly ) + if ( st->is_ism_format && st->tcxonly ) { st->core = TCX_20_CORE; move16(); @@ -244,10 +253,17 @@ void ivas_decision_matrix_enc_fx( { st->core = ACELP_CORE; } +#ifdef SUPPORT_FORCE_TCX10_TCX20 + else if ( st->force == FORCE_TCX20 || st->force == FORCE_TCX10 ) /* Initalizations should always happen with TCX20*/ + { + st->core = TCX_20_CORE; + } +#else else if ( st->force == FORCE_TCX ) { st->core = TCX_20_CORE; } +#endif else if ( st->force == FORCE_HQ && st->element_mode != IVAS_CPE_MDCT && element_brate >= IVAS_24k4 ) { st->core = HQ_CORE; @@ -276,7 +292,7 @@ void ivas_decision_matrix_enc_fx( move16(); move16(); - IF( st->low_rate_mode ) + if ( st->low_rate_mode ) { st->coder_type = INACTIVE; move16(); @@ -288,25 +304,36 @@ void ivas_decision_matrix_enc_fx( test(); test(); test(); - IF( st->is_ism_format && st->flag_ACELP16k && !st->low_rate_mode && EQ_16( st->core, ACELP_CORE ) && LT_32( st->total_brate, add( ACELP_16k_LOW_LIMIT, FB_TBE_1k8 ) ) ) + if ( st->is_ism_format && st->flag_ACELP16k && !st->low_rate_mode && st->core == ACELP_CORE && LT_32( st->total_brate, add( ACELP_16k_LOW_LIMIT, FB_TBE_1k8 ) ) ) { st->core = TCX_20_CORE; move16(); } +#ifdef DEBUG_FORCE_DIR + if ( st->force_dir[0] != '\0' ) + { + dbgread( &st->core, sizeof( int16_t ), 1, fname( st->force_dir, "force_core_loc2.enf", -1, -1, -1 ) ); + } + else + { + dbgwrite( &st->core, sizeof( int16_t ), 1, 1, "res/force_core_loc2.enf" ); + } +#endif + /*---------------------------------------------------------------------* * Select ACELP and GSC extension layer *---------------------------------------------------------------------*/ - IF( EQ_16( st->core, ACELP_CORE ) ) + IF( st->core == ACELP_CORE ) { /* WB */ + test(); IF( EQ_16( st->bwidth, WB ) ) { test(); test(); test(); - test(); IF( LT_32( st->total_brate, MIN_BRATE_WB_BWE ) || ( EQ_16( st->idchan, 1 ) && EQ_16( st->element_mode, IVAS_CPE_TD ) ) ) { st->extl = WB_BWE; @@ -316,7 +343,7 @@ void ivas_decision_matrix_enc_fx( { test(); test(); - IF( ( EQ_16( st->sp_aud_decision1, 1 ) && st->sp_aud_decision2 == 0 ) || EQ_16( st->coder_type, INACTIVE ) ) + IF( ( EQ_16( st->sp_aud_decision1, 1 ) && st->sp_aud_decision2 == 0 ) || st->coder_type == INACTIVE ) { st->extl = WB_BWE; move16(); @@ -343,6 +370,19 @@ void ivas_decision_matrix_enc_fx( } } } + +#ifdef DEBUG_FORCE_DIR + if ( st->force_dir[0] != '\0' ) + { + dbgread( &st->extl, sizeof( int16_t ), 1, fname( st->force_dir, "force_extl.enf", -1, -1, -1 ) ); + dbgread( &st->extl_brate, sizeof( int32_t ), 1, fname( st->force_dir, "force_extl_brate.enf", -1, -1, -1 ) ); + } + else + { + dbgwrite( &st->extl, sizeof( int16_t ), 1, 1, "res/force_extl.enf" ); + dbgwrite( &st->extl_brate, sizeof( int32_t ), 1, 1, "res/force_extl_brate.enf" ); + } +#endif } /* SWB and FB */ @@ -361,7 +401,7 @@ void ivas_decision_matrix_enc_fx( test(); test(); test(); - IF( ( ( ( EQ_16( st->sp_aud_decision1, 1 ) && st->sp_aud_decision2 == 0 ) || EQ_16( st->coder_type, INACTIVE ) ) && !st->GSC_noisy_speech ) /* Note: SWB BWE is not used for GSC noisy speech */ ) + IF( ( ( ( EQ_16( st->sp_aud_decision1, 1 ) && st->sp_aud_decision2 == 0 ) || st->coder_type == INACTIVE ) && !st->GSC_noisy_speech ) /* Note: SWB BWE is not used for GSC noisy speech */ ) { st->extl = SWB_BWE; move16(); @@ -423,7 +463,7 @@ void ivas_decision_matrix_enc_fx( test(); test(); - IF( GE_32( st->total_brate, MIN_BRATE_SWB_TBE_2k80 ) && st->flag_ACELP16k && EQ_16( st->element_mode, IVAS_SCE ) ) + if ( GE_32( st->total_brate, MIN_BRATE_SWB_TBE_2k80 ) && st->flag_ACELP16k && EQ_16( st->element_mode, IVAS_SCE ) ) { st->extl_brate = FB_TBE_3k0; move32(); @@ -440,6 +480,19 @@ void ivas_decision_matrix_enc_fx( move32(); } +#ifdef DEBUG_FORCE_DIR + if ( st->force_dir[0] != '\0' ) + { + dbgread( &st->extl, sizeof( int16_t ), 1, fname( st->force_dir, "force_extl.enf", -1, -1, -1 ) ); + dbgread( &st->extl_brate, sizeof( int32_t ), 1, fname( st->force_dir, "force_extl_brate.enf", -1, -1, -1 ) ); + } + else + { + dbgwrite( &st->extl, sizeof( int16_t ), 1, 1, "res/force_extl.enf" ); + dbgwrite( &st->extl_brate, sizeof( int32_t ), 1, 1, "res/force_extl_brate.enf" ); + } +#endif + /* set IC-BWE bitrate */ test(); test(); @@ -448,7 +501,7 @@ void ivas_decision_matrix_enc_fx( icbwe_brate = STEREO_BITS_ICBWE * FRAMES_PER_SEC; move32(); - IF( st->flag_ACELP16k == 0 ) + if ( st->flag_ACELP16k == 0 ) { icbwe_brate = ( STEREO_BITS_ICBWE - STEREO_ICBWE_SPBITS ) * FRAMES_PER_SEC; move32(); @@ -459,7 +512,7 @@ void ivas_decision_matrix_enc_fx( icbwe_brate = STEREO_BITS_ICBWE_DFT * FRAMES_PER_SEC; move32(); - IF( st->flag_ACELP16k == 0 ) + if ( st->flag_ACELP16k == 0 ) { icbwe_brate = ( STEREO_BITS_ICBWE_DFT - STEREO_ICBWE_SPBITS ) * FRAMES_PER_SEC; move32(); @@ -471,9 +524,9 @@ void ivas_decision_matrix_enc_fx( test(); test(); test(); - if ( GE_16( st->element_mode, IVAS_CPE_DFT ) && EQ_16( st->core, ACELP_CORE ) && ( EQ_16( st->extl, SWB_TBE ) || EQ_16( st->extl, FB_TBE ) ) && !( EQ_16( st->element_mode, IVAS_CPE_TD ) && st->tdm_LRTD_flag ) ) + if ( GE_16( st->element_mode, IVAS_CPE_DFT ) && st->core == ACELP_CORE && ( EQ_16( st->extl, SWB_TBE ) || EQ_16( st->extl, FB_TBE ) ) && !( EQ_16( st->element_mode, IVAS_CPE_TD ) && st->tdm_LRTD_flag ) ) { - icbwe_brate = L_add( icbwe_brate, STEREO_ICBWE_MSFLAG_BITS * FRAMES_PER_SEC ); + icbwe_brate = L_add( icbwe_brate, STEREO_ICBWE_MSFLAG_BITS * FRAMES_PER_SEC ); /* Q0 */ move32(); } } @@ -481,19 +534,19 @@ void ivas_decision_matrix_enc_fx( /* set core bitrate */ - st->core_brate = L_sub( L_sub( st->total_brate, st->extl_brate ), icbwe_brate ); + st->core_brate = L_sub( L_sub( st->total_brate, st->extl_brate ), icbwe_brate ); /* Q0 */ move32(); IF( st->ini_frame == 0 ) { /* avoid core switching in the very first frame */ - st->last_core = st->core; + st->last_core = st->core; /* Q0 */ move16(); - st->last_core_brate = st->core_brate; + st->last_core_brate = st->core_brate; /* Q0 */ move32(); - st->last_extl = st->extl; + st->last_extl = st->extl; /* Q0 */ move16(); } @@ -504,7 +557,7 @@ void ivas_decision_matrix_enc_fx( st->inactive_coder_type_flag = 0; /* AVQ by default */ move16(); - IF( LE_32( st->total_brate, MAX_GSC_INACTIVE_BRATE ) ) + if ( LE_32( st->total_brate, MAX_GSC_INACTIVE_BRATE ) ) { st->inactive_coder_type_flag = 1; /* GSC */ move16(); @@ -520,11 +573,11 @@ void ivas_decision_matrix_enc_fx( *---------------------------------------------------------------------*/ void ivas_signaling_enc_fx( - Encoder_State *st, /* i/o: encoder state structure */ - const Word16 MCT_flag, /* i : hMCT handle allocated (1) or not (0) */ - const Word32 element_brate, /* i : element bitrate */ - const Word16 tdm_SM_or_LRTD_Pri, /* i : channel combination scheme flag in TD stereo OR LRTD primary channel */ - const Word16 tdm_Pitch_reuse_flag /* i : primary channel pitch reuse flag in TD stereo */ + Encoder_State *st, /* i/o: encoder state structure */ + const Word16 MCT_flag, /* i : hMCT handle allocated (1) or not (0) Q0*/ + const Word32 element_brate, /* i : element bitrate Q0*/ + const Word16 tdm_SM_or_LRTD_Pri, /* i : channel combination scheme flag in TD stereo OR LRTD primary channel Q0*/ + const Word16 tdm_Pitch_reuse_flag /* i : primary channel pitch reuse flag in TD stereo Q0*/ ) { Word16 ind; @@ -559,7 +612,7 @@ void ivas_signaling_enc_fx( test(); IF( ( EQ_16( st->element_mode, IVAS_CPE_DFT ) || EQ_16( st->element_mode, IVAS_CPE_TD ) ) && !MCT_flag ) /* note: in MCT, the MDCT stereo is used exclusively */ { - ind = sub( st->element_mode, IVAS_CPE_DFT ); + ind = sub( st->element_mode, IVAS_CPE_DFT ); /* Q0 */ push_indice( hBstr, IND_SMODE, ind, NBITS_ELEMENT_MODE ); } @@ -579,7 +632,7 @@ void ivas_signaling_enc_fx( ( LT_32( element_brate, MIN_BRATE_FB_ISM ) && st->is_ism_format ) ) { /* WB and SWB are supported */ - ind = sub( st->bwidth, WB ); + ind = sub( st->bwidth, WB ); /* Q0 */ push_indice( hBstr, IND_BWIDTH, ind, 1 ); } ELSE @@ -597,7 +650,7 @@ void ivas_signaling_enc_fx( test(); IF( EQ_16( st->element_mode, IVAS_CPE_TD ) || GE_32( st->total_brate, STEREO_TCX_MIN_RATE ) ) { - IF( EQ_16( st->core, ACELP_CORE ) ) + IF( st->core == ACELP_CORE ) { push_indice( hBstr, IND_CORE, 0, 1 ); } @@ -611,7 +664,7 @@ void ivas_signaling_enc_fx( * Write core dependent signaling *--------------------------------------------------------------------------*/ - IF( EQ_16( st->core, ACELP_CORE ) ) + IF( st->core == ACELP_CORE ) { /* write coder type */ push_indice( hBstr, IND_ACELP_SIGNALLING, st->coder_type, 3 ); diff --git a/lib_enc/ivas_dirac_enc.c b/lib_enc/ivas_dirac_enc_fx.c similarity index 74% rename from lib_enc/ivas_dirac_enc.c rename to lib_enc/ivas_dirac_enc_fx.c index 51a446d383139b0704527c62aaa3ca7bbc170f4a..ac0ce95566a5adf5c1bd12f7cd54b605a27b6055 100644 --- a/lib_enc/ivas_dirac_enc.c +++ b/lib_enc/ivas_dirac_enc_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other @@ -35,9 +35,7 @@ #include "options.h" #include #include "cnst.h" -#include "prot.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "ivas_prot_fx.h" #include "ivas_cnst.h" #include "ivas_rom_com.h" @@ -53,7 +51,13 @@ static void computeIntensityVector_enc_fx( Word32 Cldfb_ImagBuffer[DIRAC_MAX_ANA_CHANS][DIRAC_NO_FB_BANDS_MAX], const Word16 enc_param_start_band, /* i : first band to process */ const Word16 num_frequency_bands, - Word32 intensity_real[DIRAC_NUM_DIMS][DIRAC_MAX_NBANDS] ); + Word32 intensity_real[DIRAC_NUM_DIMS][DIRAC_MAX_NBANDS] +#ifdef NONBE_IMPROVE_DIRAC_INTENSITY_PREC + , + Word16 q_cldfb, + Word16 q_intensity_real[DIRAC_MAX_NBANDS] +#endif +); /*------------------------------------------------------------------------- * ivas_dirac_enc_open() @@ -82,7 +86,7 @@ ivas_error ivas_dirac_enc_open_fx( { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC Config\n" ) ); } - hDirAC->firstrun_sector_params = 1; + hDirAC->firstrun_sector_params = 1; /* Q0 */ move16(); set32_fx( hDirAC->sec_I_vec_smth_x_fx[0], 0, NUM_ANA_SECTORS * IVAS_MAX_NUM_BANDS ); @@ -101,7 +105,7 @@ ivas_error ivas_dirac_enc_open_fx( st_ivas->hDirAC = hDirAC; - IF( NE_32( ( error = ivas_dirac_config_fx( (void *) st_ivas, ENC ) ), IVAS_ERR_OK ) ) + IF( ( error = ivas_dirac_config_fx( (void *) st_ivas, ENC ) ) != IVAS_ERR_OK ) { return error; } @@ -112,7 +116,7 @@ ivas_error ivas_dirac_enc_open_fx( FOR( i = 0; i < DIRAC_MAX_NBANDS + 1; i++ ) { /* adapt band grouping to from CLDFB to MDFT bands */ - hDirAC->band_grouping[i] = imult1616( hDirAC->band_grouping[i], CLDFB_TO_MDFT_FAC ); + hDirAC->band_grouping[i] = imult1616( hDirAC->band_grouping[i], CLDFB_TO_MDFT_FAC ); /* Q0 */ move16(); } dirac_slot_ns = DIRAC_SLOT_ENC_NS; @@ -139,7 +143,7 @@ ivas_error ivas_dirac_enc_open_fx( Word16 tmp_e = 0; move16(); - Word16 tmp = BASOP_Util_Divide3232_Scale( (Word32) DIRAC_NO_COL_AVG_DIFF_NS, dirac_slot_ns, &tmp_e ); + Word16 tmp = BASOP_Util_Divide3232_Scale( (Word32) DIRAC_NO_COL_AVG_DIFF_NS, dirac_slot_ns, &tmp_e ); /* exp(tmp_e) */ hDirAC->no_col_avg_diff = shr( tmp, sub( 15, tmp_e ) ); move16(); @@ -188,7 +192,7 @@ ivas_error ivas_dirac_enc_open_fx( move16(); st_ivas->hDirAC = hDirAC; - st_ivas->hSpar->enc_param_start_band = st_ivas->hDirAC->hConfig->enc_param_start_band; + st_ivas->hSpar->enc_param_start_band = st_ivas->hDirAC->hConfig->enc_param_start_band; /* Q0 */ move16(); return error; @@ -245,7 +249,7 @@ ivas_error ivas_dirac_enc_reconfigure( *------------------------------------------------------------------------*/ void ivas_dirac_enc_close_fx( DIRAC_ENC_HANDLE *hDirAC_out, /* i/o: encoder DirAC handle */ - const Word32 input_Fs /* i : input sampling rate */ + const Word32 input_Fs /* i : input sampling rate Q0*/ ) { Word16 i, j; @@ -314,15 +318,15 @@ ivas_error ivas_dirac_enc_fx( DIRAC_ENC_HANDLE hDirAC, /* i/o: encoder DirAC handle */ IVAS_QMETADATA_HANDLE hQMetaData, /* i/o: q_metadata handle */ BSTR_ENC_HANDLE hMetaData, /* i/o: Metadata bitstream handle */ - Word32 *data_f_fx[], /* i/o: SBA channels Qx */ - Word32 **pp_fr_real_fx, /* o : real freq domain values pp_fr_q */ - Word32 **pp_fr_imag_fx, /* o : imag freq domain values pp_fr_q */ + Word32 *data_f_fx[], /* i/o: SBA channels Qx*/ + Word32 **pp_fr_real_fx, /* o : real freq domain values pp_fr_q*/ + Word32 **pp_fr_imag_fx, /* o : imag freq domain values pp_fr_q*/ Word16 pp_fr_q, - const Word16 input_frame, /* i : input frame length Q0 */ - const Word16 dtx_vad, /* i : DTX vad flag Q0 */ - const IVAS_FORMAT ivas_format, /* i : ivas format */ - const Word16 hodirac_flag /* i : hodirac flag Q0 */ -) + const Word16 input_frame, /* i : input frame length Q0*/ + const Word16 dtx_vad, /* i : DTX vad flag Q0*/ + const IVAS_FORMAT ivas_format, /* i : ivas format */ + const Word16 hodirac_flag, /* i : hodirac flag Q0*/ + const Word16 shift ) { Word16 orig_dirac_bands; Word32 dir_fx[3], avg_dir_fx[3]; @@ -330,14 +334,24 @@ ivas_error ivas_dirac_enc_fx( ivas_error error; push_wmops( "ivas_dirac_enc" ); - Word16 nchan_fb_in = hodirac_flag ? HOA2_CHANNELS : FOA_CHANNELS; - move16(); + Word16 nchan_fb_in; + + IF( hodirac_flag ) + { + nchan_fb_in = HOA2_CHANNELS; + move16(); + } + ELSE + { + nchan_fb_in = FOA_CHANNELS; + move16(); + } - ivas_dirac_param_est_enc_fx( hDirAC, hQMetaData->q_direction, hQMetaData->useLowerRes, data_f_fx, pp_fr_real_fx, pp_fr_imag_fx, pp_fr_q, input_frame, ivas_format, hodirac_flag, nchan_fb_in, &( hDirAC->mono_frame_count ), &( hQMetaData->dirac_mono_flag ) ); + ivas_dirac_param_est_enc_fx( hDirAC, hQMetaData->q_direction, hQMetaData->useLowerRes, data_f_fx, pp_fr_real_fx, pp_fr_imag_fx, pp_fr_q, input_frame, ivas_format, hodirac_flag, nchan_fb_in, &( hDirAC->mono_frame_count ), &( hQMetaData->dirac_mono_flag ), shift ); IF( hQMetaData->q_direction->cfg.nbands > 0 ) { - orig_dirac_bands = hQMetaData->q_direction[0].cfg.nbands; + orig_dirac_bands = hQMetaData->q_direction[0].cfg.nbands; /* Q0 */ move16(); IF( EQ_16( dtx_vad, 1 ) ) @@ -380,7 +394,7 @@ ivas_error ivas_dirac_enc_fx( } } - IF( NE_32( ( error = ivas_qmetadata_enc_encode_fx( hMetaData, hQMetaData, hodirac_flag ) ), IVAS_ERR_OK ) ) + IF( ( error = ivas_qmetadata_enc_encode_fx( hMetaData, hQMetaData, hodirac_flag ) ) != IVAS_ERR_OK ) { return error; } @@ -405,15 +419,15 @@ ivas_error ivas_dirac_enc_fx( { ivas_qmetadata_azimuth_elevation_to_direction_vector_fx( hQMetaData->q_direction[0].band_data[j].azimuth_fx[i], hQMetaData->q_direction[0].band_data[j].elevation_fx[i], &dir_fx[0] ); - Word32 vecLen_fx = Mpy_32_32( hQMetaData->q_direction[0].band_data[j].energy_ratio_fx[i] /*Q30*/, hDirAC->buffer_energy_fx[i * orig_dirac_bands + j] ); - avg_dir_fx[0] = L_add( avg_dir_fx[0], Mpy_32_32( dir_fx[0], vecLen_fx ) ); // Q30 + hDirAC->buffer_energy_q[i * orig_dirac_bands + j] - 1 - 31 - avg_dir_fx[1] = L_add( avg_dir_fx[1], Mpy_32_32( dir_fx[1], vecLen_fx ) ); // Q30 + hDirAC->buffer_energy_q[i * orig_dirac_bands + j] - 1 - 31 - avg_dir_fx[2] = L_add( avg_dir_fx[2], Mpy_32_32( dir_fx[2], vecLen_fx ) ); // Q30 + hDirAC->buffer_energy_q[i * orig_dirac_bands + j] - 1 - 31 + Word32 vecLen_fx = Mpy_32_32( hQMetaData->q_direction[0].band_data[j].energy_ratio_fx[i] /*Q30*/, hDirAC->buffer_energy_fx[i * orig_dirac_bands + j] ); /* hDirAC->buffer_energy_q[i * orig_dirac_bands + j] - 1 */ + avg_dir_fx[0] = L_add( avg_dir_fx[0], Mpy_32_32( dir_fx[0], vecLen_fx ) ); // Q30 + hDirAC->buffer_energy_q[i * orig_dirac_bands + j] - 1 - 31 + avg_dir_fx[1] = L_add( avg_dir_fx[1], Mpy_32_32( dir_fx[1], vecLen_fx ) ); // Q30 + hDirAC->buffer_energy_q[i * orig_dirac_bands + j] - 1 - 31 + avg_dir_fx[2] = L_add( avg_dir_fx[2], Mpy_32_32( dir_fx[2], vecLen_fx ) ); // Q30 + hDirAC->buffer_energy_q[i * orig_dirac_bands + j] - 1 - 31 move32(); move32(); move32(); avg_dir_e = sub( 31, ( sub( add( Q30, hDirAC->buffer_energy_q[i * orig_dirac_bands + j] ), 1 - 31 ) ) ); - energySum_fx = BASOP_Util_Add_Mant32Exp( energySum_fx, energySum_e, hDirAC->buffer_energy_fx[i * orig_dirac_bands + j], sub( 31, hDirAC->buffer_energy_q[i * orig_dirac_bands + j] ), &energySum_e ); + energySum_fx = BASOP_Util_Add_Mant32Exp( energySum_fx, energySum_e, hDirAC->buffer_energy_fx[i * orig_dirac_bands + j], sub( 31, hDirAC->buffer_energy_q[i * orig_dirac_bands + j] ), &energySum_e ); /* exp(energySum_e) */ } Word16 x = getScaleFactor32( avg_dir_fx, 3 ); @@ -431,16 +445,16 @@ ivas_error ivas_dirac_enc_fx( move16(); Word16 denom_e = 0; move16(); - Word32 denom = BASOP_Util_Add_Mant32Exp( energySum_fx, energySum_e, EPSILON_FX_M, EPSILON_FX_E, &denom_e ); + Word32 denom = BASOP_Util_Add_Mant32Exp( energySum_fx, energySum_e, EPSILON_FX_M, EPSILON_FX_E, &denom_e ); /* exp(denom_e) */ - er_tmp = BASOP_Util_Divide3232_Scale( tmp, denom, &er_tmp_e ); + er_tmp = BASOP_Util_Divide3232_Scale( tmp, denom, &er_tmp_e ); /* exp(er_tmp_e) */ er_tmp_e = add( er_tmp_e, sub( tmp_e, denom_e ) ); er_tmp = shr( er_tmp, sub( 1, ( er_tmp_e ) ) ); // Q14 - hQMetaData->q_direction[0].band_data[0].energy_ratio_fx[i] = L_deposit_h( er_tmp ); // Q30 - hQMetaData->q_direction[0].band_data[1].azimuth_fx[i] = hQMetaData->q_direction[0].band_data[orig_dirac_bands - 1].azimuth_fx[i]; - hQMetaData->q_direction[0].band_data[1].elevation_fx[i] = hQMetaData->q_direction[0].band_data[orig_dirac_bands - 1].elevation_fx[i]; - hQMetaData->q_direction[0].band_data[1].energy_ratio_fx[i] = hQMetaData->q_direction[0].band_data[orig_dirac_bands - 1].energy_ratio_fx[i]; + hQMetaData->q_direction[0].band_data[0].energy_ratio_fx[i] = L_deposit_h( er_tmp ); // Q30 + hQMetaData->q_direction[0].band_data[1].azimuth_fx[i] = hQMetaData->q_direction[0].band_data[orig_dirac_bands - 1].azimuth_fx[i]; // Q22 + hQMetaData->q_direction[0].band_data[1].elevation_fx[i] = hQMetaData->q_direction[0].band_data[orig_dirac_bands - 1].elevation_fx[i]; // Q22 + hQMetaData->q_direction[0].band_data[1].energy_ratio_fx[i] = hQMetaData->q_direction[0].band_data[orig_dirac_bands - 1].energy_ratio_fx[i]; // Q30 move32(); move32(); move32(); @@ -459,19 +473,20 @@ ivas_error ivas_dirac_enc_fx( IF( EQ_16( dtx_vad, 1 ) ) { len = hQMetaData->q_direction[0].cfg.nblocks; + move16(); } ELSE { len = 1; + move16(); } - move16(); FOR( b = hQMetaData->q_direction->cfg.start_band; b < hQMetaData->q_direction->cfg.nbands; b++ ) { FOR( i_ts = 0; i_ts < len; i_ts++ ) { - hQMetaData->q_direction->band_data[b].azimuth_fx[i_ts] = hQMetaData->q_direction->band_data[b].q_azimuth_fx[i_ts]; - hQMetaData->q_direction->band_data[b].elevation_fx[i_ts] = hQMetaData->q_direction->band_data[b].q_elevation_fx[i_ts]; - hQMetaData->q_direction[0].band_data[b].energy_ratio_fx[0] = L_sub( ONE_IN_Q30, diffuseness_reconstructions_fx[hQMetaData->q_direction[0].band_data[b].energy_ratio_index[0]] ); + hQMetaData->q_direction->band_data[b].azimuth_fx[i_ts] = hQMetaData->q_direction->band_data[b].q_azimuth_fx[i_ts]; // Q22 + hQMetaData->q_direction->band_data[b].elevation_fx[i_ts] = hQMetaData->q_direction->band_data[b].q_elevation_fx[i_ts]; // Q22 + hQMetaData->q_direction[0].band_data[b].energy_ratio_fx[0] = L_sub( ONE_IN_Q30, diffuseness_reconstructions_fx[hQMetaData->q_direction[0].band_data[b].energy_ratio_index[0]] ); // Q30 move32(); move32(); move32(); @@ -482,9 +497,9 @@ ivas_error ivas_dirac_enc_fx( { FOR( i = 0; i < MAX_PARAM_SPATIAL_SUBFRAMES; i++ ) { - hQMetaData->q_direction[0].band_data[orig_dirac_bands - 1].azimuth_fx[i] = hQMetaData->q_direction[0].band_data[1].azimuth_fx[0]; - hQMetaData->q_direction[0].band_data[orig_dirac_bands - 1].elevation_fx[i] = hQMetaData->q_direction[0].band_data[1].elevation_fx[0]; - hQMetaData->q_direction[0].band_data[orig_dirac_bands - 1].energy_ratio_fx[i] = hQMetaData->q_direction[0].band_data[1].energy_ratio_fx[0]; + hQMetaData->q_direction[0].band_data[orig_dirac_bands - 1].azimuth_fx[i] = hQMetaData->q_direction[0].band_data[1].azimuth_fx[0]; // Q22 + hQMetaData->q_direction[0].band_data[orig_dirac_bands - 1].elevation_fx[i] = hQMetaData->q_direction[0].band_data[1].elevation_fx[0]; // Q22 + hQMetaData->q_direction[0].band_data[orig_dirac_bands - 1].energy_ratio_fx[i] = hQMetaData->q_direction[0].band_data[1].energy_ratio_fx[0]; // Q30 move32(); move32(); move32(); @@ -494,16 +509,16 @@ ivas_error ivas_dirac_enc_fx( { FOR( j = sub( orig_dirac_bands, 2 ); j >= 0; j-- ) { - hQMetaData->q_direction[0].band_data[j].azimuth_fx[i] = hQMetaData->q_direction[0].band_data[0].azimuth_fx[0]; - hQMetaData->q_direction[0].band_data[j].elevation_fx[i] = hQMetaData->q_direction[0].band_data[0].elevation_fx[0]; - hQMetaData->q_direction[0].band_data[j].energy_ratio_fx[i] = hQMetaData->q_direction[0].band_data[0].energy_ratio_fx[0]; + hQMetaData->q_direction[0].band_data[j].azimuth_fx[i] = hQMetaData->q_direction[0].band_data[0].azimuth_fx[0]; // Q22 + hQMetaData->q_direction[0].band_data[j].elevation_fx[i] = hQMetaData->q_direction[0].band_data[0].elevation_fx[0]; // Q22 + hQMetaData->q_direction[0].band_data[j].energy_ratio_fx[i] = hQMetaData->q_direction[0].band_data[0].energy_ratio_fx[0]; // Q30 move32(); move32(); move32(); } } - hQMetaData->q_direction->cfg.nbands = orig_dirac_bands; + hQMetaData->q_direction->cfg.nbands = orig_dirac_bands; /* Q0 */ move16(); } } @@ -521,12 +536,12 @@ ivas_error ivas_dirac_enc_fx( *-------------------------------------------------------------------------*/ static Word16 ivas_dirac_get_mono_flag_fx( - const Word16 *band_grouping, /* i : Band grouping for estimation */ - Word32 Cldfb_RealBuffer[DIRAC_MAX_ANA_CHANS][DIRAC_NO_FB_BANDS_MAX], /* i : Real part of input signal */ - Word32 Cldfb_ImagBuffer[DIRAC_MAX_ANA_CHANS][DIRAC_NO_FB_BANDS_MAX], /* i : Imag part of input signal */ - Word16 e_Cldfb, /* i : Exponent of cldfb buffer */ - const Word16 nchan_ana, /* i : number of analysis channels */ - Word16 *mono_frame_count ) /* i/o: current number of mono frames count */ + const Word16 *band_grouping, /* i : Band grouping for estimation Q0*/ + Word32 Cldfb_RealBuffer[DIRAC_MAX_ANA_CHANS][DIRAC_NO_FB_BANDS_MAX], /* i : Real part of input signal e_Cldfb*/ + Word32 Cldfb_ImagBuffer[DIRAC_MAX_ANA_CHANS][DIRAC_NO_FB_BANDS_MAX], /* i : Imag part of input signal e_Cldfb*/ + Word16 e_Cldfb, /* i : Exponent of cldfb buffer */ + const Word16 nchan_ana, /* i : number of analysis channels Q0*/ + Word16 *mono_frame_count ) /* i/o: current number of mono frames count Q0*/ { Word16 brange[2]; Word16 i, j, ch_idx; @@ -554,8 +569,8 @@ static Word16 ivas_dirac_get_mono_flag_fx( move32(); move32(); - brange[0] = band_grouping[i]; - brange[1] = band_grouping[i + 1]; + brange[0] = band_grouping[i]; /* Q0 */ + brange[1] = band_grouping[i + 1]; /* Q0 */ move16(); move16(); @@ -568,29 +583,33 @@ static Word16 ivas_dirac_get_mono_flag_fx( move16(); move16(); + Word16 gb = find_guarded_bits_fx( sub( brange[1], brange[0] ) ); + /* Loop over the W channel bins to calculate the power in the band */ FOR( j = brange[0]; j < brange[1]; j++ ) { - acc = W_mac_32_32( acc, Cldfb_RealBuffer[0][j], Cldfb_RealBuffer[0][j] ); - acc = W_mac_32_32( acc, Cldfb_ImagBuffer[0][j], Cldfb_ImagBuffer[0][j] ); - shift1 = W_norm( acc ); - W_band_power = W_extract_h( W_shl( acc, shift1 ) ); - W_band_power_e = sub( imult1616( (Word16) 2, e_Cldfb ), shift1 ); + acc = W_mac_32_32( acc, L_shr( Cldfb_RealBuffer[0][j], gb ), L_shr( Cldfb_RealBuffer[0][j], gb ) ); /*Q:(2*(31-e_Cldfb-gb)+1*/ + acc = W_mac_32_32( acc, L_shr( Cldfb_ImagBuffer[0][j], gb ), L_shr( Cldfb_ImagBuffer[0][j], gb ) ); /*Q:(2*(31-e_Cldfb-gb)+1*/ } + shift1 = W_norm( acc ); + W_band_power = W_extract_h( W_shl( acc, shift1 ) ); /*Q:(2*(31-e_Cldfb-gb)+1+shift1-32*/ + W_band_power_e = sub( shl( add( e_Cldfb, gb ), 1 ), shift1 ); + gb = find_guarded_bits_fx( imult1616( sub( brange[1], brange[0] ), sub( nchan_ana, 1 ) ) ); /* Loop over the other channels and bins to calculate the power in the band */ FOR( ch_idx = 1; ch_idx < nchan_ana; ch_idx++ ) { /* abs()^2 */ FOR( j = brange[0]; j < brange[1]; j++ ) { - acc1 = W_mac_32_32( acc1, Cldfb_RealBuffer[ch_idx][j], Cldfb_RealBuffer[ch_idx][j] ); - acc1 = W_mac_32_32( acc1, Cldfb_ImagBuffer[ch_idx][j], Cldfb_ImagBuffer[ch_idx][j] ); - shift2 = W_norm( acc1 ); - other_ch_band_power = W_extract_h( W_shl( acc1, shift2 ) ); - other_ch_band_power_e = sub( imult1616( (Word16) 2, e_Cldfb ), shift2 ); + acc1 = W_mac_32_32( acc1, L_shr( Cldfb_RealBuffer[ch_idx][j], gb ), L_shr( Cldfb_RealBuffer[ch_idx][j], gb ) ); /*Q:(2*(31-e_Cldfb-gb)+1*/ + acc1 = W_mac_32_32( acc1, L_shr( Cldfb_ImagBuffer[ch_idx][j], gb ), L_shr( Cldfb_ImagBuffer[ch_idx][j], gb ) ); /*Q:(2*(31-e_Cldfb-gb)+1*/ } } + shift2 = W_norm( acc1 ); + other_ch_band_power = W_extract_h( W_shl( acc1, shift2 ) ); /*Q:(2*(31-e_Cldfb-gb)+1+shift2-32*/ + other_ch_band_power_e = sub( shl( add( e_Cldfb, gb ), 1 ), shift2 ); + IF( BASOP_Util_Cmp_Mant32Exp( other_ch_band_power, other_ch_band_power_e, EPSILON_FX_M, EPSILON_FX_E ) < 0 ) { if ( BASOP_Util_Cmp_Mant32Exp( W_band_power, W_band_power_e, DIRAC_MONO_THRESH_SILENCE_FX, 31 ) > 0 ) @@ -606,7 +625,7 @@ static Word16 ivas_dirac_get_mono_flag_fx( { Word16 tmp_div_e = 0; move16(); - Word16 tmp_div = BASOP_Util_Divide3232_Scale( W_band_power, DIRAC_MONO_NORM_FACTOR_M, &tmp_div_e ); + Word16 tmp_div = BASOP_Util_Divide3232_Scale( W_band_power, DIRAC_MONO_NORM_FACTOR_M, &tmp_div_e ); /* exp(tmp_div_e) */ tmp_div_e = add( tmp_div_e, sub( W_band_power_e, DIRAC_MONO_NORM_FACTOR_E ) ); Word16 W_band_power_norm_e = 0; move16(); @@ -681,7 +700,7 @@ static Word16 ivas_dirac_get_mono_flag_fx( { IF( LT_16( *mono_frame_count, DIRAC_MONO_FRAME_THRESH ) ) { - *mono_frame_count = add( *mono_frame_count, 1 ); + *mono_frame_count = add( *mono_frame_count, 1 ); /* Q0 */ move16(); } } @@ -714,18 +733,18 @@ static Word16 ivas_dirac_get_mono_flag_fx( void computeReferencePower_enc_fx_dirac( const Word16 *band_grouping, /* i : Band grouping for estimation */ - Word32 Cldfb_RealBuffer[][DIRAC_NO_FB_BANDS_MAX], /* i : Real part of input signal */ - Word32 Cldfb_ImagBuffer[][DIRAC_NO_FB_BANDS_MAX], /* i : Imag part of input signal */ + Word32 Cldfb_RealBuffer[][DIRAC_NO_FB_BANDS_MAX], /* i : Real part of input signal e_Cldfb*/ + Word32 Cldfb_ImagBuffer[][DIRAC_NO_FB_BANDS_MAX], /* i : Imag part of input signal e_Cldfb*/ Word16 e_Cldfb, /* i : exponent of Cldfb buffer */ - Word32 *reference_power, /* o : Estimated power */ + Word32 *reference_power, /* o : Estimated power e_reference*/ Word16 *e_reference, /* o : exponent of reference_power */ - const Word16 enc_param_start_band, /* i : first band to process */ - const Word16 num_freq_bands, /* i : Number of frequency bands */ + const Word16 enc_param_start_band, /* i : first band to process Q0*/ + const Word16 num_freq_bands, /* i : Number of frequency bands Q0*/ const IVAS_FORMAT ivas_format, /* i : ivas_format */ - Word16 ref_power_w, /* i : use 0 if hodirac is enabled */ - const Word16 nchan_ana, /* i : number of analysis channels */ - Word16 *mono_frame_count, /* i/o: Mono Frame Count */ - Word16 *dirac_mono_flag /* i/o: Mono Flag */ + Word16 ref_power_w, /* i : use 0 if hodirac is enabled Q0*/ + const Word16 nchan_ana, /* i : number of analysis channels Q0*/ + Word16 *mono_frame_count, /* i/o: Mono Frame Count Q0*/ + Word16 *dirac_mono_flag /* i/o: Mono Flag Q0*/ ) { Word16 brange[2]; @@ -739,10 +758,24 @@ void computeReferencePower_enc_fx_dirac( IF( dirac_mono_flag != NULL ) { - *dirac_mono_flag = ivas_dirac_get_mono_flag_fx( band_grouping, Cldfb_RealBuffer, Cldfb_ImagBuffer, e_Cldfb, nchan_ana, mono_frame_count ); + *dirac_mono_flag = ivas_dirac_get_mono_flag_fx( band_grouping, Cldfb_RealBuffer, Cldfb_ImagBuffer, e_Cldfb, nchan_ana, mono_frame_count ); /* Q0 */ move16(); } - +#ifdef FIX_1127_IMPROVE_SBA_MLD + Word16 gb = 0; + move16(); + FOR( i = 0; i < num_freq_bands; i++ ) + { + brange[0] = band_grouping[i + enc_param_start_band]; + brange[1] = band_grouping[i + enc_param_start_band + 1]; + move16(); + move16(); + gb = s_max( gb, find_guarded_bits_fx( sub( brange[1], brange[0] ) ) ); + } + e_reference_W = sub( 31, sub( add( shl( sub( 31, e_Cldfb ), 1 ), 1 ), gb ) ); + e_reference_temp = e_reference_W; +#endif + move16(); FOR( i = 0; i < num_freq_bands; i++ ) { brange[0] = band_grouping[i + enc_param_start_band]; @@ -758,14 +791,18 @@ void computeReferencePower_enc_fx_dirac( FOR( j = brange[0]; j < brange[1]; j++ ) { +#ifdef FIX_1127_IMPROVE_SBA_MLD + reference_power_W[i] = W_add( reference_power_W[i], W_shr( W_mult_32_32( Cldfb_RealBuffer[0][j], Cldfb_RealBuffer[0][j] ), gb ) ); /* exp(2 * e_Cldfb) */ + reference_power_W[i] = W_add( reference_power_W[i], W_shr( W_mult_32_32( Cldfb_ImagBuffer[0][j], Cldfb_ImagBuffer[0][j] ), gb ) ); /* exp(2 * e_Cldfb) */ +#else reference_power_W[i] = W_mac_32_32( reference_power_W[i], Cldfb_RealBuffer[0][j], Cldfb_RealBuffer[0][j] ); reference_power_W[i] = W_mac_32_32( reference_power_W[i], Cldfb_ImagBuffer[0][j], Cldfb_ImagBuffer[0][j] ); + e_reference_W = imult1616( (Word16) 2, e_Cldfb ); +#endif move64(); move64(); - - e_reference_W = imult1616( (Word16) 2, e_Cldfb ); } - reference_power_temp[i] = W_add( reference_power_temp[i], reference_power_W[i] ); + reference_power_temp[i] = W_add( reference_power_temp[i], reference_power_W[i] ); /* exp(2 * e_Cldfb) */ move64(); FOR( ch_idx = 1; ch_idx < nchan_ana; ch_idx++ ) @@ -773,19 +810,23 @@ void computeReferencePower_enc_fx_dirac( /* abs()^2 */ FOR( j = brange[0]; j < brange[1]; j++ ) { +#ifdef FIX_1127_IMPROVE_SBA_MLD + reference_power_temp[i] = W_add( reference_power_temp[i], W_shr( W_mult_32_32( Cldfb_RealBuffer[ch_idx][j], Cldfb_RealBuffer[ch_idx][j] ), gb ) ); /* exp(2 * e_Cldfb) */ + reference_power_temp[i] = W_add( reference_power_temp[i], W_shr( W_mult_32_32( Cldfb_ImagBuffer[ch_idx][j], Cldfb_ImagBuffer[ch_idx][j] ), gb ) ); /* exp(2 * e_Cldfb) */ +#else reference_power_temp[i] = W_mac_32_32( reference_power_temp[i], Cldfb_RealBuffer[ch_idx][j], Cldfb_RealBuffer[ch_idx][j] ); reference_power_temp[i] = W_mac_32_32( reference_power_temp[i], Cldfb_ImagBuffer[ch_idx][j], Cldfb_ImagBuffer[ch_idx][j] ); + e_reference_temp = imult1616( (Word16) 2, e_Cldfb ); +#endif move64(); move64(); - - e_reference_temp = imult1616( (Word16) 2, e_Cldfb ); } } } FOR( i = 0; i < num_freq_bands; i++ ) { - reference_power_temp[i] = W_shr( reference_power_temp[i], 1 ); + reference_power_temp[i] = W_shr( reference_power_temp[i], 1 ); /* exp(2 * e_Cldfb + 1) */ move64(); } @@ -796,39 +837,35 @@ void computeReferencePower_enc_fx_dirac( { IF( BASOP_Util_Cmp_Mant32Exp( W_extract_h( reference_power_temp[i] ), e_reference_temp, W_extract_h( reference_power_W[i] ), e_reference_W ) < 0 ) { - reference_power_temp[i] = reference_power_W[i]; + reference_power_temp[i] = reference_power_W[i]; /* exp(2 * e_Cldfb + 1 ) */ move64(); } } } - min_norm = W_norm( reference_power_temp[0] ); - FOR( i = 0; i < num_freq_bands; i++ ) - { - min_norm = s_min( min_norm, W_norm( reference_power_temp[i] ) ); // Finding minimum norm for the right shifting of entire buffer - } - FOR( i = 0; i < num_freq_bands; i++ ) { + min_norm = W_norm( reference_power_temp[i] ); reference_power[i] = W_extract_h( W_shl( reference_power_temp[i], min_norm ) ); // Right shift with min_norm and extract high bits move32(); + e_reference[i] = sub( 31, sub( add( sub( 31, e_reference_temp ), min_norm ), 32 ) ); + move16(); } - *e_reference = sub( e_reference_temp, min_norm ); move16(); return; } void computeReferencePower_enc_fx( - const Word16 *band_grouping, /* i : Band grouping for estimation */ - Word32 Cldfb_RealBuffer[][DIRAC_NO_FB_BANDS_MAX], /* i : Real part of input signal */ - Word32 Cldfb_ImagBuffer[][DIRAC_NO_FB_BANDS_MAX], /* i : Imag part of input signal */ - Word32 *reference_power, /* o : Estimated power */ - const Word16 enc_param_start_band, /* i : first band to process */ - const Word16 num_freq_bands, /* i : Number of frequency bands */ + const Word16 *band_grouping, /* i : Band grouping for estimation Q0*/ + Word32 Cldfb_RealBuffer[][DIRAC_NO_FB_BANDS_MAX], /* i : Real part of input signal inp_q*/ + Word32 Cldfb_ImagBuffer[][DIRAC_NO_FB_BANDS_MAX], /* i : Imag part of input signal inp_q*/ + Word32 *reference_power, /* o : Estimated power ref_exp*/ + const Word16 enc_param_start_band, /* i : first band to process Q0*/ + const Word16 num_freq_bands, /* i : Number of frequency bands Q0*/ const IVAS_FORMAT ivas_format, /* i : ivas_format */ - Word16 ref_power_w, /* i : use 0 if hodirac is enabled */ - const Word16 nchan_ana, /* i : number of analysis channels */ + Word16 ref_power_w, /* i : use 0 if hodirac is enabled Q0*/ + const Word16 nchan_ana, /* i : number of analysis channels Q0*/ Word16 inp_q, /* i : q of cld buffers */ Word16 *ref_exp /* i : output q */ ) @@ -842,9 +879,9 @@ void computeReferencePower_enc_fx( Word64 reference_power_W[DIRAC_MAX_NBANDS]; FOR( i = 0; i < num_freq_bands; i++ ) { - brange[0] = band_grouping[i + enc_param_start_band]; + brange[0] = band_grouping[i + enc_param_start_band]; /* Q0 */ move16(); - brange[1] = band_grouping[i + enc_param_start_band + 1]; + brange[1] = band_grouping[i + enc_param_start_band + 1]; /* Q0 */ move16(); reference_power[i] = 0; move32(); @@ -884,7 +921,7 @@ void computeReferencePower_enc_fx( { IF( LT_64( reference_power_tmp[i], reference_power_W[i] ) ) { - reference_power_tmp[i] = reference_power_W[i]; + reference_power_tmp[i] = reference_power_W[i]; // 2*inp_q + 1 move64(); } } @@ -914,17 +951,18 @@ void computeReferencePower_enc_fx( void ivas_dirac_param_est_enc_fx( DIRAC_ENC_HANDLE hDirAC, IVAS_QDIRECTION *q_direction, - const UWord8 useLowerRes, - Word32 *data_f_fx[], - Word32 **pp_fr_real_fx, - Word32 **pp_fr_imag_fx, + const UWord8 useLowerRes, /* Q0 */ + Word32 *data_f_fx[], /* Qx */ + Word32 **pp_fr_real_fx, /* pp_fr_q */ + Word32 **pp_fr_imag_fx, /* pp_fr_q */ Word16 pp_fr_q, - const Word16 input_frame, + const Word16 input_frame, /* Q0 */ const IVAS_FORMAT ivas_format, - const Word16 hodirac_flag, - const Word16 nchan_fb_in, - Word16 *mono_frame_count, - Word16 *dirac_mono_flag ) + const Word16 hodirac_flag, /* Q0 */ + const Word16 nchan_fb_in, /* Q0 */ + Word16 *mono_frame_count, /* Q0 */ + Word16 *dirac_mono_flag, /* Q0 */ + const Word16 shift ) { Word16 i, j, k, d, ts, index, l_ts, num_freq_bands; Word16 band_m_idx, block_m_idx; @@ -936,13 +974,17 @@ void ivas_dirac_param_est_enc_fx( Word32 *p_Cldfb_ImagBuffer_fx[DIRAC_MAX_ANA_CHANS]; Word16 cldfb_q; Word32 intensity_real_fx[DIRAC_NUM_DIMS][DIRAC_MAX_NBANDS]; +#ifdef NONBE_IMPROVE_DIRAC_INTENSITY_PREC + Word16 intensity_real_q[DIRAC_MAX_NBANDS]; +#else Word16 intensity_real_q; +#endif Word32 direction_vector_fx[DIRAC_NUM_DIMS][DIRAC_MAX_NBANDS]; Word16 direction_vector_q; Word32 diffuseness_vector_fx[DIRAC_MAX_NBANDS]; Word16 diffuseness_vector_q; Word32 renormalization_factor_fx[DIRAC_MAX_NBANDS]; - Word16 renormalization_factor_exp; + Word16 renormalization_factor_exp[DIRAC_MAX_NBANDS]; Word32 renormalization_factor_diff_fx[DIRAC_MAX_NBANDS]; Word16 renormalization_factor_diff_exp[DIRAC_MAX_NBANDS]; Word32 norm_tmp_fx; @@ -950,7 +992,7 @@ void ivas_dirac_param_est_enc_fx( Word16 mrange[2]; Word16 num_blocks; Word32 reference_power_fx[CLDFB_NO_COL_MAX][DIRAC_NO_FB_BANDS_MAX]; - Word16 reference_power_exp; + Word16 reference_power_exp[CLDFB_NO_COL_MAX][DIRAC_NO_FB_BANDS_MAX]; Word32 azi_secs_fx[2 * DIRAC_MAX_ANA_CHANS * DIRAC_MAX_NBANDS]; Word32 ele_secs_fx[2 * DIRAC_MAX_ANA_CHANS * DIRAC_MAX_NBANDS]; Word32 diff_secs_fx[2 * DIRAC_MAX_ANA_CHANS * DIRAC_MAX_NBANDS]; @@ -959,20 +1001,24 @@ void ivas_dirac_param_est_enc_fx( Word16 ene_secs_exp[2 * DIRAC_MAX_ANA_CHANS * DIRAC_MAX_NBANDS]; push_wmops( "dirac_enc_param_est" ); - num_freq_bands = hDirAC->hConfig->nbands; + num_freq_bands = hDirAC->hConfig->nbands; /* Q0 */ move16(); /* Initialization */ cldfb_q = 0; move16(); + +#ifndef NONBE_IMPROVE_DIRAC_INTENSITY_PREC intensity_real_q = 0; move16(); +#endif + direction_vector_q = 0; move16(); diffuseness_vector_q = 0; move16(); - l_ts = idiv1616( input_frame, MAX_PARAM_SPATIAL_SUBFRAMES ); + l_ts = idiv1616( input_frame, MAX_PARAM_SPATIAL_SUBFRAMES ); /* Q0 */ IF( useLowerRes ) { q_direction->cfg.nblocks = 1; @@ -993,8 +1039,10 @@ void ivas_dirac_param_est_enc_fx( set16_zero_fx( hDirAC->diffuseness_m_exp, hDirAC->hConfig->nbands ); set_zero_fx( renormalization_factor_diff_fx, hDirAC->hConfig->nbands ); set16_zero_fx( renormalization_factor_diff_exp, hDirAC->hConfig->nbands ); - reference_power_exp = 0; - move16(); + FOR( i = 0; i < CLDFB_NO_COL_MAX; i++ ) + { + set16_zero_fx( reference_power_exp[i], DIRAC_NO_FB_BANDS_MAX ); + } set_zero_fx( azi_secs_fx, 2 * DIRAC_MAX_ANA_CHANS * DIRAC_MAX_NBANDS ); set_zero_fx( ele_secs_fx, 2 * DIRAC_MAX_ANA_CHANS * DIRAC_MAX_NBANDS ); @@ -1014,17 +1062,26 @@ void ivas_dirac_param_est_enc_fx( /* do processing over all CLDFB time slots */ FOR( block_m_idx = 0; block_m_idx < num_blocks; block_m_idx++ ) { - mrange[0] = hDirAC->block_grouping[block_m_idx]; + mrange[0] = hDirAC->block_grouping[block_m_idx]; /* Q0 */ move16(); - mrange[1] = hDirAC->block_grouping[add( block_m_idx, 1 )]; + mrange[1] = hDirAC->block_grouping[block_m_idx + 1]; move16(); set32_fx( renormalization_factor_fx, EPSILON_FX, hDirAC->hConfig->nbands ); - renormalization_factor_exp = 0; - move16(); + set16_fx( renormalization_factor_exp, 0, hDirAC->hConfig->nbands ); set_zero_fx( hDirAC->direction_vector_m_fx[0][block_m_idx], hDirAC->hConfig->nbands ); set_zero_fx( hDirAC->direction_vector_m_fx[1][block_m_idx], hDirAC->hConfig->nbands ); set_zero_fx( hDirAC->direction_vector_m_fx[2][block_m_idx], hDirAC->hConfig->nbands ); + Word64 dir[DIRAC_NUM_DIMS][DIRAC_MAX_NBANDS]; + Word16 direction_vector_exp_tmp[DIRAC_NUM_DIMS][MAX_PARAM_SPATIAL_SUBFRAMES][DIRAC_MAX_NBANDS] = { 0 }; + FOR( i = 0; i < DIRAC_NUM_DIMS; i++ ) + { + set64_fx( dir[i], 0, DIRAC_MAX_NBANDS ); + FOR( j = 0; j < MAX_PARAM_SPATIAL_SUBFRAMES; j++ ) + { + set16_fx( direction_vector_exp_tmp[i][j], 0, DIRAC_MAX_NBANDS ); + } + } hDirAC->direction_vector_m_exp[block_m_idx] = 0; move16(); @@ -1032,8 +1089,17 @@ void ivas_dirac_param_est_enc_fx( { IF( hDirAC->hFbMixer ) { + FOR( i = 0; i < nchan_fb_in; i++ ) + { + scale_sig32( pcm_in_fx[i], input_frame, shift ); // Q:Qx+shift + scale_sig32( hDirAC->hFbMixer->ppFilterbank_prior_input_fx[i], hDirAC->hFbMixer->fb_cfg->prior_input_length, shift ); // Q:Qx+shift + } ivas_fb_mixer_get_windowed_fr_fx( hDirAC->hFbMixer, pcm_in_fx, p_Cldfb_RealBuffer_fx, p_Cldfb_ImagBuffer_fx, l_ts, l_ts, hDirAC->hFbMixer->fb_cfg->num_in_chans, 0 ); - + FOR( i = 0; i < nchan_fb_in; i++ ) + { + scale_sig32( pcm_in_fx[i], input_frame, negate( shift ) ); // Q:Qx + scale_sig32( hDirAC->hFbMixer->ppFilterbank_prior_input_fx[i], hDirAC->hFbMixer->fb_cfg->prior_input_length, negate( shift ) ); // Q:Qx + } ivas_fb_mixer_update_prior_input_fx( hDirAC->hFbMixer, pcm_in_fx, l_ts, hDirAC->hFbMixer->fb_cfg->num_in_chans ); FOR( i = 0; i < nchan_fb_in; i++ ) @@ -1045,8 +1111,8 @@ void ivas_dirac_param_est_enc_fx( { FOR( i = 0; i < nchan_fb_in; i++ ) { - Copy32( &pp_fr_real_fx[i][imult1616( ts, l_ts )], Cldfb_RealBuffer_fx[i], l_ts ); - Copy32( &pp_fr_imag_fx[i][imult1616( ts, l_ts )], Cldfb_ImagBuffer_fx[i], l_ts ); + Copy32( &pp_fr_real_fx[i][ts * l_ts], Cldfb_RealBuffer_fx[i], l_ts ); /* pp_fr_q */ + Copy32( &pp_fr_imag_fx[i][ts * l_ts], Cldfb_ImagBuffer_fx[i], l_ts ); /* pp_fr_q */ } cldfb_q = pp_fr_q; move16(); @@ -1054,7 +1120,7 @@ void ivas_dirac_param_est_enc_fx( Word16 ref_power_w = 1; move16(); - IF( hodirac_flag ) + if ( hodirac_flag ) { ref_power_w = 0; move16(); @@ -1066,7 +1132,7 @@ void ivas_dirac_param_est_enc_fx( Cldfb_ImagBuffer_fx, sub( 31, cldfb_q ), reference_power_fx[ts], - &reference_power_exp, + reference_power_exp[ts], hDirAC->hConfig->enc_param_start_band, num_freq_bands, ivas_format, @@ -1081,10 +1147,16 @@ void ivas_dirac_param_est_enc_fx( Cldfb_ImagBuffer_fx, hDirAC->hConfig->enc_param_start_band, num_freq_bands, - intensity_real_fx ); - + intensity_real_fx +#ifdef NONBE_IMPROVE_DIRAC_INTENSITY_PREC + , + cldfb_q, + intensity_real_q +#endif + ); +#ifndef NONBE_IMPROVE_DIRAC_INTENSITY_PREC intensity_real_q = sub( shl( cldfb_q, 1 ), 31 ); // 2 * Q_Cldfb + 1 - 32; - +#endif IF( !hodirac_flag ) { computeDirectionVectors_fixed( @@ -1095,26 +1167,41 @@ void ivas_dirac_param_est_enc_fx( num_freq_bands, direction_vector_fx[0], direction_vector_fx[1], - direction_vector_fx[2], - sub( 31, intensity_real_q ) ); + direction_vector_fx[2] +#ifdef NONBE_IMPROVE_DIRAC_INTENSITY_PREC + , + 31, intensity_real_q +#else + , + sub( 31, intensity_real_q ) +#endif + ); direction_vector_q = Q30; move16(); } /* fill buffers of length "averaging_length" time slots for intensity and energy */ - hDirAC->index_buffer_intensity = add( ( hDirAC->index_buffer_intensity % hDirAC->no_col_avg_diff ), 1 ); /* averaging_length = 32 */ + hDirAC->index_buffer_intensity = add( ( hDirAC->index_buffer_intensity % hDirAC->no_col_avg_diff ), 1 ); /* averaging_length = 32 Q0*/ move16(); - index = hDirAC->index_buffer_intensity; + index = hDirAC->index_buffer_intensity; /* Q0 */ move16(); FOR( i = 0; i < DIRAC_NUM_DIMS; i++ ) { /* only real part needed */ - Copy32( intensity_real_fx[i], &( hDirAC->buffer_intensity_real_fx[i][index - 1][0] ), num_freq_bands ); + Copy32( intensity_real_fx[i], &( hDirAC->buffer_intensity_real_fx[i][index - 1][0] ), num_freq_bands ); /* intensity_real_q */ +#ifdef NONBE_IMPROVE_DIRAC_INTENSITY_PREC + Copy( intensity_real_q, &hDirAC->buffer_intensity_real_q[i][index - 1][0], num_freq_bands ); +#else set16_fx( &hDirAC->buffer_intensity_real_q[i][index - 1][0], intensity_real_q, num_freq_bands ); +#endif + } + Copy32( reference_power_fx[ts], &( hDirAC->buffer_energy_fx[( index - 1 ) * num_freq_bands] ), num_freq_bands ); /* exp(reference_power_exp) */ + FOR( i = 0; i < num_freq_bands; i++ ) + { + hDirAC->buffer_energy_q[( index - 1 ) * num_freq_bands + i] = sub( 31, reference_power_exp[ts][i] ); + move16(); } - Copy32( reference_power_fx[ts], &( hDirAC->buffer_energy_fx[( index - 1 ) * num_freq_bands] ), num_freq_bands ); - set16_fx( &hDirAC->buffer_energy_q[( index - 1 ) * num_freq_bands], sub( 31, reference_power_exp ), num_freq_bands ); Word16 buffer_intensity_real_single_q; buffer_intensity_real_single_q = hDirAC->buffer_intensity_real_q[0][0][0]; @@ -1135,7 +1222,7 @@ void ivas_dirac_param_est_enc_fx( { FOR( k = 0; k < num_freq_bands; k++ ) { - hDirAC->buffer_intensity_real_fx[i][j][k] = L_shl( hDirAC->buffer_intensity_real_fx[i][j][k], sub( buffer_intensity_real_single_q, hDirAC->buffer_intensity_real_q[i][j][k] ) ); + hDirAC->buffer_intensity_real_fx[i][j][k] = L_shl( hDirAC->buffer_intensity_real_fx[i][j][k], sub( buffer_intensity_real_single_q, hDirAC->buffer_intensity_real_q[i][j][k] ) ); /* buffer_intensity_real_single_q */ move32(); hDirAC->buffer_intensity_real_q[i][j][k] = buffer_intensity_real_single_q; move16(); @@ -1149,7 +1236,7 @@ void ivas_dirac_param_est_enc_fx( minimum_fx( hDirAC->buffer_energy_q, buffer_len, &buffer_energy_single_q ); FOR( i = 0; i < buffer_len; i++ ) { - hDirAC->buffer_energy_fx[i] = L_shl( hDirAC->buffer_energy_fx[i], sub( buffer_energy_single_q, hDirAC->buffer_energy_q[i] ) ); + hDirAC->buffer_energy_fx[i] = L_shl( hDirAC->buffer_energy_fx[i], sub( buffer_energy_single_q, hDirAC->buffer_energy_q[i] ) ); /* buffer_energy_single_q */ move32(); hDirAC->buffer_energy_q[i] = buffer_energy_single_q; move16(); @@ -1182,17 +1269,15 @@ void ivas_dirac_param_est_enc_fx( ene_secs_exp ); } - const Word16 gbits = 4; // 4 guard bits - move16(); IF( hodirac_flag ) { FOR( band_m_idx = 0; band_m_idx < hDirAC->hConfig->nbands; band_m_idx++ ) { Word32 tmp_diff = L_shr( diffuseness_vector_fx[band_m_idx], sub( diffuseness_vector_q, 30 ) ); // diffueseness_vector_q -> Q30 hDirAC->diffuseness_m_fx[band_m_idx] = BASOP_Util_Add_Mant32Exp( hDirAC->diffuseness_m_fx[band_m_idx], hDirAC->diffuseness_m_exp[band_m_idx], - Mpy_32_32( reference_power_fx[ts][band_m_idx], tmp_diff ), add( reference_power_exp, 1 ), &hDirAC->diffuseness_m_exp[band_m_idx] ); + Mpy_32_32( reference_power_fx[ts][band_m_idx], tmp_diff ), add( reference_power_exp[ts][band_m_idx], 1 ), &hDirAC->diffuseness_m_exp[band_m_idx] ); /* exp(hDirAC->diffuseness_m_exp) */ move32(); - renormalization_factor_diff_fx[band_m_idx] = BASOP_Util_Add_Mant32Exp( renormalization_factor_diff_fx[band_m_idx], renormalization_factor_diff_exp[band_m_idx], reference_power_fx[ts][band_m_idx], reference_power_exp, &renormalization_factor_diff_exp[band_m_idx] ); + renormalization_factor_diff_fx[band_m_idx] = BASOP_Util_Add_Mant32Exp( renormalization_factor_diff_fx[band_m_idx], renormalization_factor_diff_exp[band_m_idx], reference_power_fx[ts][band_m_idx], reference_power_exp[ts][band_m_idx], &renormalization_factor_diff_exp[band_m_idx] ); /* exp(renormalization_factor_diff_exp) */ move32(); } } @@ -1201,27 +1286,48 @@ void ivas_dirac_param_est_enc_fx( FOR( band_m_idx = 0; band_m_idx < hDirAC->hConfig->nbands; band_m_idx++ ) { Word32 tmp_diff = L_shr( diffuseness_vector_fx[band_m_idx], sub( diffuseness_vector_q, 30 ) ); // diffueseness_vector_q -> Q30 + norm_tmp_exp = add( reference_power_exp[ts][band_m_idx], 1 ); norm_tmp_fx = Mpy_32_32( reference_power_fx[ts][band_m_idx], L_sub( ONE_IN_Q30, tmp_diff ) ); - hDirAC->direction_vector_m_fx[0][block_m_idx][band_m_idx] = L_add( hDirAC->direction_vector_m_fx[0][block_m_idx][band_m_idx], L_shr( Mpy_32_32( norm_tmp_fx, direction_vector_fx[0][band_m_idx] ), gbits ) ); + dir[0][band_m_idx] = W_mult_32_32( norm_tmp_fx, direction_vector_fx[0][band_m_idx] ); + move64(); + dir[1][band_m_idx] = W_mult_32_32( norm_tmp_fx, direction_vector_fx[1][band_m_idx] ); + move64(); + dir[2][band_m_idx] = W_mult_32_32( norm_tmp_fx, direction_vector_fx[2][band_m_idx] ); + move64(); + Word16 norm = 62; + move16(); + IF( dir[0][band_m_idx] != 0 ) + { + norm = W_norm( dir[0][band_m_idx] ); + } + IF( dir[1][band_m_idx] != 0 ) + { + norm = s_min( norm, W_norm( dir[1][band_m_idx] ) ); + } + IF( dir[2][band_m_idx] != 0 ) + { + norm = s_min( norm, W_norm( dir[2][band_m_idx] ) ); + } + Word32 tmp = W_extract_h( W_shl( dir[0][band_m_idx], norm ) ); + Word16 tmp_e = sub( Q31, add( sub( direction_vector_q, norm_tmp_exp ), sub( norm, 0 ) ) ); + hDirAC->direction_vector_m_fx[0][block_m_idx][band_m_idx] = BASOP_Util_Add_Mant32Exp( hDirAC->direction_vector_m_fx[0][block_m_idx][band_m_idx], direction_vector_exp_tmp[0][block_m_idx][band_m_idx], tmp, tmp_e, &direction_vector_exp_tmp[0][block_m_idx][band_m_idx] ); move32(); - hDirAC->direction_vector_m_fx[1][block_m_idx][band_m_idx] = L_add( hDirAC->direction_vector_m_fx[1][block_m_idx][band_m_idx], L_shr( Mpy_32_32( norm_tmp_fx, direction_vector_fx[1][band_m_idx] ), gbits ) ); + tmp = W_extract_h( W_shl( dir[1][band_m_idx], norm ) ); + hDirAC->direction_vector_m_fx[1][block_m_idx][band_m_idx] = BASOP_Util_Add_Mant32Exp( hDirAC->direction_vector_m_fx[1][block_m_idx][band_m_idx], direction_vector_exp_tmp[1][block_m_idx][band_m_idx], tmp, tmp_e, &direction_vector_exp_tmp[1][block_m_idx][band_m_idx] ); move32(); - hDirAC->direction_vector_m_fx[2][block_m_idx][band_m_idx] = L_add( hDirAC->direction_vector_m_fx[2][block_m_idx][band_m_idx], L_shr( Mpy_32_32( norm_tmp_fx, direction_vector_fx[2][band_m_idx] ), gbits ) ); + tmp = W_extract_h( W_shl( dir[2][band_m_idx], norm ) ); + hDirAC->direction_vector_m_fx[2][block_m_idx][band_m_idx] = BASOP_Util_Add_Mant32Exp( hDirAC->direction_vector_m_fx[2][block_m_idx][band_m_idx], direction_vector_exp_tmp[2][block_m_idx][band_m_idx], tmp, tmp_e, &direction_vector_exp_tmp[2][block_m_idx][band_m_idx] ); move32(); - renormalization_factor_fx[band_m_idx] = L_add( renormalization_factor_fx[band_m_idx], L_shr( norm_tmp_fx, gbits ) ); + renormalization_factor_fx[band_m_idx] = BASOP_Util_Add_Mant32Exp( renormalization_factor_fx[band_m_idx], renormalization_factor_exp[band_m_idx], norm_tmp_fx, norm_tmp_exp, &renormalization_factor_exp[band_m_idx] ); /* exp(norm_tmp_exp + gbits) */ move32(); hDirAC->diffuseness_m_fx[band_m_idx] = BASOP_Util_Add_Mant32Exp( hDirAC->diffuseness_m_fx[band_m_idx], hDirAC->diffuseness_m_exp[band_m_idx], - Mpy_32_32( reference_power_fx[ts][band_m_idx], tmp_diff ), add( reference_power_exp, 1 ), &hDirAC->diffuseness_m_exp[band_m_idx] ); + Mpy_32_32( reference_power_fx[ts][band_m_idx], tmp_diff ), add( reference_power_exp[ts][band_m_idx], 1 ), &hDirAC->diffuseness_m_exp[band_m_idx] ); /* exp(hDirAC->diffuseness_m_exp) */ move32(); renormalization_factor_diff_fx[band_m_idx] = BASOP_Util_Add_Mant32Exp( renormalization_factor_diff_fx[band_m_idx], renormalization_factor_diff_exp[band_m_idx], - reference_power_fx[ts][band_m_idx], reference_power_exp, &renormalization_factor_diff_exp[band_m_idx] ); + reference_power_fx[ts][band_m_idx], reference_power_exp[ts][band_m_idx], &renormalization_factor_diff_exp[band_m_idx] ); /* exp(renormalization_factor_diff_exp) */ move32(); } - norm_tmp_exp = add( reference_power_exp, 1 ); - hDirAC->direction_vector_m_exp[block_m_idx] = add( norm_tmp_exp, add( sub( 31, direction_vector_q ), gbits ) ); - move32(); - renormalization_factor_exp = add( norm_tmp_exp, gbits ); } } @@ -1231,40 +1337,50 @@ void ivas_dirac_param_est_enc_fx( { renormalization_factor_fx[band_m_idx] = EPSILON_FX; move32(); - renormalization_factor_fx[band_m_idx] = L_add( renormalization_factor_fx[band_m_idx], Mpy_32_32( hDirAC->direction_vector_m_fx[0][block_m_idx][band_m_idx], hDirAC->direction_vector_m_fx[0][block_m_idx][band_m_idx] ) ); + renormalization_factor_exp[band_m_idx] = 0; + move16(); + Word16 tmp_e = shl( direction_vector_exp_tmp[0][block_m_idx][band_m_idx], 1 ); + renormalization_factor_fx[band_m_idx] = BASOP_Util_Add_Mant32Exp( renormalization_factor_fx[band_m_idx], renormalization_factor_exp[band_m_idx], Mpy_32_32( hDirAC->direction_vector_m_fx[0][block_m_idx][band_m_idx], hDirAC->direction_vector_m_fx[0][block_m_idx][band_m_idx] ), tmp_e, &renormalization_factor_exp[band_m_idx] ); /* norm_tmp_exp + ( 31 - direction_vector_q ) + gbits */ move32(); - renormalization_factor_fx[band_m_idx] = L_add( renormalization_factor_fx[band_m_idx], Mpy_32_32( hDirAC->direction_vector_m_fx[1][block_m_idx][band_m_idx], hDirAC->direction_vector_m_fx[1][block_m_idx][band_m_idx] ) ); + tmp_e = shl( direction_vector_exp_tmp[1][block_m_idx][band_m_idx], 1 ); + renormalization_factor_fx[band_m_idx] = BASOP_Util_Add_Mant32Exp( renormalization_factor_fx[band_m_idx], renormalization_factor_exp[band_m_idx], Mpy_32_32( hDirAC->direction_vector_m_fx[1][block_m_idx][band_m_idx], hDirAC->direction_vector_m_fx[1][block_m_idx][band_m_idx] ), tmp_e, &renormalization_factor_exp[band_m_idx] ); /* norm_tmp_exp + ( 31 - direction_vector_q ) + gbits */ move32(); - renormalization_factor_fx[band_m_idx] = L_add( renormalization_factor_fx[band_m_idx], Mpy_32_32( hDirAC->direction_vector_m_fx[2][block_m_idx][band_m_idx], hDirAC->direction_vector_m_fx[2][block_m_idx][band_m_idx] ) ); + tmp_e = shl( direction_vector_exp_tmp[2][block_m_idx][band_m_idx], 1 ); + renormalization_factor_fx[band_m_idx] = BASOP_Util_Add_Mant32Exp( renormalization_factor_fx[band_m_idx], renormalization_factor_exp[band_m_idx], Mpy_32_32( hDirAC->direction_vector_m_fx[2][block_m_idx][band_m_idx], hDirAC->direction_vector_m_fx[2][block_m_idx][band_m_idx] ), tmp_e, &renormalization_factor_exp[band_m_idx] ); /* norm_tmp_exp + ( 31 - direction_vector_q ) + gbits */ move32(); - renormalization_factor_exp = shl( hDirAC->direction_vector_m_exp[block_m_idx], 1 ); // 2 * direction_vector_m_exp - renormalization_factor_fx[band_m_idx] = Sqrt32( renormalization_factor_fx[band_m_idx], &renormalization_factor_exp ); + IF( renormalization_factor_fx[band_m_idx] == 0 ) + { + renormalization_factor_fx[band_m_idx] = EPSILON_FX; + move32(); + renormalization_factor_exp[band_m_idx] = 0; + move16(); + } + renormalization_factor_fx[band_m_idx] = Sqrt32( renormalization_factor_fx[band_m_idx], &renormalization_factor_exp[band_m_idx] ); move32(); IF( GT_32( renormalization_factor_fx[band_m_idx], EPSILON_FX ) ) { - Word16 tmp_e; Word32 tmp32; tmp32 = hDirAC->direction_vector_m_fx[0][block_m_idx][band_m_idx]; move32(); - tmp32 = L_deposit_h( BASOP_Util_Divide3232_Scale( tmp32, renormalization_factor_fx[band_m_idx], &tmp_e ) ); - tmp_e = add( tmp_e, sub( hDirAC->direction_vector_m_exp[block_m_idx], renormalization_factor_exp ) ); - hDirAC->direction_vector_m_fx[0][block_m_idx][band_m_idx] = L_shr( tmp32, sub( 1, tmp_e ) ); // Q30 + tmp32 = L_deposit_h( BASOP_Util_Divide3232_Scale( tmp32, renormalization_factor_fx[band_m_idx], &tmp_e ) ); /* exp(tmp_e + ( hDirAC->direction_vector_m_exp[block_m_idx] - renormalization_factor_exp)) */ + tmp_e = add( tmp_e, sub( direction_vector_exp_tmp[0][block_m_idx][band_m_idx], renormalization_factor_exp[band_m_idx] ) ); + hDirAC->direction_vector_m_fx[0][block_m_idx][band_m_idx] = L_shr_sat( tmp32, sub( 1, tmp_e ) ); // Q30 saturation needs to check move32(); - tmp32 = hDirAC->direction_vector_m_fx[1][block_m_idx][band_m_idx]; + tmp32 = hDirAC->direction_vector_m_fx[1][block_m_idx][band_m_idx]; // Q30 move32(); - tmp32 = L_deposit_h( BASOP_Util_Divide3232_Scale( tmp32, renormalization_factor_fx[band_m_idx], &tmp_e ) ); - tmp_e = add( tmp_e, sub( hDirAC->direction_vector_m_exp[block_m_idx], renormalization_factor_exp ) ); - hDirAC->direction_vector_m_fx[1][block_m_idx][band_m_idx] = L_shr( tmp32, sub( 1, tmp_e ) ); // Q30 + tmp32 = L_deposit_h( BASOP_Util_Divide3232_Scale( tmp32, renormalization_factor_fx[band_m_idx], &tmp_e ) ); /* exp(tmp_e + ( hDirAC->direction_vector_m_exp[block_m_idx] - renormalization_factor_exp)) */ + tmp_e = add( tmp_e, sub( direction_vector_exp_tmp[1][block_m_idx][band_m_idx], renormalization_factor_exp[band_m_idx] ) ); + hDirAC->direction_vector_m_fx[1][block_m_idx][band_m_idx] = L_shr_sat( tmp32, sub( 1, tmp_e ) ); // Q30 saturation needs to check move32(); - tmp32 = hDirAC->direction_vector_m_fx[2][block_m_idx][band_m_idx]; + tmp32 = hDirAC->direction_vector_m_fx[2][block_m_idx][band_m_idx]; // Q30 move32(); - tmp32 = L_deposit_h( BASOP_Util_Divide3232_Scale( tmp32, renormalization_factor_fx[band_m_idx], &tmp_e ) ); - tmp_e = add( tmp_e, sub( hDirAC->direction_vector_m_exp[block_m_idx], renormalization_factor_exp ) ); - hDirAC->direction_vector_m_fx[2][block_m_idx][band_m_idx] = L_shr( tmp32, sub( 1, tmp_e ) ); // Q30 + tmp32 = L_deposit_h( BASOP_Util_Divide3232_Scale( tmp32, renormalization_factor_fx[band_m_idx], &tmp_e ) ); /* exp(tmp_e + ( hDirAC->direction_vector_m_exp[block_m_idx] - renormalization_factor_exp)) */ + tmp_e = add( tmp_e, sub( direction_vector_exp_tmp[2][block_m_idx][band_m_idx], renormalization_factor_exp[band_m_idx] ) ); + hDirAC->direction_vector_m_fx[2][block_m_idx][band_m_idx] = L_shr_sat( tmp32, sub( 1, tmp_e ) ); // Q30 saturation needs to check move32(); } ELSE @@ -1276,8 +1392,6 @@ void ivas_dirac_param_est_enc_fx( hDirAC->direction_vector_m_fx[2][block_m_idx][band_m_idx] = 0; move32(); } - hDirAC->direction_vector_m_exp[block_m_idx] = 1; - move16(); /* save the elevation and azimuth values to be used later by the ivas_dirac_QuantizeParameters function */ FOR( d = 0; d < DIRAC_NUM_DIMS; d++ ) @@ -1289,10 +1403,17 @@ void ivas_dirac_param_est_enc_fx( Scale_sig32( dir_v_fx, 3, -1 ); ivas_qmetadata_direction_vector_to_azimuth_elevation_fx( dir_v_fx, +#ifdef NONBE_IMPROVE_DIRAC_INTENSITY_PREC + Q29, +#else + Q30, +#endif &q_direction->band_data[band_m_idx].azimuth_fx[block_m_idx], &q_direction->band_data[band_m_idx].elevation_fx[block_m_idx] ); } + hDirAC->direction_vector_m_exp[block_m_idx] = 1; + move16(); } /* Sectors */ @@ -1312,9 +1433,9 @@ void ivas_dirac_param_est_enc_fx( q_direction[1].band_data[band_m_idx].elevation_fx[block_m_idx] = L_shr( ele_secs_fx[num_freq_bands + band_m_idx], 1 ); // Q23 -> Q22 move32(); - L_tmp = BASOP_Util_Add_Mant32Exp( ONE_IN_Q30, Q1, L_negate( diff_secs_fx[band_m_idx] ), diff_secs_exp[band_m_idx], &e_tmp ); - L_tmp1 = BASOP_Util_Add_Mant32Exp( ONE_IN_Q30, Q1, L_negate( diff_secs_fx[num_freq_bands + band_m_idx] ), diff_secs_exp[num_freq_bands + band_m_idx], &e_tmp1 ); - L_tmp1 = BASOP_Util_Add_Mant32Exp( L_tmp, e_tmp, L_tmp1, e_tmp1, &e_tmp1 ); + L_tmp = BASOP_Util_Add_Mant32Exp( ONE_IN_Q30, Q1, L_negate( diff_secs_fx[band_m_idx] ), diff_secs_exp[band_m_idx], &e_tmp ); /* exp(e_tmp) */ + L_tmp1 = BASOP_Util_Add_Mant32Exp( ONE_IN_Q30, Q1, L_negate( diff_secs_fx[num_freq_bands + band_m_idx] ), diff_secs_exp[num_freq_bands + band_m_idx], &e_tmp1 ); /* exp(e_tmp1) */ + L_tmp1 = BASOP_Util_Add_Mant32Exp( L_tmp, e_tmp, L_tmp1, e_tmp1, &e_tmp1 ); /* exp(e_tmp1) */ IF( L_tmp1 == 0 ) { q_direction[1].band_data[band_m_idx].energy_ratio_fx[block_m_idx] = L_shl( div_l( L_tmp, EPSILON_FX ), Q30 - Q15 ); // Q30 @@ -1322,7 +1443,7 @@ void ivas_dirac_param_est_enc_fx( } ELSE { - L_tmp = L_deposit_h( BASOP_Util_Divide3232_Scale( L_tmp, L_add( L_tmp1, EPSILON_FX ), &exp_diff ) ); + L_tmp = L_deposit_h( BASOP_Util_Divide3232_Scale( L_tmp, L_add( L_tmp1, EPSILON_FX ), &exp_diff ) ); /* exp(exp_diff) */ exp_diff = add( exp_diff, sub( e_tmp, e_tmp1 ) ); q_direction[1].band_data[band_m_idx].energy_ratio_fx[block_m_idx] = L_shl( L_tmp, sub( exp_diff, Q1 ) ); // Q30 move32(); @@ -1337,7 +1458,7 @@ void ivas_dirac_param_est_enc_fx( IF( GT_32( renormalization_factor_diff_fx[band_m_idx], EPSILON_FX ) ) { Word16 tmp_e; - hDirAC->diffuseness_m_fx[band_m_idx] = L_deposit_h( BASOP_Util_Divide3232_Scale( hDirAC->diffuseness_m_fx[band_m_idx], renormalization_factor_diff_fx[band_m_idx], &tmp_e ) ); + hDirAC->diffuseness_m_fx[band_m_idx] = L_deposit_h( BASOP_Util_Divide3232_Scale( hDirAC->diffuseness_m_fx[band_m_idx], renormalization_factor_diff_fx[band_m_idx], &tmp_e ) ); /* exp(tmp_e) */ move32(); tmp_e = add( tmp_e, sub( hDirAC->diffuseness_m_exp[band_m_idx], renormalization_factor_diff_exp[band_m_idx] ) ); hDirAC->diffuseness_m_fx[band_m_idx] = L_shr( hDirAC->diffuseness_m_fx[band_m_idx], sub( 1, tmp_e ) ); // to Q30 @@ -1377,11 +1498,17 @@ void ivas_dirac_param_est_enc_fx( *------------------------------------------------------------------------*/ static void computeIntensityVector_enc_fx( const DIRAC_ENC_HANDLE hDirAC, - Word32 Cldfb_RealBuffer[DIRAC_MAX_ANA_CHANS][DIRAC_NO_FB_BANDS_MAX], - Word32 Cldfb_ImagBuffer[DIRAC_MAX_ANA_CHANS][DIRAC_NO_FB_BANDS_MAX], - const Word16 enc_param_start_band, /* i : first band to process */ - const Word16 num_frequency_bands, - Word32 intensity_real[DIRAC_NUM_DIMS][DIRAC_MAX_NBANDS] ) + Word32 Cldfb_RealBuffer[DIRAC_MAX_ANA_CHANS][DIRAC_NO_FB_BANDS_MAX], /* q_cldfb */ + Word32 Cldfb_ImagBuffer[DIRAC_MAX_ANA_CHANS][DIRAC_NO_FB_BANDS_MAX], /* q_cldfb */ + const Word16 enc_param_start_band, /* i : first band to process Q0*/ + const Word16 num_frequency_bands, /* Q0 */ + Word32 intensity_real[DIRAC_NUM_DIMS][DIRAC_MAX_NBANDS] /* q_intensity_real */ +#ifdef NONBE_IMPROVE_DIRAC_INTENSITY_PREC + , + Word16 q_cldfb, + Word16 q_intensity_real[DIRAC_MAX_NBANDS] +#endif +) { /* Reminder * X = a + ib; Y = c + id @@ -1390,14 +1517,20 @@ static void computeIntensityVector_enc_fx( Word16 i, j; Word32 real, img; Word16 brange[2]; - +#ifdef NONBE_IMPROVE_DIRAC_INTENSITY_PREC + Word16 shift_value = sub( shl( q_cldfb, 1 ), 31 ); +#endif FOR( i = 0; i < num_frequency_bands; i++ ) { - brange[0] = hDirAC->band_grouping[i + enc_param_start_band]; + brange[0] = hDirAC->band_grouping[i + enc_param_start_band]; /* Q0 */ move16(); - brange[1] = hDirAC->band_grouping[i + enc_param_start_band + 1]; + brange[1] = hDirAC->band_grouping[i + enc_param_start_band + 1]; /* Q0 */ move16(); - +#ifdef NONBE_IMPROVE_DIRAC_INTENSITY_PREC + Word16 num_bins = sub( brange[1], brange[0] ); + Word16 gb = find_guarded_bits_fx( num_bins ); + Word16 norm; +#endif intensity_real[0][i] = 0; move32(); intensity_real[1][i] = 0; @@ -1416,11 +1549,36 @@ static void computeIntensityVector_enc_fx( move32(); img = Cldfb_ImagBuffer[0][j]; move32(); +#ifdef NONBE_IMPROVE_DIRAC_INTENSITY_PREC + Word64 t1, t2, t3; + t1 = W_mac_32_32( W_mult_32_32( Cldfb_RealBuffer[3][j], real ), Cldfb_ImagBuffer[3][j], img ); /* 2 * q_cldfb + 1 */ + t2 = W_mac_32_32( W_mult_32_32( Cldfb_RealBuffer[1][j], real ), Cldfb_ImagBuffer[1][j], img ); /* 2 * q_cldfb + 1 */ + t3 = W_mac_32_32( W_mult_32_32( Cldfb_RealBuffer[2][j], real ), Cldfb_ImagBuffer[2][j], img ); /* 2 * q_cldfb + 1 */ + t1 = W_shr( t1, gb ); + t2 = W_shr( t2, gb ); + t3 = W_shr( t3, gb ); + /* Intensity is XYZ order, audio is WYZX order. */ + tmp_1 = W_add( tmp_1, t1 ); /* 2 * q_cldfb + 1 */ + tmp_2 = W_add( tmp_2, t2 ); /* 2 * q_cldfb + 1 */ + tmp_3 = W_add( tmp_3, t3 ); /* 2 * q_cldfb + 1 */ +#else /* Intensity is XYZ order, audio is WYZX order. */ tmp_1 = W_add( tmp_1, W_add( W_mult_32_32( Cldfb_RealBuffer[3][j], real ), W_mult_32_32( Cldfb_ImagBuffer[3][j], img ) ) ); tmp_2 = W_add( tmp_2, W_add( W_mult_32_32( Cldfb_RealBuffer[1][j], real ), W_mult_32_32( Cldfb_ImagBuffer[1][j], img ) ) ); tmp_3 = W_add( tmp_3, W_add( W_mult_32_32( Cldfb_RealBuffer[2][j], real ), W_mult_32_32( Cldfb_ImagBuffer[2][j], img ) ) ); +#endif } +#ifdef NONBE_IMPROVE_DIRAC_INTENSITY_PREC + norm = s_min( W_norm( tmp_1 ), W_norm( tmp_2 ) ); + norm = s_min( norm, W_norm( tmp_3 ) ); + intensity_real[0][i] = W_extract_h( W_shl( tmp_1, norm ) ); // shift_value - (gb - norm) + move32(); + intensity_real[1][i] = W_extract_h( W_shl( tmp_2, norm ) ); // shift_value - (gb - norm) + move32(); + intensity_real[2][i] = W_extract_h( W_shl( tmp_3, norm ) ); // shift_value - (gb - norm) + q_intensity_real[i] = sub( shift_value, sub( gb, norm ) ); + move16(); +#else intensity_real[0][i] = W_extract_h( tmp_1 ); // output Q= 2* input_q + 1 - 32 move32(); @@ -1428,6 +1586,7 @@ static void computeIntensityVector_enc_fx( move32(); intensity_real[2][i] = W_extract_h( tmp_3 ); // output Q= 2* input_q + 1 - 32 move32(); +#endif } return; @@ -1439,11 +1598,11 @@ static void computeIntensityVector_enc_fx( * *------------------------------------------------------------------------*/ void computeDiffuseness_mdft_fx( - Word32 **buffer_intensity[DIRAC_NUM_DIMS], - const Word32 *buffer_energy, - const Word16 num_freq_bands, - const UWord16 no_col_avg_diff, - Word32 *diffuseness, + Word32 **buffer_intensity[DIRAC_NUM_DIMS], /* q_factor_intensity */ + const Word32 *buffer_energy, /* q_factor_energy */ + const Word16 num_freq_bands, /* Q0 */ + const UWord16 no_col_avg_diff, /* Q0 */ + Word32 *diffuseness, /* q_diffuseness */ Word16 *q_factor_intensity, Word16 *q_factor_energy, Word16 *q_diffuseness /*Ouput Q*/ @@ -1479,7 +1638,7 @@ void computeDiffuseness_mdft_fx( FOR( k = 0; k < num_freq_bands; k++ ) { - energy_slow[k] = BASOP_Util_Add_Mant32Exp( energy_slow[k], energy_slow_e[k], p_tmp_c[k], sub( 31, tmp_q ), &energy_slow_e[k] ); + energy_slow[k] = BASOP_Util_Add_Mant32Exp( energy_slow[k], energy_slow_e[k], p_tmp_c[k], sub( 31, tmp_q ), &energy_slow_e[k] ); /* exp(energy_slow_e)*/ move32(); } @@ -1489,7 +1648,7 @@ void computeDiffuseness_mdft_fx( p_tmp = buffer_intensity[j][i]; FOR( k = 0; k < num_freq_bands; k++ ) { - intensity_slow[j * num_freq_bands + k] = BASOP_Util_Add_Mant32Exp( intensity_slow[j * num_freq_bands + k], intensity_slow_e[j * num_freq_bands + k], p_tmp[k], sub( 31, q_factor_intensity[i] ), &intensity_slow_e[j * num_freq_bands + k] ); + intensity_slow[j * num_freq_bands + k] = BASOP_Util_Add_Mant32Exp( intensity_slow[j * num_freq_bands + k], intensity_slow_e[j * num_freq_bands + k], p_tmp[k], sub( 31, q_factor_intensity[i] ), &intensity_slow_e[j * num_freq_bands + k] ); /* exp(intensity_slow_e) */ move32(); } } @@ -1503,10 +1662,10 @@ void computeDiffuseness_mdft_fx( FOR( k = 0; k < num_freq_bands; k++ ) { - p_tmp[k] = Mpy_32_32( p_tmp[k], p_tmp[k] ); + p_tmp[k] = Mpy_32_32( p_tmp[k], p_tmp[k] ); /* 2 * (31-p_tmp_e) - 31 */ move32(); tmp_q = sub( shl( sub( 31, p_tmp_e[k] ), 1 ), 31 ); - intensity_slow_abs[k] = BASOP_Util_Add_Mant32Exp( intensity_slow_abs[k], intensity_slow_abs_e[k], p_tmp[k], sub( 31, tmp_q ), &intensity_slow_abs_e[k] ); + intensity_slow_abs[k] = BASOP_Util_Add_Mant32Exp( intensity_slow_abs[k], intensity_slow_abs_e[k], p_tmp[k], sub( 31, tmp_q ), &intensity_slow_abs_e[k] ); /* exp(intensity_slow_abs_e) */ move32(); } } @@ -1519,7 +1678,7 @@ void computeDiffuseness_mdft_fx( { tmp = Sqrt32( p_tmp[i], &intensity_slow_abs_e[i] ); - tmp = L_deposit_h( BASOP_Util_Divide3232_Scale( tmp, L_add( energy_slow[i], EPSILLON_FX ), &tmp_q ) ); + tmp = L_deposit_h( BASOP_Util_Divide3232_Scale( tmp, L_add( energy_slow[i], EPSILLON_FX ), &tmp_q ) ); /* exp(tmp_q) */ tmp_q = add( tmp_q, sub( intensity_slow_abs_e[i], energy_slow_e[i] ) ); tmp = L_shl_sat( tmp, tmp_q ); tmp = L_sub( ONE_IN_Q31, tmp ); diff --git a/lib_enc/ivas_enc_cov_handler.c b/lib_enc/ivas_enc_cov_handler_fx.c similarity index 81% rename from lib_enc/ivas_enc_cov_handler.c rename to lib_enc/ivas_enc_cov_handler_fx.c index cf42f8cc89beccfe7ef532296592e76bac70d6ae..c05d59b9086289658e59e23ebab2248e3d9118f0 100644 --- a/lib_enc/ivas_enc_cov_handler.c +++ b/lib_enc/ivas_enc_cov_handler_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other @@ -32,11 +32,9 @@ #include #include "options.h" -#include "prot.h" -#include "ivas_prot.h" +#include "prot_fx.h" #include "ivas_rom_com.h" #include "wmc_auto.h" -#include "prot_fx.h" #include "ivas_prot_fx.h" /*------------------------------------------------------------------------------------------* @@ -62,12 +60,12 @@ static void ivas_band_cov_fx( Word32 **ppIn_FR_real, Word32 **ppIn_FR_imag, Word *------------------------------------------------------------------------*/ ivas_error ivas_spar_covar_enc_open_fx( - ivas_enc_cov_handler_state_t **hCovEnc, /* i/o: SPAR Covar. encoder handle */ - ivas_filterbank_t *pFb, /* i/o: FB handle */ - const Word32 input_Fs, /* i : input sampling rate */ - const Word16 nchan_inp, /* i : number of input channels */ - const COV_SMOOTHING_TYPE smooth_mode, /* i : Smooth covariance for SPAR or MC*/ - const Word32 ivas_total_brate /* i : IVAS total bitrate */ + ivas_enc_cov_handler_state_t **hCovEnc, /* i/o: SPAR Covar. encoder handle */ + ivas_filterbank_t *pFb, /* i/o: FB handle */ + const Word32 input_Fs, /* i : input sampling rate Q0*/ + const Word16 nchan_inp, /* i : number of input channels Q0*/ + const COV_SMOOTHING_TYPE smooth_mode, /* i : Smooth covariance for SPAR or MC */ + const Word32 ivas_total_brate /* i : IVAS total bitrate Q0*/ ) { ivas_enc_cov_handler_state_t *hCovState; @@ -92,7 +90,7 @@ ivas_error ivas_spar_covar_enc_open_fx( { cov_smooth_cfg.max_update_rate_fx = ONE_IN_Q31; // Q31 move32(); - cov_smooth_cfg.min_pool_size = 20; + cov_smooth_cfg.min_pool_size = 20; // Q0 move16(); } @@ -111,7 +109,7 @@ ivas_error ivas_spar_covar_enc_open_fx( return error; } - hCovState->num_bins = extract_l( Mpy_32_32( input_Fs, ONE_BY_FRAMES_PER_SEC_Q31 ) ); + hCovState->num_bins = extract_l( Mpy_32_32( input_Fs, ONE_BY_FRAMES_PER_SEC_Q31 ) ); /* Q0 */ hCovState->prior_dtx_present = 0; move16(); @@ -133,7 +131,7 @@ ivas_error ivas_spar_covar_enc_open_fx( void ivas_spar_covar_enc_close_fx( ivas_enc_cov_handler_state_t **hCovEnc, /* i/o: SPAR Covar. encoder handle */ - const Word16 nchan_inp /* i : number of input channels */ + const Word16 nchan_inp /* i : number of input channels Q0*/ ) { ivas_enc_cov_handler_state_t *hCovState; @@ -165,14 +163,15 @@ void ivas_spar_covar_enc_close_fx( static Word16 ivas_spar_get_activeW_flag_fx( ivas_enc_cov_handler_state_t *hCovEnc, - Word32 *cov_real[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH], - Word32 *cov_dtx_real[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH], + Word32 *cov_real[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH], /* q_cov_real */ + Word32 *cov_dtx_real[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH], /* q_cov_real */ Word16 *q_cov_real[IVAS_SPAR_MAX_CH], - const Word16 dtx_vad, - const Word16 nchan_inp, - const Word16 nchan_transport, - Word16 *res_ind, - const Word16 *dmx_order ) + const Word16 dtx_vad, /* Q0 */ + const Word16 nchan_inp, /* Q0 */ + const Word16 nchan_transport, /* Q0 */ + Word16 *res_ind, /* Q0 */ + const Word16 *dmx_order /* Q0 */ +) { Word16 b, ch, num_bands, num_chs, activeW_flag; Word32 bb_var[FOA_CHANNELS], sm_fact, side_ch_var, en_ratio; @@ -182,8 +181,8 @@ static Word16 ivas_spar_get_activeW_flag_fx( Word32 L_tmp, L_tmp1; Word16 exp_diff, q_com, guard_bits; - num_chs = s_min( nchan_inp, FOA_CHANNELS ); - num_bands = ivas_get_num_bands_from_bw_idx( SPAR_CONFIG_BW ); + num_chs = s_min( nchan_inp, FOA_CHANNELS ); /* Q0 */ + num_bands = ivas_get_num_bands_from_bw_idx( SPAR_CONFIG_BW ); /* Q0 */ set_zero_fx( bb_var, FOA_CHANNELS ); set_s( q_bb_var, Q31, FOA_CHANNELS ); @@ -225,7 +224,7 @@ static Word16 ivas_spar_get_activeW_flag_fx( q_shift = Q31; move16(); q_shift = W_norm( bb_var_64bit[ch] ); - bb_var[ch] = W_extract_l( W_shl_nosat( bb_var_64bit[ch], sub( q_shift, 32 ) ) ); + bb_var[ch] = W_extract_l( W_shl_nosat( bb_var_64bit[ch], sub( q_shift, 32 ) ) ); /* q_bb_var[ch] + sub( q_shift, 32 ) */ move32(); q_bb_var[ch] = add( q_bb_var[ch], sub( q_shift, 32 ) ); move16(); @@ -294,7 +293,7 @@ static Word16 ivas_spar_get_activeW_flag_fx( { Word16 max_idx; Word32 max_val; - max_idx = nchan_transport; + max_idx = nchan_transport; /* Q0 */ move16(); max_val = hCovEnc->bb_var_lt_fx[max_idx]; // q_bb_var[max_idx] move32(); @@ -306,12 +305,12 @@ static Word16 ivas_spar_get_activeW_flag_fx( move32(); } } - *res_ind = max_idx; + *res_ind = max_idx; /* Q0 */ move16(); } ELSE IF( EQ_16( nchan_transport, 3 ) ) { - *res_ind = dmx_order[nchan_transport]; + *res_ind = dmx_order[nchan_transport]; /* Q0 */ move16(); } } @@ -328,25 +327,26 @@ return activeW_flag; void ivas_enc_cov_handler_process_fx( ivas_enc_cov_handler_state_t *hCovEnc, /* i/o: SPAR Covar. encoder handle */ - Word32 **ppIn_FR_real, - Word32 **ppIn_FR_imag, + Word32 **ppIn_FR_real, /* q_ppIn_FR */ + Word32 **ppIn_FR_imag, /* q_ppIn_FR */ Word16 q_ppIn_FR, - Word32 *cov_real[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH], + Word32 *cov_real[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH], /* q_cov_real */ Word16 *q_cov_real[IVAS_SPAR_MAX_CH], - Word32 *cov_dtx_real[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH], + Word32 *cov_dtx_real[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH], /* q_cov_dtx_real */ Word16 *q_cov_dtx_real[IVAS_SPAR_MAX_CH], - ivas_filterbank_t *pFb, /* i/o: FB handle */ - const Word16 start_band, - const Word16 end_band, - const Word16 num_ch, - const Word16 dtx_vad, - const Word16 transient_det[2], - const Word16 HOA_md_ind[IVAS_SPAR_MAX_CH], - Word16 *res_ind, - const Word16 *remix_order, - Word16 *dyn_active_w_flag, - const Word16 nchan_transport, - const Word16 is_sba ) + ivas_filterbank_t *pFb, /* i/o: FB handle */ + const Word16 start_band, /* Q0 */ + const Word16 end_band, /* Q0 */ + const Word16 num_ch, /* Q0 */ + const Word16 dtx_vad, /* Q0 */ + const Word16 transient_det[2], /* Q0 */ + const Word16 HOA_md_ind[IVAS_SPAR_MAX_CH], /* Q0 */ + Word16 *res_ind, /* Q0 */ + const Word16 *remix_order, /* Q0 */ + Word16 *dyn_active_w_flag, /* Q0 */ + const Word16 nchan_transport, /* Q0 */ + const Word16 is_sba /* Q0 */ +) { Word16 i, j; Word16 dtx_cov_flag; @@ -410,7 +410,7 @@ void ivas_enc_cov_handler_process_fx( move16(); IF( GT_16( nchan_transport, 1 ) && LE_16( nchan_transport, sub( FOA_CHANNELS, 1 ) ) ) { - *dyn_active_w_flag = ivas_spar_get_activeW_flag_fx( hCovEnc, cov_real, cov_real, q_cov_real, dtx_vad, num_ch, nchan_transport, res_ind, remix_order ); + *dyn_active_w_flag = ivas_spar_get_activeW_flag_fx( hCovEnc, cov_real, cov_real, q_cov_real, dtx_vad, num_ch, nchan_transport, res_ind, remix_order ); /* Q0 */ } ELSE { @@ -423,7 +423,7 @@ void ivas_enc_cov_handler_process_fx( { FOR( j = 0; j < num_ch; j++ ) { - Copy32( cov_real[i][j], cov_dtx_real[i][j], pFb->filterbank_num_bands ); + Copy32( cov_real[i][j], cov_dtx_real[i][j], pFb->filterbank_num_bands ); /* q_cov_real */ q_cov_dtx_real[i][j] = q_cov_real[i][j]; move16(); } @@ -437,13 +437,13 @@ void ivas_enc_cov_handler_process_fx( { FOR( j = 0; j < num_ch; j++ ) { - Copy32( cov_real[i][j], hCovEnc->pCov_dtx_state->pPrior_cov_real_fx[i][j], pFb->filterbank_num_bands ); + Copy32( cov_real[i][j], hCovEnc->pCov_dtx_state->pPrior_cov_real_fx[i][j], pFb->filterbank_num_bands ); /* q_cov_real */ FOR( k = 0; k < pFb->filterbank_num_bands; k++ ) { hCovEnc->pCov_dtx_state->q_prior_cov_real_per_band[i][j][k] = hCovEnc->pCov_state->q_cov_real_per_band[i][j][k]; move16(); } - Copy32( cov_real[i][j], cov_dtx_real[i][j], pFb->filterbank_num_bands ); + Copy32( cov_real[i][j], cov_dtx_real[i][j], pFb->filterbank_num_bands ); /* q_cov_real */ Copy( hCovEnc->pCov_state->q_cov_real_per_band[i][j], hCovEnc->pCov_dtx_state->q_cov_real_per_band[i][j], pFb->filterbank_num_bands ); } } @@ -472,7 +472,7 @@ void ivas_enc_cov_handler_process_fx( { FOR( j = 0; j < num_ch; j++ ) { - Copy32( hCovEnc->pCov_dtx_state->pPrior_cov_real_fx[i][j], cov_dtx_real[i][j], pFb->filterbank_num_bands ); + Copy32( hCovEnc->pCov_dtx_state->pPrior_cov_real_fx[i][j], cov_dtx_real[i][j], pFb->filterbank_num_bands ); /* q_cov_real */ FOR( k = 0; k < pFb->filterbank_num_bands; k++ ) { hCovEnc->pCov_dtx_state->q_cov_real_per_band[i][j][k] = hCovEnc->pCov_dtx_state->q_prior_cov_real_per_band[i][j][k]; @@ -491,34 +491,37 @@ void ivas_enc_cov_handler_process_fx( static void ivas_band_cov_fx( - Word32 **ppIn_FR_real, - Word32 **ppIn_FR_imag, + Word32 **ppIn_FR_real, /* q_In_FR */ + Word32 **ppIn_FR_imag, /* q_In_FR */ Word16 q_In_FR, - const Word16 num_chans, - const Word16 num_bins, - Word16 stride, - Word32 **pFb_bin_to_band, - const Word16 *pFb_start_bin_per_band, - const Word16 *pFb_active_bins_per_band, - const Word16 start_band, - const Word16 end_band, - Word32 *cov_real[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH], + const Word16 num_chans, /* Q0 */ + const Word16 num_bins, /* Q0 */ + Word16 stride, /* Q0 */ + Word32 **pFb_bin_to_band, /* Q22 */ + const Word16 *pFb_start_bin_per_band, /* Q0 */ + const Word16 *pFb_active_bins_per_band, /* Q0 */ + const Word16 start_band, /* Q0 */ + const Word16 end_band, /* Q0 */ + Word32 *cov_real[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH], /* q_cov_real */ Word16 *q_cov_real[IVAS_SPAR_MAX_CH], - const Word16 HOA_md_ind[IVAS_SPAR_MAX_CH] ) + const Word16 HOA_md_ind[IVAS_SPAR_MAX_CH] /* Q0 */ +) { Word16 i, j, k; Word32 pV_re[L_FRAME48k]; Word64 pV_re_64bit[L_FRAME48k]; Word64 cov_real_64bit[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH][IVAS_MAX_NUM_BANDS]; - Word16 q_shift; + Word16 q_shift, q_shift_tmp; Word16 m, start_bin, active_bins; + Word16 num_blocks; + num_blocks = idiv1616( num_bins, stride ); /* Q0 */ FOR( i = 0; i < num_chans; i++ ) { FOR( j = i; j < num_chans; j++ ) { - Word16 i1 = HOA_md_ind[i]; - Word16 j1 = HOA_md_ind[j]; + Word16 i1 = HOA_md_ind[i]; /* Q0 */ + Word16 j1 = HOA_md_ind[j]; /* Q0 */ move16(); move16(); @@ -533,17 +536,19 @@ static void ivas_band_cov_fx( move16(); FOR( k = 0; k < num_bins; k++ ) { - IF( pV_re_64bit[k] != 0 ) + q_shift_tmp = W_norm( pV_re_64bit[k] ); + if ( pV_re_64bit[k] != 0 ) { - q_shift = s_min( q_shift, W_norm( pV_re_64bit[k] ) ); + q_shift = s_min( q_shift, q_shift_tmp ); } } + q_shift_tmp = sub( q_shift, 32 ); FOR( k = 0; k < num_bins; k++ ) { - pV_re[k] = W_extract_l( W_shl_nosat( pV_re_64bit[k], sub( q_shift, 32 ) ) ); //(q_In_FR[i1] + q_In_FR[j1]) + (q_shift - 32) + pV_re[k] = W_extract_l( W_shl_nosat( pV_re_64bit[k], q_shift_tmp ) ); //(q_In_FR[i1] + q_In_FR[j1]) + (q_shift - 32) move32(); /* perform rounding towards lower value for negative results */ - IF( pV_re[k] < 0 ) + if ( pV_re[k] < 0 ) { pV_re[k] = L_add( pV_re[k], 1 ); } @@ -553,31 +558,32 @@ static void ivas_band_cov_fx( { Word64 temp; const Word32 *p_bin_to_band = pFb_bin_to_band[k]; // Q22 - Word32 *cov_ptr = pV_re; - Word16 num_blocks; + Word32 *cov_ptr; Word16 blk; temp = 0; move64(); - num_blocks = idiv1616( num_bins, stride ); - move16(); - start_bin = pFb_start_bin_per_band[k]; + start_bin = pFb_start_bin_per_band[k]; /* Q0 */ move16(); - active_bins = pFb_active_bins_per_band[k]; + active_bins = pFb_active_bins_per_band[k]; /* Q0 */ move16(); + cov_ptr = &pV_re[start_bin]; + move16(); FOR( blk = 0; blk < num_blocks; blk++ ) { /* optional: add temporal weight here */ - FOR( m = start_bin; m < add( start_bin, active_bins ); m++ ) + FOR( m = 0; m < active_bins; m++ ) { - temp = W_add( temp, W_mult0_32_32( cov_ptr[m], p_bin_to_band[sub( m, start_bin )] ) ); // ((q_In_FR[i1] + q_In_FR[j1]) + (q_shift - 32), Q22) -> (q_In_FR[i1] + q_In_FR[j1] + (q_shift - 10) + temp = W_add( temp, W_mult0_32_32( cov_ptr[m], p_bin_to_band[m] ) ); // ((q_In_FR[i1] + q_In_FR[j1]) + (q_shift - 32), Q22) -> (q_In_FR[i1] + q_In_FR[j1] + (q_shift - 10) } cov_ptr += stride; + move16(); } // What basop to add below???? cov_real_64bit[i][j][k] = temp * (Word64) ( num_blocks ); // (q_In_FR[i1] + q_In_FR[j1] + (q_shift - 10) - guard_bits move64(); + move64(); // conservative estimation of a 64 bit multiplication } q_cov_real[i][j] = add( add( q_In_FR, q_In_FR ), sub( q_shift, Q10 ) ); move16(); @@ -592,17 +598,19 @@ static void ivas_band_cov_fx( move16(); FOR( k = start_band; k < end_band; k++ ) { - IF( cov_real_64bit[i][j][k] != 0 ) + q_shift_tmp = W_norm( cov_real_64bit[i][j][k] ); + if ( cov_real_64bit[i][j][k] != 0 ) { - q_shift = s_min( q_shift, W_norm( cov_real_64bit[i][j][k] ) ); + q_shift = s_min( q_shift, q_shift_tmp ); } } + q_shift_tmp = sub( q_shift, 32 ); FOR( k = start_band; k < end_band; k++ ) { - cov_real[i][j][k] = W_extract_l( W_shl_nosat( cov_real_64bit[i][j][k], sub( q_shift, 32 ) ) ); + cov_real[i][j][k] = W_extract_l( W_shl_nosat( cov_real_64bit[i][j][k], q_shift_tmp ) ); /* q_cov_real[i][j] + q_shift - 32 */ move32(); } - q_cov_real[i][j] = add( q_cov_real[i][j], sub( q_shift, 32 ) ); + q_cov_real[i][j] = add( q_cov_real[i][j], q_shift_tmp ); move16(); } } diff --git a/lib_enc/ivas_enc.c b/lib_enc/ivas_enc_fx.c similarity index 77% rename from lib_enc/ivas_enc.c rename to lib_enc/ivas_enc_fx.c index 3979326e44c485ed93ca92f7fe6fa48a03576d08..e8e1bc59e5913762d56f4b6d28accf33176cb34e 100644 --- a/lib_enc/ivas_enc.c +++ b/lib_enc/ivas_enc_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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,14 +36,12 @@ #include "cnst.h" #include "ivas_cnst.h" #include "rom_com.h" -#include "prot.h" -#include "ivas_prot.h" +#include "prot_fx.h" #include "ivas_rom_com.h" #ifdef DEBUGGING #include "debug.h" #endif #include "wmc_auto.h" -#include "prot_fx.h" #include "ivas_prot_fx.h" /*-------------------------------------------------------------------* @@ -52,9 +50,9 @@ * Principal IVAS encoder routine *-------------------------------------------------------------------*/ ivas_error ivas_enc_fx( - Encoder_Struct *st_ivas, /* i/o: IVAS encoder structure */ - const Word16 *data, /* i : input signal Q0 */ - const Word16 n_samples /* i : number of input samples */ + Encoder_Struct *st_ivas, /* i/o: IVAS encoder structure */ + const Word16 *data, /* i : input signal Q0*/ + const Word16 n_samples /* i : number of input samples Q0*/ ) { Word16 i, n, input_frame, n_samples_chan, nchan_inp /*, scale*/; @@ -77,10 +75,10 @@ ivas_error ivas_enc_fx( hEncoderConfig = st_ivas->hEncoderConfig; - input_Fs = hEncoderConfig->input_Fs; + input_Fs = hEncoderConfig->input_Fs; /* Q0 */ ivas_format = hEncoderConfig->ivas_format; - nchan_inp = hEncoderConfig->nchan_inp; - ivas_total_brate = hEncoderConfig->ivas_total_brate; + nchan_inp = hEncoderConfig->nchan_inp; /* Q0 */ + ivas_total_brate = hEncoderConfig->ivas_total_brate; /* Q0 */ move32(); move32(); move16(); @@ -89,12 +87,12 @@ ivas_error ivas_enc_fx( input_frame = extract_l( Mpy_32_16_1( input_Fs, INV_FRAME_PER_SEC_Q15 ) ); IF( NE_16( nchan_inp, 1 ) ) { - n_samples_chan = div_l( L_deposit_l( n_samples ), nchan_inp ); - n_samples_chan = shl( n_samples_chan, 1 ); + n_samples_chan = div_l( L_deposit_l( n_samples ), nchan_inp ); /* Q0 */ + n_samples_chan = shl( n_samples_chan, 1 ); /* Q0 */ } ELSE { - n_samples_chan = n_samples; + n_samples_chan = n_samples; /* Q0 */ move16(); } set16_fx( nb_bits_metadata, 0, MAX_SCE + 1 ); @@ -106,9 +104,12 @@ ivas_error ivas_enc_fx( FOR( n = 0; n < MAX_INPUT_CHANNELS + MAX_NUM_OBJECTS; n++ ) { data_fx[n] = st_ivas->p_data_fx[n]; + IF( data_fx[n] ) + { + Scale_sig32( data_fx[n], input_frame, sub( Q11, st_ivas->q_data_fx ) ); // Q11 + } } - - st_ivas->q_data_fx = 11; // Q-factor of the input buffer + st_ivas->q_data_fx = Q11; move16(); n = 0; move16(); @@ -119,7 +120,7 @@ ivas_error ivas_enc_fx( data_fx[n][i] = L_mult0( data[i * nchan_inp + n], shl( 1, st_ivas->q_data_fx ) ); move32(); } - n++; + n = add( n, 1 ); } IF( LT_16( n_samples_chan, input_frame ) ) @@ -132,14 +133,14 @@ ivas_error ivas_enc_fx( IF( EQ_32( ivas_format, SBA_FORMAT ) ) { - IF( NE_32( ( error = ivas_sba_enc_reconfigure( st_ivas ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = ivas_sba_enc_reconfigure_fx( st_ivas ) ), IVAS_ERR_OK ) ) { return error; } } ELSE IF( EQ_32( ivas_format, SBA_ISM_FORMAT ) ) { - IF( NE_32( ( error = ivas_osba_enc_reconfig( st_ivas ) ), IVAS_ERR_OK ) ) + IF( ( error = ivas_osba_enc_reconfig( st_ivas ) ) != IVAS_ERR_OK ) { return error; } @@ -177,9 +178,9 @@ ivas_error ivas_enc_fx( test(); IF( EQ_32( ivas_format, STEREO_FORMAT ) ) { - st_ivas->hCPE[0]->element_brate = ivas_total_brate; + st_ivas->hCPE[0]->element_brate = ivas_total_brate; /* Q0 */ move32(); - IF( NE_32( ( error = ivas_cpe_enc_fx( st_ivas, 0, data_fx[0], data_fx[1], st_ivas->q_data_fx, input_frame, 0 /* no metadata */, NULL ) ), IVAS_ERR_OK ) ) + IF( ( error = ivas_cpe_enc_fx( st_ivas, 0, data_fx[0], data_fx[1], st_ivas->q_data_fx, input_frame, 0 /* no metadata */, NULL ) ) != IVAS_ERR_OK ) { return error; } @@ -187,7 +188,7 @@ ivas_error ivas_enc_fx( ELSE IF( EQ_32( ivas_format, ISM_FORMAT ) ) { /* select ISM format mode; reconfigure the ISM format encoder */ - IF( NE_32( ( error = ivas_ism_enc_config( st_ivas ) ), IVAS_ERR_OK ) ) + IF( ( error = ivas_ism_enc_config( st_ivas ) ) != IVAS_ERR_OK ) { return error; } @@ -200,7 +201,7 @@ ivas_error ivas_enc_fx( ivas_param_ism_stereo_dmx_fx( st_ivas, data_fx, input_frame ); /* Core coding of Stereo DMX */ - IF( NE_32( ( error = ivas_ism_enc_fx( st_ivas, data_fx, st_ivas->q_data_fx, input_frame, nb_bits_metadata, 0 ) ), IVAS_ERR_OK ) ) + IF( ( error = ivas_ism_enc_fx( st_ivas, data_fx, st_ivas->q_data_fx, input_frame, nb_bits_metadata, 0 ) ) != IVAS_ERR_OK ) { return error; } @@ -208,7 +209,7 @@ ivas_error ivas_enc_fx( ELSE IF( EQ_32( st_ivas->ism_mode, ISM_MODE_DISC ) ) { /* Analysis, decision about bitrates per channel & core coding */ - IF( NE_32( ( error = ivas_ism_enc_fx( st_ivas, data_fx, st_ivas->q_data_fx, input_frame, nb_bits_metadata, 0 ) ), IVAS_ERR_OK ) ) + IF( ( error = ivas_ism_enc_fx( st_ivas, data_fx, st_ivas->q_data_fx, input_frame, nb_bits_metadata, 0 ) ) != IVAS_ERR_OK ) { return error; } @@ -238,25 +239,25 @@ ivas_error ivas_enc_fx( { ivas_masa_estimate_energy_fx( st_ivas->hMasa, data_fx, input_frame, st_ivas->nchan_transport, st_ivas->q_data_fx ); /* energy-estimation uses TF-resolution: 4x24 */ - IF( NE_32( ( error = ivas_masa_enc_config_fx( st_ivas ) ), IVAS_ERR_OK ) ) + IF( ( error = ivas_masa_enc_config_fx( st_ivas ) ) != IVAS_ERR_OK ) { return error; } IF( EQ_16( st_ivas->nchan_transport, 2 ) ) { - IF( NE_32( ( error = ivas_masa_encode_fx( st_ivas->hMasa, st_ivas->hQMetaData, hMetaData, &nb_bits_metadata[0], st_ivas->nchan_transport, ivas_format, ivas_total_brate, hEncoderConfig->Opt_DTX_ON, st_ivas->hCPE[0]->element_mode, - ISM_MODE_NONE, -1, NULL, -1, NULL, 0, 0 ) ), - IVAS_ERR_OK ) ) + IF( ( error = ivas_masa_encode_fx( st_ivas->hMasa, st_ivas->hQMetaData, hMetaData, &nb_bits_metadata[0], st_ivas->nchan_transport, ivas_format, ivas_total_brate, hEncoderConfig->Opt_DTX_ON, st_ivas->hCPE[0]->element_mode, + ISM_MODE_NONE, -1, NULL, -1, NULL, 0, 0 ) ) != + IVAS_ERR_OK ) { return error; } } ELSE { - IF( NE_32( ( error = ivas_masa_encode_fx( st_ivas->hMasa, st_ivas->hQMetaData, hMetaData, &nb_bits_metadata[0], st_ivas->nchan_transport, ivas_format, ivas_total_brate, hEncoderConfig->Opt_DTX_ON, -1, - ISM_MODE_NONE, -1, NULL, -1, NULL, 0, 0 ) ), - IVAS_ERR_OK ) ) + IF( ( error = ivas_masa_encode_fx( st_ivas->hMasa, st_ivas->hQMetaData, hMetaData, &nb_bits_metadata[0], st_ivas->nchan_transport, ivas_format, ivas_total_brate, hEncoderConfig->Opt_DTX_ON, -1, + ISM_MODE_NONE, -1, NULL, -1, NULL, 0, 0 ) ) != + IVAS_ERR_OK ) { return error; } @@ -264,7 +265,7 @@ ivas_error ivas_enc_fx( } ELSE IF( EQ_32( ivas_format, SBA_FORMAT ) ) { - IF( NE_32( ( error = ivas_spar_enc_fx( st_ivas, data_fx, input_frame, nb_bits_metadata, hMetaData ) ), IVAS_ERR_OK ) ) + IF( ( error = ivas_spar_enc_fx( st_ivas, data_fx, input_frame, nb_bits_metadata, hMetaData ) ) != IVAS_ERR_OK ) { return error; } @@ -278,21 +279,21 @@ ivas_error ivas_enc_fx( /* core-coding of transport channels */ IF( EQ_16( st_ivas->nSCE, 1 ) ) { - IF( NE_32( ( error = ivas_sce_enc_fx( st_ivas, 0, data_fx[0], st_ivas->q_data_fx, input_frame, nb_bits_metadata[0] ) ), IVAS_ERR_OK ) ) + IF( ( error = ivas_sce_enc_fx( st_ivas, 0, data_fx[0], st_ivas->q_data_fx, input_frame, nb_bits_metadata[0] ) ) != IVAS_ERR_OK ) { return error; } } ELSE IF( EQ_16( st_ivas->nCPE, 1 ) ) /* Stereo DMX */ { - IF( NE_32( ( error = ivas_cpe_enc_fx( st_ivas, 0, data_fx[0], data_fx[1], st_ivas->q_data_fx, input_frame, nb_bits_metadata[0], NULL ) ), IVAS_ERR_OK ) ) + IF( ( error = ivas_cpe_enc_fx( st_ivas, 0, data_fx[0], data_fx[1], st_ivas->q_data_fx, input_frame, nb_bits_metadata[0], NULL ) ) != IVAS_ERR_OK ) { return error; } } ELSE IF( GT_16( st_ivas->nCPE, 1 ) ) /* FOA/HOA format */ { - IF( NE_32( ( error = ivas_mct_enc_fx( st_ivas, data_fx, st_ivas->q_data_fx, input_frame, nb_bits_metadata[0] ) ), IVAS_ERR_OK ) ) + IF( ( error = ivas_mct_enc_fx( st_ivas, data_fx, st_ivas->q_data_fx, input_frame, nb_bits_metadata[0] ) ) != IVAS_ERR_OK ) { return error; } @@ -313,18 +314,18 @@ ivas_error ivas_enc_fx( IF( EQ_16( sub( st_ivas->hEncoderConfig->nchan_inp, hEncoderConfig->nchan_ism ), 1 ) ) { v_multc_fixed( data_fx[hEncoderConfig->nchan_ism], L_deposit_h( INV_SQRT2_FX_Q15 ) /* Q31 */, data_fx[hEncoderConfig->nchan_ism], input_frame ); - Copy32( data_fx[hEncoderConfig->nchan_ism], data_fx[hEncoderConfig->nchan_ism + 1], input_frame ); + Copy32( data_fx[hEncoderConfig->nchan_ism], data_fx[hEncoderConfig->nchan_ism + 1], input_frame ); /* st_ivas->q_data_fx */ } /* Estimate TF-tile energy for the input MASA stream */ ivas_masa_estimate_energy_fx( st_ivas->hMasa, &( data_fx[hEncoderConfig->nchan_ism] ), input_frame, st_ivas->nchan_transport, st_ivas->q_data_fx ); - IF( NE_32( ( error = ivas_omasa_enc_config_fx( st_ivas ) ), IVAS_ERR_OK ) ) + IF( ( error = ivas_omasa_enc_config_fx( st_ivas ) ) != IVAS_ERR_OK ) { return error; } - set_s( nb_bits_metadata, 0, MAX_SCE + 1 ); + set16_fx( nb_bits_metadata, 0, MAX_SCE + 1 ); idx_separated_object = 0; move16(); @@ -338,6 +339,7 @@ ivas_error ivas_enc_fx( /* Scaling data_fx */ { Word16 norm_data_in = MAX16B; + move16(); FOR( i = 0; i < hEncoderConfig->nchan_ism + st_ivas->nchan_transport; i++ ) { norm_data_in = s_min( norm_data_in, L_norm_arr( data_fx[i], input_frame ) ); @@ -345,7 +347,7 @@ ivas_error ivas_enc_fx( norm_data_in = sub( norm_data_in, 7 ); /*guard bit is 4->to handle overflow in cldfbAnalysis*/ FOR( i = 0; i < hEncoderConfig->nchan_ism + st_ivas->nchan_transport; i++ ) { - scale_sig32( data_fx[i], input_frame, norm_data_in ); + scale_sig32( data_fx[i], input_frame, norm_data_in ); /* st_ivas->q_data_fx + norm_data_in */ } st_ivas->q_data_fx = add( st_ivas->q_data_fx, norm_data_in ); move16(); @@ -377,14 +379,14 @@ ivas_error ivas_enc_fx( } ELSE IF( EQ_32( st_ivas->ism_mode, ISM_MASA_MODE_DISC ) ) { - flag_omasa_ener_brate = ivas_omasa_ener_brate_fx( st_ivas->hEncoderConfig->nchan_ism, ivas_total_brate, data_fx, input_frame, sub( 31, st_ivas->q_data_fx ) ); + flag_omasa_ener_brate = ivas_omasa_ener_brate_fx( st_ivas->hEncoderConfig->nchan_ism, ivas_total_brate, data_fx, input_frame, sub( 31, st_ivas->q_data_fx ) ); /* Q0 */ /* Analysis, decision about bitrates per channel & core coding */ IF( NE_32( ( error = ivas_ism_enc_fx( st_ivas, data_fx, st_ivas->q_data_fx, input_frame, &nb_bits_metadata[1], flag_omasa_ener_brate ) ), IVAS_ERR_OK ) ) { return error; } - n = st_ivas->hEncoderConfig->nchan_ism; + n = st_ivas->hEncoderConfig->nchan_ism; /* Q0 */ move16(); } @@ -398,7 +400,19 @@ ivas_error ivas_enc_fx( } /* Encode MASA parameters and write MASA metadata bitstream */ - IF( NE_32( ( error = ivas_masa_encode_fx( st_ivas->hMasa, st_ivas->hQMetaData, hMetaData, nb_bits_metadata, st_ivas->nchan_transport, ivas_format, ivas_total_brate, st_ivas->hEncoderConfig->Opt_DTX_ON, st_ivas->nchan_transport == 2 ? st_ivas->hCPE[0]->element_mode : -1, + Word16 element_mode; + if ( st_ivas->nchan_transport == 2 ) + { + element_mode = st_ivas->hCPE[0]->element_mode; + move16(); + } + else + { + element_mode = -1; + move16(); + } + + IF( NE_32( ( error = ivas_masa_encode_fx( st_ivas->hMasa, st_ivas->hQMetaData, hMetaData, nb_bits_metadata, st_ivas->nchan_transport, ivas_format, ivas_total_brate, st_ivas->hEncoderConfig->Opt_DTX_ON, element_mode, st_ivas->ism_mode, hEncoderConfig->nchan_ism, st_ivas->hIsmMetaData, idx_separated_object, st_ivas->hOMasa, st_ivas->hIsmMetaData[0]->ism_imp, flag_omasa_ener_brate ) ), IVAS_ERR_OK ) ) { @@ -430,11 +444,11 @@ ivas_error ivas_enc_fx( IF( st_ivas->ism_mode == ISM_MODE_NONE ) { - nchan = imult1616( add( st_ivas->sba_analysis_order, 1 ), add( st_ivas->sba_analysis_order, 1 ) ); + nchan = imult1616( add( st_ivas->sba_analysis_order, 1 ), add( st_ivas->sba_analysis_order, 1 ) ); /* Q0 */ } ELSE { - nchan = hEncoderConfig->nchan_ism; + nchan = hEncoderConfig->nchan_ism; /* Q0 */ move16(); } FOR( n = 0; n < nchan; n++ ) @@ -459,27 +473,27 @@ ivas_error ivas_enc_fx( } /* SBA metadata encoding and SBA metadata bitstream writing */ - IF( NE_32( ( error = ivas_spar_enc_fx( st_ivas, data_fx, input_frame, nb_bits_metadata, hMetaData ) ), IVAS_ERR_OK ) ) + IF( ( error = ivas_spar_enc_fx( st_ivas, data_fx, input_frame, nb_bits_metadata, hMetaData ) ) != IVAS_ERR_OK ) { return error; } - hEncoderConfig->sba_planar = planar_sba_orig; + hEncoderConfig->sba_planar = planar_sba_orig; /* Q0 */ move16(); } ELSE { - n = hEncoderConfig->nchan_ism; + n = hEncoderConfig->nchan_ism; /* Q0 */ move16(); hMetaData = st_ivas->hCPE[st_ivas->nCPE - 1]->hMetaData; - IF( NE_32( ( error = ivas_ism_metadata_enc( &st_ivas->hEncoderConfig->ivas_total_brate, n, st_ivas->hEncoderConfig->nchan_ism, st_ivas->hIsmMetaData, NULL, hMetaData, &nb_bits_metadata[1], 0, st_ivas->ism_mode, NULL, st_ivas->hEncoderConfig->ism_extended_metadata_flag, -256 /* -1.0f in Q8 */, 0, NULL, st_ivas->hCPE[0]->hCoreCoder[0]->ini_frame ) ), IVAS_ERR_OK ) ) + IF( ( error = ivas_ism_metadata_enc_fx( &st_ivas->hEncoderConfig->ivas_total_brate, n, st_ivas->hEncoderConfig->nchan_ism, st_ivas->hIsmMetaData, NULL, hMetaData, &nb_bits_metadata[1], 0, st_ivas->ism_mode, NULL, st_ivas->hEncoderConfig->ism_extended_metadata_flag, -256 /* -1.0f in Q8 */, 0, NULL, st_ivas->hCPE[0]->hCoreCoder[0]->ini_frame ) ) != IVAS_ERR_OK ) { return error; } /* SBA metadata encoding and SBA metadata bitstream writing */ - IF( NE_32( ( error = ivas_spar_enc_fx( st_ivas, &data_fx[n], input_frame, nb_bits_metadata, hMetaData ) ), IVAS_ERR_OK ) ) + IF( ( error = ivas_spar_enc_fx( st_ivas, &data_fx[n], input_frame, nb_bits_metadata, hMetaData ) ) != IVAS_ERR_OK ) { return error; } @@ -491,21 +505,21 @@ ivas_error ivas_enc_fx( /* core-coding of transport channels */ IF( EQ_16( st_ivas->nSCE, 1 ) ) { - IF( NE_32( ( error = ivas_sce_enc_fx( st_ivas, 0, data_fx[0], st_ivas->q_data_fx, input_frame, nb_bits_metadata[0] ) ), IVAS_ERR_OK ) ) + IF( ( error = ivas_sce_enc_fx( st_ivas, 0, data_fx[0], st_ivas->q_data_fx, input_frame, nb_bits_metadata[0] ) ) != IVAS_ERR_OK ) { return error; } } ELSE IF( EQ_16( st_ivas->nCPE, 1 ) ) /* Stereo DMX */ { - IF( NE_32( ( error = ivas_cpe_enc_fx( st_ivas, 0, data_fx[0], data_fx[1], st_ivas->q_data_fx, input_frame, nb_bits_metadata[0], NULL ) ), IVAS_ERR_OK ) ) + IF( ( error = ivas_cpe_enc_fx( st_ivas, 0, data_fx[0], data_fx[1], st_ivas->q_data_fx, input_frame, nb_bits_metadata[0], NULL ) ) != IVAS_ERR_OK ) { return error; } } ELSE IF( GT_16( st_ivas->nCPE, 1 ) ) /* FOA/HOA format */ { - IF( NE_32( ( error = ivas_mct_enc_fx( st_ivas, data_fx, st_ivas->q_data_fx, input_frame, nb_bits_metadata[0] ) ), IVAS_ERR_OK ) ) + IF( ( error = ivas_mct_enc_fx( st_ivas, data_fx, st_ivas->q_data_fx, input_frame, nb_bits_metadata[0] ) ) != IVAS_ERR_OK ) { return error; } @@ -514,7 +528,7 @@ ivas_error ivas_enc_fx( ELSE IF( EQ_32( ivas_format, MC_FORMAT ) ) { /* select MC format mode; write MC LS setup; reconfigure the MC format encoder */ - IF( NE_32( ( error = ivas_mc_enc_config_fx( st_ivas ) ), IVAS_ERR_OK ) ) + IF( ( error = ivas_mc_enc_config_fx( st_ivas ) ) != IVAS_ERR_OK ) { return error; } @@ -571,7 +585,7 @@ ivas_error ivas_enc_fx( ivas_lfe_enc_fx( st_ivas->hLFE, data_fx[LFE_CHANNEL], st_ivas->q_data_fx, input_frame, st_ivas->hLFE->hBstr ); - IF( NE_32( ( error = ivas_mct_enc_fx( st_ivas, data_fx, st_ivas->q_data_fx, input_frame, hMetaData->nb_bits_tot ) ), IVAS_ERR_OK ) ) + IF( ( error = ivas_mct_enc_fx( st_ivas, data_fx, st_ivas->q_data_fx, input_frame, hMetaData->nb_bits_tot ) ) != IVAS_ERR_OK ) { return error; } @@ -583,14 +597,14 @@ ivas_error ivas_enc_fx( IF( EQ_16( st_ivas->nCPE, 1 ) ) /* Stereo DMX */ { - IF( NE_32( ( error = ivas_cpe_enc_fx( st_ivas, 0, data_fx[0], data_fx[1], st_ivas->q_data_fx, input_frame, hMetaData->nb_bits_tot, NULL ) ), IVAS_ERR_OK ) ) + IF( ( error = ivas_cpe_enc_fx( st_ivas, 0, data_fx[0], data_fx[1], st_ivas->q_data_fx, input_frame, hMetaData->nb_bits_tot, NULL ) ) != IVAS_ERR_OK ) { return error; } } ELSE IF( GT_16( st_ivas->nCPE, 1 ) ) { - IF( NE_32( ( error = ivas_mct_enc_fx( st_ivas, data_fx, st_ivas->q_data_fx, input_frame, hMetaData->nb_bits_tot ) ), IVAS_ERR_OK ) ) + IF( ( error = ivas_mct_enc_fx( st_ivas, data_fx, st_ivas->q_data_fx, input_frame, hMetaData->nb_bits_tot ) ) != IVAS_ERR_OK ) { return error; } @@ -625,23 +639,23 @@ ivas_error ivas_enc_fx( scale_sig32( st_ivas->hQMetaData->q_direction[0].band_data[i].energy_ratio_fx, MAX_PARAM_SPATIAL_SUBFRAMES, -1 ); // Q31 -> Q30 } - IF( NE_32( ( error = ivas_masa_encode_fx( st_ivas->hMasa, st_ivas->hQMetaData, hMetaData, &nb_bits_metadata[0], st_ivas->nchan_transport, ivas_format, ivas_total_brate, 0, -1, - ISM_MODE_NONE, -1, NULL, -1, NULL, 0, 0 ) ), - IVAS_ERR_OK ) ) + IF( ( error = ivas_masa_encode_fx( st_ivas->hMasa, st_ivas->hQMetaData, hMetaData, &nb_bits_metadata[0], st_ivas->nchan_transport, ivas_format, ivas_total_brate, 0, -1, + ISM_MODE_NONE, -1, NULL, -1, NULL, 0, 0 ) ) != + IVAS_ERR_OK ) { return error; } IF( st_ivas->hMcMasa->separateChannelEnabled ) { - IF( NE_32( ( error = ivas_sce_enc_fx( st_ivas, 0, data_fx[2], st_ivas->q_data_fx, input_frame, 0 ) ), IVAS_ERR_OK ) ) + IF( ( error = ivas_sce_enc_fx( st_ivas, 0, data_fx[2], st_ivas->q_data_fx, input_frame, 0 ) ) != IVAS_ERR_OK ) { return error; } st_ivas->hCPE[0]->hCoreCoder[0]->hBstr->ind_list = st_ivas->hSCE[0]->hCoreCoder[0]->hBstr->ind_list + st_ivas->hSCE[0]->hCoreCoder[0]->hBstr->nb_ind_tot; - IF( NE_32( ( error = ivas_cpe_enc_fx( st_ivas, 0, data_fx[0], data_fx[1], st_ivas->q_data_fx, input_frame, hMetaData->nb_bits_tot, NULL ) ), IVAS_ERR_OK ) ) + IF( ( error = ivas_cpe_enc_fx( st_ivas, 0, data_fx[0], data_fx[1], st_ivas->q_data_fx, input_frame, hMetaData->nb_bits_tot, NULL ) ) != IVAS_ERR_OK ) { return error; } @@ -650,14 +664,14 @@ ivas_error ivas_enc_fx( { IF( EQ_16( st_ivas->nSCE, 1 ) ) { - IF( NE_32( ( error = ivas_sce_enc_fx( st_ivas, 0, data_fx[0], st_ivas->q_data_fx, input_frame, hMetaData->nb_bits_tot ) ), IVAS_ERR_OK ) ) + IF( ( error = ivas_sce_enc_fx( st_ivas, 0, data_fx[0], st_ivas->q_data_fx, input_frame, hMetaData->nb_bits_tot ) ) != IVAS_ERR_OK ) { return error; } } ELSE IF( EQ_16( st_ivas->nCPE, 1 ) ) /* Stereo DMX */ { - IF( NE_32( ( error = ivas_cpe_enc_fx( st_ivas, 0, data_fx[0], data_fx[1], st_ivas->q_data_fx, input_frame, hMetaData->nb_bits_tot, NULL ) ), IVAS_ERR_OK ) ) + IF( ( error = ivas_cpe_enc_fx( st_ivas, 0, data_fx[0], data_fx[1], st_ivas->q_data_fx, input_frame, hMetaData->nb_bits_tot, NULL ) ) != IVAS_ERR_OK ) { return error; } diff --git a/lib_enc/ivas_entropy_coder.c b/lib_enc/ivas_entropy_coder_fx.c similarity index 73% rename from lib_enc/ivas_entropy_coder.c rename to lib_enc/ivas_entropy_coder_fx.c index 9949aab631b0a61d79d957f54ed71601fc9fdf6e..3c8cf92e2f2ef39cf45042599aa58217fad99328 100644 --- a/lib_enc/ivas_entropy_coder.c +++ b/lib_enc/ivas_entropy_coder_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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,8 +34,7 @@ #include #include "options.h" #include "ivas_cnst.h" -#include "prot.h" -#include "ivas_prot.h" +#include "prot_fx.h" #include "ivas_rom_com.h" #include "math.h" #include "wmc_auto.h" @@ -51,18 +50,19 @@ *-----------------------------------------------------------------------------------------*/ static ivas_error ivas_get_dyn_freq_model_fx( - Word16 *pInput, - const Word16 length, - Word16 *model_index, + Word16 *pInput, /* Q0 */ + const Word16 length, /* Q0 */ + Word16 *model_index, /* Q0 */ ivas_arith_t *pArith, - Word16 **ppCum_freq ) + Word16 **ppCum_freq /* Q0 */ +) { Word32 curr_dist[IVAS_MAX_QUANT_LEVELS]; Word16 i, n[IVAS_MAX_QUANT_LEVELS + 1], model_idx; Word32 curr_bps, curr_bps_min, curr_bps_new; Word16 range = pArith->range; Word16 m; - Word16 offset = negate( pArith->vals[0] ); + Word16 offset = negate( pArith->vals[0] ); /* Q0 */ ivas_error error; error = IVAS_ERR_OK; move32(); @@ -75,7 +75,7 @@ static ivas_error ivas_get_dyn_freq_model_fx( FOR( i = 0; i < length; i++ ) { - n[pInput[i] + offset] = add( n[pInput[i] + offset], 1 ); + n[pInput[i] + offset] = add( n[pInput[i] + offset], 1 ); /* Q0 */ move16(); } @@ -85,7 +85,7 @@ static ivas_error ivas_get_dyn_freq_model_fx( { curr_dist[i] = L_deposit_l( n[i] ); move32(); - curr_bps = L_sub( curr_bps, curr_dist[i] * pArith->saved_dist_arr[0][i] ); + curr_bps = L_sub( curr_bps, W_extract_l( W_mult0_32_32( curr_dist[i], pArith->saved_dist_arr[0][i] ) ) ); } curr_bps_min = curr_bps; move32(); @@ -104,7 +104,7 @@ static ivas_error ivas_get_dyn_freq_model_fx( move32(); FOR( i = 0; i < range; i++ ) { - curr_bps_new = L_sub( curr_bps_new, ( curr_dist[i] * pArith->saved_dist_arr[m + 1][i] ) ); + curr_bps_new = L_sub( curr_bps_new, W_extract_l( W_mult0_32_32( curr_dist[i], pArith->saved_dist_arr[m + 1][i] ) ) ); } #ifdef DEBUGGING { @@ -123,32 +123,34 @@ static ivas_error ivas_get_dyn_freq_model_fx( IF( LT_32( curr_bps_min, curr_bps ) ) { - *ppCum_freq = pArith->cum_freq[model_idx + 1]; - model_idx = add( model_idx, 1 ); + *ppCum_freq = pArith->cum_freq[model_idx + 1]; /* Q0 */ + model_idx = add( model_idx, 1 ); /* Q0 */ } ELSE { model_idx = 0; - *ppCum_freq = pArith->cum_freq[0]; + move16(); + *ppCum_freq = pArith->cum_freq[0]; /* Q0 */ } - *model_index = model_idx; + *model_index = model_idx; /* Q0 */ move16(); return error; } /*-----------------------------------------------------------------------------------------* - * Function ivas_arith_encode_array() + * Function ivas_arith_encode_array_fx() * * Arith encoding of an array of symbols *-----------------------------------------------------------------------------------------*/ -static Word16 ivas_arith_encode_array( - Word16 *pInput, +static Word16 ivas_arith_encode_array_fx( + Word16 *pInput, /* Q0 */ ivas_arith_t *pArith, BSTR_ENC_HANDLE hMetaData, - const Word16 in_len, - const Word16 wc_strat_arith ) + const Word16 in_len, /* Q0 */ + const Word16 wc_strat_arith /* Q0 */ +) { Word16 model_index, i, ind; Word16 *pCum_freq = NULL; @@ -168,14 +170,14 @@ static Word16 ivas_arith_encode_array( } ELSE { - pCum_freq = pArith->cum_freq[0]; + pCum_freq = pArith->cum_freq[0]; /* Q0 */ } - ari_start_encoding_14bits( &as ); + ari_start_encoding_14bits_ivas_fx( &as ); FOR( i = 0; i < in_len; i++ ) { - ind = sub( pInput[i], pArith->vals[0] ); + ind = sub( pInput[i], pArith->vals[0] ); /* Q0 */ ivas_ari_encode_14bits_ext_fx( hMetaData, &as, ind, (const UWord16 *) pCum_freq ); IF( GT_16( hMetaData->nb_bits_tot, wc_strat_arith ) ) { @@ -195,18 +197,19 @@ static Word16 ivas_arith_encode_array( /*-----------------------------------------------------------------------------------------* - * Function ivas_arithCoder_encode_array_diff() + * Function ivas_arithCoder_encode_array_diff_fx() * * Differential arith encoding *-----------------------------------------------------------------------------------------*/ -static Word16 ivas_arithCoder_encode_array_diff( +static Word16 ivas_arithCoder_encode_array_diff_fx( ivas_arith_t *pArith_diff, - Word16 *pIn_new, - Word16 *pIn_old_scratch, - const Word16 length, + Word16 *pIn_new, /* Q0 */ + Word16 *pIn_old_scratch, /* Q0 */ + const Word16 length, /* Q0 */ BSTR_ENC_HANDLE hMetaData, - const Word16 wc_strat_arith ) + const Word16 wc_strat_arith /* Q0 */ +) { Word16 n; Word16 arith_result; @@ -215,13 +218,13 @@ static Word16 ivas_arithCoder_encode_array_diff( { FOR( n = 0; n < length; n++ ) { - pIn_old_scratch[n] = sub( pIn_new[n], pIn_old_scratch[n] ); + pIn_old_scratch[n] = sub( pIn_new[n], pIn_old_scratch[n] ); /* Q0 */ move16(); } ivas_wrap_arround_fx( pIn_old_scratch, pArith_diff->vals[0], pArith_diff->vals[pArith_diff->range - 1], length ); - arith_result = ivas_arith_encode_array( pIn_old_scratch, pArith_diff, hMetaData, length, wc_strat_arith ); + arith_result = ivas_arith_encode_array_fx( pIn_old_scratch, pArith_diff, hMetaData, length, wc_strat_arith ); /* Q0 */ IF( arith_result < 0 ) { return -1; @@ -233,27 +236,28 @@ static Word16 ivas_arithCoder_encode_array_diff( /*-----------------------------------------------------------------------------------------* - * Function ivas_huffman_encode() + * Function ivas_huffman_encode_fx() * * ivas_huffman_encode *-----------------------------------------------------------------------------------------*/ -void ivas_huffman_encode( +void ivas_huffman_encode_fx( ivas_huffman_cfg_t *huff_cfg, - Word16 in, - Word16 *hcode, - Word16 *hlen ) + Word16 in, /* Q0 */ + Word16 *hcode, /* Q0 */ + Word16 *hlen /* Q0 */ +) { Word16 min_sym_val; const Word16 *codebook; - min_sym_val = huff_cfg->codebook[0]; + min_sym_val = huff_cfg->codebook[0]; /* Q0 */ move16(); - codebook = &huff_cfg->codebook[3 * ( in - min_sym_val )]; - *hlen = codebook[1]; + codebook = &huff_cfg->codebook[3 * ( in - min_sym_val )]; /* Q0 */ + *hlen = codebook[1]; /* Q0 */ move16(); - *hcode = codebook[2]; + *hcode = codebook[2]; /* Q0 */ move16(); return; @@ -261,17 +265,17 @@ void ivas_huffman_encode( /*-----------------------------------------------------------------------------------------* - * Function arith_encode_cell_array() + * Function arith_encode_cell_array_fx() * * Arithmetic encode a cell array *-----------------------------------------------------------------------------------------*/ -static Word16 arith_encode_cell_array( +static Word16 arith_encode_cell_array_fx( ivas_cell_dim_t *pCell_dims, BSTR_ENC_HANDLE hMetaData, - const Word16 nB, + const Word16 nB, /* Q0 */ ivas_arith_t *pArith, - Word16 *pSymbol, + Word16 *pSymbol, /* Q0 */ const Word16 wc_strat_arith ) { Word16 total_symbol_len = 0; @@ -281,7 +285,7 @@ static Word16 arith_encode_cell_array( FOR( i = 0; i < nB; i++ ) { - total_symbol_len = add( total_symbol_len, imult1616( pCell_dims[i].dim1, pCell_dims[i].dim2 ) ); + total_symbol_len = add( total_symbol_len, imult1616( pCell_dims[i].dim1, pCell_dims[i].dim2 ) ); /* Q0 */ } assert( LE_16( total_symbol_len, ( IVAS_MAX_INPUT_LEN ) ) ); @@ -290,7 +294,7 @@ static Word16 arith_encode_cell_array( { IF( GT_16( pArith->range, 1 ) ) { - arith_result = ivas_arith_encode_array( pSymbol, pArith, hMetaData, total_symbol_len, wc_strat_arith ); + arith_result = ivas_arith_encode_array_fx( pSymbol, pArith, hMetaData, total_symbol_len, wc_strat_arith ); /* Q0 */ IF( arith_result < 0 ) { return -1; @@ -303,19 +307,20 @@ static Word16 arith_encode_cell_array( /*-----------------------------------------------------------------------------------------* - * Function arith_encode_cell_array_diff() + * Function arith_encode_cell_array_diff_fx() * * Arithmetic encode a cell array - differential *-----------------------------------------------------------------------------------------*/ -static Word16 arith_encode_cell_array_diff( +static Word16 arith_encode_cell_array_diff_fx( const ivas_cell_dim_t *pCell_dims, BSTR_ENC_HANDLE hMetaData, - Word16 nB, + Word16 nB, /* Q0 */ ivas_arith_t *pArith_diff, - Word16 *pSymbol_old, - Word16 *pSymbol, - const Word16 wc_strat_arith ) + Word16 *pSymbol_old, /* Q0 */ + Word16 *pSymbol, /* Q0 */ + const Word16 wc_strat_arith /* Q0 */ +) { Word16 i, total_symbol_len; Word16 arith_result; @@ -324,7 +329,7 @@ static Word16 arith_encode_cell_array_diff( move16(); FOR( i = 0; i < nB; i++ ) { - total_symbol_len = add( total_symbol_len, ( imult1616( pCell_dims[i].dim1, pCell_dims[i].dim2 ) ) ); + total_symbol_len = add( total_symbol_len, ( imult1616( pCell_dims[i].dim1, pCell_dims[i].dim2 ) ) ); /* Q0 */ } assert( LE_16( total_symbol_len, ( IVAS_MAX_INPUT_LEN ) ) ); @@ -333,7 +338,7 @@ static Word16 arith_encode_cell_array_diff( { IF( GT_16( pArith_diff->range, 1 ) ) { - arith_result = ivas_arithCoder_encode_array_diff( pArith_diff, pSymbol, pSymbol_old, total_symbol_len, hMetaData, wc_strat_arith ); + arith_result = ivas_arithCoder_encode_array_diff_fx( pArith_diff, pSymbol, pSymbol_old, total_symbol_len, hMetaData, wc_strat_arith ); /* Q0 */ IF( arith_result < 0 ) { return -1; @@ -346,22 +351,23 @@ static Word16 arith_encode_cell_array_diff( /*-----------------------------------------------------------------------------------------* - * Function ivas_arith_encode_cmplx_cell_array() + * Function ivas_arith_encode_cmplx_cell_array_fx() * * Arithmetic encode a cell array *-----------------------------------------------------------------------------------------*/ -Word16 ivas_arith_encode_cmplx_cell_array( +Word16 ivas_arith_encode_cmplx_cell_array_fx( ivas_arith_t *pArith_re, ivas_arith_t *pArith_re_diff, - const Word16 *pDo_diff, - const Word16 nB, - Word16 *pSymbol_re, - Word16 *pSymbol_old_re, + const Word16 *pDo_diff, /* Q0 */ + const Word16 nB, /* Q0 */ + Word16 *pSymbol_re, /* Q0 */ + Word16 *pSymbol_old_re, /* Q0 */ ivas_cell_dim_t *pCell_dims, BSTR_ENC_HANDLE hMetaData, - const Word16 any_diff, - const Word16 wc_strat_arith ) + const Word16 any_diff, /* Q0 */ + const Word16 wc_strat_arith /* Q0 */ +) { Word16 input_old[IVAS_MAX_INPUT_LEN]; Word16 input_new[IVAS_MAX_INPUT_LEN]; @@ -381,19 +387,19 @@ Word16 ivas_arith_encode_cmplx_cell_array( move16(); FOR( i = 0; i < nB; i++ ) { - len = ( imult1616( pCell_dims[i].dim1, pCell_dims[i].dim2 ) ); + len = ( imult1616( pCell_dims[i].dim1, pCell_dims[i].dim2 ) ); /* Q0 */ move16(); IF( pDo_diff[i] != 0 ) { FOR( j = 0; j < len; j++ ) { - input_old[idx] = pSymbol_old_re[total_len + j]; - input_new[idx++] = pSymbol_re[total_len + j]; + input_old[idx] = pSymbol_old_re[total_len + j]; /* Q0 */ + input_new[idx++] = pSymbol_re[total_len + j]; /* Q0 */ move16(); move16(); } - cell_dim_diff[i].dim1 = pCell_dims[i].dim1; - cell_dim_diff[i].dim2 = pCell_dims[i].dim2; + cell_dim_diff[i].dim1 = pCell_dims[i].dim1; /* Q0 */ + cell_dim_diff[i].dim2 = pCell_dims[i].dim2; /* Q0 */ cell_dim[i].dim1 = 0; cell_dim[i].dim2 = 0; move16(); @@ -405,28 +411,28 @@ Word16 ivas_arith_encode_cmplx_cell_array( { FOR( j = 0; j < len; j++ ) { - input[idx1++] = pSymbol_re[total_len + j]; + input[idx1++] = pSymbol_re[total_len + j]; /* Q0 */ move16(); } cell_dim_diff[i].dim1 = 0; cell_dim_diff[i].dim2 = 0; - cell_dim[i].dim1 = pCell_dims[i].dim1; - cell_dim[i].dim2 = pCell_dims[i].dim2; + cell_dim[i].dim1 = pCell_dims[i].dim1; /* Q0 */ + cell_dim[i].dim2 = pCell_dims[i].dim2; /* Q0 */ move16(); move16(); move16(); move16(); } - total_len = add( total_len, len ); + total_len = add( total_len, len ); /* Q0 */ } - arith_result = arith_encode_cell_array( cell_dim, hMetaData, nB, pArith_re, input, wc_strat_arith ); + arith_result = arith_encode_cell_array_fx( cell_dim, hMetaData, nB, pArith_re, input, wc_strat_arith ); /* Q0 */ IF( arith_result < 0 ) { return -1; } - arith_result = arith_encode_cell_array_diff( cell_dim_diff, hMetaData, nB, pArith_re_diff, input_old, input_new, wc_strat_arith ); + arith_result = arith_encode_cell_array_diff_fx( cell_dim_diff, hMetaData, nB, pArith_re_diff, input_old, input_new, wc_strat_arith ); /* Q0 */ move16(); IF( arith_result < 0 ) { @@ -435,7 +441,7 @@ Word16 ivas_arith_encode_cmplx_cell_array( } ELSE { - arith_result = arith_encode_cell_array( pCell_dims, hMetaData, nB, pArith_re, pSymbol_re, wc_strat_arith ); + arith_result = arith_encode_cell_array_fx( pCell_dims, hMetaData, nB, pArith_re, pSymbol_re, wc_strat_arith ); /* Q0 */ IF( arith_result < 0 ) { return -1; diff --git a/lib_enc/ivas_front_vad.c b/lib_enc/ivas_front_vad_fx.c similarity index 67% rename from lib_enc/ivas_front_vad.c rename to lib_enc/ivas_front_vad_fx.c index f892dca8f87d7936ebbb81c09e093f94221a4a7c..8b76b37a44dc1d3a1ddf0fa7b98ece00ddc1172c 100644 --- a/lib_enc/ivas_front_vad.c +++ b/lib_enc/ivas_front_vad_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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,14 +36,12 @@ #include "ivas_cnst.h" #include "rom_enc.h" #include "rom_com.h" -#include "prot.h" -#include "ivas_prot.h" +#include "prot_fx.h" #include "prot_fx_enc.h" #include #include "wmc_auto.h" #include #include "prot_fx_enc.h" -#include "prot_fx.h" #include "ivas_prot_fx.h" /*-----------------------------------------------------------------------------------------* @@ -52,21 +50,25 @@ * Standalone front-VAD module *-----------------------------------------------------------------------------------------*/ ivas_error front_vad_fx( - CPE_ENC_HANDLE hCPE, /* i/o: CPE encoder structure, nullable */ - Encoder_State *st, /* i/o: encoder state structure */ - const ENCODER_CONFIG_HANDLE hEncoderConfig, /* i : configuration structure */ - FRONT_VAD_ENC_HANDLE *hFrontVads, /* i/o: FrontVad handles */ - const Word16 MCT_flag, /* i : hMCT handle allocated (1) or not (0) */ - const Word16 input_frame, /* i : frame length */ - Word16 vad_flag_dtx[], /* o : HE-SAD flag with additional DTX HO */ - Word32 fr_bands_fx[][2 * NB_BANDS], /* o : energy in frequency bands Q_buffer[n] + QSCALE + 2 */ - Word16 Etot_LR_fx[], /* o : total energy Left & Right channel Q8 */ - Word32 lf_E_fx[][2 * VOIC_BINS], /* i : per bin spectrum energy in lf, LR channels Q_buffer[n] + QSCALE */ - Word16 localVAD_HE_SAD[], /* o : HE-SAD flag without hangover, LR channels */ - Word16 vad_hover_flag[], /* o : VAD hangover flag */ - Word32 band_energies_LR_fx[2 * NB_BANDS], /* o : energy in critical bands without minimum noise floor E_MIN Q_buffer[1] + QSCALE + 2 - band_ener_guardbits*/ - Word32 *PS_out_fx, /* o : energy spectrum Q_buffer + QSCALE */ - Word16 *Bin_E_out_fx, /* o : log-energy spectrum of the current frame Q7 */ + CPE_ENC_HANDLE hCPE, /* i/o: CPE encoder structure, nullable */ + Encoder_State *st, /* i/o: encoder state structure */ + const ENCODER_CONFIG_HANDLE hEncoderConfig, /* i : configuration structure */ + FRONT_VAD_ENC_HANDLE *hFrontVads, /* i/o: FrontVad handles */ + const Word16 MCT_flag, /* i : hMCT handle allocated (1) or not (0) Q0*/ + const Word16 input_frame, /* i : frame length Q0*/ + Word16 vad_flag_dtx[], /* o : HE-SAD flag with additional DTX HO Q0*/ + Word32 fr_bands_fx[][2 * NB_BANDS], /* o : energy in frequency bands q_fr_bands_fx*/ + Word16 q_fr_bands[], /* o : Q of fr_bands_fx */ + Word16 Etot_LR_fx[], /* o : total energy Left & Right channel Q8*/ + Word32 lf_E_fx[][2 * VOIC_BINS], /* i : per bin spectrum energy in lf, LR channels q_lf_E*/ + Word16 q_lf_E[], /* o : Q of lf_E_fx */ + Word16 localVAD_HE_SAD[], /* o : HE-SAD flag without hangover, LR channels Q0*/ + Word16 vad_hover_flag[], /* o : VAD hangover flag Q0*/ + Word32 band_energies_LR_fx[2 * NB_BANDS], /* o : energy in critical bands without minimum noise floor E_MIN q_band_energies_LR */ + Word16 *q_band_energies_LR, /* o : Q of band_energies_LR_fx */ + Word32 *PS_out_fx, /* o : energy spectrum q_PS_out*/ + Word16 *q_PS_out, /* o : Q of PS_out_fx Q0*/ + Word16 *Bin_E_out_fx, /* o : log-energy spectrum of the current frame Q7*/ Word16 Q_inp, Word16 *Q_buffer, Word16 Q_add, @@ -86,24 +88,30 @@ ivas_error front_vad_fx( Word16 dummy_short; Word16 element_mode, last_element_mode; ivas_error error; - Word16 Q_new = 0, band_ener_guardbits = 0; + Word16 Q_new; Word16 Qband, mem_decim_size; error = IVAS_ERR_OK; push_wmops( "front_vad" ); + move16(); + move16(); + + Q_new = 0; + move16(); lgBin_E_fx = NULL; if ( st != NULL ) { - lgBin_E_fx = &st->lgBin_E_fx[0]; + lgBin_E_fx = &st->lgBin_E_fx[0]; /* Q8 */ move16(); } IF( hCPE != NULL ) { n_chan = CPE_CHANNELS; + move16(); sts = &hCPE->hCoreCoder[0]; - element_mode = hCPE->element_mode; + element_mode = hCPE->element_mode; /* Q0 */ move16(); - last_element_mode = hCPE->last_element_mode; + last_element_mode = hCPE->last_element_mode; /* Q0 */ move16(); } ELSE IF( st != NULL ) @@ -186,19 +194,32 @@ ivas_error front_vad_fx( set_val_Word32( band_energies_LR_fx, 0, 2 * NB_BANDS ); Qband = -1; move16(); - Word16 Q_new_old = add( sub( Q_inp, Qband ), Q_add ); IF( *front_create_flag ) { + Word16 scale_inp = Q15; + Q_add = 0; + move16(); FOR( n = 0; n < n_chan; n++ ) { - scale_sig32( hFrontVads[n]->hNoiseEst->bckr_fx, 20, sub( add( Q_new_old, QSCALE ), Q11 ) ); - scale_sig32( hFrontVads[n]->hNoiseEst->enrO_fx, 20, sub( add( Q_new_old, QSCALE ), Q11 ) ); hFrontVads[n]->lp_speech_fx = shr( hFrontVads[n]->lp_speech_fx, 1 ); move16(); + + scale_inp = s_min( sts[n]->q_inp, hCPE->hFrontVad[n]->q_mem_decim ); + Scale_sig( sts[n]->input_fx, input_frame, sub( scale_inp, sts[n]->q_inp ) ); + Scale_sig( hCPE->hFrontVad[n]->mem_decim_fx, 2 * L_FILT_MAX, sub( scale_inp, hCPE->hFrontVad[n]->q_mem_decim ) ); + sts[n]->q_inp = scale_inp; + hCPE->hFrontVad[n]->q_mem_decim = scale_inp; + Q_inp = scale_inp; + move16(); + Q_buffer[n] = hCPE->hFrontVad[n]->q_buffer_12k8; + move16(); } } - band_ener_guardbits = find_guarded_bits_fx( 2 * NB_BANDS ); + + Word16 q_Bin_E, q_Bin_E_old; + Word16 q_band_energies; + Word16 q_fft_buffLR; FOR( n = 0; n < n_chan; n++ ) { FRONT_VAD_ENC_HANDLE hFrontVad; @@ -212,50 +233,80 @@ ivas_error front_vad_fx( modify_Fs_fx( sts[n]->input_fx, input_frame, sts[0]->input_Fs, hFrontVad->buffer_12k8_fx + L_FFT / 2, INT_FS_12k8, hFrontVad->mem_decim_fx, ( sts[0]->max_bwidth == NB ), &Qband, &mem_decim_size ); /* Preemphasis */ - hFrontVad->mem_preemph_fx = shl( hFrontVad->mem_preemph_fx, sub( add( Q_inp, Qband ), hFrontVad->q_mem_preemph_fx ) ); + hFrontVad->mem_preemph_fx = shl( hFrontVad->mem_preemph_fx, sub( add( Q_inp, Qband ), hFrontVad->q_mem_preemph_fx ) ); /* Q_inp + Qband */ move16(); hFrontVad->q_mem_preemph_fx = add( Q_inp, Qband ); move16(); PREEMPH_FX( hFrontVad->buffer_12k8_fx + L_FFT / 2, PREEMPH_FAC, L_FRAME, &hFrontVad->mem_preemph_fx ); - Word16 Scale_fac[2]; Q_new = add( sub( Q_inp, Qband ), Q_add ); - Scale_sig( hFrontVad->buffer_12k8_fx, L_FFT / 2, Q_new - Q_buffer[n] ); - Scale_sig( hFrontVad->buffer_12k8_fx + L_FFT / 2, 384 - L_FFT / 2, Q_new - add( Q_inp, Qband ) ); + Scale_sig( hFrontVad->buffer_12k8_fx, L_FFT / 2, sub( Q_new, Q_buffer[n] ) ); /* Q_new */ + Scale_sig( hFrontVad->buffer_12k8_fx + L_FFT / 2, 384 - L_FFT / 2, sub( Q_new, add( Q_inp, Qband ) ) ); /* Q_new */ Q_buffer[n] = Q_new; - Word32 Le_min_scaled = L_shr_r( L_add( L_shr( E_MIN_FXQ15, sub( 14, add( Q_new, QSCALE ) ) ), 1 ), 1 ); - Le_min_scaled = L_shl( Le_min_scaled, 2 ); - ivas_analy_sp_fx( IVAS_CPE_TD, hCPE, sts[0]->input_Fs, hFrontVad->buffer_12k8_fx + L_FFT / 2 - 3 * ( L_SUBFR / 2 ), Q_new, fr_bands_fx[n], lf_E_fx[n], &Etot_LR_fx[n], sts[0]->min_band, sts[0]->max_band, Le_min_scaled, Scale_fac, Bin_E_fx, Bin_E_old_fx, PS_fx, lgBin_E_fx, band_energies_fx, fft_buffLR_fx ); + move16(); + + ivas_analy_sp_fx( IVAS_CPE_TD, hCPE, sts[0]->input_Fs, hFrontVad->buffer_12k8_fx + L_FFT / 2 - 3 * ( L_SUBFR / 2 ), Q_new, fr_bands_fx[n], + &q_fr_bands[n], lf_E_fx[n], &q_lf_E[n], &Etot_LR_fx[n], sts[0]->min_band, sts[0]->max_band, Bin_E_fx, &q_Bin_E, Bin_E_old_fx, + &q_Bin_E_old, PS_fx, q_PS_out, lgBin_E_fx, band_energies_fx, &q_band_energies, fft_buffLR_fx, &q_fft_buffLR ); + if ( n == 0 ) + { + *q_band_energies_LR = q_band_energies; + move16(); + } + + /* v_add( &band_energies[0], &band_energies_LR[0], &band_energies_LR[0], 2 * NB_BANDS ); */ + IF( EQ_16( n, 1 ) ) + { + IF( LT_16( *q_band_energies_LR, q_band_energies ) ) + { + scale_sig32( band_energies_fx, 2 * NB_BANDS, sub( *q_band_energies_LR, q_band_energies ) ); // q_band_energies_LR + } + ELSE + { + scale_sig32( band_energies_LR_fx, 2 * NB_BANDS, sub( q_band_energies, *q_band_energies_LR ) ); // q_band_energies_LR + *q_band_energies_LR = q_band_energies; + move16(); + } + } + + v_add_fx( &band_energies_fx[0], &band_energies_LR_fx[0], &band_energies_LR_fx[0], 2 * NB_BANDS ); // q_band_energies_LR /* add up energies for later calculating average of channel energies */ - // Scale_sig32( &band_energies_LR_fx[0], ( Q_new + QSCALE + 2 ) - ( Q_new_old + QSCALE + 2 - band_ener_guardbits ), 40 ); - Q_new_old = Q_new; - v_add_fixed( &band_energies_fx[0], &band_energies_LR_fx[0], &band_energies_LR_fx[0], 2 * NB_BANDS, band_ener_guardbits ); - Word32 Etot_fx = L_deposit_h( Etot_LR_fx[n] ); + Word32 Etot_fx = L_deposit_h( Etot_LR_fx[n] ); /* Q24 */ noise_est_pre_32fx( Etot_fx, hFrontVads[0]->ini_frame, hFrontVad->hNoiseEst, 0, 0, 0 ); /* wb_vad */ - Scale_sig32( hFrontVads[n]->hNoiseEst->bckr_fx, NB_BANDS, Q_new + QSCALE - ( Q_new_old + QSCALE ) ); - Scale_sig32( hFrontVads[n]->hNoiseEst->enrO_fx, NB_BANDS, Q_new + QSCALE - ( Q_new_old + QSCALE ) ); - hFrontVad->hVAD->vad_flag = wb_vad_ivas_fx( sts[n], fr_bands_fx[n], &dummy, &dummy, &dummy, &snr_sum_he_fx, &localVAD_HE_SAD[n], &dummy_short, Q_new, hFrontVad->hVAD, hFrontVad->hNoiseEst, hFrontVad->lp_speech_fx, hFrontVad->lp_noise_fx ); + Word16 scale = s_min( q_fr_bands[n], add( hFrontVads[n]->hNoiseEst->q_enrO, L_norm_arr( hFrontVads[n]->hNoiseEst->enrO_fx, NB_BANDS ) ) ); + + scale_sig32( hFrontVads[n]->hNoiseEst->enrO_fx, NB_BANDS, sub( scale, hFrontVads[n]->hNoiseEst->q_enrO ) ); // scale + hFrontVads[n]->hNoiseEst->q_enrO = scale; + move16(); + + scale_sig32( fr_bands_fx[n], 2 * NB_BANDS, sub( scale, q_fr_bands[n] ) ); // scale + q_fr_bands[n] = scale; + move16(); + + hFrontVad->hVAD->vad_flag = wb_vad_ivas_fx( sts[n], fr_bands_fx[n], q_fr_bands[n], &dummy, &dummy, &dummy, &snr_sum_he_fx, + &localVAD_HE_SAD[n], &dummy_short, hFrontVad->hVAD, hFrontVad->hNoiseEst, + hFrontVad->lp_speech_fx, hFrontVad->lp_noise_fx ); // Q0 test(); test(); if ( n == 0 && GT_16( n_chan, 1 ) && EQ_16( last_element_mode, IVAS_CPE_DFT ) ) { - sts[1]->last_coder_type = sts[0]->last_coder_type; + sts[1]->last_coder_type = sts[0]->last_coder_type; /* Q0 */ move16(); } - vad_flag_dtx[n] = ivas_dtx_hangover_addition_fx( sts[n], hFrontVad->hVAD->vad_flag, hFrontVad->lp_speech_fx - hFrontVad->lp_noise_fx, 0 /* <- no cldfb addition */, &vad_hover_flag[n], hFrontVad->hVAD, hFrontVad->hNoiseEst, &hFrontVads[n]->rem_dtx_ho ); + vad_flag_dtx[n] = ivas_dtx_hangover_addition_fx( sts[n], hFrontVad->hVAD->vad_flag, sub( hFrontVad->lp_speech_fx, hFrontVad->lp_noise_fx ), 0 /* <- no cldfb addition */, &vad_hover_flag[n], hFrontVad->hVAD, hFrontVad->hNoiseEst, &hFrontVads[n]->rem_dtx_ho ); /* Q0 */ move16(); if ( EQ_16( n_chan, 1 ) ) { - sts[n]->vad_flag = hFrontVad->hVAD->vad_flag; + sts[n]->vad_flag = hFrontVad->hVAD->vad_flag; /* Q0 */ move16(); } } @@ -263,10 +314,12 @@ ivas_error front_vad_fx( IF( EQ_16( n_chan, CPE_CHANNELS ) ) { /* get average channel energies, adding up was already done, so only need to scale by number of channels */ - v_multc_fixed( &band_energies_LR_fx[0], ONE_IN_Q30, &band_energies_LR_fx[0], 2 * NB_BANDS ); + v_multc_fixed( &band_energies_LR_fx[0], ONE_IN_Q30 /* 0.5f in Q31 */, &band_energies_LR_fx[0], 2 * NB_BANDS ); /* Logical OR between L and R decisions */ + test(); vad_flag_dtx[0] = vad_flag_dtx[0] || vad_flag_dtx[1]; + move16(); } IF( sts[0]->hFdCngEnc != NULL ) { @@ -354,15 +407,15 @@ ivas_error front_vad_create_fx( move16(); hFrontVad->q_mem_preemph_fx = Q15; move16(); - hFrontVad->q_buffer_12k8 = Q31; - hFrontVad->q_mem_decim = Q31; + hFrontVad->q_buffer_12k8 = Q15; + hFrontVad->q_mem_decim = Q15; hFrontVad->ini_frame = 0; move16(); hFrontVad->hVAD->vad_flag = 1; move16(); /* allocate delay buffer to compensate for filterbank delay */ - hFrontVad->delay_samples = NS2SA( hEncoderConfig->input_Fs, IVAS_FB_ENC_DELAY_NS ); + hFrontVad->delay_samples = NS2SA_FX2( hEncoderConfig->input_Fs, IVAS_FB_ENC_DELAY_NS ); move16(); hFrontVad->delay_buf_fx = NULL; IF( GT_16( hFrontVad->delay_samples, 0 ) ) @@ -379,30 +432,6 @@ ivas_error front_vad_create_fx( return IVAS_ERR_OK; } -/*-----------------------------------------------------------------------------------------* - * Function front_vad_destroy() - * - * Deallocate Standalone front-VAD module - *-----------------------------------------------------------------------------------------*/ - -void front_vad_destroy( - FRONT_VAD_ENC_HANDLE *hFrontVad /* i/o: front-VAD handle */ -) -{ - IF( *hFrontVad != NULL ) - { - free( ( *hFrontVad )->hNoiseEst ); - ( *hFrontVad )->hNoiseEst = NULL; - - free( ( *hFrontVad )->hVAD ); - ( *hFrontVad )->hVAD = NULL; - - free( *hFrontVad ); - *hFrontVad = NULL; - } - - return; -} void front_vad_destroy_fx( FRONT_VAD_ENC_HANDLE *hFrontVad /* i/o: front-VAD handle */ ) @@ -433,10 +462,10 @@ void front_vad_destroy_fx( * Standalone front-VAD module for SPAR *-----------------------------------------------------------------------------------------*/ ivas_error front_vad_spar_fx( - SPAR_ENC_HANDLE hSpar, /* i/o: SPAR encoder structure */ - const Word32 *omni_in, /* i : omnidirectional input signal Q11 */ - ENCODER_CONFIG_HANDLE hEncoderConfig, /* i : encoder configuration handle */ - const Word16 input_frame /* i : input frame length */ + SPAR_ENC_HANDLE hSpar, /* i/o: SPAR encoder structure */ + const Word32 *omni_in, /* i : omnidirectional input signal Q11*/ + ENCODER_CONFIG_HANDLE hEncoderConfig, /* i : encoder configuration handle */ + const Word16 input_frame /* i : input frame length Q0*/ ) { FRONT_VAD_ENC_HANDLE hFrontVad; @@ -488,6 +517,7 @@ ivas_error front_vad_spar_fx( Word16 tmp; Word16 old_pitch; ivas_error error; + Word16 Qfact_PS; push_wmops( "front_vad_SPAR" ); error = IVAS_ERR_OK; @@ -506,15 +536,6 @@ ivas_error front_vad_spar_fx( move16(); Word16 front_create_flag = 0; move16(); - Word16 Qband = -1; - move16(); - Word16 Q_bands = Q9; - move16(); - - Scale_sig32( hFrontVad->hNoiseEst->ave_enr_fx, NB_BANDS, ( Q_bands + QSCALE ) - hFrontVad->hNoiseEst->ave_enr_q ); - Scale_sig32( hFrontVad->hNoiseEst->ave_enr2_fx, NB_BANDS, ( Q_bands + QSCALE ) - hFrontVad->hNoiseEst->ave_enr_q ); - hFrontVad->hNoiseEst->ave_enr_q = ( Q_bands + QSCALE ); - move16(); Word16 tmp1; Word16 Q_inp_12k8 = hFrontVad->q_buffer_12k8; move16(); @@ -525,8 +546,8 @@ ivas_error front_vad_spar_fx( MVR2R_WORD16( st->old_wsp_fx, old_wsp_fx, L_WSP_MEM ); wsp_fx = old_wsp_fx + L_WSP_MEM; - st->core_brate = -1; /* updated in dtx() */ - st->input_bwidth = st->last_input_bwidth; + st->core_brate = -1; /* updated in dtx() */ + st->input_bwidth = st->last_input_bwidth; /* Q0 */ move32(); move16(); @@ -535,7 +556,7 @@ ivas_error front_vad_spar_fx( *-----------------------------------------------------------------*/ st->input_fx = input_fx; - Copy_Scale_sig32_16( omni_in, st->input_fx, input_frame, Q16 - Q11 ); + Copy_Scale_sig32_16( omni_in, st->input_fx, input_frame, Q16 - Q11 ); /* Q16 */ delay_signal( st->input_fx, input_frame, hFrontVad->delay_buf_fx, hFrontVad->delay_samples ); /* Scaling only if the omni_in buffer contains non-zero values */ @@ -559,7 +580,7 @@ ivas_error front_vad_spar_fx( } IF( tmp != 0 ) { - Scale_sig( st->input_fx, input_frame, s ); + Scale_sig( st->input_fx, input_frame, s ); /* s */ } Q_inp = s; move16(); @@ -568,18 +589,17 @@ ivas_error front_vad_spar_fx( *-----------------------------------------------------------------*/ Word16 scale; - Word16 Q_new_old = add( sub( Q_inp, Qband ), Q_add ); - - Scale_sig32( hFrontVad->hNoiseEst->bckr_fx, 20, sub( add( Q_new_old, QSCALE + 2 ), hFrontVad->hNoiseEst->q_bckr ) ); // Q_new_old +QSCALE +2 - Scale_sig32( hFrontVad->hNoiseEst->enrO_fx, 20, sub( add( Q_new_old, QSCALE + 2 ), hFrontVad->hNoiseEst->q_enrO ) ); - hFrontVad->hNoiseEst->q_enrO = add( Q_new_old, QSCALE + 2 ); - move16(); Word16 Q_buffer = hFrontVad->q_buffer_12k8; move16(); - Scale_sig( hFrontVad->mem_decim_fx, 2 * L_FILT_MAX, sub( Q_inp, hFrontVad->q_mem_decim ) ); + Scale_sig( hFrontVad->mem_decim_fx, 2 * L_FILT_MAX, sub( Q_inp, hFrontVad->q_mem_decim ) ); /* Q_inp */ hFrontVad->q_mem_decim = Q_inp; move16(); - IF( NE_32( ( error = front_vad_fx( NULL, st, hEncoderConfig, &hFrontVad, 0 /* MCT_flag */, input_frame, vad_flag_dtx, fr_bands_fx, Etot_fx, lf_E_fx, localVAD_HE_SAD, vad_hover_flag, band_energies_fx, &PS_fx[0], &st->lgBin_E_fx[0], Q_inp, &Q_buffer, Q_add, &front_create_flag ) ), IVAS_ERR_OK ) ) + Word16 q_band_energies; + Word16 q_fr_bands[2], q_lf_E[2]; + IF( NE_32( ( error = front_vad_fx( NULL, st, hEncoderConfig, &hFrontVad, 0 /* MCT_flag */, input_frame, vad_flag_dtx, fr_bands_fx, + q_fr_bands, Etot_fx, lf_E_fx, q_lf_E, localVAD_HE_SAD, vad_hover_flag, band_energies_fx, + &q_band_energies, PS_fx, &Qfact_PS, &st->lgBin_E_fx[0], Q_inp, &Q_buffer, Q_add, &front_create_flag ) ), + IVAS_ERR_OK ) ) { return error; } @@ -589,25 +609,27 @@ ivas_error front_vad_spar_fx( Q_inp_12k8 = hFrontVad->q_buffer_12k8; move16(); - IF( st->lgBin_E_fx != NULL ) - { - Copy_Scale_sig_16_32( st->lgBin_E_fx, st->Bin_E_fx, L_FFT / 2, sub( st->q_Bin_E, Q7 ) ); - } - Scale_sig32( fr_bands_fx[0], 40, sub( ( Q_bands + QSCALE ), add( Q_buffer, QSCALE + 2 ) ) ); + scale = s_min( add( q_fr_bands[0], L_norm_arr( fr_bands_fx[0], 2 * NB_BANDS ) ), add( hFrontVad->hNoiseEst->q_bckr, L_norm_arr( hFrontVad->hNoiseEst->bckr_fx, NB_BANDS ) ) ); + scale_sig32( fr_bands_fx[0], 40, sub( scale, q_fr_bands[0] ) ); // scale + scale_sig32( hFrontVad->hNoiseEst->bckr_fx, NB_BANDS, sub( scale, hFrontVad->hNoiseEst->q_bckr ) ); // scale + hFrontVad->hNoiseEst->q_bckr = q_fr_bands[0] = scale; + move16(); + move16(); - Word32 e_min_scaled; - e_min_scaled = L_shr_r( L_add( L_shr( E_MIN_FXQ15, sub( 14, add( Q_bands, QSCALE ) ) ), 1 ), 1 ); + noise_est_down_ivas_fx( fr_bands_fx[0], q_fr_bands[0], hFrontVad->hNoiseEst->bckr_fx, tmpN_fx, tmpE_fx, st->min_band, st->max_band, + &hFrontVad->hNoiseEst->totalNoise_fx, Etot_fx[0], &hFrontVad->hNoiseEst->Etot_last_fx, &hFrontVad->hNoiseEst->Etot_v_h2_fx ); - Scale_sig32( hFrontVad->hNoiseEst->bckr_fx, 20, sub( Q_bands + QSCALE, add( Q_new_old, QSCALE + 2 ) ) ); - hFrontVad->hNoiseEst->q_bckr = Q_bands + QSCALE; - move16(); - noise_est_down_fx( fr_bands_fx[0], hFrontVad->hNoiseEst->bckr_fx, tmpN_fx, tmpE_fx, st->min_band, st->max_band, &hFrontVad->hNoiseEst->totalNoise_fx, Etot_fx[0], &hFrontVad->hNoiseEst->Etot_last_fx, &hFrontVad->hNoiseEst->Etot_v_h2_fx, Q_bands, e_min_scaled ); - corr_shift_fx = correlation_shift_fx( hFrontVad->hNoiseEst->totalNoise_fx ); + corr_shift_fx = correlation_shift_fx( hFrontVad->hNoiseEst->totalNoise_fx ); /* Q15 */ + +#ifdef NONBE_1211_DTX_BR_SWITCHING + dtx_ivas_fx( st, hEncoderConfig->last_ivas_total_brate, hEncoderConfig->ivas_total_brate, vad_flag_dtx[0], inp_12k8_fx, Q_inp_12k8 ); +#else dtx_ivas_fx( st, hEncoderConfig->ivas_total_brate, vad_flag_dtx[0], inp_12k8_fx, Q_inp_12k8 ); +#endif /* linear prediction analysis */ - alw_pitch_lag_12k8[0] = st->old_pitch_la; - alw_pitch_lag_12k8[1] = st->old_pitch_la; + alw_pitch_lag_12k8[0] = st->old_pitch_la; /* Q0 */ + alw_pitch_lag_12k8[1] = st->old_pitch_la; /* Q0 */ alw_voicing_fx[0] = st->voicing_fx[2]; alw_voicing_fx[1] = st->voicing_fx[2]; move16(); @@ -617,8 +639,8 @@ ivas_error front_vad_spar_fx( Word16 Q_r[2] = { 0 }; move16(); move16(); - Scale_sig( hFrontVad->mem_decim_fx, 2 * L_FILT_MAX, sub( s_min( Q_inp_12k8, hFrontVad->q_mem_decim ), hFrontVad->q_mem_decim ) ); - Scale_sig( inp_12k8_fx, 3 * L_FRAME / 2, sub( s_min( Q_inp_12k8, hFrontVad->q_mem_decim ), Q_inp_12k8 ) ); + Scale_sig( hFrontVad->mem_decim_fx, 2 * L_FILT_MAX, sub( s_min( Q_inp_12k8, hFrontVad->q_mem_decim ), hFrontVad->q_mem_decim ) ); /* min( hFrontVad->q_mem_decim, hFrontVad->q_buffer_12k8 */ + Scale_sig( inp_12k8_fx, 3 * L_FRAME / 2, sub( s_min( Q_inp_12k8, hFrontVad->q_mem_decim ), Q_inp_12k8 ) ); /* min( hFrontVad->q_mem_decim, hFrontVad->q_buffer_12k8 */ Q_inp_12k8 = s_min( hFrontVad->q_mem_decim, hFrontVad->q_buffer_12k8 ); hFrontVad->q_mem_decim = Q_inp_12k8; move16(); @@ -635,10 +657,10 @@ ivas_error front_vad_spar_fx( relE_fx = sub( Etot_fx[0], st->lp_speech_fx ); Scale_sig( A_fx, ( L_FRAME / L_SUBFR ) * ( M + 1 ), -2 ); // Q12 - st->mem_wsp_fx = (Word16) shl_sat( st->mem_wsp_fx, Q_inp_12k8 - st->mem_wsp_q ); + st->mem_wsp_fx = (Word16) shl_sat( st->mem_wsp_fx, Q_inp_12k8 - st->mem_wsp_q ); /* Q_inp_12k8 */ st->mem_wsp_q = Q_inp_12k8; move16(); - ivas_find_wsp( L_FRAME, L_SUBFR, NB_SUBFR, A_fx, Aw_fx, inp_12k8_fx, TILT_FAC_FX, wsp_fx, &st->mem_wsp_fx, GAMMA1, L_LOOK_12k8 ); + ivas_find_wsp_fx( L_FRAME, L_SUBFR, NB_SUBFR, A_fx, Aw_fx, inp_12k8_fx, TILT_FAC_FX, wsp_fx, &st->mem_wsp_fx, GAMMA1, L_LOOK_12k8 ); IF( st->vad_flag == 0 ) { @@ -648,32 +670,66 @@ ivas_error front_vad_spar_fx( old_pitch = st->pitch[1]; move16(); - Scale_sig( wsp_fx, 368, sub( Q8, Q_inp_12k8 ) ); - pitch_ol_ivas_fx( st->pitch, st->voicing_fx, &st->old_pitch, &st->old_corr_fx, corr_shift_fx, &st->old_thres_fx, &st->delta_pit, st->old_wsp2_fx, wsp_fx, st->mem_decim2_fx, relE_fx, st->clas, st->input_bwidth, st->Opt_SC_VBR ); + Scale_sig( wsp_fx, 368, sub( Q8, Q_inp_12k8 ) ); // Q8 + pitch_ol_ivas_fx( st->pitch, st->voicing_fx, &st->old_pitch, &st->old_corr_fx, corr_shift_fx, &st->old_thres_fx, &st->delta_pit, st->old_wsp2_fx, wsp_fx, st->mem_decim2_fx, relE_fx, st->clas, st->input_bwidth, st->Opt_SC_VBR, Q8 ); + /* Updates for adaptive lag window memory */ - st->old_pitch_la = st->pitch[2]; + st->old_pitch_la = st->pitch[2]; /* Q0 */ move16(); - Scale_sig( wsp_fx, 368, Q9 - Q8 ); + Scale_sig( wsp_fx, 368, Q9 - Q8 ); /* Q9 */ StableHighPitchDetect_ivas_fx( &flag_spitch, st->pitch, st->voicing_fx, wsp_fx, st->localVAD, &st->voicing_sm_fx, &st->voicing0_sm_fx, &st->LF_EnergyRatio_sm_fx, &st->predecision_flag, &st->diff_sm_fx, &st->energy_sm_fx, Q12, st->lgBin_E_fx ); IF( st->hSpMusClas != NULL ) { Word16 dummy_int; + Word16 *cor_strong_limit; dummy_int = 0; move16(); - loc_harm = multi_harm_fx( st->lgBin_E_fx, hFrontVad->hNoiseEst->old_S_fx, hFrontVad->hNoiseEst->cor_map_fx, &hFrontVad->hNoiseEst->multi_harm_limit_fx, st->total_brate, st->bwidth, ( st->hGSCEnc != NULL ) ? &st->hGSCEnc->cor_strong_limit : &dummy_int, &st->hSpMusClas->mean_avr_dyn_fx, &st->hSpMusClas->last_sw_dyn_fx, &cor_map_sum_fx, &dummy_fx, S_map_fx ); + if ( st->hGSCEnc != NULL ) + { + cor_strong_limit = &st->hGSCEnc->cor_strong_limit; + } + else + { + cor_strong_limit = &dummy_int; + } + loc_harm = multi_harm_fx( st->lgBin_E_fx, hFrontVad->hNoiseEst->old_S_fx, hFrontVad->hNoiseEst->cor_map_fx, &hFrontVad->hNoiseEst->multi_harm_limit_fx, st->total_brate, st->bwidth, cor_strong_limit, &st->hSpMusClas->mean_avr_dyn_fx, &st->hSpMusClas->last_sw_dyn_fx, &cor_map_sum_fx, &dummy_fx, S_map_fx ); /* Q0 */ } + scale = getScaleFactor32( epsP_fx, M + 1 ); Q_esp = add( Q_r[0], scale ); - Scale_sig32( epsP_fx, M + 1, scale ); - FOR( Word16 i = 0; i <= M; i++ ) - { - L_Extract( epsP_fx[i], &epsP_h[i], &epsP_l[i] ); - } - Q_bands = Q9; + Scale_sig32( epsP_fx, M + 1, scale ); // Q_esp + + scale = add( hFrontVad->hNoiseEst->ave_enr_q, s_min( L_norm_arr( hFrontVad->hNoiseEst->ave_enr_fx, NB_BANDS ), L_norm_arr( hFrontVad->hNoiseEst->ave_enr2_fx, NB_BANDS ) ) ); + scale = s_min( scale, add( hFrontVad->hNoiseEst->q_bckr, L_norm_arr( tmpE_fx, NB_BANDS ) ) ); + scale = sub( s_min( scale, Q31 ), 1 ); + scale_sig32( hFrontVad->hNoiseEst->ave_enr_fx, NB_BANDS, sub( scale, hFrontVad->hNoiseEst->ave_enr_q ) ); + scale_sig32( hFrontVad->hNoiseEst->ave_enr2_fx, NB_BANDS, sub( scale, hFrontVad->hNoiseEst->ave_enr_q ) ); + scale_sig32( tmpE_fx, NB_BANDS, sub( scale, hFrontVad->hNoiseEst->q_bckr ) ); + hFrontVad->hNoiseEst->ave_enr_q = scale; + move16(); + + scale = add( hFrontVad->hNoiseEst->q_bckr, s_min( L_norm_arr( hFrontVad->hNoiseEst->bckr_fx, NB_BANDS ), L_norm_arr( tmpN_fx, NB_BANDS ) ) ); + scale = sub( s_min( Q31, scale ), 1 ); // guard bits + scale_sig32( hFrontVad->hNoiseEst->bckr_fx, NB_BANDS, sub( scale, hFrontVad->hNoiseEst->q_bckr ) ); + scale_sig32( tmpN_fx, NB_BANDS, sub( scale, hFrontVad->hNoiseEst->q_bckr ) ); + hFrontVad->hNoiseEst->q_bckr = scale; + move16(); + + scale = add( hFrontVad->hNoiseEst->fr_bands_fx_q, s_min( L_norm_arr( hFrontVad->hNoiseEst->fr_bands1_fx, NB_BANDS ), L_norm_arr( hFrontVad->hNoiseEst->fr_bands2_fx, NB_BANDS ) ) ); + scale = s_min( scale, add( q_fr_bands[0], L_norm_arr( fr_bands_fx[0], 2 * NB_BANDS ) ) ); + scale = s_min( Q31, scale ); + scale_sig32( hFrontVad->hNoiseEst->fr_bands1_fx, NB_BANDS, sub( scale, hFrontVad->hNoiseEst->fr_bands_fx_q ) ); + scale_sig32( hFrontVad->hNoiseEst->fr_bands2_fx, NB_BANDS, sub( scale, hFrontVad->hNoiseEst->fr_bands_fx_q ) ); + scale_sig32( fr_bands_fx[0], 2 * NB_BANDS, sub( scale, q_fr_bands[0] ) ); + hFrontVad->hNoiseEst->fr_bands_fx_q = q_fr_bands[0] = scale; move16(); - Scale_sig32( lf_E_fx[0], 148, ( Q_bands + QSCALE - 2 ) - ( Q_buffer + QSCALE ) ); + move16(); + + noise_est_ivas_fx( st, old_pitch, tmpN_fx, epsP_fx, Etot_fx[0], sub( Etot_fx[0], hFrontVad->lp_speech_fx ), corr_shift_fx, tmpE_fx, + hFrontVad->hNoiseEst->ave_enr_q, fr_bands_fx[0], q_fr_bands[0], &cor_map_sum_fx, NULL, &sp_div_fx, &Q_sp_div, &non_staX_fx, &loc_harm, + lf_E_fx[0], q_lf_E[0], &hFrontVad->hNoiseEst->harm_cor_cnt, hFrontVad->hNoiseEst->Etot_l_lp_fx, hFrontVad->hNoiseEst->Etot_v_h2_fx, + &hFrontVad->hNoiseEst->bg_cnt, st->lgBin_E_fx, &sp_floor, S_map_fx, NULL, hFrontVad, hFrontVad->ini_frame ); - noise_est_ivas_fx( st, old_pitch, tmpN_fx, epsP_h, epsP_l, Etot_fx[0], Etot_fx[0] - hFrontVad->lp_speech_fx, corr_shift_fx, tmpE_fx, fr_bands_fx[0], &cor_map_sum_fx, NULL, &sp_div_fx, &Q_sp_div, &non_staX_fx, &loc_harm, lf_E_fx[0], &hFrontVad->hNoiseEst->harm_cor_cnt, hFrontVad->hNoiseEst->Etot_l_lp_fx, hFrontVad->hNoiseEst->Etot_v_h2_fx, &hFrontVad->hNoiseEst->bg_cnt, st->lgBin_E_fx, Q_bands, e_min_scaled, &sp_floor, S_map_fx, NULL, hFrontVad, hFrontVad->ini_frame ); MVR2R_WORD16( st->pitch, st->pitch, 3 ); vad_param_updt_fx( st, st->pitch[1], corr_shift_fx, corr_shift_fx, A_fx, &hFrontVad, 1 ); /* 1st stage speech/music classification (GMM model) */ @@ -683,7 +739,7 @@ ivas_error front_vad_spar_fx( Word16 Etot_fx_0 = Etot_fx[0]; move16(); scale = getScaleFactor32( PS_fx, 128 ); - Word16 Qfact_PS = add( add( Q_buffer, QSCALE ), scale ); + Qfact_PS = add( Qfact_PS, scale ); Scale_sig32( PS_fx, 128, scale ); ivas_smc_gmm_fx( st, NULL, localVAD_HE_SAD[0], Etot_fx_0, lsp_new_fx, cor_map_sum_fx, epsP_fx, PS_fx, non_sta_fx, relE_fx, &high_lpn_flag, flag_spitch, Qfact_PS, Q_esp, hSpMusClas->past_PS_Q ); @@ -691,10 +747,10 @@ ivas_error front_vad_spar_fx( ivas_long_enr_fx( st, -1, localVAD_HE_SAD[0], high_lpn_flag, &hFrontVad, 1, localVAD_HE_SAD, Etot_fx ); /* increase ini_frame counter */ - hFrontVad->ini_frame = min( add( hFrontVad->ini_frame, 1 ), MAX_FRAME_COUNTER ); - st->ini_frame = hFrontVad->ini_frame; + hFrontVad->ini_frame = s_min( add( hFrontVad->ini_frame, 1 ), MAX_FRAME_COUNTER ); /* Q0 */ + st->ini_frame = hFrontVad->ini_frame; /* Q0 */ move16(); - hSpar->front_vad_flag = st->vad_flag; + hSpar->front_vad_flag = st->vad_flag; /* Q0 */ move16(); hSpar->front_vad_dtx_flag = 1; move16(); diff --git a/lib_enc/ivas_init_enc.c b/lib_enc/ivas_init_enc_fx.c similarity index 72% rename from lib_enc/ivas_init_enc.c rename to lib_enc/ivas_init_enc_fx.c index 06e4f7a3aecbf5db926bf33897ad2733f28adfa7..57858b03ebb2b017899ab8a57e690e0b0be2cc36 100644 --- a/lib_enc/ivas_init_enc.c +++ b/lib_enc/ivas_init_enc_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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,14 +34,13 @@ #include #include "options.h" #include "ivas_cnst.h" -#include "prot.h" -#include "ivas_prot.h" +#include "prot_fx.h" +#include "ivas_prot_fx.h" #include "ivas_stat_enc.h" #include "ivas_rom_com.h" #include "wmc_auto.h" #include "ivas_prot_fx.h" #include "prot_fx_enc.h" -#include "prot_fx.h" /*-------------------------------------------------------------------* @@ -78,7 +77,7 @@ void ivas_write_format_fx( ind = 4; move16(); - nBits = add( nBits, extra_bits ); + nBits = add( nBits, extra_bits ); /* Q0 */ } BREAK; case MC_FORMAT: @@ -89,26 +88,26 @@ void ivas_write_format_fx( ind = 6; move16(); - nBits = add( nBits, extra_bits ); + nBits = add( nBits, extra_bits ); /* Q0 */ BREAK; case MASA_FORMAT: ind = 7; move16(); - nBits = add( nBits, extra_bits ); + nBits = add( nBits, extra_bits ); /* Q0 */ BREAK; case MASA_ISM_FORMAT: IF( st_ivas->ism_mode == ISM_MODE_NONE ) { ind = 7; /* send MASA format */ move16(); - nBits = add( nBits, extra_bits ); + nBits = add( nBits, extra_bits ); /* Q0 */ } ELSE { ind = 10; move16(); - nBits = add( nBits, add( extra_bits, IVAS_COMBINED_FORMAT_SIGNALLING_BITS ) ); + nBits = add( nBits, add( extra_bits, IVAS_COMBINED_FORMAT_SIGNALLING_BITS ) ); /* Q0 */ } BREAK; case SBA_ISM_FORMAT: @@ -116,13 +115,13 @@ void ivas_write_format_fx( { ind = 6; /* send SBA format */ move16(); - nBits = add( nBits, extra_bits ); + nBits = add( nBits, extra_bits ); /* Q0 */ } ELSE { ind = 11; /* 1011 */ move16(); - nBits = add( nBits, add( extra_bits, IVAS_COMBINED_FORMAT_SIGNALLING_BITS ) ); + nBits = add( nBits, add( extra_bits, IVAS_COMBINED_FORMAT_SIGNALLING_BITS ) ); /* Q0 */ } BREAK; default: @@ -150,7 +149,7 @@ void ivas_write_format_fx( void ivas_write_format_sid_fx( const IVAS_FORMAT ivas_format, /* i : IVAS format */ - const Word16 element_mode, /* i : element bitrate */ + const Word16 element_mode, /* i : element bitrate Q0*/ BSTR_ENC_HANDLE hBstr /* i/o: encoder bitstream handle */ ) { @@ -234,78 +233,91 @@ Word16 getNumChanAnalysis_fx( { Word16 n; - n = add( st_ivas->nSCE, CPE_CHANNELS * st_ivas->nCPE ); + n = add( st_ivas->nSCE, CPE_CHANNELS * st_ivas->nCPE ); /* Q0 */ test(); test(); test(); test(); IF( EQ_32( st_ivas->hEncoderConfig->ivas_format, SBA_FORMAT ) ) { - n = imult1616( add( st_ivas->sba_analysis_order, 1 ), add( st_ivas->sba_analysis_order, 1 ) ); + n = imult1616( add( st_ivas->sba_analysis_order, 1 ), add( st_ivas->sba_analysis_order, 1 ) ); /* Q0 */ } ELSE IF( EQ_32( st_ivas->hEncoderConfig->ivas_format, MC_FORMAT ) && ( EQ_32( st_ivas->mc_mode, MC_MODE_PARAMMC ) || EQ_32( st_ivas->mc_mode, MC_MODE_MCMASA ) ) ) { - n = st_ivas->hEncoderConfig->nchan_inp; + n = st_ivas->hEncoderConfig->nchan_inp; /* Q0 */ move16(); } ELSE IF( EQ_32( st_ivas->hEncoderConfig->ivas_format, MC_FORMAT ) && EQ_32( st_ivas->mc_mode, MC_MODE_PARAMUPMIX ) ) { - n = st_ivas->hEncoderConfig->nchan_inp; + n = st_ivas->hEncoderConfig->nchan_inp; /* Q0 */ move16(); } ELSE IF( EQ_32( st_ivas->hEncoderConfig->ivas_format, ISM_FORMAT ) && EQ_32( st_ivas->ism_mode, ISM_MODE_PARAM ) ) { - n = st_ivas->hEncoderConfig->nchan_inp; + n = st_ivas->hEncoderConfig->nchan_inp; /* Q0 */ move16(); } ELSE IF( EQ_32( st_ivas->hEncoderConfig->ivas_format, MASA_ISM_FORMAT ) ) { - n = st_ivas->hEncoderConfig->nchan_inp; + n = st_ivas->hEncoderConfig->nchan_inp; /* Q0 */ move16(); } ELSE IF( EQ_32( st_ivas->hEncoderConfig->ivas_format, SBA_ISM_FORMAT ) ) { - n = add( st_ivas->hEncoderConfig->nchan_ism, imult1616( add( st_ivas->sba_analysis_order, 1 ), add( st_ivas->sba_analysis_order, 1 ) ) ); + n = add( st_ivas->hEncoderConfig->nchan_ism, imult1616( add( st_ivas->sba_analysis_order, 1 ), add( st_ivas->sba_analysis_order, 1 ) ) ); /* Q0 */ } return n; } /*-------------------------------------------------------------------* - * copy_encoder_config() + * copy_encoder_config_ivas_fx() * * Copy configuration structrue to the state structrure *-------------------------------------------------------------------*/ -void copy_encoder_config( - Encoder_Struct *st_ivas, /* i : IVAS encoder structure */ - Encoder_State *st, /* o : encoder state structure */ - const Word16 flag_all /* i : flag 1==update all, 0=partial update*/ +void copy_encoder_config_ivas_fx( + Encoder_Struct *st_ivas, /* i : IVAS encoder structure */ + Encoder_State *st, /* o : encoder state structure */ + const Word16 flag_all /* i : flag 1==update all, 0=partial update Q0*/ ) { - if ( flag_all ) + IF( flag_all ) { - st->input_Fs = st_ivas->hEncoderConfig->input_Fs; + st->input_Fs = st_ivas->hEncoderConfig->input_Fs; /* Q0 */ + move32(); - st->last_codec_mode = st_ivas->last_codec_mode; - st->last_total_brate = st_ivas->hEncoderConfig->last_ivas_total_brate; + st->last_codec_mode = st_ivas->last_codec_mode; /* Q0 */ + move16(); + st->last_total_brate = st_ivas->hEncoderConfig->last_ivas_total_brate; /* Q0 */ + move32(); - st->Opt_DTX_ON = st_ivas->hEncoderConfig->Opt_DTX_ON; + st->Opt_DTX_ON = st_ivas->hEncoderConfig->Opt_DTX_ON; /* Q0 */ + move16(); - st->last_Opt_SC_VBR = st_ivas->hEncoderConfig->last_Opt_SC_VBR; + st->last_Opt_SC_VBR = st_ivas->hEncoderConfig->last_Opt_SC_VBR; /* Q0 */ + move16(); } - st->Opt_AMR_WB = st_ivas->hEncoderConfig->Opt_AMR_WB; - st->Opt_SC_VBR = st_ivas->hEncoderConfig->Opt_SC_VBR; + st->Opt_AMR_WB = st_ivas->hEncoderConfig->Opt_AMR_WB; /* Q0 */ + st->Opt_SC_VBR = st_ivas->hEncoderConfig->Opt_SC_VBR; /* Q0 */ + move16(); + move16(); - st->codec_mode = st_ivas->codec_mode; - st->max_bwidth = st_ivas->hEncoderConfig->max_bwidth; + st->codec_mode = st_ivas->codec_mode; /* Q0 */ + st->max_bwidth = st_ivas->hEncoderConfig->max_bwidth; /* Q0 */ + move16(); + move16(); - st->Opt_RF_ON = st_ivas->hEncoderConfig->Opt_RF_ON; - st->rf_fec_offset = st_ivas->hEncoderConfig->rf_fec_offset; - st->rf_fec_indicator = st_ivas->hEncoderConfig->rf_fec_indicator; + st->Opt_RF_ON = st_ivas->hEncoderConfig->Opt_RF_ON; /* Q0 */ + st->rf_fec_offset = st_ivas->hEncoderConfig->rf_fec_offset; /* Q0 */ + st->rf_fec_indicator = st_ivas->hEncoderConfig->rf_fec_indicator; /* Q0 */ + move16(); + move16(); + move16(); - st->element_mode = st_ivas->hEncoderConfig->element_mode_init; + st->element_mode = st_ivas->hEncoderConfig->element_mode_init; /* Q0 */ + move16(); return; } @@ -316,62 +328,65 @@ void copy_encoder_config( *-------------------------------------------------------------------*/ void copy_encoder_config_fx( - Encoder_Struct *st_ivas, /* i : IVAS encoder structure */ - Encoder_State *st_fx, /* o : encoder state structure */ - const Word16 flag_all /* i : flag 1==update all, 0=partial update*/ + Encoder_Struct *st_ivas, /* i : IVAS encoder structure */ + Encoder_State *st_fx, /* o : encoder state structure */ + const Word16 flag_all /* i : flag 1==update all, 0=partial update Q0*/ ) { IF( flag_all ) { - st_fx->input_Fs = st_ivas->hEncoderConfig->input_Fs; + st_fx->input_Fs = st_ivas->hEncoderConfig->input_Fs; /* Q0 */ move32(); - st_fx->last_codec_mode = st_ivas->last_codec_mode; + st_fx->last_codec_mode = st_ivas->last_codec_mode; /* Q0 */ move16(); - st_fx->last_total_brate = st_ivas->hEncoderConfig->last_ivas_total_brate; + st_fx->last_total_brate = st_ivas->hEncoderConfig->last_ivas_total_brate; /* Q0 */ move32(); - st_fx->Opt_DTX_ON = st_ivas->hEncoderConfig->Opt_DTX_ON; + st_fx->Opt_DTX_ON = st_ivas->hEncoderConfig->Opt_DTX_ON; /* Q0 */ move16(); - st_fx->last_Opt_SC_VBR = st_ivas->hEncoderConfig->last_Opt_SC_VBR; + st_fx->last_Opt_SC_VBR = st_ivas->hEncoderConfig->last_Opt_SC_VBR; /* Q0 */ move16(); } - st_fx->Opt_AMR_WB = st_ivas->hEncoderConfig->Opt_AMR_WB; + st_fx->Opt_AMR_WB = st_ivas->hEncoderConfig->Opt_AMR_WB; /* Q0 */ move16(); - st_fx->Opt_SC_VBR = st_ivas->hEncoderConfig->Opt_SC_VBR; + st_fx->Opt_SC_VBR = st_ivas->hEncoderConfig->Opt_SC_VBR; /* Q0 */ move16(); - st_fx->codec_mode = st_ivas->codec_mode; + st_fx->codec_mode = st_ivas->codec_mode; /* Q0 */ move16(); - st_fx->max_bwidth = st_ivas->hEncoderConfig->max_bwidth; + st_fx->max_bwidth = st_ivas->hEncoderConfig->max_bwidth; /* Q0 */ move16(); - st_fx->Opt_RF_ON = st_ivas->hEncoderConfig->Opt_RF_ON; + st_fx->Opt_RF_ON = st_ivas->hEncoderConfig->Opt_RF_ON; /* Q0 */ move16(); - st_fx->rf_fec_offset = st_ivas->hEncoderConfig->rf_fec_offset; + st_fx->rf_fec_offset = st_ivas->hEncoderConfig->rf_fec_offset; /* Q0 */ move16(); - st_fx->rf_fec_indicator = st_ivas->hEncoderConfig->rf_fec_indicator; + st_fx->rf_fec_indicator = st_ivas->hEncoderConfig->rf_fec_indicator; /* Q0 */ move16(); #ifdef DEBUGGING st_fx->force = st_ivas->hEncoderConfig->force; +#ifdef DEBUG_FORCE_DIR + st_fx->force_dir = st_ivas->hEncoderConfig->force_dir; +#endif #endif - st_fx->element_mode = st_ivas->hEncoderConfig->element_mode_init; + st_fx->element_mode = st_ivas->hEncoderConfig->element_mode_init; /* Q0 */ move16(); return; } /*------------------------------------------------------------------------- - * ivas_initialize_handles_enc() + * ivas_initialize_handles_enc_fx() * * NULL initialization of handles *-------------------------------------------------------------------------*/ -void ivas_initialize_handles_enc( +void ivas_initialize_handles_enc_fx( Encoder_Struct *st_ivas /* i/o: IVAS encoder structure */ ) { @@ -466,38 +481,48 @@ ivas_error ivas_init_encoder( hEncoderConfig = st_ivas->hEncoderConfig; ivas_format = hEncoderConfig->ivas_format; - input_Fs = hEncoderConfig->input_Fs; - ivas_total_brate = hEncoderConfig->ivas_total_brate; + input_Fs = hEncoderConfig->input_Fs; /* Q0 */ + ivas_total_brate = hEncoderConfig->ivas_total_brate; /* Q0 */ + move32(); + move32(); - hEncoderConfig->last_ivas_total_brate = ivas_total_brate; + hEncoderConfig->last_ivas_total_brate = ivas_total_brate; /* Q0 */ + move32(); - if ( ivas_format != MONO_FORMAT ) + if ( NE_32( ivas_format, MONO_FORMAT ) ) { /* In IVAS, ensure that minimum coded bandwidth is WB */ - hEncoderConfig->max_bwidth = max( hEncoderConfig->max_bwidth, WB ); + hEncoderConfig->max_bwidth = s_max( hEncoderConfig->max_bwidth, WB ); /* Q0 */ + move16(); } st_ivas->ism_mode = ISM_MODE_NONE; st_ivas->mc_mode = MC_MODE_NONE; + move32(); + move32(); st_ivas->nchan_transport = -1; + move16(); /*-----------------------------------------------------------------* * Allocate floating-point input audio buffers *-----------------------------------------------------------------*/ - nchan_inp_buff = hEncoderConfig->nchan_inp; - if ( ivas_format == MONO_FORMAT ) + nchan_inp_buff = hEncoderConfig->nchan_inp; /* Q0 */ + move16(); + + IF( EQ_32( ivas_format, MONO_FORMAT ) ) { nchan_inp_buff = 0; + move16(); } - else if ( ivas_format == MASA_ISM_FORMAT ) + ELSE IF( EQ_32( ivas_format, MASA_ISM_FORMAT ) ) { - if ( hEncoderConfig->nchan_inp - hEncoderConfig->nchan_ism == 1 ) /* mono is duplicated in monoMASA */ + if ( EQ_32( sub( hEncoderConfig->nchan_inp, hEncoderConfig->nchan_ism ), 1 ) ) /* mono is duplicated in monoMASA */ { - nchan_inp_buff++; + nchan_inp_buff = add( nchan_inp_buff, 1 ); } - nchan_inp_buff++; /* for *data_separated_object */ + nchan_inp_buff = add( nchan_inp_buff, 1 ); /* for *data_separated_object */ } FOR( n = 0; n < nchan_inp_buff; n++ ) @@ -507,7 +532,10 @@ ivas_error ivas_init_encoder( { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for floating-point input audio buffer!\n" ) ); } + set32_fx( st_ivas->p_data_fx[n], 0, extract_l( Mpy_32_16_1( input_Fs, INV_FRAME_PER_SEC_Q15 ) ) ); } + st_ivas->q_data_fx = Q11; + move16(); FOR( ; n < MAX_INPUT_CHANNELS + MAX_NUM_OBJECTS; n++ ) { st_ivas->p_data_fx[n] = NULL; @@ -517,10 +545,11 @@ ivas_error ivas_init_encoder( *-----------------------------------------------------------------*/ /* set the maximum allowed number of indices in the list */ - st_ivas->ivas_max_num_indices = get_ivas_max_num_indices_fx( ivas_format, ivas_total_brate ); + st_ivas->ivas_max_num_indices = get_ivas_max_num_indices_fx( ivas_format, ivas_total_brate ); /* Q0 */ + move16(); /* allocate buffer of indices */ - if ( ( st_ivas->ind_list = (INDICE_HANDLE) malloc( st_ivas->ivas_max_num_indices * sizeof( Indice ) ) ) == NULL ) + IF( ( st_ivas->ind_list = (INDICE_HANDLE) malloc( st_ivas->ivas_max_num_indices * sizeof( Indice ) ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for buffer of indices!\n" ) ); } @@ -529,15 +558,17 @@ ivas_error ivas_init_encoder( for ( i = 0; i < st_ivas->ivas_max_num_indices; i++ ) { st_ivas->ind_list[i].nb_bits = -1; + move16(); } /* set the maximum allowed number of metadata indices in the list */ - st_ivas->ivas_max_num_indices_metadata = get_ivas_max_num_indices_metadata_fx( st_ivas->hEncoderConfig->ivas_format, st_ivas->hEncoderConfig->ivas_total_brate ); + st_ivas->ivas_max_num_indices_metadata = get_ivas_max_num_indices_metadata_fx( st_ivas->hEncoderConfig->ivas_format, st_ivas->hEncoderConfig->ivas_total_brate ); /* Q0 */ + move16(); /* allocate buffer of metadata indices */ - if ( st_ivas->ivas_max_num_indices_metadata > 0 ) + IF( st_ivas->ivas_max_num_indices_metadata > 0 ) { - if ( ( st_ivas->ind_list_metadata = (INDICE_HANDLE) malloc( st_ivas->ivas_max_num_indices_metadata * sizeof( Indice ) ) ) == NULL ) + IF( ( st_ivas->ind_list_metadata = (INDICE_HANDLE) malloc( st_ivas->ivas_max_num_indices_metadata * sizeof( Indice ) ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for buffer of metadata indices!\n" ) ); } @@ -546,9 +577,10 @@ ivas_error ivas_init_encoder( for ( i = 0; i < st_ivas->ivas_max_num_indices_metadata; i++ ) { st_ivas->ind_list_metadata[i].nb_bits = -1; + move16(); } } - else + ELSE { st_ivas->ind_list_metadata = NULL; } @@ -557,7 +589,7 @@ ivas_error ivas_init_encoder( * Allocate and initialize SCE/CPE and other handles *-----------------------------------------------------------------*/ - if ( ivas_format == MONO_FORMAT ) + IF( EQ_32( ivas_format, MONO_FORMAT ) ) { st_ivas->nSCE = 1; /* in mono, there is always only one SCE */ move16(); @@ -569,87 +601,92 @@ ivas_error ivas_init_encoder( move16(); test(); - IF( NE_16( st_ivas->hEncoderConfig->element_mode_init, EVS_MONO ) ) + IF( st_ivas->hEncoderConfig->element_mode_init != EVS_MONO ) { - IF( NE_32( ( error = create_sce_enc_fx( st_ivas, sce_id, ivas_total_brate ) ), IVAS_ERR_OK ) ) + IF( ( error = create_sce_enc_fx( st_ivas, sce_id, ivas_total_brate ) ) != IVAS_ERR_OK ) { return error; } } ELSE { - IF( NE_32( ( error = create_evs_sce_enc( st_ivas, sce_id, ivas_total_brate ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = create_evs_sce_enc_fx( st_ivas, sce_id, ivas_total_brate ) ), IVAS_ERR_OK ) ) { return error; } } /* prepare stereo downmix for EVS */ - if ( hEncoderConfig->stereo_dmx_evs == 1 ) + IF( EQ_16( hEncoderConfig->stereo_dmx_evs, 1 ) ) { - if ( ( error = stereo_dmx_evs_init_encoder_fx( &( st_ivas->hStereoDmxEVS ), input_Fs ) ) != IVAS_ERR_OK ) + IF( ( error = stereo_dmx_evs_init_encoder_fx( &( st_ivas->hStereoDmxEVS ), input_Fs ) ) != IVAS_ERR_OK ) { return error; } } } - else if ( ivas_format == STEREO_FORMAT ) + ELSE IF( EQ_32( ivas_format, STEREO_FORMAT ) ) { st_ivas->nSCE = 0; st_ivas->nCPE = 1; /* in stereo, there is always only one CPE */ st_ivas->nchan_transport = CPE_CHANNELS; cpe_id = 0; + move16(); + move16(); + move16(); + move16(); - if ( ( error = create_cpe_enc_fx( st_ivas, cpe_id, ivas_total_brate ) ) != IVAS_ERR_OK ) + IF( ( error = create_cpe_enc_fx( st_ivas, cpe_id, ivas_total_brate ) ) != IVAS_ERR_OK ) { return error; } } - else if ( ivas_format == ISM_FORMAT ) + ELSE IF( EQ_32( ivas_format, ISM_FORMAT ) ) { st_ivas->ism_mode = ivas_ism_mode_select( hEncoderConfig->nchan_inp, ivas_total_brate ); - if ( ( error = ivas_ism_metadata_enc_create( st_ivas, hEncoderConfig->nchan_inp, element_brate_tmp ) ) != IVAS_ERR_OK ) + IF( ( error = ivas_ism_metadata_enc_create_fx( st_ivas, hEncoderConfig->nchan_inp, element_brate_tmp ) ) != IVAS_ERR_OK ) { return error; } - for ( sce_id = 0; sce_id < st_ivas->nSCE; sce_id++ ) + FOR( sce_id = 0; sce_id < st_ivas->nSCE; sce_id++ ) { - if ( ( error = create_sce_enc_fx( st_ivas, sce_id, element_brate_tmp[sce_id] ) ) != IVAS_ERR_OK ) + IF( ( error = create_sce_enc_fx( st_ivas, sce_id, element_brate_tmp[sce_id] ) ) != IVAS_ERR_OK ) { return error; } } - if ( st_ivas->ism_mode == ISM_MODE_PARAM ) + IF( EQ_32( st_ivas->ism_mode, ISM_MODE_PARAM ) ) { - if ( ( error = ivas_param_ism_enc_open( st_ivas ) ) != IVAS_ERR_OK ) + IF( ( error = ivas_param_ism_enc_open_fx( st_ivas ) ) != IVAS_ERR_OK ) { return error; } } - if ( st_ivas->hEncoderConfig->Opt_DTX_ON ) + IF( st_ivas->hEncoderConfig->Opt_DTX_ON ) { - if ( ( error = ivas_ism_dtx_open( st_ivas ) ) != IVAS_ERR_OK ) + IF( ( error = ivas_ism_dtx_open( st_ivas ) ) != IVAS_ERR_OK ) { return error; } } } - else if ( ivas_format == SBA_FORMAT || ivas_format == MASA_FORMAT ) + ELSE IF( EQ_32( ivas_format, SBA_FORMAT ) || EQ_32( ivas_format, MASA_FORMAT ) ) { IF( ( error = ivas_qmetadata_open_fx( &( st_ivas->hQMetaData ) ) ) != IVAS_ERR_OK ) { return error; } - if ( ivas_format == SBA_FORMAT ) + IF( EQ_32( ivas_format, SBA_FORMAT ) ) { - st_ivas->sba_analysis_order = ivas_sba_get_analysis_order_fx( ivas_total_brate, st_ivas->hEncoderConfig->sba_order ); + st_ivas->sba_analysis_order = ivas_sba_get_analysis_order_fx( ivas_total_brate, st_ivas->hEncoderConfig->sba_order ); /* Q0 */ + move16(); - if ( ( error = ivas_spar_enc_open_fx( st_ivas, 0 ) ) != IVAS_ERR_OK ) + IF( ( error = ivas_spar_enc_open_fx( st_ivas, 0 ) ) != IVAS_ERR_OK ) { return error; } @@ -659,74 +696,82 @@ ivas_error ivas_init_encoder( return error; } } - else + ELSE { - st_ivas->nchan_transport = hEncoderConfig->nchan_inp; + st_ivas->nchan_transport = hEncoderConfig->nchan_inp; /* Q0 */ + move16(); - if ( ( error = ivas_masa_enc_open( st_ivas ) ) != IVAS_ERR_OK ) + IF( ( error = ivas_masa_enc_open_fx( st_ivas ) ) != IVAS_ERR_OK ) { return error; } } - for ( sce_id = 0; sce_id < st_ivas->nSCE; sce_id++ ) + FOR( sce_id = 0; sce_id < st_ivas->nSCE; sce_id++ ) { IF( ( error = create_sce_enc_fx( st_ivas, sce_id, ivas_total_brate / st_ivas->nchan_transport ) ) != IVAS_ERR_OK ) { return error; } - if ( ivas_format == SBA_FORMAT && st_ivas->hEncoderConfig->Opt_DTX_ON ) + if ( EQ_32( ivas_format, SBA_FORMAT ) && st_ivas->hEncoderConfig->Opt_DTX_ON ) { st_ivas->hSCE[sce_id]->hCoreCoder[0]->dtx_sce_sba = 1; + move16(); } } - for ( cpe_id = 0; cpe_id < st_ivas->nCPE; cpe_id++ ) + FOR( cpe_id = 0; cpe_id < st_ivas->nCPE; cpe_id++ ) { - if ( ( error = create_cpe_enc_fx( st_ivas, cpe_id, ( ivas_total_brate / st_ivas->nchan_transport ) * CPE_CHANNELS ) ) != IVAS_ERR_OK ) + Word32 res_dec, res_frac; + iDiv_and_mod_32( ivas_total_brate, st_ivas->nchan_transport, &res_dec, &res_frac, 0 ); + IF( ( error = create_cpe_enc_fx( st_ivas, cpe_id, imult3216( res_dec, CPE_CHANNELS ) ) ) != IVAS_ERR_OK ) { return error; } - for ( n = 0; n < CPE_CHANNELS; n++ ) + FOR( n = 0; n < CPE_CHANNELS; n++ ) { if ( hEncoderConfig->Opt_DTX_ON ) { st_ivas->hCPE[cpe_id]->hCoreCoder[n]->cng_sba_flag = 1; + move16(); } } } - if ( st_ivas->nCPE > 1 ) + IF( GT_16( st_ivas->nCPE, 1 ) ) { - if ( ( error = create_mct_enc( st_ivas ) ) != IVAS_ERR_OK ) + IF( ( error = create_mct_enc_fx( st_ivas ) ) != IVAS_ERR_OK ) { return error; } } } - else if ( ivas_format == MASA_ISM_FORMAT ) + ELSE IF( EQ_32( ivas_format, MASA_ISM_FORMAT ) ) { Word32 ism_total_brate; Word16 k; - st_ivas->ism_mode = ivas_omasa_ism_mode_select_fx( ivas_total_brate, hEncoderConfig->nchan_ism ); + st_ivas->ism_mode = ivas_omasa_ism_mode_select_fx( ivas_total_brate, hEncoderConfig->nchan_ism ); /* Q0 */ move32(); st_ivas->nchan_transport = 2; + move16(); - if ( ( error = ivas_ism_metadata_enc_create( st_ivas, hEncoderConfig->nchan_ism, element_brate_tmp ) ) != IVAS_ERR_OK ) + IF( ( error = ivas_ism_metadata_enc_create_fx( st_ivas, hEncoderConfig->nchan_ism, element_brate_tmp ) ) != IVAS_ERR_OK ) { return error; } k = 0; - while ( k < SIZE_IVAS_BRATE_TBL && ivas_total_brate != ivas_brate_tbl[k] ) + move16(); + while ( k < SIZE_IVAS_BRATE_TBL && NE_32( ivas_total_brate, ivas_brate_tbl[k] ) ) { k++; } ism_total_brate = 0; + move32(); FOR( sce_id = 0; sce_id < st_ivas->nSCE; sce_id++ ) { ism_total_brate = L_add( ism_total_brate, sep_object_brate[k - 2][st_ivas->nSCE - 1] ); @@ -740,43 +785,45 @@ ivas_error ivas_init_encoder( { return error; } - if ( ( error = ivas_masa_enc_open( st_ivas ) ) != IVAS_ERR_OK ) + IF( ( error = ivas_masa_enc_open_fx( st_ivas ) ) != IVAS_ERR_OK ) { return error; } - if ( st_ivas->ism_mode != ISM_MASA_MODE_DISC ) + IF( NE_32( st_ivas->ism_mode, ISM_MASA_MODE_DISC ) ) { - if ( ( error = ivas_omasa_enc_open_fx( st_ivas ) ) != IVAS_ERR_OK ) + IF( ( error = ivas_omasa_enc_open_fx( st_ivas ) ) != IVAS_ERR_OK ) { return error; } } - if ( ivas_total_brate - ism_total_brate >= MIN_BRATE_MDCT_STEREO ) + if ( GE_32( L_sub( ivas_total_brate, ism_total_brate ), MIN_BRATE_MDCT_STEREO ) ) { st_ivas->hEncoderConfig->element_mode_init = IVAS_CPE_MDCT; + move16(); } else { st_ivas->hEncoderConfig->element_mode_init = IVAS_CPE_DFT; + move16(); } - if ( ( error = create_cpe_enc_fx( st_ivas, 0, ivas_total_brate - ism_total_brate ) ) != IVAS_ERR_OK ) + IF( ( error = create_cpe_enc_fx( st_ivas, 0, L_sub( ivas_total_brate, ism_total_brate ) ) ) != IVAS_ERR_OK ) { return error; } } - else if ( ivas_format == SBA_ISM_FORMAT ) + ELSE IF( EQ_32( ivas_format, SBA_ISM_FORMAT ) ) { st_ivas->ism_mode = ISM_MODE_NONE; - if ( ivas_total_brate >= IVAS_256k ) + if ( GE_32( ivas_total_brate, IVAS_256k ) ) { st_ivas->ism_mode = ISM_SBA_MODE_DISC; } - if ( ( error = ivas_ism_metadata_enc_create( st_ivas, hEncoderConfig->nchan_ism, element_brate_tmp ) ) != IVAS_ERR_OK ) + IF( ( error = ivas_ism_metadata_enc_create_fx( st_ivas, hEncoderConfig->nchan_ism, element_brate_tmp ) ) != IVAS_ERR_OK ) { return error; } @@ -788,8 +835,9 @@ ivas_error ivas_init_encoder( } st_ivas->sba_analysis_order = ivas_sba_get_analysis_order_fx( ivas_total_brate, st_ivas->hEncoderConfig->sba_order ); + move16(); - if ( ( error = ivas_spar_enc_open_fx( st_ivas, 0 ) ) != IVAS_ERR_OK ) + IF( ( error = ivas_spar_enc_open_fx( st_ivas, 0 ) ) != IVAS_ERR_OK ) { return error; } @@ -799,7 +847,7 @@ ivas_error ivas_init_encoder( return error; } - if ( st_ivas->ism_mode == ISM_MODE_NONE ) + IF( EQ_32( st_ivas->ism_mode, ISM_MODE_NONE ) ) { /* allocate and initialize SBA core-coders */ IF( EQ_16( st_ivas->nchan_transport, 1 ) ) @@ -810,132 +858,148 @@ ivas_error ivas_init_encoder( } } - for ( cpe_id = 0; cpe_id < st_ivas->nCPE; cpe_id++ ) + FOR( cpe_id = 0; cpe_id < st_ivas->nCPE; cpe_id++ ) { - if ( ( error = create_cpe_enc_fx( st_ivas, cpe_id, ( ivas_total_brate / st_ivas->nchan_transport ) * CPE_CHANNELS ) ) != IVAS_ERR_OK ) + Word32 res_dec, res_frac; + iDiv_and_mod_32( ivas_total_brate, st_ivas->nchan_transport, &res_dec, &res_frac, 0 ); + IF( ( error = create_cpe_enc_fx( st_ivas, cpe_id, imult3216( res_dec, CPE_CHANNELS ) ) ) != IVAS_ERR_OK ) { return error; } } - if ( st_ivas->nCPE > 1 ) + IF( GT_16( st_ivas->nCPE, 1 ) ) { - if ( ( error = create_mct_enc( st_ivas ) ) != IVAS_ERR_OK ) + IF( ( error = create_mct_enc_fx( st_ivas ) ) != IVAS_ERR_OK ) { return error; } } } - else + ELSE { /* allocate and initialize MCT core coder */ - st_ivas->nCPE += ( st_ivas->hEncoderConfig->nchan_ism + 1 ) >> 1; + st_ivas->nCPE = add( st_ivas->nCPE, shr( add( st_ivas->hEncoderConfig->nchan_ism, 1 ), 1 ) ); - for ( cpe_id = 0; cpe_id < st_ivas->nCPE; cpe_id++ ) + FOR( cpe_id = 0; cpe_id < st_ivas->nCPE; cpe_id++ ) { - if ( ( error = create_cpe_enc_fx( st_ivas, cpe_id, ( ivas_total_brate / st_ivas->nchan_transport ) * CPE_CHANNELS ) ) != IVAS_ERR_OK ) + Word32 res_dec, res_frac; + iDiv_and_mod_32( ivas_total_brate, st_ivas->nchan_transport, &res_dec, &res_frac, 0 ); + IF( ( error = create_cpe_enc_fx( st_ivas, cpe_id, imult3216( res_dec, CPE_CHANNELS ) ) ) != IVAS_ERR_OK ) { return error; } } - if ( ( error = create_mct_enc( st_ivas ) ) != IVAS_ERR_OK ) + IF( ( error = create_mct_enc_fx( st_ivas ) ) != IVAS_ERR_OK ) { return error; } } - if ( ( error = ivas_osba_enc_open_fx( st_ivas ) ) != IVAS_ERR_OK ) + IF( ( error = ivas_osba_enc_open_fx( st_ivas ) ) != IVAS_ERR_OK ) { return error; } } - else if ( ivas_format == MC_FORMAT ) + ELSE IF( EQ_32( ivas_format, MC_FORMAT ) ) { - st_ivas->mc_mode = ivas_mc_mode_select_fx( hEncoderConfig->mc_input_setup, ivas_total_brate ); + st_ivas->mc_mode = ivas_mc_mode_select_fx( hEncoderConfig->mc_input_setup, ivas_total_brate ); /* Q0 */ - if ( ( error = ivas_create_lfe_lpf_enc_fx( &st_ivas->hLfeLpf, hEncoderConfig->input_Fs ) ) != IVAS_ERR_OK ) + IF( ( error = ivas_create_lfe_lpf_enc_fx( &st_ivas->hLfeLpf, hEncoderConfig->input_Fs ) ) != IVAS_ERR_OK ) { return error; } - if ( st_ivas->mc_mode == MC_MODE_MCT ) + IF( EQ_32( st_ivas->mc_mode, MC_MODE_MCT ) ) { st_ivas->nSCE = 0; - st_ivas->nCPE = hEncoderConfig->nchan_inp / CPE_CHANNELS; + st_ivas->nCPE = idiv1616( hEncoderConfig->nchan_inp, CPE_CHANNELS ); /* Q0 */ + move16(); + move16(); - for ( cpe_id = 0; cpe_id < st_ivas->nCPE; cpe_id++ ) + FOR( cpe_id = 0; cpe_id < st_ivas->nCPE; cpe_id++ ) { - if ( ( error = create_cpe_enc_fx( st_ivas, cpe_id, ( ivas_total_brate / ( hEncoderConfig->nchan_inp - 1 ) * CPE_CHANNELS ) ) ) != IVAS_ERR_OK ) + Word32 res_dec, res_frac; + iDiv_and_mod_32( ivas_total_brate, sub( hEncoderConfig->nchan_inp, 1 ), &res_dec, &res_frac, 0 ); + IF( ( error = create_cpe_enc_fx( st_ivas, cpe_id, imult3216( res_dec, CPE_CHANNELS ) ) ) != IVAS_ERR_OK ) { return error; } } - if ( ( error = create_mct_enc( st_ivas ) ) != IVAS_ERR_OK ) + IF( ( error = create_mct_enc_fx( st_ivas ) ) != IVAS_ERR_OK ) { return error; } - if ( ( error = ivas_create_lfe_enc( &st_ivas->hLFE, input_Fs ) ) != IVAS_ERR_OK ) + IF( ( error = ivas_create_lfe_enc_fx( &st_ivas->hLFE, input_Fs ) ) != IVAS_ERR_OK ) { return error; } - st_ivas->nchan_transport = ivas_mc_ls_setup_get_num_channels_fx( st_ivas->hEncoderConfig->mc_input_setup ); + st_ivas->nchan_transport = ivas_mc_ls_setup_get_num_channels_fx( st_ivas->hEncoderConfig->mc_input_setup ); /* Q0 */ + move16(); } - else if ( st_ivas->mc_mode == MC_MODE_PARAMUPMIX ) + ELSE IF( EQ_32( st_ivas->mc_mode, MC_MODE_PARAMUPMIX ) ) { st_ivas->nSCE = 0; st_ivas->nCPE = MC_PARAMUPMIX_MAX_TRANSPORT_CHANS / 2; st_ivas->nchan_transport = MC_PARAMUPMIX_MAX_TRANSPORT_CHANS; + move16(); + move16(); + move16(); - if ( ( error = ivas_mc_paramupmix_enc_open( st_ivas ) ) != IVAS_ERR_OK ) + IF( ( error = ivas_mc_paramupmix_enc_open_fx( st_ivas ) ) != IVAS_ERR_OK ) { return error; } - for ( cpe_id = 0; cpe_id < st_ivas->nCPE; cpe_id++ ) + FOR( cpe_id = 0; cpe_id < st_ivas->nCPE; cpe_id++ ) { - if ( ( error = create_cpe_enc_fx( st_ivas, cpe_id, ( ivas_total_brate / st_ivas->nCPE ) ) ) != IVAS_ERR_OK ) + Word32 res_dec, res_frac; + iDiv_and_mod_32( ivas_total_brate, st_ivas->nCPE, &res_dec, &res_frac, 0 ); + IF( ( error = create_cpe_enc_fx( st_ivas, cpe_id, res_dec ) ) != IVAS_ERR_OK ) { return error; } } - if ( ( error = create_mct_enc( st_ivas ) ) != IVAS_ERR_OK ) + IF( ( error = create_mct_enc_fx( st_ivas ) ) != IVAS_ERR_OK ) { return error; } - if ( ( error = ivas_create_lfe_enc( &st_ivas->hLFE, input_Fs ) ) != IVAS_ERR_OK ) + IF( ( error = ivas_create_lfe_enc_fx( &st_ivas->hLFE, input_Fs ) ) != IVAS_ERR_OK ) { return error; } } - else if ( st_ivas->mc_mode == MC_MODE_PARAMMC ) + ELSE IF( EQ_32( st_ivas->mc_mode, MC_MODE_PARAMMC ) ) { - if ( ( error = ivas_param_mc_enc_open_fx( st_ivas ) ) != IVAS_ERR_OK ) + IF( ( error = ivas_param_mc_enc_open_fx( st_ivas ) ) != IVAS_ERR_OK ) { return error; } - for ( cpe_id = 0; cpe_id < st_ivas->nCPE; cpe_id++ ) + FOR( cpe_id = 0; cpe_id < st_ivas->nCPE; cpe_id++ ) { - if ( ( error = create_cpe_enc_fx( st_ivas, cpe_id, ivas_total_brate / ( st_ivas->nCPE + st_ivas->nSCE ) ) ) != IVAS_ERR_OK ) + Word32 res_dec, res_frac; + iDiv_and_mod_32( ivas_total_brate, add( st_ivas->nCPE, st_ivas->nSCE ), &res_dec, &res_frac, 0 ); + IF( ( error = create_cpe_enc_fx( st_ivas, cpe_id, res_dec ) ) != IVAS_ERR_OK ) { return error; } } - if ( st_ivas->nCPE > 1 ) + IF( GT_16( st_ivas->nCPE, 1 ) ) { - if ( ( error = create_mct_enc( st_ivas ) ) != IVAS_ERR_OK ) + IF( ( error = create_mct_enc_fx( st_ivas ) ) != IVAS_ERR_OK ) { return error; } } } - else if ( st_ivas->mc_mode == MC_MODE_MCMASA ) + ELSE IF( EQ_32( st_ivas->mc_mode, MC_MODE_MCMASA ) ) { Word32 brate_sce, brate_cpe; @@ -946,11 +1010,11 @@ ivas_error ivas_init_encoder( return error; } - if ( ( error = ivas_masa_enc_open( st_ivas ) ) != IVAS_ERR_OK ) + IF( ( error = ivas_masa_enc_open_fx( st_ivas ) ) != IVAS_ERR_OK ) { return error; } - if ( ( error = ivas_mcmasa_enc_open_fx( st_ivas ) ) != IVAS_ERR_OK ) + IF( ( error = ivas_mcmasa_enc_open_fx( st_ivas ) ) != IVAS_ERR_OK ) { return error; } @@ -965,11 +1029,12 @@ ivas_error ivas_init_encoder( } } - for ( cpe_id = 0; cpe_id < st_ivas->nCPE; cpe_id++ ) + FOR( cpe_id = 0; cpe_id < st_ivas->nCPE; cpe_id++ ) { hEncoderConfig->element_mode_init = IVAS_CPE_MDCT; + move16(); - if ( ( error = create_cpe_enc_fx( st_ivas, cpe_id, brate_cpe ) ) != IVAS_ERR_OK ) + IF( ( error = create_cpe_enc_fx( st_ivas, cpe_id, brate_cpe ) ) != IVAS_ERR_OK ) { return error; } @@ -982,7 +1047,8 @@ ivas_error ivas_init_encoder( *-----------------------------------------------------------------*/ /* set number of input channels used for analysis/coding */ - n = getNumChanAnalysis_fx( st_ivas ); + n = getNumChanAnalysis_fx( st_ivas ); /* Q0 */ + move16(); IF( n > 0 ) { @@ -1026,18 +1092,18 @@ ivas_error ivas_init_encoder_fx( hEncoderConfig = st_ivas->hEncoderConfig; ivas_format = hEncoderConfig->ivas_format; move32(); - input_Fs = hEncoderConfig->input_Fs; + input_Fs = hEncoderConfig->input_Fs; /* Q0 */ move32(); - ivas_total_brate = hEncoderConfig->ivas_total_brate; + ivas_total_brate = hEncoderConfig->ivas_total_brate; /* Q0 */ move32(); - hEncoderConfig->last_ivas_total_brate = ivas_total_brate; + hEncoderConfig->last_ivas_total_brate = ivas_total_brate; /* Q0 */ move32(); IF( NE_16( ivas_format, MONO_FORMAT ) ) { /* In IVAS, ensure that minimum coded bandwidth is WB */ - hEncoderConfig->max_bwidth = extract_l( L_max( hEncoderConfig->max_bwidth, WB ) ); + hEncoderConfig->max_bwidth = extract_l( L_max( hEncoderConfig->max_bwidth, WB ) ); /* Q0 */ move16(); } st_ivas->ism_mode = ISM_MODE_NONE; @@ -1052,7 +1118,7 @@ ivas_error ivas_init_encoder_fx( * Allocate floating-point input audio buffers *-----------------------------------------------------------------*/ - nchan_inp_buff = hEncoderConfig->nchan_inp; + nchan_inp_buff = hEncoderConfig->nchan_inp; /* Q0 */ move16(); IF( EQ_16( ivas_format, MONO_FORMAT ) ) { @@ -1063,10 +1129,10 @@ ivas_error ivas_init_encoder_fx( { IF( EQ_16( sub( hEncoderConfig->nchan_inp, hEncoderConfig->nchan_ism ), 1 ) ) /* mono is duplicated in monoMASA */ { - nchan_inp_buff = add( nchan_inp_buff, 1 ); + nchan_inp_buff = add( nchan_inp_buff, 1 ); /* Q0 */ } - nchan_inp_buff = add( nchan_inp_buff, 1 ); /* for *data_separated_object */ + nchan_inp_buff = add( nchan_inp_buff, 1 ); /* for *data_separated_object Q0*/ } FOR( n = 0; n < nchan_inp_buff; n++ ) @@ -1088,7 +1154,7 @@ ivas_error ivas_init_encoder_fx( *-----------------------------------------------------------------*/ /* set the maximum allowed number of indices in the list */ - st_ivas->ivas_max_num_indices = get_ivas_max_num_indices_fx( ivas_format, ivas_total_brate ); + st_ivas->ivas_max_num_indices = get_ivas_max_num_indices_fx( ivas_format, ivas_total_brate ); /* Q0 */ move16(); /* allocate buffer of indices */ @@ -1105,7 +1171,7 @@ ivas_error ivas_init_encoder_fx( } /* set the maximum allowed number of metadata indices in the list */ - st_ivas->ivas_max_num_indices_metadata = get_ivas_max_num_indices_metadata_fx( st_ivas->hEncoderConfig->ivas_format, st_ivas->hEncoderConfig->ivas_total_brate ); + st_ivas->ivas_max_num_indices_metadata = get_ivas_max_num_indices_metadata_fx( st_ivas->hEncoderConfig->ivas_format, st_ivas->hEncoderConfig->ivas_total_brate ); /* Q0 */ move16(); /* allocate buffer of metadata indices */ IF( st_ivas->ivas_max_num_indices_metadata > 0 ) @@ -1131,7 +1197,7 @@ ivas_error ivas_init_encoder_fx( * Allocate and initialize SCE/CPE and other handles *-----------------------------------------------------------------*/ test(); - IF( EQ_16( ivas_format, MONO_FORMAT ) ) + IF( EQ_32( ivas_format, MONO_FORMAT ) ) { st_ivas->nSCE = 1; /* in mono, there is always only one SCE */ move16(); @@ -1143,16 +1209,16 @@ ivas_error ivas_init_encoder_fx( move16(); test(); - IF( EQ_16( st_ivas->hEncoderConfig->element_mode_init, EVS_MONO ) ) + IF( st_ivas->hEncoderConfig->element_mode_init == EVS_MONO ) { - IF( NE_32( ( error = create_evs_sce_enc( st_ivas, sce_id, ivas_total_brate ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = create_evs_sce_enc_fx( st_ivas, sce_id, ivas_total_brate ) ), IVAS_ERR_OK ) ) { return error; } } ELSE { - IF( NE_32( ( error = create_sce_enc_fx( st_ivas, sce_id, ivas_total_brate ) ), IVAS_ERR_OK ) ) + IF( ( error = create_sce_enc_fx( st_ivas, sce_id, ivas_total_brate ) ) != IVAS_ERR_OK ) { return error; } @@ -1161,13 +1227,13 @@ ivas_error ivas_init_encoder_fx( /* prepare stereo downmix for EVS */ IF( EQ_16( hEncoderConfig->stereo_dmx_evs, 1 ) ) { - IF( NE_32( ( error = stereo_dmx_evs_init_encoder_fx( &( st_ivas->hStereoDmxEVS ), input_Fs ) ), IVAS_ERR_OK ) ) + IF( ( error = stereo_dmx_evs_init_encoder_fx( &( st_ivas->hStereoDmxEVS ), input_Fs ) ) != IVAS_ERR_OK ) { return error; } } } - ELSE IF( ivas_format == STEREO_FORMAT ) + ELSE IF( EQ_32( ivas_format, STEREO_FORMAT ) ) { st_ivas->nSCE = 0; move16(); @@ -1178,24 +1244,24 @@ ivas_error ivas_init_encoder_fx( cpe_id = 0; move16(); - IF( NE_32( ( error = create_cpe_enc_fx( st_ivas, cpe_id, ivas_total_brate ) ), IVAS_ERR_OK ) ) + IF( ( error = create_cpe_enc_fx( st_ivas, cpe_id, ivas_total_brate ) ) != IVAS_ERR_OK ) { return error; } } ELSE IF( EQ_32( ivas_format, ISM_FORMAT ) ) { - st_ivas->ism_mode = ivas_ism_mode_select( hEncoderConfig->nchan_inp, ivas_total_brate ); + st_ivas->ism_mode = ivas_ism_mode_select( hEncoderConfig->nchan_inp, ivas_total_brate ); /* Q0 */ move32(); - IF( NE_32( ( error = ivas_ism_metadata_enc_create( st_ivas, hEncoderConfig->nchan_inp, element_brate_tmp ) ), IVAS_ERR_OK ) ) + IF( ( error = ivas_ism_metadata_enc_create_fx( st_ivas, hEncoderConfig->nchan_inp, element_brate_tmp ) ) != IVAS_ERR_OK ) { return error; } FOR( sce_id = 0; sce_id < st_ivas->nSCE; sce_id++ ) { - IF( NE_32( ( error = create_sce_enc_fx( st_ivas, sce_id, element_brate_tmp[sce_id] ) ), IVAS_ERR_OK ) ) + IF( ( error = create_sce_enc_fx( st_ivas, sce_id, element_brate_tmp[sce_id] ) ) != IVAS_ERR_OK ) { return error; } @@ -1203,7 +1269,7 @@ ivas_error ivas_init_encoder_fx( IF( EQ_32( st_ivas->ism_mode, ISM_MODE_PARAM ) ) { - IF( NE_32( ( error = ivas_param_ism_enc_open( st_ivas ) ), IVAS_ERR_OK ) ) + IF( ( error = ivas_param_ism_enc_open_fx( st_ivas ) ) != IVAS_ERR_OK ) { return error; } @@ -1211,7 +1277,7 @@ ivas_error ivas_init_encoder_fx( IF( st_ivas->hEncoderConfig->Opt_DTX_ON ) { - IF( NE_32( ( error = ivas_ism_dtx_open( st_ivas ) ), IVAS_ERR_OK ) ) + IF( ( error = ivas_ism_dtx_open( st_ivas ) ) != IVAS_ERR_OK ) { return error; } @@ -1219,31 +1285,31 @@ ivas_error ivas_init_encoder_fx( } ELSE IF( EQ_32( ivas_format, SBA_FORMAT ) || EQ_32( ivas_format, MASA_FORMAT ) ) { - IF( NE_32( ( error = ivas_qmetadata_open_fx( &( st_ivas->hQMetaData ) ) ), IVAS_ERR_OK ) ) + IF( ( error = ivas_qmetadata_open_fx( &( st_ivas->hQMetaData ) ) ) != IVAS_ERR_OK ) { return error; } IF( EQ_32( ivas_format, SBA_FORMAT ) ) { - st_ivas->sba_analysis_order = ivas_sba_get_analysis_order_fx( ivas_total_brate, st_ivas->hEncoderConfig->sba_order ); + st_ivas->sba_analysis_order = ivas_sba_get_analysis_order_fx( ivas_total_brate, st_ivas->hEncoderConfig->sba_order ); /* Q0 */ move16(); - IF( NE_32( ( error = ivas_spar_enc_open_fx( st_ivas, 0 ) ), IVAS_ERR_OK ) ) + IF( ( error = ivas_spar_enc_open_fx( st_ivas, 0 ) ) != IVAS_ERR_OK ) { return error; } - IF( NE_32( ( error = ivas_dirac_enc_open_fx( st_ivas ) ), IVAS_ERR_OK ) ) + IF( ( error = ivas_dirac_enc_open_fx( st_ivas ) ) != IVAS_ERR_OK ) { return error; } } ELSE { - st_ivas->nchan_transport = hEncoderConfig->nchan_inp; + st_ivas->nchan_transport = hEncoderConfig->nchan_inp; /* Q0 */ move16(); - IF( NE_32( ( error = ivas_masa_enc_open( st_ivas ) ), IVAS_ERR_OK ) ) + IF( ( error = ivas_masa_enc_open_fx( st_ivas ) ) != IVAS_ERR_OK ) { return error; } @@ -1253,7 +1319,7 @@ ivas_error ivas_init_encoder_fx( { Word32 res_dec, res_frac; iDiv_and_mod_32( ivas_total_brate, st_ivas->nchan_transport, &res_dec, &res_frac, 0 ); - IF( NE_32( ( error = create_sce_enc_fx( st_ivas, sce_id, res_dec ) ), IVAS_ERR_OK ) ) + IF( ( error = create_sce_enc_fx( st_ivas, sce_id, res_dec ) ) != IVAS_ERR_OK ) { return error; } @@ -1269,7 +1335,7 @@ ivas_error ivas_init_encoder_fx( { Word32 res_dec, res_frac; iDiv_and_mod_32( ivas_total_brate, st_ivas->nchan_transport, &res_dec, &res_frac, 0 ); - IF( NE_32( ( error = create_cpe_enc_fx( st_ivas, cpe_id, imult3216( res_dec, CPE_CHANNELS ) ) ), IVAS_ERR_OK ) ) + IF( ( error = create_cpe_enc_fx( st_ivas, cpe_id, imult3216( res_dec, CPE_CHANNELS ) ) ) != IVAS_ERR_OK ) { return error; } @@ -1286,7 +1352,7 @@ ivas_error ivas_init_encoder_fx( IF( st_ivas->nCPE > 1 ) { - IF( NE_32( ( error = create_mct_enc( st_ivas ) ), IVAS_ERR_OK ) ) + IF( ( error = create_mct_enc_fx( st_ivas ) ) != IVAS_ERR_OK ) { return error; } @@ -1297,12 +1363,12 @@ ivas_error ivas_init_encoder_fx( Word32 ism_total_brate; Word16 k; - st_ivas->ism_mode = ivas_omasa_ism_mode_select_fx( ivas_total_brate, hEncoderConfig->nchan_ism ); + st_ivas->ism_mode = ivas_omasa_ism_mode_select_fx( ivas_total_brate, hEncoderConfig->nchan_ism ); /* Q0 */ move32(); st_ivas->nchan_transport = 2; move16(); - IF( NE_32( ( error = ivas_ism_metadata_enc_create( st_ivas, hEncoderConfig->nchan_ism, element_brate_tmp ) ), IVAS_ERR_OK ) ) + IF( ( error = ivas_ism_metadata_enc_create_fx( st_ivas, hEncoderConfig->nchan_ism, element_brate_tmp ) ) != IVAS_ERR_OK ) { return error; } @@ -1312,32 +1378,32 @@ ivas_error ivas_init_encoder_fx( test(); WHILE( LT_16( k, SIZE_IVAS_BRATE_TBL ) && NE_32( ivas_total_brate, ivas_brate_tbl[k] ) ) { - k = add( k, 1 ); + k++; } ism_total_brate = 0; move32(); FOR( sce_id = 0; sce_id < st_ivas->nSCE; sce_id++ ) { - ism_total_brate = L_add( ism_total_brate, sep_object_brate[k - 2][st_ivas->nSCE - 1] ); - IF( NE_32( ( error = create_sce_enc_fx( st_ivas, sce_id, sep_object_brate[k - 2][st_ivas->nSCE - 1] ) ), IVAS_ERR_OK ) ) + ism_total_brate = L_add( ism_total_brate, sep_object_brate[k - 2][st_ivas->nSCE - 1] ); /* Q0 */ + IF( ( error = create_sce_enc_fx( st_ivas, sce_id, sep_object_brate[k - 2][st_ivas->nSCE - 1] ) ) != IVAS_ERR_OK ) { return error; } } - IF( NE_32( ( error = ivas_qmetadata_open_fx( &( st_ivas->hQMetaData ) ) ), IVAS_ERR_OK ) ) + IF( ( error = ivas_qmetadata_open_fx( &( st_ivas->hQMetaData ) ) ) != IVAS_ERR_OK ) { return error; } - IF( NE_32( ( error = ivas_masa_enc_open( st_ivas ) ), IVAS_ERR_OK ) ) + IF( ( error = ivas_masa_enc_open_fx( st_ivas ) ) != IVAS_ERR_OK ) { return error; } IF( NE_32( st_ivas->ism_mode, ISM_MASA_MODE_DISC ) ) { - IF( NE_32( ( error = ivas_omasa_enc_open_fx( st_ivas ) ), IVAS_ERR_OK ) ) + IF( ( error = ivas_omasa_enc_open_fx( st_ivas ) ) != IVAS_ERR_OK ) { return error; } @@ -1354,7 +1420,7 @@ ivas_error ivas_init_encoder_fx( move16(); } - IF( NE_32( ( error = create_cpe_enc_fx( st_ivas, 0, L_sub( ivas_total_brate, ism_total_brate ) ) ), IVAS_ERR_OK ) ) + IF( ( error = create_cpe_enc_fx( st_ivas, 0, L_sub( ivas_total_brate, ism_total_brate ) ) ) != IVAS_ERR_OK ) { return error; } @@ -1370,25 +1436,25 @@ ivas_error ivas_init_encoder_fx( move32(); } - IF( NE_32( ( error = ivas_ism_metadata_enc_create( st_ivas, hEncoderConfig->nchan_ism, element_brate_tmp ) ), IVAS_ERR_OK ) ) + IF( ( error = ivas_ism_metadata_enc_create_fx( st_ivas, hEncoderConfig->nchan_ism, element_brate_tmp ) ) != IVAS_ERR_OK ) { return error; } /* allocate and initialize SBA handles */ - IF( NE_32( ( error = ivas_qmetadata_open_fx( &( st_ivas->hQMetaData ) ) ), IVAS_ERR_OK ) ) + IF( ( error = ivas_qmetadata_open_fx( &( st_ivas->hQMetaData ) ) ) != IVAS_ERR_OK ) { return error; } - st_ivas->sba_analysis_order = ivas_sba_get_analysis_order_fx( ivas_total_brate, st_ivas->hEncoderConfig->sba_order ); + st_ivas->sba_analysis_order = ivas_sba_get_analysis_order_fx( ivas_total_brate, st_ivas->hEncoderConfig->sba_order ); /* Q0 */ - IF( NE_32( ( error = ivas_spar_enc_open_fx( st_ivas, 0 ) ), IVAS_ERR_OK ) ) + IF( ( error = ivas_spar_enc_open_fx( st_ivas, 0 ) ) != IVAS_ERR_OK ) { return error; } - IF( NE_32( ( error = ivas_dirac_enc_open_fx( st_ivas ) ), IVAS_ERR_OK ) ) + IF( ( error = ivas_dirac_enc_open_fx( st_ivas ) ) != IVAS_ERR_OK ) { return error; } @@ -1398,7 +1464,7 @@ ivas_error ivas_init_encoder_fx( /* allocate and initialize SBA core-coders */ IF( EQ_16( st_ivas->nchan_transport, 1 ) ) { - IF( NE_32( ( error = create_sce_enc_fx( st_ivas, 0, ivas_total_brate ) ), IVAS_ERR_OK ) ) + IF( ( error = create_sce_enc_fx( st_ivas, 0, ivas_total_brate ) ) != IVAS_ERR_OK ) { return error; } @@ -1408,7 +1474,7 @@ ivas_error ivas_init_encoder_fx( { Word32 res_dec, res_frac; iDiv_and_mod_32( ivas_total_brate, st_ivas->nchan_transport, &res_dec, &res_frac, 0 ); - IF( NE_32( ( error = create_cpe_enc_fx( st_ivas, cpe_id, imult3216( res_dec, CPE_CHANNELS ) ) ), IVAS_ERR_OK ) ) + IF( ( error = create_cpe_enc_fx( st_ivas, cpe_id, imult3216( res_dec, CPE_CHANNELS ) ) ) != IVAS_ERR_OK ) { return error; } @@ -1416,7 +1482,7 @@ ivas_error ivas_init_encoder_fx( IF( GT_16( st_ivas->nCPE, 1 ) ) { - IF( NE_32( ( error = create_mct_enc( st_ivas ) ), IVAS_ERR_OK ) ) + IF( ( error = create_mct_enc_fx( st_ivas ) ) != IVAS_ERR_OK ) { return error; } @@ -1425,34 +1491,34 @@ ivas_error ivas_init_encoder_fx( ELSE { /* allocate and initialize MCT core coder */ - st_ivas->nCPE = add( st_ivas->nCPE, shr( add( st_ivas->hEncoderConfig->nchan_ism, 1 ), 1 ) ); + st_ivas->nCPE = add( st_ivas->nCPE, shr( add( st_ivas->hEncoderConfig->nchan_ism, 1 ), 1 ) ); /* Q0 */ FOR( cpe_id = 0; cpe_id < st_ivas->nCPE; cpe_id++ ) { Word32 res_dec, res_frac; iDiv_and_mod_32( ivas_total_brate, st_ivas->nchan_transport, &res_dec, &res_frac, 0 ); - IF( NE_32( ( error = create_cpe_enc_fx( st_ivas, cpe_id, imult3216( res_dec, CPE_CHANNELS ) ) ), IVAS_ERR_OK ) ) + IF( ( error = create_cpe_enc_fx( st_ivas, cpe_id, imult3216( res_dec, CPE_CHANNELS ) ) ) != IVAS_ERR_OK ) { return error; } } - IF( NE_32( ( error = create_mct_enc( st_ivas ) ), IVAS_ERR_OK ) ) + IF( ( error = create_mct_enc_fx( st_ivas ) ) != IVAS_ERR_OK ) { return error; } } - IF( NE_32( ( error = ivas_osba_enc_open_fx( st_ivas ) ), IVAS_ERR_OK ) ) + IF( ( error = ivas_osba_enc_open_fx( st_ivas ) ) != IVAS_ERR_OK ) { return error; } } ELSE IF( EQ_32( ivas_format, MC_FORMAT ) ) { - st_ivas->mc_mode = ivas_mc_mode_select_fx( hEncoderConfig->mc_input_setup, ivas_total_brate ); + st_ivas->mc_mode = ivas_mc_mode_select_fx( hEncoderConfig->mc_input_setup, ivas_total_brate ); /* Q0 */ move32(); - IF( NE_32( ( error = ivas_create_lfe_lpf_enc_fx( &st_ivas->hLfeLpf, hEncoderConfig->input_Fs ) ), IVAS_ERR_OK ) ) + IF( ( error = ivas_create_lfe_lpf_enc_fx( &st_ivas->hLfeLpf, hEncoderConfig->input_Fs ) ) != IVAS_ERR_OK ) { return error; } @@ -1461,30 +1527,30 @@ ivas_error ivas_init_encoder_fx( { st_ivas->nSCE = 0; move16(); - st_ivas->nCPE = idiv1616( hEncoderConfig->nchan_inp, CPE_CHANNELS ); + st_ivas->nCPE = idiv1616( hEncoderConfig->nchan_inp, CPE_CHANNELS ); /* Q0 */ move16(); FOR( cpe_id = 0; cpe_id < st_ivas->nCPE; cpe_id++ ) { Word32 res_dec, res_frac; iDiv_and_mod_32( ivas_total_brate, sub( hEncoderConfig->nchan_inp, 1 ), &res_dec, &res_frac, 0 ); - IF( NE_32( ( error = create_cpe_enc_fx( st_ivas, cpe_id, imult3216( res_dec, CPE_CHANNELS ) ) ), IVAS_ERR_OK ) ) + IF( ( error = create_cpe_enc_fx( st_ivas, cpe_id, imult3216( res_dec, CPE_CHANNELS ) ) ) != IVAS_ERR_OK ) { return error; } } - IF( NE_32( ( error = create_mct_enc( st_ivas ) ), IVAS_ERR_OK ) ) + IF( ( error = create_mct_enc_fx( st_ivas ) ) != IVAS_ERR_OK ) { return error; } - IF( NE_32( ( error = ivas_create_lfe_enc( &st_ivas->hLFE, input_Fs ) ), IVAS_ERR_OK ) ) + IF( ( error = ivas_create_lfe_enc_fx( &st_ivas->hLFE, input_Fs ) ) != IVAS_ERR_OK ) { return error; } - st_ivas->nchan_transport = ivas_mc_ls_setup_get_num_channels_fx( st_ivas->hEncoderConfig->mc_input_setup ); + st_ivas->nchan_transport = ivas_mc_ls_setup_get_num_channels_fx( st_ivas->hEncoderConfig->mc_input_setup ); /* Q0 */ move16(); } ELSE IF( EQ_32( st_ivas->mc_mode, MC_MODE_PARAMUPMIX ) ) @@ -1496,7 +1562,7 @@ ivas_error ivas_init_encoder_fx( st_ivas->nchan_transport = MC_PARAMUPMIX_MAX_TRANSPORT_CHANS; move16(); - IF( NE_32( ( error = ivas_mc_paramupmix_enc_open( st_ivas ) ), IVAS_ERR_OK ) ) + IF( ( error = ivas_mc_paramupmix_enc_open_fx( st_ivas ) ) != IVAS_ERR_OK ) { return error; } @@ -1505,32 +1571,32 @@ ivas_error ivas_init_encoder_fx( { Word32 res_dec, res_frac; iDiv_and_mod_32( ivas_total_brate, st_ivas->nCPE, &res_dec, &res_frac, 0 ); - IF( NE_32( ( error = create_cpe_enc_fx( st_ivas, cpe_id, res_dec ) ), IVAS_ERR_OK ) ) + IF( ( error = create_cpe_enc_fx( st_ivas, cpe_id, res_dec ) ) != IVAS_ERR_OK ) { return error; } } - IF( NE_32( ( error = create_mct_enc( st_ivas ) ), IVAS_ERR_OK ) ) + IF( ( error = create_mct_enc_fx( st_ivas ) ) != IVAS_ERR_OK ) { return error; } - IF( NE_32( ( error = ivas_create_lfe_enc( &st_ivas->hLFE, input_Fs ) ), IVAS_ERR_OK ) ) + IF( ( error = ivas_create_lfe_enc_fx( &st_ivas->hLFE, input_Fs ) ) != IVAS_ERR_OK ) { return error; } } - ELSE IF( st_ivas->mc_mode == MC_MODE_PARAMMC ) + ELSE IF( EQ_32( st_ivas->mc_mode, MC_MODE_PARAMMC ) ) { - IF( NE_32( ( error = ivas_param_mc_enc_open_fx( st_ivas ) ), IVAS_ERR_OK ) ) + IF( ( error = ivas_param_mc_enc_open_fx( st_ivas ) ) != IVAS_ERR_OK ) { return error; } FOR( cpe_id = 0; cpe_id < st_ivas->nCPE; cpe_id++ ) { - IF( NE_32( ( error = create_cpe_enc_fx( st_ivas, cpe_id, ivas_total_brate / ( st_ivas->nCPE + st_ivas->nSCE ) ) ), IVAS_ERR_OK ) ) + IF( ( error = create_cpe_enc_fx( st_ivas, cpe_id, ivas_total_brate / ( st_ivas->nCPE + st_ivas->nSCE ) ) ) != IVAS_ERR_OK ) { return error; } @@ -1538,7 +1604,7 @@ ivas_error ivas_init_encoder_fx( IF( GT_16( st_ivas->nCPE, 1 ) ) { - IF( NE_32( ( error = create_mct_enc( st_ivas ) ), IVAS_ERR_OK ) ) + IF( ( error = create_mct_enc_fx( st_ivas ) ) != IVAS_ERR_OK ) { return error; } @@ -1550,17 +1616,17 @@ ivas_error ivas_init_encoder_fx( ivas_mcmasa_setNumTransportChannels_fx( &( st_ivas->nchan_transport ), &( hEncoderConfig->element_mode_init ), ivas_total_brate ); - IF( NE_32( ( error = ivas_qmetadata_open_fx( &( st_ivas->hQMetaData ) ) ), IVAS_ERR_OK ) ) + IF( ( error = ivas_qmetadata_open_fx( &( st_ivas->hQMetaData ) ) ) != IVAS_ERR_OK ) { return error; } - IF( NE_32( ( error = ivas_masa_enc_open( st_ivas ) ), IVAS_ERR_OK ) ) + IF( ( error = ivas_masa_enc_open_fx( st_ivas ) ) != IVAS_ERR_OK ) { return error; } - IF( NE_32( ( error = ivas_mcmasa_enc_open_fx( st_ivas ) ), IVAS_ERR_OK ) ) + IF( ( error = ivas_mcmasa_enc_open_fx( st_ivas ) ) != IVAS_ERR_OK ) { return error; } @@ -1568,7 +1634,7 @@ ivas_error ivas_init_encoder_fx( FOR( sce_id = 0; sce_id < st_ivas->nSCE; sce_id++ ) { - IF( NE_32( ( error = create_sce_enc_fx( st_ivas, sce_id, brate_sce ) ), IVAS_ERR_OK ) ) + IF( ( error = create_sce_enc_fx( st_ivas, sce_id, brate_sce ) ) != IVAS_ERR_OK ) { return error; } @@ -1576,10 +1642,10 @@ ivas_error ivas_init_encoder_fx( FOR( cpe_id = 0; cpe_id < st_ivas->nCPE; cpe_id++ ) { - hEncoderConfig->element_mode_init = IVAS_CPE_MDCT; + hEncoderConfig->element_mode_init = IVAS_CPE_MDCT; /* Q0 */ move16(); - IF( NE_32( ( error = create_cpe_enc_fx( st_ivas, cpe_id, brate_cpe ) ), IVAS_ERR_OK ) ) + IF( ( error = create_cpe_enc_fx( st_ivas, cpe_id, brate_cpe ) ) != IVAS_ERR_OK ) { return error; } @@ -1929,23 +1995,24 @@ void destroy_evs_core_enc_fx( /*------------------------------------------------------------------------- - * ivas_destroy_enc() + * ivas_destroy_enc_fx() * * Close IVAS encoder handles *-------------------------------------------------------------------------*/ -void ivas_destroy_enc( +void ivas_destroy_enc_fx( Encoder_Struct *st_ivas /* i/o: IVAS encoder structure */ ) { Word16 i, n, nchan_inp; nchan_inp = st_ivas->hEncoderConfig->nchan_inp; + move16(); /* SCE handles */ for ( i = 0; i < MAX_SCE; i++ ) { if ( st_ivas->hSCE[i] != NULL ) { - destroy_sce_enc( st_ivas->hSCE[i], EQ_16( st_ivas->hEncoderConfig->element_mode_init, EVS_MONO ) ); + destroy_sce_enc_fx( st_ivas->hSCE[i], EQ_16( st_ivas->hEncoderConfig->element_mode_init, EVS_MONO ) ); st_ivas->hSCE[i] = NULL; } } @@ -1963,7 +2030,7 @@ void ivas_destroy_enc( /* HP20 filter handles */ if ( st_ivas->mem_hp20_in_fx != NULL ) { - n = getNumChanAnalysis_fx( st_ivas ); + n = getNumChanAnalysis_fx( st_ivas ); /* Q0 */ for ( i = 0; i < n; i++ ) { @@ -1991,25 +2058,25 @@ void ivas_destroy_enc( ivas_dirac_enc_close_fx( &( st_ivas->hDirAC ), st_ivas->hEncoderConfig->input_Fs ); /* ParamISM handle */ - ivas_param_ism_enc_close( &( st_ivas->hParamIsm ), st_ivas->hEncoderConfig->input_Fs ); + ivas_param_ism_enc_close_fx( &( st_ivas->hParamIsm ), st_ivas->hEncoderConfig->input_Fs ); /* SPAR handle */ ivas_spar_enc_close_fx( &( st_ivas->hSpar ), st_ivas->hEncoderConfig->input_Fs, nchan_inp, 0 ); /* MASA handle */ - ivas_masa_enc_close( &( st_ivas->hMasa ) ); + ivas_masa_enc_close_fx( &( st_ivas->hMasa ) ); /* MCT handle */ - ivas_mct_enc_close( &( st_ivas->hMCT ) ); + ivas_mct_enc_close_fx( &( st_ivas->hMCT ) ); /* LFE handle */ - ivas_lfe_enc_close( &( st_ivas->hLFE ) ); + ivas_lfe_enc_close_fx( &( st_ivas->hLFE ) ); /* LFE low pass filter state */ - ivas_lfe_lpf_enc_close( &( st_ivas->hLfeLpf ) ); + ivas_lfe_lpf_enc_close_fx( &( st_ivas->hLfeLpf ) ); /* Param-Upmix MC handle */ - ivas_mc_paramupmix_enc_close( &( st_ivas->hMCParamUpmix ), st_ivas->hEncoderConfig->input_Fs ); + ivas_mc_paramupmix_enc_close_fx( &( st_ivas->hMCParamUpmix ), st_ivas->hEncoderConfig->input_Fs ); /* Parametric MC handle */ ivas_param_mc_enc_close_fx( &( st_ivas->hParamMC ), st_ivas->hEncoderConfig->input_Fs ); @@ -2027,27 +2094,27 @@ void ivas_destroy_enc( stereo_dmx_evs_close_encoder_fx( &( st_ivas->hStereoDmxEVS ) ); /* Encoder configuration handle */ - if ( st_ivas->hEncoderConfig != NULL ) + IF( st_ivas->hEncoderConfig != NULL ) { free( st_ivas->hEncoderConfig ); st_ivas->hEncoderConfig = NULL; } /* Buffer of indices */ - if ( st_ivas->ind_list != NULL ) + IF( st_ivas->ind_list != NULL ) { free( st_ivas->ind_list ); } - if ( st_ivas->ind_list_metadata != NULL ) + IF( st_ivas->ind_list_metadata != NULL ) { free( st_ivas->ind_list_metadata ); } /* floating-point input audio buffers */ - for ( n = 0; n < MAX_INPUT_CHANNELS + MAX_NUM_OBJECTS; n++ ) + FOR( n = 0; n < MAX_INPUT_CHANNELS + MAX_NUM_OBJECTS; n++ ) { - if ( st_ivas->p_data_fx[n] != NULL ) + IF( st_ivas->p_data_fx[n] != NULL ) { free( st_ivas->p_data_fx[n] ); st_ivas->p_data_fx[n] = NULL; @@ -2061,12 +2128,12 @@ void ivas_destroy_enc( } /*------------------------------------------------------------------------- - * ivas_initialize_MD_bstr_enc() + * ivas_initialize_MD_bstr_enc_fx() * * Allocate and initialize SCE/CPE MD bitstream handle *-------------------------------------------------------------------------*/ -ivas_error ivas_initialize_MD_bstr_enc( +ivas_error ivas_initialize_MD_bstr_enc_fx( BSTR_ENC_HANDLE *hMetaData_out, /* o : encoder MD bitstream handle */ Encoder_Struct *st_ivas /* i/o: IVAS encoder structure */ ) @@ -2081,10 +2148,10 @@ ivas_error ivas_initialize_MD_bstr_enc( /* set pointer to the buffer of metadata indices */ hMetaData->ind_list = st_ivas->ind_list_metadata; hMetaData->ivas_ind_list_zero = &st_ivas->ind_list_metadata; - hMetaData->ivas_max_num_indices = &st_ivas->ivas_max_num_indices_metadata; + hMetaData->ivas_max_num_indices = &st_ivas->ivas_max_num_indices_metadata; /* Q0 */ hMetaData->st_ivas = st_ivas; - reset_indices_enc( hMetaData, st_ivas->ivas_max_num_indices_metadata ); + reset_indices_enc_fx( hMetaData, st_ivas->ivas_max_num_indices_metadata ); *hMetaData_out = hMetaData; @@ -2093,12 +2160,12 @@ ivas_error ivas_initialize_MD_bstr_enc( /*------------------------------------------------------------------------- - * ivas_destroy_MD_bstr_enc() + * ivas_destroy_MD_bstr_enc_fx() * * Destroy SCE/CPE MD bitstream handle *-------------------------------------------------------------------------*/ -void ivas_destroy_MD_bstr_enc( +void ivas_destroy_MD_bstr_enc_fx( BSTR_ENC_HANDLE *hMetaData /* i/o: encoder MD bitstream handle */ ) { diff --git a/lib_enc/ivas_ism_dtx_enc.c b/lib_enc/ivas_ism_dtx_enc_fx.c similarity index 87% rename from lib_enc/ivas_ism_dtx_enc.c rename to lib_enc/ivas_ism_dtx_enc_fx.c index 791404a11104208056aa91fb8bc18c7e6e609904..6aba283beac75621190c5b7832817fbe98af8c04 100644 --- a/lib_enc/ivas_ism_dtx_enc.c +++ b/lib_enc/ivas_ism_dtx_enc_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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,13 +34,10 @@ #include #include "options.h" #include "ivas_cnst.h" -#include "prot.h" -#include "ivas_prot.h" -#include "wmc_auto.h" #include "prot_fx.h" +#include "wmc_auto.h" #include "ivas_prot_fx.h" #include "prot_fx_enc.h" -#define IVAS_FLOAT_FIXED_TO_BE_REMOVED /*-----------------------------------------------------------------------* @@ -108,13 +105,13 @@ ivas_error ivas_ism_dtx_open( Word16 ivas_ism_dtx_enc_fx( ISM_DTX_HANDLE hISMDTX, /* i/o: ISM DTX handle */ SCE_ENC_HANDLE hSCE[MAX_SCE], /* i/o: SCE encoder structure */ - const Word32 ivas_total_brate, /* i : IVAS total bitrate */ - const Word16 nchan_ism, /* i : number of objects */ - const Word16 nchan_transport, /* i : number of transport channels */ - Word16 vad_flag[MAX_NUM_OBJECTS], /* i : VAD flag */ + const Word32 ivas_total_brate, /* i : IVAS total bitrate Q0*/ + const Word16 nchan_ism, /* i : number of objects Q0*/ + const Word16 nchan_transport, /* i : number of transport channels Q0*/ + Word16 vad_flag[MAX_NUM_OBJECTS], /* i : VAD flag Q0*/ ISM_METADATA_HANDLE hIsmMeta[], /* i/o: ISM metadata handles */ - Word16 md_diff_flag[], /* o : metadata differential flag */ - Word16 *sid_flag /* o : indication of SID frame */ + Word16 md_diff_flag[], /* o : metadata differential flag Q0*/ + Word16 *sid_flag /* o : indication of SID frame Q0*/ ) { Word16 ch, dtx_flag; @@ -139,7 +136,7 @@ Word16 ivas_ism_dtx_enc_fx( move16(); FOR( ch = 0; ch < nchan_transport; ch++ ) { - dtx_flag = s_and( dtx_flag, !vad_flag[ch] ); + dtx_flag = s_and( dtx_flag, !vad_flag[ch] ); /* Q0 */ } /* compute global ISM based on long-term background noise */ @@ -177,7 +174,11 @@ Word16 ivas_ism_dtx_enc_fx( ( EQ_16( nchan_ism, 2 ) && LE_32( ivas_total_brate, IVAS_48k ) ) || ( EQ_16( nchan_ism, 3 ) && LE_32( ivas_total_brate, IVAS_80k ) ) || ( EQ_16( nchan_ism, 4 ) && LE_32( ivas_total_brate, IVAS_96k ) ) || +#ifdef NONBE_FIX_1277_EVS_DTX_HIGH_RATE_THRESHOLD + LT_16( lp_noise_max_fx, ( DTX_THR << 8 ) ) ) ) +#else LT_16( lp_noise_max_fx, ( 15 << 8 ) ) ) ) +#endif { dtx_flag = 0; move16(); @@ -190,7 +191,7 @@ Word16 ivas_ism_dtx_enc_fx( IF( dtx_flag ) { /* reset the bitstream (IVAS format signaling was already written) */ - reset_indices_enc( hSCE[0]->hCoreCoder[0]->hBstr, hSCE[0]->hCoreCoder[0]->hBstr->nb_ind_tot ); + reset_indices_enc_fx( hSCE[0]->hCoreCoder[0]->hBstr, hSCE[0]->hCoreCoder[0]->hBstr->nb_ind_tot ); } /*------------------------------------------------------------------* @@ -222,33 +223,33 @@ Word16 ivas_ism_dtx_enc_fx( } /* estimate SID metadata bit-budget */ - nBits = add( nBits, 1 ); /* number of objects */ - nBits = add( nBits, 1 ); /* SID metadata flag */ + nBits = add( nBits, 1 ); /* number of objects Q0*/ + nBits = add( nBits, 1 ); /* SID metadata flag Q0*/ IF( EQ_16( md_diff_flag[ch], 1 ) ) { - nBits = add( nBits, nBits_azimuth ); - nBits = add( nBits, nBits_elevation ); + nBits = add( nBits, nBits_azimuth ); /* Q0 */ + nBits = add( nBits, nBits_elevation ); /* Q0 */ } } /* calculate maximum available MD bit-budget */ nBits_MD_max = ( IVAS_SID_5k2 - SID_2k40 ) / FRAMES_PER_SEC; move16(); - nBits_MD_max = sub( nBits_MD_max, SID_FORMAT_NBITS ); + nBits_MD_max = sub( nBits_MD_max, SID_FORMAT_NBITS ); /* Q0 */ if ( GT_16( nchan_transport, 1 ) ) { - nBits_MD_max = sub( nBits_MD_max, nBits_sce_id ); + nBits_MD_max = sub( nBits_MD_max, nBits_sce_id ); /* Q0 */ } FOR( ch = 0; ch < nchan_transport - 1; ch++ ) { - nBits_MD_max = sub( nBits_MD_max, nBits_coh ); /* coherence */ + nBits_MD_max = sub( nBits_MD_max, nBits_coh ); /* coherence Q0*/ } if ( GT_16( nchan_ism, 3 ) ) { - nBits_MD_max = sub( nBits_MD_max, 1 ); /* ism_mode flag */ + nBits_MD_max = sub( nBits_MD_max, 1 ); /* ism_mode flag Q0*/ } /* too many metadata bits -> switch to active coding */ @@ -308,12 +309,12 @@ Word16 ivas_ism_dtx_enc_fx( } /* * update the global SID counter */ - hISMDTX->cnt_SID_ISM = add( hISMDTX->cnt_SID_ISM, 1 ); + hISMDTX->cnt_SID_ISM = add( hISMDTX->cnt_SID_ISM, 1 ); /* Q0 */ move16(); IF( GE_16( hISMDTX->cnt_SID_ISM, hSCE[0]->hCoreCoder[0]->hDtxEnc->max_SID ) ) { /* adaptive SID update interval */ - hSCE[0]->hCoreCoder[0]->hDtxEnc->max_SID = hSCE[0]->hCoreCoder[0]->hDtxEnc->interval_SID; + hSCE[0]->hCoreCoder[0]->hDtxEnc->max_SID = hSCE[0]->hCoreCoder[0]->hDtxEnc->interval_SID; /* Q0 */ hISMDTX->cnt_SID_ISM = 0; move16(); move16(); @@ -326,7 +327,7 @@ Word16 ivas_ism_dtx_enc_fx( move32(); } - IF( EQ_16( hISMDTX->cnt_SID_ISM, 0 ) ) + IF( hISMDTX->cnt_SID_ISM == 0 ) { hSCE[hISMDTX->sce_id_dtx]->hCoreCoder[0]->core_brate = SID_2k40; *sid_flag = 1; @@ -336,7 +337,7 @@ Word16 ivas_ism_dtx_enc_fx( } test(); - IF( EQ_16( dtx_flag, 1 ) && EQ_16( *sid_flag, 0 ) ) + IF( EQ_16( dtx_flag, 1 ) && *sid_flag == 0 ) { set16_fx( md_diff_flag, 0, nchan_transport ); } @@ -352,8 +353,8 @@ Word16 ivas_ism_dtx_enc_fx( void ivas_ism_get_sce_id_dtx_fx( ISM_DTX_HANDLE hISMDTX, /* i/o: ISM DTX handle */ SCE_ENC_HANDLE hSCE[MAX_SCE], /* i/o: SCE encoder structure */ - const Word16 nchan_transport, /* i : number of transport channels */ - const Word16 input_frame /* i : input frame length per channel */ + const Word16 nchan_transport, /* i : number of transport channels Q0*/ + const Word16 input_frame /* i : input frame length per channel Q0*/ ) { Word32 tmp_energy[MAX_NUM_OBJECTS]; @@ -380,7 +381,7 @@ void ivas_ism_get_sce_id_dtx_fx( { FOR( i = 0; i < ( PARAM_ISM_HYS_BUF_SIZE - 1 ); i++ ) { - hISMDTX->long_term_energy_stereo_dmx_enc_fx[j][i] = hISMDTX->long_term_energy_stereo_dmx_enc_fx[j][i + 1]; + hISMDTX->long_term_energy_stereo_dmx_enc_fx[j][i] = hISMDTX->long_term_energy_stereo_dmx_enc_fx[j][i + 1]; /* exp(hISMDTX->long_term_energy_stereo_dmx_enc_e) */ move32(); } long_term_energy_stereo_dmx_enc_e[j] = 20; @@ -404,10 +405,10 @@ void ivas_ism_get_sce_id_dtx_fx( { FOR( i = 0; i < PARAM_ISM_HYS_BUF_SIZE - 1; i++ ) { - hISMDTX->long_term_energy_stereo_dmx_enc_fx[j][i] = L_shr( hISMDTX->long_term_energy_stereo_dmx_enc_fx[j][i], max_exp - hISMDTX->long_term_energy_stereo_dmx_enc_e ); + hISMDTX->long_term_energy_stereo_dmx_enc_fx[j][i] = L_shr( hISMDTX->long_term_energy_stereo_dmx_enc_fx[j][i], max_exp - hISMDTX->long_term_energy_stereo_dmx_enc_e ); /* exp(max_exp) */ move32(); } - hISMDTX->long_term_energy_stereo_dmx_enc_fx[j][PARAM_ISM_HYS_BUF_SIZE - 1] = L_shr( hISMDTX->long_term_energy_stereo_dmx_enc_fx[j][PARAM_ISM_HYS_BUF_SIZE - 1], max_exp - long_term_energy_stereo_dmx_enc_e[j] ); + hISMDTX->long_term_energy_stereo_dmx_enc_fx[j][PARAM_ISM_HYS_BUF_SIZE - 1] = L_shr( hISMDTX->long_term_energy_stereo_dmx_enc_fx[j][PARAM_ISM_HYS_BUF_SIZE - 1], max_exp - long_term_energy_stereo_dmx_enc_e[j] ); /* exp(max_exp) */ move32(); } hISMDTX->long_term_energy_stereo_dmx_enc_e = max_exp; @@ -417,7 +418,7 @@ void ivas_ism_get_sce_id_dtx_fx( move16(); FOR( j = 1; j < nchan_transport; j++ ) { - if ( BASOP_Util_Cmp_Mant32Exp( tmp_energy[j], tmp_energy_e[j], tmp_energy[hISMDTX->sce_id_dtx], tmp_energy_e[hISMDTX->sce_id_dtx] ) ) + IF( EQ_16( BASOP_Util_Cmp_Mant32Exp( tmp_energy[j], tmp_energy_e[j], tmp_energy[hISMDTX->sce_id_dtx], tmp_energy_e[hISMDTX->sce_id_dtx] ), 1 ) ) { hISMDTX->sce_id_dtx = j; move16(); @@ -433,19 +434,19 @@ void ivas_ism_get_sce_id_dtx_fx( * *-------------------------------------------------------------------*/ void ivas_ism_coh_estim_dtx_enc_fx( - ISM_DTX_HANDLE hISMDTX, /* i/o: ISM DTX handle */ - SCE_ENC_HANDLE hSCE[MAX_SCE], /* i/o: SCE encoder structure */ - const Word16 nchan_transport, /* i : number of transport channels */ - const Word16 input_frame /* i : input frame length */ + ISM_DTX_HANDLE hISMDTX, /* i/o: ISM DTX handle */ + SCE_ENC_HANDLE hSCE[MAX_SCE], /* i/o: SCE encoder structure */ + const Word16 nchan_transport, /* i : number of transport channels Q0*/ + const Word16 input_frame /* i : input frame length Q0*/ ) { Encoder_State *st, *st_id0; Word16 sce_id, i; Word32 acorr_ene_fx[MAX_NUM_OBJECTS], xcorr_ene_fx; Word16 acorr_ene_e[MAX_NUM_OBJECTS], xcorr_ene_e; - Word16 norm_inp; - Word16 tot_exp; - Word32 scaled_inp; + Word16 norm_inp, norm_inp0; + Word16 tot_exp, tot_exp2; + Word32 scaled_inp, scaled_inp0; set16_fx( acorr_ene_e, 0, MAX_NUM_OBJECTS ); IF( EQ_16( nchan_transport, 1 ) ) @@ -465,7 +466,7 @@ void ivas_ism_coh_estim_dtx_enc_fx( norm_inp = norm_l( st_id0->input32_fx[i] ); scaled_inp = L_shl( st_id0->input32_fx[i], norm_inp ); tot_exp = shl( sub( 20, norm_inp ), 1 ); - acorr_ene_fx[hISMDTX->sce_id_dtx] = BASOP_Util_Add_Mant32Exp( acorr_ene_fx[hISMDTX->sce_id_dtx], acorr_ene_e[hISMDTX->sce_id_dtx], Mult_32_32( scaled_inp, scaled_inp ), tot_exp, &acorr_ene_e[hISMDTX->sce_id_dtx] ); + acorr_ene_fx[hISMDTX->sce_id_dtx] = BASOP_Util_Add_Mant32Exp( acorr_ene_fx[hISMDTX->sce_id_dtx], acorr_ene_e[hISMDTX->sce_id_dtx], Mult_32_32( scaled_inp, scaled_inp ), tot_exp, &acorr_ene_e[hISMDTX->sce_id_dtx] ); /* exp(acorr_ene_e) */ move32(); } @@ -473,9 +474,9 @@ void ivas_ism_coh_estim_dtx_enc_fx( { IF( EQ_16( sce_id, hISMDTX->sce_id_dtx ) ) { - hISMDTX->coh_fx[sce_id] = 32767; + hISMDTX->coh_fx[sce_id] = 32767; /* 1 in Q15 */ move16(); - continue; + CONTINUE; } st = hSCE[sce_id]->hCoreCoder[0]; @@ -491,15 +492,18 @@ void ivas_ism_coh_estim_dtx_enc_fx( { norm_inp = norm_l( st->input32_fx[i] ); scaled_inp = L_shl( st->input32_fx[i], norm_inp ); - tot_exp = shl( sub( 20, norm_inp ), 1 ); - acorr_ene_fx[sce_id] = BASOP_Util_Add_Mant32Exp( acorr_ene_fx[sce_id], acorr_ene_e[sce_id], Mult_32_32( scaled_inp, scaled_inp ), tot_exp, &acorr_ene_e[sce_id] ); + tot_exp = shl( sub( sub( 31, st->q_inp32 ), norm_inp ), 1 ); + acorr_ene_fx[sce_id] = BASOP_Util_Add_Mant32Exp( acorr_ene_fx[sce_id], acorr_ene_e[sce_id], Mult_32_32( scaled_inp, scaled_inp ), tot_exp, &acorr_ene_e[sce_id] ); /* exp(acorr_ene_e) */ move32(); - xcorr_ene_fx = BASOP_Util_Add_Mant32Exp( xcorr_ene_fx, xcorr_ene_e, Mult_32_32( scaled_inp, scaled_inp ), tot_exp, &xcorr_ene_e ); + norm_inp0 = norm_l( st_id0->input32_fx[i] ); + scaled_inp0 = L_shl( st_id0->input32_fx[i], norm_inp0 ); + tot_exp2 = add( sub( sub( 31, st_id0->q_inp32 ), norm_inp0 ), sub( sub( 31, st->q_inp32 ), norm_inp ) ); + xcorr_ene_fx = BASOP_Util_Add_Mant32Exp( xcorr_ene_fx, xcorr_ene_e, Mult_32_32( scaled_inp, scaled_inp0 ), tot_exp2, &xcorr_ene_e ); /* exp(xcorr_ene_e) */ } Word16 coh_e; Word16 temp_e = acorr_ene_e[hISMDTX->sce_id_dtx] + acorr_ene_e[sce_id]; Word32 temp = Sqrt32( L_add( Mult_32_32( acorr_ene_fx[hISMDTX->sce_id_dtx], acorr_ene_fx[sce_id] ), EPSILON_FX ), &temp_e ); /*fabsf( xcorr_ene ) / ( sqrtf( ( acorr_ene[hISMDTX->sce_id_dtx] * acorr_ene[sce_id] ) + EPSILON ) );*/ - hISMDTX->coh_fx[sce_id] = BASOP_Util_Divide3232_Scale( L_abs( xcorr_ene_fx ), temp, &coh_e ); + hISMDTX->coh_fx[sce_id] = BASOP_Util_Divide3232_Scale( L_abs( xcorr_ene_fx ), temp, &coh_e ); /* coh_e + (xcorr_ene_e - temp_e) */ move16(); coh_e = add( coh_e, sub( xcorr_ene_e, temp_e ) ); IF( coh_e < 0 ) @@ -509,7 +513,7 @@ void ivas_ism_coh_estim_dtx_enc_fx( coh_e = 0; } /* ensure value of coherence is between [0,1] */ - hISMDTX->coh_fx[sce_id] = check_bounds_s_fx( hISMDTX->coh_fx[sce_id], 0, shl_sat( 1, 15 - coh_e ) ); + hISMDTX->coh_fx[sce_id] = check_bounds_s_fx( hISMDTX->coh_fx[sce_id], 0, shl_sat( 1, 15 - coh_e ) ); /* Q0 */ hISMDTX->coh_fx[sce_id] = shl_sat( hISMDTX->coh_fx[sce_id], coh_e ); move16(); move16(); diff --git a/lib_enc/ivas_ism_enc.c b/lib_enc/ivas_ism_enc_fx.c similarity index 77% rename from lib_enc/ivas_ism_enc.c rename to lib_enc/ivas_ism_enc_fx.c index 1a956f4c5a583fd8297302d0977672a3b37c78e7..1b648cc98a530eea4f7b8a8db1b089d6044e3e34 100644 --- a/lib_enc/ivas_ism_enc.c +++ b/lib_enc/ivas_ism_enc_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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,12 +33,10 @@ #include #include "options.h" #include "ivas_cnst.h" -#include "prot.h" -#include "ivas_prot.h" +#include "prot_fx.h" #include "ivas_stat_enc.h" #include "wmc_auto.h" #include "ivas_prot_fx.h" -#include "prot_fx.h" #include "prot_fx_enc.h" #ifdef DEBUGGING #include "debug.h" @@ -51,12 +49,12 @@ * ISM CoreCoders encoding routine *-------------------------------------------------------------------*/ ivas_error ivas_ism_enc_fx( - Encoder_Struct *st_ivas, /* i/o: IVAS encoder structure */ - Word32 *data[], /* i : input signal [channels][samples] Q(q_data) */ - Word16 q_data, /* i : Q-factor of input signal */ - const Word16 input_frame, /* i : input frame length per channel */ - Word16 *nb_bits_metadata, /* i : number of metadata bits */ - const Word16 flag_omasa_ener_brate /* i : less bitrate for objects in OMASA flag */ + Encoder_Struct *st_ivas, /* i/o: IVAS encoder structure */ + Word32 *data[], /* i : input signal [channels][samples] Q(q_data)*/ + Word16 q_data, /* i : Q-factor of input signal */ + const Word16 input_frame, /* i : input frame length per channel Q0*/ + Word16 *nb_bits_metadata, /* i : number of metadata bits Q0*/ + const Word16 flag_omasa_ener_brate /* i : less bitrate for objects in OMASA flag Q0*/ ) { SCE_ENC_HANDLE hSCE; @@ -138,7 +136,7 @@ ivas_error ivas_ism_enc_fx( move16(); set16_fx( md_diff_flag, 1, nchan_ism ); - nchan_transport_ism = st_ivas->nchan_transport; + nchan_transport_ism = st_ivas->nchan_transport; /* Q0 */ move16(); IF( EQ_32( st_ivas->ism_mode, ISM_MASA_MODE_MASA_ONE_OBJ ) ) { @@ -149,7 +147,7 @@ ivas_error ivas_ism_enc_fx( } ELSE IF( EQ_32( st_ivas->ism_mode, ISM_MASA_MODE_DISC ) ) { - nchan_transport_ism = st_ivas->hEncoderConfig->nchan_ism; + nchan_transport_ism = st_ivas->hEncoderConfig->nchan_ism; /* Q0 */ move16(); } FOR( sce_id = 0; sce_id < nchan_transport_ism; sce_id++ ) @@ -197,6 +195,9 @@ ivas_error ivas_ism_enc_fx( #ifdef DEBUGGING st->force = st_ivas->hEncoderConfig->force; st->id_element = sce_id; +#ifdef DEBUG_FORCE_DIR + st->force_dir = st_ivas->hEncoderConfig->force_dir; +#endif #endif move16(); move16(); @@ -225,6 +226,11 @@ ivas_error ivas_ism_enc_fx( st->bits_frame_nominal = sub( extract_l( Mpy_32_32( hSCE->element_brate, ONE_BY_FRAMES_PER_SEC_Q31 ) ), ISM_NB_BITS_METADATA_NOMINAL ); move16(); + +#ifdef DEBUG_MODE_INFO + dbgwrite( &st->element_mode, sizeof( int16_t ), 1, input_frame, fname( debug_dir, "element_mode", 0, st->id_element, ENC ) ); +#endif + /*----------------------------------------------------------------* * Front Pre-processing *----------------------------------------------------------------*/ @@ -237,11 +243,15 @@ ivas_error ivas_ism_enc_fx( q_old_wsp = Q15; move16(); - + Word16 q_fr_bands[2]; error = pre_proc_front_ivas_fx( hSCE, NULL, hSCE->element_brate, nb_bits_metadata[sce_id], input_frame, 0, old_inp_12k8_fx[sce_id][0], old_inp_16k_fx[sce_id][0], &ener_fx[sce_id][0], &relE_fx[sce_id][0], A_fx[sce_id][0], Aw_fx[sce_id][0], epsP_fx[sce_id][0], &epsP_fx_q[sce_id][0], lsp_new_fx[sce_id][0], lsp_mid_fx[sce_id][0], &vad_hover_flag[sce_id][0], &attack_flag[sce_id][0], realBuffer_fx[sce_id][0], imagBuffer_fx[sce_id][0], &q_re_im_buf[sce_id], old_wsp_fx[sce_id][0], &q_old_wsp, pitch_fr_fx[sce_id][0], voicing_fr_fx[sce_id][0], &loc_harm[sce_id][0], &cor_map_sum_fx[sce_id][0], &vad_flag_dtx[sce_id][0], enerBuffer_fx[sce_id][0], &enerBuffer_fx_exp[sce_id][0], - fft_buff_fx[sce_id][0], &fft_buff_fx_q[sce_id][0], A_fx[sce_id][0], lsp_new_fx[sce_id][0], currFlatness_fx[0], 0, fr_bands_fx, 31, Etot_LR_fx, lf_E_fx, 31, localVAD_HE_SAD, NULL, 31, 0, 0, 0, 0, ISM_FORMAT, 0, st_ivas->hEncoderConfig->ivas_total_brate, &Q_new[sce_id][0] +#ifdef NONBE_1211_DTX_BR_SWITCHING + fft_buff_fx[sce_id][0], &fft_buff_fx_q[sce_id][0], A_fx[sce_id][0], lsp_new_fx[sce_id][0], currFlatness_fx[0], 0, fr_bands_fx, q_fr_bands, Etot_LR_fx, lf_E_fx, 31, localVAD_HE_SAD, NULL, 31, 0, 0, 0, 0, ISM_FORMAT, 0, st_ivas->hEncoderConfig->last_ivas_total_brate, st_ivas->hEncoderConfig->ivas_total_brate, &Q_new[sce_id][0] +#else + fft_buff_fx[sce_id][0], &fft_buff_fx_q[sce_id][0], A_fx[sce_id][0], lsp_new_fx[sce_id][0], currFlatness_fx[0], 0, fr_bands_fx, q_fr_bands, Etot_LR_fx, lf_E_fx, 31, localVAD_HE_SAD, NULL, 31, 0, 0, 0, 0, ISM_FORMAT, 0, st_ivas->hEncoderConfig->ivas_total_brate, &Q_new[sce_id][0] +#endif #ifdef DEBUG_MODE_INFO , st->id_element @@ -249,7 +259,7 @@ ivas_error ivas_ism_enc_fx( ); e_old_wsp[sce_id][0] = sub( Q15, q_old_wsp ); move16(); - IF( NE_32( error, IVAS_ERR_OK ) ) + IF( error != IVAS_ERR_OK ) { return error; } @@ -261,7 +271,7 @@ ivas_error ivas_ism_enc_fx( } ELSE { - vad_flag[sce_id] = st->vad_flag; + vad_flag[sce_id] = st->vad_flag; /* Q0 */ move16(); } } @@ -276,7 +286,11 @@ ivas_error ivas_ism_enc_fx( test(); IF( st_ivas->hSCE[j] && st_ivas->hSCE[j]->hCoreCoder[0] ) { - Copy_Scale_sig_16_32( st_ivas->hSCE[j]->hCoreCoder[0]->input_fx, st_ivas->hSCE[j]->hCoreCoder[0]->input32_fx, input_frame, sub( Q11, st_ivas->hSCE[j]->hCoreCoder[0]->q_inp ) ); +#ifdef FIX_ISSUE_1237 + Copy_Scale_sig_16_32_no_sat( st_ivas->hSCE[j]->hCoreCoder[0]->input_fx, st_ivas->hSCE[j]->hCoreCoder[0]->input32_fx, input_frame, sub( Q11, st_ivas->hSCE[j]->hCoreCoder[0]->q_inp ) ); /* Q11 */ +#else + Copy_Scale_sig_16_32_DEPREC( st_ivas->hSCE[j]->hCoreCoder[0]->input_fx, st_ivas->hSCE[j]->hCoreCoder[0]->input32_fx, input_frame, sub( Q11, st_ivas->hSCE[j]->hCoreCoder[0]->q_inp ) ); /* Q11 */ +#endif st_ivas->hSCE[j]->hCoreCoder[0]->q_inp32 = Q11; move16(); } @@ -286,7 +300,7 @@ ivas_error ivas_ism_enc_fx( { ivas_ism_get_sce_id_dtx_fx( st_ivas->hISMDTX, st_ivas->hSCE, st_ivas->nchan_transport, input_frame ); - dtx_flag = ivas_ism_dtx_enc_fx( st_ivas->hISMDTX, st_ivas->hSCE, st_ivas->hEncoderConfig->ivas_total_brate, nchan_ism, st_ivas->nchan_transport, vad_flag, st_ivas->hIsmMetaData, md_diff_flag, &sid_flag ); + dtx_flag = ivas_ism_dtx_enc_fx( st_ivas->hISMDTX, st_ivas->hSCE, st_ivas->hEncoderConfig->ivas_total_brate, nchan_ism, st_ivas->nchan_transport, vad_flag, st_ivas->hIsmMetaData, md_diff_flag, &sid_flag ); /* Q0 */ IF( sid_flag ) { @@ -300,20 +314,20 @@ ivas_error ivas_ism_enc_fx( * Metadata quantization and encoding *-----------------------------------------------------------------*/ - IF( EQ_16( st_ivas->ism_mode, ISM_MODE_PARAM ) ) + IF( EQ_32( st_ivas->ism_mode, ISM_MODE_PARAM ) ) { - ivas_param_ism_compute_noisy_speech_flag( st_ivas ); - flag_noisy_speech = st_ivas->hParamIsm->flag_noisy_speech; + ivas_param_ism_compute_noisy_speech_flag_fx( st_ivas ); + flag_noisy_speech = st_ivas->hParamIsm->flag_noisy_speech; // Q0 move16(); } IF( dtx_flag ) { - ivas_ism_metadata_sid_enc( st_ivas->hISMDTX, flag_noisy_speech, nchan_ism, st_ivas->nchan_transport, st_ivas->ism_mode, st_ivas->hIsmMetaData, sid_flag, md_diff_flag, st_ivas->hSCE[st_ivas->nSCE - 1]->hMetaData, nb_bits_metadata ); + ivas_ism_metadata_sid_enc_fx( st_ivas->hISMDTX, flag_noisy_speech, nchan_ism, st_ivas->nchan_transport, st_ivas->ism_mode, st_ivas->hIsmMetaData, sid_flag, md_diff_flag, st_ivas->hSCE[st_ivas->nSCE - 1]->hMetaData, nb_bits_metadata ); } ELSE IF( EQ_32( st_ivas->ism_mode, ISM_MODE_PARAM ) ) { - IF( NE_32( ( error = ivas_ism_metadata_enc( &st_ivas->hEncoderConfig->ivas_total_brate, nchan_ism, nchan_transport_ism, st_ivas->hIsmMetaData, st_ivas->hSCE, st_ivas->hSCE[st_ivas->nSCE - 1]->hMetaData, nb_bits_metadata, vad_flag, st_ivas->ism_mode, st_ivas->hParamIsm, st_ivas->hEncoderConfig->ism_extended_metadata_flag, -256 /* -1.0f in Q8 */, 0, NULL, st_ivas->hSCE[0]->hCoreCoder[0]->ini_frame ) ), IVAS_ERR_OK ) ) + IF( ( error = ivas_ism_metadata_enc_fx( &st_ivas->hEncoderConfig->ivas_total_brate, nchan_ism, nchan_transport_ism, st_ivas->hIsmMetaData, st_ivas->hSCE, st_ivas->hSCE[st_ivas->nSCE - 1]->hMetaData, nb_bits_metadata, vad_flag, st_ivas->ism_mode, st_ivas->hParamIsm, st_ivas->hEncoderConfig->ism_extended_metadata_flag, -256 /* -1.0f in Q8 */, 0, NULL, st_ivas->hSCE[0]->hCoreCoder[0]->ini_frame ) ) != IVAS_ERR_OK ) { return error; } @@ -327,28 +341,49 @@ ivas_error ivas_ism_enc_fx( move16(); FOR( i = 0; i < st_ivas->nSCE; i++ ) { - ism_total_brate = L_add( ism_total_brate, st_ivas->hSCE[i]->element_brate ); + ism_total_brate = L_add( ism_total_brate, st_ivas->hSCE[i]->element_brate ); /* Q0 */ } } ELSE { - ism_total_brate = st_ivas->hEncoderConfig->ivas_total_brate; + ism_total_brate = st_ivas->hEncoderConfig->ivas_total_brate; /* Q0 */ move32(); } - ism_total_brate_ref = ism_total_brate; + ism_total_brate_ref = ism_total_brate; /* Q0 */ move32(); - IF( NE_32( ( error = ivas_ism_metadata_enc( &ism_total_brate, nchan_ism, nchan_transport_ism, st_ivas->hIsmMetaData, st_ivas->hSCE, st_ivas->hSCE[st_ivas->nSCE - 1]->hMetaData, - nb_bits_metadata, vad_flag, st_ivas->ism_mode, NULL, st_ivas->hEncoderConfig->ism_extended_metadata_flag, st_ivas->hMasa != NULL ? st_ivas->hMasa->data.hOmasaData->lp_noise_CPE_fx : 0, flag_omasa_ener_brate, st_ivas->hMasa != NULL ? &( st_ivas->hMasa->data.hOmasaData->omasa_stereo_sw_cnt ) : NULL, st_ivas->hSCE[0]->hCoreCoder[0]->ini_frame ) ), - IVAS_ERR_OK ) ) + Word16 lp_noise_CPE_fx; + if ( st_ivas->hMasa != NULL ) + { + lp_noise_CPE_fx = st_ivas->hMasa->data.hOmasaData->lp_noise_CPE_fx; + move16(); + } + else + { + lp_noise_CPE_fx = 0; + move16(); + } + + Word16 *omasa_stereo_sw_cnt; + if ( st_ivas->hMasa != NULL ) + { + omasa_stereo_sw_cnt = &( st_ivas->hMasa->data.hOmasaData->omasa_stereo_sw_cnt ); + } + else + { + omasa_stereo_sw_cnt = NULL; + } + IF( ( error = ivas_ism_metadata_enc_fx( &ism_total_brate, nchan_ism, nchan_transport_ism, st_ivas->hIsmMetaData, st_ivas->hSCE, st_ivas->hSCE[st_ivas->nSCE - 1]->hMetaData, + nb_bits_metadata, vad_flag, st_ivas->ism_mode, NULL, st_ivas->hEncoderConfig->ism_extended_metadata_flag, lp_noise_CPE_fx, flag_omasa_ener_brate, omasa_stereo_sw_cnt, st_ivas->hSCE[0]->hCoreCoder[0]->ini_frame ) ) != + IVAS_ERR_OK ) { return error; } IF( EQ_32( st_ivas->hEncoderConfig->ivas_format, MASA_ISM_FORMAT ) ) { - st_ivas->hCPE[0]->brate_surplus = L_sub( ism_total_brate_ref, ism_total_brate ); + st_ivas->hCPE[0]->brate_surplus = L_sub( ism_total_brate_ref, ism_total_brate ); /* Q0 */ move32(); } } @@ -403,7 +438,7 @@ ivas_error ivas_ism_enc_fx( { Word16 igf; igf = getIgfPresent_fx( st->element_mode, L_mult0( st->bits_frame_nominal, FRAMES_PER_SEC ), st->max_bwidth, st->rf_mode ); - IF( NE_32( ( error = IGF_Reconfig_fx( &st->hIGFEnc, igf, 0, L_mult0( st->bits_frame_nominal, FRAMES_PER_SEC ), st->max_bwidth, st->element_mode, st->rf_mode ) ), IVAS_ERR_OK ) ) + IF( ( error = IGF_Reconfig_fx( &st->hIGFEnc, igf, 0, L_mult0( st->bits_frame_nominal, FRAMES_PER_SEC ), st->max_bwidth, st->element_mode, st->rf_mode ) ) != IVAS_ERR_OK ) { return error; } @@ -423,7 +458,7 @@ ivas_error ivas_ism_enc_fx( } ELSE { - st->flag_ACELP16k = set_ACELP_flag_IVAS( IVAS_SCE, hSCE->element_brate, st->total_brate, 0, 0, -1, -1 ); + st->flag_ACELP16k = set_ACELP_flag_IVAS( IVAS_SCE, hSCE->element_brate, st->total_brate, 0, 0, -1, -1 ); /* Q0 */ move16(); } @@ -437,10 +472,10 @@ ivas_error ivas_ism_enc_fx( test(); IF( !dtx_flag || ( dtx_flag && EQ_16( sce_id, st_ivas->hISMDTX->sce_id_dtx ) ) ) { - Scale_sig( old_wsp_fx[sce_id][0], L_WSP, sub( e_old_wsp[sce_id][0], Q16 ) ); + Scale_sig( old_wsp_fx[sce_id][0], L_WSP, sub( e_old_wsp[sce_id][0], Q16 ) ); /* exp(16) */ e_old_wsp[sce_id][0] = 16; move16(); - IF( NE_32( ( error = ivas_core_enc( hSCE, NULL, NULL, 1, old_inp_12k8_fx[sce_id], old_inp_16k_fx[sce_id], Q_new[sce_id], ener_fx[sce_id], A_fx[sce_id], Aw_fx[sce_id], epsP_fx[sce_id], epsP_fx_q[sce_id], lsp_new_fx[sce_id], lsp_mid_fx[sce_id], vad_hover_flag[sce_id], attack_flag[sce_id], realBuffer_fx[sce_id], imagBuffer_fx[sce_id], &q_re_im_buf[sce_id], old_wsp_fx[sce_id], e_old_wsp[sce_id], loc_harm[sce_id], cor_map_sum_fx[sce_id], vad_flag_dtx[sce_id], enerBuffer_fx[sce_id], enerBuffer_fx_exp[sce_id], fft_buff_fx[sce_id], 0, ISM_FORMAT, 0 ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = ivas_core_enc_fx( hSCE, NULL, NULL, 1, old_inp_12k8_fx[sce_id], old_inp_16k_fx[sce_id], Q_new[sce_id], ener_fx[sce_id], A_fx[sce_id], Aw_fx[sce_id], epsP_fx[sce_id], epsP_fx_q[sce_id], lsp_new_fx[sce_id], lsp_mid_fx[sce_id], vad_hover_flag[sce_id], attack_flag[sce_id], realBuffer_fx[sce_id], imagBuffer_fx[sce_id], &q_re_im_buf[sce_id], old_wsp_fx[sce_id], e_old_wsp[sce_id], loc_harm[sce_id], cor_map_sum_fx[sce_id], vad_flag_dtx[sce_id], enerBuffer_fx[sce_id], enerBuffer_fx_exp[sce_id], fft_buff_fx[sce_id], 0, ISM_FORMAT, 0 ) ), IVAS_ERR_OK ) ) { return error; } @@ -452,15 +487,15 @@ ivas_error ivas_ism_enc_fx( /* update input samples buffer */ - Copy( st->input_fx, st->old_input_signal_fx, input_frame ); + Copy( st->input_fx, st->old_input_signal_fx, input_frame ); /* st->q_inp */ st->q_old_inp = st->q_inp; move16(); - hSCE->last_element_brate = hSCE->element_brate; + hSCE->last_element_brate = hSCE->element_brate; /* Q0 */ move32(); /* Store previous attack detection flag */ - st->hTranDet->transientDetector.prev_bIsAttackPresent = st->hTranDet->transientDetector.bIsAttackPresent; + st->hTranDet->transientDetector.prev_bIsAttackPresent = st->hTranDet->transientDetector.bIsAttackPresent; /* Q0 */ move16(); prev_st = st; @@ -472,9 +507,9 @@ ivas_error ivas_ism_enc_fx( { IF( NE_16( sce_id, st_ivas->hISMDTX->sce_id_dtx ) ) { - st_ivas->hSCE[sce_id]->hCoreCoder[0]->last_core = st_ivas->hSCE[st_ivas->hISMDTX->sce_id_dtx]->hCoreCoder[0]->last_core; - st_ivas->hSCE[sce_id]->hCoreCoder[0]->last_core_brate = st_ivas->hSCE[st_ivas->hISMDTX->sce_id_dtx]->hCoreCoder[0]->core_brate; - st_ivas->hSCE[sce_id]->hCoreCoder[0]->last_L_frame = st_ivas->hSCE[st_ivas->hISMDTX->sce_id_dtx]->hCoreCoder[0]->last_L_frame; + st_ivas->hSCE[sce_id]->hCoreCoder[0]->last_core = st_ivas->hSCE[st_ivas->hISMDTX->sce_id_dtx]->hCoreCoder[0]->last_core; /* Q0 */ + st_ivas->hSCE[sce_id]->hCoreCoder[0]->last_core_brate = st_ivas->hSCE[st_ivas->hISMDTX->sce_id_dtx]->hCoreCoder[0]->core_brate; /* Q0 */ + st_ivas->hSCE[sce_id]->hCoreCoder[0]->last_L_frame = st_ivas->hSCE[st_ivas->hISMDTX->sce_id_dtx]->hCoreCoder[0]->last_L_frame; /* Q0 */ move16(); move32(); move16(); @@ -482,6 +517,20 @@ ivas_error ivas_ism_enc_fx( } } +#ifdef DEBUG_MODE_INFO + for ( sce_id = 0; sce_id < nchan_transport_ism; sce_id++ ) + { + float tmpF; + int16_t id; + + st = st_ivas->hSCE[sce_id]->hCoreCoder[0]; + id = st->id_element; + + tmpF = st->element_brate / 1000.0f; + dbgwrite( &tmpF, sizeof( float ), 1, input_frame, fname( debug_dir, "element_brate", 0, id, ENC ) ); + } +#endif + pop_wmops(); return error; @@ -509,7 +558,7 @@ ivas_error ivas_ism_enc_config( move16(); /* select ISM format mode */ - st_ivas->ism_mode = ivas_ism_mode_select( st_ivas->hEncoderConfig->nchan_inp, st_ivas->hEncoderConfig->ivas_total_brate ); + st_ivas->ism_mode = ivas_ism_mode_select( st_ivas->hEncoderConfig->nchan_inp, st_ivas->hEncoderConfig->ivas_total_brate ); /* Q0 */ move16(); /* ISM bit-rate switching */ @@ -518,7 +567,7 @@ ivas_error ivas_ism_enc_config( { Word32 element_brate_tmp[MAX_NUM_OBJECTS]; - nchan_transport_old = st_ivas->nchan_transport; + nchan_transport_old = st_ivas->nchan_transport; /* Q0 */ move16(); /* Reset and Initialize */ @@ -528,25 +577,25 @@ ivas_error ivas_ism_enc_config( } ELSE { - st_ivas->nchan_transport = st_ivas->hEncoderConfig->nchan_inp; + st_ivas->nchan_transport = st_ivas->hEncoderConfig->nchan_inp; /* Q0 */ } move16(); - nCPE_old = st_ivas->nCPE; + nCPE_old = st_ivas->nCPE; /* Q0 */ move16(); - nSCE_old = st_ivas->nSCE; + nSCE_old = st_ivas->nSCE; /* Q0 */ move16(); - st_ivas->nSCE = st_ivas->nchan_transport; + st_ivas->nSCE = st_ivas->nchan_transport; /* Q0 */ move16(); st_ivas->nCPE = 0; move16(); - IF( NE_32( ( error = ivas_ism_config_fx( st_ivas->hEncoderConfig->ivas_total_brate, st_ivas->nchan_transport, st_ivas->hEncoderConfig->nchan_inp, NULL, 0, NULL, NULL, element_brate_tmp, NULL, NULL, 0 ) ), IVAS_ERR_OK ) ) + IF( ( error = ivas_ism_config_fx( st_ivas->hEncoderConfig->ivas_total_brate, st_ivas->nchan_transport, st_ivas->hEncoderConfig->nchan_inp, NULL, 0, NULL, NULL, element_brate_tmp, NULL, NULL, 0 ) ) != IVAS_ERR_OK ) { return error; } - IF( NE_32( ( error = ivas_corecoder_enc_reconfig_fx( st_ivas, nSCE_old, nCPE_old, nchan_transport_old, st_ivas->hEncoderConfig->ivas_total_brate / st_ivas->nchan_transport, imult3216( ( st_ivas->hEncoderConfig->ivas_total_brate / st_ivas->nchan_transport ), CPE_CHANNELS ), MC_MODE_NONE ) ), IVAS_ERR_OK ) ) + IF( ( error = ivas_corecoder_enc_reconfig_fx( st_ivas, nSCE_old, nCPE_old, nchan_transport_old, st_ivas->hEncoderConfig->ivas_total_brate / st_ivas->nchan_transport, imult3216( ( st_ivas->hEncoderConfig->ivas_total_brate / st_ivas->nchan_transport ), CPE_CHANNELS ), MC_MODE_NONE ) ) != IVAS_ERR_OK ) { return error; } @@ -555,7 +604,7 @@ ivas_error ivas_ism_enc_config( IF( EQ_16( st_ivas->ism_mode, ISM_MODE_PARAM ) && EQ_16( last_ism_mode, ISM_MODE_DISC ) ) { /* Allocate and Initialize the memory used by ParamISM when switch from Discrete ISM */ - IF( NE_32( ( error = ivas_param_ism_enc_open( st_ivas ) ), IVAS_ERR_OK ) ) + IF( ( error = ivas_param_ism_enc_open_fx( st_ivas ) ) != IVAS_ERR_OK ) { return error; } @@ -565,7 +614,7 @@ ivas_error ivas_ism_enc_config( IF( EQ_16( st_ivas->ism_mode, ISM_MODE_DISC ) && EQ_16( last_ism_mode, ISM_MODE_PARAM ) ) { /* Deallocate the memory used by ParamISM when switch to Discrete ISM */ - ivas_param_ism_enc_close( &( st_ivas->hParamIsm ), st_ivas->hEncoderConfig->input_Fs ); + ivas_param_ism_enc_close_fx( &( st_ivas->hParamIsm ), st_ivas->hEncoderConfig->input_Fs ); } } diff --git a/lib_enc/ivas_ism_metadata_enc.c b/lib_enc/ivas_ism_metadata_enc_fx.c similarity index 93% rename from lib_enc/ivas_ism_metadata_enc.c rename to lib_enc/ivas_ism_metadata_enc_fx.c index ffd0e1b1d456362d6500b9e23f4f0607d8fb0135..8e6e0c93f773a621f921c1fb37a68bed252f81f3 100644 --- a/lib_enc/ivas_ism_metadata_enc.c +++ b/lib_enc/ivas_ism_metadata_enc_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other @@ -35,17 +35,14 @@ #include #include "options.h" #include "ivas_cnst.h" -#include "ivas_prot.h" #include "ivas_prot_fx.h" #include "ivas_rom_com.h" -#include "prot.h" +#include "prot_fx.h" #include #include "wmc_auto.h" -#include "prot_fx.h" #include "ivas_prot_fx.h" #include "ivas_rom_com_fx.h" -#define IVAS_FLOAT_FIXED_TO_BE_REMOVED -#include "ivas_rom_com_fx.h" + /*-----------------------------------------------------------------------* * Local constants @@ -72,9 +69,9 @@ * Local function declarations *-----------------------------------------------------------------------*/ -static void encode_angle_indices( BSTR_ENC_HANDLE hBstr, ISM_METADATA_ANGLE_HANDLE angle, const int16_t last_ism_metadata_flag, const int16_t ini_frame, const int16_t idx_angle1_abs, const int16_t idx_angle2_abs, int16_t *flag_abs_angle1, int16_t *flag_abs_angle2 ); +static void encode_angle_indices_fx( BSTR_ENC_HANDLE hBstr, ISM_METADATA_ANGLE_HANDLE angle, const Word16 last_ism_metadata_flag, const Word16 ini_frame, const Word16 idx_angle1_abs, const Word16 idx_angle2_abs, Word16 *flag_abs_angle1, Word16 *flag_abs_angle2 ); -static void encode_radius( BSTR_ENC_HANDLE hBstr, int16_t *last_radius_idx, int16_t *radius_diff_cnt, const int16_t last_ism_metadata_flag, const int16_t idx_radius_abs, int16_t *flag_abs_radius ); +static void encode_radius_fx( BSTR_ENC_HANDLE hBstr, Word16 *last_radius_idx, Word16 *radius_diff_cnt, const Word16 last_ism_metadata_flag, const Word16 idx_radius_abs, Word16 *flag_abs_radius ); /*-------------------------------------------------------------------------* @@ -102,15 +99,15 @@ ivas_error ivas_set_ism_metadata_fx( move16(); /* save read metadata parameters to the internal codec structure */ - hIsmMeta->azimuth_fx = azimuth; + hIsmMeta->azimuth_fx = azimuth; // Q22 move32(); - hIsmMeta->elevation_fx = elevation; + hIsmMeta->elevation_fx = elevation; // Q22 move32(); - hIsmMeta->radius_fx = radius_meta; + hIsmMeta->radius_fx = radius_meta; // Q9 move16(); - hIsmMeta->yaw_fx = yaw; + hIsmMeta->yaw_fx = yaw; // Q22 move16(); - hIsmMeta->pitch_fx = pitch; + hIsmMeta->pitch_fx = pitch; // Q22 move16(); hIsmMeta->non_diegetic_flag = non_diegetic_flag; move16(); @@ -124,7 +121,7 @@ ivas_error ivas_set_ism_metadata_fx( * Rate importance of particular ISM streams *-------------------------------------------------------------------------*/ -static void rate_ism_importance( +static void rate_ism_importance_fx( const Word16 nchan_transport, /* i : number of transported channels */ ISM_METADATA_HANDLE hIsmMeta[], /* i/o: ISM metadata handles */ SCE_ENC_HANDLE hSCE[], /* i/o: SCE encoder handles */ @@ -187,7 +184,7 @@ static void rate_ism_importance( * quantize and encode ISM metadata *-------------------------------------------------------------------------*/ -ivas_error ivas_ism_metadata_enc( +ivas_error ivas_ism_metadata_enc_fx( Word32 *ism_total_brate, /* i/o: ISM total bitrate */ const Word16 nchan_ism, /* i : number of ISM channels */ const Word16 nchan_transport, /* i : number of transport channels */ @@ -218,7 +215,7 @@ ivas_error ivas_ism_metadata_enc( move16(); Word32 valQ_fx; ISM_METADATA_HANDLE hIsmMetaData; - int32_t element_brate[MAX_NUM_OBJECTS], total_brate[MAX_NUM_OBJECTS]; + Word32 element_brate[MAX_NUM_OBJECTS], total_brate[MAX_NUM_OBJECTS]; Word16 ism_metadata_flag_global; Word16 non_diegetic_flag_global; Word16 ism_imp[MAX_NUM_OBJECTS]; @@ -317,7 +314,10 @@ ivas_error ivas_ism_metadata_enc( } ELSE IF( EQ_16( hIsmMeta[ch]->ism_md_fec_cnt_enc, ISM_MD_FEC_CNT_MAX ) ) { - +#ifdef NONBE_1273_ISM_METADATA_COUNTER + hIsmMeta[ch]->ism_md_fec_cnt_enc = 0; + move16(); +#endif lowrate_metadata_flag[ch] = 1; move16(); hIsmMeta[ch]->position_angle.angle1_diff_cnt = ISM_FEC_MAX; @@ -334,10 +334,21 @@ ivas_error ivas_ism_metadata_enc( IF( NE_16( ism_mode, ISM_SBA_MODE_DISC ) ) { - rate_ism_importance( nchan_transport, hIsmMeta, hSCE, lowrate_metadata_flag, ism_imp ); + rate_ism_importance_fx( nchan_transport, hIsmMeta, hSCE, lowrate_metadata_flag, ism_imp ); } } +#ifdef DEBUG_FORCE_DIR + if ( hSCE[0]->hCoreCoder[0]->force_dir[0] != '\0' ) + { + dbgread( ism_imp, sizeof( int16_t ), nchan_ism, fname( hSCE[0]->hCoreCoder[0]->force_dir, "force_ism_imp.enf", -1, -1, -1 ) ); + } + else + { + dbgwrite( ism_imp, sizeof( int16_t ), nchan_ism, 1, "res/force_ism_imp.enf" ); + } +#endif + /*----------------------------------------------------------------* * Write ISM common signaling *----------------------------------------------------------------*/ @@ -475,18 +486,18 @@ ivas_error ivas_ism_metadata_enc( /* Map azimuth to panning range [-90:90] */ IF( GT_32( hIsmMetaData->azimuth_fx, 377487360 /*90.0f Q22*/ ) ) { - hIsmMetaData->azimuth_fx = L_sub( 754974720 /*180.0f Q22*/, hIsmMetaData->azimuth_fx ); + hIsmMetaData->azimuth_fx = L_sub( 754974720 /*180.0f Q22*/, hIsmMetaData->azimuth_fx ); // Q22 move32(); } IF( LT_32( hIsmMetaData->azimuth_fx, L_negate( 377487360 ) /*-90.0f Q22*/ ) ) { - hIsmMetaData->azimuth_fx = L_sub( L_negate( 754974720 ) /*-180.0f Q22*/, hIsmMetaData->azimuth_fx ); + hIsmMetaData->azimuth_fx = L_sub( L_negate( 754974720 ) /*-180.0f Q22*/, hIsmMetaData->azimuth_fx ); // Q22 move32(); } idx_angle1_abs = ism_quant_meta_fx( hIsmMetaData->azimuth_fx, &valQ_fx, ism_azimuth_borders_fx, ISM_Q_STEP_FX, ISM_Q_STEP_BORDER_FX, 1 << ISM_AZIMUTH_NBITS ); - encode_angle_indices( hBstr, &( hIsmMetaData->position_angle ), hIsmMetaData->last_ism_metadata_flag, hSCE[0]->hCoreCoder[0]->ini_frame, idx_angle1_abs, 0, &flag_abs_azimuth[ch], NULL ); + encode_angle_indices_fx( hBstr, &( hIsmMetaData->position_angle ), hIsmMetaData->last_ism_metadata_flag, hSCE[0]->hCoreCoder[0]->ini_frame, idx_angle1_abs, 0, &flag_abs_azimuth[ch], NULL ); } ELSE { @@ -506,7 +517,7 @@ ivas_error ivas_ism_metadata_enc( idx_angle2_abs = hParamIsm->ele_index[ch]; move16(); } - encode_angle_indices( hBstr, &( hIsmMetaData->position_angle ), hIsmMetaData->last_ism_metadata_flag, ini_frame, idx_angle1_abs, idx_angle2_abs, &flag_abs_azimuth[ch], &flag_abs_elevation[ch] ); + encode_angle_indices_fx( hBstr, &( hIsmMetaData->position_angle ), hIsmMetaData->last_ism_metadata_flag, ini_frame, idx_angle1_abs, idx_angle2_abs, &flag_abs_azimuth[ch], &flag_abs_elevation[ch] ); /*----------------------------------------------------------------* * Quantize and encode radius, yaw, and pitch *----------------------------------------------------------------*/ @@ -520,8 +531,8 @@ ivas_error ivas_ism_metadata_enc( idx_radius_abs = usquant_fx( hIsmMetaData->radius_fx, &valQ_fx_tmp, ISM_RADIUS_MIN_Q9, ISM_RADIUS_DELTA_Q8, 1 << ISM_RADIUS_NBITS ); valQ_fx = L_shr( L_deposit_h( valQ_fx_tmp ), 3 ); // Q22 // valQ = fixedToFloat( valQ_fx, Q22 ); - encode_angle_indices( hBstr, &( hIsmMetaData->orientation_angle ), hIsmMetaData->last_ism_metadata_flag, ini_frame, idx_angle1_abs, idx_angle2_abs, &flag_abs_yaw[ch], &flag_abs_pitch[ch] ); - encode_radius( hBstr, &hIsmMetaData->last_radius_idx, &hIsmMetaData->radius_diff_cnt, hIsmMetaData->last_ism_metadata_flag, idx_radius_abs, &flag_abs_radius[ch] ); + encode_angle_indices_fx( hBstr, &( hIsmMetaData->orientation_angle ), hIsmMetaData->last_ism_metadata_flag, ini_frame, idx_angle1_abs, idx_angle2_abs, &flag_abs_yaw[ch], &flag_abs_pitch[ch] ); + encode_radius_fx( hBstr, &hIsmMetaData->last_radius_idx, &hIsmMetaData->radius_diff_cnt, hIsmMetaData->last_ism_metadata_flag, idx_radius_abs, &flag_abs_radius[ch] ); } } @@ -536,11 +547,11 @@ ivas_error ivas_ism_metadata_enc( } /* Updates */ - hIsmMeta[ch]->last_true_azimuth_fx = hIsmMeta[ch]->azimuth_fx; + hIsmMeta[ch]->last_true_azimuth_fx = hIsmMeta[ch]->azimuth_fx; // Q22 move32(); - hIsmMeta[ch]->last_true_elevation_fx = hIsmMeta[ch]->elevation_fx; + hIsmMeta[ch]->last_true_elevation_fx = hIsmMeta[ch]->elevation_fx; // Q22 move32(); - hIsmMeta[ch]->last_true_radius_fx = hIsmMeta[ch]->radius_fx; + hIsmMeta[ch]->last_true_radius_fx = hIsmMeta[ch]->radius_fx; // Q22 move16(); } } @@ -553,7 +564,7 @@ ivas_error ivas_ism_metadata_enc( i = 0; move16(); test(); - WHILE( i == 0 || i < idiv1616( nchan_ism, INTER_OBJECT_PARAM_CHECK ) ) + WHILE( i == 0 || i < ( nchan_ism / INTER_OBJECT_PARAM_CHECK ) ) { Word16 num, abs_num, abs_first, abs_next, pos_zero; Word16 abs_matrice[INTER_OBJECT_PARAM_CHECK * ISM_NUM_PARAM]; @@ -581,7 +592,7 @@ ivas_error ivas_ism_metadata_enc( abs_first = 0; move16(); - WHILE( GT_16( abs_num, 1 ) ) + WHILE( abs_num > 1 ) { /* find first "1" entry */ WHILE( abs_matrice[abs_first] == 0 ) @@ -599,7 +610,7 @@ ivas_error ivas_ism_metadata_enc( /* find "0" position */ pos_zero = 0; move16(); - WHILE( EQ_16( abs_matrice[pos_zero], 1 ) ) + WHILE( abs_matrice[pos_zero] == 1 ) { pos_zero = add( pos_zero, 1 ); } @@ -612,7 +623,7 @@ ivas_error ivas_ism_metadata_enc( move16(); } - IF( abs_next % ISM_NUM_PARAM == 1 ) + IF( EQ_16( abs_next % ISM_NUM_PARAM, 1 ) ) { hIsmMeta[ch]->position_angle.angle2_diff_cnt = sub( abs_num, 1 ); move16(); @@ -639,6 +650,10 @@ ivas_error ivas_ism_metadata_enc( { hIsmMeta[ch]->ism_md_fec_cnt_enc = add( hIsmMeta[ch]->ism_md_fec_cnt_enc, 1 ); move16(); +#ifdef NONBE_1273_ISM_METADATA_COUNTER + hIsmMeta[ch]->ism_md_fec_cnt_enc = s_min( hIsmMeta[ch]->ism_md_fec_cnt_enc, ISM_MD_FEC_CNT_MAX ); + move16(); +#endif } ELSE { @@ -806,6 +821,10 @@ ivas_error ivas_ism_metadata_enc( { hIsmMeta[ch]->ism_md_fec_cnt_enc = add( hIsmMeta[ch]->ism_md_fec_cnt_enc, 1 ); move16(); +#ifdef NONBE_1273_ISM_METADATA_COUNTER + hIsmMeta[ch]->ism_md_fec_cnt_enc = s_min( hIsmMeta[ch]->ism_md_fec_cnt_enc, ISM_MD_FEC_CNT_MAX ); + move16(); +#endif } ELSE { @@ -854,7 +873,7 @@ ivas_error ivas_ism_metadata_enc( /* write metadata only in active frames */ IF( GT_32( hSCE[0]->hCoreCoder[0]->core_brate, SID_2k40 ) ) { - reset_indices_enc( hSCE[ch]->hMetaData, hSCE[ch]->hMetaData->nb_ind_tot ); + reset_indices_enc_fx( hSCE[ch]->hMetaData, hSCE[ch]->hMetaData->nb_ind_tot ); } } @@ -869,7 +888,7 @@ ivas_error ivas_ism_metadata_enc( * Create, allocate, initialize and configure IVAS encoder ISM metadata handles *-------------------------------------------------------------------------*/ -ivas_error ivas_ism_metadata_enc_create( +ivas_error ivas_ism_metadata_enc_create_fx( Encoder_Struct *st_ivas, /* i/o: IVAS encoder structure */ const Word16 n_ISms, /* i : number of objects */ Word32 element_brate_tmp[] /* o : element bitrate per object */ @@ -976,21 +995,21 @@ ivas_error ivas_ism_metadata_enc_create( ivas_ism_reset_metadata_enc( st_ivas->hIsmMetaData[ch] ); - st_ivas->hIsmMetaData[ch]->last_azimuth_fx = 0; + st_ivas->hIsmMetaData[ch]->last_azimuth_fx = 0; // Q22 move32(); - st_ivas->hIsmMetaData[ch]->last_elevation_fx = 0; + st_ivas->hIsmMetaData[ch]->last_elevation_fx = 0; // Q22 move32(); - st_ivas->hIsmMetaData[ch]->last_true_azimuth_fx = 0; + st_ivas->hIsmMetaData[ch]->last_true_azimuth_fx = 0; // Q22 move32(); - st_ivas->hIsmMetaData[ch]->last_true_elevation_fx = 0; + st_ivas->hIsmMetaData[ch]->last_true_elevation_fx = 0; // Q22 move32(); st_ivas->hIsmMetaData[ch]->ism_md_fec_cnt_enc = 0; move16(); st_ivas->hIsmMetaData[ch]->ism_md_inc_diff_cnt = ISM_MD_INC_DIFF_CNT_MAX; move16(); - st_ivas->hIsmMetaData[ch]->last_true_radius_fx = ONE_IN_Q9; + st_ivas->hIsmMetaData[ch]->last_true_radius_fx = ONE_IN_Q9; // Q9 move16(); } @@ -1028,7 +1047,7 @@ ivas_error ivas_ism_metadata_enc_create( * * Radius index encoding *-------------------------------------------------------------------------*/ -static void encode_radius( +static void encode_radius_fx( BSTR_ENC_HANDLE hBstr, /* i/o: bitstream handle */ Word16 *last_radius_idx, /* i/o: last radius index */ Word16 *radius_diff_cnt, /* i/o: radius diff coding counter */ @@ -1143,7 +1162,7 @@ static void encode_radius( * Encoding of an angle *----------------------------------------------------------------*/ -static void encode_angle_indices( +static void encode_angle_indices_fx( BSTR_ENC_HANDLE hBstr, /* i/o: bitstream handle */ ISM_METADATA_ANGLE_HANDLE angle, /* i/o: angle handle */ const Word16 last_ism_metadata_flag, /* i : last frame ism_metadata_flag */ @@ -1168,8 +1187,8 @@ static void encode_angle_indices( move16(); *flag_abs_angle1 = 0; /* differential coding by default */ test(); - if ( EQ_16( angle->angle1_diff_cnt, ISM_FEC_MAX ) /* make differential encoding in ISM_FEC_MAX consecutive frames at maximum (in order to control the decoding in FEC) */ - || last_ism_metadata_flag == 0 /* If last frame had no metadata coded, do not use differential coding */ + IF( EQ_16( angle->angle1_diff_cnt, ISM_FEC_MAX ) /* make differential encoding in ISM_FEC_MAX consecutive frames at maximum (in order to control the decoding in FEC) */ + || last_ism_metadata_flag == 0 /* If last frame had no metadata coded, do not use differential coding */ ) { *flag_abs_angle1 = 1; @@ -1418,7 +1437,7 @@ static void encode_angle_indices( * Quantize and encode ISM metadata in SID frame *-------------------------------------------------------------------*/ -void ivas_ism_metadata_sid_enc( +void ivas_ism_metadata_sid_enc_fx( ISM_DTX_HANDLE hISMDTX, /* i/o: ISM DTX handle */ const Word16 flag_noisy_speech, /* i : noisy speech flag */ const Word16 nchan_ism, /* i : number of objects */ diff --git a/lib_enc/ivas_ism_param_enc.c b/lib_enc/ivas_ism_param_enc_fx.c similarity index 92% rename from lib_enc/ivas_ism_param_enc.c rename to lib_enc/ivas_ism_param_enc_fx.c index 171b229b4bcd8d47533f0b9c98ba640b7e387970..cda8cffd674b477b98ea0d5bc665a92cd1198792 100644 --- a/lib_enc/ivas_ism_param_enc.c +++ b/lib_enc/ivas_ism_param_enc_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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,9 +34,7 @@ #include #include #include "options.h" -#include "ivas_prot.h" #include "ivas_prot_fx.h" -#include "prot.h" #include "prot_fx.h" #include "cnst.h" #include "ivas_cnst.h" @@ -160,7 +158,7 @@ static void ivas_param_ism_compute_obj_parameters_fx( move16(); move16(); } - assert( ( power_ratios_m[b][m] >= ONE_IN_Q14 /* 0.5 in Q15 */ ) && ( power_ratios_m[b][m] <= ONE_IN_Q15 /* 1 in Q15 */ ) ); + assert( ( power_ratios_m[b][m] >= ONE_IN_Q14 /* 0.5 in Q15 */ ) && ( power_ratios_m[b][m] <= MAX_16 /* 1 in Q15 */ ) ); /* Quantize power ratios */ /* Power ratio range [0.5,1] is mapped to [0,1] first, rounding via truncation float->integer */ @@ -180,7 +178,7 @@ static void ivas_param_ism_compute_obj_parameters_fx( tmp1 = W_norm( ref_power_local_frame[0] ); tmp2 = W_norm( ref_power_local_frame[i] ); tmp_ratio = BASOP_Util_Divide3232_Scale( W_extract_h( W_shl( ref_power_local_frame[0], tmp1 ) ), W_extract_h( W_shl( ref_power_local_frame[i], tmp2 ) ), &e_tmp ); // ((Qx + tmp1) - 16) - ((Qx + tmp2) - 16) + 15 - e_tmp = 15 + tmp1 - tmp2 - e_tmp - tmp_ratio = W_shl( tmp_ratio, sub( sub( e_tmp, 1 ), sub( tmp1, tmp2 ) ) ); // Q14 + tmp_ratio = W_shl( tmp_ratio, sub( sub( e_tmp, 1 ), sub( tmp1, tmp2 ) ) ); // Q14 // Q14 test(); IF( GT_64( tmp_ratio, 15974 /* 0.975f in Q14 */ ) && LT_64( tmp_ratio, 16794 /* 1.025f in Q14*/ ) ) @@ -220,7 +218,7 @@ static void ivas_param_ism_enc_quantize_DOA_fx( azi_idx = ism_quant_meta_fx( hIsmMetaData[i]->azimuth_fx, &valQ_fx, ism_azimuth_borders_fx, ISM_Q_STEP_FX, ISM_Q_STEP_BORDER_FX, 1 << ISM_AZIMUTH_NBITS ); /*Replace azimuth with quantized values */ - hIsmMetaData[i]->azimuth_fx = valQ_fx; + hIsmMetaData[i]->azimuth_fx = valQ_fx; // Q22 move32(); /* Copy the quantized indices */ @@ -307,22 +305,22 @@ void ivas_param_ism_stereo_dmx_fx( /* Smoothing */ cardioid_left[i] = add( mult( 24576 /* 0.75f in Q15 */, cardioid_left[i] ), mult( 8192 /* 0.25f in Q15 */, last_cardioid_left ) ); // Q14 move16(); - grad = mult( sub( cardioid_left[i], last_cardioid_left ), shl( one_by_input_frame, 1 ) /* 2.0f / (float) input_frame*/ ); /* Q14 */ /* for the right cardioid, multiply with -1 */ + Word32 grad_32 = L_mult( sub( cardioid_left[i], last_cardioid_left ), shl( one_by_input_frame, 1 ) /* 2.0f / (float) input_frame*/ ); /* Q14+Q16 = Q30 */ /* for the right cardioid, multiply with -1 */ /* Cardioids sum up to 1 */ cardioid_right[i] = sub( ONE_IN_Q14 /* 1.0f in Q14 */, cardioid_left[i] ); /* corresponds to: alpha + ( 1 - alpha ) * cosf( tmp + tmp_1 ); */ move16(); /* Loop over all samples */ - FOR( j = 0; j < shr( input_frame, 1 ); j++ ) + FOR( j = 0; j < input_frame >> 1; j++ ) { tmp = data[i][j]; move32(); - tmp = W_extract_l( W_shr( W_mult_32_16( tmp, add( last_cardioid_left, mult0( j, grad ) ) ), 15 ) ); - stereo_dmx[0][j] = L_add( stereo_dmx[0][j], tmp ); /* Qx DMX Left */ + tmp = W_extract_l( W_shr( W_mult_32_32( tmp, L_add( last_cardioid_left, L_shr( Mpy_32_32( L_shl( j, 22 ), grad_32 ), 7 ) ) ), 15 ) ); /* Qx DMX Left */ + stereo_dmx[0][j] = L_add( stereo_dmx[0][j], tmp ); /* Qx DMX Left */ move32(); tmp = data[i][j]; move32(); - tmp = W_extract_l( W_shr( W_mult_32_16( tmp, add( last_cardioid_right, negate( mult0( j, grad ) ) ) ), 15 ) ); - stereo_dmx[1][j] = L_add( stereo_dmx[1][j], tmp ); /* Qx DMX Right */ + tmp = W_extract_l( W_shr( W_mult_32_32( tmp, L_add( last_cardioid_right, L_shr( L_negate( Mpy_32_32( L_shl( j, 22 ), grad_32 ) ), 7 ) ) ), 15 ) ); /* Qx DMX Right */ + stereo_dmx[1][j] = L_add( stereo_dmx[1][j], tmp ); /* Qx DMX Right */ move32(); ene_data = W_add( ene_data, W_mult_32_32( data[i][j], data[i][j] ) ); /* 2 * Qx + 1 energy of all objects combined */ } @@ -330,13 +328,13 @@ void ivas_param_ism_stereo_dmx_fx( { tmp = data[i][j]; move32(); - tmp = W_extract_l( W_shr( W_mult_32_16( tmp, cardioid_left[i] ), 15 ) ); - stereo_dmx[0][j] = L_add( stereo_dmx[0][j], tmp ); /* Qx DMX Left */ + tmp = W_extract_l( W_shr( W_mult_32_16( tmp, cardioid_left[i] ), 15 ) ); /* Qx DMX Left */ + stereo_dmx[0][j] = L_add( stereo_dmx[0][j], tmp ); /* Qx DMX Left */ move32(); tmp = data[i][j]; move32(); - tmp = W_extract_l( W_shr( W_mult_32_16( tmp, cardioid_right[i] ), 15 ) ); - stereo_dmx[1][j] = L_add( stereo_dmx[1][j], tmp ); /* Qx DMX Right */ + tmp = W_extract_l( W_shr( W_mult_32_16( tmp, cardioid_right[i] ), 15 ) ); /* Qx DMX Right */ + stereo_dmx[1][j] = L_add( stereo_dmx[1][j], tmp ); /* Qx DMX Right */ move32(); ene_data = W_add( ene_data, W_mult_32_32( data[i][j], data[i][j] ) ); /* 2 * Qx + 1 energy of all objects combined */ } @@ -351,18 +349,18 @@ void ivas_param_ism_stereo_dmx_fx( { tmp = data[i][j]; move32(); - tmp = W_extract_l( W_shr( W_mult_32_16( tmp, cardioid_left[i] ), 15 ) ); - stereo_dmx[0][j] = L_add( stereo_dmx[0][j], tmp ); /* Qx DMX Left */ + tmp = W_extract_l( W_shr( W_mult_32_16( tmp, cardioid_left[i] ), 15 ) ); /* Qx DMX Left */ + stereo_dmx[0][j] = L_add( stereo_dmx[0][j], tmp ); /* Qx DMX Left */ move32(); tmp = data[i][j]; move32(); - tmp = W_extract_l( W_shr( W_mult_32_16( tmp, cardioid_right[i] ), 15 ) ); - stereo_dmx[1][j] = L_add( stereo_dmx[1][j], tmp ); /* Qx DMX Right */ + tmp = W_extract_l( W_shr( W_mult_32_16( tmp, cardioid_right[i] ), 15 ) ); /* Qx DMX Right */ + stereo_dmx[1][j] = L_add( stereo_dmx[1][j], tmp ); /* Qx DMX Right */ move32(); ene_data = W_add( ene_data, W_mult_32_32( data[i][j], data[i][j] ) ); /* 2 * Qx + 1 energy of all objects combined */ } } - st_ivas->hParamIsm->last_cardioid_left_fx[i] = cardioid_left[i]; + st_ivas->hParamIsm->last_cardioid_left_fx[i] = cardioid_left[i]; // Q14 move16(); } @@ -374,8 +372,8 @@ void ivas_param_ism_stereo_dmx_fx( tmp_1 = W_norm( ene_data ); tmp_2 = W_norm( ene_dmx ); ene_data = W_shl( ene_data, tmp_1 ); - ene_dmx = W_add( W_shl( ene_dmx, tmp_2 ), 1 ); - dmx_gain = BASOP_Util_Divide3232_Scale( W_extract_h( ene_data ), W_extract_h( ene_dmx ), &dmx_gain_e ); + ene_dmx = W_shl( ene_dmx, tmp_2 ); + dmx_gain = BASOP_Util_Divide3232_Scale( W_extract_h( ene_data ), L_add_sat( W_extract_h( ene_dmx ), 1 ), &dmx_gain_e ); dmx_gain_e = sub( dmx_gain_e, sub( tmp_1, tmp_2 ) ); dmx_gain = Sqrt16( dmx_gain, &dmx_gain_e ); @@ -389,7 +387,7 @@ void ivas_param_ism_stereo_dmx_fx( tmp_1 = 15 + 1; move16(); - FOR( i = 0; i < shr( input_frame, 1 ); i++ ) + FOR( i = 0; i < input_frame >> 1; i++ ) { stereo_dmx[0][i] = W_extract_l( W_shr( W_mult_32_32( stereo_dmx[0][i], L_add( tmp, mult0( i, grad ) ) ), tmp_1 ) ); // Qx move32(); @@ -437,7 +435,7 @@ void ivas_param_ism_stereo_dmx_fx( * Open Param ISM handle *-------------------------------------------------------------------------*/ -ivas_error ivas_param_ism_enc_open( +ivas_error ivas_param_ism_enc_open_fx( Encoder_Struct *st_ivas /* i/o: IVAS encoder structure */ ) { @@ -479,7 +477,7 @@ ivas_error ivas_param_ism_enc_open( hParamIsm->nbands = MAX_PARAM_ISM_NBANDS; move16(); - max_bins = extract_l( Mpy_32_32( input_Fs, 10737418 ) ); // (int16_t) ( ( MDFT_FB_BANDS_240 * input_Fs ) / 48000 ); + max_bins = extract_l( Mpy_32_32( input_Fs, 10737418 /*240/48000.Q31*/ ) ); // (int16_t) ( ( MDFT_FB_BANDS_240 * input_Fs ) / 48000 ); FOR( i = 0; i < ( hParamIsm->nbands + 1 ); i++ ) { hParamIsm->band_grouping[i] = CLDFB_TO_MDFT_FAC * Param_ISM_band_grouping[i]; @@ -505,7 +503,7 @@ ivas_error ivas_param_ism_enc_open( * Close Param ISM encoder handle *-------------------------------------------------------------------------*/ -void ivas_param_ism_enc_close( +void ivas_param_ism_enc_close_fx( PARAM_ISM_CONFIG_HANDLE *hParamIsm, /* i/o: ParamISM handle */ const Word32 input_Fs /* i : input sampling_rate */ ) @@ -604,7 +602,7 @@ void ivas_param_ism_enc_fx( * *-------------------------------------------------------------------*/ -void ivas_param_ism_compute_noisy_speech_flag( +void ivas_param_ism_compute_noisy_speech_flag_fx( Encoder_Struct *st_ivas /* i/o: IVAS encoder structure */ ) { diff --git a/lib_enc/ivas_lfe_enc.c b/lib_enc/ivas_lfe_enc_fx.c similarity index 92% rename from lib_enc/ivas_lfe_enc.c rename to lib_enc/ivas_lfe_enc_fx.c index 6a67cd814f4ab00b21402f326de9305e1d1de693..96959c9dd46fe0d60f391fcbb4c5da5f0e2d3f50 100644 --- a/lib_enc/ivas_lfe_enc.c +++ b/lib_enc/ivas_lfe_enc_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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,12 +33,10 @@ #include #include "options.h" #include "math.h" -#include "prot.h" -#include "ivas_prot.h" +#include "prot_fx.h" #include "ivas_cnst.h" #include "ivas_rom_com.h" #include "wmc_auto.h" -#include "prot_fx.h" #include "ivas_prot_fx.h" @@ -171,17 +169,17 @@ static void ivas_lfe_enc_quant_fx( { temp_lfe_dct[4 * i] = pLfe_dct[2 * i]; move32(); - lfe_abs_sum = W_add( lfe_abs_sum, abs( temp_lfe_dct[4 * i] ) ); + lfe_abs_sum = W_add( lfe_abs_sum, L_abs( temp_lfe_dct[4 * i] ) ); temp_lfe_dct[4 * i + 1] = pLfe_dct[2 * i + 1]; move32(); - lfe_abs_sum = W_add( lfe_abs_sum, abs( temp_lfe_dct[4 * i + 1] ) ); + lfe_abs_sum = W_add( lfe_abs_sum, L_abs( temp_lfe_dct[4 * i + 1] ) ); temp_lfe_dct[4 * i + 2] = pLfe_dct[2 * i + num_dct_pass_bins]; move32(); - lfe_abs_sum = W_add( lfe_abs_sum, abs( temp_lfe_dct[4 * i + 2] ) ); + lfe_abs_sum = W_add( lfe_abs_sum, L_abs( temp_lfe_dct[4 * i + 2] ) ); temp_lfe_dct[4 * i + 3] = pLfe_dct[2 * i + num_dct_pass_bins + 1]; move32(); - lfe_abs_sum = W_add( lfe_abs_sum, abs( temp_lfe_dct[4 * i + 3] ) ); + lfe_abs_sum = W_add( lfe_abs_sum, L_abs( temp_lfe_dct[4 * i + 3] ) ); } IF( LE_64( lfe_abs_sum, W_shr( IVAS_LFE_ABS_SUM_FLT_THR_Q42, sub( 42, q_pLfe_dct ) ) ) ) @@ -199,12 +197,13 @@ static void ivas_lfe_enc_quant_fx( q_lfe_abs_sum = sub( q_lfe_abs_sum, q_tmp ); } - tmp = BASOP_Util_Divide3232_Scale( max_value, W_extract_l( lfe_abs_sum ), &q_tmp ); - tmp = L_shl( tmp, sub( q_lfe_abs_sum, sub( 15, q_tmp ) ) ); /* Q0 (max_value / lfe_abs_sum) */ + tmp = L_deposit_h( BASOP_Util_Divide3232_Scale( max_value, W_extract_l( lfe_abs_sum ), &q_tmp ) ); + // tmp = L_shl( tmp, sub( q_lfe_abs_sum, sub( 15, q_tmp ) ) ); /* Q0 (max_value / lfe_abs_sum) */ + q_tmp = sub( Q16, sub( q_lfe_abs_sum, sub( 15, q_tmp ) ) ); /* log2_f(max_value / lfe_abs_sum) -> Q25 */ tmp = BASOP_Util_Log2( tmp ); - tmp = L_add( tmp, 1040187392 ) /* (31<<25) -> 1040187392 */; /* Q25 */ + tmp = L_add( tmp, L_shl( sub( Q31, q_tmp ), Q25 ) ) /* (31<<25) -> 1040187392 */; /* Q25 */ /* IVAS_LFE_SHIFTS_PER_DOUBLE * log2_f(max_value / lfe_abs_sum) */ tmp = Mpy_32_16_1( tmp, IVAS_LFE_SHIFTS_PER_DOUBLE ); /* 25-15 -> Q10 */ @@ -250,9 +249,9 @@ static void ivas_lfe_enc_quant_fx( move16(); } - IF( LT_32( max_of_vals, abs( values[i] ) ) ) + IF( LT_32( max_of_vals, abs_s( values[i] ) ) ) { - max_of_vals = (Word16) abs( values[i] ); + max_of_vals = abs_s( values[i] ); move16(); } } @@ -433,14 +432,14 @@ void ivas_lfe_enc_fx( IF( LT_16( q_data_lfe_ch, hLFE->q_old_wtda_audio ) ) { - Scale_sig32( hLFE->old_wtda_audio_fx, fade_len, sub( q_data_lfe_ch, hLFE->q_old_wtda_audio ) ); + Scale_sig32( hLFE->old_wtda_audio_fx, fade_len, sub( q_data_lfe_ch, hLFE->q_old_wtda_audio ) ); // hLFE->q_old_wtda_audio hLFE->q_old_wtda_audio = q_data_lfe_ch; move16(); } IF( GT_16( q_data_lfe_ch, hLFE->q_old_wtda_audio ) ) { - Scale_sig32( data_lfe_ch, input_frame, sub( hLFE->q_old_wtda_audio, q_data_lfe_ch ) ); + Scale_sig32( data_lfe_ch, input_frame, sub( hLFE->q_old_wtda_audio, q_data_lfe_ch ) ); // hLFE->q_old_wtda_audio; q_data_lfe_ch = hLFE->q_old_wtda_audio; move16(); } @@ -451,7 +450,7 @@ void ivas_lfe_enc_fx( q_out1 = Find_Max_Norm32( wtda_audio_fx, input_frame ); q_out1 = sub( q_out1, find_guarded_bits_fx( dct_len ) ); - Scale_sig32( wtda_audio_fx, input_frame, q_out1 ); + Scale_sig32( wtda_audio_fx, input_frame, q_out1 ); // Q10 + q_out1 q_out1 = add( q_data_lfe_ch, q_out1 ); ivas_mdct_fx( wtda_audio_fx, t_audio_fx, dct_len, &q_out1 ); @@ -464,7 +463,7 @@ void ivas_lfe_enc_fx( /* mdct */ q_out2 = Find_Max_Norm32( wtda_audio_fx, input_frame ); q_out2 = sub( q_out2, find_guarded_bits_fx( dct_len ) ); - Scale_sig32( wtda_audio_fx, input_frame, q_out2 ); + Scale_sig32( wtda_audio_fx, input_frame, q_out2 ); // Q10 + q_out2 q_out2 = add( q_data_lfe_ch, q_out2 ); ivas_mdct_fx( wtda_audio_fx, t_audio_fx, dct_len, &q_out2 ); @@ -475,22 +474,22 @@ void ivas_lfe_enc_fx( IF( GT_16( q_out1, q_out2 ) ) { - Scale_sig32( lfe_dct_fx + num_dct_pass_bins, num_dct_pass_bins, min( q_tmp2, sub( q_out1, q_out2 ) ) ); - q_out2 = add( q_out2, min( q_tmp2, sub( q_out1, q_out2 ) ) ); + Scale_sig32( lfe_dct_fx + num_dct_pass_bins, num_dct_pass_bins, s_min( q_tmp2, sub( q_out1, q_out2 ) ) ); + q_out2 = add( q_out2, s_min( q_tmp2, sub( q_out1, q_out2 ) ) ); IF( GT_16( q_out1, q_out2 ) ) { - Scale_sig32( lfe_dct_fx, num_dct_pass_bins, sub( q_out2, q_out1 ) ); + Scale_sig32( lfe_dct_fx, num_dct_pass_bins, sub( q_out2, q_out1 ) ); // q_out2 q_out1 = q_out2; move16(); } } ELSE IF( LT_16( q_out1, q_out2 ) ) { - Scale_sig32( lfe_dct_fx, num_dct_pass_bins, min( q_tmp1, sub( q_out2, q_out1 ) ) ); - q_out1 = add( q_out1, min( q_tmp1, sub( q_out2, q_out1 ) ) ); + Scale_sig32( lfe_dct_fx, num_dct_pass_bins, s_min( q_tmp1, sub( q_out2, q_out1 ) ) ); + q_out1 = add( q_out1, s_min( q_tmp1, sub( q_out2, q_out1 ) ) ); IF( LT_16( q_out1, q_out2 ) ) { - Scale_sig32( lfe_dct_fx + num_dct_pass_bins, num_dct_pass_bins, sub( q_out1, q_out2 ) ); + Scale_sig32( lfe_dct_fx + num_dct_pass_bins, num_dct_pass_bins, sub( q_out1, q_out2 ) ); // q_out1 q_out1 = q_out2; move16(); } @@ -507,7 +506,7 @@ void ivas_lfe_enc_fx( * * Create, allocate and initialize IVAS encoder LFE handle *-------------------------------------------------------------------------*/ -ivas_error ivas_create_lfe_enc( +ivas_error ivas_create_lfe_enc_fx( LFE_ENC_HANDLE *hLFE_out, /* o : IVAS LFE encoder structure */ const Word32 input_Fs /* i : input sampling rate */ ) @@ -537,12 +536,12 @@ ivas_error ivas_create_lfe_enc( * Input memory buffer: allocate and initialize *-----------------------------------------------------------------*/ - IF( ( hLFE->old_wtda_audio_fx = (Word32 *) malloc( sizeof( hLFE->old_wtda_audio_fx[0] ) * NS2SA( input_Fs, IVAS_LFE_FADE_NS ) ) ) == NULL ) + IF( ( hLFE->old_wtda_audio_fx = (Word32 *) malloc( sizeof( hLFE->old_wtda_audio_fx[0] ) * NS2SA_FX2( input_Fs, IVAS_LFE_FADE_NS ) ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LFE memory\n" ) ); } - set32_fx( hLFE->old_wtda_audio_fx, 0, NS2SA( input_Fs, IVAS_LFE_FADE_NS ) ); + set32_fx( hLFE->old_wtda_audio_fx, 0, NS2SA_FX2( input_Fs, IVAS_LFE_FADE_NS ) ); hLFE->q_old_wtda_audio = 31; move16(); @@ -575,7 +574,7 @@ ivas_error ivas_create_lfe_enc( // hLFE->lfe_enc_indices_coeffs_tbl[i][j] = // (int16_t) ceilf( log2f( (float) ( ivas_lfe_num_ele_in_coder_models[i][j] + 1 ) ) ); hLFE->lfe_enc_indices_coeffs_tbl[i][j] = - floor_log_2( add( ivas_lfe_num_ele_in_coder_models[i][j], 1 ) ); + floor_log_2( add( ivas_lfe_num_ele_in_coder_models[i][j], 1 ) ); // Q0 move16(); } } @@ -590,7 +589,7 @@ ivas_error ivas_create_lfe_enc( * * Destroy IVAS cncoder LFE handle *-------------------------------------------------------------------------*/ -void ivas_lfe_enc_close( +void ivas_lfe_enc_close_fx( LFE_ENC_HANDLE *hLFE /* i/o: LFE encoder handle */ ) { @@ -628,7 +627,7 @@ ivas_error ivas_create_lfe_lpf_enc_fx( const Word32 input_Fs /* i : input sampling rate */ ) { - const Word32 *filt_coeff; + const Word32 *filt_coeff; // 31 - filt_coeff_e const Word16 *filt_coeff_e = NULL; IF( hLfeLpf == NULL ) @@ -657,7 +656,7 @@ ivas_error ivas_create_lfe_lpf_enc_fx( * * Destroy IVAS cncoder LFE low pass filter state *-------------------------------------------------------------------------*/ -void ivas_lfe_lpf_enc_close( +void ivas_lfe_lpf_enc_close_fx( ivas_filters_process_state_t **hLfeLpf /* i/o: LFE LPF handle */ ) { @@ -681,7 +680,7 @@ void ivas_lfe_lpf_enc_close( *-------------------------------------------------------------------------*/ void ivas_lfe_lpf_enc_apply_fx( ivas_filters_process_state_t *hLfeLpf, /* i/o: LFE LPF handle */ - Word32 data_lfe_ch[], /* i/o: LFE signal */ + Word32 data_lfe_ch[], /* i/o: LFE signal Q11*/ const Word16 input_frame /* i : input frame length per channel */ ) { diff --git a/lib_enc/ivas_masa_enc.c b/lib_enc/ivas_masa_enc_fx.c similarity index 97% rename from lib_enc/ivas_masa_enc.c rename to lib_enc/ivas_masa_enc_fx.c index abf70944298a06a45d20d58667e4967a3ca28ba2..da1f836df340575c1183fad83627f59919608aae 100644 --- a/lib_enc/ivas_masa_enc.c +++ b/lib_enc/ivas_masa_enc_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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,11 +34,9 @@ #include #include "options.h" #include "ivas_cnst.h" -#include "ivas_prot.h" #include "ivas_rom_com.h" #include "ivas_stat_enc.h" #include "wmc_auto.h" -#include "prot.h" #include "prot_fx.h" #include "prot_fx_enc.h" #include "ivas_prot_fx.h" @@ -118,7 +116,7 @@ static void masa_metadata_direction_alignment_fx( MASA_ENCODER_HANDLE hMasa ); * * open and initialize MASA encoder *-----------------------------------------------------------------------*/ -ivas_error ivas_masa_enc_open( +ivas_error ivas_masa_enc_open_fx( Encoder_Struct *st_ivas /* i/o: IVAS encoder handle */ ) { @@ -154,7 +152,7 @@ ivas_error ivas_masa_enc_open( FOR( i = 0; i < hMasa->data.num_Cldfb_instances; i++ ) { - IF( NE_32( ( error = openCldfb_ivas_enc( &( hMasa->data.cldfbAnaEnc[i] ), CLDFB_ANALYSIS, hEncoderConfig->input_Fs, CLDFB_PROTOTYPE_5_00MS ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &( hMasa->data.cldfbAnaEnc[i] ), CLDFB_ANALYSIS, hEncoderConfig->input_Fs, CLDFB_PROTOTYPE_5_00MS, ENC ) ), IVAS_ERR_OK ) ) { return error; } @@ -179,16 +177,16 @@ ivas_error ivas_masa_enc_open( Copy( DirAC_block_grouping, hMasa->config.block_grouping, MAX_PARAM_SPATIAL_SUBFRAMES + 1 ); Copy( MASA_band_grouping_24, hMasa->config.band_grouping, MASA_FREQUENCY_BANDS + 1 ); - hMasa->data.onset_detector_1_fx = 0; - hMasa->data.onset_detector_2_fx = 0; + hMasa->data.onset_detector_1_fx = 0; // hMasa->data.q_onset_detector + hMasa->data.onset_detector_2_fx = 0; // hMasa->data.q_onset_detector hMasa->data.q_onset_detector = 0; move32(); move32(); move16(); - set32_fx( hMasa->data.lfeToTotalEnergyRatio_fx, 0, MAX_PARAM_SPATIAL_SUBFRAMES ); + set32_fx( hMasa->data.lfeToTotalEnergyRatio_fx, 0, MAX_PARAM_SPATIAL_SUBFRAMES ); // hMasa->data.lfeToTotalEnergyRatio_e set16_fx( hMasa->data.lfeToTotalEnergyRatio_e, 0, MAX_PARAM_SPATIAL_SUBFRAMES ); - hMasa->data.prevq_lfeToTotalEnergyRatio_fx = 0; + hMasa->data.prevq_lfeToTotalEnergyRatio_fx = 0; // Q31 move32(); hMasa->data.prevq_lfeIndex = 0; @@ -201,10 +199,10 @@ ivas_error ivas_masa_enc_open( move16(); move32(); - set_zero_fx( hMasa->data.dir_align_state.previous_azi_dir1_fx, MASA_FREQUENCY_BANDS ); - set_zero_fx( hMasa->data.dir_align_state.previous_ele_dir1_fx, MASA_FREQUENCY_BANDS ); - set_zero_fx( hMasa->data.dir_align_state.previous_azi_dir2_fx, MASA_FREQUENCY_BANDS ); - set_zero_fx( hMasa->data.dir_align_state.previous_ele_dir2_fx, MASA_FREQUENCY_BANDS ); + set_zero_fx( hMasa->data.dir_align_state.previous_azi_dir1_fx, MASA_FREQUENCY_BANDS ); // Q22 + set_zero_fx( hMasa->data.dir_align_state.previous_ele_dir1_fx, MASA_FREQUENCY_BANDS ); // Q22 + set_zero_fx( hMasa->data.dir_align_state.previous_azi_dir2_fx, MASA_FREQUENCY_BANDS ); // Q22 + set_zero_fx( hMasa->data.dir_align_state.previous_ele_dir2_fx, MASA_FREQUENCY_BANDS ); // Q22 IF( EQ_32( hEncoderConfig->ivas_format, MASA_ISM_FORMAT ) ) { @@ -217,7 +215,7 @@ ivas_error ivas_masa_enc_open( FOR( i = 0; i < MAX_PARAM_SPATIAL_SUBFRAMES; i++ ) { - set32_fx( hOmasaData->masa_to_total_energy_ratio_fx[i], 0, MASA_FREQUENCY_BANDS ); + set32_fx( hOmasaData->masa_to_total_energy_ratio_fx[i], 0, MASA_FREQUENCY_BANDS ); // Q30 } hOmasaData->lp_noise_CPE_fx = -256; /* -1 in Q8 */ @@ -227,7 +225,7 @@ ivas_error ivas_masa_enc_open( FOR( i = 0; i < MAX_PARAM_SPATIAL_SUBFRAMES; i++ ) { - set_zero_fx( hOmasaData->energy_ism_fx[i], MASA_FREQUENCY_BANDS ); + set_zero_fx( hOmasaData->energy_ism_fx[i], MASA_FREQUENCY_BANDS ); // hOmasaData->energy_ism_fx_e set16_fx( hOmasaData->energy_ism_fx_e[i], 0, MASA_FREQUENCY_BANDS ); } @@ -248,7 +246,7 @@ ivas_error ivas_masa_enc_open( * * close MASA encoder *-----------------------------------------------------------------------*/ -void ivas_masa_enc_close( +void ivas_masa_enc_close_fx( MASA_ENCODER_HANDLE *hMasa /* i/o: MASA metadata structure */ ) { @@ -262,7 +260,7 @@ void ivas_masa_enc_close( FOR( i = 0; i < ( *hMasa )->data.num_Cldfb_instances; i++ ) { - deleteCldfb_ivas( &( ( *hMasa )->data.cldfbAnaEnc[i] ) ); + deleteCldfb_ivas_fx( &( ( *hMasa )->data.cldfbAnaEnc[i] ) ); } IF( ( *hMasa )->data.hOmasaData != NULL ) @@ -322,7 +320,6 @@ ivas_error ivas_masa_encode_fx( IF( EQ_32( ivas_format, MASA_FORMAT ) || EQ_32( ivas_format, MASA_ISM_FORMAT ) ) { /* Create the MASA SID descriptor for the metadata and CPE mode, in order to have the SID frame self-contained. */ - test(); IF( Opt_DTX_ON && hQMetaData != NULL ) { IF( EQ_16( nchan_transport, 2 ) ) /* this is MASA format in CPE only */ @@ -351,9 +348,9 @@ ivas_error ivas_masa_encode_fx( { FOR( j = 0; j < MAX_PARAM_SPATIAL_SUBFRAMES; j++ ) { - Copy32( hMasa->masaMetadata.directional_meta[i].azimuth_fx[j], h_orig_metadata[i].azimuth_fx[j], MASA_FREQUENCY_BANDS ); - Copy32( hMasa->masaMetadata.directional_meta[i].elevation_fx[j], h_orig_metadata[i].elevation_fx[j], MASA_FREQUENCY_BANDS ); - Copy32( hMasa->masaMetadata.directional_meta[i].energy_ratio_fx[j], h_orig_metadata[i].energy_ratio_fx[j], MASA_FREQUENCY_BANDS ); + Copy32( hMasa->masaMetadata.directional_meta[i].azimuth_fx[j], h_orig_metadata[i].azimuth_fx[j], MASA_FREQUENCY_BANDS ); // Q22 + Copy32( hMasa->masaMetadata.directional_meta[i].elevation_fx[j], h_orig_metadata[i].elevation_fx[j], MASA_FREQUENCY_BANDS ); // Q22 + Copy32( hMasa->masaMetadata.directional_meta[i].energy_ratio_fx[j], h_orig_metadata[i].energy_ratio_fx[j], MASA_FREQUENCY_BANDS ); // Q30 Copy( (Word16 *) ( hMasa->masaMetadata.directional_meta[i].spherical_index[j] ), (Word16 *) ( h_orig_metadata[i].spherical_index[j] ), MASA_FREQUENCY_BANDS ); } } @@ -384,7 +381,7 @@ ivas_error ivas_masa_encode_fx( { FOR( j = 0; j < MASA_FREQUENCY_BANDS; j++ ) { - hMasa->data.energy_fx[i][j] = L_shr( hMasa->data.energy_fx[i][j], sub( s, hMasa->data.energy_e[i][j] ) ); + hMasa->data.energy_fx[i][j] = L_shr( hMasa->data.energy_fx[i][j], sub( s, hMasa->data.energy_e[i][j] ) ); // hMasa->data.energy_e[i][j] -> s hMasa->data.energy_e[i][j] = s; move32(); move16(); @@ -700,9 +697,9 @@ ivas_error ivas_masa_encode_fx( { FOR( j = 0; j < MAX_PARAM_SPATIAL_SUBFRAMES; j++ ) { - Copy32( h_orig_metadata[i].azimuth_fx[j], hMasa->masaMetadata.directional_meta[i].azimuth_fx[j], MASA_FREQUENCY_BANDS ); - Copy32( h_orig_metadata[i].elevation_fx[j], hMasa->masaMetadata.directional_meta[i].elevation_fx[j], MASA_FREQUENCY_BANDS ); - Copy32( h_orig_metadata[i].energy_ratio_fx[j], hMasa->masaMetadata.directional_meta[i].energy_ratio_fx[j], MASA_FREQUENCY_BANDS ); + Copy32( h_orig_metadata[i].azimuth_fx[j], hMasa->masaMetadata.directional_meta[i].azimuth_fx[j], MASA_FREQUENCY_BANDS ); // Q22 + Copy32( h_orig_metadata[i].elevation_fx[j], hMasa->masaMetadata.directional_meta[i].elevation_fx[j], MASA_FREQUENCY_BANDS ); // Q22 + Copy32( h_orig_metadata[i].energy_ratio_fx[j], hMasa->masaMetadata.directional_meta[i].energy_ratio_fx[j], MASA_FREQUENCY_BANDS ); // Q30 } } @@ -815,6 +812,9 @@ void ivas_masa_estimate_energy_fx( { q_buf = q_data; move16(); + scale_sig32( hMasa->data.cldfbAnaEnc[i]->cldfb_state_fx, hMasa->data.cldfbAnaEnc[i]->cldfb_state_length, sub( q_buf, hMasa->data.cldfbAnaEnc[i]->Q_cldfb_state ) ); + hMasa->data.cldfbAnaEnc[i]->Q_cldfb_state = q_buf; + move16(); cldfbAnalysis_ts_fx_fixed_q( &( data_fx[i][l_ts * ts] ), Input_RealBuffer[i], Input_ImagBuffer[i], l_ts, hMasa->data.cldfbAnaEnc[i], &q_buf ); // (q_data - 5) for Input_RealBuffer[i], Input_ImagBuffer[i] } @@ -1105,7 +1105,7 @@ ivas_error ivas_masa_enc_config_fx( maxBand = 0; move16(); test(); - WHILE( LE_16( maxBand, MASA_FREQUENCY_BANDS ) && LE_16( MASA_band_grouping_24[maxBand], maxBin ) ) + WHILE( ( maxBand <= MASA_FREQUENCY_BANDS ) && ( MASA_band_grouping_24[maxBand] <= maxBin ) ) { test(); maxBand = (UWord8) add( maxBand, 1 ); @@ -1131,7 +1131,7 @@ ivas_error ivas_masa_enc_config_fx( continueLoop = 1; move16(); test(); - WHILE( GT_16( maxBand, 5 ) && continueLoop ) + WHILE( ( maxBand > 5 ) && continueLoop ) { test(); FOR( sf = 0; sf < MAX_PARAM_SPATIAL_SUBFRAMES; sf++ ) @@ -1203,7 +1203,8 @@ ivas_error ivas_masa_enc_config_fx( } ELSE { - st_ivas->hMasa->data.hOmasaData->lp_noise_CPE_fx = shr( add( st_ivas->hCPE[0]->hCoreCoder[0]->lp_noise_fx, st_ivas->hCPE[0]->hCoreCoder[1]->lp_noise_fx ), 1 ); /*Q8*/ + /* ( st_ivas->hCPE[0]->hCoreCoder[0]->lp_noise + st_ivas->hCPE[0]->hCoreCoder[1]->lp_noise ) / CPE_CHANNELS; */ + st_ivas->hMasa->data.hOmasaData->lp_noise_CPE_fx = extract_h( L_mac( L_mult( st_ivas->hCPE[0]->hCoreCoder[0]->lp_noise_fx, ONE_IN_Q14 ), st_ivas->hCPE[0]->hCoreCoder[1]->lp_noise_fx, ONE_IN_Q14 ) ); /*Q8*/ } move16(); } @@ -1519,7 +1520,7 @@ static void combine_freqbands_and_subframes_fx( } } - if ( i == 0 ) + IF( i == 0 ) { energy[j][k] = energySum; // 31-energySum_e energy_e[j][k] = energySum_e; @@ -1887,7 +1888,7 @@ void ivas_masa_combine_directions_fx( } static void find_n_largest_fx( - const Word32 *input_fx, + const Word32 *input_fx, // Q(31 - exp_input) Word16 exp_input, Word16 *largestIndices, const Word16 numElements, @@ -1900,13 +1901,13 @@ static void find_n_largest_fx( FOR( j = 0; j < numElements; j++ ) { - values[j] = input_fx[j]; + values[j] = input_fx[j]; // Q(31 - exp_input) move32(); } FOR( i = 0; i < numLargest; i++ ) { - largestValue = values[0]; + largestValue = values[0]; // Q(31 - exp_input) move32(); largestIndex = 0; move16(); @@ -1914,7 +1915,7 @@ static void find_n_largest_fx( { IF( GT_32( values[j], largestValue ) ) { - largestValue = values[j]; + largestValue = values[j]; // Q(31 - exp_input) largestIndex = j; move32(); move16(); @@ -1924,12 +1925,12 @@ static void find_n_largest_fx( move16(); IF( exp_input != 0 ) { - values[largestIndex] = L_negate( 1 << ( sub( 31, exp_input ) ) ); + values[largestIndex] = L_negate( 1 << ( sub( 31, exp_input ) ) ); // Q(31 - exp_input) move32(); } ELSE { - values[largestIndex] = 1 << ( sub( 31, exp_input ) ); + values[largestIndex] = 1 << ( sub( 31, exp_input ) ); // Q(31 - exp_input) move32(); } } @@ -1966,9 +1967,9 @@ static void move_metadata_to_qmetadata_fx( { FOR( band = 0; band < numCodingBands; band++ ) { - hQMeta->q_direction[dir].band_data[band].azimuth_fx[sf] = hMeta->directional_meta[dir].azimuth_fx[sf][band]; - hQMeta->q_direction[dir].band_data[band].elevation_fx[sf] = hMeta->directional_meta[dir].elevation_fx[sf][band]; - hQMeta->q_direction[dir].band_data[band].energy_ratio_fx[sf] = hMeta->directional_meta[dir].energy_ratio_fx[sf][band]; + hQMeta->q_direction[dir].band_data[band].azimuth_fx[sf] = hMeta->directional_meta[dir].azimuth_fx[sf][band]; // Q22 + hQMeta->q_direction[dir].band_data[band].elevation_fx[sf] = hMeta->directional_meta[dir].elevation_fx[sf][band]; // Q22 + hQMeta->q_direction[dir].band_data[band].energy_ratio_fx[sf] = hMeta->directional_meta[dir].energy_ratio_fx[sf][band]; // Q30 hQMeta->q_direction[dir].band_data[band].spherical_index[sf] = hMeta->directional_meta[dir].spherical_index[sf][band]; move32(); move32(); @@ -1977,7 +1978,7 @@ static void move_metadata_to_qmetadata_fx( IF( hQMeta->q_direction[dir].coherence_band_data != NULL ) { - hQMeta->q_direction[dir].coherence_band_data[band].spread_coherence[sf] = (UWord8) mult_r( hMeta->directional_meta[dir].spread_coherence_fx[sf][band], UINT8_MAX ); + hQMeta->q_direction[dir].coherence_band_data[band].spread_coherence[sf] = (UWord8) mult_r( hMeta->directional_meta[dir].spread_coherence_fx[sf][band], UINT8_MAX ); // Q15 move16(); } } @@ -1990,7 +1991,7 @@ static void move_metadata_to_qmetadata_fx( { IF( hQMeta->surcoh_band_data != NULL ) { - hQMeta->surcoh_band_data[band].surround_coherence[sf] = (UWord8) mult_r( hMeta->common_meta.surround_coherence_fx[sf][band], UINT8_MAX ); + hQMeta->surcoh_band_data[band].surround_coherence[sf] = (UWord8) mult_r( hMeta->common_meta.surround_coherence_fx[sf][band], UINT8_MAX ); // Q15 move16(); } } @@ -2072,12 +2073,12 @@ static void detect_metadata_composition_fx( { sf = 0; move16(); - WHILE( !dirValid[dir] && LT_16( sf, MAX_PARAM_SPATIAL_SUBFRAMES ) ) + WHILE( !dirValid[dir] && ( sf < MAX_PARAM_SPATIAL_SUBFRAMES ) ) { test(); band = 0; move16(); - WHILE( !dirValid[dir] && LT_16( band, MASA_FREQUENCY_BANDS ) ) + WHILE( !dirValid[dir] && ( band < MASA_FREQUENCY_BANDS ) ) { test(); IF( GE_32( hMeta->directional_meta[dir].energy_ratio_fx[sf][band] /*q30*/, MASA_RATIO_THRESHOLD_FX >> 1 /*q30*/ ) ) @@ -2119,7 +2120,7 @@ static void detect_metadata_composition_fx( } } - IF( *isTwoDir == FALSE ) + if ( *isTwoDir == FALSE ) { /* Further checks will be done with just one direction */ numDir = 1; @@ -2132,9 +2133,10 @@ static void detect_metadata_composition_fx( sf = 1; move16(); move16(); - WHILE( EQ_16( sfSimilar, TRUE ) && LT_16( sf, MAX_PARAM_SPATIAL_SUBFRAMES ) ) + + test(); + WHILE( ( sfSimilar == TRUE ) && ( sf < MAX_PARAM_SPATIAL_SUBFRAMES ) ) { - test(); sfSimilar = are_masa_subframes_similar_fx( hMeta, 0, hMeta, sf ); sf = (Word8) add( sf, 1 ); move16(); @@ -2155,19 +2157,19 @@ static void detect_metadata_composition_fx( /* Check spread coherence */ dir = 0; move16(); - WHILE( cohPresent == FALSE && LT_16( dir, numDir ) ) + test(); + WHILE( cohPresent == FALSE && ( dir < numDir ) ) { - test(); sf = 0; move16(); - WHILE( cohPresent == FALSE && LT_16( sf, nSubFrames ) ) + test(); + WHILE( cohPresent == FALSE && ( sf < nSubFrames ) ) { - test(); band = 0; move16(); - WHILE( cohPresent == FALSE /*has value zero*/ && LT_16( band, MASA_FREQUENCY_BANDS ) ) + test(); + WHILE( cohPresent == FALSE /*has value zero*/ && ( band < MASA_FREQUENCY_BANDS ) ) { - test(); /* Check coherences for presence of coherence */ IF( GT_16( hMeta->directional_meta[dir].spread_coherence_fx[sf][band] /*Q15*/, MASA_COHERENCE_THRESHOLD_FX >> 16 ) ) /*Q15*/ { @@ -2360,7 +2362,16 @@ static void reduce_metadata_further_fx( } } - tmp2 = W_norm( W_tmp ); + IF( W_tmp != 0 ) + { + tmp2 = sub( W_norm( W_tmp ), 1 ); // Usage of guard bits to avoid the large values of onset_detector in multiplication + } + ELSE + { + tmp2 = 0; + move16(); + } + tmp2 = s_min( 32, tmp2 ); totalEnergySum = W_extract_h( W_shl( W_tmp, tmp2 ) ); tmp2 = sub( tmp2, 32 ); @@ -2496,6 +2507,8 @@ static void reduce_metadata_further_fx( Word32 x, y, z; Word32 veclen, L_tmp; + W_tmp = 0; + move64(); FOR( band = 0; band < numCodingBands; band++ ) { xSum = 0; @@ -2524,9 +2537,14 @@ static void reduce_metadata_further_fx( ySum = L_add( ySum, y ); zSum = L_add( zSum, z ); - bandSumEnergy = L_add( bandSumEnergy, energy[sf][band] ); + W_tmp = W_add( W_tmp, energy[sf][band] ); } + tmp2 = W_norm( W_tmp ); + tmp2 = s_min( 32, tmp2 ); + bandSumEnergy = W_extract_h( W_shl( W_tmp, tmp2 ) ); + tmp2 = sub( add( hMasa->data.q_energy, tmp2 ), 32 ); + aziRad = BASOP_util_atan2( ySum, xSum, 0 ); // Q13 W_xSum_sq = W_mult0_32_32( xSum, xSum ); // 2 * hMasa->data.q_energy - Q6 W_ySum_sq = W_mult0_32_32( ySum, ySum ); // 2 * hMasa->data.q_energy - Q6 @@ -2554,6 +2572,7 @@ static void reduce_metadata_further_fx( } // hqmetadata->q_direction[0].coherence_band_data[band].spread_coherence[0] = (uint8_t) roundf( spreadCohSum / ( bandSumEnergy + EPSILON ) * 255.0f ); tmp = BASOP_Util_Divide3232_Scale( spreadCohSum, bandSumEnergy, &exp ); + exp = add( exp, sub( tmp2, hMasa->data.q_energy ) ); tmp = mult_r( tmp, 32640 /* 255 in Q7 */ ); // 15 - exp + 7 - 15 => 7 - exp hqmetadata->q_direction[0].coherence_band_data[band].spread_coherence[0] = (UWord8) shr( tmp, sub( 7, exp ) ); // Q0 move16(); @@ -2563,7 +2582,7 @@ static void reduce_metadata_further_fx( { FOR( band = 0; band < numCodingBands; band++ ) { - hqmetadata->q_direction[0].coherence_band_data[band].spread_coherence[sf] = hqmetadata->q_direction[0].coherence_band_data[band].spread_coherence[0]; + hqmetadata->q_direction[0].coherence_band_data[band].spread_coherence[sf] = hqmetadata->q_direction[0].coherence_band_data[band].spread_coherence[0]; // Q0 move16(); } } @@ -2582,18 +2601,18 @@ static void reduce_metadata_further_fx( /* Use the selected frequency band to represent all data */ FOR( sf = 0; sf < MAX_PARAM_SPATIAL_SUBFRAMES; sf++ ) { - hqmetadata->q_direction[0].band_data[0].azimuth_fx[sf] = hqmetadata->q_direction[0].band_data[selectedBand].azimuth_fx[sf]; - hqmetadata->q_direction[0].band_data[0].elevation_fx[sf] = hqmetadata->q_direction[0].band_data[selectedBand].elevation_fx[sf]; - hqmetadata->q_direction[0].band_data[0].energy_ratio_fx[sf] = hqmetadata->q_direction[0].band_data[selectedBand].energy_ratio_fx[sf]; + hqmetadata->q_direction[0].band_data[0].azimuth_fx[sf] = hqmetadata->q_direction[0].band_data[selectedBand].azimuth_fx[sf]; // Q22 + hqmetadata->q_direction[0].band_data[0].elevation_fx[sf] = hqmetadata->q_direction[0].band_data[selectedBand].elevation_fx[sf]; // Q22 + hqmetadata->q_direction[0].band_data[0].energy_ratio_fx[sf] = hqmetadata->q_direction[0].band_data[selectedBand].energy_ratio_fx[sf]; // Q30 move32(); move32(); move32(); - if ( hqmetadata->q_direction[0].coherence_band_data != NULL ) + IF( hqmetadata->q_direction[0].coherence_band_data != NULL ) { - hqmetadata->q_direction[0].coherence_band_data[0].spread_coherence[sf] = hqmetadata->q_direction[0].coherence_band_data[selectedBand].spread_coherence[sf]; + hqmetadata->q_direction[0].coherence_band_data[0].spread_coherence[sf] = hqmetadata->q_direction[0].coherence_band_data[selectedBand].spread_coherence[sf]; // Q0 move16(); } - if ( hqmetadata->surcoh_band_data != NULL ) + IF( hqmetadata->surcoh_band_data != NULL ) { hqmetadata->surcoh_band_data[0].surround_coherence[sf] = hqmetadata->surcoh_band_data[selectedBand].surround_coherence[sf]; move16(); @@ -2607,7 +2626,7 @@ static void reduce_metadata_further_fx( { FOR( sf = 0; sf < MAX_PARAM_SPATIAL_SUBFRAMES; sf++ ) { - hqmetadata->q_direction[0].coherence_band_data[band].spread_coherence[sf] = hqmetadata->q_direction[0].coherence_band_data[0].spread_coherence[sf]; + hqmetadata->q_direction[0].coherence_band_data[band].spread_coherence[sf] = hqmetadata->q_direction[0].coherence_band_data[0].spread_coherence[sf]; // Q0 move16(); } } @@ -2657,7 +2676,7 @@ static Word16 encode_lfe_to_total_energy_ratio_fx( move16(); /* Determine maximum amount of LFE energy in any subframe */ - maxLFESubFrameEner = 0; + maxLFESubFrameEner = 0; // maxLFESubFrameEner_e move32(); maxLFESubFrameEner_e = 0; move16(); @@ -2665,7 +2684,7 @@ static Word16 encode_lfe_to_total_energy_ratio_fx( { IF( BASOP_Util_Cmp_Mant32Exp( hMasa->data.lfeToTotalEnergyRatio_fx[i], hMasa->data.lfeToTotalEnergyRatio_e[i], maxLFESubFrameEner, maxLFESubFrameEner_e ) > 0 ) { - maxLFESubFrameEner = hMasa->data.lfeToTotalEnergyRatio_fx[i]; + maxLFESubFrameEner = hMasa->data.lfeToTotalEnergyRatio_fx[i]; // hMasa->data.lfeToTotalEnergyRatio_e[i] move32(); maxLFESubFrameEner_e = hMasa->data.lfeToTotalEnergyRatio_e[i]; move16(); @@ -2897,7 +2916,7 @@ void ivas_masa_enc_reconfigure_fx( st_ivas->hCPE[cpe_id]->element_brate = imult3216( tmp_br, 2 ); //( ivas_total_brate / st_ivas->nchan_transport ) * CPE_CHANNELS; move32(); - IF( st_ivas->nCPE > 1 ) + IF( GT_16( st_ivas->nCPE, 1 ) ) { tmp = 1; } @@ -2939,7 +2958,7 @@ void ivas_masa_enc_reconfigure_fx( *-------------------------------------------------------------------*/ static void average_masa_metadata_fx( MASA_METADATA_FRAME *hMeta, - Word32 energy[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], /*i*/ + Word32 energy[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], /*i Q(31 - energy_e) */ Word16 energy_e[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], /*i:stores exponent values for energy_e*/ const SPHERICAL_GRID_DATA *Sph_Grid16, const UWord8 useSphGrid ) @@ -3111,16 +3130,16 @@ static void copy_masa_metadata_subframe_fx( /* directional metadata */ FOR( dir = 0; dir < MASA_MAXIMUM_DIRECTIONS; dir++ ) { - Copy32( hMetaFrom->directional_meta[dir].azimuth_fx[sfFrom], hMetaTo->directional_meta[dir].azimuth_fx[sfTo], MASA_FREQUENCY_BANDS ); - Copy32( hMetaFrom->directional_meta[dir].elevation_fx[sfFrom], hMetaTo->directional_meta[dir].elevation_fx[sfTo], MASA_FREQUENCY_BANDS ); - Copy32( hMetaFrom->directional_meta[dir].energy_ratio_fx[sfFrom], hMetaTo->directional_meta[dir].energy_ratio_fx[sfTo], MASA_FREQUENCY_BANDS ); - Copy( hMetaFrom->directional_meta[dir].spread_coherence_fx[sfFrom], hMetaTo->directional_meta[dir].spread_coherence_fx[sfTo], MASA_FREQUENCY_BANDS ); + Copy32( hMetaFrom->directional_meta[dir].azimuth_fx[sfFrom], hMetaTo->directional_meta[dir].azimuth_fx[sfTo], MASA_FREQUENCY_BANDS ); // Q22 + Copy32( hMetaFrom->directional_meta[dir].elevation_fx[sfFrom], hMetaTo->directional_meta[dir].elevation_fx[sfTo], MASA_FREQUENCY_BANDS ); // Q22 + Copy32( hMetaFrom->directional_meta[dir].energy_ratio_fx[sfFrom], hMetaTo->directional_meta[dir].energy_ratio_fx[sfTo], MASA_FREQUENCY_BANDS ); // Q30 + Copy( hMetaFrom->directional_meta[dir].spread_coherence_fx[sfFrom], hMetaTo->directional_meta[dir].spread_coherence_fx[sfTo], MASA_FREQUENCY_BANDS ); // Q15 } /* common metadata */ - Copy32( hMetaFrom->common_meta.diffuse_to_total_ratio_fx[sfFrom], hMetaTo->common_meta.diffuse_to_total_ratio_fx[sfTo], MASA_FREQUENCY_BANDS ); - Copy( hMetaFrom->common_meta.surround_coherence_fx[sfFrom], hMetaTo->common_meta.surround_coherence_fx[sfTo], MASA_FREQUENCY_BANDS ); - Copy32( hMetaFrom->common_meta.remainder_to_total_ratio_fx[sfFrom], hMetaTo->common_meta.remainder_to_total_ratio_fx[sfTo], MASA_FREQUENCY_BANDS ); + Copy32( hMetaFrom->common_meta.diffuse_to_total_ratio_fx[sfFrom], hMetaTo->common_meta.diffuse_to_total_ratio_fx[sfTo], MASA_FREQUENCY_BANDS ); // Q30 + Copy( hMetaFrom->common_meta.surround_coherence_fx[sfFrom], hMetaTo->common_meta.surround_coherence_fx[sfTo], MASA_FREQUENCY_BANDS ); // Q15 + Copy32( hMetaFrom->common_meta.remainder_to_total_ratio_fx[sfFrom], hMetaTo->common_meta.remainder_to_total_ratio_fx[sfTo], MASA_FREQUENCY_BANDS ); // Q30 return; } @@ -3209,18 +3228,18 @@ static UWord8 are_masa_subframes_similar_fx( move16(); move16(); - WHILE( EQ_16( sf_differ, FALSE ) && LE_16( dir, num_dir ) ) + WHILE( ( sf_differ == FALSE ) && ( dir <= num_dir ) ) { test(); band_idx = 0; move16(); - WHILE( EQ_16( sf_differ, FALSE ) && LT_16( band_idx, MASA_FREQUENCY_BANDS ) ) + WHILE( ( sf_differ == FALSE ) && ( band_idx < MASA_FREQUENCY_BANDS ) ) { test(); Word32 azi_dif_fx; - azi_dif_fx = L_abs( L_sub( frame1->directional_meta[dir].azimuth_fx[sf1_idx][band_idx], frame2->directional_meta[dir].azimuth_fx[sf2_idx][band_idx] ) ); + azi_dif_fx = L_abs( L_sub( frame1->directional_meta[dir].azimuth_fx[sf1_idx][band_idx], frame2->directional_meta[dir].azimuth_fx[sf2_idx][band_idx] ) ); // Q22 IF( GT_32( azi_dif_fx, 180 << Q22 ) ) - azi_dif_fx = L_sub( 360 << Q22, azi_dif_fx ); + azi_dif_fx = L_sub( 360 << Q22, azi_dif_fx ); // Q22 IF( GT_32( azi_dif_fx, ONE_IN_Q21 /*0.5 in Q22*/ ) ) { @@ -3258,7 +3277,7 @@ static UWord8 are_masa_subframes_similar_fx( } /* check the common metadata */ - WHILE( EQ_16( sf_differ, FALSE ) && LT_16( band_idx, MASA_FREQUENCY_BANDS ) ) + WHILE( ( sf_differ == FALSE ) && ( band_idx < MASA_FREQUENCY_BANDS ) ) { test(); IF( GT_32( L_abs( L_sub( frame1->common_meta.surround_coherence_fx[sf1_idx][band_idx], frame2->common_meta.surround_coherence_fx[sf2_idx][band_idx] ) ), MASA_COHERENCE_TOLERANCE_FX ) ) @@ -3770,19 +3789,19 @@ void ivas_merge_masa_metadata_fx( move16(); IF( EQ_16( band_n_dirs, 2 ) ) { - energyTimesRatioMASA_fx[1] = Mpy_32_32( eneBand_fx, hMeta->directional_meta[1].energy_ratio_fx[sf][band] ); + energyTimesRatioMASA_fx[1] = Mpy_32_32( eneBand_fx, hMeta->directional_meta[1].energy_ratio_fx[sf][band] ); // energyTimesRatioMASA_e energyTimesRatioMASA_e[1] = add( eneBand_e, 1 ); } ELSE { - energyTimesRatioMASA_fx[1] = 0; + energyTimesRatioMASA_fx[1] = 0; // energyTimesRatioMASA_e energyTimesRatioMASA_e[1] = 0; } move32(); move16(); /* target is original MASA diffuseness */ - total_diff_nrg_fx = Mpy_32_32( eneBand_fx, hMeta->common_meta.diffuse_to_total_ratio_fx[sf][band] ); + total_diff_nrg_fx = Mpy_32_32( eneBand_fx, hMeta->common_meta.diffuse_to_total_ratio_fx[sf][band] ); // total_diff_nrg_e total_diff_nrg_e = add( eneBand_e, 1 ); /* criterion is mean of ISM ratio and new ratio */ @@ -3842,6 +3861,7 @@ void ivas_merge_masa_metadata_fx( ELSE { hMeta->directional_meta[merge_dest].energy_ratio_fx[sf][band] = hOMasaMeta->directional_meta[0].energy_ratio_fx[sf][band]; /*q30*/ + move32(); } /* clip with original ISM dir */ hMeta->common_meta.diffuse_to_total_ratio_fx[sf][band] = L_sub( ONE_IN_Q30, hMeta->directional_meta[merge_dest].energy_ratio_fx[sf][band] ); /*q30*/ @@ -3920,7 +3940,7 @@ static void quantize_ratio_ism_vector_ivas_fx( IF( tmp < 0 ) { /* take it out from quantize function */ - Copy( ratio_ism, ratio_ism_loc, idx_sep_object ); + Copy( ratio_ism, ratio_ism_loc, idx_sep_object ); // Q(15 - ratio_ism_e) Copy( &ratio_ism[idx_sep_object + 1], &ratio_ism_loc[idx_sep_object], nchan_ism - idx_sep_object - 1 ); no_ism_loc = sub( nchan_ism, 1 ); } @@ -3980,7 +4000,7 @@ static void quantize_ratio_ism_vector_ivas_fx( move16(); move16(); - WHILE( LT_16( part_idx_sum, max_sum_idx ) ) + WHILE( ( part_idx_sum < max_sum_idx ) ) { best_i = -1; move16(); @@ -4162,7 +4182,7 @@ static void transform_index_and_GR_encode_ivas_fx( /* GR encoding */ FOR( i = 0; i < len; i++ ) { - ivas_qmetadata_encode_extended_gr( hMetaData, idx[i], 100, GR_order ); + ivas_qmetadata_encode_extended_gr_fx( hMetaData, idx[i], 100, GR_order ); } return; @@ -4183,7 +4203,7 @@ static Word16 try_differential_fx( b_signif = 0; move16(); - WHILE( LT_16( b_signif, numCodingBands ) && GE_32( masa_to_total_energy_ratio[b_signif], MASA2TOTAL_THR_Q30 ) ) + WHILE( ( b_signif < numCodingBands ) && ( masa_to_total_energy_ratio[b_signif] >= MASA2TOTAL_THR_Q30 ) ) { test(); b_signif = add( b_signif, 1 ); @@ -4211,7 +4231,7 @@ static Word16 try_differential_fx( /* GR encoding */ FOR( i = 0; i < nchan_ism - 1; i++ ) { - nbits0 = add( nbits0, ivas_qmetadata_encode_extended_gr_length( diff_idx[i], 100, 0 ) ); + nbits0 = add( nbits0, ivas_qmetadata_encode_extended_gr_length_fx( diff_idx[i], 100, 0 ) ); } } } @@ -4332,8 +4352,8 @@ static void estimate_bits_subband_ism_ratio_fx( /* GR encoding */ FOR( i = 0; i < nchan_ism - 1 - shift_one; i++ ) { - nbits0 = add( nbits0, ivas_qmetadata_encode_extended_gr_length( diff_idx[i], 100, 0 ) ); - nbits1 = add( nbits1, ivas_qmetadata_encode_extended_gr_length( diff_idx[i], 100, 1 ) ); + nbits0 = add( nbits0, ivas_qmetadata_encode_extended_gr_length_fx( diff_idx[i], 100, 0 ) ); + nbits1 = add( nbits1, ivas_qmetadata_encode_extended_gr_length_fx( diff_idx[i], 100, 1 ) ); } *p_nbits0 = nbits0; @@ -4471,7 +4491,7 @@ static Word16 encode_ratio_ism_subframe_fx( move16(); move16(); move16(); - WHILE( LT_16( b_signif, numCodingBands ) && GE_32( masa_to_total_energy_ratio[b_signif], MASA2TOTAL_THR_Q30 ) ) + WHILE( ( b_signif < numCodingBands ) && ( masa_to_total_energy_ratio[b_signif] >= MASA2TOTAL_THR_Q30 ) ) { test(); b_signif = add( b_signif, 1 ); @@ -4735,8 +4755,8 @@ static void ivas_encode_masaism_metadata_fx( { FOR( band = 0; band < nbands_work; band++ ) { - energy_ism = 0; /* ISM energy for current subband */ - energy_ism_e = 0; /* ISM energy for current subband */ + energy_ism = 0; /* ISM energy for current subband */ // energy_ism_e + energy_ism_e = 0; /* ISM energy for current subband */ move32(); move16(); FOR( obj = 0; obj < nchan_ism; obj++ ) diff --git a/lib_enc/ivas_mc_param_enc.c b/lib_enc/ivas_mc_param_enc_fx.c similarity index 95% rename from lib_enc/ivas_mc_param_enc.c rename to lib_enc/ivas_mc_param_enc_fx.c index 26a81c1330a574838d052a3e393cbe2297d5564d..17fefec7e780e2ed1ed4ae6b23bbc0d0dc06e6c9 100644 --- a/lib_enc/ivas_mc_param_enc.c +++ b/lib_enc/ivas_mc_param_enc_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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,28 +37,25 @@ #include "rom_enc.h" #include "ivas_rom_enc.h" #include "rom_com.h" -#include "prot.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "ivas_prot_fx.h" #include "ivas_cnst.h" #include "ivas_rom_com.h" #include "wmc_auto.h" #include "prot_fx_enc.h" -#include "prot_fx.h" /*------------------------------------------------------------------------- * Local function prototypes *------------------------------------------------------------------------*/ -static void ivas_param_mc_write_bs( const PARAM_MC_ENC_HANDLE hParamMC, int16_t *ILD_idx, int16_t *ICC_idx, uint16_t bit_buffer[PARAM_MC_MAX_BITS], int16_t *bit_pos ); +static void ivas_param_mc_write_bs_fx( const PARAM_MC_ENC_HANDLE hParamMC, Word16 *ILD_idx, Word16 *ICC_idx, UWord16 bit_buffer[PARAM_MC_MAX_BITS], Word16 *bit_pos ); -static void ivas_param_mc_dec2bin( const int16_t val, const int16_t N, uint16_t bits[PARAM_MC_MAX_BITS] ); +static void ivas_param_mc_dec2bin_fx( const Word16 val, const Word16 N, UWord16 bits[PARAM_MC_MAX_BITS] ); -static void ivas_param_mc_encode_parameter( int16_t *idx_in, HANDLE_IVAS_PARAM_MC_METADATA hMetadataPMC, HANDLE_PARAM_MC_PARAMETER_CODING_INFO hParameterCodingInfo, const int16_t nbands, const int16_t band_step, const int16_t map_size_wo_lfe, const int16_t map_size, uint16_t bit_buffer[PARAM_MC_MAX_BITS], int16_t *bit_pos ); +static void ivas_param_mc_encode_parameter_fx( Word16 *idx_in, HANDLE_IVAS_PARAM_MC_METADATA hMetadataPMC, HANDLE_PARAM_MC_PARAMETER_CODING_INFO hParameterCodingInfo, const Word16 nbands, const Word16 band_step, const Word16 map_size_wo_lfe, const Word16 map_size, UWord16 bit_buffer[PARAM_MC_MAX_BITS], Word16 *bit_pos ); -static void ivas_param_mc_range_encoder( const int16_t *seq_in, const int16_t num_symbols, const uint16_t *cum_freq, const uint16_t *sym_freq, const uint16_t tot_shift, const int16_t max_nb_bits, uint16_t *bit_buffer, int16_t *bit_pos ); +static void ivas_param_mc_range_encoder_fx( const Word16 *seq_in, const Word16 num_symbols, const UWord16 *cum_freq, const UWord16 *sym_freq, const UWord16 tot_shift, const Word16 max_nb_bits, UWord16 *bit_buffer, Word16 *bit_pos ); #define ATTACKTHRESHOLD_E 4 @@ -147,7 +144,7 @@ ivas_error ivas_param_mc_enc_open_fx( } /* get dmx factors */ - hParamMC->dmx_factors_fx = ivas_param_mc_conf[config_index].dmx_fac_fx; + hParamMC->dmx_factors_fx = ivas_param_mc_conf[config_index].dmx_fac_fx; // Q31 /* set FB config. */ IF( NE_32( ( error = ivas_fb_set_cfg( &fb_cfg, MC_FORMAT, nchan_inp, 0, 0, input_Fs, 0 ) ), IVAS_ERR_OK ) ) @@ -216,12 +213,12 @@ ivas_error ivas_param_mc_enc_open_fx( move16(); /* Init total/dmx ener factors */ - set32_fx( hParamMC->ener_fac_fx, 0, PARAM_MC_MAX_PARAMETER_BANDS ); + set32_fx( hParamMC->ener_fac_fx, 0, PARAM_MC_MAX_PARAMETER_BANDS ); // Q21 /* init previous ILDs */ FOR( i = 0; i < PARAM_MC_MAX_PARAMETER_BANDS; i++ ) { - set32_fx( hParamMC->prev_ilds_fx[i], 0, PARAM_MC_SZ_ILD_MAP ); + set32_fx( hParamMC->prev_ilds_fx[i], 0, PARAM_MC_SZ_ILD_MAP ); // Q21 } st_ivas->hParamMC = hParamMC; @@ -292,7 +289,7 @@ ivas_error ivas_param_mc_enc_reconfig_fx( } /* get dmx factors */ - hParamMC->dmx_factors_fx = ivas_param_mc_conf[config_index].dmx_fac_fx; + hParamMC->dmx_factors_fx = ivas_param_mc_conf[config_index].dmx_fac_fx; // Q31 /* open/init parameter coding */ ivas_param_mc_metadata_open_fx( mc_input_setup, ivas_total_brate, &hParamMC->hMetadataPMC ); @@ -349,7 +346,7 @@ ivas_error ivas_param_mc_enc_reconfig_fx( move16(); /* Init total/dmx ener factors */ - set32_fx( hParamMC->ener_fac_fx, 0, PARAM_MC_MAX_PARAMETER_BANDS ); + set32_fx( hParamMC->ener_fac_fx, 0, PARAM_MC_MAX_PARAMETER_BANDS ); // Q21 return error; @@ -536,7 +533,7 @@ void ivas_param_mc_enc_fx( /* just copy data_dmx generated above, contains already the downmix */ FOR( ch = 0; ch < st_ivas->nchan_transport; ch++ ) { - Copy32( data_dmx_fx[ch], data_f_fx[ch], input_frame ); + Copy32( data_dmx_fx[ch], data_f_fx[ch], input_frame ); // q_data_dmx_fx16 } /* we have to run the transient detector on the second channel of the last CPE if we @@ -547,15 +544,15 @@ void ivas_param_mc_enc_fx( { Word16 cpe_idx = shr( ch, 1 ); - set32_fx( data_f_fx[ch], 0, input_frame ); - set16_fx( data_f_fx16, 0, input_frame ); + set32_fx( data_f_fx[ch], 0, input_frame ); // Q11 + set16_fx( data_f_fx16, 0, input_frame ); // Q11 RunTransientDetection_ivas_fx( data_f_fx16, input_frame, st_ivas->hCPE[cpe_idx]->hCoreCoder[ch - cpe_idx * CPE_CHANNELS]->hTranDet, 0 ); } } /* write Parametric MC side info bitstream into temporary buffer*/ - ivas_param_mc_write_bs( hParamMC, ILD_idx, ICC_idx, bit_buffer, &bit_pos ); + ivas_param_mc_write_bs_fx( hParamMC, ILD_idx, ICC_idx, bit_buffer, &bit_pos ); /* push the Parametric MC side info from the temporary buffer into the medatdata bitstream*/ push_next_bits( hMetaData, bit_buffer, bit_pos ); @@ -606,7 +603,7 @@ static void ivas_param_mc_dmx_fx( move16(); FOR( inp_ch = 0; inp_ch < nchan_input; inp_ch++ ) { - ( *dmx_sample_fx ) = Madd_32_32( ( *dmx_sample_fx ), data_f_fx[idx[inp_ch]][i], ( *( p_dmx_fac_fx++ ) ) ); + ( *dmx_sample_fx ) = Madd_32_32( ( *dmx_sample_fx ), data_f_fx[idx[inp_ch]][i], ( *( p_dmx_fac_fx++ ) ) ); // Q_x - 11 move16(); } } @@ -626,9 +623,9 @@ static void ivas_param_mc_dmx_fx( static void ivas_param_mc_param_est_enc_fx( PARAM_MC_ENC_HANDLE hParamMC, /* i/o: Parametric MC encoder handle */ Word32 *data_f_fx[], /* i : Input frame in the time domain Q11 */ - Word32 Cy_sum_fx[][MAX_CICP_CHANNELS][MAX_CICP_CHANNELS], /* o : Covariance matrix for the original frame */ + Word32 Cy_sum_fx[][MAX_CICP_CHANNELS][MAX_CICP_CHANNELS], /* o : Covariance matrix for the original frame Cy_sum_e*/ Word16 Cy_sum_e[][MAX_CICP_CHANNELS][MAX_CICP_CHANNELS], /* o : Covariance matrix for the original frame */ - Word32 Cx_sum_fx[][PARAM_MC_MAX_TRANSPORT_CHANS][PARAM_MC_MAX_TRANSPORT_CHANS], /* o : Covariance matrix for the downmixed frame */ + Word32 Cx_sum_fx[][PARAM_MC_MAX_TRANSPORT_CHANS][PARAM_MC_MAX_TRANSPORT_CHANS], /* o : Covariance matrix for the downmixed frame Cx_sum_e*/ Word16 Cx_sum_e[][PARAM_MC_MAX_TRANSPORT_CHANS][PARAM_MC_MAX_TRANSPORT_CHANS], /* o : Covariance matrix for the downmixed frame */ const Word16 input_frame, /* i : Input frame length */ const Word16 nchan_input, /* i : number of input channels */ @@ -1009,13 +1006,15 @@ static void ivas_param_mc_param_est_enc_fx( { ref_channel_idx = h_ild_mapping->ref_channel_idx[k][ref_channel_cnt]; move16(); - ref_ener_fx = BASOP_Util_Add_Mant32Exp( ref_ener_fx, ref_ener_e, Cx_sum_fx[cur_param_band][ref_channel_idx][ref_channel_idx], + ref_ener_fx = BASOP_Util_Add_Mant32Exp( ref_ener_fx, ref_ener_e, Cx_sum_fx[cur_param_band][ref_channel_idx][ref_channel_idx], // ref_ener_e Cx_sum_e[cur_param_band][ref_channel_idx][ref_channel_idx], &ref_ener_e ); - ref_ener_e = Cx_sum_e[cur_param_band][ref_channel_idx][ref_channel_idx]; - move16(); } L_tmp = Mpy_32_16_1( ref_ener_fx, hParamMC->hMetadataPMC.ild_factors_fx[k] ); +#ifdef FIX_ISSUE_1154 + L_tmp = L_deposit_h( BASOP_Util_Divide3232_Scale( Nrg_fx[h_ild_mapping->ild_index[k]], L_add( L_tmp, EPSILLON_FX ), &tmp_e ) ); +#else L_tmp = L_deposit_h( BASOP_Util_Divide3232_Scale( Nrg_fx[h_ild_mapping->ild_index[k]], L_tmp, &tmp_e ) ); +#endif tmp_e = add( sub( Nrg_e[h_ild_mapping->ild_index[k]], ref_ener_e ), tmp_e ); @@ -1393,7 +1392,11 @@ static void ivas_param_mc_quantize_ilds_fx( ref_ener_fx = BASOP_Util_Add_Mant32Exp( ref_ener_fx, ref_ener_e, Cx_fx[ref_channel_idx][ref_channel_idx], Cx_e[ref_channel_idx][ref_channel_idx], &ref_ener_e ); } ref_ener_fx = Mpy_32_16_1( ref_ener_fx, hParamMC->hMetadataPMC.ild_factors_fx[k] ); +#ifdef FIX_ISSUE_1154 + L_tmp = L_deposit_h( BASOP_Util_Divide3232_Scale( Nrg_fx[h_ild_mapping->ild_index[k]], L_add( ref_ener_fx, EPSILLON_FX ), &tmp_e ) ); +#else L_tmp = L_deposit_h( BASOP_Util_Divide3232_Scale( Nrg_fx[h_ild_mapping->ild_index[k]], ref_ener_fx, &tmp_e ) ); +#endif tmp_e = add( sub( Nrg_e[h_ild_mapping->ild_index[k]], ref_ener_e ), tmp_e ); /*10 in Q21 = 1342177280*/ ILD_fx[k] = Mpy_32_32( 1342177280, BASOP_Util_Log10( L_tmp, tmp_e ) ); // Q21 @@ -1633,8 +1636,8 @@ static void ivas_param_mc_transient_detection_fx( push_wmops( "param_mc_trn_det" ); attackRatioThreshold_fx = hTranDet->transientDetector.attackRatioThreshold; - pSubblockNrg_fx = &hTranDet->subblockEnergies.subblockNrg[hParamMC->transient_detector_delay]; - pAccSubblockNrg_fx = &hTranDet->subblockEnergies.accSubblockNrg[hParamMC->transient_detector_delay]; + pSubblockNrg_fx = &hTranDet->subblockEnergies.subblockNrg[hParamMC->transient_detector_delay]; // Q(-1) + pAccSubblockNrg_fx = &hTranDet->subblockEnergies.accSubblockNrg[hParamMC->transient_detector_delay]; // Q(-1) bIsAttackPresent = FALSE; move16(); @@ -1645,8 +1648,8 @@ static void ivas_param_mc_transient_detection_fx( * if we had an attack very late in the last frame, * make the current frame also a transient one... */ test(); - IF( EQ_16( BASOP_Util_Cmp_Mant32Exp( pSubblockNrg_fx[-1], 31, Mpy_32_16_1( pAccSubblockNrg_fx[-1], attackRatioThreshold_fx ), ( 31 + ATTACKTHRESHOLD_E ) ), 1 ) || - EQ_16( BASOP_Util_Cmp_Mant32Exp( pSubblockNrg_fx[-2], 31, Mpy_32_16_1( pAccSubblockNrg_fx[-2], attackRatioThreshold_fx ), ( 31 + ATTACKTHRESHOLD_E ) ), 1 ) ) + IF( EQ_16( BASOP_Util_Cmp_Mant32Exp( pSubblockNrg_fx[-1], 32, Mpy_32_16_1( pAccSubblockNrg_fx[-1], attackRatioThreshold_fx ), ( 32 + ATTACKTHRESHOLD_E ) ), 1 ) || + EQ_16( BASOP_Util_Cmp_Mant32Exp( pSubblockNrg_fx[-2], 32, Mpy_32_16_1( pAccSubblockNrg_fx[-2], attackRatioThreshold_fx ), ( 32 + ATTACKTHRESHOLD_E ) ), 1 ) ) { bIsAttackPresent = TRUE; move16(); @@ -1655,7 +1658,7 @@ static void ivas_param_mc_transient_detection_fx( } FOR( i = 0; i < NSUBBLOCKS; i++ ){ - IF( EQ_16( BASOP_Util_Cmp_Mant32Exp( pSubblockNrg_fx[i], 31, Mpy_32_16_1( pAccSubblockNrg_fx[i], attackRatioThreshold_fx ), ( 31 + ATTACKTHRESHOLD_E ) ), 1 ) ){ + IF( EQ_16( BASOP_Util_Cmp_Mant32Exp( pSubblockNrg_fx[i], 32, Mpy_32_16_1( pAccSubblockNrg_fx[i], attackRatioThreshold_fx ), ( 32 + ATTACKTHRESHOLD_E ) ), 1 ) ){ bIsAttackPresent = TRUE; move16(); attackIndex = i; @@ -1680,7 +1683,7 @@ return; * Write the metadata bitstream *------------------------------------------------------------------------*/ -static void ivas_param_mc_write_bs( +static void ivas_param_mc_write_bs_fx( const PARAM_MC_ENC_HANDLE hParamMC, /* i/o: Parametric MC encoder Handle */ Word16 *ILD_idx, /* i : ILD quantizer indices sequence */ Word16 *ICC_idx, /* i : ICC quantizer indices sequence */ @@ -1762,11 +1765,11 @@ static void ivas_param_mc_write_bs( } } - ivas_param_mc_encode_parameter( ICC_idx, &hParamMC->hMetadataPMC, &hParamMC->hMetadataPMC.icc_coding, - nbands, band_step, icc_map_size_wo_lfe, icc_map_size, bit_buffer, bit_pos ); + ivas_param_mc_encode_parameter_fx( ICC_idx, &hParamMC->hMetadataPMC, &hParamMC->hMetadataPMC.icc_coding, + nbands, band_step, icc_map_size_wo_lfe, icc_map_size, bit_buffer, bit_pos ); - ivas_param_mc_encode_parameter( ILD_idx, &hParamMC->hMetadataPMC, &hParamMC->hMetadataPMC.ild_coding, - nbands, band_step, ild_map_size_wo_lfe, ild_map_size, bit_buffer, bit_pos ); + ivas_param_mc_encode_parameter_fx( ILD_idx, &hParamMC->hMetadataPMC, &hParamMC->hMetadataPMC.ild_coding, + nbands, band_step, ild_map_size_wo_lfe, ild_map_size, bit_buffer, bit_pos ); pop_wmops(); return; @@ -1774,13 +1777,13 @@ static void ivas_param_mc_write_bs( /*------------------------------------------------------------------------- - * ivas_param_mc_encode_parameter() + * ivas_param_mc_encode_parameter_fx() * * (entropy) encode a sequence of parameter indices *------------------------------------------------------------------------*/ -static void ivas_param_mc_encode_parameter( - int16_t *quant_idx, /* i : indices sequence to encode */ +static void ivas_param_mc_encode_parameter_fx( + Word16 *quant_idx, /* i : indices sequence to encode */ HANDLE_IVAS_PARAM_MC_METADATA hMetadataPMC, /* i : Parametric MC metadata handle */ HANDLE_PARAM_MC_PARAMETER_CODING_INFO hParameterCodingInfo, /* i : parameter quantization and coding info */ const Word16 nbands, /* i : number of parameter bands to encode */ @@ -1867,10 +1870,10 @@ static void ivas_param_mc_encode_parameter( bit_cnt_uni = sub( i_mult( sz_seq, hParameterCodingInfo->uni_bits ), 1 ); /* -1 for the additional diff/direct signaling bit for the range encoder*/ /* code the direct index sequence */ - ivas_param_mc_range_encoder( seq, sz_seq, hParameterCodingInfo->cum_freq, hParameterCodingInfo->sym_freq, PARAM_MC_RANGE_CODER_TOT_SHIFT, bit_cnt_uni, &tmp_bit_buffer[0], &bit_cnt_range ); + ivas_param_mc_range_encoder_fx( seq, sz_seq, hParameterCodingInfo->cum_freq, hParameterCodingInfo->sym_freq, PARAM_MC_RANGE_CODER_TOT_SHIFT, bit_cnt_uni, &tmp_bit_buffer[0], &bit_cnt_range ); /* Coding the delta index sequence */ - ivas_param_mc_range_encoder( seq_delta, sz_seq, hParameterCodingInfo->cum_freq_delta, hParameterCodingInfo->sym_freq_delta, PARAM_MC_RANGE_CODER_TOT_SHIFT, bit_cnt_uni, &tmp_bit_buffer_diff[0], &bit_cnt_range_diff ); + ivas_param_mc_range_encoder_fx( seq_delta, sz_seq, hParameterCodingInfo->cum_freq_delta, hParameterCodingInfo->sym_freq_delta, PARAM_MC_RANGE_CODER_TOT_SHIFT, bit_cnt_uni, &tmp_bit_buffer_diff[0], &bit_cnt_range_diff ); bit_cnt_range_min = s_min( bit_cnt_range, bit_cnt_range_diff ); @@ -1885,7 +1888,7 @@ static void ivas_param_mc_encode_parameter( FOR( i = 0; i < sz_seq; ++i ) { - ivas_param_mc_dec2bin( seq[i], hParameterCodingInfo->uni_bits, &bit_buffer[*( bit_pos ) + bit_pos_tmp] ); + ivas_param_mc_dec2bin_fx( seq[i], hParameterCodingInfo->uni_bits, &bit_buffer[*( bit_pos ) + bit_pos_tmp] ); bit_pos_tmp = add( bit_pos_tmp, hParameterCodingInfo->uni_bits ); } *bit_pos = add( *bit_pos, bit_pos_tmp ); @@ -1927,7 +1930,7 @@ static void ivas_param_mc_encode_parameter( * Decimal to binary routine *------------------------------------------------------------------------*/ -static void ivas_param_mc_dec2bin( +static void ivas_param_mc_dec2bin_fx( const Word16 val, /* i : value to encode */ const Word16 N, /* i : number of bits for encoding the value */ UWord16 bits[PARAM_MC_MAX_BITS] ) /* o : encoded bits buffer */ @@ -1953,7 +1956,7 @@ static void ivas_param_mc_dec2bin( * Parametric MC Range encoder *-------------------------------------------------------------------*/ -static void ivas_param_mc_range_encoder( +static void ivas_param_mc_range_encoder_fx( const Word16 *seq_in, /* i : input sequence */ const Word16 num_symbols, /* i : Number of symbole to encode */ const UWord16 *cum_freq, /* i : cumulated frequencies */ @@ -1971,14 +1974,14 @@ static void ivas_param_mc_range_encoder( UWord16 *bits; /* Initialize range encoder */ - rc_uni_enc_init( &rc_st_enc ); + rc_uni_enc_init_fx( &rc_st_enc ); /* Main loop over the length of the sequence */ FOR( i = 0; i < num_symbols; ++i ) { - rc_uni_enc_encode_symbol_fastS( &rc_st_enc, (UWord16) seq_in[i], cum_freq, sym_freq, tot_shift ); + rc_uni_enc_encode_symbol_fastS_fx( &rc_st_enc, (UWord16) seq_in[i], cum_freq, sym_freq, tot_shift ); - IF( GT_16( rc_uni_enc_virtual_finish( &rc_st_enc ), max_nb_bits ) ) + IF( GT_16( rc_uni_enc_virtual_finish_fx( &rc_st_enc ), max_nb_bits ) ) { /* we alread have exceeded the maximum number of bits allowed, i.e. the uniform fallback */ *bit_pos = MAX_BITS_PER_FRAME; @@ -1987,15 +1990,15 @@ static void ivas_param_mc_range_encoder( } /* Finish range encoder */ - rc_tot_bits = rc_uni_enc_finish( &rc_st_enc ); /* No. of bits consumed by range coder */ + rc_tot_bits = rc_uni_enc_finish_fx( &rc_st_enc ); /* No. of bits consumed by range coder */ /* Push range coded bits from byte_buffer to bitstream */ /* 1) Push all complete bytes, one byte at a time */ - FOR( i = 0; i < shr( rc_tot_bits, 3 ); ++i ) + FOR( i = 0; i < ( rc_tot_bits >> 3 ); ++i ) { /* use rc_st_enc.byte_buffer */ - bits = &bit_buffer[shl( i, 3 )]; + bits = &bit_buffer[i << 3]; byte = rc_st_enc.byte_buffer[i]; move16(); @@ -2023,7 +2026,7 @@ static void ivas_param_mc_range_encoder( { UWord8 rem_bits = (UWord8) s_and( rc_tot_bits, 7 ); - bits = &bit_buffer[shl( i, 3 )]; + bits = &bit_buffer[( i << 3 )]; byte = rc_st_enc.byte_buffer[i]; move16(); diff --git a/lib_enc/ivas_mc_paramupmix_enc.c b/lib_enc/ivas_mc_paramupmix_enc_fx.c similarity index 94% rename from lib_enc/ivas_mc_paramupmix_enc.c rename to lib_enc/ivas_mc_paramupmix_enc_fx.c index e51703ea359608ca3a18edf3a73ed76816b56a47..fd5cb6217312681796dd7e0a35c92230fb7efc2f 100644 --- a/lib_enc/ivas_mc_paramupmix_enc.c +++ b/lib_enc/ivas_mc_paramupmix_enc_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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,10 +36,8 @@ #include "cnst.h" #include "rom_enc.h" #include "rom_com.h" -#include "prot.h" -#include "ivas_prot.h" -#include "ivas_prot_fx.h" #include "prot_fx.h" +#include "ivas_prot_fx.h" #include "basop_util.h" #include "ivas_rom_com_fx.h" #include "ivas_cnst.h" @@ -80,7 +78,7 @@ static void quantize_pars_fx( const Word32 *v_fx, Word16 exp_v, const Word16 nq, void ivas_mc_paramupmix_enc_fx( Encoder_Struct *st_ivas, /* i/o: IVAS Encoder handle */ BSTR_ENC_HANDLE hBStr, /* i/o: IVAS Metadata bitstream handle */ - Word32 *data_fx[], + Word32 *data_fx[], // st_ivas->q_data_fx const Word16 input_frame /* i : input frame length */ ) { @@ -95,8 +93,8 @@ void ivas_mc_paramupmix_enc_fx( bit_pos = 0; /* Parameter estimation */ - Word32 alphas_fx[MC_PARAMUPMIX_COMBINATIONS][IVAS_MAX_NUM_BANDS]; - Word32 betas_fx[MC_PARAMUPMIX_COMBINATIONS][IVAS_MAX_NUM_BANDS]; + Word32 alphas_fx[MC_PARAMUPMIX_COMBINATIONS][IVAS_MAX_NUM_BANDS]; // exp_alphas + Word32 betas_fx[MC_PARAMUPMIX_COMBINATIONS][IVAS_MAX_NUM_BANDS]; // exp_betas Word16 exp_alphas = 31, exp_betas = 31; move16(); move16(); @@ -126,7 +124,7 @@ void ivas_mc_paramupmix_enc_fx( * * Initialize MC ParamUpmix encoder handle *------------------------------------------------------------------------*/ -ivas_error ivas_mc_paramupmix_enc_open( +ivas_error ivas_mc_paramupmix_enc_open_fx( Encoder_Struct *st_ivas /* i/o: IVAS encoder handle */ ) { @@ -201,8 +199,8 @@ ivas_error ivas_mc_paramupmix_enc_open( /* assuming parameters are calculated at end of frame, compensate for MCT delay and half of decoder fb */ /* still 1.5ms off, since MCT delay is not large enough */ /* param at end of frame */ - fb_cfg->prior_input_length = (int16_t) ( NS2SA( input_Fs, 12000000L ) + NS2SA( input_Fs, DELAY_FB_4_NS / 2 ) - input_frame / 2 - NS2SA( input_Fs, DELAY_FB_1_NS / 2 ) ); - fb_cfg->prior_input_length = (int16_t) max( fb_cfg->prior_input_length, input_frame / MAX_PARAM_SPATIAL_SUBFRAMES ); + fb_cfg->prior_input_length = (Word16) ( NS2SA_FX2( input_Fs, 12000000L ) + NS2SA_FX2( input_Fs, DELAY_FB_4_NS / 2 ) - input_frame / 2 - NS2SA_FX2( input_Fs, DELAY_FB_1_NS / 2 ) ); + fb_cfg->prior_input_length = s_max( fb_cfg->prior_input_length, (Word16) input_frame / MAX_PARAM_SPATIAL_SUBFRAMES ); /* Allocate and initialize FB mixer handle */ IF( NE_32( ( error = ivas_FB_mixer_open_fx( &( hMCParamUpmix->hFbMixer ), input_Fs, fb_cfg, 0 ) ), IVAS_ERR_OK ) ) @@ -270,7 +268,7 @@ ivas_error ivas_mc_paramupmix_enc_open( * * Close MC Param-Upmix encoder handle *------------------------------------------------------------------------*/ -void ivas_mc_paramupmix_enc_close( +void ivas_mc_paramupmix_enc_close_fx( MC_PARAMUPMIX_ENC_HANDLE *hMCParamUpmix, /* i/o: MC Param-Upmix encoder handle */ const Word32 input_Fs /* i : input sampling rate */ ) @@ -465,12 +463,12 @@ static void huffman_encode_fx( } static void quantize_pars_fx( - const Word32 *v_fx, + const Word32 *v_fx, // exp_v Word16 exp_v, const Word16 nq, - const Word32 *data_fx, + const Word32 *data_fx, // Q28 Word32 vq[IVAS_MAX_NUM_BANDS], - Word32 *vdeq_fx, + Word32 *vdeq_fx, // exp_vdeq Word16 *exp_vdeq ) { Word16 iv, iq, iq0, iq1; @@ -480,7 +478,7 @@ static void quantize_pars_fx( iq0 = 0; iq1 = sub( nq, 1 ); - WHILE( GT_16( sub( iq1, iq0 ), 1 ) ) + WHILE( ( iq1 - iq0 ) > 1 ) { iq = shr( add( iq0, iq1 ), 1 ); Word16 cmp_1 = BASOP_Util_Cmp_Mant32Exp( v_fx[iv], exp_v, data_fx[iq], 31 - Q28 ); @@ -497,12 +495,12 @@ static void quantize_pars_fx( Word16 exp_var1 = 0; move16(); Word32 var1 = BASOP_Util_Add_Mant32Exp( v_fx[iv], exp_v, L_negate( data_fx[iq0] ), 31 - Q28, &exp_var1 ); - var1 = abs( var1 ); + var1 = L_abs( var1 ); Word16 exp_var2 = 0; move16(); Word32 var2 = BASOP_Util_Add_Mant32Exp( v_fx[iv], exp_v, L_negate( data_fx[iq1] ), 31 - Q28, &exp_var2 ); - var2 = abs( var2 ); + var2 = L_abs( var2 ); Word16 cmp_2 = BASOP_Util_Cmp_Mant32Exp( var1, exp_var1, var2, exp_var2 ); @@ -527,17 +525,17 @@ static void quantize_pars_fx( } static void quantize_alpha_fx( - const Word32 *alpha_fx, + const Word32 *alpha_fx, // 31 - exp_alpha Word16 exp_alpha, Word16 *pnq, Word32 aq[IVAS_MAX_NUM_BANDS], - Word32 *adeq_fx, + Word32 *adeq_fx, // 31 - exp_adeq Word16 *exp_adeq ) { Word16 nq; const Word32 *data_fx; - nq = ivas_mc_paramupmix_alpha_quant_table_fx.nquant; + nq = ivas_mc_paramupmix_alpha_quant_table_fx.nquant; // Q0 move16(); data_fx = ivas_mc_paramupmix_alpha_quant_table_fx.data; // Q28 @@ -566,13 +564,13 @@ static void quantize_beta_fx( FOR( iv = 0; iv < IVAS_MAX_NUM_BANDS; iv++ ) { - quant_table_fx = tables_fx[ivas_param_upmx_mx_qmap[aq[iv]]]; + quant_table_fx = tables_fx[ivas_param_upmx_mx_qmap[aq[iv]]]; // Q28 iq0 = 0; move16(); iq1 = sub( quant_table_fx.nquant, 1 ); - WHILE( GT_16( sub( iq1, iq0 ), 1 ) ) + WHILE( ( ( iq1 - iq0 ) > 1 ) ) { iq = shr( add( iq0, iq1 ), 1 ); @@ -592,24 +590,24 @@ static void quantize_beta_fx( Word16 exp_var1 = 0; move16(); Word32 var1 = BASOP_Util_Add_Mant32Exp( beta_fx[iv], exp_beta, L_negate( quant_table_fx.data[iq0] ), 31 - Q28, &exp_var1 ); - var1 = abs( var1 ); + var1 = L_abs( var1 ); Word16 exp_var2 = 0; move16(); Word32 var2 = BASOP_Util_Add_Mant32Exp( beta_fx[iv], exp_beta, L_negate( quant_table_fx.data[iq1] ), 31 - Q28, &exp_var2 ); - var2 = abs( var2 ); + var2 = L_abs( var2 ); Word16 cmp_2 = BASOP_Util_Cmp_Mant32Exp( var1, exp_var1, var2, exp_var2 ); IF( EQ_16( cmp_2, negate( 1 ) ) ) { bq[iv] = iq0; - bdeq_fx[iv] = quant_table_fx.data[iq0]; + bdeq_fx[iv] = quant_table_fx.data[iq0]; // Q28 } ELSE { bq[iv] = iq1; - bdeq_fx[iv] = quant_table_fx.data[iq1]; + bdeq_fx[iv] = quant_table_fx.data[iq1]; // Q28 } move16(); move32(); @@ -625,9 +623,9 @@ static void quantize_beta_fx( static void put_ec_data_fx( MC_PARAMUPMIX_ENC_HANDLE hMCParamUpmix, const Word16 ch, - const Word32 pars_fx[IVAS_MAX_NUM_BANDS], + const Word32 pars_fx[IVAS_MAX_NUM_BANDS], // Q(31 - exp_paras) Word16 exp_paras, - const Word32 alphas_fx[IVAS_MAX_NUM_BANDS], + const Word32 alphas_fx[IVAS_MAX_NUM_BANDS], // Q(31 - exp_alphas) Word16 exp_alphas, const PAR_TYPE parType, UWord16 bit_buffer[MC_PARAMUPMIX_MAX_BITS], @@ -636,8 +634,8 @@ static void put_ec_data_fx( Word16 nq; Word32 alphaQuant[IVAS_MAX_NUM_BANDS]; Word32 betaQuant[IVAS_MAX_NUM_BANDS]; - Word32 alphaDequant_fx[IVAS_MAX_NUM_BANDS]; - Word32 betaDequant_fx[IVAS_MAX_NUM_BANDS]; + Word32 alphaDequant_fx[IVAS_MAX_NUM_BANDS]; // 31 - exp_alphaDequant + Word32 betaDequant_fx[IVAS_MAX_NUM_BANDS]; // 31 - exp_betaDequant Word16 exp_alphaDequant = 31, exp_betaDequant = 31; @@ -760,12 +758,12 @@ static void ivas_mc_paramupmix_dmx_fx( static ivas_error ivas_mc_paramupmix_param_est_enc_fx( MC_PARAMUPMIX_ENC_HANDLE hMCParamUpmix, /* i/o: MC Param-Upmix encoder handle */ - Word32 *data_f_fx[], + Word32 *data_f_fx[], // Q_data_f Word16 Q_data_f, - const Word16 input_frame, /* i : Input frame length */ - Word32 alphas_fx[MC_PARAMUPMIX_COMBINATIONS][IVAS_MAX_NUM_BANDS], + const Word16 input_frame, /* i : Input frame length */ + Word32 alphas_fx[MC_PARAMUPMIX_COMBINATIONS][IVAS_MAX_NUM_BANDS], // 31 - exp_alphas Word16 *exp_alphas, - Word32 betas_fx[MC_PARAMUPMIX_COMBINATIONS][IVAS_MAX_NUM_BANDS], + Word32 betas_fx[MC_PARAMUPMIX_COMBINATIONS][IVAS_MAX_NUM_BANDS], // 31 - exp_betas Word16 *exp_betas ) { @@ -775,11 +773,11 @@ static ivas_error ivas_mc_paramupmix_param_est_enc_fx( Word32 fr_imagbuffer_fx[MC_PARAMUPMIX_COMBINATIONS * MC_PARAMUPMIX_NCH][L_FRAME48k]; Word32 *p_fr_realbuffer_fx[MC_PARAMUPMIX_COMBINATIONS * MC_PARAMUPMIX_NCH]; Word32 *p_fr_imagbuffer_fx[MC_PARAMUPMIX_COMBINATIONS * MC_PARAMUPMIX_NCH]; - Word32 *cov_real_fx[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH]; - Word32 *cov_dtx_real_fx[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH]; + Word32 *cov_real_fx[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH]; // q_cov_real + Word32 *cov_dtx_real_fx[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH]; // q_cov_dtx_real Word16 *q_cov_real[IVAS_SPAR_MAX_CH]; Word16 *q_cov_dtx_real[IVAS_SPAR_MAX_CH]; - Word32 *pp_in_fr_real_fx[MC_PARAMUPMIX_COMBINATIONS * MC_PARAMUPMIX_NCH], *pp_in_fr_imag_fx[MC_PARAMUPMIX_COMBINATIONS * MC_PARAMUPMIX_NCH]; + Word32 *pp_in_fr_real_fx[MC_PARAMUPMIX_COMBINATIONS * MC_PARAMUPMIX_NCH], *pp_in_fr_imag_fx[MC_PARAMUPMIX_COMBINATIONS * MC_PARAMUPMIX_NCH]; // q_ppIn_FR Word16 q_ppIn_FR; Word32 rxy_fx, ryy_fx; @@ -822,8 +820,8 @@ static ivas_error ivas_mc_paramupmix_param_est_enc_fx( pcm_in_fx[2 * i] = data_f_fx[chan1s[i]]; pcm_in_fx[2 * i + 1] = data_f_fx[chan2s[i]]; - Scale_sig32( pcm_in_fx[2 * i], input_frame, sub( Q14, Q_data_f ) ); - Scale_sig32( pcm_in_fx[2 * i + 1], input_frame, sub( Q14, Q_data_f ) ); + Scale_sig32( pcm_in_fx[2 * i], input_frame, sub( Q14, Q_data_f ) ); // Q14 + Scale_sig32( pcm_in_fx[2 * i + 1], input_frame, sub( Q14, Q_data_f ) ); // Q14 } /*-----------------------------------------------------------------------------------------* @@ -898,10 +896,10 @@ static ivas_error ivas_mc_paramupmix_param_est_enc_fx( FOR( b = 0; b < MC_PARAMUPMIX_COMBINATIONS; b++ ) { - pp_in_fr_real_fx[0] = p_fr_realbuffer_fx[2 * b]; - pp_in_fr_imag_fx[0] = p_fr_imagbuffer_fx[2 * b]; - pp_in_fr_real_fx[1] = FR_Real_Mid_fx; - pp_in_fr_imag_fx[1] = FR_Imag_Mid_fx; + pp_in_fr_real_fx[0] = p_fr_realbuffer_fx[2 * b]; // q_ppIn_FR + pp_in_fr_imag_fx[0] = p_fr_imagbuffer_fx[2 * b]; // q_ppIn_FR + pp_in_fr_real_fx[1] = FR_Real_Mid_fx; // q_ppIn_FR + pp_in_fr_imag_fx[1] = FR_Imag_Mid_fx; // q_ppIn_FR v_add_fx( pp_in_fr_real_fx[0], p_fr_realbuffer_fx[2 * b + 1], pp_in_fr_real_fx[1], L_FRAME48k ); v_add_fx( pp_in_fr_imag_fx[0], p_fr_imagbuffer_fx[2 * b + 1], pp_in_fr_imag_fx[1], L_FRAME48k ); @@ -910,9 +908,9 @@ static ivas_error ivas_mc_paramupmix_param_est_enc_fx( { FOR( j = 0; j < MC_PARAMUPMIX_NCH; j++ ) { - cov_real_fx[i][j] = hMCParamUpmix->cov_real_fx[b][i][j]; + cov_real_fx[i][j] = hMCParamUpmix->cov_real_fx[b][i][j]; // q_cov_real move32(); - cov_dtx_real_fx[i][j] = hMCParamUpmix->cov_dtx_real_fx[b][i][j]; + cov_dtx_real_fx[i][j] = hMCParamUpmix->cov_dtx_real_fx[b][i][j]; // q_cov_dtx_real move32(); } IF( ( q_cov_real[i] = (Word16 *) malloc( sizeof( Word16 ) * MC_PARAMUPMIX_NCH ) ) == NULL ) @@ -1042,10 +1040,12 @@ static ivas_error ivas_mc_paramupmix_param_est_enc_fx( IF( LT_16( maxbands, IVAS_MAX_NUM_BANDS ) ) { +#ifndef FIX_1133_IMPROVE_MC_MLD *exp_alphas = 0; move16(); *exp_betas = 0; move16(); +#endif FOR( b = 0; b < MC_PARAMUPMIX_COMBINATIONS; b++ ) { FOR( bnd = maxbands; bnd < IVAS_MAX_NUM_BANDS; bnd++ ) diff --git a/lib_enc/ivas_mcmasa_enc.c b/lib_enc/ivas_mcmasa_enc_fx.c similarity index 92% rename from lib_enc/ivas_mcmasa_enc.c rename to lib_enc/ivas_mcmasa_enc_fx.c index ad46c3e4a7d96059ad59e4c8a61d3151708490ac..22f21dceb020c4852d8d97ed129dbd7a9b48d25b 100644 --- a/lib_enc/ivas_mcmasa_enc.c +++ b/lib_enc/ivas_mcmasa_enc_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other @@ -35,10 +35,8 @@ #include #include #include "ivas_cnst.h" -#include "ivas_prot.h" #include "ivas_prot_fx.h" #include "options.h" -#include "prot.h" #include "prot_fx.h" #include "ivas_rom_com.h" #include "ivas_rom_com_fx.h" @@ -191,7 +189,7 @@ ivas_error ivas_mcmasa_enc_open_fx( { IF( GE_32( hMcMasa->band_grouping[i], maxBin ) ) { - hMcMasa->band_grouping[i] = maxBin; + hMcMasa->band_grouping[i] = maxBin; // Q0 move16(); hMcMasa->nbands = i; move16(); @@ -200,22 +198,22 @@ ivas_error ivas_mcmasa_enc_open_fx( } /* initialize delay compensation */ - hMcMasa->num_samples_delay_comp = NS2SA( input_Fs, DELAY_DIRAC_ENC_CMP_NS ); + hMcMasa->num_samples_delay_comp = NS2SA_FX2( input_Fs, DELAY_DIRAC_ENC_CMP_NS ); move16(); #ifdef DISABLE_DIRAC_DELAY_COMP hMcMasa->num_samples_delay_comp = 0; /* disable delay compensation by setting to 0 */ #endif - tmp_f = idiv1616( hMcMasa->num_samples_delay_comp, ( NS2SA( input_Fs, DIRAC_SLOT_ENC_NS ) ) ); + tmp_f = idiv1616( hMcMasa->num_samples_delay_comp, ( NS2SA_FX2( input_Fs, DIRAC_SLOT_ENC_NS ) ) ); hMcMasa->num_slots_delay_comp = tmp_f; move16(); - IF( GT_16( hMcMasa->num_samples_delay_comp, ( NS2SA( input_Fs, DIRAC_SLOT_ENC_NS ) ) ) ) + IF( GT_16( hMcMasa->num_samples_delay_comp, ( NS2SA_FX2( input_Fs, DIRAC_SLOT_ENC_NS ) ) ) ) { hMcMasa->num_slots_delay_comp = add( hMcMasa->num_slots_delay_comp, 1 ); move16(); hMcMasa->offset_comp = negate( hMcMasa->num_samples_delay_comp ); move16(); - hMcMasa->num_samples_delay_comp = i_mult( hMcMasa->num_slots_delay_comp, NS2SA( input_Fs, DIRAC_SLOT_ENC_NS ) ); + hMcMasa->num_samples_delay_comp = i_mult( hMcMasa->num_slots_delay_comp, NS2SA_FX2( input_Fs, DIRAC_SLOT_ENC_NS ) ); move16(); hMcMasa->offset_comp = add( hMcMasa->offset_comp, hMcMasa->num_samples_delay_comp ); move16(); @@ -241,17 +239,17 @@ ivas_error ivas_mcmasa_enc_open_fx( IF( hMcMasa->separateChannelEnabled ) { /* TD Energy calculation with LP */ - IF( ( hMcMasa->delay_buffer_lfe[0] = (Word32 *) malloc( NS2SA( input_Fs, DELAY_DIRAC_ENC_CMP_NS + DIRAC_SLOT_ENC_NS ) * sizeof( Word32 ) ) ) == NULL ) + IF( ( hMcMasa->delay_buffer_lfe[0] = (Word32 *) malloc( NS2SA_FX2( input_Fs, DELAY_DIRAC_ENC_CMP_NS + DIRAC_SLOT_ENC_NS ) * sizeof( Word32 ) ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for McMasa\n" ) ); } - set_zero_fx( hMcMasa->delay_buffer_lfe[0], NS2SA( input_Fs, DELAY_DIRAC_ENC_CMP_NS + DIRAC_SLOT_ENC_NS ) ); + set_zero_fx( hMcMasa->delay_buffer_lfe[0], NS2SA_FX2( input_Fs, DELAY_DIRAC_ENC_CMP_NS + DIRAC_SLOT_ENC_NS ) ); - IF( ( hMcMasa->delay_buffer_lfe[1] = (Word32 *) malloc( NS2SA( input_Fs, DELAY_DIRAC_ENC_CMP_NS + DIRAC_SLOT_ENC_NS ) * sizeof( Word32 ) ) ) == NULL ) + IF( ( hMcMasa->delay_buffer_lfe[1] = (Word32 *) malloc( NS2SA_FX2( input_Fs, DELAY_DIRAC_ENC_CMP_NS + DIRAC_SLOT_ENC_NS ) * sizeof( Word32 ) ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for McMasa\n" ) ); } - set_zero_fx( hMcMasa->delay_buffer_lfe[1], NS2SA( input_Fs, DELAY_DIRAC_ENC_CMP_NS + DIRAC_SLOT_ENC_NS ) ); + set_zero_fx( hMcMasa->delay_buffer_lfe[1], NS2SA_FX2( input_Fs, DELAY_DIRAC_ENC_CMP_NS + DIRAC_SLOT_ENC_NS ) ); hMcMasa->hFbMixerLfe = NULL; } ELSE @@ -346,7 +344,7 @@ ivas_error ivas_mcmasa_enc_open_fx( { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for McMasa\n" ) ); } - set_zero_fx( hMcMasa->buffer_intensity_real_fx[i][j], hMcMasa->nbands ); + set_zero_fx( hMcMasa->buffer_intensity_real_fx[i][j], hMcMasa->nbands ); // hMcMasa->buffer_intensity_real_q } } set16_fx( hMcMasa->buffer_intensity_real_q, 31, DIRAC_NO_COL_AVG_DIFF ); @@ -358,7 +356,7 @@ ivas_error ivas_mcmasa_enc_open_fx( FOR( j = 0; j < hMcMasa->no_col_avg_diff; j++ ) { - IF( ( hMcMasa->buffer_intensity_real_vert_fx[j] = (Word32 *) malloc( hMcMasa->nbands * sizeof( Word32 ) ) ) == NULL ) + IF( ( hMcMasa->buffer_intensity_real_vert_fx[j] = (Word32 *) malloc( hMcMasa->nbands * sizeof( Word32 ) ) ) == NULL ) // hMcMasa->buffer_intensity_real_vert_q { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for McMasa\n" ) ); } @@ -369,7 +367,7 @@ ivas_error ivas_mcmasa_enc_open_fx( { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for McMasa\n" ) ); } - set_zero_fx( hMcMasa->buffer_energy_fx, imult1616( hMcMasa->nbands, hMcMasa->no_col_avg_diff ) ); + set_zero_fx( hMcMasa->buffer_energy_fx, imult1616( hMcMasa->nbands, hMcMasa->no_col_avg_diff ) ); // hMcMasa->buffer_energy_q set16_fx( hMcMasa->buffer_intensity_real_vert_q, 31, DIRAC_NO_COL_AVG_DIFF ); set16_fx( hMcMasa->buffer_energy_q, 31, DIRAC_NO_COL_AVG_DIFF ); @@ -402,8 +400,8 @@ ivas_error ivas_mcmasa_enc_open_fx( } ELSE IF( EQ_32( st_ivas->hEncoderConfig->mc_input_setup, MC_LS_SETUP_5_1_4 ) ) { - Copy32( ls_azimuth_CICP16_fx, ls_azimuth, sub( nchan_inp, 1 ) ); - Copy32( ls_elevation_CICP16_fx, ls_elevation, sub( nchan_inp, 1 ) ); + Copy32( ls_azimuth_CICP16_fx, ls_azimuth, sub( nchan_inp, 1 ) ); // Q22 + Copy32( ls_elevation_CICP16_fx, ls_elevation, sub( nchan_inp, 1 ) ); // Q22 hMcMasa->numHorizontalChannels = 5; move16(); hMcMasa->isHorizontalSetup = 0; @@ -411,8 +409,8 @@ ivas_error ivas_mcmasa_enc_open_fx( } ELSE { - Copy32( ls_azimuth_CICP19_fx, ls_azimuth, sub( nchan_inp, 1 ) ); - Copy32( ls_elevation_CICP19_fx, ls_elevation, sub( nchan_inp, 1 ) ); + Copy32( ls_azimuth_CICP19_fx, ls_azimuth, sub( nchan_inp, 1 ) ); // Q22 + Copy32( ls_elevation_CICP19_fx, ls_elevation, sub( nchan_inp, 1 ) ); // Q22 hMcMasa->numHorizontalChannels = 7; move16(); hMcMasa->isHorizontalSetup = 0; @@ -421,8 +419,8 @@ ivas_error ivas_mcmasa_enc_open_fx( IF( hMcMasa->separateChannelEnabled ) { - Copy32( &ls_azimuth[hMcMasa->separateChannelIndex + 1], &ls_azimuth[hMcMasa->separateChannelIndex], numAnalysisChannels - hMcMasa->separateChannelIndex ); - Copy32( &ls_elevation[hMcMasa->separateChannelIndex + 1], &ls_elevation[hMcMasa->separateChannelIndex], numAnalysisChannels - hMcMasa->separateChannelIndex ); + Copy32( &ls_azimuth[hMcMasa->separateChannelIndex + 1], &ls_azimuth[hMcMasa->separateChannelIndex], numAnalysisChannels - hMcMasa->separateChannelIndex ); // Q22 + Copy32( &ls_elevation[hMcMasa->separateChannelIndex + 1], &ls_elevation[hMcMasa->separateChannelIndex], numAnalysisChannels - hMcMasa->separateChannelIndex ); // Q22 hMcMasa->numHorizontalChannels = sub( hMcMasa->numHorizontalChannels, 1 ); move16(); } @@ -437,32 +435,32 @@ ivas_error ivas_mcmasa_enc_open_fx( { hMcMasa->chnlToFoaMtx_fx[0][i] = ONE_IN_Q31; move32(); - hMcMasa->chnlToFoaMtx_fx[1][i] = L_mult( getSineWord16R2( extract_l( L_shr( Mult_32_16( ls_azimuth[i], 91 /*32767/360*/ ), 7 ) ) ), getCosWord16R2( extract_l( L_shr( Mult_32_16( ls_elevation[i], 91 ), 7 ) ) ) ); // Q31 + hMcMasa->chnlToFoaMtx_fx[1][i] = L_mult( getSineWord16R2( extract_l( Mpy_32_32( ls_azimuth[i], 46603 /*32767/360*/ ) /*Q22+Q24-31=>Q15*/ ) ), getCosWord16R2( extract_l( Mpy_32_32( ls_elevation[i], 46603 /*2^24/360*/ ) ) ) ); // Q31 move32(); - hMcMasa->chnlToFoaMtx_fx[2][i] = L_shl( getSineWord16R2( extract_l( L_shr( Mult_32_16( ls_elevation[i], 91 ), 7 ) ) ), 16 ); // Q31 + hMcMasa->chnlToFoaMtx_fx[2][i] = L_shl( getSineWord16R2( extract_l( Mpy_32_32( ls_elevation[i], 46603 /*2^24/360*/ ) ) ), 16 ); // Q31 move32(); - hMcMasa->chnlToFoaMtx_fx[3][i] = L_mult( getCosWord16R2( extract_l( L_shr( Mult_32_16( ls_azimuth[i], 91 ), 7 ) ) ), getCosWord16R2( extract_l( L_shr( Mult_32_16( ls_elevation[i], 91 ), 7 ) ) ) ); // Q31 + hMcMasa->chnlToFoaMtx_fx[3][i] = L_mult( getCosWord16R2( extract_l( Mpy_32_32( ls_azimuth[i], 46603 /*2^24/360*/ ) ) ), getCosWord16R2( extract_l( Mpy_32_32( ls_elevation[i], 46603 /*2^24/360*/ ) ) ) ); // Q31 move32(); hMcMasa->chnlToFoaEvenMtx_fx[0][i] = ONE_IN_Q31; move32(); - hMcMasa->chnlToFoaEvenMtx_fx[1][i] = L_shl( getSineWord16R2( extract_l( L_shr( Mult_32_16( ls_azimuth_even[i], 91 ), 7 ) ) ), 16 ); // Q31 + hMcMasa->chnlToFoaEvenMtx_fx[1][i] = L_shl( getSineWord16R2( extract_l( Mpy_32_32( ls_azimuth_even[i], 46603 /*2^24/360*/ ) ) ), 16 ); // Q31 move32(); hMcMasa->chnlToFoaEvenMtx_fx[2][i] = 0; move32(); - hMcMasa->chnlToFoaEvenMtx_fx[3][i] = L_shl( getCosWord16R2( extract_l( L_shr( Mult_32_16( ls_azimuth_even[i], 91 ), 7 ) ) ), 16 ); + hMcMasa->chnlToFoaEvenMtx_fx[3][i] = L_shl( getCosWord16R2( extract_l( Mpy_32_32( ls_azimuth_even[i], 46603 /*2^24/360*/ ) ) ), 16 ); move32(); } hMcMasa->combineRatios = hMasa->config.mergeRatiosOverSubframes; move16(); - Copy32( ls_azimuth, hMcMasa->ls_azimuth_fx, numAnalysisChannels ); + Copy32( ls_azimuth, hMcMasa->ls_azimuth_fx, numAnalysisChannels ); // Q22 FOR( i = 0; i < hMcMasa->numHorizontalChannels; i++ ) { - left_min = L_shl( 360, 22 ); - right_min = L_negate( L_shl( 360, 22 ) ); + left_min = ( 360 << 22 ); + right_min = -( ( 360 << 22 ) ); FOR( j = 0; j < hMcMasa->numHorizontalChannels; j++ ) { @@ -546,14 +544,14 @@ ivas_error ivas_mcmasa_enc_reconfig_fx( /* bitrate changed, may need to do something */ /* brute-force solution: close McMASA and re-instantiate with new settings */ - ivas_masa_enc_close( &( st_ivas->hMasa ) ); + ivas_masa_enc_close_fx( &( st_ivas->hMasa ) ); ivas_mcmasa_enc_close_fx( &( st_ivas->hMcMasa ), st_ivas->hEncoderConfig->input_Fs ); /* Determine if to separate some channels from the analysis */ ivas_mcmasa_setNumTransportChannels_fx( &( st_ivas->nchan_transport ), &( st_ivas->hEncoderConfig->element_mode_init ), ivas_total_brate ); - IF( NE_32( ( error = ivas_masa_enc_open( st_ivas ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = ivas_masa_enc_open_fx( st_ivas ) ), IVAS_ERR_OK ) ) { return error; } @@ -575,7 +573,7 @@ ivas_error ivas_mcmasa_enc_reconfig_fx( void ivas_mcmasa_enc_close_fx( MCMASA_ENC_HANDLE *hMcMasa, /* i/o: encoder McMASA handle */ - const int32_t input_Fs /* i : input sampling rate */ + const Word32 input_Fs /* i : input sampling rate */ ) { Word16 i, j; @@ -674,21 +672,21 @@ void ivas_mcmasa_enc_fx( move16(); UWord8 fixedDistance = 0; move16(); - Word32 elevation_m_values_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS]; - Word32 azimuth_m_values_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS]; - Word32 energyRatio_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS]; - Word32 spreadCoherence_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS]; - Word32 surroundingCoherence_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS]; + Word32 elevation_m_values_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS]; // Q22 + Word32 azimuth_m_values_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS]; // Q22 + Word32 energyRatio_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS]; // Q31 + Word32 spreadCoherence_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS]; // Q30 + Word32 surroundingCoherence_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS]; // Q31 Word32 separatedChannelSignal[L_FRAME48k]; /* Compute low frequency energy */ computeLfeEnergy_fx( hMcMasa, data_fx, input_frame, q_inp ); /* Sum center and LFE, move surround channels */ - v_add_32( data_fx[2], data_fx[3], data_fx[2], input_frame ); + v_add_32( data_fx[2], data_fx[3], data_fx[2], input_frame ); // q_inp FOR( i = 4; i < nchan_inp; i++ ) { - Copy32( data_fx[i], data_fx[i - 1], input_frame ); + Copy32( data_fx[i], data_fx[i - 1], input_frame ); // q_inp } IF( hMcMasa->separateChannelEnabled ) @@ -698,12 +696,12 @@ void ivas_mcmasa_enc_fx( move16(); /* Separate the identified channel */ - Copy32( data_fx[i], separatedChannelSignal, input_frame ); + Copy32( data_fx[i], separatedChannelSignal, input_frame ); // q_inp /* Move the remaining channels in order to perform the analysis without the separated channel */ FOR( i = ( hMcMasa->separateChannelIndex + 1 ); i < ( nchan_inp - 1 ); i++ ) { - Copy32( data_fx[i], data_fx[i - 1], input_frame ); + Copy32( data_fx[i], data_fx[i - 1], input_frame ); // q_inp } } @@ -713,7 +711,7 @@ void ivas_mcmasa_enc_fx( /* Determine LFE-to-total energy ratio */ FOR( i = 0; i < MAX_PARAM_SPATIAL_SUBFRAMES; i++ ) { - hMasa->data.lfeToTotalEnergyRatio_fx[i] = L_deposit_h( BASOP_Util_Divide3232_Scale( hMcMasa->lfeLfEne[i], L_add( EPSILON_FX, hMcMasa->totalLfEne[i] ), &hMasa->data.lfeToTotalEnergyRatio_e[i] ) ); + hMasa->data.lfeToTotalEnergyRatio_fx[i] = L_deposit_h( BASOP_Util_Divide3232_Scale( hMcMasa->lfeLfEne[i], L_add( EPSILON_FX, hMcMasa->totalLfEne[i] ), &hMasa->data.lfeToTotalEnergyRatio_e[i] ) ); // hMasa->data.lfeToTotalEnergyRatio_e[i] hMasa->data.lfeToTotalEnergyRatio_e[i] = add( sub( hMcMasa->lfeLfEne_e[i], hMcMasa->totalLfEne_e[i] ), hMasa->data.lfeToTotalEnergyRatio_e[i] ); move32(); move16(); @@ -735,18 +733,18 @@ void ivas_mcmasa_enc_fx( move16(); } - hQMeta->q_direction[0].band_data[i].azimuth_fx[j] = azimuth_m_values_fx[j][i]; + hQMeta->q_direction[0].band_data[i].azimuth_fx[j] = azimuth_m_values_fx[j][i]; // Q22 move32(); - hQMeta->q_direction[0].band_data[i].elevation_fx[j] = elevation_m_values_fx[j][i]; + hQMeta->q_direction[0].band_data[i].elevation_fx[j] = elevation_m_values_fx[j][i]; // Q22 move32(); - hQMeta->q_direction[0].band_data[i].energy_ratio_fx[j] = energyRatio_fx[k][i]; + hQMeta->q_direction[0].band_data[i].energy_ratio_fx[j] = energyRatio_fx[k][i]; // Q30 move32(); hQMeta->q_direction[0].band_data[i].distance[j] = fixedDistance; move16(); IF( hQMeta->surcoh_band_data != NULL ) { - hQMeta->q_direction[0].coherence_band_data[i].spread_coherence[j] = (UWord8) round_fx( Mpy_32_32( spreadCoherence_fx[j][i], L_shl( UINT8_MAX, Q16 ) ) ); // Q0 + hQMeta->q_direction[0].coherence_band_data[i].spread_coherence[j] = (UWord8) round_fx( Mpy_32_32( spreadCoherence_fx[j][i], L_shl( UINT8_MAX, Q17 ) ) ); // Q0 hQMeta->surcoh_band_data[i].surround_coherence[j] = (UWord8) round_fx( Mpy_32_32( surroundingCoherence_fx[k][i], L_shl( UINT8_MAX, Q16 ) ) ); // Q0 move16(); move16(); @@ -761,11 +759,11 @@ void ivas_mcmasa_enc_fx( { FOR( j = 0; j < nBlocks; j++ ) { - hQMeta->q_direction[0].band_data[i].azimuth_fx[j] = 0; + hQMeta->q_direction[0].band_data[i].azimuth_fx[j] = 0; // Q22 move32(); - hQMeta->q_direction[0].band_data[i].elevation_fx[j] = 0; + hQMeta->q_direction[0].band_data[i].elevation_fx[j] = 0; // Q22 move32(); - hQMeta->q_direction[0].band_data[i].energy_ratio_fx[j] = 0; + hQMeta->q_direction[0].band_data[i].energy_ratio_fx[j] = 0; // Q30 move32(); hQMeta->q_direction[0].band_data[i].distance[j] = 0; move16(); @@ -805,7 +803,7 @@ void ivas_mcmasa_enc_fx( i = 0; move16(); test(); - WHILE( LT_16( i, nBlocks ) && hQMeta->all_coherence_zero ) + WHILE( ( i < nBlocks ) && hQMeta->all_coherence_zero ) { test(); j = 0; @@ -814,7 +812,7 @@ void ivas_mcmasa_enc_fx( WHILE( LT_16( j, nBands ) && hQMeta->all_coherence_zero ) { test(); - IF( GT_32( spreadCoherence_fx[i][j], MASA_COHERENCE_THRESHOLD_FX ) ) + IF( GT_32( spreadCoherence_fx[i][j], MASA_COHERENCE_THRESHOLD_FX >> 1 ) ) { hQMeta->all_coherence_zero = 0; move16(); @@ -873,11 +871,11 @@ void ivas_mcmasa_enc_fx( void ivas_mcmasa_param_est_enc_fx( MCMASA_ENC_HANDLE hMcMasa, /* i : McMASA encoder structure */ MASA_ENCODER_HANDLE hMasa, /* i : MASA encoder structure */ - Word32 *data_f[], /* i : Audio frame in MC-format */ + Word32 *data_f[], /* i : Audio frame in MC-format Q(q_inp) */ Word32 elevation_m_values_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], /* o : Estimated elevation Q22 */ Word32 azimuth_m_values_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], /* o : Estimated azimuth Q22 */ Word32 energyRatio_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], /* o : Estimated direct-to-total ratio Q31 */ - Word32 spreadCoherence_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], /* o : Estimated spread coherence Q31 */ + Word32 spreadCoherence_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], /* o : Estimated spread coherence Q30 */ Word32 surroundingCoherence_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], /* o : Estimated surround coherence Q31 */ const Word16 input_frame, /* i : Input frame size */ const Word16 nchan_inp, /* i : Number of input channels */ @@ -904,13 +902,13 @@ void ivas_mcmasa_param_est_enc_fx( Word32 intensity_even_real_fx[DIRAC_NUM_DIMS][MASA_FREQUENCY_BANDS]; Word32 direction_vector_fx[DIRAC_NUM_DIMS][MASA_FREQUENCY_BANDS]; Word32 diffuseness_vector_fx[MASA_FREQUENCY_BANDS]; - Word32 vertical_diffuseness_vector_fx[MASA_FREQUENCY_BANDS]; - Word32 diffuseness_m_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS]; + Word32 vertical_diffuseness_vector_fx[MASA_FREQUENCY_BANDS]; // q_vdv + Word32 diffuseness_m_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS]; // diffuseness_e Word16 diffuseness_e[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS]; - Word32 coherentEnergyRatio_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS]; + Word32 coherentEnergyRatio_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS]; // coherentEnergyRatio_e Word16 coherentEnergyRatio_e[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS]; Word16 band_m_idx, block_m_idx; - Word32 renormalization_factor_diff_fx[MASA_FREQUENCY_BANDS]; + Word32 renormalization_factor_diff_fx[MASA_FREQUENCY_BANDS]; // renormalization_factor_diff_e Word16 renormalization_factor_diff_e[MASA_FREQUENCY_BANDS]; Word32 norm_tmp_fx; Word16 mrange[2], brange[2]; @@ -918,7 +916,7 @@ void ivas_mcmasa_param_est_enc_fx( CovarianceMatrix COVls[MASA_FREQUENCY_BANDS]; Word32 absCOVls_fx[MCMASA_MAX_ANA_CHANS][MCMASA_MAX_ANA_CHANS]; Word16 absCOVls_e[MCMASA_MAX_ANA_CHANS][MCMASA_MAX_ANA_CHANS]; - Word32 lsEnergy_fx[MCMASA_MAX_ANA_CHANS]; + Word32 lsEnergy_fx[MCMASA_MAX_ANA_CHANS]; // lsEnergy_e Word16 lsEnergy_e[MCMASA_MAX_ANA_CHANS]; Word32 lsEnergySum_fx, maxEne_fx; Word16 lsEnergySum_e = 0, maxEne_e; @@ -929,15 +927,15 @@ void ivas_mcmasa_param_est_enc_fx( Word16 i1, i2, i3; Word32 angleDist_fx, minAngleDist_fx; Word32 currentAzi_fx; - Word32 lsEnergyRelation_fx; + Word32 lsEnergyRelation_fx; // lsEnergyRelation_e Word16 lsEnergyRelation_e; - Word32 tempLsEnergyRelation_fx; + Word32 tempLsEnergyRelation_fx; // tempLsEnergyRelation_e Word16 tempLsEnergyRelation_e; Word32 stereoness_fx, cohwideness_fx, spreadCoh_fx; Word32 stereoRatio_fx, cohPanRatio_fx; Word32 stereoCoh_fx, cohPanCoh_fx, cohRatio_fx; Word16 stereoCoh_e, cohPanCoh_e, spreadCoh_e, stereoness_e; - Word32 renormalization_factor_coh_fx[MASA_FREQUENCY_BANDS]; + Word32 renormalization_factor_coh_fx[MASA_FREQUENCY_BANDS]; // renormalization_factor_coh_e Word16 renormalization_factor_coh_e[MASA_FREQUENCY_BANDS]; Word16 surroundingCoherence_e[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS]; Word16 numAnalysisChannels; @@ -967,24 +965,24 @@ void ivas_mcmasa_param_est_enc_fx( IF( hMcMasa->combineRatios ) { /* Need to initialize renormalization_factors, and variables to be normalized */ - set_zero_fx( renormalization_factor_diff_fx, hMcMasa->nbands ); + set_zero_fx( renormalization_factor_diff_fx, hMcMasa->nbands ); // renormalization_factor_diff_e set16_fx( renormalization_factor_diff_e, 0, hMcMasa->nbands ); - set_zero_fx( &diffuseness_m_fx[0][0], MASA_FREQUENCY_BANDS * MAX_PARAM_SPATIAL_SUBFRAMES ); + set_zero_fx( &diffuseness_m_fx[0][0], MASA_FREQUENCY_BANDS * MAX_PARAM_SPATIAL_SUBFRAMES ); // diffuseness_e set16_fx( &diffuseness_e[0][0], 31, MASA_FREQUENCY_BANDS * MAX_PARAM_SPATIAL_SUBFRAMES ); - set_zero_fx( renormalization_factor_coh_fx, hMcMasa->nbands ); + set_zero_fx( renormalization_factor_coh_fx, hMcMasa->nbands ); // renormalization_factor_coh_e set16_fx( renormalization_factor_coh_e, 31, hMcMasa->nbands ); - set_zero_fx( surroundingCoherence_fx[0], hMcMasa->nbands ); + set_zero_fx( surroundingCoherence_fx[0], hMcMasa->nbands ); // surroundingCoherence_e set16_fx( &surroundingCoherence_e[0][0], 31, MASA_FREQUENCY_BANDS * MAX_PARAM_SPATIAL_SUBFRAMES ); - set_zero_fx( coherentEnergyRatio_fx[0], hMcMasa->nbands ); + set_zero_fx( coherentEnergyRatio_fx[0], hMcMasa->nbands ); // coherentEnergyRatio_e set16_fx( &coherentEnergyRatio_e[0][0], 0, MASA_FREQUENCY_BANDS * MAX_PARAM_SPATIAL_SUBFRAMES ); } /* Copy current frame to memory for delay compensation */ FOR( i = 0; i < numAnalysisChannels; i++ ) { - pcm_in[i] = data_f[i]; - p_Chnl_RealBuffer_fx[i] = &Chnl_RealBuffer_fx[i][0]; - p_Chnl_ImagBuffer_fx[i] = &Chnl_ImagBuffer_fx[i][0]; + pcm_in[i] = data_f[i]; // q_inp + p_Chnl_RealBuffer_fx[i] = &Chnl_RealBuffer_fx[i][0]; // q_inp + p_Chnl_ImagBuffer_fx[i] = &Chnl_ImagBuffer_fx[i][0]; // q_inp } /* initialising energy_fx */ @@ -992,7 +990,7 @@ void ivas_mcmasa_param_est_enc_fx( { FOR( i = 0; i < MASA_FREQUENCY_BANDS; i++ ) { - hMasa->data.energy_fx[block_m_idx][i] = 0; + hMasa->data.energy_fx[block_m_idx][i] = 0; // hMasa->data.energy_e move32(); hMasa->data.energy_e[block_m_idx][i] = 31; move16(); @@ -1024,8 +1022,8 @@ void ivas_mcmasa_param_est_enc_fx( { FOR( j = 0; j < numAnalysisChannels; j++ ) { - set_zero_fx( COVls[i].xr_fx[j], numAnalysisChannels ); - set_zero_fx( COVls[i].xi_fx[j], numAnalysisChannels ); + set_zero_fx( COVls[i].xr_fx[j], numAnalysisChannels ); // COVls[i].xr_e[j] + set_zero_fx( COVls[i].xi_fx[j], numAnalysisChannels ); // COVls[i].xi_e[j] set16_fx( COVls[i].xr_e[j], 0, numAnalysisChannels ); set16_fx( COVls[i].xi_e[j], 0, numAnalysisChannels ); } @@ -1094,21 +1092,21 @@ void ivas_mcmasa_param_est_enc_fx( /* Compute standard FOA */ /* W */ - v_add_32( Chnl_RealBuffer_fx[0], Chnl_RealBuffer_fx[1], Foa_RealBuffer_fx[0], num_freq_bins ); - v_add_32( Chnl_ImagBuffer_fx[0], Chnl_ImagBuffer_fx[1], Foa_ImagBuffer_fx[0], num_freq_bins ); + v_add_32( Chnl_RealBuffer_fx[0], Chnl_RealBuffer_fx[1], Foa_RealBuffer_fx[0], num_freq_bins ); // inp_q + v_add_32( Chnl_ImagBuffer_fx[0], Chnl_ImagBuffer_fx[1], Foa_ImagBuffer_fx[0], num_freq_bins ); // inp_q FOR( i = 2; i < numAnalysisChannels; i++ ) { - v_add_32( Chnl_RealBuffer_fx[i], Foa_RealBuffer_fx[0], Foa_RealBuffer_fx[0], num_freq_bins ); - v_add_32( Chnl_ImagBuffer_fx[i], Foa_ImagBuffer_fx[0], Foa_ImagBuffer_fx[0], num_freq_bins ); + v_add_32( Chnl_RealBuffer_fx[i], Foa_RealBuffer_fx[0], Foa_RealBuffer_fx[0], num_freq_bins ); // inp_q + v_add_32( Chnl_ImagBuffer_fx[i], Foa_ImagBuffer_fx[0], Foa_ImagBuffer_fx[0], num_freq_bins ); // inp_q } /* Y */ - v_multc_fixed( Chnl_RealBuffer_fx[0], hMcMasa->chnlToFoaMtx_fx[1][0], Foa_RealBuffer_fx[1], num_freq_bins ); - v_multc_fixed( Chnl_ImagBuffer_fx[0], hMcMasa->chnlToFoaMtx_fx[1][0], Foa_ImagBuffer_fx[1], num_freq_bins ); + v_multc_fixed( Chnl_RealBuffer_fx[0], hMcMasa->chnlToFoaMtx_fx[1][0], Foa_RealBuffer_fx[1], num_freq_bins ); // inp_q + v_multc_fixed( Chnl_ImagBuffer_fx[0], hMcMasa->chnlToFoaMtx_fx[1][0], Foa_ImagBuffer_fx[1], num_freq_bins ); // inp_q FOR( i = 1; i < numAnalysisChannels; i++ ) { - v_multc_acc_32_32( Chnl_RealBuffer_fx[i], hMcMasa->chnlToFoaMtx_fx[1][i], Foa_RealBuffer_fx[1], num_freq_bins ); - v_multc_acc_32_32( Chnl_ImagBuffer_fx[i], hMcMasa->chnlToFoaMtx_fx[1][i], Foa_ImagBuffer_fx[1], num_freq_bins ); + v_multc_acc_32_32( Chnl_RealBuffer_fx[i], hMcMasa->chnlToFoaMtx_fx[1][i], Foa_RealBuffer_fx[1], num_freq_bins ); // inp_q + v_multc_acc_32_32( Chnl_ImagBuffer_fx[i], hMcMasa->chnlToFoaMtx_fx[1][i], Foa_ImagBuffer_fx[1], num_freq_bins ); // inp_q } /* Z */ @@ -1120,49 +1118,49 @@ void ivas_mcmasa_param_est_enc_fx( } ELSE { - v_multc_fixed( Chnl_RealBuffer_fx[0], hMcMasa->chnlToFoaMtx_fx[2][0], Foa_RealBuffer_fx[2], num_freq_bins ); - v_multc_fixed( Chnl_ImagBuffer_fx[0], hMcMasa->chnlToFoaMtx_fx[2][0], Foa_ImagBuffer_fx[2], num_freq_bins ); + v_multc_fixed( Chnl_RealBuffer_fx[0], hMcMasa->chnlToFoaMtx_fx[2][0], Foa_RealBuffer_fx[2], num_freq_bins ); // inp_q + v_multc_fixed( Chnl_ImagBuffer_fx[0], hMcMasa->chnlToFoaMtx_fx[2][0], Foa_ImagBuffer_fx[2], num_freq_bins ); // inp_q FOR( i = 1; i < numAnalysisChannels; i++ ) { - v_multc_acc_32_32( Chnl_RealBuffer_fx[i], hMcMasa->chnlToFoaMtx_fx[2][i], Foa_RealBuffer_fx[2], num_freq_bins ); - v_multc_acc_32_32( Chnl_ImagBuffer_fx[i], hMcMasa->chnlToFoaMtx_fx[2][i], Foa_ImagBuffer_fx[2], num_freq_bins ); + v_multc_acc_32_32( Chnl_RealBuffer_fx[i], hMcMasa->chnlToFoaMtx_fx[2][i], Foa_RealBuffer_fx[2], num_freq_bins ); // inp_q + v_multc_acc_32_32( Chnl_ImagBuffer_fx[i], hMcMasa->chnlToFoaMtx_fx[2][i], Foa_ImagBuffer_fx[2], num_freq_bins ); // inp_q } } /* X */ - v_multc_fixed( Chnl_RealBuffer_fx[0], hMcMasa->chnlToFoaMtx_fx[3][0], Foa_RealBuffer_fx[3], num_freq_bins ); - v_multc_fixed( Chnl_ImagBuffer_fx[0], hMcMasa->chnlToFoaMtx_fx[3][0], Foa_ImagBuffer_fx[3], num_freq_bins ); + v_multc_fixed( Chnl_RealBuffer_fx[0], hMcMasa->chnlToFoaMtx_fx[3][0], Foa_RealBuffer_fx[3], num_freq_bins ); // inp_q + v_multc_fixed( Chnl_ImagBuffer_fx[0], hMcMasa->chnlToFoaMtx_fx[3][0], Foa_ImagBuffer_fx[3], num_freq_bins ); // inp_q FOR( i = 1; i < numAnalysisChannels; i++ ) { - v_multc_acc_32_32( Chnl_RealBuffer_fx[i], hMcMasa->chnlToFoaMtx_fx[3][i], Foa_RealBuffer_fx[3], num_freq_bins ); - v_multc_acc_32_32( Chnl_ImagBuffer_fx[i], hMcMasa->chnlToFoaMtx_fx[3][i], Foa_ImagBuffer_fx[3], num_freq_bins ); + v_multc_acc_32_32( Chnl_RealBuffer_fx[i], hMcMasa->chnlToFoaMtx_fx[3][i], Foa_RealBuffer_fx[3], num_freq_bins ); // inp_q + v_multc_acc_32_32( Chnl_ImagBuffer_fx[i], hMcMasa->chnlToFoaMtx_fx[3][i], Foa_ImagBuffer_fx[3], num_freq_bins ); // inp_q } /* Compute even FOA */ /* W */ - Copy32( Foa_RealBuffer_fx[0], FoaEven_RealBuffer_fx[0], num_freq_bins ); - Copy32( Foa_ImagBuffer_fx[0], FoaEven_ImagBuffer_fx[0], num_freq_bins ); + Copy32( Foa_RealBuffer_fx[0], FoaEven_RealBuffer_fx[0], num_freq_bins ); // inp_q + Copy32( Foa_ImagBuffer_fx[0], FoaEven_ImagBuffer_fx[0], num_freq_bins ); // inp_q /* Y */ - v_multc_fixed( Chnl_RealBuffer_fx[0], hMcMasa->chnlToFoaEvenMtx_fx[1][0], FoaEven_RealBuffer_fx[1], num_freq_bins ); - v_multc_fixed( Chnl_ImagBuffer_fx[0], hMcMasa->chnlToFoaEvenMtx_fx[1][0], FoaEven_ImagBuffer_fx[1], num_freq_bins ); + v_multc_fixed( Chnl_RealBuffer_fx[0], hMcMasa->chnlToFoaEvenMtx_fx[1][0], FoaEven_RealBuffer_fx[1], num_freq_bins ); // inp_q + v_multc_fixed( Chnl_ImagBuffer_fx[0], hMcMasa->chnlToFoaEvenMtx_fx[1][0], FoaEven_ImagBuffer_fx[1], num_freq_bins ); // inp_q FOR( i = 1; i < numAnalysisChannels; i++ ) { - v_multc_acc_32_32( Chnl_RealBuffer_fx[i], hMcMasa->chnlToFoaEvenMtx_fx[1][i], FoaEven_RealBuffer_fx[1], num_freq_bins ); - v_multc_acc_32_32( Chnl_ImagBuffer_fx[i], hMcMasa->chnlToFoaEvenMtx_fx[1][i], FoaEven_ImagBuffer_fx[1], num_freq_bins ); + v_multc_acc_32_32( Chnl_RealBuffer_fx[i], hMcMasa->chnlToFoaEvenMtx_fx[1][i], FoaEven_RealBuffer_fx[1], num_freq_bins ); // inp_q + v_multc_acc_32_32( Chnl_ImagBuffer_fx[i], hMcMasa->chnlToFoaEvenMtx_fx[1][i], FoaEven_ImagBuffer_fx[1], num_freq_bins ); // inp_q } /* Z (even setups are handled as horizontal) */ - set_zero_fx( FoaEven_RealBuffer_fx[2], num_freq_bins ); - set_zero_fx( FoaEven_ImagBuffer_fx[2], num_freq_bins ); + set_zero_fx( FoaEven_RealBuffer_fx[2], num_freq_bins ); // inp_q + set_zero_fx( FoaEven_ImagBuffer_fx[2], num_freq_bins ); // inp_q /* X */ - v_multc_fixed( Chnl_RealBuffer_fx[0], hMcMasa->chnlToFoaEvenMtx_fx[3][0], FoaEven_RealBuffer_fx[3], num_freq_bins ); - v_multc_fixed( Chnl_ImagBuffer_fx[0], hMcMasa->chnlToFoaEvenMtx_fx[3][0], FoaEven_ImagBuffer_fx[3], num_freq_bins ); + v_multc_fixed( Chnl_RealBuffer_fx[0], hMcMasa->chnlToFoaEvenMtx_fx[3][0], FoaEven_RealBuffer_fx[3], num_freq_bins ); // inp_q + v_multc_fixed( Chnl_ImagBuffer_fx[0], hMcMasa->chnlToFoaEvenMtx_fx[3][0], FoaEven_ImagBuffer_fx[3], num_freq_bins ); // inp_q FOR( i = 1; i < numAnalysisChannels; i++ ) { - v_multc_acc_32_32( Chnl_RealBuffer_fx[i], hMcMasa->chnlToFoaEvenMtx_fx[3][i], FoaEven_RealBuffer_fx[3], num_freq_bins ); - v_multc_acc_32_32( Chnl_ImagBuffer_fx[i], hMcMasa->chnlToFoaEvenMtx_fx[3][i], FoaEven_ImagBuffer_fx[3], num_freq_bins ); + v_multc_acc_32_32( Chnl_RealBuffer_fx[i], hMcMasa->chnlToFoaEvenMtx_fx[3][i], FoaEven_RealBuffer_fx[3], num_freq_bins ); // inp_q + v_multc_acc_32_32( Chnl_ImagBuffer_fx[i], hMcMasa->chnlToFoaEvenMtx_fx[3][i], FoaEven_ImagBuffer_fx[3], num_freq_bins ); // inp_q } /* Direction estimation */ @@ -1182,7 +1180,12 @@ void ivas_mcmasa_param_est_enc_fx( num_freq_bands, direction_vector_fx[0], direction_vector_fx[1], - direction_vector_fx[2], c_e ); + direction_vector_fx[2], c_e +#ifdef NONBE_IMPROVE_DIRAC_INTENSITY_PREC + , + NULL +#endif + ); /* Power and intensity estimation for diffuseness */ computeIntensityVector_enc_fx( @@ -1212,11 +1215,11 @@ void ivas_mcmasa_param_est_enc_fx( FOR( i = 0; i < DIRAC_NUM_DIMS; i++ ) { /* only real part needed */ - Copy32( intensity_even_real_fx[i], &( hMcMasa->buffer_intensity_real_fx[i][index - 1][0] ), num_freq_bands ); + Copy32( intensity_even_real_fx[i], &( hMcMasa->buffer_intensity_real_fx[i][index - 1][0] ), num_freq_bands ); // hMcMasa->buffer_intensity_real_q } hMcMasa->buffer_intensity_real_q[index - 1] = sub( shl( inp_q, 1 ), 31 ); move16(); - Copy32( reference_power_fx[ts], &( hMcMasa->buffer_energy_fx[( index - 1 ) * num_freq_bands] ), num_freq_bands ); + Copy32( reference_power_fx[ts], &( hMcMasa->buffer_energy_fx[( index - 1 ) * num_freq_bands] ), num_freq_bands ); // ref_e hMcMasa->buffer_energy_q[index - 1] = sub( Q31, ref_e ); move16(); @@ -1356,7 +1359,7 @@ void ivas_mcmasa_param_est_enc_fx( } } } - surrCoh_fx = L_shl( surrCoh_fx, surrCoh_e ); + surrCoh_fx = L_shl( surrCoh_fx, surrCoh_e ); // Q31 surrCoh_e = 0; move16(); surrCoh_fx = Mult_32_32( surrCoh_fx, surrCoh_fx ); @@ -1526,18 +1529,18 @@ void ivas_mcmasa_param_est_enc_fx( tempCoh_fx = BASOP_Util_Add_Mant32Exp( stereoness_fx, stereoness_e, L_negate( L_sub( cohwideness_fx, L_shl( 1, sub( 30, cohPanCoh_e ) ) ) ), cohPanCoh_e, &tempCoh_e ); IF( ( tempCoh_e < 0 ) ) { - tempCoh_fx = L_shl( tempCoh_fx, tempCoh_e ); + tempCoh_fx = L_shl( tempCoh_fx, tempCoh_e ); // Q31 tempCoh_e = 0; move16(); } IF( GT_32( tempCoh_fx, L_shl_sat( 1, sub( 30, tempCoh_e ) ) ) ) { - spreadCoh_fx = tempCoh_fx; + spreadCoh_fx = tempCoh_fx; // tempCoh_e move32(); } ELSE { - spreadCoh_fx = L_shl_sat( 1, sub( 30, tempCoh_e ) ); + spreadCoh_fx = L_shl_sat( 1, sub( 30, tempCoh_e ) ); // Q30 } spreadCoh_e = tempCoh_e; move16(); @@ -1545,21 +1548,21 @@ void ivas_mcmasa_param_est_enc_fx( } IF( ( spreadCoh_e < 0 ) ) { - spreadCoh_fx = L_shl( spreadCoh_fx, spreadCoh_e ); + spreadCoh_fx = L_shl( spreadCoh_fx, spreadCoh_e ); // Q31 spreadCoh_e = 0; move16(); } IF( ( GE_32( spreadCoh_fx, L_shl_sat( 1, sub( 31, spreadCoh_e ) ) ) ) ) { - spreadCoh_fx = L_shl_sat( 1, sub( 31, spreadCoh_e ) ); + spreadCoh_fx = L_shl_sat( 1, sub( 31, spreadCoh_e ) ); // Q31 } IF( ( spreadCoh_fx <= 0 ) ) { spreadCoh_fx = 0; move32(); } - spreadCoh_fx = L_shl( spreadCoh_fx, spreadCoh_e ); /*Q31*/ + spreadCoh_fx = L_shl( spreadCoh_fx, sub( spreadCoh_e, 1 ) ); /*Q30*/ /* Compute energy ratio tuning parameter */ lsEnergySum_fx = 0; @@ -1594,7 +1597,7 @@ void ivas_mcmasa_param_est_enc_fx( IF( GE_32( cohRatio_fx, ONE_IN_Q31 ) ) { - cohRatio_fx = ONE_IN_Q31; + cohRatio_fx = ONE_IN_Q31; // Q31 move32(); } IF( cohRatio_fx <= 0 ) @@ -1619,7 +1622,7 @@ void ivas_mcmasa_param_est_enc_fx( } /* Store values */ - spreadCoherence_fx[block_m_idx][band_m_idx] = spreadCoh_fx; /*Q31*/ + spreadCoherence_fx[block_m_idx][band_m_idx] = spreadCoh_fx; /*Q30*/ move32(); IF( hMcMasa->combineRatios ) @@ -1729,6 +1732,7 @@ void ivas_mcmasa_param_est_enc_fx( void ivas_mcmasa_dmx_modify_fx( const Word16 n_samples, /* i : input frame length in samples */ Word32 dmx_fx[][L_FRAME48k + NS2SA( 48000, IVAS_FB_ENC_DELAY_NS )], /* i/o: downmix signal to be transformed into another format Qx*/ + Word16 dmx_Q[], /* i/o : Q of the intput signal which is being transformed*/ const Word16 n_chnls_dmx_old, /* i : number of downmix channels in the old format Q0 */ const Word16 n_chnls_dmx_new ) /* i : number of downmix channels in the target format Q0*/ { @@ -1744,6 +1748,11 @@ void ivas_mcmasa_dmx_modify_fx( return; } + Word16 Q_min_1_2, Q_min_0_1_2; + + Q_min_1_2 = s_min( dmx_Q[1], dmx_Q[2] ); + Q_min_0_1_2 = s_min( dmx_Q[1], s_min( dmx_Q[2], dmx_Q[0] ) ); + IF( EQ_16( n_chnls_dmx_old, 1 ) ) { /* split mono energy into identical channels */ @@ -1770,14 +1779,24 @@ void ivas_mcmasa_dmx_modify_fx( IF( EQ_16( n_chnls_dmx_new, 1 ) ) { /* sum l and r */ - dmx_fx[0][i] = L_add( dmx_fx[1][i], dmx_fx[2][i] ); + dmx_fx[1][i] = L_shl( dmx_fx[1][i], sub( Q_min_1_2, dmx_Q[1] ) ); + dmx_fx[2][i] = L_shl( dmx_fx[2][i], sub( Q_min_1_2, dmx_Q[2] ) ); + move32(); + move32(); + + dmx_fx[0][i] = L_add( dmx_fx[1][i], dmx_fx[2][i] ); // dmx_q move32(); } ELSE IF( EQ_16( n_chnls_dmx_new, 3 ) ) { + dmx_fx[1][i] = L_shl( dmx_fx[1][i], sub( Q_min_1_2, dmx_Q[1] ) ); + dmx_fx[2][i] = L_shl( dmx_fx[2][i], sub( Q_min_1_2, dmx_Q[2] ) ); + move32(); + move32(); + dmx_fx[0][i] = L_shr( L_add( dmx_fx[1][i], dmx_fx[2][i] ), 1 ); - dmx_fx[1][i] = L_sub( dmx_fx[1][i], dmx_fx[0][i] ); - dmx_fx[2][i] = L_sub( dmx_fx[2][i], dmx_fx[0][i] ); + dmx_fx[1][i] = L_sub( dmx_fx[1][i], dmx_fx[0][i] ); // dmx_q + dmx_fx[2][i] = L_sub( dmx_fx[2][i], dmx_fx[0][i] ); // dmx_q move32(); move32(); move32(); @@ -1791,15 +1810,31 @@ void ivas_mcmasa_dmx_modify_fx( IF( EQ_16( n_chnls_dmx_new, 1 ) ) { /* sum all channels */ + + dmx_fx[0][i] = L_shl( dmx_fx[0][i], sub( Q_min_0_1_2, dmx_Q[1] ) ); + dmx_fx[1][i] = L_shl( dmx_fx[1][i], sub( Q_min_0_1_2, dmx_Q[1] ) ); + dmx_fx[2][i] = L_shl( dmx_fx[2][i], sub( Q_min_0_1_2, dmx_Q[2] ) ); + move32(); + move32(); + move32(); + dmx_fx[0][i] = L_add( L_add( dmx_fx[0][i], dmx_fx[1][i] ), dmx_fx[2][i] ); move32(); } ELSE IF( EQ_16( n_chnls_dmx_new, 2 ) ) { + + dmx_fx[0][i] = L_shl( dmx_fx[0][i], sub( Q_min_0_1_2, dmx_Q[1] ) ); + dmx_fx[1][i] = L_shl( dmx_fx[1][i], sub( Q_min_0_1_2, dmx_Q[1] ) ); + dmx_fx[2][i] = L_shl( dmx_fx[2][i], sub( Q_min_0_1_2, dmx_Q[2] ) ); + move32(); + move32(); + move32(); + /* mix center into sides */ dmx_fx[0][i] = Mpy_32_16_1( dmx_fx[0][i], INV_SQRT2_FX_Q15 ); - dmx_fx[1][i] = L_add( dmx_fx[1][i], dmx_fx[0][i] ); - dmx_fx[2][i] = L_add( dmx_fx[2][i], dmx_fx[0][i] ); + dmx_fx[1][i] = L_add( dmx_fx[1][i], dmx_fx[0][i] ); // dmx_q + dmx_fx[2][i] = L_add( dmx_fx[2][i], dmx_fx[0][i] ); // dmx_q move32(); move32(); move32(); @@ -1807,6 +1842,39 @@ void ivas_mcmasa_dmx_modify_fx( } } + // Q updation for different channels + + IF( EQ_16( n_chnls_dmx_old, 1 ) ) + { + /* split mono energy into identical channels */ + IF( EQ_16( n_chnls_dmx_new, 2 ) ) + { + dmx_Q[1] = dmx_Q[0]; + move16(); + dmx_Q[2] = dmx_Q[0]; + move16(); + } + } + ELSE IF( EQ_16( n_chnls_dmx_old, 2 ) ) + { + dmx_Q[0] = Q_min_1_2; + move16(); + dmx_Q[1] = Q_min_1_2; + move16(); + dmx_Q[2] = Q_min_1_2; + move16(); + } + ELSE IF( EQ_16( n_chnls_dmx_old, 3 ) ) + { + dmx_Q[0] = Q_min_0_1_2; + move16(); + dmx_Q[1] = Q_min_0_1_2; + move16(); + dmx_Q[2] = Q_min_0_1_2; + move16(); + } + + return; } @@ -1817,7 +1885,7 @@ void ivas_mcmasa_dmx_modify_fx( /* Compute downmix */ static void ivas_mcmasa_dmx_fx( MCMASA_ENC_HANDLE hMcMasa, - Word32 *data_fx[], + Word32 *data_fx[], // Q(31 - data_e) Word16 data_e, const Word16 input_frame, const Word16 nchan_transport, @@ -1875,7 +1943,7 @@ static void ivas_mcmasa_dmx_fx( FOR( i = 0; i < input_frame; i++ ) { - data_fx[0][i] = L_add( data_fx[0][i], data_fx[leftIndex][i] ); + data_fx[0][i] = L_add( data_fx[0][i], data_fx[leftIndex][i] ); // data_e move32(); data_fx[1][i] = L_add( data_fx[1][i], data_fx[rightIndex][i] ); move32(); @@ -1888,9 +1956,9 @@ static void ivas_mcmasa_dmx_fx( { dmx_c_fx = W_extract_h( W_mult_32_32( INV_SQRT2_FX, data_fx[2][i] ) ); move32(); - data_fx[0][i] = L_add( dmx_c_fx, data_fx[0][i] ); + data_fx[0][i] = L_add( dmx_c_fx, data_fx[0][i] ); // data_e move32(); - data_fx[1][i] = L_add( dmx_c_fx, data_fx[1][i] ); + data_fx[1][i] = L_add( dmx_c_fx, data_fx[1][i] ); // data_e move32(); } } @@ -1954,10 +2022,10 @@ static void ivas_mcmasa_dmx_fx( FOR( j = 0; j < nchan_transport; j++ ) { - data_fx[j][i] = Mpy_32_32( instEQ_fx, data_fx[j][i] ); + data_fx[j][i] = Mpy_32_32( instEQ_fx, data_fx[j][i] ); // data_e + instEQ_e - 31 move32(); move32(); - data_fx[j][i] = L_shl( data_fx[j][i], instEQ_e ); + data_fx[j][i] = L_shl( data_fx[j][i], instEQ_e ); // data_e + 2*instEQ_e - 31 } } @@ -2138,8 +2206,8 @@ static void computeVerticalDiffuseness_fx( return; } static void computeEvenLayout_fx( - const Word32 *ls_azimuth, - Word32 *ls_azimuth_even, + const Word32 *ls_azimuth, // Q22 + Word32 *ls_azimuth_even, // Q22 const Word16 numChannels ) { Word16 i; @@ -2208,7 +2276,7 @@ static void computeEvenLayout_fx( } static void computeLfeEnergy_fx( MCMASA_ENC_HANDLE hMcMasa, - Word32 *data_fx[], + Word32 *data_fx[], // q_inp const Word16 input_frame, Word16 q_inp ) { @@ -2229,8 +2297,8 @@ static void computeLfeEnergy_fx( IF( hMcMasa->separateChannelEnabled ) { - Copy32( data_fx[lfeChannelIndex], &( hMcMasa->delay_buffer_lfe[0][hMcMasa->num_samples_delay_comp - hMcMasa->offset_comp] ), hMcMasa->offset_comp ); - Copy32( data_fx[separateChannelIndex], &( hMcMasa->delay_buffer_lfe[1][hMcMasa->num_samples_delay_comp - hMcMasa->offset_comp] ), hMcMasa->offset_comp ); + Copy32( data_fx[lfeChannelIndex], &( hMcMasa->delay_buffer_lfe[0][hMcMasa->num_samples_delay_comp - hMcMasa->offset_comp] ), hMcMasa->offset_comp ); // q_inp + Copy32( data_fx[separateChannelIndex], &( hMcMasa->delay_buffer_lfe[1][hMcMasa->num_samples_delay_comp - hMcMasa->offset_comp] ), hMcMasa->offset_comp ); // q_inp } ELSE { @@ -2252,10 +2320,10 @@ static void computeLfeEnergy_fx( Word32 delayedInputSignal[2][L_FRAME48k]; Word32 lowPassSignal[2][L_FRAME48k]; - Copy32( &( hMcMasa->delay_buffer_lfe[0][0] ), &( delayedInputSignal[0][0] ), hMcMasa->num_slots_delay_comp * l_ts ); - Copy32( data_fx[lfeChannelIndex] + hMcMasa->offset_comp, &( delayedInputSignal[0][hMcMasa->num_slots_delay_comp * l_ts] ), ( MDFT_NO_COL_MAX - hMcMasa->num_slots_delay_comp ) * l_ts ); - Copy32( &( hMcMasa->delay_buffer_lfe[1][0] ), &( delayedInputSignal[1][0] ), hMcMasa->num_slots_delay_comp * l_ts ); - Copy32( data_fx[separateChannelIndex] + hMcMasa->offset_comp, &( delayedInputSignal[1][hMcMasa->num_slots_delay_comp * l_ts] ), ( MDFT_NO_COL_MAX - hMcMasa->num_slots_delay_comp ) * l_ts ); + Copy32( &( hMcMasa->delay_buffer_lfe[0][0] ), &( delayedInputSignal[0][0] ), hMcMasa->num_slots_delay_comp * l_ts ); // q_inp + Copy32( data_fx[lfeChannelIndex] + hMcMasa->offset_comp, &( delayedInputSignal[0][hMcMasa->num_slots_delay_comp * l_ts] ), ( MDFT_NO_COL_MAX - hMcMasa->num_slots_delay_comp ) * l_ts ); // q_inp + Copy32( &( hMcMasa->delay_buffer_lfe[1][0] ), &( delayedInputSignal[1][0] ), hMcMasa->num_slots_delay_comp * l_ts ); // q_inp + Copy32( data_fx[separateChannelIndex] + hMcMasa->offset_comp, &( delayedInputSignal[1][hMcMasa->num_slots_delay_comp * l_ts] ), ( MDFT_NO_COL_MAX - hMcMasa->num_slots_delay_comp ) * l_ts ); // q_inp lowpassCoef = L_shl( div_w( 1, (Word32) hMcMasa->ringBufferSize ), Q6 ); // Q.37(31+6) @@ -2342,8 +2410,8 @@ static void computeLfeEnergy_fx( IF( hMcMasa->separateChannelEnabled ) { - Copy32( data_fx[lfeChannelIndex] + ( input_frame - hMcMasa->num_samples_delay_comp + hMcMasa->offset_comp ), &( hMcMasa->delay_buffer_lfe[0][0] ), sub( hMcMasa->num_samples_delay_comp, hMcMasa->offset_comp ) ); - Copy32( data_fx[separateChannelIndex] + ( input_frame - hMcMasa->num_samples_delay_comp + hMcMasa->offset_comp ), &( hMcMasa->delay_buffer_lfe[1][0] ), sub( hMcMasa->num_samples_delay_comp, hMcMasa->offset_comp ) ); + Copy32( data_fx[lfeChannelIndex] + ( input_frame - hMcMasa->num_samples_delay_comp + hMcMasa->offset_comp ), &( hMcMasa->delay_buffer_lfe[0][0] ), sub( hMcMasa->num_samples_delay_comp, hMcMasa->offset_comp ) ); // q_in + Copy32( data_fx[separateChannelIndex] + ( input_frame - hMcMasa->num_samples_delay_comp + hMcMasa->offset_comp ), &( hMcMasa->delay_buffer_lfe[1][0] ), sub( hMcMasa->num_samples_delay_comp, hMcMasa->offset_comp ) ); // q_in } return; diff --git a/lib_enc/ivas_mct_core_enc.c b/lib_enc/ivas_mct_core_enc_fx.c similarity index 87% rename from lib_enc/ivas_mct_core_enc.c rename to lib_enc/ivas_mct_core_enc_fx.c index db8ca015496e2fac9d6fba4059527925140ac78e..71515571d02cb289ea4d7438f1370decbcff0162 100644 --- a/lib_enc/ivas_mct_core_enc.c +++ b/lib_enc/ivas_mct_core_enc_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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,14 +34,11 @@ #include #include "options.h" #include "cnst.h" -#include "prot.h" -#include "ivas_prot.h" +#include "prot_fx.h" #include "rom_com.h" #include "wmc_auto.h" -#include "prot_fx.h" #include "prot_fx_enc.h" #include "ivas_prot_fx.h" -#include "prot_fx.h" #include @@ -78,11 +75,11 @@ static void FindChannelRatio_fx( IF( NE_32( sts[i]->mct_chan_mode, MCT_CHAN_MODE_IGNORE ) ) { // sum_nrg += nrg[i]; - sum_nrg = BASOP_Util_Add_Mant32Exp( sum_nrg, sum_e, nrg[i], nrg_e[i], &sum_e ); + sum_nrg = BASOP_Util_Add_Mant32Exp( sum_nrg, sum_e, nrg[i], nrg_e[i], &sum_e ); // sum_e } } // sum_nrg = 1.0f / max( sum_nrg, EPSILON ); - sum_nrg = BASOP_Util_Divide3232_Scale( ONE_IN_Q31, L_add_sat( sum_nrg, EPSILON_FX ), &inv_e ); + sum_nrg = BASOP_Util_Divide3232_Scale( ONE_IN_Q31, L_add_sat( sum_nrg, EPSILON_FX ), &inv_e ); // inv_e inv_e = add( inv_e, sub( 0, sum_e ) ); FOR( i = 0; i < nChannels; i++ ) @@ -137,7 +134,7 @@ static void AdjustChannelRatios_fx( move32(); FOR( i = 0; i < nChannels; i++ ) { - sum_ratio = L_add( sum_ratio, temp_brs[i] ); + sum_ratio = L_add( sum_ratio, temp_brs[i] ); // Q0 } FOR( i = 0; i < nChannels; i++ ) { @@ -145,7 +142,7 @@ static void AdjustChannelRatios_fx( // force_ch_bit_ratios[i] = min( BITRATE_MCT_RATIO_RANGE - 1, max( 1, (uint16_t) ( BITRATE_MCT_RATIO_RANGE * cur_ratio + 0.5f ) ) ); cur_ratio = BASOP_Util_Divide3232_Scale( temp_brs[i], sum_ratio, &cur_ratio_e ); - cur_ratio = shr_r( cur_ratio, sub( 11, cur_ratio_e ) ); + cur_ratio = shr_r( cur_ratio, sub( 11, cur_ratio_e ) ); // Q11 force_ch_bit_ratios[i] = s_min( BITRATE_MCT_RATIO_RANGE - 1, s_max( 1, (UWord16) ( cur_ratio ) ) ); move16(); } @@ -207,8 +204,8 @@ static void AdjustChannelRatios_fx( // cur_ratio = chBitRatios[i] / sum_ratio; // chBitRatios[i] = min( BITRATE_MCT_RATIO_RANGE - 1, max( 1, (uint16_t) ( BITRATE_MCT_RATIO_RANGE * cur_ratio + 0.5f ) ) ); - cur_ratio = div_s( chBitRatios[i], extract_l( sum_ratio ) ); - chBitRatios[i] = s_min( BITRATE_MCT_RATIO_RANGE - 1, s_max( 1, (UWord16) mult_r( BITRATE_MCT_RATIO_RANGE, cur_ratio ) ) ); + cur_ratio = div_s( chBitRatios[i], extract_l( sum_ratio ) ); // Q15 + chBitRatios[i] = s_min( BITRATE_MCT_RATIO_RANGE - 1, s_max( 1, (UWord16) mult_r( BITRATE_MCT_RATIO_RANGE, cur_ratio ) ) ); // Q0 move16(); } @@ -237,16 +234,17 @@ void ivas_mct_core_enc_fx( Word16 nCPE; Word32 *orig_spectrum_fx[MCT_MAX_CHANNELS][2]; /* Pointers to MDCT output for a short block (L/R) */ Word32 powerSpec_fx[MCT_MAX_CHANNELS][L_FRAME48k]; + Word16 exp_powerSpec[MCT_MAX_CHANNELS][N_MAX + L_MDCT_OVLP_MAX]; Word32 mdst_fx; Word32 powerSpecMsInv_long_fx[MCT_MAX_CHANNELS][L_FRAME48k]; /* MS inv power spectrum, also inverse MDST spectrum */ Word32 *powerSpecMsInv_fx[MCT_MAX_CHANNELS][2]; Word32 *inv_mdst_spectrum_fx[MCT_MAX_CHANNELS][2]; Word32 *inv_spectrum_fx[MCT_MAX_CHANNELS][2]; - Word32 *mdst_spectrum_fx[MCT_MAX_CHANNELS][2] = { NULL }; + Word32 *mdst_spectrum_fx[MCT_MAX_CHANNELS][2] = { { NULL } }; Word32 inv_spectrum_long_fx[MCT_MAX_CHANNELS][L_FRAME48k]; /* quantized MDCT spectrum, inv ms mask mdst spectrum, scratch for MS spectra in the MS decision */ Word16 total_side_bits; Word16 chBitRatios[MCT_MAX_CHANNELS]; - Word16 q_powSpec[MCT_MAX_CHANNELS], q_spec, q_origSpec, tmp_s; + Word16 q_powSpec[MCT_MAX_CHANNELS], q_powerSpecMsInv[MCT_MAX_CHANNELS], q_spec, q_origSpec, tmp_s; Word16 tmp_q_powSpec[L_FRAME48k], tmp_q_powSpecInv[L_FRAME48k], *tmp_q_psi[2]; Word64 W_tmp; Encoder_State *sts[MCT_MAX_CHANNELS]; @@ -277,13 +275,15 @@ void ivas_mct_core_enc_fx( { set32_fx( powerSpecMsInv_long_fx[ch], 0, L_FRAME48k ); q_powSpec[ch] = 0; + move16(); + set16_fx( exp_powerSpec[ch], 0, N_MAX + L_MDCT_OVLP_MAX ); } #endif // MSAN_FIX FOR( ch = 0; ch < nChannels; ch++ ) { set32_fx( inv_spectrum_long_fx[ch], 0, L_FRAME48k ); - set32_fx( powerSpec_fx[ch], 0, L_FRAME48k ); - set32_fx( powerSpecMsInv_long_fx[ch], 0, L_FRAME48k ); + set32_fx( powerSpec_fx[ch], 0, L_FRAME48k ); // tmp_q_powSpec + set32_fx( powerSpecMsInv_long_fx[ch], 0, L_FRAME48k ); // tmp_q_powSpecInv inv_mdst_spectrum_fx[ch][0] = powerSpecMsInv_fx[ch][0] = powerSpecMsInv_long_fx[ch]; inv_mdst_spectrum_fx[ch][1] = powerSpecMsInv_fx[ch][1] = powerSpecMsInv_long_fx[ch] + N_TCX10_MAX; @@ -310,7 +310,7 @@ void ivas_mct_core_enc_fx( mdst_spectrum_fx[i][0] = hMCT->p_mdst_spectrum_long_fx[cpe_id][ch]; mdst_spectrum_fx[i][1] = hMCT->p_mdst_spectrum_long_fx[cpe_id][ch] + N_TCX10_MAX; - orig_spectrum_fx[i][0] = hMCT->p_orig_spectrum_long_fx[cpe_id][ch]; + orig_spectrum_fx[i][0] = hMCT->p_orig_spectrum_long_fx[cpe_id][ch]; // q_origSpec orig_spectrum_fx[i][1] = hMCT->p_orig_spectrum_long_fx[cpe_id][ch] + N_TCX10_MAX; sp_aud_decision0[i] = hCPE[cpe_id]->hCoreCoder[0]->sp_aud_decision0; @@ -334,8 +334,21 @@ void ivas_mct_core_enc_fx( IF( switch_bw ) { +#ifdef FIX_USAN_ISSUES + IF( sts[ch_core]->hIGFEnc == NULL ) + { + initMdctStereoEncData_fx( hMCT->hBlockData[ch]->hStereoMdct, ivas_format, sts[ch_core]->element_mode, sts[ch_core]->element_brate, sts[ch_core]->bwidth, + sts[ch_core]->igf, NULL, 0 ); + } + ELSE + { + initMdctStereoEncData_fx( hMCT->hBlockData[ch]->hStereoMdct, ivas_format, sts[ch_core]->element_mode, sts[ch_core]->element_brate, sts[ch_core]->bwidth, + sts[ch_core]->igf, sts[ch_core]->hIGFEnc->igfData.igfInfo.grid, 0 ); + } +#else initMdctStereoEncData_fx( hMCT->hBlockData[ch]->hStereoMdct, ivas_format, sts[ch_core]->element_mode, sts[ch_core]->element_brate, sts[ch_core]->bwidth, sts[ch_core]->igf, sts[ch_core]->hIGFEnc->igfData.igfInfo.grid, 0 ); +#endif } IF( sts[ch_core]->igf ) @@ -434,15 +447,15 @@ void ivas_mct_core_enc_fx( FOR( i = 0; i < L_subframeTCX; i++ ) { W_tmp = W_mac_32_32( W_mult_32_32( mdst_spectrum_fx[ch][n][i], mdst_spectrum_fx[ch][n][i] ), sts[ch]->hTcxEnc->spectrum_fx[n][i], sts[ch]->hTcxEnc->spectrum_fx[n][i] ); - tmp_s = sub( W_norm( W_tmp ), 1 ); + tmp_s = W_norm( W_tmp ); W_tmp = W_shl( W_tmp, tmp_s ); - powerSpec_fx[ch][add( i, imult1616( n, L_subframeTCX ) )] = W_extract_h( W_tmp ); - tmp_q_powSpec[add( i, imult1616( n, L_subframeTCX ) )] = sub( add( imult1616( q_spec, 2 ), tmp_s ), 31 ); // Q = 2 * q_spec + 1 + tmp_s - 32 + powerSpec_fx[ch][( i + ( n * L_subframeTCX ) )] = W_extract_h( W_tmp ); + tmp_q_powSpec[( i + ( n * L_subframeTCX ) )] = sub( add( imult1616( q_spec, 2 ), tmp_s ), 31 ); // Q = 2 * q_spec + 1 + tmp_s - 32 move32(); move16(); W_tmp = W_mac_32_32( W_mult_32_32( inv_mdst_spectrum_fx[ch][n][i], inv_mdst_spectrum_fx[ch][n][i] ), inv_spectrum_fx[ch][n][i], inv_spectrum_fx[ch][n][i] ); - tmp_s = sub( W_norm( W_tmp ), 1 ); + tmp_s = W_norm( W_tmp ); W_tmp = W_shl( W_tmp, tmp_s ); powerSpecMsInv_fx[ch][n][i] = W_extract_h( W_tmp ); tmp_q_psi[n][i] = sub( add( imult1616( q_spec, 2 ), tmp_s ), 31 ); // Q = 2 * q_spec + 1 + tmp_s - 32 @@ -456,7 +469,7 @@ void ivas_mct_core_enc_fx( { /* power spectrum: MDCT^2 + MDST^2 */ W_tmp = W_mult_32_32( inv_spectrum_fx[ch][n][0], inv_spectrum_fx[ch][n][0] ); - tmp_s = sub( W_norm( W_tmp ), 1 ); + tmp_s = W_norm( W_tmp ); W_tmp = W_shl( W_tmp, tmp_s ); powerSpecMsInv_fx[ch][n][0] = W_extract_h( W_tmp ); tmp_q_psi[n][0] = sub( add( imult1616( q_spec, 2 ), tmp_s ), 31 ); // Q = 2 * q_spec + 1 + tmp_s - 32 @@ -468,7 +481,7 @@ void ivas_mct_core_enc_fx( mdst_fx = L_sub( inv_spectrum_fx[ch][n][i + 1], inv_spectrum_fx[ch][n][i - 1] ); /* An MDST estimate */ W_tmp = W_mac_32_32( W_mult_32_32( mdst_fx, mdst_fx ), inv_spectrum_fx[ch][n][i], inv_spectrum_fx[ch][n][i] ); - tmp_s = sub( W_norm( W_tmp ), 1 ); + tmp_s = W_norm( W_tmp ); W_tmp = W_shl( W_tmp, tmp_s ); powerSpecMsInv_fx[ch][n][i] = W_extract_h( W_tmp ); tmp_q_psi[n][i] = sub( add( imult1616( q_spec, 2 ), tmp_s ), 31 ); // Q = 2 * q_spec + 1 + tmp_s - 32 @@ -477,7 +490,7 @@ void ivas_mct_core_enc_fx( } W_tmp = W_mult_32_32( inv_spectrum_fx[ch][n][L_subframeTCX - 1], inv_spectrum_fx[ch][n][L_subframeTCX - 1] ); - tmp_s = sub( W_norm( W_tmp ), 1 ); + tmp_s = W_norm( W_tmp ); W_tmp = W_shl( W_tmp, tmp_s ); powerSpecMsInv_fx[ch][n][L_subframeTCX - 1] = W_extract_h( W_tmp ); tmp_q_psi[n][L_subframeTCX - 1] = sub( add( imult1616( q_spec, 2 ), tmp_s ), 31 ); // Q = 2 * q_spec + 1 + tmp_s - 32 @@ -487,7 +500,7 @@ void ivas_mct_core_enc_fx( /* power spectrum: MDCT^2 + MDST^2 */ W_tmp = W_mult_32_32( sts[ch]->hTcxEnc->spectrum_fx[n][0], sts[ch]->hTcxEnc->spectrum_fx[n][0] ); - tmp_s = sub( W_norm( W_tmp ), 1 ); + tmp_s = W_norm( W_tmp ); W_tmp = W_shl( W_tmp, tmp_s ); powerSpec_fx[ch][n * L_subframeTCX] = W_extract_h( W_tmp ); tmp_q_powSpec[n * L_subframeTCX] = sub( add( imult1616( q_spec, 2 ), tmp_s ), 31 ); // Q = 2 * q_spec + 1 + tmp_s - 32 @@ -496,22 +509,24 @@ void ivas_mct_core_enc_fx( FOR( i = 1; i < L_subframeTCX - 1; i++ ) { - mdst_fx = L_sub( L_shr( sts[ch]->hTcxEnc->spectrum_fx[n][i + 1], 1 ), L_shr( sts[ch]->hTcxEnc->spectrum_fx[n][i - 1], 1 ) ); /* An MDST estimate */ + mdst_fx = L_sub( L_shr( sts[ch]->hTcxEnc->spectrum_fx[n][i + 1], 1 ), L_shr( sts[ch]->hTcxEnc->spectrum_fx[n][i - 1], 1 ) ); /* An MDST estimate, Q = q_spec - 1 */ - W_tmp = W_mac_32_32( W_mult_32_32( mdst_fx, mdst_fx ), L_shr( sts[ch]->hTcxEnc->spectrum_fx[n][i], 1 ), L_shr( sts[ch]->hTcxEnc->spectrum_fx[n][i], 1 ) ); + W_tmp = W_mac_32_32( W_mult_32_32( mdst_fx, mdst_fx ), L_shr( sts[ch]->hTcxEnc->spectrum_fx[n][i], 1 ), L_shr( sts[ch]->hTcxEnc->spectrum_fx[n][i], 1 ) ); // Q = 2 * (q_spec - 1) + 1 tmp_s = W_norm( W_tmp ); W_tmp = W_shl( W_tmp, tmp_s ); - powerSpec_fx[ch][add( i, imult1616( n, L_subframeTCX ) )] = W_extract_h( W_tmp ); - tmp_q_powSpec[add( i, imult1616( n, L_subframeTCX ) )] = sub( add( imult1616( q_spec, 2 ), tmp_s ), 31 ); // Q = 2 * q_spec + 1 + tmp_s - 32 + + powerSpec_fx[ch][i + ( n * L_subframeTCX )] = W_extract_h( W_tmp ); + tmp_q_powSpec[i + ( n * L_subframeTCX )] = sub( add( imult1616( q_spec, 2 ), tmp_s ), 33 ); // Q = 2 * (q_spec - 1) + 1 + tmp_s - 32 + move32(); move16(); } W_tmp = W_mult_32_32( sts[ch]->hTcxEnc->spectrum_fx[n][L_subframeTCX - 1], sts[ch]->hTcxEnc->spectrum_fx[n][L_subframeTCX - 1] ); - tmp_s = sub( W_norm( W_tmp ), 1 ); + tmp_s = W_norm( W_tmp ); W_tmp = W_shl( W_tmp, tmp_s ); - powerSpec_fx[ch][add( sub( L_subframeTCX, 1 ), imult1616( n, L_subframeTCX ) )] = W_extract_h( W_tmp ); - tmp_q_powSpec[add( sub( L_subframeTCX, 1 ), imult1616( n, L_subframeTCX ) )] = sub( add( imult1616( q_spec, 2 ), tmp_s ), 31 ); // Q = 2 * q_spec + 1 + tmp_s - 32 + powerSpec_fx[ch][( ( L_subframeTCX - 1 ) + ( n * L_subframeTCX ) )] = W_extract_h( W_tmp ); + tmp_q_powSpec[( ( L_subframeTCX - 1 ) + ( n * L_subframeTCX ) )] = sub( add( imult1616( q_spec, 2 ), tmp_s ), 31 ); // Q = 2 * q_spec + 1 + tmp_s - 32 move32(); move16(); } @@ -519,31 +534,31 @@ void ivas_mct_core_enc_fx( /* Aligning the Q-factors */ { + q_powSpec[ch] = Q31; + move16(); + q_powerSpecMsInv[ch] = Q31; + move16(); /* NOTE: This logic has been added because using a constant headroom while computing `powSpec` and `powSpecMsInv` leads to significant precision loss, which results in poor quality. */ FOR( i = 0; i < L_FRAME48k; i++ ) { - if ( powerSpec_fx[ch][i] == 0 ) + IF( powerSpec_fx[ch][i] != 0 ) { - tmp_q_powSpec[i] = 63; + q_powSpec[ch] = s_min( q_powSpec[ch], add( tmp_q_powSpec[i], norm_l( powerSpec_fx[ch][i] ) ) ); move16(); } - if ( powerSpecMsInv_fx[ch][0][i] == 0 ) + IF( powerSpecMsInv_fx[ch][0][i] != 0 ) { - tmp_q_powSpecInv[i] = 63; + q_powerSpecMsInv[ch] = s_min( q_powerSpecMsInv[ch], add( tmp_q_powSpecInv[i], norm_l( powerSpecMsInv_fx[ch][0][i] ) ) ); move16(); } } - minimum_s( tmp_q_powSpec, L_FRAME48k, &q_powSpec[ch] ); - minimum_s( tmp_q_powSpecInv, L_FRAME48k, &tmp_s ); - q_powSpec[ch] = s_min( q_powSpec[ch], tmp_s ); - move16(); FOR( n = 0; n < nSubframes; n++ ) { FOR( i = 0; i < L_subframeTCX; i++ ) { - powerSpecMsInv_fx[ch][n][i] = L_shr( powerSpecMsInv_fx[ch][n][i], sub( tmp_q_psi[n][i], q_powSpec[ch] ) ); - powerSpec_fx[ch][add( i, imult1616( n, L_subframeTCX ) )] = L_shr( powerSpec_fx[ch][add( i, imult1616( n, L_subframeTCX ) )], sub( tmp_q_powSpec[i], q_powSpec[ch] ) ); + powerSpecMsInv_fx[ch][n][i] = L_shr( powerSpecMsInv_fx[ch][n][i], sub( tmp_q_psi[n][i], q_powerSpecMsInv[ch] ) ); + powerSpec_fx[ch][( i + ( n * L_subframeTCX ) )] = L_shr( powerSpec_fx[ch][( i + ( n * L_subframeTCX ) )], sub( tmp_q_powSpec[i + ( n * L_subframeTCX )], q_powSpec[ch] ) ); move32(); move32(); } @@ -601,7 +616,7 @@ void ivas_mct_core_enc_fx( { IF( hMCT->currBlockDataCnt > 0 ) { - mctStereoIGF_enc_fx( hMCT, sts, orig_spectrum_fx, q_origSpec, powerSpec_fx, powerSpecMsInv_fx, q_powSpec, inv_spectrum_fx, sp_aud_decision0 ); + mctStereoIGF_enc_fx( hMCT, sts, orig_spectrum_fx, q_origSpec, powerSpec_fx, q_powSpec, powerSpecMsInv_fx, q_powerSpecMsInv, inv_spectrum_fx, sp_aud_decision0 ); } ELSE { @@ -636,8 +651,13 @@ void ivas_mct_core_enc_fx( FOR( n = 0; n < nSubframes; n++ ) { q_spectrum = sub( 31, st->hTcxEnc->spectrum_e[n] ); + set16_fx( exp_powerSpec[ch], sub( Q31, q_powSpec[ch] ), N_MAX + L_MDCT_OVLP_MAX ); - ProcessIGF_ivas_fx( st, st->hTcxEnc->spectrum_fx[n], orig_spectrum_fx[ch][n], &q_spectrum, &powerSpec_fx[ch][n * L_subframeTCX], &q_powSpec[ch], st->core == TCX_20_CORE, n, sp_aud_decision0[ch], 0 ); +#ifndef MSAN_FIX + ProcessIGF_ivas_fx( st, st->hTcxEnc->spectrum_fx[n], orig_spectrum_fx[ch][n], &q_spectrum, &powerSpec_fx[ch][n * L_subframeTCX], &exp_powerSpec[ch][n * L_subframeTCX], st->core == TCX_20_CORE, n, sp_aud_decision0[ch], 0 ); +#else + ProcessIGF_ivas_fx( st, L_FRAME48k, st->hTcxEnc->spectrum_fx[n], orig_spectrum_fx[ch][n], &q_spectrum, &powerSpec_fx[ch][n * L_subframeTCX], &exp_powerSpec[ch][n * L_subframeTCX], st->core == TCX_20_CORE, n, sp_aud_decision0[ch], 0 ); +#endif st->hIGFEnc->spec_be_igf_e = sub( 31, q_origSpec ); st->hTcxEnc->spectrum_e[n] = sub( 31, q_spectrum ); diff --git a/lib_enc/ivas_mct_enc.c b/lib_enc/ivas_mct_enc_fx.c similarity index 86% rename from lib_enc/ivas_mct_enc.c rename to lib_enc/ivas_mct_enc_fx.c index 98bf7a3a5ca0ba88e91ba6f3a09c81fe1a3f8910..56f5e44db890533036f9f12cb5adae4d75c8d495 100644 --- a/lib_enc/ivas_mct_enc.c +++ b/lib_enc/ivas_mct_enc_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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,10 +36,8 @@ #include #include "cnst.h" #include "ivas_cnst.h" -#include "prot.h" -#include "ivas_prot.h" -#include "wmc_auto.h" #include "prot_fx.h" +#include "wmc_auto.h" #include "ivas_prot_fx.h" #include "prot_fx_enc.h" #include "rom_com.h" @@ -58,7 +56,7 @@ static ivas_error ivas_mc_enc_reconfig_fx( Encoder_Struct *st_ivas, const Word16 * Set hMCT handle parameters *-------------------------------------------------------------------*/ -static void set_mct_enc_params( +static void set_mct_enc_params_fx( MCT_ENC_HANDLE hMCT, /* i/o: MCT encoder structure */ const Word32 ivas_total_brate, /* i : IVAS total bitrate */ const IVAS_FORMAT ivas_format, /* i : IVAS_format */ @@ -79,7 +77,7 @@ static void set_mct_enc_params( FOR( n = 0; n < MCT_MAX_CHANNELS; n++ ) { - set32_fx( hMCT->lastxCorrMatrix_fx[n], 0, MCT_MAX_CHANNELS ); + set32_fx( hMCT->lastxCorrMatrix_fx[n], 0, MCT_MAX_CHANNELS ); // hMCT->lastxCorrMatrix_e } hMCT->lastxCorrMatrix_e = 0; move16(); @@ -129,7 +127,7 @@ static void map_input_to_cpe_channels_ivas_fx( FOR( n = 0; n < LFE_CHANNEL - 1; n++ ) { - pdata[i] = data[n]; + pdata[i] = data[n]; // Qx i = add( i, 1 ); } test(); @@ -138,7 +136,7 @@ static void map_input_to_cpe_channels_ivas_fx( { FOR( n = LFE_CHANNEL + 1; n < nchan_transport; n++ ) { - pdata[i] = data[n]; + pdata[i] = data[n]; // Qx i = add( i, 1 ); } pdata[i] = data[LFE_CHANNEL - 1]; @@ -147,7 +145,7 @@ static void map_input_to_cpe_channels_ivas_fx( { FOR( ; n < nchan_transport; n++ ) { - pdata[i] = data[n]; + pdata[i] = data[n]; // Qx i = add( i, 1 ); } } @@ -282,45 +280,54 @@ ivas_error ivas_mct_enc_fx( } } -#ifdef IVAS_FLOAT_FIXED_CONVERSIONS // Float to Fixed, to be removed Word16 q_spec = Q31; Word16 q_origSpec = Q31; - Word16 q_com = Q31, q_com_spec = Q31; move16(); move16(); Word16 length, ch, nCPE; - nCPE = ( hMCT->nchan_out_woLFE % 2 ) == 0 ? ( hMCT->nchan_out_woLFE / 2 ) : ( hMCT->nchan_out_woLFE / 2 ) + 1; + IF( ( hMCT->nchan_out_woLFE % 2 ) == 0 ) + { + nCPE = idiv1616( hMCT->nchan_out_woLFE, 2 ); + } + ELSE + { + nCPE = add( idiv1616( hMCT->nchan_out_woLFE, 2 ), 1 ); + } - for ( cpe_id = 0; cpe_id < nCPE; cpe_id++ ) + FOR( cpe_id = 0; cpe_id < nCPE; cpe_id++ ) { - for ( ch = 0; ch < CPE_CHANNELS; ch++ ) + FOR( ch = 0; ch < CPE_CHANNELS; ch++ ) { - if ( st_ivas->hCPE[cpe_id]->hCoreCoder[ch]->mct_chan_mode == MCT_CHAN_MODE_IGNORE ) + Word16 norm; + IF( EQ_32( st_ivas->hCPE[cpe_id]->hCoreCoder[ch]->mct_chan_mode, MCT_CHAN_MODE_IGNORE ) ) { - continue; + CONTINUE; } - length = st_ivas->hCPE[cpe_id]->hCoreCoder[ch]->hTcxEnc->L_frameTCX / ( ( st_ivas->hCPE[cpe_id]->hCoreCoder[ch]->hTcxEnc->tcxMode == TCX_20 ) ? 1 : NB_DIV ); - if ( st_ivas->hCPE[cpe_id]->hCoreCoder[ch]->last_core == ACELP_CORE ) + + // length = st_ivas->hCPE[cpe_id]->hCoreCoder[ch]->hTcxEnc->L_frameTCX / ( ( st_ivas->hCPE[cpe_id]->hCoreCoder[ch]->hTcxEnc->tcxMode == TCX_20 ) ? 1 : NB_DIV ); + + IF( EQ_16( st_ivas->hCPE[cpe_id]->hCoreCoder[ch]->hTcxEnc->tcxMode, TCX_20 ) ) { - length += length / 4; + length = st_ivas->hCPE[cpe_id]->hCoreCoder[ch]->hTcxEnc->L_frameTCX; + move16(); } - for ( Word16 k = 0; k <= ( ( st_ivas->hCPE[cpe_id]->hCoreCoder[ch]->core == TCX_20_CORE ) ? 1 : NB_DIV ) - 1; k++ ) + ELSE { - IF( hMCT->p_mdst_spectrum_long_fx[cpe_id][ch] ) - { - q_spec = s_min( q_spec, hMCT->q_mdst_spectrum_long_fx[cpe_id][ch][k] ); - q_com_spec = s_min( q_com_spec, L_norm_arr( &hMCT->p_mdst_spectrum_long_fx[cpe_id][ch][k * N_TCX10_MAX], length ) ); - } + length = idiv1616( st_ivas->hCPE[cpe_id]->hCoreCoder[ch]->hTcxEnc->L_frameTCX, NB_DIV ); // st_ivas->hCPE[cpe_id]->hCoreCoder[ch]->hTcxEnc->L_frameTCX / NB_DIV + } + + IF( st_ivas->hCPE[cpe_id]->hCoreCoder[ch]->last_core == ACELP_CORE ) + { + length = add( length, idiv1616( length, 4 ) ); } IF( hMCT->p_orig_spectrum_long_fx[cpe_id][ch] ) { - q_origSpec = s_min( q_origSpec, hMCT->q_orig_spectrum_long_fx[cpe_id][ch] ); - q_com = s_min( q_com, L_norm_arr( hMCT->p_orig_spectrum_long_fx[cpe_id][ch], L_FRAME48k ) ); + norm = L_norm_arr( hMCT->p_orig_spectrum_long_fx[cpe_id][ch], L_FRAME48k ); + q_origSpec = s_min( q_origSpec, add( norm, hMCT->q_orig_spectrum_long_fx[cpe_id][ch] ) ); } } } - q_spec = sub( add( q_spec, q_com_spec ), 1 ); - q_origSpec = sub( add( q_origSpec, q_com ), 1 ); + q_origSpec = sub( q_origSpec, 1 ); FOR( cpe_id = 0; cpe_id < nCPE; cpe_id++ ) { @@ -332,7 +339,7 @@ ivas_error ivas_mct_enc_fx( } IF( hMCT->p_orig_spectrum_long_fx[cpe_id][ch] ) { - Scale_sig32( hMCT->p_orig_spectrum_long_fx[cpe_id][ch], L_FRAME48k, sub( q_origSpec, hMCT->q_orig_spectrum_long_fx[cpe_id][ch] ) ); + Scale_sig32( hMCT->p_orig_spectrum_long_fx[cpe_id][ch], L_FRAME48k, sub( q_origSpec, hMCT->q_orig_spectrum_long_fx[cpe_id][ch] ) ); // q_origSpec hMCT->q_orig_spectrum_long_fx[cpe_id][ch] = q_origSpec; move16(); } @@ -340,67 +347,36 @@ ivas_error ivas_mct_enc_fx( } hMCT->q_orig_spectrum_long_com = q_origSpec; move16(); - for ( cpe_id = 0; cpe_id < nCPE; cpe_id++ ) + + FOR( cpe_id = 0; cpe_id < nCPE; cpe_id++ ) { - for ( ch = 0; ch < CPE_CHANNELS; ch++ ) + FOR( ch = 0; ch < CPE_CHANNELS; ch++ ) { - length = st_ivas->hCPE[cpe_id]->hCoreCoder[ch]->hTcxEnc->L_frameTCX / ( ( st_ivas->hCPE[cpe_id]->hCoreCoder[ch]->hTcxEnc->tcxMode == TCX_20 ) ? 1 : NB_DIV ); - if ( st_ivas->hCPE[cpe_id]->hCoreCoder[ch]->last_core == ACELP_CORE ) + IF( EQ_16( st_ivas->hCPE[cpe_id]->hCoreCoder[ch]->core, TCX_20 ) ) { - length += length / 4; + length = st_ivas->hCPE[cpe_id]->hCoreCoder[ch]->hTcxEnc->L_frameTCX; + move16(); } - for ( Word16 k = 0; k <= ( ( st_ivas->hCPE[cpe_id]->hCoreCoder[ch]->core == TCX_20_CORE ) ? 1 : NB_DIV ) - 1; k++ ) + ELSE { - /*if ( st_ivas->hCPE[cpe_id]->hCoreCoder[ch]->hTcxEnc->spectrum[0] ) - { - floatToFixed_arrL32( st_ivas->hCPE[cpe_id]->hCoreCoder[ch]->hTcxEnc->spectrum[k], st_ivas->hCPE[cpe_id]->hCoreCoder[ch]->hTcxEnc->spectrum_fx[k], q_spec, length ); - st_ivas->hCPE[cpe_id]->hCoreCoder[ch]->hTcxEnc->spectrum_e[0] = sub( Q31, q_spec ); - st_ivas->hCPE[cpe_id]->hCoreCoder[ch]->hTcxEnc->spectrum_e[1] = sub( Q31, q_spec ); - }*/ - IF( hMCT->p_mdst_spectrum_long_fx[cpe_id][ch] ) - { - Scale_sig32( &hMCT->p_mdst_spectrum_long_fx[cpe_id][ch][k * N_TCX10_MAX], length, sub( q_spec, hMCT->q_mdst_spectrum_long_fx[cpe_id][ch][k] ) ); - hMCT->q_mdst_spectrum_long_fx[cpe_id][ch][k] = q_spec; - move16(); - } + length = idiv1616( st_ivas->hCPE[cpe_id]->hCoreCoder[ch]->hTcxEnc->L_frameTCX, NB_DIV ); } - } - } -#ifdef IVAS_FLOAT_FIXED_CONVERSIONS - Encoder_State *sts_tmp[MCT_MAX_CHANNELS]; - Encoder_State *st; - Word16 i; - nCPE = shr( hMCT->nchan_out_woLFE, 1 ); // nChannels / CPE_CHANNELS - - /*in case of odd number of channels*/ - IF( NE_16( ( nCPE * CPE_CHANNELS ), hMCT->nchan_out_woLFE ) ) - { - nCPE = add( nCPE, 1 ); - } - FOR( ( cpe_id = 0, i = 0 ); cpe_id < nCPE; cpe_id++ ) - { - FOR( ch = 0; ch < CPE_CHANNELS; ch++ ) - { - sts_tmp[i] = st_ivas->hCPE[cpe_id]->hCoreCoder[ch]; - IF( EQ_32( st_ivas->hCPE[cpe_id]->hCoreCoder[ch]->mct_chan_mode, MCT_CHAN_MODE_IGNORE ) ) + IF( st_ivas->hCPE[cpe_id]->hCoreCoder[ch]->last_core == ACELP_CORE ) { - i = add( i, 1 ); - CONTINUE; + length = add( length, idiv1616( length, 4 ) ); } - i++; - } - } -#endif -#endif // 1 - - - FOR( cpe_id = 0; cpe_id < nCPE; cpe_id++ ) - { - FOR( ch = 0; ch < CPE_CHANNELS; ch++ ) - { Word16 norm = L_norm_arr( st_ivas->hCPE[cpe_id]->hCoreCoder[ch]->hTcxEnc->spectrum_long_fx, N_MAX ); q_spec = s_min( q_spec, add( sub( 31, st_ivas->hCPE[cpe_id]->hCoreCoder[ch]->hTcxEnc->spectrum_long_e ), norm ) ); q_spec = s_min( q_spec, add( sub( 31, st_ivas->hCPE[cpe_id]->hCoreCoder[ch]->hTcxEnc->spectrum_long_e ), norm ) ); + + FOR( Word16 k = 0; k <= ( ( st_ivas->hCPE[cpe_id]->hCoreCoder[ch]->core == TCX_20_CORE ) ? 1 : NB_DIV ) - 1; k++ ) + { + IF( hMCT->p_mdst_spectrum_long_fx[cpe_id][ch] ) + { + norm = L_norm_arr( &hMCT->p_mdst_spectrum_long_fx[cpe_id][ch][k * N_TCX10_MAX], length ); + q_spec = s_min( q_spec, add( norm, hMCT->q_mdst_spectrum_long_fx[cpe_id][ch][k] ) ); + } + } } } @@ -417,17 +393,34 @@ ivas_error ivas_mct_enc_fx( { length = idiv1616( st_ivas->hCPE[cpe_id]->hCoreCoder[ch]->hTcxEnc->L_frameTCX, NB_DIV ); } - scale_sig32( st_ivas->hCPE[cpe_id]->hCoreCoder[ch]->hTcxEnc->spectrum_long_fx, N_MAX, sub( q_spec, sub( 31, st_ivas->hCPE[cpe_id]->hCoreCoder[ch]->hTcxEnc->spectrum_long_e ) ) ); + scale_sig32( st_ivas->hCPE[cpe_id]->hCoreCoder[ch]->hTcxEnc->spectrum_long_fx, N_MAX, sub( q_spec, sub( 31, st_ivas->hCPE[cpe_id]->hCoreCoder[ch]->hTcxEnc->spectrum_long_e ) ) ); // q_spec st_ivas->hCPE[cpe_id]->hCoreCoder[ch]->hTcxEnc->spectrum_e[0] = sub( 31, q_spec ); move16(); st_ivas->hCPE[cpe_id]->hCoreCoder[ch]->hTcxEnc->spectrum_e[1] = sub( 31, q_spec ); move16(); + st_ivas->hCPE[cpe_id]->hCoreCoder[ch]->hTcxEnc->spectrum_long_e = sub( 31, q_spec ); + move16(); + + IF( st_ivas->hCPE[cpe_id]->hCoreCoder[ch]->last_core == ACELP_CORE ) + { + length = add( length, idiv1616( length, 4 ) ); + } + + FOR( Word16 k = 0; k <= ( ( st_ivas->hCPE[cpe_id]->hCoreCoder[ch]->core == TCX_20_CORE ) ? 1 : NB_DIV ) - 1; k++ ) + { + IF( hMCT->p_mdst_spectrum_long_fx[cpe_id][ch] ) + { + Scale_sig32( &hMCT->p_mdst_spectrum_long_fx[cpe_id][ch][k * N_TCX10_MAX], length, sub( q_spec, hMCT->q_mdst_spectrum_long_fx[cpe_id][ch][k] ) ); // q_spec + hMCT->q_mdst_spectrum_long_fx[cpe_id][ch][k] = q_spec; + move16(); + } + } } } /* joint MCT encoding */ - ivas_mct_core_enc_fx( ivas_format, hMCT, st_ivas->hCPE, hMCT->nchan_out_woLFE, ivas_total_brate, switch_bw, ( ivas_format == MC_FORMAT && ( st_ivas->mc_mode == MC_MODE_MCT || st_ivas->mc_mode == MC_MODE_PARAMUPMIX ) ) ? (int16_t) st_ivas->hLFE->lfe_bits : 0, st_ivas->hEncoderConfig->sba_order ); + ivas_mct_core_enc_fx( ivas_format, hMCT, st_ivas->hCPE, hMCT->nchan_out_woLFE, ivas_total_brate, switch_bw, ( ivas_format == MC_FORMAT && ( st_ivas->mc_mode == MC_MODE_MCT || st_ivas->mc_mode == MC_MODE_PARAMUPMIX ) ) ? (Word16) st_ivas->hLFE->lfe_bits : 0, st_ivas->hEncoderConfig->sba_order ); FOR( cpe_id = 0; cpe_id < nCPE; cpe_id++ ) { @@ -456,10 +449,10 @@ ivas_error ivas_mct_enc_fx( } ELSE { - scale_sig32( st_ivas->hCPE[cpe_id]->hCoreCoder[ch]->hTcxEnc->spectrum_fx[0], length, sub( st_ivas->hCPE[cpe_id]->hCoreCoder[ch]->hTcxEnc->spectrum_e[0], e_spec ) ); - scale_sig32( st_ivas->hCPE[cpe_id]->hCoreCoder[ch]->hTcxEnc->spectrum_fx[0] + length, sub( N_TCX10_MAX, length ), sub( sub( 31, q_spec ), e_spec ) ); - scale_sig32( st_ivas->hCPE[cpe_id]->hCoreCoder[ch]->hTcxEnc->spectrum_fx[1], length, sub( st_ivas->hCPE[cpe_id]->hCoreCoder[ch]->hTcxEnc->spectrum_e[0], e_spec ) ); - scale_sig32( st_ivas->hCPE[cpe_id]->hCoreCoder[ch]->hTcxEnc->spectrum_fx[1] + length, sub( N_MAX - N_TCX10_MAX, length ), sub( sub( 31, q_spec ), e_spec ) ); + scale_sig32( st_ivas->hCPE[cpe_id]->hCoreCoder[ch]->hTcxEnc->spectrum_fx[0], length, sub( st_ivas->hCPE[cpe_id]->hCoreCoder[ch]->hTcxEnc->spectrum_e[0], e_spec ) ); // st_ivas->hCPE[cpe_id]->hCoreCoder[ch]->hTcxEnc->spectrum_e[0] + scale_sig32( st_ivas->hCPE[cpe_id]->hCoreCoder[ch]->hTcxEnc->spectrum_fx[0] + length, sub( N_TCX10_MAX, length ), sub( sub( 31, q_spec ), e_spec ) ); // 31 - q_spec + scale_sig32( st_ivas->hCPE[cpe_id]->hCoreCoder[ch]->hTcxEnc->spectrum_fx[1], length, sub( st_ivas->hCPE[cpe_id]->hCoreCoder[ch]->hTcxEnc->spectrum_e[0], e_spec ) ); // st_ivas->hCPE[cpe_id]->hCoreCoder[ch]->hTcxEnc->spectrum_e[0] + scale_sig32( st_ivas->hCPE[cpe_id]->hCoreCoder[ch]->hTcxEnc->spectrum_fx[1] + length, sub( N_MAX - N_TCX10_MAX, length ), sub( sub( 31, q_spec ), e_spec ) ); // 31 - q_spec st_ivas->hCPE[cpe_id]->hCoreCoder[ch]->hTcxEnc->spectrum_long_e = e_spec; move16(); } @@ -470,45 +463,21 @@ ivas_error ivas_mct_enc_fx( } } -#ifdef IVAS_FLOAT_FIXED_CONVERSIONS q_spec = 31; move16(); - for ( ch = 0; ch < hMCT->nchan_out_woLFE; ch++ ) - { - length = sts_tmp[ch]->hTcxEnc->L_frameTCX / ( ( sts_tmp[ch]->hTcxEnc->tcxMode == TCX_20 ) ? 1 : NB_DIV ); - if ( sts_tmp[ch]->last_core == ACELP_CORE ) - { - length += length / 4; - } - } -#endif /* Spectrum quantization and coding */ FOR( cpe_id = 0; cpe_id < st_ivas->nCPE; cpe_id++ ) { hCPE = st_ivas->hCPE[cpe_id]; - if ( cpe_id > 0 ) + IF( cpe_id > 0 ) { hCPE->hCoreCoder[0]->hBstr->ind_list = st_ivas->hCPE[cpe_id - 1]->hCoreCoder[1]->hBstr->ind_list + st_ivas->hCPE[cpe_id - 1]->hCoreCoder[1]->hBstr->nb_ind_tot; } -#ifdef IVAS_FLOAT_FIXED_CONVERSIONS - Encoder_State /**st,*/ **sts; - FOR( ch = 0; ch < CPE_CHANNELS; ch++ ) - { - sts = hCPE->hCoreCoder; - st = sts[ch]; - } -#endif + ivas_mdct_quant_coder_fx( hCPE, hMCT->tnsBits[cpe_id], hMCT->tnsSize[cpe_id], hMCT->p_param[cpe_id], 1 ); -#ifdef IVAS_FLOAT_FIXED_CONVERSIONS - FOR( ch = 0; ch < CPE_CHANNELS; ch++ ) - { - sts = hCPE->hCoreCoder; - st = sts[ch]; - } -#endif /* update input samples buffer (as done in ivas_cpe_enc() for other than MCT coding) */ FOR( n = 0; n < CPE_CHANNELS; n++ ) { @@ -516,22 +485,8 @@ ivas_error ivas_mct_enc_fx( hCPE->hCoreCoder[n]->q_old_inp = hCPE->hCoreCoder[n]->q_inp; move16(); /* common encoder updates */ -#ifdef IVAS_FLOAT_FIXED_CONVERSIONS - st = hCPE->hCoreCoder[n]; - IF( st->hTcxEnc != NULL ) - { - st->hTcxEnc->exp_buf_speech_ltp = 31; /*Q0*/ - } -#endif - - updt_enc_common_ivas_fx( st, Q_new_out[cpe_id][n] ); -#ifdef IVAS_FLOAT_FIXED_CONVERSIONS - IF( st->hTcxEnc != NULL ) - { - Scale_sig( st->hTcxEnc->buf_speech_ltp, L_PAST_MAX_32k + L_FRAME32k + L_NEXT_MAX_32k, st->hTcxEnc->exp_buf_speech_ltp ); - } -#endif + updt_enc_common_ivas_fx( hCPE->hCoreCoder[n], Q_new_out[cpe_id][n] ); } } @@ -545,7 +500,7 @@ ivas_error ivas_mct_enc_fx( * Create, allocate and initialize IVAS encoder MCT handle *-------------------------------------------------------------------------*/ -ivas_error create_mct_enc( +ivas_error create_mct_enc_fx( Encoder_Struct *st_ivas /* i/o: IVAS encoder structure */ ) { @@ -677,7 +632,7 @@ ivas_error create_mct_enc( * Initializations *-----------------------------------------------------------------*/ - set_mct_enc_params( hMCT, ivas_total_brate, ivas_format, 1 ); + set_mct_enc_params_fx( hMCT, ivas_total_brate, ivas_format, 1 ); st_ivas->hMCT = hMCT; @@ -869,7 +824,7 @@ ivas_error mct_enc_reconfigure_fx( * Initializations *-----------------------------------------------------------------*/ - set_mct_enc_params( hMCT, ivas_total_brate, ivas_format, b_nchan_change ); + set_mct_enc_params_fx( hMCT, ivas_total_brate, ivas_format, b_nchan_change ); return error; } @@ -881,7 +836,7 @@ ivas_error mct_enc_reconfigure_fx( * Close MCT *-------------------------------------------------------------------------*/ -void ivas_mct_enc_close( +void ivas_mct_enc_close_fx( MCT_ENC_HANDLE *hMCT /* i/o: MCT encoder structure */ ) { @@ -1013,11 +968,11 @@ static ivas_error ivas_mc_enc_reconfig_fx( IF( st_ivas->hLFE != NULL ) { /* LFE handle */ - ivas_lfe_enc_close( &( st_ivas->hLFE ) ); + ivas_lfe_enc_close_fx( &( st_ivas->hLFE ) ); } /* create LFE handle */ - IF( NE_32( ( error = ivas_create_lfe_enc( &st_ivas->hLFE, st_ivas->hEncoderConfig->input_Fs ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = ivas_create_lfe_enc_fx( &st_ivas->hLFE, st_ivas->hEncoderConfig->input_Fs ) ), IVAS_ERR_OK ) ) { return error; } @@ -1025,12 +980,12 @@ static ivas_error ivas_mc_enc_reconfig_fx( /*De-allocate handles for other MC modes*/ ivas_param_mc_enc_close_fx( &( st_ivas->hParamMC ), st_ivas->hEncoderConfig->input_Fs ); - ivas_mc_paramupmix_enc_close( &( st_ivas->hMCParamUpmix ), st_ivas->hEncoderConfig->input_Fs ); + ivas_mc_paramupmix_enc_close_fx( &( st_ivas->hMCParamUpmix ), st_ivas->hEncoderConfig->input_Fs ); /* De-allocate McMasa-related handles */ ivas_mcmasa_enc_close_fx( &( st_ivas->hMcMasa ), st_ivas->hEncoderConfig->input_Fs ); - ivas_masa_enc_close( &( st_ivas->hMasa ) ); + ivas_masa_enc_close_fx( &( st_ivas->hMasa ) ); ivas_qmetadata_close_fx( &st_ivas->hQMetaData ); } @@ -1049,11 +1004,11 @@ static ivas_error ivas_mc_enc_reconfig_fx( IF( st_ivas->hLFE != NULL ) { /* LFE handle */ - ivas_lfe_enc_close( &( st_ivas->hLFE ) ); + ivas_lfe_enc_close_fx( &( st_ivas->hLFE ) ); } /* create LFE handle */ - IF( NE_32( ( error = ivas_create_lfe_enc( &st_ivas->hLFE, st_ivas->hEncoderConfig->input_Fs ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = ivas_create_lfe_enc_fx( &st_ivas->hLFE, st_ivas->hEncoderConfig->input_Fs ) ), IVAS_ERR_OK ) ) { return error; } @@ -1061,7 +1016,7 @@ static ivas_error ivas_mc_enc_reconfig_fx( IF( NE_32( last_mc_mode, MC_MODE_PARAMUPMIX ) ) { - IF( NE_32( ( error = ivas_mc_paramupmix_enc_open( st_ivas ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = ivas_mc_paramupmix_enc_open_fx( st_ivas ) ), IVAS_ERR_OK ) ) { return error; } @@ -1072,7 +1027,7 @@ static ivas_error ivas_mc_enc_reconfig_fx( /* De-allocate McMasa-related handles */ ivas_mcmasa_enc_close_fx( &( st_ivas->hMcMasa ), st_ivas->hEncoderConfig->input_Fs ); - ivas_masa_enc_close( &( st_ivas->hMasa ) ); + ivas_masa_enc_close_fx( &( st_ivas->hMasa ) ); ivas_qmetadata_close_fx( &st_ivas->hQMetaData ); } @@ -1098,17 +1053,17 @@ static ivas_error ivas_mc_enc_reconfig_fx( IF( st_ivas->hMasa != NULL ) { - ivas_masa_enc_close( &( st_ivas->hMasa ) ); + ivas_masa_enc_close_fx( &( st_ivas->hMasa ) ); st_ivas->hMasa = NULL; } - ivas_mc_paramupmix_enc_close( &( st_ivas->hMCParamUpmix ), st_ivas->hEncoderConfig->input_Fs ); + ivas_mc_paramupmix_enc_close_fx( &( st_ivas->hMCParamUpmix ), st_ivas->hEncoderConfig->input_Fs ); test(); IF( EQ_32( last_mc_mode, MC_MODE_PARAMUPMIX ) && st_ivas->hLFE != NULL ) { /* LFE handle */ - ivas_lfe_enc_close( &( st_ivas->hLFE ) ); + ivas_lfe_enc_close_fx( &( st_ivas->hLFE ) ); } ivas_qmetadata_close_fx( &st_ivas->hQMetaData ); @@ -1117,14 +1072,14 @@ static ivas_error ivas_mc_enc_reconfig_fx( test(); IF( EQ_32( last_mc_mode, MC_MODE_MCT ) && LE_16( st_ivas->nchan_transport, CPE_CHANNELS ) ) { - ivas_mct_enc_close( &( st_ivas->hMCT ) ); + ivas_mct_enc_close_fx( &( st_ivas->hMCT ) ); } test(); IF( EQ_32( last_mc_mode, MC_MODE_MCT ) && st_ivas->hLFE != NULL ) { /* LFE handle */ - ivas_lfe_enc_close( &( st_ivas->hLFE ) ); + ivas_lfe_enc_close_fx( &( st_ivas->hLFE ) ); } } ELSE IF( EQ_32( st_ivas->mc_mode, MC_MODE_MCMASA ) ) @@ -1138,7 +1093,7 @@ static ivas_error ivas_mc_enc_reconfig_fx( return error; } - IF( NE_32( ( error = ivas_masa_enc_open( st_ivas ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = ivas_masa_enc_open_fx( st_ivas ) ), IVAS_ERR_OK ) ) { return error; } @@ -1158,21 +1113,21 @@ static ivas_error ivas_mc_enc_reconfig_fx( ivas_param_mc_enc_close_fx( &( st_ivas->hParamMC ), st_ivas->hEncoderConfig->input_Fs ); - ivas_mc_paramupmix_enc_close( &( st_ivas->hMCParamUpmix ), st_ivas->hEncoderConfig->input_Fs ); + ivas_mc_paramupmix_enc_close_fx( &( st_ivas->hMCParamUpmix ), st_ivas->hEncoderConfig->input_Fs ); test(); IF( EQ_32( last_mc_mode, MC_MODE_PARAMUPMIX ) && st_ivas->hLFE != NULL ) { /* LFE handle */ - ivas_lfe_enc_close( &( st_ivas->hLFE ) ); + ivas_lfe_enc_close_fx( &( st_ivas->hLFE ) ); } IF( EQ_32( last_mc_mode, MC_MODE_MCT ) ) { /* LFE handle */ - ivas_lfe_enc_close( &( st_ivas->hLFE ) ); + ivas_lfe_enc_close_fx( &( st_ivas->hLFE ) ); - ivas_mct_enc_close( &( st_ivas->hMCT ) ); + ivas_mct_enc_close_fx( &( st_ivas->hMCT ) ); } } diff --git a/lib_enc/ivas_mct_enc_mct.c b/lib_enc/ivas_mct_enc_mct_fx.c similarity index 91% rename from lib_enc/ivas_mct_enc_mct.c rename to lib_enc/ivas_mct_enc_mct_fx.c index db6d8916cef61c38c87ca125eb505a6af97d9d55..a8ba9a3202c2f5ad298c482148b2292a7b95ca8b 100644 --- a/lib_enc/ivas_mct_enc_mct.c +++ b/lib_enc/ivas_mct_enc_mct_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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,9 +34,7 @@ #include "options.h" #include #include "ivas_cnst.h" -#include "ivas_prot.h" #include "ivas_prot_fx.h" -#include "prot.h" #include "prot_fx.h" #include "prot_fx_enc.h" #include "wmc_auto.h" @@ -97,7 +95,7 @@ void getChannelEnergies_fx( move32(); FOR( n = 0; n < nSubframes; n++ ) { - sum2 = sum2_32_exp_fx( st->hTcxEnc->spectrum_fx[n], L_subframe, &sum2_e, gb ); + sum2 = sum2_32_exp_fx( st->hTcxEnc->spectrum_fx[n], L_subframe, &sum2_e, gb ); // 31 - sum2_e nrg[ch] = BASOP_Util_Add_Mant32Exp( nrg[ch], nrg_e[ch], sum2, sum2_e, &nrg_e[ch] ); move32(); @@ -106,7 +104,7 @@ void getChannelEnergies_fx( move16(); } - nrg[ch] = Sqrt32( nrg[ch], &nrg_e[ch] ); + nrg[ch] = Sqrt32( nrg[ch], &nrg_e[ch] ); // nrg_e move32(); } } @@ -145,7 +143,7 @@ static void getNextBestCorrelation_fx( IF( L_abs( xCorrMatrix[ch1][ch2] ) > 0 ) { assert( i < ( MCT_MAX_CHANNELS * ( MCT_MAX_CHANNELS - 1 ) ) / 2 ); - tmp_corrVals[i] = L_abs( xCorrMatrix[ch1][ch2] ); + tmp_corrVals[i] = L_abs( xCorrMatrix[ch1][ch2] ); // Qx move32(); i = add( i, 1 ); } @@ -158,7 +156,7 @@ static void getNextBestCorrelation_fx( v_sort_ind_fixed( tmp_corrVals, tmp_org, add( tmp_idx, 1 ) ); /* get max, or 2nd max and so on depending on sortInd value */ - *max_corr = tmp_corrVals[sub( tmp_idx, sortInd )]; + *max_corr = tmp_corrVals[( tmp_idx - sortInd )]; // Qx move32(); /*find channel pair for this max_corr*/ @@ -170,7 +168,7 @@ static void getNextBestCorrelation_fx( { *_ch1 = ch1; *_ch2 = ch2; - *max_corr = xCorrMatrix[ch1][ch2]; /* assign to max_corr its actual value */ + *max_corr = xCorrMatrix[ch1][ch2]; /* assign to max_corr its actual value */ // Qx move16(); move16(); move32(); @@ -252,9 +250,9 @@ static void getCorrelationMatrix_fx( FOR( ch2 = ch1 + 1; ch2 < nchan; ch2++ ) { // tmp = sqrtf( xCorrMatrix[ch1][ch1] * xCorrMatrix[ch2][ch2] ); - W_tmp = W_mult0_32_32( xCorrMatrix[ch1][ch1], xCorrMatrix[ch2][ch2] ); + W_tmp = W_mult0_32_32( xCorrMatrix[ch1][ch1], xCorrMatrix[ch2][ch2] ); // ( 31 - xCorrMatrix_exp[ch1][ch1] ) + ( 31 - xCorrMatrix_exp[ch2][ch2] ) s = W_norm( W_tmp ); - L_tmp = W_extract_h( W_shl( W_tmp, s ) ); + L_tmp = W_extract_h( W_shl( W_tmp, s ) ); // s + ( 31 - xCorrMatrix_exp[ch1][ch1] ) + ( 31 - xCorrMatrix_exp[ch2][ch2] ) - 32 s = sub( add( s, 30 ), add( xCorrMatrix_exp[ch1][ch1], xCorrMatrix_exp[ch2][ch2] ) ); // s = s + ( 31 - xCorrMatrix_exp[ch1][ch1] ) + ( 31 - xCorrMatrix_exp[ch2][ch2] ) - 32; s = sub( 31, s ); @@ -296,7 +294,7 @@ static void getCorrelationMatrix_fx( { FOR( ch2 = ch1 + 1; ch2 < nchan; ch2++ ) { - xCorrMatrix[ch1][ch2] = L_shl_sat( xCorrMatrix[ch1][ch2], add( s, sub( xCorrMatrix_exp[ch1][ch2], *xCorrMatrix_e ) ) ); + xCorrMatrix[ch1][ch2] = L_shl_sat( xCorrMatrix[ch1][ch2], add( s, sub( xCorrMatrix_exp[ch1][ch2], *xCorrMatrix_e ) ) ); // xCorrMatrix_e - s move32(); } } @@ -334,7 +332,7 @@ static void getBestCorrelation_fx( { IF( LT_32( L_abs( *max_corr ), L_abs( xCorrMatrix[ch1][ch2] ) ) ) { - *max_corr = xCorrMatrix[ch1][ch2]; + *max_corr = xCorrMatrix[ch1][ch2]; // Qx move32(); *_ch1 = ch1; @@ -377,12 +375,12 @@ static void getBlockValues_fx( /* map vectors to current block channels */ FOR( n = 0; n < 2; n++ ) { - p_mdst_spectrum[0][n] = mdst_spectrum[ch1][n]; - p_mdst_spectrum[1][n] = mdst_spectrum[ch2][n]; - p_inv_spectrum[0][n] = inv_spectrum[ch1][n]; - p_inv_spectrum[1][n] = inv_spectrum[ch2][n]; - p_inv_mdst_spectrum[0][n] = inv_mdst_spectrum[ch1][n]; - p_inv_mdst_spectrum[1][n] = inv_mdst_spectrum[ch2][n]; + p_mdst_spectrum[0][n] = mdst_spectrum[ch1][n]; // q_spec + p_mdst_spectrum[1][n] = mdst_spectrum[ch2][n]; // q_spec + p_inv_spectrum[0][n] = inv_spectrum[ch1][n]; // q_spec + p_inv_spectrum[1][n] = inv_spectrum[ch2][n]; // q_spec + p_inv_mdst_spectrum[0][n] = inv_mdst_spectrum[ch1][n]; // q_spec + p_inv_mdst_spectrum[1][n] = inv_mdst_spectrum[ch2][n]; // q_spec } p_st[0] = sts[ch1]; p_st[1] = sts[ch2]; @@ -601,11 +599,16 @@ static void getGlobalILD_fx( { sts[ch]->hTcxEnc->spectrum_e[k] = add( sts[ch]->hTcxEnc->spectrum_e[k], 4 ); // Updating exponent of spectrum as q_ratio is in Q11 } + IF( GT_16( nSubframes, 1 ) ) + { + sts[ch]->hTcxEnc->spectrum_long_e = add( sts[ch]->hTcxEnc->spectrum_long_e, 4 ); + move16(); + } FOR( k = 0; k < nSubframes; k++ ) { - v_multc_fixed( sts[ch]->hTcxEnc->spectrum_fx[k], L_deposit_h( qratio ), sts[ch]->hTcxEnc->spectrum_fx[k], L_subframe ); - v_multc_fixed( mdst_spectrum[ch][k], L_deposit_h( qratio ), mdst_spectrum[ch][k], L_subframe ); + v_multc_fixed( sts[ch]->hTcxEnc->spectrum_fx[k], L_deposit_h( qratio ), sts[ch]->hTcxEnc->spectrum_fx[k], L_subframe ); // sts[ch]->hTcxEnc->spectrum_e + v_multc_fixed( mdst_spectrum[ch][k], L_deposit_h( qratio ), mdst_spectrum[ch][k], L_subframe ); // sts[ch]->hTcxEnc->spectrum_e } } } @@ -623,9 +626,9 @@ static void getGlobalILD_fx( void apply_MCT_enc_fx( MCT_ENC_HANDLE hMCT, /* i/o: MCT encoder structure */ Encoder_State **sts, /* i/o: encoder state structure */ - Word32 *mdst_spectrum[MCT_MAX_CHANNELS][NB_DIV], /* i/o: MDST spectrum */ - Word32 *inv_spectrum[MCT_MAX_CHANNELS][NB_DIV], /* i/o: inverse spectrum */ - Word32 *inv_mdst_spectrum[MCT_MAX_CHANNELS][NB_DIV], /* i/o: inverse MDST spectrum */ + Word32 *mdst_spectrum[MCT_MAX_CHANNELS][NB_DIV], /* i/o: MDST spectrum Qx*/ + Word32 *inv_spectrum[MCT_MAX_CHANNELS][NB_DIV], /* i/o: inverse spectrum Qx*/ + Word32 *inv_mdst_spectrum[MCT_MAX_CHANNELS][NB_DIV], /* i/o: inverse MDST spectrum Qx*/ const Word16 nchan /* i : number of channels */ ) { @@ -734,7 +737,7 @@ void apply_MCT_enc_fx( move16(); move16(); currBlockDataCnt = 0; - WHILE( LT_16( currBlockDataCnt, hMCT->nchan_out_woLFE ) ) + WHILE( ( currBlockDataCnt < hMCT->nchan_out_woLFE ) ) { /* find best fitting channel pair: */ ch1 = -1; @@ -877,10 +880,12 @@ void apply_MCT_enc_fx( } sts[ch]->hTcxEnc->spectrum_e[1] = add( sts[ch]->hTcxEnc->spectrum_e[0], exp ); sts[ch]->hTcxEnc->spectrum_e[0] = add( sts[ch]->hTcxEnc->spectrum_e[0], exp ); + sts[ch]->hTcxEnc->spectrum_long_e = add( sts[ch]->hTcxEnc->spectrum_long_e, exp ); hMCT->mc_global_ild[ch] = 0; move16(); move16(); move16(); + move16(); } } } @@ -959,7 +964,7 @@ void write_mct_bitstream_fx( p_st[1] = sts[hBlock->ch2]; /*then business as usual for each block pair */ - write_stereo_to_bitstream( hMCT->hBlockData[pair]->hStereoMdct, p_st, hBlock->mask, 1, hBstr ); + write_stereo_to_bitstream_fx( hMCT->hBlockData[pair]->hStereoMdct, p_st, hBlock->mask, 1, hBstr ); } hMCT->nBitsMCT = sub( hBstr->nb_bits_tot, nbits_start ); @@ -974,15 +979,16 @@ void write_mct_bitstream_fx( * IGF analysis of channels after MCT processing *--------------------------------------------------------------------*/ void mctStereoIGF_enc_fx( - MCT_ENC_HANDLE hMCT, /* i/o: MCT encoder structure */ - Encoder_State **sts, /* i/o: encoder state structure */ - Word32 *orig_spectrum_fx[MCT_MAX_CHANNELS][2], /* i : MDCT spectrum for ITF */ - Word16 q_origSpec, /* i : Q for MDCT spectrum */ - Word32 powerSpec_fx[MCT_MAX_CHANNELS][L_FRAME48k], /* i/o: MDCT^2 + MDST^2 spectrum,or estimate*/ - Word32 *powerSpecMsInv_fx[MCT_MAX_CHANNELS][NB_DIV], /* i : same as above but for inverse spect.*/ - Word16 q_powerSpec[MCT_MAX_CHANNELS], /* i : Q for powSpec_fx and powSpecMsInv_fx*/ - Word32 *inv_spectrum_fx[MCT_MAX_CHANNELS][NB_DIV], /* i : inverse spectrum */ - const Word16 sp_aud_decision0[MCT_MAX_CHANNELS] /* i : speech audio decision */ + MCT_ENC_HANDLE hMCT, /* i/o: MCT encoder structure */ + Encoder_State **sts, /* i/o: encoder state structure */ + Word32 *orig_spectrum_fx[MCT_MAX_CHANNELS][2], /* i : MDCT spectrum for ITF */ + Word16 q_origSpec, /* i : Q for MDCT spectrum */ + Word32 powerSpec_fx[MCT_MAX_CHANNELS][L_FRAME48k], /* i/o: MDCT^2 + MDST^2 spectrum,or estimate */ + Word16 q_powerSpec[MCT_MAX_CHANNELS], /* i : Q for powSpec_fx */ + Word32 *powerSpecMsInv_fx[MCT_MAX_CHANNELS][NB_DIV], /* i : same as powerSpec_fx but for inverse spect.*/ + Word16 q_powerSpecMsInv[MCT_MAX_CHANNELS], /* i : Q for powSpecMsInv_fx */ + Word32 *inv_spectrum_fx[MCT_MAX_CHANNELS][NB_DIV], /* i : inverse spectrum */ + const Word16 sp_aud_decision0[MCT_MAX_CHANNELS] /* i : speech audio decision */ ) { Word32 *p_powerSpecMsInv_fx[CPE_CHANNELS][NB_DIV]; @@ -992,11 +998,13 @@ void mctStereoIGF_enc_fx( Word16 b, nSubframes, L_subframeTCX; Word16 p_ch[2], n, ch, ch1, ch2, s = 31; + Word16 q_pSI_ch[2]; Word16 q_pS_ch[2]; Encoder_State *p_st[NB_DIV]; Encoder_State *st; Word16 singleChEle[MCT_MAX_CHANNELS]; Word16 q_spectrum; + Word16 exp_powerSpec[MCT_MAX_CHANNELS][N_MAX + L_MDCT_OVLP_MAX]; L_subframeTCX = 0; /* to avoid compilation warning */ move16(); @@ -1033,7 +1041,7 @@ void mctStereoIGF_enc_fx( sts[ch2]->hBstr->ind_list = sts[0]->hBstr->ind_list + sts[0]->hBstr->nb_ind_tot; } - p_powerSpec_fx[0] = powerSpec_fx[ch1]; + p_powerSpec_fx[0] = powerSpec_fx[ch1]; // q_powerSpec p_powerSpec_fx[1] = powerSpec_fx[ch2]; /* Band-wise M/S for MDST */ @@ -1047,14 +1055,16 @@ void mctStereoIGF_enc_fx( FOR( n = 0; n < nSubframes; n++ ) { - p_orig_spectrum_fx[0][n] = orig_spectrum_fx[ch1][n]; + p_orig_spectrum_fx[0][n] = orig_spectrum_fx[ch1][n]; // q_origSpec p_orig_spectrum_fx[1][n] = orig_spectrum_fx[ch2][n]; - p_powerSpecMsInv_fx[0][n] = powerSpecMsInv_fx[ch1][n]; + p_powerSpecMsInv_fx[0][n] = powerSpecMsInv_fx[ch1][n]; // q_powerSpec p_powerSpecMsInv_fx[1][n] = powerSpecMsInv_fx[ch2][n]; p_inv_spectrum_fx[0][n] = inv_spectrum_fx[ch1][n]; p_inv_spectrum_fx[1][n] = inv_spectrum_fx[ch2][n]; q_pS_ch[0] = q_powerSpec[ch1]; + q_pSI_ch[0] = q_powerSpecMsInv[ch1]; q_pS_ch[1] = q_powerSpec[ch2]; + q_pSI_ch[1] = q_powerSpecMsInv[ch2]; move16(); move16(); @@ -1067,6 +1077,7 @@ void mctStereoIGF_enc_fx( { s = s_min( s, sub( 31, p_st[ch]->hTcxEnc->spectrum_e[n] ) ); s = s_min( s, q_pS_ch[ch] ); + s = s_min( s, q_pSI_ch[ch] ); } FOR( ch = 0; ch < CPE_CHANNELS; ch++ ) { @@ -1077,7 +1088,7 @@ void mctStereoIGF_enc_fx( move16(); move16(); - scale_sig32( p_powerSpecMsInv_fx[ch][0], L_FRAME48k, sub( s, q_pS_ch[ch] ) ); + scale_sig32( p_powerSpecMsInv_fx[ch][0], L_FRAME48k, sub( s, q_pSI_ch[ch] ) ); scale_sig32( &p_powerSpec_fx[ch][0], sts[ch]->hTcxEnc->L_frameTCX, sub( s, q_pS_ch[ch] ) ); q_powerSpec[ch1] = s; q_powerSpec[ch2] = s; @@ -1085,14 +1096,9 @@ void mctStereoIGF_enc_fx( move16(); } - p_st[0]->hIGFEnc->spec_be_igf_e = sub( 31, q_origSpec ); - p_st[1]->hIGFEnc->spec_be_igf_e = sub( 31, q_origSpec ); - move16(); - move16(); - ProcessStereoIGF_fx( hMCT->hBlockData[b]->hStereoMdct, p_st, hMCT->hBlockData[b]->mask, - p_orig_spectrum_fx, - p_powerSpec_fx, p_powerSpecMsInv_fx, p_inv_spectrum_fx, n, sp_aud_decision0[ch1], p_st[0]->total_brate ); + p_orig_spectrum_fx, q_origSpec, q_origSpec, + p_powerSpec_fx, p_powerSpecMsInv_fx, p_inv_spectrum_fx, n, sp_aud_decision0[ch1], p_st[0]->total_brate, 1 ); } ELSE { @@ -1109,7 +1115,12 @@ void mctStereoIGF_enc_fx( q_spectrum = sub( 31, st->hTcxEnc->spectrum_e[n] ); - ProcessIGF_ivas_fx( st, st->hTcxEnc->spectrum_fx[n], orig_spectrum_fx[p_ch[ch]][n], &q_spectrum, &powerSpec_fx[p_ch[ch]][n * L_subframeTCX], &q_powerSpec[p_ch[ch]], st->core == TCX_20_CORE, n, sp_aud_decision0[ch], 0 ); + set16_fx( exp_powerSpec[p_ch[ch]], sub( Q31, q_powerSpec[p_ch[ch]] ), N_MAX + L_MDCT_OVLP_MAX ); +#ifndef MSAN_FIX + ProcessIGF_ivas_fx( st, st->hTcxEnc->spectrum_fx[n], orig_spectrum_fx[p_ch[ch]][n], &q_spectrum, &powerSpec_fx[p_ch[ch]][n * L_subframeTCX], &exp_powerSpec[p_ch[ch]][n * L_subframeTCX], st->core == TCX_20_CORE, n, sp_aud_decision0[ch], 0 ); +#else + ProcessIGF_ivas_fx( st, L_FRAME48k, st->hTcxEnc->spectrum_fx[n], orig_spectrum_fx[p_ch[ch]][n], &q_spectrum, &powerSpec_fx[p_ch[ch]][n * L_subframeTCX], &exp_powerSpec[p_ch[ch]][n * L_subframeTCX], st->core == TCX_20_CORE, n, sp_aud_decision0[ch], 0 ); +#endif st->hTcxEnc->spectrum_e[n] = sub( 31, q_spectrum ); move16(); @@ -1149,7 +1160,12 @@ void mctStereoIGF_enc_fx( { q_spectrum = sub( 31, st->hTcxEnc->spectrum_e[n] ); - ProcessIGF_ivas_fx( st, st->hTcxEnc->spectrum_fx[n], orig_spectrum_fx[ch][n], &q_spectrum, &powerSpec_fx[ch][n * L_subframeTCX], &q_powerSpec[ch], st->core == TCX_20_CORE, n, sp_aud_decision0[ch], 0 ); + set16_fx( exp_powerSpec[ch], sub( Q31, q_powerSpec[ch] ), N_MAX + L_MDCT_OVLP_MAX ); +#ifndef MSAN_FIX + ProcessIGF_ivas_fx( st, st->hTcxEnc->spectrum_fx[n], orig_spectrum_fx[ch][n], &q_spectrum, &powerSpec_fx[ch][n * L_subframeTCX], &exp_powerSpec[ch][n * L_subframeTCX], st->core == TCX_20_CORE, n, sp_aud_decision0[ch], 0 ); +#else + ProcessIGF_ivas_fx( st, L_FRAME48k, st->hTcxEnc->spectrum_fx[n], orig_spectrum_fx[ch][n], &q_spectrum, &powerSpec_fx[ch][n * L_subframeTCX], &exp_powerSpec[ch][n * L_subframeTCX], st->core == TCX_20_CORE, n, sp_aud_decision0[ch], 0 ); +#endif st->hTcxEnc->spectrum_e[n] = sub( 31, q_spectrum ); move16(); diff --git a/lib_enc/ivas_mdct_core_enc.c b/lib_enc/ivas_mdct_core_enc_fx.c similarity index 90% rename from lib_enc/ivas_mdct_core_enc.c rename to lib_enc/ivas_mdct_core_enc_fx.c index 1313ba4f33bfef47235d49d5bdfc84d7f25df203..9f674473ecec6f4e2b009791b04c1debadaf6f7b 100644 --- a/lib_enc/ivas_mdct_core_enc.c +++ b/lib_enc/ivas_mdct_core_enc_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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,13 +36,11 @@ #include "options.h" #include #include "cnst.h" -#include "prot.h" -#include "ivas_prot.h" +#include "prot_fx.h" #include "rom_com.h" #include "ivas_rom_com.h" #include "wmc_auto.h" #include "prot_fx_enc.h" -#include "prot_fx.h" #include "ivas_prot_fx.h" @@ -81,15 +79,15 @@ static void enc_prm_pre_mdct_fx( * Header *--------------------------------------------------------------------------------*/ - writeTCXMode( st, hBstr, MCT_flag, &nbits_start ); + writeTCXMode_fx( st, hBstr, MCT_flag, &nbits_start ); /* write last_core for core switching and error concealment */ push_next_indice( hBstr, st->last_core != ACELP_CORE, 1 ); - writeTCXWindowing( hBstr, st->hTcxCfg->tcx_curr_overlap_mode ); + writeTCXWindowing_fx( hBstr, st->hTcxCfg->tcx_curr_overlap_mode ); IF( EQ_16( st->core, TCX_10_CORE ) ) { - writeTCXWindowing( hBstr, st->hTcxCfg->tcx_last_overlap_mode ); + writeTCXWindowing_fx( hBstr, st->hTcxCfg->tcx_last_overlap_mode ); } IF( st->last_core != ACELP_CORE ) @@ -130,10 +128,10 @@ static void enc_prm_pre_mdct_fx( *---------------------------------------------------------------*/ static Word16 kernel_switch_detect_fx( - Word32 *sigR0, /* i/o: MDCT samples of the 1st (left) channel */ - Word32 *sigR1, /* i/o: MDCT samples of the 2nd (right) channel */ - Word32 *sigI0, /* i/o: MDST samples of the 1st (left) channel */ - Word32 *sigI1, /* i/o: MDST samples of the 2nd (right) channel */ + Word32 *sigR0, /* i/o: MDCT samples of the 1st (left) channel q_in*/ + Word32 *sigR1, /* i/o: MDCT samples of the 2nd (right) channel q_in*/ + Word32 *sigI0, /* i/o: MDST samples of the 1st (left) channel q_in*/ + Word32 *sigI1, /* i/o: MDST samples of the 2nd (right) channel q_in*/ const Word16 q_in, /* i : common Q for MDCT and MDST samples */ const Word16 nSamplesCore, /* i : number of core-coded samples below IGF */ const Word16 nSamplesMax, /* i : transform length (number of MCLT lines) */ @@ -436,24 +434,24 @@ static void kernel_switch_update_transforms_fx( #else Scale_sig( &tcxTimeSignal[n - s], shl( s, 1 ), -Q1 ); // Q0 -> Q-1 #endif - wtda_ext_fx( tcxTimeSignal, windowedTimeSignal_16, extract_l( windowedTimeSignal[0] ), extract_l( windowedTimeSignal[1] ), s, kernelType ); // Q-1 + wtda_ext_fx( tcxTimeSignal, windowedTimeSignal_16, extract_l( windowedTimeSignal[0] ), extract_l( windowedTimeSignal[1] ), s, kernelType ); // Q-2 #ifdef MSAN_FIX Scale_sig( &tcxTimeSignal[n - s], add( sub( shl( s, 1 ), n ), 1 ), Q1 ); // Q-1 -> Q0 #else Scale_sig( &tcxTimeSignal[n - s], shl( s, 1 ), Q1 ); // Q-1 -> Q0 #endif - Copy_Scale_sig_16_32_no_sat( windowedTimeSignal_16, windowedTimeSignal, s, Q16 ); // Q15 - scale_sig32( windowedTimeSignal, s, -Q8 /* guard bits */ ); // Q7 + Copy_Scale_sig_16_32_no_sat( windowedTimeSignal_16 /* Q(-2) */, windowedTimeSignal, s, Q16 ); // Q14 + scale_sig32( windowedTimeSignal, s, -Q8 /* guard bits */ ); // Q6 edxt_fx( windowedTimeSignal, sigR, s, kernelType, FALSE ); tmp = BASOP_Util_Divide1616_Scale( NORM_MDCT_FACTOR, s, &exp_tmp ); tmp = Sqrt16( tmp, &exp_tmp ); factor = L_shl( L_deposit_h( tmp ), sub( exp_tmp, Q1 ) ); // Q30 - v_multc_fixed( sigR, factor, sigR, s ); // (Q7, Q30) -> Q6 + v_multc_fixed( sigR, factor, sigR, s ); // (Q6, Q30) -> Q5 q_com = L_norm_arr( sigR, s ); - q_com = s_min( add( q_com, Q6 ), *q_sig ); - scale_sig32( sigR, s, sub( q_com, Q6 ) ); // q_com + q_com = s_min( add( q_com, Q5 ), *q_sig ); + scale_sig32( sigR, s, sub( q_com, Q5 ) ); // q_com scale_sig32( sigI, s, sub( q_com, *q_sig ) ); // q_com *q_sig = q_com; move16(); @@ -520,7 +518,7 @@ static void kernel_switch_update_transforms_fx( Word16 tcx5Win[N_TCX10_MAX / 2 + L_MDCT_OVLP_MAX]; /* temporary buffer for TCX5 windowing */ Word32 tcx5Win_32[N_TCX10_MAX / 2 + L_MDCT_OVLP_MAX]; /* temporary buffer for TCX5 windowing */ Word16 windowedTimeSignal_16[2 + L_FRAME48k]; - Word16 q_shift, q_com; + Word16 q_shift, q_com, q_temp; assert( L_subframe == nSubframes * hTcxCfg->tcx5SizeFB ); @@ -547,14 +545,18 @@ static void kernel_switch_update_transforms_fx( Copy_Scale_sig_32_16( windowedTimeSignal + 2, windowedTimeSignal_16 + 2, add( s, shr( add( leftOverlap, rightOverlap ), 1 ) ), -Q16 ); // *q_windowedTimeSignal - Q16 WindowSignal( hTcxCfg, shr( leftOverlap, 1 ), RECTANGULAR_OVERLAP, MIN_OVERLAP, &leftOverlap, &rightOverlap, windowedTimeSignal_16 + 2, &s, tcx5Win, 0, 1 ); // *q_windowedTimeSignal - Q16 Copy_Scale_sig_16_32_no_sat( tcx5Win, tcx5Win_32, add( s, shr( add( leftOverlap, rightOverlap ), 1 ) ), Q16 ); // *q_windowedTimeSignal - +#ifdef FIX_ISSUE_1157 + q_shift = -Q8; +#else q_shift = -Q7; +#endif move16(); scale_sig32( tcx5Win_32, add( s /* L_subfr. */, shr( add( leftOverlap, rightOverlap ), 1 ) ), q_shift ); // *q_windowedTimeSignal + q_shift kernel_switch_trafo_fx( tcx5Win_32, sigR, leftOverlap, sub( s /* L_subfr. */, shr( add( leftOverlap, rightOverlap ), 1 ) ), rightOverlap, kernelType ); // *q_windowedTimeSignal + q_shift /* Move both sigR and sigI to common Q */ - q_com = s_min( *q_sig, sub( add( *q_windowedTimeSignal, q_shift ), Q1 ) ); + q_temp = add( sub( add( *q_windowedTimeSignal, q_shift ), Q1 ), L_norm_arr( sigR, L_subframe ) ); + q_com = s_min( *q_sig, q_temp ); scale_sig32( sigR, s, sub( q_com, sub( add( *q_windowedTimeSignal, q_shift ), Q1 ) ) ); scale_sig32( sigR + s, sub( L_subframe, s ), sub( q_com, *q_sig ) ); scale_sig32( sigI, L_subframe, sub( q_com, *q_sig ) ); @@ -576,14 +578,19 @@ static void kernel_switch_update_transforms_fx( } ELSE /* tcxTransType != TCX_5 */ { - Word16 q_shift, q_com; + Word16 q_shift, q_com, q_temp; +#ifdef FIX_ISSUE_1157 + q_shift = -Q8; +#else q_shift = -Q7; +#endif move16(); scale_sig32( windowedTimeSignal + 2, add( s /* L_subfr. */, shr( add( leftOverlap, rightOverlap ), 1 ) ), q_shift ); // *q_windowedTimeSignal + q_shift kernel_switch_trafo_fx( windowedTimeSignal + 2, sigR, leftOverlap, sub( s /* L_subfr. */, shr( add( leftOverlap, rightOverlap ), 1 ) ), rightOverlap, kernelType ); // *q_windowedTimeSignal + q_shift /* Move both sigR and sigI to common Q */ - q_com = s_min( *q_sig, sub( add( *q_windowedTimeSignal, q_shift ), Q1 ) ); + q_temp = add( sub( add( *q_windowedTimeSignal, q_shift ), Q1 ), L_norm_arr( sigR, L_subframe ) ); + q_com = s_min( *q_sig, q_temp ); scale_sig32( sigR, s, sub( q_com, sub( add( *q_windowedTimeSignal, q_shift ), Q1 ) ) ); scale_sig32( sigR + s, sub( L_subframe, s ), sub( q_com, *q_sig ) ); scale_sig32( sigI, L_subframe, sub( q_com, *q_sig ) ); @@ -651,26 +658,26 @@ static void applyStereoPreProcessingCplx( { IF( sign < 0 ) { - dmxR1_fx = L_add( Mpy_32_32( valR1_fx, factDe_fx ), Mpy_32_32( valR2_fx, factIn_fx ) ); - dmxI1_fx = L_add( Mpy_32_32( valI1_fx, factDe_fx ), Mpy_32_32( valI2_fx, factIn_fx ) ); + dmxR1_fx = L_add( Mpy_32_32( valR1_fx, factDe_fx ), Mpy_32_32( valR2_fx, factIn_fx ) ); // Q = q_com + Q22 - 31 + dmxI1_fx = L_add( Mpy_32_32( valI1_fx, factDe_fx ), Mpy_32_32( valI2_fx, factIn_fx ) ); // Q = q_com + Q22 - 31 } ELSE { - dmxR1_fx = L_sub( Mpy_32_32( valR2_fx, factIn_fx ), Mpy_32_32( valR1_fx, factDe_fx ) ); - dmxI1_fx = L_sub( Mpy_32_32( valI2_fx, factIn_fx ), Mpy_32_32( valI1_fx, factDe_fx ) ); + dmxR1_fx = L_sub( Mpy_32_32( valR2_fx, factIn_fx ), Mpy_32_32( valR1_fx, factDe_fx ) ); // Q = q_com + Q22 - 31 + dmxI1_fx = L_sub( Mpy_32_32( valI2_fx, factIn_fx ), Mpy_32_32( valI1_fx, factDe_fx ) ); // Q = q_com + Q22 - 31 } } ELSE { IF( sign < 0 ) { - dmxR1_fx = L_add( Mpy_32_32( valR1_fx, factDe_fx ), Mpy_32_32( valR2_fx, factIn_fx ) ); - dmxI1_fx = L_add( Mpy_32_32( valI1_fx, factDe_fx ), Mpy_32_32( valI2_fx, factIn_fx ) ); + dmxR1_fx = L_add( Mpy_32_32( valR1_fx, factDe_fx ), Mpy_32_32( valR2_fx, factIn_fx ) ); // Q = q_com + Q22 - 31 + dmxI1_fx = L_add( Mpy_32_32( valI1_fx, factDe_fx ), Mpy_32_32( valI2_fx, factIn_fx ) ); // Q = q_com + Q22 - 31 } ELSE { - dmxR1_fx = L_sub( Mpy_32_32( valR1_fx, factDe_fx ), Mpy_32_32( valR2_fx, factIn_fx ) ); - dmxI1_fx = L_sub( Mpy_32_32( valI1_fx, factDe_fx ), Mpy_32_32( valI2_fx, factIn_fx ) ); + dmxR1_fx = L_sub( Mpy_32_32( valR1_fx, factDe_fx ), Mpy_32_32( valR2_fx, factIn_fx ) ); // Q = q_com + Q22 - 31 + dmxI1_fx = L_sub( Mpy_32_32( valI1_fx, factDe_fx ), Mpy_32_32( valI2_fx, factIn_fx ) ); // Q = q_com + Q22 - 31 } } } @@ -678,40 +685,40 @@ static void applyStereoPreProcessingCplx( { IF( sign < 0 ) { - dmxI1_fx = L_sub( Mpy_32_32( valI1_fx, factDe_fx ), Mpy_32_32( valI2_fx, factIn_fx ) ); + dmxI1_fx = L_sub( Mpy_32_32( valI1_fx, factDe_fx ), Mpy_32_32( valI2_fx, factIn_fx ) ); // Q = q_com + Q22 - 31 } ELSE { - dmxI1_fx = L_add( Mpy_32_32( valI1_fx, factDe_fx ), Mpy_32_32( valI2_fx, factIn_fx ) ); + dmxI1_fx = L_add( Mpy_32_32( valI1_fx, factDe_fx ), Mpy_32_32( valI2_fx, factIn_fx ) ); // Q = q_com + Q22 - 31 } } IF( LT_32( L_abs( dmxR2_fx ), L_shr( L_add( absR1_fx, absR2_fx ), 9 ) ) ) /* avoid destructive summations */ { - IF( Mpy_32_32( absR1_fx, factIn_fx ) < Mpy_32_32( absR2_fx, factDe_fx ) ) + IF( LT_32( Mpy_32_32( absR1_fx, factIn_fx ), Mpy_32_32( absR2_fx, factDe_fx ) ) ) { IF( sign < 0 ) { - dmxR2_fx = L_add( Mpy_32_32( valR2_fx, factDe_fx ), Mpy_32_32( valR1_fx, factIn_fx ) ); - dmxI2_fx = L_add( Mpy_32_32( valI2_fx, factDe_fx ), Mpy_32_32( valI1_fx, factIn_fx ) ); + dmxR2_fx = L_add( Mpy_32_32( valR2_fx, factDe_fx ), Mpy_32_32( valR1_fx, factIn_fx ) ); // Q = q_com + Q22 - 31 + dmxI2_fx = L_add( Mpy_32_32( valI2_fx, factDe_fx ), Mpy_32_32( valI1_fx, factIn_fx ) ); // Q = q_com + Q22 - 31 } ELSE { - dmxR2_fx = L_sub( Mpy_32_32( valR1_fx, factIn_fx ), Mpy_32_32( valR2_fx, factDe_fx ) ); - dmxI2_fx = L_sub( Mpy_32_32( valI1_fx, factIn_fx ), Mpy_32_32( valI2_fx, factDe_fx ) ); + dmxR2_fx = L_sub( Mpy_32_32( valR2_fx, factDe_fx ), Mpy_32_32( valR1_fx, factIn_fx ) ); // Q = q_com + Q22 - 31 + dmxI2_fx = L_sub( Mpy_32_32( valI2_fx, factDe_fx ), Mpy_32_32( valI1_fx, factIn_fx ) ); // Q = q_com + Q22 - 31 } } ELSE { IF( sign < 0 ) { - dmxR2_fx = L_add( Mpy_32_32( valR1_fx, factIn_fx ), Mpy_32_32( valR2_fx, factDe_fx ) ); - dmxI2_fx = L_add( Mpy_32_32( valI1_fx, factIn_fx ), Mpy_32_32( valI2_fx, factDe_fx ) ); + dmxR2_fx = L_add( Mpy_32_32( valR1_fx, factIn_fx ), Mpy_32_32( valR2_fx, factDe_fx ) ); // Q = q_com + Q22 - 31 + dmxI2_fx = L_add( Mpy_32_32( valI1_fx, factIn_fx ), Mpy_32_32( valI2_fx, factDe_fx ) ); // Q = q_com + Q22 - 31 } ELSE { - dmxR2_fx = L_sub( Mpy_32_32( valR1_fx, factIn_fx ), Mpy_32_32( valR2_fx, factDe_fx ) ); - dmxI2_fx = L_sub( Mpy_32_32( valI1_fx, factIn_fx ), Mpy_32_32( valI2_fx, factDe_fx ) ); + dmxR2_fx = L_sub( Mpy_32_32( valR1_fx, factIn_fx ), Mpy_32_32( valR2_fx, factDe_fx ) ); // Q = q_com + Q22 - 31 + dmxI2_fx = L_sub( Mpy_32_32( valI1_fx, factIn_fx ), Mpy_32_32( valI2_fx, factDe_fx ) ); // Q = q_com + Q22 - 31 } } } @@ -719,11 +726,11 @@ static void applyStereoPreProcessingCplx( { IF( sign < 0 ) { - dmxI2_fx = L_sub( Mpy_32_32( valI2_fx, factDe_fx ), Mpy_32_32( valI1_fx, factIn_fx ) ); + dmxI2_fx = L_sub( Mpy_32_32( valI2_fx, factDe_fx ), Mpy_32_32( valI1_fx, factIn_fx ) ); // Q = q_com + Q22 - 31 } ELSE { - dmxI2_fx = L_add( Mpy_32_32( valI2_fx, factDe_fx ), Mpy_32_32( valI1_fx, factIn_fx ) ); + dmxI2_fx = L_add( Mpy_32_32( valI2_fx, factDe_fx ), Mpy_32_32( valI1_fx, factIn_fx ) ); // Q = q_com + Q22 - 31 } } temp1 = norm_l( valR1_fx ); @@ -791,7 +798,7 @@ static void applyStereoPreProcessingCplx( * * encoder-side complex-valued stereo pre-processing (crosstalk) *---------------------------------------------------------------*/ -static uint16_t enc_ste_pre_mdct( +static UWord16 enc_ste_pre_mdct( Word32 *sigR0_fx, /* i/o: MDCT samples of the 1st (left) channel q_com*/ Word32 *sigR1_fx, /* i/o: MDCT samples of the 2nd (right) channel q_com*/ Word32 *sigI0_fx, /* i/o: MDST samples of the 1st (left) channel q_com*/ @@ -905,9 +912,13 @@ static uint16_t enc_ste_pre_mdct( absMagnR_fx = Sqrt32( L_add( Mpy_32_32( sigR1_fx[s], sigR1_fx[s] ), Mpy_32_32( sigI1_fx[s], sigI1_fx[s] ) ), &absMagnR_e ); corr_fx = L_add( corr_fx, L_add( Mpy_32_32( sigR0_fx[s], sigR1_fx[s] ), Mpy_32_32( sigI0_fx[s], sigI1_fx[s] ) ) ); // q_com*2 - 31 - sumL_fx = L_add( sumL_fx, L_add( sigR0_fx[s], sigI0_fx[s] ) ); // q_com - sumR_fx = L_add( sumR_fx, L_add( sigR1_fx[s], sigI1_fx[s] ) ); // q_com - +#ifdef FIX_ISSUE_1092 + sumL_fx = L_add( sumL_fx, L_add( L_shr( sigR0_fx[s], 1 ), L_shr( sigI0_fx[s], 1 ) ) ); // q_com -1 + sumR_fx = L_add( sumR_fx, L_add( L_shr( sigR1_fx[s], 1 ), L_shr( sigI1_fx[s], 1 ) ) ); // q_com - 1 +#else + sumL_fx = L_add( sumL_fx, L_add( sigR0_fx[s], sigI0_fx[s] ) ); // q_com + sumR_fx = L_add( sumR_fx, L_add( sigR1_fx[s], sigI1_fx[s] ) ); // q_com +#endif sumMagnL_fx = BASOP_Util_Add_Mant32Exp( sumMagnL_fx, sumMagnL_e, absMagnL_fx, absMagnL_e, &sumMagnL_e ); sumMagnR_fx = BASOP_Util_Add_Mant32Exp( sumMagnR_fx, sumMagnR_e, absMagnR_fx, absMagnR_e, &sumMagnR_e ); sumPrdLR_fx = BASOP_Util_Add_Mant32Exp( sumPrdLR_fx, sumPrdLR_e, Mpy_32_32( absMagnL_fx, absMagnR_fx ), add( absMagnL_e, absMagnR_e ), &sumPrdLR_e ); @@ -919,8 +930,11 @@ static uint16_t enc_ste_pre_mdct( temp1 = L_shl( preproLen, x1 ); corr_fx = Mpy_32_32( corr_fx, temp1 ); x1 = sub( 62, add( shl( *q_com, 1 ), x1 ) ); +#ifdef FIX_ISSUE_1092 + corr_fx = BASOP_Util_Add_Mant32Exp( corr_fx, x1, Mpy_32_32( sumL_fx, sumR_fx ), sub( 62, shl( sub( *q_com, 1 ), 1 ) ), &x1 ); +#else corr_fx = BASOP_Util_Add_Mant32Exp( corr_fx, x1, Mpy_32_32( sumL_fx, sumR_fx ), sub( 62, shl( *q_com, 1 ) ), &x1 ); - +#endif IF( EQ_16( BASOP_Util_Cmp_Mant32Exp( corr_fx, x1, -maxSqrValue_fx, 52 ), -1 ) ) { @@ -955,7 +969,7 @@ static uint16_t enc_ste_pre_mdct( sumR_fx = BASOP_Util_Add_Mant32Exp( sumPrdRR_fx, sumPrdRR_e, temp3, shl( sumMagnR_e, 1 ), &sumR_e ); test(); - IF( LE_32( corr_fx, 0 ) || LE_32( Mpy_32_32( sumL_fx, sumR_fx ), 0 ) ) + IF( ( corr_fx <= 0 ) || ( Mpy_32_32( sumL_fx, sumR_fx ) <= 0 ) ) { corr_fx = 0; move32(); @@ -971,14 +985,14 @@ static uint16_t enc_ste_pre_mdct( test(); test(); test(); - IF( ( GT_32( L_shl( corr_fx, sub( corr_e, s_max( corr_e, 0 ) ) ), L_shl( 1610612736, sub( 0, s_max( corr_e, 0 ) ) ) ) && corrIdxPrev == 0 ) || ( LE_32( L_shl( corr_fx, sub( corr_e, s_max( corr_e, 0 ) ) ), L_shl( 1610612736, sub( 0, s_max( corr_e, 0 ) ) ) ) && corrIdxPrev > 0 ) ) + IF( ( GT_32( L_shl( corr_fx, sub( corr_e, s_max( corr_e, 0 ) ) ), L_shl( 1610612736 /*0.75.Q31*/, sub( 0, s_max( corr_e, 0 ) ) ) ) && corrIdxPrev == 0 ) || ( LE_32( L_shl( corr_fx, sub( corr_e, s_max( corr_e, 0 ) ) ), L_shl( 1610612736 /*0.75.Q31*/, sub( 0, s_max( corr_e, 0 ) ) ) ) && corrIdxPrev > 0 ) ) { stepWeightI_fx = ONE_IN_Q22; move32(); stepWeightD_fx = L_sub( ONE_IN_Q24, stepWeightI_fx ); } test(); - IF( LE_32( L_shl( corr_fx, sub( corr_e, s_max( corr_e, 0 ) ) ), L_shl( 1610612736, sub( 0, s_max( corr_e, 0 ) ) ) ) && corrIdxPrev == 0 ) /* bypass all processing, just return */ + IF( LE_32( L_shl( corr_fx, sub( corr_e, s_max( corr_e, 0 ) ) ), L_shl( 1610612736 /*0.75.Q31*/, sub( 0, s_max( corr_e, 0 ) ) ) ) && corrIdxPrev == 0 ) /* bypass all processing, just return */ { return 0; } @@ -991,7 +1005,7 @@ static uint16_t enc_ste_pre_mdct( xTalkI_fx = stepWeightI_fx; // Q22 xTalkD_fx = imult3216( stepWeightD_fx, sub( shl( fadeInLen, 1 ), 1 ) ); // Q22 - for ( s = sub( fadeInLen, 1 ); s > 0; s--, sigR0_fx++, sigR1_fx++, sigI0_fx++, sigI1_fx++, tmp++ ) + FOR( s = ( fadeInLen - 1 ); s > 0; ( s--, sigR0_fx++, sigR1_fx++, sigI0_fx++, sigI1_fx++, tmp++ ) ) { applyStereoPreProcessingCplx( sigR0_fx, sigR1_fx, sigI0_fx, sigI1_fx, *q_com, xTalkI_fx, xTalkD_fx, chanCorrSign_fx, &x1, &x2, &x3, &x4 ); mdct_exp1[tmp] = x1; @@ -1006,7 +1020,7 @@ static uint16_t enc_ste_pre_mdct( xTalkD_fx = L_sub( xTalkD_fx, stepWeightD_fx ); } - for ( s = preproLen - fadeInLen; s > 0; s--, sigR0_fx++, sigR1_fx++, sigI0_fx++, sigI1_fx++, tmp++ ) + FOR( s = preproLen - fadeInLen; s > 0; ( s--, sigR0_fx++, sigR1_fx++, sigI0_fx++, sigI1_fx++, tmp++ ) ) { applyStereoPreProcessingCplx( sigR0_fx, sigR1_fx, sigI0_fx, sigI1_fx, *q_com, xTalkI_fx, xTalkD_fx, chanCorrSign_fx, &x1, &x2, &x3, &x4 ); mdct_exp1[tmp] = x1; @@ -1021,7 +1035,7 @@ static uint16_t enc_ste_pre_mdct( IF( LT_16( nSampProc, nSamplesMax ) ) /* fade-out of processing at start of IGF range */ { - for ( s = s_min( fadeInLen, nSamplesMax - nSampProc ) - 1; s > 0; s--, sigR0_fx++, sigR1_fx++, sigI0_fx++, sigI1_fx++, tmp++ ) + FOR( s = s_min( fadeInLen, nSamplesMax - nSampProc ) - 1; s > 0; ( s--, sigR0_fx++, sigR1_fx++, sigI0_fx++, sigI1_fx++, tmp++ ) ) { xTalkI_fx = L_sub( xTalkI_fx, stepWeightI_fx ); xTalkD_fx = L_add( xTalkD_fx, stepWeightD_fx ); @@ -1054,18 +1068,18 @@ static uint16_t enc_ste_pre_mdct( FOR( s = 0; s < s_max( nSamplesCore, nSamplesMax ); s++ ) { - sigR0_fx[s] = L_shl( sigR0_fx[s], sub( mdct_exp1[s], shift_r ) ); + sigR0_fx[s] = L_shl( sigR0_fx[s], sub( mdct_exp1[s], shift_r ) ); // mdct_exp1 move32(); - sigI0_fx[s] = L_shl( sigI0_fx[s], sub( mdst_exp1[s], shift_r ) ); + sigI0_fx[s] = L_shl( sigI0_fx[s], sub( mdst_exp1[s], shift_r ) ); // mdct_exp1 move32(); - sigR1_fx[s] = L_shl( sigR1_fx[s], sub( mdct_exp2[s], shift_r ) ); + sigR1_fx[s] = L_shl( sigR1_fx[s], sub( mdct_exp2[s], shift_r ) ); // mdct_exp2 move32(); - sigI1_fx[s] = L_shl( sigI1_fx[s], sub( mdst_exp2[s], shift_r ) ); + sigI1_fx[s] = L_shl( sigI1_fx[s], sub( mdst_exp2[s], shift_r ) ); // mdct_exp2 move32(); } *q_com = sub( 31, shift_r ); move16(); - IF( GT_32( L_shl( corr_fx, sub( corr_e, s_max( corr_e, 0 ) ) ), L_shl( 1610612736, sub( 0, s_max( corr_e, 0 ) ) ) ) ) + IF( GT_32( L_shl( corr_fx, sub( corr_e, s_max( corr_e, 0 ) ) ), L_shl( 1610612736 /*0.75.Q31*/, sub( 0, s_max( corr_e, 0 ) ) ) ) ) { ans = 1; } @@ -1119,12 +1133,12 @@ void enc_prm_igf_mdct( void ivas_mdct_core_whitening_enc_fx( CPE_ENC_HANDLE hCPE, /* i/o: CPE encoder structure */ - Word16 new_samples_fx[CPE_CHANNELS][L_INP], /* i : new samples */ - Word16 old_wsp_fx[CPE_CHANNELS][L_WSP], /* i : 12.8kHz weighted speech (for LTP */ - Word16 pitch_buf_fx[CPE_CHANNELS][NB_SUBFR16k], /* o : floating pitch for each subframe */ - Word32 *mdst_spectrum_long_fx[CPE_CHANNELS], /* o : buffer for MDST spectrum */ + Word16 new_samples_fx[CPE_CHANNELS][L_INP], /* i : new samples Q0*/ + Word16 old_wsp_fx[CPE_CHANNELS][L_WSP], /* i : 12.8kHz weighted speech (for LTP Qx*/ + Word16 pitch_buf_fx[CPE_CHANNELS][NB_SUBFR16k], /* o : floating pitch for each subframe Q6*/ + Word32 *mdst_spectrum_long_fx[CPE_CHANNELS], /* o : buffer for MDST spectrum mdst_spectrum_e*/ Word16 tnsBits[CPE_CHANNELS][NB_DIV], /* o : buffer TNS bits */ - Word32 *orig_spectrum_long[CPE_CHANNELS], /* o : origingal spectrum w/o whitening */ + Word32 *orig_spectrum_long[CPE_CHANNELS], /* o : origingal spectrum w/o whitening orig_spectrum_e*/ Word16 tnsSize[CPE_CHANNELS][NB_DIV], /* o : number of tns parameters put into prm */ Word16 p_param[CPE_CHANNELS][NB_DIV], /* o : pointer to the parameter table */ BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ @@ -1152,6 +1166,7 @@ void ivas_mdct_core_whitening_enc_fx( Word32 scf_fx[CPE_CHANNELS][NB_DIV][M]; Word32 scf_q_fx[CPE_CHANNELS][NB_DIV][M]; Word64 chE_fx[2], chE_tot_fx; + Word16 chE_q[2]; Word8 sns_low_br_mode; Word16 nbits_start_sns; Word16 num_sns; @@ -1171,7 +1186,7 @@ void ivas_mdct_core_whitening_enc_fx( { FOR( i = 0; i < NB_DIV; i++ ) { - set32_fx( scf_fx[ch][i], 0, M ); + set32_fx( scf_fx[ch][i], 0, M ); // scf_q_fx set32_fx( scf_q_fx[ch][i], 0, M ); } set16_fx( A_q_fx[ch][0], 0, M + 1 ); @@ -1242,7 +1257,7 @@ void ivas_mdct_core_whitening_enc_fx( move32(); move32(); - sts[0]->hTcxEnc->tcxltp_norm_corr_past = sts[1]->hTcxEnc->tcxltp_norm_corr_past = extract_l( L_shr( L_add( sts[0]->hTcxEnc->tcxltp_norm_corr_past, sts[1]->hTcxEnc->tcxltp_norm_corr_past ), 1 ) ); + sts[0]->hTcxEnc->tcxltp_norm_corr_past = sts[1]->hTcxEnc->tcxltp_norm_corr_past = extract_l( L_shr( L_add( sts[0]->hTcxEnc->tcxltp_norm_corr_past, sts[1]->hTcxEnc->tcxltp_norm_corr_past ), 1 ) ); // Q15 move16(); move16(); @@ -1393,10 +1408,10 @@ void ivas_mdct_core_whitening_enc_fx( q_com = s_min( Q31, add( q_min, q_com ) ); - Scale_sig32( hTcxEnc0->spectrum_fx[n], shr( hTcxEnc0->L_frameTCX, shift ) /*hTcxEnc0->L_frameTCX / nSubframes*/, sub( q_com, sub( Q31, hTcxEnc0->spectrum_e[n] ) ) ); - Scale_sig32( hTcxEnc1->spectrum_fx[n], shr( hTcxEnc1->L_frameTCX, shift ) /*hTcxEnc1->L_frameTCX / nSubframes*/, sub( q_com, sub( Q31, hTcxEnc1->spectrum_e[n] ) ) ); - Scale_sig32( mdst_spectrum_fx[0][n], shr( hTcxEnc0->L_frameTCX, shift ) /*hTcxEnc0->L_frameTCX / nSubframes*/, sub( q_com, sub( Q31, mdst_spectrum_e[0][n] ) ) ); - Scale_sig32( mdst_spectrum_fx[1][n], shr( hTcxEnc1->L_frameTCX, shift ) /*hTcxEnc1->L_frameTCX / nSubframes*/, sub( q_com, sub( Q31, mdst_spectrum_e[1][n] ) ) ); + Scale_sig32( hTcxEnc0->spectrum_fx[n], shr( hTcxEnc0->L_frameTCX, shift ) /*hTcxEnc0->L_frameTCX / nSubframes*/, sub( q_com, sub( Q31, hTcxEnc0->spectrum_e[n] ) ) ); // q_com + Scale_sig32( hTcxEnc1->spectrum_fx[n], shr( hTcxEnc1->L_frameTCX, shift ) /*hTcxEnc1->L_frameTCX / nSubframes*/, sub( q_com, sub( Q31, hTcxEnc1->spectrum_e[n] ) ) ); // q_com + Scale_sig32( mdst_spectrum_fx[0][n], shr( hTcxEnc0->L_frameTCX, shift ) /*hTcxEnc0->L_frameTCX / nSubframes*/, sub( q_com, sub( Q31, mdst_spectrum_e[0][n] ) ) ); // q_com + Scale_sig32( mdst_spectrum_fx[1][n], shr( hTcxEnc1->L_frameTCX, shift ) /*hTcxEnc1->L_frameTCX / nSubframes*/, sub( q_com, sub( Q31, mdst_spectrum_e[1][n] ) ) ); // q_com const Word16 switchKernel = /* these 4 transform types can be applied: 0 = MDCT-IV, 1 = MDST-II, 2 = MDCT-II, 3 = MDST-IV */ kernel_switch_detect_fx( hTcxEnc0->spectrum_fx[n], hTcxEnc1->spectrum_fx[n], mdst_spectrum_fx[0][n], mdst_spectrum_fx[1][n], q_com, nSampCore / nSubframes, @@ -1462,7 +1477,7 @@ void ivas_mdct_core_whitening_enc_fx( hTcxEnc0->kernel_type[n] = 0; move16(); - if ( hTcxEnc0->kernel_symmetry_past ) + IF( hTcxEnc0->kernel_symmetry_past ) { hTcxEnc0->kernel_type[n] = 3; move16(); @@ -1470,7 +1485,7 @@ void ivas_mdct_core_whitening_enc_fx( hTcxEnc1->kernel_type[n] = 0; move16(); - if ( hTcxEnc1->kernel_symmetry_past ) + IF( hTcxEnc1->kernel_symmetry_past ) { hTcxEnc1->kernel_type[n] = 3; move16(); @@ -1487,8 +1502,8 @@ void ivas_mdct_core_whitening_enc_fx( q_com = s_min( L_norm_arr( hTcxEnc0->spectrum_fx[n], shr( hTcxEnc0->L_frameTCX, shift ) /*hTcxEnc0->L_frameTCX / nSubframes*/ ), L_norm_arr( mdst_spectrum_fx[0][n], shr( hTcxEnc0->L_frameTCX, shift ) /*hTcxEnc0->L_frameTCX / nSubframes*/ ) ); q_com = s_min( Q31, add( q_min, q_com ) ); - Scale_sig32( hTcxEnc0->spectrum_fx[n], shr( hTcxEnc0->L_frameTCX, shift ) /*hTcxEnc0->L_frameTCX / nSubframes*/, sub( q_com, sub( Q31, hTcxEnc0->spectrum_e[n] ) ) ); - Scale_sig32( mdst_spectrum_fx[0][n], shr( hTcxEnc0->L_frameTCX, shift ) /*hTcxEnc0->L_frameTCX / nSubframes*/, sub( q_com, sub( Q31, mdst_spectrum_e[0][n] ) ) ); + Scale_sig32( hTcxEnc0->spectrum_fx[n], shr( hTcxEnc0->L_frameTCX, shift ) /*hTcxEnc0->L_frameTCX / nSubframes*/, sub( q_com, sub( Q31, hTcxEnc0->spectrum_e[n] ) ) ); // q_com + Scale_sig32( mdst_spectrum_fx[0][n], shr( hTcxEnc0->L_frameTCX, shift ) /*hTcxEnc0->L_frameTCX / nSubframes*/, sub( q_com, sub( Q31, mdst_spectrum_e[0][n] ) ) ); // q_com speech = NULL; if ( NE_16( n, 1 ) ) @@ -1508,8 +1523,8 @@ void ivas_mdct_core_whitening_enc_fx( q_com = s_min( L_norm_arr( hTcxEnc1->spectrum_fx[n], shr( hTcxEnc1->L_frameTCX, shift ) /*hTcxEnc1->L_frameTCX / nSubframes*/ ), L_norm_arr( mdst_spectrum_fx[1][n], shr( hTcxEnc1->L_frameTCX, shift ) /*hTcxEnc1->L_frameTCX / nSubframes*/ ) ); q_com = s_min( Q31, add( q_min, q_com ) ); - Scale_sig32( hTcxEnc1->spectrum_fx[n], shr( hTcxEnc1->L_frameTCX, shift ) /*hTcxEnc1->L_frameTCX / nSubframes*/, sub( q_com, sub( Q31, hTcxEnc1->spectrum_e[n] ) ) ); - Scale_sig32( mdst_spectrum_fx[1][n], shr( hTcxEnc1->L_frameTCX, shift ) /*hTcxEnc1->L_frameTCX / nSubframes*/, sub( q_com, sub( Q31, mdst_spectrum_e[1][n] ) ) ); + Scale_sig32( hTcxEnc1->spectrum_fx[n], shr( hTcxEnc1->L_frameTCX, shift ) /*hTcxEnc1->L_frameTCX / nSubframes*/, sub( q_com, sub( Q31, hTcxEnc1->spectrum_e[n] ) ) ); // q_com + Scale_sig32( mdst_spectrum_fx[1][n], shr( hTcxEnc1->L_frameTCX, shift ) /*hTcxEnc1->L_frameTCX / nSubframes*/, sub( q_com, sub( Q31, mdst_spectrum_e[1][n] ) ) ); // q_com speech = NULL; if ( NE_16( n, 1 ) ) @@ -1541,27 +1556,30 @@ void ivas_mdct_core_whitening_enc_fx( } IF( EQ_16( hTcxEnc0->transform_type[n], TCX_5 ) ) { - Word16 length; + Word16 length, len_sbfr; const Word16 tcx5SizeFB = sts[1]->hTcxCfg->tcx5SizeFB; move16(); /* length = max(nSampCore / (2 * NB_DIV), L_subframeTCX / (2 * NB_DIV), NB_DIV = 2 */ length = shr( s_max( nSampCore, L_subframeTCX ), 2 ); + len_sbfr = shr( hTcxEnc0->L_frameTCX, shift ); + assert( hTcxEnc0->L_frameTCX == hTcxEnc1->L_frameTCX ); exp_max = s_max( hTcxEnc0->spectrum_e[n], hTcxEnc1->spectrum_e[n] ); exp_max = s_max( exp_max, mdst_spectrum_e[0][n] ); exp_max = s_max( exp_max, mdst_spectrum_e[1][n] ); // calculate the headroom available - exp_com = s_min( L_norm_arr( hTcxEnc1->spectrum_fx[n], length ), L_norm_arr( hTcxEnc0->spectrum_fx[n], length ) ); - exp_com = s_min( exp_com, L_norm_arr( mdst_spectrum_fx[0][n], length ) ); - exp_com = s_min( exp_com, L_norm_arr( mdst_spectrum_fx[1][n], length ) ); + exp_com = s_min( L_norm_arr( hTcxEnc1->spectrum_fx[n], len_sbfr ), L_norm_arr( hTcxEnc0->spectrum_fx[n], len_sbfr ) ); + exp_com = s_min( exp_com, L_norm_arr( mdst_spectrum_fx[0][n], len_sbfr ) ); + exp_com = s_min( exp_com, L_norm_arr( mdst_spectrum_fx[1][n], len_sbfr ) ); q_com = sub( s_min( Q31, add( sub( Q31, exp_max ), exp_com ) ), 6 ); // 6 guarded bits + q_com = s_max( q_com, 9 ); // Keep the Q-factor at least 9 to avoid precision loss inside enc_ste_pre_mdct. exp_com = sub( Q31, q_com ); - Scale_sig32( hTcxEnc0->spectrum_fx[n], shr( hTcxEnc0->L_frameTCX, shift ) /* hTcxEnc0->L_frameTCX/nSubframes */, sub( hTcxEnc0->spectrum_e[n], exp_com ) ); - Scale_sig32( hTcxEnc1->spectrum_fx[n], shr( hTcxEnc1->L_frameTCX, shift ) /* hTcxEnc1->L_frameTCX/nSubframes */, sub( hTcxEnc1->spectrum_e[n], exp_com ) ); - Scale_sig32( mdst_spectrum_fx[0][n], shr( hTcxEnc0->L_frameTCX, shift ) /* hTcxEnc0->L_frameTCX/nSubframes */, sub( mdst_spectrum_e[0][n], exp_com ) ); - Scale_sig32( mdst_spectrum_fx[1][n], shr( hTcxEnc1->L_frameTCX, shift ) /* hTcxEnc1->L_frameTCX/nSubframes */, sub( mdst_spectrum_e[1][n], exp_com ) ); + scale_sig32( hTcxEnc0->spectrum_fx[n], len_sbfr /* hTcxEnc0->L_frameTCX/nSubframes */, sub( hTcxEnc0->spectrum_e[n], exp_com ) ); // hTcxEnc0->spectrum_e + scale_sig32( hTcxEnc1->spectrum_fx[n], len_sbfr /* hTcxEnc1->L_frameTCX/nSubframes */, sub( hTcxEnc1->spectrum_e[n], exp_com ) ); // hTcxEnc1->spectrum_e + scale_sig32( mdst_spectrum_fx[0][n], len_sbfr /* hTcxEnc0->L_frameTCX/nSubframes */, sub( mdst_spectrum_e[0][n], exp_com ) ); // mdst_spectrum_e + scale_sig32( mdst_spectrum_fx[1][n], len_sbfr /* hTcxEnc1->L_frameTCX/nSubframes */, sub( mdst_spectrum_e[1][n], exp_com ) ); // mdst_spectrum_e Word16 q_com_orig = q_com; move16(); @@ -1576,26 +1594,27 @@ void ivas_mdct_core_whitening_enc_fx( IF( NE_16( q_com_orig, q_com ) ) { Word16 scale = sub( q_com, q_com_orig ); - Scale_sig32( hTcxEnc0->spectrum_fx[n] + length, offset2, scale ); - Scale_sig32( hTcxEnc1->spectrum_fx[n] + length, offset2, scale ); - Scale_sig32( mdst_spectrum_fx[0][n] + length, offset2, scale ); - Scale_sig32( mdst_spectrum_fx[1][n] + length, offset2, scale ); + Scale_sig32( hTcxEnc0->spectrum_fx[n] + length, offset2, scale ); // q_com + Scale_sig32( hTcxEnc1->spectrum_fx[n] + length, offset2, scale ); // q_com + Scale_sig32( mdst_spectrum_fx[0][n] + length, offset2, scale ); // q_com + Scale_sig32( mdst_spectrum_fx[1][n] + length, offset2, scale ); // q_com } exp_max = sub( Q31, q_com ); move16(); - exp_com = s_min( L_norm_arr( hTcxEnc1->spectrum_fx[n], shr( hTcxEnc1->L_frameTCX, shift ) /* hTcxEnc1->L_frameTCX/nSubframes */ ), L_norm_arr( hTcxEnc0->spectrum_fx[n], shr( hTcxEnc0->L_frameTCX, shift ) /* hTcxEnc0->L_frameTCX/nSubframes */ ) ); - exp_com = s_min( exp_com, L_norm_arr( mdst_spectrum_fx[0][n], shr( hTcxEnc0->L_frameTCX, shift ) /* hTcxEnc0->L_frameTCX/nSubframes */ ) ); - exp_com = s_min( exp_com, L_norm_arr( mdst_spectrum_fx[1][n], shr( hTcxEnc1->L_frameTCX, shift ) /* hTcxEnc1->L_frameTCX/nSubframes */ ) ); + exp_com = s_min( L_norm_arr( hTcxEnc1->spectrum_fx[n], len_sbfr /* hTcxEnc1->L_frameTCX/nSubframes */ ), L_norm_arr( hTcxEnc0->spectrum_fx[n], len_sbfr /* hTcxEnc0->L_frameTCX/nSubframes */ ) ); + exp_com = s_min( exp_com, L_norm_arr( mdst_spectrum_fx[0][n], len_sbfr /* hTcxEnc0->L_frameTCX/nSubframes */ ) ); + exp_com = s_min( exp_com, L_norm_arr( mdst_spectrum_fx[1][n], len_sbfr /* hTcxEnc1->L_frameTCX/nSubframes */ ) ); q_com = sub( s_min( Q31, add( q_com, exp_com ) ), 6 ); + q_com = s_max( q_com, 9 ); // Keep the Q-factor at least 9 to avoid precision loss inside enc_ste_pre_mdct. exp_com = sub( Q31, q_com ); - Scale_sig32( hTcxEnc0->spectrum_fx[n], shr( hTcxEnc0->L_frameTCX, shift ) /* hTcxEnc0->L_frameTCX/nSubframes */, sub( exp_max, exp_com ) ); - Scale_sig32( hTcxEnc1->spectrum_fx[n], shr( hTcxEnc1->L_frameTCX, shift ) /* hTcxEnc1->L_frameTCX/nSubframes */, sub( exp_max, exp_com ) ); - Scale_sig32( mdst_spectrum_fx[0][n], shr( hTcxEnc0->L_frameTCX, shift ) /* hTcxEnc0->L_frameTCX/nSubframes */, sub( exp_max, exp_com ) ); - Scale_sig32( mdst_spectrum_fx[1][n], shr( hTcxEnc1->L_frameTCX, shift ) /* hTcxEnc1->L_frameTCX/nSubframes */, sub( exp_max, exp_com ) ); + scale_sig32( hTcxEnc0->spectrum_fx[n], len_sbfr /* hTcxEnc0->L_frameTCX/nSubframes */, sub( exp_max, exp_com ) ); // exp_max + scale_sig32( hTcxEnc1->spectrum_fx[n], len_sbfr /* hTcxEnc1->L_frameTCX/nSubframes */, sub( exp_max, exp_com ) ); // exp_max + scale_sig32( mdst_spectrum_fx[0][n], len_sbfr /* hTcxEnc0->L_frameTCX/nSubframes */, sub( exp_max, exp_com ) ); // exp_max + scale_sig32( mdst_spectrum_fx[1][n], len_sbfr /* hTcxEnc1->L_frameTCX/nSubframes */, sub( exp_max, exp_com ) ); // exp_max q_com_orig = q_com; move16(); @@ -1607,15 +1626,19 @@ void ivas_mdct_core_whitening_enc_fx( IF( NE_16( q_com_orig, q_com ) ) { Word16 scale = sub( q_com, q_com_orig ); - Scale_sig32( hTcxEnc0->spectrum_fx[n], tcx5SizeFB, scale ); - Scale_sig32( hTcxEnc1->spectrum_fx[n], tcx5SizeFB, scale ); - Scale_sig32( mdst_spectrum_fx[0][n], tcx5SizeFB, scale ); - Scale_sig32( mdst_spectrum_fx[1][n], tcx5SizeFB, scale ); - - Scale_sig32( hTcxEnc0->spectrum_fx[n] + offset1, offset2, scale ); - Scale_sig32( hTcxEnc1->spectrum_fx[n] + offset1, offset2, scale ); - Scale_sig32( mdst_spectrum_fx[0][n] + offset1, offset2, scale ); - Scale_sig32( mdst_spectrum_fx[1][n] + offset1, offset2, scale ); + Scale_sig32( hTcxEnc0->spectrum_fx[n], tcx5SizeFB, scale ); // q_com + Scale_sig32( hTcxEnc1->spectrum_fx[n], tcx5SizeFB, scale ); // q_com + Scale_sig32( mdst_spectrum_fx[0][n], tcx5SizeFB, scale ); // q_com + Scale_sig32( mdst_spectrum_fx[1][n], tcx5SizeFB, scale ); // q_com + + offset2 = sub( idiv1616( hTcxEnc0->L_frameTCX, nSubframes ), offset1 ); + IF( offset2 > 0 ) + { + Scale_sig32( hTcxEnc0->spectrum_fx[n] + offset1, offset2, scale ); // q_com + Scale_sig32( hTcxEnc1->spectrum_fx[n] + offset1, offset2, scale ); // q_com + Scale_sig32( mdst_spectrum_fx[0][n] + offset1, offset2, scale ); // q_com + Scale_sig32( mdst_spectrum_fx[1][n] + offset1, offset2, scale ); // q_com + } } mdst_spectrum_e[0][n] = sub( Q31, q_com ); hTcxEnc0->spectrum_e[n] = sub( Q31, q_com ); @@ -1642,10 +1665,10 @@ void ivas_mdct_core_whitening_enc_fx( q_com = sub( s_min( Q31, add( sub( Q31, exp_max ), exp_com ) ), 6 ); exp_com = sub( Q31, q_com ); - Scale_sig32( hTcxEnc0->spectrum_fx[n], shr( hTcxEnc0->L_frameTCX, shift ) /* hTcxEnc0->L_frameTCX/nSubframes */, sub( hTcxEnc0->spectrum_e[n], exp_com ) ); - Scale_sig32( hTcxEnc1->spectrum_fx[n], shr( hTcxEnc1->L_frameTCX, shift ) /* hTcxEnc1->L_frameTCX/nSubframes */, sub( hTcxEnc1->spectrum_e[n], exp_com ) ); - Scale_sig32( mdst_spectrum_fx[0][n], shr( hTcxEnc0->L_frameTCX, shift ) /* hTcxEnc0->L_frameTCX/nSubframes */, sub( mdst_spectrum_e[0][n], exp_com ) ); - Scale_sig32( mdst_spectrum_fx[1][n], shr( hTcxEnc1->L_frameTCX, shift ) /* hTcxEnc1->L_frameTCX/nSubframes */, sub( mdst_spectrum_e[1][n], exp_com ) ); + Scale_sig32( hTcxEnc0->spectrum_fx[n], shr( hTcxEnc0->L_frameTCX, shift ) /* hTcxEnc0->L_frameTCX/nSubframes */, sub( hTcxEnc0->spectrum_e[n], exp_com ) ); // hTcxEnc0->spectrum_e + Scale_sig32( hTcxEnc1->spectrum_fx[n], shr( hTcxEnc1->L_frameTCX, shift ) /* hTcxEnc1->L_frameTCX/nSubframes */, sub( hTcxEnc1->spectrum_e[n], exp_com ) ); // hTcxEnc0->spectrum_e + Scale_sig32( mdst_spectrum_fx[0][n], shr( hTcxEnc0->L_frameTCX, shift ) /* hTcxEnc0->L_frameTCX/nSubframes */, sub( mdst_spectrum_e[0][n], exp_com ) ); // mdst_spectrum_e + Scale_sig32( mdst_spectrum_fx[1][n], shr( hTcxEnc1->L_frameTCX, shift ) /* hTcxEnc1->L_frameTCX/nSubframes */, sub( mdst_spectrum_e[1][n], exp_com ) ); // mdst_spectrum_e Word16 q_com_orig = q_com; move16(); @@ -1656,10 +1679,10 @@ void ivas_mdct_core_whitening_enc_fx( IF( NE_16( q_com_orig, q_com ) ) { Word16 scale = sub( q_com, q_com_orig ); - Scale_sig32( hTcxEnc0->spectrum_fx[n] + length, offset2, scale ); - Scale_sig32( hTcxEnc1->spectrum_fx[n] + length, offset2, scale ); - Scale_sig32( mdst_spectrum_fx[0][n] + length, offset2, scale ); - Scale_sig32( mdst_spectrum_fx[1][n] + length, offset2, scale ); + Scale_sig32( hTcxEnc0->spectrum_fx[n] + length, offset2, scale ); // q_com + Scale_sig32( hTcxEnc1->spectrum_fx[n] + length, offset2, scale ); // q_com + Scale_sig32( mdst_spectrum_fx[0][n] + length, offset2, scale ); // q_com + Scale_sig32( mdst_spectrum_fx[1][n] + length, offset2, scale ); // q_com } exp_com = sub( Q31, q_com ); mdst_spectrum_e[0][n] = exp_com; @@ -1734,8 +1757,8 @@ void ivas_mdct_core_whitening_enc_fx( q_com = s_min( Q31, add( q_min, q_com ) ); - Scale_sig32( hTcxEncCh->spectrum_fx[n], shr( hTcxEncCh->L_frameTCX, shift ) /*hTcxEncCh->L_frameTCX / nSubframes*/, sub( q_com, sub( Q31, hTcxEncCh->spectrum_e[n] ) ) ); - Scale_sig32( mdst_spectrum_fx[ch][n], shr( hTcxEncCh->L_frameTCX, shift ) /*hTcxEncCh->L_frameTCX / nSubframes*/, sub( q_com, sub( Q31, mdst_spectrum_e[ch][n] ) ) ); + Scale_sig32( hTcxEncCh->spectrum_fx[n], shr( hTcxEncCh->L_frameTCX, shift ) /*hTcxEncCh->L_frameTCX / nSubframes*/, sub( q_com, sub( Q31, hTcxEncCh->spectrum_e[n] ) ) ); // q_com + Scale_sig32( mdst_spectrum_fx[ch][n], shr( hTcxEncCh->L_frameTCX, shift ) /*hTcxEncCh->L_frameTCX / nSubframes*/, sub( q_com, sub( Q31, mdst_spectrum_e[ch][n] ) ) ); // q_com speech = hTcxEncCh->speech_TCX; if ( n != 0 ) @@ -1797,7 +1820,7 @@ void ivas_mdct_core_whitening_enc_fx( } FOR( n = 0; n < nSubframes; n++ ) { - Scale_sig32( hTcxEnc->spectrum_fx[n], shr( hTcxEnc->L_frameTCX, shift ) /*hTcxEnc->L_frameTCX / nSubframes*/, sub( q_com, sub( Q31, hTcxEnc->spectrum_e[n] ) ) ); + Scale_sig32( hTcxEnc->spectrum_fx[n], shr( hTcxEnc->L_frameTCX, shift ) /*hTcxEnc->L_frameTCX / nSubframes*/, sub( q_com, sub( Q31, hTcxEnc->spectrum_e[n] ) ) ); // q_com hTcxEnc->spectrum_e[n] = sub( Q31, q_com ); move16(); } @@ -1855,8 +1878,8 @@ void ivas_mdct_core_whitening_enc_fx( } FOR( n = 0; n < nSubframes; n++ ) { - Scale_sig32( hTcxEnc->spectrum_fx[n], shr( hTcxEnc->L_frameTCX, shift ) /*hTcxEnc->L_frameTCX / nSubframes*/, sub( q_com, sub( Q31, hTcxEnc->spectrum_e[n] ) ) ); - Scale_sig32( mdst_spectrum_fx[ch][n], shr( hTcxEnc->L_frameTCX, shift ) /*hTcxEnc->L_frameTCX / nSubframes*/, sub( q_com, sub( Q31, mdst_spectrum_e[ch][n] ) ) ); + Scale_sig32( hTcxEnc->spectrum_fx[n], shr( hTcxEnc->L_frameTCX, shift ) /*hTcxEnc->L_frameTCX / nSubframes*/, sub( q_com, sub( Q31, hTcxEnc->spectrum_e[n] ) ) ); // q_com + Scale_sig32( mdst_spectrum_fx[ch][n], shr( hTcxEnc->L_frameTCX, shift ) /*hTcxEnc->L_frameTCX / nSubframes*/, sub( q_com, sub( Q31, mdst_spectrum_e[ch][n] ) ) ); // q_com hTcxEnc->spectrum_e[n] = sub( Q31, q_com ); move16(); mdst_spectrum_e[ch][n] = sub( Q31, q_com ); @@ -1885,6 +1908,7 @@ void ivas_mdct_core_whitening_enc_fx( IF( mct_on ) { set64_fx( chE_fx, 0, NB_DIV ); + set16_fx( chE_q, 0, NB_DIV ); } init_tcx_enc_info_fx( st, &L_subframe, &L_subframeTCX, &tcx_subframe_coded_lines ); @@ -1902,7 +1926,6 @@ void ivas_mdct_core_whitening_enc_fx( tcx_subframe_coded_lines = shr( tcx_subframe_coded_lines, shift ); /*tcx_subframe_coded_lines / nSubframes*/ Word16 q_pow = 62, q_pow_tmp = sub( 63, shl( mdst_spectrum_e[0][0], 1 ) ); // add( shl( sub( Q31, mdst_spectrum_e[0][0] ), 1 ), 1 ); move16(); - FOR( n = 0; n < nSubframes; n++ ) { IF( st->hTcxEnc->fUseTns[n] ) @@ -1911,34 +1934,19 @@ void ivas_mdct_core_whitening_enc_fx( { powerSpec_fx64[i] = W_mult_32_32( st->hTcxEnc->spectrum_fx[n][i], st->hTcxEnc->spectrum_fx[n][i] ); move64(); - IF( powerSpec_fx64[i] == 0 ) - { - q_pow = s_min( q_pow, 62 ); - } - ELSE - - { - q_pow = s_min( q_pow, W_norm( powerSpec_fx64[i] ) ); - } } + q_pow = W_norm_arr( powerSpec_fx64, L_subframeTCX ); } ELSE { FOR( i = 0; i < L_subframeTCX; i++ ) { - powerSpec_fx64[i] = W_add( W_mult_32_32( mdst_spectrum_fx[ch][n][i], mdst_spectrum_fx[ch][n][i] ), W_mult_32_32( st->hTcxEnc->spectrum_fx[n][i], st->hTcxEnc->spectrum_fx[n][i] ) ); + powerSpec_fx64[i] = W_mac_32_32( W_mult_32_32( mdst_spectrum_fx[ch][n][i], mdst_spectrum_fx[ch][n][i] ), st->hTcxEnc->spectrum_fx[n][i], st->hTcxEnc->spectrum_fx[n][i] ); move64(); - IF( powerSpec_fx64[i] == 0 ) - { - q_pow = s_min( q_pow, 62 ); - } - ELSE - - { - q_pow = s_min( q_pow, W_norm( powerSpec_fx64[i] ) ); - } } + q_pow = W_norm_arr( powerSpec_fx64, L_subframeTCX ); } + FOR( i = 0; i < L_subframeTCX; i++ ) { powerSpec_fx64[i] = W_shl( powerSpec_fx64[i], q_pow ); @@ -1953,6 +1961,8 @@ void ivas_mdct_core_whitening_enc_fx( chE_fx[n] = W_add( W_deposit32_l( powerSpec_fx[i] ), chE_fx[n] ); move64(); } + chE_q[n] = sub( add( q_pow_tmp, q_pow ), 32 ); + move16(); } sns_compute_scf_fx( powerSpec_fx, st->hTcxCfg->psychParamsCurrent, st->L_frame, scf_fx[ch][n], sub( add( q_pow_tmp, q_pow ), 32 ) ); } @@ -1960,14 +1970,14 @@ void ivas_mdct_core_whitening_enc_fx( /* MCT: detect whether there are silent channels and set mct_chan_mode accordingly */ IF( mct_on ) { - Word16 q = sub( add( q_pow_tmp, q_pow ), 32 ); + Word16 q = s_min( chE_q[0], chE_q[1] ); Word64 silent_thr = SILENT_CHANNEL_THRES_FX; move64(); chE_tot_fx = 0; move64(); FOR( i = 0; i < NB_DIV; i++ ) { - chE_tot_fx = W_add( chE_fx[i], chE_tot_fx ); + chE_tot_fx = W_add( W_shr( chE_fx[i], sub( chE_q[i], q ) ), chE_tot_fx ); } IF( GT_16( q, Q24 ) ) { @@ -2088,8 +2098,13 @@ void ivas_mdct_core_whitening_enc_fx( st->hTcxEnc->spectrum_e[n] = sub( st->hTcxEnc->spectrum_e[n], q_com ); move16(); + Word16 exp_tmp = st->hTcxEnc->spectrum_e[n]; + move16(); + /* Shape spectrum */ ShapeSpectrum_ivas_fx( st->hTcxCfg, A_q_fx[ch][n], NULL, NULL, L_subframe, tcx_subframe_coded_lines, st->hTcxEnc->spectrum_fx[n], &st->hTcxEnc->spectrum_e[n], st->hTcxEnc->fUseTns[n], st, scf_q_fx[ch][n] ); + + Scale_sig32( st->hTcxEnc->spectrum_fx[n] + L_subframe, sub( L_subframeTCX, L_subframe ), sub( exp_tmp, st->hTcxEnc->spectrum_e[n] ) ); } } /*--------------------------------------------------------------* @@ -2175,7 +2190,7 @@ void ivas_mdct_core_whitening_enc_fx( FOR( n = 0; n < nSubframes; n++ ) { - Scale_sig32( hTcxEnc->spectrum_fx[n], shr( hTcxEnc->L_frameTCX, shift ) /*hTcxEnc->L_frameTCX / nSubframes*/, sub( q_com, sub( 31, hTcxEnc->spectrum_e[n] ) ) ); + Scale_sig32( hTcxEnc->spectrum_fx[n], shr( hTcxEnc->L_frameTCX, shift ) /*hTcxEnc->L_frameTCX / nSubframes*/, sub( q_com, sub( 31, hTcxEnc->spectrum_e[n] ) ) ); // q_com hTcxEnc->spectrum_e[n] = sub( 31, q_com ); move16(); } @@ -2223,8 +2238,13 @@ void ivas_mdct_core_whitening_enc_fx( mdst_spectrum_e[ch][n] = sub( mdst_spectrum_e[ch][n], q_com ); move16(); + Word16 exp_tmp = mdst_spectrum_e[ch][n]; + move16(); + /* Shape spectrum */ ShapeSpectrum_ivas_fx( st->hTcxCfg, A_q_fx[ch][n], NULL, NULL, L_subframe, tcx_subframe_coded_lines, mdst_spectrum_fx[ch][n], &mdst_spectrum_e[ch][n], st->hTcxEnc->fUseTns[n], st, scf_q_fx[ch][n] ); + + Scale_sig32( mdst_spectrum_fx[ch][n] + L_subframe, sub( L_subframeTCX, L_subframe ), sub( exp_tmp, mdst_spectrum_e[ch][n] ) ); } } } @@ -2463,7 +2483,7 @@ void ivas_mdct_core_whitening_enc_fx( } ELSE { - set16_fx( pitch_buf_fx[ch], L_SUBFR << Q6, NB_SUBFR16k ); + set16_fx( pitch_buf_fx[ch], L_SUBFR << Q6, NB_SUBFR16k ); // Q6 } } @@ -2493,11 +2513,11 @@ void ivas_mdct_quant_coder_fx( Word16 nbits_start, total_nbbits; Word16 fac_ns_fx[CPE_CHANNELS][NB_DIV]; /* noise filling level */ - Word32 ener_fx[CPE_CHANNELS][NB_DIV]; /* energy of the quantized spectrum */ - Word16 gain_tcx_fx[CPE_CHANNELS][NB_DIV]; /* global gain */ + Word32 ener_fx[CPE_CHANNELS][NB_DIV]; /* energy of the quantized spectrum ener_e*/ + Word16 gain_tcx_fx[CPE_CHANNELS][NB_DIV]; /* global gain gain_tcx_e*/ Word16 gain_tcx_e[CPE_CHANNELS][NB_DIV]; Word32 quantized_spectrum_long_fx[CPE_CHANNELS][N_MAX]; /* quantized MDCT spectrum, inv ms mask mdst spectrum, scratch for MS spectra in the MS decision */ - Word32 *quantized_spectrum_fx[CPE_CHANNELS][NB_DIV]; + Word32 *quantized_spectrum_fx[CPE_CHANNELS][NB_DIV]; // quantized_spectrum_e Word16 quantized_spectrum_e[CPE_CHANNELS][NB_DIV]; Word16 ener_e[CPE_CHANNELS][NB_DIV]; @@ -2527,7 +2547,7 @@ void ivas_mdct_quant_coder_fx( { ignore_chan[ch] = 1; move16(); - continue; + CONTINUE; } IF( EQ_16( st->hTcxEnc->tcxMode, TCX_20 ) ) @@ -2599,17 +2619,17 @@ void ivas_mdct_quant_coder_fx( IF( EQ_16( st->mct_chan_mode, MCT_CHAN_MODE_IGNORE ) ) { - continue; + CONTINUE; } FOR( n = 0; n < nSubframes; n++ ) { temp_scale = getScaleFactor32( quantized_spectrum_fx[ch][n], L_spec[ch][n] ); - scale_sig32( quantized_spectrum_fx[ch][n], L_spec[ch][n], temp_scale ); + scale_sig32( quantized_spectrum_fx[ch][n], L_spec[ch][n], temp_scale ); // quantized_spectrum_e quantized_spectrum_e[ch][n] = sub( quantized_spectrum_e[ch][n], temp_scale ); min_shift = s_max( min_shift, quantized_spectrum_e[ch][n] ); temp_scale = getScaleFactor32( st->hTcxEnc->spectrum_fx[n], L_spec[ch][n] ); - scale_sig32( st->hTcxEnc->spectrum_fx[n], L_spec[ch][n], temp_scale ); + scale_sig32( st->hTcxEnc->spectrum_fx[n], L_spec[ch][n], temp_scale ); // st->hTcxEnc->spectrum_e st->hTcxEnc->spectrum_e[n] = sub( st->hTcxEnc->spectrum_e[n], temp_scale ); min_shift = s_max( min_shift, st->hTcxEnc->spectrum_e[n] ); } @@ -2630,7 +2650,7 @@ void ivas_mdct_quant_coder_fx( IF( EQ_16( st->mct_chan_mode, MCT_CHAN_MODE_IGNORE ) ) { - continue; + CONTINUE; } FOR( n = 0; n < nSubframes; n++ ) @@ -2642,6 +2662,11 @@ void ivas_mdct_quant_coder_fx( st->hTcxEnc->spectrum_e[n] = min_shift; move16(); } + if ( GT_16( nSubframes, 1 ) ) + { + st->hTcxEnc->spectrum_long_e = min_shift; + move16(); + } } EstimateStereoTCXNoiseLevel_fx( sts, quantized_spectrum_fx, gain_tcx_fx, gain_tcx_e, L_frame, noiseFillingBorder, hm_active, ignore_chan, fac_ns_fx, param_core, MCT_flag ); @@ -2709,16 +2734,17 @@ void ivas_mdct_quant_coder_fx( * Generate Bitstream *---------------------------------------------------------------*/ - if ( EQ_16( st->mct_chan_mode, MCT_CHAN_MODE_IGNORE ) ) + IF( EQ_16( st->mct_chan_mode, MCT_CHAN_MODE_IGNORE ) ) { - continue; + CONTINUE; } nbits_start = st->hBstr->nb_bits_tot; move16(); writeTCXparam_fx( st, st->hBstr, NULL, param_core[ch], 0, 0, 0, NULL, p_param[ch], target_bitsTCX10[ch], 1 ); - total_nbbits = st->hBstr->nb_bits_tot - nbits_start - nSubframes * ( NBITS_TCX_GAIN + NOISE_FILL_RANGES * NBITS_NOISE_FILL_LEVEL ); + total_nbbits = sub( sub( st->hBstr->nb_bits_tot, nbits_start ), imult1616( nSubframes, ( NBITS_TCX_GAIN + NOISE_FILL_RANGES * NBITS_NOISE_FILL_LEVEL ) ) ); + // total_nbbits = st->hBstr->nb_bits_tot - nbits_start - nSubframes * ( NBITS_TCX_GAIN + NOISE_FILL_RANGES * NBITS_NOISE_FILL_LEVEL ); assert( st->bits_frame_channel == total_nbbits ); } diff --git a/lib_enc/ivas_omasa_enc.c b/lib_enc/ivas_omasa_enc_fx.c similarity index 97% rename from lib_enc/ivas_omasa_enc.c rename to lib_enc/ivas_omasa_enc_fx.c index bee6fa22ce0744420084afdecec5ff49952143b5..d31e6d53d63eb92bba1ec19c146fcbd29a9b12c3 100644 --- a/lib_enc/ivas_omasa_enc.c +++ b/lib_enc/ivas_omasa_enc_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other @@ -35,9 +35,7 @@ #include #include #include "ivas_cnst.h" -#include "ivas_prot.h" #include "ivas_prot_fx.h" -#include "prot.h" #include "prot_fx.h" #include "ivas_rom_com.h" #include "ivas_rom_enc.h" @@ -126,7 +124,7 @@ ivas_error ivas_omasa_enc_open_fx( move16(); FOR( i = 0; i < hOMasa->num_Cldfb_instances; i++ ) { - IF( ( error = openCldfb_ivas_enc( &( hOMasa->cldfbAnaEnc[i] ), CLDFB_ANALYSIS, st_ivas->hEncoderConfig->input_Fs, CLDFB_PROTOTYPE_5_00MS ) ) != IVAS_ERR_OK ) + IF( ( error = openCldfb_ivas_fx( &( hOMasa->cldfbAnaEnc[i] ), CLDFB_ANALYSIS, st_ivas->hEncoderConfig->input_Fs, CLDFB_PROTOTYPE_5_00MS, ENC ) ) != IVAS_ERR_OK ) { return error; } @@ -229,7 +227,7 @@ void ivas_omasa_enc_close_fx( FOR( i = 0; i < ( *hOMasa )->num_Cldfb_instances; i++ ) { - deleteCldfb_ivas( &( ( *hOMasa )->cldfbAnaEnc[i] ) ); + deleteCldfb_ivas_fx( &( ( *hOMasa )->cldfbAnaEnc[i] ) ); } FOR( i = 0; i < DIRAC_NUM_DIMS; i++ ) @@ -291,7 +289,7 @@ ivas_error ivas_omasa_enc_config_fx( k = 0; move16(); - WHILE( LT_16( k, SIZE_IVAS_BRATE_TBL ) && NE_32( ivas_total_brate, ivas_brate_tbl[k] ) ) + WHILE( ( k < SIZE_IVAS_BRATE_TBL ) && ( ivas_total_brate != ivas_brate_tbl[k] ) ) { test(); k = add( k, 1 ); @@ -338,11 +336,11 @@ ivas_error ivas_omasa_enc_config_fx( /* re-write IVAS format signalling - actual 'ism_mode' was not known before */ IF( st_ivas->nSCE > 0 ) { - reset_indices_enc( st_ivas->hSCE[0]->hCoreCoder[0]->hBstr, st_ivas->hSCE[0]->hCoreCoder[0]->hBstr->nb_bits_tot ); + reset_indices_enc_fx( st_ivas->hSCE[0]->hCoreCoder[0]->hBstr, st_ivas->hSCE[0]->hCoreCoder[0]->hBstr->nb_bits_tot ); } ELSE { - reset_indices_enc( st_ivas->hCPE[0]->hCoreCoder[0]->hBstr, st_ivas->hCPE[0]->hCoreCoder[0]->hBstr->nb_bits_tot ); + reset_indices_enc_fx( st_ivas->hCPE[0]->hCoreCoder[0]->hBstr, st_ivas->hCPE[0]->hCoreCoder[0]->hBstr->nb_bits_tot ); } ivas_write_format_fx( st_ivas ); @@ -458,7 +456,7 @@ void ivas_omasa_set_config_fx( } } - Copy( DirAC_block_grouping, hOMasa->block_grouping, MAX_PARAM_SPATIAL_SUBFRAMES + 1 ); + Copy( DirAC_block_grouping, hOMasa->block_grouping, MAX_PARAM_SPATIAL_SUBFRAMES + 1 ); // Q0 IF( EQ_16( hOMasa->nSubframes, 1 ) ) { hOMasa->block_grouping[1] = hOMasa->block_grouping[MAX_PARAM_SPATIAL_SUBFRAMES]; @@ -478,7 +476,7 @@ void ivas_omasa_enc_fx( OMASA_ENC_HANDLE hOMasa, /* i/o: OMASA encoder handle */ MASA_ENCODER_HANDLE hMasa, /* i/o: MASA encoder handle */ ISM_METADATA_HANDLE hIsmMeta[], /* i/o: ISM metadata handle */ - Word32 *data_in[], /* i/o: Input / transport audio signals */ + Word32 *data_in[], /* i/o: Input / transport audio signals q_data*/ Word16 q_data, /* i : Q0 Stores the q for data_in */ const Word16 input_frame, /* i : Input frame size */ const Word16 nchan_transport, /* i : Number of transport channels */ @@ -756,8 +754,8 @@ void ivas_omasa_enc_fx( /* Move the ISM metadata to the first entry for encoding in the MASA_ONE_OBJ mode */ IF( EQ_16( ism_mode, ISM_MASA_MODE_MASA_ONE_OBJ ) ) { - hIsmMeta[0]->azimuth_fx = hIsmMeta[*idx_separated_object]->azimuth_fx; - hIsmMeta[0]->elevation_fx = hIsmMeta[*idx_separated_object]->elevation_fx; + hIsmMeta[0]->azimuth_fx = hIsmMeta[*idx_separated_object]->azimuth_fx; // Q22 + hIsmMeta[0]->elevation_fx = hIsmMeta[*idx_separated_object]->elevation_fx; // Q22 move32(); move32(); } @@ -815,6 +813,7 @@ void ivas_set_ism_importance_interformat_fx( } ctype = hSCE[ch]->hCoreCoder[0]->coder_type_raw; + move16(); st->low_rate_mode = 0; move16(); @@ -920,7 +919,7 @@ void ivas_set_surplus_brate_enc( Word16 ivas_omasa_ener_brate_fx( const Word16 nchan_ism, /* i : number of ISMs */ const Word32 ivas_total_brate, /* i : IVAS total bitrate */ - Word32 *data_f[], /* i : Input / transport audio signals */ + Word32 *data_f[], /* i : Input / transport audio signals data_e*/ const Word16 input_frame, /* i : Input frame size */ Word16 data_e /*i:exponent for data_f */ ) @@ -973,7 +972,7 @@ Word16 ivas_omasa_ener_brate_fx( energy_ism = Mpy_32_16_1( energy_ism, temp ); IF( energy_ism_e < 0 ) { - energy_ism = L_shl( energy_ism, energy_ism_e ); + energy_ism = L_shl( energy_ism, energy_ism_e ); // Q31 energy_ism_e = 0; move16(); } @@ -1115,7 +1114,12 @@ static void ivas_omasa_param_est_enc_fx( { q = q_data; move16(); - cldfbAnalysis_ts_fx_fixed_q( &( data[i][l_ts * ts] ), Chnl_RealBuffer_fx[i], Chnl_ImagBuffer_fx[i], l_ts, hOMasa->cldfbAnaEnc[i], &q ); /*q_data-5*/ +#if 0 + scale_sig32( hOMasa->cldfbAnaEnc[i]->cldfb_state_fx, hOMasa->cldfbAnaEnc[i]->cldfb_state_length, sub( q, hOMasa->cldfbAnaEnc[i]->Q_cldfb_state ) ); + hOMasa->cldfbAnaEnc[i]->Q_cldfb_state = q; + move16(); +#endif + cldfbAnalysis_ts_fx_var_q( &( data[i][l_ts * ts] ), Chnl_RealBuffer_fx[i], Chnl_ImagBuffer_fx[i], l_ts, hOMasa->cldfbAnaEnc[i], &q ); /*q_data-5*/ norm_buff = s_min( norm_buff, L_norm_arr( Chnl_RealBuffer_fx[i], 60 ) ); norm_buff = s_min( norm_buff, L_norm_arr( Chnl_ImagBuffer_fx[i], 60 ) ); } @@ -1197,7 +1201,12 @@ static void ivas_omasa_param_est_enc_fx( computeIntensityVector_enc_fx( hOMasa->band_grouping, Foa_RealBuffer_fx, Foa_ImagBuffer_fx, num_freq_bands, intensity_real_fx, guard_bits ); intensity_real_e = sub( add( 62, guard_bits ), shl( q, 1 ) ); - computeDirectionVectors_fixed( intensity_real_fx[0], intensity_real_fx[1], intensity_real_fx[2], 0, num_freq_bands, direction_vector_fx[0], direction_vector_fx[1], direction_vector_fx[2], intensity_real_e ); + computeDirectionVectors_fixed( intensity_real_fx[0], intensity_real_fx[1], intensity_real_fx[2], 0, num_freq_bands, direction_vector_fx[0], direction_vector_fx[1], direction_vector_fx[2], intensity_real_e +#ifdef NONBE_IMPROVE_DIRAC_INTENSITY_PREC + , + NULL +#endif + ); /* Power estimation for diffuseness */ diff --git a/lib_enc/ivas_osba_enc.c b/lib_enc/ivas_osba_enc_fx.c similarity index 93% rename from lib_enc/ivas_osba_enc.c rename to lib_enc/ivas_osba_enc_fx.c index f018f250a9f7e980b6db552c8a5b639278879213..2a6944c502fd97256ec50250b6c774159c9694fc 100644 --- a/lib_enc/ivas_osba_enc.c +++ b/lib_enc/ivas_osba_enc_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other @@ -35,13 +35,11 @@ #include #include #include "ivas_cnst.h" -#include "ivas_prot.h" -#include "prot.h" +#include "prot_fx.h" #include "ivas_rom_com.h" #include "ivas_rom_enc.h" #include "wmc_auto.h" #include "ivas_prot_fx.h" -#include "prot_fx.h" /*------------------------------------------------------------------------- @@ -63,9 +61,9 @@ static void ivas_osba_render_ism_to_sba_fx( * Merge SBA transport channels *-------------------------------------------------------------------*/ static void ivas_merge_sba_transports_fx( - Word32 data_in_f1[][L_FRAME48k], - Word32 *data_in_f2[], - Word32 *data_out_f[], + Word32 data_in_f1[][L_FRAME48k], // Q_f1 + Word32 *data_in_f2[], // Q_f2 + Word32 *data_out_f[], // Q_out const Word16 input_frame, const Word16 sba_analysis_order, Word16 Q_f1, @@ -114,7 +112,7 @@ ivas_error ivas_osba_enc_open_fx( { set_val_Word32( hOSba->prev_object_dm_gains_fx[i], INV_SQRT_2_Q30, MAX_INPUT_CHANNELS ); } - len = NS2SA( st_ivas->hEncoderConfig->input_Fs, IVAS_FB_ENC_DELAY_NS ); + len = NS2SA_FX2( st_ivas->hEncoderConfig->input_Fs, IVAS_FB_ENC_DELAY_NS ); move16(); FOR( i = 0; i < st_ivas->hEncoderConfig->nchan_ism; i++ ) { @@ -133,10 +131,10 @@ ivas_error ivas_osba_enc_open_fx( tmp32 = L_shr( tmp32, sub( 15, tmp_e ) ); input_frame = extract_l( tmp32 ); - for ( i = 0; i < input_frame; i++ ) + FOR( i = 0; i < input_frame; i++ ) { tmp32 = L_deposit_h( BASOP_Util_Divide1616_Scale( i, input_frame, &tmp_e ) ); - hOSba->interpolator_fx[i] = L_shl( tmp32, tmp_e ); + hOSba->interpolator_fx[i] = L_shl( tmp32, tmp_e ); // Q31 move32(); } st_ivas->hOSba = hOSba; @@ -301,7 +299,7 @@ ivas_error ivas_osba_enc_reconfig( } } - ivas_spar_config_fx( ivas_total_brate, min( st_ivas->sba_analysis_order, IVAS_MAX_SBA_ORDER ), &st_ivas->nchan_transport, &st_ivas->nSCE, &st_ivas->nCPE, &st_ivas->hSpar->core_nominal_brate, -1 ); + ivas_spar_config_fx( ivas_total_brate, s_min( st_ivas->sba_analysis_order, IVAS_MAX_SBA_ORDER ), &st_ivas->nchan_transport, &st_ivas->nSCE, &st_ivas->nCPE, &st_ivas->hSpar->core_nominal_brate, -1 ); hSpar = st_ivas->hSpar; @@ -408,7 +406,7 @@ ivas_error ivas_osba_enc_reconfig( void ivas_osba_enc_fx( OSBA_ENC_HANDLE hOSba, /* i/o: OSBA encoder handle */ ISM_METADATA_HANDLE hIsmMeta[], /* i/o: ISM metadata handle */ - Word32 *data_in_fx[], /* i/o: Input / transport audio signals */ + Word32 *data_in_fx[], /* i/o: Input / transport audio signals q_data*/ const Word16 input_frame, /* i : Input frame size */ const Word16 nchan_ism, /* i : Number of objects for parameter analysis */ const ISM_MODE ism_mode, /* i : ISM mode */ @@ -421,13 +419,13 @@ void ivas_osba_enc_fx( Word16 Q_out = *q_data; move16(); Word16 n, delay_s; - delay_s = NS2SA( input_Fs, IVAS_FB_ENC_DELAY_NS ); + delay_s = NS2SA_FX2( input_Fs, IVAS_FB_ENC_DELAY_NS ); IF( ism_mode == ISM_MODE_NONE ) { /*keep the delay buffer up to date*/ FOR( n = 0; n < nchan_ism; n++ ) { - MVR2R_WORD32( &data_in_fx[n][input_frame - delay_s], hOSba->input_data_mem_fx[n], delay_s ); + MVR2R_WORD32( &data_in_fx[n][input_frame - delay_s], hOSba->input_data_mem_fx[n], delay_s ); // Q_data } /* Convert ISM to SBA */ @@ -450,8 +448,8 @@ void ivas_osba_enc_fx( { delay_signal_fx( data_in_fx[n], input_frame, hOSba->input_data_mem_fx[n], delay_s ); - azimuth_fx = extract_l( L_shr( L_add( hIsmMeta[n]->azimuth_fx, 2097152 ), Q22 ) ); - elevation_fx = extract_l( L_shr( L_add( hIsmMeta[n]->elevation_fx, 2097152 ), Q22 ) ); + azimuth_fx = extract_l( L_shr( L_add( hIsmMeta[n]->azimuth_fx, 2097152 /*0.5.Q22*/ ), Q22 ) ); // Q0 + elevation_fx = extract_l( L_shr( L_add( hIsmMeta[n]->elevation_fx, 2097152 /*0.5.Q22*/ ), Q22 ) ); // Q0 ivas_dirac_dec_get_response_fx( azimuth_fx, elevation_fx, hOSba->prev_object_dm_gains_fx[n], sba_analysis_order, Q30 ); } } @@ -467,14 +465,14 @@ void ivas_osba_enc_fx( *--------------------------------------------------------------------------*/ /* Render ISMs to SBA */ static void ivas_osba_render_ism_to_sba_fx( - Word32 *data_in_fx[], - Word32 data_out_fx[][L_FRAME48k], + Word32 *data_in_fx[], // Q_data + Word32 data_out_fx[][L_FRAME48k], // Q_data const Word16 input_frame, const Word16 sba_analysis_order, const Word16 nchan_ism, ISM_METADATA_HANDLE hIsmMeta[], - Word32 prev_gains_fx[][MAX_INPUT_CHANNELS], - const Word32 interpolator_fx[L_FRAME48k], + Word32 prev_gains_fx[][MAX_INPUT_CHANNELS], // Q30 + const Word32 interpolator_fx[L_FRAME48k], // Q31 Word16 *Q_data ) { Word16 i, j, k; @@ -495,31 +493,32 @@ static void ivas_osba_render_ism_to_sba_fx( FOR( i = 0; i < nchan_ism; i++ ) { // azimuth = (int16_t) floorf( hIsmMeta[i]->azimuth + 0.5f ); - azimuth_fx = extract_l( L_shr( L_add( hIsmMeta[i]->azimuth_fx, 2097152 ), Q22 ) ); + azimuth_fx = extract_l( L_shr( L_add( hIsmMeta[i]->azimuth_fx, 2097152 /*0.5.Q22*/ ), Q22 ) ); // Q0 // elevation = (int16_t) floorf( hIsmMeta[i]->elevation + 0.5f ); - elevation_fx = extract_l( L_shr( L_add( hIsmMeta[i]->elevation_fx, 2097152 ), Q22 ) ); + elevation_fx = extract_l( L_shr( L_add( hIsmMeta[i]->elevation_fx, 2097152 /*0.5.Q22*/ ), Q22 ) ); // Q0 ivas_dirac_dec_get_response_fx( azimuth_fx, elevation_fx, gains_fx, sba_analysis_order, Q30 ); /* Render using the sh gains */ FOR( j = 0; j < nchan_sba; j++ ) { + test(); IF( L_abs( gains_fx[j] ) > 0 || L_abs( prev_gains_fx[i][j] ) > 0 ) { FOR( k = 0; k < input_frame; k++ ) { // g1 = interpolator[k]; - g1_fx = interpolator_fx[k]; + g1_fx = interpolator_fx[k]; // Q31 move32(); // g2 = 1.0f - g1; - g2_fx = L_sub( ONE_IN_Q31, g1_fx ); + g2_fx = L_sub( ONE_IN_Q31, g1_fx ); // Q31 move32(); // data_out_f[j][k] += ( g1 * gains[j] + g2 * prev_gains[i][j] ) * data_in_f[i][k]; data_out_fx[j][k] = L_add( data_out_fx[j][k], L_shr( Mpy_32_32( L_add( Mpy_32_32( g1_fx, gains_fx[j] ), Mpy_32_32( g2_fx, prev_gains_fx[i][j] ) ), data_in_fx[i][k] ), 1 ) ); // Q_data-2 move32(); } } - prev_gains_fx[i][j] = gains_fx[j]; + prev_gains_fx[i][j] = gains_fx[j]; // Q30 move32(); } } diff --git a/lib_enc/ivas_pca_enc.c b/lib_enc/ivas_pca_enc_fx.c similarity index 93% rename from lib_enc/ivas_pca_enc.c rename to lib_enc/ivas_pca_enc_fx.c index fccef003672e81c07cc1b37862f3bb6d6a26bcea..2cb347a026794ad3e32d70cad242c81d02731e86 100644 --- a/lib_enc/ivas_pca_enc.c +++ b/lib_enc/ivas_pca_enc_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other @@ -32,14 +32,12 @@ #include #include "options.h" -#include "prot.h" -#include "ivas_prot.h" +#include "prot_fx.h" #include "ivas_cnst.h" #include #include #include "wmc_auto.h" -#include "prot_fx.h" #include "ivas_prot_fx.h" @@ -98,7 +96,7 @@ static void pca_enc_reset_fx( } static void pca_transform_sub_fx( - Word16 *eigVec, + Word16 *eigVec, // Q15 Word32 *transformed_data[8], /* i : input/transformed audio channels Q11 */ const Word16 start, const Word16 len, @@ -112,7 +110,7 @@ static void pca_transform_sub_fx( { FOR( k = 0; k < n_channels; k++ ) { - buffer_data[k] = transformed_data[k][j + start]; + buffer_data[k] = transformed_data[k][j + start]; // Q11 move32(); } FOR( k = 0; k < n_channels; k++ ) @@ -121,10 +119,10 @@ static void pca_transform_sub_fx( move32(); FOR( i = 0; i < n_channels; i++ ) { - temp2 = Mpy_32_16_1( buffer_data[i], eigVec[k * IVAS_PCA_INTERP + i] ); + temp2 = Mpy_32_16_1( buffer_data[i], eigVec[k * IVAS_PCA_INTERP + i] ); // Q11 temp = L_add( temp, temp2 ); } - transformed_data[k][add( j, start )] = temp; + transformed_data[k][( j + start )] = temp; // Q11 move32(); } } @@ -142,7 +140,7 @@ static void pca_enc_transform_fx( { Word16 time_slot; Word16 slot_len; - Word16 eigVec_interp_fx[FOA_CHANNELS * FOA_CHANNELS]; /* eigenvectors in current frame */ + Word16 eigVec_interp_fx[FOA_CHANNELS * FOA_CHANNELS]; /* eigenvectors in current frame Q15*/ Word16 ql_interp_fx[IVAS_PCA_LEN_INTERP_Q], qr_interp_fx[IVAS_PCA_LEN_INTERP_Q]; quat_shortestpath_fx( hPCA->prev_ql_fx, ql_fx, hPCA->prev_qr_fx, qr_fx ); @@ -167,9 +165,9 @@ static void pca_update_state_fx( Word16 *eigVec, // Q15 const Word16 n_channels ) { - Copy( qr, hPCA->prev_qr_fx, IVAS_PCA_INTERP ); - Copy( ql, hPCA->prev_ql_fx, IVAS_PCA_INTERP ); - Copy( eigVec, hPCA->prev_eigVec_fx, imult1616( n_channels, n_channels ) ); + Copy( qr, hPCA->prev_qr_fx, IVAS_PCA_INTERP ); // Q15 + Copy( ql, hPCA->prev_ql_fx, IVAS_PCA_INTERP ); // Q15 + Copy( eigVec, hPCA->prev_eigVec_fx, imult1616( n_channels, n_channels ) ); // Q15 return; } @@ -356,7 +354,7 @@ void ivas_pca_enc_fx( { FOR( k = 0; k < FOA_CHANNELS; k++ ) { - ptr_sig_fx[k] = &data_fx[k][i]; + ptr_sig_fx[k] = &data_fx[k][i]; // Q11 } @@ -388,7 +386,7 @@ void ivas_pca_enc_fx( FOR( Word16 idx = 0; idx < FOA_CHANNELS * FOA_CHANNELS; idx++ ) { - r_fx[idx] = L_shr( r_fx[idx], ( sub( tmp_q[idx], q ) ) ); + r_fx[idx] = L_shr( r_fx[idx], ( sub( tmp_q[idx], q ) ) ); // q move32(); } @@ -401,10 +399,10 @@ void ivas_pca_enc_fx( FOR( k = 0; k < FOA_CHANNELS * FOA_CHANNELS; k++ ) { - L_tmp = L_shr( Mpy_32_32( alpha_fx, r_fx[k] ), sub( q, min_q ) ); - L_tmp1 = L_shr( Mpy_32_32( one_minus_alpha_fx, hPCA->old_r_sm_fx[k] ), sub( hPCA->old_r_sm_q, min_q ) ); - r_sm_fx[k] = L_add( L_tmp, L_tmp1 ); - hPCA->old_r_sm_fx[k] = r_sm_fx[k]; + L_tmp = L_shr( Mpy_32_32( alpha_fx, r_fx[k] ), sub( q, min_q ) ); // min_q + L_tmp1 = L_shr( Mpy_32_32( one_minus_alpha_fx, hPCA->old_r_sm_fx[k] ), sub( hPCA->old_r_sm_q, min_q ) ); // min_q + r_sm_fx[k] = L_add( L_tmp, L_tmp1 ); // min_q + hPCA->old_r_sm_fx[k] = r_sm_fx[k]; // min_q move32(); move32(); } @@ -415,13 +413,13 @@ void ivas_pca_enc_fx( /* conditioning */ FOR( k = 0; k < FOA_CHANNELS; k++ ) { - temp_fx32 = r_sm_fx[k * FOA_CHANNELS + k]; + temp_fx32 = r_sm_fx[k * FOA_CHANNELS + k]; // min_q move32(); IF( LT_32( temp_fx32, L_shr( 64424, sub( 31, hPCA->old_r_sm_q ) ) ) ) // IVAS_PCA_COV_THRES in Q31 { - temp_fx32 = L_shr( 64424, sub( 31, hPCA->old_r_sm_q ) ); // IVAS_PCA_COV_THRES in Q31 + temp_fx32 = L_shr( 64424, sub( 31, hPCA->old_r_sm_q ) ); // IVAS_PCA_COV_THRES in Q31 /*hPCA->old_r_sm_q */ } - r_sm_fx[k * FOA_CHANNELS + k] = temp_fx32; /* pointer reuse */ + r_sm_fx[k * FOA_CHANNELS + k] = temp_fx32; /* pointer reuse */ // hPCA->old_r_sm_q move32(); } @@ -539,7 +537,7 @@ void ivas_pca_enc_fx( /* copy j-th column to column k */ FOR( l = 0; l < n_channels; l++ ) { - eigVec_tmp_fx[l * n_channels + k] = eigVec_fx[l * n_channels + j]; + eigVec_tmp_fx[l * n_channels + k] = eigVec_fx[l * n_channels + j]; // Q31 move16(); } D_tmp_fx[k] = extract_l( D_fx[j] ); @@ -548,7 +546,7 @@ void ivas_pca_enc_fx( FOR( k = 0; k < n_channels * n_channels; k++ ) { - eigVec_fx[k] = eigVec_tmp_fx[k]; + eigVec_fx[k] = eigVec_tmp_fx[k]; // Q31 move32(); } @@ -571,14 +569,14 @@ void ivas_pca_enc_fx( { FOR( i = 0; i < n_channels; i++ ) { - eigVec_fx[i * n_channels + k] = L_negate( eigVec_fx[i * n_channels + k] ); + eigVec_fx[i * n_channels + k] = L_negate( eigVec_fx[i * n_channels + k] ); // Q31 move32(); } } } /* force rotation matrix(det = +1) */ - Copy_Scale_sig32_16( eigVec_fx, eigVec_fx16, FOA_CHANNELS * FOA_CHANNELS, -16 ); + Copy_Scale_sig32_16( eigVec_fx, eigVec_fx16, FOA_CHANNELS * FOA_CHANNELS, -16 ); // Q15 det_fx = mat_det4_fx( eigVec_fx16 ); IF( det_fx < 0 ) { @@ -603,29 +601,29 @@ void ivas_pca_enc_fx( *-----------------------------------------------------------------*/ /* convert frrm rotation matrix to double quaternion */ - Copy_Scale_sig_32_16( eigVec_fx, eigVec_fx16, FOA_CHANNELS * FOA_CHANNELS, -16 ); + Copy_Scale_sig_32_16( eigVec_fx, eigVec_fx16, FOA_CHANNELS * FOA_CHANNELS, -16 ); // Q15 mat2dquat_fx( eigVec_fx16, ql_fx, qr_fx ); - dotl_fx = Dot_product( hPCA->prev_ql_fx, ql_fx, 4 ); - dotr_fx = Dot_product( hPCA->prev_qr_fx, qr_fx, 4 ); + dotl_fx = Dot_product( hPCA->prev_ql_fx, ql_fx, 4 ); // Q31 + dotr_fx = Dot_product( hPCA->prev_qr_fx, qr_fx, 4 ); // Q31 IF( LT_32( dotl_fx, dotr_fx ) ) { - min_dot_fx = dotl_fx; + min_dot_fx = dotl_fx; // Q31 move32(); } ELSE { - min_dot_fx = dotr_fx; + min_dot_fx = dotr_fx; // Q31 move32(); } IF( LT_16( ql_fx[0], qr_fx[0] ) ) { - min_dot2_fx = L_deposit_h( ql_fx[0] ); + min_dot2_fx = L_deposit_h( ql_fx[0] ); // Q31 } ELSE { - min_dot2_fx = L_deposit_h( qr_fx[0] ); + min_dot2_fx = L_deposit_h( qr_fx[0] ); // Q31 } bypass_decision = PCA_MODE_ACTIVE; diff --git a/lib_enc/ivas_qmetadata_enc.c b/lib_enc/ivas_qmetadata_enc_fx.c similarity index 90% rename from lib_enc/ivas_qmetadata_enc.c rename to lib_enc/ivas_qmetadata_enc_fx.c index 28218d70d4752d444463a6a490574e85054484ba..7de54c482bf7a2a7b8d8f5153206d76a7c15d822 100644 --- a/lib_enc/ivas_qmetadata_enc.c +++ b/lib_enc/ivas_qmetadata_enc_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other @@ -35,15 +35,12 @@ #include "options.h" #include #include "ivas_cnst.h" -#include "prot.h" -#include "ivas_prot.h" +#include "prot_fx.h" #include "ivas_prot_fx.h" #include "ivas_rom_com.h" #include "ivas_stat_enc.h" #include "wmc_auto.h" -#include "prot.h" -#include "prot_fx.h" #include "basop_util.h" #include "ivas_rom_com_fx.h" @@ -51,7 +48,7 @@ * Local function prototypes *-----------------------------------------------------------------------*/ -static void ivas_qmetadata_quantize_diffuseness_nrg_ratios_fx( IVAS_QMETADATA_HANDLE hQMetaData, int16_t *needed_bits, int16_t *nbits_diff, int16_t *dfRatioBits, const int16_t hodirac_flag ); +static void ivas_qmetadata_quantize_diffuseness_nrg_ratios_fx( IVAS_QMETADATA_HANDLE hQMetaData, Word16 *needed_bits, Word16 *nbits_diff, Word16 *dfRatioBits, const Word16 hodirac_flag ); static Word16 ivas_qmetadata_entropy_encode_diffuseness_fx( BSTR_ENC_HANDLE hMetaData, @@ -88,11 +85,11 @@ static Word16 ivas_qmetadata_get_optimal_gr_param_fx( const Word16 gr_param_count, Word16 *opt_gr_size ); -Word16 ivas_qmetadata_encode_extended_gr_length( const UWord16 value, const UWord16 alphabet_size, const Word16 gr_param ); +Word16 ivas_qmetadata_encode_extended_gr_length_fx( const UWord16 value, const UWord16 alphabet_size, const Word16 gr_param ); -static Word16 ivas_qmetadata_encode_quasi_uniform_length( const UWord16 value, const UWord16 alphabet_size ); +static Word16 ivas_qmetadata_encode_quasi_uniform_length_fx( const UWord16 value, const UWord16 alphabet_size ); -static void ivas_qmetadata_encode_quasi_uniform( BSTR_ENC_HANDLE hMetaData, const UWord16 value, const UWord16 alphabet_size ); +static void ivas_qmetadata_encode_quasi_uniform_fx( BSTR_ENC_HANDLE hMetaData, const UWord16 value, const UWord16 alphabet_size ); static Word16 ivas_qmetadata_reorder_elevation_index_fx( const Word16 elevation_index, @@ -131,16 +128,16 @@ static Word16 ivas_qmetadata_quantize_coherence_fx( ); static void dct4_transform_fx( - uint8_t *v, /* i : input 4D vector */ + UWord8 *v, /* i : input 4D vector */ Word32 *dct_v /* o : output transformed vector Q31 */ ); static Word32 quantize_DCT_0_coh_fx( // o:Q21 const Word16 x, /* i : input value Q14 */ - const int16_t j, /* i : subband index */ + const Word16 j, /* i : subband index */ const Word16 *coherence_cb, /* i : coherence codebook Q14 */ const Word16 delta_var, /* i : azimuth variance threshold Q6 */ - const int16_t no_cb, /* i : maximum number of codewords */ + const Word16 no_cb, /* i : maximum number of codewords */ IVAS_QDIRECTION *q_direction, /* i : quantized metadata */ UWord16 *idx_x, /* o : codewords index */ Word16 *p_no_cb, /* o : actual number of codewords dependent on energy ratio value */ @@ -162,7 +159,7 @@ static Word16 encode_coherence_indexesDCT1_fx( BSTR_ENC_HANDLE hMetaData /* i : metadata handle */ ); -static UWord64 create_combined_index( uint16_t *idx_dct, const int16_t len, const int16_t *no_cb_vec ); +static UWord64 create_combined_index_fx( UWord16 *idx_dct, const Word16 len, const Word16 *no_cb_vec ); static Word16 encode_surround_coherence_fx( IVAS_QMETADATA *hQMetaData, /* i : quantized metadata */ @@ -186,9 +183,9 @@ static void ivas_diffuseness_huff_ec_prepare_fx( UWord16 *avr_idx, Word16 *diffuseness_bits_huff ); -static int16_t coherence_coding_length( const uint16_t *idx_sur_coh_shift, const uint8_t idx_shift_len, const int16_t coding_subbands, const int16_t *no_cv, uint16_t *mr_idx, int16_t *no_cv_shift, int16_t *p_min_idx, int16_t *GR_ord, int16_t *nbits_fr, int16_t *nbits_fr1 ); +static Word16 coherence_coding_length( const UWord16 *idx_sur_coh_shift, const UWord8 idx_shift_len, const Word16 coding_subbands, const Word16 *no_cv, UWord16 *mr_idx, Word16 *no_cv_shift, Word16 *p_min_idx, Word16 *GR_ord, Word16 *nbits_fr, Word16 *nbits_fr1 ); -static int16_t write_2dir_info( BSTR_ENC_HANDLE hMetaData, uint8_t *twoDirBands, const int16_t n, const int16_t k ); +static Word16 write_2dir_info( BSTR_ENC_HANDLE hMetaData, UWord8 *twoDirBands, const Word16 n, const Word16 k ); static void transform_azimuth_dir2_fx( IVAS_QMETADATA_HANDLE hQMetaData, @@ -289,9 +286,9 @@ ivas_error ivas_qmetadata_enc_encode_fx( { IF( EQ_16( hQMetaData->twoDirBands[i], 1 ) ) { - Copy32( hQMetaData->q_direction[1].band_data[i].azimuth_fx, hQMetaData->q_direction[1].band_data[d].azimuth_fx, hQMetaData->q_direction[1].cfg.nblocks ); - Copy32( hQMetaData->q_direction[1].band_data[i].elevation_fx, hQMetaData->q_direction[1].band_data[d].elevation_fx, hQMetaData->q_direction[1].cfg.nblocks ); - Copy32( hQMetaData->q_direction[1].band_data[i].energy_ratio_fx, hQMetaData->q_direction[1].band_data[d].energy_ratio_fx, hQMetaData->q_direction[1].cfg.nblocks ); + Copy32( hQMetaData->q_direction[1].band_data[i].azimuth_fx, hQMetaData->q_direction[1].band_data[d].azimuth_fx, hQMetaData->q_direction[1].cfg.nblocks ); // Q22 + Copy32( hQMetaData->q_direction[1].band_data[i].elevation_fx, hQMetaData->q_direction[1].band_data[d].elevation_fx, hQMetaData->q_direction[1].cfg.nblocks ); // Q22 + Copy32( hQMetaData->q_direction[1].band_data[i].energy_ratio_fx, hQMetaData->q_direction[1].band_data[d].energy_ratio_fx, hQMetaData->q_direction[1].cfg.nblocks ); // Q30 dir2_bands[d] = i; move16(); @@ -646,7 +643,7 @@ ivas_error ivas_qmetadata_enc_encode_fx( /* finalize writing coherence */ test(); test(); - IF( GT_16( bits_coherence[d], 0 ) && EQ_16( all_coherence_zero, 0 ) && GT_16( nblocks, 1 ) ) + IF( ( bits_coherence[d] > 0 ) && ( all_coherence_zero == 0 ) && GT_16( nblocks, 1 ) ) { bit_pos_start = hMetaData->nb_bits_tot; hMetaData->nb_bits_tot = bit_pos_start_coh; @@ -716,7 +713,7 @@ ivas_error ivas_qmetadata_enc_encode_hr_384_512_fx( { push_next_indice( hMetaData, 1, 1 ); /* write the number of inactive higher bands */ - ivas_qmetadata_encode_extended_gr( hMetaData, sub( hQMetaData->q_direction->cfg.inactiveBands, 1 ), MASA_MAXIMUM_CODING_SUBBANDS, 1 ); + ivas_qmetadata_encode_extended_gr_fx( hMetaData, sub( hQMetaData->q_direction->cfg.inactiveBands, 1 ), MASA_MAXIMUM_CODING_SUBBANDS, 1 ); } ELSE { @@ -741,9 +738,9 @@ ivas_error ivas_qmetadata_enc_encode_hr_384_512_fx( { IF( EQ_16( hQMetaData->twoDirBands[i], 1 ) ) { - Copy32( hQMetaData->q_direction[1].band_data[i].azimuth_fx, hQMetaData->q_direction[1].band_data[d].azimuth_fx, hQMetaData->q_direction[1].cfg.nblocks ); - Copy32( hQMetaData->q_direction[1].band_data[i].elevation_fx, hQMetaData->q_direction[1].band_data[d].elevation_fx, hQMetaData->q_direction[1].cfg.nblocks ); - Copy32( hQMetaData->q_direction[1].band_data[i].energy_ratio_fx, hQMetaData->q_direction[1].band_data[d].energy_ratio_fx, hQMetaData->q_direction[1].cfg.nblocks ); + Copy32( hQMetaData->q_direction[1].band_data[i].azimuth_fx, hQMetaData->q_direction[1].band_data[d].azimuth_fx, hQMetaData->q_direction[1].cfg.nblocks ); // Q22 + Copy32( hQMetaData->q_direction[1].band_data[i].elevation_fx, hQMetaData->q_direction[1].band_data[d].elevation_fx, hQMetaData->q_direction[1].cfg.nblocks ); // Q22 + Copy32( hQMetaData->q_direction[1].band_data[i].energy_ratio_fx, hQMetaData->q_direction[1].band_data[d].energy_ratio_fx, hQMetaData->q_direction[1].cfg.nblocks ); // Q30 IF( hQMetaData->coherence_flag ) { @@ -827,16 +824,16 @@ ivas_error ivas_qmetadata_enc_encode_hr_384_512_fx( { FOR( i = start_band; i < nbands; i++ ) { - Copy32( azimuth_orig_fx[i], q_direction->band_data[i].azimuth_fx, nblocks ); - Copy32( elevation_orig_fx[i], q_direction->band_data[i].elevation_fx, nblocks ); + Copy32( azimuth_orig_fx[i], q_direction->band_data[i].azimuth_fx, nblocks ); // Q22 + Copy32( elevation_orig_fx[i], q_direction->band_data[i].elevation_fx, nblocks ); // Q22 } } ELSE { FOR( i = start_band; i < nbands; i++ ) { - Copy32( q_direction->band_data[i].azimuth_fx, q_direction->band_data[i].q_azimuth_fx, nblocks ); - Copy32( q_direction->band_data[i].elevation_fx, q_direction->band_data[i].q_elevation_fx, nblocks ); + Copy32( q_direction->band_data[i].azimuth_fx, q_direction->band_data[i].q_azimuth_fx, nblocks ); // Q22 + Copy32( q_direction->band_data[i].elevation_fx, q_direction->band_data[i].q_elevation_fx, nblocks ); // Q22 } } } @@ -945,7 +942,7 @@ void ivas_qmetadata_enc_sid_encode_fx( { q_direction->band_data[b].energy_ratio_index[0] = s_max( q_direction->band_data[b].energy_ratio_index[0], 4 ); move16(); - bits_diff = add( bits_diff, ivas_qmetadata_encode_quasi_uniform_length( sub( q_direction->band_data[b].energy_ratio_index[0], 4 ), DIRAC_DIFFUSE_LEVELS - 4 ) ); + bits_diff = add( bits_diff, ivas_qmetadata_encode_quasi_uniform_length_fx( sub( q_direction->band_data[b].energy_ratio_index[0], 4 ), DIRAC_DIFFUSE_LEVELS - 4 ) ); q_direction->band_data[b].bits_sph_idx[0] = bits_direction_masa[q_direction->band_data[b].energy_ratio_index[0]]; move16(); @@ -953,7 +950,7 @@ void ivas_qmetadata_enc_sid_encode_fx( { q_direction->band_data[b].azimuth_m_alphabet[0] = 1 << ( s_min( 8, q_direction->band_data[b].bits_sph_idx[0] ) ); move16(); - bits_dir = add( bits_dir, ivas_qmetadata_encode_quasi_uniform_length( sub( q_direction->band_data[b].azimuth_m_alphabet[0], 1 ), q_direction->band_data[b].azimuth_m_alphabet[0] ) ); + bits_dir = add( bits_dir, ivas_qmetadata_encode_quasi_uniform_length_fx( sub( q_direction->band_data[b].azimuth_m_alphabet[0], 1 ), q_direction->band_data[b].azimuth_m_alphabet[0] ) ); } ELSE { @@ -1016,7 +1013,7 @@ void ivas_qmetadata_enc_sid_encode_fx( FOR( b = start_band; b < nbands; b++ ) { q_direction->band_data[b].energy_ratio_index[0] = s_max( q_direction->band_data[b].energy_ratio_index[0], 4 ); - bits_diff = add( bits_diff, ivas_qmetadata_encode_quasi_uniform_length( sub( q_direction->band_data[b].energy_ratio_index[0], 4 ), DIRAC_DIFFUSE_LEVELS - 4 ) ); + bits_diff = add( bits_diff, ivas_qmetadata_encode_quasi_uniform_length_fx( sub( q_direction->band_data[b].energy_ratio_index[0], 4 ), DIRAC_DIFFUSE_LEVELS - 4 ) ); q_direction->band_data[b].bits_sph_idx[0] = bits_direction_masa[q_direction->band_data[b].energy_ratio_index[0]]; move16(); move16(); @@ -1025,7 +1022,7 @@ void ivas_qmetadata_enc_sid_encode_fx( { q_direction->band_data[b].azimuth_m_alphabet[0] = shl( 1, ( s_min( 5, q_direction->band_data[b].bits_sph_idx[0] ) ) ); move16(); - bits_dir = add( bits_dir, ivas_qmetadata_encode_quasi_uniform_length( sub( q_direction->band_data[b].azimuth_m_alphabet[0], 1 ), q_direction->band_data[b].azimuth_m_alphabet[0] ) ); + bits_dir = add( bits_dir, ivas_qmetadata_encode_quasi_uniform_length_fx( sub( q_direction->band_data[b].azimuth_m_alphabet[0], 1 ), q_direction->band_data[b].azimuth_m_alphabet[0] ) ); } ELSE { @@ -1061,7 +1058,7 @@ void ivas_qmetadata_enc_sid_encode_fx( /*Code diffuseness*/ FOR( b = start_band; b < nbands; b++ ) { - ivas_qmetadata_encode_quasi_uniform( hMetaData, sub( q_direction->band_data[b].energy_ratio_index[0], 4 ), DIRAC_DIFFUSE_LEVELS - 4 ); + ivas_qmetadata_encode_quasi_uniform_fx( hMetaData, sub( q_direction->band_data[b].energy_ratio_index[0], 4 ), DIRAC_DIFFUSE_LEVELS - 4 ); } /* Compute and Quantize an average direction per band*/ @@ -1117,14 +1114,14 @@ void ivas_qmetadata_enc_sid_encode_fx( { FOR( b = start_band; b < nbands; b++ ) { - ivas_qmetadata_encode_quasi_uniform( hMetaData, q_direction->band_data[b].azimuth_index[0], q_direction->band_data[b].azimuth_m_alphabet[0] ); + ivas_qmetadata_encode_quasi_uniform_fx( hMetaData, q_direction->band_data[b].azimuth_index[0], q_direction->band_data[b].azimuth_m_alphabet[0] ); } } /* fill bits*/ assert( ( hMetaData->nb_bits_tot - bit_pos_start ) <= metadata_sid_bits && "Too many written bits!" ); - WHILE( LT_16( ( sub( hMetaData->nb_bits_tot, bit_pos_start ) ), metadata_sid_bits ) ) + WHILE( ( ( ( hMetaData->nb_bits_tot - bit_pos_start ) ) < metadata_sid_bits ) ) { push_next_indice( hMetaData, 0, 1 ); /*fill bit*/ } @@ -1165,7 +1162,7 @@ void reset_metadata_spatial_fx( metadata_sid_bits = (Word16) ( IVAS_SID_5k2 - SID_2k40 ) / FRAMES_PER_SEC - SID_FORMAT_NBITS; move16(); - WHILE( LT_16( hMetaData->nb_bits_tot, metadata_sid_bits ) ) + WHILE( ( hMetaData->nb_bits_tot < metadata_sid_bits ) ) { push_next_indice( hMetaData, 0, 1 ); /*fill bit*/ } @@ -1177,9 +1174,9 @@ void reset_metadata_spatial_fx( next_ind_sid = hMetaData->nb_ind_tot; move16(); move16(); - WHILE( GT_16( hMetaData->nb_bits_tot, nb_bits_metadata ) ) + WHILE( ( hMetaData->nb_bits_tot > nb_bits_metadata ) ) { - next_ind_sid--; + next_ind_sid = sub( next_ind_sid, 1 ); hMetaData->nb_bits_tot = sub( hMetaData->nb_bits_tot, hMetaData->ind_list[next_ind_sid].nb_bits ); move16(); } @@ -1212,7 +1209,7 @@ void reset_metadata_spatial_fx( ELSE { /*Reset metadata*/ - reset_indices_enc( hMetaData, hMetaData->nb_ind_tot ); + reset_indices_enc_fx( hMetaData, hMetaData->nb_ind_tot ); } *total_brate = element_brate; @@ -1221,9 +1218,9 @@ void reset_metadata_spatial_fx( ELSE IF( NE_32( ivas_format, SBA_FORMAT ) ) { /* Reset SID metadata bits*/ - WHILE( GT_16( hMetaData->nb_bits_tot, nb_bits_metadata ) ) + WHILE( ( hMetaData->nb_bits_tot > nb_bits_metadata ) ) { - hMetaData->nb_ind_tot--; + hMetaData->nb_ind_tot = sub( hMetaData->nb_ind_tot, 1 ); hMetaData->nb_bits_tot = sub( hMetaData->nb_bits_tot, hMetaData->ind_list[hMetaData->nb_ind_tot].nb_bits ); hMetaData->ind_list[hMetaData->nb_ind_tot].nb_bits = -1; move16(); @@ -1381,10 +1378,10 @@ static void ivas_qmetadata_quantize_diffuseness_nrg_ratios_hr_512_fx( push_next_indice( hMetaData, index, MASA_BITS_ER_HR ); hQMetaData->q_direction[1].band_data[j].energy_ratio_index[k] = index; move16(); - hQMetaData->q_direction[1].band_data[j].energy_ratio_fx[k] = W_extract_h( W_sub( ONE_IN_Q62, diffuseness_reconstructions_hr_fx[index] ) ); + hQMetaData->q_direction[1].band_data[j].energy_ratio_fx[k] = W_extract_h( W_sub( ONE_IN_Q62, diffuseness_reconstructions_hr_fx[index] ) ); // Q30 move32(); - ratioSum = L_add( hQMetaData->q_direction[0].band_data[pos_2dir_band[j]].energy_ratio_fx[k], hQMetaData->q_direction[1].band_data[j].energy_ratio_fx[k] ); + ratioSum = L_add( hQMetaData->q_direction[0].band_data[pos_2dir_band[j]].energy_ratio_fx[k], hQMetaData->q_direction[1].band_data[j].energy_ratio_fx[k] ); // Q30 IF( GT_32( ratioSum, ONE_IN_Q30 /*1.0f*/ ) ) { @@ -1672,9 +1669,9 @@ static void ivas_diffuseness_huff_ec_prepare_fx( { av = add( av, q_direction->band_data[b].energy_ratio_index[0] ); } - // av = (int16_t) ( 0.5f + av / (float) nbands ); + // av = (Word16) ( 0.5f + av / (float) nbands ); av = BASOP_Util_Divide1616_Scale( av, nbands, &av_e ); - av = shr_r( av, sub( 15, av_e ) ); + av = shr_r( av, sub( 15, av_e ) ); // Q0 *best_av = av; move16(); @@ -1769,7 +1766,7 @@ static Word16 ivas_qmetadata_entropy_encode_diffuseness_fx( move16(); FOR( b = start_band; b < nbands; b++ ) { - diffuseness_bits_raw = add( diffuseness_bits_raw, ivas_qmetadata_encode_quasi_uniform_length( q_direction->band_data[b].energy_ratio_index[0], DIRAC_DIFFUSE_LEVELS ) ); + diffuseness_bits_raw = add( diffuseness_bits_raw, ivas_qmetadata_encode_quasi_uniform_length_fx( q_direction->band_data[b].energy_ratio_index[0], DIRAC_DIFFUSE_LEVELS ) ); } min_diffuseness_m_index = q_direction->band_data[start_band].energy_ratio_index[0]; @@ -1798,15 +1795,15 @@ static Word16 ivas_qmetadata_entropy_encode_diffuseness_fx( /* one bit is used to indicate whether diffuseness values are entropy coded or coded raw */ IF( EQ_16( min_diffuseness_m_index, max_diffuseness_m_index ) ) /* all values are equal */ { - push_next_indice( hMetaData, 0, 1 ); /* dif_use_raw_coding */ - push_next_indice( hMetaData, 1, 1 ); /* dif_have_unique_value */ - ivas_qmetadata_encode_quasi_uniform( hMetaData, min_diffuseness_m_index, DIRAC_DIFFUSE_LEVELS ); /* dif_unique_value */ + push_next_indice( hMetaData, 0, 1 ); /* dif_use_raw_coding */ + push_next_indice( hMetaData, 1, 1 ); /* dif_have_unique_value */ + ivas_qmetadata_encode_quasi_uniform_fx( hMetaData, min_diffuseness_m_index, DIRAC_DIFFUSE_LEVELS ); /* dif_unique_value */ } ELSE IF( EQ_16( add( min_diffuseness_m_index, 1 ), max_diffuseness_m_index ) ) /* only two consecutive values are present */ { - push_next_indice( hMetaData, 0, 1 ); /* dif_use_raw_coding */ - push_next_indice( hMetaData, 0, 1 ); /* dif_have_unique_value */ - ivas_qmetadata_encode_quasi_uniform( hMetaData, min_diffuseness_m_index, DIRAC_DIFFUSE_LEVELS - 1 ); /* dif_min_value */ + push_next_indice( hMetaData, 0, 1 ); /* dif_use_raw_coding */ + push_next_indice( hMetaData, 0, 1 ); /* dif_have_unique_value */ + ivas_qmetadata_encode_quasi_uniform_fx( hMetaData, min_diffuseness_m_index, DIRAC_DIFFUSE_LEVELS - 1 ); /* dif_min_value */ FOR( b = start_band; b < nbands; b++ ) { @@ -1819,7 +1816,7 @@ static Word16 ivas_qmetadata_entropy_encode_diffuseness_fx( FOR( b = start_band; b < nbands; b++ ) { - ivas_qmetadata_encode_quasi_uniform( hMetaData, q_direction->band_data[b].energy_ratio_index[0], DIRAC_DIFFUSE_LEVELS ); /* dif_values */ + ivas_qmetadata_encode_quasi_uniform_fx( hMetaData, q_direction->band_data[b].energy_ratio_index[0], DIRAC_DIFFUSE_LEVELS ); /* dif_values */ } } } @@ -1850,7 +1847,7 @@ static Word16 ivas_qmetadata_entropy_encode_diffuseness_fx( push_next_indice( hMetaData, 1, 1 ); FOR( b = start_band; b < nbands; b++ ) { - ivas_qmetadata_encode_quasi_uniform( hMetaData, q_direction->band_data[b].energy_ratio_index[0], DIRAC_DIFFUSE_LEVELS ); /* dif_values */ + ivas_qmetadata_encode_quasi_uniform_fx( hMetaData, q_direction->band_data[b].energy_ratio_index[0], DIRAC_DIFFUSE_LEVELS ); /* dif_values */ } } } @@ -1858,7 +1855,7 @@ static Word16 ivas_qmetadata_entropy_encode_diffuseness_fx( *diffuseness_index_max_ec_frame = 5; move16(); /* adaptively select the diffuseness_index_max_ec threshold */ - if ( GT_16( min_diffuseness_m_index, 5 ) ) + IF( GT_16( min_diffuseness_m_index, 5 ) ) { *diffuseness_index_max_ec_frame = DIRAC_DIFFUSE_LEVELS - 1; move16(); @@ -1961,13 +1958,13 @@ static Word16 ivas_qmetadata_entropy_encode_df_ratio_fx( push_next_indice( hMetaData, 0, 1 ); /* Signal between one value or bandwise diff mode */ } - ivas_qmetadata_encode_quasi_uniform( hMetaData, min_index, max_alphabet_size ); + ivas_qmetadata_encode_quasi_uniform_fx( hMetaData, min_index, max_alphabet_size ); } ELSE IF( EQ_16( add( min_index, 1 ), max_index ) && GT_16( ec_mode, 1 ) ) /* only two consecutive values are present */ { push_next_indice( hMetaData, 0, 1 ); push_next_indice( hMetaData, 1, 1 ); - ivas_qmetadata_encode_quasi_uniform( hMetaData, min_index, sub( max_alphabet_size, 1 ) ); + ivas_qmetadata_encode_quasi_uniform_fx( hMetaData, min_index, sub( max_alphabet_size, 1 ) ); FOR( b = start_band; b < nbands; b++ ) { @@ -1983,7 +1980,7 @@ static Word16 ivas_qmetadata_entropy_encode_df_ratio_fx( FOR( b = start_band; b < nbands; b++ ) { - ivas_qmetadata_encode_quasi_uniform( hMetaData, q_direction->band_data[b].energy_ratio_index[0], shl( 1, df_ratio_bits[b] ) ); /* dif_values */ + ivas_qmetadata_encode_quasi_uniform_fx( hMetaData, q_direction->band_data[b].energy_ratio_index[0], shl( 1, df_ratio_bits[b] ) ); /* dif_values */ } } @@ -2016,11 +2013,11 @@ void restore_metadata_buffer_fx( } /*------------------------------------------------------------------------- - * ivas_qmetadata_encode_quasi_uniform() + * ivas_qmetadata_encode_quasi_uniform_fx() * * encode value using a quasi-uniform code of b or b + 1 bits, where b = floor(log2(alphabet_size)) *------------------------------------------------------------------------*/ -static void ivas_qmetadata_encode_quasi_uniform( +static void ivas_qmetadata_encode_quasi_uniform_fx( BSTR_ENC_HANDLE hMetaData, const UWord16 value, const UWord16 alphabet_size ) @@ -2048,12 +2045,12 @@ static void ivas_qmetadata_encode_quasi_uniform( * GR encoder function definitions *-----------------------------------------------------------------------*/ /*------------------------------------------------------------------------- - * GR_bits_new() + * GR_bits_new_fx() * * *------------------------------------------------------------------------*/ /*! r: number of bits using Golomb Rice code */ -static Word16 GR_bits_new( +static Word16 GR_bits_new_fx( UWord16 *data, /* i : data to encode with GR */ Word16 *no_symb, /* i : number of symbols for each component*/ const Word16 no_data, /* i : number of input data */ @@ -2070,7 +2067,7 @@ static Word16 GR_bits_new( FOR( i = 0; i < no_data; i++ ) { - nb = ivas_qmetadata_encode_extended_gr_length( data[i], no_symb[i], GR_order ); + nb = ivas_qmetadata_encode_extended_gr_length_fx( data[i], no_symb[i], GR_order ); nbits = add( nbits, nb ); } @@ -2078,7 +2075,7 @@ static Word16 GR_bits_new( { FOR( i = 0; i < no_data; i++ ) { - nb = ivas_qmetadata_encode_extended_gr_length( data[i], no_symb[i], GR_order - 1 ); + nb = ivas_qmetadata_encode_extended_gr_length_fx( data[i], no_symb[i], GR_order - 1 ); nbits1 = add( nbits1, nb ); } @@ -2111,8 +2108,8 @@ static Word16 GR_bits_new( * Encoding azimuth indexes with GR code using context *------------------------------------------------------------------------*/ /*! r: numer of bits used for coding */ -static Word16 GR_bits_azimuth_context( - UWord16 *data_in, /* i : data to be encoded */ +static Word16 GR_bits_azimuth_context_fx( + UWord16 *data_in, /* i : data to be encoded Qx*/ Word16 *no_symb, /* i : number of symbols for each component */ const Word16 no_data_in, /* i : number of input data */ const Word16 GR_order, /* i : GR order (GR_order or GR_order-1 are used ) */ @@ -2135,7 +2132,7 @@ static Word16 GR_bits_azimuth_context( { no_symb_local[no_data] = no_symb[i]; move16(); - data[no_data++] = data_in[i]; + data[no_data++] = data_in[i]; // Qx move16(); } } @@ -2163,7 +2160,7 @@ static Word16 GR_bits_azimuth_context( { *real_GR_ord = sub( GR_order, (Word16) EQ_16( bits_dir[i], 2 ) ); move16(); - nbits = add( nbits, ivas_qmetadata_encode_extended_gr_length( data[i], no_symb_local[i], *real_GR_ord ) ); + nbits = add( nbits, ivas_qmetadata_encode_extended_gr_length_fx( data[i], no_symb_local[i], *real_GR_ord ) ); } } @@ -2171,27 +2168,27 @@ static Word16 GR_bits_azimuth_context( move16(); IF( use_context == 0 ) { - nbits = GR_bits_new( data, no_symb_local, no_data, GR_order, 1, real_GR_ord ); + nbits = GR_bits_new_fx( data, no_symb_local, no_data, GR_order, 1, real_GR_ord ); nbits1 = nbits; move16(); - min_val = data[0]; + min_val = data[0]; // Qx move16(); FOR( i = 1; i < no_data; i++ ) { if ( LT_32( data[i], min_val ) ) { - min_val = data[i]; + min_val = data[i]; // Qx move16(); } } FOR( i = 0; i < no_data; i++ ) { - cdata[i] = (UWord16) L_sub( data[i], min_val ); + cdata[i] = (UWord16) L_sub( data[i], min_val ); // Qx move16(); } maximum_s( no_symb_local, no_data, &max_val ); - nbits1 = add( GR_bits_new( cdata, no_symb_local, no_data, sub( GR_order, 1 ), 1, &real_GR_ord1 ), ivas_qmetadata_encode_extended_gr_length( min_val, max_val, MASA_GR_ORD_AZ ) ); + nbits1 = add( GR_bits_new_fx( cdata, no_symb_local, no_data, sub( GR_order, 1 ), 1, &real_GR_ord1 ), ivas_qmetadata_encode_extended_gr_length_fx( min_val, max_val, MASA_GR_ORD_AZ ) ); IF( LT_16( nbits1, nbits ) ) { @@ -2220,7 +2217,7 @@ static Word16 GR_bits_azimuth_context( * Golomb Rice encoding with mean removing *------------------------------------------------------------------------*/ /*! r: number of bits used */ -static Word16 mean_removed_GR_new( +static Word16 mean_removed_GR_new_fx( const UWord16 *idx, /* i : data to encode */ const Word16 max_no_symb, const Word16 len, /* i : number of data */ @@ -2235,7 +2232,7 @@ static Word16 mean_removed_GR_new( Word16 max_ns[MASA_MAXIMUM_CODING_SUBBANDS]; /* av = (Word16) ( 0.5f + sum_s( (const Word16 *) idx, len ) / (float) len ); */ - av = div_l( L_add( L_shl( sum16_fx( (const Word16 *) idx, len ), 1 ), 1 ), len ); + av = shr( add( 1, idiv1616U( shl( sum16_fx( (const Word16 *) idx, len ), 1 ), len ) ), 1 ); // Q0 *p_av = av; move16(); @@ -2251,7 +2248,7 @@ static Word16 mean_removed_GR_new( { IF( sh_idx[i] < 0 ) { - sh_idx[i] = -2 * sh_idx[i]; + sh_idx[i] = imult1616( -2, sh_idx[i] ); } ELSE IF( sh_idx[i] > 0 ) { @@ -2267,16 +2264,16 @@ static Word16 mean_removed_GR_new( move16(); } - nbits = GR_bits_new( mr_idx, max_ns, len, *GR_ord, adapt_GR, GR_ord ); + nbits = GR_bits_new_fx( mr_idx, max_ns, len, *GR_ord, adapt_GR, GR_ord ); return nbits; } /*------------------------------------------------------------------------- - * ivas_qmetadata_encode_quasi_uniform_length() + * ivas_qmetadata_encode_quasi_uniform_length_fx() * *------------------------------------------------------------------------*/ -static Word16 ivas_qmetadata_encode_quasi_uniform_length( +static Word16 ivas_qmetadata_encode_quasi_uniform_length_fx( const UWord16 value, const UWord16 alphabet_size ) { @@ -2328,7 +2325,7 @@ static Word16 ivas_qmetadata_entropy_encode_dir_fx( move16(); UWord16 dist_elevation_indexes_best[MAX_PARAM_SPATIAL_SUBFRAMES * MASA_MAXIMUM_CODING_SUBBANDS]; Word16 gr_param_azimuth_best, avg_azimuth_index_best; - uint16_t dist_azimuth_indexes_best[MAX_PARAM_SPATIAL_SUBFRAMES * MASA_MAXIMUM_CODING_SUBBANDS]; + UWord16 dist_azimuth_indexes_best[MAX_PARAM_SPATIAL_SUBFRAMES * MASA_MAXIMUM_CODING_SUBBANDS]; UWord16 idx, dist_count; Word16 direction_bits_ec; @@ -2392,7 +2389,7 @@ static Word16 ivas_qmetadata_entropy_encode_dir_fx( { FOR( j = 0; j < nblocks; j++ ) { - direction_bits_ec = add( direction_bits_ec, ivas_qmetadata_encode_quasi_uniform_length( q_direction->band_data[i].azimuth_index[j], q_direction->band_data[i].azimuth_m_alphabet[j] ) ); + direction_bits_ec = add( direction_bits_ec, ivas_qmetadata_encode_quasi_uniform_length_fx( q_direction->band_data[i].azimuth_index[j], q_direction->band_data[i].azimuth_m_alphabet[j] ) ); } } } @@ -2415,24 +2412,24 @@ static Word16 ivas_qmetadata_entropy_encode_dir_fx( IF( NE_32( q_direction->cfg.mc_ls_setup, MC_LS_SETUP_INVALID ) ) { - avg_elevation_alphabet = no_theta_masa[bits_direction_masa[diff_idx_min] - 3]; + avg_elevation_alphabet = no_theta_masa[bits_direction_masa[diff_idx_min] - 3]; // Q0 move16(); - avg_azimuth_alphabet = no_phi_masa[bits_direction_masa[diff_idx_min] - 1][0]; /* average azimuth is quantized on the equatorial plane */ + avg_azimuth_alphabet = no_phi_masa[bits_direction_masa[diff_idx_min] - 1][0]; /* average azimuth is quantized on the equatorial plane Q0*/ move16(); } ELSE { - avg_elevation_alphabet = sub( shl( no_theta_masa[bits_direction_masa[diff_idx_min] - 3], 1 ), 1 ); - avg_azimuth_alphabet = no_phi_masa[bits_direction_masa[diff_idx_min] - 1][0]; /* average azimuth is quantized on the equatorial plane */ + avg_elevation_alphabet = sub( shl( no_theta_masa[bits_direction_masa[diff_idx_min] - 3], 1 ), 1 ); // Q0 + avg_azimuth_alphabet = no_phi_masa[bits_direction_masa[diff_idx_min] - 1][0]; /* average azimuth is quantized on the equatorial plane Q0*/ move16(); } - no_th = no_theta_masa[bits_direction_masa[diff_idx_min] - 3]; + no_th = no_theta_masa[bits_direction_masa[diff_idx_min] - 3]; // Q0 move16(); FOR( i = 0; i < no_th; i++ ) { - theta_cb[i] = imult1616( i, round_fx( delta_theta_masa_fx[bits_direction_masa[diff_idx_min] - 3] ) ); + theta_cb[i] = imult1616( i, round_fx( delta_theta_masa_fx[bits_direction_masa[diff_idx_min] - 3] ) ); // Q6 move16(); } @@ -2444,13 +2441,13 @@ static Word16 ivas_qmetadata_entropy_encode_dir_fx( IF( avg_elevation < 0 ) { - abs_theta = L_negate( avg_elevation ); + abs_theta = L_negate( avg_elevation ); // Q22 sign_th = -1; move16(); } ELSE { - abs_theta = avg_elevation; + abs_theta = avg_elevation; // Q22 move32(); sign_th = 1; move16(); @@ -2477,7 +2474,7 @@ static Word16 ivas_qmetadata_entropy_encode_dir_fx( // avg_elevation *= sign_th; if ( sign_th < 0 ) { - avg_elevation = L_negate( avg_elevation ); + avg_elevation = L_negate( avg_elevation ); // Q22 } } @@ -2503,7 +2500,11 @@ static Word16 ivas_qmetadata_entropy_encode_dir_fx( } ELSE { +#ifdef FIX_USAN_ISSUES + avg_elevation_index = (UWord16) L_add( avg_elevation_index_initial, ivas_qmetadata_dereorder_generic_fx( avg_elevation_offset ) ); +#else avg_elevation_index = u_extract_l( UL_addNsD( avg_elevation_index_initial, ivas_qmetadata_dereorder_generic_fx( avg_elevation_offset ) ) ); +#endif } // avg_elevation_index = (uint16_t) ( ( avg_elevation_index + avg_elevation_alphabet ) % avg_elevation_alphabet ); avg_elevation_index = u_extract_l( UL_addNsD( avg_elevation_index, avg_elevation_alphabet ) % avg_elevation_alphabet ); @@ -2512,11 +2513,11 @@ static Word16 ivas_qmetadata_entropy_encode_dir_fx( move16(); IF( NE_32( q_direction->cfg.mc_ls_setup, MC_LS_SETUP_INVALID ) ) { - elevation_bits_ec = ivas_qmetadata_encode_quasi_uniform_length( avg_elevation_index, avg_elevation_alphabet ); + elevation_bits_ec = ivas_qmetadata_encode_quasi_uniform_length_fx( avg_elevation_index, avg_elevation_alphabet ); } ELSE { - elevation_bits_ec = ivas_qmetadata_encode_quasi_uniform_length( ivas_qmetadata_reorder_generic_fx( sub( avg_elevation_index, shr( avg_elevation_alphabet, 1 ) ) ), avg_elevation_alphabet ); + elevation_bits_ec = ivas_qmetadata_encode_quasi_uniform_length_fx( ivas_qmetadata_reorder_generic_fx( sub( avg_elevation_index, shr( avg_elevation_alphabet, 1 ) ) ), avg_elevation_alphabet ); } idx = 0; move16(); @@ -2529,11 +2530,11 @@ static Word16 ivas_qmetadata_entropy_encode_dir_fx( /* project the quantized average elevation to the same grid as the current sample */ IF( NE_32( q_direction->cfg.mc_ls_setup, MC_LS_SETUP_INVALID ) ) { - avg_elevation_index_projected = ivas_chan_project_elevation_index_fx( avg_elevation_index, avg_elevation_alphabet, q_direction->band_data[i].elevation_m_alphabet[j] ); + avg_elevation_index_projected = ivas_chan_project_elevation_index_fx( avg_elevation_index, avg_elevation_alphabet, q_direction->band_data[i].elevation_m_alphabet[j] ); // Q0 } ELSE { - avg_elevation_index_projected = ivas_dirac_project_elevation_index_fx( avg_elevation_index, avg_elevation_alphabet, q_direction->band_data[i].elevation_m_alphabet[j] ); + avg_elevation_index_projected = ivas_dirac_project_elevation_index_fx( avg_elevation_index, avg_elevation_alphabet, q_direction->band_data[i].elevation_m_alphabet[j] ); // Q0 } IF( NE_32( q_direction->cfg.mc_ls_setup, MC_LS_SETUP_INVALID ) ) @@ -2586,23 +2587,23 @@ static Word16 ivas_qmetadata_entropy_encode_dir_fx( } ELSE { - gr_param_elevation = ivas_qmetadata_get_optimal_gr_param_fx( dist_elevation_indexes, idx, 4, &gr_size_elevation ); + gr_param_elevation = ivas_qmetadata_get_optimal_gr_param_fx( dist_elevation_indexes, idx, 4, &gr_size_elevation ); // Q0 egr_size_elevation = 0; move16(); FOR( i = 0; i < idx; i++ ) { - egr_size_elevation = add( egr_size_elevation, ivas_qmetadata_encode_extended_gr_length( dist_elevation_indexes[i], dist_elevation_alphabets[i], gr_param_elevation ) ); + egr_size_elevation = add( egr_size_elevation, ivas_qmetadata_encode_extended_gr_length_fx( dist_elevation_indexes[i], dist_elevation_alphabets[i], gr_param_elevation ) ); // Q0 } } - elevation_bits_ec = add( elevation_bits_ec, add( ivas_qmetadata_encode_quasi_uniform_length( gr_param_elevation, 4 + 1 ), egr_size_elevation ) ); + elevation_bits_ec = add( elevation_bits_ec, add( ivas_qmetadata_encode_quasi_uniform_length_fx( gr_param_elevation, 4 + 1 ), egr_size_elevation ) ); // Q0 IF( LT_16( elevation_bits_ec, elevation_bits_ec_best ) ) { - elevation_bits_ec_best = elevation_bits_ec; + elevation_bits_ec_best = elevation_bits_ec; // Q0 move16(); - avg_elevation_index_best = avg_elevation_index; + avg_elevation_index_best = avg_elevation_index; // Q0 move16(); - gr_param_elevation_best = gr_param_elevation; + gr_param_elevation_best = gr_param_elevation; // Q0 move16(); FOR( idx = 0; idx < dist_count; idx++ ) { @@ -2638,11 +2639,16 @@ static Word16 ivas_qmetadata_entropy_encode_dir_fx( FOR( avg_azimuth_offset = 0; avg_azimuth_offset < q_direction->cfg.search_effort; avg_azimuth_offset++ ) { set_zero_fx( avg_direction_vector, 3 ); +#ifdef FIX_USAN_ISSUES + avg_azimuth_index = (UWord16) L_add( avg_azimuth_index_initial, ivas_qmetadata_dereorder_generic_fx( avg_azimuth_offset ) ); + avg_azimuth_index = (UWord16) ( L_add( avg_azimuth_index, avg_azimuth_alphabet ) % avg_azimuth_alphabet ); +#else avg_azimuth_index = (UWord16) add( avg_azimuth_index_initial, ivas_qmetadata_dereorder_generic_fx( avg_azimuth_offset ) ); avg_azimuth_index = (UWord16) ( add( avg_azimuth_index, avg_azimuth_alphabet ) % avg_azimuth_alphabet ); +#endif all_zero_dist_azimuth_indexes = 1; move16(); - azimuth_bits_ec = ivas_qmetadata_encode_quasi_uniform_length( ivas_qmetadata_reorder_generic_fx( sub( avg_azimuth_index, shr( avg_azimuth_alphabet, 1 ) ) ), avg_azimuth_alphabet ); + azimuth_bits_ec = ivas_qmetadata_encode_quasi_uniform_length_fx( ivas_qmetadata_reorder_generic_fx( sub( avg_azimuth_index, shr( avg_azimuth_alphabet, 1 ) ) ), avg_azimuth_alphabet ); idx = 0; move16(); @@ -2724,11 +2730,11 @@ static Word16 ivas_qmetadata_entropy_encode_dir_fx( move16(); FOR( i = 0; i < idx; i++ ) { - egr_size_azimuth = add( egr_size_azimuth, ivas_qmetadata_encode_extended_gr_length( dist_azimuth_indexes[i], dist_azimuth_alphabets[i], gr_param_azimuth ) ); + egr_size_azimuth = add( egr_size_azimuth, ivas_qmetadata_encode_extended_gr_length_fx( dist_azimuth_indexes[i], dist_azimuth_alphabets[i], gr_param_azimuth ) ); } } - azimuth_bits_ec = add( azimuth_bits_ec, add( ivas_qmetadata_encode_quasi_uniform_length( gr_param_azimuth, 5 + 1 ), egr_size_azimuth ) ); + azimuth_bits_ec = add( azimuth_bits_ec, add( ivas_qmetadata_encode_quasi_uniform_length_fx( gr_param_azimuth, 5 + 1 ), egr_size_azimuth ) ); IF( LT_16( azimuth_bits_ec, azimuth_bits_ec_best ) ) { @@ -2778,7 +2784,7 @@ static Word16 ivas_qmetadata_entropy_encode_dir_fx( { FOR( j = 0; j < nblocks; j++ ) { - ivas_qmetadata_encode_quasi_uniform( hMetaData, q_direction->band_data[i].azimuth_index[j], q_direction->band_data[i].azimuth_m_alphabet[j] ); + ivas_qmetadata_encode_quasi_uniform_fx( hMetaData, q_direction->band_data[i].azimuth_index[j], q_direction->band_data[i].azimuth_m_alphabet[j] ); } } } @@ -2797,28 +2803,28 @@ static Word16 ivas_qmetadata_entropy_encode_dir_fx( /* encode the ExtendedGR part for elevation */ IF( NE_32( q_direction->cfg.mc_ls_setup, MC_LS_SETUP_INVALID ) ) { - ivas_qmetadata_encode_quasi_uniform( hMetaData, avg_elevation_index_best, avg_elevation_alphabet ); + ivas_qmetadata_encode_quasi_uniform_fx( hMetaData, avg_elevation_index_best, avg_elevation_alphabet ); } ELSE { - ivas_qmetadata_encode_quasi_uniform( hMetaData, ivas_qmetadata_reorder_generic_fx( sub( avg_elevation_index_best, shr( avg_elevation_alphabet, 1 ) ) ), avg_elevation_alphabet ); + ivas_qmetadata_encode_quasi_uniform_fx( hMetaData, ivas_qmetadata_reorder_generic_fx( sub( avg_elevation_index_best, shr( avg_elevation_alphabet, 1 ) ) ), avg_elevation_alphabet ); } - ivas_qmetadata_encode_quasi_uniform( hMetaData, gr_param_elevation_best, 4 + 1 ); + ivas_qmetadata_encode_quasi_uniform_fx( hMetaData, gr_param_elevation_best, 4 + 1 ); IF( NE_16( gr_param_elevation_best, 4 ) ) /* not all zero */ { FOR( idx = 0; idx < dist_count; idx++ ) { - ivas_qmetadata_encode_extended_gr( hMetaData, dist_elevation_indexes_best[idx], dist_elevation_alphabets[idx], gr_param_elevation_best ); + ivas_qmetadata_encode_extended_gr_fx( hMetaData, dist_elevation_indexes_best[idx], dist_elevation_alphabets[idx], gr_param_elevation_best ); } } } /* encode the ExtendedGR part for azimuth */ - ivas_qmetadata_encode_quasi_uniform( hMetaData, ivas_qmetadata_reorder_generic_fx( sub( avg_azimuth_index_best, shr( avg_azimuth_alphabet, 1 ) ) ), avg_azimuth_alphabet ); + ivas_qmetadata_encode_quasi_uniform_fx( hMetaData, ivas_qmetadata_reorder_generic_fx( sub( avg_azimuth_index_best, shr( avg_azimuth_alphabet, 1 ) ) ), avg_azimuth_alphabet ); - ivas_qmetadata_encode_quasi_uniform( hMetaData, gr_param_azimuth_best, 5 + 1 ); + ivas_qmetadata_encode_quasi_uniform_fx( hMetaData, gr_param_azimuth_best, 5 + 1 ); IF( NE_16( gr_param_azimuth_best, 5 ) ) /* not all zero */ { @@ -2830,24 +2836,24 @@ static Word16 ivas_qmetadata_entropy_encode_dir_fx( { IF( GT_16( dist_azimuth_indexes_best[idx], 1 ) ) { - ivas_qmetadata_encode_extended_gr( hMetaData, sub( dist_azimuth_indexes_best[idx], 2 ), dist_azimuth_alphabets[idx], gr_param_azimuth_best ); - bits_gained = add( bits_gained, sub( ivas_qmetadata_encode_extended_gr_length( dist_azimuth_indexes_best[idx], dist_azimuth_alphabets[idx], gr_param_azimuth_best ), - ivas_qmetadata_encode_extended_gr_length( sub( dist_azimuth_indexes_best[idx], 2 ), dist_azimuth_alphabets[idx], gr_param_azimuth_best ) ) ); + ivas_qmetadata_encode_extended_gr_fx( hMetaData, sub( dist_azimuth_indexes_best[idx], 2 ), dist_azimuth_alphabets[idx], gr_param_azimuth_best ); + bits_gained = add( bits_gained, sub( ivas_qmetadata_encode_extended_gr_length_fx( dist_azimuth_indexes_best[idx], dist_azimuth_alphabets[idx], gr_param_azimuth_best ), + ivas_qmetadata_encode_extended_gr_length_fx( sub( dist_azimuth_indexes_best[idx], 2 ), dist_azimuth_alphabets[idx], gr_param_azimuth_best ) ) ); } ELSE IF( EQ_16( dist_azimuth_indexes_best[idx], 1 ) ) { - ivas_qmetadata_encode_extended_gr( hMetaData, sub( dist_azimuth_indexes_best[idx], 1 ), dist_azimuth_alphabets[idx], gr_param_azimuth_best ); - bits_gained = add( bits_gained, sub( ivas_qmetadata_encode_extended_gr_length( dist_azimuth_indexes_best[idx], dist_azimuth_alphabets[idx], gr_param_azimuth_best ), - ivas_qmetadata_encode_extended_gr_length( sub( dist_azimuth_indexes_best[idx], 1 ), dist_azimuth_alphabets[idx], gr_param_azimuth_best ) ) ); + ivas_qmetadata_encode_extended_gr_fx( hMetaData, sub( dist_azimuth_indexes_best[idx], 1 ), dist_azimuth_alphabets[idx], gr_param_azimuth_best ); + bits_gained = add( bits_gained, sub( ivas_qmetadata_encode_extended_gr_length_fx( dist_azimuth_indexes_best[idx], dist_azimuth_alphabets[idx], gr_param_azimuth_best ), + ivas_qmetadata_encode_extended_gr_length_fx( sub( dist_azimuth_indexes_best[idx], 1 ), dist_azimuth_alphabets[idx], gr_param_azimuth_best ) ) ); } ELSE { - ivas_qmetadata_encode_extended_gr( hMetaData, dist_azimuth_indexes_best[idx], dist_azimuth_alphabets[idx], gr_param_azimuth_best ); + ivas_qmetadata_encode_extended_gr_fx( hMetaData, dist_azimuth_indexes_best[idx], dist_azimuth_alphabets[idx], gr_param_azimuth_best ); } } ELSE { - ivas_qmetadata_encode_extended_gr( hMetaData, dist_azimuth_indexes_best[idx], dist_azimuth_alphabets[idx], gr_param_azimuth_best ); + ivas_qmetadata_encode_extended_gr_fx( hMetaData, dist_azimuth_indexes_best[idx], dist_azimuth_alphabets[idx], gr_param_azimuth_best ); } } @@ -2866,24 +2872,24 @@ static Word16 ivas_qmetadata_entropy_encode_dir_fx( { IF( GT_16( dist_azimuth_indexes_best[idx], 1 ) ) { - ivas_qmetadata_encode_extended_gr( hMetaData, sub( dist_azimuth_indexes_best[idx], 2 ), dist_azimuth_alphabets[idx], gr_param_azimuth_best ); - bits_gained = add( bits_gained, sub( ivas_qmetadata_encode_extended_gr_length( dist_azimuth_indexes_best[idx], dist_azimuth_alphabets[idx], gr_param_azimuth_best ), - ivas_qmetadata_encode_extended_gr_length( sub( dist_azimuth_indexes_best[idx], 2 ), dist_azimuth_alphabets[idx], gr_param_azimuth_best ) ) ); + ivas_qmetadata_encode_extended_gr_fx( hMetaData, sub( dist_azimuth_indexes_best[idx], 2 ), dist_azimuth_alphabets[idx], gr_param_azimuth_best ); + bits_gained = add( bits_gained, sub( ivas_qmetadata_encode_extended_gr_length_fx( dist_azimuth_indexes_best[idx], dist_azimuth_alphabets[idx], gr_param_azimuth_best ), + ivas_qmetadata_encode_extended_gr_length_fx( sub( dist_azimuth_indexes_best[idx], 2 ), dist_azimuth_alphabets[idx], gr_param_azimuth_best ) ) ); } ELSE IF( EQ_16( dist_azimuth_indexes_best[idx], 1 ) ) { - ivas_qmetadata_encode_extended_gr( hMetaData, sub( dist_azimuth_indexes_best[idx], 1 ), dist_azimuth_alphabets[idx], gr_param_azimuth_best ); - bits_gained = add( bits_gained, sub( ivas_qmetadata_encode_extended_gr_length( dist_azimuth_indexes_best[idx], dist_azimuth_alphabets[idx], gr_param_azimuth_best ), - ivas_qmetadata_encode_extended_gr_length( sub( dist_azimuth_indexes_best[idx], 1 ), dist_azimuth_alphabets[idx], gr_param_azimuth_best ) ) ); + ivas_qmetadata_encode_extended_gr_fx( hMetaData, sub( dist_azimuth_indexes_best[idx], 1 ), dist_azimuth_alphabets[idx], gr_param_azimuth_best ); + bits_gained = add( bits_gained, sub( ivas_qmetadata_encode_extended_gr_length_fx( dist_azimuth_indexes_best[idx], dist_azimuth_alphabets[idx], gr_param_azimuth_best ), + ivas_qmetadata_encode_extended_gr_length_fx( sub( dist_azimuth_indexes_best[idx], 1 ), dist_azimuth_alphabets[idx], gr_param_azimuth_best ) ) ); } ELSE { - ivas_qmetadata_encode_extended_gr( hMetaData, dist_azimuth_indexes_best[idx], dist_azimuth_alphabets[idx], gr_param_azimuth_best ); + ivas_qmetadata_encode_extended_gr_fx( hMetaData, dist_azimuth_indexes_best[idx], dist_azimuth_alphabets[idx], gr_param_azimuth_best ); } } ELSE { - ivas_qmetadata_encode_extended_gr( hMetaData, dist_azimuth_indexes_best[idx], dist_azimuth_alphabets[idx], gr_param_azimuth_best ); + ivas_qmetadata_encode_extended_gr_fx( hMetaData, dist_azimuth_indexes_best[idx], dist_azimuth_alphabets[idx], gr_param_azimuth_best ); } } } @@ -2950,18 +2956,18 @@ static Word16 ivas_qmetadata_raw_encode_dir_fx( { IF( hMetaData != NULL ) { - ivas_qmetadata_encode_quasi_uniform( hMetaData, q_direction->band_data[i].azimuth_index[j], q_direction->band_data[i].azimuth_m_alphabet[j] ); + ivas_qmetadata_encode_quasi_uniform_fx( hMetaData, q_direction->band_data[i].azimuth_index[j], q_direction->band_data[i].azimuth_m_alphabet[j] ); } ELSE { direction_bits_raw = add( direction_bits_raw, - ivas_qmetadata_encode_quasi_uniform_length( q_direction->band_data[i].azimuth_index[j], q_direction->band_data[i].azimuth_m_alphabet[j] ) ); + ivas_qmetadata_encode_quasi_uniform_length_fx( q_direction->band_data[i].azimuth_index[j], q_direction->band_data[i].azimuth_m_alphabet[j] ) ); } } } } - if ( hMetaData != NULL ) + IF( hMetaData != NULL ) { direction_bits_raw = sub( hMetaData->nb_bits_tot, start_bits ); } @@ -3013,12 +3019,12 @@ static Word16 ivas_qmetadata_get_optimal_gr_param_fx( } /*------------------------------------------------------------------------- - * ivas_qmetadata_encode_extended_gr_length() + * ivas_qmetadata_encode_extended_gr_length_fx() * * *------------------------------------------------------------------------*/ Word16 -ivas_qmetadata_encode_extended_gr_length( +ivas_qmetadata_encode_extended_gr_length_fx( const UWord16 value, const UWord16 alphabet_size, const Word16 gr_param ) @@ -3033,7 +3039,7 @@ ivas_qmetadata_encode_extended_gr_length( IF( LE_32( msb_alphabet_size, 3 ) ) { /* EncodeQuasiUniform is always equal or better than Limited GR with up to 3 msb values */ - bits = ivas_qmetadata_encode_quasi_uniform_length( value, alphabet_size ); + bits = ivas_qmetadata_encode_quasi_uniform_length_fx( value, alphabet_size ); } ELSE { @@ -3048,7 +3054,7 @@ ivas_qmetadata_encode_extended_gr_length( ELSE { lsb = (UWord16) L_and( value, L_sub( L_shl( 1U, gr_param ), 1 ) ); - bits = add( bits, ivas_qmetadata_encode_quasi_uniform_length( lsb, (UWord16) L_sub( alphabet_size, L_shl( L_sub( msb_alphabet_size, 1 ), gr_param ) ) ) ); + bits = add( bits, ivas_qmetadata_encode_quasi_uniform_length_fx( lsb, (UWord16) L_sub( alphabet_size, L_shl( L_sub( msb_alphabet_size, 1 ), gr_param ) ) ) ); } } @@ -3133,11 +3139,11 @@ static Word16 ivas_qmetadata_reorder_azimuth_index_fx( } /*------------------------------------------------------------------------- - * ivas_qmetadata_encode_extended_gr() + * ivas_qmetadata_encode_extended_gr_fx() * * *------------------------------------------------------------------------*/ -void ivas_qmetadata_encode_extended_gr( +void ivas_qmetadata_encode_extended_gr_fx( BSTR_ENC_HANDLE hMetaData, const UWord16 value, const UWord16 alphabet_size, @@ -3152,7 +3158,7 @@ void ivas_qmetadata_encode_extended_gr( IF( LE_32( msb_alphabet_size, 3 ) ) { /* EncodeQuasiUniform is always equal or better than Limited GR with up to 3 msb values */ - ivas_qmetadata_encode_quasi_uniform( hMetaData, value, alphabet_size ); + ivas_qmetadata_encode_quasi_uniform_fx( hMetaData, value, alphabet_size ); } ELSE { @@ -3175,7 +3181,7 @@ void ivas_qmetadata_encode_extended_gr( } ELSE { - ivas_qmetadata_encode_quasi_uniform( hMetaData, lsb, (UWord16) L_sub( alphabet_size, L_shl( L_sub( msb_alphabet_size, 1 ), gr_param ) ) ); + ivas_qmetadata_encode_quasi_uniform_fx( hMetaData, lsb, (UWord16) L_sub( alphabet_size, L_shl( L_sub( msb_alphabet_size, 1 ), gr_param ) ) ); } } @@ -3253,7 +3259,7 @@ static Word16 truncGR0_fx( move32(); data_idx[i] = remap3b[data_idx[i]]; move16(); - bits = add( bits, ivas_qmetadata_encode_extended_gr_length( data_idx[i], 8, 0 ) ); + bits = add( bits, ivas_qmetadata_encode_extended_gr_length_fx( data_idx[i], 8, 0 ) ); // diff[i] = -st[i] - ct[i] * cosf( PI_OVER_180 * ( data[i] - data_hat[i] ) ); /*(data[i] - data_hat[i])*(data[i] - data_hat[i]);*/ L_temp = L_deposit_h( getCosWord16R2( extract_l( L_shr( Mpy_32_16_1( L_sub( data_fx[i], data_hat_fx[i] ), 91 ), 7 ) ) ) ); // Q31 diff_fx[i] = L_negate( L_add( L_shr( st_fx[i], 1 ), L_shr( Mpy_32_32( ct_fx[i], L_temp ), 1 ) ) ); // Q30 @@ -3269,7 +3275,7 @@ static Word16 truncGR0_fx( { IF( GT_32( data_idx[indx[i]], 3 ) ) { - bits = sub( bits, ivas_qmetadata_encode_extended_gr_length( data_idx[indx[i]], 8, 0 ) ); + bits = sub( bits, ivas_qmetadata_encode_extended_gr_length_fx( data_idx[indx[i]], 8, 0 ) ); // data_idx[indx[i]] = quantize_phi( data[indx[i]] + 180, 0, &data_hat[indx[i]], 4 ); data_idx[indx[i]] = quantize_phi_enc_fx( L_add( data_fx[indx[i]], DEGREE_180_Q_22 ), 0, &data_hat_fx[indx[i]], 4 ); move16(); @@ -3278,7 +3284,7 @@ static Word16 truncGR0_fx( move32(); data_idx[indx[i]] = remap2b[data_idx[indx[i]]]; move16(); - bits = add( bits, ivas_qmetadata_encode_extended_gr_length( data_idx[indx[i]], 8, 0 ) ); + bits = add( bits, ivas_qmetadata_encode_extended_gr_length_fx( data_idx[indx[i]], 8, 0 ) ); // diff[indx[i]] = -st[i] - ct[i] * cosf( PI_OVER_180 * ( data[indx[i]] - data_hat[indx[i]] ) ); L_temp = L_deposit_h( getCosWord16R2( extract_l( L_shr( Mpy_32_16_1( L_sub( data_fx[indx[i]], data_hat_fx[indx[i]] ), 91 ), 7 ) ) ) ); // Q31 @@ -3300,7 +3306,7 @@ static Word16 truncGR0_fx( IF( GT_16( data_idx[indx[i]], 1 ) ) { - bits = sub( bits, ivas_qmetadata_encode_extended_gr_length( data_idx[indx[i]], 8, 0 ) ); + bits = sub( bits, ivas_qmetadata_encode_extended_gr_length_fx( data_idx[indx[i]], 8, 0 ) ); IF( LE_32( L_abs( data_fx[indx[i]] ), 377487360 ) ) // 90 in Q22 { @@ -3319,7 +3325,7 @@ static Word16 truncGR0_fx( move32(); } - bits = add( bits, ivas_qmetadata_encode_extended_gr_length( data_idx[indx[i]], 8, 0 ) ); + bits = add( bits, ivas_qmetadata_encode_extended_gr_length_fx( data_idx[indx[i]], 8, 0 ) ); // diff[indx[i]] = -st[i] - ct[i] * cosf( PI_OVER_180 * ( data[indx[i]] - data_hat[indx[i]] ) ); L_temp = L_deposit_h( getCosWord16R2( extract_l( L_shr( Mpy_32_16_1( L_sub( data_fx[indx[i]], data_hat_fx[indx[i]] ), 91 ), 7 ) ) ) ); // Q31 @@ -3412,14 +3418,14 @@ static Word16 truncGR0_chan_fx( { data_idx[i] = quantize_phi_chan_lbr_fx( data_fx[i], &data_hat_fx[i], 9 ); move16(); - bits = add( bits, ivas_qmetadata_encode_extended_gr_length( data_idx[i], 9, 0 ) ); + bits = add( bits, ivas_qmetadata_encode_extended_gr_length_fx( data_idx[i], 9, 0 ) ); // diff[i] = -st[i] - ct[i] * cosf( ( data[i] - data_hat[i] ) * PI_OVER_180 ); L_temp = L_deposit_h( getCosWord16R2( extract_l( L_shr( Mpy_32_16_1( L_sub( data_fx[i], data_hat_fx[i] ), 91 ), 7 ) ) ) ); // Q31 diff_fx[i] = L_negate( L_add( L_shr( st_fx[i], 1 ), L_shr( Mpy_32_32( ct_fx[i], L_temp ), 1 ) ) ); // Q30 move32(); } - WHILE( GT_16( bits, bits_allowed ) ) + WHILE( ( bits > bits_allowed ) ) { // min_diff = 1000.0f; min_diff_fx = 2097152000; // 1000 in Q21 @@ -3454,10 +3460,10 @@ static Word16 truncGR0_chan_fx( IF( GT_16( idx_crt, -1 ) ) { - bits = sub( bits, ivas_qmetadata_encode_extended_gr_length( data_idx[idx_crt], 9, 0 ) ); + bits = sub( bits, ivas_qmetadata_encode_extended_gr_length_fx( data_idx[idx_crt], 9, 0 ) ); data_idx[idx_crt] = quantize_phi_chan_lbr_fx( data_fx[idx_crt], &data_hat_fx[idx_crt], add( data_idx[idx_crt], 1 ) ); move16(); - bits = add( bits, ivas_qmetadata_encode_extended_gr_length( data_idx[idx_crt], 9, 0 ) ); + bits = add( bits, ivas_qmetadata_encode_extended_gr_length_fx( data_idx[idx_crt], 9, 0 ) ); // diff[idx_crt] = -st[idx_crt] - ct[idx_crt] * cosf( ( data[idx_crt] - data_hat[idx_crt] ) * PI_OVER_180 ); L_temp = L_deposit_h( getCosWord16R2( extract_l( L_shr( Mpy_32_16_1( L_sub( data_fx[idx_crt], data_hat_fx[idx_crt] ), 91 ), 7 ) ) ) ); // Q31 @@ -3481,7 +3487,7 @@ static Word16 truncGR0_chan_fx( move16(); IF( data_idx[idx_crt] > 0 ) { - bits = sub( bits, ivas_qmetadata_encode_extended_gr_length( data_idx[idx_crt], 9, 0 ) ); + bits = sub( bits, ivas_qmetadata_encode_extended_gr_length_fx( data_idx[idx_crt], 9, 0 ) ); data_idx[idx_crt] = 0; move16(); data_hat_fx[idx_crt] = 0; @@ -3705,14 +3711,14 @@ static Word16 common_direction_fx( { FOR( i = 0; i < len; i++ ) { - ivas_qmetadata_encode_extended_gr( hMetaData, q_direction->band_data[band_idx].azimuth_index[i], 9, 0 ); + ivas_qmetadata_encode_extended_gr_fx( hMetaData, q_direction->band_data[band_idx].azimuth_index[i], 9, 0 ); } } ELSE { FOR( i = 0; i < len; i++ ) { - ivas_qmetadata_encode_extended_gr( hMetaData, q_direction->band_data[band_idx].azimuth_index[i], 8, 0 ); + ivas_qmetadata_encode_extended_gr_fx( hMetaData, q_direction->band_data[band_idx].azimuth_index[i], 8, 0 ); } } } @@ -3734,8 +3740,9 @@ static Word16 encode_directions_subband_fx( const Word16 no_subframes, const Word16 last_subband, Word16 *p_diff, - Word32 *elevation_orig_fx, - Word32 *azimuth_orig_fx ) + Word32 *elevation_orig_fx, // Q22 + Word32 *azimuth_orig_fx // Q22 +) { Word16 allowed_bits, use_vq, max_nb_idx, k; Word16 diff; @@ -3807,8 +3814,8 @@ static Word16 encode_directions_subband_fx( IF( last_subband == 0 ) { - Copy32( elevation_orig_fx, q_direction->band_data[j].elevation_fx, no_subframes ); - Copy32( azimuth_orig_fx, q_direction->band_data[j].azimuth_fx, no_subframes ); + Copy32( elevation_orig_fx, q_direction->band_data[j].elevation_fx, no_subframes ); // Q22 + Copy32( azimuth_orig_fx, q_direction->band_data[j].azimuth_fx, no_subframes ); // Q22 joint_encoding_fx( q_direction, j, next_j, coding_subbands, bits_dir0, allowed_bits, hMetaData, &diff ); } ELSE @@ -3831,8 +3838,8 @@ static Word16 encode_directions_subband_fx( ELSE { /* there is only joint coding */ - Copy32( elevation_orig_fx, q_direction->band_data[j].elevation_fx, no_subframes ); - Copy32( azimuth_orig_fx, q_direction->band_data[j].azimuth_fx, no_subframes ); + Copy32( elevation_orig_fx, q_direction->band_data[j].elevation_fx, no_subframes ); // Q22 + Copy32( azimuth_orig_fx, q_direction->band_data[j].azimuth_fx, no_subframes ); // Q22 IF( last_subband == 0 ) { @@ -3859,8 +3866,8 @@ static Word16 encode_directions_subband_fx( { /* 1 subframe case */ /* there is only joint coding */ - Copy32( elevation_orig_fx, q_direction->band_data[j].elevation_fx, no_subframes ); - Copy32( azimuth_orig_fx, q_direction->band_data[j].azimuth_fx, no_subframes ); + Copy32( elevation_orig_fx, q_direction->band_data[j].elevation_fx, no_subframes ); // Q22 + Copy32( azimuth_orig_fx, q_direction->band_data[j].azimuth_fx, no_subframes ); // Q22 IF( last_subband == 0 ) { @@ -3983,8 +3990,8 @@ static ivas_error requantize_direction_EC_3_fx( IVAS_QDIRECTION *q_direction, const Word16 coding_subbands, BSTR_ENC_HANDLE hMetaData, - Word32 elevation_orig_fx[MASA_MAXIMUM_CODING_SUBBANDS][MAX_PARAM_SPATIAL_SUBFRAMES], - Word32 azimuth_orig_fx[MASA_MAXIMUM_CODING_SUBBANDS][MAX_PARAM_SPATIAL_SUBFRAMES], + Word32 elevation_orig_fx[MASA_MAXIMUM_CODING_SUBBANDS][MAX_PARAM_SPATIAL_SUBFRAMES], // Q22 + Word32 azimuth_orig_fx[MASA_MAXIMUM_CODING_SUBBANDS][MAX_PARAM_SPATIAL_SUBFRAMES], // Q22 Word16 *ind_order ) { /* gradually increase the bits following the performance of the EC layer*/ @@ -4081,7 +4088,8 @@ static ivas_error requantize_direction_EC_3_fx( IF( LE_16( allowed_bits, add( no_subframes, 1 ) ) ) { - FOR( k = 0; k < min( no_subframes, allowed_bits ); k++ ) + Word16 len = s_min( no_subframes, allowed_bits ); + FOR( k = 0; k < len; k++ ) { push_next_indice( hMetaData, q_direction->band_data[j].azimuth_index[k], 1 ); } @@ -4090,7 +4098,7 @@ static ivas_error requantize_direction_EC_3_fx( { FOR( k = 0; k < no_subframes; k++ ) { - ivas_qmetadata_encode_extended_gr( hMetaData, q_direction->band_data[j].azimuth_index[k], q_direction->cfg.mc_ls_setup != MC_LS_SETUP_INVALID ? 9 : 8, 0 ); + ivas_qmetadata_encode_extended_gr_fx( hMetaData, q_direction->band_data[j].azimuth_index[k], q_direction->cfg.mc_ls_setup != MC_LS_SETUP_INVALID ? 9 : 8, 0 ); } } } @@ -4240,7 +4248,7 @@ static void joint_encoding_fx( IF( len_data > 0 ) { - nbits = GR_bits_new( data, no_symb_ele, len_data, MASA_GR_ORD_EL, 1, &GR_ord_elevation ); + nbits = GR_bits_new_fx( data, no_symb_ele, len_data, MASA_GR_ORD_EL, 1, &GR_ord_elevation ); } ELSE { @@ -4273,9 +4281,9 @@ static void joint_encoding_fx( nbits = add( nbits, 1 ); } - nbits = add( nbits, GR_bits_azimuth_context( q_direction->band_data[j].azimuth_index, - q_direction->band_data[j].azimuth_m_alphabet, q_direction->cfg.nblocks, MASA_GR_ORD_AZ, - q_direction->band_data[j].bits_sph_idx, &GR_ord_azimuth, &use_context ) ); + nbits = add( nbits, GR_bits_azimuth_context_fx( q_direction->band_data[j].azimuth_index, + q_direction->band_data[j].azimuth_m_alphabet, q_direction->cfg.nblocks, MASA_GR_ORD_AZ, + q_direction->band_data[j].bits_sph_idx, &GR_ord_azimuth, &use_context ) ); IF( allowed_bits == 0 ) { @@ -4507,7 +4515,7 @@ static ivas_error write_ec_direction_fx( { bits_crt = hMetaData->nb_bits_tot; move16(); - ivas_qmetadata_encode_extended_gr( hMetaData, data, qdirection->band_data[j_idx].elevation_m_alphabet[i], GR_ord_elevation ); + ivas_qmetadata_encode_extended_gr_fx( hMetaData, data, qdirection->band_data[j_idx].elevation_m_alphabet[i], GR_ord_elevation ); nbits = add( nbits, sub( hMetaData->nb_bits_tot, bits_crt ) ); } } @@ -4532,7 +4540,7 @@ static ivas_error write_ec_direction_fx( { bits_crt = hMetaData->nb_bits_tot; move16(); - ivas_qmetadata_encode_extended_gr( hMetaData, data, qdirection->band_data[j_idx].azimuth_m_alphabet[i], GR_ord_azimuth ); + ivas_qmetadata_encode_extended_gr_fx( hMetaData, data, qdirection->band_data[j_idx].azimuth_m_alphabet[i], GR_ord_azimuth ); nbits = add( nbits, sub( hMetaData->nb_bits_tot, bits_crt ) ); } } @@ -4562,7 +4570,7 @@ static ivas_error write_ec_direction_fx( bits_crt = hMetaData->nb_bits_tot; move16(); maximum_s( qdirection->band_data[j_idx].azimuth_m_alphabet, len, &max_val ); - ivas_qmetadata_encode_extended_gr( hMetaData, min_val, max_val, MASA_GR_ORD_AZ ); + ivas_qmetadata_encode_extended_gr_fx( hMetaData, min_val, max_val, MASA_GR_ORD_AZ ); nbits = add( nbits, sub( hMetaData->nb_bits_tot, bits_crt ) ); FOR( i = 0; i < len; i++ ) @@ -4572,7 +4580,7 @@ static ivas_error write_ec_direction_fx( { bits_crt = hMetaData->nb_bits_tot; move16(); - ivas_qmetadata_encode_extended_gr( hMetaData, data, qdirection->band_data[j_idx].azimuth_m_alphabet[i], GR_ord_azimuth ); + ivas_qmetadata_encode_extended_gr_fx( hMetaData, data, qdirection->band_data[j_idx].azimuth_m_alphabet[i], GR_ord_azimuth ); nbits = add( nbits, sub( hMetaData->nb_bits_tot, bits_crt ) ); } } @@ -4596,13 +4604,13 @@ static ivas_error write_ec_direction_fx( case 2: bits_crt = hMetaData->nb_bits_tot; move16(); - ivas_qmetadata_encode_extended_gr( hMetaData, data, qdirection->band_data[j_idx].azimuth_m_alphabet[i], MASA_GR_ORD_AZ - 1 ); + ivas_qmetadata_encode_extended_gr_fx( hMetaData, data, qdirection->band_data[j_idx].azimuth_m_alphabet[i], MASA_GR_ORD_AZ - 1 ); nbits = add( nbits, sub( hMetaData->nb_bits_tot, bits_crt ) ); BREAK; default: bits_crt = hMetaData->nb_bits_tot; move16(); - ivas_qmetadata_encode_extended_gr( hMetaData, data, qdirection->band_data[j_idx].azimuth_m_alphabet[i], MASA_GR_ORD_AZ ); + ivas_qmetadata_encode_extended_gr_fx( hMetaData, data, qdirection->band_data[j_idx].azimuth_m_alphabet[i], MASA_GR_ORD_AZ ); nbits = add( nbits, sub( hMetaData->nb_bits_tot, bits_crt ) ); BREAK; } @@ -4619,7 +4627,7 @@ static ivas_error write_ec_direction_fx( * Local functions (coherence Q and coding) *-----------------------------------------------------------------------*/ /*! r: index */ -static UWord64 create_combined_index( +static UWord64 create_combined_index_fx( UWord16 *idx_dct, /* i : indexes to combine */ const Word16 len, /* i : number of indexes */ const Word16 *no_cb_vec /* i : how many codewords for each position */ @@ -4665,12 +4673,12 @@ static Word16 encode_coherence_indexesDCT0_fx( IF( nbits1 > 0 ) { half_len = shr( len, 1 ); - idx = create_combined_index( idx_dct, half_len, no_cb_vec ); - idx1 = create_combined_index( &idx_dct[half_len], half_len, &no_cb_vec[half_len] ); + idx = create_combined_index_fx( idx_dct, half_len, no_cb_vec ); + idx1 = create_combined_index_fx( &idx_dct[half_len], half_len, &no_cb_vec[half_len] ); } ELSE { - idx = create_combined_index( idx_dct, len, no_cb_vec ); + idx = create_combined_index_fx( idx_dct, len, no_cb_vec ); idx1 = 0; move16(); } @@ -4682,7 +4690,7 @@ static Word16 encode_coherence_indexesDCT0_fx( } ELSE { - // no_idx16 = (int16_t) round_f( ( nbits / 16.0f + 0.5f ) ); + // no_idx16 = (Word16) round_f( ( nbits / 16.0f + 0.5f ) ); no_idx16 = shr_r( add( nbits, ONE_IN_Q3 ), 4 ); } @@ -4708,7 +4716,7 @@ static Word16 encode_coherence_indexesDCT0_fx( } ELSE { - // no_idx16 = (int16_t) round_f( ( nbits1 / 16.0f + 0.5f ) ); + // no_idx16 = (Word16) round_f( ( nbits1 / 16.0f + 0.5f ) ); no_idx16 = shr_r( add( nbits1, ONE_IN_Q3 ), 4 ); } @@ -4765,7 +4773,7 @@ static Word16 coherence_coding_length( { no_cb = no_cb * no_cv[j]; } - //*nbits_fr = (int16_t) ceilf( logf( (float) no_cb ) * INV_LOG_2 ); + //*nbits_fr = (Word16) ceilf( logf( (float) no_cb ) * INV_LOG_2 ); IF( LE_64( no_cb, 1 ) ) { *nbits_fr = 0; @@ -4781,7 +4789,7 @@ static Word16 coherence_coding_length( { no_cb = no_cb * no_cv[j]; } - //*nbits_fr1 = (int16_t) ceilf( logf( (float) no_cb ) * INV_LOG_2 ); + //*nbits_fr1 = (Word16) ceilf( logf( (float) no_cb ) * INV_LOG_2 ); IF( LE_64( no_cb, 1 ) ) { *nbits_fr1 = 0; @@ -4799,7 +4807,7 @@ static Word16 coherence_coding_length( { no_cb = no_cb * no_cv[j]; } - //*nbits_fr = (int16_t) ceilf( logf( (float) no_cb ) * INV_LOG_2 ); + //*nbits_fr = (Word16) ceilf( logf( (float) no_cb ) * INV_LOG_2 ); IF( LE_64( no_cb, 1 ) ) { *nbits_fr = 0; @@ -4814,7 +4822,7 @@ static Word16 coherence_coding_length( } - minimum_s( (const Word16 *) idx_sur_coh_shift, (int16_t) idx_shift_len, &min_idx ); + minimum_s( (const Word16 *) idx_sur_coh_shift, (Word16) idx_shift_len, &min_idx ); FOR( j = 0; j < idx_shift_len; j++ ) { mr_idx[j] = sub( idx_sur_coh_shift[j], min_idx ); @@ -4822,7 +4830,7 @@ static Word16 coherence_coding_length( no_cv_shift[j] = sub( no_cv_shift[j], min_idx ); move16(); } - nbits = add( add( min_idx, 1 ), GR_bits_new( mr_idx, no_cv_shift, idx_shift_len, *GR_ord, 1, GR_ord ) ); + nbits = add( add( min_idx, 1 ), GR_bits_new_fx( mr_idx, no_cv_shift, idx_shift_len, *GR_ord, 1, GR_ord ) ); *p_min_idx = min_idx; move16(); @@ -4876,7 +4884,7 @@ static Word16 encode_spread_coherence_1sf_fx( move16(); extra_cv = -1; move16(); - WHILE( LE_16( tmp, coding_subbands ) ) + WHILE( ( tmp <= coding_subbands ) ) { tmp = add( tmp, 6 ); extra_cv = add( extra_cv, 1 ); @@ -4897,7 +4905,7 @@ static Word16 encode_spread_coherence_1sf_fx( // idx_sp_coh[j] = (uint16_t) roundf( q_direction->coherence_band_data[j].spread_coherence[0] / ( 255.0f / (float) idx_ER ) ); idx_sp_coh[j] = extract_l( Mpy_32_32_r( imult1616( q_direction->coherence_band_data[j].spread_coherence[0], idx_ER ), 8421505 /* 1/255.f in Q31 */ ) ); move16(); - // q_direction->coherence_band_data[j].spread_coherence[0] = (uint8_t) roundf( idx_sp_coh[j] * ( 255.0f / (float) idx_ER ) ); + // q_direction->coherence_band_data[j].spread_coherence[0] = (UWord8) roundf( idx_sp_coh[j] * ( 255.0f / (float) idx_ER ) ); IF( idx_sp_coh[j] ) { q_direction->coherence_band_data[j].spread_coherence[0] = (UWord8) idiv1616( imult1616( idx_sp_coh[j], 255 ), idx_ER ); @@ -4966,19 +4974,19 @@ static Word16 encode_spread_coherence_1sf_fx( /* write max value*/ bits_GR = hMasaMetaData->nb_bits_tot; move16(); - ivas_qmetadata_encode_extended_gr( hMasaMetaData, add( sub( sub( MASA_MAX_NO_CV_SUR_COH, max_val ), 1 ), extra_cv ), add( MASA_MAX_NO_CV_SUR_COH, extra_cv ), 0 ); + ivas_qmetadata_encode_extended_gr_fx( hMasaMetaData, add( sub( sub( MASA_MAX_NO_CV_SUR_COH, max_val ), 1 ), extra_cv ), add( MASA_MAX_NO_CV_SUR_COH, extra_cv ), 0 ); nbits = add( nbits, sub( hMasaMetaData->nb_bits_tot, bits_GR ) ); } IF( nbits_fr1 > 0 ) { half_coding_subbands = shr( coding_subbands, 1 ); - idx = create_combined_index( idx_sp_coh, half_coding_subbands, no_cv ); - idx1 = create_combined_index( &idx_sp_coh[half_coding_subbands], half_coding_subbands, &no_cv[half_coding_subbands] ); + idx = create_combined_index_fx( idx_sp_coh, half_coding_subbands, no_cv ); + idx1 = create_combined_index_fx( &idx_sp_coh[half_coding_subbands], half_coding_subbands, &no_cv[half_coding_subbands] ); } ELSE { - idx = create_combined_index( idx_sp_coh, coding_subbands, no_cv ); + idx = create_combined_index_fx( idx_sp_coh, coding_subbands, no_cv ); } // if ( nbits_fr % 16 == 0 ) @@ -4988,7 +4996,7 @@ static Word16 encode_spread_coherence_1sf_fx( } ELSE { - // no_idx16 = (int16_t) round_f( ( nbits_fr / 16.0f + 0.5f ) ); + // no_idx16 = (Word16) round_f( ( nbits_fr / 16.0f + 0.5f ) ); no_idx16 = shr_r( add( nbits_fr, ONE_IN_Q3 ), 4 ); } @@ -5012,7 +5020,7 @@ static Word16 encode_spread_coherence_1sf_fx( } ELSE { - // no_idx16 = (int16_t) round_f( ( nbits_fr1 / 16.0f + 0.5f ) ); + // no_idx16 = (Word16) round_f( ( nbits_fr1 / 16.0f + 0.5f ) ); no_idx16 = shr_r( add( nbits_fr1, ONE_IN_Q3 ), 4 ); } @@ -5044,7 +5052,7 @@ static Word16 encode_spread_coherence_1sf_fx( /* write the min */ bits_GR = hMasaMetaData->nb_bits_tot; move16(); - ivas_qmetadata_encode_extended_gr( hMasaMetaData, min_idx, add( MASA_MAX_NO_CV_SUR_COH, extra_cv ), 0 ); + ivas_qmetadata_encode_extended_gr_fx( hMasaMetaData, min_idx, add( MASA_MAX_NO_CV_SUR_COH, extra_cv ), 0 ); nbits = add( nbits, sub( hMasaMetaData->nb_bits_tot, bits_GR ) ); /* write GR data */ @@ -5052,7 +5060,7 @@ static Word16 encode_spread_coherence_1sf_fx( { bits_GR = hMasaMetaData->nb_bits_tot; move16(); - ivas_qmetadata_encode_extended_gr( hMasaMetaData, mr_idx_sp_coh[j], no_cv_shift[j], GR_ord ); + ivas_qmetadata_encode_extended_gr_fx( hMasaMetaData, mr_idx_sp_coh[j], no_cv_shift[j], GR_ord ); nbits = add( nbits, sub( hMasaMetaData->nb_bits_tot, bits_GR ) ); } } @@ -5118,11 +5126,11 @@ static Word16 encode_surround_coherence_fx( { k = add( k, hQMetaData->twoDirBands[j] ); idx16 = s_max( sub( k, 1 ), 0 ); - error_ratio_surr = W_sat_l( W_sub( W_sub( ONE_IN_Q30, q_direction[0].band_data[j].energy_ratio_fx[0] ), W_mult0_32_32( q_direction[1].band_data[idx16].energy_ratio_fx[0], hQMetaData->twoDirBands[j] ) ) ); + error_ratio_surr = W_sat_l( W_sub( W_sub( ONE_IN_Q30, q_direction[0].band_data[j].energy_ratio_fx[0] ), W_mult0_32_32( q_direction[1].band_data[idx16].energy_ratio_fx[0], hQMetaData->twoDirBands[j] ) ) ); // Q30 } ELSE { - error_ratio_surr = L_sub( ONE_IN_Q30, q_direction[0].band_data[j].energy_ratio_fx[0] ); + error_ratio_surr = L_sub( ONE_IN_Q30, q_direction[0].band_data[j].energy_ratio_fx[0] ); // Q30 } IF( error_ratio_surr <= 0 ) @@ -5193,18 +5201,18 @@ static Word16 encode_surround_coherence_fx( /* write max value*/ bits_GR = hMetaData->nb_bits_tot; move16(); - ivas_qmetadata_encode_extended_gr( hMetaData, sub( MASA_MAX_NO_CV_SUR_COH - 1, max_val ), MASA_MAX_NO_CV_SUR_COH, 0 ); + ivas_qmetadata_encode_extended_gr_fx( hMetaData, sub( MASA_MAX_NO_CV_SUR_COH - 1, max_val ), MASA_MAX_NO_CV_SUR_COH, 0 ); nbits = add( nbits, sub( hMetaData->nb_bits_tot, bits_GR ) ); } IF( nbits_fr1 > 0 ) { - idx = create_combined_index( idx_sur_coh, half_coding_subbands, no_cv ); - idx1 = create_combined_index( &idx_sur_coh[half_coding_subbands], half_coding_subbands, &no_cv[half_coding_subbands] ); + idx = create_combined_index_fx( idx_sur_coh, half_coding_subbands, no_cv ); + idx1 = create_combined_index_fx( &idx_sur_coh[half_coding_subbands], half_coding_subbands, &no_cv[half_coding_subbands] ); } ELSE { - idx = create_combined_index( idx_sur_coh, coding_subbands, no_cv ); + idx = create_combined_index_fx( idx_sur_coh, coding_subbands, no_cv ); } // if ( nbits_fr % 16 == 0 ) @@ -5214,7 +5222,7 @@ static Word16 encode_surround_coherence_fx( } ELSE { - // no_idx16 = (int16_t) round_f( ( nbits_fr / 16.0f + 0.5f ) ); + // no_idx16 = (Word16) round_f( ( nbits_fr / 16.0f + 0.5f ) ); no_idx16 = shr_r( add( nbits_fr, ONE_IN_Q3 ), 4 ); } @@ -5238,7 +5246,7 @@ static Word16 encode_surround_coherence_fx( } ELSE { - // no_idx16 = (int16_t) round_f( ( nbits_fr1 / 16.0f + 0.5f ) ); + // no_idx16 = (Word16) round_f( ( nbits_fr1 / 16.0f + 0.5f ) ); no_idx16 = shr_r( add( nbits_fr1, ONE_IN_Q3 ), 4 ); } @@ -5271,7 +5279,7 @@ static Word16 encode_surround_coherence_fx( /* write the min */ bits_GR = hMetaData->nb_bits_tot; move16(); - ivas_qmetadata_encode_extended_gr( hMetaData, min_idx, MASA_MAX_NO_CV_SUR_COH, 0 ); + ivas_qmetadata_encode_extended_gr_fx( hMetaData, min_idx, MASA_MAX_NO_CV_SUR_COH, 0 ); nbits = add( nbits, sub( hMetaData->nb_bits_tot, bits_GR ) ); /* write GR data */ @@ -5280,7 +5288,7 @@ static Word16 encode_surround_coherence_fx( bits_GR = hMetaData->nb_bits_tot; move16(); - ivas_qmetadata_encode_extended_gr( hMetaData, mr_idx_sur_coh[j], no_cv_shift[j], GR_ord ); + ivas_qmetadata_encode_extended_gr_fx( hMetaData, mr_idx_sur_coh[j], no_cv_shift[j], GR_ord ); nbits = add( nbits, sub( hMetaData->nb_bits_tot, bits_GR ) ); } @@ -5303,7 +5311,7 @@ static Word16 encode_surround_coherence_hr_fx( UWord64 idx, idx1; Word16 no_idx16; Word16 no_cv[MASA_MAXIMUM_CODING_SUBBANDS]; - Word32 error_ratio_surr; + Word32 error_ratio_surr; // Q30 IVAS_QDIRECTION *q_direction; Word16 half_coding_subbands, nbits_fr1, coding_subbands; Word16 all_coherence_zero; @@ -5343,15 +5351,15 @@ static Word16 encode_surround_coherence_hr_fx( { k = add( k, hQMetaData->twoDirBands[j] ); idx16 = s_max( sub( k, 1 ), 0 ); - error_ratio_surr = L_sub( ONE_IN_Q30, q_direction[0].band_data[j].energy_ratio_fx[sf] ); + error_ratio_surr = L_sub( ONE_IN_Q30, q_direction[0].band_data[j].energy_ratio_fx[sf] ); // Q30 IF( hQMetaData->twoDirBands[j] ) { - error_ratio_surr = L_sub( error_ratio_surr, q_direction[1].band_data[idx16].energy_ratio_fx[sf] ); + error_ratio_surr = L_sub( error_ratio_surr, q_direction[1].band_data[idx16].energy_ratio_fx[sf] ); // Q30 } } ELSE { - error_ratio_surr = L_sub( ONE_IN_Q30, q_direction[0].band_data[j].energy_ratio_fx[sf] ); + error_ratio_surr = L_sub( ONE_IN_Q30, q_direction[0].band_data[j].energy_ratio_fx[sf] ); // Q30 } /* if ( error_ratio_surr <= 0 ) Restricting precision to 7 decimal places */ @@ -5424,18 +5432,18 @@ static Word16 encode_surround_coherence_hr_fx( /* write max value*/ bits_GR = hMetaData->nb_bits_tot; move16(); - ivas_qmetadata_encode_extended_gr( hMetaData, sub( MASA_MAX_NO_CV_SUR_COH - 1, max_val ), MASA_MAX_NO_CV_SUR_COH, 0 ); + ivas_qmetadata_encode_extended_gr_fx( hMetaData, sub( MASA_MAX_NO_CV_SUR_COH - 1, max_val ), MASA_MAX_NO_CV_SUR_COH, 0 ); nbits = add( nbits, sub( hMetaData->nb_bits_tot, bits_GR ) ); } IF( nbits_fr1 > 0 ) { - idx = create_combined_index( idx_sur_coh, half_coding_subbands, no_cv ); - idx1 = create_combined_index( &idx_sur_coh[half_coding_subbands], half_coding_subbands, &no_cv[half_coding_subbands] ); + idx = create_combined_index_fx( idx_sur_coh, half_coding_subbands, no_cv ); + idx1 = create_combined_index_fx( &idx_sur_coh[half_coding_subbands], half_coding_subbands, &no_cv[half_coding_subbands] ); } ELSE { - idx = create_combined_index( idx_sur_coh, coding_subbands, no_cv ); + idx = create_combined_index_fx( idx_sur_coh, coding_subbands, no_cv ); } IF( nbits_fr % 16 == 0 ) @@ -5444,7 +5452,11 @@ static Word16 encode_surround_coherence_hr_fx( } ELSE { +#ifdef FIX_USAN_ISSUES + no_idx16 = add( shr( nbits_fr, 4 ), 1 ); +#else no_idx16 = shr_r( nbits_fr, 4 ); +#endif } /* write combined index */ @@ -5466,7 +5478,11 @@ static Word16 encode_surround_coherence_hr_fx( } ELSE { +#ifdef FIX_USAN_ISSUES + no_idx16 = add( shr( nbits_fr1, 4 ), 1 ); +#else no_idx16 = shr_r( nbits_fr1, 4 ); +#endif } assert( no_idx16 <= 4 ); @@ -5497,7 +5513,7 @@ static Word16 encode_surround_coherence_hr_fx( /* write the min */ bits_GR = hMetaData->nb_bits_tot; move16(); - ivas_qmetadata_encode_extended_gr( hMetaData, min_idx, MASA_MAX_NO_CV_SUR_COH, 0 ); + ivas_qmetadata_encode_extended_gr_fx( hMetaData, min_idx, MASA_MAX_NO_CV_SUR_COH, 0 ); nbits = add( nbits, sub( hMetaData->nb_bits_tot, bits_GR ) ); /* write GR data */ @@ -5506,7 +5522,7 @@ static Word16 encode_surround_coherence_hr_fx( bits_GR = hMetaData->nb_bits_tot; move16(); - ivas_qmetadata_encode_extended_gr( hMetaData, mr_idx_sur_coh[j], no_cv_shift[j], GR_ord ); + ivas_qmetadata_encode_extended_gr_fx( hMetaData, mr_idx_sur_coh[j], no_cv_shift[j], GR_ord ); nbits = add( nbits, sub( hMetaData->nb_bits_tot, bits_GR ) ); } @@ -5527,10 +5543,10 @@ static Word16 encode_surround_coherence_hr_fx( /*! r: quantized value */ static Word32 quantize_DCT_0_coh_fx( // o:Q21 const Word16 x, /* i : input value Q14 */ - const int16_t j, /* i : subband index */ + const Word16 j, /* i : subband index */ const Word16 *coherence_cb, /* i : coherence codebook Q14 */ const Word16 delta_var, /* i : azimuth variance threshold Q6 */ - const int16_t no_cb, /* i : maximum number of codewords */ + const Word16 no_cb, /* i : maximum number of codewords */ IVAS_QDIRECTION *q_direction, /* i : quantized metadata */ UWord16 *idx_x, /* o : codewords index */ Word16 *p_no_cb, /* o : actual number of codewords dependent on energy ratio value */ @@ -5596,11 +5612,11 @@ static Word16 encode_coherence_indexesDCT1_fx( nbits = 0; move16(); - nbits = mean_removed_GR_new( idx_dct, MASA_NO_CV_COH1, len, 0, &GR_ord, &av, mr_idx_dct ); + nbits = mean_removed_GR_new_fx( idx_dct, MASA_NO_CV_COH1, len, 0, &GR_ord, &av, mr_idx_dct ); FOR( i = 0; i < len; i++ ) { - ivas_qmetadata_encode_extended_gr( hMetaData, mr_idx_dct[i], 2 * MASA_NO_CV_COH1, GR_ord ); + ivas_qmetadata_encode_extended_gr_fx( hMetaData, mr_idx_dct[i], 2 * MASA_NO_CV_COH1, GR_ord ); } nbits = add( nbits, len_huf_masa[av] ); @@ -5616,7 +5632,7 @@ static Word16 encode_coherence_indexesDCT1_fx( * 4D implementation of DCT transform *-------------------------------------------------------------------*/ static void dct4_transform_fx( - uint8_t *v, /* i : input 4D vector */ + UWord8 *v, /* i : input 4D vector */ Word32 *dct_v /* o : output transformed vector Q21 */ ) { @@ -5629,11 +5645,11 @@ static void dct4_transform_fx( dct_v[0] = L_add( a, b ); // 0.5f * (a + b); move32(); - dct_v[1] = L_add( Mpy_32_32_r( 1402911301 /*0.653281482438188f*/, c ), Mpy_32_32_r( 581104888 /*0.270598050073099f*/, d ) ); + dct_v[1] = L_add( Mpy_32_32_r( 1402911301 /*0.653281482438188f.Q31*/, c ), Mpy_32_32_r( 581104888 /*0.270598050073099f.Q31*/, d ) ); move32(); dct_v[2] = L_sub( a, b ); // 0.5f * (a - b); move32(); - dct_v[3] = L_sub( Mpy_32_32_r( 581104888 /*0.270598050073099f*/, c ), Mpy_32_32_r( 1402911301 /*0.653281482438188f*/, d ) ); + dct_v[3] = L_sub( Mpy_32_32_r( 581104888 /*0.270598050073099f.Q31*/, c ), Mpy_32_32_r( 1402911301 /*0.653281482438188f.Q31*/, d ) ); move32(); return; @@ -5679,7 +5695,7 @@ static Word16 ivas_qmetadata_quantize_coherence_hr_512_fx( cbsize = shl( 1, bits_coh ); // delta = 256.0f / cbsize; - delta = div_l( 256, shr( cbsize, 1 ) ); + delta = div_l( 256, shr( cbsize, 1 ) ); // Q15 FOR( k = 0; k < nblocks; k++ ) { @@ -5689,7 +5705,7 @@ static Word16 ivas_qmetadata_quantize_coherence_hr_512_fx( { idx_coh[j] = usquant_fx( (Word16) ( q_direction->coherence_band_data[j].spread_coherence[k] ), &tmp, shr( delta, 1 ), shr( delta, 1 ) /* Q-1 */, cbsize ); move16(); - q_direction->coherence_band_data[j].spread_coherence[k] = (UWord8) add( imult1616( idx_coh[j], delta ), shr( delta, 1 ) ); + q_direction->coherence_band_data[j].spread_coherence[k] = (UWord8) add( imult1616( idx_coh[j], delta ), shr( delta, 1 ) /*delta/2*/ ); // Q15 if ( LT_16( idx_coh[j], min_idx ) ) { min_idx = idx_coh[j]; @@ -5706,8 +5722,8 @@ static Word16 ivas_qmetadata_quantize_coherence_hr_512_fx( { idx_coh[j] = sub( idx_coh[j], min_idx ); move16(); - nbits0 = add( nbits0, ivas_qmetadata_encode_extended_gr_length( idx_coh[j], sub( cbsize, min_idx ), 0 ) ); - nbits1 = add( nbits1, ivas_qmetadata_encode_extended_gr_length( idx_coh[j], sub( cbsize, min_idx ), 1 ) ); + nbits0 = add( nbits0, ivas_qmetadata_encode_extended_gr_length_fx( idx_coh[j], sub( cbsize, min_idx ), 0 ) ); + nbits1 = add( nbits1, ivas_qmetadata_encode_extended_gr_length_fx( idx_coh[j], sub( cbsize, min_idx ), 1 ) ); } IF( nbits0 < nbits1 ) { @@ -5724,7 +5740,7 @@ static Word16 ivas_qmetadata_quantize_coherence_hr_512_fx( GR_param_av = 1; move16(); - nbits_av = mean_removed_GR_new( idx_coh, cbsize, nbands, 1, &GR_param_av, &av, mr_idx ); + nbits_av = mean_removed_GR_new_fx( idx_coh, cbsize, nbands, 1, &GR_param_av, &av, mr_idx ); IF( LT_16( nbits_av, nbits1 ) ) { @@ -5744,7 +5760,7 @@ static Word16 ivas_qmetadata_quantize_coherence_hr_512_fx( FOR( j = 0; j < nbands; j++ ) { - ivas_qmetadata_encode_extended_gr( hMetaData, mr_idx[j], imult1616( 2, cbsize ), GR_param ); + ivas_qmetadata_encode_extended_gr_fx( hMetaData, mr_idx[j], imult1616( 2, cbsize ), GR_param ); } } ELSE @@ -5760,7 +5776,7 @@ static Word16 ivas_qmetadata_quantize_coherence_hr_512_fx( FOR( j = 0; j < nbands; j++ ) { - ivas_qmetadata_encode_extended_gr( hMetaData, idx_coh[j], sub( cbsize, min_idx ), GR_param ); + ivas_qmetadata_encode_extended_gr_fx( hMetaData, idx_coh[j], sub( cbsize, min_idx ), GR_param ); } } } @@ -5893,7 +5909,7 @@ static Word16 ivas_qmetadata_quantize_coherence_fx( IF( write_flag ) { /* quantize first DCT parameter */ - dct_coh[j][0] = quantize_DCT_0_coh_fx( extract_l( L_shr_r( dct_coh[j][0], 7 ) ), j, coherence_cb0_masa_Q14, MASA_DELTA_AZI_DCT0 << Q6, MASA_NO_CV_COH, q_direction, &idx_dct[k], &no_cb_vec[j], hrmasa_flag ); + dct_coh[j][0] = quantize_DCT_0_coh_fx( extract_l( L_shr_r( dct_coh[j][0], 7 ) ), j, coherence_cb0_masa_Q14, MASA_DELTA_AZI_DCT0 << Q6, MASA_NO_CV_COH, q_direction, &idx_dct[k], &no_cb_vec[j], hrmasa_flag ); // Q21 move32(); } @@ -5930,7 +5946,7 @@ static Word16 ivas_qmetadata_quantize_coherence_fx( no_cb = no_cb * no_cb_vec[j]; } - // nbits = (int16_t) ceilf( logf( (float) no_cb ) * INV_LOG_2 ); + // nbits = (Word16) ceilf( logf( (float) no_cb ) * INV_LOG_2 ); IF( LE_64( no_cb, 1 ) ) { nbits = 0; @@ -5947,7 +5963,7 @@ static Word16 ivas_qmetadata_quantize_coherence_fx( { no_cb = no_cb * no_cb_vec[j]; } - // nbits1 = (int16_t) ceilf( logf( (float) no_cb ) * INV_LOG_2 ); + // nbits1 = (Word16) ceilf( logf( (float) no_cb ) * INV_LOG_2 ); IF( LE_64( no_cb, 1 ) ) { nbits1 = 0; @@ -5968,7 +5984,7 @@ static Word16 ivas_qmetadata_quantize_coherence_fx( no_cb = no_cb * no_cb_vec[j]; } - // nbits = (int16_t) ceilf( logf( (float) no_cb ) * INV_LOG_2 ); + // nbits = (Word16) ceilf( logf( (float) no_cb ) * INV_LOG_2 ); IF( LE_64( no_cb, 1 ) ) { nbits = 0; @@ -6064,7 +6080,7 @@ static void ivas_qmetadata_reorder_2dir_bands_fx( hQMetaData->q_direction[1].band_data[band].spherical_index[sf] = uint16_tmp; move16(); - fx_tmp = hQMetaData->q_direction[0].band_data[band].azimuth_fx[sf]; + fx_tmp = hQMetaData->q_direction[0].band_data[band].azimuth_fx[sf]; // Q22 move32(); hQMetaData->q_direction[0].band_data[band].azimuth_fx[sf] = hQMetaData->q_direction[1].band_data[band].azimuth_fx[sf]; move32(); @@ -6073,7 +6089,7 @@ static void ivas_qmetadata_reorder_2dir_bands_fx( fx_tmp = hQMetaData->q_direction[0].band_data[band].elevation_fx[sf]; move32(); - hQMetaData->q_direction[0].band_data[band].elevation_fx[sf] = hQMetaData->q_direction[1].band_data[band].elevation_fx[sf]; + hQMetaData->q_direction[0].band_data[band].elevation_fx[sf] = hQMetaData->q_direction[1].band_data[band].elevation_fx[sf]; // Q22 move32(); hQMetaData->q_direction[1].band_data[band].elevation_fx[sf] = fx_tmp; move32(); @@ -6099,7 +6115,7 @@ static void ivas_qmetadata_reorder_2dir_bands_fx( { fx_tmp = hQMetaData->q_direction[0].band_data[band].energy_ratio_fx[0]; move32(); - hQMetaData->q_direction[0].band_data[band].energy_ratio_fx[0] = hQMetaData->q_direction[1].band_data[band].energy_ratio_fx[0]; + hQMetaData->q_direction[0].band_data[band].energy_ratio_fx[0] = hQMetaData->q_direction[1].band_data[band].energy_ratio_fx[0]; // Q30 move32(); hQMetaData->q_direction[1].band_data[band].energy_ratio_fx[0] = fx_tmp; move32(); @@ -6153,7 +6169,7 @@ static Word16 write_2dir_info( move16(); FOR( i = 0; i < k; i++ ) { - ivas_qmetadata_encode_extended_gr( hMetaData, dif_p[i], 24, 0 ); + ivas_qmetadata_encode_extended_gr_fx( hMetaData, dif_p[i], 24, 0 ); } nbits = sub( hMetaData->nb_bits_tot, j ); @@ -6179,7 +6195,7 @@ static void transform_azimuth_dir2_fx( FOR( b = 0; b < hQMetaData->q_direction[1].cfg.nblocks; b++ ) { Word64 azimuth; - azimuth = W_add( W_deposit32_l( L_sub( hQMetaData->q_direction[1].band_data[i].azimuth_fx[b], hQMetaData->q_direction[0].band_data[dir2_bands[i]].azimuth_fx[b] ) ), DEGREE_180_Q_22 ); + azimuth = W_add( W_deposit32_l( L_sub( hQMetaData->q_direction[1].band_data[i].azimuth_fx[b], hQMetaData->q_direction[0].band_data[dir2_bands[i]].azimuth_fx[b] ) ), DEGREE_180_Q_22 ); // Q22 IF( GE_64( azimuth, DEGREE_180_Q_22 ) ) { @@ -6227,11 +6243,11 @@ static Word16 divide_GR_orders_fx( FOR( j = 0; j <= i; j++ ) { - nb_GR = add( nb_GR, ivas_qmetadata_encode_extended_gr_length( q_idx[j], 100, GR1 ) ); + nb_GR = add( nb_GR, ivas_qmetadata_encode_extended_gr_length_fx( q_idx[j], 100, GR1 ) ); } FOR( j = i + 1; j < len; j++ ) { - nb_GR = add( nb_GR, ivas_qmetadata_encode_extended_gr_length( q_idx[j], 100, GR2 ) ); + nb_GR = add( nb_GR, ivas_qmetadata_encode_extended_gr_length_fx( q_idx[j], 100, GR2 ) ); } IF( LT_16( nb_GR, nb_GR_min ) ) @@ -6261,8 +6277,8 @@ static Word16 find_optimal_GR_order_fx( move16(); FOR( i = 0; i < len; i++ ) { - nb_GR_0 = add( nb_GR_0, ivas_qmetadata_encode_extended_gr_length( q_idx[i], 100, 0 ) ); - nb_GR_1 = add( nb_GR_1, ivas_qmetadata_encode_extended_gr_length( q_idx[i], 100, 1 ) ); + nb_GR_0 = add( nb_GR_0, ivas_qmetadata_encode_extended_gr_length_fx( q_idx[i], 100, 0 ) ); + nb_GR_1 = add( nb_GR_1, ivas_qmetadata_encode_extended_gr_length_fx( q_idx[i], 100, 1 ) ); } IF( LT_16( nb_GR_0, nb_GR_1 ) ) @@ -6410,7 +6426,7 @@ static Word16 write_stream_dct_coeffs_omasa_fx( update_needed = 0; move16(); move16(); - WHILE( GE_16( len_stream, 8 ) && GT_16( nb_GR_min, max_bits ) && GE_16( changed, 1 ) ) + WHILE( ( len_stream >= 8 ) && ( nb_GR_min > max_bits ) && ( changed >= 1 ) ) { test(); test(); @@ -6427,19 +6443,19 @@ static Word16 write_stream_dct_coeffs_omasa_fx( { changed = 1; move16(); - nb_GR_min = sub( nb_GR_min, ivas_qmetadata_encode_extended_gr_length( q_idx[j], 100, GR2 ) ); + nb_GR_min = sub( nb_GR_min, ivas_qmetadata_encode_extended_gr_length_fx( q_idx[j], 100, GR2 ) ); q_idx[j] = sub( q_idx[j], 2 ); move16(); - nb_GR_min = add( nb_GR_min, ivas_qmetadata_encode_extended_gr_length( q_idx[j], 100, GR2 ) ); + nb_GR_min = add( nb_GR_min, ivas_qmetadata_encode_extended_gr_length_fx( q_idx[j], 100, GR2 ) ); } ELSE { changed = 1; move16(); - nb_GR_min = sub( nb_GR_min, ivas_qmetadata_encode_extended_gr_length( q_idx[j], 100, GR1 ) ); + nb_GR_min = sub( nb_GR_min, ivas_qmetadata_encode_extended_gr_length_fx( q_idx[j], 100, GR1 ) ); q_idx[j] = sub( q_idx[j], 2 ); move16(); - nb_GR_min = add( nb_GR_min, ivas_qmetadata_encode_extended_gr_length( q_idx[j], 100, 0 ) ); + nb_GR_min = add( nb_GR_min, ivas_qmetadata_encode_extended_gr_length_fx( q_idx[j], 100, 0 ) ); } } ELSE IF( EQ_16( q_idx[j], 1 ) ) @@ -6448,20 +6464,20 @@ static Word16 write_stream_dct_coeffs_omasa_fx( { changed = 1; move16(); - nb_GR_min = sub( nb_GR_min, ivas_qmetadata_encode_extended_gr_length( q_idx[j], 100, GR2 ) ); + nb_GR_min = sub( nb_GR_min, ivas_qmetadata_encode_extended_gr_length_fx( q_idx[j], 100, GR2 ) ); q_idx[j] = sub( q_idx[j], 1 ); move16(); - nb_GR_min = add( nb_GR_min, ivas_qmetadata_encode_extended_gr_length( q_idx[j], 100, GR2 ) ); + nb_GR_min = add( nb_GR_min, ivas_qmetadata_encode_extended_gr_length_fx( q_idx[j], 100, GR2 ) ); } ELSE { changed = 1; move16(); - nb_GR_min = sub( nb_GR_min, ivas_qmetadata_encode_extended_gr_length( q_idx[j], 100, GR1 ) ); + nb_GR_min = sub( nb_GR_min, ivas_qmetadata_encode_extended_gr_length_fx( q_idx[j], 100, GR1 ) ); q_idx[j] = sub( q_idx[j], 1 ); move16(); - nb_GR_min = add( nb_GR_min, ivas_qmetadata_encode_extended_gr_length( q_idx[j], 100, 0 ) ); + nb_GR_min = add( nb_GR_min, ivas_qmetadata_encode_extended_gr_length_fx( q_idx[j], 100, 0 ) ); } } IF( LT_16( nb_GR_min, max_bits ) ) @@ -6495,12 +6511,12 @@ static Word16 write_stream_dct_coeffs_omasa_fx( /* write GR data */ FOR( i = 1; i <= i_min; i++ ) { - ivas_qmetadata_encode_extended_gr( hMetaData, q_idx[i], 100, GR1 ); + ivas_qmetadata_encode_extended_gr_fx( hMetaData, q_idx[i], 100, GR1 ); } FOR( i = i_min + 1; i < len_stream; i++ ) { - ivas_qmetadata_encode_extended_gr( hMetaData, q_idx[i], 100, GR2 ); + ivas_qmetadata_encode_extended_gr_fx( hMetaData, q_idx[i], 100, GR2 ); } } ELSE @@ -6511,7 +6527,7 @@ static Word16 write_stream_dct_coeffs_omasa_fx( nb_bits = add( nb_bits, 1 ); FOR( i = 1; i < len_stream; i++ ) { - ivas_qmetadata_encode_extended_gr( hMetaData, q_idx[i], 100, GR1 ); + ivas_qmetadata_encode_extended_gr_fx( hMetaData, q_idx[i], 100, GR1 ); } } @@ -6542,7 +6558,6 @@ void ivas_omasa_encode_masa_to_total_fx( Word16 q_idx[MAX_PARAM_SPATIAL_SUBFRAMES * MASA_FREQUENCY_BANDS]; Word32 dct_data_tmp[MAX_PARAM_SPATIAL_SUBFRAMES * MASA_FREQUENCY_BANDS]; Word32 dct_data[MAX_PARAM_SPATIAL_SUBFRAMES * MASA_FREQUENCY_BANDS]; - Word16 dct_data_e = 0, dct_data_tmp_e, q_dct_data_e; Word16 bits_pos, nb_bits; Word16 n_streams, len_stream, tmp_e; Word32 L_tmp; @@ -6558,7 +6573,7 @@ void ivas_omasa_encode_masa_to_total_fx( { FOR( j = 0; j < nblocks; j++ ) { - data[k] = masa_to_total_energy_ratio[j][i]; + data[k] = L_shr( masa_to_total_energy_ratio[j][i], Q5 ); move32(); k = add( k, 1 ); } @@ -6571,42 +6586,42 @@ void ivas_omasa_encode_masa_to_total_fx( SWITCH( len_stream ) { case 4: - matrix_product_mant_exp_fx( dct4_fx, 0 /* Q31 */, nblocks, nblocks, 0, data, 1 /* Q30*/, 1, nblocks, 1, dct_data, &dct_data_e ); + matrix_product_fx( dct4_fx, nblocks, nblocks, 0, data, 1, nblocks, 1, dct_data ); n_streams = 1; len_stream = 4; move16(); BREAK; case 5: - matrix_product_mant_exp_fx( dct5_fx, 0 /* Q31 */, nbands, nbands, 0, data, 1 /* Q30 */, 1, nbands, 1, dct_data, &dct_data_e ); + matrix_product_fx( dct5_fx, nbands, nbands, 0, data, 1, nbands, 1, dct_data ); n_streams = 1; len_stream = nbands; move16(); move16(); BREAK; case 8: - matrix_product_mant_exp_fx( dct8_fx, 0 /* Q31 */, nbands, nbands, 0, data, 1 /* Q30 */, 1, nbands, 1, dct_data, &dct_data_e ); + matrix_product_fx( dct8_fx, nbands, nbands, 0, data, 1, nbands, 1, dct_data ); n_streams = 1; len_stream = nbands; move16(); BREAK; case 12: - matrix_product_mant_exp_fx( dct12_fx, 0 /* Q31 */, nbands, nbands, 0, data, 1 /* Q30 */, 1, nbands, 1, dct_data, &dct_data_e ); + matrix_product_fx( dct12_fx, nbands, nbands, 0, data, 1, nbands, 1, dct_data ); n_streams = 1; len_stream = nbands; move16(); move16(); BREAK; case 20: - matrix_product_mant_exp_fx( dct5_fx, 0 /* Q31 */, nbands, nbands, 0, data, 1 /* Q30 */, nblocks, nbands, 1, dct_data_tmp, &dct_data_e ); - matrix_product_mant_exp_fx( dct_data_tmp, dct_data_e, nbands, nblocks, 0, dct4_fx, 0 /* Q31 */, nblocks, nblocks, 1, dct_data, &dct_data_e ); + matrix_product_fx( dct5_fx, nbands, nbands, 0, data, nblocks, nbands, 1, dct_data_tmp ); + matrix_product_fx( dct_data_tmp, nbands, nblocks, 0, dct4_fx, nblocks, nblocks, 1, dct_data ); n_streams = 1; len_stream = imult1616( nbands, nblocks ); move16(); move16(); BREAK; case 32: - matrix_product_mant_exp_fx( dct8_fx, 0 /* Q31 */, nbands, nbands, 0, data, 1 /* Q30 */, nblocks, nbands, 1, dct_data_tmp, &dct_data_e ); - matrix_product_mant_exp_fx( dct_data_tmp, dct_data_e, nbands, nblocks, 0, dct4_fx, 0 /* Q31 */, nblocks, nblocks, 1, dct_data, &dct_data_e ); + matrix_product_fx( dct8_fx, nbands, nbands, 0, data, nblocks, nbands, 1, dct_data_tmp ); + matrix_product_fx( dct_data_tmp, nbands, nblocks, 0, dct4_fx, nblocks, nblocks, 1, dct_data ); n_streams = nblocks; len_stream = nbands; move16(); @@ -6622,7 +6637,7 @@ void ivas_omasa_encode_masa_to_total_fx( j = imult1616( k, len_stream ); /* quantize with fixed common step */ L_tmp = BASOP_Util_Divide3232_Scale_cadence( dct_data[j], step, &tmp_e ); - tmp_e = add( tmp_e, dct_data_e ); + tmp_e = add( tmp_e, Q6 ); q_idx[j] = rint_new_fx( L_shr( L_tmp, sub( 15, tmp_e ) ) /* Q16 */ ); // Q0 move16(); @@ -6645,7 +6660,7 @@ void ivas_omasa_encode_masa_to_total_fx( FOR( i = 1; i < len_stream; i++ ) { L_tmp = BASOP_Util_Divide3232_Scale_cadence( dct_data[j + i], step, &tmp_e ); - tmp_e = add( tmp_e, dct_data_e ); + tmp_e = add( tmp_e, Q6 ); q_idx[j + i] = rint_new_fx( L_shr( L_tmp, sub( 15, tmp_e ) ) ); move16(); q_dct_data[j + i] = Mpy_32_16_1( step, shl( q_idx[j + i], 9 ) /* Q9 */ ); // Q25 @@ -6689,50 +6704,38 @@ void ivas_omasa_encode_masa_to_total_fx( } } - q_dct_data_e = 6; // Q25 - move16(); /* inverse DCT2 transform */ SWITCH( len_stream ) { case 4: - matrix_product_mant_exp_fx( dct4_fx, 0 /* Q31 */, nblocks, nblocks, 1, q_dct_data, q_dct_data_e, nblocks, 1, 0, dct_data_tmp, &dct_data_tmp_e ); + matrix_product_q30_fx( dct4_fx, nblocks, nblocks, 1, q_dct_data, nblocks, 1, 0, dct_data_tmp ); Copy32( dct_data_tmp, q_dct_data, nblocks ); - q_dct_data_e = dct_data_tmp_e; - move16(); BREAK; case 5: - matrix_product_mant_exp_fx( dct5_fx, 0 /* Q31 */, nbands, nbands, 1, q_dct_data, q_dct_data_e, nbands, 1, 0, dct_data_tmp, &dct_data_tmp_e ); + matrix_product_q30_fx( dct5_fx, nbands, nbands, 1, q_dct_data, nbands, 1, 0, dct_data_tmp ); Copy32( dct_data_tmp, q_dct_data, nbands ); - q_dct_data_e = dct_data_tmp_e; - move16(); BREAK; case 8: - matrix_product_mant_exp_fx( dct8_fx, 0 /* Q31 */, nbands, nbands, 1, q_dct_data, q_dct_data_e, nbands, 1, 0, dct_data_tmp, &dct_data_tmp_e ); + matrix_product_q30_fx( dct8_fx, nbands, nbands, 1, q_dct_data, nbands, 1, 0, dct_data_tmp ); Copy32( dct_data_tmp, q_dct_data, nbands ); - q_dct_data_e = dct_data_tmp_e; - move16(); BREAK; case 12: - matrix_product_mant_exp_fx( dct12_fx, 0 /* Q31 */, nbands, nbands, 1, q_dct_data, q_dct_data_e, nbands, 1, 0, dct_data_tmp, &dct_data_tmp_e ); + matrix_product_q30_fx( dct12_fx, nbands, nbands, 1, q_dct_data, nbands, 1, 0, dct_data_tmp ); Copy32( dct_data_tmp, q_dct_data, nbands ); - q_dct_data_e = dct_data_tmp_e; - move16(); BREAK; case 20: - matrix_product_mant_exp_fx( dct5_fx, 0 /* Q31 */, nbands, nbands, 1, q_dct_data, q_dct_data_e, nbands, nblocks, 0, dct_data_tmp, &dct_data_tmp_e ); - matrix_product_mant_exp_fx( dct_data_tmp, dct_data_tmp_e, nbands, nblocks, 0, dct4_fx, 0 /* Q31 */, nblocks, nblocks, 0, q_dct_data, &q_dct_data_e ); /* reuse of variable*/ + matrix_product_fx( dct5_fx, nbands, nbands, 1, q_dct_data, nbands, nblocks, 0, dct_data_tmp ); + matrix_product_q30_fx( dct_data_tmp, nbands, nblocks, 0, dct4_fx, nblocks, nblocks, 0, q_dct_data ); /* reuse of variable*/ BREAK; case 32: - matrix_product_mant_exp_fx( dct8_fx, 0 /* Q31 */, nbands, nbands, 1, q_dct_data, q_dct_data_e, nbands, nblocks, 0, dct_data_tmp, &dct_data_tmp_e ); - matrix_product_mant_exp_fx( dct_data_tmp, dct_data_tmp_e, nbands, nblocks, 0, dct4_fx, 0 /* Q31 */, nblocks, nblocks, 0, q_dct_data, &q_dct_data_e ); + matrix_product_fx( dct8_fx, nbands, nbands, 1, q_dct_data, nbands, nblocks, 0, dct_data_tmp ); + matrix_product_q30_fx( dct_data_tmp, nbands, nblocks, 0, dct4_fx, nblocks, nblocks, 0, q_dct_data ); BREAK; default: printf( "Incorrect number of coefficients for OMASA.\n" ); BREAK; } - scale_sig32( q_dct_data, MAX_PARAM_SPATIAL_SUBFRAMES * MASA_FREQUENCY_BANDS, sub( Q30, sub( 31, q_dct_data_e ) ) ); // Scaling to Q30 - k = 0; move16(); FOR( i = 0; i < nblocks; i++ ) @@ -6740,7 +6743,7 @@ void ivas_omasa_encode_masa_to_total_fx( FOR( j = 0; j < nbands; j++ ) { masa_to_total_energy_ratio[i][j] = L_max( 0, q_dct_data[k] ); - masa_to_total_energy_ratio[i][j] = L_min( ONE_IN_Q30, masa_to_total_energy_ratio[i][j] ); + masa_to_total_energy_ratio[i][j] = L_min( ONE_IN_Q30, masa_to_total_energy_ratio[i][j] ); // Q30 move32(); move32(); k = add( k, 1 ); diff --git a/lib_enc/ivas_qspherical_enc.c b/lib_enc/ivas_qspherical_enc_fx.c similarity index 99% rename from lib_enc/ivas_qspherical_enc.c rename to lib_enc/ivas_qspherical_enc_fx.c index 4bf3650e60d7be1cd50da97914d95849eef64d1d..2e7a289f9d38d51dbe634700f0ff7dd66ee23b17 100644 --- a/lib_enc/ivas_qspherical_enc.c +++ b/lib_enc/ivas_qspherical_enc_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other @@ -35,11 +35,9 @@ #include "options.h" #include #include "ivas_cnst.h" -#include "ivas_prot.h" #include "ivas_rom_com.h" #include "ivas_stat_enc.h" #include "wmc_auto.h" -#include "prot.h" #include "prot_fx.h" #include "ivas_prot_fx.h" #include "ivas_rom_com_fx.h" diff --git a/lib_enc/ivas_range_uni_enc.c b/lib_enc/ivas_range_uni_enc_fx.c similarity index 93% rename from lib_enc/ivas_range_uni_enc.c rename to lib_enc/ivas_range_uni_enc_fx.c index 5bb5118a102040eff4a9a324e90fc71dcfb6b9f4..6c322a3d953bfa19abc3df4d0196203117d76867 100644 --- a/lib_enc/ivas_range_uni_enc.c +++ b/lib_enc/ivas_range_uni_enc_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other @@ -31,14 +31,14 @@ *******************************************************************************************************/ #include -#include "ivas_prot.h" +#include "ivas_prot_fx.h" #include "ivas_cnst.h" #include "ivas_stat_enc.h" #include "cnst.h" #include "rom_com.h" #include #include "options.h" -#include "prot.h" +#include "prot_fx.h" #include "wmc_auto.h" @@ -55,15 +55,15 @@ * Local function prototypes *-------------------------------------------------------------------*/ -static void rc_uni_enc_shift( RangeUniEncState *rc_st_enc ); +static void rc_uni_enc_shift_fx( RangeUniEncState *rc_st_enc ); /*-------------------------------------------------------------------* - * rc_uni_enc_init() + * rc_uni_enc_init_fx() * * Initalize the range encoder *-------------------------------------------------------------------*/ -void rc_uni_enc_init( +void rc_uni_enc_init_fx( RangeUniEncState *rc_st_enc /* i/o: RC state handle */ ) { @@ -91,7 +91,7 @@ void rc_uni_enc_init( * * Encode given cumulative frequency and frequency when total frequency is a power of 2 *-------------------------------------------------------------------*/ -void rc_uni_enc_encode_fast( +void rc_uni_enc_encode_fast_fx( RangeUniEncState *rc_st_enc, /* i/o: RC state handle */ const UWord16 cum_freq, /* i : Cumulative frequency up to symbol */ const UWord16 sym_freq, /* i : Symbol frequency */ @@ -119,12 +119,12 @@ void rc_uni_enc_encode_fast( { rc_st_enc->rc_range = UL_lshl( rc_st_enc->rc_range, 8 ); move32(); - rc_uni_enc_shift( rc_st_enc ); + rc_uni_enc_shift_fx( rc_st_enc ); IF( LT_64( rc_st_enc->rc_range, 0x01000000 ) ) { rc_st_enc->rc_range = UL_lshl( rc_st_enc->rc_range, 8 ); move32(); - rc_uni_enc_shift( rc_st_enc ); + rc_uni_enc_shift_fx( rc_st_enc ); } } @@ -133,11 +133,11 @@ void rc_uni_enc_encode_fast( /*-------------------------------------------------------------------* - * rc_uni_enc_encode_symbol_fastS() + * rc_uni_enc_encode_symbol_fastS_fx() * * Encode an alphabet symbol when total frequency is a power of 2 *-------------------------------------------------------------------*/ -void rc_uni_enc_encode_symbol_fastS( +void rc_uni_enc_encode_symbol_fastS_fx( RangeUniEncState *rc_st_enc, /* i/o: Encoder state */ const UWord16 symbol, /* i : Symbol to encode */ const UWord16 cum_freq[], /* i : Cumulative frequency up to symbol */ @@ -145,18 +145,18 @@ void rc_uni_enc_encode_symbol_fastS( const UWord16 tot_shift /* i : Total frequency as a power of 2 */ ) { - rc_uni_enc_encode_fast( rc_st_enc, cum_freq[symbol], sym_freq[symbol], tot_shift ); + rc_uni_enc_encode_fast_fx( rc_st_enc, cum_freq[symbol], sym_freq[symbol], tot_shift ); return; } /*-------------------------------------------------------------------* - * rc_uni_enc_finish() + * rc_uni_enc_finish_fx() * * Finalize the range encoder *-------------------------------------------------------------------*/ /*! r: Total number of bits produced */ -Word16 rc_uni_enc_finish( +Word16 rc_uni_enc_finish_fx( RangeUniEncState *rc_st_enc /* i/o: RC state handle */ ) { @@ -186,7 +186,7 @@ Word16 rc_uni_enc_finish( WHILE( bits > 0 ) { - rc_uni_enc_shift( rc_st_enc ); + rc_uni_enc_shift_fx( rc_st_enc ); bits = sub( bits, 8 ); } @@ -245,7 +245,7 @@ Word16 rc_uni_enc_finish( * Get the total number of bits that would be produced by finalization *-------------------------------------------------------------------*/ /*! r: Total number of bits produced */ -Word16 rc_uni_enc_virtual_finish( +Word16 rc_uni_enc_virtual_finish_fx( RangeUniEncState *rc_st_enc /* i : RC state handle */ ) { @@ -278,11 +278,11 @@ Word16 rc_uni_enc_virtual_finish( /*-------------------------------------------------------------------* - * rc_uni_enc_shift() + * rc_uni_enc_shift_fx() * * Shift a byte out to bitstream (internal function) *-------------------------------------------------------------------*/ -static void rc_uni_enc_shift( +static void rc_uni_enc_shift_fx( RangeUniEncState *rc_st_enc /* i/o: RC state handle */ ) { @@ -326,11 +326,11 @@ static void rc_uni_enc_shift( /*-------------------------------------------------------------------* - * rc_uni_enc_encode_bits() + * rc_uni_enc_encode_bits_fx() * * Encode up to 16 bits with uniform probability *-------------------------------------------------------------------*/ -void rc_uni_enc_encode_bits( +void rc_uni_enc_encode_bits_fx( RangeUniEncState *rc_st_enc, /* i/o: RC state handle */ const UWord16 value, /* i : Value to encode */ const Word16 bits /* i : Number of bits */ @@ -355,12 +355,12 @@ void rc_uni_enc_encode_bits( { rc_st_enc->rc_range = UL_lshl( rc_st_enc->rc_range, 8 ); move32(); - rc_uni_enc_shift( rc_st_enc ); + rc_uni_enc_shift_fx( rc_st_enc ); IF( LT_64( rc_st_enc->rc_range, 0x01000000 ) ) { rc_st_enc->rc_range = UL_lshl( rc_st_enc->rc_range, 8 ); move32(); - rc_uni_enc_shift( rc_st_enc ); + rc_uni_enc_shift_fx( rc_st_enc ); } } diff --git a/lib_enc/ivas_rom_enc.h b/lib_enc/ivas_rom_enc.h index e859dc5e69e75bc0cf2f39d98479c15b3f753862..0d0941cc43ce9a1d47dd0bdbe30308779e1d23f8 100644 --- a/lib_enc/ivas_rom_enc.h +++ b/lib_enc/ivas_rom_enc.h @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other @@ -48,16 +48,16 @@ extern const Word32 unclr_mean_td[]; extern const Word32 unclr_scale_td[]; extern const Word32 unclr_coef_td[]; -extern const int16_t xtalk_isel_td[]; +extern const Word16 xtalk_isel_td[]; extern const Word32 xtalk_mean_td[]; extern const Word32 xtalk_scale_td[]; extern const Word32 xtalk_coef_td[]; -extern const int16_t xtalk_isel_dft[]; +extern const Word16 xtalk_isel_dft[]; extern const Word32 xtalk_mean_dft_q15[]; extern const Word32 xtalk_scale_dft_q15[]; extern const Word32 xtalk_coef_dft_q30[]; -extern const int16_t unclr_isel_dft[]; +extern const Word16 unclr_isel_dft[]; extern const Word32 unclr_mean_dft_Q15[]; extern const Word32 unclr_scale_dft_Q15[]; extern const Word32 unclr_coef_dft_Q28[]; @@ -75,9 +75,8 @@ extern const Word32 icbwe_regressionValuesDFT_fx[]; * DFT stereo ROM tables *----------------------------------------------------------------------------------*/ -extern const int16_t itd_vad_band_tbl[]; +extern const Word16 itd_vad_band_tbl[]; extern const Word32 ild_q_Q25[16]; -extern const int16_t ild_q[]; extern const Word32 Wn_table_fx[50]; extern const Word16 win_ana_8k_fx[STEREO_DFT_OVL_8k]; @@ -101,12 +100,12 @@ extern const Word32 ari_bit_estimate_s17_LC_fx[RANGE_N_CONTEXT][RANGE_N_SYMBOLS] /*----------------------------------------------------------------------------------* * ECLVQ Stereo ROM tables *----------------------------------------------------------------------------------*/ -extern const int16_t log2_1px_table[65]; +extern const Word16 log2_1px_table[65]; extern const Word32 log2TB_Q31[ECSQ_log2TB_SIZE]; extern const Word16 ECSQ_log2_fact_Q10[1 + ECSQ_SEGMENT_SIZE]; -extern const uint16_t ECSQ_tab_param[ECSQ_CONFIG_COUNT][1 + ECSQ_PARAM_COUNT]; -extern const uint16_t *const ECSQ_tab_abs_lsbs[1 + 4]; -extern const uint16_t ECSQ_tab_vals[ECSQ_PARAM_COUNT - 1][1 + ECSQ_TAB_VALS_SIZE]; +extern const UWord16 ECSQ_tab_param[ECSQ_CONFIG_COUNT][1 + ECSQ_PARAM_COUNT]; +extern const UWord16 *const ECSQ_tab_abs_lsbs[1 + 4]; +extern const UWord16 ECSQ_tab_vals[ECSQ_PARAM_COUNT - 1][1 + ECSQ_TAB_VALS_SIZE]; /*----------------------------------------------------------------------------------* @@ -123,7 +122,7 @@ extern const Word32 Stereo_dmx_wnd_coef_48k_fx[L_FRAME48k]; extern const HUFF_TABLE huff_alpha_table; extern const HUFF_TABLE huff_beta_table; -extern const int16_t mc_paramupmix_fb_remix_order[4]; +extern const Word16 mc_paramupmix_fb_remix_order[4]; /*----------------------------------------------------------------------------------* * ParamMC ROM tables diff --git a/lib_enc/ivas_rom_enc.c b/lib_enc/ivas_rom_enc_fx.c similarity index 98% rename from lib_enc/ivas_rom_enc.c rename to lib_enc/ivas_rom_enc_fx.c index 2326c5c8c8822d3e95dd114e3c50445dbc0f7201..b26972b8aa56df444edcd9c4cb51e05eaeeba2be 100644 --- a/lib_enc/ivas_rom_enc.c +++ b/lib_enc/ivas_rom_enc_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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,7 +67,7 @@ const Word32 unclr_coef_td[SIZE_UNCLR_ISEL_TD] = /*Q15*/ }; /* UNCLR classifier in DFT stereo: list of selected features */ -const int16_t unclr_isel_dft[SIZE_UNCLR_ISEL_DFT] = +const Word16 unclr_isel_dft[SIZE_UNCLR_ISEL_DFT] = { E_gainILD, E_gainIPD, E_angle_rot, E_g_pred, E_cohSNR, E_d_prodL_prodR, E_sum_xcorr, E_xcorr_itd_value }; @@ -90,7 +90,7 @@ const Word32 unclr_coef_dft_Q28[SIZE_UNCLR_ISEL_DFT] = }; /* xtalk clasifier in TD stereo: list of selected features */ -const int16_t xtalk_isel_td[SIZE_XTALK_ISEL_TD] = +const Word16 xtalk_isel_td[SIZE_XTALK_ISEL_TD] = { E_d_clas, E_d_voicing, E_sum_d_LSF, E_d_lepsP_13, E_d_cor_map_sum, E_d_nchar, E_d_non_sta, E_d_sp_div, E_sum_prod, E_tdm_es_em, E_m_corrL_corrR, E_corrEst0, E_corrEst_ncorr, E_corrLagStats0, E_ica_corr_value0, E_diff_corrLM_corrRM, E_tdm_LT_es_em }; @@ -108,7 +108,7 @@ const Word32 xtalk_coef_td[SIZE_XTALK_ISEL_TD] = /*Q15*/ { 1841, 4353, 3322, -5411, 1061, 2716, -2453, 1046, 45199, -51474, -2431, -2245, 2194, -542, -135853, 99, 18138 }; -const int16_t xtalk_isel_dft[SIZE_XTALK_ISEL_DFT] = +const Word16 xtalk_isel_dft[SIZE_XTALK_ISEL_DFT] = { E_clas, E_gainILD, E_gainIPD, E_angle_rot, E_g_pred, E_d_prodL_prodR, E_sum_xcorr, E_xcorr_itd_value, E_gphat_d_itd2, E_gphat_ratio_m1_m2, E_gphat_m2_m2 }; @@ -127,8 +127,6 @@ const Word32 xtalk_coef_dft_q30[SIZE_XTALK_ISEL_DFT] = /*----------------------------------------------------------------------------------* * Stereo IC-BWE ROM tables *----------------------------------------------------------------------------------*/ -#define FLOAT_2_FIX_Q30(a) ((Word32)(a * 1024.0 * 1024.0 * 1024.0)) -#define FLOAT_2_FIX_Q31(a) ((Word32)(a * 1024.0 * 1024.0 * 1024.0 * 2.0)) /* Q30Value >> Q5 */ const Word32 icbwe_thr_TDM_fx[7] = {-1318855552 >> 5, -1667671424 >> 5, -1072553216 >> 5, 920192448 >> 5, 897910144 >> 5, 936654016 >> 5, @@ -148,8 +146,8 @@ const Word32 icbwe_regressionValuesDFT_fx[8] = {65221224, 333933696, 1127643648, * DFT stereo ROM tables *----------------------------------------------------------------------------------*/ -/* DFT stereo ITD ROM table */ -const int16_t itd_vad_band_tbl[STEREO_DFT_ITD_VAD_BAND_NUM+1] = +/* DFT stereo ITD ROM table Q0*/ +const Word16 itd_vad_band_tbl[STEREO_DFT_ITD_VAD_BAND_NUM+1] = { 5, 8, 11, 16, 21, 26, 30, 37, 43, 51, 59, 69, 80, 93, 107, 126, 147, 176, 211, 254, 320 @@ -159,10 +157,6 @@ const Word32 ild_q_Q25[16] = { 0, 67108864, 134217728, 201326592, 268435456, 335544320, 436207616, 536870912, 637534208, 738197504, 838860800, 1006632960, 1174405120, 1342177280, 1509949440, 1677721600 }; -const int16_t ild_q[16] = -{ - 0,2,4,6,8,10,13,16,19,22,25,30,35,40,45,50 -}; /* table of values of the analysis window cross-correlation function at 32kHz (stride 8) */ const Word32 Wn_table_fx[50] = /*Q31*/ @@ -176,14 +170,14 @@ const Word32 Wn_table_fx[50] = /*Q31*/ 1208316416, 1184339328 }; - +//Q15 const Word16 win_ana_8k_fx[STEREO_DFT_OVL_8k] = { 3471, 6011, 7759, 9178, 10404, 11497, 12492, 13411, 14268, 15072, 15832, 16554, 17241, 17898, 18527, 19131, 19711, 20271, 20810, 21331, 21834, 22320, 22790, 23245, 23686, 24113, 24526, 24927, 25315, 25691, 26055, 26407, 26749, 27079, 27399, 27708, 28007, 28295, 28574, 28843, 29102, 29352, 29592, 29823, 30045, 30257, 30461, 30656, 30841, 31018, 31186, 31345, 31496, 31638, 31772, 31897, 32013, 32121, 32221, 32312, 32395, 32470, 32536, 32594, 32643, 32684, 32717, 32742, 32759, 32767 }; - +//Q15 const Word16 win_ana_12k8_fx[STEREO_DFT_OVL_12k8] = { 2744, 4753, 6135, 7259, 8229, 9096, 9887, 10618, 11300, 11943, 12552, 13131, 13685, 14216, 14726, 15218, 15693, 16152, 16598, 17030, 17449, 17857, 18255, 18642, 19019, 19388, 19747, 20098, 20441, 20777, 21105, 21426, 21741, 22048, 22350, @@ -193,7 +187,7 @@ const Word16 win_ana_12k8_fx[STEREO_DFT_OVL_12k8] = { 31714, 31796, 31874, 31949, 32020, 32088, 32153, 32215, 32273, 32328, 32380, 32429, 32474, 32516, 32555, 32590, 32622, 32652, 32677, 32700, 32719, 32735, 32748, 32758, 32764, 32767 }; - +//Q15 const Word16 win_ana_16k_fx[STEREO_DFT_OVL_16k] = { 2454, 4251, 5488, 6493, 7361, 8137, 8845, 9500, 10112, 10688, 11234, 11754, 12251, 12729, 13188, 13631, 14059, 14473, 14875, 15266, 15646, 16016, 16377, 16729, 17072, 17408, 17736, 18057, 18372, 18680, 18982, 19278, 19568, 19853, 20133, @@ -205,7 +199,7 @@ const Word16 win_ana_16k_fx[STEREO_DFT_OVL_16k] = { 32375, 32414, 32452, 32487, 32520, 32551, 32580, 32607, 32632, 32654, 32675, 32693, 32710, 32724, 32737, 32747, 32755, 32762, 32766, 32767 }; - +//Q15 const Word16 win_ana_32k_fx[STEREO_DFT_OVL_32k] = { 1735, 3006, 3881, 4591, 5206, 5755, 6257, 6720, 7154, 7563, 7951, 8320, 8674, 9013, 9341, 9657, 9962, 10259, 10547, 10827, 11100, 11366, 11626, 11881, 12129, 12373, 12611, 12845, 13075, 13300, 13521, 13739, 13953, 14164, 14371, 14575, @@ -225,7 +219,7 @@ const Word16 win_ana_32k_fx[STEREO_DFT_OVL_32k] = { 32637, 32649, 32660, 32670, 32680, 32689, 32698, 32706, 32714, 32721, 32728, 32734, 32740, 32745, 32749, 32753, 32757, 32760, 32763, 32765, 32766, 32767, 32767, }; - +//Q15 const Word16 win_ana_48k_fx[STEREO_DFT_OVL_MAX] = { 1417, 2454, 3168, 3749, 4251, 4699, 5109, 5488, 5842, 6176, 6493, 6795, 7084, 7361, 7629, 7887, 8137, 8380, 8616, 8845, 9069, 9287, 9500, 9708, 9912, 10112, 10307, 10500, 10688, 10873, 11055, 11234, 11410, 11583, 11754, 11922, 12088, 12251, @@ -253,6 +247,7 @@ const Word16 win_ana_48k_fx[STEREO_DFT_OVL_MAX] = { 32699, 32705, 32710, 32715, 32720, 32724, 32729, 32733, 32737, 32740, 32744, 32747, 32750, 32753, 32755, 32758, 32760, 32762, 32763, 32765, 32766, 32767, 32767, 32767, 32767 }; +//Q31 const Word32 win_syn_8k_fx[STEREO_DFT_OVL_8k] = { 2552069, 13257920, 28512140, 47194820, 68734296, 92758192, 118992928, 147223104, 177270272, 208980864, 242218768, 276861760, 312796896, 349919776, 388131456, 427338304, 467450272, 508381120, 550047232, 592367232, 635262144, 678654848, 722469312, 766631488, 811068480, 855708672, 900481344, 945317568, 990149120, @@ -261,7 +256,7 @@ const Word32 win_syn_8k_fx[STEREO_DFT_OVL_8k] = { 1980701440, 2002483840, 2022827776, 2041707136, 2059098624, 2074979712, 2089330176, 2102132224, 2113369344, 2123027840, 2131095296, 2137561472, 2142418176, 2145659392, 2147280896 }; - +//Q31 const Word32 win_syn_12k8_fx[STEREO_DFT_OVL_12k8] = { 1261002, 6551972, 14094794, 23341214, 34014852, 45938972, 58986220, 73058896, 88077968, 103977504, 120700824, 138198304, 156425504, 175342256, 194911840, 215100336, 235876160, 257209056, 279070880, 301434752, 324274976, 347566784, 371285952, 395409728, 419915296, 444781024, 469985376, 495507360, 521326560, @@ -273,7 +268,7 @@ const Word32 win_syn_12k8_fx[STEREO_DFT_OVL_12k8] = { 2062192000, 2072117888, 2081447424, 2090175872, 2098299008, 2105812608, 2112713344, 2118997504, 2124662144, 2129704192, 2134121728, 2137912064, 2141073664, 2143604608, 2145504128, 2146770944, 2147404416 }; - +//Q31 const Word32 win_syn_16k_fx[STEREO_DFT_OVL_16k] = { 902372, 4688386, 10086516, 16705275, 24347740, 32888712, 42238640, 52328808, 63104236, 74519400, 86535432, 99118824, 112239520, 125870888, 139988880, 154570928, 169597088, 185047600, 200904832, 217152048, 233772928, 250752224, 268075536, 285728512, 303697792, 321970304, 340533344, 359374528, 378481760, 397843456, @@ -287,7 +282,7 @@ const Word32 win_syn_16k_fx[STEREO_DFT_OVL_16k] = { 2092676480, 2099077632, 2105088640, 2110707584, 2115932544, 2120762112, 2125194240, 2129228160, 2132862336, 2136095360, 2138926592, 2141355136, 2143379968, 2145000704, 2146216576, 2147027584, 2147432960 }; - +//Q31 const Word32 win_syn_32k_fx[STEREO_DFT_OVL_32k] = { 319116, 1657642, 3566755, 5907942, 8612268, 11636355, 14948419, 18525698, 22348862, 26402882, 30674656, 35153448, 39829380, 44694072, 49740016, 54960336, 60348800, 65899616, 71607840, 77468328, 83476984, 89629312, 95921440, 102349712, 108910496, 115600336, 122416448, 129355608, 136415040, 143591712, 150883056, 158286720, @@ -311,7 +306,7 @@ const Word32 win_syn_32k_fx[STEREO_DFT_OVL_32k] = { 2126240128, 2128257280, 2130174336, 2131991296, 2133708160, 2135324800, 2136840960, 2138256512, 2139571712, 2140785920, 2141899136, 2142911616, 2143823104, 2144633472, 2145342592, 2145950592, 2146457344, 2146862848, 2147166848, 2147369600, 2147470976 }; - +//Q31 const Word32 win_syn_48k_fx[STEREO_DFT_OVL_MAX] = { 173731, 902372, 1941540, 3216071, 4688386, 6334862, 8138533, 10086516, 12168931, 14377618, 16705275, 19146106, 21695168, 24347740, 27099956, 29947948, 32888712, 35919240, 39036744, 42238640, 45522788, 48886820, 52328808, 55846816, 59439128, 63104236, 66840212, 70645768, 74519400, 78459600, 82465520, 86535432, 90668480, @@ -345,7 +340,7 @@ const Word32 win_syn_48k_fx[STEREO_DFT_OVL_MAX] = { 2133984512, 2135062400, 2136095360, 2137083776, 2138027648, 2138926592, 2139780992, 2140590464, 2141355136, 2142075008, 2142749952, 2143379968, 2143965184, 2144505344, 2145000704, 2145451008, 2145856256, 2146216576, 2146531840, 2146802304, 2147027584, 2147207680, 2147342720, 2147432960, 2147478016 }; - +//Q31 const Word32 win_mdct_8k_fx[STEREO_DFT_OVL_8k] = { 24094122, 72270552, 120410264, 168489632, 216483968, 264369408, 312121728, 359716832, 407130912, 454339904, 501320192, 548047936, 594499712, 640652160, 686482048, 731966336, 777081984, 821806336, 866117120, 909991488, 953407808, 996343936, 1038778432, 1080689792, 1122057216, 1162859392, 1203076224, 1242687104, 1281672320, @@ -360,7 +355,7 @@ const Word32 win_mdct_8k_fx[STEREO_DFT_OVL_8k] = { *----------------------------------------------------------------------------------*/ /* approximation table for log2(1 + x) in Q10 format, with x in [0, 1] in Q6 format */ -const int16_t log2_1px_table[65] = +const Word16 log2_1px_table[65] = { 0, 23, 45, 68, 90, 111, 132, 153, 174, 194, 214, 234, 254, 273, 292, 311, 330, 348, 366, 384, 402, 419, 436, 454, 470, 487, 504, 520, 536, 552, 568, 584, @@ -376,7 +371,8 @@ const Word16 ECSQ_log2_fact_Q10[1 + ECSQ_SEGMENT_SIZE] = { 0, 0, 1024, 2647, 4695, 7072, 9719, 12594, 15666 }; -const uint16_t ECSQ_tab_param[ECSQ_CONFIG_COUNT][1 + ECSQ_PARAM_COUNT] = +//Q0 +const UWord16 ECSQ_tab_param[ECSQ_CONFIG_COUNT][1 + ECSQ_PARAM_COUNT] = { { 16384, 15360, 14336, 13312, 12288, 11264, 10240, 9216, 8192, 7168, 6144, 5120, 4096, 3072, 2048, 1024, 0 }, /* un-optimized (reserved) */ { 16384, 7090, 365, 171, 73, 38, 21, 13, 9, 7, 6, 5, 4, 3, 2, 1, 0 }, /* 34 kbps target SNR */ @@ -386,8 +382,8 @@ const uint16_t ECSQ_tab_param[ECSQ_CONFIG_COUNT][1 + ECSQ_PARAM_COUNT] = { 16384, 6940, 633, 186, 74, 38, 21, 13, 9, 7, 6, 5, 4, 3, 2, 1, 0 }, /* 56 kbps target SNR */ { 16384, 10548, 1936, 774, 117, 41, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 } /* 56 kbps target bits */ }; - -const uint16_t ECSQ_tab_vals[ECSQ_PARAM_COUNT - 1][1 + ECSQ_TAB_VALS_SIZE] = +//Q0 +const UWord16 ECSQ_tab_vals[ECSQ_PARAM_COUNT - 1][1 + ECSQ_TAB_VALS_SIZE] = { { 16384, 9939, 3659, 1349, 499, 186, 71, 29, 14, 8, 6, 5, 4, 3, 2, 1, 0 }, /* param = 0 */ { 16384, 12760, 7739, 4694, 2847, 1727, 1048, 636, 386, 234, 142, 86, 52, 32, 20, 12, 0 }, /* param = 1 */ @@ -407,31 +403,32 @@ const uint16_t ECSQ_tab_vals[ECSQ_PARAM_COUNT - 1][1 + ECSQ_TAB_VALS_SIZE] = }; /* table for uniform coding of absolute values in {0, +-1} */ -static const uint16_t ECSQ_tab_abs_1bit[1 + 2] = +//Q0 +static const UWord16 ECSQ_tab_abs_1bit[1 + 2] = { 16384, 10922, 0 }; /* table for uniform coding of absolute values in {0, +-1, +-2, +-3} */ -static const uint16_t ECSQ_tab_abs_2bit[1 + 4] = +static const UWord16 ECSQ_tab_abs_2bit[1 + 4] = { 16384, 14046, 9364, 4682, 0 }; /* table for uniform coding of absolute values in {0, +-1, ..., +-7} */ -static const uint16_t ECSQ_tab_abs_3bit[1 + 8] = +static const UWord16 ECSQ_tab_abs_3bit[1 + 8] = { 16384, 15288, 13104, 10920, 8736, 6552, 4368, 2184, 0 }; /* table for uniform coding of absolute values in {0, +-1, ..., +-15} */ -static const uint16_t ECSQ_tab_abs_4bit[1 + 16] = +static const UWord16 ECSQ_tab_abs_4bit[1 + 16] = { 16384, 15870, 14812, 13754, 12696, 11638, 10580, 9522, 8464, 7406, 6348, 5290, 4232, 3174, 2116, 1058, 0 }; /* array of tables for uniform coding of absolute values */ -const uint16_t * const ECSQ_tab_abs_lsbs[1 + 4] = +const UWord16 * const ECSQ_tab_abs_lsbs[1 + 4] = { NULL, ECSQ_tab_abs_1bit, ECSQ_tab_abs_2bit, ECSQ_tab_abs_3bit, ECSQ_tab_abs_4bit }; @@ -747,7 +744,7 @@ const HUFF_TABLE huff_beta_table = } }; -const int16_t mc_paramupmix_fb_remix_order[4] = {0, 1, 2, 3}; +const Word16 mc_paramupmix_fb_remix_order[4] = {0, 1, 2, 3}; /*----------------------------------------------------------------------------------* * ParamMC ROM tables diff --git a/lib_enc/ivas_sba_enc.c b/lib_enc/ivas_sba_enc_fx.c similarity index 96% rename from lib_enc/ivas_sba_enc.c rename to lib_enc/ivas_sba_enc_fx.c index 0fe07179a9fdfc85ad770bc33485c78b98f82c26..e630a70d954f4e5764dba5b446df8b125884a346 100644 --- a/lib_enc/ivas_sba_enc.c +++ b/lib_enc/ivas_sba_enc_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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,12 +37,11 @@ #include "cnst.h" #include "ivas_cnst.h" #include "rom_com.h" -#include "prot.h" -#include "ivas_prot.h" +#include "prot_fx.h" +#include "ivas_prot_fx.h" #include "ivas_rom_com.h" #include "wmc_auto.h" #include "ivas_prot_fx.h" -#include "prot_fx.h" /*-------------------------------------------------------------------* @@ -86,12 +85,12 @@ void ivas_sba_getTCs_fx( } /*-------------------------------------------------------------------* - * ivas_sba_enc_reconfigure() + * ivas_sba_enc_reconfigure_fx() * * Reconfigure IVAS SBA encoder *-------------------------------------------------------------------*/ -/* To be renamed as ivas_sba_enc_reconfigure_fx later */ -ivas_error ivas_sba_enc_reconfigure( + +ivas_error ivas_sba_enc_reconfigure_fx( Encoder_Struct *st_ivas /* i/o: IVAS encoder structure */ ) { @@ -199,7 +198,7 @@ ivas_error ivas_sba_enc_reconfigure( } } - ivas_spar_config_fx( ivas_total_brate, min( st_ivas->sba_analysis_order, IVAS_MAX_SBA_ORDER ), &st_ivas->nchan_transport, &st_ivas->nSCE, &st_ivas->nCPE, &st_ivas->hSpar->core_nominal_brate, -1 ); + ivas_spar_config_fx( ivas_total_brate, s_min( st_ivas->sba_analysis_order, IVAS_MAX_SBA_ORDER ), &st_ivas->nchan_transport, &st_ivas->nSCE, &st_ivas->nCPE, &st_ivas->hSpar->core_nominal_brate, -1 ); hSpar = st_ivas->hSpar; diff --git a/lib_enc/ivas_sce_enc.c b/lib_enc/ivas_sce_enc_fx.c similarity index 92% rename from lib_enc/ivas_sce_enc.c rename to lib_enc/ivas_sce_enc_fx.c index 52c899f08009118c9ce9eb584683339d96dde98b..35b65e4c1604f4cf2a0763aefc69553aec6bb6a4 100644 --- a/lib_enc/ivas_sce_enc.c +++ b/lib_enc/ivas_sce_enc_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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,10 +36,8 @@ #include "cnst.h" #include "ivas_cnst.h" #include "rom_com.h" -#include "prot.h" #include "prot_fx.h" #include "prot_fx_enc.h" -#include "ivas_prot.h" #include "ivas_rom_com.h" #ifdef DEBUGGING #include "debug.h" @@ -161,6 +159,9 @@ ivas_error ivas_sce_enc_fx( #ifdef DEBUGGING st->force = st_ivas->hEncoderConfig->force; st->id_element = sce_id; +#ifdef DEBUG_FORCE_DIR + st->force_dir = st_ivas->hEncoderConfig->force_dir; +#endif #endif move16(); move16(); @@ -177,8 +178,6 @@ ivas_error ivas_sce_enc_fx( IF( NE_32( ivas_format, MC_FORMAT ) || NE_32( st_ivas->mc_mode, MC_MODE_PARAMMC ) ) { RunTransientDetection_ivas_fx( st->input_fx, input_frame, st->hTranDet, q_input ); - move16(); - move16(); } currFlatness_fx[0] = GetTCXAvgTemporalFlatnessMeasure_ivas_fx( (const TransientDetection *) st->hTranDet, NSUBBLOCKS, 0 ); // Q7 @@ -249,11 +248,16 @@ ivas_error ivas_sce_enc_fx( q_old_wsp = Q15; move16(); + Word16 q_fr_bands[2]; error = pre_proc_front_ivas_fx( hSCE, NULL, hSCE->element_brate, nb_bits_metadata, input_frame, 0, old_inp_12k8_fx[0], old_inp_16k_fx[0], &ener_fx[0], &relE_fx[0], A_fx[0], Aw_fx[0], epsP_fx[0], &epsP_fx_q[0], lsp_new_fx[0], lsp_mid_fx[0], &vad_hover_flag[0], &attack_flag[0], realBuffer_fx[0], imagBuffer_fx[0], &q_re_im_buf, old_wsp_fx[0], &q_old_wsp, pitch_fr_fx[0], voicing_fr_fx[0], &loc_harm[0], &cor_map_sum_fx[0], &vad_flag_dtx[0], enerBuffer_fx[0], &enerBuffer_fx_exp[0], - fft_buff_fx[0], &fft_buff_fx_q[0], A_fx[0], lsp_new_fx[0], currFlatness_fx[0], 0, fr_bands_fx, 31, Etot_LR_fx, lf_E_fx, 31, localVAD_HE_SAD, NULL, 31, flag_16k_smc, + fft_buff_fx[0], &fft_buff_fx_q[0], A_fx[0], lsp_new_fx[0], currFlatness_fx[0], 0, fr_bands_fx, q_fr_bands, Etot_LR_fx, lf_E_fx, 31, localVAD_HE_SAD, NULL, 31, flag_16k_smc, +#ifdef NONBE_1211_DTX_BR_SWITCHING + st_ivas->hSpar != NULL ? st_ivas->hSpar->front_vad_flag : 0, st_ivas->hSpar != NULL ? st_ivas->hSpar->force_front_vad : 0, st_ivas->hSpar != NULL ? st_ivas->hSpar->front_vad_dtx_flag : 0, ivas_format, 0, st_ivas->hEncoderConfig->last_ivas_total_brate, st_ivas->hEncoderConfig->ivas_total_brate, &Q_new[0] +#else st_ivas->hSpar != NULL ? st_ivas->hSpar->front_vad_flag : 0, st_ivas->hSpar != NULL ? st_ivas->hSpar->force_front_vad : 0, st_ivas->hSpar != NULL ? st_ivas->hSpar->front_vad_dtx_flag : 0, ivas_format, 0, st_ivas->hEncoderConfig->ivas_total_brate, &Q_new[0] +#endif #ifdef DEBUG_MODE_INFO , st->id_element @@ -261,7 +265,7 @@ ivas_error ivas_sce_enc_fx( ); e_old_wsp[0] = sub( Q15, q_old_wsp ); move16(); - IF( error != IVAS_ERR_OK ) + IF( NE_32( error, IVAS_ERR_OK ) ) { return error; } @@ -314,7 +318,7 @@ ivas_error ivas_sce_enc_fx( /* IGF reconfiguration */ test(); - IF( hSCE->last_element_brate != hSCE->element_brate || st->last_bwidth != st->bwidth ) + IF( NE_32( hSCE->last_element_brate, hSCE->element_brate ) || NE_16( st->last_bwidth, st->bwidth ) ) { Word16 igf; igf = getIgfPresent_fx( st->element_mode, L_mult0( st->bits_frame_nominal, FRAMES_PER_SEC ), st->max_bwidth, st->rf_mode ); @@ -327,7 +331,7 @@ ivas_error ivas_sce_enc_fx( /* set ACELP@12k8 / ACELP@16k flag for flexible ACELP core */ test(); test(); - IF( st->core_brate == SID_2k40 || st->core_brate == FRAME_NO_DATA ) + IF( EQ_32( st->core_brate, SID_2k40 ) || st->core_brate == FRAME_NO_DATA ) { st->flag_ACELP16k = set_ACELP_flag_IVAS( IVAS_SCE, hSCE->element_brate, st->core_brate, 0, 0, -1, -1 ); } @@ -348,10 +352,10 @@ ivas_error ivas_sce_enc_fx( * Encoder *----------------------------------------------------------------*/ - Scale_sig( old_wsp_fx[0], L_WSP, sub( e_old_wsp[0], Q16 ) ); + Scale_sig( old_wsp_fx[0], L_WSP, sub( e_old_wsp[0], Q16 ) ); // Q(15-16) e_old_wsp[0] = 16; move16(); - IF( ( error = ivas_core_enc( hSCE, NULL, NULL, 1, old_inp_12k8_fx, old_inp_16k_fx, Q_new, ener_fx, A_fx, Aw_fx, epsP_fx, epsP_fx_q, lsp_new_fx, lsp_mid_fx, vad_hover_flag, attack_flag, realBuffer_fx, imagBuffer_fx, &q_re_im_buf, old_wsp_fx, e_old_wsp, loc_harm, cor_map_sum_fx, vad_flag_dtx, enerBuffer_fx, enerBuffer_fx_exp, fft_buff_fx, 0, ivas_format, flag_16k_smc ) ) != IVAS_ERR_OK ) + IF( NE_32( ( error = ivas_core_enc_fx( hSCE, NULL, NULL, 1, old_inp_12k8_fx, old_inp_16k_fx, Q_new, ener_fx, A_fx, Aw_fx, epsP_fx, epsP_fx_q, lsp_new_fx, lsp_mid_fx, vad_hover_flag, attack_flag, realBuffer_fx, imagBuffer_fx, &q_re_im_buf, old_wsp_fx, e_old_wsp, loc_harm, cor_map_sum_fx, vad_flag_dtx, enerBuffer_fx, enerBuffer_fx_exp, fft_buff_fx, 0, ivas_format, flag_16k_smc ) ), IVAS_ERR_OK ) ) { return error; } @@ -429,7 +433,7 @@ ivas_error create_sce_enc_fx( test(); IF( NE_16( st_ivas->hEncoderConfig->ivas_format, MONO_FORMAT ) && EQ_16( sce_id, sub( st_ivas->nSCE, 1 ) ) ) { - IF( ( error = ivas_initialize_MD_bstr_enc( &( hSCE->hMetaData ), st_ivas ) ) != IVAS_ERR_OK ) + IF( NE_32( ( error = ivas_initialize_MD_bstr_enc_fx( &( hSCE->hMetaData ), st_ivas ) ), IVAS_ERR_OK ) ) { return error; } @@ -464,7 +468,7 @@ ivas_error create_sce_enc_fx( move32(); move32(); - IF( ( error = init_encoder_ivas_fx( st, st_ivas, 0, st_ivas->hEncoderConfig->var_SID_rate_flag, st_ivas->hEncoderConfig->interval_SID, 0, st_ivas->ism_mode, hSCE->element_brate ) ) != IVAS_ERR_OK ) + IF( NE_32( ( error = init_encoder_ivas_fx( st, st_ivas, 0, st_ivas->hEncoderConfig->var_SID_rate_flag, st_ivas->hEncoderConfig->interval_SID, 0, st_ivas->ism_mode, hSCE->element_brate ) ), IVAS_ERR_OK ) ) { return error; } @@ -476,12 +480,12 @@ ivas_error create_sce_enc_fx( } /*------------------------------------------------------------------------- - * create_evs_sce_enc() + * create_evs_sce_enc_fx() * * Create, allocate and initialize EVS encoder SCE handle *-------------------------------------------------------------------------*/ -ivas_error create_evs_sce_enc( +ivas_error create_evs_sce_enc_fx( Encoder_Struct *st_ivas, /* i/o: IVAS encoder structure */ const Word16 sce_id, /* i : SCE # identifier */ const Word32 element_brate /* i : element bitrate */ @@ -520,7 +524,7 @@ ivas_error create_evs_sce_enc( test(); IF( NE_32( st_ivas->hEncoderConfig->ivas_format, MONO_FORMAT ) && EQ_16( sce_id, sub( st_ivas->nSCE, 1 ) ) ) { - IF( NE_32( ( error = ivas_initialize_MD_bstr_enc( &( hSCE->hMetaData ), st_ivas ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = ivas_initialize_MD_bstr_enc_fx( &( hSCE->hMetaData ), st_ivas ) ), IVAS_ERR_OK ) ) { return error; } @@ -604,7 +608,7 @@ ivas_error create_evs_sce_enc( } st_fx->hBstr->ind_list = ind_list; // st_fx->hBstr->ind_list_fx = st->hBstr->ind_list; - reset_indices_enc_fx( st_fx->hBstr ); + reset_indices_enc_fx( st_fx->hBstr, MAX_NUM_INDICES ); hSCE->hCoreCoder[0] = st_fx; st_ivas->hSCE[sce_id] = hSCE; @@ -613,12 +617,12 @@ ivas_error create_evs_sce_enc( } /*------------------------------------------------------------------------- - * destroy_sce_enc() + * destroy_sce_enc_fx() * * Destroy and deallocate IVAS encoder SCE handle *-------------------------------------------------------------------------*/ -void destroy_sce_enc( +void destroy_sce_enc_fx( SCE_ENC_HANDLE hSCE, /* i/o: SCE encoder structure */ Flag is_evs /* i : Flag to indicate EVS encoder*/ ) @@ -642,7 +646,7 @@ void destroy_sce_enc( } } - ivas_destroy_MD_bstr_enc( &( hSCE->hMetaData ) ); + ivas_destroy_MD_bstr_enc_fx( &( hSCE->hMetaData ) ); free( hSCE ); diff --git a/lib_enc/ivas_sns_enc.c b/lib_enc/ivas_sns_enc_fx.c similarity index 98% rename from lib_enc/ivas_sns_enc.c rename to lib_enc/ivas_sns_enc_fx.c index d36fcaaa5d9c54b4a3a13443ec3b2245d728e5e8..dfd207c3e4d30c8841684d661401349efb8553a1 100644 --- a/lib_enc/ivas_sns_enc.c +++ b/lib_enc/ivas_sns_enc_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other @@ -35,10 +35,8 @@ #include "options.h" #include #include "cnst.h" -#include "prot.h" -#include "ivas_prot.h" -#include "ivas_prot_fx.h" #include "prot_fx.h" +#include "ivas_prot_fx.h" #include "rom_com.h" #include "ivas_rom_com.h" #include "ivas_rom_com_fx.h" @@ -61,7 +59,7 @@ static Word16 sns_1st_cod_fx( Word32 *snsq_fx /* o : quantized sns Q16 */ ) { - Word16 index; + Word16 index, i; const Word16 split_len = M / 2; move16(); const Word16 *means; @@ -86,7 +84,7 @@ static Word16 sns_1st_cod_fx( Word16 exp_snsq_buffer[M] = { 0 }, exp_snsq = 0; move16(); move16(); - FOR( Word16 i = 0; i < M; ++i ) + FOR( i = 0; i < M; ++i ) { Word32 tmp = L_mult( means[i], means_fix ); // Q16 exp_snsq_buffer[i] = 0; @@ -94,11 +92,11 @@ static Word16 sns_1st_cod_fx( snsq_fx[i] = BASOP_Util_Add_Mant32Exp( sns_fx[i], exp_sns, L_negate( tmp ), 15, &exp_snsq_buffer[i] ); move32(); } - FOR( int i = 0; i < M; i++ ) + FOR( i = 0; i < M; i++ ) { exp_snsq = s_max( exp_snsq_buffer[i], exp_snsq ); } - FOR( int i = 0; i < M; i++ ) + FOR( i = 0; i < M; i++ ) { snsq_fx[i] = L_shr( snsq_fx[i], exp_snsq - exp_snsq_buffer[i] ); move32(); @@ -122,7 +120,7 @@ static Word16 sns_1st_cod_fx( dist_min_fx = MAXVAL_WORD32; Word16 exp_dist_min = 31; index_split = 0; - FOR( Word16 i = 0; i < 32; ++i ) + FOR( i = 0; i < 32; ++i ) { Word32 dist_fx = 0; move32(); @@ -235,6 +233,7 @@ static Word16 sns_2st_cod_fx( FOR( i = 0; i < 2; i++ ) { nq = indx[i]; + move16(); nbits = add( nbits, ( add( 2, ( shl( nq, 2 ) ) ) ) ); /* 2 bits to specify Q2,Q3,Q4,ext */ IF( GT_16( nq, 6 ) ) @@ -393,7 +392,7 @@ void sns_avq_cod_stereo_fx( side_fx[i] = BASOP_Util_Add_Mant32Exp( snsl_fx[i], exp_snl, L_negate( snsr_fx[i] ), exp_snr, &exp_side_buffer[i] ); move32(); Word32 tmp = Mpy_32_32( side_fx[i], side_fx[i] ); // exp_side[i] * 2 - ener_side_fx = BASOP_Util_Add_Mant32Exp( ener_side_fx, exp_ener_side, tmp, exp_side_buffer[i] * 2, &exp_ener_side ); + ener_side_fx = BASOP_Util_Add_Mant32Exp( ener_side_fx, exp_ener_side, tmp, shl( exp_side_buffer[i], 1 ), &exp_ener_side ); } FOR( i = 0; i < M; i++ ) { @@ -681,7 +680,7 @@ Word16 quantize_sns_fx( IF( zero_side_flag[k] ) { set32_fx( snsQ_fx, 0, M ); - continue; + CONTINUE; } nStages = SNS_MSVQ_NSTAGES_SIDE; @@ -697,7 +696,7 @@ Word16 quantize_sns_fx( } Word16 shift = find_guarded_bits_fx( M ); sns_e_tmp[ch][k] = sub( 31, sub( 20, shift ) ); - + move16(); idxIndices = add( idxIndices, nStages ); FOR( i = 0; i < nStages; ++i ) @@ -721,7 +720,7 @@ Word16 quantize_sns_fx( #ifdef MSAN_FIX FOR( k = 0; k < nSubframes; k++ ) { - scale_sig32( snsQ_out_fx[ch][k], M, sub( sns_e_tmp[ch][k], sns_e ) ); + scale_sig32( snsQ_out_fx[ch][k], M, sub( sns_e_tmp[ch][k], sns_e ) ); // Q(31-sns_e_tmp[ch][k]) } #else scale_sig32( snsQ_out_fx[ch][0], M, sub( sns_e_tmp[ch][0], *sns_e ) ); diff --git a/lib_enc/ivas_spar_encoder.c b/lib_enc/ivas_spar_encoder_fx.c similarity index 92% rename from lib_enc/ivas_spar_encoder.c rename to lib_enc/ivas_spar_encoder_fx.c index a366d86fba24b7fb7e3ac041f02f6e4f7344d7be..3b380f2ebacda088f27ceaa010823af2bd6199b3 100644 --- a/lib_enc/ivas_spar_encoder.c +++ b/lib_enc/ivas_spar_encoder_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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,12 +33,10 @@ #include #include #include "options.h" -#include "ivas_prot.h" #include "ivas_prot_fx.h" #include "prot_fx.h" #include "ivas_rom_com.h" #include "ivas_stat_com.h" -#include "prot.h" #include "math.h" #include "wmc_auto.h" #include "prot_fx_enc.h" @@ -130,14 +128,14 @@ ivas_error ivas_spar_enc_open_fx( /* set FB config. */ active_w_mixing = ivas_spar_br_table_consts[table_idx].active_w; move16(); - IF( ( error = ivas_fb_set_cfg( &fb_cfg, SBA_FORMAT, nchan_inp, nchan_transport, active_w_mixing, input_Fs, nchan_fb_in ) ) != IVAS_ERR_OK ) + IF( NE_32( ( error = ivas_fb_set_cfg( &fb_cfg, SBA_FORMAT, nchan_inp, nchan_transport, active_w_mixing, input_Fs, nchan_fb_in ) ), IVAS_ERR_OK ) ) { return error; } fb_cfg->remix_order = remix_order_set[hSpar->hMdEnc->spar_md_cfg.remix_unmix_order]; /* FB mixer handle */ - IF( ( error = ivas_FB_mixer_open_fx( &( hSpar->hFbMixer ), input_Fs, fb_cfg, spar_reconfig_flag ) ) != IVAS_ERR_OK ) + IF( NE_32( ( error = ivas_FB_mixer_open_fx( &( hSpar->hFbMixer ), input_Fs, fb_cfg, spar_reconfig_flag ) ), IVAS_ERR_OK ) ) { return error; } @@ -150,7 +148,7 @@ ivas_error ivas_spar_enc_open_fx( IF( !spar_reconfig_flag ) { /* Transient Detector handle */ - IF( ( error = ivas_transient_det_open_fx( &( hSpar->hTranDet ), input_Fs ) ) != IVAS_ERR_OK ) + IF( NE_32( ( error = ivas_transient_det_open_fx( &( hSpar->hTranDet ), input_Fs ) ), IVAS_ERR_OK ) ) { return error; } @@ -165,7 +163,7 @@ ivas_error ivas_spar_enc_open_fx( hSpar->hAgcEnc = NULL; IF( hSpar->AGC_Enable ) { - IF( ( error = ivas_spar_agc_enc_open_fx( &hSpar->hAgcEnc, input_Fs, nchan_inp ) ) != IVAS_ERR_OK ) + IF( NE_32( ( error = ivas_spar_agc_enc_open_fx( &hSpar->hAgcEnc, input_Fs, nchan_inp ) ), IVAS_ERR_OK ) ) { return error; } @@ -214,7 +212,7 @@ ivas_error ivas_spar_enc_open_fx( move16(); IF( hEncoderConfig->Opt_DTX_ON ) { - IF( ( error = front_vad_create_fx( &( hSpar->hFrontVad ), hEncoderConfig ) ) != IVAS_ERR_OK ) + IF( NE_32( ( error = front_vad_create_fx( &( hSpar->hFrontVad ), hEncoderConfig ) ), IVAS_ERR_OK ) ) { return error; } @@ -230,7 +228,7 @@ ivas_error ivas_spar_enc_open_fx( hSpar->hCoreCoderVAD->mct_chan_mode = MCT_CHAN_MODE_IGNORE; move32(); move32(); - IF( ( error = init_encoder_ivas_fx( hSpar->hCoreCoderVAD, st_ivas, 0, hEncoderConfig->var_SID_rate_flag, hEncoderConfig->interval_SID, 1, st_ivas->ism_mode, hSpar->hCoreCoderVAD->total_brate ) ) != IVAS_ERR_OK ) + IF( NE_32( ( error = init_encoder_ivas_fx( hSpar->hCoreCoderVAD, st_ivas, 0, hEncoderConfig->var_SID_rate_flag, hEncoderConfig->interval_SID, 1, st_ivas->ism_mode, hSpar->hCoreCoderVAD->total_brate ) ), IVAS_ERR_OK ) ) { return error; } @@ -343,10 +341,20 @@ ivas_error ivas_spar_enc_fx( error = IVAS_ERR_OK; move32(); hEncoderConfig = st_ivas->hEncoderConfig; - st0 = ( st_ivas->nSCE > 0 ) ? st_ivas->hSCE[0]->hCoreCoder[0] : st_ivas->hCPE[0]->hCoreCoder[0]; + IF( st_ivas->nSCE > 0 ) + { + st0 = st_ivas->hSCE[0]->hCoreCoder[0]; + } + ELSE + { + st0 = st_ivas->hCPE[0]->hCoreCoder[0]; + } + + test(); + test(); /* Write SBA signaling bits */ - if ( hEncoderConfig->ivas_format == SBA_FORMAT || ( hEncoderConfig->ivas_format == SBA_ISM_FORMAT && st_ivas->ism_mode == ISM_SBA_MODE_DISC ) ) + IF( EQ_32( hEncoderConfig->ivas_format, SBA_FORMAT ) || ( EQ_32( hEncoderConfig->ivas_format, SBA_ISM_FORMAT ) && EQ_32( st_ivas->ism_mode, ISM_SBA_MODE_DISC ) ) ) { /* Write SBA planar flag */ push_indice( st0->hBstr, IND_SMODE, hEncoderConfig->sba_planar, SBA_PLANAR_BITS ); @@ -354,9 +362,9 @@ ivas_error ivas_spar_enc_fx( /* Write SBA order */ push_indice( st0->hBstr, IND_SMODE, hEncoderConfig->sba_order, SBA_ORDER_BITS ); } - else /* ism_mode == ISM_MODE_NONE */ + ELSE /* ism_mode == ISM_MODE_NONE */ { - if ( hEncoderConfig->ivas_total_brate < IVAS_24k4 ) + IF( LT_32( hEncoderConfig->ivas_total_brate, IVAS_24k4 ) ) { /* Write SBA planar flag */ push_indice( st0->hBstr, IND_SMODE, hEncoderConfig->sba_planar, SBA_PLANAR_BITS ); @@ -364,20 +372,20 @@ ivas_error ivas_spar_enc_fx( /* hack to indicate OSBA bitstream at VLBR */ push_indice( st0->hBstr, IND_SMODE, 0, SBA_ORDER_BITS ); } - else + ELSE { /* Write SBA order */ push_indice( st0->hBstr, IND_SMODE, hEncoderConfig->sba_order, SBA_ORDER_BITS ); } } - if ( hEncoderConfig->ivas_format == SBA_ISM_FORMAT ) + IF( EQ_32( hEncoderConfig->ivas_format, SBA_ISM_FORMAT ) ) { /* write the number of objects in ISM_SBA format*/ push_indice( hMetaData, IND_ISM_NUM_OBJECTS, hEncoderConfig->nchan_ism - 1, NO_BITS_MASA_ISM_NO_OBJ ); } /* front VAD */ - IF( ( error = front_vad_spar_fx( st_ivas->hSpar, data_fx[0], hEncoderConfig, input_frame ) ) != IVAS_ERR_OK ) + IF( NE_32( ( error = front_vad_spar_fx( st_ivas->hSpar, data_fx[0], hEncoderConfig, input_frame ) ), IVAS_ERR_OK ) ) { return error; } @@ -394,11 +402,14 @@ ivas_error ivas_spar_enc_fx( } *nb_bits_metadata = hMetaData->nb_bits_tot; + move16(); + test(); /* Force IVAS front pre-proc decision for higher bitrates */ - if ( hEncoderConfig->ivas_total_brate > SBA_DTX_BITRATE_THRESHOLD || hEncoderConfig->Opt_DTX_ON == 0 ) + if ( GT_32( hEncoderConfig->ivas_total_brate, SBA_DTX_BITRATE_THRESHOLD ) || hEncoderConfig->Opt_DTX_ON == 0 ) { st_ivas->hSpar->front_vad_flag = 0; + move16(); } return error; @@ -418,8 +429,8 @@ static ivas_error ivas_spar_cov_md_process_fx( BSTR_ENC_HANDLE hMetaData, const Word16 nchan_inp, const Word16 sba_order, - Word32 *ppIn_FR_real_fx[IVAS_SPAR_MAX_CH], - Word32 *ppIn_FR_imag_fx[IVAS_SPAR_MAX_CH], + Word32 *ppIn_FR_real_fx[IVAS_SPAR_MAX_CH], // q_ppIn_FR + Word32 *ppIn_FR_imag_fx[IVAS_SPAR_MAX_CH], // q_ppIn_FR const Word16 transient_det[2], const Word16 dtx_vad, const Word16 nchan_transport, @@ -659,7 +670,7 @@ static ivas_error ivas_spar_enc_process_fx( const ENCODER_CONFIG_HANDLE hEncoderConfig, /* i : configuration structure */ BSTR_ENC_HANDLE hMetaData, /* i/o: MetaData handle */ const Word16 front_vad_flag, /* i : front-VAD decision */ - Word32 *data_fx[], /* i/o: input/transport audio channels */ + Word32 *data_fx[], /* i/o: input/transport audio channels Q(q_data) */ const Word16 q_data ) { Word32 pcm_tmp_fx[DIRAC_MAX_ANA_CHANS][L_FRAME48k * 2]; @@ -762,15 +773,19 @@ static ivas_error ivas_spar_enc_process_fx( FOR( i = 0; i < hSpar->hFbMixer->fb_cfg->num_in_chans; i++ ) { /* changing q format to q_data*/ - scale_sig32( p_pcm_tmp_fx[i], shl( input_frame, 1 ), sub( q_data, q_p_pcm_tmp_fx[i] ) ); + scale_sig32( p_pcm_tmp_fx[i], shl( input_frame, 1 ), sub( q_data, q_p_pcm_tmp_fx[i] ) ); // q_data } /* prepare Parameter MDFT analysis */ + Word16 shift = Q31; + move16(); FOR( i = 0; i < nchan_fb_in; i++ ) { ppIn_FR_real_fx[i] = p_pcm_tmp_fx[i]; ppIn_FR_imag_fx[i] = p_pcm_tmp_fx[i] + input_frame; p_pcm_tmp_fx[i] = data_fx[i]; + shift = s_min( shift, L_norm_arr( hSpar->hFbMixer->ppFilterbank_prior_input_fx[i], hSpar->hFbMixer->fb_cfg->prior_input_length ) ); + shift = s_min( shift, L_norm_arr( data_fx[i], input_frame ) ); } l_ts = idiv1616( input_frame, MAX_PARAM_SPATIAL_SUBFRAMES ); @@ -778,8 +793,17 @@ static ivas_error ivas_spar_enc_process_fx( Word16 gb = find_guarded_bits_fx( l_ts ); FOR( ts = 0; ts < MAX_PARAM_SPATIAL_SUBFRAMES; ts++ ) { + FOR( i = 0; i < nchan_fb_in; i++ ) + { + scale_sig32( data_fx[i], input_frame, shift ); // Q:q_data+shift + scale_sig32( hSpar->hFbMixer->ppFilterbank_prior_input_fx[i], hSpar->hFbMixer->fb_cfg->prior_input_length, shift ); // Q:q_data+shift + } ivas_fb_mixer_get_windowed_fr_fx( hSpar->hFbMixer, p_pcm_tmp_fx, ppIn_FR_real_fx, ppIn_FR_imag_fx, l_ts, l_ts, nchan_fb_in, gb ); - + FOR( i = 0; i < nchan_fb_in; i++ ) + { + scale_sig32( data_fx[i], input_frame, negate( shift ) ); // Q:q_data + scale_sig32( hSpar->hFbMixer->ppFilterbank_prior_input_fx[i], hSpar->hFbMixer->fb_cfg->prior_input_length, negate( shift ) ); // Q:q_data + } ivas_fb_mixer_update_prior_input_fx( hSpar->hFbMixer, p_pcm_tmp_fx, l_ts, nchan_fb_in ); FOR( i = 0; i < nchan_fb_in; i++ ) @@ -818,7 +842,7 @@ static ivas_error ivas_spar_enc_process_fx( /*Finding max possible q*/ Word16 pp_fr_q; - pp_fr_q = sub( q_data, gb ); + pp_fr_q = sub( add( q_data, shift ), gb ); Word16 re_q = MAX_16, im_q = MAX_16, FR_q; move16(); move16(); @@ -830,12 +854,12 @@ static ivas_error ivas_spar_enc_process_fx( FR_q = s_min( re_q, im_q ); FOR( i = 0; i < nchan_fb_in; i++ ) { - scale_sig32( ppIn_FR_real_fx[i], input_frame, FR_q ); - scale_sig32( ppIn_FR_imag_fx[i], input_frame, FR_q ); + scale_sig32( ppIn_FR_real_fx[i], input_frame, FR_q ); // Q(FR_q+pp_fr_q) + scale_sig32( ppIn_FR_imag_fx[i], input_frame, FR_q ); // Q(FR_q+pp_fr_q) } pp_fr_q = add( FR_q, pp_fr_q ); - IF( NE_32( ( error = ivas_dirac_enc_fx( st_ivas->hDirAC, hQMetaData, hMetaData, data_fx, ppIn_FR_real_fx, ppIn_FR_imag_fx, pp_fr_q, input_frame, dtx_vad, hEncoderConfig->ivas_format, hodirac_flag ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = ivas_dirac_enc_fx( st_ivas->hDirAC, hQMetaData, hMetaData, data_fx, ppIn_FR_real_fx, ppIn_FR_imag_fx, pp_fr_q, input_frame, dtx_vad, hEncoderConfig->ivas_format, hodirac_flag, shift ) ), IVAS_ERR_OK ) ) { return error; } @@ -892,7 +916,7 @@ static ivas_error ivas_spar_enc_process_fx( FOR( Word32 ch = ( hSpar->hFbMixer->fb_cfg->active_w_mixing == 0 ); ch < hSpar->hFbMixer->fb_cfg->num_out_chans; ch++ ) { /* changing q format to q_data*/ - scale_sig32( p_pcm_tmp_fx[ch], input_frame, sub( q_data, q_p_pcm_tmp_fx[ch] ) ); + scale_sig32( p_pcm_tmp_fx[ch], input_frame, sub( q_data, q_p_pcm_tmp_fx[ch] ) ); // q_data q_p_pcm_tmp_fx[ch] = q_data; move16(); } @@ -982,7 +1006,7 @@ static ivas_error ivas_spar_enc_process_fx( FOR( i = 0; i < hSpar->hFbMixer->fb_cfg->num_out_chans; i++ ) { - scale_sig32( p_pcm_tmp_fx[i], input_frame, sub( q_data, q_pcm_fx[i] ) ); + scale_sig32( p_pcm_tmp_fx[i], input_frame, sub( q_data, q_pcm_fx[i] ) ); // q_data q_pcm_fx[i] = q_data; move16(); } diff --git a/lib_enc/ivas_spar_md_enc.c b/lib_enc/ivas_spar_md_enc_fx.c similarity index 95% rename from lib_enc/ivas_spar_md_enc.c rename to lib_enc/ivas_spar_md_enc_fx.c index 21c876f565ee698627fd695c125579d7b356bf1d..9c4fcc937163e672569f913223ec1cce692b2a20 100644 --- a/lib_enc/ivas_spar_md_enc.c +++ b/lib_enc/ivas_spar_md_enc_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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,22 +33,19 @@ #include #include #include "options.h" -#include "prot.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "ivas_prot_fx.h" #include "math.h" #include "ivas_rom_com.h" #include "ivas_rom_com_fx.h" #include #include "wmc_auto.h" -#include "prot_fx.h" /*------------------------------------------------------------------------------------------* * PreProcessor *------------------------------------------------------------------------------------------*/ /*Q28*/ -static const Word32 pr_boost_range_fx[2] = { 26843546, 107374182 }; +static const Word32 pr_boost_range_fx[2] = { 26843546 /*.1f in Q28*/, 107374182 /*.4f in Q28*/ }; typedef enum ivas_strats_t { @@ -141,8 +138,8 @@ ivas_error ivas_spar_md_enc_open_fx( } } hMdEnc->q_mixer_mat_fx = 0; - - IF( ( error = ivas_spar_md_enc_init_fx( hMdEnc, hEncoderConfig, sba_order ) ) != IVAS_ERR_OK ) + move16(); + IF( NE_32( ( error = ivas_spar_md_enc_init_fx( hMdEnc, hEncoderConfig, sba_order ) ), IVAS_ERR_OK ) ) { return error; } @@ -455,17 +452,17 @@ static void write_metadata_buffer_fx( *-----------------------------------------------------------------------------------------*/ ivas_error ivas_spar_md_enc_process_fx( - ivas_spar_md_enc_state_t *hMdEnc, /* i/o: SPAR MD encoder handle */ - const ENCODER_CONFIG_HANDLE hEncoderConfig, /* i : configuration structure */ - Word32 *cov_real_fx[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH], + ivas_spar_md_enc_state_t *hMdEnc, /* i/o: SPAR MD encoder handle */ + const ENCODER_CONFIG_HANDLE hEncoderConfig, /* i : configuration structure */ + Word32 *cov_real_fx[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH], /*Q(cov_real_q)*/ Word16 *cov_real_q[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH], - Word32 *cov_dtx_real_fx[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH], + Word32 *cov_dtx_real_fx[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH], /*Q(cov_dtx_real_q)*/ Word16 *cov_dtx_real_q[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH], BSTR_ENC_HANDLE hMetaData, /* i/o: MetaData handle */ const Word16 dtx_vad, const Word16 nchan_inp, const Word16 sba_order, /* i : Ambisonic (SBA) order */ - Word32 *prior_mixer[IVAS_MAX_FB_MIXER_OUT_CH][IVAS_MAX_SPAR_FB_MIXER_IN_CH], /* i : prior mixer_matrix */ + Word32 *prior_mixer[IVAS_MAX_FB_MIXER_OUT_CH][IVAS_MAX_SPAR_FB_MIXER_IN_CH], /* i : prior mixer_matrix Q(q_prior_mixer) */ Word16 *q_prior_mixer, /* i/o : q for prior mixer_matrix */ const Word16 dyn_active_w_flag, /* i : flag to indicate dynamic active W */ const Word16 dirac_mono_flag, /* i : flag to indicate mono only mode in SBA */ @@ -479,6 +476,7 @@ ivas_error ivas_spar_md_enc_process_fx( Word16 k, bwidth, num_bands, num_bands_full, num_bands_bw; Word16 active_w, nchan_transport, dmx_switch, strat; Word16 nB, bands_bw, packed_ok = 0; + move16(); ivas_strats_t cs[MAX_CODING_STRATS]; Word16 code_strat; Word16 bit_pos_start, next_ind_start; @@ -711,7 +709,7 @@ ivas_error ivas_spar_md_enc_process_fx( PR_step_e = sub( PR_step_e, Q12 ); Word16 PR_sign; - PR_sign = sub( (Word16) ( GT_32( PR_uq, 0 ) ), (Word16) ( LT_32( PR_uq, 0 ) ) ); + PR_sign = sub( extract_l( GT_32( PR_uq, 0 ) ), extract_l( LT_32( PR_uq, 0 ) ) ); hMdEnc->spar_md.band_coeffs_idx[b].pred_index_re[i] = PR_sign; move16(); @@ -851,7 +849,7 @@ ivas_error ivas_spar_md_enc_process_fx( move16(); IF( NE_16( strat, NO_STRAT ) ) { - reset_indices_enc( &hMetaData_tmp, md_indices_allocated ); + reset_indices_enc_fx( &hMetaData_tmp, md_indices_allocated ); ivas_write_spar_md_bitstream_fx( hMdEnc, num_bands, bands_bw, &hMetaData_tmp, hEncoderConfig->ivas_total_brate, strat, qsi ); @@ -989,7 +987,7 @@ ivas_error ivas_spar_md_enc_process_fx( *-----------------------------------------------------------------------------------------*/ static void ivas_band_mixer_fx( - Word32 *cov_real_fx[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH], + Word32 *cov_real_fx[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH], // Q(cov_real_q) Word16 *cov_real_q[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH], const Word16 num_ch, Word16 *num_bands, @@ -1141,7 +1139,7 @@ static void ivas_write_spar_md_bitstream_fx( push_next_indice( hMetaData, 5, SPAR_NUM_CODING_STRAT_BITS ); FOR( i = 0; i < nB; i++ ) { - do_diff[i] = (Word16) ( NE_16( ( s_and( ( add( i, 1 ) ), 3 ) ), 1 ) ); + do_diff[i] = extract_l( NE_16( ( s_and( ( add( i, 1 ) ), 3 ) ), 1 ) ); move16(); } ivas_map_prior_coeffs_quant( &hMdEnc->spar_md_prior, &hMdEnc->spar_md_cfg, qsi, nB ); @@ -1150,7 +1148,7 @@ static void ivas_write_spar_md_bitstream_fx( push_next_indice( hMetaData, 6, SPAR_NUM_CODING_STRAT_BITS ); FOR( i = 0; i < nB; i++ ) { - do_diff[i] = (Word16) ( NE_16( ( s_and( ( add( i, 1 ) ), 3 ) ), 2 ) ); + do_diff[i] = extract_l( NE_16( ( s_and( ( add( i, 1 ) ), 3 ) ), 2 ) ); move16(); } ivas_map_prior_coeffs_quant( &hMdEnc->spar_md_prior, &hMdEnc->spar_md_cfg, qsi, nB ); @@ -1159,7 +1157,7 @@ static void ivas_write_spar_md_bitstream_fx( push_next_indice( hMetaData, 7, SPAR_NUM_CODING_STRAT_BITS ); FOR( i = 0; i < nB; i++ ) { - do_diff[i] = (Word16) ( NE_16( ( s_and( ( add( i, 1 ) ), 3 ) ), 3 ) ); + do_diff[i] = extract_l( NE_16( ( s_and( ( add( i, 1 ) ), 3 ) ), 3 ) ); move16(); } ivas_map_prior_coeffs_quant( &hMdEnc->spar_md_prior, &hMdEnc->spar_md_cfg, qsi, nB ); @@ -1231,7 +1229,7 @@ static Word16 ivas_get_huffman_coded_bs_fx( FOR( j = pred_offset; j < pred_coeff_dim; j++ ) { - ivas_huffman_encode( &hMdEnc->huff_coeffs.pred_huff_re[qsi], hMdEnc->spar_md.band_coeffs_idx[i].pred_index_re[j], &code, &len ); + ivas_huffman_encode_fx( &hMdEnc->huff_coeffs.pred_huff_re[qsi], hMdEnc->spar_md.band_coeffs_idx[i].pred_index_re[j], &code, &len ); IF( GT_16( ( add( hMetaData->nb_bits_tot, len ) ), hMdEnc->spar_md_cfg.max_bits_per_blk ) ) { return -1; @@ -1242,7 +1240,7 @@ static Word16 ivas_get_huffman_coded_bs_fx( Word16 n = imult1616( ndec, sub( ndm, 1 ) ); FOR( j = 0; j < n; j++ ) { - ivas_huffman_encode( &hMdEnc->huff_coeffs.drct_huff_re[qsi], hMdEnc->spar_md.band_coeffs_idx[i].drct_index_re[j], &code, &len ); + ivas_huffman_encode_fx( &hMdEnc->huff_coeffs.drct_huff_re[qsi], hMdEnc->spar_md.band_coeffs_idx[i].drct_index_re[j], &code, &len ); IF( GT_16( ( add( hMetaData->nb_bits_tot, len ) ), hMdEnc->spar_md_cfg.max_bits_per_blk ) ) { return -1; @@ -1252,7 +1250,7 @@ static Word16 ivas_get_huffman_coded_bs_fx( FOR( j = 0; j < ndec; j++ ) { - ivas_huffman_encode( &hMdEnc->huff_coeffs.decd_huff_re[qsi], hMdEnc->spar_md.band_coeffs_idx[i].decd_index_re[j], &code, &len ); + ivas_huffman_encode_fx( &hMdEnc->huff_coeffs.decd_huff_re[qsi], hMdEnc->spar_md.band_coeffs_idx[i].decd_index_re[j], &code, &len ); IF( GT_16( ( add( hMetaData->nb_bits_tot, len ) ), hMdEnc->spar_md_cfg.max_bits_per_blk ) ) { return -1; @@ -1327,6 +1325,7 @@ static Word16 ivas_get_arith_coded_bs_fx( { pred_cell_dims[i].dim1 = sub( add( ndm, ndec ), 1 ); move16(); + test(); IF( hMdEnc->spar_hoa_md_flag && hMdEnc->spar_hoa_dirac2spar_md_flag ) { IF( GE_16( i, SPAR_DIRAC_SPLIT_START_BAND ) ) @@ -1393,8 +1392,8 @@ static Word16 ivas_get_arith_coded_bs_fx( ivas_copy_band_coeffs_idx_to_arr( hMdEnc->spar_md_prior.band_coeffs_idx_mapped, nB, symbol_arr_old_re, pred_cell_dims, PRED_COEFF ); } - arith_result = ivas_arith_encode_cmplx_cell_array( &hMdEnc->arith_coeffs.pred_arith_re[qsi], &hMdEnc->arith_coeffs.pred_arith_re_diff[qsi], pDo_diff, nB, - symbol_arr_re, symbol_arr_old_re, pred_cell_dims, hMetaData, any_diff, hMdEnc->spar_md_cfg.max_bits_per_blk ); + arith_result = ivas_arith_encode_cmplx_cell_array_fx( &hMdEnc->arith_coeffs.pred_arith_re[qsi], &hMdEnc->arith_coeffs.pred_arith_re_diff[qsi], pDo_diff, nB, + symbol_arr_re, symbol_arr_old_re, pred_cell_dims, hMetaData, any_diff, hMdEnc->spar_md_cfg.max_bits_per_blk ); move16(); IF( arith_result < 0 ) { @@ -1431,8 +1430,8 @@ static Word16 ivas_get_arith_coded_bs_fx( } - arith_result = ivas_arith_encode_cmplx_cell_array( &hMdEnc->arith_coeffs.drct_arith_re[qsi], &hMdEnc->arith_coeffs.drct_arith_re_diff[qsi], pDo_diff, nB, - symbol_arr_re, symbol_arr_old_re, drct_cell_dims, hMetaData, any_diff, hMdEnc->spar_md_cfg.max_bits_per_blk ); + arith_result = ivas_arith_encode_cmplx_cell_array_fx( &hMdEnc->arith_coeffs.drct_arith_re[qsi], &hMdEnc->arith_coeffs.drct_arith_re_diff[qsi], pDo_diff, nB, + symbol_arr_re, symbol_arr_old_re, drct_cell_dims, hMetaData, any_diff, hMdEnc->spar_md_cfg.max_bits_per_blk ); move16(); IF( arith_result < 0 ) @@ -1447,8 +1446,8 @@ static Word16 ivas_get_arith_coded_bs_fx( ivas_copy_band_coeffs_idx_to_arr( hMdEnc->spar_md_prior.band_coeffs_idx_mapped, nB, symbol_arr_old_re, decd_cell_dims, DECD_COEFF ); } - arith_result = ivas_arith_encode_cmplx_cell_array( &hMdEnc->arith_coeffs.decd_arith_re[qsi], &hMdEnc->arith_coeffs.decd_arith_re_diff[qsi], pDo_diff, nB, - symbol_arr_re, symbol_arr_old_re, decd_cell_dims, hMetaData, any_diff, hMdEnc->spar_md_cfg.max_bits_per_blk ); + arith_result = ivas_arith_encode_cmplx_cell_array_fx( &hMdEnc->arith_coeffs.decd_arith_re[qsi], &hMdEnc->arith_coeffs.decd_arith_re_diff[qsi], pDo_diff, nB, + symbol_arr_re, symbol_arr_old_re, decd_cell_dims, hMetaData, any_diff, hMdEnc->spar_md_cfg.max_bits_per_blk ); move16(); IF( arith_result < 0 ) @@ -1665,7 +1664,7 @@ static void ivas_write_parameter_bitstream_dtx_fx( Word16 *num_dec, const Word16 num_bands ) { - int16_t i, j; + Word16 i, j; Word32 val; Word16 idx; Word32 pr_min_max[2]; @@ -1752,7 +1751,7 @@ static void ivas_write_parameter_bitstream_dtx_fx( zero_pad_bits = sub( zero_pad_bits, 1 ); } - WHILE( GT_16( zero_pad_bits, 0 ) ) + WHILE( zero_pad_bits > 0 ) { j = s_min( zero_pad_bits, 16 ); push_next_indice( hMetaData, 0, j ); @@ -1803,7 +1802,7 @@ static void ivas_quant_c_per_band_fx( { C_re[k] = pband_coeffs->C_re_fx[i][j]; move32(); - k = add( k, 1 ); + k++; } } ivas_quantise_real_values_enc_fx_varq( C_re, pQs->C.q_levels[0], pQs->C.min_fx, pQs->C.max_fx, pBand_coeffs_idx->drct_index_re, C_re, ndec * ( ndm - 1 ), q_C ); @@ -1815,7 +1814,7 @@ static void ivas_quant_c_per_band_fx( { pband_coeffs->C_quant_re_fx[i][j] = C_re[k]; move32(); - k = add( k, 1 ); + k++; } } diff --git a/lib_enc/ivas_stat_enc.h b/lib_enc/ivas_stat_enc.h index e9b06d77df8844c24b5fc3cffad5f54006ebbbbc..ac258cfc1b9a428df1bdb1466943095d24577d5d 100644 --- a/lib_enc/ivas_stat_enc.h +++ b/lib_enc/ivas_stat_enc.h @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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,6 +39,9 @@ #include "ivas_cnst.h" #include "stat_enc.h" #include "ivas_stat_com.h" +#ifdef DEBUG_FORCE_DIR +#include "debug.h" +#endif /*----------------------------------------------------------------------------------* * DFT Stereo encoder structures @@ -85,9 +88,14 @@ typedef struct stereo_itd_data_struct Word16 prev_sum_nrg_L_lb_fx_e; Word32 prev_xcorr_lb_fx[STEREO_DFT_XCORR_LB_MAX]; Word16 prev_xcorr_lb_fx_e; +#ifdef FIX_ISSUE_1092 + Word32 E_band_n_fx[STEREO_DFT_ITD_VAD_BAND_NUM]; /*E_band_n_exp*/ + Word16 E_band_n_exp[STEREO_DFT_ITD_VAD_BAND_NUM]; +#else Word32 E_band_n_fx[STEREO_DFT_ITD_VAD_BAND_NUM]; /*Q0*/ +#endif Word32 xcorr_smooth_fx[STEREO_DFT_N_32k_ENC]; - Word16 xcorr_smooth_fx_e; + Word16 xcorr_smooth_fx_e[STEREO_DFT_N_32k_ENC]; Word32 lp_phat_peak_fx; /* low-pass GCC PHAT peak value */ // Q31 // Word16 q_itd; Word32 deltaItd_fx[STEREO_DFT_ENC_DFT_NB]; // Q16 @@ -116,15 +124,15 @@ typedef struct dft_ana_struct /* State of the range encoder */ typedef struct { - uint32_t rc_low; - uint32_t rc_range; - int16_t rc_cache; - int16_t rc_carry; - int16_t rc_carry_count; + UWord32 rc_low; + UWord32 rc_range; + Word16 rc_cache; + Word16 rc_carry; + Word16 rc_carry_count; - uint8_t byte_buffer[RANGE_UNI_BUFFER_BYTES_MAX]; - int16_t byte_count; - int16_t last_byte_bit_count; + UWord8 byte_buffer[RANGE_UNI_BUFFER_BYTES_MAX]; + Word16 byte_count; + Word16 last_byte_bit_count; } RangeUniEncState; @@ -272,7 +280,7 @@ typedef struct stereo_dft_enc_data_struct const Word16 *dft_trigo_16k_fx; const Word16 *dft_trigo_32k_fx; - Word32 output_mem_res_8k_fx[STEREO_DFT_OVL_8k]; // Q16 + Word32 output_mem_res_8k_fx[STEREO_DFT_OVL_8k]; // Q15 Word32 res_cod_NRG_M_fx[STEREO_DFT_BAND_MAX]; // Q(31 - res_cod_NRG_M_fx_e[]) Word16 res_cod_NRG_M_fx_e[STEREO_DFT_BAND_MAX]; @@ -289,11 +297,11 @@ typedef struct stereo_dft_enc_data_struct Word16 past_dot_prod_real_fx_e[STEREO_DFT_NRG_PAST_LEN * STEREO_DFT_BAND_MAX]; Word32 past_dot_prod_imag_fx[STEREO_DFT_NRG_PAST_LEN * STEREO_DFT_BAND_MAX]; // Q(31 - past_dot_prod_imag_fx_e[]) Word16 past_dot_prod_imag_fx_e[STEREO_DFT_NRG_PAST_LEN * STEREO_DFT_BAND_MAX]; - Word32 output_mem_dmx_fx[STEREO_DFT_OVL_MAX]; // Q16 - Word32 output_mem_dmx_12k8_fx[STEREO_DFT_OVL_12k8]; // Q16 - Word32 output_mem_dmx_16k_fx[STEREO_DFT_OVL_16k]; /*can hold 16, 12.8 or 32kHz signals*/ // Q16 - Word32 output_mem_dmx_32k_fx[STEREO_DFT_OVL_32k]; /*can hold 16, 12.8 or 32kHz signals*/ // Q16 - Word32 output_mem_dmx_16k_shb_fx[STEREO_DFT_OVL_16k]; // Q16 + Word32 output_mem_dmx_fx[STEREO_DFT_OVL_MAX]; // Q15 + Word32 output_mem_dmx_12k8_fx[STEREO_DFT_OVL_12k8]; // Q15 + Word32 output_mem_dmx_16k_fx[STEREO_DFT_OVL_16k]; /*can hold 16, 12.8 or 32kHz signals*/ // Q15 + Word32 output_mem_dmx_32k_fx[STEREO_DFT_OVL_32k]; /*can hold 16, 12.8 or 32kHz signals*/ // Q15 + Word32 output_mem_dmx_16k_shb_fx[STEREO_DFT_OVL_16k]; // Q15 Word16 input_mem_itd_fx[CPE_CHANNELS][STEREO_DFT_OVL_MAX]; Word16 q_input_mem_itd[CPE_CHANNELS]; Word32 gipd_fx[STEREO_DFT_ENC_DFT_NB]; // Q13 @@ -313,23 +321,23 @@ typedef struct stereo_mdct_enc_data_structure STEREO_MDCT_BAND_PARAMETERS stbParamsTCX20afterACELP; /* stereo frequency band parameters for transition frames */ /* only intraframe */ - int16_t mdct_stereo_mode[2]; /* mdct stereo mode: LR, MS, band-wise MS */ + Word16 mdct_stereo_mode[2]; /* mdct stereo mode: LR, MS, band-wise MS */ #ifdef DEBUGGING - int16_t mdct_stereo_mode_cmdl; /* MDCT stereo mode from command-line */ - int16_t fDualMono; /* force dual mono in MDCT stereo mode */ - int16_t fMSstereo; /* force full-band MS in MDCT stereo mode */ + Word16 mdct_stereo_mode_cmdl; /* MDCT stereo mode from command-line */ + Word16 fDualMono; /* force dual mono in MDCT stereo mode */ + Word16 fMSstereo; /* force full-band MS in MDCT stereo mode */ #endif - int16_t global_ild[2]; /* Quantized ILD for the whole spectrum */ - int16_t split_ratio; /* Ratio of bitrate (1 to 7), split_ratio = 8 * 1st chn bitrate / (1st + 2nd chn bitrate) */ + Word16 global_ild[2]; /* Quantized ILD for the whole spectrum */ + Word16 split_ratio; /* Ratio of bitrate (1 to 7), split_ratio = 8 * 1st chn bitrate / (1st + 2nd chn bitrate) */ - int16_t IGFStereoMode[2]; /* MDCT stereo mode for IGF */ + Word16 IGFStereoMode[2]; /* MDCT stereo mode for IGF */ ITD_DATA_HANDLE hItd; DFT_ANA_HANDLE hDft_ana; - int16_t sw_uncorr; + Word16 sw_uncorr; - int16_t isSBAStereoMode; + Word16 isSBAStereoMode; } STEREO_MDCT_ENC_DATA, *STEREO_MDCT_ENC_DATA_HANDLE; @@ -395,17 +403,16 @@ typedef struct stereo_td_enc_data_structure Word16 tdm_SM_modi_flag; /* Flag that indicates to modify ratio */ Word16 tdm_SM_reset_flag; /* Flag that indicates to reset the parameters for SM mode */ - Word16 tdm_FD2LRTD_SW_cnt; /* Count the number of frames following a FD to LRTD switching */ - Word16 tdm_LRTD_flag; /* LRTD stereo mode flag */ - Word16 prev_fr_LRTD_TD_dec; /* At the beginning of a frame, contains the previous LRTD decision that might have been modified during last frame */ - Word16 tdm_inst_ratio_idx; /* Instantaneous correlation ratio index */ - Word16 tdm_last_inst_ratio_idx; /* previous frame instantaneous correlation ratio index */ - Word16 tdm_vad_hangover_cnt; /* Count the number of frames where hangover_cnt >= 5 in both primary and secondary channel */ - Word16 tdm_ini_frame_cnt; /* Count the number of frame to decide how to evaluate the local VAD of primary and secondary channel */ - Word16 tdm_last_LRTD_frame_cnt; /* Count the number of frame since the last LRTD frame */ - Word16 tdm_last_LRTD_PriCh_cnt; /* Count the number of frame since the primary channel changed */ - Word16 flag_skip_DMX; /* flag that indicates whether the TD downmixing is skipped */ - // Word32 tdm_Pri_pitch_buf_fx[NB_SUBFR]; + Word16 tdm_FD2LRTD_SW_cnt; /* Count the number of frames following a FD to LRTD switching */ + Word16 tdm_LRTD_flag; /* LRTD stereo mode flag */ + Word16 prev_fr_LRTD_TD_dec; /* At the beginning of a frame, contains the previous LRTD decision that might have been modified during last frame */ + Word16 tdm_inst_ratio_idx; /* Instantaneous correlation ratio index */ + Word16 tdm_last_inst_ratio_idx; /* previous frame instantaneous correlation ratio index */ + Word16 tdm_vad_hangover_cnt; /* Count the number of frames where hangover_cnt >= 5 in both primary and secondary channel */ + Word16 tdm_ini_frame_cnt; /* Count the number of frame to decide how to evaluate the local VAD of primary and secondary channel */ + Word16 tdm_last_LRTD_frame_cnt; /* Count the number of frame since the last LRTD frame */ + Word16 tdm_last_LRTD_PriCh_cnt; /* Count the number of frame since the primary channel changed */ + Word16 flag_skip_DMX; /* flag that indicates whether the TD downmixing is skipped */ Word16 tdm_Pri_pitch_buf_fx[NB_SUBFR]; // Q6 } STEREO_TD_ENC_DATA, *STEREO_TD_ENC_DATA_HANDLE; @@ -452,7 +459,6 @@ typedef struct stereo_tca_enc_data_structure Word32 C_mem_fx[2 * L_NCSHIFT_DS + 1]; Word16 C_mem_exp[2 * L_NCSHIFT_DS + 1]; Word32 E1_mem_fx, E2_mem_fx; - // Word16 E1_E2_mem_exp; Word16 E1_mem_exp; Word16 E2_mem_exp; Word32 delay_0_mem_fx[MAX_DELAYREGLEN]; @@ -573,6 +579,7 @@ typedef struct ivas_stereo_classifier_data_structure Word32 non_sta_ch1_fx; Word16 non_sta_ch1_e; Word16 sp_div_ch1_fx; + Word16 sp_div_ch1_e; Word32 ps_sta_ch1_fx, ps_sta_ch2_fx; Word16 ps_sta_ch1_e, ps_sta_ch2_e; Word32 prev_g_IPD_fx; // Q29 @@ -589,11 +596,10 @@ typedef struct ivas_stereo_classifier_data_structure Word32 Etot_up_fx; /* average energy in dB - upper bound */ Word16 Etot_up_e; /* average energy in dB - upper bound */ Word32 relE_buf_fx[UNCLR_L_RELE]; /* running buffer for relative energy Q31 */ - Word16 relE_buf_e; /* running buffer for relative energy Q31 */ Word32 Etot_buf_fx[UNCLR_L_ETOT]; /* running buffer for average energy in dB */ Word16 e_Etot_buf_fx; /* exponent for Etot_buf_fx*/ Word32 relE_0_1_fx; /* relative energy in the current frame normalized to (0,1) Q31 */ - Word32 relE_0_1_LT_fx; // Q31 + Word32 relE_0_1_LT_fx; /* Q31 */ Word32 unclr_relE_0_1_LT_fx[UNCLR_RC_ORDER]; // Q31 Word32 unclr_wscore_fx; // Q31 Word32 unclr_fv_fx[SSC_MAX_NFEA]; /* UNCLR - feature vector */ // Q15 @@ -645,7 +651,6 @@ typedef struct front_vad_enc Word16 buffer_12k8_fx[3 * L_FRAME / 2]; Word16 q_mem_decim; Word16 q_buffer_12k8; - // Word32 buffer_12k8_fx[3 * L_FRAME / 2]; /* 12k8 signal buffer */ } FRONT_VAD_ENC, *FRONT_VAD_ENC_HANDLE; @@ -729,9 +734,9 @@ typedef struct ivas_enc_cov_handler_state_t { ivas_cov_smooth_state_t *pCov_state; ivas_cov_smooth_state_t *pCov_dtx_state; - int16_t num_bins; - int16_t prior_dtx_present; - int16_t prior_var_flag; + Word16 num_bins; + Word16 prior_dtx_present; + Word16 prior_var_flag; Word32 bb_var_lt_fx[FOA_CHANNELS]; } ivas_enc_cov_handler_state_t; @@ -785,10 +790,6 @@ typedef struct ivas_spar_enc_lib_t Word32 core_nominal_brate; /* Nominal bitrate for core coding */ FRONT_VAD_ENC_HANDLE hFrontVad; /* front-VAD handle */ ENC_CORE_HANDLE hCoreCoderVAD; /* core-coder handle for front-VAD module */ -#ifndef EVS_FLOAT_ENC - // ENC_CORE_HANDLE_FX hCoreCoderVAD_fx; /* core coder handle */ -#endif - Word16 spar_reconfig_flag; Word16 front_vad_flag; Word16 front_vad_dtx_flag; @@ -859,23 +860,23 @@ typedef struct ivas_omasa_enc_state_structure Word16 broadband_energy_prev_e; /*exponent for broadband_energy_prev_fx*/ Word16 fade_out_gain_fx[L_FRAME48k]; /*q15*/ Word16 fade_in_gain_fx[L_FRAME48k]; /*q15*/ - uint8_t nbands; - uint8_t nCodingBands; - uint8_t nSubframes; + UWord8 nbands; + UWord8 nCodingBands; + UWord8 nSubframes; /* CLDFB analysis */ - int16_t num_Cldfb_instances; + Word16 num_Cldfb_instances; HANDLE_CLDFB_FILTER_BANK cldfbAnaEnc[MAX_NUM_OBJECTS]; /* DirAC parameter estimation */ - int16_t band_grouping[MASA_FREQUENCY_BANDS + 1]; - int16_t block_grouping[5]; + Word16 band_grouping[MASA_FREQUENCY_BANDS + 1]; + Word16 block_grouping[5]; /* diffuseness */ - int16_t index_buffer_intensity; + Word16 index_buffer_intensity; - int16_t prev_selected_object; - uint8_t changing_object; + Word16 prev_selected_object; + UWord8 changing_object; } OMASA_ENC_STATE, *OMASA_ENC_HANDLE; @@ -912,8 +913,8 @@ typedef struct ivas_masa_dir_align_struct typedef struct ivas_masa_sync_struct { MASA_METADATA_FRAME previous_metadata; - uint8_t prev_sim_stop; - uint8_t prev_offset; + UWord8 prev_sim_stop; + UWord8 prev_offset; MASA_FRAME_MODE frame_mode; } MASA_SYNC_STATE, *MASA_SYNC_HANDLE; @@ -961,15 +962,15 @@ typedef struct ivas_masa_encoder_struct typedef struct ivas_mcmasa_enc_data_structure { - int16_t nbands; - int16_t nCodingBands; + Word16 nbands; + Word16 nCodingBands; /* delay compensation */ Word32 *delay_buffer_lfe[2]; /* Delay buffer for LFE estimation */ - int16_t num_samples_delay_comp; - int16_t num_slots_delay_comp; - int16_t offset_comp; + Word16 num_samples_delay_comp; + Word16 num_slots_delay_comp; + Word16 offset_comp; IVAS_FB_MIXER_HANDLE hFbMixer; IVAS_FB_MIXER_HANDLE hFbMixerLfe; @@ -977,12 +978,12 @@ typedef struct ivas_mcmasa_enc_data_structure /* DirAC parameter estimation */ Word32 **direction_vector_m_fx[DIRAC_NUM_DIMS]; /* Average direction vector */ Word16 **direction_vector_e[DIRAC_NUM_DIMS]; /* Average direction vector */ - int16_t band_grouping[MASA_FREQUENCY_BANDS + 1]; - int16_t block_grouping[5]; + Word16 band_grouping[MASA_FREQUENCY_BANDS + 1]; + Word16 block_grouping[5]; /* diffuseness */ - int16_t index_buffer_intensity; - int8_t no_col_avg_diff; + Word16 index_buffer_intensity; + Word8 no_col_avg_diff; Word32 **buffer_intensity_real_fx[DIRAC_NUM_DIMS]; Word16 buffer_intensity_real_q[DIRAC_NO_COL_AVG_DIFF]; Word32 **buffer_intensity_real_vert_fx; @@ -993,11 +994,11 @@ typedef struct ivas_mcmasa_enc_data_structure Word32 chnlToFoaEvenMtx_fx[FOA_CHANNELS][MCMASA_MAX_ANA_CHANS]; Word32 ls_azimuth_fx[MCMASA_MAX_ANA_CHANS]; - int16_t leftNearest[MCMASA_MAX_ANA_CHANS]; - int16_t rightNearest[MCMASA_MAX_ANA_CHANS]; - int16_t numHorizontalChannels; - uint8_t isHorizontalSetup; - uint8_t combineRatios; + Word16 leftNearest[MCMASA_MAX_ANA_CHANS]; + Word16 rightNearest[MCMASA_MAX_ANA_CHANS]; + Word16 numHorizontalChannels; + UWord8 isHorizontalSetup; + UWord8 combineRatios; Word32 prevMultiChEne_fx; Word16 prevMultiChEne_e; @@ -1007,8 +1008,8 @@ typedef struct ivas_mcmasa_enc_data_structure Word16 prevEQ_e; Word16 interpolator_fx[L_FRAME48k]; - uint8_t separateChannelEnabled; - int16_t separateChannelIndex; + UWord8 separateChannelEnabled; + Word16 separateChannelIndex; /* LFE coding */ Word32 lfeLfEne[MAX_PARAM_SPATIAL_SUBFRAMES]; @@ -1016,9 +1017,9 @@ typedef struct ivas_mcmasa_enc_data_structure Word32 totalLfEne[MAX_PARAM_SPATIAL_SUBFRAMES]; Word16 totalLfEne_e[MAX_PARAM_SPATIAL_SUBFRAMES]; Word32 *lfeAnaRingBuffer[2]; - int16_t ringBufferPointer; + Word16 ringBufferPointer; Word32 lowpassSum[2]; - int16_t ringBufferSize; + Word16 ringBufferSize; } MCMASA_ENC_DATA, *MCMASA_ENC_HANDLE; @@ -1033,7 +1034,7 @@ typedef struct ivas_osba_enc_data_structure Word32 interpolator_fx[L_FRAME48k]; Word32 prev_object_dm_gains_fx[MAX_NUM_OBJECTS][MAX_INPUT_CHANNELS]; - int16_t nchan_ism; + Word16 nchan_ism; Word32 *input_data_mem_fx[MAX_NUM_OBJECTS]; } OSBA_ENC_DATA, *OSBA_ENC_HANDLE; @@ -1101,14 +1102,12 @@ typedef struct cpe_enc_data_structure STEREO_CNG_ENC_HANDLE hStereoCng; /* Stereo CNG data structure */ FRONT_VAD_ENC_HANDLE hFrontVad[CPE_CHANNELS]; - // float *input_mem[CPE_CHANNELS]; /* input channels buffers memory; needed to be up-to-date for TD->DFT stereo switching */ - Word32 brate_surplus; /* bitrate surplus for bitrate adaptation in combined format coding */ Word16 *input_mem_fx[CPE_CHANNELS]; /* input channels buffers memory; needed to be up-to-date for TD->DFT stereo switching */ Word16 q_input_mem[CPE_CHANNELS]; #ifdef DEBUGGING - int16_t stereo_mode_cmdl; /* stereo mode forced from the commaand-line */ + Word16 stereo_mode_cmdl; /* stereo mode forced from the commaand-line */ #endif } CPE_ENC_DATA, *CPE_ENC_HANDLE; @@ -1120,9 +1119,9 @@ typedef struct cpe_enc_data_structure typedef struct mct_block_data_struct { - int16_t isActive; - int16_t ch1, ch2; - int16_t mask[2][MAX_SFB]; + Word16 isActive; + Word16 ch1, ch2; + Word16 mask[2][MAX_SFB]; STEREO_MDCT_ENC_DATA_HANDLE hStereoMdct; /* MDCT stereo data handle */ } MCT_BLOCK_DATA, *MCT_BLOCK_DATA_HANDLE; @@ -1131,16 +1130,16 @@ typedef struct mct_enc_data_structure { BSTR_ENC_HANDLE hBstr; /* bitstream handle for side bits - in MCT, side bits are written at the beginning of the bitstream */ - int16_t nchan_out_woLFE; /* number of active channels within multi-channel configuration */ - int16_t currBlockDataCnt; - int16_t bitsChannelPairIndex; /* bits needed to code channel pair index, depends on number of active channels */ + Word16 nchan_out_woLFE; /* number of active channels within multi-channel configuration */ + Word16 currBlockDataCnt; + Word16 bitsChannelPairIndex; /* bits needed to code channel pair index, depends on number of active channels */ MCT_BLOCK_DATA_HANDLE hBlockData[MCT_MAX_BLOCKS]; Word32 lastxCorrMatrix_fx[MCT_MAX_CHANNELS][MCT_MAX_CHANNELS]; Word16 lastxCorrMatrix_e; - int16_t lowE_ch[MCT_MAX_CHANNELS]; - uint16_t mc_global_ild[MCT_MAX_CHANNELS]; - int16_t nBitsMCT; /* number of bits spent on mct side info */ + Word16 lowE_ch[MCT_MAX_CHANNELS]; + UWord16 mc_global_ild[MCT_MAX_CHANNELS]; + Word16 nBitsMCT; /* number of bits spent on mct side info */ /* pointers to local buffers */ Word32 *p_mdst_spectrum_long_fx[MCT_MAX_BLOCKS][CPE_CHANNELS]; Word32 *p_orig_spectrum_long_fx[MCT_MAX_BLOCKS][CPE_CHANNELS]; @@ -1148,11 +1147,11 @@ typedef struct mct_enc_data_structure Word16 q_orig_spectrum_long_com; Word16 q_mdst_spectrum_long_fx[MCT_MAX_BLOCKS][CPE_CHANNELS][NB_DIV]; - int16_t tnsBits[MCT_MAX_BLOCKS][CPE_CHANNELS][NB_DIV]; /* number of tns bits in the frame */ - int16_t tnsSize[MCT_MAX_BLOCKS][CPE_CHANNELS][NB_DIV]; /* number of tns parameters put into prm */ - int16_t p_param[MCT_MAX_BLOCKS][CPE_CHANNELS][NB_DIV]; + Word16 tnsBits[MCT_MAX_BLOCKS][CPE_CHANNELS][NB_DIV]; /* number of tns bits in the frame */ + Word16 tnsSize[MCT_MAX_BLOCKS][CPE_CHANNELS][NB_DIV]; /* number of tns parameters put into prm */ + Word16 p_param[MCT_MAX_BLOCKS][CPE_CHANNELS][NB_DIV]; - int16_t hbr_mct; + Word16 hbr_mct; } MCT_ENC_DATA, *MCT_ENC_HANDLE; @@ -1169,9 +1168,9 @@ typedef struct stereo_dmx_evs_phase_only_correlation_structure Word32 peak_width_fx[CPE_CHANNELS]; // Q16 Word32 confidence_fx; // Q31 - int16_t ispeak[CPE_CHANNELS]; - int16_t itdLR[CPE_CHANNELS]; - int16_t shift_limit; + Word16 ispeak[CPE_CHANNELS]; + Word16 itdLR[CPE_CHANNELS]; + Word16 shift_limit; const Word32 *wnd_fx; @@ -1182,7 +1181,7 @@ typedef struct stereo_dmx_evs_phase_only_correlation_structure typedef struct stereo_dmx_evs_correlation_filter_structure { - int16_t init_frmCntr; + Word16 init_frmCntr; Word16 isd_rate_s_fx; // Q15 Word32 iccr_s_fx; // Q31 @@ -1191,8 +1190,8 @@ typedef struct stereo_dmx_evs_correlation_filter_structure Word32 Pi_fx[STEREO_DMX_EVS_NB_SUBBAND_MAX]; // Q31 Word16 rfft_ipd_coef_fx[L_FRAME48k / 2 + 1]; - int16_t pha_len; - int16_t fad_len; + Word16 pha_len; + Word16 fad_len; Word16 win_fx[STEREO_DMX_EVS_PHA_LEN_MAX]; // Q14 @@ -1204,14 +1203,14 @@ typedef struct stereo_dmx_evs_correlation_filter_structure STEREO_DMX_EVS_PHA curr_pha; STEREO_DMX_EVS_PHA prev_pha; - int16_t pha_hys_cnt; + Word16 pha_hys_cnt; - int16_t prc_thres; + Word16 prc_thres; STEREO_DMX_EVS_PRC curr_prc; STEREO_DMX_EVS_PRC prev_prc; - int16_t prc_hys_cnt; + Word16 prc_hys_cnt; Word32 fad_g_prc_fx[L_FRAME48k]; // Q31 - int16_t fad_len_prc; + Word16 fad_len_prc; Word32 trns_aux_energy_fx[CPE_CHANNELS]; @@ -1248,9 +1247,9 @@ typedef struct ivas_lfe_enc_data_structure { LFE_WINDOW_HANDLE pWindow_state; BSTR_ENC_HANDLE hBstr; /* pointer to encoder bitstream handle */ - const uint16_t *cum_freq_models[IVAS_MAX_NUM_QUANT_STRATS][IVAS_MAX_NUM_DCT_COEF_GROUPS]; - int16_t lfe_enc_indices_coeffs_tbl[IVAS_MAX_NUM_QUANT_STRATS][IVAS_MAX_NUM_DCT_COEF_GROUPS]; - int16_t lfe_bits; + const UWord16 *cum_freq_models[IVAS_MAX_NUM_QUANT_STRATS][IVAS_MAX_NUM_DCT_COEF_GROUPS]; + Word16 lfe_enc_indices_coeffs_tbl[IVAS_MAX_NUM_QUANT_STRATS][IVAS_MAX_NUM_DCT_COEF_GROUPS]; + Word16 lfe_bits; Word32 *old_wtda_audio_fx; Word16 q_old_wtda_audio; @@ -1297,10 +1296,13 @@ typedef struct encoder_config_structure Word16 Opt_PCA_ON; /* flag indicating PCA operation in SBA */ #ifdef DEBUGGING -/* debugging options */ - int16_t stereo_mode_cmdl; /* stereo mode forced from the command-line */ - int16_t force; /* parameter to force specific "core" of the Core-Coder*/ - int16_t mdct_stereo_mode_cmdl; /* mdct stereo mode forced from command-line, employed only when DEBUG_FORCE_MDCT_STEREO_MODE is activated */ + /* debugging options */ + Word16 stereo_mode_cmdl; /* stereo mode forced from the command-line */ + Word16 force; /* parameter to force specific "core" of the Core-Coder*/ + Word16 mdct_stereo_mode_cmdl; /* mdct stereo mode forced from command-line, employed only when DEBUG_FORCE_MDCT_STEREO_MODE is activated */ +#ifdef DEBUG_FORCE_DIR + char force_dir[FORCE_DIR_MAX_LENGTH]; /* directory containing external binary files for modes/parameters enforcement (empty string indicates no enforcement) */ +#endif #endif diff --git a/lib_enc/ivas_stereo_adapt_GR_enc.c b/lib_enc/ivas_stereo_adapt_GR_enc_fx.c similarity index 92% rename from lib_enc/ivas_stereo_adapt_GR_enc.c rename to lib_enc/ivas_stereo_adapt_GR_enc_fx.c index e5cd1da07ca953b8f15c89e553af153176f38e30..8e79b228875469ea0b56b50d505f7e59771346eb 100644 --- a/lib_enc/ivas_stereo_adapt_GR_enc.c +++ b/lib_enc/ivas_stereo_adapt_GR_enc_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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,8 +33,7 @@ #include #include "options.h" #include "cnst.h" -#include "ivas_prot.h" -#include "prot.h" +#include "prot_fx.h" #include "stat_enc.h" #include "wmc_auto.h" #include "ivas_rom_com.h" @@ -44,16 +43,16 @@ * Local function prototypes *---------------------------------------------------------------------*/ -static int16_t adapt_GR_sg( const int16_t *in, const int16_t len, const int16_t no_symb, int16_t *nbits, int16_t *in_enc, const int16_t *map0, const int16_t no_GR_ord ); +static Word16 adapt_GR_sg_fx( const Word16 *in, const Word16 len, const Word16 no_symb, Word16 *nbits, Word16 *in_enc, const Word16 *map0, const Word16 no_GR_ord ); /*---------------------------------------------------------------------* - * calculate_diff() + * calculate_diff_fx() * * calculate difference wrt previous frame and maps it to positive integer *---------------------------------------------------------------------*/ -static void calculate_diff( +static void calculate_diff_fx( const Word16 *in, /* i : current frame values */ const Word16 *prev, /* i : previous frmae values */ Word16 *in_diff, /* o : difference values */ @@ -90,14 +89,14 @@ static void calculate_diff( /*---------------------------------------------------------------------* - * calculate_bit_diff() + * calculate_bit_diff_fx() * * estimates the GR number of bits for encoding differential values * selects between GR order 0 or 1 *---------------------------------------------------------------------*/ /*! r: number of bits */ -static Word16 calculate_bit_diff( +static Word16 calculate_bit_diff_fx( Word16 *in_diff, /* i : values to be encoded */ Word16 len, /* i : number of params */ Word16 *flag_diff /* o : selected GR order */ @@ -153,7 +152,7 @@ Word16 adapt_GR_ief_fx( const Word16 no_GR_ord, /* i : number of GR order to try 2: 0,1; 3:0,1,2 */ Word16 *nbits_diff, /* o : number bits in diff encoding */ const Word16 side_gain_counter, /* i : number of frames since last abs coding */ - Word16 *side_gain_bitdiff_lp, /* i/o: LP-filtered bit difference between abs/diff */ + Word16 *side_gain_bitdiff_lp, /* i/o: LP-filtered bit difference between abs/diff Q(q_side_gain_bitdiff_lp) */ Word16 *q_side_gain_bitdiff_lp, /* i/o: Q of LP-filtered bit difference between abs/diff */ const Word16 try_diff /* i : diff coding allowed 1/0 */ ) @@ -163,12 +162,12 @@ Word16 adapt_GR_ief_fx( Word32 L_tmp, L_tmp1; Word16 exp_diff; - flag = adapt_GR_sg( in, len, no_symb, nbits, in_enc, map0, no_GR_ord ); + flag = adapt_GR_sg_fx( in, len, no_symb, nbits, in_enc, map0, no_GR_ord ); IF( try_diff ) /* inter-frame prediction allowed */ { - calculate_diff( in, prev, in_diff, len ); - nb_diff = calculate_bit_diff( in_diff, len, &flag_diff ); + calculate_diff_fx( in, prev, in_diff, len ); + nb_diff = calculate_bit_diff_fx( in_diff, len, &flag_diff ); *nbits_diff = nb_diff; move16(); @@ -202,13 +201,13 @@ Word16 adapt_GR_ief_fx( /*---------------------------------------------------------------------* - * adapt_GR_rpg1_ief() + * adapt_GR_rpg1_ief_fx() * * use adaptive GR for RPG's considering also the differential case *---------------------------------------------------------------------*/ /*! r: used GR order */ -Word16 adapt_GR_rpg1_ief( +Word16 adapt_GR_rpg1_ief_fx( const Word16 *in, /* i : res pred gains input vector */ Word16 *in_diff, /* o : encoded symbols in case of differential encoding */ const Word16 *prev, /* i : previous frame data */ @@ -254,13 +253,13 @@ Word16 adapt_GR_rpg1_ief( } ELSE { - GR_ord = adapt_GR_sg( in, len, no_symb, nbits, in_enc, maps, no_GR_ord ); + GR_ord = adapt_GR_sg_fx( in, len, no_symb, nbits, in_enc, maps, no_GR_ord ); } IF( try_diff ) { - calculate_diff( in, prev, in_diff, len ); - nb_diff = calculate_bit_diff( in_diff, len, &flag_diff ); + calculate_diff_fx( in, prev, in_diff, len ); + nb_diff = calculate_bit_diff_fx( in_diff, len, &flag_diff ); *nbits_diff = nb_diff; move16(); @@ -283,13 +282,13 @@ Word16 adapt_GR_rpg1_ief( /*---------------------------------------------------------------------* - * adapt_GR_sg() + * adapt_GR_sg_fx() * * adaptive GR coding *---------------------------------------------------------------------*/ /*! r: GR order */ -static Word16 adapt_GR_sg( +static Word16 adapt_GR_sg_fx( const Word16 *in, /* i : data to be encoded */ const Word16 len, /* i : number of params to be encoded */ const Word16 no_symb, /* i : max number of symbols */ @@ -411,13 +410,13 @@ static Word16 adapt_GR_sg( /*---------------------------------------------------------------------* - * write_GR0() + * write_GR0_fx() * * write data with GR order 0 *---------------------------------------------------------------------*/ /*! r: number of bits written */ -Word16 write_GR0( +Word16 write_GR0_fx( BSTR_ENC_HANDLE hBstr, /* i/o: Encoder bitstream handle */ const Word16 ind, /* i : bitstream index */ const Word16 *in, /* i : data to be encoded */ @@ -452,13 +451,13 @@ Word16 write_GR0( /*---------------------------------------------------------------------* - * write_GR1() + * write_GR1_fx() * * write data with GR order 1 *---------------------------------------------------------------------*/ /*! r: number of bits written */ -Word16 write_GR1( +Word16 write_GR1_fx( BSTR_ENC_HANDLE hBstr, /* i/o: Encoder bitstream handle */ const Word16 ind, /* i : bitstream index */ const Word16 *in, /* i : data to be encoded */ @@ -496,13 +495,13 @@ Word16 write_GR1( /*---------------------------------------------------------------------* - * write_GR2() + * write_GR2_fx() * * write data with GR order 2 *---------------------------------------------------------------------*/ /*! r: number of bits written */ -static Word16 write_GR2( +static Word16 write_GR2_fx( BSTR_ENC_HANDLE hBstr, /* i/o: bitstream handle */ const Word16 ind, /* i : bitstream index */ const Word16 *in, /* i : data to be encoded */ @@ -543,13 +542,13 @@ static Word16 write_GR2( /*---------------------------------------------------------------------* - * write_bitstream_GR() + * write_bitstream_GR_fx() * * generic GR encoder for GR order 0 or 1 *---------------------------------------------------------------------*/ /*! r: number of bits written */ -Word16 write_bitstream_GR( +Word16 write_bitstream_GR_fx( BSTR_ENC_HANDLE hBstr, /* i/o: Encoder bitstream handle */ const Word16 ind, /* i : bitstream index */ const Word16 *in, /* i : input vector */ @@ -566,11 +565,11 @@ Word16 write_bitstream_GR( IF( GR_ord == 0 ) { - nb = add( nb, write_GR0( hBstr, ind, in, len ) ); + nb = add( nb, write_GR0_fx( hBstr, ind, in, len ) ); } ELSE { - nb = add( nb, write_GR1( hBstr, ind, in, len ) ); + nb = add( nb, write_GR1_fx( hBstr, ind, in, len ) ); } return nb; @@ -578,13 +577,13 @@ Word16 write_bitstream_GR( /*---------------------------------------------------------------------* - * write_bitstream_adapt_GR() + * write_bitstream_adapt_GR_fx() * * write encoded data using adaptive GR *---------------------------------------------------------------------*/ /*! r: number of bits written */ -Word16 write_bitstream_adapt_GR( +Word16 write_bitstream_adapt_GR_fx( BSTR_ENC_HANDLE hBstr, /* i/o: Encoder bitstream handle */ const Word16 ind, /* i : bitstream index */ const Word16 *in, /* i : values to be written in bitstream */ @@ -596,8 +595,9 @@ Word16 write_bitstream_adapt_GR( Word16 nb; nb = 0; + move16(); /* first component first */ - nb = add( nb, write_GR1( hBstr, ind, in, 1 ) ); + nb = add( nb, write_GR1_fx( hBstr, ind, in, 1 ) ); /* write the GR order */ IF( EQ_16( no_GR_ord, 2 ) ) @@ -622,17 +622,17 @@ Word16 write_bitstream_adapt_GR( IF( GR_ord == 0 ) { - nb = add( nb, write_GR0( hBstr, ind, &in[1], sub( len, 1 ) ) ); + nb = add( nb, write_GR0_fx( hBstr, ind, &in[1], sub( len, 1 ) ) ); } ELSE { IF( EQ_16( GR_ord, 1 ) ) { - nb = add( nb, write_GR1( hBstr, ind, &in[1], sub( len, 1 ) ) ); + nb = add( nb, write_GR1_fx( hBstr, ind, &in[1], sub( len, 1 ) ) ); } ELSE { - nb = add( nb, write_GR2( hBstr, ind, &in[1], sub( len, 1 ) ) ); + nb = add( nb, write_GR2_fx( hBstr, ind, &in[1], sub( len, 1 ) ) ); } } diff --git a/lib_enc/ivas_stereo_classifier.c b/lib_enc/ivas_stereo_classifier_fx.c similarity index 88% rename from lib_enc/ivas_stereo_classifier.c rename to lib_enc/ivas_stereo_classifier_fx.c index c2e4f350c3d4900bf43ac04cd45f0b7f3afcea8a..3e148a5aeb36fbfe22286463f8f5aa5b1643a9f4 100644 --- a/lib_enc/ivas_stereo_classifier.c +++ b/lib_enc/ivas_stereo_classifier_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other @@ -38,13 +38,11 @@ #endif #include "cnst.h" #include "rom_com.h" -#include "prot.h" -#include "ivas_prot.h" +#include "prot_fx.h" #include "ivas_rom_com.h" #include "ivas_rom_enc.h" #include "ivas_cnst.h" #include "wmc_auto.h" -#include "prot_fx.h" #include "ivas_prot_fx.h" /*-------------------------------------------------------------------* @@ -86,18 +84,18 @@ * Local function prototypes *-------------------------------------------------------------------*/ static void rc_filter_fx( const Word32 x, Word32 *y, const Word16 order, const Word32 tau ); -static void edge_detect( const Word32 *inp, const Word16 len, const Word32 inp_min, const Word32 inp_max, Word16 *edge_str, Word16 *edge_type ); +static void edge_detect_fx( const Word32 *inp, const Word16 len, const Word32 inp_min, const Word32 inp_max, Word16 *edge_str, Word16 *edge_type ); static Word32 redge_detect_fx( const Word32 *inp, const Word16 len, const Word32 inp_min, const Word32 inp_max, Word16 *edge_min_e ); /*-------------------------------------------------------------------* - * Function select_stereo_mode() + * Function select_stereo_mode_fx() * * Select stereo technology based on output of stereo classifiers *-------------------------------------------------------------------*/ /*! r: element mode */ -Word16 select_stereo_mode( +Word16 select_stereo_mode_fx( CPE_ENC_HANDLE hCPE, /* i/o: CPE encoder structure */ const IVAS_FORMAT ivas_format /* i : IVAS format */ ) @@ -130,11 +128,12 @@ Word16 select_stereo_mode( test(); test(); + test(); #ifdef DEBUGGING IF( GE_32( hCPE->element_brate, MIN_BRATE_MDCT_STEREO ) || ( ( ( EQ_16( ivas_format, MASA_FORMAT ) || EQ_16( ivas_format, MASA_ISM_FORMAT ) ) && LT_32( hCPE->element_brate, MASA_STEREO_MIN_BITRATE ) ) ) || ( hCPE->stereo_mode_cmdl == IVAS_CPE_DFT || hCPE->stereo_mode_cmdl == IVAS_CPE_TD ) ) #else - IF( GE_32( hCPE->element_brate, MIN_BRATE_MDCT_STEREO ) || ( ( ( EQ_16( ivas_format, MASA_FORMAT ) || EQ_16( ivas_format, MASA_ISM_FORMAT ) ) && - LT_32( hCPE->element_brate, MASA_STEREO_MIN_BITRATE ) ) ) ) + if ( GE_32( hCPE->element_brate, MIN_BRATE_MDCT_STEREO ) || ( ( ( EQ_16( ivas_format, MASA_FORMAT ) || EQ_16( ivas_format, MASA_ISM_FORMAT ) ) && + LT_32( hCPE->element_brate, MASA_STEREO_MIN_BITRATE ) ) ) ) #endif { stereo_switching_flag = 0; @@ -161,7 +160,8 @@ Word16 select_stereo_mode( test(); test(); test(); - IF( EQ_16( stereo_switching_flag, 1 ) && GT_32( hCPE->element_brate, IVAS_13k2 ) && LT_16( hCPE->hCoreCoder[0]->hSpMusClas->past_dlp_fx[0], ONE_IN_Q9 ) && LT_32( hCPE->hCoreCoder[0]->hSpMusClas->wdlp_xtalk_fx, -5243 /* -0.01 in Q19*/ ) && EQ_16( hCPE->hCoreCoder[0]->vad_flag, 1 ) && ( hCPE->hStereoMdct->sw_uncorr || hStereoClassif->xtalk_decision ) ) + test(); + IF( EQ_16( stereo_switching_flag, 1 ) && GT_32( hCPE->element_brate, IVAS_13k2 ) && LT_16( hCPE->hCoreCoder[0]->hSpMusClas->past_dlp_fx[0], ONE_IN_Q9 ) && LT_32( hCPE->hCoreCoder[0]->hSpMusClas->wdlp_xtalk_fx, -335544 /* -0.01 in Q25 */ ) && EQ_16( hCPE->hCoreCoder[0]->vad_flag, 1 ) && ( hCPE->hStereoMdct->sw_uncorr || hStereoClassif->xtalk_decision ) ) { hStereoClassif->lrtd_mode = 1; move16(); @@ -183,7 +183,7 @@ Word16 select_stereo_mode( { test(); test(); - IF( ( EQ_16( ivas_format, MASA_FORMAT ) || EQ_16( ivas_format, MASA_ISM_FORMAT ) ) && LT_32( hCPE->element_brate, MASA_STEREO_MIN_BITRATE ) ) + if ( ( EQ_16( ivas_format, MASA_FORMAT ) || EQ_16( ivas_format, MASA_ISM_FORMAT ) ) && LT_32( hCPE->element_brate, MASA_STEREO_MIN_BITRATE ) ) { element_mode = IVAS_CPE_DFT; move16(); @@ -229,7 +229,7 @@ Word16 select_stereo_mode( test(); IF( hCPE->hStereoTD->prev_fr_LRTD_TD_dec == 0 && GT_16( hCPE->hStereoTD->tdm_FD2LRTD_SW_cnt, 15 ) && GT_16( hCPE->hStereoTD->tdm_last_LRTD_frame_cnt, 3 ) && LT_16( hCPE->hCoreCoder[0]->clas, VOICED_CLAS ) && ( GE_32( hCPE->element_brate, IVAS_16k4 ) || LT_32( hStereoClassif->xtalk_wscore_fx, 21474836 /*0.01f in Q31*/ ) ) ) { - IF( EQ_16( stereo_switching_flag, 1 ) ) + if ( EQ_16( stereo_switching_flag, 1 ) ) { element_mode = IVAS_CPE_DFT; move16(); @@ -241,6 +241,17 @@ Word16 select_stereo_mode( } } +#ifdef DEBUG_FORCE_DIR + if ( hCPE->hCoreCoder[0]->force_dir[0] != '\0' ) + { + dbgread( &element_mode, sizeof( int16_t ), 1, fname( hCPE->hCoreCoder[0]->force_dir, "force_element_mode.enf", -1, -1, -1 ) ); + } + else + { + dbgwrite( &element_mode, sizeof( int16_t ), 1, 1, "res/force_element_mode.enf" ); + } +#endif + IF( NE_16( hCPE->last_element_mode, element_mode ) ) { test(); @@ -365,8 +376,6 @@ void stereo_classifier_init_fx( move16(); set_zero_fx( hStereoClassif->relE_buf_fx, UNCLR_L_RELE ); - hStereoClassif->relE_buf_e = 0; - move16(); set_zero_fx( hStereoClassif->Etot_buf_fx, UNCLR_L_ETOT ); hStereoClassif->e_Etot_buf_fx = 0; move16(); @@ -425,15 +434,12 @@ void stereo_classifier_init_fx( *-----------------------------------------------------------------*/ /* Information on ouputs: hStereoClassif->Etot_buf_fx has expoenent hStereoClassif->e_Etot_buf_fx -hStereoClassif->relE_buf_fx has expoenent hStereoClassif->relE_buf_e hStereoClassif->lsf_ch1_fx has Q1*1.28 hStereoClassif->xtalk_fv_fx has exponent 16 hStereoClassif->voicing_ch1_fx has Q-factor Q15 hStereoClassif->lepsP_ch1_fx has exponent 16 hStereoClassif->Etot_up_fx has exponent hStereoClassif->Etot_up_e hStereoClassif->Etot_dn_fx has exponent hStereoClassif->Etot_dn_e -hStereoClassif->relE_0_1_fx has exponent hStereoClassif->relE_buf_e -hStereoClassif->relE_0_1_LT_fx has exponent hStereoClassif->relE_buf_e hStereoClassif->cor_map_sum_ch1_fx has exponent hStereoClassif->cor_map_sum_ch1_e hStereoClassif->non_sta_ch1_fx has exponent hStereoClassif->non_sta_ch1_e hStereoClassif->sp_div_ch1_fx has exponent sp_div_e @@ -455,9 +461,9 @@ void stereo_classifier_features_ivas_fx( Word32 epsP_fx[], /* i : LP analysis residual energies for each iteration*/ Word16 pitch[], /* i : open-loop pitch values for quantiz. Q0 */ Word16 voicing_fx[], /* i : OL maximum normalized correlation Q15 */ - Word32 cor_map_sum_fx, /* i : speech/music clasif. parameter */ - Word32 non_staX_fx, /* i : unbound non-stationarity for sp/mu clas. */ - Word16 sp_div_fx, /* i : spectral diversity feature */ + Word32 cor_map_sum_fx, /* i : speech/music clasif. parameter Q(31-cor_map_sum_e) */ + Word32 non_staX_fx, /* i : unbound non-stationarity for sp/mu clas. Q(31-non_staX_e) */ + Word16 sp_div_fx, /* i : spectral diversity feature Q(15-sp_div_e) */ const Word16 clas, /* i : signal class */ Word16 epsP_e, /*exponent for epsP_fx */ Word16 cor_map_sum_e, /*exponent for cor_map_sum_fx */ @@ -466,10 +472,11 @@ void stereo_classifier_features_ivas_fx( ) { Word16 i, clas_ch2; - Word16 e_relE_0_1_fx; Word16 ener_e; Word32 lepsP_ch2_fx, ener_l_fx, ener_r_fx; + Word32 L_tmp; + Word16 exp; /* combine VAD flags from both channels */ IF( idchan == 0 ) { @@ -500,12 +507,38 @@ void stereo_classifier_features_ivas_fx( move32(); move16(); /* update Etot_up and Etot_dn based on aEn */ + exp = norm_l( hStereoClassif->ave_ener_L_fx ); + if ( sub( hStereoClassif->ave_ener_L_fx_e, exp ) < 0 ) + { + exp = hStereoClassif->ave_ener_L_fx_e; + move16(); + } + hStereoClassif->ave_ener_L_fx = L_shl( hStereoClassif->ave_ener_L_fx, exp ); + move32(); + hStereoClassif->ave_ener_L_fx_e = sub( hStereoClassif->ave_ener_L_fx_e, exp ); + move16(); + exp = norm_l( hStereoClassif->ave_ener_R_fx ); + if ( sub( hStereoClassif->ave_ener_R_fx_e, exp ) < 0 ) + { + exp = hStereoClassif->ave_ener_R_fx_e; + move16(); + } + hStereoClassif->ave_ener_R_fx = L_shl( hStereoClassif->ave_ener_R_fx, exp ); + move32(); + hStereoClassif->ave_ener_R_fx_e = sub( hStereoClassif->ave_ener_R_fx_e, exp ); + move16(); ener_l_fx = Mpy_32_16_1( BASOP_Util_Log10( L_add( L_shr( hStereoClassif->ave_ener_L_fx, 1 ), L_shr( ONE_IN_Q30, hStereoClassif->ave_ener_L_fx_e ) ), hStereoClassif->ave_ener_L_fx_e + 1 ), 10 << 11 ); /*q21*/ ener_r_fx = Mpy_32_16_1( BASOP_Util_Log10( L_add( L_shr( hStereoClassif->ave_ener_R_fx, 1 ), L_shr( ONE_IN_Q30, hStereoClassif->ave_ener_R_fx_e ) ), hStereoClassif->ave_ener_R_fx_e + 1 ), 10 << 11 ); /*q21*/ ener_e = 10; move16(); + + /*scaling Etot_buf_fx,Etot_up_fx and Etot_dn_fx to exponent ener_e*/ + exp = L_norm_arr( hStereoClassif->Etot_buf_fx, 3 ); + exp = s_min( exp, L_norm_arr( &hStereoClassif->Etot_up_fx, 1 ) ); + exp = s_min( exp, L_norm_arr( &hStereoClassif->Etot_dn_fx, 1 ) ); + Copy32( &hStereoClassif->Etot_buf_fx[0], &hStereoClassif->Etot_buf_fx[1], UNCLR_L_ETOT - 1 ); - IF( GE_16( hStereoClassif->e_Etot_buf_fx, ener_e ) ) + IF( GE_16( sub( hStereoClassif->e_Etot_buf_fx, exp ), ener_e ) ) { hStereoClassif->Etot_buf_fx[0] = L_shl( L_max( 0, L_max( ener_l_fx, ener_r_fx ) ), sub( ener_e, hStereoClassif->e_Etot_buf_fx ) ); /*scaling from q25 to 31-e_Etot_buf_fx*/ move32(); @@ -576,7 +609,7 @@ void stereo_classifier_features_ivas_fx( IF( LT_32( L_shr( hStereoClassif->Etot_up_fx, 1 ), L_add( L_shr( hStereoClassif->Etot_dn_fx, 1 ), L_shl( 20, sub( 30, hStereoClassif->e_Etot_buf_fx ) ) ) ) ) /*right shifted by 1 to avoid avoid overflow in addition*/ { hStereoClassif->Etot_dn_fx = L_shr( hStereoClassif->Etot_dn_fx, 1 ); - scale_sig32( hStereoClassif->Etot_buf_fx, 3, -1 ); + scale_sig32( hStereoClassif->Etot_buf_fx, 3, -1 ); // Q(31-(e_Etot_buf_fx+1)) hStereoClassif->e_Etot_buf_fx = add( hStereoClassif->e_Etot_buf_fx, 1 ); hStereoClassif->Etot_up_fx = L_add( hStereoClassif->Etot_dn_fx, L_shl( 20, sub( 31, hStereoClassif->e_Etot_buf_fx ) ) ); move32(); @@ -585,30 +618,27 @@ void stereo_classifier_features_ivas_fx( } /* normalize Etot to (0,1) */ - e_relE_0_1_fx = sub( 31, hStereoClassif->e_Etot_buf_fx ); - hStereoClassif->relE_0_1_fx = lin_interp32_fx( hStereoClassif->Etot_buf_fx[0], hStereoClassif->Etot_dn_fx, 0, hStereoClassif->Etot_up_fx, L_shr( 1932735283, hStereoClassif->e_Etot_buf_fx /*0.9f exp:Etot_buf_fx*/ ), 1, &e_relE_0_1_fx ); /*e_relE_0_1_fx is ouput exp*/ - e_relE_0_1_fx = sub( 31, e_relE_0_1_fx ); + hStereoClassif->relE_0_1_fx = lin_interp32_fx( hStereoClassif->Etot_buf_fx[0], hStereoClassif->Etot_dn_fx, 0, hStereoClassif->Etot_up_fx, 1932735283 /* 0.9 in Q31 */, 1 ); move32(); /* update relE_buf */ Copy32( &hStereoClassif->relE_buf_fx[0], &hStereoClassif->relE_buf_fx[1], UNCLR_L_RELE - 1 ); - hStereoClassif->relE_0_1_fx = L_shr( hStereoClassif->relE_0_1_fx, sub( hStereoClassif->relE_buf_e, e_relE_0_1_fx ) ); /*scaling down to exponent of e_relE_buf_fx*/ - hStereoClassif->relE_buf_fx[0] = hStereoClassif->relE_0_1_fx; /*scaling down to exponent of e_relE_buf_fx*/ - move32(); + hStereoClassif->relE_buf_fx[0] = hStereoClassif->relE_0_1_fx; move32(); IF( GE_32( hStereoClassif->relE_0_1_fx, hStereoClassif->relE_buf_fx[1] ) ) { - hStereoClassif->relE_0_1_LT_fx = Mpy_32_16_1( hStereoClassif->relE_0_1_LT_fx, 29491 /*0.9f q15*/ ) + Mpy_32_16_1( hStereoClassif->relE_0_1_fx, 3277 /*0.1f q15*/ ); + hStereoClassif->relE_0_1_LT_fx = L_add( Mpy_32_16_1( hStereoClassif->relE_0_1_LT_fx, 29491 /* 0.9f in Q15 */ ), Mpy_32_16_1( hStereoClassif->relE_0_1_fx, 3277 /* 0.1f in Q15 */ ) ); } ELSE { - hStereoClassif->relE_0_1_LT_fx = Mpy_32_16_1( hStereoClassif->relE_0_1_LT_fx, 31129 /*0.95f q15*/ ) + Mpy_32_16_1( hStereoClassif->relE_0_1_fx, 1638 /*0.05f0 q15*/ ); + hStereoClassif->relE_0_1_LT_fx = L_add( Mpy_32_16_1( hStereoClassif->relE_0_1_LT_fx, 31129 /* 0.95f in Q15 */ ), Mpy_32_16_1( hStereoClassif->relE_0_1_fx, 1638 /* 0.05f in Q15 */ ) ); } move32(); /* estimate VAD flag based on relative energy */ - IF( LT_32( hStereoClassif->relE_0_1_LT_fx, L_shr( 214748365, hStereoClassif->relE_buf_e ) ) ) + + IF( LT_32( hStereoClassif->relE_0_1_LT_fx, 214748365 /* 0.1f in Q31 */ ) ) { hStereoClassif->vad_relE = 0; } @@ -628,7 +658,6 @@ void stereo_classifier_features_ivas_fx( Copy( lsf_new_fx, hStereoClassif->lsf_ch1_fx, M ); hStereoClassif->lepsP_ch1_fx = L_shr( L_sub( BASOP_Util_Loge( L_add( epsP_fx[13], L_shr( 21474 /*1e-5*2^31*/, epsP_e ) ), epsP_e ), BASOP_Util_Loge( L_add( epsP_fx[0], L_shr( 21474 /*1e-5*2^31*/, epsP_e ) ), epsP_e ) ), 10 ); /*q15*/ move32(); - move16(); hStereoClassif->xtalk_fv_fx[E_lsf_1] = Mpy_32_16_1( 419430400 /* 1/2.56f in Q30 */, lsf_new_fx[0] ); /*q15*/ hStereoClassif->xtalk_fv_fx[E_lsf_4] = Mpy_32_16_1( 419430400 /* 1/2.56f in Q30 */, lsf_new_fx[3] ); /*q15*/ @@ -720,11 +749,12 @@ void stereo_classifier_features_ivas_fx( hStereoClassif->non_sta_ch1_fx = non_staX_fx; hStereoClassif->non_sta_ch1_e = non_staX_e; hStereoClassif->sp_div_ch1_fx = sp_div_fx; + hStereoClassif->sp_div_ch1_e = sp_div_e; hStereoClassif->xtalk_fv_fx[E_cor_map_sum] = L_shr( cor_map_sum_fx, sub( 16, cor_map_sum_e ) ); /*q15*/ hStereoClassif->xtalk_fv_fx[E_nchar] = L_shr( BASOP_Util_Loge( L_add( L_shr( hStereoClassif->nchar_ch1_fx, 1 ), L_shl( 1, sub( 30, hStereoClassif->nchar_ch1_e ) ) ), add( hStereoClassif->nchar_ch1_e, 1 ) ) /*q25*/, 10 ); /*q15*/ hStereoClassif->xtalk_fv_fx[E_non_sta] = L_shr( non_staX_fx, sub( 16, non_staX_e ) ); /*q15*/ - hStereoClassif->xtalk_fv_fx[E_sp_div] = L_shr( BASOP_Util_Loge( L_deposit_h( add( shr( sp_div_fx, 1 ), shl( 1, sub( 15 - 1, sp_div_e ) ) ) ), add( sp_div_e, 1 ) ), 10 ); /*q15*/ - move32(); + L_tmp = BASOP_Util_Add_Mant32Exp( L_deposit_h( sp_div_fx ), sp_div_e, ONE_IN_Q31, 0, &exp ); + hStereoClassif->xtalk_fv_fx[E_sp_div] = L_shr( BASOP_Util_Loge( L_tmp, exp ), 10 ); /*q15*/ move32(); move32(); move32(); @@ -734,13 +764,19 @@ void stereo_classifier_features_ivas_fx( move16(); move16(); move16(); + move16(); } ELSE { hStereoClassif->xtalk_fv_fx[E_d_cor_map_sum] = L_abs( L_sub( L_shr( hStereoClassif->cor_map_sum_ch1_fx, sub( 16, hStereoClassif->cor_map_sum_ch1_e ) ) /*q15*/, L_shr( cor_map_sum_fx, sub( 16, cor_map_sum_e ) ) /*q15*/ ) ); /*q15*/ hStereoClassif->xtalk_fv_fx[E_d_nchar] = L_abs( L_shr( L_sub( BASOP_Util_Loge( L_add( L_shr( hStereoClassif->nchar_ch1_fx, 1 ), L_shl( 1, sub( 30, hStereoClassif->nchar_ch1_e ) ) ), add( hStereoClassif->nchar_ch1_e, 1 ) ), BASOP_Util_Loge( L_add( L_shr( hStereoClassif->nchar_ch2_fx, 1 ), L_shl( 1, sub( 30, hStereoClassif->nchar_ch2_e ) ) ), add( hStereoClassif->nchar_ch2_e, 1 ) ) ) /*q25*/, 10 ) ); /*q15*/ hStereoClassif->xtalk_fv_fx[E_d_non_sta] = L_abs( L_sub( L_shr( hStereoClassif->non_sta_ch1_fx, sub( 16, hStereoClassif->non_sta_ch1_e ) ) /*q15*/, L_shr( non_staX_fx, sub( 16, non_staX_e ) ) /*q15*/ ) ); /*q15*/ - hStereoClassif->xtalk_fv_fx[E_d_sp_div] = L_abs( L_shr( L_sub( BASOP_Util_Loge( L_deposit_h( add( shr( hStereoClassif->sp_div_ch1_fx, 1 ), shl( 1, sub( 15 - 1, sp_div_e ) ) ) ), add( sp_div_e, 1 ) ), BASOP_Util_Loge( L_deposit_h( add( shr( sp_div_fx, 1 ), shl( 1, sub( 15 - 1, sp_div_e ) ) ) ), add( sp_div_e, 1 ) ) ) /*q25*/, 10 ) ); /*q15*/ + L_tmp = BASOP_Util_Add_Mant32Exp( L_deposit_h( sp_div_fx ), sp_div_e, ONE_IN_Q31, 0, &exp ); + hStereoClassif->xtalk_fv_fx[E_d_sp_div] = L_shr( BASOP_Util_Loge( L_tmp, exp ), 10 ); /*q15*/ + L_tmp = BASOP_Util_Add_Mant32Exp( L_deposit_h( hStereoClassif->sp_div_ch1_fx ), hStereoClassif->sp_div_ch1_e, ONE_IN_Q31, 0, &exp ); + hStereoClassif->xtalk_fv_fx[E_d_sp_div] = L_abs( L_sub( L_shr( BASOP_Util_Loge( L_tmp, exp ), 10 ), hStereoClassif->xtalk_fv_fx[E_d_sp_div] ) ); /*q15*/ + // hStereoClassif->xtalk_fv_fx[E_d_sp_div] = L_abs( L_shr( L_sub( BASOP_Util_Loge( L_deposit_h( add( shr( hStereoClassif->sp_div_ch1_fx, 1 ), shl( 1, sub( 15 - 1, hStereoClassif->sp_div_ch1_e ) ) ) ), add( hStereoClassif->sp_div_ch1_e, 1 ) ), BASOP_Util_Loge( L_deposit_h( add( shr( sp_div_fx, 1 ), shl( 1, sub( 15 - 1, sp_div_e ) ) ) ), add( sp_div_e, 1 ) ) ) /*q25*/, 10 ) ); /*q15*/ + move32(); move32(); move32(); move32(); @@ -883,7 +919,31 @@ void unclr_classifier_td_fx( score = Mpy_32_32( score, hStereoClassif->relE_0_1_fx ); // Q31 /* rising edge detection on relE */ - relE_ST = Mean32( hStereoClassif->relE_buf_fx, UNCLR_L_RELE ); // Q31 + Word32 L_tmp = 0, tmp32; + move32(); + Word16 L_tmp_e = 0, flag = 0; + move16(); + move16(); + tmp32 = hStereoClassif->relE_buf_fx[0]; + FOR( i = 0; i < UNCLR_L_RELE; i++ ) + { + L_tmp = BASOP_Util_Add_Mant32Exp( L_tmp, L_tmp_e, hStereoClassif->relE_buf_fx[i], 0, &L_tmp_e ); + IF( NE_32( tmp32, hStereoClassif->relE_buf_fx[i] ) ) + { + flag = 1; + move16(); + } + } + IF( EQ_16( flag, 1 ) ) + { + relE_ST = L_shl( Mpy_32_32( L_tmp, ONE_BY_UNCLR_L_RELE_Q31 ), L_tmp_e ); // Q31 + } + ELSE + { + relE_ST = hStereoClassif->relE_buf_fx[0]; + move16(); + } + IF( hStereoClassif->relE_0_1_fx > relE_ST ) { rc_filter_fx( hStereoClassif->relE_0_1_fx, hStereoClassif->unclr_relE_0_1_LT_fx, UNCLR_RC_ORDER, RC_FACT_UP_Q31 ); @@ -906,13 +966,23 @@ void unclr_classifier_td_fx( test(); test(); test(); - if ( ( ( hStereoClassif->unclr_decision == 0 && GT_32( hStereoClassif->unclr_wscore_fx, 214748365 /*0.1f in Q31*/ ) ) || ( EQ_16( hStereoClassif->unclr_decision, 1 ) && LT_32( hStereoClassif->unclr_wscore_fx, 150323855 /*-0.07f in Q31*/ ) ) ) && ( hStereoClassif->unclr_sw_enable_cnt[0] > 0 || hStereoClassif->unclr_sw_enable_cnt[1] > 0 ) ) + if ( ( ( hStereoClassif->unclr_decision == 0 && GT_32( hStereoClassif->unclr_wscore_fx, 214748365 /*0.1f in Q31*/ ) ) || ( EQ_16( hStereoClassif->unclr_decision, 1 ) && LT_32( hStereoClassif->unclr_wscore_fx, -150323855 /*-0.07f in Q31*/ ) ) ) && ( hStereoClassif->unclr_sw_enable_cnt[0] > 0 || hStereoClassif->unclr_sw_enable_cnt[1] > 0 ) ) { /* let's switch the binary decision */ hStereoClassif->unclr_decision = !hStereoClassif->unclr_decision; move16(); } +#ifdef DEBUG_FORCE_DIR + if ( hCPE->hCoreCoder[0]->force_dir[0] != '\0' ) + { + dbgread( &hStereoClassif->unclr_decision, sizeof( int16_t ), 1, fname( hCPE->hCoreCoder[0]->force_dir, "force_unclr_decision.enf", -1, -1, -1 ) ); + } + else + { + dbgwrite( &hStereoClassif->unclr_decision, sizeof( int16_t ), 1, 1, "res/force_unclr_decision.enf" ); + } +#endif return; } @@ -985,7 +1055,32 @@ void unclr_classifier_dft_fx( /* rising edge detector on relE */ // relE_ST = mean(hStereoClassif->relE_buf, UNCLR_L_RELE); - relE_ST = Mean32( hStereoClassif->relE_buf_fx, UNCLR_L_RELE ); // Q31 + Word32 L_tmp = 0, tmp32; + move32(); + Word16 L_tmp_e = 0, flag = 0; + move16(); + move16(); + tmp32 = hStereoClassif->relE_buf_fx[0]; + move32(); + FOR( i = 0; i < UNCLR_L_RELE; i++ ) + { + L_tmp = BASOP_Util_Add_Mant32Exp( L_tmp, L_tmp_e, hStereoClassif->relE_buf_fx[i], 0, &L_tmp_e ); + IF( NE_32( tmp32, hStereoClassif->relE_buf_fx[i] ) ) + { + flag = 1; + move16(); + } + } + IF( EQ_16( flag, 1 ) ) + { + relE_ST = L_shl( Mpy_32_32( L_tmp, ONE_BY_UNCLR_L_RELE_Q31 ), L_tmp_e ); // Q31 + } + ELSE + { + relE_ST = hStereoClassif->relE_buf_fx[0]; + move16(); + } + IF( GT_32( hStereoClassif->relE_0_1_fx, relE_ST ) ) { // rc_filter(hStereoClassif->relE_0_1, hStereoClassif->unclr_relE_0_1_LT, UNCLR_RC_ORDER, RC_FACT_UP); @@ -1020,6 +1115,16 @@ void unclr_classifier_dft_fx( move16(); } +#ifdef DEBUG_FORCE_DIR + if ( hCPE->hCoreCoder[0]->force_dir[0] != '\0' ) + { + dbgread( &hStereoClassif->unclr_decision, sizeof( int16_t ), 1, fname( hCPE->hCoreCoder[0]->force_dir, "force_unclr_decision.enf", -1, -1, -1 ) ); + } + else + { + dbgwrite( &hStereoClassif->unclr_decision, sizeof( int16_t ), 1, 1, "res/force_unclr_decision.enf" ); + } +#endif return; } @@ -1126,7 +1231,7 @@ void xtalk_classifier_td_fx( /* test rising edge (use 0 as edge_type because of newer->older buffer samples ordering) */ edge_type = 0; move16(); - edge_detect( hStereoClassif->xtalk_score_buf_fx, XTALK_SCORE_BUF_LEN, -53687091 /*-0.2f Q28*/, ONE_IN_Q28, &edge, &edge_type ); + edge_detect_fx( hStereoClassif->xtalk_score_buf_fx, XTALK_SCORE_BUF_LEN, -53687091 /*-0.2f Q28*/, ONE_IN_Q28, &edge, &edge_type ); test(); IF( edge_type == 0 && LT_16( edge, 9830 /*0.3f Q15*/ ) ) @@ -1161,6 +1266,8 @@ void xtalk_classifier_td_fx( /* binary decision w. hysteresis (switch the decision only when coder_type is GC, UC or IC) */ test(); test(); + test(); + test(); if ( ( hStereoClassif->unclr_decision == 0 && hStereoClassif->xtalk_decision == 0 && GT_32( hStereoClassif->xtalk_wscore_fx, 64424509 /*0.03f Q31*/ ) ) /*|| (hStereoClassif->xtalk_decision == 1 && hStereoClassif->xtalk_wscore < 0.00f)*/ && ( hStereoClassif->unclr_sw_enable_cnt[0] > 0 || hStereoClassif->unclr_sw_enable_cnt[1] > 0 ) ) { /* let's switch the binary decision */ @@ -1168,6 +1275,17 @@ void xtalk_classifier_td_fx( move16(); } +#ifdef DEBUG_FORCE_DIR + if ( hCPE->hCoreCoder[0]->force_dir[0] != '\0' ) + { + dbgread( &hStereoClassif->xtalk_decision, sizeof( int16_t ), 1, fname( hCPE->hCoreCoder[0]->force_dir, "force_xtalk_decision.enf", -1, -1, -1 ) ); + } + else + { + dbgwrite( &hStereoClassif->xtalk_decision, sizeof( int16_t ), 1, 1, "res/force_xtalk_decision.enf" ); + } +#endif + return; } @@ -1195,7 +1313,14 @@ void xtalk_classifier_dft_fx( Word64 W_tmp; hStereoClassif = hCPE->hStereoClassif; - hItd = ( hCPE->hStereoDft != NULL ) ? hCPE->hStereoDft->hItd : hCPE->hStereoMdct->hItd; + IF( hCPE->hStereoDft != NULL ) + { + hItd = hCPE->hStereoDft->hItd; + } + ELSE + { + hItd = hCPE->hStereoMdct->hItd; + } m1 = 0; move32(); @@ -1221,7 +1346,7 @@ void xtalk_classifier_dft_fx( m2 = L_abs( gcc_phat[0] ); itd2 = -XTALK_PHAT_LEN; move16(); - FOR( i = 1; i < sub( XTALK_PHAT_LEN, thr ); i++ ) + FOR( i = 1; i < ( XTALK_PHAT_LEN - thr ); i++ ) { IF( GT_32( L_abs( gcc_phat[i] ), m2 ) ) { @@ -1235,7 +1360,7 @@ void xtalk_classifier_dft_fx( m1 = L_abs( gcc_phat[itd + XTALK_PHAT_LEN] ); m2 = L_abs( gcc_phat[XTALK_PHAT_LEN + thr + 1] ); itd2 = add( thr, 1 ); - FOR( i = add( XTALK_PHAT_LEN + 2, thr ); i < 2 * XTALK_PHAT_LEN + 1; i++ ) + FOR( i = ( XTALK_PHAT_LEN + 2 + thr ); i < 2 * XTALK_PHAT_LEN + 1; i++ ) { IF( GT_32( L_abs( gcc_phat[i] ), m2 ) ) { @@ -1323,7 +1448,7 @@ void xtalk_classifier_dft_fx( /* rising edge detector on raw score -> yields 1 if strong rising edge is detected in the given buffer */ Copy32( &hStereoClassif->xtalk_score_buf_fx[0], &hStereoClassif->xtalk_score_buf_fx[1], XTALK_SCORE_BUF_LEN - 1 ); hStereoClassif->xtalk_score_buf_fx[0] = score; - + move32(); minimum_l( hStereoClassif->xtalk_score_buf_fx, XTALK_SCORE_BUF_LEN, &scr_min ); maximum_l( hStereoClassif->xtalk_score_buf_fx, XTALK_SCORE_BUF_LEN, &scr_max ); @@ -1388,7 +1513,6 @@ void xtalk_classifier_dft_fx( move16(); } - /* updates */ hItd->prev_m1_fx = m1; move32(); @@ -1399,6 +1523,17 @@ void xtalk_classifier_dft_fx( hItd->prev_itd2 = itd2; move16(); +#ifdef DEBUG_FORCE_DIR + if ( hCPE->hCoreCoder[0]->force_dir[0] != '\0' ) + { + dbgread( &hStereoClassif->xtalk_decision, sizeof( int16_t ), 1, fname( hCPE->hCoreCoder[0]->force_dir, "force_xtalk_decision.enf", -1, -1, -1 ) ); + } + else + { + dbgwrite( &hStereoClassif->xtalk_decision, sizeof( int16_t ), 1, 1, "res/force_xtalk_decision.enf" ); + } +#endif + return; } @@ -1427,14 +1562,14 @@ static void rc_filter_fx( } /*-------------------------------------------------------------------* - * Function edge_detect() + * Function edge_detect_fx() * * Rising/falling edge detection algorithm * Analyzes the input buffer and outputs strength and type of the detected edge (rising or falling) * Set edge_type to 0/1/2 when calling this function to specify the edge type you want to detect. The returned value will be modified * according to the edge type detected (-1 indicates that no edge has been detected) *-------------------------------------------------------------------*/ -static void edge_detect( +static void edge_detect_fx( const Word32 *inp, /* i : input buffer Q31*/ const Word16 len, /* i : length of the input buffer Q0*/ const Word32 inp_min, /* i : minimum value for edge detection Q28*/ @@ -1562,7 +1697,11 @@ static void edge_detect( } } +#ifndef FIX_1297_OVERFLOW *edge_str = extract_l( L_shr( edge_min, 10 ) ); // Q15 +#else + *edge_str = extract_h( L_shl_sat( edge_min, 16 - 10 ) ); // Q15 +#endif move16(); *edge_type = et; // Q0 move16(); @@ -1579,10 +1718,10 @@ static void edge_detect( /*! r: rising edge strength normalized to 0-1 */ static Word32 redge_detect_fx( - const Word32 *inp, /* i : input buffer (ordered from newest to oldest values)*/ + const Word32 *inp, /* i : input buffer (ordered from newest to oldest values) Q31*/ const Word16 len, /* i : length of the input buffer */ - const Word32 inp_min, /* i : minimum value for edge detection */ - const Word32 inp_max, /* i : maximum value for edge detection */ + const Word32 inp_min, /* i : minimum value for edge detection Q31 */ + const Word32 inp_max, /* i : maximum value for edge detection Q31 */ Word16 *edge_min_e ) { Word16 i, j; diff --git a/lib_enc/ivas_stereo_cng_enc.c b/lib_enc/ivas_stereo_cng_enc_fx.c similarity index 98% rename from lib_enc/ivas_stereo_cng_enc.c rename to lib_enc/ivas_stereo_cng_enc_fx.c index 0a3c84b1e77b3196498aa7765831a300a8c75356..aa7c2d0aa6d1211a5724d95e60d69deaacbfac59 100644 --- a/lib_enc/ivas_stereo_cng_enc.c +++ b/lib_enc/ivas_stereo_cng_enc_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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,12 +36,10 @@ #include "cnst.h" #include "rom_enc.h" #include "rom_com.h" -#include "prot.h" -#include "ivas_prot.h" +#include "prot_fx.h" #include "ivas_cnst.h" #include "ivas_rom_com.h" #include "wmc_auto.h" -#include "prot_fx.h" #include "ivas_prot_fx.h" @@ -109,11 +107,11 @@ void stereo_dft_enc_sid_calc_coh_fx( xspec_scale = Sqrt32( L_tmp3, &L_tmp3_e ); // xspec_scale = L_shl(xspec_scale, L_tmp3_e);//Q31 - hStereoDft->xspec_smooth_fx[2 * k] = Mpy_32_32( hStereoDft->xspec_smooth_fx[2 * k], xspec_scale ); + hStereoDft->xspec_smooth_fx[2 * k] = Mpy_32_32( hStereoDft->xspec_smooth_fx[2 * k], xspec_scale ); // Q(31-(xspec_smooth_fx_e+tmp3_e)) move32(); hStereoDft->xspec_smooth_fx_e[2 * k] = add( hStereoDft->xspec_smooth_fx_e[2 * k], L_tmp3_e ); move16(); - hStereoDft->xspec_smooth_fx[2 * k + 1] = Mpy_32_32( hStereoDft->xspec_smooth_fx[2 * k + 1], xspec_scale ); + hStereoDft->xspec_smooth_fx[2 * k + 1] = Mpy_32_32( hStereoDft->xspec_smooth_fx[2 * k + 1], xspec_scale ); // Q(31-(xspec_smooth_fx_e+tmp3_e)) move32(); hStereoDft->xspec_smooth_fx_e[2 * k + 1] = add( hStereoDft->xspec_smooth_fx_e[2 * k + 1], L_tmp3_e ); move16(); @@ -231,10 +229,10 @@ void stereo_dft_enc_sid_calc_coh_fx( void stereo_dft_enc_sid_coh_fx( BSTR_ENC_HANDLE hBstr, /* i/o: bitstream handle */ - Word32 *mem_cohBand, /* i/o: Coherence memory */ + Word32 *mem_cohBand, /* i/o: Coherence memory Q31 */ const Word16 nbands, /* i : number of DFT stereo bands */ Word16 *nb_bits, /* i/o: number of bits written */ - Word32 *cohBand /* i/o: Coherence per band */ + Word32 *cohBand /* i/o: Coherence per band Q31 */ ) { Word16 b, k; @@ -384,7 +382,7 @@ void stereo_dft_enc_sid_coh_fx( alphaptr = &dft_cng_alpha_bits_fx[alpha_step][alpha_level]; pptr = dft_cng_coh_pred_fx[coh_pred_index]; /* Set pointer to selected predictor */ pred = 3277 /*0.4f in Q13*/; - + move16(); FOR( b = 0; b < nbands; b++ ) { /* Intra-frame prediction using quantized values */ @@ -411,7 +409,7 @@ void stereo_dft_enc_sid_coh_fx( /* Write residual index to bitstream */ IF( LE_16( add( add( res_index, 1 ), *nb_bits ), nr_of_sid_stereo_bits ) ) /* If the bit limit is reached, res_index = 0 is assumed for remaining indices */ { - *nb_bits = add( *nb_bits, write_GR0( hBstr, IND_STEREO_DFT_SID_COH, &res_index, 1 ) ); + *nb_bits = add( *nb_bits, write_GR0_fx( hBstr, IND_STEREO_DFT_SID_COH, &res_index, 1 ) ); move16(); } @@ -429,7 +427,7 @@ void stereo_dft_enc_sid_coh_fx( move16(); } - mem_cohBand[b] = L_deposit_h( cohBandq[b] ); /* Update memory for next frame */ + mem_cohBand[b] = L_deposit_h( cohBandq[b] ); /* Update memory for next frame Q31*/ move32(); pred = 0; move16(); @@ -658,7 +656,7 @@ void stereo_cng_upd_counters_fx( STEREO_CNG_ENC_HANDLE hStereoCng, /* i/o: Stereo CNG data structure */ const Word32 element_mode, /* i : element mode */ const Word16 nbands, /* i : Number of bands in active */ - const Word32 sidSideGain[], /* i : SID side gains */ + const Word32 sidSideGain[], /* i : SID side gains Q31 */ const Word16 burst_ho_count, /* i : Hang-over count */ Word16 *coh_fade_counter /* i : Coherence fade counter */ ) diff --git a/lib_enc/ivas_stereo_dft_enc.c b/lib_enc/ivas_stereo_dft_enc_fx.c similarity index 97% rename from lib_enc/ivas_stereo_dft_enc.c rename to lib_enc/ivas_stereo_dft_enc_fx.c index e2b4597653eaf9b59053312cffc747149fcfcc27..3eb6c0e8232af7ddfc96be1a8625e2dddf501b2b 100644 --- a/lib_enc/ivas_stereo_dft_enc.c +++ b/lib_enc/ivas_stereo_dft_enc_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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,10 +37,8 @@ #include "cnst.h" #include "rom_enc.h" #include "rom_com.h" -#include "prot.h" -#include "ivas_prot.h" -#include "ivas_prot_fx.h" #include "prot_fx.h" +#include "ivas_prot_fx.h" #include "ivas_cnst.h" #include "ivas_rom_com.h" #include "ivas_rom_com_fx.h" @@ -737,8 +735,7 @@ void stereo_enc_itd_init_fx( set16_fx( hItd->td_itd_32k, 0, STEREO_DFT_ENC_DFT_NB ); set16_fx( hItd->itd_index, 0, STEREO_DFT_ENC_DFT_NB ); set32_fx( hItd->xcorr_smooth_fx, 0, STEREO_DFT_N_32k_ENC ); - hItd->xcorr_smooth_fx_e = 0; - move16(); + set16_fx( hItd->xcorr_smooth_fx_e, 0, STEREO_DFT_N_32k_ENC ); hItd->lp_phat_peak_fx = 0; move32(); hItd->itd_hangover = 0; @@ -753,6 +750,9 @@ void stereo_enc_itd_init_fx( hItd->prev_xcorr_lb_fx_e = 0; move16(); set32_fx( hItd->E_band_n_fx, ITD_VAD_E_BAND_N_INIT, STEREO_DFT_ITD_VAD_BAND_NUM ); +#ifdef FIX_ISSUE_1092 + set16_fx( hItd->E_band_n_exp, Q31, STEREO_DFT_ITD_VAD_BAND_NUM ); +#endif hItd->vad_frm_cnt = 0; move16(); hItd->pre_vad = 0; @@ -819,7 +819,7 @@ void stereo_dft_enc_update_fx( move32(); /* Update the parameters and serial */ - FOR( i = 0; i < imult1616( k_offset, STEREO_DFT_BAND_MAX ); i++ ) + FOR( i = 0; i < ( k_offset * STEREO_DFT_BAND_MAX ); i++ ) { hStereoDft->side_gain_fx[i] = hStereoDft->side_gain_fx[STEREO_DFT_BAND_MAX + i]; move32(); @@ -884,7 +884,7 @@ void stereo_dft_enc_update_fx( // hStereoDft->res_cod_line_max = (int16_t) ( 0.5f + ( hStereoDft->band_limits[hStereoDft->res_cod_band_max] - 1 ) * 2.f * hStereoDft->N / (float) ( hStereoDft->NFFT ) ); Word32 tmp = L_shl( L_mult0( sub( hStereoDft->band_limits[hStereoDft->res_cod_band_max], 1 ), hStereoDft->N ), 1 ); Word16 exp; - tmp = BASOP_Util_Divide3232_Scale_cadence( tmp, hStereoDft->N, &exp ); + tmp = BASOP_Util_Divide3232_Scale_cadence( tmp, hStereoDft->NFFT, &exp ); hStereoDft->res_cod_line_max = extract_l( L_shr( tmp, sub( 31, exp ) ) ); move16(); // hStereoDft->res_cod_line_max = 8 * (hStereoDft->res_cod_line_max / 8); @@ -937,9 +937,9 @@ void stereo_dft_enc_analyze_fx( const Word16 input_frame, /* i : input frame length */ STEREO_DFT_ENC_DATA_HANDLE hStereoDft, /* i/o: encoder stereo handle */ STEREO_MDCT_ENC_DATA_HANDLE hStereoMdct, /* i/o: encoder MDCT stereo handle */ - Word32 DFT[CPE_CHANNELS][STEREO_DFT_N_MAX_ENC], /* o : DFT buffers */ + Word32 DFT[CPE_CHANNELS][STEREO_DFT_N_MAX_ENC], /* o : DFT buffers Q(31-DFT_e) */ Word16 DFT_e[CPE_CHANNELS], /* o : DFT buffers */ - Word16 *input_mem[CPE_CHANNELS], /* i/o: input buffer memory */ + Word16 *input_mem[CPE_CHANNELS], /* i/o: input buffer memory Q(q_input_mem_ */ Word16 *q_input_mem ) { Word16 i, n; @@ -1011,10 +1011,10 @@ void stereo_dft_enc_analyze_fx( { trigo_enc[i] = pTrigo[i * trigo_step]; move16(); - trigo_enc[sub( shr( NFFT, 1 ), i )] = pTrigo[L_mult0( i, trigo_step )]; + trigo_enc[( ( NFFT / 2 ) - i )] = pTrigo[L_mult0( i, trigo_step )]; move16(); } - trigo_enc[shr( NFFT, 2 )] = pTrigo[L_mult0( shr( NFFT, 2 ), trigo_step )]; + trigo_enc[NFFT / 4] = pTrigo[( ( NFFT / 4 ) * trigo_step )]; move16(); /*Forwards FFT: L and R*/ @@ -1023,42 +1023,42 @@ void stereo_dft_enc_analyze_fx( { pDFT_L[i] = 0; move32(); - pDFT_L[sub( sub( NFFT, 1 ), i )] = 0; + pDFT_L[( ( NFFT - 1 ) - i )] = 0; move32(); pDFT_R[i] = 0; move32(); - pDFT_R[sub( sub( NFFT, 1 ), i )] = 0; + pDFT_R[( ( NFFT - 1 ) - i )] = 0; move32(); } FOR( n = 0; n < n_channels; n++ ) { - Scale_sig( &mem[n][0], dft_ovl, sts[n]->q_inp - q_input_mem[n] ); + Scale_sig( &mem[n][0], dft_ovl, sts[n]->q_inp - q_input_mem[n] ); // Q(sts[n]->q_inp) q_input_mem[n] = sts[n]->q_inp; move16(); } /*overlapping parts*/ FOR( i = 0; i < dft_ovl; i++ ) { - pDFT_L[add( dft_zp, i )] = L_mult0( mem[0][i], pWin[i] ); + pDFT_L[( dft_zp + i )] = L_mult0( mem[0][i], pWin[i] ); move32(); - pDFT_L[sub( add( add( dft_zp, N ), dft_ovl ) - 1, i )] = L_mult0( input[0][sub( add( add( offset, N ), dft_ovl ) - 1, i )], pWin[i] ); + pDFT_L[( ( ( dft_zp + N ) + dft_ovl ) - 1 - i )] = L_mult0( input[0][offset + N + dft_ovl - 1 - i], pWin[i] ); move32(); - pDFT_R[add( dft_zp, i )] = L_mult0( mem[1][i], pWin[i] ); + pDFT_R[dft_zp + i] = L_mult0( mem[1][i], pWin[i] ); move32(); - pDFT_R[sub( add( add( dft_zp, N ), dft_ovl ) - 1, i )] = L_mult0( input[1][sub( add( add( offset, N ), dft_ovl ) - 1, i )], pWin[i] ); + pDFT_R[( ( dft_zp + N ) + dft_ovl ) - 1 - i] = L_mult0( input[1][offset + N + dft_ovl - 1 - i], pWin[i] ); move32(); } /*middle part*/ FOR( i = 0; i < N - dft_ovl; i++ ) { - pDFT_L[add( add( dft_zp, dft_ovl ), i )] = L_shr( L_deposit_h( input[0][add( add( offset, dft_ovl ), i )] ), 1 ); + pDFT_L[dft_zp + dft_ovl + i] = L_shr( L_deposit_h( input[0][offset + dft_ovl + i] ), 1 ); move32(); - pDFT_R[add( add( dft_zp, dft_ovl ), i )] = L_shr( L_deposit_h( input[1][add( add( offset, dft_ovl ), i )] ), 1 ); + pDFT_R[dft_zp + dft_ovl + i] = L_shr( L_deposit_h( input[1][offset + dft_ovl + i] ), 1 ); move32(); } DFT_e[0] = sub( 31, add( 15, sts[0]->q_inp ) ); @@ -1096,13 +1096,14 @@ void stereo_dft_enc_analyze_fx( { mem[n] = &input[n][sub( N, dft_ovl )]; } - + test(); + test(); IF( hStereoDft != NULL && hStereoDft->hConfig->hybrid_itd_flag && hStereoDft->hItd->td_itd[STEREO_DFT_OFFSET] ) { FOR( n = 0; n < n_channels; n++ ) { #ifdef MSAN_FIX - Scale_sig( hStereoDft->input_mem_itd_fx[n], dft_ovl, sub( sts[n]->q_inp, hStereoDft->q_input_mem_itd[n] ) ); + Scale_sig( hStereoDft->input_mem_itd_fx[n], dft_ovl, sub( sts[n]->q_inp, hStereoDft->q_input_mem_itd[n] ) ); // Q(sts[n]->q_inp) #else Scale_sig( hStereoDft->input_mem_itd_fx[n], STEREO_DFT_OVL_MAX, sts[n]->q_inp - hStereoDft->q_input_mem_itd[n] ); #endif // MSAN_FIX @@ -1132,7 +1133,7 @@ void stereo_dft_enc_analyze_fx( Word32 stereo_dft_enc_synthesize_fx( STEREO_DFT_ENC_DATA_HANDLE hStereoDft, /* i/o: encoder stereo handle */ // float *output, /* o : output synthesis */ - Word32 *output_fx, /* o : output synthesis Q16 */ + Word32 *output_fx, /* o : output synthesis Q15 */ Word16 *output_start_index, Word16 *output_end_index, const Word16 chan, /* i : channel number */ @@ -1360,14 +1361,14 @@ Word32 stereo_dft_enc_synthesize_fx( offset = 0; move16(); - FOR( i = 0; i < shr( NFFT, 2 ); i++ ) + FOR( i = 0; i < NFFT / 4; i++ ) { - trigo_enc_fx[i] = trigo_fx[imult1616( i, trigo_step )]; + trigo_enc_fx[i] = trigo_fx[i * trigo_step]; move16(); - trigo_enc_fx[sub( shr( NFFT, 1 ), i )] = trigo_fx[imult1616( i, trigo_step )]; + trigo_enc_fx[( NFFT / 2 ) - i] = trigo_fx[i * trigo_step]; move16(); } - trigo_enc_fx[shr( NFFT, 2 )] = trigo_fx[imult1616( shr( NFFT, 2 ), trigo_step )]; + trigo_enc_fx[NFFT / 4] = trigo_fx[( NFFT / 4 ) * trigo_step]; move16(); /*-----------------------------------------------------------------* @@ -1497,15 +1498,15 @@ Word32 stereo_dft_enc_synthesize_fx( scal_fac = sub( 1, find_guarded_bits_fx( NFFT ) ); scale_sig32( tmp_fx, NFFT, scal_fac ); // Q16 rfft_fx( tmp_fx, trigo_enc_fx, NFFT, +1 ); - Scale_sig32( tmp_fx, NFFT, sub( sub( DFT_in_fx_e, scal_fac ), 15 ) ); // Q16 + Scale_sig32( tmp_fx, NFFT, sub( sub( DFT_in_fx_e, scal_fac ), 16 ) ); // Q15 FOR( i = 0; i < ovl; i++ ) { // output[offset + i] = mem[i] + tmp[zp + i] * win[i]; - output_fx[offset + i] = L_add_sat( mem_fx[i], Mpy_32_32( tmp_fx[zp + i], win_fx[i] ) ); + output_fx[offset + i] = L_add_sat( mem_fx[i], Mpy_32_32( tmp_fx[zp + i], win_fx[i] ) ); // Q15 move32(); // mem[i] = tmp[zp + N + i] * win[ovl - 1 - i]; - mem_fx[i] = Mpy_32_32( tmp_fx[zp + N + i], win_fx[ovl - 1 - i] ); + mem_fx[i] = Mpy_32_32( tmp_fx[zp + N + i], win_fx[ovl - 1 - i] ); // Q15 move32(); } @@ -1513,7 +1514,7 @@ Word32 stereo_dft_enc_synthesize_fx( FOR( i = 0; i < N - ovl; i++ ) { // output_fx[offset + ovl + i] = tmp[zp + ovl + i]; - output_fx[offset + ovl + i] = tmp_fx[zp + ovl + i]; + output_fx[offset + ovl + i] = tmp_fx[zp + ovl + i]; // Q15 move32(); } @@ -1523,13 +1524,13 @@ Word32 stereo_dft_enc_synthesize_fx( FOR( i = 0; i < ovl; i++ ) { - Word32 ifft_deviation = tmp_fx[zp + N + ovl]; + Word32 ifft_deviation = tmp_fx[zp + N + ovl]; // Q15 move32(); // output[offset + N + i] = ( tmp[zp + N + i] - ifft_deviation ) / win_ana[ovl - 1 - i] + ifft_deviation; Word16 L_temp_e; Word32 L_temp = BASOP_Util_Divide3232_Scale_cadence( L_sub_sat( tmp_fx[zp + N + i], ifft_deviation ), L_deposit_h( win_ana_fx[ovl - 1 - i] ), &L_temp_e ); L_temp = L_shl_sat( L_temp, L_temp_e ); - output_fx[offset + N + i] = L_add_sat( L_temp, ifft_deviation ); // Q16 + output_fx[offset + N + i] = L_add_sat( L_temp, ifft_deviation ); // Q15 move32(); } @@ -1629,7 +1630,7 @@ void stereo_dft_enc_process_fx( // hStereoDft->res_cod_line_max = (int16_t) ( 0.5f + ( hStereoDft->band_limits[hStereoDft->res_cod_band_max] - 1 ) * 2.f * input_frame / (float) ( hStereoDft->NFFT ) ); tmp_32fx = L_shl( L_mult0( sub( hStereoDft->band_limits[hStereoDft->res_cod_band_max], 1 ), input_frame ), 1 ); tmp_32fx = BASOP_Util_Divide3216_Scale( tmp_32fx, hStereoDft->NFFT, &tmp_e ); - hStereoDft->res_cod_line_max = extract_l( L_shr_r( tmp_32fx, sub( 31, tmp_e ) ) ); + hStereoDft->res_cod_line_max = extract_l( L_shr_r( tmp_32fx, sub( -1, tmp_e ) ) ); // 15 - (31 - 15 + tmp_e) = -1 - tmp_e move16(); // hStereoDft->res_cod_line_max = 8 * (hStereoDft->res_cod_line_max / 8); hStereoDft->res_cod_line_max = shl( shr( hStereoDft->res_cod_line_max, 3 ), 3 ); @@ -1703,20 +1704,22 @@ void stereo_dft_enc_process_fx( IF( alpha_fx >= 0 ) { + c_fx = shr( c_fx, 1 ); + s_fx = shr( s_fx, 1 ); FOR( i = 1; i < hStereoDft->NFFT / 2; i++ ) { // tmp = s * c1 + c * s1; - tmp_fx = add_sat( mult_r( s_fx, c1_fx ), mult_r( c_fx, s1_fx ) ); // saturation expected + tmp_fx = add( mult_r( s_fx, c1_fx ), mult_r( c_fx, s1_fx ) ); // c = c * c1 - s * s1; - c_fx = sub_sat( mult_r( c_fx, c1_fx ), mult_r( s_fx, s1_fx ) ); // saturation expected + c_fx = sub( mult_r( c_fx, c1_fx ), mult_r( s_fx, s1_fx ) ); s_fx = tmp_fx; move16(); /*time shift of L*/ // tmp = pDFT_L[2 * i] * c - pDFT_L[2 * i + 1] * s; - tmp_32fx = BASOP_Util_Add_Mant32Exp( Mpy_32_16_1( pDFT_L_fx[2 * i], c_fx ), DFT_L_e_tmp[2 * i], L_negate( Mpy_32_16_1( pDFT_L_fx[2 * i + 1], s_fx ) ), DFT_L_e_tmp[2 * i + 1], &tmp_e ); + tmp_32fx = BASOP_Util_Add_Mant32Exp( Mpy_32_16_1( pDFT_L_fx[2 * i], c_fx ), add( DFT_L_e_tmp[2 * i], 1 ), L_negate( Mpy_32_16_1( pDFT_L_fx[2 * i + 1], s_fx ) ), add( DFT_L_e_tmp[2 * i + 1], 1 ), &tmp_e ); // pDFT_L[2 * i + 1] = pDFT_L[2 * i] * s + pDFT_L[2 * i + 1] * c; - pDFT_L_fx[2 * i + 1] = BASOP_Util_Add_Mant32Exp( Mpy_32_16_1( pDFT_L_fx[2 * i], s_fx ), DFT_L_e_tmp[2 * i], Mpy_32_16_1( pDFT_L_fx[2 * i + 1], c_fx ), DFT_L_e_tmp[2 * i + 1], &DFT_L_e_tmp[2 * i + 1] ); + pDFT_L_fx[2 * i + 1] = BASOP_Util_Add_Mant32Exp( Mpy_32_16_1( pDFT_L_fx[2 * i], s_fx ), add( DFT_L_e_tmp[2 * i], 1 ), Mpy_32_16_1( pDFT_L_fx[2 * i + 1], c_fx ), add( DFT_L_e_tmp[2 * i + 1], 1 ), &DFT_L_e_tmp[2 * i + 1] ); move32(); // pDFT_L[2 * i] = tmp; pDFT_L_fx[2 * i] = tmp_32fx; @@ -1859,8 +1862,28 @@ void stereo_dft_enc_process_fx( IF( pgIpd[0] != 0 ) { - c_fx = shl_sat( getCosWord16( (Word16) pgIpd[0] ), 1 ); // Q15 saturation expected - s_fx = getSinWord16( (Word16) pgIpd[0] ); // Q15 + Word32 theta = pgIpd[0]; + WHILE( GT_32( theta, EVS_2PI_FX ) ) + { + theta = L_sub( theta, EVS_2PI_FX ); /* Q13 */ + } + WHILE( LT_32( theta, -EVS_2PI_FX ) ) + { + theta = L_add( theta, EVS_2PI_FX ); /* Q13 */ + } + + IF( GT_32( theta, MAX_16 ) ) + { + theta = L_sub( theta, EVS_2PI_FX ); /* Q13 */ + } + ELSE IF( LT_32( theta, MIN_16 ) ) + { + theta = L_add( theta, EVS_2PI_FX ); /* Q13 */ + } + + c_fx = shl_sat( getCosWord16( extract_l( theta ) ), 1 ); + s_fx = getSinWord16( extract_l( theta ) ); + FOR( i = hStereoDft->band_limits_dmx[b]; i < hStereoDft->band_limits_dmx[b + 1]; i++ ) { /*rotate L*/ @@ -2413,7 +2436,7 @@ void stereo_dft_enc_process_fx( } FOR( i = 0; i < STEREO_DFT_N_MAX_ENC; i++ ) { - DFT_DMX[i] = L_shr_r( DFT_DMX[i], sub( max_exp, DFT_DMX_e[i] ) ); + DFT_DMX[i] = L_shr_r( DFT_DMX[i], sub( max_exp, DFT_DMX_e[i] ) ); // Q(31-max_exp) move32(); } hStereoDft->DFT_fx_e[0] = max_exp; @@ -2427,7 +2450,7 @@ void stereo_dft_enc_process_fx( } FOR( i = 0; i < STEREO_DFT_N_8k_ENC; i++ ) { - DFT_RES[i] = L_shr_r( DFT_RES[i], sub( max_exp, DFT_RES_e[i] ) ); + DFT_RES[i] = L_shr_r( DFT_RES[i], sub( max_exp, DFT_RES_e[i] ) ); // Q(31-max_exp) move32(); } hStereoDft->DFT_fx_e[1] = max_exp; @@ -2675,7 +2698,7 @@ static void stereo_dft_enc_get_res_cod_mode_flag_fx( void stereo_dft_enc_res_fx( STEREO_DFT_ENC_DATA_HANDLE hStereoDft, /* i/o: encoder stereo handle */ - const Word32 *input_8k, /* i : input buffer sampled at 8kHz Q16 */ + const Word32 *input_8k, /* i : input buffer sampled at 8kHz Q15 */ BSTR_ENC_HANDLE hBstr, /* i/o: bitstream handle */ Word16 *nb_bits, /* o : number of bits written */ const Word16 max_bits ) @@ -2720,7 +2743,7 @@ void stereo_dft_enc_res_fx( /* MDCT analysis */ // TCX_MDCT_flt( win, MDCT_RES, STEREO_DFT_OVL_8k, L_FRAME8k - STEREO_DFT_OVL_8k, STEREO_DFT_OVL_8k, IVAS_CPE_DFT ); - MDCT_RES_e = 16; + MDCT_RES_e = 17; move16(); TCX_MDCT( win, MDCT_RES, &MDCT_RES_e, STEREO_DFT_OVL_8k, L_FRAME8k - STEREO_DFT_OVL_8k, STEREO_DFT_OVL_8k, IVAS_CPE_DFT ); @@ -2746,7 +2769,7 @@ void stereo_dft_enc_res_fx( // in_phase_ratio = check_bounds(in_phase_ratio, 0, 1); // res_cod_gain[b] = in_phase_ratio * STEREO_DFT_RES_COD_SNR_MIN + ( 1 - in_phase_ratio ) * STEREO_DFT_RES_COD_SNR_MAX; - res_cod_gain[b] = L_add( Mpy_32_32( in_phase_ratio, STEREO_DFT_RES_COD_SNR_MIN_Q25 ), Mpy_32_32( L_sub( MAX_32, in_phase_ratio ), STEREO_DFT_RES_COD_SNR_MAX ) ); // Q25 + res_cod_gain[b] = L_add( Mpy_32_32( in_phase_ratio, STEREO_DFT_RES_COD_SNR_MIN_Q25 ), Mpy_32_32( L_sub( MAX_32, in_phase_ratio ), STEREO_DFT_RES_COD_SNR_MAX_Q25 ) ); // Q25 move32(); /*get the maximum through bands*/ @@ -2772,7 +2795,7 @@ void stereo_dft_enc_res_fx( push_wmops( "residual_encode" ); /* residual encoding */ ECSQ_init_instance_fx( &ecsq_inst, 0 /*dummy index*/, &range_uni_enc_state ); - rc_uni_enc_init( &range_uni_enc_state ); + rc_uni_enc_init_fx( &range_uni_enc_state ); ecsq_inst.bit_count_estimate = 0; move32(); @@ -2783,7 +2806,7 @@ void stereo_dft_enc_res_fx( ECSQ_encode_target_SNR_fx( &ecsq_inst, MDCT_RES, MDCT_RES_e, hStereoDft->res_cod_line_max, max_snr, max_bits - ( *nb_bits ) - STEREO_DFT_RES_GLOBAL_GAIN_BITS - 2 - 8, NULL, &global_gain_index ); IF( NE_16( global_gain_index, ECSQ_GLOBAL_GAIN_INDEX_ALL_ZERO ) ) { - total_bit_count = rc_uni_enc_finish( &range_uni_enc_state ); + total_bit_count = rc_uni_enc_finish_fx( &range_uni_enc_state ); IF( LE_16( total_bit_count, sub( sub( max_bits, *nb_bits ), STEREO_DFT_RES_GLOBAL_GAIN_BITS ) ) ) { @@ -2866,7 +2889,7 @@ void stereo_dft_enc_write_BS_fx( sp_aud_decision0 = 0; move16(); - IF( EQ_16( hCPE->last_element_mode, IVAS_CPE_DFT ) ) + if ( EQ_16( hCPE->last_element_mode, IVAS_CPE_DFT ) ) { sp_aud_decision0 = hCPE->hCoreCoder[0]->sp_aud_decision0; move16(); @@ -2881,7 +2904,7 @@ void stereo_dft_enc_write_BS_fx( move16(); test(); - IF( EQ_32( core_brate, FRAME_NO_DATA ) || EQ_32( core_brate, SID_2k40 ) ) + IF( ( core_brate == FRAME_NO_DATA ) || EQ_32( core_brate, SID_2k40 ) ) { NFFT_inner = s_min( STEREO_DFT_N_32k_ENC, STEREO_DFT_N_MAX_ENC * inner_frame_tbl[hCPE->hCoreCoder[0]->bwidth] / L_FRAME48k ); hStereoDft->band_res[k_offset] = hStereoDft->hConfig->band_res; @@ -2901,7 +2924,7 @@ void stereo_dft_enc_write_BS_fx( hStereoDft->nbands = stereo_dft_band_config_fx( hStereoDft->band_limits, hStereoDft->band_res[k_offset], NFFT_inner, ENC ); move16(); - IF( EQ_32( core_brate, FRAME_NO_DATA ) ) + IF( core_brate == FRAME_NO_DATA ) { /* No data frame */ ( *nb_bits ) = 0; @@ -3035,11 +3058,11 @@ void stereo_dft_enc_write_BS_fx( IF( hStereoDft->side_gain_flag_1 == 0 ) { - nb = add( nb, write_bitstream_adapt_GR( hBstr, IND_STEREO_DFT_SIDEGAINS, encoded_ind_GR, hStereoDft->nbands, hStereoDft->side_gain_flag_2, no_GR_ord ) ); + nb = add( nb, write_bitstream_adapt_GR_fx( hBstr, IND_STEREO_DFT_SIDEGAINS, encoded_ind_GR, hStereoDft->nbands, hStereoDft->side_gain_flag_2, no_GR_ord ) ); } ELSE{ IF( EQ_16( hStereoDft->side_gain_flag_1, 2 ) ){ - nb = add( nb, write_bitstream_GR( hBstr, IND_STEREO_DFT_SIDEGAINS, hStereoDft->side_gain_index_ECDiff, hStereoDft->nbands, hStereoDft->side_gain_flag_2 - no_GR_ord ) ); + nb = add( nb, write_bitstream_GR_fx( hBstr, IND_STEREO_DFT_SIDEGAINS, hStereoDft->side_gain_index_ECDiff, hStereoDft->nbands, hStereoDft->side_gain_flag_2 - no_GR_ord ) ); } ELSE { @@ -3208,18 +3231,18 @@ IF( hStereoDft->res_pred_mode[k_offset] ) { IF( EQ_16( encoded_ind_pred_GR[0], dft_maps_rpg[8 * NO_SYMB_GR_PRED_G] ) ) { - nb = add( nb, write_GR1( hBstr, IND_STEREO_DFT_PRED_GAIN_COD, encoded_ind_pred_GR, 1 ) ); + nb = add( nb, write_GR1_fx( hBstr, IND_STEREO_DFT_PRED_GAIN_COD, encoded_ind_pred_GR, 1 ) ); } ELSE { - nb = add( nb, write_bitstream_adapt_GR( hBstr, IND_STEREO_DFT_PRED_GAIN_COD, encoded_ind_pred_GR, nbands - hStereoDft->res_pred_band_min, hStereoDft->res_pred_flag_2, 2 ) ); + nb = add( nb, write_bitstream_adapt_GR_fx( hBstr, IND_STEREO_DFT_PRED_GAIN_COD, encoded_ind_pred_GR, nbands - hStereoDft->res_pred_band_min, hStereoDft->res_pred_flag_2, 2 ) ); } } ELSE { IF( EQ_16( hStereoDft->res_pred_flag_1, 2 ) ) { - nb = add( nb, write_bitstream_GR( hBstr, IND_STEREO_DFT_PRED_GAIN_COD, &hStereoDft->res_pred_index_ECDiff[hStereoDft->res_pred_band_min], nbands - hStereoDft->res_pred_band_min, hStereoDft->res_pred_flag_2 - no_GR_ord ) ); + nb = add( nb, write_bitstream_GR_fx( hBstr, IND_STEREO_DFT_PRED_GAIN_COD, &hStereoDft->res_pred_index_ECDiff[hStereoDft->res_pred_band_min], nbands - hStereoDft->res_pred_band_min, hStereoDft->res_pred_flag_2 - no_GR_ord ) ); } ELSE { @@ -3242,6 +3265,7 @@ ELSE } ( *nb_bits ) = add( *nb_bits, nb ); +move16(); IF( EQ_32( core_brate, SID_2k40 ) ) { @@ -3277,8 +3301,8 @@ static void stereo_dft_enc_compute_prm_fx( Word32 *dot_prod_nrg_ratio_fx, // Q(31-dot_prod_nrg_ratio_fx_e[]) Word16 *dot_prod_nrg_ratio_fx_e ) { - int16_t b, i; - int16_t b2; + Word16 b, i; + Word16 b2; Word32 *pDFT_L, *pDFT_R; // Word16 DFT_L_e, DFT_R_e; Word32 sum_nrg_L, sum_nrg_R; @@ -3327,7 +3351,7 @@ static void stereo_dft_enc_compute_prm_fx( Word16 sum_past_dot_prod_abs_e, sum_past_dot_prod_abs2_e = 0; Word32 sum_past_nrg_dmx; Word16 sum_past_nrg_dmx_e; - int16_t pos; + Word16 pos; Word32 pIpd[STEREO_DFT_BAND_MAX]; // Q13 Word32 ipd_smooth[STEREO_DFT_BAND_MAX]; // Q13 Word32 ipd_mean_change; // Q13 @@ -3437,7 +3461,7 @@ static void stereo_dft_enc_compute_prm_fx( sum_past_dpi_e = 0; move16(); - WHILE( LT_16( hStereoDft->band_limits_dmx[b2], hStereoDft->band_limits[b + 1] ) ) + WHILE( hStereoDft->band_limits_dmx[b2] < hStereoDft->band_limits[b + 1] ) { pDFT_L = DFT_L_fx; // DFT_L_e = hStereoDft->DFT_fx_e[0]; @@ -3796,7 +3820,7 @@ static void stereo_dft_enc_compute_prm_fx( move32(); } // dItd32 = (int16_t) floorf( conversion_factor * hStereoDft->hItd->deltaItd[k_offset] + 0.5f ); - dItd32 = (Word16) L_shr_r( Mpy_32_32( conversion_factor, hStereoDft->hItd->deltaItd_fx[k_offset] ), Q15 ); // Q0 + dItd32 = extract_l( L_shr_r( Mpy_32_32( conversion_factor, hStereoDft->hItd->deltaItd_fx[k_offset] ), Q15 ) ); // Q0 gain_offset = stereo_dft_gain_offset_fx( c, c_e, dItd32 ); // Q31 pPredGain[b] = L_max( 0, L_sub( pPredGain[b], gain_offset ) ); @@ -3947,8 +3971,6 @@ static void stereo_dft_enc_compute_prm_fx( ELSE { stereo_dft_enc_get_reverb_flag_fx( hStereoDft, pPredGain, sub_nrg_DMX, sub_nrg_DMX_e, sub_nrg_L, sub_nrg_L_e, sub_nrg_R, sub_nrg_R_e, k_offset, bin_nrgL_fx, bin_nrgL_fx_e, bin_nrgR_fx, bin_nrgR_fx_e ); - // printf( "\n%d ", hStereoDft->reverb_flag ); - // printf( "\n%f ", (float)hStereoDft->res_pred_gain_fx[18]/0x7fffffff); } @@ -4174,7 +4196,7 @@ static void res_pred_gain_mode_decision_fx( no_GR_ord = 2; move16(); - hStereoDft->res_pred_flag_2 = adapt_GR_rpg1_ief( &hStereoDft->res_pred_index_EC[hStereoDft->res_pred_band_min], &hStereoDft->res_pred_index_ECDiff[hStereoDft->res_pred_band_min], &hStereoDft->res_pred_index_ECprevious[hStereoDft->res_pred_band_min], nbands - hStereoDft->res_pred_band_min, NO_SYMB_GR_PRED_G, &n_bits, encoded_ind_pred_GR, dft_maps_rpg, &nb_diff, no_GR_ord, try_diff ); + hStereoDft->res_pred_flag_2 = adapt_GR_rpg1_ief_fx( &hStereoDft->res_pred_index_EC[hStereoDft->res_pred_band_min], &hStereoDft->res_pred_index_ECDiff[hStereoDft->res_pred_band_min], &hStereoDft->res_pred_index_ECprevious[hStereoDft->res_pred_band_min], nbands - hStereoDft->res_pred_band_min, NO_SYMB_GR_PRED_G, &n_bits, encoded_ind_pred_GR, dft_maps_rpg, &nb_diff, no_GR_ord, try_diff ); move16(); FOR( i = 0; i < nbands; i++ ) @@ -4269,6 +4291,7 @@ static Word32 stereo_dft_calc_mean_bipd_fx( { ipd_buf[i] = L_add( ipd_buf[i], 2 * EVS_PI_FX ); } + move32(); } // ipd_smooth = (i / (float)(i + 1)) * ipd_smooth + (1 / (float)(i + 1)) * ipd_buf[i]; ipd_smooth = L_add( Mpy_32_16_1( ipd_smooth, ipd_table1[i] ), Mpy_32_16_1( ipd_buf[i], ipd_table2[i] ) ); // Q13 @@ -4326,7 +4349,7 @@ static Word32 stereo_dft_calc_mean_ipd_change_fx( // ipd_mean_change /= gipd_band_max; ipd_mean_change = BASOP_Util_Divide3232_Scale_cadence( ipd_mean_change, gipd_band_max, &ipd_mean_change_e ); ipd_mean_change_e = add( ipd_mean_change_e, 18 - 31 ); - ipd_mean_change = L_shr( ipd_mean_change, sub( 18, ipd_mean_change_e ) ); + ipd_mean_change = L_shr( ipd_mean_change, sub( 18, ipd_mean_change_e ) ); // Q13 return ipd_mean_change; } @@ -4434,6 +4457,7 @@ static void stereo_dft_enc_get_nipd_flag_fx( hStereoDft->no_ipd_flag = hStereoDft->prev_no_ipd_flag; move16(); hStereoDft->no_ipd_cnt = add( hStereoDft->no_ipd_cnt, 1 ); + move16(); } ELSE { @@ -4454,8 +4478,8 @@ static void stereo_dft_enc_get_nipd_flag_fx( * ---------------------------------------------------------------*/ static void stereo_dft_enc_get_reverb_flag_fx( STEREO_DFT_ENC_DATA_HANDLE hStereoDft, - Word32 *pPredGain, // Q31 - Word32 *sub_nrg_DMX, + Word32 *pPredGain, // Q31 + Word32 *sub_nrg_DMX, // Q(31-sub_nrg_DMX_e) Word16 *sub_nrg_DMX_e, const Word32 *sub_nrg_L, // Q(31-sub_nrg_L_e[]) const Word16 *sub_nrg_L_e, diff --git a/lib_enc/ivas_stereo_dft_enc_itd.c b/lib_enc/ivas_stereo_dft_enc_itd_fx.c similarity index 93% rename from lib_enc/ivas_stereo_dft_enc_itd.c rename to lib_enc/ivas_stereo_dft_enc_itd_fx.c index 45eb643a570256b33d5c65f990ac20f1608f26b7..8a887de89f027b6906f8fddd25843e59e21cfdbc 100644 --- a/lib_enc/ivas_stereo_dft_enc_itd.c +++ b/lib_enc/ivas_stereo_dft_enc_itd_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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 "cnst.h" #include "rom_enc.h" #include "rom_com.h" -#include "prot.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "ivas_prot_fx.h" #include "ivas_cnst.h" #include "ivas_rom_com.h" @@ -109,7 +107,7 @@ static void set_band_limits_fx( move16(); *nbands = 0; move16(); - WHILE( LT_16( band_limits[( *nbands )++], shr( NFFT, 1 ) ) ) + WHILE( band_limits[( *nbands )++] < ( NFFT / 2 ) ) { band_limits[*nbands] = extract_l( Mpy_32_32_r( shl( dft_band_limits_erb4[*nbands], 1 ), 1717986918 /*( (float) ( STEREO_DFT_N_NS_ENC ) / STEREO_DFT_N_NS ) in Q 30*/ ) ); move16(); @@ -166,7 +164,7 @@ void stereo_dft_hybrid_ITD_flag_fx( static void stereo_dft_quantize_itd_fx( const Word16 in, - Word32 *out, + Word32 *out, // Q16 const Word32 input_Fs, Word16 *ind ) { @@ -205,10 +203,15 @@ static void stereo_dft_quantize_itd_fx( *-------------------------------------------------------------------------*/ static Word32 itd_vad_ms_snr_calc_fx( +#ifdef FIX_ISSUE_1092 + Word32 E_band_n[STEREO_DFT_ITD_VAD_BAND_NUM], // E_band_n_exp + Word16 E_band_n_exp[STEREO_DFT_ITD_VAD_BAND_NUM], +#else Word32 E_band_n[STEREO_DFT_ITD_VAD_BAND_NUM], // Q0 - Word32 *Spd, +#endif + Word32 *Spd, // Q(31-Spd_e) Word16 *Spd_e, - Word32 *E_band, + Word32 *E_band, // Q(31-E_band_e) Word16 *E_band_e, Word16 *ms_snr_e ) { @@ -248,7 +251,11 @@ static Word32 itd_vad_ms_snr_calc_fx( // snr[i] = E_band[i] / E_band_n[i]; snr[i] = BASOP_Util_Divide3232_Scale_cadence( E_band[i], E_band_n[i], &snr_e[i] ); move32(); +#ifdef FIX_ISSUE_1092 + snr_e[i] = add( snr_e[i], sub( E_band_e[i], E_band_n_exp[i] ) ); +#else snr_e[i] = add( snr_e[i], sub( E_band_e[i], 31 ) ); +#endif move16(); // if ( snr[i] < 1 ) IF( BASOP_Util_Cmp_Mant32Exp( snr[i], snr_e[i], 1, 31 ) < 0 ) @@ -284,11 +291,16 @@ static Word32 itd_vad_ms_snr_calc_fx( * *-------------------------------------------------------------------------*/ static void itd_vad_background_update_fx( +#ifdef FIX_ISSUE_1092 + Word32 E_band_n[STEREO_DFT_ITD_VAD_BAND_NUM], // E_band_n_exp + Word16 E_band_n_exp[STEREO_DFT_ITD_VAD_BAND_NUM], +#else Word32 E_band_n[STEREO_DFT_ITD_VAD_BAND_NUM], // Q0 +#endif Word16 *vad_frm_cnt, - const Word32 ms_snr, + const Word32 ms_snr, // Q(31-ms_snr_e) const Word16 ms_snr_e, - Word32 *E_band, + Word32 *E_band, // Q(31-E_band_e) Word16 *E_band_e ) { Word16 i; @@ -326,23 +338,21 @@ static void itd_vad_background_update_fx( Word16 q_temp = norm_l( *vad_frm_cnt ); L_temp = L_shl( *vad_frm_cnt, q_temp ); L_temp_e = sub( 31, q_temp ); +#ifdef FIX_ISSUE_1092 + L_temp = BASOP_Util_Add_Mant32Exp( Mpy_32_32( E_band_n[i], L_temp ), add( E_band_n_exp[i], L_temp_e ), E_band[i], E_band_e[i], &L_temp_e ); +#else L_temp = BASOP_Util_Add_Mant32Exp( Mpy_32_32( E_band_n[i], L_temp ), add( 31, L_temp_e ), E_band[i], E_band_e[i], &L_temp_e ); +#endif E_band_n[i] = BASOP_Util_Divide3232_Scale_cadence( L_temp, L_add( *vad_frm_cnt, 1 ), &E_band_n_e_tmp ); move32(); +#ifdef FIX_ISSUE_1092 + E_band_n_exp[i] = add( E_band_n_e_tmp, sub( L_temp_e, 31 ) ); +#else E_band_n_e_tmp = add( E_band_n_e_tmp, sub( L_temp_e, 31 ) ); E_band_n[i] = L_shr_r( E_band_n[i], sub( 31, E_band_n_e_tmp ) ); // Q31 +#endif move16(); } - /*Word16 max_exp = E_band_n_e_tmp[0]; - for ( i = 1; i < STEREO_DFT_ITD_VAD_BAND_NUM; i++ ) - { - max_exp = s_max( max_exp, E_band_n_e_tmp[i] ); - } - *E_band_n_e = max_exp; - for ( i = 0; i < STEREO_DFT_ITD_VAD_BAND_NUM; i++ ) - { - E_band_n[i] = L_shr_r( E_band_n[i], sub( *E_band_n_e, E_band_n_e_tmp[i] ) ); - }*/ } ELSE { @@ -352,6 +362,20 @@ static void itd_vad_background_update_fx( FOR( i = 0; i < STEREO_DFT_ITD_VAD_BAND_NUM; i++ ) { // E_band_n[i] = 0.96f * E_band_n[i] + 0.04f * E_band[i]; +#ifdef FIX_ISSUE_1092 + E_band_n[i] = BASOP_Util_Add_Mant32Exp( Mpy_32_32( 2061584302 /*0.96 in Q31*/, E_band_n[i] ), E_band_n_exp[i], Mpy_32_32( 85899346 /*0.04 in Q31*/, E_band[i] ), E_band_e[i], &E_band_n_e_tmp ); + move32(); + E_band_n_exp[i] = E_band_n_e_tmp; + move16(); + // if ( E_band_n[i] < 1.0f ) + IF( BASOP_Util_Cmp_Mant32Exp( E_band_n[i], E_band_n_exp[i], MAX_32, 0 ) < 0 ) + { + E_band_n[i] = MAX_32; + move32(); + E_band_n_exp[i] = 0; + move16(); + } +#else E_band_n[i] = BASOP_Util_Add_Mant32Exp( Mpy_32_32( 2061584302, E_band_n[i] ), 31, Mpy_32_32( 85899346, E_band[i] ), E_band_e[i], &E_band_n_e_tmp ); move32(); // if ( E_band_n[i] < 1.0f ) @@ -364,17 +388,8 @@ static void itd_vad_background_update_fx( } E_band_n[i] = L_shr_r( E_band_n[i], sub( 31, E_band_n_e_tmp ) ); // Q31 move32(); +#endif } - /*Word16 max_exp = E_band_n_e_tmp[0]; - for ( i = 1; i < STEREO_DFT_ITD_VAD_BAND_NUM; i++ ) - { - max_exp = s_max( max_exp, E_band_n_e_tmp[i] ); - } - *E_band_n_e = max_exp; - for ( i = 0; i < STEREO_DFT_ITD_VAD_BAND_NUM; i++ ) - { - E_band_n[i] = L_shr_r( E_band_n[i], sub( *E_band_n_e, E_band_n_e_tmp[i] ) ); - }*/ } } @@ -387,13 +402,18 @@ static void itd_vad_background_update_fx( *-------------------------------------------------------------------------*/ static Word16 stereo_dft_enc_itd_vad_fx( +#ifdef FIX_ISSUE_1092 + Word32 E_band_n[STEREO_DFT_ITD_VAD_BAND_NUM], // E_band_n_exp + Word16 E_band_n_exp[STEREO_DFT_ITD_VAD_BAND_NUM], +#else Word32 E_band_n[STEREO_DFT_ITD_VAD_BAND_NUM], // Q0 +#endif Word16 *vad_frm_cnt, - Word32 *Spd_L, + Word32 *Spd_L, // Q(31-Spd_L_e) Word16 *Spd_L_e, - Word32 *Spd_R, + Word32 *Spd_R, // Q(31-Spd_R_e) Word16 *Spd_R_e, - Word32 *mssnr, + Word32 *mssnr, // Q(31-mssnr_e) Word16 *mssnr_e ) { Word16 i; @@ -414,12 +434,17 @@ static Word16 stereo_dft_enc_itd_vad_fx( Spd_e[i] = sub( Spd_e[i], 1 ); move16(); } +#ifdef FIX_ISSUE_1092 + *mssnr = itd_vad_ms_snr_calc_fx( E_band_n, E_band_n_exp, Spd, Spd_e, E_band, E_band_e, mssnr_e ); + move32(); + itd_vad_background_update_fx( E_band_n, E_band_n_exp, vad_frm_cnt, *mssnr, *mssnr_e, E_band, E_band_e ); +#else *mssnr = itd_vad_ms_snr_calc_fx( E_band_n, Spd, Spd_e, E_band, E_band_e, mssnr_e ); move32(); itd_vad_background_update_fx( E_band_n, vad_frm_cnt, *mssnr, *mssnr_e, E_band, E_band_e ); - +#endif // if ( *mssnr < ITD_VAD_THRSHOLD ) IF( BASOP_Util_Cmp_Mant32Exp( *mssnr, *mssnr_e, ITD_VAD_THRSHOLD_Q31, 0 ) < 0 ) { @@ -445,12 +470,12 @@ static Word32 calc_mean_E_ratio_fx( ITD_DATA_HANDLE hItd, Word16 nbands, Word16 band_limits[], - const Word32 sfm, - const Word32 nrg_L[STEREO_DFT_N_32k_ENC / 2], + const Word32 sfm, // Q31 + const Word32 nrg_L[STEREO_DFT_N_32k_ENC / 2], // Q(31-nrg_L_e) const Word16 nrg_L_e[STEREO_DFT_N_32k_ENC / 2], - const Word32 nrg_R[STEREO_DFT_N_32k_ENC / 2], + const Word32 nrg_R[STEREO_DFT_N_32k_ENC / 2], // Q(31-nrg_R_e) const Word16 nrg_R_e[STEREO_DFT_N_32k_ENC / 2], - Word32 *total_mEr, + Word32 *total_mEr, // Q(31-total_mEr_e) Word16 *total_mEr_e, Word16 *sum_Er_e ) { @@ -495,7 +520,7 @@ static Word32 calc_mean_E_ratio_fx( move16(); /*take bands up to 32kHz bandwidth as ITD is always calculated at 32kHz sampling rate*/ - nbands -= ( band_limits[nbands] > STEREO_DFT_N_32k_ENC / 2 ); + nbands = sub( nbands, ( band_limits[nbands] > STEREO_DFT_N_32k_ENC / 2 ) ); sum_Er = 0; move32(); @@ -521,13 +546,14 @@ static Word32 calc_mean_E_ratio_fx( sum_nrg_R_e = 0; move16(); - FOR( i = band_limits[b]; i < min( band_limits[b + 1], STEREO_DFT_N_32k_ENC / 2 ); i++ ) + Word16 len = s_min( band_limits[b + 1], STEREO_DFT_N_32k_ENC >> 1 ); + FOR( i = band_limits[b]; i < len; i++ ) { // sum_xcorr[0] += hItd->xcorr_smooth[2 * i]; - sum_xcorr[0] = BASOP_Util_Add_Mant32Exp( sum_xcorr[0], sum_xcorr_e[0], hItd->xcorr_smooth_fx[2 * i], hItd->xcorr_smooth_fx_e, &sum_xcorr_e[0] ); + sum_xcorr[0] = BASOP_Util_Add_Mant32Exp( sum_xcorr[0], sum_xcorr_e[0], hItd->xcorr_smooth_fx[2 * i], hItd->xcorr_smooth_fx_e[2 * i], &sum_xcorr_e[0] ); move32(); // sum_xcorr[1] += hItd->xcorr_smooth[2 * i + 1]; - sum_xcorr[1] = BASOP_Util_Add_Mant32Exp( sum_xcorr[1], sum_xcorr_e[1], hItd->xcorr_smooth_fx[2 * i + 1], hItd->xcorr_smooth_fx_e, &sum_xcorr_e[1] ); + sum_xcorr[1] = BASOP_Util_Add_Mant32Exp( sum_xcorr[1], sum_xcorr_e[1], hItd->xcorr_smooth_fx[2 * i + 1], hItd->xcorr_smooth_fx_e[2 * i + 1], &sum_xcorr_e[1] ); move32(); // sum_nrg_L += nrg_L[i]; sum_nrg_L = BASOP_Util_Add_Mant32Exp( sum_nrg_L, sum_nrg_L_e, nrg_L[i], nrg_L_e[i], &sum_nrg_L_e ); @@ -583,6 +609,8 @@ static Word32 calc_mean_E_ratio_fx( } hItd->acorr_L_fx_e = max_exp1; hItd->acorr_R_fx_e = max_exp2; + move16(); + move16(); FOR( b = 0; b < nbands; b++ ) { hItd->acorr_L_fx[b] = L_shr_r( hItd->acorr_L_fx[b], sub( hItd->acorr_L_fx_e, acorr_L_fx_tmp_e[b] ) ); @@ -622,15 +650,14 @@ static void resetEstimates_fx( ITD_DATA_HANDLE hItd ) { set32_fx( hItd->xcorr_smooth_fx, 0, STEREO_DFT_N_32k_ENC ); - hItd->xcorr_smooth_fx_e = 0; - move16(); + set16_fx( hItd->xcorr_smooth_fx_e, 0, STEREO_DFT_N_32k_ENC ); set32_fx( hItd->acorr_L_fx, 0, STEREO_DFT_BAND_MAX ); hItd->acorr_L_fx_e = 0; move16(); set32_fx( hItd->acorr_R_fx, 0, STEREO_DFT_BAND_MAX ); hItd->acorr_R_fx_e = 0; move16(); - hItd->cohSNR_fx = 983040; + hItd->cohSNR_fx = 983040; // 15.0f in Q16 move32(); return; @@ -641,8 +668,8 @@ static void resetEstimates_fx( * time-domain smoothing filter for smoothing the cross-correlation vector *-------------------------------------------------------------------------*/ static void td_sm_filter_fx( - Word32 *x, - Word32 *y, + Word32 *x, // Q0 + Word32 *y, // Q0 const Word16 L ) { Word16 i; @@ -682,12 +709,12 @@ static Word32 peak_detect_fx( const Word16 vad, Word32 *second_max, Word16 *second_max_lag, - const Word16 prev_itd, + const Word16 prev_itd, // Q0 const Word16 flag_noisy_speech_snr, const Word16 detected_itd_flag, Word32 *prev_max, // Q31 Word16 *prev_index, - Word32 *prev_avg_max, + Word32 *prev_avg_max, // Q(31-prev_avg_max) Word16 *prev_avg_max_e, Word32 *total_max, // xcorr_itd_e Word16 *out_e ) @@ -738,7 +765,7 @@ static Word32 peak_detect_fx( /*if maximum is out of boundaries signal zero itd OR maximum value is negative*/ test(); - *zero_itd_flag = ( L_sub( *max_max, 4294968 ) < max_low || *max_max < max_high ); + *zero_itd_flag = ( L_sub( *max_max, 4294968 /*.002 Q31*/ ) < max_low || *max_max < max_high ); move16(); // adjustment is done for matching processing path with float code (differing due to precision loss) @@ -844,7 +871,7 @@ static Word32 peak_detect_fx( test(); test(); test(); - if ( vad && thres_diff > 0 && ( ( BASOP_Util_Cmp_Mant32Exp( thres_diff, thres_diff_e, 107374182, 0 ) < 0 && ( BASOP_Util_Cmp_Mant32Exp( snr, 15, 15, 31 ) <= 0 && BASOP_Util_Cmp_Mant32Exp( snr, 15, 7, 31 ) > 0 ) ) || ( BASOP_Util_Cmp_Mant32Exp( thres_diff, thres_diff_e, 21474836, 0 ) < 0 && ( BASOP_Util_Cmp_Mant32Exp( snr, 15, 15, 31 ) > 0 && BASOP_Util_Cmp_Mant32Exp( snr, 15, 30, 31 ) < 0 ) ) ) ) + if ( vad && thres_diff > 0 && ( ( BASOP_Util_Cmp_Mant32Exp( thres_diff, thres_diff_e, 107374182 /*.05 in Q31*/, 0 ) < 0 && ( BASOP_Util_Cmp_Mant32Exp( snr, 15, 15, 31 ) <= 0 && BASOP_Util_Cmp_Mant32Exp( snr, 15, 7, 31 ) > 0 ) ) || ( BASOP_Util_Cmp_Mant32Exp( thres_diff, thres_diff_e, 21474836 /* 0.01f in Q31*/, 0 ) < 0 && ( BASOP_Util_Cmp_Mant32Exp( snr, 15, 15, 31 ) > 0 && BASOP_Util_Cmp_Mant32Exp( snr, 15, 30, 31 ) < 0 ) ) ) ) { wfac = ONE_IN_Q30; // 2.0f move32(); @@ -861,7 +888,7 @@ static Word32 peak_detect_fx( move32(); } // else if ( detected_itd_flag == 0 && *max_max > 1.5f * avg_max && *prev_max > 1.5f * *prev_avg_max && abs( *index - *prev_index ) <= 2 ) - ELSE IF( detected_itd_flag == 0 && BASOP_Util_Cmp_Mant32Exp( *max_max, 0, Mpy_32_32( 1610612736, avg_max ), add( sum_max_e, 1 ) ) > 0 && BASOP_Util_Cmp_Mant32Exp( *prev_max, 0, Mpy_32_32( 1610612736, *prev_avg_max ), add( *prev_avg_max_e, 1 ) ) > 0 && LE_16( abs_s( sub( *index, *prev_index ) ), 2 ) ) + ELSE IF( detected_itd_flag == 0 && BASOP_Util_Cmp_Mant32Exp( *max_max, 0, Mpy_32_32( 1610612736 /*1.5f in Q29*/, avg_max ), add( sum_max_e, 1 ) ) > 0 && BASOP_Util_Cmp_Mant32Exp( *prev_max, 0, Mpy_32_32( 1610612736 /*1.5f in Q29*/, *prev_avg_max ), add( *prev_avg_max_e, 1 ) ) > 0 && LE_16( abs_s( sub( *index, *prev_index ) ), 2 ) ) { wfac = 805306368; // 1.5f in Q29 move32(); @@ -1096,13 +1123,13 @@ void stereo_dft_enc_compute_itd_fx( move32(); prod_R_e = 0; move16(); - sum_nrg_L = Mpy_32_32( pDFT_L[0], pDFT_L[0] ) /*+ FLT_MIN*/; + sum_nrg_L = Mpy_32_32( pDFT_L[0], pDFT_L[0] ) /*+ FLT_MIN Q(31-(2*DFT_L_e))*/; sum_nrg_L_e = shl( DFT_L_e[0], 1 ); - sum_nrg_R = Mpy_32_32( pDFT_R[0], pDFT_R[0] ) /*+ FLT_MIN*/; + sum_nrg_R = Mpy_32_32( pDFT_R[0], pDFT_R[0] ) /*+ FLT_MIN //Q(31-(2*DFT_L_e))*/; sum_nrg_R_e = shl( DFT_R_e[0], 1 ); sum_abs_L = BASOP_Util_Add_Mant32Exp( L_abs( pDFT_L[0] ), DFT_L_e[0], EPSILON_FX_M, EPSILON_FX_E, &sum_abs_L_e ) /*+ EPSILON*/; sum_abs_R = BASOP_Util_Add_Mant32Exp( L_abs( pDFT_R[0] ), DFT_R_e[0], EPSILON_FX_M, EPSILON_FX_E, &sum_abs_R_e ) /*+ EPSILON*/; - xcorr_lb[0] = Mpy_32_32( pDFT_L[0], pDFT_L[0] ); + xcorr_lb[0] = Mpy_32_32( pDFT_L[0], pDFT_L[0] ); // Q(31-(2*DFT_L_e)) move32(); xcorr_lb_e[0] = shl( DFT_L_e[0], 1 ); move16(); @@ -1134,6 +1161,7 @@ void stereo_dft_enc_compute_itd_fx( set16_fx( Spd_R_e, 0, STEREO_DFT_N_32k_ENC / 2 + 1 ); j = 0; // for loop statement + move16(); FOR( i = 1; i < NFFT_mid; i++ ) { /*if ( i == 121 ) @@ -1293,7 +1321,7 @@ void stereo_dft_enc_compute_itd_fx( j = 0; move16(); } - j++; // for loop statement + j = add( j, 1 ); // for loop statement } /* collect UNCLR classifier parameters */ @@ -1444,13 +1472,15 @@ void stereo_dft_enc_compute_itd_fx( move16(); FOR( Word16 ii = 0; ii < 11; ii++ ) { - L_temp = BASOP_Util_Add_Mant32Exp( L_temp, L_temp_e, Spd_L[i + 1], Spd_L_e[i + 1], &L_temp_e ); + L_temp = BASOP_Util_Add_Mant32Exp( L_temp, L_temp_e, Spd_L[ii + 1], Spd_L_e[ii + 1], &L_temp_e ); } // L_temp = sum2_32_fx( &Spd_L[1], 11, &L_temp_e ); sum_nrg_L_lb = BASOP_Util_Add_Mant32Exp( sum_nrg_L_lb, sum_nrg_L_lb_e, L_temp, L_temp_e, &sum_nrg_L_lb_e ); - +#ifdef FIX_ISSUE_1092 + vad_flag_itd = stereo_dft_enc_itd_vad_fx( hItd->E_band_n_fx, hItd->E_band_n_exp, &( hItd->vad_frm_cnt ), Spd_L, Spd_L_e, Spd_R, Spd_R_e, &mssnr, &mssnr_e ); +#else vad_flag_itd = stereo_dft_enc_itd_vad_fx( hItd->E_band_n_fx, &( hItd->vad_frm_cnt ), Spd_L, Spd_L_e, Spd_R, Spd_R_e, &mssnr, &mssnr_e ); - +#endif vad_flag_itd = vad_flag_itd && vad_flag_dtx[0]; // if ( sum_nrg_L < EPSILON ) @@ -1466,7 +1496,7 @@ void stereo_dft_enc_compute_itd_fx( // sfm_L = expf( log_prod_L / ( NFFT_mid ) ) / ( sum_abs_L / ( NFFT_mid ) ); L_temp = BASOP_Util_Divide3232_Scale_cadence( log_prod_L, NFFT_mid, &L_temp_e ); L_temp_e = add( L_temp_e, sub( log_prod_L_e, 31 ) ); - L_temp = BASOP_Util_fPow( 1459366444, 2, L_temp, L_temp_e, &L_temp_e ); + L_temp = BASOP_Util_fPow( 1459366444 /*2.718 in Q29*/, 2, L_temp, L_temp_e, &L_temp_e ); q_temp = norm_l( NFFT_mid ); L_temp2 = L_shl( NFFT_mid, q_temp ); L_temp2_e = sub( 31, q_temp ); @@ -1490,7 +1520,7 @@ void stereo_dft_enc_compute_itd_fx( // sfm_R = expf( log_prod_R / ( NFFT_mid ) ) / ( sum_abs_R / ( NFFT_mid ) ); L_temp = BASOP_Util_Divide3232_Scale_cadence( log_prod_R, NFFT_mid, &L_temp_e ); L_temp_e = add( L_temp_e, sub( log_prod_R_e, 31 ) ); - L_temp = BASOP_Util_fPow( 1459366444, 2, L_temp, L_temp_e, &L_temp_e ); + L_temp = BASOP_Util_fPow( 1459366444 /*2.718 in Q29*/, 2, L_temp, L_temp_e, &L_temp_e ); q_temp = norm_l( NFFT_mid ); L_temp2 = L_shl( NFFT_mid, q_temp ); L_temp2_e = sub( 31, q_temp ); @@ -1583,7 +1613,7 @@ void stereo_dft_enc_compute_itd_fx( } Word16 xcorr_smooth_fx_tmp_e[STEREO_DFT_N_32k_ENC]; - set16_fx( xcorr_smooth_fx_tmp_e, hItd->xcorr_smooth_fx_e, STEREO_DFT_N_32k_ENC ); + Copy( hItd->xcorr_smooth_fx_e, xcorr_smooth_fx_tmp_e, STEREO_DFT_N_32k_ENC ); hItd->xcorr_smooth_fx[0] = 0; move32(); xcorr_smooth_fx_tmp_e[0] = 0; @@ -1690,7 +1720,7 @@ void stereo_dft_enc_compute_itd_fx( hStereoDft->currentNumUpdates = add( hStereoDft->currentNumUpdates, 1 ); move16(); - FOR( i = 1; i < shr( NFFT, 2 ); i++ ) + FOR( i = 1; i < NFFT / 4; i++ ) { /* Low pass filter cross L/R power spectrum */ // hStereoDft->xspec_smooth[2 * i] = ( 1.f - cng_xcorr_filt ) * hStereoDft->xspec_smooth[2 * i] + cng_xcorr_filt * xcorr[2 * i]; @@ -1733,6 +1763,10 @@ void stereo_dft_enc_compute_itd_fx( } } } + test(); + test(); + test(); + test(); IF( ( vad_flag_dtx[0] == 0 ) || ( hCPE->hFrontVad[0] == NULL && ( EQ_32( hCPE->hCoreCoder[0]->last_core_brate, SID_2k40 ) || EQ_32( hCPE->hCoreCoder[0]->last_core_brate, FRAME_NO_DATA ) ) ) || hCPE->hStereoCng->first_SID_after_TD ) { IF( vad_flag_dtx[0] == 0 ) @@ -1796,7 +1830,9 @@ void stereo_dft_enc_compute_itd_fx( // tmpf1 += EPSILON; tmpf1 = BASOP_Util_Add_Mant32Exp( L_temp, L_temp_e, EPSILON_FX_M, EPSILON_FX_E, &tmpf1_e ); tmpf2 = tmpf1; + move32(); tmpf2_e = tmpf1_e; + move16(); // tmpf1 = powf( tmpf1, alpha ); tmpf1 = BASOP_Util_fPow( tmpf1, tmpf1_e, alpha, 0, &tmpf1_e ); // tmpf3 += tmpf2 * tmpf1; @@ -1843,7 +1879,9 @@ void stereo_dft_enc_compute_itd_fx( // tmpf1 += EPSILON; tmpf1 = BASOP_Util_Add_Mant32Exp( L_temp, L_temp_e, EPSILON_FX_M, EPSILON_FX_E, &tmpf1_e ); tmpf2 = tmpf1; + move32(); tmpf2_e = tmpf1_e; + move16(); // tmpf1 = powf( tmpf1, alpha ); tmpf1 = BASOP_Util_fPow( tmpf1, tmpf1_e, alpha, 0, &tmpf1_e ); // tmpf3 += tmpf2 * tmpf1; @@ -1909,7 +1947,9 @@ void stereo_dft_enc_compute_itd_fx( // tmpf1 += EPSILON; tmpf1 = BASOP_Util_Add_Mant32Exp( L_temp, L_temp_e, EPSILON_FX_M, EPSILON_FX_E, &tmpf1_e ); tmpf2 = tmpf1; + move32(); tmpf2_e = tmpf1_e; + move16(); // tmpf1 = powf( tmpf1, alpha ); tmpf1 = BASOP_Util_fPow( tmpf1, tmpf1_e, alpha, 0, &tmpf1_e ); // tmpf3 += tmpf2 * tmpf1; @@ -1942,17 +1982,7 @@ void stereo_dft_enc_compute_itd_fx( /* RESCALING TO COMMON EXP */ max_exp = MIN_16; move16(); - FOR( i = 0; i < STEREO_DFT_N_32k_ENC; i++ ) - { - max_exp = s_max( max_exp, xcorr_smooth_fx_tmp_e[i] ); - } - hItd->xcorr_smooth_fx_e = max_exp; - move16(); - FOR( i = 0; i < STEREO_DFT_N_32k_ENC; i++ ) - { - hItd->xcorr_smooth_fx[i] = L_shr_r( hItd->xcorr_smooth_fx[i], sub( hItd->xcorr_smooth_fx_e, xcorr_smooth_fx_tmp_e[i] ) ); - move32(); - } + Copy( xcorr_smooth_fx_tmp_e, hItd->xcorr_smooth_fx_e, STEREO_DFT_N_32k_ENC ); max_exp = MIN_16; move16(); FOR( i = 0; i < STEREO_DFT_N_32k_ENC; i++ ) @@ -2062,7 +2092,7 @@ void stereo_dft_enc_compute_itd_fx( move32(); sum_xcorr_e = 0; move16(); - for ( i = 1; i < NFFT_mid; i++ ) + FOR( i = 1; i < NFFT_mid; i++ ) { // xcorr_abs[i] = logf( xcorr_abs[i] / ( sum_nrg_L + sum_nrg_R + 1e-5f ) + 1e-5f ); L_temp = BASOP_Util_Add_Mant32Exp( sum_nrg_L, sum_nrg_L_e, sum_nrg_R, sum_nrg_R_e, &L_temp_e ); @@ -2094,7 +2124,7 @@ void stereo_dft_enc_compute_itd_fx( /*smooth cohSNR with time */ // if ( ( hItd->cohSNR - cohSNR ) < 10.0f ) - IF( LT_32( L_sub( hItd->cohSNR_fx, cohSNR ), 655360 ) ) + IF( LT_32( L_sub( hItd->cohSNR_fx, cohSNR ), 655360 /*10 in Q16*/ ) ) { // tmpf1 = max( 0.05f, min( 0.25f, sfm_L * 0.5f ) ); tmpf1 = L_max( 107374182, L_min( ONE_IN_Q29, L_shr( sfm_L, 1 ) ) ); @@ -2105,7 +2135,7 @@ void stereo_dft_enc_compute_itd_fx( ELSE { // hItd->cohSNR = hItd->cohSNR - 0.05f; - hItd->cohSNR_fx = L_sub( hItd->cohSNR_fx, 3277 ); + hItd->cohSNR_fx = L_sub( hItd->cohSNR_fx, 3277 /*.05 in Q16*/ ); move32(); } @@ -2162,7 +2192,7 @@ void stereo_dft_enc_compute_itd_fx( test(); test(); test(); - IF( hCPE->hCoreCoder[0]->sp_aud_decision0 && sub( index, STEREO_DFT_ITD_MAX_ANA ) != hItd->prev_itd && !flag_noisy_speech_snr && hCPE->hCoreCoder[0]->vad_flag && LT_32( tmpf1, 644245094 ) ) + IF( hCPE->hCoreCoder[0]->sp_aud_decision0 && NE_16( sub( index, STEREO_DFT_ITD_MAX_ANA ), hItd->prev_itd ) && !flag_noisy_speech_snr && hCPE->hCoreCoder[0]->vad_flag && LT_32( tmpf1, 644245094 ) ) { // thres *= 1.0f + 1.f * min( 1.f, max( 0.f, ( -1.0f * sfm_L + 0.5f ) / ( 0.5f - 0.2f ) ) ); L_temp = BASOP_Util_Add_Mant32Exp( L_negate( sfm_L ), 0, ONE_IN_Q30, 0, &L_temp_e ); @@ -2170,6 +2200,7 @@ void stereo_dft_enc_compute_itd_fx( L_temp2_e = add( L_temp2_e, L_temp_e - 0 ); L_temp2 = L_shl_sat( L_temp2, sub( L_temp2_e, 1 ) ); // Q30 L_temp2_e = 1; + move16(); L_temp2 = L_min( ONE_IN_Q30, L_max( 0, L_temp2 ) ); L_temp2 = L_add_sat( ONE_IN_Q30, L_temp2 ); // Q30 thres = Mpy_32_32( thres, L_temp2 ); @@ -2185,7 +2216,7 @@ void stereo_dft_enc_compute_itd_fx( test(); test(); test(); - IF( hCPE->hCoreCoder[0]->ini_frame == 0 || hCPE->last_element_mode != IVAS_CPE_DFT || !hCPE->hCoreCoder[0]->sp_aud_decision0 || flag_noisy_speech_snr || BASOP_Util_Cmp_Mant32Exp( cohSNR, 15, 20, 31 ) < 0 ) + IF( hCPE->hCoreCoder[0]->ini_frame == 0 || NE_16( hCPE->last_element_mode, IVAS_CPE_DFT ) || !hCPE->hCoreCoder[0]->sp_aud_decision0 || flag_noisy_speech_snr || BASOP_Util_Cmp_Mant32Exp( cohSNR, 15, 20, 31 ) < 0 ) { hItd->itd_thres_fx = thres; move32(); @@ -2202,7 +2233,7 @@ void stereo_dft_enc_compute_itd_fx( test(); test(); test(); - IF( flag_noisy_speech_snr == 0 && hCPE->hCoreCoder[0]->vad_flag == 1 && hItd->detected_itd_flag == 0 && ( LT_16( hItd->currFlatness_fx, 192 ) /* 1.5 in Q7*/ || hCPE->hCoreCoder[0]->sp_aud_decision0 == 1 ) ) + IF( flag_noisy_speech_snr == 0 && EQ_16( hCPE->hCoreCoder[0]->vad_flag, 1 ) && hItd->detected_itd_flag == 0 && ( LT_16( hItd->currFlatness_fx, 192 ) /* 1.5 in Q7*/ || EQ_16( hCPE->hCoreCoder[0]->sp_aud_decision0, 1 ) ) ) { // hItd->itd_thres *= 1.5f; hItd->itd_thres_fx = L_shl_sat( Mpy_32_32( hItd->itd_thres_fx, 1610612736 ), 1 ); /* Saturation added to avoid assertions (this needs to be investigated) */ @@ -2223,7 +2254,7 @@ void stereo_dft_enc_compute_itd_fx( // if ( hItd->itd_tracking == 1 && ( second_max > hItd->itd_thres || tmpf1 - second_max < min( tmpf1 * 0.5f, 0.2f ) ) ) test(); test(); - if ( EQ_16( hItd->itd_tracking, 1 ) && ( GT_32( second_max, hItd->itd_thres_fx ) || LT_32( L_sub( tmpf1, second_max ), L_min( L_shr( tmpf1, 1 ), 429496730 ) ) ) ) + if ( EQ_16( hItd->itd_tracking, 1 ) && ( GT_32( second_max, hItd->itd_thres_fx ) || LT_32( L_sub( tmpf1, second_max ), L_min( L_shr( tmpf1, 1 ), 429496730 /*.2f in Q31*/ ) ) ) ) { index = second_max_lag; move16(); @@ -2231,7 +2262,7 @@ void stereo_dft_enc_compute_itd_fx( // if ( hItd->itd_tracking == 1 && abs( hItd->prev_itd - ( index - STEREO_DFT_ITD_MAX_ANA ) ) <= max( 2, (int16_t) round_f( abs( hItd->prev_itd ) / 16.f ) ) ) test(); - if ( hItd->itd_tracking == 1 && abs_s( sub( hItd->prev_itd, sub( index, STEREO_DFT_ITD_MAX_ANA ) ) ) <= s_max( 2, shr_r( abs_s( hItd->prev_itd ), 4 ) ) ) + IF( EQ_16( hItd->itd_tracking, 1 ) && LE_16( abs_s( sub( hItd->prev_itd, sub( index, STEREO_DFT_ITD_MAX_ANA ) ) ), s_max( 2, shr_r( abs_s( hItd->prev_itd ), 4 ) ) ) ) { // hItd->itd_thres *= 0.75f; hItd->itd_thres_fx = Mpy_32_32( hItd->itd_thres_fx, 1610612736 ); @@ -2417,24 +2448,33 @@ void stereo_dft_enc_compute_itd_fx( /*Breakdown of fine-control conditions */ // fc_condition_1 = abs( hItd->prev_itd ) > 0.2f * abs( itd ); - fc_condition_1 = (Word16) GT_16( abs_s( hItd->prev_itd ), mult( 6554 /*0.2f*/, abs_s( itd ) ) ); + fc_condition_1 = extract_l( GT_16( abs_s( hItd->prev_itd ), mult( 6554 /*0.2f*/, abs_s( itd ) ) ) ); // fc_condition_2 = cor_lb_avrg > 0.85f; - fc_condition_2 = (Word16) GT_32( cor_lb_avrg, 1825361101 /*0.85f*/ ); + fc_condition_2 = extract_l( GT_32( cor_lb_avrg, 1825361101 /*0.85f*/ ) ); // fc_condition_3 = ( cor_lb_avrg > 0.7f && ( cor_lb[0] > 0.9f || cor_lb[1] > 0.9f || cor_lb[2] > 0.9f ) && hItd->prev_sum_nrg_L_lb > 0.5f * sum_nrg_L_lb && hItd->prev_sum_nrg_L_lb < 2.0f * sum_nrg_L_lb ); test(); test(); test(); test(); test(); - fc_condition_3 = (Word16) ( GT_32( cor_lb_avrg, 1503238554 /*0.7f*/ ) && ( GT_32( cor_lb[0], 1932735283 /*0.9f*/ ) || GT_32( cor_lb[1], 1932735283 /*0.9f*/ ) || GT_32( cor_lb[2], 1932735283 /*0.9f*/ ) ) && + fc_condition_3 = extract_l( GT_32( cor_lb_avrg, 1503238554 /*0.7f*/ ) && ( GT_32( cor_lb[0], 1932735283 /*0.9f*/ ) || GT_32( cor_lb[1], 1932735283 /*0.9f*/ ) || GT_32( cor_lb[2], 1932735283 /*0.9f*/ ) ) && BASOP_Util_Cmp_Mant32Exp( hItd->prev_sum_nrg_L_lb_fx, hItd->prev_sum_nrg_L_lb_fx_e, sum_nrg_L_lb, sub( sum_nrg_L_lb_e, 1 ) ) > 0 && BASOP_Util_Cmp_Mant32Exp( hItd->prev_sum_nrg_L_lb_fx, hItd->prev_sum_nrg_L_lb_fx_e, sum_nrg_L_lb, add( sum_nrg_L_lb_e, 1 ) ) < 0 ); // fc_condition_4 = par_L_avrg > 0.6f; - fc_condition_4 = (Word16) GT_32( par_L_avrg, 1288490189 /*0.6f*/ ); + fc_condition_4 = extract_l( GT_32( par_L_avrg, 1288490189 /*0.6f*/ ) ); fc_condition_5 = hItd->prev_itd != 0; fc_condition_6_a = L_mult0( itd, hItd->prev_itd ) < 0; /* ITD sign change */ fc_condition_6_b = L_mult0( itd, hItd->prev_itd ) == 0; /* ITD jump to zero */ // fc_condition_6_c = abs( itd - hItd->prev_itd ) > 0.5f * ( ( abs( itd ) > abs( hItd->prev_itd ) ) ? abs( itd ) : abs( hItd->prev_itd ) ); /* Magnitude of the ITD jump */ - fc_condition_6_c = (Word16) GT_16( abs_s( sub( itd, hItd->prev_itd ) ), shr( ( ( abs_s( itd ) > abs_s( hItd->prev_itd ) ) ? abs_s( itd ) : abs_s( hItd->prev_itd ) ), 1 ) ); /* Magnitude of the ITD jump */ + fc_condition_6_c = extract_l( GT_16( abs_s( sub( itd, hItd->prev_itd ) ), shr( ( ( abs_s( itd ) > abs_s( hItd->prev_itd ) ) ? abs_s( itd ) : abs_s( hItd->prev_itd ) ), 1 ) ) ); /* Magnitude of the ITD jump */ + + IF( GT_16( abs_s( itd ), abs_s( hItd->prev_itd ) ) ) + { + fc_condition_6_c = extract_l( GT_16( abs_s( sub( itd, hItd->prev_itd ) ), shr( ( abs_s( itd ) ), 1 ) ) ); /* Magnitude of the ITD jump */ + } + ELSE + { + fc_condition_6_c = extract_l( GT_16( abs_s( sub( itd, hItd->prev_itd ) ), shr( ( abs_s( hItd->prev_itd ) ), 1 ) ) ); /* Magnitude of the ITD jump */ + } /* Combining conditions 1,2,3,4 */ test(); @@ -2528,7 +2568,11 @@ void stereo_dft_enc_compute_itd_fx( prev_itd_max = hItd->hybrid_itd_max; move16(); /* enable hybrid ITD handling for very large ITDs*/ - hItd->hybrid_itd_max = ( abs( itd ) > STEREO_DFT_ITD_MAX && abs( itd ) < STEREO_DFT_ITD_MAX_ANA && !hCPE->hCoreCoder[0]->sp_aud_decision0 && hCPE->element_brate < IVAS_32k ); + // hItd->hybrid_itd_max = ( abs_s( itd ) > STEREO_DFT_ITD_MAX && abs_s( itd ) < STEREO_DFT_ITD_MAX_ANA && !hCPE->hCoreCoder[0]->sp_aud_decision0 && hCPE->element_brate < IVAS_32k ); + test(); + test(); + test(); + hItd->hybrid_itd_max = ( GT_16( abs_s( itd ), STEREO_DFT_ITD_MAX ) && LT_16( abs_s( itd ), STEREO_DFT_ITD_MAX_ANA ) && !hCPE->hCoreCoder[0]->sp_aud_decision0 && LT_32( hCPE->element_brate, IVAS_32k ) ); move16(); /* Update memory */ hItd->prev_itd = itd; diff --git a/lib_enc/ivas_stereo_dft_td_itd.c b/lib_enc/ivas_stereo_dft_td_itd_fx.c similarity index 86% rename from lib_enc/ivas_stereo_dft_td_itd.c rename to lib_enc/ivas_stereo_dft_td_itd_fx.c index 35f2467151a02a6e921a27388ed7b42b5758abd7..df4fe3edd15fe29ac3813dec4130beccfd7487cd 100644 --- a/lib_enc/ivas_stereo_dft_td_itd.c +++ b/lib_enc/ivas_stereo_dft_td_itd_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other @@ -35,15 +35,13 @@ #include "options.h" #include #include "cnst.h" -#include "prot.h" +#include "prot_fx.h" #include "rom_com.h" -#include "ivas_prot.h" #include "ivas_rom_com.h" #include "ivas_stat_enc.h" #include "ivas_cnst.h" #include "wmc_auto.h" #include "ivas_prot_fx.h" -#include "prot_fx.h" /*-------------------------------------------------------------------* @@ -54,7 +52,7 @@ #define STEREO_DFT_CHANNEL_EXTR_LPC_VEC_LIMIT 320 #define FLR_FX 16384 // Q15 #define ONE_HALF 24576 // Q14 -const Word16 wac_swb_h_fx[LPC_SHB_ORDER + 1] = { +const Word16 wac_swb_h_fx[LPC_SHB_ORDER + 1] = { // Q15 32767, 32758, 32731, @@ -68,7 +66,7 @@ const Word16 wac_swb_h_fx[LPC_SHB_ORDER + 1] = { 31870 }; -const Word16 wac_swb_l_fx[LPC_SHB_ORDER + 1] = { +const Word16 wac_swb_l_fx[LPC_SHB_ORDER + 1] = { // Q15 32767, 29696, 20864, @@ -90,7 +88,7 @@ const Word16 wac_swb_l_fx[LPC_SHB_ORDER + 1] = { static void stereo_td_get_td_itd_fx( Word16 *td_itd, /* o : td_itd in samples at sampling frequency */ Word16 *td_itd_32, /* o : td_itd in samples at 32kHz */ - const Word32 itd, /* i : itd in samples at sampling frequency */ + const Word32 itd, /* i : itd in samples at sampling frequency q_itd */ Word16 q_itd, const Word32 input_Fs /* i : sampling frequency */ ) @@ -114,7 +112,14 @@ static void stereo_td_get_td_itd_fx( temp_e = add( temp_e, sub( sub( 31, q_itd ), d_e ) ); // e+(e1-e2)// temp_add = add_sat( temp_div, shr_sat( FLR_FX, temp_e ) ); - *td_itd_32 = shl( shr( temp_add, sub( 15, temp_e ) ), 1 ); + IF( itd != 0 ) + { + *td_itd_32 = extract_l( L_shl( L_shr( L_add( temp_add, EPSILON_FX ), sub( 15, temp_e ) ), 1 ) ); + } + ELSE + { + *td_itd_32 = shl( shr( temp_add, sub( 15, temp_e ) ), 1 ); + } move16(); *td_itd = i_mult( shr( *td_itd_32, 1 ), shr( d, sub( 15, d_e ) ) ); @@ -133,13 +138,13 @@ static void stereo_td_get_td_itd_fx( static void stereo_td_channel_extrapolate_fx( Encoder_State **sts, const Word16 dft_ovl, - const Word16 shift_mem[], + const Word16 shift_mem[], // q_shift Word16 q_shift, - Word16 shift_input[], + Word16 shift_input[], // q_shift const Word16 input_frame, const Word16 itd_shift, const Word16 lagging_channel, - Word16 *input_mem[CPE_CHANNELS], /* i/o: input buffer memory */ + Word16 *input_mem[CPE_CHANNELS], /* i/o: input buffer memory q_input_mem */ Word16 *q_input_mem, Word16 *q_new_shift ) { @@ -165,7 +170,7 @@ static void stereo_td_channel_extrapolate_fx( set16_fx( shift_combined, 0, add( L_FRAME48k, L_FRAME48k ) ); set16_fx( residual, 0, STEREO_DFT_CHANNEL_EXTR_LPC_VEC_LIMIT + ( STEREO_DFT_ITD_MAX * input_frame ) / L_FRAME32k ); - leading_channel = add( lagging_channel, 1 ) & 1; + leading_channel = s_and( add( lagging_channel, 1 ), 1 ); IF( EQ_16( sts[0]->element_mode, IVAS_CPE_DFT ) ) { size_ovl = dft_ovl; @@ -176,6 +181,8 @@ static void stereo_td_channel_extrapolate_fx( size_ovl = input_frame; pitch0 = sts[lagging_channel]->pitch[0]; } + move16(); + move16(); pred_ovlp = idiv1616( input_frame, 10 ); @@ -192,9 +199,16 @@ static void stereo_td_channel_extrapolate_fx( dot_lead_lag_1 = EPSILON_FX; dot_lead_lead_1 = EPSILON_FX; dot_lag_lag_1 = EPSILON_FX; + move64(); + move64(); + move64(); + move32(); + move32(); + move32(); FOR( i = 0; i < size_ovl; i++ ) { shift_combined[i] = shift_mem[i]; // q_shift + move16(); // q_shift_combined = q_shift; dot_lead_lag = W_mac0_16_16( dot_lead_lag, input_mem[leading_channel][i], shift_mem[i] ); dot_lead_lead = W_mac0_16_16( dot_lead_lead, input_mem[leading_channel][i], input_mem[leading_channel][i] ); @@ -202,19 +216,20 @@ static void stereo_td_channel_extrapolate_fx( } FOR( i = 0; i < input_frame - itd_shift; i++ ) { - shift_combined[add( i, size_ovl )] = shift_input[i]; // q_shift + shift_combined[i + size_ovl] = shift_input[i]; // q_shift + move16(); dot_lead_lag = W_mac0_16_16( dot_lead_lag, sts[leading_channel]->input_fx[i], shift_input[i] ); dot_lead_lead = W_mac0_16_16( dot_lead_lead, sts[leading_channel]->input_fx[i], sts[leading_channel]->input_fx[i] ); dot_lag_lag = W_mac0_16_16( dot_lag_lag, shift_input[i], shift_input[i] ); } q_dot_lead_lag = q_shift + q_input_mem[leading_channel]; // q_input_mem = q_input q_dot_lead_lead = q_input_mem[leading_channel] + q_input_mem[leading_channel]; - q_dot_lag_lag = q_shift + q_shift; + q_dot_lag_lag = add( q_shift, q_shift ); - q_dot_lead_lag = q_dot_lead_lag + W_norm( dot_lead_lag ) - 32; - q_dot_lead_lead = q_dot_lead_lead + W_norm( dot_lead_lead ) - 32; - q_dot_lag_lag = q_dot_lag_lag + W_norm( dot_lag_lag ) - 32; + q_dot_lead_lag = sub( add( q_dot_lead_lag, W_norm( dot_lead_lag ) ), 32 ); + q_dot_lead_lead = sub( add( q_dot_lead_lead, W_norm( dot_lead_lead ) ), 32 ); + q_dot_lag_lag = sub( add( q_dot_lag_lag, W_norm( dot_lag_lag ) ), 32 ); dot_lead_lag_1 = W_extract_h( W_shl( dot_lead_lag, W_norm( dot_lead_lag ) ) ); dot_lead_lead_1 = W_extract_h( W_shl( dot_lead_lead, W_norm( dot_lead_lead ) ) ); dot_lag_lag_1 = W_extract_h( W_shl( dot_lag_lag, W_norm( dot_lag_lag ) ) ); @@ -222,26 +237,27 @@ static void stereo_td_channel_extrapolate_fx( Word16 g_e, f, f_e, g_lpc_e, nsr_e; g = BASOP_Util_Divide3232_Scale( dot_lead_lag_1, dot_lead_lead_1, &g_e ); - g_e = g_e + ( q_dot_lead_lead - q_dot_lead_lag ); + g_e = add( g_e, sub( q_dot_lead_lead, q_dot_lead_lag ) ); f = BASOP_Util_Divide3232_Scale( dot_lead_lag_1, dot_lag_lag_1, &f_e ); - f_e = f_e + ( q_dot_lag_lag - q_dot_lead_lag ); + f_e = add( f_e, sub( q_dot_lag_lag, q_dot_lead_lag ) ); nsr = mult( g, f ); - nsr_e = BASOP_Util_Add_MantExp( ONE_IN_Q14, 1, negate( nsr ), g_e + f_e, &nsr ); - IF( LE_16( g_e, 0 ) ) - g = g; - ELSE - g = check_bounds_s_fx( g, negate( shl( 1, 15 - g_e ) ), shl( ONE_HALF, ( 1 - g_e ) ) ); - IF( LE_16( nsr_e, 0 ) ) - nsr = nsr; - ELSE - nsr = check_bounds_s_fx( nsr, 0, shl( 1, 15 - ( nsr_e ) ) ); - g = shl( g, g_e - 1 ); // q14 - nsr = shl( nsr, nsr_e ); // Q15 + nsr_e = BASOP_Util_Add_MantExp( ONE_IN_Q14, 1, negate( nsr ), add( g_e, f_e ), &nsr ); + IF( g_e > 0 ) + { + g = check_bounds_s_fx( g, negate( shl( 1, sub( 15, g_e ) ) ), shl( ONE_HALF, sub( 1, g_e ) ) ); + } + IF( nsr_e > 0 ) + { + nsr = check_bounds_s_fx( nsr, 0, shl( 1, sub( 15, nsr_e ) ) ); + } + g = shl( g, sub( g_e, 1 ) ); // q14 + nsr = shl( nsr, nsr_e ); // Q15 g_lpc_e = 0; + move16(); g_lpc = Sqrt16( nsr, &g_lpc_e ); - g_lpc = shl( g_lpc, g_lpc_e - 1 ); // Q14 + g_lpc = shl( g_lpc, sub( g_lpc_e, 1 ) ); // Q14 /* rectangular window */ set16_fx( window, 32767, STEREO_DFT_CHANNEL_EXTR_LPC_VEC_LIMIT ); set16_zero_fx( mem_zero, STEREO_DFT_CHANNEL_EXTR_LPC_ORDER ); @@ -250,18 +266,20 @@ static void stereo_td_channel_extrapolate_fx( autocorr_ivas_fx( shift_combined + input_frame + size_ovl - itd_shift - STEREO_DFT_CHANNEL_EXTR_LPC_VEC_LIMIT, q_shift, STEREO_DFT_CHANNEL_EXTR_LPC_ORDER, r_h, r_l, &Q_r, STEREO_DFT_CHANNEL_EXTR_LPC_VEC_LIMIT, window, 0, 0, 0 ); /* Ensure R[0] isn't zero when entering Levinson-Durbin */ r_l[0] = s_max( r_l[0], 1 ); + move16(); FOR( i = 0; i <= STEREO_DFT_CHANNEL_EXTR_LPC_ORDER; i++ ) { L_tmp = Mpy_32( r_h[i], r_l[i], wac_swb_h_fx[i], wac_swb_l_fx[i] ); L_Extract( L_tmp, &r_h[i], &r_l[i] ); } r_l[0] = s_max( r_l[0], 1 ); - + move16(); flag = E_LPC_lev_dur( r_h, r_l, A, NULL, STEREO_DFT_CHANNEL_EXTR_LPC_ORDER, NULL ); Copy_Scale_sig( A, A, STEREO_DFT_CHANNEL_EXTR_LPC_ORDER + 1, sub( norm_s( A[0] ), 2 ) ); IF( EQ_16( flag, 1 ) ) { g_lpc = 0; + move16(); } ELSE { @@ -270,15 +288,25 @@ static void stereo_td_channel_extrapolate_fx( /* extend the residual */ /* to prevent out of bound reading */ - res_shift = ( pitch_lag < PIT_MAX ? pitch_lag : itd_shift ); + IF( LT_16( pitch_lag, PIT_MAX ) ) + { + res_shift = pitch_lag; + move16(); + } + ELSE + { + res_shift = itd_shift; + move16(); + } FOR( i = STEREO_DFT_CHANNEL_EXTR_LPC_VEC_LIMIT; i < STEREO_DFT_CHANNEL_EXTR_LPC_VEC_LIMIT + itd_shift; i++ ) { residual[i] = residual[i - res_shift]; + move16(); } /* perform sythesis */ - E_UTIL_synthesis( 0, A, residual, shift_combined + input_frame + size_ovl - STEREO_DFT_CHANNEL_EXTR_LPC_VEC_LIMIT - itd_shift, STEREO_DFT_CHANNEL_EXTR_LPC_VEC_LIMIT + itd_shift, mem_zero, 0, STEREO_DFT_CHANNEL_EXTR_LPC_ORDER ); + E_UTIL_synthesis( 0, A, residual, shift_combined + sub( add( input_frame, size_ovl ), add( STEREO_DFT_CHANNEL_EXTR_LPC_VEC_LIMIT, itd_shift ) ), STEREO_DFT_CHANNEL_EXTR_LPC_VEC_LIMIT + itd_shift, mem_zero, 0, STEREO_DFT_CHANNEL_EXTR_LPC_ORDER ); } Copy( shift_combined + size_ovl, shift_input, input_frame ); // q_shift @@ -328,13 +356,13 @@ static void stereo_td_channel_extrapolate_fx( void stereo_td_itd_fx( ITD_DATA *hITD, /* i/o: ITD data structure */ - Word16 input_mem_itd[CPE_CHANNELS][STEREO_DFT_OVL_MAX], /* o : ITD memory (only used in DFT Stereo) */ + Word16 input_mem_itd[CPE_CHANNELS][STEREO_DFT_OVL_MAX], /* o : ITD memory (only used in DFT Stereo) q_input_mem_itd*/ Word16 *q_input_mem_itd, const Word16 hybrid_itd_flag, /* i : flag for hybrid TD/FD ITD processing */ const Word16 dft_ovl, /* i : size of DFT overlap */ Encoder_State **sts, /* i/o: Encoder state structure */ const Word16 input_frame, /* i : input frame length */ - Word16 *input_mem[CPE_CHANNELS], /* i/o: input buffer memory */ + Word16 *input_mem[CPE_CHANNELS], /* i/o: input buffer memory q_input_mem */ Word16 *q_input_mem ) { Word16 i, ch, n; @@ -343,6 +371,7 @@ void stereo_td_itd_fx( Word16 itd, itd_max; Word16 shift_input[L_FRAME48k]; Word16 shift_mem[L_FRAME48k]; + Word16 q_shift_mem; Word16 *mdct_mem[CPE_CHANNELS]; // Word16 q_mdct_mem[CPE_CHANNELS]; Word16 q_shift, q_new_shift; @@ -354,23 +383,18 @@ void stereo_td_itd_fx( FOR( n = 0; n < CPE_CHANNELS; n++ ) { - Scale_sig( &input_mem[n][0], dft_ovl, sts[n]->q_inp - q_input_mem[n] ); + Scale_sig( &input_mem[n][0], dft_ovl, sts[n]->q_inp - q_input_mem[n] ); // Q(sts[n]->q_inp) // Scale_sig(&sts[n]->old_input_signal_fx, 1965, sts[n]->q_inp - sts[n]->q_old_inp); // sts[n]->q_old_inp = sts[n]->q_inp; q_input_mem[n] = sts[n]->q_inp; move16(); - } // check this block once + } IF( EQ_16( sts[0]->element_mode, IVAS_CPE_MDCT ) ) { - /*FOR(n = 0; n < CPE_CHANNELS; n++) - { - Scale_sig(sts[n]->old_input_signal_fx, 1965, sts[n]->q_inp - sts[n]->q_old_inp); - sts[n]->q_old_inp = sts[n]->q_inp; - }*/ - // check this block onc FOR( n = 0; n < CPE_CHANNELS; n++ ) { mdct_mem[n] = sts[n]->old_input_signal_fx; + move16(); // q_mdct_mem[n] = sts[n]->q_old_inp; } } @@ -408,8 +432,8 @@ void stereo_td_itd_fx( move16(); itd_max = shr( input_frame, 2 ); - Word16 comp_flag1 = (Word16) LE_16( extract_l( L_shr( hITD->itd_fx[k_offset], Q16 ) ), itd_max ); - Word16 comp_flag2 = (Word16) LE_16( extract_l( L_shr( hITD->itd_fx[sub( k_offset, 1 )], Q16 ) ), itd_max ); + Word16 comp_flag1 = extract_l( LE_16( extract_l( L_shr( hITD->itd_fx[k_offset], Q16 ) ), itd_max ) ); + Word16 comp_flag2 = extract_l( LE_16( extract_l( L_shr( hITD->itd_fx[sub( k_offset, 1 )], Q16 ) ), itd_max ) ); assert( ( comp_flag1 ) && "ITD value is too high!" ); assert( ( comp_flag2 ) && "ITD value is too high!" ); @@ -449,17 +473,21 @@ void stereo_td_itd_fx( } /*shift past part*/ - Copy( input_mem[ch] + shift[ch], shift_mem, size_ovl - shift[ch] ); + Copy( input_mem[ch] + shift[ch], shift_mem, sub( size_ovl, shift[ch] ) ); Copy( sts[ch]->input_fx, shift_mem + size_ovl - shift[ch], shift[ch] ); + q_shift_mem = sts[ch]->q_inp; + move16(); } ELSE { /*shift past part*/ Copy( mdct_mem[ch] + shift[ch], shift_mem, input_frame - shift[ch] ); Copy( sts[ch]->input_fx, shift_mem + input_frame - shift[ch], shift[ch] ); + q_shift_mem = sts[ch]->q_inp; + move16(); } /*shift current part*/ - Copy( sts[ch]->input_fx + shift[ch], shift_input, input_frame - shift[ch] ); + Copy( sts[ch]->input_fx + shift[ch], shift_input, sub( input_frame, shift[ch] ) ); q_shift = sts[ch]->q_inp; move16(); @@ -490,7 +518,9 @@ void stereo_td_itd_fx( ELSE { Copy( shift_mem, mdct_mem[ch], input_frame ); - Scale_sig( mdct_mem[ch], input_frame, sub( sts[ch]->q_inp, *q_input_mem ) ); + sts[ch]->q_old_inp = q_new_shift; + move16(); + Scale_sig( mdct_mem[ch], input_frame, sub( sts[ch]->q_inp, q_shift_mem ) ); // Q(sts[ch]->q_inp) } } } @@ -520,6 +550,7 @@ void stereo_td_itd_mdct_stereo_fx( Word16 DFT_tmp_e[CPE_CHANNELS][STEREO_DFT_N_MAX_ENC]; STEREO_MDCT_ENC_DATA_HANDLE hStereoMdct; + test(); IF( hCPE->hStereoMdct != NULL && hCPE->hStereoMdct->hItd != NULL ) { hStereoMdct = hCPE->hStereoMdct; diff --git a/lib_enc/ivas_stereo_dmx_evs.c b/lib_enc/ivas_stereo_dmx_evs_fx.c similarity index 94% rename from lib_enc/ivas_stereo_dmx_evs.c rename to lib_enc/ivas_stereo_dmx_evs_fx.c index 801aae865f15574a313d07f1da729b75675e5a19..ae8a8203e815b5597d27cb4d6ffeb44070301274 100644 --- a/lib_enc/ivas_stereo_dmx_evs.c +++ b/lib_enc/ivas_stereo_dmx_evs_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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,16 +36,13 @@ #include "cnst.h" #include "ivas_cnst.h" #include "rom_com.h" -#include "prot.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "ivas_prot_fx.h" #include "ivas_rom_com.h" #include "ivas_rom_com_fx.h" #include "ivas_rom_enc.h" #include "wmc_auto.h" #include "ivas_prot_fx.h" -#include "prot_fx.h" /*-----------------------------------------------------------------------* @@ -55,54 +52,33 @@ #define STEREO_DMX_EVS_FIND_POC_PEAK_TAU 4 #define STEREO_DMX_EVS_FIND_POC_PEAK_TAU2 8 -#define STEREO_DMX_EVS_POC_GAMMA 0.75f -#define STEREO_DMX_EVS_POC_SMOOTH 1.25f #define STEREO_DMX_EVS_POC_SMOOTH_Q30 1342177280 -#define STEREO_DMX_EVS_POC_FORGETTING 0.78f #define STEREO_DMX_EVS_POC_FORGETTING_Q31 1675037245 -#define STEREO_DMX_EVS_TARGET_POC_FORGETTING 0.79f #define STEREO_DMX_EVS_TARGET_POC_FORGETTING_Q31 1696512082 -#define STEREO_DMX_EVS_POC_W_FORGETTING 0.875f -#define STEREO_DMX_EVS_SHIFT_LIMIT 5.625f /* ms */ -#define STEREO_DMX_EVS_SHIFT_LIMIT_Q12 23040 /* ms */ +#define STEREO_DMX_EVS_SHIFT_LIMIT_Q12 23040 /* ms */ -#define STEREO_DMX_EVS_DMX_EGY_FORGETTING 0.25f #define STEREO_DMX_EVS_DMX_EGY_FORGETTING_FX 536870912 // 0.25f in Q31 -#define STEREO_DMX_EVS_CORR_FORGETTING 0.78f #define STEREO_DMX_EVS_CORR_FORGETTING_FX 1610612736 /*Q31*/ #define STEREO_DMX_EVS_POC_W_FORGETTING_FX 1879048192 /*Q31*/ -#define Q_BAND 0.25f #define Q_BAND_FX 536870912 /*Q31*/ -#define STEREO_DMX_EVS_ISD_FORGETTING 0.95f #define STEREO_DMX_EVS_ISD_FORGETTING_Q15 31129 -#define STEREO_DMX_EVS_ISD_THRES_H 1.69f -#define STEREO_DMX_EVS_ISD_THRES_L 0.9f #define STEREO_DMX_EVS_ISD_THRES_L_Q31 1932735283 -#define STEREO_DMX_EVS_ISD_DIST_THRES_IPD 0.5f #define STEREO_DMX_EVS_ISD_DIST_THRES_IPD_Q15 ONE_IN_Q14 -#define STEREO_DMX_EVS_ISD_DIST_HYST_L 0.36f #define STEREO_DMX_EVS_ISD_DIST_HYST_L_Q15 11796 -#define STEREO_DMX_EVS_ISD_DIST_HYST_H 0.43f #define STEREO_DMX_EVS_ISD_DIST_HYST_H_Q15 14090 -#define STEREO_DMX_EVS_ICCR_FORGETTING 0.7f #define STEREO_DMX_EVS_ICCR_FORGETTING_Q31 1503238554 -#define STEREO_DMX_EVS_ICCR_HYST_L 0.75f #define STEREO_DMX_EVS_ICCR_HYST_L_Q31 1610612736 -#define STEREO_DMX_EVS_ICCR_HYST_H 0.85f #define STEREO_DMX_EVS_ICCR_HYST_H_Q31 1825361101 #define STEREO_DMX_EVS_SWTCH_HYS_THRES 1 -#define STEREO_DMX_EVS_LR_EGY 15.0f #define STEREO_DMX_EVS_LR_EGY_Q27 2013265920 -#define STEREO_DMX_EVS_ILDS_EGY 10000.0f #define STEREO_DMX_EVS_ILDS_EGY_Q17 1310720000 -#define STEREO_DMX_EVS_ILD_PRC 0.1f #define STEREO_DMX_EVS_ILD_PRC_Q15 3277 #define STEREO_DMX_EVS_SWTCH_PRC_THRES_16 55 @@ -110,15 +86,14 @@ #define STEREO_DMX_EVS_SWTCH_PRC_THRES_48 29 #define STEREO_DMX_EVS_SWTCH_PRC_HYS_THRES 1 -#define STEREO_DMX_EVS_FADE_LEN_PRC 20.0f +#define STEREO_DMX_EVS_FADE_LEN_PRC_Q0 20 -#define STEREO_DMX_EVS_NB_SBFRM 5 -#define STEREO_DMX_EVS_TRNS_DTC_INST 75.0f -#define STEREO_DMX_EVS_CRST_FCTR_16 80.0f -#define STEREO_DMX_EVS_CRST_FCTR_32 40.0f -#define STEREO_DMX_EVS_CRST_FCTR_48 35.0f +#define STEREO_DMX_EVS_NB_SBFRM 5 +#define STEREO_DMX_EVS_TRNS_DTC_INST_Q0 75 +#define STEREO_DMX_EVS_CRST_FCTR_16_Q0 80 +#define STEREO_DMX_EVS_CRST_FCTR_32_Q0 40 +#define STEREO_DMX_EVS_CRST_FCTR_48_Q0 35 -#define STEREO_DMX_EVS_TRNS_EGY_FORGETTING 0.75f #define STEREO_DMX_EVS_TRNS_EGY_FORGETTING_Q15 24576 const Word32 ipd_ff_Q31[STEREO_DMX_EVS_NB_SUBBAND_MAX] = { @@ -270,7 +245,7 @@ void estimate_itd_wnd_fft_fx( } rshift = sub( getScaleFactor32( rfft_buf, input_frame ), find_guarded_bits_fx( input_frame ) ); - scale_sig32( rfft_buf, input_frame, rshift ); + scale_sig32( rfft_buf, input_frame, rshift ); // Q(16+rshift) *spec_e = sub( 15, rshift ); move16(); rfft_fx( rfft_buf, rfft_coef, input_frame, -1 ); @@ -362,22 +337,22 @@ static void calc_poc_fx( // igamma = STEREO_DMX_EVS_POC_GAMMA * iN; IF( EQ_16( input_frame, L_FRAME16k ) ) { - igamma = 5033165; + igamma = 5033165; //(STEREO_DMX_EVS_POC_GAMMA/input_frame) in Q31 move16(); } ELSE IF( EQ_16( input_frame, L_FRAME32k ) ) { - igamma = 3355444; + igamma = 3355444; //(STEREO_DMX_EVS_POC_GAMMA/input_frame) in Q31 move16(); } ELSE IF( EQ_16( input_frame, L_FRAME48k ) ) { - igamma = 1677722; + igamma = 1677722; //(STEREO_DMX_EVS_POC_GAMMA/input_frame) in Q31 move16(); } ELSE { - igamma = 1677722; + igamma = 1677722; //(STEREO_DMX_EVS_POC_GAMMA/input_frame) in Q31 move16(); IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "invalid sample rate\n" ); } @@ -518,41 +493,41 @@ static void calc_poc_fx( FOR( ; i < n0 >> 3; i++ ) /* binary search from 8 angles */ { - tmp1 = Mpy_32_32_r( wnd[i * step + bias], gamma ); + tmp1 = Mpy_32_32_r( wnd[i * step + bias], gamma ); // Q31 IF( W_mult0_32_32( L_sub( specPOr[i], specPOi[i] ), L_add( specPOr[i], specPOi[i] ) ) > 0 ) { - specPOr[i] = Mpy_32_16_1( tmp1, imult1616( sign_fx( specPOr[i] ), /*0.923880f*/ s[120 * mult_angle] ) ); /* cos(PI/8)*/ + specPOr[i] = Mpy_32_16_1( tmp1, imult1616( sign_fx( specPOr[i] ), /*0.923880f*/ s[120 * mult_angle] ) ); /* cos(PI/8) Q31*/ move32(); - specPOi[i] = Mpy_32_16_1( tmp1, imult1616( sign_fx( specPOi[i] ), /*0.382683f*/ s[40 * mult_angle] ) ); + specPOi[i] = Mpy_32_16_1( tmp1, imult1616( sign_fx( specPOi[i] ), /*0.382683f*/ s[40 * mult_angle] ) ); // Q31 move32(); } ELSE { - specPOr[i] = Mpy_32_16_1( tmp1, imult1616( sign_fx( specPOr[i] ), /*0.382683f*/ s[40 * mult_angle] ) ); /* cos(PI*3/8)*/ + specPOr[i] = Mpy_32_16_1( tmp1, imult1616( sign_fx( specPOr[i] ), /*0.382683f*/ s[40 * mult_angle] ) ); /* cos(PI*3/8) Q31*/ move32(); - specPOi[i] = Mpy_32_16_1( tmp1, imult1616( sign_fx( specPOi[i] ), /*0.923880f*/ s[120 * mult_angle] ) ); + specPOi[i] = Mpy_32_16_1( tmp1, imult1616( sign_fx( specPOi[i] ), /*0.923880f*/ s[120 * mult_angle] ) ); // Q31 move32(); } gamma = L_sub( gamma, igamma ); } FOR( ; i < end; i++ ) /* binary search from 16 angles */ { - tmp1 = Mpy_32_32_r( wnd[i * step + bias], gamma ); + tmp1 = Mpy_32_32_r( wnd[i * step + bias], gamma ); // Q31 IF( W_mult0_32_32( L_sub( specPOr[i], specPOi[i] ), L_add( specPOr[i], specPOi[i] ) ) > 0 ) { IF( W_mult0_32_32( L_sub( Mpy_32_16_1( specPOr[i], 13573 /*0.414213f*/ ), specPOi[i] ), L_add( Mpy_32_16_1( specPOr[i], 13573 /*0.414213f*/ ), specPOi[i] ) ) > 0 ) /*tan(PI/8)*/ { - specPOr[i] = Mpy_32_16_1( tmp1 /*0.980785f */, imult1616( sign_fx( specPOr[i] ), s[140 * mult_angle] ) ); /* cos(PI/16)*/ + specPOr[i] = Mpy_32_16_1( tmp1 /*0.980785f */, imult1616( sign_fx( specPOr[i] ), s[140 * mult_angle] ) ); /* cos(PI/16) Q31*/ move32(); - specPOi[i] = Mpy_32_16_1( tmp1 /*0.195090f */, imult1616( sign_fx( specPOi[i] ), s[20 * mult_angle] ) ); + specPOi[i] = Mpy_32_16_1( tmp1 /*0.195090f */, imult1616( sign_fx( specPOi[i] ), s[20 * mult_angle] ) ); // Q31 move32(); } ELSE { - specPOr[i] = Mpy_32_16_1( tmp1 /* 0.831470f */, imult1616( sign_fx( specPOr[i] ), s[100 * mult_angle] ) ); /*cos(PI*3/16)*/ + specPOr[i] = Mpy_32_16_1( tmp1 /* 0.831470f */, imult1616( sign_fx( specPOr[i] ), s[100 * mult_angle] ) ); /*cos(PI*3/16) Q31*/ move32(); - specPOi[i] = Mpy_32_16_1( tmp1 /* 0.555570f*/, imult1616( sign_fx( specPOi[i] ), s[60 * mult_angle] ) ); + specPOi[i] = Mpy_32_16_1( tmp1 /* 0.555570f*/, imult1616( sign_fx( specPOi[i] ), s[60 * mult_angle] ) ); // Q31 move32(); } } @@ -560,16 +535,16 @@ static void calc_poc_fx( { IF( W_mult0_32_32( L_sub( specPOr[i], Mpy_32_16_1( specPOi[i], 13573 /*0.414213f*/ ) ), L_add( specPOr[i], Mpy_32_16_1( specPOi[i], 13573 /*0.414213f*/ ) ) ) > 0 ) /*tan(PI/8)*/ { - specPOr[i] = Mpy_32_16_1( tmp1 /** 0.555570f*/, imult1616( sign_fx( specPOr[i] ), s[60 * mult_angle] ) ); /*cos(PI*5/16)*/ + specPOr[i] = Mpy_32_16_1( tmp1 /** 0.555570f*/, imult1616( sign_fx( specPOr[i] ), s[60 * mult_angle] ) ); /*cos(PI*5/16) Q31*/ move32(); - specPOi[i] = Mpy_32_16_1( tmp1 /** 0.831470f*/, imult1616( sign_fx( specPOi[i] ), s[100 * mult_angle] ) ); + specPOi[i] = Mpy_32_16_1( tmp1 /** 0.831470f*/, imult1616( sign_fx( specPOi[i] ), s[100 * mult_angle] ) ); // Q31 move32(); } ELSE { - specPOr[i] = Mpy_32_16_1( tmp1 /** 0.195090f*/, imult1616( sign_fx( specPOr[i] ), s[20 * mult_angle] ) ); /*cos(PI*7/16)*/ + specPOr[i] = Mpy_32_16_1( tmp1 /** 0.195090f*/, imult1616( sign_fx( specPOr[i] ), s[20 * mult_angle] ) ); /*cos(PI*7/16) Q31*/ move32(); - specPOi[i] = Mpy_32_16_1( tmp1 /** 0.980785f*/, imult1616( sign_fx( specPOi[i] ), s[140 * mult_angle] ) ); + specPOi[i] = Mpy_32_16_1( tmp1 /** 0.980785f*/, imult1616( sign_fx( specPOi[i] ), s[140 * mult_angle] ) ); // Q31 move32(); } } @@ -587,11 +562,12 @@ static void calc_poc_fx( specPOi[i] = 0; move32(); } - specPOr[n0] = imult3216( Mpy_32_32_r( wnd[i * step + bias], gamma ), sign_fx( Mpy_32_32_r( specLr[n0], specRr[n0] ) ) ); + specPOr[n0] = imult3216( Mpy_32_32_r( wnd[i * step + bias], gamma ), sign_fx( Mpy_32_32_r( specLr[n0], specRr[n0] ) ) ); // Q31 move32(); hPHA->init_frmCntr = sub( hPHA->init_frmCntr, 1 ); + move16(); if ( hPHA->init_frmCntr < 0 ) { hPHA->init_frmCntr = 0; @@ -629,11 +605,11 @@ static void calc_poc_fx( Dr = L_add( specLr[i], specRr[i] ); // spec_e Di = L_add( specLi[i], specRi[i] ); // spec_e // if ( ( Nr * Nr + Ni * Ni ) > STEREO_DMX_EVS_ISD_THRES_H * ( Dr * Dr + Di * Di ) ) - if ( GT_32( Mpy_32_32_r( L_add( Mpy_32_32_r( Nr, Nr ), Mpy_32_32_r( Ni, Ni ) ), 1270700383 ), L_add( Mpy_32_32_r( Dr, Dr ), Mpy_32_32_r( Di, Di ) ) ) ) + IF( GT_32( Mpy_32_32_r( L_add( Mpy_32_32_r( Nr, Nr ), Mpy_32_32_r( Ni, Ni ) ), 1270700383 /*1/STEREO_DMX_EVS_ISD_THRES_H in Q31*/ ), L_add( Mpy_32_32_r( Dr, Dr ), Mpy_32_32_r( Di, Di ) ) ) ) { isd_cnt_h = add( isd_cnt_h, 1 ); } - if ( LT_32( L_add( Mpy_32_32_r( Nr, Nr ), Mpy_32_32_r( Ni, Ni ) ), Mpy_32_32_r( STEREO_DMX_EVS_ISD_THRES_L_Q31, L_add( Mpy_32_32_r( Dr, Dr ), Mpy_32_32_r( Di, Di ) ) ) ) ) + IF( LT_32( L_add( Mpy_32_32_r( Nr, Nr ), Mpy_32_32_r( Ni, Ni ) ), Mpy_32_32_r( STEREO_DMX_EVS_ISD_THRES_L_Q31, L_add( Mpy_32_32_r( Dr, Dr ), Mpy_32_32_r( Di, Di ) ) ) ) ) { isd_cnt_l = add( isd_cnt_l, 1 ); } @@ -826,8 +802,8 @@ static void calc_poc_fx( ICCr = L_shl_sat( ICCr, L_tmp_e ); // Q31 // hPHA->iccr_s = STEREO_DMX_EVS_ICCR_FORGETTING * hPHA->iccr_s + ( 1.0f - STEREO_DMX_EVS_ICCR_FORGETTING ) * ICCr; - hPHA->iccr_s_fx = L_add( Mpy_32_32_r( STEREO_DMX_EVS_ICCR_FORGETTING_Q31, hPHA->iccr_s_fx ), Mpy_32_32_r( MAX_32 - STEREO_DMX_EVS_ICCR_FORGETTING_Q31, ICCr ) ); - move16(); + hPHA->iccr_s_fx = L_add( Mpy_32_32_r( STEREO_DMX_EVS_ICCR_FORGETTING_Q31, hPHA->iccr_s_fx ), Mpy_32_32_r( MAX_32 - STEREO_DMX_EVS_ICCR_FORGETTING_Q31, ICCr ) ); // Q31 + move32(); IF( EQ_32( hPHA->curr_pha, STEREO_DMX_EVS_PHA_IPD ) ) { @@ -935,7 +911,7 @@ static void calc_poc_fx( rfft_pha_buf[i * 2 + 1] = imult3216( L_shl_r( L_tmp, sub( L_tmp_e, 9 ) ), sign_fx( rfft_pha_buf[i * 2 + 1] ) ); // Q22 move32(); // rfft_pha_buf[i * 2] = (float) sqrt( ( 1.0f + rfft_pha_buf[i * 2] ) / 2.0f ); - L_tmp = L_add( ONE_IN_Q21, L_shr( rfft_pha_buf[i * 2], 1 ) ); + L_tmp = L_add( ONE_IN_Q21, L_shr( rfft_pha_buf[i * 2], 1 ) ); // Q22 L_tmp_e = 9; move16(); L_tmp = Sqrt32( L_tmp, &L_tmp_e ); @@ -1005,7 +981,11 @@ static void calc_poc_fx( FOR( i = 0; i < hPHA->pha_len; i++ ) { // hPHA->p_curr_taps[n][i] *= hPHA->win[i]; +#ifdef FIX_ISSUE_1153 + hPHA->p_curr_taps_fx[n][i] = Mpy_32_16_1( hPHA->p_curr_taps_fx[n][i], hPHA->win_fx[i] ); // Q30 +#else hPHA->p_curr_taps_fx[n][i] = L_shl( Mpy_32_16_1( hPHA->p_curr_taps_fx[n][i], hPHA->win_fx[i] ), 1 ); // Q31 +#endif move32(); } @@ -1013,9 +993,22 @@ static void calc_poc_fx( move32(); energy_e = 0; move16(); +#ifdef FIX_ISSUE_1153 + Word16 shift = L_norm_arr( hPHA->p_curr_taps_fx[n], hPHA->pha_len ); + IF( shift ) + { + scale_sig32( hPHA->p_curr_taps_fx[n], hPHA->pha_len, 1 ); + shift = 1; + move16(); + } +#endif FOR( i = 0; i < hPHA->pha_len; i++ ) { +#ifdef FIX_ISSUE_1153 + energy = BASOP_Util_Add_Mant32Exp( energy, energy_e, Mpy_32_32_r( hPHA->p_curr_taps_fx[n][i], hPHA->p_curr_taps_fx[n][i] ), shl( sub( 1, shift ), 1 ), &energy_e ); +#else energy = BASOP_Util_Add_Mant32Exp( energy, energy_e, Mpy_32_32_r( hPHA->p_curr_taps_fx[n][i], hPHA->p_curr_taps_fx[n][i] ), 0, &energy_e ); +#endif } // energy = (float) inv_sqrt( energy + EPSILON ); energy = BASOP_Util_Add_Mant32Exp( energy, energy_e, EPSILON_FX_M, EPSILON_FX_E, &energy_e ); @@ -1065,7 +1058,7 @@ static void calc_poc_fx( move32(); } - tmp1 = L_shl( Mpy_32_32_r( STEREO_DMX_EVS_POC_SMOOTH_Q30, tmpPOC1[n0] ) + Mpy_32_32_r( -ONE_IN_Q28 /*0.5f * ( 1.0f - STEREO_DMX_EVS_POC_SMOOTH )*/, L_add( L_shr( tmpPOC1[n0 - 1], 1 ), L_shr( tmpPOC1[n0 + 1], 1 ) ) ), 1 ); // Q31 + tmp1 = L_shl( L_add( Mpy_32_32_r( STEREO_DMX_EVS_POC_SMOOTH_Q30, tmpPOC1[n0] ), Mpy_32_32_r( -ONE_IN_Q28 /*0.5f * ( 1.0f - STEREO_DMX_EVS_POC_SMOOTH )*/, L_add( L_shr( tmpPOC1[n0 - 1], 1 ), L_shr( tmpPOC1[n0 + 1], 1 ) ) ) ), 1 ); // Q31 tmpPOC2[n0] = L_max( tmp1, 0 ); move32(); @@ -1125,9 +1118,9 @@ static void calc_poc_fx( *-------------------------------------------------------------------*/ static Word32 find_poc_peak_fx( STEREO_DMX_EVS_POC_HANDLE hPOC, /* i/o: phase only correlation structure */ - Word32 itd_fx[], /* o : estimated itd */ + Word32 itd_fx[], /* o : estimated itd Q16 */ const Word16 input_frame, /* i : input frame length per channel */ - const Word32 ratio_fixed /* i : adapting ratio */ + const Word32 ratio_fixed /* i : adapting ratio Q31 */ ) { Word16 itd_cand[CPE_CHANNELS], i, n, cnt[CPE_CHANNELS], Lh, peak_range, *on, *itdLR, prev_off[CPE_CHANNELS], eps_fx; @@ -1144,16 +1137,13 @@ static Word32 find_poc_peak_fx( itd_cand[0] = itd_cand[1] = 0; move16(); move16(); - move16(); - move16(); width_fx = 816043776; /*0.38f in Q31*/ eps_fx = Inv16( input_frame, &eps_e ); peak_width_fx = hPOC->peak_width_fx; peakQ_fx = hPOC->peakQ_fx; // Q16 move16(); - move16(); - move16(); + set16_fx( peakQ_e, 31 - Q16, CPE_CHANNELS ); Q_fx[0] = hPOC->P_fx[Lh]; // Q31 Q_fx[1] = 0; @@ -1186,6 +1176,7 @@ static Word32 find_poc_peak_fx( } Word16 tmp1, tmp11, tmp_var1, tmp12 = 0, tmp13; + move16(); Word32 tmp4, tmp5, tmp6, tmp7, tmp8, tmp9, tmp10, tmp14, tmp15, tmp16; Word16 tmp8_e, tmp9_e, tmp10_e, tmp11_e, tmp12_e, tmp13_e, tmp15_e; @@ -1211,7 +1202,7 @@ static Word32 find_poc_peak_fx( /*compute peak_range*/ tmp1 = idiv1616( hPOC->shift_limit, STEREO_DMX_EVS_FIND_POC_PEAK_TAU ); - peak_range = idiv1616( add( (Word16) abs( itd_cand[n] ), tmp1 ), STEREO_DMX_EVS_FIND_POC_PEAK_TAU2 ); // Q0 + peak_range = idiv1616( add( extract_l( abs_s( itd_cand[n] ) ), tmp1 ), STEREO_DMX_EVS_FIND_POC_PEAK_TAU2 ); // Q0 FOR( i = 1; i <= peak_range; i++ ) { @@ -1219,7 +1210,7 @@ static Word32 find_poc_peak_fx( tmp4 = L_add( P_fx[Lh - itd_cand[n] + i], P_fx[Lh - itd_cand[n] - i] ); // Q31 cQ_fx[n] = L_add( cQ_fx[n], tmp4 ); move16(); - move16(); + move32(); } /*compute eps2_fx*/ @@ -1258,7 +1249,7 @@ static Word32 find_poc_peak_fx( IF( on[n] ) /*if channel n was active (likely to be preceding) in the previous frame*/ { tmp13_e = 0, tmp15_e = 0; - tmp13 = BASOP_Util_Divide1616_Scale( (Word16) abs( itd_cand[n] ), hPOC->shift_limit, &tmp13_e ); + tmp13 = BASOP_Util_Divide1616_Scale( abs_s( itd_cand[n] ), hPOC->shift_limit, &tmp13_e ); tmp14 = L_mult( 6554 /*0.2f Q15*/, tmp13 ); // tmp13_e tmp15 = BASOP_Util_Add_Mant32Exp( 644245120 /*0.75f in Q31*/, 0, L_negate( tmp14 ), tmp13_e, &tmp15_e ); tmp15 = Mpy_32_32( tmp15, peakQ_fx[n] ); // tmp15_e + peakQ_e[n] @@ -1307,7 +1298,7 @@ static Word32 find_poc_peak_fx( tmp13_e = 0, tmp15_e = 0; move16(); move16(); - tmp13 = BASOP_Util_Divide1616_Scale( (Word16) abs( itd_cand[n] ), hPOC->shift_limit, &tmp13_e ); + tmp13 = BASOP_Util_Divide1616_Scale( abs_s( itd_cand[n] ), hPOC->shift_limit, &tmp13_e ); tmp14 = L_mult( 6554 /*0.2f Q15*/, tmp13 ); // tmp13_e tmp15 = BASOP_Util_Add_Mant32Exp( 1610612736 /*0.75f in Q31*/, 0, L_negate( tmp14 ), tmp13_e, &tmp15_e ); @@ -1357,9 +1348,17 @@ static Word32 find_poc_peak_fx( test(); test(); test(); + test(); IF( ( on[0] && prev_off[0] ) && ( on[1] && prev_off[1] ) ) /*if both channels have newly detected as active (possibility of preceding), select channel by peakness Q[] of POC */ { - *itd_fx = ( GT_32( Q_fx[0], Q_fx[1] ) ) ? itdLR[0] : itdLR[1]; + IF( GT_32( Q_fx[0], Q_fx[1] ) ) + { + *itd_fx = itdLR[0]; + } + ELSE + { + *itd_fx = itdLR[1]; + } } ELSE IF( ( on[0] && prev_off[0] ) && ( EQ_16( var0_flag, 1 ) ) ) /* if channel 0 becomes active, select channel 0*/ { @@ -1383,7 +1382,14 @@ static Word32 find_poc_peak_fx( } ELSE /*follow the status of the previous frame*/ { - *itd_fx = ( *itd_fx > 0 ) ? itdLR[0] : itdLR[1]; + IF( *itd_fx > 0 ) + { + *itd_fx = itdLR[0]; + } + ELSE + { + *itd_fx = itdLR[1]; + } } move32(); @@ -1403,12 +1409,12 @@ static Word32 find_poc_peak_fx( Word32 Q_sub_sqrt = Sqrt32( L_abs( L_sub( Q_fx[0], Q_fx[1] ) ), &Q_sub_sqrt_e ); cconfidence_fx = Q_sub_sqrt; move16(); - move16(); + move32(); Word32 cconfidence_var1 = Mpy_32_32( hPOC->confidence_fx, STEREO_DMX_EVS_CORR_FORGETTING_FX ); // Q31 Word32 cconfidence_var2 = Mpy_32_32( L_shr( cconfidence_fx, negate( Q_sub_sqrt_e ) ) /*Q31*/, L_sub( ONE_IN_Q30, L_shr( STEREO_DMX_EVS_CORR_FORGETTING_FX, 1 ) ) ); // Q30 hPOC->confidence_fx = L_add( cconfidence_var1, L_shl( cconfidence_var2, 1 ) ); // Q31 - move16(); + move32(); return hPOC->confidence_fx; } @@ -1480,11 +1486,11 @@ static ivas_error estimate_itd_fx( spec_e = s_max( sub( specL_e, s_min( getScaleFactor32( specLr, input_frame / 2 + 1 ), getScaleFactor32( specLi, input_frame / 2 + 1 ) ) ), sub( specR_e, s_min( getScaleFactor32( specRr, input_frame / 2 + 1 ), getScaleFactor32( specRi, input_frame / 2 + 1 ) ) ) ); - spec_e = add( spec_e, 2 ); // guard bits - scale_sig32( specLr, input_frame / 2 + 1, sub( specL_e, spec_e ) ); - scale_sig32( specLi, input_frame / 2 + 1, sub( specL_e, spec_e ) ); - scale_sig32( specRr, input_frame / 2 + 1, sub( specR_e, spec_e ) ); - scale_sig32( specRi, input_frame / 2 + 1, sub( specR_e, spec_e ) ); + spec_e = add( spec_e, 2 ); // guard bits + scale_sig32( specLr, add( shr( input_frame, 1 ), 1 ), sub( specL_e, spec_e ) ); // Q(31-(specL_e-spec_e)) + scale_sig32( specLi, add( shr( input_frame, 1 ), 1 ), sub( specL_e, spec_e ) ); // Q(31-(specL_e-spec_e)) + scale_sig32( specRr, add( shr( input_frame, 1 ), 1 ), sub( specR_e, spec_e ) ); // Q(31-(specR_e-spec_e)) + scale_sig32( specRi, add( shr( input_frame, 1 ), 1 ), sub( specR_e, spec_e ) ); // Q(31-(specR_e-spec_e)) calc_poc_fx( hPOC, hPHA, hPOC->wnd_fx, rfft_coef, specLr, specLi, specRr, specRi, spec_e, input_frame ); @@ -1554,20 +1560,20 @@ static void calc_energy_fx( move32(); wnd_diff_fx = 107374182; // initialising for L_FRAME16k =( 1.0f /20) in Q31; move32(); - switch ( input_frame ) + SWITCH( input_frame ) { case L_FRAME16k: wnd_fx = 53687091; // wnd = 0.5f / (float) adaptlen; adaptlen= 20;in Q31 wnd_diff_fx = 107374182; // wnd = 1.0f / (float) adaptlen;adaptlen= 20;in Q31 - break; + BREAK; case L_FRAME32k: wnd_fx = 26843545; // wnd = 0.5f / (float) adaptlen; adaptlen= 40;in Q31 wnd_diff_fx = 53687091; // wnd = 1.0f / (float) adaptlen;adaptlen= 40;in Q31 - break; + BREAK; case L_FRAME48k: wnd_fx = 17895697; // wnd = 0.5f / (float) adaptlen; adaptlen= 60;in Q31 wnd_diff_fx = 35791394; // wnd = 1.0f / (float) adaptlen;adaptlen= 60;in Q31 - break; + BREAK; } move32(); move32(); @@ -1605,7 +1611,7 @@ static void calc_energy_fx( q_temp32 = add( add( q_E, sub( 15, temp_e ) ), 16 ); // *energy = *energy * ratio_float + ( E / (float) input_frame ) * ( 1.0f - ratio_float ); *energy_fx = BASOP_Util_Add_Mant32Exp( Mpy_32_32( *energy_fx, ratio_float_fx ), *energy_fx_e, Mpy_32_32( temp32, L_sub( MAX_32, ratio_float_fx ) ), sub( 31, q_temp32 ), energy_fx_e ); - + move32(); return; } @@ -1616,7 +1622,7 @@ static void calc_energy_fx( *-------------------------------------------------------------------*/ static void adapt_gain_fx( const Word32 src_fx[], /* i : input signal Q16 */ - Word32 dst_fx[], /* o : output signal */ + Word32 dst_fx[], /* o : output signal Q16 */ const Word32 gain_fx, /* i : adapting gain Q31*/ const Word32 old_gain_fx, /* i : adapting prev gain Q31*/ const Word16 input_frame, /* i : input frame length per channel */ @@ -1860,7 +1866,7 @@ void stereo_dmx_evs_enc_fx( W_tmp = W_mult_32_32( p_sub_frame[n], p_sub_frame[n] ); W_tmp_q = W_norm( W_tmp ); W_tmp = W_shl( W_tmp, W_tmp_q ); - L_tmp1 = W_extract_h( W_tmp ); + L_tmp1 = W_extract_h( W_tmp ); // Q(31-(30-W_tmp_q)) L_tmp1_e = sub( 15 * 2, W_tmp_q ); subframe_energy[m] = BASOP_Util_Add_Mant32Exp( subframe_energy[m], subframe_energy_e[m], L_tmp1, L_tmp1_e, &subframe_energy_e[m] ); move32(); @@ -1898,7 +1904,7 @@ void stereo_dmx_evs_enc_fx( L_tmp2 = BASOP_Util_Divide3232_Scale_cadence( subframe_energy[m], L_tmp1, &L_tmp2_e ); L_tmp2_e = add( L_tmp2_e, sub( subframe_energy_e[m], L_tmp1_e ) ); // if ( subframe_energy[m] / ( subframe_energy[m - 1] + EPSILON ) > STEREO_DMX_EVS_TRNS_DTC_INST ) - if ( BASOP_Util_Cmp_Mant32Exp( L_tmp2, L_tmp2_e, (Word16) STEREO_DMX_EVS_TRNS_DTC_INST, 31 ) > 0 ) + if ( BASOP_Util_Cmp_Mant32Exp( L_tmp2, L_tmp2_e, STEREO_DMX_EVS_TRNS_DTC_INST_Q0, 31 ) > 0 ) { is_transient = 1; move16(); @@ -1928,7 +1934,7 @@ void stereo_dmx_evs_enc_fx( move16(); } - create_M_signal_fx( data_fx[0], data_fx[1], dmx_poc_data, dmx_weight, input_frame, hStereoDmxEVS->s_wnd_fx, + create_M_signal_fx( data_fx[0], data_fx[1], dmx_poc_data, L_deposit_h( dmx_weight ), input_frame, hStereoDmxEVS->s_wnd_fx, hStereoDmxEVS->dmx_weight_fx, hStereoDmxEVS->pre_dmx_energy_fx, hStereoDmxEVS->pre_dmx_energy_fx_e, hStereoDmxEVS->aux_dmx_energy_fx, hStereoDmxEVS->aux_dmx_energy_fx_e ); // Downscaling signals to avoid accumulation overflows @@ -2084,7 +2090,7 @@ void stereo_dmx_evs_enc_fx( move16(); } - IF( hStereoDmxEVS->hPHA->curr_prc == STEREO_DMX_EVS_PRC_POC ) + IF( EQ_32( hStereoDmxEVS->hPHA->curr_prc, STEREO_DMX_EVS_PRC_POC ) ) { p_dmx_data = dmx_poc_data; @@ -2123,7 +2129,7 @@ void stereo_dmx_evs_enc_fx( } } - Copy_Scale_sig32_16( p_dmx_data, data, n_samples, 5 ); + Copy_Scale_sig32_16( p_dmx_data, data, n_samples, 5 ); // Q11->Q0 return; @@ -2276,16 +2282,16 @@ ivas_error stereo_dmx_evs_init_encoder_fx( SWITCH( input_frame ) { case 160: - hStereoDmxEVS->hPOC->eps_fx = 84331486; + hStereoDmxEVS->hPOC->eps_fx = 84331486; // (2.0f * EVS_PI / (160)) in Q31 BREAK; case 320: - hStereoDmxEVS->hPOC->eps_fx = 42165743; + hStereoDmxEVS->hPOC->eps_fx = 42165743; // (2.0f * EVS_PI / (160)) in Q31 BREAK; case 640: - hStereoDmxEVS->hPOC->eps_fx = 21082871; + hStereoDmxEVS->hPOC->eps_fx = 21082871; // (2.0f * EVS_PI / (160)) in Q31 BREAK; case 960: - hStereoDmxEVS->hPOC->eps_fx = 14055248; + hStereoDmxEVS->hPOC->eps_fx = 14055248; // (2.0f * EVS_PI / (160)) in Q31 BREAK; } move32(); @@ -2333,7 +2339,7 @@ ivas_error stereo_dmx_evs_init_encoder_fx( move16(); hStereoDmxEVS->hPHA->prc_thres = STEREO_DMX_EVS_SWTCH_PRC_THRES_16; move16(); - hStereoDmxEVS->hPHA->crst_fctr_fx = (Word16) STEREO_DMX_EVS_CRST_FCTR_16; + hStereoDmxEVS->hPHA->crst_fctr_fx = STEREO_DMX_EVS_CRST_FCTR_16_Q0; move32(); } ELSE IF( EQ_32( input_Fs, 32000 ) ) @@ -2344,7 +2350,7 @@ ivas_error stereo_dmx_evs_init_encoder_fx( move16(); hStereoDmxEVS->hPHA->prc_thres = STEREO_DMX_EVS_SWTCH_PRC_THRES_32; move16(); - hStereoDmxEVS->hPHA->crst_fctr_fx = (Word16) STEREO_DMX_EVS_CRST_FCTR_32; + hStereoDmxEVS->hPHA->crst_fctr_fx = STEREO_DMX_EVS_CRST_FCTR_32_Q0; move32(); } ELSE IF( EQ_32( input_Fs, 48000 ) ) @@ -2355,7 +2361,7 @@ ivas_error stereo_dmx_evs_init_encoder_fx( move16(); hStereoDmxEVS->hPHA->prc_thres = STEREO_DMX_EVS_SWTCH_PRC_THRES_48; move16(); - hStereoDmxEVS->hPHA->crst_fctr_fx = (Word16) STEREO_DMX_EVS_CRST_FCTR_48; + hStereoDmxEVS->hPHA->crst_fctr_fx = STEREO_DMX_EVS_CRST_FCTR_48_Q0; move32(); } ELSE @@ -2380,14 +2386,15 @@ ivas_error stereo_dmx_evs_init_encoder_fx( trans_len = idiv1616( pha_len, 20 ); set16_fx( hStereoDmxEVS->hPHA->win_fx, 29491 /*1.8f in Q15*/, sub( pha_len, trans_len ) ); hStereoDmxEVS->hPHA->win_fx[0] = ONE_IN_Q14; + move16(); // tmp_r = 1.0f / ( ( trans_len * 2 ) + 1 ); tmp_r = div_s( 1, add( shl( trans_len, 1 ), 1 ) ); win = &( hStereoDmxEVS->hPHA->win_fx[pha_len - trans_len] ); FOR( n = 0; n < trans_len; n++ ) { // win[n] = ( 0.5f * ( 1.0f + cosf( ( PI2 * ( n + 1 ) ) * tmp_r ) ) ) * 1.8f; - win[n] = mult_r( add( ONE_IN_Q14, getCosWord16R2( imult1616( add( n, 1 ), tmp_r ) ) ), 29491 ); - move32(); + win[n] = mult_r( add( ONE_IN_Q14, getCosWord16R2( imult1616( add( n, 1 ), tmp_r ) ) ), 29491 /*1.8/2 in Q15*/ ); + move16(); } fad_g = hStereoDmxEVS->hPHA->fad_g_fx; @@ -2395,7 +2402,7 @@ ivas_error stereo_dmx_evs_init_encoder_fx( fad_r = BASOP_Util_Divide3232_Scale_cadence( 1, add( fad_len, 1 ), &tmp_e ); fad_r = L_shl_r( fad_r, tmp_e ); fad_len2 = shr( fad_len, 1 ); - FOR( ( n = 0, m = sub( fad_len, 1 ) ); n < fad_len2; ( n++, m-- ) ) + FOR( ( n = 0, m = ( fad_len - 1 ) ); n < fad_len2; ( n++, m-- ) ) { fad_g[n] = imult3216( fad_r, add( n, 1 ) ); move32(); @@ -2487,19 +2494,19 @@ ivas_error stereo_dmx_evs_init_encoder_fx( SWITCH( input_Fs ) { case 8000: - hStereoDmxEVS->hPHA->fad_len_prc = (Word16) STEREO_DMX_EVS_FADE_LEN_PRC * 8; + hStereoDmxEVS->hPHA->fad_len_prc = STEREO_DMX_EVS_FADE_LEN_PRC_Q0 * 8; move16(); BREAK; case 16000: - hStereoDmxEVS->hPHA->fad_len_prc = (Word16) STEREO_DMX_EVS_FADE_LEN_PRC * 16; + hStereoDmxEVS->hPHA->fad_len_prc = STEREO_DMX_EVS_FADE_LEN_PRC_Q0 * 16; move16(); BREAK; case 32000: - hStereoDmxEVS->hPHA->fad_len_prc = (Word16) STEREO_DMX_EVS_FADE_LEN_PRC * 32; + hStereoDmxEVS->hPHA->fad_len_prc = STEREO_DMX_EVS_FADE_LEN_PRC_Q0 * 32; move16(); BREAK; case 48000: - hStereoDmxEVS->hPHA->fad_len_prc = (Word16) STEREO_DMX_EVS_FADE_LEN_PRC * 48; + hStereoDmxEVS->hPHA->fad_len_prc = STEREO_DMX_EVS_FADE_LEN_PRC_Q0 * 48; move16(); BREAK; default: @@ -2513,7 +2520,7 @@ ivas_error stereo_dmx_evs_init_encoder_fx( fad_r = BASOP_Util_Divide3232_Scale_cadence( 1, add( fad_len, 1 ), &tmp_e ); fad_r = L_shl_r( fad_r, tmp_e ); fad_len2 = shr( fad_len, 1 ); - FOR( ( n = 0, m = sub( fad_len, 1 ) ); n < fad_len2; ( n++, m-- ) ) + FOR( ( n = 0, m = ( fad_len - 1 ) ); n < fad_len2; ( n++, m-- ) ) { fad_g[n] = imult3216( fad_r, add( n, 1 ) ); move32(); diff --git a/lib_enc/ivas_stereo_eclvq_enc.c b/lib_enc/ivas_stereo_eclvq_enc_fx.c similarity index 90% rename from lib_enc/ivas_stereo_eclvq_enc.c rename to lib_enc/ivas_stereo_eclvq_enc_fx.c index d108e3add54804aea7d3c317911eadb24f69084d..3abc07811450ec80c6e98e508eef739e2d647f27 100644 --- a/lib_enc/ivas_stereo_eclvq_enc.c +++ b/lib_enc/ivas_stereo_eclvq_enc_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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,13 +33,11 @@ #include #include "options.h" #include -#include "ivas_prot.h" #include "ivas_prot_fx.h" #include "ivas_cnst.h" #include "ivas_rom_com.h" #include "ivas_rom_enc.h" #include -#include "prot.h" #include "prot_fx.h" #include "wmc_auto.h" /* used only for norm_s in the code_length_from_count function */ @@ -69,7 +67,7 @@ static Word16 get_sign_fx( Word16 n ) * * ---------------------------------------------------------------*/ void ECSQ_quantize_vector_fx( - const Word32 *input, + const Word32 *input, // Q(31-input_e) const Word16 input_e, const Word32 global_gain, // Q15 const Word16 N, @@ -80,13 +78,25 @@ void ECSQ_quantize_vector_fx( Word16 inv_global_gain_e; // inv_global_gain = 1.0f / global_gain; - inv_global_gain = BASOP_Util_Divide3232_Scale_cadence( ONE_IN_Q15, global_gain, &inv_global_gain_e ); - inv_global_gain = L_shl( inv_global_gain, inv_global_gain_e ); // Q31 - FOR( i = 0; i < N; ++i ) + IF( EQ_32( global_gain, ONE_IN_Q15 ) ) { - // output[i] = (int16_t) round_f( input[i] * inv_global_gain ); - output[i] = extract_l( L_shr_r( Mpy_32_32( input[i], inv_global_gain ), sub( 31, input_e ) ) ); - move16(); + FOR( i = 0; i < N; ++i ) + { + // output[i] = (int16_t) round_f( input[i] * inv_global_gain ); + output[i] = extract_l( L_shr_r( input[i], sub( 31, input_e ) ) ); + move16(); + } + } + ELSE + { + inv_global_gain = BASOP_Util_Divide3232_Scale_cadence( ONE_IN_Q15, global_gain, &inv_global_gain_e ); + inv_global_gain = L_shl( inv_global_gain, inv_global_gain_e ); // Q31 + FOR( i = 0; i < N; ++i ) + { + // output[i] = (int16_t) round_f( input[i] * inv_global_gain ); + output[i] = extract_l( L_shr_r( Mpy_32_32( input[i], inv_global_gain ), sub( 31, input_e ) ) ); + move16(); + } } return; @@ -99,7 +109,7 @@ void ECSQ_quantize_vector_fx( * if all the values in output are zero, it returns 0 * ---------------------------------------------------------------*/ Word32 ECSQ_compute_optimal_gain_fx( // Q15 - const Word32 *input, + const Word32 *input, // Q(31-input_e) const Word16 input_e, const Word16 N, const Word16 *output ) @@ -107,6 +117,7 @@ Word32 ECSQ_compute_optimal_gain_fx( // Q15 Word16 i; Word32 sum_sq_output; Word32 sum_input_output; + Word16 sum_input_output_e; Word32 optimal_global_gain; Word16 optimal_global_gain_e; @@ -114,12 +125,14 @@ Word32 ECSQ_compute_optimal_gain_fx( // Q15 move32(); sum_input_output = 0; move32(); + sum_input_output_e = 0; + move16(); FOR( i = 0; i < N; ++i ) { // sum_sq_output += (float) output[i] * (float) output[i]; - sum_sq_output = L_add( sum_sq_output, L_shl( L_mult0( output[i], output[i] ), 15 ) ); // Q15 + sum_sq_output = L_add( sum_sq_output, L_mult0( output[i], output[i] ) ); // sum_input_output += input[i] * (float) output[i]; - sum_input_output = L_add( sum_input_output, L_shr( W_extract_l( W_mult0_32_32( input[i], output[i] ) ), sub( 16, input_e ) ) ); // Q15 + sum_input_output = BASOP_Util_Add_Mant32Exp( sum_input_output, sum_input_output_e, W_extract_l( W_mult0_32_32( input[i], output[i] ) ), input_e, &sum_input_output_e ); } optimal_global_gain = 0; @@ -127,8 +140,8 @@ Word32 ECSQ_compute_optimal_gain_fx( // Q15 IF( sum_sq_output != 0 ) { // optimal_global_gain = sum_input_output / sum_sq_output; - optimal_global_gain = BASOP_Util_Divide3232_Scale_cadence( sum_input_output, sum_sq_output, &optimal_global_gain_e ); - optimal_global_gain = L_shr( optimal_global_gain, sub( 16, optimal_global_gain_e ) ); // Q15 + optimal_global_gain = BASOP_Util_Divide3232_Scale_cadence( sum_input_output, sum_sq_output, &optimal_global_gain_e ); // 31 - ( sum_input_output_e - 31 + optimal_global_gain_e ) = 62 - ( sum_input_output_e + optimal_global_gain_e ) + optimal_global_gain = L_shr( optimal_global_gain, sub( sub( 62, add( sum_input_output_e, optimal_global_gain_e ) ), 15 ) ); // Q15 } return optimal_global_gain; @@ -182,7 +195,7 @@ static void arith_encode_bit_fx( IF( ecsq_inst->encoding_active ) { /* call to the actual AC */ - rc_uni_enc_encode_bits( rc_st_enc, bit, 1 ); + rc_uni_enc_encode_bits_fx( rc_st_enc, bit, 1 ); } return; @@ -206,7 +219,7 @@ static void arith_encode_bits_fx( IF( ecsq_inst->encoding_active ) { - rc_uni_enc_encode_bits( rc_st_enc, n, size ); + rc_uni_enc_encode_bits_fx( rc_st_enc, n, size ); } return; @@ -267,7 +280,7 @@ static void arith_encode_bit_prob_fx( IF( ecsq_inst->encoding_active ) { /* call to the actual AC */ - rc_uni_enc_encode_fast( rc_st_enc, bit * count0, count, 14 ); + rc_uni_enc_encode_fast_fx( rc_st_enc, u_extract_l( L_mult0( bit, count0 ) ), count, 14 ); } return; @@ -299,7 +312,7 @@ static void arith_encode_prob_fx( IF( ecsq_inst->encoding_active ) { /* call to the actual AC */ - rc_uni_enc_encode_fast( rc_st_enc, ECSQ_PROB_TOTAL - table[symbol], count, 14 ); + rc_uni_enc_encode_fast_fx( rc_st_enc, u_extract_l( UL_subNsD( ECSQ_PROB_TOTAL, table[symbol] ) ), count, 14 ); } return; @@ -336,7 +349,7 @@ static void arith_encode_elias_mod_fx( arith_encode_bit_fx( ecsq_inst, 1 ); /* encode the n_bits data bits at once */ - arith_encode_bits_fx( ecsq_inst, n - ( 1 << n_bits ), n_bits ); + arith_encode_bits_fx( ecsq_inst, u_extract_l( L_sub( n, ( shl( 1, n_bits ) ) ) ), n_bits ); } return; @@ -404,8 +417,7 @@ static Word16 get_best_param_fx( sum_abs = L_add( sum_abs, L_shl( abs_s( val ), 10 ) ); // Q10 IF( val == 0 ) { - ++count0; - move16(); + count0 = add( count0, 1 ); } } @@ -435,8 +447,7 @@ static Word16 get_best_param_fx( /* the best Laplace integer parameter is floor(log2(avg_abs_sum) + log2(offset)) */ // param = (int16_t) floor( log_base2( *avg_abs_sum * offset ) ); - param = sub( 31, norm_l( L_sub( L_shr( Mpy_32_16_1( *avg_abs_sum, offset ), 10 - 1 ), 1 ) ) ); - // sub( 31, norm_l( L_sub( n, 1 ) ) ) + param = extract_l( L_shr( L_add( BASOP_Util_Log2( Mpy_32_16_1( *avg_abs_sum, offset ) ), 738197504 /* (31-(10+14-15)) <<25 */ ), 25 ) ); /* limit param value to the available exponent range */ param = s_max( ECSQ_ALL_ZERO_PARAM + 1, param ); @@ -536,7 +547,7 @@ static Word32 ECSQ_encode_raw_fx( Word16 *input, const Word16 N ) { - int32_t bit_count_estimate_initial; + Word32 bit_count_estimate_initial; Word32 total_size; // Q10 Word16 segment_count; @@ -556,7 +567,7 @@ static Word32 ECSQ_encode_raw_fx( const UWord16 *tab_vals, *tab_abs_lsbs; bit_count_estimate_initial = ecsq_inst->bit_count_estimate; - + move32(); total_size = 0; move32(); @@ -595,7 +606,7 @@ static Word32 ECSQ_encode_raw_fx( FOR( param = first_param; param <= last_param; ++param ) { param_zb = sub( param, ECSQ_ALL_ZERO_PARAM ); - count = ECSQ_tab_param[ecsq_inst->config_index][param_zb] - ECSQ_tab_param[ecsq_inst->config_index][param_zb + 1]; + count = sub( ECSQ_tab_param[ecsq_inst->config_index][param_zb], ECSQ_tab_param[ecsq_inst->config_index][param_zb + 1] ); // test_size = scale_Q10 * code_length_from_count( count ); test_size = code_length_from_count_fx( count ); // Q10 @@ -611,6 +622,7 @@ static Word32 ECSQ_encode_raw_fx( } best_params[segment] = best_param; + move16(); total_size = L_add( total_size, best_size ); } @@ -629,6 +641,7 @@ static Word32 ECSQ_encode_raw_fx( seg_start = imult1616( segment, ECSQ_SEGMENT_SIZE ); seg_stop = add( seg_start, ECSQ_SEGMENT_SIZE - 1 ); seg_length = ECSQ_SEGMENT_SIZE; + move16(); IF( EQ_16( segment, sub( segment_count, 1 ) ) ) { seg_stop = sub( N, 1 ); @@ -744,7 +757,7 @@ static Word32 ECSQ_encode_raw_fx( Word32 ECSQ_encode_target_SNR_fx( ECSQ_instance *ecsq_inst, - const Word32 *input, + const Word32 *input, // Q(31-input_e) const Word16 input_e, const Word16 N, const Word32 target_SNR, // Q25 @@ -767,6 +780,8 @@ Word32 ECSQ_encode_target_SNR_fx( // const Word32 global_gain_step = 1165018877; // powf( 10.0f, ECLVQ_INV_GLOBAL_GAIN_FACTOR ) in Q30 Word32 L_tmp1; Word16 L_tmp1_e; + Word64 W_tmp1; + Word16 shift; // max_bits_fixpt = max_bits * 1024; /* max_bits_fixpt is in 22Q10 fixed-point representation */ max_bits_fixpt = L_shl( max_bits, 10 ); /* max_bits_fixpt is in 22Q10 fixed-point representation */ @@ -775,6 +790,7 @@ Word32 ECSQ_encode_target_SNR_fx( { /* a target SNR of 0.0 dB is already achieved by quantizing all values in the vector to zero */ *global_gain_index_output = ECSQ_GLOBAL_GAIN_INDEX_ALL_ZERO; + move16(); IF( output != NULL ) { set32_fx( output, 0, N ); @@ -787,10 +803,24 @@ Word32 ECSQ_encode_target_SNR_fx( move32(); sum_squared_e = 0; move16(); + FOR( i = 0; i < N; ++i ) { // sum_squared += input[i] * input[i]; - sum_squared = BASOP_Util_Add_Mant32Exp( sum_squared, sum_squared_e, Mpy_32_32( input[i], input[i] ), shl( input_e, 1 ), &sum_squared_e ); + W_tmp1 = W_mult0_32_32( input[i], input[i] ); // 2(31-input_e) + IF( W_tmp1 == 0 ) + { + shift = 32; + move16(); + } + ELSE + { + shift = W_norm( W_tmp1 ); + } + shift = sub( 32, shift ); + L_tmp1 = W_extract_l( W_shr( W_tmp1, shift ) ); // 2(31-input_e) - shift = 62 - 2input_e - shift + L_tmp1_e = sub( add( shl( input_e, 1 ), shift ), 31 ); // 31 - (62 - 2input_e - shift) = 2input_e + shift - 31 + sum_squared = BASOP_Util_Add_Mant32Exp( sum_squared, sum_squared_e, L_tmp1, L_tmp1_e, &sum_squared_e ); } // if ( sum_squared < 0.25f ) /* all the values in the input vector will always be quantized to zero */ @@ -830,6 +860,7 @@ Word32 ECSQ_encode_target_SNR_fx( // global_gain = sqrtf( target_sum_squared_error / ( 0.0833f * (float) N ) ); global_gain = BASOP_Util_Divide3232_Scale_cadence( target_sum_squared_error, L_mult0( 5459 /*0.0833f in Q16*/, N ), &global_gain_e ); global_gain_e = add( global_gain_e, sub( target_sum_squared_error_e, 15 ) ); + global_gain = Sqrt32( global_gain, &global_gain_e ); global_gain = L_shr( global_gain, sub( 16, global_gain_e ) ); // Q15 /* quantize the estimated global_gain */ global_gain_index = ECSQ_quantize_gain_fx( global_gain ); @@ -845,9 +876,9 @@ Word32 ECSQ_encode_target_SNR_fx( test_size = ECSQ_encode_raw_fx( ecsq_inst, quantized_input, N ); - ++iteration; - move16(); + iteration = add( iteration, 1 ); Word16 tmp_e; + test(); WHILE( GT_32( test_size, max_bits_fixpt ) && LT_16( iteration, ECSQ_MAX_BITS_ITERATIONS ) ) { test(); @@ -856,7 +887,13 @@ Word32 ECSQ_encode_target_SNR_fx( // adjust_global_gain_index = (int16_t) ceil( adjust_size / ( 1024.0f * N * log_base2( global_gain_step ) ) ); adjust_global_gain_index = BASOP_Util_Divide3232_Scale_cadence( adjust_size, N, &tmp_e ); adjust_global_gain_index = Mpy_32_32( adjust_global_gain_index, 17816838 /*/ ( 1024.0f * log_base2( global_gain_step ) )*/ ); - adjust_global_gain_index = extract_l( L_shr( L_add( adjust_global_gain_index, L_shl( 1, sub( 31, tmp_e ) ) ), sub( 31, tmp_e ) ) ); + IF( NE_32( adjust_global_gain_index, L_shl( L_shr( adjust_global_gain_index, sub( 31, tmp_e ) ), sub( 31, tmp_e ) ) ) ) + { + adjust_global_gain_index = BASOP_Util_Add_Mant32Exp( adjust_global_gain_index, tmp_e, ONE_IN_Q30, 1, &tmp_e ); + } + + adjust_global_gain_index = extract_l( L_shr( adjust_global_gain_index, sub( 31, tmp_e ) ) ); + global_gain_index = s_min( add( global_gain_index, (Word16) adjust_global_gain_index ), 126 ); global_gain = ECSQ_dequantize_gain_fx( global_gain_index ); // Q15 @@ -866,8 +903,7 @@ Word32 ECSQ_encode_target_SNR_fx( test_size = ECSQ_encode_raw_fx( ecsq_inst, quantized_input, N ); - ++iteration; - move16(); + iteration = add( iteration, 1 ); } IF( GT_32( test_size, max_bits_fixpt ) ) @@ -885,7 +921,7 @@ Word32 ECSQ_encode_target_SNR_fx( /* do the quantization with the dequantized final global_gain_index found */ global_gain = ECSQ_dequantize_gain_fx( global_gain_index ); // Q15 - IF( global_gain_index != global_gain_index_last ) + IF( NE_16( global_gain_index, global_gain_index_last ) ) { ECSQ_quantize_vector_fx( input, input_e, global_gain, N, quantized_input ); } diff --git a/lib_enc/ivas_stereo_ica_enc.c b/lib_enc/ivas_stereo_ica_enc_fx.c similarity index 76% rename from lib_enc/ivas_stereo_ica_enc.c rename to lib_enc/ivas_stereo_ica_enc_fx.c index dbf4e1f7cfe5cb2b388a9e22e8133c46a40e9c3a..0577987067b0619181a31f741ac782884febb4a2 100644 --- a/lib_enc/ivas_stereo_ica_enc.c +++ b/lib_enc/ivas_stereo_ica_enc_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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,12 +36,10 @@ #include #include "cnst.h" #include "ivas_cnst.h" -#include "prot.h" -#include "ivas_prot.h" +#include "prot_fx.h" #include "wmc_auto.h" #include "rom_com.h" #include "ivas_rom_com.h" -#include "prot_fx.h" #include "ivas_prot_fx.h" #include "ivas_rom_com_fx.h" @@ -52,14 +50,14 @@ static void unclr_calc_corr_features_fx( STEREO_CLASSIF_HANDLE hStereoClassif, /* i/o: stereo classifier handle */ STEREO_TCA_ENC_HANDLE hStereoTCA, /* i/o: ICA Stereo Encoder handle */ - Word32 buf1[], /* i : left channel */ - Word32 buf2[], /* i : right channel */ + Word32 buf1[], /* i : left channel q_com*/ + Word32 buf2[], /* i : right channel q_com*/ Word16 q_com, - const Word16 length, /* i : length of input signal buffers */ - Word32 corrEst[], /* i : buffer containing inter-channel correlation values */ + const Word16 length, /* i : length of input signal buffers Q0*/ + Word32 corrEst[], /* i : buffer containing inter-channel correlation values Q31-corrEst_exp*/ Word16 corrEst_exp, - const int16_t lagSearchRange[], /* i : minimum and maximum lags for corrEst[] */ - Word32 *corrEst_ncorr, /* o : norm. x-correlation btw. current and previous correlation buffers */ + const Word16 lagSearchRange[], /* i : minimum and maximum lags for corrEst[] Q0*/ + Word32 *corrEst_ncorr, /* o : norm. x-correlation btw. current and previous correlation buffers Q31-corrEst_ncorr_exp*/ Word16 *corrEst_ncorr_exp ); @@ -67,7 +65,7 @@ static void unclr_calc_corr_features_fx( #define XH_BIAS_FX_Q15 13107 #define XL_WIDTH_FX_Q15 3932 #define XH_WIDTH_FX_Q15 4915 -#define SMOOTH_DIST_FACTOR_FX_Q15 14418 +#define SMOOTH_DIST_FACTOR_FX_Q15 13107 #define A_BIAS_FX_Q15 3277 #define B_BIAS_FX_Q15 -16384 #define A_WIDTH_FX_Q31 32212264 @@ -82,11 +80,11 @@ static void unclr_calc_corr_features_fx( * ---------------------------------------------------------------*/ static void tcaTargetCh_LA_fx( STEREO_TCA_ENC_HANDLE hStereoTCA, - Word32 *ptrChanL, - Word32 *ptrChanR, + Word32 *ptrChanL, /* q_com */ + Word32 *ptrChanR, /* q_com */ Word16 *q_com, - const Word16 currentNCShift, - const Word16 input_frame ) + const Word16 currentNCShift, /* Q0 */ + const Word16 input_frame /* Q0 */ ) { Word16 i, j; Word16 tempS, temp, sine_inp; @@ -99,7 +97,7 @@ static void tcaTargetCh_LA_fx( ref_exp = sub( 31, *q_com ); target_exp = sub( 31, *q_com ); - set16_fx( target_exp_temp, target_exp, L_FRAME48k + 30 ); + set16_fx( target_exp_temp, target_exp, L_FRAME48k + currentNCShift ); IF( EQ_16( hStereoTCA->refChanIndx, L_CH_INDX ) ) { @@ -112,7 +110,7 @@ static void tcaTargetCh_LA_fx( target = ptrChanL; } - tempS = NS2SA( L_mult0( input_frame, FRAMES_PER_SEC ), L_SAMPLES_LA_NS ); + tempS = NS2SA_FX2( L_mult0( input_frame, FRAMES_PER_SEC ), L_SAMPLES_LA_NS ); tempF1 = 0; move32(); tempF1_exp = 0; @@ -121,44 +119,46 @@ static void tcaTargetCh_LA_fx( move32(); tempF2_exp = 0; move16(); - FOR( i = 0; i < sub( input_frame, currentNCShift ); i++ ) + FOR( i = 0; i < ( input_frame - currentNCShift ); i++ ) { - tempF1 = BASOP_Util_Add_Mant32Exp( tempF1, tempF1_exp, L_abs( ref[i] ), ref_exp, &tempF1_exp ); - tempF2 = BASOP_Util_Add_Mant32Exp( tempF2, tempF2_exp, L_abs( target[i + currentNCShift] ), target_exp, &tempF2_exp ); + tempF1 = BASOP_Util_Add_Mant32Exp( tempF1, tempF1_exp, L_abs( ref[i] ), ref_exp, &tempF1_exp ); /* Q31-tempF1_exp */ + tempF2 = BASOP_Util_Add_Mant32Exp( tempF2, tempF2_exp, L_abs( target[i + currentNCShift] ), target_exp, &tempF2_exp ); /* Q31-tempF2_exp */ } IF( tempF1 == 0 ) { - gAdj = ONE_IN_Q31; + gAdj = ONE_IN_Q31; /* Q31 */ move32(); gAdj_exp = 0; move16(); } ELSE { - Word32 deno = BASOP_Util_Add_Mant32Exp( tempF1, tempF1_exp, -21475 /*0.00001f in Q31*/, 0, &temp ); + Word32 deno = BASOP_Util_Add_Mant32Exp( tempF1, tempF1_exp, -21475 /*0.00001f in Q31*/, 0, &temp ); /* Q31-temp */ Word16 deno_exp; IF( deno > 0 ) { deno = tempF1; + move32(); deno_exp = tempF1_exp; + move16(); } ELSE { deno = 21475; + move32(); deno_exp = 0; + move16(); } - move32(); - move32(); - gAdj = BASOP_Util_Divide3232_Scale_cadence( tempF2, deno, &gAdj_exp ); + gAdj = BASOP_Util_Divide3232_Scale_cadence( tempF2, deno, &gAdj_exp ); /* Q31-gAdj_exp */ gAdj_exp = add( gAdj_exp, sub( tempF2_exp, deno_exp ) ); } FOR( i = 0; i < tempS; i++ ) { - sine_inp = BASOP_Util_Divide1616_Scale( add( shl( i, 10 ), 512 ), shl( tempS, 1 ), &temp ); - sine_inp = shl_sat( sine_inp, add( temp, -10 ) ); - win[i] = getSineWord16R2( shr( sine_inp, 1 ) ); + sine_inp = BASOP_Util_Divide1616_Scale( add( shl( i, 10 ), 512 /* 0.5 Q10 */ ), shl( tempS, 1 ), &temp ); /* Q15-(temp+(15-10)) */ + sine_inp = shl_sat( sine_inp, add( temp, -10 ) ); /*Q0*/ + win[i] = getSineWord16R2( shr( sine_inp, 1 ) ); /*Q15*/ move16(); } @@ -167,9 +167,9 @@ static void tcaTargetCh_LA_fx( Word16 exp_com = target_exp_temp[0]; move16(); - FOR( i = sub( input_frame, add( currentNCShift, tempS ) ); i < sub( input_frame, currentNCShift ); ( i++, j++ ) ) + FOR( i = ( input_frame - ( currentNCShift + tempS ) ); i < ( input_frame - currentNCShift ); ( i++, j++ ) ) { - target[i + currentNCShift] = BASOP_Util_Add_Mant32Exp( Mpy_32_32( Mpy_32_16_1( gAdj, win[j] ), ref[i] ), add( ref_exp, gAdj_exp ), Mpy_32_16_1( target[i + currentNCShift], sub( MAX_16, win[j] ) ), target_exp, &temp ); + target[i + currentNCShift] = BASOP_Util_Add_Mant32Exp( Mpy_32_32( Mpy_32_16_1( gAdj, win[j] ), ref[i] ), add( ref_exp, gAdj_exp ), Mpy_32_16_1( target[i + currentNCShift], sub( MAX_16, win[j] ) ), target_exp, &temp ); /* Q31-temp */ move32(); target_exp_temp[i + currentNCShift] = temp; move16(); @@ -178,18 +178,18 @@ static void tcaTargetCh_LA_fx( FOR( ; i < input_frame; i++ ) { - target[i + currentNCShift] = Mpy_32_32( gAdj, ref[i] ); + target[i + currentNCShift] = Mpy_32_32( gAdj, ref[i] ); /* Q31-target_exp_temp */ move32(); target_exp_temp[i + currentNCShift] = add( gAdj_exp, ref_exp ); move16(); exp_com = s_max( exp_com, target_exp_temp[i + currentNCShift] ); } - FOR( i = 0; i < input_frame; i++ ) + FOR( i = 0; i < input_frame + currentNCShift; i++ ) { - target[i] = L_shl( target[i], sub( target_exp_temp[i], exp_com ) ); + target[i] = L_shl( target[i], sub( target_exp_temp[i], exp_com ) ); /* Q31-exp_com */ move32(); - ref[i] = L_shl( ref[i], sub( ref_exp, exp_com ) ); + ref[i] = L_shl( ref[i], sub( ref_exp, exp_com ) ); /* Q31-exp_com */ move32(); } *q_com = sub( 31, exp_com ); @@ -206,8 +206,8 @@ static void tcaTargetCh_LA_fx( void spectral_balancer_fx16( Word16 *signal, /* i/o : signal Qx */ Word16 *mem, /* i/o : mem Qx */ - const Word16 lg, /* i : input signal length */ - const Word16 coeff_set /* i : coefficient set */ + const Word16 lg, /* i : input signal length Q0*/ + const Word16 coeff_set /* i : coefficient set Q0*/ ) { Word16 i; @@ -268,26 +268,26 @@ void spectral_balancer_fx16( FOR( i = 0; i < lg; i++ ) { - x2 = x1; + x2 = x1; /*Qx*/ move16(); - x1 = x0; + x1 = x0; /*Qx*/ move16(); - x0 = signal[i]; + x0 = signal[i]; /*Qx*/ move16(); // y0 = (y1 * a1) + (y2 * a2) + (x0 * b0) + (x1 * b1) + (x2 * b2); y0 = extract_l( W_extract_l( W_shr( W_mac_32_16( W_mac_32_16( W_mac_32_16( W_mac_32_16( W_mult_32_16( a1, y1 ), a2, y2 ), b0, x0 ), b1, x1 ), b2, x2 ), 30 ) ) ); // Qx - signal[i] = y0; + signal[i] = y0; /*Qx*/ move16(); - y2 = y1; + y2 = y1; /*Qx*/ move16(); - y1 = y0; + y1 = y0; /*Qx*/ move16(); } - mem[0] = y1; - mem[1] = y2; - mem[2] = x0; - mem[3] = x1; + mem[0] = y1; /*Qx*/ + mem[1] = y2; /*Qx*/ + mem[2] = x0; /*Qx*/ + mem[3] = x1; /*Qx*/ move16(); move16(); move16(); @@ -299,18 +299,18 @@ void spectral_balancer_fx16( void spectral_balancer_fx( Word32 *signal, /* i/o : signal Qx */ Word32 *mem, /* i/o : mem Qx */ - const Word16 lg, /* i : input signal length */ - const Word16 coeff_set /* i : coefficient set */ + const Word16 lg, /* i : input signal length Q0*/ + const Word16 coeff_set /* i : coefficient set Q0*/ ) { Word16 i; Word32 x0, x1, x2, y0, y1, y2; Word32 a1, a2, b0, b1, b2; - y1 = mem[0]; - y2 = mem[1]; - x0 = mem[2]; - x1 = mem[3]; + y1 = mem[0]; /*Qx*/ + y2 = mem[1]; /*Qx*/ + x0 = mem[2]; /*Qx*/ + x1 = mem[3]; /*Qx*/ move32(); move32(); move32(); @@ -351,28 +351,28 @@ void spectral_balancer_fx( FOR( i = 0; i < lg; i++ ) { - x2 = x1; + x2 = x1; /*Qx*/ move16(); - x1 = x0; + x1 = x0; /*Qx*/ move16(); - x0 = signal[i]; + x0 = signal[i]; /*Qx*/ move16(); y0 = W_extract_l( W_shr( W_mac_32_32( W_mac_32_32( W_mac_32_32( W_mac_32_32( W_mult_32_32( a1, y1 ), a2, y2 ), b0, x0 ), b1, x1 ), b2, x2 ), 30 ) ); // Qx - signal[i] = y0; + signal[i] = y0; /*Qx*/ move16(); - y2 = y1; + y2 = y1; /*Qx*/ move16(); - y1 = y0; + y1 = y0; /*Qx*/ move16(); } - mem[0] = y1; + mem[0] = y1; /*Qx*/ move32(); - mem[1] = y2; + mem[1] = y2; /*Qx*/ move32(); - mem[2] = x0; + mem[2] = x0; /*Qx*/ move32(); - mem[3] = x1; + mem[3] = x1; /*Qx*/ move32(); return; @@ -384,14 +384,14 @@ void spectral_balancer_fx( * * De-emphasize and resample the L and R channels. * ---------------------------------------------------------------*/ -static void deEmphResample( +static void deEmphResample_fx( STEREO_TCA_ENC_HANDLE hStereoTCA, /* i/o: Stereo TCA encoder handle */ const Word32 *tempChan1_fx, /* i : Stereo data Qx*/ const Word32 *tempChan2_fx, /* i : Stereo data Qx*/ - Word32 *chan1_fx, // Qx - Word32 *chan2_fx, // Qx - const Word16 input_frame, - const Word16 dsFactor ) + Word32 *chan1_fx, /*Qx*/ + Word32 *chan2_fx, /*Qx*/ + const Word16 input_frame, /*Q0*/ + const Word16 dsFactor /*Q0*/ ) { Word32 buf1_fx[L_FRAME48k], buf2_fx[L_FRAME48k]; Word32 tempBuf1_fx[2 * L_FRAME_DS], tempBuf2_fx[2 * L_FRAME_DS]; @@ -399,23 +399,23 @@ static void deEmphResample( Word16 dsFac1, dsFac2; /* Estimate first and second stage downsample factors */ - dsFac1 = shr( dsFactor, 1 ); - dsFac2 = idiv1616( dsFactor, dsFac1 ); + dsFac1 = shr( dsFactor, 1 ); /*Qx*/ + dsFac2 = idiv1616( dsFactor, dsFac1 ); /*Qx*/ /* convert stereo data to two distinct channels, e.g., L, R */ - Copy32( tempChan1_fx, buf1_fx, input_frame ); - Copy32( tempChan2_fx, buf2_fx, input_frame ); + Copy32( tempChan1_fx, buf1_fx, input_frame ); /*Qx*/ + Copy32( tempChan2_fx, buf2_fx, input_frame ); /*Qx*/ /* De-emphasis, 1/(1-mu z^-1), and resample, stage 1 */ deemph_fx_32( 0, buf1_fx, PREEMPH_FAC_16k, input_frame, &hStereoTCA->memdecim_fx[0] ); deemph_fx_32( 0, buf2_fx, PREEMPH_FAC_16k, input_frame, &hStereoTCA->memdecim_fx[1] ); - FOR( i = 0; i < idiv1616( input_frame, dsFac1 ); i++ ) + FOR( i = 0; i < ( input_frame / dsFac1 ); i++ ) { - tempBuf1_fx[i] = buf1_fx[i * dsFac1]; + tempBuf1_fx[i] = buf1_fx[i * dsFac1]; /*Qx*/ move32(); - tempBuf2_fx[i] = buf2_fx[i * dsFac1]; + tempBuf2_fx[i] = buf2_fx[i * dsFac1]; /*Qx*/ move32(); } @@ -423,11 +423,11 @@ static void deEmphResample( deemph_fx_32( 0, tempBuf1_fx, PREEMPH_FAC_16k, idiv1616( input_frame, dsFac1 ), &hStereoTCA->memdecim_fx[2] ); deemph_fx_32( 0, tempBuf2_fx, PREEMPH_FAC_16k, idiv1616( input_frame, dsFac1 ), &hStereoTCA->memdecim_fx[3] ); - FOR( i = 0; i < idiv1616( input_frame, dsFactor ); i++ ) + FOR( i = 0; i < ( input_frame / dsFactor ); i++ ) { - chan1_fx[i] = tempBuf1_fx[i * dsFac2]; + chan1_fx[i] = tempBuf1_fx[i * dsFac2]; /*Qx*/ move32(); - chan2_fx[i] = tempBuf2_fx[i * dsFac2]; + chan2_fx[i] = tempBuf2_fx[i * dsFac2]; /*Qx*/ move32(); } @@ -444,13 +444,13 @@ static void deEmphResample( * ---------------------------------------------------------------*/ static void utilCrossCorr_mod_fx( STEREO_TCA_ENC_HANDLE hStereoTCA, /* i/o: ICA Stereo Encoder handle */ - Word32 *buf1, - Word32 *buf2, + Word32 *buf1, /*q_com*/ + Word32 *buf2, /*q_com*/ const Word16 q_com, - Word32 *corrEst, /* o : correlation estimate */ - Word16 *corrEst_Exp, /* o : correlation estimate */ - const Word16 *lagSearchRange, - const Word16 len ) + Word32 *corrEst, /* o : correlation estimate Q31-corrEst_Exp*/ + Word16 *corrEst_Exp, /* o : correlation estimate Q31-corrEst_Exp*/ + const Word16 *lagSearchRange, /*Q0*/ + const Word16 len /*Q0*/ ) { Word32 C, E1, E2, C_C_mem; Word16 i, j, E1_exp, E2_exp, Inv_Tot_E_exp, k, C_exp, exp, gb; @@ -463,33 +463,34 @@ static void utilCrossCorr_mod_fx( gb = 0; move16(); - if ( LT_16( L_norm_arr( buf1, len ), 2 ) ) + IF( LT_16( L_norm_arr( buf1, len ), 2 ) ) { gb = 2; move16(); } - E1 = sum2_32_exp_fx( buf1, len, &E1_exp, gb ); + E1 = sum2_32_exp_fx( buf1, len, &E1_exp, gb ); /* Q31-E1_exp */ gb = 0; move16(); - if ( LT_16( L_norm_arr( buf2, len ), 2 ) ) + IF( LT_16( L_norm_arr( buf2, len ), 2 ) ) { gb = 2; move16(); } - E2 = sum2_32_exp_fx( buf2, len, &E2_exp, gb ); + E2 = sum2_32_exp_fx( buf2, len, &E2_exp, gb ); /* Q31-E2_exp */ - Word32 E1_mul = BASOP_Util_Add_Mant32Exp( E1, E1_exp, hStereoTCA->E1_mem_fx, hStereoTCA->E1_mem_exp, &E1_exp ); - Word32 E2_mul = BASOP_Util_Add_Mant32Exp( E2, E2_exp, hStereoTCA->E2_mem_fx, hStereoTCA->E2_mem_exp, &E2_exp ); + Word16 temp1, temp2; + Word32 E1_mul = BASOP_Util_Add_Mant32Exp( E1, E1_exp, hStereoTCA->E1_mem_fx, hStereoTCA->E1_mem_exp, &temp1 ); /* Q31-temp1 */ + Word32 E2_mul = BASOP_Util_Add_Mant32Exp( E2, E2_exp, hStereoTCA->E2_mem_fx, hStereoTCA->E2_mem_exp, &temp2 ); /* Q31-temp2 */ Word32 sqr_inp = Mpy_32_32( E1_mul, E2_mul ); - Word16 sq_exp = add( E1_exp, E2_exp ); + Word16 sq_exp = add( temp1, temp2 ); IF( sqr_inp ) { - sqr_inp = Sqrt32( sqr_inp, &sq_exp ); - sqr_inp = Mpy_32_32( sqr_inp, 1342177280 /* 320 in Q22*/ ); + sqr_inp = Sqrt32( sqr_inp, &sq_exp ); /* Q31-sq_exp */ + sqr_inp = Mpy_32_32( sqr_inp, 1342177280 /* 320 in Q22*/ ); /* Q31-sq_exp+22-31 */ sq_exp = add( sq_exp, 9 ); - Inv_Tot_E = BASOP_Util_Divide3232_Scale( ONE_IN_Q31, sqr_inp, &Inv_Tot_E_exp ); + Inv_Tot_E = BASOP_Util_Divide3232_Scale( ONE_IN_Q31, sqr_inp, &Inv_Tot_E_exp ); /* Q15-Inv_Tot_E_exp */ Inv_Tot_E_exp = add( Inv_Tot_E_exp, sub( 0, sq_exp ) ); } ELSE @@ -500,9 +501,9 @@ static void utilCrossCorr_mod_fx( move16(); } - hStereoTCA->E1_mem_fx = E1; + hStereoTCA->E1_mem_fx = E1; /* Q31-E1_exp */ move32(); - hStereoTCA->E2_mem_fx = E2; + hStereoTCA->E2_mem_fx = E2; /* Q31-E2_exp */ move32(); hStereoTCA->E1_mem_exp = E1_exp; move16(); @@ -511,21 +512,20 @@ static void utilCrossCorr_mod_fx( *corrEst_Exp = corrEst_exp[0]; move16(); - /* FOR BASOP causing error/warning */ - for ( i = lagSearchRange[0], j = 0; i <= 0; i++, j++ ) + FOR( ( i = lagSearchRange[0], j = 0 ); i <= 0; ( i++, j++ ) ) { L64_sum = 1; move64(); FOR( k = 0; k < len; k++ ) { - L64_sum = W_mac_32_32( L64_sum, buf1[k], buf2[k + i] ); + L64_sum = W_mac_32_32( L64_sum, buf1[k], buf2[k + i] ); /* 2*q_com+1 */ } k = W_norm( L64_sum ); - L64_sum = W_shl( L64_sum, k ); - C = W_extract_h( L64_sum ); // ener_side_q + L64_sum = W_shl( L64_sum, k ); /* 2*q_com+1+k */ + C = W_extract_h( L64_sum ); // ener_side_q C_exp = sub( 31, sub( add( add( shl( q_com, 1 ), 1 ), k ), 32 ) ); - C_C_mem = BASOP_Util_Add_Mant32Exp( C, C_exp, hStereoTCA->C_mem_fx[j], hStereoTCA->C_mem_exp[j], &exp ); - corrEst[j] = Mpy_32_16_1( C_C_mem, Inv_Tot_E ); + C_C_mem = BASOP_Util_Add_Mant32Exp( C, C_exp, hStereoTCA->C_mem_fx[j], hStereoTCA->C_mem_exp[j], &exp ); /* Q31-exp */ + corrEst[j] = Mpy_32_16_1( C_C_mem, Inv_Tot_E ); /* Q31-corrEst_exp */ move32(); corrEst_exp[j] = add( Inv_Tot_E_exp, exp ); move16(); @@ -537,21 +537,20 @@ static void utilCrossCorr_mod_fx( move16(); } - /* FOR BASOP causing error/warning */ - for ( ; i <= lagSearchRange[1]; i++, j++ ) + FOR( ; i <= lagSearchRange[1]; ( i++, j++ ) ) { L64_sum = 1; move64(); FOR( k = 0; k < len; k++ ) { - L64_sum = W_mac_32_32( L64_sum, buf1[k - i], buf2[k] ); + L64_sum = W_mac_32_32( L64_sum, buf1[k - i], buf2[k] ); /* 2*q_com+1 */ } k = W_norm( L64_sum ); - L64_sum = W_shl( L64_sum, k ); - C = W_extract_h( L64_sum ); // ener_side_q + L64_sum = W_shl( L64_sum, k ); /* 2*q_com+1+k */ + C = W_extract_h( L64_sum ); // ener_side_q C_exp = sub( 31, sub( add( add( shl( q_com, 1 ), 1 ), k ), 32 ) ); - C_C_mem = BASOP_Util_Add_Mant32Exp( C, C_exp, hStereoTCA->C_mem_fx[j], hStereoTCA->C_mem_exp[j], &exp ); - corrEst[j] = Mpy_32_16_1( C_C_mem, Inv_Tot_E ); + C_C_mem = BASOP_Util_Add_Mant32Exp( C, C_exp, hStereoTCA->C_mem_fx[j], hStereoTCA->C_mem_exp[j], &exp ); /* Q31-exp */ + corrEst[j] = Mpy_32_16_1( C_C_mem, Inv_Tot_E ); /* Q31-corrEst_exp */ move32(); corrEst_exp[j] = add( Inv_Tot_E_exp, exp ); move16(); @@ -567,7 +566,7 @@ static void utilCrossCorr_mod_fx( FOR( i = 0; i < ( 2 * L_NCSHIFT_DS + 1 ); i++ ) { - corrEst[i] = L_shl( corrEst[i], sub( corrEst_exp[i], *corrEst_Exp ) ); + corrEst[i] = L_shl( corrEst[i], sub( corrEst_exp[i], *corrEst_Exp ) ); /* Q31-corrEst_Exp */ move32(); } @@ -584,12 +583,12 @@ static void utilCrossCorr_fx( Word16 buf1_q, const Word32 *buf2, // buf2_q Word16 buf2_q, - const Word32 *win, - Word32 *corrEst, /* o : correlation estimate corrEst_e */ + const Word32 *win, /*Qx*/ + Word32 *corrEst, /* o : correlation estimate corrEst_e */ Word16 *corrEst_e, - const Word16 *lagSearchRange, - const Word16 len, - const Word16 winSymmFlag ) + const Word16 *lagSearchRange, /*Q0*/ + const Word16 len, /*Q0*/ + const Word16 winSymmFlag /*Q0*/ ) { Word32 tempBuf1[L_FRAME48k]; Word32 tempBuf2[L_FRAME48k]; @@ -619,17 +618,17 @@ static void utilCrossCorr_fx( FOR( i = shr( len, 1 ); i < len; i++ ) { - tempBuf1[i] = Mpy_32_32( win[len - 1 - i], buf1[i] ); + tempBuf1[i] = Mpy_32_32( win[len - 1 - i], buf1[i] ); /* Qx+buf1_q-31 */ move32(); - tempBuf2[i] = Mpy_32_32( win[len - 1 - i], buf2[i] ); + tempBuf2[i] = Mpy_32_32( win[len - 1 - i], buf2[i] ); /* Qx+buf2_q-31 */ move32(); } } } ELSE { - Copy32( buf1, tempBuf1, len ); - Copy32( buf2, tempBuf2, len ); + Copy32( buf1, tempBuf1, len ); /* buf1_q */ + Copy32( buf2, tempBuf2, len ); /* buf2_q */ } Word16 temp1_e = sub( Q31, buf1_q ); @@ -653,20 +652,20 @@ static void utilCrossCorr_fx( assert( lagSearchRange[0] <= lagSearchRange[1] ); /* first part of noncausal corr est. */ - for ( i = lagSearchRange[0], j = 0; i <= s_min( 0, lagSearchRange[1] ); ( i++, j++ ) ) + FOR( ( i = lagSearchRange[0], j = 0 ); i <= s_min( 0, lagSearchRange[1] ); ( i++, j++ ) ) { L64_sum = 0; move64(); - FOR( k = 0; k < add( len, i ); k++ ) + FOR( k = 0; k < ( len + i ); k++ ) { - L64_sum = W_mac_32_32( L64_sum, buf1[k - i], buf2[k] ); + L64_sum = W_mac_32_32( L64_sum, buf1[k - i], buf2[k] ); /* buf1_q+buf2_q+1 */ } k = W_norm( L64_sum ); - L64_sum = W_shl( L64_sum, k ); - temp = W_extract_h( L64_sum ); + L64_sum = W_shl( L64_sum, k ); /* buf1_q+buf2_q+1+k */ + temp = W_extract_h( L64_sum ); /* buf1_q+buf2_q+1+k-32 */ res_e = sub( 31, sub( add( add( add( buf1_q, buf2_q ), 1 ), k ), 32 ) ); - corrEst[j] = L_deposit_h( BASOP_Util_Divide3216_Scale( temp, ( len + i ), &tmp_e ) ); + corrEst[j] = L_deposit_h( BASOP_Util_Divide3216_Scale( temp, ( len + i ), &tmp_e ) ); /* Q31-max_e */ move32(); corrEstTemp_e[j] = add( tmp_e, sub( res_e, 15 ) ); move16(); @@ -674,20 +673,20 @@ static void utilCrossCorr_fx( } /* second part of noncausal corr est. */ - for ( ; i <= lagSearchRange[1]; ( i++, j++ ) ) + FOR( ; i <= lagSearchRange[1]; ( i++, j++ ) ) { L64_sum = 1; move64(); FOR( k = 0; k < sub( len, i ); k++ ) { - L64_sum = W_mac_32_32( L64_sum, buf1[k], buf2[k + i] ); + L64_sum = W_mac_32_32( L64_sum, buf1[k], buf2[k + i] ); /* buf1_q+buf2_q+1 */ } k = W_norm( L64_sum ); - L64_sum = W_shl( L64_sum, k ); - temp = W_extract_h( L64_sum ); + L64_sum = W_shl( L64_sum, k ); /* buf1_q+buf2_q+1+k */ + temp = W_extract_h( L64_sum ); /* buf1_q+buf2_q+1+k-32 */ res_e = sub( 31, sub( add( add( add( buf1_q, buf2_q ), 1 ), k ), 32 ) ); - corrEst[j] = L_deposit_h( BASOP_Util_Divide3216_Scale( temp, ( len - i ), &tmp_e ) ); + corrEst[j] = L_deposit_h( BASOP_Util_Divide3216_Scale( temp, ( len - i ), &tmp_e ) ); /* Q31-max_e */ move32(); corrEstTemp_e[j] = add( tmp_e, sub( res_e, 15 ) ); move16(); @@ -698,7 +697,7 @@ static void utilCrossCorr_fx( FOR( i = 0; i < j; i++ ) { - corrEst[i] = L_shr( corrEst[i], sub( max_e, corrEstTemp_e[i] ) ); + corrEst[i] = L_shr( corrEst[i], sub( max_e, corrEstTemp_e[i] ) ); /* Q31-corrEstTemp_e */ move32(); } @@ -716,22 +715,23 @@ static void utilCrossCorr_fx( * Non-causal shift estimation to encode future samples. * ---------------------------------------------------------------*/ -static Word16 TRUNC_FX( Word32 inp, Word16 exp ) +static Word16 TRUNC_FX( Word32 inp /*Q31-exp*/, Word16 exp ) { Word16 ouptut; Word32 temp; - temp = L_shr( inp, sub( 31, exp ) ); + temp = L_shr( inp, sub( 31, exp ) ); /*Q0*/ test(); IF( GT_32( temp, 32767 ) || LT_32( temp, -32768 ) ) { + test(); IF( temp < 0 ) { - ouptut = -32768; + ouptut = -32768; /*Q0*/ } ELSE { - ouptut = 32767; + ouptut = 32767; /*Q0*/ } move16(); } @@ -739,31 +739,31 @@ static Word16 TRUNC_FX( Word32 inp, Word16 exp ) { IF( NE_32( temp, L_shl_sat( 1, sub( 31, exp ) ) ) ) { - Word32 temp1 = L_add_sat( inp, L_shl_sat( 1, sub( 31, add( exp, 1 ) ) ) ); - ouptut = (Word16) L_shr( temp1, sub( 31, exp ) ); + Word32 temp1 = L_add_sat( inp, L_shl_sat( 1, sub( 31, add( exp, 1 ) ) ) ); /* Q31-exp */ + ouptut = extract_l( L_shr( temp1, sub( 31, exp ) ) ); /*Q0*/ IF( temp < 0 ) { - ouptut = add( ouptut, 1 ); + ouptut = add( ouptut, 1 ); /*Q0*/ } } ELSE { - ouptut = (Word16) temp; + ouptut = extract_l( temp ); /*Q0*/ move16(); } } - return ouptut; + return ouptut; /*Q0*/ } static void corrStatsEst_fx( STEREO_TCA_ENC_HANDLE hStereoTCA, /* i/o: Stereo TCA Encoder handle */ Word32 *buf1_fx, /* i : channel 1 q_com*/ Word32 *buf2_fx, /* i : channel 2 q_com*/ Word16 q_com, - const Word16 bufLenDS, /* i : buffer length */ - const Word16 dsFactor, /* i : buffer length */ - const Word16 vad_flag1, /* i : VAD flag channel 1 */ - const Word16 vad_flag2, /* i : VAD flag channel 2 */ + const Word16 bufLenDS, /* i : buffer length Q0*/ + const Word16 dsFactor, /* i : buffer length Q0*/ + const Word16 vad_flag1, /* i : VAD flag channel 1 Q0*/ + const Word16 vad_flag2, /* i : VAD flag channel 2 Q0*/ STEREO_CLASSIF_HANDLE hStereoClassif /* i/o: stereo classifier handle */ ) { @@ -831,46 +831,36 @@ static void corrStatsEst_fx( /* back up the corrEst */ FOR( i = 0; i < 2; i++ ) { - Copy32( hStereoTCA->corrEstPrev_fx[i + 1], hStereoTCA->corrEstPrev_fx[i], tempLen ); + Copy32( hStereoTCA->corrEstPrev_fx[i + 1], hStereoTCA->corrEstPrev_fx[i], tempLen ); /* Q31-hStereoTCA->corrEstPrev_exp */ } temp = getScaleFactor32( corrEst_fx, 2 * L_NCSHIFT_DS + 1 ); - scale_sig32( corrEst_fx, 2 * L_NCSHIFT_DS + 1, temp ); + scale_sig32( corrEst_fx, 2 * L_NCSHIFT_DS + 1, temp ); /* Q31-corrEst_exp */ corrEst_exp = sub( corrEst_exp, temp ); - IF( GT_16( corrEst_exp, hStereoTCA->corrEstPrev_exp ) ) - { - scale_sig32( hStereoTCA->corrEstPrev_fx[0], 2 * L_NCSHIFT_DS + 1, sub( hStereoTCA->corrEstPrev_exp, corrEst_exp ) ); - scale_sig32( hStereoTCA->corrEstPrev_fx[1], 2 * L_NCSHIFT_DS + 1, sub( hStereoTCA->corrEstPrev_exp, corrEst_exp ) ); - Copy32( corrEst_fx, hStereoTCA->corrEstPrev_fx[2], tempLen ); - hStereoTCA->corrEstPrev_exp = corrEst_exp; - move16(); - } - ELSE - { - Copy32( corrEst_fx, hStereoTCA->corrEstPrev_fx[2], tempLen ); - scale_sig32( hStereoTCA->corrEstPrev_fx[2], 2 * L_NCSHIFT_DS + 1, sub( corrEst_exp, hStereoTCA->corrEstPrev_exp ) ); - } - scale_sig32( hStereoTCA->corrEstPrev_fx[0], 2 * L_NCSHIFT_DS + 1, -1 ); - scale_sig32( hStereoTCA->corrEstPrev_fx[1], 2 * L_NCSHIFT_DS + 1, -1 ); - scale_sig32( hStereoTCA->corrEstPrev_fx[2], 2 * L_NCSHIFT_DS + 1, -1 ); - hStereoTCA->corrEstPrev_exp = add( hStereoTCA->corrEstPrev_exp, 1 ); + Copy32( corrEst_fx, hStereoTCA->corrEstPrev_fx[2], tempLen ); /* Q31-corrEst_exp */ + hStereoTCA->corrEstPrev_exp = corrEst_exp; + move16(); + Word16 gb = find_guarded_bits_fx( 2 * L_NCSHIFT_DS + 1 ); + + scale_sig32( hStereoTCA->corrEstPrev_fx[2], 2 * L_NCSHIFT_DS + 1, -gb ); /* Q31-hStereoTCA->corrEstPrev_exp-1 */ + hStereoTCA->corrEstPrev_exp = add( hStereoTCA->corrEstPrev_exp, gb ); move16(); Word32 buf1_fx_temp[L_FRAME_DS]; Word32 buf2_fx_temp[L_FRAME_DS]; - Copy32( buf1_fx, buf1_fx_temp, L_FRAME_DS ); - Copy32( buf2_fx, buf2_fx_temp, L_FRAME_DS ); + Copy32( buf1_fx, buf1_fx_temp, L_FRAME_DS ); /* q_com */ + Copy32( buf2_fx, buf2_fx_temp, L_FRAME_DS ); /* q_com */ - scale_sig32( buf1_fx_temp, L_FRAME_DS, -4 ); - scale_sig32( buf2_fx_temp, L_FRAME_DS, -4 ); + scale_sig32( buf1_fx_temp, L_FRAME_DS, -4 ); /* q_com-4 */ + scale_sig32( buf2_fx_temp, L_FRAME_DS, -4 ); /* q_com-4 */ temp_A_fx = L_add( sumAbs_fx( buf1_fx_temp, L_FRAME_DS - L_XCORRMEM_DS ), sumAbs_fx( buf2_fx_temp, L_FRAME_DS - L_XCORRMEM_DS ) ); temp_B_fx = L_add( sumAbs_fx( buf1_fx_temp + ( L_FRAME_DS - L_XCORRMEM_DS ), L_XCORRMEM_DS ), sumAbs_fx( buf2_fx_temp + ( L_FRAME_DS - L_XCORRMEM_DS ), L_XCORRMEM_DS ) ); - tempF_fx = BASOP_Util_Add_Mant32Exp( L_add( temp_A_fx, temp_B_fx ), sub( 31, sub( q_com, 4 ) ), hStereoTCA->mem_tempF_fx, hStereoTCA->mem_tempF_exp, &temp ); + tempF_fx = BASOP_Util_Add_Mant32Exp( L_add( temp_A_fx, temp_B_fx ), sub( 31, sub( q_com, 4 ) ), hStereoTCA->mem_tempF_fx, hStereoTCA->mem_tempF_exp, &temp ); /* Q31-tempF_exp */ Word16 tempF_exp = temp; - hStereoTCA->mem_tempF_fx = temp_B_fx; + hStereoTCA->mem_tempF_fx = temp_B_fx; /* Q31-hStereoTCA->mem_tempF_exp */ move32(); hStereoTCA->mem_tempF_exp = sub( 31, sub( q_com, 4 ) ); move16(); @@ -894,18 +884,18 @@ static void corrStatsEst_fx( move32(); /* long term corr Stats estimation */ - v_multc_fixed_16( hStereoTCA->corrEstLT_fx, alpha_fx, hStereoTCA->corrEstLT_fx, 2 * L_NCSHIFT_DS + 1 ); - v_multc_fixed_16( corrEst_fx, sub( MAX_16, alpha_fx ), corrEst_fx, 2 * L_NCSHIFT_DS + 1 ); + v_multc_fixed_16( hStereoTCA->corrEstLT_fx, alpha_fx, hStereoTCA->corrEstLT_fx, 2 * L_NCSHIFT_DS + 1 ); /* Q31-hStereoTCA->corrEstLT_exp */ + v_multc_fixed_16( corrEst_fx, sub( MAX_16, alpha_fx ), corrEst_fx, 2 * L_NCSHIFT_DS + 1 ); /* Q31-corrEst_exp */ v_add_fixed_me( hStereoTCA->corrEstLT_fx, hStereoTCA->corrEstLT_exp, corrEst_fx, corrEst_exp, hStereoTCA->corrEstLT_fx, &hStereoTCA->corrEstLT_exp, 2 * L_NCSHIFT_DS + 1, 0 ); - hStereoTCA->ica_envVarLT_fx = BASOP_Util_Add_Mant32Exp( Mpy_32_16_1( hStereoTCA->ica_envVarLT_fx, SMOOTH_ENV_FACTOR_FX_Q15 ), hStereoTCA->ica_envVarLT_exp, Mpy_32_16_1( tempF_fx, ONE_IN_Q15 - SMOOTH_ENV_FACTOR_FX_Q15 ), tempF_exp, &hStereoTCA->ica_envVarLT_exp ); // SMOOTH_ENV_FACTOR_FX_Q15 + hStereoTCA->ica_envVarLT_fx = BASOP_Util_Add_Mant32Exp( Mpy_32_16_1( hStereoTCA->ica_envVarLT_fx, SMOOTH_ENV_FACTOR_FX_Q15 ), hStereoTCA->ica_envVarLT_exp, Mpy_32_16_1( tempF_fx, ONE_IN_Q15 - SMOOTH_ENV_FACTOR_FX_Q15 ), tempF_exp, &hStereoTCA->ica_envVarLT_exp ); // SMOOTH_ENV_FACTOR_FX_Q15 (Q31-hStereoTCA->ica_envVarLT_exp) move32(); - Copy32( hStereoTCA->corrEstLT_fx, corrEst_fx, 2 * L_NCSHIFT_DS + 1 ); + Copy32( hStereoTCA->corrEstLT_fx, corrEst_fx, 2 * L_NCSHIFT_DS + 1 ); /* Q31-hStereoTCA->corrEstLT_exp */ corrEst_exp = hStereoTCA->corrEstLT_exp; move16(); - Y_hat_fx = hStereoTCA->delay_0_mem_fx[0]; + Y_hat_fx = hStereoTCA->delay_0_mem_fx[0]; /* Q31-hStereoTCA->delay_0_mem_exp */ move32(); Y_hat_exp = hStereoTCA->delay_0_mem_exp; move16(); @@ -913,36 +903,38 @@ static void corrStatsEst_fx( /* Note: keep X_hat and X_SQR_hat calculations inside the loop to allow future tuning of MAX_DELAYREGLEN */ FOR( i = 1; i < MAX_DELAYREGLEN; i++ ) { - X_hat_fx = BASOP_Util_Add_Mant32Exp( X_hat_fx, X_hat_exp, L_shl( i, 27 ), 4, &X_hat_exp ); - Y_hat_fx = BASOP_Util_Add_Mant32Exp( Y_hat_fx, Y_hat_exp, hStereoTCA->delay_0_mem_fx[i], hStereoTCA->delay_0_mem_exp, &Y_hat_exp ); - XY_hat_fx = BASOP_Util_Add_Mant32Exp( XY_hat_fx, XY_hat_exp, Mpy_32_32( hStereoTCA->delay_0_mem_fx[i], L_shl( i, 27 ) ), add( 4, hStereoTCA->delay_0_mem_exp ), &XY_hat_exp ); - X_SQR_hat_fx = BASOP_Util_Add_Mant32Exp( X_SQR_hat_fx, X_SQR_hat_exp, Mpy_32_32( L_shl( i, 27 ), L_shl( i, 27 ) ), 8, &X_SQR_hat_exp ); + X_hat_fx = BASOP_Util_Add_Mant32Exp( X_hat_fx, X_hat_exp, L_shl( i, 27 ), 4, &X_hat_exp ); /* Q31-X_hat_exp */ + Y_hat_fx = BASOP_Util_Add_Mant32Exp( Y_hat_fx, Y_hat_exp, hStereoTCA->delay_0_mem_fx[i], hStereoTCA->delay_0_mem_exp, &Y_hat_exp ); /* Q31-Y_hat_exp */ + XY_hat_fx = BASOP_Util_Add_Mant32Exp( XY_hat_fx, XY_hat_exp, Mpy_32_32( hStereoTCA->delay_0_mem_fx[i], L_shl( i, 27 ) ), add( 4, hStereoTCA->delay_0_mem_exp ), &XY_hat_exp ); /* Q31-XY_hat_exp */ + X_SQR_hat_fx = BASOP_Util_Add_Mant32Exp( X_SQR_hat_fx, X_SQR_hat_exp, Mpy_32_32( L_shl( i, 27 ), L_shl( i, 27 ) ), 8, &X_SQR_hat_exp ); /* Q31-X_SQR_hat_exp */ } - X_hat_fx = Mpy_32_16_1( X_hat_fx, INV_MAX_DELAYREGLEN_FX_Q15 ); - Y_hat_fx = Mpy_32_16_1( Y_hat_fx, INV_MAX_DELAYREGLEN_FX_Q15 ); - XY_hat_fx = Mpy_32_16_1( XY_hat_fx, INV_MAX_DELAYREGLEN_FX_Q15 ); - X_SQR_hat_fx = Mpy_32_16_1( X_SQR_hat_fx, INV_MAX_DELAYREGLEN_FX_Q15 ); + X_hat_fx = Mpy_32_16_1( X_hat_fx, INV_MAX_DELAYREGLEN_FX_Q15 ); /* Q31-X_hat_exp */ + Y_hat_fx = Mpy_32_16_1( Y_hat_fx, INV_MAX_DELAYREGLEN_FX_Q15 ); /* Q31-Y_hat_exp */ + XY_hat_fx = Mpy_32_16_1( XY_hat_fx, INV_MAX_DELAYREGLEN_FX_Q15 ); /* Q31-XY_hat_exp */ + X_SQR_hat_fx = Mpy_32_16_1( X_SQR_hat_fx, INV_MAX_DELAYREGLEN_FX_Q15 ); /* Q31-X_SQR_hat_exp */ beta_reg_fx = 0; move32(); beta_reg_exp = 0; move16(); - tempF_fx = BASOP_Util_Add_Mant32Exp( X_SQR_hat_fx, X_SQR_hat_exp, L_negate( Mpy_32_32( X_hat_fx, X_hat_fx ) ), shl( X_hat_exp, 1 ), &tempF_exp ); + tempF_fx = BASOP_Util_Add_Mant32Exp( X_SQR_hat_fx, X_SQR_hat_exp, L_negate( Mpy_32_32( X_hat_fx, X_hat_fx ) ), shl( X_hat_exp, 1 ), &tempF_exp ); /* Q31-tempF_exp */ IF( tempF_fx != 0 ) { - temp32 = BASOP_Util_Add_Mant32Exp( XY_hat_fx, XY_hat_exp, L_negate( Mpy_32_32( X_hat_fx, Y_hat_fx ) ), add( X_hat_exp, Y_hat_exp ), &exp ); - beta_reg_fx = BASOP_Util_Divide3232_Scale_cadence( temp32, tempF_fx, &beta_reg_exp ); + temp32 = BASOP_Util_Add_Mant32Exp( XY_hat_fx, XY_hat_exp, L_negate( Mpy_32_32( X_hat_fx, Y_hat_fx ) ), add( X_hat_exp, Y_hat_exp ), &exp ); /* Q31-exp */ + beta_reg_fx = BASOP_Util_Divide3232_Scale_cadence( temp32, tempF_fx, &beta_reg_exp ); /* Q31-beta_reg_exp */ if ( beta_reg_fx ) { beta_reg_exp = add( beta_reg_exp, sub( exp, tempF_exp ) ); } } - alpha_reg_fx = BASOP_Util_Add_Mant32Exp( Y_hat_fx, Y_hat_exp, L_negate( Mpy_32_32( X_hat_fx, beta_reg_fx ) ), add( X_hat_exp, beta_reg_exp ), &alpha_reg_exp ); - reg_prv_corr_fx = BASOP_Util_Add_Mant32Exp( alpha_reg_fx, alpha_reg_exp, Mpy_32_32( beta_reg_fx, L_shl( MAX_DELAYREGLEN, 27 ) ), add( 4, beta_reg_exp ), ®_prv_corr_exp ); + alpha_reg_fx = BASOP_Util_Add_Mant32Exp( Y_hat_fx, Y_hat_exp, L_negate( Mpy_32_32( X_hat_fx, beta_reg_fx ) ), add( X_hat_exp, beta_reg_exp ), &alpha_reg_exp ); /* Q31-alpha_reg_exp */ + reg_prv_corr_fx = BASOP_Util_Add_Mant32Exp( alpha_reg_fx, alpha_reg_exp, Mpy_32_32( beta_reg_fx, L_shl( MAX_DELAYREGLEN, 27 ) ), add( 4, beta_reg_exp ), ®_prv_corr_exp ); /* Q31-reg_prv_corr_exp */ + reg_prv_corr_fx = L_shr( reg_prv_corr_fx, 1 ); + reg_prv_corr_exp = add( reg_prv_corr_exp, 1 ); IF( LE_16( TRUNC_FX( reg_prv_corr_fx, reg_prv_corr_exp ), -L_NCSHIFT_DS ) ) { reg_prv_corr_fx = -L_NCSHIFT_DS + 1; @@ -959,21 +951,21 @@ static void corrStatsEst_fx( move16(); } - bias_par_fx = BASOP_Util_Add_Mant32Exp( Mpy_32_16_1( hStereoTCA->smooth_dist_reg_prv_corr_fx, A_BIAS_FX_Q15 ), hStereoTCA->smooth_dist_reg_prv_corr_exp, L_shl( B_BIAS_FX_Q15, Q16 ), 0, &bias_par_exp ); + bias_par_fx = BASOP_Util_Add_Mant32Exp( Mpy_32_16_1( hStereoTCA->smooth_dist_reg_prv_corr_fx, A_BIAS_FX_Q15 ), hStereoTCA->smooth_dist_reg_prv_corr_exp, L_shl( B_BIAS_FX_Q15, Q16 ), 0, &bias_par_exp ); /* Q31-bias_par_exp */ - Word32 XH_BIAS_tmp = L_shl( XH_BIAS_FX_Q15, Q16 ); - Word32 XL_BIAS_tmp = L_shl( XL_BIAS_FX_Q15, Q16 ); + Word32 XH_BIAS_tmp = L_shl( XH_BIAS_FX_Q15, Q16 ); /* Q31 */ + Word32 XL_BIAS_tmp = L_shl( XL_BIAS_FX_Q15, Q16 ); /* Q31 */ IF( bias_par_exp < 0 ) { - bias_par_fx = L_shl( bias_par_fx, bias_par_exp ); + bias_par_fx = L_shl( bias_par_fx, bias_par_exp ); /* Q31 */ bias_par_exp = 0; move16(); } ELSE { - XH_BIAS_tmp = L_shr( XH_BIAS_tmp, bias_par_exp ); - XL_BIAS_tmp = L_shr( XL_BIAS_tmp, bias_par_exp ); + XH_BIAS_tmp = L_shr( XH_BIAS_tmp, bias_par_exp ); /* Q31-bias_par_exp */ + XL_BIAS_tmp = L_shr( XL_BIAS_tmp, bias_par_exp ); /* Q31-bias_par_exp */ } bias_par_fx = L_min( bias_par_fx, XH_BIAS_tmp ); @@ -982,13 +974,13 @@ static void corrStatsEst_fx( bias_par_exp = 0; move16(); - width_par_fx = BASOP_Util_Add_Mant32Exp( Mpy_32_32( hStereoTCA->smooth_dist_reg_prv_corr_fx, A_WIDTH_FX_Q31 ), hStereoTCA->smooth_dist_reg_prv_corr_exp, B_WIDTH_FX_Q31, 0, &width_par_exp ); - Word32 XH_WIDTH_tmp = L_shl( XH_WIDTH_FX_Q15, Q16 ); - Word32 XL_WIDTH_tmp = L_shl( XL_WIDTH_FX_Q15, Q16 ); + width_par_fx = BASOP_Util_Add_Mant32Exp( Mpy_32_32( hStereoTCA->smooth_dist_reg_prv_corr_fx, A_WIDTH_FX_Q31 ), hStereoTCA->smooth_dist_reg_prv_corr_exp, B_WIDTH_FX_Q31, 0, &width_par_exp ); /* Q31-width_par_exp */ + Word32 XH_WIDTH_tmp = L_shl( XH_WIDTH_FX_Q15, Q16 ); /* Q31 */ + Word32 XL_WIDTH_tmp = L_shl( XL_WIDTH_FX_Q15, Q16 ); /* Q31 */ IF( width_par_exp < 0 ) { - width_par_fx = L_shl( width_par_fx, width_par_exp ); + width_par_fx = L_shl( width_par_fx, width_par_exp ); /* Q31 */ width_par_exp = 0; move16(); } @@ -1003,39 +995,40 @@ static void corrStatsEst_fx( width_par_exp = 0; move16(); - win_width = (Word16) L_shr( Mpy_32_32( width_par_fx, 1350565888 /* ( 4L_NCSHIFT_DS + 1 ) in Q23 */ ), sub( 31, add( width_par_exp, 8 ) ) ); + win_width = (Word16) L_shr( Mpy_32_32( width_par_fx, 1350565888 /* ( 4L_NCSHIFT_DS + 1 ) in Q23 */ ), sub( 31, add( width_par_exp, 8 ) ) ); /* Q23-(31-(width_par_exp-8)) */ win_bias_fx = round_fx( bias_par_fx ); // Q15 k1_fx = add( MAX_16 >> 1, shr( win_bias_fx, 1 ) ); // Q15 k2_fx = sub( MAX_16 >> 1, shr( win_bias_fx, 1 ) ); // Q15 - FOR( i = 0; i < sub( 2 * L_NCSHIFT_DS, shl( win_width, 1 ) ); i++ ) + FOR( i = 0; i < ( 2 * L_NCSHIFT_DS - ( win_width * 2 ) ); i++ ) { loc_weight_win_fx[i] = win_bias_fx; // Q15 move16(); } - FOR( i = sub( 2 * L_NCSHIFT_DS, shl( win_width, 1 ) ); i <= add( 2 * L_NCSHIFT_DS, shl( win_width, 1 ) ); i++ ) + FOR( i = ( 2 * L_NCSHIFT_DS - ( win_width * 2 ) ); i <= ( 2 * L_NCSHIFT_DS + ( win_width * 2 ) ); i++ ) { - Word16 cos_inp = BASOP_Util_Divide1616_Scale( sub( i, 2 * L_NCSHIFT_DS ), shl( win_width, 1 ), &exp ); + Word16 cos_inp = BASOP_Util_Divide1616_Scale( sub( i, 2 * L_NCSHIFT_DS ), shl( win_width, 1 ), &exp ); /* Q15-exp */ cos_inp = shr_sat( cos_inp, sub( 0, exp ) ); - cos_inp = getCosWord16R2( shr( cos_inp, 1 ) ); - loc_weight_win_fx[i] = add( k1_fx, mult( k2_fx, cos_inp ) ); + cos_inp = getCosWord16R2( shr( cos_inp, 1 ) ); // Q15 + loc_weight_win_fx[i] = add( k1_fx, mult( k2_fx, cos_inp ) ); // Q15 move16(); } - FOR( i = add( 2 * L_NCSHIFT_DS, shl( win_width, 1 ) ); i < ( 4 * L_NCSHIFT_DS + 1 ); i++ ) + FOR( i = ( 2 * L_NCSHIFT_DS + ( win_width * 2 ) ); i < ( 4 * L_NCSHIFT_DS + 1 ); i++ ) { loc_weight_win_fx[i] = win_bias_fx; // Q15 move16(); } - - Word16 x = TRUNC_FX( reg_prv_corr_fx, reg_prv_corr_exp ); + reg_prv_corr_fx = L_shr( reg_prv_corr_fx, 1 ); + reg_prv_corr_exp = add( reg_prv_corr_exp, 1 ); + Word16 x = TRUNC_FX( reg_prv_corr_fx, reg_prv_corr_exp ); /* Q0 */ move16(); - for ( i = 0, j = sub( L_NCSHIFT_DS, x ); i < 2 * L_NCSHIFT_DS + 1; i++, j++ ) + for ( i = 0, j = ( L_NCSHIFT_DS - x ); i < 2 * L_NCSHIFT_DS + 1; i++, j++ ) { - corrEst_fx[i] = Mpy_32_16_1( corrEst_fx[i], loc_weight_win_fx[j] ); + corrEst_fx[i] = Mpy_32_16_1( corrEst_fx[i], loc_weight_win_fx[j] ); /* Q31-corrEst_exp */ move32(); } test(); @@ -1043,15 +1036,15 @@ static void corrStatsEst_fx( IF( LT_32( hStereoTCA->prevTargetGain_fx, 429496730 /*0.8f in Q29*/ ) && vad_flag1 ) { /* ch 2 is prev reference channel */ - v_multc_fixed( corrEst_fx, 644245095 /*1.2f in Q29*/, corrEst_fx, L_NCSHIFT_DS + 1 ); - v_multc_fixed( corrEst_fx + L_NCSHIFT_DS + 1, 447213470 /* 0.833 in Q29*/, corrEst_fx + L_NCSHIFT_DS + 1, L_NCSHIFT_DS ); + v_multc_fixed( corrEst_fx, 644245095 /*1.2f in Q29*/, corrEst_fx, L_NCSHIFT_DS + 1 ); /* Q31-corrEst_exp */ + v_multc_fixed( corrEst_fx + L_NCSHIFT_DS + 1, 447213470 /* 0.833 in Q29*/, corrEst_fx + L_NCSHIFT_DS + 1, L_NCSHIFT_DS ); /* Q31-corrEst_exp */ corrEst_exp = add( corrEst_exp, 2 ); } ELSE IF( GT_32( hStereoTCA->prevTargetGain_fx, 644245094 /*1.2f in Q29*/ ) && vad_flag1 ) { /* ch 1 is prev reference channel */ - v_multc_fixed( corrEst_fx, 447213470 /* 0.833 f in Q29*/, corrEst_fx, L_NCSHIFT_DS ); - v_multc_fixed( corrEst_fx + L_NCSHIFT_DS, 644245095 /*1.2f in Q29*/, corrEst_fx + L_NCSHIFT_DS, L_NCSHIFT_DS + 1 ); + v_multc_fixed( corrEst_fx, 447213470 /* 0.833 f in Q29*/, corrEst_fx, L_NCSHIFT_DS ); /* Q31-corrEst_exp */ + v_multc_fixed( corrEst_fx + L_NCSHIFT_DS, 644245095 /*1.2f in Q29*/, corrEst_fx + L_NCSHIFT_DS, L_NCSHIFT_DS + 1 ); /* Q31-corrEst_exp */ corrEst_exp = add( corrEst_exp, 2 ); } test(); @@ -1061,9 +1054,9 @@ static void corrStatsEst_fx( j = s_min( 2 * L_NCSHIFT_DS, add( hStereoTCA->prevCorrLagStats[0], 1 + L_NCSHIFT_DS ) ); k = add( sub( j, i ), 1 ); - v_multc_fixed( corrEst_fx, ONE_IN_Q29 /*1.0f in Q29*/, corrEst_fx, i ); // to allign in same exp - v_multc_fixed( corrEst_fx + i, 644245095 /*1.2f in Q29*/, corrEst_fx + i, k ); - v_multc_fixed( corrEst_fx + i + k, ONE_IN_Q29 /*1.0f in Q29*/, corrEst_fx + i + k, sub( 2 * L_NCSHIFT_DS + 1, i + k ) ); // to allign in same exp + v_multc_fixed( corrEst_fx, ONE_IN_Q29 /*1.0f in Q29*/, corrEst_fx, i ); // to allign in same exp (Q31-corrEst_exp) + v_multc_fixed( corrEst_fx + i, 644245095 /*1.2f in Q29*/, corrEst_fx + i, k ); /* Q31-corrEst_exp */ + v_multc_fixed( corrEst_fx + i + k, ONE_IN_Q29 /*1.0f in Q29*/, corrEst_fx + i + k, sub( 2 * L_NCSHIFT_DS + 1, i + k ) ); // to allign in same exp (Q31-corrEst_exp) corrEst_exp = add( corrEst_exp, 2 ); } @@ -1075,35 +1068,39 @@ static void corrStatsEst_fx( corrLagStats[0] = add( corrLagStats[0], lagSearchRange[0] ); move16(); - stmp = i_mult( corrLagStats[0], dsFactor ); - hStereoClassif->unclr_fv_fx[E_corrLagStats0] = L_shl( stmp, Q15 ); + stmp = i_mult( corrLagStats[0], dsFactor ); /* Q0 */ + hStereoClassif->unclr_fv_fx[E_corrLagStats0] = L_shl( stmp, Q15 ); /* Q15 */ move32(); - hStereoClassif->xtalk_fv_fx[E_corrLagStats0] = L_shl( stmp, Q15 ); + hStereoClassif->xtalk_fv_fx[E_corrLagStats0] = L_shl( stmp, Q15 ); /* Q15 */ move32(); - hStereoClassif->xtalk_fv_fx[E_ica_corr_value0] = L_shl( tempF_fx, sub( tempF_exp, Q16 ) ); + hStereoClassif->xtalk_fv_fx[E_ica_corr_value0] = L_shl( tempF_fx, sub( tempF_exp, Q16 ) ); /* Q15 */ move32(); test(); - if ( vad_flag1 == 0 && GT_16( alpha_fx, 22938 /* 0.7f in Q15 */ ) ) + IF( vad_flag1 == 0 && GT_16( alpha_fx, 22938 /* 0.7f in Q15 */ ) ) { corrLagStats[0] = 0; move16(); } - dist_reg_prv_corr_fx = L_abs( BASOP_Util_Add_Mant32Exp( reg_prv_corr_fx, reg_prv_corr_exp, -corrLagStats[0], Q31, &dist_reg_prv_corr_exp ) ); + dist_reg_prv_corr_fx = L_abs( BASOP_Util_Add_Mant32Exp( reg_prv_corr_fx, reg_prv_corr_exp, -corrLagStats[0], Q31, &dist_reg_prv_corr_exp ) ); /* Q31-dist_reg_prv_corr_exp */ test(); IF( EQ_16( vad_flag1, 1 ) && EQ_16( vad_flag2, 1 ) ) { - hStereoTCA->smooth_dist_reg_prv_corr_fx = BASOP_Util_Add_Mant32Exp( Mpy_32_16_1( hStereoTCA->smooth_dist_reg_prv_corr_fx, SMOOTH_DIST_FACTOR_FX_Q15 ), hStereoTCA->smooth_dist_reg_prv_corr_exp, Mpy_32_16_1( dist_reg_prv_corr_fx, MAX_16 - SMOOTH_DIST_FACTOR_FX_Q15 ), dist_reg_prv_corr_exp, &hStereoTCA->smooth_dist_reg_prv_corr_exp ); + hStereoTCA->smooth_dist_reg_prv_corr_fx = BASOP_Util_Add_Mant32Exp( Mpy_32_16_1( hStereoTCA->smooth_dist_reg_prv_corr_fx, SMOOTH_DIST_FACTOR_FX_Q15 ), hStereoTCA->smooth_dist_reg_prv_corr_exp, Mpy_32_16_1( dist_reg_prv_corr_fx, MAX_16 - SMOOTH_DIST_FACTOR_FX_Q15 ), dist_reg_prv_corr_exp, &hStereoTCA->smooth_dist_reg_prv_corr_exp ); /* Q31-hStereoTCA->smooth_dist_reg_prv_corr_exp */ move32(); - Copy32( &( hStereoTCA->delay_0_mem_fx[1] ), &( hStereoTCA->delay_0_mem_fx[0] ), MAX_DELAYREGLEN - 1 ); + Copy32( &( hStereoTCA->delay_0_mem_fx[1] ), &( hStereoTCA->delay_0_mem_fx[0] ), MAX_DELAYREGLEN - 1 ); /* Q31-hStereoTCA->delay_0_mem_exp */ - hStereoTCA->delay_0_mem_fx[MAX_DELAYREGLEN - 1] = BASOP_Util_Add_Mant32Exp( Mpy_32_32( hStereoTCA->delay_0_mem_fx[MAX_DELAYREGLEN - 1], 429496730 /* 0.2 in Q31*/ ), hStereoTCA->delay_0_mem_exp, L_mult0( 26214 /* 0.8 in Q15*/, corrLagStats[0] ), Q16, &temp ); + hStereoTCA->delay_0_mem_fx[MAX_DELAYREGLEN - 1] = BASOP_Util_Add_Mant32Exp( Mpy_32_32( hStereoTCA->delay_0_mem_fx[MAX_DELAYREGLEN - 1], 429496730 /* 0.2 in Q31*/ ), hStereoTCA->delay_0_mem_exp, L_mult0( 26214 /* 0.8 in Q15*/, corrLagStats[0] ), Q16, &temp ); /* Q31-temp */ move32(); - Word32 inpp = L_abs( BASOP_Util_Add_Mant32Exp( reg_prv_corr_fx, reg_prv_corr_exp, -hStereoTCA->delay_0_mem_fx[0], hStereoTCA->delay_0_mem_exp, &exp ) ); - inpp = L_shr( inpp, sub( Q31, exp ) ); - IF( GT_32( inpp, 25 ) ) +#ifdef FIX_USAN_ISSUES + Word32 inpp = L_abs( BASOP_Util_Add_Mant32Exp( reg_prv_corr_fx, reg_prv_corr_exp, L_negate( hStereoTCA->delay_0_mem_fx[0] ), hStereoTCA->delay_0_mem_exp, &exp ) ); /* Q31-exp */ +#else + Word32 inpp = L_abs( BASOP_Util_Add_Mant32Exp( reg_prv_corr_fx, reg_prv_corr_exp, -hStereoTCA->delay_0_mem_fx[0], hStereoTCA->delay_0_mem_exp, &exp ) ); /* Q31-exp */ +#endif + inpp = L_shl_sat( inpp, sub( exp, 5 ) ); /* Q26 */ + IF( GT_32( inpp, 1677721600 ) ) // 25 in Q26 { set32_fx( &( hStereoTCA->delay_0_mem_fx[0] ), hStereoTCA->delay_0_mem_fx[MAX_DELAYREGLEN - 1], MAX_DELAYREGLEN - 1 ); hStereoTCA->delay_0_mem_exp = temp; @@ -1113,13 +1110,13 @@ static void corrStatsEst_fx( { IF( GT_16( temp, hStereoTCA->delay_0_mem_exp ) ) { - scale_sig32( hStereoTCA->delay_0_mem_fx, MAX_DELAYREGLEN - 1, sub( hStereoTCA->delay_0_mem_exp, temp ) ); + scale_sig32( hStereoTCA->delay_0_mem_fx, MAX_DELAYREGLEN - 1, sub( hStereoTCA->delay_0_mem_exp, temp ) ); /* Q31-hStereoTCA->delay_0_mem_exp */ hStereoTCA->delay_0_mem_exp = temp; move16(); } ELSE { - hStereoTCA->delay_0_mem_fx[MAX_DELAYREGLEN - 1] = L_shl( hStereoTCA->delay_0_mem_fx[MAX_DELAYREGLEN - 1], sub( temp, hStereoTCA->delay_0_mem_exp ) ); + hStereoTCA->delay_0_mem_fx[MAX_DELAYREGLEN - 1] = L_shl( hStereoTCA->delay_0_mem_fx[MAX_DELAYREGLEN - 1], sub( temp, hStereoTCA->delay_0_mem_exp ) ); /* Q31-temp */ move32(); } } @@ -1134,7 +1131,9 @@ static void corrStatsEst_fx( test(); IF( vad_flag1 == 0 || vad_flag2 == 0 ) { - corrLagStats[0] = TRUNC_FX( hStereoTCA->delay_0_mem_fx[MAX_DELAYREGLEN - 1], hStereoTCA->delay_0_mem_exp ); + Word32 tmp_delay = L_shr( hStereoTCA->delay_0_mem_fx[MAX_DELAYREGLEN - 1], 1 ); + Word16 tmp_delay_e = add( hStereoTCA->delay_0_mem_exp, 1 ); + corrLagStats[0] = TRUNC_FX( tmp_delay, tmp_delay_e ); /* Q0 */ move32(); } @@ -1155,7 +1154,7 @@ static void corrStatsEst_fx( winInterp_fx = ica_sincInterp6_fx + SINC_ORDER1; } - corrLagStats[1] = i_mult( corrLagStats[0], dsFactor ); + corrLagStats[1] = i_mult( corrLagStats[0], dsFactor ); /* Q0 */ move16(); interpMin = s_max( -sub( dsFactor, 1 ), -add( corrLagStats[1], i_mult( L_NCSHIFT_DS, dsFactor ) ) ); interpMax = s_min( sub( dsFactor, 1 ), sub( i_mult( L_NCSHIFT_DS, dsFactor ), corrLagStats[1] ) ); @@ -1165,29 +1164,29 @@ static void corrStatsEst_fx( { rInterp_fx[k] = 0; move32(); - FOR( j = -idiv1616( SINC_ORDER1, dsFactor ); j <= idiv1616( SINC_ORDER1, dsFactor ); j++ ) + FOR( j = -( SINC_ORDER1 / dsFactor ); j <= ( SINC_ORDER1 / dsFactor ); j++ ) { - m = i_mult( j, dsFactor ); + m = i_mult( j, dsFactor ); /* Q0 */ test(); IF( GE_16( sub( m, i ), -SINC_ORDER1 ) && LE_16( sub( m, i ), SINC_ORDER1 ) ) { IF( GT_16( j, sub( lagSearchRange[1], corrLagStats[0] ) ) ) { - rInterp_fx[k] = BASOP_Util_Add_Mant32Exp( rInterp_fx[k], rInterp_exp[k], Mpy_32_32( tempRK_fx[lagSearchRange[1] - corrLagStats[0]], winInterp_fx[m - i] ), hStereoTCA->corrEstLT_exp, &temp ); + rInterp_fx[k] = BASOP_Util_Add_Mant32Exp( rInterp_fx[k], rInterp_exp[k], Mpy_32_32( tempRK_fx[lagSearchRange[1] - corrLagStats[0]], winInterp_fx[m - i] ), hStereoTCA->corrEstLT_exp, &temp ); /* Q31-temp */ move32(); rInterp_exp[k] = temp; move16(); } ELSE IF( LT_16( j, sub( lagSearchRange[0], corrLagStats[0] ) ) ) { - rInterp_fx[k] = BASOP_Util_Add_Mant32Exp( rInterp_fx[k], rInterp_exp[k], Mpy_32_32( tempRK_fx[lagSearchRange[0] - corrLagStats[0]], winInterp_fx[m - i] ), hStereoTCA->corrEstLT_exp, &temp ); + rInterp_fx[k] = BASOP_Util_Add_Mant32Exp( rInterp_fx[k], rInterp_exp[k], Mpy_32_32( tempRK_fx[lagSearchRange[0] - corrLagStats[0]], winInterp_fx[m - i] ), hStereoTCA->corrEstLT_exp, &temp ); /* Q31-temp */ move32(); rInterp_exp[k] = temp; move16(); } ELSE { - rInterp_fx[k] = BASOP_Util_Add_Mant32Exp( rInterp_fx[k], rInterp_exp[k], Mpy_32_32( tempRK_fx[j], winInterp_fx[m - i] ), hStereoTCA->corrEstLT_exp, &temp ); + rInterp_fx[k] = BASOP_Util_Add_Mant32Exp( rInterp_fx[k], rInterp_exp[k], Mpy_32_32( tempRK_fx[j], winInterp_fx[m - i] ), hStereoTCA->corrEstLT_exp, &temp ); /* Q31-temp */ move32(); rInterp_exp[k] = temp; move16(); @@ -1204,15 +1203,15 @@ static void corrStatsEst_fx( FOR( i = 0; i < MAX_INTERPOLATE; i++ ) { - rInterp_fx[i] = L_shl( rInterp_fx[i], sub( rInterp_exp[i], temp ) ); + rInterp_fx[i] = L_shl( rInterp_fx[i], sub( rInterp_exp[i], temp ) ); /* Q31-rInterp_exp[i] */ move32(); } - corrLagStats[1] = add( corrLagStats[1], add( maximum_32_fx( rInterp_fx, interpLen, &tempF_fx ), interpMin ) ); + corrLagStats[1] = add( corrLagStats[1], add( maximum_32_fx( rInterp_fx, interpLen, &tempF_fx ), interpMin ) ); /* Q0 */ move16(); /* save corr lag stats for the current frame */ - Copy( corrLagStats, hStereoTCA->corrLagStats, 3 ); + Copy( corrLagStats, hStereoTCA->corrLagStats, 3 ); /* Q0 */ return; } @@ -1225,14 +1224,14 @@ static void corrStatsEst_fx( static void estDownmixGain_fx( STEREO_TCA_ENC_HANDLE hStereoTCA, /* i/o: Stereo TCA Encoder handle */ - const Word32 *chan1, /* i : reference signal Qx */ - const Word32 *chan2, /* i/o: target signal to be scaled Qx */ - const Word16 q_chan, /* i : Q of the channel signal */ - const Word16 ncShift, /* i : shift */ - const Word16 length, /* i : input frame length */ - const Word16 element_mode, /* i : element mode */ + const Word32 *chan1, /* i : reference signal q_chan */ + const Word32 *chan2, /* i/o: target signal to be scaled q_chan */ + const Word16 q_chan, /* i : Q of the channel signal Q0*/ + const Word16 ncShift, /* i : shift Q0*/ + const Word16 length, /* i : input frame length Q0*/ + const Word16 element_mode, /* i : element mode Q0*/ STEREO_CLASSIF_HANDLE hStereoClassif, /* i/o: stereo classifier handle */ - const Word16 tdm_LRTD_flag /* i : LRTD stereo mode flag */ + const Word16 tdm_LRTD_flag /* i : LRTD stereo mode flag Q0*/ ) { Word16 i, i1, i2; @@ -1251,12 +1250,12 @@ static void estDownmixGain_fx( { i1 = 0; move16(); - i2 = ncShift; + i2 = ncShift; /* Q0 */ move16(); } ELSE { - i1 = ncShift; + i1 = ncShift; /* Q0 */ move16(); i2 = 0; move16(); @@ -1269,11 +1268,11 @@ static void estDownmixGain_fx( move32(); FOR( i = 0; i < length; i++ ) { - tempN = L_add( tempN, L_abs( chan1[i1 + i] ) ); - tempD = L_add( tempD, L_abs( chan2[i2 + i] ) ); + tempN = L_add( tempN, L_abs( chan1[i1 + i] ) ); /* q_chan */ + tempD = L_add( tempD, L_abs( chan2[i2 + i] ) ); /* q_chan */ } - alpha = hStereoTCA->corrStatsSmoothFac_fx; + alpha = hStereoTCA->corrStatsSmoothFac_fx; /* Q15 */ move16(); IF( tempD == 0 ) { @@ -1283,7 +1282,7 @@ static void estDownmixGain_fx( } ELSE { - currentGain = BASOP_Util_Divide3232_Scale( tempN, tempD, &exp ); + currentGain = BASOP_Util_Divide3232_Scale( tempN, tempD, &exp ); /* Q31-exp */ currentGain_e = exp; move16(); if ( currentGain == 0 ) @@ -1306,7 +1305,7 @@ static void estDownmixGain_fx( currentGain_log10 = BASOP_Util_Log10( L_deposit_h( currentGain ), currentGain_e ); // Output in Q25 // multiplication result will be Q25 should be fit to Q15 hence right shift by 10. // Q25 - Q10 = Q15 - currentGain = extract_l( L_shr( Madd_32_16( Mpy_32_16_1( prevTargetGain_log10, alpha ), currentGain_log10, sub( MAX_16, alpha ) ), Q10 ) ); + currentGain = extract_l( L_shr( Madd_32_16( Mpy_32_16_1( prevTargetGain_log10, alpha ), currentGain_log10, sub( MAX_16, alpha ) ), Q10 ) ); /* Q15 */ currentGain_e = 0; move16(); @@ -1318,8 +1317,8 @@ static void estDownmixGain_fx( // tempD = powf( 10, currentGain ); // 10 ^ currentGain = 2 ^ (3.32192809488 * currentGain) // 3.32192809488 in Q13 27213 - tempD = BASOP_util_Pow2( L_mult( currentGain, 27213 ), add( currentGain_e, Q2 ), &exp ); - unclr_instTargetGain = L_deposit_h( BASOP_Util_Divide3232_Scale( tempN, L_add( tempD, EPSILON_FX ), &exp_div ) ); + tempD = BASOP_util_Pow2( L_mult( currentGain, 27213 ), add( currentGain_e, Q2 ), &exp ); /* Q31-exp */ + unclr_instTargetGain = L_deposit_h( BASOP_Util_Divide3232_Scale( tempN, L_add( tempD, EPSILON_FX ), &exp_div ) ); /* Q31-exp */ exp = add( sub( exp_chan, exp ), exp_div ); if ( unclr_instTargetGain == 0 ) { @@ -1328,7 +1327,7 @@ static void estDownmixGain_fx( } unclr_instTargetGain = BASOP_Util_Log10( L_add( unclr_instTargetGain, L_shr( MAX_32, sub( Q31, exp ) ) ), exp ); // unclr_fv_fx is expected in Q15 - log result will be in Q25 - hence rightshift by 10. - hStereoClassif->unclr_fv_fx[E_ica_instTargetGain] = L_shr( unclr_instTargetGain, Q10 ); + hStereoClassif->unclr_fv_fx[E_ica_instTargetGain] = L_shr( unclr_instTargetGain, Q10 ); /* Q15 */ move32(); } @@ -1340,21 +1339,14 @@ static void estDownmixGain_fx( } ELSE IF( GT_16( hStereoTCA->LRTD_G_ATT_cnt, 1 ) ) /* lrtd_mode == 1 but tdm_LRTD_flag still 0 */ { - currentGain = BASOP_Util_Divide1616_Scale( currentGain, hStereoTCA->LRTD_G_ATT_cnt, ¤tGain_e ); // Q = 15 + 0 - (15 - exp) - /* Division result Q has to be got back to the Q of initial currentGain hence the shift operation below */ - IF( currentGain_e != 0 ) - { - currentGain = shr( currentGain, sub( Q15, currentGain_e ) ); - currentGain_e = 0; - move16(); - } + currentGain = BASOP_Util_Divide1616_Scale( currentGain, hStereoTCA->LRTD_G_ATT_cnt, &exp ); + currentGain_e = add( exp, sub( currentGain_e, 15 ) ); } - IF( GE_16( norm_s( currentGain ), sub( currentGain_e, 1 ) ) ) { /* convert currentGain into Q14 */ - currentGain = shl( currentGain, sub( currentGain_e, 1 ) ); + currentGain = shl( currentGain, sub( currentGain_e, 1 ) ); /* Q14 */ currentGain_e = 1; move16(); } @@ -1365,7 +1357,7 @@ static void estDownmixGain_fx( } /* quantize the target gain */ - hStereoTCA->indx_ica_gD = usquant_fx( currentGain, &temp, shr( STEREO_TCA_GDMIN_FX_Q14, shift ), shr( STEREO_TCA_GDSTEP_FX_Q13, shift ), 1 << STEREO_BITS_TCA_GD ); + hStereoTCA->indx_ica_gD = usquant_fx( currentGain, &temp, shr( STEREO_TCA_GDMIN_FX_Q14, shift ), shr( STEREO_TCA_GDSTEP_FX_Q13, shift ), ( 1 << STEREO_BITS_TCA_GD ) ); /* Q13 */ move16(); // hStereoTCA->targetGain_fx = powf( 10, temp ); // 10 ^ temp = 2 ^ (3.32192809488 * temp) @@ -1373,7 +1365,7 @@ static void estDownmixGain_fx( // exponent of power function input will be 2 more since constant is in Q13 exp = 2; move16(); - hStereoTCA->targetGain_fx = BASOP_util_Pow2( L_mult( temp, 27213 ), add( currentGain_e, 2 ), &exp ); + hStereoTCA->targetGain_fx = BASOP_util_Pow2( L_mult( temp, 27213 ), add( currentGain_e, 2 ), &exp ); /* Q31-exp */ move32(); hStereoTCA->targetGain_fx = L_shl( hStereoTCA->targetGain_fx, sub( exp, 2 ) ); // Q29 move32(); @@ -1391,9 +1383,9 @@ static void icaMemUpdate_fx( Word32 *bufChanL, /* i/o: L signal correction from previous frame q_com*/ Word32 *bufChanR, /* i/o: R signal correction from previous frame q_com*/ Word16 q_com, - const Word16 lMemRecalc, /* i : memory length at input Sampling Rate */ - const Word16 lMemRecalc_SCh, /* i : SCh memory length at input Sampling Rate*/ - const Word16 input_frame /* i : frame length */ + const Word16 lMemRecalc, /* i : memory length at input Sampling Rate Q0*/ + const Word16 lMemRecalc_SCh, /* i : SCh memory length at input Sampling Rate Q0*/ + const Word16 input_frame /* i : frame length Q0*/ ) { Word32 *ptr1, *ptr2; @@ -1409,29 +1401,29 @@ static void icaMemUpdate_fx( IF( hCPE->hStereoTD->tdm_last_SM_flag ) { - ratio_L = hCPE->hStereoTD->tdm_last_ratio_SM_fx; + ratio_L = hCPE->hStereoTD->tdm_last_ratio_SM_fx; /* Q31 */ move32(); One_m_Ratio = L_sub( ratio_L, MAX_32 ); } ELSE { - ratio_L = hCPE->hStereoTD->tdm_last_ratio_fx; + ratio_L = hCPE->hStereoTD->tdm_last_ratio_fx; /* Q31 */ move32(); One_m_Ratio = L_sub( MAX_32, ratio_L ); } - ptr1 = sts[0]->input32_fx - add( lMemRecalc, lMemRecalc_SCh ); - ptr2 = sts[1]->input32_fx - add( lMemRecalc, lMemRecalc_SCh ); + ptr1 = sts[0]->input32_fx - add( lMemRecalc, lMemRecalc_SCh ); /* Q31-sts[0]->q_inp32 */ + ptr2 = sts[1]->input32_fx - add( lMemRecalc, lMemRecalc_SCh ); /* Q31-sts[1]->q_inp32 */ IF( EQ_16( hCPE->last_element_mode, IVAS_CPE_TD ) ) { IF( hCPE->hStereoTD->flag_skip_DMX ) { - FOR( i = lMemRecalc_SCh; i < add( lMemRecalc, lMemRecalc_SCh ); i++ ) + FOR( i = lMemRecalc_SCh; i < ( lMemRecalc + lMemRecalc_SCh ); i++ ) { - ptr1[i] = bufChanL[i]; + ptr1[i] = bufChanL[i]; /* q_com */ move32(); - ptr2[i] = bufChanR[i]; + ptr2[i] = bufChanR[i]; /* q_com */ move32(); } } @@ -1439,9 +1431,9 @@ static void icaMemUpdate_fx( { FOR( i = lMemRecalc_SCh; i < lMemRecalc + lMemRecalc_SCh; i++ ) { - ptr1[i] = L_add( Mpy_32_32( bufChanR[i], One_m_Ratio ), Mpy_32_32( bufChanL[i], ratio_L ) ); + ptr1[i] = L_add( Mpy_32_32( bufChanR[i], One_m_Ratio ), Mpy_32_32( bufChanL[i], ratio_L ) ); /* q_com */ move32(); - ptr2[i] = L_sub( Mpy_32_32( bufChanL[i], One_m_Ratio ), Mpy_32_32( bufChanR[i], ratio_L ) ); + ptr2[i] = L_sub( Mpy_32_32( bufChanL[i], One_m_Ratio ), Mpy_32_32( bufChanR[i], ratio_L ) ); /* q_com */ move32(); } } @@ -1459,7 +1451,7 @@ static void icaMemUpdate_fx( /* reconstruction of the Secondary channel past segment */ FOR( i = 0; i < lMemRecalc_SCh; i++ ) { - ptr2[i] = L_add( Mpy_32_32( bufChanL[i], One_m_Ratio ), Mpy_32_32( bufChanR[i], ratio_L ) ); + ptr2[i] = L_add( Mpy_32_32( bufChanL[i], One_m_Ratio ), Mpy_32_32( bufChanR[i], ratio_L ) ); /* q_com */ move32(); } @@ -1468,18 +1460,18 @@ static void icaMemUpdate_fx( incr = fac; // Q15 move16(); - FOR( i = lMemRecalc_SCh; i < add( lMemRecalc, lMemRecalc_SCh ); i++ ) + FOR( i = lMemRecalc_SCh; i < ( lMemRecalc + lMemRecalc_SCh ); i++ ) { - tmp1 = bufChanL[i]; + tmp1 = bufChanL[i]; /* q_com */ move32(); - tmp2 = bufChanR[i]; + tmp2 = bufChanR[i]; /* q_com */ move32(); - ptr1[i] = L_add( Mpy_32_16_1( ptr1[i], sub( MAX_16, fac ) ), Mpy_32_16_1( tmp1, fac ) ); + ptr1[i] = L_add( Mpy_32_16_1( ptr1[i], sub( MAX_16, fac ) ), Mpy_32_16_1( tmp1, fac ) ); /* q_com */ move32(); /*ptr2[i] = (1.0f - fac) * ptr2[i] + fac * tmp2;*/ /* the secondary channel (downmixed) buffer of DFT stereo is empty ! */ - ptr2[i] = tmp2; + ptr2[i] = tmp2; /* q_com */ move32(); fac = add_sat( fac, incr ); @@ -1490,7 +1482,7 @@ static void icaMemUpdate_fx( /* reconstruction of the Secondary channel past segment */ FOR( i = 0; i < lMemRecalc_SCh; i++ ) { - ptr2[i] = L_sub( Mpy_32_32( bufChanL[i], One_m_Ratio ), Mpy_32_32( bufChanR[i], ratio_L ) ); + ptr2[i] = L_sub( Mpy_32_32( bufChanL[i], One_m_Ratio ), Mpy_32_32( bufChanR[i], ratio_L ) ); /* q_com */ move32(); } @@ -1498,15 +1490,15 @@ static void icaMemUpdate_fx( fac = div_s( 1, lMemRecalc ); // Q15 incr = fac; // Q15 move16(); - FOR( i = lMemRecalc_SCh; i < add( lMemRecalc, lMemRecalc_SCh ); i++ ) + FOR( i = lMemRecalc_SCh; i < ( lMemRecalc + lMemRecalc_SCh ); i++ ) { - tmp1 = L_add( Mpy_32_32( bufChanR[i], One_m_Ratio ), Mpy_32_32( bufChanL[i], ratio_L ) ); - tmp2 = L_sub( Mpy_32_32( bufChanL[i], One_m_Ratio ), Mpy_32_32( bufChanR[i], ratio_L ) ); + tmp1 = L_add( Mpy_32_32( bufChanR[i], One_m_Ratio ), Mpy_32_32( bufChanL[i], ratio_L ) ); /* q_com */ + tmp2 = L_sub( Mpy_32_32( bufChanL[i], One_m_Ratio ), Mpy_32_32( bufChanR[i], ratio_L ) ); /* q_com */ - ptr1[i] = L_add( Mpy_32_16_1( ptr1[i], sub( MAX_16, fac ) ), Mpy_32_16_1( tmp1, fac ) ); + ptr1[i] = L_add( Mpy_32_16_1( ptr1[i], sub( MAX_16, fac ) ), Mpy_32_16_1( tmp1, fac ) ); /* q_com */ move32(); /*ptr2[i] = (1.0f - fac) * ptr2[i] + fac * tmp2;*/ /* the secondary channel (downmixed) buffer of DFT stereo is empty ! */ - ptr2[i] = tmp2; + ptr2[i] = tmp2; /* q_com */ move32(); fac = add_sat( fac, incr ); @@ -1518,9 +1510,9 @@ static void icaMemUpdate_fx( IF( hCPE->hStereoICBWE != NULL ) { assert( L_MEM_RECALC_TBE_NS <= L_MEM_RECALC_NS ); - i = NS2SA( sts[0]->input_Fs, L_MEM_RECALC_TBE_NS ); - Copy_Scale_sig_32_16( bufChanL + sub( add( lMemRecalc, lMemRecalc_SCh ), i ), hCPE->hStereoICBWE->icbwe_inp_mem_fx[0], i, -Q16 ); - Copy_Scale_sig_32_16( bufChanR + sub( add( lMemRecalc, lMemRecalc_SCh ), i ), hCPE->hStereoICBWE->icbwe_inp_mem_fx[1], i, -Q16 ); + i = NS2SA_FX2( sts[0]->input_Fs, L_MEM_RECALC_TBE_NS ); + Copy_Scale_sig_32_16( bufChanL + sub( add( lMemRecalc, lMemRecalc_SCh ), i ), hCPE->hStereoICBWE->icbwe_inp_mem_fx[0], i, -Q16 ); /* q_com-16 */ + Copy_Scale_sig_32_16( bufChanR + sub( add( lMemRecalc, lMemRecalc_SCh ), i ), hCPE->hStereoICBWE->icbwe_inp_mem_fx[1], i, -Q16 ); /* q_com-16 */ hCPE->hStereoICBWE->q_dataChan_fx = sub( q_com, Q16 ); move16(); } @@ -1535,7 +1527,7 @@ static void icaMemUpdate_fx( * ---------------------------------------------------------------*/ void stereo_tca_enc_fx( CPE_ENC_HANDLE hCPE, /* i : CPE encoder structure */ - const Word16 input_frame /* i : length of a frame per channel */ + const Word16 input_frame /* i : length of a frame per channel Q0*/ ) { /* temp variables */ @@ -1586,9 +1578,9 @@ void stereo_tca_enc_fx( q_com = sts[0]->q_inp32; move16(); - lMemRecalc = NS2SA( input_Fs, L_MEM_RECALC_NS ); + lMemRecalc = NS2SA_FX2( input_Fs, L_MEM_RECALC_NS ); move16(); - lMemRecalc_SCh = NS2SA( input_Fs, L_MEM_RECALC_SCH_NS ); + lMemRecalc_SCh = NS2SA_FX2( input_Fs, L_MEM_RECALC_SCH_NS ); move16(); IF( EQ_16( hCPE->element_mode, IVAS_CPE_MDCT ) ) @@ -1599,12 +1591,12 @@ void stereo_tca_enc_fx( /* populate L/R memories into current buffers */ Word16 tempp_scale = L_norm_arr( hStereoTCA->memChanL_fx, L_MEM_RECALC_48K + L_MEM_RECALC_48k_SCH ); tempp_scale = s_min( tempp_scale, L_norm_arr( hStereoTCA->memChanR_fx, L_MEM_RECALC_48K + L_MEM_RECALC_48k_SCH ) ); - scale_sig32( hStereoTCA->memChanL_fx, L_MEM_RECALC_48K + L_MEM_RECALC_48k_SCH, tempp_scale ); - scale_sig32( hStereoTCA->memChanR_fx, L_MEM_RECALC_48K + L_MEM_RECALC_48k_SCH, tempp_scale ); + scale_sig32( hStereoTCA->memChanL_fx, L_MEM_RECALC_48K + L_MEM_RECALC_48k_SCH, tempp_scale ); /* hStereoTCA->memChan_q + tempp_scale */ + scale_sig32( hStereoTCA->memChanR_fx, L_MEM_RECALC_48K + L_MEM_RECALC_48k_SCH, tempp_scale ); /* hStereoTCA->memChan_q + tempp_scale */ hStereoTCA->memChan_q = add( hStereoTCA->memChan_q, tempp_scale ); move16(); - Copy32( hStereoTCA->memChanL_fx, bufChanL_fx, add( lMemRecalc, lMemRecalc_SCh ) ); - Copy32( hStereoTCA->memChanR_fx, bufChanR_fx, add( lMemRecalc, lMemRecalc_SCh ) ); + Copy32( hStereoTCA->memChanL_fx, bufChanL_fx, add( lMemRecalc, lMemRecalc_SCh ) ); /* hStereoTCA->memChan_q */ + Copy32( hStereoTCA->memChanR_fx, bufChanR_fx, add( lMemRecalc, lMemRecalc_SCh ) ); /* hStereoTCA->memChan_q */ bufChan_q = hStereoTCA->memChan_q; move16(); /* pointers to the current frame */ @@ -1612,14 +1604,14 @@ void stereo_tca_enc_fx( ptrChanR_fx = bufChanR_fx + add( lMemRecalc, lMemRecalc_SCh ); // Q:bufChan_q /* copy interleaved stereo data to two channels, e.g., L, R */ - Copy32( sts[0]->input32_fx, ptrChanL_fx, input_frame ); - Copy32( sts[1]->input32_fx, ptrChanR_fx, input_frame ); + Copy32( sts[0]->input32_fx, ptrChanL_fx, input_frame ); /* sts[0]->q_inp32 */ + Copy32( sts[1]->input32_fx, ptrChanR_fx, input_frame ); /* sts[1]->q_inp32 */ /* Scaling buffers to common Q*/ - scale_sig32( ptrChanL_fx, input_frame, sub( s_min( q_com, bufChan_q ), q_com ) ); - scale_sig32( ptrChanR_fx, input_frame, sub( s_min( q_com, bufChan_q ), q_com ) ); - scale_sig32( bufChanL_fx, add( lMemRecalc, lMemRecalc_SCh ), sub( s_min( q_com, bufChan_q ), bufChan_q ) ); - scale_sig32( bufChanR_fx, add( lMemRecalc, lMemRecalc_SCh ), sub( s_min( q_com, bufChan_q ), bufChan_q ) ); + scale_sig32( ptrChanL_fx, input_frame, sub( s_min( q_com, bufChan_q ), q_com ) ); /* s_min( q_com, bufChan_q ) */ + scale_sig32( ptrChanR_fx, input_frame, sub( s_min( q_com, bufChan_q ), q_com ) ); /* s_min( q_com, bufChan_q ) */ + scale_sig32( bufChanL_fx, add( lMemRecalc, lMemRecalc_SCh ), sub( s_min( q_com, bufChan_q ), bufChan_q ) ); /* s_min( q_com, bufChan_q ) */ + scale_sig32( bufChanR_fx, add( lMemRecalc, lMemRecalc_SCh ), sub( s_min( q_com, bufChan_q ), bufChan_q ) ); /* s_min( q_com, bufChan_q ) */ bufChan_q = s_min( q_com, bufChan_q ); q_com = bufChan_q; move16(); @@ -1673,7 +1665,7 @@ void stereo_tca_enc_fx( tempS = hStereoTCA->prevRefChanIndx; move16(); - Copy( hStereoTCA->prevCorrLagStats, tempS_buff, 3 ); + Copy( hStereoTCA->prevCorrLagStats, tempS_buff, 3 ); /* Q0 */ stereo_tca_init_enc_fx( hStereoTCA, input_Fs ); @@ -1695,13 +1687,13 @@ void stereo_tca_enc_fx( hStereoTCA->prevRefChanIndx = tempS; move16(); - Copy( tempS_buff, hStereoTCA->prevCorrLagStats, 3 ); + Copy( tempS_buff, hStereoTCA->prevCorrLagStats, 3 ); /* Q0 */ /* populate memory */ IF( EQ_16( hCPE->last_element_mode, IVAS_CPE_MDCT ) ) { - Copy32( sts[0]->input32_fx - add( lMemRecalc, lMemRecalc_SCh ), bufChanL_fx, add( lMemRecalc, lMemRecalc_SCh ) ); - Copy32( sts[1]->input32_fx - add( lMemRecalc, lMemRecalc_SCh ), bufChanR_fx, add( lMemRecalc, lMemRecalc_SCh ) ); + Copy32( sts[0]->input32_fx - add( lMemRecalc, lMemRecalc_SCh ), bufChanL_fx, add( lMemRecalc, lMemRecalc_SCh ) ); /* sts[0]->q_inp32 */ + Copy32( sts[1]->input32_fx - add( lMemRecalc, lMemRecalc_SCh ), bufChanR_fx, add( lMemRecalc, lMemRecalc_SCh ) ); /* sts[1]->q_inp32 */ } } @@ -1714,6 +1706,7 @@ void stereo_tca_enc_fx( scale_sig32( bufChanL_DS_fx, ADDED_MEM_DS, sub( s_min( hStereoTCA->memChan_DS_q, bufChan_q ), hStereoTCA->memChan_DS_q ) ); // s_min( hStereoTCA->memChan_DS_q, bufChan_q ) scale_sig32( bufChanR_DS_fx, ADDED_MEM_DS, sub( s_min( hStereoTCA->memChan_DS_q, bufChan_q ), hStereoTCA->memChan_DS_q ) ); // s_min( hStereoTCA->memChan_DS_q, bufChan_q ) + scale_sig32( hStereoTCA->memdecim_fx, 12, sub( s_min( hStereoTCA->memChan_DS_q, bufChan_q ), hStereoTCA->memChan_DS_q ) ); // s_min( hStereoTCA->memChan_DS_q, bufChan_q ) bufChan_q = s_min( hStereoTCA->memChan_DS_q, bufChan_q ); q_com = bufChan_q; @@ -1723,14 +1716,14 @@ void stereo_tca_enc_fx( /* pointers to the current frame of DS */ - ptrChanL_DS_fx = bufChanL_DS_fx + ADDED_MEM_DS; - ptrChanR_DS_fx = bufChanR_DS_fx + ADDED_MEM_DS; + ptrChanL_DS_fx = bufChanL_DS_fx + ADDED_MEM_DS; /* hStereoTCA->memChan_DS_q */ + ptrChanR_DS_fx = bufChanR_DS_fx + ADDED_MEM_DS; /* hStereoTCA->memChan_DS_q */ /* resample factor */ - dsFactor = (Word16) Mpy_32_32( input_Fs, 268436 /* 1/CORR_INTER_FS in Q31*/ ); // Q0 + dsFactor = extract_l( Mpy_32_32( input_Fs, 268436 /* 1/CORR_INTER_FS in Q31*/ ) ); // Q0 /* resample the stereo channels */ - deEmphResample( hStereoTCA, ptrChanL_fx, ptrChanR_fx, ptrChanL_DS_fx, ptrChanR_DS_fx, input_frame, dsFactor ); + deEmphResample_fx( hStereoTCA, ptrChanL_fx, ptrChanR_fx, ptrChanL_DS_fx, ptrChanR_DS_fx, input_frame, dsFactor ); /**********************NEED to Allign first 40 index in each channel ************************************/ /* inter-channel corrStats estimation */ @@ -1743,7 +1736,7 @@ void stereo_tca_enc_fx( prev_ICA_flag = 0; move16(); test(); - if ( hCPE->hStereoTD->prev_fr_LRTD_TD_dec && abs( hStereoTCA->prevCorrLagStats[2] ) != 0 ) + if ( hCPE->hStereoTD->prev_fr_LRTD_TD_dec && abs_s( hStereoTCA->prevCorrLagStats[2] ) != 0 ) { prev_ICA_flag = 1; move16(); @@ -1757,7 +1750,7 @@ void stereo_tca_enc_fx( move16(); maxCorrStatsDev = N_MAX_SHIFT_CHANGE; move16(); - if ( LE_16( hStereoTCA->corrStatsSmoothFac_fx, 22938 /*0.7f*/ ) ) + IF( LE_16( hStereoTCA->corrStatsSmoothFac_fx, 22938 /*0.7f*/ ) ) { maxCorrStatsDev = 160; /* L_NCSHIFT_MAX @ 32kHz */ move16(); @@ -1765,7 +1758,7 @@ void stereo_tca_enc_fx( IF( LT_32( input_Fs, 32000 ) ) { - maxCorrStatsDev = (Word16) Mpy_32_32( imult3216( input_Fs, maxCorrStatsDev ), 67109 /* 1/32000.0f in Q31*/ ); // Q0 + maxCorrStatsDev = extract_l( Mpy_32_32( imult3216( input_Fs, maxCorrStatsDev ), 67109 /* 1/32000.0f in Q31*/ ) ); // Q0 } musicMode = ( hCPE->hCoreCoder[0]->sp_aud_decision0 == 1 || sts[0]->last_core > ACELP_CORE ); @@ -1778,17 +1771,17 @@ void stereo_tca_enc_fx( set16_fx( hStereoTCA->corrLagStats + 1, 0, 2 ); } - tempS = sub( hStereoTCA->corrLagStats[1], hStereoTCA->prevCorrLagStats[2] ); + tempS = sub( hStereoTCA->corrLagStats[1], hStereoTCA->prevCorrLagStats[2] ); /* Q0 */ IF( GT_16( abs_s( tempS ), maxCorrStatsDev ) ) { IF( tempS > 0 ) { - hStereoTCA->corrLagStats[2] = add( hStereoTCA->prevCorrLagStats[2], maxCorrStatsDev ); + hStereoTCA->corrLagStats[2] = add( hStereoTCA->prevCorrLagStats[2], maxCorrStatsDev ); /* Q0 */ } ELSE { - hStereoTCA->corrLagStats[2] = add( hStereoTCA->prevCorrLagStats[2], -maxCorrStatsDev ); + hStereoTCA->corrLagStats[2] = add( hStereoTCA->prevCorrLagStats[2], -maxCorrStatsDev ); /* Q0 */ } move16(); } @@ -1802,22 +1795,24 @@ void stereo_tca_enc_fx( { tempF_fx = 0; move32(); + corrEstStage2_exp = 0; + move16(); IF( !musicMode ) { - tempLag[0] = s_min( hStereoTCA->corrLagStats[2], hStereoTCA->prevCorrLagStats[2] ); + tempLag[0] = s_min( hStereoTCA->corrLagStats[2], hStereoTCA->prevCorrLagStats[2] ); /* Q0 */ move16(); - tempLag[1] = s_max( hStereoTCA->corrLagStats[2], hStereoTCA->prevCorrLagStats[2] ); + tempLag[1] = s_max( hStereoTCA->corrLagStats[2], hStereoTCA->prevCorrLagStats[2] ); /* Q0 */ move16(); neighborLimit = s_min( 3, maxCorrStatsDev ); IF( LT_16( hStereoTCA->prevCorrLagStats[2], hStereoTCA->corrLagStats[2] ) ) { - tempLag[1] = s_min( tempLag[1], add( tempLag[0], neighborLimit ) ); + tempLag[1] = s_min( tempLag[1], add( tempLag[0], neighborLimit ) ); /* Q0 */ } ELSE { - tempLag[0] = s_max( tempLag[0], sub( tempLag[1], neighborLimit ) ); + tempLag[0] = s_max( tempLag[0], sub( tempLag[1], neighborLimit ) ); /* Q0 */ } move16(); utilCrossCorr_fx( ptrChanL_fx, q_com, ptrChanR_fx, q_com, NULL, corrEstStage2_fx, &corrEstStage2_exp, tempLag, input_frame, 0 ); @@ -1830,22 +1825,22 @@ void stereo_tca_enc_fx( IF( GT_16( abs_s( tempS ), neighborLimit ) ) { - tempLag[0] = hStereoTCA->corrLagStats[1]; + tempLag[0] = hStereoTCA->corrLagStats[1]; /* Q0 */ move16(); - tempLag[1] = hStereoTCA->corrLagStats[1]; + tempLag[1] = hStereoTCA->corrLagStats[1]; /* Q0 */ move16(); utilCrossCorr_fx( ptrChanL_fx, q_com, ptrChanR_fx, q_com, NULL, &tempF1_fx, &tempF1_exp, tempLag, input_frame, 0 ); test(); - IF( GT_32( tempF1_fx, tempF_fx ) || musicMode ) + IF( ( BASOP_Util_Cmp_Mant32Exp( tempF1_fx, tempF1_exp, tempF_fx, corrEstStage2_exp ) > 0 ) || musicMode ) { IF( tempS > 0 ) { - hStereoTCA->corrLagStats[2] = add( hStereoTCA->prevCorrLagStats[2], s_min( abs_s( tempS ), maxCorrStatsDev ) ); + hStereoTCA->corrLagStats[2] = add( hStereoTCA->prevCorrLagStats[2], s_min( abs_s( tempS ), maxCorrStatsDev ) ); /* Q0 */ } ELSE { - hStereoTCA->corrLagStats[2] = add( hStereoTCA->prevCorrLagStats[2], s_max( -abs_s( tempS ), -maxCorrStatsDev ) ); + hStereoTCA->corrLagStats[2] = add( hStereoTCA->prevCorrLagStats[2], s_max( -abs_s( tempS ), -maxCorrStatsDev ) ); /* Q0 */ } move16(); } @@ -1879,37 +1874,37 @@ void stereo_tca_enc_fx( 1. adjust samples, 2. interp shift variation, 3. gain estimation */ - prevNCShift = abs_s( hStereoTCA->prevCorrLagStats[2] ); - currentNCShift = abs_s( hStereoTCA->corrLagStats[2] ); + prevNCShift = abs_s( hStereoTCA->prevCorrLagStats[2] ); /* Q0 */ + currentNCShift = abs_s( hStereoTCA->corrLagStats[2] ); /* Q0 */ IF( EQ_16( hStereoTCA->prevRefChanIndx, L_CH_INDX ) ) { - v_multc_fixed( bufChanL_fx, ONE_IN_Q29, bufChanL_fx, L_MEM_RECALC_48K + L_MEM_RECALC_48k_SCH + L_FRAME48k + L_NCSHIFTMAX ); /* TO make in common Q*/ + v_multc_fixed( bufChanL_fx, ONE_IN_Q29, bufChanL_fx, L_MEM_RECALC_48K + L_MEM_RECALC_48k_SCH + L_FRAME48k + L_NCSHIFTMAX ); /* TO make in common Q bufChan_q - 2*/ Copy32( ptrChanL_fx - add( lMemRecalc, lMemRecalc_SCh ), input_mem_loc_fx[0], add( lMemRecalc, lMemRecalc_SCh ) ); // bufChan_q - 2 v_multc_fixed( ptrChanR_fx + sub( prevNCShift, add( lMemRecalc, lMemRecalc_SCh ) ), hStereoTCA->prevTargetGain_fx, input_mem_loc_fx[1], add( lMemRecalc, lMemRecalc_SCh ) ); // bufChan_q-2 - v_multc_fixed( bufChanR_fx, ONE_IN_Q29, bufChanR_fx, L_MEM_RECALC_48K + L_MEM_RECALC_48k_SCH + L_FRAME48k + L_NCSHIFTMAX ); /* TO make in common Q bufChan_q -2 */ + v_multc_fixed( bufChanR_fx, ONE_IN_Q29, bufChanR_fx, L_MEM_RECALC_48K + L_MEM_RECALC_48k_SCH + L_FRAME48k + L_NCSHIFTMAX ); /* TO make in common Q bufChan_q -2*/ } ELSE { - v_multc_fixed( bufChanL_fx, ONE_IN_Q29, bufChanL_fx, L_MEM_RECALC_48K + L_MEM_RECALC_48k_SCH + L_FRAME48k + L_NCSHIFTMAX ); /* TO make in common Q*/ - Copy32( ptrChanL_fx + add( prevNCShift, sub( lMemRecalc, lMemRecalc_SCh ) ), input_mem_loc_fx[0], add( lMemRecalc, lMemRecalc_SCh ) ); // bufChan_q -2 + v_multc_fixed( bufChanL_fx, ONE_IN_Q29, bufChanL_fx, L_MEM_RECALC_48K + L_MEM_RECALC_48k_SCH + L_FRAME48k + L_NCSHIFTMAX ); /* TO make in common Q bufChan_q -2*/ + Copy32( ptrChanL_fx + sub( prevNCShift, add( lMemRecalc, lMemRecalc_SCh ) ), input_mem_loc_fx[0], add( lMemRecalc, lMemRecalc_SCh ) ); // bufChan_q -2 v_multc_fixed( ptrChanR_fx - add( lMemRecalc, lMemRecalc_SCh ), hStereoTCA->prevTargetGain_fx, input_mem_loc_fx[1], add( lMemRecalc, lMemRecalc_SCh ) ); // bufChan_q -2 - v_multc_fixed( bufChanR_fx, ONE_IN_Q29, bufChanR_fx, L_MEM_RECALC_48K + L_MEM_RECALC_48k_SCH + L_FRAME48k + L_NCSHIFTMAX ); /* TO make in common Q*/ + v_multc_fixed( bufChanR_fx, ONE_IN_Q29, bufChanR_fx, L_MEM_RECALC_48K + L_MEM_RECALC_48k_SCH + L_FRAME48k + L_NCSHIFTMAX ); /* TO make in common Q bufChan_q -2*/ } bufChan_q = sub( bufChan_q, 2 ); q_com = bufChan_q; move16(); input_mem_loc_q = bufChan_q; move16(); - target_fx = ptrChanR_fx; - target_idx = R_CH_INDX; + target_fx = ptrChanR_fx; /* bufChan_q -2 */ + target_idx = R_CH_INDX; /* Q0 */ move16(); /* identify target signal to correct for shift variations */ test(); test(); IF( ( prevNCShift == 0 && hStereoTCA->corrLagStats[2] < 0 ) || EQ_16( hStereoTCA->prevRefChanIndx, R_CH_INDX ) ) { - target_fx = ptrChanL_fx; + target_fx = ptrChanL_fx; /* bufChan_q - 2 */ target_idx = L_CH_INDX; move16(); } @@ -1926,26 +1921,30 @@ void stereo_tca_enc_fx( } /* Note!! : Always keep the assert (prevNCShift>>1) below according to the equation used here to get tempS */ - tempS = shr( currentNCShift, 1 ); + tempS = shr( currentNCShift, 1 ); /* Q0 */ - IF( LE_32( abs( sub( currentNCShift, prevNCShift ) ), L_min( N_MAX_SHIFT_CHANGE, Mpy_32_32( imult3216( input_Fs, N_MAX_SHIFT_CHANGE ), 67109 /* 1/32000.0f in Q31*/ ) ) ) ) + IF( LE_32( abs_s( sub( currentNCShift, prevNCShift ) ), L_min( N_MAX_SHIFT_CHANGE, Mpy_32_32( imult3216( input_Fs, N_MAX_SHIFT_CHANGE ), 67109 /* 1/32000.0f in Q31*/ ) ) ) ) { adjustTargetSignal_fx( ( target_fx - tempS ), prevNCShift, currentNCShift, L_shift_adapt, 0 ); } ELSE { - tempS = s_min( s_max( tempS, add( sub( prevNCShift, currentNCShift ), sub( L_shift_adapt, input_frame ) ) ), add( sub( prevNCShift, currentNCShift ), lMemRecalc ) ); + tempS = s_min( s_max( tempS, add( sub( prevNCShift, currentNCShift ), sub( L_shift_adapt, input_frame ) ) ), add( sub( prevNCShift, currentNCShift ), lMemRecalc ) ); /* Q0 */ adjustTargetSignal_fx( ( target_fx - tempS ), prevNCShift, currentNCShift, L_shift_adapt, 1 ); } IF( target_idx == L_CH_INDX ) { - Copy32( target_fx - tempS, &( input_mem_loc_fx[target_idx][lMemRecalc + lMemRecalc_SCh - tempS - currentNCShift] ), add( currentNCShift, tempS ) ); + Copy32( target_fx - tempS, &( input_mem_loc_fx[target_idx][lMemRecalc + lMemRecalc_SCh - tempS - currentNCShift] ), add( currentNCShift, tempS ) ); /* bufChan_q - 2 */ } ELSE { - v_multc_fixed( target_fx - tempS, hStereoTCA->prevTargetGain_fx, &( input_mem_loc_fx[target_idx][lMemRecalc + lMemRecalc_SCh - tempS - currentNCShift] ), add( currentNCShift, tempS ) ); + v_multc_fixed( target_fx - tempS, hStereoTCA->prevTargetGain_fx, &( input_mem_loc_fx[target_idx][lMemRecalc + lMemRecalc_SCh - tempS - currentNCShift] ), add( currentNCShift, tempS ) ); /* bufChan_q - 2 */ + scale_sig32( input_mem_loc_fx[target_idx], sub( sub( add( lMemRecalc, lMemRecalc_SCh ), tempS ), currentNCShift ), -2 ); + scale_sig32( &input_mem_loc_fx[target_idx][lMemRecalc + lMemRecalc_SCh], sub( NS2SA( 48000, L_MEM_RECALC_NS + L_MEM_RECALC_SCH_NS ), add( lMemRecalc, lMemRecalc_SCh ) ), -2 ); + scale_sig32( input_mem_loc_fx[0], NS2SA( 48000, L_MEM_RECALC_NS + L_MEM_RECALC_SCH_NS ), -2 ); + input_mem_loc_q = sub( bufChan_q, 2 ); } } @@ -1967,18 +1966,25 @@ void stereo_tca_enc_fx( /* quantize the corrStats */ Word16 temp_exp, tempF_16fx; - Word16 scalar_value = BASOP_Util_Divide1616_Scale( currentNCShift, dsFactor, &temp_exp ); + Word16 scalar_value = BASOP_Util_Divide1616_Scale( currentNCShift, dsFactor, &temp_exp ); /* Q15-temp_exp */ + +#ifndef FIX_1300_ICA_SHIFT_QUANT_IMPROV IF( temp_exp < 0 ) { - scalar_value = shl( scalar_value, sub( temp_exp, Q3 ) ); // Q12 - hStereoTCA->indx_ica_NCShift = usquant_fx( scalar_value, &tempF_16fx, 0, ONE_IN_Q11, 1 << STEREO_BITS_TCA_CORRSTATS ); + scalar_value = shl( scalar_value, sub( temp_exp, Q3 ) ); // Q12 + hStereoTCA->indx_ica_NCShift = usquant_fx( scalar_value, &tempF_16fx, 0, ONE_IN_Q11, ( 1 << STEREO_BITS_TCA_CORRSTATS ) ); /* Q0 */ move16(); } ELSE { - hStereoTCA->indx_ica_NCShift = usquant_fx( scalar_value, &tempF_16fx, 0, shl( 1, sub( 14, temp_exp ) ), 1 << STEREO_BITS_TCA_CORRSTATS ); + hStereoTCA->indx_ica_NCShift = usquant_fx( scalar_value, &tempF_16fx, 0, shl( 1, sub( 14, temp_exp ) ), ( 1 << STEREO_BITS_TCA_CORRSTATS ) ); /* Q0 */ move16(); } +#else + scalar_value = shl_sat( scalar_value, sub( temp_exp, 5 ) ); /*Q10*/ + hStereoTCA->indx_ica_NCShift = usquant_fx( scalar_value, &tempF_16fx, 0, 512 /* 0.5 in Q10 */, ( 1 << STEREO_BITS_TCA_CORRSTATS ) ); /* Q0 */ +#endif + tempF_fx = tempF_16fx; move32(); } @@ -1995,7 +2001,7 @@ void stereo_tca_enc_fx( currentNCShift = 0; /* only to avoid compilation warning */ move16(); - target_fx = ptrChanL_fx; /* only to avoid compilation warning */ + target_fx = ptrChanL_fx; /* only to avoid compilation warning bufChan_q*/ move16(); target_idx = L_CH_INDX; /* only to avoid compilation warning */ move16(); @@ -2021,8 +2027,8 @@ void stereo_tca_enc_fx( *-----------------------------------------------------------------*/ /* back up the L/R missing target */ - Copy32( bufChanL_fx + input_frame, hStereoTCA->memChanL_fx, add( lMemRecalc, lMemRecalc_SCh ) ); - Copy32( bufChanR_fx + input_frame, hStereoTCA->memChanR_fx, add( lMemRecalc, lMemRecalc_SCh ) ); + Copy32( bufChanL_fx + input_frame, hStereoTCA->memChanL_fx, add( lMemRecalc, lMemRecalc_SCh ) ); /* bufChan_q */ + Copy32( bufChanR_fx + input_frame, hStereoTCA->memChanR_fx, add( lMemRecalc, lMemRecalc_SCh ) ); /* bufChan_q */ hStereoTCA->memChan_q = bufChan_q; IF( currentNCShift != 0 ) @@ -2030,16 +2036,14 @@ void stereo_tca_enc_fx( /* Temporal channel adjustment of the LA samples based on the NC shift */ tcaTargetCh_LA_fx( hStereoTCA, ptrChanL_fx, ptrChanR_fx, &q_com, currentNCShift, input_frame ); - Word16 additional_length = NS2SA( L_mult0( input_frame, FRAMES_PER_SEC ), L_SAMPLES_LA_NS ); - move16(); - scale_sig32( bufChanL_fx, add( lMemRecalc, lMemRecalc_SCh ), sub( s_min( q_com, bufChan_q ), bufChan_q ) ); // s_min( q_com, bufChan_q ) - scale_sig32( bufChanL_fx + add( lMemRecalc, lMemRecalc_SCh ), add( input_frame, additional_length ), sub( s_min( q_com, bufChan_q ), q_com ) ); // s_min( q_com, bufChan_q ) - scale_sig32( bufChanL_fx + add( add( lMemRecalc, lMemRecalc_SCh ), add( input_frame, additional_length ) ), sub( L_MEM_RECALC_48K + L_MEM_RECALC_48k_SCH + L_FRAME48k + L_NCSHIFTMAX, add( add( lMemRecalc, lMemRecalc_SCh ), add( input_frame, additional_length ) ) ), sub( s_min( q_com, bufChan_q ), bufChan_q ) ); // s_min( q_com, bufChan_q ) + scale_sig32( bufChanL_fx, add( lMemRecalc, lMemRecalc_SCh ), sub( s_min( q_com, bufChan_q ), bufChan_q ) ); // s_min( q_com, bufChan_q ) + scale_sig32( bufChanL_fx + add( lMemRecalc, lMemRecalc_SCh ), add( input_frame, currentNCShift ), sub( s_min( q_com, bufChan_q ), q_com ) ); // s_min( q_com, bufChan_q ) + scale_sig32( bufChanL_fx + add( add( lMemRecalc, lMemRecalc_SCh ), add( input_frame, currentNCShift ) ), sub( L_MEM_RECALC_48K + L_MEM_RECALC_48k_SCH + L_FRAME48k + L_NCSHIFTMAX, add( add( lMemRecalc, lMemRecalc_SCh ), add( input_frame, currentNCShift ) ) ), sub( s_min( q_com, bufChan_q ), bufChan_q ) ); // s_min( q_com, bufChan_q ) /* Scaling to common Q*/ - scale_sig32( bufChanR_fx, add( lMemRecalc, lMemRecalc_SCh ), sub( s_min( q_com, bufChan_q ), bufChan_q ) ); // s_min( q_com, bufChan_q ) - scale_sig32( bufChanR_fx + add( lMemRecalc, lMemRecalc_SCh ), add( input_frame, additional_length ), sub( s_min( q_com, bufChan_q ), q_com ) ); // s_min( q_com, bufChan_q ) - scale_sig32( bufChanR_fx + add( add( lMemRecalc, lMemRecalc_SCh ), add( input_frame, additional_length ) ), sub( L_MEM_RECALC_48K + L_MEM_RECALC_48k_SCH + L_FRAME48k + L_NCSHIFTMAX, add( add( lMemRecalc, lMemRecalc_SCh ), add( input_frame, additional_length ) ) ), sub( s_min( q_com, bufChan_q ), bufChan_q ) ); // s_min( q_com, bufChan_q ) + scale_sig32( bufChanR_fx, add( lMemRecalc, lMemRecalc_SCh ), sub( s_min( q_com, bufChan_q ), bufChan_q ) ); // s_min( q_com, bufChan_q ) + scale_sig32( bufChanR_fx + add( lMemRecalc, lMemRecalc_SCh ), add( input_frame, currentNCShift ), sub( s_min( q_com, bufChan_q ), q_com ) ); // s_min( q_com, bufChan_q ) + scale_sig32( bufChanR_fx + add( add( lMemRecalc, lMemRecalc_SCh ), add( input_frame, currentNCShift ) ), sub( L_MEM_RECALC_48K + L_MEM_RECALC_48k_SCH + L_FRAME48k + L_NCSHIFTMAX, add( add( lMemRecalc, lMemRecalc_SCh ), add( input_frame, currentNCShift ) ) ), sub( s_min( q_com, bufChan_q ), bufChan_q ) ); // s_min( q_com, bufChan_q ) bufChan_q = s_min( q_com, bufChan_q ); q_com = bufChan_q; } @@ -2051,26 +2055,31 @@ void stereo_tca_enc_fx( scale_sig32( sts[0]->input_buff32_fx, L_FRAME48k + L_FRAME48k + NS2SA( 48000, DELAY_FIR_RESAMPL_NS ), sub( s_min( input_mem_loc_q, sts[0]->q_inp32 ), sts[0]->q_inp32 ) ); // s_min( input_mem_loc_q, sts[0]->q_inp32 ) scale_sig32( sts[1]->input_buff32_fx, L_FRAME48k + L_FRAME48k + NS2SA( 48000, DELAY_FIR_RESAMPL_NS ), sub( s_min( input_mem_loc_q, sts[1]->q_inp32 ), sts[1]->q_inp32 ) ); // s_min( input_mem_loc_q, sts[0]->q_inp32 ) - input_mem_loc_q = s_min( input_mem_loc_q, sts[0]->q_inp32 ); + input_mem_loc_q = s_min( input_mem_loc_q, sts[0]->q_inp32 ); /* sts[0]->q_inp32 */ sts[0]->q_inp32 = input_mem_loc_q; move16(); sts[1]->q_inp32 = input_mem_loc_q; move16(); - icaMemUpdate_fx( sts, hCPE, input_mem_loc_fx[0], input_mem_loc_fx[1], q_com, lMemRecalc, lMemRecalc_SCh, input_frame ); + icaMemUpdate_fx( sts, hCPE, input_mem_loc_fx[0], input_mem_loc_fx[1], input_mem_loc_q, lMemRecalc, lMemRecalc_SCh, input_frame ); /* populate the st->input target buffer */ test(); IF( hCPE->hStereoTD->prev_fr_LRTD_TD_dec == 0 || EQ_16( prev_ICA_flag, 1 ) ) { - Copy32( target_fx + currentNCShift, sts[target_idx]->input32_fx, input_frame ); + Word16 shift = sub( q_com, sts[target_idx]->q_inp32 ); + FOR( Word16 idx = 0; idx < input_frame; idx++ ) + { + sts[target_idx]->input32_fx[idx] = L_shr( target_fx[currentNCShift + idx], shift ); + move32(); + } } IF( NE_16( hCPE->element_mode, IVAS_CPE_DFT ) ) { /* Scale the Right channel with the gain */ Word16 j; - Word16 l_ica_ovl = NS2SA( input_Fs, STEREO_L_TCA_OVLP_NS ); + Word16 l_ica_ovl = NS2SA_FX2( input_Fs, STEREO_L_TCA_OVLP_NS ); Word16 winSlope = div_s( 1, l_ica_ovl ); // Q15 @@ -2100,14 +2109,14 @@ void stereo_tca_enc_fx( } /* update L/R DS memories */ - Copy32( bufChanL_DS_fx + L_FRAME_DS, hStereoTCA->memChanL_DS_fx, ADDED_MEM_DS ); - Copy32( bufChanR_DS_fx + L_FRAME_DS, hStereoTCA->memChanR_DS_fx, ADDED_MEM_DS ); + Copy32( bufChanL_DS_fx + L_FRAME_DS, hStereoTCA->memChanL_DS_fx, ADDED_MEM_DS ); /* hStereoTCA->memChan_DS_q */ + Copy32( bufChanR_DS_fx + L_FRAME_DS, hStereoTCA->memChanR_DS_fx, ADDED_MEM_DS ); /* hStereoTCA->memChan_DS_q */ /* save the reference channel index for next frame */ - hStereoTCA->prevRefChanIndx = hStereoTCA->refChanIndx; + hStereoTCA->prevRefChanIndx = hStereoTCA->refChanIndx; /* Q0 */ move16(); /* save the corr lag stats for next frame */ - Copy( hStereoTCA->corrLagStats, hStereoTCA->prevCorrLagStats, 3 ); + Copy( hStereoTCA->corrLagStats, hStereoTCA->prevCorrLagStats, 3 ); /* Q0 */ /* save the target gain for next frame */ hStereoTCA->prevTargetGain_fx = hStereoTCA->targetGain_fx; // Q29 @@ -2121,18 +2130,18 @@ void stereo_tca_enc_fx( *-------------------------------------------------------------------*/ void stereo_tca_init_enc_fx( STEREO_TCA_ENC_HANDLE hStereoTCA, /* i/o: Stereo ICA handle */ - const Word32 input_Fs /* i : input sampling frequency */ + const Word32 input_Fs /* i : input sampling frequency Q0*/ ) { Word16 div1; Word16 div_e; hStereoTCA->lMemRecalc = NS2SA_FX2( input_Fs, L_MEM_RECALC_NS ); move16(); - div1 = BASOP_Util_Divide3232_Scale( L_mult( hStereoTCA->lMemRecalc, INT_FS_12k8 ), input_Fs, &div_e ); + div1 = BASOP_Util_Divide3232_Scale( L_mult( hStereoTCA->lMemRecalc, INT_FS_12k8 ), input_Fs, &div_e ); /* Q15-div_e */ hStereoTCA->lMemRecalc_12k8 = shr( div1, 1 + sub( 15, div_e ) ); move16(); - div1 = BASOP_Util_Divide3232_Scale( L_mult( hStereoTCA->lMemRecalc, INT_FS_16k ), input_Fs, &div_e ); + div1 = BASOP_Util_Divide3232_Scale( L_mult( hStereoTCA->lMemRecalc, INT_FS_16k ), input_Fs, &div_e ); /* Q15-div_e */ hStereoTCA->lMemRecalc_16k = shr( div1, 1 + sub( 15, div_e ) ); move16(); @@ -2210,10 +2219,10 @@ static void unclr_calc_corr_features_fx( Word32 buf1[], /* i : left channel q_com*/ Word32 buf2[], /* i : right channel q_com*/ Word16 q_com, - const Word16 length, /* i : length of input signal buffers */ + const Word16 length, /* i : length of input signal buffers Q0*/ Word32 corrEst[], /* i : buffer containing inter-channel correlation values corrEst_exp*/ Word16 corrEst_exp, - const Word16 lagSearchRange[], /* i : minimum and maximum lags for corrEst[] */ + const Word16 lagSearchRange[], /* i : minimum and maximum lags for corrEst[] Q0*/ Word32 *corrEst_ncorr, /* o : norm. x-correlation btw. current and previous correlation buffers corrEst_ncorr_exp*/ Word16 *corrEst_ncorr_exp ) { @@ -2246,22 +2255,35 @@ static void unclr_calc_corr_features_fx( FOR( i = 0; i < length; i++ ) { - mono_i = BASOP_Util_Add_Mant32Exp( L_shr( buf1[i], 1 ), sub( 31, q_com ), L_shr( buf2[i], 1 ), sub( 31, q_com ), &exp ); - corrL = BASOP_Util_Add_Mant32Exp( corrL, corrL_exp, Mpy_32_32( buf1[i], mono_i ), add( sub( 31, q_com ), exp ), &corrL_exp ); - corrR = BASOP_Util_Add_Mant32Exp( corrR, corrR_exp, Mpy_32_32( buf2[i], mono_i ), add( sub( 31, q_com ), exp ), &corrR_exp ); + mono_i = BASOP_Util_Add_Mant32Exp( L_shr( buf1[i], 1 ), sub( 31, q_com ), L_shr( buf2[i], 1 ), sub( 31, q_com ), &exp ); /* Q31-exp */ + corrL = BASOP_Util_Add_Mant32Exp( corrL, corrL_exp, Mpy_32_32( buf1[i], mono_i ), add( sub( 31, q_com ), exp ), &corrL_exp ); /* Q31-corrL_exp */ + corrR = BASOP_Util_Add_Mant32Exp( corrR, corrR_exp, Mpy_32_32( buf2[i], mono_i ), add( sub( 31, q_com ), exp ), &corrR_exp ); /* Q31-corrR_exp */ ener = BASOP_Util_Add_Mant32Exp( ener, ener_exp, Mpy_32_32( mono_i, mono_i ), shl( exp, 1 ), &ener_exp ); - side_i = BASOP_Util_Add_Mant32Exp( L_shr( buf1[i], 1 ), sub( 31, q_com ), L_negate( L_shr( buf2[i], 1 ) ), sub( 31, q_com ), &exp ); - ener_side = BASOP_Util_Add_Mant32Exp( ener_side, ener_side_exp, Mpy_32_32( side_i, side_i ), shl( exp, 1 ), &ener_side_exp ); - sum_prod = BASOP_Util_Add_Mant32Exp( sum_prod, sum_prod_exp, Mpy_32_32( buf1[i], buf2[i] ), sub( 62, shl( q_com, 1 ) ), &sum_prod_exp ); + side_i = BASOP_Util_Add_Mant32Exp( L_shr( buf1[i], 1 ), sub( 31, q_com ), L_negate( L_shr( buf2[i], 1 ) ), sub( 31, q_com ), &exp ); /* Q31-exp */ + ener_side = BASOP_Util_Add_Mant32Exp( ener_side, ener_side_exp, Mpy_32_32( side_i, side_i ), shl( exp, 1 ), &ener_side_exp ); /* Q31-ener_side_exp */ + +#ifdef FIX_ISSUE_1125 + Word16 n1, n2, prod_i_exp; + Word32 x, y, prod_i; + n1 = norm_l( buf1[i] ); + n2 = norm_l( buf2[i] ); + x = L_shl( buf1[i], n1 ); // q: q_com + n1 + y = L_shl( buf2[i], n2 ); // q: q_com + n2 + prod_i = Mpy_32_32( x, y ); // q: q_com * 2 + n1 + n2 - 31 + prod_i_exp = sub( 62, add( shl( q_com, 1 ), add( n1, n2 ) ) ); + sum_prod = BASOP_Util_Add_Mant32Exp( sum_prod, sum_prod_exp, prod_i, prod_i_exp, &sum_prod_exp ); /* Q31-sum_prod_exp */ +#else + sum_prod = BASOP_Util_Add_Mant32Exp( sum_prod, sum_prod_exp, Mpy_32_32( buf1[i], buf2[i] ), sub( 62, shl( q_com, 1 ) ), &sum_prod_exp ); /* Q31-sum_prod_exp */ +#endif } /* average energy of L and R channels */ - hStereoClassif->ave_ener_L_fx = Mpy_32_32( hStereoTCA->E1_mem_fx, 13421772 /* 1/length in Q31*/ ); + hStereoClassif->ave_ener_L_fx = Mpy_32_32( hStereoTCA->E1_mem_fx, 13421772 /* 1/length in Q31*/ ); /* Q31-hStereoClassif->ave_ener_L_fx_e */ move32(); hStereoClassif->ave_ener_L_fx_e = hStereoTCA->E1_mem_exp; move16(); - hStereoClassif->ave_ener_R_fx = Mpy_32_32( hStereoTCA->E2_mem_fx, 13421772 /* 1/length in Q31*/ ); + hStereoClassif->ave_ener_R_fx = Mpy_32_32( hStereoTCA->E2_mem_fx, 13421772 /* 1/length in Q31*/ ); /* Q31-hStereoClassif->ave_ener_R_fx_e */ move32(); hStereoClassif->ave_ener_R_fx_e = hStereoTCA->E2_mem_exp; move16(); @@ -2269,7 +2291,7 @@ static void unclr_calc_corr_features_fx( /* unnormalized L/R correlation */ IF( sum_prod ) { - sum_prod = BASOP_Util_Log10( L_abs( sum_prod ), sum_prod_exp ); + sum_prod = BASOP_Util_Log10( L_abs( sum_prod ), sum_prod_exp ); /* Q31-sum_prod_exp */ sum_prod_exp = 6; move16(); } @@ -2286,12 +2308,12 @@ static void unclr_calc_corr_features_fx( hStereoClassif->xtalk_fv_fx[E_sum_prod] = L_shr( sum_prod, 10 ); // Q15 move32(); /* S/M energy ratio */ - Word32 inp1 = Sqrt32( Mpy_32_32( ener_side, 13421773 /* 1/L_FRAME_DS in Q31*/ ), &ener_side_exp ); - inp1 = BASOP_Util_Log10( inp1, ener_side_exp ); + Word32 inp1 = Sqrt32( Mpy_32_32( ener_side, 13421773 /* 1/L_FRAME_DS in Q31*/ ), &ener_side_exp ); /* Q31-ener_side_exp */ + inp1 = BASOP_Util_Log10( inp1, ener_side_exp ); /* Q31-ener_side_exp */ Word16 temp = ener_exp; move16(); - Word32 inp2 = Sqrt32( Mpy_32_32( ener, 13421773 /* 1/L_FRAME_DS in Q31*/ ), &ener_exp ); - inp2 = BASOP_Util_Log10( inp2, ener_exp ); + Word32 inp2 = Sqrt32( Mpy_32_32( ener, 13421773 /* 1/L_FRAME_DS in Q31*/ ), &ener_exp ); /* Q31-ener_exp */ + inp2 = BASOP_Util_Log10( inp2, ener_exp ); /* Q31-ener_exp */ ener_exp = temp; move16(); @@ -2319,17 +2341,17 @@ static void unclr_calc_corr_features_fx( move32(); } - hStereoClassif->unclr_fv_fx[E_corrEst0] = L_shl( corrEst[abs_s( lagSearchRange[0] )], sub( corrEst_exp, 16 ) ); + hStereoClassif->unclr_fv_fx[E_corrEst0] = L_shl( corrEst[abs_s( lagSearchRange[0] )], sub( corrEst_exp, 16 ) ); /* Q15 */ move32(); - hStereoClassif->unclr_fv_fx[E_corrEstMax] = L_shl( corrEstMax, sub( corrEst_exp, 16 ) ); + hStereoClassif->unclr_fv_fx[E_corrEstMax] = L_shl( corrEstMax, sub( corrEst_exp, 16 ) ); /* Q15 */ move32(); - hStereoClassif->unclr_fv_fx[E_corrLagMax] = L_shl( corrLagMax, 15 ); + hStereoClassif->unclr_fv_fx[E_corrLagMax] = L_shl( corrLagMax, 15 ); /* Q15 */ move32(); - hStereoClassif->xtalk_fv_fx[E_corrEst0] = L_shl( corrEst[abs_s( lagSearchRange[0] )], sub( corrEst_exp, 16 ) ); + hStereoClassif->xtalk_fv_fx[E_corrEst0] = L_shl( corrEst[abs_s( lagSearchRange[0] )], sub( corrEst_exp, 16 ) ); /* Q15 */ move32(); - hStereoClassif->xtalk_fv_fx[E_corrEstMax] = L_shl( corrEstMax, sub( corrEst_exp, 16 ) ); + hStereoClassif->xtalk_fv_fx[E_corrEstMax] = L_shl( corrEstMax, sub( corrEst_exp, 16 ) ); /* Q15 */ move32(); - hStereoClassif->xtalk_fv_fx[E_corrLagMax] = L_shl( corrLagMax, 15 ); + hStereoClassif->xtalk_fv_fx[E_corrLagMax] = L_shl( corrLagMax, 15 ); /* Q15 */ move32(); /* L/M and R/M correlation */ @@ -2345,14 +2367,14 @@ static void unclr_calc_corr_features_fx( move32(); } - ic_Lm = BASOP_Util_Divide3232_Scale_cadence( corrL, ener, &exp1 ); + ic_Lm = BASOP_Util_Divide3232_Scale_cadence( corrL, ener, &exp1 ); /* Q31-exp1 */ exp1 = add( exp1, sub( corrL_exp, ener_exp ) ); - ic_Rm = BASOP_Util_Divide3232_Scale_cadence( corrR, ener, &exp2 ); + ic_Rm = BASOP_Util_Divide3232_Scale_cadence( corrR, ener, &exp2 ); /* Q31-exp2 */ exp2 = add( exp2, sub( corrR_exp, ener_exp ) ); m_corrL_corrR = L_sub( L_max( L_abs( L_shl( ic_Lm, sub( exp1, s_max( exp1, exp2 ) ) ) ), L_abs( L_shl( ic_Rm, sub( exp2, s_max( exp1, exp2 ) ) ) ) ), L_min( L_abs( L_shl( ic_Lm, sub( exp1, s_max( exp1, exp2 ) ) ) ), L_abs( L_shl( ic_Rm, sub( exp2, s_max( exp1, exp2 ) ) ) ) ) ); // s_max(exp1, exp2) - inp1 = BASOP_Util_Add_Mant32Exp( corrL, corrL_exp, corrR, corrR_exp, &exp ); + inp1 = BASOP_Util_Add_Mant32Exp( corrL, corrL_exp, L_negate( corrR ), corrR_exp, &exp ); /* Q31-exp */ IF( inp1 ) { d_corrL_corrR = BASOP_Util_Log10( L_abs( inp1 ), exp ); // Q25 @@ -2372,16 +2394,17 @@ static void unclr_calc_corr_features_fx( /* norm. x-correlation btw. current and previous correlation buffers */ tempLen = ( 2 * L_NCSHIFT_DS + 1 ); + move16(); Word64 L64_sum = 0; move64(); FOR( k = 0; k < tempLen; k++ ) { - L64_sum = W_mac_32_32( L64_sum, corrEst[k], hStereoTCA->corrEstPrev_fx[2][k] ); + L64_sum = W_mac_32_32( L64_sum, corrEst[k], hStereoTCA->corrEstPrev_fx[2][k] ); /* 2*(Q31-corrEst_exp)+1 */ } k = W_norm( L64_sum ); - L64_sum = W_shl( L64_sum, k ); - num = W_extract_h( L64_sum ); // ener_side_q + L64_sum = W_shl( L64_sum, k ); /* 2*(Q31-corrEst_exp)+1+k */ + num = W_extract_h( L64_sum ); // ener_side_q num_exp = sub( 31, sub( add( add( add( sub( 31, corrEst_exp ), sub( 31, hStereoTCA->corrEstPrev_exp ) ), 1 ), k ), 32 ) ); exp1 = corrEst_exp; @@ -2393,24 +2416,26 @@ static void unclr_calc_corr_features_fx( inp2 = sum2_32_exp_fx( hStereoTCA->corrEstPrev_fx[2], tempLen, &exp2, 3 ); den_exp = add( exp1, exp2 ); - den = Sqrt32( Mpy_32_32( inp1, inp2 ), &den_exp ); + den = Sqrt32( Mpy_32_32( inp1, inp2 ), &den_exp ); /* Q31-den_exp */ IF( den == 0 ) { *corrEst_ncorr = 0; - move16(); - *corrEst_ncorr_exp = 0; move32(); + *corrEst_ncorr_exp = 0; + move16(); } ELSE { - *corrEst_ncorr = BASOP_Util_Divide3232_Scale_cadence( num, den, &exp ); + *corrEst_ncorr = BASOP_Util_Divide3232_Scale_cadence( num, den, &exp ); /* Q31-corrEst_ncorr_exp */ *corrEst_ncorr_exp = add( exp, sub( num_exp, den_exp ) ); + move32(); + move16(); } - hStereoClassif->unclr_fv_fx[E_corrEst_ncorr] = L_shl( *corrEst_ncorr, sub( *corrEst_ncorr_exp, 16 ) ); + hStereoClassif->unclr_fv_fx[E_corrEst_ncorr] = L_shl( *corrEst_ncorr, sub( *corrEst_ncorr_exp, 16 ) ); /* Q15 */ move32(); - hStereoClassif->xtalk_fv_fx[E_corrEst_ncorr] = L_shl( *corrEst_ncorr, sub( *corrEst_ncorr_exp, 16 ) ); + hStereoClassif->xtalk_fv_fx[E_corrEst_ncorr] = L_shl( *corrEst_ncorr, sub( *corrEst_ncorr_exp, 16 ) ); /* Q15 */ move32(); return; diff --git a/lib_enc/ivas_stereo_icbwe_enc.c b/lib_enc/ivas_stereo_icbwe_enc_fx.c similarity index 75% rename from lib_enc/ivas_stereo_icbwe_enc.c rename to lib_enc/ivas_stereo_icbwe_enc_fx.c index 7ed9d71d179ec00e7e98b21412195130e0481684..bc84ba419072bd70dd77f4726678c80f6c4a4591 100644 --- a/lib_enc/ivas_stereo_icbwe_enc.c +++ b/lib_enc/ivas_stereo_icbwe_enc_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other @@ -35,12 +35,10 @@ #include #include "cnst.h" #include "ivas_cnst.h" -#include "prot.h" -#include "ivas_prot.h" +#include "prot_fx.h" #include "wmc_auto.h" #include "rom_com.h" #include "ivas_rom_com.h" -#include "prot_fx.h" #include "ivas_prot_fx.h" #include "ivas_rom_com_fx.h" @@ -61,7 +59,7 @@ static void ic_bwe_enc_reset_fx( /* inter-channel BWE spectral shape adj. */ hStereoICBWE->prevSpecMapping_fx = 0; move32(); - hStereoICBWE->prevgsMapping_fx = ONE_IN_Q31; + hStereoICBWE->prevgsMapping_fx = ONE_IN_Q31; /* Q31 */ move32(); hStereoICBWE->prevgsMapping_e = 0; move16(); @@ -71,7 +69,7 @@ static void ic_bwe_enc_reset_fx( set32_fx( hStereoICBWE->memShbSpecXcorr_fx, 0, 6 ); hStereoICBWE->memShbSpecXcorr_e = 0; move16(); - set32_fx( hStereoICBWE->memGsEnerMap_fx, ONE_IN_Q31, 2 ); + set32_fx( hStereoICBWE->memGsEnerMap_fx, ONE_IN_Q31, 2 ); /* Q31 */ hStereoICBWE->memGsEnerMap_e = 0; move16(); set32_fx( hStereoICBWE->mem_nrg_L_fx, 0, 2 ); @@ -83,7 +81,7 @@ static void ic_bwe_enc_reset_fx( set32_fx( hStereoICBWE->mem_nrg_DMX_fx, 0, 2 ); hStereoICBWE->mem_nrg_DMX_fx_e = 0; move16(); - hStereoICBWE->gDes_pastFrame_fx = ONE_IN_Q31; + hStereoICBWE->gDes_pastFrame_fx = ONE_IN_Q31; /* Q31 */ move32(); hStereoICBWE->gDes_pastFrame_e = 0; move16(); @@ -101,13 +99,13 @@ static void ic_bwe_enc_reset_fx( * Encode and apply the spectral shape mapping of ref to the non-ref channel *---------------------------------------------------------------------------*/ static Word16 ic_bwe_enc_specMapping_ivas_fx( - const Word32 *shb_frame_target_fx, /* i : target shb */ + const Word32 *shb_frame_target_fx, /* i : target shb Q31-shb_frame_target_e*/ Word16 shb_frame_target_e, - Word32 *shb_synth_nonref_fx, /* o : non-ref shb synth */ + Word32 *shb_synth_nonref_fx, /* o : non-ref shb synth Q31-shb_synth_nonref_e*/ Word16 shb_synth_nonref_e, - Word32 *specMapping_fx, /* i/o: current frame's mapping */ - Word32 *memShbSpecMapping_fx, /* i/o: current frame's mapping */ - Word32 *memShbSpecXcorr_fx, /* i/o: ic bwe spec mapping scorr memory */ + Word32 *specMapping_fx, /* i/o: current frame's mapping Qx*/ + Word32 *memShbSpecMapping_fx, /* i/o: current frame's mapping Qx*/ + Word32 *memShbSpecXcorr_fx, /* i/o: ic bwe spec mapping scorr memory Q31-memShbSpecXcorr_e*/ Word16 *memShbSpecXcorr_e ) { Word16 idx; @@ -115,11 +113,12 @@ static Word16 ic_bwe_enc_specMapping_ivas_fx( Word16 Txx1_fx = 0, Txx2_fx = 0, Txx3_fx = 0, T_desired_fx = 0; Word16 Txx1_e = 0, Txx2_e = 0, Txx3_e = 0, T_desired_e = 0; Word16 T_nonref_target_fx, temp_fx; + Word32 temp00_fx, temp11_fx; + Word16 temp00_exp, temp11_exp; Word32 temp0_fx, temp1_fx, temp2_fx, temp3_fx; Word16 a_fx, b_fx, c_fx, a_e, b_e, c_e; Word16 u_fx, u1_fx, u2_fx, u_e = 0, u1_e, u2_e; Word16 temp0_exp, temp1_exp, temp2_exp, temp3_exp, exp, T_nonref_target_e; - Word16 exp_buf[6]; move16(); move16(); @@ -133,84 +132,71 @@ static Word16 ic_bwe_enc_specMapping_ivas_fx( /* Calculate rxx(1)/rxx(0) of the non ref target */ - temp0_fx = dotp_fixed_ivas_fx( shb_frame_target_fx, shb_frame_target_e, shb_frame_target_fx, shb_frame_target_e, L_FRAME16k - 1, &temp0_exp ); - temp1_fx = dotp_fixed_ivas_fx( shb_frame_target_fx, shb_frame_target_e, shb_frame_target_fx + 1, shb_frame_target_e, L_FRAME16k - 1, &temp1_exp ); + temp00_fx = dotp_fixed_ivas_fx( shb_frame_target_fx, shb_frame_target_e, shb_frame_target_fx, shb_frame_target_e, L_FRAME16k - 1, &temp00_exp ); /* Q31-temp0_exp */ + temp11_fx = dotp_fixed_ivas_fx( shb_frame_target_fx, shb_frame_target_e, shb_frame_target_fx + 1, shb_frame_target_e, L_FRAME16k - 1, &temp11_exp ); /* Q31-temp1_exp */ - /* Smoothing */ - temp0_fx = L_shr( temp0_fx, 1 ); - temp1_fx = L_shr( temp1_fx, 1 ); + /* Calculate rxx(1)/rxx(0) of the non ref synth */ + temp0_fx = dotp_fixed_ivas_fx( shb_synth_nonref_fx, shb_synth_nonref_e, shb_synth_nonref_fx, shb_synth_nonref_e, L_FRAME16k - 3, &temp0_exp ); /* Q31-temp0_exp */ + temp1_fx = dotp_fixed_ivas_fx( shb_synth_nonref_fx, shb_synth_nonref_e, shb_synth_nonref_fx + 1, shb_synth_nonref_e, L_FRAME16k - 3, &temp1_exp ); /* Q31-temp1_exp */ + temp2_fx = dotp_fixed_ivas_fx( shb_synth_nonref_fx, shb_synth_nonref_e, shb_synth_nonref_fx + 2, shb_synth_nonref_e, L_FRAME16k - 3, &temp2_exp ); /* Q31-temp2_exp */ + temp3_fx = dotp_fixed_ivas_fx( shb_synth_nonref_fx, shb_synth_nonref_e, shb_synth_nonref_fx + 3, shb_synth_nonref_e, L_FRAME16k - 3, &temp3_exp ); /* Q31-temp3_exp */ + exp = s_max( *memShbSpecXcorr_e, s_max( s_max( s_max( temp00_exp, temp11_exp ), s_max( temp0_exp, temp1_exp ) ), s_max( temp2_exp, temp3_exp ) ) ); - memShbSpecXcorr_fx[0] = temp0_fx; // tem0_exp - memShbSpecXcorr_fx[1] = L_shr( temp1_fx, temp0_exp - temp1_exp ); // temp0_exp - exp = sub( temp0_exp, temp1_exp ); - exp_buf[0] = exp; - exp_buf[1] = exp; - move32(); - move32(); - move16(); - move16(); + temp00_fx = L_shr( temp00_fx, sub( exp, temp00_exp ) ); + temp11_fx = L_shr( temp11_fx, sub( exp, temp11_exp ) ); + temp0_fx = L_shr( temp0_fx, sub( exp, temp0_exp ) ); + temp1_fx = L_shr( temp1_fx, sub( exp, temp1_exp ) ); + temp2_fx = L_shr( temp2_fx, sub( exp, temp2_exp ) ); + temp3_fx = L_shr( temp3_fx, sub( exp, temp3_exp ) ); - IF( temp0_fx != 0 ) - { - T_nonref_target_fx = BASOP_Util_Divide3232_Scale( temp1_fx, temp0_fx, &T_nonref_target_e ); // exp - } - ELSE + /* Smoothing */ + + FOR( Word16 i = 0; i < 6; i++ ) { - T_nonref_target_fx = 0; - T_nonref_target_e = 31; + memShbSpecXcorr_fx[i] = L_shl( memShbSpecXcorr_fx[i], sub( *memShbSpecXcorr_e, exp ) ); move32(); - move16(); } + *memShbSpecXcorr_e = exp; + move16(); - /* Calculate rxx(1)/rxx(0) of the non ref synth */ - temp0_fx = dotp_fixed_ivas_fx( shb_synth_nonref_fx, shb_synth_nonref_e, shb_synth_nonref_fx, shb_synth_nonref_e, L_FRAME16k - 3, &temp0_exp ); - temp1_fx = dotp_fixed_ivas_fx( shb_synth_nonref_fx, shb_synth_nonref_e, shb_synth_nonref_fx + 1, shb_synth_nonref_e, L_FRAME16k - 3, &temp1_exp ); - temp2_fx = dotp_fixed_ivas_fx( shb_synth_nonref_fx, shb_synth_nonref_e, shb_synth_nonref_fx + 2, shb_synth_nonref_e, L_FRAME16k - 3, &temp2_exp ); - temp3_fx = dotp_fixed_ivas_fx( shb_synth_nonref_fx, shb_synth_nonref_e, shb_synth_nonref_fx + 3, shb_synth_nonref_e, L_FRAME16k - 3, &temp3_exp ); + temp00_fx = L_add( L_shr( temp00_fx, 1 ), L_shr( memShbSpecXcorr_fx[0], 1 ) ); + temp11_fx = L_add( L_shr( temp11_fx, 1 ), L_shr( memShbSpecXcorr_fx[1], 1 ) ); + temp0_fx = L_add( L_shr( temp0_fx, 1 ), L_shr( memShbSpecXcorr_fx[2], 1 ) ); + temp1_fx = L_add( L_shr( temp1_fx, 1 ), L_shr( memShbSpecXcorr_fx[3], 1 ) ); + temp2_fx = L_add( L_shr( temp2_fx, 1 ), L_shr( memShbSpecXcorr_fx[4], 1 ) ); + temp3_fx = L_add( L_shr( temp3_fx, 1 ), L_shr( memShbSpecXcorr_fx[5], 1 ) ); - /* Smoothing */ - temp0_fx = L_shr( temp0_fx, 1 ); - temp1_fx = L_shr( temp1_fx, 1 ); - temp2_fx = L_shr( temp2_fx, 1 ); - temp3_fx = L_shr( temp3_fx, 1 ); - - exp_buf[2] = temp0_exp; - exp_buf[3] = temp1_exp; - exp_buf[4] = temp2_exp; - exp_buf[5] = temp3_exp; - exp = exp_buf[0]; - move16(); - move16(); - move16(); - move16(); + T_nonref_target_fx = 0; + move32(); + T_nonref_target_e = 31; move16(); - FOR( Word16 i = 0; i < 6; i++ ) + + IF( temp00_fx != 0 ) { - IF( LT_16( exp, exp_buf[i] ) ) - { - exp = exp_buf[i]; - move16(); - } + T_nonref_target_fx = BASOP_Util_Divide3232_Scale( temp11_fx, temp00_fx, &T_nonref_target_e ); } - memShbSpecXcorr_fx[2] = L_shr( temp0_fx, sub( exp, temp0_exp ) ); - memShbSpecXcorr_fx[3] = L_shr( temp1_fx, sub( exp, temp1_exp ) ); - memShbSpecXcorr_fx[4] = L_shr( temp2_fx, sub( exp, temp2_exp ) ); - memShbSpecXcorr_fx[5] = L_shr( temp3_fx, sub( exp, temp3_exp ) ); - *memShbSpecXcorr_e = exp; + + memShbSpecXcorr_fx[0] = temp00_fx; move32(); + memShbSpecXcorr_fx[1] = temp11_fx; move32(); + memShbSpecXcorr_fx[2] = temp0_fx; /* Q31-exp */ move32(); + memShbSpecXcorr_fx[3] = temp1_fx; /* Q31-exp */ + move32(); + memShbSpecXcorr_fx[4] = temp2_fx; /* Q31-exp */ + move32(); + memShbSpecXcorr_fx[5] = temp3_fx; /* Q31-exp */ move32(); - move16(); IF( temp0_fx != 0 ) { - Txx1_fx = BASOP_Util_Divide3232_Scale( temp1_fx, temp0_fx, &Txx1_e ); - Txx2_fx = BASOP_Util_Divide3232_Scale( temp2_fx, temp0_fx, &Txx2_e ); - Txx3_fx = BASOP_Util_Divide3232_Scale( temp3_fx, temp0_fx, &Txx3_e ); + Txx1_fx = BASOP_Util_Divide3232_Scale( temp1_fx, temp0_fx, &Txx1_e ); /* Q31-Txx1_e */ + Txx2_fx = BASOP_Util_Divide3232_Scale( temp2_fx, temp0_fx, &Txx2_e ); /* Q31-Txx1_e */ + Txx3_fx = BASOP_Util_Divide3232_Scale( temp3_fx, temp0_fx, &Txx3_e ); /* Q31-Txx1_e */ } T_desired_fx = T_nonref_target_fx; @@ -219,32 +205,35 @@ static Word16 ic_bwe_enc_specMapping_ivas_fx( move16(); Word16 tmp, tmp1; - exp = BASOP_Util_Add_MantExp( Txx3_fx, Txx3_e, Txx1_fx, Txx1_e, &tmp ); - tmp1 = mult( Txx2_fx, T_desired_fx ); // Txx2_e + T_desired_e - a_e = BASOP_Util_Add_MantExp( tmp1, sub( add( Txx2_e, T_desired_e ), 1 ), negate( tmp ), exp, &a_fx ); + exp = BASOP_Util_Add_MantExp( Txx3_fx, Txx3_e, Txx1_fx, Txx1_e, &tmp ); /* Q15-exp */ + tmp1 = mult( Txx2_fx, T_desired_fx ); // Txx2_e + T_desired_e + a_e = BASOP_Util_Add_MantExp( tmp1, sub( add( Txx2_e, T_desired_e ), 1 ), negate( tmp ), exp, &a_fx ); /* Q15-a_e */ - exp = BASOP_Util_Add_MantExp( Txx2_fx, Txx2_e, 32767, 1, &tmp ); - tmp1 = mult( Txx1_fx, T_desired_fx ); // Txx1_e + T_desired_e - b_e = BASOP_Util_Add_MantExp( tmp1, sub( add( Txx1_e, T_desired_e ), 1 ), negate( tmp ), exp, &b_fx ); + exp = BASOP_Util_Add_MantExp( Txx2_fx, Txx2_e, 32767, 1, &tmp ); /* Q15-exp */ + tmp1 = mult( Txx1_fx, T_desired_fx ); // Txx1_e + T_desired_e + b_e = BASOP_Util_Add_MantExp( tmp1, sub( add( Txx1_e, T_desired_e ), 1 ), negate( tmp ), exp, &b_fx ); /* Q15-b_fx */ - c_e = BASOP_Util_Add_MantExp( T_desired_fx, T_desired_e, negate( Txx1_fx ), Txx1_e, &c_fx ); + c_e = BASOP_Util_Add_MantExp( T_desired_fx, T_desired_e, negate( Txx1_fx ), Txx1_e, &c_fx ); /* Q15-c_fx */ u_fx = extract_l( *specMapping_fx ); - tmp = mult( b_fx, b_fx ); // b_e + b_e; - tmp1 = mult( a_fx, c_fx ); // a_e + c_e + 2 - exp = BASOP_Util_Add_MantExp( tmp, add( b_e, b_e ), tmp1, add( a_e, add( c_e, 2 ) ), &temp_fx ); + /* while performing (-32768)*(-32768), overflow occurs because the result comes out as 32768 after mult. This is the only case for mult where overflow happens. In order to avoid this scenario mult_sat is used */ + + tmp = mult_sat( b_fx, b_fx ); // b_e + b_e; + tmp1 = mult_sat( a_fx, c_fx ); // a_e + c_e + 2 + + exp = BASOP_Util_Add_MantExp( tmp, add( b_e, b_e ), tmp1, add( a_e, add( c_e, 2 ) ), &temp_fx ); /* Q15-exp */ test(); IF( temp_fx >= 0 && a_fx != 0 ) { - temp_fx = Sqrt16( temp_fx, &exp ); - exp = BASOP_Util_Add_MantExp( negate( b_fx ), b_e, temp_fx, exp, &tmp ); - u1_e = BASOP_Util_Divide1616_Scale( tmp, a_fx, &u1_fx ); + temp_fx = Sqrt16( temp_fx, &exp ); /* Q15-exp */ + exp = BASOP_Util_Add_MantExp( negate( b_fx ), b_e, temp_fx, exp, &tmp ); /* Q15-exp */ + u1_e = BASOP_Util_Divide1616_Scale( tmp, a_fx, &u1_fx ); /* Q15-u1_e */ u1_e = add( u1_e, sub( exp, add( a_e, 1 ) ) ); - exp = BASOP_Util_Add_MantExp( negate( b_fx ), b_e, negate( temp_fx ), exp, &tmp ); - u2_e = BASOP_Util_Divide1616_Scale( tmp, a_fx, &u2_fx ); + exp = BASOP_Util_Add_MantExp( negate( b_fx ), b_e, negate( temp_fx ), exp, &tmp ); /* Q15-exp */ + u2_e = BASOP_Util_Divide1616_Scale( tmp, a_fx, &u2_fx ); /* Q15-u2_e */ u2_e = add( u2_e, sub( exp, add( a_e, 1 ) ) ); test(); @@ -298,7 +287,7 @@ static Word16 ic_bwe_enc_specMapping_ivas_fx( /* Quantize spec. mapping **/ Word16 specMapping16; - idx = usquant_fx( shr( u_fx, sub( 0, u_e ) ), &specMapping16, -19660, 6553, 1 << STEREO_ICBWE_SPBITS ); // -0.6 in in Q15 -> -19660, 0.2 in Q15 -> 6553 + idx = usquant_fx( shr( u_fx, sub( 0, u_e ) ), &specMapping16, -19660, 6553 >> 1, ( 1 << STEREO_ICBWE_SPBITS ) ); // -0.6 in in Q15 -> -19660, 0.2 in Q15 -> 6553 *specMapping_fx = L_deposit_h( specMapping16 ); move32(); @@ -324,17 +313,17 @@ static Word16 ic_bwe_enc_specMapping_ivas_fx( /*! r: return quant. index value */ static Word16 ic_bwe_enc_gsMapping_ivas_fx( - const Word32 relG_targ_fx, /* i : gDes, rel gain target */ + const Word32 relG_targ_fx, /* i : gDes, rel gain target Q31-relG_targ_e*/ Word16 relG_targ_e, - const Word16 *shbSynth_fx, /* i : ref synth signal */ + const Word16 *shbSynth_fx, /* i : ref synth signal Q15-shbSynth_e*/ Word16 shbSynth_e, /* i : ref synth signal */ - Word32 *synthSHB_nonref_fx, /* i : nonref synth signal */ + Word32 *synthSHB_nonref_fx, /* i : nonref synth signal Q31-synthSHB_nonref_e*/ Word16 *synthSHB_nonref_e, /* i : nonref synth signal */ - Word32 *gsMapping_fx, /* i/o: gs mapping */ + Word32 *gsMapping_fx, /* i/o: gs mapping Q31-gsMapping_e*/ Word16 *gsMapping_e, /* i/o: gs mapping */ - Word32 *memEner_fx, /* */ + Word32 *memEner_fx, /* Q31-memEner_e*/ Word16 *memEner_e, - const Word16 element_mode /* i : element mode */ + const Word16 element_mode /* i : element mode Q0*/ ) { Word16 i; @@ -355,19 +344,17 @@ static Word16 ic_bwe_enc_gsMapping_ivas_fx( move16(); FOR( i = 0; i < L_FRAME16k; i++ ) { - temp1_fx32 = BASOP_Util_Add_Mant32Exp( temp1_fx32, temp1_exp, L_abs( L_deposit_h( shbSynth_fx[i] ) ), exp1, &temp1_exp ); - temp2_fx32 = BASOP_Util_Add_Mant32Exp( temp2_fx32, temp2_exp, L_abs( synthSHB_nonref_fx[i] ), exp2, &temp2_exp ); + temp1_fx32 = BASOP_Util_Add_Mant32Exp( temp1_fx32, temp1_exp, L_abs( L_deposit_h( shbSynth_fx[i] ) ), exp1, &temp1_exp ); /* Q31-temp1_exp */ + temp2_fx32 = BASOP_Util_Add_Mant32Exp( temp2_fx32, temp2_exp, L_abs( synthSHB_nonref_fx[i] ), exp2, &temp2_exp ); /* Q31-temp2_exp */ } - - memEner_fx[0] = temp1_fx32; - memEner_fx[1] = L_shr( temp2_fx32, abs_s( sub( temp1_exp, temp2_exp ) ) ); + memEner_fx[0] = L_shr( temp1_fx32, sub( s_max( temp1_exp, temp2_exp ), temp1_exp ) ); + memEner_fx[1] = L_shr( temp2_fx32, sub( s_max( temp1_exp, temp2_exp ), temp2_exp ) ); move32(); move32(); *memEner_e = s_max( temp1_exp, temp2_exp ); move16(); - IF( temp2_fx32 == 0 ) { *gsMapping_fx = *gsMapping_fx; @@ -376,7 +363,7 @@ static Word16 ic_bwe_enc_gsMapping_ivas_fx( ELSE { L_mult = Mpy_32_32( relG_targ_fx, temp1_fx32 ); // relG_targ_e + temp1_e - temp1 = BASOP_Util_Divide3232_Scale( L_mult, temp1_fx32, &exp ); // exp = exp - ( relG_targ_e + temp1_e + temp2_e ) + temp1 = BASOP_Util_Divide3232_Scale( L_mult, temp2_fx32, &exp ); // exp = exp - ( relG_targ_e + temp1_e - temp2_e ) exp = add( exp, sub( add( relG_targ_e, temp1_exp ), temp2_exp ) ); *gsMapping_fx = L_deposit_h( temp1 ); // exp move32(); @@ -386,24 +373,45 @@ static Word16 ic_bwe_enc_gsMapping_ivas_fx( /* quantize the IC-BWE GS mapping*/ IF( EQ_16( element_mode, IVAS_CPE_TD ) ) { - temp2_fx = extract_l( L_shr( temp2_fx32, Q10 ) ); // Q15 + IF( LT_32( temp2_fx32, -( 2 << 25 ) ) ) + { + temp2_fx = -( 2 << 12 ); // Q12 + move16(); + } + ELSE IF( GT_32( temp2_fx32, 1 << 25 ) ) + { + temp2_fx = 1 << 12; // Q12 + move16(); + } + + temp2_fx = extract_h( L_shl_sat( temp2_fx32, Q3 ) ); // Q12 gsMapping_fx16 = 0; move16(); - idx = squant_fx( temp2_fx, &gsMapping_fx16, icbwe_gsMapping_tbl_fx, 1 << STEREO_ICBWE_GSBITS ); // Q12 - // idx = squant_fx( temp2, gsMapping, icbwe_gsMapping_tbl_fx, 1 << STEREO_ICBWE_GSBITS ); + idx = squant_fx( temp2_fx, &gsMapping_fx16, icbwe_gsMapping_tbl_fx, ( 1 << STEREO_ICBWE_GSBITS ) ); // Q12 } ELSE { - temp2_fx = extract_l( L_shr( temp2_fx32, Q10 ) ); // Q15 + IF( LT_32( temp2_fx32, -( 5 << 25 ) ) ) + { + temp2_fx = -( 5 << 12 ); // Q12 + move16(); + } + ELSE IF( GT_32( temp2_fx32, 1 << 25 ) ) + { + temp2_fx = 1 << 12; // Q12 + move16(); + } + + temp2_fx = extract_h( L_shl_sat( temp2_fx32, Q3 ) ); // Q12 gsMapping_fx16 = 0; move16(); - idx = squant_fx( temp2_fx, &gsMapping_fx16, icbwe_gsMappingDFT_tbl_fx, 1 << STEREO_ICBWE_GSBITS ); // Q12 + idx = squant_fx( temp2_fx, &gsMapping_fx16, icbwe_gsMappingDFT_tbl_fx, ( 1 << STEREO_ICBWE_GSBITS_DFT ) ); // Q12 } *gsMapping_fx = L_deposit_h( gsMapping_fx16 ); // Q28 move32(); Word16 e; - L_mult = Mult_32_16( *gsMapping_fx, 27213 /*=log2(10)*2^13*/ ); // Q27 + Q13 - Q15 -> Q26 - *gsMapping_fx = BASOP_util_Pow2( L_mult, 5, &e ); + L_mult = Mult_32_16( *gsMapping_fx, 27213 /*=log2(10)*2^13*/ ); // Q28 + Q13 - Q15 -> Q26 + *gsMapping_fx = BASOP_util_Pow2( L_mult, 5, &e ); /* Q31-e */ move32(); *gsMapping_e = e; // Q31 @@ -420,7 +428,7 @@ static void icbwe_dft_stereo_param_ivas_fx( STEREO_ICBWE_ENC_HANDLE hStereoICBWE, /* i/o: */ STEREO_DFT_ENC_DATA_HANDLE hStereoDft, /* i : */ Encoder_State *st, /* i/o: */ - Word32 *shb_synth_nonref_fx, /* i/o: */ + Word32 *shb_synth_nonref_fx, /* i/o: Q31-shb_synth_nonref_e*/ Word16 shb_synth_nonref_e /* i/o: */ ) { @@ -441,30 +449,32 @@ static void icbwe_dft_stereo_param_ivas_fx( nrg_R_fx = hStereoDft->nrg_R_fx; nrg_DMX_fx = hStereoDft->nrg_DMX_fx; - - hStereoICBWE->mem_nrg_L_fx[0] = nrg_L_fx[0]; // hStereoICBWE->nrg_L_fx_e[0] - hStereoICBWE->mem_nrg_R_fx[0] = nrg_R_fx[0]; // hStereoICBWE->nrg_R_fx_e[0] - hStereoICBWE->mem_nrg_DMX_fx[0] = nrg_DMX_fx[0]; // hStereoICBWE->nrg_DMX_fx_e[0] - hStereoICBWE->mem_nrg_L_fx[1] = L_shr( nrg_L_fx[1], abs_s( sub( hStereoDft->nrg_L_fx_e[0], hStereoDft->nrg_L_fx_e[1] ) ) ); // hStereoICBWE->nrg_L_fx_e[1] - hStereoICBWE->mem_nrg_R_fx[1] = L_shr( nrg_R_fx[1], abs_s( sub( hStereoDft->nrg_R_fx_e[0], hStereoDft->nrg_R_fx_e[1] ) ) ); // hStereoICBWE-> nrg_R_fx_e[1] - hStereoICBWE->mem_nrg_DMX_fx[1] = L_shr( nrg_DMX_fx[1], abs_s( sub( hStereoDft->nrg_DMX_fx_e[0], hStereoDft->nrg_DMX_fx_e[1] ) ) ); // hStereoICBWE->nrg_DMX_fx_e[1] - move32(); - move32(); - move32(); - move32(); - move32(); - move32(); hStereoICBWE->mem_nrg_L_fx_e = s_max( hStereoDft->nrg_L_fx_e[0], hStereoDft->nrg_L_fx_e[1] ); hStereoICBWE->mem_nrg_R_fx_e = s_max( hStereoDft->nrg_R_fx_e[0], hStereoDft->nrg_R_fx_e[1] ); hStereoICBWE->mem_nrg_DMX_fx_e = s_max( hStereoDft->nrg_DMX_fx_e[0], hStereoDft->nrg_DMX_fx_e[1] ); move16(); move16(); move16(); + hStereoICBWE->mem_nrg_L_fx[0] = L_shr( nrg_L_fx[0], sub( hStereoICBWE->mem_nrg_L_fx_e, hStereoDft->nrg_L_fx_e[0] ) ); + hStereoICBWE->mem_nrg_R_fx[0] = L_shr( nrg_R_fx[0], sub( hStereoICBWE->mem_nrg_R_fx_e, hStereoDft->nrg_R_fx_e[0] ) ); + hStereoICBWE->mem_nrg_DMX_fx[0] = L_shr( nrg_DMX_fx[0], sub( hStereoICBWE->mem_nrg_DMX_fx_e, hStereoDft->nrg_DMX_fx_e[0] ) ); + hStereoICBWE->mem_nrg_L_fx[1] = L_shr( nrg_L_fx[1], sub( hStereoICBWE->mem_nrg_L_fx_e, hStereoDft->nrg_L_fx_e[1] ) ); + hStereoICBWE->mem_nrg_R_fx[1] = L_shr( nrg_R_fx[1], sub( hStereoICBWE->mem_nrg_R_fx_e, hStereoDft->nrg_R_fx_e[1] ) ); + hStereoICBWE->mem_nrg_DMX_fx[1] = L_shr( nrg_DMX_fx[1], sub( hStereoICBWE->mem_nrg_DMX_fx_e, hStereoDft->nrg_DMX_fx_e[1] ) ); + move32(); + move32(); + move32(); + move32(); + move32(); + move32(); Word16 sum_nrg_L_e = hStereoICBWE->mem_nrg_L_fx_e, sum_nrg_R_e = hStereoICBWE->mem_nrg_R_fx_e, sum_nrg_DMX_e = hStereoICBWE->mem_nrg_DMX_fx_e; sum_nrg_L_fx = sum_32_fx( hStereoICBWE->mem_nrg_L_fx, 2, &sum_nrg_L_e ); // hStereoICBWE->mem_nrg_L_fx_e sum_nrg_R_fx = sum_32_fx( hStereoICBWE->mem_nrg_R_fx, 2, &sum_nrg_R_e ); // hStereoICBWE->mem_nrg_R_fx_e sum_nrg_DMX_fx = sum_32_fx( hStereoICBWE->mem_nrg_DMX_fx, 2, &sum_nrg_DMX_e ); // hStereoICBWE->mem_nrg_DMX_fx_e + move16(); + move16(); + move16(); /* refChanIndex_bwe refinement */ @@ -487,7 +497,7 @@ static void icbwe_dft_stereo_param_ivas_fx( slopeILD_fx = 0; move32(); - spIndx = squant_fx( slopeILD_fx, &slopeILD_fx, slope_table_fx16, 1 << STEREO_ICBWE_SPBITS_DFT ); + spIndx = squant_fx( slopeILD_fx, &slopeILD_fx, slope_table_fx16, 1 << STEREO_ICBWE_SPBITS_DFT ); /* Q0 */ test(); test(); @@ -499,34 +509,33 @@ static void icbwe_dft_stereo_param_ivas_fx( Word32 L_tmp, L_tmp1; L_tmp = Mpy_32_32( hStereoICBWE->mem_nrg_L_fx[1], hStereoICBWE->mem_nrg_R_fx[0] ); // hStereoICBWE->mem_nrg_L_fx_e[1] + hStereoICBWE->mem_nrg_R_fx_e[1] L_tmp1 = Mpy_32_32( hStereoICBWE->mem_nrg_R_fx[1], hStereoICBWE->mem_nrg_L_fx[0] ); // hStereoICBWE->mem_nrg_L_fx_e[1] + hStereoICBWE->mem_nrg_R_fx_e[1] - tmp1 = BASOP_Util_Divide3232_Scale( L_tmp, L_tmp1, &exp1 ); + tmp1 = BASOP_Util_Divide3232_Scale( L_tmp, L_tmp1, &exp1 ); /* Q15-exp1 */ exp1 = add( exp1, sub( add( hStereoICBWE->mem_nrg_L_fx_e, hStereoICBWE->mem_nrg_R_fx_e ), add( hStereoICBWE->mem_nrg_L_fx_e, hStereoICBWE->mem_nrg_R_fx_e ) ) ); L_tmp = BASOP_Util_Log10( L_deposit_h( tmp1 ), exp1 ); L_tmp = Mpy_32_32( normFac_fx, L_tmp ); // // Q25 + Q29 - Q31 -> Q23 slopeILD_fx = extract_l( L_shr( L_tmp, 16 ) ); // Q23 - Q16 -> Q7 IF( hStereoICBWE->refChanIndx_bwe == L_CH_INDX ) { - slopeILD_fx = negate( slopeILD_fx ); - } - ELSE - { - slopeILD_fx = slopeILD_fx; - move16(); + slopeILD_fx = negate( slopeILD_fx ); /* Q7 */ } spIndx = squant_fx( slopeILD_fx, &slopeILD_fx, slope_table_fx16, 1 << STEREO_ICBWE_SPBITS_DFT ); IF( Mpy_32_32( spec_table_fx[spIndx], hStereoICBWE->prevSpecMapping_fx ) < 0 ) { slopeILD_fx = 0; move32(); - spIndx = squant_fx( slopeILD_fx, &slopeILD_fx, slope_table_fx16, 1 << STEREO_ICBWE_SPBITS_DFT ); + spIndx = squant_fx( slopeILD_fx, &slopeILD_fx, slope_table_fx16, 1 << STEREO_ICBWE_SPBITS_DFT ); /* Q0 */ } hStereoICBWE->prevSpecMapping_fx = spec_table_fx[spIndx]; // q31 /* ic bwe spec mapping application */ deemph_fx_32( 0, shb_synth_nonref_fx, extract_l( L_shr( hStereoICBWE->prevSpecMapping_fx, 16 ) ), L_FRAME16k, &hStereoICBWE->memShbSpecMapping_fx ); // shb_synth_nonref_e + hStereoICBWE->memShbSpecMapping_e = shb_synth_nonref_e; + move16(); } ELSE { + hStereoICBWE->memShbSpecMapping_e = 0; + move16(); hStereoICBWE->memShbSpecMapping_fx = 0; hStereoICBWE->prevSpecMapping_fx = 0; move32(); @@ -538,16 +547,16 @@ static void icbwe_dft_stereo_param_ivas_fx( Word16 exp; IF( hStereoICBWE->refChanIndx_bwe == L_CH_INDX ) { - gDes_fx = BASOP_Util_Divide3232_Scale( sum_nrg_R_fx, sum_nrg_DMX_fx, &exp ); + gDes_fx = BASOP_Util_Divide3232_Scale( sum_nrg_R_fx, sum_nrg_DMX_fx, &exp ); /* Q15-exp */ exp = add( exp, sub( sum_nrg_R_e, sum_nrg_DMX_e ) ); } ELSE { - gDes_fx = BASOP_Util_Divide3232_Scale( sum_nrg_L_fx, sum_nrg_DMX_fx, &exp ); + gDes_fx = BASOP_Util_Divide3232_Scale( sum_nrg_L_fx, sum_nrg_DMX_fx, &exp ); /* Q15-exp */ exp = add( exp, sub( sum_nrg_L_e, sum_nrg_DMX_e ) ); } - gDes_fx = Sqrt16( gDes_fx, &exp ); + gDes_fx = Sqrt16( gDes_fx, &exp ); /* Q15-exp */ Word16 exp1 = hStereoICBWE->gDes_pastFrame_e, exp2, tmp; Word32 tmp321 = 0, tmp322 = 0; move32(); @@ -556,16 +565,16 @@ static void icbwe_dft_stereo_param_ivas_fx( tmp321 = Sqrt32( hStereoICBWE->gDes_pastFrame_fx, &exp1 ); // exp1 exp2 = exp; move16(); - tmp = Sqrt16( gDes_fx, &exp2 ); + tmp = Sqrt16( gDes_fx, &exp2 ); /* Q15-exp2 */ tmp322 = Mpy_32_32( tmp321, L_deposit_h( tmp ) ); // exp1 + exp2 hStereoICBWE->gDes_pastFrame_fx = tmp322; hStereoICBWE->gDes_pastFrame_e = add( exp1, exp2 ); move32(); move16(); - gsIndx = ic_bwe_enc_gsMapping_ivas_fx( hStereoICBWE->gDes_pastFrame_fx, hStereoICBWE->gDes_pastFrame_e, hStereoICBWE->shbSynthRef_fx, hStereoICBWE->shbSynthRef_e, shb_synth_nonref_fx, &shb_synth_nonref_e, &( hStereoICBWE->prevgsMapping_fx ), &( hStereoICBWE->prevgsMapping_e ), hStereoICBWE->memGsEnerMap_fx, &hStereoICBWE->memGsEnerMap_e, st->element_mode ); + gsIndx = ic_bwe_enc_gsMapping_ivas_fx( hStereoICBWE->gDes_pastFrame_fx, hStereoICBWE->gDes_pastFrame_e, hStereoICBWE->shbSynthRef_fx, hStereoICBWE->shbSynthRef_e, shb_synth_nonref_fx, &shb_synth_nonref_e, &( hStereoICBWE->prevgsMapping_fx ), &( hStereoICBWE->prevgsMapping_e ), hStereoICBWE->memGsEnerMap_fx, &hStereoICBWE->memGsEnerMap_e, st->element_mode ); /* Q0 */ - hStereoICBWE->gDes_pastFrame_fx = L_deposit_h( gDes_fx ); + hStereoICBWE->gDes_pastFrame_fx = L_deposit_h( gDes_fx ); /* Q31-exp */ hStereoICBWE->gDes_pastFrame_e = exp; move32(); move16(); @@ -584,9 +593,9 @@ static void icbwe_dft_stereo_param_ivas_fx( void stereo_icBWE_enc_ivas_fx( CPE_ENC_HANDLE hCPE, /* i/o: CPE encoder structure */ - const Word32 shb_speech_ref_fx[], /* i : SHB speech ref channel */ + const Word32 shb_speech_ref_fx[], /* i : SHB speech ref channel Q31-shb_speech_ref_e*/ const Word16 shb_speech_ref_e, /* i : SHB speech ref channel */ - Word32 shb_speech_nonref_fx[], /* i/o: SHB speech non-ref channel */ + Word32 shb_speech_nonref_fx[], /* i/o: SHB speech non-ref channel Q31-shb_speech_nonref_e*/ Word16 shb_speech_nonref_e, /* i/o: SHB speech non-ref channel */ const Word32 *voice_factors_fx /* i : voicing factors Q31 */ ) @@ -678,7 +687,8 @@ void stereo_icBWE_enc_ivas_fx( Copy_Scale_sig( hStereoICBWE->mem_shb_speech_ref_fx, hStereoICBWE->mem_shb_speech_ref_fx, L_LOOK_16k, negate( sub( max_e, hStereoICBWE->mem_shb_speech_ref_e ) ) ); // mem_shb_speech_ref_e set32_fx( shb_frame_ref_fx, 0, L_LOOK_16k + L_FRAME16k ); - Copy_Scale_sig_16_32( hStereoICBWE->mem_shb_speech_ref_fx, shb_frame_ref_fx, L_LOOK_16k, negate( sub( max_e, hStereoICBWE->mem_shb_speech_ref_e ) ) + Q16 ); // mem_shb_speech_ref_e + Copy_Scale_sig_16_32_DEPREC( hStereoICBWE->mem_shb_speech_ref_fx, shb_frame_ref_fx, L_LOOK_16k, 0 ); // Q = 15 - mem_shb_speech_ref_e + scale_sig32( shb_frame_ref_fx, L_LOOK_16k, add( negate( sub( max_e, hStereoICBWE->mem_shb_speech_ref_e ) ), Q16 ) ); // Q = 31 - mem_shb_speech_ref_e hStereoICBWE->mem_shb_speech_ref_e = max_e; shb_frame_ref_e = max_e; @@ -689,9 +699,10 @@ void stereo_icBWE_enc_ivas_fx( shb_synth_nonref_e = max_e; move16(); - Copy_Scale_sig32( shb_speech_ref_fx, shb_frame_ref_fx + L_LOOK_16k - refMemLen, L_FRAME16k, negate( sub( max_e, shb_speech_ref_e ) ) ); + Copy_Scale_sig32( shb_speech_ref_fx, shb_frame_ref_fx + L_LOOK_16k - refMemLen, L_FRAME16k, negate( sub( max_e, shb_speech_ref_e ) ) ); /* shb_speech_ref_e */ Copy_Scale_sig_32_16( shb_frame_ref_fx + L_FRAME16k, hStereoICBWE->mem_shb_speech_ref_fx, L_LOOK_16k, negate( sub( max_e, hStereoICBWE->mem_shb_speech_ref_e ) ) - Q16 ); // mem_shb_speech_ref_e + test(); test(); IF( ( EQ_16( st->extl, SWB_TBE ) || EQ_16( st->extl, FB_TBE ) ) && EQ_16( st->flag_ACELP16k, 1 ) ) @@ -704,6 +715,8 @@ void stereo_icBWE_enc_ivas_fx( v_multc_fixed( voice_factors_fx, 1073741824, nlMixFac_fx, NB_SUBFR16k ); // Q31, 0.5 in Q31 -> 1073741824 } + Word16 L_FRAME16k_by_nbSubFr = L_FRAME16k / NB_SUBFR; + move16(); IF( st->flag_ACELP16k == 0 ) { nbSubFr = NB_SUBFR; @@ -713,6 +726,8 @@ void stereo_icBWE_enc_ivas_fx( { nbSubFr = NB_SUBFR16k; move16(); + L_FRAME16k_by_nbSubFr = L_FRAME16k / NB_SUBFR16k; + move16(); } Word16 exp_buf[L_FRAME16k]; @@ -724,7 +739,7 @@ void stereo_icBWE_enc_ivas_fx( { temp1_fx = 0; temp1_e = 0; - temp2_fx = ONE_IN_Q31; + temp2_fx = ONE_IN_Q31; /* Q31 */ temp2_e = 0; move16(); move32(); @@ -735,16 +750,14 @@ void stereo_icBWE_enc_ivas_fx( { temp1_e = 0, temp2_e = 0; move16(); - move32(); + move16(); temp1_fx = Sqrt32( nlMixFac_fx[i], &temp1_e ); - temp2_fx = Sqrt32( L_sub( ONE_IN_Q31, nlMixFac_fx[i] ), &temp2_e ); + temp2_fx = Sqrt32( L_sub( ONE_IN_Q31, nlMixFac_fx[i] ), &temp2_e ); /* Q31-temp2_e */ } - tmp = BASOP_Util_Divide1616_Scale( L_FRAME16k, nbSubFr, &exp ); - tmp = shr( tmp, sub( Q15, exp ) ); - FOR( j = 0; j < tmp; ( j++, k++ ) ) + FOR( j = 0; j < L_FRAME16k_by_nbSubFr; ( j++, k++ ) ) { - excSHB_nonref_fx[k] = extract_l( BASOP_Util_Add_Mant32Exp( Mpy_32_32( temp1_fx, hStereoICBWE->nlExc16k_fx[k] ), add( temp1_e, hStereoICBWE->nlExc16k_e ), Mpy_32_32( temp2_fx, hStereoICBWE->mixExc16k_fx[k] ), add( temp2_e, hStereoICBWE->mixExc16k_e ), &exp_buf[k] ) ); + excSHB_nonref_fx[k] = BASOP_Util_Add_Mant32Exp( Mpy_32_32( temp1_fx, L_deposit_h( hStereoICBWE->nlExc16k_fx[k] ) ), add( temp1_e, hStereoICBWE->nlExc16k_e ), Mpy_32_32( temp2_fx, L_deposit_h( hStereoICBWE->mixExc16k_fx[k] ) ), add( temp2_e, hStereoICBWE->mixExc16k_e ), &exp_buf[k] ); /* Q31-exp_buf */ move32(); } } @@ -762,38 +775,32 @@ void stereo_icBWE_enc_ivas_fx( FOR( j = 0; j < L_FRAME16k; j++ ) { - excSHB_nonref_fx[j] = L_shr( excSHB_nonref_fx[j], sub( max_e, exp_buf[j] ) ); + excSHB_nonref_fx[j] = L_shr( excSHB_nonref_fx[j], sub( max_e, exp_buf[j] ) ); /* Q31-max_e */ move32(); } /* LP synthesis */ - Word16 tmp_e = s_max( hCPE->hStereoICBWE->lpSHBRef_e, max_e ); - Word32 lpSHBRef_fx32[LPC_SHB_ORDER + 1]; + Copy_Scale_sig32( hStereoICBWE->mem_lpc_shbsynth_nonref_fx, hStereoICBWE->mem_lpc_shbsynth_nonref_fx, LPC_SHB_ORDER, sub( hStereoICBWE->mem_lpc_shbsynth_nonref_e, s_max( hStereoICBWE->mem_lpc_shbsynth_nonref_e, max_e ) ) ); /* Q31-tmp_e */ + Copy_Scale_sig32( excSHB_nonref_fx, excSHB_nonref_fx, L_FRAME16k, sub( max_e, s_max( hStereoICBWE->mem_lpc_shbsynth_nonref_e, max_e ) ) ); /* Q31-tmp_e */ + max_e = s_max( hStereoICBWE->mem_lpc_shbsynth_nonref_e, max_e ); + hStereoICBWE->mem_lpc_shbsynth_nonref_e = s_max( hStereoICBWE->mem_lpc_shbsynth_nonref_e, max_e ); - Copy_Scale_sig32( hCPE->hStereoICBWE->lpSHBRef_fx, lpSHBRef_fx32, LPC_SHB_ORDER + 1, negate( sub( tmp_e, hCPE->hStereoICBWE->lpSHBRef_e ) ) ); - Copy_Scale_sig32( excSHB_nonref_fx, excSHB_nonref_fx, L_FRAME16k, negate( sub( tmp_e, max_e ) ) ); - // set32_fx( hStereoICBWE->mem_lpc_shbsynth_nonref_fx, 0, LPC_SHB_ORDER ); - E_UTIL_synthesis_fx( 0, lpSHBRef_fx32, excSHB_nonref_fx, shb_synth_nonref_fx, L_FRAME16k, hStereoICBWE->mem_lpc_shbsynth_nonref_fx, 1, LPC_SHB_ORDER ); - - shb_synth_nonref_e = tmp_e; - hStereoICBWE->mem_lpc_shbsynth_nonref_e = tmp_e; - move16(); - move16(); + syn_filt_fx32( hStereoICBWE->lpSHBRef_e, hStereoICBWE->lpSHBRef_fx, LPC_SHB_ORDER, excSHB_nonref_fx, max_e, shb_synth_nonref_fx, &shb_synth_nonref_e, L_FRAME16k, hStereoICBWE->mem_lpc_shbsynth_nonref_fx, &hStereoICBWE->mem_lpc_shbsynth_nonref_e, 1 ); } ELSE { - Copy_Scale_sig_32_16( shb_frame_ref_fx, hStereoICBWE->shbSynthRef_fx, L_FRAME16k, -16 ); // max_e + Copy_Scale_sig_32_16( shb_frame_ref_fx, hStereoICBWE->shbSynthRef_fx, L_FRAME16k, -16 ); /* Q15-shb_frame_ref_e */ hStereoICBWE->shbSynthRef_e = shb_frame_ref_e; move16(); - Copy32( shb_frame_ref_fx, shb_synth_nonref_fx, L_FRAME16k ); // max_e + Copy32( shb_frame_ref_fx, shb_synth_nonref_fx, L_FRAME16k ); /* Q31-shb_frame_ref_e */ shb_synth_nonref_e = shb_frame_ref_e; move16(); set32_fx( hStereoICBWE->mem_lpc_shbsynth_nonref_fx, 0, 10 ); + hStereoICBWE->mem_lpc_shbsynth_nonref_e = 0; + move16(); } icbwe_dft_stereo_param_ivas_fx( hStereoICBWE, hStereoDft, st, shb_synth_nonref_fx, shb_synth_nonref_e ); - hStereoICBWE->memShbSpecMapping_e = shb_synth_nonref_e; - move16(); } ELSE { @@ -802,31 +809,36 @@ void stereo_icBWE_enc_ivas_fx( Copy_Scale_sig( hStereoICBWE->mem_shb_speech_ref_fx, hStereoICBWE->mem_shb_speech_ref_fx, L_LOOK_16k, negate( sub( max_e, hStereoICBWE->mem_shb_speech_ref_e ) ) ); // mem_shb_speech_ref_e set32_fx( shb_frame_ref_fx, 0, L_LOOK_16k + L_FRAME16k ); - Copy_Scale_sig_16_32( hStereoICBWE->mem_shb_speech_ref_fx, shb_frame_ref_fx, L_LOOK_16k, add( negate( sub( max_e, hStereoICBWE->mem_shb_speech_ref_e ) ), Q16 ) ); // mem_shb_speech_ref_e - +#ifdef FIX_ISSUE_1237 + Copy_Scale_sig_16_32_no_sat( hStereoICBWE->mem_shb_speech_ref_fx, shb_frame_ref_fx, L_LOOK_16k, add( negate( sub( max_e, hStereoICBWE->mem_shb_speech_ref_e ) ), Q16 ) ); // mem_shb_speech_ref_e +#else + Copy_Scale_sig_16_32_DEPREC( hStereoICBWE->mem_shb_speech_ref_fx, shb_frame_ref_fx, L_LOOK_16k, add( negate( sub( max_e, hStereoICBWE->mem_shb_speech_ref_e ) ), Q16 ) ); // mem_shb_speech_ref_e +#endif hStereoICBWE->mem_shb_speech_ref_e = max_e; shb_frame_ref_e = max_e; move16(); move16(); /* shb_frame_ref_ICBWE @ (8.75 - shb_speech_delay (=1.25) ms) after shb_speech */ - Copy_Scale_sig32( shb_speech_ref_fx, shb_frame_ref_fx + L_LOOK_16k - refMemLen, L_FRAME16k, negate( sub( max_e, shb_speech_ref_e ) ) ); + Copy_Scale_sig32( shb_speech_ref_fx, shb_frame_ref_fx + L_LOOK_16k - refMemLen, L_FRAME16k, negate( sub( max_e, shb_speech_ref_e ) ) ); /* Q31-max_e */ Copy_Scale_sig_32_16( shb_frame_ref_fx + L_FRAME16k, hStereoICBWE->mem_shb_speech_ref_fx, L_LOOK_16k, sub( negate( sub( max_e, hStereoICBWE->mem_shb_speech_ref_e ) ), Q16 ) ); // mem_shb_speech_ref_e set32_fx( shb_frame_nonref_fx, 0, L_LOOK_16k + L_FRAME16k ); max_e = s_max( hStereoICBWE->mem_shb_speech_nonref_e, shb_speech_nonref_e ); Copy_Scale_sig( hStereoICBWE->mem_shb_speech_nonref_fx, hStereoICBWE->mem_shb_speech_nonref_fx, L_LOOK_16k, negate( sub( max_e, hStereoICBWE->mem_shb_speech_nonref_e ) ) ); // mem_shb_speech_ref_e - - Copy_Scale_sig_16_32( hStereoICBWE->mem_shb_speech_nonref_fx, shb_frame_nonref_fx, L_LOOK_16k, add( negate( sub( max_e, hStereoICBWE->mem_shb_speech_nonref_e ) ), Q16 ) ); // mem_shb_speech_ref_e - +#ifdef FIX_ISSUE_1237 + Copy_Scale_sig_16_32_no_sat( hStereoICBWE->mem_shb_speech_nonref_fx, shb_frame_nonref_fx, L_LOOK_16k, add( negate( sub( max_e, hStereoICBWE->mem_shb_speech_nonref_e ) ), Q16 ) ); // mem_shb_speech_ref_e +#else + Copy_Scale_sig_16_32_DEPREC( hStereoICBWE->mem_shb_speech_nonref_fx, shb_frame_nonref_fx, L_LOOK_16k, add( negate( sub( max_e, hStereoICBWE->mem_shb_speech_nonref_e ) ), Q16 ) ); // mem_shb_speech_ref_e +#endif hStereoICBWE->mem_shb_speech_nonref_e = max_e; shb_frame_nonref_e = max_e; move16(); move16(); /* shb_frame_ref_ICBWE @ (8.75 - shb_speech_delay (=1.25) ms) after shb_speech */ - Copy_Scale_sig32( shb_speech_nonref_fx, shb_frame_nonref_fx + L_LOOK_16k - nonRefMemLen, L_FRAME16k, negate( sub( max_e, shb_speech_nonref_e ) ) ); + Copy_Scale_sig32( shb_speech_nonref_fx, shb_frame_nonref_fx + L_LOOK_16k - nonRefMemLen, L_FRAME16k, negate( sub( max_e, shb_speech_nonref_e ) ) ); /* Q31-max_e */ Copy_Scale_sig_32_16( shb_frame_nonref_fx + L_FRAME16k, hStereoICBWE->mem_shb_speech_nonref_fx, L_LOOK_16k, sub( negate( sub( max_e, hStereoICBWE->mem_shb_speech_ref_e ) ), Q16 ) ); // mem_shb_speech_ref_e @@ -854,6 +866,8 @@ void stereo_icBWE_enc_ivas_fx( IF( ( NE_16( hStereoICBWE->prev_refChanIndx_bwe, hStereoICBWE->refChanIndx_bwe ) ) || NE_16( st->last_extl, st->extl ) || NE_16( st->flag_ACELP16k, 1 ) ) { hStereoICBWE->prevSpecMapping_fx = 0; + hStereoICBWE->memShbSpecMapping_e = 0; + move16(); hStereoICBWE->memShbSpecMapping_fx = 0; move32(); move32(); @@ -871,14 +885,14 @@ void stereo_icBWE_enc_ivas_fx( move32(); move32(); L_tmp = sum2_32_fx( shb_frame_nonref_fx + sub( L_LOOK_16k, refMemLen ), L_FRAME16k, &temp1_e ); - temp1_fx = Sqrt32( L_tmp, &temp1_e ); + temp1_fx = Sqrt32( L_tmp, &temp1_e ); /* Q31-temp1_e */ /*temp1 = 0.8f*hStereoICBWE->prevNonRefEner + 0.2f*temp1;*/ /*temp2 = 0.8f*hStereoICBWE->prevRefEner + 0.2f*temp2;*/ IF( temp2_fx == 0 ) { - gDes_fx = 1073741824; + gDes_fx = 1073741824; /* 1.0 in Q30 */ gDes_e = 1; move16(); move32(); @@ -894,8 +908,8 @@ void stereo_icBWE_enc_ivas_fx( exp = hStereoICBWE->gDes_pastFrame_e; move16(); move16(); - L_tmp = Sqrt32( gDes_fx, &tmp ); - L_tmp1 = Sqrt32( hStereoICBWE->gDes_pastFrame_fx, &exp ); + L_tmp = Sqrt32( gDes_fx, &tmp ); /* Q31-tmp */ + L_tmp1 = Sqrt32( hStereoICBWE->gDes_pastFrame_fx, &exp ); /* Q31-exp */ hStereoICBWE->gDes_pastFrame_fx = Mpy_32_32( L_tmp, L_tmp1 ); // tmp + exp hStereoICBWE->gDes_pastFrame_e = add( tmp, exp ); @@ -918,11 +932,13 @@ void stereo_icBWE_enc_ivas_fx( Copy32( voice_factors_fx, nlMixFac_fx, NB_SUBFR16k ); // Q31 test(); - IF( LT_32( gTarget_fx, 268435456 ) || GT_32( gTarget_fx, 1073741824 ) ) // + IF( LT_32( gTarget_fx, 268435456 ) || GT_32( gTarget_fx, 1073741824 ) ) // 0.5 in Q29 & 2.0 in Q29 { - v_multc_fixed( voice_factors_fx, 1073741824, nlMixFac_fx, NB_SUBFR16k ); + v_multc_fixed( voice_factors_fx, 1073741824 /*0.5 in Q31*/, nlMixFac_fx, NB_SUBFR16k ); /* Q31 */ } + Word16 L_FRAME16k_by_nbSubFr = L_FRAME16k / NB_SUBFR; + move16(); IF( st->flag_ACELP16k == 0 ) { nbSubFr = NB_SUBFR; @@ -932,6 +948,8 @@ void stereo_icBWE_enc_ivas_fx( { nbSubFr = NB_SUBFR16k; move16(); + L_FRAME16k_by_nbSubFr = L_FRAME16k / NB_SUBFR16k; + move16(); } Word16 exp_buf[L_FRAME16k]; @@ -944,7 +962,7 @@ void stereo_icBWE_enc_ivas_fx( temp1_fx = 0; temp1_e = 0; - temp2_fx = ONE_IN_Q31; + temp2_fx = ONE_IN_Q31; /* Q31 */ temp2_e = 0; move32(); move32(); @@ -954,15 +972,15 @@ void stereo_icBWE_enc_ivas_fx( ELSE { temp1_e = 0, temp2_e = 0; - temp1_fx = Sqrt32( nlMixFac_fx[i], &temp1_e ); - temp2_fx = Sqrt32( L_sub( ONE_IN_Q31, nlMixFac_fx[i] ), &temp2_e ); - move32(); + temp1_fx = Sqrt32( nlMixFac_fx[i], &temp1_e ); /* Q31-temp1_e */ + temp2_fx = Sqrt32( L_sub( ONE_IN_Q31, nlMixFac_fx[i] ), &temp2_e ); /* Q31 */ + move16(); move16(); } - FOR( j = 0; j < ( L_FRAME16k / nbSubFr ); ( j++, k++ ) ) + FOR( j = 0; j < L_FRAME16k_by_nbSubFr; ( j++, k++ ) ) { - excSHB_nonref_fx[k] = extract_l( BASOP_Util_Add_Mant32Exp( Mpy_32_32( temp1_fx, hStereoICBWE->nlExc16k_fx[k] ), temp1_e + hStereoICBWE->nlExc16k_e, Mpy_32_32( temp2_fx, hStereoICBWE->mixExc16k_fx[k] ), temp2_e + hStereoICBWE->mixExc16k_e, &exp_buf[k] ) ); + excSHB_nonref_fx[k] = BASOP_Util_Add_Mant32Exp( Mpy_32_32( temp1_fx, L_deposit_h( hStereoICBWE->nlExc16k_fx[k] ) ), add( temp1_e, hStereoICBWE->nlExc16k_e ), Mpy_32_32( temp2_fx, L_deposit_h( hStereoICBWE->mixExc16k_fx[k] ) ), add( temp2_e, hStereoICBWE->mixExc16k_e ), &exp_buf[k] ); /* Q31-exp_buf */ move32(); } } @@ -980,32 +998,28 @@ void stereo_icBWE_enc_ivas_fx( FOR( j = 0; j < L_FRAME16k; j++ ) { - excSHB_nonref_fx[j] = L_shr( excSHB_nonref_fx[j], sub( max_e, exp_buf[j] ) ); + excSHB_nonref_fx[j] = L_shr( excSHB_nonref_fx[j], sub( max_e, exp_buf[j] ) ); /* Q31-max_e */ move32(); } /* LP synthesis */ + Copy_Scale_sig32( hStereoICBWE->mem_lpc_shbsynth_nonref_fx, hStereoICBWE->mem_lpc_shbsynth_nonref_fx, LPC_SHB_ORDER, sub( hStereoICBWE->mem_lpc_shbsynth_nonref_e, s_max( hStereoICBWE->mem_lpc_shbsynth_nonref_e, max_e ) ) ); /* Q31-tmp_e */ + Copy_Scale_sig32( excSHB_nonref_fx, excSHB_nonref_fx, L_FRAME16k, sub( max_e, s_max( hStereoICBWE->mem_lpc_shbsynth_nonref_e, max_e ) ) ); /* Q31-tmp_e */ + max_e = s_max( hStereoICBWE->mem_lpc_shbsynth_nonref_e, max_e ); + hStereoICBWE->mem_lpc_shbsynth_nonref_e = s_max( hStereoICBWE->mem_lpc_shbsynth_nonref_e, max_e ); - Word16 tmp_e = s_max( hCPE->hStereoICBWE->lpSHBRef_e, max_e ); - - Word32 lpSHBRef_fx32[LPC_SHB_ORDER + 1]; - - Copy_Scale_sig32( hCPE->hStereoICBWE->lpSHBRef_fx, lpSHBRef_fx32, LPC_SHB_ORDER + 1, negate( sub( tmp_e, hCPE->hStereoICBWE->lpSHBRef_e ) ) ); - Copy_Scale_sig32( excSHB_nonref_fx, excSHB_nonref_fx, L_FRAME16k, negate( sub( tmp_e, max_e ) ) ); - - E_UTIL_synthesis_fx( 0, hStereoICBWE->lpSHBRef_fx, excSHB_nonref_fx, shb_synth_nonref_fx, L_FRAME16k, hStereoICBWE->mem_lpc_shbsynth_nonref_fx, 1, LPC_SHB_ORDER ); - shb_synth_nonref_e = sub( 31, tmp_e ); - hStereoICBWE->mem_lpc_shbsynth_nonref_e = shb_synth_nonref_e; - move16(); + syn_filt_fx32( hStereoICBWE->lpSHBRef_e, hStereoICBWE->lpSHBRef_fx, LPC_SHB_ORDER, excSHB_nonref_fx, max_e, shb_synth_nonref_fx, &shb_synth_nonref_e, L_FRAME16k, hStereoICBWE->mem_lpc_shbsynth_nonref_fx, &hStereoICBWE->mem_lpc_shbsynth_nonref_e, 1 ); } ELSE { Copy_Scale_sig_32_16( shb_frame_ref_fx, hStereoICBWE->shbSynthRef_fx, L_FRAME16k, -16 ); // max_e hStereoICBWE->shbSynthRef_e = shb_frame_ref_e; move16(); - Copy32( shb_frame_ref_fx, shb_synth_nonref_fx, L_FRAME16k ); + Copy32( shb_frame_ref_fx, shb_synth_nonref_fx, L_FRAME16k ); /* Q31-shb_synth_nonref_e */ shb_synth_nonref_e = shb_frame_ref_e; move16(); set32_fx( hStereoICBWE->mem_lpc_shbsynth_nonref_fx, 0, 10 ); + hStereoICBWE->mem_lpc_shbsynth_nonref_e = 0; + move16(); } test(); @@ -1014,7 +1028,14 @@ void stereo_icBWE_enc_ivas_fx( IF( ( EQ_16( st->extl, SWB_TBE ) || EQ_16( st->extl, WB_TBE ) || EQ_16( st->extl, FB_TBE ) ) && EQ_16( st->flag_ACELP16k, 1 ) ) { /* IC BWE spectral mapping */ - spIndx = ic_bwe_enc_specMapping_ivas_fx( shb_frame_nonref_fx, shb_frame_nonref_e, shb_synth_nonref_fx, shb_synth_nonref_e, &( hStereoICBWE->prevSpecMapping_fx ), &( hStereoICBWE->memShbSpecMapping_fx ), hStereoICBWE->memShbSpecXcorr_fx, &( hStereoICBWE->memShbSpecXcorr_e ) ); + Word32 max_abs_val; + maximum_abs_32_fx( shb_synth_nonref_fx, L_FRAME16k, &max_abs_val ); + IF( max_abs_val > 0 ) + { + scale_sig32( shb_synth_nonref_fx, L_FRAME16k, -1 ); + shb_synth_nonref_e = sub( shb_synth_nonref_e, -1 ); + } + spIndx = ic_bwe_enc_specMapping_ivas_fx( shb_frame_nonref_fx, shb_frame_nonref_e, shb_synth_nonref_fx, shb_synth_nonref_e, &( hStereoICBWE->prevSpecMapping_fx ), &( hStereoICBWE->memShbSpecMapping_fx ), hStereoICBWE->memShbSpecXcorr_fx, &( hStereoICBWE->memShbSpecXcorr_e ) ); /* Q0 */ } ELSE { @@ -1038,9 +1059,9 @@ void stereo_icBWE_enc_ivas_fx( /* IC BWE GS mapping */ - gsIndx = ic_bwe_enc_gsMapping_ivas_fx( hStereoICBWE->gDes_pastFrame_fx, hStereoICBWE->gDes_pastFrame_e, hStereoICBWE->shbSynthRef_fx, hStereoICBWE->shbSynthRef_e, shb_synth_nonref_fx, &shb_synth_nonref_e, &( hStereoICBWE->prevgsMapping_fx ), &( hStereoICBWE->prevgsMapping_e ), hStereoICBWE->memGsEnerMap_fx, &hStereoICBWE->memGsEnerMap_e, st->element_mode ); + gsIndx = ic_bwe_enc_gsMapping_ivas_fx( hStereoICBWE->gDes_pastFrame_fx, hStereoICBWE->gDes_pastFrame_e, hStereoICBWE->shbSynthRef_fx, hStereoICBWE->shbSynthRef_e, shb_synth_nonref_fx, &shb_synth_nonref_e, &( hStereoICBWE->prevgsMapping_fx ), &( hStereoICBWE->prevgsMapping_e ), hStereoICBWE->memGsEnerMap_fx, &hStereoICBWE->memGsEnerMap_e, st->element_mode ); /* Q0 */ - hStereoICBWE->gDes_pastFrame_fx = gDes_fx; + hStereoICBWE->gDes_pastFrame_fx = gDes_fx; /* Q31-hStereoICBWE->gDes_pastFrame_e */ hStereoICBWE->gDes_pastFrame_e = gDes_e; move32(); move16(); @@ -1048,7 +1069,7 @@ void stereo_icBWE_enc_ivas_fx( } /* IC-BWE updates */ - hStereoICBWE->prev_refChanIndx_bwe = hStereoICBWE->refChanIndx_bwe; + hStereoICBWE->prev_refChanIndx_bwe = hStereoICBWE->refChanIndx_bwe; /* Q0 */ move16(); return; @@ -1079,6 +1100,8 @@ void stereo_icBWE_init_enc_fx( /* unscaled & scaled SHB synthesis memory */ set32_fx( hStereoICBWE->mem_lpc_shbsynth_nonref_fx, 0, LPC_SHB_ORDER ); + hStereoICBWE->mem_lpc_shbsynth_nonref_e = 0; + move16(); /* inter-channel BWE spectral shape adj. */ hStereoICBWE->prevSpecMapping_fx = 0; @@ -1152,19 +1175,19 @@ void stereo_icBWE_init_enc_fx( * Inter-channel BWE pre-proc of the non-ref channel *-------------------------------------------------------------------*/ static void findRefChanBWE_fx( - const Word16 *input0_fx, /* i/o : input 0 Qx */ - const Word16 *input1_fx, /* i/o : input 1 Qx */ - Word16 *refChanIndx_bwe, /* o : Ref Channel Index bwe */ - const Word16 input_frame, /* i : input 0 & 1 frame length */ - Word16 *mem0_fx, /* i/o : mem 0 for input 0 Qx */ - Word16 *mem1_fx /* i/o : mem 1 for input 1 Qx */ + const Word16 *input0_fx, /* i/o : input 0 Qx q_dataChan_fx*/ + const Word16 *input1_fx, /* i/o : input 1 Qx q_dataChan_fx*/ + Word16 *refChanIndx_bwe, /* o : Ref Channel Index bwe Q0*/ + const Word16 input_frame, /* i : input 0 & 1 frame length Q0*/ + Word16 *mem0_fx, /* i/o : mem 0 for input 0 Qx q_dataChan_fx*/ + Word16 *mem1_fx /* i/o : mem 1 for input 1 Qx q_dataChan_fx*/ ) { Word16 inp0_fx[L_FRAME48k], inp1_fx[L_FRAME48k]; Word32 tempF_fx, tempF1_fx; - Copy( input0_fx, inp0_fx, input_frame ); - Copy( input1_fx, inp1_fx, input_frame ); + Copy( input0_fx, inp0_fx, input_frame ); /* q_dataChan_fx */ + Copy( input1_fx, inp1_fx, input_frame ); /* q_dataChan_fx */ spectral_balancer_fx16( inp0_fx, mem0_fx, input_frame, 1 ); spectral_balancer_fx16( inp1_fx, mem1_fx, input_frame, 1 ); @@ -1174,12 +1197,12 @@ static void findRefChanBWE_fx( IF( LT_32( tempF1_fx, Mpy_32_32( 1374389535 /* 0.64f Q31 */, tempF_fx ) ) ) { - *refChanIndx_bwe = L_CH_INDX; + *refChanIndx_bwe = L_CH_INDX; /* Q0 */ move16(); } ELSE IF( LT_32( tempF_fx, Mpy_32_32( 1374389535 /* 0.64f Q31 */, tempF1_fx ) ) ) { - *refChanIndx_bwe = R_CH_INDX; + *refChanIndx_bwe = R_CH_INDX; /* Q0 */ move16(); } @@ -1194,8 +1217,8 @@ static void findRefChanBWE_fx( *-------------------------------------------------------------------*/ void stereo_icBWE_preproc_fx( CPE_ENC_HANDLE hCPE, /* i/o: CPE encoder structure */ - const Word16 input_frame, /* i : input frame length */ - Word16 shb_speech_nonref_fx[], /* o : SHB speech non-ref channel */ + const Word16 input_frame, /* i : input frame length Q0*/ + Word16 shb_speech_nonref_fx[], /* o : SHB speech non-ref channel q_shb_speech_nonref_fx*/ Word16 q_shb_speech_nonref_fx /* i : Q SHB speech non-ref channel */ ) { @@ -1210,6 +1233,10 @@ void stereo_icBWE_preproc_fx( Word32 gD_fx; Word32 input_Fs; +#ifdef MSAN_FIX + set16_fx( temp_inp_fx, 0, L_FRAME48k ); +#endif + /* initialization */ hStereoTCA = hCPE->hStereoTCA; /* Stereo TCA encoder handle */ hStereoICBWE = hCPE->hStereoICBWE; /* Stereo IC BWE encoder handle */ @@ -1238,11 +1265,11 @@ void stereo_icBWE_preproc_fx( IF( GE_16( hCPE->element_mode, IVAS_CPE_DFT ) && GE_32( input_Fs, 32000 ) ) { set16_fx( temp_inp_fx, 0, L_FRAME48k ); - Copy( hStereoICBWE->dataChan_fx[0], temp_inp_fx + nonRefMemLen, sub( input_frame, nonRefMemLen ) ); + Copy( hStereoICBWE->dataChan_fx[0], temp_inp_fx + nonRefMemLen, sub( input_frame, nonRefMemLen ) ); /* q_dataChan_fx */ IF( EQ_32( input_Fs, 48000 ) ) { - Copy( temp_inp_fx, temp_in_fx, L_FRAME48k ); + Copy( temp_inp_fx, temp_in_fx, L_FRAME48k ); /* q_dataChan_fx */ set16_fx( temp_inp_fx, 0, L_FRAME48k ); i = 2 * L_FILT48k + L_FILT_2OVER3; move16(); @@ -1252,17 +1279,17 @@ void stereo_icBWE_preproc_fx( /* flip the spectrum */ FOR( i = 0; i < L_FRAME32k; i += 2 ) { - temp_inp_fx[i] = negate( temp_inp_fx[i] ); + temp_inp_fx[i] = negate( temp_inp_fx[i] ); /* q_dataChan_fx */ move16(); } - Copy( temp_inp_fx + L_FRAME32k - 2 * L_FILT32k, hStereoICBWE->memModifyFs_icbwe_fx[0], 2 * L_FILT32k ); + Copy( temp_inp_fx + L_FRAME32k - 2 * L_FILT32k, hStereoICBWE->memModifyFs_icbwe_fx[0], 2 * L_FILT32k ); /* q_dataChan_fx */ set16_fx( temp_inp_fx, 0, L_FRAME48k ); - Copy( hStereoICBWE->dataChan_fx[1], temp_inp_fx + nonRefMemLen, sub( input_frame, nonRefMemLen ) ); + Copy( hStereoICBWE->dataChan_fx[1], temp_inp_fx + nonRefMemLen, sub( input_frame, nonRefMemLen ) ); /* q_dataChan_fx */ IF( EQ_32( input_Fs, 48000 ) ) { - Copy( temp_inp_fx, temp_in_fx, L_FRAME48k ); + Copy( temp_inp_fx, temp_in_fx, L_FRAME48k ); /* q_dataChan_fx */ set16_fx( temp_inp_fx, 0, L_FRAME48k ); i = 2 * L_FILT48k + L_FILT_2OVER3; move16(); @@ -1273,10 +1300,10 @@ void stereo_icBWE_preproc_fx( /* flip the spectrum */ FOR( i = 0; i < input_frame; i += 2 ) { - temp_inp_fx[i] = negate( temp_inp_fx[i] ); + temp_inp_fx[i] = negate( temp_inp_fx[i] ); /* q_dataChan_fx */ move16(); } - Copy( temp_inp_fx + L_FRAME32k - 2 * L_FILT32k, hStereoICBWE->memModifyFs_icbwe_fx[1], 2 * L_FILT32k ); + Copy( temp_inp_fx + L_FRAME32k - 2 * L_FILT32k, hStereoICBWE->memModifyFs_icbwe_fx[1], 2 * L_FILT32k ); /* q_dataChan_fx */ } return; @@ -1285,10 +1312,10 @@ void stereo_icBWE_preproc_fx( IF( NE_16( hCPE->element_mode, IVAS_CPE_TD ) ) { /* initial estimate of refChanIndx_bwe */ - gD_fx = hStereoTCA->targetGain_fx; + gD_fx = hStereoTCA->targetGain_fx; /* Q29 */ move32(); - refChanIndx_bwe = hStereoTCA->refChanIndx; + refChanIndx_bwe = hStereoTCA->refChanIndx; /* Q0 */ move16(); test(); test(); @@ -1298,7 +1325,7 @@ void stereo_icBWE_preproc_fx( refChanIndx_bwe = !( hStereoTCA->refChanIndx ); move16(); } - hStereoICBWE->refChanIndx_bwe = refChanIndx_bwe; + hStereoICBWE->refChanIndx_bwe = refChanIndx_bwe; /* Q0 */ move16(); set16_fx( hStereoICBWE->dec_2over3_mem_fx, 0, L_FILT_2OVER3 ); @@ -1310,10 +1337,10 @@ void stereo_icBWE_preproc_fx( return; } - gD_fx = hStereoTCA->targetGain_fx; + gD_fx = hStereoTCA->targetGain_fx; /* Q29 */ move32(); - refChanIndx_bwe = hStereoTCA->refChanIndx; + refChanIndx_bwe = hStereoTCA->refChanIndx; /* Q0 */ move16(); test(); test(); @@ -1331,19 +1358,19 @@ void stereo_icBWE_preproc_fx( IF( EQ_16( refChanIndx_bwe, R_CH_INDX ) ) { - Copy( hStereoICBWE->icbwe_inp_mem_fx[0], temp_inp_fx, nonRefMemLen ); - Copy( hStereoICBWE->dataChan_fx[0], temp_inp_fx + nonRefMemLen, sub( input_frame, nonRefMemLen ) ); + Copy( hStereoICBWE->icbwe_inp_mem_fx[0], temp_inp_fx, nonRefMemLen ); /* q_dataChan_fx */ + Copy( hStereoICBWE->dataChan_fx[0], temp_inp_fx + nonRefMemLen, sub( input_frame, nonRefMemLen ) ); /* q_dataChan_fx */ } ELSE { - Copy( hStereoICBWE->icbwe_inp_mem_fx[1], temp_inp_fx, nonRefMemLen ); - Copy( hStereoICBWE->dataChan_fx[1], temp_inp_fx + nonRefMemLen, sub( input_frame, nonRefMemLen ) ); + Copy( hStereoICBWE->icbwe_inp_mem_fx[1], temp_inp_fx, nonRefMemLen ); /* q_dataChan_fx */ + Copy( hStereoICBWE->dataChan_fx[1], temp_inp_fx + nonRefMemLen, sub( input_frame, nonRefMemLen ) ); /* q_dataChan_fx */ } IF( EQ_32( input_Fs, 48000 ) ) { /*printf("\n Non-ref target HB generation for 48 kHz sample rate needs alignment verification \n");*/ - Copy( temp_inp_fx, temp_in_fx, L_FRAME48k ); + Copy( temp_inp_fx, temp_in_fx, L_FRAME48k ); /* q_dataChan_fx */ set16_fx( temp_inp_fx, 0, L_FRAME48k ); decimate_2_over_3_allpass_fx( temp_in_fx, L_FRAME48k, temp_inp_fx, hStereoICBWE->dec_2over3_mem_fx, allpass_poles_3_ov_2, decimate_3_ov_2_lowpass_num_fx, decimate_3_ov_2_lowpass_den_fx, hStereoICBWE->dec_2over3_mem_lp_fx ); @@ -1352,25 +1379,25 @@ void stereo_icBWE_preproc_fx( /* flip the spectrum */ FOR( i = 0; i < input_frame; i += 2 ) { - temp_inp_fx[i] = negate( temp_inp_fx[i] ); + temp_inp_fx[i] = negate( temp_inp_fx[i] ); /* q_dataChan_fx */ move16(); } test(); test(); test(); - IF( GE_16( hCPE->element_mode, IVAS_CPE_DFT ) && GE_32( input_Fs, 32000 ) && ( NE_16( st->last_core, ACELP_CORE ) || EQ_16( st->last_extl, -1 ) ) ) + IF( GE_16( hCPE->element_mode, IVAS_CPE_DFT ) && GE_32( input_Fs, 32000 ) && ( ( st->last_core != ACELP_CORE ) || EQ_16( st->last_extl, -1 ) ) ) { - Copy_Scale_sig( hStereoICBWE->memModifyFs_icbwe_fx[!refChanIndx_bwe], hStereoICBWE->mem_decim_shb_ch0_fx, 2 * L_FILT32k, sub( 0, hStereoICBWE->q_dataChan_fx ) ); + Copy_Scale_sig( hStereoICBWE->memModifyFs_icbwe_fx[!refChanIndx_bwe], hStereoICBWE->mem_decim_shb_ch0_fx, 2 * L_FILT32k, sub( 0, hStereoICBWE->q_dataChan_fx ) ); /* Q0 */ } Word16 Q_new_inp, mem_decim_size; - Scale_sig( temp_inp_fx, L_FRAME48k, sub( 0, hStereoICBWE->q_dataChan_fx ) ); + Scale_sig( temp_inp_fx, L_FRAME48k, sub( 0, hStereoICBWE->q_dataChan_fx ) ); /* q_dataChan_fx */ /* IVAS-219: Re-wire the shb nonref estimation through a lite CLDFB */ modify_Fs_fx( temp_inp_fx, L_FRAME32k, 32000, tempSHB_fx, 16000, hStereoICBWE->mem_decim_shb_ch0_fx, 0, &Q_new_inp, &mem_decim_size ); - Copy_Scale_sig( tempSHB_fx, shb_speech_nonref_fx, L_FRAME16k, sub( q_shb_speech_nonref_fx, Q_new_inp ) ); + Copy_Scale_sig( tempSHB_fx, shb_speech_nonref_fx, L_FRAME16k, sub( q_shb_speech_nonref_fx, Q_new_inp ) ); /* q_shb_speech_nonref_fx */ return; } diff --git a/lib_enc/ivas_stereo_mdct_core_enc.c b/lib_enc/ivas_stereo_mdct_core_enc_fx.c similarity index 77% rename from lib_enc/ivas_stereo_mdct_core_enc.c rename to lib_enc/ivas_stereo_mdct_core_enc_fx.c index 123b2615905547e3fb23f1144414bc3145d03e35..b6857854222703856361681d216a5cddf98fe512 100644 --- a/lib_enc/ivas_stereo_mdct_core_enc.c +++ b/lib_enc/ivas_stereo_mdct_core_enc_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other @@ -35,9 +35,7 @@ #include "options.h" #include #include "cnst.h" -#include "prot.h" #include "prot_fx.h" -#include "ivas_prot.h" #include "rom_com.h" #include "wmc_auto.h" #include "ivas_prot_fx.h" @@ -49,17 +47,17 @@ * Synchronize under certain conditions the tcx modes and set overlap * windows accordingly *-------------------------------------------------------------------*/ -static void sync_tcx_mode( +static void sync_tcx_mode_fx( Encoder_State **st /* i/o: Encoder state */ ) { - const Word32 prevAccNrg0 = st[0]->hTranDet->subblockEnergies.accSubblockNrg[st[0]->hTranDet->subblockEnergies.nDelay]; + const Word32 prevAccNrg0 = st[0]->hTranDet->subblockEnergies.accSubblockNrg[st[0]->hTranDet->subblockEnergies.nDelay]; /* Q(-1) */ move32(); - const Word32 prevAccNrg1 = st[1]->hTranDet->subblockEnergies.accSubblockNrg[st[1]->hTranDet->subblockEnergies.nDelay]; + const Word32 prevAccNrg1 = st[1]->hTranDet->subblockEnergies.accSubblockNrg[st[1]->hTranDet->subblockEnergies.nDelay]; /* Q(-1) */ move32(); - const Word32 lastAccNrg0 = st[0]->hTranDet->subblockEnergies.accSubblockNrg[add( st[0]->hTranDet->subblockEnergies.nDelay, st[0]->hTranDet->transientDetector.nSubblocksToCheck )]; + const Word32 lastAccNrg0 = st[0]->hTranDet->subblockEnergies.accSubblockNrg[( st[0]->hTranDet->subblockEnergies.nDelay + st[0]->hTranDet->transientDetector.nSubblocksToCheck )]; /* Q(-1) */ move32(); - const Word32 lastAccNrg1 = st[1]->hTranDet->subblockEnergies.accSubblockNrg[add( st[1]->hTranDet->subblockEnergies.nDelay, st[1]->hTranDet->transientDetector.nSubblocksToCheck )]; + const Word32 lastAccNrg1 = st[1]->hTranDet->subblockEnergies.accSubblockNrg[( st[1]->hTranDet->subblockEnergies.nDelay + st[1]->hTranDet->transientDetector.nSubblocksToCheck )]; /* Q(-1) */ move32(); test(); @@ -84,8 +82,8 @@ static void sync_tcx_mode( test(); test(); test(); - IF( GT_32( prevAccNrg0, Mpy_32_16_1( prevAccNrg1, 1311 ) ) && GT_32( prevAccNrg1, Mpy_32_16_1( prevAccNrg0, 1311 ) ) /* 14 dB */ - && GT_32( lastAccNrg0, Mpy_32_16_1( lastAccNrg1, 2048 ) ) && GT_32( lastAccNrg1, Mpy_32_16_1( lastAccNrg0, 2048 ) ) ) /* 12 dB */ + IF( GT_32( prevAccNrg0, Mpy_32_16_1( prevAccNrg1, 1311 /*1/25 in Q15*/ ) ) && GT_32( prevAccNrg1, Mpy_32_16_1( prevAccNrg0, 1311 /*1/25 in Q15*/ ) ) /* 14 dB */ + && GT_32( lastAccNrg0, Mpy_32_16_1( lastAccNrg1, 2048 /*1/12 in Q15*/ ) ) && GT_32( lastAccNrg1, Mpy_32_16_1( lastAccNrg0, 2048 /*1/12 in Q15*/ ) ) ) /* 12 dB */ { st[0]->hTcxEnc->tcxMode = st[1]->hTcxEnc->tcxMode = s_max( st[0]->hTcxEnc->tcxMode, st[1]->hTcxEnc->tcxMode ); /* synchronize TCX mode of both channels */ move16(); @@ -130,15 +128,17 @@ static void sync_tcx_mode( *-------------------------------------------------------------------*/ void stereo_mdct_core_enc_fx( CPE_ENC_HANDLE hCPE, /* i/o: CPE encoder structure */ - Word16 new_samples[CPE_CHANNELS][L_INP], /* i : new samples */ - Word16 old_wsp[CPE_CHANNELS][L_WSP], /* i : 12.8kHz weighted speech (for LTP */ - Word16 pitch_buf_fx[CPE_CHANNELS][NB_SUBFR16k] /* o : floating pitch for each subframe */ + Word16 new_samples[CPE_CHANNELS][L_INP], /* i : new samples Q0*/ + Word16 old_wsp[CPE_CHANNELS][L_WSP], /* i : 12.8kHz weighted speech (for LTP Qx*/ + Word16 pitch_buf_fx[CPE_CHANNELS][NB_SUBFR16k] /* o : floating pitch for each subframe Q6*/ ) { Word32 orig_spectrum_long_fx[CPE_CHANNELS][N_MAX]; /* MDCT output (L/R). */ Word32 *orig_spectrum_fx[CPE_CHANNELS][NB_DIV]; /* Pointers to MDCT output for a short block (L/R) */ Word32 powerSpec_fx[CPE_CHANNELS][N_MAX]; + Word32 powerSpec_fx_tmp[CPE_CHANNELS][N_MAX]; /* This 32 bit buffer is created to preserve the precision for original separate Q calculation of powerSpec_fx buffer ( Related to 3gpp issue #1192 ) */ Word32 *p_powerSpec_fx[CPE_CHANNELS]; + Word16 exp_powerSpec[CPE_CHANNELS][N_MAX + L_MDCT_OVLP_MAX]; Word32 powerSpecMsInv_long_fx[CPE_CHANNELS][N_MAX]; /* MS inv power spectrum, also inverse MDST spectrum */ Word32 *powerSpecMsInv_fx[CPE_CHANNELS][NB_DIV]; Word32 quantized_spectrum_long_fx[CPE_CHANNELS][N_MAX]; /* quantized MDCT spectrum, inv ms mask mdst spectrum, scratch for MS spectra in the MS decision */ @@ -153,7 +153,7 @@ void stereo_mdct_core_enc_fx( Word32 *p_mdst_spectrum_long_fx[CPE_CHANNELS]; Word32 mdst_spectrum_long_fx[CPE_CHANNELS][N_MAX]; Word32 *mdst_spectrum_fx[CPE_CHANNELS][NB_DIV]; - Word16 q_powSpec[MCT_MAX_CHANNELS], q_spec, tmp_s; + Word16 q_powSpec[MCT_MAX_CHANNELS], q_powSpecMsInv[MCT_MAX_CHANNELS], q_spec, tmp_s; Word16 tmp_q_powSpec[N_MAX], tmp_q_powSpecInv[N_MAX], *tmp_q_psi[2]; Word64 W_tmp; Encoder_State *st, **sts; @@ -186,10 +186,13 @@ void stereo_mdct_core_enc_fx( p_orig_spectrum_long_fx[ch] = orig_spectrum_long_fx[ch]; orig_spectrum_fx[ch][0] = orig_spectrum_long_fx[ch]; orig_spectrum_fx[ch][1] = orig_spectrum_long_fx[ch] + N_TCX10_MAX; + set16_fx( exp_powerSpec[ch], 0, N_MAX + L_MDCT_OVLP_MAX ); } - set16_fx( tmp_q_powSpecInv, 63, L_FRAME48k ); - set16_fx( tmp_q_powSpec, 63, L_FRAME48k ); + set16_fx( tmp_q_powSpecInv, 63, N_MAX ); + set16_fx( tmp_q_powSpec, 63, N_MAX ); + set16_fx( q_powSpec, 31, MCT_MAX_CHANNELS ); + set16_fx( q_powSpecMsInv, 31, MCT_MAX_CHANNELS ); tmp_q_psi[0] = tmp_q_powSpecInv; tmp_q_psi[1] = &tmp_q_powSpecInv[N_TCX10_MAX]; @@ -209,11 +212,11 @@ void stereo_mdct_core_enc_fx( Word16 tmp_e = 0; move16(); Word32 L_tmp; - L_tmp = Sqrt32( L_add( L_shr( Mpy_32_32( sts[0]->hTcxEnc->tfm_mem_fx, sts[0]->hTcxEnc->tfm_mem_fx ), 1 ), L_shr( Mpy_32_32( sts[1]->hTcxEnc->tfm_mem_fx, sts[1]->hTcxEnc->tfm_mem_fx ), 1 ) ), &tmp_e ); /* RMS */ + L_tmp = Sqrt32( L_add( L_shr( Mpy_32_32( sts[0]->hTcxEnc->tfm_mem_fx, sts[0]->hTcxEnc->tfm_mem_fx ), 1 ), L_shr( Mpy_32_32( sts[1]->hTcxEnc->tfm_mem_fx, sts[1]->hTcxEnc->tfm_mem_fx ), 1 ) ), &tmp_e ); /* RMS Q31-tmp_e*/ sts[0]->hTcxEnc->tfm_mem_fx = sts[1]->hTcxEnc->tfm_mem_fx = L_shl( L_tmp, tmp_e ); /* Q31 */ move32(); move32(); - sts[0]->hTcxEnc->tcxltp_norm_corr_past = sts[1]->hTcxEnc->tcxltp_norm_corr_past = extract_l( L_shr( L_add( sts[0]->hTcxEnc->tcxltp_norm_corr_past, sts[1]->hTcxEnc->tcxltp_norm_corr_past ), 1 ) ); + sts[0]->hTcxEnc->tcxltp_norm_corr_past = sts[1]->hTcxEnc->tcxltp_norm_corr_past = extract_l( L_shr( L_add( sts[0]->hTcxEnc->tcxltp_norm_corr_past, sts[1]->hTcxEnc->tcxltp_norm_corr_past ), 1 ) ); /* Q15 */ move16(); move16(); FOR( ch = 0; ch < CPE_CHANNELS; ch++ ) @@ -229,7 +232,7 @@ void stereo_mdct_core_enc_fx( EQ_16( sts[0]->hTcxCfg->tcx_last_overlap_mode, sts[1]->hTcxCfg->tcx_last_overlap_mode ) || EQ_16( add( sts[0]->hTcxCfg->tcx_last_overlap_mode, sts[1]->hTcxCfg->tcx_last_overlap_mode ), extract_l( 5 ) ) ) ) /* disable syncing for stereo switching or large diff in last frame overlap */ { - sync_tcx_mode( sts ); + sync_tcx_mode_fx( sts ); } IF( hCPE->hCoreCoder[0]->igf ) { @@ -264,14 +267,15 @@ void stereo_mdct_core_enc_fx( set32_fx( quantized_spectrum_long_fx[ch], 0, N_MAX ); set32_fx( mdst_spectrum_long_fx[ch], 0, N_MAX ); set32_fx( powerSpec_fx[ch], 0, N_MAX ); + set32_fx( powerSpec_fx_tmp[ch], 0, N_MAX ); set32_fx( powerSpecMsInv_long_fx[ch], 0, N_MAX ); sts[ch]->hTcxEnc->tns_ms_flag[0] = 0; move16(); sts[ch]->hTcxEnc->tns_ms_flag[1] = 0; move16(); - Scale_sig( sts[ch]->input_fx, (Word16) ( sts[ch]->input_Fs / 50 ) + NS2SA( 48000, DELAY_FIR_RESAMPL_NS ), negate( sts[ch]->q_inp ) ); - Scale_sig( sts[ch]->old_input_signal_fx, (Word16) ( sts[ch]->input_Fs / 50 ), negate( sts[ch]->q_old_inp ) ); + Scale_sig( sts[ch]->input_fx, add( extract_l( Mpy_32_32( sts[ch]->input_Fs, ONE_BY_FRAMES_PER_SEC_Q31 ) ), NS2SA( 48000, DELAY_FIR_RESAMPL_NS ) ), negate( sts[ch]->q_inp ) ); /* Q0 */ + Scale_sig( sts[ch]->old_input_signal_fx, extract_l( Mpy_32_32( sts[ch]->input_Fs, ONE_BY_FRAMES_PER_SEC_Q31 ) ), negate( sts[ch]->q_old_inp ) ); /* Q0 */ sts[ch]->q_old_inp = 0; move16(); sts[ch]->q_inp = 0; @@ -303,8 +307,8 @@ void stereo_mdct_core_enc_fx( IF( EQ_16( nSubframes, NB_DIV ) ) { Word16 max_e = s_max( orig_spectrum_e[i][0], orig_spectrum_e[i][1] ); - Scale_sig32( orig_spectrum_fx[i][0], N_TCX10_MAX, sub( orig_spectrum_e[i][0], max_e ) ); - Scale_sig32( orig_spectrum_fx[i][1], N_TCX10_MAX, sub( orig_spectrum_e[i][1], max_e ) ); + Scale_sig32( orig_spectrum_fx[i][0], N_TCX10_MAX, sub( orig_spectrum_e[i][0], max_e ) ); /* Q31-max_e */ + Scale_sig32( orig_spectrum_fx[i][1], N_TCX10_MAX, sub( orig_spectrum_e[i][1], max_e ) ); /* Q31-max_e */ p_orig_spectrum_e[i] = max_e; move16(); } @@ -328,19 +332,19 @@ void stereo_mdct_core_enc_fx( FOR( n = 0; n < nSubframes; n++ ) { - st->side_bits_frame_channel = add( st->side_bits_frame_channel, NBITS_TCX_GAIN + NOISE_FILL_RANGES * NBITS_NOISE_FILL_LEVEL ); + st->side_bits_frame_channel = add( st->side_bits_frame_channel, NBITS_TCX_GAIN + NOISE_FILL_RANGES * NBITS_NOISE_FILL_LEVEL ); /* Q0 */ move16(); } } - sts[0]->side_bits_frame_channel = add( sts[0]->side_bits_frame_channel, SMDCT_NBBITS_SPLIT_RATIO ); + sts[0]->side_bits_frame_channel = add( sts[0]->side_bits_frame_channel, SMDCT_NBBITS_SPLIT_RATIO ); /* Q0 */ move16(); /*--------------------------------------------------------------* * Stereo Processing *---------------------------------------------------------------*/ - - if ( !hStereoMdct->isSBAStereoMode ) + test(); + IF( !hStereoMdct->isSBAStereoMode ) { /* Common q for mdst_spectrum and spectrum */ Word16 k; @@ -365,13 +369,13 @@ void stereo_mdct_core_enc_fx( n_sb = 1; move16(); } - length = idiv1616( sts[ch]->hTcxEnc->L_frameTCX, n_sb ); + length = idiv1616( sts[ch]->hTcxEnc->L_frameTCX, n_sb ); /* Q0 */ FOR( k = 0; k <= ( ( sts[ch]->core == TCX_20_CORE ) ? 1 : NB_DIV ) - 1; k++ ) { - Scale_sig32( sts[ch]->hTcxEnc->spectrum_fx[k], length, sub( q_spec, sub( Q31, sts[ch]->hTcxEnc->spectrum_e[k] ) ) ); + Scale_sig32( sts[ch]->hTcxEnc->spectrum_fx[k], length, sub( q_spec, sub( Q31, sts[ch]->hTcxEnc->spectrum_e[k] ) ) ); /* q_spec */ sts[ch]->hTcxEnc->spectrum_e[k] = sub( Q31, q_spec ); - Scale_sig32( mdst_spectrum_fx[ch][k], length, sub( q_spec, sub( Q31, mdst_spectrum_e[ch][k] ) ) ); + Scale_sig32( mdst_spectrum_fx[ch][k], length, sub( q_spec, sub( Q31, mdst_spectrum_e[ch][k] ) ) ); /* q_spec */ mdst_spectrum_e[ch][k] = sub( Q31, q_spec ); } } @@ -388,7 +392,7 @@ void stereo_mdct_core_enc_fx( IF( EQ_16( sts[ch]->hTcxEnc->tcxMode, TCX_20 ) ) { nSubframes = 1; - L_subframeTCX = sts[ch]->hTcxEnc->L_frameTCX; + L_subframeTCX = sts[ch]->hTcxEnc->L_frameTCX; /* Q0 */ move16(); move16(); } @@ -396,13 +400,13 @@ void stereo_mdct_core_enc_fx( { nSubframes = NB_DIV; move16(); - L_subframeTCX = shr( sts[ch]->hTcxEnc->L_frameTCX, 1 ); + L_subframeTCX = shr( sts[ch]->hTcxEnc->L_frameTCX, 1 ); /* Q0 */ } /* in MCT only relevant for bitrate switching from non-MCT bitrates */ IF( EQ_16( sts[ch]->last_core, ACELP_CORE ) ) { - L_subframeTCX = add( L_subframeTCX, shr( L_subframeTCX, 2 ) ); + L_subframeTCX = add( L_subframeTCX, shr( L_subframeTCX, 2 ) ); /* Q0 */ } FOR( n = 0; n < nSubframes; n++ ) @@ -414,18 +418,18 @@ void stereo_mdct_core_enc_fx( /* power spectrum: MDCT^2 + MDST^2 */ FOR( i = 0; i < L_subframeTCX; i++ ) { - W_tmp = W_mac_32_32( W_mult_32_32( mdst_spectrum_fx[ch][n][i], mdst_spectrum_fx[ch][n][i] ), sts[ch]->hTcxEnc->spectrum_fx[n][i], sts[ch]->hTcxEnc->spectrum_fx[n][i] ); - tmp_s = sub( W_norm( W_tmp ), 1 ); - W_tmp = W_shl( W_tmp, tmp_s ); - powerSpec_fx[ch][( i + ( n * L_subframeTCX ) )] = W_extract_h( W_tmp ); + W_tmp = W_mac_32_32( W_mult_32_32( mdst_spectrum_fx[ch][n][i], mdst_spectrum_fx[ch][n][i] ), sts[ch]->hTcxEnc->spectrum_fx[n][i], sts[ch]->hTcxEnc->spectrum_fx[n][i] ); /* 2*q_spec+1 */ + tmp_s = W_norm( W_tmp ); + W_tmp = W_shl( W_tmp, tmp_s ); /* 2*q_spec+1+tmp_s */ + powerSpec_fx[ch][( i + ( n * L_subframeTCX ) )] = W_extract_h( W_tmp ); /* 2*q_spec+1+tmp_s-32 */ tmp_q_powSpec[( i + ( n * L_subframeTCX ) )] = sub( add( imult1616( q_spec, 2 ), tmp_s ), 31 ); // Q = 2 * q_spec + 1 + tmp_s - 32 move32(); move16(); - W_tmp = W_mac_32_32( W_mult_32_32( inv_mdst_spectrum_fx[ch][n][i], inv_mdst_spectrum_fx[ch][n][i] ), inv_spectrum_fx[ch][n][i], inv_spectrum_fx[ch][n][i] ); - tmp_s = sub( W_norm( W_tmp ), 1 ); - W_tmp = W_shl( W_tmp, tmp_s ); - powerSpecMsInv_fx[ch][n][i] = W_extract_h( W_tmp ); + W_tmp = W_mac_32_32( W_mult_32_32( inv_mdst_spectrum_fx[ch][n][i], inv_mdst_spectrum_fx[ch][n][i] ), inv_spectrum_fx[ch][n][i], inv_spectrum_fx[ch][n][i] ); /* 2*q_spec+1 */ + tmp_s = W_norm( W_tmp ); + W_tmp = W_shl( W_tmp, tmp_s ); /* 2*q_spec+1+tmp_s */ + powerSpecMsInv_fx[ch][n][i] = W_extract_h( W_tmp ); /* 2*q_spec+1+tmp_s-32 */ tmp_q_psi[n][i] = sub( add( imult1616( q_spec, 2 ), tmp_s ), 31 ); // Q = 2 * q_spec + 1 + tmp_s - 32 move32(); move16(); @@ -436,62 +440,62 @@ void stereo_mdct_core_enc_fx( IF( NE_16( hStereoMdct->mdct_stereo_mode[n], SMDCT_DUAL_MONO ) ) { /* power spectrum: MDCT^2 + MDST^2 */ - W_tmp = W_mult_32_32( inv_spectrum_fx[ch][n][0], inv_spectrum_fx[ch][n][0] ); - tmp_s = sub( W_norm( W_tmp ), 1 ); - W_tmp = W_shl( W_tmp, tmp_s ); - powerSpecMsInv_fx[ch][n][0] = W_extract_h( W_tmp ); + W_tmp = W_mult_32_32( inv_spectrum_fx[ch][n][0], inv_spectrum_fx[ch][n][0] ); /* 2*q_spec+1 */ + tmp_s = W_norm( W_tmp ); + W_tmp = W_shl( W_tmp, tmp_s ); /* 2*q_spec+1+tmp_s */ + powerSpecMsInv_fx[ch][n][0] = W_extract_h( W_tmp ); /* 2*q_spec+1+tmp_s-32 */ tmp_q_psi[n][0] = sub( add( imult1616( q_spec, 2 ), tmp_s ), 31 ); // Q = 2 * q_spec + 1 + tmp_s - 32 move32(); move16(); FOR( i = 1; i < L_subframeTCX - 1; i++ ) { - Word32 mdst_fx = L_sub( inv_spectrum_fx[ch][n][i + 1], inv_spectrum_fx[ch][n][i - 1] ); /* An MDST estimate */ + Word32 mdst_fx = L_sub( inv_spectrum_fx[ch][n][i + 1], inv_spectrum_fx[ch][n][i - 1] ); /* An MDST estimate q_spec*/ - W_tmp = W_mac_32_32( W_mult_32_32( mdst_fx, mdst_fx ), inv_spectrum_fx[ch][n][i], inv_spectrum_fx[ch][n][i] ); - tmp_s = sub( W_norm( W_tmp ), 1 ); - W_tmp = W_shl( W_tmp, tmp_s ); - powerSpecMsInv_fx[ch][n][i] = W_extract_h( W_tmp ); + W_tmp = W_mac_32_32( W_mult_32_32( mdst_fx, mdst_fx ), inv_spectrum_fx[ch][n][i], inv_spectrum_fx[ch][n][i] ); /* 2*q_spec+1 */ + tmp_s = W_norm( W_tmp ); + W_tmp = W_shl( W_tmp, tmp_s ); /* 2*q_spec+1+tmp_s */ + powerSpecMsInv_fx[ch][n][i] = W_extract_h( W_tmp ); /* 2*q_spec+1+tmp_s-32 */ tmp_q_psi[n][i] = sub( add( imult1616( q_spec, 2 ), tmp_s ), 31 ); // Q = 2 * q_spec + 1 + tmp_s - 32 move32(); move16(); } - W_tmp = W_mult_32_32( inv_spectrum_fx[ch][n][L_subframeTCX - 1], inv_spectrum_fx[ch][n][L_subframeTCX - 1] ); - tmp_s = sub( W_norm( W_tmp ), 1 ); - W_tmp = W_shl( W_tmp, tmp_s ); - powerSpecMsInv_fx[ch][n][L_subframeTCX - 1] = W_extract_h( W_tmp ); + W_tmp = W_mult_32_32( inv_spectrum_fx[ch][n][L_subframeTCX - 1], inv_spectrum_fx[ch][n][L_subframeTCX - 1] ); /* 2*q_spec+1 */ + tmp_s = W_norm( W_tmp ); + W_tmp = W_shl( W_tmp, tmp_s ); /* 2*q_spec+1+tmp_s */ + powerSpecMsInv_fx[ch][n][L_subframeTCX - 1] = W_extract_h( W_tmp ); /* 2*q_spec+1+tmp_s-32 */ tmp_q_psi[n][L_subframeTCX - 1] = sub( add( imult1616( q_spec, 2 ), tmp_s ), 31 ); // Q = 2 * q_spec + 1 + tmp_s - 32 move32(); move16(); } /* power spectrum: MDCT^2 + MDST^2 */ - W_tmp = W_mult_32_32( sts[ch]->hTcxEnc->spectrum_fx[n][0], sts[ch]->hTcxEnc->spectrum_fx[n][0] ); - tmp_s = sub( W_norm( W_tmp ), 1 ); - W_tmp = W_shl( W_tmp, tmp_s ); - powerSpec_fx[ch][n * L_subframeTCX] = W_extract_h( W_tmp ); + W_tmp = W_mult_32_32( sts[ch]->hTcxEnc->spectrum_fx[n][0], sts[ch]->hTcxEnc->spectrum_fx[n][0] ); /* 2*q_spec+1 */ + tmp_s = W_norm( W_tmp ); + W_tmp = W_shl( W_tmp, tmp_s ); /* 2*q_spec+1+tmp_s */ + powerSpec_fx[ch][n * L_subframeTCX] = W_extract_h( W_tmp ); /* 2*q_spec+1+tmp_s-32 */ tmp_q_powSpec[n * L_subframeTCX] = sub( add( imult1616( q_spec, 2 ), tmp_s ), 31 ); // Q = 2 * q_spec + 1 + tmp_s - 32 move32(); move16(); FOR( i = 1; i < L_subframeTCX - 1; i++ ) { - Word32 mdst_fx = L_sub( sts[ch]->hTcxEnc->spectrum_fx[n][i + 1], sts[ch]->hTcxEnc->spectrum_fx[n][i - 1] ); /* An MDST estimate */ + Word32 mdst_fx = L_sub( sts[ch]->hTcxEnc->spectrum_fx[n][i + 1], sts[ch]->hTcxEnc->spectrum_fx[n][i - 1] ); /* An MDST estimate q_spec*/ - W_tmp = W_mac_32_32( W_mult_32_32( mdst_fx, mdst_fx ), sts[ch]->hTcxEnc->spectrum_fx[n][i], sts[ch]->hTcxEnc->spectrum_fx[n][i] ); - tmp_s = sub( W_norm( W_tmp ), 1 ); - W_tmp = W_shl( W_tmp, tmp_s ); - powerSpec_fx[ch][( i + ( n * L_subframeTCX ) )] = W_extract_h( W_tmp ); + W_tmp = W_mac_32_32( W_mult_32_32( mdst_fx, mdst_fx ), sts[ch]->hTcxEnc->spectrum_fx[n][i], sts[ch]->hTcxEnc->spectrum_fx[n][i] ); /* 2*q_spec+1 */ + tmp_s = W_norm( W_tmp ); + W_tmp = W_shl( W_tmp, tmp_s ); /* 2*q_spec+1+tmp_s */ + powerSpec_fx[ch][( i + ( n * L_subframeTCX ) )] = W_extract_h( W_tmp ); /* 2*q_spec+1+tmp_s-32 */ tmp_q_powSpec[( i + ( n * L_subframeTCX ) )] = sub( add( imult1616( q_spec, 2 ), tmp_s ), 31 ); // Q = 2 * q_spec + 1 + tmp_s - 32 move32(); move16(); } - W_tmp = W_mult_32_32( sts[ch]->hTcxEnc->spectrum_fx[n][L_subframeTCX - 1], sts[ch]->hTcxEnc->spectrum_fx[n][L_subframeTCX - 1] ); - tmp_s = sub( W_norm( W_tmp ), 1 ); - W_tmp = W_shl( W_tmp, tmp_s ); - powerSpec_fx[ch][( ( L_subframeTCX - 1 ) + ( n * L_subframeTCX ) )] = W_extract_h( W_tmp ); + W_tmp = W_mult_32_32( sts[ch]->hTcxEnc->spectrum_fx[n][L_subframeTCX - 1], sts[ch]->hTcxEnc->spectrum_fx[n][L_subframeTCX - 1] ); /* 2*q_spec+1 */ + tmp_s = W_norm( W_tmp ); + W_tmp = W_shl( W_tmp, tmp_s ); /* 2*q_spec+1+tmp_s */ + powerSpec_fx[ch][( ( L_subframeTCX - 1 ) + ( n * L_subframeTCX ) )] = W_extract_h( W_tmp ); /* 2*q_spec+1+tmp_s-32 */ tmp_q_powSpec[( ( L_subframeTCX - 1 ) + ( n * L_subframeTCX ) )] = sub( add( imult1616( q_spec, 2 ), tmp_s ), 31 ); // Q = 2 * q_spec + 1 + tmp_s - 32 move32(); move16(); @@ -500,30 +504,40 @@ void stereo_mdct_core_enc_fx( /* Aligning the Q-factors */ { + q_powSpec[ch] = Q31; + q_powSpecMsInv[ch] = Q31; + move16(); + move16(); FOR( i = 0; i < N_MAX; i++ ) { - if ( powerSpec_fx[ch][i] == 0 ) + IF( powerSpec_fx[ch][i] != 0 ) { - tmp_q_powSpec[i] = 63; + q_powSpec[ch] = s_min( q_powSpec[ch], tmp_q_powSpec[i] ); + move16(); + exp_powerSpec[ch][i] = sub( Q31, tmp_q_powSpec[i] ); move16(); } - if ( powerSpecMsInv_fx[ch][0][i] == 0 ) + } + FOR( n = 0; n < nSubframes; n++ ) + { + FOR( i = 0; i < L_subframeTCX; i++ ) { - tmp_q_powSpecInv[i] = 63; - move16(); + IF( powerSpecMsInv_fx[ch][n][i] != 0 ) + { + q_powSpecMsInv[ch] = s_min( q_powSpecMsInv[ch], tmp_q_psi[n][i] ); + move16(); + } } } - minimum_s( tmp_q_powSpec, N_MAX, &q_powSpec[ch] ); - minimum_s( tmp_q_powSpecInv, N_MAX, &tmp_s ); - q_powSpec[ch] = s_min( q_powSpec[ch], tmp_s ); - move16(); FOR( n = 0; n < nSubframes; n++ ) { FOR( i = 0; i < L_subframeTCX; i++ ) { - powerSpecMsInv_fx[ch][n][i] = L_shr( powerSpecMsInv_fx[ch][n][i], sub( tmp_q_psi[n][i], q_powSpec[ch] ) ); - powerSpec_fx[ch][( i + ( n * L_subframeTCX ) )] = L_shr( powerSpec_fx[ch][( i + ( n * L_subframeTCX ) )], sub( tmp_q_powSpec[i], q_powSpec[ch] ) ); + powerSpecMsInv_fx[ch][n][i] = L_shr_sat( powerSpecMsInv_fx[ch][n][i], sub( tmp_q_psi[n][i], q_powSpecMsInv[ch] ) ); + /* Here precision is preserved for powerSpec_fx buffer by storing the fixed Q copy of same buffer in powerSpec_fx_tmp buffer */ + /* powerSpec_fx implementation has separate Q for each index, powerSpec_fx_tmp has all indices in same Q beyond this point */ + powerSpec_fx_tmp[ch][( i + ( n * L_subframeTCX ) )] = L_shr( powerSpec_fx[ch][( i + ( n * L_subframeTCX ) )], sub( tmp_q_powSpec[i + ( n * L_subframeTCX )], q_powSpec[ch] ) ); /* q_powSpec */ move32(); move32(); } @@ -545,11 +559,11 @@ void stereo_mdct_core_enc_fx( nSubframes = NB_DIV; move16(); } - L_subframeTCX = idiv1616( st->hTcxEnc->L_frameTCX, nSubframes ); + L_subframeTCX = idiv1616( st->hTcxEnc->L_frameTCX, nSubframes ); /* Q0 */ IF( st->last_core == ACELP_CORE ) { - L_subframeTCX = add( L_subframeTCX, shr( L_subframeTCX, 2 ) ); + L_subframeTCX = add( L_subframeTCX, shr( L_subframeTCX, 2 ) ); /* Q0 */ } test(); test(); @@ -560,11 +574,11 @@ void stereo_mdct_core_enc_fx( * and quantization (0: tonal, 1: noise-like). * * Detect low pass if present. * *-----------------------------------------------------------*/ - ComputeSpectrumNoiseMeasure_fx( powerSpec_fx[ch], L_subframeTCX, i_mult( st->hTcxEnc->nmStartLine, idiv1616( L_subframeTCX, st->hTcxEnc->L_frameTCX ) ), + ComputeSpectrumNoiseMeasure_fx( powerSpec_fx_tmp[ch], L_subframeTCX, i_mult( st->hTcxEnc->nmStartLine, idiv1616( L_subframeTCX, st->hTcxEnc->L_frameTCX ) ), NE_32( imult3216( st->last_sr_core, st->L_frame ), imult3216( st->sr_core, st->L_frame_past ) ) || NE_16( st->last_core, TCX_20_CORE ), st->hTcxEnc->memQuantZeros, L_subframeTCX ); } - st->hTcxEnc->measuredBwRatio = ONE_IN_Q14; /* No bandwidth limit for the noise filling */ + st->hTcxEnc->measuredBwRatio = ONE_IN_Q14; /* No bandwidth limit for the noise filling Q14*/ move16(); } @@ -586,7 +600,7 @@ void stereo_mdct_core_enc_fx( nSubframes = 1; move16(); } - L_subframeTCX = idiv1616( sts[0]->hTcxEnc->L_frameTCX, nSubframes ); + L_subframeTCX = idiv1616( sts[0]->hTcxEnc->L_frameTCX, nSubframes ); /* Q0 */ FOR( n = 0; n < nSubframes; n++ ) { test(); @@ -594,14 +608,15 @@ void stereo_mdct_core_enc_fx( IF( ( NE_16( hStereoMdct->mdct_stereo_mode[n], hStereoMdct->IGFStereoMode[n] ) || EQ_16( hStereoMdct->mdct_stereo_mode[n], SMDCT_BW_MS ) ) && !hStereoMdct->isSBAStereoMode ) { IGF_ENC_INSTANCE_HANDLE hIGFEnc[CPE_CHANNELS]; - p_powerSpec_fx[0] = powerSpec_fx[0]; - p_powerSpec_fx[1] = powerSpec_fx[1]; + p_powerSpec_fx[0] = powerSpec_fx_tmp[0]; + p_powerSpec_fx[1] = powerSpec_fx_tmp[1]; hIGFEnc[0] = sts[0]->hIGFEnc; hIGFEnc[1] = sts[1]->hIGFEnc; FOR( ch = 0; ch < CPE_CHANNELS; ch++ ) { q_spec = sub( Q31, sts[ch]->hTcxEnc->spectrum_e[n] ); + Word16 q_comm = s_min( sub( Q31, sts[ch]->hTcxEnc->spectrum_e[n] ), s_min( q_powSpec[ch], q_powSpecMsInv[ch] ) ); Word16 n_sb = NB_DIV; move16(); if ( EQ_16( sts[ch]->hTcxEnc->tcxMode, TCX_20 ) ) @@ -609,18 +624,25 @@ void stereo_mdct_core_enc_fx( n_sb = 1; move16(); } - length = idiv1616( sts[ch]->hTcxEnc->L_frameTCX, n_sb ); - IF( GT_16( q_spec, q_powSpec[ch] ) ) + length = idiv1616( sts[ch]->hTcxEnc->L_frameTCX, n_sb ); /* Q0 */ + IF( NE_16( q_spec, q_comm ) ) + { + Scale_sig32( sts[ch]->hTcxEnc->spectrum_fx[n], length, sub( q_comm, q_spec ) ); /* q_powSpec */ + Scale_sig32( inv_spectrum_fx[ch][n], length, sub( q_comm, q_spec ) ); /* q_powSpec */ + sts[ch]->hTcxEnc->spectrum_e[n] = sub( Q31, q_comm ); + move16(); + } + IF( NE_16( q_powSpec[ch], q_comm ) ) { - Scale_sig32( sts[ch]->hTcxEnc->spectrum_fx[n], length, sub( q_powSpec[ch], q_spec ) ); - Scale_sig32( inv_spectrum_fx[ch][n], length, sub( q_powSpec[ch], q_spec ) ); - sts[ch]->hTcxEnc->spectrum_e[n] = sub( Q31, q_powSpec[ch] ); + Scale_sig32( &p_powerSpec_fx[ch][0], L_subframeTCX, sub( q_comm, q_powSpec[ch] ) ); /* q_spec */ + q_powSpec[ch] = q_comm; move16(); } - ELSE + IF( NE_16( q_powSpecMsInv[ch], q_comm ) ) { - Scale_sig32( &p_powerSpec_fx[ch][0], L_subframeTCX, sub( q_spec, q_powSpec[ch] ) ); - Scale_sig32( powerSpecMsInv_fx[ch][0], L_subframeTCX, sub( q_spec, q_powSpec[ch] ) ); + Scale_sig32( powerSpecMsInv_fx[ch][0], L_subframeTCX, sub( q_comm, q_powSpecMsInv[ch] ) ); /* q_spec */ + q_powSpecMsInv[ch] = q_comm; + move16(); } } hIGFEnc[0]->spec_be_igf_e = p_orig_spectrum_e[0]; @@ -628,8 +650,8 @@ void stereo_mdct_core_enc_fx( hIGFEnc[1]->spec_be_igf_e = p_orig_spectrum_e[1]; move16(); ProcessStereoIGF_fx( hStereoMdct, sts, ms_mask, - orig_spectrum_fx, - p_powerSpec_fx, powerSpecMsInv_fx, inv_spectrum_fx, n, hCPE->hCoreCoder[0]->sp_aud_decision0, hCPE->hCoreCoder[0]->element_brate ); + orig_spectrum_fx, sub( Q31, p_orig_spectrum_e[0] ), sub( Q31, p_orig_spectrum_e[1] ), + p_powerSpec_fx, powerSpecMsInv_fx, inv_spectrum_fx, n, hCPE->hCoreCoder[0]->sp_aud_decision0, hCPE->hCoreCoder[0]->element_brate, 0 ); } ELSE { @@ -641,17 +663,22 @@ void stereo_mdct_core_enc_fx( { st->hBstr->ind_list = sts[0]->hBstr->ind_list + sts[0]->hBstr->nb_ind_tot; } - L_subframeTCX = idiv1616( st->hTcxEnc->L_frameTCX, nSubframes ); + L_subframeTCX = idiv1616( st->hTcxEnc->L_frameTCX, nSubframes ); /* Q0 */ Word16 q_spectrum; q_spectrum = sub( Q31, p_orig_spectrum_e[ch] ); IF( st->hIGFEnc ) { q_spectrum = s_min( q_spectrum, sub( Q31, st->hIGFEnc->spec_be_igf_e ) ); } - Scale_sig32( orig_spectrum_fx[ch][n], N_TCX10_MAX, sub( q_spectrum, sub( Q31, p_orig_spectrum_e[ch] ) ) ); q_spectrum = sub( Q31, st->hTcxEnc->spectrum_e[n] ); - ProcessIGF_ivas_fx( st, st->hTcxEnc->spectrum_fx[n], orig_spectrum_fx[ch][n], &q_spectrum, &powerSpec_fx[ch][n * L_subframeTCX], &q_powSpec[ch], st->core == TCX_20_CORE, n, hCPE->hCoreCoder[0]->sp_aud_decision0, 0 ); + + Scale_sig32( orig_spectrum_fx[ch][n], st->hIGFEnc->infoStopLine, sub( q_spectrum, sub( Q31, p_orig_spectrum_e[ch] ) ) ); /* q_spectrum */ +#ifndef MSAN_FIX + ProcessIGF_ivas_fx( st, st->hTcxEnc->spectrum_fx[n], orig_spectrum_fx[ch][n], &q_spectrum, &powerSpec_fx[ch][n * L_subframeTCX], &exp_powerSpec[ch][n * L_subframeTCX], st->core == TCX_20_CORE, n, hCPE->hCoreCoder[0]->sp_aud_decision0, 0 ); +#else + ProcessIGF_ivas_fx( st, N_MAX, st->hTcxEnc->spectrum_fx[n], orig_spectrum_fx[ch][n], &q_spectrum, &powerSpec_fx[ch][n * L_subframeTCX], &exp_powerSpec[ch][n * L_subframeTCX], st->core == TCX_20_CORE, n, hCPE->hCoreCoder[0]->sp_aud_decision0, 0 ); +#endif } } } @@ -681,16 +708,22 @@ void stereo_mdct_core_enc_fx( FOR( n = 0; n < nSubframes; n++ ) { Word16 q_spectrum; - L_subframeTCX = idiv1616( st->hTcxEnc->L_frameTCX, nSubframes ); + L_subframeTCX = idiv1616( st->hTcxEnc->L_frameTCX, nSubframes ); /* Q0 */ q_spectrum = sub( Q31, p_orig_spectrum_e[ch] ); IF( st->hIGFEnc ) { q_spectrum = s_min( q_spectrum, sub( Q31, st->hIGFEnc->spec_be_igf_e ) ); } - Scale_sig32( orig_spectrum_fx[ch][n], N_TCX10_MAX, sub( q_spectrum, sub( Q31, p_orig_spectrum_e[ch] ) ) ); q_spectrum = sub( Q31, st->hTcxEnc->spectrum_e[n] ); - ProcessIGF_ivas_fx( st, st->hTcxEnc->spectrum_fx[n], orig_spectrum_fx[ch][n], &q_spectrum, &powerSpec_fx[ch][n * L_subframeTCX], &q_powSpec[ch], st->core == TCX_20_CORE, n, hCPE->hCoreCoder[0]->sp_aud_decision0, 0 ); + + Scale_sig32( orig_spectrum_fx[ch][n], st->hIGFEnc->infoStopLine, sub( q_spectrum, sub( Q31, p_orig_spectrum_e[ch] ) ) ); /* q_spectrum */ + +#ifndef MSAN_FIX + ProcessIGF_ivas_fx( st, st->hTcxEnc->spectrum_fx[n], orig_spectrum_fx[ch][n], &q_spectrum, &powerSpec_fx[ch][n * L_subframeTCX], &exp_powerSpec[ch][n * L_subframeTCX], st->core == TCX_20_CORE, n, hCPE->hCoreCoder[0]->sp_aud_decision0, 0 ); +#else + ProcessIGF_ivas_fx( st, N_MAX, st->hTcxEnc->spectrum_fx[n], orig_spectrum_fx[ch][n], &q_spectrum, &powerSpec_fx[ch][n * L_subframeTCX], &exp_powerSpec[ch][n * L_subframeTCX], st->core == TCX_20_CORE, n, hCPE->hCoreCoder[0]->sp_aud_decision0, 0 ); +#endif } } } @@ -709,7 +742,7 @@ void stereo_mdct_core_enc_fx( move16(); IF( !hStereoMdct->isSBAStereoMode ) { - stereo_bits = write_stereo_to_bitstream( hStereoMdct, sts, ms_mask, 0, hBstr ); + stereo_bits = write_stereo_to_bitstream_fx( hStereoMdct, sts, ms_mask, 0, hBstr ); /* Q0 */ } ELSE { @@ -731,11 +764,11 @@ void stereo_mdct_core_enc_fx( n_sb = 1; move16(); } - L_subframeTCX = idiv1616( sts[ch]->hTcxEnc->L_frameTCX, n_sb ); + L_subframeTCX = idiv1616( sts[ch]->hTcxEnc->L_frameTCX, n_sb ); /* Q0 */ FOR( n = 0; n <= ( ( sts[ch]->hTcxEnc->tcxMode == TCX_20 ) ? 1 : NB_DIV ) - 1; n++ ) { q_com = L_norm_arr( sts[ch]->hTcxEnc->spectrum_fx[n], L_subframeTCX ); - Scale_sig32( sts[ch]->hTcxEnc->spectrum_fx[n], L_subframeTCX, q_com ); + Scale_sig32( sts[ch]->hTcxEnc->spectrum_fx[n], L_subframeTCX, q_com ); /* Q31 - sts[ch]->hTcxEnc->spectrum_e + q_com */ sts[ch]->hTcxEnc->spectrum_e[n] = sub( sts[ch]->hTcxEnc->spectrum_e[n], q_com ); } } @@ -760,7 +793,7 @@ void stereo_mdct_core_enc_fx( FOR( ch = 0; ch < CPE_CHANNELS; ch++ ) { - sts[ch]->total_brate = imult3216( L_deposit_l( add( sts[ch]->bits_frame_channel, sts[ch]->side_bits_frame_channel ) ), FRAMES_PER_SEC ); + sts[ch]->total_brate = imult3216( L_deposit_l( add( sts[ch]->bits_frame_channel, sts[ch]->side_bits_frame_channel ) ), FRAMES_PER_SEC ); /* Q0 */ move32(); } stereo_bits = add( stereo_bits, SMDCT_NBBITS_SPLIT_RATIO ); diff --git a/lib_enc/ivas_stereo_mdct_igf_enc.c b/lib_enc/ivas_stereo_mdct_igf_enc_fx.c similarity index 89% rename from lib_enc/ivas_stereo_mdct_igf_enc.c rename to lib_enc/ivas_stereo_mdct_igf_enc_fx.c index c200a748caf06abb39b9164a83d085cd4ea0f4c8..851df60d532327c819ce1f4d60abca6127ce0de8 100644 --- a/lib_enc/ivas_stereo_mdct_igf_enc.c +++ b/lib_enc/ivas_stereo_mdct_igf_enc_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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,12 +34,10 @@ #include #include "options.h" #include -#include "prot.h" #include "prot_fx.h" #include "cnst.h" #include "stat_enc.h" #include "ivas_stat_enc.h" -#include "ivas_prot.h" #include "ivas_prot_fx.h" #include "wmc_auto.h" @@ -64,10 +62,10 @@ static Word16 calcCoh_fx( // Q15 const Word32 *sig1_fx, // Q( q_sig ) const Word32 *sig2_fx, // Q( q_sig ) const Word16 q_sig, - const Word16 nSamples, - Word32 *corr, + const Word16 nSamples, /* Q0 */ + Word32 *corr, /* Q31-corr_e */ Word16 *corr_e, - Word16 *predCoeff, + Word16 *predCoeff, /* Q31-predCoeff_e */ Word16 *predCoeff_e ) { Word32 ener1_fx, ener2_fx, cEner_fx, cc_fx; @@ -82,13 +80,13 @@ static Word16 calcCoh_fx( // Q15 move16(); q_cc = q_ener1; move16(); - ener1_fx = dotp_fixed_o( sig1_fx, sig1_fx, nSamples, gB, &q_ener1 ); - ener2_fx = dotp_fixed_o( sig2_fx, sig2_fx, nSamples, gB, &q_ener2 ); - cEner_fx = Mpy_32_32( ener1_fx, ener2_fx ); + ener1_fx = dotp_fixed_o( sig1_fx, sig1_fx, nSamples, gB, &q_ener1 ); /* q_ener1 */ + ener2_fx = dotp_fixed_o( sig2_fx, sig2_fx, nSamples, gB, &q_ener2 ); /* q_ener2 */ + cEner_fx = Mpy_32_32( ener1_fx, ener2_fx ); /* q_ener1+q_ener2-31 */ q_cEner = sub( 62, add( q_ener1, q_ener2 ) ); - cEner_fx = Sqrt32( cEner_fx, &q_cEner ); + cEner_fx = Sqrt32( cEner_fx, &q_cEner ); /* Q31-q_cEner */ q_cEner = sub( Q31, q_cEner ); - cc_fx = dotp_fixed_o( sig1_fx, sig2_fx, nSamples, gB, &q_cc ); + cc_fx = dotp_fixed_o( sig1_fx, sig2_fx, nSamples, gB, &q_cc ); /* q_cc */ IF( corr != NULL ) { @@ -100,7 +98,7 @@ static Word16 calcCoh_fx( // Q15 IF( cEner_fx > 0 ) { - coh_fx = BASOP_Util_Divide3232_Scale( cc_fx, cEner_fx, &coh_e ); + coh_fx = BASOP_Util_Divide3232_Scale( cc_fx, cEner_fx, &coh_e ); /* Q15-coh_e */ coh_e = add( coh_e, sub( q_cEner, q_cc ) ); coh_fx = shl_sat( coh_fx, coh_e ); // Q15 } @@ -111,7 +109,7 @@ static Word16 calcCoh_fx( // Q15 move32(); IF( ener1_fx > 0 ) { - *predCoeff = BASOP_Util_Divide3232_Scale( cc_fx, ener1_fx, predCoeff_e ); + *predCoeff = BASOP_Util_Divide3232_Scale( cc_fx, ener1_fx, predCoeff_e ); /* Q31-predCoeff_e */ move32(); *predCoeff_e = add( *predCoeff_e, sub( q_ener1, q_cc ) ); move16(); @@ -131,12 +129,12 @@ static Word16 calcCoh_fx( // Q15 static void IGF_MsStereoDecision_fx( STEREO_MDCT_BAND_PARAMETERS *sfbParam, H_IGF_GRID hGrid, - const Word32 *specL_fx, - const Word32 *specR_fx, + const Word32 *specL_fx, /* q_spec */ + const Word32 *specR_fx, /* q_spec */ Word16 q_spec, - Word16 *igfStereoMode, /* output*/ - Word16 *msMask, /* output*/ - const Word16 mdct_stereo_mode ) + Word16 *igfStereoMode, /* output Q0*/ + Word16 *msMask, /* output Q0*/ + const Word16 mdct_stereo_mode /* Q0 */ ) { Word16 sfb; Word16 msMaskTrueSomewhere, msMaskFalseSomewhere; @@ -150,18 +148,18 @@ static void IGF_MsStereoDecision_fx( if ( EQ_16( mdct_stereo_mode, SMDCT_MS_FULL ) ) { - thresh = 13762; /* lower threshold if core is already MS */ + thresh = 13762; /* lower threshold if core is already MS TARGET_COH_THRESHOLD_FX*(0.7 in Q15)*/ move16(); } FOR( tile_idx = 0; tile_idx < hGrid->nTiles; tile_idx++ ) { - strt_cpy = hGrid->sbWrap[tile_idx]; + strt_cpy = hGrid->sbWrap[tile_idx]; /* Q0 */ move16(); FOR( sfb = hGrid->sfbWrap[tile_idx]; sfb < hGrid->sfbWrap[tile_idx + 1]; sfb++ ) { - Word16 width = sub( hGrid->swb_offset[sfb + 1], hGrid->swb_offset[sfb] ); + Word16 width = sub( hGrid->swb_offset[sfb + 1], hGrid->swb_offset[sfb] ); /* Q0 */ Word32 cc_src_fx, cc_target_fx; Word16 cc_src_e, cc_target_e; Word16 pc_target_fx, pc_src_fx; @@ -177,10 +175,10 @@ static void IGF_MsStereoDecision_fx( Word16 coh_src = calcCoh_fx( &specL_fx[strt_cpy], &specR_fx[strt_cpy], q_spec, width, &cc_src_fx, &cc_src_e, &pc_src_fx, &pc_src_e ); Word16 coh_target = calcCoh_fx( &specL_fx[hGrid->swb_offset[sfb]], &specR_fx[hGrid->swb_offset[sfb]], q_spec, width, &cc_target_fx, &cc_target_e, &pc_target_fx, &pc_target_e ); - tmp1_e = BASOP_Util_Add_MantExp( pc_target_fx, pc_target_e, negate( pc_src_fx ), pc_src_e, &tmp1 ); - tmp2_e = BASOP_Util_Add_MantExp( pc_target_fx, pc_target_e, -16384, 1, &tmp2 ); + tmp1_e = BASOP_Util_Add_MantExp( pc_target_fx, pc_target_e, negate( pc_src_fx ), pc_src_e, &tmp1 ); /* Q15-tmp1_e */ + tmp2_e = BASOP_Util_Add_MantExp( pc_target_fx, pc_target_e, -16384, 1, &tmp2 ); /* Q15-tmp2_e */ - strt_cpy = add( strt_cpy, width ); + strt_cpy = add( strt_cpy, width ); /* Q0 */ IF( GT_16( abs_s( coh_target ), thresh ) ) { /* target is very coherent */ @@ -236,14 +234,14 @@ static void IGF_MsStereoDecision_fx( case IGF_PATCH_LR: msMask[sfb] = 0; move16(); - numMsMaskFalse = add( numMsMaskFalse, 1 ); + numMsMaskFalse = add( numMsMaskFalse, 1 ); /* Q0 */ msMaskFalseSomewhere = 1; move16(); break; case IGF_PATCH_MS: msMask[sfb] = 1; move16(); - numMsMaskTrue = add( numMsMaskTrue, 1 ); + numMsMaskTrue = add( numMsMaskTrue, 1 ); /* Q0 */ msMaskTrueSomewhere = 1; move16(); break; @@ -302,14 +300,14 @@ static void IGF_MsStereoDecision_fx( void IGFEncStereoEncoder_fx( STEREO_MDCT_BAND_PARAMETERS *sfbParam, /* i/o: sfb parameters for the right channel */ const IGF_ENC_INSTANCE_HANDLE hIGFEnc, /* i : IGF handle */ - const Word32 *mdctSpectrumL_fx, /* i : left spectrum */ - const Word32 *mdctSpectrumR_fx, /* i : right spectrum */ + const Word32 *mdctSpectrumL_fx, /* i : left spectrum q_mdctSpectrum*/ + const Word32 *mdctSpectrumR_fx, /* i : right spectrum q_mdctSpectrum*/ Word16 q_mdctSpectrum, - Word16 *msMask, /* i/o: MS mask */ - Word16 *igfStereoMode, /* o : IGF stereo mode */ - const Word16 mdct_stereo_mode, /* i : MDCT stereo mode */ - const Word16 isTCX20, /* i : flag for indicating TCX20 */ - const Word16 isTransition /* i : flag for transtition */ + Word16 *msMask, /* i/o: MS mask Q0*/ + Word16 *igfStereoMode, /* o : IGF stereo mode Q0*/ + const Word16 mdct_stereo_mode, /* i : MDCT stereo mode Q0*/ + const Word16 isTCX20, /* i : flag for indicating TCX20 Q0*/ + const Word16 isTransition /* i : flag for transtition Q0*/ ) { Word16 igfGridIdx; diff --git a/lib_enc/ivas_stereo_mdct_stereo_enc.c b/lib_enc/ivas_stereo_mdct_stereo_enc_fx.c similarity index 83% rename from lib_enc/ivas_stereo_mdct_stereo_enc.c rename to lib_enc/ivas_stereo_mdct_stereo_enc_fx.c index b69883930fbdca711d76911d6d5aef4cfc62c2a5..a61b2b0106170638a85e848080f6176e5ce661d5 100644 --- a/lib_enc/ivas_stereo_mdct_stereo_enc.c +++ b/lib_enc/ivas_stereo_mdct_stereo_enc_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other @@ -35,10 +35,8 @@ #include "options.h" #include #include "ivas_cnst.h" -#include "ivas_prot.h" #include "ivas_prot_fx.h" #include "prot_fx.h" -#include "prot.h" #include "prot_fx_enc.h" #include "ivas_rom_com.h" #include "ivas_rom_com_fx.h" @@ -77,7 +75,7 @@ static void MsStereoDecision_fx( STEREO_MDCT_BAND_PARAMETERS *sfbParam, Word32 * static void dft_ana_init_fx( DFT_ANA_HANDLE hDft_ana, /*i : DFT analysis handle */ - const Word32 input_Fs /*i : Input sampling frequency */ + const Word32 input_Fs /*i : Input sampling frequency Q0*/ ) { hDft_ana->N = extract_l( Mpy_32_16_1( input_Fs, 656 /* STEREO_DFT_HOP_MAX_ENC / 48000 in Q15 */ ) ); @@ -89,29 +87,29 @@ static void dft_ana_init_fx( hDft_ana->dft_zp = extract_l( Mpy_32_16_1( input_Fs, 185 /* STEREO_DFT_ZP_MAX_ENC / 48000 in Q15 */ ) ); move16(); - hDft_ana->dft_trigo_32k_fx = dft_trigo_32k_fx; + hDft_ana->dft_trigo_32k_fx = dft_trigo_32k_fx; /* Q15 */ IF( EQ_32( input_Fs, 16000 ) ) { - hDft_ana->dft_trigo_fx = dft_trigo_32k_fx; + hDft_ana->dft_trigo_fx = dft_trigo_32k_fx; /* Q15 */ hDft_ana->dft_trigo_step = STEREO_DFT_TRIGO_SRATE_16k_STEP; move16(); - hDft_ana->win_ana_fx = win_ana_16k_fx; + hDft_ana->win_ana_fx = win_ana_16k_fx; /* Q15 */ } ELSE IF( EQ_32( input_Fs, 32000 ) ) { - hDft_ana->dft_trigo_fx = dft_trigo_32k_fx; + hDft_ana->dft_trigo_fx = dft_trigo_32k_fx; /* Q15 */ hDft_ana->dft_trigo_step = STEREO_DFT_TRIGO_SRATE_32k_STEP; move16(); - hDft_ana->win_ana_fx = win_ana_32k_fx; + hDft_ana->win_ana_fx = win_ana_32k_fx; /* Q15 */ } ELSE { assert( input_Fs == 48000 ); - hDft_ana->dft_trigo_fx = dft_trigo_48k_fx; + hDft_ana->dft_trigo_fx = dft_trigo_48k_fx; /* Q15 */ hDft_ana->dft_trigo_step = STEREO_DFT_TRIGO_SRATE_48k_STEP; move16(); - hDft_ana->win_ana_fx = win_ana_48k_fx; + hDft_ana->win_ana_fx = win_ana_48k_fx; /* Q15 */ } return; @@ -139,7 +137,7 @@ static void write_itd_data_fx( IF( hItd->itd_fx[k_offset] != 0 ) { - itd = hItd->itd_index[k_offset]; + itd = hItd->itd_index[k_offset]; /* Q0 */ IF( GT_16( itd, 255 ) ) { itd = sub( itd, 256 ); @@ -184,14 +182,14 @@ static void write_itd_data_fx( void stereo_coder_tcx_fx( STEREO_MDCT_ENC_DATA_HANDLE hStereoMdct, /* i/o: Stereo MDCT encoder structure */ Encoder_State **sts, /* i/o: encoder state structure */ - Word16 ms_mask[NB_DIV][MAX_SFB], /* i : bandwise MS mask */ + Word16 ms_mask[NB_DIV][MAX_SFB], /* i : bandwise MS mask Q0*/ Word32 *mdst_spectrum_fx[CPE_CHANNELS][NB_DIV], /* i/o: MDST spectrum */ // Q( q_spec ) (same as spectrum buffer in hTcxEnc) Word32 *inv_spectrum_fx[CPE_CHANNELS][NB_DIV], /* i/o: inverse spectrum */ // Q( q_spec ) (same as spectrum buffer in hTcxEnc) Word32 *inv_mdst_spectrum_fx[CPE_CHANNELS][NB_DIV], /* i/o: inverse MDST spectrum */ // Q( q_spec ) (same as spectrum buffer in hTcxEnc) - const Word16 mct_on, /* i : flag mct block (1) or stereo (0) */ + const Word16 mct_on, /* i : flag mct block (1) or stereo (0) Q0*/ Word16 q_spec ) { STEREO_MDCT_BAND_PARAMETERS *sfbConf = NULL; @@ -208,7 +206,7 @@ void stereo_coder_tcx_fx( set16_fx( nAvailBitsMS, 0, NB_DIV ); nSubframes = ( sts[0]->core == TCX_20_CORE && sts[1]->core == TCX_20_CORE ) ? 1 : NB_DIV; - L_frameTCX = sts[0]->hTcxEnc->L_frameTCX / nSubframes; + L_frameTCX = idiv1616( sts[0]->hTcxEnc->L_frameTCX, nSubframes ); set16_fx( &ms_mask[0][0], 0, MAX_SFB ); set16_fx( &ms_mask[1][0], 0, MAX_SFB ); @@ -224,7 +222,7 @@ void stereo_coder_tcx_fx( hStereoMdct->global_ild[k] = s_max( 1, s_min( SMDCT_ILD_RANGE - 1, round_fx( L_mult( SMDCT_ILD_RANGE, nonQNrgRatio_fx[k] ) ) ) ); move16(); - nrgRatio_fx[k] = L_deposit_h( BASOP_Util_Divide1616_Scale( sub( SMDCT_ILD_RANGE, hStereoMdct->global_ild[k] ), hStereoMdct->global_ild[k], &nrgRatio_e[k] ) ); + nrgRatio_fx[k] = L_deposit_h( BASOP_Util_Divide1616_Scale( sub( SMDCT_ILD_RANGE, hStereoMdct->global_ild[k] ), hStereoMdct->global_ild[k], &nrgRatio_e[k] ) ); /* Q31-nrgRatio_e[k] */ move32(); /*nonQNrgRatio[k] = max( 0.5f / SMDCT_ILD_RANGE, min( ( SMDCT_ILD_RANGE - 0.5f ) / SMDCT_ILD_RANGE, nonQNrgRatio[k] ) ); nonQNrgRatio[k] = 1.0f / nonQNrgRatio[k] - 1.0f;*/ @@ -233,11 +231,11 @@ void stereo_coder_tcx_fx( } ELSE { - nonQNrgRatio_fx[0] = nonQNrgRatio_fx[1] = GetChannelEnergyRatio_fx( sts, 0, nSubframes - 1, 1 ); + nonQNrgRatio_fx[0] = nonQNrgRatio_fx[1] = GetChannelEnergyRatio_fx( sts, 0, nSubframes - 1, 1 ); /* Q15 */ move16(); hStereoMdct->global_ild[0] = s_max( 1, s_min( SMDCT_ILD_RANGE - 1, round_fx( L_mult( SMDCT_ILD_RANGE, nonQNrgRatio_fx[0] ) ) ) ); move16(); - nrgRatio_fx[0] = nrgRatio_fx[1] = L_deposit_h( BASOP_Util_Divide1616_Scale( sub( SMDCT_ILD_RANGE, hStereoMdct->global_ild[0] ), hStereoMdct->global_ild[0], &nrgRatio_e[0] ) ); /* nrgRatio = nrg[1]/nrg[0] */ + nrgRatio_fx[0] = nrgRatio_fx[1] = L_deposit_h( BASOP_Util_Divide1616_Scale( sub( SMDCT_ILD_RANGE, hStereoMdct->global_ild[0] ), hStereoMdct->global_ild[0], &nrgRatio_e[0] ) ); /* nrgRatio = nrg[1]/nrg[0] (Q31-nrgRatio_e[0])*/ move32(); nrgRatio_e[1] = nrgRatio_e[0]; move16(); @@ -250,24 +248,24 @@ void stereo_coder_tcx_fx( { IF( EQ_16( BASOP_Util_Cmp_Mant32Exp( nrgRatio_fx[k], nrgRatio_e[k], ONE_IN_Q27, 4 ), 1 ) && LT_16( k, ( EQ_16( sts[1]->core, TCX_20_CORE ) ? 1 : NB_DIV ) ) ) { - L_frameTCX = add( sts[1]->hTcxEnc->L_frameTCX, ( ( sts[1]->last_core == 0 ) ? shr( sts[1]->hTcxEnc->L_frameTCX, 2 ) : 0 ) ); - L_frameTCX = idiv1616( L_frameTCX, ( sts[1]->core == TCX_20_CORE ) ? 1 : NB_DIV ); + L_frameTCX = add( sts[1]->hTcxEnc->L_frameTCX, ( ( sts[1]->last_core == 0 ) ? shr( sts[1]->hTcxEnc->L_frameTCX, 2 ) : 0 ) ); /* Q0 */ + L_frameTCX = idiv1616( L_frameTCX, ( sts[1]->core == TCX_20_CORE ) ? 1 : NB_DIV ); /* Q0 */ e_tmp = nrgRatio_e[k]; - tmp = Inv16( extract_h( nrgRatio_fx[k] ), &e_tmp ); - tmp = shl( tmp, e_tmp ); + tmp = Inv16( extract_h( nrgRatio_fx[k] ), &e_tmp ); /* Q15-e_tmp */ + tmp = shl( tmp, e_tmp ); /* Q15 */ - v_multc_fixed_16( sts[1]->hTcxEnc->spectrum_fx[k], tmp, sts[1]->hTcxEnc->spectrum_fx[k], L_frameTCX ); - v_multc_fixed_16( mdst_spectrum_fx[1][k], tmp, mdst_spectrum_fx[1][k], L_frameTCX ); + v_multc_fixed_16( sts[1]->hTcxEnc->spectrum_fx[k], tmp, sts[1]->hTcxEnc->spectrum_fx[k], L_frameTCX ); /* Q31-spectrum_e[k] */ + v_multc_fixed_16( mdst_spectrum_fx[1][k], tmp, mdst_spectrum_fx[1][k], L_frameTCX ); /* q_spec */ } ELSE IF( EQ_16( BASOP_Util_Cmp_Mant32Exp( nrgRatio_fx[k], nrgRatio_e[k], ONE_IN_Q27, 4 ), -1 ) && LT_16( k, EQ_16( sts[0]->core, TCX_20_CORE ) ? 1 : NB_DIV ) ) { - L_frameTCX = add( sts[0]->hTcxEnc->L_frameTCX, EQ_16( sts[0]->last_core, 0 ) ? shr( sts[0]->hTcxEnc->L_frameTCX, 2 ) : 0 ); - L_frameTCX = idiv1616( L_frameTCX, ( sts[0]->core == TCX_20_CORE ) ? 1 : NB_DIV ); + L_frameTCX = add( sts[0]->hTcxEnc->L_frameTCX, EQ_16( sts[0]->last_core, 0 ) ? shr( sts[0]->hTcxEnc->L_frameTCX, 2 ) : 0 ); /* Q0 */ + L_frameTCX = idiv1616( L_frameTCX, ( sts[0]->core == TCX_20_CORE ) ? 1 : NB_DIV ); /* Q0 */ /* This operation is resulting in some high MLDs in fixed point. */ - v_multc_fixed_16( sts[0]->hTcxEnc->spectrum_fx[k], extract_l( L_shr( nrgRatio_fx[k], 16 - nrgRatio_e[k] ) ), sts[0]->hTcxEnc->spectrum_fx[k], L_frameTCX ); - v_multc_fixed_16( mdst_spectrum_fx[0][k], extract_l( L_shr( nrgRatio_fx[k], 16 - nrgRatio_e[k] ) ), mdst_spectrum_fx[0][k], L_frameTCX ); + v_multc_fixed_16( sts[0]->hTcxEnc->spectrum_fx[k], extract_l( L_shr( nrgRatio_fx[k], 16 - nrgRatio_e[k] ) ), sts[0]->hTcxEnc->spectrum_fx[k], L_frameTCX ); /* Q31-spectrum_e[k] */ + v_multc_fixed_16( mdst_spectrum_fx[0][k], extract_l( L_shr( nrgRatio_fx[k], 16 - nrgRatio_e[k] ) ), mdst_spectrum_fx[0][k], L_frameTCX ); /* q_spec */ } } } @@ -352,9 +350,9 @@ void stereo_coder_tcx_fx( FOR( sfb--; sfb < sfbConf->nBandsStereoCore; sfb++ ) /* start one SFB early for the fade-in */ { - const Word16 startLine = sfbConf->sfbOffset[sfb]; + const Word16 startLine = sfbConf->sfbOffset[sfb]; /* Q0 */ move16(); - const Word16 endLine = sfbConf->sfbOffset[sfb + 1]; + const Word16 endLine = sfbConf->sfbOffset[sfb + 1]; /* Q0 */ move16(); const Word16 sfbWidth = sub( endLine, startLine ); @@ -362,9 +360,9 @@ void stereo_coder_tcx_fx( move16(); move16(); - nrgRatio_fx[0] = sum2_32_fx( &sts[0]->hTcxEnc->spectrum_fx[k][startLine], sfbWidth, &nrgRatio_e[0] ); + nrgRatio_fx[0] = sum2_32_fx( &sts[0]->hTcxEnc->spectrum_fx[k][startLine], sfbWidth, &nrgRatio_e[0] ); /* Q31-nrgRatio_e[0] */ move32(); - nrgRatio_fx[1] = sum2_32_fx( &sts[1]->hTcxEnc->spectrum_fx[k][startLine], sfbWidth, &nrgRatio_e[1] ); + nrgRatio_fx[1] = sum2_32_fx( &sts[1]->hTcxEnc->spectrum_fx[k][startLine], sfbWidth, &nrgRatio_e[1] ); /* Q31-nrgRatio_e[1] */ move32(); test(); @@ -373,29 +371,29 @@ void stereo_coder_tcx_fx( Word32 tmp_fx; Word16 tmp_e; tmp_e = sub( Q31, q_spec ); - tmp_fx = sum2_32_fx( &mdst_spectrum_fx[0][k][startLine], sfbWidth, &tmp_e ); - nrgRatio_fx[0] = BASOP_Util_Add_Mant32Exp( nrgRatio_fx[0], nrgRatio_e[0], tmp_fx, tmp_e, &nrgRatio_e[0] ); + tmp_fx = sum2_32_fx( &mdst_spectrum_fx[0][k][startLine], sfbWidth, &tmp_e ); /* Q31-tmp_e */ + nrgRatio_fx[0] = BASOP_Util_Add_Mant32Exp( nrgRatio_fx[0], nrgRatio_e[0], tmp_fx, tmp_e, &nrgRatio_e[0] ); /* Q31-nrgRatio_e[0] */ tmp_e = sub( Q31, q_spec ); - tmp_fx = sum2_32_fx( &mdst_spectrum_fx[1][k][startLine], sfbWidth, &tmp_e ); - nrgRatio_fx[1] = BASOP_Util_Add_Mant32Exp( nrgRatio_fx[1], nrgRatio_e[1], tmp_fx, tmp_e, &nrgRatio_e[1] ); + tmp_fx = sum2_32_fx( &mdst_spectrum_fx[1][k][startLine], sfbWidth, &tmp_e ); /* Q31-tmp_e */ + nrgRatio_fx[1] = BASOP_Util_Add_Mant32Exp( nrgRatio_fx[1], nrgRatio_e[1], tmp_fx, tmp_e, &nrgRatio_e[1] ); /* Q31-nrgRatio_e[1] */ } IF( ( nrgRatio_fx[0] > 0 ) && ( nrgRatio_fx[1] > 0 ) && BASOP_Util_Cmp_Mant32Exp( nrgRatio_fx[0], nrgRatio_e[0], nrgRatio_fx[1], nrgRatio_e[1] ) ) { Word16 fTemp_e, tmp_e; - Word32 fTemp_fx = BASOP_Util_Add_Mant32Exp( nrgRatio_fx[0], nrgRatio_e[0], nrgRatio_fx[1], nrgRatio_e[1], &fTemp_e ); + Word32 fTemp_fx = BASOP_Util_Add_Mant32Exp( nrgRatio_fx[0], nrgRatio_e[0], nrgRatio_fx[1], nrgRatio_e[1], &fTemp_e ); /* Q31-fTemp_e */ fTemp_e = sub( fTemp_e, 1 ); - nrgRatio_fx[0] = BASOP_Util_Divide3232_Scale_cadence( fTemp_fx, nrgRatio_fx[0], &tmp_e ); + nrgRatio_fx[0] = BASOP_Util_Divide3232_Scale_cadence( fTemp_fx, nrgRatio_fx[0], &tmp_e ); /* Q31 - tmp_e - fTemp_e + nrgRatio_e[0] */ move32(); nrgRatio_e[0] = add( tmp_e, sub( fTemp_e, nrgRatio_e[0] ) ); move16(); - nrgRatio_fx[0] = Sqrt32( nrgRatio_fx[0], &nrgRatio_e[0] ); + nrgRatio_fx[0] = Sqrt32( nrgRatio_fx[0], &nrgRatio_e[0] ); /* Q31-nrgRatio_e[0] */ move32(); - nrgRatio_fx[1] = BASOP_Util_Divide3232_Scale_cadence( fTemp_fx, nrgRatio_fx[1], &tmp_e ); + nrgRatio_fx[1] = BASOP_Util_Divide3232_Scale_cadence( fTemp_fx, nrgRatio_fx[1], &tmp_e ); /* Q31 - tmp_e - fTemp_e + nrgRatio_e[1] */ move32(); nrgRatio_e[1] = add( tmp_e, sub( fTemp_e, nrgRatio_e[1] ) ); move16(); - nrgRatio_fx[1] = Sqrt32( nrgRatio_fx[1], &nrgRatio_e[1] ); + nrgRatio_fx[1] = Sqrt32( nrgRatio_fx[1], &nrgRatio_e[1] ); /* Q31-nrgRatio_e[1] */ move32(); nrgRatio_fx[0] = L_max( ONE_IN_Q27, L_shl_sat( nrgRatio_fx[0], sub( nrgRatio_e[0], 2 ) ) ); // max( 0.25f, min( 4.f, nrgRatio[0] ) ); @@ -409,16 +407,16 @@ void stereo_coder_tcx_fx( IF( ( LT_16( sfbWidth, 12 ) && LT_16( add( sfb, 1 ), sfbConf->nBandsStereoCore ) ) || GT_32( sts[0]->element_brate, IVAS_48k ) ) /* attenuate ILD alignment in the first SFB or at 64k */ { - nrgRatio_fx[0] = BASOP_Util_fPow( nrgRatio_fx[0], nrgRatio_e[0], ONE_IN_Q29, 0, &nrgRatio_e[0] ); + nrgRatio_fx[0] = BASOP_Util_fPow( nrgRatio_fx[0], nrgRatio_e[0], ONE_IN_Q29, 0, &nrgRatio_e[0] ); /* Q31-nrgRatio_e[0] */ move32(); - nrgRatio_fx[1] = BASOP_Util_fPow( nrgRatio_fx[1], nrgRatio_e[1], ONE_IN_Q29, 0, &nrgRatio_e[1] ); + nrgRatio_fx[1] = BASOP_Util_fPow( nrgRatio_fx[1], nrgRatio_e[1], ONE_IN_Q29, 0, &nrgRatio_e[1] ); /* Q31-nrgRatio_e[1] */ move32(); } ELSE { - nrgRatio_fx[0] = Sqrt32( nrgRatio_fx[0], &nrgRatio_e[0] ); + nrgRatio_fx[0] = Sqrt32( nrgRatio_fx[0], &nrgRatio_e[0] ); /* Q31-nrgRatio_e[0] */ move32(); - nrgRatio_fx[1] = Sqrt32( nrgRatio_fx[1], &nrgRatio_e[1] ); + nrgRatio_fx[1] = Sqrt32( nrgRatio_fx[1], &nrgRatio_e[1] ); /* Q31-nrgRatio_e[1] */ move32(); } @@ -428,15 +426,15 @@ void stereo_coder_tcx_fx( move32(); - v_multc_fixed( &sts[0]->hTcxEnc->spectrum_fx[k][startLine], nrgRatio_fx[0], &sts[0]->hTcxEnc->spectrum_fx[k][startLine], sfbWidth ); - v_multc_fixed( &mdst_spectrum_fx[0][k][startLine], nrgRatio_fx[0], &mdst_spectrum_fx[0][k][startLine], sfbWidth ); - scale_sig32( &sts[0]->hTcxEnc->spectrum_fx[k][startLine], sfbWidth, Q1 ); // Scaling back to q_spec - scale_sig32( &mdst_spectrum_fx[0][k][startLine], sfbWidth, Q1 ); // Scaling back to q_spec + v_multc_fixed( &sts[0]->hTcxEnc->spectrum_fx[k][startLine], nrgRatio_fx[0], &sts[0]->hTcxEnc->spectrum_fx[k][startLine], sfbWidth ); /* q_spec+30-31 */ + v_multc_fixed( &mdst_spectrum_fx[0][k][startLine], nrgRatio_fx[0], &mdst_spectrum_fx[0][k][startLine], sfbWidth ); /* q_spec+30-31 */ + scale_sig32( &sts[0]->hTcxEnc->spectrum_fx[k][startLine], sfbWidth, Q1 ); // Scaling back to q_spec + scale_sig32( &mdst_spectrum_fx[0][k][startLine], sfbWidth, Q1 ); // Scaling back to q_spec - v_multc_fixed( &sts[1]->hTcxEnc->spectrum_fx[k][startLine], nrgRatio_fx[1], &sts[1]->hTcxEnc->spectrum_fx[k][startLine], sfbWidth ); - v_multc_fixed( &mdst_spectrum_fx[1][k][startLine], nrgRatio_fx[1], &mdst_spectrum_fx[1][k][startLine], sfbWidth ); - scale_sig32( &sts[1]->hTcxEnc->spectrum_fx[k][startLine], sfbWidth, Q1 ); // Scaling back to q_spec - scale_sig32( &mdst_spectrum_fx[1][k][startLine], sfbWidth, Q1 ); // Scaling back to q_spec + v_multc_fixed( &sts[1]->hTcxEnc->spectrum_fx[k][startLine], nrgRatio_fx[1], &sts[1]->hTcxEnc->spectrum_fx[k][startLine], sfbWidth ); /* q_spec+30-31 */ + v_multc_fixed( &mdst_spectrum_fx[1][k][startLine], nrgRatio_fx[1], &mdst_spectrum_fx[1][k][startLine], sfbWidth ); /* q_spec+30-31 */ + scale_sig32( &sts[1]->hTcxEnc->spectrum_fx[k][startLine], sfbWidth, Q1 ); // Scaling back to q_spec + scale_sig32( &mdst_spectrum_fx[1][k][startLine], sfbWidth, Q1 ); // Scaling back to q_spec } } } @@ -445,30 +443,30 @@ void stereo_coder_tcx_fx( set16_fx( &ms_mask[k][0], 0, MAX_SFB ); IF( mct_on ) { - nAvailBitsMS[k] = shl( sts[0]->bits_frame_channel, 1 ); + nAvailBitsMS[k] = shl( sts[0]->bits_frame_channel, 1 ); /* Q0 */ move16(); } ELSE { - nAvailBitsMS[k] = sts[0]->bits_frame_nominal; + nAvailBitsMS[k] = sts[0]->bits_frame_nominal; /* Q0 */ move16(); } - nAvailBitsMS[k] = sub( nAvailBitsMS[k], add( sts[0]->side_bits_frame_channel, sts[1]->side_bits_frame_channel ) ); + nAvailBitsMS[k] = sub( nAvailBitsMS[k], add( sts[0]->side_bits_frame_channel, sts[1]->side_bits_frame_channel ) ); /* Q0 */ move16(); IF( EQ_16( nSubframes, 2 ) ) { - nAvailBitsMS[k] = sub( nAvailBitsMS[k], OFFSET_BITS_TCX10 ); + nAvailBitsMS[k] = sub( nAvailBitsMS[k], OFFSET_BITS_TCX10 ); /* Q0 */ move16(); } ELSE { - nAvailBitsMS[k] = sub( nAvailBitsMS[k], OFFSET_BITS_TCX20 ); + nAvailBitsMS[k] = sub( nAvailBitsMS[k], OFFSET_BITS_TCX20 ); /* Q0 */ move16(); } - nAvailBitsMS[k] = idiv1616( nAvailBitsMS[k], nSubframes ); + nAvailBitsMS[k] = idiv1616( nAvailBitsMS[k], nSubframes ); /* Q0 */ move16(); MsStereoDecision_fx( sfbConf, sts[0]->hTcxEnc->spectrum_fx[k], sts[1]->hTcxEnc->spectrum_fx[k], inv_spectrum_fx[0][k], inv_spectrum_fx[1][k], q_spec, &hStereoMdct->mdct_stereo_mode[k], &ms_mask[k][0], nAvailBitsMS[k] ); @@ -512,21 +510,21 @@ void stereo_coder_tcx_fx( FOR( k = 0; k < nSubframes; k++ ) { sfbConf = EQ_16( sts[0]->core, TCX_20_CORE ) ? &hStereoMdct->stbParamsTCX20 : &hStereoMdct->stbParamsTCX10; - ms_bands[k] = sum_s( ms_mask[k], sfbConf->nBandsStereoCore ); + ms_bands[k] = sum_s( ms_mask[k], sfbConf->nBandsStereoCore ); /* Q0 */ move16(); - sw_uncorr[k] = sub( 32767, div_s( ms_bands[k], sfbConf->nBandsStereoCore ) ); + sw_uncorr[k] = sub( 32767 /*Q15*/, div_s( ms_bands[k], sfbConf->nBandsStereoCore ) ); /* Q15 */ move16(); } IF( EQ_16( sts[0]->core, TCX_20_CORE ) ) { - sw_uncorr_mean = sw_uncorr[0]; + sw_uncorr_mean = sw_uncorr[0]; /* Q15 */ move16(); } ELSE { - sw_uncorr_mean = add( shr( sw_uncorr[0], 1 ), shr( sw_uncorr[1], 1 ) ); + sw_uncorr_mean = add( shr( sw_uncorr[0], 1 ), shr( sw_uncorr[1], 1 ) ); /* Q15 */ } - hStereoMdct->sw_uncorr = extract_l( GT_16( sw_uncorr_mean, 19661 ) ); + hStereoMdct->sw_uncorr = extract_l( GT_16( sw_uncorr_mean, 19661 /*0.6 in Q15*/ ) ); move16(); } @@ -543,13 +541,13 @@ void stereo_coder_tcx_fx( void ms_processing_fx( STEREO_MDCT_ENC_DATA_HANDLE hStereoMdct, /* i/o: Stereo MDCT encoder structure */ Encoder_State **sts, /* i/o: Encoder state structure */ - Word16 ms_mask[NB_DIV][MAX_SFB], /* i : bandwise MS mask */ - const int16_t iSubframe, /* i : subframe number */ + Word16 ms_mask[NB_DIV][MAX_SFB], /* i : bandwise MS mask Q0*/ + const Word16 iSubframe, /* i : subframe number Q0*/ Word32 x_0_fx[], /* i/o: spectrum 1 */ // Q( q_x ) Word32 x_1_fx[], /* i/o: spectrum 1 */ // Q( q_x ) - Word16 maxSfb /* i : number of stereo frequency bands*/ + Word16 maxSfb /* i : number of stereo frequency bands Q0*/ ) { Word16 sfb; @@ -565,7 +563,7 @@ void ms_processing_fx( if ( EQ_16( maxSfb, -1 ) ) { - maxSfb = sfbConf->sfbCnt; + maxSfb = sfbConf->sfbCnt; /* Q0 */ move16(); } @@ -589,8 +587,8 @@ void ms_processing_fx( void ms_inv_mask_processing_fx( STEREO_MDCT_ENC_DATA_HANDLE hStereoMdct, /* i/o: Stereo MDCT encoder structure */ Encoder_State **sts, /* i/o: Encoder state structure */ - Word16 ms_mask[NB_DIV][MAX_SFB], /* i : bandwise MS mask */ - const Word16 iSubframe, /* i : subframe number */ + Word16 ms_mask[NB_DIV][MAX_SFB], /* i : bandwise MS mask Q0*/ + const Word16 iSubframe, /* i : subframe number Q0*/ const Word32 x_0_fx[], /* i : spectrum 1 */ // Q( q_x ) const Word32 x_1_fx[], @@ -599,7 +597,7 @@ void ms_inv_mask_processing_fx( /* o : inverse spectrum 1 */ // Q( q_x ) Word32 x_inv_1_fx[], /* o : inverse spectrum 2 */ // Q( q_x ) - Word16 maxSfb /* i : number of stereo frequency bands*/ + Word16 maxSfb /* i : number of stereo frequency bands Q0*/ ) { Word16 sfb; @@ -607,7 +605,7 @@ void ms_inv_mask_processing_fx( Word16 nSubframes, L_subframeTCX; nSubframes = ( sts[0]->hTcxEnc->tcxMode == TCX_20 ) ? 1 : NB_DIV; - L_subframeTCX = idiv1616( sts[0]->hTcxEnc->L_frameTCX, nSubframes ); + L_subframeTCX = idiv1616( sts[0]->hTcxEnc->L_frameTCX, nSubframes ); /* Q0 */ sfbConf = ( sts[0]->core == TCX_20_CORE ) ? &hStereoMdct->stbParamsTCX20 : &hStereoMdct->stbParamsTCX10; IF( EQ_16( sts[0]->last_core, ACELP_CORE ) ) @@ -618,14 +616,14 @@ void ms_inv_mask_processing_fx( IF( EQ_16( maxSfb, -1 ) ) { - maxSfb = sfbConf->sfbCnt; + maxSfb = sfbConf->sfbCnt; /* Q0 */ move16(); } FOR( sfb = 0; sfb < maxSfb; sfb++ ) { - Copy32( &x_0_fx[sfbConf->sfbOffset[sfb]], &x_inv_0_fx[sfbConf->sfbOffset[sfb]], sfbConf->sfbOffset[sfb + 1] - sfbConf->sfbOffset[sfb] ); - Copy32( &x_1_fx[sfbConf->sfbOffset[sfb]], &x_inv_1_fx[sfbConf->sfbOffset[sfb]], sfbConf->sfbOffset[sfb + 1] - sfbConf->sfbOffset[sfb] ); + Copy32( &x_0_fx[sfbConf->sfbOffset[sfb]], &x_inv_0_fx[sfbConf->sfbOffset[sfb]], sfbConf->sfbOffset[sfb + 1] - sfbConf->sfbOffset[sfb] ); /* q_x */ + Copy32( &x_1_fx[sfbConf->sfbOffset[sfb]], &x_inv_1_fx[sfbConf->sfbOffset[sfb]], sfbConf->sfbOffset[sfb + 1] - sfbConf->sfbOffset[sfb] ); /* q_x */ IF( EQ_16( ms_mask[iSubframe][sfb], 0 ) ) { @@ -650,12 +648,12 @@ void ms_inv_mask_processing_fx( * *-------------------------------------------------------------------*/ -Word16 write_stereo_to_bitstream( - STEREO_MDCT_ENC_DATA_HANDLE hStereoMdct, /* i/o: Stereo MDCT encoder structure */ - Encoder_State **sts, /* i/o: Encoder state structure */ - Word16 ms_mask[NB_DIV][MAX_SFB], /* i : bandwise MS mask */ - const Word16 mct_on, /* i : flag mct block (1) or stereo (0)*/ - BSTR_ENC_HANDLE hBstr /* i/o: bitstream handle */ +Word16 write_stereo_to_bitstream_fx( + STEREO_MDCT_ENC_DATA_HANDLE hStereoMdct, /* i/o: Stereo MDCT encoder structure */ + Encoder_State **sts, /* i/o: Encoder state structure */ + Word16 ms_mask[NB_DIV][MAX_SFB], /* i : bandwise MS mask Q0*/ + const Word16 mct_on, /* i : flag mct block (1) or stereo (0) Q0*/ + BSTR_ENC_HANDLE hBstr /* i/o: bitstream handle */ ) { Word16 i, k, nSubframes; @@ -787,8 +785,8 @@ Word16 write_stereo_to_bitstream( *-------------------------------------------------------------------*/ static void convertToBwMS_fx( - const Word16 startLine, /* i : start line of sfb */ - const Word16 stopLine, /* i : stop line of sfb */ + const Word16 startLine, /* i : start line of sfb Q0*/ + const Word16 stopLine, /* i : stop line of sfb Q0*/ Word32 x0[], /* i/o: mid/left channel coefficients */ /* Q_x */ Word32 x1[], @@ -801,11 +799,11 @@ static void convertToBwMS_fx( FOR( j = startLine; j < stopLine; j++ ) { - tmpValue_fx = x0[j]; + tmpValue_fx = x0[j]; /*Q_x*/ move32(); - x0[j] = Mpy_32_32( L_add( x0[j], x1[j] ), norm_fac ); + x0[j] = Mpy_32_32( L_add( x0[j], x1[j] ), norm_fac ); /* Q_x */ move32(); - x1[j] = Mpy_32_32( L_sub( tmpValue_fx, x1[j] ), norm_fac ); + x1[j] = Mpy_32_32( L_sub( tmpValue_fx, x1[j] ), norm_fac ); /* Q_x */ move32(); } @@ -819,12 +817,10 @@ static void convertToBwMS_fx( *-------------------------------------------------------------------*/ void convertToMS_fx( - const Word16 L_frame, /* i : frame length */ - Word32 x0[], - /* i/o: mid/left channel coefficients */ // Q(q_x) - Word32 x1[], - /* i/o: side/right channel coefficients */ // Q(q_x) - const Word32 norm_fac /* i : normalization factor */ // Q31 + const Word16 L_frame, /* i : frame length Q0*/ + Word32 x0[], /* i/o: mid/left channel coefficients Q(q_x)*/ + Word32 x1[], /* i/o: side/right channel coefficients Q(q_x)*/ + const Word32 norm_fac /* i : normalization factor Q31*/ ) { convertToBwMS_fx( 0, L_frame, x0, x1, norm_fac ); @@ -840,14 +836,12 @@ void convertToMS_fx( /*! r: SQ gain */ static Word32 SQ_gain_estimate_stereo_fx( // e_res - Word32 xL_fx[], - /* i : L vector to quantize */ // e_xL + Word32 xL_fx[], /* i : L vector to quantize Q31-e_xL*/ Word16 e_xL, - Word32 xR_fx[], - /* i : R vector to quantize */ // e_xR + Word32 xR_fx[], /* i : R vector to quantize Q31-e_xR*/ Word16 e_xR, - const Word16 nbitsSQ, /* i : number of bits targeted */ - const Word16 lg, /* i : vector size (2048 max) */ + const Word16 nbitsSQ, /* i : number of bits targeted Q0*/ + const Word16 lg, /* i : vector size (2048 max) Q0*/ Word16 *e_res ) { Word16 i, q, iter, e_ener, e_tmp; @@ -855,24 +849,24 @@ static Word32 SQ_gain_estimate_stereo_fx( // e_res Word32 en_fx[N_MAX / 2]; // Q(26) Word16 lg2, lg_4, lg2_4; - lg_4 = shr( lg, 2 ); - lg2_4 = shl( lg_4, 1 ); - lg2 = shl( lg2_4, 2 ); + lg_4 = shr( lg, 2 ); /* Q0 */ + lg2_4 = shl( lg_4, 1 ); /* Q0 */ + lg2 = shl( lg2_4, 2 ); /* Q0 */ i = 0; move16(); - set32_fx( en_fx, 21474836 /* 0.01 in Q31 */, N_MAX / 2 ); + set32_fx( en_fx, 21474836 /* 0.01 in Q31 */, idiv1616( N_MAX, 2 ) ); /* energy of quadruples with 9dB offset */ /* ignore that we may take no all lines into account, max. 3 lines at the upper end of the spectrum can be missed (if lg is not a multiple of 4, happens also in SQGain()*/ FOR( q = 0; q < lg_4; q++ ) { - ener_fx = BASOP_Util_Add_Mant32Exp( 21474836, 0, Mpy_32_32( xL_fx[i], xL_fx[i] ), e_xL * 2, &e_ener ); - ener_fx = BASOP_Util_Add_Mant32Exp( ener_fx, e_ener, Mpy_32_32( xL_fx[i + 1], xL_fx[i + 1] ), e_xL * 2, &e_ener ); - ener_fx = BASOP_Util_Add_Mant32Exp( ener_fx, e_ener, Mpy_32_32( xL_fx[i + 2], xL_fx[i + 2] ), e_xL * 2, &e_ener ); - ener_fx = BASOP_Util_Add_Mant32Exp( ener_fx, e_ener, Mpy_32_32( xL_fx[i + 3], xL_fx[i + 3] ), e_xL * 2, &e_ener ); - en_fx[q] = BASOP_Util_Log2( ener_fx ); /* saves a MAC */ + ener_fx = BASOP_Util_Add_Mant32Exp( 21474836 /*0.01 in Q15*/, 0, Mpy_32_32( xL_fx[i], xL_fx[i] ), e_xL * 2, &e_ener ); /* Q31-e_ener */ + ener_fx = BASOP_Util_Add_Mant32Exp( ener_fx, e_ener, Mpy_32_32( xL_fx[i + 1], xL_fx[i + 1] ), e_xL * 2, &e_ener ); /* Q31-e_ener */ + ener_fx = BASOP_Util_Add_Mant32Exp( ener_fx, e_ener, Mpy_32_32( xL_fx[i + 2], xL_fx[i + 2] ), e_xL * 2, &e_ener ); /* Q31-e_ener */ + ener_fx = BASOP_Util_Add_Mant32Exp( ener_fx, e_ener, Mpy_32_32( xL_fx[i + 3], xL_fx[i + 3] ), e_xL * 2, &e_ener ); /* Q31-e_ener */ + en_fx[q] = BASOP_Util_Log2( ener_fx ); /* saves a MAC */ move32(); en_fx[q] = Mpy_32_16_1( L_add( e_ener * ONE_IN_Q25, en_fx[q] ), 9864 /* log10(2) in Q15 */ ); // Q(25) move32(); @@ -881,11 +875,11 @@ static Word32 SQ_gain_estimate_stereo_fx( // e_res i = 0; FOR( ; q < lg2_4; q++ ) { - ener_fx = BASOP_Util_Add_Mant32Exp( 21474836, 0, Mpy_32_32( xR_fx[i], xR_fx[i] ), e_xR * 2, &e_ener ); - ener_fx = BASOP_Util_Add_Mant32Exp( ener_fx, e_ener, Mpy_32_32( xR_fx[i + 1], xR_fx[i + 1] ), e_xR * 2, &e_ener ); - ener_fx = BASOP_Util_Add_Mant32Exp( ener_fx, e_ener, Mpy_32_32( xR_fx[i + 2], xR_fx[i + 2] ), e_xR * 2, &e_ener ); - ener_fx = BASOP_Util_Add_Mant32Exp( ener_fx, e_ener, Mpy_32_32( xR_fx[i + 3], xR_fx[i + 3] ), e_xR * 2, &e_ener ); - en_fx[q] = BASOP_Util_Log2( ener_fx ); /* saves a MAC */ + ener_fx = BASOP_Util_Add_Mant32Exp( 21474836 /*0.01 Q15*/, 0, Mpy_32_32( xR_fx[i], xR_fx[i] ), e_xR * 2, &e_ener ); /* Q31-e_ener */ + ener_fx = BASOP_Util_Add_Mant32Exp( ener_fx, e_ener, Mpy_32_32( xR_fx[i + 1], xR_fx[i + 1] ), e_xR * 2, &e_ener ); /* Q31-e_ener */ + ener_fx = BASOP_Util_Add_Mant32Exp( ener_fx, e_ener, Mpy_32_32( xR_fx[i + 2], xR_fx[i + 2] ), e_xR * 2, &e_ener ); /* Q31-e_ener */ + ener_fx = BASOP_Util_Add_Mant32Exp( ener_fx, e_ener, Mpy_32_32( xR_fx[i + 3], xR_fx[i + 3] ), e_xR * 2, &e_ener ); /* Q31-e_ener */ + en_fx[q] = BASOP_Util_Log2( ener_fx ); /* saves a MAC */ move32(); en_fx[q] = Mpy_32_16_1( L_add( e_ener * ONE_IN_Q25, en_fx[q] ), 9864 /* log10(2) in Q15 */ ); // Q(25) move32(); @@ -896,14 +890,14 @@ static Word32 SQ_gain_estimate_stereo_fx( // e_res target_fx = L_mult( 19660 /* 0.15 in Q17 */, sub( nbitsSQ, shr( lg2, 4 ) ) ); // Q(18) fac_fx = 429496729; /* 12.8 in Q25 */ move32(); - offset_fx = fac_fx; + offset_fx = fac_fx; /* Q25 */ move32(); /* find offset (0 to 128 dB with step of 0.125dB) */ FOR( iter = 0; iter < 10; iter++ ) { - fac_fx = L_shr( fac_fx, 1 ); - offset_fx = L_sub( offset_fx, fac_fx ); + fac_fx = L_shr( fac_fx, 1 ); /* Q25 */ + offset_fx = L_sub( offset_fx, fac_fx ); /* Q25 */ ener_fx = 0; move32(); e_ener = 0; @@ -911,19 +905,19 @@ static Word32 SQ_gain_estimate_stereo_fx( // e_res FOR( i = 0; i < lg2_4; i++ ) { - tmp_32 = L_sub( en_fx[i], offset_fx ); + tmp_32 = L_sub( en_fx[i], offset_fx ); /* Q25 */ e_tmp = 6; move16(); /* avoid SV with 1 bin of amp < 0.5f */ - IF( GT_32( tmp_32, 10066329 ) ) + IF( GT_32( tmp_32, 10066329 /*0.3 Q25*/ ) ) { - ener_fx = BASOP_Util_Add_Mant32Exp( ener_fx, e_ener, tmp_32, e_tmp, &e_ener ); + ener_fx = BASOP_Util_Add_Mant32Exp( ener_fx, e_ener, tmp_32, e_tmp, &e_ener ); /* Q31-e_ener */ /* if ener is above target -> break and increase offset */ IF( L_shl_sat( ener_fx, sub( e_ener, Q13 ) ) > target_fx ) { - offset_fx = L_add( offset_fx, fac_fx ); + offset_fx = L_add( offset_fx, fac_fx ); /* Q25 */ BREAK; } } @@ -933,7 +927,7 @@ static Word32 SQ_gain_estimate_stereo_fx( // e_res /* return gain */ tmp_32 = L_add( 12539858, Mpy_32_16_1( offset_fx, 13606 ) ); // Q23 - return BASOP_util_Pow2( tmp_32, Q8, e_res ); + return BASOP_util_Pow2( tmp_32, Q8, e_res ); /* Q31-e_res */ } /*-------------------------------------------------------------------* @@ -943,23 +937,23 @@ static Word32 SQ_gain_estimate_stereo_fx( // e_res *-------------------------------------------------------------------*/ static Word16 QuantSpecEstimateBits_fx( - Word32 *spec_fx, + Word32 *spec_fx, /* Q15-spec_e */ Word16 spec_e, - Word16 G_fx, + Word16 G_fx, /* Q15-G_e */ Word16 G_e, - const Word16 length, - const Word16 nBitsAvailable, - Word16 sqQ[] ) + const Word16 length, /* Q0 */ + const Word16 nBitsAvailable, /* Q0 */ + Word16 sqQ[] /* Q0 */ ) { Word16 stop, sqBits, nEncoded; Word16 lastnz; - tcx_scalar_quantization_ivas_fx( spec_fx, spec_e, sqQ, length, G_fx, G_e, 16384, NULL, 1 ); + tcx_scalar_quantization_ivas_fx( spec_fx, spec_e, sqQ, length, G_fx, G_e, 16384 /*Q15*/, NULL, 1 ); stop = 0; move16(); - sqBits = RCcontextMapping_encode2_estimate_no_mem_s17_LCS( sqQ, length, &lastnz, &nEncoded, nBitsAvailable, &stop, 0, NULL ); + sqBits = RCcontextMapping_encode2_estimate_no_mem_s17_LCS_fx( sqQ, length, &lastnz, &nEncoded, nBitsAvailable, &stop, 0, NULL ); /*Q0*/ if ( stop != 0 ) { @@ -976,15 +970,15 @@ static Word16 QuantSpecEstimateBits_fx( * *-------------------------------------------------------------------*/ -static void context_update( +static void context_update_fx( HANDLE_RC_CONTEXT_MEM ctxSrc, HANDLE_RC_CONTEXT_MEM ctxTarget, - const Word16 endLine ) + const Word16 endLine /*Q0*/ ) { Word16 last_nz; /* check if last_nz of target is smaller than endLine, save and update */ - last_nz = s_max( ctxTarget->lastnz, endLine ); + last_nz = s_max( ctxTarget->lastnz, endLine ); /* Q0 */ mvc2c( (UWord8 *) ctxSrc, (UWord8 *) ctxTarget, sizeof( RC_CONTEXT_MEM ) ); ctxTarget->lastnz = last_nz; @@ -1003,7 +997,7 @@ static Word16 GetChannelEnergyRatio_fx( // Q15 Encoder_State **sts, /* i/o: Encoder state structure */ const Word16 iFirstSubframe, const Word16 iLastSubframe, - const UWord8 ratioInRmsDomain ) + const UWord8 ratioInRmsDomain /* Q0 */ ) { Word16 ch, n, i; Word32 nrg_fx[2]; @@ -1023,11 +1017,11 @@ static Word16 GetChannelEnergyRatio_fx( // Q15 move16(); } - Word16 L_subframeTCX = shr( st->hTcxEnc->L_frameTCX, sub( nSubframes, 1 ) ); + Word16 L_subframeTCX = shr( st->hTcxEnc->L_frameTCX, sub( nSubframes, 1 ) ); /* Q0 */ if ( st->last_core == ACELP_CORE ) { - L_subframeTCX = add( L_subframeTCX, shr( L_subframeTCX, 2 ) ); + L_subframeTCX = add( L_subframeTCX, shr( L_subframeTCX, 2 ) ); /* Q0 */ } assert( iFirstSubframe >= 0 && ( iFirstSubframe <= iLastSubframe ) ); @@ -1040,28 +1034,28 @@ static Word16 GetChannelEnergyRatio_fx( // Q15 { FOR( i = 0; i < L_subframeTCX; i++ ) { - nrg_fx[ch] = BASOP_Util_Add_Mant32Exp( nrg_fx[ch], nrg_e[ch], Mpy_32_32( st->hTcxEnc->spectrum_fx[n][i], st->hTcxEnc->spectrum_fx[n][i] ), shl( st->hTcxEnc->spectrum_e[n], 1 ), &nrg_e[ch] ); + nrg_fx[ch] = BASOP_Util_Add_Mant32Exp( nrg_fx[ch], nrg_e[ch], Mpy_32_32( st->hTcxEnc->spectrum_fx[n][i], st->hTcxEnc->spectrum_fx[n][i] ), shl( st->hTcxEnc->spectrum_e[n], 1 ), &nrg_e[ch] ); /* Q31-nrg_e */ move32(); } } IF( ratioInRmsDomain && nrg_fx[ch] ) { - nrg_fx[ch] = Sqrt32( nrg_fx[ch], &nrg_e[ch] ); + nrg_fx[ch] = Sqrt32( nrg_fx[ch], &nrg_e[ch] ); /* Q31-nrg_e */ move32(); } } IF( L_add_sat( nrg_fx[0], nrg_fx[1] ) ) { - nrg_fx[1] = BASOP_Util_Add_Mant32Exp( nrg_fx[0], nrg_e[0], nrg_fx[1], nrg_e[1], &nrg_e[1] ); + nrg_fx[1] = BASOP_Util_Add_Mant32Exp( nrg_fx[0], nrg_e[0], nrg_fx[1], nrg_e[1], &nrg_e[1] ); /* Q31-nrg_e[1] */ move32(); IF( NE_16( nrg_e[1], nrg_e[0] ) ) { - nrg_fx[0] = L_shr( nrg_fx[0], sub( nrg_e[1], nrg_e[0] ) ); + nrg_fx[0] = L_shr( nrg_fx[0], sub( nrg_e[1], nrg_e[0] ) ); /* Q31-nrg_e[1] */ move32(); } - return divide3232( nrg_fx[0], nrg_fx[1] ); + return divide3232( nrg_fx[0], nrg_fx[1] ); /* Q15 */ } return MIN_16; @@ -1090,21 +1084,21 @@ void FindSplitRatio_fx( IF( ratio_fx >= 0 ) { - hCPE->hStereoMdct->split_ratio = round_fx( L_mult( SMDCT_BITRATE_RATIO_RANGE, ratio_fx ) ); + hCPE->hStereoMdct->split_ratio = round_fx( L_mult( SMDCT_BITRATE_RATIO_RANGE, ratio_fx ) ); /* Q0 */ move16(); /* Tuning to get closer to the optimal split ratio */ IF( LT_32( L_mult0( 9, ratio_fx ), 8 * ONE_IN_Q15 ) && GT_16( hCPE->hStereoMdct->split_ratio, SMDCT_EQUAL_RATIO_RANGE + ( SMDCT_BITRATE_RATIO_RANGE >> 4 ) ) ) { - hCPE->hStereoMdct->split_ratio = sub( hCPE->hStereoMdct->split_ratio, SMDCT_BITRATE_RATIO_RANGE >> 3 ); + hCPE->hStereoMdct->split_ratio = sub( hCPE->hStereoMdct->split_ratio, SMDCT_BITRATE_RATIO_RANGE >> 3 ); /* Q0 */ move16(); } IF( GT_32( L_mult0( 9, ratio_fx ), 1 * ONE_IN_Q15 ) && LT_16( hCPE->hStereoMdct->split_ratio, SMDCT_EQUAL_RATIO_RANGE - ( SMDCT_BITRATE_RATIO_RANGE >> 4 ) ) ) { - hCPE->hStereoMdct->split_ratio = add( hCPE->hStereoMdct->split_ratio, SMDCT_BITRATE_RATIO_RANGE >> 3 ); + hCPE->hStereoMdct->split_ratio = add( hCPE->hStereoMdct->split_ratio, SMDCT_BITRATE_RATIO_RANGE >> 3 ); /* Q0 */ move16(); } - hCPE->hStereoMdct->split_ratio = s_min( SMDCT_BITRATE_RATIO_RANGE - 1, s_max( 1, hCPE->hStereoMdct->split_ratio ) ); + hCPE->hStereoMdct->split_ratio = s_min( SMDCT_BITRATE_RATIO_RANGE - 1, s_max( 1, hCPE->hStereoMdct->split_ratio ) ); /* Q0 */ move16(); } @@ -1126,11 +1120,11 @@ static void MsStereoDecision_fx( Word32 *specS_fx, /* scratch buffer for M, use buffer for inverse MS mask spectrum */ /* Q( q_spec ) */ Word16 q_spec, - Word16 *mdct_stereo_mode, /* output */ - Word16 *msMask, /* output */ - const Word16 nBitsAvailable ) + Word16 *mdct_stereo_mode, /* output Q0*/ + Word16 *msMask, /* output Q0*/ + const Word16 nBitsAvailable /*Q0*/ ) { - Word16 length = sfbParam->sfbOffset[sfbParam->nBandsStereoCore]; + Word16 length = sfbParam->sfbOffset[sfbParam->nBandsStereoCore]; /* Q0 */ Word16 bitsL, bitsR, bitsM, bitsS; Word16 bitsBW, bitsLR, bitsMS; @@ -1163,7 +1157,7 @@ static void MsStereoDecision_fx( specM_e = sub( Q31, q_spec ); specS_e = sub( Q31, q_spec ); - GLR_fx = SQ_gain_estimate_stereo_fx( specL_fx, specL_e, specR_fx, specR_e, nBitsAvailable, length, &e_GLR ); + GLR_fx = SQ_gain_estimate_stereo_fx( specL_fx, specL_e, specR_fx, specR_e, nBitsAvailable, length, &e_GLR ); /* Q31-e_GLR */ FOR( i = 0; i < length; i++ ) { @@ -1173,12 +1167,12 @@ static void MsStereoDecision_fx( move32(); } - G_fx = extract_h( GLR_fx ); /* seems to be favourable to underestimate a bit */ + G_fx = extract_h( GLR_fx ); /* seems to be favourable to underestimate a bit Q15-e_GLR*/ G_e = sub( e_GLR, 1 ); /* do the full spectrum estimates already here, as side effect we get the quantized spectra... */ - bitsLR = add( QuantSpecEstimateBits_fx( specL_fx, specL_e, G_fx, G_e, length, nBitsAvailable, quantSpecL ), QuantSpecEstimateBits_fx( specR_fx, specR_e, G_fx, G_e, length, nBitsAvailable, quantSpecR ) ); - bitsMS = add( QuantSpecEstimateBits_fx( specM_fx, specM_e, G_fx, G_e, length, nBitsAvailable, quantSpecM ), QuantSpecEstimateBits_fx( specS_fx, specS_e, G_fx, G_e, length, nBitsAvailable, quantSpecS ) ); + bitsLR = add( QuantSpecEstimateBits_fx( specL_fx, specL_e, G_fx, G_e, length, nBitsAvailable, quantSpecL ), QuantSpecEstimateBits_fx( specR_fx, specR_e, G_fx, G_e, length, nBitsAvailable, quantSpecR ) ); /* Q0 */ + bitsMS = add( QuantSpecEstimateBits_fx( specM_fx, specM_e, G_fx, G_e, length, nBitsAvailable, quantSpecM ), QuantSpecEstimateBits_fx( specS_fx, specS_e, G_fx, G_e, length, nBitsAvailable, quantSpecS ) ); /* Q0 */ /* clean-up MS scratch buffers */ set32_fx( specM_fx, 0, length ); @@ -1189,11 +1183,11 @@ static void MsStereoDecision_fx( bitsBW = 0; move16(); - RCcontextMapping_encode2_estimate_bandWise_start( quantSpecL, length, nBitsAvailable, ctxL ); - RCcontextMapping_encode2_estimate_bandWise_start( quantSpecR, length, nBitsAvailable, ctxR ); + RCcontextMapping_encode2_estimate_bandWise_start_fx( quantSpecL, length, nBitsAvailable, ctxL ); + RCcontextMapping_encode2_estimate_bandWise_start_fx( quantSpecR, length, nBitsAvailable, ctxR ); - bitsBW = add( bitsBW, RCcontextMapping_encode2_estimate_bandWise_start( quantSpecM, length, nBitsAvailable, ctxM ) ); - bitsBW = add( bitsBW, RCcontextMapping_encode2_estimate_bandWise_start( quantSpecS, length, nBitsAvailable, ctxS ) ); + bitsBW = add( bitsBW, RCcontextMapping_encode2_estimate_bandWise_start_fx( quantSpecM, length, nBitsAvailable, ctxM ) ); /* Q0 */ + bitsBW = add( bitsBW, RCcontextMapping_encode2_estimate_bandWise_start_fx( quantSpecS, length, nBitsAvailable, ctxS ) ); /* Q0 */ /*find_max_lastnz(ctxL,ctxR,ctxM,ctxS);*/ @@ -1204,32 +1198,32 @@ static void MsStereoDecision_fx( const Word16 endline = sfbParam->sfbOffset[sfb + 1]; move16(); - bitsL = RCcontextMapping_encode2_estimate_bandWise( quantSpecL, startline, endline, ctxL ); - bitsR = RCcontextMapping_encode2_estimate_bandWise( quantSpecR, startline, endline, ctxR ); - bitsM = RCcontextMapping_encode2_estimate_bandWise( quantSpecM, startline, endline, ctxM ); - bitsS = RCcontextMapping_encode2_estimate_bandWise( quantSpecS, startline, endline, ctxS ); + bitsL = RCcontextMapping_encode2_estimate_bandWise_fx( quantSpecL, startline, endline, ctxL ); + bitsR = RCcontextMapping_encode2_estimate_bandWise_fx( quantSpecR, startline, endline, ctxR ); + bitsM = RCcontextMapping_encode2_estimate_bandWise_fx( quantSpecM, startline, endline, ctxM ); + bitsS = RCcontextMapping_encode2_estimate_bandWise_fx( quantSpecS, startline, endline, ctxS ); IF( LE_16( add( bitsM, bitsS ), add( bitsL, bitsR ) ) ) { msMask[sfb] = 1; move16(); nMSOn = add( nMSOn, 1 ); - context_update( ctxM, ctxL, endline ); - context_update( ctxS, ctxR, endline ); - bitsBW = add( bitsBW, add( bitsM, bitsS ) ); + context_update_fx( ctxM, ctxL, endline ); + context_update_fx( ctxS, ctxR, endline ); + bitsBW = add( bitsBW, add( bitsM, bitsS ) ); /* Q0 */ } ELSE { msMask[sfb] = 0; move16(); - context_update( ctxL, ctxM, endline ); - context_update( ctxR, ctxS, endline ); - bitsBW = add( bitsBW, add( bitsL, bitsR ) ); + context_update_fx( ctxL, ctxM, endline ); + context_update_fx( ctxR, ctxS, endline ); + bitsBW = add( bitsBW, add( bitsL, bitsR ) ); /* Q0 */ } } - bitsBW = add( bitsBW, sfbParam->nBandsStereoCore ); /* Signaling bits */ + bitsBW = add( bitsBW, sfbParam->nBandsStereoCore ); /* Signaling bits Q0*/ IF( LT_16( bitsLR, bitsBW ) ) { @@ -1273,17 +1267,17 @@ static void MsStereoDecision_fx( void initMdctStereoEncData_fx( STEREO_MDCT_ENC_DATA *hStereoMdct, /* i/o: mdct stereo parameters structure */ const IVAS_FORMAT ivas_format, /* i : IVAS format */ - const Word16 element_mode, /* i : element mode */ - const Word32 element_brate, /* i : element bitrate */ - const Word16 bwidth, /* i : bandwidth */ - const Word16 igf, /* i : flag indicating IGF activity */ + const Word16 element_mode, /* i : element mode Q0*/ + const Word32 element_brate, /* i : element bitrate Q0*/ + const Word16 bwidth, /* i : bandwidth Q0*/ + const Word16 igf, /* i : flag indicating IGF activity Q0*/ const H_IGF_GRID hIgfGrid, /* i : IGF grid setup */ - const Word16 mem_init /* i : initialize memory after malloc */ + const Word16 mem_init /* i : initialize memory after malloc Q0*/ ) { Word16 tcx_coded_lines; - tcx_coded_lines = getNumTcxCodedLines( bwidth ); + tcx_coded_lines = getNumTcxCodedLines( bwidth ); /* Q0 */ /*initialize mdct stereo mode*/ set16_fx( hStereoMdct->mdct_stereo_mode, -1, 2 ); @@ -1301,7 +1295,7 @@ void initMdctStereoEncData_fx( set16_fx( hStereoMdct->IGFStereoMode, -1, 2 ); - hStereoMdct->split_ratio = SMDCT_EQUAL_RATIO_RANGE; + hStereoMdct->split_ratio = SMDCT_EQUAL_RATIO_RANGE; /* Q0 */ move16(); set16_fx( hStereoMdct->global_ild, SMDCT_ILD_RANGE >> 1, 2 ); @@ -1340,9 +1334,11 @@ void initMdctStereoEncData_fx( ivas_error initMdctItdHandling_fx( STEREO_MDCT_ENC_DATA *hStereoMdct, /* i/o: mdct stereo parameters structure */ - const Word32 input_Fs /* i : input sampling rate */ + const Word32 input_Fs /* i : input sampling rate Q0*/ ) { + test(); + test(); IF( hStereoMdct->hItd == NULL ) { IF( ( hStereoMdct->hItd = (ITD_DATA_HANDLE) malloc( sizeof( ITD_DATA ) ) ) == NULL ) @@ -1351,6 +1347,8 @@ ivas_error initMdctItdHandling_fx( } } + test(); + test(); IF( hStereoMdct->hDft_ana == NULL ) { IF( ( hStereoMdct->hDft_ana = (DFT_ANA_HANDLE) malloc( sizeof( DFT_ANA ) ) ) == NULL ) diff --git a/lib_enc/ivas_stereo_switching_enc.c b/lib_enc/ivas_stereo_switching_enc_fx.c similarity index 90% rename from lib_enc/ivas_stereo_switching_enc.c rename to lib_enc/ivas_stereo_switching_enc_fx.c index ba84be1a2000f4ada3bb3b6fc5e901d993dae781..0a526561ae7317a3a06d15ea472636f2f3ad12fd 100644 --- a/lib_enc/ivas_stereo_switching_enc.c +++ b/lib_enc/ivas_stereo_switching_enc_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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,14 +34,12 @@ #include "options.h" #include "cnst.h" #include "rom_com.h" -#include "prot.h" -#include "ivas_prot.h" +#include "prot_fx.h" #include "ivas_rom_com_fx.h" #include "ivas_rom_com.h" #include "assert.h" #include "wmc_auto.h" #include "prot_fx_enc.h" -#include "prot_fx.h" #include "ivas_prot_fx.h" /*-------------------------------------------------------------------* @@ -54,7 +52,7 @@ static ivas_error allocate_CoreCoder_enc_fx( ENC_CORE_HANDLE st /* i/o: Core encoder state structure */ ) { - IF( st->hLPDmem == NULL && st->element_mode != IVAS_CPE_MDCT ) + IF( st->hLPDmem == NULL && NE_16( st->element_mode, IVAS_CPE_MDCT ) ) { IF( ( st->hLPDmem = (LPD_state_HANDLE) malloc( sizeof( LPD_state ) ) ) == NULL ) { @@ -63,7 +61,7 @@ static ivas_error allocate_CoreCoder_enc_fx( LPDmem_enc_init_ivas_fx( st->hLPDmem ); } - IF( st->hGSCEnc == NULL && st->element_mode != IVAS_CPE_MDCT ) + IF( st->hGSCEnc == NULL && NE_16( st->element_mode, IVAS_CPE_MDCT ) ) { IF( ( st->hGSCEnc = (GSC_ENC_HANDLE) malloc( sizeof( GSC_ENC_DATA ) ) ) == NULL ) { @@ -221,10 +219,10 @@ static void deallocate_CoreCoder_enc_fx( ivas_error stereo_memory_enc_fx( CPE_ENC_HANDLE hCPE, /* i : CPE encoder structure */ - const Word32 input_Fs, /* i : input sampling rate */ - const Word16 max_bwidth, /* i : maximum audio bandwidth */ + const Word32 input_Fs, /* i : input sampling rate Q0*/ + const Word16 max_bwidth, /* i : maximum audio bandwidth Q0*/ const IVAS_FORMAT ivas_format, /* i : ivas format */ - const Word16 nchan_transport /* i : number transport chans */ + const Word16 nchan_transport /* i : number transport chans Q0*/ ) { Encoder_State *st; @@ -241,7 +239,16 @@ ivas_error stereo_memory_enc_fx( test(); IF( hCPE->hStereoTCA != NULL && EQ_16( hCPE->last_element_mode, IVAS_CPE_DFT ) ) { +#ifdef FIX_1132_STACK_CORRUPTION + Word16 tmp = extract_h( L_abs( hCPE->hStereoDft->hItd->itd_fx[1] ) ); + if ( hCPE->hStereoDft->hItd->itd_fx[1] < 0 ) + { + tmp = negate( tmp ); + } + set16_fx( hCPE->hStereoTCA->prevCorrLagStats, tmp, 3 ); +#else set16_fx( hCPE->hStereoTCA->prevCorrLagStats, extract_h( hCPE->hStereoDft->hItd->itd_fx[1] ), 3 ); +#endif IF( hCPE->hStereoDft->hItd->itd_fx[1] >= 0 ) { hCPE->hStereoTCA->prevRefChanIndx = L_CH_INDX; @@ -359,8 +366,8 @@ ivas_error stereo_memory_enc_fx( IF( EQ_16( hCPE->last_element_mode, IVAS_CPE_MDCT ) && ( EQ_16( hCPE->element_mode, IVAS_CPE_DFT ) || EQ_16( hCPE->element_mode, IVAS_CPE_TD ) ) ) { /* Deallocate MDCT CNG structures */ - deleteCldfb_ivas( &hCPE->hCoreCoder[0]->cldfbAnaEnc ); - deleteCldfb_ivas( &hCPE->hCoreCoder[1]->cldfbAnaEnc ); + deleteCldfb_ivas_fx( &hCPE->hCoreCoder[0]->cldfbAnaEnc ); + deleteCldfb_ivas_fx( &hCPE->hCoreCoder[1]->cldfbAnaEnc ); IF( EQ_16( hCPE->element_mode, IVAS_CPE_DFT ) ) { @@ -410,7 +417,7 @@ ivas_error stereo_memory_enc_fx( /* allocate CLDFB for primary channel */ IF( st->cldfbAnaEnc == NULL ) { - IF( NE_32( ( error = openCldfb_ivas_enc( &st->cldfbAnaEnc, CLDFB_ANALYSIS, input_Fs, CLDFB_PROTOTYPE_1_25MS ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &st->cldfbAnaEnc, CLDFB_ANALYSIS, input_Fs, CLDFB_PROTOTYPE_1_25MS, ENC ) ), IVAS_ERR_OK ) ) { return error; } @@ -426,7 +433,7 @@ ivas_error stereo_memory_enc_fx( IF( st->cldfbSynTd == NULL ) { - IF( NE_32( ( error = openCldfb_ivas_enc( &st->cldfbSynTd, CLDFB_SYNTHESIS, 16000, CLDFB_PROTOTYPE_1_25MS ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &st->cldfbSynTd, CLDFB_SYNTHESIS, 16000, CLDFB_PROTOTYPE_1_25MS, ENC ) ), IVAS_ERR_OK ) ) { return error; } @@ -517,8 +524,8 @@ ivas_error stereo_memory_enc_fx( // st->hTcxEnc->spectrum[0] = st->hTcxEnc->spectrum_long; // st->hTcxEnc->spectrum[1] = st->hTcxEnc->spectrum_long + N_TCX10_MAX; - st->hTcxEnc->spectrum_fx[0] = st->hTcxEnc->spectrum_long_fx; - st->hTcxEnc->spectrum_fx[1] = st->hTcxEnc->spectrum_long_fx + N_TCX10_MAX; + st->hTcxEnc->spectrum_fx[0] = st->hTcxEnc->spectrum_long_fx; /* Q31-st->hTcxEnc->spectrum_e[0] */ + st->hTcxEnc->spectrum_fx[1] = st->hTcxEnc->spectrum_long_fx + N_TCX10_MAX; /* Q31-st->hTcxEnc->spectrum_e[1] */ st->hTcxEnc->spectrum_e[0] = st->hTcxEnc->spectrum_e[1] = 0; move16(); move16(); @@ -527,6 +534,8 @@ ivas_error stereo_memory_enc_fx( set32_fx( st->hTcxEnc->spectrum_long_fx, 0, N_MAX ); st->hTcxEnc->spectrum_long_e = 0; st->hTcxEnc->tfm_mem_fx = 1610612736; /* 0.75 in Q31 */ + move16(); + move32(); IF( EQ_16( hCPE->last_element_mode, IVAS_CPE_DFT ) ) { @@ -560,6 +569,7 @@ ivas_error stereo_memory_enc_fx( test(); hCPE->hStereoMdct->isSBAStereoMode = ( EQ_32( ivas_format, SBA_FORMAT ) && EQ_16( nchan_transport, 2 ) ); + move16(); test(); test(); @@ -577,7 +587,7 @@ ivas_error stereo_memory_enc_fx( FOR( i = 0; i < CPE_CHANNELS; i++ ) { st = hCPE->hCoreCoder[i]; - IF( NE_32( ( error = openCldfb_ivas_enc( &st->cldfbAnaEnc, CLDFB_ANALYSIS, st->input_Fs, CLDFB_PROTOTYPE_1_25MS ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &st->cldfbAnaEnc, CLDFB_ANALYSIS, st->input_Fs, CLDFB_PROTOTYPE_1_25MS, ENC ) ), IVAS_ERR_OK ) ) { return error; } @@ -625,17 +635,17 @@ ivas_error stereo_memory_enc_fx( } static void v_multc_fixed_32_16( - const Word16 x[], /* i : Input vector */ - const Word32 c, /* i : Constant */ - Word32 y[], /* o : Output vector that contains c*x */ - const Word16 N /* i : Vector length */ + const Word16 x[], /* i : Input vector Qx*/ + const Word32 c, /* i : Constant Q31*/ + Word32 y[], /* o : Output vector that contains c*x Qx*/ + const Word16 N /* i : Vector length Q0*/ ) { Word16 i; FOR( i = 0; i < N; i++ ) { - y[i] = Mpy_32_16_1( c, x[i] ); + y[i] = Mpy_32_16_1( c, x[i] ); /* Q16+Qx */ move32(); } @@ -649,8 +659,8 @@ static void v_multc_fixed_32_16( void stereo_switching_enc_fx( CPE_ENC_HANDLE hCPE, /* i : CPE encoder structure */ - Word16 old_input_signal_pri[], /* i : old input signal of primary channel */ - const Word16 input_frame, /* i : input frame length */ + Word16 old_input_signal_pri[], /* i : old input signal of primary channel q_inp*/ + const Word16 input_frame, /* i : input frame length Q0*/ const Word16 q_inp ) { Word16 i, n, dft_ovl, offset; @@ -668,16 +678,20 @@ void stereo_switching_enc_fx( { FOR( n = 0; n < CPE_CHANNELS; n++ ) { - Copy( sts[n]->input_fx + input_frame - dft_ovl, hCPE->input_mem_fx[n], dft_ovl ); + Copy( sts[n]->input_fx + input_frame - dft_ovl, hCPE->input_mem_fx[n], dft_ovl ); /* sts[n]->q_inp */ +#ifdef FIX_ISSUE_1327 + hCPE->q_input_mem[n] = sts[n]->q_inp; + move16(); +#endif } } /* save original stereo input (MDCT overlap part) for both channels in unused old input of right channel for possible DFT->MDCT transition */ IF( EQ_16( hCPE->element_mode, IVAS_CPE_DFT ) ) { - Copy( sts[0]->input_fx + sub( (Word16) Mpy_32_32( sts[0]->input_Fs, 42949673 /* 1/50 in Q31*/ ), sts[0]->encoderLookahead_FB ), sts[1]->input_fx - shl( sts[0]->encoderLookahead_FB, 1 ), sts[0]->encoderLookahead_FB ); + Copy( sts[0]->input_fx + sub( (Word16) Mpy_32_32( sts[0]->input_Fs, 42949673 /* 1/50 in Q31*/ ), sts[0]->encoderLookahead_FB ), sts[1]->input_fx - shl( sts[0]->encoderLookahead_FB, 1 ), sts[0]->encoderLookahead_FB ); /* sts[0]->q_inp */ - Copy( sts[1]->input_fx + sub( (Word16) Mpy_32_32( sts[1]->input_Fs, 42949673 /* 1/50 in Q31*/ ), sts[1]->encoderLookahead_FB ), sts[1]->input_fx - sts[1]->encoderLookahead_FB, sts[1]->encoderLookahead_FB ); + Copy( sts[1]->input_fx + sub( (Word16) Mpy_32_32( sts[1]->input_Fs, 42949673 /* 1/50 in Q31*/ ), sts[1]->encoderLookahead_FB ), sts[1]->input_fx - sts[1]->encoderLookahead_FB, sts[1]->encoderLookahead_FB ); /* sts[1]->q_inp */ } @@ -688,7 +702,7 @@ void stereo_switching_enc_fx( /* window DFT synthesis overlap memory @input_Fs, primary channel */ FOR( i = 0; i < dft_ovl; i++ ) { - hCPE->hStereoDft->output_mem_dmx_fx[i] = L_shr( Mpy_32_16_r( hCPE->hStereoDft->win_fx[dft_ovl - 1 - i], old_input_signal_pri[input_frame - dft_ovl + i] ), q_inp ); // ( ( Q31 + q_inp ) - Q15 ) - Q16 ) -> Q16 + hCPE->hStereoDft->output_mem_dmx_fx[i] = L_shr( Mpy_32_16_r( hCPE->hStereoDft->win_fx[dft_ovl - 1 - i], old_input_signal_pri[input_frame - dft_ovl + i] ), add( q_inp, 1 ) ); // Q31 + q_inp - Q15 - (q_inp + 1) -> Q15 move32(); } /* reset 48kHz BWE overlap memory */ @@ -710,7 +724,7 @@ void stereo_switching_enc_fx( tmp_fx = usdequant_fx( hCPE->hStereoTCA->indx_ica_gD, STEREO_TCA_GDMIN_FX, STEREO_TCA_GDSTEP_FX ); FOR( i = 0; i < STEREO_DFT_BAND_MAX; i++ ) { - hCPE->hStereoDft->side_gain_fx[STEREO_DFT_BAND_MAX + i] = L_deposit_h( tmp_fx ); + hCPE->hStereoDft->side_gain_fx[STEREO_DFT_BAND_MAX + i] = L_deposit_h( tmp_fx ); /* Q31 */ move32(); } } @@ -722,22 +736,22 @@ void stereo_switching_enc_fx( /* update DFT synthesis overlap memory @12.8kHz */ FOR( i = 0; i < STEREO_DFT_OVL_12k8; i++ ) { - hCPE->hStereoDft->output_mem_dmx_12k8_fx[i] = L_shr( Mpy_32_16_r( hCPE->hStereoDft->win_12k8_fx[STEREO_DFT_OVL_12k8 - 1 - i], sts[0]->buf_speech_enc[L_FRAME32k + L_FRAME - STEREO_DFT_OVL_12k8 + i] ), q_inp ); + hCPE->hStereoDft->output_mem_dmx_12k8_fx[i] = L_shr( Mpy_32_16_r( hCPE->hStereoDft->win_12k8_fx[STEREO_DFT_OVL_12k8 - 1 - i], sts[0]->buf_speech_enc[L_FRAME32k + L_FRAME - STEREO_DFT_OVL_12k8 + i] ), q_inp + 1 ); /* Q15 */ move32(); } - Word16 q_dmx = Q16; + Word16 q_dmx = Q15; move16(); /* update DFT synthesis overlap memory @16kHz, primary channel only */ L_lerp_fx( hCPE->hStereoDft->output_mem_dmx_fx, hCPE->hStereoDft->output_mem_dmx_16k_fx, STEREO_DFT_OVL_16k, dft_ovl, &q_dmx ); FOR( i = 0; i < STEREO_DFT_OVL_16k; i++ ) { - hCPE->hStereoDft->output_mem_dmx_16k_fx[i] = L_shl( hCPE->hStereoDft->output_mem_dmx_16k_fx[i], sub( Q16, q_dmx ) ); // Q16 + hCPE->hStereoDft->output_mem_dmx_16k_fx[i] = L_shl( hCPE->hStereoDft->output_mem_dmx_16k_fx[i], sub( Q15, q_dmx ) ); // Q15 move32(); } FOR( i = 0; i < STEREO_DFT_OVL_MAX; i++ ) { - hCPE->hStereoDft->output_mem_dmx_fx[i] = L_shl( hCPE->hStereoDft->output_mem_dmx_fx[i], sub( Q16, q_dmx ) ); // Q16 + hCPE->hStereoDft->output_mem_dmx_fx[i] = L_shl( hCPE->hStereoDft->output_mem_dmx_fx[i], sub( Q15, q_dmx ) ); // Q15 move32(); } @@ -782,7 +796,8 @@ void stereo_switching_enc_fx( set_zero_fx( sts[1]->input32_fx - input_frame, input_frame ); set16_zero_fx( sts[1]->input_fx - input_frame, input_frame ); sts[1]->q_old_inp = Q15; - hCPE->hStereoTD->tdm_last_ratio_fx = tdm_ratio_tabl_fx[LRTD_STEREO_LEFT_IS_PRIM]; + hCPE->hStereoTD->tdm_last_ratio_fx = tdm_ratio_tabl_fx[LRTD_STEREO_LEFT_IS_PRIM]; /* Q31 */ + move16(); move32(); hCPE->hStereoTD->tdm_last_ratio_idx = LRTD_STEREO_LEFT_IS_PRIM; @@ -790,9 +805,9 @@ void stereo_switching_enc_fx( test(); test(); - IF( LT_32( hCPE->hStereoTCA->instTargetGain_fx, 26843546 ) && ( hCPE->hCoreCoder[0]->vad_flag || hCPE->hCoreCoder[1]->vad_flag ) ) /* but if there is no content in the L channel -> the primary channel is forced to right */ + IF( LT_32( hCPE->hStereoTCA->instTargetGain_fx, 26843546 /*Q29*/ ) && ( hCPE->hCoreCoder[0]->vad_flag || hCPE->hCoreCoder[1]->vad_flag ) ) /* but if there is no content in the L channel -> the primary channel is forced to right */ { - hCPE->hStereoTD->tdm_last_ratio_fx = tdm_ratio_tabl_fx[LRTD_STEREO_RIGHT_IS_PRIM]; + hCPE->hStereoTD->tdm_last_ratio_fx = tdm_ratio_tabl_fx[LRTD_STEREO_RIGHT_IS_PRIM]; /* Q31 */ move32(); hCPE->hStereoTD->tdm_last_ratio_idx = LRTD_STEREO_RIGHT_IS_PRIM; move16(); @@ -806,10 +821,10 @@ void stereo_switching_enc_fx( { IF( sts[0]->cldfbAnaEnc != NULL ) { - offset = sub( sts[0]->cldfbAnaEnc->p_filter_length, sts[0]->cldfbAnaEnc->no_channels ); + offset = sub( sts[0]->cldfbAnaEnc->p_filter_length, sts[0]->cldfbAnaEnc->no_channels ); /* Q0 */ FOR( i = 0; i < offset; i++ ) { - sts[0]->cldfbAnaEnc->cldfb_state_fx[i] = L_deposit_h( old_input_signal_pri[input_frame - offset - NS2SA( input_frame * FRAMES_PER_SEC, L_MEM_RECALC_TBE_NS ) + i] ); + sts[0]->cldfbAnaEnc->cldfb_state_fx[i] = L_deposit_h( old_input_signal_pri[input_frame - offset - NS2SA_FX2( L_mult0( input_frame, FRAMES_PER_SEC ), L_MEM_RECALC_TBE_NS ) + i] ); /* Q16+q_inp */ move32(); } sts[0]->cldfbAnaEnc->Q_cldfb_state = add( Q16, q_inp ); @@ -819,7 +834,7 @@ void stereo_switching_enc_fx( IF( sts[0]->cldfbSynTd != NULL ) { cldfb_reset_memory_fx( sts[0]->cldfbSynTd ); - sts[0]->currEnergyLookAhead_fx = 130996; + sts[0]->currEnergyLookAhead_fx = 130996; /* Q31 */ move32(); } @@ -831,7 +846,7 @@ void stereo_switching_enc_fx( test(); IF( hCPE->hStereoTD != NULL && EQ_16( hCPE->hStereoTD->tdm_last_ratio_idx, LRTD_STEREO_LEFT_IS_PRIM ) ) { - v_multc_fixed_32_16( hCPE->hCoreCoder[1]->old_input_signal_fx + sub( input_frame, add( offset, NS2SA( input_frame * FRAMES_PER_SEC, L_MEM_RECALC_TBE_NS ) ) ), -MAX_32, sts[1]->cldfbAnaEnc->cldfb_state_fx, offset ); + v_multc_fixed_32_16( hCPE->hCoreCoder[1]->old_input_signal_fx + sub( input_frame, add( offset, NS2SA_FX2( L_mult0( input_frame, FRAMES_PER_SEC ), L_MEM_RECALC_TBE_NS ) ) ), -MAX_32, sts[1]->cldfbAnaEnc->cldfb_state_fx, offset ); /* Q16+q_inp */ sts[1]->cldfbAnaEnc->Q_cldfb_state = add( Q16, q_inp ); move16(); } @@ -839,7 +854,7 @@ void stereo_switching_enc_fx( { FOR( i = 0; i < offset; i++ ) { - sts[1]->cldfbAnaEnc->cldfb_state_fx[i] = L_shr( L_deposit_h( hCPE->hCoreCoder[1]->old_input_signal_fx[input_frame - offset - NS2SA( input_frame * FRAMES_PER_SEC, L_MEM_RECALC_TBE_NS ) + i] ), 5 ); + sts[1]->cldfbAnaEnc->cldfb_state_fx[i] = L_shr( L_deposit_h( hCPE->hCoreCoder[1]->old_input_signal_fx[input_frame - offset - NS2SA_FX2( L_mult0( input_frame, FRAMES_PER_SEC ), L_MEM_RECALC_TBE_NS ) + i] ), 5 ); /* Q11+q_inp */ move32(); } sts[1]->cldfbAnaEnc->Q_cldfb_state = add( Q16 - 5, q_inp ); @@ -849,7 +864,7 @@ void stereo_switching_enc_fx( IF( sts[1]->cldfbSynTd != NULL ) { cldfb_reset_memory_fx( sts[1]->cldfbSynTd ); - sts[1]->currEnergyLookAhead_fx = 130996; + sts[1]->currEnergyLookAhead_fx = 130996; /* Q31 */ move32(); } } @@ -909,32 +924,32 @@ void stereo_switching_enc_fx( { Copy( sts[0]->hLPDmem->old_exc, sts[1]->hLPDmem->old_exc, L_EXC_MEM ); } - Copy( sts[0]->lsf_old_fx, sts[1]->lsf_old_fx, M ); - Copy( sts[0]->lsp_old_fx, sts[1]->lsp_old_fx, M ); - Copy( sts[0]->lsf_old1_fx, sts[1]->lsf_old1_fx, M ); - Copy( sts[0]->lsp_old1_fx, sts[1]->lsp_old1_fx, M ); + Copy( sts[0]->lsf_old_fx, sts[1]->lsf_old_fx, M ); /* Qlog2(2.56) */ + Copy( sts[0]->lsp_old_fx, sts[1]->lsp_old_fx, M ); /* Q15 */ + Copy( sts[0]->lsf_old1_fx, sts[1]->lsf_old1_fx, M ); /* Qlog2(2.56) */ + Copy( sts[0]->lsp_old1_fx, sts[1]->lsp_old1_fx, M ); /* Q15 */ sts[1]->GSC_noisy_speech = 0; move16(); IF( EQ_16( hCPE->element_mode, IVAS_CPE_MDCT ) ) { /* cross-fade overlap region of DFT Stereo downmix and original stereo channels */ - tmp_fx = div_s( 64, shl( sts[0]->encoderLookahead_FB, Q6 ) ); + tmp_fx = div_s( 64, shl( sts[0]->encoderLookahead_FB, Q6 ) ); /* Q15 */ FOR( i = 0; i < sts[0]->encoderLookahead_FB; i++ ) { - sts[1]->input32_fx[-sts[0]->encoderLookahead_FB + i] = L_shr( Mpy_32_16_1( L_add( Mpy_32_16_1( sts[0]->input32_fx[-sts[0]->encoderLookahead_FB + i], sts[0]->encoderLookahead_FB - i ), Mpy_32_16_1( sts[1]->input32_fx[-sts[0]->encoderLookahead_FB + i], i ) ), tmp_fx ), 13 ); + sts[1]->input32_fx[-sts[0]->encoderLookahead_FB + i] = L_shr( Mpy_32_16_1( L_add( Mpy_32_16_1( sts[0]->input32_fx[-sts[0]->encoderLookahead_FB + i], sts[0]->encoderLookahead_FB - i ), Mpy_32_16_1( sts[1]->input32_fx[-sts[0]->encoderLookahead_FB + i], i ) ), tmp_fx ), 13 ); /* q_inp32+0-15+15-15-13 */ move32(); - sts[0]->input32_fx[-sts[0]->encoderLookahead_FB + i] = L_shr( Mpy_32_16_1( L_add( Mpy_32_16_1( sts[0]->input32_fx[-sts[0]->encoderLookahead_FB + i], sts[0]->encoderLookahead_FB - i ), Mpy_32_16_1( sts[1]->input32_fx[-2 * sts[0]->encoderLookahead_FB + i], i ) ), tmp_fx ), 13 ); + sts[0]->input32_fx[-sts[0]->encoderLookahead_FB + i] = L_shr( Mpy_32_16_1( L_add( Mpy_32_16_1( sts[0]->input32_fx[-sts[0]->encoderLookahead_FB + i], sts[0]->encoderLookahead_FB - i ), Mpy_32_16_1( sts[1]->input32_fx[-2 * sts[0]->encoderLookahead_FB + i], i ) ), tmp_fx ), 13 ); /* q_inp32+0-15+15-15-13 */ move32(); } /* restore continuous signal in right channel (part of old_output was used to store original left channel) */ - Copy32( sts[0]->input32_fx - sts[0]->hTcxEnc->L_frameTCX, sts[1]->input32_fx - sts[0]->hTcxEnc->L_frameTCX, sts[0]->hTcxEnc->L_frameTCX - sts[0]->encoderLookahead_FB ); + Copy32( sts[0]->input32_fx - sts[0]->hTcxEnc->L_frameTCX, sts[1]->input32_fx - sts[0]->hTcxEnc->L_frameTCX, sub( sts[0]->hTcxEnc->L_frameTCX, sts[0]->encoderLookahead_FB ) ); /* sts[0]->q_inp32 */ - sts[1]->last_core = sts[0]->last_core; + sts[1]->last_core = sts[0]->last_core; /* Q0 */ move16(); - sts[1]->last_coder_type = sts[0]->last_coder_type; + sts[1]->last_coder_type = sts[0]->last_coder_type; /* Q0 */ move16(); - sts[1]->last_bwidth = sts[0]->last_bwidth; + sts[1]->last_bwidth = sts[0]->last_bwidth; /* Q0 */ move16(); } } @@ -949,7 +964,7 @@ void stereo_switching_enc_fx( test(); IF( EQ_16( hCPE->element_mode, IVAS_CPE_MDCT ) && NE_16( hCPE->last_element_mode, IVAS_CPE_MDCT ) ) { - sts[1]->hTcxCfg->last_aldo = sts[0]->hTcxCfg->last_aldo; + sts[1]->hTcxCfg->last_aldo = sts[0]->hTcxCfg->last_aldo; /* Q0 */ move16(); sts[1]->hTcxCfg->tcx_curr_overlap_mode = sts[0]->hTcxCfg->tcx_curr_overlap_mode; move16(); diff --git a/lib_enc/ivas_stereo_td_analysis.c b/lib_enc/ivas_stereo_td_analysis_fx.c similarity index 82% rename from lib_enc/ivas_stereo_td_analysis.c rename to lib_enc/ivas_stereo_td_analysis_fx.c index fdf53370e97239e1b7f5e94d5c0e0c55d6db3c51..44c08efa8a4fc05b01735b8127d84623b0ef3711 100644 --- a/lib_enc/ivas_stereo_td_analysis.c +++ b/lib_enc/ivas_stereo_td_analysis_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other @@ -35,14 +35,12 @@ #include #include "cnst.h" #include "rom_com.h" -#include "prot.h" -#include "ivas_prot.h" +#include "prot_fx.h" #include "ivas_rom_com.h" #include "ivas_cnst.h" #include "rom_enc.h" #include "wmc_auto.h" #include "ivas_prot_fx.h" -#include "prot_fx.h" #include "ivas_rom_com_fx.h" @@ -74,9 +72,13 @@ #define RATIO_MAX 1.5f /* Maximum correlation ratio */ #define RATIO_MAX_FX_Q30 ( 1610612736 ) /* 1.5f in Q30 */ /* Maximum correlation ratio */ -#define RATIO_MAX_FX_Q24 ( 2516582 ) /* 1.5f in Q24 */ /* Maximum correlation ratio */ -#define RATIO_MAX_FX_Q23 ( 1258291 ) /* 1.5f in Q23 */ /* Maximum correlation ratio */ - +#ifdef FIX_1301_CORRECT_TD_CNST +#define RATIO_MAX_FX_Q24 ( 25165824 ) /* 1.5f in Q24 */ /* Maximum correlation ratio */ +#define RATIO_MAX_FX_Q23 ( 12582912 ) /* 1.5f in Q23 */ /* Maximum correlation ratio */ +#else +#define RATIO_MAX_FX_Q24 ( 2516582 ) /* 1.5f in Q24 */ /* Maximum correlation ratio */ +#define RATIO_MAX_FX_Q23 ( 1258291 ) /* 1.5f in Q23 */ /* Maximum correlation ratio */ +#endif #define LIMIT_ADAP_FAC_FX_Q16 ( 9830 ) /* 0.15f in Q16 */ #define MIN_ADAP_FAC_FX_Q16 ( 6554 ) /*0.1f in Q16*/ #define M_ADAP_FX_Q31 ( 1932735 ) /* 0.0009f in Q31 */ @@ -114,23 +116,23 @@ * Local function prototypes *-------------------------------------------------------------------*/ -static Word16 stereo_tdm_ener_analysis_SM_fx( CPE_ENC_HANDLE hCPE, Encoder_State **sts, const Word16 input_frame, Word16 *tdm_SM_flag ); +static Word16 stereo_tdm_ener_analysis_SM_fx( CPE_ENC_HANDLE hCPE, Encoder_State **sts, const Word16 input_frame /*Q0*/, Word16 *tdm_SM_flag /*Q0*/ ); -static void Get_corr_n_fx( const Word16 L[], const Word16 R[], Word32 *ic_Lm, Word16 *q_ic_Lm, Word32 *ic_Rm, Word16 *q_ic_Rm, const Word16 len, Word32 *es_em, const Word16 tdm_SM_calc_flag ); +static void Get_corr_n_fx( const Word16 L[] /*q_in*/, const Word16 R[] /*q_in*/, Word32 *ic_Lm, Word16 *q_ic_Lm, Word32 *ic_Rm, Word16 *q_ic_Rm, const Word16 len, Word32 *es_em, const Word16 tdm_SM_calc_flag ); static Word16 stereo_smooth_LR_transition_fx( Word16 *tdm_prev_stable_idx, Word16 *tdm_ratio_transition_mov_flag, Word16 tdm_last_ratio_idx, Word16 *tdm_prev_desired_idx, Word16 *tdm_ratio_transition_cnt, const Word16 tdm_SM_flag, Word16 desired_idx ); -static Word16 limit_idx_Dwnmix_fx( const Word16 idx_in, const Word16 unclr_decision, const Word16 inst_idx, const Word16 previous_idx, const Word16 tdm_last_LRTD_PriCh_cnt, const Word16 tdm_last_LRTD_frame_cnt ); +static Word16 limit_idx_Dwnmix_fx( const Word16 idx_in /*Q0*/, const Word16 unclr_decision /*Q0*/, const Word16 inst_idx /*Q0*/, const Word16 previous_idx /*Q0*/, const Word16 tdm_last_LRTD_PriCh_cnt /*Q0*/, const Word16 tdm_last_LRTD_frame_cnt /*Q0*/ ); -static Word16 limit_idx_NoDwnmix_fx( const Word16 idx_in, const Word16 side_can_change, const Word32 d_lt_corr_raw, const Word16 q_d_lt_corr_raw ); +static Word16 limit_idx_NoDwnmix_fx( const Word16 idx_in /*Q0*/, const Word16 side_can_change /*Q0*/, const Word32 d_lt_corr_raw, const Word16 q_d_lt_corr_raw ); -static void Get_LR_rms_fx( const Word16 *Left_in, const Word16 *Right_in, const Word16 input_frame, Word32 *rms_L, Word16 *q_rms_L, Word32 *rms_R, Word16 *q_rms_R ); +static void Get_LR_rms_fx( const Word16 *Left_in /*q_inp*/, const Word16 *Right_in /*q_inp*/, const Word16 input_frame, Word32 *rms_L, Word16 *q_rms_L, Word32 *rms_R, Word16 *q_rms_R ); -static Word16 Get_dt_lt_ener_fx( CPE_ENC_HANDLE hCPE, const Word16 IsSideMono, const Word16 input_frame, const Word16 tdm_last_SM_flag, const Word32 rms_L, const Word16 q_rms_L, const Word32 rms_R, const Word16 q_rms_R, Word32 *tdm_lt_rms_L, Word32 *tdm_lt_rms_R, Word32 *tdm_last_ener_lt_L, Word32 *tdm_last_ener_lt_R, Word32 *tdm_LT_es_em, Word16 *tdm_hyst_cnt, Word16 *tdm_NOOP_SM_flag_loc, Word32 *ener_R_dt, Word32 *ener_L_dt, Word32 *corr_LM, Word16 *q_corr_LM, Word32 *corr_RM, Word16 *q_corr_RM ); +static Word16 Get_dt_lt_ener_fx( CPE_ENC_HANDLE hCPE, const Word16 IsSideMono, const Word16 input_frame, const Word16 tdm_last_SM_flag, const Word32 rms_L, const Word16 q_rms_L, const Word32 rms_R, const Word16 q_rms_R, Word32 *tdm_lt_rms_L /*Q16*/, Word32 *tdm_lt_rms_R /*Q16*/, Word32 *tdm_last_ener_lt_L /*Q16*/, Word32 *tdm_last_ener_lt_R /*Q16*/, Word32 *tdm_LT_es_em /*Q21*/, Word16 *tdm_hyst_cnt, Word16 *tdm_NOOP_SM_flag_loc, Word32 *ener_R_dt /*Q16*/, Word32 *ener_L_dt /*Q16*/, Word32 *corr_LM, Word16 *q_corr_LM, Word32 *corr_RM, Word16 *q_corr_RM ); -static void NOOP_decision_fx( CPE_ENC_HANDLE hCPE, const Word16 tdm_NOOP_flag_loc, const Word16 tmp_SM_flag, const Word32 rms_L, const Word16 q_rms_L, const Word32 rms_R, const Word16 q_rms_R, Word16 *tdm_SM_flag_loc ); +static void NOOP_decision_fx( CPE_ENC_HANDLE hCPE, const Word16 tdm_NOOP_flag_loc /*Q0*/, const Word16 tmp_SM_flag /*Q0*/, const Word32 rms_L, const Word16 q_rms_L, const Word32 rms_R, const Word16 q_rms_R, Word16 *tdm_SM_flag_loc /*Q0*/ ); -static Word32 Comp_diff_lt_corr_fx( CPE_ENC_HANDLE hCPE, const Word16 IsSideMono, const Word32 rms_L, const Word16 q_rms_L, const Word32 rms_R, const Word16 q_rms_R, const Word32 ener_L_dt, const Word32 ener_R_dt, Word32 corr_LM, Word16 q_corr_LM, Word32 corr_RM, Word16 q_corr_RM, const Word32 tdm_lt_rms_L, const Word32 tdm_lt_rms_R, Word32 *tdm_lt_corr_LM, Word32 *tdm_lt_corr_RM, Word32 *tdm_last_diff_lt_corr, Word16 *q_tdm_last_diff_lt_corr, Word32 *inst_ratio_L_out, Word32 *diff_lt_corr, Word16 *q_d_lt_corr_raw ); +static Word32 Comp_diff_lt_corr_fx( CPE_ENC_HANDLE hCPE, const Word16 IsSideMono /*Q0*/, const Word32 rms_L, const Word16 q_rms_L, const Word32 rms_R, const Word16 q_rms_R, const Word32 ener_L_dt /*Q16*/, const Word32 ener_R_dt /*Q16*/, Word32 corr_LM, Word16 q_corr_LM, Word32 corr_RM, Word16 q_corr_RM, const Word32 tdm_lt_rms_L /*Q16*/, const Word32 tdm_lt_rms_R /*Q16*/, Word32 *tdm_lt_corr_LM /*Q24*/, Word32 *tdm_lt_corr_RM /*Q24*/, Word32 *tdm_last_diff_lt_corr, Word16 *q_tdm_last_diff_lt_corr, Word32 *inst_ratio_L_out /*Q24*/, Word32 *diff_lt_corr, Word16 *q_d_lt_corr_raw ); /*-------------------------------------------------------------------* @@ -140,9 +142,9 @@ static Word32 Comp_diff_lt_corr_fx( CPE_ENC_HANDLE hCPE, const Word16 IsSideMono Word16 stereo_tdm_ener_analysis_fx( const Word16 ivas_format, /* i : IVAS format */ CPE_ENC_HANDLE hCPE, /* i : CPE structure */ - const Word16 input_frame, /* i : Number of samples */ - Word16 *tdm_SM_or_LRTD_Pri, /* o : channel combination scheme flag in TD stereo OR LRTD primary channel */ - Word16 *tdm_ratio_idx_SM /* o : TDM ratio index for SM mode */ + const Word16 input_frame, /* i : Number of samples Q0*/ + Word16 *tdm_SM_or_LRTD_Pri, /* o : channel combination scheme flag in TD stereo OR LRTD primary channel Q0*/ + Word16 *tdm_ratio_idx_SM /* o : TDM ratio index for SM mode Q0*/ ) { Word32 diff_lt_corr_fx /*Q24*/; @@ -189,7 +191,7 @@ Word16 stereo_tdm_ener_analysis_fx( * - evolution of the L and R to Mono gain *----------------------------------------------------------------*/ - tdm_SM_flag_loc = hStereoTD->tdm_last_SM_flag; + tdm_SM_flag_loc = hStereoTD->tdm_last_SM_flag; /* Q0 */ move16(); tmp_SM_flag = Get_dt_lt_ener_fx( hCPE, 0, input_frame, hStereoTD->tdm_last_SM_flag, rms_L_fx, q_rms_L, rms_R_fx, q_rms_R, @@ -218,7 +220,7 @@ Word16 stereo_tdm_ener_analysis_fx( IF( GT_16( q_d_lt_corr_raw, 31 ) ) { - d_lt_corr_raw_fx = L_shr( d_lt_corr_raw_fx, sub( q_d_lt_corr_raw, Q31 ) ); + d_lt_corr_raw_fx = L_shr( d_lt_corr_raw_fx, sub( q_d_lt_corr_raw, Q31 ) ); /* Q31 */ q_d_lt_corr_raw = Q31; move16(); } @@ -232,7 +234,7 @@ Word16 stereo_tdm_ener_analysis_fx( xtalk_classifier_td_fx( hCPE ); /* switch to LRTD on cross-talk segments where two speakers are weakly correlated */ - hStereoTD->prev_fr_LRTD_TD_dec = hCPE->hStereoClassif->lrtd_mode; + hStereoTD->prev_fr_LRTD_TD_dec = hCPE->hStereoClassif->lrtd_mode; /* Q0 */ move16(); /*----------------------------------------------------------------* @@ -251,14 +253,18 @@ Word16 stereo_tdm_ener_analysis_fx( } } - rms_thd_fx = RMS_MIN_Q16; + rms_thd_fx = RMS_MIN_Q16; /* Q16 */ move32(); IF( EQ_16( hCPE->hStereoClassif->lrtd_mode, 1 ) ) { rms_thd_fx = L_shr( rms_thd_fx, 2 ); /*Q16*/ /*rms_thd_fx *= 0.25f*/ test(); test(); +#ifdef FIX_1301_CORRECT_TD_CNST + IF( LE_32( hStereoTD->tdm_lt_rms_L_fx, 4915200 /* 75 in Q16*/ ) || LE_32( hStereoTD->tdm_lt_rms_R_fx, 4915200 /* 75 in Q16*/ ) /*|| sts[0]->last_coder_type == TRANSITION */ ) +#else IF( LE_32( hStereoTD->tdm_lt_rms_L_fx, 4915200 /* 75 in Q16*/ ) || LE_32( hStereoTD->tdm_lt_rms_R_fx, 75 /* 75 in Q16*/ ) /*|| sts[0]->last_coder_type == TRANSITION */ ) +#endif { rms_thd_fx = L_shr( rms_thd_fx, 5 ); /* Q16*/ /*rms_thd_fx *= 0.03125f*/ } @@ -326,12 +332,16 @@ Word16 stereo_tdm_ener_analysis_fx( move16(); } - if ( NE_16( hCPE->last_element_mode, IVAS_CPE_TD ) ) + IF( NE_16( hCPE->last_element_mode, IVAS_CPE_TD ) ) { side_can_change = 1; move16(); } +#ifdef FIX_1301_CORRECT_TD_CNST + rms_L_fx = L_shl( rms_L_fx, sub( Q16, q_rms_L ) ); /* All the following energy comparison are done in Q16 */ + rms_R_fx = L_shl( rms_R_fx, sub( Q16, q_rms_R ) ); +#endif test(); IF( EQ_16( hStereoTD->prev_fr_LRTD_TD_dec, 1 ) && side_can_change == 0 ) { @@ -353,8 +363,8 @@ Word16 stereo_tdm_ener_analysis_fx( test(); test(); test(); - if ( ( ( LT_32( rms_L_fx, RMS_THR_Q16 ) && LT_32( rms_R_fx, RMS_THR_Q16 ) && LT_32( L_abs( L_sub( rms_R_fx, rms_L_fx ) ), RMS_THR_Q16 / 2 ) && GT_32( L_abs( d_lt_corr_raw_fx ), L_shr( 644245094 /*0.3f in Q31*/, sub( Q31, q_d_lt_corr_raw ) ) ) ) || - ( LT_16( abs_s( sub( sts[0]->old_corr_fx, sts[1]->old_corr_fx ) ), 4915 /*0.15f in Q15*/ ) && GT_16( sts[0]->old_corr_fx, 22937 /*0.7f in Q15*/ ) && LT_16( sts[0]->old_corr_fx, 27853 /*0.85f in Q15*/ ) && LT_32( L_abs( L_sub( rms_L_fx, rms_R_fx ) ), rms_thd_fx ) && GT_32( L_abs( d_lt_corr_raw_fx ), L_shr( 644245094 /*0.3f in Q31*/, sub( Q31, q_d_lt_corr_raw ) ) ) ) ) /* Both channels are low energy, clean background switching is allowed */ + IF( ( ( LT_32( rms_L_fx, RMS_THR_Q16 ) && LT_32( rms_R_fx, RMS_THR_Q16 ) && LT_32( L_abs( L_sub( rms_R_fx, rms_L_fx ) ), RMS_THR_Q16 / 2 ) && GT_32( L_abs( d_lt_corr_raw_fx ), L_shr( 644245094 /*0.3f in Q31*/, sub( Q31, q_d_lt_corr_raw ) ) ) ) || + ( LT_16( abs_s( sub( sts[0]->old_corr_fx, sts[1]->old_corr_fx ) ), 4915 /*0.15f in Q15*/ ) && GT_16( sts[0]->old_corr_fx, 22937 /*0.7f in Q15*/ ) && LT_16( sts[0]->old_corr_fx, 27853 /*0.85f in Q15*/ ) && LT_32( L_abs( L_sub( rms_L_fx, rms_R_fx ) ), rms_thd_fx ) && GT_32( L_abs( d_lt_corr_raw_fx ), L_shr( 644245094 /*0.3f in Q31*/, sub( Q31, q_d_lt_corr_raw ) ) ) ) ) /* Both channels are low energy, clean background switching is allowed */ ) { side_can_change = 1; @@ -388,7 +398,7 @@ Word16 stereo_tdm_ener_analysis_fx( test(); test(); - if ( GE_32( hCPE->hStereoClassif->xtalk_wscore_fx, 107374182 /*0.05f in Q31*/ ) && hStereoTD->prev_fr_LRTD_TD_dec == 0 && EQ_16( hCPE->hStereoClassif->lrtd_mode, 1 ) ) + IF( GE_32( hCPE->hStereoClassif->xtalk_wscore_fx, 107374182 /*0.05f in Q31*/ ) && hStereoTD->prev_fr_LRTD_TD_dec == 0 && EQ_16( hCPE->hStereoClassif->lrtd_mode, 1 ) ) { side_can_change = 0; move16(); @@ -430,7 +440,11 @@ Word16 stereo_tdm_ener_analysis_fx( ELSE { /*ratio_L = ( 1.0f - cosf( EVS_PI * ratio_L / 2.0f ) ) / 2.0f;*/ +#ifdef FIX_1301_CORRECT_TD_CNST + ratio_L_fx = L_deposit_h( sub_sat( ONE_IN_Q14, getCosWord16( extract_l( Mpy_32_32( 1647099 /* EVS_PI/2 in Q20 */, ratio_L_fx ) ) ) ) ); // Q31 (Q14 + Q1(division by 2.0f) + Q16) +#else ratio_L_fx = L_deposit_h( sub( ONE_IN_Q14, getCosWord16( extract_l( Mpy_32_32( 1647099 /* EVS_PI/2 in Q20 */, ratio_L_fx ) ) ) ) ); // Q31 (Q14 + Q1(division by 2.0f) + Q16) +#endif } test(); @@ -478,16 +492,16 @@ Word16 stereo_tdm_ener_analysis_fx( { test(); test(); - if ( GE_32( hCPE->element_brate, IVAS_48k ) && sts[0]->hVAD->hangover_cnt != 0 && LT_32( L_max( hStereoTD->tdm_lt_rms_L_fx, hStereoTD->tdm_lt_rms_R_fx ), 33554432 /* 512.0f */ ) ) + IF( GE_32( hCPE->element_brate, IVAS_48k ) && sts[0]->hVAD->hangover_cnt != 0 && LT_32( L_max( hStereoTD->tdm_lt_rms_L_fx, hStereoTD->tdm_lt_rms_R_fx ), 33554432 /* 512.0f in Q16*/ ) ) { - ratio_L_fx = check_bounds_l( ratio_L_fx, 644245094 /*0.3f in Q31*/, 1503238554 /*0.7f in Q31*/ ); + ratio_L_fx = check_bounds_l( ratio_L_fx, 644245094 /*0.3f in Q31*/, 1503238554 /*0.7f in Q31*/ ); /* Q31 */ } test(); test(); test(); test(); - IF( ( GT_32( hCPE->hStereoTCA->instTargetGain_fx, 644245094 /*1.2f in Q29*/ ) || GT_32( hCPE->hStereoTCA->targetGain_fx, ONE_IN_Q29 ) ) && LT_32( ratio_L_fx, 858993459 /*0.4f*/ ) ) + IF( ( GT_32( hCPE->hStereoTCA->instTargetGain_fx, 644245094 /*1.2f in Q29*/ ) || GT_32( hCPE->hStereoTCA->targetGain_fx, ONE_IN_Q29 ) ) && LT_32( ratio_L_fx, 858993459 /*0.4f in Q31*/ ) ) { ratio_L_fx = 858993459; /*0.4f in Q31*/ move32(); @@ -512,7 +526,7 @@ Word16 stereo_tdm_ener_analysis_fx( } } - idx = stereo_smooth_LR_transition_fx( &hStereoTD->tdm_prev_stable_idx, &hStereoTD->tdm_ratio_transition_mov_flag, hStereoTD->tdm_last_ratio_idx, &hStereoTD->tdm_prev_desired_idx, &hStereoTD->tdm_ratio_transition_cnt, tdm_SM_flag_loc, desired_idx ); + idx = stereo_smooth_LR_transition_fx( &hStereoTD->tdm_prev_stable_idx, &hStereoTD->tdm_ratio_transition_mov_flag, hStereoTD->tdm_last_ratio_idx, &hStereoTD->tdm_prev_desired_idx, &hStereoTD->tdm_ratio_transition_cnt, tdm_SM_flag_loc, desired_idx ); /* Q0 */ /* Change the switching level in case of dual mono (in case the scenario still accept left right switching */ /* This logic is needed in case the content is exactly the same in the 2 channel and it is expected to get back to LRTD, to prevent the secondary channel to be completely empty */ @@ -565,7 +579,7 @@ Word16 stereo_tdm_ener_analysis_fx( } } - IF( LT_16( sub( sts[1]->lp_speech_fx, sts[1]->lp_noise_fx ), 12800 /*50.0f*/ ) ) /* likely presence of noisy content */ + IF( LT_16( sub( sts[1]->lp_speech_fx, sts[1]->lp_noise_fx ), 12800 /*50.0f in Q8*/ ) ) /* likely presence of noisy content */ { /* pointing in the right direction, inverse it else do nothing */ test(); @@ -577,19 +591,19 @@ Word16 stereo_tdm_ener_analysis_fx( Word16 idx_offet; idx_offet = 5; move16(); - if ( GT_16( desired_idx, LRTD_STEREO_MID_IS_PRIM ) ) /* slightly Favor the 2nd channel */ + IF( GT_16( desired_idx, LRTD_STEREO_MID_IS_PRIM ) ) /* slightly Favor the 2nd channel */ { idx_offet = negate( idx_offet ); } desired_idx = add( desired_idx, idx_offet ); - desired_idx = check_bounds_s_fx( desired_idx, 0, 30 ); + desired_idx = check_bounds_s_fx( desired_idx, 0, 30 ); /* Q0 */ } } test(); IF( sts[1]->clas != UNVOICED_CLAS || sts[0]->clas != UNVOICED_CLAS ) { - desired_idx = check_bounds_s_fx( desired_idx, 5, 25 ); + desired_idx = check_bounds_s_fx( desired_idx, 5, 25 ); /* Q0 */ } hStereoTD->tdm_inst_ratio_idx = desired_idx; @@ -635,14 +649,23 @@ Word16 stereo_tdm_ener_analysis_fx( hStereoTD->tdm_last_LRTD_PriCh_cnt = add( hStereoTD->tdm_last_LRTD_PriCh_cnt, 1 ); move16(); } - ratio_L_fx = tdm_ratio_tabl_fx[idx]; // Q31 + +#ifdef FIX_ISSUE_1125 + ratio_L_fx = tdm_ratio_tabl_fx_Q30[idx]; // Q30 +#else + ratio_L_fx = tdm_ratio_tabl_fx[idx]; // Q31 +#endif move32(); test(); IF( EQ_16( hStereoTD->tdm_SM_modi_flag, 1 ) && hStereoTD->tdm_LRTD_flag == 0 ) { idx = shr( add( hStereoTD->tdm_last_ratio_idx, add( LRTD_STEREO_MID_IS_PRIM, 1 ) ), 1 ); - ratio_L_fx = tdm_ratio_tabl_fx[idx]; // Q31 +#ifdef FIX_ISSUE_1125 + ratio_L_fx = tdm_ratio_tabl_fx_Q30[idx]; // Q30 +#else + ratio_L_fx = tdm_ratio_tabl_fx[idx]; // Q31 +#endif move32(); } @@ -673,9 +696,9 @@ Word16 stereo_tdm_ener_analysis_fx( move32(); hStereoTD->tdm_lt_corr_LM_SM_fx = 167772 /*0.01f Q24*/; move32(); - hStereoTD->tdm_last_ratio_SM_fx = hStereoTD->tdm_last_ratio_fx; + hStereoTD->tdm_last_ratio_SM_fx = hStereoTD->tdm_last_ratio_fx; /* Q31 */ move32(); - hStereoTD->tdm_last_ratio_idx_SM = hStereoTD->tdm_last_ratio_idx; + hStereoTD->tdm_last_ratio_idx_SM = hStereoTD->tdm_last_ratio_idx; /* Q0 */ move16(); hStereoTD->tdm_lt_rms_L_SM_fx = 2621440; // 40.0f Q16 move32(); @@ -706,7 +729,7 @@ Word16 stereo_tdm_ener_analysis_fx( move16(); } - *tdm_ratio_idx_SM = stereo_tdm_ener_analysis_SM_fx( hCPE, sts, input_frame, &tdm_NOOP_flag ); + *tdm_ratio_idx_SM = stereo_tdm_ener_analysis_SM_fx( hCPE, sts, input_frame, &tdm_NOOP_flag ); /* Q0 */ move16(); } ELSE @@ -723,16 +746,20 @@ Word16 stereo_tdm_ener_analysis_fx( move16(); /* set channel combination scheme flag */ - *tdm_SM_or_LRTD_Pri = tdm_SM_flag_loc; + *tdm_SM_or_LRTD_Pri = tdm_SM_flag_loc; /* Q0 */ move16(); if ( EQ_16( hCPE->hStereoTD->tdm_LRTD_flag, 1 ) ) { - *tdm_SM_or_LRTD_Pri = tdm_LRTD_pri_side; + *tdm_SM_or_LRTD_Pri = tdm_LRTD_pri_side; /* Q0 */ move16(); } - hCPE->hStereoClassif->ratio_L_fx = ratio_L_fx; + hCPE->hStereoClassif->ratio_L_fx = ratio_L_fx; /* 31 - ratio_L_e */ move32(); +#ifdef FIX_ISSUE_1125 + hCPE->hStereoClassif->ratio_L_e = 1; + move16(); +#endif return idx; } @@ -744,12 +771,12 @@ Word16 stereo_tdm_ener_analysis_fx( *-------------------------------------------------------------------*/ static void Get_LR_rms_fx( - const Word16 *Left_in, - const Word16 *Right_in, - const Word16 input_frame, - Word32 *rms_L, + const Word16 *Left_in, /* q_inp */ + const Word16 *Right_in, /* q_inp */ + const Word16 input_frame, /* Q0 */ + Word32 *rms_L, /* q_rms_L */ Word16 *q_rms_L, - Word32 *rms_R, + Word32 *rms_R, /* q_rms_R */ Word16 *q_rms_R ) { Word32 ener_l, ener_r; @@ -763,9 +790,9 @@ static void Get_LR_rms_fx( move64(); W_ener_r_tmp = 0; move64(); - ener_l = ONE_BY_100_Q31; + ener_l = ONE_BY_100_Q31; /* Q31 */ move32(); - ener_r = ONE_BY_100_Q31; + ener_r = ONE_BY_100_Q31; /* Q31 */ move32(); guard_bits = sub( 32, find_guarded_bits_fx( input_frame ) ); @@ -778,12 +805,12 @@ static void Get_LR_rms_fx( ener_l_tmp = W_extract_h( W_shl( W_ener_l_tmp, guard_bits ) ); // guard_bits - 32 ener_r_tmp = W_extract_h( W_shl( W_ener_r_tmp, guard_bits ) ); // guard_bits - 32 - ener_l = BASOP_Util_Add_Mant32Exp( ener_l, 0, ener_l_tmp, sub( Q31, sub( guard_bits, 32 ) ), &exp_out_l ); - ener_r = BASOP_Util_Add_Mant32Exp( ener_r, 0, ener_r_tmp, sub( Q31, sub( guard_bits, 32 ) ), &exp_out_r ); + ener_l = BASOP_Util_Add_Mant32Exp( ener_l, 0, ener_l_tmp, sub( Q31, sub( guard_bits, 32 ) ), &exp_out_l ); /* Q31-exp_out_l */ + ener_r = BASOP_Util_Add_Mant32Exp( ener_r, 0, ener_r_tmp, sub( Q31, sub( guard_bits, 32 ) ), &exp_out_r ); /* Q31-exp_out_r */ - ener_l_tmp = BASOP_Util_Divide3232_Scale( ener_l, input_frame, &exp_diff ); + ener_l_tmp = BASOP_Util_Divide3232_Scale( ener_l, input_frame, &exp_diff ); /* Q31- exp_out_l*/ exp_out_l = sub( add( exp_diff, exp_out_l ), Q15 ); - ener_r_tmp = BASOP_Util_Divide3232_Scale( ener_r, input_frame, &exp_diff ); + ener_r_tmp = BASOP_Util_Divide3232_Scale( ener_r, input_frame, &exp_diff ); /* Q31-exp_out_r */ exp_out_r = sub( add( exp_diff, exp_out_r ), Q15 ); *rms_L = Sqrt32( ener_l_tmp, &exp_out_l ); // Q31 - exp_out_l @@ -811,25 +838,25 @@ static void Get_LR_rms_fx( static Word16 Get_dt_lt_ener_fx( CPE_ENC_HANDLE hCPE, - const Word16 IsSideMono, - const Word16 input_frame, - const Word16 tdm_last_SM_flag, - const Word32 rms_L, + const Word16 IsSideMono, /* Q0 */ + const Word16 input_frame, /* Q0 */ + const Word16 tdm_last_SM_flag, /* Q0 */ + const Word32 rms_L, /* q_rms_L */ const Word16 q_rms_L, - const Word32 rms_R, + const Word32 rms_R, /* q_rms_R */ const Word16 q_rms_R, - Word32 *tdm_lt_rms_L, - Word32 *tdm_lt_rms_R, - Word32 *tdm_last_ener_lt_L, - Word32 *tdm_last_ener_lt_R, - Word32 *tdm_LT_es_em, - Word16 *tdm_hyst_cnt, - Word16 *tdm_NOOP_SM_flag_loc, - Word32 *ener_R_dt, - Word32 *ener_L_dt, - Word32 *corr_LM, + Word32 *tdm_lt_rms_L, /* Q16 */ + Word32 *tdm_lt_rms_R, /* Q16 */ + Word32 *tdm_last_ener_lt_L, /* Q16 */ + Word32 *tdm_last_ener_lt_R, /* Q16 */ + Word32 *tdm_LT_es_em, /* Q21 */ + Word16 *tdm_hyst_cnt, /* Q0 */ + Word16 *tdm_NOOP_SM_flag_loc, /* Q0 */ + Word32 *ener_R_dt, /* Q16 */ + Word32 *ener_L_dt, /* Q16 */ + Word32 *corr_LM, /* q_corr_LM */ Word16 *q_corr_LM, - Word32 *corr_RM, + Word32 *corr_RM, /* q_corr_RM */ Word16 *q_corr_RM ) { Encoder_State **sts; @@ -841,27 +868,27 @@ static Word16 Get_dt_lt_ener_fx( sts = hCPE->hCoreCoder; - Left_in_fx = sts[0]->input_fx; /* Left channel */ - Right_in_fx = sts[1]->input_fx; /* Right channel */ + Left_in_fx = sts[0]->input_fx; /* Left channel sts[0]->q_inp*/ + Right_in_fx = sts[1]->input_fx; /* Right channel sts[1]->q_inp*/ tmp = sub( getScaleFactor16( sts[0]->input_fx, input_frame ), 1 ); - Scale_sig( sts[0]->input_fx, input_frame, tmp ); + Scale_sig( sts[0]->input_fx, input_frame, tmp ); /* sts[0]->q_inp + tmp */ sts[0]->q_inp = add( tmp, sts[0]->q_inp ); move16(); tmp = getScaleFactor16( sts[1]->input_fx, input_frame ); - Scale_sig( sts[1]->input_fx, input_frame, tmp ); + Scale_sig( sts[1]->input_fx, input_frame, tmp ); /* sts[1]->q_inp + tmp */ sts[1]->q_inp = add( tmp, sts[1]->q_inp ); move16(); - Scale_sig( sts[0]->input_fx, input_frame, sub( s_min( sts[0]->q_inp, sts[1]->q_inp ), sts[0]->q_inp ) ); - Scale_sig( sts[1]->input_fx, input_frame, sub( s_min( sts[0]->q_inp, sts[1]->q_inp ), sts[1]->q_inp ) ); + Scale_sig( sts[0]->input_fx, input_frame, sub( s_min( sts[0]->q_inp, sts[1]->q_inp ), sts[0]->q_inp ) ); /* s_min( sts[0]->q_inp, sts[1]->q_inp ) */ + Scale_sig( sts[1]->input_fx, input_frame, sub( s_min( sts[0]->q_inp, sts[1]->q_inp ), sts[1]->q_inp ) ); /* s_min( sts[0]->q_inp, sts[1]->q_inp ) */ sts[1]->q_inp = s_min( sts[0]->q_inp, sts[1]->q_inp ); move16(); sts[0]->q_inp = sts[1]->q_inp; move16(); - tdm_SM_flag_loc = tdm_last_SM_flag; + tdm_SM_flag_loc = tdm_last_SM_flag; /* Q0 */ move16(); test(); @@ -916,7 +943,7 @@ static Word16 Get_dt_lt_ener_fx( Get_corr_n_fx( Left_in_fx, Right_in_fx, corr_LM, q_corr_LM, corr_RM, q_corr_RM, input_frame, &es_em_fx, IsSideMono ); - hCPE->hStereoClassif->xtalk_fv_fx[E_diff_corrLM_corrRM] = BASOP_Util_Add_Mant32Exp( *corr_LM, sub( Q31, *q_corr_LM ), L_negate( *corr_RM ), sub( Q31, *q_corr_RM ), &exp_diff ); + hCPE->hStereoClassif->xtalk_fv_fx[E_diff_corrLM_corrRM] = BASOP_Util_Add_Mant32Exp( *corr_LM, sub( Q31, *q_corr_LM ), L_negate( *corr_RM ), sub( Q31, *q_corr_RM ), &exp_diff ); /* Q31-exp_diff */ move32(); hCPE->hStereoClassif->xtalk_fv_fx[E_diff_corrLM_corrRM] = L_shl( hCPE->hStereoClassif->xtalk_fv_fx[E_diff_corrLM_corrRM], sub( Q15, sub( Q31, exp_diff ) ) ); // Q15 move32(); @@ -937,8 +964,15 @@ static Word16 Get_dt_lt_ener_fx( tmp_SM_flag = 0; move16(); - if ( LT_16( s_min( sts[0]->old_corr_fx, sts[1]->old_corr_fx ), 27853 /* 0.85f in Q15 */ ) && LT_16( s_max( sts[0]->old_corr_fx, sts[1]->old_corr_fx ), 30147 /* 0.92f in Q15 */ ) && - ( GT_32( *tdm_LT_es_em, ONE_IN_Q22 /* 2.0f in Q21 */ ) || GT_32( es_em_fx, 5242880 /* 2.5f in Q21 */ ) ) && ( LE_16( sts[0]->hVAD->hangover_cnt, 1 ) && LE_16( sts[1]->hVAD->hangover_cnt, 3 ) && sts[0]->tdm_LRTD_flag == 0 ) ) + + test(); + test(); + test(); + test(); + test(); + test(); + IF( LT_16( s_min( sts[0]->old_corr_fx, sts[1]->old_corr_fx ), 27853 /* 0.85f in Q15 */ ) && LT_16( s_max( sts[0]->old_corr_fx, sts[1]->old_corr_fx ), 30147 /* 0.92f in Q15 */ ) && + ( GT_32( *tdm_LT_es_em, ONE_IN_Q22 /* 2.0f in Q21 */ ) || GT_32( es_em_fx, 5242880 /* 2.5f in Q21 */ ) ) && ( LE_16( sts[0]->hVAD->hangover_cnt, 1 ) && LE_16( sts[1]->hVAD->hangover_cnt, 3 ) && sts[0]->tdm_LRTD_flag == 0 ) ) { tmp_SM_flag = 1; move16(); @@ -951,6 +985,9 @@ static Word16 Get_dt_lt_ener_fx( IF( NE_16( tmp_SM_flag, tdm_SM_flag_loc ) ) { + test(); + test(); + test(); IF( GE_16( *tdm_hyst_cnt, 2 ) && EQ_16( tmp_SM_flag, 1 ) && ( GT_16( sts[0]->tdm_pc, PC_LIMIT ) || GT_16( sts[1]->tdm_pc, PC_LIMIT ) ) ) { tdm_hyst_cnt++; @@ -975,7 +1012,7 @@ static Word16 Get_dt_lt_ener_fx( move16(); } - return tmp_SM_flag; + return tmp_SM_flag; /* Q0 */ } @@ -987,13 +1024,13 @@ static Word16 Get_dt_lt_ener_fx( static void NOOP_decision_fx( CPE_ENC_HANDLE hCPE, - const Word16 tdm_NOOP_flag_loc, - const Word16 tmp_SM_flag, - const Word32 rms_L, + const Word16 tdm_NOOP_flag_loc, /* Q0 */ + const Word16 tmp_SM_flag, /* Q0 */ + const Word32 rms_L, /* q_rms_L */ const Word16 q_rms_L, - const Word32 rms_R, + const Word32 rms_R, /* q_rms_R */ const Word16 q_rms_R, - Word16 *tdm_SM_flag_loc ) + Word16 *tdm_SM_flag_loc /* Q0 */ ) { Word16 tdm_NOOP_switch_flag; STEREO_TD_ENC_DATA_HANDLE hStereoTD; @@ -1008,6 +1045,14 @@ static void NOOP_decision_fx( move16(); IF( hCPE->hCoreCoder[0]->sp_aud_decision0 == 0 ) { + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); IF( ( ( GT_16( hStereoTD->tdm_SM_last2_clas[0], VOICED_TRANSITION ) && ( hStereoTD->tdm_SM_last_clas[0] == UNVOICED_CLAS || EQ_16( hStereoTD->tdm_SM_last_clas[0], VOICED_TRANSITION ) ) ) || ( GT_16( hStereoTD->tdm_SM_last2_clas[1], VOICED_TRANSITION ) && ( hStereoTD->tdm_SM_last_clas[1] == UNVOICED_CLAS || EQ_16( hStereoTD->tdm_SM_last_clas[1], VOICED_TRANSITION ) ) ) ) && ( !( EQ_16( sts[0]->last_coder_type_raw, VOICED ) || EQ_16( sts[1]->last_coder_type_raw, VOICED ) ) && GT_16( hStereoTD->tdm_NOOP_cnt, 5 ) ) ) @@ -1028,7 +1073,11 @@ static void NOOP_decision_fx( } ELSE { +#ifdef FIX_1301_CORRECT_TD_CNST + if ( LT_32( sts[0]->ee_old_fx, 320000 /* 5000.f in Q6 */ ) && LT_32( sts[1]->ee_old_fx, 320000 /* 5000.f in Q6 */ ) ) +#else if ( LT_32( sts[0]->ee_old_fx, 160000 /* 5000.f in Q6 */ ) && LT_32( sts[1]->ee_old_fx, 160000 /* 5000.f in Q6 */ ) ) +#endif { tdm_NOOP_switch_flag = 1; move16(); @@ -1082,6 +1131,8 @@ static void NOOP_decision_fx( } } + test(); + test(); IF( GT_16( hStereoTD->tdm_SM_flag, 0 ) && EQ_16( tdm_NOOP_switch_flag, 1 ) && NE_16( *tdm_SM_flag_loc, tmp_SM_flag ) ) { *tdm_SM_flag_loc = !( *tdm_SM_flag_loc ); @@ -1130,25 +1181,25 @@ static void NOOP_decision_fx( static Word32 Comp_diff_lt_corr_fx( CPE_ENC_HANDLE hCPE, - const Word16 IsSideMono, - const Word32 rms_L, + const Word16 IsSideMono, /* Q0 */ + const Word32 rms_L, /* q_rms_L */ const Word16 q_rms_L, - const Word32 rms_R, + const Word32 rms_R, /* q_rms_R */ const Word16 q_rms_R, - const Word32 ener_L_dt, - const Word32 ener_R_dt, - Word32 corr_LM, + const Word32 ener_L_dt, /* Q16 */ + const Word32 ener_R_dt, /* Q16 */ + Word32 corr_LM, /* q_corr_LM */ Word16 q_corr_LM, - Word32 corr_RM, + Word32 corr_RM, /* q_corr_RM */ Word16 q_corr_RM, - const Word32 tdm_lt_rms_L, - const Word32 tdm_lt_rms_R, - Word32 *tdm_lt_corr_LM, - Word32 *tdm_lt_corr_RM, - Word32 *tdm_last_diff_lt_corr, + const Word32 tdm_lt_rms_L, /* Q16 */ + const Word32 tdm_lt_rms_R, /* Q16 */ + Word32 *tdm_lt_corr_LM, /* Q24 */ + Word32 *tdm_lt_corr_RM, /* Q24 */ + Word32 *tdm_last_diff_lt_corr, /* q_tdm_last_diff_lt_corr */ Word16 *q_tdm_last_diff_lt_corr, - Word32 *inst_ratio_L_out, - Word32 *diff_lt_corr, + Word32 *inst_ratio_L_out, /* Q24 */ + Word32 *diff_lt_corr, /* q_d_lt_corr_raw */ Word16 *q_d_lt_corr_raw ) { Encoder_State **sts; @@ -1177,7 +1228,9 @@ static Word32 Comp_diff_lt_corr_fx( * adaptation rate factor is lower. This prevent stereo image * move on speech offset *----------------------------------------------------------------*/ - + test(); + test(); + test(); IF( IsSideMono == 0 && EQ_16( hCPE->hStereoClassif->lrtd_mode, 1 ) && ( GT_32( L_shr( tdm_lt_rms_R, Q1 ), tdm_lt_rms_L ) || GT_32( L_shr( tdm_lt_rms_L, Q1 ), tdm_lt_rms_R ) ) ) { adaprate_fx = L_add( Mpy_32_32( M_ADAP_FX_Q31, L_max( tdm_lt_rms_R, tdm_lt_rms_L ) ), B_ADAP_FX_Q16 ); // Q16 @@ -1193,7 +1246,10 @@ static Word32 Comp_diff_lt_corr_fx( * In case of unvoiced content (expect when it is part of an onset), * the adaptation rate is minimal. *----------------------------------------------------------------*/ - + test(); + test(); + test(); + test(); IF( GT_16( sts[0]->ini_frame, 2 ) && ( ( LE_16( sts[0]->last_clas, VOICED_TRANSITION ) && sts[0]->hVAD->hangover_cnt == 0 ) || ( LE_16( sts[1]->last_clas, VOICED_TRANSITION ) && sts[1]->hVAD->hangover_cnt == 0 ) ) ) @@ -1203,9 +1259,14 @@ static Word32 Comp_diff_lt_corr_fx( d_lt_corr_raw_fx = 0; move32(); + IF( IsSideMono == 0 ) { - if ( NE_16( hCPE->last_element_mode, IVAS_CPE_TD ) || ( ( LT_32( tdm_lt_rms_R, ONE_IN_Q16 ) || LT_32( tdm_lt_rms_L, ONE_IN_Q16 ) ) && EQ_16( hCPE->hStereoClassif->lrtd_mode, 1 ) && LT_32( L_max( tdm_lt_rms_R, tdm_lt_rms_L ), TEN_IN_Q16 ) ) ) + test(); + test(); + test(); + test(); + IF( NE_16( hCPE->last_element_mode, IVAS_CPE_TD ) || ( ( LT_32( tdm_lt_rms_R, ONE_IN_Q16 ) || LT_32( tdm_lt_rms_L, ONE_IN_Q16 ) ) && EQ_16( hCPE->hStereoClassif->lrtd_mode, 1 ) && LT_32( L_max( tdm_lt_rms_R, tdm_lt_rms_L ), TEN_IN_Q16 ) ) ) { adaprate_fx = 64225; /* 0.98f in Q16 */ /* speed up the adaptation of the long term values to the current values after coming from DFT */ move32(); @@ -1242,13 +1303,13 @@ static Word32 Comp_diff_lt_corr_fx( corr_LM = BASOP_Util_Add_Mant32Exp( Mpy_32_32( adaprate_fx, corr_LM ), sub( Q31, sub( q_corr_LM, Q15 ) ), Mpy_32_32( madaprate_fx, *tdm_lt_corr_LM ), Q31 - Q9, &exp_diff ); // Q31 - exp_diff q_corr_LM = sub( Q31, exp_diff ); - L_tmp = Mpy_32_32( ALP_REF_FX_Q31, *tdm_lt_corr_LM ); // Q24 - L_tmp1 = Mpy_32_32( BET_REF_FX_Q31, corr_LM ); // q_corr_LM - diff_lt_corr_LM_tmp_fx = BASOP_Util_Add_Mant32Exp( L_tmp, Q31 - Q24, L_tmp1, sub( Q31, q_corr_LM ), &exp_diff ); + L_tmp = Mpy_32_32( ALP_REF_FX_Q31, *tdm_lt_corr_LM ); // Q24 + L_tmp1 = Mpy_32_32( BET_REF_FX_Q31, corr_LM ); // q_corr_LM + diff_lt_corr_LM_tmp_fx = BASOP_Util_Add_Mant32Exp( L_tmp, Q31 - Q24, L_tmp1, sub( Q31, q_corr_LM ), &exp_diff ); /* Q31-exp_diff */ q_diff_lt_corr_LM_tmp = sub( Q31, exp_diff ); - L_tmp = Mpy_32_32( ALP_REF_FX_Q31, *tdm_lt_corr_RM ); // Q24 - L_tmp1 = Mpy_32_32( BET_REF_FX_Q31, corr_RM ); // q_corr_RM - diff_lt_corr_RM_tmp_fx = BASOP_Util_Add_Mant32Exp( L_tmp, Q31 - Q24, L_tmp1, sub( Q31, q_corr_RM ), &exp_diff ); + L_tmp = Mpy_32_32( ALP_REF_FX_Q31, *tdm_lt_corr_RM ); // Q24 + L_tmp1 = Mpy_32_32( BET_REF_FX_Q31, corr_RM ); // q_corr_RM + diff_lt_corr_RM_tmp_fx = BASOP_Util_Add_Mant32Exp( L_tmp, Q31 - Q24, L_tmp1, sub( Q31, q_corr_RM ), &exp_diff ); /* Q31-exp_diff */ q_diff_lt_corr_RM_tmp = sub( Q31, exp_diff ); diff_lt_corr_tmp_fx = BASOP_Util_Add_Mant32Exp( diff_lt_corr_LM_tmp_fx, sub( Q31, q_diff_lt_corr_LM_tmp ), L_negate( diff_lt_corr_RM_tmp_fx ), sub( Q31, q_diff_lt_corr_RM_tmp ), &exp_diff ); // (Q31 - exp_diff) q_diff_lt_corr_tmp = sub( Q31, exp_diff ); @@ -1267,7 +1328,7 @@ static Word32 Comp_diff_lt_corr_fx( move16(); shift = sub( q_d_lt_corr, Q31 ); } - *tdm_last_diff_lt_corr = diff_lt_corr_tmp_fx; + *tdm_last_diff_lt_corr = diff_lt_corr_tmp_fx; /* q_tdm_last_diff_lt_corr */ move32(); *q_tdm_last_diff_lt_corr = q_diff_lt_corr_tmp; move16(); @@ -1275,7 +1336,18 @@ static Word32 Comp_diff_lt_corr_fx( /*----------------------------------------------------------------* * Correct the estimation depending of channels energies evolution *----------------------------------------------------------------*/ - + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); IF( EQ_16( IsSideMono, 1 ) && ( ( LT_32( L_shl( rms_L, sub( Q21, q_rms_L ) ), RMS_MIN2_FX_Q21 ) && LT_32( L_shl( rms_R, sub( Q21, q_rms_R ) ), RMS_MIN2_FX_Q21 ) ) && @@ -1307,9 +1379,9 @@ static Word32 Comp_diff_lt_corr_fx( ) { /* Use estimated results */ - *tdm_lt_corr_LM = L_shl( diff_lt_corr_LM_tmp_fx, sub( Q24, q_diff_lt_corr_LM_tmp ) ); + *tdm_lt_corr_LM = L_shl( diff_lt_corr_LM_tmp_fx, sub( Q24, q_diff_lt_corr_LM_tmp ) ); /* Q24 */ move32(); - *tdm_lt_corr_RM = L_shl( diff_lt_corr_RM_tmp_fx, sub( Q24, q_diff_lt_corr_RM_tmp ) ); + *tdm_lt_corr_RM = L_shl( diff_lt_corr_RM_tmp_fx, sub( Q24, q_diff_lt_corr_RM_tmp ) ); /* Q24 */ move32(); } ELSE @@ -1340,23 +1412,26 @@ static Word32 Comp_diff_lt_corr_fx( *-------------------------------------------------------------------*/ static Word16 limit_idx_Dwnmix_fx( - const Word16 idx_in, - const Word16 unclr_decision, - const Word16 inst_idx, - const Word16 previous_idx, - const Word16 tdm_last_LRTD_PriCh_cnt, - const Word16 tdm_last_LRTD_frame_cnt ) + const Word16 idx_in, /* Q0 */ + const Word16 unclr_decision, /* Q0 */ + const Word16 inst_idx, /* Q0 */ + const Word16 previous_idx, /* Q0 */ + const Word16 tdm_last_LRTD_PriCh_cnt, /* Q0 */ + const Word16 tdm_last_LRTD_frame_cnt /* Q0 */ ) { Word16 idx; idx = idx_in; move16(); - idx = check_bounds_s_fx( idx, 1, 29 ); + idx = check_bounds_s_fx( idx, 1, 29 ); /* Q0 */ + test(); IF( EQ_16( unclr_decision, 1 ) && GT_16( tdm_last_LRTD_frame_cnt, 1 ) ) { IF( tdm_last_LRTD_PriCh_cnt > 0 ) { + test(); + test(); IF( LE_16( idx, LRTD_STEREO_MID_IS_PRIM ) && LT_16( inst_idx, LRTD_STEREO_MID_IS_PRIM + 2 ) ) { idx = s_min( 1, idx ); @@ -1386,7 +1461,7 @@ static Word16 limit_idx_Dwnmix_fx( } } - return idx; + return idx; /* Q0 */ } @@ -1396,9 +1471,9 @@ static Word16 limit_idx_Dwnmix_fx( *-------------------------------------------------------------------*/ static Word16 limit_idx_NoDwnmix_fx( - const Word16 idx_in, /* i : Index */ - const Word16 side_can_change, /* i : Primary and secondary channel allowed to change ? */ - const Word32 d_lt_corr_raw, /* i : Raw corrrelation differences */ + const Word16 idx_in, /* i : Index Q0*/ + const Word16 side_can_change, /* i : Primary and secondary channel allowed to change ? Q0*/ + const Word32 d_lt_corr_raw, /* i : Raw corrrelation differences q_d_lt_corr_raw*/ const Word16 q_d_lt_corr_raw /* i : Q-factor of Raw corrrelation differences */ ) { @@ -1406,11 +1481,14 @@ static Word16 limit_idx_NoDwnmix_fx( idx = idx_in; move16(); + + test(); + test(); IF( side_can_change == 0 && GT_16( idx_in, 10 ) && LT_16( idx_in, 20 ) ) { idx = 30; move16(); - if ( LT_32( d_lt_corr_raw, L_negate( L_shl( 214748365 /* 0.1f in Q31 */, sub( q_d_lt_corr_raw, Q31 ) ) ) ) ) + IF( LT_32( d_lt_corr_raw, L_negate( L_shl( 214748365 /* 0.1f in Q31 */, sub( q_d_lt_corr_raw, Q31 ) ) ) ) ) { idx = 0; move16(); @@ -1430,7 +1508,7 @@ static Word16 limit_idx_NoDwnmix_fx( } } - return idx; + return idx; /* Q0 */ } @@ -1443,8 +1521,8 @@ static Word16 limit_idx_NoDwnmix_fx( static Word16 stereo_tdm_ener_analysis_SM_fx( CPE_ENC_HANDLE hCPE, /* i : CPE encoder structure */ Encoder_State **sts, /* i/o: Encoder static variables structure */ - const Word16 input_frame, /* i : Number of samples */ - Word16 *tdm_SM_flag /* i/o: channel combination scheme flag */ + const Word16 input_frame, /* i : Number of samples Q0*/ + Word16 *tdm_SM_flag /* i/o: channel combination scheme flag Q0*/ ) { Word32 rms_R_fx, rms_L_fx; @@ -1473,7 +1551,7 @@ static Word16 stereo_tdm_ener_analysis_SM_fx( *----------------------------------------------------------------*/ /* Simple logic to set SM flag, should be done in the frequency domain for low SM correlation signal, especially for music item such as Music_1_org_s */ - tdm_SM_flag_loc = hStereoTD->tdm_last_SM_flag_noop; + tdm_SM_flag_loc = hStereoTD->tdm_last_SM_flag_noop; /* Q0 */ move16(); /*----------------------------------------------------------------* @@ -1515,27 +1593,38 @@ static Word16 stereo_tdm_ener_analysis_SM_fx( * When the energies of channels are low enough, compute the ratio * of L and R needed to create new mono/side signals *----------------------------------------------------------------*/ - + test(); + test(); + test(); IF( ( LE_32( L_shl( hStereoTD->tdm_lt_rms_L_SM_fx, Q20 - Q24 ), RMS_MIN_FX_Q20 ) && LE_32( L_shl( hStereoTD->tdm_lt_rms_R_SM_fx, Q19 /* adjusted for 2 in RHS */ - Q24 ), RMS_MIN_FX_Q20 ) ) || - ( LE_32( L_shl( hStereoTD->tdm_lt_rms_R_SM_fx, Q20 - Q24 ), RMS_MIN_FX_Q20 ) && LE_32( L_shl( hStereoTD->tdm_lt_rms_L_SM_fx, Q19 /* adjusted for 2 in RHS */ - Q24 ), RMS_MIN_FX_Q20 ) ) ) + ( LE_32( L_shl( hStereoTD->tdm_lt_rms_R_SM_fx, Q20 - Q24 ), RMS_MIN_FX_Q20 ) && LE_32( L_shl( hStereoTD->tdm_lt_rms_L_SM_fx, Q19 /* adjusted for 2 in RHS */ - Q24 ), RMS_MIN_FX_Q20 ) ) ) /* Q20 */ { - if ( ( LT_16( sts[0]->old_corr_fx, CORR_THRES_FX_Q15 ) && LT_16( sts[1]->old_corr_fx, CORR_THRES_FX_Q15 ) ) || - ( LE_32( L_shl( hStereoTD->tdm_lt_rms_L_SM_fx, Q21 - Q24 ), RMS_MIN2_FX_Q21 ) && LE_32( L_shl( hStereoTD->tdm_lt_rms_R_SM_fx, Q21 - Q24 ), RMS_MIN2_FX_Q21 ) ) ) + test(); + test(); + test(); + IF( ( LT_16( sts[0]->old_corr_fx, CORR_THRES_FX_Q15 ) && LT_16( sts[1]->old_corr_fx, CORR_THRES_FX_Q15 ) ) || + ( LE_32( L_shl( hStereoTD->tdm_lt_rms_L_SM_fx, Q21 - Q24 ), RMS_MIN2_FX_Q21 ) && LE_32( L_shl( hStereoTD->tdm_lt_rms_R_SM_fx, Q21 - Q24 ), RMS_MIN2_FX_Q21 ) ) ) { side_can_change = 1; move16(); } } + test(); + test(); + test(); IF( ( LE_32( L_shl( hStereoTD->tdm_lt_rms_L_SM_fx, Q21 - Q24 ), RMS_MIN2_FX_Q21 ) && LE_32( L_shl( hStereoTD->tdm_lt_rms_R_SM_fx, Q20 /* adjusted for 2 in RHS */ - Q24 ), RMS_MIN2_FX_Q21 ) ) || - ( LE_32( L_shl( hStereoTD->tdm_lt_rms_R_SM_fx, Q21 - Q24 ), RMS_MIN2_FX_Q21 ) && LE_32( L_shl( hStereoTD->tdm_lt_rms_L_SM_fx, Q20 /* adjusted for 2 in RHS */ - Q24 ), RMS_MIN2_FX_Q21 ) ) ) + ( LE_32( L_shl( hStereoTD->tdm_lt_rms_R_SM_fx, Q21 - Q24 ), RMS_MIN2_FX_Q21 ) && LE_32( L_shl( hStereoTD->tdm_lt_rms_L_SM_fx, Q20 /* adjusted for 2 in RHS */ - Q24 ), RMS_MIN2_FX_Q21 ) ) ) /* Q21 */ { + test(); + test(); + test(); IF( ( ( NE_16( hStereoTD->tdm_last_SM_flag_noop, tdm_SM_flag_loc ) ) && hStereoTD->tdm_noop_cnt == 0 ) || EQ_16( hStereoTD->tdm_noop_mov_flag, 1 ) || NE_16( hStereoTD->tdm_prev_desired_idx_SM, hStereoTD->tdm_prev_stable_idx_SM ) ) { hStereoTD->tdm_noop_mov_flag = 1; move16(); - if ( hStereoTD->tdm_last_ratio_idx_SM != 0 && NE_16( hStereoTD->tdm_last_ratio_idx_SM, ( TDM_NQ - 1 ) ) ) + IF( hStereoTD->tdm_last_ratio_idx_SM != 0 && NE_16( hStereoTD->tdm_last_ratio_idx_SM, ( TDM_NQ - 1 ) ) ) { side_can_change = 1; move16(); @@ -1543,7 +1632,8 @@ static Word16 stereo_tdm_ener_analysis_SM_fx( } } - if ( side_can_change == 0 && EQ_16( tdm_SM_flag_loc, 1 ) && GT_32( es_em_fx, 31457280 /* 15.0f in Q21 */ ) ) + test(); + IF( side_can_change == 0 && EQ_16( tdm_SM_flag_loc, 1 ) && GT_32( es_em_fx, 31457280 /* 15.0f in Q21 */ ) ) { side_can_change = 1; move16(); @@ -1584,7 +1674,7 @@ static Word16 stereo_tdm_ener_analysis_SM_fx( } } - idx = stereo_smooth_LR_transition_fx( &hStereoTD->tdm_prev_stable_idx_SM, &hStereoTD->tdm_noop_mov_flag, hStereoTD->tdm_last_ratio_idx_SM, &hStereoTD->tdm_prev_desired_idx_SM, &hStereoTD->tdm_noop_cnt, tdm_SM_flag_loc, desired_idx ); + idx = stereo_smooth_LR_transition_fx( &hStereoTD->tdm_prev_stable_idx_SM, &hStereoTD->tdm_noop_mov_flag, hStereoTD->tdm_last_ratio_idx_SM, &hStereoTD->tdm_prev_desired_idx_SM, &hStereoTD->tdm_noop_cnt, tdm_SM_flag_loc, desired_idx ); /* Q0 */ idx = extract_l( L_add( Mpy_32_32( 1717986918 /* 0.8f in Q31 */, idx ), Mpy_32_32( 429496729 /* 0.2f in Q31 */, hStereoTD->tdm_last_ratio_idx_SM ) ) ); // (Q31, Q0) -> Q0 @@ -1598,6 +1688,9 @@ static Word16 stereo_tdm_ener_analysis_SM_fx( move16(); } + test(); + test(); + test(); IF( ( EQ_16( hStereoTD->tdm_noop_mov_flag, 1 ) && GE_16( hStereoTD->tdm_noop_cnt, 31 ) ) || ( ( EQ_16( hStereoTD->tdm_last_SM_flag_noop, tdm_SM_flag_loc ) ) && ( EQ_16( idx, hStereoTD->tdm_prev_stable_idx_SM ) ) ) ) { hStereoTD->tdm_noop_cnt = 0; @@ -1606,6 +1699,7 @@ static Word16 stereo_tdm_ener_analysis_SM_fx( move16(); } + test(); if ( hStereoTD->tdm_noop_mov_flag == 0 || tdm_SM_flag_loc == 0 ) { hStereoTD->tdm_prev_stable_idx_SM = idx; @@ -1634,11 +1728,11 @@ Word16 tdm_lp_comparison_fx( Word32 *speech_buff, /* i : Current speech frame Q_speech */ const Word16 *A_PCh_fx, /* i : primary channel LP coefficients Q12*/ const Word16 *A_SCh_fx, /* i : secondary channel LP coeff. Q12*/ - const Word16 m, /* i : filter length */ + const Word16 m, /* i : filter length Q0*/ const Word16 *isp_PCh_fx, /* i : primary channel LSPs Q15 */ const Word16 *isp_SCh_fx, /* i : secondary channel LSPs Q15 */ - const Word16 L_frame, /* i : frame length */ - const Word32 element_brate_wo_meta, /* i : element bitrate without metadata*/ + const Word16 L_frame, /* i : frame length Q0*/ + const Word32 element_brate_wo_meta, /* i : element bitrate without metadata Q0*/ Word16 Q_speech ) { Word32 ener_sig_fx, pred_gain_reuse_PCh_fx, log10_fx, predgain_SCh_fx; @@ -1646,7 +1740,6 @@ Word16 tdm_lp_comparison_fx( Word32 dist_fx, ftmp_fx; Word16 i; Word32 res_fx[L_FRAME16k]; - Word16 gb1 = find_guarded_bits_fx( M ); Word16 Q_A_SCh; Word32 *speech_fx = &speech_buff[M]; @@ -1657,8 +1750,8 @@ Word16 tdm_lp_comparison_fx( // residu( A_SCh, m, speech, res, L_frame ); Word16 gb = find_guarded_bits_fx( L_frame ); - scale_sig32( speech_buff, L_FRAME + M, gb1 ); - Word16 exp = sub( 31, Q_speech ); + scale_sig32( speech_buff, L_FRAME + M, Q4 ); /* Q_speech + 4 */ + Word16 exp = sub( Q27, Q_speech ); Word32 sum2_value = sum2_32_exp_fx( speech_fx, L_frame, &exp, gb ); // 2*Q_speech -31-gb IF( LT_16( exp, -5 ) ) /*maximum q to prevent 0.01 from saturating is 37, since we are adding it headroom of 1 is required*/ { @@ -1666,28 +1759,28 @@ Word16 tdm_lp_comparison_fx( exp = -5; move16(); } - sum2_value = BASOP_Util_Add_Mant32Exp( sum2_value, exp, 328, Q31 - Q15, &exp ); - Word32 temp32_log = L_add( BASOP_Util_Log2( sum2_value ), L_shl( sub( Q31, sub( 31, exp ) ), Q25 ) ); - ener_sig_fx = Mpy_32_32( temp32_log, 646456623 ); // Q25 + sum2_value = BASOP_Util_Add_Mant32Exp( sum2_value, exp, 328, Q16, &exp ); /* Q31-exp */ + Word32 temp32_log = L_add( BASOP_Util_Log2( sum2_value ), L_shl( sub( Q31, sub( 31, exp ) ), Q25 ) ); /* Q25 */ + ener_sig_fx = Mpy_32_32( temp32_log, 646456623 ); // Q25 // ener_sig = log10f( sum2_f( speech, L_frame ) + 0.01f ); - exp = sub( 31, sub( Q_speech, gb1 ) ); - sum2_value = sum2_32_exp_fx( res_fx, L_frame, &exp, gb ); // 2*Q_speech -31-gb - sum2_value = BASOP_Util_Add_Mant32Exp( sum2_value, exp, 328, Q31 - Q15, &exp ); - temp32_log = L_add( BASOP_Util_Log2( sum2_value ), L_shl( sub( Q31, sub( 31, exp ) ), Q25 ) ); - log10_fx = Mpy_32_32( temp32_log, 646456623 ); // Q25 - predgain_SCh_fx = Mpy_32_32( L_sub( ener_sig_fx, log10_fx ), 1342177280 ); // Q27+Q25-31 = Q21 + exp = sub( Q31, Q_speech ); + sum2_value = sum2_32_exp_fx( res_fx, L_frame, &exp, gb ); // 2*Q_speech -31-gb + sum2_value = BASOP_Util_Add_Mant32Exp( sum2_value, exp, 328, Q16, &exp ); /* Q31-exp */ + temp32_log = L_add( BASOP_Util_Log2( sum2_value ), L_shl( sub( Q31, sub( 31, exp ) ), Q25 ) ); /* Q25 */ + log10_fx = Mpy_32_32( temp32_log, 646456623 ); // Q25 + predgain_SCh_fx = Mpy_32_32( L_sub( ener_sig_fx, log10_fx ), 1342177280 ); // Q27+Q25-31 = Q21 // pred_gain_reuse_PCh = 10.0f * ( ener_sig - log10f( sum2_f( res, L_frame ) + 0.01f ) ); // predgain_SCh = 10.0f * ( ener_sig - log10f( sum2_f( res, L_frame ) + 0.01f ) ); /* Find prediction gain when resuing the Primary Channel LP filter */ // residu( A_PCh, m, speech, res, L_frame ); - scale_sig32( speech_buff, L_FRAME + M, negate( gb1 ) ); + scale_sig32( speech_buff, L_FRAME + M, -4 ); /* Q_speech */ residu_ivas_fx( A_PCh_fx, sub( 14, norm_s( A_PCh_fx[0] ) ), m, speech_fx, res_fx, L_frame ); - exp = sub( 31, sub( Q_speech, gb1 ) ); + exp = sub( Q31, Q_speech ); sum2_value = sum2_32_exp_fx( res_fx, L_frame, &exp, gb ); // 2*Q_speech -31-gb - sum2_value = BASOP_Util_Add_Mant32Exp( sum2_value, exp, 328, Q31 - Q15, &exp ); - temp32_log = L_add( BASOP_Util_Log2( sum2_value ), L_shl( sub( Q31, sub( 31, exp ) ), Q25 ) ); - log10_fx = Mpy_32_32( temp32_log, 646456623 ); // Q25 + sum2_value = BASOP_Util_Add_Mant32Exp( sum2_value, exp, 328, Q16, &exp ); + temp32_log = L_add( BASOP_Util_Log2( sum2_value ), L_shl( sub( Q31, sub( 31, exp ) ), Q25 ) ); /* Q25 */ + log10_fx = Mpy_32_32( temp32_log, 646456623 ); // Q25 pred_gain_reuse_PCh_fx = Mpy_32_32( L_sub( ener_sig_fx, log10_fx ), 1342177280 ); // Q27+Q25-31 = Q21 // pred_gain_reuse_PCh = 10.0f * ( ener_sig - log10f( sum2_f( res, L_frame ) + 0.01f ) ); @@ -1695,11 +1788,12 @@ Word16 tdm_lp_comparison_fx( /* Find Euclidian distance between the 2 filters */ dist_fx = 0; move16(); - gb = find_guarded_bits_fx( M ); + gb = 4; + move16(); FOR( i = 0; i < m; i++ ) { // ftmp = isp_SCh[i] - isp_PCh[i]; - ftmp_fx = L_deposit_h( sub( isp_SCh_fx[i], isp_PCh_fx[i] ) ); + ftmp_fx = L_deposit_h( sub( isp_SCh_fx[i], isp_PCh_fx[i] ) ); /* Q31 */ // dist += ftmp * ftmp; dist_fx = L_add( dist_fx, L_shr( Mpy_32_32( ftmp_fx, ftmp_fx ), gb ) ); // Q31-gb } @@ -1738,9 +1832,9 @@ Word16 tdm_lp_comparison_fx( test(); test(); - if ( ( GE_32( element_brate_wo_meta, IVAS_48k ) && !( GE_32( pred_gain_reuse_PCh_fx, Mpy_32_32( RATIO_PG_HR_FX, predgain_SCh_fx ) ) && LT_32( dist_fx, L_shr( EUCLDST_FX, gb ) ) ) ) || - ( EQ_16( hStereoClassif->lrtd_mode, 1 ) && LT_32( element_brate_wo_meta, IVAS_16k4 ) && !( GE_32( pred_gain_reuse_PCh_fx, Mpy_32_32( RATIO_PG_HR_FX, predgain_SCh_fx ) ) && LT_32( dist_fx, L_shr( EUCLDST_FX, add( gb, 1 ) ) ) ) ) || - ( EQ_16( hStereoClassif->lrtd_mode, 1 ) && GE_32( element_brate_wo_meta, IVAS_16k4 ) && !( GE_32( pred_gain_reuse_PCh_fx, Mpy_32_32( RATIO_PG_LRTD_FX, predgain_SCh_fx ) ) && LT_32( dist_fx, L_shr( EUCLDST_FX, gb + 2 ) ) ) ) || st->tc_cnt > 0 ) + IF( ( GE_32( element_brate_wo_meta, IVAS_48k ) && !( GE_32( pred_gain_reuse_PCh_fx, Mpy_32_32( RATIO_PG_HR_FX, predgain_SCh_fx ) ) && LT_32( dist_fx, L_shr( EUCLDST_FX, gb ) ) ) ) || + ( EQ_16( hStereoClassif->lrtd_mode, 1 ) && LT_32( element_brate_wo_meta, IVAS_16k4 ) && !( GE_32( pred_gain_reuse_PCh_fx, Mpy_32_32( RATIO_PG_HR_FX, predgain_SCh_fx ) ) && LT_32( dist_fx, L_shr( EUCLDST_FX, add( gb, 1 ) ) ) ) ) || + ( EQ_16( hStereoClassif->lrtd_mode, 1 ) && GE_32( element_brate_wo_meta, IVAS_16k4 ) && !( GE_32( pred_gain_reuse_PCh_fx, Mpy_32_32( RATIO_PG_LRTD_FX, predgain_SCh_fx ) ) && LT_32( dist_fx, L_shr( EUCLDST_FX, gb + 2 ) ) ) ) || st->tc_cnt > 0 ) { LP_mode = 0; move16(); @@ -1776,14 +1870,14 @@ void tdm_ol_pitch_comparison_fx( st0 = hCPE->hCoreCoder[0]; /* Encoder structure - primary channel */ st1 = hCPE->hCoreCoder[1]; /* Encoder structure - secondary channel */ - if ( GT_32( hCPE->element_brate, IVAS_13k2 ) ) + IF( GT_32( hCPE->element_brate, IVAS_13k2 ) ) { diff_thr = 3; move16(); } test(); - if ( GE_32( hCPE->element_brate, IVAS_48k ) || EQ_16( hCPE->hStereoTD->tdm_LRTD_flag, 1 ) ) + IF( GE_32( hCPE->element_brate, IVAS_48k ) || EQ_16( hCPE->hStereoTD->tdm_LRTD_flag, 1 ) ) { diff_thr = 1; move16(); @@ -1819,12 +1913,12 @@ void tdm_ol_pitch_comparison_fx( test(); IF( GE_16( voicmin[0], 29491 /* 0.9f in Q15 */ ) && GE_16( voicmin[1], 29491 /* 0.9f in Q15 */ ) && GE_16( voicmin[2], 27853 /* 0.85f in Q15 */ ) && GE_16( voicmin[3], 27853 /* 0.85f in Q15 */ ) ) { - tmp_diff = add( abs_s( sub( st0->pitch[0], st1->pitch[0] ) ), add( abs_s( sub( st0->pitch[1], st1->pitch[1] ) ), abs_s( sub( st0->pitch[2], st1->pitch[2] ) ) ) ); + tmp_diff = add( abs_s( sub( st0->pitch[0], st1->pitch[0] ) ), add( abs_s( sub( st0->pitch[1], st1->pitch[1] ) ), abs_s( sub( st0->pitch[2], st1->pitch[2] ) ) ) ); /* Q0 */ } } ELSE { - tmp_diff = abs_s( sub( add( st0->pitch[0], add( st0->pitch[1], st0->pitch[2] ) ), add( st1->pitch[0], add( st1->pitch[1], st1->pitch[2] ) ) ) ); + tmp_diff = abs_s( sub( add( st0->pitch[0], add( st0->pitch[1], st0->pitch[2] ) ), add( st1->pitch[0], add( st1->pitch[1], st1->pitch[2] ) ) ) ); /* Q0 */ } IF( LE_16( tmp_diff, diff_thr ) ) @@ -1833,23 +1927,23 @@ void tdm_ol_pitch_comparison_fx( move16(); /* 1/4 pitch precision update*/ - Copy( st0->pitch, st1->pitch, 3 ); - Copy( st0->voicing_fx, st1->voicing_fx, 3 ); + Copy( st0->pitch, st1->pitch, 3 ); /* Q0 */ + Copy( st0->voicing_fx, st1->voicing_fx, 3 ); /* Q15 */ /* Update some parameters accordingly */ - st1->old_corr_fx = st0->old_corr_fx; - st1->old_thres_fx = st0->old_thres_fx; - st1->delta_pit = st0->delta_pit; + st1->old_corr_fx = st0->old_corr_fx; /* Q15 */ + st1->old_thres_fx = st0->old_thres_fx; /* Q15 */ + st1->delta_pit = st0->delta_pit; /* Q0 */ move16(); move16(); move16(); /* Updates for adaptive lag window memory */ - st1->old_pitch_la = st0->old_pitch_la; + st1->old_pitch_la = st0->old_pitch_la; /* Q0 */ move16(); /* 1/4 pitch precision update*/ - Copy( pitch_fr[0], pitch_fr[1], NB_SUBFR ); - Copy( voicing_fr[0], voicing_fr[1], NB_SUBFR ); + Copy( pitch_fr[0], pitch_fr[1], NB_SUBFR ); /* Q6 */ + Copy( voicing_fr[0], voicing_fr[1], NB_SUBFR ); /* Q15 */ } } @@ -1863,15 +1957,15 @@ void tdm_ol_pitch_comparison_fx( *-------------------------------------------------------------------*/ static void Get_corr_n_fx( - const Word16 L[], /* i : Left signal */ - const Word16 R[], /* i : Right signal */ - Word32 *ic_Lm, /* o : Left signal */ + const Word16 L[], /* i : Left signal q_in*/ + const Word16 R[], /* i : Right signal q_in*/ + Word32 *ic_Lm, /* o : Left signal q_ic_Lm*/ Word16 *q_ic_Lm, /* o : Q factor of Left signal */ - Word32 *ic_Rm, /* o : Right signal */ + Word32 *ic_Rm, /* o : Right signal q_ic_Rm*/ Word16 *q_ic_Rm, /* o : Q factor of Right signal */ - const Word16 len, /* i : segment length */ + const Word16 len, /* i : segment length Q0*/ Word32 *es_em, /* o : return the difference between the side and mono energy */ - const Word16 tdm_SM_calc_flag /* i : Flag that indicates that it is for SM mode */ + const Word16 tdm_SM_calc_flag /* i : Flag that indicates that it is for SM mode Q0*/ ) { Word32 corrL, corrR, ener; @@ -1892,7 +1986,7 @@ static void Get_corr_n_fx( move64(); W_ener_side = EPSILON_FX; move64(); - guard_bits = sub( 32, find_guarded_bits_fx( len ) ); + guard_bits = sub( 32, find_guarded_bits_fx( len ) ); /* Q0 */ /*----------------------------------------------------------------* * Find the normalized correlation between: left/mono and right/mono based @@ -1910,8 +2004,8 @@ static void Get_corr_n_fx( W_ener_side = W_mac0_16_16( W_ener_side, side_i, side_i ); // (q_in + q_in ) } /* Scaling back to the original proposal */ - corrL = W_extract_h( W_shl( W_corrL, guard_bits ) ); - corrR = W_extract_h( W_shl( W_corrR, guard_bits ) ); + corrL = W_extract_h( W_shl( W_corrL, guard_bits ) ); /* 2*q_in + guard_bits - 32 */ + corrR = W_extract_h( W_shl( W_corrR, guard_bits ) ); /* 2*q_in + guard_bits - 32 */ ener = W_extract_h( W_shl( W_ener, guard_bits ) ); ener_side = W_extract_h( W_shl( W_ener_side, guard_bits ) ); } @@ -1927,8 +2021,8 @@ static void Get_corr_n_fx( W_ener_side = W_mac0_16_16( W_ener_side, side_i, side_i ); // (q_in + q_in ) } /* Scaling back to the original proposal */ - corrL = W_extract_h( W_shl( W_corrL, guard_bits ) ); - corrR = W_extract_h( W_shl( W_corrR, guard_bits ) ); + corrL = W_extract_h( W_shl( W_corrL, guard_bits ) ); /* 2*q_in + guard_bits - 32 */ + corrR = W_extract_h( W_shl( W_corrR, guard_bits ) ); /* 2*q_in + guard_bits - 32 */ ener = W_extract_h( W_shl( W_ener, guard_bits ) ); ener_side = W_extract_h( W_shl( W_ener_side, guard_bits ) ); } @@ -1976,9 +2070,9 @@ static void Get_corr_n_fx( /* *es_em = 10 * ( log10f( sqrtf( ener_side / len ) ) - log10f( sqrtf( ener / len ) ) ); is simplified to *es_em = 10 * ( log10f( sqrtf( ener_side / ener ) ) ); */ - L_tmp = BASOP_Util_Divide3232_Scale_cadence( ener_side, ener, &exp_diff ); // (Q31 - exp_diff) - L_tmp = Sqrt32( L_tmp, &exp_diff ); - L_tmp = BASOP_Util_Log2( L_tmp ); + L_tmp = BASOP_Util_Divide3232_Scale_cadence( ener_side, ener, &exp_diff ); // (Q31 - exp_diff) + L_tmp = Sqrt32( L_tmp, &exp_diff ); /* (Q31 - exp_diff) */ + L_tmp = BASOP_Util_Log2( L_tmp ); /* Q25 */ *es_em = Mpy_32_32( Mpy_32_32( L_add( L_tmp, L_shl( exp_diff, Q25 ) ), LOG10_2_Q31 ), TEN_IN_Q27 ); // (Q25, Q27) -> Q21 move32(); } @@ -1994,24 +2088,24 @@ static void Get_corr_n_fx( /*! r: smoothed position */ static Word16 stereo_smooth_LR_transition_fx( - Word16 *tdm_prev_stable_idx, /* i/o: Previous Transmitted ratio index */ - Word16 *tdm_ratio_transition_mov_flag, /* i/o: Flag that indicates that L-R energy is changing */ - Word16 tdm_last_ratio_idx, /* i : last TDM ratio index */ - Word16 *tdm_prev_desired_idx, /* i/o: Previous Transmitted ratio index */ - Word16 *tdm_ratio_transition_cnt, /* i/o: Counter */ - const Word16 tdm_SM_flag, /* i : channel combination scheme flag for current frame */ - Word16 desired_idx /* i : desired final position */ + Word16 *tdm_prev_stable_idx, /* i/o: Previous Transmitted ratio index Q0*/ + Word16 *tdm_ratio_transition_mov_flag, /* i/o: Flag that indicates that L-R energy is changing Q0*/ + Word16 tdm_last_ratio_idx, /* i : last TDM ratio index Q0*/ + Word16 *tdm_prev_desired_idx, /* i/o: Previous Transmitted ratio index Q0*/ + Word16 *tdm_ratio_transition_cnt, /* i/o: Counter Q0*/ + const Word16 tdm_SM_flag, /* i : channel combination scheme flag for current frame Q0*/ + Word16 desired_idx /* i : desired final position Q0*/ ) { Word16 idx; - if ( EQ_16( tdm_SM_flag, 1 ) ) + IF( EQ_16( tdm_SM_flag, 1 ) ) { desired_idx = 15; move16(); } - if ( NE_16( desired_idx, *tdm_prev_stable_idx ) ) + IF( NE_16( desired_idx, *tdm_prev_stable_idx ) ) { *tdm_ratio_transition_mov_flag = 1; move16(); diff --git a/lib_enc/ivas_stereo_td_enc.c b/lib_enc/ivas_stereo_td_enc_fx.c similarity index 98% rename from lib_enc/ivas_stereo_td_enc.c rename to lib_enc/ivas_stereo_td_enc_fx.c index a06c30301f01b177e5479575a7f2a72e33203533..3780688276320dd2c4ac9d81bb6e849389e9fa6f 100644 --- a/lib_enc/ivas_stereo_td_enc.c +++ b/lib_enc/ivas_stereo_td_enc_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other @@ -35,8 +35,7 @@ #include "options.h" #include "cnst.h" #include "rom_com.h" -#include "prot.h" -#include "ivas_prot.h" +#include "prot_fx.h" #include "ivas_rom_com.h" #include "wmc_auto.h" #ifdef DEBUGGING @@ -44,7 +43,6 @@ #endif #include "prot_fx_enc.h" #include "ivas_prot_fx.h" -#include "prot_fx.h" #include "ivas_rom_com_fx.h" @@ -197,7 +195,7 @@ void stereo_td_init_enc_fx( move32(); hStereoTD->tdm_hBstr_tmp.ivas_max_num_indices = &hStereoTD->max_ind_tdm_tmp; hStereoTD->tdm_hBstr_tmp.st_ivas = NULL; - reset_indices_enc( &hStereoTD->tdm_hBstr_tmp, MAX_IND_TDM_TMP ); + reset_indices_enc_fx( &hStereoTD->tdm_hBstr_tmp, MAX_IND_TDM_TMP ); return; } @@ -265,7 +263,7 @@ ivas_error stereo_set_tdm_fx( /* deallocate CLDFB ana for secondary channel */ IF( st->cldfbAnaEnc != NULL ) { - deleteCldfb_ivas( &st->cldfbAnaEnc ); + deleteCldfb_ivas_fx( &st->cldfbAnaEnc ); } /* deallocate BWEs for secondary channel */ @@ -277,7 +275,7 @@ ivas_error stereo_set_tdm_fx( st->hBWE_TD = NULL; } - deleteCldfb_ivas( &st->cldfbSynTd ); + deleteCldfb_ivas_fx( &st->cldfbSynTd ); IF( st->hBWE_FD != NULL ) { @@ -311,7 +309,7 @@ ivas_error stereo_set_tdm_fx( /* allocate CLDFB ana for secondary channel */ IF( st->cldfbAnaEnc == NULL ) { - IF( NE_32( ( error = openCldfb_ivas_enc( &st->cldfbAnaEnc, CLDFB_ANALYSIS, st->input_Fs, CLDFB_PROTOTYPE_1_25MS ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &st->cldfbAnaEnc, CLDFB_ANALYSIS, st->input_Fs, CLDFB_PROTOTYPE_1_25MS, ENC ) ), IVAS_ERR_OK ) ) { return error; } @@ -324,7 +322,7 @@ ivas_error stereo_set_tdm_fx( { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for TD BWE\n" ) ); } - IF( NE_32( ( error = openCldfb_ivas_enc( &st->cldfbSynTd, CLDFB_SYNTHESIS, 16000, CLDFB_PROTOTYPE_1_25MS ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &st->cldfbSynTd, CLDFB_SYNTHESIS, 16000, CLDFB_PROTOTYPE_1_25MS, ENC ) ), IVAS_ERR_OK ) ) { return error; } @@ -473,7 +471,7 @@ void tdm_configure_enc_fx( } } ELSE IF( ( LT_16( sts[1]->coder_type, AUDIO ) && NE_16( sts[1]->coder_type, UNVOICED ) ) || /* TC and VC are not supported in secondary channel */ - ( ( EQ_16( sts[1]->coder_type, AUDIO ) && LE_32( hCPE->element_brate, IVAS_24k4 ) ) || ( EQ_16( sts[0]->sp_aud_decision1, 1 ) && GE_32( hCPE->element_brate, IVAS_16k4 ) ) || ( EQ_16( sts[1]->sp_aud_decision0, 1 ) && GE_32( hCPE->element_brate, IVAS_13k2 ) ) ) ) + ( ( EQ_16( sts[1]->coder_type, AUDIO ) && LE_32( hCPE->element_brate, IVAS_24k4 ) ) || ( EQ_16( sts[0]->sp_aud_decision1, 1 ) && GE_32( hCPE->element_brate, IVAS_16k4 ) ) || ( EQ_16( sts[1]->sp_aud_decision0, 1 ) && GT_32( hCPE->element_brate, IVAS_13k2 ) ) ) ) { sts[1]->coder_type = GENERIC; move16(); @@ -485,7 +483,7 @@ void tdm_configure_enc_fx( } test(); - IF( GE_32( hCPE->element_brate, IVAS_24k4 ) && EQ_16( hCPE->hStereoClassif->lrtd_mode, 1 ) ) + IF( GT_32( hCPE->element_brate, IVAS_24k4 ) && EQ_16( hCPE->hStereoClassif->lrtd_mode, 1 ) ) { if ( EQ_16( sts[1]->coder_type, UNVOICED ) ) { @@ -1007,9 +1005,8 @@ void stereo_tdm_prep_dwnmx_fx( const Word16 input_q /* i : frame lenght */ ) { -#define USER_ENER Word32 mener; - int16_t i, sw_pos, enr_len; + Word16 i, sw_pos, enr_len; Encoder_State **sts; Word16 mener_e; sts = hCPE->hCoreCoder; diff --git a/lib_enc/ivas_tcx_core_enc.c b/lib_enc/ivas_tcx_core_enc_fx.c similarity index 96% rename from lib_enc/ivas_tcx_core_enc.c rename to lib_enc/ivas_tcx_core_enc_fx.c index b944816a9d18dc9bd1d78318126c41ab82e54c40..1e66c148868960ae61e8dbcdbfe15f84b7cff136 100644 --- a/lib_enc/ivas_tcx_core_enc.c +++ b/lib_enc/ivas_tcx_core_enc_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other @@ -35,13 +35,11 @@ #include "options.h" #include #include "cnst.h" -#include "prot.h" +#include "prot_fx.h" #include "rom_com.h" #include "basop_proto_func.h" #include "wmc_auto.h" -#include "ivas_prot.h" #include "ivas_prot_fx.h" -#include "prot_fx.h" #include "prot_fx_enc.h" #include "rom_com_fx.h" #include "ivas_prot_fx.h" @@ -347,7 +345,7 @@ void stereo_tcx_core_enc( *--------------------------------------------------------------------------------*/ /* TCX20/TCX10 and coder type */ - writeTCXMode( st, hBstr, 0, /* MCT_flag */ &nbits_start ); + writeTCXMode_fx( st, hBstr, 0, /* MCT_flag */ &nbits_start ); /* write last_core for error concealment */ q_ind_val = 0; @@ -361,10 +359,10 @@ void stereo_tcx_core_enc( push_next_indice( hBstr, q_ind_val, 1 ); /* write TCX overlap mode (1 bit: full, 2 bits: half or no overlap) */ - writeTCXWindowing( hBstr, st->hTcxCfg->tcx_curr_overlap_mode ); + writeTCXWindowing_fx( hBstr, st->hTcxCfg->tcx_curr_overlap_mode ); IF( EQ_16( st->core, TCX_10_CORE ) ) { - writeTCXWindowing( hBstr, st->hTcxCfg->tcx_last_overlap_mode ); + writeTCXWindowing_fx( hBstr, st->hTcxCfg->tcx_last_overlap_mode ); } assert( nbits_header == ( hBstr->nb_bits_tot - nbits_start ) ); @@ -466,7 +464,7 @@ void stereo_tcx_core_enc( E_LPC_lsp_lsf_conversion( lsp_fx, lsf_fx, M ); /* Quantize */ - Q_lsf_tcxlpc_fx( lsf_fx, lsf_tcx_q_fx, lspq_ind, param_lpc, M, st->narrowBand, tcx_lpc_cdk, st->mem_MA_fx, st->hTcxCfg->coder_type, st->Bin_E_fx, Q_ener ); + Q_lsf_tcxlpc_ivas_fx( lsf_fx, lsf_tcx_q_fx, lspq_ind, param_lpc, M, st->narrowBand, tcx_lpc_cdk, st->mem_MA_fx, st->hTcxCfg->coder_type, st->Bin_E_fx, st->q_Bin_E ); /* Account for consumed bits */ nbits_lpc[0] = TCXLPC_NUMBITS; @@ -557,8 +555,8 @@ void stereo_tcx_core_enc( st->hTcxCfg->tcx_last_overlap_mode = st->hTcxCfg->tcx_curr_overlap_mode; move16(); - s = sub( getScaleFactor16( st->synth, st->L_frame ), 2 ); - s = s_min( s, getScaleFactor16( st->hLPDmem->syn, M ) ); + s = sub( norm_arr( st->synth, st->L_frame ), 2 ); + s = s_min( s, norm_arr( st->hLPDmem->syn, M ) ); IF( st->tcxonly == 0 ) { s = s_min( s, norm_s( st->wspeech_enc[st->L_frame - 1] ) ); @@ -570,22 +568,10 @@ void stereo_tcx_core_enc( move16(); move16(); - /* Scaling old_exc buffer to Q_new */ - IF( NE_16( Q_new, Q_exc ) ) - { - Scale_sig( st->hLPDmem->old_exc, L_EXC_MEM, sub( Q_new, Q_exc ) ); - } - coder_tcx_post_ivas_fx( st, st->hLPDmem, st->hTcxCfg, st->synth, A_q_fx, Aw_fx, st->wspeech_enc, Q_new ); - /* Upscaling old_exc buffer */ - s = getScaleFactor16( st->hLPDmem->old_exc, L_EXC_MEM ) - 1; - Scale_sig( st->hLPDmem->old_exc, L_EXC_MEM, s ); - IF( st->hTdCngEnc != NULL ) - { - Scale_sig( st->hTdCngEnc->cng_exc2_buf, HO_HIST_SIZE * L_FFT, sub( add( shl( Q_new, 1 ), s ), Q_exc ) ); - } - Q_exc = add( shl( Q_new, 1 ), s ); // 2 * Q_new + s + Q_exc = Q_new; // Q_new + move16(); IF( st->enableTcxLpc ) { @@ -657,7 +643,7 @@ void stereo_tcx_core_enc( ELSE { cng_params_upd_ivas_fx( lsp_new_fx, st->hLPDmem->old_exc + L_EXC_MEM - st->L_frame, st->L_frame, &st->hTdCngEnc->ho_circ_ptr, st->hTdCngEnc->ho_ener_circ_fx, &st->hTdCngEnc->ho_circ_size, - st->hTdCngEnc->ho_lsp_circ_fx, Q_exc, ENC, st->hTdCngEnc->ho_env_circ_fx, &st->hTdCngEnc->cng_buf_cnt, st->hTdCngEnc->cng_exc2_buf, st->hTdCngEnc->cng_Qexc_buf, st->hTdCngEnc->cng_brate_buf, st->hDtxEnc->last_active_brate, st->element_mode, + st->hTdCngEnc->ho_lsp_circ_fx, st->hLPDmem->q_lpd_old_exc, ENC, st->hTdCngEnc->ho_env_circ_fx, &st->hTdCngEnc->cng_buf_cnt, st->hTdCngEnc->cng_exc2_buf, st->hTdCngEnc->cng_Qexc_buf, st->hTdCngEnc->cng_brate_buf, st->hDtxEnc->last_active_brate, st->element_mode, st->hFdCngEnc->hFdCngCom->CngBandwidth ); } @@ -712,12 +698,10 @@ void stereo_tcx_core_enc( move16(); Scale_sig( st->hLPDmem->mem_syn1_fx, M, sub( s_min( curr_q_syn, st->hLPDmem->q_mem_syn ), st->hLPDmem->q_mem_syn ) ); Scale_sig( st->hLPDmem->mem_syn3, M, sub( s_min( curr_q_syn, st->hLPDmem->q_mem_syn ), st->hLPDmem->q_mem_syn ) ); - st->hLPDmem->q_mem_syn = sub( Q_new, 1 ); + st->hLPDmem->q_mem_syn = s_min( curr_q_syn, st->hLPDmem->q_mem_syn ); move16(); st->hLPDmem->q_lpd_syn = Q_new; move16(); - st->hLPDmem->q_lpd_old_exc = Q_new; - move16(); IF( st->hTdCngEnc != NULL ) { FOR( Word16 ii = 0; ii < HO_HIST_SIZE; ii++ ) @@ -727,10 +711,6 @@ void stereo_tcx_core_enc( move16(); } } - st->q_Bin_E = Q_new + Q_SCALE - 2; - move16(); - st->q_Bin_E_old = Q_new + Q_SCALE - 2; - move16(); Scale_sig( st->synth, st->L_frame, -Q_new ); IF( st->tcxonly == 0 ) { @@ -810,6 +790,13 @@ Word16 ivas_acelp_tcx20_switching_fx( #ifdef MSAN_FIX set16_fx( window_fx, 0, L_LOOK_16k ); set16_fx( xn_buf_fx, 0, L_MDCT_OVLP_MAX + L_FRAME_PLUS + L_MDCT_OVLP_MAX ); + FOR( i = 0; i < L_LOOK_16k; i++ ) + { + window_p_fx[i].v.re = 0; + move16(); + window_p_fx[i].v.im = 0; + move16(); + } #endif L_frame_tmp = L_frame; @@ -865,6 +852,15 @@ Word16 ivas_acelp_tcx20_switching_fx( overlap = st->hTcxCfg->tcx_mdct_window_delay; move16(); +#ifdef MSAN_FIX + FOR( i = 0; i < st->hTcxCfg->tcx_mdct_window_length / 2; i++ ) + { + window_fx[st->hTcxCfg->tcx_mdct_window_length - 1 - i] = st->hTcxCfg->tcx_mdct_window[i].v.re; // Q15 + move16(); + window_fx[i] = st->hTcxCfg->tcx_mdct_window[i].v.im; // Q15 + move16(); + } +#else FOR( i = 0; i < L_LOOK_16k / 2; i++ ) { window_fx[L_LOOK_16k / 2 - 1 - i] = st->hTcxCfg->tcx_mdct_window[i].v.re; // Q15 @@ -872,6 +868,7 @@ Word16 ivas_acelp_tcx20_switching_fx( window_fx[i] = st->hTcxCfg->tcx_mdct_window[i].v.im; // Q15 move16(); } +#endif } ELSE { @@ -1048,7 +1045,12 @@ Word16 ivas_acelp_tcx20_switching_fx( IF( LE_32( offset, 0xAA153 ) ) /* 0xAA153 -> 32.f * log2(10)/10 */ { +#ifdef FIX_USAN_ISSUES + offset = (Word32) 0xFFD57AB5; /* 0xFFD57AB5 -> -128.f * log2(10)/10; */ + move32(); +#else offset = L_add( 0xFFD57AB5, 0 ); /* 0xFFD57AB5 -> -128.f * log2(10)/10; */ +#endif } offset_tcx = offset; move32(); @@ -1060,6 +1062,8 @@ Word16 ivas_acelp_tcx20_switching_fx( ener = Mpy_32_16_1( Mpy_32_16_1( ener, 0x78AE ), getInvFrameLen( L_frame ) ); /* 0x78AE -> sqrt(2)/12 (Q18) */ ener_e = sub( s, 9 ); + x_fx = hTcxEnc->spectrum_long_fx; + IF( !flag_16k_smc ) { const Word16 *bands; @@ -1149,7 +1153,11 @@ Word16 ivas_acelp_tcx20_switching_fx( { *pt_ener_sfr = -668739840; /* 0xFFEC1185 -> log2(1e-6) in 6Q25 */ move32(); - tmp32 = 0xFFEC1185; /* 0xFFEC1185 -> log2(1e-6) in 15Q16 */ +#ifdef FIX_USAN_ISSUES + tmp32 = (Word32) 0xFFEC1185; /* 0xFFEC1185 -> log2(1e-6) in 15Q16 */ +#else + tmp32 = 0xFFEC1185; /* 0xFFEC1185 -> log2(1e-6) in 15Q16 */ +#endif move32(); } ELSE diff --git a/lib_enc/ivas_td_low_rate_enc.c b/lib_enc/ivas_td_low_rate_enc_fx.c similarity index 86% rename from lib_enc/ivas_td_low_rate_enc.c rename to lib_enc/ivas_td_low_rate_enc_fx.c index 22ce9b6e9d0f2b825bf0ccf7dc42f4d48833c4b2..2daa9ed5035a5747a51d0cdd486d20fa0a1d7527 100644 --- a/lib_enc/ivas_td_low_rate_enc.c +++ b/lib_enc/ivas_td_low_rate_enc_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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,10 +37,8 @@ #include "rom_com.h" #include "ivas_rom_com.h" #include "ivas_cnst.h" -#include "prot.h" #include "prot_fx.h" #include "prot_fx_enc.h" -#include "ivas_prot.h" #include "ivas_prot_fx.h" #include "wmc_auto.h" @@ -219,9 +217,18 @@ void encod_gen_2sbfr( Word32 norm_gain_code; Word16 pitch_limit_flag; Word16 error; + Word16 q_h1; LPD_state_HANDLE hLPDmem = st->hLPDmem; +#ifdef FIX_1320_LOWRATE_ACELP + Word16 gcode16; + Word32 Lgcode, Ltmp; +#endif +#ifdef MSAN_FIX + set16_fx( cn, 0, 2 * L_SUBFR ); /* Target vector in residual domain */ +#endif + /*------------------------------------------------------------------* * Initializations *------------------------------------------------------------------*/ @@ -261,22 +268,23 @@ void encod_gen_2sbfr( Copy( &res[i_subfr], &exc[i_subfr], 2 * L_SUBFR ); // Q_new - // Scaling mem_syn buffer to Q_new - 1 from e_mem_syn - // Scale_sig( &hLPDmem->mem_w0, M + 1, sub( add( *Q_new, hLPDmem->e_mem_syn ), Q16 ) ); // M + 1 to sync mem_syn exponent with mem_w0 exponent - // hLPDmem->e_mem_syn = sub( Q16, *Q_new ); - +#ifndef FIX_1320_LOWRATE_ACELP find_targets_fx( speech, hLPDmem->mem_syn, i_subfr, &hLPDmem->mem_w0, p_Aq, res, 2 * L_SUBFR, p_Aw, st->preemph_fac, xn, cn, h1 ); +#else + find_targets_ivas_fx( speech, hLPDmem->mem_syn, i_subfr, &hLPDmem->mem_w0, p_Aq, res, 2 * L_SUBFR, p_Aw, st->preemph_fac, xn, cn, h1 ); +#endif - /*Scale_sig(h1, L_SUBFR, shift); */ /*Q14-shift */ - Copy_Scale_sig( h1, h2, 2 * L_SUBFR, -2 ); - Scale_sig( h1, 2 * L_SUBFR, add( 1, shift ) ); /* set h1[] in Q14 with scaling for convolution */ + q_h1 = sub( 14, norm_s( h1[0] ) ); + Copy_Scale_sig( h1, h2, 2 * L_SUBFR, sub( 11, q_h1 ) ); /*------------------------------------------------------------------------* * Close-loop pitch search on the 1st and 3rd subfr only and quantization * Adaptive exc. construction *------------------------------------------------------------------------*/ + *pt_pitch = pit_encode_ivas_fx( st->hBstr, st->acelp_cfg.pitch_bits, st->core_brate, 0, L_frame, coder_type, &pitch_limit_flag, i_subfr, exc, 2 * L_SUBFR, st->pitch, &T0_min, &T0_max, &T0, &T0_frac, h1, xn, tdm_Pitch_reuse_flag, tdm_Pri_pitch_buf, Q_new ); + move16(); - *pt_pitch = pit_encode_ivas_fx( st->hBstr, st->acelp_cfg.pitch_bits, st->core_brate, 0, L_frame, coder_type, &pitch_limit_flag, i_subfr, exc, 2 * L_SUBFR, st->pitch, &T0_min, &T0_max, &T0, &T0_frac, h1, xn, tdm_Pitch_reuse_flag, tdm_Pri_pitch_buf ); + Scale_sig( h1, 2 * L_SUBFR, sub( 13, q_h1 ) ); // Q13 tbe_celp_exc_ivas( st->element_mode, st->idchan, L_frame, 2 * L_SUBFR, i_subfr, T0, T0_frac, &error, bwe_exc, st->tdm_LRTD_flag ); @@ -290,14 +298,21 @@ void encod_gen_2sbfr( * Gain clipping test to avoid unstable synthesis on frame erasure *-----------------------------------------------------------------*/ +#ifndef FIX_1320_LOWRATE_ACELP clip_gain = gp_clip_fx( st->element_mode, st->core_brate, st->voicing_fx, i_subfr, coder_type, xn, st->clip_var_fx, Q_new ); // Q0 - +#else + clip_gain = gp_clip_fx( st->element_mode, st->core_brate, st->voicing_fx, i_subfr, coder_type, xn, st->clip_var_fx, sub( Q_new, 1 ) ); // Q0 +#endif /*-----------------------------------------------------------------* * LP filtering of the adaptive excitation, codebook target computation *-----------------------------------------------------------------*/ + Scale_sig( h1, 2 * L_SUBFR, add( 1, shift ) ); /* set h1[] in Q14 with scaling for convolution */ +#ifndef FIX_1320_LOWRATE_ACELP lp_filt_exc_enc_fx( MODE1, coder_type, i_subfr, exc, h1, xn, y1, xn2, 2 * L_SUBFR, L_frame, g_corr, clip_gain, &gain_pit, &st->acelp_cfg.ltf_mode ); - +#else + lp_filt_exc_enc_ivas_fx( MODE1, coder_type, i_subfr, exc, h1, xn, y1, xn2, 2 * L_SUBFR, L_frame, g_corr, clip_gain, &gain_pit, &st->acelp_cfg.ltf_mode ); +#endif /* update long-term pitch gain for speech/music classifier */ st->hSpMusClas->lowrate_pitchGain = add( mult( 29491, st->hSpMusClas->lowrate_pitchGain ), mult( 3277, gain_pit ) ); // Q14 move16(); @@ -330,14 +345,30 @@ void encod_gen_2sbfr( gp_clip_test_gain_pit_fx( st->element_mode, st->core_brate, gain_pit, st->clip_var_fx ); +#ifndef FIX_1320_LOWRATE_ACELP hLPDmem->tilt_code = est_tilt_ivas_fx( exc + i_subfr, gain_pit, code, gain_code, &voice_fac, Q_new, 2 * L_SUBFR, 0 ); +#else + Lgcode = L_shl_sat( gain_code, Q_new ); /* scaled gain_code with Qnew -> Q16*/ + gcode16 = round_fx_sat( Lgcode ); /*Q0*/ + hLPDmem->tilt_code = est_tilt_ivas_fx( exc + i_subfr, gain_pit, code, Lgcode, &voice_fac, Q_new, 2 * L_SUBFR, 0 ); +#endif move16(); /*-----------------------------------------------------------------* * Update memory of the weighting filter *-----------------------------------------------------------------*/ +#ifndef FIX_1320_LOWRATE_ACELP hLPDmem->mem_w0 = sub( sub( xn[2 * L_SUBFR - 1], mult_r( gain_pit, y1[2 * L_SUBFR - 1] ) ), mult_r( extract_h( gain_code ), y2[2 * L_SUBFR - 1] ) ); +#else + Ltmp = L_mult0( gcode16, y2[2 * L_SUBFR - 1] ); /*Q10*/ + Ltmp = L_shl( Ltmp, add( 5, shift ) ); /*Q15+shift*/ + Ltmp = L_negate( Ltmp ); + Ltmp = L_mac( Ltmp, xn[2 * L_SUBFR - 1], 16384 /*Q14*/ ); /* Q_new-1+shift+14+1 */ + Ltmp = L_msu( Ltmp, y1[2 * L_SUBFR - 1], gain_pit /*Q14*/ ); /* Q_new-1+shift+14+1 */ + Ltmp = L_shl_sat( Ltmp, sub( 1, shift ) ); /* 15 + Q_new */ + hLPDmem->mem_w0 = round_fx_sat( Ltmp ); /*Q_new-1 */ +#endif move16(); /*-----------------------------------------------------------------* @@ -345,6 +376,7 @@ void encod_gen_2sbfr( * Save the non-enhanced excitation for FEC_exc *-----------------------------------------------------------------*/ +#ifndef FIX_1320_LOWRATE_ACELP FOR( i = 0; i < 2 * L_SUBFR; i++ ) { exc2[i + i_subfr] = mult( gain_pit, exc[i + i_subfr] ); @@ -352,7 +384,20 @@ void encod_gen_2sbfr( exc[i + i_subfr] = add( exc2[i + i_subfr], mult( extract_h( gain_code ), code[i] ) ); move16(); } - +#else + FOR( i = 0; i < 2 * L_SUBFR; i++ ) + { + /* code in Q9, gain_pit in Q14 */ + exc2[i + i_subfr] = shl_sat( mult( gain_pit, exc[i + i_subfr] ), 1 ); + Ltmp = L_mult( gcode16, code[i] ); /* Q10 */ + Ltmp = L_shl_sat( Ltmp, 5 ); /* Q15 */ + Ltmp = L_mac_sat( Ltmp, exc[i + i_subfr], gain_pit ); /* Q15 */ + Ltmp = L_shl_sat( Ltmp, 1 ); /* saturation can occur here Q16*/ + exc[i + i_subfr] = round_fx_sat( Ltmp ); + move16(); + move16(); + } +#endif /*-----------------------------------------------------------------* * Prepare TBE excitation *-----------------------------------------------------------------*/ @@ -366,9 +411,11 @@ void encod_gen_2sbfr( * Synthesize speech to update mem_syn_flt[]. * Update A(z) filters *-----------------------------------------------------------------*/ - +#ifndef FIX_1320_LOWRATE_ACELP E_UTIL_synthesis( 0, p_Aq, &exc[i_subfr], &syn[i_subfr], 2 * L_SUBFR, hLPDmem->mem_syn, 1, M ); - +#else + Syn_filt_s( 1, p_Aq, M, &exc[i_subfr], &syn[i_subfr], 2 * L_SUBFR, hLPDmem->mem_syn, 1 ); +#endif p_Aw += 2 * ( M + 1 ); p_Aq += 2 * ( M + 1 ); diff --git a/lib_enc/lead_indexing.c b/lib_enc/lead_indexing.c deleted file mode 100644 index d20e6a703cc1aa958456de8a872773b68d4ecc89..0000000000000000000000000000000000000000 --- a/lib_enc/lead_indexing.c +++ /dev/null @@ -1,208 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include "rom_com.h" -#include "prot.h" -#include "wmc_auto.h" - -/*-------------------------------------------------------------------* - * Local function prototypes - *-------------------------------------------------------------------*/ - -static int16_t fcb_encode_pos( const int16_t pos_vector[], const int16_t pulse_num, const int16_t pos_num ); - - -/*-------------------------------------------------------------------* - * re8_compute_base_index: - * - * Compute base index for RE8 - *-------------------------------------------------------------------*/ - -void re8_compute_base_index( - const int16_t *x, /* i : Elemen of Q2, Q3 or Q4 */ - const int16_t ka, /* i : Identifier of the absolute leader related to x */ - uint16_t *I /* o : index */ -) -{ - int16_t i, j, k1, m; - int16_t setor_8p[8], setor_8p_temp[8]; - int16_t sign_8p; - int16_t code_index, code_level, code_area; - uint16_t offset; - const int16_t *a1, *a2; - - a1 = vals_a[ka]; - a2 = vals_q[ka]; - - /* the sign process */ - - sign_8p = 0; - m = 0; - code_index = 0; - k1 = a2[0]; - - if ( ( a2[1] == 2 ) && ( a1[0] ^ 1 ) && ( ka != 5 ) ) - { - for ( i = 0; i < 8; i++ ) - { - if ( x[i] != 0 ) - { - sign_8p = sign_8p * 2; - setor_8p_temp[m] = i; - m++; - } - if ( x[i] < 0 ) - { - sign_8p += 1; - } - } - - code_index = fcb_encode_pos( setor_8p_temp, 8, m ); - code_index = ( code_index << k1 ) + sign_8p; - - offset = Is[ka]; - - - *I = offset + code_index; - } - else - { - for ( i = 0; i < 8; i++ ) - { - setor_8p[i] = (int16_t) abs( x[i] ); - - if ( x[i] < 0 ) - { - sign_8p = sign_8p * 2 + 1; - m++; - } - if ( x[i] > 0 ) - { - sign_8p = sign_8p * 2; - m++; - } - } - - if ( k1 != m ) - { - sign_8p = sign_8p >> 1; - } - - /* code level by level */ - - code_level = a2[1]; - code_area = 8; - - if ( a2[2] != 1 ) - { - for ( j = 0; j < code_level - 1; j++ ) - { - m = 0; - - for ( i = 0; i < code_area; i++ ) - { - if ( setor_8p[i] != a1[j] ) - { - setor_8p_temp[m] = i; - setor_8p[m] = setor_8p[i]; - m++; - } - } - code_index *= select_table22[m][code_area]; - - code_index += fcb_encode_pos( setor_8p_temp, code_area, m ); - - code_area = m; - } - } - else - { - for ( i = 0; i < code_area; i++ ) - { - if ( setor_8p[i] == a1[1] ) - { - code_index += i; - } - } - } - - code_index = ( code_index << k1 ) + sign_8p; - - offset = Is[ka]; - - *I = offset + code_index; - } - - return; -} - -/*-------------------------------------------------------------------* - * fcb_encode_pos: - * - * Base function to compute base index for RE8 - *-------------------------------------------------------------------*/ - -/*! r: Code index */ -static int16_t fcb_encode_pos( - const int16_t pos_vector[], /* i : Position vectort */ - const int16_t pulse_num, /* i : Pulse number */ - const int16_t pos_num /* i : Position number */ -) -{ - int16_t i, j; - int16_t code_index; - int16_t temp, temp1; - const int16_t *select_table23; - - temp = pulse_num - 1; - - select_table23 = select_table22[pos_num]; - - code_index = select_table23[pulse_num] - select_table23[pulse_num - pos_vector[0]]; - - for ( i = 0, j = 1; i < pos_num - 1; i++, j++ ) - { - temp1 = pos_num - j; - - select_table23 = select_table22[temp1]; - - code_index += select_table23[temp - pos_vector[i]] - select_table23[pulse_num - pos_vector[j]]; - } - - return code_index; -} diff --git a/lib_enc/lib_enc.c b/lib_enc/lib_enc.c index aa1b6e32b7157d3cf1b90a91f3b9f0d4e2cf6e84..9c15a329c4fe37f917ea2c2facf30f0601dbf6ac 100644 --- a/lib_enc/lib_enc.c +++ b/lib_enc/lib_enc.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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,7 @@ #include "debug.h" #endif #include "lib_enc.h" -#include "ivas_prot.h" #include "ivas_prot_fx.h" -#include "prot.h" #include "prot_fx.h" #include "prot_fx_enc.h" #include "wmc_auto.h" @@ -60,8 +58,8 @@ struct IVAS_ENC bool cmd_stereo; #endif bool switchingActive; /* flag for configuration changes during encoding - currently only used with mono */ - int16_t Opt_RF_ON_loc; - int16_t rf_fec_offset_loc; + Word16 Opt_RF_ON_loc; + Word16 rf_fec_offset_loc; bool ismMetadataProvided[MAX_NUM_OBJECTS]; bool maxBandwidthUser; /* Was a specific max bandwith selected by the user? */ IVAS_ENC_BANDWIDTH newBandwidthApi; /* maximum encoded bandwidth, as set on API level */ @@ -78,14 +76,14 @@ static ivas_error setChannelAwareConfig_fx( IVAS_ENC_HANDLE hIvasEnc, const IVAS static ivas_error sanitizeBandwidth_fx( const IVAS_ENC_HANDLE hIvasEnc ); static ivas_error sanitizeBitrateISM_fx( const ENCODER_CONFIG_HANDLE hEncoderConfig, const bool extMetadataApi ); static Word16 getInputBufferSize_fx( const Encoder_Struct *st_ivas ); -static ivas_error configureEncoder( IVAS_ENC_HANDLE hIvasEnc, const int32_t inputFs, const int32_t initBitrate, const IVAS_ENC_BANDWIDTH initBandwidth, const IVAS_ENC_DTX_CONFIG dtxConfig, const IVAS_ENC_CHANNEL_AWARE_CONFIG caConfig ); -static ivas_error setBitrate( IVAS_ENC_HANDLE hIvasEnc, const int32_t totalBitrate ); +static ivas_error configureEncoder( IVAS_ENC_HANDLE hIvasEnc, const Word32 inputFs, const Word32 initBitrate, const IVAS_ENC_BANDWIDTH initBandwidth, const IVAS_ENC_DTX_CONFIG dtxConfig, const IVAS_ENC_CHANNEL_AWARE_CONFIG caConfig ); +static ivas_error setBitrate( IVAS_ENC_HANDLE hIvasEnc, const Word32 totalBitrate ); static ivas_error doCommonConfigureChecks( IVAS_ENC_HANDLE hIvasEnc ); static ivas_error doCommonSetterChecks( IVAS_ENC_HANDLE hIvasEnc ); static void init_encoder_config( ENCODER_CONFIG_HANDLE hEncoderConfig ); static void resetIsmMetadataProvidedFlags( IVAS_ENC_HANDLE hIvasEnc ); -static ivas_error bandwidthApiToInternal( const IVAS_ENC_BANDWIDTH maxBandwidth, int16_t *internalMaxBandwidth ); -static ivas_error fecIndicatorApiToInternal( const IVAS_ENC_FEC_INDICATOR fecIndicator, int16_t *fecIndicatorInternal ); +static ivas_error bandwidthApiToInternal( const IVAS_ENC_BANDWIDTH maxBandwidth, Word16 *internalMaxBandwidth ); +static ivas_error fecIndicatorApiToInternal( const IVAS_ENC_FEC_INDICATOR fecIndicator, Word16 *fecIndicatorInternal ); #ifdef DEBUGGING static ivas_error forcedModeApiToInternal( IVAS_ENC_FORCED_MODE forcedMode, int16_t *forcedModeInternal ); #endif @@ -150,7 +148,7 @@ ivas_error IVAS_ENC_Open( init_encoder_config( st_ivas->hEncoderConfig ); /* initialize pointers to handles to NULL */ - ivas_initialize_handles_enc( st_ivas ); + ivas_initialize_handles_enc_fx( st_ivas ); st_ivas->ind_list = NULL; st_ivas->ind_list_metadata = NULL; @@ -216,7 +214,7 @@ ivas_error IVAS_ENC_Open_fx( init_encoder_config( st_ivas->hEncoderConfig ); /* initialize pointers to handles to NULL */ - ivas_initialize_handles_enc( st_ivas ); + ivas_initialize_handles_enc_fx( st_ivas ); st_ivas->ind_list = NULL; st_ivas->ind_list_metadata = NULL; @@ -246,7 +244,7 @@ void IVAS_ENC_Close( if ( ( *phIvasEnc )->isConfigured ) { - ivas_destroy_enc( ( *phIvasEnc )->st_ivas ); + ivas_destroy_enc_fx( ( *phIvasEnc )->st_ivas ); } else { @@ -277,8 +275,8 @@ void IVAS_ENC_Close( ivas_error IVAS_ENC_ConfigureForMono( IVAS_ENC_HANDLE hIvasEnc, /* i/o: IVAS encoder handle */ - const int32_t inputFs, /* i : input sampling frequency */ - const int32_t bitrate, /* i : requested bitrate of the output bitstream */ + const Word32 inputFs, /* i : input sampling frequency */ + const Word32 bitrate, /* i : requested bitrate of the output bitstream */ const bool max_bwidth_user, /* i : shows if bandwidth limitation was set by the user (true) or if default bandwidth was used (false) */ const IVAS_ENC_BANDWIDTH maxBandwidth, /* i : bandwidth limitation */ const IVAS_ENC_DTX_CONFIG dtxConfig, /* i : configuration of DTX, can by set to default by using IVAS_ENC_GetDefaultDtxConfig() */ @@ -297,7 +295,7 @@ ivas_error IVAS_ENC_ConfigureForMono( } hIvasEnc->st_ivas->hEncoderConfig->ivas_format = MONO_FORMAT; - hIvasEnc->st_ivas->hEncoderConfig->is_binaural = (int16_t) is_binaural; + hIvasEnc->st_ivas->hEncoderConfig->is_binaural = (Word16) is_binaural; if ( downmixFromStereo ) { @@ -319,8 +317,8 @@ ivas_error IVAS_ENC_ConfigureForMono( ivas_error IVAS_ENC_ConfigureForStereo( IVAS_ENC_HANDLE hIvasEnc, /* i/o: IVAS encoder handle */ - const int32_t inputFs, /* i : input sampling frequency */ - const int32_t bitrate, /* i : requested bitrate of the output bitstream */ + const Word32 inputFs, /* i : input sampling frequency */ + const Word32 bitrate, /* i : requested bitrate of the output bitstream */ const bool max_bwidth_user, /* i : shows if bandwidth limitation was set by the user (true) or if default bandwidth was used (false) */ const IVAS_ENC_BANDWIDTH maxBandwidth, /* i : bandwidth limitation */ const IVAS_ENC_DTX_CONFIG dtxConfig, /* i : configuration of DTX, can by set to default by using IVAS_ENC_GetDefaultDtxConfig() */ @@ -345,7 +343,7 @@ ivas_error IVAS_ENC_ConfigureForStereo( hEncoderConfig = st_ivas->hEncoderConfig; hEncoderConfig->nchan_inp = 2; hEncoderConfig->ivas_format = STEREO_FORMAT; - hEncoderConfig->is_binaural = (int16_t) is_binaural; + hEncoderConfig->is_binaural = (Word16) is_binaural; #ifdef DEBUGGING switch ( stereoMode ) @@ -459,12 +457,12 @@ ivas_error IVAS_ENC_ConfigureForMASAObjects( ivas_error IVAS_ENC_ConfigureForObjects( IVAS_ENC_HANDLE hIvasEnc, /* i/o: IVAS encoder handle */ - const int32_t inputFs, /* i : input sampling frequency */ - const int32_t bitrate, /* i : requested bitrate of the output bitstream */ + const Word32 inputFs, /* i : input sampling frequency */ + const Word32 bitrate, /* i : requested bitrate of the output bitstream */ const bool max_bwidth_user, /* i : shows if bandwidth limitation was set by the user (true) or if default bandwidth was used (false) */ const IVAS_ENC_BANDWIDTH maxBandwidth, /* i : bandwidth limitation */ const IVAS_ENC_DTX_CONFIG dtxConfig, /* i : configuration of DTX, can by set to default by using IVAS_ENC_GetDefaultDtxConfig() */ - const uint16_t numObjects, /* i : number of objects to be encoded */ + const UWord16 numObjects, /* i : number of objects to be encoded */ const bool ism_extended_metadata /* i : Extended metadata used (true/false), where extended metadata includes radius and orientation */ ) { @@ -504,7 +502,7 @@ ivas_error IVAS_ENC_ConfigureForObjects( ivas_error IVAS_ENC_FeedObjectMetadata( IVAS_ENC_HANDLE hIvasEnc, /* i/o: IVAS encoder handle */ - const uint16_t ismIndex, /* i : object index */ + const UWord16 ismIndex, /* i : object index */ const IVAS_ISM_METADATA metadata /* i : object metadata handle for current frame */ ) { @@ -552,8 +550,8 @@ ivas_error IVAS_ENC_FeedObjectMetadata( ivas_error IVAS_ENC_ConfigureForAmbisonics( IVAS_ENC_HANDLE hIvasEnc, /* i/o: IVAS encoder handle */ - const int32_t inputFs, /* i : input sampling frequency */ - const int32_t bitrate, /* i : requested bitrate of the output bitstream */ + const Word32 inputFs, /* i : input sampling frequency */ + const Word32 bitrate, /* i : requested bitrate of the output bitstream */ const bool max_bwidth_user, /* i : shows if bandwidth limitation was set by the user (true) or if default bandwidth was used (false) */ const IVAS_ENC_BANDWIDTH maxBandwidth, /* i : bandwidth limitation */ const IVAS_ENC_DTX_CONFIG dtxConfig, /* i : configuration of DTX, can by set to default by using IVAS_ENC_GetDefaultDtxConfig() */ @@ -581,7 +579,7 @@ ivas_error IVAS_ENC_ConfigureForAmbisonics( hEncoderConfig->nchan_inp = ivas_sba_get_nchan_fx( hEncoderConfig->sba_order, 0 ); /*planar input arg. deliberately set to zero since input always in ACN/SN3D*/ - hEncoderConfig->Opt_PCA_ON = (int16_t) Opt_PCA_ON; + hEncoderConfig->Opt_PCA_ON = (Word16) Opt_PCA_ON; hIvasEnc->maxBandwidthUser = max_bwidth_user; @@ -781,8 +779,8 @@ ivas_error IVAS_ENC_FeedMasaMetadata( ivas_error IVAS_ENC_ConfigureForMultichannel( IVAS_ENC_HANDLE hIvasEnc, /* i/o: IVAS encoder handle */ - const int32_t inputFs, /* i : input sampling frequency */ - const int32_t bitrate, /* i : requested bitrate of the output bitstream */ + const Word32 inputFs, /* i : input sampling frequency */ + const Word32 bitrate, /* i : requested bitrate of the output bitstream */ const bool max_bwidth_user, /* i : shows if bandwidth limitation was set by the user (true) or if default bandwidth was used (false) */ const IVAS_ENC_BANDWIDTH maxBandwidth, /* i : bandwidth limitation */ const IVAS_ENC_DTX_CONFIG dtxConfig, /* i : configuration of DTX, can by set to default by using IVAS_ENC_GetDefaultDtxConfig() */ @@ -842,8 +840,8 @@ ivas_error IVAS_ENC_ConfigureForMultichannel( static ivas_error configureEncoder( IVAS_ENC_HANDLE hIvasEnc, - const int32_t inputFs, - const int32_t initBitrate, + const Word32 inputFs, + const Word32 initBitrate, const IVAS_ENC_BANDWIDTH initBandwidth, const IVAS_ENC_DTX_CONFIG dtxConfig, const IVAS_ENC_CHANNEL_AWARE_CONFIG caConfig ) @@ -851,7 +849,7 @@ static ivas_error configureEncoder( Encoder_Struct *st_ivas; ENCODER_CONFIG_HANDLE hEncoderConfig; ivas_error error; - int32_t cpe_brate; + Word32 cpe_brate; error = IVAS_ERR_OK; @@ -1095,7 +1093,11 @@ static ivas_error configureEncoder( } +#ifdef NONBE_FIX_708_OSBA_BR_SWITCHING_CRASH + if ( hEncoderConfig->Opt_PCA_ON && !( ( hEncoderConfig->ivas_format == SBA_FORMAT || hEncoderConfig->ivas_format == SBA_ISM_FORMAT ) && hEncoderConfig->ivas_total_brate == PCA_BRATE && hEncoderConfig->sba_order == SBA_FOA_ORDER ) ) +#else if ( hEncoderConfig->Opt_PCA_ON && !( hEncoderConfig->ivas_format == SBA_FORMAT && hEncoderConfig->ivas_total_brate == PCA_BRATE && hEncoderConfig->sba_order == SBA_FOA_ORDER ) ) +#endif { return IVAS_ERROR( IVAS_ERR_NOT_SUPPORTED_OPTION, "PCA supported at SBA FOA 256 kbps only." ); } @@ -1406,9 +1408,6 @@ static ivas_error configureEncoder_fx( IF( EQ_16( hEncoderConfig->ivas_format, MONO_FORMAT ) ) { hIvasEnc->hCoreCoder = st_ivas->hSCE[0]->hCoreCoder[0]; /* Note: this is needed for switching in EVS mono */ - //#ifndef EVS_FLOAT_ENC - // hIvasEnc->hCoreCoder_fx = st_ivas->hSCE[0]->hCoreCoder_fx[0]; - //#endif } ELSE { @@ -1447,8 +1446,13 @@ ivas_error IVAS_ENC_GetDelay( return IVAS_ERR_UNEXPECTED_NULL_POINTER; } - *delay = NS2SA( hEncoderConfig->input_Fs, get_delay_fx( ENC, hEncoderConfig->input_Fs, hEncoderConfig->ivas_format, NULL ) ); +#ifdef SPLIT_REND_WITH_HEAD_ROT + *delay = NS2SA_FX2( hEncoderConfig->input_Fs, get_delay_fx( ENC, hEncoderConfig->input_Fs, hEncoderConfig->ivas_format, NULL, IVAS_AUDIO_CONFIG_INVALID ) ); move16(); +#else + *delay = NS2SA_FX2( hEncoderConfig->input_Fs, get_delay_fx( ENC, hEncoderConfig->input_Fs, hEncoderConfig->ivas_format, NULL ) ); + move16(); +#endif *delay = imult1616( *delay, hEncoderConfig->nchan_inp ); move16(); @@ -1476,7 +1480,7 @@ static Word16 getInputBufferSize_fx( *---------------------------------------------------------------------*/ ivas_error IVAS_ENC_GetNumInChannels( const IVAS_ENC_HANDLE hIvasEnc, /* i/o: IVAS encoder handle */ - int16_t *numInChannels /* o : total number of samples expected in the input buffer for current encoder configuration */ + Word16 *numInChannels /* o : total number of samples expected in the input buffer for current encoder configuration */ ) { if ( hIvasEnc == NULL || numInChannels == NULL ) @@ -1749,6 +1753,9 @@ ivas_error IVAS_ENC_EncodeFrameToSerial( } ELSE { +#ifdef DEBUG_MODE_INFO + dbgwrite( inputBuffer, sizeof( int16_t ), inputBufferSize, 1, strcat( fname( debug_dir, "ivas_input_dmx", 0, 1, ENC ), ".pcm" ) ); +#endif hCoreCoder->input_frame_fx = inputBufferSize; move32(); IF( NE_32( ( error = evs_enc_fx( hCoreCoder, inputBuffer, hCoreCoder->mem_hp20_in_fx, inputBufferSize ) ), IVAS_ERR_OK ) ) @@ -1821,8 +1828,8 @@ ivas_error IVAS_ENC_SetBandwidth( *---------------------------------------------------------------------*/ ivas_error IVAS_ENC_SetBitrate( - IVAS_ENC_HANDLE hIvasEnc, /* i/o: IVAS encoder handle */ - const int32_t totalBitrate /* i : requested bitrate of the output bitstream */ + IVAS_ENC_HANDLE hIvasEnc, /* i/o: IVAS encoder handle */ + const Word32 totalBitrate /* i : requested bitrate of the output bitstream */ ) { ivas_error error; @@ -1872,6 +1879,10 @@ ivas_error IVAS_ENC_SetChannelAwareConfig( ivas_error IVAS_ENC_SetForcedMode( IVAS_ENC_HANDLE hIvasEnc, /* i/o: IVAS encoder handle */ const IVAS_ENC_FORCED_MODE forcedMode /* i : forced coding mode */ +#ifdef DEBUG_FORCE_DIR + , + const char *forcedModeDir /* i : directory containing external binary files for modes/parameters enforcement */ +#endif ) { int16_t newForced; @@ -1883,6 +1894,27 @@ ivas_error IVAS_ENC_SetForcedMode( return error; } +#ifdef DEBUG_FORCE_DIR + hIvasEnc->st_ivas->hEncoderConfig->force_dir[0] = '\0'; + if ( forcedMode < IVAS_ENC_FORCE_FILE ) + { + if ( ( error = forcedModeApiToInternal( forcedMode, &newForced ) ) != IVAS_ERR_OK ) + { + return error; + } + + if ( hIvasEnc->st_ivas->hEncoderConfig->force != newForced ) + { + hIvasEnc->st_ivas->hEncoderConfig->force = newForced; + hIvasEnc->switchingActive = true; + } + } + else if ( forcedMode == IVAS_ENC_FORCE_DIR ) + { + strcpy( hIvasEnc->st_ivas->hEncoderConfig->force_dir, forcedModeDir ); + hIvasEnc->st_ivas->hEncoderConfig->force = IVAS_ENC_FORCE_UNFORCED; + } +#else if ( ( error = forcedModeApiToInternal( forcedMode, &newForced ) ) != IVAS_ERR_OK ) { return error; @@ -1893,6 +1925,7 @@ ivas_error IVAS_ENC_SetForcedMode( hIvasEnc->st_ivas->hEncoderConfig->force = newForced; hIvasEnc->switchingActive = true; } +#endif return IVAS_ERR_OK; } @@ -1974,11 +2007,11 @@ const char *IVAS_ENC_GetErrorMessage( static ivas_error printConfigInfo_enc( IVAS_ENC_HANDLE hIvasEnc, - const int16_t channelAwareModeEnabled ) + const Word16 channelAwareModeEnabled ) { Encoder_Struct *st_ivas; ENCODER_CONFIG_HANDLE hEncoderConfig; - int16_t newBandwidthApi; + Word16 newBandwidthApi; ivas_error error; st_ivas = hIvasEnc->st_ivas; @@ -2208,7 +2241,7 @@ static ivas_error printConfigInfo_enc( static ivas_error setBitrate( IVAS_ENC_HANDLE hIvasEnc, - const int32_t totalBitrate ) + const Word32 totalBitrate ) { Encoder_Struct *st_ivas; ENCODER_CONFIG_HANDLE hEncoderConfig; @@ -2690,9 +2723,18 @@ static ivas_error forcedModeApiToInternal( case IVAS_ENC_FORCE_GSC: *forcedModeInternal = FORCE_GSC; break; +#ifdef SUPPORT_FORCE_TCX10_TCX20 + case IVAS_ENC_FORCE_TCX10: + *forcedModeInternal = FORCE_TCX10; + break; + case IVAS_ENC_FORCE_TCX20: + *forcedModeInternal = FORCE_TCX20; + break; +#else case IVAS_ENC_FORCE_TCX: *forcedModeInternal = FORCE_TCX; break; +#endif case IVAS_ENC_FORCE_HQ: *forcedModeInternal = FORCE_HQ; break; @@ -2715,8 +2757,8 @@ static ivas_error forcedModeApiToInternal( *---------------------------------------------------------------------*/ ivas_error IVAS_ENC_PrintConfig( - const IVAS_ENC_HANDLE hIvasEnc, /* i : IVAS encoder handle */ - const int16_t channelAwareModeEnabled /* i : channel-aware mode enabled flag */ + const IVAS_ENC_HANDLE hIvasEnc, /* i : IVAS encoder handle */ + const Word16 channelAwareModeEnabled /* i : channel-aware mode enabled flag */ ) { return printConfigInfo_enc( hIvasEnc, channelAwareModeEnabled ); diff --git a/lib_enc/lib_enc.h b/lib_enc/lib_enc.h index 1fd4e0ad06cc523f1125b52761a5fa8ac4ca3894..ab6c39c23c4da9b2ca62da54e672eaf5dbc61607 100644 --- a/lib_enc/lib_enc.h +++ b/lib_enc/lib_enc.h @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other @@ -68,7 +68,7 @@ typedef struct _IVAS_ENC_DTX_CONFIG { bool enabled; bool variable_SID_rate; - int16_t SID_interval; + Word16 SID_interval; } IVAS_ENC_DTX_CONFIG; typedef enum _IVAS_ENC_SBA_ORDER @@ -127,8 +127,17 @@ typedef enum _IVAS_ENC_FORCED_MODE IVAS_ENC_FORCE_MUSIC, IVAS_ENC_FORCE_ACELP, IVAS_ENC_FORCE_GSC, +#ifdef SUPPORT_FORCE_TCX10_TCX20 + IVAS_ENC_FORCE_TCX10, + IVAS_ENC_FORCE_TCX20, +#else IVAS_ENC_FORCE_TCX, +#endif IVAS_ENC_FORCE_HQ, +#ifdef DEBUG_FORCE_DIR + IVAS_ENC_FORCE_FILE, + IVAS_ENC_FORCE_DIR, +#endif IVAS_ENC_FORCE_UNFORCED, IVAS_ENC_FORCE_UNDEFINED = 0xffff } IVAS_ENC_FORCED_MODE; @@ -160,8 +169,8 @@ ivas_error IVAS_ENC_Open_fx( /*! r: error code */ ivas_error IVAS_ENC_ConfigureForMono( IVAS_ENC_HANDLE hIvasEnc, /* i/o: IVAS encoder handle */ - const int32_t inputFs, /* i : input sampling frequency */ - const int32_t bitrate, /* i : requested bitrate of the output bitstream */ + const Word32 inputFs, /* i : input sampling frequency */ + const Word32 bitrate, /* i : requested bitrate of the output bitstream */ const bool max_bwidth_user, /* i : shows if bandwidth limitation was set by the user (true) or if default bandwidth was used (false) */ const IVAS_ENC_BANDWIDTH maxBandwidth, /* i : bandwidth limitation */ const IVAS_ENC_DTX_CONFIG dtxConfig, /* i : configuration of DTX, can by set to default by using IVAS_ENC_GetDefaultDtxConfig() */ @@ -173,8 +182,8 @@ ivas_error IVAS_ENC_ConfigureForMono( /*! r: error code */ ivas_error IVAS_ENC_ConfigureForStereo( IVAS_ENC_HANDLE hIvasEnc, /* i/o: IVAS encoder handle */ - const int32_t inputFs, /* i : input sampling frequency */ - const int32_t bitrate, /* i : requested bitrate of the output bitstream */ + const Word32 inputFs, /* i : input sampling frequency */ + const Word32 bitrate, /* i : requested bitrate of the output bitstream */ const bool max_bwidth_user, /* i : shows if bandwidth limitation was set by the user (true) or if default bandwidth was used (false) */ const IVAS_ENC_BANDWIDTH maxBandwidth, /* i : bandwidth limitation */ const IVAS_ENC_DTX_CONFIG dtxConfig, /* i : configuration of DTX, can by set to default by using IVAS_ENC_GetDefaultDtxConfig() */ @@ -188,34 +197,34 @@ ivas_error IVAS_ENC_ConfigureForStereo( /*! r: error code */ ivas_error IVAS_ENC_ConfigureForObjects( IVAS_ENC_HANDLE hIvasEnc, /* i/o: IVAS encoder handle */ - const int32_t inputFs, /* i : input sampling frequency */ - const int32_t bitrate, /* i : requested bitrate of the output bitstream */ + const Word32 inputFs, /* i : input sampling frequency */ + const Word32 bitrate, /* i : requested bitrate of the output bitstream */ const bool max_bwidth_user, /* i : shows if bandwidth limitation was set by the user (true) or if default bandwidth was used (false) */ const IVAS_ENC_BANDWIDTH maxBandwidth, /* i : bandwidth limitation */ const IVAS_ENC_DTX_CONFIG dtxConfig, /* i : configuration of DTX, can by set to default by using IVAS_ENC_GetDefaultDtxConfig() */ - const uint16_t numObjects, /* i : number of objects to be encoded */ + const UWord16 numObjects, /* i : number of objects to be encoded */ const bool ism_extended_metadata /* i : Extended metadata used (true/false), where extended metadata includes radius and orientation */ ); /*! r: encoder error code */ ivas_error IVAS_ENC_ConfigureForMASAObjects( IVAS_ENC_HANDLE hIvasEnc, /* i/o: IVAS encoder handle */ - const int32_t inputFs, /* i : input sampling frequency */ - const int32_t bitrate, /* i : requested bitrate of the ouput bitstream */ + const Word32 inputFs, /* i : input sampling frequency */ + const Word32 bitrate, /* i : requested bitrate of the ouput bitstream */ const IVAS_ENC_BANDWIDTH maxBandwidth, /* i : bandwidth limitation */ const IVAS_ENC_DTX_CONFIG dtxConfig, /* i : configuration of DTX, can by set to default by using IVAS_ENC_GetDefaultDtxConfig() */ - const uint16_t numObjects, /* i : number of objects to be encoded */ - const int16_t masaVariant /* i : index specifying the number of MASA transport channels */ + const UWord16 numObjects, /* i : number of objects to be encoded */ + const Word16 masaVariant /* i : index specifying the number of MASA transport channels */ ); /*! r: encoder error code */ ivas_error IVAS_ENC_ConfigureForSBAObjects( IVAS_ENC_HANDLE hIvasEnc, /* i/o: IVAS encoder handle */ - const int32_t inputFs, /* i : input sampling frequency */ - const int32_t bitrate, /* i : requested bitrate of the ouput bitstream */ + const Word32 inputFs, /* i : input sampling frequency */ + const Word32 bitrate, /* i : requested bitrate of the ouput bitstream */ const IVAS_ENC_BANDWIDTH maxBandwidth, /* i : bandwidth limitation */ const IVAS_ENC_DTX_CONFIG dtxConfig, /* i : configuration of DTX, can by set to default by using IVAS_ENC_GetDefaultDtxConfig() */ - const uint16_t numObjects, /* i : number of objects to be encoded */ + const UWord16 numObjects, /* i : number of objects to be encoded */ const IVAS_ENC_SBA_ORDER order, /* i : order of the Ambisonics input */ const bool isPlanar, /* i : if true, input is treated as planar Ambisonics */ const bool Opt_PCA_ON /* i : PCA option flag */ @@ -224,8 +233,8 @@ ivas_error IVAS_ENC_ConfigureForSBAObjects( /*! r: error code */ ivas_error IVAS_ENC_ConfigureForAmbisonics( IVAS_ENC_HANDLE hIvasEnc, /* i/o: IVAS encoder handle */ - const int32_t inputFs, /* i : input sampling frequency */ - const int32_t bitrate, /* i : requested bitrate of the output bitstream */ + const Word32 inputFs, /* i : input sampling frequency */ + const Word32 bitrate, /* i : requested bitrate of the output bitstream */ const bool max_bwidth_user, /* i : shows if bandwidth limitation was set by the user (true) or if default bandwidth was used (false) */ const IVAS_ENC_BANDWIDTH maxBandwidth, /* i : bandwidth limitation */ const IVAS_ENC_DTX_CONFIG dtxConfig, /* i : configuration of DTX, can by set to default by using IVAS_ENC_GetDefaultDtxConfig() */ @@ -236,8 +245,8 @@ ivas_error IVAS_ENC_ConfigureForAmbisonics( ivas_error IVAS_ENC_ConfigureForAmbisonics_fx( IVAS_ENC_HANDLE hIvasEnc, /* i/o: IVAS encoder handle */ - const int32_t inputFs, /* i : input sampling frequency */ - const int32_t bitrate, /* i : requested bitrate of the output bitstream */ + const Word32 inputFs, /* i : input sampling frequency */ + const Word32 bitrate, /* i : requested bitrate of the output bitstream */ const bool max_bwidth_user, /* i : shows if bandwidth limitation was set by the user (true) or if default bandwidth was used (false) */ const IVAS_ENC_BANDWIDTH maxBandwidth, /* i : bandwidth limitation */ const IVAS_ENC_DTX_CONFIG dtxConfig, /* i : configuration of DTX, can by set to default by using IVAS_ENC_GetDefaultDtxConfig() */ @@ -248,8 +257,8 @@ ivas_error IVAS_ENC_ConfigureForAmbisonics_fx( /*! r: error code */ ivas_error IVAS_ENC_ConfigureForMasa( IVAS_ENC_HANDLE hIvasEnc, /* i/o: IVAS encoder handle */ - const int32_t inputFs, /* i : input sampling frequency */ - const int32_t bitrate, /* i : requested bitrate of the output bitstream */ + const Word32 inputFs, /* i : input sampling frequency */ + const Word32 bitrate, /* i : requested bitrate of the output bitstream */ const bool max_bwidth_user, /* i : shows if bandwidth limitation was set by the user (true) or if default bandwidth was used (false) */ const IVAS_ENC_BANDWIDTH maxBandwidth, /* i : bandwidth limitation */ const IVAS_ENC_DTX_CONFIG dtxConfig, /* i : configuration of DTX, can by set to default by using IVAS_ENC_GetDefaultDtxConfig() */ @@ -259,8 +268,8 @@ ivas_error IVAS_ENC_ConfigureForMasa( /*! r: encoder error code */ ivas_error IVAS_ENC_ConfigureForMultichannel( IVAS_ENC_HANDLE hIvasEnc, /* i/o: IVAS encoder handle */ - const int32_t inputFs, /* i : input sampling frequency */ - const int32_t bitrate, /* i : requested bitrate of the output bitstream */ + const Word32 inputFs, /* i : input sampling frequency */ + const Word32 bitrate, /* i : requested bitrate of the output bitstream */ const bool max_bwidth_user, /* i : shows if bandwidth limitation was set by the user (true) or if default bandwidth was used (false) */ const IVAS_ENC_BANDWIDTH maxBandwidth, /* i : bandwidth limitation */ const IVAS_ENC_DTX_CONFIG dtxConfig, /* i : configuration of DTX, can by set to default by using IVAS_ENC_GetDefaultDtxConfig() */ @@ -276,7 +285,7 @@ void IVAS_ENC_Close( /*! r: error code */ ivas_error IVAS_ENC_FeedObjectMetadata( IVAS_ENC_HANDLE hIvasEnc, /* i/o: IVAS encoder handle */ - const uint16_t ismIndex, /* i : object index */ + const UWord16 ismIndex, /* i : object index */ const IVAS_ISM_METADATA metadata /* i : object metadata handle for current frame */ ); @@ -298,10 +307,10 @@ ivas_error IVAS_ENC_EncodeFrameToSerial( /*! r: error code */ ivas_error IVAS_ENC_EncodeFrameToCompact( IVAS_ENC_HANDLE hIvasEnc, /* i/o: IVAS encoder handle */ - int16_t *inputBuffer, /* i : PCM input */ - const int16_t inputBufferSize, /* i : total number of samples in the input buffer. Related function: IVAS_ENC_GetInputBufferSize() */ - uint8_t *outputBitStream, /* o : pointer to compact output bitstream. The array must already be allocated. */ - uint16_t *numOutBits /* o : number of bits written to output bitstream */ + Word16 *inputBuffer, /* i : PCM input */ + const Word16 inputBufferSize, /* i : total number of samples in the input buffer. Related function: IVAS_ENC_GetInputBufferSize() */ + UWord8 *outputBitStream, /* o : pointer to compact output bitstream. The array must already be allocated. */ + UWord16 *numOutBits /* o : number of bits written to output bitstream */ ); /* Setter functions - apply changes to encoder configuration */ @@ -315,7 +324,7 @@ ivas_error IVAS_ENC_SetBandwidth( /*! r: error code */ ivas_error IVAS_ENC_SetBitrate( IVAS_ENC_HANDLE hIvasEnc, /* i/o: IVAS encoder handle */ - const int32_t totalBitrate /* i : requested bitrate of the output bitstream */ + const Word32 totalBitrate /* i : requested bitrate of the output bitstream */ ); /*! r: error code */ @@ -329,6 +338,9 @@ ivas_error IVAS_ENC_SetChannelAwareConfig( ivas_error IVAS_ENC_SetForcedMode( IVAS_ENC_HANDLE hIvasEnc, /* i/o: IVAS encoder handle */ const IVAS_ENC_FORCED_MODE forcedMode /* i : forced coding mode */ +#ifdef DEBUG_FORCE_DIR + ,const char *forcedModeDir /* i : directory containing external binary files for modes/parameters enforcement */ +#endif ); #endif @@ -343,13 +355,13 @@ ivas_error IVAS_ENC_GetDelay( /*! r: encoder error code */ ivas_error IVAS_ENC_GetNumInChannels( const IVAS_ENC_HANDLE hIvasEnc, /* i/o: IVAS encoder handle */ - int16_t *numInChannels /* o : total number of samples expected in the input buffer for current encoder configuration */ + Word16 *numInChannels /* o : total number of samples expected in the input buffer for current encoder configuration */ ); /*! r: encoder error code */ ivas_error IVAS_ENC_GetInputBufferSize( const IVAS_ENC_HANDLE hIvasEnc, /* i/o: IVAS encoder handle */ - int16_t *inputBufferSize /* o : total number of samples expected in the input buffer for current encoder configuration */ + Word16 *inputBufferSize /* o : total number of samples expected in the input buffer for current encoder configuration */ ); /* Utility functions */ @@ -376,7 +388,7 @@ const char *IVAS_ENC_GetErrorMessage( ivas_error IVAS_ENC_PrintConfig( const IVAS_ENC_HANDLE hIvasEnc, /* i : IVAS encoder handle */ - const int16_t channelAwareModeEnabled /* i : channel-aware mode enabled flag */ + const Word16 channelAwareModeEnabled /* i : channel-aware mode enabled flag */ ); void IVAS_ENC_PrintDisclaimer( diff --git a/lib_enc/long_enr.c b/lib_enc/long_enr.c deleted file mode 100644 index aba21a1fe9a92c5eaab5064451c9a0d56b24dd33..0000000000000000000000000000000000000000 --- a/lib_enc/long_enr.c +++ /dev/null @@ -1,47 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include "cnst.h" -#include "prot.h" -#include "wmc_auto.h" - -/*-------------------------------------------------------------------* - * long_enr() - * - * Compute relative energy, long-term average total noise energy and total active speech energy - *-------------------------------------------------------------------*/ diff --git a/lib_enc/long_enr_fx.c b/lib_enc/long_enr_fx.c index 0916b2b09c9e59e65e5c00d4012d29f0c220f90a..5fe465f2946e037b8f2b92f9f2741c2c0432c308 100644 --- a/lib_enc/long_enr_fx.c +++ b/lib_enc/long_enr_fx.c @@ -150,18 +150,13 @@ void ivas_long_enr_fx( *-----------------------------------------------------------------*/ return; } + + void long_enr_fx( Encoder_State *st_fx, /* i/o: state structure */ const Word16 Etot, /* i : total channel E (see lib_enc\analy_sp.c) */ const Word16 localVAD_HE_SAD, /* i : HE-SAD flag without hangover */ Word16 high_lpn_flag /* i : sp/mus LPN flag */ -#ifdef IVAS_CODE - , - FRONT_VAD_ENC_HANDLE hFrontVad[CPE_CHANNELS], /* i/o: front-VAD handles */ - const int16_t n_chan, /* i : number of channels */ - const int16_t localVAD_HE_SAD_LR[CPE_CHANNELS], /* i : HE-SAD flag without hangover LR channels */ - const float Etot_LR[CPE_CHANNELS] /* i : total channel energy LR channels */ -#endif ) { Word16 tmp; @@ -172,58 +167,7 @@ void long_enr_fx( * Compute long term estimate of total noise energy * and total active speech energy *-----------------------------------------------------------------*/ -#ifdef IVAS_CODE - Word16 n; - if ( hFrontVad != NULL ) - { - if ( hFrontVad[0]->ini_frame < 4 ) - { - for ( n = 0; n < n_chan; n++ ) - { - hFrontVad[n]->lp_noise = hFrontVad[n]->hNoiseEst->totalNoise; - tmp = hFrontVad[n]->lp_noise + 10.0f; - - if ( hFrontVad[n]->lp_speech < tmp ) - { - hFrontVad[n]->lp_speech = tmp; - } - } - } - else - { - float smooth_prev, smooth_curr; - - if ( hFrontVad[0]->ini_frame < 150 ) - { - smooth_prev = 0.95f; - smooth_curr = 0.05f; - } - else - { - smooth_prev = 0.98f; - smooth_curr = 0.02f; - } - for ( n = 0; n < n_chan; n++ ) - { - hFrontVad[n]->lp_noise = smooth_prev * hFrontVad[n]->lp_noise + smooth_curr * hFrontVad[n]->hNoiseEst->totalNoise; - - if ( localVAD_HE_SAD_LR[n] && !high_lpn_flag ) - { - if ( ( hFrontVad[n]->lp_speech - Etot_LR[n] ) < 10.0f ) - { - hFrontVad[n]->lp_speech = 0.98f * hFrontVad[n]->lp_speech + 0.02f * Etot_LR[n]; - } - else - { - hFrontVad[n]->lp_speech = hFrontVad[n]->lp_speech - 0.05f; - } - } - } - } - } - else -#endif { IF( LT_16( st_fx->ini_frame, 4 ) ) { diff --git a/lib_enc/lp_exc_e.c b/lib_enc/lp_exc_e.c deleted file mode 100644 index 7d23dd6f703552ed5f1af9f2941cf4dee9763f27..0000000000000000000000000000000000000000 --- a/lib_enc/lp_exc_e.c +++ /dev/null @@ -1,42 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include -#include "cnst.h" -#include "prot.h" -#include "wmc_auto.h" diff --git a/lib_enc/lp_exc_e_fx.c b/lib_enc/lp_exc_e_fx.c index 8b9cb113e98d08f0eafbf693ab39722cc3d25917..01005f6419fac1fdfb8a1c1dad6f30bdb96f60e1 100644 --- a/lib_enc/lp_exc_e_fx.c +++ b/lib_enc/lp_exc_e_fx.c @@ -53,7 +53,8 @@ Word16 lp_filt_exc_enc_fx( Word16 wtmp, wtmp1; Word32 Ltmp; - Word16 use_prev_sf_pit_gain = 0; + Word16 use_prev_sf_pit_gain = 0; // Q0 + move16(); gain1 = 0; move16(); @@ -66,7 +67,8 @@ Word16 lp_filt_exc_enc_fx( test(); IF( EQ_16( codec_mode, MODE2 ) && EQ_16( coder_type, 100 ) ) { - use_prev_sf_pit_gain = 1; + use_prev_sf_pit_gain = 1; // Q0 + move16(); } exp_ener = 0; move16(); @@ -75,7 +77,7 @@ Word16 lp_filt_exc_enc_fx( test(); IF( EQ_16( *lp_flag, FULL_BAND ) || EQ_16( *lp_flag, NORMAL_OPERATION ) ) { - wtmp = adpt_enr_fx( codec_mode, &exc[i_subfr], h1, y1, L_subfr, &gain1, g_corr, clip_gain, xn, xn2, &exp_ener, use_prev_sf_pit_gain ); + wtmp = adpt_enr_fx( codec_mode, &exc[i_subfr], h1, y1, L_subfr, &gain1, g_corr, clip_gain, xn, xn2, &exp_ener, use_prev_sf_pit_gain ); // exp_ener move16(); } @@ -89,7 +91,7 @@ Word16 lp_filt_exc_enc_fx( wtmp1 = 0; move16(); test(); - IF( ( EQ_16( *lp_flag, LOW_PASS ) ) || ( EQ_16( *lp_flag, NORMAL_OPERATION ) ) ) + IF( ( ( *lp_flag == LOW_PASS ) ) || ( EQ_16( *lp_flag, NORMAL_OPERATION ) ) ) { test(); IF( EQ_16( codec_mode, MODE2 ) && EQ_16( L_frame, L_FRAME16k ) ) @@ -100,6 +102,7 @@ Word16 lp_filt_exc_enc_fx( Ltmp = L_mac( Ltmp, 19005, exc[i + i_subfr] ); Ltmp = L_mac( Ltmp, 6881, exc[i + 1 + i_subfr] ); exc_tmp[i] = round_fx( Ltmp ); + move16(); } } ELSE @@ -110,20 +113,21 @@ Word16 lp_filt_exc_enc_fx( Ltmp = L_mac( Ltmp, 20972, exc[i + i_subfr] ); Ltmp = L_mac( Ltmp, 5898, exc[i + 1 + i_subfr] ); exc_tmp[i] = round_fx( Ltmp ); + move16(); } } - wtmp1 = adpt_enr_fx( codec_mode, exc_tmp, h1, y1_tmp, L_subfr, &gain2, g_corr2, clip_gain, xn, xn2_tmp, &exp_ener1, use_prev_sf_pit_gain ); + wtmp1 = adpt_enr_fx( codec_mode, exc_tmp, h1, y1_tmp, L_subfr, &gain2, g_corr2, clip_gain, xn, xn2_tmp, &exp_ener1, use_prev_sf_pit_gain ); // exp_ener1 } if ( LT_16( exp_ener, exp_ener1 ) ) { - wtmp = shr( wtmp, 1 ); + wtmp = shr( wtmp, 1 ); // exp_ener + 1 } if ( GT_16( exp_ener, exp_ener1 ) ) { - wtmp1 = shr( wtmp1, 1 ); + wtmp1 = shr( wtmp1, 1 ); // exp_ener1 + 1 } /*-----------------------------------------------------------------* @@ -132,18 +136,18 @@ Word16 lp_filt_exc_enc_fx( test(); test(); - IF( ( ( LT_16( wtmp1, wtmp ) ) && ( EQ_16( *lp_flag, NORMAL_OPERATION ) ) ) || ( EQ_16( *lp_flag, LOW_PASS ) ) ) + IF( ( ( LT_16( wtmp1, wtmp ) ) && ( EQ_16( *lp_flag, NORMAL_OPERATION ) ) ) || ( ( *lp_flag == LOW_PASS ) ) ) { /* use the LP filter for pitch excitation prediction */ select = LOW_PASS; move16(); - Copy( exc_tmp, &exc[i_subfr], L_subfr ); - Copy( y1_tmp, y1, L_subfr ); - Copy( xn2_tmp, xn2, L_subfr ); + Copy( exc_tmp, &exc[i_subfr], L_subfr ); // Q_new + Copy( y1_tmp, y1, L_subfr ); // Q_new-1+shift + Copy( xn2_tmp, xn2, L_subfr ); // Q_new-1+shift IF( use_prev_sf_pit_gain == 0 ) { - *gain_pit = gain2; + *gain_pit = gain2; // Q14 move16(); g_corr[0] = g_corr2[0]; move16(); @@ -162,7 +166,7 @@ Word16 lp_filt_exc_enc_fx( move16(); IF( use_prev_sf_pit_gain == 0 ) { - *gain_pit = gain1; + *gain_pit = gain1; // Q14 move16(); } } @@ -175,7 +179,7 @@ Word16 lp_filt_exc_enc_ivas_fx( const Word16 coder_type, /* i : coding type Q0 */ const Word16 i_subfr, /* i : subframe index Q0 */ Word16 *exc, /* i/o: pointer to excitation signal frame Q_new */ - const Word16 *h1, /* i : weighted filter input response Q(14+shift) */ + const Word16 *h1, /* i : weighted filter input response Q(15) */ const Word16 *xn, /* i : target vector Q_new-1+shift */ Word16 *y1, /* o : zero-memory filtered adaptive excitation Q_new-1+shift */ Word16 *xn2, /* o : target vector for innovation search Q_new-1+shift */ @@ -193,7 +197,8 @@ Word16 lp_filt_exc_enc_ivas_fx( Word16 wtmp, wtmp1; Word32 Ltmp; - Word16 use_prev_sf_pit_gain = 0; + Word16 use_prev_sf_pit_gain = 0; // Q0 + move16(); gain1 = 0; move16(); @@ -206,7 +211,8 @@ Word16 lp_filt_exc_enc_ivas_fx( test(); IF( EQ_16( codec_mode, MODE2 ) && EQ_16( coder_type, 100 ) ) { - use_prev_sf_pit_gain = 1; + use_prev_sf_pit_gain = 1; // Q0 + move16(); } exp_ener = 0; move16(); @@ -215,13 +221,13 @@ Word16 lp_filt_exc_enc_ivas_fx( test(); IF( EQ_16( *lp_flag, FULL_BAND ) || EQ_16( *lp_flag, NORMAL_OPERATION ) ) { - IF( use_prev_sf_pit_gain == 1 ) + IF( EQ_16( use_prev_sf_pit_gain, 1 ) ) { - wtmp = adpt_enr_fx( codec_mode, &exc[i_subfr], h1, y1, L_subfr, gain_pit, g_corr, clip_gain, xn, xn2, &exp_ener, use_prev_sf_pit_gain ); + wtmp = adpt_enr_fx( codec_mode, &exc[i_subfr], h1, y1, L_subfr, gain_pit, g_corr, clip_gain, xn, xn2, &exp_ener, use_prev_sf_pit_gain ); // exp_ener } - else + ELSE { - wtmp = adpt_enr_fx( codec_mode, &exc[i_subfr], h1, y1, L_subfr, &gain1, g_corr, clip_gain, xn, xn2, &exp_ener, use_prev_sf_pit_gain ); + wtmp = adpt_enr_fx( codec_mode, &exc[i_subfr], h1, y1, L_subfr, &gain1, g_corr, clip_gain, xn, xn2, &exp_ener, use_prev_sf_pit_gain ); // exp_ener } } @@ -235,7 +241,7 @@ Word16 lp_filt_exc_enc_ivas_fx( wtmp1 = 0; move16(); test(); - IF( ( EQ_16( *lp_flag, LOW_PASS ) ) || ( EQ_16( *lp_flag, NORMAL_OPERATION ) ) ) + IF( ( ( *lp_flag == LOW_PASS ) ) || ( EQ_16( *lp_flag, NORMAL_OPERATION ) ) ) { test(); IF( EQ_16( codec_mode, MODE2 ) && EQ_16( L_frame, L_FRAME16k ) ) @@ -246,6 +252,7 @@ Word16 lp_filt_exc_enc_ivas_fx( Ltmp = L_mac( Ltmp, 19005, exc[i + i_subfr] ); Ltmp = L_mac( Ltmp, 6881, exc[i + 1 + i_subfr] ); exc_tmp[i] = round_fx( Ltmp ); + move16(); } } ELSE @@ -256,15 +263,16 @@ Word16 lp_filt_exc_enc_ivas_fx( Ltmp = L_mac( Ltmp, 20972, exc[i + i_subfr] ); Ltmp = L_mac( Ltmp, 5898, exc[i + 1 + i_subfr] ); exc_tmp[i] = round_fx( Ltmp ); + move16(); } } - IF( use_prev_sf_pit_gain == 1 ) + IF( EQ_16( use_prev_sf_pit_gain, 1 ) ) { - wtmp1 = adpt_enr_fx( codec_mode, exc_tmp, h1, y1_tmp, L_subfr, &gain2, gain_pit, clip_gain, xn, xn2_tmp, &exp_ener1, use_prev_sf_pit_gain ); + wtmp1 = adpt_enr_fx( codec_mode, exc_tmp, h1, y1_tmp, L_subfr, gain_pit, g_corr2, clip_gain, xn, xn2_tmp, &exp_ener1, use_prev_sf_pit_gain ); // exp_ener1 } ELSE { - wtmp1 = adpt_enr_fx( codec_mode, exc_tmp, h1, y1_tmp, L_subfr, &gain2, g_corr2, clip_gain, xn, xn2_tmp, &exp_ener1, use_prev_sf_pit_gain ); + wtmp1 = adpt_enr_fx( codec_mode, exc_tmp, h1, y1_tmp, L_subfr, &gain2, g_corr2, clip_gain, xn, xn2_tmp, &exp_ener1, use_prev_sf_pit_gain ); // exp_ener1 } } @@ -284,18 +292,18 @@ Word16 lp_filt_exc_enc_ivas_fx( test(); test(); - IF( ( ( LT_16( wtmp1, wtmp ) ) && ( EQ_16( *lp_flag, NORMAL_OPERATION ) ) ) || ( EQ_16( *lp_flag, LOW_PASS ) ) ) + IF( ( ( LT_16( wtmp1, wtmp ) ) && ( EQ_16( *lp_flag, NORMAL_OPERATION ) ) ) || ( ( *lp_flag == LOW_PASS ) ) ) { /* use the LP filter for pitch excitation prediction */ select = LOW_PASS; move16(); - Copy( exc_tmp, &exc[i_subfr], L_subfr ); - Copy( y1_tmp, y1, L_subfr ); - Copy( xn2_tmp, xn2, L_subfr ); + Copy( exc_tmp, &exc[i_subfr], L_subfr ); // Q_new + Copy( y1_tmp, y1, L_subfr ); // Q_new-1+shift + Copy( xn2_tmp, xn2, L_subfr ); // Q_new-1+shift IF( use_prev_sf_pit_gain == 0 ) { - *gain_pit = gain2; + *gain_pit = gain2; // Q14 move16(); g_corr[0] = g_corr2[0]; move16(); @@ -314,7 +322,7 @@ Word16 lp_filt_exc_enc_ivas_fx( move16(); IF( use_prev_sf_pit_gain == 0 ) { - *gain_pit = gain1; + *gain_pit = gain1; // Q14 move16(); } } @@ -354,18 +362,12 @@ static Word16 adpt_enr_fx( /* o : adaptive excitation Overflow = 0; move16(); -#ifdef BASOP_NOGLOB /* Critical Overflow */ Overflow = -#endif conv_fx( exc, h1, y1, L_subfr ); IF( use_prev_sf_pit_gain == 0 ) { -#ifdef BASOP_NOGLOB /* Critical Overflow */ *gain = corr_xy1_fx( xn, y1, g_corr, L_subfr, codec_mode == MODE2, &Overflow ); -#else - *gain = corr_xy1_fx( xn, y1, g_corr, L_subfr, codec_mode == MODE2 ); -#endif move16(); test(); @@ -373,19 +375,15 @@ static Word16 adpt_enr_fx( /* o : adaptive excitation { FOR( i = 0; i < L_subfr; i++ ) { - exc_tmp[i] = mult( exc[i], 8192 ); + exc_tmp[i] = mult( exc[i], 8192 /*0.25.Q15*/ ); // Q_new move16(); - xn_tmp[i] = mult( xn[i], 8192 ); + xn_tmp[i] = mult( xn[i], 8192 /*0.25.Q15*/ ); // Q_new move16(); } Overflow = 0; conv_fx( exc_tmp, h1, y1, L_subfr ); -#ifdef BASOP_NOGLOB *gain = corr_xy1_fx( xn_tmp, y1, g_corr, L_subfr, codec_mode == MODE2, &Overflow ); -#else - *gain = corr_xy1_fx( xn_tmp, y1, g_corr, L_subfr, codec_mode == MODE2 ); -#endif move16(); } @@ -393,14 +391,14 @@ static Word16 adpt_enr_fx( /* o : adaptive excitation test(); if ( EQ_16( clip_gain, 1 ) && GT_16( *gain, 15565 ) ) /* constant in Q14 */ { - *gain = 15565; + *gain = 15565; // 0.95.Q14 move16(); } test(); - if ( EQ_16( clip_gain, 2 ) && GT_16( *gain, 10650 ) ) + IF( EQ_16( clip_gain, 2 ) && GT_16( *gain, 10650 ) ) // 0.65.Q14 { - *gain = 10650; + *gain = 10650; // 0.65.Q14 move16(); } } @@ -413,14 +411,14 @@ static Word16 adpt_enr_fx( /* o : adaptive excitation /* could possibly happen in GSC */ Ltmp = Calc_Energy_Autoscaled( xn2, 0, L_subfr, exp_ener ); i = norm_l( Ltmp ); - ener = extract_h( L_shl( Ltmp, i ) ); + ener = extract_h( L_shl( Ltmp, i ) ); // exp_ener i = sub( 31, i ); *exp_ener = sub( i, *exp_ener ); move16(); } ELSE { - ener = extract_h( Dot_product12( xn2, xn2, L_SUBFR, exp_ener ) ); + ener = extract_h( Dot_product12( xn2, xn2, L_SUBFR, exp_ener ) ); // Q15 } return ener; @@ -434,15 +432,13 @@ static Word16 adpt_enr_fx( /* o : adaptive excitation *-------------------------------------------------------------------*/ Word16 corr_xy1_fx( /* o : pitch gain (0..GAIN_PIT_MAX) */ - const Word16 xn_1[], /* i : target signal */ - const Word16 y1_1[], /* i : filtered adaptive codebook excitation */ - Word16 g_corr[], /* o : correlations and -2 */ + const Word16 xn_1[], /* i : target signal Q_new*/ + const Word16 y1_1[], /* i : filtered adaptive codebook excitation 12 bits*/ + Word16 g_corr[], /* o : correlations and -2 mant/exp*/ const Word16 L_subfr, /* i : vector length */ const Word16 norm_flag /* i : flag for constraining pitch contribution */ -#ifdef BASOP_NOGLOB , Flag *Overflow_out /* o : propagating the Overflow flag to upper level */ -#endif ) { Word16 i; @@ -458,24 +454,20 @@ Word16 corr_xy1_fx( /* o : pitch gain (0..GAIN_PIT_MAX) *----------------------------------------------------------------*/ /* Compute scalar product */ - Copy( xn_1, xn, L_subfr ); + Copy( xn_1, xn, L_subfr ); // Q_new Copy( y1_1, y1, L_subfr ); Overflow = 0; move16(); -#ifdef BASOP_NOGLOB /* Critical Overflow */ Ltmp1 = Dot_product12_o( y1, y1, L_subfr, &exp_yy, &Overflow ); *Overflow_out |= Overflow; move16(); -#else - Ltmp1 = Dot_product12( y1, y1, L_subfr, &exp_yy ); -#endif IF( Overflow ) { FOR( i = 0; i < L_subfr; i++ ) { - xn[i] = mult_r( xn_1[i], 4096 ); + xn[i] = mult_r( xn_1[i], 4096 /*0.125.Q15*/ ); // Q-new move16(); - y1[i] = mult_r( y1_1[i], 4096 ); + y1[i] = mult_r( y1_1[i], 4096 /*0.125.Q15*/ ); move16(); } @@ -500,17 +492,13 @@ Word16 corr_xy1_fx( /* o : pitch gain (0..GAIN_PIT_MAX) } ELSE { - yy = extract_h( Ltmp1 ); + yy = extract_h( Ltmp1 ); // exp_yy /* Ltmp1 = L_shr(Ltmp1, sub(30, exp_yy));*/ /* Compute scalar product */ -#ifdef BASOP_NOGLOB Ltmp2 = Dot_product12_o( xn, y1, L_subfr, &exp_xy, &Overflow ); *Overflow_out |= Overflow; move16(); -#else - Ltmp2 = Dot_product12( xn, y1, L_subfr, &exp_xy ); -#endif xy = extract_h( Ltmp2 ); /* Ltmp2 = L_shr(Ltmp2, sub(30, exp_xy));*/ @@ -519,7 +507,7 @@ Word16 corr_xy1_fx( /* o : pitch gain (0..GAIN_PIT_MAX) g_corr[1] = exp_yy; move16(); /* -2.0*temp1 + 0.01 is done in Gain_enc_2 function*/ - g_corr[2] = xy; + g_corr[2] = xy; // exp_xy move16(); g_corr[3] = exp_xy; move16(); @@ -530,16 +518,12 @@ Word16 corr_xy1_fx( /* o : pitch gain (0..GAIN_PIT_MAX) IF( xy >= 0 && NE_16( s_or( yy, xy ), 16384 ) ) { /* compute gain = xy/yy */ - xy = shr( xy, 1 ); /* be sure that xy < yy */ - gain = div_s( xy, yy ); + xy = shr( xy, 1 ); /* be sure that xy < yy */ + gain = div_s( xy, yy ); // Q15 i = sub( exp_xy, exp_yy ); -#ifdef BASOP_NOGLOB gain = shl_o( gain, i, &Overflow ); /* saturation can occur here */ *Overflow_out |= Overflow; move16(); -#else /* BASOP_NOGLOB */ - gain = shl( gain, i ); /* saturation can occur here */ -#endif gain = s_max( gain, 0 ); gain = s_min( gain, GAIN_PIT_MAX ); /* 1.2 in Q14 */ @@ -553,29 +537,23 @@ Word16 corr_xy1_fx( /* o : pitch gain (0..GAIN_PIT_MAX) /* Limit the energy of pitch contribution */ IF( norm_flag ) { -#ifdef BASOP_NOGLOB /*that part of code seems never used*/ -#endif /* Compute scalar product */ xx = round_fx( Dot_product12_offs( xn, xn, L_subfr, &exp_xx, 1 ) ); /* gain_p_snr = sqrt(/) */ tmp = BASOP_Util_Divide1616_Scale( xx, yy, &exp_div ); exp_xx = add( sub( exp_xx, exp_yy ), exp_div ); - tmp = Sqrt16( tmp, &exp_xx ); + tmp = Sqrt16( tmp, &exp_xx ); // exp_xx /* Note: shl works as shl or shr. */ exp_xx = sub( exp_xx, 1 ); BASOP_SATURATE_WARNING_OFF_EVS -#ifdef BASOP_NOGLOB gain_p_snr = round_fx_sat( L_shl_sat( Mpy_32_16_1( 1717986944l /*ACELP_GAINS_CONST Q31*/, tmp ), exp_xx ) ); -#else - gain_p_snr = round_fx( L_shl( Mpy_32_16_1( 1717986944l /*ACELP_GAINS_CONST Q31*/, tmp ), exp_xx ) ); -#endif BASOP_SATURATE_WARNING_ON_EVS - gain = s_min( gain, gain_p_snr ); + gain = s_min( gain, gain_p_snr ); // Q14 } - return gain; + return gain; // Q14 } diff --git a/lib_enc/lsf_enc.c b/lib_enc/lsf_enc.c deleted file mode 100644 index 06e686f8142b9c7463e42f3abbbea3f1e7e4166e..0000000000000000000000000000000000000000 --- a/lib_enc/lsf_enc.c +++ /dev/null @@ -1,49 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include "cnst.h" -#include "rom_enc.h" -#include "rom_com.h" -#include "prot.h" -#include "prot_fx.h" -#include "prot_fx_enc.h" -#include "basop_proto_func.h" -#include "ivas_prot.h" -#include "ivas_prot_fx.h" -#include "ivas_rom_com.h" -#include "wmc_auto.h" diff --git a/lib_enc/lsf_enc_fx.c b/lib_enc/lsf_enc_fx.c index af1dbd1bd72aa737403b148eb9fba04620c69740..6761dfb8296d21226261d62f774f892ba973f889 100644 --- a/lib_enc/lsf_enc_fx.c +++ b/lib_enc/lsf_enc_fx.c @@ -8,7 +8,6 @@ #include "rom_com_fx.h" /* Static table prototypes */ #include "rom_com.h" /* Static table prototypes */ //#include "prot_fx.h" /* Function prototypes */ -#include "prot.h" /* Function prototypes */ #include "prot_fx.h" /* Function prototypes */ #include "prot_fx_enc.h" /* Function prototypes */ #include "ivas_prot_fx.h" /* Function prototypes */ @@ -32,9 +31,9 @@ static Word32 vq_lvq_lsf_enc( Word16 pred_flag, Word16 mode, Word16 u[], Word16 static Word32 vq_lvq_lsf_enc_ivas_fx( Word16 pred_flag, Word16 mode, Word16 u[], Word16 *levels, Word16 stages, Word16 w[], Word16 Idx[], const Word16 *lsf, const Word16 *pred, Word16 *resq, Word16 *lsfq ); -static void lsf_mid_enc_fx( BSTR_ENC_HANDLE hBstr, int16_t nb_bits, const Word16 int_fs, const Word16 qlsp0[], const Word16 qlsp1[], Word16 lsp[], const Word16 coder_type, const Word16 bwidth, Word32 Bin_Ener_old[], Word32 Bin_Ener[], Word16 Q_ener, Word16 ppp_mode, Word16 nelp_mode ); +static void lsf_mid_enc_fx( BSTR_ENC_HANDLE hBstr, Word16 nb_bits, const Word16 int_fs, const Word16 qlsp0[], const Word16 qlsp1[], Word16 lsp[], const Word16 coder_type, const Word16 bwidth, Word32 Bin_Ener_old[], Word32 Bin_Ener[], Word16 Q_ener, Word16 ppp_mode, Word16 nelp_mode ); -static void lsf_mid_enc_ivas_fx( BSTR_ENC_HANDLE hBstr, int16_t nb_bits, const Word32 int_fs, const Word16 qlsp0[], const Word16 qlsp1[], Word16 lsp[], const Word16 coder_type, const Word16 bwidth, Word32 Bin_Ener_old[], Word16 Q_ener, Word16 ppp_mode, Word16 nelp_mode ); +static void lsf_mid_enc_ivas_fx( BSTR_ENC_HANDLE hBstr, Word16 nb_bits, const Word32 int_fs, const Word16 qlsp0[], const Word16 qlsp1[], Word16 lsp[], const Word16 coder_type, const Word16 bwidth, Word32 Bin_Ener_old[], Word16 Q_ener, Word16 ppp_mode, Word16 nelp_mode ); /*===========================================================================*/ /* FUNCTION : lsf_enc_fx() */ @@ -72,21 +71,14 @@ void lsf_enc_fx( const Word16 Nb_ACELP_frames, const Word16 tdm_low_rate_mode, /* i : secondary channel low rate mode flag */ const Word16 GSC_IVAS_mode, /* i : GSC IVAS mode */ -#ifdef LSF_RE_USE_SECONDARY_CHANNEL - const float tdm_lsfQ_PCh[M], /* i : Q LSFs for primary channel */ -#endif const Word16 Q_new ) { Word16 nBits = 0; + move16(); Word16 int_fs; Word16 force_sf = 0; + move16(); Word16 fec_lsf[M], stab, i; -#ifdef REMOVE_IVAS_UNUSED_PARAMETERS_WARNING - (void) tdm_low_rate_mode; -#endif -#ifdef IVAS_CODE - Word16 param_lpc[NPRM_LPC_NEW]; -#endif Word32 L_tmp; Word16 coder_type, ppp_mode, nelp_mode; @@ -191,36 +183,20 @@ void lsf_enc_fx( /*-------------------------------------------------------------------------------------* * Frame end LSF quantization *-------------------------------------------------------------------------------------*/ -#ifdef LSF_RE_USE_SECONDARY_CHANNEL - lsf_end_enc_fx( st_fx, lsf_new, lsf_new, nBits, coder_type, Q_new + QSCALE - 2, - force_sf, NULL, NULL, NULL, st_fx->coder_type_raw_fxtdm_lsfQ_PCh ); -#else + lsf_end_enc_fx( st_fx, lsf_new, lsf_new, nBits, coder_type, Q_new + QSCALE - 2, force_sf, NULL, NULL, NULL, st_fx->coder_type_raw ); -#endif + /* convert quantized LSFs back to LSPs */ lsf2lsp_fx( lsf_new, lsp_new, M, int_fs ); test(); - IF( EQ_16( st_fx->last_core, HQ_CORE ) && EQ_16( st_fx->core, ACELP_CORE ) ) + IF( EQ_16( st_fx->last_core, HQ_CORE ) && ( st_fx->core == ACELP_CORE ) ) { /* don't use old LSF values if this is the first ACELP frame after HQ frames */ Copy( lsf_new, st_fx->lsf_old_fx, M ); } /* set seed_acelp used in UC mode */ -#ifdef IVAS_CODE - test(); - IF( EQ_16( coder_type, UNVOICED ) && GT_16( st_fx->element_mode, EVS_MONO ) ) - { - st_fx->seed_acelp = 0; - move16(); - FOR( i = no_param_lpc - 1; i >= 0; i-- ) - { - /* rightshift before *seed_acelp+param_lpc[i] to avoid overflows*/ - st->seed_acelp = (int16_t) ( ( ( ( st->seed_acelp ) >> 1 ) + param_lpc[i] ) * 31821L + 13849L ); - } - } -#endif IF( EQ_32( st_fx->core_brate, SID_2k40 ) ) { /* return if SID frame (conversion to A(z) done in the calling function) */ @@ -242,7 +218,7 @@ void lsf_enc_fx( FEC_lsf_estim_enc_fx( st_fx, fec_lsf ); /* in case of FEC in decoder - calculate LSF stability */ - stab = lsf_stab_fx( lsf_new, fec_lsf, 0, st_fx->L_frame ); + stab = lsf_stab_fx( lsf_new, fec_lsf, 0, st_fx->L_frame ); // Q15 test(); test(); @@ -281,8 +257,8 @@ void lsf_enc_fx( if ( st_fx->rate_switching_reset ) { /*extrapolation in case of unstable LSF convert*/ - Copy( lsp_new, st_fx->lsp_old_fx, M ); - Copy( lsf_new, st_fx->lsf_old_fx, M ); + Copy( lsp_new, st_fx->lsp_old_fx, M ); // Q15 + Copy( lsf_new, st_fx->lsf_old_fx, M ); // Q15 } /* Mid-frame LSF encoding */ lsf_mid_enc_fx( st_fx->hBstr, st_fx->acelp_cfg.mid_lsf_bits, int_fs, st_fx->lsp_old_fx, lsp_new, lsp_mid, coder_type, st_fx->bwidth, st_fx->Bin_E_old_fx, st_fx->Bin_E_fx, Q_new + QSCALE - 2, ppp_mode, nelp_mode ); @@ -291,16 +267,15 @@ void lsf_enc_fx( IF( EQ_16( st_fx->last_core, HQ_CORE ) && EQ_16( st_fx->core, ACELP_CORE ) ) { /* don't use old LSP/LSF values if this is the first ACELP frame after HQ frames */ - Copy( lsp_mid, st_fx->lsp_old_fx, M ); + Copy( lsp_mid, st_fx->lsp_old_fx, M ); // Q15 lsp2lsf_fx( lsp_mid, st_fx->lsf_old_fx, M, int_fs ); } /* LSP interpolation and conversion of LSPs to A(z) */ -#ifdef ADD_LRTD test(); IF( EQ_16( tdm_low_rate_mode, 1 ) && GT_16( coder_type, UNVOICED ) ) { - IF( EQ_16( st_fx->active_cnt_fx, 1 ) ) + IF( EQ_16( st_fx->active_cnt, 1 ) ) { Copy( lsp_mid, st_fx->lsp_old_fx, M ); lsp2lsf_fx( lsp_mid, st_fx->lsf_old_fx, M, int_fs ); @@ -311,7 +286,6 @@ void lsf_enc_fx( int_lsp4_fx( st_fx->L_frame, st_fx->lsp_old_fx, lsp_mid, lsp_new, Aq, M, -2 ); } ELSE -#endif { int_lsp4_fx( st_fx->L_frame, st_fx->lsp_old_fx, lsp_mid, lsp_new, Aq, M, 0 ); } @@ -327,10 +301,10 @@ void lsf_enc_fx( void lsf_enc_ivas_fx( Encoder_State *st, /* i/o: state structure */ - Word16 *lsf_new, /* o : quantized LSF vector */ - Word16 *lsp_new, /* i/o: LSP vector to quantize/quantized */ - Word16 *lsp_mid, /* i/o : mid-frame LSP vector */ - Word16 *Aq, /* o : quantized A(z) for 4 subframes */ + Word16 *lsf_new, /* o : quantized LSF vector Q(x2.56)*/ + Word16 *lsp_new, /* i/o: LSP vector to quantize/quantized Q15*/ + Word16 *lsp_mid, /* i/o : mid-frame LSP vector Q15*/ + Word16 *Aq, /* o : quantized A(z) for 4 subframes Q12*/ const Word16 tdm_low_rate_mode, /* i : secondary channel low rate mode flag */ const Word16 GSC_IVAS_mode, /* i : GSC IVAS mode */ const Word16 tdm_lsfQ_PCh[M], /* i : Q LSFs for primary channel */ @@ -490,15 +464,15 @@ void lsf_enc_ivas_fx( IF( NE_16( st->last_L_frame, st->L_frame ) ) { /* FEC - in case of core switching, use old LSFs */ - Copy( st->lsf_old_fx, st->lsfoldbfi1_fx, M ); - Copy( st->lsf_old_fx, st->lsfoldbfi0_fx, M ); - Copy( st->lsf_old_fx, st->lsf_adaptive_mean_fx, M ); + Copy( st->lsf_old_fx, st->lsfoldbfi1_fx, M ); // Q15 + Copy( st->lsf_old_fx, st->lsfoldbfi0_fx, M ); // Q15 + Copy( st->lsf_old_fx, st->lsf_adaptive_mean_fx, M ); // Q15 } FEC_lsf_estim_enc_fx( st, fec_lsf ); /* in case of FEC in decoder - calculate LSF stability */ - stab = lsf_stab_ivas_fx( lsf_new, fec_lsf, 0, st->L_frame ); + stab = lsf_stab_ivas_fx( lsf_new, fec_lsf, 0, st->L_frame ); // Q15 test(); test(); @@ -537,8 +511,8 @@ void lsf_enc_ivas_fx( IF( st->rate_switching_reset ) { /*extrapolation in case of unstable LSF convert*/ - Copy( lsp_new, st->lsp_old_fx, M ); - Copy( lsf_new, st->lsf_old_fx, M ); + Copy( lsp_new, st->lsp_old_fx, M ); // Q15 + Copy( lsf_new, st->lsf_old_fx, M ); // Q15 } /* Mid-frame LSF encoding */ lsf_mid_enc_ivas_fx( st->hBstr, st->acelp_cfg.mid_lsf_bits, st->sr_core, st->lsp_old_fx, lsp_new, lsp_mid, coder_type, st->bwidth, st->Bin_E_old_fx, Q_new + QSCALE - 2, ppp_mode, nelp_mode ); @@ -557,9 +531,9 @@ void lsf_enc_ivas_fx( { IF( EQ_16( st->active_cnt, 1 ) ) { - Copy( lsp_mid, st->lsp_old_fx, M ); + Copy( lsp_mid, st->lsp_old_fx, M ); // Q15 lsp2lsf_fx( lsp_mid, st->lsf_old_fx, M, st->sr_core ); - Copy( lsp_new, lsp_mid, M ); + Copy( lsp_new, lsp_mid, M ); // Q15 } /* LSP interpolation and conversion of LSPs to A(z) - two-subframe mode */ @@ -574,7 +548,7 @@ void lsf_enc_ivas_fx( *------------------------------------------------------------------*/ IF( NE_32( st->core_brate, SID_2k40 ) ) { - st->stab_fac_fx = lsf_stab_ivas_fx( lsf_new, st->lsf_old_fx, 0, st->L_frame ); + st->stab_fac_fx = lsf_stab_ivas_fx( lsf_new, st->lsf_old_fx, 0, st->L_frame ); // Q15 } return; } @@ -807,11 +781,7 @@ static Word16 qlsf_Mode_Select_fx( { pred_pow2[i] = shl( pred1[i], cs ); move16(); -#ifdef BASOP_NOGLOB En = L_mac_o( En, mult( pred_pow2[i], shl_o( w[i], 2, &Overflow ) ), pred_pow2[i], &Overflow ); /* 2.56*2.56 at Q-4 */ -#else /* BASOP_NOGLOB */ - En = L_mac( En, mult( pred_pow2[i], shl( w[i], 2 ) ), pred_pow2[i] ); /* 2.56*2.56 at Q-4 */ -#endif /* BASOP_NOGLOB */ } cs = shl( cs, 1 ); @@ -879,8 +849,8 @@ static Word16 qlsf_Mode_Select_fx( /*========================================================================*/ void lsf_end_enc_fx( Encoder_State *st, /* i/o: encoder state structure */ - const Word16 *lsf, /* i : LSF in the frequency domain (0..6400) */ - Word16 *qlsf, /* o : quantized LSF */ + const Word16 *lsf, /* i : LSF in the frequency domain (0..6400) x2.56*/ + Word16 *qlsf, /* o : quantized LSF x2.56*/ const Word16 nBits_in, /* i : number of bits to spend on ISF quantization */ const Word16 coder_type_org, /* i : coding type */ Word16 Q_ener, /* i : Q valuen for Bin_Ener */ @@ -889,10 +859,6 @@ void lsf_end_enc_fx( Word16 *no_indices, Word16 *bits_param_lpc, Word16 coder_type_raw /* i : Coder type (LSF coder_type have some special cases)*/ -#ifdef LSF_RE_USE_SECONDARY_CHANNEL - , - const Word16 tdm_lsfQ_PCh[M] /* i : Q LSFs for primary channel */ -#endif ) { Word16 i; @@ -926,10 +892,6 @@ void lsf_end_enc_fx( Word16 tmp; Word16 flag_1bit_gran; BSTR_ENC_HANDLE hBstr = st->hBstr; -#ifdef LSF_RE_USE_SECONDARY_CHANNEL - Word16 pred3[M]; - Word16 dummy, dummy_v[5]; -#endif flag_1bit_gran = (Word16) GT_16( st->element_mode, EVS_MONO ); @@ -939,11 +901,7 @@ void lsf_end_enc_fx( test(); test(); test(); -#ifdef LSF_RE_USE_SECONDARY_CHANNEL - IF( EQ_16( coder_type_org, GENERIC ) && EQ_32( st->sr_core, INT_FS_16k ) && EQ_16( st->codec_mode, MODE1 ) && ( st->idchan == 0 ) ) /* this bit is used only for primary channel or mono */ -#else IF( EQ_16( coder_type_org, GENERIC ) && EQ_32( st->sr_core, INT_FS_16k ) && EQ_16( st->codec_mode, MODE1 ) ) -#endif { IF( EQ_16( coder_type_raw, VOICED ) ) { @@ -1018,16 +976,7 @@ void lsf_end_enc_fx( pred1[i] = add( ModeMeans_fx[mode_lvq][i], mult_r( MU_MA_FX, st->mem_MA_fx[i] ) ); move16(); } -#ifdef LSF_RE_USE_SECONDARY_CHANNEL - /* TD stereo SCh: perform intra-frame prediction with pulling-to-mean */ - if ( st->tdm_LRTD_flag == 0 && st->idchan == 1 && tdm_lsfQ_PCh != NULL ) - { - /* if secondary channel predmode is set to be > 2 */ - predmode += 3; - tdm_SCh_LSF_intra_pred( st->element_brate, tdm_lsfQ_PCh, pred3 ); - } -#endif IF( predmode == 0 ) { /* Subtract only mean */ @@ -1052,206 +1001,127 @@ void lsf_end_enc_fx( move16(); } ELSE -#ifdef LSF_RE_USE_SECONDARY_CHANNEL - PMT( "LSF_RE_USE_SECONDARY_CHANNEL CODE IS MISSING " ) { - if ( predmode == 2 ) -#endif - { - /* Adaptive scaling factor (multiplier) is updated in order to reduce the amount of consecutive predictive frames in + /* Adaptive scaling factor (multiplier) is updated in order to reduce the amount of consecutive predictive frames in case of possible frame erasure. AR-predictive usage for VOICED mode is allowed to be higher than other modes. */ - test(); - test(); - test(); - IF( ( ( GT_16( st->pstreaklen, ( STREAKLEN + 3 ) ) ) && ( EQ_16( coder_type, VOICED ) ) ) || ( ( GT_16( st->pstreaklen, ( STREAKLEN ) ) ) && ( NE_16( coder_type, VOICED ) ) ) ) + test(); + test(); + test(); + IF( ( ( GT_16( st->pstreaklen, ( STREAKLEN + 3 ) ) ) && ( EQ_16( coder_type, VOICED ) ) ) || ( ( GT_16( st->pstreaklen, ( STREAKLEN ) ) ) && ( NE_16( coder_type, VOICED ) ) ) ) + { + /* update the adaptive scaling factor to become smaller with increasing number of concecutive predictive frames. */ + st->streaklimit_fx = mult( st->streaklimit_fx, STREAKMULT_FX ); // Q15 + move16(); + } + + IF( st->pstreaklen == 0 ) + { + /* reset the consecutive AR-predictor multiplier */ + st->streaklimit_fx = 32767; /*1.0 in Q15 */ + move16(); + } + + /* VOICED_WB@16kHz */ + test(); + IF( EQ_32( st->sr_core, INT_FS_16k ) && EQ_16( coder_type, VOICED ) && flag_1bit_gran == 0 ) + { + /* Subtract mean and AR prediction */ + Copy( ModeMeans_fx[mode_lvq], pred0, M ); + /* subtract only mean */ + Vr_subt( lsf, pred0, Tmp, M ); + + FOR( i = 0; i < M; i++ ) { - /* update the adaptive scaling factor to become smaller with increasing number of concecutive predictive frames. */ - st->streaklimit_fx = mult( st->streaklimit_fx, STREAKMULT_FX ); - move16(); + /* subtract mean and AR prediction */ + pred2[i] = mult( Predictors_fx[mode_lvq_p][i], sub( st->mem_AR_fx[i], pred0[i] ) ); + Tmp2[i] = sub( Tmp[i], pred2[i] ); + pred2[i] = add( pred2[i], pred0[i] ); } - IF( st->pstreaklen == 0 ) + /* select safety_net or predictive */ + safety_net = qlsf_Mode_Select_fx( wghts, Tmp2, st->streaklimit_fx, OP_LOOP_THR_HVO ); + IF( EQ_16( force_sf, 1 ) ) { - /* reset the consecutive AR-predictor multiplier */ - st->streaklimit_fx = 32767; /*1.0 in Q15 */ + safety_net = 1; move16(); } - /* VOICED_WB@16kHz */ - test(); - IF( EQ_32( st->sr_core, INT_FS_16k ) && EQ_16( coder_type, VOICED ) && flag_1bit_gran == 0 ) + IF( safety_net ) { - /* Subtract mean and AR prediction */ - Copy( ModeMeans_fx[mode_lvq], pred0, M ); - /* subtract only mean */ - Vr_subt( lsf, pred0, Tmp, M ); - - FOR( i = 0; i < M; i++ ) - { - /* subtract mean and AR prediction */ - pred2[i] = mult( Predictors_fx[mode_lvq_p][i], sub( st->mem_AR_fx[i], pred0[i] ) ); - Tmp2[i] = sub( Tmp[i], pred2[i] ); - pred2[i] = add( pred2[i], pred0[i] ); - } - - /* select safety_net or predictive */ - safety_net = qlsf_Mode_Select_fx( wghts, Tmp2, st->streaklimit_fx, OP_LOOP_THR_HVO ); - IF( EQ_16( force_sf, 1 ) ) - { - safety_net = 1; - move16(); - } - - IF( safety_net ) - { - /* Safety-net - BC-TCQ quantization : SN */ - Err[0] = qlsf_ARSN_tcvq_Enc_16k_fx( Tmp, lsfq, TCQIdx0, wghts, sub( nBits, 1 ), safety_net ); - st->pstreaklen = 0; - move16(); - } - ELSE - { - /* predictive - BC-TCQ quantization : AR */ - Err[1] = qlsf_ARSN_tcvq_Enc_16k_fx( Tmp2, lsfq, TCQIdx0, wghts, sub( nBits, 1 ), safety_net ); - st->pstreaklen = add( st->pstreaklen, 1 ); - } + /* Safety-net - BC-TCQ quantization : SN */ + Err[0] = qlsf_ARSN_tcvq_Enc_16k_fx( Tmp, lsfq, TCQIdx0, wghts, sub( nBits, 1 ), safety_net ); + st->pstreaklen = 0; + move16(); } - /* all other frames (not VOICED@16kHz) */ ELSE { - /* Subtract mean and AR prediction */ - Copy( ModeMeans_fx[mode_lvq], pred0, M ); - /* subtract only mean */ - Vr_subt( lsf, pred0, Tmp, M ); - - FOR( i = 0; i < M; i++ ) - { - /* subtract mean and AR prediction */ - pred2[i] = add( pred0[i], mult( Predictors_fx[mode_lvq_p][i], sub( st->mem_AR_fx[i], pred0[i] ) ) ); - Tmp2[i] = sub( lsf[i], pred2[i] ); - } - - /* safety-net */ - Err[0] = vq_lvq_lsf_enc( 0, mode_lvq, Tmp, levels0, stages0, wghts, Idx0, lsf, pred0, st->offset_scale1_fx, st->offset_scale2_fx, st->no_scales_fx, resq, lsfq ); - /* Predictive quantizer is calculated only if it can be selected */ - test(); - IF( !force_sf || GT_32( Err[0], abs_threshold ) ) - { - Err[1] = vq_lvq_lsf_enc( 2, mode_lvq_p, Tmp2, levels1, stages1, wghts, Idx1, lsf, pred2, - st->offset_scale1_p_fx, st->offset_scale2_p_fx, st->no_scales_p_fx, &resq[M], &lsfq[M] ); - } - test(); - test(); - /* Select whether to use safety-net (non-predictive) or predictive LSF quantizer. The decision is based on following: - if the non-predictive (safety-net) quantization error (Err[0]) is low enough (spectral distortion is low) it is selected - or if the predictively quantized error (Err[1]) is by at least adaptive margin smaller than non-predictive quantizer. - or if the in case of frame erasure the resulting concealed predictive LSF would be unstable safety-net is selected */ - IF( force_sf || LT_32( Mult_32_16( Err[0], ( st->streaklimit_fx ) ), L_add( Err[1], Mult_32_16( Err[1], PREFERSFNET_FX ) ) ) || LT_32( Err[0], abs_threshold ) ) - { - safety_net = 1; - move16(); - st->pstreaklen = 0; - move16(); /* Reset the consecutive predictive frame counter */ - } - ELSE - { - safety_net = 0; - move16(); /* Increase the consecutive predictive frame counter by one */ - st->pstreaklen = add( st->pstreaklen, 1 ); - } + /* predictive - BC-TCQ quantization : AR */ + Err[1] = qlsf_ARSN_tcvq_Enc_16k_fx( Tmp2, lsfq, TCQIdx0, wghts, sub( nBits, 1 ), safety_net ); + st->pstreaklen = add( st->pstreaklen, 1 ); } } -#ifdef LSF_RE_USE_SECONDARY_CHANNEL - PMT( "LSF_RE_USE_SECONDARY_CHANNEL CODE IS MISSING " ) - else /* of "if (predmode==2)" */ + /* all other frames (not VOICED@16kHz) */ + ELSE { - mvr2r( ModeMeans[mode_lvq], pred0, M ); - - if ( predmode == 4 ) - { - mode_lvq_p = 9; /* force to Generic WB with AR*/ - } + /* Subtract mean and AR prediction */ + Copy( ModeMeans_fx[mode_lvq], pred0, M ); + /* subtract only mean */ + Vr_subt( lsf, pred0, Tmp, M ); - for ( i = 0; i < M; i++ ) + FOR( i = 0; i < M; i++ ) { /* subtract mean and AR prediction */ - pred2[i] = pred0[i] + Predictors[mode_lvq_p][i] * ( st->mem_AR[i] - pred0[i] ); - Tmp[i] = lsf[i] - pred2[i]; - Tmp2[i] = lsf[i] - pred3[i]; + pred2[i] = add( pred0[i], mult( Predictors_fx[mode_lvq_p][i], sub( st->mem_AR_fx[i], pred0[i] ) ) ); + Tmp2[i] = sub( lsf[i], pred2[i] ); } - /* Adaptive scaling factor (multiplier) is updated in order to reduce the amount of consecutive predictive frames in - case of possible frame erasure. AR-predictive usage for VOICED mode is allowed to be higher than other modes. */ - if ( st->pstreaklen > ( STREAKLEN ) ) + /* safety-net */ + Err[0] = vq_lvq_lsf_enc( 0, mode_lvq, Tmp, levels0, stages0, wghts, Idx0, lsf, pred0, st->offset_scale1_fx, st->offset_scale2_fx, st->no_scales_fx, resq, lsfq ); + /* Predictive quantizer is calculated only if it can be selected */ + test(); + IF( !force_sf || GT_32( Err[0], abs_threshold ) ) { - /* update the adaptive scaling factor to become smaller with increasing number of concecutive predictive frames. */ - st->streaklimit *= STREAKMULT; + Err[1] = vq_lvq_lsf_enc( 2, mode_lvq_p, Tmp2, levels1, stages1, wghts, Idx1, lsf, pred2, + st->offset_scale1_p_fx, st->offset_scale2_p_fx, st->no_scales_p_fx, &resq[M], &lsfq[M] ); } - - if ( st->pstreaklen == 0 ) + test(); + test(); + /* Select whether to use safety-net (non-predictive) or predictive LSF quantizer. The decision is based on following: + if the non-predictive (safety-net) quantization error (Err[0]) is low enough (spectral distortion is low) it is selected + or if the predictively quantized error (Err[1]) is by at least adaptive margin smaller than non-predictive quantizer. + or if the in case of frame erasure the resulting concealed predictive LSF would be unstable safety-net is selected */ + IF( force_sf || LT_32( Mult_32_16( Err[0], ( st->streaklimit_fx ) ), L_add( Err[1], Mult_32_16( Err[1], PREFERSFNET_FX ) ) ) || LT_32( Err[0], abs_threshold ) ) { - /* reset the adaptive scaling factor */ - st->streaklimit = 1.0f; + safety_net = 1; + move16(); + st->pstreaklen = 0; + move16(); /* Reset the consecutive predictive frame counter */ } - - /* intra pred */ - /* use G AR pred for the intra mode (as a safety mode, this is why the indexes 0/1 are interchanged)*/ - - lsf_allocate( nBits - 1, mode_lvq, 9, &stages1, &stages0, levels1, levels0, bits1, bits0 ); - - Err[0] = vq_lvq_lsf_enc( 2, 9, Tmp2, levels0, stages0, wghts, Idx0, lsf, pred3, &resq[M], &lsfq[M] ); - - if ( force_sf ) + ELSE { - safety_net = 1; /* intra-frame prediction */ - st->pstreaklen = 0; /* Reset the consecutive predictive frame counter */ - } - else - { /* try also the inter frame prediction */ - - /* AR inter-frame prediction */ - lsf_allocate( nBits - 1, mode_lvq, mode_lvq_p, &dummy, &stages1, dummy_v, levels1, dummy_v, bits1 ); - - - Err[1] = vq_lvq_lsf_enc( 2, mode_lvq_p, Tmp, levels1, stages1, wghts, Idx1, lsf, pred2, resq, lsfq ); - - if ( Err[0] * ( st->streaklimit ) < PREFERSFNET * Err[1] ) - { - safety_net = 1; - st->pstreaklen = 0; /* Reset the consecutive predictive frame counter */ - } - else - { - safety_net = 0; - ( st->pstreaklen )++; /* Increase the consecutive predictive frame counter by one */ - } + safety_net = 0; + move16(); /* Increase the consecutive predictive frame counter by one */ + st->pstreaklen = add( st->pstreaklen, 1 ); } } } -#endif /*--------------------------------------------------------------------------* \ - * Write indices to array \ - *--------------------------------------------------------------------------*/ + + /*--------------------------------------------------------------------------* \ + * Write indices to array \ + *--------------------------------------------------------------------------*/ IF( EQ_16( st->codec_mode, MODE1 ) && EQ_16( st->core, ACELP_CORE ) ) { /* write coder_type bit for VOICED@16kHz or GENERIC@16kHz */ test(); -#ifdef LSF_RE_USE_SECONDARY_CHANNEL - IF( EQ_16( coder_type_org, GENERIC ) && EQ_32( st->sr_core, INT_FS_16k ) && ( st->idchan == 0 ) ) -#else IF( EQ_16( coder_type_org, GENERIC ) && EQ_32( st->sr_core, INT_FS_16k ) ) -#endif { /* VOICED =2 and GENERIC=3, so "coder_type-2" means VOICED =0 and GENERIC=1*/ push_indice_fx( hBstr, IND_LSF_PREDICTOR_SELECT_BIT, sub( coder_type, 2 ), 1 ); } /* write predictor selection bit */ -#ifdef LSF_RE_USE_SECONDARY_CHANNEL - IF( GE( predmode, 2 ) ) -#else IF( EQ_16( predmode, 2 ) ) -#endif { push_indice_fx( st->hBstr, IND_LSF_PREDICTOR_SELECT_BIT, safety_net, 1 ); } @@ -1271,11 +1141,7 @@ void lsf_end_enc_fx( { cumleft = nBits; move16(); -#ifdef LSF_RE_USE_SECONDARY_CHANNEL - IF( GE( predmode, 2 ) ) -#else IF( EQ_16( predmode, 2 ) ) -#endif { /* subtract predictor selection bit */ cumleft = sub( nBits, 1 ); @@ -1347,7 +1213,7 @@ void lsf_end_enc_fx( { lpc_param[i] = TCQIdx0[i]; move16(); - bits_param_lpc[i] = BC_TCVQ_BIT_ALLOC_40B[i]; + bits_param_lpc[i] = BC_TCVQ_BIT_ALLOC_40B[i]; // Q0 move16(); } } @@ -1438,16 +1304,6 @@ void lsf_end_enc_fx( } ELSE { -#ifdef LSF_RE_USE_SECONDARY_CHANNEL - if ( st->tdm_LRTD_flag == 0 && st->idchan == 1 && tdm_lsfQ_PCh != NULL ) - { - /* intra mode*/ - vq_dec_lvq( 0, qlsf, &indice[0], stages0, M, 9, /*mode_lvq_p,*/ levels0[stages0 - 1] ); - v_add( qlsf, pred3, qlsf, M ); - v_sub( qlsf, pred1, st->mem_MA, M ); - } - else -#endif { vq_dec_lvq_fx( 1, qlsf, &indice[0], stages0, M, mode_lvq, levels0[stages0 - 1], &st->offset_scale1_fx[0][0], &st->offset_scale2_fx[0][0], &st->offset_scale1_p_fx[0][0], &st->offset_scale2_p_fx[0][0], @@ -1498,8 +1354,8 @@ void lsf_end_enc_fx( void lsf_end_enc_ivas_fx( Encoder_State *st, /* i/o: encoder state structure */ - const Word16 *lsf, /* i : LSF in the frequency domain (0..6400) */ - Word16 *qlsf, /* o : quantized LSF */ + const Word16 *lsf, /* i : LSF in the frequency domain (0..6400) x2.56*/ + Word16 *qlsf, /* o : quantized LSF x2.56*/ const Word16 nBits_in, /* i : number of bits to spend on ISF quantization */ const Word16 coder_type_org, /* i : coding type */ Word16 Q_ener, /* i : Q valuen for Bin_Ener */ @@ -2090,10 +1946,10 @@ void lsf_end_enc_ivas_fx( static void first_VQstages( const Word16 *const *cb, - Word16 u[], /* i : vector to be encoded (prediction and mean removed) */ + Word16 u[], /* i : vector to be encoded (prediction and mean removed) x2.56*/ Word16 *levels, /* i : number of levels in each stage */ Word16 stagesVQ, /* i : number of stages */ - Word16 w[], /* i : weights */ + Word16 w[], /* i : weights Q8*/ Word16 N, /* i : vector dimension */ Word16 max_inner, /* i : maximum number of swaps in inner loop */ Word16 indices_VQstage[] ) @@ -2133,11 +1989,7 @@ static void first_VQstages( L_tmp = L_deposit_l( 0 ); FOR( j = 0; j < N; j++ ) { -#ifdef BASOP_NOGLOB L_tmp1 = L_shl_o( L_mult0( u[j], w[j] ), 7, &Overflow ); /*x2.56 + Q8 + Q7 */ -#else /* BASOP_NOGLOB */ - L_tmp1 = L_shl( L_mult0( u[j], w[j] ), 7 ); /*x2.56 + Q8 + Q7 */ -#endif /* BASOP_NOGLOB */ L_tmp1 = Mult_32_16( L_tmp1, u[j] ); /*x2.56 + Q15 + x2.56 -Q15 */ L_tmp = L_add( L_tmp, L_tmp1 ); /*Q0 + x2.56 +x2.56 */ } @@ -2282,6 +2134,195 @@ static void first_VQstages( return; } +static void first_VQstages_ivas_fx( + const Word16 *const *cb, + Word16 u[], /* i : vector to be encoded (prediction and mean removed) */ + Word16 *levels, /* i : number of levels in each stage */ + Word16 stagesVQ, /* i : number of stages */ + Word16 w[], /* i : weights */ + Word16 N, /* i : vector dimension */ + Word16 max_inner, /* i : maximum number of swaps in inner loop */ + Word16 indices_VQstage[] ) +{ + Word16 resid_buf[2 * LSFMBEST * M], *resid[2]; + Word32 dist_buf[2 * LSFMBEST], *dist[2], en; + Word32 f_tmp, L_tmp, L_tmp1, *pTmp32; + Word16 Tmp[M], *pTmp, cs; + Word16 *pTmp_short, idx_buf[2 * LSFMBEST * MAX_VQ_STAGES], parents[LSFMBEST], counter = 0, j, + m, s, c, c2, p_max, *indices[2]; + Word16 maxC = LSFMBEST; +#ifdef BASOP_NOGLOB_DECLARE_LOCAL + Flag Overflow = 0; +#endif + + /*float dd[16];*/ + const Word16 *cb_stage, *cbp; + + /* Set pointers to previous (parent) and current node (parent node is indexed [0], current node is indexed [1]) */ + indices[0] = idx_buf; + move16(); + indices[1] = idx_buf + maxC * stagesVQ; + move16(); + resid[0] = resid_buf; + move16(); + resid[1] = resid_buf + maxC * N; + move16(); + dist[0] = dist_buf; + move16(); + dist[1] = dist_buf + maxC; + move16(); + + set16_fx( idx_buf, 0, ( const Word16 )( 2 * stagesVQ * maxC ) ); + set16_fx( parents, 0, maxC ); + + /* Set up inital distance vector */ + L_tmp = L_deposit_l( 0 ); + FOR( j = 0; j < N; j++ ) + { + L_tmp1 = L_shl_o( L_mult0( u[j], w[j] ), 7, &Overflow ); /*x2.56 + Q8 + Q7 */ + L_tmp1 = Mult_32_16( L_tmp1, u[j] ); /*x2.56 + Q15 + x2.56 -Q15 */ + L_tmp = L_add( L_tmp, L_tmp1 ); /*Q0 + x2.56 +x2.56 */ + } + set32_fx( dist[1], L_shr( L_tmp, 1 ), maxC ); /*Q-1 + x2.56 +x2.56 */ + + /* Set up initial error (residual) vectors */ + pTmp = resid[1]; + move16(); + FOR( c = 0; c < maxC; c++ ) + { + Copy( u, pTmp, N ); + pTmp += N; + } + + /*----------------------------------------------------------------* + * LSF quantization + *----------------------------------------------------------------*/ + + /* Loop over all stages */ + m = 1; + move16(); + FOR( s = 0; s < stagesVQ; s++ ) + { + /* set codebook pointer to point to first stage */ + cbp = cb[s]; + move16(); + + /* save pointer to the beginning of the current stage */ + cb_stage = cbp; + move16(); + + /* swap pointers to parent and current nodes */ + pTmp_short = indices[0]; + indices[0] = indices[1]; + move16(); + indices[1] = pTmp_short; + move16(); + + pTmp = resid[0]; + resid[0] = resid[1]; + move16(); + resid[1] = pTmp; + move16(); + + pTmp32 = dist[0]; + dist[0] = dist[1]; + move32(); + dist[1] = pTmp32; + move32(); + + /* p_max points to maximum distortion node (worst of best) */ + p_max = 0; + move16(); + + /* set distortions to a large value */ + set32_fx( dist[1], MAXINT32, maxC ); + + FOR( j = 0; j < levels[s]; j++ ) + { + /* compute weighted codebook element and its energy */ + FOR( c2 = 0; c2 < N; c2++ ) + { + Tmp[c2] = extract_h( L_shl( L_mult0( w[c2], cbp[c2] ), 6 ) ); /* Q8 + x2.56 + q6 -q16 */ + move16(); + } + + en = L_mult( cbp[0], Tmp[0] ); /*x2.56 + x2.56 + Q-2 +Q1 */ + + FOR( c2 = 1; c2 < N; c2++ ) + { + en = L_mac( en, cbp[c2], Tmp[c2] ); /*x2.56 + x2.56 + Q-2 +Q1 */ + } + cbp += N; + move16(); + + /* iterate over all parent nodes */ + FOR( c = 0; c < m; c++ ) + { + pTmp = &resid[0][c * N]; /*x2.56*/ + move16(); + L_tmp = L_mult( pTmp[0], Tmp[0] ); /*x2.56 + x2.56 + Q-2 +Q1 */ + FOR( c2 = 1; c2 < N; c2++ ) + { + L_tmp = L_mac( L_tmp, pTmp[c2], Tmp[c2] ); /*x2.56 + x2.56 + Q-2 +Q1 */ + } + + L_tmp = L_add( dist[0][c], L_sub( en, L_shl( L_tmp, 1 ) ) ); /*x2.56 + x2.56 -1*/ + + IF( LE_32( L_tmp, dist[1][p_max] ) ) + { + /* replace worst */ + dist[1][p_max] = L_tmp; + move32(); + indices[1][p_max * stagesVQ + s] = j; + move16(); + parents[p_max] = c; + move16(); + + /* limit number of times inner loop is entered */ + IF( LT_16( counter, max_inner ) ) + { + counter = add( counter, 1 ); + IF( LT_16( counter, max_inner ) ) + { + /* find new worst */ + p_max = maximum_32_fx( dist[1], maxC, &f_tmp ); + } + ELSE + { + /* find minimum distortion */ + p_max = minimum_32_fx( dist[1], maxC, &f_tmp ); + } + } + } + } + } + + /*------------------------------------------------------------* + * Compute error vectors for each node + *------------------------------------------------------------*/ + cs = 0; + move16(); + FOR( c = 0; c < maxC; c++ ) + { + /* subtract codebook entry from the residual vector of the parent node */ + pTmp = resid[1] + c * N; + move16(); + Copy( resid[0] + parents[c] * N, pTmp, N ); + Vr_subt( pTmp, cb_stage + ( indices[1][cs + s] ) * N, pTmp, N ); + + /* get indices that were used for parent node */ + Copy( indices[0] + parents[c] * stagesVQ, indices[1] + cs, s ); + cs = add( cs, stagesVQ ); + } + + m = maxC; + move16(); + } + + Copy( indices[1], indices_VQstage, maxC * stagesVQ ); + + return; +} /*--------------------------------------------------------------------------- * vq_enc_lsf_lvq() * @@ -2299,10 +2340,10 @@ static void first_VQstages( static Word32 vq_lvq_lsf_enc( Word16 pred_flag, Word16 mode, - Word16 u[], + Word16 u[], // x2.56 Word16 *levels, Word16 stages, - Word16 w[], + Word16 w[], // Q8 Word16 Idx[], const Word16 *lsf, const Word16 *pred, @@ -2331,13 +2372,13 @@ static Word32 vq_lvq_lsf_enc( { cb = &Quantizers_fx[CB_lsf[mode]]; move16(); - mode_glb = add( offset_lvq_modes_SN_fx[mode], offset_in_lvq_mode_SN_fx[mode][sub( levels[stagesVQ], min_lat_bits_SN_fx[mode] )] ); + mode_glb = add( offset_lvq_modes_SN_fx[mode], offset_in_lvq_mode_SN_fx[mode][( levels[stagesVQ] - min_lat_bits_SN_fx[mode] )] ); // Q0 } ELSE /* predictive */ { cb = &Quantizers_p_fx[CB_p_lsf[mode]]; move16(); - mode_glb = add( offset_lvq_modes_pred_fx[mode], offset_in_lvq_mode_pred_fx[mode][sub( levels[stagesVQ], min_lat_bits_pred_fx[mode] )] ); + mode_glb = add( offset_lvq_modes_pred_fx[mode], offset_in_lvq_mode_pred_fx[mode][( levels[stagesVQ] - min_lat_bits_pred_fx[mode] )] ); // Q0 } IF( stagesVQ > 0 ) { @@ -2374,27 +2415,15 @@ static Word32 vq_lvq_lsf_enc( Vr_subt( cand[i], lsf, diff, M ); FOR( j = 0; j < M; j++ ) { -#ifdef BASOP_NOGLOB diff[j] = shl_o( diff[j], 4, &Overflow ); -#else /* BASOP_NOGLOB */ - diff[j] = shl( diff[j], 4 ); -#endif /* BASOP_NOGLOB */ move16(); } -#ifdef BASOP_NOGLOB L_tmp = L_mult( mult( diff[0], shl_o( w[0], 1, &Overflow ) ), diff[0] ); /*(2.56+Q5+ Q10 -Q15) + 2.56+ Q5 + Q1 = 2.56 + 2.56 + Q6 */ -#else - L_tmp = L_mult( mult( diff[0], shl( w[0], 1 ) ), diff[0] ); /*(2.56+Q5+ Q10 -Q15) + 2.56+ Q5 + Q1 = 2.56 + 2.56 + Q6 */ -#endif FOR( j = 1; j < M; j++ ) { -#ifdef BASOP_NOGLOB L_tmp = L_mac( L_tmp, mult( diff[j], shl_o( w[j], 1, &Overflow ) ), diff[j] ); /*(2.56+Q5+ Q10 -Q15) + 2.56+ Q5 + Q1 = 2.56 + 2.56 + Q6 */ -#else - L_tmp = L_mac( L_tmp, mult( diff[j], shl( w[j], 1 ) ), diff[j] ); /*(2.56+Q5+ Q10 -Q15) + 2.56+ Q5 + Q1 = 2.56 + 2.56 + Q6 */ -#endif } - e[i] = L_tmp; + e[i] = L_tmp; /*(2.56+Q5+ Q10 -Q15) + 2.56+ Q5 + Q1 = 2.56 + 2.56 + Q6 */ move32(); } @@ -2420,10 +2449,10 @@ static Word32 vq_lvq_lsf_enc( static Word32 vq_lvq_lsf_enc_ivas_fx( Word16 pred_flag, Word16 mode, - Word16 u[], + Word16 u[], // x2.56 Word16 *levels, Word16 stages, - Word16 w[], + Word16 w[], // Q8 Word16 Idx[], const Word16 *lsf, const Word16 *pred, @@ -2451,7 +2480,7 @@ static Word32 vq_lvq_lsf_enc_ivas_fx( IF( LT_16( mode, 6 ) ) { move16(); - mode_glb = add( offset_lvq_modes_SN[mode], offset_in_lvq_mode_SN[mode][sub( levels[stagesVQ], min_lat_bits_SN[mode] )] ); + mode_glb = add( offset_lvq_modes_SN[mode], offset_in_lvq_mode_SN[mode][( levels[stagesVQ] - min_lat_bits_SN[mode] )] ); } ELSE { @@ -2465,7 +2494,7 @@ static Word32 vq_lvq_lsf_enc_ivas_fx( IF( LT_16( mode, 6 ) || EQ_16( mode, 12 ) ) { move16(); - mode_glb = add( offset_lvq_modes_pred[mode], offset_in_lvq_mode_pred[mode][sub( levels[stagesVQ], min_lat_bits_pred_fx[mode] )] ); + mode_glb = add( offset_lvq_modes_pred[mode], offset_in_lvq_mode_pred[mode][( levels[stagesVQ] - min_lat_bits_pred_fx[mode] )] ); } ELSE { @@ -2477,7 +2506,7 @@ static Word32 vq_lvq_lsf_enc_ivas_fx( IF( stagesVQ > 0 ) { /* first VQ stages */ - first_VQstages( cb, u, levels, stagesVQ, w, M, MSVQ_MAXCNT, indices_firstVQ ); + first_VQstages_ivas_fx( cb, u, levels, stagesVQ, w, M, MSVQ_MAXCNT, indices_firstVQ ); } @@ -2509,25 +2538,13 @@ static Word32 vq_lvq_lsf_enc_ivas_fx( Vr_subt( cand[i], lsf, diff, M ); FOR( j = 0; j < M; j++ ) { -#ifdef BASOP_NOGLOB diff[j] = shl_o( diff[j], 4, &Overflow ); -#else /* BASOP_NOGLOB */ - diff[j] = shl( diff[j], 4 ); -#endif /* BASOP_NOGLOB */ move16(); } -#ifdef BASOP_NOGLOB L_tmp = L_mult( mult( diff[0], shl_o( w[0], 1, &Overflow ) ), diff[0] ); /*(2.56+Q5+ Q10 -Q15) + 2.56+ Q5 + Q1 = 2.56 + 2.56 + Q6 */ -#else - L_tmp = L_mult( mult( diff[0], shl( w[0], 1 ) ), diff[0] ); /*(2.56+Q5+ Q10 -Q15) + 2.56+ Q5 + Q1 = 2.56 + 2.56 + Q6 */ -#endif FOR( j = 1; j < M; j++ ) { -#ifdef BASOP_NOGLOB L_tmp = L_mac( L_tmp, mult( diff[j], shl_o( w[j], 1, &Overflow ) ), diff[j] ); /*(2.56+Q5+ Q10 -Q15) + 2.56+ Q5 + Q1 = 2.56 + 2.56 + Q6 */ -#else - L_tmp = L_mac( L_tmp, mult( diff[j], shl( w[j], 1 ) ), diff[j] ); /*(2.56+Q5+ Q10 -Q15) + 2.56+ Q5 + Q1 = 2.56 + 2.56 + Q6 */ -#endif } e[i] = L_tmp; move32(); @@ -2557,7 +2574,7 @@ static void BcTcvq_1st_fx( Word16 c[][16], Word32 cDist_fx[][16], /*2.56*2.56*Q(-5 - 2)*/ Word16 Q_fx[][16][2], - Word16 W_fx[][2] /*Q10*/ + Word16 W_fx[][2] /*Q8*/ ) { Word16 state, prev_state; @@ -2618,7 +2635,7 @@ static void BcTcvq_2nd_fx( Word16 c[][16], Word32 cDist_fx[][16], /*2.56*2.56*Q(-5 - 2) */ Word16 Q_fx[][16][2], /*x2.56*/ - Word16 W_fx[][2], /*Q10*/ + Word16 W_fx[][2], /*Q8*/ const Word16 itc_fx[][2][2] /*Q15*/ ) { @@ -2906,12 +2923,12 @@ static Word32 BcTcvq_FixSearch_fx( Q_fx[stage][*prev_state][1] = add( CB_fx[stage4][bestCode][1], pred_fx[1] ); move16(); - minDist_fx = L_shr( minDist_fx, 2 ); + minDist_fx = L_shr( minDist_fx, 2 ); /*2.56*2.56*Q(-5 - 2)*/ return minDist_fx; } static Word16 optimalPath_fx( - Word32 cDist_fx[][16], - Word32 blockDist_fx[], + Word32 cDist_fx[][16], /*2.56*2.56*Q(-5 - 2)*/ + Word32 blockDist_fx[], /*2.56*2.56*Q(-5 - 2)*/ Word16 blockCodeword[][4], Word16 bestCodeword[], Word16 codeWord[][16], @@ -2970,10 +2987,11 @@ static Word16 optimalPath_fx( static void quantEnc_fx( Word16 *y_fx, Word16 c[], - const Word16 CB_SUB1_fx[][128][2], - const Word16 CB_SUB2_fx[][64][2], - const Word16 CB_SUB3_fx[][32][2], - const Word16 itc_fx[][2][2] ) + const Word16 CB_SUB1_fx[][128][2], /*x2.56*/ + const Word16 CB_SUB2_fx[][64][2], /*x2.56*/ + const Word16 CB_SUB3_fx[][32][2], /*x2.56*/ + const Word16 itc_fx[][2][2] // Q15 +) { Word16 i, j; Word16 stage; @@ -3088,9 +3106,9 @@ static void buildCode_fx( } static void BcTcvq_fx( Word16 snFlag, - const Word16 *x_fx, - Word16 *y_fx, - const Word16 *weight_fx, + const Word16 *x_fx, // x2.65 + Word16 *y_fx, // x2.65 + const Word16 *weight_fx, // Q8 Word16 *ind ) { Word16 X_fx[N_STAGE_VQ][N_DIM], W_fx[N_STAGE_VQ][N_DIM]; @@ -3147,9 +3165,9 @@ static void BcTcvq_fx( { FOR( j = 0; j < N_DIM; j++ ) { - X_fx[i][j] = x_fx[( N_DIM * i ) + j]; + X_fx[i][j] = x_fx[( N_DIM * i ) + j]; // x2.65 move16(); - W_fx[i][j] = weight_fx[( N_DIM * i ) + j]; + W_fx[i][j] = weight_fx[( N_DIM * i ) + j]; // x2.56 move16(); } } @@ -3244,10 +3262,10 @@ static void BcTcvq_fx( } static Word16 SVQ_2d_fx( - Word16 *x_fx, - Word16 *y_fx, - const Word16 *W_fx, - const Word16 CB_fx[][8], + Word16 *x_fx, // x2.65 + Word16 *y_fx, // x2.65 + const Word16 *W_fx, // Q8 + const Word16 CB_fx[][8], // x2.65 Word16 Size ) { Word16 i, j; @@ -3265,7 +3283,7 @@ static Word16 SVQ_2d_fx( { temp16_fx = sub( x_fx[j], CB_fx[i][j] ); distortion_fx = L_add( distortion_fx, - L_shr( Mult_32_16( L_mult( temp16_fx, temp16_fx ), W_fx[j] ), 1 ) ); + L_shr( Mult_32_16( L_mult( temp16_fx, temp16_fx ), W_fx[j] ), 1 ) ); // (2*x2.65 + Q1 + Q8) - Q15 - Q1 } IF( LT_32( distortion_fx, temp_fx ) ) @@ -3375,11 +3393,7 @@ Word32 qlsf_ARSN_tcvq_Enc_16k_fx( { yy_fx[i] = shl( yy_fx[i], cs ); move16(); -#ifdef BASOP_NOGLOB temp_l = L_mac_o( temp_l, mult( yy_fx[i], shl_o( w_fx[i], 2, &Overflow ) ), yy_fx[i], &Overflow ); -#else /* BASOP_NOGLOB */ - temp_l = L_mac( temp_l, mult( yy_fx[i], shl( w_fx[i], 2 ) ), yy_fx[i] ); -#endif /* BASOP_NOGLOB */ } cs = shl( cs, 1 ); temp_l = L_shr( temp_l, cs ); @@ -3392,9 +3406,9 @@ Word32 qlsf_ARSN_tcvq_Enc_16k_fx( } static void FFT_Mid_Interpol_16k_fx( - Word32 Bin_Ener_old[], /* i/o: Old 2nd FFT Bin energy (128) */ - Word32 Bin_Ener[], /* i : Current 2nd FFT Bin energy (128) */ - Word32 Bin_Ener_mid[] /* o : LP weighting filter (numerator) */ + Word32 Bin_Ener_old[], /* i/o: Old 2nd FFT Bin energy (128) Q_ener*/ + Word32 Bin_Ener[], /* i : Current 2nd FFT Bin energy (128) Q_ener*/ + Word32 Bin_Ener_mid[] /* o : LP weighting filter (numerator) Q_ener*/ ) { Word16 i; @@ -3405,11 +3419,7 @@ static void FFT_Mid_Interpol_16k_fx( FOR( i = 0; i < L_FFT / 2; i++ ) { /* Interpolation */ -#ifdef BASOP_NOGLOB Bin_Ener_mid[i] = L_shr( L_add_o( Bin_Ener_old[i], Bin_Ener[i], &Overflow ), 1 ); -#else /* BASOP_NOGLOB */ - Bin_Ener_mid[i] = L_shr( L_add( Bin_Ener_old[i], Bin_Ener[i] ), 1 ); -#endif /* BASOP_NOGLOB */ /* Memory update */ Bin_Ener_old[i] = Bin_Ener[i]; @@ -3510,14 +3520,6 @@ static void lsf_mid_enc_fx( move16(); BREAK; } -#ifdef IVAS_CODE - case 1: - { - ratio = tbl_mid_voi_wb_1b_fx; - move16(); - BREAK; - } -#endif } } ELSE IF( EQ_16( coder_type, UNVOICED ) ) @@ -3535,14 +3537,6 @@ static void lsf_mid_enc_fx( move16(); BREAK; } -#ifdef IVAS_CODE - case 4: - { - ratio = tbl_mid_gen_wb_4b_fx; - move16(); - BREAK; - } -#endif case 2: { ratio = tbl_mid_gen_wb_2b_fx; @@ -3603,15 +3597,9 @@ static void lsf_mid_enc_fx( tmp = sub( lsf[j], qlsf[j] ); /* err += wghts[j] * ftemp * ftemp; */ /* tmp is usually very small, we can have some extra precision with very rare saturation */ -#ifdef BASOP_NOGLOB tmp = shl_o( tmp, 4, &Overflow ); tmp = mult_ro( tmp, tmp, &Overflow ); err = L_mac_o( err, tmp, shl_o( wghts[j], 2, &Overflow ), &Overflow ); -#else /* BASOP_NOGLOB */ - tmp = shl( tmp, 4 ); - tmp = mult_r( tmp, tmp ); - err = L_mac( err, tmp, shl( wghts[j], 2 ) ); -#endif } /* err = L_shl(err,Wscale); */ err = Mult_32_16( err, LSF_1_OVER_256SQ ); @@ -3657,12 +3645,12 @@ static void lsf_mid_enc_ivas_fx( BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ Word16 nb_bits, /* i : number of bits */ const Word32 int_fs, /* i : internal (ACELP) sampling frequency*/ - const Word16 qlsp0[], /* i : quantized LSPs from frame beginning*/ - const Word16 qlsp1[], /* i : quantized LSPs from frame end */ - Word16 lsp[], /* i/o: mid-frame LSP */ + const Word16 qlsp0[], /* i : quantized LSPs from frame beginning Q15*/ + const Word16 qlsp1[], /* i : quantized LSPs from frame end Q15*/ + Word16 lsp[], /* i/o: mid-frame LSP Q15*/ const Word16 coder_type, /* i : coding type */ const Word16 bwidth, /* i : input signal bandwidth */ - Word32 Bin_Ener[], /* i : per bin log energy spectrum */ + Word32 Bin_Ener[], /* i : per bin log energy spectrum Q_ener*/ Word16 Q_ener, /* i : Q value of Bin_ener */ Word16 ppp_mode, Word16 nelp_mode ) @@ -3696,19 +3684,19 @@ static void lsf_mid_enc_ivas_fx( { case 5: { - ratio = tbl_mid_voi_wb_5b_fx; + ratio = tbl_mid_voi_wb_5b_fx; // Q13 move16(); BREAK; } case 4: { - ratio = tbl_mid_voi_wb_4b_fx; + ratio = tbl_mid_voi_wb_4b_fx; // Q13 move16(); BREAK; } case 1: { - ratio = tbl_mid_voi_wb_1b_fx; + ratio = tbl_mid_voi_wb_1b_fx; // Q13 move16(); BREAK; } @@ -3716,7 +3704,7 @@ static void lsf_mid_enc_ivas_fx( } ELSE IF( EQ_16( coder_type, UNVOICED ) ) { - ratio = tbl_mid_unv_wb_5b_fx; + ratio = tbl_mid_unv_wb_5b_fx; // Q13 } ELSE { @@ -3725,19 +3713,19 @@ static void lsf_mid_enc_ivas_fx( { case 5: { - ratio = tbl_mid_gen_wb_5b_fx; + ratio = tbl_mid_gen_wb_5b_fx; // Q13 move16(); BREAK; } case 4: { - ratio = tbl_mid_gen_wb_4b_fx; + ratio = tbl_mid_gen_wb_4b_fx; // Q13 move16(); BREAK; } case 2: { - ratio = tbl_mid_gen_wb_2b_fx; + ratio = tbl_mid_gen_wb_2b_fx; // Q13 move16(); BREAK; } @@ -3749,7 +3737,7 @@ static void lsf_mid_enc_ivas_fx( } ELSE IF( EQ_16( ppp_mode, 1 ) ) { - ratio = tbl_mid_voi_wb_1b_fx; + ratio = tbl_mid_voi_wb_1b_fx; // Q13 move16(); nb_bits = 1; move16(); @@ -3758,7 +3746,7 @@ static void lsf_mid_enc_ivas_fx( } ELSE IF( EQ_16( nelp_mode, 1 ) ) { - ratio = tbl_mid_unv_wb_4b_fx; + ratio = tbl_mid_unv_wb_4b_fx; // Q13 move16(); nb_bits = 4; move16(); @@ -3780,7 +3768,7 @@ static void lsf_mid_enc_ivas_fx( FOR( j = 0; j < M; j++ ) { /* qlsf[j] = (1.0f - ratio[k*M+j]) * qlsf0[j] + ratio[k*M+j] * qlsf1[j]; */ - L_tmp = L_mult( sub( 0x2000, ratio[k1 + j] ), qlsf0[j] ); + L_tmp = L_mult( sub( 0x2000 /*1.Q13*/, ratio[k1 + j] ), qlsf0[j] ); L_tmp = L_mac( L_tmp, ratio[k1 + j], qlsf1[j] ); qlsf[j] = round_fx( L_shl( L_tmp, 2 ) ); @@ -3795,15 +3783,9 @@ static void lsf_mid_enc_ivas_fx( tmp = sub( lsf[j], qlsf[j] ); /* err += wghts[j] * ftemp * ftemp; */ /* tmp is usually very small, we can have some extra precision with very rare saturation */ -#ifdef BASOP_NOGLOB tmp = shl_o( tmp, 4, &Overflow ); tmp = mult_ro( tmp, tmp, &Overflow ); err = L_mac_o( err, tmp, shl_o( wghts[j], 2, &Overflow ), &Overflow ); -#else /* BASOP_NOGLOB */ - tmp = shl( tmp, 4 ); - tmp = mult_r( tmp, tmp ); - err = L_mac( err, tmp, shl( wghts[j], 2 ) ); -#endif } /* err = L_shl(err,Wscale); */ err = Mult_32_16( err, LSF_1_OVER_256SQ ); @@ -3823,7 +3805,7 @@ static void lsf_mid_enc_ivas_fx( FOR( j = 0; j < M; j++ ) { /* qlsf[j] = (1.0f - ratio[idx*M+j]) * qlsf0[j] + ratio[idx*M+j] * qlsf1[j]; */ - L_tmp = L_mult( sub( 0x2000, ratio[idx * M + j] ), qlsf0[j] ); + L_tmp = L_mult( sub( 0x2000 /*1.Q13*/, ratio[idx * M + j] ), qlsf0[j] ); L_tmp = L_mac( L_tmp, ratio[idx * M + j], qlsf1[j] ); qlsf[j] = round_fx( L_shl( L_tmp, 2 ) ); diff --git a/lib_enc/lsf_msvq_ma_enc.c b/lib_enc/lsf_msvq_ma_enc.c index 2af64bf141f2009b2ddf9be421f6ba25f0f3011f..60375ddcce113a6c5ac6236fdbd3afd55aec93e9 100644 --- a/lib_enc/lsf_msvq_ma_enc.c +++ b/lib_enc/lsf_msvq_ma_enc.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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,8 +37,6 @@ #include #include "options.h" #include "cnst.h" -#include "ivas_prot.h" -#include "prot.h" #include "prot_fx.h" #include "rom_com.h" #include "rom_enc.h" @@ -94,7 +92,7 @@ Word16 msvq_stage1_dct_search_fx( Word32 *dist1_ptr_fx, /* o : resulting stage 1 MSEs in DCT-N domain */ Word16 *dist1_ptr_e ) { - Word32 dct_target_fx[FDCNG_VQ_DCT_MAXTRUNC]; + Word32 dct_target_fx[FDCNG_VQ_DCT_MAXTRUNC]; // Q20 Word32 u_mr_fx[FDCNG_VQ_MAX_LEN]; Word16 dist1_ptr_e_buf[2 * LSFMBEST_MAX]; Word64 mse_trunc_segm_fx[FDCNG_VQ_DCT_NSEGM]; @@ -128,7 +126,7 @@ Word16 msvq_stage1_dct_search_fx( tmp_e = s_max( 12, u_e ); FOR( i = 0; i < n_ana; i++ ) { - u_mr_fx[i] = L_sub( L_shl( u_fx[i], sub( u_e, tmp_e ) ), L_shl( midQ_truncQ_fx[i], sub( Q31 - Q10, tmp_e ) ) ); + u_mr_fx[i] = L_sub( L_shl( u_fx[i], sub( u_e, tmp_e ) ), L_shl( midQ_truncQ_fx[i], sub( Q31 - Q10, tmp_e ) ) ); // tmp_e move32(); } @@ -137,9 +135,9 @@ Word16 msvq_stage1_dct_search_fx( /* init search state ptr's at the top */ set32_fx( dist1_ptr_fx, MAX_32, maxC_st1 ); set16_fx( dist1_ptr_e_buf, 32, maxC_st1 ); - st1_mse_pair_fx = &( dist1_ptr_fx[0] ); /* req. ptr post upd +=2 */ - st1_mse_pair_e = &( dist1_ptr_e_buf[0] ); /* req. ptr post upd +=2 */ - st1_idx_pair = &( indices_st1_local[0] ); /* req. ptr post upd +=2 */ + st1_mse_pair_fx = &( dist1_ptr_fx[0] ); /* req. ptr post upd +=2 */ // st1_mse_pair_e + st1_mse_pair_e = &( dist1_ptr_e_buf[0] ); /* req. ptr post upd +=2 */ + st1_idx_pair = &( indices_st1_local[0] ); /* req. ptr post upd +=2 */ set64_fx( mse_trunc_segm_fx, 0, n_segm ); // set16_fx( mse_trunc_segm_e, u_e, FDCNG_VQ_DCT_NSEGM ); @@ -153,7 +151,7 @@ Word16 msvq_stage1_dct_search_fx( FOR( i = 0; i < trunc_dct_cols_per_segment[segm]; i++ ) { - mse_trunc_segm_fx[segm] = W_mac_32_32( mse_trunc_segm_fx[segm], dct_target_fx[cols_per_segment[segm] + i], dct_target_fx[cols_per_segment[segm] + i] ); + mse_trunc_segm_fx[segm] = W_mac_32_32( mse_trunc_segm_fx[segm], dct_target_fx[cols_per_segment[segm] + i], dct_target_fx[cols_per_segment[segm] + i] ); // Q41 move64(); } @@ -164,7 +162,7 @@ Word16 msvq_stage1_dct_search_fx( /* unweighted segmented search DCT domain loop */ j_full = add( j, cum_entries_per_segment[segm] ); /* or simply use j_full++ */ - mse_fx = mse_trunc_segm_fx[segm]; /* init mse with with common mse truncation part, in BASOP a move32() */ + mse_fx = mse_trunc_segm_fx[segm]; /* init mse with with common mse truncation part, in BASOP a move32() */ // Q41 move64(); dct_col_shift_tab = col_syn_shift[segm]; /* ptr init */ @@ -177,10 +175,10 @@ Word16 msvq_stage1_dct_search_fx( SHIFT( 1 ); ADD( 1 ); /* in BASOP: s_and(for W8->W16), shl(), sub()*/ #undef WMC_TOOL_SKIP - mse_fx = W_mac_32_32( mse_fx, tmp_fx, tmp_fx ); /* L_mac or L_mac0() square Word16 -> Word32*/ + mse_fx = W_mac_32_32( mse_fx, tmp_fx, tmp_fx ); /* L_mac or L_mac0() square Word16 -> Word32*/ // Q41 } Word16 L_tmp = W_norm( mse_fx ); - st1_mse_ptr_fx[j_full] = W_extract_h( W_lshl( mse_fx, L_tmp ) ); /* save MSE in shared dynamic RAM, move32() in BASOP */ + st1_mse_ptr_fx[j_full] = W_extract_h( W_lshl( mse_fx, L_tmp ) ); /* save MSE in shared dynamic RAM, move32() in BASOP */ // st1_mse_ptr_e move32(); st1_mse_ptr_e[j_full] = sub( shl( tmp_e, 1 ), L_tmp ); move16(); @@ -363,11 +361,11 @@ Word16 msvq_stage1_dct_search_fx( /*! r: (updated p_max) */ Word16 msvq_stage1_dct_recalc_candidates_fdcng_wb_fx( - const Word32 *st1_syn_vec_ptr_fx, /* i : IDCT24 synthesis vectors */ + const Word32 *st1_syn_vec_ptr_fx, /* i : IDCT24 synthesis vectors st1_syn_vec_e*/ const Word16 st1_syn_vec_e, /* i : exp for IDCT24 synthesis vectors */ - const Word32 *u_fx, /* i : target signal */ + const Word32 *u_fx, /* i : target signal u_e*/ const Word16 u_e, /* i : exp for target signal */ - const int16_t maxC_st1, /* i : number of candidates in stage1 */ + const Word16 maxC_st1, /* i : number of candidates in stage1 */ Word32 *dist_ptr_fx, /* i/o: updated MSE vector for stage1 */ Word16 *dist_ptr_e /* i/o: exp for updated MSE vector for stage1 */ ) @@ -391,7 +389,7 @@ Word16 msvq_stage1_dct_recalc_candidates_fdcng_wb_fx( /* for stage#1 use "u" instead of the shortened resid[0], to access the extended/extrapolated input target */ FOR( i = 0; i < FDCNG_VQ_MAX_LEN - FDCNG_VQ_MAX_LEN_WB; i++ ) { - high_diff_fx[i] = L_sub( L_shr( p2_fx[i], sub( tmp_e, st1_syn_vec_e ) ), L_shr( u_fx[FDCNG_VQ_MAX_LEN_WB + i], sub( tmp_e, u_e ) ) ); + high_diff_fx[i] = L_sub( L_shr( p2_fx[i], sub( tmp_e, st1_syn_vec_e ) ), L_shr( u_fx[FDCNG_VQ_MAX_LEN_WB + i], sub( tmp_e, u_e ) ) ); // tmp_e move32(); } acc = 0; @@ -458,7 +456,7 @@ void msvq_enc_ivas_fx( Word16 j; const Word16 *cbp, *cb_stage; Word32 resid_buf_fx[2 * LSFMBEST_MAX * M_MAX], *resid_fx[2]; - Word32 *pTmp, *p1, *p2; + Word32 *pTmp, *p1, *p2; // pTmp_e Word16 pTmp_e; Word16 *indices[2], m, s, c, c2, p_max, i; Word16 idx_buf[2 * LSFMBEST_MAX * MAX_VQ_STAGES_USED], parents[LSFMBEST_MAX]; @@ -737,7 +735,7 @@ void msvq_enc_ivas_fx( IF( cb_stage != NULL ) { // p2 = cb_stage + ( indices[1][c * stages + s] ) * maxn; /* regular ptr init */ - Copy_Scale_sig_16_32( cb_stage + ( indices[1][c * stages + s] ) * maxn, Tmp, N, 0 ); + Copy_Scale_sig_16_32_DEPREC( cb_stage + ( indices[1][c * stages + s] ) * maxn, Tmp, N, 0 ); scale_sig32( Tmp, N, sub( sub( Q31, Q_cb ), resid_e ) ); p2 = Tmp; } diff --git a/lib_enc/lsf_msvq_ma_enc_fx.c b/lib_enc/lsf_msvq_ma_enc_fx.c index 5e65218e5df99d3d8c6efb483cc49a740151f011..aa2255c68b1dbb7687dfb4be495a015286717a76 100644 --- a/lib_enc/lsf_msvq_ma_enc_fx.c +++ b/lib_enc/lsf_msvq_ma_enc_fx.c @@ -36,10 +36,10 @@ val2 = shr( ( cbp )[2], 4 ); \ val3 = add( add( shr( lshl( ( cbp )[2], 12 ), 4 ), lshr( lshl( ( cbp )[1], 12 ), 8 ) ), s_and( ( cbp )[0], 0xF ) ); /*--------------------------------------------------------------------------* - * depack_mul_values() + * depack_mul_values_fx() * *--------------------------------------------------------------------------*/ -static Word32 depack_mul_values( Word16 *Tmp, const Word16 *w, const Word16 *cbp, const Word16 N ) +static Word32 depack_mul_values_fx( Word16 *Tmp, const Word16 *w, const Word16 *cbp, const Word16 N ) { Word16 i, val0, val1, val2, val3; Word32 en; @@ -49,7 +49,6 @@ static Word32 depack_mul_values( Word16 *Tmp, const Word16 *w, const Word16 *cbp FOR( i = 0; i < N; i += 4 ) { depack_4_values( cbp + i_mult( shr( i, 2 ), 3 ), val0, val1, val2, val3 ) -#ifdef BASOP_NOGLOB Tmp[i + 0] = mult_r( shl_sat( w[i + 0], 2 ), val0 ); move16(); en = L_mac_sat( en, val0, Tmp[i + 0] ); @@ -62,20 +61,6 @@ static Word32 depack_mul_values( Word16 *Tmp, const Word16 *w, const Word16 *cbp Tmp[i + 3] = mult_r( shl_sat( w[i + 3], 2 ), val3 ); move16(); en = L_mac_sat( en, val3, Tmp[i + 3] ); -#else - Tmp[i + 0] = mult_r( shl( w[i + 0], 2 ), val0 ); - move16(); - en = L_mac( en, val0, Tmp[i + 0] ); - Tmp[i + 1] = mult_r( shl( w[i + 1], 2 ), val1 ); - move16(); - en = L_mac( en, val1, Tmp[i + 1] ); - Tmp[i + 2] = mult_r( shl( w[i + 2], 2 ), val2 ); - move16(); - en = L_mac( en, val2, Tmp[i + 2] ); - Tmp[i + 3] = mult_r( shl( w[i + 3], 2 ), val3 ); - move16(); - en = L_mac( en, val3, Tmp[i + 3] ); -#endif } return en; @@ -84,7 +69,7 @@ static Word32 depack_mul_values( Word16 *Tmp, const Word16 *w, const Word16 *cbp * depack_sub_values() * *--------------------------------------------------------------------------*/ -static void depack_sub_values( Word16 *pTmp, const Word16 *p1, const Word16 *cbp, const Word16 N ) +static void depack_sub_values_fx( Word16 *pTmp, const Word16 *p1, const Word16 *cbp, const Word16 N ) { Word16 j, val0, val1, val2, val3; @@ -108,7 +93,7 @@ static void depack_sub_values( Word16 *pTmp, const Word16 *p1, const Word16 *cbp * * Unroll of inner search loop for maxC == 8 *--------------------------------------------------------------------------*/ -static Word16 msvq_enc_find_p_max_8( Word32 dist[] ) +static Word16 msvq_enc_find_p_max_8_fx( Word32 dist[] ) { Word16 p_max; @@ -159,7 +144,7 @@ static Word16 msvq_enc_find_p_max_8( Word32 dist[] ) * * Unroll of inner search loop for maxC == 6 *--------------------------------------------------------------------------*/ -static Word16 msvq_enc_find_p_max_6( Word32 dist[] ) +static Word16 msvq_enc_find_p_max_6_fx( Word32 dist[] ) { Word16 p_max; @@ -209,7 +194,7 @@ void msvq_enc_fx( const Word16 maxC, /* i : Tree search size (number of candidates kept from */ /* one stage to the next == M-best) */ const Word16 stages, /* i : Number of stages */ - const Word16 w[], /* i : Weights */ + const Word16 w[], /* i : Weights Q8*/ const Word16 N, /* i : Vector dimension */ const Word16 maxN, /* i : Codebook dimension */ Word16 Idx[] /* o : Indices */ @@ -246,11 +231,11 @@ void msvq_enc_fx( set16_fx( parents, 0, maxC ); - func_ptr = msvq_enc_find_p_max_6; + func_ptr = msvq_enc_find_p_max_6_fx; move16(); if ( EQ_16( maxC, 8 ) ) { - func_ptr = msvq_enc_find_p_max_8; + func_ptr = msvq_enc_find_p_max_8_fx; move16(); } @@ -263,11 +248,7 @@ void msvq_enc_fx( move16(); FOR( j = 1; j < N; j++ ) { -#ifdef BASOP_NOGLOB ss2 = L_mac_sat( ss2, mult( u[j], shl_sat( w[j], 2 ) ), u[j] ); -#else - ss2 = L_mac( ss2, mult( u[j], shl( w[j], 2 ) ), u[j] ); -#endif } /* Set up inital error (residual) vectors */ @@ -345,7 +326,7 @@ void msvq_enc_fx( FOR( j = 0; j < levels[s]; j++ ) { /* Compute weighted codebook element and its energy */ - en = depack_mul_values( Tmp + start, w + start, cbp, n ); + en = depack_mul_values_fx( Tmp + start, w + start, cbp, n ); cbp += N34; /* pointer is incremented */ @@ -363,13 +344,8 @@ void msvq_enc_fx( BASOP_SATURATE_WARNING_OFF_EVS /*NOTE: as long as a shorter distance is found, saturation can be accepted.*/ -#ifdef BASOP_NOGLOB tmp = L_add_sat( dist[0][c], L_sub_sat( en, L_shl( t1, 1 ) ) ); t1 = L_sub_sat( tmp, dist[1][p_max] ); -#else - tmp = L_add( dist[0][c], L_sub( en, L_shl( t1, 1 ) ) ); - t1 = L_sub( tmp, dist[1][p_max] ); -#endif BASOP_SATURATE_WARNING_ON_EVS IF( t1 <= 0 ) @@ -402,7 +378,7 @@ void msvq_enc_fx( move16(); Copy( p1, pTmp, start ); - depack_sub_values( pTmp + start, p1 + start, &cb[s][p2i * N34], n ); + depack_sub_values_fx( pTmp + start, p1 + start, &cb[s][p2i * N34], n ); Copy( p1 + start + n, pTmp + start + n, sub( N, add( start, n ) ) ); pTmp += N; @@ -431,12 +407,12 @@ void msvq_enc_fx( *--------------------------------------------------------------------------*/ void midlsf_enc_fx( - const Word16 qlsf0[], /* i: quantized lsf coefficients (3Q12) */ - const Word16 qlsf1[], /* i: quantized lsf coefficients (3Q12) */ - const Word16 lsf[], /* i: lsf coefficients (3Q12) */ - Word16 *idx, /* o: codebook index */ - const Word16 lpcorder, /* i: order of the lpc */ - const Word32 *Bin_Ener_128_fx, + const Word16 qlsf0[], /* i: quantized lsf coefficients (3Q12) */ + const Word16 qlsf1[], /* i: quantized lsf coefficients (3Q12) */ + const Word16 lsf[], /* i: lsf coefficients (3Q12) */ + Word16 *idx, /* o: codebook index */ + const Word16 lpcorder, /* i: order of the lpc */ + const Word32 *Bin_Ener_128_fx, // Q_ener const Word16 Q_ener, const Word8 narrowBand, const Word32 sr_core, @@ -497,20 +473,11 @@ void midlsf_enc_fx( tmp = sub( lsf[j], qlsf[j] ); /* err += wghts[j] * ftemp * ftemp; */ /* tmp is usually very small, we can have some extra precision with very rare saturation */ -#ifdef BASOP_NOGLOB tmp = shl_o( tmp, 4, &Overflow ); tmp = mult_ro( tmp, tmp, &Overflow ); -#else /* BASOP_NOGLOB */ - tmp = shl( tmp, 4 ); - tmp = mult_r( tmp, tmp ); -#endif /* BASOP_NOGLOB */ err = L_mac( err, tmp, wghts[j] ); } -#ifdef BASOP_NOGLOB err = L_shl_o( err, 2, &Overflow ); -#else /* BASOP_NOGLOB */ - err = L_shl( err, 2 ); -#endif /* err = L_shl(err,Wscale); */ err = Mult_32_16( err, LSF_1_OVER_256SQ ); @@ -535,6 +502,158 @@ void midlsf_enc_fx( * Returns: number of indices *--------------------------------------------------------------------------*/ Word16 Q_lsf_tcxlpc_fx( + /* const */ Word16 lsf[], /* i : original lsf 14Q1 * 1.28 */ + Word16 lsf_q[], /* o : quantized lsf (14Q1*1.28)*/ + Word16 lsp_q_ind[], /* o : quantized lsp (w/o MA prediction) */ + Word16 indices[], /* o : VQ indices */ + const Word16 lpcorder, /* i : LPC order */ + const Word16 narrowband, /* i : narrowband flag */ + const Word16 cdk, /* i : codebook selector */ + const Word16 mem_MA[], /* i : MA memory */ + const Word16 coder_type, + const Word32 *Bin_Ener, // Q_ener + const Word16 Q_ener ) +{ + Word16 weights[M + 1]; + Word16 pred[M16k]; + Word16 i; + Word16 NumIndices; + Word16 lsf_q_ind[M16k]; + const Word16 *means; + Word16 lsf_rem[M]; + Word16 lsf_rem_q_ind[M]; + + Unified_weighting_fx( Bin_Ener, Q_ener, lsf, weights, narrowband, (Word16) EQ_16( coder_type, UNVOICED ), 12800, M ); + + move16(); + NumIndices = 0; + + /* Put disabled flag */ + indices[NumIndices] = 0; + move16(); + NumIndices = add( NumIndices, 1 ); + + /* Inter-frame prediction */ + + means = lsf_means[narrowband]; /* 14Q1 * 1.28 */ + + FOR( i = 0; i < lpcorder; ++i ) + { + pred[i] = add( means[i], mult_r( MU_MA_FX, mem_MA[i] ) ); /* 14Q1 * 1.28 + ( 14Q1 * 1.28 * Q15 ) = 14Q1 * 1.28*/ + } + + /* Subtract prediction */ + + FOR( i = 0; i < lpcorder; ++i ) + { + lsf[i] = sub( lsf[i], pred[i] ); /* 14Q1 * 1.28 */ + } + + + msvq_enc_fx( + lsf_codebook[narrowband][cdk], + lsf_dims, + lsf_offs, + lsf, + lsf_numlevels, + kMaxC, + TCXLPC_NUMSTAGES, + weights, + lpcorder, + lpcorder, + indices + NumIndices ); + msvq_dec( + lsf_codebook[narrowband][cdk], + lsf_dims, + lsf_offs, + TCXLPC_NUMSTAGES, + lpcorder, + lpcorder, + indices + NumIndices, +#ifdef IVAS_MSVQ + 0, NULL, +#endif + lsf_q ); + NumIndices = add( NumIndices, TCXLPC_NUMSTAGES ); + + FOR( i = 0; i < lpcorder; ++i ) + { + lsf_q_ind[i] = lsf_q[i]; /*(14Q1*1.28)*/ + move16(); + } + + /* Update flag */ + indices[0] = lsf_ind_is_active( lsf_q_ind, lsf_means[narrowband], narrowband, cdk ); + move16(); + + /* Get residual vector */ + FOR( i = 0; i < lpcorder; ++i ) + { + lsf_rem[i] = add( sub( pred[i], lsf_means[narrowband][i] ), sub( lsf[i], lsf_q_ind[i] ) ); + } + + /* Quantize using extra stage(s) */ + msvq_enc_fx( + lsf_ind_codebook[narrowband][cdk], + lsf_ind_dims, + lsf_ind_offs, + lsf_rem, + lsf_ind_numlevels, + kMaxC, + TCXLPC_IND_NUMSTAGES, + weights, + lpcorder, + lpcorder, + indices + NumIndices ); + /* Only add contribution if flag is enabled */ + IF( indices[0] ) + { + /* Decode */ + msvq_dec( + lsf_ind_codebook[narrowband][cdk], + lsf_ind_dims, + lsf_ind_offs, + TCXLPC_IND_NUMSTAGES, + lpcorder, + lpcorder, + indices + NumIndices, +#ifdef IVAS_MSVQ + 0, NULL, +#endif + lsf_rem_q_ind ); + NumIndices = add( NumIndices, TCXLPC_IND_NUMSTAGES ); + + /* Add to MA-removed vector */ + FOR( i = 0; i < lpcorder; ++i ) + { + lsf_q_ind[i] = add( lsf_q_ind[i], lsf_rem_q_ind[i] ); + } + } + + /* Add inter-frame prediction */ + FOR( i = 0; i < lpcorder; ++i ) + { + lsf_q[i] = add( lsf_q[i], pred[i] ); + lsf[i] = add( lsf[i], pred[i] ); + } + + reorder_lsf_fx( lsf_q, TCXLPC_LSF_GAP, lpcorder, INT_FS_FX ); + + FOR( i = 0; i < lpcorder; ++i ) + { + lsf_q_ind[i] = add( lsf_q_ind[i], lsf_means[narrowband][i] ); + } + reorder_lsf_fx( lsf_q_ind, TCXLPC_LSF_GAP, lpcorder, INT_FS_FX ); + + IF( lsp_q_ind ) + { + E_LPC_lsf_lsp_conversion /*lsf2lsp*/ ( lsf_q_ind, lsp_q_ind, lpcorder ); + } + + return NumIndices; +} + +Word16 Q_lsf_tcxlpc_ivas_fx( /* const */ Word16 lsf[], /* i : original lsf */ Word16 lsf_q[], /* o : quantized lsf */ Word16 lsp_q_ind[], /* o : quantized lsp (w/o MA prediction) */ @@ -556,7 +675,7 @@ Word16 Q_lsf_tcxlpc_fx( Word16 lsf_rem[M]; Word16 lsf_rem_q_ind[M]; - Unified_weighting_fx( Bin_Ener, Q_ener, lsf, weights, narrowband, (Word16) EQ_16( coder_type, UNVOICED ), 12800, M ); + Unified_weighting_fx( &Bin_Ener[L_FFT / 2], Q_ener, lsf, weights, narrowband, (Word16) EQ_16( coder_type, UNVOICED ), 12800, M ); move16(); NumIndices = 0; @@ -573,6 +692,7 @@ Word16 Q_lsf_tcxlpc_fx( FOR( i = 0; i < lpcorder; ++i ) { pred[i] = add( means[i], mult_r( MU_MA_FX, mem_MA[i] ) ); /* 14Q1 * 1.28 + ( 14Q1 * 1.28 * Q15 ) = 14Q1 * 1.28*/ + move16(); } /* Subtract prediction */ @@ -580,6 +700,7 @@ Word16 Q_lsf_tcxlpc_fx( FOR( i = 0; i < lpcorder; ++i ) { lsf[i] = sub( lsf[i], pred[i] ); /* 14Q1 * 1.28 */ + move16(); } @@ -623,6 +744,7 @@ Word16 Q_lsf_tcxlpc_fx( FOR( i = 0; i < lpcorder; ++i ) { lsf_rem[i] = add( sub( pred[i], lsf_means[narrowband][i] ), sub( lsf[i], lsf_q_ind[i] ) ); + move16(); } /* Quantize using extra stage(s) */ @@ -660,6 +782,7 @@ Word16 Q_lsf_tcxlpc_fx( FOR( i = 0; i < lpcorder; ++i ) { lsf_q_ind[i] = add( lsf_q_ind[i], lsf_rem_q_ind[i] ); + move16(); } } @@ -668,6 +791,8 @@ Word16 Q_lsf_tcxlpc_fx( { lsf_q[i] = add( lsf_q[i], pred[i] ); lsf[i] = add( lsf[i], pred[i] ); + move16(); + move16(); } reorder_lsf_fx( lsf_q, TCXLPC_LSF_GAP, lpcorder, INT_FS_FX ); @@ -675,6 +800,7 @@ Word16 Q_lsf_tcxlpc_fx( FOR( i = 0; i < lpcorder; ++i ) { lsf_q_ind[i] = add( lsf_q_ind[i], lsf_means[narrowband][i] ); + move16(); } reorder_lsf_fx( lsf_q_ind, TCXLPC_LSF_GAP, lpcorder, INT_FS_FX ); @@ -765,7 +891,7 @@ Word16 enc_lsf_tcxlpc_ivas_fx( Word16 lsf_msvq_ma_encprm_fx( BSTR_ENC_HANDLE hBstr, - Word16 *param_lpc, + Word16 *param_lpc, // Q0 Word16 core, Word16 acelp_mode, Word16 acelp_midLpc, @@ -790,7 +916,7 @@ Word16 lsf_msvq_ma_encprm_fx( IF( NE_16( acelp_mode, VOICED ) ) { test(); - IF( EQ_16( core, ACELP_CORE ) && acelp_midLpc ) + IF( ( core == ACELP_CORE ) && acelp_midLpc ) { push_next_indice_fx( hBstr, *param_lpc, bits_midlpc ); @@ -802,7 +928,7 @@ Word16 lsf_msvq_ma_encprm_fx( } Word16 lsf_msvq_ma_encprm_ivas_fx( BSTR_ENC_HANDLE hBstr, - const Word16 *param_lpc, + const Word16 *param_lpc, // Q0 const Word16 core, const Word16 acelp_mode, const Word16 acelp_midLpc, @@ -827,7 +953,7 @@ Word16 lsf_msvq_ma_encprm_ivas_fx( IF( NE_16( acelp_mode, VOICED ) ) { test(); - IF( EQ_16( core, ACELP_CORE ) && acelp_midLpc ) + IF( ( core == ACELP_CORE ) && acelp_midLpc ) { push_next_indice( hBstr, *param_lpc, bits_midlpc ); @@ -845,7 +971,7 @@ Word16 lsf_msvq_ma_encprm_ivas_fx( *--------------------------------------------------------------------------*/ Word16 lsf_bctcvq_encprm_fx( BSTR_ENC_HANDLE hBstr, - Word16 *param_lpc, + Word16 *param_lpc, // Q0 Word16 *bits_param_lpc, Word16 no_indices ) { @@ -864,7 +990,7 @@ Word16 lsf_bctcvq_encprm_fx( } Word16 lsf_bctcvq_encprm_ivas_fx( BSTR_ENC_HANDLE hBstr, - const Word16 *param_lpc, + const Word16 *param_lpc, // Q0 const Word16 *bits_param_lpc, const Word16 no_indices ) { diff --git a/lib_enc/ltd_stable.c b/lib_enc/ltd_stable.c deleted file mode 100644 index 825401325748d89d4db5894372ff8dd2e53d76ec..0000000000000000000000000000000000000000 --- a/lib_enc/ltd_stable.c +++ /dev/null @@ -1,41 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include -#include "prot.h" -#include "wmc_auto.h" diff --git a/lib_enc/ltd_stable_fx.c b/lib_enc/ltd_stable_fx.c index 63ade58a8ce9eddacd3fb3d852aa0415ca57b67b..036fe2a7e82b382fd7e8a48723a567799aa62e39 100644 --- a/lib_enc/ltd_stable_fx.c +++ b/lib_enc/ltd_stable_fx.c @@ -21,7 +21,7 @@ void ltd_stable_fx( VAD_CLDFB_HANDLE hVAD_CLDFB, /* i/o: CLDFB VAD state */ Word16 *ltd_stable_rate, /* o : time-domain stable rate*/ - const Word32 frame_energy, /* i : current frame energy*/ + const Word32 frame_energy, /* i : current frame energy Q_frames_power*/ const Word16 frameloop, /* i : amount of frames*/ const Word16 Q_frames_power /* i : the Scaling of frames_power*/ ) @@ -57,7 +57,7 @@ void ltd_stable_fx( move16(); Q_apow = 0; move16(); - frames_power_32 = hVAD_CLDFB->frames_power_32; + frames_power_32 = hVAD_CLDFB->frames_power_32; // Q_frames_power_last_32 Q_frames_power_last_32 = hVAD_CLDFB->Q_frames_power_32; move16(); leadingzero_midamp = 31; @@ -76,7 +76,7 @@ void ltd_stable_fx( IF( GE_16( Q_frames_power32, 40 ) ) { zerop001 = L_shr( CNT0P001, 1 ); - frame_energy_Sqr32 = L_shr( frame_energy_Sqr32, sub( Q_frames_power32, 39 ) ); + frame_energy_Sqr32 = L_shr( frame_energy_Sqr32, sub( Q_frames_power32, 39 ) ); // Q_frames_power32 Q_frames_power32 = 39; move16(); } @@ -86,14 +86,14 @@ void ltd_stable_fx( frame_energy_Sqr32 = L_shr( frame_energy_Sqr32, 1 ); zerop001 = L_shr( CNT0P001, sub( 40, Q_frames_power32 ) ); } - frames_power_32[0] = L_add( frame_energy_Sqr32, zerop001 ); + frames_power_32[0] = L_add( frame_energy_Sqr32, zerop001 ); // Q_frames_power32 move32(); IF( LT_16( frameloop, 3 ) ) { FOR( i = 1; i < 40; i++ ) { - frames_power_32[i] = frames_power_32[0]; + frames_power_32[i] = frames_power_32[0]; // Q_frames_power32 move32(); } } @@ -104,7 +104,7 @@ void ltd_stable_fx( move32(); FOR( i = 1; i < 40; i++ ) { - maxVal = L_max( maxVal, frames_power_32[i] ); + maxVal = L_max( maxVal, frames_power_32[i] ); // Q_frames_power32 } leadingzero = 31; move16(); @@ -119,7 +119,7 @@ void ltd_stable_fx( scale1 = sub( scale1, leadingzero ); FOR( i = 1; i < 40; i++ ) { - frames_power_32[i] = L_shr( frames_power_32[i], scale1 ); + frames_power_32[i] = L_shr( frames_power_32[i], scale1 ); // Q_frames_power32 move32(); } } @@ -140,7 +140,7 @@ void ltd_stable_fx( FOR( i = 0; i < 20; i++ ) { - mid_frame_ampadd32[i] = L_add( L_shr( frames_power_32[2 * i], 1 ), L_shr( frames_power_32[2 * i + 1], 1 ) ); + mid_frame_ampadd32[i] = L_add( L_shr( frames_power_32[2 * i], 1 ), L_shr( frames_power_32[2 * i + 1], 1 ) ); // Q_frames_power32 move32(); } @@ -148,16 +148,18 @@ void ltd_stable_fx( move32(); FOR( i = 0; i < 20; i++ ) { - maxVal = L_max( maxVal, mid_frame_ampadd32[i] ); + maxVal = L_max( maxVal, mid_frame_ampadd32[i] ); // Q_frames_power32 } leadingzero_midamp = 31; move16(); if ( maxVal ) + { leadingzero_midamp = norm_l( maxVal ); + } FOR( i = 0; i < 20; i++ ) { - mid_frame_amp32[i] = L_shl( mid_frame_ampadd32[i], leadingzero_midamp ); + mid_frame_amp32[i] = L_shl( mid_frame_ampadd32[i], leadingzero_midamp ); // Q_frames_power32 + leadingzero_midamp move32(); } @@ -165,19 +167,19 @@ void ltd_stable_fx( move32(); FOR( i = 0; i < 20; i++ ) { - seg_amp32 = L_add( seg_amp32, L_shr( mid_frame_amp32[i], 5 ) ); + seg_amp32 = L_add( seg_amp32, L_shr( mid_frame_amp32[i], 5 ) ); // Q_frames_power32 + leadingzero_midamp - 5 } - seg_amp32 = MUL_F( seg_amp32, 0x0666 ); + seg_amp32 = MUL_F( seg_amp32, 0x0666 /*(1/20).Q15*/ ); dif32 = 0; move32(); apow32 = 0; move32(); - seg_amp32tmp = L_shl( seg_amp32, 5 ); + seg_amp32tmp = L_shl( seg_amp32, 5 ); // Q_frames_power32 + leadingzero_midamp FOR( i = 0; i < 20; i++ ) { - tmp32[i] = L_sub( mid_frame_amp32[i], seg_amp32tmp ); + tmp32[i] = L_sub( mid_frame_amp32[i], seg_amp32tmp ); // Q_frames_power32 + leadingzero_midamp move32(); } @@ -185,26 +187,24 @@ void ltd_stable_fx( move32(); FOR( i = 0; i < 20; i++ ) { - maxVal = L_max( maxVal, L_abs( tmp32[i] ) ); + maxVal = L_max( maxVal, L_abs( tmp32[i] ) ); // Q_frames_power32 + leadingzero_midamp - 5 } leadingzero_tmp32 = 31; move16(); if ( maxVal ) + { leadingzero_tmp32 = norm_l( maxVal ); + } FOR( i = 0; i < 20; i++ ) { - tmp16[i] = extract_h( L_shl( tmp32[i], leadingzero_tmp32 ) ); + tmp16[i] = extract_h( L_shl( tmp32[i], leadingzero_tmp32 ) ); //// Q_frames_power32 + leadingzero_midamp + leadingzero_tmp32 - 16 } FOR( i = 0; i < 20; i++ ) { -#ifdef BASOP_NOGLOB - tmp_mul = L_mult_sat( tmp16[i], tmp16[i] ); -#else - tmp_mul = L_mult( tmp16[i], tmp16[i] ); -#endif - tmp_mul = L_shr( tmp_mul, 5 ); + tmp_mul = L_mult_sat( tmp16[i], tmp16[i] ); // 2 * (Q_frames_power32 + leadingzero_midamp + leadingzero_tmp32 - 16) + 1 + tmp_mul = L_shr( tmp_mul, 5 ); // 2 * (Q_frames_power32 + leadingzero_midamp + leadingzero_tmp32 - 16) - 4 dif32 = L_add( dif32, tmp_mul ); tmp = extract_h( mid_frame_amp32[i] ); @@ -248,7 +248,9 @@ void ltd_stable_fx( leadingzero_midamp = 31; move16(); if ( maxVal ) + { leadingzero_midamp = norm_l( maxVal ); + } FOR( i = 0; i < 14; i++ ) { @@ -260,15 +262,15 @@ void ltd_stable_fx( move32(); FOR( i = 0; i < 14; i++ ) { - seg_amp32 = L_add( seg_amp32, L_shr( mid_frame_amp32[i], 4 ) ); + seg_amp32 = L_add( seg_amp32, L_shr( mid_frame_amp32[i], 4 ) ); // Q_frames_power32 - 4 } - seg_amp32 = MUL_F( seg_amp32, 0x0924 ); + seg_amp32 = MUL_F( seg_amp32, 0x0924 /*(1/14).Q15*/ ); dif32 = 0; move32(); apow32 = 0; move32(); - seg_amp32tmp = L_shl( seg_amp32, 4 ); + seg_amp32tmp = L_shl( seg_amp32, 4 ); // Q_frames_power32 FOR( i = 0; i < 14; i++ ) { tmp32[i] = L_sub( mid_frame_amp32[i], seg_amp32tmp ); @@ -284,7 +286,9 @@ void ltd_stable_fx( leadingzero_tmp32 = 31; move16(); if ( maxVal ) + { leadingzero_tmp32 = norm_l( maxVal ); + } FOR( i = 0; i < 14; i++ ) { @@ -295,11 +299,7 @@ void ltd_stable_fx( FOR( i = 0; i < 14; i++ ) { tmp = extract_h( tmp32[i] ); -#ifdef BASOP_NOGLOB tmp_mul = L_mult_sat( tmp, tmp ); -#else - tmp_mul = L_mult( tmp, tmp ); -#endif tmp_mul = L_shr( tmp_mul, 4 ); dif32 = L_add( dif32, tmp_mul ); @@ -375,8 +375,10 @@ void ltd_stable_fx( } leadingzero_midamp = 31; move16(); - if ( maxVal ) + IF( maxVal ) + { leadingzero_midamp = norm_l( maxVal ); + } FOR( i = 0; i < 8; i++ ) { @@ -390,7 +392,7 @@ void ltd_stable_fx( { seg_amp32 = L_add( seg_amp32, L_shr( mid_frame_amp32[i], 3 ) ); } - seg_amp32 = MUL_F( seg_amp32, 0x1000 ); + seg_amp32 = MUL_F( seg_amp32, 0x1000 /*(1/8).Q15*/ ); dif32 = 0; move32(); @@ -411,9 +413,10 @@ void ltd_stable_fx( } leadingzero_tmp32 = 31; move16(); - if ( maxVal ) + IF( maxVal ) + { leadingzero_tmp32 = norm_l( maxVal ); - + } FOR( i = 0; i < 8; i++ ) { tmp32[i] = L_shl( tmp32[i], leadingzero_tmp32 ); @@ -423,20 +426,12 @@ void ltd_stable_fx( FOR( i = 0; i < 8; i++ ) { tmp = extract_h( tmp32[i] ); -#ifdef BASOP_NOGLOB tmp_mul = L_mult_sat( tmp, tmp ); -#else - tmp_mul = L_mult( tmp, tmp ); -#endif tmp_mul = L_shr( tmp_mul, 3 ); dif32 = L_add( dif32, tmp_mul ); tmp = extract_h( mid_frame_amp32[i] ); -#ifdef BASOP_NOGLOB mid_frame_amp_mul = L_mult_sat( tmp, tmp ); -#else - mid_frame_amp_mul = L_mult( tmp, tmp ); -#endif mid_frame_amp_mul = L_shr( mid_frame_amp_mul, 3 ); apow32 = L_add( apow32, mid_frame_amp_mul ); } @@ -498,7 +493,7 @@ void ltd_stable_fx( ltd_stable_rate[2] = shr( ltd_stable_rate[2], ltd_stable_rate_Qtmp ); move16(); - ltd_stable_rate[3] = add( mult( ltd_stable_rate[3], 0x7333 ), mult( ltd_stable_rate[2], 0x0ccc ) ); + ltd_stable_rate[3] = add( mult( ltd_stable_rate[3], 0x7333 /*0.9.Q15*/ ), mult( ltd_stable_rate[2], 0x0ccc /*0.1.Q15*/ ) ); move16(); FOR( i = 55; i > 0; i-- ) diff --git a/lib_enc/mdct_classifier.c b/lib_enc/mdct_classifier.c deleted file mode 100644 index b157e0ff9c551ecdad0373734e433d1d168869fe..0000000000000000000000000000000000000000 --- a/lib_enc/mdct_classifier.c +++ /dev/null @@ -1,43 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include "cnst.h" -#include "prot.h" -#include "wmc_auto.h" -#include -#include "ivas_prot_fx.h" diff --git a/lib_enc/mdct_classifier_fx.c b/lib_enc/mdct_classifier_fx.c index 51fe086df0a7fd3d7931e10beb8daa5d01f20c0c..a4e19e0400c7da71ab98c14c25a732eecc3a692f 100644 --- a/lib_enc/mdct_classifier_fx.c +++ b/lib_enc/mdct_classifier_fx.c @@ -9,7 +9,6 @@ #include "rom_com.h" #include "prot_fx.h" /* Function prototypes */ #include "prot_fx_enc.h" /* Function prototypes */ -#include "prot_fx.h" /* Function prototypes */ #include "prot_fx_enc.h" /* Function prototypes */ #include "ivas_prot_fx.h" /* Function prototypes */ @@ -47,7 +46,7 @@ * Square magnitude of fft spectrum *----------------------------------------------------------------------------*/ static void dft_mag_square_fx( - const Word16 x[], /* i : Input vector: re[0], re[1], ..., re[n/2], im[n/2 - 1], im[n/2 - 2], ..., im[1] */ + const Word16 x[], /* i : Input vector: re[0], re[1], ..., re[n/2], im[n/2 - 1], im[n/2 - 2], ..., im[1] Qx*/ Word32 magSq[], /* o : Magnitude square spectrum */ const Word16 n /* i : Input vector length */ ) @@ -58,7 +57,7 @@ static void dft_mag_square_fx( /* Magnitude square at 0. */ pMagSq = &magSq[0]; - pRe = &x[0]; + pRe = &x[0]; // Qx *pMagSq++ = L_mult0( *pRe, *pRe ); pRe++; move32(); @@ -71,13 +70,13 @@ static void dft_mag_square_fx( { acc = L_mult0( *pRe, *pRe ); pRe++; - *pMagSq++ = L_mac0( acc, *pIm, *pIm ); + *pMagSq++ = L_mac0( acc, *pIm, *pIm ); // 2*Qx pIm--; move32(); } /* The magnitude square at N/2 */ - *pMagSq = L_mult0( *pRe, *pRe ); + *pMagSq = L_mult0( *pRe, *pRe ); // 2*Qx move32(); return; } @@ -90,7 +89,7 @@ static void dft_mag_square_fx( Word16 mdct_classifier_fx( /* o: MDCT A/B decision */ const Word16 *fft_buff, /* i: re[0], re[1], ..., re[n/2], im[n/2 - 1], im[n/2 - 2], ..., im[1] */ Encoder_State *st_fx, /* i/o: Encoder state variable */ - Word32 *cldfbBuf_Ener, + Word32 *cldfbBuf_Ener, // enerBuffer_exp Word16 enerBuffer_exp, const Word32 brate /* i : current brate, IVAS: nominal bitrate, EVS: st->total_brate */ ) @@ -261,7 +260,7 @@ Word16 mdct_classifier_fx( /* o: MDCT A/B decision { IF( max_i > 0 ) { - IF( GT_16( np, 0 ) ) + IF( ( np > 0 ) ) { d_acc = sub( add( d_acc, max_i ), pos_last ); } @@ -278,7 +277,7 @@ Word16 mdct_classifier_fx( /* o: MDCT A/B decision IF( pe != 0 ) { expo = norm_l( pe ); - man = L_shl( pe, expo ); + man = L_shl( pe, expo ); // expo Mpy_32_32_ss( man, man, &man, &lsb32 ); /* pe square */ expo = shl( expo, 1 ); /* Multiply by 2 due to squaring. */ floating_point_add( &p_energy_man, &p_energy_exp, man, expo ); @@ -310,35 +309,35 @@ Word16 mdct_classifier_fx( /* o: MDCT A/B decision /* gain11 = 8*(gain1 - cldfbBuf_Ener[0]/8)/7; */ acc = L_shr( cldfbBuf_Ener[0], 3 ); acc = L_sub( gain1, acc ); - acc = Mult_32_16( acc, 4681 ); + acc = Mult_32_16( acc, 4681 /*(1/7).Q15*/ ); gain11 = L_shl( acc, 3 ); gain4 = L_deposit_l( 0 ); FOR( k = 0; k < 12; k++ ) { - gain4 = L_add( gain4, Mult_32_16( cldfbBuf_Ener[k + 12], 2731 ) ); + gain4 = L_add( gain4, Mult_32_16( cldfbBuf_Ener[k + 12], 2731 /*(1/12).Q15*/ ) ); } peak_H1 = L_add( cldfbBuf_Ener[25], 0 ); - Mpy_32_16_ss( cldfbBuf_Ener[25], 6554, &avrg_H1, &lsb16 ); + Mpy_32_16_ss( cldfbBuf_Ener[25], 6554 /*0.4.Q15*/, &avrg_H1, &lsb16 ); FOR( k = 1; k < 5; k++ ) { IF( GT_32( cldfbBuf_Ener[k + 25], peak_H1 ) ) { peak_H1 = L_add( cldfbBuf_Ener[k + 25], 0 ); } - avrg_H1 = L_add( avrg_H1, Mult_32_16( cldfbBuf_Ener[k + 25], 6554 ) ); + avrg_H1 = L_add( avrg_H1, Mult_32_16( cldfbBuf_Ener[k + 25], 6554 /*0.4.Q15*/ ) ); } peak_H2 = L_add( cldfbBuf_Ener[20], 0 ); - Mpy_32_16_ss( cldfbBuf_Ener[20], 6554, &avrg_H2, &lsb16 ); + Mpy_32_16_ss( cldfbBuf_Ener[20], 6554 /*0.4.Q15*/, &avrg_H2, &lsb16 ); FOR( k = 1; k < 5; k++ ) { IF( GT_32( cldfbBuf_Ener[k + 20], peak_H2 ) ) { peak_H2 = L_add( cldfbBuf_Ener[k + 20], 0 ); } - avrg_H2 = L_add( avrg_H2, Mult_32_16( cldfbBuf_Ener[k + 20], 6554 ) ); + avrg_H2 = L_add( avrg_H2, Mult_32_16( cldfbBuf_Ener[k + 20], 6554 /*0.4.Q15*/ ) ); } // End peak_l = L_deposit_l( 0 ); @@ -401,7 +400,7 @@ Word16 mdct_classifier_fx( /* o: MDCT A/B decision condition4 = 0; move16(); - L_tmp = Mult_32_16( peak_h, 12603 ); + L_tmp = Mult_32_16( peak_h, 12603 /*1/2.56.Q15*/ ); IF( GT_32( peak_l, L_tmp ) ) { exp = norm_l( peak_l ); @@ -419,7 +418,7 @@ Word16 mdct_classifier_fx( /* o: MDCT A/B decision exp1 = norm_l( avrg_l ); } - L_tmp1 = Mult_32_16( peak_l, 12603 ); + L_tmp1 = Mult_32_16( peak_l, 12603 /*1/2.56.Q15*/ ); IF( GT_32( peak_h, L_tmp1 ) ) { exp2 = norm_l( peak_h ); @@ -433,17 +432,13 @@ Word16 mdct_classifier_fx( /* o: MDCT A/B decision test(); test(); test(); -#ifdef BASOP_NOGLOB IF( GT_32( Mult_32_16( gain3, 27307 ), gain2 ) || ( GE_32( gain3, Mult_32_16( gain2, 26214 ) ) && GT_32( peak_H1, L_shl_o( avrg_H1, 1, &Overflow ) ) ) || ( LT_32( Mult_32_32( L_shl_o( peak_l, exp, &Overflow ), L_shl_o( avrg_h, exp1, &Overflow ) ), Mult_32_32( L_shl_o( L_tmp, exp, &Overflow ), L_shl_o( avrg_l, exp1, &Overflow ) ) ) || GT_32( Mult_32_32( L_shl_o( L_tmp1, exp2, &Overflow ), L_shl_o( avrg_h, exp1, &Overflow ) ), Mult_32_32( L_shl_o( peak_h, exp2, &Overflow ), L_shl_o( avrg_l, exp1, &Overflow ) ) ) ) ) -#else - IF( GT_32( Mult_32_16( gain3, 27307 ), gain2 ) || ( GE_32( gain3, Mult_32_16( gain2, 26214 ) ) && GT_32( peak_H1, L_shl( avrg_H1, 1 ) ) ) || ( LT_32( Mult_32_32( L_shl( peak_l, exp ), L_shl( avrg_h, exp1 ) ), Mult_32_32( L_shl( L_tmp, exp ), L_shl( avrg_l, exp1 ) ) ) || GT_32( Mult_32_32( L_shl( L_tmp1, exp2 ), L_shl( avrg_h, exp1 ) ), Mult_32_32( L_shl( peak_h, exp2 ), L_shl( avrg_l, exp1 ) ) ) ) ) -#endif { condition3 = 1; move16(); } - L_tmp = Mult_32_16( peak_h, 12800 ); + L_tmp = Mult_32_16( peak_h, 12800 /*(1/2.56).Q15*/ ); IF( GT_32( peak_l, L_tmp ) ) { exp = norm_l( peak_l ); @@ -453,7 +448,7 @@ Word16 mdct_classifier_fx( /* o: MDCT A/B decision exp = norm_l( L_tmp ); } - L_tmp1 = Mult_32_16( peak_l, 6400 ); + L_tmp1 = Mult_32_16( peak_l, 6400 /*(1/5.12).Q15*/ ); IF( GT_32( peak_h, L_tmp1 ) ) { exp2 = norm_l( peak_h ); @@ -481,7 +476,7 @@ Word16 mdct_classifier_fx( /* o: MDCT A/B decision test(); test(); test(); - IF( ( GT_32( gain4, Mult_32_16( gain11, 26214 ) ) && GT_32( Mult_32_32( L_shl( peak_l, exp ), L_shl( avrg_h, exp1 ) ), Mult_32_32( L_shl( Mult_32_16( peak_h, 12800 ), exp ), L_shl( avrg_l, exp1 ) ) ) && LT_32( Mult_32_32( L_shl( Mult_32_16( peak_l, 6400 ), exp2 ), L_shl( avrg_h, exp1 ) ), Mult_32_32( L_shl( peak_h, exp2 ), L_shl( avrg_l, exp1 ) ) ) ) || ( GT_32( gain4, Mult_32_16( gain11, 9830 ) ) && LT_32( Mult_32_16( peak_h, 21845 ), avrg_h ) && LT_32( Mult_32_16( peak_H2, 21845 ), avrg_H2 ) ) || ( LT_32( Mult_32_32( L_shl( peak_l, exp ), L_shl( avrg_h, exp1 ) ), Mult_32_32( L_shl( Mult_32_16( peak_h, 12800 ), exp ), L_shl( avrg_l, exp1 ) ) ) && GT_32( Mult_32_16( peak_h, 21845 ), avrg_h ) ) || ( GT_32( Mult_32_32( L_shl( Mult_32_16( peak_l, 12800 ), exp3 ), L_shl( avrg_h, exp1 ) ), Mult_32_32( L_shl( peak_h, exp3 ), L_shl( avrg_l, exp1 ) ) ) > 0 && LT_32( Mult_32_16( peak_h, 21845 ), avrg_h ) ) ) + IF( ( GT_32( gain4, Mult_32_16( gain11, 26214 /*0.8.Q15*/ ) ) && GT_32( Mult_32_32( L_shl( peak_l, exp ), L_shl( avrg_h, exp1 ) ), Mult_32_32( L_shl( Mult_32_16( peak_h, 12800 /*(1/2.56).Q15*/ ), exp ), L_shl( avrg_l, exp1 ) ) ) && LT_32( Mult_32_32( L_shl( Mult_32_16( peak_l, 6400 /*(1/5.12).Q15*/ ), exp2 ), L_shl( avrg_h, exp1 ) ), Mult_32_32( L_shl( peak_h, exp2 ), L_shl( avrg_l, exp1 ) ) ) ) || ( GT_32( gain4, Mult_32_16( gain11, 9830 /*0.3.Q15*/ ) ) && LT_32( Mult_32_16( peak_h, 21845 /*(1/1.5).Q15*/ ), avrg_h ) && LT_32( Mult_32_16( peak_H2, 21845 /*(1/1.5).Q15*/ ), avrg_H2 ) ) || ( LT_32( Mult_32_32( L_shl( peak_l, exp ), L_shl( avrg_h, exp1 ) ), Mult_32_32( L_shl( Mult_32_16( peak_h, 12800 /*(1/2.56).Q15*/ ), exp ), L_shl( avrg_l, exp1 ) ) ) && GT_32( Mult_32_16( peak_h, 21845 /*(1/1.5).Q15*/ ), avrg_h ) ) || ( GT_32( Mult_32_32( L_shl( Mult_32_16( peak_l, 12800 /*(1/2.56).Q15*/ ), exp3 ), L_shl( avrg_h, exp1 ) ), Mult_32_32( L_shl( peak_h, exp3 ), L_shl( avrg_l, exp1 ) ) ) > 0 && LT_32( Mult_32_16( peak_h, 21845 /*(1/1.5).Q15*/ ), avrg_h ) ) ) { condition4 = 1; move16(); @@ -503,21 +498,21 @@ Word16 mdct_classifier_fx( /* o: MDCT A/B decision } /* Smooth decision from instantaneous decision*/ - acc = L_mult( hTcxEnc->clas_sec_old_fx, MDCT_CLASSIFER_SMOOTH_FILT_COEFF ); /* st_fx->clas_sec_old_fx in Q13 */ - clas_sec = mac_r( acc, c, 0x7fff - MDCT_CLASSIFER_SMOOTH_FILT_COEFF ); /* clas_sec and c are in Q13 */ + acc = L_mult( hTcxEnc->clas_sec_old_fx, MDCT_CLASSIFER_SMOOTH_FILT_COEFF ); /* st_fx->clas_sec_old_fx in Q13 */ + clas_sec = mac_r( acc, c, 0x7fff /*1.Q15*/ - MDCT_CLASSIFER_SMOOTH_FILT_COEFF ); /* clas_sec and c are in Q13 */ /* Do thresholding with hysteresis */ IF( GT_16( st_fx->last_enerBuffer_exp, enerBuffer_exp ) ) { - gain1_tmp = L_shr( gain1, sub( st_fx->last_enerBuffer_exp, enerBuffer_exp ) ); + gain1_tmp = L_shr( gain1, sub( st_fx->last_enerBuffer_exp, enerBuffer_exp ) ); // st_fx->last_enerBuffer_exp move32(); - gain2_tmp = L_shr( gain2, sub( st_fx->last_enerBuffer_exp, enerBuffer_exp ) ); + gain2_tmp = L_shr( gain2, sub( st_fx->last_enerBuffer_exp, enerBuffer_exp ) ); // st_fx->last_enerBuffer_exp move32(); } ELSE { - hTcxEnc->last_gain1 = L_shr( hTcxEnc->last_gain1, sub( enerBuffer_exp, st_fx->last_enerBuffer_exp ) ); + hTcxEnc->last_gain1 = L_shr( hTcxEnc->last_gain1, sub( enerBuffer_exp, st_fx->last_enerBuffer_exp ) ); // enerBuffer_exp move32(); - hTcxEnc->last_gain2 = L_shr( hTcxEnc->last_gain2, sub( enerBuffer_exp, st_fx->last_enerBuffer_exp ) ); + hTcxEnc->last_gain2 = L_shr( hTcxEnc->last_gain2, sub( enerBuffer_exp, st_fx->last_enerBuffer_exp ) ); // enerBuffer_exp move32(); gain1_tmp = gain1; move32(); @@ -531,11 +526,7 @@ Word16 mdct_classifier_fx( /* o: MDCT A/B decision test(); test(); test(); -#ifdef BASOP_NOGLOB IF( ( EQ_16( hTcxEnc->clas_final_old, HQ_CORE ) || EQ_16( hTcxEnc->clas_final_old, TCX_20_CORE ) ) && ( ( GT_32( hTcxEnc->last_gain1, L_shr( gain1_tmp, 1 ) ) && LT_32( hTcxEnc->last_gain1, L_shl_o( gain1_tmp, 1, &Overflow ) ) ) && ( GT_32( hTcxEnc->last_gain2, L_shr( gain2_tmp, 1 ) ) && LT_32( hTcxEnc->last_gain2, L_shl_o( gain2_tmp, 1, &Overflow ) ) ) ) ) -#else - IF( ( EQ_16( hTcxEnc->clas_final_old, HQ_CORE ) || EQ_16( hTcxEnc->clas_final_old, TCX_20_CORE ) ) && ( ( GT_32( hTcxEnc->last_gain1, L_shr( gain1_tmp, 1 ) ) && LT_32( hTcxEnc->last_gain1, L_shl( gain1_tmp, 1 ) ) ) && ( GT_32( hTcxEnc->last_gain2, L_shr( gain2_tmp, 1 ) ) && LT_32( hTcxEnc->last_gain2, L_shl( gain2_tmp, 1 ) ) ) ) ) -#endif { clas_final = hTcxEnc->clas_final_old; move16(); @@ -591,10 +582,11 @@ Word16 mdct_classifier_fx( /* o: MDCT A/B decision return clas_final; /* Q0 */ } + Word16 mdct_classifier_ivas_fx( Encoder_State *st, /* i/o: Encoder state variable */ const Word16 *fft_buff, /* i : FFT spectrum from fft_rel */ - const Word32 enerBuffer[], /* i : energy buffer */ + const Word32 enerBuffer[], /* i : energy buffer enerBuffer_exp*/ Word16 enerBuffer_exp, const Word32 brate /* i : current brate, IVAS: nominal bitrate, EVS: st->total_brate */ ) @@ -781,7 +773,7 @@ Word16 mdct_classifier_ivas_fx( IF( pe != 0 ) { expo = norm_l( pe ); - man = L_shl( pe, expo ); + man = L_shl( pe, expo ); // expo Mpy_32_32_ss( man, man, &man, &lsb32 ); /* pe square */ expo = shl( expo, 1 ); /* Multiply by 2 due to squaring. */ floating_point_add( &p_energy_man, &p_energy_exp, man, expo ); @@ -804,32 +796,32 @@ Word16 mdct_classifier_ivas_fx( { IF( EQ_16( gain2_start, GAIN2_START_SWB ) ) { - gain1 = L_add( gain1, L_shr( enerBuffer[i], 3 ) ); - gain2 = L_add( gain2, L_shr( enerBuffer[gain2_start + i], 3 ) ); - gain3 = L_add( gain3, L_shr( enerBuffer[gain3_start + i], 3 ) ); + gain1 = L_add( gain1, L_shr( enerBuffer[i], 3 ) ); // enerBuffer_exp - 3 + gain2 = L_add( gain2, L_shr( enerBuffer[gain2_start + i], 3 ) ); // enerBuffer_exp - 3 + gain3 = L_add( gain3, L_shr( enerBuffer[gain3_start + i], 3 ) ); // enerBuffer_exp - 3 } ELSE { - gain1 = L_add( gain1, Mult_32_16( enerBuffer[i], 5461 ) ); - gain2 = L_add( gain2, Mult_32_16( enerBuffer[gain2_start + i], 5461 ) ); - gain3 = L_add( gain3, Mult_32_16( enerBuffer[gain3_start + i], 5461 ) ); + gain1 = L_add( gain1, Mult_32_16( enerBuffer[i], 5461 ) ); // enerBuffer_exp + gain2 = L_add( gain2, Mult_32_16( enerBuffer[gain2_start + i], 5461 /*0.16.Q15*/ ) ); // enerBuffer_exp + gain3 = L_add( gain3, Mult_32_16( enerBuffer[gain3_start + i], 5461 /*0.16.Q15*/ ) ); // enerBuffer_exp } } IF( EQ_16( gain2_start, GAIN2_START_SWB ) ) { - acc = L_shr( enerBuffer[0], 3 ); - acc = L_sub( gain1, acc ); - acc = Mult_32_16( acc, 4681 ); - gain11 = L_shl( acc, 3 ); + acc = L_shr( enerBuffer[0], 3 ); // enerBuffer_exp - 3 + acc = L_sub( gain1, acc ); // enerBuffer_exp - 3 + acc = Mult_32_16( acc, 4681 /*(1/7).Q15*/ ); // enerBuffer_exp - 3 + gain11 = L_shl( acc, 3 ); // enerBuffer_exp gain4 = L_deposit_l( 0 ); } ELSE { - acc = Mult_32_16( enerBuffer[0], 5461 ); - acc = L_sub( gain1, acc ); - acc = Mult_32_16( acc, 6553 ); + acc = Mult_32_16( enerBuffer[0], 5461 /*0.16.Q15*/ ); // enerBuffer_exp + acc = L_sub( gain1, acc ); // enerBuffer_exp + acc = Mult_32_16( acc, 6553 /*0.4.Q15*/ ); // enerBuffer_exp gain11 = (Word32) W_mult_32_16( acc, 6 ); gain4 = L_deposit_l( 0 ); } @@ -839,28 +831,28 @@ Word16 mdct_classifier_ivas_fx( { IF( EQ_16( gain4_start, GAIN4_START_SWB ) ) { - gain4 = L_add( gain4, Mult_32_16( enerBuffer[gain4_start + i], 2731 ) ); + gain4 = L_add( gain4, Mult_32_16( enerBuffer[gain4_start + i], 2731 /*(1/12).Q15*/ ) ); } ELSE { - gain4 = L_add( gain4, Mult_32_16( enerBuffer[gain4_start + i], 3641 ) ); + gain4 = L_add( gain4, Mult_32_16( enerBuffer[gain4_start + i], 3641 /*(1/9).Q1.15*/ ) ); } } - peak_H1 = enerBuffer[H1_start]; + peak_H1 = enerBuffer[H1_start]; // enerBuffer_exp move32(); - avrg_H1 = enerBuffer[H1_start]; + avrg_H1 = enerBuffer[H1_start]; // enerBuffer_exp move32(); FOR( i = 1; i < H_length; i++ ) { IF( GT_32( enerBuffer[H1_start + i], peak_H1 ) ) { - peak_H1 = enerBuffer[H1_start + i]; + peak_H1 = enerBuffer[H1_start + i]; // enerBuffer_exp move32(); } - avrg_H1 = L_add( avrg_H1, enerBuffer[H1_start + i] ); + avrg_H1 = L_add( avrg_H1, enerBuffer[H1_start + i] ); // enerBuffer_exp } peak_H2 = enerBuffer[H2_start]; @@ -972,17 +964,13 @@ Word16 mdct_classifier_ivas_fx( test(); test(); test(); -#ifdef BASOP_NOGLOB IF( GT_32( Mult_32_16( gain3, 27307 ), gain2 ) || ( GE_32( gain3, Mult_32_16( gain2, 26214 ) ) && GT_32( peak_H1, L_shl_o( avrg_H1, 1, &Overflow ) ) ) || ( LT_32( Mult_32_32( L_shl_o( peak_l, exp, &Overflow ), L_shl_o( avrg_h, exp1, &Overflow ) ), Mult_32_32( L_shl_o( L_tmp, exp, &Overflow ), L_shl_o( avrg_l, exp1, &Overflow ) ) ) || GT_32( Mult_32_32( L_shl_o( L_tmp1, exp2, &Overflow ), L_shl_o( avrg_h, exp1, &Overflow ) ), Mult_32_32( L_shl_o( peak_h, exp2, &Overflow ), L_shl_o( avrg_l, exp1, &Overflow ) ) ) ) ) -#else - IF( GT_32( Mult_32_16( gain3, 27307 ), gain2 ) || ( GE_32( gain3, Mult_32_16( gain2, 26214 ) ) && GT_32( peak_H1, L_shl( avrg_H1, 1 ) ) ) || ( LT_32( Mult_32_32( L_shl( peak_l, exp ), L_shl( avrg_h, exp1 ) ), Mult_32_32( L_shl( L_tmp, exp ), L_shl( avrg_l, exp1 ) ) ) || GT_32( Mult_32_32( L_shl( L_tmp1, exp2 ), L_shl( avrg_h, exp1 ) ), Mult_32_32( L_shl( peak_h, exp2 ), L_shl( avrg_l, exp1 ) ) ) ) ) -#endif { condition3 = 1; move16(); } - L_tmp = Mult_32_16( peak_h, 12800 ); + L_tmp = Mult_32_16( peak_h, 12800 /*(1/2.56).Q15*/ ); IF( GT_32( peak_l, L_tmp ) ) { exp = norm_l( peak_l ); @@ -992,7 +980,7 @@ Word16 mdct_classifier_ivas_fx( exp = norm_l( L_tmp ); } - L_tmp1 = Mult_32_16( peak_l, 6400 ); + L_tmp1 = Mult_32_16( peak_l, 6400 /*(1/5.12).Q15*/ ); IF( GT_32( peak_h, L_tmp1 ) ) { exp2 = norm_l( peak_h ); @@ -1020,8 +1008,8 @@ Word16 mdct_classifier_ivas_fx( test(); test(); test(); - IF( ( GT_32( gain4, Mult_32_16( gain11, 26214 ) ) && GT_32( Mult_32_32( L_shl( peak_l, exp ), L_shl( avrg_h, exp1 ) ), Mult_32_32( L_shl( Mult_32_16( peak_h, 12800 ), exp ), L_shl( avrg_l, exp1 ) ) ) && LT_32( Mult_32_32( L_shl( Mult_32_16( peak_l, 6400 ), exp2 ), L_shl( avrg_h, exp1 ) ), Mult_32_32( L_shl( peak_h, exp2 ), L_shl( avrg_l, exp1 ) ) ) ) || ( GT_32( gain4, Mult_32_16( gain11, 9830 ) ) && LT_32( Mult_32_16( peak_h, 21845 ), avrg_h ) && LT_32( Mult_32_16( peak_H2, 21845 ), avrg_H2 ) ) || - ( LT_32( Mult_32_32( L_shl( peak_l, exp ), L_shl( avrg_h, exp1 ) ), Mult_32_32( L_shl( Mult_32_16( peak_h, 12800 ), exp ), L_shl( avrg_l, exp1 ) ) ) && GT_32( Mult_32_16( peak_h, 21845 ), avrg_h ) ) || ( GT_32( Mult_32_32( L_shl( Mult_32_16( peak_l, 12800 ), exp3 ), L_shl( avrg_h, exp1 ) ), Mult_32_32( L_shl( peak_h, exp3 ), L_shl( avrg_l, exp1 ) ) ) > 0 && LT_32( Mult_32_16( peak_h, 21845 ), avrg_h ) ) ) + IF( ( GT_32( gain4, Mult_32_16( gain11, 26214 /*0.8.Q15*/ ) ) && GT_32( Mult_32_32( L_shl( peak_l, exp ), L_shl( avrg_h, exp1 ) ), Mult_32_32( L_shl( Mult_32_16( peak_h, 12800 /*(1/2.56).Q15*/ ), exp ), L_shl( avrg_l, exp1 ) ) ) && LT_32( Mult_32_32( L_shl( Mult_32_16( peak_l, 6400 /*(1/5.12).Q15*/ ), exp2 ), L_shl( avrg_h, exp1 ) ), Mult_32_32( L_shl( peak_h, exp2 ), L_shl( avrg_l, exp1 ) ) ) ) || ( GT_32( gain4, Mult_32_16( gain11, 9830 /*0.3.Q15*/ ) ) && LT_32( Mult_32_16( peak_h, 21845 /*(1/1.5).Q15*/ ), avrg_h ) && LT_32( Mult_32_16( peak_H2, 21845 /*(1/1.5).Q15*/ ), avrg_H2 ) ) || + ( LT_32( Mult_32_32( L_shl( peak_l, exp ), L_shl( avrg_h, exp1 ) ), Mult_32_32( L_shl( Mult_32_16( peak_h, 12800 /*(1/2.56).Q15*/ ), exp ), L_shl( avrg_l, exp1 ) ) ) && GT_32( Mult_32_16( peak_h, 21845 /*(1/1.5).Q15*/ ), avrg_h ) ) || ( GT_32( Mult_32_32( L_shl( Mult_32_16( peak_l, 12800 /*(1/2.56).Q15*/ ), exp3 ), L_shl( avrg_h, exp1 ) ), Mult_32_32( L_shl( peak_h, exp3 ), L_shl( avrg_l, exp1 ) ) ) > 0 && LT_32( Mult_32_16( peak_h, 21845 /*(1/1.5).Q15*/ ), avrg_h ) ) ) { condition4 = 1; move16(); @@ -1077,11 +1065,7 @@ Word16 mdct_classifier_ivas_fx( test(); test(); -#ifdef BASOP_NOGLOB IF( ( EQ_16( hTcxEnc->clas_final_old, HQ_CORE ) || EQ_16( hTcxEnc->clas_final_old, TCX_20_CORE ) ) && ( ( GT_32( hTcxEnc->last_gain1, L_shr( gain1_tmp, 1 ) ) && LT_32( hTcxEnc->last_gain1, L_shl_o( gain1_tmp, 1, &Overflow ) ) ) && ( GT_32( hTcxEnc->last_gain2, L_shr( gain2_tmp, 1 ) ) && LT_32( hTcxEnc->last_gain2, L_shl_o( gain2_tmp, 1, &Overflow ) ) ) ) ) -#else - IF( ( EQ_16( hTcxEnc->clas_final_old, HQ_CORE ) || EQ_16( hTcxEnc->clas_final_old, TCX_20_CORE ) ) && ( ( GT_32( hTcxEnc->last_gain1, L_shr( gain1_tmp, 1 ) ) && LT_32( hTcxEnc->last_gain1, L_shl( gain1_tmp, 1 ) ) ) && ( GT_32( hTcxEnc->last_gain2, L_shr( gain2_tmp, 1 ) ) && LT_32( hTcxEnc->last_gain2, L_shl( gain2_tmp, 1 ) ) ) ) ) -#endif { clas_final = hTcxEnc->clas_final_old; move16(); diff --git a/lib_enc/mdct_selector.c b/lib_enc/mdct_selector.c deleted file mode 100644 index 9d6f499db09e405ecf613f29cb1442072afc3305..0000000000000000000000000000000000000000 --- a/lib_enc/mdct_selector.c +++ /dev/null @@ -1,44 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include -#include "cnst.h" -#include "rom_enc.h" -#include "rom_com.h" -#include "prot.h" -#include "wmc_auto.h" diff --git a/lib_enc/mdct_selector_fx.c b/lib_enc/mdct_selector_fx.c index 52c30f7ef6be8666370f19d2f3d0cfeb545a2f25..c4cc7d0db8bcca97c26af11090363cbb12dfc166 100644 --- a/lib_enc/mdct_selector_fx.c +++ b/lib_enc/mdct_selector_fx.c @@ -62,14 +62,14 @@ static Word16 get_sparseness( /* Returns sparseness measur FOR( i = 1; i < n - 1; ++i ) { - if ( GT_16( Bin_E[i], s_max( s_max( Bin_E[i - 1], Bin_E[i + 1] ), thr ) ) ) + IF( GT_16( Bin_E[i], s_max( s_max( Bin_E[i - 1], Bin_E[i + 1] ), thr ) ) ) { num_max = add( num_max, 1 ); } } n = shr( sub( n, 2 ), 1 ); - return div_s( sub( n, num_max ), n ); + return div_s( sub( n, num_max ), n ); // Q15 } /*--------------------------------------------------------------------------* * get_mean_ener() @@ -78,7 +78,7 @@ static Word16 get_sparseness( /* Returns sparseness measur *--------------------------------------------------------------------------*/ static Word16 get_mean_ener( /* Returns mean energy in dB (Q8) */ - const Word32 enerBuffer[], /* i : CLDFB buffers */ + const Word32 enerBuffer[], /* i : CLDFB buffers enerBuffer_exp*/ Word16 enerBuffer_exp, /* i : exponent of enerBuffer */ Word16 n /* i : number of bins */ ) @@ -87,8 +87,10 @@ static Word16 get_mean_ener( /* Returns mean energy i Word16 i, shift, frac_nrg, exp_nrg; shift = sub( 14, norm_s( n ) ); - if ( LT_16( shl( 1, shift ), n ) ) + IF( LT_16( shl( 1, shift ), n ) ) + { shift = add( shift, 1 ); + } L_tmp = L_deposit_l( 0 ); FOR( i = 0; i < n; ++i ) @@ -104,7 +106,7 @@ static Word16 get_mean_ener( /* Returns mean energy i exp_nrg = sub( add( exp_nrg, shift ), sub( 31, enerBuffer_exp ) ); L_tmp = Mpy_32_16( exp_nrg, frac_nrg, 9864 ); /* log10(2) in Q15 */ - return round_fx( L_shl( L_tmp, 8 ) ); + return round_fx( L_shl( L_tmp, 8 ) ); // Q8 } /*--------------------------------------------------------------------------* * MDCT_selector_fx() @@ -117,7 +119,7 @@ void MDCT_selector_fx( Word16 sp_floor, /* i : Noise floor estimate Q7 */ const Word16 Etot, /* i : Total energy Q8 */ const Word16 cor_map_sum, /* i : harmonicity factor Q8 */ - const Word32 enerBuffer[], /* i : CLDFB buffers */ + const Word32 enerBuffer[], /* i : CLDFB buffers enerBuffer_exp*/ const Word16 enerBuffer_exp /* i : exponent of enerBuffer */ ) { @@ -135,7 +137,7 @@ void MDCT_selector_fx( sp_floor = shl( sp_floor, 1 ); /* convert to Q8 */ - IF( EQ_16( st->bwidth, NB ) ) + IF( ( st->bwidth == NB ) ) { lob_cldfb = 3200 / 400; move16(); @@ -188,7 +190,7 @@ void MDCT_selector_fx( frame_voicing = add( shr( st->voicing_fx[0], 1 ), shr( st->voicing_fx[1], 1 ) ); /* Spectral sparseness */ - sparseness = get_sparseness( st->lgBin_E_fx, lob_fft, sub( Etot, MDCT_SW_SIG_PEAK_THR ) ); + sparseness = get_sparseness( st->lgBin_E_fx, lob_fft, sub( Etot, MDCT_SW_SIG_PEAK_THR ) ); // Q15 /* Hi band energy */ hi_ener = get_mean_ener( &enerBuffer[lob_cldfb], enerBuffer_exp, sub( hib_cldfb, lob_cldfb ) ); @@ -255,23 +257,23 @@ void MDCT_selector_fx( IF( EQ_16( st->mdct_sw_enable, MODE1 ) ) { - sig_lo_level_thr = MDCT_SW_1_SIG_LO_LEVEL_THR; + sig_lo_level_thr = MDCT_SW_1_SIG_LO_LEVEL_THR; // Q8 move16(); - sig_hi_level_thr = MDCT_SW_1_SIG_HI_LEVEL_THR; + sig_hi_level_thr = MDCT_SW_1_SIG_HI_LEVEL_THR; // Q8 move16(); - cor_thr = MDCT_SW_1_COR_THR; + cor_thr = MDCT_SW_1_COR_THR; // Q8 move16(); - cor_thr2 = MDCT_SW_1_COR_THR2; + cor_thr2 = MDCT_SW_1_COR_THR2; // Q8 move16(); - voicing_thr = MDCT_SW_1_VOICING_THR; + voicing_thr = MDCT_SW_1_VOICING_THR; // Q15 move16(); - voicing_thr2 = MDCT_SW_1_VOICING_THR2; + voicing_thr2 = MDCT_SW_1_VOICING_THR2; // Q15 move16(); - sparseness_thr = MDCT_SW_1_SPARSENESS_THR; + sparseness_thr = MDCT_SW_1_SPARSENESS_THR; // Q15 move16(); - sparseness_thr2 = MDCT_SW_1_SPARSENESS_THR2; + sparseness_thr2 = MDCT_SW_1_SPARSENESS_THR2; // Q15 move16(); - hi_ener_lo_thr = MDCT_SW_1_HI_ENER_LO_THR; + hi_ener_lo_thr = MDCT_SW_1_HI_ENER_LO_THR; // Q8 move16(); } ELSE /* st->mdct_sw_enable == MODE2 */ diff --git a/lib_enc/mslvq_enc.c b/lib_enc/mslvq_enc.c deleted file mode 100644 index 9f95d696c1a7ff0612049f066bd40360d8713923..0000000000000000000000000000000000000000 --- a/lib_enc/mslvq_enc.c +++ /dev/null @@ -1,308 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include -#include "prot.h" -#include "prot_fx.h" -#include "rom_com.h" -#include "cnst.h" -#include "wmc_auto.h" -#include "ivas_prot.h" - -/*-----------------------------------------------------------------* - * Local function prototypes - *-----------------------------------------------------------------*/ - -Word32 quantize_data_ivas_fx( Word16 *data, const Word16 *w_in, Word16 *qin, Word16 *cv_out, Word16 *idx_lead, Word16 *idx_scale, const Word16 *sigma, const Word16 *inv_sigma, const Word16 *scales, const Word16 *no_lead ); - -/*-----------------------------------------------------------------* - * mslvq() - * - * Encodes the LSF residual - *-----------------------------------------------------------------*/ - -Word32 mslvq_ivas_16( - Word16 *pTmp, /* i : M-dimensional input vector */ - Word16 *quant, /* o : quantized vector */ - Word16 *cv_out, /* o : corresponding 8-dim lattice codevectors (without the scaling) */ - Word16 *idx_lead, /* o : leader index for each 8-dim subvector */ - Word16 *idx_scale, /* o : scale index for each subvector */ - const Word16 *w, /* i : weights for LSF quantization */ - const Word16 mode, /* i : number indicating the coding type (V/UV/G...)*/ - const Word16 mode_glb, /* i : LVQ coding mode */ - const Word16 pred_flag /* i : prediction flag (0: safety net, 1,2 - predictive )*/ - /*Retunr dist in q 22*/ -) -{ - Word32 dist, L_tmp; - const Word16 *p_scales, *p_sigma, *p_inv_sigma; - Word16 i, tmp, tmp1; - Word16 p_no_lead[MAX_NO_SCALES * 2]; - dist = L_deposit_l( 0 ); - IF( pred_flag == 0 ) - { - p_sigma = sigma_MSLVQ_fx[mode]; - /* inverse sigma is precomputed to save complexity */ - p_inv_sigma = inv_sigma_MSLVQ_fx[mode]; - p_scales = scales_ivas_fx[mode_glb]; - - tmp = no_lead_idx[mode_glb][0]; - move16(); - tmp1 = no_lead_idx[mode_glb][1]; - move16(); - test(); - if ( LE_16( tmp, LIMIT_LEADER ) && LT_16( tmp, sub( tmp1, 2 ) ) ) - { - tmp = add( tmp, DELTA_LEADER ); - } - FOR( i = 0; i < MAX_NO_SCALES; i++ ) - { - p_no_lead[i] = (Word16) leaders_short[tmp][i]; - move16(); - p_no_lead[i + MAX_NO_SCALES] = (Word16) leaders_short[tmp1][i]; - move16(); - } - } - ELSE - { - IF( GE_16( pred_flag, 5 ) ) - { - /* assert( pred_flag >= 12 && pred_flag <= 15 ); */ - /* pred_flag is here the number of bits for MSLVQ */ - - p_sigma = &modified_sigma_BWE_fx[mode_glb * LATTICE_DIM]; - - /* inverse sigma is precomputed to save complexity */ - p_inv_sigma = &inv_modified_sigma_BWE_fx[mode_glb * LATTICE_DIM]; - IF( mode_glb == 0 ) - { - p_scales = &scales_BWE_fx_new[i_mult( sub( pred_flag, mslvq_SHB_min_bits[mode_glb] ), 3 )]; - - FOR( i = 0; i < MAX_NO_SCALES; i++ ) - { - p_no_lead[i] = (Word16) no_lead_BWE[i + ( pred_flag - mslvq_SHB_min_bits[mode_glb] ) * 3]; - move16(); - } - } - ELSE - { - p_scales = &scales_BWE_3b_fx_new[i_mult( sub( pred_flag, mslvq_SHB_min_bits[mode_glb] ), 3 )]; - FOR( i = 0; i < MAX_NO_SCALES; i++ ) - { - p_no_lead[i] = (Word16) no_lead_BWE_3b[i + ( pred_flag - mslvq_SHB_min_bits[mode_glb] ) * 3]; - move16(); - } - } - } - ELSE - { - p_sigma = sigma_p_fx[mode]; - - /* inverse sigma is precomputed to save complexity */ - p_inv_sigma = inv_sigma_p_fx[mode]; - - p_scales = scales_p_ivas_fx[mode_glb]; - - tmp = no_lead_p_idx[mode_glb][0]; - move16(); - tmp1 = no_lead_p_idx[mode_glb][1]; - move16(); - - test(); - IF( LE_16( tmp, LIMIT_LEADER ) && LT_16( tmp, sub( tmp1, 2 ) ) ) - { - tmp = add( tmp, DELTA_LEADER ); - } - - test(); - IF( EQ_16( tmp, LIMIT_LEADER ) && ( tmp1 == 0 ) ) - { - tmp = add( tmp, DELTA_LEADER ); - tmp1 = add( tmp1, DELTA_LEADER ); - } - - FOR( i = 0; i < MAX_NO_SCALES; i++ ) - { - p_no_lead[i] = (Word16) leaders_short[tmp][i]; - move16(); - p_no_lead[i + MAX_NO_SCALES] = (Word16) leaders_short[tmp1][i]; - move16(); - } - } - } - - /* first subvector */ - dist = quantize_data_ivas_fx( pTmp, w, quant, cv_out, idx_lead, idx_scale, - p_sigma, p_inv_sigma, p_scales, p_no_lead ); - - IF( LT_16( pred_flag, 5 ) ) - { - /* second subvector */ - L_tmp = quantize_data_ivas_fx( pTmp + LATTICE_DIM, w + LATTICE_DIM, quant + LATTICE_DIM, cv_out + LATTICE_DIM, &idx_lead[1], &idx_scale[1], p_sigma + LATTICE_DIM, p_inv_sigma + LATTICE_DIM, p_scales + MAX_NO_SCALES, p_no_lead + MAX_NO_SCALES ); - - dist = L_add( dist, L_tmp ); - } - - return dist; -} - -/*-----------------------------------------------------------------* - * mslvq_cng() - * - * Encodes the LSF residual in SID frames - *-----------------------------------------------------------------*/ - -/*-----------------------------------------------------------------* - * prepare_data() - * - *-----------------------------------------------------------------*/ - - -/*-----------------------------------------------------------------* - * calculate_min_dist() - * - *-----------------------------------------------------------------*/ - - -/*-----------------------------------------------------------------* - * quantize_data() - * - *-----------------------------------------------------------------*/ - - -/*-----------------------------------------------------------------* - * index_lvq() - * - * sorts in descending order and computes indices in the sorted vector - *-----------------------------------------------------------------*/ - - -/*-----------------------------------------------------------------* - * encode_comb() - * - * creates an index for the lattice codevector - *-----------------------------------------------------------------*/ - - -/*-----------------------------------------------------------------* - * index_leaders() - * - * gives the index in a class of leaders without considering the sign yet - *-----------------------------------------------------------------*/ - - -/*-----------------------------------------------------------------* - * find_pos() - * - * Finds the positions in vector c for which the vector components are equal to 'arg'. - * It returns the number of such positions and their values in the array 'p'. - *-----------------------------------------------------------------*/ - - -/*-----------------------------------------------------------------* - * encode_sign_pc1() - * - * Creates an index for signs of the significant codevector components - * Gives the index of the signs - binary representation where negative sign stands for 1 - * and positive sign stands for 1. - *-----------------------------------------------------------------*/ - - -/*-----------------------------------------------------------------* - * take_out_val() - * - * removes the value val from the vector v - *-----------------------------------------------------------------*/ - - -/*-----------------------------------------------------------------* - * c2idx() - * - *-----------------------------------------------------------------*/ - - -/*-----------------------------------------------------------------* - * index_lvq_SHB() - * - *-----------------------------------------------------------------*/ - - -UWord32 index_lvq_SHB_fx( - const Word16 idx_lead, - const Word16 idx_scale, - const Word16 nbits, - Word16 *lat_cv, - const Word16 mode ) -{ - UWord16 i; - const Word8 *p_no_lead; - UWord32 index; - - IF( mode == 0 ) - { - p_no_lead = &no_lead_BWE[( nbits - mslvq_SHB_min_bits[0] ) * 3]; - } - ELSE - { - p_no_lead = &no_lead_BWE_3b[( nbits - mslvq_SHB_min_bits[1] ) * 3]; - } - - index = 0; - move32(); - IF( GT_16( idx_lead, -1 ) ) - { - index = 1; - move32(); - FOR( i = 0; i < idx_scale; i++ ) - { - index = index + table_no_cv[p_no_lead[i]]; - move32(); - } - - IF( idx_lead > 0 ) - { - index = index + table_no_cv[idx_lead]; - move32(); - } - - index = index + encode_comb_fx( lat_cv, idx_lead ); - move32(); - } - - return index; -} diff --git a/lib_enc/mslvq_enc_fx.c b/lib_enc/mslvq_enc_fx.c index b6445443bdf549b9e0775e347e3554317373a111..af5a82b69edc9c96987d221c032b1aa30450ca50 100644 --- a/lib_enc/mslvq_enc_fx.c +++ b/lib_enc/mslvq_enc_fx.c @@ -6,9 +6,8 @@ #include "rom_com_fx.h" #include "rom_com.h" #include "stl.h" -#include "prot.h" /* Function prototypes */ -#include "basop32.h" /* Function prototypes */ #include "prot_fx.h" /* Function prototypes */ +#include "basop32.h" /* Function prototypes */ #include "prot_fx_enc.h" /* Function prototypes */ @@ -59,19 +58,19 @@ Word32 mslvq_fx( IF( pred_flag == 0 ) { - p_sigma = sigma_MSLVQ_fx[mode]; + p_sigma = sigma_MSLVQ_fx[mode]; // Qlog2(2.56) /* inverse sigma is precomputed to save complexity */ - p_inv_sigma = inv_sigma_MSLVQ_fx[mode]; - p_scales = scales_fx[mode_glb]; - p_no_lead = no_lead_fx[mode_glb]; + p_inv_sigma = inv_sigma_MSLVQ_fx[mode]; // Q15 + p_scales = scales_fx[mode_glb]; // Q11 + p_no_lead = no_lead_fx[mode_glb]; // Q0 } ELSE { - p_sigma = sigma_p_fx[mode]; + p_sigma = sigma_p_fx[mode]; // Qlog2(2.56) /* inverse sigma is precomputed to save complexity */ - p_inv_sigma = inv_sigma_p_fx[mode]; - p_scales = scales_p_fx[mode_glb]; - p_no_lead = no_lead_p_fx[mode_glb]; + p_inv_sigma = inv_sigma_p_fx[mode]; // Q15 + p_scales = scales_p_fx[mode_glb]; // Q11 + p_no_lead = no_lead_p_fx[mode_glb]; // Q0 } /* first subvector */ @@ -185,15 +184,15 @@ Word32 mslvq_cng_fx( mode_glb = add( START_CNG, idx_cv ); move16(); - p_sigma = sigma_MSLVQ_fx[mode]; + p_sigma = sigma_MSLVQ_fx[mode]; // x2.56 move16(); - p_inv_sigma = inv_sigma_MSLVQ_fx[mode]; + p_inv_sigma = inv_sigma_MSLVQ_fx[mode]; // Q15 move16(); - p_scales = scales_fx[mode_glb]; + p_scales = scales_fx[mode_glb]; // Q11 move16(); - p_no_lead = no_lead_fx[mode_glb]; + p_no_lead = no_lead_fx[mode_glb]; // Q0 move16(); - p_no_scales = &no_scales[shl( mode_glb, 1 )]; + p_no_scales = &no_scales[( mode_glb << 1 )]; move16(); /* check if LSF component permutation is needed or not */ @@ -248,11 +247,11 @@ Word32 mslvq_cng_ivas_fx( mode_glb = add( START_CNG, idx_cv ); move16(); - p_sigma = sigma_MSLVQ_fx[mode]; + p_sigma = sigma_MSLVQ_fx[mode]; // x2.56 move16(); - p_inv_sigma = inv_sigma_MSLVQ_fx[mode]; + p_inv_sigma = inv_sigma_MSLVQ_fx[mode]; // Q15 move16(); - p_scales = scales_fx[mode_glb]; + p_scales = scales_fx[mode_glb]; // Q11 move16(); no_scales[0] = 0; @@ -774,7 +773,7 @@ static void sort_desc_ind_fx( move16(); } sorted = 0; - FOR( k = sub( len, 1 ); k > 0; k-- ) + FOR( k = ( len - 1 ); k > 0; k-- ) { IF( sorted ) { @@ -838,7 +837,7 @@ void index_lvq_fx( /* for first subvector */ IF( GT_16( idx_scale[0], -1 ) ) { - index1 = L_add( encode_comb_fx( quant, idx_lead[0] ), L_add( table_no_cv_fx[idx_lead[0]], p_offset_scale1[i_mult2( mode, len_offset ) + idx_scale[0]] ) ); + index1 = L_add( encode_comb_fx( quant, idx_lead[0] ), L_add( table_no_cv_fx[idx_lead[0]], p_offset_scale1[( mode * len_offset ) + idx_scale[0]] ) ); } /* for second subvector */ @@ -846,7 +845,7 @@ void index_lvq_fx( IF( GT_16( idx_scale[1], -1 ) ) { - index2 = L_add( encode_comb_fx( &quant[LATTICE_DIM], idx_lead[1] ), L_add( table_no_cv_fx[idx_lead[1]], p_offset_scale2[i_mult2( mode, len_offset ) + idx_scale[1]] ) ); + index2 = L_add( encode_comb_fx( &quant[LATTICE_DIM], idx_lead[1] ), L_add( table_no_cv_fx[idx_lead[1]], p_offset_scale2[( mode * len_offset ) + idx_scale[1]] ) ); } idx64 = W_mult0_32_32( index1, p_offset_scale2[mode * len_offset + p_no_scales[mode * 2 + 1]] ); index2_64 = W_deposit32_l( index2 ); @@ -855,9 +854,9 @@ void index_lvq_fx( /* convert to 3 short */ index[0] = ( ( idx64 ) & ( 0x7fff ) ); move16(); - index[1] = ( idx64 >> 15 ) & ( 0x7fff ); + index[1] = ( W_shr( idx64, 15 ) ) & ( 0x7fff ); move16(); - index[2] = ( idx64 >> 30 ) & ( 0x7fff ); + index[2] = ( W_shr( idx64, 30 ) ) & ( 0x7fff ); move16(); return; } @@ -901,9 +900,9 @@ void index_lvq_ivas_fx( /* convert to 3 short */ index[0] = ( ( idx64 ) & ( 0x7fff ) ); move16(); - index[1] = ( idx64 >> 15 ) & ( 0x7fff ); + index[1] = ( W_shr( idx64, 15 ) ) & ( 0x7fff ); move16(); - index[2] = ( idx64 >> 30 ) & ( 0x7fff ); + index[2] = ( W_shr( idx64, 30 ) ) & ( 0x7fff ); move16(); return; @@ -1060,7 +1059,7 @@ static Word16 encode_sign_pc1_fx( /* o : index of signs IF( cv[i] < 0 ) { idx_sign = add( idx_sign, ( shl( 1, cnt ) ) ); - cnt++; + cnt = add( cnt, 1 ); } if ( cv[i] > 0 ) @@ -1092,7 +1091,7 @@ static void take_out_val_fx( FOR( i = 0; i < len; i++ ) { - IF( NE_16( v[i], val ) ) + if ( NE_16( v[i], val ) ) { v_out[cnt++] = v[i]; move16(); @@ -1126,7 +1125,7 @@ Word16 c2idx_fx( /* o: index */ move16(); FOR( i = 1; i <= p[0]; i++ ) { - skip = add( skip, C_VQ[sub( n, i )][sub( k, 1 )] ); + skip = add( skip, C_VQ[( n - i )][( k - 1 )] ); // Q0 } p0 = p[0]; @@ -1140,3 +1139,180 @@ Word16 c2idx_fx( /* o: index */ return tmp; } } + +/*-----------------------------------------------------------------* + * mslvq() + * + * Encodes the LSF residual + *-----------------------------------------------------------------*/ + +Word32 mslvq_ivas_16( + Word16 *pTmp, /* i : M-dimensional input vector */ + Word16 *quant, /* o : quantized vector */ + Word16 *cv_out, /* o : corresponding 8-dim lattice codevectors (without the scaling) */ + Word16 *idx_lead, /* o : leader index for each 8-dim subvector */ + Word16 *idx_scale, /* o : scale index for each subvector */ + const Word16 *w, /* i : weights for LSF quantization */ + const Word16 mode, /* i : number indicating the coding type (V/UV/G...)*/ + const Word16 mode_glb, /* i : LVQ coding mode */ + const Word16 pred_flag /* i : prediction flag (0: safety net, 1,2 - predictive )*/ + /*Retunr dist in q 22*/ +) +{ + Word32 dist, L_tmp; + const Word16 *p_scales, *p_sigma, *p_inv_sigma; + Word16 i, tmp, tmp1; + Word16 p_no_lead[MAX_NO_SCALES * 2]; + dist = L_deposit_l( 0 ); + IF( pred_flag == 0 ) + { + p_sigma = sigma_MSLVQ_fx[mode]; + /* inverse sigma is precomputed to save complexity */ + p_inv_sigma = inv_sigma_MSLVQ_fx[mode]; + p_scales = scales_ivas_fx[mode_glb]; + + tmp = no_lead_idx[mode_glb][0]; + move16(); + tmp1 = no_lead_idx[mode_glb][1]; + move16(); + test(); + if ( LE_16( tmp, LIMIT_LEADER ) && LT_16( tmp, sub( tmp1, 2 ) ) ) + { + tmp = add( tmp, DELTA_LEADER ); + } + FOR( i = 0; i < MAX_NO_SCALES; i++ ) + { + p_no_lead[i] = (Word16) leaders_short[tmp][i]; + move16(); + p_no_lead[i + MAX_NO_SCALES] = (Word16) leaders_short[tmp1][i]; + move16(); + } + } + ELSE + { + IF( GE_16( pred_flag, 5 ) ) + { + /* assert( pred_flag >= 12 && pred_flag <= 15 ); */ + /* pred_flag is here the number of bits for MSLVQ */ + + p_sigma = &modified_sigma_BWE_fx[mode_glb * LATTICE_DIM]; + + /* inverse sigma is precomputed to save complexity */ + p_inv_sigma = &inv_modified_sigma_BWE_fx[mode_glb * LATTICE_DIM]; + IF( mode_glb == 0 ) + { + p_scales = &scales_BWE_fx_new[i_mult( sub( pred_flag, mslvq_SHB_min_bits[mode_glb] ), 3 )]; + + FOR( i = 0; i < MAX_NO_SCALES; i++ ) + { + p_no_lead[i] = (Word16) no_lead_BWE[i + ( pred_flag - mslvq_SHB_min_bits[mode_glb] ) * 3]; + move16(); + } + } + ELSE + { + p_scales = &scales_BWE_3b_fx_new[i_mult( sub( pred_flag, mslvq_SHB_min_bits[mode_glb] ), 3 )]; + FOR( i = 0; i < MAX_NO_SCALES; i++ ) + { + p_no_lead[i] = (Word16) no_lead_BWE_3b[i + ( pred_flag - mslvq_SHB_min_bits[mode_glb] ) * 3]; + move16(); + } + } + } + ELSE + { + p_sigma = sigma_p_fx[mode]; + + /* inverse sigma is precomputed to save complexity */ + p_inv_sigma = inv_sigma_p_fx[mode]; + + p_scales = scales_p_ivas_fx[mode_glb]; + + tmp = no_lead_p_idx[mode_glb][0]; + move16(); + tmp1 = no_lead_p_idx[mode_glb][1]; + move16(); + + test(); + IF( LE_16( tmp, LIMIT_LEADER ) && LT_16( tmp, sub( tmp1, 2 ) ) ) + { + tmp = add( tmp, DELTA_LEADER ); + } + + test(); + IF( EQ_16( tmp, LIMIT_LEADER ) && ( tmp1 == 0 ) ) + { + tmp = add( tmp, DELTA_LEADER ); + tmp1 = add( tmp1, DELTA_LEADER ); + } + + FOR( i = 0; i < MAX_NO_SCALES; i++ ) + { + p_no_lead[i] = (Word16) leaders_short[tmp][i]; + move16(); + p_no_lead[i + MAX_NO_SCALES] = (Word16) leaders_short[tmp1][i]; + move16(); + } + } + } + + /* first subvector */ + dist = quantize_data_ivas_fx( pTmp, w, quant, cv_out, idx_lead, idx_scale, + p_sigma, p_inv_sigma, p_scales, p_no_lead ); + + IF( LT_16( pred_flag, 5 ) ) + { + /* second subvector */ + L_tmp = quantize_data_ivas_fx( pTmp + LATTICE_DIM, w + LATTICE_DIM, quant + LATTICE_DIM, cv_out + LATTICE_DIM, &idx_lead[1], &idx_scale[1], p_sigma + LATTICE_DIM, p_inv_sigma + LATTICE_DIM, p_scales + MAX_NO_SCALES, p_no_lead + MAX_NO_SCALES ); + + dist = L_add( dist, L_tmp ); + } + + return dist; +} + + +UWord32 index_lvq_SHB_fx( + const Word16 idx_lead, + const Word16 idx_scale, + const Word16 nbits, + Word16 *lat_cv, + const Word16 mode ) +{ + UWord16 i; + const Word8 *p_no_lead; + UWord32 index; + + IF( mode == 0 ) + { + p_no_lead = &no_lead_BWE[( nbits - mslvq_SHB_min_bits[0] ) * 3]; + } + ELSE + { + p_no_lead = &no_lead_BWE_3b[( nbits - mslvq_SHB_min_bits[1] ) * 3]; + } + + index = 0; + move32(); + IF( GT_16( idx_lead, -1 ) ) + { + index = 1; + move32(); + FOR( i = 0; i < idx_scale; i++ ) + { + index = index + table_no_cv[p_no_lead[i]]; + move32(); + } + + IF( idx_lead > 0 ) + { + index = index + table_no_cv[idx_lead]; + move32(); + } + + index = index + encode_comb_fx( lat_cv, idx_lead ); + move32(); + } + + return index; +} diff --git a/lib_enc/multi_harm.c b/lib_enc/multi_harm.c deleted file mode 100644 index 7d23dd6f703552ed5f1af9f2941cf4dee9763f27..0000000000000000000000000000000000000000 --- a/lib_enc/multi_harm.c +++ /dev/null @@ -1,42 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include -#include "cnst.h" -#include "prot.h" -#include "wmc_auto.h" diff --git a/lib_enc/multi_harm_fx.c b/lib_enc/multi_harm_fx.c index 92666570c892508d994b40f50663f7fa1ded24c7..1bae597b6892428a06b6c83e1b0de38121329432 100644 --- a/lib_enc/multi_harm_fx.c +++ b/lib_enc/multi_harm_fx.c @@ -53,7 +53,7 @@ Word16 multi_harm_fx( /* o : frame multi-harmonicity /* length of the useful part of the spectrum (up to 6.4kHz) */ L = L_FFT / 2; move16(); - if ( EQ_16( bwidth, NB ) ) + if ( ( bwidth == NB ) ) { /* length of the useful part of the spectrum (up to 3.6kHz) */ L = 76; @@ -170,14 +170,14 @@ Word16 multi_harm_fx( /* o : frame multi-harmonicity mean_dyn = round_fx( L_acc ); /*Q7*/ test(); - IF( LT_16( mean_dyn, 1229 ) /*9.6f*/ && *cor_strong_limit != 0 ) + IF( LT_16( mean_dyn, 1229 ) /*9.6f.Q7*/ && *cor_strong_limit != 0 ) { *cor_strong_limit = 0; move16(); *st_last_sw_dyn = mean_dyn; move16(); } - ELSE IF( GT_16( sub( mean_dyn, *st_last_sw_dyn ), 576 ) /*4.5f*/ ) + ELSE IF( GT_16( sub( mean_dyn, *st_last_sw_dyn ), 576 ) /*4.5f.Q7*/ ) { *cor_strong_limit = 1; move16(); @@ -212,11 +212,7 @@ Word16 multi_harm_fx( /* o : frame multi-harmonicity IF( EQ_16( i, ind_mins[k] ) ) { /* include the last peak point (new minimum) to the corr. sum */ -#ifdef BASOP_NOGLOB Lcory2 = L_mac_o( Lcory2, old_S[i], old_S[i], &Overflow ); -#else /* BASOP_NOGLOB */ - Lcory2 = L_mac( Lcory2, old_S[i], old_S[i] ); -#endif /* BASOP_NOGLOB */ /* calculation of the norm. peak correlation */ test(); @@ -242,11 +238,7 @@ Word16 multi_harm_fx( /* o : frame multi-harmonicity corxy = shl( corxy, cor ); /* cor = corxy * corxy / (corx2 * cory2) */ corxy = div_s( corxy, corx2 ); -#ifdef BASOP_NOGLOB cor = shr_o( corxy, sub( shl( tmp16, 1 ), Expx2 ), &Overflow ); /* Q15 */ -#else /* BASOP_NOGLOB */ - cor = shr( corxy, sub( shl( tmp16, 1 ), Expx2 ) ); /* Q15 */ -#endif /* BASOP_NOGLOB */ } ELSE { @@ -271,15 +263,9 @@ Word16 multi_harm_fx( /* o : frame multi-harmonicity k++; } -#ifdef BASOP_NOGLOB Lcorx2 = L_mac_o( Lcorx2, S[i], S[i], &Overflow ); Lcory2 = L_mac_o( Lcory2, old_S[i], old_S[i], &Overflow ); Lcorxy = L_mac_o( Lcorxy, S[i], old_S[i], &Overflow ); -#else /* BASOP_NOGLOB */ - Lcorx2 = L_mac( Lcorx2, S[i], S[i] ); - Lcory2 = L_mac( Lcory2, old_S[i], old_S[i] ); - Lcorxy = L_mac( Lcorxy, S[i], old_S[i] ); -#endif } Copy( S, old_S, ind_mins[0] ); @@ -304,7 +290,7 @@ Word16 multi_harm_fx( /* o : frame multi-harmonicity cor_strong = 0; move16(); - pt1 = cor_map_LT; + pt1 = cor_map_LT; // Q15 move16(); pt2 = cor_map; move16(); @@ -320,7 +306,7 @@ Word16 multi_harm_fx( /* o : frame multi-harmonicity /* cor_map_LT_sum += *pt1 */ Lcor_map_LT_sum = L_add( Lcor_map_LT_sum, *pt1 ); /* cor_map_LT_sum in Q15; max value is 128) */ - if ( GT_16( *pt1, 31130 ) /*0.95f*/ ) + if ( GT_16( *pt1, 31130 ) /*0.95f.Q15*/ ) { cor_strong = 1; move16(); @@ -330,7 +316,7 @@ Word16 multi_harm_fx( /* o : frame multi-harmonicity pt2++; } - IF( EQ_16( bwidth, NB ) ) + IF( ( bwidth == NB ) ) { /* cor_map_LT_sum *= 1.53f; */ /* tmp2 *= 1.53f; */ @@ -393,6 +379,7 @@ Word16 multi_harm_ivas_fx( /* o : frame multi-harmoni { Word16 i, j, k, L, stemp, N_mins, ind_mins[L_FFT / 4], *pt_mins, harm; Word16 S[L_FFT / 2], flor, step, tmp16, tmp2, Expx2, Expy2; + Word32 tmp2_32; Word16 corx2, cory2, corxy, cor, cor_map[L_FFT / 2], *pt1, *pt2, cor_strong; Word32 L_acc; Word32 Lcorx2, Lcory2, Lcorxy, Lcor_map_LT_sum; @@ -409,7 +396,7 @@ Word16 multi_harm_ivas_fx( /* o : frame multi-harmoni /* length of the useful part of the spectrum (up to 6.4kHz) */ L = L_FFT / 2; move16(); - if ( EQ_16( bwidth, NB ) ) + if ( ( bwidth == NB ) ) { /* length of the useful part of the spectrum (up to 3.6kHz) */ L = 76; @@ -562,11 +549,7 @@ Word16 multi_harm_ivas_fx( /* o : frame multi-harmoni IF( EQ_16( i, ind_mins[k] ) ) { /* include the last peak point (new minimum) to the corr. sum */ -#ifdef BASOP_NOGLOB Lcory2 = L_mac_o( Lcory2, old_S[i], old_S[i], &Overflow ); -#else /* BASOP_NOGLOB */ - Lcory2 = L_mac( Lcory2, old_S[i], old_S[i] ); -#endif /* BASOP_NOGLOB */ /* calculation of the norm. peak correlation */ test(); @@ -592,11 +575,7 @@ Word16 multi_harm_ivas_fx( /* o : frame multi-harmoni corxy = shl( corxy, cor ); /* cor = corxy * corxy / (corx2 * cory2) */ corxy = div_s( corxy, corx2 ); -#ifdef BASOP_NOGLOB cor = shr_o( corxy, sub( shl( tmp16, 1 ), Expx2 ), &Overflow ); /* Q15 */ -#else /* BASOP_NOGLOB */ - cor = shr( corxy, sub( shl( tmp16, 1 ), Expx2 ) ); /* Q15 */ -#endif /* BASOP_NOGLOB */ } ELSE { @@ -621,15 +600,9 @@ Word16 multi_harm_ivas_fx( /* o : frame multi-harmoni k++; } -#ifdef BASOP_NOGLOB Lcorx2 = L_mac_o( Lcorx2, S[i], S[i], &Overflow ); Lcory2 = L_mac_o( Lcory2, old_S[i], old_S[i], &Overflow ); Lcorxy = L_mac_o( Lcorxy, S[i], old_S[i], &Overflow ); -#else /* BASOP_NOGLOB */ - Lcorx2 = L_mac( Lcorx2, S[i], S[i] ); - Lcory2 = L_mac( Lcory2, old_S[i], old_S[i] ); - Lcorxy = L_mac( Lcorxy, S[i], old_S[i] ); -#endif } Copy( S, old_S, ind_mins[0] ); @@ -649,7 +622,7 @@ Word16 multi_harm_ivas_fx( /* o : frame multi-harmoni *------------------------------------------------------------------*/ Lcor_map_LT_sum = L_deposit_l( 0 ); - tmp2 = 0; + tmp2_32 = 0; move16(); cor_strong = 0; @@ -661,7 +634,7 @@ Word16 multi_harm_ivas_fx( /* o : frame multi-harmoni FOR( i = 0; i < L; i++ ) { /* tmp2 += S[i]; */ - tmp2 = add( tmp2, shl( S[i], 1 ) ); /* tmp2 in Q8; max value is 128) */ + tmp2_32 = L_add( tmp2_32, cor_map[i] ); /* tmp2_32 in Q15; max value is 128) */ /* *pt1 = M_ALPHA_FX * *pt1 + (1-M_ALPHA_FX) * *pt2++ */ *pt1 = mac_r( L_mult( ONE_MINUS_M_ALPHA, *pt2 ), M_ALPHA_FX, *pt1 ); @@ -679,8 +652,9 @@ Word16 multi_harm_ivas_fx( /* o : frame multi-harmoni pt1++; pt2++; } + tmp2 = extract_l( L_shr_sat( tmp2_32, 7 ) ); // q15-> q8 - IF( EQ_16( bwidth, NB ) ) + IF( ( bwidth == NB ) ) { /* cor_map_LT_sum *= 1.53f; */ /* tmp2 *= 1.53f; */ diff --git a/lib_enc/nelp_enc.c b/lib_enc/nelp_enc.c deleted file mode 100644 index d1de09bc73bcde0f9193c0b1d468183cb122cda9..0000000000000000000000000000000000000000 --- a/lib_enc/nelp_enc.c +++ /dev/null @@ -1,43 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include -#include "cnst.h" -#include "prot.h" -#include "rom_com.h" -#include "wmc_auto.h" diff --git a/lib_enc/nelp_enc_fx.c b/lib_enc/nelp_enc_fx.c index 259987bba43611a9f4c89041ea1a1ce51cc65533..a7588283a503b6da73f49adf95eccb3ac0473ace 100644 --- a/lib_enc/nelp_enc_fx.c +++ b/lib_enc/nelp_enc_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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,7 +33,6 @@ #include #include "options.h" /* Compilation switches */ #include "cnst.h" /* Common constants */ -#include "prot.h" /* Function prototypes */ #include "prot_fx.h" /* Function prototypes */ #include "prot_fx_enc.h" /* Function prototypes */ #include "rom_com.h" @@ -115,6 +114,7 @@ void quantize_uvg_fx( Word16 *G, Word16 *iG1, Word16 *iG2, Word16 *quantG, Word1 move16(); /*(+1)=/2 in log */ L_tmp = Mpy_32_16( exp, frac, 4932 ); /*Q16 ; 0.5*log10(2) in Q15 */ G1[i] = round_fx( L_shl( L_tmp, 13 ) ); /*Q13 */ + move16(); } ELSE { @@ -129,13 +129,8 @@ void quantize_uvg_fx( Word16 *G, Word16 *iG1, Word16 *iG2, Word16 *quantG, Word1 move16(); FOR( i = 0; i < UVG1_CBSIZE; i++ ) { -#ifdef BASOP_NOGLOB L16 = shr( sub_sat( G1[0], UVG1CB_fx[i][0] ), 1 ); /* Q12 */ L16_1 = shr( sub_sat( G1[1], UVG1CB_fx[i][1] ), 1 ); /* Q12 */ -#else - L16 = shr( sub( G1[0], UVG1CB_fx[i][0] ), 1 ); /* Q12 */ - L16_1 = shr( sub( G1[1], UVG1CB_fx[i][1] ), 1 ); /* Q12 */ -#endif Lacc = 0; Lacc = L_mac0( Lacc, L16, L16 ); /*Q24 */ Lacc = L_mac0( Lacc, L16_1, L16_1 ); /*Q24 */ @@ -152,9 +147,10 @@ void quantize_uvg_fx( Word16 *G, Word16 *iG1, Word16 *iG2, Word16 *quantG, Word1 L_tmp = L_shr( L_tmp, 10 ); /* From Q26 to Q16 */ frac = L_Extract_lc( L_tmp, &exp ); /* Extract exponent of L_tmp */ L_tmp = Pow2( 30, frac ); - exp = exp - 30; /*move16(); */ + exp = exp - 30; + move16(); Lexp[0] = L_shl( L_tmp, exp + 15 ); - + move32(); L_tmp = L_mult0( UVG1CB_fx[*iG1][1], 27213 ); /*Q26 */ L_tmp = L_shr( L_tmp, 10 ); /* From Q26 to Q16 */ @@ -162,7 +158,7 @@ void quantize_uvg_fx( Word16 *G, Word16 *iG1, Word16 *iG2, Word16 *quantG, Word1 L_tmp = Pow2( 30, frac ); exp = exp - 30; /*move16(); */ Lexp[1] = L_shl( L_tmp, exp + 15 ); - + move32(); FOR( i = 0; i < 2; i++ ) { @@ -174,6 +170,7 @@ void quantize_uvg_fx( Word16 *G, Word16 *iG1, Word16 *iG2, Word16 *quantG, Word1 tmp = div_s( 16384, tmp ); /*Q(15+exp) */ L_tmp = L_shr( L_mult0( G[i * 5 + j], tmp ), exp + 3 ); /*Q12 */ G2[i * 5 + j] = extract_l( L_tmp ); /*Q12 */ + move16(); } } @@ -191,25 +188,15 @@ void quantize_uvg_fx( Word16 *G, Word16 *iG1, Word16 *iG2, Word16 *quantG, Word1 { /*mse += SQR(G2[i*5+k]-UVG2CB1[j][k]); */ ind = add( shr( extract_l( L_mult( i, 5 ) ), 1 ), k ); -#ifdef BASOP_NOGLOB temp = sub_sat( G2[ind], UVG2CB1_fx[j][k] ); Lacc = L_mac0_sat( Lacc, temp, temp ); /*Q24 */ -#else - temp = sub( G2[ind], UVG2CB1_fx[j][k] ); - Lacc = L_mac0( Lacc, temp, temp ); /*Q24 */ -#endif } - ELSE IF( i == 1 ) + ELSE IF( EQ_16( i, 1 ) ) { /*mse += SQR(G2[i*5+k]-UVG2CB2[j][k]); */ ind = add( shr( extract_l( L_mult( i, 5 ) ), 1 ), k ); -#ifdef BASOP_NOGLOB temp = sub_sat( G2[ind], UVG2CB2_fx[j][k] ); Lacc = L_mac0_sat( Lacc, temp, temp ); /*Q24 */ -#else - temp = sub( G2[ind], UVG2CB2_fx[j][k] ); - Lacc = L_mac0( Lacc, temp, temp ); /*Q24 */ -#endif } } @@ -256,6 +243,7 @@ static void normalize_arr( Word16 *arr, Word16 *qf, Word16 size, Word16 hdr ) } *qf = norm_s( (Word16) max_s ); + move16(); test(); IF( ( *qf == 0 ) && ( ( (Word16) max_s ) == 0 ) ) { @@ -264,7 +252,7 @@ static void normalize_arr( Word16 *arr, Word16 *qf, Word16 size, Word16 hdr ) } *qf = *qf - hdr; - + move16(); FOR( i = 0; i < size; i++ ) { arr[i] = shl( arr[i], *qf ); @@ -314,41 +302,72 @@ void nelp_encoder_fx( { Word16 i, j; Word16 *ptr_fx = exc_fx; - Word16 lag = 25; /* to cover 25*9 + 31 */ - Word16 sqrt_inv_lag = 6554; /* sqrt(1/lag) in Q15 */ + Word16 lag = 25; /* to cover 25*9 + 31 */ + move16(); + Word16 sqrt_inv_lag = 6554; /* sqrt(1/lag) in Q15 */ + move16(); Word16 sqrt_inv_lframe_lag = 5885; /* sqrt(1/(L_FRAME-lag*9)) */ + move16(); Word16 Gains_fx[10], gain_fac_fx; Word16 iG1_fx, iG2_fx[2]; Word16 fid; Word16 fdbck_fx; Word32 var_dB_fx; Word32 E1_fx = 0, EL1_fx = 0, EH1_fx = 0, E2_fx = 0, E3_fx = 0, EL2_fx = 0, EH2_fx = 0; + move32(); /*E1_fx*/ + move32(); /*EL1_fx*/ + move32(); /*EH1_fx*/ + move32(); /*E2_fx*/ + move32(); /*E3_fx*/ + move32(); /*EL2_fx*/ + move32(); /*EH2_fx*/ Word32 RL_fx = 0, RH_fx = 0; + move32(); /*RL_fx*/ + move32(); /*RH_fx*/ Word16 R_fx = 0; + move16(); Word16 filtRes_fx[L_FRAME]; Word16 ptr_tmp_fx[L_FRAME]; Word16 qE1 = 0, qE2 = 0, qE3 = 0, qEL1 = 0, qEL2 = 0, qEH1 = 0, qEH2 = 0; + move16(); + move16(); + move16(); + move16(); + move16(); + move16(); + move16(); Word16 qIn = 0, qGain = 0, qf = 0, qf1 = 0, qNelpGain = 0; + move16(); + move16(); + move16(); + move16(); + move16(); Word16 exp1, exp2, tmp1, tmp2; Word16 f_Noise, etmp, e_Noise; Word16 max1 = 0; + move16(); Word32 l_nelp_gain_mem; Word32 Ltemp = 0, Ltemp1 = 0, L_tmp = 0, L_const_1; + move32(); + move32(); + move32(); Word16 BP1_ORDER; Word16 rf_flag; #ifdef BASOP_NOGLOB_DECLARE_LOCAL Flag Overflow = 0; + move32(); #endif SC_VBR_ENC_HANDLE hSC_VBR = st_fx->hSC_VBR; BSTR_ENC_HANDLE hBstr = st_fx->hBstr; RF_ENC_HANDLE hRF = st_fx->hRF; rf_flag = st_fx->rf_mode; - + move16(); if ( EQ_16( hSC_VBR->last_nelp_mode, 1 ) && NE_16( st_fx->bwidth, st_fx->last_bwidth ) ) { hSC_VBR->last_nelp_mode = 0; + move16(); } qIn = *qIn1; @@ -403,11 +422,7 @@ void nelp_encoder_fx( E1_fx = L_deposit_l( 0 ); FOR( i = 0; i < L_FRAME; i++ ) { -#ifdef BASOP_NOGLOB E1_fx = L_mac0_o( E1_fx, in_fx[i], in_fx[i], &Overflow ); /*Q(qE1+qE1) */ -#else - E1_fx = L_mac0( E1_fx, in_fx[i], in_fx[i] ); /*Q(qE1+qE1) */ -#endif } qE1 = shl( qE1, 1 ); @@ -423,11 +438,7 @@ void nelp_encoder_fx( EL1_fx = L_deposit_l( 0 ); FOR( i = 0; i < L_FRAME; i++ ) { -#ifdef BASOP_NOGLOB EL1_fx = L_mac0_o( EL1_fx, filtRes_fx[i], filtRes_fx[i], &Overflow ); /*Q(2*qIn) */ -#else - EL1_fx = L_mac0( EL1_fx, filtRes_fx[i], filtRes_fx[i] ); /*Q(2*qIn) */ -#endif } qEL1 = shl( qEL1, 1 ); @@ -443,11 +454,7 @@ void nelp_encoder_fx( EH1_fx = L_deposit_l( 0 ); FOR( i = 0; i < L_FRAME; i++ ) { -#ifdef BASOP_NOGLOB EH1_fx = L_mac0_o( EH1_fx, filtRes_fx[i], filtRes_fx[i], &Overflow ); /*Q(2*qEH1) */ -#else - EH1_fx = L_mac0( EH1_fx, filtRes_fx[i], filtRes_fx[i] ); /*Q(2*qEH1) */ -#endif } qEH1 = 2 * qEH1; move16(); @@ -463,11 +470,7 @@ void nelp_encoder_fx( Ltemp = L_deposit_l( 0 ); FOR( j = (Word16) ( i * lag ); j < (Word16) ( ( i + 1 ) * lag ); j++ ) { -#ifdef BASOP_NOGLOB Ltemp = L_mac0_o( Ltemp, in_fx[j], in_fx[j], &Overflow ); /*Q(2*qGain) */ -#else - Ltemp = L_mac0( Ltemp, in_fx[j], in_fx[j] ); /*Q(2*qGain) */ -#endif } /*Gains[i] = (float) sqrt(Gains[i]/lag); */ @@ -481,28 +484,17 @@ void nelp_encoder_fx( L_tmp = L_deposit_h( tmp1 ); L_tmp = Isqrt_lc( L_tmp, &exp1 ); L_tmp = Mult_32_16( L_tmp, sqrt_inv_lag ); -#ifdef BASOP_NOGLOB Ltemp = L_shl_sat( L_tmp, sub( exp1, 12 ) ); /*Q3 */ -#else - Ltemp = L_shl( L_tmp, sub( exp1, 12 ) ); /*Q3 */ -#endif } -#ifdef BASOP_NOGLOB Gains_fx[i] = round_fx_sat( Ltemp ); -#else - Gains_fx[i] = round_fx( Ltemp ); -#endif + move16(); } Ltemp = L_deposit_l( 0 ); FOR( j = (Word16) ( i * lag ); j < L_FRAME; j++ ) { -#ifdef BASOP_NOGLOB Ltemp = L_mac0_o( Ltemp, in_fx[j], in_fx[j], &Overflow ); /*Q(2*qGain) */ -#else - Ltemp = L_mac0( Ltemp, in_fx[j], in_fx[j] ); /*Q(2*qGain) */ -#endif } /*Gains[i] = (float) sqrt(Gains[i]/(L_FRAME-(lag*i))); */ @@ -516,23 +508,17 @@ void nelp_encoder_fx( L_tmp = L_deposit_h( tmp1 ); L_tmp = Isqrt_lc( L_tmp, &exp1 ); L_tmp = Mult_32_16( L_tmp, sqrt_inv_lframe_lag ); -#ifdef BASOP_NOGLOB Ltemp = L_shl_sat( L_tmp, sub( exp1, 12 ) ); -#else - Ltemp = L_shl( L_tmp, sub( exp1, 12 ) ); -#endif } -#ifdef BASOP_NOGLOB Gains_fx[i] = round_fx_sat( Ltemp ); -#else - Gains_fx[i] = round_fx( Ltemp ); -#endif + move16(); IF( EQ_16( reduce_gains, 1 ) ) { FOR( i = 0; i < 10; i++ ) { Gains_fx[i] = mult( Gains_fx[i], 19661 ); + move16(); } } @@ -563,8 +549,7 @@ void nelp_encoder_fx( L_tmp = L_max( L_tmp, 1 ); exp2 = norm_l( L_tmp ); L_tmp = L_shl( L_tmp, exp2 ); /*15+qEL1-qEL2-exp1+exp2 */ - exp2 = 30 - exp2 - qNelpGain; - move16(); + exp2 = sub( 30, add( exp2, qNelpGain ) ); tmp2 = Log2_norm_lc( L_tmp ); Ltemp1 = Mpy_32_16( exp2, tmp2, 9864 ); /*log(2) in Q13 format = Q0 format */ Ltemp1 = L_sub( Ltemp, Ltemp1 ); /*Q16 */ @@ -587,8 +572,7 @@ void nelp_encoder_fx( L_tmp = L_max( L_tmp, 1 ); exp2 = norm_l( L_tmp ); L_tmp = L_shl( L_tmp, exp2 ); /*15+qEL1-qEL2-exp1+exp2 */ - exp2 = 30 - exp2 - qGain; - move16(); + exp2 = sub( 30, add( exp2, qGain ) ); tmp2 = Log2_norm_lc( L_tmp ); Ltemp1 = Mpy_32_16( exp2, tmp2, 9864 ); /*log(2) in Q13 format = Q0 format */ Ltemp1 = L_sub( Ltemp, Ltemp1 ); /*Q16 */ @@ -641,13 +625,8 @@ void nelp_encoder_fx( IF( e_Noise > 0 ) { -#ifdef BASOP_NOGLOB L_tmp = L_shl_sat( etmp, e_Noise ); /* Result in Q30 */ L_tmp = L_add_sat( 1, L_tmp ); -#else - L_tmp = L_shl( etmp, e_Noise ); /* Result in Q30 */ - L_tmp = L_add( 1, L_tmp ); -#endif exp1 = norm_l( L_tmp ); @@ -670,7 +649,7 @@ void nelp_encoder_fx( } } - IF( exp1 == 31 ) + IF( EQ_16( exp1, 31 ) ) { L_const_1 = 0x7fffffff; move32(); @@ -694,17 +673,13 @@ void nelp_encoder_fx( Ltemp1 = Mult_32_16( l_nelp_gain_mem, fdbck_fx ); /*exp1+qGain-15 */ L_tmp = L_add( L_tmp, Ltemp1 ); L_tmp = L_shr_r( L_tmp, ( exp1 - 15 ) ); -#ifdef BASOP_NOGLOB Gains_fx[i] = round_fx_sat( L_shl_sat( L_tmp, 16 ) ); -#else - Gains_fx[i] = round_fx( L_shl( L_tmp, 16 ) ); -#endif move16(); l_nelp_gain_mem = L_tmp; } hSC_VBR->nelp_gain_mem_fx = round_fx( L_shl( l_nelp_gain_mem, 16 ) ); - + move16(); Scale_sig( &hSC_VBR->nelp_gain_mem_fx, 1, -qGain ); Scale_sig( Gains_fx, 10, -qGain ); qGain = 0; @@ -715,8 +690,11 @@ void nelp_encoder_fx( IF( EQ_16( rf_flag, 1 ) ) { hRF->rf_indx_nelp_iG1[0] = iG1_fx; + move16(); hRF->rf_indx_nelp_iG2[0][0] = iG2_fx[0]; + move16(); hRF->rf_indx_nelp_iG2[0][1] = iG2_fx[1]; + move16(); } ELSE { @@ -746,6 +724,7 @@ void nelp_encoder_fx( IF( EQ_16( st_fx->bwidth, WB ) || EQ_16( st_fx->bwidth, SWB ) ) { BP1_ORDER = 4; + move16(); Scale_sig( hSC_VBR->bp1_filt_mem_wb_fx, BP1_ORDER * 2, qGain - hSC_VBR->qprevGain_fx ); /*qf-qAdj */ pz_filter_sp_fx( bp1_num_coef_wb_fx, bp1_den_coef_wb_fx, ptr_fx, ptr_tmp_fx, hSC_VBR->bp1_filt_mem_wb_fx, BP1_ORDER, BP1_ORDER, L_FRAME, 2 ); Copy( ptr_tmp_fx, ptr_fx, L_FRAME ); @@ -760,21 +739,18 @@ void nelp_encoder_fx( Scale_sig( ptr_fx, L_FRAME, -1 ); /* bring exc to qgain-1 */ *qIn1 = qGain - 1; /* use this temp only in the parent */ + move16(); } E3_fx = L_deposit_l( 0 ); FOR( i = 0; i < L_FRAME; i++ ) { -#ifdef BASOP_NOGLOB E3_fx = L_mac_sat( E3_fx, ptr_fx[i], ptr_fx[i] ); /*Q1 */ -#else - E3_fx = L_mac( E3_fx, ptr_fx[i], ptr_fx[i] ); /*Q1 */ -#endif } qE3 = 2 * qGain + 1; move16(); test(); - IF( st_fx->bwidth == WB || EQ_16( st_fx->bwidth, SWB ) ) + IF( EQ_16( st_fx->bwidth, WB ) || EQ_16( st_fx->bwidth, SWB ) ) { Scale_sig( hSC_VBR->shape1_filt_mem_fx, 10, ( qGain - hSC_VBR->qprevGain_fx ) ); pz_filter_sp_fx( shape1_num_coef_fx, shape1_den_coef_fx, ptr_fx, ptr_tmp_fx, hSC_VBR->shape1_filt_mem_fx, 10, 10, L_FRAME, 1 ); /*1 = (16-qformat of shape1 cofficient) */ @@ -831,11 +807,8 @@ void nelp_encoder_fx( { Ltemp = L_mult0( R_fx, ptr_fx[i] ); Ltemp = L_shr_r( Ltemp, exp1 ); -#ifdef BASOP_NOGLOB filtRes_fx[i] = round_fx_sat( L_shl_sat( Ltemp, 16 ) ); -#else - filtRes_fx[i] = round_fx( L_shl( Ltemp, 16 ) ); -#endif + move16(); } qf1 = qGain; @@ -850,11 +823,7 @@ void nelp_encoder_fx( EL2_fx = L_deposit_l( 0 ); FOR( i = 0; i < L_FRAME; i++ ) { -#ifdef BASOP_NOGLOB EL2_fx = L_mac0_sat( EL2_fx, filtRes_fx[i], filtRes_fx[i] ); /*Q(2*qEL2) */ -#else - EL2_fx = L_mac0( EL2_fx, filtRes_fx[i], filtRes_fx[i] ); /*Q(2*qEL2) */ -#endif } qEL2 = 2 * qEL2; move16(); @@ -863,11 +832,8 @@ void nelp_encoder_fx( { Ltemp = L_mult0( R_fx, ptr_fx[i] ); Ltemp = L_shr_r( Ltemp, exp1 ); -#ifdef BASOP_NOGLOB filtRes_fx[i] = round_fx_sat( L_shl_sat( Ltemp, 16 ) ); -#else - filtRes_fx[i] = round_fx( L_shl( Ltemp, 16 ) ); -#endif + move16(); } qf = qGain; @@ -882,11 +848,7 @@ void nelp_encoder_fx( EH2_fx = L_deposit_l( 0 ); FOR( i = 0; i < L_FRAME; i++ ) { -#ifdef BASOP_NOGLOB EH2_fx = L_mac0_sat( EH2_fx, filtRes_fx[i], filtRes_fx[i] ); /*Q(2*qEH2) */ -#else - EH2_fx = L_mac0( EH2_fx, filtRes_fx[i], filtRes_fx[i] ); /*Q(2*qEH2) */ -#endif } qEH2 = 2 * qEH2; move16(); @@ -894,15 +856,10 @@ void nelp_encoder_fx( { exp2 = norm_l( EL1_fx ); L_tmp = L_shl( EL1_fx, exp2 ); - exp2 = 30 - exp2 - qEL1; - move16(); + exp2 = sub( 30, add( exp2, qEL1 ) ); tmp1 = Log2_norm_lc( L_tmp ); - Ltemp = Mpy_32_16( exp2, tmp1, 9864 ); /*10*log(2) in Q15 format = Q0 format */ -#ifdef BASOP_NOGLOB + Ltemp = Mpy_32_16( exp2, tmp1, 9864 ); /*10*log(2) in Q15 format = Q0 format */ tmp1 = round_fx_sat( L_shl_sat( Ltemp, 12 ) ); /* Q12 */ -#else - tmp1 = round_fx( L_shl( Ltemp, 12 ) ); /* Q12 */ -#endif RL_fx = L_mult0( tmp1, 10 ); } ELSE @@ -913,16 +870,11 @@ void nelp_encoder_fx( L_tmp = Mult_32_16( EL1_fx, tmp1 ); /*qEL1+30-qEL2-exp1-15=>15+qE1-qEL2-exp1 */ exp2 = norm_l( L_tmp ); - L_tmp = L_shl( L_tmp, exp2 ); /*15+qEL1-qEL2-exp1+exp2 */ - exp2 = 30 - ( 30 + qEL1 - qEL2 - exp1 + exp2 ); - move16(); + L_tmp = L_shl( L_tmp, exp2 ); /*15+qEL1-qEL2-exp1+exp2 */ + exp2 = sub( add( qEL2, exp1 ), add( qEL1, exp2 ) ); /*30 - ( 30 + qEL1 - qEL2 - exp1 + exp2 )*/ tmp1 = Log2_norm_lc( L_tmp ); - Ltemp = Mpy_32_16( exp2, tmp1, 9864 ); /*10*log(2) in Q15 format = Q0 format */ -#ifdef BASOP_NOGLOB + Ltemp = Mpy_32_16( exp2, tmp1, 9864 ); /*10*log(2) in Q15 format = Q0 format */ tmp1 = round_fx_sat( L_shl_sat( Ltemp, 12 ) ); /* Q12 */ -#else - tmp1 = round_fx( L_shl( Ltemp, 12 ) ); /* Q12 */ -#endif RL_fx = L_mult0( tmp1, 10 ); } @@ -930,15 +882,10 @@ void nelp_encoder_fx( { exp2 = norm_l( EH2_fx ); L_tmp = L_shl( EH2_fx, exp2 ); - exp2 = 30 - exp2 - qEH2; - move16(); + exp2 = sub( 30, add( exp2, qEH2 ) ); tmp1 = Log2_norm_lc( L_tmp ); - Ltemp = Mpy_32_16( exp2, tmp1, 9864 ); /*10*log(2) in Q13 format = Q0 format */ -#ifdef BASOP_NOGLOB + Ltemp = Mpy_32_16( exp2, tmp1, 9864 ); /*10*log(2) in Q13 format = Q0 format */ tmp1 = round_fx_sat( L_shl_sat( Ltemp, 12 ) ); /* Q12 */ -#else - tmp1 = round_fx( L_shl( Ltemp, 12 ) ); /* Q12 */ -#endif RH_fx = L_mult0( tmp1, 10 ); } ELSE @@ -949,16 +896,11 @@ void nelp_encoder_fx( L_tmp = Mult_32_16( EH1_fx, tmp1 ); /*15+qEH1-qEH2-exp1 */ exp2 = norm_l( L_tmp ); - L_tmp = L_shl( L_tmp, exp2 ); /*15+qEH1-qEH2-exp1+exp2 */ - exp2 = 30 - ( 30 + qEH1 - qEH2 - exp1 + exp2 ); - move16(); + L_tmp = L_shl( L_tmp, exp2 ); /*15+qEH1-qEH2-exp1+exp2 */ + exp2 = sub( add( qEH2, exp1 ), add( qEH1, exp2 ) ); /*30 - ( 30 + qEH1 - qEH2 - exp1 + exp2 )*/ tmp1 = Log2_norm_lc( L_tmp ); - Ltemp = Mpy_32_16( exp2, tmp1, 9864 ); /*10*log(2) in Q13 format = Q0 format */ -#ifdef BASOP_NOGLOB + Ltemp = Mpy_32_16( exp2, tmp1, 9864 ); /*10*log(2) in Q13 format = Q0 format */ tmp1 = round_fx_sat( L_shl_sat( Ltemp, 12 ) ); /* Q12 */ -#else - tmp1 = round_fx( L_shl( Ltemp, 12 ) ); /* Q12 */ -#endif RH_fx = L_mult0( tmp1, 10 ); } @@ -1051,12 +993,11 @@ void nelp_encoder_fx( L_tmp = Mult_32_16( E2_fx, tmp1 ); /*qE2+30-qE3-exp1-15=>15+qE2-qE3-exp1 */ exp2 = norm_l( L_tmp ); - L_tmp = L_shl( L_tmp, exp2 ); /*15+qE2-qE3-exp1+exp2 */ - exp2 = 30 - ( 15 + qE2 - qE3 - exp1 + exp2 ); - move16(); - L_tmp = Isqrt_lc( L_tmp, &exp2 ); /*Q(31+exp2) */ + L_tmp = L_shl( L_tmp, exp2 ); /*15+qE2-qE3-exp1+exp2 */ + exp2 = add( 15, sub( add( qE3, exp1 ), add( qE2, exp2 ) ) ); /*30 - ( 15 + qE2 - qE3 - exp1 + exp2 )*/ + L_tmp = Isqrt_lc( L_tmp, &exp2 ); /*Q(31+exp2) */ R_fx = round_fx( L_tmp ); - exp1 = 31 - exp2 - 16 - 7; + exp1 = sub( 8, exp2 ); /*31 - exp2 - 16 - 7*/ move16(); } @@ -1065,6 +1006,7 @@ void nelp_encoder_fx( L_tmp = L_mult0( R_fx, ptr_fx[i] ); L_tmp = L_shr_r( L_tmp, exp1 + 1 ); ptr_fx[i] = round_fx( L_shl( L_tmp, 16 ) ); + move16(); } *qIn1 = qGain - 1; move16(); @@ -1202,7 +1144,7 @@ void nelp_encoder_ivas_fx( IF( NE_16( hSC_VBR->last_nelp_mode, 1 ) ) { test(); - IF( st_fx->bwidth == WB || EQ_16( st_fx->bwidth, SWB ) ) + IF( EQ_16( st_fx->bwidth, WB ) || EQ_16( st_fx->bwidth, SWB ) ) { set16_fx( hSC_VBR->shape1_filt_mem_fx, 0, 10 ); set16_fx( hSC_VBR->shape2_filt_mem_fx, 0, 10 ); @@ -1227,11 +1169,7 @@ void nelp_encoder_ivas_fx( E1_fx = L_deposit_l( 0 ); FOR( i = 0; i < L_FRAME; i++ ) { -#ifdef BASOP_NOGLOB E1_fx = L_mac0_o( E1_fx, in_fx[i], in_fx[i], &Overflow ); /*Q(qE1+qE1) */ -#else - E1_fx = L_mac0( E1_fx, in_fx[i], in_fx[i] ); /*Q(qE1+qE1) */ -#endif } qE1 = shl( qE1, 1 ); @@ -1246,11 +1184,7 @@ void nelp_encoder_ivas_fx( EL1_fx = L_deposit_l( 0 ); FOR( i = 0; i < L_FRAME; i++ ) { -#ifdef BASOP_NOGLOB EL1_fx = L_mac0_o( EL1_fx, filtRes_fx[i], filtRes_fx[i], &Overflow ); /*Q(2*qIn) */ -#else - EL1_fx = L_mac0( EL1_fx, filtRes_fx[i], filtRes_fx[i] ); /*Q(2*qIn) */ -#endif } qEL1 = shl( qEL1, 1 ); @@ -1266,11 +1200,7 @@ void nelp_encoder_ivas_fx( EH1_fx = L_deposit_l( 0 ); FOR( i = 0; i < L_FRAME; i++ ) { -#ifdef BASOP_NOGLOB EH1_fx = L_mac0_o( EH1_fx, filtRes_fx[i], filtRes_fx[i], &Overflow ); /*Q(2*qEH1) */ -#else - EH1_fx = L_mac0( EH1_fx, filtRes_fx[i], filtRes_fx[i] ); /*Q(2*qEH1) */ -#endif } qEH1 = shl( qEH1, 1 ); move16(); @@ -1279,18 +1209,13 @@ void nelp_encoder_ivas_fx( qGain = qIn; move16(); qGain = shl( qGain, 1 ); - move16(); FOR( i = 0; i < 9; i++ ) { Ltemp = L_deposit_l( 0 ); FOR( j = (Word16) ( i * lag ); j < (Word16) ( ( i + 1 ) * lag ); j++ ) { -#ifdef BASOP_NOGLOB Ltemp = L_mac0_o( Ltemp, in_fx[j], in_fx[j], &Overflow ); /*Q(2*qGain) */ -#else - Ltemp = L_mac0( Ltemp, in_fx[j], in_fx[j] ); /*Q(2*qGain) */ -#endif } /*Gains[i] = (float) sqrt(Gains[i]/lag); */ @@ -1304,17 +1229,9 @@ void nelp_encoder_ivas_fx( L_tmp = L_deposit_h( tmp1 ); L_tmp = Isqrt_lc( L_tmp, &exp1 ); L_tmp = Mult_32_16( L_tmp, sqrt_inv_lag ); -#ifdef BASOP_NOGLOB Ltemp = L_shl_sat( L_tmp, sub( exp1, 12 ) ); /*Q3 */ -#else - Ltemp = L_shl( L_tmp, sub( exp1, 12 ) ); /*Q3 */ -#endif } -#ifdef BASOP_NOGLOB Gains_fx[i] = round_fx_sat( Ltemp ); -#else - Gains_fx[i] = round_fx( Ltemp ); -#endif move16(); } @@ -1322,11 +1239,7 @@ void nelp_encoder_ivas_fx( Ltemp = L_deposit_l( 0 ); FOR( j = i_mult( i, lag ); j < L_FRAME; j++ ) { -#ifdef BASOP_NOGLOB Ltemp = L_mac0_o( Ltemp, in_fx[j], in_fx[j], &Overflow ); /*Q(2*qGain) */ -#else - Ltemp = L_mac0( Ltemp, in_fx[j], in_fx[j] ); /*Q(2*qGain) */ -#endif } /*Gains[i] = (float) sqrt(Gains[i]/(L_FRAME-(lag*i))); */ @@ -1340,18 +1253,10 @@ void nelp_encoder_ivas_fx( L_tmp = L_deposit_h( tmp1 ); L_tmp = Isqrt_lc( L_tmp, &exp1 ); L_tmp = Mult_32_16( L_tmp, sqrt_inv_lframe_lag ); -#ifdef BASOP_NOGLOB Ltemp = L_shl_sat( L_tmp, sub( exp1, 12 ) ); -#else - Ltemp = L_shl( L_tmp, sub( exp1, 12 ) ); -#endif } -#ifdef BASOP_NOGLOB Gains_fx[i] = round_fx_sat( Ltemp ); -#else - Gains_fx[i] = round_fx( Ltemp ); -#endif move16(); IF( EQ_16( reduce_gains, 1 ) ) @@ -1464,13 +1369,8 @@ void nelp_encoder_ivas_fx( IF( e_Noise > 0 ) { -#ifdef BASOP_NOGLOB L_tmp = L_shl_sat( etmp, e_Noise ); /* Result in Q30 */ L_tmp = L_add_sat( 1, L_tmp ); -#else - L_tmp = L_shl( etmp, e_Noise ); /* Result in Q30 */ - L_tmp = L_add( 1, L_tmp ); -#endif exp1 = norm_l( L_tmp ); @@ -1517,11 +1417,7 @@ void nelp_encoder_ivas_fx( Ltemp1 = Mult_32_16( l_nelp_gain_mem, fdbck_fx ); /*exp1+qGain-15 */ L_tmp = L_add( L_tmp, Ltemp1 ); L_tmp = L_shr_r( L_tmp, ( exp1 - 15 ) ); -#ifdef BASOP_NOGLOB Gains_fx[i] = round_fx_sat( L_shl_sat( L_tmp, 16 ) ); -#else - Gains_fx[i] = round_fx( L_shl( L_tmp, 16 ) ); -#endif move16(); l_nelp_gain_mem = L_tmp; } @@ -1593,11 +1489,7 @@ void nelp_encoder_ivas_fx( E3_fx = L_deposit_l( 0 ); FOR( i = 0; i < L_FRAME; i++ ) { -#ifdef BASOP_NOGLOB E3_fx = L_mac_sat( E3_fx, ptr_fx[i], ptr_fx[i] ); /*Q1 */ -#else - E3_fx = L_mac( E3_fx, ptr_fx[i], ptr_fx[i] ); /*Q1 */ -#endif } qE3 = add( shl( qGain, 1 ), 1 ); @@ -1656,11 +1548,7 @@ void nelp_encoder_ivas_fx( { Ltemp = L_mult0( R_fx, ptr_fx[i] ); Ltemp = L_shr_r( Ltemp, exp1 ); -#ifdef BASOP_NOGLOB filtRes_fx[i] = round_fx_sat( L_shl_sat( Ltemp, 16 ) ); -#else - filtRes_fx[i] = round_fx( L_shl( Ltemp, 16 ) ); -#endif move16(); } @@ -1676,11 +1564,7 @@ void nelp_encoder_ivas_fx( EL2_fx = L_deposit_l( 0 ); FOR( i = 0; i < L_FRAME; i++ ) { -#ifdef BASOP_NOGLOB EL2_fx = L_mac0_sat( EL2_fx, filtRes_fx[i], filtRes_fx[i] ); /*Q(2*qEL2) */ -#else - EL2_fx = L_mac0( EL2_fx, filtRes_fx[i], filtRes_fx[i] ); /*Q(2*qEL2) */ -#endif } qEL2 = shl( qEL2, 1 ); @@ -1688,11 +1572,7 @@ void nelp_encoder_ivas_fx( { Ltemp = L_mult0( R_fx, ptr_fx[i] ); Ltemp = L_shr_r( Ltemp, exp1 ); -#ifdef BASOP_NOGLOB filtRes_fx[i] = round_fx_sat( L_shl_sat( Ltemp, 16 ) ); -#else - filtRes_fx[i] = round_fx( L_shl( Ltemp, 16 ) ); -#endif move16(); } @@ -1708,11 +1588,7 @@ void nelp_encoder_ivas_fx( EH2_fx = L_deposit_l( 0 ); FOR( i = 0; i < L_FRAME; i++ ) { -#ifdef BASOP_NOGLOB EH2_fx = L_mac0_sat( EH2_fx, filtRes_fx[i], filtRes_fx[i] ); /*Q(2*qEH2) */ -#else - EH2_fx = L_mac0( EH2_fx, filtRes_fx[i], filtRes_fx[i] ); /*Q(2*qEH2) */ -#endif } qEH2 = shl( qEH2, 1 ); IF( EL2_fx == 0 ) @@ -1721,12 +1597,8 @@ void nelp_encoder_ivas_fx( L_tmp = L_shl( EL1_fx, exp2 ); exp2 = sub( sub( 30, exp2 ), qEL1 ); tmp1 = Log2_norm_lc( L_tmp ); - Ltemp = Mpy_32_16( exp2, tmp1, 9864 ); /*10*log(2) in Q15 format = Q0 format */ -#ifdef BASOP_NOGLOB + Ltemp = Mpy_32_16( exp2, tmp1, 9864 ); /*10*log(2) in Q15 format = Q0 format */ tmp1 = round_fx_sat( L_shl_sat( Ltemp, 12 ) ); /* Q12 */ -#else - tmp1 = round_fx( L_shl( Ltemp, 12 ) ); /* Q12 */ -#endif RL_fx = L_mult0( tmp1, 10 ); } ELSE @@ -1740,12 +1612,8 @@ void nelp_encoder_ivas_fx( L_tmp = L_shl( L_tmp, exp2 ); /*15+qEL1-qEL2-exp1+exp2 */ exp2 = sub( 30, add( sub( sub( add( 30, qEL1 ), qEL2 ), exp1 ), exp2 ) ); tmp1 = Log2_norm_lc( L_tmp ); - Ltemp = Mpy_32_16( exp2, tmp1, 9864 ); /*10*log(2) in Q15 format = Q0 format */ -#ifdef BASOP_NOGLOB + Ltemp = Mpy_32_16( exp2, tmp1, 9864 ); /*10*log(2) in Q15 format = Q0 format */ tmp1 = round_fx_sat( L_shl_sat( Ltemp, 12 ) ); /* Q12 */ -#else - tmp1 = round_fx( L_shl( Ltemp, 12 ) ); /* Q12 */ -#endif RL_fx = L_mult0( tmp1, 10 ); } @@ -1755,12 +1623,8 @@ void nelp_encoder_ivas_fx( L_tmp = L_shl( EH2_fx, exp2 ); exp2 = sub( sub( 30, exp2 ), qEH2 ); tmp1 = Log2_norm_lc( L_tmp ); - Ltemp = Mpy_32_16( exp2, tmp1, 9864 ); /*10*log(2) in Q13 format = Q0 format */ -#ifdef BASOP_NOGLOB + Ltemp = Mpy_32_16( exp2, tmp1, 9864 ); /*10*log(2) in Q13 format = Q0 format */ tmp1 = round_fx_sat( L_shl_sat( Ltemp, 12 ) ); /* Q12 */ -#else - tmp1 = round_fx( L_shl( Ltemp, 12 ) ); /* Q12 */ -#endif RH_fx = L_mult0( tmp1, 10 ); } ELSE @@ -1774,12 +1638,8 @@ void nelp_encoder_ivas_fx( L_tmp = L_shl( L_tmp, exp2 ); /*15+qEH1-qEH2-exp1+exp2 */ exp2 = sub( 30, add( 30, add( sub( sub( qEH1, qEH2 ), exp1 ), exp2 ) ) ); tmp1 = Log2_norm_lc( L_tmp ); - Ltemp = Mpy_32_16( exp2, tmp1, 9864 ); /*10*log(2) in Q13 format = Q0 format */ -#ifdef BASOP_NOGLOB + Ltemp = Mpy_32_16( exp2, tmp1, 9864 ); /*10*log(2) in Q13 format = Q0 format */ tmp1 = round_fx_sat( L_shl_sat( Ltemp, 12 ) ); /* Q12 */ -#else - tmp1 = round_fx( L_shl( Ltemp, 12 ) ); /* Q12 */ -#endif RH_fx = L_mult0( tmp1, 10 ); } @@ -1884,8 +1744,10 @@ void nelp_encoder_ivas_fx( L_tmp = L_mult0( R_fx, ptr_fx[i] ); L_tmp = L_shr_r( L_tmp, exp1 + 1 ); ptr_fx[i] = round_fx( L_shl( L_tmp, 16 ) ); + move16(); } *qIn1 = sub( qGain, 1 ); + move16(); } IF( EQ_16( rf_flag, 1 ) ) diff --git a/lib_enc/nois_est.c b/lib_enc/nois_est.c deleted file mode 100644 index 370e0aeef76d707062c56fbeca491edfb15a05aa..0000000000000000000000000000000000000000 --- a/lib_enc/nois_est.c +++ /dev/null @@ -1,46 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include -#include "cnst.h" -#include "prot.h" -#include "wmc_auto.h" - -/*-----------------------------------------------------------------* - * Local constants - *-----------------------------------------------------------------*/ diff --git a/lib_enc/nois_est_fx.c b/lib_enc/nois_est_fx.c index 2b8bded71038a4a6429a3d3c4721f502e5fe4c25..0851e4c1745ea0f780cac567fafdf0f63564bcd9 100644 --- a/lib_enc/nois_est_fx.c +++ b/lib_enc/nois_est_fx.c @@ -90,13 +90,10 @@ static Word16 noise_est_ln_q8_fx( Word32 L_tmp; #ifdef BASOP_NOGLOB_DECLARE_LOCAL Flag Overflow = 0; + move32(); #endif -#ifdef BASOP_NOGLOB L_tmp = L_add_o( L_enr, L_shl( (Word32) 1L, q_new_plus_q_scale ), &Overflow ); /* +1.0f */ -#else /* BASOP_NOGLOB */ - L_tmp = L_add( L_enr, L_shl( (Word32) 1L, q_new_plus_q_scale ) ); /* +1.0f */ -#endif /* BASOP_NOGLOB */ if ( flag_add1p0 == 0 ) { L_tmp = L_add( L_enr, 0 ); /* +0 , no offset */ @@ -192,15 +189,14 @@ void noise_est_init_fx( hNoiseEst->ave_enr_q = Q7; move16(); - move16(); hNoiseEst->totalNoise_fx = 0; move16(); hNoiseEst->first_noise_updt = 0; - // hNoiseEst->first_noise_updt_cnt_fx = 0; IVAS_CODE ?? move16(); hNoiseEst->aEn = 6; - // hNoiseEst->aEn_inac_cnt = 0; IVAS_CODE + move16(); + hNoiseEst->aEn_inac_cnt = 0; move16(); hNoiseEst->harm_cor_cnt = 0; @@ -221,7 +217,8 @@ void noise_est_init_fx( hNoiseEst->Etot_st_est_fx = 5120; /* 20.0f in Q8 */ hNoiseEst->Etot_sq_st_est_fx = 1600; /* 400 in Q2 */ - //### + move16(); + move16(); hNoiseEst->epsP_0_2_lp_fx = 4096; /*1.0 Q12*/ move16(); @@ -248,7 +245,7 @@ void noise_est_init_fx( hNoiseEst->noise_char_fx = 0; move16(); hNoiseEst->multi_harm_limit_fx = THR_CORR_INIT_FX; - + move16(); hNoiseEst->Etot_lp_fx = 0; hNoiseEst->Etot_h_fx = 0; hNoiseEst->Etot_l_fx = 0; @@ -272,16 +269,7 @@ void noise_est_init_ivas_fx( ) { Word16 i; -#ifdef IVAS_FLOAT_FIXED_CONVERSIONS - hNoiseEst->first_noise_updt = 0; - hNoiseEst->first_noise_updt_cnt = 0; - hNoiseEst->aEn = 6; - hNoiseEst->aEn_inac_cnt = 0; - hNoiseEst->harm_cor_cnt = 0; - hNoiseEst->bg_cnt = 0; - hNoiseEst->low_tn_track_cnt = 0; -#endif FOR( i = 0; i < NB_BANDS; i++ ) { hNoiseEst->fr_bands1_fx[i] = 1; @@ -310,13 +298,14 @@ void noise_est_init_ivas_fx( hNoiseEst->totalNoise_fx = 0; move16(); hNoiseEst->first_noise_updt = 0; - // hNoiseEst->first_noise_updt_cnt_fx = 0; IVAS_CODE ?? + move16(); + hNoiseEst->first_noise_updt_cnt = 0; move16(); hNoiseEst->aEn = 6; - // hNoiseEst->aEn_inac_cnt = 0; IVAS_CODE move16(); - + hNoiseEst->aEn_inac_cnt = 0; + move16(); hNoiseEst->harm_cor_cnt = 0; move16(); hNoiseEst->bg_cnt = 0; @@ -335,8 +324,12 @@ void noise_est_init_ivas_fx( hNoiseEst->Etot_st_est_fx = 5120; /* 20.0f in Q8 */ hNoiseEst->Etot_sq_st_est_fx = 1600; /* 400 in Q2 */ - //### - + move16(); + move16(); + hNoiseEst->L_Etot_st_est_fx = 167772160; /* 20.0f in Q23 */ + hNoiseEst->L_Etot_sq_st_est_fx = 26214400; /* 400 in Q16 */ + move32(); + move32(); hNoiseEst->epsP_0_2_lp_fx = 4096; /*1.0 Q12*/ move16(); hNoiseEst->epsP_0_2_ad_lp_fx = 0; @@ -362,7 +355,7 @@ void noise_est_init_ivas_fx( hNoiseEst->noise_char_fx = 0; move16(); hNoiseEst->multi_harm_limit_fx = THR_CORR_INIT_FX; - + move16(); hNoiseEst->Etot_lp_fx = 0; hNoiseEst->Etot_h_fx = 0; hNoiseEst->Etot_l_fx = 0; @@ -387,12 +380,12 @@ void noise_est_init_ivas_fx( *-----------------------------------------------------------------*/ void noise_est_pre_fx( - const Word16 Etot, /* i : Energy of current frame */ - const Word16 ini_frame_fx, /* i : Frame number (init) */ - NOISE_EST_HANDLE hNoiseEst, /* i/o: Noise estimation handle */ - const int16_t idchan, /* i : channel ID */ - const int16_t element_mode, /* i : element mode */ - const int16_t last_element_mode /* i : last element mode */ + const Word16 Etot, /* i : Energy of current frame */ + const Word16 ini_frame_fx, /* i : Frame number (init) */ + NOISE_EST_HANDLE hNoiseEst, /* i/o: Noise estimation handle */ + const Word16 idchan, /* i : channel ID */ + const Word16 element_mode, /* i : element mode */ + const Word16 last_element_mode /* i : last element mode */ ) { Word16 tmp; @@ -459,7 +452,8 @@ void noise_est_pre_fx( } hNoiseEst->Etot_l_fx = s_min( hNoiseEst->Etot_l_fx, Etot ); - + move16(); + test(); IF( LT_16( ini_frame_fx, 100 ) && LT_16( hNoiseEst->Etot_l_fx, hNoiseEst->Etot_l_lp_fx ) ) { /**Etot_l_lp = 0.1f * *Etot_l + (1.0f - 0.1) * *Etot_l_lp; */ @@ -482,10 +476,12 @@ void noise_est_pre_fx( { /* *Etot_l_lp = 0.02f * *Etot_l + (1.0f - 0.02f) * *Etot_l_lp; */ hNoiseEst->Etot_l_lp_fx = round_fx( L_mac( L_mult( 655, hNoiseEst->Etot_l_fx ), 32113, hNoiseEst->Etot_l_lp_fx ) ); + move16(); } } /**sign_dyn_lp = 0.1f * (*Etot_h - *Etot_l) + (1.0f - 0.1f) * *sign_dyn_lp;*/ hNoiseEst->sign_dyn_lp_fx = round_fx( L_mac( L_mult( 3277, sub_sat( hNoiseEst->Etot_h_fx, hNoiseEst->Etot_l_fx ) ), 29491, hNoiseEst->sign_dyn_lp_fx ) ); + move16(); } return; @@ -671,11 +667,7 @@ void noise_est_down_fx( totalNoise_temp = L_deposit_l( 0 ); FOR( i = min_band; i <= max_band; i++ ) { -#ifdef BASOP_NOGLOB totalNoise_temp = L_add_o( totalNoise_temp, bckr[i], &Overflow ); /*Q_new+QSCALE*/ -#else - totalNoise_temp = L_add( totalNoise_temp, bckr[i] ); /*Q_new+QSCALE*/ -#endif } totalNoise_temp = L_max( totalNoise_temp, L_shl( e_min, 4 ) ); @@ -689,7 +681,7 @@ void noise_est_down_fx( e_Noise = sub( e_Noise, scale ); Ltmp = Mpy_32_16( e_Noise, f_Noise, LG10 ); *totalNoise = round_fx( L_shl( Ltmp, 10 ) ); /*Q8*/ - + move16(); /*-----------------------------------------------------------------* * Average energy per frame for each frequency band *-----------------------------------------------------------------*/ @@ -699,11 +691,7 @@ void noise_est_down_fx( FOR( i = 0; i < NB_BANDS; i++ ) { -#ifdef BASOP_NOGLOB Ltmp = L_add_o( L_shr_r( *pt1, 1 ), L_shr_r( *pt2, 1 ), &Overflow ); -#else /* BASOP_NOGLOB */ - Ltmp = L_add( L_shr_r( *pt1, 1 ), L_shr_r( *pt2, 1 ) ); -#endif /* BASOP_NOGLOB */ /*Ltmp = L_shr_r(L_add(*pt1,*pt2),1);*/ enr[i] = Ltmp; move32(); /*Q_new+QSCALE*/ @@ -722,7 +710,7 @@ void noise_est_down_fx( tmpN[i] = Madd_32_16( L_tmp, bckr[i], ALPHAM1_FX ); move32(); /*Q_new+QSCALE*/ tmpN[i] = L_max( tmpN[i], e_min ); /* handle div by zero in find_tilt_fx */ - + move32(); /* if( tmpN[i] < bckr[i] ) { bckr[i] = tmpN[i]; }*/ /* Defend to increase noise estimate: keep as it is or decrease */ bckr[i] = L_max( L_min( bckr[i], tmpN[i] ), e_min ); @@ -741,9 +729,122 @@ void noise_est_down_fx( L_tmp = Mult_32_16( L_Etot_v, 655 ); /*.02 in Q15 , Q24+Q15+1 -16 ==> Q24 ) */ *Etot_v_h2 = round_fx( L_add( L_Etot_v_h2, L_tmp ) ); /*Q24->Q8*/ - + move16(); /* if (*Etot_v_h2 < 0.1f) { *Etot_v_h2 = 0.1f; } */ *Etot_v_h2 = s_max( *Etot_v_h2, 26 ); /* 0.1 in Q8*/ + move16(); + return; +} + +void noise_est_down_ivas_fx( + const Word32 fr_bands[], /* i : per band input energy (contains 2 vectors) q_fr_bands */ + const Word16 q_fr_bands, /* i : Q of fr_bands */ + Word32 bckr[], /* i/o: per band background noise energy estimate q_fr_bands */ + Word32 tmpN[], /* o : temporary noise update q_fr_bands */ + Word32 enr[], /* o : averaged energy over both subframes */ + const Word16 min_band, /* i : minimum critical band */ + const Word16 max_band, /* i : maximum critical band */ + Word16 *totalNoise, /* o : noise estimate over all critical bands */ + Word16 Etot, /* i : Energy of current frame */ + Word16 *Etot_last, /* i/o: Energy of last frame Q8 */ + Word16 *Etot_v_h2 /* i/o: Energy variations of noise frames Q8 */ +) + +{ + Word32 Ltmp, L_tmp; + const Word32 *pt1, *pt2; + Word16 i; + Word16 e_Noise, f_Noise; + Word32 e_min; + Word32 totalNoise_temp; + Word32 L_Etot, L_Etot_last, L_Etot_v_h2, L_Etot_v; + Word64 sum; + Word16 q_sum; + + e_min = L_shl( E_MIN_FXQ31, sub( q_fr_bands, Q31 ) ); // q_fr_bands + + L_Etot = L_shl( Etot, 16 ); /*Q24 for later AR1 computations*/ + L_Etot_last = L_shl( *Etot_last, 16 ); + L_Etot_v_h2 = L_shl( *Etot_v_h2, 16 ); + + /*-----------------------------------------------------------------* + * Estimate total noise energy + *-----------------------------------------------------------------*/ + + totalNoise_temp = L_deposit_l( 0 ); + sum = 0; + move64(); + FOR( i = min_band; i <= max_band; i++ ) + { + sum = W_mac_32_16( sum, bckr[i], 1 ); // q_fr_bands+1 + } + q_sum = add( q_fr_bands, 1 ); + IF( sum == 0 ) + { + sum = W_mult0_32_32( E_MIN_FXQ31, add( sub( max_band, min_band ), 1 ) ); // Q31 + q_sum = Q31; + move16(); + } + e_Noise = W_norm( sum ); + totalNoise_temp = W_extract_h( W_shl( sum, e_Noise ) ); // q_sum+e_Noise-32 + e_Noise = sub( 63, add( e_Noise, q_sum ) ); // 31-(q_sum+e_Noise-32) + + /*totalNoise = 10.0f * (float)log10( *totalNoise );*/ + f_Noise = Log2_norm_lc( totalNoise_temp ); // exponent of log => 30-0 = 30 + e_Noise = sub( e_Noise, 1 ); // 30-(31-e_Noise) = e_Noise-1 + Ltmp = L_mac( L_deposit_h( e_Noise ), f_Noise, 1 ); // Q16 + Ltmp = Mpy_32_16_1( Ltmp, LG10 ); // Q14 (16+13-15) + Ltmp = L_shl( Ltmp, 10 ); // Q26 + *totalNoise = round_fx( Ltmp ); /*Q8*/ + move16(); + + /*-----------------------------------------------------------------* + * Average energy per frame for each frequency band + *-----------------------------------------------------------------*/ + + pt1 = fr_bands; + pt2 = fr_bands + NB_BANDS; + + FOR( i = 0; i < NB_BANDS; i++ ) + { + /* enr[i] = 0.5f * ( *pt1++ + *pt2++ ); */ + enr[i] = W_extract_h( W_mac_32_32( W_mult_32_32( *pt1, ONE_IN_Q30 ), *pt2, ONE_IN_Q30 ) ); // q_fr_bands+30+1-32+1 = q_fr_bands + move32(); + pt1++; + pt2++; + } + + /*-----------------------------------------------------------------* + * Background noise energy update + *-----------------------------------------------------------------*/ + + FOR( i = 0; i < NB_BANDS; i++ ) + { + /* tmpN[i] = (1-ALPHA) * bckr[i] + ALPHA * enr[i]; */ + /* handle div by zero in find_tilt_fx */ + tmpN[i] = L_max( Madd_32_16( Mpy_32_16_1( bckr[i], ALPHAM1_FX ), enr[i], ALPHA_FX ), e_min ); // q_fr_bands + move32(); + + /* if( tmpN[i] < bckr[i] ) { bckr[i] = tmpN[i]; }*/ + /* Defend to increase noise estimate: keep as it is or decrease */ + bckr[i] = L_max( L_min( bckr[i], tmpN[i] ), e_min ); // q_fr_bands + move32(); + } + + /*------------------------------------------------------------------* + * Energy variation update + *------------------------------------------------------------------*/ + /*Etot_v = (float) fabs(*Etot_last - Etot);*/ + L_Etot_v = L_abs( L_sub( L_Etot_last, L_Etot ) ); /* Q24 */ + + /* *Etot_v_h2 = (1.0f-0.02f) * *Etot_v_h2 + 0.02f * min(3.0f, Etot_v); */ + L_tmp = L_min( 50331648 /* 3.0f in Q24 */, L_Etot_v ); // Q24 + L_tmp = Mult_32_16( L_tmp, 655 /*.02 in Q15 */ ); // Q24 + L_Etot_v_h2 = Madd_32_16( L_tmp, L_Etot_v_h2, 32113 /* 0.98 in Q15 */ ); // Q24 + + /* if (*Etot_v_h2 < 0.1f) { *Etot_v_h2 = 0.1f; } */ + *Etot_v_h2 = s_max( round_fx( L_Etot_v_h2 ), 26 /* 0.1 in Q8*/ ); // Q8 + move16(); return; } @@ -780,11 +881,7 @@ void noise_est_fx( const Word32 Le_min_scaled, /*i : Minimum energy value in Q_new + Q_SCALE */ Word16 *sp_floor, /* o : noise floor estimate Q7 */ Word16 S_map[], /* o : short-term correlation map Q7 */ -#ifdef IVAS_CODE - STEREO_CLASSIF_HANDLE hStereoClassif, /* i/o: stereo classifier structure */ - FRONT_VAD_ENC_HANDLE hFrontVad, /* i/o: front-VAD handle */ -#endif - const Word16 ini_frame /* i : Frame number (init) */ + const Word16 ini_frame /* i : Frame number (init) */ ) { Word16 alpha, alpha2, alpha2m1, alpham1; @@ -829,14 +926,8 @@ void noise_est_fx( #ifdef REMOVE_IVAS_UNUSED_PARAMETERS_WARNING (void) ( ncharX ); #endif + /* Check if LR-VAD */ -#ifdef IVAS_CODE - IF( hFrontVad != NULL ) - { - hNoiseEst = hFrontVad->hNoiseEst; - } - ELSE -#endif { hNoiseEst = st_fx->hNoiseEst; } @@ -844,6 +935,7 @@ void noise_est_fx( GSC_ENC_HANDLE hGSCEnc = st_fx->hGSCEnc; #ifdef BASOP_NOGLOB_DECLARE_LOCAL Flag Overflow = 0; + move32(); #endif /*-----------------------------------------------------------------* @@ -853,11 +945,8 @@ void noise_est_fx( move16(); /*st_fx->ener_RAT = 10.0f * (float)log10( mean(lf_E, 8));*/ -#ifdef IVAS_CODE - IF( hFrontVad == NULL ) -#endif { - if ( hSpMusClas != NULL ) + IF( hSpMusClas != NULL ) { Ltmp = L_shr( lf_E[0], 3 ); FOR( i = 1; i < 8; i++ ) @@ -867,6 +956,7 @@ void noise_est_fx( IF( LT_32( Ltmp, L_shl( 1, add( Q_new, Q_SCALE - 2 ) ) ) ) { hSpMusClas->ener_RAT_fx = 0; + move16(); // PMT("hSpMusClas->ener_RAT_fx = 0, that should be validated") } ELSE @@ -888,9 +978,10 @@ void noise_est_fx( { hSpMusClas->ener_RAT_fx = 32767; move16(); /*Q15*/ - if ( GE_16( wtmp1, wtmp ) ) + IF( GE_16( wtmp1, wtmp ) ) { hSpMusClas->ener_RAT_fx = div_s( wtmp, wtmp1 ); /*Q15*/ /* wtmp1 gte than wtmp */ + move16(); } } } @@ -904,7 +995,7 @@ void noise_est_fx( * order" spectral envelope => the epsP ratio is much less effective. *-----------------------------------------------------------------*/ - IF( NE_16( vad_bwidth_fx, NB ) ) /* WB input */ + IF( vad_bwidth_fx != NB ) /* WB input */ { th_eps = TH_EPS16_FX; move16(); /*Q11*/ @@ -940,13 +1031,8 @@ void noise_est_fx( Ltmp = L_deposit_h( corr_shift ); Ltmp = L_mac( Ltmp, st_fx->voicing_fx[0], 10923 ); -#ifdef BASOP_NOGLOB Ltmp = L_mac_o( Ltmp, st_fx->voicing_fx[1], 10923, &Overflow ); wtmp = mac_ro( Ltmp, st_fx->voicing_fx[2], 10923, &Overflow ); -#else /* BASOP_NOGLOB */ - Ltmp = L_mac( Ltmp, st_fx->voicing_fx[1], 10923 ); - wtmp = mac_r( Ltmp, st_fx->voicing_fx[2], 10923 ); -#endif /* BASOP_NOGLOB */ tmp_pc = pc; move16(); @@ -956,14 +1042,12 @@ void noise_est_fx( move16(); /* low correlation -> probably inactive signal */ } - move16(); /* Update */ + /* Update */ /*-----------------------------------------------------------------* * Multi-harmonic analysis *-----------------------------------------------------------------*/ -#ifdef IVAS_CODE - IF( hFrontVad == NULL ) -#endif + { IF( st_fx->hSpMusClas != NULL ) { @@ -971,6 +1055,7 @@ void noise_est_fx( move16(); *loc_harm = multi_harm_fx( EspecdB, hNoiseEst->old_S_fx, hNoiseEst->cor_map_fx, &hNoiseEst->multi_harm_limit_fx, st_fx->total_brate, st_fx->bwidth, ( st_fx->hGSCEnc != NULL ) ? &hGSCEnc->cor_strong_limit : &i, &hSpMusClas->mean_avr_dyn_fx, &hSpMusClas->last_sw_dyn_fx, cor_map_sum, sp_floor, S_map ); + move16(); } } /*-----------------------------------------------------------------* @@ -1000,11 +1085,7 @@ void noise_est_fx( FOR( i = 10; i <= st_fx->max_band; i++ ) { Lnum = L_max( *pt1, *pt2 ); /* Don't need if anymore */ -#ifdef BASOP_NOGLOB Lsum_den = L_add_o( Lsum_den, Lnum, &Overflow ); -#else /* BASOP_NOGLOB */ - Lsum_den = L_add( Lsum_den, Lnum ); -#endif /* BASOP_NOGLOB */ Ltmpden = L_min( *pt1, *pt2 ); if ( Ltmpden == 0 ) { @@ -1060,17 +1141,8 @@ void noise_est_fx( /* calculation of energy in the rest of bands */ Ltmp2 = sum32_fx( &fr_bands[10], sub( st_fx->max_band, 9 ) ); -#ifdef BASOP_NOGLOB wtmp = shl_o( 1, sub( add( Q_new, QSCALE ), 1 ), &Overflow ); -#else /* BASOP_NOGLOB */ - wtmp = shl( 1, sub( add( Q_new, QSCALE ), 1 ) ); -#endif /* BASOP_NOGLOB */ -#ifdef IVAS_CODE - IF( ncharX != NULL ) - { - *ncharX = ftemp2 / ( ftemp + 1e-5f ); - } -#endif + test(); IF( L_msu( Ltmp, 100, wtmp ) < 0 || L_msu( Ltmp2, 100, wtmp ) < 0 ) { @@ -1086,11 +1158,7 @@ void noise_est_fx( ExpDen = norm_l( Ltmp ); den = extract_h( L_shl( Ltmp, ExpDen ) ); num = div_s( num, den ); -#ifdef BASOP_NOGLOB noise_chartmp = extract_h( L_shr_o( num, add( sub( ExpNum, ExpDen ), 4 - 16 ), &Overflow ) ); /* Q11 */ -#else /* BASOP_NOGLOB */ - noise_chartmp = extract_h( L_shr( num, add( sub( ExpNum, ExpDen ), 4 - 16 ) ) ); /* Q11 */ -#endif /* BASOP_NOGLOB */ } noise_chartmp = s_min( noise_chartmp, (Word16) 10 << 11 ); /* Q11 */ @@ -1102,7 +1170,7 @@ void noise_est_fx( nchar_thr = THR_NCHAR_WB_FX; move16(); /* 1.0 Q11 */ - if ( EQ_16( vad_bwidth_fx, NB ) ) + if ( vad_bwidth_fx == NB ) { nchar_thr = THR_NCHAR_NB_FX; move16(); /* 1.0 Q11 */ @@ -1131,13 +1199,9 @@ void noise_est_fx( tmp = s_max( relE, 0 ); /* Q8 */ /* alpha = 0.064f * ftemp + 0.75f; */ - Ltmp = Mult_32_16( (Word32) 137438953L, tmp ); /* Q31(.064)+Q8+1-16 --> Q24 */ - Ltmp = L_mac( Ltmp, 256, 24576 ); /* Q8+Q15(.75)+1 --> Q24 */ -#ifdef BASOP_NOGLOB + Ltmp = Mult_32_16( (Word32) 137438953L, tmp ); /* Q31(.064)+Q8+1-16 --> Q24 */ + Ltmp = L_mac( Ltmp, 256, 24576 ); /* Q8+Q15(.75)+1 --> Q24 */ alpha = round_fx_o( L_shl_o( Ltmp, 7, &Overflow ), &Overflow ); /*Q24 +7 --> Q31 Q15*/ -#else /* BASOP_NOGLOB */ - alpha = round_fx( L_shl( Ltmp, 7 ) ); /*Q24 +7 --> Q31 Q15*/ -#endif /* BASOP_NOGLOB */ /*if( alpha > 0.999f { alpha = 0.999f;} */ alpha = s_min( alpha, 32735 ); /*.999 in Q15*/ @@ -1172,14 +1236,9 @@ void noise_est_fx( /* + 1.0f added to reduce sensitivity to non stationarity in low energies */ /* tmp_enr = enr[i] + 1.0f; */ tmp_Q = add( Q_new, Q_SCALE ); - Ltmp = L_shl( (Word32) 1L, tmp_Q ); /* 1.0 added in the right dynamic domain */ -#ifdef BASOP_NOGLOB + Ltmp = L_shl( (Word32) 1L, tmp_Q ); /* 1.0 added in the right dynamic domain */ L_tmp_enr = L_add_o( enr[i], Ltmp, &Overflow ); /* enr scale dynamic */ L_tmp_ave_enr = L_add_o( hNoiseEst->ave_enr_fx[i], Ltmp, &Overflow ); /* ave__enr scale dynamic */ -#else /* BASOP_NOGLOB */ - L_tmp_enr = L_add( enr[i], Ltmp ); /* enr scale dynamic */ - L_tmp_ave_enr = L_add( hNoiseEst->ave_enr_fx[i], Ltmp ); /* ave__enr scale dynamic */ -#endif /* BASOP_NOGLOB */ IF( LE_32( non_sta, th_sta ) ) /* Just to limit the saturation */ { @@ -1198,11 +1257,7 @@ void noise_est_fx( den = extract_h( L_shl( Lden, ExpDen ) ); num = div_s( num, den ); Ltmp = Mult_32_16( non_sta, num ); -#ifdef BASOP_NOGLOB non_sta = L_shr_o( Ltmp, sub( ExpNum, ExpDen ), &Overflow ); /* Q10 */ -#else /* BASOP_NOGLOB */ - non_sta = L_shr( Ltmp, sub( ExpNum, ExpDen ) ); /* Q10 */ -#endif /* BASOP_NOGLOB */ } /* st->ave_enr[i] = alpha * st->ave_enr[i] + (1-alpha) * enr[i];*/ /* update long-term average */ @@ -1222,14 +1277,10 @@ void noise_est_fx( } */ /* ave_enr2:: calculation of another non-stationarity measure (following attacks) */ - Ltmp = L_shl( (Word32) 1L, tmp_Q ); /* 1.0 added in the right dynamic domain */ - /*L_tmp_enr = L_add(enr[i] , Ltmp );*/ /* enr scale dynamic , done above */ -#ifdef BASOP_NOGLOB + Ltmp = L_shl( (Word32) 1L, tmp_Q ); /* 1.0 added in the right dynamic domain */ + /*L_tmp_enr = L_add(enr[i] , Ltmp );*/ /* enr scale dynamic , done above */ L_tmp_ave_enr2 = L_add_o( hNoiseEst->ave_enr2_fx[i], Ltmp, &Overflow ); /* ave__enr scale dynamic */ -#else - L_tmp_ave_enr2 = L_add( hNoiseEst->ave_enr2_fx[i], Ltmp ); /* ave__enr scale dynamic */ -#endif - IF( LE_32( Lnon_sta2, th_sta ) ) /* Just to limit the saturation */ + IF( LE_32( Lnon_sta2, th_sta ) ) /* Just to limit the saturation */ { Lnum = L_max( L_tmp_enr, L_tmp_ave_enr2 ); Lden = L_min( L_tmp_enr, L_tmp_ave_enr2 ); @@ -1241,11 +1292,7 @@ void noise_est_fx( den = extract_h( L_shl( Lden, ExpDen ) ); num = div_s( num, den ); Ltmp1 = Mult_32_16( Lnon_sta2, num ); -#ifdef BASOP_NOGLOB Lnon_sta2 = L_shr_o( Ltmp1, sub( ExpNum, ExpDen ), &Overflow ); /* Q10 */ -#else /* BASOP_NOGLOB */ - Lnon_sta2 = L_shr( Ltmp1, sub( ExpNum, ExpDen ) ); /* Q10 */ -#endif /* BASOP_NOGLOB */ } /* st_ave_enr2[i] = (float)alpha2 * st_ave_enr2[i] @@ -1256,9 +1303,6 @@ void noise_est_fx( move32(); /* calculation of non-stationarity measure for speech/music classification */ -#ifdef IVAS_CODE - IF( hFrontVad == NULL ) -#endif { test(); test(); @@ -1267,16 +1311,13 @@ void noise_est_fx( /* log_enr = (float)ln_fx(enr[i]); */ log_enr16 = noise_est_ln_q8_fx( enr[i], 0, tmp_Q ); wtmp = abs_s( sub( log_enr16, hSpMusClas->past_log_enr_fx[i - START_BAND_SPMUS] ) ); -#ifdef BASOP_NOGLOB *non_staX = add_o( *non_staX, wtmp, &Overflow ); -#else /* BASOP_NOGLOB */ - *non_staX = add( *non_staX, wtmp ); -#endif /* BASOP_NOGLOB */ move16(); /* Q8 */ hSpMusClas->past_log_enr_fx[i - START_BAND_SPMUS] = log_enr16; move16(); } } + test(); IF( GE_16( i, 2 ) && LE_16( i, 16 ) ) { IF( GE_16( ini_frame, 100 ) ) @@ -1286,11 +1327,7 @@ void noise_est_fx( tmp_floor = LN_E_MIN_PLUS_ONE_FX; move16(); /* non dynamic init constant in Q8 */ tmp_floor = noise_est_ln_q8_fx( hNoiseEst->bckr_fx[i], 1, tmp_Q ); -#ifdef BASOP_NOGLOB non_staB = add_o( non_staB, abs_s( sub( tmp_enr, tmp_floor ) ), &Overflow ); /* Q8 */ -#else /* BASOP_NOGLOB */ - non_staB = add( non_staB, abs_s( sub( tmp_enr, tmp_floor ) ) ); /* Q8 */ -#endif /* BASOP_NOGLOB */ } ELSE /*ini_frame < 100*/ { @@ -1299,11 +1336,7 @@ void noise_est_fx( tmp_floor = LN_E_MIN_PLUS_ONE_FX; move16(); /* non dynamic init constant in Q8 */ tmp_floor = noise_est_ln_q8_fx( E_MIN_FX, 1, tmp_Q ); -#ifdef BASOP_NOGLOB non_staB = add_o( non_staB, abs_s( sub( tmp_enr, tmp_floor ) ), &Overflow ); /* Q8 */ -#else /* BASOP_NOGLOB */ - non_staB = add( non_staB, abs_s( sub( tmp_enr, tmp_floor ) ) ); /* Q8 */ -#endif /* BASOP_NOGLOB */ } } @@ -1318,7 +1351,7 @@ void noise_est_fx( lim_Etot_fx = s_max( 5120, Etot ); /* 20.0f Q8 */ lim_Etot_sq_fx = extract_h( L_shl_r( L_mult( lim_Etot_fx, lim_Etot_fx ), 1 ) ); /* Q2 */ - if ( st_fx->ini_frame < 150 ) + IF( LT_16( st_fx->ini_frame, 150 ) ) { /* Allow use of quicker filter during init - if needed */ /* st->Etot_st_est = 0.25f * lim_Etot + (1.0f-0.25F) * st->Etot_st_est; */ @@ -1328,7 +1361,7 @@ void noise_est_fx( hNoiseEst->Etot_sq_st_est_fx = mac_r( L_mult( 8192, lim_Etot_sq_fx ), 24576, hNoiseEst->Etot_sq_st_est_fx ); move16(); } - else + ELSE { /* st->Etot_st_est = 0.25f * lim_Etot + (1.0f-0.25F) * st->Etot_st_est; */ hNoiseEst->Etot_st_est_fx = mac_r( L_mult( 8192, lim_Etot_fx ), 24576, hNoiseEst->Etot_st_est_fx ); @@ -1351,20 +1384,24 @@ void noise_est_fx( test(); test(); *st_harm_cor_cnt = add( *st_harm_cor_cnt, 1 ); + move16(); if ( ( Etot > 0 ) && ( ( *loc_harm > 0 ) || ( GT_16( round_fx( Ltmp ), COR_MAX_NNE_FX ) ) ) ) { *st_harm_cor_cnt = 0; move16(); } - - IF( ( GT_16( *st_harm_cor_cnt, 1 ) ) && ( ( LT_16( Etot, 3840 ) ) || /* 15 in Q8 */ - ( GT_16( st_fx->ini_frame, 10 ) && - GT_16( sub( Etot, hNoiseEst->Etot_lp_fx ), 1792 ) ) ) /* 7 in Q8 */ + test(); + test(); + test(); + if ( ( GT_16( *st_harm_cor_cnt, 1 ) ) && ( ( LT_16( Etot, 3840 ) ) || /* 15 in Q8 */ + ( GT_16( st_fx->ini_frame, 10 ) && + GT_16( sub( Etot, hNoiseEst->Etot_lp_fx ), 1792 ) ) ) /* 7 in Q8 */ ) { *st_harm_cor_cnt = 1; } - + test(); + test(); if ( GT_16( *st_harm_cor_cnt, 1 ) && GT_16( Etot, 7680 ) && /* 30.0f in Q8 */ GT_16( st_E_var_est_fx, 32 ) /* 8.0f in Q2 */ @@ -1373,6 +1410,7 @@ void noise_est_fx( /* st->harm_cor_cnt = max(1, (short) round_f( (float) st->harm_cor_cnt / 4.0f )) ; */ *st_harm_cor_cnt = s_max( 1, shr( add( *st_harm_cor_cnt, 2 ), 1 ) ); + move16(); } @@ -1408,13 +1446,9 @@ void noise_est_fx( /*epsP_0_2 = max(0 , min(8, epsP[0] / epsP[2])); */ Ltmp = eps_quota_fx( epsP_h[0], epsP_l[0], - epsP_h[2], epsP_l[2], 12 ); /* Word32 Q12 */ - BASOP_SATURATE_WARNING_OFF_EVS /* may saturate*/ -#ifdef BASOP_NOGLOB + epsP_h[2], epsP_l[2], 12 ); /* Word32 Q12 */ + BASOP_SATURATE_WARNING_OFF_EVS /* may saturate*/ epsP_0_2 = round_fx_o( L_shl_o( Ltmp, 16, &Overflow ), &Overflow ); /* Q12+16 -16 -> Q12 , NB saturation in Q12 sets max value to 7,999 */ -#else /* BASOP_NOGLOB */ - epsP_0_2 = round_fx( L_shl( Ltmp, 16 ) ); /* Q12+16 -16 -> Q12 , NB saturation in Q12 sets max value to 7,999 */ -#endif /* BASOP_NOGLOB */ BASOP_SATURATE_WARNING_ON_EVS epsP_0_2 = s_max( 0, epsP_0_2 ); /* min value is 0 , Q12 */ @@ -1424,7 +1458,7 @@ void noise_est_fx( alpha = 4915; move16(); /*0.15 in Q15 */ hNoiseEst->epsP_0_2_lp_fx = noise_est_AR1_Qx( epsP_0_2, hNoiseEst->epsP_0_2_lp_fx, alpha ); - + move16(); /* epsP_0_2_ad = (float) fabs(epsP_0_2 - st->epsP_0_2_lp ); */ epsP_0_2_ad = abs_s( sub( epsP_0_2, hNoiseEst->epsP_0_2_lp_fx ) ); /* Q12 */ @@ -1440,7 +1474,7 @@ void noise_est_fx( alpha = shr( alpha, 1 ); /* 0.1 Q15 */ } hNoiseEst->epsP_0_2_ad_lp_fx = noise_est_AR1_Qx( epsP_0_2_ad, hNoiseEst->epsP_0_2_ad_lp_fx, alpha ); - + move16(); /* epsP_0_2_ad_lp_max = max(epsP_0_2_ad,st->epsP_0_2_ad_lp);*/ epsP_0_2_ad_lp_max = s_max( epsP_0_2_ad, hNoiseEst->epsP_0_2_ad_lp_fx ); /* Q12 */ @@ -1451,15 +1485,10 @@ void noise_est_fx( /* epsP_2_16 = max(0 , min(8, epsP[2] / epsP[16])); */ Ltmp = eps_quota_fx( epsP_h[2], epsP_l[2], - epsP_h[16], epsP_l[16], 12 ); /* Word32 Q12 */ - BASOP_SATURATE_WARNING_OFF_EVS /* may saturate*/ -#ifdef BASOP_NOGLOB + epsP_h[16], epsP_l[16], 12 ); /* Word32 Q12 */ + BASOP_SATURATE_WARNING_OFF_EVS /* may saturate*/ epsP_2_16 = round_fx_o( L_shl_o( Ltmp, 16, &Overflow ), &Overflow ); /* Q12+16 -16 -> Q12 , NB saturation in Q12 sets max value to 7,999 */ -#else /* BASOP_NOGLOB */ - epsP_2_16 = round_fx( L_shl( Ltmp, 16 ) ); /* Q12+16 -16 -> Q12 , - NB saturation in Q12 sets max value to 7,999 */ -#endif /* BASOP_NOGLOB */ BASOP_SATURATE_WARNING_ON_EVS epsP_2_16 = s_max( 0, epsP_2_16 ); /* min value is 0 , Q12 */ @@ -1481,9 +1510,9 @@ void noise_est_fx( move16(); /* 0.2 Q15 */ } hNoiseEst->epsP_2_16_lp_fx = noise_est_AR1_Qx( epsP_2_16, hNoiseEst->epsP_2_16_lp_fx, alpha ); - + move16(); hNoiseEst->epsP_2_16_lp2_fx = noise_est_AR1_Qx( epsP_2_16, hNoiseEst->epsP_2_16_lp2_fx, 655 ); /* 0.02 */ - + move16(); epsP_2_16_dlp = sub( hNoiseEst->epsP_2_16_lp_fx, hNoiseEst->epsP_2_16_lp2_fx ); @@ -1500,7 +1529,7 @@ void noise_est_fx( move16(); /* 0.02 Q15 */ } hNoiseEst->epsP_2_16_dlp_lp2_fx = noise_est_AR1_Qx( epsP_2_16_dlp, hNoiseEst->epsP_2_16_dlp_lp2_fx, alpha ); - + move16(); /* epsP_2_16_dlp_max = max(epsP_2_16_dlp,st->epsP_2_16_dlp_lp2); */ epsP_2_16_dlp_max = s_max( epsP_2_16_dlp, hNoiseEst->epsP_2_16_dlp_lp2_fx ); @@ -1518,14 +1547,14 @@ void noise_est_fx( move16(); } hNoiseEst->lt_tn_track_fx = noise_est_AR1_Qx( tmp2, hNoiseEst->lt_tn_track_fx, 983 ); /*0.03 in Q15 ,Q15 state*/ - + move16(); /* st->lt_tn_dist = 0.03f* (Etot - st->totalNoise) + 0.97f*st->lt_tn_dist; */ hNoiseEst->lt_tn_dist_fx = noise_est_AR1_Qx( tmp, hNoiseEst->lt_tn_dist_fx, 983 ); /*0.03 in Q15 ,Q8 state*/ - + move16(); /* st->lt_Ellp_dist = 0.03f* (Etot - st->Etot_l_lp) + 0.97f*st->lt_Ellp_dist;*/ tmp = sub( Etot, hNoiseEst->Etot_l_lp_fx ); /* Q8 */ hNoiseEst->lt_Ellp_dist_fx = noise_est_AR1_Qx( tmp, hNoiseEst->lt_Ellp_dist_fx, 983 ); /*0.03 in Q15 ,Q8 state*/ - + move16(); /* if (st->harm_cor_cnt == 0) { st->lt_haco_ev = 0.03f*1.0 + 0.97f*st->lt_haco_ev; @@ -1540,7 +1569,7 @@ void noise_est_fx( { hNoiseEst->lt_haco_ev_fx = mult_r( 32440, hNoiseEst->lt_haco_ev_fx ); /*.99 in Q15 , Q15 state */ } - + move16(); /* if (st->lt_tn_track < 0.05f) { st->low_tn_track_cnt++; @@ -1581,11 +1610,7 @@ void noise_est_fx( *-----------------------------------------------------------------*/ Ltmp = L_mult( st_fx->voicing_fx[0], 16384 ); Ltmp = L_mac( Ltmp, st_fx->voicing_fx[1], 16384 ); -#ifdef BASOP_NOGLOB cor_tmp = mac_ro( Ltmp, corr_shift, MAX_16, &Overflow ); -#else /* BASOP_NOGLOB */ - cor_tmp = mac_r( Ltmp, corr_shift, MAX_16 ); -#endif LepsP = eps_quota_fx( epsP_h[2], epsP_l[2], epsP_h[16], epsP_l[16], 11 ); /* L_epsP in Q11 */ @@ -1650,39 +1675,6 @@ void noise_est_fx( hNoiseEst->aEn = s_min( hNoiseEst->aEn, 6 ); hNoiseEst->aEn = s_max( hNoiseEst->aEn, 0 ); -#ifdef IVAS_CODE - /*-----------------------------------------------------------------* - * Stereo classifier - save raw aEn - *-----------------------------------------------------------------*/ - - if ( hStereoClassif != NULL ) - { - if ( ( non_sta > th_sta ) || - ( tmp_pc < TH_PC ) || - ( 0.5f * ( st->voicing[0] + st->voicing[1] ) > cor_max ) || - ( epsP[2] / epsP[16] > th_eps ) || - ( ( hNoiseEst->act_pred > 0.8f ) && ( non_sta2 > th_sta ) ) ) - { - /* active signal present - increment counter */ - hStereoClassif->aEn_raw[st->idchan] = hStereoClassif->aEn_raw[st->idchan] + 2; - } - else - { - /* background noise present - decrement counter */ - hStereoClassif->aEn_raw[st->idchan] = hStereoClassif->aEn_raw[st->idchan] - 1; - } - - if ( hStereoClassif->aEn_raw[st->idchan] > 6 ) - { - hStereoClassif->aEn_raw[st->idchan] = 6; - } - else if ( hStereoClassif->aEn_raw[st->idchan] < 0 ) - { - hStereoClassif->aEn_raw[st->idchan] = 0; - } - } -#endif - /* Additional NNE detectors */ @@ -1918,13 +1910,20 @@ void noise_est_fx( test(); test(); test(); - if ( ( ( LT_16( hNoiseEst->act_pred_fx, 19333 ) ) && ( LT_16( hNoiseEst->lt_haco_ev_fx, 7537 ) ) ) /* .59 in Q15 .23 in Q15 */ - || ( LT_16( hNoiseEst->act_pred_fx, 12452 ) ) /* .38 in Q15 */ - || ( ( EQ_16( st_fx->element_mode, EVS_MONO ) && LT_16( hNoiseEst->lt_haco_ev_fx, 4915 ) ) || ( GT_16( st_fx->element_mode, EVS_MONO ) && LT_16( hNoiseEst->lt_haco_ev_fx, 2621 ) ) ) /* .15 in Q15 || 0.08 */ - || ( LT_16( non_staB, 50 * 256 ) ) /* 50.0 in Q8 */ - || aE_bgd != 0 || ( ( LT_16( Etot, 10752 ) ) /* 42 in Q8 */ - && ( GT_16( hNoiseEst->harm_cor_cnt, 10 ) ) && ( LT_16( hNoiseEst->lt_haco_ev_fx, 11469 ) ) /* 0.35 in Q15 */ - && ( LT_16( hNoiseEst->act_pred_fx, 26214 ) ) /* 0.80 in Q15 */ + test(); + test(); + test(); + test(); + test(); + test(); + test(); + if ( ( ( LT_16( hNoiseEst->act_pred_fx, 19333 ) ) && ( LT_16( hNoiseEst->lt_haco_ev_fx, 7537 ) ) ) /* .59 in Q15 .23 in Q15 */ + || ( LT_16( hNoiseEst->act_pred_fx, 12452 ) ) /* .38 in Q15 */ + || ( ( st_fx->element_mode == EVS_MONO && LT_16( hNoiseEst->lt_haco_ev_fx, 4915 ) ) || ( st_fx->element_mode > EVS_MONO && LT_16( hNoiseEst->lt_haco_ev_fx, 2621 ) ) ) /* .15 in Q15 || 0.08 */ + || ( LT_16( non_staB, 50 * 256 ) ) /* 50.0 in Q8 */ + || aE_bgd != 0 || ( ( LT_16( Etot, 10752 ) ) /* 42 in Q8 */ + && ( GT_16( hNoiseEst->harm_cor_cnt, 10 ) ) && ( LT_16( hNoiseEst->lt_haco_ev_fx, 11469 ) ) /* 0.35 in Q15 */ + && ( LT_16( hNoiseEst->act_pred_fx, 26214 ) ) /* 0.80 in Q15 */ ) ) { tmp = 1; @@ -1935,6 +1934,7 @@ void noise_est_fx( move16(); test(); test(); + test(); if ( ( LT_16( st_fx->ini_frame, HE_LT_CNT_INIT_FX ) ) && ( GT_16( hNoiseEst->harm_cor_cnt, 5 ) ) /* > 5 Q0 */ && ( LT_16( sub( Etot, hNoiseEst->Etot_lp_fx ), 1792 ) ) /* 7 in Q8 */ && ( NE_16( tmp, 0 ) ) ) @@ -2007,8 +2007,6 @@ void noise_est_fx( test(); test(); test(); - test(); - test(); IF( ( ( LT_16( hNoiseEst->act_pred_fx, 27853 ) ) /* 0.85 in Q15 */ && ( NE_16( aE_bgd, 0 ) ) && ( ( LT_16( hNoiseEst->lt_Ellp_dist_fx, 10 * 256 ) ) || ( NE_16( sd1_bgd, 0 ) ) ) /* 10.0 in Q8*/ && ( LT_16( hNoiseEst->lt_tn_dist_fx, 40 * 256 ) ) /* 40.0 in Q8*/ @@ -2023,6 +2021,7 @@ void noise_est_fx( updt_step = 32767; move16(); hNoiseEst->first_noise_updt = 1; + move16(); FOR( i = 0; i < NB_BANDS; i++ ) { hNoiseEst->bckr_fx[i] = tmpN[i]; @@ -2092,6 +2091,7 @@ void noise_est_fx( ELSE IF( ( aE_bgd != 0 ) || ( GT_16( hNoiseEst->harm_cor_cnt, 100 ) ) ) { hNoiseEst->first_noise_updt = add( hNoiseEst->first_noise_updt, 1 ); + move16(); } } ELSE @@ -2124,19 +2124,9 @@ void noise_est_fx( move16(); } hNoiseEst->lt_aEn_zero_fx = noise_est_AR1_Qx( tmp, hNoiseEst->lt_aEn_zero_fx, 6554 ); /* alpha=0.2 , Q15 */ + move16(); } -#ifdef IVAS_CODE - IF( GT_16( st_fx->element_mode, EVS_MONO ) ) - { - test(); - if ( hNoiseEst->first_noise_updt_cnt_fx > 0 && LT_16( hNoiseEst->first_noise_updt_cnt_fx, 100 ) ) - { - hNoiseEst->first_noise_updt_cnt_fx = add( hNoiseEst->first_noise_updt_cnt_fx, 1 ); - } - } -#endif - return; } @@ -2149,27 +2139,27 @@ void noise_est_ivas_fx( Encoder_State *st_fx, /* i/o: state structure */ const Word16 old_pitch1, /* i : previous frame OL pitch[1] */ const Word32 tmpN[], /* i : temporary noise update Q_new + QSCALE */ - const Word16 epsP_h[], /* i : msb prediction error energies Q_r-1 */ - const Word16 epsP_l[], /* i : msb prediction error energies Q_r-1 */ + const Word32 epsP[], /* i : msb prediction error energies Qx */ const Word16 Etot, /* i : total channel E (see find_enr_fx.c) Q8 */ const Word16 relE, /* i : (VA_CHECK addition) relative frame energy Q8? */ const Word16 corr_shift, /* i : normalized correlation correction Q15 */ - const Word32 enr[], /* i : averaged energy over both subframes Q_new + Q_SCALE */ - Word32 fr_bands[], /* i : spectrum per critical bands of the current frame Q_new + Q_SCALE */ + const Word32 enr[], /* i : averaged energy over both subframes q_enr */ + const Word16 q_enr, /* i : q_enr of enr Q0 */ + Word32 fr_bands[], /* i : spectrum per critical bands of the current frame q_fr_bands */ + Word16 q_fr_bands, /* i : Q of q_fr_bands */ Word16 *cor_map_sum, /* o : Q8 */ Word16 *ncharX, /* o : Q11 */ Word16 *sp_div, /* o : Q_sp_div */ Word16 *Q_sp_div, /* o : Q factor for sp_div */ Word16 *non_staX, /* o : non-stationarity for sp/mus classifier Q8 */ Word16 *loc_harm, /* o : multi-harmonicity flag for UV classifier */ - const Word32 *lf_E, /* i : per bin energy for low frequencies Q_new + Q_SCALE -2 */ + const Word32 *lf_E, /* i : per bin energy for low frequencies q_lf_E */ + const Word16 q_lf_E, /* i : Q of lf_E Q0 */ Word16 *st_harm_cor_cnt, /* i/o : 1st harm correlation timer Q0 */ const Word16 Etot_l_lp, /* i : Smoothed low energy Q8 */ const Word16 Etot_v_h2, /* i : Energy variations Q8 */ Word16 *bg_cnt, /* i : Background burst length timer Q0 */ Word16 EspecdB[], /* i/o: log E spectrum (with f=0) of the current frame Q7 for multi harm */ - Word16 Q_new, /* i : SCaling of current frame */ - const Word32 Le_min_scaled, /*i : Minimum energy value in Q_new + Q_SCALE */ Word16 *sp_floor, /* o : noise floor estimate Q7 */ Word16 S_map[], /* o : short-term correlation map Q7 */ STEREO_CLASSIF_HANDLE hStereoClassif, /* i/o: stereo classifier structure */ @@ -2179,9 +2169,9 @@ void noise_est_ivas_fx( { Word16 alpha, alpha2, alpha2m1, alpham1; Word16 cor_min, cor_max, num, den, ExpNum, ExpDen, noise_chartmp; - Word16 wtmp1, wtmp, ExpLmax, ExpLmax2, tmpExp, nchar_thr, cor_tmp; + Word16 wtmp1, wtmp, nchar_thr, cor_tmp; Word16 i, tmp_pc, pc, th_eps; - Word32 th_sta, Lnum, Lden, non_sta, LepsP, Ltmpden; + Word32 th_sta, Lnum, Lden, non_sta, LepsP; Word16 e_ener, f_ener; Word32 Ltmp, Ltmp1, Lsum_num, Lsum_den, *pt1, *pt2, Ltmp2, Lnon_sta2; Word64 w_sum_num, w_tmp; @@ -2200,23 +2190,32 @@ void noise_est_ivas_fx( Word16 enr_bgd, cns_bgd, lp_bgd, ns_mask; Word16 lt_haco_mask, bg_haco_mask; - Word16 SD_1, SD_1_inv, bg_bgd3, PD_1, PD_2, PD_3, PD_4, PD_5; + Word16 SD_1, bg_bgd3, PD_1, PD_2, PD_3, PD_4, PD_5; Word16 non_staB; /* Q8 */ - Word32 L_tmp_enr, L_tmp_ave_enr, L_tmp_ave_enr2; - Word16 tmp_Q; + Word32 L_tmp_enr, L_tmp_ave, L_tmp_ave2; Word16 tmp, tmp2; /* general temp registers */ Word16 tmp_enr, tmp_floor; /* constants in Q8 */ Word16 vad_bwidth_fx; /* vad ns control variabel for input bwidth from teh BWD */ /* for DTX operation */ - Word16 vad_2nd_stage_fx; - Word16 lim_Etot_fx; /* Q8 */ - Word16 lim_Etot_sq_fx; /* Q2 */ - Word16 st_E_var_est_fx; /* Q2 */ + Word16 lim_Etot_fx; /* Q8 */ + Word32 lim_Etot_sq_fx; /* Q16 */ + Word32 st_E_var_est_fx; NOISE_EST_HANDLE hNoiseEst; SP_MUS_CLAS_HANDLE hSpMusClas; + Word32 Le_min_scaled; + Word64 temp; hSpMusClas = st_fx->hSpMusClas; + + Le_min_scaled = L_shl( E_MIN_FXQ31, sub( q_fr_bands, Q31 ) ); // q_fr_bands + + GSC_ENC_HANDLE hGSCEnc = st_fx->hGSCEnc; +#ifdef BASOP_NOGLOB_DECLARE_LOCAL + Flag Overflow = 0; + move32(); +#endif + /* Check if LR-VAD */ IF( hFrontVad != NULL ) { @@ -2227,56 +2226,61 @@ void noise_est_ivas_fx( hNoiseEst = st_fx->hNoiseEst; } - GSC_ENC_HANDLE hGSCEnc = st_fx->hGSCEnc; -#ifdef BASOP_NOGLOB_DECLARE_LOCAL - Flag Overflow = 0; - move32(); -#endif - /*-----------------------------------------------------------------* * Initialization *-----------------------------------------------------------------*/ vad_bwidth_fx = st_fx->input_bwidth; move16(); - /*st_fx->ener_RAT = 10.0f * (float)log10( mean(lf_E, 8));*/ + /*st_fx->ener_RAT = 10.0f * (float)log10( mean(lf_E, 8));*/ + temp = 0; + move64(); IF( hFrontVad == NULL ) { - if ( hSpMusClas != NULL ) + IF( hSpMusClas != NULL ) { - Ltmp = L_shr( lf_E[0], 3 ); - FOR( i = 1; i < 8; i++ ) + /* E = mean( lf_E, 8 ); */ + FOR( i = 0; i < 8; i++ ) { - Ltmp = L_add( Ltmp, L_shr( lf_E[i], 3 ) ); + temp = W_mac_32_16( temp, lf_E[i], 1 ); // q_lf_E+1 } - IF( LT_32( Ltmp, L_shl( 1, add( Q_new, Q_SCALE - 2 ) ) ) ) + /* (temp / 8) */ + Ltmp = W_extract_l( W_shr( temp, 4 ) ); // q_lf_E+1 -> q_lf_E + + IF( LT_32( Ltmp, L_shl_sat( 1, q_lf_E ) ) ) { hSpMusClas->ener_RAT_fx = 0; - // PMT("hSpMusClas->ener_RAT_fx = 0, that should be validated") } ELSE { - Ltmp = L_max( Ltmp, (Word32) 1L ); /* make sure log2_norm_lc does not cause table reading out of bounds */ e_ener = norm_l( Ltmp ); f_ener = Log2_norm_lc( L_shl( Ltmp, e_ener ) ); e_ener = sub( 30, e_ener ); - e_ener = sub( e_ener, sub( add( Q_new, QSCALE ), 2 ) ); - Ltmp = Mpy_32_16( e_ener, f_ener, LG10 ); - wtmp = round_fx( L_shl( Ltmp, 10 ) ); /*Q8*/ - - /* st_fx->ener_RAT /= (Etot + 0.01f); */ - wtmp1 = add( Etot, 3 ); /*3 is 0.01 in Q8 */ - /* st_fx->ener_RAT_fx = wtmp/wtmp1 */ + e_ener = sub( e_ener, q_lf_E ); + Ltmp = L_mac( L_deposit_h( e_ener ), f_ener, 1 ); // Q16 + Ltmp = Mpy_32_16_1( Ltmp, LG10 ); // Q14 (16+13-15) + Ltmp = L_shl( Ltmp, 10 ); // Q24 + wtmp = round_fx( Ltmp ); /*Q8*/ + + /* st_fx->ener_RAT /= (Etot + 0.01f); + if ( st->hSpMusClas->ener_RAT > 1.0 ) + { + st->hSpMusClas->ener_RAT = 1.0f; + } + */ + + wtmp1 = add( Etot, 3 ); /* 0.01f in Q8 */ hSpMusClas->ener_RAT_fx = 0; move16(); IF( wtmp > 0 ) { hSpMusClas->ener_RAT_fx = 32767; move16(); /*Q15*/ - if ( GE_16( wtmp1, wtmp ) ) + IF( GE_16( wtmp1, wtmp ) ) { hSpMusClas->ener_RAT_fx = div_s( wtmp, wtmp1 ); /*Q15*/ /* wtmp1 gte than wtmp */ + move16(); } } } @@ -2290,7 +2294,7 @@ void noise_est_ivas_fx( * order" spectral envelope => the epsP ratio is much less effective. *-----------------------------------------------------------------*/ - IF( NE_16( vad_bwidth_fx, NB ) ) /* WB input */ + IF( vad_bwidth_fx != NB ) /* WB input */ { th_eps = TH_EPS16_FX; move16(); /*Q11*/ @@ -2326,13 +2330,8 @@ void noise_est_ivas_fx( Ltmp = L_deposit_h( corr_shift ); Ltmp = L_mac( Ltmp, st_fx->voicing_fx[0], 10923 ); -#ifdef BASOP_NOGLOB Ltmp = L_mac_o( Ltmp, st_fx->voicing_fx[1], 10923, &Overflow ); wtmp = mac_ro( Ltmp, st_fx->voicing_fx[2], 10923, &Overflow ); -#else /* BASOP_NOGLOB */ - Ltmp = L_mac( Ltmp, st_fx->voicing_fx[1], 10923 ); - wtmp = mac_r( Ltmp, st_fx->voicing_fx[2], 10923 ); -#endif /* BASOP_NOGLOB */ tmp_pc = pc; move16(); @@ -2342,7 +2341,7 @@ void noise_est_ivas_fx( move16(); /* low correlation -> probably inactive signal */ } - move16(); /* Update */ + /* Update */ /*-----------------------------------------------------------------* * Multi-harmonic analysis @@ -2361,95 +2360,115 @@ void noise_est_ivas_fx( /*-----------------------------------------------------------------* * Detection of frames with non-stationary spectral content *-----------------------------------------------------------------*/ - /* weighted sum of spectral changes per critical bands */ w_sum_num = 0; move64(); Lsum_den = L_deposit_l( 0 ); - /* Find a proper scaling to prevent overflow, but acheiving good computation on low level signals */ - tmpExp = 0; - move16(); - ExpLmax = sub( 30, norm_l( fr_bands[10] ) ); - ExpLmax2 = sub( 30, norm_l( hNoiseEst->fr_bands2_fx[10] ) ); - tmpExp = s_max( tmpExp, sub( shl( s_max( ExpLmax, ExpLmax2 ), 1 ), s_min( ExpLmax, ExpLmax2 ) ) ); - FOR( i = 11; i <= st_fx->max_band; i++ ) - { - ExpLmax = sub( 30, norm_l( fr_bands[i] ) ); - ExpLmax2 = sub( 30, norm_l( hNoiseEst->fr_bands2_fx[i] ) ); - tmpExp = s_max( tmpExp, sub( shl( s_max( ExpLmax, ExpLmax2 ), 1 ), s_min( ExpLmax, ExpLmax2 ) ) ); - } - tmpExp = sub( tmpExp, 30 - 4 - 4 ); /* 4bits for internal summation and 4 bits for comparaison */ - pt1 = fr_bands + 10; pt2 = hNoiseEst->fr_bands2_fx + 10; + Word64 w_sum_den; + Word16 exp, exp2; + w_sum_den = 0; + move64(); FOR( i = 10; i <= st_fx->max_band; i++ ) { - Lnum = L_max( *pt1, *pt2 ); /* Don't need if anymore */ -#ifdef BASOP_NOGLOB - Lsum_den = L_add_o( Lsum_den, Lnum, &Overflow ); -#else /* BASOP_NOGLOB */ - Lsum_den = L_add( Lsum_den, Lnum ); -#endif /* BASOP_NOGLOB */ - Ltmpden = L_min( *pt1, *pt2 ); - if ( Ltmpden == 0 ) + Lnum = L_max( *pt1, *pt2 ); + Lden = L_min( *pt1, *pt2 ); + + w_sum_den = W_mac_32_16( w_sum_den, Lnum, 1 ); // q_fr_bands+1 + + exp = sub( norm_l( Lnum ), 1 ); + Lnum = L_shl( Lnum, exp ); // q_fr_bands+exp + num = extract_h( Mpy_32_32( Lnum, Lnum ) ); // 2*(q_fr_bands+exp)-31-16 + ExpNum = add( sub( shl( q_fr_bands, 1 ), 47 ), shl( exp, 1 ) ); + + + den = E_MIN_FXQ31 >> 8; // 29360, 0.0035f in Q23 + ExpDen = Q23; + move32(); + move16(); + + IF( Lden != 0 ) { - Ltmpden = L_add( Ltmpden, 1 ); + exp = norm_l( Lden ); + den = extract_h( L_shl( Lden, exp ) ); // q_fr_bands+ExpDen-16 + ExpDen = sub( add( q_fr_bands, exp ), Q16 ); } - ExpNum = sub( norm_l( Lnum ), 1 ); - num = extract_h( L_shl( Lnum, ExpNum ) ); - num = mult_r( num, num ); - ExpDen = norm_l( Ltmpden ); - den = extract_h( L_shl( Ltmpden, ExpDen ) ); - num = div_s( num, den ); - w_tmp = W_shr( num, add( sub( sub( shl( ExpNum, 1 ), ExpDen ), 15 + 1 ), tmpExp ) ); + + num = div_s( num, den ); // Q15+ExpNum-ExpDen + w_tmp = W_shl( num, sub( q_fr_bands, sub( ExpNum, ExpDen ) ) ); // q_fr_bands+15 w_sum_num = W_add( w_sum_num, w_tmp ); pt1++; pt2++; } - Lsum_den = L_shr( Lsum_den, tmpExp ); ExpNum = W_norm( w_sum_num ); - Lsum_num = W_extract_h( W_shl( w_sum_num, ExpNum ) ); - ExpNum = sub( ExpNum, 32 ); + Lsum_num = W_extract_h( W_shl( w_sum_num, ExpNum ) ); // q_fr_bands+15+ExpNum-32 + ExpNum = add( q_fr_bands, sub( ExpNum, 17 ) ); + + ExpDen = W_norm( w_sum_den ); + Lsum_den = W_extract_h( W_shl( w_sum_den, ExpDen ) ); // q_fr_bands+1+ExpDen-32 + ExpDen = add( add( q_fr_bands, 1 ), sub( ExpDen, 32 ) ); /* calculation of spectral diversity */ /* THR_SPDIV_FX = 5 , 1/5 Q15 = 6554 */ spec_div = 0; move16(); - if ( GT_32( Mult_32_16( Lsum_num, 6554 ), L_shl_sat( Lsum_den, ExpNum ) ) ) /* Qx+Q15+1-16 ==> Qx */ + if ( GT_32( Mult_32_16( Lsum_num, 6554 ), L_shl_sat( Lsum_den, sub( ExpNum, ExpDen ) ) ) ) /* Qx+Q15+1-16 ==> Qx */ { spec_div = 1; move16(); } /* *sp_div = Lsum_num / (Lsum_den + 1e-5f); */ - Lsum_den = L_add( Lsum_den, 1 ); - Word16 exp = 0; + IF( Lsum_den == 0 ) + { + Lsum_den = 1407374884; // 1e-5 in Q47 + ExpDen = 47; + move32(); + move16(); + } + *sp_div = BASOP_Util_Divide3232_Scale( Lsum_num, Lsum_den, &exp ); move16(); - - *Q_sp_div = add( sub( 15, exp ), ExpNum ); + *Q_sp_div = add( sub( 15, exp ), sub( ExpNum, ExpDen ) ); move16(); /*-----------------------------------------------------------------* * Detection of frames with high energy content in high frequencies *-----------------------------------------------------------------*/ + pt1 = &fr_bands[st_fx->min_band]; + pt2 = &fr_bands[10]; + w_sum_num = 0; + w_sum_den = 0; + move64(); + move64(); + /* calculation of energy in first 10 critical bands */ - Ltmp = sum32_fx( &fr_bands[st_fx->min_band], sub( 10, st_fx->min_band ) ); + FOR( i = 0; i < sub( 10, st_fx->min_band ); i++ ) + { + w_sum_den = W_mac_32_16( w_sum_den, *pt1, 1 ); // q_fr_bands+1 + pt1++; + } + exp = W_norm( w_sum_den ); + Ltmp = W_extract_h( W_shl( w_sum_den, exp ) ); // q_fr_bands+1+exp-32 + exp = sub( add( q_fr_bands, exp ), 31 ); /* calculation of energy in the rest of bands */ - Ltmp2 = sum32_fx( &fr_bands[10], sub( st_fx->max_band, 9 ) ); + FOR( i = 0; i < sub( st_fx->max_band, 9 ); i++ ) + { + w_sum_num = W_mac_32_16( w_sum_num, *pt2, 1 ); + pt2++; + } + exp2 = sub( W_norm( w_sum_num ), 1 ); + Ltmp2 = W_extract_h( W_shl( w_sum_num, exp2 ) ); // q_fr_bands+1+exp2-32 + exp2 = sub( add( q_fr_bands, exp2 ), 31 ); -#ifdef BASOP_NOGLOB - wtmp = shl_o( 1, sub( add( Q_new, QSCALE ), 1 ), &Overflow ); -#else /* BASOP_NOGLOB */ - wtmp = shl( 1, sub( add( Q_new, QSCALE ), 1 ) ); -#endif /* BASOP_NOGLOB */ test(); - IF( L_msu( Ltmp, 100, wtmp ) < 0 || L_msu( Ltmp2, 100, wtmp ) < 0 ) + IF( LT_32( L_shr( Ltmp, exp ), 100 ) || LT_32( L_shr( Ltmp2, exp2 ), 100 ) ) { noise_chartmp = 0; move16(); @@ -2457,17 +2476,8 @@ void noise_est_ivas_fx( ELSE { /* ftemp2 /= ftemp */ - ExpNum = sub( norm_l( Ltmp2 ), 1 ); - num = extract_h( L_shl( Ltmp2, ExpNum ) ); - - ExpDen = norm_l( Ltmp ); - den = extract_h( L_shl( Ltmp, ExpDen ) ); - num = div_s( num, den ); -#ifdef BASOP_NOGLOB - noise_chartmp = extract_h( L_shr_o( num, add( sub( ExpNum, ExpDen ), 4 - 16 ), &Overflow ) ); /* Q11 */ -#else /* BASOP_NOGLOB */ - noise_chartmp = extract_h( L_shr( num, add( sub( ExpNum, ExpDen ), 4 - 16 ) ) ); /* Q11 */ -#endif /* BASOP_NOGLOB */ + num = div_s( extract_h( Ltmp2 ), extract_h( Ltmp ) ); // 15+exp2-exp + noise_chartmp = shl_o( num, sub( sub( exp, exp2 ), 4 ), &Overflow ); // 15+exp2-exp1 -> Q11 } if ( ncharX != NULL ) @@ -2494,16 +2504,16 @@ void noise_est_ivas_fx( } } - noise_chartmp = s_min( noise_chartmp, (Word16) 10 << 11 ); /* Q11 */ + noise_chartmp = s_min( noise_chartmp, 10 << 11 ); /* Q11 */ /* update LT value of the final parameter */ /* *st_noise_char = M_ALPHA * *st_noise_char + (1-M_ALPHA) * noise_chartmp */ hNoiseEst->noise_char_fx = mac_r( L_mult( M_ALPHA_FX, hNoiseEst->noise_char_fx ), ONE_MINUS_M_ALPHA, noise_chartmp ); - + move16(); nchar_thr = THR_NCHAR_WB_FX; move16(); /* 1.0 Q11 */ - if ( EQ_16( vad_bwidth_fx, NB ) ) + if ( vad_bwidth_fx == NB ) { nchar_thr = THR_NCHAR_NB_FX; move16(); /* 1.0 Q11 */ @@ -2518,8 +2528,8 @@ void noise_est_ivas_fx( } /* save the 2 last spectra per crit. bands for the future */ - Copy32( hNoiseEst->fr_bands1_fx, hNoiseEst->fr_bands2_fx, NB_BANDS ); - Copy32( fr_bands + NB_BANDS, hNoiseEst->fr_bands1_fx, NB_BANDS ); + Copy32( hNoiseEst->fr_bands1_fx, hNoiseEst->fr_bands2_fx, NB_BANDS ); // q_fr_bands + Copy32( fr_bands + NB_BANDS, hNoiseEst->fr_bands1_fx, NB_BANDS ); // q_fr_bands /*-----------------------------------------------------------------* * Non-stationarity estimation for each band @@ -2532,13 +2542,8 @@ void noise_est_ivas_fx( tmp = s_max( relE, 0 ); /* Q8 */ /* alpha = 0.064f * ftemp + 0.75f; */ - Ltmp = Mult_32_16( (Word32) 137438953L, tmp ); /* Q31(.064)+Q8+1-16 --> Q24 */ - Ltmp = L_mac( Ltmp, 256, 24576 ); /* Q8+Q15(.75)+1 --> Q24 */ -#ifdef BASOP_NOGLOB + Ltmp = Madd_32_16( 12582912 /* 0.75 in Q24*/, 137438953, tmp ); // Q24 alpha = round_fx_o( L_shl_o( Ltmp, 7, &Overflow ), &Overflow ); /*Q24 +7 --> Q31 Q15*/ -#else /* BASOP_NOGLOB */ - alpha = round_fx( L_shl( Ltmp, 7 ) ); /*Q24 +7 --> Q31 Q15*/ -#endif /* BASOP_NOGLOB */ /*if( alpha > 0.999f { alpha = 0.999f;} */ alpha = s_min( alpha, 32735 ); /*.999 in Q15*/ @@ -2560,60 +2565,55 @@ void noise_est_ivas_fx( alpha2m1 = 32767; move16(); } - Lnon_sta2 = L_deposit_l( 1 << 10 ); + Lnon_sta2 = L_deposit_l( 1 << 10 ); // Q10 - non_sta = L_deposit_l( 1 << 10 ); + non_sta = L_deposit_l( 1 << 10 ); // Q10 *non_staX = 0; move16(); non_staB = 0; move16(); + Le_min_scaled = L_shl( E_MIN_FXQ31, sub( q_enr, Q31 ) ); // q_enr + FOR( i = st_fx->min_band; i <= st_fx->max_band; i++ ) { + Ltmp = L_shl( 1, q_enr ); // q_enr /* + 1.0f added to reduce sensitivity to non stationarity in low energies */ /* tmp_enr = enr[i] + 1.0f; */ - tmp_Q = add( Q_new, Q_SCALE ); - Ltmp = L_shl( (Word32) 1L, tmp_Q ); /* 1.0 added in the right dynamic domain */ -#ifdef BASOP_NOGLOB - L_tmp_enr = L_add_o( enr[i], Ltmp, &Overflow ); /* enr scale dynamic */ - L_tmp_ave_enr = L_add_o( hNoiseEst->ave_enr_fx[i], Ltmp, &Overflow ); /* ave__enr scale dynamic */ -#else /* BASOP_NOGLOB */ - L_tmp_enr = L_add( enr[i], Ltmp ); /* enr scale dynamic */ - L_tmp_ave_enr = L_add( hNoiseEst->ave_enr_fx[i], Ltmp ); /* ave__enr scale dynamic */ -#endif /* BASOP_NOGLOB */ - IF( LE_32( non_sta, th_sta ) ) /* Just to limit the saturation */ + L_tmp_enr = L_add( enr[i], Ltmp ); // q_enr + + IF( LE_32( non_sta, th_sta ) ) /* Just to limit the saturation */ { + L_tmp_ave = L_add( hNoiseEst->ave_enr_fx[i], Ltmp ); // q_enr + /* if( enr[i] > st_ave_enr2[i] ) */ /* non_sta2 = non_sta2 * ((enr[i]+1) / (st_ave_enr2[i]+1)) */ - Lnum = L_max( L_tmp_enr, L_tmp_ave_enr ); + Lnum = L_max( L_tmp_enr, L_tmp_ave ); // q_enr /* else */ /* non_sta2 = non_sta2 * ((st_ave_enr2[i]+1) / (enr[i]+1)) */ - Lden = L_min( L_tmp_enr, L_tmp_ave_enr ); + Lden = L_min( L_tmp_enr, L_tmp_ave ); // q_enr if ( Lden == 0 ) { - Lden = L_add( Lden, EPSILON_FX ); + Lden = L_max( Ltmp, EPSILON_FX ); // q_enr } ExpNum = sub( norm_l( Lnum ), 1 ); - num = extract_h( L_shl( Lnum, ExpNum ) ); - Lnum = L_shl( Lnum, ExpNum ); + num = extract_h( L_shl( Lnum, ExpNum ) ); // q_enr+ExpNum-16 + ExpDen = norm_l( Lden ); - den = extract_h( L_shl( Lden, ExpDen ) ); - num = div_s( num, den ); - Ltmp = Mult_32_16( non_sta, num ); -#ifdef BASOP_NOGLOB - non_sta = L_shr_o( Ltmp, sub( ExpNum, ExpDen ), &Overflow ); /* Q10 */ -#else /* BASOP_NOGLOB */ - non_sta = L_shr( Ltmp, sub( ExpNum, ExpDen ) ); /* Q10 */ -#endif /* BASOP_NOGLOB */ + den = extract_h( L_shl( Lden, ExpDen ) ); // q_enr+ExpDen-16 + + num = div_s( num, den ); // 15+ExpNum-ExpDen + Ltmp1 = Mult_32_16( non_sta, num ); // 15+ExpNum-ExpDen+10-15 + non_sta = L_shr_o( Ltmp1, sub( ExpNum, ExpDen ), &Overflow ); /* Q10 */ } /* st->ave_enr[i] = alpha * st->ave_enr[i] + (1-alpha) * enr[i];*/ /* update long-term average */ - Ltmp = Mult_32_16( hNoiseEst->ave_enr_fx[i], alpha ); - Ltmp = L_add_sat( Ltmp, Mult_32_16( enr[i], alpham1 ) ); - hNoiseEst->ave_enr_fx[i] = L_max( Le_min_scaled, Ltmp ); + Ltmp1 = Mult_32_16( hNoiseEst->ave_enr_fx[i], alpha ); // q_enr + Ltmp1 = Madd_32_16( Ltmp1, enr[i], alpham1 ); // q_enr + hNoiseEst->ave_enr_fx[i] = L_max( Le_min_scaled, Ltmp1 ); // q_enr move32(); /* calculation of another non-stationarity measure (following attacks) */ @@ -2627,41 +2627,32 @@ void noise_est_ivas_fx( } */ /* ave_enr2:: calculation of another non-stationarity measure (following attacks) */ - Ltmp = L_shl( (Word32) 1L, tmp_Q ); /* 1.0 added in the right dynamic domain */ - /*L_tmp_enr = L_add(enr[i] , Ltmp );*/ /* enr scale dynamic , done above */ -#ifdef BASOP_NOGLOB - L_tmp_ave_enr2 = L_add_o( hNoiseEst->ave_enr2_fx[i], Ltmp, &Overflow ); /* ave__enr scale dynamic */ -#else - L_tmp_ave_enr2 = L_add( hNoiseEst->ave_enr2_fx[i], Ltmp ); /* ave__enr scale dynamic */ -#endif IF( LE_32( Lnon_sta2, th_sta ) ) /* Just to limit the saturation */ { - Lnum = L_max( L_tmp_enr, L_tmp_ave_enr2 ); - Lden = L_min( L_tmp_enr, L_tmp_ave_enr2 ); + L_tmp_ave2 = L_add( hNoiseEst->ave_enr2_fx[i], Ltmp ); // q_enr + Lnum = L_max( L_tmp_enr, L_tmp_ave2 ); // q_enr + Lden = L_min( L_tmp_enr, L_tmp_ave2 ); // q_enr + if ( Lden == 0 ) { - Lden = L_add( Lden, EPSILON_FX ); + Lden = L_max( Ltmp, EPSILON_FX ); // q_enr } ExpNum = sub( norm_l( Lnum ), 1 ); - num = extract_h( L_shl( Lnum, ExpNum ) ); - Lnum = L_shl( Lnum, ExpNum ); + num = extract_h( L_shl( Lnum, ExpNum ) ); // q_enr+ExpNum-16 + ExpDen = norm_l( Lden ); - den = extract_h( L_shl( Lden, ExpDen ) ); - num = div_s( num, den ); - Ltmp1 = Mult_32_16( Lnon_sta2, num ); -#ifdef BASOP_NOGLOB + den = extract_h( L_shl( Lden, ExpDen ) ); // q_enr+ExpDen-16 + + num = div_s( num, den ); // 15+ExpNum-ExpDen + Ltmp1 = Mult_32_16( Lnon_sta2, num ); // 15+ExpNum-ExpDen+10-15 Lnon_sta2 = L_shr_o( Ltmp1, sub( ExpNum, ExpDen ), &Overflow ); /* Q10 */ -#else /* BASOP_NOGLOB */ - Lnon_sta2 = L_shr( Ltmp1, sub( ExpNum, ExpDen ) ); /* Q10 */ -#endif /* BASOP_NOGLOB */ } - /* st_ave_enr2[i] = (float)alpha2 * st_ave_enr2[i] - + (1.0f - alpha2) * (enr[i]) */ - Ltmp1 = Mult_32_16( hNoiseEst->ave_enr2_fx[i], alpha2 ); - Ltmp1 = L_add( Ltmp1, Mult_32_16( enr[i], alpha2m1 ) ); - hNoiseEst->ave_enr2_fx[i] = L_max( Le_min_scaled, Ltmp1 ); + /* st_ave_enr2[i] = (float)alpha2 * st_ave_enr2[i] + (1.0f - alpha2) * (enr[i]) */ + Ltmp1 = Mult_32_16( hNoiseEst->ave_enr2_fx[i], alpha2 ); // q_enr + Ltmp1 = Madd_32_16( Ltmp1, enr[i], alpha2m1 ); // q_enr + hNoiseEst->ave_enr2_fx[i] = L_max( Le_min_scaled, Ltmp1 ); // q_enr move32(); /* calculation of non-stationarity measure for speech/music classification */ @@ -2672,112 +2663,123 @@ void noise_est_ivas_fx( IF( GE_16( i, START_BAND_SPMUS ) && LT_16( i, NB_BANDS_SPMUS + START_BAND_SPMUS ) && st_fx->hSpMusClas != NULL ) { /* log_enr = (float)ln_fx(enr[i]); */ - log_enr16 = noise_est_ln_q8_fx( enr[i], 0, tmp_Q ); + Ltmp1 = L_max( enr[i], 1 ); + e_ener = norm_l( Ltmp1 ); + f_ener = Log2_norm_lc( L_shl( Ltmp1, e_ener ) ); + e_ener = sub( sub( 30, e_ener ), q_enr ); + Ltmp1 = L_mac( f_ener, e_ener, ONE_IN_Q14 ); // Q15 + Ltmp1 = Mpy_32_16_1( Ltmp1, 22713 ); // Q15 + log_enr16 = round_fx( L_shl( Ltmp1, 9 ) ); /* Q8 */ wtmp = abs_s( sub( log_enr16, hSpMusClas->past_log_enr_fx[i - START_BAND_SPMUS] ) ); -#ifdef BASOP_NOGLOB *non_staX = add_o( *non_staX, wtmp, &Overflow ); -#else /* BASOP_NOGLOB */ - *non_staX = add( *non_staX, wtmp ); -#endif /* BASOP_NOGLOB */ move16(); /* Q8 */ hSpMusClas->past_log_enr_fx[i - START_BAND_SPMUS] = log_enr16; move16(); } } + + test(); IF( GE_16( i, 2 ) && LE_16( i, 16 ) ) { - IF( GE_16( ini_frame, 100 ) ) + tmp_enr = LN_E_MIN_PLUS_ONE_FX; // Q8 + move16(); + IF( enr[i] != 0 ) { - /* calculate non-stationarity feature relative background */ - tmp_enr = noise_est_ln_q8_fx( enr[i], 1, tmp_Q ); /* 1.0f added */ - tmp_floor = LN_E_MIN_PLUS_ONE_FX; - move16(); /* non dynamic init constant in Q8 */ - tmp_floor = noise_est_ln_q8_fx( hNoiseEst->bckr_fx[i], 1, tmp_Q ); -#ifdef BASOP_NOGLOB - non_staB = add_o( non_staB, abs_s( sub( tmp_enr, tmp_floor ) ), &Overflow ); /* Q8 */ -#else /* BASOP_NOGLOB */ - non_staB = add( non_staB, abs_s( sub( tmp_enr, tmp_floor ) ) ); /* Q8 */ -#endif /* BASOP_NOGLOB */ + Ltmp1 = L_add( enr[i], Ltmp ); // q_enr + e_ener = norm_l( Ltmp1 ); + f_ener = Log2_norm_lc( L_shl( Ltmp1, e_ener ) ); + e_ener = sub( sub( 30, e_ener ), q_enr ); + Ltmp1 = L_mac( f_ener, e_ener, ONE_IN_Q14 ); // Q15 + Ltmp1 = Mpy_32_16_1( Ltmp1, 22713 ); // Q15 + tmp_enr = round_fx( L_shl( Ltmp1, 9 ) ); /* Q8 */ + } + + IF( LT_16( ini_frame, 100 ) ) + { + non_staB = add_o( non_staB, abs_s( sub( tmp_enr, LN_E_MIN_PLUS_ONE_FX ) ), &Overflow ); /* Q8 */ } ELSE /*ini_frame < 100*/ { - /* calculate non-stationarity feature relative background */ - tmp_enr = noise_est_ln_q8_fx( enr[i], 1, tmp_Q ); /* 1.0f added */ - tmp_floor = LN_E_MIN_PLUS_ONE_FX; - move16(); /* non dynamic init constant in Q8 */ - tmp_floor = noise_est_ln_q8_fx( E_MIN_FX, 1, tmp_Q ); -#ifdef BASOP_NOGLOB + tmp_floor = LN_E_MIN_PLUS_ONE_FX; // Q8 + move16(); + IF( hNoiseEst->bckr_fx[i] != 0 ) + { + Ltmp1 = L_add( hNoiseEst->bckr_fx[i], L_shl( 1, hNoiseEst->q_bckr ) ); // hNoiseEst->q_bckr + e_ener = norm_l( Ltmp1 ); + f_ener = Log2_norm_lc( L_shl( Ltmp1, e_ener ) ); + e_ener = sub( sub( 30, e_ener ), hNoiseEst->q_bckr ); + Ltmp1 = L_mac( f_ener, e_ener, ONE_IN_Q14 ); // Q15 + Ltmp1 = Mpy_32_16_1( Ltmp1, 22713 ); // Q15 + tmp_floor = round_fx( L_shl( Ltmp1, 9 ) ); /* Q8 */ + } non_staB = add_o( non_staB, abs_s( sub( tmp_enr, tmp_floor ) ), &Overflow ); /* Q8 */ -#else /* BASOP_NOGLOB */ - non_staB = add( non_staB, abs_s( sub( tmp_enr, tmp_floor ) ) ); /* Q8 */ -#endif /* BASOP_NOGLOB */ } } } /* end of band loop FOR( i = st_fx->min_band; i <= st_fx->max_band; i++ ) */ - IF( LT_16( Etot, -1280 ) ) + IF( LT_16( Etot, -1280 /* -5.0f in Q8 */ ) ) { non_sta = L_deposit_l( 1024 ); /* 1.0 in Q10 */ Lnon_sta2 = L_deposit_l( 1024 ); /* 1.0 in Q10 */ } - lim_Etot_fx = s_max( 5120, Etot ); /* 20.0f Q8 */ - lim_Etot_sq_fx = extract_h( L_shl_r( L_mult( lim_Etot_fx, lim_Etot_fx ), 1 ) ); /* Q2 */ + lim_Etot_fx = s_max( 5120, Etot ); /* 20.0f Q8 */ + lim_Etot_sq_fx = L_mult0( lim_Etot_fx, lim_Etot_fx ); /* Q16 */ - IF( LT_16( st_fx->ini_frame, 150 ) ) + IF( LT_16( ini_frame, 150 ) ) { /* Allow use of quicker filter during init - if needed */ /* st->Etot_st_est = 0.25f * lim_Etot + (1.0f-0.25F) * st->Etot_st_est; */ - hNoiseEst->Etot_st_est_fx = mac_r( L_mult( 8192, lim_Etot_fx ), 24576, hNoiseEst->Etot_st_est_fx ); - move16(); + hNoiseEst->L_Etot_st_est_fx = Madd_32_16_r( L_mult0( 8192, lim_Etot_fx ), hNoiseEst->L_Etot_st_est_fx, 24576 ); // Q23 + move32(); /* st->Etot_sq_st_est = 0.25f * lim_Etot * lim_Etot + (1.0f-0.25f) * st->Etot_sq_st_est; */ - hNoiseEst->Etot_sq_st_est_fx = mac_r( L_mult( 8192, lim_Etot_sq_fx ), 24576, hNoiseEst->Etot_sq_st_est_fx ); - move16(); + hNoiseEst->L_Etot_sq_st_est_fx = Madd_32_16_r( Mult_32_16( lim_Etot_sq_fx, 8192 ), hNoiseEst->L_Etot_sq_st_est_fx, 24576 ); // Q16 + move32(); } ELSE { /* st->Etot_st_est = 0.25f * lim_Etot + (1.0f-0.25F) * st->Etot_st_est; */ - hNoiseEst->Etot_st_est_fx = mac_r( L_mult( 8192, lim_Etot_fx ), 24576, hNoiseEst->Etot_st_est_fx ); - move16(); + hNoiseEst->L_Etot_st_est_fx = Madd_32_16_r( L_mult0( 8192, lim_Etot_fx ), hNoiseEst->L_Etot_st_est_fx, 24576 ); // Q23 + move32(); /* st->Etot_sq_st_est = 0.25f * lim_Etot * lim_Etot + (1.0f-0.25f) * st->Etot_sq_st_est; */ - hNoiseEst->Etot_sq_st_est_fx = mac_r( L_mult( 8192, lim_Etot_sq_fx ), 24576, hNoiseEst->Etot_sq_st_est_fx ); - move16(); + hNoiseEst->L_Etot_sq_st_est_fx = Madd_32_16_r( Mult_32_16( lim_Etot_sq_fx, 8192 ), hNoiseEst->L_Etot_sq_st_est_fx, 24576 ); // Q16 + move32(); } - st_E_var_est_fx = sub( hNoiseEst->Etot_sq_st_est_fx, extract_h( L_shl_r( L_mult( hNoiseEst->Etot_st_est_fx, hNoiseEst->Etot_st_est_fx ), 1 ) ) ); - - + Word16 exp_tmp; + st_E_var_est_fx = BASOP_Util_Add_Mant32Exp( hNoiseEst->L_Etot_sq_st_est_fx, Q15, L_negate( Mpy_32_32( hNoiseEst->L_Etot_st_est_fx, hNoiseEst->L_Etot_st_est_fx ) ), Q16, &exp_tmp ); // exp(exp_tmp) /*-----------------------------------------------------------------* * Count frames since last correlation or harmonic event *-----------------------------------------------------------------*/ - Ltmp = L_mult( st_fx->voicing_fx[0], 16384 ); - Ltmp = L_mac( Ltmp, st_fx->voicing_fx[1], 16384 ); + Ltmp = L_mult( st_fx->voicing_fx[0], 16384 /* 0.5 in Q15 */ ); // Q31 + Ltmp = L_mac( Ltmp, st_fx->voicing_fx[1], 16384 /* 0.5 in Q15 */ ); // Q31 + *st_harm_cor_cnt = add( *st_harm_cor_cnt, 1 ); + move16(); test(); test(); - *st_harm_cor_cnt = add( *st_harm_cor_cnt, 1 ); - if ( ( Etot > 0 ) && ( ( *loc_harm > 0 ) || ( GT_16( round_fx( Ltmp ), COR_MAX_NNE_FX ) ) ) ) + if ( ( Etot > 0 ) && ( ( *loc_harm > 0 ) || ( GT_32( Ltmp, 1825361101 /* 0.85 in Q31 */ ) ) ) ) { *st_harm_cor_cnt = 0; move16(); } - IF( ( GT_16( *st_harm_cor_cnt, 1 ) ) && ( ( LT_16( Etot, 3840 ) ) || /* 15 in Q8 */ - ( GT_16( st_fx->ini_frame, 10 ) && - GT_16( sub( Etot, hNoiseEst->Etot_lp_fx ), 1792 ) ) ) /* 7 in Q8 */ - ) + test(); + test(); + test(); + if ( ( GT_16( *st_harm_cor_cnt, 1 ) ) && ( ( LT_16( Etot, 3840 /* 15 in Q8 */ ) ) || + ( GT_16( ini_frame, 10 ) && + GT_16( sub( Etot, hNoiseEst->Etot_lp_fx ), 1792 /* 7 in Q8 */ ) ) ) ) { *st_harm_cor_cnt = 1; + move16(); } - - if ( GT_16( *st_harm_cor_cnt, 1 ) && - GT_16( Etot, 7680 ) && /* 30.0f in Q8 */ - GT_16( st_E_var_est_fx, 32 ) /* 8.0f in Q2 */ - ) + test(); + test(); + IF( GT_16( *st_harm_cor_cnt, 1 ) && GT_16( Etot, 7680 /* 30.0f in Q8 */ ) && EQ_16( BASOP_Util_Cmp_Mant32Exp( st_E_var_est_fx, exp_tmp, 524288 /* 8.0f in Q16 */, Q15 ), 1 ) ) { - /* st->harm_cor_cnt = max(1, (short) round_f( (float) st->harm_cor_cnt / 4.0f )) ; */ *st_harm_cor_cnt = s_max( 1, shr( add( *st_harm_cor_cnt, 2 ), 2 ) ); move16(); @@ -2815,23 +2817,20 @@ void noise_est_ivas_fx( *-----------------------------------------------------------------*/ /*epsP_0_2 = max(0 , min(8, epsP[0] / epsP[2])); */ - Ltmp = eps_quota_fx( epsP_h[0], epsP_l[0], - epsP_h[2], epsP_l[2], 12 ); /* Word32 Q12 */ - BASOP_SATURATE_WARNING_OFF_EVS /* may saturate*/ -#ifdef BASOP_NOGLOB - epsP_0_2 = round_fx_o( L_shl_o( Ltmp, 16, &Overflow ), &Overflow ); /* Q12+16 -16 -> Q12 , NB saturation in Q12 sets max value to 7,999 */ -#else /* BASOP_NOGLOB */ - epsP_0_2 = round_fx( L_shl( Ltmp, 16 ) ); /* Q12+16 -16 -> Q12 , NB saturation in Q12 sets max value to 7,999 */ -#endif /* BASOP_NOGLOB */ - BASOP_SATURATE_WARNING_ON_EVS + exp = sub( norm_l( epsP[0] ), 1 ); + num = extract_h( L_shl( epsP[0], exp ) ); // Qx+exp-16 - epsP_0_2 = s_max( 0, epsP_0_2 ); /* min value is 0 , Q12 */ + exp2 = norm_l( epsP[2] ); + den = extract_h( L_shl( epsP[2], exp2 ) ); // Qx+exp2-16 + /* max(0, min(8, epsP[0] / epsP[2])) */ + epsP_0_2 = div_s( num, den ); // Q15+exp-exp2 + epsP_0_2 = shr_sat( epsP_0_2, add( sub( exp, exp2 ), 3 ) ); // Q12 + epsP_0_2 = s_max( 0, epsP_0_2 ); /* min value is 0 , Q12 */ /* st->epsP_0_2_lp = 0.15f * epsP_0_2 + (1.0f-0.15f) * st->epsP_0_2_lp; */ - alpha = 4915; - move16(); /*0.15 in Q15 */ - hNoiseEst->epsP_0_2_lp_fx = noise_est_AR1_Qx( epsP_0_2, hNoiseEst->epsP_0_2_lp_fx, alpha ); + hNoiseEst->epsP_0_2_lp_fx = mac_r( L_mult( epsP_0_2, 4915 /* 0.15 in Q15*/ ), hNoiseEst->epsP_0_2_lp_fx, 27853 /* 0.85 in Q15*/ ); // Q12 + move16(); /* epsP_0_2_ad = (float) fabs(epsP_0_2 - st->epsP_0_2_lp ); */ epsP_0_2_ad = abs_s( sub( epsP_0_2, hNoiseEst->epsP_0_2_lp_fx ) ); /* Q12 */ @@ -2841,13 +2840,17 @@ void noise_est_ivas_fx( } else { st->epsP_0_2_ad_lp = 0.2f * epsP_0_2_ad + (1.0f - 0.2f) * st->epsP_0_2_ad_lp; } */ - alpha = 6554; - move16(); /* 0.2 Q15 */ - if ( LT_16( epsP_0_2_ad, hNoiseEst->epsP_0_2_ad_lp_fx ) ) + + IF( LT_16( epsP_0_2_ad, hNoiseEst->epsP_0_2_ad_lp_fx ) ) { - alpha = shr( alpha, 1 ); /* 0.1 Q15 */ + hNoiseEst->epsP_0_2_ad_lp_fx = mac_r( L_mult( epsP_0_2_ad, 3277 /* 0.1 in Q15*/ ), hNoiseEst->epsP_0_2_ad_lp_fx, 29491 /* 0.9 in Q15*/ ); // Q12 + move16(); + } + ELSE + { + hNoiseEst->epsP_0_2_ad_lp_fx = mac_r( L_mult( epsP_0_2_ad, 6554 /* 0.2 in Q15*/ ), hNoiseEst->epsP_0_2_ad_lp_fx, 26214 /* 0.8 in Q15*/ ); // Q12 + move16(); } - hNoiseEst->epsP_0_2_ad_lp_fx = noise_est_AR1_Qx( epsP_0_2_ad, hNoiseEst->epsP_0_2_ad_lp_fx, alpha ); /* epsP_0_2_ad_lp_max = max(epsP_0_2_ad,st->epsP_0_2_ad_lp);*/ epsP_0_2_ad_lp_max = s_max( epsP_0_2_ad, hNoiseEst->epsP_0_2_ad_lp_fx ); /* Q12 */ @@ -2857,57 +2860,55 @@ void noise_est_ivas_fx( * Linear predition efficiency 2 to 16 order *-----------------------------------------------------------------*/ - /* epsP_2_16 = max(0 , min(8, epsP[2] / epsP[16])); */ - Ltmp = eps_quota_fx( epsP_h[2], epsP_l[2], - epsP_h[16], epsP_l[16], 12 ); /* Word32 Q12 */ - BASOP_SATURATE_WARNING_OFF_EVS /* may saturate*/ -#ifdef BASOP_NOGLOB - epsP_2_16 = round_fx_o( L_shl_o( Ltmp, 16, &Overflow ), &Overflow ); /* Q12+16 -16 -> Q12 , - NB saturation in Q12 sets max value to 7,999 */ -#else /* BASOP_NOGLOB */ - epsP_2_16 = round_fx( L_shl( Ltmp, 16 ) ); /* Q12+16 -16 -> Q12 , - NB saturation in Q12 sets max value to 7,999 */ -#endif /* BASOP_NOGLOB */ - BASOP_SATURATE_WARNING_ON_EVS + /*epsP_2_16 = max(0 , min(8, epsP[2] / epsP[16])); */ + exp = sub( norm_l( epsP[2] ), 1 ); + num = extract_h( L_shl( epsP[2], exp ) ); // Qx+exp-16 - epsP_2_16 = s_max( 0, epsP_2_16 ); /* min value is 0 , Q12 */ + exp2 = norm_l( epsP[16] ); + den = extract_h( L_shl( epsP[16], exp2 ) ); // Qx+exp2-16 + epsP_2_16 = div_s( num, den ); // Q15+exp-exp2 + epsP_2_16 = shr_sat( epsP_2_16, add( sub( exp, exp2 ), 3 ) ); // Q12 + epsP_2_16 = s_max( 0, epsP_2_16 ); /* min value is 0 , Q12 */ /* if (epsP_2_16 > st->epsP_2_16_lp){ st->epsP_2_16_lp = 0.2f * epsP_2_16 + (1.0f-0.2f) * st->epsP_2_16_lp; } else { st->epsP_2_16_lp = 0.03f * epsP_2_16 + (1.0f-0.03f) * st->epsP_2_16_lp; - } + } */ - st->epsP_2_16_lp2 = 0.02f * epsP_2_16 + (1.0f-0.02f) * st->epsP_2_16_lp2; */ - - alpha = 983; - move16(); /* 0.03 Q15 */ - if ( GT_16( epsP_2_16, hNoiseEst->epsP_2_16_lp_fx ) ) + IF( GT_16( epsP_2_16, hNoiseEst->epsP_2_16_lp_fx ) ) { - alpha = 6554; - move16(); /* 0.2 Q15 */ + hNoiseEst->epsP_2_16_lp_fx = mac_r( L_mult( epsP_2_16, 6554 /* 0.2 in Q15*/ ), hNoiseEst->epsP_2_16_lp_fx, 26214 /* 0.8 in Q15*/ ); // Q12 + move16(); + } + ELSE + { + hNoiseEst->epsP_2_16_lp_fx = mac_r( L_mult( epsP_2_16, 983 /* 0.03 in Q15*/ ), hNoiseEst->epsP_2_16_lp_fx, 31785 /* 0.97 in Q15*/ ); // Q12 + move16(); } - hNoiseEst->epsP_2_16_lp_fx = noise_est_AR1_Qx( epsP_2_16, hNoiseEst->epsP_2_16_lp_fx, alpha ); - hNoiseEst->epsP_2_16_lp2_fx = noise_est_AR1_Qx( epsP_2_16, hNoiseEst->epsP_2_16_lp2_fx, 655 ); /* 0.02 */ + hNoiseEst->epsP_2_16_lp2_fx = mac_r( L_mult( epsP_2_16, 655 /* 0.02 in Q15*/ ), hNoiseEst->epsP_2_16_lp2_fx, 32113 /* 0.98 in Q15*/ ); // Q12 + move16(); epsP_2_16_dlp = sub( hNoiseEst->epsP_2_16_lp_fx, hNoiseEst->epsP_2_16_lp2_fx ); - /* if (epsP_2_16_dlp < st->epsP_2_16_dlp_lp2 ) { st->epsP_2_16_dlp_lp2 = 0.02f * epsP_2_16_dlp + (1.0f-0.02f) * st->epsP_2_16_dlp_lp2; } else { st->epsP_2_16_dlp_lp2 = 0.05f * epsP_2_16_dlp + (1.0f-0.05f) * st->epsP_2_16_dlp_lp2; }*/ - alpha = 1638; - move16(); /* 0.05 Q15 */ - if ( LT_16( epsP_2_16_dlp, hNoiseEst->epsP_2_16_dlp_lp2_fx ) ) + + IF( LT_16( epsP_2_16_dlp, hNoiseEst->epsP_2_16_dlp_lp2_fx ) ) { - alpha = 655; - move16(); /* 0.02 Q15 */ + hNoiseEst->epsP_2_16_dlp_lp2_fx = mac_r( L_mult( epsP_2_16_dlp, 655 /* 0.02 in Q15*/ ), hNoiseEst->epsP_2_16_dlp_lp2_fx, 32113 /* 0.98 in Q15*/ ); // Q12 + move16(); + } + ELSE + { + hNoiseEst->epsP_2_16_dlp_lp2_fx = mac_r( L_mult( epsP_2_16_dlp, 1638 /* 0.05 in Q15*/ ), hNoiseEst->epsP_2_16_dlp_lp2_fx, 31130 /* 0.95 in Q15*/ ); // Q12 + move16(); } - hNoiseEst->epsP_2_16_dlp_lp2_fx = noise_est_AR1_Qx( epsP_2_16_dlp, hNoiseEst->epsP_2_16_dlp_lp2_fx, alpha ); /* epsP_2_16_dlp_max = max(epsP_2_16_dlp,st->epsP_2_16_dlp_lp2); */ epsP_2_16_dlp_max = s_max( epsP_2_16_dlp, hNoiseEst->epsP_2_16_dlp_lp2_fx ); @@ -2925,14 +2926,17 @@ void noise_est_ivas_fx( tmp2 = 32767; move16(); } - hNoiseEst->lt_tn_track_fx = noise_est_AR1_Qx( tmp2, hNoiseEst->lt_tn_track_fx, 983 ); /*0.03 in Q15 ,Q15 state*/ + hNoiseEst->lt_tn_track_fx = mac_r( L_mult( tmp2, 983 /* 0.03 in Q15*/ ), hNoiseEst->lt_tn_track_fx, 31785 /* 0.97 in Q15*/ ); // Q12 + move16(); /* st->lt_tn_dist = 0.03f* (Etot - st->totalNoise) + 0.97f*st->lt_tn_dist; */ - hNoiseEst->lt_tn_dist_fx = noise_est_AR1_Qx( tmp, hNoiseEst->lt_tn_dist_fx, 983 ); /*0.03 in Q15 ,Q8 state*/ + hNoiseEst->lt_tn_dist_fx = mac_r( L_mult( tmp, 983 /* 0.03 in Q15*/ ), hNoiseEst->lt_tn_dist_fx, 31785 /* 0.97 in Q15*/ ); // Q8 + move16(); /* st->lt_Ellp_dist = 0.03f* (Etot - st->Etot_l_lp) + 0.97f*st->lt_Ellp_dist;*/ - tmp = sub( Etot, hNoiseEst->Etot_l_lp_fx ); /* Q8 */ - hNoiseEst->lt_Ellp_dist_fx = noise_est_AR1_Qx( tmp, hNoiseEst->lt_Ellp_dist_fx, 983 ); /*0.03 in Q15 ,Q8 state*/ + tmp = sub( Etot, hNoiseEst->Etot_l_lp_fx ); /* Q8 */ + hNoiseEst->lt_Ellp_dist_fx = mac_r( L_mult( tmp, 983 /* 0.03 in Q15*/ ), hNoiseEst->lt_Ellp_dist_fx, 31785 /* 0.97 in Q15*/ ); // Q8 + move16(); /* if (st->harm_cor_cnt == 0) { @@ -2942,29 +2946,30 @@ void noise_est_ivas_fx( } */ IF( *st_harm_cor_cnt == 0 ) { - hNoiseEst->lt_haco_ev_fx = noise_est_AR1_Qx( (Word16) 32767, hNoiseEst->lt_haco_ev_fx, 983 ); /*.03 in Q15 , Q15 state */ + hNoiseEst->lt_haco_ev_fx = mac_r( 64424509 /* 0.03 in Q32*/, hNoiseEst->lt_haco_ev_fx, 31785 /* 0.97 in Q15*/ ); // Q15 + move16(); } ELSE { hNoiseEst->lt_haco_ev_fx = mult_r( 32440, hNoiseEst->lt_haco_ev_fx ); /*.99 in Q15 , Q15 state */ + move16(); } - /* if (st->lt_tn_track < 0.05f) { st->low_tn_track_cnt++; } else { st->low_tn_track_cnt=0; }*/ - tmp = 0; - move16(); - move16(); - if ( LT_16( hNoiseEst->lt_tn_track_fx, 1638 ) ) /* 0.05 in Q15*/ + IF( LT_16( hNoiseEst->lt_tn_track_fx, 1638 ) ) /* 0.05 in Q15*/ { - tmp = add( hNoiseEst->low_tn_track_cnt, 1 ); + hNoiseEst->low_tn_track_cnt = add( hNoiseEst->low_tn_track_cnt, 1 ); + move16(); + } + ELSE + { + hNoiseEst->low_tn_track_cnt = 0; + move16(); } - hNoiseEst->low_tn_track_cnt = tmp; - move16(); - /* update of the long-term non-stationarity measure (between 0 and 1) */ /* if ( (non_sta > th_sta) || (*loc_harm > 0) ) { @@ -2972,35 +2977,21 @@ void noise_est_ivas_fx( } else { st->act_pred = M_GAMMA * st->act_pred + (1-M_GAMMA) * 0; }*/ - Ltmp = L_mult( M_GAMMA_FX, hNoiseEst->act_pred_fx ); /*Q15*Q15+1 --> Q31 , 32440= .99 Q15 */ - tmp = round_fx( Ltmp ); /* Q15 */ test(); - if ( ( GT_32( non_sta, th_sta ) ) /* float th_sta NB 5e10 , WB 3.5e10*/ - || ( *loc_harm > 0 ) ) + IF( ( GT_32( non_sta, th_sta ) ) || ( *loc_harm > 0 ) ) { - tmp = mac_r( Ltmp, ( -32768 + M_GAMMA_FX ), -32768 ); /* (-0.01)*(-1.0) */ + hNoiseEst->act_pred_fx = mac_r( 21474836 /* 1 - M_GAMMA in Q31 */, M_GAMMA_FX, hNoiseEst->act_pred_fx ); // Q31 + move16(); + } + ELSE + { + hNoiseEst->act_pred_fx = mult_r( M_GAMMA_FX, hNoiseEst->act_pred_fx ); /*Q15*Q15+1 --> Q31 , 32440= .99 Q15 */ + move16(); } - hNoiseEst->act_pred_fx = tmp; - move16(); - /*-----------------------------------------------------------------* * Background noise adaptation enable flag *-----------------------------------------------------------------*/ - Ltmp = L_mult( st_fx->voicing_fx[0], 16384 ); - Ltmp = L_mac( Ltmp, st_fx->voicing_fx[1], 16384 ); -#ifdef BASOP_NOGLOB - cor_tmp = mac_ro( Ltmp, corr_shift, MAX_16, &Overflow ); -#else /* BASOP_NOGLOB */ - cor_tmp = mac_r( Ltmp, corr_shift, MAX_16 ); -#endif - - LepsP = eps_quota_fx( epsP_h[2], epsP_l[2], - epsP_h[16], epsP_l[16], 11 ); /* L_epsP in Q11 */ - /* note this epsP2/eps16 is not limited to 8 as, epsP_2_16 is !! */ - - vad_2nd_stage_fx = 0; - move16(); /* background noise present - decrement counter */ /* if( ( (*st_harm_cor_cnt < 3*HC_CNT_SLOW ) && ( ( non_sta > th_sta ) || @@ -3022,6 +3013,16 @@ void noise_est_ivas_fx( cor_tmp = 0; move16(); } + /* epsP[2] / epsP[16] */ + exp = sub( norm_l( epsP[2] ), 1 ); + num = extract_h( L_shl( epsP[2], exp ) ); // Qx+exp-16 + + exp2 = norm_l( epsP[16] ); + den = extract_h( L_shl( epsP[16], exp2 ) ); // Qx+exp2-16 + + LepsP = extract_l( div_s( num, den ) ); // Q15+exp-exp2 + LepsP = L_shr( LepsP, add( sub( exp, exp2 ), 4 ) ); // Q11 + test(); test(); @@ -3033,31 +3034,35 @@ void noise_est_ivas_fx( test(); test(); test(); - - if ( ( ( LT_16( *st_harm_cor_cnt, ( 3 * HC_CNT_SLOW_FX ) ) ) && ( ( GT_32( non_sta, th_sta ) ) || ( LT_16( tmp_pc, TH_PC_FX ) ) || ( GT_16( noise_char, 0 ) ) ) ) || - ( ( GT_16( st_fx->ini_frame, HE_LT_CNT_INIT_FX ) ) && ( GT_16( sub( Etot, Etot_l_lp ), 2560 ) ) ) || - ( GT_16( cor_tmp, cor_max ) ) || /* Q15 */ - ( GT_32( LepsP, th_eps ) ) || /* Q11 */ - ( GT_16( *loc_harm, 0 ) ) || - ( ( GT_16( hNoiseEst->act_pred_fx, 26214 ) ) && ( GT_32( Lnon_sta2, th_sta ) ) ) /*act_pred in Q15 , th_sta in Q10 */ + IF( ( ( LT_16( *st_harm_cor_cnt, ( 3 * HC_CNT_SLOW_FX ) ) ) && ( ( GT_32( non_sta, th_sta ) ) || ( LT_16( tmp_pc, TH_PC_FX ) ) || ( noise_char > 0 ) ) ) || + ( ( GT_16( ini_frame, HE_LT_CNT_INIT_FX ) ) && ( GT_16( sub( Etot, Etot_l_lp ), 2560 ) ) ) || + ( GT_16( cor_tmp, cor_max ) ) || /* Q15 */ + ( GT_32( LepsP, th_eps ) ) || /* Q11 */ + ( GT_16( *loc_harm, 0 ) ) || + ( ( GT_16( hNoiseEst->act_pred_fx, 26214 ) ) && ( GT_32( Lnon_sta2, th_sta ) ) ) /*act_pred in Q15 , th_sta in Q10 */ ) { - vad_2nd_stage_fx = 1; - move16(); /* active signal present - increment counter */ + /* hNoiseEst->aEn = hNoiseEst->aEn + 2; */ + hNoiseEst->aEn = add( hNoiseEst->aEn, 2 ); /* active signal present - increment counter */ + move16(); } - - tmp = 2; - move16(); /* Signal present */ - if ( vad_2nd_stage_fx == 0 ) + ELSE { - tmp = -1; - move16(); /* Background present */ + /* hNoiseEst->aEn = hNoiseEst->aEn - 1; */ + hNoiseEst->aEn = add( hNoiseEst->aEn, -1 ); /* background noise present - decrement counter */ + move16(); } - hNoiseEst->aEn = add( hNoiseEst->aEn, tmp ); + hNoiseEst->aEn = s_max( s_min( hNoiseEst->aEn, 6 ), 0 ); + move16(); - hNoiseEst->aEn = s_min( hNoiseEst->aEn, 6 ); - hNoiseEst->aEn = s_max( hNoiseEst->aEn, 0 ); + IF( LE_16( hNoiseEst->aEn, 1 ) ) + { + hNoiseEst->aEn_inac_cnt = add( hNoiseEst->aEn_inac_cnt, 1 ); + hNoiseEst->aEn_inac_cnt = s_min( hNoiseEst->aEn_inac_cnt, 128 ); + move16(); + move16(); + } /*-----------------------------------------------------------------* * Stereo classifier - save raw aEn *-----------------------------------------------------------------*/ @@ -3069,33 +3074,25 @@ void noise_est_ivas_fx( ( 0.5f * ( st->voicing[0] + st->voicing[1] ) > cor_max ) || ( epsP[2] / epsP[16] > th_eps ) || ( ( hNoiseEst->act_pred > 0.8f ) && ( non_sta2 > th_sta ) ) )*/ + wtmp = sub( hStereoClassif->aEn_raw[st_fx->idchan], 1 ); test(); test(); test(); test(); test(); - IF( ( GT_32( non_sta, th_sta ) ) || ( LT_16( tmp_pc, TH_PC_FX ) ) || - ( GT_16( cor_tmp, cor_max ) ) || - ( GT_32( LepsP, th_eps ) ) || - ( ( GT_16( hNoiseEst->act_pred_fx, 26214 ) ) && ( GT_32( Lnon_sta2, th_sta ) ) ) ) /*act_pred in Q15 , th_sta in Q10 */ + if ( ( GT_32( non_sta, th_sta ) ) || ( LT_16( tmp_pc, TH_PC_FX ) ) || + ( GT_16( cor_tmp, cor_max ) ) || + ( GT_32( LepsP, th_eps ) ) || + ( ( GT_16( hNoiseEst->act_pred_fx, 26214 ) ) && ( GT_32( Lnon_sta2, th_sta ) ) ) ) /*act_pred in Q15 , th_sta in Q10 */ { /* active signal present - increment counter */ - hStereoClassif->aEn_raw[st_fx->idchan] = hStereoClassif->aEn_raw[st_fx->idchan] + 2; - } - ELSE - { - /* background noise present - decrement counter */ - hStereoClassif->aEn_raw[st_fx->idchan] = hStereoClassif->aEn_raw[st_fx->idchan] - 1; + wtmp = add( hStereoClassif->aEn_raw[st_fx->idchan], 2 ); } + hStereoClassif->aEn_raw[st_fx->idchan] = wtmp; move16(); - if ( GT_16( hStereoClassif->aEn_raw[st_fx->idchan], 6 ) ) - { - hStereoClassif->aEn_raw[st_fx->idchan] = 6; - } - else if ( hStereoClassif->aEn_raw[st_fx->idchan] < 0 ) - { - hStereoClassif->aEn_raw[st_fx->idchan] = 0; - } + + wtmp = s_min( hStereoClassif->aEn_raw[st_fx->idchan], 6 ); + hStereoClassif->aEn_raw[st_fx->idchan] = s_max( wtmp, 0 ); move16(); } @@ -3104,7 +3101,7 @@ void noise_est_ivas_fx( /* comb_ahc_epsP = max(max(st->act_pred, st->lt_haco_ev), epsP_2_16_dlp); */ /* Q15 Q15 Q12 */ - comb_ahc_epsP = s_max( s_max( shr( hNoiseEst->act_pred_fx, 15 - 12 ), shr( hNoiseEst->lt_haco_ev_fx, 15 - 12 ) ), epsP_2_16_dlp ); /* Q12 */ + comb_ahc_epsP = s_max( shr( s_max( hNoiseEst->act_pred_fx, hNoiseEst->lt_haco_ev_fx ), 15 - 12 ), epsP_2_16_dlp ); /* Q12 */ /* comb_hcm_epsP = max(max(st->lt_haco_ev,epsP_2_16_dlp_max),epsP_0_2_ad_lp_max); */ @@ -3116,7 +3113,7 @@ void noise_est_ivas_fx( move16(); if ( *st_harm_cor_cnt == 0 ) { - tmp = (Word16) 32767; + tmp = 32767; move16(); } haco_ev_max = s_max( tmp, hNoiseEst->lt_haco_ev_fx ); /* Q15 */ @@ -3164,7 +3161,7 @@ void noise_est_ivas_fx( /* ns_mask = non_sta < 1e5f; */ ns_mask = 0; move16(); - if ( LT_32( non_sta, (Word32) 102400000L ) ) /* (1e5f in Q10)*/ + if ( LT_32( non_sta, 102400000 ) ) /* (1e5f in Q10)*/ { ns_mask = 1; move16(); /* Q0 */ @@ -3200,14 +3197,18 @@ void noise_est_ivas_fx( SD_1 = 1; move16(); /* Q0 */ } - SD_1_inv = sub( 1, SD_1 ); /* Q0 */ /* NB "STL::test()"; has a cost of 2, using bitwise "s_and" , "s_or" at a cost of 1 */ /* NB only lowest bit position is used, result is always 0 or 1 */ /* bg_bgd3 = enr_bgd || ( ( cns_bgd || lp_bgd ) && ns_mask && lt_haco_mask && SD_1==0 ); */ - tmp = s_and( s_and( s_and( s_or( cns_bgd, lp_bgd ), ns_mask ), lt_haco_mask ), SD_1_inv ); - bg_bgd3 = s_or( enr_bgd, tmp ); + test(); + test(); + test(); + test(); + test(); + bg_bgd3 = enr_bgd || ( ( cns_bgd || lp_bgd ) && ns_mask && lt_haco_mask && ( SD_1 == 0 ) ); + move16(); /*PD_1 = (epsP_2_16_dlp_max < 0.10f ) ; */ PD_1 = 0; @@ -3273,21 +3274,19 @@ void noise_est_ivas_fx( || ( (Etot < 55.0f) && (SD_1==0) && ( ( PD_3 && (PD_1 || PD_2 ) ) || ( PD_4 || PD_5 ) ) ); */ PAU = 0; - move16(); /*Q0*/ - if ( hNoiseEst->aEn == 0 ) + move16(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + if ( ( hNoiseEst->aEn == 0 ) || ( LT_16( Etot, 55 * 256 ) && ( SD_1 == 0 ) && ( ( PD_3 && ( PD_1 || PD_2 ) ) || ( PD_4 || PD_5 ) ) ) ) { PAU = 1; - move16(); /*Q0*/ - } - tmp = 0; - move16(); /*Q0*/ - if ( LT_16( Etot, 55 * 256 ) ) /*55.0 in Q8 */ - { - tmp = 1; - move16(); /*Q0*/ + move16(); } - tmp = s_and( tmp, SD_1_inv ); - PAU = s_or( PAU, s_and( tmp, s_or( s_and( PD_3, s_or( PD_1, PD_2 ) ), s_or( PD_4, PD_5 ) ) ) ); /* NEW_POS_BG = (PAU | BG_1) & bg_bgd3; note bitwise logic in float */ @@ -3303,7 +3302,6 @@ void noise_est_ivas_fx( move16(); } - /* When the signal dynamics is high and the energy is close to the background estimate */ /* sd1_bgd = (st->sign_dyn_lp > 15) && (Etot - st->Etot_l_lp ) < 2*st->Etot_v_h2 @@ -3326,34 +3324,27 @@ void noise_est_ivas_fx( st->lt_haco_ev < 0.15f || non_staB < 50.0f || aE_bgd );*/ - - tmp = 0; + tn_ini = 0; move16(); test(); test(); test(); test(); test(); - if ( ( ( LT_16( hNoiseEst->act_pred_fx, 19333 ) ) && ( LT_16( hNoiseEst->lt_haco_ev_fx, 7537 ) ) ) /* .59 in Q15 .23 in Q15 */ - || ( LT_16( hNoiseEst->act_pred_fx, 12452 ) ) /* .38 in Q15 */ - || ( ( EQ_16( st_fx->element_mode, EVS_MONO ) && LT_16( hNoiseEst->lt_haco_ev_fx, 4915 ) ) || ( GT_16( st_fx->element_mode, EVS_MONO ) && LT_16( hNoiseEst->lt_haco_ev_fx, 2621 ) ) ) /* .15 in Q15 || 0.08 */ - || ( LT_16( non_staB, 50 * 256 ) ) /* 50.0 in Q8 */ - || aE_bgd != 0 || ( ( LT_16( Etot, 10752 ) ) /* 42 in Q8 */ - && ( GT_16( hNoiseEst->harm_cor_cnt, 10 ) ) && ( LT_16( hNoiseEst->lt_haco_ev_fx, 11469 ) ) /* 0.35 in Q15 */ - && ( LT_16( hNoiseEst->act_pred_fx, 26214 ) ) /* 0.80 in Q15 */ - ) ) - { - tmp = 1; - move16(); - } - - tn_ini = 0; - move16(); test(); test(); - if ( ( LT_16( st_fx->ini_frame, HE_LT_CNT_INIT_FX ) ) && ( GT_16( hNoiseEst->harm_cor_cnt, 5 ) ) /* > 5 Q0 */ - && ( LT_16( sub( Etot, hNoiseEst->Etot_lp_fx ), 1792 ) ) /* 7 in Q8 */ - && ( NE_16( tmp, 0 ) ) ) + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + if ( LT_16( ini_frame, HE_LT_CNT_INIT_FX ) && GT_16( hNoiseEst->harm_cor_cnt, 5 ) && LT_16( sub( Etot, hNoiseEst->Etot_lp_fx ), 1792 /* 7 in Q8 */ ) && + ( ( LT_16( hNoiseEst->act_pred_fx, 19333 /* 0.59 in Q15 */ ) && LT_16( hNoiseEst->lt_haco_ev_fx, 7537 /* 0.23 in Q15 */ ) ) || LT_16( hNoiseEst->act_pred_fx, 12452 /* 0.38 in Q15 */ ) || + ( ( ( st_fx->element_mode == EVS_MONO ) && LT_16( hNoiseEst->lt_haco_ev_fx, 4915 /* 0.15 in Q15 */ ) ) || ( ( st_fx->element_mode > EVS_MONO ) && LT_16( hNoiseEst->lt_haco_ev_fx, 2621 /* 0.08 in Q15 */ ) ) ) || + LT_16( non_staB, 50 * 256 /* 50 in Q8 */ ) || ( aE_bgd != 0 ) || ( LT_16( Etot, 10752 /* 42.0 in Q8 */ ) && GT_16( hNoiseEst->harm_cor_cnt, 10 ) && LT_16( hNoiseEst->lt_haco_ev_fx, 11469 /* 0.35 in Q8 */ ) && LT_16( hNoiseEst->act_pred_fx, 26214 /* 0.8 in Q8 */ ) ) ) ) { tn_ini = 1; move16(); @@ -3374,15 +3365,12 @@ void noise_est_ivas_fx( move16(); /* Q15 */ /*if (( bg_bgd2 && ( aE_bgd || sd1_bgd || st->lt_tn_track >0.90f || NEW_POS_BG ) ) || tn_ini ) */ - tmp = 0; - move16(); - if ( GT_16( hNoiseEst->lt_tn_track_fx, 29491 ) ) /* .90 in Q15 */ - { - tmp = 1; - move16(); - } - - IF( s_or( s_and( bg_bgd2, s_or( aE_bgd, s_or( sd1_bgd, s_or( tmp, NEW_POS_BG ) ) ) ), tn_ini ) ) + test(); + test(); + test(); + test(); + test(); + IF( ( bg_bgd2 && ( aE_bgd || sd1_bgd || GT_16( hNoiseEst->lt_tn_track_fx, 29491 /* 0.90 in Q15 */ ) || NEW_POS_BG ) ) || tn_ini ) { /*if( ( ( st->act_pred < 0.85f ) && (aE_bgd !=0) @@ -3425,20 +3413,15 @@ void noise_est_ivas_fx( test(); test(); test(); - IF( ( ( LT_16( hNoiseEst->act_pred_fx, 27853 ) ) /* 0.85 in Q15 */ - && ( NE_16( aE_bgd, 0 ) ) && ( ( LT_16( hNoiseEst->lt_Ellp_dist_fx, 10 * 256 ) ) || ( NE_16( sd1_bgd, 0 ) ) ) /* 10.0 in Q8*/ - && ( LT_16( hNoiseEst->lt_tn_dist_fx, 40 * 256 ) ) /* 40.0 in Q8*/ - && ( LT_16( sub( Etot, hNoiseEst->totalNoise_fx ), 10 * 256 ) ) /* 10.0 in Q8*/ - ) || - ( ( hNoiseEst->first_noise_updt == 0 ) && ( GT_16( hNoiseEst->harm_cor_cnt, 80 ) ) && ( aE_bgd != 0 ) && ( GT_16( hNoiseEst->lt_aEn_zero_fx, 16384 ) ) /*.5 in Q15*/ - ) || - ( ( tn_ini != 0 ) && ( ( aE_bgd != 0 ) || ( LT_16( non_staB, 10 * 256 ) ) || ( GT_16( hNoiseEst->harm_cor_cnt, 80 ) ) ) /* 10.0 in Q8*/ - ) ) - + IF( ( LT_16( hNoiseEst->act_pred_fx, 27853 /* 0.85 in Q15 */ ) && ( aE_bgd != 0 ) && ( LT_16( hNoiseEst->lt_Ellp_dist_fx, 10 * 256 /* 10 in Q8*/ ) || ( sd1_bgd != 0 ) ) && ( LT_16( hNoiseEst->lt_tn_dist_fx, 40 * 256 ) ) /* 40.0 in Q8*/ + && LT_16( sub( Etot, hNoiseEst->totalNoise_fx ), 10 * 256 /* 10 in Q8 */ ) /* 10.0 in Q8*/ ) || + ( ( hNoiseEst->first_noise_updt == 0 ) && GT_16( hNoiseEst->harm_cor_cnt, 80 ) && ( aE_bgd != 0 ) && GT_16( hNoiseEst->lt_aEn_zero_fx, 16384 /* 0.5 in Q15 */ ) ) || + ( ( tn_ini != 0 ) && ( ( aE_bgd != 0 ) || LT_16( non_staB, 10 * 256 /* 10 in Q8*/ ) || GT_16( hNoiseEst->harm_cor_cnt, 80 ) ) ) ) { updt_step = 32767; move16(); hNoiseEst->first_noise_updt = 1; + move16(); FOR( i = 0; i < NB_BANDS; i++ ) { hNoiseEst->bckr_fx[i] = tmpN[i]; @@ -3452,21 +3435,14 @@ void noise_est_ivas_fx( ( st->harm_cor_cnt > 50 && st->first_noise_updt > 30 && aE_bgd && st->lt_aEn_zero>0.5f ) || tn_ini ) */ - ELSE IF( ( ( LT_16( hNoiseEst->act_pred_fx, 26214 ) ) /* .8 in Q15*/ - && ( ( aE_bgd != 0 ) || ( PAU != 0 ) ) && ( LT_16( hNoiseEst->lt_haco_ev_fx, 3277 ) ) ) /* .10 in q15*/ - || ( ( LT_16( hNoiseEst->act_pred_fx, 22938 ) ) /* 0.70 in Q15 */ - && ( ( aE_bgd != 0 ) || ( LT_16( non_staB, 17 * 256 ) ) ) /* 17.0 in Q8 */ - && ( PAU != 0 ) && ( LT_16( hNoiseEst->lt_haco_ev_fx, 4915 ) ) /* 0.15 in Q15 */ - ) || - ( ( GT_16( hNoiseEst->harm_cor_cnt, 80 ) ) && ( GT_16( hNoiseEst->totalNoise_fx, 5 * 256 ) ) /* 5.0 in Q8 */ - && ( LT_16( Etot, s_max( (Word16) 1 * 256, add( Etot_l_lp, add( hNoiseEst->Etot_v_h2_fx, shr( hNoiseEst->Etot_v_h2_fx, 1 ) ) ) ) ) ) /* 1.5= 1.0+.5 */ - ) || - ( ( GT_16( hNoiseEst->harm_cor_cnt, 50 ) ) && ( GT_16( hNoiseEst->first_noise_updt, 30 ) ) && ( aE_bgd != 0 ) && ( GT_16( hNoiseEst->lt_aEn_zero_fx, 16384 ) ) ) /*.5 in Q15*/ - || ( tn_ini != 0 ) ) - + ELSE IF( ( LT_16( hNoiseEst->act_pred_fx, 26214 /* 0.8 in Q15*/ ) && ( ( aE_bgd != 0 ) || ( PAU != 0 ) ) && ( LT_16( hNoiseEst->lt_haco_ev_fx, 3277 /* 0.1 in q15*/ ) ) ) || + ( ( LT_16( hNoiseEst->act_pred_fx, 22938 /* 0.70 in Q15 */ ) ) && ( ( aE_bgd != 0 ) || ( LT_16( non_staB, 17 * 256 /* 17.0 in Q8 */ ) ) ) && ( PAU != 0 ) && ( LT_16( hNoiseEst->lt_haco_ev_fx, 4915 /* 0.15 in Q15 */ ) ) ) || + ( GT_16( hNoiseEst->harm_cor_cnt, 80 ) && GT_16( hNoiseEst->totalNoise_fx, 5 * 256 /* 5.0 in Q8 */ ) && LT_16( Etot, s_max( 1 * 256, add( Etot_l_lp, add( hNoiseEst->Etot_v_h2_fx, shr( hNoiseEst->Etot_v_h2_fx, 1 ) ) /* 1.5= 1.0+.5 */ ) ) ) ) || + ( GT_16( hNoiseEst->harm_cor_cnt, 50 ) && GT_16( hNoiseEst->first_noise_updt, 30 ) && ( aE_bgd != 0 ) && GT_16( hNoiseEst->lt_aEn_zero_fx, 16384 /*.5 in Q15*/ ) ) || ( tn_ini != 0 ) ) { updt_step = 3277; move16(); /* 0.1 in Q15 */ + /* if ( !aE_bgd && st->harm_cor_cnt < 50 && ( (st->act_pred > 0.6f) || ( (tn_ini==0) && (Etot_l_lp - st->totalNoise < 10.0f) && non_staB > 8.0f ) @@ -3478,36 +3454,31 @@ void noise_est_ivas_fx( test(); test(); test(); - IF( ( aE_bgd == 0 ) && ( LT_16( hNoiseEst->harm_cor_cnt, 50 ) ) && ( ( GT_16( hNoiseEst->act_pred_fx, 19661 ) ) /* 0.6 in Q15*/ - || ( ( tn_ini == 0 ) && ( LT_16( sub( Etot_l_lp, hNoiseEst->totalNoise_fx ), 10 * 256 ) ) /* 10.0 in Q8 */ - && ( GT_16( non_staB, 8 * 256 ) ) /* 8.0 in in Q8*/ - ) ) ) + if ( ( aE_bgd == 0 ) && LT_16( hNoiseEst->harm_cor_cnt, 50 ) && + ( GT_16( hNoiseEst->act_pred_fx, 19661 /* 0.6 in Q15*/ ) || + ( ( tn_ini == 0 ) && LT_16( sub( Etot_l_lp, hNoiseEst->totalNoise_fx ), 10 * 256 /* 10.0 in Q8 */ ) && GT_16( non_staB, 8 * 256 /* 8.0 in in Q8*/ ) ) ) ) { updt_step = 328; move16(); /* 0.01 Q15 */ } - /* - IF (updt_step > 0 ) - { - */ + hNoiseEst->first_noise_updt = 1; move16(); FOR( i = 0; i < NB_BANDS; i++ ) { /* st->bckr[i] = st->bckr[i] + updt_step * (tmpN[i]-st->bckr[i]);*/ /* 32 bit state update */ - Ltmp = L_sub( tmpN[i], hNoiseEst->bckr_fx[i] ); /*Q_new+Q_SCALE*/ - Ltmp = Mult_32_16( Ltmp, updt_step ); /* Q_new+Q_SCALE+15+1 -16*/ - hNoiseEst->bckr_fx[i] = L_add( Ltmp, hNoiseEst->bckr_fx[i] ); + Ltmp = L_sub( tmpN[i], hNoiseEst->bckr_fx[i] ); // hNoiseEst->q_bckr + Ltmp = Mult_32_16( Ltmp, updt_step ); + hNoiseEst->bckr_fx[i] = L_add( Ltmp, hNoiseEst->bckr_fx[i] ); // hNoiseEst->q_bckr move32(); } - /* - } */ } /*else if (aE_bgd || st->harm_cor_cnt > 100 )*/ - ELSE IF( ( aE_bgd != 0 ) || ( GT_16( hNoiseEst->harm_cor_cnt, 100 ) ) ) + ELSE IF( ( aE_bgd != 0 ) || GT_16( hNoiseEst->harm_cor_cnt, 100 ) ) { hNoiseEst->first_noise_updt = add( hNoiseEst->first_noise_updt, 1 ); + move16(); } } ELSE @@ -3515,18 +3486,17 @@ void noise_est_ivas_fx( /* If in music lower bckr to drop further */ test(); test(); - IF( ( GT_16( hNoiseEst->low_tn_track_cnt, 300 ) ) && ( GT_16( hNoiseEst->lt_haco_ev_fx, 29491 ) ) /*.9 in Q15 */ - && ( hNoiseEst->totalNoise_fx > 0 ) ) + IF( GT_16( hNoiseEst->low_tn_track_cnt, 300 ) && GT_16( hNoiseEst->lt_haco_ev_fx, 29491 /* 0.9 in Q15 */ ) && ( hNoiseEst->totalNoise_fx > 0 ) ) { updt_step = -655; move16(); /* for debug purposes */ FOR( i = 0; i < NB_BANDS; i++ ) { - IF( GT_32( hNoiseEst->bckr_fx[i], L_shl( Le_min_scaled, 1L ) ) ) /* 2*E_MIN(float) in float, here we use 2*Le_min_scaled Q_new+Q_SCALE */ + IF( GT_32( hNoiseEst->bckr_fx[i], L_shl_sat( E_MIN_FXQ31, sub( hNoiseEst->q_bckr, Q30 ) ) /* 2*E_MIN */ ) ) { /* st->bckr[i] = 0.98f*st->bckr[i]; */ - hNoiseEst->bckr_fx[i] = Mult_32_16( hNoiseEst->bckr_fx[i], 32113 ); /* .98 in Q15 */ - move32(); /* move to array */ + hNoiseEst->bckr_fx[i] = Mult_32_16( hNoiseEst->bckr_fx[i], 32113 /* .98 in Q15 */ ); // hNoiseEst->q_bckr + move32(); /* move to array */ } } } @@ -3537,14 +3507,16 @@ void noise_est_ivas_fx( move16(); if ( hNoiseEst->aEn == 0 ) { - tmp = 32767; + tmp = 6554; // 0.2 in Q15 move16(); } - hNoiseEst->lt_aEn_zero_fx = noise_est_AR1_Qx( tmp, hNoiseEst->lt_aEn_zero_fx, 6554 ); /* alpha=0.2 , Q15 */ + hNoiseEst->lt_aEn_zero_fx = mac_r( tmp, hNoiseEst->lt_aEn_zero_fx, 26214 /* 0.8 in Q15*/ ); // Q15 + move16(); + IF( st_fx->element_mode > EVS_MONO ) { test(); - if ( hNoiseEst->first_noise_updt > 0 && LT_16( hNoiseEst->first_noise_updt_cnt, 100 ) ) + IF( hNoiseEst->first_noise_updt > 0 && LT_16( hNoiseEst->first_noise_updt_cnt, 100 ) ) { hNoiseEst->first_noise_updt_cnt = add( hNoiseEst->first_noise_updt_cnt, 1 ); move16(); diff --git a/lib_enc/noise_adjust.c b/lib_enc/noise_adjust.c deleted file mode 100644 index d441f6ead49ddcb3a6a1ffab0962633db8157cd0..0000000000000000000000000000000000000000 --- a/lib_enc/noise_adjust.c +++ /dev/null @@ -1,43 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include -#include "cnst.h" -#include "rom_com.h" -#include "prot.h" -#include "wmc_auto.h" diff --git a/lib_enc/normalizecoefs.c b/lib_enc/normalizecoefs.c deleted file mode 100644 index 8f0950fbae8f9f2c626e0122b0369502d15bcff1..0000000000000000000000000000000000000000 --- a/lib_enc/normalizecoefs.c +++ /dev/null @@ -1,47 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include "rom_com.h" -#include "prot.h" -#include "wmc_auto.h" - -/*-------------------------------------------------------------------------- - * normalizecoefs() - * - * Normalize MDCT coefficients with quantized norms - *--------------------------------------------------------------------------*/ diff --git a/lib_enc/normalizecoefs_fx.c b/lib_enc/normalizecoefs_fx.c index f6f5eedee7a031fce359b4471da4a17cf0aa892c..ea394f54bd29ca2e04f9320d4a5196335a727b69 100644 --- a/lib_enc/normalizecoefs_fx.c +++ b/lib_enc/normalizecoefs_fx.c @@ -31,6 +31,7 @@ void normalizecoefs_fx( Word16 subvec_start, subvec_end, num_coefs; #ifdef BASOP_NOGLOB_DECLARE_LOCAL Flag Overflow = 0; + move16(); #endif pcoefs = coefs; pcoefs16 = coefs_norm; @@ -54,13 +55,8 @@ void normalizecoefs_fx( *pcoefs = Mpy_32_16_1( *pcoefs, INV2POWHALF ); move32(); } -#ifdef BASOP_NOGLOB *pcoefs16++ = round_fx_o( L_shl_o( *pcoefs++, 16 - k, &Overflow ), &Overflow ); /* Q12 */ -#else - BASOP_SATURATE_WARNING_OFF_EVS /* May saturate for strong peaks in a high band, in which case saturation is desirable */ - *pcoefs16++ = round_fx( L_shl( *pcoefs++, 16 - k ) ); /* Q12 */ - BASOP_SATURATE_WARNING_ON_EVS -#endif + move16(); } } diff --git a/lib_enc/peak_vq_enc.c b/lib_enc/peak_vq_enc.c deleted file mode 100644 index 867e40cdc445406ceb1dc5e53245e971abe03b05..0000000000000000000000000000000000000000 --- a/lib_enc/peak_vq_enc.c +++ /dev/null @@ -1,44 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include -#include "cnst.h" -#include "prot.h" -#include "rom_com.h" -#include "wmc_auto.h" -#include diff --git a/lib_enc/peak_vq_enc_fx.c b/lib_enc/peak_vq_enc_fx.c index 81a83c7f3d59407d852000ce35e30bbd4c48c61c..aa4763aa63e49e848b61f4c05ecaa63ceeb20dd0 100644 --- a/lib_enc/peak_vq_enc_fx.c +++ b/lib_enc/peak_vq_enc_fx.c @@ -11,7 +11,6 @@ #include "rom_com_fx.h" #include "rom_com.h" #include "prot_fx.h" /* Function prototypes */ -#include "prot.h" /* Function prototypes */ #include "prot_fx_enc.h" /* Function prototypes */ /*-------------------------------------------------------------------------- @@ -135,16 +134,18 @@ Word16 peak_vq_enc_ivas_fx( logqnorm_ivas_fx( &nf_gains[i], 12, &indx, 32, 1, &thren_HQ_fx[0] ); /* De-quantization */ - acc = L_add( dicn_fx[indx], 0 ); /* Q14 */ + acc = dicn_fx[indx]; /* Q14 */ + move32(); nf_gains[i] = L_shr( acc, 1 + 2 ); /* nf_gains in Q12. dicn_fx is in Q14. Need extra shift +2. */ move32(); - push_indice( hBstr, IND_HVQ_NF_GAIN, (int) indx, 5 ); + + push_indice( hBstr, IND_HVQ_NF_GAIN, indx, 5 ); bits = add( bits, 5 ); } /* Signal number of peaks */ i = sub( max_peaks, vq_peaks ); - push_indice( hBstr, IND_NUM_PEAKS, (int) i, 5 ); + push_indice( hBstr, IND_NUM_PEAKS, i, 5 ); bits = add( bits, 5 ); /* Identify position of first peak and arrange peak gains by position */ @@ -258,8 +259,8 @@ Word16 peak_vq_enc_ivas_fx( move16(); } - push_indice( hBstr, IND_FLAGN, (int) FlagN, 1 ); - push_indice( hBstr, IND_PG_IDX, (int) pgain_difidx[0], GAIN0_BITS ); + push_indice( hBstr, IND_FLAGN, FlagN, 1 ); + push_indice( hBstr, IND_PG_IDX, pgain_difidx[0], GAIN0_BITS ); IF( FlagN ) { @@ -273,7 +274,7 @@ Word16 peak_vq_enc_ivas_fx( r = pgain_huffsizn[j]; move16(); - push_indice( hBstr, IND_PG_IDX, (int) m, r ); + push_indice( hBstr, IND_PG_IDX, m, r ); } } ELSE @@ -281,7 +282,7 @@ Word16 peak_vq_enc_ivas_fx( pPgainDifIdx = &pgain_difidx[1]; FOR( i = 0; i < vqPeaksMinus1; i++ ) { - push_indice( hBstr, IND_PG_IDX, (int) ( *pPgainDifIdx++ ), GAINI_BITS ); + push_indice( hBstr, IND_PG_IDX, ( *pPgainDifIdx++ ), GAINI_BITS ); } } @@ -298,6 +299,7 @@ Word16 peak_vq_enc_ivas_fx( IF( pos_vec[indx] < 0 ) { peak_gains[i] = L_negate( peak_gains[i] ); /* Q12 */ + move32(); } } @@ -307,13 +309,13 @@ Word16 peak_vq_enc_ivas_fx( num_overlap_bins = sub( 5, sub( vq_peak_idx[i + 1], vq_peak_idx[i] ) ); indx = sub( vq_peak_idx[i], 2 ); quant_peaks_ivas_fx( hBstr, &coefs[indx], &coefs_out[indx], &peak_gains[i], &vq_cb_idx, num_overlap_bins, core_brate, vq_peaks ); - push_indice( hBstr, IND_HVQ_PEAKS, (UWord16) vq_cb_idx, 8 ); + push_indice( hBstr, IND_HVQ_PEAKS, vq_cb_idx, 8 ); bits = add( bits, 9 ); } indx = sub( vq_peak_idx[i], 2 ); quant_peaks_ivas_fx( hBstr, &coefs[indx], &coefs_out[indx], &peak_gains[i], &vq_cb_idx, 0, core_brate, vq_peaks ); - push_indice( hBstr, IND_HVQ_PEAKS, (UWord16) vq_cb_idx, 8 ); + push_indice( hBstr, IND_HVQ_PEAKS, vq_cb_idx, 8 ); bits = add( bits, 9 ); /* Quantize peak positions and sign with HVQ */ @@ -392,6 +394,7 @@ Word16 peak_vq_enc_ivas_fx( FOR( k = 0; k < pvq_bands; k++ ) { indx = pvq_norm[k]; + move16(); tmp1 = ratio( gopt[k], fg_pred[k], &exp1 ); tmp1 = shr( tmp1, sub( 1, exp1 ) ); /* Q13 */ Mpy_32_16_ss( dicn_fx[indx], tmp1, &normq, &dontCare16 ); /* dicn_fx in Q14, sorted_pvq_gain_pred_err_fx in Q13. */ @@ -412,7 +415,8 @@ Word16 peak_vq_enc_ivas_fx( move16(); indx = pvq_norm[k]; move16(); - normq = L_add( dicn_fx[indx], 0 ); /* in Q14 */ + normq = dicn_fx[indx]; /* in Q14 */ + move32(); j = 0; move16(); IF( GE_16( k, sub( pvq_bands, n_sel_bnds ) ) ) @@ -551,15 +555,17 @@ Word16 peak_vq_enc_fx( logqnorm_fx( &nf_gains[i], 12, &indx, 32, 1, 0 ); /* De-quantization */ - acc = L_add( dicn_fx[indx], 0 ); /* Q14 */ + acc = dicn_fx[indx]; /* Q14 */ + move32(); nf_gains[i] = L_shr( acc, 1 + 2 ); /* nf_gains in Q12. dicn_fx is in Q14. Need extra shift +2. */ - push_indice_fx( hBstr, IND_HVQ_NF_GAIN, (int) indx, 5 ); + move32(); + push_indice_fx( hBstr, IND_HVQ_NF_GAIN, indx, 5 ); bits = add( bits, 5 ); } /* Signal number of peaks */ i = sub( max_peaks, vq_peaks ); - push_indice_fx( hBstr, IND_NUM_PEAKS, (int) i, 5 ); + push_indice_fx( hBstr, IND_NUM_PEAKS, i, 5 ); bits = add( bits, 5 ); /* Identify position of first peak and arrange peak gains by position */ @@ -650,6 +656,7 @@ Word16 peak_vq_enc_fx( /* Huffman coding */ hcode_l = 0; + move16(); pPgainDifIdx = &pgain_difidx[1]; FOR( i = 0; i < vqPeaksMinus1; i++ ) { @@ -670,8 +677,8 @@ Word16 peak_vq_enc_fx( move16(); } - push_indice_fx( hBstr, IND_FLAGN, (int) FlagN, 1 ); - push_indice_fx( hBstr, IND_PG_IDX, (int) pgain_difidx[0], GAIN0_BITS ); + push_indice_fx( hBstr, IND_FLAGN, FlagN, 1 ); + push_indice_fx( hBstr, IND_PG_IDX, pgain_difidx[0], GAIN0_BITS ); IF( FlagN ) { @@ -685,7 +692,7 @@ Word16 peak_vq_enc_fx( r = pgain_huffsizn[j]; move16(); - push_indice_fx( hBstr, IND_PG_IDX, (int) m, r ); + push_indice_fx( hBstr, IND_PG_IDX, m, r ); } } ELSE @@ -693,7 +700,7 @@ Word16 peak_vq_enc_fx( pPgainDifIdx = &pgain_difidx[1]; FOR( i = 0; i < vqPeaksMinus1; i++ ) { - push_indice_fx( hBstr, IND_PG_IDX, (int) ( *pPgainDifIdx++ ), GAINI_BITS ); + push_indice_fx( hBstr, IND_PG_IDX, ( *pPgainDifIdx++ ), GAINI_BITS ); } } @@ -710,6 +717,7 @@ Word16 peak_vq_enc_fx( IF( pos_vec[indx] < 0 ) { peak_gains[i] = L_negate( peak_gains[i] ); /* Q12 */ + move32(); } } @@ -719,13 +727,13 @@ Word16 peak_vq_enc_fx( num_overlap_bins = sub( 5, sub( vq_peak_idx[i + 1], vq_peak_idx[i] ) ); indx = sub( vq_peak_idx[i], 2 ); quant_peaks_fx( hBstr, &coefs[indx], &coefs_out[indx], &peak_gains[i], &vq_cb_idx, num_overlap_bins, core_brate, vq_peaks ); - push_indice_fx( hBstr, IND_HVQ_PEAKS, (UWord16) vq_cb_idx, 8 ); + push_indice_fx( hBstr, IND_HVQ_PEAKS, vq_cb_idx, 8 ); bits = add( bits, 9 ); } indx = sub( vq_peak_idx[i], 2 ); quant_peaks_fx( hBstr, &coefs[indx], &coefs_out[indx], &peak_gains[i], &vq_cb_idx, 0, core_brate, vq_peaks ); - push_indice_fx( hBstr, IND_HVQ_PEAKS, (UWord16) vq_cb_idx, 8 ); + push_indice_fx( hBstr, IND_HVQ_PEAKS, vq_cb_idx, 8 ); bits = add( bits, 9 ); /* Quantize peak positions and sign with HVQ */ @@ -757,6 +765,7 @@ Word16 peak_vq_enc_fx( pCoefsOut = coefs_out + i; } k_sort[k] = k; + move16(); j = 0; move16(); pPvqVectorBandStart = pPvqVector; @@ -803,12 +812,14 @@ Word16 peak_vq_enc_fx( FOR( k = 0; k < pvq_bands; k++ ) { indx = pvq_norm[k]; + move16(); tmp1 = ratio( gopt[k], fg_pred[k], &exp1 ); tmp1 = shr( tmp1, sub( 1, exp1 ) ); /* Q13 */ Mpy_32_16_ss( dicn_fx[indx], tmp1, &normq, &dontCare16 ); /* dicn_fx in Q14, sorted_pvq_gain_pred_err_fx in Q13. */ logqnorm_fx( &normq, 12, &pvq_norm[k], 40, 1, 0 ); /* normq in Q(14+(16+13)+1-32)=Q12 */ pvq_norm[k] = sub( pvq_norm[k], 8 ); + move16(); IF( pvq_norm[k] < 0 ) { pvq_norm[k] = 0; @@ -819,7 +830,7 @@ Word16 peak_vq_enc_fx( pvq_bits = add( pvq_bits, HVQ_PVQ_GAIN_BITS ); pvq_norm[k] = add( pvq_norm[k], 8 ); - + move16(); indx = pvq_norm[k]; move16(); normq = L_add( dicn_fx[indx], 0 ); /* in Q14 */ @@ -839,6 +850,7 @@ Word16 peak_vq_enc_fx( tmp16 = extract_h( acc ); /* in Q(28 - 16 = 12) */ Mpy_32_16_ss( normq, tmp16, &acc, &dontCare16 ); /* acc(Q11), normq(Q14), tmp16(Q12) */ *pCoefsOut = L_shl( acc, 12 - 11 ); /* Q12 */ + move32(); j = add( j, 1 ); } pCoefsOut++; @@ -1064,12 +1076,14 @@ static void quant_peaks_fx( x[i] = div_s( manIn, manPeakGain ); /* in Q(15+expIn-expPeakGain) */ Qx_vec[i] = add( 15, sub( expIn, expPeakGain ) ); + move16(); Qx = s_min( Qx, Qx_vec[i] ); /* Restore the sign destroyed by abs operations. */ if ( L_xor( vectIn, *peak_gain ) < 0 ) /* Check the sign bits (MSB). */ { x[i] = negate( x[i] ); + move16(); } } FOR( i = 0; i < 4; i++ ) @@ -1077,6 +1091,7 @@ static void quant_peaks_fx( IF( NE_16( Qx_vec[i], Qx ) ) { x[i] = shr( x[i], sub( Qx_vec[i], Qx ) ); /* Qx */ + move16(); } } absPeakGain = L_abs( peak_gain[0] ); @@ -1132,25 +1147,31 @@ static void quant_peaks_fx( IF( cb_class == 0 ) { *vq_idx = w_vquant_fx( x, Qx, weights, xq, hvq_peak_cb_fx, cbSize, 0 ); + move16(); push_indice_fx( hBstr, IND_HVQ_PEAKS, 0, 1 ); } ELSE IF( EQ_16( cb_class, 1 ) ) { indx = sub( HVQ_CB_SIZE * 2, shl( search_overlap, 2 ) ); *vq_idx = w_vquant_fx( x, Qx, weights, xq, &hvq_peak_cb_fx[indx], cbSize, 0 ); + move16(); *vq_idx = add( *vq_idx, sub( HVQ_CB_SIZE / 2, search_overlap ) ); + move16(); push_indice_fx( hBstr, IND_HVQ_PEAKS, 0, 1 ); } ELSE IF( EQ_16( cb_class, 2 ) ) { indx = sub( HVQ_CB_SIZE * 2, shl( search_overlap, 2 ) ); *vq_idx = w_vquant_fx( x, Qx, weights, xq, &hvq_peak_cb_fx[indx], cbSize, 1 ); + move16(); *vq_idx = add( *vq_idx, sub( HVQ_CB_SIZE / 2, search_overlap ) ); + move16(); push_indice_fx( hBstr, IND_HVQ_PEAKS, 1, 1 ); } ELSE { *vq_idx = w_vquant_fx( x, Qx, weights, xq, hvq_peak_cb_fx, cbSize, 1 ); + move16(); push_indice_fx( hBstr, IND_HVQ_PEAKS, 1, 1 ); } @@ -1239,7 +1260,7 @@ static Word16 sparse_code_pos_fx( FOR( i = 0; i < HVQ_CP_MAP_IDX_LEN; i++ ) { result[bits++] = shr( s_and( idx, mask ), sub( HVQ_CP_MAP_IDX_LEN - 1, i ) ); - mask >>= 1; + mask = shr( mask, 1 ); } } } @@ -1409,6 +1430,7 @@ static Word16 hvq_code_pos_fx( FOR( i = 1; i < num_peaks; i++ ) { delta[i] = sub( sub( peak_idx[i], peak_idx[i - 1] ), HVQ_CP_HUFF_OFFSET ); + move16(); if ( LT_16( delta_max, delta[i] ) ) { delta_max = delta[i]; diff --git a/lib_enc/pit_enc.c b/lib_enc/pit_enc.c deleted file mode 100644 index 224203cb0ee0bd99d04af22294321c92c62da034..0000000000000000000000000000000000000000 --- a/lib_enc/pit_enc.c +++ /dev/null @@ -1,45 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include -#include "options.h" -#include -#include "cnst.h" -#include "prot.h" -#include "rom_enc.h" -#include "rom_com.h" -#include "wmc_auto.h" diff --git a/lib_enc/pit_enc_fx.c b/lib_enc/pit_enc_fx.c index ea09805be3b3cdaf5cdf45ff52fbf2a35c491850..bcf7d33bb2431fb8cfb1709656b8080e40c4150a 100644 --- a/lib_enc/pit_enc_fx.c +++ b/lib_enc/pit_enc_fx.c @@ -10,7 +10,6 @@ #include "rom_com.h" /* Static table prototypes */ //#include "prot_fx.h" /* Function prototypes */ #include "rom_basop_util.h" -#include "prot.h" /* Function prototypes */ #include "prot_fx.h" /* Function prototypes */ #include "prot_fx_enc.h" /* Function prototypes */ #include "prot_fx_enc.h" /* Function prototypes */ @@ -90,11 +89,14 @@ Word16 pit_encode_fx( /* o : Fractional pitc if ( EQ_16( L_subfr, 2 * L_SUBFR ) ) { L_sufr_sft = 7; + move16(); } /*----------------------------------------------------------------* * convert pitch values to 16kHz domain *----------------------------------------------------------------*/ + test(); + test(); IF( EQ_16( L_frame, L_FRAME ) || ( tdm_Pri_pitch_buf != NULL && tdm_Pri_pitch_buf[0] < 0 ) ) { Copy( pitch, T_op, 2 ); @@ -183,7 +185,8 @@ Word16 pit_encode_fx( /* o : Fractional pitc move16(); IF( NE_16( coder_type, AUDIO ) ) { - nBits = pitch_bits[shr( i_subfr, L_sufr_sft )]; + nBits = pitch_bits[i_subfr >> L_sufr_sft]; + move16(); } IF( EQ_16( coder_type, AUDIO ) ) { @@ -196,7 +199,7 @@ Word16 pit_encode_fx( /* o : Fractional pitc move16(); test(); test(); - if ( EQ_16( L_subfr, L_frame / 2 ) && i_subfr != 0 && EQ_16( L_frame, L_FRAME ) ) + if ( EQ_16( L_subfr, shr( L_frame, 1 ) ) && i_subfr != 0 && EQ_16( L_frame, L_FRAME ) ) { pit_flag = L_SUBFR; move16(); @@ -225,7 +228,7 @@ Word16 pit_encode_fx( /* o : Fractional pitc /* search and encode the closed loop pitch period */ *T0 = pitch_fr4_fx( &exc[i_subfr], xn, h1, *T0_min, *T0_max, T0_frac, pit_flag, *limit_flag, PIT_MAX, PIT_MAX, L_FRAME, L_subfr ); - + move16(); pit_Q_enc_fx( hBstr, 0, nBits, delta, pit_flag, *limit_flag, *T0, *T0_frac, T0_min, T0_max ); } ELSE IF( EQ_16( coder_type, VOICED ) ) @@ -249,7 +252,7 @@ Word16 pit_encode_fx( /* o : Fractional pitc } /* search and encode the closed loop pitch period */ - test(); + test(); IF( EQ_16( nBits, 9 ) || EQ_16( nBits, 5 ) ) { @@ -264,48 +267,6 @@ Word16 pit_encode_fx( /* o : Fractional pitc pit_Q_enc_fx( hBstr, 0, nBits, delta, pit_flag, *limit_flag, *T0, *T0_frac, T0_min, T0_max ); } -#ifdef ADD_LRTD - else if ( tdm_Pitch_reuse_flag == 1 || nBits == 4 ) - { - /*-------------------------------------------------------* - * Pitch encoding with reusing primary channel information - *-------------------------------------------------------*/ - int16_t loc_T0, loc_frac; - - delta = 4; - - pit_flag = L_SUBFR; - - if ( L_subfr == 2 * L_SUBFR ) - { - loc_T0 = (int16_t) ( 0.5f * tdm_Pri_pitch_buf[i_subfr / L_SUBFR] + 0.5f * tdm_Pri_pitch_buf[( i_subfr + L_SUBFR ) / L_SUBFR] ); - loc_frac = (int16_t) ( ( ( 0.5f * tdm_Pri_pitch_buf[i_subfr / L_SUBFR] + 0.5f * tdm_Pri_pitch_buf[( i_subfr + L_SUBFR ) / L_SUBFR] ) - loc_T0 ) * 4.0f ); - } - else - { - loc_T0 = (int16_t) tdm_Pri_pitch_buf[i_subfr / L_SUBFR]; - loc_frac = (int16_t) ( ( tdm_Pri_pitch_buf[i_subfr / L_SUBFR] - loc_T0 ) * 4.0f ); - } - - /* pitch lag search limitation */ - limit_T0( L_FRAME, delta, pit_flag, *limit_flag, loc_T0, loc_frac, T0_min, T0_max ); - if ( nBits > 0 ) - { - /* search and encode the closed loop pitch period */ - *T0 = pitch_fr4( &exc[i_subfr], xn, h1, *T0_min, *T0_max, T0_frac, pit_flag, *limit_flag, PIT_MIN, PIT_FR1_8b, L_FRAME, L_SUBFR ); - if ( delta == 8 ) - { - *T0_frac = 0; - } - pit_Q_enc( hBstr, 0, nBits, delta, pit_flag, *limit_flag, *T0, *T0_frac, T0_min, T0_max ); - } - else - { - *T0 = loc_T0; - *T0_frac = loc_frac; - } - } -#endif ELSE { /*-------------------------------------------------------* @@ -336,10 +297,12 @@ Word16 pit_encode_fx( /* o : Fractional pitc IF( *limit_flag == 0 ) { *T0 = pitch_fr4_fx( &exc[i_subfr], xn, h1, *T0_min, *T0_max, T0_frac, pit_flag, *limit_flag, PIT_MIN, PIT_FR1_8b, L_FRAME, L_SUBFR ); + move16(); } ELSE { *T0 = pitch_fr4_fx( &exc[i_subfr], xn, h1, *T0_min, *T0_max, T0_frac, pit_flag, *limit_flag, PIT_MIN_EXTEND, PIT_FR1_EXTEND_8b, L_FRAME, L_SUBFR ); + move16(); } } ELSE IF( EQ_16( nBits, 9 ) || EQ_16( nBits, 6 ) ) @@ -347,15 +310,18 @@ Word16 pit_encode_fx( /* o : Fractional pitc IF( *limit_flag == 0 ) { *T0 = pitch_fr4_fx( &exc[i_subfr], xn, h1, *T0_min, *T0_max, T0_frac, pit_flag, *limit_flag, PIT_FR2_9b, PIT_FR1_9b, L_FRAME, L_SUBFR ); + move16(); } ELSE { *T0 = pitch_fr4_fx( &exc[i_subfr], xn, h1, *T0_min, *T0_max, T0_frac, pit_flag, *limit_flag, PIT_FR2_EXTEND_9b, PIT_FR1_EXTEND_9b, L_FRAME, L_SUBFR ); + move16(); } } ELSE IF( EQ_16( nBits, 10 ) ) { *T0 = pitch_fr4_fx( &exc[i_subfr], xn, h1, *T0_min, *T0_max, T0_frac, pit_flag, *limit_flag, PIT_MAX, PIT_MAX, L_FRAME, L_SUBFR ); + move16(); } pit_Q_enc_fx( hBstr, 0, nBits, delta, pit_flag, *limit_flag, *T0, *T0_frac, T0_min, T0_max ); @@ -366,10 +332,12 @@ Word16 pit_encode_fx( /* o : Fractional pitc IF( EQ_16( nBits, 9 ) || EQ_16( nBits, 6 ) ) { *T0 = pitch_fr4_fx( &exc[i_subfr], xn, h1, *T0_min, *T0_max, T0_frac, pit_flag, *limit_flag, PIT16k_FR2_EXTEND_9b, PIT16k_FR1_EXTEND_9b, L_FRAME16k, L_SUBFR ); + move16(); } - ELSE IF( nBits == 10 ) + ELSE IF( EQ_16( nBits, 10 ) ) { *T0 = pitch_fr4_fx( &exc[i_subfr], xn, h1, *T0_min, *T0_max, T0_frac, pit_flag, *limit_flag, PIT16k_FR2_EXTEND_10b, PIT16k_MAX, L_FRAME16k, L_SUBFR ); + move16(); } pit16k_Q_enc_fx( hBstr, nBits, *limit_flag, *T0, *T0_frac, T0_min, T0_max ); @@ -410,6 +378,7 @@ Word16 pit_encode_fx( /* o : Fractional pitc /* search and encode the closed loop pitch period */ *T0 = pitch_fr4_fx( &exc[i_subfr], xn, h1, *T0_min, *T0_max, T0_frac, pit_flag, *limit_flag, PIT_MIN, PIT_FR1_8b, L_FRAME, L_SUBFR ); + move16(); } ELSE IF( EQ_32( core_brate, ACELP_8k85 ) ) { @@ -432,6 +401,7 @@ Word16 pit_encode_fx( /* o : Fractional pitc /* search and encode the closed loop pitch period */ *T0 = pitch_fr4_fx( &exc[i_subfr], xn, h1, *T0_min, *T0_max, T0_frac, pit_flag, *limit_flag, PIT_MIN, PIT_FR1_8b, L_FRAME, L_SUBFR ); + move16(); } ELSE { @@ -458,6 +428,7 @@ Word16 pit_encode_fx( /* o : Fractional pitc /* search and encode the closed loop pitch period */ *T0 = pitch_fr4_fx( &exc[i_subfr], xn, h1, *T0_min, *T0_max, T0_frac, pit_flag, *limit_flag, PIT_FR2_9b, PIT_FR1_9b, L_FRAME, L_SUBFR ); + move16(); } pit_Q_enc_fx( hBstr, 1, nBits, delta, pit_flag, *limit_flag, *T0, *T0_frac, T0_min, T0_max ); @@ -473,26 +444,27 @@ Word16 pit_encode_fx( /* o : Fractional pitc return pitch_cl; } -Word16 pit_encode_ivas_fx( /* o : Fractional pitch for each subframe */ - BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ - const Word16 pitch_bits[], /* i : pitch bits */ - const Word32 core_brate, /* i : core bitrate */ - const Word16 Opt_AMR_WB, /* i : flag indicating AMR-WB IO mode */ - const Word16 L_frame, /* i : length of the frame */ - const Word16 coder_type, /* i : coding type */ - Word16 *limit_flag, /* i/o: restrained(0) or extended(1) Q limits */ - const Word16 i_subfr, /* i : subframe index */ - Word16 *exc, /* i/o: pointer to excitation signal frame */ - const Word16 L_subfr, /* i : subframe length */ - const Word16 *pitch, /* i : open loop pitch estimates in current frame */ - Word16 *T0_min, /* i/o: lower limit for close-loop search */ - Word16 *T0_max, /* i/o: higher limit for close-loop search */ - Word16 *T0, /* i/o: close loop integer pitch */ - Word16 *T0_frac, /* i/o: close loop fractional part of the pitch */ - const Word16 *h1, /* i : weighted filter input response */ - const Word16 *xn, /* i : target vector */ - const Word16 tdm_Pitch_reuse_flag, /* i : primary channel pitch reuse flag */ - const Word16 tdm_Pri_pitch_buf[] /* i : primary channel pitch buffer */ +Word16 pit_encode_ivas_fx( /* o : Fractional pitch for each subframe */ + BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ + const Word16 pitch_bits[], /* i : pitch bits */ + const Word32 core_brate, /* i : core bitrate */ + const Word16 Opt_AMR_WB, /* i : flag indicating AMR-WB IO mode */ + const Word16 L_frame, /* i : length of the frame */ + const Word16 coder_type, /* i : coding type */ + Word16 *limit_flag, /* i/o: restrained(0) or extended(1) Q limits */ + const Word16 i_subfr, /* i : subframe index */ + Word16 *exc, /* i/o: pointer to excitation signal frame Q_new */ + const Word16 L_subfr, /* i : subframe length */ + const Word16 *pitch, /* i : open loop pitch estimates in current frame */ + Word16 *T0_min, /* i/o: lower limit for close-loop search */ + Word16 *T0_max, /* i/o: higher limit for close-loop search */ + Word16 *T0, /* i/o: close loop integer pitch */ + Word16 *T0_frac, /* i/o: close loop fractional part of the pitch */ + const Word16 *h1, /* i : weighted filter input response Q(14 - norm_s(h1[0]) */ + const Word16 *xn, /* i : target vector Q_new */ + const Word16 tdm_Pitch_reuse_flag, /* i : primary channel pitch reuse flag */ + const Word16 tdm_Pri_pitch_buf[], /* i : primary channel pitch buffer */ + Word16 Q_new /* i */ ) { Word16 pitch_cl; @@ -505,11 +477,14 @@ Word16 pit_encode_ivas_fx( /* o : Fractional if ( EQ_16( L_subfr, 2 * L_SUBFR ) ) { L_sufr_sft = 7; + move16(); } /*----------------------------------------------------------------* * convert pitch values to 16kHz domain *----------------------------------------------------------------*/ + test(); + test(); IF( EQ_16( L_frame, L_FRAME ) || ( tdm_Pri_pitch_buf != NULL && tdm_Pri_pitch_buf[0] < 0 ) ) { Copy( pitch, T_op, 2 ); @@ -598,8 +573,9 @@ Word16 pit_encode_ivas_fx( /* o : Fractional move16(); IF( NE_16( coder_type, AUDIO ) ) { - nBits = pitch_bits[shr( i_subfr, L_sufr_sft )]; + nBits = pitch_bits[i_subfr >> L_sufr_sft]; } + test(); IF( EQ_16( coder_type, AUDIO ) ) { /*-------------------------------------------------------* @@ -611,7 +587,7 @@ Word16 pit_encode_ivas_fx( /* o : Fractional move16(); test(); test(); - if ( EQ_16( L_subfr, L_frame / 2 ) && i_subfr != 0 && EQ_16( L_frame, L_FRAME ) ) + if ( EQ_16( L_subfr, shr( L_frame, 1 ) ) && i_subfr != 0 && EQ_16( L_frame, L_FRAME ) ) { pit_flag = L_SUBFR; move16(); @@ -639,8 +615,8 @@ Word16 pit_encode_ivas_fx( /* o : Fractional } /* search and encode the closed loop pitch period */ - *T0 = pitch_fr4_fx( &exc[i_subfr], xn, h1, *T0_min, *T0_max, T0_frac, pit_flag, *limit_flag, PIT_MAX, PIT_MAX, L_FRAME, L_subfr ); - + *T0 = pitch_fr4_ivas_fx( &exc[i_subfr], xn, h1, *T0_min, *T0_max, T0_frac, pit_flag, *limit_flag, PIT_MAX, PIT_MAX, L_FRAME, L_subfr, Q_new ); + move16(); pit_Q_enc_ivas_fx( hBstr, 0, nBits, delta, pit_flag, *limit_flag, *T0, *T0_frac, T0_min, T0_max ); } ELSE IF( EQ_16( coder_type, VOICED ) ) @@ -665,22 +641,19 @@ Word16 pit_encode_ivas_fx( /* o : Fractional /* search and encode the closed loop pitch period */ test(); - test(); IF( EQ_16( nBits, 9 ) || EQ_16( nBits, 5 ) ) { - *T0 = pitch_fr4_fx( &exc[i_subfr], xn, h1, *T0_min, *T0_max, T0_frac, pit_flag, *limit_flag, PIT_FR2_DOUBLEEXTEND_9b, PIT_FR1_DOUBLEEXTEND_9b, L_FRAME, L_SUBFR ); + *T0 = pitch_fr4_ivas_fx( &exc[i_subfr], xn, h1, *T0_min, *T0_max, T0_frac, pit_flag, *limit_flag, PIT_FR2_DOUBLEEXTEND_9b, PIT_FR1_DOUBLEEXTEND_9b, L_FRAME, L_SUBFR, Q_new ); move16(); } ELSE IF( EQ_16( nBits, 10 ) ) { - *T0 = pitch_fr4_fx( &exc[i_subfr], xn, h1, *T0_min, *T0_max, T0_frac, pit_flag, *limit_flag, PIT_MAX, PIT_MAX, L_FRAME, L_SUBFR ); + *T0 = pitch_fr4_ivas_fx( &exc[i_subfr], xn, h1, *T0_min, *T0_max, T0_frac, pit_flag, *limit_flag, PIT_MAX, PIT_MAX, L_FRAME, L_SUBFR, Q_new ); move16(); } pit_Q_enc_ivas_fx( hBstr, 0, nBits, delta, pit_flag, *limit_flag, *T0, *T0_frac, T0_min, T0_max ); } -#if 1 - //#ifdef ADD_LRTD ELSE IF( EQ_16( tdm_Pitch_reuse_flag, 1 ) || EQ_16( nBits, 4 ) ) { /*-------------------------------------------------------* @@ -715,7 +688,8 @@ Word16 pit_encode_ivas_fx( /* o : Fractional IF( nBits > 0 ) { /* search and encode the closed loop pitch period */ - *T0 = pitch_fr4_fx( &exc[i_subfr], xn, h1, *T0_min, *T0_max, T0_frac, pit_flag, *limit_flag, PIT_MIN, PIT_FR1_8b, L_FRAME, L_SUBFR ); + *T0 = pitch_fr4_ivas_fx( &exc[i_subfr], xn, h1, *T0_min, *T0_max, T0_frac, pit_flag, *limit_flag, PIT_MIN, PIT_FR1_8b, L_FRAME, L_SUBFR, Q_new ); + move16(); IF( EQ_16( delta, 8 ) ) { *T0_frac = 0; @@ -731,7 +705,6 @@ Word16 pit_encode_ivas_fx( /* o : Fractional move16(); } } -#endif ELSE { /*-------------------------------------------------------* @@ -761,27 +734,31 @@ Word16 pit_encode_ivas_fx( /* o : Fractional { IF( *limit_flag == 0 ) { - *T0 = pitch_fr4_fx( &exc[i_subfr], xn, h1, *T0_min, *T0_max, T0_frac, pit_flag, *limit_flag, PIT_MIN, PIT_FR1_8b, L_FRAME, L_SUBFR ); + *T0 = pitch_fr4_ivas_fx( &exc[i_subfr], xn, h1, *T0_min, *T0_max, T0_frac, pit_flag, *limit_flag, PIT_MIN, PIT_FR1_8b, L_FRAME, L_SUBFR, Q_new ); + move16(); } ELSE { - *T0 = pitch_fr4_fx( &exc[i_subfr], xn, h1, *T0_min, *T0_max, T0_frac, pit_flag, *limit_flag, PIT_MIN_EXTEND, PIT_FR1_EXTEND_8b, L_FRAME, L_SUBFR ); + *T0 = pitch_fr4_ivas_fx( &exc[i_subfr], xn, h1, *T0_min, *T0_max, T0_frac, pit_flag, *limit_flag, PIT_MIN_EXTEND, PIT_FR1_EXTEND_8b, L_FRAME, L_SUBFR, Q_new ); + move16(); } } ELSE IF( EQ_16( nBits, 9 ) || EQ_16( nBits, 6 ) ) { IF( *limit_flag == 0 ) { - *T0 = pitch_fr4_fx( &exc[i_subfr], xn, h1, *T0_min, *T0_max, T0_frac, pit_flag, *limit_flag, PIT_FR2_9b, PIT_FR1_9b, L_FRAME, L_SUBFR ); + *T0 = pitch_fr4_ivas_fx( &exc[i_subfr], xn, h1, *T0_min, *T0_max, T0_frac, pit_flag, *limit_flag, PIT_FR2_9b, PIT_FR1_9b, L_FRAME, L_SUBFR, Q_new ); + move16(); } ELSE { - *T0 = pitch_fr4_fx( &exc[i_subfr], xn, h1, *T0_min, *T0_max, T0_frac, pit_flag, *limit_flag, PIT_FR2_EXTEND_9b, PIT_FR1_EXTEND_9b, L_FRAME, L_SUBFR ); + *T0 = pitch_fr4_ivas_fx( &exc[i_subfr], xn, h1, *T0_min, *T0_max, T0_frac, pit_flag, *limit_flag, PIT_FR2_EXTEND_9b, PIT_FR1_EXTEND_9b, L_FRAME, L_SUBFR, Q_new ); + move16(); } } ELSE IF( EQ_16( nBits, 10 ) ) { - *T0 = pitch_fr4_fx( &exc[i_subfr], xn, h1, *T0_min, *T0_max, T0_frac, pit_flag, *limit_flag, PIT_MAX, PIT_MAX, L_FRAME, L_SUBFR ); + *T0 = pitch_fr4_ivas_fx( &exc[i_subfr], xn, h1, *T0_min, *T0_max, T0_frac, pit_flag, *limit_flag, PIT_MAX, PIT_MAX, L_FRAME, L_SUBFR, Q_new ); } pit_Q_enc_ivas_fx( hBstr, 0, nBits, delta, pit_flag, *limit_flag, *T0, *T0_frac, T0_min, T0_max ); @@ -791,11 +768,13 @@ Word16 pit_encode_ivas_fx( /* o : Fractional test(); IF( EQ_16( nBits, 9 ) || EQ_16( nBits, 6 ) ) { - *T0 = pitch_fr4_fx( &exc[i_subfr], xn, h1, *T0_min, *T0_max, T0_frac, pit_flag, *limit_flag, PIT16k_FR2_EXTEND_9b, PIT16k_FR1_EXTEND_9b, L_FRAME16k, L_SUBFR ); + *T0 = pitch_fr4_ivas_fx( &exc[i_subfr], xn, h1, *T0_min, *T0_max, T0_frac, pit_flag, *limit_flag, PIT16k_FR2_EXTEND_9b, PIT16k_FR1_EXTEND_9b, L_FRAME16k, L_SUBFR, Q_new ); + move16(); } - ELSE IF( nBits == 10 ) + ELSE IF( EQ_16( nBits, 10 ) ) { - *T0 = pitch_fr4_fx( &exc[i_subfr], xn, h1, *T0_min, *T0_max, T0_frac, pit_flag, *limit_flag, PIT16k_FR2_EXTEND_10b, PIT16k_MAX, L_FRAME16k, L_SUBFR ); + *T0 = pitch_fr4_ivas_fx( &exc[i_subfr], xn, h1, *T0_min, *T0_max, T0_frac, pit_flag, *limit_flag, PIT16k_FR2_EXTEND_10b, PIT16k_MAX, L_FRAME16k, L_SUBFR, Q_new ); + move16(); } pit16k_Q_enc_ivas_fx( hBstr, nBits, *limit_flag, *T0, *T0_frac, T0_min, T0_max ); @@ -835,7 +814,8 @@ Word16 pit_encode_ivas_fx( /* o : Fractional } /* search and encode the closed loop pitch period */ - *T0 = pitch_fr4_fx( &exc[i_subfr], xn, h1, *T0_min, *T0_max, T0_frac, pit_flag, *limit_flag, PIT_MIN, PIT_FR1_8b, L_FRAME, L_SUBFR ); + *T0 = pitch_fr4_ivas_fx( &exc[i_subfr], xn, h1, *T0_min, *T0_max, T0_frac, pit_flag, *limit_flag, PIT_MIN, PIT_FR1_8b, L_FRAME, L_SUBFR, Q_new ); + move16(); } ELSE IF( EQ_32( core_brate, ACELP_8k85 ) ) { @@ -857,7 +837,8 @@ Word16 pit_encode_ivas_fx( /* o : Fractional } /* search and encode the closed loop pitch period */ - *T0 = pitch_fr4_fx( &exc[i_subfr], xn, h1, *T0_min, *T0_max, T0_frac, pit_flag, *limit_flag, PIT_MIN, PIT_FR1_8b, L_FRAME, L_SUBFR ); + *T0 = pitch_fr4_ivas_fx( &exc[i_subfr], xn, h1, *T0_min, *T0_max, T0_frac, pit_flag, *limit_flag, PIT_MIN, PIT_FR1_8b, L_FRAME, L_SUBFR, Q_new ); + move16(); } ELSE { @@ -883,7 +864,8 @@ Word16 pit_encode_ivas_fx( /* o : Fractional } /* search and encode the closed loop pitch period */ - *T0 = pitch_fr4_fx( &exc[i_subfr], xn, h1, *T0_min, *T0_max, T0_frac, pit_flag, *limit_flag, PIT_FR2_9b, PIT_FR1_9b, L_FRAME, L_SUBFR ); + *T0 = pitch_fr4_ivas_fx( &exc[i_subfr], xn, h1, *T0_min, *T0_max, T0_frac, pit_flag, *limit_flag, PIT_FR2_9b, PIT_FR1_9b, L_FRAME, L_SUBFR, Q_new ); + move16(); } pit_Q_enc_ivas_fx( hBstr, 1, nBits, delta, pit_flag, *limit_flag, *T0, *T0_frac, T0_min, T0_max ); @@ -1105,6 +1087,7 @@ Word16 delta_pit_enc_fx( /* o : pitch index ) { Word16 pitch_index = 0; + move16(); IF( fr_steps == 0 ) { @@ -1129,6 +1112,197 @@ Word16 delta_pit_enc_fx( /* o : pitch index * * Find the closed loop pitch period with 1/4 subsample resolution. *-------------------------------------------------------------------*/ +Word16 pitch_fr4_ivas_fx( /* o : chosen integer pitch lag */ + const Word16 exc[], /* i : excitation buffer Q_new */ + const Word16 xn[], /* i : target signal Q_new-1 */ + const Word16 h[], /* i : weighted synthesis filter impulse response Q(14 - norm_s[h[0]) */ + const Word16 t0_min, /* i : minimum value in the searched range. Q0 */ + const Word16 t0_max, /* i : maximum value in the searched range. Q0 */ + Word16 *pit_frac, /* o : chosen fraction (0, 1, 2 or 3) */ + const Word16 i_subfr, /* i : flag to first subframe */ + const Word16 limit_flag, /* i : flag for limits (0=restrained, 1=extended) */ + const Word16 t0_fr2, /* i : minimum value for resolution 1/2 */ + const Word16 t0_fr1, /* i : minimum value for resolution 1 */ + const Word16 L_frame, /* i : length of the frame */ + const Word16 L_subfr, /* i : size of subframe */ + Word16 Q_new /* i */ +) +{ + Word16 i; + Word16 t_min, t_max; + Word16 max_val, t0, t1, fraction, step, temp; + Word16 *corr; + Word16 corr_v[15 + 2 * L_INTERPOL1 + 1]; /* Total length = t0_max-t0_min+1+2*L_inter */ + Word16 pit_min; + Word16 cor_max; + + /* initialization */ + IF( limit_flag == 0 ) + { + IF( EQ_16( L_frame, L_FRAME ) ) + { + pit_min = PIT_MIN; + move16(); + } + ELSE /* L_frame == L_FRAME16k */ + { + pit_min = PIT16k_MIN; + move16(); + } + } + ELSE + { + IF( EQ_16( L_frame, L_FRAME ) ) + { + pit_min = PIT_MIN_EXTEND; + move16(); + IF( EQ_16( limit_flag, 2 ) ) + { + pit_min = PIT_MIN_DOUBLEEXTEND; + move16(); + } + } + ELSE /* L_frame == L_FRAME16k */ + { + pit_min = PIT16k_MIN_EXTEND; + move16(); + } + } + + /*-----------------------------------------------------------------* + * - Find interval to compute normalized correlation + * - allocate memory to normalized correlation vector + * - Compute normalized correlation between target and filtered + * excitation + *-----------------------------------------------------------------*/ + + t_min = sub( t0_min, L_INTERPOL1 ); + t_max = add( t0_max, L_INTERPOL1 ); + corr = &corr_v[-t_min]; + move16(); + move16(); /* corr[t_min..t_max] */ + + norm_corr_ivas_fx( exc, xn, h, t_min, t_max, corr, L_subfr, Q_new ); + + /*-----------------------------------------------------------------* + * Find integer pitch + *-----------------------------------------------------------------*/ + + max_val = corr[t0_min]; + move16(); + t0 = t0_min; + move16(); + + FOR( i = add( t0_min, 1 ); i <= t0_max; i++ ) + { + if ( GE_16( corr[i], max_val ) ) + { + t0 = i; + move16(); + } + max_val = s_max( corr[i], max_val ); + } + + IF( EQ_16( t0_fr1, pit_min ) ) + { + /* don't search fraction (for 7b/4b quant) */ + test(); + IF( ( i_subfr == 0 ) && ( GE_16( t0, t0_fr2 ) ) ) + { + i = shl( shr( t0, 1 ), 1 ); /* 2 samples resolution */ + if ( GT_16( add( i, 2 ), PIT_MAX ) ) + { + i = sub( i, 2 ); + } + IF( GT_16( corr[i], corr[i + 2] ) ) + { + t0 = i; + move16(); + } + ELSE + { + t0 = add( i, 2 ); + } + } + *pit_frac = 0; + move16(); + + return ( t0 ); + } + + test(); + IF( ( i_subfr == 0 ) && ( GE_16( t0, t0_fr1 ) ) ) + { + *pit_frac = 0; + move16(); + + return ( t0 ); + } + + /*------------------------------------------------------------------* + * Search fractionnal pitch with 1/4 subsample resolution. + * search the fractions around t0 and choose the one which maximizes + * the interpolated normalized correlation. + *-----------------------------------------------------------------*/ + + t1 = t0; + move16(); + step = 1; + move16(); /* 1/4 subsample resolution */ + fraction = 1; + move16(); + test(); + test(); + IF( ( ( i_subfr == 0 ) && ( GE_16( t0, t0_fr2 ) ) ) || ( EQ_16( t0_fr2, pit_min ) ) ) + { + step = 2; + move16(); /* 1/2 subsample resolution */ + fraction = 2; + move16(); + } + + IF( EQ_16( t0, t0_min ) ) /* Limit case */ + { + fraction = 0; + move16(); + cor_max = Interpol_4( &corr[t0], fraction ); + } + ELSE + { + t0 = sub( t0, 1 ); + cor_max = Interpol_4( &corr[t0], fraction ); + FOR( i = add( fraction, step ); i <= 3; i = (Word16) ( i + step ) ) + { + temp = Interpol_4( &corr[t0], i ); + IF( GT_16( temp, cor_max ) ) + { + cor_max = temp; + move16(); + fraction = i; + move16(); + } + } + } + + FOR( i = 0; i <= 3; i = (Word16) ( i + step ) ) + { + temp = Interpol_4( &corr[t1], i ); + IF( GT_16( temp, cor_max ) ) + { + cor_max = temp; + move16(); + fraction = i; + move16(); + t0 = t1; + move16(); + } + } + + *pit_frac = fraction; + move16(); + + return ( t0 ); +} Word16 pitch_fr4_fx( /* o : chosen integer pitch lag */ const Word16 exc[], /* i : excitation buffer Q_new*/ @@ -1196,8 +1370,7 @@ Word16 pitch_fr4_fx( /* o : chosen integer pitch lag t_min = sub( t0_min, L_INTERPOL1 ); t_max = add( t0_max, L_INTERPOL1 ); corr = &corr_v[-t_min]; - move16(); - move16(); /* corr[t_min..t_max] */ + /* corr[t_min..t_max] */ norm_corr_fx( exc, xn, h, t_min, t_max, corr, L_subfr ); @@ -1210,9 +1383,9 @@ Word16 pitch_fr4_fx( /* o : chosen integer pitch lag t0 = t0_min; move16(); - FOR( i = add( t0_min, 1 ); i <= t0_max; i++ ) + FOR( i = t0_min + 1; i <= t0_max; i++ ) { - if ( corr[i] >= max_val ) + if ( GE_16( corr[i], max_val ) ) { t0 = i; move16(); @@ -1227,7 +1400,7 @@ Word16 pitch_fr4_fx( /* o : chosen integer pitch lag IF( ( i_subfr == 0 ) && ( GE_16( t0, t0_fr2 ) ) ) { i = shl( shr( t0, 1 ), 1 ); /* 2 samples resolution */ - if ( GT_16( add( i, 2 ), PIT_MAX ) ) + IF( GT_16( add( i, 2 ), PIT_MAX ) ) { i = sub( i, 2 ); } @@ -1288,7 +1461,7 @@ Word16 pitch_fr4_fx( /* o : chosen integer pitch lag { t0 = sub( t0, 1 ); cor_max = Interpol_4( &corr[t0], fraction ); - FOR( i = add( fraction, step ); i <= 3; i = (Word16) ( i + step ) ) + FOR( i = fraction + step; i <= 3; i = ( i + step ) ) { temp = Interpol_4( &corr[t0], i ); IF( GT_16( temp, cor_max ) ) @@ -1301,7 +1474,7 @@ Word16 pitch_fr4_fx( /* o : chosen integer pitch lag } } - FOR( i = 0; i <= 3; i = (Word16) ( i + step ) ) + FOR( i = 0; i <= 3; i = ( i + step ) ) { temp = Interpol_4( &corr[t1], i ); IF( GT_16( temp, cor_max ) ) @@ -1329,6 +1502,104 @@ Word16 pitch_fr4_fx( /* o : chosen integer pitch lag * excitation divided by the square root of energy of filtered * excitation) *---------------------------------------------------------------------*/ +void norm_corr_ivas_fx( + const Word16 exc[], /* i : excitation buffer Q_new */ + const Word16 xn[], /* i : target signal Q_new-1 */ + const Word16 h[], /* i : weighted synthesis filter impulse response Q(14 - norm_s(h[0])) */ + const Word16 t_min, /* i : minimum value of searched range */ + const Word16 t_max, /* i : maximum value of searched range */ + Word16 ncorr[], /* o : normalized correlation */ + const Word16 L_subfr, /* i : subframe size */ + Word16 Q_new /* i */ +) +{ + Word16 i, k, t; + Word16 corr, exp_corr, norm, exp_norm, exp; + Word16 excf[L_FRAME16k]; + Word16 ncorr_e[15 + 2 * L_INTERPOL1 + 1]; + Word16 h_e, e_max; + Word32 L_tmp; + Word64 W_tmp; +#ifdef BASOP_NOGLOB_DECLARE_LOCAL + Flag Overflow = 0; + move16(); +#endif + + k = negate( t_min ); + h_e = add( 1, norm_s( h[0] ) ); // exponent of h + /*-----------------------------------------------------------------* + * compute the filtered excitation for the first delay t_min + *-----------------------------------------------------------------*/ + + conv_fx( &exc[k], h, excf, L_subfr ); // Q_new - h_e + + /*----------------------------------------------------------------* + * loop for every possible period + *----------------------------------------------------------------*/ + + FOR( t = t_min; t <= t_max; t++ ) + { + /* Compute correlation between xn[] and excf[] */ + + L_tmp = L_mac( 0, xn[0], excf[0] ); + FOR( i = 1; i < L_subfr; i++ ) + { + L_tmp = L_mac_o( L_tmp, xn[i], excf[i], &Overflow ); // (Q_new - 1) + (Q_new - h_e) + 1 + } + exp = norm_l( L_tmp ); + L_tmp = L_shl( L_tmp, exp ); + exp_corr = sub( 31, add( exp, ( Q_new - 1 ) + ( Q_new - h_e ) + 1 ) ); + corr = extract_h( L_tmp ); + + /* Compute 1/sqrt(energy of excf[]) */ + Word16 _0_01 = extract_l( L_shr( 21474836 /* 0.01 in Q31 */, sub( 31, add( shl( sub( Q_new, h_e ), 1 ), 1 ) ) ) ); + + W_tmp = W_mac_16_16( _0_01, excf[0], excf[0] ); + FOR( i = 1; i < L_subfr; i++ ) + { + W_tmp = W_mac_16_16( W_tmp, excf[i], excf[i] ); // 2*(Q_new - h_e) + 1 + } + + exp = W_norm( W_tmp ); + L_tmp = W_extract_h( W_shl( W_tmp, exp ) ); // 2*(Q_new - h_e) + 1 + exp - 32 + exp_norm = sub( 31 + 32, add( add( shl( sub( Q_new, h_e ), 1 ), 1 ), exp ) ); + + L_tmp = Isqrt_lc( L_tmp, &exp_norm ); + norm = extract_h( L_tmp ); + + /* Normalize correlation = correlation * (1/sqrt(energy)) */ + L_tmp = L_mult( corr, norm ); + + ncorr[t] = round_fx_sat( L_tmp ); + ncorr_e[t - t_min] = add( exp_corr, exp_norm ); + move16(); + move16(); + + /* update the filtered excitation excf[] for the next iteration */ + IF( NE_16( t, t_max ) ) + { + k--; + FOR( i = (Word16) ( L_subfr - 1 ); i > 0; i-- ) + { + /* saturation can occur in add() */ + excf[i] = round_fx_sat( L_mac_sat( L_mult( excf[i - 1], 32767 ), exc[k], h[i] ) ); + move16(); + } + excf[0] = mult_r( exc[k], h[0] ); + move16(); + } + } + // Aligning the values of ncorr to a common exponent + maximum_fx( ncorr_e, t_max + 1 - t_min, &e_max ); + FOR( t = t_min; t <= t_max; t++ ) + { + ncorr[t] = shr( ncorr[t], sub( e_max, ncorr_e[t - t_min] ) ); + move16(); + } + + return; +} + void norm_corr_fx( const Word16 exc[], /* i : excitation buffer Q_new*/ @@ -1346,6 +1617,7 @@ void norm_corr_fx( Word32 L_tmp; #ifdef BASOP_NOGLOB_DECLARE_LOCAL Flag Overflow = 0; + move32(); #endif k = negate( t_min ); @@ -1357,18 +1629,10 @@ void norm_corr_fx( conv_fx( &exc[k], h, excf, L_subfr ); /* Compute rounded down 1/sqrt(energy of xn[]) */ -#ifdef BASOP_NOGLOB L_tmp = L_mac_o( 1, xn[0], xn[0], &Overflow ); -#else - L_tmp = L_mac( 1, xn[0], xn[0] ); -#endif FOR( i = 1; i < L_subfr; i++ ) { -#ifdef BASOP_NOGLOB L_tmp = L_mac_o( L_tmp, xn[i], xn[i], &Overflow ); -#else /* BASOP_NOGLOB */ - L_tmp = L_mac( L_tmp, xn[i], xn[i] ); -#endif } exp = norm_l( L_tmp ); exp = sub( 30, exp ); @@ -1387,11 +1651,7 @@ void norm_corr_fx( L_tmp = L_mac( 1, xn[0], excf[0] ); FOR( i = 1; i < L_subfr; i++ ) { -#ifdef BASOP_NOGLOB L_tmp = L_mac_o( L_tmp, xn[i], excf[i], &Overflow ); -#else - L_tmp = L_mac( L_tmp, xn[i], excf[i] ); -#endif } exp = norm_l( L_tmp ); L_tmp = L_shl( L_tmp, exp ); @@ -1402,11 +1662,7 @@ void norm_corr_fx( L_tmp = L_mac( 1, excf[0], excf[0] ); FOR( i = 1; i < L_subfr; i++ ) { -#ifdef BASOP_NOGLOB L_tmp = L_mac_o( L_tmp, excf[i], excf[i], &Overflow ); -#else - L_tmp = L_mac( L_tmp, excf[i], excf[i] ); -#endif } exp = norm_l( L_tmp ); @@ -1418,27 +1674,19 @@ void norm_corr_fx( /* Normalize correlation = correlation * (1/sqrt(energy)) */ L_tmp = L_mult( corr, norm ); -#ifdef BASOP_NOGLOB L_tmp = L_shl_sat( L_tmp, add( add( exp_corr, exp_norm ), scale ) ); ncorr[t] = round_fx_sat( L_tmp ); -#else - L_tmp = L_shl( L_tmp, add( add( exp_corr, exp_norm ), scale ) ); - ncorr[t] = round_fx( L_tmp ); -#endif /* update the filtered excitation excf[] for the next iteration */ IF( NE_16( t, t_max ) ) { k--; - FOR( i = (Word16) ( L_subfr - 1 ); i > 0; i-- ) + FOR( i = ( L_subfr - 1 ); i > 0; i-- ) { /* saturation can occur in add() */ /*excf[i] = add(mult(exc[k], h[i]), excf[i - 1]); move16(); */ -#ifdef BASOP_NOGLOB excf[i] = round_fx_sat( L_mac_sat( L_mult( excf[i - 1], 32767 ), exc[k], h[i] ) ); -#else - excf[i] = round_fx( L_mac( L_mult( excf[i - 1], 32767 ), exc[k], h[i] ) ); -#endif + move16(); } excf[0] = mult_r( exc[k], h[0] ); move16(); @@ -1899,7 +2147,7 @@ void Mode2_pit_encode_fx( { Word16 pit_res_max2 = pit_res_max; - if ( EQ_16( pit_min, PIT_MIN_16k ) ) + IF( EQ_16( pit_min, PIT_MIN_16k ) ) { pit_res_max2 = shr( pit_res_max, 1 ); } @@ -1928,7 +2176,7 @@ void Mode2_pit_encode_fx( ELSE IF( coder_type == 4 ) /* 9/6/9/6 (AMRWB) */ { Word16 pit_res_max2 = pit_res_max; - if ( EQ_16( pit_min, PIT_MIN_16k ) ) + IF( EQ_16( pit_min, PIT_MIN_16k ) ) { pit_res_max2 = shr( pit_res_max, 1 ); } @@ -1943,6 +2191,7 @@ void Mode2_pit_encode_fx( } *T0 = E_GAIN_closed_loop_search_fx( exc, xn, h1, *T0_min, *T0_min_frac, *T0_max, *T0_max_frac, pit_res_max2, T0_frac, T0_res, pit_res_max, pit_flag, pit_min, pit_fr2, pit_fr1, L_SUBFR ); + move16(); IF( pit_flag == 0 ) /* if 1st/3rd/5th subframe */ { Mode2_abs_pit_enc_fx( *T0, *T0_frac, pt_indice, pit_min, pit_fr1, pit_fr2, pit_res_max ); @@ -1964,6 +2213,7 @@ void Mode2_pit_encode_fx( } *T0 = E_GAIN_closed_loop_search_fx( exc, xn, h1, *T0_min, *T0_min_frac, *T0_max, *T0_max_frac, shr( pit_res_max, 1 ), T0_frac, T0_res, pit_res_max, i_subfr, pit_min, pit_min, pit_fr1b, L_SUBFR ); + move16(); IF( i_subfr == 0 ) { @@ -1986,6 +2236,7 @@ void Mode2_pit_encode_fx( } *T0 = E_GAIN_closed_loop_search_fx( exc, xn, h1, *T0_min, *T0_min_frac, *T0_max, *T0_max_frac, shr( pit_res_max, 1 ), T0_frac, T0_res, pit_res_max, i_subfr, pit_min, pit_min, pit_fr1b, L_SUBFR ); + move16(); IF( i_subfr == 0 ) { @@ -2046,6 +2297,7 @@ static void limit_T0_voiced2( if ( LT_16( temp1, t ) ) { temp1 = t; + move16(); } temp2 = mult( temp1, inv_T0_res[res2] ); @@ -2092,16 +2344,19 @@ static void limit_T0_voiced2( move16(); *T0_max_frac = sub( temp1, i_mult2( temp2, res ) ); + move16(); IF( GT_16( *T0_max, pit_max ) ) { *T0_max = pit_max; *T0_max_frac = sub( res, 1 ); + move16(); + move16(); temp1 = add( sub( i_mult2( *T0_max, res ), 64 ), res ); temp2 = mult( temp1, inv_T0_res[res2] ); - if ( EQ_16( res, 6 ) ) + IF( EQ_16( res, 6 ) ) { temp2 = shr( temp2, 1 ); } @@ -2137,14 +2392,17 @@ void Mode2_abs_pit_enc_fx( IF( LT_16( T0, pit_fr2 ) ) { **pt_indice = add( i_mult2( T0, pit_res_max ), sub( T0_frac, i_mult2( pit_min, pit_res_max ) ) ); + move16(); } ELSE IF( LT_16( T0, pit_fr1 ) ) { **pt_indice = add( sub( add( i_mult2( T0, pit_res_max_half ), T0_frac ), i_mult2( pit_fr2, pit_res_max_half ) ), i_mult2( sub( pit_fr2, pit_min ), pit_res_max ) ); + move16(); } ELSE { **pt_indice = add( add( sub( T0, pit_fr1 ), i_mult2( sub( pit_fr2, pit_min ), pit_res_max ) ), i_mult2( sub( pit_fr1, pit_fr2 ), pit_res_max_half ) ); + move16(); } ( *pt_indice )++; diff --git a/lib_enc/pitch_ol.c b/lib_enc/pitch_ol.c deleted file mode 100644 index 65b32d74cc46708b40b2e978ee4d324fd9429a20..0000000000000000000000000000000000000000 --- a/lib_enc/pitch_ol.c +++ /dev/null @@ -1,48 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include -#include "prot.h" -#include "cnst.h" -#include "rom_com.h" -#include "rom_enc.h" -#include "wmc_auto.h" - -/*---------------------------------------------------------------------* - * Local constants - *---------------------------------------------------------------------*/ diff --git a/lib_enc/pitch_ol2.c b/lib_enc/pitch_ol2.c deleted file mode 100644 index 4e4277eef53dad8cbbdae27ed9fcd105103e7fb3..0000000000000000000000000000000000000000 --- a/lib_enc/pitch_ol2.c +++ /dev/null @@ -1,301 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include "cnst.h" -#include "rom_enc.h" -#include "prot.h" -#include "wmc_auto.h" - -#include "prot_fx.h" /* Function prototypes */ -#include "prot_fx_enc.h" /* Function prototypes */ - -/*-------------------------------------------------------------------* - * Local constants - *-------------------------------------------------------------------*/ - -#define MAX_DELTA 16 /* half-length of the delta search */ -#define COR_BUF_LEN ( L_INTERPOL1 * 2 + MAX_DELTA * 2 + 1 ) -/*-------------------------------------------------------------------* - * pitch_ol2() - * - * Open-loop pitch precision improvement with 1/4 resolution - * The pitch is searched in the interval 0 ) - { - ratio = 0; - move16(); - } - ELSE - { - ratio = s_max( sub( energy1_16, energy0_16 ), 0 ); /*Q7 */ - } - /*ratio *= max(voicing,0);*/ - tmp = s_max( voicing_m, 0 ); - ratio = mult_r( ratio, tmp ); /*Q7*/ - /**LF_EnergyRatio_sm = (15*(*LF_EnergyRatio_sm) + ratio)/16;*/ - L_tmp = L_mult( ratio, 2048 ); - L_tmp = L_mac( L_tmp, *LF_EnergyRatio_sm, 30720 ); - *LF_EnergyRatio_sm = round_fx( L_tmp ); - move16(); - test(); - if ( GT_16( *LF_EnergyRatio_sm, 4480 ) || GT_16( ratio, 6400 ) ) - { - *predecision_flag = 1; - move16(); - } - - if ( LT_16( *LF_EnergyRatio_sm, 2048 ) ) - { - *predecision_flag = 0; - move16(); - } - - /* short pitch candidate detection */ - Tp = pitch[1]; - move16(); - cor_max = 0; - move16(); - pt_wsp = wsp + 3 * L_SUBFR; - pit_min = PIT_MIN_DOUBLEEXTEND; - move16(); - pit_min_up = PIT_MIN; - move16(); - FOR( T = pit_min; T <= pit_min_up; T++ ) - { - energy1 = Dot_product( pt_wsp, pt_wsp - T, L_SUBFR ); - test(); - IF( ( GT_32( energy1, cor_max ) ) || ( EQ_16( T, pit_min ) ) ) - { - cor_max = L_add( energy1, 0 ); - Tp = T; - move16(); - } - } - energy0 = Dot_product12( pt_wsp, pt_wsp, L_SUBFR, &exp1 ); - exp1 = sub( exp1, shl( Q_new, 1 ) ); - energy1 = Dot_product12( pt_wsp - Tp, pt_wsp - Tp, L_SUBFR, &exp2 ); - exp2 = sub( exp2, shl( Q_new, 1 ) ); - /* cor_max *= inv_sqrt( energy0*energy1 );*/ - L_tmp = Mult_32_32( energy0, energy1 ); - exp = norm_l( L_tmp ); - L_tmp1 = L_shl( L_tmp, exp ); - - exp = sub( sub( 31, exp ), ( sub( sub( 31, exp1 ), exp2 ) ) ); - move16(); - L_tmp1 = Isqrt_lc( L_tmp1, &exp ); /*Q(31-exp)*/ - cor_max = Mult_32_32( cor_max, L_tmp1 ); - exp = add( sub( sub( 31, add( shl( Q_new, 1 ), 1 ) ), sub( 31, exp ) ), 31 ); -#ifdef BASOP_NOGLOB - cor_max16 = round_fx_o( L_shl_o( cor_max, exp, &Overflow ), &Overflow ); /*Q15*/ -#else /* BASOP_NOGLOB */ - cor_max16 = round_fx( L_shl( cor_max, exp ) ); /*Q15*/ -#endif - /**voicing0_sm = add(mult_r(24576 ,(*voicing0_sm)) , mult_r(8192 , cor_max16));*/ - *voicing0_sm = round_fx( L_mac( L_mult( 24576, *voicing0_sm ), 8192, cor_max16 ) ); - move16(); - - /* final short pitch detection */ - test(); - test(); - test(); - *flag_spitch = 0; - move16(); - IF( ( EQ_16( localVAD, 1 ) ) && ( EQ_16( *predecision_flag, 1 ) ) && - ( GT_16( *voicing0_sm, 16384 ) ) && ( GT_16( *voicing0_sm, mult_r( *voicing_sm, 21299 ) ) ) ) - { - *flag_spitch = 1; - move16(); - pitch[0] = Tp; - move16(); - pitch[1] = Tp; - move16(); - pitch[2] = Tp; - move16(); - } - - return; -} diff --git a/lib_enc/pitch_ol2_fx.c b/lib_enc/pitch_ol2_fx.c index bd66fda139e28f53c4564560776f148ba8d5e4d2..7ca13171ea309caea5710891b929962bcc6914b9 100644 --- a/lib_enc/pitch_ol2_fx.c +++ b/lib_enc/pitch_ol2_fx.c @@ -51,6 +51,7 @@ void pitch_ol2_fx( Word16 pit_max; #ifdef BASOP_NOGLOB_DECLARE_LOCAL Flag Overflow = 0; + move32(); #endif /* initialization */ @@ -80,13 +81,9 @@ void pitch_ol2_fx( pt_cor_fx = cor_fx; FOR( t = t_min; t <= t_max; t++ ) { -#ifdef BASOP_NOGLOB t0 = L_shl_o( *pt_cor_32++, exp3, &Overflow ); *pt_cor_fx++ = round_fx_o( t0, &Overflow ); -#else - t0 = L_shl( *pt_cor_32++, exp3 ); - *pt_cor_fx++ = round_fx( t0 ); -#endif + move16(); } pt_cor_fx = cor_fx + L_INTERPOL1; @@ -94,7 +91,7 @@ void pitch_ol2_fx( move16(); t1s = t0_min; move16(); - FOR( t = add( t0_min, 1 ); t <= t0_max; t++ ) + FOR( t = t0_min + 1; t <= t0_max; t++ ) { if ( GT_16( *pt_cor_fx, cor_max_fx ) ) { @@ -123,8 +120,7 @@ void pitch_ol2_fx( { t0s = sub( t0s, 1 ); cor_max_fx = Interpol_4( &pt_cor_fx[t0s], fraction ); - move16(); - FOR( i = add( fraction, step ); i <= 3; i += step ) + FOR( i = fraction + step; i <= 3; i += step ) { temp_fx = Interpol_4( &pt_cor_fx[t0s], i ); if ( GT_16( temp_fx, cor_max_fx ) ) @@ -145,7 +141,6 @@ void pitch_ol2_fx( FOR( i = 0; i <= 3; i += step ) /* Process positive fractions */ { temp_fx = Interpol_4( &pt_cor_fx[t1s], i ); - move16(); IF( GT_16( temp_fx, cor_max_fx ) ) { @@ -171,13 +166,8 @@ void pitch_ol2_fx( R2 = L_mult( wsp_fr_fx[0], wsp_fr_fx[0] ); FOR( j = 1; j < L_SUBFR; j++ ) { -#ifdef BASOP_NOGLOB R1 = L_mac_sat( R1, pt_wsp_fx[j], pt_wsp_fx[j] ); R2 = L_mac_sat( R2, wsp_fr_fx[j], wsp_fr_fx[j] ); -#else - R1 = L_mac( R1, pt_wsp_fx[j], pt_wsp_fx[j] ); - R2 = L_mac( R2, wsp_fr_fx[j], wsp_fr_fx[j] ); -#endif } /* *voicing_fr = cor_max * inv_sqrt(enr_wsp * enr_old) */ @@ -191,11 +181,7 @@ void pitch_ol2_fx( exp_R2 = norm_l( R2 ); R2 = L_shl( R2, exp_R2 ); -#ifdef BASOP_NOGLOB R1 = L_mult_o( round_fx_o( R1, &Overflow ), round_fx_o( R2, &Overflow ), &Overflow ); -#else - R1 = L_mult( round_fx( R1 ), round_fx( R2 ) ); -#endif i = norm_l( R1 ); R1 = L_shl( R1, i ); @@ -205,19 +191,12 @@ void pitch_ol2_fx( R1 = Isqrt_lc( R1, &exp_R1 ); -#ifdef BASOP_NOGLOB R1 = L_mult( R0, round_fx_o( R1, &Overflow ) ); -#else - R1 = L_mult( R0, round_fx( R1 ) ); -#endif exp_R0 = sub( 31, exp_R0 ); exp_R0 = sub( add( exp_R0, exp_R1 ), exp3 ); -#ifdef BASOP_NOGLOB *voicing_fr_fx = round_fx_o( L_shl_o( R1, exp_R0, &Overflow ), &Overflow ); /*Q15*/ -#else /* BASOP_NOGLOB */ - *voicing_fr_fx = round_fx( L_shl( R1, exp_R0 ) ); /*Q15*/ -#endif /* BASOP_NOGLOB */ + move16(); } ELSE { @@ -258,22 +237,20 @@ void StableHighPitchDetect_fx( Word16 Top; #ifdef BASOP_NOGLOB_DECLARE_LOCAL Flag Overflow = 0; + move32(); #endif /*voicing = (voicing[0] + voicing[1] + voicing[2] )/3;*/ - L_tmp = L_mult( voicing[0], 10923 ); - L_tmp = L_mac( L_tmp, voicing[1], 10923 ); - L_tmp = L_mac( L_tmp, voicing[2], 10923 ); -#ifdef BASOP_NOGLOB + L_tmp = L_mult( voicing[0], 10923 /*1/3 in Q15*/ ); + L_tmp = L_mac( L_tmp, voicing[1], 10923 /*1/3 in Q15*/ ); + L_tmp = L_mac( L_tmp, voicing[2], 10923 /*1/3 in Q15*/ ); voicing_m = round_fx_sat( L_tmp ); -#else - voicing_m = round_fx( L_tmp ); -#endif /**voicing_sm = 0.75f*(*voicing_sm) + 0.25f*voicing;*/ - *voicing_sm = round_fx( L_mac( L_mult( *voicing_sm, 24576 ), voicing_m, 8192 ) ); - + *voicing_sm = round_fx( L_mac( L_mult( *voicing_sm, 24576 /*0.75f Q15*/ ), voicing_m, 8192 /*0.25f Q15*/ ) ); + move16(); /* pitch_freq_point = (short)(L_FFT/(mult_fact*T_op[1])+0.5f);*/ Top = pitch[1]; + move16(); exp = norm_s( Top ); tmp = div_s( shl( 1, sub( 14, exp ) ), Top ); /*Q(29 - exp)*/ L_tmp = L_mult0( tmp, L_FFT ); /*Q(29 - exp)*/ @@ -309,53 +286,33 @@ void StableHighPitchDetect_fx( tmp = abs_s( tmp ); tmp = div_s( 16384, tmp ); /*Q(15+exp)*/ BASOP_SATURATE_WARNING_OFF_EVS -#ifdef BASOP_NOGLOB diff = L_negate( L_shr_o( Mult_32_16( diff, tmp ), sub( exp + 7, 31 ), &Overflow ) ); -#else /* BASOP_NOGLOB */ - diff = L_negate( L_shr( Mult_32_16( diff, tmp ), sub( exp + 7, 31 ) ) ); -#endif /* BASOP_NOGLOB */ BASOP_SATURATE_WARNING_ON_EVS -#ifdef BASOP_NOGLOB diff16 = round_fx_o( diff, &Overflow ); -#else /* BASOP_NOGLOB */ - diff16 = round_fx( diff ); -#endif /* BASOP_NOGLOB */ } ELSE { tmp = div_s( 16384, tmp ); /*Q(15+exp)*/ BASOP_SATURATE_WARNING_OFF_EVS -#ifdef BASOP_NOGLOB diff = L_shr_o( Mult_32_16( diff, tmp ), sub( exp + 7, 31 ), &Overflow ); -#else /* BASOP_NOGLOB */ - diff = L_shr( Mult_32_16( diff, tmp ), sub( exp + 7, 31 ) ); -#endif /* BASOP_NOGLOB */ BASOP_SATURATE_WARNING_ON_EVS -#ifdef BASOP_NOGLOB diff16 = round_fx_o( diff, &Overflow ); -#else /* BASOP_NOGLOB */ - diff16 = round_fx( diff ); -#endif /* BASOP_NOGLOB */ } } ELSE { -#ifdef BASOP_NOGLOB diff16 = round_fx_o( L_shl_o( diff, 25, &Overflow ), &Overflow ); -#else - diff16 = round_fx( L_shl( diff, 25 ) ); -#endif } test(); test(); - IF( LT_32( *diff_sm, -1280 ) && LT_32( *energy_sm, 4928 ) && LT_16( diff16, -26214 ) ) + if ( LT_32( *diff_sm, -1280 /*-10.0f Q7*/ ) && LT_32( *energy_sm, 4928 /*38.5f Q7*/ ) && LT_16( diff16, -26214 /*-.8f Q15*/ ) ) { *predecision_flag = 1; move16(); } test(); test(); - if ( GT_32( *diff_sm, 1280 ) && GT_32( *energy_sm, 10624 ) && GT_16( diff16, 16384 ) ) + if ( GT_32( *diff_sm, 1280 /*10.0f Q7*/ ) && GT_32( *energy_sm, 10624 /*83.0f Q7*/ ) && GT_16( diff16, 16384 /*.5 Q15*/ ) ) { *predecision_flag = 0; move16(); @@ -372,14 +329,15 @@ void StableHighPitchDetect_fx( L_tmp = L_mult( ratio, 2048 ); L_tmp = L_mac( L_tmp, *LF_EnergyRatio_sm, 30720 ); *LF_EnergyRatio_sm = round_fx( L_tmp ); + move16(); test(); - if ( GT_16( *LF_EnergyRatio_sm, 4480 ) || GT_16( ratio, 6400 ) ) + if ( GT_16( *LF_EnergyRatio_sm, 4480 /*35.0f Q7*/ ) || GT_16( ratio, 6400 /*50.0f Q7*/ ) ) { *predecision_flag = 1; move16(); } - if ( LT_16( *LF_EnergyRatio_sm, 2048 ) ) + if ( LT_16( *LF_EnergyRatio_sm, 2048 /*16.0f Q7*/ ) ) { *predecision_flag = 0; move16(); @@ -420,13 +378,10 @@ void StableHighPitchDetect_fx( L_tmp1 = Isqrt_lc( L_tmp1, &exp ); /*Q(31-exp)*/ cor_max = Mult_32_32( cor_max, L_tmp1 ); exp = 31 - ( shl( Q_new, 1 ) + 1 ) - ( 31 - exp ) + 31; -#ifdef BASOP_NOGLOB cor_max16 = round_fx_o( L_shl_o( cor_max, exp, &Overflow ), &Overflow ); /*Q15*/ -#else /* BASOP_NOGLOB */ - cor_max16 = round_fx( L_shl( cor_max, exp ) ); /*Q15*/ -#endif /**voicing0_sm = add(mult_r(24576 ,(*voicing0_sm)) , mult_r(8192 , cor_max16));*/ - *voicing0_sm = round_fx( L_mac( L_mult( 24576, *voicing0_sm ), 8192, cor_max16 ) ); + *voicing0_sm = round_fx( L_mac( L_mult( 24576 /*.75f Q15*/, *voicing0_sm ), 8192 /*.25f Q15*/, cor_max16 ) ); + move16(); /* final short pitch detection */ test(); @@ -449,3 +404,227 @@ void StableHighPitchDetect_fx( return; } + + +/*-------------------------------------------------------------------* + * pitch_ol2() + * + * Open-loop pitch precision improvement with 1/4 resolution + * The pitch is searched in the interval 0 ) + { + ratio = 0; + move16(); + } + ELSE + { + ratio = s_max( sub( energy1_16, energy0_16 ), 0 ); /*Q7 */ + } + /*ratio *= max(voicing,0);*/ + tmp = s_max( voicing_m, 0 ); + ratio = mult_r( ratio, tmp ); /*Q7*/ + /**LF_EnergyRatio_sm = (15*(*LF_EnergyRatio_sm) + ratio)/16;*/ + L_tmp = L_mult( ratio, 2048 ); + L_tmp = L_mac( L_tmp, *LF_EnergyRatio_sm, 30720 ); + *LF_EnergyRatio_sm = round_fx( L_tmp ); + move16(); + test(); + if ( GT_16( *LF_EnergyRatio_sm, 4480 /*35.0f Q7*/ ) || GT_16( ratio, 6400 /*50.0f Q7*/ ) ) + { + *predecision_flag = 1; + move16(); + } + + if ( LT_16( *LF_EnergyRatio_sm, 2048 /*16.0f Q7*/ ) ) + { + *predecision_flag = 0; + move16(); + } + + /* short pitch candidate detection */ + Tp = pitch[1]; + move16(); + cor_max = 0; + move16(); + pt_wsp = wsp + 3 * L_SUBFR; + pit_min = PIT_MIN_DOUBLEEXTEND; + move16(); + pit_min_up = PIT_MIN; + move16(); + FOR( T = pit_min; T <= pit_min_up; T++ ) + { + energy1 = Dot_product( pt_wsp, pt_wsp - T, L_SUBFR ); + test(); + IF( ( GT_32( energy1, cor_max ) ) || ( EQ_16( T, pit_min ) ) ) + { + cor_max = L_add( energy1, 0 ); + Tp = T; + move16(); + } + } + energy0 = Dot_product12( pt_wsp, pt_wsp, L_SUBFR, &exp1 ); + exp1 = sub( exp1, shl( Q_new, 1 ) ); + energy1 = Dot_product12( pt_wsp - Tp, pt_wsp - Tp, L_SUBFR, &exp2 ); + exp2 = sub( exp2, shl( Q_new, 1 ) ); + /* cor_max *= inv_sqrt( energy0*energy1 );*/ + L_tmp = Mult_32_32( energy0, energy1 ); + exp = norm_l( L_tmp ); + L_tmp1 = L_shl( L_tmp, exp ); + + exp = sub( sub( 31, exp ), ( sub( sub( 31, exp1 ), exp2 ) ) ); + move16(); + L_tmp1 = Isqrt_lc( L_tmp1, &exp ); /*Q(31-exp)*/ + cor_max = Mult_32_32( cor_max, L_tmp1 ); + exp = add( sub( sub( 31, add( shl( Q_new, 1 ), 1 ) ), sub( 31, exp ) ), 31 ); + cor_max16 = round_fx_o( L_shl_o( cor_max, exp, &Overflow ), &Overflow ); /*Q15*/ + /**voicing0_sm = add(mult_r(24576 ,(*voicing0_sm)) , mult_r(8192 , cor_max16));*/ + *voicing0_sm = round_fx( L_mac( L_mult( 24576 /*.75f Q15*/, *voicing0_sm ), 8192 /*.25f Q15*/, cor_max16 ) ); + move16(); + + /* final short pitch detection */ + test(); + test(); + test(); + *flag_spitch = 0; + move16(); + IF( ( EQ_16( localVAD, 1 ) ) && ( EQ_16( *predecision_flag, 1 ) ) && + ( GT_16( *voicing0_sm, 21299 /*.65f in Q15*/ ) ) && ( GT_16( *voicing0_sm, mult_r( *voicing_sm, 22938 /*.7f in Q15*/ ) ) ) ) + { + *flag_spitch = 1; + move16(); + pitch[0] = Tp; + move16(); + pitch[1] = Tp; + move16(); + pitch[2] = Tp; + move16(); + } + + return; +} diff --git a/lib_enc/pitch_ol_fx.c b/lib_enc/pitch_ol_fx.c index 82b00ead0b1b92e3a5ec90ed7fbc5389dc8eab07..91181714af9242f49697b8f221c167f31d525faf 100644 --- a/lib_enc/pitch_ol_fx.c +++ b/lib_enc/pitch_ol_fx.c @@ -46,21 +46,6 @@ /*-----------------------------------------------------------------* * Local function prototypes *-----------------------------------------------------------------*/ -static Word32 Dot_product12_o_ivas( /* (o) Q31: normalized result (1 < val <= -1) */ - const Word16 x[], /* (i) 12bits: x vector */ - const Word16 y[], /* (i) 12bits: y vector */ - const Word16 lg, /* (i) : vector length */ - Word16 *exp, /* (o) : exponent of result (0..+30) */ - Flag *Overflow_out /* o : propagating the Overflow flag to upper level, set to NULL to ignore internal overflows */ -); -static Word32 Dot_product12_ivas( /* (o) Q31: normalized result (1 < val <= -1) */ - const Word16 x[], /* (i) 12bits: x vector */ - const Word16 y[], /* (i) 12bits: y vector */ - const Word16 lg, /* (i) : vector length */ - Word16 *exp /* (o) : exponent of result (0..+30) */ -); -static Word32 Dot_product12_OL_ivas( Word16 *sum1, const Word16 x[], const Word16 y[], const Word16 lg, const Word16 lg2, Word16 *exp, Word16 *exp2 ); -static Word32 Dot_product12_OL_back_ivas( Word16 *sum1, const Word16 x[], const Word16 y[], const Word16 lg, const Word16 lg2, Word16 *exp, Word16 *exp2 ); static void LP_Decim2_Copy( const Word16 x[], Word16 y[], Word16 l, Word16 mem[] ); @@ -73,191 +58,7 @@ static Word16 pitch_coherence_fx( Word16 pitch0, Word16 pitch1, Word16 fac_max, static Word32 Dot_product12_OL( Word16 *sum1, const Word16 x[], const Word16 y[], const Word16 lg, const Word16 lg2, Word16 *exp, Word16 *exp2 ); static Word32 Dot_product12_OL_back( Word16 *sum1, const Word16 x[], const Word16 y[], const Word16 lg, const Word16 lg2, Word16 *exp, Word16 *exp2 ); -#ifdef BASOP_NOGLOB -static Word32 Dot_product12_o_ivas( /* (o) Q31: normalized result (1 < val <= -1) */ - const Word16 x[], /* (i) 12bits: x vector */ - const Word16 y[], /* (i) 12bits: y vector */ - const Word16 lg, /* (i) : vector length */ - Word16 *exp, /* (o) : exponent of result (0..+30) */ - Flag *Overflow_out /* o : propagating the Overflow flag to upper level, set to NULL to ignore internal overflows */ -) -#else /* BASOP_NOGLOB */ -Word32 Dot_product12_ivas( /* (o) Q31: normalized result (1 < val <= -1) */ - const Word16 x[], /* (i) 12bits: x vector */ - const Word16 y[], /* (i) 12bits: y vector */ - const Word16 lg, /* (i) : vector length */ - Word16 *exp /* (o) : exponent of result (0..+30) */ -) -#endif /* BASOP_NOGLOB */ -{ - Word16 i, sft; - Word32 L_sum; -#ifdef BASOP_NOGLOB - Flag Overflow_ignored = 0; -#endif /* BASOP_NOGLOB */ - -#ifdef BASOP_NOGLOB - L_sum = L_mac_o( 0, x[0], y[0], &Overflow_ignored ); -#else - L_sum = L_mac( 1, x[0], y[0] ); -#endif - FOR( i = 1; i < lg; i++ ) - { -#ifdef BASOP_NOGLOB - L_sum = L_mac_o( L_sum, x[i], y[i], Overflow_out ? Overflow_out : &Overflow_ignored ); -#else /* BASOP_NOGLOB */ - L_sum = L_mac( L_sum, x[i], y[i] ); -#endif /* BASOP_NOGLOB */ - } - - /* Normalize acc in Q31 */ - - sft = norm_l( L_sum ); - L_sum = L_shl( L_sum, sft ); - - *exp = sub( 30, sft ); - move16(); /* exponent = 0..30 */ - - return L_sum; -} - -static Word32 Dot_product12_ivas( /* (o) Q31: normalized result (1 < val <= -1) */ - const Word16 x[], /* (i) 12bits: x vector */ - const Word16 y[], /* (i) 12bits: y vector */ - const Word16 lg, /* (i) : vector length */ - Word16 *exp /* (o) : exponent of result (0..+30) */ -) -{ - /* Ignore internal overflows */ - return Dot_product12_o_ivas( x, y, lg, exp, NULL ); -} -/*---------------------------------------------------------------------* - * Dot_product12_OL_back() - * - * two different length dot products of x and y, computed backward - *---------------------------------------------------------------------*/ -static Word32 Dot_product12_OL_back_ivas( /* o : Q31: normalized result (1 < val <= -1) */ - Word16 *sum1, /* o : Q31: normalized result 2 */ - const Word16 x[], /* i : 12bits: x vector */ - const Word16 y[], /* i : 12bits: y vector */ - const Word16 lg, /* i : vector length */ - const Word16 lg2, /* i : vector length 2 */ - Word16 *exp, /* o : exponent of result (0..+30) */ - Word16 *exp2 /* o : exponent of result 2 (0..+30) */ -) -{ - Word16 i, sft; - Word32 L_sum, L_sum2; - Flag Overflow_ignored = 0; - - L_sum = L_mac( 0, x[0], y[0] ); - IF( LE_16( lg, lg2 ) ) - { - FOR( i = 1; i < lg; i++ ) - { - L_sum = L_mac_o( L_sum, x[-i], y[-i], &Overflow_ignored ); - } - /* sets to 'L_sum' in 1 clock */ - L_sum2 = L_sum; - move32(); - FOR( ; i < lg2; i++ ) - { - L_sum2 = L_mac_o( L_sum2, x[-i], y[-i], &Overflow_ignored ); - } - } - ELSE - { - FOR( i = 1; i < lg2; i++ ) - { - L_sum = L_mac_o( L_sum, x[-i], y[-i], &Overflow_ignored ); - } - /* sets to 'L_sum' in 1 clock */ - L_sum2 = L_sum; - move32(); - FOR( ; i < lg; i++ ) - { - L_sum = L_mac_o( L_sum, x[-i], y[-i], &Overflow_ignored ); - } - } - - /* Q31 */ - sft = norm_l( L_sum ); - L_sum = L_shl( L_sum, sft ); - *exp = sub( 30, sft ); - move16(); /* exponent = 0..30 */ - - sft = norm_l( L_sum2 ); - L_sum2 = L_shl( L_sum2, sft ); - *exp2 = sub( 30, sft ); - move16(); /* exponent = 0..30 */ - - *sum1 = extract_h( L_shr( L_sum2, 1 ) ); - - return L_sum; -} -/*---------------------------------------------------------------------* - * Dot_product12_OL - * - * two different length dot products of x and y - *---------------------------------------------------------------------*/ -static Word32 Dot_product12_OL_ivas( /* o : Q31: normalized result (1 < val <= -1) */ - Word16 *sum1, /* o : Q31: normalized result 2 */ - const Word16 x[], /* i : 12bits: x vector */ - const Word16 y[], /* i : 12bits: y vector */ - const Word16 lg, /* i : vector length */ - const Word16 lg2, /* i : vector length 2 */ - Word16 *exp, /* o : exponent of result (0..+30) */ - Word16 *exp2 /* o : exponent of result 2 (0..+30) */ -) -{ - Word16 i, sft; - Word32 L_sum, L_sum2; - Flag Overflow_ignored = 0; - L_sum = L_mac( 0, x[0], y[0] ); - IF( LE_16( lg, lg2 ) ) - { - FOR( i = 1; i < lg; i++ ) - { - L_sum = L_mac_o( L_sum, x[i], y[i], &Overflow_ignored ); - } - /* sets to 'L_sum' in 1 clock */ - L_sum2 = L_sum; - move32(); - FOR( ; i < lg2; i++ ) - { - L_sum2 = L_mac_o( L_sum2, x[i], y[i], &Overflow_ignored ); - } - } - ELSE - { - FOR( i = 1; i < lg2; i++ ) - { - L_sum = L_mac_o( L_sum, x[i], y[i], &Overflow_ignored ); - } - /* sets to 'L_sum' in 1 clock */ - L_sum2 = L_sum; - move32(); - FOR( ; i < lg; i++ ) - { - L_sum = L_mac_o( L_sum, x[i], y[i], &Overflow_ignored ); - } - } - - /* Q31 */ - sft = norm_l( L_sum ); - L_sum = L_shl( L_sum, sft ); - *exp = sub( 30, sft ); - move16(); /* exponent = 0..30 */ - - sft = norm_l( L_sum2 ); - L_sum2 = L_shl( L_sum2, sft ); - *exp2 = sub( 30, sft ); - move16(); /* exponent = 0..30 */ - *sum1 = extract_h( L_shr( L_sum2, 1 ) ); - - return L_sum; -} /*-----------------------------------------------------------------* * pitch_ol_init() * @@ -461,9 +262,9 @@ void pitch_ol_fx( tmp_mem[2] = mem_decim2[2]; move16(); - LP_Decim2_Copy( &wsp[L_FRAME], &wsp2[shr( L_FRAME, 1 )], L_LOOK_12k8, tmp_mem ); /* shr() used instead of division by OPL_DECIM*/ + LP_Decim2_Copy( &wsp[L_FRAME], &wsp2[( L_FRAME / 2 )], L_LOOK_12k8, tmp_mem ); /* shr() used instead of division by OPL_DECIM*/ - Copy( &old_wsp2[shr( L_FRAME, 1 )], st_old_wsp2, ( L_WSP_MEM - L_INTERPOL ) / OPL_DECIM ); + Copy( &old_wsp2[L_FRAME / 2], st_old_wsp2, ( L_WSP_MEM - L_INTERPOL ) / OPL_DECIM ); /*-----------------------------------------------------------------* * Attenuate the correlation correction factor due to noise. @@ -936,11 +737,7 @@ void pitch_ol_fx( enr1_exp = 0; move16(); -#ifdef BASOP_NOGLOB enr1 = add_o( extract_h( dotp_fx( pt2, pt2, len[j], &enr1_exp ) ), 1, &Overflow ); -#else - enr1 = add( extract_h( dotp_fx( pt2, pt2, len[j], &enr1_exp ) ), 1 ); -#endif enr2 = L_mult( enr0[j], enr1 ); enr2_exp = norm_l( enr2 ); @@ -954,11 +751,7 @@ void pitch_ol_fx( Ltmp = L_mult0( cor_buf[ind], enr1 ); qCorX = add( sub( 15, enr1_exp ), sub( 14, pt_exp1[ind] ) ); -#ifdef BASOP_NOGLOB corX[i][j] = extract_h( L_shr_o( Ltmp, sub( qCorX, 31 ), &Overflow ) ); -#else /* BASOP_NOGLOB */ - corX[i][j] = extract_h( L_shr( Ltmp, sub( qCorX, 31 ) ) ); -#endif /* BASOP_NOGLOB */ qCorX = 31; move16(); @@ -980,11 +773,7 @@ void pitch_ol_fx( move16(); /* selected moving vector */ enr1_exp = 0; move16(); -#ifdef BASOP_NOGLOB enr1 = add_o( extract_h( dotp_fx( pt4, pt4, len1[j], &enr1_exp ) ), 1, &Overflow ); -#else - enr1 = add( extract_h( dotp_fx( pt4, pt4, len1[j], &enr1_exp ) ), 1 ); -#endif enr2 = L_mult( enr0_1[j], enr1 ); enr2_exp = norm_l( enr2 ); @@ -999,11 +788,7 @@ void pitch_ol_fx( Ltmp = L_mult0( cor_buf[ind1 + len_x], enr1 ); qCorX = add( sub( 15, enr1_exp ), sub( 14, pt_exp3[ind1] ) ); -#ifdef BASOP_NOGLOB corX[i][j + NSECT] = extract_h( L_shr_o( Ltmp, qCorX - 31, &Overflow ) ); -#else /* BASOP_NOGLOB */ - corX[i][j + NSECT] = extract_h( L_shr( Ltmp, qCorX - 31 ) ); -#endif /* BASOP_NOGLOB */ qCorX = 31; move16(); @@ -1083,11 +868,7 @@ void pitch_ol_fx( move16(); pitch_tmp[i] = pitchX[i][ind]; move16(); -#ifdef BASOP_NOGLOB cor_tmp[i] = add_o( corX[i][ind], corr_shift, &Overflow ); -#else /* BASOP_NOGLOB */ - cor_tmp[i] = add( corX[i][ind], corr_shift ); -#endif /* BASOP_NOGLOB */ move16(); /* Higher is the neighbour's correlation, higher is the weighting */ @@ -1101,11 +882,7 @@ void pitch_ol_fx( move16(); pitch_tmp[i + NHFR] = pitchX[i][ind1]; move16(); -#ifdef BASOP_NOGLOB cor_tmp[i + NHFR] = add_o( corX[i][ind1], corr_shift, &Overflow ); -#else /* BASOP_NOGLOB */ - cor_tmp[i + NHFR] = add( corX[i][ind1], corr_shift ); -#endif move16(); /* Higher is the neighbour's correlation, higher is the weighting */ @@ -1287,7 +1064,7 @@ void pitch_ol_ivas_fx( Word16 *old_pitch, /* i/o: pitch of the 2nd half-frame of previous frame (i.e. pitch[1]) Q0 */ Word16 *old_corr, /* i/o: correlation of old_pitch (i.e. voicing[1] or corr_mean) Q15 */ Word16 corr_shift, /* i : normalized correlation correction Q15 */ - Word16 *old_thres, /* i/o: maximum correlation weighting with respect to past frame pitch Q15 */ + Word16 *old_thres, /* i/o: maximum correlation weighting with respect to past frame pitch Q14 */ Word16 *delta_pit, /* i/o: old pitch extrapolation correction in range [-14,+14] Q0 */ Word16 *st_old_wsp2, /* i/o: weighted speech memory qwsp */ const Word16 *wsp, /* i : weighted speech for current frame and look-ahead qwsp */ @@ -1295,7 +1072,8 @@ void pitch_ol_ivas_fx( const Word16 relE, /* i : relative frame energy Q8 */ const Word16 last_class, /* i : frame classification of last frame */ const Word16 bwidth, /* i : bandwidth */ - const Word16 Opt_SC_VBR /* i : SC-VBR flag */ + const Word16 Opt_SC_VBR, /* i : SC-VBR flag */ + Word16 qwsp /* i : Q factor for wsp Q0 */ ) { Word16 ftmp, old_wsp2[( L_WSP - L_INTERPOL ) / OPL_DECIM], *wsp2; @@ -1303,11 +1081,11 @@ void pitch_ol_ivas_fx( Word16 scale1[2 * DELTA_COH - 1]; Word16 scaled_buf[2 * LEN_X + 3 * ( DELTA_COH - 1 )]; - Word16 scaled_buf_exp[2 * LEN_X + 3 * ( DELTA_COH - 1 )], exp_sect[8], exp_sect1[8], exp_sect0; - Word16 cor_buf[2 * LEN_X]; - Word16 *pt_exp1, *pt_exp2, *pt_exp3, *pt_exp4; + Word16 scaled_buf_exp[2 * LEN_X + 3 * ( DELTA_COH - 1 )]; + Word16 cor_buf[2 * LEN_X], cor_buf_exp[2 * LEN_X]; Word16 *pt1, *pt2, *pt3, *pt4, *pt5, *pt6; - Word16 *pt_cor0, *pt_cor1, *pt_cor2, *pt_cor3, *pt_cor4, *pt_cor5, *pt_cor6; + Word16 *pt_cor0, *pt_cor1, *pt_cor2, *pt_cor3, *pt_cor4; + Word16 *pt_cor0_exp, *pt_cor1_exp, *pt_cor2_exp, *pt_cor3_exp, *pt_cor4_exp; Word16 thres1[6]; Word16 diff, cnt, ind, ind1, offset, offset1, offset_la, offset_la1, coh_flag, coh_flag1; Word16 ind_corX, ind1_corX; @@ -1316,10 +1094,11 @@ void pitch_ol_ivas_fx( Word16 len_temp; Word16 pitchX[NHFR][2 * NSECT], pitch_tmp[2 * NHFR], ind_tmp[2 * NHFR], tmp_buf[NHFR + 1]; - Word16 enr0[NSECT], enr0_exp[NSECT], enr0_1[NSECT], enr0_1_exp[NSECT], enr1, enr1_exp, enr2_exp; - Word32 enr, enr2, Ltmp; + Word16 enr0_exp[NSECT], enr0_1_exp[NSECT], enr1_exp; + Word32 enr0[NSECT], enr0_1[NSECT], enr1; + Word64 temp, temp1; + Word32 Ltmp; Word16 fac, tmp16, tmp16_2; - Word16 qCorX, qScaledX; Word16 scaledX[NHFR][2 * NSECT], corX[NHFR][2 * NSECT], cor_tmp[2 * NHFR], cor_mean; const Word16 *len, *len1, *sublen, *sublen1, *pit_max, *sec_length, *sec_length1; @@ -1327,6 +1106,8 @@ void pitch_ol_ivas_fx( #ifdef BASOP_NOGLOB_DECLARE_LOCAL Flag Overflow = 0; #endif + Word16 new_q; + new_q = sub( 63, shl( qwsp, 1 ) ); /*--------------------------------------------------------------* * Initialization @@ -1354,7 +1135,7 @@ void pitch_ol_ivas_fx( test(); test(); IF( ( ( NE_16( bwidth, NB ) ) && ( GT_16( *old_pitch, PIT_MIN ) ) ) || - ( ( EQ_16( bwidth, NB ) ) && ( ( GT_16( *old_pitch, PIT_MIN2_1 ) ) || ( LT_16( *old_thres, 3277 ) ) ) ) ) /* 0.1 inQ15*/ + ( ( EQ_16( bwidth, NB ) ) && ( ( GT_16( *old_pitch, PIT_MIN2_1 ) ) || ( LT_16( *old_thres, 1638 /* 0.1 in Q14*/ ) ) ) ) ) { pit_min = PIT_MIN / OPL_DECIM; move16(); @@ -1403,9 +1184,9 @@ void pitch_ol_ivas_fx( tmp_mem[2] = mem_decim2[2]; move16(); - LP_Decim2_Copy( &wsp[L_FRAME], &wsp2[shr( L_FRAME, 1 )], L_LOOK_12k8, tmp_mem ); /* shr() used instead of division by OPL_DECIM*/ + LP_Decim2_Copy( &wsp[L_FRAME], &wsp2[L_FRAME / 2], L_LOOK_12k8, tmp_mem ); /* shr() used instead of division by OPL_DECIM*/ - Copy( &old_wsp2[shr( L_FRAME, 1 )], st_old_wsp2, ( L_WSP_MEM - L_INTERPOL ) / OPL_DECIM ); + Copy( &old_wsp2[L_FRAME / 2], st_old_wsp2, ( L_WSP_MEM - L_INTERPOL ) / OPL_DECIM ); /*-----------------------------------------------------------------* * Attenuate the correlation correction factor due to noise. @@ -1423,21 +1204,16 @@ void pitch_ol_ivas_fx( pt1 = scale1 + DELTA_COH - 1; pt2 = pt1; - tmp16 = mult( negate( *old_thres ), MAX_16 / DELTA_COH ); - k = *old_thres; - move16(); + tmp16 = mult( *old_thres, -32768 / DELTA_COH ); // Q14 + k = add( *old_thres, ONE_IN_Q14 ); // Q14 FOR( i = 0; i < DELTA_COH; i++ ) { - /* - * *pt1 = ( -(*old_thres)/DELTA_COH * i + *old_thres+1.0f ); - * To keep Q15 values, the following code does not add 1 to the result. - * A scaling factor must be applied accordingly (see next use of scale1) - */ - *pt1 = k; + *pt1 = k; // Q14 + *pt2-- = *pt1++; // Q14 move16(); - k = add( k, tmp16 ); - *pt2-- = *pt1++; move16(); + + k = add( k, tmp16 ); // Q14 } /*-----------------------------------------------------------------------------* @@ -1454,9 +1230,13 @@ void pitch_ol_ivas_fx( * Loop for all three half-frames (current frame + look-ahead) *-----------------------------------------------------------------*/ pt_cor0 = scaled_buf + DELTA_COH - 1; + pt_cor0_exp = scaled_buf_exp + DELTA_COH - 1; pt_cor2 = pt_cor0 - pit_min + old_tmp; + pt_cor2_exp = pt_cor0_exp - pit_min + old_tmp; + pt_cor4 = pt_cor0 - pit_min1 + old_tmp + ( DELTA_COH - 1 ) + len_x; + pt_cor4_exp = pt_cor0_exp - pit_min1 + old_tmp + ( DELTA_COH - 1 ) + len_x; FOR( i = 0; i < NHFR; i++ ) /* i = 0, 1, 2 */ { @@ -1464,15 +1244,14 @@ void pitch_ol_ivas_fx( pt2 = pt1 - pit_min; /* *pt2 -> Q12 */ pt4 = pt1 - pit_min1; /* *pt4 -> Q12 */ - enr = 0; + temp = 0; + move64(); pt_cor1 = pt_cor0; - pt_cor3 = pt_cor0 + ( DELTA_COH - 1 ) + len_x; + pt_cor1_exp = pt_cor0_exp; - pt_exp1 = scaled_buf_exp + DELTA_COH - 1; - pt_exp2 = pt_exp1; - pt_exp3 = scaled_buf_exp + 2 * ( DELTA_COH - 1 ) + len_x; - pt_exp4 = pt_exp3; + pt_cor3 = pt_cor0 + ( DELTA_COH - 1 ) + len_x; + pt_cor3_exp = pt_cor0_exp + ( DELTA_COH - 1 ) + len_x; IF( LT_16( i, NHFR - 1 ) ) /* First two half-frames (current frame) */ { @@ -1488,72 +1267,83 @@ void pitch_ol_ivas_fx( /* 1st set */ k = (Word16) ( pt1 - pt3 ); move16(); - Flag overflow = 0; FOR( k = add( k, len[j] ); k > 0; k-- ) { - enr = L_mac0_o( enr, *pt3, *pt3, &overflow ); + temp = W_mac0_16_16( temp, *pt3, *pt3 ); // 2*qwsp pt3++; } - /* keep Q15 normalized result */ - cnt = norm_l( enr ); - enr0[j] = extract_h( L_shl( enr, cnt ) ); - enr0_exp[j] = sub( 30, cnt ); - move16(); + IF( temp == 0 ) + { + enr0[j] = 21474836; // 0.01 in Q31 + enr0_exp[j] = 0; + move32(); + move16(); + } + ELSE + { + cnt = W_norm( temp ); + enr0[j] = W_extract_h( W_shl( temp, cnt ) ); // 2*qwsp+cnt-32 + enr0_exp[j] = sub( new_q, cnt ); // 31-(2*qwsp+cnt-32) + move32(); + move16(); + } /* Reduce complexity (length of 'enr2' section is equal or larger than 'enr') */ pt5 = pt3; - enr2 = enr; /* sets to 'enr' in 1 clock */ - move32(); /* 2nd set */ k = (Word16) ( pt1 - pt5 ); move16(); - FOR( k = add( k, len1[j] ); k > 0; k-- ) + temp1 = temp; + move64(); + FOR( k = ( k + len1[j] ); k > 0; k-- ) { - enr2 = L_mac0_o( enr2, *pt5, *pt5, &overflow ); + temp1 = W_mac0_16_16( temp1, *pt5, *pt5 ); // 2*qwsp pt5++; } - cnt = norm_l( enr2 ); - enr0_1[j] = extract_h( L_shl( enr2, cnt ) ); - enr0_1_exp[j] = sub( 30, cnt ); - move16(); + IF( temp1 == 0 ) + { + enr0_1[j] = 21474836; // 0.01 in Q31 + enr0_1_exp[j] = 0; + move32(); + move16(); + } + ELSE + { + cnt = W_norm( temp1 ); + enr0_1[j] = W_extract_h( W_shl( temp1, cnt ) ); // 2*qwsp+cnt-32 + enr0_1_exp[j] = sub( new_q, cnt ); // 31-(2*qwsp+cnt-32) + move32(); + move16(); + } } /*----------------------------------------------------------* * Find correlation for the non-overlapping pitch lag values *----------------------------------------------------------*/ - exp_sect[subsect0] = 0; - move16(); - pt_cor5 = pt_cor1; - pt_cor6 = pt_cor3; - - tmp16 = exp_sect[subsect0]; - move16(); k = (Word16) ( pt2 - pt1 + pit_max[subsect0] ); + move16(); - IF( k >= 0 ) + FOR( ; k >= 0; k-- ) { - len_temp = sublen[0]; - move16(); - - FOR( ; k >= 0; k-- ) + temp = 0; + move64(); + FOR( m = 0; m < sublen[0]; m++ ) { - /* Keep Q15 normalized result */ - /* shr by 1 to make room for scaling in the neighbourhood of the extrapolated pitch */ - /* Update exponent to reflect shr by 1 */ - *pt_cor1 = extract_h( L_shr( Dot_product12_ivas( pt1, pt2--, len_temp, pt_exp1 ), 1 ) ); - - /* save the biggest exponent */ - tmp16 = s_max( tmp16, *pt_exp1 ); - - pt_cor1++; - pt_exp1++; + temp = W_mac0_16_16( temp, pt1[m], pt2[m] ); // 2*qwsp } + cnt = W_norm( temp ); + *pt_cor1 = extract_h( W_extract_h( W_shl( temp, cnt ) ) ); // 2*qwsp+cnt-32-16 + *pt_cor1_exp = sub( new_q, cnt ); // 15-(2*qwsp+cnt-32-16) + move16(); + move16(); + + pt2--; + pt_cor1++; + pt_cor1_exp++; } - exp_sect[subsect0] = tmp16; - move16(); /*----------------------------------------------------------* * For each subsection, find the correlation @@ -1566,44 +1356,73 @@ void pitch_ol_ivas_fx( k = (Word16) ( pt2 - pt1 ); move16(); k = add( k, pit_max[j + 1] ); - exp_sect[j + 1] = 0; - move16(); - exp_sect1[j] = 0; - move16(); - IF( k >= 0 ) + /* Keep Q15 normalized result */ + IF( LT_16( sublen[j], sublen1[j] ) ) { - ind = exp_sect[j + 1]; - move16(); - ind1 = exp_sect1[j]; - move16(); + FOR( ; k >= 0; k-- ) + { + temp = W_mult0_16_16( pt1[0], pt2[0] ); // 2*qwsp + FOR( m = 1; m < sublen[j]; m++ ) + { + temp = W_mac0_16_16( temp, pt1[m], pt2[m] ); // 2*qwsp + } + cnt = W_norm( temp ); + *pt_cor1 = extract_h( W_extract_h( W_shl( temp, cnt ) ) ); // 2*qwsp+cnt-32-16 + *pt_cor1_exp = sub( new_q, cnt ); + move16(); + move16(); + FOR( ; m < sublen1[j]; m++ ) + { + temp = W_mac0_16_16( temp, pt1[m], pt2[m] ); // 2*qwsp + } + cnt = W_norm( temp ); + *pt_cor3 = extract_h( W_extract_h( W_shl( temp, cnt ) ) ); // 2*qwsp+cnt-32-16 + *pt_cor3_exp = sub( new_q, cnt ); + move16(); + move16(); + + pt_cor1++; + pt_cor1_exp++; + pt_cor3++; + pt_cor3_exp++; + pt2--; + } + } + ELSE + { FOR( ; k >= 0; k-- ) { - /* Keep Q15 normalized result */ - /* shr by 1 to make room for scaling in the neighbourhood of the extrapolated pitch */ - /* Update exponent to reflect shr by 1 (done in Dot_product12_OL() for pt_cor3/pt_exp3) */ - *pt_cor1 = extract_h( L_shr( Dot_product12_OL_ivas( pt_cor3, pt1, pt2--, sublen[j], sublen1[j], pt_exp1, pt_exp3 ), 1 ) ); - /* The line above replaces: - * *pt_cor1 = shr(extract_h(Dot_product12(pt1, pt2, Sublen[j], pt_exp1)),1); move16(); - * *pt_cor3 = shr(extract_h(Dot_product12(pt1, pt2--, Sublen1[j+i*7], pt_exp3)),1); move16(); - */ + temp = W_mult0_16_16( pt1[0], pt2[0] ); // 2*qwsp + FOR( m = 1; m < sublen1[j]; m++ ) + { + temp = W_mac0_16_16( temp, pt1[m], pt2[m] ); // 2*qwsp + } + cnt = W_norm( temp ); + *pt_cor3 = extract_h( W_extract_h( W_shl( temp, cnt ) ) ); // 2*qwsp+cnt-32-16 + *pt_cor3_exp = sub( new_q, cnt ); + move16(); + move16(); - /* save the biggest exponent */ - ind = s_max( ind, *pt_exp1 ); - ind1 = s_max( ind1, *pt_exp3 ); + FOR( ; m < sublen[j]; m++ ) + { + temp = W_mac0_16_16( temp, pt1[m], pt2[m] ); // 2*qwsp + } + cnt = W_norm( temp ); + *pt_cor1 = extract_h( W_extract_h( W_shl( temp, cnt ) ) ); // 2*qwsp+cnt-32-16 + *pt_cor1_exp = sub( new_q, cnt ); + move16(); + move16(); pt_cor1++; - pt_exp1++; + pt_cor1_exp++; pt_cor3++; - pt_exp3++; + pt_cor3_exp++; + pt2--; } - exp_sect[j + 1] = ind; - move16(); - exp_sect1[j] = ind1; - move16(); - } /* IF (k >= 0) */ - } /* FOR (j = subsect0; ... */ + } + } /* FOR (j = subsect0; ... */ } ELSE /* 3rd half-frame (look-ahead) */ { @@ -1614,7 +1433,6 @@ void pitch_ol_ivas_fx( /*-----------------------------------------------------------------* * For each section in both sets, find fixed vector energy *-----------------------------------------------------------------*/ - Flag overflow = 0; FOR( j = sect0; j < NSECT; j++ ) /* loop for each section */ { /* 1st set */ @@ -1623,93 +1441,91 @@ void pitch_ol_ivas_fx( FOR( k = add( k, len[j] ); k > 0; k-- ) { - enr = L_mac0_o( enr, *pt3, *pt3, &overflow ); + temp = W_mac0_16_16( temp, *pt3, *pt3 ); pt3--; } - - cnt = norm_l( enr ); - enr0[j] = extract_h( L_shl( enr, cnt ) ); /*qwsp+cnt-16*/ - enr0_exp[j] = sub( 30, cnt ); - move16(); + IF( temp == 0 ) + { + enr0[j] = 21474836; // 0.01 in Q31 + enr0_exp[j] = 0; + move32(); + move16(); + } + ELSE + { + cnt = W_norm( temp ); + enr0[j] = W_extract_h( W_shl( temp, cnt ) ); // 2*qwsp+cnt-32 + enr0_exp[j] = sub( new_q, cnt ); // 31-(2*qwsp+cnt-32) + move32(); + move16(); + } /* Reduce complexity (length of 'enr2' section is equal or larger than 'enr') */ pt5 = pt3; - enr2 = enr; - move16(); + temp1 = temp; + move64(); /* 2nd set */ k = (Word16) ( pt5 - pt6 ); move16(); - FOR( k = add( k, len1[j] ); k > 0; k-- ) { - enr2 = L_mac0_o( enr2, *pt5, *pt5, &overflow ); + temp1 = W_mac0_16_16( temp1, *pt5, *pt5 ); // 2*qwsp pt5--; } - - cnt = norm_l( enr2 ); - enr0_1[j] = extract_h( L_shl( enr2, cnt ) ); /*qwsp+cnt-16*/ - enr0_1_exp[j] = sub( 30, cnt ); - move16(); + IF( temp1 == 0 ) + { + enr0_1[j] = 21474836; // 0.01 in Q31 + enr0_1_exp[j] = 0; + move32(); + move16(); + } + ELSE + { + cnt = W_norm( temp1 ); + temp1 = W_shl( temp1, cnt ); // 2*qwsp+cnt + enr0_1[j] = W_extract_h( temp1 ); // 2*qwsp+cnt-32 + enr0_1_exp[j] = sub( new_q, cnt ); // 31-(2*qwsp+cnt-32) + move32(); + move16(); + } } - /* Set pointers */ + /* Set pointers: same as IF/ELSE block */ + pt2 = pt6 - pit_min; + k = 2; + move16(); IF( sect0 != 0 ) { pt2 = pt6 - add( pit_max[1], 1 ); k = sub( pit_max[2], pit_max[1] ); move16(); } - ELSE - { - pt2 = pt6 - pit_min; - k = 2; - move16(); - } /*-----------------------------------------------------------------* * Find correlation for the non-overlapping pitch lag values *-----------------------------------------------------------------*/ - exp_sect[subsect0] = 0; - move16(); - pt_cor5 = pt_cor1; - pt_cor6 = pt_cor3; - tmp16 = exp_sect[subsect0]; + len_temp = sublen[0]; move16(); - IF( k > 0 ) + FOR( ; k > 0; k-- ) { - len_temp = sublen[0]; - move16(); - - FOR( ; k > 0; k-- ) + temp = 0; + move64(); + FOR( m = 0; m < len_temp; m++ ) { - /* Following lines are equivalent of Dot_product12() but with a backward incrementing */ - Ltmp = L_deposit_l( 1 ); - FOR( m = 0; m < len_temp; m++ ) - { - Ltmp = L_mac_o( Ltmp, pt6[-m], pt2[-m], &overflow ); - } - - /* Normalize acc in Q31 */ - tmp16_2 = norm_l( Ltmp ); - Ltmp = L_shl( Ltmp, tmp16_2 ); - *pt_exp1 = sub( 30, tmp16_2 ); - move16(); /* exponent = 0..30 */ - - /* Save result */ - *pt_cor1 = extract_h( L_shr( Ltmp, 1 ) ); - - /* Save the biggest exponent */ - tmp16 = s_max( tmp16, *pt_exp1 ); - - pt_cor1++; - pt_exp1++; - pt2--; + temp = W_mac0_16_16( temp, pt6[-m], pt2[-m] ); // 2*qwsp } - exp_sect[subsect0] = tmp16; + tmp16_2 = W_norm( temp ); + *pt_cor1 = extract_h( W_extract_h( W_shl( temp, tmp16_2 ) ) ); // 2*qwsp+tmp16_2 + *pt_cor1_exp = sub( new_q, tmp16_2 ); // 2*qwsp+tmp16_2-32-16 move16(); + move16(); + + pt_cor1++; + pt_cor1_exp++; + pt2--; } /*-----------------------------------------------------------------* @@ -1718,125 +1534,115 @@ void pitch_ol_ivas_fx( FOR( j = subsect0; j < NSUBSECT; j++ ) { - exp_sect[j + 1] = 0; - move16(); - exp_sect1[j] = 0; - move16(); - - ind = exp_sect[j + 1]; - move16(); - ind1 = exp_sect1[j]; - move16(); - k = sub( pit_max[j + 1], pit_max[j] ); - FOR( ; k > 0; k-- ) + IF( LT_16( sublen[j], sublen1[j] ) ) { - *pt_cor1 = extract_h( L_shr( Dot_product12_OL_back_ivas( pt_cor3, pt6, pt2--, sublen[j], sublen1[j], pt_exp1, pt_exp3 ), 1 ) ); - - /* Save the biggest exponent */ - ind = s_max( ind, *pt_exp1 ); - ind1 = s_max( ind1, *pt_exp3 ); - - pt_cor1++; - pt_exp1++; - pt_cor3++; - pt_exp3++; - } - exp_sect[j + 1] = ind; - move16(); - exp_sect1[j] = ind1; - move16(); - } - } /* 3rd half-frame (look-ahead) */ + FOR( ; k > 0; k-- ) + { + temp = W_mult0_16_16( pt6[0], pt2[0] ); // 2*qwsp + FOR( m = 1; m < sublen[j]; m++ ) + { + temp = W_mac0_16_16( temp, pt6[-m], pt2[-m] ); // 2*qwsp + } + cnt = W_norm( temp ); + *pt_cor1 = extract_h( W_extract_h( W_shl( temp, cnt ) ) ); // 2*qwsp+cnt-32-16 + *pt_cor1_exp = sub( new_q, cnt ); + move16(); + move16(); - /* Scale all values in each section to the same exponent for upcoming Find_max() */ - offset = 0; - move16(); - offset1 = 0; - move16(); - exp_sect1[7] = 0; /* padding */ - move16(); - FOR( j = sect0; j < NSECT; j++ ) - { - exp_sect0 = s_max( exp_sect[j * 2], exp_sect[j * 2 + 1] ); + FOR( ; m < sublen1[j]; m++ ) + { + temp = W_mac0_16_16( temp, pt6[-m], pt2[-m] ); // 2*qwsp + } + cnt = W_norm( temp ); + *pt_cor3 = extract_h( W_extract_h( W_shl( temp, cnt ) ) ); // 2*qwsp+cnt-32-16 + *pt_cor3_exp = sub( new_q, cnt ); + move16(); + move16(); - /* scaling of exp for track 1 */ - offset = add( offset, sec_length[j] ); - k = (Word16) ( pt_cor0 - pt_cor5 ); - move16(); - FOR( k = add( k, offset ); k > 0; k-- ) - { - cnt = sub( exp_sect0, *pt_exp2 ); - tmp16 = s_min( 15, cnt ); - if ( cnt > 0 ) - { - tmp16 = shr( *pt_cor5, tmp16 ); + pt_cor1++; + pt_cor1_exp++; + pt_cor3++; + pt_cor3_exp++; + pt2--; + } } - if ( cnt > 0 ) + ELSE { - *pt_cor5 = tmp16; - move16(); - } - *pt_exp2 = s_max( *pt_exp2, exp_sect0 ); - move16(); - pt_cor5++; - pt_exp2++; - } + FOR( ; k > 0; k-- ) + { + temp = W_mult0_16_16( pt6[0], pt2[0] ); // 2*qwsp + FOR( m = 1; m < sublen1[j]; m++ ) + { + temp = W_mac0_16_16( temp, pt6[-m], pt2[-m] ); // 2*qwsp + } + cnt = W_norm( temp ); + *pt_cor3 = extract_h( W_extract_h( W_shl( temp, cnt ) ) ); // 2*qwsp+cnt-32-16 + *pt_cor3_exp = sub( new_q, cnt ); + move16(); + move16(); - exp_sect0 = s_max( exp_sect1[j * 2], exp_sect1[j * 2 + 1] ); + FOR( ; m < sublen[j]; m++ ) + { + temp = W_mac0_16_16( temp, pt6[-m], pt2[-m] ); // 2*qwsp + } + cnt = W_norm( temp ); + *pt_cor1 = extract_h( W_extract_h( W_shl( temp, cnt ) ) ); // 2*qwsp+cnt-32-16 + *pt_cor1_exp = sub( new_q, cnt ); + move16(); + move16(); - /* scaling of exp for track 2 */ - offset1 = add( offset1, sec_length1[j] ); - k = (Word16) ( pt_cor0 - pt_cor6 + ( DELTA_COH - 1 ) ); - move16(); - k = add( k, len_x ); - FOR( k = add( k, offset1 ); k > 0; k-- ) - { - cnt = sub( exp_sect0, *pt_exp4 ); - tmp16 = s_min( 15, cnt ); - if ( cnt > 0 ) - { - tmp16 = shr( *pt_cor6, tmp16 ); - } - if ( cnt > 0 ) - { - *pt_cor6 = tmp16; - move16(); + pt_cor1++; + pt_cor1_exp++; + pt_cor3++; + pt_cor3_exp++; + pt2--; + } } - *pt_exp4 = s_max( *pt_exp4, exp_sect0 ); - move16(); - pt_cor6++; - pt_exp4++; } - } /* FOR (j = sect0; ... */ + } /* 3rd half-frame (look-ahead) */ - Copy( pt_cor0, cor_buf, len_x ); /* Save unscaled correlation vector */ + /* Scale all values in each section to the same exponent for upcoming Find_max() */ + Copy( pt_cor0, cor_buf, len_x ); /* Save unscaled correlation vector */ + Copy( pt_cor0_exp, cor_buf_exp, len_x ); /* Save unscaled correlation vector */ Copy( pt_cor0 + ( DELTA_COH - 1 ) + len_x, cor_buf + len_x, len_x1 ); + Copy( pt_cor0_exp + ( DELTA_COH - 1 ) + len_x, cor_buf_exp + len_x, len_x1 ); /*-----------------------------------------------------------------* * Scale correlation function in the neighbourhood of * the extrapolated pitch *-----------------------------------------------------------------*/ pt_cor1 = pt_cor2 - ( DELTA_COH - 1 ); + pt_cor1_exp = pt_cor2_exp - ( DELTA_COH - 1 ); pt_cor3 = pt_cor4 - ( DELTA_COH - 1 ); + pt_cor3_exp = pt_cor4_exp - ( DELTA_COH - 1 ); pt2 = scale1; FOR( k = 0; k < 2 * DELTA_COH - 1; k++ ) { - /* all Q15 here */ - *pt_cor1 = add( *pt_cor1, mult( *pt_cor1, *pt2 ) ); + *pt_cor1 = mult( *pt_cor1, *pt2 ); // *pt_cor1_exp+1 + *pt_cor1_exp = add( *pt_cor1_exp, 1 ); // *pt_cor1_exp+1 + move16(); + move16(); + + *pt_cor3 = mult( *pt_cor3, *pt2++ ); // *pt_cor3_exp+1 + *pt_cor3_exp = add( *pt_cor3_exp, 1 ); // *pt_cor1_exp+1 move16(); - *pt_cor3 = add( *pt_cor3, mult( *pt_cor3, *pt2++ ) ); move16(); pt_cor1++; + pt_cor1_exp++; pt_cor3++; + pt_cor3_exp++; } /* Update for next half-frame & look-ahead */ pt_cor2 = pt_cor0 - pit_min + old_tmp1; + pt_cor2_exp = pt_cor0_exp - pit_min + old_tmp1; + pt_cor4 = pt_cor0 - pit_min1 + old_tmp1 + ( DELTA_COH - 1 ) + len_x; + pt_cor4_exp = pt_cor0_exp - pit_min1 + old_tmp1 + ( DELTA_COH - 1 ) + len_x; /*-----------------------------------------------------------------* * For each section, find maximum correlation and compute @@ -1844,11 +1650,11 @@ void pitch_ol_ivas_fx( *-----------------------------------------------------------------*/ pt_cor1 = pt_cor0; - pt_exp1 = scaled_buf_exp + DELTA_COH - 1; + pt_cor1_exp = pt_cor0_exp; offset = 0; move16(); pt_cor3 = pt_cor0 + ( DELTA_COH - 1 ) + len_x; - pt_exp3 = scaled_buf_exp + 2 * ( DELTA_COH - 1 ) + len_x; + pt_cor3_exp = pt_cor0_exp + ( DELTA_COH - 1 ) + len_x; offset1 = 0; move16(); @@ -1871,93 +1677,80 @@ void pitch_ol_ivas_fx( } /* 1st set of candidates */ - ind = add( maximum_fx( pt_cor1, sec_length[j], &ftmp ), offset ); + ind = add( maximum_exp_fx( pt_cor1, pt_cor1_exp, sec_length[j] ), offset ); pitchX[i][j] = add( ind, pit_min ); move16(); pt2 = pt1 - pitchX[i][j] + /*-*/ offset_la; /* selected moving vector */ enr1_exp = 0; move16(); -#ifdef BASOP_NOGLOB - enr1 = add_o( extract_h( dotp_fx( pt2, pt2, len[j], &enr1_exp ) ), 1, &Overflow ); -#else - enr1 = add( extract_h( dotp_fx( pt2, pt2, len[j], &enr1_exp ) ), 1 ); -#endif - enr2 = L_mult( enr0[j], enr1 ); - enr2_exp = norm_l( enr2 ); - enr2 = L_shl( enr2, enr2_exp ); - enr2_exp = sub( 31, add( sub( 28, add( enr0_exp[j], enr1_exp ) ), add( enr2_exp, 1 ) ) ); + /* enr1 = dotp( pt2, pt2, len[j] ) + 0.01f; */ + temp = 167772 /*0.01f in Q24*/; + move64(); + FOR( m = 0; m < len[j]; m++ ) + { + temp = W_mac0_16_16( temp, pt2[m], pt2[m] ); // 2*qwsp + } + temp = W_shl( temp, sub( Q24, shl( qwsp, 1 ) ) ); // Q24 + enr1_exp = W_norm( temp ); + enr1 = W_extract_h( W_shl( temp, enr1_exp ) ); // enr1_exp+24-32 + enr1_exp = sub( 39, enr1_exp ); // 31-(enr1_exp+24-32) - enr2 = Isqrt_lc( enr2, &enr2_exp ); /* 1/sqrt(energy) */ /*31-enr2_exp*/ - enr1_exp = norm_l( enr2 ); - enr1 = extract_h( L_shl( enr2, enr1_exp ) ); /*31-enr2_exp+enr1_exp-16*/ - enr1_exp = sub( enr2_exp, enr1_exp ); /*15-enr1_exp*/ + enr1 = Mpy_32_32( enr0[j], enr1 ); + enr1_exp = add( enr0_exp[j], enr1_exp ); - Ltmp = L_mult0( cor_buf[ind], enr1 ); - qCorX = add( sub( 15, enr1_exp ), sub( 14, pt_exp1[ind] ) ); -#ifdef BASOP_NOGLOB - corX[i][j] = extract_h( L_shr_o( Ltmp, sub( qCorX, 31 ), &Overflow ) ); -#else /* BASOP_NOGLOB */ - corX[i][j] = extract_h( L_shr( Ltmp, sub( qCorX, 31 ) ) ); -#endif /* BASOP_NOGLOB */ - qCorX = 31; + enr1 = ISqrt32( enr1, &enr1_exp ); /* 1/sqrt(energy) */ /*31-enr2_exp*/ + + Ltmp = Mpy_32_16_1( enr1, cor_buf[ind] ); + corX[i][j] = extract_h( L_shl_o( Ltmp, add( enr1_exp, cor_buf_exp[ind] ), &Overflow ) ); // Q15 move16(); - Ltmp = L_mult0( pt_cor0[ind], enr1 ); - qScaledX = add( sub( 15, enr1_exp ), sub( 14, pt_exp1[ind] ) ); - scaledX[i][j] = round_fx( L_shl( Ltmp, sub( 16 + 12, qScaledX ) ) ); - qScaledX = 12; + Ltmp = Mpy_32_16_1( enr1, pt_cor0[ind] ); + scaledX[i][j] = round_fx( L_shl( Ltmp, sub( add( enr1_exp, pt_cor0_exp[ind] ), 3 ) ) ); // Q12 move16(); pt_cor1 += sec_length[j]; - move16(); + pt_cor1_exp += sec_length[j]; offset = add( offset, sec_length[j] ); /* 2nd set of candidates */ - ind1 = add( maximum_fx( pt_cor3, sec_length1[j], &ftmp ), offset1 ); + ind1 = add( maximum_exp_fx( pt_cor3, pt_cor3_exp, sec_length1[j] ), offset1 ); pitchX[i][j + NSECT] = add( ind1, pit_min1 ); move16(); pt4 = pt1 - pitchX[i][j + NSECT] + /*-*/ offset_la1; move16(); /* selected moving vector */ enr1_exp = 0; move16(); -#ifdef BASOP_NOGLOB - enr1 = add_o( extract_h( dotp_fx( pt4, pt4, len1[j], &enr1_exp ) ), 1, &Overflow ); -#else - enr1 = add( extract_h( dotp_fx( pt4, pt4, len1[j], &enr1_exp ) ), 1 ); -#endif - enr2 = L_mult( enr0_1[j], enr1 ); - enr2_exp = norm_l( enr2 ); - enr2 = L_shl( enr2, enr2_exp ); + /* enr1 = dotp(pt4, pt4, len1[j]) + 0.01f; */ + temp = 167772 /*0.01f in Q24*/; + move64(); + FOR( m = 0; m < len1[j]; m++ ) + { + temp = W_mac0_16_16( temp, pt4[m], pt4[m] ); // 2*qwsp + } + temp = W_shl( temp, sub( Q24, shl( qwsp, 1 ) ) ); // Q24 + enr1_exp = W_norm( temp ); + enr1 = W_extract_h( W_shl( temp, enr1_exp ) ); // enr1_exp+24-32 + enr1_exp = sub( 39, enr1_exp ); // 31-(enr1_exp+24-32) - enr2_exp = sub( 31, add( sub( 28, add( enr0_1_exp[j], enr1_exp ) ), add( enr2_exp, 1 ) ) ); - enr2 = Isqrt_lc( enr2, &enr2_exp ); /* 1/sqrt(energy) */ /*31-enr2_exp*/ - enr1_exp = norm_l( enr2 ); - enr1 = extract_h( L_shl( enr2, enr1_exp ) ); /*31-enr2_exp+enr1_exp-16*/ - enr1_exp = sub( enr2_exp, enr1_exp ); /*15-enr1_exp*/ + enr1 = Mpy_32_32( enr0_1[j], enr1 ); + enr1_exp = add( enr0_1_exp[j], enr1_exp ); - Ltmp = L_mult0( cor_buf[ind1 + len_x], enr1 ); + enr1 = ISqrt32( enr1, &enr1_exp ); /* 1/sqrt(energy) */ /*31-enr1_exp*/ - qCorX = add( sub( 15, enr1_exp ), sub( 14, pt_exp3[ind1] ) ); -#ifdef BASOP_NOGLOB - corX[i][j + NSECT] = extract_h( L_shr_o( Ltmp, qCorX - 31, &Overflow ) ); -#else /* BASOP_NOGLOB */ - corX[i][j + NSECT] = extract_h( L_shr( Ltmp, qCorX - 31 ) ); -#endif /* BASOP_NOGLOB */ - qCorX = 31; + Ltmp = Mpy_32_16_1( enr1, cor_buf[ind1 + len_x] ); + corX[i][j + NSECT] = extract_h( L_shl_o( Ltmp, add( enr1_exp, cor_buf_exp[ind1 + len_x] ), &Overflow ) ); // Q15 move16(); - Ltmp = L_mult0( pt_cor0[ind1 + ( DELTA_COH - 1 ) + len_x], enr1 ); - qScaledX = add( sub( 15, enr1_exp ), sub( 14, pt_exp3[ind1] ) ); - scaledX[i][j + NSECT] = round_fx( L_shl( Ltmp, sub( 16 + 12, qScaledX ) ) ); - /*scaledX[i][j+NSECT] = saturate(L_shr(Ltmp, qScaledX-12));*/ - qScaledX = 12; + Ltmp = Mpy_32_16_1( enr1, pt_cor0[ind1 + ( DELTA_COH - 1 ) + len_x] ); + scaledX[i][j + NSECT] = round_fx( L_shl( Ltmp, sub( add( enr1_exp, pt_cor0_exp[ind1 + ( DELTA_COH - 1 ) + len_x] ), 3 ) ) ); // Q12 move16(); + /*scaledX[i][j+NSECT] = saturate(L_shr(Ltmp, qScaledX-12));*/ pt_cor3 += sec_length1[j]; - move16(); + pt_cor3_exp += sec_length1[j]; offset1 = add( offset1, sec_length1[j] ); } /* FOR j < NSECT */ @@ -2025,11 +1818,7 @@ void pitch_ol_ivas_fx( move16(); pitch_tmp[i] = pitchX[i][ind]; move16(); -#ifdef BASOP_NOGLOB cor_tmp[i] = add_o( corX[i][ind], corr_shift, &Overflow ); -#else /* BASOP_NOGLOB */ - cor_tmp[i] = add( corX[i][ind], corr_shift ); -#endif /* BASOP_NOGLOB */ move16(); /* Higher is the neighbour's correlation, higher is the weighting */ @@ -2043,11 +1832,7 @@ void pitch_ol_ivas_fx( move16(); pitch_tmp[i + NHFR] = pitchX[i][ind1]; move16(); -#ifdef BASOP_NOGLOB cor_tmp[i + NHFR] = add_o( corX[i][ind1], corr_shift, &Overflow ); -#else /* BASOP_NOGLOB */ - cor_tmp[i + NHFR] = add( corX[i][ind1], corr_shift ); -#endif move16(); /* Higher is the neighbour's correlation, higher is the weighting */ @@ -2109,8 +1894,8 @@ void pitch_ol_ivas_fx( /* all Q15 here */ /* cor_mean = 0.5f * (voicing[0] + voicing[1]) + corr_shift; */ - Ltmp = L_mult( voicing[0], 16384 ); - Ltmp = L_mac( Ltmp, voicing[1], 16384 ); + Ltmp = L_mult( voicing[0], 16384 /*.5 Q15*/ ); + Ltmp = L_mac( Ltmp, voicing[1], 16384 /*.5 Q15*/ ); cor_mean = round_fx( L_add( Ltmp, corr_shift ) ); /* pitch unstable in present frame or from previous frame or normalized correlation too low */ @@ -2132,10 +1917,11 @@ void pitch_ol_ivas_fx( { /* The threshold increase is directly dependent on normalized correlation */ /* *old_thres += (0.16f * cor_mean); */ - *old_thres = round_fx( L_mac( L_deposit_h( *old_thres ), 5243, cor_mean ) ); + *old_thres = round_fx( L_mac0( L_deposit_h( *old_thres ), 5243 /* 0.16f in Q15 */, cor_mean ) ); // Q14 + move16(); } - *old_thres = s_min( *old_thres, THRES3 ); + *old_thres = s_min( *old_thres, 11469 /* 0.7f in Q14 */ ); // Q14 move16(); IF( GT_16( voicing[1], voicing[0] ) ) @@ -2194,13 +1980,13 @@ void pitch_ol_ivas_fx( /* *delta_pit /= 3; */ if ( k < 0 ) { - *delta_pit = mult( *delta_pit, -32768 ); + *delta_pit = mult( *delta_pit, -32768 /*-1 Q15*/ ); move16(); } - tmp16 = mult( *delta_pit, 10923 ); + tmp16 = mult( *delta_pit, 10923 /*1/3 Q15*/ ); if ( k < 0 ) { - tmp16 = mult( tmp16, -32768 ); + tmp16 = mult( tmp16, -32768 /*-1 Q15*/ ); } *delta_pit = tmp16; move16(); @@ -2254,7 +2040,7 @@ static void find_mult_fx( L_tmp = L_shl( L_mult( *corr, *fac ), 3 ); /* if ( *old_corr < 0.6f || (float)pitch0 > (float)*old_pitch * 0.4f ) */ - IF( s_max( sub( 19660, *old_corr ), sub( pitch0, mult( *old_pitch, 13107 ) ) ) > 0 ) + IF( s_max( sub( 19660 /*.6 Q15*/, *old_corr ), sub( pitch0, mult( *old_pitch, 13107 /*.4 Q15*/ ) ) ) > 0 ) { /* reinforce the normalized correlation */ /* operands are Q12, result is Q12 */ @@ -2325,7 +2111,7 @@ static void pitch_neighbour_fx( { /* corr[i][k] *= ( -thres1[j]/DELTA1 * 0.625f * delta + 0.625f * thres1[j] +1.0f ); */ fac = mult( negate( thres1[j] ), 20479 / DELTA_COH ); - fac = add( i_mult2( fac, delta ), mult( 20479, thres1[j] ) ); + fac = add( i_mult2( fac, delta ), mult( 20479 /*.625 Q15*/, thres1[j] ) ); } corr[i][k] = add_sat( corr[i][k], mult( fac, corr[i][k] ) ); move16(); @@ -2448,7 +2234,7 @@ static void LP_Decim2_Copy( *p_x++ = x[i]; move16(); } - if ( l & 1 ) /* Fix for valgrind error in case l is odd. Anyway this function will be removed. */ + if ( s_and( l, 1 ) ) /* Fix for valgrind error in case l is odd. Anyway this function will be removed. */ { *p_x = *( p_x - 1 ); move16(); @@ -2472,6 +2258,7 @@ static void LP_Decim2_Copy( p_x += 2; y[j++] = round_fx( L_tmp ); + move16(); } } /*---------------------------------------------------------------------* @@ -2534,7 +2321,7 @@ static Word32 Dot_product12_OL( /* o : Q31: normalized result move16(); /* exponent = 0..30 */ *sum1 = extract_h( L_shr( L_sum2, 1 ) ); - + move16(); return L_sum; } @@ -2598,7 +2385,7 @@ static Word32 Dot_product12_OL_back( /* o : Q31: normalized r move16(); /* exponent = 0..30 */ *sum1 = extract_h( L_shr( L_sum2, 1 ) ); - + move16(); return L_sum; } diff --git a/lib_enc/plc_enc_ext.c b/lib_enc/plc_enc_ext.c deleted file mode 100644 index 404ee401e163c860087111a920728c667c5c4e14..0000000000000000000000000000000000000000 --- a/lib_enc/plc_enc_ext.c +++ /dev/null @@ -1,43 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include "prot.h" -#include "stat_enc.h" -#include "cnst.h" -#include "rom_com.h" -#include "wmc_auto.h" diff --git a/lib_enc/plc_enc_ext_fx.c b/lib_enc/plc_enc_ext_fx.c index 56598be2f5ab0342173145bfc314929340d29f4e..97e3fd4bc44ca91ab63acb69b5f914d01f747e93 100644 --- a/lib_enc/plc_enc_ext_fx.c +++ b/lib_enc/plc_enc_ext_fx.c @@ -82,6 +82,9 @@ void init_PLC_enc_fx( hPlcExt->lsf_con[itr] = add( lsf_init_fx[itr], shr( lsf_init_fx[itr], 2 ) ); hPlcExt->last_lsf_ref[itr] = add( lsf_init_fx[itr], shr( lsf_init_fx[itr], 2 ) ); hPlcExt->last_lsf_con[itr] = add( lsf_init_fx[itr], shr( lsf_init_fx[itr], 2 ) ); + move16(); + move16(); + move16(); } } diff --git a/lib_enc/ppp_enc.c b/lib_enc/ppp_enc.c deleted file mode 100644 index d1de09bc73bcde0f9193c0b1d468183cb122cda9..0000000000000000000000000000000000000000 --- a/lib_enc/ppp_enc.c +++ /dev/null @@ -1,43 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include -#include "cnst.h" -#include "prot.h" -#include "rom_com.h" -#include "wmc_auto.h" diff --git a/lib_enc/ppp_enc_fx.c b/lib_enc/ppp_enc_fx.c index 3e5de17fa033d09164281b096fe1819354c3d15e..9afb27065559b4746745352c09b11dace1f3ed88 100644 --- a/lib_enc/ppp_enc_fx.c +++ b/lib_enc/ppp_enc_fx.c @@ -5,7 +5,6 @@ #include #include "options.h" #include "cnst.h" -//#include "prot_fx.h" #include "rom_com_fx.h" #include "rom_com.h" /* Common constants */ #include "prot_fx.h" /* Function prototypes */ @@ -153,10 +152,12 @@ ivas_error ppp_quarter_encoder_fx( /*As the upper cut of freqencies are normalized to 12800, we have to multiply upper cut off freq by 2.56(1/12800 in Q15) */ - Ltempn = L_mult( CURRCW_Q_FX->upper_cut_off_freq_fx, 10486 ); /* Q0+Q27 = Q28 */ - CURRCW_Q_FX->upper_cut_off_freq_fx = (Word16) L_shr( Ltempn, 13 ); /*Q15 */ + Ltempn = L_mult( CURRCW_Q_FX->upper_cut_off_freq_fx, 10486 ); /* Q0+Q27 = Q28 */ + CURRCW_Q_FX->upper_cut_off_freq_fx = (Word16) L_shr( Ltempn, 13 ); /*Q15 */ + move16(); Ltempn = L_mult( CURRCW_Q_FX->upper_cut_off_freq_of_interest_fx, 10486 ); /* Q0+Q27 = Q28 */ CURRCW_Q_FX->upper_cut_off_freq_of_interest_fx = (Word16) L_shr( Ltempn, 13 ); /*Q15 */ + move16(); *returnFlag = DTFS_quant_cw_fx( CURRCW_Q_FX, prevCW_lag, curr_lpc_fx, &POWER_IDX_FX, AMP_IDX_fx, lastLgainE_fx, lastHgainE_fx, lasterbE_fx, S_fx, C_fx ); @@ -168,6 +169,7 @@ ivas_error ppp_quarter_encoder_fx( move16(); Ltempn = L_shl( (Word32) CURRCW_Q_FX->upper_cut_off_freq_of_interest_fx, 13 ); /*Q28 */ CURRCW_Q_FX->upper_cut_off_freq_of_interest_fx = (Word16) find_remd( Ltempn, 20971, &Ltempd ); + move16(); push_indice_fx( hBstr, IND_AMP0, AMP_IDX_fx[0], 6 ); push_indice_fx( hBstr, IND_AMP1, AMP_IDX_fx[1], 6 ); @@ -184,10 +186,9 @@ ivas_error ppp_quarter_encoder_fx( /*DTFS_pol2car(TARGETCW); */ tmp_fx = DTFS_alignment_fine_new_fx( *TARGETCW_FX, *CURRCW_Q_FX, S_fx, C_fx ); - move16(); test(); - IF( GT_16( add( tmp_fx, 12 ), 28 ) || LT_16( tmp_fx, -12 ) ) + IF( GT_16( tmp_fx, 28 - 12 ) || LT_16( tmp_fx, -12 ) ) { tmp_fx = 0; move16(); @@ -227,9 +228,9 @@ void set_ppp_mode_fx( test(); test(); - IF( EQ_16( st_fx->vad_flag, 1 ) && - ( EQ_16( noisy_speech_HO, 1 ) || EQ_16( clean_speech_HO, 1 ) || EQ_16( NB_speech_HO, 1 ) ) && - ( st_fx->localVAD == 0 || localVAD_he == 0 ) ) + if ( EQ_16( st_fx->vad_flag, 1 ) && + ( EQ_16( noisy_speech_HO, 1 ) || EQ_16( clean_speech_HO, 1 ) || EQ_16( NB_speech_HO, 1 ) ) && + ( st_fx->localVAD == 0 || localVAD_he == 0 ) ) { st_fx->coder_type = UNVOICED; @@ -238,7 +239,7 @@ void set_ppp_mode_fx( test(); test(); - IF( EQ_16( st_fx->coder_type, INACTIVE ) && ( st_fx->vad_flag == 0 ) && EQ_16( hSC_VBR->last_nelp_mode, 1 ) ) /* avoid HO frame go to GSC */ + if ( EQ_16( st_fx->coder_type, INACTIVE ) && ( st_fx->vad_flag == 0 ) && EQ_16( hSC_VBR->last_nelp_mode, 1 ) ) /* avoid HO frame go to GSC */ { st_fx->coder_type = UNVOICED; move16(); @@ -315,7 +316,7 @@ void set_ppp_mode_fx( move16(); } - IF( st_fx->last_core == HQ_CORE ) + IF( EQ_16( st_fx->last_core, HQ_CORE ) ) { hSC_VBR->ppp_mode = 0; move16(); @@ -329,7 +330,7 @@ void set_ppp_mode_fx( test(); test(); test(); - IF( ( hSC_VBR->last_ppp_mode != 0 ) && ( hSC_VBR->ppp_mode == 0 ) && ( st_fx->sp_aud_decision1 != 0 ) && EQ_16( st_fx->bwidth, NB ) && st_fx->Opt_SC_VBR != 0 ) /*if it were about to go from ppp->HQ*/ + IF( ( hSC_VBR->last_ppp_mode != 0 ) && ( hSC_VBR->ppp_mode == 0 ) && ( st_fx->sp_aud_decision1 != 0 ) && ( st_fx->bwidth == NB ) && ( st_fx->Opt_SC_VBR != 0 ) ) /*if it were about to go from ppp->HQ*/ { hSC_VBR->avoid_HQ_VBR_NB = 1; move16(); @@ -340,7 +341,7 @@ void set_ppp_mode_fx( test(); test(); test(); - IF( ( hSC_VBR->last_nelp_mode != 0 ) && ( st_fx->sp_aud_decision1 != 0 ) && EQ_16( st_fx->bwidth, NB ) && ( st_fx->Opt_SC_VBR != 0 ) ) /*if it were about to go from nelp->HQ*/ + IF( ( hSC_VBR->last_nelp_mode != 0 ) && ( st_fx->sp_aud_decision1 != 0 ) && ( st_fx->bwidth == NB ) && ( st_fx->Opt_SC_VBR != 0 ) ) /*if it were about to go from nelp->HQ*/ { hSC_VBR->avoid_HQ_VBR_NB = 1; move16(); @@ -412,6 +413,7 @@ static Word16 DTFS_quant_cw_fx( { Word16 num_erb = 0; + move16(); const Word16 *PowerCB_fx = NULL; Word16 tmp, w[2], target[2], j, slot[NUM_ERB_WB], flag; Word16 n, d1, d2, exp; @@ -439,7 +441,6 @@ static Word16 DTFS_quant_cw_fx( num_erb = NUM_ERB_WB; move16(); PowerCB_fx = PowerCB_WB_fx; - move16(); } /* Get weighting and target */ @@ -500,10 +501,10 @@ static Word16 DTFS_quant_cw_fx( erb_add_fx( curr_erb_fx, X_fx->lag_fx, lasterbE_fx, pl, AMP_IDX, num_erb ); curr_erb_fx[0] = mult_r( curr_erb_fx[1], 9830 ); - move16(); /* 0.3 inQ15 leaves curr_erb in Q13 */ - curr_erb_fx[sub( num_erb, 2 )] = mult_r( curr_erb_fx[sub( num_erb, 3 )], 9830 ); /* Q13 */ + move16(); /* 0.3 inQ15 leaves curr_erb in Q13 */ + curr_erb_fx[num_erb - 2] = mult_r( curr_erb_fx[num_erb - 3], 9830 ); /* Q13 */ - curr_erb_fx[sub( num_erb, 1 )] = 0; + curr_erb_fx[num_erb - 1] = 0; move16(); flag = 1; move16(); @@ -553,9 +554,11 @@ static Word16 DTFS_quant_cw_fx( ELSE IF( n > 0 ) rshiftHarmBand_fx( X_fx, 0, 2828, sub( Qh, Ql ) ); - tmp = shl( *POWER_IDX, 1 ); /* tmp=2*POWER_IDX */ - *lastLgainE_fx = add( *lastLgainE_fx, PowerCB_fx[tmp] ); /* Q11 */ + tmp = shl( *POWER_IDX, 1 ); /* tmp=2*POWER_IDX */ + *lastLgainE_fx = add( *lastLgainE_fx, PowerCB_fx[tmp] ); /* Q11 */ + move16(); *lastHgainE_fx = add( *lastHgainE_fx, PowerCB_fx[tmp + 1] ); /* Q11 */ + move16(); Ltemp = log10_fx( X_fx->lag_fx ); /* Ltemp=10*log10(lag), Q23 */ logLag_fx = Mult_32_16( Ltemp, 0x6666 ); /* logLag=log10(lag), Q26 */ @@ -621,6 +624,7 @@ static Word16 DTFS_alignment_fine_new_fx( DTFS_STRUCTURE X1_fx, DTFS_STRUCTURE X Word32 maxcorr_fx, wcorr_fx, diff_corr; #ifdef BASOP_NOGLOB_DECLARE_LOCAL Flag Overflow = 0; + move16(); #endif IF( LT_16( X1_fx.lag_fx, X2_fx.lag_fx ) ) { @@ -635,7 +639,9 @@ static Word16 DTFS_alignment_fine_new_fx( DTFS_STRUCTURE X1_fx, DTFS_STRUCTURE X FOR( k = 0; k <= HalfLag; k++ ) { ab1[k] = round_fx( L_mac( L_mult( X1_fx.a_fx[k], X2_fx.a_fx[k] ), X1_fx.b_fx[k], X2_fx.b_fx[k] ) ); + move16(); ab2[k] = round_fx( L_msu( L_mult( X1_fx.b_fx[k], X2_fx.a_fx[k] ), X1_fx.a_fx[k], X2_fx.b_fx[k] ) ); + move16(); } @@ -657,15 +663,9 @@ static Word16 DTFS_alignment_fine_new_fx( DTFS_STRUCTURE X1_fx, DTFS_STRUCTURE X FOR( k = 0; k <= HalfLag; k++ ) { -#ifdef BASOP_NOGLOB corr_fx = L_mac_o( corr_fx, ab1[k], C_fx[temp % ( 4 * X2_fx.lag_fx )], &Overflow ); corr_fx = L_mac_o( corr_fx, ab2[k], S_fx[temp % ( 4 * X2_fx.lag_fx )], &Overflow ); temp = add_o( temp, temp1, &Overflow ); -#else - corr_fx = L_mac( corr_fx, ab1[k], C_fx[temp % ( 4 * X2_fx.lag_fx )] ); - corr_fx = L_mac( corr_fx, ab2[k], S_fx[temp % ( 4 * X2_fx.lag_fx )] ); - temp = add( temp, temp1 ); -#endif } temp = sub( 32767, extract_l( L_shr( L_mult( 82, abs_s( n ) ), 1 ) ) ); /* Q15 */ Qcorr = norm_l( corr_fx ); @@ -675,40 +675,23 @@ static Word16 DTFS_alignment_fine_new_fx( DTFS_STRUCTURE X1_fx, DTFS_STRUCTURE X move16(); } -#ifdef BASOP_NOGLOB temp1 = round_fx_o( (Word32) L_shl_o( corr_fx, Qcorr, &Overflow ), &Overflow ); /* Q(Qcorr-16) */ wcorr_fx = L_mult_o( temp1, temp, &Overflow ); /* Q(Qcorr-16+15+1)=Q(Qcorr) */ -#else - temp1 = round_fx( (Word32) L_shl( corr_fx, Qcorr ) ); /* Q(Qcorr-16) */ - wcorr_fx = L_mult( temp1, temp ); /* Q(Qcorr-16+15+1)=Q(Qcorr) */ -#endif IF( GE_16( Qmaxcorr, Qcorr ) ) { -#ifdef BASOP_NOGLOB diff_corr = L_sub_o( wcorr_fx, L_shl_o( maxcorr_fx, sub( Qcorr, Qmaxcorr ), &Overflow ), &Overflow ); /* Qcorr */ -#else - diff_corr = L_sub( wcorr_fx, L_shl( maxcorr_fx, sub( Qcorr, Qmaxcorr ) ) ); /* Qcorr */ -#endif } ELSE { -#ifdef BASOP_NOGLOB diff_corr = L_sub_o( L_shl_o( wcorr_fx, sub( Qmaxcorr, Qcorr ), &Overflow ), maxcorr_fx, &Overflow ); /* Qmaxcorr */ -#else - diff_corr = L_sub( L_shl( wcorr_fx, sub( Qmaxcorr, Qcorr ) ), maxcorr_fx ); /* Qmaxcorr */ -#endif } if ( diff_corr > 0 ) { fshift_fx = n; move16(); -#ifdef BASOP_NOGLOB maxcorr_fx = (Word32) L_shl_o( corr_fx, Qcorr, &Overflow ); /* Qcorr */ -#else - maxcorr_fx = (Word32) L_shl( corr_fx, Qcorr ); /* Qcorr */ -#endif Qmaxcorr = Qcorr; move16(); } @@ -758,6 +741,7 @@ static void LPCPowSpect_fx( Word16 tmp, exp; #ifdef BASOP_NOGLOB_DECLARE_LOCAL Flag Overflow = 0; + move16(); #endif FOR( k = 0; k < Nf; k++ ) { @@ -789,17 +773,11 @@ static void LPCPowSpect_fx( t1 = add( t1, (Word16) L_shr( Ltemp, 16 ) ); /* t1 is interpolated cos(w) */ Ltemp = L_shr( L_mult( LPC[i], t1 ), 1 ); /* Ltemp in Q27 */ -#ifdef BASOP_NOGLOB - Re = L_add_o( Re, Ltemp, &Overflow ); /* Re=1-sum(LPC[i]*cos(Lw)); */ - Ltemp = L_add_o( Lw, 0x6000, &Overflow ); /* add 0.75, which is 3pi/2 to convert sin to cos */ - Ltemp = L_shl_o( Ltemp, 10, &Overflow ); /* Q25 */ -#else - Re = L_add( Re, Ltemp ); /* Re=1-sum(LPC[i]*cos(Lw)); */ - Ltemp = L_add( Lw, 0x6000 ); /* add 0.75, which is 3pi/2 to convert sin to cos */ - Ltemp = L_shl( Ltemp, 10 ); /* Q25 */ -#endif - w = extract_h( Ltemp ); /* w is equivalent cos index */ - dl = extract_l( Ltemp ); /* dl is 6 bit left-over for interpolation */ + Re = L_add_o( Re, Ltemp, &Overflow ); /* Re=1-sum(LPC[i]*cos(Lw)); */ + Ltemp = L_add_o( Lw, 0x6000, &Overflow ); /* add 0.75, which is 3pi/2 to convert sin to cos */ + Ltemp = L_shl_o( Ltemp, 10, &Overflow ); /* Q25 */ + w = extract_h( Ltemp ); /* w is equivalent cos index */ + dl = extract_l( Ltemp ); /* dl is 6 bit left-over for interpolation */ w = s_and( w, 511 ); t1 = cos_table[w]; /*t2=cos_table[s_and(add(w,1),511)]; */ @@ -819,13 +797,8 @@ static void LPCPowSpect_fx( t1 = add( t1, (Word16) L_shr( Ltemp, 16 ) ); /* t1 is interpolated cos(w) */ Ltemp = L_shr( L_mult( LPC[i], t1 ), 1 ); /* Ltemp in Q27 */ -#ifdef BASOP_NOGLOB - Im = L_sub_o( Im, Ltemp, &Overflow ); /* Im=sum(LPC[i]*sin(Lw)) */ - Lw = L_add_o( Lw, freq[k], &Overflow ); /* Lw=(i+1)*freq[k] */ -#else - Im = L_sub( Im, Ltemp ); /* Im=sum(LPC[i]*sin(Lw)) */ - Lw = L_add( Lw, freq[k] ); /* Lw=(i+1)*freq[k] */ -#endif + Im = L_sub_o( Im, Ltemp, &Overflow ); /* Im=sum(LPC[i]*sin(Lw)) */ + Lw = L_add_o( Lw, freq[k], &Overflow ); /* Lw=(i+1)*freq[k] */ } /* If necessary, we can block-normalize Re and Im to improve precision */ dh = extract_h( Re ); @@ -840,11 +813,7 @@ static void LPCPowSpect_fx( ELSE Lacc = L_mult0( dh, dl ); -#ifdef BASOP_NOGLOB Lacc = L_add_o( L_shr( Lacc, 15 ), L_shr( L_mult_o( dh, dh, &Overflow ), 1 ), &Overflow ); /* Lacc=Re*Re */ -#else - Lacc = L_add( L_shr( Lacc, 15 ), L_shr( L_mult( dh, dh ), 1 ) ); /* Lacc=Re*Re */ -#endif dh = extract_h( Im ); dl = extract_l( Im ); @@ -875,11 +844,8 @@ static void LPCPowSpect_fx( move16(); } Ltemp = L_deposit_h( tmp ); -#ifdef BASOP_NOGLOB out[k] = round_fx_o( L_shl_o( Ltemp, negate( add( exp, 8 ) ), &Overflow ), &Overflow ); -#else - out[k] = round_fx( L_shl( Ltemp, negate( add( exp, 8 ) ) ) ); -#endif + move16(); /* out[k] = shl(tmp,-exp-8); in Q7 */ } @@ -981,7 +947,7 @@ static void erb_diff_fx( tmp = t_prev_erb[num_erb - 1]; move16(); - FOR( i = sub( num_erb, 1 ); i >= 0; i-- ) + FOR( i = num_erb - 1; i >= 0; i-- ) { IF( pslot[i] != 0 ) { diff --git a/lib_enc/pre_proc.c b/lib_enc/pre_proc.c deleted file mode 100644 index dc0d098987194e4ae0ac1c7dc0b7b2d50ec319d2..0000000000000000000000000000000000000000 --- a/lib_enc/pre_proc.c +++ /dev/null @@ -1,46 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include "cnst.h" -#include "rom_enc.h" -#include "rom_com.h" -#include "prot.h" -#include "wmc_auto.h" - -#include "prot_fx.h" -#include "prot_fx_enc.h" diff --git a/lib_enc/pre_proc_fx.c b/lib_enc/pre_proc_fx.c index 12b09c9ebc1a4425ce6af05c4b2dafafae6786b1..4ce9403a6e22ca5fc9ceef17563a8f6322260495 100644 --- a/lib_enc/pre_proc_fx.c +++ b/lib_enc/pre_proc_fx.c @@ -6,7 +6,6 @@ #include "options.h" #include "cnst.h" #include "rom_com_fx.h" -//#include "prot_fx.h" #include "rom_com.h" /* Common constants */ #include "prot_fx.h" /* Function prototypes */ #include "prot_fx_enc.h" /* Function prototypes */ @@ -106,6 +105,8 @@ void pre_proc_fx( Word16 fft_buff[2 * L_FFT]; Word16 sp_floor; Word16 freqTable_local[2] = { 20, 40 }; + move16(); + move16(); Word16 last_core_orig; Word16 headroom; Word16 cldfb_addition = 0; @@ -127,6 +128,7 @@ void pre_proc_fx( #ifdef BASOP_NOGLOB_DECLARE_LOCAL Flag Overflow = 0; + move16(); #endif /*------------------------------------------------------------------* @@ -206,6 +208,7 @@ void pre_proc_fx( analysisCldfbEncoder_fx( st, signal_in, realBuffer, imagBuffer, realBuffer16, imagBuffer16, enerBuffer, &enerBuffer_exp, cldfbScale ); cldfbScale->hb_scale = cldfbScale->lb_scale; + move16(); /*----------------------------------------------------------------* * Change the sampling frequency to 12.8 kHz @@ -227,7 +230,7 @@ void pre_proc_fx( test(); /* reserve an extra bit of headroom in case of NB coding and if there is a chance of energy above 4 kHz */ /* st->bwidth refers to the coded bandwidth of the previous frame */ - if ( ( ( EQ_16( st->bwidth, NB ) ) || ( EQ_16( st->max_bwidth, NB ) ) ) && ( GT_32( st->input_Fs, 8000 ) ) ) + if ( ( ( st->bwidth == NB ) || ( st->max_bwidth == NB ) ) && ( GT_32( st->input_Fs, 8000 ) ) ) { headroom = add( headroom, 1 ); } @@ -251,11 +254,7 @@ void pre_proc_fx( * Spectral analysis *--------------------------------------------------------------------------*/ - analy_sp_fx( -1, -#ifdef IVAS_CODE_CPE - NULL, -#endif - st->input_Fs, inp_12k8, *Q_new, fr_bands, lf_E, Etot, st->min_band, st->max_band, Le_min_scaled, Scale_fac, st->Bin_E_fx, st->Bin_E_old_fx, + analy_sp_fx( -1, inp_12k8, *Q_new, fr_bands, lf_E, Etot, st->min_band, st->max_band, Le_min_scaled, Scale_fac, st->Bin_E_fx, st->Bin_E_old_fx, PS, st->lgBin_E_fx, st->band_energies, fft_buff ); st->band_energies_exp = sub( sub( WORD32_BITS - 1, *Q_new ), QSCALE ); @@ -277,7 +276,7 @@ void pre_proc_fx( { /* Combine decisions from SADS */ test(); - IF( EQ_16( st->vad_flag, 1 ) && vad_flag_cldfb == 0 ) + if ( EQ_16( st->vad_flag, 1 ) && vad_flag_cldfb == 0 ) { st->localVAD = 0; move16(); @@ -486,7 +485,6 @@ void pre_proc_fx( move16(); } - move16(); /*------------------------------------------------------------------* * Update estimated noise energy and voicing cut-off frequency @@ -495,9 +493,6 @@ void pre_proc_fx( noise_est_fx( st, old_pitch1, tmpN, epsP_h, epsP_l, *Etot, relE, corr_shift, tmpE, fr_bands, &cor_map_sum, NULL, &sp_div, &Q_sp_div, &non_staX, &loc_harm, lf_E, &hNoiseEst->harm_cor_cnt, hNoiseEst->Etot_l_lp_fx, hNoiseEst->Etot_v_h2_fx, &hNoiseEst->bg_cnt, st->lgBin_E_fx, *Q_new, Le_min_scaled, &sp_floor, NULL, -#ifdef IVAS_CODE - NULL, NULL, -#endif st->ini_frame ); /*------------------------------------------------------------------* @@ -514,43 +509,43 @@ void pre_proc_fx( st->max_band, hp_E, st->codec_mode, *Q_new, &( st->bckr_tilt_lt ), st->Opt_SC_VBR ); st->coder_type = find_uv_fx( st, pitch_fr, voicing_fr, inp_12k8, ee, -#ifdef IVAS_CODE - NULL, -#endif - corr_shift, relE, *Etot, hp_E, *Q_new, &flag_spitch, *shift, last_core_orig -#ifdef IVAS_CODE - , - NULL -#endif - ); + corr_shift, relE, *Etot, hp_E, *Q_new, &flag_spitch, *shift, last_core_orig ); /*----------------------------------------------------------------* * channel aware mode configuration * *-----------------------------------------------------------------*/ test(); test(); - test(); IF( !st->Opt_RF_ON ) { st->rf_mode = 0; + move16(); st->rf_target_bits_write = 0; + move16(); } - ELSE IF( st->rf_mode && NE_32( st->core_brate, FRAME_NO_DATA ) && NE_32( st->core_brate, SID_2k40 ) ) + ELSE IF( st->rf_mode && st->core_brate != FRAME_NO_DATA && NE_32( st->core_brate, SID_2k40 ) ) { /* the RF config is for (n- fec_offset)th frame that will be packed along with the n-th frame bitstream */ st->rf_mode = 1; + move16(); st->codec_mode = MODE2; + move16(); st->rf_target_bits_write = hRF->rf_targetbits_buff[st->rf_fec_offset]; + move16(); } ELSE { st->rf_mode = 0; + move16(); st->codec_mode = MODE1; + move16(); IF( st->Opt_RF_ON ) { hRF->rf_indx_frametype[0] = RF_NO_DATA; + move16(); hRF->rf_targetbits_buff[0] = 6; /* rf_mode: 1, rf_frame_type: 3, and fec_offset: 2 */ + move16(); } } @@ -588,12 +583,7 @@ void pre_proc_fx( speech_music_classif_fx( st, new_inp_12k8, inp_12k8, localVAD_HE_SAD, lsp_new, cor_map_sum, epsP, PS, *Etot, old_cor, attack_flag, non_staX, relE, Q_esp, *Q_new, &high_lpn_flag, flag_spitch ); - long_enr_fx( st, *Etot, localVAD_HE_SAD, high_lpn_flag -#ifdef IVAS_CODE - , - NULL, 1, NULL, NULL -#endif - ); /* has to be after after sp_music classfier */ + long_enr_fx( st, *Etot, localVAD_HE_SAD, high_lpn_flag ); /* has to be after after sp_music classfier */ /*----------------------------------------------------------------* * Rewrite the VAD flag by VAD flag with DTX hangover for further processing) @@ -625,7 +615,7 @@ void pre_proc_fx( test(); test(); test(); - IF( EQ_32( st->core_brate, FRAME_NO_DATA ) ) + IF( st->core_brate == FRAME_NO_DATA ) { /* prevent "L_frame" changes in CNG segments */ st->L_frame = st->last_L_frame; @@ -672,9 +662,11 @@ void pre_proc_fx( } st->sr_core = L_mult0( FRAMES_PER_SEC, st->L_frame ); + move32(); st->encoderLookahead_enc = NS2SA_FX2( st->sr_core, ACELP_LOOK_NS ); move16(); st->encoderPastSamples_enc = shr( imult1616( st->L_frame, 9 ), 4 ); + move16(); } /*-----------------------------------------------------------------* @@ -699,7 +691,7 @@ void pre_proc_fx( test(); test(); test(); - IF( NE_16( st->last_L_frame, st->L_frame ) && NE_32( st->core_brate, FRAME_NO_DATA ) && NE_32( st->core_brate, SID_2k40 ) && ( NE_16( st->coder_type_raw, VOICED ) ) ) + IF( NE_16( st->last_L_frame, st->L_frame ) && st->core_brate != FRAME_NO_DATA && NE_32( st->core_brate, SID_2k40 ) && ( NE_16( st->coder_type_raw, VOICED ) ) ) { /* enforce TC frame in case of ACELP@12k8 <-> ACELP@16k core switching */ st->coder_type = TRANSITION; @@ -826,12 +818,14 @@ void pre_proc_fx( { SetModeIndex_fx( st, st->last_total_brate, EVS_MONO, 0, *shift ); st->sr_core = getCoreSamplerateMode2( st->element_mode, st->total_brate, st->bwidth, st->flag_ACELP16k, st->rf_mode, 0 ); - + move32(); Mpy_32_16_ss( st->sr_core, 5243, &L_tmp, &lsb ); /* 5243 is 1/50 in Q18. (0+18-15=3) */ st->L_frame = extract_l( L_shr( L_tmp, 3 ) ); /* Q0 */ + move16(); st->encoderLookahead_enc = NS2SA_FX2( st->sr_core, ACELP_LOOK_NS ); move16(); st->encoderPastSamples_enc = shr( imult1616( st->L_frame, 9 ), 4 ); + move16(); assert( st->L_frame == st->sr_core / 50 ); IF( EQ_32( st->sr_core, INT_FS_12k8 ) ) @@ -882,7 +876,9 @@ void pre_proc_fx( IF( EQ_32( st->total_brate, ACELP_32k ) && EQ_16( loc_harm, 1 ) && GT_16( cor_map_sum, 50 << 8 ) && EQ_16( st->clas, VOICED_CLAS ) && EQ_16( st->coder_type, GENERIC ) ) { st->last_harm_flag_acelp = add( st->last_harm_flag_acelp, 1 ); + move16(); st->last_harm_flag_acelp = s_min( st->last_harm_flag_acelp, 10 ); + move16(); } ELSE { @@ -897,14 +893,18 @@ void pre_proc_fx( IF( EQ_16( st->coder_type, AUDIO ) ) { st->audio_frame_cnt = add( st->audio_frame_cnt, AUDIO_COUNTER_STEP ); + move16(); } - ELSE IF( NE_16( st->coder_type, INACTIVE ) ) + ELSE IF( st->coder_type != INACTIVE ) { st->audio_frame_cnt = sub( st->audio_frame_cnt, 1 ); + move16(); } st->audio_frame_cnt = s_min( st->audio_frame_cnt, AUDIO_COUNTER_MAX ); + move16(); st->audio_frame_cnt = s_max( st->audio_frame_cnt, 0 ); + move16(); /*-----------------------------------------------------------------* * Set formant sharpening flag @@ -959,9 +959,10 @@ void pre_proc_fx( /* channel-aware mode - due to lack of signalling bit, sharpFlag is 1 always in RF mode */ test(); test(); - IF( EQ_16( st->rf_mode, 1 ) && ( EQ_16( st->coder_type, VOICED ) || EQ_16( st->coder_type, GENERIC ) ) ) + if ( EQ_16( st->rf_mode, 1 ) && ( EQ_16( st->coder_type, VOICED ) || EQ_16( st->coder_type, GENERIC ) ) ) { st->sharpFlag = 1; + move16(); } /*-----------------------------------------------------------------* @@ -995,8 +996,7 @@ void pre_proc_fx( L_frame_tmp = L_FRAME16k; move16(); } - L_look = NS2SA_FX2( sr_core_tmp, ACELP_LOOK_NS ); - move16(); /* lookahead at other sampling rate (16kHz, 25.5kHz, 32kHz) */ + L_look = NS2SA_FX2( sr_core_tmp, ACELP_LOOK_NS ); /* lookahead at other sampling rate (16kHz, 25.5kHz, 32kHz) */ new_inp_16k = old_inp_16k + L_INP_MEM; /* pointer to new samples of the input signal in 16kHz core */ inp_16k = new_inp_16k - L_look; /* pointer to the current frame of input signal in 16kHz core */ @@ -1047,11 +1047,8 @@ void pre_proc_fx( test(); IF( ( ( st->tcxonly == 0 ) || ( EQ_16( st->codec_mode, MODE1 ) ) ) && GT_32( st->input_Fs, 8000 ) ) { -#ifdef BASOP_NOGLOB st->mem_preemph_enc = shl_o( new_inp_16k[sub( L_frame_tmp, 1 )], 1, &Overflow ); -#else /* BASOP_NOGLOB */ - st->mem_preemph_enc = shl( new_inp_16k[sub( L_frame_tmp, 1 )], 1 ); -#endif + move16(); } test(); @@ -1061,7 +1058,7 @@ void pre_proc_fx( } ELSE IF( GT_32( st->input_Fs, 8000 ) ) /* keep memory up-to-date in case of bit-rate switching */ { - st->mem_preemph16k_fx = new_inp_16k[sub( L_frame_tmp, 1 )]; + st->mem_preemph16k_fx = new_inp_16k[L_frame_tmp - 1]; move16(); } @@ -1075,7 +1072,7 @@ void pre_proc_fx( test(); test(); test(); - IF( ( ( ( st->tcxonly == 0 ) || !( NE_32( st->core_brate, FRAME_NO_DATA ) || NE_32( st->core_brate, SID_2k40 ) ) ) && EQ_16( st->L_frame, L_FRAME16k ) && EQ_16( st->codec_mode, MODE2 ) ) || + IF( ( ( ( st->tcxonly == 0 ) || !( st->core_brate != FRAME_NO_DATA || NE_32( st->core_brate, SID_2k40 ) ) ) && EQ_16( st->L_frame, L_FRAME16k ) && EQ_16( st->codec_mode, MODE2 ) ) || ( EQ_16( st->L_frame, L_FRAME16k ) && EQ_16( st->codec_mode, MODE1 ) ) ) { *Q_new = Q_new_16k; @@ -1092,7 +1089,6 @@ void pre_proc_fx( /* Above computed Q_new is used to scale primary copy exc and memory here by (Q_new, st->prev_Q_new) */ Q_exp = sub( *Q_new, st->prev_Q_new ); - move16(); Q_wsp_exp = add( Q_exp, shift_exp ); Scale_mem_enc( Q_exp, old_inp_16k, old_exc, hBWE_TD->old_bwe_exc_fx, &( hLPDmem->mem_w0 ), hLPDmem->mem_syn, @@ -1110,9 +1106,9 @@ void pre_proc_fx( test(); test(); #ifndef CR_2109_to_2112_cd0_ce0 - IF( ( ( ( st->tcxonly == 0 ) || !( NE_32( st->core_brate, FRAME_NO_DATA ) || NE_32( st->core_brate, SID_2k40 ) ) ) && EQ_16( st->L_frame, L_FRAME16k ) && EQ_16( st->codec_mode, MODE2 ) ) || ( EQ_16( st->L_frame, L_FRAME16k ) && EQ_16( st->codec_mode, MODE1 ) ) ) + IF( ( ( ( st->tcxonly == 0 ) || !( st->core_brate != FRAME_NO_DATA || NE_32( st->core_brate, SID_2k40 ) ) ) && EQ_16( st->L_frame, L_FRAME16k ) && EQ_16( st->codec_mode, MODE2 ) ) || ( EQ_16( st->L_frame, L_FRAME16k ) && EQ_16( st->codec_mode, MODE1 ) ) ) #else - IF( ( ( ( st->tcxonly == 0 ) || !( NE_32( st->core_brate, FRAME_NO_DATA ) && NE_32( st->core_brate, SID_2k40 ) ) ) && EQ_16( st->L_frame, L_FRAME16k ) && EQ_16( st->codec_mode, MODE2 ) ) || ( EQ_16( st->L_frame, L_FRAME16k ) && EQ_16( st->codec_mode, MODE1 ) ) ) + IF( ( ( ( st->tcxonly == 0 ) || !( st->core_brate != FRAME_NO_DATA && NE_32( st->core_brate, SID_2k40 ) ) ) && EQ_16( st->L_frame, L_FRAME16k ) && EQ_16( st->codec_mode, MODE2 ) ) || ( EQ_16( st->L_frame, L_FRAME16k ) && EQ_16( st->codec_mode, MODE1 ) ) ) #endif { /* update signal buffers */ @@ -1221,7 +1217,7 @@ void pre_proc_fx( { test(); test(); - IF( ( NE_32( st->core_brate, FRAME_NO_DATA ) && NE_32( st->core_brate, SID_2k40 ) && st->tcxonly == 0 ) ) + IF( ( st->core_brate != FRAME_NO_DATA && NE_32( st->core_brate, SID_2k40 ) && st->tcxonly == 0 ) ) { core_acelp_tcx20_switching_fx( st, non_staX, pitch_fr, voicing_fr, currFlatness, lsp_mid, stab_fac, *Q_new, *shift ); } @@ -1318,16 +1314,18 @@ void pre_proc_fx( } /* Update vAD hangover frame counter in active frames */ - if ( ( NE_16( st->core, HQ_CORE ) && st->tcxonly == 0 ) || EQ_16( st->core, ACELP_CORE ) ) + if ( ( NE_16( st->core, HQ_CORE ) && st->tcxonly == 0 ) || st->core == ACELP_CORE ) { - IF( !( EQ_32( st->core_brate, SID_2k40 ) || EQ_32( st->core_brate, FRAME_NO_DATA ) ) ) + IF( !( EQ_32( st->core_brate, SID_2k40 ) || st->core_brate == FRAME_NO_DATA ) ) { test(); IF( st->Opt_DTX_ON != 0 && *vad_hover_flag != 0 ) { hTdCngEnc->burst_ho_cnt = add( hTdCngEnc->burst_ho_cnt, 1 ); + move16(); hTdCngEnc->burst_ho_cnt = s_min( hTdCngEnc->burst_ho_cnt, HO_HIST_SIZE ); + move16(); } ELSE { diff --git a/lib_enc/prot_fx_enc.h b/lib_enc/prot_fx_enc.h index 2001f296664bf8854fbb33f99f1f72f15d9690fd..10d020ee3928e6c84324b352e5722b7e5c71f2c3 100644 --- a/lib_enc/prot_fx_enc.h +++ b/lib_enc/prot_fx_enc.h @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other @@ -46,29 +46,28 @@ *----------------------------------------------------------------------------------*/ ivas_error acelp_core_enc_fx( Encoder_State *st_fx, /* i/o: encoder state structure */ - const Word16 inp_fx[], /* i : i signal of the current frame */ - const Word32 ener_fx, /* i : residual energy from Levinson-Durbin*/ - Word16 A_fx[NB_SUBFR16k * ( M + 1 )], /* i : A(z) unquantized for the 4 subframes*/ - Word16 Aw_fx[NB_SUBFR16k * ( M + 1 )], /* i : weighted A(z) unquant. for subframes*/ - const Word16 epsP_h_fx[M + 1], /* i : LP prediction errors */ - const Word16 epsP_l_fx[M + 1], /* i : LP prediction errors */ - Word16 lsp_new_fx[M], /* i : LSPs at the end of the frame */ - Word16 lsp_mid_fx[M], /* i : LSPs in the middle of the frame */ - Word16 vad_hover_flag_fx, /* i : VAD hangover flag */ - const Word16 attack_flag, /* i : attack flag (GSC or TC) */ - Word32 bwe_exc_extended_fx[], /* i/o: bandwidth extended excitation */ - Word16 *voice_factors_fx, /* o : voicing factors */ - Word16 old_syn_12k8_16k_fx[], /* o : intermediate ACELP synthesis at 12.8kHz or 16kHz to be used by SWB BWE */ - Word16 pitch_buf_fx[NB_SUBFR16k], /* o : floating pitch for each subframe */ - Word16 *unbits_fx, /* o : number of unused bits */ + const Word16 inp_fx[], /* i : input signal of the current frame Q_new*/ + const Word32 ener_fx, /* i : residual energy from Levinson-Durbin Q6*/ + Word16 A_fx[NB_SUBFR16k * ( M + 1 )], /* i : A(z) unquantized for the 4 subframes Q12*/ + Word16 Aw_fx[NB_SUBFR16k * ( M + 1 )], /* i : weighted A(z) unquant. for subframes Q12*/ + const Word16 epsP_h_fx[M + 1], /* i : LP prediction errors Qx*/ + const Word16 epsP_l_fx[M + 1], /* i : LP prediction errors Qx*/ + Word16 lsp_new_fx[M], /* i : LSPs at the end of the frame Q15*/ + Word16 lsp_mid_fx[M], /* i : LSPs in the middle of the frame Q15*/ + Word16 vad_hover_flag_fx, /* i : VAD hangover flag Q0*/ + const Word16 attack_flag, /* i : attack flag (GSC or TC) Q0*/ + Word32 bwe_exc_extended_fx[], /* i/o: bandwidth extended excitation st->prev_Q_bwe_exc*/ + Word16 *voice_factors_fx, /* o : voicing factors Q15*/ + Word16 old_syn_12k8_16k_fx[], /* o : intermediate ACELP synthesis at 12.8kHz or 16kHz to be used by SWB BWE q_old_syn*/ + Word16 pitch_buf_fx[NB_SUBFR16k], /* o : floating pitch for each subframe Q6*/ + Word16 *unbits_fx, /* o : number of unused bits Q0*/ + STEREO_TD_ENC_DATA_HANDLE hStereoTD, /* i/o: TD stereo encoder handle */ + const float tdm_lsfQ_PCh[M], /* i : Q LSFs for primary channel */ const Word16 Q_new, const Word16 shift -#ifdef ADD_LRTD - , - STEREO_TD_ENC_DATA_HANDLE hStereoTD, /* i/o: TD stereo encoder handle */ - const float tdm_lsfQ_PCh[M] /* i : Q LSFs for primary channel */ -#endif + ); + void analy_lp_ivas_fx( const Word16 speech[], /* i :(Q_new) pointer to the speech frame */ const Word16 L_frame, /* i :(q0) length of the frame */ @@ -88,20 +87,20 @@ void analy_lp_ivas_fx( Word16 *Q_r /*stores q for ener*/ ); void analy_lp_fx( - const Word16 speech[], /* i : pointer to the speech frame */ - const Word16 L_frame, /* i : length of the frame */ - const Word16 L_look, /* i : look-ahead */ - Word32 *ener, /* o : residual energy from Levinson-Durbin */ - Word16 A[], /* o : A(z) filter coefficients */ - Word16 epsP_h[], /* o : LP analysis residual energies for each iteration */ - Word16 epsP_l[], /* o : LP analysis residual energies for each iteration */ - Word16 lsp_new[], /* o : current frame LSPs */ - Word16 lsp_mid[], /* o : current mid-frame LSPs */ - Word16 lsp_old[], /* i/o: previous frame unquantized LSPs */ - const Word16 Top[2], /* i : open loop pitch lag */ - const Word16 Tnc[2], /* i : open loop pitch gain */ - const Word32 Core_sr, /* i : Internal core sampling rate */ - const Word16 sec_chan_low_rate, /* i : flag to signal second channel */ + const Word16 speech[], /* i : pointer to the speech frame Q_new*/ + const Word16 L_frame, /* i : length of the frame Q0*/ + const Word16 L_look, /* i : look-ahead Q0*/ + Word32 *ener, /* o : residual energy from Levinson-Durbin Q_r*/ + Word16 A[], /* o : A(z) filter coefficients Q14*/ + Word16 epsP_h[], /* o : LP analysis residual energies for each iteration Q_r*/ + Word16 epsP_l[], /* o : LP analysis residual energies for each iteration Q_r*/ + Word16 lsp_new[], /* o : current frame LSPs Q15*/ + Word16 lsp_mid[], /* o : current mid-frame LSPs Q15*/ + Word16 lsp_old[], /* i/o: previous frame unquantized LSPs Q15*/ + const Word16 Top[2], /* i : open loop pitch lag Q0*/ + const Word16 Tnc[2], /* i : open loop pitch gain Q15*/ + const Word32 Core_sr, /* i : Internal core sampling rate Q0*/ + const Word16 sec_chan_low_rate, /* i : flag to signal second channel Q0*/ Word16 Q_new, Word16 *Q_r ); @@ -144,7 +143,7 @@ void bw_detect_fx( const Word32 *enerBuffer, /* i : CLDFB Energy Q31 */ const Word16 *cldfbBuf_Ener_Exp, /* i : CLDFB Energy Exponent */ const IVAS_FORMAT ivas_format, /* i : IVAS format */ - const int16_t mct_on /* i : flag MCT mode */ + const Word16 mct_on /* i : flag MCT mode */ ); void core_switching_post_enc_fx( /*done */ @@ -178,7 +177,10 @@ void dtx_fx( ); void dtx_ivas_fx( - Encoder_State *st_fx, /* i/o: encoder state structure */ + Encoder_State *st_fx, /* i/o: encoder state structure */ +#ifdef NONBE_1211_DTX_BR_SWITCHING + const Word32 last_ivas_total_brate, /* i : last IVAS total bitrate Q0*/ +#endif const Word32 ivas_total_brate, /* i : IVAS total bitrate Q0*/ const Word16 vad, /* i : vad flag for DTX Q0*/ const Word16 speech[], /* i : Pointer to the speech frame Q_speech*/ @@ -226,74 +228,72 @@ Word16 ffr_getSfWord32( const Word16 len /*!< Length of i vector */ ); void find_tilt_ivas_fx( - const Word32 fr_bands[], /* i : energy in frequency bands Q_new*/ - const Word32 bckr[], /* i : per band background noise energy estimate Q_new*/ - Word32 ee[2], /* o : lf/hf E ration for present frame Q6*/ + const Word32 fr_bands[], /* i : energy in frequency bands q_fr_bands*/ + const Word16 q_fr_bands, /* i : Q of fr_bands Q0*/ + const Word32 bckr[], /* i : per band background noise energy estimate q_bckr*/ + const Word16 q_bckr, /* i : Q of bckr Q0*/ + Word32 ee[2], /* o : lf/hf E ration for present frame Q_bckr*/ const Word16 pitch[3], /* i : open loop pitch values for 3 half-frames Q0*/ const Word16 voicing[3], /* i : normalized correlation for 3 half-frames Q15*/ - const Word32 *lf_E, /* i : per bin energy for low frequencies Q_new - 2*/ + const Word32 *lf_E, /* i : per bin energy for low frequencies q_lf_E*/ + const Word16 q_lf_E, /* i : Q of lf_E */ const Word16 corr_shift, /* i : normalized correlation correction Q15*/ const Word16 bwidth, /* i : i signal bandwidth */ const Word16 max_band, /* i : maximum critical band */ Word32 hp_E[], /* o : energy in HF Q_new*/ const Word16 codec_mode, /* i : MODE1 or MODE2 */ - const Word16 Q_new, /* i : scaling factor */ Word32 *bckr_tilt_lt, Word16 Opt_vbr_mode ); void find_tilt_fx( - const Word32 fr_bands[], /* i : energy in frequency bands Q_new + Q_SCALE*/ - const Word32 bckr[], /* i : per band background noise energy estimate Q_new + Q_SCALE*/ - Word32 ee[2], /* o : lf/hf E ration for present frame Q6*/ - const Word16 pitch[3], /* i : open loop pitch values for 3 half-frames Q0*/ - const Word16 voicing[3], /* i : normalized correlation for 3 half-frames Q15*/ + const Word32 fr_bands[], /* i : energy in frequency bands Q_new + Q_SCALE*/ + const Word32 bckr[], /* i : per band background noise energy estimate Q_new + Q_SCALE*/ + Word32 ee[2], /* o : lf/hf E ration for present frame Q6*/ + const Word16 pitch[3], /* i : open loop pitch values for 3 half-frames Q0*/ + const Word16 voicing[3], /* i : normalized correlation for 3 half-frames Q15*/ const Word32 *lf_E, /* i : per bin energy for low frequencies Q_new + Q_SCALE - 2*/ - const Word16 corr_shift, /* i : normalized correlation correction Q15*/ - const Word16 bwidth, /* i : i signal bandwidth */ - const Word16 max_band, /* i : maximum critical band */ + const Word16 corr_shift, /* i : normalized correlation correction Q15*/ + const Word16 bwidth, /* i : input signal bandwidth Q0*/ + const Word16 max_band, /* i : maximum critical band Q0*/ Word32 hp_E[], /* o : energy in HF Q_new + Q_SCALE*/ - const Word16 codec_mode, /* i : MODE1 or MODE2 */ - const Word16 Q_new, /* i : scaling factor */ - Word32 *bckr_tilt_lt, - Word16 Opt_vbr_mode ); + const Word16 codec_mode, /* i : MODE1 or MODE2 Q0*/ + const Word16 Q_new, /* i : scaling factor */ + Word32 *bckr_tilt_lt /* i/o: lf/hf E ratio of background noise Q16*/ + , + Word16 Opt_vbr_mode /* Q0 */ +); Word16 find_uv_ivas_fx( /* o : coding type */ Encoder_State *st_fx, /* i/o: encoder state structure */ - const Word16 *T_op_fr, /* i : pointer to adjusted fractional pitch (4 val.) Q6 */ - const Word16 *voicing_fr, /* i : refined correlation for each subframes Q15 */ - const Word16 *speech, /* i : pointer to speech signal for E computation Q_new */ - const Word32 *ee, /* i : lf/hf Energy ratio for present frame Q6 */ - Word32 *dE1X, /* o : sudden energy increase for S/M classifier */ - const Word16 corr_shift, /* i : normalized correlation correction in noise Q15 */ - const Word16 relE, /* i : relative frame energy Q8 */ - const Word16 Etot, /* i : total energy Q8 */ - const Word32 hp_E[], /* i : energy in HF Q_new */ - Word16 *flag_spitch, /* i/o: flag to indicate very short stable pitch and high correlation */ - const Word16 last_core_orig, /* i : original last core */ + const Word16 *T_op_fr, /* i : pointer to adjusted fractional pitch (4 val.) Q6*/ + const Word16 *voicing_fr, /* i : refined correlation for each subframes Q15*/ + const Word16 *speech, /* i : pointer to speech signal for E computation Q_new*/ + const Word32 *ee, /* i : lf/hf Energy ratio for present frame Q6*/ + Word32 *dE1X, /* o : sudden energy increase for S/M classifier Q13*/ + const Word16 corr_shift, /* i : normalized correlation correction in noise Q15*/ + const Word16 relE, /* i : relative frame energy Q8*/ + const Word16 Etot, /* i : total energy Q8*/ + const Word32 hp_E[], /* i : energy in HF q_hp_E*/ + Word16 *flag_spitch, /* i/o: flag to indicate very short stable pitch and high correlation Q0*/ + const Word16 last_core_orig, /* i : original last core Q0*/ STEREO_CLASSIF_HANDLE hStereoClassif, /* i/o: stereo classifier structure */ const Word16 Q_new, const Word16 q_hp_E ); + Word16 find_uv_fx( /* o : coding type */ - Encoder_State *st_fx, /* i/o: encoder state structure */ - const Word16 *T_op_fr, /* i : pointer to adjusted fractional pitch (4 val.) Q6*/ - const Word16 *voicing_fr, /* i : refined correlation for each subframes Q15*/ - const Word16 *speech, /* i : pointer to speech signal for E computation Q_new*/ - const Word32 *ee, /* i : lf/hf Energy ratio for present frame Q6*/ -#ifdef IVAS_CODE - Word32 *dE1X, /* o : sudden energy increase for S/M classifier */ -#endif - const Word16 corr_shift, /* i : normalized correlation correction in noise Q15*/ - const Word16 relE, /* i : relative frame energy Q8*/ - const Word16 Etot, /* i : total energy Q8*/ - const Word32 hp_E[], /* i : energy in HF Q_new + Q_SCALE*/ + Encoder_State *st_fx, /* i/o: encoder state structure */ + const Word16 *T_op_fr, /* i : pointer to adjusted fractional pitch (4 val.) Q6*/ + const Word16 *voicing_fr, /* i : refined correlation for each subframes Q15*/ + const Word16 *speech, /* i : pointer to speech signal for E computation Q_new*/ + const Word32 *ee, /* i : lf/hf Energy ratio for present frame Q6*/ + const Word16 corr_shift, /* i : normalized correlation correction in noise Q15*/ + const Word16 relE, /* i : relative frame energy Q8*/ + const Word16 Etot, /* i : total energy Q8*/ + const Word32 hp_E[], /* i : energy in HF Q_new + Q_SCALE*/ const Word16 Q_new, - Word16 *flag_spitch, /* i/o: flag to indicate very short stable pitch and high correlation */ + Word16 *flag_spitch, /* i/o: flag to indicate very short stable pitch and high correlation Q0*/ const Word16 shift, - const Word16 last_core_orig /* i : original last core */ -#ifdef IVAS_CODE - , - STEREO_CLASSIF_HANDLE hStereoClassif /* i/o: stereo classifier structure */ -#endif + const Word16 last_core_orig /* i : original last core Q0*/ ); void fine_gain_quant_fx( @@ -308,10 +308,10 @@ void fine_gain_quant_fx( void hq_core_enc_fx( Encoder_State *st_fx, const Word16 *audio, /* i : i audio signal Q0 */ - const Word16 input_frame_orig, /* i : frame length */ - const Word16 hq_core_type, /* i : HQ core type */ - const Word16 Voicing_flag, /* i : Voicing flag for FER method selection */ - const Word16 vad_hover_flag /* i : VAD hangover flag */ + const Word16 input_frame_orig, /* i : frame length Q0*/ + const Word16 hq_core_type, /* i : HQ core type Q0*/ + const Word16 Voicing_flag, /* i : Voicing flag for FER method selection Q0*/ + const Word16 vad_hover_flag /* i : VAD hangover flag Q0*/ ); void long_enr_fx( @@ -353,6 +353,20 @@ void noise_est_down_fx( const Word32 e_min /* i : minimum energy scaled Q_new + QSCALE */ ); +void noise_est_down_ivas_fx( + const Word32 fr_bands[], /* i : per band i energy (contains 2 vectors) */ + const Word16 q_fr_bands, /* i : Q of fr_bands */ + Word32 bckr[], /* i/o: per band background noise energy estimate */ + Word32 tmpN[], /* o : temporary noise update */ + Word32 enr[], /* o : averaged energy over both subframes */ + const Word16 min_band, /* i : minimum critical band */ + const Word16 max_band, /* i : maximum critical band */ + Word16 *totalNoise, /* o : noise estimate over all critical bands */ + Word16 Etot, /* i : Energy of current frame */ + Word16 *Etot_last, /* i/o: Energy of last frame Q8 */ + Word16 *Etot_v_h2 /* i/o: Energy variations of noise frames Q8 */ +); + void noise_est_fx( Encoder_State *st_fx, /* i/o: state structure */ const Word16 old_pitch1, /* i : previous frame OL pitch[1] */ @@ -380,37 +394,33 @@ void noise_est_fx( const Word32 Le_min_scaled, /*i : Minimum energy value in Q_new + Q_SCALE */ Word16 *sp_floor, /* o : noise floor estimate Q7 */ Word16 S_map[], /* o : short-term correlation map Q7 */ -#ifdef IVAS_CODE - STEREO_CLASSIF_HANDLE hStereoClassif, /* i/o: stereo classifier structure */ - FRONT_VAD_ENC_HANDLE hFrontVad, /* i/o: front-VAD handle */ -#endif - const Word16 ini_frame /* i : Frame number (init) */ + const Word16 ini_frame /* i : Frame number (init) */ ); void noise_est_ivas_fx( Encoder_State *st_fx, /* i/o: state structure */ const Word16 old_pitch1, /* i : previous frame OL pitch[1] */ const Word32 tmpN[], /* i : temporary noise update Q_new + QSCALE */ - const Word16 epsP_h[], /* i : msb prediction error energies Q_r-1 */ - const Word16 epsP_l[], /* i : msb prediction error energies Q_r-1 */ + const Word32 epsP[], /* i : msb prediction error energies Qx */ const Word16 Etot, /* i : total channel E (see find_enr_fx.c) Q8 */ const Word16 relE, /* i : (VA_CHECK addition) relative frame energy Q8? */ const Word16 corr_shift, /* i : normalized correlation correction Q15 */ - const Word32 enr[], /* i : averaged energy over both subframes Q_new + Q_SCALE */ - Word32 fr_bands[], /* i : spectrum per critical bands of the current frame Q_new + Q_SCALE */ + const Word32 enr[], /* i : averaged energy over both subframes q_enr */ + const Word16 q_enr, /* i : q_enr of enr Q0 */ + Word32 fr_bands[], /* i : spectrum per critical bands of the current frame q_fr_bands */ + Word16 q_fr_bands, /* i : Q of q_fr_bands */ Word16 *cor_map_sum, /* o : Q8 */ Word16 *ncharX, /* o : Q11 */ Word16 *sp_div, /* o : Q_sp_div */ Word16 *Q_sp_div, /* o : Q factor for sp_div */ Word16 *non_staX, /* o : non-stationarity for sp/mus classifier */ Word16 *loc_harm, /* o : multi-harmonicity flag for UV classifier */ - const Word32 *lf_E, /* i : per bin energy for low frequencies Q_new + Q_SCALE -2 */ + const Word32 *lf_E, /* i : per bin energy for low frequencies q_lf_E */ + const Word16 q_lf_E, /* i : Q of lf_E Q0 */ Word16 *st_harm_cor_cnt, /* i/o : 1st harm correlation timer Q0 */ const Word16 Etot_l_lp, /* i : Smoothed low energy Q8 */ const Word16 Etot_v_h2, /* i : Energy variations Q8 */ Word16 *bg_cnt, /* i : Background burst length timer Q0 */ Word16 EspecdB[], /* i/o: log E spectrum (with f=0) of the current frame Q7 for multi harm */ - Word16 Q_new, /* i : SCaling of current frame */ - const Word32 Le_min_scaled, /*i : Minimum energy value in Q_new + Q_SCALE */ Word16 *sp_floor, /* o : noise floor estimate Q7 */ Word16 S_map[], /* o : short-term correlation map Q7 */ STEREO_CLASSIF_HANDLE hStereoClassif, /* i/o: stereo classifier structure */ @@ -464,7 +474,8 @@ void pitch_ol_ivas_fx( const Word16 relE, /* i : relative frame energy Q8 */ const Word16 last_class, /* i : frame classification of last frame */ const Word16 bwidth, /* i : bandwidth */ - const Word16 Opt_SC_VBR /* i : SC-VBR flag */ + const Word16 Opt_SC_VBR, /* i : SC-VBR flag */ + Word16 qwsp /* i : Q factor for wsp Q0 */ ); void pitch_ol_fx( @@ -492,17 +503,17 @@ void pitch_ol_init_fx( ); void Preemph_scaled( - Word16 new_speech[], /* i : Speech to scale already on 14 bits*/ - Word16 *Q_new, /* o : Scaling factor */ - Word16 *mem_preemph, /* i/o: Preemph memory */ - Word16 *Q_max, /* i/o: Q_new limitation */ - const Word16 Preemph_factor, /* i : Preemphasis factor Q15 */ - const Word16 bits, /* i : Bit to remove from the output to (15-bits)*/ - const Word16 bit1, /* i : Limit the output scaling to ((15-bits)-bit1) bits */ - const Word16 L_Q_mem, /* i : Number of old scaling to take into account */ - const Word16 Lframe, /* i : Frame length */ - const Word16 last_coder_type, /* i : coder_type */ - const Word16 Search_scaling /* i : enable the search of a proper scaling factor*/ + Word16 new_speech[], /* i : Speech to scale already on 14 bits Q_new*/ + Word16 *Q_new, /* o : Scaling factor */ + Word16 *mem_preemph, /* i/o: Preemph memory Q(-1)*/ + Word16 *Q_max, /* i/o: Q_new limitation */ + const Word16 Preemph_factor, /* i : Preemphasis factor Q15*/ + const Word16 bits, /* i : Bit to remove from the output to (15-bits) */ + const Word16 bit1, /* i : Limit the output scaling to ((15-bits)-bit1) bits */ + const Word16 L_Q_mem, /* i : Number of old scaling to take into account Q0*/ + const Word16 Lframe, /* i : Frame length Q0*/ + const Word16 last_coder_type, /* i : coder_type Q0*/ + const Word16 Search_scaling /* i : enable the search of a proper scaling factor Q0*/ ); void Scale_mem_enc( @@ -518,17 +529,17 @@ void Scale_mem_enc( Word16 *old_input_lp ); Word32 Scale_mem_pre_proc( /* o : Min energy scaled */ - Word16 ini_frame_fx, /* i : Frame number */ + Word16 ini_frame_fx, /* i : Frame number Q0*/ Word16 Q_exp, /* i : Diff scaling factor */ Word16 *Q_new, /* i/o: Absolute scaling factor */ Word16 *old_speech, /* i/o: Speech memory */ - Word16 *mem_wsp, /* i/o: wsp vector memory */ - Word32 *enrO, /* i/o: Enr mem */ - Word32 *bckr, /* i/o: Back ground_fx ener mem */ - Word32 *ave_enr, /* i/o: Ave_enr mem */ - Word32 *ave_enr2, /* i/o: Ave_enr2 mem */ - Word32 *st_fr_bands1, /* i/o: spectrum per critical bands of the previous frame */ - Word32 *st_fr_bands2, /* i/o: spectrum per critical bands 2 frames ago */ + Word16 *mem_wsp, /* i/o: wsp vector memory st->mem_wsp_q*/ + Word32 *enrO, /* i/o: Enr mem q_enrO*/ + Word32 *bckr, /* i/o: Back ground_fx ener mem q_bckr*/ + Word32 *ave_enr, /* i/o: Ave_enr mem Q_new + QSCALE*/ + Word32 *ave_enr2, /* i/o: Ave_enr2 mem Q_new + QSCALE*/ + Word32 *st_fr_bands1, /* i/o: spectrum per critical bands of the previous frame Q_new + QSCALE*/ + Word32 *st_fr_bands2, /* i/o: spectrum per critical bands 2 frames ago Q_new + QSCALE*/ Word32 *st_Bin_E_old ); void Scale_wsp( @@ -540,7 +551,7 @@ void Scale_wsp( Word16 *old_wsp, /* i/o: Old weighted speech buffer */ Word16 *mem_decim2, /* i/o: Decimation buffer */ Word16 *old_wsp12k8, /* i/o: wsp memory @ 12.8 kHz used in pitol2 */ - const Word16 Len_p_look /* i : L_frame + look ahead */ + const Word16 Len_p_look /* i : L_frame + look ahead Q0*/ ); Word16 signal_clas_fx( /* o : classification for current frames */ @@ -616,7 +627,7 @@ void swb_bwe_enc_fx( void swb_bwe_enc_ivas_fx( Encoder_State *st_fx, /* i/o: encoder state structure */ - const int16_t last_element_mode, /* i : last element mode */ + const Word16 last_element_mode, /* i : last element mode */ Word16 *old_input_12k8_fx, /* i : input signal @12.8kHz for SWB BWE */ Word16 *old_input_16k_fx, /* i : input signal @16kHz for SWB BWE */ const Word16 *old_syn_12k8_16k_fx, /* i : ACELP core synthesis at 12.8kHz or 16kHz */ @@ -783,28 +794,28 @@ Word16 wb_vad_fx( Word16 wb_vad_ivas_fx( Encoder_State *st_fx, /* i/o: encoder state structure */ - const Word32 fr_bands[], /* i : per band i energy (contains 2 vectors) Q_new+QSCALE*/ + const Word32 fr_bands[], /* i : per band i energy (contains 2 vectors) q_fr_bands*/ + const Word16 q_fr_bands, /* i : Q of fr_bands */ Word16 *noisy_speech_HO, /* o : SC-VBR noisy speech HO flag */ Word16 *clean_speech_HO, /* o : SC-VBR clean speech HO flag */ Word16 *NB_speech_HO, /* o : SC-VBR NB speech HO flag */ Word16 *snr_sum_he, /* o : Output snr_sum as weighted spectral measure*/ Word16 *localVAD_HE_SAD, Word16 *flag_noisy_speech_snr, /* o : */ - const Word16 Q_new, /* i : scaling factor Q0 */ VAD_HANDLE hVAD, /* i/o: VAD data handle */ NOISE_EST_HANDLE hNoiseEst, /* i : Noise estimation handle */ Word16 lp_speech, /* i : long term active speech energy average */ Word16 lp_noise /* i : long term noise energy */ ); -Word32 construct_snr_thresh_fx( Word16 sp_center[], /*(i) spectral center*/ - Word32 snr_flux, /*(i) snr flux*/ - Word32 lt_snr, /*(i) long time time domain snr*/ - Word32 l_snr, /*(i) long time frequency domain snr*/ - Word32 continuous_speech_num, /*(i) amount of continuous speech frames*/ - Word16 continuous_noise_num, /*(i) amount of continuous noise frames*/ - Word32 fg_energy_est_start, /*(i) whether if estimated energy*/ - Word16 bw_index /*(i) band width index*/ +Word32 construct_snr_thresh_fx( Word16 sp_center[], /*(i) spectral center Q10*/ + Word32 snr_flux, /*(i) snr flux Q25*/ + Word32 lt_snr, /*(i) long time time domain snr Q25*/ + Word32 l_snr, /*(i) long time frequency domain snr Q25*/ + Word32 continuous_speech_num, /*(i) amount of continuous speech frames Q0*/ + Word16 continuous_noise_num, /*(i) amount of continuous noise frames Q0*/ + Word32 fg_energy_est_start, /*(i) whether if estimated energy Q0*/ + Word16 bw_index /*(i) band width index Q0*/ ); void sc_vbr_enc_init_fx( @@ -825,14 +836,12 @@ Word16 corr_xy1_fx( /* o : pitch gain (0..GAIN_PIT_MAX) Word16 g_corr[], /* o : correlations and -2 */ const Word16 L_subfr, /* i : vector length */ const Word16 norm_flag /* i : flag for constraining pitch contribution */ -#ifdef BASOP_NOGLOB , Flag *Overflow_out /* o : propagating the Overflow flag to upper level */ -#endif ); -Word16 E_ACELP_indexing_fx( const Word16 code[], const PulseConfig *config, Word16 num_tracks, Word16 prm[] ); -void fcb_pulse_track_joint_fx( UWord16 *idxs, Word16 wordcnt, UWord32 *index_n, Word16 *pulse_num, Word16 track_num ); +Word16 E_ACELP_indexing_fx( const Word16 code[] /*Q9*/, const PulseConfig *config, Word16 num_tracks /*Q0*/, Word16 prm[] /*Q(shift_bits)*/ ); +void fcb_pulse_track_joint_fx( UWord16 *idxs /*Q0*/, Word16 wordcnt /*Q0*/, UWord32 *index_n /*Q0*/, Word16 *pulse_num /*Q0*/, Word16 track_num /*Q0*/ ); Word16 gain_quant_fx( /* o: quantization index */ Word32 *gain, /* i/o: quantized gain */ @@ -885,10 +894,6 @@ void lsf_end_enc_fx( Word16 *no_indices, Word16 *bits_param_lpc, Word16 coder_type_raw /* i : Coder type (LSF coder_type have some special cases)*/ -#ifdef LSF_RE_USE_SECONDARY_CHANNEL - , - const Word16 tdm_lsfQ_PCh[M] /* i : Q LSFs for primary channel */ -#endif ); void lsf_end_enc_ivas_fx( @@ -902,10 +907,10 @@ void lsf_end_enc_ivas_fx( Word16 *lpc_param, Word16 *no_indices, Word16 *bits_param_lpc, - Word16 coder_type_raw /* i : Coder type (LSF coder_type have some special cases)*/ - , + Word16 coder_type_raw, /* i : Coder type (LSF coder_type have some special cases)*/ const Word16 tdm_lsfQ_PCh[M] /* i : Q LSFs for primary channel */ ); + void Mode2_abs_pit_enc_fx( Word16 T0, /* i : integer pitch lag */ Word16 T0_frac, /* i : pitch fraction */ @@ -934,19 +939,30 @@ void norm_corr_fx( const Word16 L_subfr /* i : subframe size */ ); +void norm_corr_ivas_fx( + const Word16 exc[], /* i : excitation buffer Q_new */ + const Word16 xn[], /* i : target signal Q_new-1 */ + const Word16 h[], /* i : weighted synthesis filter impulse response Q(14 - norm_s(h[0])) */ + const Word16 t_min, /* i : minimum value of searched range */ + const Word16 t_max, /* i : maximum value of searched range */ + Word16 ncorr[], /* o : normalized correlation */ + const Word16 L_subfr, /* i : subframe size */ + Word16 Q_new /* i */ +); + Word16 peak_avrg_ratio_fx( - const Word32 total_brate, - const Word32 *input_hi_fx, /* i : i signal */ - const Word16 length, /* i : number of coefficients */ - Word16 *mode_count, /* i/o: HQ_HARMONIC mode count */ - Word16 *mode_count1, /* i/o: HQ_NORMAL mode count */ + const Word32 total_brate, /* Q0 */ + const Word32 *input_hi_fx, /* i : i signal Q_coeff*/ + const Word16 length, /* i : number of coefficients Q0*/ + Word16 *mode_count, /* i/o: HQ_HARMONIC mode count Q0*/ + Word16 *mode_count1, /* i/o: HQ_NORMAL mode count Q0*/ Word16 Q_coeff ); Word16 peak_avrg_ratio_ivas_fx( - const Word32 total_brate, - const Word32 *input_hi_fx, /* i : i signal */ - const Word16 length, /* i : number of coefficients */ - Word16 *mode_count, /* i/o: HQ_HARMONIC mode count */ - Word16 *mode_count1, /* i/o: HQ_NORMAL mode count */ + const Word32 total_brate, /* Q0 */ + const Word32 *input_hi_fx, /* i : i signal Q_coeff*/ + const Word16 length, /* i : number of coefficients Q0*/ + Word16 *mode_count, /* i/o: HQ_HARMONIC mode count Q0*/ + Word16 *mode_count1, /* i/o: HQ_NORMAL mode count Q0*/ Word16 Q_coeff ); void hvq_classifier_ivas_fx( const Word32 *input, /* i : input signal Q12 */ @@ -995,6 +1011,23 @@ Word16 pitch_fr4_fx( /* o : chosen integer pitch lag const Word16 L_frame, /* i : length of the frame */ const Word16 L_subfr /* i : size of subframe */ ); + +Word16 pitch_fr4_ivas_fx( /* o : chosen integer pitch lag */ + const Word16 exc[], /* i : excitation buffer Q_new */ + const Word16 xn[], /* i : target signal Q_new-1 */ + const Word16 h[], /* i : weighted synthesis filter impulse response Q(14 - norm_s[h[0]) */ + const Word16 t0_min, /* i : minimum value in the searched range. Q0 */ + const Word16 t0_max, /* i : maximum value in the searched range. Q0 */ + Word16 *pit_frac, /* o : chosen fraction (0, 1, 2 or 3) */ + const Word16 i_subfr, /* i : flag to first subframe */ + const Word16 limit_flag, /* i : flag for limits (0=restrained, 1=extended) */ + const Word16 t0_fr2, /* i : minimum value for resolution 1/2 */ + const Word16 t0_fr1, /* i : minimum value for resolution 1 */ + const Word16 L_frame, /* i : length of the frame */ + const Word16 L_subfr, /* i : size of subframe */ + Word16 Q_new /* i */ +); + void pit_Q_enc_fx( BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ const Word16 Opt_AMR_WB, /* i : flag indicating AMR-WB IO mode */ @@ -1201,7 +1234,10 @@ void AVQ_cod_lpc_fx( ); void ProcessIGF_ivas_fx( - Encoder_State *st, /* i : Encoder state */ + Encoder_State *st, /* i : Encoder state */ +#ifdef MSAN_FIX + Word16 powerSpec_len, /* i : length of pPowerSpectrum buffer */ +#endif Word32 *pMDCTSpectrum, /* i : MDCT spectrum */ const Word32 *pITFMDCTSpectrum, /* i : MDCT spectrum fir ITF */ Word16 *q_spectrum, /* i/o: Q of spectrum */ @@ -1237,6 +1273,18 @@ void AnalyzePowerSpectrum_fx( Word32 powerSpec[], /* o : Power spectrum. Can point to signal */ Word16 *powerSpec_e ); +void AnalyzePowerSpectrum_ivas_fx( + Encoder_State *st, /* i/o: encoder states */ + Word16 L_frame, /* i : frame length */ + Word16 L_frameTCX, /* i : full band frame length */ + Word16 left_overlap, /* i : left overlap length */ + Word16 right_overlap, /* i : right overlap length */ + Word32 const mdctSpectrum[], /* i : MDCT spectrum */ + Word16 mdctSpectrum_e, + Word16 const signal[], /* i : windowed signal corresponding to mdctSpectrum */ + Word32 powerSpec[], /* o : Power spectrum. Can point to signal */ + Word16 powerSpec_e[] ); + void AdaptLowFreqEmph_fx( Word32 x[], Word16 x_e, Word16 xq[], @@ -1253,6 +1301,13 @@ Word16 SQ_gain_fx( /* o : SQ gain */ Word16 lg, /* i : vector size (2048 max) */ Word16 *gain_e ); /* o : SQ gain exponent */ +Word16 SQ_gain_ivas_fx( /* o : SQ gain */ + Word32 x[], /* i : vector to quantize */ + Word16 x_e, /* i : exponent */ + Word16 nbitsSQ, /* i : number of bits targeted */ + Word16 lg, /* i : vector size (2048 max) */ + Word16 *gain_e ); /* o : SQ gain exponent */ + Word16 SQ_gain_estimate_fx( /* o : SQ gain */ Word32 x[], /* i : vector to quantize */ Word16 x_e, /* i : exponent */ @@ -1445,34 +1500,34 @@ void ComputeSpectrumNoiseMeasure_fx( const Word32 *powerSpec, void lpc_quantization_fx( Encoder_State *st, - const Word16 lsp[], - const Word16 lspmid[], - Word16 lsp_q[], - Word16 lsf_q[], /* 14Q1*1.28 */ - Word16 lspmid_q[], - Word16 lspq_ind[], - Word16 clip_var[], - const Word16 coder_type, - const Word16 acelp_midLpc, - Word16 param_lpc[], - Word16 nbits_lpc[], - Word16 *bits_param_lpc, - Word16 *no_param_lpc, + const Word16 lsp[], /* Q15 */ + const Word16 lspmid[], /* Q15 */ + Word16 lsp_q[], /* Q15 */ + Word16 lsf_q[], /* 14Q1*1.28 */ + Word16 lspmid_q[], /* Q15 */ + Word16 lspq_ind[], /* Q15 */ + Word16 clip_var[], /* [2.56x,Q14,Q8,Q0,Q14,Q14] */ + const Word16 coder_type, /* Q0 */ + const Word16 acelp_midLpc, /* Q0 */ + Word16 param_lpc[], /* Q0 */ + Word16 nbits_lpc[], /* Q0 */ + Word16 *bits_param_lpc, /* Q0 */ + Word16 *no_param_lpc, /* Q0 */ const Word16 Q_ener ); void lpc_quantization_ivas_fx( Encoder_State *st, - const Word16 lsp[], /* Q15 */ - const Word16 lspmid[], /* Q15 */ - Word16 lsp_q[], /* Q15 */ - Word16 lsf_q[], /* 14Q1*1.28 */ - Word16 lspmid_q[], /* Q15 */ - const Word16 coder_type, - const Word16 acelp_midLpc, - Word16 param_lpc[], - Word16 nbits_lpc[], - Word16 *bits_param_lpc, - Word16 *no_param_lpc, + const Word16 lsp[], /* Q15 */ + const Word16 lspmid[], /* Q15 */ + Word16 lsp_q[], /* Q15 */ + Word16 lsf_q[], /* 14Q1*1.28 */ + Word16 lspmid_q[], /* Q15 */ + const Word16 coder_type, /* Q0 */ + const Word16 acelp_midLpc, /* Q0 */ + Word16 param_lpc[], /* Q0 */ + Word16 nbits_lpc[], /* Q0 */ + Word16 *bits_param_lpc, /* Q0 */ + Word16 *no_param_lpc, /* Q0 */ const Word16 Q_ener ); void Mode2_pit_encode_fx( @@ -1496,15 +1551,19 @@ void Mode2_pit_encode_fx( Word16 pit_fr2, Word16 pit_max, Word16 pit_res_max ); -void E_ACELP_4tsearch_fx( Word16 dn[], const Word16 cn[], const Word16 H[], Word16 code[], const PulseConfig *config, Word16 ind[], Word16 y[] ); +void E_ACELP_4tsearch_fx( Word16 dn[] /*Qdn*/, const Word16 cn[] /*Q_xn*/, const Word16 H[] /*Q12*/, Word16 code[] /*Q9*/, const PulseConfig *config, Word16 ind[] /*Q0*/, Word16 y[] /*Qy*/ ); + +#ifdef FIX_ISSUE_1165 +void E_ACELP_4tsearch_ivas_fx( Word16 dn[] /*Qdn*/, const Word16 cn[] /*Q_xn*/, const Word16 H[] /*Q12*/, Word16 code[] /*Q9*/, const PulseConfig *config, Word16 ind[] /*Q0*/, Word16 y[] /*Qy*/ ); +#endif void E_ACELP_4t_fx( - Word16 dn[], + Word16 dn[], /* Qdn */ Word16 cn[] /* Q_xn */, - Word16 H[], - Word16 R[], + Word16 H[], /* Q12 */ + Word16 R[], /* Qx */ Word8 acelpautoc, - Word16 code[], + Word16 code[], /* Q9 */ Word16 cdk_index, Word16 _index[], const Word16 L_frame, @@ -1514,19 +1573,19 @@ void E_ACELP_4t_fx( const Word16 cmpl_flag ); void E_ACELP_4t_ivas_fx( - Word16 dn[], + Word16 dn[], /* Qdn */ Word16 cn[] /* Q_xn */, - Word16 H[], - Word16 R[], + Word16 H[], /* Q12 */ + Word16 R[], /* Qx */ Word8 acelpautoc, - Word16 code[], + Word16 code[], /* Q9 */ Word16 cdk_index, Word16 _index[], const Word16 L_frame, const Word16 last_L_frame, const Word32 total_brate, const Word16 i_subfr, - const int16_t cmpl_flag, + const Word16 cmpl_flag, Word16 element_mode ); void E_ACELP_innovative_codebook_fx( @@ -1556,8 +1615,8 @@ void E_ACELP_innovative_codebook_fx( void CalculateTnsFilt_fx( STnsConfig const *pTnsConfig, /* i : TNS Configuration struct */ const Word32 pSpectrum[], /* i : MDCT spectrum Qx*/ - STnsData *pTnsData, /* o : TNS data struct */ - Word16 *predictionGain /* o : TNS prediction gain Q7*/ + const Word16 pSpectrum_e, + STnsData *pTnsData /* o : TNS data struct */ ); /** Detect TNS parameters. @@ -1636,7 +1695,13 @@ void subband_FFT_fx( Word32 Offset, /*(i) offset of the CLDFB*/ Word16 *fftoQ /*(o) the Scaling */ ); -Word16 E_ACELP_toeplitz_mul_fx( const Word16 R[], const Word16 c[], Word16 d[], const Word16 L_subfr, const Word16 highrate ); +Word16 E_ACELP_toeplitz_mul_fx( + const Word16 R[], /* Q9 */ + const Word16 c[], /* Qx */ + Word16 d[], /* exp(j) */ + const Word16 L_subfr, /* Q0 */ + const Word16 highrate /* Q0 */ +); Word16 E_ACELP_code43bit_fx( const Word16 code[], UWord32 *ps, Word16 *p, UWord16 idxs[] ); void tc_classif_enc_fx( const Word16 Q_new, /* i : scaling factor */ @@ -1686,21 +1751,22 @@ void ari_copy_states_fx( TastatEnc *dest ); Word16 ari_encode_14bits_ext_fx( - Word16 *ptr, - Word16 bp, + Word16 *ptr, /* Q0 */ + Word16 bp, /* Q0 */ TastatEnc *s, - Word32 symbol, - UWord16 const *cum_freq ); + Word32 symbol, /* Q0 */ + UWord16 const *cum_freq /* Q0 */ +); Word16 ari_put_bit_plus_follow( - Word16 ptr[], /* o: bit-stream */ - Word16 bp, /* i: bit-stream position */ - Word16 bits_to_follow, /* i: number of opposite bits to follow 'bit' */ - Word16 bit /* i: bit to send */ + Word16 ptr[], /* o: bit-stream Q0*/ + Word16 bp, /* i: bit-stream position Q0*/ + Word16 bits_to_follow, /* i: number of opposite bits to follow 'bit' Q0*/ + Word16 bit /* i: bit to send Q0*/ ); Word16 ari_done_encoding_14bits_fx( - Word16 *ptr, - Word16 bp, + Word16 *ptr, /* Q0 */ + Word16 bp, /* Q0 */ TastatEnc *s ); void reset_rf_indices_fx( @@ -1745,22 +1811,22 @@ void generate_comfort_noise_enc_fx( Encoder_State *stcod, Word16 gen_exc ); Word16 cng_energy_fx( - const Word16 element_mode, /* i : element mode */ - const Word16 bwidth, /* i : audio bandwidh */ - const Word16 CNG_mode, /* i : mode for DTX configuration */ - const Word16 CNG_att, /* i : attenuation factor for CNG */ - const Word16 *exc, /* i : i signal */ - const Word16 len, /* i : vector length */ + const Word16 element_mode, /* i : element mode Q0*/ + const Word16 bwidth, /* i : audio bandwidh Q0*/ + const Word16 CNG_mode, /* i : mode for DTX configuration Q0*/ + const Word16 CNG_att, /* i : attenuation factor for CNG Q7*/ + const Word16 *exc, /* i : input signal Q_new*/ + const Word16 len, /* i : vector length Q0*/ const Word16 Q_new /* i : Input scaling */ ); void CNG_reset_enc_fx( - Encoder_State *st_fx, /* i/o: encoder state structure */ - LPD_state_HANDLE hLPDmemm, /* i/o: acelp memories */ - Word16 *pitch_buf, /* o : floating pitch for each subframe */ - Word16 *voice_factors /* o : voicing factors */ - , - Word16 VBR_cng_reset_flag ); + Encoder_State *st_fx, /* i/o: encoder state structure */ + LPD_state_HANDLE hLPDmem, /* i/o: acelp memories */ + Word16 *pitch_buf, /* o : floating pitch for each subframe Q6*/ + Word16 *voice_factors, /* o : voicing factors Q15*/ + Word16 VBR_cng_reset_flag /* Q0 */ +); void lsf_enc_fx( Encoder_State *st_fx, /* i/o: state structure */ @@ -1771,9 +1837,6 @@ void lsf_enc_fx( const Word16 Nb_ACELP_frames, const Word16 tdm_low_rate_mode, /* i : secondary channel low rate mode flag */ const Word16 GSC_IVAS_mode, /* i : GSC IVAS mode */ -#ifdef LSF_RE_USE_SECONDARY_CHANNEL - const float tdm_lsfQ_PCh[M], /* i : Q LSFs for primary channel */ -#endif const Word16 Q_new ); void lsf_enc_ivas_fx( @@ -1786,87 +1849,99 @@ void lsf_enc_ivas_fx( const Word16 GSC_IVAS_mode, /* i : GSC IVAS mode */ const Word16 tdm_lsfQ_PCh[M], /* i : Q LSFs for primary channel */ const Word16 Q_new ); + void Es_pred_enc_fx( - Word16 *Es_pred, /* o : predicited scaled innovation energy Q8 */ - Word16 *indice, /* o : indice of quantization */ - const Word16 L_frame, /* i : length of the frame */ - const Word16 *res, /* i : residual signal */ - const Word16 *voicing, /* i : normalized correlation in three 1/2frames */ - const Word16 nb_bits, /* i : allocated number of bits */ - const Word16 no_ltp, /* i : no_ltp flag */ - Word16 Q_new /* i : Scaling in speech Q0 */ + Word16 *Es_pred, /* o : predicited scaled innovation energy Q8*/ + Word16 *indice, /* o : indice of quantization Q0*/ + const Word16 L_frame, /* i : length of the frame Q0*/ + const Word16 *res, /* i : residual signal Q_new*/ + const Word16 *voicing, /* i : normalized correlation in three 1/2frames Q15*/ + const Word16 nb_bits, /* i : allocated number of bits Q0*/ + const Word16 no_ltp, /* i : no_ltp flag Q0*/ + Word16 Q_new /* i : Scaling in speech Q0*/ ); void encod_nelp_fx( Encoder_State *st_fx, /* i/o: state structure */ - const Word16 *speech_fx, /* i : i speech */ - const Word16 Aw_fx[], /* i : weighted A(z) unquantized for subframes */ - const Word16 Aq_fx[], /* i : 12k8 Lp coefficient */ - Word16 *res_fx, /* o : residual signal */ - Word16 *synth_fx, /* o : core synthesis */ - Word16 *tmp_noise_fx, /* o : long-term noise energy */ - Word16 *exc_fx, /* i/o: current non-enhanced excitation */ - Word16 *exc2_fx, /* i/o: current enhanced excitation */ - Word16 *pitch_buf_fx, /* o : floating pitch values for each subframe */ - Word16 *voice_factors_fx, /* o : voicing factors */ - Word16 *bwe_exc_fx, /* o : excitation for SWB TBE */ + const Word16 *speech_fx, /* i : input speech Q_new-1*/ + const Word16 Aw_fx[], /* i : weighted A(z) unquantized for subframes Q12*/ + const Word16 Aq_fx[], /* i : 12k8 Lp coefficient Q12*/ + Word16 *res_fx, /* o : residual signal Q_new*/ + Word16 *synth_fx, /* o : core synthesis Q_new*/ + Word16 *tmp_noise_fx, /* o : long-term noise energy Q0*/ + Word16 *exc_fx, /* i/o: current non-enhanced excitation Q_new*/ + Word16 *exc2_fx, /* i/o: current enhanced excitation Q_new*/ + Word16 *pitch_buf_fx, /* o : floating pitch values for each subframe Q6*/ + Word16 *voice_factors_fx, /* o : voicing factors Q15*/ + Word16 *bwe_exc_fx, /* o : excitation for SWB TBE Q_new*/ Word16 Q_new, Word16 shift ); void encod_nelp_ivas_fx( - Encoder_State *st_fx, /* i/o: state structure */ - const Word16 *speech_fx, /* i : input speech */ - const Word16 Aw_fx[], /* i : weighted A(z) unquantized for subframes */ - const Word16 Aq_fx[], /* i : 12k8 Lp coefficient */ - Word16 *res_fx, /* o : residual signal */ - Word16 *synth_fx, /* o : core synthesis */ - Word16 *tmp_noise_fx, /* o : long-term noise energy */ - Word16 *exc_fx, /* i/o: current non-enhanced excitation */ - Word16 *exc2_fx, /* i/o: current enhanced excitation */ - Word16 *pitch_buf_fx, /* o : floating pitch values for each subframe */ - Word16 *voice_factors_fx, /* o : voicing factors */ - Word16 *bwe_exc_fx, /* o : excitation for SWB TBE */ + Encoder_State *st_fx, /* i/o: state structure */ + const Word16 *speech_fx, + /* i : input speech */ /* Q_new-1 */ + const Word16 Aw_fx[], + /* i : weighted A(z) unquantized for subframes */ /*exp(norm_s(Aw_fx[0])+1)*/ + const Word16 Aq_fx[], + /* i : 12k8 Lp coefficient */ /*exp(norm_s(Aw_fx[0])+1)*/ + Word16 *res_fx, + /* o : residual signal */ /* Q_new */ + Word16 *synth_fx, + /* o : core synthesis */ /* Q_new */ + Word16 *tmp_noise_fx, + /* o : long-term noise energy */ /* Q8 */ + Word16 *exc_fx, + /* i/o: current non-enhanced excitation */ /* Q_new */ + Word16 *exc2_fx, + /* i/o: current enhanced excitation */ /* Q_new */ + Word16 *pitch_buf_fx, + /* o : floating pitch values for each subframe */ /* Q6 */ + Word16 *voice_factors_fx, + /* o : voicing factors */ /* Q15 */ + Word16 *bwe_exc_fx, + /* o : excitation for SWB TBE */ /* Q_new */ Word16 Q_new, Word16 shift ); Word16 encod_tran_fx( - Encoder_State *st_fx, /* i/o: state structure */ - const Word16 speech_fx[], /* i : i speech */ - const Word16 Aw_fx[], /* i : weighted A(z) unquantized for subframes */ - const Word16 Aq_fx[], /* i : 12k8 Lp coefficient */ - const Word16 Es_pred_fx, /* i : predicted scaled innov. energy */ - const Word16 *res_fx, /* i : residual signal */ - Word16 *syn_fx, /* i/o: core synthesis */ - Word16 *exc_fx, /* i/o: current non-enhanced excitation */ - Word16 *exc2_fx, /* i/o: current enhanced excitation */ - Word16 *pitch_buf_fx, /* i/o: floating pitch values for each subframe */ - Word16 *voice_factors, /* o : voicing factors */ - Word16 *bwe_exc_fx, /* i/o: excitation for SWB TBE */ - Word16 tc_subfr, /* i/o: TC subframe classification */ - Word16 position, /* i : maximum of residual signal index */ - Word16 *unbits, /* i/o: number of unused bits */ - const Word16 shift, /* i : Scaling to get 12 bits */ - const Word16 Q_new /* i : Input scaling */ + Encoder_State *st_fx, /* i/o: state structure */ + const Word16 speech_fx[], /* i : input speech Q0*/ + const Word16 Aw_fx[], /* i : weighted A(z) unquantized for subframes Q12*/ + const Word16 Aq_fx[], /* i : 12k8 Lp coefficient Q12*/ + const Word16 Es_pred_fx, /* i : predicted scaled innov. energy Q8*/ + const Word16 *res_fx, /* i : residual signal Q_new*/ + Word16 *syn_fx, /* i/o: core synthesis Q_new*/ + Word16 *exc_fx, /* i/o: current non-enhanced excitation Q0*/ + Word16 *exc2_fx, /* i/o: current enhanced excitation Q0*/ + Word16 *pitch_buf_fx, /* i/o: floating pitch values for each subframe Q6*/ + Word16 *voice_factors, /* o : voicing factors Q15*/ + Word16 *bwe_exc_fx, /* i/o: excitation for SWB TBE Q0*/ + Word16 tc_subfr, /* i/o: TC subframe classification Q0*/ + Word16 position, /* i : maximum of residual signal index Q0*/ + Word16 *unbits, /* i/o: number of unused bits Q0*/ + const Word16 shift, /* i : Scaling to get 12 bits */ + const Word16 Q_new /* i : Input scaling */ ); Word16 encod_tran_ivas_fx( Encoder_State *st_fx, /* i/o: state structure */ - const Word16 speech_fx[], /* i : input speech */ - const Word16 Aw_fx[], /* i : weighted A(z) unquantized for subframes */ - const Word16 Aq_fx[], /* i : 12k8 Lp coefficient */ - const Word16 Es_pred_fx, /* i : predicted scaled innov. energy */ - const Word16 *res_fx, /* i : residual signal */ - Word16 *syn_fx, /* i/o: core synthesis */ - Word16 *exc_fx, /* i/o: current non-enhanced excitation */ - Word16 *exc2_fx, /* i/o: current enhanced excitation */ - Word16 *pitch_buf_fx, /* i/o: floating pitch values for each subframe */ - Word16 *voice_factors, /* o : voicing factors */ - Word16 *bwe_exc_fx, /* i/o: excitation for SWB TBE */ - Word16 tc_subfr, /* i/o: TC subframe classification */ - Word16 position, /* i : maximum of residual signal index */ - Word16 *unbits, /* i/o: number of unused bits */ + const Word16 speech_fx[], /* i : input speech Q0*/ + const Word16 Aw_fx[], /* i : weighted A(z) unquantized for subframes Q12*/ + const Word16 Aq_fx[], /* i : 12k8 Lp coefficient Q12*/ + const Word16 Es_pred_fx, /* i : predicted scaled innov. energy Q8*/ + const Word16 *res_fx, /* i : residual signal Q_new*/ + Word16 *syn_fx, /* i/o: core synthesis Q_new*/ + Word16 *exc_fx, /* i/o: current non-enhanced excitation Q0*/ + Word16 *exc2_fx, /* i/o: current enhanced excitation Q0*/ + Word16 *pitch_buf_fx, /* i/o: floating pitch values for each subframe Q6*/ + Word16 *voice_factors, /* o : voicing factors Q15*/ + Word16 *bwe_exc_fx, /* i/o: excitation for SWB TBE Q0*/ + Word16 tc_subfr, /* i/o: TC subframe classification Q0*/ + Word16 position, /* i : maximum of residual signal index Q0*/ + Word16 *unbits, /* i/o: number of unused bits Q0*/ const Word16 shift, /* i : Scaling to get 12 bits */ const Word16 Q_new /* i : Input scaling */ ); @@ -1876,61 +1951,66 @@ void deleteFdCngEnc_fx( HANDLE_FD_CNG_ENC *hFdCngEnc ); void coder_acelp_rf_fx( ACELP_config *acelp_cfg_rf, /*i /o : configuration of the ACELP coding*/ - const Word16 coder_type, /* i : coding type */ - const Word16 A[], /* i : coefficients 4xAz[M+1] */ - const Word16 Aq[], /* i : coefficients 4xAz_q[M+1] */ - Word16 speech[], /* i : speech[-M..lg] */ - const Word16 voicing[], /* i : open-loop LTP gain */ - const Word16 T_op[], /* i : open-loop LTP lag */ - Word16 stab_fac, + const Word16 coder_type, /* input: coding type Q0*/ + const Word16 A[], /* input: coefficients 4xAz[M+1] Q12*/ + const Word16 Aq[], /* input: coefficients 4xAz_q[M+1] Q12*/ + Word16 speech[], /* input: speech[-M..lg] Q_new-1*/ + const Word16 voicing[], /* input: open-loop LTP gain Q15*/ + const Word16 T_op[], /* input: open-loop LTP lag Q0*/ + Word16 stab_fac, /* Q15 */ Encoder_State *st, - Word16 target_bits, /* i/o : coder memory state */ - const Word16 rf_frame_type, /* i : rf_frame_type */ - Word16 *exc_rf, /* i/o: pointer to RF excitation */ - Word16 *syn_rf, /* i/o: pointer to RF synthesis */ + Word16 target_bits, /* i/o : coder memory state Q0*/ + const Word16 rf_frame_type, /* i : rf_frame_type Q0*/ + Word16 *exc_rf, /* i/o: pointer to RF excitation Q_new*/ + Word16 *syn_rf, /* i/o: pointer to RF synthesis Q_new-1*/ Word16 Q_new, Word16 shift ); /* Create an instance of type FD_CNG */ void createFdCngEnc_fx( HANDLE_FD_CNG_ENC *hFdCngEnc ); -void initFdCngEnc_fx( HANDLE_FD_CNG_ENC hsEnc, Word32 input_Fs, Word16 scale ); +void initFdCngEnc_fx( + HANDLE_FD_CNG_ENC hsEnc, + Word32 input_Fs, /* Q0 */ + Word16 scale ); /* Configure CLDFB-CNG */ void configureFdCngEnc_fx( HANDLE_FD_CNG_ENC hs, /* i/o: Contains the variables related to the CLDFB-based CNG process */ - Word16 bandwidth, /* i: bandwidth */ - Word32 bitrate ); + Word16 bandwidth, /* i: bandwidth Q0*/ + Word32 bitrate /* Q0 */ +); /* Perform noise estimation */ void perform_noise_estimation_enc_fx( - Word32 *band_energies, /* i: energy in critical bands without minimum noise floor MODE2_E_MIN */ + Word32 *band_energies, /* i: energy in critical bands without minimum noise floor MODE2_E_MIN exp_band_energies*/ Word16 exp_band_energies, - Word32 *enerBuffer, + Word32 *enerBuffer, /* enerBuffer_exp */ Word16 enerBuffer_exp, HANDLE_FD_CNG_ENC st ); /* i/o: FD_CNG structure containing all buffers and variables */ void perform_noise_estimation_enc_ivas_fx( - Word32 *band_energies, /* i: energy in critical bands without minimum noise floor MODE2_E_MIN */ + Word32 *band_energies, /* i: energy in critical bands without minimum noise floor MODE2_E_MIN band_energies_exp*/ Word16 band_energies_exp, - Word32 *enerBuffer, + Word32 *enerBuffer, /* enerBuffer_exp */ Word16 enerBuffer_exp, HANDLE_FD_CNG_ENC hFdCngEnc, /* i/o: CNG structure containing all buffers and variables */ - const Word32 input_Fs, /* i : input sampling rate */ + const Word32 input_Fs, /* i : input sampling rate Q0*/ CPE_ENC_HANDLE hCPE /* i : CPE encoder structure */ ); /* Adjust the noise estimator at the beginning of each CNG phase (encoder-side) */ -Word16 -AdjustFirstSID_fx( Word16 npart, - Word32 *msPeriodog, - Word16 msPeriodog_exp, - Word32 *energy_ho, - Word16 *energy_ho_exp, - Word32 *msNoiseEst, - Word16 *msNoiseEst_exp, - Word32 *msNoiseEst_old, - Word16 *msNoiseEst_old_exp, - Word16 *active_frame_counter, - Encoder_State *stcod ); +Word16 AdjustFirstSID_fx( + Word16 npart, /* i : number of parts Q0*/ + Word32 *msPeriodog, /* i : pointer to periodog vector msPeriodog_exp */ + Word16 msPeriodog_exp, /* i : exponent of periodog vector */ + Word32 *energy_ho, /* i/o : pointer to energy energy_ho_exp*/ + Word16 *energy_ho_exp, /* i/o : pointer to exponent of energy */ + Word32 *msNoiseEst, /* i/o : pointer to estimated noise msNoiseEst_exp*/ + Word16 *msNoiseEst_exp, /* i/o : pointer to exponent of estimated noise */ + Word32 *msNoiseEst_old, /* i/o : pointer to old estimated noise msNoiseEst_old_exp*/ + Word16 *msNoiseEst_old_exp, /* i/o : pointer to exponent of old estimated noise */ + Word16 *active_frame_counter, /* i/o : pointer to active frame counter Q0*/ + Encoder_State *stcod /* i : pointer to Coder_State_Plus structure */ +); void FdCng_encodeSID_ivas_fx( Encoder_State *st /* i/o: encoder state structure */ @@ -1940,113 +2020,113 @@ void resetFdCngEnc_fx( Encoder_State *st ); void encod_unvoiced_fx( Encoder_State *st_fx, /* i/o: state structure */ - const Word16 *speech_fx, /* i : Input speech */ - const Word16 Aw_fx[], /* i : weighted A(z) unquantized for subframes */ - const Word16 *Aq_fx, /* i : 12k8 Lp coefficient */ - const Word16 Es_pred, /* i : predicted scaled innov. energy */ - const Word16 uc_two_stage_flag, /* i : flag indicating two-stage UC */ - const Word16 *res_fx, /* i : residual signal */ - Word16 *syn_fx, /* o : core synthesis */ - Word16 *tmp_noise_fx, /* o : long-term noise energy */ - Word16 *exc_fx, /* i/o: current non-enhanced excitation */ - Word16 *pitch_buf_fx, /* o : floating pitch values for each subframe */ - Word16 *voice_factors_fx, /* o : voicing factors */ - Word16 *bwe_exc_fx, /* i/o: excitation for SWB TBE */ + const Word16 *speech_fx, /* i : Input speech Q_new*/ + const Word16 Aw_fx[], /* i : weighted A(z) unquantized for subframes Q12*/ + const Word16 *Aq_fx, /* i : 12k8 Lp coefficient Q12*/ + const Word16 Es_pred, /* i : predicted scaled innov. energy Q8*/ + const Word16 uc_two_stage_flag, /* i : flag indicating two-stage UC Q0*/ + const Word16 *res_fx, /* i : residual signal Q_new*/ + Word16 *syn_fx, /* o : core synthesis Q_new*/ + Word16 *tmp_noise_fx, /* o : long-term noise energy Q0*/ + Word16 *exc_fx, /* i/o: current non-enhanced excitation Q_new*/ + Word16 *pitch_buf_fx, /* o : floating pitch values for each subframe Q6*/ + Word16 *voice_factors_fx, /* o : voicing factors Q15*/ + Word16 *bwe_exc_fx, /* i/o: excitation for SWB TBE Q_exc*/ const Word16 Q_new, const Word16 shift ); void encod_unvoiced_ivas_fx( Encoder_State *st_fx, /* i/o: state structure */ - const Word16 *speech_fx, /* i : Input speech */ - const Word16 Aw_fx[], /* i : weighted A(z) unquantized for subframes */ - const Word16 *Aq_fx, /* i : 12k8 Lp coefficient */ - const Word16 Es_pred, /* i : predicted scaled innov. energy */ - const Word16 uc_two_stage_flag, /* i : flag indicating two-stage UC */ - const Word16 *res_fx, /* i : residual signal */ - Word16 *syn_fx, /* o : core synthesis */ - Word16 *tmp_noise_fx, /* o : long-term noise energy */ - Word16 *exc_fx, /* i/o: current non-enhanced excitation */ - Word16 *pitch_buf_fx, /* o : floating pitch values for each subframe */ - Word16 *voice_factors_fx, /* o : voicing factors */ - Word16 *bwe_exc_fx, /* i/o: excitation for SWB TBE */ + const Word16 *speech_fx, /* i : Input speech Q_new*/ + const Word16 Aw_fx[], /* i : weighted A(z) unquantized for subframes Q12*/ + const Word16 *Aq_fx, /* i : 12k8 Lp coefficient Q12*/ + const Word16 Es_pred, /* i : predicted scaled innov. energy Q8*/ + const Word16 uc_two_stage_flag, /* i : flag indicating two-stage UC Q0*/ + const Word16 *res_fx, /* i : residual signal Q_new*/ + Word16 *syn_fx, /* o : core synthesis Q_new*/ + Word16 *tmp_noise_fx, /* o : long-term noise energy Q0*/ + Word16 *exc_fx, /* i/o: current non-enhanced excitation Q_new*/ + Word16 *pitch_buf_fx, /* o : floating pitch values for each subframe Q6*/ + Word16 *voice_factors_fx, /* o : voicing factors Q15*/ + Word16 *bwe_exc_fx, /* i/o: excitation for SWB TBE Q_exc*/ const Word16 Q_new, const Word16 shift ); void enc_acelp_tcx_main_fx( - const Word16 new_samples[], /* i : new samples */ - Encoder_State *st, /* i/o: encoder state structure */ - Word16 Aw[NB_SUBFR16k * ( M + 1 )], /* i : weighted A(z) unquant. for subframes*/ - const Word16 lsp_new[M], /* i : LSPs at the end of the frame */ - const Word16 lsp_mid[M], /* i : LSPs at the middle of the frame */ - Word32 bwe_exc_extended[], /* i/o: bandwidth extended excitation */ - Word16 *voice_factors, /* o : voicing factors */ - Word16 pitch_buf[], /* o : floating pitch for each subframe */ - Word16 vad_hover_flag, /* i : VAD hangover flag */ + const Word16 new_samples[], /* i : new samples Q15*/ + Encoder_State *st, /* i/o: encoder state structure */ + Word16 Aw[NB_SUBFR16k * ( M + 1 )], /* i : weighted A(z) unquant. for subframes Q12*/ + const Word16 lsp_new[M], /* i : LSPs at the end of the frame Q15*/ + const Word16 lsp_mid[M], /* i : LSPs at the middle of the frame Q15*/ + Word32 bwe_exc_extended[], /* i/o: bandwidth extended excitation Q_new*/ + Word16 *voice_factors, /* o : voicing factors Q15*/ + Word16 pitch_buf[], /* o : floating pitch for each subframe Q6*/ + Word16 vad_hover_flag, /* i : VAD hangover flag Q0*/ Word16 *Q_new, Word16 *shift ); ivas_error encod_ppp_fx( Encoder_State *st_fx, /* i/o: state structure */ - const Word16 speech_fx[], /* i : i speech Q_new*/ - const Word16 Aw_fx[], /* i : weighted A(z) unquantized for subframes */ - const Word16 Aq_fx[], /* i : 12k8 Lp coefficient */ - Word16 *res_fx, /* i : residual signal Q_new*/ - Word16 *synth_fx, /* o : core synthesis Q-1*/ - Word16 *exc_fx, /* i/o: current non-enhanced excitation Q_new*/ - Word16 *exc2_fx, /* o : current enhanced excitation Q0*/ - Word16 *pitch_buf_fx, /* o : floating pitch values for each subframe Q6*/ - Word16 *voice_factors, /* o : voicing factors */ - Word16 *bwe_exc, /* o : excitation for SWB TBE */ + const Word16 speech_fx[], /* i : input speech Q_new*/ + const Word16 Aw_fx[], /* i : weighted A(z) unquantized for subframes Q12*/ + const Word16 Aq_fx[], /* i : 12k8 Lp coefficient Q14*/ + Word16 *res_fx, /* i : residual signal Q_new*/ + Word16 *synth_fx, /* o : core synthesis Q-1*/ + Word16 *exc_fx, /* i/o: current non-enhanced excitation Q_new*/ + Word16 *exc2_fx, /* o : current enhanced excitation Q0*/ + Word16 *pitch_buf_fx, /* o : floating pitch values for each subframe Q6*/ + Word16 *voice_factors, /* o : voicing factors Q15*/ + Word16 *bwe_exc, /* o : excitation for SWB TBE Q_new*/ Word16 Q_new, Word16 shift ); ivas_error encod_ppp_ivas_fx( Encoder_State *st_fx, /* i/o: state structure */ - const Word16 speech_fx[], /* i : input speech Q_new*/ - const Word16 Aw_fx[], /* i : weighted A(z) unquantized for subframes */ - const Word16 Aq_fx[], /* i : 12k8 Lp coefficient */ - Word16 *res_fx, /* i : residual signal Q_new*/ - Word16 *synth_fx, /* o : core synthesis Q-1*/ - Word16 *exc_fx, /* i/o: current non-enhanced excitation Q_new*/ - Word16 *exc2_fx, /* o : current enhanced excitation Q0*/ - Word16 *pitch_buf_fx, /* o : floating pitch values for each subframe Q6*/ - Word16 *voice_factors, /* o : voicing factors */ - Word16 *bwe_exc, /* o : excitation for SWB TBE */ + const Word16 speech_fx[], /* i : input speech Q_new*/ + const Word16 Aw_fx[], /* i : weighted A(z) unquantized for subframes Q12*/ + const Word16 Aq_fx[], /* i : 12k8 Lp coefficient Q12*/ + Word16 *res_fx, /* i : residual signal Q_new*/ + Word16 *synth_fx, /* o : core synthesis Q-1*/ + Word16 *exc_fx, /* i/o: current non-enhanced excitation Q_new*/ + Word16 *exc2_fx, /* o : current enhanced excitation Q0*/ + Word16 *pitch_buf_fx, /* o : floating pitch values for each subframe Q6*/ + Word16 *voice_factors, /* o : voicing factors Q15*/ + Word16 *bwe_exc, /* o : excitation for SWB TBE Q_new*/ Word16 Q_new, Word16 shift ); void encod_gen_voic_fx( Encoder_State *st_fx, /* i/o: state structure */ - const Word16 speech_fx[], /* i : i speech */ - const Word16 Aw_fx[], /* i : weighted A(z) unquantized for subframes */ - const Word16 Aq_fx[], /* i : 12k8 Lp coefficient */ - const Word16 Es_pred_fx, /* i : predicted scaled innov. energy */ - const Word16 *res_fx, /* i : residual signal */ - Word16 *syn_fx, /* i/o: core synthesis */ - Word16 *exc_fx, /* i/o: current non-enhanced excitation */ - Word16 *exc2_fx, /* i/o: current enhanced excitation */ - Word16 *pitch_buf_fx, /* i/o: floating pitch values for each subframe */ - Word16 *voice_factors_fx, /* o : voicing factors */ - Word16 *bwe_exc_fx, /* o : excitation for SWB TBE */ - Word16 *unbits_fx, /* i/o: number of unused bits */ - const Word16 tdm_Pitch_reuse_flag, /* i : primary channel pitch reuse flag */ - const Word16 tdm_Pri_pitch_buf[], /* i : primary channel pitch buffer */ + const Word16 speech_fx[], /* i : i speech Q0*/ + const Word16 Aw_fx[], /* i : weighted A(z) unquantized for subframes Q12*/ + const Word16 Aq_fx[], /* i : 12k8 Lp coefficient Q12*/ + const Word16 Es_pred_fx, /* i : predicted scaled innov. energy Q8*/ + const Word16 *res_fx, /* i : residual signal Q_new*/ + Word16 *syn_fx, /* i/o: core synthesis Q_new*/ + Word16 *exc_fx, /* i/o: current non-enhanced excitation Q0*/ + Word16 *exc2_fx, /* i/o: current enhanced excitation Q0*/ + Word16 *pitch_buf_fx, /* i/o: floating pitch values for each subframe Q6*/ + Word16 *voice_factors_fx, /* o : voicing factors Q15*/ + Word16 *bwe_exc_fx, /* o : excitation for SWB TBE Q0*/ + Word16 *unbits_fx, /* i/o: number of unused bits Q0*/ + const Word16 tdm_Pitch_reuse_flag, /* i : primary channel pitch reuse flag Q0*/ + const Word16 tdm_Pri_pitch_buf[], /* i : primary channel pitch buffer Q6*/ Word16 shift, Word16 Q_new ); void encod_gen_voic_ivas_fx( Encoder_State *st_fx, /* i/o: state structure */ - const Word16 speech_fx[], /* i : input speech */ - const Word16 Aw_fx[], /* i : weighted A(z) unquantized for subframes */ - const Word16 Aq_fx[], /* i : 12k8 Lp coefficient */ - const Word16 Es_pred_fx, /* i : predicted scaled innov. energy */ - const Word16 *res_fx, /* i : residual signal */ - Word16 *syn_fx, /* i/o: core synthesis */ - Word16 *exc_fx, /* i/o: current non-enhanced excitation */ - Word16 *exc2_fx, /* i/o: current enhanced excitation */ - Word16 *pitch_buf_fx, /* i/o: floating pitch values for each subframe */ - Word16 *voice_factors_fx, /* o : voicing factors */ - Word16 *bwe_exc_fx, /* o : excitation for SWB TBE */ - Word16 *unbits_fx, /* i/o: number of unused bits */ - const Word16 tdm_Pitch_reuse_flag, /* i : primary channel pitch reuse flag */ - const Word16 tdm_Pri_pitch_buf[], /* i : primary channel pitch buffer */ + const Word16 speech_fx[], /* i : input speech Q0*/ + const Word16 Aw_fx[], /* i : weighted A(z) unquantized for subframes Q12*/ + const Word16 Aq_fx[], /* i : 12k8 Lp coefficient Q12*/ + const Word16 Es_pred_fx, /* i : predicted scaled innov. energy Q8*/ + const Word16 *res_fx, /* i : residual signal Q_new*/ + Word16 *syn_fx, /* i/o: core synthesis Q_new*/ + Word16 *exc_fx, /* i/o: current non-enhanced excitation Q0*/ + Word16 *exc2_fx, /* i/o: current enhanced excitation Q0*/ + Word16 *pitch_buf_fx, /* i/o: floating pitch values for each subframe Q6*/ + Word16 *voice_factors_fx, /* o : voicing factors Q15*/ + Word16 *bwe_exc_fx, /* o : excitation for SWB TBE Q0*/ + Word16 *unbits_fx, /* i/o: number of unused bits Q0*/ + const Word16 tdm_Pitch_reuse_flag, /* i : primary channel pitch reuse flag Q0*/ + const Word16 tdm_Pri_pitch_buf[], /* i : primary channel pitch buffer Q6*/ Word16 shift, Word16 Q_new ); @@ -2110,10 +2190,6 @@ void stat_noise_uv_enc_ivas_fx( void analy_sp_fx( const Word16 element_mode, /* i : element mode */ -#ifdef IVAS_CODE_CPE - CPE_ENC_HANDLE hCPE, /* i/o: CPE encoder structure */ -#endif - const Word32 input_Fs, /* i : i sampling rate */ Word16 *speech, /* i : speech buffer Q_new - preemph_bits */ const Word16 Q_new, /* i : current scaling exp Q0 */ Word32 *fr_bands, /* o : energy in critical frequency bands Q_new + QSCALE */ @@ -2130,46 +2206,31 @@ void analy_sp_fx( Word32 *band_energies, /* o : energy in critical frequency bands without minimum noise floor MODE2_E_MIN */ Word16 *fft_buff /* o : FFT coefficients */ ); -void ivas_analy_sp_fx( - const Word16 element_mode, /* i : element mode */ - CPE_ENC_HANDLE hCPE, /* i/o: CPE encoder structure */ - const Word32 input_Fs, /* i : input sampling rate */ - Word16 *speech, /* i : speech buffer Q_new - preemph_bits */ - const Word16 Q_new, /* i : current scaling exp Q0 */ - Word32 *fr_bands, /* o : energy in critical frequency bands Q_new + QSCALE */ - Word32 *lf_E, /* o : per bin E for first... Q_new + QSCALE - 2*/ - Word16 *Etot, /* o : total input energy Q8 */ - const Word16 min_band, /* i : minimum critical band Q0 */ - const Word16 max_band, /* i : maximum critical band Q0 */ - const Word32 e_min_scaled, /* i : minimum energy scaled Q_new + QSCALE */ - Word16 Scale_fac[2], /* o : FFT scales factors (2 values by frame) Q0 */ - Word32 *Bin_E, /* o : per-bin energy spectrum Q7 */ - Word32 *Bin_E_old, /* o : per-bin energy spectrum of the previous frame Q7 */ - Word32 *PS, /* o : per-bin energy spectrum Q_new + QSCALE */ - Word16 *EspecdB, /* o : per-bin log energy spectrum (with f=0) Q7 */ - Word32 *band_energies, /* o : energy in critical frequency bands without minimum noise floor MODE2_E_MIN (Q_new + QSCALE + 2)*/ - Word16 *fft_buff /* o : FFT coefficients (Q_new + QSCALE + 2) */ -); -void ivas_analy_sp_fx_front( - const Word16 element_mode, /* i : element mode */ - CPE_ENC_HANDLE hCPE, /* i/o: CPE encoder structure */ - const Word32 input_Fs, /* i : input sampling rate */ - Word16 *speech, /* i : speech buffer Q_new - preemph_bits */ - const Word16 Q_new, /* i : current scaling exp Q0 */ - Word32 *fr_bands, /* o : energy in critical frequency bands Q_new + QSCALE */ - Word32 *lf_E, /* o : per bin E for first... Q_new + QSCALE - 2*/ - Word16 *Etot, /* o : total input energy Q8 */ - const Word16 min_band, /* i : minimum critical band Q0 */ - const Word16 max_band, /* i : maximum critical band Q0 */ - const Word32 e_min_scaled, /* i : minimum energy scaled Q_new + QSCALE */ - Word16 Scale_fac[2], /* o : FFT scales factors (2 values by frame) Q0 */ - Word32 *Bin_E, /* o : per-bin energy spectrum Q7 */ - Word32 *Bin_E_old, /* o : per-bin energy spectrum of the previous frame Q7 */ - Word32 *PS, /* o : per-bin energy spectrum Q_new + QSCALE - 2 */ - Word16 *EspecdB, /* o : per-bin log energy spectrum (with f=0) Q7 */ - Word32 *band_energies, /* o : energy in critical frequency bands without minimum noise floor MODE2_E_MIN (Q_new + QSCALE)*/ - Word16 *fft_buff /* o : FFT coefficients (Q_new + Scale_fac[i_subfr]) */ +void ivas_analy_sp_fx( + const Word16 element_mode, /* i : element mode Q0 */ + CPE_ENC_HANDLE hCPE, /* i/o: CPE encoder structure */ + const Word32 input_Fs, /* i : input sampling rate Q0 */ + Word16 *speech, /* i : speech buffer Q_new */ + const Word16 Q_new, /* i : current scaling exp Q0 */ + Word32 *fr_bands, /* o : energy in critical frequency bands q_fr_bands */ + Word16 *q_fr_bands, /* o : energy in critical frequency bands Q0 */ + Word32 *lf_E, /* o : per bin E for first... q_lf_E */ + Word16 *q_lf_E, /* o : per bin E for first... Q0 */ + Word16 *Etot, /* o : total input energy Q8 */ + const Word16 min_band, /* i : minimum critical band Q0 */ + const Word16 max_band, /* i : maximum critical band Q0 */ + Word32 *Bin_E, /* o : per-bin energy spectrum q_Bin_E */ + Word16 *q_Bin_E, /* o : per-bin energy spectrum Q0 */ + Word32 *Bin_E_old, /* o : per-bin energy spectrum of the previous frame q_Bin_E_old */ + Word16 *q_Bin_E_old, /* o : per-bin energy spectrum of the previous frame Q0 */ + Word32 *PS, /* o : per-bin energy spectrum q_PS */ + Word16 *q_PS, /* o : per-bin energy spectrum Q0 */ + Word16 *EspecdB, /* o : per-bin log energy spectrum (with f=0) Q7 */ + Word32 *band_energies, /* o : energy in critical frequency bands without minimum noise floor MODE2_E_MIN (q_band_energies) */ + Word16 *q_band_energies, /* o : Q of energy in critical frequency bands without minimum noise floor MODE2_E_MIN */ + Word16 *fft_buff, /* o : FFT coefficients (q_fft_buff) */ + Word16 *q_fft_buff /* o : Q of FFT coefficients Q0 */ ); void find_wsp_fx( const Word16 Az[], @@ -2186,9 +2247,26 @@ void find_wsp_fx( ); Word16 ari_encode_overflow_fx( TastatEnc *s ); -Word16 ari_encode_14bits_range_fx( Word16 *ptr, Word16 bp, Word16 bits, TastatEnc *s, Word16 cum_freq_low, Word16 cum_freq_high ); -Word16 ari_encode_14bits_sign_fx( Word16 *ptr, Word16 bp, Word16 bits, TastatEnc *s, Word16 sign ); -Word16 ari_done_cbr_encoding_14bits_fx( Word16 *ptr, Word16 bp, Word16 bits, TastatEnc *s ); +Word16 ari_encode_14bits_range_fx( + Word16 *ptr, /* Q0 */ + Word16 bp, /* Q0 */ + Word16 bits, /* Q0 */ + TastatEnc *s, + Word16 cum_freq_low, /* Q0 */ + Word16 cum_freq_high /* Q0 */ +); +Word16 ari_encode_14bits_sign_fx( + Word16 *ptr, /* Q0 */ + Word16 bp, /* Q0 */ + Word16 bits, /* Q0 */ + TastatEnc *s, + Word16 sign /* Q0 */ +); +Word16 ari_done_cbr_encoding_14bits_fx( + Word16 *ptr, /* Q0 */ + Word16 bp, /* Q0 */ + Word16 bits, /* Q0 */ + TastatEnc *s ); void tcx_hm_analyse_fx( const Word32 abs_spectrum[], /* i: absolute spectrum Q31-e */ @@ -2202,75 +2280,74 @@ void tcx_hm_analyse_fx( const Word16 LtpGain, /* i: LTP gain Q15 */ Word16 *hm_bits_out /* o: bit consumption Q0 */ ); -void E_ACELP_4tsearchx_fx( Word16 dn[], const Word16 cn[], Word16 Rw[], Word16 code[], const PulseConfig *config, Word16 ind[] ); +void E_ACELP_4tsearchx_fx( Word16 dn[] /*Qdn*/, const Word16 cn[] /*Q_new*/, Word16 Rw[] /*Q9*/, Word16 code[] /*Q9*/, const PulseConfig *config, Word16 ind[] /*Q0*/ ); void E_ACELP_4tsearchx_ivas_fx( - Word16 dn[], - const Word16 cn[], - Word16 Rw[], - Word16 code[], + Word16 dn[], /*Qdn*/ + const Word16 cn[], /*Q_new*/ + Word16 Rw[], /*Q9*/ + Word16 code[], /*Q9*/ const PulseConfig *config, - Word16 ind[], + Word16 ind[], /*Q0*/ Word16 element_mode ); void E_ACELP_weighted_code( - const Word16 code[], /* i: code */ - const Word16 H[], /* i: impulse response */ - Word16 Q, /* i: Q format of H */ - Word16 y[] /* o: weighted code */ + const Word16 code[], /* i: code Q9*/ + const Word16 H[], /* i: impulse response Q*/ + Word16 Q, /* i: Q format of H */ + Word16 y[] /* o: weighted code Q9*/ ); void find_targets_fx( const Word16 *speech, /* i : pointer to the speech frame Q_new-1*/ const Word16 *mem_syn, /* i : memory of the synthesis filter Q_new-1*/ - const Word16 i_subfr, /* i : subframe index */ + const Word16 i_subfr, /* i : subframe index Q0*/ Word16 *mem_w0, /* i/o: weighting filter denominator memory Q_new-1*/ const Word16 *p_Aq, /* i : interpolated quantized A(z) filter Q12*/ const Word16 *res, /* i : residual signal Q_new*/ - const Word16 L_subfr, /* i : length of vectors for gain quantization */ + const Word16 L_subfr, /* i : length of vectors for gain quantization Q0*/ const Word16 *Ap, /* i : unquantized A(z) filter with bandwidth expansion Q12*/ - Word16 tilt_fac, /* i : tilt factor Q15 */ + Word16 tilt_fac, /* i : tilt factor Q15*/ Word16 *xn, /* o : Close-loop Pitch search target vector Q_new-1*/ - Word16 *cn /* o : target vector in residual domain Q_new*/ - , - Word16 *h1 /* Q14 ?*/ + Word16 *cn, /* o : target vector in residual domain Q_new*/ + Word16 *h1 /* o : impulse response of weighted synthesis filter Q14*/ ); void find_targets_ivas_fx( const Word16 *speech, /* i : pointer to the speech frame Q_new-1*/ const Word16 *mem_syn, /* i : memory of the synthesis filter Q_new-1*/ - const Word16 i_subfr, /* i : subframe index */ + const Word16 i_subfr, /* i : subframe index Q0*/ Word16 *mem_w0, /* i/o: weighting filter denominator memory Q_new-1*/ const Word16 *p_Aq, /* i : interpolated quantized A(z) filter Q12*/ const Word16 *res, /* i : residual signal Q_new*/ - const Word16 L_subfr, /* i : length of vectors for gain quantization */ + const Word16 L_subfr, /* i : length of vectors for gain quantization Q0*/ const Word16 *Ap, /* i : unquantized A(z) filter with bandwidth expansion Q12*/ - Word16 tilt_fac, /* i : tilt factor Q15 */ + Word16 tilt_fac, /* i : tilt factor Q15*/ Word16 *xn, /* o : Close-loop Pitch search target vector Q_new-1*/ Word16 *cn, /* o : target vector in residual domain Q_new*/ - Word16 *h1 /* o : impulse response of weighted synthesis filter */ + Word16 *h1 /* o : impulse response of weighted synthesis filter Q(14 - norm_s(h1[0]))*/ ); void E_ACELP_adaptive_codebook( - Word16 *exc, /* i : pointer to the excitation frame */ - Word16 T0, /* i : integer pitch lag */ - Word16 T0_frac, /* i : fraction of lag */ - Word16 T0_res, /* i : pitch resolution */ - Word16 T0_res_max, /* i : maximum pitch resolution */ - Word16 mode, /* i : filtering mode (0: no, 1: yes, 2: adaptive) */ - Word16 i_subfr, /* i : subframe index */ - Word16 L_subfr, /* i : subframe length */ - Word16 L_frame, /* i : subframe length */ - Word16 *h1, /* i : impulse response of weighted synthesis filter */ - Word16 clip_gain, - Word16 *xn, /* i : Close-loop Pitch search target vector */ - Word16 *y1, /* o : zero-memory filtered adaptive excitation */ + Word16 *exc, /* i : pointer to the excitation frame Q_new */ + Word16 T0, /* i : integer pitch lag Q0 */ + Word16 T0_frac, /* i : fraction of lag Q0 */ + Word16 T0_res, /* i : pitch resolution Q0 */ + Word16 T0_res_max, /* i : maximum pitch resolution Q0 */ + Word16 mode, /* i : filtering mode (0: no, 1: yes, 2: adaptive) Q0 */ + Word16 i_subfr, /* i : subframe index */ + Word16 L_subfr, /* i : subframe length Q0 */ + Word16 L_frame, /* i : subframe length Q0 */ + Word16 *h1, /* i : impulse response of weighted synthesis filter 1Q14+shift */ + Word16 clip_gain, /* Q14 */ + Word16 *xn, /* i : Close-loop Pitch search target vector Q_xn */ + Word16 *y1, /* o : zero-memory filtered adaptive excitation Q_xn */ ACELP_CbkCorr *g_corr, /* o : ACELP correlation values */ Word16 **pt_indice, /* i/o: quantization indices pointer */ - Word16 *pitch_gain, /* o : adaptive codebook gain */ + Word16 *pitch_gain, /* o : adaptive codebook gain 1Q14 */ Word16 exp_xn, Word16 rf_mode, Word16 use_prev_sf_pit_gain, Word16 *lp_select ); -void E_ACELP_xy2_corr( Word16 xn[], Word16 y1[], Word16 y2[], ACELP_CbkCorr *g_corr, Word16 L_subfr, Word16 exp_xn ); +void E_ACELP_xy2_corr( Word16 xn[] /*Q_xn*/, Word16 y1[] /*Q_xn*/, Word16 y2[] /*Q9*/, ACELP_CbkCorr *g_corr, Word16 L_subfr /*Q0*/, Word16 exp_xn ); void gauss_L2_fx( const Word16 h[], /* i : weighted LP filter impulse response Q14+s */ @@ -2314,12 +2391,12 @@ Word16 SearchPeriodicityIndex_fx( ); Word16 ACcontextMapping_encode2_estimate_no_mem_s17_LC_fx( - const Word16 *x, - Word16 nt, - Word16 *lastnz, - Word16 *nEncoded, - Word16 target, - Word16 *stop, + const Word16 *x, /* Q0 */ + Word16 nt, /* Q0 */ + Word16 *lastnz_out, /* Q0 */ + Word16 *nEncoded, /* Q0 */ + Word16 target, /* Q0 */ + Word16 *stop, /* Q0 */ CONTEXT_HM_CONFIG *hm_cfg ); void tcx_arith_encode_envelope_fx( @@ -2341,6 +2418,24 @@ void tcx_arith_encode_envelope_fx( const Word16 low_complexity /* i: low-complexity flag Q0 */ ); +void tcx_arith_encode_envelope_ivas_fx( + Word32 spectrum[], /* i/o: MDCT coefficients Q31-e */ + Word16 *spectrum_e, /* i/o: MDCT exponent Q0 */ + Word16 signs[], /* o: signs (spectrum[.]<0) Q0 */ + const Word16 L_frame, /* i: frame or MDCT length Q0 */ + const Word16 L_spec, /* i: frame or MDCT length Q0 */ + Encoder_State *st, /* i/o: coder state */ + const Word16 A_ind[], /* i: quantised LPC coefficients Q12 */ + Word16 target_bits, /* i: number of available bits Q0 */ + Word16 prm[], /* o: bitstream parameters Q0 */ + const Word8 use_hm, /* i: use HM in current frame? */ + Word16 prm_hm[], /* o: HM parameter area Q0 */ + const Word16 tcxltp_pitch, /* i: TCX LTP pitch in FD, -1 if n/a Q0*/ + Word16 *arith_bits, /* o: bits used for ari. coding Q0 */ + Word16 *signaling_bits, /* o: bits used for signaling Q0 */ + const Word16 low_complexity /* i: low-complexity flag Q0 */ +); + /** Quantize gain. * Quantize gain in range [0..127], * @param n Length of the spectrum. @@ -2352,38 +2447,38 @@ void QuantizeGain( Word16 n, Word16 *pGain, Word16 *pGain_e, Word16 *pQuantizedG void core_signal_analysis_high_bitrate_fx( const Word16 *new_samples, /*i: 0Q15*/ - const Word16 T_op[3], /* i : open-loop pitch values for quantiz. */ - Word16 lsp_new[], - Word16 lsp_mid[], + const Word16 T_op[3], /* i : open-loop pitch values for quantiz. Q0*/ + Word16 lsp_new[], /* Q15 */ + Word16 lsp_mid[], /* Q15 */ Encoder_State *st, - Word16 pTnsSize[], - Word16 pTnsBits[], - Word16 param_core[], - Word16 *ltpBits, - const Word16 L_frame, - const Word16 L_frameTCX, - const Word16 last_element_mode, - const Word16 vad_hover_flag, /* i : VAD hangover flag */ - Word32 **spectrum, + Word16 pTnsSize[], /* Q0 */ + Word16 pTnsBits[], /* Q0 */ + Word16 param_core[], /* Q0 */ + Word16 *ltpBits, /* Q0 */ + const Word16 L_frame, /* Q0 */ + const Word16 L_frameTCX, /* Q0 */ + const Word16 last_element_mode, /* Q0 */ + const Word16 vad_hover_flag, /* i : VAD hangover flag Q0*/ + Word32 **spectrum, /* spectrum_e */ Word16 *spectrum_e, Word16 *Q_new ); void core_signal_analysis_high_bitrate_ivas_fx( const Word16 *new_samples, /*i: Q0 */ - const Word16 T_op[3], /* i : open-loop pitch values for quantiz. */ + const Word16 T_op[3], /* i : open-loop pitch values for quantiz. Q0*/ Word16 lsp_new[], /* Q15 */ Word16 lsp_mid[], /* Q15 */ Encoder_State *st, - Word16 pTnsSize[], - Word16 pTnsBits[], - Word16 param_core[], - Word16 *ltpBits, - Word32 *windowed_samples, - const Word16 L_frame, - const Word16 L_frameTCX, - const Word16 last_element_mode, - const Word16 vad_hover_flag, /* i : VAD hangover flag */ - Word32 **spectrum, + Word16 pTnsSize[], /* Q0 */ + Word16 pTnsBits[], /* Q0 */ + Word16 param_core[], /* Q0 */ + Word16 *ltpBits, /* Q0 */ + Word32 *windowed_samples, /* q_win */ + const Word16 L_frame, /* Q0 */ + const Word16 L_frameTCX, /* Q0 */ + const Word16 last_element_mode, /* Q0 */ + const Word16 vad_hover_flag, /* i : VAD hangover flag Q0*/ + Word32 **spectrum, /* exp(spectrum_e) */ Word16 *spectrum_e, Word16 *Q_new, Word16 *q_win ); @@ -2439,7 +2534,7 @@ void QuantizeTCXSpectrum_fx( Encoder_State *st, /* i : state handle */ const Word16 frame_cnt, /* i : frame counter in the super_frame Q0 */ Word32 *x_orig_fx, /* i : shaped MDCT spectrum */ - const Word16 x_orig_e, /* i : exp of shaped MDCT spectrum */ + Word16 x_orig_e, /* i : exp of shaped MDCT spectrum */ Word16 *gainlpc_fx, /* i : FDNS gains */ Word16 *gainlpc_e, /* i : exp of FDNS gains */ const Word16 *Aqind, /* i : frame-independent quantized coefficients (M+1) Q0 */ @@ -2561,6 +2656,19 @@ Word16 Q_lsf_tcxlpc_fx( const Word32 *Bin_Ener, const Word16 Q_ener ); +Word16 Q_lsf_tcxlpc_ivas_fx( + /* const */ Word16 lsf[], /* i : original lsf */ + Word16 lsf_q[], /* o : quantized lsf */ + Word16 lsp_q_ind[], /* o : quantized lsp (w/o MA prediction) */ + Word16 indices[], /* o : VQ indices */ + const Word16 lpcorder, /* i : LPC order */ + const Word16 narrowband, /* i : narrowband flag */ + const Word16 cdk, /* i : codebook selector */ + const Word16 mem_MA[], /* i : MA memory */ + const Word16 coder_type, + const Word32 *Bin_Ener, + const Word16 Q_ener ); + Word16 signalling_mode1_tcx20_enc_fx( Encoder_State *st, /* i : encoder state structure */ Word16 push /*Q0*/ ); @@ -2662,36 +2770,36 @@ void enc_prm_rf_fx( void enc_prm_rf_ivas_fx( Encoder_State *st, const Word16 rf_frame_type, const Word16 fec_offset ); -void E_ACELP_pulsesign( const Word16 cn[], Word16 dn[], Word16 dn2[], Word16 sign[], Word16 vec[], const Word16 alp, Word16 const sign_val, const Word16 L_subfr ); +void E_ACELP_pulsesign( const Word16 cn[] /*Q_xn*/, Word16 dn[] /*Qdn*/, Word16 dn2[] /*Qdn2*/, Word16 sign[] /*Q13*/, Word16 vec[] /*Q15*/, const Word16 alp /*Q13*/, Word16 const sign_val /*Q15*/, const Word16 L_subfr /*Q0*/ ); -void E_ACELP_findcandidates( Word16 dn2[], Word16 dn2_pos[], Word16 pos_max[] ); +void E_ACELP_findcandidates( Word16 dn2[] /*Qx*/, Word16 dn2_pos[] /*Q0*/, Word16 pos_max[] /*Q0*/ ); void E_ACELP_setup_pulse_search_pos( - const PulseConfig *config, /* i: pulse configuration */ - Word16 k, /* i: interation number */ - UWord8 ipos[] /* o: pulse search positions */ + const PulseConfig *config, /* i: pulse configuration */ + Word16 k, /* i: interation number Q0*/ + UWord8 ipos[] /* o: pulse search positions Q0*/ ); void E_ACELP_build_code( - Word16 nb_pulse, /* i */ - const Word16 codvec[], /* i */ - const Word16 sign[], /* i */ - Word16 code[], /* o */ - Word16 ind[] /* o */ + Word16 nb_pulse, /* i Q0*/ + const Word16 codvec[], /* i Q0*/ + const Word16 sign[], /* i Q0*/ + Word16 code[], /* o Q9*/ + Word16 ind[] /* o Q0*/ ); void E_UTIL_f_convolve( const Word16 x[], const Word16 h[], Word16 y[], const Word16 size ); void E_ACELP_conv( - const Word16 xn2[], /* i */ - const Word16 h2[], /* i */ - Word16 cn2[] /* o */ + const Word16 xn2[], /* i Qx*/ + const Word16 h2[], /* i Q12*/ + Word16 cn2[] /* o Q0*/ ); -void E_ACELP_conv_ivas( - const Word16 xn2[], /* i */ - const Word16 h2[], /* i */ - Word16 cn2[] /* o */ +void E_ACELP_conv_ivas_fx( + const Word16 xn2[], /* i Qx*/ + const Word16 h2[], /* i Q12*/ + Word16 cn2[] /* o Q0*/ ); void gPLC_encInfo_fx( @@ -2761,18 +2869,18 @@ Word16 enc_lsf_tcxlpc_ivas_fx( Word16 encode_lpc_avq_fx( BSTR_ENC_HANDLE hBstr, /* i/o: bitstream handle */ - const Word16 numlpc, /* i : Number of sets of lpc */ - const Word16 *param_lpc, /* i : lpc parameters */ - const Word16 core, /* i : core */ - const Word16 element_mode /* i : element mode - decides between SNS and LPC coding */ + const Word16 numlpc, /* i : Number of sets of lpc Q0*/ + const Word16 *param_lpc, /* i : lpc parameters Q0*/ + const Word16 core, /* i : core Q0*/ + const Word16 element_mode /* i : element mode - decides between SNS and LPC coding Q0*/ ); Word16 encode_lpc_avq_ivas_fx( BSTR_ENC_HANDLE hBstr, /* i/o: bitstream handle */ - const Word16 numlpc, /* i : Number of sets of lpc */ - const Word16 *param_lpc, /* i : lpc parameters */ - const Word16 core, /* i : core */ - const Word16 element_mode /* i : element mode - decides between SNS and LPC coding */ + const Word16 numlpc, /* i : Number of sets of lpc Q0*/ + const Word16 *param_lpc, /* i : lpc parameters Q0*/ + const Word16 core, /* i : core Q0*/ + const Word16 element_mode /* i : element mode - decides between SNS and LPC coding Q0*/ ); Word16 lsf_bctcvq_encprm_fx( @@ -2815,11 +2923,11 @@ Word16 IGFEncWriteBitstream_fx( /**< ou void ACcontextMapping_encode2_no_mem_s17_LC_fx( BSTR_ENC_HANDLE hBstr, /* i/o: bitstream handle */ - Word16 *x, - Word16 nt, - Word16 lastnz, - Word16 nbbits, - Word16 resQMaxBits, + Word16 *x, /* Q0 */ + Word16 nt, /* Q0 */ + Word16 lastnz, /* Q0 */ + Word16 nbbits, /* Q0 */ + Word16 resQMaxBits, /* Q0 */ CONTEXT_HM_CONFIG *hm_cfg ); Word16 IGFEncWriteConcatenatedBitstream_fx( /**< out: Q0 | total number of bits written */ @@ -2909,11 +3017,11 @@ void qlpc_avq_fx( const Word16 *lsfmid, /* i : Input LSF vectors (14Q1*1.28) */ Word16 *lsf_q, /* o : Quantized LFS vectors (14Q1*1.28) */ Word16 *lsfmid_q, /* o : Quantized LFS vectors (14Q1*1.28) */ - Word16 *index, /* o : Quantization indices */ - Word16 *nb_indices, /* o : Number of quantization indices */ - Word16 *nbbits, /* o : Number of quantization bits */ - const Word16 core, /* i : TCX10 or TCX20 */ - const Word32 sr_core /* i : internal sampling rate */ + Word16 *index, /* o : Quantization indices Q0 */ + Word16 *nb_indices, /* o : Number of quantization indices Q0 */ + Word16 *nbbits, /* o : Number of quantization bits Q0 */ + const Word16 core, /* i : TCX10 or TCX20 Q0 */ + const Word32 sr_core /* i : internal sampling rate Q0 */ ); /* ivas_tcx_core_enc.c */ @@ -2945,6 +3053,14 @@ void IGF_ErodeSpectrum( Word16 *highPassEner_exp, /**< out: | Word16 pPowerSpectrum_exp, /**< in: | exponent of power spectrum */ const Word16 igfGridIdx /**< in: Q0 | IGF grid index */ ); + +void IGF_ErodeSpectrum_ivas_fx( const IGF_ENC_INSTANCE_HANDLE hInstance, /**< in: | instance handle of IGF Encoder */ + Word32 *pSpectrum, /**< in/out: | MDCT spectrum */ + Word32 *pPowerSpectrum, /**< in/out: | power spectrum */ + Word16 pPowerSpectrum_exp, /**< in: | exponent of power spectrum */ + const Word16 igfGridIdx, /**< in: Q0 | IGF grid index */ + const Word16 mct_on ); + void IGFEncApplyMono_fx( const IGF_ENC_INSTANCE_HANDLE hInstance, /**< in: | instance handle of IGF Encoder */ const Word16 igfGridIdx, /**< in: Q0 | IGF grid index */ Encoder_State *st, /**< in: | Encoder state */ @@ -2957,16 +3073,19 @@ void IGFEncApplyMono_fx( const IGF_ENC_INSTANCE_HANDLE hInstance, /**< in: | Word16 last_core_acelp /**< in: Q0 | indictaor if last frame was acelp coded */ ); -void IGFEncApplyMono_ivas_fx( Encoder_State *st, /* i : Encoder state */ - const int16_t igfGridIdx, /* i : IGF grid index */ - Word32 *pMDCTSpectrum_fx, /* i/o: MDCT spectrum */ - Word16 e_mdct, /* i : exponent of pMDCTspectrum */ - Word32 *pPowerSpectrum_fx, /* i/o: MDCT^2 + MDST^2 spectrum, or estimate */ - Word16 e_ps, /* i : exponent of pPowerSpectrum */ - const int16_t isTCX20, /* i : flag indicating if the input is TCX20 or TCX10/2xTCX5 */ - const int8_t isTNSActive, /* i : flag indicating if the TNS is active */ - const int16_t sp_aud_decision0, /* i : first stage switching decision */ - const int16_t vad_hover_flag /* i : VAD hangover flag */ +void IGFEncApplyMono_ivas_fx( Encoder_State *st, /* i : Encoder state */ +#ifdef MSAN_FIX + Word16 powerSpectrum_len, /* i: length of pPowerSpectrum_fx*/ +#endif + const Word16 igfGridIdx, /* i : IGF grid index */ + Word32 *pMDCTSpectrum_fx, /* i/o: MDCT spectrum */ + Word16 e_mdct, /* i : exponent of pMDCTspectrum */ + Word32 *pPowerSpectrum_fx, /* i/o: MDCT^2 + MDST^2 spectrum, or estimate */ + Word16 *e_ps, /* i : exponent of pPowerSpectrum */ + const Word16 isTCX20, /* i : flag indicating if the input is TCX20 or TCX10/2xTCX5 */ + const Word8 isTNSActive, /* i : flag indicating if the TNS is active */ + const Word16 sp_aud_decision0, /* i : first stage switching decision */ + const Word16 vad_hover_flag /* i : VAD hangover flag */ ); void IGFEncConcatenateBitstream_ivas_fx( const IGF_ENC_INSTANCE_HANDLE hIGFEnc, /* i : instance handle of IGF Encoder */ @@ -3021,33 +3140,32 @@ Word16 vad_proc_fx( ); void calc_lf_snr_fx( - Word32 *lf_snr_smooth, /* o : smoothed lf_snr*/ - Word32 *lf_snr, /* o : long time frequency domain - SNR calculated by l_speech_snr and l_silence_snr*/ - const Word32 l_speech_snr, /* i : sum of active frames snr */ - const Word32 l_speech_snr_count, /* i : amount of the active frame */ - const Word32 l_silence_snr, /* i : sum of the nonactive frames snr*/ - const Word32 l_silence_snr_count, /* i : amount of the nonactive frame */ - const Word16 fg_energy_count, /* i : amount of the foreground energy frame */ - const Word16 bg_energy_count, /* i : amount of the background energy frame */ - const Word16 bw_index /* i : band width index*/ + Word32 *lf_snr_smooth, /* o : smoothed lf_snr Q25*/ + Word32 *lf_snr, /* o : long time frequency domain SNR calculated by l_speech_snr and l_silence_snr Q25*/ + const Word32 l_speech_snr, /* i : sum of active frames snr Q16*/ + const Word32 l_speech_snr_count, /* i : amount of the active frame Q0*/ + const Word32 l_silence_snr, /* i : sum of the nonactive frames snr Q16*/ + const Word32 l_silence_snr_count, /* i : amount of the nonactive frame Q0*/ + const Word16 fg_energy_count, /* i : amount of the foreground energy frame Q0*/ + const Word16 bg_energy_count, /* i : amount of the background energy frame Q0*/ + const Word16 bw_index /* i : band width index Q0*/ ); void calc_lt_snr_fx( VAD_CLDFB_HANDLE hVAD_CLDFB, /* i/o: CLDFB VAD state */ - Word32 *lt_snr_org_fp, /* o : original long time SNR*/ - Word32 *lt_snr_fp, /* o : long time SNR calculated by fg_energy and bg_energy*/ - Word32 fg_energy, /* i : foreground energy sum */ - Word16 fg_energy_count, /* i : amount of the foreground energy frame */ - Word32 bg_energy, /* i : background energy sum */ - Word16 bg_energy_count, /* i : amount of the background energy frame */ - Word16 bw_index, /* i : band width index*/ - Word16 lt_noise_sp_center0 /* i : long time noise spectral center by 0*/ + Word32 *lt_snr_org_fp, /* o : original long time SNR Q25*/ + Word32 *lt_snr_fp, /* o : long time SNR calculated by fg_energy and bg_energy Q25*/ + Word32 fg_energy, /* i : foreground energy sum Qx*/ + Word16 fg_energy_count, /* i : amount of the foreground energy frame Q0*/ + Word32 bg_energy, /* i : background energy sum Qx*/ + Word16 bg_energy_count, /* i : amount of the background energy frame Q0*/ + Word16 bw_index, /* i : band width index Q0*/ + Word16 lt_noise_sp_center0 /* i : long time noise spectral center by 0 Q10*/ ); -void calc_snr_flux_fx( Word32 tsnr_fix, /*(i) time-domain SNR*/ - Word32 *pre_snr, /*(io)time-domain SNR storage*/ - Word32 *snr_flux /*(o) average tsnr*/ +void calc_snr_flux_fx( Word32 tsnr_fix, /*(i) time-domain SNR Q25*/ + Word32 *pre_snr, /*(io)time-domain SNR storage Q25*/ + Word32 *snr_flux /*(o) average tsnr Q25*/ ); Word16 vlpc_2st_cod_fx( /* o : number of allocated bits */ @@ -3093,9 +3211,9 @@ void spec_flatness_fx( Word32 *spec_amp, /*(i) spectral amplitude*/ void SetModeIndex_fx( Encoder_State *st, - Word32 last_total_brate, - const Word16 last_element_mode, - const Word16 is_mct, + Word32 last_total_brate, /* Q0 */ + const Word16 last_element_mode, /* Q0 */ + const Word16 is_mct, /* Q0 */ const Word16 shift ); void MDCT_selector_fx( @@ -3154,39 +3272,40 @@ void IGFSCFEncoderRestoreContextState_fx( ); void frame_spec_dif_cor_rate_fx( - VAD_CLDFB_HANDLE hVAD_CLDFB, /* i/o: CLDFB VAD state */ - Word32 *spec_amp, /* i : spectral amplitude*/ - Word16 sacle, /* i : the scaling of spec_amp*/ - Word16 f_tonality_rate[3] /* o : tonality rate*/ + VAD_CLDFB_HANDLE hVAD_CLDFB, /* i/o: CLDFB VAD state */ + Word32 *spec_amp, /* i : spectral amplitude scale*/ + Word16 sacle, /* i : the scaling of spec_amp */ + Word16 f_tonality_rate[3] /* o : tonality rate Qx*/ ); void est_energy_fx( - Word32 enerBuffer[CLDFB_NO_CHANNELS_MAX], /* i : energy vector per band */ - Word16 enerBuffer_exp, /* i : exponent of energy vector */ - Word32 *frame_sb_energy, /* o : energy of sub-band divided non-uniformly*/ - Word32 *frame_energy2_p, /* o : frame energy 2*/ - Word32 *HB_Power_p, /* o : high frequency energy*/ - Word32 *frame_energy_p, /* o : frame energy 1*/ - Word16 *sb_power_Q, /* o : the scaling of sb_power*/ - Word16 *frame_energy2_Q, /* o : the scaling of frame_energy*/ - Word16 *HB_Power_Q, /* o : the scaling of HB_Power*/ - Word16 *frame_energy_Q, /* o : the Scaling of frame_energy*/ - Word16 *frame_sb_energy_scale, /* o : the Scaling of frame_sb_energy[]*/ - const Word32 bandwidth /* i : band width*/ + Word32 enerBuffer[CLDFB_NO_CHANNELS_MAX], /* i : energy vector per band enerBuffer_exp*/ + Word16 enerBuffer_exp, /* i : exponent of energy vector */ + Word32 *frame_sb_energy, /* o : energy of sub-band divided non-uniformly frame_sb_energy_scale*/ + Word32 *frame_energy2_p, /* o : frame energy 2 frame_energy2_Q*/ + Word32 *HB_Power_p, /* o : high frequency energy HB_Power_Q*/ + Word32 *frame_energy_p, /* o : frame energy 1 frame_energy_Q*/ + Word16 *sb_power_Q, /* o : the scaling of sb_power */ + Word16 *frame_energy2_Q, /* o : the scaling of frame_energy */ + Word16 *HB_Power_Q, /* o : the scaling of HB_Power */ + Word16 *frame_energy_Q, /* o : the Scaling of frame_energy */ + Word16 *frame_sb_energy_scale, /* o : the Scaling of frame_sb_energy[] */ + const Word32 bandwidth /* i : band width Q0*/ ); void background_update_fx( - VAD_CLDFB_HANDLE hVAD_CLDFB, /* i/o: CLDFB VAD state */ - Word16 scale, /* i : the scaling of frame energy*/ - Word32 frame_energy, /* i : current frame energy*/ - Word32 update_flag, /* i : update flag*/ - Word16 music_backgound_f, /* i : background music flag*/ - Word32 snr ); + VAD_CLDFB_HANDLE hVAD_CLDFB, /* i/o: CLDFB VAD state */ + Word16 scale, /* i : the scaling of frame energy */ + Word32 frame_energy, /* i : current frame energy scale*/ + Word32 update_flag, /* i : update flag Q0*/ + Word16 music_backgound_f, /* i : background music flag Q0*/ + Word32 snr /* Q25 */ +); /* enc_gain.c */ -Word16 E_GAIN_closed_loop_search_fx( Word16 exc[], - Word16 xn[], - Word16 h[], +Word16 E_GAIN_closed_loop_search_fx( Word16 exc[], /*Q_new*/ + Word16 xn[], /*Q_xn*/ + Word16 h[], /* Q14+shift */ Word16 t0_min, Word16 t0_min_frac, Word16 t0_max, @@ -3230,26 +3349,26 @@ void amr_wb_enc_init_fx( ); void snr_calc( - VAD_CLDFB_HANDLE hVAD_CLDFB, /* i/o: CLDFB VAD state */ - const Word16 sacle_sbpower, /* i : the Scaling of sbpower*/ - Word32 *snr, /* o : frequency domain SNR */ - Word32 *tsnr, /* o : time domain SNR */ - const Word32 frame_energy, /* i : current frame energy */ - const Word32 bwidth /* i : audio band width*/ + VAD_CLDFB_HANDLE hVAD_CLDFB, /* i/o: CLDFB VAD state */ + const Word16 sacle_sbpower, /* i : the Scaling of sbpower */ + Word32 *snr, /* o : frequency domain SNR Q25*/ + Word32 *tsnr, /* o : time domain SNR Q25*/ + const Word32 frame_energy, /* i : current frame energy sacle_sbpower*/ + const Word32 bwidth /* i : audio band width Q0*/ ); void FEC_encode_fx( - BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ - const ACELP_config acelp_cfg, /* i/o: configuration of the ACELP */ - const Word16 *synth, /* i : pointer to synthesized speech for E computation */ - const Word16 coder_type, /* i : type of coder */ - Word16 clas, /* i : signal clas for current frame */ - const Word16 *fpit, /* i : close loop fractional pitch buffer */ - const Word16 *res, /* i : LP residual signal frame */ - Word16 *last_pulse_pos, /* i/o: Position of the last pulse */ - const Word16 L_frame, /* i : Frame length */ - const Word32 total_brate, /* i : total codec bitrate */ - const Word16 Q_new, /* i : i scaling */ - const Word16 shift /* i : scaling to get 12bits */ + BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ + const ACELP_config acelp_cfg, /* i/o: configuration of the ACELP */ + const Word16 *synth, /* i : pointer to synthesized speech for E computation Q_synth*/ + const Word16 coder_type, /* i : type of coder Q0*/ + Word16 clas, /* i : signal clas for current frame Q0*/ + const Word16 *fpit, /* i : close loop fractional pitch buffer Q6*/ + const Word16 *res, /* i : LP residual signal frame Qx*/ + Word16 *last_pulse_pos, /* i/o: Position of the last pulse Q0*/ + const Word16 L_frame, /* i : Frame length Q0*/ + const Word32 total_brate, /* i : total codec bitrate Q0*/ + const Word16 Q_new, /* i : i scaling */ + const Word16 shift /* i : scaling to get 12bits */ ); void updt_enc_fx( @@ -3294,26 +3413,27 @@ Word16 pit_encode_fx( /* o : Fractional pitc const Word16 tdm_Pri_pitch_buf[] /* i : primary channel pitch buffer */ ); -Word16 pit_encode_ivas_fx( /* o : Fractional pitch for each subframe */ - BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ - const Word16 pitch_bits[], /* i : pitch bits */ - const Word32 core_brate, /* i : core bitrate */ - const Word16 Opt_AMR_WB, /* i : flag indicating AMR-WB IO mode */ - const Word16 L_frame, /* i : length of the frame */ - const Word16 coder_type, /* i : coding type */ - Word16 *limit_flag, /* i/o: restrained(0) or extended(1) Q limits */ - const Word16 i_subfr, /* i : subframe index */ - Word16 *exc, /* i/o: pointer to excitation signal frame */ - const Word16 L_subfr, /* i : subframe length */ - const Word16 *pitch, /* i : open loop pitch estimates in current frame */ - Word16 *T0_min, /* i/o: lower limit for close-loop search */ - Word16 *T0_max, /* i/o: higher limit for close-loop search */ - Word16 *T0, /* i/o: close loop integer pitch */ - Word16 *T0_frac, /* i/o: close loop fractional part of the pitch */ - const Word16 *h1, /* i : weighted filter input response */ - const Word16 *xn, /* i : target vector */ - const Word16 tdm_Pitch_reuse_flag, /* i : primary channel pitch reuse flag */ - const Word16 tdm_Pri_pitch_buf[] /* i : primary channel pitch buffer */ +Word16 pit_encode_ivas_fx( /* o : Fractional pitch for each subframe */ + BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ + const Word16 pitch_bits[], /* i : pitch bits */ + const Word32 core_brate, /* i : core bitrate */ + const Word16 Opt_AMR_WB, /* i : flag indicating AMR-WB IO mode */ + const Word16 L_frame, /* i : length of the frame */ + const Word16 coder_type, /* i : coding type */ + Word16 *limit_flag, /* i/o: restrained(0) or extended(1) Q limits */ + const Word16 i_subfr, /* i : subframe index */ + Word16 *exc, /* i/o: pointer to excitation signal frame Q_new */ + const Word16 L_subfr, /* i : subframe length */ + const Word16 *pitch, /* i : open loop pitch estimates in current frame */ + Word16 *T0_min, /* i/o: lower limit for close-loop search */ + Word16 *T0_max, /* i/o: higher limit for close-loop search */ + Word16 *T0, /* i/o: close loop integer pitch */ + Word16 *T0_frac, /* i/o: close loop fractional part of the pitch */ + const Word16 *h1, /* i : weighted filter input response Q(14 - norm_s(h1[0]) */ + const Word16 *xn, /* i : target vector Q_new */ + const Word16 tdm_Pitch_reuse_flag, /* i : primary channel pitch reuse flag */ + const Word16 tdm_Pri_pitch_buf[], /* i : primary channel pitch buffer */ + Word16 Q_new /* i */ ); Word16 lp_filt_exc_enc_fx( @@ -3338,7 +3458,7 @@ Word16 lp_filt_exc_enc_ivas_fx( const Word16 coder_type, /* i : coding type Q0 */ const Word16 i_subfr, /* i : subframe index Q0 */ Word16 *exc, /* i/o: pointer to excitation signal frame Q_new */ - const Word16 *h1, /* i : weighted filter i response Q(14+shift) */ + const Word16 *h1, /* i : weighted filter i response Q(15) */ const Word16 *xn, /* i : target vector Q_new-1+shift */ Word16 *y1, /* o : zero-memory filtered adaptive excitation Q_new-1+shift */ Word16 *xn2, /* o : target vector for innovation search Q_new-1+shift */ @@ -3403,44 +3523,44 @@ Word16 inov_encode_ivas_fx( void gain_enc_mless_fx( BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ - const Word16 gains_mode[], /* i : gain bits */ - const Word16 element_mode, /* i : element mode */ - const Word16 L_frame, /* i : length of the frame */ - const Word16 i_subfr, /* i : subframe index */ - const Word16 tc_subfr, /* i : TC subframe index */ - const Word16 *xn, /* i : target vector */ - const Word16 *y1, /* i : zero-memory filtered adaptive excitation */ - const Word16 Q_xn, /* i : xn and y1 scaling */ - const Word16 *y2, /* i : zero-memory filtered algebraic codebook excitation */ - const Word16 *code, /* i : algebraic excitation */ - const Word16 Es_pred, /* i : predicted scaled innovation energy */ - Word16 *gain_pit, /* o : quantized pitch gain */ - Word32 *gain_code, /* o : quantized codebook gain */ - Word16 *gain_inov, /* o : gain of the innovation (used for normalization) */ - Word32 *norm_gain_code, /* o : norm. gain of the codebook excitation */ - Word16 *g_corr, /* i/o: correlations , -2,, -2 and 2 */ - const Word16 clip_gain /* i : gain pitch clipping flag (1 = clipping) */ + const Word16 gains_mode[], /* i : gain bits Q0*/ + const Word16 element_mode, /* i : element mode Q0*/ + const Word16 L_frame, /* i : length of the frame Q0*/ + const Word16 i_subfr, /* i : subframe index Q0*/ + const Word16 tc_subfr, /* i : TC subframe index Q0*/ + const Word16 *xn, /* i : target vector Q_xn*/ + const Word16 *y1, /* i : zero-memory filtered adaptive excitation Q_xn*/ + const Word16 Q_xn, /* i : xn and y1 scaling */ + const Word16 *y2, /* i : zero-memory filtered algebraic codebook excitation Q9*/ + const Word16 *code, /* i : algebraic excitation Q9*/ + const Word16 Es_pred, /* i : predicted scaled innovation energy Q8*/ + Word16 *gain_pit, /* o : quantized pitch gain Q14*/ + Word32 *gain_code, /* o : quantized codebook gain Q16*/ + Word16 *gain_inov, /* o : gain of the innovation (used for normalization) Q12*/ + Word32 *norm_gain_code, /* o : norm. gain of the codebook excitation Q16*/ + Word16 *g_corr, /* i/o: correlations , -2,, -2 and 2 Qx*/ + const Word16 clip_gain /* i : gain pitch clipping flag (1 = clipping) Q0*/ ); void gain_enc_mless_ivas_fx( BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ - const Word16 gains_mode[], /* i : gain bits */ - const Word16 element_mode, /* i : element mode */ - const Word16 L_frame, /* i : length of the frame */ - const Word16 i_subfr, /* i : subframe index */ - const Word16 tc_subfr, /* i : TC subframe index */ - const Word16 *xn, /* i : target vector */ - const Word16 *y1, /* i : zero-memory filtered adaptive excitation */ - const Word16 Q_xn, /* i : xn and y1 scaling */ - const Word16 *y2, /* i : zero-memory filtered algebraic codebook excitation */ - const Word16 *code, /* i : algebraic excitation */ - const Word16 Es_pred, /* i : predicted scaled innovation energy */ - Word16 *gain_pit, /* o : quantized pitch gain */ - Word32 *gain_code, /* o : quantized codebook gain */ - Word16 *gain_inov, /* o : gain of the innovation (used for normalization) */ - Word32 *norm_gain_code, /* o : norm. gain of the codebook excitation */ - Word16 *g_corr, /* i/o: correlations , -2,, -2 and 2 */ - const Word16 clip_gain /* i : gain pitch clipping flag (1 = clipping) */ + const Word16 gains_mode[], /* i : gain bits Q0*/ + const Word16 element_mode, /* i : element mode Q0*/ + const Word16 L_frame, /* i : length of the frame Q0*/ + const Word16 i_subfr, /* i : subframe index Q0*/ + const Word16 tc_subfr, /* i : TC subframe index Q0*/ + const Word16 *xn, /* i : target vector Q_xn*/ + const Word16 *y1, /* i : zero-memory filtered adaptive excitation Q_xn*/ + const Word16 Q_xn, /* i : xn and y1 scaling */ + const Word16 *y2, /* i : zero-memory filtered algebraic codebook excitation Q9*/ + const Word16 *code, /* i : algebraic excitation Q9*/ + const Word16 Es_pred, /* i : predicted scaled innovation energy Q8*/ + Word16 *gain_pit, /* o : quantized pitch gain Q14*/ + Word32 *gain_code, /* o : quantized codebook gain Q16*/ + Word16 *gain_inov, /* o : gain of the innovation (used for normalization) Q12*/ + Word32 *norm_gain_code, /* o : norm. gain of the codebook excitation Q16*/ + Word16 *g_corr, /* i/o: correlations , -2,, -2 and 2 Qx*/ + const Word16 clip_gain /* i : gain pitch clipping flag (1 = clipping) Q0*/ ); void updt_IO_switch_enc_fx( Encoder_State *st, /* i/o: state structure */ @@ -3456,39 +3576,39 @@ void hf_cod_init_fx( ); void analy_lp_AMR_WB_fx( - const Word16 speech[], /* i : pointer to the speech frame */ - Word32 *ener, /* o : residual energy from Levinson-Durbin */ - Word16 A[], /* o : A(z) filter coefficients */ - Word16 epsP_h[], /* o : LP analysis residual energies for each iteration */ - Word16 epsP_l[], /* o : LP analysis residual energies for each iteration */ - Word16 isp_new[], /* o : current frame ISPs */ - Word16 isp_old[], /* i/o: previous frame unquantized ISPs */ - Word16 isf_new[], /* o : current frame ISPs */ - Word16 Top, /* i : open loop pitch lag */ - Word16 Tnc, /* i : open loop pitch gain */ + const Word16 speech[], /* i : pointer to the speech frame Q_new*/ + Word32 *ener, /* o : residual energy from Levinson-Durbin Q_r*/ + Word16 A[], /* o : A(z) filter coefficients Q14*/ + Word16 epsP_h[], /* o : LP analysis residual energies for each iteration Q_r*/ + Word16 epsP_l[], /* o : LP analysis residual energies for each iteration Q_r*/ + Word16 isp_new[], /* o : current frame ISPs Q15*/ + Word16 isp_old[], /* i/o: previous frame unquantized ISPs Q15*/ + Word16 isf_new[], /* o : current frame ISPs Q15*/ + Word16 Top, /* i : open loop pitch lag Q0*/ + Word16 Tnc, /* i : open loop pitch gain Qx*/ Word16 Q_new, Word16 *Q_r ); void encod_amr_wb_fx( Encoder_State *st, /* i/o: state structure */ - const Word16 speech[], /* i : i speech */ - const Word16 Aw[], /* i : weighted A(z) unquantized for subframes */ - const Word16 Aq[], /* i : 12k8 Lp coefficient */ - const Word16 *res, /* i : residual signal */ - Word16 *syn, /* i/o: core synthesis */ - Word16 *exc, /* i/o: current non-enhanced excitation */ - Word16 *exc2, /* i/o: current enhanced excitation */ - Word16 *pitch_buf, /* i/o: floating pitch values for each subframe */ - Word16 hf_gain_fx[NB_SUBFR], /* o : decoded HF gain */ - const Word16 *speech16k_fx, /* i : i speech @16kHz */ + const Word16 speech[], /* i : i speech Q_new-1*/ + const Word16 Aw[], /* i : weighted A(z) unquantized for subframes Q12*/ + const Word16 Aq[], /* i : 12k8 Lp coefficient Q12*/ + const Word16 *res, /* i : residual signal Q_new*/ + Word16 *syn, /* i/o: core synthesis st->Q_syn*/ + Word16 *exc, /* i/o: current non-enhanced excitation Q_new*/ + Word16 *exc2, /* i/o: current enhanced excitation Q_new*/ + Word16 *pitch_buf, /* i/o: floating pitch values for each subframe Q6*/ + Word16 hf_gain_fx[NB_SUBFR], /* o : decoded HF gain Q0*/ + const Word16 *speech16k_fx, /* i : i speech @16kHz Qx*/ Word16 shift, Word16 Q_new ); void re8_cod_fx( - Word16 x[], /* i : point in RE8 (8-dimensional integer vector) */ - Word16 *n, /* i : codebook number (*n is an integer defined in {0,2,3,4,..,n_max}) */ - UWord16 *I, /* o : index of c (pointer to unsigned 16-bit word) */ - Word16 k[] /* o : index of v (8-dimensional vector of binary indices) = Voronoi index */ + Word16 x[], /* i : point in RE8 (8-dimensional integer vector) Q0*/ + Word16 *n, /* i : codebook number (*n is an integer defined in {0,2,3,4,..,n_max}) Q0*/ + UWord16 *I, /* o : index of c (pointer to unsigned 16-bit word) Q0*/ + Word16 k[] /* o : index of v (8-dimensional vector of binary indices) = Voronoi index Q0*/ ); void TBEreset_enc_fx( @@ -3513,20 +3633,20 @@ void acelp_core_switch_enc_ivas_fx( Word16 Q_new ); void gain_enc_amr_wb_fx( - BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ - const Word16 *xn, /* i : target vector */ - const Word16 Q_xn, /* i : xn and yy1 format Q0 */ - const Word16 *yy1, /* i : zero-memory filtered adaptive excitation */ - const Word16 *y2, /* i : zero-memory filtered algebraic codebook excitation */ - const Word16 *code, /* i : algebraic excitation */ - const Word32 core_brate, /* i : core bitrate */ - Word16 *gain_pit, /* i/o: pitch gain / Quantized pitch gain */ - Word32 *gain_code, /* o : quantized codebook gain */ - Word16 *gain_inov, /* o : gain of the innovation (used for normalization) */ - Word32 *norm_gain_code, /* o : norm. gain of the codebook excitation */ - Word16 *g_coeff, /* i/o: correlations , -2,, -2 and 2 */ - const Word16 clip_gain, /* i : gain pitch clipping flag (1 = clipping) */ - Word16 *past_qua_en /* i/o: gain quantization memory (4 words) */ + BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ + const Word16 *xn, /* i : target vector Q_xn*/ + const Word16 Q_xn, /* i : xn and yy1 format */ + const Word16 *yy1, /* i : zero-memory filtered adaptive excitation Q_xn*/ + const Word16 *y2, /* i : zero-memory filtered algebraic codebook excitation Q9*/ + const Word16 *code, /* i : algebraic excitation Q9*/ + const Word32 core_brate, /* i : core bitrate Q0*/ + Word16 *gain_pit, /* i/o: pitch gain / Quantized pitch gain Q14*/ + Word32 *gain_code, /* o : quantized codebook gain Q16*/ + Word16 *gain_inov, /* o : gain of the innovation (used for normalization) Q12*/ + Word32 *norm_gain_code, /* o : norm. gain of the codebook excitation Q16*/ + Word16 *g_coeff, /* i/o: correlations , -2,, -2 and 2 Qx*/ + const Word16 clip_gain, /* i : gain pitch clipping flag (1 = clipping) Q0*/ + Word16 *past_qua_en /* i/o: gain quantization memory (4 words) Q10*/ ); @@ -3549,59 +3669,59 @@ void hf_cod_fx( void transf_cdbk_enc_fx( Encoder_State *st_fx, /* i/o: encoder state structure */ - const Word16 harm_flag_acelp, /* i : harmonic flag for higher rates ACELP */ - const Word16 i_subfr, /* i : subframe index */ - Word16 cn[], /* i/o: target vector in residual domain */ - Word16 exc[], /* i/o: pointer to excitation signal frame */ - const Word16 *p_Aq, /* i : 12k8 Lp coefficient */ - const Word16 Ap[], /* i : weighted LP filter coefficients */ - const Word16 h1[], /* i : weighted filter i response */ - Word16 xn[], /* i/o: target vector */ - Word16 xn2[], /* i/o: target vector for innovation search */ - Word16 y1[], /* i/o: zero-memory filtered adaptive excitation */ - const Word16 y2[], /* i : zero-memory filtered innovative excitation */ - const Word16 Es_pred, /* i : predicited scaled innovation energy */ - Word16 *gain_pit, /* i/o: adaptive excitation gain */ - const Word32 gain_code, /* i : innovative excitation gain */ - Word16 g_corr[], /* o : ACELP correlation values */ - const Word16 clip_gain, /* i : adaptive gain clipping flag */ - Word16 *gain_preQ, /* o : prequantizer excitation gain */ - Word16 code_preQ[], /* o : prequantizer excitation */ - Word16 *unbits, /* o : number of AVQ unused bits */ + const Word16 harm_flag_acelp, /* i : harmonic flag for higher rates ACELP Q0*/ + const Word16 i_subfr, /* i : subframe index Q0*/ + Word16 cn[], /* i/o: target vector in residual domain Q_new*/ + Word16 exc[], /* i/o: pointer to excitation signal frame Q_new*/ + const Word16 *p_Aq, /* i : 12k8 Lp coefficient Q12*/ + const Word16 Ap[], /* i : weighted LP filter coefficients Q12*/ + const Word16 h1[], /* i : weighted filter input response Q15*/ + Word16 xn[], /* i/o: target vector Q_new + shift -1*/ + Word16 xn2[], /* i/o: target vector for innovation search Q_new + shift -1*/ + Word16 y1[], /* i/o: zero-memory filtered adaptive excitation Q_new + shift -1*/ + const Word16 y2[], /* i : zero-memory filtered innovative excitation Q9*/ + const Word16 Es_pred, /* i : predicited scaled innovation energy Q8*/ + Word16 *gain_pit, /* i/o: adaptive excitation gain Q14*/ + const Word32 gain_code, /* i : innovative excitation gain Q16*/ + Word16 g_corr[], /* o : ACELP correlation values Q15*/ + const Word16 clip_gain, /* i : adaptive gain clipping flag Q0*/ + Word16 *gain_preQ, /* o : prequantizer excitation gain Q2*/ + Word16 code_preQ[], /* o : prequantizer excitation Q_AVQ_OUT_DEC*/ + Word16 *unbits, /* o : number of AVQ unused bits Q0*/ const Word16 Q_new, /* i : Current frame scaling */ const Word16 shift /* i : shifting applied to y1, xn,... */ ); void transf_cdbk_enc_ivas_fx( Encoder_State *st_fx, /* i/o: encoder state structure */ - const Word16 harm_flag_acelp, /* i : harmonic flag for higher rates ACELP */ - const Word16 i_subfr, /* i : subframe index */ - Word16 cn[], /* i/o: target vector in residual domain */ - Word16 exc[], /* i/o: pointer to excitation signal frame */ - const Word16 *p_Aq, /* i : 12k8 Lp coefficient */ - const Word16 Ap[], /* i : weighted LP filter coefficients */ - const Word16 h1[], /* i : weighted filter input response */ - Word16 xn[], /* i/o: target vector */ - Word16 xn2[], /* i/o: target vector for innovation search */ - Word16 y1[], /* i/o: zero-memory filtered adaptive excitation */ - const Word16 y2[], /* i : zero-memory filtered innovative excitation */ - const Word16 Es_pred, /* i : predicited scaled innovation energy */ - Word16 *gain_pit, /* i/o: adaptive excitation gain */ - const Word32 gain_code, /* i : innovative excitation gain */ - Word16 g_corr[], /* o : ACELP correlation values */ - const Word16 clip_gain, /* i : adaptive gain clipping flag */ - Word16 *gain_preQ, /* o : prequantizer excitation gain */ - Word16 code_preQ[], /* o : prequantizer excitation */ - Word16 *unbits, /* o : number of AVQ unused bits */ + const Word16 harm_flag_acelp, /* i : harmonic flag for higher rates ACELP Q0*/ + const Word16 i_subfr, /* i : subframe index Q0*/ + Word16 cn[], /* i/o: target vector in residual domain Q_new*/ + Word16 exc[], /* i/o: pointer to excitation signal frame Q_new*/ + const Word16 *p_Aq, /* i : 12k8 Lp coefficient Q12*/ + const Word16 Ap[], /* i : weighted LP filter coefficients Q12*/ + const Word16 h1[], /* i : weighted filter input response Q15*/ + Word16 xn[], /* i/o: target vector Q_new + shift -1*/ + Word16 xn2[], /* i/o: target vector for innovation search Q_new + shift -1*/ + Word16 y1[], /* i/o: zero-memory filtered adaptive excitation Q_new + shift -1*/ + const Word16 y2[], /* i : zero-memory filtered innovative excitation Q9*/ + const Word16 Es_pred, /* i : predicited scaled innovation energy Q8*/ + Word16 *gain_pit, /* i/o: adaptive excitation gain Q14*/ + const Word32 gain_code, /* i : innovative excitation gain Q16*/ + Word16 g_corr[], /* o : ACELP correlation values Q15*/ + const Word16 clip_gain, /* i : adaptive gain clipping flag Q0*/ + Word16 *gain_preQ, /* o : prequantizer excitation gain Q2*/ + Word16 code_preQ[], /* o : prequantizer excitation Q_AVQ_OUT_DEC*/ + Word16 *unbits, /* o : number of AVQ unused bits Q0*/ const Word16 Q_new, /* i : Current frame scaling */ const Word16 shift /* i : shifting applied to y1, xn,... */ ); void gain_enc_lbr_fx( BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ - const Word16 gains_mode[], /* i : gain bits */ - const Word16 coder_type, /* i : coding type */ - const Word16 i_subfr, /* i : subframe index */ + const Word16 gains_mode[], /* i : gain bits Q0*/ + const Word16 coder_type, /* i : coding type Q0*/ + const Word16 i_subfr, /* i : subframe index Q0*/ const Word16 *xn, /* i : target vector Q_xn*/ const Word16 *y1, /* i : zero-memory filtered adaptive excitation Q_xn*/ const Word16 Q_xn, /* i : xn and y1 format */ @@ -3612,17 +3732,17 @@ void gain_enc_lbr_fx( Word16 *gain_inov, /* o : gain of the innovation (used for normalization) Q12*/ Word32 *norm_gain_code, /* o : norm. gain of the codebook excitation Q16*/ Word16 *g_corr, /* i/o: correlations , -2,, -2 and 2 mant/exp*/ - Word32 gc_mem[], /* i/o: gain_code from previous subframes */ - Word16 gp_mem[], /* i/o: gain_pitch from previous subframes */ - const Word16 clip_gain, /* i : gain pitch clipping flag (1 = clipping) */ - const Word16 L_subfr /* i : subframe length */ + Word32 gc_mem[], /* i/o: gain_code from previous subframes Q16*/ + Word16 gp_mem[], /* i/o: gain_pitch from previous subframes Q14*/ + const Word16 clip_gain, /* i : gain pitch clipping flag (1 = clipping) Q0*/ + const Word16 L_subfr /* i : subframe length Q0*/ ); void gain_enc_lbr_ivas_fx( BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ - const Word16 gains_mode[], /* i : gain bits */ - const Word16 coder_type, /* i : coding type */ - const Word16 i_subfr, /* i : subframe index */ + const Word16 gains_mode[], /* i : gain bits Q0*/ + const Word16 coder_type, /* i : coding type Q0*/ + const Word16 i_subfr, /* i : subframe index Q0*/ const Word16 *xn, /* i : target vector Q_xn*/ const Word16 *y1, /* i : zero-memory filtered adaptive excitation Q_xn*/ const Word16 Q_xn, /* i : xn and y1 format */ @@ -3633,46 +3753,46 @@ void gain_enc_lbr_ivas_fx( Word16 *gain_inov, /* o : gain of the innovation (used for normalization) Q12*/ Word32 *norm_gain_code, /* o : norm. gain of the codebook excitation Q16*/ Word16 *g_corr, /* i/o: correlations , -2,, -2 and 2 mant/exp*/ - Word32 gc_mem[], /* i/o: gain_code from previous subframes */ - Word16 gp_mem[], /* i/o: gain_pitch from previous subframes */ - const Word16 clip_gain, /* i : gain pitch clipping flag (1 = clipping) */ - const int16_t L_subfr /* i : subframe length */ + Word32 gc_mem[], /* i/o: gain_code from previous subframes Q16*/ + Word16 gp_mem[], /* i/o: gain_pitch from previous subframes Q14*/ + const Word16 clip_gain, /* i : gain pitch clipping flag (1 = clipping) Q0*/ + const Word16 L_subfr /* i : subframe length Q0*/ ); void gain_enc_SQ_fx( BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ - const Word16 gains_mode[], /* i : gain bits */ - const Word16 i_subfr, /* i : subframe index */ - const Word16 *xn, /* i : target vector Q_xn */ - const Word16 *yy1, /* i : zero-memory filtered adaptive excitation Q_xn */ - const Word16 *y2, /* i : zero-memory filtered algebraic codebook excitation Q9 */ - const Word16 *code, /* i : algebraic excitation Q9 */ - const Word16 Es_pred, /* i : predicted scaled innovation energy Q8 */ - Word16 *gain_pit, /* o : quantized pitch gain Q14 */ - Word32 *gain_code, /* o : quantized codebook gain Q16 */ - Word16 *gain_inov, /* o : gain of the innovation (used for normalization) Q12 */ - Word32 *norm_gain_code, /* o : norm. gain of the codebook excitation Q16 */ - Word16 *g_corr, /* i/o: correlations , ,, -2 and 2 */ - const Word16 clip_gain, /* i : gain pitch clipping flag (1 = clipping) */ - const Word16 Q_xn /* i : xn and y1 scaling */ + const Word16 gains_mode[], /* i : gain bits Q0*/ + const Word16 i_subfr, /* i : subframe index Q0*/ + const Word16 *xn, /* i : target vector Q_xn*/ + const Word16 *yy1, /* i : zero-memory filtered adaptive excitation Q_xn*/ + const Word16 *y2, /* i : zero-memory filtered algebraic codebook excitation Q9*/ + const Word16 *code, /* i : algebraic excitation Q9*/ + const Word16 Es_pred, /* i : predicted scaled innovation energy Q8*/ + Word16 *gain_pit, /* o : quantized pitch gain Q14*/ + Word32 *gain_code, /* o : quantized codebook gain Q16*/ + Word16 *gain_inov, /* o : gain of the innovation (used for normalization) Q12*/ + Word32 *norm_gain_code, /* o : norm. gain of the codebook excitation Q16*/ + Word16 *g_corr, /* i/o: correlations , ,, -2 and 2 Qx*/ + const Word16 clip_gain, /* i : gain pitch clipping flag (1 = clipping) Q0*/ + const Word16 Q_xn /* i : xn and y1 scaling */ ); void gain_enc_SQ_ivas_fx( - BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ - const Word16 gains_mode[], /* i : gain bits */ - const Word16 i_subfr, /* i : subframe index */ - const Word16 *xn, /* i : target vector Q_xn */ - const Word16 *yy1, /* i : zero-memory filtered adaptive excitation Q_xn */ - const Word16 *y2, /* i : zero-memory filtered algebraic codebook excitation Q9 */ - const Word16 *code, /* i : algebraic excitation Q9 */ - const Word16 Es_pred, /* i : predicted scaled innovation energy Q8 */ - Word16 *gain_pit, /* o : quantized pitch gain Q14 */ - Word32 *gain_code, /* o : quantized codebook gain Q16 */ - Word16 *gain_inov, /* o : gain of the innovation (used for normalization) Q12 */ - Word32 *norm_gain_code, /* o : norm. gain of the codebook excitation Q16 */ - Word16 *g_corr, /* i/o: correlations , ,, -2 and 2 */ - const Word16 clip_gain, /* i : gain pitch clipping flag (1 = clipping) */ - const Word16 Q_xn /* i : xn and y1 scaling */ + BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ + const Word16 gains_mode[], /* i : gain bits Q0*/ + const Word16 i_subfr, /* i : subframe index Q0*/ + const Word16 *xn, /* i : target vector Q_xn*/ + const Word16 *yy1, /* i : zero-memory filtered adaptive excitation Q_xn*/ + const Word16 *y2, /* i : zero-memory filtered algebraic codebook excitation Q9*/ + const Word16 *code, /* i : algebraic excitation Q9*/ + const Word16 Es_pred, /* i : predicted scaled innovation energy Q8*/ + Word16 *gain_pit, /* o : quantized pitch gain Q14*/ + Word32 *gain_code, /* o : quantized codebook gain Q16*/ + Word16 *gain_inov, /* o : gain of the innovation (used for normalization) Q12*/ + Word32 *norm_gain_code, /* o : norm. gain of the codebook excitation Q16*/ + Word16 *g_corr, /* i/o: correlations , ,, -2 and 2 Qx*/ + const Word16 clip_gain, /* i : gain pitch clipping flag (1 = clipping) Q0*/ + const Word16 Q_xn /* i : xn and y1 scaling */ ); void updt_tar_fx( @@ -3691,11 +3811,7 @@ void updt_tar_HR_fx( const Word16 L /* i : subframe size */ ); -#ifdef BASOP_NOGLOB Flag conv_fx( -#else -void conv_fx( -#endif const Word16 x[], /* i : i vector Q_new*/ const Word16 h[], /* i : impulse response (or second i vector) Q(15)*/ Word16 y[], /* o : output vetor (result of convolution) 12 bits*/ @@ -3775,98 +3891,74 @@ void transition_enc_ivas_fx( ); -void transf_cdbk_enc_fx( - Encoder_State *st_fx, /* i/o: encoder state structure */ - const Word16 harm_flag_acelp, /* i : harmonic flag for higher rates ACELP */ - const Word16 i_subfr, /* i : subframe index */ - Word16 cn[], /* i/o: target vector in residual domain */ - Word16 exc[], /* i/o: pointer to excitation signal frame */ - const Word16 *p_Aq, /* i : 12k8 Lp coefficient */ - const Word16 Ap[], /* i : weighted LP filter coefficients */ - const Word16 h1[], /* i : weighted filter i response */ - Word16 xn[], /* i/o: target vector */ - Word16 xn2[], /* i/o: target vector for innovation search */ - Word16 y1[], /* i/o: zero-memory filtered adaptive excitation */ - const Word16 y2[], /* i : zero-memory filtered innovative excitation */ - const Word16 Es_pred, /* i : predicited scaled innovation energy */ - Word16 *gain_pit, /* i/o: adaptive excitation gain */ - const Word32 gain_code, /* i : innovative excitation gain */ - Word16 g_corr[], /* o : ACELP correlation values */ - const Word16 clip_gain, /* i : adaptive gain clipping flag */ - Word16 *gain_preQ, /* o : prequantizer excitation gain */ - Word16 code_preQ[], /* o : prequantizer excitation */ - Word16 *unbits, /* o : number of AVQ unused bits */ - const Word16 Q_new, /* i : Current frame scaling */ - const Word16 shift /* i : shifting applied to y1, xn,... */ -); void gain_enc_tc_fx( - BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ - const Word16 gains_mode[], /* i : gain bits */ - const Word16 i_subfr, /* i : subframe index */ - const Word16 xn_fx[], /* i : target vector */ - const Word16 y2_fx[], /* i : zero-memory filtered algebraic codebook excitation */ - const Word16 code_fx[], /* i : algebraic excitation */ - const Word16 Es_pred_fx, /* i : predicted scaled innovation energy */ - Word16 *gain_pit_fx, /* o : Pitch gain / Quantized pitch gain */ - Word32 *gain_code_fx, /* o : quantized codebook gain */ - Word16 *gain_inov_fx, /* o : innovation gain */ - Word32 *norm_gain_code_fx, /* o : norm. gain of the codebook excitation */ - const Word16 Q_xn /* i : xn and y1 scaling Q0 */ + BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ + const Word16 gains_mode[], /* i : gain bits Q0*/ + const Word16 i_subfr, /* i : subframe index Q0*/ + const Word16 xn_fx[], /* i : target vector Q_xn*/ + const Word16 y2_fx[], /* i : zero-memory filtered algebraic codebook excitation Q_xn*/ + const Word16 code_fx[], /* i : algebraic excitation Q9*/ + const Word16 Es_pred_fx, /* i : predicted scaled innovation energy Q8*/ + Word16 *gain_pit_fx, /* o : Pitch gain / Quantized pitch gain Q14*/ + Word32 *gain_code_fx, /* o : quantized codebook gain Q16*/ + Word16 *gain_inov_fx, /* o : innovation gain Q12*/ + Word32 *norm_gain_code_fx, /* o : norm. gain of the codebook excitation Q16*/ + const Word16 Q_xn /* i : xn and y1 scaling */ ); void gain_enc_tc_ivas_fx( - BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ - const Word16 gains_mode[], /* i : gain bits */ - const Word16 i_subfr, /* i : subframe index */ - const Word16 xn_fx[], /* i : target vector */ - const Word16 y2_fx[], /* i : zero-memory filtered algebraic codebook excitation */ - const Word16 code_fx[], /* i : algebraic excitation */ - const Word16 Es_pred_fx, /* i : predicted scaled innovation energy */ - Word16 *gain_pit_fx, /* o : Pitch gain / Quantized pitch gain */ - Word32 *gain_code_fx, /* o : quantized codebook gain */ - Word16 *gain_inov_fx, /* o : innovation gain */ - Word32 *norm_gain_code_fx, /* o : norm. gain of the codebook excitation */ - const Word16 Q_xn /* i : xn and y1 scaling Q0 */ + BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ + const Word16 gains_mode[], /* i : gain bits Q0*/ + const Word16 i_subfr, /* i : subframe index Q0*/ + const Word16 xn_fx[], /* i : target vector Q_xn*/ + const Word16 y2_fx[], /* i : zero-memory filtered algebraic codebook excitation Q_xn*/ + const Word16 code_fx[], /* i : algebraic excitation Q9*/ + const Word16 Es_pred_fx, /* i : predicted scaled innovation energy Q8*/ + Word16 *gain_pit_fx, /* o : Pitch gain / Quantized pitch gain Q14*/ + Word32 *gain_code_fx, /* o : quantized codebook gain Q16*/ + Word16 *gain_inov_fx, /* o : innovation gain Q12*/ + Word32 *norm_gain_code_fx, /* o : norm. gain of the codebook excitation Q6*/ + const Word16 Q_xn /* i : xn and y1 scaling */ ); Word16 gaus_encode_fx( Encoder_State *st_fx, /* i/o: encoder state structure */ - const Word16 i_subfr, /* i : subframe index */ - const Word16 *h1, /* i : weighted filter i response */ - const Word16 *xn, /* i : target vector */ - Word16 *exc, /* o : pointer to excitation signal frame */ - Word16 *mem_w0, /* o : weighting filter denominator memory */ - Word16 *clip_gain, /* o : memory of gain of pitch clipping algorithm */ - Word16 *tilt_code, /* o : synthesis excitation spectrum tilt */ - Word16 *code, /* o : algebraic excitation Q9 */ - Word32 *gain_code, /* o : Code gain. Q16 */ - Word16 *y2, /* o : zero-memory filtered adaptive excitation Q9 */ - Word16 *gain_inov, /* o : innovation gain Q12 */ - Word16 *voice_fac, /* o : voicing factor Q15 */ - Word16 *gain_pit, /* o : adaptive excitation gain Q14 */ - const Word16 Q_new, /* i : scaling factor */ - const Word16 shift, /* i : scaling factor */ - Word32 *norm_gain_code /* o : normalized innovative cb. gain Q16 */ + const Word16 i_subfr, /* i : subframe index Q0*/ + const Word16 *h1, /* i : weighted filter input response Q14*/ + const Word16 *xn, /* i : target vector Q12*/ + Word16 *exc, /* o : pointer to excitation signal frame Q_new*/ + Word16 *mem_w0, /* o : weighting filter denominator memory Q_new*/ + Word16 *clip_gain, /* o : memory of gain of pitch clipping algorithm [2.56x,Q14,Q8,Q0,Q14,Q14]*/ + Word16 *tilt_code, /* o : synthesis excitation spectrum tilt Q15*/ + Word16 *code, /* o : algebraic excitation Q9*/ + Word32 *gain_code, /* o : Code gain. Q16*/ + Word16 *y2, /* o : zero-memory filtered adaptive excitation Q9*/ + Word16 *gain_inov, /* o : innovation gain Q12*/ + Word16 *voice_fac, /* o : voicing factor Q15*/ + Word16 *gain_pit, /* o : adaptive excitation gain Q14*/ + const Word16 Q_new, /* i : scaling factor */ + const Word16 shift, /* i : scaling factor */ + Word32 *norm_gain_code /* o : normalized innovative cb. gain Q16*/ ); Word16 gaus_encode_ivas_fx( Encoder_State *st_fx, /* i/o: encoder state structure */ - const Word16 i_subfr, /* i : subframe index */ - const Word16 *h1, /* i : weighted filter input response */ - const Word16 *xn, /* i : target vector */ - Word16 *exc, /* o : pointer to excitation signal frame */ - Word16 *mem_w0, /* o : weighting filter denominator memory */ - Word16 *clip_gain, /* o : memory of gain of pitch clipping algorithm */ - Word16 *tilt_code, /* o : synthesis excitation spectrum tilt */ - Word16 *code, /* o : algebraic excitation Q9 */ - Word32 *gain_code, /* o : Code gain. Q16 */ - Word16 *y2, /* o : zero-memory filtered adaptive excitation Q9 */ - Word16 *gain_inov, /* o : innovation gain Q12 */ - Word16 *voice_fac, /* o : voicing factor Q15 */ - Word16 *gain_pit, /* o : adaptive excitation gain Q14 */ - const Word16 Q_new, /* i : scaling factor */ - const Word16 shift, /* i : scaling factor */ - Word32 *norm_gain_code /* o : normalized innovative cb. gain Q16 */ + const Word16 i_subfr, /* i : subframe index Q0*/ + const Word16 *h1, /* i : weighted filter input response Q14*/ + const Word16 *xn, /* i : target vector Q12*/ + Word16 *exc, /* o : pointer to excitation signal frame Q_new*/ + Word16 *mem_w0, /* o : weighting filter denominator memory Q_new*/ + Word16 *clip_gain, /* o : memory of gain of pitch clipping algorithm [2.56x,Q14,Q8,Q0,Q14,Q14]*/ + Word16 *tilt_code, /* o : synthesis excitation spectrum tilt Q15*/ + Word16 *code, /* o : algebraic excitation Q9*/ + Word32 *gain_code, /* o : Code gain. Q16*/ + Word16 *y2, /* o : zero-memory filtered adaptive excitation Q9*/ + Word16 *gain_inov, /* o : innovation gain Q12*/ + Word16 *voice_fac, /* o : voicing factor Q15*/ + Word16 *gain_pit, /* o : adaptive excitation gain Q14*/ + const Word16 Q_new, /* i : scaling factor */ + const Word16 shift, /* i : scaling factor */ + Word32 *norm_gain_code /* o : normalized innovative cb. gain Q16*/ ); void pre_proc_fx( @@ -3910,68 +4002,68 @@ void swb_bwe_enc_hr_fx( ); Word16 gain_enc_gaus_fx( /* o : Return index of quantization */ - Word32 *gain, /* i/o: Code gain to quantize */ - const Word16 bits, /* i : number of bits to quantize */ - const Word16 lowBound, /* i : lower bound of quantizer (dB) Q8 */ - const Word16 stepSize, /* i : Step size choice Q14 */ - const Word16 inv_stepSize /* i : Step size choice Q15 */ + Word32 *gain, /* i/o: Code gain to quantize Q16*/ + const Word16 bits, /* i : number of bits to quantize Q0*/ + const Word16 lowBound, /* i : lower bound of quantizer (dB) Q8*/ + const Word16 stepSize, /* i : Step size choice Q14*/ + const Word16 inv_stepSize /* i : Step size choice Q15*/ ); void enc_pit_exc_fx( Encoder_State *st_fx, /* i/o: State structure */ - const Word16 *speech, /* i : Input speech */ - const Word16 Aw[], /* i : weighted A(z) unquantized for subframes */ - const Word16 Aq[], /* i : 12k8 Lp coefficient */ - const Word16 Es_pred, /* i : predicted scaled innov. energy */ - const Word16 *res, /* i : residual signal */ - Word16 *synth, /* i/o: core synthesis */ - Word16 *exc, /* i/o: current non-enhanced excitation */ - Word16 *T0, /* i/o: close loop integer pitch */ - Word16 *T0_frac, /* i/o: close-loop pitch period - fractional part */ - Word16 *pitch_buf, /* i/o: Fractionnal per subframe pitch */ - const Word16 nb_subfr, /* i : Number of subframe considered */ - Word16 *gpit, /* o : pitch mean gpit */ - Word16 *saved_bit_pos, /* o : saved position in the bitstream before pitch contribution */ - const Word16 tdm_Pitch_reuse_flag, /* i : primary channel pitch reuse flag */ - const Word16 tdm_Pri_pitch_buf[], /* i : primary channel pitch buffer */ + const Word16 *speech, /* i : Input speech Q_new-1*/ + const Word16 Aw[], /* i : weighted A(z) unquantized for subframes Q12*/ + const Word16 Aq[], /* i : 12k8 Lp coefficient Q12*/ + const Word16 Es_pred, /* i : predicted scaled innov. energy Q8*/ + const Word16 *res, /* i : residual signal Q_new*/ + Word16 *synth, /* i/o: core synthesis Q_new*/ + Word16 *exc, /* i/o: current non-enhanced excitation Q_new*/ + Word16 *T0, /* i/o: close loop integer pitch Q0*/ + Word16 *T0_frac, /* i/o: close-loop pitch period - fractional part Q0*/ + Word16 *pitch_buf, /* i/o: Fractionnal per subframe pitch Q6*/ + const Word16 nb_subfr, /* i : Number of subframe considered Q0*/ + Word16 *gpit, /* o : pitch mean gpit Q15*/ + Word16 *saved_bit_pos, /* o : saved position in the bitstream before pitch contribution Q0*/ + const Word16 tdm_Pitch_reuse_flag, /* i : primary channel pitch reuse flag Q0*/ + const Word16 tdm_Pri_pitch_buf[], /* i : primary channel pitch buffer Q6*/ Word16 Q_new, Word16 shift ); void enc_pit_exc_ivas_fx( Encoder_State *st_fx, /* i/o: State structure */ - const Word16 *speech, /* i : Input speech */ - const Word16 Aw[], /* i : weighted A(z) unquantized for subframes */ - const Word16 Aq[], /* i : 12k8 Lp coefficient */ - const Word16 Es_pred, /* i : predicted scaled innov. energy */ - const Word16 *res, /* i : residual signal */ - Word16 *synth, /* i/o: core synthesis */ - Word16 *exc, /* i/o: current non-enhanced excitation */ - Word16 *T0, /* i/o: close loop integer pitch */ - Word16 *T0_frac, /* i/o: close-loop pitch period - fractional part */ - Word16 *pitch_buf, /* i/o: Fractionnal per subframe pitch */ - const Word16 nb_subfr, /* i : Number of subframe considered */ - Word16 *gpit, /* o : pitch mean gpit */ - Word16 *saved_bit_pos, /* o : saved position in the bitstream before pitch contribution */ - const Word16 tdm_Pitch_reuse_flag, /* i : primary channel pitch reuse flag */ - const Word16 tdm_Pri_pitch_buf[], /* i : primary channel pitch buffer */ + const Word16 *speech, /* i : Input speech Q_new-1*/ + const Word16 Aw[], /* i : weighted A(z) unquantized for subframes Q12*/ + const Word16 Aq[], /* i : 12k8 Lp coefficient Q12*/ + const Word16 Es_pred, /* i : predicted scaled innov. energy Q8*/ + const Word16 *res, /* i : residual signal Q_new*/ + Word16 *synth, /* i/o: core synthesis Q_new*/ + Word16 *exc, /* i/o: current non-enhanced excitation Q_new*/ + Word16 *T0, /* i/o: close loop integer pitch Q0*/ + Word16 *T0_frac, /* i/o: close-loop pitch period - fractional part Q0*/ + Word16 *pitch_buf, /* i/o: Fractionnal per subframe pitch Q6*/ + const Word16 nb_subfr, /* i : Number of subframe considered Q0*/ + Word16 *gpit, /* o : pitch mean gpit Q15*/ + Word16 *saved_bit_pos, /* o : saved position in the bitstream before pitch contribution Q0*/ + const Word16 tdm_Pitch_reuse_flag, /* i : primary channel pitch reuse flag Q0*/ + const Word16 tdm_Pri_pitch_buf[], /* i : primary channel pitch buffer Q6*/ Word16 Q_new, Word16 shift ); Word16 Pit_exc_contribution_len_fx( /* o : bin where pitch contribution is significant */ Encoder_State *st_fx, /* i/o: state structure */ - const Word16 *dct_res, /* i : DCT of residual */ - Word16 *dct_pitex, /* i/o: DCT of pitch contribution */ - Word16 *pitch_buf, /* i/o: Pitch per subframe */ - const Word16 nb_subfr, /* i : Number of subframe considered */ - Word16 *hangover, /* i : hangover for the time contribution switching */ + const Word16 *dct_res, /* i : DCT of residual Qnew*/ + Word16 *dct_pitex, /* i/o: DCT of pitch contribution Qnew*/ + Word16 *pitch_buf, /* i/o: Pitch per subframe Q6*/ + const Word16 nb_subfr, /* i : Number of subframe considered Q0*/ + Word16 *hangover, /* i : hangover for the time contribution switching Q0*/ Word16 Qnew ); Word16 Pit_exc_contribution_len_ivas_fx( /* o : bin where pitch contribution is significant */ Encoder_State *st_fx, /* i/o: state structure */ - const Word16 *dct_res, /* i : DCT of residual */ - Word16 *dct_pitex, /* i/o: DCT of pitch contribution */ - Word16 *pitch_buf, /* i/o: Pitch per subframe */ - const Word16 nb_subfr, /* i : Number of subframe considered */ - Word16 *hangover, /* i : hangover for the time contribution switching */ + const Word16 *dct_res, /* i : DCT of residual Qnew*/ + Word16 *dct_pitex, /* i/o: DCT of pitch contribution Qnew*/ + Word16 *pitch_buf, /* i/o: Pitch per subframe Q6*/ + const Word16 nb_subfr, /* i : Number of subframe considered Q0*/ + Word16 *hangover, /* i : hangover for the time contribution switching Q0*/ Word16 Qnew ); Word16 pvq_core_enc_fx( @@ -4036,7 +4128,7 @@ void hq_hr_enc_fx( const Word16 length, /* i : length of spectrum Q0 */ Word16 *num_bits, /* i : number of available bits Q0 */ const Word16 is_transient, /* i : transient flag Q0 */ - const Word16 vad_hover_flag /* i : VAD hangover flag */ + const Word16 vad_hover_flag /* i : VAD hangover flag Q0 */ ); void hq_hr_enc_ivas_fx( @@ -4045,7 +4137,7 @@ void hq_hr_enc_ivas_fx( const Word16 length, /* i : length of spectrum Q0 */ Word16 *num_bits, /* i : number of available bits Q0 */ const Word16 is_transient, /* i : transient flag Q0 */ - const Word16 vad_hover_flag /* i : VAD hangover flag */ + const Word16 vad_hover_flag /* i : VAD hangover flag Q0 */ ); void reordernorm_fx( @@ -4094,7 +4186,7 @@ void diff_envelope_coding_fx( ); Word16 encode_envelope_indices_ivas_fx( /* o : Number of bits if flag_pack=0,0 if flag_pack=1 Q0 */ - BSTR_ENC_HANDLE hBstr, /* i : handle to the bitstream */ + BSTR_ENC_HANDLE hBstr, /* i : handle to the bitstream Q0 */ const Word16 num_sfm, /* i : Number of subbands Q0 */ const Word16 numnrmibits, /* i : Bitrate of fall-back coding mode Q0 */ Word16 *difidx, /* i/o: Diff indices/encoded diff indices Q0 */ @@ -4217,7 +4309,7 @@ ivas_error tcq_core_LR_enc_ivas_fx( const Word16 is_transient ); Word16 encode_envelope_indices_fx( /* o : Number of bits if flag_pack=0,0 if flag_pack=1 Q0 */ - BSTR_ENC_HANDLE hBstr, /* i : handle to the bitstream */ + BSTR_ENC_HANDLE hBstr, /* i : handle to the bitstream Q0 */ const Word16 num_sfm, /* i : Number of subbands Q0 */ const Word16 numnrmibits, /* i : Bitrate of fall-back coding mode Q0 */ Word16 *difidx, /* i/o: Diff indices/encoded diff indices Q0 */ @@ -4288,7 +4380,7 @@ void InitSWBencBuffer_ivas_fx( void ResetSHBbuffer_Enc_fx( Encoder_State *st_fx /* i/o: SHB encoder structure */ ); -Word16 E_ACELP_hh_corr( Word16 *x, Word16 *y, Word16 L_subfr, Word16 bits ); +Word16 E_ACELP_hh_corr( Word16 *x /*Q11*/, Word16 *y /*Qy*/, Word16 L_subfr /*Q0*/, Word16 bits /*Q0*/ ); void acelp_1t64_fx( BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ @@ -4353,10 +4445,10 @@ Word16 acelp_4t64_ivas_fx( Word16 element_mode ); ivas_error evs_enc_fx( - Encoder_State *st, /* i/o: encoder state structure */ - const Word16 *data, /* i : i signal */ - Word32 *mem_hp20_in_fx, /* i/o: hp20 filter memory */ - const Word16 n_samples /* i : number of i samples */ + Encoder_State *st, /* i/o: encoder state structure */ + const Word16 *data, /* i : input signal Q0*/ + Word32 *mem_hp20_in_fx, /* i/o: hp20 filter memory Qx*/ + const Word16 n_samples /* i : number of input samples Q0*/ ); /* y(n)(Qx) = alpha(Q15) * x(Qx) + (1.0f-alpha)* y(n-1) (Qx) */ @@ -4366,8 +4458,8 @@ Word16 noise_est_AR1_Qx( /* o: Qx y(n) */ Word16 alpha /*i : Q15 scaling of driving x(n) */ ); void FEC_lsf_estim_enc_fx( - Encoder_State *st_fx, /* i : Encoder static memory */ - Word16 *lsf /* o : estimated LSF vector */ + Encoder_State *st_fx, /* i : Encoder static memory */ + Word16 *lsf /* o : estimated LSF vector Qlog2(2.56)*/ ); Word32 mslvq_cng_fx( @@ -4391,14 +4483,14 @@ Word32 mslvq_cng_ivas_fx( ); void Unified_weighting_fx( - const Word32 Bin_Ener_128_fx[], /* i : FFT Bin energy 128 bins in two sets Q_ener */ + const Word32 Bin_Ener_128_fx[], /* i : FFT Bin energy 128 bins in two sets Q_ener */ Word16 Q_ener, - const Word16 lsf_fx[], /* i : LSF vector x2.56 */ - Word16 w_fx[], /* o : LP weighting filter (numerator) Q8 */ - const Word16 narrowBand, /* i : flag for Narrowband */ - const Word16 unvoiced, /* i : flag for Unvoiced frame */ - const Word32 sr_core, /* i : sampling rate of core-coder */ - const Word16 order /* i : LP order */ + const Word16 lsf_fx[], /* i : LSF vector x2.56 */ + Word16 w_fx[], /* o : LP weighting filter (numerator) Q8 */ + const Word16 narrowBand, /* i : flag for Narrowband Q0*/ + const Word16 unvoiced, /* i : flag for Unvoiced frame Q0*/ + const Word32 sr_core, /* i : sampling rate of core-coder Q0*/ + const Word16 order /* i : LP order Q0*/ ); Word32 qlsf_ARSN_tcvq_Enc_16k_fx( @@ -4527,7 +4619,7 @@ void pvq_encode_ivas_fx( ); void rc_enc_init_fx( PVQ_ENC_HANDLE hPVQ, /* i/o: PVQ encoder handle */ - Word16 tot_bits /* i : Total bit budget */ + Word16 tot_bits /* i : Total bit budget Q0*/ ); void rc_enc_finish_fx( @@ -4540,43 +4632,43 @@ void rc_enc_finish_ivas_fx( ); void rc_encode_fx( - BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ - PVQ_ENC_HANDLE hPVQ, /* i/o: PVQ encoder handle */ - UWord32 cum_freq, /* i : Cumulative frequency up to symbol */ - UWord32 sym_freq, /* i : Symbol probability */ - UWord32 tot /* i : Total cumulative frequency */ + BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ + PVQ_ENC_HANDLE hPVQ, /* i/o: PVQ encoder handle */ + UWord32 cum_freq, /* i : Cumulative frequency up to symbol Q0*/ + UWord32 sym_freq, /* i : Symbol probability Q0*/ + UWord32 tot /* i : Total cumulative frequency Q0*/ ); void rc_encode_ivas_fx( - BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ - PVQ_ENC_HANDLE hPVQ, /* i/o: PVQ encoder handle */ - UWord32 cum_freq, /* i : Cumulative frequency up to symbol */ - UWord32 sym_freq, /* i : Symbol probability */ - UWord32 tot /* i : Total cumulative frequency */ + BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ + PVQ_ENC_HANDLE hPVQ, /* i/o: PVQ encoder handle */ + UWord32 cum_freq, /* i : Cumulative frequency up to symbol Q0*/ + UWord32 sym_freq, /* i : Symbol probability Q0*/ + UWord32 tot /* i : Total cumulative frequency Q0*/ ); void rc_enc_uniform_ivas_fx( - BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ - PVQ_ENC_HANDLE hPVQ, /* i/o: PVQ encoder handle */ - UWord32 value, /* i : Value to encode */ - UWord32 tot /* i : Maximum value */ + BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ + PVQ_ENC_HANDLE hPVQ, /* i/o: PVQ encoder handle */ + UWord32 value, /* i : Value to encode Q0*/ + UWord32 tot /* i : Maximum value Q0*/ ); void rc_enc_uniform_fx( - BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ - PVQ_ENC_HANDLE hPVQ, /* i/o: PVQ encoder handle */ - UWord32 value, /* i : Value to encode */ - UWord32 tot /* i : Maximum value */ + BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ + PVQ_ENC_HANDLE hPVQ, /* i/o: PVQ encoder handle */ + UWord32 value, /* i : Value to encode Q0*/ + UWord32 tot /* i : Maximum value Q0*/ ); void rc_enc_bits_fx( - BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ - PVQ_ENC_HANDLE hPVQ, /* i/o: PVQ encoder handle */ - UWord32 value, /* i : Value to encode */ - Word16 bits /* i : Number of bits used */ + BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ + PVQ_ENC_HANDLE hPVQ, /* i/o: PVQ encoder handle */ + UWord32 value, /* i : Value to encode Q0*/ + Word16 bits /* i : Number of bits used Q0*/ ); void rc_enc_bits_ivas_fx( - BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ - PVQ_ENC_HANDLE hPVQ, /* i/o: PVQ encoder handle */ - UWord32 value, /* i : Value to encode */ - Word16 bits /* i : Number of bits used */ + BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ + PVQ_ENC_HANDLE hPVQ, /* i/o: PVQ encoder handle */ + UWord32 value, /* i : Value to encode Q0*/ + Word16 bits /* i : Number of bits used Q0*/ ); void re8_compute_base_index_fx( const Word16 *x, /* i : Elemen of Q2, Q3 or Q4 */ @@ -4596,14 +4688,14 @@ Word16 delta_pit_enc_fx( /* o : pitch index ); void set_impulse_fx( - const Word16 xn_fx[], /* i : target signal */ - const Word16 h_orig_fx[], /* i : impulse response of weighted synthesis filter */ - Word16 exc_fx[], /* o : adaptive codebook excitation */ - Word16 yy1_fx[], /* o : filtered adaptive codebook excitation */ - Word16 *imp_shape, /* o : adaptive codebook index */ - Word16 *imp_pos, /* o : position of the glotal impulse center index */ - Word32 *gain_trans_fx, /* o : transition gain Q7 */ - Word16 Q_new /* i : Current scaling */ + const Word16 xn_fx[], /* i : target signal Q_new-1+shift*/ + const Word16 h_orig_fx[], /* i : impulse response of weighted synthesis filter Q(14+shift)*/ + Word16 exc_fx[], /* o : adaptive codebook excitation Q_new*/ + Word16 yy1_fx[], /* o : filtered adaptive codebook excitation Q_new*/ + Word16 *imp_shape, /* o : adaptive codebook index Q0*/ + Word16 *imp_pos, /* o : position of the glottal impulse center index Q0*/ + Word32 *gain_trans_fx, /* o : transition gain Q7*/ + Word16 Q_new /* i : Current scaling */ ); Word16 abs_pit_enc_fx( /* o : pitch index */ @@ -4652,9 +4744,9 @@ ivas_error init_encoder_fx( ); void copy_encoder_config_fx( - Encoder_Struct *st_ivas, /* i : IVAS encoder structure */ - Encoder_State *st, /* o : encoder state structure */ - const Word16 flag_all /* i : flag 1==update all, 0=partial update*/ + Encoder_Struct *st_ivas, /* i : IVAS encoder structure */ + Encoder_State *st, /* o : encoder state structure */ + const Word16 flag_all /* i : flag 1==update all, 0=partial update Q0*/ ); void destroy_encoder_fx( @@ -4663,8 +4755,8 @@ void destroy_encoder_fx( void amr_wb_enc_fx( Encoder_State *st, /* i/o: encoder state structure */ - const Word16 input_sp[], /* i : i signal */ - const Word16 n_samples /* i : number of i samples */ + const Word16 input_sp[], /* i : i signal Q0*/ + const Word16 n_samples /* i : number of i samples Q0*/ ); void writeLPCparam_fx( diff --git a/lib_enc/pvq_core_enc.c b/lib_enc/pvq_core_enc.c deleted file mode 100644 index ce12347234733459bf08743ee7fa4381e3c076ce..0000000000000000000000000000000000000000 --- a/lib_enc/pvq_core_enc.c +++ /dev/null @@ -1,44 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include -#include "rom_com.h" -#include "prot.h" -#include "prot.h" -#include "stl.h" -#include "wmc_auto.h" diff --git a/lib_enc/pvq_core_enc_fx.c b/lib_enc/pvq_core_enc_fx.c index 3b20e82c3aad5b0c7abcdae17e93d3a7bc53cf73..214522126120348426c0f9a7d5bc2569f584a903 100644 --- a/lib_enc/pvq_core_enc_fx.c +++ b/lib_enc/pvq_core_enc_fx.c @@ -5,9 +5,8 @@ #include #include "options.h" /* Compilation switches */ #include "cnst.h" -#include "rom_com_fx.h" /* Static table prototypes */ -#include "rom_com.h" /* Static table prototypes */ -//#include "prot_fx.h" /* Function prototypes */ +#include "rom_com_fx.h" /* Static table prototypes */ +#include "rom_com.h" /* Static table prototypes */ #include "prot_fx.h" /* Function prototypes */ #include "prot_fx_enc.h" /* Function prototypes */ #include "ivas_prot_fx.h" @@ -202,12 +201,15 @@ static void pvq_encode_band_fx( move16(); } - pool_tot = 0; /* Word16 */ + pool_tot = 0; /* Word16 */ + move16(); pool_part = 0; /* Word16 */ + move16(); FOR( j = 0; j < Np; j++ ) { g_part[j] = negate( g_part_neg[j] ); + move16(); } srt_vec_ind16_fx( g_part, sg_part, idx_sort, Np ); FOR( j = 0; j < Np; j++ ) @@ -215,6 +217,7 @@ static void pvq_encode_band_fx( js = idx_sort[Np - 1 - j]; pool_part = shrtCDivSignedApprox( pool_tot, sub( Np, j ) ); bits_part[js] = s_max( 0, s_min( add( bits_part[js], pool_part ), 256 ) ); + move16(); conservativeL1Norm_fx( dim_part[js], bits_part[js], strict_bits, *bits_left, pool_tot, *npulses, /* inputs */ &K_val, bits_left, &pool_tot, npulses ); /* outputs */ @@ -266,7 +269,7 @@ void pvq_encode_frame_ivas_fx( PVQ_ENC_HANDLE hPVQ = &pvq_enc; #ifdef BASOP_NOGLOB_DECLARE_LOCAL Flag Overflow = 0; - move32(); + move16(); #endif rc_enc_init_fx( hPVQ, pvq_bits ); @@ -310,8 +313,8 @@ void pvq_encode_frame_ivas_fx( move16(); IF( R[is] > 0 ) { - bandBitsAdjustment_fx( hPVQ->rc_num_bits, hPVQ->rc_range, bits, bands_to_code, bands_to_code - coded_bands, sfmsize[is], R[is], bit_pool, /* inputs */ - &band_bits, &bits_left, &bit_pool ); /* outputs */ + bandBitsAdjustment_fx( hPVQ->rc_num_bits, hPVQ->rc_range, bits, bands_to_code, sub( bands_to_code, coded_bands ), sfmsize[is], R[is], bit_pool, /* inputs */ + &band_bits, &bits_left, &bit_pool ); /* outputs */ pvq_encode_band_ivas_fx( hBstr, hPVQ, &coefs_norm[sfm_start[is]], Q_coefs, &pulse_vector[sfm_start[is]], &npulses[is], &coefs_quant[sfm_start[is]], sfmsize[is], band_bits, &bits_left, strict_bits ); @@ -328,12 +331,8 @@ void pvq_encode_frame_ivas_fx( } tmp = ratio( xy_corr, yy_corr, &exp ); -#ifdef BASOP_NOGLOB gopt[is] = shl_o( tmp, sub( sub( sub( 14, Q_coefs ), shift ), exp ), &Overflow ); move16(); -#else /* BASOP_NOGLOB */ - gopt[is] = shl( tmp, sub( sub( sub( 14, Q_coefs ), shift ), exp ) ); -#endif if ( gopt[is] == 0 ) { @@ -382,6 +381,7 @@ void pvq_encode_frame_fx( Word16 band_bits, bits_left; Word16 bit_pool = 0; + move16(); Word16 coded_bands, bands_to_code; Word16 bits; Word16 R_sort[NB_SFM]; @@ -393,6 +393,7 @@ void pvq_encode_frame_fx( PVQ_ENC_HANDLE hPVQ = &pvq_enc; #ifdef BASOP_NOGLOB_DECLARE_LOCAL Flag Overflow = 0; + move16(); #endif rc_enc_init_fx( hPVQ, pvq_bits ); @@ -436,15 +437,15 @@ void pvq_encode_frame_fx( move16(); IF( R[is] > 0 ) { - bandBitsAdjustment_fx( hPVQ->rc_num_bits, hPVQ->rc_range, bits, bands_to_code, bands_to_code - coded_bands, sfmsize[is], R[is], bit_pool, /* inputs */ - &band_bits, &bits_left, &bit_pool ); /* outputs */ + bandBitsAdjustment_fx( hPVQ->rc_num_bits, hPVQ->rc_range, bits, bands_to_code, sub( bands_to_code, coded_bands ), sfmsize[is], R[is], bit_pool, /* inputs */ + &band_bits, &bits_left, &bit_pool ); /* outputs */ pvq_encode_band_fx( hBstr, hPVQ, &coefs_norm[sfm_start[is]], Q_coefs, &pulse_vector[sfm_start[is]], &npulses[is], &coefs_quant[sfm_start[is]], sfmsize[is], band_bits, &bits_left, strict_bits ); xy_corr = L_deposit_l( 0 ); yy_corr = L_deposit_l( 1 ); - shift = band_len_ener_shift[band_len_idx[shr( sfmsize[is], 3 )]]; + shift = band_len_ener_shift[band_len_idx[sfmsize[is] >> 3]]; move16(); FOR( j = 0; j < sfmsize[i]; j++ ) { @@ -454,12 +455,8 @@ void pvq_encode_frame_fx( } tmp = ratio( xy_corr, yy_corr, &exp ); -#ifdef BASOP_NOGLOB gopt[is] = shl_o( tmp, sub( sub( sub( 14, Q_coefs ), shift ), exp ), &Overflow ); -#else /* BASOP_NOGLOB */ - gopt[is] = shl( tmp, sub( sub( sub( 14, Q_coefs ), shift ), exp ) ); -#endif - + move16(); if ( gopt[is] == 0 ) { gopt[is] = 1; @@ -664,6 +661,7 @@ static void encode_energies_fx( Word16 density; Word16 phi; Word16 index_phi = -1; + move16(); Word16 oppRQ3, qzero; Word16 angle; Word32 sqrt_r_enr, sqrt_l_enr; @@ -739,11 +737,13 @@ static void encode_energies_fx( FOR( i = 0; i < l_Np; i++ ) { g_part[i] = mult_r( l_gain, g_part[i] ); + move16(); } FOR( i = l_Np; i < Np; i++ ) { g_part[i] = mult_r( r_gain, g_part[i] ); + move16(); } NearOppSplitAdjustment_fx( qband, qzero, hPVQ->rc_num_bits, hPVQ->rc_range, *bits_left, @@ -933,7 +933,7 @@ static void densityIndexSymbolEncode_ivas_fx( UWord16 lsb; #ifdef BASOP_NOGLOB_DECLARE_LOCAL Flag Overflow = 0; - move32(); + move16(); #endif sym_freq = L_deposit_l( 1 ); @@ -941,11 +941,7 @@ static void densityIndexSymbolEncode_ivas_fx( IF( s_and( (Word16) 0xFFFE, density ) != 0 ) /* even */ { angle = atan2_fx( SQRT_DIM_fx[r_dim], SQRT_DIM_fx[l_dim] ); -#ifdef BASOP_NOGLOB angle = shl_o( angle, 1, &Overflow ); -#else - angle = shl( angle, 1 ); -#endif angle = mult_r( angle, 20861 ); c = mult_r( density, angle ); @@ -1014,6 +1010,7 @@ static void densityIndexSymbolEncode_fx( UWord16 lsb; #ifdef BASOP_NOGLOB_DECLARE_LOCAL Flag Overflow = 0; + move16(); #endif sym_freq = L_deposit_l( 1 ); @@ -1021,11 +1018,7 @@ static void densityIndexSymbolEncode_fx( IF( s_and( (Word16) 0xFFFE, density ) != 0 ) /* even */ { angle = atan2_fx( SQRT_DIM_fx[r_dim], SQRT_DIM_fx[l_dim] ); -#ifdef BASOP_NOGLOB angle = shl_o( angle, 1, &Overflow ); -#else - angle = shl( angle, 1 ); -#endif angle = mult_r( angle, 20861 ); c = mult_r( density, angle ); @@ -1247,6 +1240,7 @@ static Word16 calc_pvq_splits_fx( /* o : Number of segm acc = L_shr( acc, qPoint ); E[i] = sub( 30, norm_l( L_max( 1L, acc ) ) ); /* L_max needed to handle low subvector levels */ + move16(); eTotal = add( eTotal, E[i] ); } diff --git a/lib_enc/pvq_encode.c b/lib_enc/pvq_encode.c deleted file mode 100644 index 23468cbe8bbfdcb2b56d900848a3cac1fc090edf..0000000000000000000000000000000000000000 --- a/lib_enc/pvq_encode.c +++ /dev/null @@ -1,43 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include -#include "prot.h" -#include "rom_com.h" -#include "prot.h" -#include "wmc_auto.h" diff --git a/lib_enc/pvq_encode_fx.c b/lib_enc/pvq_encode_fx.c index b09d77802a6d84480e095e00b09d156204420887..749a39ed91243268b64f71275ce5106e00cf9749 100644 --- a/lib_enc/pvq_encode_fx.c +++ b/lib_enc/pvq_encode_fx.c @@ -4,7 +4,6 @@ #include #include "options.h" /* Compilation switches */ #include "cnst.h" -//#include "prot_fx.h" #include "prot_fx.h" /* Function prototypes */ #include "prot_fx_enc.h" /* Function prototypes */ #include "rom_com_fx.h" @@ -63,6 +62,7 @@ static Word16 one_pulse_search( UWord16 u_sgn; #ifdef BASOP_NOGLOB_DECLARE_LOCAL Flag Overflow = 0; + move16(); #endif en_tmp = en_dn_shift; /* dummy assignment to avoid compiler warning for unused parameter */ @@ -77,21 +77,17 @@ static Word16 one_pulse_search( IF( high_prec_active == 0 ) { - en_max_den = 0; /*move16()*/ + en_max_den = 0; /*move16()*/ + move16(); ; /* OPT: move saved by using high_prec_active as en_max_den */ /* 1 op */ cmax_num = -1; move16(); /* req. to force a 1st update for n==0 */ /* 1 op */ FOR( i = 0; i < dim; i++ ) /* FOR 3 ops */ { -#ifdef BASOP_NOGLOB L_tmp_corr = L_shl_o( L_mac_o( *L_xy_ptr, 1, x_abs[i], &Overflow ), corr_up_shift, &Overflow ); /* actual in-loop target value, 2 ops */ corr_tmp = round_fx_o( L_tmp_corr, &Overflow ); /* 1 op */ -#else - L_tmp_corr = L_shl( L_mac( *L_xy_ptr, 1, x_abs[i] ), corr_up_shift ); /* actual in-loop target value, 2 ops */ - corr_tmp = round_fx( L_tmp_corr ); /* 1 op */ -#endif - corr_sq_tmp = mult( corr_tmp, corr_tmp ); /* CorrSq, is a 16bit for low compelxity cross multiplication 1 op */ + corr_sq_tmp = mult( corr_tmp, corr_tmp ); /* CorrSq, is a 16bit for low compelxity cross multiplication 1 op */ L_tmp_en_lc = L_mac( *L_yy_ptr, 1, y[i] ); /*Q1 result , energy may span up to ~14+1(Q1)+1(sign)=16 bits, 1 op */ /* extract_l without shift can always be used for this section as energy is guaranteed to stay in the lower word, 1 op */ @@ -167,6 +163,7 @@ static Word16 one_pulse_search( y[imax] = add( y[imax], 1 ); move16(); /* Q0 added pulse */ ( *pulse_tot_ptr ) = add( ( *pulse_tot_ptr ), 1 ); /* increment total pulse sum */ + move16(); return imax; } @@ -207,7 +204,7 @@ void pvq_encode_ivas_fx( PvqEntry entry; #ifdef BASOP_NOGLOB_DECLARE_LOCAL Flag Overflow = 0; - move32(); + move16(); #endif L_proj_fac = 4096; @@ -262,11 +259,7 @@ void pvq_encode_ivas_fx( proj_fac = div_l( L_num, den ); /* L_num always has to be less than den<<16 */ shift_delta = sub( shift_num, shift_den ); -#ifdef BASOP_NOGLOB L_proj_fac = L_shl_sat( L_deposit_l( proj_fac ), sub( 9, shift_delta ) ); /* bring to a fixed Q12 */ -#else - L_proj_fac = L_shl( L_deposit_l( proj_fac ), sub( 9, shift_delta ) ); /* bring to a fixed Q12 */ -#endif } pulse_tot = 0; @@ -366,14 +359,9 @@ void pvq_encode_ivas_fx( } Mpy_32_16_ss( L_isqrt, tmp, &L_tmp, &u16_tmp ); /* Q31*Q(0+x) +1 */ Mpy_32_16_ss( L_tmp, neg_gain_norm, &L_tmp, &u16_tmp ); /* Q31*Q(0+x) *Q15 +1 */ -#ifdef BASOP_NOGLOB - L_tmp = L_shr_o( L_tmp, shift_tot, &Overflow ); /* Q31+x */ - xq[i] = round_fx_o( L_tmp, &Overflow ); /* Q15, array move */ + L_tmp = L_shr_o( L_tmp, shift_tot, &Overflow ); /* Q31+x */ + xq[i] = round_fx_o( L_tmp, &Overflow ); /* Q15, array move */ move16(); -#else - L_tmp = L_shr( L_tmp, shift_tot ); /* Q31+x */ - xq[i] = round_fx( L_tmp ); /* Q15, array move */ -#endif L_xq[i] = L_tmp; /* Q31 currently unused */ move32(); } @@ -424,9 +412,11 @@ void pvq_encode_fx( PvqEntry entry; #ifdef BASOP_NOGLOB_DECLARE_LOCAL Flag Overflow = 0; + move16(); #endif L_proj_fac = 4096; + move32(); L_xsum = L_deposit_h( 0 ); max_xabs = -1; move16(); @@ -477,11 +467,7 @@ void pvq_encode_fx( proj_fac = div_l( L_num, den ); /* L_num always has to be less than den<<16 */ shift_delta = sub( shift_num, shift_den ); -#ifdef BASOP_NOGLOB L_proj_fac = L_shl_sat( L_deposit_l( proj_fac ), sub( 9, shift_delta ) ); /* bring to a fixed Q12 */ -#else - L_proj_fac = L_shl( L_deposit_l( proj_fac ), sub( 9, shift_delta ) ); /* bring to a fixed Q12 */ -#endif } pulse_tot = 0; @@ -581,14 +567,11 @@ void pvq_encode_fx( } Mpy_32_16_ss( L_isqrt, tmp, &L_tmp, &u16_tmp ); /* Q31*Q(0+x) +1 */ Mpy_32_16_ss( L_tmp, neg_gain_norm, &L_tmp, &u16_tmp ); /* Q31*Q(0+x) *Q15 +1 */ -#ifdef BASOP_NOGLOB - L_tmp = L_shr_o( L_tmp, shift_tot, &Overflow ); /* Q31+x */ - xq[i] = round_fx_o( L_tmp, &Overflow ); /* Q15, array move */ -#else - L_tmp = L_shr( L_tmp, shift_tot ); /* Q31+x */ - xq[i] = round_fx( L_tmp ); /* Q15, array move */ -#endif + L_tmp = L_shr_o( L_tmp, shift_tot, &Overflow ); /* Q31+x */ + xq[i] = round_fx_o( L_tmp, &Overflow ); /* Q15, array move */ + move16(); L_xq[i] = L_tmp; /* Q31 currently unused */ + move32(); } /* index the found PVQ vector into short codewords */ diff --git a/lib_enc/q_gain2p.c b/lib_enc/q_gain2p.c deleted file mode 100644 index bcdeaa0415b3291cebf3e4463a6e123980ab180f..0000000000000000000000000000000000000000 --- a/lib_enc/q_gain2p.c +++ /dev/null @@ -1,43 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include -#include "prot.h" -#include "cnst.h" -#include "rom_com.h" -#include "wmc_auto.h" diff --git a/lib_enc/q_gain2p_fx.c b/lib_enc/q_gain2p_fx.c index 14d6d59073c50a91706cdc99b96a4763f66ba5ff..4618483d26b649a5e066f1dc307655f4bec5c505 100644 --- a/lib_enc/q_gain2p_fx.c +++ b/lib_enc/q_gain2p_fx.c @@ -6,7 +6,6 @@ #include #include "options.h" #include "cnst.h" /* Common constants */ -//#include "prot_fx.h" #include "basop_util.h" #include "rom_com_fx.h" #include "rom_com.h" /* Common constants */ @@ -57,6 +56,8 @@ void encode_acelp_gains_fx( ) { Word16 index = 0, func_type = 0; + move16(); + move16(); BASOP_SATURATE_ERROR_ON_EVS; @@ -146,6 +147,7 @@ static Word16 gain_enc( /* o : quantization pitch index Word32 L_tmp, dist_min, L_tmp1; #ifdef BASOP_NOGLOB_DECLARE_LOCAL Flag Overflow = 0; + move16(); #endif @@ -163,11 +165,8 @@ static Word16 gain_enc( /* o : quantization pitch index /* gain_inov = 1.0f / sqrt((dot_product(code, code, L_SUBFR) + 0.01) / L_SUBFR) */ L_tmp = calc_gain_inov( code, lcode, &L_tmp1, &exp_L_tmp1 ); move16(); -#ifdef BASOP_NOGLOB *gain_inov = round_fx_o( L_shl_o( L_tmp, 15 - 3, &Overflow ), &Overflow ); /* gain_inov in Q12 */ -#else - *gain_inov = round_fx( L_shl( L_tmp, 15 - 3 ) ); /* gain_inov in Q12 */ -#endif + move16(); /*----------------------------------------------------------------* * calculate the predicted gain code *----------------------------------------------------------------*/ @@ -325,6 +324,8 @@ static Word16 gain_enc( /* o : quantization pitch index size_clip = 21; size = NB_QUA_GAIN7B; } + move16(); + move16(); if ( EQ_16( clip_gain, 1 ) ) { @@ -333,7 +334,6 @@ static Word16 gain_enc( /* o : quantization pitch index gcode0_gi = gcode0; move16(); } - move16(); p = t_qua_gain; index = 0; @@ -377,11 +377,7 @@ static Word16 gain_enc( /* o : quantization pitch index /* Here, we use L_mult0 to compensate the factor 0.5 applied to coeff[1..4] before */ L_tmp = L_add( L_tmp, L_shr( L_mult0( p[2 * i + 0], p[2 * i + 0] ), shr_coeff0 ) ); L_tmp = L_sub( L_tmp, L_shr( L_mult( p[2 * i + 0], coeff1 ), shr_coeff1 ) ); -#ifdef BASOP_NOGLOB L_tmp1 = L_sub_o( L_tmp, dist_min, &Overflow ); -#else /* BASOP_NOGLOB */ - L_tmp1 = L_sub( L_tmp, dist_min ); -#endif BASOP_SATURATE_WARNING_ON_EVS if ( L_tmp1 < 0 ) { @@ -401,21 +397,14 @@ static Word16 gain_enc( /* o : quantization pitch index L_tmp = L_mult( g_code, gcode0 ); /* Q11*Q15 -> Q27 */ exp_gcode0 = add( exp_gcode0, -11 ); -#ifdef BASOP_NOGLOB L_tmp = L_shl_o( L_tmp, exp_gcode0, &Overflow ); /* Q27 -> Q16 */ -#else - L_tmp = L_shl( L_tmp, exp_gcode0 ); /* Q27 -> Q16 */ -#endif *gain_code = L_tmp; move32(); /* Q16/Q12 => Q5 */ L_tmp = L_deposit_h( BASOP_Util_Divide3216_Scale( L_tmp, *gain_inov, &i ) ); -#ifdef BASOP_NOGLOB *past_gcode = L_shl_o( L_tmp, sub( i, 15 - 12 ), &Overflow ); -#else - *past_gcode = L_shl( L_tmp, sub( i, 15 - 12 ) ); -#endif + move16(); return index; } @@ -446,12 +435,17 @@ Word16 gain_enc_uv_fx( /* o : quantization pitch ind Word16 s, tmp1, s1; Word16 index2; const Word16 log2_scale = 16; + move16(); #ifdef BASOP_NOGLOB_DECLARE_LOCAL Flag Overflow = 0; + move16(); #endif pred_nrg_frame = 0; /* to suppress compilation warnings */ g_code2 = 0; /* to suppress compilation warnings */ exp_gcode2 = 0; /* to suppress compilation warnings */ + move32(); + move16(); + move16(); assert( ( func_type != FUNC_GAIN_ENC_MLESS ) ); @@ -476,6 +470,7 @@ Word16 gain_enc_uv_fx( /* o : quantization pitch ind /* gain_inov = 1.0f / sqrt((dot_product(code, code, L_SUBFR) + 0.01) / L_SUBFR) */ L_tmp = calc_gain_inov( code, lcode, NULL, NULL ); *gain_inov = round_fx( L_shl( L_tmp, 15 - 3 ) ); /* gain_inov in Q12 */ + move16(); /*----------------------------------------------------------------* * calculate the predicted gain code @@ -489,7 +484,7 @@ Word16 gain_enc_uv_fx( /* o : quantization pitch ind /* gcode = pred_nrg_frame * (*gain_inov); */ L_tmp = Mpy_32_16_1( pred_nrg_frame, *gain_inov ); /* 18Q13 */ i = norm_l( L_tmp ); - g_code = round_fx( L_shl( L_tmp, i ) ); + g_code = round_fx_sat( L_shl( L_tmp, i ) ); exp_gcode = sub( 18, i ); /* norm_code2 = 1.0f / sqrt((dot_product(code2, code2, lcode) + 0.01f) / lcode); */ @@ -499,11 +494,7 @@ Word16 gain_enc_uv_fx( /* o : quantization pitch ind /* g_code2 = pred_nrg_frame * norm_code2; */ L_tmp = Mpy_32_16_1( pred_nrg_frame, norm_code2 ); /* 18Q13 */ i = norm_l( L_tmp ); -#ifdef BASOP_NOGLOB g_code2 = round_fx_sat( L_shl_sat( L_tmp, i ) ); -#else - g_code2 = round_fx( L_shl( L_tmp, i ) ); -#endif exp_gcode2 = sub( 18, i ); } ELSE @@ -563,7 +554,7 @@ Word16 gain_enc_uv_fx( /* o : quantization pitch ind L_tmp = L_and( 0x7FFFFFFF, L_tmp ); L_tmp = Pow2( 30, round_fx( L_tmp ) ); - L_tmp = L_shl( L_tmp, i - ( 31 - 16 ) ); /* Q16 */ + L_tmp = L_shl( L_tmp, sub( i, ( 31 - 16 ) ) ); /* Q16 */ IF( gacelp_uv != 0 ) { @@ -586,11 +577,7 @@ Word16 gain_enc_uv_fx( /* o : quantization pitch ind } -#ifdef BASOP_NOGLOB *gain_code = L_shl_sat( Mpy_32_16_1( *past_gcode, *gain_inov ), 3 ); -#else - *gain_code = L_shl( Mpy_32_16_1( *past_gcode, *gain_inov ), 3 ); -#endif move32(); *gain_pit = 0; @@ -608,11 +595,7 @@ Word16 gain_enc_uv_fx( /* o : quantization pitch ind } s1 = norm_l( *gain_code ); -#ifdef BASOP_NOGLOB tmp1 = round_fx_o( L_shl_o( *gain_code, s1, &Overflow ), &Overflow ); -#else - tmp1 = round_fx( L_shl( *gain_code, s1 ) ); -#endif s1 = sub( 15, s1 ); tmp1 = mult_r( mult_r( tmp1, tmp1 ), g_coeff->y2y2 ); @@ -625,11 +608,7 @@ Word16 gain_enc_uv_fx( /* o : quantization pitch ind L_tmp1 = L_add( L_tmp, 0 ); s1 = norm_l( *gain_code ); -#ifdef BASOP_NOGLOB tmp1 = round_fx_o( L_shl_o( *gain_code, s1, &Overflow ), &Overflow ); -#else - tmp1 = round_fx( L_shl( *gain_code, s1 ) ); -#endif s1 = sub( 15, s1 ); c_index2 = 0x7FFF; @@ -640,11 +619,7 @@ Word16 gain_enc_uv_fx( /* o : quantization pitch ind { /* c = c_first - L_tmp1 * (L_tmp1 * g_coeff->y1y1 + 2 * (*gain_code) * g_coeff->y1y2); */ s = norm_l( L_tmp1 ); -#ifdef BASOP_NOGLOB tmp = round_fx_sat( L_shl_sat( L_tmp1, s ) ); -#else - tmp = round_fx( L_shl( L_tmp1, s ) ); -#endif s = sub( 15, s ); c_e = BASOP_Util_Add_MantExp( mult_r( tmp, g_coeff->y1y1 ), add( s, g_coeff->y1y1_e ), diff --git a/lib_enc/qlpc_avq.c b/lib_enc/qlpc_avq.c deleted file mode 100644 index 24f06eafe31fb859892ef40e5947576a60ab5108..0000000000000000000000000000000000000000 --- a/lib_enc/qlpc_avq.c +++ /dev/null @@ -1,41 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include "prot.h" -#include "ivas_prot.h" -#include "wmc_auto.h" diff --git a/lib_enc/qlpc_avq_fx.c b/lib_enc/qlpc_avq_fx.c index b3b126876ce5b858466290261984f152bbd4325e..13e0a3cf7e196cb86b31882c04a719a52bd8d1f0 100644 --- a/lib_enc/qlpc_avq_fx.c +++ b/lib_enc/qlpc_avq_fx.c @@ -23,11 +23,11 @@ void qlpc_avq_fx( const Word16 *lsfmid, /* i : Input LSF vectors (14Q1*1.28) */ Word16 *lsf_q, /* o : Quantized LFS vectors (14Q1*1.28) */ Word16 *lsfmid_q, /* o : Quantized LFS vectors (14Q1*1.28) */ - Word16 *index, /* o : Quantization indices */ - Word16 *nb_indices, /* o : Number of quantization indices */ - Word16 *nbbits, /* o : Number of quantization bits */ - const Word16 core, /* i : TCX10 or TCX20 */ - const Word32 sr_core /* i : internal sampling rate */ + Word16 *index, /* o : Quantization indices Q0 */ + Word16 *nb_indices, /* o : Number of quantization indices Q0 */ + Word16 *nbbits, /* o : Number of quantization bits Q0 */ + const Word16 core, /* i : TCX10 or TCX20 Q0 */ + const Word32 sr_core /* i : internal sampling rate Q0 */ ) { Word16 i; @@ -37,25 +37,25 @@ void qlpc_avq_fx( /* Init */ - tmp_index = &index[0]; + tmp_index = &index[0]; // Q0 *nb_indices = 0; move16(); - tmp_index[0] = vlpc_1st_cod_fx( lsf, lsf_q, dummy, 0 ); + tmp_index[0] = vlpc_1st_cod_fx( lsf, lsf_q, dummy, 0 ); // Q0 - nbt = vlpc_2st_cod_fx( lsf, lsf_q, &tmp_index[1], 0, sr_core ); + nbt = vlpc_2st_cod_fx( lsf, lsf_q, &tmp_index[1], 0, sr_core ); // Q0 /*nit = 1 + 2 + index[1] + index[2]; nit < NPRM_LPC_NEW(=50) */ - nit = add( add( 3, index[1] ), index[2] ); + nit = add( add( 3, index[1] ), index[2] ); // Q0 assert( nit < NPRM_LPC_NEW ); /*tmp_index += nit;*/ tmp_index = tmp_index + nit; /**nb_indices += nit;*/ - *nb_indices = add( *nb_indices, nit ); + *nb_indices = add( *nb_indices, nit ); // Q0 move16(); /*nbbits[0] = 8 + nbt;*/ - nbbits[0] = add( 8, nbt ); + nbbits[0] = add( 8, nbt ); // Q0 move16(); *tmp_index = 0; @@ -70,51 +70,51 @@ void qlpc_avq_fx( /* Quantize intermediate LPC (512 framing) */ tmp_index++; /**nb_indices +=1;*/ - *nb_indices = add( *nb_indices, 1 ); + *nb_indices = add( *nb_indices, 1 ); // Q0 move16(); /* LPC2: Abs? */ - tmp_index[0] = vlpc_1st_cod_fx( lsfmid, lsfmid_q, dummy, 0 ); + tmp_index[0] = vlpc_1st_cod_fx( lsfmid, lsfmid_q, dummy, 0 ); // Q0 - nbits = vlpc_2st_cod_fx( lsfmid, lsfmid_q, &tmp_index[1], 0, sr_core ); + nbits = vlpc_2st_cod_fx( lsfmid, lsfmid_q, &tmp_index[1], 0, sr_core ); // Q0 /*nbt = 8 + nbits;*/ nbt = add( 8, nbits ); /*nit = 1 + 2 + tmp_index[1] + tmp_index[2];*/ - nit = add( add( 3, tmp_index[1] ), tmp_index[2] ); + nit = add( add( 3, tmp_index[1] ), tmp_index[2] ); // Q0 /* LPC2: RelR? */ FOR( i = 0; i < M; i++ ) { - lsfmid_q0[i] = lsf_q[i]; + lsfmid_q0[i] = lsf_q[i]; /* 14Q1*1.28 */ move16(); } - nbits = vlpc_2st_cod_fx( lsfmid, lsfmid_q0, indxt, 3, sr_core ); + nbits = vlpc_2st_cod_fx( lsfmid, lsfmid_q0, indxt, 3, sr_core ); // Q0 IF( LT_16( nbits, nbt ) ) { - nbt = nbits; + nbt = nbits; // Q0 move16(); /*nit = 2 + indxt[0] + indxt[1];*/ - nit = add( add( 2, indxt[0] ), indxt[1] ); + nit = add( add( 2, indxt[0] ), indxt[1] ); // Q0 tmp_index[-1] = 1; move16(); FOR( i = 0; i < M; i++ ) { - lsfmid_q[i] = lsfmid_q0[i]; + lsfmid_q[i] = lsfmid_q0[i]; /* 14Q1*1.28 */ move16(); } FOR( i = 0; i < nit; i++ ) { - tmp_index[i] = indxt[i]; + tmp_index[i] = indxt[i]; // Q0 move16(); } } tmp_index += nit; /**nb_indices += nit;*/ - *nb_indices = add( *nb_indices, nit ); + *nb_indices = add( *nb_indices, nit ); // Q0 move16(); /*nbbits[1] = 1 + nbt;*/ nbbits[1] = add( 1, nbt ); @@ -129,7 +129,9 @@ void qlpc_avq_fx( * *--------------------------------------------------------------------*/ -static Word16 unary_code( Word16 ind, BSTR_ENC_HANDLE hBstr ) +static Word16 unary_code( + Word16 ind, /* Q0 */ + BSTR_ENC_HANDLE hBstr ) { Word16 nb_bits; @@ -142,7 +144,7 @@ static Word16 unary_code( Word16 ind, BSTR_ENC_HANDLE hBstr ) FOR( ; ind > 0; ind-- ) { push_next_indice_fx( hBstr, 1, 1 ); - nb_bits = add( nb_bits, 1 ); + nb_bits = add( nb_bits, 1 ); // Q0 } /* Stop bit */ @@ -150,7 +152,9 @@ static Word16 unary_code( Word16 ind, BSTR_ENC_HANDLE hBstr ) return ( nb_bits ); } -static Word16 unary_code_ivas_fx( Word16 ind, BSTR_ENC_HANDLE hBstr ) +static Word16 unary_code_ivas_fx( + Word16 ind, /* Q0 */ + BSTR_ENC_HANDLE hBstr ) { Word16 nb_bits; @@ -158,18 +162,18 @@ static Word16 unary_code_ivas_fx( Word16 ind, BSTR_ENC_HANDLE hBstr ) nb_bits = 1; /* Index bits */ - ind = sub( ind, 1 ); + ind = sub( ind, 1 ); // Q0 WHILE( ind >= 16 ) { push_next_indice( hBstr, 0xffffU, 16 ); - nb_bits = add( nb_bits, 16 ); + nb_bits = add( nb_bits, 16 ); // Q0 ind = sub( ind, 16 ); } IF( ind > 0 ) { push_next_indice( hBstr, ( 1U << ind ) - 1, ind ); - nb_bits = add( nb_bits, ind ); + nb_bits = add( nb_bits, ind ); // Q0 } /* Stop bit */ @@ -182,7 +186,10 @@ static Word16 unary_code_ivas_fx( Word16 ind, BSTR_ENC_HANDLE hBstr ) * * *--------------------------------------------------------------------*/ -static Word16 unpack4bits( Word16 nbits, const Word16 *prm, BSTR_ENC_HANDLE hBstr ) +static Word16 unpack4bits( + Word16 nbits, /* Q0 */ + const Word16 *prm, /* Q0 */ + BSTR_ENC_HANDLE hBstr ) { Word16 i; @@ -208,7 +215,10 @@ static Word16 unpack4bits( Word16 nbits, const Word16 *prm, BSTR_ENC_HANDLE hBst return ( i ); } -static Word16 unpack4bits_ivas_fx( Word16 nbits, const Word16 *prm, BSTR_ENC_HANDLE hBstr ) +static Word16 unpack4bits_ivas_fx( + Word16 nbits, /* Q0 */ + const Word16 *prm, /* Q0 */ + BSTR_ENC_HANDLE hBstr ) { Word16 i; @@ -242,10 +252,10 @@ static Word16 unpack4bits_ivas_fx( Word16 nbits, const Word16 *prm, BSTR_ENC_HAN Word16 encode_lpc_avq_fx( BSTR_ENC_HANDLE hBstr, /* i/o: bitstream handle */ - const Word16 numlpc, /* i : Number of sets of lpc */ - const Word16 *param_lpc, /* i : lpc parameters */ - const Word16 core, /* i : core */ - const Word16 element_mode /* i : element mode - decides between SNS and LPC coding */ + const Word16 numlpc, /* i : Number of sets of lpc Q0*/ + const Word16 *param_lpc, /* i : lpc parameters Q0*/ + const Word16 core, /* i : core Q0*/ + const Word16 element_mode /* i : element mode - decides between SNS and LPC coding Q0*/ ) { Word16 k, j; @@ -281,13 +291,13 @@ Word16 encode_lpc_avq_fx( if ( k != 0 ) { move16(); - q_type = param_lpc[j]; + q_type = param_lpc[j]; // Q0 j = add( j, 1 ); } test(); if ( EQ_16( element_mode, IVAS_CPE_MDCT ) && k == 0 ) { - stereo_mode = param_lpc[j]; + stereo_mode = param_lpc[j]; // Q0 move16(); j = add( j, 1 ); } @@ -298,17 +308,19 @@ Word16 encode_lpc_avq_fx( if ( q_type == 0 ) { move16(); - st1 = param_lpc[j++]; + st1 = param_lpc[j++]; // Q0 } move16(); move16(); - qn1 = param_lpc[j++]; - qn2 = param_lpc[j++]; + qn1 = param_lpc[j++]; // Q0 + qn2 = param_lpc[j++]; // Q0 IF( EQ_16( qn1, SNS_LOW_BR_MODE ) ) { nb_ind = add( qn1, qn2 ); } + test(); + test(); IF( k == 0 || ( EQ_16( k, 1 ) && NE_16( core, TCX_20_CORE ) ) ) { /* Encode quantizer type */ @@ -317,12 +329,13 @@ Word16 encode_lpc_avq_fx( IF( k != 0 ) { nb = 1; + move16(); push_next_indice_fx( hBstr, q_type, nb ); } - nb_bits = add( nb_bits, nb ); + nb_bits = add( nb_bits, nb ); // Q0 /* Encode quantizer data */ -#if 1 // IVAS_CODE + test(); test(); test(); test(); @@ -330,7 +343,7 @@ Word16 encode_lpc_avq_fx( { /* Absolute quantizer with 1st stage stochastic codebook */ push_next_indice_fx( hBstr, st1, bits_for_abs_quant ); - nb_bits = add( nb_bits, bits_for_abs_quant ); + nb_bits = add( nb_bits, bits_for_abs_quant ); // Q0 } test(); @@ -338,21 +351,16 @@ Word16 encode_lpc_avq_fx( IF( EQ_16( element_mode, IVAS_CPE_MDCT ) && EQ_16( stereo_mode, 3 ) && st1 < 0 ) { push_next_indice_fx( hBstr, add( st1, 2 ), 1 ); - nb_bits = add( nb_bits, 1 ); - } -#else - IF( q_type == 0 ) - { - /* Absolute quantizer with 1st stage stochastic codebook */ - push_next_indice_fx( hBstr, st1, 8 ); - nb_bits = add( nb_bits, 8 ); + nb_bits = add( nb_bits, 1 ); // Q0 } -#endif + + test(); + test(); IF( NE_16( element_mode, IVAS_CPE_MDCT ) || ( NE_16( st1, -2 ) && NE_16( qn1, SNS_LOW_BR_MODE ) ) ) { /* 2 bits to specify Q2,Q3,Q4,ext */ - nb_bits = add( nb_bits, 4 ); + nb_bits = add( nb_bits, 4 ); // Q0 i = sub( qn1, 2 ); if ( s_or( i < 0, (Word16) GT_16( i, 3 ) ) ) @@ -399,18 +407,18 @@ Word16 encode_lpc_avq_fx( { unary_code( nb, hBstr ); } - nb_bits = add( nb_bits, nb ); + nb_bits = add( nb_bits, nb ); // Q0 move16(); nb = qn2; IF( GT_16( nb, 6 ) ) { - nb = sub( nb, 3 ); + nb = sub( nb, 3 ); // Q0 } ELSE IF( GT_16( nb, 4 ) ) { - nb = sub( nb, 4 ); + nb = sub( nb, 4 ); // Q0 } ELSE IF( nb == 0 ) { @@ -427,17 +435,17 @@ Word16 encode_lpc_avq_fx( { unary_code( nb, hBstr ); } - nb_bits = add( nb_bits, nb ); + nb_bits = add( nb_bits, nb ); // Q0 avqBits = shl( qn1, 2 ); unpack4bits( avqBits, ¶m_lpc[j], hBstr ); j = add( j, qn1 ); - nb_bits = add( nb_bits, avqBits ); + nb_bits = add( nb_bits, avqBits ); // Q0 avqBits = shl( qn2, 2 ); unpack4bits( avqBits, ¶m_lpc[j], hBstr ); j = add( j, qn2 ); - nb_bits = add( nb_bits, avqBits ); + nb_bits = add( nb_bits, avqBits ); // Q0 } } ELSE @@ -451,10 +459,10 @@ Word16 encode_lpc_avq_fx( Word16 encode_lpc_avq_ivas_fx( BSTR_ENC_HANDLE hBstr, /* i/o: bitstream handle */ - const Word16 numlpc, /* i : Number of sets of lpc */ - const Word16 *param_lpc, /* i : lpc parameters */ - const Word16 core, /* i : core */ - const Word16 element_mode /* i : element mode - decides between SNS and LPC coding */ + const Word16 numlpc, /* i : Number of sets of lpc Q0*/ + const Word16 *param_lpc, /* i : lpc parameters Q0*/ + const Word16 core, /* i : core Q0*/ + const Word16 element_mode /* i : element mode - decides between SNS and LPC coding Q0*/ ) { Word16 k, j; @@ -490,13 +498,13 @@ Word16 encode_lpc_avq_ivas_fx( IF( k != 0 ) { move16(); - q_type = param_lpc[j]; + q_type = param_lpc[j]; // Q0 j = add( j, 1 ); } test(); IF( EQ_16( element_mode, IVAS_CPE_MDCT ) && k == 0 ) { - stereo_mode = param_lpc[j]; + stereo_mode = param_lpc[j]; // Q0 move16(); j = add( j, 1 ); } @@ -507,18 +515,18 @@ Word16 encode_lpc_avq_ivas_fx( IF( q_type == 0 ) { move16(); - st1 = param_lpc[j]; + st1 = param_lpc[j]; // Q0 j = add( j, 1 ); } move16(); move16(); - qn1 = param_lpc[j]; + qn1 = param_lpc[j]; // Q0 j = add( j, 1 ); - qn2 = param_lpc[j]; + qn2 = param_lpc[j]; // Q0 j = add( j, 1 ); IF( NE_16( qn1, SNS_LOW_BR_MODE ) ) { - nb_ind = add( nb_ind, add( qn1, qn2 ) ); + nb_ind = add( nb_ind, add( qn1, qn2 ) ); // Q0 } test(); @@ -534,7 +542,7 @@ Word16 encode_lpc_avq_ivas_fx( move16(); push_next_indice( hBstr, q_type, nb ); } - nb_bits = add( nb_bits, nb ); + nb_bits = add( nb_bits, nb ); // Q0 /* Encode quantizer data */ test(); @@ -545,7 +553,7 @@ Word16 encode_lpc_avq_ivas_fx( { /* Absolute quantizer with 1st stage stochastic codebook */ push_next_indice( hBstr, st1, bits_for_abs_quant ); - nb_bits = add( nb_bits, bits_for_abs_quant ); + nb_bits = add( nb_bits, bits_for_abs_quant ); // Q0 } test(); @@ -553,7 +561,7 @@ Word16 encode_lpc_avq_ivas_fx( IF( EQ_16( element_mode, IVAS_CPE_MDCT ) && EQ_16( stereo_mode, 3 ) && st1 < 0 ) { push_next_indice( hBstr, add( st1, 2 ), 1 ); - nb_bits = add( nb_bits, 1 ); + nb_bits = add( nb_bits, 1 ); // Q0 } test(); @@ -642,12 +650,12 @@ Word16 encode_lpc_avq_ivas_fx( avqBits = shl( qn1, 2 ); unpack4bits_ivas_fx( avqBits, ¶m_lpc[j], hBstr ); j = add( j, qn1 ); - nb_bits = add( nb_bits, avqBits ); + nb_bits = add( nb_bits, avqBits ); // Q0 avqBits = shl( qn2, 2 ); unpack4bits_ivas_fx( avqBits, ¶m_lpc[j], hBstr ); j = add( j, qn2 ); - nb_bits = add( nb_bits, avqBits ); + nb_bits = add( nb_bits, avqBits ); // Q0 } } ELSE diff --git a/lib_enc/qlpc_stoch.c b/lib_enc/qlpc_stoch.c deleted file mode 100644 index bb488002d71e75a2e34c66942bb1e8f1fc8762ca..0000000000000000000000000000000000000000 --- a/lib_enc/qlpc_stoch.c +++ /dev/null @@ -1,46 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include -#include "options.h" -#include -#include "cnst.h" -#include "prot.h" -#include "rom_com.h" -#include "rom_enc.h" -#include "basop_proto_func.h" -#include "wmc_auto.h" diff --git a/lib_enc/qlpc_stoch_fx.c b/lib_enc/qlpc_stoch_fx.c index 1750528b3d433010d0e4905c32413f978b7f1149..d6f0b504f8f2c5ebc0aea689ff87b5eaac0a7ad0 100644 --- a/lib_enc/qlpc_stoch_fx.c +++ b/lib_enc/qlpc_stoch_fx.c @@ -30,19 +30,19 @@ *--------------------------------------------------------------------*/ void lpc_quantization_fx( Encoder_State *st, - const Word16 lsp[], - const Word16 lspmid[], - Word16 lsp_q[], - Word16 lsf_q[], /* 14Q1*1.28 */ - Word16 lspmid_q[], - Word16 lspq_ind[], - Word16 clip_var[], - const Word16 coder_type, - const Word16 acelp_midLpc, - Word16 param_lpc[], - Word16 nbits_lpc[], - Word16 *bits_param_lpc, - Word16 *no_param_lpc, + const Word16 lsp[], /* Q15 */ + const Word16 lspmid[], /* Q15 */ + Word16 lsp_q[], /* Q15 */ + Word16 lsf_q[], /* 14Q1*1.28 */ + Word16 lspmid_q[], /* Q15 */ + Word16 lspq_ind[], /* Q15 */ + Word16 clip_var[], /* [2.56x,Q14,Q8,Q0,Q14,Q14] */ + const Word16 coder_type, /* Q0 */ + const Word16 acelp_midLpc, /* Q0 */ + Word16 param_lpc[], /* Q0 */ + Word16 nbits_lpc[], /* Q0 */ + Word16 *bits_param_lpc, /* Q0 */ + Word16 *no_param_lpc, /* Q0 */ const Word16 Q_ener ) { Word16 nb_indices; @@ -114,7 +114,9 @@ void lpc_quantization_fx( IF( EQ_16( st->next_force_safety_net, 1 ) && EQ_16( st->Opt_RF_ON, 1 ) ) { force_sf = 1; + move16(); st->next_force_safety_net = 0; + move16(); } test(); @@ -123,14 +125,16 @@ void lpc_quantization_fx( lsf_end_enc_fx( st, lsf, lsf_q, ENDLSF_NBITS, GENERIC, Q_ener, force_sf, param_lpc, no_param_lpc, bits_param_lpc, GENERIC ); - nb_indices = *no_param_lpc; + nb_indices = *no_param_lpc; // Q0 + move16(); } ELSE { lsf_end_enc_fx( st, lsf, lsf_q, ENDLSF_NBITS, coder_type, Q_ener, force_sf, param_lpc, no_param_lpc, bits_param_lpc, coder_type ); - nb_indices = *no_param_lpc; + nb_indices = *no_param_lpc; // Q0 + move16(); } @@ -147,6 +151,7 @@ void lpc_quantization_fx( ( EQ_16( coder_type, VOICED ) || EQ_16( coder_type, GENERIC ) ) && EQ_16( st->Opt_RF_ON, 1 ) ) { st->next_force_safety_net = 1; + move16(); } lsf2lsp_fx( lsf_q, lsp_q, M, st->sr_core ); @@ -168,7 +173,7 @@ void lpc_quantization_fx( move16(); FOR( i = nb_indices - 1; i >= 0; i-- ) { - st->seed_acelp = extract_l( L_mac0( L_mac0( 13849, shr( st->seed_acelp, 1 ), 31821 ), param_lpc[i], 31821 ) ); + st->seed_acelp = extract_l( L_mac0( L_mac0( 13849, shr( st->seed_acelp, 1 ), 31821 ), param_lpc[i], 31821 ) ); // Q0 move16(); } @@ -183,7 +188,7 @@ void lpc_quantization_fx( lsp2lsf_fx( lspmid, lsfmid, M, extract_l( st->sr_core ) ); midlsf_enc_fx( st->lsf_old_fx, lsf_q, lsfmid, &lsfmid_idx, M, st->Bin_E_old_fx, Q_ener, (Word8) st->narrowBand, st->sr_core, coder_type ); - param_lpc[nb_indices++] = lsfmid_idx; + param_lpc[nb_indices++] = lsfmid_idx; // Q0 move16(); midlsf_dec( st->lsf_old_fx, lsf_q, lsfmid_idx, lsfmid_q, coder_type, NULL, 0, 1 ); @@ -203,17 +208,17 @@ void lpc_quantization_fx( void lpc_quantization_ivas_fx( Encoder_State *st, - const Word16 lsp[], /* Q15 */ - const Word16 lspmid[], /* Q15 */ - Word16 lsp_q[], /* Q15 */ - Word16 lsf_q[], /* 14Q1*1.28 */ - Word16 lspmid_q[], /* Q15 */ - const Word16 coder_type, - const Word16 acelp_midLpc, - Word16 param_lpc[], - Word16 nbits_lpc[], - Word16 *bits_param_lpc, - Word16 *no_param_lpc, + const Word16 lsp[], /* Q15 */ + const Word16 lspmid[], /* Q15 */ + Word16 lsp_q[], /* Q15 */ + Word16 lsf_q[], /* 14Q1*1.28 */ + Word16 lspmid_q[], /* Q15 */ + const Word16 coder_type, /* Q0 */ + const Word16 acelp_midLpc, /* Q0 */ + Word16 param_lpc[], /* Q0 */ + Word16 nbits_lpc[], /* Q0 */ + Word16 *bits_param_lpc, /* Q0 */ + Word16 *no_param_lpc, /* Q0 */ const Word16 Q_ener ) { Word16 nb_indices; @@ -262,7 +267,7 @@ void lpc_quantization_ivas_fx( /*Force safety net when possible in case of transitions*/ test(); test(); - IF( st->tc_cnt >= 1 || LE_32( st->last_core_brate, SID_2k40 ) || ( EQ_16( st->next_force_safety_net, 1 ) ) ) + IF( GE_32( st->tc_cnt, 1 ) || LE_32( st->last_core_brate, SID_2k40 ) || ( EQ_16( st->next_force_safety_net, 1 ) ) ) { force_sf = 1; move16(); @@ -285,7 +290,7 @@ void lpc_quantization_ivas_fx( lsf_end_enc_ivas_fx( st, lsf, lsf_q, ENDLSF_NBITS, GENERIC, Q_ener, force_sf, param_lpc, no_param_lpc, bits_param_lpc, GENERIC, NULL ); - nb_indices = *no_param_lpc; + nb_indices = *no_param_lpc; // Q0 move16(); } ELSE @@ -293,7 +298,7 @@ void lpc_quantization_ivas_fx( lsf_end_enc_ivas_fx( st, lsf, lsf_q, ENDLSF_NBITS, coder_type, Q_ener, force_sf, param_lpc, no_param_lpc, bits_param_lpc, coder_type, NULL ); - nb_indices = *no_param_lpc; + nb_indices = *no_param_lpc; // Q0 move16(); } @@ -328,7 +333,7 @@ void lpc_quantization_ivas_fx( move16(); FOR( i = nb_indices - 1; i >= 0; i-- ) { - st->seed_acelp = extract_l( L_mac0( L_mac0( 13849, shr( st->seed_acelp, 1 ), 31821 ), param_lpc[i], 31821 ) ); + st->seed_acelp = extract_l( L_mac0( L_mac0( 13849, shr( st->seed_acelp, 1 ), 31821 ), param_lpc[i], 31821 ) ); // Q0 move16(); } @@ -343,7 +348,7 @@ void lpc_quantization_ivas_fx( lsp2lsf_fx( lspmid, lsfmid, M, extract_l( st->sr_core ) ); midlsf_enc_fx( st->lsf_old_fx, lsf_q, lsfmid, &lsfmid_idx, M, st->Bin_E_old_fx, Q_ener, (Word8) st->narrowBand, st->sr_core, coder_type ); - param_lpc[nb_indices] = lsfmid_idx; + param_lpc[nb_indices] = lsfmid_idx; // Q0 move16(); nb_indices = add( nb_indices, 1 ); midlsf_dec( st->lsf_old_fx, lsf_q, lsfmid_idx, lsfmid_q, coder_type, NULL, 0, 1 ); @@ -355,7 +360,7 @@ void lpc_quantization_ivas_fx( { param_lpc[nb_indices] = 0; move16(); - nb_indices = add( nb_indices, 1 ); + nb_indices = add( nb_indices, 1 ); // Q0 } } @@ -371,14 +376,14 @@ void lpc_quantization_ivas_fx( *-------------------------------------------------------------------*/ void Unified_weighting_fx( - const Word32 Bin_Ener_128_fx[], /* i : FFT Bin energy 128 bins in two sets Q_ener */ + const Word32 Bin_Ener_128_fx[], /* i : FFT Bin energy 128 bins in two sets Q_ener */ Word16 Q_ener, - const Word16 lsf_fx[], /* i : LSF vector x2.56 */ - Word16 w_fx[], /* o : LP weighting filter (numerator) Q8 */ - const Word16 narrowBand, /* i : flag for Narrowband */ - const Word16 unvoiced, /* i : flag for Unvoiced frame */ - const Word32 sr_core, /* i : sampling rate of core-coder */ - const Word16 order /* i : LP order */ + const Word16 lsf_fx[], /* i : LSF vector x2.56 */ + Word16 w_fx[], /* o : LP weighting filter (numerator) Q8 */ + const Word16 narrowBand, /* i : flag for Narrowband Q0*/ + const Word16 unvoiced, /* i : flag for Unvoiced frame Q0*/ + const Word32 sr_core, /* i : sampling rate of core-coder Q0*/ + const Word16 order /* i : LP order Q0*/ ) { Word16 i; @@ -396,67 +401,64 @@ void Unified_weighting_fx( const Word32 *Freq_w_Table_fx, *Bin_Ener_fx; #ifdef BASOP_NOGLOB_DECLARE_LOCAL Flag Overflow = 0; + move32(); #endif /*Config. weighting*/ IF( narrowBand ) { - ptr_lsf_fit_model = lsf_unified_fit_model_nb; - nf_fx = 16384; - move16(); /* x2.56 */ + ptr_lsf_fit_model = lsf_unified_fit_model_nb; // Q0 + nf_fx = 16384; /* 6400 in x2.56 */ + move16(); last_bin = 127; move16(); - Bin_Ener_fx = Bin_Ener_128_fx; + Bin_Ener_fx = Bin_Ener_128_fx; /* Q_ener */ } ELSE IF( EQ_32( sr_core, INT_FS_12k8 ) ) { ptr_lsf_fit_model = lsf_unified_fit_model_wb; - nf_fx = 16384; - move16(); /* x2.56 */ + nf_fx = 16384; /* 6400 in x2.56 */ + move16(); last_bin = 127; move16(); - Bin_Ener_fx = Bin_Ener_128_fx; + Bin_Ener_fx = Bin_Ener_128_fx; /* Q_ener */ } ELSE { ptr_lsf_fit_model = lsf_unified_fit_model_wbhb; - nf_fx = 20480; - move16(); /* x2.56 */ + nf_fx = 20480; /* 8000 in x2.56 */ + move16(); /* Fill the missing part (128~159) of the bin energy */ last_bin = 159; move16(); - Copy32( Bin_Ener_128_fx, Bin_Ener_160_fx, L_FFT / 2 ); + Copy32( Bin_Ener_128_fx, Bin_Ener_160_fx, L_FFT / 2 ); /* Q_ener */ /* Find average bin energy (32 Energy) */ L_tmp = L_deposit_l( 0 ); FOR( i = 95; i < 127; i++ ) { -#ifdef BASOP_NOGLOB - L_tmp = L_add_o( L_tmp, Bin_Ener_160_fx[i], &Overflow ); -#else - L_tmp = L_add( L_tmp, Bin_Ener_160_fx[i] ); -#endif + L_tmp = L_add_o( L_tmp, Bin_Ener_160_fx[i], &Overflow ); /* Q_ener */ } L_tmp = L_shr( L_tmp, 5 ); FOR( i = 127; i < 160; i++ ) { - Bin_Ener_160_fx[i] = L_tmp; + Bin_Ener_160_fx[i] = L_tmp; /* Q_ener */ move32(); } - Bin_Ener_fx = Bin_Ener_160_fx; + Bin_Ener_fx = Bin_Ener_160_fx; /* Q_ener */ } /* 1) FFT weights*/ - Freq_w_Table_fx = Freq_Weight_Com_fx; + Freq_w_Table_fx = Freq_Weight_Com_fx; /* Q31 */ if ( unvoiced ) { - Freq_w_Table_fx = Freq_Weight_UV_fx; + Freq_w_Table_fx = Freq_Weight_UV_fx; /* Q31 */ } /* Use Envelope */ @@ -506,7 +508,7 @@ void Unified_weighting_fx( if ( LT_16( w_fft_fx[i], min_fx ) ) { - min_fx = w_fft_fx[i]; + min_fx = w_fft_fx[i]; // Q8 move16(); } } @@ -520,11 +522,7 @@ void Unified_weighting_fx( } ELSE { -#ifdef BASOP_NOGLOB L_tmp = L_shl_o( L_deposit_l( sub_o( w_fft_fx[i], min_fx, &Overflow ) ), 13, &Overflow ); /* Q21 */ -#else - L_tmp = L_shl( L_deposit_l( sub( w_fft_fx[i], min_fx ) ), 13 ); /* Q21 */ -#endif exp = norm_l( L_tmp ); frac = round_fx( L_shl( L_tmp, exp ) ); exp = sub( add( exp, 21 ), 30 ); @@ -541,21 +539,21 @@ void Unified_weighting_fx( FOR( i = 0; i < order; i++ ) { /* 2) IHM weights*/ - tmp1_fx = lsf_fx[i]; + tmp1_fx = lsf_fx[i]; /* x2.56 */ move16(); if ( i > 0 ) { - tmp1_fx = sub( tmp1_fx, lsf_fx[i - 1] ); + tmp1_fx = sub( tmp1_fx, lsf_fx[i - 1] ); /* x2.56 */ } tmp2_fx = nf_fx; move16(); - if ( NE_16( i, order - 1 ) ) + if ( NE_16( i, sub( order, 1 ) ) ) { - tmp2_fx = lsf_fx[i + 1]; + tmp2_fx = lsf_fx[i + 1]; /* x2.56 */ move16(); } - tmp2_fx = sub( tmp2_fx, lsf_fx[i] ); + tmp2_fx = sub( tmp2_fx, lsf_fx[i] ); /* x2.56 */ s1 = 15; move16(); @@ -564,15 +562,17 @@ void Unified_weighting_fx( if ( tmp1_fx == 0 ) { tmp1_fx = 8; + move16(); } tmp1_fx = Inv16( tmp1_fx, &s1 ); if ( tmp2_fx == 0 ) { tmp2_fx = 8; + move16(); } tmp2_fx = Inv16( tmp2_fx, &s2 ); s1 = BASOP_Util_Add_MantExp( tmp1_fx, s1, tmp2_fx, s2, &tmp1_fx ); /* x * 2.56 / pow(2.0, 15 + |s1|) */ - tmp_fx = mult_r( nf_fx, 10430 ); + tmp_fx = mult_r( nf_fx, 10430 /* 0.31 in Q15*/ ); s2 = norm_s( tmp_fx ); tmp_fx = shl( tmp_fx, s2 ); s1 = sub( s1, s2 ); @@ -589,7 +589,7 @@ void Unified_weighting_fx( IF( LT_32( L_shl( L_tmp, 5 ), InvIntTable[i + 1] ) ) { - w_fx[i] = shr( InvIntTable[i + 1], 7 ); + w_fx[i] = shr( InvIntTable[i + 1], 7 ); // Q8 move16(); } ELSE @@ -601,7 +601,8 @@ void Unified_weighting_fx( } ELSE { - w_fx[i] = extract_l( L_shr( L_tmp, 2 ) ); + w_fx[i] = extract_l( L_shr( L_tmp, 2 ) ); // Q8 + move16(); } } } diff --git a/lib_enc/range_enc.c b/lib_enc/range_enc.c deleted file mode 100644 index fd4f3cb7c53af6bc1a4a149c6db6799b8f39655e..0000000000000000000000000000000000000000 --- a/lib_enc/range_enc.c +++ /dev/null @@ -1,42 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include "cnst.h" -#include "rom_com.h" -#include "prot.h" -#include "wmc_auto.h" diff --git a/lib_enc/range_enc_fx.c b/lib_enc/range_enc_fx.c index da325b2bd232a5fa22087054352ad2c5f3e941cb..689b313d8f2da140d0419f59704d676dfa48621b 100644 --- a/lib_enc/range_enc_fx.c +++ b/lib_enc/range_enc_fx.c @@ -10,7 +10,6 @@ #include "rom_com.h" /* Static table prototypes */ //#include "prot_fx.h" /* Function prototypes */ #include "prot_fx.h" /* Function prototypes */ -#include "prot.h" /* Function prototypes */ #include "prot_fx_enc.h" /* Function prototypes */ @@ -26,7 +25,7 @@ static void rc_enc_write_ivas_fx( BSTR_ENC_HANDLE hBstr, Word16 byte, Word16 bit void rc_enc_init_fx( PVQ_ENC_HANDLE hPVQ, /* i/o: PVQ encoder handle */ - Word16 tot_bits /* i : Total bit budget */ + Word16 tot_bits /* i : Total bit budget Q0*/ ) { hPVQ->rc_low = L_deposit_l( 0 ); @@ -40,7 +39,7 @@ void rc_enc_init_fx( move16(); hPVQ->rc_num_bits = 0; move16(); - hPVQ->rc_tot_bits = tot_bits; + hPVQ->rc_tot_bits = tot_bits; // Q0 move16(); hPVQ->rc_offset = 0; move16(); @@ -54,37 +53,37 @@ void rc_enc_init_fx( * Encode symbol with range coder *-------------------------------------------------------------------*/ void rc_encode_ivas_fx( - BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ - PVQ_ENC_HANDLE hPVQ, /* i/o: PVQ encoder handle */ - UWord32 cum_freq, /* i : Cumulative frequency up to symbol */ - UWord32 sym_freq, /* i : Symbol probability */ - UWord32 tot /* i : Total cumulative frequency */ + BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ + PVQ_ENC_HANDLE hPVQ, /* i/o: PVQ encoder handle */ + UWord32 cum_freq, /* i : Cumulative frequency up to symbol Q0*/ + UWord32 sym_freq, /* i : Symbol probability Q0*/ + UWord32 tot /* i : Total cumulative frequency Q0*/ ) { UWord32 r, tmp, inv_tot, lsb; Word16 exp; UWord16 carry; - inv_tot = UL_inverse( tot, &exp ); + inv_tot = UL_inverse( tot, &exp ); // Q0 Mpy_32_32_uu( hPVQ->rc_range, inv_tot, &tmp, &lsb ); /*0+exp-32 */ r = UL_lshr( tmp, sub( exp, 32 ) ); /* exp-32-exp3+32 = 0 */ tmp = UL_Mpy_32_32( r, cum_freq ); - hPVQ->rc_low = UL_addNs( hPVQ->rc_low, tmp, &carry ); + hPVQ->rc_low = UL_addNs( hPVQ->rc_low, tmp, &carry ); // Q0 move32(); if ( carry != 0 ) { - hPVQ->rc_carry = carry; + hPVQ->rc_carry = carry; // Q0 move16(); } - hPVQ->rc_range = UL_Mpy_32_32( r, sym_freq ); + hPVQ->rc_range = UL_Mpy_32_32( r, sym_freq ); // Q0 move32(); WHILE( LT_64( hPVQ->rc_range, 1 << 24 ) ) { - hPVQ->rc_range = UL_lshl( hPVQ->rc_range, 8 ); + hPVQ->rc_range = UL_lshl( hPVQ->rc_range, 8 ); // Q0 move32(); - hPVQ->rc_num_bits = add( hPVQ->rc_num_bits, 8 ); + hPVQ->rc_num_bits = add( hPVQ->rc_num_bits, 8 ); // Q0 move16(); rc_enc_shift_ivas_fx( hBstr, hPVQ ); } @@ -92,36 +91,36 @@ void rc_encode_ivas_fx( return; } void rc_encode_fx( - BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ - PVQ_ENC_HANDLE hPVQ, /* i/o: PVQ encoder handle */ - UWord32 cum_freq, /* i : Cumulative frequency up to symbol */ - UWord32 sym_freq, /* i : Symbol probability */ - UWord32 tot /* i : Total cumulative frequency */ + BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ + PVQ_ENC_HANDLE hPVQ, /* i/o: PVQ encoder handle */ + UWord32 cum_freq, /* i : Cumulative frequency up to symbol Q0*/ + UWord32 sym_freq, /* i : Symbol probability Q0*/ + UWord32 tot /* i : Total cumulative frequency Q0*/ ) { UWord32 r, tmp, inv_tot, lsb; Word16 exp; UWord16 carry; - inv_tot = UL_inverse( tot, &exp ); + inv_tot = UL_inverse( tot, &exp ); // Q0 Mpy_32_32_uu( hPVQ->rc_range, inv_tot, &tmp, &lsb ); /*0+exp-32 */ r = UL_lshr( tmp, sub( exp, 32 ) ); /* exp-32-exp3+32 = 0 */ tmp = UL_Mpy_32_32( r, cum_freq ); - hPVQ->rc_low = UL_addNs( hPVQ->rc_low, tmp, &carry ); + hPVQ->rc_low = UL_addNs( hPVQ->rc_low, tmp, &carry ); // Q0 if ( carry != 0 ) { - hPVQ->rc_carry = carry; + hPVQ->rc_carry = carry; // Q0 move16(); } - hPVQ->rc_range = UL_Mpy_32_32( r, sym_freq ); + hPVQ->rc_range = UL_Mpy_32_32( r, sym_freq ); // Q0 WHILE( hPVQ->rc_range < 1 << 24 ) { - L_sub( 0, 0 ); /* Comparison in while */ - hPVQ->rc_range = UL_lshl( hPVQ->rc_range, 8 ); - hPVQ->rc_num_bits = add( hPVQ->rc_num_bits, 8 ); + L_sub( 0, 0 ); /* Comparison in while */ + hPVQ->rc_range = UL_lshl( hPVQ->rc_range, 8 ); // Q0 + hPVQ->rc_num_bits = add( hPVQ->rc_num_bits, 8 ); // Q0 rc_enc_shift_fx( hBstr, hPVQ ); } @@ -146,8 +145,8 @@ void rc_enc_finish_ivas_fx( bits = add( norm_ul( hPVQ->rc_range ), 1 ); mask = UL_lshr( 0xffffffff, bits ); - val = UL_addNs( hPVQ->rc_low, mask, &over1 ); - high = UL_addNs( hPVQ->rc_low, hPVQ->rc_range, &over2 ); + val = UL_addNs( hPVQ->rc_low, mask, &over1 ); // Q0 + high = UL_addNs( hPVQ->rc_low, hPVQ->rc_range, &over2 ); // Q0 val = L_and( val, ~mask ); L_xor( 0, 0 ); /* For bit not */ @@ -157,13 +156,13 @@ void rc_enc_finish_ivas_fx( L_sub( 0, 0 ); /* For comparision in if */ IF( UL_addNsD( val, mask ) >= high ) { - bits = add( bits, 1 ); - mask = UL_lshr( mask, 1 ); - val = UL_and( UL_addNsD( hPVQ->rc_low, mask ), ~mask ); - L_xor( 0, 0 ); /* For bit not */ + bits = add( bits, 1 ); // Q0 + mask = UL_lshr( mask, 1 ); // Q0 + val = UL_and( UL_addNsD( hPVQ->rc_low, mask ), ~mask ); // Q0 + L_xor( 0, 0 ); /* For bit not */ } - if ( LT_32( val, hPVQ->rc_low ) ) + if ( LT_64( val, hPVQ->rc_low ) ) { hPVQ->rc_carry = 1; move16(); @@ -175,10 +174,10 @@ void rc_enc_finish_ivas_fx( IF( GT_16( bits, sub( hPVQ->rc_tot_bits, hPVQ->rc_num_bits ) ) ) { - bits = sub( hPVQ->rc_tot_bits, hPVQ->rc_num_bits ); + bits = sub( hPVQ->rc_tot_bits, hPVQ->rc_num_bits ); // Q0 } - hPVQ->rc_num_bits = add( hPVQ->rc_num_bits, bits ); + hPVQ->rc_num_bits = add( hPVQ->rc_num_bits, bits ); // Q0 move16(); FOR( ; bits > 0; bits -= 8 ) { @@ -201,7 +200,7 @@ void rc_enc_finish_ivas_fx( rc_enc_write_ivas_fx( hBstr, lshr( add( hPVQ->rc_cache, hPVQ->rc_carry ), sub( 8, bits ) ), bits ); } - bits = hPVQ->rc_num_bits; + bits = hPVQ->rc_num_bits; // Q0 move16(); WHILE( LT_16( bits, sub( hPVQ->rc_tot_bits, 16 ) ) ) { @@ -209,7 +208,7 @@ void rc_enc_finish_ivas_fx( bits = add( bits, 16 ); } - bits = sub( hPVQ->rc_tot_bits, bits ); + bits = sub( hPVQ->rc_tot_bits, bits ); // Q0 IF( bits > 0 ) { rc_enc_write_ivas_fx( hBstr, 0, bits ); @@ -227,11 +226,11 @@ void rc_enc_finish_fx( Word16 bits; UWord16 over1, over2; - bits = add( norm_ul( hPVQ->rc_range ), 1 ); + bits = add( norm_ul( hPVQ->rc_range ), 1 ); // Q0 mask = UL_lshr( 0xffffffff, bits ); - val = UL_addNs( hPVQ->rc_low, mask, &over1 ); - high = UL_addNs( hPVQ->rc_low, hPVQ->rc_range, &over2 ); + val = UL_addNs( hPVQ->rc_low, mask, &over1 ); // Q0 + high = UL_addNs( hPVQ->rc_low, hPVQ->rc_range, &over2 ); // Q0 val = L_and( val, ~mask ); L_xor( 0, 0 ); /* For bit not */ @@ -241,10 +240,10 @@ void rc_enc_finish_fx( L_sub( 0, 0 ); /* For comparision in if */ IF( UL_addNsD( val, mask ) >= high ) { - bits = add( bits, 1 ); - mask = UL_lshr( mask, 1 ); - val = UL_and( UL_addNsD( hPVQ->rc_low, mask ), ~mask ); - L_xor( 0, 0 ); /* For bit not */ + bits = add( bits, 1 ); // Q0 + mask = UL_lshr( mask, 1 ); // Q0 + val = UL_and( UL_addNsD( hPVQ->rc_low, mask ), ~mask ); // Q0 + L_xor( 0, 0 ); /* For bit not */ } if ( val < hPVQ->rc_low ) @@ -259,10 +258,10 @@ void rc_enc_finish_fx( IF( GT_16( bits, sub( hPVQ->rc_tot_bits, hPVQ->rc_num_bits ) ) ) { - bits = sub( hPVQ->rc_tot_bits, hPVQ->rc_num_bits ); + bits = sub( hPVQ->rc_tot_bits, hPVQ->rc_num_bits ); // Q0 } - hPVQ->rc_num_bits = add( hPVQ->rc_num_bits, bits ); + hPVQ->rc_num_bits = add( hPVQ->rc_num_bits, bits ); // Q0 FOR( ; bits > 0; bits -= 8 ) { rc_enc_shift_fx( hBstr, hPVQ ); @@ -284,7 +283,7 @@ void rc_enc_finish_fx( rc_enc_write_fx( hBstr, lshr( add( hPVQ->rc_cache, hPVQ->rc_carry ), sub( 8, bits ) ), bits ); } - bits = hPVQ->rc_num_bits; + bits = hPVQ->rc_num_bits; // Q0 move16(); WHILE( LT_16( bits, sub( hPVQ->rc_tot_bits, 16 ) ) ) { @@ -323,7 +322,7 @@ static void rc_enc_shift_ivas_fx( WHILE( hPVQ->rc_carry_count > 0 ) { rc_enc_write_ivas_fx( hBstr, s_and( add( hPVQ->rc_carry, 0xff ), 255 ), 8 ); - hPVQ->rc_carry_count = sub( hPVQ->rc_carry_count, 1 ); + hPVQ->rc_carry_count = sub( hPVQ->rc_carry_count, 1 ); // Q0 move16(); } @@ -333,7 +332,7 @@ static void rc_enc_shift_ivas_fx( } ELSE { - hPVQ->rc_carry_count = add( hPVQ->rc_carry_count, 1 ); + hPVQ->rc_carry_count = add( hPVQ->rc_carry_count, 1 ); // Q0 move16(); } hPVQ->rc_low = UL_lshl( hPVQ->rc_low, 8 ); @@ -357,7 +356,7 @@ static void rc_enc_shift_fx( WHILE( hPVQ->rc_carry_count > 0 ) { rc_enc_write_fx( hBstr, s_and( add( hPVQ->rc_carry, 0xff ), 255 ), 8 ); - hPVQ->rc_carry_count = sub( hPVQ->rc_carry_count, 1 ); + hPVQ->rc_carry_count = sub( hPVQ->rc_carry_count, 1 ); // Q0 } hPVQ->rc_cache = u_extract_l( UL_lshr( hPVQ->rc_low, 24 ) ); @@ -366,9 +365,9 @@ static void rc_enc_shift_fx( } ELSE { - hPVQ->rc_carry_count = add( hPVQ->rc_carry_count, 1 ); + hPVQ->rc_carry_count = add( hPVQ->rc_carry_count, 1 ); // Q0 } - hPVQ->rc_low = UL_lshl( hPVQ->rc_low, 8 ); + hPVQ->rc_low = UL_lshl( hPVQ->rc_low, 8 ); // Q0 return; } @@ -379,29 +378,29 @@ static void rc_enc_shift_fx( * *-------------------------------------------------------------------*/ void rc_enc_bits_ivas_fx( - BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ - PVQ_ENC_HANDLE hPVQ, /* i/o: PVQ encoder handle */ - UWord32 value, /* i : Value to encode */ - Word16 bits /* i : Number of bits used */ + BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ + PVQ_ENC_HANDLE hPVQ, /* i/o: PVQ encoder handle */ + UWord32 value, /* i : Value to encode Q0*/ + Word16 bits /* i : Number of bits used Q0*/ ) { IF( LE_16( add( rc_get_bits2_fx( hPVQ->rc_num_bits, hPVQ->rc_range ), bits ), hPVQ->rc_tot_bits ) ) { - hPVQ->rc_num_bits = add( hPVQ->rc_num_bits, bits ); + hPVQ->rc_num_bits = add( hPVQ->rc_num_bits, bits ); // Q0 move16(); IF( GT_16( bits, 16 ) ) { push_indice( hBstr, sub( IND_RC_END, hPVQ->rc_offset ), u_extract_l( UL_lshr( value, 16 ) ), sub( bits, 16 ) ); - hPVQ->rc_offset = add( hPVQ->rc_offset, 1 ); + hPVQ->rc_offset = add( hPVQ->rc_offset, 1 ); // Q0 move16(); push_indice( hBstr, sub( IND_RC_END, hPVQ->rc_offset ), u_extract_l( UL_and( value, 0x0000ffff ) ), 16 ); - hPVQ->rc_offset = add( hPVQ->rc_offset, 1 ); + hPVQ->rc_offset = add( hPVQ->rc_offset, 1 ); // Q0 move16(); } ELSE { push_indice( hBstr, sub( IND_RC_END, hPVQ->rc_offset ), u_extract_l( value ), bits ); - hPVQ->rc_offset = add( hPVQ->rc_offset, 1 ); + hPVQ->rc_offset = add( hPVQ->rc_offset, 1 ); // Q0 move16(); } } @@ -412,27 +411,27 @@ void rc_enc_bits_ivas_fx( return; } void rc_enc_bits_fx( - BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ - PVQ_ENC_HANDLE hPVQ, /* i/o: PVQ encoder handle */ - UWord32 value, /* i : Value to encode */ - Word16 bits /* i : Number of bits used */ + BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ + PVQ_ENC_HANDLE hPVQ, /* i/o: PVQ encoder handle */ + UWord32 value, /* i : Value to encode Q0*/ + Word16 bits /* i : Number of bits used Q0*/ ) { IF( LE_16( add( rc_get_bits2_fx( hPVQ->rc_num_bits, hPVQ->rc_range ), bits ), hPVQ->rc_tot_bits ) ) { - hPVQ->rc_num_bits = add( hPVQ->rc_num_bits, bits ); + hPVQ->rc_num_bits = add( hPVQ->rc_num_bits, bits ); // Q0 IF( GT_16( bits, 16 ) ) { push_indice_fx( hBstr, sub( IND_RC_END, hPVQ->rc_offset ), u_extract_l( UL_lshr( value, 16 ) ), sub( bits, 16 ) ); - hPVQ->rc_offset = add( hPVQ->rc_offset, 1 ); + hPVQ->rc_offset = add( hPVQ->rc_offset, 1 ); // Q0 push_indice_fx( hBstr, sub( IND_RC_END, hPVQ->rc_offset ), u_extract_l( UL_and( value, 0x0000ffff ) ), 16 ); - hPVQ->rc_offset = add( hPVQ->rc_offset, 1 ); + hPVQ->rc_offset = add( hPVQ->rc_offset, 1 ); // Q0 } ELSE { push_indice_fx( hBstr, sub( IND_RC_END, hPVQ->rc_offset ), u_extract_l( value ), bits ); - hPVQ->rc_offset = add( hPVQ->rc_offset, 1 ); + hPVQ->rc_offset = add( hPVQ->rc_offset, 1 ); // Q0 } } ELSE @@ -448,10 +447,10 @@ void rc_enc_bits_fx( * Encode with uniform distribution *-------------------------------------------------------------------*/ void rc_enc_uniform_ivas_fx( - BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ - PVQ_ENC_HANDLE hPVQ, /* i/o: PVQ encoder handle */ - UWord32 value, /* i : Value to encode */ - UWord32 tot /* i : Maximum value */ + BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ + PVQ_ENC_HANDLE hPVQ, /* i/o: PVQ encoder handle */ + UWord32 value, /* i : Value to encode Q0*/ + UWord32 tot /* i : Maximum value Q0*/ ) { Word16 n; @@ -472,15 +471,15 @@ void rc_enc_uniform_ivas_fx( return; } void rc_enc_uniform_fx( - BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ - PVQ_ENC_HANDLE hPVQ, /* i/o: PVQ encoder handle */ - UWord32 value, /* i : Value to encode */ - UWord32 tot /* i : Maximum value */ + BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ + PVQ_ENC_HANDLE hPVQ, /* i/o: PVQ encoder handle */ + UWord32 value, /* i : Value to encode Q0*/ + UWord32 tot /* i : Maximum value Q0*/ ) { Word16 n; - n = sub( 32, norm_ul( UL_subNsD( tot, 1 ) ) ); + n = sub( 32, norm_ul( UL_subNsD( tot, 1 ) ) ); // Q0 IF( LE_16( n, 8 ) ) { @@ -488,7 +487,7 @@ void rc_enc_uniform_fx( } ELSE { - n = sub( n, 8 ); + n = sub( n, 8 ); // Q0 rc_encode_fx( hBstr, hPVQ, UL_lshr( value, n ), 1, UL_addNsD( UL_lshr( tot, n ), 1 ) ); rc_enc_bits_fx( hBstr, hPVQ, UL_and( value, UL_subNsD( UL_lshl( 1, n ), 1 ) ), n ); } @@ -502,9 +501,9 @@ void rc_enc_uniform_fx( * Write a byte to bitstream *-------------------------------------------------------------------*/ static void rc_enc_write_ivas_fx( - BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ - Word16 byte, /* i : Byte to write */ - Word16 bits /* i : Number of bits */ + BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ + Word16 byte, /* i : Byte to write Q0*/ + Word16 bits /* i : Number of bits Q0*/ ) { push_indice( hBstr, IND_RC_START, byte, bits ); @@ -512,9 +511,9 @@ static void rc_enc_write_ivas_fx( return; } static void rc_enc_write_fx( - BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ - Word16 byte, /* i : Byte to write */ - Word16 bits /* i : Number of bits */ + BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ + Word16 byte, /* i : Byte to write Q0*/ + Word16 bits /* i : Number of bits Q0*/ ) { push_indice_fx( hBstr, IND_RC_START, byte, bits ); diff --git a/lib_enc/re8_cod.c b/lib_enc/re8_cod.c deleted file mode 100644 index e748899a9667996f0776eb65127752b66796a660..0000000000000000000000000000000000000000 --- a/lib_enc/re8_cod.c +++ /dev/null @@ -1,40 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include "prot.h" -#include "wmc_auto.h" diff --git a/lib_enc/re8_cod_fx.c b/lib_enc/re8_cod_fx.c index e035baf57ccfbd988bbb2596722035453751371f..d43dbbf57aa184d18022f519071e0e3df1c0a9b8 100644 --- a/lib_enc/re8_cod_fx.c +++ b/lib_enc/re8_cod_fx.c @@ -4,7 +4,6 @@ #include #include "options.h" /* Compilation switches */ #include "cnst.h" -//#include "prot_fx.h" #include "prot_fx.h" /* Function prototypes */ #include "prot_fx_enc.h" /* Function prototypes */ @@ -17,10 +16,10 @@ *--------------------------------------------------------------------------*/ void re8_cod_fx( - Word16 x[], /* i : point in RE8 (8-dimensional integer vector) */ - Word16 *n, /* i : codebook number (*n is an integer defined in {0,2,3,4,..,n_max}) */ - UWord16 *I, /* o : index of c (pointer to unsigned 16-bit word) */ - Word16 k[] /* o : index of v (8-dimensional vector of binary indices) = Voronoi index */ + Word16 x[], /* i : point in RE8 (8-dimensional integer vector) Q0*/ + Word16 *n, /* i : codebook number (*n is an integer defined in {0,2,3,4,..,n_max}) Q0*/ + UWord16 *I, /* o : index of c (pointer to unsigned 16-bit word) Q0*/ + Word16 k[] /* o : index of v (8-dimensional vector of binary indices) = Voronoi index Q0*/ ) { Word16 ka_fx, c_fx[8]; diff --git a/lib_enc/reordernorm.c b/lib_enc/reordernorm.c deleted file mode 100644 index 4922b9e4cac63a8b7e0bad323eeb65ac2b6706ba..0000000000000000000000000000000000000000 --- a/lib_enc/reordernorm.c +++ /dev/null @@ -1,42 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include "prot.h" -#include "cnst.h" -#include "rom_com.h" -#include "wmc_auto.h" diff --git a/lib_enc/reordernorm_fx.c b/lib_enc/reordernorm_fx.c index 40f12ffb8bec38ed8ecbc01a358e73bd0db34972..176b54f8e586150bc57f8f4e6f404d3c9724d994 100644 --- a/lib_enc/reordernorm_fx.c +++ b/lib_enc/reordernorm_fx.c @@ -7,7 +7,6 @@ #include "cnst.h" /* Common constants */ #include "rom_com_fx.h" #include "rom_com.h" -//#include "prot_fx.h" #include "prot_fx.h" /* Function prototypes */ #include "prot_fx_enc.h" /* Function prototypes */ @@ -32,25 +31,25 @@ void reordernorm_fx( SWITCH( nb_sfm ) { case NB_SFM: - order = norm_order_48; + order = norm_order_48; // Q0 BREAK; case SFM_N_SWB: - order = norm_order_32; + order = norm_order_32; // Q0 BREAK; case SFM_N_WB: - order = norm_order_16; + order = norm_order_16; // Q0 BREAK; default: - order = norm_order_48; + order = norm_order_48; // Q0 BREAK; } FOR( i = 0; i < nb_sfm; i++ ) { - idxbuf[i] = ynrm[order[i]]; + idxbuf[i] = ynrm[order[i]]; // Q0 move16(); move16(); - normbuf[i] = normqlg2[order[i]]; + normbuf[i] = normqlg2[order[i]]; // Q0 move16(); move16(); } diff --git a/lib_enc/rom_enc.c b/lib_enc/rom_enc.c index aabc7deefae8579778101ee7e4615ecdb18b95bd..abdb1249d12cdc3c9eb1ddb4e4640998de8fa641 100644 --- a/lib_enc/rom_enc.c +++ b/lib_enc/rom_enc.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other @@ -46,12 +46,12 @@ * VAD ROM tables *----------------------------------------------------------------------------------*/ -const int16_t hangover_hd_tbl[3] = {1, 1, 3}; -const int16_t hangover_sf_tbl[6] = {1, 3, 4, 1, 1, 2}; -const int16_t bwd_start_bin[BWD_N_BINS_MAX] = {1, 3, 6, 11}; -const int16_t bwd_end_bin[BWD_N_BINS_MAX] = {1, 4, 9, 12}; +const Word16 hangover_hd_tbl[3] = {1, 1, 3}; // Q0 +const Word16 hangover_sf_tbl[6] = {1, 3, 4, 1, 1, 2}; // Q0 +const Word16 bwd_start_bin[BWD_N_BINS_MAX] = {1, 3, 6, 11}; // Q0 +const Word16 bwd_end_bin[BWD_N_BINS_MAX] = {1, 4, 9, 12}; // Q0 -const int16_t BAND_NUM_TAB[5] = {10,10,20,40,60}; /* {OFFSET, NB, WB, SWB, FB} */ +const Word16 BAND_NUM_TAB[5] = {10,10,20,40,60}; /* {OFFSET, NB, WB, SWB, FB} Q0*/ typedef struct { Word16 r; @@ -76,16 +76,16 @@ const Word16 M_Wi_fix16[16] = 32609/* 9.9518473e-001f Q15 */,31356/* 9.5694034e-001f Q15 */,28898/* 8.8192126e-001f Q15 */,25329/* 7.7301045e-001f Q15 */,20787/* 6.3439328e-001f Q15 */,15446/* 4.7139674e-001f Q15 */, 9512/* 2.9028468e-001f Q15 */, 3212/* 9.8017140e-002f Q15 */ }; -const int16_t SP_CENTER_BAND_NUM_TAB[5] = {10, 10, 20, 24, 24}; +const Word16 SP_CENTER_BAND_NUM_TAB[5] = {10, 10, 20, 24, 24}; // Q0 /* 107374184.f = 32768.f * 32768.f * 0.1 */ -const int16_t NREGION_INDEX_NB[9] = {0,1,2,3,4,5,6,7, 9}; -const int16_t NREGION_INDEX_WB[13] = {0,1,2,3,4,5,6,8,10,12,16}; -const int16_t NREGION_INDEX_SWB[16] = {0,1,2,3,4,5,6,8,10,12,16,24,36}; -const int16_t NREGION_INDEX_FB[16] = {0,1,2,3,4,5,6,8,10,12,16,24,36}; +const Word16 NREGION_INDEX_NB[9] = {0,1,2,3,4,5,6,7, 9}; // Q0 +const Word16 NREGION_INDEX_WB[13] = {0,1,2,3,4,5,6,8,10,12,16}; // Q0 +const Word16 NREGION_INDEX_SWB[16] = {0,1,2,3,4,5,6,8,10,12,16,24,36}; // Q0 +const Word16 NREGION_INDEX_FB[16] = {0,1,2,3,4,5,6,8,10,12,16,24,36}; // Q0 const Word16 NREGION_PREOFF[12] = { 0,0,0,0,0,0,1,1,1,2,3,4 }; -const int16_t ENERGY_BAND_NUM[4] = {8,10,12,MAX_SUBBAND_NUM}; -const int16_t * const REGION_INDEX[4] = {NREGION_INDEX_NB, NREGION_INDEX_WB,NREGION_INDEX_SWB,NREGION_INDEX_FB}; +const Word16 ENERGY_BAND_NUM[4] = {8,10,12,MAX_SUBBAND_NUM}; // Q0 +const Word16 * const REGION_INDEX[4] = {NREGION_INDEX_NB, NREGION_INDEX_WB,NREGION_INDEX_SWB,NREGION_INDEX_FB}; // Q0 const Word32 MAX_LF_SNR_TAB_FX[5] = { 26843545/* 0.8 Q25 */,26843545/* 0.8 Q25 */,53687090/* 1.6 Q25 */,26843545/* 0.8 Q25 */,26843545/* 0.8 Q25 */ }; const Word32 COMVAD_INIT_SNR_DELTA_FX[5] = { 33554431/* 1.0 Q25 */, 20132659/* 0.6 Q25 */, 28856811/* 0.86 Q25 */, 38923139/* 1.16 Q25 */, 33554431/* 1.0 Q25 */ }; const Word32 LT_MIN_SILENCE_SNR_FX[4] = { 150994940/* 4.5 Q25 */, 150994940/* 4.5 Q25 */, 150994940/* 4.5 Q25 */,150994940/* 4.5 Q25 */ }; @@ -106,12 +106,12 @@ const Word16 sqrt_han_window_fx[L_FFT / 2 + 1] = 31785, 31880, 31971, 32057, 32137, 32213, 32285, 32351, 32412, 32469, 32521, 32567, 32609, 32646, 32678, 32705, 32728, 32745, 32757, 32765, 32767 -}; +}; // Q15 /*----------------------------------------------------------------------------------* * Starting points for pulse position search in Algebraic innovation codebook *----------------------------------------------------------------------------------*/ -const int16_t tipos[40] = +const Word16 tipos[40] = { 0, 1, 2, 3, /* starting point &ipos[0], 1st iter */ 1, 2, 3, 0, /* starting point &ipos[4], 2nd iter */ @@ -123,22 +123,22 @@ const int16_t tipos[40] = 3, 0, 1, 2, 0, 1, 2, 3, 1, 2, 3, 0 /* end point for 28 pulses &ipos[39], 4th iter */ -}; +}; // Q0 /*----------------------------------------------------------------------------------* * Open-loop pitch tables *----------------------------------------------------------------------------------*/ -const int16_t nb_sect_12k8[3] = { 4, 4, 4 }; -const int16_t nb_subsect_12k8[3] = { 7, 7, 7 }; -const int16_t pit_max_12k8[8] = { 11, 16, 21, 31, 40, 61, 77, 115}; +const Word16 nb_sect_12k8[3] = { 4, 4, 4 }; // Q0 +const Word16 nb_subsect_12k8[3] = { 7, 7, 7 }; // Q0 +const Word16 pit_max_12k8[8] = { 11, 16, 21, 31, 40, 61, 77, 115}; // Q0 -const int16_t len_12k8[4] = { 40, 40, 62, 115 }; -const int16_t len1_12k8[4] = { 40, 50, 80, 115 }; -const int16_t sublen_12k8[7] = { 40, 40, 40, 62, 62, 115, 115 }; -const int16_t sublen1_12k8[7] = { 40, 40, 50, 50, 80, 80, 115 }; -const int16_t sec_length_12k8[4] = { 7, 15, 30, 54 }; -const int16_t sec_length1_12k8[4] = { 10, 19, 37, 38 }; -const Word16 h_fir_fx[] = { 4260, 7536, 9175, 7536, 4260 }; +const Word16 len_12k8[4] = { 40, 40, 62, 115 }; // Q0 +const Word16 len1_12k8[4] = { 40, 50, 80, 115 }; // Q0 +const Word16 sublen_12k8[7] = { 40, 40, 40, 62, 62, 115, 115 }; // Q0 +const Word16 sublen1_12k8[7] = { 40, 40, 50, 50, 80, 80, 115 }; // Q0 +const Word16 sec_length_12k8[4] = { 7, 15, 30, 54 }; // Q0 +const Word16 sec_length1_12k8[4] = { 10, 19, 37, 38 }; // Q0 +const Word16 h_fir_fx[] = { 4260, 7536, 9175, 7536, 4260 }; // Q15 const Word16 W_HIST_FX[DTX_HIST_SIZE] = { 13107, 10486, 8389, 6711, 5369, 4295, 3436, 687 }; /* Q16 */ const Word16 W_HIST_S_FX[DTX_HIST_SIZE] = { 20480, 11378, 8393, 6938, 6092, 5551, 5183, 5115 }; /* Q12 */ @@ -148,32 +148,32 @@ const Word16 preemphCompensation_fx[NB_BANDS] = { 19960/*9.7461f Q11*/, 19493/* * LSF quantizer *----------------------------------------------------------------------------------*/ -const int16_t lsf_numlevels[TCXLPC_NUMSTAGES] = { 32, 16, 16 }; -const int16_t lsf_ind_numlevels[TCXLPC_IND_NUMSTAGES] = { 4 }; +const Word16 lsf_numlevels[TCXLPC_NUMSTAGES] = { 32, 16, 16 }; // Q0 +const Word16 lsf_ind_numlevels[TCXLPC_IND_NUMSTAGES] = { 4 }; // Q0 -const int16_t lsf_unified_fit_model_nb[4][16] = +const Word16 lsf_unified_fit_model_nb[4][16] = { {12506 , -17641 , -6444 , -6646 , -3523 , -2132 , -511 , -92 , 699 , 1062 , 2578 , 3564 , 3200 , -285 , 2928 , -250}, {20383 , 18855 , 8494 , 8062 , 8105 , 6211 , 5068 , 4408 , 3741 , 3458 , 2732 , 3174 , 2412 , 17421 , -21717 , 0}, {-717 , -617 , -144 , -117 , -229 , -144 , -141 , -98 , -92 , -69 , -51 , -87 , -37 , -3019 , 19864 , 8034}, {-2424 , 8999 , 5723 , 5629 , 4239 , 3423 , 2507 , 2019 , 1245 , 736 , -907 , -2237 , -2558 , -1979 , -652 , 1657} -}; +}; // Q0 -const int16_t lsf_unified_fit_model_wb[4][16] = +const Word16 lsf_unified_fit_model_wb[4][16] = { {8323 , -567 , 3402 , 1389 , 1437 , 1820 , 1407 , 1299 , 1292 , 1206 , 1031 , 928 , 898 , 832 , 840 , 681}, {24635 , 19605 , 9294 , 7407 , 6419 , 5459 , 4966 , 4189 , 3394 , 2964 , 2425 , 2110 , 2140 , 1972 , 1540 , 2252}, {-867 , -666 , -168 , -114 , -90 , -122 , -129 , -101 , -65 , -56 , -39 , -35 , -40 , -42 , -35 , -56}, {-2313 , 3035 , 1677 , 2854 , 2334 , 1232 , 1347 , 1034 , 863 , 707 , 886 , 891 , 432 , 357 , 206 , -310} -}; +}; // Q0 -const int16_t lsf_unified_fit_model_wbhb[4][16] = +const Word16 lsf_unified_fit_model_wbhb[4][16] = { {5312 , 1967 , 2914 , 1438 , 2595 , 1848 , 1980 , 2021 , 1535 , 1489 , 1651 , 1502 , 1447 , 1311 , 1353 , 1202}, {28135 , 16053 , 10129 , 7366 , 5898 , 5341 , 3290 , 2780 , 3146 , 2423 , 1613 , 1370 , 1294 , 1635 , 1105 , 1431}, {-615 , -308 , -147 , -119 , -104 , -105 , -30 , -28 , -50 , -39 , -15 , -14 , -14 , -21 , -19 , -29}, {1534 , 3569 , 3138 , 4023 , 2105 , 2023 , 2046 , 1264 , 1340 , 1067 , 780 , 547 , 188 , -540 , -722 , -479} -}; +}; // Q0 const Word32 Freq_Weight_Com_fx[160] = /*Q31 */ { 1073741824, 1351646720, 1610612736, 1832992000, 2003629568, 2110896768, 2147483647, 2147483647, @@ -240,7 +240,7 @@ const Word32 sm_means_fx[N_SMC_FEATURES] = { 114371648, 762918, 258533, 305622, 877131, 1071555, 1272603, 67350312, 1296274, -2461829, 1882791, -41135, -306269, 641721, 5859343, -}; +}; // Q20 const Word32 sm_scale_fx[N_SMC_FEATURES] = {//Q20 46789116, 166914, 66905, 70898, 117576, 108472, 96226, 17324576, @@ -257,12 +257,12 @@ const Word32 bcox_add_cnst_fx[N_SMC_FEATURES] = { 0, 0, -1886955264, -1559167616, 0, 0, 0, 0, -1672874752, 0, 0, 0, 0, 0, 0, -}; +}; // Q31 const Word32 bcox_lmbd_fx[N_SMC_FEATURES] = { 0, 0, -1426534784, -907320448, 0, 0, 0, 0, -1362524672, 0, 0, 0, 0, 0, 0, -}; +}; // Q31 const Word32 pca_mean_fx[N_SMC_FEATURES] = { 0, 0, 0, 0, 0, 0, 0, 0, @@ -310,13 +310,8 @@ const Word32 means_speech_fx[N_SMC_MIXTURES*N_PCA_COEF] = 401886, 142397, -185738, 101340, -281425, -159212, -106902, }; const Word32 log_det_chol_speech_fx[N_SMC_MIXTURES] = -{//Q19 - 3408173, - 3068506, - 2925146, - 3487906, - 2491427, - 2798882, +{//Q18 + 1704087, 1534253, 1462573, 1743953, 1245714, 1399441 }; const Word32 prec_chol_speech_fx[N_SMC_MIXTURES*(N_PCA_COEF*N_PCA_COEF + N_PCA_COEF) / 2] = { @@ -396,13 +391,8 @@ const Word32 means_music_fx[N_SMC_MIXTURES*N_PCA_COEF] = -254348, -119888, 187975, 89841, -1729, -280392, 30281, }; const Word32 log_det_chol_music_fx[N_SMC_MIXTURES] = -{//Q19 - 1696729, - 1843978, - 2975523, - 1507561, - -1171774, - 4174141, +{//Q18 + 848365, 921989, 1487762, 753781, -585887, 2087071, }; const Word32 prec_chol_music_fx[N_SMC_MIXTURES*(N_PCA_COEF*N_PCA_COEF + N_PCA_COEF) / 2] = { @@ -482,13 +472,8 @@ const Word32 means_noise_fx[N_SMC_MIXTURES*N_PCA_COEF] = -566101, 252900, 1677892, -314852, 1285163, 84872, -242426, }; const Word32 log_det_chol_noise_fx[N_SMC_MIXTURES] = -{//Q19 - 6227573, - 6829164, - 6727211, - 3722206, - 6943115, - 6238179, +{//Q18 + 3113787, 3414582, 3363606, 1861103, 3471558, 3119090 }; const Word32 prec_chol_noise_fx[N_SMC_MIXTURES*(N_PCA_COEF*N_PCA_COEF + N_PCA_COEF) / 2] = { @@ -828,15 +813,15 @@ const Word32 lvm_noise_fx[N_MIXTURES] = }; /* Mel filterbank */ -const int16_t mel_fb_start[NB_MEL_BANDS] = +const Word16 mel_fb_start[NB_MEL_BANDS] = { 1, 1, 2, 3, 4, 5, 5, 7, 8, 9, 10, 11, 13, 14, 16, 17, 19, 21, 23, 25, 28, 30, 33, 35, 38, 41, 45, 48, 52, 56, 60, 65, 69, 74, 80, 86, 92, 98, 105, 112 -}; +}; // Q0 -const int16_t mel_fb_len[NB_MEL_BANDS] = +const Word16 mel_fb_len[NB_MEL_BANDS] = { 1, 2, 2, 2, 1, 2, 3, 2, 2, 2, 3, 3, 3, 3, 3, 4, 4, 4, 5, 5, 5, 5, 5, 6, 7, 7, 7, 8, 8, 9, 9, 9, 11, 12, 12, 12, 13, 14, 15, 16 -}; +}; // Q0 const Word32 mel_fb_fx[246] = { 1306887040, 840596608, 701826176, 1445657472, 297866656, 1849617024, 67613584, 2079870080, @@ -870,7 +855,7 @@ const Word32 mel_fb_fx[246] = 1556051584, 1278092800, 1002327744, 728722176, 457242624, 187856208, 28791110, 311244128, 591432000, 869390912, 1145155968, 1418761472, 1690241024, 1959627392, 2068014592, 1802719104, 1539422848, 1278095872, 1018709056, 761233728, 505641920, 251906256, -}; +}; // Q30 const Word32 dct_mtx_fx[NB_MEL_BANDS * NB_MEL_COEF] = { //Q31 479821728, 476863456, 470965184, 462163232, 450511904, 436083040, 418965536, 399264992, @@ -987,61 +972,61 @@ const Word32 thren_pg_fx[44] = 3444, }; /* Huffmann coding - searching thresholds for quantization of peak gains */ -const int16_t huffnorm_e[32] = +const Word16 huffnorm_e[32] = { 1062, 550, 314, 274, 273, 272, 156, 79, 69, 38, 18, 40, 5, 3, 0, 1, 3, 4, 11, 21, 41, 32, 35, 67, 133, 264, 530, 315, 551, 2126, 4254, 4255 -}; +}; // Q0 -const int16_t huffnorm_n[32] = +const Word16 huffnorm_n[32] = { 14831, 14830, 7414, 3706, 593, 927, 462, 297, 230, 116, 50, 36, 13, 8, 5, 1, 0, 2, 6, 7, 15, 19, 24, 56, 59, 51, 114, 117, 75, 149, 592, 1852 -}; +}; // Q0 -const int16_t huffsizn_e[32] = +const Word16 huffsizn_e[32] = { 13, 12, 11, 11, 11, 11, 10, 9, 9, 8, 7, 6, 5, 4, 3, 2, 2, 3, 4, 5, 6, 8, 8, 9, 10, 11, 12, 11, 12, 14, 15, 15 -}; +}; // Q0 -const int16_t huffsizn_n[32] = +const Word16 huffsizn_n[32] = { 14, 14, 13, 12, 10, 10, 9, 9, 8, 7, 7, 6, 5, 4, 3, 3, 3, 3, 3, 4, 4, 5, 6, 6, 6, 7, 7, 7, 7, 8, 10, 11 -}; +}; // Q0 -const int16_t resize_huffnorm[32] = +const Word16 resize_huffnorm[32] = { 0, 0, 0, 0, 0, 1023, 511, 255, 127, 63, 31, 15, 7, 3, 1, 0, 2, 5, 11, 23, 47, 95, 191, 383, 767, 2047, 0, 0, 0, 0, 0, 0 -}; +}; // Q0 -const int16_t huffnorm[32] = +const Word16 huffnorm[32] = { 26, 58, 90, 122, 27, 59, 91, 123, 12, 28, 44, 60, 2, 6, 4, 6, 0, 2, 10, 14, 14, 30, 46, 62, 30, 62, 94, 126, 31, 63, 95, 127 -}; +}; // Q0 -const int16_t pgain_huffnorm[32] = +const Word16 pgain_huffnorm[32] = { 1, 1, 2, 3, 3, 2, 2, 2, 3, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 4, 5, 3, 2, 3, 3, 4, 5, 0, 1 -}; +}; // Q0 -const int16_t hessize[8]= +const Word16 hessize[8]= { 7, 5, 3, 2, 1, 4, 6, 7 -}; +}; // Q0 -const int16_t hescode[8]= +const Word16 hescode[8]= { 11, 3, 1, 1, 1, 0, 4, 10 -}; +}; // Q0 /*----------------------------------------------------------------------------------* * BWD @@ -1068,15 +1053,15 @@ const Word16 hann_window_320_fx[BWD_TOTAL_WIDTH / 2] = 7761, 7796, 7830, 7863, 7894, 7923, 7951, 7978, 8003, 8026, 8048, 8068, 8087, 8105, 8121, 8135, 8147, 8158, 8168, 8176, 8182, 8187, 8190, 8192 -}; +}; // Q13 /*----------------------------------------------------------------------------------* * Starting line for the noise measurement in TCX. *----------------------------------------------------------------------------------*/ -const int16_t startLineWB[N_TCX_STARTLINE_NOISE_WB] = { 8, 23, 36, 45, 66, 128 /* 13.2kbps */, 200, 320, 320, 320 /* 48kbps */, 320 }; +const Word16 startLineWB[N_TCX_STARTLINE_NOISE_WB] = { 8, 23, 36, 45, 66, 128 /* 13.2kbps */, 200, 320, 320, 320 /* 48kbps */, 320 }; // Q0 -const int16_t startLineSWB[N_TCX_STARTLINE_NOISE_SWB] = { 8, 44, 96 /* 13.2kbps */, 160, 320, 320, 256 /* 48kbps */, 341, 640 }; +const Word16 startLineSWB[N_TCX_STARTLINE_NOISE_SWB] = { 8, 44, 96 /* 13.2kbps */, 160, 320, 320, 256 /* 48kbps */, 341, 640 }; // Q0 const Word32 LS_MIN_SILENCE_SNR[4] = { 251658233/* 7.5 Q25 */, 251658233/* 7.5 Q25 */, 228170137/* 6.8 Q25 */,228170137/* 6.8 Q25 */ }; @@ -1096,7 +1081,7 @@ const UWord8 E_ROM_tipos[40] = 3, 0, 1, 2, 0, 1, 2, 3, /* end point for 24 pulses &ipos[35], 4th iter */ 1, 2, 3, 0 /* end point for 36 pulses &ipos[39], 2nd iter */ -}; +}; // Q0 /* pow(3 * i + 1, 0.3) / pow(256 - 1, 0.3) */ const Word16 Weight[86] = @@ -1109,7 +1094,7 @@ const Word16 Weight[86] = 0x7D61, 0x7DDA, 0x7E51, 0x7EC8, 0x7F3E, 0x7FB3, 0x7FFF }; -const Word16 BAND_SCALE_AJ[5] = { 3,3,5,6,6 }; /* {OFFSET, NB, WB, SWB, FB} */ +const Word16 BAND_SCALE_AJ[5] = { 3,3,5,6,6 }; /* {OFFSET, NB, WB, SWB, FB} Q0*/ /* Inv possible delta used in gaus_enc (1.0/(1.0+delta*delta)) and delta = [1,7] */ const Word16 inv_delta_tab[7] = /*Q15*/ @@ -1210,4 +1195,4 @@ const complex_16 wnk_table_16[16] = { /* integer square (i*i) */ const Word16 int_sqr[17] = { 0, 1, 4, 9, 16, 25, 36, 49, 64, 81, 100, 121, 144, 169, 196, 225, 256 -}; +}; // Q0 diff --git a/lib_enc/rom_enc.h b/lib_enc/rom_enc.h index 8479d5b4b296cf15d83c50212e6a6a48f0b0bc09..35fd3027d58538bd9b81b5120e1530337cbd9060 100644 --- a/lib_enc/rom_enc.h +++ b/lib_enc/rom_enc.h @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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,141 +45,141 @@ /*----------------------------------------------------------------------------------* * General tables *----------------------------------------------------------------------------------*/ -extern const Word16 sqrt_han_window_fx[]; /* Half of the square root hanning window */ -extern const int16_t tipos[]; /* Starting points for pulse position search in Algebraic innovation codebook */ -extern const Word16 W_HIST_FX[DTX_HIST_SIZE]; /* CNG & DTX - table for calculation of average excitation energy */ -extern const Word16 W_HIST_S_FX[DTX_HIST_SIZE]; /* CNG & DTX - table for calculation of average excitation energy */ +extern const Word16 sqrt_han_window_fx[]; /* Half of the square root hanning window Q15*/ +extern const Word16 tipos[]; /* Starting points for pulse position search in Algebraic innovation codebook Q0*/ +extern const Word16 W_HIST_FX[DTX_HIST_SIZE]; /* CNG & DTX - table for calculation of average excitation energy Q16*/ +extern const Word16 W_HIST_S_FX[DTX_HIST_SIZE]; /* CNG & DTX - table for calculation of average excitation energy Q12*/ -extern const int16_t bwd_start_bin[]; -extern const int16_t bwd_end_bin[]; -extern const float h_fir[]; /* 2nd order fir filter for wsp, decimation by 2 */ -extern const Word16 h_fir_fx[]; /* 2nd order fir filter for wsp, decimation by 2 */ -extern const Word16 preemphCompensation_fx[]; +extern const Word16 bwd_start_bin[]; // Q0 +extern const Word16 bwd_end_bin[]; // Q0 +extern const float h_fir[]; /* 2nd order fir filter for wsp, decimation by 2 */ +extern const Word16 h_fir_fx[]; /* 2nd order fir filter for wsp, decimation by 2 Q15*/ +extern const Word16 preemphCompensation_fx[]; // Q11 /*----------------------------------------------------------------------------------* * VAD tables *----------------------------------------------------------------------------------*/ -extern const int16_t hangover_hd_tbl[3]; -extern const int16_t hangover_sf_tbl[6]; +extern const Word16 hangover_hd_tbl[3]; // Q0 +extern const Word16 hangover_sf_tbl[6]; // Q0 /*----------------------------------------------------------------------------------* * Open-loop pitch search tables *----------------------------------------------------------------------------------*/ -extern const int16_t nb_sect_12k8[]; -extern const int16_t nb_subsect_12k8[]; -extern const int16_t len_12k8[]; -extern const int16_t len1_12k8[]; -extern const int16_t sublen_12k8[]; -extern const int16_t sublen1_12k8[]; -extern const int16_t pit_max_12k8[]; -extern const int16_t sec_length_12k8[]; -extern const int16_t sec_length1_12k8[]; +extern const Word16 nb_sect_12k8[]; // Q0 +extern const Word16 nb_subsect_12k8[]; // Q0 +extern const Word16 len_12k8[]; // Q0 +extern const Word16 len1_12k8[]; // Q0 +extern const Word16 sublen_12k8[]; // Q0 +extern const Word16 sublen1_12k8[]; // Q0 +extern const Word16 pit_max_12k8[]; // Q0 +extern const Word16 sec_length_12k8[]; // Q0 +extern const Word16 sec_length1_12k8[]; // Q0 /*----------------------------------------------------------------------------------* * LSF quantizer *----------------------------------------------------------------------------------*/ -extern const int16_t lsf_numlevels[TCXLPC_NUMSTAGES]; -extern const int16_t lsf_ind_numlevels[TCXLPC_IND_NUMSTAGES]; +extern const Word16 lsf_numlevels[TCXLPC_NUMSTAGES]; // Q0 +extern const Word16 lsf_ind_numlevels[TCXLPC_IND_NUMSTAGES]; // Q0 -extern const int16_t lsf_unified_fit_model_nb[4][16]; -extern const int16_t lsf_unified_fit_model_wb[4][16]; -extern const int16_t lsf_unified_fit_model_wbhb[4][16]; -extern const Word32 Freq_Weight_Com_fx[160]; -extern const Word32 Freq_Weight_UV_fx[160]; +extern const Word16 lsf_unified_fit_model_nb[4][16]; // Q0 +extern const Word16 lsf_unified_fit_model_wb[4][16]; // Q0 +extern const Word16 lsf_unified_fit_model_wbhb[4][16]; // Q0 +extern const Word32 Freq_Weight_Com_fx[160]; // Q31 +extern const Word32 Freq_Weight_UV_fx[160]; // Q31 /*----------------------------------------------------------------------------------* * Speech/music classification *----------------------------------------------------------------------------------*/ -extern const Word16 w_spmus_fx[HANG_LEN][HANG_LEN]; -extern const Word32 pca_components_fx[]; +extern const Word16 w_spmus_fx[HANG_LEN][HANG_LEN]; // Q15 +extern const Word32 pca_components_fx[]; // Q31 extern const Word32 pca_mean_fx[]; -extern const Word32 sm_means_fx[]; -extern const Word32 sm_scale_fx[]; -extern const Word32 bcox_lmbd_fx[N_SMC_FEATURES]; -extern const Word32 hout_intervals_fx[]; -extern const Word32 bcox_add_cnst_fx[N_SMC_FEATURES]; -extern const Word32 prec_chol_speech_fx[]; -extern const Word32 prec_chol_music_fx[]; -extern const Word32 prec_chol_noise_fx[]; -extern const Word32 means_speech_fx[]; // Q20 -extern const Word32 means_music_fx[]; // Q20 -extern const Word32 means_noise_fx[]; // Q20 -extern const Word32 mel_fb_fx[]; -extern const Word32 dct_mtx_fx[]; -extern const Word32 log_det_chol_speech_fx[]; // Q19 -extern const Word32 log_det_chol_music_fx[]; // Q19 -extern const Word32 log_det_chol_noise_fx[]; // Q19 -extern const Word16 m_speech_fx[]; -extern const Word32 invV_speech_fx[]; -extern const Word32 lvm_speech_fx[]; - -extern const Word32 prec_chol_speech_fx[]; -extern const Word32 prec_chol_music_fx[]; -extern const Word32 prec_chol_noise_fx[]; -extern const Word16 m_music_fx[]; -extern const Word32 invV_music_fx[]; -extern const Word32 lvm_music_fx[]; -extern const Word16 m_noise_fx[]; -extern const Word32 invV_noise_fx[]; -extern const Word32 lvm_noise_fx[]; - -extern const int16_t mel_fb_start[]; -extern const int16_t mel_fb_len[]; -extern const Word16 hann_window_320_fx[]; +extern const Word32 sm_means_fx[]; // Q20 +extern const Word32 sm_scale_fx[]; // Q20 +extern const Word32 bcox_lmbd_fx[N_SMC_FEATURES]; // Q31 +extern const Word32 hout_intervals_fx[]; // Q20 +extern const Word32 bcox_add_cnst_fx[N_SMC_FEATURES]; // Q31 +extern const Word32 prec_chol_speech_fx[]; // Q28 +extern const Word32 prec_chol_music_fx[]; // Q28 +extern const Word32 prec_chol_noise_fx[]; // Q28 +extern const Word32 means_speech_fx[]; // Q20 +extern const Word32 means_music_fx[]; // Q20 +extern const Word32 means_noise_fx[]; // Q20 +extern const Word32 mel_fb_fx[]; // Q30 +extern const Word32 dct_mtx_fx[]; // Q31 +extern const Word32 log_det_chol_speech_fx[]; // Q19 +extern const Word32 log_det_chol_music_fx[]; // Q19 +extern const Word32 log_det_chol_noise_fx[]; // Q19 +extern const Word16 m_speech_fx[]; // Q15 +extern const Word32 invV_speech_fx[]; // Q10 +extern const Word32 lvm_speech_fx[]; // Q10 + +extern const Word32 prec_chol_speech_fx[]; // Q28 +extern const Word32 prec_chol_music_fx[]; // Q28 +extern const Word32 prec_chol_noise_fx[]; // Q28 +extern const Word16 m_music_fx[]; // Q15 +extern const Word32 invV_music_fx[]; // Q10 +extern const Word32 lvm_music_fx[]; // Q10 +extern const Word16 m_noise_fx[]; // Q15 +extern const Word32 invV_noise_fx[]; // Q10 +extern const Word32 lvm_noise_fx[]; // Q10 + +extern const Word16 mel_fb_start[]; // Q0 +extern const Word16 mel_fb_len[]; // Q0 +extern const Word16 hann_window_320_fx[]; // Q13 /*----------------------------------------------------------------------------------* * Huffman coding *----------------------------------------------------------------------------------*/ -extern const int16_t huffsizn_e[32]; -extern const int16_t huffsizn_n[32]; +extern const Word16 huffsizn_e[32]; // Q0 +extern const Word16 huffsizn_n[32]; // Q0 -extern const int16_t huffnorm_e[32]; -extern const int16_t huffnorm_n[32]; -extern const int16_t hessize[8]; -extern const int16_t hescode[8]; +extern const Word16 huffnorm_e[32]; // Q0 +extern const Word16 huffnorm_n[32]; // Q0 +extern const Word16 hessize[8]; // Q0 +extern const Word16 hescode[8]; // Q0 /*----------------------------------------------------------------------------------* * VAD *----------------------------------------------------------------------------------*/ -extern const int16_t BAND_NUM_TAB[5]; +extern const Word16 BAND_NUM_TAB[5]; // Q0 extern const complex_16 M_in_fix16[16]; -extern const Word16 M_Wr_fix16[16]; -extern const Word16 M_Wi_fix16[16]; -extern const int16_t SP_CENTER_BAND_NUM_TAB[5]; -extern const int16_t NREGION_INDEX_NB[9]; -extern const int16_t NREGION_INDEX_WB[13]; -extern const int16_t NREGION_INDEX_SWB[16]; -extern const int16_t NREGION_INDEX_FB[16]; -extern const Word16 NREGION_PREOFF[16]; -extern const int16_t ENERGY_BAND_NUM[4]; -extern const int16_t *REGION_INDEX[4]; -extern const Word32 MAX_LF_SNR_TAB_FX[4]; -extern const Word32 COMVAD_INIT_SNR_DELTA_FX[5]; -extern const Word32 LT_MIN_SILENCE_SNR_FX[4]; +extern const Word16 M_Wr_fix16[16]; // Q15 +extern const Word16 M_Wi_fix16[16]; // Q15 +extern const Word16 SP_CENTER_BAND_NUM_TAB[5]; // Q0 +extern const Word16 NREGION_INDEX_NB[9]; // Q0 +extern const Word16 NREGION_INDEX_WB[13]; // Q0 +extern const Word16 NREGION_INDEX_SWB[16]; // Q0 +extern const Word16 NREGION_INDEX_FB[16]; // Q0 +extern const Word16 NREGION_PREOFF[16]; // Q0 +extern const Word16 ENERGY_BAND_NUM[4]; // Q0 +extern const Word16 *REGION_INDEX[4]; // Q0 +extern const Word32 MAX_LF_SNR_TAB_FX[4]; // Q25 +extern const Word32 COMVAD_INIT_SNR_DELTA_FX[5]; // Q25 +extern const Word32 LT_MIN_SILENCE_SNR_FX[4]; // Q25 /*----------------------------------------------------------------------------------* * Starting line for the noise measurement in TCX. *----------------------------------------------------------------------------------*/ -extern const int16_t startLineWB[N_TCX_STARTLINE_NOISE_WB]; -extern const int16_t startLineSWB[N_TCX_STARTLINE_NOISE_SWB]; +extern const Word16 startLineWB[N_TCX_STARTLINE_NOISE_WB]; // Q0 +extern const Word16 startLineSWB[N_TCX_STARTLINE_NOISE_SWB]; // Q0 // EVS basop -extern const Word32 LS_MIN_SILENCE_SNR[4]; -extern const Word16 SNR_SUB_BAND_NUM[4]; -extern const Word16 BAND_MUL[4]; +extern const Word32 LS_MIN_SILENCE_SNR[4]; // Q25 +extern const Word16 SNR_SUB_BAND_NUM[4]; // Q0 +extern const Word16 BAND_MUL[4]; // Q15 -extern const UWord8 E_ROM_tipos[]; /* ACELP indexing */ +extern const UWord8 E_ROM_tipos[]; /* ACELP indexing Q0*/ extern const Word16 Weight[86]; -extern const Word16 BAND_SCALE_AJ[5]; -extern const Word16 inv_delta_tab[7]; +extern const Word16 BAND_SCALE_AJ[5]; // Q0 +extern const Word16 inv_delta_tab[7]; // Q15 extern const Word16 i_t_1[10]; extern const Word16 i_t_2[23]; extern const Word16 SF_mult_fx[N_FEATURES]; diff --git a/lib_enc/rst_enc.c b/lib_enc/rst_enc.c deleted file mode 100644 index fd4f3cb7c53af6bc1a4a149c6db6799b8f39655e..0000000000000000000000000000000000000000 --- a/lib_enc/rst_enc.c +++ /dev/null @@ -1,42 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include "cnst.h" -#include "rom_com.h" -#include "prot.h" -#include "wmc_auto.h" diff --git a/lib_enc/rst_enc_fx.c b/lib_enc/rst_enc_fx.c index 85821ef0b028b6e360b6a57d40979f86ecd85985..d519bc12f9db4e464b977c66e13b329713fb216e 100644 --- a/lib_enc/rst_enc_fx.c +++ b/lib_enc/rst_enc_fx.c @@ -20,14 +20,15 @@ void CNG_reset_enc_fx( Encoder_State *st_fx, /* i/o: encoder state structure */ LPD_state_HANDLE hLPDmem, /* i/o: acelp memories */ - Word16 *pitch_buf, /* o : floating pitch for each subframe */ - Word16 *voice_factors, /* o : voicing factors */ - Word16 VBR_cng_reset_flag ) + Word16 *pitch_buf, /* o : floating pitch for each subframe Q6*/ + Word16 *voice_factors, /* o : voicing factors Q15*/ + Word16 VBR_cng_reset_flag /* Q0 */ +) { TD_CNG_ENC_HANDLE hTdCngEnc = st_fx->hTdCngEnc; init_gp_clip_fx( st_fx->clip_var_fx ); - Copy( UVWB_Ave_fx, st_fx->mem_AR_fx, M ); + Copy( UVWB_Ave_fx, st_fx->mem_AR_fx, M ); /* Qlog2(2.56) */ set16_fx( st_fx->mem_MA_fx, 0, M ); hLPDmem->mem_w0 = 0; move16(); diff --git a/lib_enc/scale_enc_fx.c b/lib_enc/scale_enc_fx.c index cfb3568bb669ed9fa5279c0f59236dfc84d98689..76eae22b7b1f21cc40f7593b1cf4e5fcff81da16 100644 --- a/lib_enc/scale_enc_fx.c +++ b/lib_enc/scale_enc_fx.c @@ -24,7 +24,7 @@ void Scale_wsp( Word16 *old_wsp, /* i/o: Old weighted speech buffer */ Word16 *mem_decim2, /* i/o: Decimation buffer */ Word16 *old_wsp12k8, /* i/o: wsp memory @ 12.8 kHz used in pitol2 */ - const Word16 Len_p_look /* i : L_frame + look ahead */ + const Word16 Len_p_look /* i : L_frame + look ahead Q0*/ ) { Word16 max, i, tmp; @@ -69,17 +69,17 @@ void Scale_wsp( * Find scaled preemphasis vector and its scaling factor *-------------------------------------------------------------------*/ void Preemph_scaled( - Word16 new_speech[], /* i : Speech to scale already on 14 bits*/ - Word16 *Q_new, /* o : Scaling factor */ - Word16 *mem_preemph, /* i/o: Preemph memory */ - Word16 *Q_max, /* i/o: Q_new limitation */ - const Word16 Preemph_factor, /* i : Preemphasis factor Q15 */ - const Word16 bits, /* i : Bit to remove from the output to (15-bits)*/ - const Word16 bit1, /* i : Limit the output scaling to ((15-bits)-bit1) bits */ - const Word16 L_Q_mem, /* i : Number of old scaling to take into account */ - const Word16 Lframe, /* i : Frame length */ - const Word16 last_coder_type, /* i : coder_type */ - const Word16 Search_scaling /* i : enable the search of a proper scaling factor*/ + Word16 new_speech[], /* i : Speech to scale already on 14 bits Q_new*/ + Word16 *Q_new, /* o : Scaling factor */ + Word16 *mem_preemph, /* i/o: Preemph memory Q(-1)*/ + Word16 *Q_max, /* i/o: Q_new limitation */ + const Word16 Preemph_factor, /* i : Preemphasis factor Q15*/ + const Word16 bits, /* i : Bit to remove from the output to (15-bits) */ + const Word16 bit1, /* i : Limit the output scaling to ((15-bits)-bit1) bits */ + const Word16 L_Q_mem, /* i : Number of old scaling to take into account Q0*/ + const Word16 Lframe, /* i : Frame length Q0*/ + const Word16 last_coder_type, /* i : coder_type Q0*/ + const Word16 Search_scaling /* i : enable the search of a proper scaling factor Q0*/ ) { Word16 i, tmp_fixed; @@ -88,6 +88,7 @@ void Preemph_scaled( Word16 Q_min; #ifdef BASOP_NOGLOB_DECLARE_LOCAL Flag Overflow = 0; + move32(); #endif /*---------------------------------------------------------------* @@ -96,12 +97,8 @@ void Preemph_scaled( *---------------------------------------------------------------*/ BASOP_SATURATE_WARNING_OFF_EVS -#ifdef BASOP_NOGLOB Overflow = 0; QVal = shl_o( 1, sub( 15, bits ), &Overflow ); -#else /* BASOP_NOGLOB */ - QVal = shl( 1, sub( 15, bits ) ); -#endif /* BASOP_NOGLOB */ BASOP_SATURATE_WARNING_ON_EVS mu = shr( Preemph_factor, bits ); /* Q15 --> Q(15-bits) */ @@ -110,11 +107,7 @@ void Preemph_scaled( /* get max of new preemphased samples (L_FRAME+L_FILT) */ L_tmp = L_mult( new_speech[0], QVal ); -#ifdef BASOP_NOGLOB L_tmp = L_msu_sat( L_tmp, *mem_preemph, mu ); -#else - L_tmp = L_msu( L_tmp, *mem_preemph, mu ); -#endif L_maxloc = L_abs( L_tmp ); FOR( i = 1; i < Lframe; i++ ) @@ -122,11 +115,7 @@ void Preemph_scaled( /* Equivalent to tmp = max((abs(x[i] - mu*x[i-1]),tmp) * finds the max of preemphasized signal */ L_tmp = L_mult( new_speech[i], QVal ); -#ifdef BASOP_NOGLOB L_tmp = L_msu_o( L_tmp, new_speech[i - 1], mu, &Overflow ); -#else /* BASOP_NOGLOB */ - L_tmp = L_msu( L_tmp, new_speech[i - 1], mu ); -#endif /* BASOP_NOGLOB */ L_tmp = L_abs( L_tmp ); L_maxloc = L_max( L_tmp, L_maxloc ); } @@ -170,35 +159,21 @@ void Preemph_scaled( * Done backwards to save storage space *---------------------------------------------------------------*/ - tmp_fixed = new_speech[Lframe - 1]; + tmp_fixed = new_speech[Lframe - 1]; // Q_new move16(); FOR( i = sub( Lframe, 1 ); i > 0; i-- ) { L_tmp = L_mult( new_speech[i], QVal ); -#ifdef BASOP_NOGLOB L_tmp = L_msu_o( L_tmp, new_speech[i - 1], mu, &Overflow ); -#else /* BASOP_NOGLOB */ - L_tmp = L_msu( L_tmp, new_speech[i - 1], mu ); -#endif /* BASOP_NOGLOB */ L_tmp = L_shl( L_tmp, *Q_new ); -#ifdef BASOP_NOGLOB - new_speech[i] = round_fx_sat( L_tmp ); -#else - new_speech[i] = round_fx( L_tmp ); -#endif + new_speech[i] = round_fx_sat( L_tmp ); // Q_new } L_tmp = L_mult( new_speech[0], QVal ); -#ifdef BASOP_NOGLOB L_tmp = L_msu_sat( L_tmp, *mem_preemph, mu ); L_tmp = L_shl_sat( L_tmp, *Q_new ); new_speech[0] = round_fx_sat( L_tmp ); -#else - L_tmp = L_msu( L_tmp, *mem_preemph, mu ); - L_tmp = L_shl( L_tmp, *Q_new ); - new_speech[0] = round_fx( L_tmp ); -#endif *mem_preemph = tmp_fixed; move16(); } @@ -208,17 +183,17 @@ void Preemph_scaled( * Rescale memories *-------------------------------------------------------------------*/ Word32 Scale_mem_pre_proc( /* o : Min energy scaled */ - Word16 ini_frame_fx, /* i : Frame number */ + Word16 ini_frame_fx, /* i : Frame number Q0*/ Word16 Q_exp, /* i : Diff scaling factor */ Word16 *Q_new, /* i/o: Absolute scaling factor */ Word16 *old_speech, /* i/o: Speech memory */ - Word16 *mem_wsp, /* i/o: wsp vector memory */ - Word32 *enrO, /* i/o: Enr mem */ - Word32 *bckr, /* i/o: Back ground_fx ener mem */ - Word32 *ave_enr, /* i/o: Ave_enr mem */ - Word32 *ave_enr2, /* i/o: Ave_enr2 mem */ - Word32 *st_fr_bands1, /* i/o: spectrum per critical bands of the previous frame */ - Word32 *st_fr_bands2, /* i/o: spectrum per critical bands 2 frames ago */ + Word16 *mem_wsp, /* i/o: wsp vector memory st->mem_wsp_q*/ + Word32 *enrO, /* i/o: Enr mem q_enrO*/ + Word32 *bckr, /* i/o: Back ground_fx ener mem q_bckr*/ + Word32 *ave_enr, /* i/o: Ave_enr mem Q_new + QSCALE*/ + Word32 *ave_enr2, /* i/o: Ave_enr2 mem Q_new + QSCALE*/ + Word32 *st_fr_bands1, /* i/o: spectrum per critical bands of the previous frame Q_new + QSCALE*/ + Word32 *st_fr_bands2, /* i/o: spectrum per critical bands 2 frames ago Q_new + QSCALE*/ Word32 *st_Bin_E_old ) { Word16 i; @@ -254,21 +229,12 @@ Word32 Scale_mem_pre_proc( /* o : Min energy scaled /* Do scaling and valide minimum energy value */ FOR( i = 0; i < NB_BANDS; i++ ) { -#ifdef BASOP_NOGLOB enrO[i] = L_max( L_shl_o( enrO[i], Q_exp, &Overflow ), e_min_scaled ); bckr[i] = L_max( L_shl_o( bckr[i], Q_exp, &Overflow ), e_min_scaled ); ave_enr[i] = L_max( L_shl_o( ave_enr[i], Q_exp, &Overflow ), e_min_scaled ); ave_enr2[i] = L_max( L_shl_o( ave_enr2[i], Q_exp, &Overflow ), e_min_scaled ); st_fr_bands1[i] = L_max( L_shl_o( st_fr_bands1[i], Q_exp, &Overflow ), e_min_scaled ); st_fr_bands2[i] = L_max( L_shl_o( st_fr_bands2[i], Q_exp, &Overflow ), e_min_scaled ); -#else - enrO[i] = L_max( L_shl( enrO[i], Q_exp ), e_min_scaled ); - bckr[i] = L_max( L_shl( bckr[i], Q_exp ), e_min_scaled ); - ave_enr[i] = L_max( L_shl( ave_enr[i], Q_exp ), e_min_scaled ); - ave_enr2[i] = L_max( L_shl( ave_enr2[i], Q_exp ), e_min_scaled ); - st_fr_bands1[i] = L_max( L_shl( st_fr_bands1[i], Q_exp ), e_min_scaled ); - st_fr_bands2[i] = L_max( L_shl( st_fr_bands2[i], Q_exp ), e_min_scaled ); -#endif move32(); move32(); move32(); diff --git a/lib_enc/set_impulse.c b/lib_enc/set_impulse.c deleted file mode 100644 index fd4f3cb7c53af6bc1a4a149c6db6799b8f39655e..0000000000000000000000000000000000000000 --- a/lib_enc/set_impulse.c +++ /dev/null @@ -1,42 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include "cnst.h" -#include "rom_com.h" -#include "prot.h" -#include "wmc_auto.h" diff --git a/lib_enc/set_impulse_fx.c b/lib_enc/set_impulse_fx.c index ebdfe868973b39312baa154696c596ea89192f0c..9ad5f4a2cdb9a4bab773a1008a6b70cb948771af 100644 --- a/lib_enc/set_impulse_fx.c +++ b/lib_enc/set_impulse_fx.c @@ -47,14 +47,14 @@ static void convolve_tc2_fx( const Word16 g[], const Word16 h[], Word16 y[], con * * *---------------------------------------------------------------------------------------*/ void set_impulse_fx( - const Word16 xn_fx[], /* i : target signal */ - const Word16 h_orig_fx[], /* i : impulse response of weighted synthesis filter */ - Word16 exc_fx[], /* o : adaptive codebook excitation */ - Word16 yy1_fx[], /* o : filtered adaptive codebook excitation */ - Word16 *imp_shape, /* o : adaptive codebook index */ - Word16 *imp_pos, /* o : position of the glottal impulse center index */ - Word32 *gain_trans_fx, /* o : transition gain Q7 */ - Word16 Q_new /* i : Current scaling */ + const Word16 xn_fx[], /* i : target signal Q_new-1+shift*/ + const Word16 h_orig_fx[], /* i : impulse response of weighted synthesis filter Q(14+shift)*/ + Word16 exc_fx[], /* o : adaptive codebook excitation Q_new*/ + Word16 yy1_fx[], /* o : filtered adaptive codebook excitation Q_new*/ + Word16 *imp_shape, /* o : adaptive codebook index Q0*/ + Word16 *imp_pos, /* o : position of the glottal impulse center index Q0*/ + Word32 *gain_trans_fx, /* o : transition gain Q7*/ + Word16 Q_new /* i : Current scaling */ ) { Word16 i, j, m; @@ -67,6 +67,7 @@ void set_impulse_fx( const Word16 *pt_Glt; #ifdef BASOP_NOGLOB_DECLARE_LOCAL Flag Overflow = 0; + move32(); #endif krit_max_fx = -32768; move16(); @@ -78,7 +79,7 @@ void set_impulse_fx( /* set searching ranges */ IF( LT_16( *imp_pos, L_SUBFR - INPOL ) ) { - end1 = add( *imp_pos, INPOL ); + end1 = add( *imp_pos, INPOL ); // Q0 } ELSE { @@ -87,7 +88,7 @@ void set_impulse_fx( } IF( GT_16( *imp_pos, INPOL ) ) { - start1 = sub( *imp_pos, INPOL ); + start1 = sub( *imp_pos, INPOL ); // Q0 } ELSE { @@ -118,21 +119,12 @@ void set_impulse_fx( /* nominator & DEnominator row <0> */ FOR( i = 0; i < L_SUBFR; i++ ) { -#ifdef BASOP_NOGLOB - Lrr = L_mac_o( Lrr, gh_fx[i], gh_fx[i], &Overflow ); - Ldd = L_mac_o( Ldd, gh_fx[i], xn_fx[i], &Overflow ); -#else - Lrr = L_mac( Lrr, gh_fx[i], gh_fx[i] ); - Ldd = L_mac( Ldd, gh_fx[i], xn_fx[i] ); -#endif + Lrr = L_mac_o( Lrr, gh_fx[i], gh_fx[i], &Overflow ); // Q27 + Ldd = L_mac_o( Ldd, gh_fx[i], xn_fx[i], &Overflow ); // Q27 } rr_fx[start1] = Lrr; move32(); -#ifdef BASOP_NOGLOB - dd_fx[start1] = round_fx_o( Ldd, &Overflow ); -#else - dd_fx[start1] = round_fx( Ldd ); -#endif + dd_fx[start1] = round_fx_o( Ldd, &Overflow ); // Q11 rr_fx[start1] = L_max( rr_fx[start1], 1 ); FOR( i = add( start1, 1 ); i < L_IMPULSE2; i++ ) @@ -144,28 +136,17 @@ void set_impulse_fx( { /* gh_fx[j] = gh_fx[j-1] + glottal_cdbk[m*L_IMPULSE+L_IMPULSE2-i]*h_orig_fx[j] */ gh_fx[j] = mac_r( L_deposit_h( gh_fx[j - 1] ), - Glottal_cdbk_fx[m * L_IMPULSE + L_IMPULSE2 - i], h_orig_fx[j] ); + Glottal_cdbk_fx[m * L_IMPULSE + L_IMPULSE2 - i], h_orig_fx[j] ); // Q13 move16(); -#ifdef BASOP_NOGLOB - Lrr = L_mac_o( Lrr, gh_fx[j], gh_fx[j], &Overflow ); - Ldd = L_mac_o( Ldd, gh_fx[j], xn_fx[j], &Overflow ); -#else /* BASOP_NOGLOB */ - Lrr = L_mac( Lrr, gh_fx[j], gh_fx[j] ); - Ldd = L_mac( Ldd, gh_fx[j], xn_fx[j] ); -#endif /* BASOP_NOGLOB */ + Lrr = L_mac_o( Lrr, gh_fx[j], gh_fx[j], &Overflow ); // Q27 + Ldd = L_mac_o( Ldd, gh_fx[j], xn_fx[j], &Overflow ); // Q27 } - gh_fx[0] = mult_r( Glottal_cdbk_fx[m * L_IMPULSE + L_IMPULSE2 - i], h_orig_fx[0] ); + gh_fx[0] = mult_r( Glottal_cdbk_fx[m * L_IMPULSE + L_IMPULSE2 - i], h_orig_fx[0] ); // Q13 move16(); -#ifdef BASOP_NOGLOB - Lrr = L_mac_o( Lrr, gh_fx[0], gh_fx[0], &Overflow ); - Ldd = L_mac_o( Ldd, gh_fx[0], xn_fx[0], &Overflow ); - dd_fx[i] = round_fx_sat( Ldd ); -#else /* BASOP_NOGLOB */ - Lrr = L_mac( Lrr, gh_fx[0], gh_fx[0] ); - Ldd = L_mac( Ldd, gh_fx[0], xn_fx[0] ); - dd_fx[i] = round_fx( Ldd ); -#endif + Lrr = L_mac_o( Lrr, gh_fx[0], gh_fx[0], &Overflow ); // Q27 + Ldd = L_mac_o( Ldd, gh_fx[0], xn_fx[0], &Overflow ); // Q27 + dd_fx[i] = round_fx_sat( Ldd ); // Q11 rr_fx[i] = L_max( Lrr, 1 ); move32(); /* move rr and dd into rr[i] and dd[i] */ @@ -175,7 +156,7 @@ void set_impulse_fx( FOR( j = L_SUBFR - 1; j > 0; j-- ) { gh_fx[j] = mac_r( L_deposit_h( gh_fx[j - 1] ), - Glottal_cdbk_fx[m * L_IMPULSE], h_orig_fx[j] ); + Glottal_cdbk_fx[m * L_IMPULSE], h_orig_fx[j] ); // Q13 } } ELSE @@ -186,15 +167,11 @@ void set_impulse_fx( IF( GE_16( end1, start2 ) ) { /* DEnominator row */ - Lrr = L_mult( gh_fx[0], gh_fx[0] ); + Lrr = L_mult( gh_fx[0], gh_fx[0] ); // Q27 FOR( j = 1; j <= L_IMPULSE2; j++ ) { /*rr[L_SUBFR-1] += gh[j]*gh[j];*/ -#ifdef BASOP_NOGLOB - Lrr = L_mac_sat( Lrr, gh_fx[j], gh_fx[j] ); -#else - Lrr = L_mac( Lrr, gh_fx[j], gh_fx[j] ); -#endif + Lrr = L_mac_sat( Lrr, gh_fx[j], gh_fx[j] ); // Q27 } rr_fx[L_SUBFR - 1] = Lrr; move32(); @@ -202,13 +179,8 @@ void set_impulse_fx( FOR( i = L_SUBFR - 2; i >= start2; i-- ) { /*rr[i] = rr[i+1] + gh[L_SUBFR+L_IMPULSE2-1-i]*gh[L_SUBFR+L_IMPULSE2-1-i];*/ -#ifdef BASOP_NOGLOB rr_fx[i] = L_mac_o( rr_fx[i + 1], gh_fx[L_SUBFR + L_IMPULSE2 - 1 - i], - gh_fx[L_SUBFR + L_IMPULSE2 - 1 - i], &Overflow ); -#else - rr_fx[i] = L_mac( rr_fx[i + 1], gh_fx[L_SUBFR + L_IMPULSE2 - 1 - i], - gh_fx[L_SUBFR + L_IMPULSE2 - 1 - i] ); -#endif + gh_fx[L_SUBFR + L_IMPULSE2 - 1 - i], &Overflow ); // Q27 move32(); } /* nominator rows */ @@ -229,15 +201,11 @@ void set_impulse_fx( den = extract_h( L_shl( rr_fx[i], exp_den ) ); num = div_s( num, den ); -#ifdef BASOP_NOGLOB krit_fx = shr_o( num, sub( sub( shl_o( exp_num, 1, &Overflow ), exp_den ), 2 ), &Overflow ); /* Q18 */ -#else - krit_fx = shr( num, sub( sub( shl( exp_num, 1 ), exp_den ), 2 ) ); /* Q18 */ -#endif IF( GT_16( krit_fx, krit_max_fx ) ) { - krit_max_fx = krit_fx; + krit_max_fx = krit_fx; // Q18 move16(); *imp_pos = i; move16(); @@ -254,7 +222,7 @@ void set_impulse_fx( set16_fx( exc_fx, 0, L_SUBFR ); set16_fx( yy1_fx, 0, L_SUBFR ); tmp16 = sub( extract_l( L_mac0( L_IMPULSE2, *imp_shape, L_IMPULSE ) ), *imp_pos ); - pt_Glt = &Glottal_cdbk_fx[tmp16]; + pt_Glt = &Glottal_cdbk_fx[tmp16]; // Q13 move16(); j = add( *imp_pos, L_IMPULSE2 ); FOR( i = sub( *imp_pos, L_IMPULSE2 ); i <= j; i++ ) @@ -290,9 +258,9 @@ void set_impulse_fx( gain16 = div_s( num, den ); i = add( exp_num, sub( Q_new, 1 + 1 + 3 ) ); - i = sub( i, exp_den ); /* Gain_trans in Q7 */ - gain16 = i_mult2( gain16, tmp16 ); /* apply sign */ - *gain_trans_fx = L_shr( L_deposit_l( gain16 ), i ); + i = sub( i, exp_den ); /* Gain_trans in Q7 */ + gain16 = i_mult2( gain16, tmp16 ); /* apply sign */ + *gain_trans_fx = L_shr( L_deposit_l( gain16 ), i ); // Q7 move32(); } /*-------------------------------------------------------------------* @@ -304,8 +272,8 @@ static void convolve_tc_fx( const Word16 g[], /* i : input vector Qx */ const Word16 h[], /* i : impulse response (or second input vector) Q15 */ Word16 y[], /* o : output vector (result of convolution) 12 bits */ - const Word16 L_1, /* i : vector h size */ - const Word16 L_2 /* i : vector g size */ + const Word16 L_1, /* i : vector h size Q0 */ + const Word16 L_2 /* i : vector g size Q0 */ ) { Word16 i, n, len; @@ -314,13 +282,13 @@ static void convolve_tc_fx( FOR( n = 0; n < L_2; n++ ) { len = s_min( add( n, 1 ), L_1 ); - L_sum = L_mult( g[0], h[n] ); + L_sum = L_mult( g[0], h[n] ); /* Qx */ FOR( i = 1; i < len; i++ ) { - L_sum = L_mac( L_sum, g[i], h[n - i] ); + L_sum = L_mac( L_sum, g[i], h[n - i] ); /* Qx + 16 */ } - y[n] = round_fx( L_sum ); /* Q12*/ + y[n] = round_fx( L_sum ); /* Qx */ } } /*-------------------------------------------------------------------* @@ -332,29 +300,29 @@ static void convolve_tc2_fx( const Word16 g[], /* i : input vector Qx */ const Word16 h[], /* i : impulse response (or second input vector) Q15 */ Word16 y[], /* o : output vector (result of convolution) 12 bits */ - const Word16 pos_max /* o : artificial impulse position */ + const Word16 pos_max /* o : artificial impulse position Q0 */ ) { Word32 temp; Word16 i, n; Word16 i_start, i_end, i_end2; - i_start = sub( pos_max, L_IMPULSE2 ); + i_start = sub( pos_max, L_IMPULSE2 ); // Q0 i_start = s_max( i_start, 0 ); - i_end = add( pos_max, L_IMPULSE ); + i_end = add( pos_max, L_IMPULSE ); // Q0 i_end = s_min( i_end, L_SUBFR ); FOR( n = i_start; n < L_SUBFR; n++ ) { - temp = L_mult( g[0], h[n] ); + temp = L_mult( g[0], h[n] ); /* Qx + 16 */ i_end2 = s_min( add( n, 1 ), i_end ); FOR( i = 1; i < i_end2; i++ ) { - temp = L_mac( temp, g[i], h[n - i] ); + temp = L_mac( temp, g[i], h[n - i] ); // Qx + 16 } - y[n] = round_fx( temp ); + y[n] = round_fx( temp ); // Qx } } /*-------------------------------------------------------------------* @@ -363,12 +331,12 @@ static void convolve_tc2_fx( * correlation for different vectors' lengths *-------------------------------------------------------------------*/ static void correlate_tc_fx( - const Word16 *x, /* i: target signal */ - Word16 *y, /* o: correlation between x[] and h[] -Q3 */ - const Word16 *h, /* i: impulse response (of weighted synthesis filter) */ - const Word16 start, /* i: index of iterest */ - const Word16 L_1, /* i: vector size */ - const Word16 L_2 /* i: index of interest */ + const Word16 *x, /* i: target signal Qx*/ + Word16 *y, /* o: correlation between x[] and h[] -Q3*/ + const Word16 *h, /* i: impulse response (of weighted synthesis filter) Q15*/ + const Word16 start, /* i: index of iterest Q0*/ + const Word16 L_1, /* i: vector size Q0*/ + const Word16 L_2 /* i: index of interest Q0*/ ) { Word16 i, j; @@ -379,16 +347,8 @@ static void correlate_tc_fx( s = L_deposit_l( 0 ); FOR( j = i; j < L_1; j++ ) { -#ifdef BASOP_NOGLOB - s = L_mac_sat( s, x[j], h[j - i] ); -#else - s = L_mac( s, x[j], h[j - i] ); -#endif + s = L_mac_sat( s, x[j], h[j - i] ); /* Qx + 16 */ } -#ifdef BASOP_NOGLOB - y[i] = round_fx_sat( s ); -#else - y[i] = round_fx( s ); -#endif + y[i] = round_fx_sat( s ); /* Qx */ } } diff --git a/lib_enc/setmodeindex.c b/lib_enc/setmodeindex.c deleted file mode 100644 index 8c2130280a4b05b2e28e395bc076bb63ed98778f..0000000000000000000000000000000000000000 --- a/lib_enc/setmodeindex.c +++ /dev/null @@ -1,97 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include "prot.h" -#include "cnst.h" -#include "ivas_cnst.h" -#include "wmc_auto.h" -#include "prot_fx.h" - -/*--------------------------------------------------------------------------- - - function name: SetModeIndex - description: function for configuring the codec between frames - currently bitrate and bandwidth only - must not be called while a frame is encoded - hence mutexes must be used in MT environments - - format: BANDWIDTH*16 + BITRATE (mode index) - - ---------------------------------------------------------------------------*/ - -void SetModeIndex_ivas_fx( - Encoder_State *st, /* i : Encoder state */ - const Word32 last_total_brate, /* i : last total bitrate */ - const Word16 last_element_mode, /* i : last IVAS element mode */ - const Word16 MCT_flag /* i : hMCT handle allocated (1) or not (0) */ -) -{ - Word16 ini_frame_loc = st->ini_frame; - move16(); - - test(); - test(); - IF( EQ_16( st->element_mode, IVAS_CPE_MDCT ) && NE_16( last_element_mode, IVAS_CPE_MDCT ) && EQ_16( st->idchan, 1 ) ) - { - st->ini_frame = 0; - move16(); - } - - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - /* Reconfigure the core coder */ - IF( ( NE_32( last_total_brate, st->total_brate ) ) || - ( NE_16( st->last_bwidth, st->bwidth ) ) || - ( EQ_16( st->last_codec_mode, MODE1 ) && EQ_16( st->element_mode, EVS_MONO ) ) || - ( ( NE_16( st->last_core, TCX_20_CORE ) && NE_16( st->last_core, TCX_10_CORE ) ) && GT_16( st->element_mode, EVS_MONO ) ) || - ( NE_16( st->rf_mode_last, st->rf_mode ) ) || - ( GT_16( st->element_mode, EVS_MONO ) && st->ini_frame == 0 ) ) - { - core_coder_mode_switch_ivas_fx( st, last_total_brate, MCT_flag ); - } - - st->ini_frame = ini_frame_loc; - move16(); - - return; -} diff --git a/lib_enc/setmodeindex_fx.c b/lib_enc/setmodeindex_fx.c index dff13ec8964ba2be52e6649edb3e78c08ff5fdfa..012c5757f2b9ea041c5bb4541e580f11fd27e656 100644 --- a/lib_enc/setmodeindex_fx.c +++ b/lib_enc/setmodeindex_fx.c @@ -4,7 +4,6 @@ #include #include "options.h" -//#include "prot_fx.h" #include "cnst.h" #include "rom_com_fx.h" #include "rom_enc.h" @@ -23,12 +22,12 @@ void SetModeIndex_fx( Encoder_State *st, - Word32 last_total_brate, - const Word16 last_element_mode, - const Word16 is_mct, + Word32 last_total_brate, /* Q0 */ + const Word16 last_element_mode, /* Q0 */ + const Word16 is_mct, /* Q0 */ const Word16 shift ) { - Word16 ini_frame_loc = st->ini_frame; + Word16 ini_frame_loc = st->ini_frame; // Q0 test(); test(); @@ -52,7 +51,52 @@ void SetModeIndex_fx( { core_coder_mode_switch_fx( st, last_total_brate, is_mct, shift ); } - st->ini_frame = ini_frame_loc; + st->ini_frame = ini_frame_loc; // Q0 + + return; +} + + +void SetModeIndex_ivas_fx( + Encoder_State *st, /* i : Encoder state */ + const Word32 last_total_brate, /* i : last total bitrate Q0*/ + const Word16 last_element_mode, /* i : last IVAS element mode Q0*/ + const Word16 MCT_flag /* i : hMCT handle allocated (1) or not (0) Q0*/ +) +{ + Word16 ini_frame_loc = st->ini_frame; // Q0 + move16(); + + test(); + test(); + IF( EQ_16( st->element_mode, IVAS_CPE_MDCT ) && NE_16( last_element_mode, IVAS_CPE_MDCT ) && EQ_16( st->idchan, 1 ) ) + { + st->ini_frame = 0; + move16(); + } + + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + /* Reconfigure the core coder */ + IF( ( NE_32( last_total_brate, st->total_brate ) ) || + ( NE_16( st->last_bwidth, st->bwidth ) ) || + ( EQ_16( st->last_codec_mode, MODE1 ) && EQ_16( st->element_mode, EVS_MONO ) ) || + ( ( NE_16( st->last_core, TCX_20_CORE ) && NE_16( st->last_core, TCX_10_CORE ) ) && GT_16( st->element_mode, EVS_MONO ) ) || + ( NE_16( st->rf_mode_last, st->rf_mode ) ) || + ( st->element_mode > EVS_MONO && st->ini_frame == 0 ) ) + { + core_coder_mode_switch_ivas_fx( st, last_total_brate, MCT_flag ); + } + + st->ini_frame = ini_frame_loc; // Q0 + move16(); return; } diff --git a/lib_enc/sig_clas.c b/lib_enc/sig_clas.c deleted file mode 100644 index 0828accec986944779b557c4d45118d355476c85..0000000000000000000000000000000000000000 --- a/lib_enc/sig_clas.c +++ /dev/null @@ -1,59 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include -#include "cnst.h" -#include "prot.h" -#include "wmc_auto.h" - -/*---------------------------------------------------------------------* - * Local constants - *---------------------------------------------------------------------*/ - -#define K_COR_ENC 2.857f -#define C_COR_ENC -1.286f -#define K_EE_ENC 0.04167f -#define C_EE_ENC 0.0f -#define K_ZC_ENC -0.04f -#define C_ZC_ENC 2.4f -#define K_RELE_ENC 0.05f -#define C_RELE_ENC 0.45f -#define K_PC_ENC -0.07143f -#define C_PC_ENC 1.857f -#define K_SNR_ENC 0.1111f -#define C_SNR_ENC -0.3333f diff --git a/lib_enc/sig_clas_fx.c b/lib_enc/sig_clas_fx.c index 501f907b60aa73eb2126df1d8cdedee46325b026..cf5d31d22001c277a70040332e8c73383e4be02a 100644 --- a/lib_enc/sig_clas_fx.c +++ b/lib_enc/sig_clas_fx.c @@ -44,9 +44,9 @@ Word16 signal_clas_fx( /* o : classification for current frames */ Encoder_State *st, /* i/o: encoder state structure */ - const Word16 *speech, /* i : pointer to speech signal for E computation */ - const Word32 *ee, /* i : lf/hf E ration for 2 half-frames */ - const Word16 relE, /* i : frame relative E to the long term average */ + const Word16 *speech, /* i : pointer to speech signal for E computation in Qx */ + const Word32 *ee, /* i : lf/hf E ration for 2 half-frames in Q6 */ + const Word16 relE, /* i : frame relative E to the long term average in Q8 */ const Word16 L_look, /* i : look-ahead */ Word16 *clas_mod /* o : class flag for NOOP detection */ ) @@ -58,6 +58,7 @@ Word16 signal_clas_fx( /* o : classification for current const Word16 *pt1; #ifdef BASOP_NOGLOB_DECLARE_LOCAL Flag Overflow = 0; + move32(); #endif /*----------------------------------------------------------------* @@ -68,7 +69,7 @@ Word16 signal_clas_fx( /* o : classification for current *----------------------------------------------------------------*/ /* average voicing on second half-frame and look-ahead */ - Ltmp = L_mult( st->voicing_fx[1], 16384 ); + Ltmp = L_mult( st->voicing_fx[1], 16384 ); /* Q15*Q14->Q30 */ mean_voi2 = mac_r( Ltmp, st->voicing_fx[2], 16384 ); /* average spectral tilt in dB */ @@ -101,7 +102,7 @@ Word16 signal_clas_fx( /* o : classification for current } /* compute zero crossing rate */ - pt1 = speech + L_look - 1; + pt1 = speech + sub( L_look, 1 ); tmpS = shr( *pt1, 15 ); /* sets 'tmpS to -1 if *pt1 < 0 */ Ltmp = L_deposit_l( 0 ); FOR( i = 0; i < L_FRAME; i++ ) @@ -116,7 +117,7 @@ Word16 signal_clas_fx( /* o : classification for current /* compute pitch stability */ pc = add( abs_s( sub( st->pitch[1], st->pitch[0] ) ), abs_s( sub( st->pitch[2], st->pitch[1] ) ) ); st->tdm_pc = pc; - + move16(); /*-----------------------------------------------------------------* * Transform parameters to the range <0:1> * Compute the merit function @@ -135,7 +136,7 @@ Word16 signal_clas_fx( /* o : classification for current zcn = s_max( zcn, 0 ); zcn = s_min( zcn, 512 ); - Ltmp = L_mult( C_RELE_FX, 256 ); /*Q15 ->Q24*/ + Ltmp = L_mult( C_RELE_FX, 256 ); /*Q15*Q8 ->Q24*/ relEn = round_fx( L_shl( L_mac( Ltmp, relE, K_RELE_FX ), 1 ) ); /*relE in Q8 but relEn in Q9*/ /* Limit [0.5, 1] */ relEn = s_max( relEn, 256 ); @@ -153,17 +154,14 @@ Word16 signal_clas_fx( /* o : classification for current Ltmp = L_mac( Ltmp, relEn, 10923 ); Ltmp = L_mac( Ltmp, pcn, 10923 ); -#ifdef BASOP_NOGLOB fmerit1 = round_fx_o( L_shl_o( Ltmp, 16 - 10 - 1, &Overflow ), &Overflow ); /* fmerit1 ->Q15 */ -#else - fmerit1 = round_fx( L_shl( Ltmp, 16 - 10 - 1 ) ); /* fmerit1 ->Q15 */ -#endif /*-----------------------------------------------------------------* * FEC classification *-----------------------------------------------------------------*/ - st->fmerit_dt = sub( st->prev_fmerit, fmerit1 ); + st->fmerit_dt = sub( st->prev_fmerit, fmerit1 ); /*Q15*/ + move16(); st->prev_fmerit = fmerit1; move16(); @@ -254,14 +252,14 @@ Word16 signal_clas_fx( /* o : classification for current /* tc_cnt == 1: onset/transition frame, coded by GC coder type */ /* tc_cnt == 2: frame after onset/transition frame, coded by TC coder type */ - if ( EQ_16( clas, UNVOICED_CLAS ) ) + if ( clas == 0 ) { st->tc_cnt = 0; move16(); } test(); - if ( GE_16( clas, VOICED_TRANSITION ) && st->tc_cnt >= 0 ) + IF( GE_16( clas, VOICED_TRANSITION ) && st->tc_cnt >= 0 ) { st->tc_cnt = add( st->tc_cnt, 1 ); move16(); @@ -323,7 +321,7 @@ void select_TC_fx( void coder_type_modif_fx( Encoder_State *st, /* i/o: encoder state structure */ - const Word16 relE /* i : frame relative E to the long term average */ + const Word16 relE /* i : frame relative E to the long term average Q8*/ ) { Word16 unmod_coder_type, vbr_generic_ho; @@ -354,8 +352,12 @@ void coder_type_modif_fx( /* At higher rates, use GC coding instead of UC coding to improve quality */ test(); - if ( ( EQ_16( st->element_mode, EVS_MONO ) && GT_32( st->total_brate, ACELP_9k60 ) && EQ_16( st->coder_type, UNVOICED ) ) || - ( GT_16( st->element_mode, EVS_MONO ) && GT_32( st->total_brate, MAX_UNVOICED_BRATE ) && EQ_16( st->coder_type, UNVOICED ) ) ) + test(); + test(); + test(); + test(); + if ( ( st->element_mode == 0 && GT_32( st->total_brate, ACELP_9k60 ) && EQ_16( st->coder_type, UNVOICED ) ) || + ( st->element_mode > 0 && GT_32( st->total_brate, MAX_UNVOICED_BRATE ) && EQ_16( st->coder_type, UNVOICED ) ) ) { st->coder_type = GENERIC; move16(); @@ -395,13 +397,13 @@ void coder_type_modif_fx( test(); IF( EQ_16( st->Opt_SC_VBR, 1 ) ) { + test(); if ( EQ_16( st->coder_type, GENERIC ) && EQ_16( unmod_coder_type, UNVOICED ) ) { hSC_VBR->vbr_generic_ho = 1; move16(); } - test(); if ( GT_16( st->coder_type, UNVOICED ) ) { hSC_VBR->vbr_generic_ho = 0; @@ -419,12 +421,12 @@ void coder_type_modif_fx( } //} closing bracket here in IVAS float, but not in EVS float. currently affects BE for switching bitrate on Linux 20220929 _DIFF_FLOAT_FIX_ !! - IF( EQ_16( st->element_mode, EVS_MONO ) ) + IF( st->element_mode == 0 ) { /* At higher rates and with 16kHz core, allow only GC and TC coder type */ test(); test(); - test(); + // test(); if ( GT_32( st->total_brate, ACELP_16k40 ) && NE_16( st->coder_type, GENERIC ) && NE_16( st->coder_type, TRANSITION ) ) { /* onset/transition frame is always coded using GC mode */ @@ -435,6 +437,9 @@ void coder_type_modif_fx( ELSE /*IVAS*/ { /* At higher bitrates, disable UC and VC coder type; note that IC coder type is classified later */ + test(); + test(); + test(); if ( ( GT_32( st->total_brate, MAX_VOICED_BRATE ) && EQ_16( st->coder_type, VOICED ) ) || ( GT_32( st->total_brate, MAX_UNVOICED_BRATE ) && EQ_16( st->coder_type, UNVOICED ) ) ) { @@ -447,7 +452,7 @@ void coder_type_modif_fx( test(); test(); test(); - if ( EQ_16( st->coder_type, VOICED ) && EQ_16( st->input_bwidth, NB ) && LT_16( relE, -2560 ) && LE_32( st->total_brate, ACELP_8k00 ) ) + if ( EQ_16( st->coder_type, VOICED ) && st->input_bwidth == 0 && LT_16( relE, -2560 ) && LE_32( st->total_brate, ACELP_8k00 ) ) { st->coder_type = GENERIC; move16(); @@ -493,8 +498,8 @@ void coder_type_modif_ivas_fx( test(); test(); test(); - if ( ( EQ_16( st->element_mode, EVS_MONO ) && GT_32( st->total_brate, ACELP_9k60 ) && EQ_16( st->coder_type, UNVOICED ) ) || - ( GT_16( st->element_mode, EVS_MONO ) && GT_32( st->total_brate, MAX_UNVOICED_BRATE ) && EQ_16( st->coder_type, UNVOICED ) ) ) + if ( ( st->element_mode == 0 && GT_32( st->total_brate, ACELP_9k60 ) && EQ_16( st->coder_type, UNVOICED ) ) || + ( st->element_mode > 0 && GT_32( st->total_brate, MAX_UNVOICED_BRATE ) && EQ_16( st->coder_type, UNVOICED ) ) ) { st->coder_type = GENERIC; move16(); @@ -530,7 +535,7 @@ void coder_type_modif_ivas_fx( move16(); } - IF( EQ_16( st->Opt_SC_VBR, 1 ) ) + if ( EQ_16( st->Opt_SC_VBR, 1 ) ) { test(); if ( EQ_16( st->coder_type, GENERIC ) && EQ_16( unmod_coder_type, UNVOICED ) ) @@ -555,7 +560,7 @@ void coder_type_modif_ivas_fx( } } - IF( EQ_16( st->element_mode, EVS_MONO ) ) + IF( st->element_mode == 0 ) { /* At higher rates and with 16kHz core, allow only GC and TC coder type */ test(); diff --git a/lib_enc/spec_center.c b/lib_enc/spec_center.c deleted file mode 100644 index 5cd8e2875deb519346d7148c847ad9a672078b2a..0000000000000000000000000000000000000000 --- a/lib_enc/spec_center.c +++ /dev/null @@ -1,42 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include "prot.h" -#include "rom_enc.h" -#include "cnst.h" -#include "wmc_auto.h" diff --git a/lib_enc/spec_center_fx.c b/lib_enc/spec_center_fx.c index 920da568d721927e05f5e795583fbd17c7efefc4..1e908d0c388682b49e1d71d6807d6deb2e3be89e 100644 --- a/lib_enc/spec_center_fx.c +++ b/lib_enc/spec_center_fx.c @@ -18,9 +18,9 @@ *-------------------------------------------------------------------*/ void spec_center_fx( - Word32 *sb_power, /* i : energy of sub-band divided uniformly*/ - Word16 *sp_center, /* o : spectral center*/ - const Word32 bw_index, /* i : band width*/ + Word32 *sb_power, /* i : energy of sub-band divided uniformly Q31 */ + Word16 *sp_center, /* o : spectral center Q10 */ + const Word32 bw_index, /* i : band width Q0 */ const Word16 Q_sb_p /* i : the Scaling of sb_power*/ ) { @@ -48,15 +48,15 @@ void spec_center_fx( FOR( i = 0; i < 10; i++ ) { - sb_power_shr[i] = L_shr( sb_power[i], 5 ); + sb_power_shr[i] = L_shr( sb_power[i], 5 ); /* Q26 */ move32(); } FOR( i = 0; i < 10; i++ ) { - sb_power_mlt = Mpy_32_16_1( sb_power[i], i_t_1[i] ); - t_sp_center = L_add( L_shr( sb_power_mlt, 6 ), t_sp_center ); - frame_power = L_add( sb_power_shr[i], frame_power ); /*0-9 */ + sb_power_mlt = Mpy_32_16_1( sb_power[i], i_t_1[i] ); /* Q16 + QB */ + t_sp_center = L_add( L_shr( sb_power_mlt, 6 ), t_sp_center ); /* Q11 + QB */ + frame_power = L_add( sb_power_shr[i], frame_power ); /*0-9 */ /* Q26 */ } t_sp_center_nb = t_sp_center; @@ -68,16 +68,17 @@ void spec_center_fx( Q_t_sc = sub( Q_sb_p, 10 ); IF( GE_16( Q_t_sc, 34 ) ) { - t_sp_center = L_shr( t_sp_center, sub( Q_t_sc, 33 ) ); - zerop1 = L_shr( CNT0P1, 1 ); + t_sp_center = L_shr( t_sp_center, sub( Q_t_sc, 33 ) ); /* Q44 + QB - Q_t_sc)*/ + zerop1 = CNT0P1 >> 1; /* Q33 */ + move32(); Q_t_sc = 33; move16(); } ELSE { - Q_t_sc = sub( Q_t_sc, 1 ); - t_sp_center = L_shr( t_sp_center, 1 ); - zerop1 = L_shr( CNT0P1, sub( 34, Q_t_sc ) ); + Q_t_sc = sub( Q_t_sc, 1 ); /* Q_t_sc - 1 */ + t_sp_center = L_shr( t_sp_center, 1 ); /* Q10 + QB */ + zerop1 = L_shr( CNT0P1, sub( 34, Q_t_sc ) ); /* Q_t_sc */ } t_sp_center_num = L_add( t_sp_center, zerop1 ); @@ -85,7 +86,8 @@ void spec_center_fx( IF( GE_16( Q_f_p, 34 ) ) { frame_power = L_shr( frame_power, sub( Q_f_p, 33 ) ); - zerop1 = L_shr( CNT0P1, 1 ); + zerop1 = ( CNT0P1 >> 1 ); + move32(); Q_f_p = 33; move16(); } @@ -120,9 +122,9 @@ void spec_center_fx( d_t_sp_center = shr( d_t_sp_center, d_t_sp_center_Qtmp ); sp_center[0] = add( mult( sp_center[0], 0x5999 ), mult( d_t_sp_center, 0x2666 ) ); - move16(); sp_center[2] = d_t_sp_center; move16(); + move16(); t_sp_center = 0; move32(); @@ -148,7 +150,8 @@ void spec_center_fx( IF( GE_16( Q_t_sc, 34 ) ) { t_sp_center = L_shr( t_sp_center, sub( Q_t_sc, 33 ) ); - zerop1 = L_shr( CNT0P1, 1 ); + zerop1 = ( CNT0P1 >> 1 ); + move32(); Q_t_sc = 33; move16(); } @@ -221,7 +224,8 @@ void spec_center_fx( IF( GE_16( Q_t_sc, 34 ) ) { t_sp_center = L_shr( t_sp_center, limitScale32( sub( Q_t_sc, 33 ) ) ); - zerop1 = L_shr( CNT0P1, 1 ); + zerop1 = ( CNT0P1 >> 1 ); + move32(); Q_t_sc = 33; move16(); } @@ -237,7 +241,8 @@ void spec_center_fx( IF( GE_16( Q_f_p, 34 ) ) { frame_power = L_shr( frame_power, sub( Q_f_p, 33 ) ); - zerop1 = L_shr( CNT0P1, 1 ); + zerop1 = ( CNT0P1 >> 1 ); + move32(); Q_f_p = 33; move16(); } diff --git a/lib_enc/spec_flatness.c b/lib_enc/spec_flatness.c deleted file mode 100644 index 68731d8f1702d45c4fc58916c47fef083afa1903..0000000000000000000000000000000000000000 --- a/lib_enc/spec_flatness.c +++ /dev/null @@ -1,42 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include -#include "options.h" -#include -#include "prot.h" -#include "wmc_auto.h" diff --git a/lib_enc/spec_flatness_fx.c b/lib_enc/spec_flatness_fx.c index 2ee10bf068b1469a7a2e455367b9d106b52b8123..c2451886dac977208e677dc5ca833459b53afa5e 100644 --- a/lib_enc/spec_flatness_fx.c +++ b/lib_enc/spec_flatness_fx.c @@ -104,7 +104,8 @@ void spec_flatness_fx( IF( GE_16( prods_Q, 34 ) ) { prods = L_shr( prods, sub( prods_Q, 33 ) ); - zerop1 = L_shr( CNT0P1, 1 ); + zerop1 = CNT0P1 >> 1; + move32(); prods_Q = 33; move16(); } @@ -116,7 +117,8 @@ void spec_flatness_fx( } prods = L_add( prods, zerop1 ); - zerop1 = L_shr( CNT0P1, 20 ); + zerop1 = CNT0P1 >> 20; + move32(); sums = L_add( sums, zerop1 ); /*div*/ @@ -188,7 +190,8 @@ void spec_flatness_fx( IF( GE_16( prods_Q, 34 ) ) { prods = L_shr( prods, sub( prods_Q, 33 ) ); - zerop1 = L_shr( CNT0P1, 1 ); + zerop1 = CNT0P1 >> 1; + move32(); prods_Q = 33; move16(); } @@ -200,7 +203,8 @@ void spec_flatness_fx( } prods = L_add( prods, zerop1 ); - zerop1 = L_shr( CNT0P1, 20 ); + zerop1 = CNT0P1 >> 20; + move32(); sums = L_add( sums, zerop1 ); /*div*/ @@ -217,7 +221,12 @@ void spec_flatness_fx( SFM_Qtmp = sub( SFM_Qtmp, SPEC_AMP_Q ); SFM_Qtmp = sub( SFM_Qtmp, SFM_Q ); +#ifdef FIX_ISSUE_1209 + sSFM[1] = add_sat( mult( sSFM[1], 0x6ccc ), shr( mult( SFM, 0x1333 ), SFM_Qtmp ) ); +#else sSFM[1] = add( mult( sSFM[1], 0x6ccc ), shr( mult( SFM, 0x1333 ), SFM_Qtmp ) ); +#endif + move16(); /*sSFM3*/ sums = 0; @@ -271,7 +280,8 @@ void spec_flatness_fx( IF( GE_16( prods_Q, 34 ) ) { prods = L_shr( prods, sub( prods_Q, 33 ) ); - zerop1 = L_shr( CNT0P1, 1 ); + zerop1 = CNT0P1 >> 1; + move32(); prods_Q = 33; move16(); } @@ -283,7 +293,8 @@ void spec_flatness_fx( } prods = L_add( prods, zerop1 ); - zerop1 = L_shr( CNT0P1, 20 ); + zerop1 = CNT0P1 >> 20; + move32(); sums = L_add( sums, zerop1 ); /*div*/ @@ -300,10 +311,6 @@ void spec_flatness_fx( SFM_Qtmp = sub( SFM_Qtmp, SPEC_AMP_Q ); SFM_Qtmp = sub( SFM_Qtmp, SFM_Q ); -#ifdef BASOP_NOGLOB sSFM[2] = add_sat( mult( sSFM[2], 0x6ccc ), shr_sat( mult( SFM, 0x1333 ), SFM_Qtmp ) ); -#else - sSFM[2] = add( mult( sSFM[2], 0x6ccc ), shr( mult( SFM, 0x1333 ), SFM_Qtmp ) ); -#endif move16(); } diff --git a/lib_enc/speech_music_classif.c b/lib_enc/speech_music_classif.c deleted file mode 100644 index 514f654cb83eceb9d6adabce02e9bf97f1ccc6fc..0000000000000000000000000000000000000000 --- a/lib_enc/speech_music_classif.c +++ /dev/null @@ -1,46 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include -#include "options.h" -#include -#include "cnst.h" -#include "prot.h" -#include "ivas_prot.h" -#include "rom_enc.h" -#include "rom_com.h" /* Common static table prototypes */ -#include "wmc_auto.h" diff --git a/lib_enc/speech_music_classif_fx.c b/lib_enc/speech_music_classif_fx.c index 6f8fba9f1e49c0fc7f74d14ca84ab9f1a4522b38..e04f5172b54a7022360d2afada7514b3e9e49624 100644 --- a/lib_enc/speech_music_classif_fx.c +++ b/lib_enc/speech_music_classif_fx.c @@ -17,9 +17,7 @@ #include "debug.h" #endif #include -#include "ivas_prot.h" #include "ivas_prot_fx.h" -#include "prot.h" /*---------------------------------------------------------------------* @@ -32,7 +30,7 @@ #define LOG_PROB_CONST 11292 /*0.5f * N_FEATURES * LOG_PI2 in Q10 */ #define DLP_BIAS 0.138121f -#define DLP_BIAS_FX 72415 /*Q19*/ +#define DLP_BIAS_FX 36208 /*Q18*/ #define TON_ALPHA_FX 31130 /* 0.95f in Q15 */ #define THR_MASS_MAX_FX 3565158 /* 0.85f in Q22 */ @@ -55,44 +53,20 @@ static void tonal_context_improv_fx( Encoder_State *st_fx, const Word32 PS[], co static void var_cor_calc_fx( const Word16 old_corr, Word16 *mold_corr, Word16 var_cor_t[], Word16 *high_stable_cor ); -static Word16 attack_det_fx( const Word16 *inp, const Word16 Qx, const Word16 last_clas, const Word16 localVAD, const Word16 coder_type, const Word32 total_brate -#ifdef IVAS_CODE - , - const Word16 element_mode, - const Word16 clas, - Word32 finc_prev[], - Word32 *lt_finc, - Word16 *last_strong_attack -#endif -); +static Word16 attack_det_fx( const Word16 *inp, const Word16 Qx, const Word16 last_clas, const Word16 localVAD, const Word16 coder_type, const Word32 total_brate ); static void order_spectrum_fx( Word16 *vec, Word16 len ); static void detect_sparseness_fx( Encoder_State *st_fx, const Word16 localVAD_HE_SAD, const Word16 voi_fv ); -// Q19 +// Q18 Word32 log_weights_speech_compute[N_SMC_MIXTURES] = { - -1156091, - -966805, - -946740, - -936304, - -758939, - -946469, + -578045, -483403, -473370, -468152, -379470, -473234 }; Word32 log_weights_music_compute[N_SMC_MIXTURES] = { - -973594, - -1045660, - -631047, - -859997, - -1551963, - -954511, + -486797, -522830, -315523, -429999, -775981, -477255 }; Word32 log_weights_noise_compute[N_SMC_MIXTURES] = { - -879882, - -1153486, - -538486, - -1290903, - -1058455, - -1084391, + -439941, -576743, -269243, -645452, -529228, -542196 }; /*---------------------------------------------------------------------* * speech_music_clas_init_fx() @@ -104,7 +78,7 @@ void speech_music_clas_init_fx( SP_MUS_CLAS_HANDLE hSpMusClas /* i/o: speech/music classifier handle */ ) { - int16_t i; + Word16 i; hSpMusClas->inact_cnt = 0; @@ -218,11 +192,14 @@ void speech_music_clas_init_fx( hSpMusClas->lt_dec_thres_fx = 5120; move16(); /*10 in Q9 */ hSpMusClas->ener_RAT_fx = 0; + move16(); /* speech/music classification */ set16_fx( hSpMusClas->lt_old_mode, 1, 3 ); hSpMusClas->lt_voicing = 16384 /*0.5f Q15*/; + move16(); hSpMusClas->lt_corr = 16384 /*0.5f Q15*/; + move16(); hSpMusClas->lt_tonality = 0; move32(); set16_fx( hSpMusClas->lt_corr_pitch, 0, 3 ); @@ -283,8 +260,8 @@ void speech_music_clas_init_ivas_fx( hSpMusClas->sp_mus_state = -8; move16(); - hSpMusClas->wdrop_fx = 0; - move16(); + hSpMusClas->wdrop_32fx = 0; + move32(); hSpMusClas->wrise_fx = 0; move16(); hSpMusClas->wdlp_0_95_sp_fx = 0; @@ -404,8 +381,13 @@ void speech_music_clas_init_ivas_fx( move16(); set32_fx( hSpMusClas->finc_prev_fx, 0, ATT_NSEG ); + hSpMusClas->q_finc_prev = Q31; + move16(); hSpMusClas->lt_finc_fx = 0; move32(); + hSpMusClas->Q_lt_finc = Q31; + move16(); + hSpMusClas->last_strong_attack = 0; move16(); hSpMusClas->tdm_lt_Etot_fx = 3; /* 0.01f in Q8 */ @@ -522,13 +504,13 @@ void speech_music_classif_fx( } st->sp_aud_decision0 = st->sp_aud_decision1; - + move16(); /* 2nd stage speech/music classifier (rewrite music to speech in onsets) */ st->sp_aud_decision2 = st->sp_aud_decision1; move16(); - IF( GT_16( st->bwidth, NB ) ) + IF( st->bwidth > NB ) { sp_mus_classif_2nd_fx( st, Etot, attack_flag, inp, Q_inp - 1 ); @@ -594,8 +576,6 @@ void speech_music_classif_fx( /* Select AUDIO frames */ test(); test(); - test(); - test(); #ifdef DEBUGGING if ( st->codec_mode == MODE1 && ( st->force == 1 || ( st->force == -1 && ( st->sp_aud_decision2 || st->GSC_noisy_speech ) ) ) ) #else @@ -611,6 +591,7 @@ void speech_music_classif_fx( ELSE { st->sp_aud_decision0 = st->sp_aud_decision1; + move16(); } @@ -661,14 +642,29 @@ static Word16 sp_mus_classif_gmm_fx( /* o : decis Word32 dPS[128], PS_norm[128]; Word32 lepsP1; Word32 max_s = 0, max_m = 0, py_s, py_m; + move32(); + move32(); Word32 max_n, py_n; /* pyn */ Word16 ishift[12] = { 8, 0, 2, 2, 2, 2, 2, 1, 0, 2, 2, 1 }; + move16(); + move16(); + move16(); + move16(); + move16(); + move16(); + move16(); + move16(); + move16(); + move16(); + move16(); + move16(); Word16 tmp; Word16 tmp1, tmp2, exp2, scale, exp3; SP_MUS_CLAS_HANDLE hSpMusClas = st_fx->hSpMusClas; HQ_ENC_HANDLE hHQ_core = st_fx->hHQ_core; #ifdef BASOP_NOGLOB_DECLARE_LOCAL Flag Overflow = 0; + move16(); #endif /*------------------------------------------------------------------* @@ -697,6 +693,7 @@ static Word16 sp_mus_classif_gmm_fx( /* o : decis ELSE { *pFV++ = round_fx( L_tmp ); + move16(); } /* [1] voicing Q15 */ @@ -712,11 +709,8 @@ static Word16 sp_mus_classif_gmm_fx( /* o : decis L_tmp = L_mult( st_fx->voicing_fx[0], 10923 ); L_tmp = L_mac( L_tmp, st_fx->voicing_fx[1], 10923 ); L_tmp = L_mac( L_tmp, st_fx->voicing_fx[2], 10923 ); -#ifdef BASOP_NOGLOB *pFV++ = round_fx_sat( L_tmp ); -#else - *pFV++ = round_fx( L_tmp ); -#endif + move16(); } /* [2,3,4,5,6] LSFs Q15*/ @@ -739,11 +733,13 @@ static Word16 sp_mus_classif_gmm_fx( /* o : decis /* [7] cor_map_sum Q8 */ *pFV++ = round_fx( L_mac( L_mult( cor_map_sum, 16384 ), hSpMusClas->last_cor_map_sum_fx, 16384 ) ); /* Q8 ->Q7*/ + move16(); hSpMusClas->last_cor_map_sum_fx = cor_map_sum; move16(); /* [8] non_sta Q8*/ *pFV++ = round_fx( L_mac( L_mult( non_sta, 16384 ), hSpMusClas->last_non_sta_fx, 16384 ) ); /* Q8 -> Q7 */ + move16(); hSpMusClas->last_non_sta_fx = non_sta; move16(); @@ -798,18 +794,10 @@ static Word16 sp_mus_classif_gmm_fx( /* o : decis sum_PS = L_deposit_l( 0 ); FOR( i = LOWEST_FBIN; i < HIGHEST_FBIN; i++ ) { -#ifdef BASOP_NOGLOB sum_PS = L_add_o( sum_PS, PS[i], &Overflow ); -#else /* BASOP_NOGLOB */ - sum_PS = L_add( sum_PS, PS[i] ); -#endif /* BASOP_NOGLOB */ } exp1 = norm_l( sum_PS ); -#ifdef BASOP_NOGLOB tmp1 = round_fx_o( L_shl( sum_PS, exp1 ), &Overflow ); -#else /* BASOP_NOGLOB */ - tmp1 = round_fx( L_shl( sum_PS, exp1 ) ); -#endif /* BASOP_NOGLOB */ exp1 = sub( 30, exp1 ); FOR( i = LOWEST_FBIN; i < HIGHEST_FBIN; i++ ) @@ -817,11 +805,7 @@ static Word16 sp_mus_classif_gmm_fx( /* o : decis /*PS_norm[i] = PS[i] / sum_PS;*/ /*dPS[i] = (float)fabs(PS_norm[i] - st->past_PS[i]);*/ exp2 = norm_l( PS[i] ); -#ifdef BASOP_NOGLOB tmp2 = round_fx_o( L_shl( PS[i], exp2 ), &Overflow ); -#else /* BASOP_NOGLOB */ - tmp2 = round_fx( L_shl( PS[i], exp2 ) ); -#endif /* BASOP_NOGLOB */ exp2 = sub( 30, exp2 ); scale = shr( sub( tmp1, tmp2 ), 15 ); @@ -891,11 +875,7 @@ static Word16 sp_mus_classif_gmm_fx( /* o : decis ELSE { exp1 = norm_l( L_add( dPS[i], 336 ) ); -#ifdef BASOP_NOGLOB tmp1 = round_fx_o( L_shl_o( L_add( dPS[i], 336 ), exp1, &Overflow ), &Overflow ); -#else - tmp1 = round_fx( L_shl( L_add( dPS[i], 336 ), exp1 ) ); -#endif exp1 = sub( 30, exp1 ); exp2 = norm_l( mx ); @@ -907,21 +887,29 @@ static Word16 sp_mus_classif_gmm_fx( /* o : decis exp2 = sub( exp2, scale ); exp3 = sub( exp1, exp2 ); - move16(); tmp = div_s( tmp2, tmp1 ); /*Q(15+exp3) */ L_tmp = L_shl( tmp, sub( 1, exp3 ) ); /*Q16 */ - ps_sta = L_add( ps_sta, L_tmp ); /*Q16 */ +#ifdef FIX_ISSUE_1151 + ps_sta = L_add_sat( ps_sta, L_tmp ); /*Q16 */ +#else + ps_sta = L_add( ps_sta, L_tmp ); /*Q16 */ +#endif } } /**pFV++ = (float)log(ps_sta + 1e-5f);*/ +#ifdef FIX_ISSUE_1151 + ps_sta = L_add_sat( ps_sta, 336 ); +#else ps_sta = L_add( ps_sta, 336 ); +#endif e_tmp = norm_l( ps_sta ); f_tmp = Log2_norm_lc( L_shl( ps_sta, e_tmp ) ); e_tmp = sub( 30 - 16, e_tmp ); L_tmp = Mpy_32_16( e_tmp, f_tmp, 22713 ); /* Q16 */ /* 22713 = ln(2) in Q15 */ *pFV++ = round_fx( L_shl( L_tmp, 11 ) ); /*Q11 */ + move16(); /* update PS vector */ Copy32( &PS_norm[LOWEST_FBIN], hSpMusClas->past_PS_fx, HIGHEST_FBIN - LOWEST_FBIN ); @@ -938,7 +926,6 @@ static Word16 sp_mus_classif_gmm_fx( /* o : decis pFV = FV; - move16(); IF( EQ_16( st_fx->bwidth, NB ) ) { pSF_m = SF_8k_mult_fx; @@ -953,11 +940,8 @@ static Word16 sp_mus_classif_gmm_fx( /* o : decis FOR( i = 0; i < N_FEATURES; i++ ) { /**pFV = pSF[0] * *pFV + pSF[1];*/ -#ifdef BASOP_NOGLOB *pFV = round_fx_o( L_shl_o( L_mac( pSF_a[i], *pFV, pSF_m[i] ), ishift[i], &Overflow ), &Overflow ); -#else /* BASOP_NOGLOB */ - *pFV = round_fx( L_shl( L_mac( pSF_a[i], *pFV, pSF_m[i] ), ishift[i] ) ); -#endif /* BASOP_NOGLOB */ + move16(); pFV++; } @@ -987,11 +971,7 @@ static Word16 sp_mus_classif_gmm_fx( /* o : decis FOR( p = 0; p < N_FEATURES; p++ ) { /* xm[p] = FV[p] - m_speech[k*N_FEATURES+p];*/ -#ifdef BASOP_NOGLOB xm[p] = sub_o( FV[p], m_speech_fx[k * N_FEATURES + p], &Overflow ); -#else /* BASOP_NOGLOB */ - xm[p] = sub( FV[p], m_speech_fx[k * N_FEATURES + p] ); -#endif /* BASOP_NOGLOB */ move16(); /*Q15 */ } @@ -1007,11 +987,7 @@ static Word16 sp_mus_classif_gmm_fx( /* o : decis FOR( p = 0; p < N_FEATURES; p++ ) { /*xm[p] = FV[p] - m_noise[k*N_FEATURES+p];*/ -#ifdef BASOP_NOGLOB xm[p] = sub_o( FV[p], m_noise_fx[k * N_FEATURES + p], &Overflow ); -#else /* BASOP_NOGLOB */ - xm[p] = sub( FV[p], m_noise_fx[k * N_FEATURES + p] ); -#endif /* BASOP_NOGLOB */ move16(); /*Q15 */ } @@ -1026,11 +1002,7 @@ static Word16 sp_mus_classif_gmm_fx( /* o : decis FOR( p = 0; p < N_FEATURES; p++ ) { /*xm[p] = FV[p] - m_music[k*N_FEATURES+p];*/ -#ifdef BASOP_NOGLOB xm[p] = sub_o( FV[p], m_music_fx[k * N_FEATURES + p], &Overflow ); -#else /* BASOP_NOGLOB */ - xm[p] = sub( FV[p], m_music_fx[k * N_FEATURES + p] ); -#endif /* BASOP_NOGLOB */ move16(); /*Q15 */ } @@ -1044,11 +1016,7 @@ static Word16 sp_mus_classif_gmm_fx( /* o : decis /* calculate log-probability */ /*log(0.0001)-0.5f * N_FEATURES * LOG_PI2 in Q9 */ -#ifdef BASOP_NOGLOB lps = extract_h( L_shl_o( L_sub( max_s, LOG_PROB_CONST ), 16 - 1, &Overflow ) ); /*Q9 */ -#else /* BASOP_NOGLOB */ - lps = extract_h( L_shl( L_sub( max_s, LOG_PROB_CONST ), 16 - 1 ) ); /*Q9 */ -#endif /* BASOP_NOGLOB */ lps = s_max( lps, -10832 ); lpm = extract_h( L_shl( L_sub( max_m, LOG_PROB_CONST ), 16 - 1 ) ); /*Q9 */ @@ -1056,11 +1024,7 @@ static Word16 sp_mus_classif_gmm_fx( /* o : decis /* lpn = (float)log(pyn) - 0.5f * N_FEATURES * (float)log(2*PI); */ -#ifdef BASOP_NOGLOB lpn = extract_h( L_shl_o( L_sub( max_n, LOG_PROB_CONST ), 16 - 1, &Overflow ) ); /*Q9 */ -#else /* BASOP_NOGLOB */ - lpn = extract_h( L_shl( L_sub( max_n, LOG_PROB_CONST ), 16 - 1 ) ); /*Q9 */ -#endif /* BASOP_NOGLOB */ lpn = s_max( lpn, -10832 ); *high_lpn_flag_ptr = 0; @@ -1361,12 +1325,7 @@ static void sp_mus_classif_2nd_fx( var_cor_calc_fx( st->old_corr_fx, &hSpMusClas->mold_corr_fx, hSpMusClas->var_cor_t_fx, &hSpMusClas->high_stable_cor ); /* attack detection */ - attack = attack_det_fx( inp, Qx, st->clas, st->localVAD, st->coder_type, st->total_brate -#ifdef IVAS_CODE - , - EVS_MONO, st->clas, hSpMusClas->finc_prev, &hSpMusClas->lt_finc, &hSpMusClas->last_strong_attack -#endif - ); + attack = attack_det_fx( inp, Qx, st->clas, st->localVAD, st->coder_type, st->total_brate ); test(); test(); @@ -1392,7 +1351,7 @@ static void sp_mus_classif_2nd_fx( move16(); test(); - IF( EQ_16( st->codec_mode, MODE1 ) && EQ_16( st->coder_type, TRANSITION ) ) + if ( EQ_16( st->codec_mode, MODE1 ) && EQ_16( st->coder_type, TRANSITION ) ) { st->coder_type = GENERIC; move16(); @@ -1406,7 +1365,7 @@ static void sp_mus_classif_2nd_fx( st->sp_aud_decision2 = 0; move16(); - IF( EQ_16( st->codec_mode, MODE1 ) ) + if ( EQ_16( st->codec_mode, MODE1 ) ) { st->coder_type = TRANSITION; move16(); @@ -1421,19 +1380,19 @@ static void sp_mus_classif_2nd_fx( move16(); *attack_flag = add( attack, 1 ); move16(); - IF( EQ_16( st->codec_mode, MODE1 ) ) + if ( EQ_16( st->codec_mode, MODE1 ) ) { st->coder_type = TRANSITION; move16(); } } - ELSE IF( GE_16( attack, ATT_SEG_LEN / 2 ) ) + ELSE IF( GE_16( attack, ATT_SEG_LEN >> 1 ) ) { /* do GSC coding if attack is located after the first quarter of the first subframe */ /* (pre-echo will be treated at the decoder side) */ st->sp_aud_decision2 = 1; - *attack_flag = 31; move16(); + *attack_flag = 31; move16(); } } @@ -1446,7 +1405,7 @@ static void sp_mus_classif_2nd_fx( /* do TC coding if attack is located in the last subframe */ *attack_flag = add( attack, 1 ); move16(); - IF( EQ_16( st->codec_mode, MODE1 ) ) + if ( EQ_16( st->codec_mode, MODE1 ) ) { st->coder_type = TRANSITION; move16(); @@ -1486,7 +1445,7 @@ static void var_cor_calc_fx( *high_stable_cor = 0; move16(); test(); - IF( GT_16( *mold_corr, 26214 ) && LT_16( var_cor, 2 ) ) + if ( GT_16( *mold_corr, 26214 ) && LT_16( var_cor, 2 ) ) { *high_stable_cor = 1; move16(); @@ -1512,24 +1471,14 @@ static Word16 attack_det_fx( /* o : attack flag const Word16 localVAD, /* i : local VAD flag */ const Word16 coder_type, /* i : coder type */ const Word32 total_brate /* i : total bitrate */ -#ifdef IVAS_CODE - , - const Word16 element_mode, /* i : IVAS element mode */ - const Word16 clas, /* i : signal class */ - Word32 finc_prev[], /* i/o: previous finc */ - Word32 *lt_finc, /* i/o: long-term mean finc */ - Word16 *last_strong_attack /* i/o: last strong attack flag */ -#endif ) { Word16 i, j, tmp, tmp1, attack, exp1; Word32 L_tmp, etmp, etmp2, finc[ATT_NSEG]; Word16 att_3lsub_pos; -#ifdef IVAS_CODE - Word16 attack1; -#endif #ifdef BASOP_NOGLOB_DECLARE_LOCAL Flag Overflow = 0; + move16(); #endif att_3lsub_pos = ATT_3LSUB_POS; @@ -1547,11 +1496,7 @@ static Word16 attack_det_fx( /* o : attack flag FOR( j = 1; j < ATT_SEG_LEN; j++ ) { -#ifdef BASOP_NOGLOB L_tmp = L_mac0_o( L_tmp, inp[i * ATT_SEG_LEN + j], inp[i * ATT_SEG_LEN + j], &Overflow ); /*2*Qx */ -#else /* BASOP_NOGLOB */ - L_tmp = L_mac0( L_tmp, inp[i * ATT_SEG_LEN + j], inp[i * ATT_SEG_LEN + j] ); /*2*Qx */ -#endif /* BASOP_NOGLOB */ } finc[i] = L_tmp; @@ -1559,9 +1504,6 @@ static Word16 attack_det_fx( /* o : attack flag } attack = maximum_32_fx( finc, ATT_NSEG, &etmp ); -#ifdef IVAS_CODE - attack1 = attack; -#endif move16(); test(); IF( EQ_16( localVAD, 1 ) && EQ_16( coder_type, GENERIC ) ) @@ -1575,19 +1517,11 @@ static Word16 attack_det_fx( /* o : attack flag exp1 = norm_s( att_3lsub_pos ); tmp = div_s( shl( 1, sub( 14, exp1 ) ), att_3lsub_pos ); /*Q(29-exp1) */ -#ifdef BASOP_NOGLOB L_tmp = L_shr_o( finc[0], Qx, &Overflow ); /*Qx */ -#else /* BASOP_NOGLOB */ - L_tmp = L_shr( finc[0], Qx ); /*Qx */ -#endif /* BASOP_NOGLOB */ FOR( i = 1; i < att_3lsub_pos; i++ ) { -#ifdef BASOP_NOGLOB L_tmp = L_add_o( L_tmp, L_shr_o( finc[i], Qx, &Overflow ), &Overflow ); /*Qx */ -#else /* BASOP_NOGLOB */ - L_tmp = L_add( L_tmp, L_shr( finc[i], Qx ) ); /*Qx */ -#endif /* BASOP_NOGLOB */ } L_tmp = Mult_32_16( L_tmp, tmp ); /*Q(14-exp1+Qx) */ etmp = L_shl( L_tmp, sub( exp1, 14 ) ); /*Qx */ @@ -1596,18 +1530,10 @@ static Word16 attack_det_fx( /* o : attack flag exp1 = norm_s( tmp1 ); tmp = div_s( shl( 1, sub( 14, exp1 ) ), tmp1 ); /*Q(29-exp1) */ -#ifdef BASOP_NOGLOB L_tmp = L_shr_o( finc[attack], Qx, &Overflow ); /*Qx */ -#else /* BASOP_NOGLOB */ - L_tmp = L_shr( finc[attack], Qx ); /*Qx */ -#endif /* BASOP_NOGLOB */ FOR( i = 1; i < tmp1; i++ ) { -#ifdef BASOP_NOGLOB L_tmp = L_add_o( L_tmp, L_shr_o( finc[i + attack], Qx, &Overflow ), &Overflow ); /*Qx */ -#else /* BASOP_NOGLOB */ - L_tmp = L_add( L_tmp, L_shr( finc[i + attack], Qx ) ); /*Qx */ -#endif /* BASOP_NOGLOB */ } L_tmp = Mult_32_16( L_tmp, tmp ); /*Q(14-exp1+Qx) */ etmp2 = L_shl( L_tmp, sub( exp1, 14 ) ); /*Qx */ @@ -1643,37 +1569,6 @@ static Word16 attack_det_fx( /* o : attack flag } } } -#ifdef IVAS_CODE - test(); - test(); - test(); - IF( attack == 0 && GT_16( element_mode, EVS_MONO ) && ( LT_16( clas, VOICED_TRANSITION ) || EQ_16( clas, ONSET ) ) ) - { - Copy32( finc, finc_prev, attack1 ); - - /* compute mean energy before the attack */ - etmp = L_shr( sum32_fx( finc_prev, ATT_NSEG ), 5 ); /*ATT_NSEG == 32*/ - - etmp2 = finc[attack1]; - move32(); - test(); - test(); - if ( ( LT_32( L_shl( etmp, 4 ), etmp2 ) ) || ( LT_32( L_mult0( etmp, 12 ), etmp2 ) && EQ_16( last_clas, UNVOICED_CLAS ) ) ) - { - attack = attack1; - move16(); - } - PMT( "Size of lf_finc not verified yet" ) - test(); - if ( GT_32( L_mult0( 20, *lt_finc ), etmp2 ) || *last_strong_attack ) /*lt_finc assumes same Q as etmp2, TBV!!!! */ - { - attack = 0; - move16(); - } - } - *last_strong_attack = attack; - move16(); -#endif } ELSE IF( attack > 0 ) { @@ -1690,10 +1585,6 @@ static Word16 attack_det_fx( /* o : attack flag BREAK; } } -#ifdef IVAS_CODE - *last_strong_attack = 0; -#endif - move16(); } return attack; @@ -1726,10 +1617,16 @@ Word16 ivas_smc_gmm_fx( Word16 flag_odv; Word32 lps_fx, lpm_fx, lpn_fx; Word32 ps_fx[N_SMC_MIXTURES], pm_fx[N_SMC_MIXTURES], pn_fx[N_SMC_MIXTURES]; +#ifndef DOT_PROD_CHOLESKY_64BIT Word32 lprob_fx; Word16 lprob_exp = 0; +#else + Word64 wprob_fx; +#endif Word32 fvm_fx[N_PCA_COEF]; +#ifndef DOT_PROD_CHOLESKY_64BIT Word16 fvm_exp = 0; +#endif Word32 sum_PS_fx, ps_diff_fx, ps_sta_fx; Word32 dlp_fx, wrelE_fx, wdrop_fx, wght_fx; Word32 wrise_fx; @@ -1752,6 +1649,7 @@ Word16 ivas_smc_gmm_fx( Word32 temp32_log1, temp32_log2; Word16 temp16; Word16 dotp_exp = 0; + move16(); /*------------------------------------------------------------------* * Initialization *------------------------------------------------------------------*/ @@ -1810,14 +1708,15 @@ Word16 ivas_smc_gmm_fx( hSpMusClas->sp_mus_state = add( hSpMusClas->sp_mus_state, 1 ); } + test(); IF( hSpMusClas->sp_mus_state < 0 && hSpMusClas->inact_cnt > 0 ) { hSpMusClas->inact_cnt = sub( hSpMusClas->inact_cnt, 1 ); + move16(); } } ELSE { - test(); test(); IF( hSpMusClas->sp_mus_state > 0 && LT_16( hSpMusClas->sp_mus_state, HANG_LEN ) ) { @@ -1829,6 +1728,7 @@ Word16 ivas_smc_gmm_fx( hSpMusClas->inact_cnt = sub( hSpMusClas->inact_cnt, 1 ); } + test(); IF( hSpMusClas->sp_mus_state > 0 && LT_16( hSpMusClas->sp_mus_state, HANG_LEN ) ) { hSpMusClas->sp_mus_state = -HANG_LEN; @@ -1899,8 +1799,8 @@ Word16 ivas_smc_gmm_fx( ELSE { hSpMusClas->relE_attack_cnt = 0; - relE_attack_flag = 0; move16(); + relE_attack_flag = 0; move16(); } @@ -1944,42 +1844,53 @@ Word16 ivas_smc_gmm_fx( move16(); temp16 = lsp_new_fx[2]; move16(); + temp32 = L_sub( ONE_IN_Q30, L_mult0( temp16, temp16 ) ); // Q30 temp_sqrt = Sqrt32( temp32, &temp_exp ); temp_acos = BASOP_util_atan2( temp_sqrt, L_deposit_h( temp16 ), temp_exp ); *pFV_fx++ = L_shl( temp_acos, Q7 ); // Q20 + move32(); temp_exp = 1; move16(); temp16 = lsp_new_fx[3]; move16(); + temp32 = L_sub( ONE_IN_Q30, L_mult0( temp16, temp16 ) ); // Q30 temp_sqrt = Sqrt32( temp32, &temp_exp ); temp_acos = BASOP_util_atan2( temp_sqrt, L_deposit_h( temp16 ), temp_exp ); *pFV_fx++ = L_shl( temp_acos, Q7 ); // Q20 + move32(); temp_exp = 1; move16(); temp16 = lsp_new_fx[4]; move16(); + temp32 = L_sub( ONE_IN_Q30, L_mult0( temp16, temp16 ) ); // Q30 temp_sqrt = Sqrt32( temp32, &temp_exp ); temp_acos = BASOP_util_atan2( temp_sqrt, L_deposit_h( temp16 ), temp_exp ); *pFV_fx++ = L_shl( temp_acos, Q7 ); // Q20 + move32(); temp_exp = 1; move16(); temp16 = lsp_new_fx[5]; move16(); + temp32 = L_sub( ONE_IN_Q30, L_mult0( temp16, temp16 ) ); // Q30 temp_sqrt = Sqrt32( temp32, &temp_exp ); temp_acos = BASOP_util_atan2( temp_sqrt, L_deposit_h( temp16 ), temp_exp ); *pFV_fx++ = L_shl( temp_acos, Q7 ); // Q20 + move32(); temp_exp = 1; move16(); temp16 = lsp_new_fx[6]; move16(); + + temp32 = L_sub( ONE_IN_Q30, L_mult0( temp16, temp16 ) ); // Q30 temp_sqrt = Sqrt32( temp32, &temp_exp ); temp_acos = BASOP_util_atan2( temp_sqrt, L_deposit_h( temp16 ), temp_exp ); *pFV_fx++ = L_shl( temp_acos, Q7 ); // Q20 + move32(); // temf = acosf( lsp_new[2] ); /* [2,3,4,5,6] LSFs */ /* *pFV++ = acosf( lsp_new[2] ); @@ -1998,12 +1909,10 @@ Word16 ivas_smc_gmm_fx( /* [9] epsP */ temp32 = L_add( epsP_fx[14], L_shr( 21475, sub( 31, Q_esp ) ) ); - move32(); temp32_log = L_add( BASOP_Util_Log2( temp32 ), L_shl( sub( Q31, Q_esp ), Q25 ) ); temp32_log1 = Mpy_32_32( temp32_log, 1488522239 ); /*logf(x) = log2(x)*logf(2)*/ temp32 = L_add( epsP_fx[0], L_shr( 21475, sub( 31, Q_esp ) ) ); - move32(); temp32_log = L_add( BASOP_Util_Log2( temp32 ), L_shl( sub( Q31, Q_esp ), Q25 ) ); temp32_log2 = Mpy_32_32( temp32_log, 1488522239 ); /*logf(x) = log2(x)*logf(2)*/ @@ -2015,7 +1924,6 @@ Word16 ivas_smc_gmm_fx( set_zero_fx( melS_fx, NB_MEL_BANDS ); pt_mel_fb_fx = mel_fb_fx; - move32(); FOR( i = 0; i < NB_MEL_BANDS; i++ ) { @@ -2039,25 +1947,42 @@ Word16 ivas_smc_gmm_fx( } Word16 guard_bits = find_guarded_bits_fx( NB_MEL_BANDS ); + move16(); v_mult_mat_fixed( mfcc_fx, melS_fx, dct_mtx_fx, NB_MEL_BANDS, NB_MEL_COEF, guard_bits ); // Q19 *pFV_fx++ = L_shl( mfcc_fx[2], 1 ); // Q20 + move32(); *pFV_fx++ = L_shl( mfcc_fx[6], 1 ); + move32(); *pFV_fx++ = L_shl( mfcc_fx[12], 1 ); + move32(); /* *pFV++ = mfcc[2]; *pFV++ = mfcc[6]; *pFV++ = mfcc[12];*/ /* calculation of differential normalized power spectrum */ sum_PS_fx = 0; - Word16 sum_PS_e = 0; move32(); + Word16 sum_PS_e = 0; move16(); + Word64 sum = W_shl( 21475 /* 1e-5 in Q31 */, sub( Qfact_PS, 30 ) ); // Qfact_PS+1 + move64(); FOR( i = LOWEST_FBIN; i < HIGHEST_FBIN; i++ ) { - sum_PS_fx = BASOP_Util_Add_Mant32Exp( sum_PS_fx, sum_PS_e, PS_fx[i], sub( 31, Qfact_PS ), &sum_PS_e ); // sum_PS_e + sum = W_mac_32_32( sum, PS_fx[i], 1 ); // Qfact_PS+1 + } + IF( sum == 0 ) + { + sum_PS_fx = 1407374884; // 1e-5 in Q47 + move32(); + sum_PS_e = -16; + move16(); + } + ELSE + { + sum_PS_e = W_norm( sum ); + sum_PS_fx = W_extract_h( W_shl( sum, sum_PS_e ) ); // Qfact_PS+1+sum_PS_e-32 + sum_PS_e = sub( 62, add( Qfact_PS, sum_PS_e ) ); // 31-(Qfact_PS+1+sum_PS_e-32) } - sum_PS_e = add( sum_PS_e, 1 ); // to avoid overflow - sum_PS_fx = L_add( L_shr( sum_PS_fx, 1 ), L_shr( 21475 /*1 e-5 q31*/, sum_PS_e ) ); // 31-sum_PS_e FOR( i = LOWEST_FBIN; i < HIGHEST_FBIN; i++ ) { @@ -2089,13 +2014,14 @@ Word16 ivas_smc_gmm_fx( IF( GT_32( PS_norm_fx[i], hSpMusClas->past_PS_fx[i - LOWEST_FBIN] ) ) { temp32 = BASOP_Util_Divide3232_Scale_cadence( PS_norm_fx[i], ( L_add( dPS_fx[i], L_shr( 21475, sub( 31, Qfact_PS_past ) ) ) ), &temp_exp ); // 31-temp_exp + move32(); ps_sta_fx = BASOP_Util_Add_Mant32Exp( temp32, temp_exp, ps_sta_fx, ps_sta_exp, &ps_sta_exp ); + move32(); } ELSE { // ps_sta += hSpMusClas->past_PS[i - LOWEST_FBIN] / ( dPS[i] + 1e-5f ); temp32 = BASOP_Util_Divide3232_Scale_cadence( hSpMusClas->past_PS_fx[i - LOWEST_FBIN], ( L_add( dPS_fx[i], L_shr( 21475, sub( 31, Qfact_PS_past ) ) ) ), &temp_exp ); // 31-temp_exp - move32(); ps_sta_fx = BASOP_Util_Add_Mant32Exp( temp32, temp_exp, ps_sta_fx, ps_sta_exp, &ps_sta_exp ); } } @@ -2124,8 +2050,8 @@ Word16 ivas_smc_gmm_fx( hStereoClassif->ps_sta_ch2_e = 6; // logf( ps_sta + 1e-5f );Q25 } move32(); - move32(); move16(); + move32(); move16(); } @@ -2143,6 +2069,7 @@ Word16 ivas_smc_gmm_fx( move16(); FOR( i = 0; i < N_SMC_FEATURES; i++ ) { + test(); IF( LT_32( *pFV_fx, pODV_fx[0] ) || GT_32( *pFV_fx, pODV_fx[1] ) ) { *p_out++ = i; @@ -2180,6 +2107,8 @@ Word16 ivas_smc_gmm_fx( { //*pFV_st = smc_st_mean_fact * ( *pFV_st ) + ( 1 - smc_st_mean_fact ) * ( *pFV ); *pFV_st_fx = L_add( L_shr( *pFV_st_fx, smc_st_mean_fact_fx ), L_shr( *pFV_fx, 1 ) ); + move32(); + test(); test(); test(); @@ -2201,6 +2130,7 @@ Word16 ivas_smc_gmm_fx( ELSE { *pFV_fx++ = *pFV_st_fx++; + move32(); } } @@ -2215,15 +2145,17 @@ Word16 ivas_smc_gmm_fx( IF( bcox_lmbd_fx[i] != 0 ) { *pFV_fx = L_sub( *pFV_fx, L_shr( bcox_add_cnst_fx[i], sub( 31, Qfact_FV ) ) ); + move32(); IF( LT_32( *pFV_fx, L_shl( 1, Qfact_FV ) ) ) { *pFV_fx = L_shl( 1, Qfact_FV ); + move32(); } Word16 pow_e = 0; move32(); temp32_log = L_add( BASOP_Util_Log2( *pFV_fx ), L_shl( sub( 31, Qfact_FV ), Q25 ) ); // Q25 temp32 = Mpy_32_32( temp32_log, bcox_lmbd_fx[i] ); // Q25 - Word32 pow_temp = BASOP_util_Pow2( temp32, sub( 31, Q25 ), &pow_e ); + Word32 pow_temp = BASOP_util_Pow2( temp32, 31 - Q25, &pow_e ); IF( pow_e <= 0 ) { pow_temp = L_shr( pow_temp, sub( 1, pow_e ) ); @@ -2234,6 +2166,7 @@ Word16 ivas_smc_gmm_fx( move32(); temp32 = L_deposit_h( BASOP_Util_Divide3232_Scale( temp32, bcox_lmbd_fx[i], &temp_exp ) ); *pFV_fx = L_shl( temp32, sub( Qfact_FV, sub( 31, add( temp_exp, pow_e ) ) ) ); + move32(); // float temp = powf( *pFV, bcox_lmbd[i] ); // *pFV = ( powf( *pFV, bcox_lmbd[i] ) - 1 ) / bcox_lmbd[i]; } @@ -2253,8 +2186,11 @@ Word16 ivas_smc_gmm_fx( // *pFV = ( *pFV - sm_means[i] ) / sm_scale[i]; temp32 = L_sub( *pFV_fx, sm_means_fx[i] ); temp_exp = 0; + move16(); temp32 = L_deposit_h( BASOP_Util_Divide3232_Scale( temp32, sm_scale_fx[i], &temp_exp ) ); - *pFV_fx = L_shl( temp32, Qfact_FV - ( 31 - temp_exp ) ); + // *pFV_fx = L_shl( temp32, Qfact_FV - ( 31 - temp_exp ) ); + *pFV_fx = L_shl( temp32, sub( Qfact_FV, sub( 31, temp_exp ) ) ); + move32(); pFV_fx++; /* MinMax sclaer - mean and variance normalization */ /**pFV = *pFV * sm_scale[i] + sm_min[i];*/ @@ -2277,29 +2213,44 @@ Word16 ivas_smc_gmm_fx( FOR( m = 0; m < N_SMC_MIXTURES; m++ ) { v_sub32_fx( FV_fx, &means_speech_fx[m * N_PCA_COEF], fvm_fx, N_PCA_COEF ); +#ifndef DOT_PROD_CHOLESKY_64BIT fvm_exp = sub( 31, Qfact_FV ); lprob_exp = 0; move16(); lprob_fx = dot_product_cholesky_fixed( fvm_fx, &prec_chol_speech_fx[m * ( N_PCA_COEF * N_PCA_COEF + N_PCA_COEF ) / 2], N_PCA_COEF, fvm_exp, 31 - 28, &lprob_exp ); - ps_fx[m] = L_sub( L_sub( L_add( log_weights_speech_compute[m], log_det_chol_speech_fx[m] ), L_shl( lprob_fx, sub( Q19 - 1, sub( Q31, lprob_exp ) ) ) ), HALF_N_PCA_COEF_LOG_P12_Q19 ); // Q19 + ps_fx[m] = L_sub( L_sub( L_add( log_weights_speech_compute[m], log_det_chol_speech_fx[m] ), L_shl( lprob_fx, sub( Q18 - 1, sub( Q31, lprob_exp ) ) ) ), HALF_N_PCA_COEF_LOG_P12_Q18 ); // Q18 +#else + wprob_fx = dot_product_cholesky_fixed( fvm_fx, &prec_chol_speech_fx[m * ( N_PCA_COEF * N_PCA_COEF + N_PCA_COEF ) / 2], N_PCA_COEF ); // Q10 + ps_fx[m] = L_sub( L_sub( L_add( log_weights_speech_compute[m], log_det_chol_speech_fx[m] ), W_extract_l( W_shr( wprob_fx, Q10 ) ) ), HALF_N_PCA_COEF_LOG_P12_Q18 ); // Q18 +#endif move32(); v_sub32_fx( FV_fx, &means_music_fx[m * N_PCA_COEF], fvm_fx, N_PCA_COEF ); +#ifndef DOT_PROD_CHOLESKY_64BIT lprob_exp = 0; move16(); lprob_fx = dot_product_cholesky_fixed( fvm_fx, &prec_chol_music_fx[m * ( N_PCA_COEF * N_PCA_COEF + N_PCA_COEF ) / 2], N_PCA_COEF, fvm_exp, 31 - 28, &lprob_exp ); - pm_fx[m] = L_sub( L_sub( L_add( log_weights_music_compute[m], log_det_chol_music_fx[m] ), L_shl( lprob_fx, sub( Q19 - 1, sub( Q31, lprob_exp ) ) ) ), HALF_N_PCA_COEF_LOG_P12_Q19 ); // Q19 + pm_fx[m] = L_sub( L_sub( L_add( log_weights_music_compute[m], log_det_chol_music_fx[m] ), L_shl( lprob_fx, sub( Q18 - 1, sub( Q31, lprob_exp ) ) ) ), HALF_N_PCA_COEF_LOG_P12_Q18 ); // Q18 +#else + wprob_fx = dot_product_cholesky_fixed( fvm_fx, &prec_chol_music_fx[m * ( N_PCA_COEF * N_PCA_COEF + N_PCA_COEF ) / 2], N_PCA_COEF ); // Q10 + pm_fx[m] = L_sub( L_sub( L_add( log_weights_music_compute[m], log_det_chol_music_fx[m] ), W_extract_l( W_shr( wprob_fx, Q10 ) ) ), HALF_N_PCA_COEF_LOG_P12_Q18 ); // Q18 +#endif move32(); v_sub32_fx( FV_fx, &means_noise_fx[m * N_PCA_COEF], fvm_fx, N_PCA_COEF ); +#ifndef DOT_PROD_CHOLESKY_64BIT lprob_exp = 0; move16(); lprob_fx = dot_product_cholesky_fixed( fvm_fx, &prec_chol_noise_fx[m * ( N_PCA_COEF * N_PCA_COEF + N_PCA_COEF ) / 2], N_PCA_COEF, fvm_exp, 31 - 28, &lprob_exp ); - pn_fx[m] = L_sub( L_sub( L_add( log_weights_noise_compute[m], log_det_chol_noise_fx[m] ), L_shl( lprob_fx, sub( Q19 - 1, sub( Q31, lprob_exp ) ) ) ), HALF_N_PCA_COEF_LOG_P12_Q19 ); // Q19 + pn_fx[m] = L_sub( L_sub( L_add( log_weights_noise_compute[m], log_det_chol_noise_fx[m] ), L_shl( lprob_fx, sub( Q18 - 1, sub( Q31, lprob_exp ) ) ) ), HALF_N_PCA_COEF_LOG_P12_Q18 ); // Q18 +#else + wprob_fx = dot_product_cholesky_fixed( fvm_fx, &prec_chol_noise_fx[m * ( N_PCA_COEF * N_PCA_COEF + N_PCA_COEF ) / 2], N_PCA_COEF ); // Q10 + pn_fx[m] = L_sub( L_sub( L_add( log_weights_noise_compute[m], log_det_chol_noise_fx[m] ), W_extract_l( W_shr( wprob_fx, Q10 ) ) ), HALF_N_PCA_COEF_LOG_P12_Q18 ); // Q18 +#endif move32(); } - lps_fx = logsumexp_fx( ps_fx, sub( 31, Q19 ), N_SMC_MIXTURES ); - lpm_fx = logsumexp_fx( pm_fx, sub( 31, Q19 ), N_SMC_MIXTURES ); - lpn_fx = logsumexp_fx( pn_fx, sub( 31, Q19 ), N_SMC_MIXTURES ); + lps_fx = logsumexp_fx( ps_fx, 31 - Q18, N_SMC_MIXTURES ); + lpm_fx = logsumexp_fx( pm_fx, 31 - Q18, N_SMC_MIXTURES ); + lpn_fx = logsumexp_fx( pn_fx, 31 - Q18, N_SMC_MIXTURES ); *high_lpn_flag = 0; move16(); if ( GT_32( lpn_fx, lps_fx ) && GT_32( lpn_fx, lpm_fx ) ) @@ -2307,15 +2258,25 @@ Word16 ivas_smc_gmm_fx( *high_lpn_flag = 1; move32(); } - - hSpMusClas->lpm_fx = extract_l( L_shr( lpm_fx, 12 ) ); // Q7 - hSpMusClas->lps_fx = extract_l( L_shr( lps_fx, 12 ) ); // Q7 - hSpMusClas->lpn_fx = extract_l( L_shr( lpn_fx, 12 ) ); // Q7 - +#ifndef FIX_1297_OVERFLOW + hSpMusClas->lpm_fx = extract_l( L_shr( lpm_fx, 11 ) ); // Q7 + move16(); + hSpMusClas->lps_fx = extract_l( L_shr( lps_fx, 11 ) ); // Q7 + move16(); + hSpMusClas->lpn_fx = extract_l( L_shr( lpn_fx, 11 ) ); // Q7 + move16(); +#else + hSpMusClas->lpm_fx = extract_h( L_shl_sat( lpm_fx, 16 - 11 ) ); // Q7 + move16(); + hSpMusClas->lps_fx = extract_h( L_shl_sat( lps_fx, 16 - 11 ) ); // Q7 + move16(); + hSpMusClas->lpn_fx = extract_h( L_shl_sat( lpn_fx, 16 - 11 ) ); // Q7 + move16(); +#endif /* determine HQ Generic speech class */ IF( st->hHQ_core != NULL ) { - IF( GT_32( lps_fx, L_add( lpm_fx, ONE_IN_Q18 ) ) ) + IF( GT_32( lps_fx, L_add( lpm_fx, ONE_IN_Q17 ) ) ) { st->hHQ_core->hq_generic_speech_class = 1; } @@ -2344,6 +2305,7 @@ Word16 ivas_smc_gmm_fx( ELSE { dlp_fx = L_add( L_sub( lpm_fx, lps_fx ), DLP_BIAS_FX ); + dlp_fx = L_shl( dlp_fx, 1 ); // Q19 IF( GT_32( dlp_fx, 15728640 ) ) /*30.0f in Q19*/ { @@ -2357,12 +2319,10 @@ Word16 ivas_smc_gmm_fx( } dec = (Word16) GT_32( dlp_fx, 0 ); + move16(); /* calculate weight based on relE (higher relE -> lower weight, lower relE -> higher weight) */ - Word16 Qio = Q24; - move16(); - wrelE_fx = lin_interp32_fx( L_deposit_h( relE_fx ), 15 << 24, 15099494 /*0.9 q24*/, -( 15 << 24 ), 16609443 /*0.99 q24*/, 1, &Qio ); // Q25 - wrelE_fx = L_shr( wrelE_fx, sub( Qio, 25 ) ); + wrelE_fx = lin_interp32_fx( L_deposit_h( relE_fx ), 15 << 24, 1932735283 /*0.9 in Q31*/, -( 15 << 24 ), 2126008812 /*0.99 in Q31*/, 1 ); // Q31 /* calculate weight based on drops of dlp (close to 1 during sudden drops of dlp, close to 0 otherwise) */ // hSpMusClas->dlp_mean_ST = 0.8f * hSpMusClas->dlp_mean_ST + 0.2f * dlp; hSpMusClas->dlp_mean_ST_fx = L_add( Mpy_32_32( 1717986918, hSpMusClas->dlp_mean_ST_fx ), Mpy_32_32( 429496729, dlp_fx ) ); @@ -2372,26 +2332,27 @@ Word16 ivas_smc_gmm_fx( { IF( hSpMusClas->dlp_mean_ST_fx > 0 ) { - hSpMusClas->wdrop_fx = -extract_l( L_shr( dlp_fx, 10 ) ); // Q9 + hSpMusClas->wdrop_32fx = L_negate( dlp_fx ); // Q19 + move32(); } - ELSE IF( hSpMusClas->wdrop_fx > 0 ) + ELSE IF( hSpMusClas->wdrop_32fx > 0 ) { - hSpMusClas->wdrop_fx = extract_l( L_shr( L_sub( hSpMusClas->dlp_mean_ST_fx, dlp_fx ), 10 ) ); + hSpMusClas->wdrop_32fx = L_add( hSpMusClas->wdrop_32fx, L_sub( hSpMusClas->dlp_mean_ST_fx, dlp_fx ) ); + move32(); } + move16(); } ELSE { - hSpMusClas->wdrop_fx = 0; - move16(); + hSpMusClas->wdrop_32fx = 0; + move32(); } - Qio = Q25; - move16(); - wdrop_fx = lin_interp32_fx( L_deposit_h( hSpMusClas->wdrop_fx ), 503316480, 23488102, 0, ONE_IN_Q25, 1, &Qio ); - wdrop_fx = L_shr( wdrop_fx, sub( Qio, 25 ) ); + wdrop_fx = lin_interp32_fx( hSpMusClas->wdrop_32fx, 7864320, 1503238554 /* 0.7 in Q31 */, 0, ONE_IN_Q31 /* 1.0f in Q31 */, 1 ); /* Q31 */ + test(); test(); /* calculate weight based on rises of dlp (close to 1 during sudden rise of dlp, close to 0 otherwise) */ - IF( EQ_16( hSpMusClas->sp_mus_state, HANG_LEN ) && hSpMusClas->dlp_mean_ST_fx > 0 && hSpMusClas->dlp_mean_ST_fx > hSpMusClas->past_dlp_mean_ST_fx[0] ) + IF( EQ_16( hSpMusClas->sp_mus_state, HANG_LEN ) && hSpMusClas->dlp_mean_ST_fx > 0 && GT_32( hSpMusClas->dlp_mean_ST_fx, hSpMusClas->past_dlp_mean_ST_fx[0] ) ) { IF( hSpMusClas->past_dlp_mean_ST_fx[0] < 0 ) { @@ -2401,6 +2362,7 @@ Word16 ivas_smc_gmm_fx( { hSpMusClas->wrise_fx = add( hSpMusClas->wrise_fx, extract_l( L_shr( L_sub( hSpMusClas->dlp_mean_ST_fx, hSpMusClas->past_dlp_mean_ST_fx[0] ), 10 ) ) ); } + move16(); } ELSE { @@ -2409,21 +2371,18 @@ Word16 ivas_smc_gmm_fx( } - Qio = Q25; - move16(); - wrise_fx = lin_interp32_fx( L_deposit_h( hSpMusClas->wrise_fx ), 167772160, 31876710, 0, ONE_IN_Q25, 1, &Qio ); - wrise_fx = L_shr( wrise_fx, sub( Qio, 25 ) ); + wrise_fx = lin_interp32_fx( L_deposit_h( hSpMusClas->wrise_fx ), 167772160, 2040109466 /* 0.95 in Q31 */, 0, ONE_IN_Q31 /* 1.0f in Q31 */, 1 ); /* Q31 */ /* combine weights into one */ // wght = wrelE * wdrop * wrise; - wght_fx = Mpy_32_32( Mpy_32_32( wrelE_fx, wdrop_fx ), wrise_fx ); // Q13 + wght_fx = Mpy_32_32( Mpy_32_32( wrelE_fx, wdrop_fx ), wrise_fx ); /* Q31 */ test(); /* ratio of delta means vs. delta variances */ IF( hSpMusClas->sp_mus_state > 0 && LT_16( hSpMusClas->sp_mus_state, HANG_LEN ) ) { hSpMusClas->dlp_mean_LT_fx = dlp_fx; - hSpMusClas->dlp_var_LT_fx = 0; move32(); + hSpMusClas->dlp_var_LT_fx = 0; move32(); } @@ -2434,11 +2393,11 @@ Word16 ivas_smc_gmm_fx( hSpMusClas->dlp_var_LT_fx = L_add( Mpy_32_32( 1932735283, hSpMusClas->dlp_var_LT_fx ), Mpy_32_32( 214748365, temp32 ) ); test(); - IF( hSpMusClas->sp_mus_state > 0 && hSpMusClas->sp_mus_state < HANG_LEN ) + IF( hSpMusClas->sp_mus_state > 0 && LT_16( hSpMusClas->sp_mus_state, HANG_LEN ) ) { dlp_mean2var_fx = 0; - dlp_mean2var_q = 0; move16(); + dlp_mean2var_q = 0; move16(); } ELSE @@ -2469,34 +2428,34 @@ Word16 ivas_smc_gmm_fx( IF( GT_32( L_deposit_l( dlp_mean2var_fx ), L_shl( 15, dlp_mean2var_q ) ) ) { /* decrease the weight little bit when the classifier indicates "strong speech" or "strong music" */ - // wght *= 0.9f; - wght_fx = Mpy_32_32( wght_fx, 1932735283 ); // Q13 + wght_fx = Mpy_32_32( wght_fx, 1932735283 /* 0.9f in Q31 */ ); /* Q31 */ } - IF( GT_32( wght_fx, ONE_IN_Q13 ) ) + IF( GT_32( wght_fx, ONE_IN_Q31 ) ) { - wght_fx = ONE_IN_Q13; + wght_fx = ONE_IN_Q31; /* 1.0f in Q31 */ } - ELSE IF( LT_32( wght_fx, 82 ) ) + ELSE IF( LT_32( wght_fx, 21474836 /* 0.01f in Q31 */ ) ) { - wght_fx = 82; + wght_fx = 21474836; /* 0.01f in Q31 */ } move32(); - if ( LT_16( Etot_fx, 2560 ) ) + if ( LT_16( Etot_fx, 2560 /* 10f in Q8 */ ) ) { /* silence */ - wght_fx = 7537; + wght_fx = 1975684956; /* 0.92f in Q31 */ move32(); } /* calculate weighted decision */ // hSpMusClas->wdlp_0_95_sp = wght * hSpMusClas->wdlp_0_95_sp + ( 1 - wght ) * dlp; - hSpMusClas->wdlp_0_95_sp_32fx = L_add( Mpy_32_32( L_shl( wght_fx /*q13*/, 18 ), hSpMusClas->wdlp_0_95_sp_32fx /*q24*/ ), Mpy_32_32( L_shl( L_sub( ONE_IN_Q13, wght_fx /*q13*/ ), Q18 ), L_shl( dlp_fx /*q19*/, 5 ) ) ); // Q24 + hSpMusClas->wdlp_0_95_sp_32fx = L_add( Mpy_32_32( wght_fx, hSpMusClas->wdlp_0_95_sp_32fx /*q24*/ ), Mpy_32_32( L_sub( ONE_IN_Q31, wght_fx ), L_shl( dlp_fx /*q19*/, 5 ) ) ); // Q24 move32(); /* xtalk classifier: apply long hysteresis to prevent LRTD on music */ - hSpMusClas->wdlp_xtalk_fx = L_add( Mpy_32_32( 2136746229, hSpMusClas->wdlp_xtalk_fx ), Mpy_32_32( 10737418, dlp_fx ) ); + hSpMusClas->wdlp_xtalk_fx = Madd_32_32( Mpy_32_32( 2136746230 /* 0.995f in Q31*/, hSpMusClas->wdlp_xtalk_fx /* Q25*/ ), 687194767 /* 0.005f in Q37 */, dlp_fx /* Q19*/ ); // Q25 + move32(); /*------------------------------------------------------------------* * Final speech/music decision @@ -2510,6 +2469,7 @@ Word16 ivas_smc_gmm_fx( ELSE IF( hSpMusClas->flag_spitch_cnt > 0 ) { hSpMusClas->flag_spitch_cnt = sub( hSpMusClas->flag_spitch_cnt, 1 ); + move16(); } test(); IF( Etot_fx < 2560 ) @@ -2522,11 +2482,10 @@ Word16 ivas_smc_gmm_fx( { temp32 = L_mult( w_spmus_fx[hSpMusClas->sp_mus_state - 1][0], (Word16) L_shr( dlp_fx, 10 ) ); /*Q25 */ temp32 = L_add( temp32, Dot_product( &w_spmus_fx[hSpMusClas->sp_mus_state - 1][1], hSpMusClas->past_dlp_fx, sub( HANG_LEN, 1 ) ) ); - move16(); /* entry state -> final decision is calculated based on weighted average of past non-binary decisions */ - IF( GT_32( temp32, L_shl( 2, 25 ) ) ) + IF( GT_32( temp32, 2 << 25 ) ) { - IF( GT_32( dlp_fx, L_shl( 2, 19 ) ) ) + IF( GT_32( dlp_fx, 2 << 19 ) ) { dec = 2; } @@ -2660,7 +2619,7 @@ static void var_cor_calc_ivas_fx( *high_stable_cor = 0; move16(); test(); - IF( GT_16( *mold_corr, 26214 ) && LT_16( var_cor, 1 ) ) + if ( GT_16( *mold_corr, 26214 ) && LT_16( var_cor, 1 ) ) { *high_stable_cor = 1; move16(); @@ -2689,8 +2648,10 @@ static Word16 attack_det_ivas_fx( /* o : attack flag const Word32 total_brate, /* i : total bitrate */ const Word16 element_mode, /* i : IVAS element mode */ const Word16 clas, /* i : signal class */ - Word32 finc_prev[], /* i/o: previous finc, (2 * Qx) */ - Word32 *lt_finc, /* i/o: long-term mean finc, (2 * Qx) */ + Word32 finc_prev[], /* i/o: previous finc, (q_finc_prev) */ + Word16 *q_finc_prev, /* i/o: Q of previous finc */ + Word32 *lt_finc, /* i/o: long-term mean finc, (q_lt_finc) */ + Word16 *q_lt_finc, /* i/o: Q of lt_finc */ Word16 *last_strong_attack /* i/o: last strong attack flag */ ) { @@ -2698,8 +2659,8 @@ static Word16 attack_det_ivas_fx( /* o : attack flag Word32 L_tmp, etmp, etmp2, finc[ATT_NSEG], mean_finc; Word16 att_3lsub_pos; Word16 attack1; - Word64 W_tmp = 0; - move64(); + Word64 W_tmp; + Word16 q_diff; #ifdef BASOP_NOGLOB_DECLARE_LOCAL Flag Overflow = 0; @@ -2721,11 +2682,7 @@ static Word16 attack_det_ivas_fx( /* o : attack flag FOR( j = 1; j < ATT_SEG_LEN; j++ ) { -#ifdef BASOP_NOGLOB L_tmp = L_mac0_o( L_tmp, inp[i * ATT_SEG_LEN + j], inp[i * ATT_SEG_LEN + j], &Overflow ); /*2*Qx */ -#else /* BASOP_NOGLOB */ - L_tmp = L_mac0( L_tmp, inp[i * ATT_SEG_LEN + j], inp[i * ATT_SEG_LEN + j] ); /*2*Qx */ -#endif /* BASOP_NOGLOB */ } finc[i] = L_tmp; @@ -2736,6 +2693,9 @@ static Word16 attack_det_ivas_fx( /* o : attack flag attack1 = attack; move16(); + *q_finc_prev = shl( Qx, 1 ); // Q of finc + move16(); + q_diff = sub( *q_finc_prev, *q_lt_finc ); test(); IF( EQ_16( localVAD, 1 ) && EQ_16( coder_type, GENERIC ) ) { @@ -2748,19 +2708,11 @@ static Word16 attack_det_ivas_fx( /* o : attack flag exp1 = norm_s( att_3lsub_pos ); tmp = div_s( shl( 1, sub( 14, exp1 ) ), att_3lsub_pos ); /*Q(29-exp1) */ -#ifdef BASOP_NOGLOB L_tmp = L_shr_o( finc[0], Qx, &Overflow ); /*Qx */ -#else /* BASOP_NOGLOB */ - L_tmp = L_shr( finc[0], Qx ); /*Qx */ -#endif /* BASOP_NOGLOB */ FOR( i = 1; i < att_3lsub_pos; i++ ) { -#ifdef BASOP_NOGLOB L_tmp = L_add_o( L_tmp, L_shr_o( finc[i], Qx, &Overflow ), &Overflow ); /*Qx */ -#else /* BASOP_NOGLOB */ - L_tmp = L_add( L_tmp, L_shr( finc[i], Qx ) ); /*Qx */ -#endif /* BASOP_NOGLOB */ } L_tmp = Mult_32_16( L_tmp, tmp ); /*Q(14-exp1+Qx) */ etmp = L_shl( L_tmp, sub( exp1, 14 ) ); /*Qx */ @@ -2769,18 +2721,10 @@ static Word16 attack_det_ivas_fx( /* o : attack flag exp1 = norm_s( tmp1 ); tmp = div_s( shl( 1, sub( 14, exp1 ) ), tmp1 ); /*Q(29-exp1) */ -#ifdef BASOP_NOGLOB L_tmp = L_shr_o( finc[attack], Qx, &Overflow ); /*Qx */ -#else /* BASOP_NOGLOB */ - L_tmp = L_shr( finc[attack], Qx ); /*Qx */ -#endif /* BASOP_NOGLOB */ FOR( i = 1; i < tmp1; i++ ) { -#ifdef BASOP_NOGLOB L_tmp = L_add_o( L_tmp, L_shr_o( finc[i + attack], Qx, &Overflow ), &Overflow ); /*Qx */ -#else /* BASOP_NOGLOB */ - L_tmp = L_add( L_tmp, L_shr( finc[i + attack], Qx ) ); /*Qx */ -#endif /* BASOP_NOGLOB */ } L_tmp = Mult_32_16( L_tmp, tmp ); /*Q(14-exp1+Qx) */ etmp2 = L_shl( L_tmp, sub( exp1, 14 ) ); /*Qx */ @@ -2825,19 +2769,24 @@ static Word16 attack_det_ivas_fx( /* o : attack flag Copy32( finc, finc_prev, attack1 ); /* compute mean energy before the attack */ - etmp = L_shr( sum32_fx( finc_prev, ATT_NSEG ), 5 ); /*ATT_NSEG == 32*/ + Word64 W_etmp = W_deposit32_l( finc_prev[0] ); + FOR( Word16 idx = 1; idx < ATT_NSEG; idx++ ) + { + W_etmp = W_add( W_etmp, W_deposit32_l( finc_prev[idx] ) ); + } + W_etmp = W_shr( W_etmp, 5 ); /*ATT_NSEG == 32*/ etmp2 = finc[attack1]; move32(); test(); test(); - if ( ( LT_32( L_shl( etmp, 4 ), etmp2 ) ) || ( LT_32( L_add( L_shl( etmp, 3 ), L_shl( etmp, 2 ) ), etmp2 ) && EQ_16( last_clas, UNVOICED_CLAS ) ) ) + if ( ( LT_64( W_shl( W_etmp, 4 ), W_deposit32_l( etmp2 ) ) ) || ( LT_64( W_add( W_shl( W_etmp, 3 ), W_shl( W_etmp, 2 ) ), W_deposit32_l( etmp2 ) ) && EQ_16( last_clas, UNVOICED_CLAS ) ) ) { attack = attack1; move16(); } test(); - if ( GT_32( *lt_finc, Mpy_32_32( etmp2, 107374182 /* 1.f/20 in Q31 */ ) ) || *last_strong_attack ) + if ( GT_32( L_shl_sat( *lt_finc, q_diff ), Mpy_32_32( etmp2, 107374182 /* 1.f/20 in Q31 */ ) ) || *last_strong_attack ) { attack = 0; move16(); @@ -2869,15 +2818,29 @@ static Word16 attack_det_ivas_fx( /* o : attack flag Copy32( finc, finc_prev, ATT_NSEG ); /* Calculating mean of finc */ - FOR( i = 0; i < ATT_NSEG; i++ ) + W_tmp = W_mult_32_16( finc[0], 1 ); // q_finc_prev+1 + FOR( i = 1; i < ATT_NSEG; i++ ) { - W_tmp = W_add( W_tmp, (Word64) finc[i] ); + W_tmp = W_mac_32_16( W_tmp, finc[i], 1 ); // q_finc_prev+1 } - mean_finc = W_extract_l( W_shr( W_tmp, 5 ) ); + /* mean = W_tmp / 32 and change the Q from q_finc_prev+1 to q_finc_prev + Mean value doesn't saturate, W_shl_sat_l is used only considering complexity */ + mean_finc = W_shl_sat_l( W_tmp, -Q6 ); // q_finc_prev+1 -> q_finc_prev //*lt_finc = 0.95f * *lt_finc + 0.05f * mean( finc, ATT_NSEG ); - *lt_finc = L_add( Mpy_32_32( *lt_finc, 2040109466 /* 0.95 in Q31 */ ), Mpy_32_32( mean_finc, 107374182 /* 0.05f in Q31 */ ) ); - move32(); + IF( q_diff > 0 ) /* q_finc_prev > q_lt_finc */ + { + mean_finc = L_shr( mean_finc, q_diff ); // q_lt_finc + *lt_finc = Madd_32_32( Mpy_32_32( *lt_finc, 2040109466 /* 0.95 in Q31 */ ), mean_finc, 107374182 /* 0.05f in Q31 */ ); // q_lt_finc + move32(); + } + ELSE + { + *lt_finc = Madd_32_32( Mpy_32_32( L_shl( *lt_finc, q_diff ), 2040109466 /* 0.95 in Q31 */ ), mean_finc, 107374182 /* 0.05f in Q31 */ ); // q_finc_prev + move32(); + *q_lt_finc = *q_finc_prev; + move16(); + } return attack; } @@ -2934,43 +2897,41 @@ static Word32 tonal_det_fx( IF( GT_32( S_mass, *tod_S_mass_prev ) ) { alpha = 1503238554; /* 0.7f in Q31 */ - move16(); } ELSE { alpha = 644245094; /* 0.3f in Q31 */ - move16(); } + move16(); + *tod_S_mass_prev = S_mass; + move32(); *tod_S_mass_lt = L_add( Mpy_32_32( alpha, *tod_S_mass_lt ), Mpy_32_32( L_sub( ONE_IN_Q31, alpha ), S_mass ) ); // Q22 + move32(); S_mass = *tod_S_mass_lt; - move16(); - move16(); - move16(); + move32(); /* updating adaptive decision threshold */ IF( GT_32( S_mass, *tod_thr_lt ) ) { *tod_thr_lt = L_sub( *tod_thr_lt, THR_MASS_STEP_DN_FX ); - move16(); } ELSE { *tod_thr_lt = L_add( *tod_thr_lt, THR_MASS_STEP_UP_FX ); - move16(); } + move16(); if ( GT_32( *tod_thr_lt, THR_MASS_MAX_FX ) ) { *tod_thr_lt = THR_MASS_MAX_FX; - move16(); } if ( LT_32( *tod_thr_lt, THR_MASS_MIN_FX ) ) { *tod_thr_lt = THR_MASS_MIN_FX; - move16(); } + move16(); return S_mass; /* Q22 */ } @@ -3003,15 +2964,15 @@ void ivas_smc_mode_selection_fx( Word32 ton; Word16 i; Word32 S_p2a, S_max, S_ave = 0; - Word32 thr_sp2a; move32(); + Word32 thr_sp2a; SP_MUS_CLAS_HANDLE hSpMusClas = st->hSpMusClas; /* initialization */ *attack_flag = 0; - st->sp_aud_decision2 = 0; move16(); + st->sp_aud_decision2 = 0; move16(); /* signal stability estimation */ @@ -3021,7 +2982,14 @@ void ivas_smc_mode_selection_fx( var_cor_calc_ivas_fx( st->old_corr_fx, &hSpMusClas->mold_corr_fx, hSpMusClas->var_cor_t_fx, &hSpMusClas->high_stable_cor ); /* attack detection */ - attack = attack_det_ivas_fx( inp, Q_new, st->clas, st->localVAD, st->coder_type, 0, st->element_mode, st->clas, hSpMusClas->finc_prev_fx, &hSpMusClas->lt_finc_fx, &hSpMusClas->last_strong_attack ); + IF( NE_16( shl( Q_new, 1 ), hSpMusClas->q_finc_prev ) ) + { + Scale_sig32( hSpMusClas->finc_prev_fx, ATT_NSEG, sub( shl( Q_new, 1 ), hSpMusClas->q_finc_prev ) ); + hSpMusClas->q_finc_prev = shl( Q_new, 1 ); + move16(); + } + attack = attack_det_ivas_fx( inp, Q_new, st->clas, st->localVAD, st->coder_type, 0, st->element_mode, st->clas, hSpMusClas->finc_prev_fx, + &hSpMusClas->q_finc_prev, &hSpMusClas->lt_finc_fx, &hSpMusClas->Q_lt_finc, &hSpMusClas->last_strong_attack ); /* tonal detector */ ton = tonal_det_fx( S_map, st->vad_flag, hSpMusClas->tod_S_map_lt_fx, &hSpMusClas->tod_thr_lt_fx, &hSpMusClas->tod_weight_fx, &hSpMusClas->tod_S_mass_prev_fx, &hSpMusClas->tod_S_mass_lt_fx ); // Q22 @@ -3063,33 +3031,27 @@ void ivas_smc_mode_selection_fx( /* select TCX to encode extremely peaky signals or strongly tonal signals */ st->sp_aud_decision1 = 1; st->sp_aud_decision2 = 1; - move16(); - move16(); } ELSE IF( smc_dec == SPEECH ) { /* select ACELP to encode speech */ st->sp_aud_decision1 = 0; st->sp_aud_decision2 = 0; - move16(); - move16(); } ELSE IF( EQ_16( smc_dec, SPEECH_OR_MUSIC ) ) { /* select GSC to encode "unclear" segments (classifier's score on the borderline) */ st->sp_aud_decision1 = 1; st->sp_aud_decision2 = 0; - move16(); - move16(); } ELSE { /* select TCX to encode music */ st->sp_aud_decision1 = 1; st->sp_aud_decision2 = 1; - move16(); - move16(); } + move16(); + move16(); /* change decision from GSC to ACELP/TCX in some special cases */ test(); @@ -3140,8 +3102,8 @@ void ivas_smc_mode_selection_fx( { /* do ACELP TC coding instead of GC/VC if onset has been already declared before */ st->sp_aud_decision1 = 0; - st->coder_type = TRANSITION; move16(); + st->coder_type = TRANSITION; move16(); } ELSE @@ -3150,10 +3112,10 @@ void ivas_smc_mode_selection_fx( { /* do ACELP TC coding also if attack is located in the last subframe */ st->sp_aud_decision1 = 0; - *attack_flag = add( attack, 1 ); - st->coder_type = TRANSITION; move16(); + *attack_flag = add( attack, 1 ); move16(); + st->coder_type = TRANSITION; move16(); } ELSE IF( GE_16( attack, ATT_SEG_LEN / 2 ) ) @@ -3161,8 +3123,8 @@ void ivas_smc_mode_selection_fx( /* do GSC coding if attack is located after the first quarter of the first subframe */ /* (pre-echo will be treated at the decoder side) */ *attack_flag = 31; - *attack_flag = add( attack, 1 ); move16(); + *attack_flag = add( attack, 1 ); move16(); } } @@ -3177,13 +3139,13 @@ void ivas_smc_mode_selection_fx( { /* change ACELP coder_type to TC if attack has been detected */ st->sp_aud_decision1 = 0; + move16(); st->sp_aud_decision2 = 0; + move16(); st->coder_type = TRANSITION; - *attack_flag = add( attack, 1 ); - move16(); - move16(); move16(); + *attack_flag = add( attack, 1 ); move16(); } @@ -3246,26 +3208,24 @@ void ivas_smc_mode_selection_fx( { /* music-like content */ st->GSC_IVAS_mode = 3; - move16(); } ELSE IF( st->tc_cnt > 0 ) { /* likely presence of an onset, GSC bit allocation will be more focused on LF */ st->GSC_IVAS_mode = 2; - move16(); } + move16(); test(); IF( EQ_16( st->coder_type_raw, UNVOICED ) && st->sp_aud_decision0 == 0 /*&& st->GSC_IVAS_mode < 3*/ ) { st->GSC_noisy_speech = 1; - move16(); } ELSE { st->GSC_noisy_speech = 0; - move16(); } + move16(); } /* set coder_type to AUDIO when GSC is selected (st->core will be set later in the decision matrix) */ @@ -3401,6 +3361,7 @@ static Word16 mode_decision_fx( } inv_len = 3277; /*Q15 */ + move16(); L_tmp = L_deposit_l( 0 ); FOR( i = 0; i < 10; i++ ) @@ -3676,11 +3637,7 @@ static void flux_fx( { IF( p2v_map[i] != 0 ) { -#ifdef BASOP_NOGLOB L_flux = L_add_sat( L_flux, abs_s( sub_sat( Bin_E[i], old_Bin_E[i] ) ) ); /*Q7 */ -#else - L_flux = L_add( L_flux, abs_s( sub( Bin_E[i], old_Bin_E[i] ) ) ); /*Q7 */ -#endif } if ( p2v_map[i] != 0 ) { @@ -3754,6 +3711,7 @@ static void spec_analysis_fx( Word16 p2v[65]; #ifdef BASOP_NOGLOB_DECLARE_LOCAL Flag Overflow = 0; + move32(); #endif /* find spectral peaks */ @@ -3837,11 +3795,8 @@ static void spec_analysis_fx( test(); IF( GT_16( peak_idx[k], valey_idx[i] ) && LT_16( peak_idx[k], valey_idx[i + 1] ) ) { -#ifdef BASOP_NOGLOB p2v[k] = sub_o( shl_o( peak[k], 1, &Overflow ), add_o( valley[i], valley[i + 1], &Overflow ), &Overflow ); -#else /* BASOP_NOGLOB */ - p2v[k] = sub( shl( peak[k], 1 ), add( valley[i], valley[i + 1] ) ); -#endif /* BASOP_NOGLOB */ + move16(); k = add( k, 1 ); } } @@ -3873,6 +3828,7 @@ static void music_mixed_classif_improv_fx( Word16 exp, frac, expn, fracn, expd, fracd, scale; Word16 tmp; Word32 L_tmp, ftmp, ftmp1, epsP_max = MIN_32; + move32(); SP_MUS_CLAS_HANDLE hSpMusClas = st->hSpMusClas; /* find sample with maximum absolute amplitude */ @@ -3964,7 +3920,7 @@ static void music_mixed_classif_improv_fx( test(); test(); test(); - IF( LT_16( old_cor, 24576 ) && LT_16( st->voicing_fx[0], 24576 ) && LT_16( st->voicing_fx[1], 24576 ) && GT_16( hSpMusClas->old_lt_diff_fx[0], 1280 ) ) + if ( LT_16( old_cor, 24576 ) && LT_16( st->voicing_fx[0], 24576 ) && LT_16( st->voicing_fx[1], 24576 ) && GT_16( hSpMusClas->old_lt_diff_fx[0], 1280 ) ) { percus_flag = 1; move16(); @@ -3977,7 +3933,7 @@ static void music_mixed_classif_improv_fx( test(); test(); test(); - IF( GT_16( sub( hSpMusClas->buf_etot_fx[3], hSpMusClas->buf_etot_fx[2] ), 1536 ) && GT_16( hSpMusClas->dec_mov_fx, 29491 ) && GT_16( sub( etot, st->lp_speech_fx ), 1280 ) && GT_16( hSpMusClas->old_lt_diff_fx[0], 640 ) ) + if ( GT_16( sub( hSpMusClas->buf_etot_fx[3], hSpMusClas->buf_etot_fx[2] ), 1536 ) && GT_16( hSpMusClas->dec_mov_fx, 29491 ) && GT_16( sub( etot, st->lp_speech_fx ), 1280 ) && GT_16( hSpMusClas->old_lt_diff_fx[0], 640 ) ) { hSpMusClas->attack_hangover = 3; move16(); @@ -4007,7 +3963,9 @@ static void music_mixed_classif_improv_fx( flux_fx( st->lgBin_E_fx, p2v_map, hSpMusClas->old_Bin_E_fx, hSpMusClas->buf_flux_fx, hSpMusClas->attack_hangover, hSpMusClas->dec_mov_fx ); hSpMusClas->attack_hangover = sub( hSpMusClas->attack_hangover, 1 ); + move16(); hSpMusClas->attack_hangover = s_max( hSpMusClas->attack_hangover, 0 ); + move16(); /* identify flux buffer buffering status */ len = 0; @@ -4113,11 +4071,7 @@ static void music_mixed_classif_improv_fx( expn = sub( sub( 30, expn ), Q_epsP - 4 ); expd = norm_l( ftmp ); -#ifdef BASOP_NOGLOB fracd = round_fx_sat( L_shl( ftmp, expd ) ); -#else - fracd = round_fx( L_shl( ftmp, expd ) ); -#endif expd = sub( sub( 30, expd ), sub( Q_epsP, 4 ) ); scale = shr( sub( fracd, fracn ), 15 ); @@ -4176,6 +4130,8 @@ static void music_mixed_classif_improv_fx( hSpMusClas->dec_mov_fx = add( mult_r( 31785, hSpMusClas->dec_mov_fx ), 983 ); /*Q15 */ hSpMusClas->dec_mov1_fx = add( mult_r( 31785, hSpMusClas->dec_mov1_fx ), 983 ); /*Q15 */ } + move16(); + move16(); } /* update long term unvoiced counter */ @@ -4191,24 +4147,27 @@ static void music_mixed_classif_improv_fx( { hSpMusClas->UV_cnt1 = add( hSpMusClas->UV_cnt1, 1 ); } + move16(); hSpMusClas->UV_cnt1 = s_min( hSpMusClas->UV_cnt1, 300 ); + move16(); hSpMusClas->UV_cnt1 = s_max( hSpMusClas->UV_cnt1, 0 ); + move16(); /**LT_UV_cnt1 = add(mult_r(29491,*LT_UV_cnt1),mult_r(3277,shl(*UV_cnt1,6)));*/ /* Q6 */ hSpMusClas->LT_UV_cnt1_fx = round_fx( L_mac( L_mult( 29491, hSpMusClas->LT_UV_cnt1_fx ), 3277, shl( hSpMusClas->UV_cnt1, 6 ) ) ); /*Q6 */ - + move16(); /* revert classification decision due to long-term unvoiced counter */ test(); test(); - IF( EQ_16( dec, 1 ) && LT_16( hSpMusClas->dec_mov1_fx, 6554 ) && LT_16( hSpMusClas->LT_UV_cnt1_fx, 12800 ) ) + if ( EQ_16( dec, 1 ) && LT_16( hSpMusClas->dec_mov1_fx, 6554 ) && LT_16( hSpMusClas->LT_UV_cnt1_fx, 12800 ) ) { dec = 0; move16(); } /* overwrite 1st stage speech/music decision to music */ - IF( EQ_16( dec, 1 ) ) + if ( EQ_16( dec, 1 ) ) { st->sp_aud_decision1 = 1; move16(); @@ -4240,6 +4199,7 @@ static void tonal_context_improv_fx( SP_MUS_CLAS_HANDLE hSpMusClas = st_fx->hSpMusClas; #ifdef BASOP_NOGLOB_DECLARE_LOCAL Flag Overflow = 0; + move16(); #endif IF( EQ_16( st_fx->last_codec_mode, MODE2 ) ) @@ -4283,11 +4243,7 @@ static void tonal_context_improv_fx( tmp = div_s( fraca, fracb ); exp1 = sub( expa, expb ); -#ifdef BASOP_NOGLOB tonality1 = L_shl_o( tmp, exp1, &Overflow ); -#else /* BASOP_NOGLOB */ - tonality1 = L_shl( tmp, exp1 ); -#endif } ELSE { @@ -4318,11 +4274,7 @@ static void tonal_context_improv_fx( tmp = div_s( fraca, fracb ); exp2 = sub( expa, expb ); -#ifdef BASOP_NOGLOB tonality2 = L_shl_o( tmp, exp2, &Overflow ); -#else - tonality2 = L_shl( tmp, exp2 ); -#endif } ELSE { @@ -4352,11 +4304,7 @@ static void tonal_context_improv_fx( tmp = div_s( fraca, fracb ); exp3 = sub( expa, expb ); -#ifdef BASOP_NOGLOB tonality3 = L_shl_o( tmp, exp3, &Overflow ); -#else - tonality3 = L_shl( tmp, exp3 ); -#endif } ELSE { @@ -4368,11 +4316,7 @@ static void tonal_context_improv_fx( /* voi_mean = 0.33f * (st->voicing_fx[0] + voicing[1] + voicing[2]); */ L_tmp = L_mult( st_fx->voicing_fx[0], 10923 ); L_tmp = L_mac( L_tmp, st_fx->voicing_fx[1], 10923 ); -#ifdef BASOP_NOGLOB // -dtx 12650 amrwb\Dtx3.INP voi_mean = mac_r_sat( L_tmp, st_fx->voicing_fx[2], 10923 ); /* Q15 */ -#else - voi_mean = mac_r( L_tmp, st_fx->voicing_fx[2], 10923 ); /* Q15 */ -#endif test(); IF( EQ_16( hVAD->hangover_cnt, 10 ) && EQ_16( st_fx->vad_flag, 1 ) ) { @@ -4396,6 +4340,9 @@ static void tonal_context_improv_fx( /* long-term tonality measure */ hSpMusClas->lt_tonality = L_add( Mult_32_16( hSpMusClas->lt_tonality, 16384 ), Mult_32_16( tonality, 16384 ) ); } + move16(); + move16(); + move16(); /* Pitch difference w.r.t to past 3 frames */ lt_pitch_diff = abs_s( sub( hSpMusClas->lt_corr_pitch[0], st_fx->pitch[0] ) ); @@ -4473,6 +4420,7 @@ static void tonal_context_improv_fx( exp = sub( 30, add( exp, 16 ) ); L_tmp = Mpy_32_16( exp, tmp, 15783 ); /*19 //3945, 0.2*log10(2), Q18 */ hSpMusClas->tonality2_buf_fx[HANG_LEN_INIT - 1] = round_fx( L_shl( L_tmp, 11 ) ); /*14 */ + move16(); /* t2 = std( st->tonality2_buf, HANG_LEN_INIT ); */ t2_fx = std_fx( hSpMusClas->tonality2_buf_fx, HANG_LEN_INIT ); /*14 */ @@ -4484,6 +4432,7 @@ static void tonal_context_improv_fx( L_tmp = Mpy_32_16( exp, tmp, 15783 ); /*19 //3945, 0.2*log10(2), Q18 */ hSpMusClas->tonality3_buf_fx[HANG_LEN_INIT - 1] = round_fx( L_shl( L_tmp, 11 ) ); /*14 */ t3_fx = std_fx( hSpMusClas->tonality3_buf_fx, HANG_LEN_INIT ); /*14 */ + move16(); /* tL = 0.2f*(float)log10(st->lt_tonality); */ exp = norm_l( hSpMusClas->lt_tonality ); @@ -4495,6 +4444,7 @@ static void tonal_context_improv_fx( /* calculate standard deviation of residual LP energy */ Copy( hSpMusClas->LPCErr_buf_fx + 1, hSpMusClas->LPCErr_buf_fx, HANG_LEN_INIT - 1 ); hSpMusClas->LPCErr_buf_fx[HANG_LEN_INIT - 1] = LPCErr; + move16(); /* err = std( st->LPCErr_buf, HANG_LEN_INIT ); */ err_fx = std_fx( hSpMusClas->LPCErr_buf_fx, HANG_LEN_INIT ); @@ -4535,6 +4485,7 @@ static void tonal_context_improv_fx( IF( hSpMusClas->lt_music_hangover > 0 ) { hSpMusClas->lt_music_hangover = sub( hSpMusClas->lt_music_hangover, 1 ); + move16(); } /* state machine for strong speech */ @@ -4572,6 +4523,7 @@ static void tonal_context_improv_fx( IF( hSpMusClas->lt_speech_hangover > 0 ) { hSpMusClas->lt_speech_hangover = sub( hSpMusClas->lt_speech_hangover, 1 ); + move16(); } /* final decision */ @@ -4618,10 +4570,14 @@ static void detect_sparseness_fx( Word16 S1[128]; Word16 i, j; Word16 hb_sp_high_flag = 0; + move16(); Word16 lb_sp_high_flag = 0; + move16(); Word16 sparse; Word16 tmp_buf[4]; Word16 Mlpe = 0, Mv = 0, Msp; + move16(); + move16(); SP_MUS_CLAS_HANDLE hSpMusClas = st_fx->hSpMusClas; Copy( st_fx->lgBin_E_fx, S1, 128 ); @@ -4753,12 +4709,12 @@ static void detect_sparseness_fx( IF( tmp == 0 ) { hSpMusClas->hf_spar_buf_fx[HANG_LEN_INIT - 1] = 0; - move16(); } ELSE { hSpMusClas->hf_spar_buf_fx[HANG_LEN_INIT - 1] = div_s( tmp, sumh ); } + move16(); tmp = 0; move16(); @@ -4853,6 +4809,7 @@ static void detect_sparseness_fx( if ( EQ_16( st_fx->bwidth, WB ) ) { tmp = 90; + move16(); } IF( GT_16( sparse, tmp ) ) @@ -4915,7 +4872,7 @@ static void detect_sparseness_fx( hSpMusClas->gsc_hangover = 1; move16(); } - ELSE IF( EQ_16( hSpMusClas->gsc_hangover, 1 ) && !( st_fx->sp_aud_decision1 == 0 && st_fx->sp_aud_decision2 == 1 ) ) + ELSE IF( EQ_16( hSpMusClas->gsc_hangover, 1 ) && !( st_fx->sp_aud_decision1 == 0 && EQ_16( st_fx->sp_aud_decision2, 1 ) ) ) { IF( LT_16( abs_s( sub( sparse, mean_fx( &hSpMusClas->sparse_buf_fx[HANG_LEN_INIT - 1 - hSpMusClas->gsc_cnt], hSpMusClas->gsc_cnt ) ) ), 7 ) ) { diff --git a/lib_enc/stat_enc.h b/lib_enc/stat_enc.h index 73cb96e15ba3e502148ea05cc0347b59c7c8eeaf..41c6b04680eefa6ea2e268e92280e90b4179450d 100644 --- a/lib_enc/stat_enc.h +++ b/lib_enc/stat_enc.h @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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,7 +43,7 @@ #include "stat_com.h" #include "cnst.h" #include "ivas_cnst.h" -#include "stat_dec.h" /* Compilation switches */ + /*------------------------------------------------------------------------------------------* * Indice @@ -51,9 +51,9 @@ typedef struct { - int16_t id; /* id of the indice */ - uint16_t value; /* value of the quantized indice */ - int16_t nb_bits; /* number of bits used for the quantization of the indice */ + Word16 id; /* id of the indice */ + UWord16 value; /* value of the quantized indice */ + Word16 nb_bits; /* number of bits used for the quantization of the indice */ } Indice, *INDICE_HANDLE; typedef struct @@ -84,12 +84,12 @@ typedef struct typedef struct bitstream_enc_data_structure { - int16_t nb_ind_tot; /* total number of indices already written */ - int16_t nb_bits_tot; /* total number of bits already written */ - Indice *ind_list; /* list of indices */ - int16_t *ivas_max_num_indices; /* maximum total number of indices in the list */ - Indice **ivas_ind_list_zero; /* beginning of the buffer of indices */ - void *st_ivas; /* IVAS encoder structure */ + Word16 nb_ind_tot; /* total number of indices already written */ + Word16 nb_bits_tot; /* total number of bits already written */ + Indice *ind_list; /* list of indices */ + Word16 *ivas_max_num_indices; /* maximum total number of indices in the list */ + Indice **ivas_ind_list_zero; /* beginning of the buffer of indices */ + void *st_ivas; /* IVAS encoder structure */ // Word16 nb_bits_tot_fx; /* total number of bits already written */ // Indice *ind_list_fx; /* list of indices */ Word16 next_ind_fx; /* pointer to the next empty slot in the list of indices */ @@ -113,9 +113,9 @@ typedef struct signal_buffers_enc_data_structure Word16 old_inp_12k8_fx[L_INP_MEM]; /* memory of input signal at 12.8kHz */ Word16 old_inp_16k_fx[L_INP_MEM]; /* ACELP@16kHz - memory of input signal @16 kHz */ - Word16 buf_speech_enc_pe[L_PAST_MAX_32k + L_FRAME32k + L_NEXT_MAX_32k]; + Word16 buf_speech_enc_pe[L_PAST_MAX_32k + L_FRAME32k + L_NEXT_MAX_32k]; // exp_buf_speech_enc_pe Word16 buf_synth[OLD_SYNTH_SIZE_ENC + L_FRAME32k]; - Word16 buf_speech_enc[L_PAST_MAX_32k + L_FRAME32k + L_NEXT_MAX_32k]; + Word16 buf_speech_enc[L_PAST_MAX_32k + L_FRAME32k + L_NEXT_MAX_32k]; // exp_buf_speech_enc Word16 buf_wspeech_enc[L_FRAME16k + L_SUBFR + L_FRAME16k + L_NEXT_MAX_16k + 320]; /*normally there is a lookahead for 12k8 and 16k but L_FRAME_MAX=L_FRAME_16K+L_NEXT_16k*/ /* increased by 320 to avoid memory overlap in ivas_find_wsp() and also to accomodate for the wspeech_enc */ } SIGNAL_BUFFERS_ENC_DATA, *SIGNAL_BUFFERS_ENC_HANDLE; @@ -128,9 +128,9 @@ typedef struct signal_buffers_enc_data_structure /* Delay buffer: Used to buffer input samples and to define the subblock size of a transient detector. */ typedef struct { - int16_t nSubblockSize; /* Subblock size of a transient detector that uses this delay buffer. */ + Word16 nSubblockSize; /* Subblock size of a transient detector that uses this delay buffer. */ Word16 buffer[L_FRAME48k / NSUBBLOCKS]; - int16_t nDelay; /* Size of the delay buffer in use. Maximum delay from all users of this buffer. */ + Word16 nDelay; /* Size of the delay buffer in use. Maximum delay from all users of this buffer. */ } DelayBuffer; @@ -138,11 +138,11 @@ typedef struct typedef struct { DelayBuffer *pDelayBuffer; /* Delay buffer. */ - Word32 subblockNrg[NSUBBLOCKS + MAX_TD_DELAY]; // IVAS Q0 - Word32 accSubblockNrg[NSUBBLOCKS + MAX_TD_DELAY + 1]; // IVAS Q0 + Word32 subblockNrg[NSUBBLOCKS + MAX_TD_DELAY]; // IVAS Q(-1) + Word32 accSubblockNrg[NSUBBLOCKS + MAX_TD_DELAY + 1]; // IVAS Q(-1) Word16 subblockNrgChange[NSUBBLOCKS + MAX_TD_DELAY]; /* EVS: Q7(15 - SUBBLOCK_NRG_CHANGE_E) */ /* IVAS: Q3 */ - int16_t nDelay; /* Size of the delay buffer in use, as number of subblocks. Maximum delay from all users of this buffer. */ - int16_t nPartialDelay; /* Delay of the input (modulo pDelayBuffer->nSubblockSize), nPartialDelay <= pDelayBuffer->nDelay. */ + Word16 nDelay; /* Size of the delay buffer in use, as number of subblocks. Maximum delay from all users of this buffer. */ + Word16 nPartialDelay; /* Delay of the input (modulo pDelayBuffer->nSubblockSize), nPartialDelay <= pDelayBuffer->nDelay. */ /* Decay factor for the recursive accumulation */ Word16 facAccSubblockNrg; @@ -152,27 +152,25 @@ typedef struct Word16 firState2; Word16 q_firState; - uint16_t ramp_up_flag; /* bit map flags to indicate a ramp up in beginning of TCX frame */ + UWord16 ramp_up_flag; /* bit map flags to indicate a ramp up in beginning of TCX frame */ } SubblockEnergies; /* Attack detection function. */ -typedef void ( *TCheckSubblocksForAttack )( const float *pSubblockNrg, const float *pAccSubblockNrg, int16_t nSubblocks, int16_t nPastSubblocks, float attackRatioThreshold, int16_t *pbIsAttackPresent, int16_t *pAttackIndex ); typedef void ( *TCheckSubblocksForAttack_fx )( Word32 const *pSubblockNrg, Word32 const *pAccSubblockNrg, Word16 nSubblocks, Word16 nPastSubblocks, Word16 attackRatioThreshold, Word16 *pbIsAttackPresent, Word16 *pAttackIndex ); /* Transient detector. */ typedef struct TransientDetector { SubblockEnergies *pSubblockEnergies; /* Subblock energies used in this transient detector. */ - int16_t nDelay; /* Delay of the transient detector in number of subblocks, nDelay <= pSubblockEnergies->nDelay. */ - int16_t nSubblocksToCheck; /* Number of subblocks to check for transients. */ - TCheckSubblocksForAttack CheckSubblocksForAttack; /* Function for checking a presence of an attack. */ + Word16 nDelay; /* Delay of the transient detector in number of subblocks, nDelay <= pSubblockEnergies->nDelay. */ + Word16 nSubblocksToCheck; /* Number of subblocks to check for transients. */ TCheckSubblocksForAttack_fx CheckSubblocksForAttack_fx; /* Function for checking a presence of an attack. */ Word16 attackRatioThreshold; /* Attack ratio threshold Q11 */ - int16_t bIsAttackPresent; /* True when an attack was detected. */ - int16_t prev_bIsAttackPresent; /* True if an attack was detected in the previous frame. */ - int16_t attackIndex; /* The index of an attack. */ + Word16 bIsAttackPresent; /* True when an attack was detected. */ + Word16 prev_bIsAttackPresent; /* True if an attack was detected in the previous frame. */ + Word16 attackIndex; /* The index of an attack. */ } TransientDetector; /* Transient detection: Holds all transient detectors and buffers used by them. */ @@ -191,25 +189,25 @@ typedef struct TransientDetection_structure typedef struct vad_structure { - int16_t nb_active_frames; - int16_t hangover_cnt; - int16_t nb_active_frames_he; - int16_t hangover_cnt_he; - int32_t vad_flag_reg_H; - int32_t vad_flag_reg_L; - int32_t vad_prim_reg; - - int16_t vad_flag_cnt_50; - int16_t vad_prim_cnt_16; - - int16_t hangover_cnt_dtx; - int16_t hangover_cnt_music; + Word16 nb_active_frames; + Word16 hangover_cnt; + Word16 nb_active_frames_he; + Word16 hangover_cnt_he; + Word32 vad_flag_reg_H; + Word32 vad_flag_reg_L; + Word32 vad_prim_reg; + + Word16 vad_flag_cnt_50; + Word16 vad_prim_cnt_16; + + Word16 hangover_cnt_dtx; + Word16 hangover_cnt_music; Word16 bcg_flux_fx; // Q4 - int16_t soft_hangover; - int16_t voiced_burst; - int16_t bcg_flux_init; - int16_t nb_active_frames_he1; - int16_t hangover_cnt_he1; + Word16 soft_hangover; + Word16 voiced_burst; + Word16 bcg_flux_init; + Word16 nb_active_frames_he1; + Word16 hangover_cnt_he1; Word16 prim_act_quick_fx; /*Q15 */ /* Noise estimator - primary activity quick */ Word16 prim_act_slow_fx; /*Q15 */ /* Noise estimator - primary activity slow */ Word16 prim_act_fx; /*Q15 */ /* Noise estimator - primary activity slow rise quick fall */ @@ -217,22 +215,22 @@ typedef struct vad_structure Word16 prim_act_slow_he_fx; /*Q15 */ /* Noise estimator - primary activity slow */ Word16 prim_act_he_fx; /*Q15 */ /* Q15 Noise estimator - primary activity slow rise quick fall */ - int16_t spectral_tilt_reset; - int16_t consec_inactive; + Word16 spectral_tilt_reset; + Word16 consec_inactive; Word16 ra_deltasum_fx; - int16_t trigger_SID; + Word16 trigger_SID; Word16 snr_sum_vad_fx; /*Q15 */ Word16 running_avg_fx; /*Q15 */ Word32 L_snr_sum_vad_fx; /*Q4*/ - int16_t hangover_terminate_flag; /* CNG and DTX - flag indicating whether to early terminate DTX hangover */ - int16_t vad_flag; /* VAD flag */ + Word16 hangover_terminate_flag; /* CNG and DTX - flag indicating whether to early terminate DTX hangover */ + Word16 vad_flag; /* VAD flag */ } VAD_DATA, *VAD_HANDLE; typedef struct cldfb_vad_structure { - int16_t bw_index; /* index of band width */ + Word16 bw_index; /* index of band width */ /* feature */ Word16 sp_center[SP_CENTER_NUM]; /* spectral center*/ @@ -248,8 +246,8 @@ typedef struct cldfb_vad_structure Word32 t_bg_energy; /* time background energy of several frames*/ Word16 scale_t_bg_energy; /* the Scaling of t_bg_energy*/ T_VAD_EXP t_bg_energy_sum; /* number of time background energy*/ - int16_t tbg_energy_count; /* sum of time background energy of several frames*/ - int16_t bg_update_count; /* time of background update*/ + Word16 tbg_energy_count; /* sum of time background energy of several frames*/ + Word16 bg_update_count; /* time of background update*/ Word32 frame_energy_smooth; /* smoothed energy of several frames*/ Word16 frame_energy_smooth_scale; /* the Scaling of frame_energy_smooth*/ @@ -268,14 +266,14 @@ typedef struct cldfb_vad_structure Word16 fg_energy_scale; /* the Scaling of fg_energy*/ Word32 bg_energy; /* background energy sum */ Word16 bg_energy_scale; /* the Scaling of bg_energy*/ - int16_t fg_energy_count; /* number of the foreground energy frame */ - int16_t bg_energy_count; /* number of the background energy frame */ + Word16 fg_energy_count; /* number of the foreground energy frame */ + Word16 bg_energy_count; /* number of the background energy frame */ Word32 fg_energy_est_start; /* flag by that indicate whether if estimate energy*/ - int16_t speech_flag; /* residual number of hangover 1 */ - int16_t continuous_noise_num; /* time of continuous noise frames*/ - int16_t continuous_speech_num; /* time of continuous speech frames*/ - int16_t continuous_speech_num2; /* time 2 of continuous speech frames*/ - int16_t frameloop; /* number of frame*/ + Word16 speech_flag; /* residual number of hangover 1 */ + Word16 continuous_noise_num; /* time of continuous noise frames*/ + Word16 continuous_speech_num; /* time of continuous speech frames*/ + Word16 continuous_speech_num2; /* time 2 of continuous speech frames*/ + Word16 frameloop; /* number of frame*/ Word16 tonality_rate3; /* tonality rate*/ Word16 music_background_rate; /* music background rate*/ Word32 lt_noise_sp_center_diff_sum; /* different sum of long time noise sp_center*/ @@ -283,10 +281,10 @@ typedef struct cldfb_vad_structure Word16 lt_noise_sp_center0; /* long time noise sp_center0*/ Word16 lt_noise_sp_center3; /* long time noise sp_center3*/ Word32 lt_bg_highf_eng; /* average of long time high frequency energy*/ - int16_t update_num_with_snr; /* the number of the background update with SNR*/ - int16_t update_count; - int16_t warm_hang_num; /* the number of hangover for warm up*/ - int16_t vad_flag_for_bk_update; + Word16 update_num_with_snr; /* the number of the background update with SNR*/ + Word16 update_count; + Word16 warm_hang_num; /* the number of hangover for warm up*/ + Word16 vad_flag_for_bk_update; } T_CldfbVadState, *VAD_CLDFB_HANDLE; @@ -326,7 +324,7 @@ typedef struct td_cng_enc_structure Word16 cng_buf_cnt; /* CNG and DTX - Counter of buffered CNG parameters */ Word16 cng_exc2_buf[HO_HIST_SIZE * L_FFT]; /* CNG and DTX - exc2 buffer for storing */ Word16 cng_Qexc_buf[HO_HIST_SIZE]; /* CNG and DTX - Q_exc buffer for storing */ - int32_t cng_brate_buf[HO_HIST_SIZE]; /* CNG and DTX - buffer for storing last_active_brate */ + Word32 cng_brate_buf[HO_HIST_SIZE]; /* CNG and DTX - buffer for storing last_active_brate */ Word16 CNG_att_fx; /* CNG and DTX - attenuation factor for CNG, in dB Q7 */ Word16 ho_16k_lsp[HO_HIST_SIZE]; /* CNG and DTX - 16k LSPs flags */ Word16 act_cnt2; /* CNG and DTX - counter of active frames for CNG_mode switching */ @@ -432,23 +430,23 @@ typedef struct dtx_enc_structure typedef struct igfscfenc_public_data_struct { - int16_t ptrBitIndex; - int16_t bitCount; - int16_t prev[64]; /* no more than 64 SCFs for the IGF energy envelope of one block */ - int16_t prevSave[64]; - int16_t scfCountLongBlock[IGF_NOF_GRIDS]; - int16_t t; - int16_t Tsave; - int16_t contex_saved; - const uint16_t *cf_se00; - const uint16_t *cf_se01; - int16_t cf_off_se01; - const uint16_t *cf_se02; - const int16_t *cf_off_se02; - const uint16_t *cf_se10; - int16_t cf_off_se10; - const uint16_t *cf_se11; - const int16_t *cf_off_se11; + Word16 ptrBitIndex; + Word16 bitCount; + Word16 prev[64]; /* no more than 64 SCFs for the IGF energy envelope of one block */ + Word16 prevSave[64]; + Word16 scfCountLongBlock[IGF_NOF_GRIDS]; + Word16 t; + Word16 Tsave; + Word16 contex_saved; + const UWord16 *cf_se00; + const UWord16 *cf_se01; + Word16 cf_off_se01; + const UWord16 *cf_se02; + const Word16 *cf_off_se02; + const UWord16 *cf_se10; + Word16 cf_off_se10; + const UWord16 *cf_se11; + const Word16 *cf_off_se11; Tastat acState; TastatEnc acState_fx; @@ -566,6 +564,9 @@ typedef struct noise_estimation_structure Word16 Etot_st_est_fx; /* Q8 Noise estimation - short term estimate of E{ Etot } */ Word16 Etot_sq_st_est_fx; /* Q2 Noise estimation - short term estimate of E{ Etot^2 } */ + Word32 L_Etot_st_est_fx; /* Q23 Noise estimation - short term estimate of E{ Etot } */ + Word32 L_Etot_sq_st_est_fx; /* Q16 Noise estimation - short term estimate of E{ Etot^2 } */ + Word16 aEn_inac_cnt; } NOISE_EST_DATA, *NOISE_EST_HANDLE; @@ -585,10 +586,11 @@ typedef struct sp_mus_clas_structure Word16 past_epsP2_fx; /* Q10 */ Word16 inact_cnt; Word16 wdrop_fx; /* Q9 */ + Word32 wdrop_32fx; /* Q19 */ Word16 wrise_fx; /* Q9 */ Word16 wdlp_0_95_sp_fx; /* EVS - Q8 */ Word32 wdlp_0_95_sp_32fx; /* IVAS - Q24 */ - Word32 wdlp_xtalk_fx; /* Q19 */ + Word32 wdlp_xtalk_fx; /* Q25 */ Word16 sp_mus_state; Word16 past_dec[HANG_LEN - 1]; /* Speech/music classifier - buffer of past binary decisions */ Word16 past_dlp_fx[HANG_LEN - 1]; /* Speech/music classifier - buffer of past non-binary decisions Q9 */ @@ -640,8 +642,10 @@ typedef struct sp_mus_clas_structure Word16 UV_cnt1; Word16 LT_UV_cnt1_fx; /* Q6 */ - Word32 finc_prev_fx[ATT_NSEG]; /* strong attack detection - previous finc, (Q_new * 2) */ - Word32 lt_finc_fx; /* strong attack detection - long-term finc energy, (Q_new * 2) */ + Word32 finc_prev_fx[ATT_NSEG]; /* strong attack detection - previous finc, (q_finc_prev) */ + Word16 q_finc_prev; + Word32 lt_finc_fx; /* strong attack detection - long-term finc energy, Q_lt_finc */ + Word16 Q_lt_finc; Word16 last_strong_attack; /* strong attack detection - last strong attack flag */ Word32 tod_lt_Bin_E_fx[TOD_NSPEC]; /* tonal detector - long-term energy spectrum, Q_tod_lt_Bin_E */ Word16 Q_tod_lt_Bin_E; @@ -743,21 +747,21 @@ typedef struct acelp_cbkcorr_structure typedef struct gsc_enc_structure { - int16_t seed_tcx; /* AC mode (GSC) - seed for noise fill */ - int16_t cor_strong_limit; /* AC mode (GSC) - Indicator about high spectral correlation per band */ - int16_t mem_last_pit_band; /* AC mode (GSC) - memory of the last band where pitch contribution was significant */ + Word16 seed_tcx; /* AC mode (GSC) - seed for noise fill */ + Word16 cor_strong_limit; /* AC mode (GSC) - Indicator about high spectral correlation per band */ + Word16 mem_last_pit_band; /* AC mode (GSC) - memory of the last band where pitch contribution was significant */ Word16 mem_w0_tmp_fx; Word16 mem_syn_tmp_fx[M]; Word16 mid_dyn_fx; /* AC mode (GSC) - signal dynamic Q7 */ - int16_t noise_lev; /* AC mode (GSC) - noise level */ - int16_t past_dyn_dec; /* AC mode (GSC) - Past noise level decision */ + Word16 noise_lev; /* AC mode (GSC) - noise level */ + Word16 past_dyn_dec; /* AC mode (GSC) - Past noise level decision */ Word32 Last_frame_ener_fx; /* AC mode (GSC) - Last frame energy */ - int16_t pit_exc_hangover; /* AC mode (GSC) - Hangover for the time contribution switching */ + Word16 pit_exc_hangover; /* AC mode (GSC) - Hangover for the time contribution switching */ Word16 last_exc_dct_in_fx[L_FRAME16k]; /* AC mode (GSC) - previous exciation */ Word16 Q_last_exc_dct_in; - Word16 last_ener_fx; /* AC mode (GSC) - previous energy Q0 */ - int16_t last_bitallocation_band[6]; /* AC mode (GSC) - previous bit allocation of each band */ - Word16 lt_gpitch_fx; /* Q15 */ + Word16 last_ener_fx; /* AC mode (GSC) - previous energy Q0 */ + Word16 last_bitallocation_band[6]; /* AC mode (GSC) - previous bit allocation of each band */ + Word16 lt_gpitch_fx; /* Q15 */ } GSC_ENC_DATA, *GSC_ENC_HANDLE; @@ -798,14 +802,14 @@ typedef struct hq_enc_structure /* PVQ range coder state */ typedef struct pvq_enc_structure { - uint32_t rc_low; - uint32_t rc_range; - int16_t rc_cache; - int16_t rc_carry; - int16_t rc_carry_count; - int16_t rc_num_bits; - int16_t rc_tot_bits; - int16_t rc_offset; + UWord32 rc_low; + UWord32 rc_range; + Word16 rc_cache; + Word16 rc_carry; + Word16 rc_carry_count; + Word16 rc_num_bits; + Word16 rc_tot_bits; + Word16 rc_offset; } PVQ_ENC_DATA, *PVQ_ENC_HANDLE; @@ -832,33 +836,33 @@ typedef struct sc_vbr_enc_structure Word16 nelp_lp_fit_mem[NELP_LP_ORDER * 2]; /* Q(prev_Q_new) */ Word32 bp1_filt_mem_nb_fx[14]; /* Q(qprevGain_fx) */ - int16_t nelp_enc_seed; + Word16 nelp_enc_seed; Word16 nelp_gain_mem_fx; /* Q0 */ - int16_t last_nelp_mode; - int16_t nelp_mode; + Word16 last_nelp_mode; + Word16 nelp_mode; Word16 qprevIn_fx; Word16 qprevGain_fx; /* PPP variables */ - int16_t pppcountE; - int16_t bump_up; - int16_t last_ppp_mode; - int16_t last_last_ppp_mode; - int16_t ppp_mode; + Word16 pppcountE; + Word16 bump_up; + Word16 last_ppp_mode; + Word16 last_last_ppp_mode; + Word16 ppp_mode; Word16 prev_ppp_gain_pit_fx; /* Q14 */ Word16 prev_tilt_code_fx; /* Q15 */ /* voiced encoder variables */ - int16_t firstTime_voicedenc; + Word16 firstTime_voicedenc; /* DTFS variables */ Word16 dtfs_enc_a_fx[MAXLAG_WI]; /* Q(dtfs_enc_Q) */ Word16 dtfs_enc_b_fx[MAXLAG_WI]; /* Q(dtfs_enc_Q) */ - int16_t dtfs_enc_lag; - int16_t dtfs_enc_nH; - int16_t dtfs_enc_nH_4kHz; + Word16 dtfs_enc_lag; + Word16 dtfs_enc_nH; + Word16 dtfs_enc_nH_4kHz; Word16 dtfs_enc_upper_cut_off_freq_of_interest_fx; /* Q0 */ Word16 dtfs_enc_upper_cut_off_freq_fx; /* Q0 */ Word16 dtfs_enc_Q; @@ -870,23 +874,23 @@ typedef struct sc_vbr_enc_structure Word16 lasterbE_fx[NUM_ERB_WB]; /* Previous Amplitude spectrum (ERB) Q13 */ Word16 Q_prev_cw_en_fx; - int16_t mode_QQF; - int16_t rate_control; + Word16 mode_QQF; + Word16 rate_control; Word16 SNR_THLD_fx; /* Q8 */ - int16_t Q_to_F; - int16_t pattern_m; - int16_t patterncount; - int16_t Last_Resort; - int16_t numactive; /* keep the count of the frames inside current 600 frame block */ + Word16 Q_to_F; + Word16 pattern_m; + Word16 patterncount; + Word16 Last_Resort; + Word16 numactive; /* keep the count of the frames inside current 600 frame block */ Word32 sum_of_rates_fx; /*Q=13 sum of the rates of past 600 active frames*/ Word32 global_avr_rate_fx; /*Q=13 global rate upto current time. recorded a (rate in kbps) *6000*/ - int16_t global_frame_cnt; /* 600 active frame block count. Used to update the global rate */ - int16_t set_ppp_generic; - int16_t avoid_HQ_VBR_NB; + Word16 global_frame_cnt; /* 600 active frame block count. Used to update the global rate */ + Word16 set_ppp_generic; + Word16 avoid_HQ_VBR_NB; - int16_t vbr_generic_ho; - int16_t Local_VAD; - int16_t last_7k2_coder_type; + Word16 vbr_generic_ho; + Word16 Local_VAD; + Word16 last_7k2_coder_type; } SC_VBR_ENC_DATA, *SC_VBR_ENC_HANDLE; @@ -904,7 +908,7 @@ typedef struct amrwb_io_enc_structure Word16 mem_hp400_enc_fx[6]; Word16 mem_hf_enc_fx[L_FIR - 1]; Word16 mem_syn_hf_enc_fx[M]; - int16_t seed2_enc; + Word16 seed2_enc; } AMRWB_IO_ENC_DATA, *AMRWB_IO_ENC_HANDLE; @@ -938,7 +942,7 @@ typedef struct td_bwe_enc_structure Word16 state_syn_shbexc_fx[L_SHB_LAHEAD]; /* Q(prev_Q_bwe_exc - 16) */ Word16 state_lpc_syn_fx[LPC_SHB_ORDER]; /* Q(prev_Q_bwe_exc - 16) */ Word16 old_bwe_exc_fx[PIT16k_MAX * 2]; /*Q_exc*/ - int16_t bwe_seed[2]; + Word16 bwe_seed[2]; Word32 bwe_non_lin_prev_scale_fx; /* Q30 */ Word16 old_bwe_exc_extended_fx[NL_BUFF_OFFSET]; /* Q(prev_Q_bwe_exc - 16) */ Word16 syn_overlap_fx[L_SHB_LAHEAD]; /* overlap buffer used to Adjust SHB Frame Gain */ @@ -958,7 +962,7 @@ typedef struct td_bwe_enc_structure Word16 shb_inv_filt_mem_fx[LPC_SHB_ORDER]; /* Q(Q_shb_spch) */ Word16 lsp_shb_spacing_fx[3]; /* Q15 */ Word16 prev_swb_GainShape_fx; /* Q15 */ - int16_t prev_frGainAtten; + Word16 prev_frGainAtten; Word16 prev_wb_GainShape; /* Q15 */ Word16 swb_lsp_prev_interp_fx[LPC_SHB_ORDER]; /* Q15 */ @@ -967,25 +971,25 @@ typedef struct td_bwe_enc_structure Word16 fb_tbe_demph_fx; Word16 tilt_mem_fx; /* Q12 */ - int16_t prev_coder_type; + Word16 prev_coder_type; Word16 prev_lsf_diff_fx[LPC_SHB_ORDER - 2]; /* Q15 */ Word16 prev_tilt_para_fx; /* Q10 */ Word16 cur_sub_Aq_fx[M + 1]; /* Q12 */ /* quantized data */ - int16_t lsf_idx[NUM_Q_LSF]; - int16_t m_idx; - int16_t grid_idx; - int16_t idxSubGains; - int16_t idxFrameGain; - int16_t idx_shb_fr_gain; - int16_t idx_res_gs[NB_SUBFR16k]; - int16_t idx_mixFac; - - int16_t lsf_WB; - int16_t gFrame_WB; - - int16_t idxGain; + Word16 lsf_idx[NUM_Q_LSF]; + Word16 m_idx; + Word16 grid_idx; + Word16 idxSubGains; + Word16 idxFrameGain; + Word16 idx_shb_fr_gain; + Word16 idx_res_gs[NB_SUBFR16k]; + Word16 idx_mixFac; + + Word16 lsf_WB; + Word16 gFrame_WB; + + Word16 idxGain; Word16 dec_2_over_3_mem_fx[L_FILT_2OVER3]; Word16 dec_2_over_3_mem_lp_fx[6]; @@ -1005,11 +1009,14 @@ typedef struct td_bwe_enc_structure typedef struct fd_bwe_enc_structure { - Word16 new_input_hp_fx[NS2SA( 16000, ACELP_LOOK_NS + DELAY_FD_BWE_ENC_NS + DELAY_FIR_RESAMPL_NS - DELAY_CLDFB_NS )]; // q0 - Word16 old_input_fx[NS2SA( 48000, DELAY_FD_BWE_ENC_NS + DELAY_FIR_RESAMPL_NS )]; // q0 - Word16 old_input_wb_fx[NS2SA( 16000, DELAY_FD_BWE_ENC_NS )]; /* Q(-1) */ - Word16 old_input_lp_fx[NS2SA( 16000, ACELP_LOOK_NS + DELAY_FD_BWE_ENC_NS )]; // st->hBWE_FD->prev_Q_input_lp - Word16 old_syn_12k8_16k_fx[NS2SA( 16000, DELAY_FD_BWE_ENC_NS )]; // st->Q_syn + Word16 new_input_hp_fx[NS2SA( 16000, ACELP_LOOK_NS + DELAY_FD_BWE_ENC_NS + DELAY_FIR_RESAMPL_NS - DELAY_CLDFB_NS )]; // Q_new_input_hp +#ifdef FIX_ISSUE_1230 + Word16 Q_new_input_hp; +#endif + Word16 old_input_fx[NS2SA( 48000, DELAY_FD_BWE_ENC_NS + DELAY_FIR_RESAMPL_NS )]; // q0 + Word16 old_input_wb_fx[NS2SA( 16000, DELAY_FD_BWE_ENC_NS )]; /* Q(-1) */ + Word16 old_input_lp_fx[NS2SA( 16000, ACELP_LOOK_NS + DELAY_FD_BWE_ENC_NS )]; // st->hBWE_FD->prev_Q_input_lp + Word16 old_syn_12k8_16k_fx[NS2SA( 16000, DELAY_FD_BWE_ENC_NS )]; // st->Q_syn Word16 old_fdbwe_speech_fx[L_FRAME48k]; Word16 mem_deemph_old_syn_fx; Word16 q_mem_deemph_old_syn; @@ -1020,6 +1027,7 @@ typedef struct fd_bwe_enc_structure Word32 prev_global_gain_fx; /* Q(2 * prev_Q_shb) */ Word16 modeCount; Word32 EnergyLF_fx; + Word16 EnergyLF_exp; Word16 mem_old_wtda_swb_fx; /* Q(-1) */ } FD_BWE_ENC_DATA, *FD_BWE_ENC_HANDLE; @@ -1031,9 +1039,9 @@ typedef struct fd_bwe_enc_structure typedef struct rf_enc_structure { - int16_t rf_frame_type; - int16_t rf_targetbits_buff[MAX_RF_FEC_OFFSET]; - int16_t rf_indx_frametype[MAX_RF_FEC_OFFSET]; + Word16 rf_frame_type; + Word16 rf_targetbits_buff[MAX_RF_FEC_OFFSET]; + Word16 rf_indx_frametype[MAX_RF_FEC_OFFSET]; ACELP_config acelp_cfg_rf; /* configuration for RF frame */ @@ -1044,31 +1052,31 @@ typedef struct rf_enc_structure struct dispMem_fx rf_dm_fx; Word32 rf_gc_threshold; - int16_t rf_target_bits; + Word16 rf_target_bits; Word16 rf_tilt_buf[NB_SUBFR16k]; - int16_t rf_indx_lsf[MAX_RF_FEC_OFFSET][3]; - int16_t rf_indx_pitch[MAX_RF_FEC_OFFSET][NB_SUBFR16k]; - int16_t rf_indx_fcb[MAX_RF_FEC_OFFSET][NB_SUBFR16k]; - int16_t rf_indx_gain[MAX_RF_FEC_OFFSET][NB_SUBFR16k]; - int16_t rf_indx_EsPred[MAX_RF_FEC_OFFSET]; - int16_t rf_indx_ltfMode[MAX_RF_FEC_OFFSET][NB_SUBFR16k]; + Word16 rf_indx_lsf[MAX_RF_FEC_OFFSET][3]; + Word16 rf_indx_pitch[MAX_RF_FEC_OFFSET][NB_SUBFR16k]; + Word16 rf_indx_fcb[MAX_RF_FEC_OFFSET][NB_SUBFR16k]; + Word16 rf_indx_gain[MAX_RF_FEC_OFFSET][NB_SUBFR16k]; + Word16 rf_indx_EsPred[MAX_RF_FEC_OFFSET]; + Word16 rf_indx_ltfMode[MAX_RF_FEC_OFFSET][NB_SUBFR16k]; - int16_t rf_indx_nelp_fid[MAX_RF_FEC_OFFSET]; - int16_t rf_indx_nelp_iG1[MAX_RF_FEC_OFFSET]; - int16_t rf_indx_nelp_iG2[MAX_RF_FEC_OFFSET][2]; + Word16 rf_indx_nelp_fid[MAX_RF_FEC_OFFSET]; + Word16 rf_indx_nelp_iG1[MAX_RF_FEC_OFFSET]; + Word16 rf_indx_nelp_iG2[MAX_RF_FEC_OFFSET][2]; - int16_t rf_indx_tbeGainFr[MAX_RF_FEC_OFFSET]; + Word16 rf_indx_tbeGainFr[MAX_RF_FEC_OFFSET]; - int16_t rf_tcxltp_pitch_int_past; - int16_t rf_last_tns_active; - int16_t rf_second_last_tns_active; - int16_t rf_second_last_core; - int16_t rf_clas[MAX_RF_FEC_OFFSET]; - int16_t rf_gain_tcx[MAX_RF_FEC_OFFSET]; - int16_t rf_tcxltp_param[MAX_RF_FEC_OFFSET]; + Word16 rf_tcxltp_pitch_int_past; + Word16 rf_last_tns_active; + Word16 rf_second_last_tns_active; + Word16 rf_second_last_core; + Word16 rf_clas[MAX_RF_FEC_OFFSET]; + Word16 rf_gain_tcx[MAX_RF_FEC_OFFSET]; + Word16 rf_tcxltp_param[MAX_RF_FEC_OFFSET]; - int16_t RF_bwe_gainFr_ind; + Word16 RF_bwe_gainFr_ind; } RF_ENC_DATA, *RF_ENC_HANDLE; @@ -1078,17 +1086,17 @@ typedef struct rf_enc_structure typedef struct plc_enc_evs_structure { - int16_t nBits; /* number of bits */ + Word16 nBits; /* number of bits */ Word16 Q_new; Word16 Q_exp; - int16_t enableGplc; - int16_t T0_4th; - int16_t T0; - int16_t calcOnlylsf; - int16_t pit_min; - int16_t pit_max; + Word16 enableGplc; + Word16 T0_4th; + Word16 T0; + Word16 calcOnlylsf; + Word16 pit_min; + Word16 pit_max; Word16 mem_MA_14Q1[M]; Word16 mem_AR[M]; @@ -1121,8 +1129,8 @@ typedef struct tec_enc_structure Word16 loTempEnv[CLDFB_NO_COL_MAX]; /* Q7 */ Word16 loTempEnv_ns[CLDFB_NO_COL_MAX]; /* Q7 */ Word16 hiTempEnv[CLDFB_NO_COL_MAX + DELAY_TEMP_ENV_BUFF_TEC + EXT_DELAY_HI_TEMP_ENV]; /* Q7 */ - int16_t tranFlag; - int16_t corrFlag; + Word16 tranFlag; + Word16 corrFlag; } TEC_ENC_DATA, *TEC_ENC_HANDLE; @@ -1133,63 +1141,63 @@ typedef struct tec_enc_structure typedef struct tcx_enc_structure { - int16_t L_frameTCX; + Word16 L_frameTCX; - int16_t tcxMode; /* Chosen TCX mode for this frame */ - int16_t transform_type[2]; /* TCX20/10/5 mode in each subframe */ + Word16 tcxMode; /* Chosen TCX mode for this frame */ + Word16 transform_type[2]; /* TCX20/10/5 mode in each subframe */ /* Core Signal Analysis Outputs */ Word16 noiseTiltFactor; /* compensation for LPC tilt in noise filling Q15 */ - int16_t noiseLevelMemory_cnt; /* counter of consecutive low TCX noise levels */ + Word16 noiseLevelMemory_cnt; /* counter of consecutive low TCX noise levels */ Word16 ltpGainMemory_fx[N_LTP_GAIN_MEMS]; /* for smoothing noiseTransWidth Q15 */ STnsData tnsData[2]; - // int16_t fUseTns[2]; + // Word16 fUseTns[2]; Word8 fUseTns[2]; - int16_t bTnsOnWhithenedSpectra[2]; + Word16 bTnsOnWhithenedSpectra[2]; - // int16_t memQuantZeros[L_FRAME_PLUS]; /* Quantization deadzone flags */ + // Word16 memQuantZeros[L_FRAME_PLUS]; /* Quantization deadzone flags */ Word8 memQuantZeros[L_FRAME_PLUS]; /* Quantization deadzone flags */ Word16 *speech_TCX; Word16 *new_speech_TCX; // Word16 q_speech_TCX; - int16_t tcxltp; - int16_t tcxltp_pitch_int; - int16_t tcxltp_pitch_fr; + Word16 tcxltp; + Word16 tcxltp_pitch_int; + Word16 tcxltp_pitch_fr; Word16 tcxltp_gain; /* Q15 */ - int16_t tcxltp_pitch_int_past; - int16_t tcxltp_pitch_fr_past; + Word16 tcxltp_pitch_int_past; + Word16 tcxltp_pitch_fr_past; Word16 tcxltp_gain_past; /* Q15 */ Word16 tcxltp_norm_corr_past; /* Q15 */ Word16 tcxltp_norm_corr_mem; /* Q15 */ Word16 kernel_switch_corr_past; /* Q15 */ - uint16_t kernel_type[2]; /* transform kernel type in each subframe (MDCT or MDST) */ - uint16_t kernel_symmetry_past; /* last TDA symmetry (0 for MDCT, 1 for MDST type) */ - uint16_t enc_ste_pre_corr_past; + UWord16 kernel_type[2]; /* transform kernel type in each subframe (MDCT or MDST) */ + UWord16 kernel_symmetry_past; /* last TDA symmetry (0 for MDCT, 1 for MDST type) */ + UWord16 enc_ste_pre_corr_past; Word32 tfm_mem_fx; /* state of IIR filtered temporal flatness measure Q31 */ Word16 buf_speech_ltp[L_PAST_MAX_32k + L_FRAME32k + L_NEXT_MAX_32k]; Word16 exp_buf_speech_ltp; Word16 *speech_ltp; Word16 *new_speech_ltp; - int16_t tcxltp_filt_idx; - int16_t tcxltp_bits; - int16_t tcxltp_param[LTPSIZE]; - int16_t tcxltp_on_mem; + Word16 tcxltp_filt_idx; + Word16 tcxltp_bits; + Word16 tcxltp_param[LTPSIZE]; + Word16 tcxltp_on_mem; Word16 measuredBwRatio; /* measured bw; used for TCX noise-filling. 1Q14 */ - int16_t nmStartLine; /* Starting line for the noise measurement */ + Word16 nmStartLine; /* Starting line for the noise measurement */ - int16_t tcx_lpc_shaped_ari; + Word16 tcx_lpc_shaped_ari; Word16 old_out_fx[L_FRAME32k]; /* buffer for OLA; at the encoder, the maximum length is L_FRAME32k (corresponds to maximum internal L_frame length) */ Word16 Q_old_out; /* MDCT switching */ Word16 prev_hi_ener; /* Q8 */ - int16_t prev_hi_sparse; + Word16 prev_hi_sparse; Word16 clas_sec_old_fx; /* Q13 */ - int16_t clas_final_old; + Word16 clas_final_old; Word32 last_gain1; /* Q(31 - st->last_enerBuffer_exp) */ Word32 last_gain2; /* Q(31 - st->last_enerBuffer_exp) */ @@ -1199,7 +1207,7 @@ typedef struct tcx_enc_structure Word16 q_Txnq; Word16 tcx_target_bits_fac; /* Q14 */ - int16_t tns_ms_flag[2]; + Word16 tns_ms_flag[2]; Word32 *spectrum_fx[2]; /* MDCT output for a short block */ Word16 spectrum_e[2]; Word32 spectrum_long_fx[N_MAX]; /* MDCT output for a long block. Points to spectrum */ @@ -1231,9 +1239,9 @@ typedef struct enc_core_structure Word16 idchan; /* channel ID (audio channel number) */ Word16 id_element; /* element ID */ - int16_t element_mode; /* element mode */ + Word16 element_mode; /* element mode */ Word16 last_element_mode; /* element mode */ - int32_t element_brate; /* element bitrate */ + Word32 element_brate; /* element bitrate */ Word16 extl_orig; /* extension layer */ Word32 extl_brate_orig; /* extension layer bitrate */ Word16 codec_mode; /* Mode1 or Mode2 */ @@ -1247,40 +1255,43 @@ typedef struct enc_core_structure BSTR_ENC_HANDLE hBstr; /* encoder bitstream handle */ Word16 last_enerBuffer_exp; - int16_t bitstreamformat; /* Bitstream format flag (G.192/MIME) */ - Word16 next_bit_pos_fx; /* position of the next bit to be written in the bitstream */ - - int32_t input_Fs; /* input signal sampling frequency in Hz */ - int32_t total_brate; /* total bitrate in kbps of the codec */ - int32_t last_total_brate; /* last frame's total bitrate in kbps of the codec */ - int32_t last_total_brate_cng; /* last inactive frame's total bitrate in kbps of the codec */ - int16_t core; /* core (ACELP_CORE, TCX_20_CORE, TCX_10_CORE, HQ_CORE, AMR_WB_CORE) */ - int16_t last_core; /* previous frame core */ - int16_t coder_type; /* core coder type */ - int16_t flag_ACELP16k; /* flag indicating use of ACELP core at 16kHz internal sampling rate */ - int32_t core_brate; /* core bitrate */ - int32_t last_core_brate; /* previous frame core bitrate */ - int16_t extl; /* extension layer */ - int16_t last_extl; /* previous extension layer */ - int32_t extl_brate; /* extension layer bitrate */ - int16_t input_bwidth; /* input signal bandwidth */ - int16_t bwidth; /* encoded bandwidth NB, WB, SWB or FB */ - int16_t max_bwidth; /* maximum encoded bandwidth */ - int16_t last_input_bwidth; /* input signal bandwidth in the previous frame */ - int16_t last_bwidth; /* coded bandwidth in the previous frame */ - int16_t last_bwidth_cng; /* coded bandwidth in the previous inactive frame */ - int16_t bwidth_sw_cnt; /* bandwidth switching counter */ - int16_t L_frame; /* ACELP core internal frame length */ - int16_t Opt_AMR_WB; /* flag indicating AMR-WB IO mode */ - int16_t Opt_DTX_ON; /* flag indicating DTX operation */ - int16_t cng_type; /* flag indicating LP or CLDFB based SID/CNG */ - int16_t cng_sba_flag; /* flag indicating CNG/SID for SBA 2TC */ - int16_t Opt_SC_VBR; /* flag indicating SC-VBR mode */ - int16_t last_Opt_SC_VBR; /* flag indicating prev frame's SC-VBR mode */ - int16_t low_rate_mode; /* low-rate mode flag */ - int16_t inactive_coder_type_flag; /* inactive coder type flag (0 = AVQ / 1 = GSC) */ + Word16 bitstreamformat; /* Bitstream format flag (G.192/MIME) */ + Word16 next_bit_pos_fx; /* position of the next bit to be written in the bitstream */ + + Word32 input_Fs; /* input signal sampling frequency in Hz */ + Word32 total_brate; /* total bitrate in kbps of the codec */ + Word32 last_total_brate; /* last frame's total bitrate in kbps of the codec */ + Word32 last_total_brate_cng; /* last inactive frame's total bitrate in kbps of the codec */ + Word16 core; /* core (ACELP_CORE, TCX_20_CORE, TCX_10_CORE, HQ_CORE, AMR_WB_CORE) */ + Word16 last_core; /* previous frame core */ + Word16 coder_type; /* core coder type */ + Word16 flag_ACELP16k; /* flag indicating use of ACELP core at 16kHz internal sampling rate */ + Word32 core_brate; /* core bitrate */ + Word32 last_core_brate; /* previous frame core bitrate */ + Word16 extl; /* extension layer */ + Word16 last_extl; /* previous extension layer */ + Word32 extl_brate; /* extension layer bitrate */ + Word16 input_bwidth; /* input signal bandwidth */ + Word16 bwidth; /* encoded bandwidth NB, WB, SWB or FB */ + Word16 max_bwidth; /* maximum encoded bandwidth */ + Word16 last_input_bwidth; /* input signal bandwidth in the previous frame */ + Word16 last_bwidth; /* coded bandwidth in the previous frame */ + Word16 last_bwidth_cng; /* coded bandwidth in the previous inactive frame */ + Word16 bwidth_sw_cnt; /* bandwidth switching counter */ + Word16 L_frame; /* ACELP core internal frame length */ + Word16 Opt_AMR_WB; /* flag indicating AMR-WB IO mode */ + Word16 Opt_DTX_ON; /* flag indicating DTX operation */ + Word16 cng_type; /* flag indicating LP or CLDFB based SID/CNG */ + Word16 cng_sba_flag; /* flag indicating CNG/SID for SBA 2TC */ + Word16 Opt_SC_VBR; /* flag indicating SC-VBR mode */ + Word16 last_Opt_SC_VBR; /* flag indicating prev frame's SC-VBR mode */ + Word16 low_rate_mode; /* low-rate mode flag */ + Word16 inactive_coder_type_flag; /* inactive coder type flag (0 = AVQ / 1 = GSC) */ #ifdef DEBUGGING - int16_t force; /* flag indicating specific signal type (0 = speech, 1 = music, -1 = N/A) */ + Word16 force; /* flag indicating specific signal type (0 = speech, 1 = music, -1 = N/A) */ +#ifdef DEBUG_FORCE_DIR + char *force_dir; /* directory containing external binary files for modes/parameters enforcement (empty string indicates no enforcement) */ +#endif #endif Word16 nTimeSlots; /* for CLDFB */ @@ -1315,13 +1326,13 @@ typedef struct enc_core_structure * ACELP core parameters *----------------------------------------------------------------------------------*/ - int16_t clas; /* current frame clas */ - int16_t last_clas; /* previous frame signal classification */ + Word16 clas; /* current frame clas */ + Word16 last_clas; /* previous frame signal classification */ Word16 prev_fmerit; /* previous signal classification score Q15 */ Word16 fmerit_dt; /* signal classification score difference Q15 */ - int16_t Nb_ACELP_frames; + Word16 Nb_ACELP_frames; - int16_t pitch[3]; /* open-loop pitch values @12.8 kHz for three half-frames */ + Word16 pitch[3]; /* open-loop pitch values @12.8 kHz for three half-frames */ // Word16 pitch_fx[3]; Word16 voicing_fx[3]; /* open-loop normalized correlation values for three half-frames Q15 */ @@ -1335,7 +1346,7 @@ typedef struct enc_core_structure Word16 lsf_old_fx[M]; /* old LSF vector at the end of the frame Qlog2(2.56) */ Word16 lsp_old16k_fx[M]; /* old LSP vector at the end of the frame @16kHz Q15 */ Word16 lspold_enc_fx[M]; /* old LSP vector at the end of the frame @16kHz Q15 */ - int16_t pstreaklen; /* LSF quantizer */ + Word16 pstreaklen; /* LSF quantizer */ Word16 streaklimit_fx; /* LSF quantizer Q15 */ Word16 stab_fac_fx; /* LSF stability factor Q15 */ Word16 clip_var_fx[6]; /* pitch gain clipping memory [2.56x,Q14,Q8,Q0,Q14,Q14] */ @@ -1362,42 +1373,42 @@ typedef struct enc_core_structure Word16 mem_deemph_fx; /* deemphasis filter memory */ Word32 mem_hp20_in_fx[5]; /* HP filter memory for AMR-WB IO */ Word16 mCb1_fx; /* LSF quantizer - counter of stationary frames after a transition frame */ - int16_t GSC_noisy_speech; /* AC mode (GSC) - flag to indicate GSC on SWB noisy speech */ - int16_t GSC_IVAS_mode; + Word16 GSC_noisy_speech; /* AC mode (GSC) - flag to indicate GSC on SWB noisy speech */ + Word16 GSC_IVAS_mode; GSC_ENC_HANDLE hGSCEnc; - int16_t Last_pulse_pos; /* FEC - last position of the first glottal pulse in the frame */ + Word16 Last_pulse_pos; /* FEC - last position of the first glottal pulse in the frame */ Word16 lsfoldbfi0_fx[M]; /* FEC - LSF vector of the previous frame Qlog2(2.56) */ Word16 lsfoldbfi1_fx[M]; /* FEC - LSF vector of the past previous frame Qlog2(2.56) */ Word16 lsf_adaptive_mean_fx[M]; /* FEC - adaptive mean LSF vector for FEC Qlog2(2.56) */ - int16_t next_force_safety_net; /* FEC - flag to force safety net in next frame */ + Word16 next_force_safety_net; /* FEC - flag to force safety net in next frame */ // Word16 next_force_safety_net_fx; /* FEC - flag to force safety net in next frame */ - int16_t uv_count; /* Stationary noise UV modification - unvoiced counter */ - int16_t act_count; /* Stationary noise UV modification - activation counter */ + Word16 uv_count; /* Stationary noise UV modification - unvoiced counter */ + Word16 act_count; /* Stationary noise UV modification - activation counter */ Word32 ge_sm_fx; /* Stationary noise UV modification - smoothed excitation gain Q(GE_SHIFT) */ Word16 lspold_s_fx[M]; /* Stationary noise UV modification - old LSP vector Q15 */ - int16_t noimix_seed; /* Stationary noise UV modification - mixture seed */ + Word16 noimix_seed; /* Stationary noise UV modification - mixture seed */ Word16 min_alpha_fx; /* Stationary noise UV modification - minimum alpha Q15 */ Word16 exc_pe_fx; /* Stationary noise UV modification - memory of the preemphasis filter */ - int16_t coder_type_raw; /* raw coder_type (before UNVOICED is lost) */ - int16_t last_coder_type_raw; /* raw last_coder_type (coming from the sigal classification) */ - int16_t last_coder_type; /* previous coding type */ - Word16 old_thres_fx; /* normalized correlation weighting in open-loop pitch Q15 */ + Word16 coder_type_raw; /* raw coder_type (before UNVOICED is lost) */ + Word16 last_coder_type_raw; /* raw last_coder_type (coming from the sigal classification) */ + Word16 last_coder_type; /* previous coding type */ + Word16 old_thres_fx; /* normalized correlation weighting in open-loop pitch Q14 */ Word16 old_corr_fx; /* normalized correlation in previous frame (mean value) Q15 */ - int16_t old_pitch; /* previous pitch for open-loop pitch search */ - int16_t delta_pit; /* open-loop pitch extrapolation correction */ + Word16 old_pitch; /* previous pitch for open-loop pitch search */ + Word16 delta_pit; /* open-loop pitch extrapolation correction */ Word32 ee_old_fx; /* previous frame low/high frequency energy ratio Q6 */ - int16_t min_band; /* minimum critical band of useful bandwidth */ - int16_t max_band; /* maximum critical band of useful bandwidth */ - int16_t tc_cnt; /* TC frame counter */ - int16_t audio_frame_cnt; /* Counter of relative presence of audio frames */ + Word16 min_band; /* minimum critical band of useful bandwidth */ + Word16 max_band; /* maximum critical band of useful bandwidth */ + Word16 tc_cnt; /* TC frame counter */ + Word16 audio_frame_cnt; /* Counter of relative presence of audio frames */ Word32 old_dE1_fx; /* Maximum energy increase in previous frame Q13 */ - int16_t old_ind_deltaMax; /* Index of the sub-subframe of maximum energy in previous frame */ + Word16 old_ind_deltaMax; /* Index of the sub-subframe of maximum energy in previous frame */ Word32 old_enr_ssf_fx[2 * NB_SSF]; /* Maxima of energies per sub-subframes of previous frame */ - int16_t spike_hyst; /* Hysteresis to prevent UC after sharp energy spike */ - int16_t last_harm_flag_acelp; /* harmonicity flag for ACELP @32kbps rate */ + Word16 spike_hyst; /* Hysteresis to prevent UC after sharp energy spike */ + Word16 last_harm_flag_acelp; /* harmonicity flag for ACELP @32kbps rate */ Word16 old_Aq_12_8_fx[M + 1]; /* Q12 old Aq[] for core switching */ Word16 old_Es_pred_fx; /* old Es_pred for core switching Q8 */ Word16 music_hysteresis_fx; /* Counter of frames after AUDIO coding mode to prevent UC */ @@ -1420,7 +1431,7 @@ typedef struct enc_core_structure Word16 voicing0_sm_fx; Word16 voicing_sm_fx; Word16 LF_EnergyRatio_sm_fx; - int16_t predecision_flag; + Word16 predecision_flag; Word32 diff_sm_fx; /* Q7 */ Word32 energy_sm_fx; /* Q7 */ @@ -1453,10 +1464,10 @@ typedef struct enc_core_structure Word16 *old_inp_12k8_fx; /* memory of input signal at 12.8kHz */ Word16 *old_inp_16k_fx; /* ACELP@16kHz - memory of input signal @16 kHz */ - Word16 *buf_speech_enc_pe; - Word16 *buf_synth; /*can be reduced to PIT_MAX_MAX+L_FRAME_MAX if no rate switching*/ - Word16 *buf_speech_enc; - Word16 *buf_wspeech_enc; + Word16 *buf_speech_enc_pe; // exp_buf_speech_enc_pe + Word16 *buf_synth; /*can be reduced to PIT_MAX_MAX+L_FRAME_MAX if no rate switching*/ + Word16 *buf_speech_enc; // exp_buf_speech_enc + Word16 *buf_wspeech_enc; // exp_buf_wspeech_enc Word16 exp_buf_speech_enc_pe; Word16 exp_buf_speech_enc; @@ -1479,9 +1490,9 @@ typedef struct enc_core_structure Word16 lgBin_E_fx[L_FFT / 2]; /* Q8 per bin energy of two frames */ - int16_t sp_aud_decision0; /* 1st stage speech/music decision flag */ - int16_t sp_aud_decision1; /* 1st stage speech/music classification flag */ - int16_t sp_aud_decision2; /* 2nd stage speech/music classification flag */ + Word16 sp_aud_decision0; /* 1st stage speech/music decision flag */ + Word16 sp_aud_decision1; /* 1st stage speech/music classification flag */ + Word16 sp_aud_decision2; /* 2nd stage speech/music classification flag */ /*----------------------------------------------------------------------------------* * VAD/DTX/CNG @@ -1492,9 +1503,9 @@ typedef struct enc_core_structure VAD_CLDFB_HANDLE hVAD_CLDFB; T_CldfbVadState vad_st; - int16_t vad_flag; /* i : VAD flag */ - int16_t sharpFlag; - int16_t localVAD; /* i : local VAD flag */ + Word16 vad_flag; /* i : VAD flag */ + Word16 sharpFlag; + Word16 localVAD; /* i : local VAD flag */ Word32 bckr_tilt_lt; /* Q16 */ Word16 lp_speech_fx; /* Q8 */ @@ -1504,7 +1515,7 @@ typedef struct enc_core_structure Word16 voicing_old_fx; Word16 var_SID_rate_flag_fx; /* CNG and DTX - flag for variable SID rate */ Word16 interval_SID_fx; - int16_t active_cnt; /* counter of active frames */ + Word16 active_cnt; /* counter of active frames */ TD_CNG_ENC_HANDLE hTdCngEnc; @@ -1531,10 +1542,10 @@ typedef struct enc_core_structure *----------------------------------------------------------------------------------*/ HANDLE_FD_CNG_ENC hFdCngEnc; - int16_t fd_cng_reset_flag; + Word16 fd_cng_reset_flag; Word16 last_totalNoise_fx; /* Q8 */ Word16 totalNoise_increase_hist_fx[TOTALNOISE_HIST_SIZE]; /* Q8 */ - int16_t totalNoise_increase_len; + Word16 totalNoise_increase_len; /*----------------------------------------------------------------------------------* * SC-VBR parameters @@ -1551,7 +1562,7 @@ typedef struct enc_core_structure Word16 old_hpfilt_out_fx; Word32 EnergyLT_fx; /* Q(EnergyLT_fx_exp) */ Word32 Energy_Old_fx; - int16_t TransientHangOver; + Word16 TransientHangOver; HQ_ENC_HANDLE hHQ_core; /* HQ core encoder handle */ @@ -1575,21 +1586,21 @@ typedef struct enc_core_structure Word16 lt_mean_NB_fx; /* Q11 */ Word16 lt_mean_WB_fx; /* Q11 */ Word16 lt_mean_SWB_fx; /* Q11 */ - int16_t count_WB; - int16_t count_SWB; - int16_t count_FB; + Word16 count_WB; + Word16 count_SWB; + Word16 count_FB; /*----------------------------------------------------------------------------------* * Channel-aware mode *----------------------------------------------------------------------------------*/ - int16_t rf_mode; /* flag to signal the RF mode */ - int16_t rf_mode_last; - int16_t last_rf_mode_cng; - int16_t Opt_RF_ON; - int16_t rf_fec_offset; - int16_t rf_target_bits_write; - int16_t rf_fec_indicator; + Word16 rf_mode; /* flag to signal the RF mode */ + Word16 rf_mode_last; + Word16 last_rf_mode_cng; + Word16 Opt_RF_ON; + Word16 rf_fec_offset; + Word16 rf_target_bits_write; + Word16 rf_fec_indicator; RF_ENC_HANDLE hRF; /* RF encoder handle */ @@ -1630,24 +1641,24 @@ typedef struct enc_core_structure Word16 exp_mem_preemph_enc; /* speech preemph filter memory (at encoder-sampling-rate) */ /* Signal Buffers and Pointers at encoder-sampling-rate */ - Word16 *speech_enc; - Word16 *speech_enc_pe; - Word16 *new_speech_enc; - Word16 *new_speech_enc_pe; - Word16 *wspeech_enc; + Word16 *speech_enc; // exp_buf_speech_enc + Word16 *speech_enc_pe; // exp_buf_speech_enc_pe + Word16 *new_speech_enc; // exp_buf_speech_enc + Word16 *new_speech_enc_pe; // exp_buf_speech_enc_pe + Word16 *wspeech_enc; // exp_buf_wspeech_enc Word16 *synth; - int16_t enableTcxLpc; /* global toggle for the TCX LPC quantizer */ - int16_t envWeighted; /* are is{p,f}_old_q[] weighted or not? */ + Word16 enableTcxLpc; /* global toggle for the TCX LPC quantizer */ + Word16 envWeighted; /* are is{p,f}_old_q[] weighted or not? */ - int16_t acelpEnabled; /* Flag indicating if ACELP can be used */ - int16_t tcx10Enabled; /* Flag indicating if TCX 10 can be used */ - int16_t tcx20Enabled; /* Flag indicating if TCX 20 can be used */ + Word16 acelpEnabled; /* Flag indicating if ACELP can be used */ + Word16 tcx10Enabled; /* Flag indicating if TCX 10 can be used */ + Word16 tcx20Enabled; /* Flag indicating if TCX 20 can be used */ Word16 mem_wsp_enc; /* wsp vector memory */ - int16_t nb_bits_header_ace; /* number of bits for the header */ - int16_t nb_bits_header_tcx; /* number of bits for the header */ + Word16 nb_bits_header_ace; /* number of bits for the header */ + Word16 nb_bits_header_tcx; /* number of bits for the header */ Word16 preemph_fac; /*Preemphasis factor Q15*/ Word16 gamma; /* Q15 */ @@ -1656,7 +1667,7 @@ typedef struct enc_core_structure TRAN_DET_HANDLE hTranDet; TransientDetection transientDetection; Word16 transient_info[3]; - int16_t acelpFramesCount; + Word16 acelpFramesCount; Word16 prevTempFlatness_fx; /* exponent is AVG_FLAT_E Q7 in EVS */ /* Q4 in IVAS */ // float currEnergyLookAhead; @@ -1671,34 +1682,34 @@ typedef struct enc_core_structure Word16 parcorr[2]; Word16 parcorr_mid[2]; - int16_t lpcQuantization; + Word16 lpcQuantization; Word16 numlpc; - int16_t encoderLookahead_enc; - int16_t encoderPastSamples_enc; - int16_t encoderLookahead_FB; + Word16 encoderLookahead_enc; + Word16 encoderPastSamples_enc; + Word16 encoderLookahead_FB; /* pitch_ol for adaptive lag window */ - int16_t old_pitch_la; /* past open loop pitch lag from look-ahead before very short stable pitch detection */ + Word16 old_pitch_la; /* past open loop pitch lag from look-ahead before very short stable pitch detection */ Word16 old_voicing_la; /* past open loop pitch gain from look-ahead */ Word32 band_energies[2 * NB_BANDS]; /* energy in critical bands without minimum noise floor MODE2_E_MIN */ Word16 band_energies_exp; /* exponent for energy in critical bands without minimum noise floor MODE2_E_MIN */ - int16_t acelp_autocorr; /* Optimize acelp in 0 covariance or 1 correlation domain */ + Word16 acelp_autocorr; /* Optimize acelp in 0 covariance or 1 correlation domain */ - int16_t pit_min; - int16_t pit_fr1; - int16_t pit_fr1b; - int16_t pit_fr2; - int16_t pit_max; - int16_t pit_res_max; + Word16 pit_min; + Word16 pit_fr1; + Word16 pit_fr1b; + Word16 pit_fr2; + Word16 pit_max; + Word16 pit_res_max; /* for FAC */ - int16_t L_frame_past; + Word16 L_frame_past; /*Adaptive BPF*/ - int16_t bpf_gain_param; + Word16 bpf_gain_param; Word32 mem_bpf_fx1[2 * L_FILT16k]; Word32 mem_error_bpf_fx[2 * L_FILT16k]; Word16 bpf_T[NB_SUBFR16k]; @@ -1713,24 +1724,24 @@ typedef struct enc_core_structure Word16 noise_shift_old; } mem_bpf_fx; - int16_t glr; - int16_t glr_idx[2]; + Word16 glr; + Word16 glr_idx[2]; Word32 mean_gc[2]; /* Q15 */ Word16 prev_lsf4_mean; /* Qlog2(2.56) */ - int16_t glr_reset; - int32_t last_sr_core; + Word16 glr_reset; + Word32 last_sr_core; Word16 last_stab_fac; /* Q15 */ Word32 gain_code[NB_SUBFR16k]; /*for rate switching*/ - int16_t rate_switching_reset; /*Rate switching flag requiring a reset of memories at least partially */ - int16_t rate_switching_reset_16kHz; + Word16 rate_switching_reset; /*Rate switching flag requiring a reset of memories at least partially */ + Word16 rate_switching_reset_16kHz; - int16_t enablePlcWaveadjust; - int16_t Tonal_SideInfo; + Word16 enablePlcWaveadjust; + Word16 Tonal_SideInfo; - int16_t seed_acelp; + Word16 seed_acelp; PLC_ENC_EVS_HANDLE hPlcExt; @@ -1739,23 +1750,23 @@ typedef struct enc_core_structure *----------------------------------------------------------------------------------*/ IGF_ENC_INSTANCE_HANDLE hIGFEnc; /* IGF encoder handle */ - int16_t igf; + Word16 igf; /*----------------------------------------------------------------------------------* * TEC *----------------------------------------------------------------------------------*/ - int16_t tec_tfa; + Word16 tec_tfa; TEC_ENC_HANDLE hTECEnc; /* TEC encoder handle */ - int16_t tec_flag; - int16_t tfa_flag; + Word16 tec_flag; + Word16 tfa_flag; Word32 tfa_enr[N_TEC_TFA_SUBFR]; /*---------------------------------------------------------------* * IVAS parameters *---------------------------------------------------------------*/ - int16_t tdm_LRTD_flag; /* LRTD stereo mode flag */ + Word16 tdm_LRTD_flag; /* LRTD stereo mode flag */ Word16 cna_dirac_flag; /* CNA in DirAC flag */ /* stereo switching memories */ @@ -1770,9 +1781,10 @@ typedef struct enc_core_structure Word16 is_ism_format; /* Indication whether the codec operates in ISM format */ Word16 dtx_sce_sba; /* enable use of FD CNG with transform domain cores in SCE SBA */ - /*----------------------------------------------------------------------------------* - * Fixed point only variables - *----------------------------------------------------------------------------------*/ + + /*----------------------------------------------------------------------------------* + * Fixed point only variables + *----------------------------------------------------------------------------------*/ Word16 last_ener_fx; /* AC mode (GSC) - previous energy */ @@ -1799,553 +1811,24 @@ typedef struct enc_core_structure Word16 prev_lpc_wb_fx[LPC_SHB_ORDER_WB]; Word16 prev_lsp_wb_temp_fx[LPC_SHB_ORDER_WB]; - int16_t sba_br_sw_while_no_data; /* Indicator for SBA bitrate switch while in FRAME_NO_DATA mode */ + Word16 sba_br_sw_while_no_data; /* Indicator for SBA bitrate switch while in FRAME_NO_DATA mode */ } Encoder_State, *ENC_CORE_HANDLE; -// typedef struct Encoder_State_fx -//{ -// -// /*----------------------------------------------------------------------------------* -// * Common parameters - -// *----------------------------------------------------------------------------------*/ -// /*----------------------------------------------------------------------------------* -// * Stereo/IVAS parameters -// *----------------------------------------------------------------------------------*/ -// Word16 flag_ACELP16k; /* flag indicating use of ACELP core at 16kHz internal sampling rate */ -// -// Word16 tdm_LRTD_flag; /* LRTD stereo mode flag */ -// Word16 cna_dirac_flag; /* CNA in DirAC flag */ -// Word16 cng_sba_flag; /* CNG in SBA flag */ -// Word16 idchan; /* channel ID (audio channel number) */ -// Word16 element_mode; /* element mode */ -// Word16 last_element_mode; /* element mode */ -// Word16 low_rate_mode; /* low-rate mode flag */ -// MCT_CHAN_MODE mct_chan_mode; -// Word16 GSC_IVAS_mode; -// Word16 is_ism_format; /* Indication whether the codec operates in ISM format */ -// Word16 dtx_sce_sba; /* enable use of FD CNG with transform domain cores in SCE SBA */ -// -// -// //#ifdef IVAS_CODE -// -// #ifdef DEBUGGING -// Word16 id_element; /* element ID */ -// #endif -// Word32 element_brate; /* element bitrate */ -// Word16 extl_orig; /* extension layer */ -// Word32 extl_brate_orig; /* extension layer bitrate */ -// /*----------------------- End of IVAS specific--------------------------------------*/ -// -// -// Word16 codec_mode; /* MODE1 or MODE2 */ -// Word16 last_codec_mode; /* Previous Codec Mode*/ -// Word16 last_codec_mode_cng; /* Codec Mode of the last inactive frame*/ -// Word16 mdct_sw_enable; /* MDCT switching enable flag */ -// Word16 mdct_sw; /* MDCT switching indicator */ -// Word16 last_enerBuffer_exp; -// Word16 next_bit_pos_fx; /* position of the next bit to be written in the bitstream */ -// Word16 bitstreamformat; /* Bitstream format flag (G.192/MIME) */ -// -// BSTR_ENC_HANDLE hBstr; /* encoder bitstream handle */ -// -// -// LPD_state_HANDLE hLPDmem; /* ACELP LPDmem memories */ -// -// -// Word32 input_Fs_fx; /* input signal sampling frequency in Hz */ -// Word32 total_brate_fx; /* total bitrate in kbps of the codec */ -// Word32 last_total_brate_fx; /* total bitrate in kbps of the codec */ -// Word32 last_total_brate_cng_fx; /* total bitrate in kbps of the last inactive frame */ -// Word16 core_fx; /* core (ACELP_CORE, TCX_20_CORE, TCX_10_CORE, HQ_CORE, AMR_WB_CORE) */ -// Word32 core_brate_fx; /* core bitrate */ -// Word32 last_core_brate_fx; /* previous frame core bitrate */ -// Word16 input_frame_fx; /* Frame lenght (function of input_Fs) */ -// Word16 extl_fx; /* extension layer */ -// Word16 last_extl_fx; /* previous extension layer */ -// Word32 extl_brate_fx; /* extension layer bitrate */ -// Word16 input_bwidth_fx; /* input signal bandwidth */ -// Word16 last_input_bwidth_fx; /* input signal bandwidth in the previous frame */ -// Word16 bwidth_fx; /* encoded bandwidth NB, WB, SWB or FB */ -// Word16 max_bwidth_fx; /* maximum encoded bandwidth */ -// Word16 last_bwidth_fx; /* input signal bandwidth in the previous frame */ -// Word16 last_bwidth_cng_fx; /* input signal bandwidth in the previous inactive frame */ -// Word16 L_frame_fx; /* ACELP core internal frame length */ -// Word16 Opt_AMR_WB_fx; /* flag indicating AMR-WB IO mode */ -// Word16 Opt_DTX_ON_fx; /* flag indicating DTX operation */ -// Word16 cng_type_fx; /* flag indicating LP or CLDFB based SID/CNG */ -// Word16 active_fr_cnt_fx; /* counter of active frames */ -// Word16 Opt_SC_VBR_fx; /* flag indicating SC-VBR mode */ -// Word16 last_Opt_SC_VBR_fx; /* flag indicating SC-VBR mode in the last frame */ -// /*----------------------------------------------------------------------------------* -// * ACELP core parameters -// *----------------------------------------------------------------------------------*/ -// -// Word16 clas_fx; /* current frame clas */ -// Word16 last_clas_fx; /* previous frame signal classification */ -// Word32 Bin_E_fx[L_FFT]; /* Q_new + Q_SCALE -2 per bin energy of two frames */ -// -// /*----------------------------------------------------------------------------------* -// * General signal buffers -// *----------------------------------------------------------------------------------*/ -// Word16* input_buff; -// /*Word16* input; -// Word16* old_input_signal;*/ -// -// SIGNAL_BUFFERS_ENC_HANDLE hSignalBuf; -// -// Word32* Bin_E_old_fx; /* per bin energy of old 2nd frames */ -// Word16* mem_decim_fx; /* decimation filter memory */ -// Word16* mem_decim16k_fx; /* ACELP@16kHz - decimation filter memory @16kHz */ -// Word16* old_inp_12k8_fx; /* memory of input signal at 12.8kHz */ -// Word16* old_inp_16k_fx; /* ACELP@16kHz - memory of input signal @16 kHz */ -// -// Word16* buf_speech_enc_pe; -// Word16* buf_synth; /*can be reduced to PIT_MAX_MAX+L_FRAME_MAX if no rate switching*/ -// Word16* buf_speech_enc; -// Word16* buf_wspeech_enc; -// -// -// Word16 lsp_old1_fx[M]; /* old unquantized LSP vector at the end of the frame */ -// Word16 lsf_old1_fx[M]; /* old LSF vector at the end of the frame */ -// Word16 lsp_old_fx[M]; /* old LSP vector at the end of the frame */ -// Word16 lsf_old_fx[M]; /* old LSF vector at the end of the frame */ -// Word16 lsp_old16k_fx[M]; /* old LSP vector at the end of the frame @16kHz */ -// Word16 lspold_enc_fx[M]; /* old LSP vector at the end of the frame @16kHz */ -// Word16 pstreaklen_fx; /* LSF quantizer */ -// Word16 streaklimit_fx; /* LSF quantizer */ -// Word32 offset_scale1_fx[MAX_NO_MODES + 1][MAX_NO_SCALES + 1]; /* offsets for LSF LVQ structure 1st 8-dim subvector*/ -// Word32 offset_scale2_fx[MAX_NO_MODES + 1][MAX_NO_SCALES + 1]; /* offsets for LSF LVQ structure 2nd 8-dim subvector*/ -// Word32 offset_scale1_p_fx[MAX_NO_MODES_p + 1][MAX_NO_SCALES + 1]; /* offsets for LSF LVQ structure, pred. case, 1st 8-dim subvector*/ -// Word32 offset_scale2_p_fx[MAX_NO_MODES_p + 1][MAX_NO_SCALES + 1]; /* offsets for LSF LVQ structure, pred. case, 2nd 8-dim subvector*/ -// Word16 no_scales_fx[MAX_NO_MODES][2]; /* LSF LVQ structure Q0*/ -// Word16 no_scales_p_fx[MAX_NO_MODES_p][2]; /* LSF LVQ structure Q0*/ -// Word16 stab_fac_fx; /* LSF stability factor */ -// Word16 mem_deemph_fx; /* deemphasis filter memory */ -// Word16 mem_preemph_fx; /* preemphasis filter memory */ -// Word32 mem_hp20_in_fx[5]; /* HP filter memory for AMR-WB IO */ -// Word16 old_wsp_fx[L_WSP_MEM]; /* old weighted signal vector */ -// /*Word16 old_exc_fx[L_EXC_MEM];*/ /* old excitation vector */ -// Word16 old_wsp2_fx[(L_WSP_MEM - L_INTERPOL) / OPL_DECIM]; /* old decimated weighted signal vector qwsp */ -// -// /*----------------------------------------------------------------------------------* -// * Noise estimation -// *----------------------------------------------------------------------------------*/ -// -// NOISE_EST_HANDLE hNoiseEst; -// -// Word16 mem_wsp_fx; /* weighted signal vector memory */ -// Word16 mem_decim2_fx[3]; /* weighted signal decimation filter memory qwsp */ -// Word16 clip_var_fx[6]; -// Word16 mem_AR_fx[M]; /* AR memory of LSF quantizer (past quantized LSFs without mean) */ -// Word16 mem_MA_fx[M]; /* MA memory of LSF quantizer (past quantized residual) (used also in AMR-WB IO mode) */ -// Word16 mCb1_fx; /* LSF quantizer - counter of stationary frames after a transition frame */ -// Word16 coder_type_raw_fx; -// Word16 last_coder_type_raw_fx; /* raw last_coder_type (coming from the sigal classification) */ -// Word16 last_coder_type; /*Q0 previous coding type */ -// Word16 ini_frame_fx; /* initialization frames counter */ -// Word16 old_thres_fx; /* normalized correlation weighting in open-loop pitch Q15 */ -// Word16 old_corr_fx; /* normalized correlation in previous frame (mean value) Q15 */ -// Word16 old_pitch; /* previous pitch for open-loop pitch search Q0 */ -// Word16 delta_pit_fx; /* open-loop pitch extrapolation correction Q0 */ -// Word32 ee_old_fx; -// Word16 min_band_fx; /* Q0 minimum critical band of useful bandwidth */ -// Word16 max_band_fx; /* Q0 maximum critical band of useful bandwidth */ -// Word16 tc_cnt_fx; /* TC frame counter */ -// Word16 audio_frame_cnt_fx; /* Counter of relative presence of audio frames */ -// Word32 old_dE1_fx; /* Maximum energy increase in previous frame */ -// Word16 old_ind_deltaMax_fx; /* Index of the sub-subframe of maximum energy in previous frame */ -// Word32 old_enr_ssf_fx[2 * NB_SSF]; /* Maxima of energies per sub-subframes of previous frame */ -// Word16 spike_hyst_fx; /* Hysteresis to prevent UC after sharp energy spike */ -// Word16 music_hysteresis_fx; /* Counter of frames after AUDIO coding mode to prevent UC */ -// Word16 last_harm_flag_acelp_fx; /* harmonicity flag for ACELP @32kbps rate */ -// Word16 old_Aq_12_8_fx[M + 1]; /* Q12 old Aq[] for core switching */ -// Word16 old_Es_pred_fx; /* Q8 old Es_pred for core switching */ -// -// GSC_ENC_HANDLE hGSCEnc; -// -// -// Word16 GSC_noisy_speech; /* AC mode (GSC) - flag to indicate GSC on SWB noisy speech */ -// -// SP_MUS_CLAS_HANDLE hSpMusClas; -// -// Word16 lgBin_E_fx[L_FFT / 2]; /* Q8 per bin energy of two frames */ -// -// /* speech/music classifier improvement parameters */ -// Word16 last_vad_spa_fx; -// -// -// Word16 Last_pulse_pos_fx; /* FEC - last position of the first glotal pulse in the frame */ -// Word16 lsfoldbfi0_fx[M]; /* FEC - LSF vector of the previous frame */ -// Word16 lsfoldbfi1_fx[M]; /* FEC - LSF vector of the past previous frame */ -// Word16 lsf_adaptive_mean_fx[M]; /* FEC - adaptive mean LSF vector for FEC */ -// Word16 next_force_safety_net_fx; /* FEC - flag to force safety net in next frame */ -// -// -// /*----------------------------------------------------------------------------------* -// * VAD/DTX/CNG -// *----------------------------------------------------------------------------------*/ -// -// VAD_HANDLE hVAD; -// -// VAD_CLDFB_HANDLE hVAD_CLDFB; -// Word16 lp_speech_fx; -// Word16 Opt_HE_SAD_ON_fx; -// Word16 nb_active_frames_HE_SAD_fx; -// -// -// -// -// Word16 voicing_old_fx; -// -// -// Word32 bckr_tilt_lt; -// -// -// TD_CNG_ENC_HANDLE hTdCngEnc; -// -// DTX_ENC_HANDLE hDtxEnc; -// Word16 var_SID_rate_flag_fx; /* CNG and DTX - flag for variable SID rate */ -// Word16 interval_SID_fx; /* CNG and DTX - interval of SID update, default 8 */ -// -// Word16 lp_noise_fx; /* CNG and DTX - LP filtered total noise estimation */ -// -// Word16 uv_count; /*Q0*/ /* Stationary noise UV modification - unvoiced counter */ -// Word16 act_count; /*Q0*/ /* Stationary noise UV modification - activation counter */ -// Word32 ge_sm_fx; /* Stationary noise UV modification - smoothed excitation gain */ -// Word16 lspold_s_fx[M]; /*Q15*/ /* Stationary noise UV modification - old LSP vector */ -// Word16 noimix_seed; /*Q0*/ /* Stationary noise UV modification - mixture seed */ -// Word16 min_alpha_fx; /*Q15*/ /* Stationary noise UV modification - minimum alpha */ -// Word16 exc_pe_fx; /* Stationary noise UV modification - memory of the preemphasis filter */ -// -// Word16 last_L_frame_fx; /* ACELP@16kHz - last L_frame value */ -// Word16 mem_preemph16k_fx; /* ACELP@16kHz - preemphasis filter memory @16kHz */ -// Word16 mem_deemp_preQ_fx; /* ACELP@16kHz - prequantizer deemhasis memory */ -// Word16 mem_preemp_preQ_fx; /* ACELP@16kHz - prequantizer preemhasis memory */ -// Word16 last_nq_preQ; /* ACELP@16kHz - AVQ subquantizer number of the last sub-band of the last subframe */ -// Word16 use_acelp_preq; /* ACELP@16kHz - flag of prequantizer usage */ -// -// Word16 bpf_off_fx; -// Word16 old_pitch_buf_fx[2 * NB_SUBFR16k]; /*Q6 Bass post-filter - buffer of old subframe pitch values */ -// -// -// /* stable short pitch detection */ -// Word16 voicing0_sm_fx; -// Word16 voicing_sm_fx; -// Word16 LF_EnergyRatio_sm_fx; -// Word16 predecision_flag_fx; -// Word32 diff_sm_fx; -// Word32 energy_sm_fx; -// -// Word16 last_ener_fx; /* AC mode (GSC) - previous energy */ -// -// /*----------------------------------------------------------------------------------* -// * AMR-WB IO handle -// *----------------------------------------------------------------------------------*/ -// HANDLE_CLDFB_FILTER_BANK cldfbAna_Fx; -// -// AMRWB_IO_ENC_HANDLE hAmrwb_IO; /* AMR-WB IO encoder handle */ -// -// /*----------------------------------------------------------------------------------* -// * CLDFB analysis -// *----------------------------------------------------------------------------------*/ -// HANDLE_CLDFB_FILTER_BANK cldfbAna_Fx; -// -// HANDLE_CLDFB_FILTER_BANK cldfbSyn_Fx; -// -// /*----------------------------------------------------------------------------------* -// * FD CNG handle -// *----------------------------------------------------------------------------------*/ -// HANDLE_FD_CNG_ENC_FX hFdCngEnc_fx; -// Word16 fd_cng_reset_flag; -// Word16 last_totalNoise_fx; -// Word16 totalNoise_increase_hist_fx[TOTALNOISE_HIST_SIZE]; -// Word16 totalNoise_increase_len_fx; -// /*----------------------------------------------------------------------------------* -// * SC-VBR parameters -// *----------------------------------------------------------------------------------*/ -// -// /*----------------------------------------------------------------------------------* -// * SC-VBR parameters -// *----------------------------------------------------------------------------------*/ -// -// SC_VBR_ENC_HANDLE hSC_VBR; -// -// /*----------------------------------------------------------------------------------* -// * HQ core parameters -// *----------------------------------------------------------------------------------*/ -// Word16 * input; -// Word16 * old_input_signal_fx; -// Word16 Q_old_wtda; -// Word16 old_hpfilt_in_fx; -// Word16 old_hpfilt_out_fx; -// Word32 EnergyLT_fx; -// Word32 Energy_Old_fx; -// Word16 TransientHangOver_fx; -// Word16 last_core_fx; -// -// HQ_ENC_HANDLE hHQ_core; /* HQ core encoder handle */ -// -// Word16 Nb_ACELP_frames_fx; -// -// PVQ_ENC_HANDLE hPVQ; -// -// /*----------------------------------------------------------------------------------* -// * TD BWE parameters -// *----------------------------------------------------------------------------------*/ -// -// TD_BWE_ENC_HANDLE hBWE_TD; -// -// /*----------------------------------------------------------------------------------* -// * FD BWE parameters -// *----------------------------------------------------------------------------------*/ -// -// FD_BWE_ENC_HANDLE hBWE_FD; -// -// /*----------------------------------------------------------------------------------* -// * WB, SWB and FB bandwidth detector -// *----------------------------------------------------------------------------------*/ -// -// Word16 lt_mean_NB_fx; -// Word16 lt_mean_WB_fx; -// Word16 lt_mean_SWB_fx; -// Word16 count_WB_fx; -// Word16 count_SWB_fx; -// Word16 count_FB_fx; -// -// RF_ENC_HANDLE hRF; /* RF encoder handle */ -// -// Word16 rf_mode; -// Word16 rf_target_bits_write; -// Word16 rf_mode_last; -// Word16 last_rf_mode_cng; -// Word16 Opt_RF_ON; -// Word16 rf_fec_offset; -// Word16 rf_fec_indicator; -// -// /*----------------------------------------------------------------------------------* -// * Fixed point only variables -// *----------------------------------------------------------------------------------*/ -// -// Word16 prev_Q_bwe_exc; -// Word16 prev_Q_bwe_syn; -// Word16 Q_stat_noise_ge; -// Word16 Q_stat_noise; -// Word16 Q_syn2; -// Word16 Q_syn; -// Word16 Q_max[L_Q_MEM]; -// Word16 Q_max_16k[L_Q_MEM]; -// Word16 Q_old; -// Word16 prev_Q_old; -// Word16 old_wsp_max; /* Last weigthed speech maximal value */ -// Word16 old_wsp_shift; /* Last wsp scaling */ -// Word16 prev_Q_new; -// Word16 prev_Q_shb; -// -// /*----------------------------------------------------------------------------------* -// * -// *----------------------------------------------------------------------------------*/ -// -// Word16 EnergyLT_fx_exp; -// Word16 prev_lsp_wb_fx[LPC_SHB_ORDER_WB]; -// Word16 prev_lpc_wb_fx[LPC_SHB_ORDER_WB]; -// Word16 prev_lsp_wb_temp_fx[LPC_SHB_ORDER_WB]; -// -// Word16 frame_size_index; /* 0-FRAME_SIZE_NB-1: index determining the frame size */ -// Word16 bits_frame_nominal; /* avg bits per frame on active frame */ -// Word16 bits_frame; /* total bits per frame */ -// Word16 bits_frame_core; /* bits per frame for the core */ -// Word8 narrowBand; -// -// /*ACELP config*/ -// ACELP_config acelp_cfg; /* configuration set for each frame */ -// -// ACELP_config acelp_cfg_rf; /* configuration for RF frame */ -// -// Word16 mode_index; /* Mode Index for LPD core */ -// -// /*TCX config*/ -// TCX_CONFIG_HANDLE hTcxCfg; -// /*----------------------------------------------------------------------------------* -// * TCX core encoder handle -// *----------------------------------------------------------------------------------*/ -// -// TCX_ENC_HANDLE hTcxEnc; -// -// /* cod_main.c */ -// Word16 mem_preemph_enc; /* speech preemph filter memory (at encoder-sampling-rate) */ -// -// -// Word16 *speech_enc; -// Word16 *speech_enc_pe; -// Word16 *new_speech_enc; -// Word16 *new_speech_enc_pe; -// Word16 *wspeech_enc; -// Word16 *synth; -// /* Core Signal Analysis Outputs */ -// -// Word8 enableTcxLpc; /* global toggle for the TCX LPC quantizer */ -// Word16 envWeighted; /* are is{p,f}_old_q[] weighted or not? */ -// -// Word8 acelpEnabled; /* Flag indicating if ACELP can be used */ -// Word8 tcx10Enabled; /* Flag indicating if TCX 10 can be used */ -// Word8 tcx20Enabled; /* Flag indicating if TCX 20 can be used */ -// -// -// Word16 mem_wsp_enc; /* wsp vector memory */ -// -// Word16 nb_bits_header_ace; /* number of bits for the header */ -// Word16 nb_bits_header_tcx; /* number of bits for the header */ -// -// /*Added by fcs : restrict the possible in EVS: 0 base 10 = d.c.b.a base 2*/ -// /* a = 0/1 : ACELP on/off*/ -// /* b = 0/1 : TCX20 on/off*/ -// /* c = 0/1 : TCX40 on/off*/ -// /* d = 0/1 : TCX80 on/off*/ -// Word16 restrictedMode; -// -// /* Framing */ -// Word16 nb_subfr; -// -// Word16 preemph_fac; /*Preemphasis factor*/ -// -// Word16 gamma; -// Word16 inv_gamma; -// -// TransientDetection transientDetection; -// Word16 transient_info[3]; -// -// Word16 acelpFramesCount; /* Acelp frame counter. Counts upto 50 only !!! */ -// -// Word16 prevTempFlatness_fx; /* exponent is AVG_FLAT_E */ -// -// Word32 prevEnergyHF_fx; -// Word32 currEnergyHF_fx; -// Word16 currEnergyHF_e_fx; /* exponent of currEnergyHF and prevEnergyHF */ -// Word32 energyCoreLookahead_Fx; -// Word16 sf_energyCoreLookahead_Fx; -// -// /* lsf quantizer*/ -// Word16 parcorr[2]; -// Word16 parcorr_mid[2]; -// -// Word16 lpcQuantization; -// Word16 numlpc; -// Word16 encoderLookahead_enc; -// Word16 encoderPastSamples_enc; -// Word16 encoderLookahead_FB; -// -// /* pitch_ol for adaptive lag window */ -// Word16 old_pitch_la; /* past open loop pitch lag from look-ahead */ -// Word16 old_voicing_la; /* past open loop pitch gain from look-ahead */ -// -// Word32 band_energies[2 * NB_BANDS]; /* energy in critical bands without minimum noise floor MODE2_E_MIN */ -// Word16 band_energies_exp; /* exponent for energy in critical bands without minimum noise floor MODE2_E_MIN */ -// -// Word8 tcxonly; -// -// Word16 Q_max_enc[2]; -// -// Word16 finalVAD; -// Word8 flag_noisy_speech_snr; /*encoder detector for noisy speech*/ -// Word16 Pos_relE_cnt; /* Number of frames between positive relE */ -// -// Word16 fscale; -// Word32 sr_core; -// Word32 last_sr_core; -// Word8 acelp_autocorr; /* Optimize acelp in 0 covariance or 1 correlation domain */ -// -// Word16 pit_min; -// Word16 pit_fr1; -// Word16 pit_fr1b; -// Word16 pit_fr2; -// Word16 pit_max; -// Word16 pit_res_max; /* goes from 1 upto 6 (see core_enc_init.c: init_acelp()) */ -// -// /* for FAC */ -// Word16 L_frame_past; -// -// /*Adaptive BPF*/ -// Word16 bpf_gain_param; -// Word16 bpf_T[NB_SUBFR16k]; -// Word16 bpf_gainT[NB_SUBFR16k]; -// -// struct MEM_BPF -// { -// Word16 noise_buf[2 * L_FILT16k]; -// Word16 error_buf[L_FILT16k]; -// Word32 lp_error; -// Word32 lp_error_ener; -// Word16 noise_shift_old; -// } mem_bpf; -// -// -// -// Word8 glr; -// Word16 glr_idx[2]; -// Word32 gain_code[NB_SUBFR16k]; -// Word32 mean_gc[2]; -// Word16 prev_lsf4_mean; -// Word16 last_stab_fac; -// Word8 glr_reset; -// -// /*for rate switching*/ -// Word16 rate_switching_reset; /*Rate switching flag requiring a reset of memories at least partially */ -// Word16 rate_switching_reset_16kHz; -// -// Word16 enablePlcWaveadjust; -// Word16 Tonal_SideInfo; -// -// IGF_ENC_INSTANCE_HANDLE hIGFEnc; /* IGF encoder handle */ -// Word16 igf; -// -// Word16 seed_acelp; -// -// PLC_ENC_EVS_HANDLE hPlcExt; -// -// Word16 tec_tfa; -// TEC_ENC_HANDLE hTECEnc; /* TEC encoder handle */ -// Word16 tec_flag; -// Word16 tfa_flag; -// Word32 tfa_enr[N_TEC_TFA_SUBFR]; -// -// Word16 nTimeSlots; /* for CLDFB */ -// -// T_CldfbVadState_fx vad_st; -// -// -// Word16 pitch_fx[3]; -// Word16 voicing_fx[3]; -// Word16 sp_aud_decision0; /* 1st stage speech/music classification */ -// Word16 sp_aud_decision1; /* 1st stage speech/music classification */ -// Word16 sp_aud_decision2; /* 2nd stage speech/music classification */ -// Word16 coder_type; /* coder type */ -// Word16 vad_flag; -// Word16 sharpFlag; /* formant sharpening flag */ -// Word16 localVAD; -// -// Word16 tdm_pc; -// Word16 prev_fmerit; -// Word16 fmerit_dt; -// -// -// } Encoder_State, * ENC_CORE_HANDLE_FX; typedef struct GainItemStr { - int16_t gainIndex; + Word16 gainIndex; } GainItem; typedef struct context_rc_mem_struct { - int16_t nbits_old; - int16_t ctx; - Word32 bit_estimate_fx; - Word16 bit_estimate_e; - int16_t rateFlag; - int16_t lastnz; - int16_t nt_half; + Word16 nbits_old; + Word16 ctx; + Word64 bit_estimate_fx; /* Q23 */ + Word16 rateFlag; + Word16 lastnz; + Word16 nt_half; } RC_CONTEXT_MEM, *HANDLE_RC_CONTEXT_MEM; diff --git a/lib_enc/stat_noise_uv_enc.c b/lib_enc/stat_noise_uv_enc.c deleted file mode 100644 index fc894ba6cc3b0f6891e5522d7bdaa893786ada84..0000000000000000000000000000000000000000 --- a/lib_enc/stat_noise_uv_enc.c +++ /dev/null @@ -1,41 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include "prot.h" -#include "rom_com.h" -#include "wmc_auto.h" diff --git a/lib_enc/stat_noise_uv_enc_fx.c b/lib_enc/stat_noise_uv_enc_fx.c index 1045d8efd8c45b22973cc66673b87d16928ad0cb..0a20db8edddf25e93b17485f43ff53037422e996 100644 --- a/lib_enc/stat_noise_uv_enc_fx.c +++ b/lib_enc/stat_noise_uv_enc_fx.c @@ -11,7 +11,6 @@ #include "prot_fx.h" /* Function prototypes */ #include "prot_fx_enc.h" /* Function prototypes */ -#include "prot.h" /*======================================================================*/ /* FUNCTION : stat_noise_uv_enc_fx */ @@ -49,10 +48,13 @@ void stat_noise_uv_enc_fx( Word16 Q_new ) { Word16 noisiness = 0; + move16(); Word16 num, den, expn, expd; #ifdef BASOP_NOGLOB_DECLARE_LOCAL Flag Overflow = 0; + move16(); #endif + test(); test(); test(); IF( ( EQ_16( st_fx->coder_type, UNVOICED ) && uc_two_stage_flag == 0 ) || ( EQ_16( st_fx->coder_type, INACTIVE ) && LE_32( st_fx->core_brate, ACELP_9k60 ) ) ) @@ -63,24 +65,12 @@ void stat_noise_uv_enc_fx( *-----------------------------------------------------------------*/ /* epsP[2] is located in LepsP[0] and epsP[16] in LepsP[1] */ expn = sub( norm_l( LepsP[0] ), 1 ); -#ifdef BASOP_NOGLOB num = extract_h( L_shl_o( LepsP[0], expn, &Overflow ) ); /*expn-16*/ -#else - num = extract_h( L_shl( LepsP[0], expn ) ); /*expn-16*/ -#endif expd = norm_l( LepsP[1] ); -#ifdef BASOP_NOGLOB - den = extract_h( L_shl_o( LepsP[1], expd, &Overflow ) ); /*expd-16*/ -#else - den = extract_h( L_shl( LepsP[1], expd ) ); /*expd-16*/ -#endif - num = div_s( num, den ); /*expn-expd+15*/ -#ifdef BASOP_NOGLOB + den = extract_h( L_shl_o( LepsP[1], expd, &Overflow ) ); /*expd-16*/ + num = div_s( num, den ); /*expn-expd+15*/ num = shr_o( num, add( sub( expn, expd ), 5 ), &Overflow ); /*Q10*/ -#else - num = shr( num, add( sub( expn, expd ), 5 ) ); /*Q10*/ -#endif - num = sub( num, 1024 ); /*num - 1*/ + num = sub( num, 1024 ); /*num - 1*/ test(); IF( NE_16( st_fx->bwidth, NB ) ) @@ -148,24 +138,12 @@ void stat_noise_uv_enc_ivas_fx( *-----------------------------------------------------------------*/ /* epsP[2] is located in LepsP[0] and epsP[16] in LepsP[1] */ expn = sub( norm_l( LepsP[0] ), 1 ); -#ifdef BASOP_NOGLOB num = extract_h( L_shl_o( LepsP[0], expn, &Overflow ) ); /*expn-16*/ -#else - num = extract_h( L_shl( LepsP[0], expn ) ); /*expn-16*/ -#endif expd = norm_l( LepsP[1] ); -#ifdef BASOP_NOGLOB - den = extract_h( L_shl_o( LepsP[1], expd, &Overflow ) ); /*expd-16*/ -#else - den = extract_h( L_shl( LepsP[1], expd ) ); /*expd-16*/ -#endif - num = div_s( num, den ); /*expn-expd+15*/ -#ifdef BASOP_NOGLOB + den = extract_h( L_shl_o( LepsP[1], expd, &Overflow ) ); /*expd-16*/ + num = div_s( num, den ); /*expn-expd+15*/ num = shr_o( num, add( sub( expn, expd ), 5 ), &Overflow ); /*Q10*/ -#else - num = shr( num, add( sub( expn, expd ), 5 ) ); /*Q10*/ -#endif - num = sub( num, 1024 ); /*num - 1*/ + num = sub( num, 1024 ); /*num - 1*/ test(); IF( NE_16( st_fx->bwidth, NB ) ) diff --git a/lib_enc/subband_fft.c b/lib_enc/subband_fft.c deleted file mode 100644 index 8d4adb219f2e97f01fc9e529ffbc94de34a8fde5..0000000000000000000000000000000000000000 --- a/lib_enc/subband_fft.c +++ /dev/null @@ -1,42 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include -#include "prot.h" -#include "rom_enc.h" -#include "wmc_auto.h" diff --git a/lib_enc/subband_fft_fx.c b/lib_enc/subband_fft_fx.c index 83a1b41dd1dc30fe79f5b36f00f8f584d2ead612..10de09fe95e85e1dbbbc7ef6f6686115770cbbc6 100644 --- a/lib_enc/subband_fft_fx.c +++ b/lib_enc/subband_fft_fx.c @@ -107,7 +107,7 @@ static void passf4_1_16( UWord16 i; - for ( i = 0; i < 4; i++ ) + FOR( i = 0; i < 4; i++ ) { cmplx_s c2, c3, c4, t1, t2, t3, t4; @@ -142,7 +142,7 @@ static void passf4_2_16( Word16 k; - for ( k = 0; k < 4; k++ ) + FOR( k = 0; k < 4; k++ ) { cmplx_s t1, t2, t3, t4; diff --git a/lib_enc/swb_bwe_enc.c b/lib_enc/swb_bwe_enc.c deleted file mode 100644 index f633228119386e13dda4efacbed7ef242c8cb4c2..0000000000000000000000000000000000000000 --- a/lib_enc/swb_bwe_enc.c +++ /dev/null @@ -1,54 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include -#include "cnst.h" -#include "prot.h" -#include "rom_com.h" -#include "rom_enc.h" -#include "basop_util.h" -#include "basop_proto_func.h" -#include "wmc_auto.h" -#include "prot_fx.h" - - -/*-------------------------------------------------------------------* - * fd_bwe_enc_init() - * - * Initialize FD BWE state structure at the encoder - *-------------------------------------------------------------------*/ diff --git a/lib_enc/swb_bwe_enc_fx.c b/lib_enc/swb_bwe_enc_fx.c index ef16b333c8ba897e299e4bfa8a3b6f88d9f4ec51..44f415dc72a3a19a7ab46eefd21661bec8f5ce8b 100644 --- a/lib_enc/swb_bwe_enc_fx.c +++ b/lib_enc/swb_bwe_enc_fx.c @@ -4,12 +4,11 @@ #include #include "options.h" -#include "prot.h" +#include "prot_fx.h" #include "cnst.h" #include "rom_com_fx.h" #include "rom_com.h" #include "stl.h" -#include "prot_fx.h" /* Function prototypes */ #include "prot_fx_enc.h" /* Function prototypes */ /*---------------------------------------------------------------------* @@ -130,6 +129,7 @@ void wb_bwe_enc_fx( ) { Word16 mode = 0; + move16(); Word16 Sample_Delay_WB_BWE; Word16 old_input_fx[NS2SA( 16000, DELAY_FD_BWE_ENC_NS + DELAY_FIR_RESAMPL_NS ) + L_FRAME16k]; Word32 yorig_32[L_FRAME16k]; @@ -183,13 +183,14 @@ void wb_bwe_enc_fx( scl = s_min( Q_synth, scl ); } Copy_Scale_sig32_16( yorig_32, yorig_fx, L_FRAME16k, scl ); - Q_synth = add( sub( new_input_fx_exp, 16 ), scl ) - 1; + Q_synth = sub( add( sub( new_input_fx_exp, 16 ), scl ), 1 ); mode = WB_BWE_encoding_fx( coder_type, yorig_fx, WB_fenv_fx, st_fx, Q_synth, Q_synth ); - push_indice_fx( st_fx->hBstr, IND_WB_CLASS, mode - 2, 1 ); + push_indice_fx( st_fx->hBstr, IND_WB_CLASS, sub( mode, 2 ), 1 ); } hBWE_FD->prev_mode = mode; + move16(); return; } @@ -206,6 +207,7 @@ void wb_bwe_enc_ivas_fx( ) { Word16 mode = 0; + move16(); Word16 Sample_Delay_WB_BWE; Word16 old_input_fx[NS2SA( 16000, DELAY_FD_BWE_ENC_NS + DELAY_FIR_RESAMPL_NS ) + L_FRAME16k]; Word32 yorig_32[L_FRAME16k]; @@ -216,15 +218,14 @@ void wb_bwe_enc_ivas_fx( Word16 Q_synth; FD_BWE_ENC_HANDLE hBWE_FD = st_fx->hBWE_FD; Word16 WB_fenv_fx[SWB_FENV]; - move16(); - IF( GT_32( st_fx->extl_brate, 0 ) ) + IF( st_fx->extl_brate > 0 ) { /*---------------------------------------------------------------------* * Delay the original input signal to be synchronized with ACELP core synthesis *---------------------------------------------------------------------*/ - set16_fx( old_input_fx, 0, NS2SA_FX2( 16000, DELAY_FD_BWE_ENC_12k8_NS + DELAY_FIR_RESAMPL_NS ) + L_FRAME16k ); - Sample_Delay_WB_BWE = NS2SA_FX2( 16000, DELAY_FD_BWE_ENC_12k8_NS ); + set16_fx( old_input_fx, 0, NS2SA( 16000, DELAY_FD_BWE_ENC_12k8_NS + DELAY_FIR_RESAMPL_NS ) + L_FRAME16k ); + Sample_Delay_WB_BWE = NS2SA( 16000, DELAY_FD_BWE_ENC_12k8_NS ); move16(); new_input_fx = old_input_fx + Sample_Delay_WB_BWE; @@ -261,10 +262,11 @@ void wb_bwe_enc_ivas_fx( scl = s_min( Q_synth, scl ); } Copy_Scale_sig32_16( yorig_32, yorig_fx, L_FRAME16k, scl ); - Q_synth = add( sub( new_input_fx_exp, 16 ), scl ) - 1; + Q_synth = sub( add( sub( new_input_fx_exp, 16 ), scl ), 1 ); mode = WB_BWE_encoding_ivas_fx( st_fx, yorig_fx, WB_fenv_fx, Q_synth, Q_synth ); - push_indice( st_fx->hBstr, IND_WB_CLASS, mode - 2, 1 ); + move16(); + push_indice( st_fx->hBstr, IND_WB_CLASS, sub( mode, 2 ), 1 ); } hBWE_FD->prev_mode = mode; @@ -280,7 +282,7 @@ void wb_bwe_enc_ivas_fx( *-------------------------------------------------------------------*/ void swb_bwe_enc_ivas_fx( Encoder_State *st_fx, /* i/o: encoder state structure */ - const int16_t last_element_mode, /* i : last element mode */ + const Word16 last_element_mode, /* i : last element mode */ Word16 *old_input_12k8_fx, /* i : input signal @12.8kHz for SWB BWE */ Word16 *old_input_16k_fx, /* i : input signal @16kHz for SWB BWE */ const Word16 *old_syn_12k8_16k_fx, /* i : ACELP core synthesis at 12.8kHz or 16kHz */ @@ -322,6 +324,9 @@ void swb_bwe_enc_ivas_fx( move32(); #endif Word16 fb_band_begin; +#ifdef FIX_ISSUE_1230 + Word16 q_new_input_hp; +#endif FD_BWE_ENC_HANDLE hBWE_FD = st_fx->hBWE_FD; TD_BWE_ENC_HANDLE hBWE_TD = st_fx->hBWE_TD; @@ -335,21 +340,21 @@ void swb_bwe_enc_ivas_fx( inner_frame = L_FRAME48k; move16(); inner_Fs = 48000; - move16(); + move32(); } ELSE { inner_frame = L_FRAME32k; move16(); inner_Fs = 32000; - move16(); + move32(); } - set16_fx( old_input_fx, 0, add( NS2SA( inner_Fs, DELAY_FD_BWE_ENC_12k8_NS + DELAY_FIR_RESAMPL_NS ), inner_frame ) ); + set16_fx( old_input_fx, 0, add( NS2SA_FX2( inner_Fs, DELAY_FD_BWE_ENC_12k8_NS + DELAY_FIR_RESAMPL_NS ), inner_frame ) ); IF( EQ_16( st_fx->L_frame, L_FRAME ) ) { - Sample_Delay_SWB_BWE = NS2SA( inner_Fs, DELAY_FD_BWE_ENC_12k8_NS + DELAY_FIR_RESAMPL_NS ); + Sample_Delay_SWB_BWE = NS2SA_FX2( inner_Fs, DELAY_FD_BWE_ENC_12k8_NS + DELAY_FIR_RESAMPL_NS ); Sample_Delay_HP = NS2SA( 16000, ACELP_LOOK_NS + DELAY_FD_BWE_ENC_12k8_NS + DELAY_FIR_RESAMPL_NS - DELAY_CLDFB_NS ); IF( EQ_16( st_fx->element_mode, IVAS_CPE_TD ) ) { @@ -359,7 +364,7 @@ void swb_bwe_enc_ivas_fx( IF( st_fx->element_mode > EVS_MONO ) { - Sample_Delay_SWB_BWE = sub( Sample_Delay_SWB_BWE, NS2SA( inner_Fs, DELAY_FIR_RESAMPL_NS ) ); + Sample_Delay_SWB_BWE = sub( Sample_Delay_SWB_BWE, NS2SA_FX2( inner_Fs, DELAY_FIR_RESAMPL_NS ) ); Sample_Delay_HP = sub( Sample_Delay_HP, NS2SA( 16000, DELAY_FIR_RESAMPL_NS ) ); IF( EQ_16( st_fx->element_mode, IVAS_CPE_DFT ) ) @@ -374,7 +379,7 @@ void swb_bwe_enc_ivas_fx( } ELSE { - Sample_Delay_SWB_BWE = NS2SA( inner_Fs, DELAY_FD_BWE_ENC_16k_NS + DELAY_FIR_RESAMPL_NS ); + Sample_Delay_SWB_BWE = NS2SA_FX2( inner_Fs, DELAY_FD_BWE_ENC_16k_NS + DELAY_FIR_RESAMPL_NS ); Sample_Delay_HP = NS2SA( 16000, ACELP_LOOK_NS + DELAY_FD_BWE_ENC_16k_NS + DELAY_FIR_RESAMPL_NS - DELAY_CLDFB_NS ); IF( EQ_16( st_fx->element_mode, IVAS_CPE_TD ) ) { @@ -383,7 +388,7 @@ void swb_bwe_enc_ivas_fx( Sample_Delay_LP = NS2SA( 16000, ACELP_LOOK_NS + DELAY_FD_BWE_ENC_16k_NS ); IF( st_fx->element_mode > EVS_MONO ) { - Sample_Delay_SWB_BWE = sub( Sample_Delay_SWB_BWE, NS2SA( inner_Fs, DELAY_FIR_RESAMPL_NS ) ); + Sample_Delay_SWB_BWE = sub( Sample_Delay_SWB_BWE, NS2SA_FX2( inner_Fs, DELAY_FIR_RESAMPL_NS ) ); Sample_Delay_HP = sub( Sample_Delay_HP, NS2SA( 16000, DELAY_FIR_RESAMPL_NS ) ); IF( EQ_16( st_fx->element_mode, IVAS_CPE_DFT ) ) @@ -397,8 +402,25 @@ void swb_bwe_enc_ivas_fx( Copy( old_input_16k_fx + L_INP_MEM + L_FRAME16k - Sample_Delay_LP, hBWE_FD->old_input_lp_fx, Sample_Delay_LP ); } +#ifdef FIX_ISSUE_1230 + q_new_input_hp = s_min( Q_shb_speech, hBWE_FD->Q_new_input_hp ); + IF( LT_16( Q_shb_speech, hBWE_FD->Q_new_input_hp ) ) + { + Copy_Scale_sig( hBWE_FD->new_input_hp_fx, new_input_hp_fx, Sample_Delay_HP, sub( Q_shb_speech, hBWE_FD->Q_new_input_hp ) ); // Q_shb_speech + Copy( shb_speech_fx, &new_input_hp_fx[Sample_Delay_HP], L_FRAME16k - Sample_Delay_HP ); // Q_shb_speech + } + ELSE + { + Copy( hBWE_FD->new_input_hp_fx, new_input_hp_fx, Sample_Delay_HP ); // hBWE_FD->Q_new_input_hp + Copy_Scale_sig( shb_speech_fx, &new_input_hp_fx[Sample_Delay_HP], L_FRAME16k - Sample_Delay_HP, sub( hBWE_FD->Q_new_input_hp, Q_shb_speech ) ); // hBWE_FD->Q_new_input_hp + } + + hBWE_FD->Q_new_input_hp = Q_shb_speech; + move16(); +#else Copy( hBWE_FD->new_input_hp_fx, new_input_hp_fx, Sample_Delay_HP ); Copy( shb_speech_fx, &new_input_hp_fx[Sample_Delay_HP], L_FRAME16k - Sample_Delay_HP ); +#endif Copy( shb_speech_fx + L_FRAME16k - Sample_Delay_HP, hBWE_FD->new_input_hp_fx, Sample_Delay_HP ); new_input_fx = old_input_fx + Sample_Delay_SWB_BWE; Copy( hBWE_FD->old_input_fx, old_input_fx, Sample_Delay_SWB_BWE ); @@ -409,11 +431,7 @@ void swb_bwe_enc_ivas_fx( *----------------------------------------------------------------------*/ /* tilt returned in Q24 goto to Q11 */ -#ifdef BASOP_NOGLOB tilt_nb_fx = round_fx_o( L_shl_o( calc_tilt_bwe_fx( old_input_lp_fx, Q_slb_speech, st_fx->L_frame ), 3, &Overflow ), &Overflow ); -#else - tilt_nb_fx = round_fx( L_shl( calc_tilt_bwe_fx( old_input_lp_fx, Q_slb_speech, st_fx->L_frame ), 3 ) ); -#endif /*---------------------------------------------------------------------* * SWB BWE encoding * FB BWE encoding @@ -486,6 +504,7 @@ void swb_bwe_enc_ivas_fx( } Copy_Scale_sig( &yorig_fx[scl], &yorig_fx[scl], sub( inner_frame, scl ), exp ); Q_synth_hf = add( exp, Q_synth ); + test(); IF( EQ_16( st_fx->last_extl, SWB_BWE ) || EQ_16( st_fx->last_extl, FB_BWE ) ) { @@ -499,7 +518,7 @@ void swb_bwe_enc_ivas_fx( ELSE { Q_shb = shr( add( st_fx->EnergyLT_fx_exp, exp ), 1 ); - IF( EQ_16( s_and( exp, 0x0001 ), 1 ) ) + if ( EQ_16( s_and( exp, 0x0001 ), 1 ) ) { exp = sub( exp, 1 ); } @@ -511,14 +530,18 @@ void swb_bwe_enc_ivas_fx( { Q_shb = sub( Q_synth_hf, 4 ); } +#ifdef FIX_ISSUE_1230 + Copy_Scale_sig( new_input_hp_fx, new_input_hp_fx, L_FRAME16k, sub( Q_shb, q_new_input_hp ) ); +#else Copy_Scale_sig( new_input_hp_fx, new_input_hp_fx, L_FRAME16k, sub( Q_shb, Q_shb_speech ) ); +#endif /* FB BWE encoding */ IF( EQ_16( st_fx->extl, FB_BWE ) ) { fb_band_begin = FB_BAND_BEGIN; move16(); - IF( EQ_16( st_fx->L_frame, L_FRAME ) ) + if ( EQ_16( st_fx->L_frame, L_FRAME ) ) { fb_band_begin = FB_BAND_BEGIN_12k8; move16(); @@ -546,12 +569,8 @@ void swb_bwe_enc_ivas_fx( exp1 = norm_l( L_tmp ); L_tmp = L_shl( L_tmp, exp1 ); exp = sub( sub( 31, exp1 ), sub( 30, exp ) ); - L_tmp = Isqrt_lc( L_tmp, &exp ); /*31-exp */ -#ifdef BASOP_NOGLOB + L_tmp = Isqrt_lc( L_tmp, &exp ); /*31-exp */ fb_ener_adjust_fx = round_fx_o( L_shl_o( L_tmp, exp, &Overflow ), &Overflow ); /*Q15 */ -#else - fb_ener_adjust_fx = round_fx( L_shl( L_tmp, exp ) ); /*Q15 */ -#endif } ELSE { @@ -567,7 +586,7 @@ void swb_bwe_enc_ivas_fx( IF( EQ_16( st_fx->L_frame, L_FRAME16k ) ) { SWB_BWE_encoding_ivas_fx( st_fx, old_input_fx, old_input_lp_fx, new_input_hp_fx, old_syn_12k8_16k_fx, yorig_32, - SWB_fenv_fx, tilt_nb_fx, 80, Q_slb_speech, Q_shb, new_input_fx_exp, Q_synth ); + SWB_fenv_fx, tilt_nb_fx, 80, Q_slb_speech, Q_shb, new_input_fx_exp, new_input_fx_exp ); } ELSE { @@ -620,16 +639,20 @@ void swb_bwe_enc_fx( Word16 Sample_Delay_HP; Word16 Sample_Delay_LP; Word16 idxGain = 0; + move16(); Word16 Q_synth_hf, Q_synth, Q_shb; Word16 tilt_nb_fx; Word16 SWB_fenv_fx[SWB_FENV]; Word32 ener_low_fx; Word32 energy_fbe_fb_fx = 0; + move32(); Word16 fb_ener_adjust_fx; Word16 ener_adjust_quan_fx = 0; + move16(); #ifdef BASOP_NOGLOB_DECLARE_LOCAL Flag Overflow = 0; + move32(); #endif FD_BWE_ENC_HANDLE hBWE_FD = st_fx->hBWE_FD; @@ -641,19 +664,23 @@ void swb_bwe_enc_fx( IF( EQ_16( st_fx->extl, FB_BWE ) ) { inner_frame = L_FRAME48k; + move16(); inner_Fs = 48000; + move32(); } ELSE { inner_frame = L_FRAME32k; + move16(); inner_Fs = 32000; + move32(); } - set16_fx( old_input_fx, 0, add( NS2SA( inner_Fs, DELAY_FD_BWE_ENC_12k8_NS + DELAY_FIR_RESAMPL_NS ), inner_frame ) ); + set16_fx( old_input_fx, 0, add( NS2SA_FX2( inner_Fs, DELAY_FD_BWE_ENC_12k8_NS + DELAY_FIR_RESAMPL_NS ), inner_frame ) ); IF( EQ_16( st_fx->L_frame, L_FRAME ) ) { - Sample_Delay_SWB_BWE = NS2SA( inner_Fs, DELAY_FD_BWE_ENC_12k8_NS + DELAY_FIR_RESAMPL_NS ); + Sample_Delay_SWB_BWE = NS2SA_FX2( inner_Fs, DELAY_FD_BWE_ENC_12k8_NS + DELAY_FIR_RESAMPL_NS ); Sample_Delay_HP = NS2SA( 16000, ACELP_LOOK_NS + DELAY_FD_BWE_ENC_12k8_NS + DELAY_FIR_RESAMPL_NS - DELAY_CLDFB_NS ); Sample_Delay_LP = NS2SA( 12800, ACELP_LOOK_NS + DELAY_FD_BWE_ENC_12k8_NS ); @@ -661,12 +688,15 @@ void swb_bwe_enc_fx( } ELSE { - Sample_Delay_SWB_BWE = NS2SA( inner_Fs, DELAY_FD_BWE_ENC_16k_NS + DELAY_FIR_RESAMPL_NS ); + Sample_Delay_SWB_BWE = NS2SA_FX2( inner_Fs, DELAY_FD_BWE_ENC_16k_NS + DELAY_FIR_RESAMPL_NS ); Sample_Delay_HP = NS2SA( 16000, ACELP_LOOK_NS + DELAY_FD_BWE_ENC_16k_NS + DELAY_FIR_RESAMPL_NS - DELAY_CLDFB_NS ); Sample_Delay_LP = NS2SA( 16000, ACELP_LOOK_NS + DELAY_FD_BWE_ENC_16k_NS ); delay_input_signal_fx( hBWE_FD->old_input_lp_fx, old_input_lp_fx, &old_input_16k_fx[L_INP_MEM], Sample_Delay_LP, L_FRAME16k, &hBWE_FD->prev_Q_input_lp, &Q_slb_speech ); } + move16(); + move16(); + move16(); Copy( hBWE_FD->new_input_hp_fx, new_input_hp_fx, Sample_Delay_HP ); Copy( shb_speech_fx, &new_input_hp_fx[Sample_Delay_HP], L_FRAME16k - Sample_Delay_HP ); @@ -680,16 +710,13 @@ void swb_bwe_enc_fx( *----------------------------------------------------------------------*/ /* tilt returned in Q24 goto to Q11 */ -#ifdef BASOP_NOGLOB tilt_nb_fx = round_fx_o( L_shl_o( calc_tilt_bwe_fx( old_input_lp_fx, Q_slb_speech, st_fx->L_frame ), 3, &Overflow ), &Overflow ); -#else - tilt_nb_fx = round_fx( L_shl( calc_tilt_bwe_fx( old_input_lp_fx, Q_slb_speech, st_fx->L_frame ), 3 ) ); -#endif /*---------------------------------------------------------------------* * SWB BWE encoding * FB BWE encoding *---------------------------------------------------------------------*/ new_input_fx_exp = 0; + move16(); /* MDCT of the core synthesis signal */ wtda_fx( old_input_fx, &new_input_fx_exp, L_old_input_fx, hBWE_FD->L_old_wtda_swb_fx, &st_fx->Q_old_wtda, ALDO_WINDOW, ALDO_WINDOW, /* window overlap of current frame (0: full, 2: none, or 3: half) */ @@ -719,13 +746,12 @@ void swb_bwe_enc_fx( IF( EQ_16( st_fx->L_frame, L_FRAME16k ) ) { scl = 300; - move16(); } ELSE { scl = 240; - move16(); } + move16(); FOR( i = scl; i < inner_frame; i++ ) { max = s_max( max, abs_s( yorig_fx[i] ) ); @@ -754,11 +780,12 @@ void swb_bwe_enc_fx( ELSE { Q_shb = shr( add( st_fx->EnergyLT_fx_exp, exp ), 1 ); - IF( s_and( exp, 0x0001 ) == 1 ) + if ( EQ_16( s_and( exp, 0x0001 ), 1 ) ) { exp = sub( exp, 1 ); } st_fx->EnergyLT_fx = L_shl( st_fx->EnergyLT_fx, exp ); + move32(); } } ELSE @@ -803,13 +830,10 @@ void swb_bwe_enc_fx( L_tmp = Mult_32_16( ener_low_fx, tmp ); /*45-(exp+2*(Q_synth_hf-4)) + 2*(Q_synth_hf-4) - 15 = 30-exp */ exp1 = norm_l( L_tmp ); L_tmp = L_shl( L_tmp, exp1 ); - exp = 31 - exp1 - ( 30 - exp ); - L_tmp = Isqrt_lc( L_tmp, &exp ); /*31-exp */ -#ifdef BASOP_NOGLOB + // exp = 31 - exp1 - ( 30 - exp ); + exp = add( 31 - 30, sub( exp, exp1 ) ); + L_tmp = Isqrt_lc( L_tmp, &exp ); /*31-exp */ fb_ener_adjust_fx = round_fx_o( L_shl_o( L_tmp, exp, &Overflow ), &Overflow ); /*Q15 */ -#else - fb_ener_adjust_fx = round_fx( L_shl( L_tmp, exp ) ); /*Q15 */ -#endif } ELSE { @@ -857,6 +881,7 @@ static Word16 WB_BWE_fenv_q_fx( /* o: quantized gain i ) { Word16 i, j, indx = 0; + move16(); Word32 dist, min_dist; const Word16 *pit = cb; /*Q10 */ Word16 tmp; @@ -869,15 +894,9 @@ static Word16 WB_BWE_fenv_q_fx( /* o: quantized gain i dist = L_deposit_l( 0 ); FOR( j = 0; j < cb_dim; j++ ) { -#ifdef BASOP_NOGLOB tmp = sub_sat( x[j], *pit ); /*Q10 */ L_tmp = L_mult0( tmp, tmp ); /*Q(10+10)->Q20 */ dist = L_add_sat( dist, L_tmp ); -#else - tmp = sub( x[j], *pit ); /*Q10 */ - L_tmp = L_mult0( tmp, tmp ); /*Q(10+10)->Q20 */ - dist = L_add( dist, L_tmp ); -#endif pit++; } @@ -919,6 +938,7 @@ static void get_normalize_spec_fx( set16_fx( SWB_signal, 0, add( HQ_GENERIC_HIGH0, offset ) ); calc_normal_length_fx( core, org_fx, mode, extl, &L_swb_norm, prev_L_swb_norm, Q_new_lf ); + test(); IF( EQ_16( extl, SWB_BWE ) || EQ_16( extl, FB_BWE ) ) { @@ -1001,12 +1021,14 @@ static Word16 FD_BWE_class_fx( /* o : FD BWE class ) { Word16 i, j, k, noise, sharpMod = 0; + move16(); Word16 peak, mag; Word32 mean[20]; Word16 sharpPeak; const Word16 *input_hi = 0; Word16 sharp; Word16 gain_tmp = 0; + move16(); Word16 mode; Word32 L_meanH, L_mean_d, L_tmp; Word16 sharplimit; @@ -1014,9 +1036,8 @@ static Word16 FD_BWE_class_fx( /* o : FD BWE class Word16 numharmonic, tmp, expn, expd, scale; #ifdef BASOP_NOGLOB_DECLARE_LOCAL Flag Overflow = 0; - move32(); -#endif move16(); +#endif FD_BWE_ENC_HANDLE hBWE_FD = st_fx->hBWE_FD; @@ -1042,7 +1063,6 @@ static Word16 FD_BWE_class_fx( /* o : FD BWE class IF( EQ_16( st_fx->extl, SWB_BWE ) || EQ_16( st_fx->extl, FB_BWE ) ) { input_hi = &fSpectrum[256]; - move16(); numsharp = NUM_SHARP; move16(); @@ -1053,52 +1073,32 @@ static Word16 FD_BWE_class_fx( /* o : FD BWE class { IF( hBWE_FD->prev_global_gain_fx == 0 ) { -#ifdef BASOP_NOGLOB gain_tmp = round_fx_o( L_shl_o( fGain, 30, &Overflow ), &Overflow ); /*Q14 */ -#else - gain_tmp = round_fx( L_shl( fGain, 30 ) ); /*Q14 */ -#endif } ELSE { expn = norm_l( fGain ); -#ifdef BASOP_NOGLOB num = extract_h( L_shl_o( fGain, expn, &Overflow ) ); -#else - num = extract_h( L_shl( fGain, expn ) ); -#endif expn = sub( sub( 30, expn ), shl( Q_shb, 1 ) ); expd = norm_l( hBWE_FD->prev_global_gain_fx ); -#ifdef BASOP_NOGLOB den = extract_h( L_shl_o( hBWE_FD->prev_global_gain_fx, expd, &Overflow ) ); -#else - den = extract_h( L_shl( hBWE_FD->prev_global_gain_fx, expd ) ); -#endif expd = sub( sub( 30, expd ), shl( st_fx->prev_Q_shb, 1 ) ); scale = shr( sub( den, num ), 15 ); -#ifdef BASOP_NOGLOB num = shl_o( num, scale, &Overflow ); -#else - num = shl( num, scale ); -#endif expn = sub( expn, scale ); tmp = div_s( num, den ); expn = sub( expn, expd ); -#ifdef BASOP_NOGLOB gain_tmp = shl_o( tmp, sub( expn, 1 ), &Overflow ); /*Q14 */ -#else - gain_tmp = shl( tmp, sub( expn, 1 ) ); /*Q14 */ -#endif } test(); IF( EQ_16( hBWE_FD->prev_mode, TRANSIENT ) ) { numharmonic = shl( numharmonic, 1 ); } - ELSE IF( EQ_16( hBWE_FD->prev_mode, NORMAL ) || EQ_16( hBWE_FD->prev_mode, NOISE ) ) + ELSE IF( EQ_16( hBWE_FD->prev_mode, NORMAL ) || hBWE_FD->prev_mode == NOISE ) { numharmonic = add( shr( numharmonic, 1 ), numharmonic ); } @@ -1122,7 +1122,6 @@ static Word16 FD_BWE_class_fx( /* o : FD BWE class ELSE IF( EQ_16( st_fx->extl, WB_BWE ) ) { input_hi = &fSpectrum[224]; - move16(); numsharp = 3; move16(); @@ -1158,7 +1157,7 @@ static Word16 FD_BWE_class_fx( /* o : FD BWE class FOR( j = 0; j < SHARP_WIDTH; j++ ) { mag = abs_s( *input_hi ); - IF( GT_16( mag, peak ) ) + if ( GT_16( mag, peak ) ) { peak = mag; move16(); /*Q_syn */ @@ -1175,19 +1174,15 @@ static Word16 FD_BWE_class_fx( /* o : FD BWE class L_tmp = L_sub( mean[i], peak ); /*Q_syn */ L_tmp = Mpy_32_16_1( L_tmp, 16913 ); /* 1/31->Q19 -> Q_syn+19-15 */ den = extract_l( L_shr( L_tmp, 4 ) ); /*Q_syn */ - IF( den == 0 ) + if ( den == 0 ) { den = 1; move16(); } expd = norm_s( den ); - tmp = div_s( shl( 1, sub( 14, expd ) ), den ); /*Q(29-expd-Q_syn) */ - L_tmp = L_mult( tmp, peak ); /*Q(30-expd) */ -#ifdef BASOP_NOGLOB + tmp = div_s( shl( 1, sub( 14, expd ) ), den ); /*Q(29-expd-Q_syn) */ + L_tmp = L_mult( tmp, peak ); /*Q(30-expd) */ sharp = round_fx_o( L_shl_o( L_tmp, sub( expd, 4 ), &Overflow ), &Overflow ); /*Q10 */ -#else - sharp = round_fx( L_shl( L_tmp, sub( expd, 4 ) ) ); /*Q10 */ -#endif } ELSE { @@ -1196,11 +1191,7 @@ static Word16 FD_BWE_class_fx( /* o : FD BWE class } test(); -#ifdef BASOP_NOGLOB IF( GT_16( sharp, 4608 ) && GT_16( peak, shl_o( 1, add( Q_syn, 3 ), &Overflow ) ) ) -#else - IF( GT_16( sharp, 4608 ) && GT_16( peak, shl( 1, add( Q_syn, 3 ) ) ) ) -#endif { k = add( k, 1 ); move16(); @@ -1211,12 +1202,13 @@ static Word16 FD_BWE_class_fx( /* o : FD BWE class move16(); } - IF( GT_16( sharp, sharpPeak ) ) + if ( GT_16( sharp, sharpPeak ) ) { sharpPeak = sharp; move16(); } } + test(); IF( EQ_16( st_fx->extl, SWB_BWE ) || EQ_16( st_fx->extl, FB_BWE ) ) { @@ -1226,13 +1218,12 @@ static Word16 FD_BWE_class_fx( /* o : FD BWE class IF( GE_16( k, numharmonic ) && GT_16( gain_tmp, 8192 ) && LT_16( gain_tmp, 29491 ) && GT_16( sharpPeak, shl( sharplimit, 10 ) ) ) { sharpMod = 1; - move16(); } ELSE { sharpMod = 0; - move16(); } + move16(); L_meanH = Mpy_32_16_1( L_meanH, 29127 ); /*Q_syn+8 */ L_mean_d = 0; @@ -1249,13 +1240,12 @@ static Word16 FD_BWE_class_fx( /* o : FD BWE class IF( GE_16( k, numharmonic ) && GT_16( sharpPeak, shl( sharplimit, 10 ) ) ) { sharpMod = 1; - move16(); } ELSE { sharpMod = 0; - move16(); } + move16(); } test(); @@ -1271,7 +1261,7 @@ static Word16 FD_BWE_class_fx( /* o : FD BWE class move16(); } - IF( GE_16( hBWE_FD->modeCount, 2 ) ) + if ( GE_16( hBWE_FD->modeCount, 2 ) ) { sharpMod = 1; move16(); @@ -1290,7 +1280,7 @@ static Word16 FD_BWE_class_fx( /* o : FD BWE class test(); test(); test(); - IF( GT_16( noise, 4 ) && ( LT_32( L_tmp, L_meanH ) || L_meanH == 0 ) && LT_16( tilt_nb, 10240 ) ) + if ( GT_16( noise, 4 ) && ( LT_32( L_tmp, L_meanH ) || L_meanH == 0 ) && LT_16( tilt_nb, 10240 ) ) { mode = NOISE; move16(); @@ -1343,11 +1333,7 @@ static void freq_weights_fx( { exp = norm_s( tmp ); tmp = div_s( shl( 1, sub( 14, exp ) ), tmp ); /*(21-exp) */ -#ifdef BASOP_NOGLOB - tmp = shl_sat( tmp, sub( exp, 6 ) ); /*Q15 */ -#else - tmp = shl( tmp, sub( exp, 6 ) ); /*Q15 */ -#endif + tmp = shl_sat( tmp, sub( exp, 6 ) ); /*Q15 */ } ELSE { @@ -1411,22 +1397,14 @@ static void vqWithCand_w_fx( FOR( i = 0; i < E_ROM_dico_size; i++ ) { -#ifdef BASOP_NOGLOB dist = sub_o( x[0], *p_E_ROM_dico++, &Overflow ); /*Q8 */ -#else - dist = sub( x[0], *p_E_ROM_dico++ ); /*Q8 */ -#endif - L_dist = L_mult( dist, w[0] ); /*Q22 */ - L_dist = Mult_32_16( L_dist, dist ); /*Q15 */ - L_dist = L_shr( L_dist, 10 ); /*Q5 */ + L_dist = L_mult( dist, w[0] ); /*Q22 */ + L_dist = Mult_32_16( L_dist, dist ); /*Q15 */ + L_dist = L_shr( L_dist, 10 ); /*Q5 */ FOR( j = 1; j < dim; j++ ) { -#ifdef BASOP_NOGLOB temp1 = sub_o( x[j], *p_E_ROM_dico++, &Overflow ); -#else - temp1 = sub( x[j], *p_E_ROM_dico++ ); -#endif L_tmp = L_mult( temp1, w[j] ); /*Q22 */ L_tmp = Mult_32_16( L_tmp, temp1 ); /*Q15 */ L_dist = L_add( L_dist, L_shr( L_tmp, 10 ) ); /*Q5 */ @@ -1467,13 +1445,9 @@ static void vqWithCand_w_fx( FOR( i = 0; i < E_ROM_dico_size; i++ ) { -#ifdef BASOP_NOGLOB dist = sub_sat( x[0], *p_E_ROM_dico++ ); /*Q8 */ -#else - dist = sub( x[0], *p_E_ROM_dico++ ); /*Q8 */ -#endif - L_dist = L_mult( dist, dist ); /*Q17 */ - L_dist = L_shr( L_dist, 12 ); /*Q5 */ + L_dist = L_mult_sat( dist, dist ); /*Q17 */ + L_dist = L_shr( L_dist, 12 ); /*Q5 */ FOR( j = 1; j < dim; j++ ) { @@ -1588,7 +1562,7 @@ static Word16 vqSimple_w_fx( /* Reading the selected vector */ - Copy( &cb[i_mult( index, dim )], y, dim ); + Copy( &cb[index * dim], y, dim ); return ( index ); } @@ -1741,26 +1715,20 @@ static void msvq_interpol_fx( } ind_tmp[0] = vqSimple_w_fx( quant_tmp2, quant_tmp2, EnvCdbk1st_fx, w_env11, DIM1ST, N_CB1ST, 1 ); + move16(); ind_tmp[1] = vqSimple_w_fx( quant_tmp2 + DIM1ST, quant_tmp2 + DIM1ST, EnvCdbk2nd_fx, w_env11 + DIM1ST, DIM2ND, N_CB2ND, 1 ); + move16(); /* Extract vector for odd position */ FOR( n_band = 0; n_band < DIM11; n_band++ ) { -#ifdef BASOP_NOGLOB quant_tmp[n_band] = add_o( quant_tmp1[n_band], quant_tmp2[n_band], &Overflow ); -#else - quant_tmp[n_band] = add( quant_tmp1[n_band], quant_tmp2[n_band] ); -#endif move16(); } FOR( n_band = 0; n_band < DIM12 - 1; n_band++ ) { -#ifdef BASOP_NOGLOB tmp = add_o( quant_tmp[n_band], quant_tmp[n_band + 1], &Overflow ); /*Q8 */ -#else - tmp = add( quant_tmp[n_band], quant_tmp[n_band + 1] ); /*Q8 */ -#endif tmp = shr( tmp, 1 ); quant_tmp2[n_band] = sub( env_temp12[n_band], tmp ); move16(); /*Q8 */ @@ -1783,16 +1751,12 @@ static void msvq_interpol_fx( FOR( n_band = 0; n_band < DIM12 - 1; n_band++ ) { -#ifdef BASOP_NOGLOB tmp = add_o( quant_tmp[n_band], quant_tmp[n_band + 1], &Overflow ); -#else - tmp = add( quant_tmp[n_band], quant_tmp[n_band + 1] ); -#endif tmp = shr( tmp, 1 ); - quant_select[add( shl( n_band, 1 ), 1 )] = add( tmp, quant_tmp2[n_band] ); + quant_select[( n_band << 1 ) + 1] = add( tmp, quant_tmp2[n_band] ); move16(); /*Q8 */ } - quant_select[add( shl( n_band, 1 ), 1 )] = add( quant_tmp[n_band], quant_tmp2[n_band] ); + quant_select[( n_band << 1 ) + 1] = add( quant_tmp[n_band], quant_tmp2[n_band] ); move16(); /*Q8 */ L_dist = L_deposit_l( 0 ); @@ -1907,15 +1871,9 @@ static void msvq_interpol_2_fx( move16(); FOR( n_band = 1; n_band < DIM12 - 1; n_band++ ) { -#ifdef BASOP_NOGLOB tmp_q = add_o( quant_tmp[n_band - 1], quant_tmp[n_band], &Overflow ); tmp_q = shr( tmp_q, 1 ); quant_tmp2[n_band] = sub_o( env_temp12[n_band], tmp_q, &Overflow ); -#else - tmp_q = add( quant_tmp[n_band - 1], quant_tmp[n_band] ); - tmp_q = shr( tmp_q, 1 ); - quant_tmp2[n_band] = sub( env_temp12[n_band], tmp_q ); -#endif move16(); } @@ -1936,15 +1894,9 @@ static void msvq_interpol_2_fx( move16(); /*Q8 */ FOR( n_band = 1; n_band < DIM12 - 1; n_band++ ) { -#ifdef BASOP_NOGLOB tmp_q = add_o( quant_tmp[n_band - 1], quant_tmp[n_band], &Overflow ); tmp_q = shr( tmp_q, 1 ); - quant_select[sub( shl( n_band, 1 ), 1 )] = add_o( quant_tmp2[n_band], tmp_q, &Overflow ); -#else - tmp_q = add( quant_tmp[n_band - 1], quant_tmp[n_band] ); - tmp_q = shr( tmp_q, 1 ); - quant_select[sub( shl( n_band, 1 ), 1 )] = add( quant_tmp2[n_band], tmp_q ); -#endif + quant_select[( n_band << 1 ) - 1] = add_o( quant_tmp2[n_band], tmp_q, &Overflow ); } L_dist = L_deposit_l( 0 ); @@ -1957,7 +1909,7 @@ static void msvq_interpol_2_fx( } /* Check optimal candidate */ - IF( L_dist < L_minDist ) + IF( LT_32( L_dist, L_minDist ) ) { L_minDist = L_add( L_dist, 0 ); Copy( quant_select, synth_energy, SWB_FENV - 2 ); @@ -2053,11 +2005,7 @@ static void calculate_Tonality_fx( l_shift = norm_s( max ); FOR( n_coeff = 0; n_coeff < length; n_coeff++ ) { -#ifdef BASOP_NOGLOB gen_spec[n_coeff] = shl_sat( gen_spec[n_coeff], l_shift ); -#else - gen_spec[n_coeff] = shl( gen_spec[n_coeff], l_shift ); -#endif move16(); IF( gen_spec[n_coeff] == 0 ) { @@ -2118,11 +2066,7 @@ static void calculate_Tonality_fx( L_tmp2 = Mpy_32_16_1( L_log_gm_org, inv_len ); /* Q14 */ L_tmp = L_sub( L_tmp1, L_tmp2 ); -#ifdef BASOP_NOGLOB *SFM_org = round_fx_o( L_shl_o( L_tmp, 14, &Overflow ), &Overflow ); /*Q12 */ -#else - *SFM_org = round_fx( L_shl( L_tmp, 14 ) ); /*Q12 */ -#endif move16(); *SFM_org = s_max( 0, s_min( *SFM_org, 24547 ) ); move16(); /*0.0001 and 5.993 in Q12 */ @@ -2143,11 +2087,7 @@ static void calculate_Tonality_fx( L_tmp2 = Mpy_32_16_1( L_log_gm_gen, inv_len ); /* Q14 */ L_tmp = L_sub( L_tmp1, L_tmp2 ); -#ifdef BASOP_NOGLOB *SFM_gen = round_fx_o( L_shl_o( L_tmp, 14, &Overflow ), &Overflow ); /*Q12 */ -#else - *SFM_gen = round_fx( L_shl( L_tmp, 14 ) ); /*Q12 */ -#endif move16(); *SFM_gen = s_max( 0, s_min( *SFM_gen, 24547 ) ); move16(); /*0.0001 and 5.993 in Q12 */ @@ -2223,11 +2163,7 @@ static void calculate_Tonality_ivas_fx( l_shift = norm_s( max ); FOR( n_coeff = 0; n_coeff < length; n_coeff++ ) { -#ifdef BASOP_NOGLOB gen_spec[n_coeff] = shl_sat( gen_spec[n_coeff], l_shift ); -#else - gen_spec[n_coeff] = shl( gen_spec[n_coeff], l_shift ); -#endif move16(); IF( gen_spec[n_coeff] == 0 ) { @@ -2288,11 +2224,7 @@ static void calculate_Tonality_ivas_fx( L_tmp2 = Mpy_32_16_1( L_log_gm_org, inv_len ); /* Q14 */ L_tmp = L_sub( L_tmp1, L_tmp2 ); -#ifdef BASOP_NOGLOB *SFM_org = round_fx_o( L_shl_o( L_tmp, 14, &Overflow ), &Overflow ); /*Q12 */ -#else - *SFM_org = round_fx( L_shl( L_tmp, 14 ) ); /*Q12 */ -#endif move16(); *SFM_org = s_max( 0, s_min( *SFM_org, 24547 ) ); move16(); /*0.0001 and 5.993 in Q12 */ @@ -2313,11 +2245,7 @@ static void calculate_Tonality_ivas_fx( L_tmp2 = Mpy_32_16_1( L_log_gm_gen, inv_len ); /* Q14 */ L_tmp = L_sub( L_tmp1, L_tmp2 ); -#ifdef BASOP_NOGLOB *SFM_gen = round_fx_o( L_shl_o( L_tmp, 14, &Overflow ), &Overflow ); /*Q12 */ -#else - *SFM_gen = round_fx( L_shl( L_tmp, 14 ) ); /*Q12 */ -#endif move16(); *SFM_gen = s_max( 0, s_min( *SFM_gen, 24547 ) ); move16(); /*0.0001 and 5.993 in Q12 */ @@ -2353,29 +2281,26 @@ static void energy_control_fx( IF( NE_16( coder_type, AUDIO ) && LT_32( st_fx->total_brate, ACELP_8k85 ) ) { core_type = 0; - move16(); } ELSE { core_type = 1; - move16(); } + move16(); get_normalize_spec_fx( core, st_fx->extl, mode, core_type, org_fx, SWB_signal_fx, &( hBWE_FD->prev_L_swb_norm1 ), offset, Q_new_lf ); IF( EQ_16( st_fx->extl, WB_BWE ) ) { max_band = 4; - move16(); band_step = 2; - move16(); } ELSE { max_band = SWB_FENV; - move16(); band_step = 1; - move16(); } + move16(); + move16(); } ELSE /* HQ core */ { @@ -2388,13 +2313,12 @@ static void energy_control_fx( IF( EQ_16( offset, HQ_GENERIC_FOFFSET_32K ) ) { max_band = 12; - move16(); } ELSE { max_band = SWB_FENV; - move16(); } + move16(); } FOR( n_band = 0; n_band < max_band; ) @@ -2405,7 +2329,7 @@ static void energy_control_fx( IF( LT_16( SFM_gen_fx[n_band], mult_r( 24576, SFM_org_fx[n_band] ) ) ) { energy_factor_fx[n_band] = div_s( SFM_gen_fx[n_band], SFM_org_fx[n_band] ); /*Q15 */ - IF( LT_16( energy_factor_fx[n_band], gamma_fx ) ) + if ( LT_16( energy_factor_fx[n_band], gamma_fx ) ) { energy_factor_fx[n_band] = gamma_fx; move16(); @@ -2449,29 +2373,26 @@ static void energy_control_ivas_fx( IF( NE_16( coder_type, AUDIO ) && LE_32( st_fx->total_brate, ACELP_8k00 ) ) { core_type = 0; - move16(); } ELSE { core_type = 1; - move16(); } + move16(); get_normalize_spec_fx( core, st_fx->extl, mode, core_type, org_fx, SWB_signal_fx, &( hBWE_FD->prev_L_swb_norm1 ), offset, Q_new_lf ); IF( EQ_16( st_fx->extl, WB_BWE ) ) { max_band = 4; - move16(); band_step = 2; - move16(); } ELSE { max_band = SWB_FENV; - move16(); band_step = 1; - move16(); } + move16(); + move16(); } ELSE /* HQ core */ { @@ -2484,13 +2405,12 @@ static void energy_control_ivas_fx( IF( EQ_16( offset, HQ_GENERIC_FOFFSET_32K ) ) { max_band = 12; - move16(); } ELSE { max_band = SWB_FENV; - move16(); } + move16(); } FOR( n_band = 0; n_band < max_band; ) @@ -2502,7 +2422,7 @@ static void energy_control_ivas_fx( { energy_factor_fx[n_band] = div_s( SFM_gen_fx[n_band], SFM_org_fx[n_band] ); /*Q15 */ move16(); - IF( LT_16( energy_factor_fx[n_band], gamma_fx ) ) + if ( LT_16( energy_factor_fx[n_band], gamma_fx ) ) { energy_factor_fx[n_band] = gamma_fx; move16(); @@ -2573,6 +2493,7 @@ Word16 WB_BWE_encoding_fx( /* o : classification of wb exp = sub( sub( 30, exp ), ( sub( shl( Q_synth, 1 ), 2 ) ) ); L_tmp = Mpy_32_16( exp, tmp, 32767 ); /* Q16 */ WB_fenv_fx[i] = round_fx( L_shl( L_tmp, 10 ) ); /*Q10 */ + move16(); } ELSE { @@ -2701,6 +2622,7 @@ static Word16 SWB_BWE_encoding_fx( Word16 energy_factor_fx[SWB_FENV], w_env_fx[SWB_FENV]; #ifdef BASOP_NOGLOB_DECLARE_LOCAL Flag Overflow = 0; + move16(); #endif FD_BWE_ENC_HANDLE hBWE_FD = st_fx->hBWE_FD; @@ -2709,13 +2631,12 @@ static Word16 SWB_BWE_encoding_fx( IF( EQ_16( st_fx->L_frame, L_FRAME ) ) { L = L_SUBFR; - move16(); } ELSE { L = L_SUBFR16k; - move16(); } + move16(); /* HF transient detect */ IsTransient = detect_transient_fx( insig_hp_fx, L_FRAME16k, Q_shb, st_fx ); @@ -2733,7 +2654,7 @@ static Word16 SWB_BWE_encoding_fx( energy_fx = L_add( energy_fx, L_shr( L_mult0( insig_lp_fx[i + tmp], insig_lp_fx[i + tmp] ), 7 ) ); /*2*Q_slb_speech - 7 */ } - IF( GT_32( Mult_32_16( energy_fx, 5958 ), hBWE_FD->EnergyLF_fx ) ) + if ( GT_32( Mult_32_16( energy_fx, 5958 ), hBWE_FD->EnergyLF_fx ) ) { IsTransient_LF = 1; move16(); @@ -2744,11 +2665,7 @@ static Word16 SWB_BWE_encoding_fx( } /* tilt returned in Q24 go to Q11 */ -#ifdef BASOP_NOGLOB tilt_fx = round_fx_o( L_shl_o( calc_tilt_bwe_fx( insig_fx, 0, L_FRAME32k ), 3, &Overflow ), &Overflow ); -#else - tilt_fx = round_fx( L_shl( calc_tilt_bwe_fx( insig_fx, 0, L_FRAME32k ), 3 ) ); -#endif test(); test(); IF( EQ_16( IsTransient, 1 ) && ( GT_16( tilt_fx, 16384 ) || GT_16( st_fx->clas, 1 ) ) ) @@ -2788,7 +2705,6 @@ static Word16 SWB_BWE_encoding_fx( L_tmp = Mult_32_16( L_SWB_fenv_fx[n_band], tmp ); /*2*Q_synth-7+29-expd - 15 */ exp = norm_l( L_tmp ); tmp = Log2_norm_lc( L_shl( L_tmp, exp ) ); - move16(); exp = sub( sub( 30, exp ), sub( add( shl( Q_synth, 1 ), 7 ), expd ) ); L_tmp = Mpy_32_16( exp, tmp, 24660 ); /* Q14 */ /*10log10(2) in Q13 */ tmp = round_fx( L_shl( L_tmp, 10 ) ); /* Q8 */ @@ -2805,11 +2721,7 @@ static Word16 SWB_BWE_encoding_fx( L_SWB_tenv = L_deposit_l( 0 ); FOR( i = 0; i < L_SUBFR16k; i++ ) { -#ifdef BASOP_NOGLOB L_SWB_tenv = L_add_sat( L_SWB_tenv, L_mult0( insig_hp_fx[i + tmp], insig_hp_fx[i + tmp] ) ); /*2*Q_shb */ -#else - L_SWB_tenv = L_add( L_SWB_tenv, L_mult0( insig_hp_fx[i + tmp], insig_hp_fx[i + tmp] ) ); /*2*Q_shb */ -#endif } tmp = i_mult2( n_band, L ); @@ -2832,11 +2744,8 @@ static Word16 SWB_BWE_encoding_fx( L_tmp = L_deposit_h( tmp ); L_tmp = Isqrt_lc( L_tmp, &exp ); /*Q(31-exp) */ -#ifdef BASOP_NOGLOB - SWB_tenv_fx[n_band] = round_fx_sat( L_shl_sat( L_tmp, sub( exp, 12 ) ) ); /*Q3 */ -#else - SWB_tenv_fx[n_band] = round_fx( L_shl( L_tmp, sub( exp, 12 ) ) ); /*Q3 */ -#endif + SWB_tenv_fx[n_band] = round_fx_sat( L_shl_sat( L_tmp, sub( exp, 12 ) ) ); /*Q3*/ + move16(); } } @@ -2860,11 +2769,7 @@ static Word16 SWB_BWE_encoding_fx( L_tmp = L_deposit_h( tmp ); L_tmp = Isqrt_lc( L_tmp, &expn ); /*31-expn */ -#ifdef BASOP_NOGLOB Rat_tenv_fx = round_fx_o( L_shl_o( L_tmp, sub( expn, 1 ), &Overflow ), &Overflow ); /*Q14 */ -#else - Rat_tenv_fx = round_fx( L_shl( L_tmp, sub( expn, 1 ) ) ); /*Q14 */ -#endif } ELSE { @@ -2875,11 +2780,8 @@ static Word16 SWB_BWE_encoding_fx( IF( LT_16( Rat_tenv_fx, 8192 ) ) { L_tmp = L_mult( Rat_tenv_fx, 19661 ); /*Q29 */ -#ifdef BASOP_NOGLOB + Rat_tenv_fx = round_fx_o( L_shl_o( L_tmp, 2, &Overflow ), &Overflow ); /*Q15 */ -#else - Rat_tenv_fx = round_fx( L_shl( L_tmp, 2 ) ); /*Q15 */ -#endif } ELSE IF( GT_16( Rat_tenv_fx, 16384 ) ) { @@ -2945,11 +2847,8 @@ static Word16 SWB_BWE_encoding_fx( } /*SWB_tenv_fx[pos] = add(SWB_tenv_fx[pos], mult_r(SWB_tenv_fx[pos], 164)); move16();//Q3 */ -#ifdef BASOP_NOGLOB SWB_tenv_fx[pos] = round_fx_sat( L_mac_sat( L_mult_sat( SWB_tenv_fx[pos], 32767 ), SWB_tenv_fx[pos], 164 ) ); /*Q3 */ -#else - SWB_tenv_fx[pos] = round_fx( L_mac( L_mult( SWB_tenv_fx[pos], 32767 ), SWB_tenv_fx[pos], 164 ) ); /*Q3 */ -#endif + move16(); IF( LT_32( energy_fx, SWB_tenv_fx[pos] ) ) { @@ -2967,21 +2866,14 @@ static Word16 SWB_BWE_encoding_fx( IF( GT_16( SWB_tenv_fx[n_band - 1], SWB_tenv_fx[n_band] ) ) { /*SWB_tenv_fx[n_band-1] = add(mult_r(SWB_tenv_fx[n_band-1], 16384), mult_r(SWB_tenv_fx[n_band], 16384)); move16();//Q3 */ -#ifdef BASOP_NOGLOB SWB_tenv_fx[n_band - 1] = round_fx_sat( L_mac_sat( L_mult( SWB_tenv_fx[n_band - 1], 16384 ), SWB_tenv_fx[n_band], 16384 ) ); /*Q3 */ -#else - SWB_tenv_fx[n_band - 1] = round_fx( L_mac( L_mult( SWB_tenv_fx[n_band - 1], 16384 ), SWB_tenv_fx[n_band], 16384 ) ); /*Q3 */ -#endif } ELSE { /*SWB_tenv_fx[n_band] = add(mult_r(SWB_tenv_fx[n_band-1], 16384), mult_r(SWB_tenv_fx[n_band], 16384)); move16();//Q3 */ -#ifdef BASOP_NOGLOB SWB_tenv_fx[n_band] = round_fx_sat( L_mac_sat( L_mult( SWB_tenv_fx[n_band - 1], 16384 ), SWB_tenv_fx[n_band], 16384 ) ); /*Q3 */ -#else - SWB_tenv_fx[n_band] = round_fx( L_mac( L_mult( SWB_tenv_fx[n_band - 1], 16384 ), SWB_tenv_fx[n_band], 16384 ) ); /*Q3 */ -#endif } + move16(); } FOR( n_band = 0; n_band < SWB_TENV; n_band++ ) @@ -3029,6 +2921,7 @@ static Word16 SWB_BWE_encoding_fx( expn = sub( sub( 30, expn ), 19 ); L_tmp = Mpy_32_16( expn, tmp, 32767 ); /* Q16 */ /*1 in Q15 */ SWB_tenv_tmp_fx[n_band] = round_fx( L_shl( L_tmp, 11 ) ); /* Q11 */ + move16(); } IF( GT_16( SWB_tenv_tmp_fx[n_band], 30720 ) ) @@ -3093,6 +2986,7 @@ static Word16 SWB_BWE_encoding_fx( expn = sub( 30, add( expn, sub( shl( Q_synth, 1 ), 5 ) ) ); L_tmp = Mpy_32_16( expn, tmp, 24660 ); /* Q14 */ /*10log10(2) in Q13 */ SWB_fenv_fx[n_band] = round_fx( L_shl( L_tmp, 10 ) ); /* Q8 */ + move16(); } ELSE { @@ -3218,25 +3112,23 @@ static Word16 SWB_BWE_encoding_ivas_fx( energy_fx = L_deposit_l( 0 ); FOR( i = 0; i < L; i++ ) { - energy_fx = L_add( energy_fx, L_shr( L_mult0( insig_lp_fx[i + tmp], insig_lp_fx[i + tmp] ), 7 ) ); /*2*Q_slb_speech - 7 */ + energy_fx = L_add( energy_fx, L_shr( L_mult0( insig_lp_fx[i + tmp], insig_lp_fx[i + tmp] ), 7 ) ); /*Q = 2 * Q_insig_lp - 7 */ } - IF( GT_32( Mult_32_16( energy_fx, 5958 ), hBWE_FD->EnergyLF_fx ) ) + if ( BASOP_Util_Cmp_Mant32Exp( Mpy_32_16_1( energy_fx, 5958 /* 1/5.5f in Q15 */ ), sub( 31 + 7, shl( Q_insig_lp, 1 ) ), hBWE_FD->EnergyLF_fx, hBWE_FD->EnergyLF_exp ) > 0 ) { IsTransient_LF = 1; move16(); } hBWE_FD->EnergyLF_fx = energy_fx; + hBWE_FD->EnergyLF_exp = sub( 31 + 7, shl( Q_insig_lp, 1 ) ); move32(); + move16(); } /* tilt returned in Q24 go to Q11 */ -#ifdef BASOP_NOGLOB tilt_fx = round_fx_o( L_shl_o( calc_tilt_bwe_fx( insig_fx, 0, L_FRAME32k ), 3, &Overflow ), &Overflow ); -#else - tilt_fx = round_fx( L_shl( calc_tilt_bwe_fx( insig_fx, 0, L_FRAME32k ), 3 ) ); -#endif test(); test(); IF( EQ_16( IsTransient, 1 ) && ( GT_16( tilt_fx, 16384 ) || GT_16( st_fx->clas, 1 ) ) ) @@ -3306,17 +3198,13 @@ static Word16 SWB_BWE_encoding_ivas_fx( L_SWB_tenv = L_deposit_l( 0 ); FOR( i = 0; i < L_SUBFR16k; i++ ) { -#ifdef BASOP_NOGLOB L_SWB_tenv = L_add_sat( L_SWB_tenv, L_mult0( insig_hp_fx[i + tmp], insig_hp_fx[i + tmp] ) ); /*2*Q_shb */ -#else - L_SWB_tenv = L_add( L_SWB_tenv, L_mult0( insig_hp_fx[i + tmp], insig_hp_fx[i + tmp] ) ); /*2*Q_shb */ -#endif } tmp = i_mult2( n_band, L ); FOR( i = 0; i < L; i++ ) { - WB_tenv_syn_fx = L_add( WB_tenv_syn_fx, L_shr( L_mult0( synth_fx[i + tmp], synth_fx[i + tmp] ), 7 ) ); /*2*st_fx->Q_syn2 - 7 */ + WB_tenv_syn_fx = L_add( WB_tenv_syn_fx, L_shr( L_mult0( synth_fx[i + tmp], synth_fx[i + tmp] ), 7 ) ); /*2*Q_insig_lp-7 */ WB_tenv_orig_fx = L_add( WB_tenv_orig_fx, L_shr( L_mult0( insig_lp_fx[i + tmp], insig_lp_fx[i + tmp] ), 7 ) ); /*2*Q_insig_lp - 7 */ } @@ -3333,11 +3221,7 @@ static Word16 SWB_BWE_encoding_ivas_fx( L_tmp = L_deposit_h( tmp ); L_tmp = Isqrt_lc( L_tmp, &exp ); /*Q(31-exp) */ -#ifdef BASOP_NOGLOB SWB_tenv_fx[n_band] = round_fx_sat( L_shl_sat( L_tmp, sub( exp, 12 ) ) ); /*Q3 */ -#else - SWB_tenv_fx[n_band] = round_fx( L_shl( L_tmp, sub( exp, 12 ) ) ); /*Q3 */ -#endif move16(); } } @@ -3349,8 +3233,12 @@ static Word16 SWB_BWE_encoding_ivas_fx( expn = sub( sub( 30, expn ), sub( shl( Q_insig_lp, 1 ), 7 ) ); expd = norm_l( WB_tenv_syn_fx ); +#ifdef FIX_ISSUE_1156 + den = round_fx_o( L_shl( WB_tenv_syn_fx, expd ), &Overflow ); +#else den = round_fx( L_shl( WB_tenv_syn_fx, expd ) ); - expd = sub( sub( 30, expd ), sub( shl( st_fx->Q_syn2, 1 ), 7 ) ); +#endif + expd = sub( sub( 30, expd ), sub( shl( Q_insig_lp, 1 ), 7 ) ); scale = shr( sub( den, num ), 15 ); num = shl( num, scale ); @@ -3362,11 +3250,7 @@ static Word16 SWB_BWE_encoding_ivas_fx( L_tmp = L_deposit_h( tmp ); L_tmp = Isqrt_lc( L_tmp, &expn ); /*31-expn */ -#ifdef BASOP_NOGLOB Rat_tenv_fx = round_fx_o( L_shl_o( L_tmp, sub( expn, 1 ), &Overflow ), &Overflow ); /*Q14 */ -#else - Rat_tenv_fx = round_fx( L_shl( L_tmp, sub( expn, 1 ) ) ); /*Q14 */ -#endif } ELSE { @@ -3376,12 +3260,8 @@ static Word16 SWB_BWE_encoding_ivas_fx( IF( LT_16( Rat_tenv_fx, 8192 ) ) { - L_tmp = L_mult( Rat_tenv_fx, 19661 ); /*Q29 */ -#ifdef BASOP_NOGLOB + L_tmp = L_mult( Rat_tenv_fx, 19661 ); /*Q29 */ Rat_tenv_fx = round_fx_o( L_shl_o( L_tmp, 2, &Overflow ), &Overflow ); /*Q15 */ -#else - Rat_tenv_fx = round_fx( L_shl( L_tmp, 2 ) ); /*Q15 */ -#endif } ELSE IF( GT_16( Rat_tenv_fx, 16384 ) ) { @@ -3447,11 +3327,7 @@ static Word16 SWB_BWE_encoding_ivas_fx( } /*SWB_tenv_fx[pos] = add(SWB_tenv_fx[pos], mult_r(SWB_tenv_fx[pos], 164)); move16();//Q3 */ -#ifdef BASOP_NOGLOB SWB_tenv_fx[pos] = round_fx_sat( L_mac_sat( L_mult_sat( SWB_tenv_fx[pos], 32767 ), SWB_tenv_fx[pos], 164 ) ); /*Q3 */ -#else - SWB_tenv_fx[pos] = round_fx( L_mac( L_mult( SWB_tenv_fx[pos], 32767 ), SWB_tenv_fx[pos], 164 ) ); /*Q3 */ -#endif move16(); IF( LT_32( energy_fx, SWB_tenv_fx[pos] ) ) @@ -3470,21 +3346,13 @@ static Word16 SWB_BWE_encoding_ivas_fx( IF( GT_16( SWB_tenv_fx[n_band - 1], SWB_tenv_fx[n_band] ) ) { /*SWB_tenv_fx[n_band-1] = add(mult_r(SWB_tenv_fx[n_band-1], 16384), mult_r(SWB_tenv_fx[n_band], 16384)); move16();//Q3 */ -#ifdef BASOP_NOGLOB SWB_tenv_fx[n_band - 1] = round_fx_sat( L_mac_sat( L_mult( SWB_tenv_fx[n_band - 1], 16384 ), SWB_tenv_fx[n_band], 16384 ) ); /*Q3 */ -#else - SWB_tenv_fx[n_band - 1] = round_fx( L_mac( L_mult( SWB_tenv_fx[n_band - 1], 16384 ), SWB_tenv_fx[n_band], 16384 ) ); /*Q3 */ -#endif move16(); } ELSE { /*SWB_tenv_fx[n_band] = add(mult_r(SWB_tenv_fx[n_band-1], 16384), mult_r(SWB_tenv_fx[n_band], 16384)); move16();//Q3 */ -#ifdef BASOP_NOGLOB SWB_tenv_fx[n_band] = round_fx_sat( L_mac_sat( L_mult( SWB_tenv_fx[n_band - 1], 16384 ), SWB_tenv_fx[n_band], 16384 ) ); /*Q3 */ -#else - SWB_tenv_fx[n_band] = round_fx( L_mac( L_mult( SWB_tenv_fx[n_band - 1], 16384 ), SWB_tenv_fx[n_band], 16384 ) ); /*Q3 */ -#endif move16(); } } @@ -3588,11 +3456,12 @@ static Word16 SWB_BWE_encoding_ivas_fx( global_gain_fx = L_shr( global_gain_fx, 1 ); /*2*Q_shb */ - Copy_Scale_sig32_16( yos_fx, yos_fx_16, inner_frame, 0 ); - mode = FD_BWE_class_fx( yos_fx_16, global_gain_fx, tilt_nb_fx, sub( Q_synth, Q16 ), Q_shb, st_fx ); + scale = s_min( L_norm_arr( yos_fx, inner_frame ), sub( Q27, Q_synth ) /* To accomodate 10 in Q_synth*/ ); + Copy_Scale_sig32_16( yos_fx, yos_fx_16, inner_frame, scale ); + mode = FD_BWE_class_fx( yos_fx_16, global_gain_fx, tilt_nb_fx, sub( add( Q_synth, scale ), Q16 ), Q_shb, st_fx ); push_indice( hBstr, IND_SWB_CLASS, mode, 2 ); - energy_control_ivas_fx( st_fx, ACELP_CORE, mode, -1, yos_fx_16, st_offset, energy_factor_fx, sub( Q_synth_lf, Q16 ) ); + energy_control_ivas_fx( st_fx, ACELP_CORE, mode, -1, yos_fx_16, st_offset, energy_factor_fx, sub( add( Q_synth_lf, scale ), Q16 ) ); FOR( n_band = 0; n_band < SWB_FENV; n_band++ ) { @@ -3793,13 +3662,8 @@ static void calculate_tonality_fx_32( FOR( n_coeff = 0; n_coeff < length; n_coeff++ ) { -#ifdef BASOP_NOGLOB am_org_fx = L_add_sat( am_org_fx, org_spec_fx[n_coeff] ); am_gen_fx = L_add_sat( am_gen_fx, gen_spec_fx[n_coeff] ); -#else - am_org_fx = L_add( am_org_fx, org_spec_fx[n_coeff] ); - am_gen_fx = L_add( am_gen_fx, gen_spec_fx[n_coeff] ); -#endif IF( org_spec_fx[n_coeff] != 0 ) { exp = norm_l( org_spec_fx[n_coeff] ); @@ -4009,26 +3873,18 @@ static Word16 decision_hq_generic_class_fx_32( { a_fx = L_deposit_l( 0 ); p_fx = L_deposit_l( 0 ); - tmp2 = add( swb_bwe_subband[add( k, 1 )], hq_generic_offset ); + tmp2 = add( swb_bwe_subband[k + 1], hq_generic_offset ); FOR( i = add( swb_bwe_subband[k], hq_generic_offset ); i < tmp2; i++ ) { exp = norm_l( coefs_fx[i] ); - tmp = extract_h( L_shl( coefs_fx[i], exp ) ); /*12 + exp - 16 */ - L_tmp = L_mult0( tmp, tmp ); /*2 * exp - 8 */ -#ifdef BASOP_NOGLOB + tmp = extract_h( L_shl( coefs_fx[i], exp ) ); /*12 + exp - 16 */ + L_tmp = L_mult0( tmp, tmp ); /*2 * exp - 8 */ L_tmp = L_shl_sat( L_tmp, sub( 14, shl( exp, 1 ) ) ); /*6 */ -#else - L_tmp = L_shl( L_tmp, sub( 14, shl( exp, 1 ) ) ); /*6 */ -#endif IF( GT_32( L_tmp, p_fx ) ) { p_fx = L_add( L_tmp, 0 ); /*6 */ } -#ifdef BASOP_NOGLOB a_fx = L_add_sat( a_fx, L_tmp ); /*6 */ -#else - a_fx = L_add( a_fx, L_tmp ); /*6 */ -#endif } IF( a_fx > 0 ) @@ -4076,7 +3932,7 @@ void hq_generic_encoding_fx( Word16 indice[HQ_GENERIC_NVQIDX]; Word16 nenv; - Word16 energy_factor_fx[SWB_FENV] = { 0 }; + Word16 energy_factor_fx[SWB_FENV]; Word16 cs, exp, tmp, tmp2; Word32 energy_fx; Word32 L_tmp, max_coefs_fx; @@ -4084,6 +3940,7 @@ void hq_generic_encoding_fx( HQ_ENC_HANDLE hHQ_core = st_fx->hHQ_core; BSTR_ENC_HANDLE hBstr = st_fx->hBstr; + set16_fx( energy_factor_fx, 0, SWB_FENV ); IF( LE_16( hq_generic_offset, HQ_GENERIC_FOFFSET_24K4 ) ) { @@ -4108,6 +3965,7 @@ void hq_generic_encoding_fx( ELSE { *hq_generic_exc_clas = decision_hq_generic_class_fx_32( coefs_fx, hq_generic_offset ); + move16(); push_indice_fx( hBstr, IND_HQ_SWB_EXC_SP_CLAS, 0, 1 ); push_indice_fx( hBstr, IND_HQ_SWB_EXC_CLAS, *hq_generic_exc_clas, 1 ); } @@ -4117,7 +3975,7 @@ void hq_generic_encoding_fx( energy_fx = L_deposit_l( 0 ); max_coefs_fx = L_deposit_l( 0 ); tmp2 = add( swb_bwe_subband[n_band + 1], hq_generic_offset ); - FOR( n_coeff = add( swb_bwe_subband[n_band], hq_generic_offset ); n_coeff < tmp2; n_coeff++ ) + FOR( n_coeff = swb_bwe_subband[n_band] + hq_generic_offset; n_coeff < tmp2; n_coeff++ ) { IF( LT_32( max_coefs_fx, L_abs( coefs_fx[n_coeff] ) ) ) { @@ -4126,7 +3984,7 @@ void hq_generic_encoding_fx( } cs = norm_l( max_coefs_fx ); tmp2 = add( swb_bwe_subband[n_band + 1], hq_generic_offset ); - FOR( n_coeff = add( swb_bwe_subband[n_band], hq_generic_offset ); n_coeff < tmp2; n_coeff++ ) + FOR( n_coeff = swb_bwe_subband[n_band] + hq_generic_offset; n_coeff < tmp2; n_coeff++ ) { tmp = extract_h( L_shl( coefs_fx[n_coeff], cs ) ); /*12 + cs - 16 */ L_tmp = L_mult0( tmp, tmp ); /*2*cs - 8 */ @@ -4144,6 +4002,7 @@ void hq_generic_encoding_fx( L_tmp = Mpy_32_16( exp, tmp, 24660 ); /* Q14 */ /*10log10(2) in Q13 */ hq_generic_fenv_fx[n_band] = round_fx( L_shl( L_tmp, 10 ) ); /*Q8 */ + move16(); } ELSE { @@ -4167,7 +4026,7 @@ void hq_generic_encoding_fx( } } cs = norm_l( max_coefs_fx ); - tmp2 = fb_bwe_subband[add( n_band, 1 )]; + tmp2 = fb_bwe_subband[n_band + 1]; FOR( n_coeff = fb_bwe_subband[n_band]; n_coeff < tmp2; n_coeff++ ) { tmp = extract_h( L_shl( coefs_fx[n_coeff], cs ) ); /*12 + cs - 16 */ @@ -4183,12 +4042,13 @@ void hq_generic_encoding_fx( tmp = Log2_norm_lc( L_shl( L_tmp, exp ) ); exp = sub( 30, add( exp, 2 * cs - 13 ) ); - L_tmp = Mpy_32_16( exp, tmp, 24660 ); /* Q14 */ /*10log10(2) in Q13 */ - hq_generic_fenv_fx[add( n_band, nenv )] = round_fx( L_shl( L_tmp, 10 ) ); /*Q8 */ + L_tmp = Mpy_32_16( exp, tmp, 24660 ); /* Q14 */ /*10log10(2) in Q13 */ + hq_generic_fenv_fx[n_band + nenv] = round_fx( L_shl( L_tmp, 10 ) ); /*Q8 */ + move16(); } ELSE { - hq_generic_fenv_fx[add( n_band, nenv )] = -24576; + hq_generic_fenv_fx[n_band + nenv] = -24576; move16(); } } @@ -4199,13 +4059,15 @@ void hq_generic_encoding_fx( FOR( n_band = 0; n_band < nenv; n_band++ ) { hq_generic_fenv_fx[n_band] = sub( hq_generic_fenv_fx[n_band], Mean_env_fx[n_band] ); + move16(); } IF( st_fx->bwidth == FB ) { FOR( n_band = 0; n_band < DIM_FB; n_band++ ) { - hq_generic_fenv_fx[add( n_band, nenv )] = sub( shr( hq_generic_fenv_fx[add( n_band, nenv )], 1 ), Mean_env_fb_fx[n_band] ); + hq_generic_fenv_fx[n_band + nenv] = sub( shr( hq_generic_fenv_fx[n_band + nenv], 1 ), Mean_env_fb_fx[n_band] ); + move16(); } } @@ -4223,6 +4085,7 @@ void hq_generic_encoding_fx( IF( EQ_16( st_fx->bwidth, FB ) ) { indice[5] = vqSimple_w_fx( hq_generic_fenv_fx + nenv, hq_generic_fenv_fx + nenv, EnvCdbkFB_fx, NULL, DIM_FB, N_CB_FB, 0 ); + move16(); } push_indice_fx( hBstr, IND_SWB_FENV_HQ, indice[0], 5 ); @@ -4252,11 +4115,8 @@ void hq_generic_encoding_fx( L_Extract( L_tmp, &exp, &tmp ); /* */ tmp = extract_l( Pow2( 13, tmp ) ); exp = sub( exp, 13 ); -#ifdef BASOP_NOGLOB hq_generic_fenv_fx[n_band] = shl_sat( tmp, add( exp, 1 ) ); /*1 */ -#else - hq_generic_fenv_fx[n_band] = shl( tmp, add( exp, 1 ) ); /*1 */ -#endif + move16(); } @@ -4264,13 +4124,14 @@ void hq_generic_encoding_fx( { FOR( n_band = 0; n_band < DIM_FB; n_band++ ) { - tmp = add( hq_generic_fenv_fx[add( n_band, nenv )], Mean_env_fb_fx[n_band] ); /*7 */ - L_tmp = L_mult( tmp, 21771 ); /*25 */ - L_tmp = L_shr( L_tmp, 9 ); /*16 */ + tmp = add( hq_generic_fenv_fx[n_band + nenv], Mean_env_fb_fx[n_band] ); /*7 */ + L_tmp = L_mult( tmp, 21771 ); /*25 */ + L_tmp = L_shr( L_tmp, 9 ); /*16 */ L_Extract( L_tmp, &exp, &tmp ); tmp = extract_l( Pow2( 13, tmp ) ); exp = sub( exp, 13 ); - hq_generic_fenv_fx[add( n_band, nenv )] = shl( tmp, add( exp, 1 ) ); /*2 */ + hq_generic_fenv_fx[n_band + nenv] = shl( tmp, add( exp, 1 ) ); /*2 */ + move16(); } } @@ -4288,6 +4149,10 @@ void fd_bwe_enc_init_fx( ) { set16_fx( hBWE_FD->new_input_hp_fx, 0, NS2SA( 16000, ACELP_LOOK_NS + DELAY_FD_BWE_ENC_12k8_NS + DELAY_FIR_RESAMPL_NS - DELAY_CLDFB_NS ) ); +#ifdef FIX_ISSUE_1230 + hBWE_FD->Q_new_input_hp = 0; + move16(); +#endif set16_fx( hBWE_FD->old_input_fx, 0, NS2SA( 48000, DELAY_FD_BWE_ENC_12k8_NS + DELAY_FIR_RESAMPL_NS ) ); set16_fx( hBWE_FD->old_input_wb_fx, 0, NS2SA( 16000, DELAY_FD_BWE_ENC_12k8_NS ) ); #ifndef MSAN_FIX @@ -4306,8 +4171,10 @@ void fd_bwe_enc_init_fx( hBWE_FD->modeCount = 0; move16(); hBWE_FD->EnergyLF_fx = 0; + hBWE_FD->EnergyLF_exp = 0; hBWE_FD->mem_old_wtda_swb_fx = 0; move32(); + move16(); move32(); hBWE_FD->prev_Q_input_lp = 0; @@ -4410,6 +4277,7 @@ void hq_generic_hf_encoding_fx( L_tmp = Mpy_32_16( exp, tmp, 24660 ); /* Q14 */ /*10log10(2) in Q13 */ hq_generic_fenv_fx[n_band] = round_fx( L_shl( L_tmp, 10 ) ); /*Q8 */ + move16(); } ELSE { @@ -4449,13 +4317,13 @@ void hq_generic_hf_encoding_fx( tmp = Log2_norm_lc( L_shl( L_tmp, exp ) ); exp = sub( 30, add( exp, sub( shl( cs, 1 ), 13 ) ) ); - L_tmp = Mpy_32_16( exp, tmp, 24660 ); /* Q14 */ /*10log10(2) in Q13 */ - hq_generic_fenv_fx[add( n_band, nenv )] = round_fx( L_shl( L_tmp, 10 ) ); /*Q8 */ + L_tmp = Mpy_32_16( exp, tmp, 24660 ); /* Q14 */ /*10log10(2) in Q13 */ + hq_generic_fenv_fx[n_band + nenv] = round_fx( L_shl( L_tmp, 10 ) ); /*Q8 */ move16(); } ELSE { - hq_generic_fenv_fx[add( n_band, nenv )] = -24576; + hq_generic_fenv_fx[n_band + nenv] = -24576; move16(); } } @@ -4473,7 +4341,7 @@ void hq_generic_hf_encoding_fx( { FOR( n_band = 0; n_band < DIM_FB; n_band++ ) { - hq_generic_fenv_fx[add( n_band, nenv )] = sub( shr( hq_generic_fenv_fx[add( n_band, nenv )], 1 ), Mean_env_fb_fx[n_band] ); + hq_generic_fenv_fx[n_band + nenv] = sub( shr( hq_generic_fenv_fx[n_band + nenv], 1 ), Mean_env_fb_fx[n_band] ); move16(); } } @@ -4491,15 +4359,15 @@ void hq_generic_hf_encoding_fx( IF( EQ_16( length, L_SPEC48k ) ) { - Word16 sf = getScaleFactor16( hq_generic_fenv_fx, DIM_FB + nenv ); - Scale_sig( hq_generic_fenv_fx, DIM_FB + nenv, negate( sf ) ); + Word16 sf = getScaleFactor16( hq_generic_fenv_fx, add( DIM_FB, nenv ) ); + Scale_sig( hq_generic_fenv_fx, add( DIM_FB, nenv ), negate( sf ) ); Copy_Scale_sig( EnvCdbkFB_fx, EnvCdbkFB_fx_loc, N_CB_FB * DIM_FB, negate( sf ) ); // Scaling done to handel overflow inside vqSimple_w_fx indice[5] = vqSimple_w_fx( hq_generic_fenv_fx + nenv, hq_generic_fenv_fx + nenv, EnvCdbkFB_fx_loc, NULL, DIM_FB, N_CB_FB, 0 ); move16(); - Scale_sig( hq_generic_fenv_fx, DIM_FB + nenv, sf ); + Scale_sig( hq_generic_fenv_fx, add( DIM_FB, nenv ), sf ); } push_indice( hBstr, IND_SWB_FENV_HQ, indice[0], 5 ); @@ -4529,11 +4397,7 @@ void hq_generic_hf_encoding_fx( L_Extract( L_tmp, &exp, &tmp ); /* */ tmp = extract_l( Pow2( 13, tmp ) ); exp = sub( exp, 13 ); -#ifdef BASOP_NOGLOB hq_generic_fenv_fx[n_band] = shl_sat( tmp, add( exp, 1 ) ); /*1 */ -#else - hq_generic_fenv_fx[n_band] = shl( tmp, add( exp, 1 ) ); /*1 */ -#endif move16(); } @@ -4542,13 +4406,13 @@ void hq_generic_hf_encoding_fx( { FOR( n_band = 0; n_band < DIM_FB; n_band++ ) { - tmp = add( hq_generic_fenv_fx[add( n_band, nenv )], Mean_env_fb_fx[n_band] ); /*7 */ - L_tmp = L_mult( tmp, 21771 ); /*25 */ - L_tmp = L_shr( L_tmp, 9 ); /*16 */ + tmp = add( hq_generic_fenv_fx[n_band + nenv], Mean_env_fb_fx[n_band] ); /*7 */ + L_tmp = L_mult( tmp, 21771 ); /*25 */ + L_tmp = L_shr( L_tmp, 9 ); /*16 */ L_Extract( L_tmp, &exp, &tmp ); tmp = extract_l( Pow2( 13, tmp ) ); exp = sub( exp, 13 ); - hq_generic_fenv_fx[add( n_band, nenv )] = shl( tmp, add( exp, 1 ) ); /*1 */ + hq_generic_fenv_fx[n_band + nenv] = shl( tmp, add( exp, 1 ) ); /*1 */ move16(); } } diff --git a/lib_enc/swb_bwe_enc_hr.c b/lib_enc/swb_bwe_enc_hr.c deleted file mode 100644 index 8e752f0ac516550ba25f4c9dcce588dfd9e16b42..0000000000000000000000000000000000000000 --- a/lib_enc/swb_bwe_enc_hr.c +++ /dev/null @@ -1,42 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include -#include "prot.h" -#include "rom_com.h" -#include "wmc_auto.h" diff --git a/lib_enc/swb_bwe_enc_hr_fx.c b/lib_enc/swb_bwe_enc_hr_fx.c index 094ad37fa96e5d3e5371e3b7e55ff76d6cd87dc2..fd4a9f1259669e751e5164a7814c623739939c11 100644 --- a/lib_enc/swb_bwe_enc_hr_fx.c +++ b/lib_enc/swb_bwe_enc_hr_fx.c @@ -4,10 +4,9 @@ #include #include #include "options.h" -#include "cnst.h" /* Common constants */ -#include "rom_enc.h" /* Encoder static table prototypes */ -#include "rom_com_fx.h" /* Static table prototypes */ -//#include "prot_fx.h" /* Function prototypes */ +#include "cnst.h" /* Common constants */ +#include "rom_enc.h" /* Encoder static table prototypes */ +#include "rom_com_fx.h" /* Static table prototypes */ #include "rom_com.h" /* Common constants */ #include "prot_fx.h" /* Function prototypes */ #include "prot_fx_enc.h" /* Function prototypes */ @@ -120,6 +119,7 @@ void swb_bwe_enc_hr_fx( #endif #ifdef BASOP_NOGLOB_DECLARE_LOCAL Flag Overflow = 0; + move16(); #endif FD_BWE_ENC_HANDLE hBWE_FD = st_fx->hBWE_FD; BSTR_ENC_HANDLE hBstr = st_fx->hBstr; @@ -132,9 +132,7 @@ void swb_bwe_enc_hr_fx( /* Use 32 Bits Buffer to Store Two 16 Bits Vectors in Order to Save Stack Space */ t_audio_fx = (Word16 *) &t_audio32[0]; - move16(); t_audio_tmp_fx = (Word16 *) &t_audio32[L_FRAME48k / 2]; - move16(); ind2 = 0; move16(); /* only to suppress warnings */ @@ -185,6 +183,7 @@ void swb_bwe_enc_hr_fx( Copy_Scale_sig( new_input_fx, t_audio_fx, input_frame, temp ); /* Bring Energy in 2*Q'exp1' */ st_fx->EnergyLT_fx = L_shl( st_fx->EnergyLT_fx, shl( sub( exp1, st_fx->EnergyLT_fx_exp ), 1 ) ); + move32(); is_transient = detect_transient_fx( t_audio_fx, input_frame, exp1, st_fx ); st_fx->EnergyLT_fx_exp = exp1; @@ -201,6 +200,7 @@ void swb_bwe_enc_hr_fx( st_fx->Q_old_wtda = new_input_fx_exp; move16(); new_input_fx_exp = 0; + move16(); wtda_fx( new_input_fx, &new_input_fx_exp, L_t_audio_tmp_fx, hBWE_FD->L_old_wtda_swb_fx, &st_fx->Q_old_wtda, ALDO_WINDOW, ALDO_WINDOW, input_frame ); @@ -246,7 +246,6 @@ void swb_bwe_enc_hr_fx( scl = 99; move16(); ptr16 = &t_audio_fx[NUM_TRANS_START_FREQ_COEF]; - move16(); FOR( k = 0; k < input_frame; k += temp ) { /* from t_audio_fx[k..NUM_TRANS_START_FREQ_COEF+k-1] will be zeroed out */ @@ -314,8 +313,7 @@ void swb_bwe_enc_hr_fx( nBits = sub( nBits, NBITS_GLOB_GAIN_BWE_HR ); /* normalization with global gain */ - ptr16 = &t_audio_fx[add( NUM_TRANS_START_FREQ_COEF, temp )]; - move16(); + ptr16 = &t_audio_fx[NUM_TRANS_START_FREQ_COEF + temp]; temp2 = negate( exp1 ); gain2_fx = Invert16( gain1_fx, &temp2 ); @@ -326,6 +324,7 @@ void swb_bwe_enc_hr_fx( L_temp = L_mult( *ptr16, gain2_fx ); L_temp = L_shr( L_temp, temp2 ); *ptr16++ = round_fx( L_temp ); + move16(); } FOR( ; i < L_FRAME32k / NUM_TIME_SWITCHING_BLOCKS - NUM_TRANS_START_FREQ_COEF; i++ ) { @@ -339,18 +338,14 @@ void swb_bwe_enc_hr_fx( *---------------------------------------------------------------------*/ /* compute energy per band */ - ptr16 = &t_audio_fx[add( temp, NUM_TRANS_START_FREQ_COEF )]; - move16(); + ptr16 = &t_audio_fx[temp + NUM_TRANS_START_FREQ_COEF]; FOR( i = 0; i < N_BANDS_TRANS_BWE_HR; i++ ) { L_temp = Calc_Energy_Autoscaled( ptr16, t_audio_fx_exp, WIDTH_TRANS_FREQ_COEF, &temp2 ); ptr16 += WIDTH_TRANS_FREQ_COEF; L_temp = Sqrt_Ratio32( L_temp, temp2, WIDTH_TRANS_FREQ_COEF, /*WIDTH_TRANS_FREQ_COEF is in Q0*/ 0, &temp2 ); -#ifdef BASOP_NOGLOB en_band_fx[i] = round_fx_sat( L_shr_sat( L_temp, sub( 15 - 9, temp2 ) ) ); -#else - en_band_fx[i] = round_fx( L_shr( L_temp, sub( 15 - 9, temp2 ) ) ); -#endif + move16(); } /* Q energy per band */ @@ -368,12 +363,10 @@ void swb_bwe_enc_hr_fx( IF( LT_16( ind2, NUM_ENVLOPE_CODE_HR_TR2 ) ) { ind1 = en_band_quant_fx( en_band_fx, swb_hr_env_code3_fx, NUM_ENVLOPE_CODE_HR_TR2 ); - move16(); } ELSE { ind1 = en_band_quant_fx( en_band_fx, swb_hr_env_code3_fx + ( NUM_ENVLOPE_CODE_HR_TR2 * 2 ), NUM_ENVLOPE_CODE_HR_TR2 ); - move16(); } push_indice_fx( hBstr, IND_HR_ENVELOPE, ind1, NBITS_ENVELOPE_BWE_HR_TR - 1 ); @@ -381,8 +374,7 @@ void swb_bwe_enc_hr_fx( } /* normalize spectrum per bands */ - ptr16 = &t_audio_fx[add( temp, NUM_TRANS_START_FREQ_COEF )]; - move16(); + ptr16 = &t_audio_fx[temp + NUM_TRANS_START_FREQ_COEF]; FOR( i = 0; i < N_BANDS_TRANS_BWE_HR; i++ ) { temp2 = 9; @@ -394,6 +386,7 @@ void swb_bwe_enc_hr_fx( L_temp = L_mult( *ptr16, gain2_fx ); L_temp = L_shr( L_temp, temp2 ); *ptr16++ = round_fx( L_temp ); + move16(); } } @@ -519,7 +512,6 @@ void swb_bwe_enc_hr_fx( /* normalization with global gain */ ptr16 = &t_audio_fx[NUM_NONTRANS_START_FREQ_COEF]; - move16(); /* Find Max Scaling on Remaining Frequencies */ temp2 = Find_Max_Norm16( ptr16, NUM_NONTRANS_END_FREQ_COEF - NUM_NONTRANS_START_FREQ_COEF ); temp2 = s_max( 0, sub( temp2, NON_TRANSIENT_RESCALE_Q_GUARD ) ); @@ -533,6 +525,7 @@ void swb_bwe_enc_hr_fx( L_temp = L_mult( *ptr16, temp ); L_temp = L_shr( L_temp, temp2 ); *ptr16++ = round_fx( L_temp ); + move16(); } /*---------------------------------------------------------------------* @@ -541,17 +534,13 @@ void swb_bwe_enc_hr_fx( /* compute energy per band */ ptr16 = &t_audio_fx[NUM_NONTRANS_START_FREQ_COEF]; - move16(); FOR( i = 0; i < N_BANDS_BWE_HR; i++ ) { L_temp = Calc_Energy_Autoscaled( ptr16, t_audio_fx_exp, WIDTH_NONTRANS_FREQ_COEF, &temp2 ); ptr16 += WIDTH_NONTRANS_FREQ_COEF; L_temp = Sqrt_Ratio32( L_temp, temp2, WIDTH_NONTRANS_FREQ_COEF, /*WIDTH_TRANS_FREQ_COEF is in Q0*/ 0, &temp2 ); -#ifdef BASOP_NOGLOB en_band_fx[i] = round_fx_sat( L_shr_sat( L_temp, sub( 15 - 9, temp2 ) ) ); /* Put in Q9 */ -#else - en_band_fx[i] = round_fx( L_shr( L_temp, sub( 15 - 9, temp2 ) ) ); /* Put in Q9 */ -#endif + move16(); } /* Q energy per band */ @@ -566,7 +555,6 @@ void swb_bwe_enc_hr_fx( /* normalize spectrum per bands */ ptr32 = &L_t_audio_tmp_fx[0]; ptr16 = &t_audio_fx[NUM_NONTRANS_START_FREQ_COEF]; - move16(); FOR( i = 0; i < N_BANDS_BWE_HR; i++ ) { temp2 = 9; @@ -712,7 +700,6 @@ void swb_bwe_enc_hr_fx( { /* select spectrum of the second stage coding */ ptr16 = &t_audio_fx[0]; - move16(); FOR( i = 0; i < Nsv; i++ ) { IF( nq[i] == 0 ) @@ -734,6 +721,7 @@ void swb_bwe_enc_hr_fx( L_temp = L_deposit_l( t_audio_tmp_fx[i * WIDTH_BAND + j] ); L_temp = L_msu0( L_temp, temp2, x_norm_fx[i * WIDTH_BAND + j] ); *ptr16++ = extract_l( L_temp ); + move16(); } } } @@ -755,10 +743,10 @@ void swb_bwe_enc_hr_fx( /* Nsv2 * 12 <= nBits (Nsv2 is not too high) AND */ /* nBits - Nsv2 * 12 < 12 (Nsv2 is the highest divisor) */ L_temp = L_msu0( L_deposit_l( nBits ), 12, Nsv2 ); - if ( GE_32( L_temp, 12L ) ) - Nsv2 = add( Nsv2, 1 ); - if ( L_temp < 0 ) - Nsv2 = sub( Nsv2, 1 ); + IF( GE_32( L_temp, 12L ) ) + Nsv2 = add( Nsv2, 1 ); + IF( L_temp < 0 ) + Nsv2 = sub( Nsv2, 1 ); } /* second stage global gain estimation and coding */ @@ -779,13 +767,9 @@ void swb_bwe_enc_hr_fx( FOR( i = 0; i < Nsv2 * WIDTH_BAND; i++ ) { L_tmp = L_mult( temp, t_audio_fx[i] ); -#ifdef BASOP_NOGLOB L_tmp = L_shr_o( L_tmp, temp2, &Overflow ); t_audio_fx[i] = round_fx_o( L_tmp, &Overflow ); -#else - L_tmp = L_shr( L_tmp, temp2 ); - t_audio_fx[i] = round_fx( L_tmp ); -#endif + move16(); } set16_fx( nq2, 0, Nsv ); diff --git a/lib_enc/swb_bwe_enc_lr.c b/lib_enc/swb_bwe_enc_lr.c deleted file mode 100644 index 5bd24db09d3a0629cf156dd436c5f5a401b21bd5..0000000000000000000000000000000000000000 --- a/lib_enc/swb_bwe_enc_lr.c +++ /dev/null @@ -1,44 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include -#include "cnst.h" -#include "prot.h" -#include "rom_com.h" -#include "stat_com.h" -#include "wmc_auto.h" diff --git a/lib_enc/swb_bwe_enc_lr_fx.c b/lib_enc/swb_bwe_enc_lr_fx.c index c5fdfec9989d2c4628cad638e88fc2d7dcdaef64..1a397c514951163ef7f4a99dd9c5143283e0a601 100644 --- a/lib_enc/swb_bwe_enc_lr_fx.c +++ b/lib_enc/swb_bwe_enc_lr_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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,7 +36,6 @@ #include "prot_fx_enc.h" /* Function prototypes */ #include "rom_com.h" #include "stl.h" -#include "prot.h" /*--------------------------------------------------------------------------* * GetSubbandCorrIndex2_har() @@ -92,9 +91,11 @@ static Word16 GetSubbandCorrIndex2_har_fx( /* o : #ifdef BASOP_NOGLOB_DECLARE_LOCAL Flag Overflow = 0; + move16(); #endif exp_safe_e = 4; + move16(); L_tmp = L_deposit_l( 0 ); FOR( i = 0; i < fLen; i++ ) @@ -107,6 +108,7 @@ static Word16 GetSubbandCorrIndex2_har_fx( /* o : FOR( i = 0; i < fLen; i++ ) { ibuf_fx[i] = extract_h( L_shl( L_inBuf[i], exp_shift ) ); /* Qi+exp_shift-16 */ + move16(); } FOR( i = 0; i < predBufLen; i++ ) @@ -148,11 +150,7 @@ static Word16 GetSubbandCorrIndex2_har_fx( /* o : FOR( j = 0; j < fLen; j++ ) { /*energy += *predBuf * *predBuf; */ -#ifdef BASOP_NOGLOB /* Critical Overflow , as well as those below*/ L_energy = L_mac_o( L_energy, *ptr_pbuf, *ptr_pbuf, &Overflow ); /* Q*2-1; */ -#else - L_energy = L_mac( L_energy, *ptr_pbuf, *ptr_pbuf ); /* Q*2-1; */ -#endif ptr_pbuf++; } @@ -165,11 +163,7 @@ static Word16 GetSubbandCorrIndex2_har_fx( /* o : FOR( j = 0; j < nZero_fx; j++ ) { /*corr += inBuf[G_item[j].gainIndex]* predBuf[G_item[j].gainIndex]; */ -#ifdef BASOP_NOGLOB /* Critical Overflow */ L_corr = L_mac_o( L_corr, ibuf_fx[G_item_fx[j].gainIndex_fx], ptr_pbuf[G_item_fx[j].gainIndex_fx], &Overflow ); /* Q*2-1 */ -#else - L_corr = L_mac( L_corr, ibuf_fx[G_item_fx[j].gainIndex_fx], ptr_pbuf[G_item_fx[j].gainIndex_fx] ); /* Q*2-1 */ -#endif } /*corr_sq = corr*corr; */ @@ -178,13 +172,8 @@ static Word16 GetSubbandCorrIndex2_har_fx( /* o : L_corr_sq = L_shl( L_corr, exp_norm ); corr_sq_hi_fx = extract_h( L_corr_sq ); -#ifdef BASOP_NOGLOB /* Critical Overflow */ L_corr_sq = L_mult_o( corr_sq_hi_fx, corr_sq_hi_fx, &Overflow ); /* (((Qhi:Qsh+exp_norm_hi-16)+Qss+1)+exp_norm-16)*2+1 */ L_corr_sq = L_shr_o( L_corr_sq, s_min( shl( exp_norm, 1 ), 31 ), &Overflow ); /* (QCorr-16)*2+1 */ -#else - L_corr_sq = L_mult( corr_sq_hi_fx, corr_sq_hi_fx ); /* (((Qhi:Qsh+exp_norm_hi-16)+Qss+1)+exp_norm-16)*2+1 */ - L_corr_sq = L_shr( L_corr_sq, s_min( shl( exp_norm, 1 ), 31 ) ); /* (QCorr-16)*2+1 */ -#endif IF( Overflow != 0 ) { L_corr_sq = 0x0L; @@ -279,6 +268,7 @@ static void getswbindices_har_fx( { /*nlags[sb] = (short)pow(2, bits_lagIndices_mode0_Har[sb]); */ nlags_fx[sb] = shl( 1, bits_lagIndices_mode0_Har[sb] ); + move16(); } j = 0; @@ -290,6 +280,7 @@ static void getswbindices_har_fx( sbWidth_fx[sb], &n_nbiggestsearch_fx[sb], N_NBIGGEST_PULSEARCH ); search_offset_fx[sb] = subband_search_offset_fx[sb]; + move16(); j = add( j, N_NBIGGEST_PULSEARCH ); } @@ -316,7 +307,8 @@ static void getswbindices_har_fx( FOR( j = add( search_offset_fx[sb], shr( nlags_fx[sb], 1 ) ); j > tmp; j-- ) { low_freqsgnl_fx[k] = y2_fx[j]; - k = add( k, 1 ); + move16(); + k++; } } /* correlation b/w HF spectrum Group1 of length sbLen and decoded LF spectrum */ @@ -326,6 +318,7 @@ static void getswbindices_har_fx( add( sbWidth_fx[sb], nlags_fx[sb] ), nlags_fx[sb], Nbiggest_fx + ( sb * N_NBIGGEST_PULSEARCH ), n_nbiggestsearch_fx[sb], &prev_frame_bstindx_fx[sb] ); + move16(); } return; @@ -354,7 +347,6 @@ static Word16 GetSubbandCorrIndex2_pulsestep_fx( Word32 L_lagEnergy; const Word16 *ptr_predBuf; - const Word16 *ptr_predBuf_ni; Word32 L_energy; Word32 L_corr; @@ -402,8 +394,6 @@ static Word16 GetSubbandCorrIndex2_pulsestep_fx( move32(); ptr_predBuf = predBuf_fx; - ptr_predBuf_ni = predBuf_ni_fx; - /* This part must be computed on parent function. */ exp_norm_ss = 2; move16(); @@ -432,17 +422,17 @@ static Word16 GetSubbandCorrIndex2_pulsestep_fx( } /* Get the initial energy for zero lag */ + test(); WHILE( *ptr_predBuf == 0 && LT_16( absPos_fx, ssearch_buflim ) ) { + test(); ptr_predBuf++; - ptr_predBuf_ni++; absPos_fx = add( absPos_fx, 1 ); } IF( EQ_16( absPos_fx, ssearch_buflim ) ) { ptr_predBuf--; - ptr_predBuf_ni--; absPos_fx = sub( absPos_fx, 1 ); } @@ -452,11 +442,9 @@ static Word16 GetSubbandCorrIndex2_pulsestep_fx( { L_energy = L_mac( L_energy, *ptr_ssBuf_ni_fx, *ptr_ssBuf_ni_fx ); /* (Qss-exp_norm_ss)*2+1 */ ptr_ssBuf_ni_fx++; - ptr_predBuf_ni++; } ptr_ssBuf_ni_fx -= fLen; - ptr_predBuf_ni -= fLen; L_lagEnergy = L_add( L_energy, 0 ); @@ -471,10 +459,8 @@ static Word16 GetSubbandCorrIndex2_pulsestep_fx( { L_energy = L_mac( L_energy, *ptr_ssBuf_ni_fx, *ptr_ssBuf_ni_fx ); ptr_ssBuf_ni_fx++; - ptr_predBuf_ni++; } ptr_ssBuf_ni_fx -= fLen; - ptr_predBuf_ni -= fLen; /* Get cross-correlation */ IF( L_energy != 0x0L ) @@ -531,14 +517,13 @@ static Word16 GetSubbandCorrIndex2_pulsestep_fx( } ptr_predBuf++; ptr_ssBuf_ni_fx++; - ptr_predBuf_ni++; absPos_fx++; - + test(); WHILE( *ptr_predBuf == 0 && LT_16( absPos_fx, ssearch_buflim ) ) { + test(); ptr_predBuf++; ptr_ssBuf_ni_fx++; - ptr_predBuf_ni++; absPos_fx = add( absPos_fx, 1 ); } @@ -554,7 +539,7 @@ static Word16 GetSubbandCorrIndex2_pulsestep_fx( } } - IF( EQ_16( ib_flag_fx, 1 ) ) + if ( EQ_16( ib_flag_fx, 1 ) ) { bestIdx_fx = 0; move16(); @@ -622,6 +607,7 @@ static void GetSWBIndices_fx( } sspectra_ma_fx[0] = add( shr( predBuf_ni_fx[0], 1 ), shr( predBuf_ni_fx[1], 1 ) ); + move16(); tmp = sub( predBufLen, 1 ); FOR( sb = 1; sb < tmp; sb++ ) { @@ -630,8 +616,10 @@ static void GetSWBIndices_fx( L_temp = L_add( L_temp, L_mult( predBuf_ni_fx[sb - 1], 10922 ) ); L_temp = L_add( L_temp, L_mult( predBuf_ni_fx[sb + 1], 10922 ) ); /* Qss+15+1 */ sspectra_ma_fx[sb] = round_fx( L_temp ); + move16(); } sspectra_ma_fx[sb] = add( shr( predBuf_ni_fx[sb - 1], 1 ), shr( predBuf_ni_fx[sb], 1 ) ); + move16(); /* Partial search for rest of subbands except the last which is fixed */ FOR( sb = 0; sb < nBands_search; sb++ ) @@ -645,6 +633,7 @@ static void GetSWBIndices_fx( sbLen, nlags_fx[sb], gi_fx + ( sb * N_NBIGGEST_PULSEARCH ), n_nbiggestsearch_fx[sb], ssearch_buflim_fx, predBuf_ni_fx + search_offset_fx[sb] ); + move16(); } } /*--------------------------------------------------------------------------* @@ -710,6 +699,7 @@ static void gethar_noisegn_fx( Word16 Qg; #ifdef BASOP_NOGLOB_DECLARE_LOCAL Flag Overflow = 0; + move16(); #endif /*Generate HF noise*/ genhf_noise_fx( noise_flr_fx, Qss, L_xSynth_har, QsL, sspectra_fx, bands, har_bands, har_freq_est2, pos_max_hfe2, pul_res_fx, pk_sf_fx, fLenLow, @@ -724,6 +714,7 @@ static void gethar_noisegn_fx( } L_temp = 0x0; + move32(); FOR( i = 0; i < fLenHigh; i++ ) { L_temp = L_or( L_temp, L_abs( L_hfspec[i] ) ); @@ -732,9 +723,11 @@ static void gethar_noisegn_fx( FOR( i = 0; i < fLenHigh; i++ ) { L_hfspec_sft[i] = L_shl( L_hfspec[i], exp_norm_g1 ); + move32(); } L_temp = 0x0; + move32(); FOR( i = 0; i < fLenHigh; i++ ) { L_temp = L_or( L_temp, L_abs( L_xSynth_har[i] ) ); @@ -743,6 +736,7 @@ static void gethar_noisegn_fx( FOR( i = 0; i < fLenHigh; i++ ) { L_xSynth_har_sft[i] = L_shl( L_xSynth_har[i], exp_norm_g2 ); + move32(); } exp_safe = 4; @@ -787,14 +781,9 @@ static void gethar_noisegn_fx( exp = sub( exp, Qsqrt ); L_temp = L_Comp( exp, frac ); - L_temp = Mpy_32_16_1( L_temp, 19728 ); /* log(2)/log(10)=.30102999566398119521 = 19728.3(Q16) Q(0+16+1)=Q17 */ -#ifdef BASOP_NOGLOB + L_temp = Mpy_32_16_1( L_temp, 19728 ); /* log(2)/log(10)=.30102999566398119521 = 19728.3(Q16) Q(0+16+1)=Q17 */ L_temp = L_shl_o( L_temp, 13, &Overflow ); /* Q17+13=30 30-16=14 */ g_fx = round_fx_o( L_temp, &Overflow ); -#else - L_temp = L_shl( L_temp, 13 ); /* Q17+13=30 30-16=14 */ - g_fx = round_fx( L_temp ); -#endif } gqlevs_fx = 4; @@ -926,7 +915,7 @@ static void EncodeSWBSubbands_fx( IF( flag_dis == 0 ) { test(); - if ( NE_16( har_freq_est2, SWB_HAR_RAN1 ) || NE_16( har_freq_est2, *prev_frm_hfe2 ) ) + IF( NE_16( har_freq_est2, SWB_HAR_RAN1 ) || NE_16( har_freq_est2, *prev_frm_hfe2 ) ) { har_freq_est2 = add( har_freq_est2, lagIndices_fx[0] ); move16(); @@ -995,14 +984,17 @@ static void EncodeSWBSubbands_fx( FOR( k = 0; k < NB_SWB_SUBBANDS; k++ ) { lagGains_fx[k] = mult_r( lagGains_fx[k], 29491 ); /* lagGains[k]*0.9f; */ + move16(); } FOR( k = 0; k < NB_SWB_SUBBANDS; k++ ) { L_th_g[k] = L_deposit_l( 0 ); + move32(); IF( p2a_flags_fx[BANDS_fx - NB_SWB_SUBBANDS + k] == 0 ) { L_th_g[k] = L_shl( L_mult( lagGains_fx[k], ss_min_fx ), sub( QsL, add( add( QlagGains[k], Qss ), 1 ) ) ); /* QlagGain+Qss -> QsL */ + move32(); } } @@ -1121,7 +1113,7 @@ static void EncodeSWBSubbands_ivas_fx( IF( flag_dis == 0 ) { test(); - if ( NE_16( har_freq_est2, SWB_HAR_RAN1 ) || NE_16( har_freq_est2, *prev_frm_hfe2 ) ) + IF( NE_16( har_freq_est2, SWB_HAR_RAN1 ) || NE_16( har_freq_est2, *prev_frm_hfe2 ) ) { har_freq_est2 = add( har_freq_est2, lagIndices_fx[0] ); move16(); @@ -1190,14 +1182,17 @@ static void EncodeSWBSubbands_ivas_fx( FOR( k = 0; k < NB_SWB_SUBBANDS; k++ ) { lagGains_fx[k] = mult_r( lagGains_fx[k], 29491 ); /* lagGains[k]*0.9f; */ + move16(); } FOR( k = 0; k < NB_SWB_SUBBANDS; k++ ) { L_th_g[k] = L_deposit_l( 0 ); + move32(); IF( p2a_flags_fx[BANDS_fx - NB_SWB_SUBBANDS + k] == 0 ) { L_th_g[k] = L_shl( L_mult( lagGains_fx[k], ss_min_fx ), sub( QsL, add( add( QlagGains[k], Qss ), 1 ) ) ); /* QlagGain+Qss -> QsL */ + move32(); } } @@ -1313,6 +1308,7 @@ void swb_bwe_enc_lr_fx( FOR( k = 0; k < swb_lowband_fx; k++ ) { L_m[k] = L_deposit_l( 0 ); + move32(); } return; @@ -1396,6 +1392,7 @@ void swb_bwe_enc_lr_ivas_fx( FOR( k = 0; k < swb_lowband_fx; k++ ) { L_m[k] = L_deposit_l( 0 ); + move32(); } return; diff --git a/lib_enc/swb_pre_proc.c b/lib_enc/swb_pre_proc.c deleted file mode 100644 index db5861968e78a1a8eb34edab050ba9bada4ce2a9..0000000000000000000000000000000000000000 --- a/lib_enc/swb_pre_proc.c +++ /dev/null @@ -1,748 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include -#include "cnst.h" -#include "prot.h" -#include "rom_com.h" -#include "rom_enc.h" -#include "wmc_auto.h" -#include "ivas_prot.h" -#include "ivas_rom_enc.h" -#include "ivas_prot_fx.h" -#include "prot_fx.h" -#include "prot_fx_enc.h" - - -/*-------------------------------------------------------------------* - * swb_pre_proc() - * - * - Calculate the 6 to 14 kHz (or 7.5 - 15.5 kHz) SHB target signal - * for SWB TBE or SWB BWE coding - * - Common SWB TBE and SWB BWE pre-processing - *-------------------------------------------------------------------*/ - -/*full implementation pending*/ -void swb_pre_proc_ivas_fx( - Encoder_State *st, /* i/o: encoder state structure */ - Word16 *new_swb_speech, /* o : original input signal at 32kHz - Q0 */ - Word32 *new_swb_speech_fx, /* o : original input signal at 32kHz - Q - q_reImBuffer */ - Word16 *shb_speech, /* o : SHB target signal (6-14kHz) at 16kHz- Q(Q_shb_spch) */ - Word16 *Q_shb_spch, - Word32 realBuffer[CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], /* i : real buffer Q - q_reImbuffer */ - Word32 imagBuffer[CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], /* i : imag buffer Q - q_reImbuffer */ - Word16 q_reImBuffer, /* i : scale data of real and imag CLDFB buffers */ - CPE_ENC_HANDLE hCPE /* i/o: CPE encoder structure */ -) -{ - Word16 Sample_Delay_SWB_BWE, inner_frame, delay; - TD_BWE_ENC_HANDLE hBWE_TD; - FD_BWE_ENC_HANDLE hBWE_FD; - Word32 inner_Fs, input_Fs; - Word16 old_input_fx[NS2SA( 48000, DELAY_FD_BWE_ENC_NS + DELAY_FIR_RESAMPL_NS ) + L_FRAME48k]; // fixed counterpart - Word32 old_input_fx_32[NS2SA( 48000, DELAY_FD_BWE_ENC_NS + DELAY_FIR_RESAMPL_NS ) + L_FRAME48k]; // fixed counterpart - Word16 spchTmp[L_FRAME32k], spchTmp2[L_FRAME32k]; - Word16 i, j, L_resamp; - Word16 startB, endB; - Word32 *realBufferFlipped[CLDFB_NO_COL_MAX]; - Word32 *imagBufferFlipped[CLDFB_NO_COL_MAX]; - Word32 realBufferTmp[CLDFB_NO_COL_MAX][20]; - Word32 imagBufferTmp[CLDFB_NO_COL_MAX][20]; - Word32 shb_speech_fx_32[L_FRAME16k]; - Word16 ts, nB, uB; - Word32 v, t, regression; - Word16 t_16; - const Word32 *thr, *regV; - Word32 lbEner; - Word16 exp_lbEner = 0; - Word16 Sample_Delay_SWB_BWE32k, lMemRecalc32k, dft_ovl32k; - Word32 one_by_50_Q31 = 42949673; - - lMemRecalc32k = NS2SA_FX2( 32000, L_MEM_RECALC_NS ); - move16(); // exp_lbEner - move16(); // lMemRecalc32k - move32(); // one_by_50_Q31 - - /* initialization */ - hBWE_TD = st->hBWE_TD; - hBWE_FD = st->hBWE_FD; - input_Fs = st->input_Fs; - - FOR( j = 0; j < CLDFB_NO_COL_MAX; j++ ) - { - set32_fx( realBufferTmp[j], 0, 20 ); - set32_fx( imagBufferTmp[j], 0, 20 ); - realBufferFlipped[j] = realBufferTmp[j]; - imagBufferFlipped[j] = imagBufferTmp[j]; - } - - set16_fx( old_input_fx, 0, NS2SA_FX2( 48000, DELAY_FD_BWE_ENC_12k8_NS + DELAY_FIR_RESAMPL_NS ) + L_FRAME48k ); - - IF( EQ_32( st->input_Fs, 32000 ) ) - { - IF( st->element_mode > EVS_MONO ) - { - Sample_Delay_SWB_BWE = NS2SA_FX2( 32000, DELAY_FD_BWE_ENC_12k8_NS ); - move16(); - IF( EQ_16( st->L_frame, L_FRAME16k ) ) - { - Sample_Delay_SWB_BWE = NS2SA_FX2( 32000, DELAY_FD_BWE_ENC_16k_NS ); - move16(); - } - - Copy( st->input_fx - Sample_Delay_SWB_BWE, hBWE_FD->old_input_fx, Sample_Delay_SWB_BWE ); - Copy( st->input_fx - L_FRAME32k, hBWE_FD->old_fdbwe_speech_fx, L_FRAME32k ); - - test(); - test(); - IF( EQ_16( st->element_mode, IVAS_CPE_TD ) && GE_16( st->bwidth, SWB ) ) - { - Copy( st->input_fx - hCPE->hStereoTCA->lMemRecalc, hBWE_FD->L_old_wtda_swb_fx + L_FRAME32k - sub( hCPE->hStereoTCA->lMemRecalc, Sample_Delay_SWB_BWE ), sub( hCPE->hStereoTCA->lMemRecalc, Sample_Delay_SWB_BWE ) ); - } - ELSE IF( EQ_16( st->element_mode, IVAS_CPE_DFT ) && GE_16( st->bwidth, SWB ) ) - { - Copy( st->input_fx - hCPE->hStereoDft->dft_ovl, hBWE_FD->L_old_wtda_swb_fx + L_FRAME32k - sub( hCPE->hStereoDft->dft_ovl, Sample_Delay_SWB_BWE ), sub( hCPE->hStereoDft->dft_ovl, Sample_Delay_SWB_BWE ) ); - } - } - - Copy( st->input_fx, new_swb_speech, L_FRAME32k ); - - test(); - test(); - IF( NE_16( st->last_extl, SWB_BWE ) && NE_16( st->last_extl, FB_BWE ) && NE_16( st->extl, SWB_BWE_HIGHRATE ) ) - { - Sample_Delay_SWB_BWE = NS2SA_FX2( 32000, DELAY_FD_BWE_ENC_12k8_NS + DELAY_FIR_RESAMPL_NS ); - move16(); - test(); - IF( st->element_mode > EVS_MONO && EQ_16( st->L_frame, L_FRAME16k ) ) - { - Sample_Delay_SWB_BWE = NS2SA_FX2( 32000, DELAY_FD_BWE_ENC_16k_NS + DELAY_FIR_RESAMPL_NS ); - move16(); - } - IF( st->element_mode > EVS_MONO ) - { - Sample_Delay_SWB_BWE = sub( Sample_Delay_SWB_BWE, NS2SA_FX2( 32000, DELAY_FIR_RESAMPL_NS ) ); - } - - Copy( hBWE_FD->old_fdbwe_speech_fx, &old_input_fx[Sample_Delay_SWB_BWE], L_FRAME32k ); - - set16_fx( old_input_fx, 0, Sample_Delay_SWB_BWE ); - Copy( hBWE_FD->old_fdbwe_speech_fx + L_FRAME32k - Sample_Delay_SWB_BWE, hBWE_FD->old_input_fx, Sample_Delay_SWB_BWE ); - IF( NE_16( st->extl, WB_BWE ) ) - { - Copy( old_input_fx, hBWE_FD->L_old_wtda_swb_fx, L_FRAME32k ); - } - } - - test(); - IF( NE_16( st->extl, SWB_BWE ) && NE_16( st->extl, FB_BWE ) ) - { - Copy( st->input_fx, hBWE_FD->old_fdbwe_speech_fx, L_FRAME32k ); - } - } - ELSE /* 48 kHz */ - { - - Sample_Delay_SWB_BWE32k = NS2SA_FX2( 32000, DELAY_FD_BWE_ENC_12k8_NS ); - move16(); - Sample_Delay_SWB_BWE = NS2SA_FX2( 48000, DELAY_FD_BWE_ENC_12k8_NS ); - move16(); - IF( EQ_16( st->L_frame, L_FRAME16k ) ) - { - Sample_Delay_SWB_BWE32k = NS2SA_FX2( 32000, DELAY_FD_BWE_ENC_16k_NS ); - move16(); - Sample_Delay_SWB_BWE = NS2SA_FX2( 48000, DELAY_FD_BWE_ENC_16k_NS ); - move16(); - } - - dft_ovl32k = 0; - move16(); - IF( EQ_16( st->element_mode, IVAS_CPE_DFT ) ) - { - dft_ovl32k = (Word16) ( STEREO_DFT_OVL_MAX * 32000 / 48000 ); - move16(); - } - - IF( EQ_16( st->codec_mode, MODE1 ) ) - { - IF( st->element_mode > EVS_MONO ) - { - - IF( EQ_16( st->element_mode, IVAS_CPE_TD ) ) - { - } - ELSE IF( EQ_16( st->bwidth, FB ) ) - { - Copy( st->input_fx - Sample_Delay_SWB_BWE, hBWE_FD->old_input_fx, Sample_Delay_SWB_BWE ); - } - - Copy( st->input_fx - L_FRAME48k, hBWE_FD->old_fdbwe_speech_fx, L_FRAME48k ); - - test(); - test(); - IF( EQ_16( st->element_mode, IVAS_CPE_TD ) && GE_16( st->bwidth, SWB ) ) - { - IF( EQ_16( st->bwidth, SWB ) ) - { - /* buffers hBWE_FD->old_input[] and hBWE_FD->old_wtda_swb[] need to be at 32 kHz (inner) sampling rate */ - - decimate_2_over_3_allpass_fx( st->input_fx - hCPE->hStereoTCA->lMemRecalc, hCPE->hStereoTCA->lMemRecalc, spchTmp, hBWE_TD->dec_2_over_3_mem_fx, - allpass_poles_3_ov_2, decimate_3_ov_2_lowpass_num_fx, decimate_3_ov_2_lowpass_den_fx, hBWE_TD->dec_2_over_3_mem_lp_fx ); - - Copy( spchTmp, hBWE_FD->L_old_wtda_swb_fx + L_FRAME32k - sub( lMemRecalc32k, Sample_Delay_SWB_BWE32k ), sub( lMemRecalc32k, Sample_Delay_SWB_BWE32k ) ); - Copy( spchTmp + lMemRecalc32k - Sample_Delay_SWB_BWE32k, hBWE_FD->old_input_fx, Sample_Delay_SWB_BWE32k ); - } - ELSE /* FB_BWE */ - { - Copy( st->input_fx - hCPE->hStereoTCA->lMemRecalc, hBWE_FD->L_old_wtda_swb_fx + L_FRAME48k - sub( hCPE->hStereoTCA->lMemRecalc, Sample_Delay_SWB_BWE ), sub( hCPE->hStereoTCA->lMemRecalc, Sample_Delay_SWB_BWE ) ); - Copy( st->input_fx - Sample_Delay_SWB_BWE, hBWE_FD->old_input_fx, Sample_Delay_SWB_BWE ); - } - } - ELSE IF( EQ_16( st->element_mode, IVAS_CPE_DFT ) && GE_16( st->bwidth, SWB ) ) - { - IF( EQ_16( st->bwidth, SWB ) ) - { - lerp( st->input_fx - hCPE->hStereoDft->dft_ovl, spchTmp, dft_ovl32k - Sample_Delay_SWB_BWE32k, hCPE->hStereoDft->dft_ovl - Sample_Delay_SWB_BWE ); - - Copy( spchTmp, hBWE_FD->L_old_wtda_swb_fx + L_FRAME32k - ( dft_ovl32k - Sample_Delay_SWB_BWE32k ), dft_ovl32k - Sample_Delay_SWB_BWE32k ); - } - ELSE - { - Copy( st->input_fx - hCPE->hStereoDft->dft_ovl, hBWE_FD->L_old_wtda_swb_fx + L_FRAME48k - ( hCPE->hStereoDft->dft_ovl - Sample_Delay_SWB_BWE ), hCPE->hStereoDft->dft_ovl - Sample_Delay_SWB_BWE ); - } - } - } - - test(); - test(); - test(); - test(); - IF( ( NE_16( st->extl, SWB_BWE ) && NE_16( st->extl, FB_BWE ) && ( st->core == ACELP_CORE ) ) || ( EQ_16( st->element_mode, IVAS_CPE_DFT ) && ( st->core != ACELP_CORE ) ) /*resampling not needed for MDCT cores*/ ) - { - /* move the resampling out of the TDBWE path as new_swb_speech is not needed for TDBWE. */ - Copy( st->input_fx, hBWE_FD->old_fdbwe_speech_fx, L_FRAME48k ); - } - ELSE - { - test(); - IF( NE_16( st->last_extl, SWB_BWE ) && NE_16( st->last_extl, FB_BWE ) ) - { - /* resample 48 kHz to 32kHz */ - IF( EQ_16( st->last_bwidth, FB ) ) - { - inner_frame = L_FRAME48k; - move16(); - inner_Fs = 48000; - move32(); - Copy( hBWE_FD->old_fdbwe_speech_fx, new_swb_speech, L_FRAME48k ); - } - ELSE - { - inner_frame = L_FRAME32k; - move16(); - inner_Fs = 32000; - move32(); - - IF( NE_16( st->element_mode, IVAS_CPE_DFT ) ) - { - decimate_2_over_3_allpass_fx( hBWE_FD->old_fdbwe_speech_fx, L_FRAME48k, new_swb_speech, hBWE_TD->dec_2_over_3_mem_fx, allpass_poles_3_ov_2, decimate_3_ov_2_lowpass_num_fx, decimate_3_ov_2_lowpass_den_fx, hBWE_TD->dec_2_over_3_mem_lp_fx ); - } - ELSE - { - lerp( hBWE_FD->old_fdbwe_speech_fx, new_swb_speech, inner_frame, L_FRAME48k ); - } - - test(); - IF( EQ_16( st->element_mode, IVAS_CPE_DFT ) && st->idchan == 0 ) - { - FOR( i = 0; i < STEREO_DFT_OVL_32k; i++ ) - { - hCPE->hStereoDft->output_mem_dmx_32k_fx[i] = Mpy_32_16_1( hCPE->hStereoDft->win_32k_fx[STEREO_DFT_OVL_32k - 1 - i], new_swb_speech[sub( add( inner_frame, i ), STEREO_DFT_OVL_32k )] ); - move32(); - } - } - } - - Sample_Delay_SWB_BWE = NS2SA_FX2( inner_Fs, DELAY_FD_BWE_ENC_12k8_NS + DELAY_FIR_RESAMPL_NS ); - move16(); - test(); - IF( st->element_mode > EVS_MONO && EQ_16( st->L_frame, L_FRAME16k ) ) - { - Sample_Delay_SWB_BWE = NS2SA_FX2( inner_Fs, DELAY_FD_BWE_ENC_16k_NS + DELAY_FIR_RESAMPL_NS ); - move16(); - } - IF( st->element_mode > EVS_MONO ) - { - Sample_Delay_SWB_BWE = sub( Sample_Delay_SWB_BWE, NS2SA_FX2( inner_Fs, DELAY_FIR_RESAMPL_NS ) ); - } - - Copy( new_swb_speech, &old_input_fx[Sample_Delay_SWB_BWE], inner_frame ); - set16_fx( old_input_fx, 0, Sample_Delay_SWB_BWE ); - Copy( new_swb_speech + inner_frame - Sample_Delay_SWB_BWE, hBWE_FD->old_input_fx, Sample_Delay_SWB_BWE ); - Copy( old_input_fx, hBWE_FD->L_old_wtda_swb_fx, inner_frame ); - } - - /* resample 48 kHz to 32kHz */ - IF( EQ_16( st->bwidth, FB ) ) - { - Copy( st->input_fx, new_swb_speech, L_FRAME48k ); - } - ELSE - { - IF( EQ_16( st->element_mode, IVAS_CPE_TD ) ) - { - Word16 dec_2_over_3_mem_tmp[L_FILT_2OVER3], dec_2_over_3_mem_lp_tmp[L_FILT_2OVER3_LP]; - - decimate_2_over_3_allpass_fx( st->input_fx, L_FRAME48k - hCPE->hStereoTCA->lMemRecalc, new_swb_speech, hBWE_TD->dec_2_over_3_mem_fx, allpass_poles_3_ov_2, decimate_3_ov_2_lowpass_num_fx, decimate_3_ov_2_lowpass_den_fx, hBWE_TD->dec_2_over_3_mem_lp_fx ); - - Copy( hBWE_TD->dec_2_over_3_mem_fx, dec_2_over_3_mem_tmp, L_FILT_2OVER3 ); - Copy( hBWE_TD->dec_2_over_3_mem_lp_fx, dec_2_over_3_mem_lp_tmp, L_FILT_2OVER3_LP ); - - decimate_2_over_3_allpass_fx( st->input_fx + L_FRAME48k - hCPE->hStereoTCA->lMemRecalc, hCPE->hStereoTCA->lMemRecalc, new_swb_speech + L_FRAME32k - lMemRecalc32k, dec_2_over_3_mem_tmp, allpass_poles_3_ov_2, decimate_3_ov_2_lowpass_num_fx, decimate_3_ov_2_lowpass_den_fx, dec_2_over_3_mem_lp_tmp ); - } - ELSE IF( NE_16( st->element_mode, IVAS_CPE_DFT ) ) - { - decimate_2_over_3_allpass_fx( st->input_fx, L_FRAME48k, new_swb_speech, hBWE_TD->dec_2_over_3_mem_fx, allpass_poles_3_ov_2, decimate_3_ov_2_lowpass_num_fx, decimate_3_ov_2_lowpass_den_fx, hBWE_TD->dec_2_over_3_mem_lp_fx ); - } - ELSE /* IVAS_CPE_DFT */ - { - Word16 out_start_ind, out_end_ind; - stereo_dft_enc_synthesize_fx( hCPE->hStereoDft, new_swb_speech_fx, &out_start_ind, &out_end_ind, st->idchan, input_Fs, 32000, 0, NULL ); - Copy_Scale_sig32_16( new_swb_speech_fx - STEREO_DFT_OVL_MAX, new_swb_speech - STEREO_DFT_OVL_MAX, L_FRAME48k + STEREO_DFT_OVL_MAX, q_reImBuffer ); - Copy( new_swb_speech - Sample_Delay_SWB_BWE32k, hBWE_FD->old_input_fx, Sample_Delay_SWB_BWE32k ); - } - } - } - } - ELSE - { - /* resample 48 kHz to 32kHz */ - IF( EQ_16( st->bwidth, FB ) ) - { - Copy( st->input_fx, new_swb_speech, L_FRAME48k ); - } - ELSE - { - decimate_2_over_3_allpass_fx( st->input_fx, L_FRAME48k, new_swb_speech, hBWE_TD->dec_2_over_3_mem_fx, allpass_poles_3_ov_2, decimate_3_ov_2_lowpass_num_fx, decimate_3_ov_2_lowpass_den_fx, hBWE_TD->dec_2_over_3_mem_lp_fx ); - } - } - } - - test(); - test(); - test(); - test(); - test(); - test(); - IF( ( ( st->core == ACELP_CORE ) && NE_16( st->extl, SWB_BWE_HIGHRATE ) && NE_16( st->extl, FB_BWE_HIGHRATE ) ) || - ( ( EQ_32( st->total_brate, ACELP_9k60 ) || st->rf_mode ) && EQ_16( st->bwidth, SWB ) && ( st->element_mode == EVS_MONO ) ) ) - { - Word32 CldfbHB_fx = 0; // fixed counterpart - Word16 CldfbHB_fx_e = 0; // fixed counterpart -#ifdef BASOP_NOGLOB_DECLARE_LOCAL - Flag Overflow = 0; -#endif - Word16 realQ_neg1, imagQ_neg1, exp = 0, Cldfbtemp1; - move32(); - move16(); - move16(); - - IF( EQ_16( st->element_mode, IVAS_CPE_DFT ) ) - { - Word16 out_start_ind, out_end_ind; - Word16 exp_icbweRefEner_fx; - Copy_Scale_sig_16_32( (const Word16 *) &old_input_fx[0], &old_input_fx_32[0], NS2SA( 48000, DELAY_FD_BWE_ENC_NS + DELAY_FIR_RESAMPL_NS ) + L_FRAME48k, Q16 ); - CldfbHB_fx = stereo_dft_enc_synthesize_fx( hCPE->hStereoDft, old_input_fx_32 + STEREO_DFT_OVL_16k, &out_start_ind, &out_end_ind, st->idchan, input_Fs, 16000, st->L_frame, &CldfbHB_fx_e ); - Copy_Scale_sig_32_16( (const Word32 *) &old_input_fx_32[0], &old_input_fx[0], NS2SA( 48000, DELAY_FD_BWE_ENC_NS + DELAY_FIR_RESAMPL_NS ) + L_FRAME48k, -Q16 ); - - /* delay corresponding to CLDFB delay */ - Copy( old_input_fx + STEREO_DFT_OVL_16k - 20, shb_speech, L_FRAME16k ); - Copy( old_input_fx, hBWE_TD->old_speech_shb_fx + L_LOOK_16k + L_SUBFR16k - ( STEREO_DFT_OVL_16k - 20 ), STEREO_DFT_OVL_16k - 20 ); - Copy( old_input_fx, hCPE->hStereoICBWE->mem_shb_speech_ref_fx, STEREO_DFT_OVL_16k - 20 ); - - IF( LE_32( CldfbHB_fx, 0 ) ) - { - CldfbHB_fx = EPSILON_FX; - move32(); - } - CldfbHB_fx = L_shl( CldfbHB_fx, exp ); /* CldfbHB_ener = CldfbHB_fl*2^(exp) */ - Cldfbtemp1 = Log2_norm_lc( CldfbHB_fx ); /* Log2_norm_lc(t) = 2^15*(log2(t/2^30)) */ - Cldfbtemp1 = sub( shr( Cldfbtemp1, 6 ), shl( add( sub( Q31 - Q30, CldfbHB_fx_e ), exp ), 9 ) ); - CldfbHB_fx = L_mult( Cldfbtemp1, 9864 ); /* Q9 + Q15 + Q1 = Q25 */ - CldfbHB_fx = Mpy_32_16_1( L_sub( CldfbHB_fx, 1 << Q25 ), 11611 /* 0.1 * 0.221462 in Q19 */ ); - /* Resulting Q = Q25 + Q19 - Q15 = Q29 */ - hBWE_TD->cldfbHBLT = mac_r( CldfbHB_fx, 29491 /*0.9 Q15*/, hBWE_TD->cldfbHBLT ); /* cldfbHBLT is in Q13 */ - move16(); - - exp_lbEner = hCPE->hStereoDft->lbEner_fx_e; - move32(); - lbEner = Mpy_32_16_1( Sqrt32( hCPE->hStereoDft->lbEner_fx, &exp_lbEner ), 1638 /* 0.05 in Q15 */ ); - exp_icbweRefEner_fx = hCPE->hStereoDft->icbweRefEner_fx_e; - move16(); - hCPE->hStereoICBWE->icbweRefEner_fx = Mpy_32_16_1( Sqrt32( hCPE->hStereoDft->icbweRefEner_fx, &exp_icbweRefEner_fx ), 1638 /* 0.05 in Q15 */ ); - move32(); - hCPE->hStereoICBWE->icbweRefEner_fx_e = exp_icbweRefEner_fx; - move16(); - // lbEner = 0.05f * (float) sqrt( hCPE->hStereoDft->lbEner ); - thr = icbwe_thr_DFT_fx; - regV = icbwe_regressionValuesDFT_fx; - } - ELSE - { - IF( EQ_16( st->L_frame, L_FRAME ) ) - { - startB = 34; - move16(); - endB = 14; - move16(); - FOR( ts = 0; ts < CLDFB_NO_COL_MAX; ts++ ) - { - uB = 0; - move16(); - FOR( nB = startB; nB > endB; nB-- ) - { - realBufferFlipped[ts][uB] = realBuffer[ts][nB]; - move32(); - if ( s_and( ts, 1 ) != 0 ) - { - realBufferFlipped[ts][uB] = L_negate( realBufferFlipped[ts][uB] ); - move32(); - } - imagBufferFlipped[ts][uB] = imagBuffer[ts][nB]; - move32(); - if ( s_and( ts, 1 ) == 0 ) - { - imagBufferFlipped[ts][uB] = L_negate( imagBufferFlipped[ts][uB] ); - move32(); - } - uB = add( uB, 1 ); /* uB ++ */ - } - } - } - ELSE - { - startB = 39; - move16(); - endB = 19; - move16(); - FOR( ts = 0; ts < CLDFB_NO_COL_MAX; ts++ ) - { - uB = 0; - move16(); - FOR( nB = startB; nB > endB; nB-- ) - { - realBufferFlipped[ts][uB] = L_negate( realBuffer[ts][nB] ); - move32(); - imagBufferFlipped[ts][uB] = imagBuffer[ts][nB]; - move32(); - uB = add( uB, 1 ); /* uB ++ */ - } - } - } - - FOR( nB = 0; nB < 10; nB++ ) - { - FOR( ts = 0; ts < CLDFB_NO_COL_MAX; ts++ ) - { - realQ_neg1 = extract_l( L_shr( realBufferFlipped[ts][nB], 16 ) ); - imagQ_neg1 = extract_l( L_shr( imagBufferFlipped[ts][nB], 16 ) ); /* Q(-1), headroom needed */ - -#ifdef BASOP_NOGLOB - CldfbHB_fx = L_mac0_o( CldfbHB_fx, realQ_neg1, realQ_neg1, &Overflow ); - CldfbHB_fx = L_mac0_o( CldfbHB_fx, imagQ_neg1, imagQ_neg1, &Overflow ); /* Q(-2) */ -#else - CldfbHB_fx = L_mac0( CldfbHB_fx, realQ_neg1, realQ_neg1 ); - CldfbHB_fx = L_mac0( CldfbHB_fx, imagQ_neg1, imagQ_neg1 ); /* Q(-2) */ -#endif - } - } - CldfbHB_fx_e = sub( Q31, shl( sub( q_reImBuffer, Q16 ), 1 ) ); - exp = norm_l( CldfbHB_fx ); - CldfbHB_fx = L_shl( CldfbHB_fx, exp ); /* CldfbHB_ener = CldfbHB_fl*2^(exp) */ - Cldfbtemp1 = Log2_norm_lc( CldfbHB_fx ); /* Log2_norm_lc(t) = 2^15*(log2(t/2^30)) */ - Cldfbtemp1 = sub( shr( Cldfbtemp1, 6 ), shl( add( sub( Q31 - Q30, CldfbHB_fx_e ), exp ), 9 ) ); - CldfbHB_fx = L_mult( Cldfbtemp1, 9864 ); /* Q9 + Q15 + Q1 = Q25 */ - CldfbHB_fx = Mpy_32_16_1( L_sub( CldfbHB_fx, 1 << Q25 ), 11611 /* 0.1 * 0.221462 in Q19 */ ); - /* Resulting Q = Q25 + Q19 - Q15 = Q29 */ - hBWE_TD->cldfbHBLT = mac_r( CldfbHB_fx, 29491 /*0.9 Q15*/, hBWE_TD->cldfbHBLT ); /* cldfbHBLT is in Q13 */ - move32(); - - IF( CldfbHB_fx == 0 ) - { - CldfbHB_fx = EPSILLON_FX; - move32(); - } - - test(); - IF( GE_16( st->element_mode, IVAS_CPE_DFT ) && hCPE->hStereoICBWE != NULL ) - { - Word32 icbweRefEner_fx = EPSILON_FX; - Word16 exp_icbweRefEner_fx = 0; - - move32(); - move16(); - FOR( nB = 20; nB < 40; nB++ ) - { - FOR( ts = 0; ts < CLDFB_NO_COL_MAX; ts++ ) - { - realQ_neg1 = extract_l( L_shr( realBuffer[ts][nB], 16 ) ); - imagQ_neg1 = extract_l( L_shr( imagBuffer[ts][nB], 16 ) ); /* Q(-1), headroom needed */ - icbweRefEner_fx = L_mac0_o( icbweRefEner_fx, realQ_neg1, realQ_neg1, &Overflow ); - icbweRefEner_fx = L_mac0_o( icbweRefEner_fx, imagQ_neg1, imagQ_neg1, &Overflow ); /* Q(-2) */ - } - } - exp_icbweRefEner_fx = sub( Q31, shl( sub( q_reImBuffer, Q16 ), 1 ) ); - hCPE->hStereoICBWE->icbweRefEner_fx = Mpy_32_16_1( Sqrt32( icbweRefEner_fx, &exp_icbweRefEner_fx ), 1638 /* 0.05 in Q15 */ ); - move32(); - hCPE->hStereoICBWE->icbweRefEner_fx_e = exp_icbweRefEner_fx; - move16(); - } - - lbEner = EPSILON_FX; - move32(); - FOR( nB = 0; nB < 20; nB++ ) - { - FOR( ts = 0; ts < CLDFB_NO_COL_MAX; ts++ ) - { - realQ_neg1 = extract_l( L_shr( realBuffer[ts][nB], 16 ) ); - imagQ_neg1 = extract_l( L_shr( imagBuffer[ts][nB], 16 ) ); /* Q(-1), headroom needed */ - - lbEner = L_mac0_o( lbEner, realQ_neg1, realQ_neg1, &Overflow ); - lbEner = L_mac0_o( lbEner, imagQ_neg1, imagQ_neg1, &Overflow ); /* Q(-2) */ - } - } - exp_lbEner = sub( Q31, shl( sub( q_reImBuffer, Q16 ), 1 ) ); - lbEner = Mpy_32_16_1( Sqrt32( lbEner, &exp_lbEner ), 1638 /* 0.05 in Q15 */ ); - thr = icbwe_thr_TDM_fx; - regV = icbwe_regressionValuesTDM_fx; - - cldfbSynthesis_ivas_fx( realBufferFlipped, imagBufferFlipped, shb_speech_fx_32, -1, st->cldfbSynTd ); - Copy_Scale_sig_32_16( shb_speech_fx_32, shb_speech, L_FRAME16k, negate( sub( q_reImBuffer, 1 ) ) ); - *Q_shb_spch = 0; - move16(); - } - - IF( GE_16( st->element_mode, IVAS_CPE_DFT ) && hCPE->hStereoICBWE != NULL ) - { - Word16 exp_t; - hCPE->hStereoICBWE->MSFlag = 0; /* Init the multi-source flag */ - move16(); - v = Mpy_32_16_1( sum16_fx( st->voicing_fx, 3 ), 10923 /* 0.33333 in Q15 */ ); - - // t = log10f( ( hCPE->hStereoICBWE->icbweRefEner + 1e-6f ) / ( lbEner + 1e-6f ) ); - t = L_deposit_h( BASOP_Util_Divide3232_Scale( L_add( hCPE->hStereoICBWE->icbweRefEner_fx, EPSILON_FX ), L_add( lbEner, EPSILON_FX ), &exp_t ) ); - exp_t = add( exp_t, sub( hCPE->hStereoICBWE->icbweRefEner_fx_e, exp_lbEner ) ); - exp = norm_l( t ); - t = L_shl( t, exp ); - t_16 = Log2_norm_lc( t ); /* Log2_norm_lc(t) = 2^15*(log2(t/2^30)) */ - t_16 = sub( shr( t_16, 6 ), shl( add( sub( Q31 - Q30, exp_t ), exp ), 9 ) ); - t = L_mult( t_16, 9864 ); /* Q9 + Q15 + Q1 = Q25 */ - /* Three Level Decision Tree to calculate a regression value first */ - IF( LT_32( t, thr[0] ) ) /* level 1 */ - { - IF( LT_32( t, thr[1] ) ) /* level 2 */ - { - IF( LT_32( v, thr[3] ) ) - { - regression = regV[0]; /* level 3 */ - move32(); - } - ELSE - { - regression = regV[1]; - move32(); - } - } - ELSE - { - IF( LT_32( v, thr[4] ) ) - { - regression = regV[2]; /* level 3 */ - move32(); - } - ELSE - { - regression = regV[3]; - move32(); - } - } - } - ELSE - { - IF( LT_32( t, thr[2] ) ) /* level 2 */ - { - IF( LT_32( v, thr[5] ) ) - { - regression = regV[4]; /* level 3 */ - move32(); - } - ELSE - { - regression = regV[5]; - move32(); - } - } - ELSE - { - IF( LT_32( v, thr[6] ) ) - { - regression = regV[6]; /* level 3 */ - move32(); - } - ELSE - { - regression = regV[7]; - move32(); - } - } - } - - test(); - test(); - /* Convert the regression to a hard decision (classification) */ - IF( GT_32( regression, 1696512081 /* 0.79f in Q31*/ ) && !( LT_16( st->bwidth, SWB ) || hCPE->hCoreCoder[0]->vad_flag == 0 ) ) - { - hCPE->hStereoICBWE->MSFlag = 1; - move16(); - } - } - - test(); - test(); - IF( NE_16( st->extl, WB_TBE ) && NE_16( st->extl, SWB_TBE ) && NE_16( st->extl, FB_TBE ) ) - { - /* Update the previous superwideband speech buffer in case of a SWB_BWE frame - this code is in swb_tbe_enc */ - delay = L_LOOK_16k + L_SUBFR16k; - move16(); - Copy( shb_speech + sub( L_FRAME16k, delay ), hBWE_TD->old_speech_shb_fx, delay ); - } - } - ELSE - { - test(); - test(); - IF( ( EQ_16( st->bwidth, FB ) || st->core == ACELP_CORE ) && ( st->element_mode == EVS_MONO ) ) - { - InitSWBencBufferStates_fx( st->hBWE_TD, shb_speech ); - } - ELSE - { - IF( EQ_16( st->element_mode, IVAS_CPE_DFT ) ) - { - IF( EQ_16( st->L_frame, L_FRAME ) ) - { - L_resamp = 560; /* 6.4 kHz core -> 6 - 14 kHz SHB target. 20 ms is 560 samples in 28 kHz sample rate */ - move16(); - } - ELSE - { - L_resamp = 620; /* 8 kHz core -> 7.5 - 15.5 kHz SHB target. 20 ms is 620 samples in 31 kHz sample rate */ - move16(); - } - - /* Dirty downsampling to match Nyquist to upper frequency limit of target */ - lerp( st->input_fx, new_swb_speech, L_resamp, (int16_t) Mpy_32_32( input_Fs, one_by_50_Q31 ) ); - - /* flip the spectrum */ - Copy( new_swb_speech, spchTmp, L_resamp ); - FOR( i = 0; i < L_resamp; i = i + 2 ) - { - spchTmp[i] = negate( spchTmp[i] ); - move16(); - } - - /* Dirty upsampling to match Nyquist/2 to lower frequency limit of target (reversed spectrum)*/ - lerp( spchTmp, spchTmp2, L_FRAME32k, L_resamp ); - Copy( spchTmp2, spchTmp, L_FRAME32k ); - } - ELSE - { - /* flip the spectrum */ - Copy( new_swb_speech, spchTmp, L_FRAME32k ); - - FOR( i = 0; i < L_FRAME32k; i = i + 2 ) - { - spchTmp[i] = negate( spchTmp[i] ); - move16(); - } - } - - Decimate_allpass_steep_fx( spchTmp, hBWE_TD->state_ana_filt_shb_fx, L_FRAME32k, shb_speech ); - - Copy( shb_speech + L_FRAME16k - ( L_LOOK_16k + L_SUBFR16k ), hBWE_TD->old_speech_shb_fx, L_LOOK_16k + L_SUBFR16k ); - - /*Compute the past overlap for potential next iDFTs SHB*/ - IF( EQ_16( st->element_mode, IVAS_CPE_DFT ) ) - { - FOR( i = 0; i < STEREO_DFT_OVL_16k; i++ ) - { - hCPE->hStereoDft->output_mem_dmx_16k_shb_fx[i] = L_mult( shb_speech[20 + i], mult_r( hCPE->hStereoDft->win_ana_16k_fx[STEREO_DFT_OVL_16k - 1 - i], hCPE->hStereoDft->win_ana_16k_fx[STEREO_DFT_OVL_16k - 1 - i] ) ); - move32(); - } - } - } - - IF( NE_16( st->element_mode, IVAS_CPE_DFT ) ) - { - /* Reset CLDFB synthesis buffer */ - set32_fx( st->cldfbSynTd->cldfb_state_fx, 0, st->cldfbSynTd->p_filter_length ); - } - ELSE - { - hCPE->hStereoDft->flip_sign = negate( hCPE->hStereoDft->flip_sign ); /* Make sure sign is updated even if DFT SHB target is not generated */ - move16(); - } - } - - /* Memory reset to compensate for 0.9375 ms offset when transitioning from IO to SWB */ - /* When switching from n >1 to n = 1, we keep the enc/dec delay as 8.75/3.25 and below code not needed; - only when n = 1 start, it will be 9.6875/2.3125 in that case this reset is needed for IO->BWE.*/ - test(); - IF( EQ_16( st->last_extl, -1 ) && ( st->element_mode == EVS_MONO ) ) - { - delay = NS2SA_FX2( input_Fs, DELAY_FIR_RESAMPL_NS ); - move16(); - FOR( i = 0; i < delay; i++ ) - { - shb_speech[i] = mult_r( mult_r( i, 983 /*0.03f Q15*/ ), shb_speech[2 * delay - 1 - i] ); - move16(); - } - } - - return; -} diff --git a/lib_enc/swb_pre_proc_fx.c b/lib_enc/swb_pre_proc_fx.c index 9a60072c3c4d412e58421a3d4cf616c2fd815854..5c96a2f297d8eefba4346fa564f850c13f5b0b9a 100644 --- a/lib_enc/swb_pre_proc_fx.c +++ b/lib_enc/swb_pre_proc_fx.c @@ -9,9 +9,11 @@ #include "rom_com_fx.h" #include "rom_com.h" #include "stl.h" -#include "prot_fx.h" /* Function prototypes */ -#include "prot_fx_enc.h" /* Function prototypes */ +#include "prot_fx.h" /* Function prototypes */ +#include "ivas_prot_fx.h" /* Function prototypes */ +#include "prot_fx_enc.h" /* Function prototypes */ #include "basop_util.h" +#include "ivas_rom_enc.h" #include @@ -52,8 +54,11 @@ void wb_pre_proc_fx( Word16 temp_buf[320]; Word16 Q_wb_sp, i, max_wb; Word16 fSwitchFromIO = 0; + move16(); Word32 temp1 = 0; + move32(); Word32 temp2 = 0; + move32(); SC_VBR_ENC_HANDLE hSC_VBR = st_fx->hSC_VBR; TD_BWE_ENC_HANDLE hBWE_TD = st_fx->hBWE_TD; FD_BWE_ENC_HANDLE hBWE_FD = st_fx->hBWE_FD; @@ -75,7 +80,7 @@ void wb_pre_proc_fx( move16(); } - set16_fx( old_input, 0, NS2SA_FX2( 16000, DELAY_FD_BWE_ENC_12k8_NS + DELAY_FIR_RESAMPL_NS ) + L_FRAME16k ); + set16_fx( old_input, 0, NS2SA( 16000, DELAY_FD_BWE_ENC_12k8_NS + DELAY_FIR_RESAMPL_NS ) + L_FRAME16k ); max_wb = 1; move16(); @@ -93,7 +98,7 @@ void wb_pre_proc_fx( temp2 = L_mac0( temp2, temp_buf[i - 1], temp_buf[i] ); } - if ( temp2 < Mult_32_16( temp1, 31129 /*0.95f*/ ) ) + IF( temp2 < Mult_32_16( temp1, 31129 /*0.95f*/ ) ) { Q_wb_sp = sub( Q_wb_sp, 3 ); /* leave 3 bit headroom */ } @@ -107,15 +112,17 @@ void wb_pre_proc_fx( IF( EQ_16( st_fx->extl, WB_BWE ) || EQ_16( st_fx->extl, WB_TBE ) || st_fx->igf != 0 ) { ramp_flag = 0; + move16(); test(); test(); test(); test(); - IF( ( NE_16( st_fx->last_extl, WB_TBE ) && NE_16( st_fx->last_extl, WB_BWE ) && st_fx->igf == 0 ) || - ( st_fx->igf != 0 && fSwitchFromIO != 0 ) ) + if ( ( NE_16( st_fx->last_extl, WB_TBE ) && NE_16( st_fx->last_extl, WB_BWE ) && st_fx->igf == 0 ) || + ( st_fx->igf != 0 && fSwitchFromIO != 0 ) ) { ramp_flag = 1; + move16(); } IF( !hSC_VBR->ppp_mode ) @@ -153,7 +160,7 @@ void wb_pre_proc_fx( test(); IF( ( NE_16( st_fx->extl, WB_BWE ) || ( EQ_16( st_fx->extl, WB_BWE ) && LE_32( st_fx->total_brate, ACELP_8k00 ) ) ) && !hSC_VBR->ppp_mode ) { - Sample_Delay_WB_BWE = NS2SA_FX2( 16000, DELAY_FD_BWE_ENC_12k8_NS ); + Sample_Delay_WB_BWE = NS2SA( 16000, DELAY_FD_BWE_ENC_12k8_NS ); Copy( new_inp_resamp16k, &old_input[Sample_Delay_WB_BWE], L_FRAME16k ); Copy( hBWE_FD->old_input_wb_fx, old_input, Sample_Delay_WB_BWE ); @@ -204,11 +211,13 @@ void wb_pre_proc_ivas_fx( Word16 Q_wb_sp, i, max_wb; Word16 fSwitchFromIO = 0; Word16 ppp_mode; - Word32 temp1 = 0; - Word32 temp2 = 0; + Word64 temp1 = 0; + Word64 temp2 = 0; + Word32 tmp1, tmp2; + Word16 norm; move16(); - move32(); - move32(); + move64(); + move64(); TD_BWE_ENC_HANDLE hBWE_TD = st_fx->hBWE_TD; @@ -233,21 +242,21 @@ void wb_pre_proc_ivas_fx( test(); test(); test(); - IF( ( EQ_32( st_fx->last_total_brate, ACELP_6k60 ) ) || - ( EQ_32( st_fx->last_total_brate, ACELP_8k85 ) ) || - ( EQ_32( st_fx->last_total_brate, ACELP_12k65 ) ) || - ( EQ_32( st_fx->last_total_brate, ACELP_14k25 ) ) || - ( EQ_32( st_fx->last_total_brate, ACELP_15k85 ) ) || - ( EQ_32( st_fx->last_total_brate, ACELP_18k25 ) ) || - ( EQ_32( st_fx->last_total_brate, ACELP_19k85 ) ) || - ( EQ_32( st_fx->last_total_brate, ACELP_23k05 ) ) || - ( EQ_32( st_fx->last_total_brate, ACELP_23k85 ) ) ) + if ( ( EQ_32( st_fx->last_total_brate, ACELP_6k60 ) ) || + ( EQ_32( st_fx->last_total_brate, ACELP_8k85 ) ) || + ( EQ_32( st_fx->last_total_brate, ACELP_12k65 ) ) || + ( EQ_32( st_fx->last_total_brate, ACELP_14k25 ) ) || + ( EQ_32( st_fx->last_total_brate, ACELP_15k85 ) ) || + ( EQ_32( st_fx->last_total_brate, ACELP_18k25 ) ) || + ( EQ_32( st_fx->last_total_brate, ACELP_19k85 ) ) || + ( EQ_32( st_fx->last_total_brate, ACELP_23k05 ) ) || + ( EQ_32( st_fx->last_total_brate, ACELP_23k85 ) ) ) { fSwitchFromIO = 1; move16(); } - set16_fx( old_input, 0, NS2SA_FX2( 16000, DELAY_FD_BWE_ENC_12k8_NS + DELAY_FIR_RESAMPL_NS ) + STEREO_DFT_OVL_16k + L_FRAME16k ); + set16_fx( old_input, 0, NS2SA( 16000, DELAY_FD_BWE_ENC_12k8_NS + DELAY_FIR_RESAMPL_NS ) + STEREO_DFT_OVL_16k + L_FRAME16k ); max_wb = 1; move16(); @@ -258,14 +267,17 @@ void wb_pre_proc_ivas_fx( Q_wb_sp = norm_s( max_wb ); Copy_Scale_sig( new_inp_resamp16k, temp_buf, L_FRAME16k, -3 ); - temp1 = L_mac0( temp1, temp_buf[0], temp_buf[0] ); + temp1 = W_mac_32_32( temp1, temp_buf[0], temp_buf[0] ); FOR( i = 1; i < L_FRAME16k; i++ ) { - temp1 = L_mac0( temp1, temp_buf[i], temp_buf[i] ); - temp2 = L_mac0( temp2, temp_buf[i - 1], temp_buf[i] ); + temp1 = W_mac_32_32( temp1, temp_buf[i], temp_buf[i] ); + temp2 = W_mac_32_32( temp2, temp_buf[i - 1], temp_buf[i] ); } + norm = s_min( W_norm( temp1 ), W_norm( temp2 ) ); + tmp1 = W_extract_h( W_shl( temp1, norm ) ); + tmp2 = W_extract_h( W_shl( temp2, norm ) ); - if ( LT_32( temp2, Mpy_32_16_1( temp1, 31129 /*0.95f*/ ) ) ) + IF( LT_32( tmp2, Mpy_32_16_1( tmp1, 31129 /*0.95f*/ ) ) ) { Q_wb_sp = sub( Q_wb_sp, 3 ); /* leave 3 bit headroom */ } @@ -299,7 +311,6 @@ void wb_pre_proc_ivas_fx( IF( EQ_16( st_fx->element_mode, IVAS_CPE_DFT ) ) { Sample_Delay_WB_BWE = NS2SA( 16000, DELAY_FD_BWE_ENC_12k8_NS ); - move16(); IF( EQ_16( last_element_mode, IVAS_CPE_TD ) ) { @@ -332,7 +343,9 @@ void wb_pre_proc_ivas_fx( ELSE IF( EQ_16( st_fx->element_mode, IVAS_CPE_TD ) ) { Word16 l_recalc_16k = L_MEM_RECALC_16K + L_FILT16k + 1; /* Note: "+1" is used because L_FILT16k is not divisible by 4 */ + move16(); Word16 l_recalc_4k = ( L_MEM_RECALC_16K + L_FILT16k + 1 ) / 4; + move16(); Sample_Delay_WB_BWE = NS2SA( 16000, DELAY_FD_BWE_ENC_12k8_NS ); IF( EQ_16( last_element_mode, IVAS_CPE_DFT ) ) @@ -370,7 +383,7 @@ void wb_pre_proc_ivas_fx( { IF( EQ_32( st_fx->input_Fs, 16000 ) ) { - flip_spectrum_and_decimby4_fx( new_inp_resamp16k, hb_speech, L_FRAME16k, hBWE_TD->decim_state1_fx, hBWE_TD->decim_state2_fx, ramp_flag ); + flip_spectrum_and_decimby4_fx( temp_buf, hb_speech, L_FRAME16k, hBWE_TD->decim_state1_fx, hBWE_TD->decim_state2_fx, ramp_flag ); } ELSE { @@ -440,7 +453,7 @@ void wb_pre_proc_ivas_fx( test(); IF( ( NE_16( st_fx->extl, WB_BWE ) || ( EQ_16( st_fx->extl, WB_BWE ) && EQ_32( st_fx->total_brate, 0 ) ) ) && !ppp_mode ) { - Sample_Delay_WB_BWE = NS2SA_FX2( 16000, DELAY_FD_BWE_ENC_12k8_NS ); + Sample_Delay_WB_BWE = NS2SA( 16000, DELAY_FD_BWE_ENC_12k8_NS ); Copy( new_inp_resamp16k, &old_input[Sample_Delay_WB_BWE], L_FRAME16k ); Copy( hBWE_FD->old_input_wb_fx, old_input, Sample_Delay_WB_BWE ); @@ -512,6 +525,7 @@ void swb_pre_proc_fx( Word32 CldfbHB_ener; #ifdef BASOP_NOGLOB_DECLARE_LOCAL Flag Overflow = 0; + move16(); #endif Word16 realQ_neg1, imagQ_neg1, exp, Cldfbtemp1; TD_BWE_ENC_HANDLE hBWE_TD = st_fx->hBWE_TD; @@ -525,7 +539,7 @@ void swb_pre_proc_fx( imagBufferFlipped[j] = imagBufferTmp[j]; } - set16_fx( old_input_fx, 0, NS2SA_FX2( 48000, DELAY_FD_BWE_ENC_12k8_NS + DELAY_FIR_RESAMPL_NS ) + L_FRAME48k ); + set16_fx( old_input_fx, 0, NS2SA( 48000, DELAY_FD_BWE_ENC_12k8_NS + DELAY_FIR_RESAMPL_NS ) + L_FRAME48k ); IF( EQ_32( st_fx->input_Fs, 32000 ) ) { @@ -534,7 +548,7 @@ void swb_pre_proc_fx( test(); IF( NE_16( st_fx->last_extl, SWB_BWE ) && NE_16( st_fx->last_extl, FB_BWE ) && NE_16( st_fx->extl, SWB_BWE_HIGHRATE ) ) { - Sample_Delay_SWB_BWE = NS2SA_FX2( 32000, DELAY_FD_BWE_ENC_12k8_NS + DELAY_FIR_RESAMPL_NS ); + Sample_Delay_SWB_BWE = NS2SA( 32000, DELAY_FD_BWE_ENC_12k8_NS + DELAY_FIR_RESAMPL_NS ); Copy( hBWE_FD->old_fdbwe_speech_fx, &old_input_fx[Sample_Delay_SWB_BWE], L_FRAME32k ); set16_fx( old_input_fx, 0, Sample_Delay_SWB_BWE ); Copy( hBWE_FD->old_fdbwe_speech_fx + L_FRAME32k - Sample_Delay_SWB_BWE, hBWE_FD->old_input_fx, Sample_Delay_SWB_BWE ); @@ -582,6 +596,8 @@ void swb_pre_proc_fx( decimate_2_over_3_allpass_fx( hBWE_FD->old_fdbwe_speech_fx, L_FRAME48k, new_swb_speech_fx, hBWE_TD->dec_2_over_3_mem_fx, allpass_poles_3_ov_2, decimate_3_ov_2_lowpass_num_fx, decimate_3_ov_2_lowpass_den_fx, hBWE_TD->dec_2_over_3_mem_lp_fx ); } + move16(); + move16(); Sample_Delay_SWB_BWE = NS2SA_FX2( inner_Fs, DELAY_FD_BWE_ENC_12k8_NS + DELAY_FIR_RESAMPL_NS ); Copy( new_swb_speech_fx, &old_input_fx[Sample_Delay_SWB_BWE], inner_frame ); @@ -623,27 +639,33 @@ void swb_pre_proc_fx( test(); test(); test(); - IF( ( EQ_16( st_fx->core, ACELP_CORE ) && NE_16( st_fx->extl, SWB_BWE_HIGHRATE ) && NE_16( st_fx->extl, FB_BWE_HIGHRATE ) ) || ( ( EQ_32( st_fx->total_brate, 9600 ) || st_fx->rf_mode != 0 ) && EQ_16( st_fx->bwidth, SWB ) ) ) + IF( ( st_fx->core == ACELP_CORE && NE_16( st_fx->extl, SWB_BWE_HIGHRATE ) && NE_16( st_fx->extl, FB_BWE_HIGHRATE ) ) || ( ( EQ_32( st_fx->total_brate, 9600 ) || st_fx->rf_mode != 0 ) && EQ_16( st_fx->bwidth, SWB ) ) ) { IF( EQ_16( st_fx->L_frame, L_FRAME ) ) { startB = 34; + move16(); endB = 14; + move16(); FOR( ts = 0; ts < CLDFB_NO_COL_MAX; ts++ ) { uB = 0; + move16(); FOR( nB = startB; nB > endB; nB-- ) { - move16(); realBufferFlipped[ts][uB] = realBuffer[ts][nB]; + move32(); if ( s_and( ts, 1 ) != 0 ) { realBufferFlipped[ts][uB] = L_negate( realBufferFlipped[ts][uB] ); + move32(); } imagBufferFlipped[ts][uB] = imagBuffer[ts][nB]; + move32(); if ( s_and( ts, 1 ) == 0 ) { imagBufferFlipped[ts][uB] = L_negate( imagBufferFlipped[ts][uB] ); + move32(); } uB = add( uB, 1 ); /* uB ++ */ } @@ -652,14 +674,19 @@ void swb_pre_proc_fx( ELSE { startB = 39; + move16(); endB = 19; + move16(); FOR( ts = 0; ts < CLDFB_NO_COL_MAX; ts++ ) { uB = 0; + move16(); FOR( nB = startB; nB > endB; nB-- ) { realBufferFlipped[ts][uB] = L_negate( realBuffer[ts][nB] ); + move32(); imagBufferFlipped[ts][uB] = imagBuffer[ts][nB]; + move32(); uB = add( uB, 1 ); /* uB ++ */ } } @@ -668,6 +695,7 @@ void swb_pre_proc_fx( /* Highband energy computation for gain shape control in case of bandwidth switching fix*/ { CldfbHB_ener = 0; + move32(); FOR( nB = 0; nB < 10; nB++ ) { FOR( ts = 0; ts < CLDFB_NO_COL_MAX; ts++ ) @@ -675,13 +703,8 @@ void swb_pre_proc_fx( realQ_neg1 = extract_l( L_shr( realBufferFlipped[ts][nB], 31 - ( 15 + cldfbScale->hb_scale ) + 1 ) ); imagQ_neg1 = extract_l( L_shr( imagBufferFlipped[ts][nB], 31 - ( 15 + cldfbScale->hb_scale ) + 1 ) ); /* Q(-1), headroom needed */ -#ifdef BASOP_NOGLOB CldfbHB_ener = L_mac0_o( CldfbHB_ener, realQ_neg1, realQ_neg1, &Overflow ); CldfbHB_ener = L_mac0_o( CldfbHB_ener, imagQ_neg1, imagQ_neg1, &Overflow ); /* Q(-2) */ -#else - CldfbHB_ener = L_mac0( CldfbHB_ener, realQ_neg1, realQ_neg1 ); - CldfbHB_ener = L_mac0( CldfbHB_ener, imagQ_neg1, imagQ_neg1 ); /* Q(-2) */ -#endif } } @@ -695,6 +718,7 @@ void swb_pre_proc_fx( cldfbSynthesisFiltering( st_fx->cldfbSynTd, realBufferFlipped, imagBufferFlipped, cldfbScale, shb_speech_fx, 0, CLDFB_NO_COL_MAX, cldfbWorkBuffer ); *Q_shb_spch = 0; /*shb_speech_fx : Q0*/ + move16(); test(); test(); @@ -707,6 +731,7 @@ void swb_pre_proc_fx( } ELSE { + test(); IF( EQ_16( st_fx->bwidth, FB ) || EQ_16( st_fx->core, ACELP_CORE ) ) { set16_fx( hBWE_TD->old_speech_shb_fx, 0, L_LOOK_16k + L_SUBFR16k ); @@ -720,6 +745,7 @@ void swb_pre_proc_fx( FOR( i = 0; i < L_FRAME32k; i = i + 2 ) { spchTmp_fx[i] = negate( spchTmp_fx[i] ); + move16(); } Decimate_allpass_steep_fx( spchTmp_fx, hBWE_TD->state_ana_filt_shb_fx, L_FRAME32k, shb_speech_fx ); @@ -729,12 +755,705 @@ void swb_pre_proc_fx( /* Reset CLDFB synthesis buffer */ set16_fx( st_fx->cldfbSynTd->FilterStates, 0, st_fx->cldfbSynTd->p_filter_length + st_fx->cldfbSynTd->no_channels * st_fx->cldfbSynTd->no_col ); } - IF( st_fx->last_extl == -1 ) + IF( EQ_16( st_fx->last_extl, -1 ) ) { - delay = NS2SA( st_fx->input_Fs, DELAY_FIR_RESAMPL_NS ); + delay = NS2SA_FX2( st_fx->input_Fs, DELAY_FIR_RESAMPL_NS ); FOR( i = 0; i < delay; i++ ) { shb_speech_fx[i] = mult_r( mult_r( i, 983 /*0.03f Q15*/ ), shb_speech_fx[2 * delay - 1 - i] ); + move16(); + } + } + + return; +} + +/*-------------------------------------------------------------------* + * swb_pre_proc() + * + * - Calculate the 6 to 14 kHz (or 7.5 - 15.5 kHz) SHB target signal + * for SWB TBE or SWB BWE coding + * - Common SWB TBE and SWB BWE pre-processing + *-------------------------------------------------------------------*/ + +/*full implementation pending*/ +void swb_pre_proc_ivas_fx( + Encoder_State *st, /* i/o: encoder state structure */ + Word16 *new_swb_speech, /* o : original input signal at 32kHz - Q0 */ + Word32 *new_swb_speech_fx, /* o : original input signal at 32kHz - Q - q_reImBuffer */ + Word16 *shb_speech, /* o : SHB target signal (6-14kHz) at 16kHz- Q(Q_shb_spch) */ + Word16 *Q_shb_spch, + Word32 realBuffer[CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], /* i : real buffer Q - q_reImbuffer */ + Word32 imagBuffer[CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], /* i : imag buffer Q - q_reImbuffer */ + Word16 q_reImBuffer, /* i : scale data of real and imag CLDFB buffers */ + CPE_ENC_HANDLE hCPE /* i/o: CPE encoder structure */ +) +{ + Word16 Sample_Delay_SWB_BWE, inner_frame, delay; + TD_BWE_ENC_HANDLE hBWE_TD; + FD_BWE_ENC_HANDLE hBWE_FD; + Word32 inner_Fs, input_Fs; + Word16 old_input_fx[NS2SA( 48000, DELAY_FD_BWE_ENC_NS + DELAY_FIR_RESAMPL_NS ) + L_FRAME48k]; // fixed counterpart + Word32 old_input_fx_32[NS2SA( 48000, DELAY_FD_BWE_ENC_NS + DELAY_FIR_RESAMPL_NS ) + L_FRAME48k]; // fixed counterpart + Word16 spchTmp[L_FRAME32k], spchTmp2[L_FRAME32k]; + Word16 i, j, L_resamp; + Word16 startB, endB; + Word32 *realBufferFlipped[CLDFB_NO_COL_MAX]; + Word32 *imagBufferFlipped[CLDFB_NO_COL_MAX]; + Word32 realBufferTmp[CLDFB_NO_COL_MAX][20]; + Word32 imagBufferTmp[CLDFB_NO_COL_MAX][20]; + Word32 shb_speech_fx_32[L_FRAME16k]; + Word16 ts, nB, uB; + Word32 v, t, regression; + Word16 t_16; + const Word32 *thr, *regV; + Word32 lbEner; + Word16 exp_lbEner = 0; + Word16 Sample_Delay_SWB_BWE32k, lMemRecalc32k, dft_ovl32k; + Word32 one_by_50_Q31 = 42949673; + + lMemRecalc32k = NS2SA( 32000, L_MEM_RECALC_NS ); + move16(); // exp_lbEner + move16(); // lMemRecalc32k + move32(); // one_by_50_Q31 + + /* initialization */ + hBWE_TD = st->hBWE_TD; + hBWE_FD = st->hBWE_FD; + input_Fs = st->input_Fs; + + FOR( j = 0; j < CLDFB_NO_COL_MAX; j++ ) + { + set32_fx( realBufferTmp[j], 0, 20 ); + set32_fx( imagBufferTmp[j], 0, 20 ); + realBufferFlipped[j] = realBufferTmp[j]; + imagBufferFlipped[j] = imagBufferTmp[j]; + } + + set16_fx( old_input_fx, 0, NS2SA( 48000, DELAY_FD_BWE_ENC_12k8_NS + DELAY_FIR_RESAMPL_NS ) + L_FRAME48k ); + + IF( EQ_32( st->input_Fs, 32000 ) ) + { + IF( st->element_mode > EVS_MONO ) + { + Sample_Delay_SWB_BWE = NS2SA( 32000, DELAY_FD_BWE_ENC_12k8_NS ); + IF( EQ_16( st->L_frame, L_FRAME16k ) ) + { + Sample_Delay_SWB_BWE = NS2SA( 32000, DELAY_FD_BWE_ENC_16k_NS ); + } + + Copy( st->input_fx - Sample_Delay_SWB_BWE, hBWE_FD->old_input_fx, Sample_Delay_SWB_BWE ); + Copy( st->input_fx - L_FRAME32k, hBWE_FD->old_fdbwe_speech_fx, L_FRAME32k ); + + test(); + test(); + IF( EQ_16( st->element_mode, IVAS_CPE_TD ) && GE_16( st->bwidth, SWB ) ) + { + Copy( st->input_fx - hCPE->hStereoTCA->lMemRecalc, hBWE_FD->L_old_wtda_swb_fx + L_FRAME32k - sub( hCPE->hStereoTCA->lMemRecalc, Sample_Delay_SWB_BWE ), sub( hCPE->hStereoTCA->lMemRecalc, Sample_Delay_SWB_BWE ) ); + } + ELSE IF( EQ_16( st->element_mode, IVAS_CPE_DFT ) && GE_16( st->bwidth, SWB ) ) + { + Copy( st->input_fx - hCPE->hStereoDft->dft_ovl, hBWE_FD->L_old_wtda_swb_fx + L_FRAME32k - sub( hCPE->hStereoDft->dft_ovl, Sample_Delay_SWB_BWE ), sub( hCPE->hStereoDft->dft_ovl, Sample_Delay_SWB_BWE ) ); + } + } + + Copy( st->input_fx, new_swb_speech, L_FRAME32k ); + + test(); + test(); + IF( NE_16( st->last_extl, SWB_BWE ) && NE_16( st->last_extl, FB_BWE ) && NE_16( st->extl, SWB_BWE_HIGHRATE ) ) + { + Sample_Delay_SWB_BWE = NS2SA( 32000, DELAY_FD_BWE_ENC_12k8_NS + DELAY_FIR_RESAMPL_NS ); + test(); + IF( st->element_mode > EVS_MONO && EQ_16( st->L_frame, L_FRAME16k ) ) + { + Sample_Delay_SWB_BWE = NS2SA( 32000, DELAY_FD_BWE_ENC_16k_NS + DELAY_FIR_RESAMPL_NS ); + } + IF( st->element_mode > EVS_MONO ) + { + Sample_Delay_SWB_BWE = sub( Sample_Delay_SWB_BWE, NS2SA( 32000, DELAY_FIR_RESAMPL_NS ) ); + } + + Copy( hBWE_FD->old_fdbwe_speech_fx, &old_input_fx[Sample_Delay_SWB_BWE], L_FRAME32k ); + + set16_fx( old_input_fx, 0, Sample_Delay_SWB_BWE ); + Copy( hBWE_FD->old_fdbwe_speech_fx + L_FRAME32k - Sample_Delay_SWB_BWE, hBWE_FD->old_input_fx, Sample_Delay_SWB_BWE ); + IF( NE_16( st->extl, WB_BWE ) ) + { + Copy( old_input_fx, hBWE_FD->L_old_wtda_swb_fx, L_FRAME32k ); + } + } + + test(); + IF( NE_16( st->extl, SWB_BWE ) && NE_16( st->extl, FB_BWE ) ) + { + Copy( st->input_fx, hBWE_FD->old_fdbwe_speech_fx, L_FRAME32k ); + } + } + ELSE /* 48 kHz */ + { + + Sample_Delay_SWB_BWE32k = NS2SA( 32000, DELAY_FD_BWE_ENC_12k8_NS ); + move16(); + Sample_Delay_SWB_BWE = NS2SA( 48000, DELAY_FD_BWE_ENC_12k8_NS ); + move16(); + IF( EQ_16( st->L_frame, L_FRAME16k ) ) + { + Sample_Delay_SWB_BWE32k = NS2SA( 32000, DELAY_FD_BWE_ENC_16k_NS ); + move16(); + Sample_Delay_SWB_BWE = NS2SA( 48000, DELAY_FD_BWE_ENC_16k_NS ); + move16(); + } + + dft_ovl32k = 0; + move16(); + IF( EQ_16( st->element_mode, IVAS_CPE_DFT ) ) + { + dft_ovl32k = (Word16) ( STEREO_DFT_OVL_MAX * 32000 / 48000 ); + move16(); + } + + IF( EQ_16( st->codec_mode, MODE1 ) ) + { + IF( st->element_mode > EVS_MONO ) + { + + IF( EQ_16( st->element_mode, IVAS_CPE_TD ) ) + { + } + ELSE IF( EQ_16( st->bwidth, FB ) ) + { + Copy( st->input_fx - Sample_Delay_SWB_BWE, hBWE_FD->old_input_fx, Sample_Delay_SWB_BWE ); + } + + Copy( st->input_fx - L_FRAME48k, hBWE_FD->old_fdbwe_speech_fx, L_FRAME48k ); + + test(); + test(); + IF( EQ_16( st->element_mode, IVAS_CPE_TD ) && GE_16( st->bwidth, SWB ) ) + { + IF( EQ_16( st->bwidth, SWB ) ) + { + /* buffers hBWE_FD->old_input[] and hBWE_FD->old_wtda_swb[] need to be at 32 kHz (inner) sampling rate */ + + decimate_2_over_3_allpass_fx( st->input_fx - hCPE->hStereoTCA->lMemRecalc, hCPE->hStereoTCA->lMemRecalc, spchTmp, hBWE_TD->dec_2_over_3_mem_fx, + allpass_poles_3_ov_2, decimate_3_ov_2_lowpass_num_fx, decimate_3_ov_2_lowpass_den_fx, hBWE_TD->dec_2_over_3_mem_lp_fx ); + + Copy( spchTmp, hBWE_FD->L_old_wtda_swb_fx + L_FRAME32k - sub( lMemRecalc32k, Sample_Delay_SWB_BWE32k ), sub( lMemRecalc32k, Sample_Delay_SWB_BWE32k ) ); + Copy( spchTmp + lMemRecalc32k - Sample_Delay_SWB_BWE32k, hBWE_FD->old_input_fx, Sample_Delay_SWB_BWE32k ); + } + ELSE /* FB_BWE */ + { + Copy( st->input_fx - hCPE->hStereoTCA->lMemRecalc, hBWE_FD->L_old_wtda_swb_fx + L_FRAME48k - sub( hCPE->hStereoTCA->lMemRecalc, Sample_Delay_SWB_BWE ), sub( hCPE->hStereoTCA->lMemRecalc, Sample_Delay_SWB_BWE ) ); + Copy( st->input_fx - Sample_Delay_SWB_BWE, hBWE_FD->old_input_fx, Sample_Delay_SWB_BWE ); + } + } + ELSE IF( EQ_16( st->element_mode, IVAS_CPE_DFT ) && GE_16( st->bwidth, SWB ) ) + { + IF( EQ_16( st->bwidth, SWB ) ) + { + lerp( st->input_fx - hCPE->hStereoDft->dft_ovl, spchTmp, dft_ovl32k - Sample_Delay_SWB_BWE32k, hCPE->hStereoDft->dft_ovl - Sample_Delay_SWB_BWE ); + + Copy( spchTmp, hBWE_FD->L_old_wtda_swb_fx + L_FRAME32k - ( dft_ovl32k - Sample_Delay_SWB_BWE32k ), dft_ovl32k - Sample_Delay_SWB_BWE32k ); + } + ELSE + { + Copy( st->input_fx - hCPE->hStereoDft->dft_ovl, hBWE_FD->L_old_wtda_swb_fx + L_FRAME48k - ( hCPE->hStereoDft->dft_ovl - Sample_Delay_SWB_BWE ), hCPE->hStereoDft->dft_ovl - Sample_Delay_SWB_BWE ); + } + } + } + + test(); + test(); + test(); + test(); + IF( ( NE_16( st->extl, SWB_BWE ) && NE_16( st->extl, FB_BWE ) && ( st->core == ACELP_CORE ) ) || ( EQ_16( st->element_mode, IVAS_CPE_DFT ) && ( st->core != ACELP_CORE ) ) /*resampling not needed for MDCT cores*/ ) + { + /* move the resampling out of the TDBWE path as new_swb_speech is not needed for TDBWE. */ + Copy( st->input_fx, hBWE_FD->old_fdbwe_speech_fx, L_FRAME48k ); + } + ELSE + { + test(); + IF( NE_16( st->last_extl, SWB_BWE ) && NE_16( st->last_extl, FB_BWE ) ) + { + /* resample 48 kHz to 32kHz */ + IF( EQ_16( st->last_bwidth, FB ) ) + { + inner_frame = L_FRAME48k; + move16(); + inner_Fs = 48000; + move32(); + Copy( hBWE_FD->old_fdbwe_speech_fx, new_swb_speech, L_FRAME48k ); + } + ELSE + { + inner_frame = L_FRAME32k; + move16(); + inner_Fs = 32000; + move32(); + + IF( NE_16( st->element_mode, IVAS_CPE_DFT ) ) + { + decimate_2_over_3_allpass_fx( hBWE_FD->old_fdbwe_speech_fx, L_FRAME48k, new_swb_speech, hBWE_TD->dec_2_over_3_mem_fx, allpass_poles_3_ov_2, decimate_3_ov_2_lowpass_num_fx, decimate_3_ov_2_lowpass_den_fx, hBWE_TD->dec_2_over_3_mem_lp_fx ); + } + ELSE + { + lerp( hBWE_FD->old_fdbwe_speech_fx, new_swb_speech, inner_frame, L_FRAME48k ); + } + + test(); + IF( EQ_16( st->element_mode, IVAS_CPE_DFT ) && st->idchan == 0 ) + { + FOR( i = 0; i < STEREO_DFT_OVL_32k; i++ ) + { + hCPE->hStereoDft->output_mem_dmx_32k_fx[i] = L_shr( Mpy_32_16_1( hCPE->hStereoDft->win_32k_fx[STEREO_DFT_OVL_32k - 1 - i], new_swb_speech[( ( inner_frame + i ) - STEREO_DFT_OVL_32k )] ), 1 ); // Q15 + move32(); + } + } + } + + Sample_Delay_SWB_BWE = NS2SA_FX2( inner_Fs, DELAY_FD_BWE_ENC_12k8_NS + DELAY_FIR_RESAMPL_NS ); + move16(); + test(); + IF( st->element_mode > EVS_MONO && EQ_16( st->L_frame, L_FRAME16k ) ) + { + Sample_Delay_SWB_BWE = NS2SA_FX2( inner_Fs, DELAY_FD_BWE_ENC_16k_NS + DELAY_FIR_RESAMPL_NS ); + move16(); + } + IF( st->element_mode > EVS_MONO ) + { + Sample_Delay_SWB_BWE = sub( Sample_Delay_SWB_BWE, NS2SA_FX2( inner_Fs, DELAY_FIR_RESAMPL_NS ) ); + } + + Copy( new_swb_speech, &old_input_fx[Sample_Delay_SWB_BWE], inner_frame ); + set16_fx( old_input_fx, 0, Sample_Delay_SWB_BWE ); + Copy( new_swb_speech + inner_frame - Sample_Delay_SWB_BWE, hBWE_FD->old_input_fx, Sample_Delay_SWB_BWE ); + Copy( old_input_fx, hBWE_FD->L_old_wtda_swb_fx, inner_frame ); + } + + /* resample 48 kHz to 32kHz */ + IF( EQ_16( st->bwidth, FB ) ) + { + Copy( st->input_fx, new_swb_speech, L_FRAME48k ); + } + ELSE + { + IF( EQ_16( st->element_mode, IVAS_CPE_TD ) ) + { + Word16 dec_2_over_3_mem_tmp[L_FILT_2OVER3], dec_2_over_3_mem_lp_tmp[L_FILT_2OVER3_LP]; + + decimate_2_over_3_allpass_fx( st->input_fx, L_FRAME48k - hCPE->hStereoTCA->lMemRecalc, new_swb_speech, hBWE_TD->dec_2_over_3_mem_fx, allpass_poles_3_ov_2, decimate_3_ov_2_lowpass_num_fx, decimate_3_ov_2_lowpass_den_fx, hBWE_TD->dec_2_over_3_mem_lp_fx ); + + Copy( hBWE_TD->dec_2_over_3_mem_fx, dec_2_over_3_mem_tmp, L_FILT_2OVER3 ); + Copy( hBWE_TD->dec_2_over_3_mem_lp_fx, dec_2_over_3_mem_lp_tmp, L_FILT_2OVER3_LP ); + + decimate_2_over_3_allpass_fx( st->input_fx + L_FRAME48k - hCPE->hStereoTCA->lMemRecalc, hCPE->hStereoTCA->lMemRecalc, new_swb_speech + L_FRAME32k - lMemRecalc32k, dec_2_over_3_mem_tmp, allpass_poles_3_ov_2, decimate_3_ov_2_lowpass_num_fx, decimate_3_ov_2_lowpass_den_fx, dec_2_over_3_mem_lp_tmp ); + } + ELSE IF( NE_16( st->element_mode, IVAS_CPE_DFT ) ) + { + decimate_2_over_3_allpass_fx( st->input_fx, L_FRAME48k, new_swb_speech, hBWE_TD->dec_2_over_3_mem_fx, allpass_poles_3_ov_2, decimate_3_ov_2_lowpass_num_fx, decimate_3_ov_2_lowpass_den_fx, hBWE_TD->dec_2_over_3_mem_lp_fx ); + } + ELSE /* IVAS_CPE_DFT */ + { + Word16 out_start_ind, out_end_ind; + stereo_dft_enc_synthesize_fx( hCPE->hStereoDft, new_swb_speech_fx, &out_start_ind, &out_end_ind, st->idchan, input_Fs, 32000, 0, NULL ); + Copy_Scale_sig32_16( new_swb_speech_fx - STEREO_DFT_OVL_MAX, new_swb_speech - STEREO_DFT_OVL_MAX, L_FRAME48k + STEREO_DFT_OVL_MAX, add( q_reImBuffer, 1 ) ); // Q0 + Copy( new_swb_speech - Sample_Delay_SWB_BWE32k, hBWE_FD->old_input_fx, Sample_Delay_SWB_BWE32k ); // Q0 + } + } + } + } + ELSE + { + /* resample 48 kHz to 32kHz */ + IF( EQ_16( st->bwidth, FB ) ) + { + Copy( st->input_fx, new_swb_speech, L_FRAME48k ); + } + ELSE + { + decimate_2_over_3_allpass_fx( st->input_fx, L_FRAME48k, new_swb_speech, hBWE_TD->dec_2_over_3_mem_fx, allpass_poles_3_ov_2, decimate_3_ov_2_lowpass_num_fx, decimate_3_ov_2_lowpass_den_fx, hBWE_TD->dec_2_over_3_mem_lp_fx ); + } + } + } + + test(); + test(); + test(); + test(); + test(); + test(); + IF( ( ( st->core == ACELP_CORE ) && NE_16( st->extl, SWB_BWE_HIGHRATE ) && NE_16( st->extl, FB_BWE_HIGHRATE ) ) || + ( ( EQ_32( st->total_brate, ACELP_9k60 ) || st->rf_mode ) && EQ_16( st->bwidth, SWB ) && ( st->element_mode == EVS_MONO ) ) ) + { + Word32 CldfbHB_fx = 0; // fixed counterpart + Word16 CldfbHB_fx_e = 0; // fixed counterpart +#ifdef BASOP_NOGLOB_DECLARE_LOCAL + Flag Overflow = 0; + move16(); +#endif + Word16 realQ_neg1, imagQ_neg1, exp = 0, Cldfbtemp1; + move32(); + move16(); + move16(); + + IF( EQ_16( st->element_mode, IVAS_CPE_DFT ) ) + { + Word16 out_start_ind, out_end_ind; + Word16 exp_icbweRefEner_fx; + Copy_Scale_sig_16_32_DEPREC( (const Word16 *) &old_input_fx[0], &old_input_fx_32[0], NS2SA( 48000, DELAY_FD_BWE_ENC_NS + DELAY_FIR_RESAMPL_NS ) + L_FRAME48k, Q15 ); // Q15 + CldfbHB_fx = stereo_dft_enc_synthesize_fx( hCPE->hStereoDft, old_input_fx_32 + STEREO_DFT_OVL_16k, &out_start_ind, &out_end_ind, st->idchan, input_Fs, 16000, st->L_frame, &CldfbHB_fx_e ); + Copy_Scale_sig_32_16( (const Word32 *) &old_input_fx_32[0], &old_input_fx[0], NS2SA( 48000, DELAY_FD_BWE_ENC_NS + DELAY_FIR_RESAMPL_NS ) + L_FRAME48k, -Q15 ); // Q0 + + /* delay corresponding to CLDFB delay */ + Copy( old_input_fx + STEREO_DFT_OVL_16k - 20, shb_speech, L_FRAME16k ); + Copy( old_input_fx, hBWE_TD->old_speech_shb_fx + L_LOOK_16k + L_SUBFR16k - ( STEREO_DFT_OVL_16k - 20 ), STEREO_DFT_OVL_16k - 20 ); + Copy( old_input_fx, hCPE->hStereoICBWE->mem_shb_speech_ref_fx, STEREO_DFT_OVL_16k - 20 ); // Q0 + hCPE->hStereoICBWE->mem_shb_speech_ref_e = 15; + move16(); + + IF( LE_32( CldfbHB_fx, 0 ) ) + { + CldfbHB_fx = EPSILON_FX; + move32(); + } + CldfbHB_fx = L_shl( CldfbHB_fx, exp ); /* CldfbHB_ener = CldfbHB_fl*2^(exp) */ + Cldfbtemp1 = Log2_norm_lc( CldfbHB_fx ); /* Log2_norm_lc(t) = 2^15*(log2(t/2^30)) */ + Cldfbtemp1 = sub( shr( Cldfbtemp1, 6 ), shl( add( sub( Q31 - Q30, CldfbHB_fx_e ), exp ), 9 ) ); + CldfbHB_fx = L_mult( Cldfbtemp1, 9864 ); /* Q9 + Q15 + Q1 = Q25 */ + CldfbHB_fx = Mpy_32_16_1( L_sub( CldfbHB_fx, 1 << Q25 ), 11611 /* 0.1 * 0.221462 in Q19 */ ); + /* Resulting Q = Q25 + Q19 - Q15 = Q29 */ + hBWE_TD->cldfbHBLT = mac_r( CldfbHB_fx, 29491 /*0.9 Q15*/, hBWE_TD->cldfbHBLT ); /* cldfbHBLT is in Q13 */ + move16(); + + exp_lbEner = hCPE->hStereoDft->lbEner_fx_e; + move32(); + lbEner = Mpy_32_16_1( Sqrt32( hCPE->hStereoDft->lbEner_fx, &exp_lbEner ), 1638 /* 0.05 in Q15 */ ); + exp_icbweRefEner_fx = hCPE->hStereoDft->icbweRefEner_fx_e; + move16(); + hCPE->hStereoICBWE->icbweRefEner_fx = Mpy_32_16_1( Sqrt32( hCPE->hStereoDft->icbweRefEner_fx, &exp_icbweRefEner_fx ), 1638 /* 0.05 in Q15 */ ); + move32(); + hCPE->hStereoICBWE->icbweRefEner_fx_e = exp_icbweRefEner_fx; + move16(); + // lbEner = 0.05f * (float) sqrt( hCPE->hStereoDft->lbEner ); + thr = icbwe_thr_DFT_fx; + regV = icbwe_regressionValuesDFT_fx; + } + ELSE + { + IF( EQ_16( st->L_frame, L_FRAME ) ) + { + startB = 34; + move16(); + endB = 14; + move16(); + FOR( ts = 0; ts < CLDFB_NO_COL_MAX; ts++ ) + { + uB = 0; + move16(); + FOR( nB = startB; nB > endB; nB-- ) + { + realBufferFlipped[ts][uB] = realBuffer[ts][nB]; + move32(); + if ( s_and( ts, 1 ) != 0 ) + { + realBufferFlipped[ts][uB] = L_negate( realBufferFlipped[ts][uB] ); + move32(); + } + imagBufferFlipped[ts][uB] = imagBuffer[ts][nB]; + move32(); + if ( s_and( ts, 1 ) == 0 ) + { + imagBufferFlipped[ts][uB] = L_negate( imagBufferFlipped[ts][uB] ); + move32(); + } + uB = add( uB, 1 ); /* uB ++ */ + } + } + } + ELSE + { + startB = 39; + move16(); + endB = 19; + move16(); + FOR( ts = 0; ts < CLDFB_NO_COL_MAX; ts++ ) + { + uB = 0; + move16(); + FOR( nB = startB; nB > endB; nB-- ) + { + realBufferFlipped[ts][uB] = L_negate( realBuffer[ts][nB] ); + move32(); + imagBufferFlipped[ts][uB] = imagBuffer[ts][nB]; + move32(); + uB = add( uB, 1 ); /* uB ++ */ + } + } + } + + FOR( nB = 0; nB < 10; nB++ ) + { + FOR( ts = 0; ts < CLDFB_NO_COL_MAX; ts++ ) + { + realQ_neg1 = extract_l( L_shr( realBufferFlipped[ts][nB], 16 ) ); + imagQ_neg1 = extract_l( L_shr( imagBufferFlipped[ts][nB], 16 ) ); /* Q(-1), headroom needed */ + + CldfbHB_fx = L_mac0_o( CldfbHB_fx, realQ_neg1, realQ_neg1, &Overflow ); + CldfbHB_fx = L_mac0_o( CldfbHB_fx, imagQ_neg1, imagQ_neg1, &Overflow ); /* Q(-2) */ + } + } + CldfbHB_fx_e = sub( Q31, shl( sub( q_reImBuffer, Q16 ), 1 ) ); + exp = norm_l( CldfbHB_fx ); + CldfbHB_fx = L_shl( CldfbHB_fx, exp ); /* CldfbHB_ener = CldfbHB_fl*2^(exp) */ + Cldfbtemp1 = Log2_norm_lc( CldfbHB_fx ); /* Log2_norm_lc(t) = 2^15*(log2(t/2^30)) */ + Cldfbtemp1 = sub( shr( Cldfbtemp1, 6 ), shl( add( sub( Q31 - Q30, CldfbHB_fx_e ), exp ), 9 ) ); + CldfbHB_fx = L_mult( Cldfbtemp1, 9864 ); /* Q9 + Q15 + Q1 = Q25 */ + CldfbHB_fx = Mpy_32_16_1( L_sub( CldfbHB_fx, 1 << Q25 ), 11611 /* 0.1 * 0.221462 in Q19 */ ); + /* Resulting Q = Q25 + Q19 - Q15 = Q29 */ + hBWE_TD->cldfbHBLT = mac_r( CldfbHB_fx, 29491 /*0.9 Q15*/, hBWE_TD->cldfbHBLT ); /* cldfbHBLT is in Q13 */ + move32(); + + IF( CldfbHB_fx == 0 ) + { + CldfbHB_fx = EPSILLON_FX; + move32(); + } + + test(); + IF( GE_16( st->element_mode, IVAS_CPE_DFT ) && hCPE->hStereoICBWE != NULL ) + { + Word32 icbweRefEner_fx = EPSILON_FX; + Word16 exp_icbweRefEner_fx = 0; + + move32(); + move16(); + FOR( nB = 20; nB < 40; nB++ ) + { + FOR( ts = 0; ts < CLDFB_NO_COL_MAX; ts++ ) + { + realQ_neg1 = extract_l( L_shr( realBuffer[ts][nB], 16 ) ); + imagQ_neg1 = extract_l( L_shr( imagBuffer[ts][nB], 16 ) ); /* Q(-1), headroom needed */ + icbweRefEner_fx = L_mac0_o( icbweRefEner_fx, realQ_neg1, realQ_neg1, &Overflow ); + icbweRefEner_fx = L_mac0_o( icbweRefEner_fx, imagQ_neg1, imagQ_neg1, &Overflow ); /* Q(-2) */ + } + } + exp_icbweRefEner_fx = sub( Q31, shl( sub( q_reImBuffer, Q16 ), 1 ) ); + hCPE->hStereoICBWE->icbweRefEner_fx = Mpy_32_16_1( Sqrt32( icbweRefEner_fx, &exp_icbweRefEner_fx ), 1638 /* 0.05 in Q15 */ ); + move32(); + hCPE->hStereoICBWE->icbweRefEner_fx_e = exp_icbweRefEner_fx; + move16(); + } + + lbEner = EPSILON_FX; + move32(); + FOR( nB = 0; nB < 20; nB++ ) + { + FOR( ts = 0; ts < CLDFB_NO_COL_MAX; ts++ ) + { + realQ_neg1 = extract_l( L_shr( realBuffer[ts][nB], 16 ) ); + imagQ_neg1 = extract_l( L_shr( imagBuffer[ts][nB], 16 ) ); /* Q(-1), headroom needed */ + + lbEner = L_mac0_o( lbEner, realQ_neg1, realQ_neg1, &Overflow ); + lbEner = L_mac0_o( lbEner, imagQ_neg1, imagQ_neg1, &Overflow ); /* Q(-2) */ + } + } + exp_lbEner = sub( Q31, shl( sub( q_reImBuffer, Q16 ), 1 ) ); + lbEner = Mpy_32_16_1( Sqrt32( lbEner, &exp_lbEner ), 1638 /* 0.05 in Q15 */ ); + thr = icbwe_thr_TDM_fx; + regV = icbwe_regressionValuesTDM_fx; + + cldfbSynthesis_ivas_fx( realBufferFlipped, imagBufferFlipped, shb_speech_fx_32, -1, st->cldfbSynTd ); + Copy_Scale_sig_32_16( shb_speech_fx_32, shb_speech, L_FRAME16k, negate( sub( q_reImBuffer, 1 ) ) ); + *Q_shb_spch = 0; + move16(); + } + + IF( GE_16( st->element_mode, IVAS_CPE_DFT ) && hCPE->hStereoICBWE != NULL ) + { + Word16 exp_t; + hCPE->hStereoICBWE->MSFlag = 0; /* Init the multi-source flag */ + move16(); + v = Mpy_32_16_1( L_add( L_deposit_l( st->voicing_fx[0] ), L_add( L_deposit_l( st->voicing_fx[1] ), L_deposit_l( st->voicing_fx[2] ) ) ), 10923 /* 0.33333 in Q15 */ ); + + // t = log10f( ( hCPE->hStereoICBWE->icbweRefEner + 1e-6f ) / ( lbEner + 1e-6f ) ); + t = L_deposit_h( BASOP_Util_Divide3232_Scale( L_add( hCPE->hStereoICBWE->icbweRefEner_fx, EPSILON_FX ), L_add( lbEner, EPSILON_FX ), &exp_t ) ); + exp_t = add( exp_t, sub( hCPE->hStereoICBWE->icbweRefEner_fx_e, exp_lbEner ) ); + exp = norm_l( t ); + t = L_shl( t, exp ); + t_16 = Log2_norm_lc( t ); /* Log2_norm_lc(t) = 2^15*(log2(t/2^30)) */ + t_16 = sub( shr( t_16, 6 ), shl( add( sub( Q31 - Q30, exp_t ), exp ), 9 ) ); + t = L_mult( t_16, 9864 ); /* Q9 + Q15 + Q1 = Q25 */ + /* Three Level Decision Tree to calculate a regression value first */ + IF( LT_32( t, thr[0] ) ) /* level 1 */ + { + IF( LT_32( t, thr[1] ) ) /* level 2 */ + { + IF( LT_32( v, thr[3] ) ) + { + regression = regV[0]; /* level 3 */ + move32(); + } + ELSE + { + regression = regV[1]; + move32(); + } + } + ELSE + { + IF( LT_32( v, thr[4] ) ) + { + regression = regV[2]; /* level 3 */ + move32(); + } + ELSE + { + regression = regV[3]; + move32(); + } + } + } + ELSE + { + IF( LT_32( t, thr[2] ) ) /* level 2 */ + { + IF( LT_32( v, thr[5] ) ) + { + regression = regV[4]; /* level 3 */ + move32(); + } + ELSE + { + regression = regV[5]; + move32(); + } + } + ELSE + { + IF( LT_32( v, thr[6] ) ) + { + regression = regV[6]; /* level 3 */ + move32(); + } + ELSE + { + regression = regV[7]; + move32(); + } + } + } + + test(); + test(); + /* Convert the regression to a hard decision (classification) */ + IF( GT_32( regression, 1696512081 /* 0.79f in Q31*/ ) && !( LT_16( st->bwidth, SWB ) || hCPE->hCoreCoder[0]->vad_flag == 0 ) ) + { + hCPE->hStereoICBWE->MSFlag = 1; + move16(); + } + } + + test(); + test(); + IF( NE_16( st->extl, WB_TBE ) && NE_16( st->extl, SWB_TBE ) && NE_16( st->extl, FB_TBE ) ) + { + /* Update the previous superwideband speech buffer in case of a SWB_BWE frame - this code is in swb_tbe_enc */ + delay = L_LOOK_16k + L_SUBFR16k; + move16(); + Copy( shb_speech + sub( L_FRAME16k, delay ), hBWE_TD->old_speech_shb_fx, delay ); + } + } + ELSE + { + test(); + test(); + IF( ( EQ_16( st->bwidth, FB ) || st->core == ACELP_CORE ) && ( st->element_mode == EVS_MONO ) ) + { + InitSWBencBufferStates_fx( st->hBWE_TD, shb_speech ); + } + ELSE + { + IF( EQ_16( st->element_mode, IVAS_CPE_DFT ) ) + { + IF( EQ_16( st->L_frame, L_FRAME ) ) + { + L_resamp = 560; /* 6.4 kHz core -> 6 - 14 kHz SHB target. 20 ms is 560 samples in 28 kHz sample rate */ + move16(); + } + ELSE + { + L_resamp = 620; /* 8 kHz core -> 7.5 - 15.5 kHz SHB target. 20 ms is 620 samples in 31 kHz sample rate */ + move16(); + } + + /* Dirty downsampling to match Nyquist to upper frequency limit of target */ + lerp( st->input_fx, new_swb_speech, L_resamp, extract_l( Mpy_32_32( input_Fs, one_by_50_Q31 ) ) ); + + /* flip the spectrum */ + Copy( new_swb_speech, spchTmp, L_resamp ); + FOR( i = 0; i < L_resamp; i = i + 2 ) + { + spchTmp[i] = negate( spchTmp[i] ); + move16(); + } + + /* Dirty upsampling to match Nyquist/2 to lower frequency limit of target (reversed spectrum)*/ + lerp( spchTmp, spchTmp2, L_FRAME32k, L_resamp ); + Copy( spchTmp2, spchTmp, L_FRAME32k ); + } + ELSE + { + /* flip the spectrum */ + Copy( new_swb_speech, spchTmp, L_FRAME32k ); + + FOR( i = 0; i < L_FRAME32k; i = i + 2 ) + { + spchTmp[i] = negate( spchTmp[i] ); + move16(); + } + } + + Decimate_allpass_steep_fx( spchTmp, hBWE_TD->state_ana_filt_shb_fx, L_FRAME32k, shb_speech ); + + Copy( shb_speech + L_FRAME16k - ( L_LOOK_16k + L_SUBFR16k ), hBWE_TD->old_speech_shb_fx, L_LOOK_16k + L_SUBFR16k ); + + /*Compute the past overlap for potential next iDFTs SHB*/ + IF( EQ_16( st->element_mode, IVAS_CPE_DFT ) ) + { + FOR( i = 0; i < STEREO_DFT_OVL_16k; i++ ) + { + hCPE->hStereoDft->output_mem_dmx_16k_shb_fx[i] = L_mult0( shb_speech[20 + i], mult_r( hCPE->hStereoDft->win_ana_16k_fx[STEREO_DFT_OVL_16k - 1 - i], hCPE->hStereoDft->win_ana_16k_fx[STEREO_DFT_OVL_16k - 1 - i] ) ); // Q15 + move32(); + } + } + } + + IF( NE_16( st->element_mode, IVAS_CPE_DFT ) ) + { + /* Reset CLDFB synthesis buffer */ + set32_fx( st->cldfbSynTd->cldfb_state_fx, 0, st->cldfbSynTd->p_filter_length ); + } + ELSE + { + hCPE->hStereoDft->flip_sign = negate( hCPE->hStereoDft->flip_sign ); /* Make sure sign is updated even if DFT SHB target is not generated */ + move16(); + } + } + + /* Memory reset to compensate for 0.9375 ms offset when transitioning from IO to SWB */ + /* When switching from n >1 to n = 1, we keep the enc/dec delay as 8.75/3.25 and below code not needed; + only when n = 1 start, it will be 9.6875/2.3125 in that case this reset is needed for IO->BWE.*/ + test(); + IF( EQ_16( st->last_extl, -1 ) && ( st->element_mode == EVS_MONO ) ) + { + delay = NS2SA_FX2( input_Fs, DELAY_FIR_RESAMPL_NS ); + move16(); + FOR( i = 0; i < delay; i++ ) + { + shb_speech[i] = mult_r( mult_r( i, 983 /*0.03f Q15*/ ), shb_speech[2 * delay - 1 - i] ); + move16(); } } diff --git a/lib_enc/swb_tbe_enc.c b/lib_enc/swb_tbe_enc.c deleted file mode 100644 index 018ac1f0e8199d87bc99f56c9a6f04c514463a29..0000000000000000000000000000000000000000 --- a/lib_enc/swb_tbe_enc.c +++ /dev/null @@ -1,46 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include -#include "cnst.h" -#include "prot.h" -#include "prot_fx.h" -#include "rom_com.h" -#include "rom_enc.h" -#include "wmc_auto.h" -#include "ivas_prot.h" diff --git a/lib_enc/swb_tbe_enc_fx.c b/lib_enc/swb_tbe_enc_fx.c index 3e8e7aac5c2a32f6e53bab6620196270c1bfdf7f..ba8ee5aa8741d9cd5a64d4d2ecccc3113ca32ef7 100644 --- a/lib_enc/swb_tbe_enc_fx.c +++ b/lib_enc/swb_tbe_enc_fx.c @@ -6,13 +6,10 @@ #include #include "options.h" #include "cnst.h" -//#include "prot_fx.h" #include "rom_com_fx.h" #include "rom_com.h" -#include "prot.h" /* Function prototypes */ #include "prot_fx.h" /* Function prototypes */ #include "prot_fx_enc.h" /* Function prototypes */ -#include "ivas_prot.h" /* Function prototypes */ #include "stl.h" #include "ivas_prot_fx.h" @@ -63,6 +60,16 @@ static void EstimateSHBFrameGain_fx( const Word16 length, const Word16 *subwin_shb, const Word16 n_subfr_saturation ); +static void EstimateSHBFrameGain_ivas_fx( const Word16 length, + const Word16 *oriSHB, + const Word16 Q_oriSHB, + const Word16 *synSHB, + const Word16 Q_synSHB, + Word16 *subgain, + Word32 *GainFrame, + const Word16 *win_shb, + const Word16 *subwin_shb, + const Word16 n_subfr_saturation ); static void EstimateSHBGainShape_fx( const Word16 length, const Word16 *oriSHB, @@ -132,8 +139,11 @@ void find_max_mem_enc( Word16 i; Word16 n_mem_32; Word16 max = 0; + move16(); Word32 Lmax = 0; + move32(); Word16 tempQ15, max2 = 0; + move16(); TD_BWE_ENC_HANDLE hBWE_TD = st_fx->hBWE_TD; /* old BWE exc max */ @@ -175,9 +185,13 @@ void find_max_mem_enc( /* for total_brate > 16.4kbps, use n_mem2; else account for the max2 for n_mem calculation */ *n_mem2 = norm_s( max2 ); + move16(); if ( max2 == 0 ) + { *n_mem2 = 15; - if ( LT_32( st_fx->total_brate, ACELP_24k40 ) ) + move16(); + } + IF( LT_32( st_fx->total_brate, ACELP_24k40 ) ) { max = s_max( max, max2 ); } @@ -202,9 +216,11 @@ void find_max_mem_enc( } /* estimate the norm for 16-bit memories */ *n_mem = norm_s( max ); + move16(); if ( max == 0 ) { *n_mem = 15; + move16(); } /* estimate the norm for 32-bit memories */ @@ -214,10 +230,12 @@ void find_max_mem_enc( if ( Lmax == 0 ) { n_mem_32 = 31; + move16(); } tempQ15 = sub( s_min( *n_mem, n_mem_32 ), 1 ); *n_mem = s_max( tempQ15, 0 ); + move16(); } @@ -587,9 +605,9 @@ void InitSWBencBuffer_ivas_fx( // TV2TV IVAS_CODE -> To be verify if it has to be moved to hBWE_TD - st_fx->prev_Q_bwe_exc = 31; + st_fx->prev_Q_bwe_exc = 15; move16(); - st_fx->prev_Q_bwe_syn = 31; + st_fx->prev_Q_bwe_syn = 15; move16(); set16_fx( st_fx->prev_lsp_wb_fx, 0, 6 ); set16_fx( st_fx->prev_lsp_wb_temp_fx, 0, 6 ); @@ -684,7 +702,7 @@ void wb_tbe_enc_fx( const Word16 voicing_fx[] /* i : OL maximum normalized correlation */ ) { - Word16 i, j, k; + Word16 i, j; Word16 hb_old_speech[( L_LOOK_12k8 + L_SUBFR + L_FRAME ) * 5 / 16]; Word16 bwe_exc_extended_16[L_FRAME32k + NL_BUFF_OFFSET]; @@ -696,6 +714,8 @@ void wb_tbe_enc_fx( Word16 lpc_wb[LPC_SHB_ORDER_WB + 1]; Word32 lpc_wb_32_fx[LPC_SHB_ORDER_WB + 1]; Word16 lsp_wb[LPC_SHB_ORDER_WB], weights_lsp[LPC_SHB_ORDER_WB] = { 32767, 32767 }; + move16(); + move16(); Word16 *hb_new_speech, *hb_frame /*, hb_speech[ L_FRAME16k ]*/; Word16 R_h[LPC_SHB_ORDER_WB + 2], R_l[LPC_SHB_ORDER_WB + 2]; Word16 Q_R; @@ -710,6 +730,7 @@ void wb_tbe_enc_fx( Word32 L_tmp, Lmax; Word16 tmp, exp, Q_out, sc; Word16 Q_ns = -1; + move16(); Word16 pitBufAvg_fx, voicingBufAvg_fx; Word16 vf_modified_fx[NB_SUBFR16k]; @@ -720,11 +741,13 @@ void wb_tbe_enc_fx( Word16 frac, exp1; Word16 uv_flag; Word16 dummy = 0; + move16(); Word16 avg_voice_fac; TD_BWE_ENC_HANDLE hBWE_TD = st_fx->hBWE_TD; RF_ENC_HANDLE hRF = st_fx->hRF; #ifdef BASOP_NOGLOB_DECLARE_LOCAL Flag Overflow = 0; + move16(); #endif /*Word16 att = 32767;*/ @@ -742,15 +765,13 @@ void wb_tbe_enc_fx( test(); test(); test(); - IF( ( NE_16( st_fx->last_extl, WB_TBE ) && NE_16( st_fx->last_extl, WB_BWE ) ) && ( EQ_16( st_fx->clas, UNVOICED_CLAS ) || ( LT_16( voicing_fx[0], 16384 ) && LT_16( voicing_fx[1], 16384 ) && LT_16( voicing_fx[2], 16384 ) ) ) && st_fx->igf == 0 ) + IF( ( NE_16( st_fx->last_extl, WB_TBE ) && NE_16( st_fx->last_extl, WB_BWE ) ) && ( st_fx->clas == UNVOICED_CLAS || ( LT_16( voicing_fx[0], 16384 ) && LT_16( voicing_fx[1], 16384 ) && LT_16( voicing_fx[2], 16384 ) ) ) && st_fx->igf == 0 ) { /* In case of unvoiced signals after switching cores, back-propagate the target signal */ Copy( hb_speech, hb_old_speech, WBTBE_LOOK_LSUFBR_5_OVER_16 ); i = WBTBE_LOOK_LSUFBR_5_OVER_16; move16(); - k = 0; - move16(); FOR( j = 0; j < L_SUBFR16k; j = j + 4 ) { @@ -758,7 +779,6 @@ void wb_tbe_enc_fx( hb_old_speech[i] = mac_r( L_tmp, hb_speech[j], ola_win_shb_switch_fold_fx[L_SUBFR16k - 4 - j] ); move16(); i--; - k++; } } @@ -961,6 +981,7 @@ void wb_tbe_enc_fx( } Q_bwe_exc = 31; + move16(); if ( Lmax != 0 ) { Q_bwe_exc = norm_l( Lmax ); @@ -970,7 +991,7 @@ void wb_tbe_enc_fx( find_max_mem_wb_enc( st_fx, &n_mem ); - if ( GT_16( sub( Q_bwe_exc, st_fx->prev_Q_bwe_exc ), n_mem ) ) + IF( GT_16( sub( Q_bwe_exc, st_fx->prev_Q_bwe_exc ), n_mem ) ) { Q_bwe_exc = add( st_fx->prev_Q_bwe_exc, n_mem ); } @@ -989,11 +1010,7 @@ void wb_tbe_enc_fx( IF( st_fx->element_mode > EVS_MONO ) { tmp = sub( shl( sub( st_fx->prev_Q_bwe_exc, 16 ), 1 ), 31 + 16 ); -#ifdef BASOP_NOGLOB prev_pow = L_shl_sat( 1407374848l /*0.00001f Q47*/, tmp ); /*Q(2*(st_fx->prev_Q_bwe_exc-16))*/ -#else - prev_pow = L_shl( 1407374848l /*0.00001f Q47*/, tmp ); /*Q(2*(st_fx->prev_Q_bwe_exc-16))*/ -#endif } FOR( i = 0; i < L_SHB_LAHEAD / 4; i++ ) { @@ -1007,6 +1024,7 @@ void wb_tbe_enc_fx( FOR( i = 0; i < L_FRAME32k; i++ ) { bwe_exc_extended_16[i + NL_BUFF_OFFSET] = round_fx( L_shl( bwe_exc_extended[i], sc ) ); + move16(); } Copy( bwe_exc_extended_16 + L_FRAME32k, hBWE_TD->old_bwe_exc_extended_fx, NL_BUFF_OFFSET ); @@ -1025,11 +1043,7 @@ void wb_tbe_enc_fx( IF( st_fx->element_mode > EVS_MONO ) { tmp = sub( shl( Q_bwe_exc_ext, 1 ), 31 + 16 ); -#ifdef BASOP_NOGLOB curr_pow = L_shl_sat( 1407374848l /*0.00001f Q47*/, tmp ); /*Q(2*(Q_bwe_exc_ext))*/ -#else - curr_pow = L_shl( 1407374848l /*0.00001f Q47*/, tmp ); /* 2*(Q_bwe_exc_ext) */ -#endif } FOR( i = 0; i < L_SHB_LAHEAD / 4; i++ ) { @@ -1046,18 +1060,15 @@ void wb_tbe_enc_fx( FOR( i = 0; i < L_SHB_LAHEAD / 4 - 1; i++ ) { - L_tmp = Mult_32_16( Lscale, shaped_wb_excitation[i] ); /* Q(16-exp+Q_bwe_exc_ext) */ -#ifdef BASOP_NOGLOB + L_tmp = Mult_32_16( Lscale, shaped_wb_excitation[i] ); /* Q(16-exp+Q_bwe_exc_ext) */ shaped_wb_excitation[i] = round_fx_sat( L_shl_sat( L_tmp, exp ) ); /* Q_bwe_exc_ext */ -#else - shaped_wb_excitation[i] = round_fx( L_shl( L_tmp, exp ) ); /* Q_bwe_exc_ext */ -#endif + move16(); } Lscale = root_a_fx( Lscale, 31 - exp, &exp ); L_tmp = Mult_32_16( Lscale, shaped_wb_excitation[L_SHB_LAHEAD / 4 - 1] ); /* Q(16-exp+Q_bwe_exc_ext) */ shaped_wb_excitation[L_SHB_LAHEAD / 4 - 1] = round_fx( L_shl( L_tmp, exp ) ); /* Q_bwe_exc_ext */ - + move16(); /* Update WB excitation */ Copy( shaped_wb_excitation + L_FRAME16k / 4, hBWE_TD->state_syn_shbexc_fx, L_SHB_LAHEAD / 4 ); @@ -1196,18 +1207,14 @@ void wb_tbe_enc_fx( exp = norm_s( voicingBufAvg_fx ); tmp = div_s( shl( 1, sub( 14, exp ) ), voicingBufAvg_fx ); /* (14-exp) */ L_tmp = L_mult( pitBufAvg_fx, tmp ); /* (21-exp) */ -#ifdef BASOP_NOGLOB L_tmp = L_shl_o( L_tmp, add( exp, 10 ), &Overflow ); tmp = round_fx_o( L_tmp, &Overflow ); /* Q15 */ -#else /* BASOP_NOGLOB */ - L_tmp = L_shl( L_tmp, add( exp, 10 ) ); - tmp = round_fx( L_tmp ); /* Q15 */ -#endif } tmp = s_max( s_min( tmp, 32767 ), 22938 ); /* Q15 */ GainFrame = Mult_32_16( GainFrame, tmp ); /* Q18 */ + test(); IF( LT_16( lsp_spacing_fx, 328 ) && lsp_spacing_fx ) { GainFrame = Mult_32_16( GainFrame, 21299 ); /* Q18 */ @@ -1246,6 +1253,7 @@ void wb_tbe_enc_fx( /* Adjust the subframe and frame gain of the synthesized SHB signal */ /* Scale the shaped excitation*/ + ScaleShapedSHB_fx( SHB_OVERLAP_LEN / 2, shaped_wb_excitation, hBWE_TD->syn_overlap_fx, GainShape, GainFrame, window_wb_fx, subwin_wb_fx, &Q_bwe_exc_ext, &dummy, dummy, dummy ); @@ -1293,6 +1301,7 @@ void wb_tbe_enc_ivas_fx( Word16 bwe_exc_extended_16[L_FRAME32k + NL_BUFF_OFFSET]; Word16 shaped_wb_excitation[( L_FRAME16k + L_SHB_LAHEAD ) / 4]; + Word16 shaped_wb_exc_scale[L_SHB_LAHEAD / 4]; Word16 exc4kWhtnd[L_FRAME16k / 4]; /*Word16 ana_align_delay = WBTBE_ANA_ALIGNDELAY; */ /* -L_SHB_LAHEAD/4 - 5 */ Word32 GainFrame; @@ -1300,19 +1309,19 @@ void wb_tbe_enc_ivas_fx( Word16 lpc_wb[LPC_SHB_ORDER_WB + 1]; Word32 lpc_wb_32_fx[LPC_SHB_ORDER_WB + 1]; Word16 lsp_wb[LPC_SHB_ORDER_WB], weights_lsp[LPC_SHB_ORDER_WB] = { 32767, 32767 }; + move16(); + move16(); Word16 *hb_new_speech, *hb_frame /*, hb_speech[ L_FRAME16k ]*/; Word16 R_h[LPC_SHB_ORDER_WB + 2], R_l[LPC_SHB_ORDER_WB + 2]; Word16 Q_R; Word32 LepsP[LPC_SHB_ORDER_WB + 1]; - move16(); - move16(); Word32 prev_pow, curr_pow, Lscale; /* Word16 scale; */ /*Word16 ramp_flag;*/ Word32 p2m_in, p2m_out; /*Word16 cnt, max =0;*/ - Word16 n_mem, Q_bwe_exc, Q_bwe_exc_ext, exp_out; /* Q_hb_frame; */ + Word16 n_mem, Q_bwe_exc, Q_bwe_exc_ext, exp_out, Q_cur_pow, Q_prev_pow; /* Q_hb_frame; */ Word32 L_tmp, Lmax; Word16 tmp, exp, Q_out, sc; Word16 Q_ns = -1; @@ -1331,12 +1340,12 @@ void wb_tbe_enc_ivas_fx( TD_BWE_ENC_HANDLE hBWE_TD = st_fx->hBWE_TD; #ifdef BASOP_NOGLOB_DECLARE_LOCAL Flag Overflow = 0; - move32(); + move16(); #endif move16(); /*Word16 att = 32767;*/ - + set16_fx( bwe_exc_extended_16, 0, L_FRAME32k + NL_BUFF_OFFSET ); hb_new_speech = hb_old_speech + WBTBE_LOOK_LSUFBR_5_OVER_16; hb_frame = hb_old_speech + WBTBE_LSUBFR_5_OVER_16 + WBTBE_ANA_ALIGNDELAY; @@ -1350,7 +1359,7 @@ void wb_tbe_enc_ivas_fx( test(); test(); test(); - IF( ( NE_16( st_fx->last_extl, WB_TBE ) && NE_16( st_fx->last_extl, WB_BWE ) ) && ( EQ_16( st_fx->clas, UNVOICED_CLAS ) || ( LT_16( st_fx->voicing_fx[0], 16384 ) && LT_16( st_fx->voicing_fx[1], 16384 ) && LT_16( st_fx->voicing_fx[2], 16384 ) ) ) && !st_fx->igf ) + IF( ( NE_16( st_fx->last_extl, WB_TBE ) && NE_16( st_fx->last_extl, WB_BWE ) ) && ( st_fx->clas == UNVOICED_CLAS || ( LT_16( st_fx->voicing_fx[0], 16384 ) && LT_16( st_fx->voicing_fx[1], 16384 ) && LT_16( st_fx->voicing_fx[2], 16384 ) ) ) && !st_fx->igf ) { /* In case of unvoiced signals after switching cores, back-propagate the target signal */ Copy( hb_speech, hb_old_speech, WBTBE_LOOK_LSUFBR_5_OVER_16 ); @@ -1363,27 +1372,31 @@ void wb_tbe_enc_ivas_fx( FOR( j = 0; j < L_SUBFR16k; j = j + 4 ) { L_tmp = L_mult( hb_old_speech[i], ola_win_shb_switch_fold_fx[j] ); - hb_old_speech[i] = mac_r( L_tmp, hb_speech[k], ola_win_shb_switch_fold_fx[L_SUBFR16k - 4 - j] ); + hb_old_speech[i] = mac_ro( L_tmp, hb_speech[k], ola_win_shb_switch_fold_fx[L_SUBFR16k - 4 - j], &Overflow ); move16(); - i = sub( i, 1 ); - k = add( k, 1 ); + i--; + k++; } } - autocorr_fx( hb_old_speech, LPC_SHB_ORDER_WB + 1, R_h, R_l, &Q_R, ( ( NS2SA( INT_FS_12k8, 5000000L ) + L_SUBFR + L_FRAME ) * 5 / 16 ), win_lpc_hb_wb_fx, 0, 1 ); + autocorr_fx( hb_old_speech, LPC_SHB_ORDER_WB + 1, R_h, R_l, &Q_R, ( ( NS2SA( INT_FS_12k8, 5000000L ) + L_SUBFR + L_FRAME ) * 5 / 16 ), win_lpc_hb_wb_ivas_fx, 0, 1 ); - E_LPC_lev_dur( R_h, R_l, lpc_wb_temp_fx, LepsP, LPC_SHB_ORDER_WB, NULL ); + E_LPC_lev_dur( R_h, R_l, lpc_wb_temp_fx, LepsP, LPC_SHB_ORDER_WB, NULL ); // Since 0th index will be 1 in floating point buffer, in fixed point one has to take norm of 0th index to identify the Q-factor - Copy_Scale_sig( lpc_wb_temp_fx, lpc_wb_temp_fx, LPC_SHB_ORDER_WB + 1, sub( norm_s( lpc_wb_temp_fx[0] ), 2 ) ); + Copy_Scale_sig( lpc_wb_temp_fx, lpc_wb_temp_fx, LPC_SHB_ORDER_WB + 1, sub( norm_s( lpc_wb_temp_fx[0] ), 2 ) ); // Q12 /* convert into lsps and calculate weights */ FOR( i = 0; i <= LPC_SHB_ORDER_WB; i++ ) { - lpc_wb_32_fx[i] = L_negate( L_shr( L_deposit_h( lpc_wb_temp_fx[i] ), 1 ) ); + lpc_wb_32_fx[i] = L_negate( L_deposit_h( shr( lpc_wb_temp_fx[i], 1 ) ) ); // Q27 move32(); } +#ifdef FIX_ISSUE_1165 + lpc2lsp_ivas_fx( &lpc_wb_32_fx[1], lsp_wb_temp_fx, st_fx->prev_lsp_wb_temp_fx, LPC_SHB_ORDER_WB ); +#else lpc2lsp_fx( &lpc_wb_32_fx[1], lsp_wb_temp_fx, st_fx->prev_lsp_wb_temp_fx, LPC_SHB_ORDER_WB ); +#endif FOR( i = 0; i < LPC_SHB_ORDER_WB; i++ ) { @@ -1572,7 +1585,7 @@ void wb_tbe_enc_ivas_fx( find_max_mem_wb_enc( st_fx, &n_mem ); - if ( GT_16( sub( Q_bwe_exc, st_fx->prev_Q_bwe_exc ), n_mem ) ) + IF( GT_16( sub( Q_bwe_exc, st_fx->prev_Q_bwe_exc ), n_mem ) ) { Q_bwe_exc = add( st_fx->prev_Q_bwe_exc, n_mem ); } @@ -1588,76 +1601,111 @@ void wb_tbe_enc_ivas_fx( prev_pow = 0; move32(); + Q_prev_pow = norm_arr( hBWE_TD->state_syn_shbexc_fx, L_SHB_LAHEAD / 4 ); + /* Compare with the guard bits needed in the subsequent operations. + * Guard bits for L_SHB_LAHEAD / 4 (expression evaluates to 5) is 3. + */ + IF( LT_16( Q_prev_pow, 3 ) ) + { + FOR( i = 0; i < L_SHB_LAHEAD / 4; i++ ) + { + shaped_wb_exc_scale[i] = shr( hBWE_TD->state_syn_shbexc_fx[i], 3 ); + move16(); + } + Q_prev_pow = shl_r( sub( sub( st_fx->prev_Q_bwe_exc, 16 ), 3 ), 1 ); + move16(); + } + ELSE + { + FOR( i = 0; i < L_SHB_LAHEAD / 4; i++ ) + { + shaped_wb_exc_scale[i] = hBWE_TD->state_syn_shbexc_fx[i]; + move16(); + } + Q_prev_pow = shl_r( sub( st_fx->prev_Q_bwe_exc, 16 ), 1 ); + move16(); + } + IF( st_fx->element_mode > EVS_MONO ) { - tmp = sub( shl( sub( st_fx->prev_Q_bwe_exc, 16 ), 1 ), 31 + 16 ); -#ifdef BASOP_NOGLOB - prev_pow = L_shl_sat( 1407374848l /*0.00001f Q47*/, tmp ); /*Q(2*(st_fx->prev_Q_bwe_exc-16))*/ -#else - prev_pow = L_shl( 1407374848l /*0.00001f Q47*/, tmp ); /*Q(2*(st_fx->prev_Q_bwe_exc-16))*/ -#endif + tmp = sub( Q_prev_pow, 31 + 16 ); + prev_pow = L_shl_sat( 1407374848l /*0.00001f Q47*/, tmp ); /*Q_prev_pow*/ } FOR( i = 0; i < L_SHB_LAHEAD / 4; i++ ) { - prev_pow = L_mac0( prev_pow, hBWE_TD->state_syn_shbexc_fx[i], hBWE_TD->state_syn_shbexc_fx[i] ); /* Q(2*st_fx->prev_Q_bwe_exc) */ + prev_pow = L_mac0( prev_pow, shaped_wb_exc_scale[i], shaped_wb_exc_scale[i] ); /* Q_prev_pow */ } rescale_genWB_mem_enc( st_fx, sub( Q_bwe_exc, st_fx->prev_Q_bwe_exc ) ); - Copy( hBWE_TD->old_bwe_exc_extended_fx, bwe_exc_extended_16, NL_BUFF_OFFSET ); sc = sub( Q_bwe_exc, add( Q_new, Q_new ) ); FOR( i = 0; i < L_FRAME32k; i++ ) { bwe_exc_extended_16[i + NL_BUFF_OFFSET] = round_fx( L_shl( bwe_exc_extended[i], sc ) ); move16(); } - Copy( bwe_exc_extended_16 + L_FRAME32k, hBWE_TD->old_bwe_exc_extended_fx, NL_BUFF_OFFSET ); Copy( hBWE_TD->state_syn_shbexc_fx, shaped_wb_excitation, L_SHB_LAHEAD / 4 ); Q_bwe_exc_ext = sub( Q_bwe_exc, 16 ); - GenShapedWBExcitation_fx( shaped_wb_excitation + L_SHB_LAHEAD / 4, lpc_wb, exc4kWhtnd, hBWE_TD->mem_csfilt_fx, - hBWE_TD->mem_genSHBexc_filt_down_shb_fx, hBWE_TD->mem_genSHBexc_filt_down_wb2_fx, hBWE_TD->mem_genSHBexc_filt_down_wb3_fx, - hBWE_TD->state_lpc_syn_fx, st_fx->coder_type, bwe_exc_extended_16, Q_bwe_exc_ext, hBWE_TD->bwe_seed, - vf_modified_fx, uv_flag, st_fx->igf ); + GenShapedWBExcitation_ivas_fx( shaped_wb_excitation + L_SHB_LAHEAD / 4, lpc_wb, exc4kWhtnd, hBWE_TD->mem_csfilt_fx, + hBWE_TD->mem_genSHBexc_filt_down_shb_fx, hBWE_TD->mem_genSHBexc_filt_down_wb2_fx, hBWE_TD->mem_genSHBexc_filt_down_wb3_fx, + hBWE_TD->state_lpc_syn_fx, st_fx->coder_type, bwe_exc_extended_16, Q_bwe_exc_ext, hBWE_TD->bwe_seed, + vf_modified_fx, uv_flag, st_fx->igf ); curr_pow = 0; move32(); + Q_cur_pow = norm_arr( &shaped_wb_excitation[L_SHB_LAHEAD / 4], L_SHB_LAHEAD / 4 ); + /* Compare with the guard bits needed in the subsequent operations. + * Guard bits for L_SHB_LAHEAD / 4 (expression evaluates to 5) is 3. + */ + IF( LT_16( Q_cur_pow, 3 ) ) + { + FOR( i = 0; i < L_SHB_LAHEAD / 4; i++ ) + { + shaped_wb_exc_scale[i] = shr( shaped_wb_excitation[i + L_SHB_LAHEAD / 4], 3 ); + move16(); + } + Q_cur_pow = shl_r( sub( Q_bwe_exc_ext, 3 ), 1 ); + move16(); + } + ELSE + { + FOR( i = 0; i < L_SHB_LAHEAD / 4; i++ ) + { + shaped_wb_exc_scale[i] = shaped_wb_excitation[i + L_SHB_LAHEAD / 4]; + move16(); + } + Q_cur_pow = shl_r( Q_bwe_exc_ext, 1 ); + move16(); + } IF( st_fx->element_mode > EVS_MONO ) { - tmp = sub( shl( Q_bwe_exc_ext, 1 ), 31 + 16 ); -#ifdef BASOP_NOGLOB - curr_pow = L_shl_sat( 1407374848l /*0.00001f Q47*/, tmp ); /*Q(2*(Q_bwe_exc_ext))*/ -#else - curr_pow = L_shl( 1407374848l /*0.00001f Q47*/, tmp ); /* 2*(Q_bwe_exc_ext) */ -#endif + tmp = sub( Q_cur_pow, 31 + 16 ); + curr_pow = L_shl_sat( 1407374848l /*0.00001f Q47*/, tmp ); /*Q(Q_cur_pow)*/ } FOR( i = 0; i < L_SHB_LAHEAD / 4; i++ ) { - curr_pow = L_mac0( curr_pow, shaped_wb_excitation[i + L_SHB_LAHEAD / 4], shaped_wb_excitation[i + L_SHB_LAHEAD / 4] ); /* Q(2*Q_bwe_exc_ext) */ + curr_pow = L_mac0( curr_pow, shaped_wb_exc_scale[i], shaped_wb_exc_scale[i] ); /* Q(Q_cur_pow) */ } IF( GT_16( voice_factors[0], 24576 ) ) { - curr_pow = L_shr( curr_pow, 2 ); /* Q(2*Q_bwe_exc_ext) */ + curr_pow = L_shr( curr_pow, 2 ); /* Q(Q_pow) */ } - Lscale = root_a_over_b_fx( curr_pow, shl_r( Q_bwe_exc_ext, 1 ), prev_pow, shl_r( sub( st_fx->prev_Q_bwe_exc, 16 ), 1 ), &exp ); + Lscale = root_a_over_b_fx( curr_pow, Q_cur_pow, prev_pow, Q_prev_pow, &exp ); FOR( i = 0; i < L_SHB_LAHEAD / 4 - 1; i++ ) { - L_tmp = Mpy_32_16_1( Lscale, shaped_wb_excitation[i] ); /* Q(16-exp+Q_bwe_exc_ext) */ -#ifdef BASOP_NOGLOB + L_tmp = Mpy_32_16_1( Lscale, shaped_wb_excitation[i] ); /* Q(16-exp+Q_bwe_exc_ext) */ shaped_wb_excitation[i] = round_fx_sat( L_shl_sat( L_tmp, exp ) ); /* Q_bwe_exc_ext */ -#else - shaped_wb_excitation[i] = round_fx( L_shl( L_tmp, exp ) ); /* Q_bwe_exc_ext */ -#endif move16(); } Lscale = root_a_fx( Lscale, sub( 31, exp ), &exp ); - L_tmp = Mpy_32_16_1( Lscale, shaped_wb_excitation[L_SHB_LAHEAD / 4 - 1] ); /* Q(16-exp+Q_bwe_exc_ext) */ - shaped_wb_excitation[L_SHB_LAHEAD / 4 - 1] = round_fx( L_shl( L_tmp, exp ) ); /* Q_bwe_exc_ext */ + L_tmp = Mpy_32_16_1( Lscale, shaped_wb_excitation[L_SHB_LAHEAD / 4 - 1] ); /* Q(16-exp+Q_bwe_exc_ext) */ + shaped_wb_excitation[L_SHB_LAHEAD / 4 - 1] = round_fx_sat( L_shl_sat( L_tmp, exp ) ); /* Q_bwe_exc_ext */ move16(); /* Update WB excitation */ @@ -1738,7 +1786,7 @@ void wb_tbe_enc_ivas_fx( move16(); } - hBWE_TD->prev_wb_GainShape = GainShape[sub( shr( NUM_SHB_SUBFR, 2 ), 1 )]; + hBWE_TD->prev_wb_GainShape = GainShape[( NUM_SHB_SUBFR >> 2 ) - 1]; move16(); /* Compute the power of gains away from the peak gain prior to quantization */ @@ -1778,8 +1826,8 @@ void wb_tbe_enc_ivas_fx( } /* Estimate the gain parameter */ - EstimateSHBFrameGain_fx( SHB_OVERLAP_LEN / 2, hb_frame, Q_ns, shaped_wb_excitation, Q_bwe_exc_ext, GainShape, - &GainFrame, window_wb_fx, subwin_wb_fx, 0 ); + EstimateSHBFrameGain_ivas_fx( SHB_OVERLAP_LEN / 2, hb_frame, Q_ns, shaped_wb_excitation, Q_bwe_exc_ext, GainShape, + &GainFrame, window_wb_fx, subwin_wb_fx, 0 ); /* If there's a big difference in the power of gains away from the peak gain */ @@ -1812,13 +1860,8 @@ void wb_tbe_enc_ivas_fx( exp = norm_s( voicingBufAvg_fx ); tmp = div_s( shl( 1, sub( 14, exp ) ), voicingBufAvg_fx ); /* (14-exp) */ L_tmp = L_mult( pitBufAvg_fx, tmp ); /* (21-exp) */ -#ifdef BASOP_NOGLOB L_tmp = L_shl_o( L_tmp, add( exp, 10 ), &Overflow ); tmp = round_fx_o( L_tmp, &Overflow ); /* Q15 */ -#else /* BASOP_NOGLOB */ - L_tmp = L_shl( L_tmp, add( exp, 10 ) ); - tmp = round_fx( L_tmp ); /* Q15 */ -#endif } tmp = s_max( s_min( tmp, 32767 ), 22938 ); /* Q15 */ @@ -1862,9 +1905,14 @@ void wb_tbe_enc_ivas_fx( /* Adjust the subframe and frame gain of the synthesized SHB signal */ /* Scale the shaped excitation*/ + + scale_sig( shaped_wb_excitation, ( L_FRAME16k + L_SHB_LAHEAD ) / 4, -1 ); + scale_sig( hBWE_TD->syn_overlap_fx, L_SHB_LAHEAD, -1 ); + Q_bwe_exc_ext = sub( Q_bwe_exc_ext, 1 ); ScaleShapedSHB_fx( SHB_OVERLAP_LEN / 2, shaped_wb_excitation, hBWE_TD->syn_overlap_fx, GainShape, GainFrame, window_wb_fx, subwin_wb_fx, &Q_bwe_exc_ext, &dummy, dummy, dummy ); + Scale_sig( hBWE_TD->syn_overlap_fx, L_SHB_LAHEAD, 1 ); st_fx->prev_Q_bwe_exc = Q_bwe_exc; move16(); @@ -1949,6 +1997,8 @@ void swb_tbe_enc_fx( Word32 LepsP[LPC_SHB_ORDER + 1]; Word16 ana_align_delay[2] = { -L_SHB_LAHEAD - ( NL_BUFF_OFFSET / 2 ), -L_SHB_LAHEAD - ( NL_BUFF_OFFSET / 2 ) }; + move16(); + move16(); Word32 prev_pow_fx, curr_pow_fx, Lscale; Word32 p2m_in_fx, p2m_out_fx; @@ -1994,6 +2044,7 @@ void swb_tbe_enc_fx( Word16 n_subfr_saturation; #ifdef BASOP_NOGLOB_DECLARE_LOCAL Flag Overflow = 0; + move16(); #endif TD_BWE_ENC_HANDLE hBWE_TD = st_fx->hBWE_TD; RF_ENC_HANDLE hRF = st_fx->hRF; @@ -2069,6 +2120,7 @@ void swb_tbe_enc_fx( FOR( i = 1; i <= LPC_SHB_ORDER; i++ ) { lpc_shb_fx[i] = mult_r( lpc_shb_fx[i], lpc_weights_fx[i] ); + move16(); } } @@ -2095,7 +2147,9 @@ void swb_tbe_enc_fx( /* to compensate for the 1.1* weighting done inside the function lsp_weights */ /*weights_lsp[3]*=0.909091f; weights_lsp[4]*=0.909091f; */ weights_lsp[3] = mult_r( weights_lsp[3], 29789 /*0.909091f Q15*/ ); + move16(); weights_lsp[4] = mult_r( weights_lsp[4], 29789 /*0.909091f Q15*/ ); + move16(); /* 8-bit VQ, 10 dimension */ i = closest_centroid_fx( lsf_shb_fx, weights_lsp, swb_tbe_lsfvq_cbook_8b, 256, LPC_SHB_ORDER ); @@ -2103,6 +2157,7 @@ void swb_tbe_enc_fx( set16_fx( hBWE_TD->lsf_idx, 0, NUM_Q_LSF ); hBWE_TD->lsf_idx[0] = i; + move16(); } ELSE { @@ -2165,10 +2220,12 @@ void swb_tbe_enc_fx( Copy( lsp_shb_2_fx, lsp_shb_1_fx, LPC_SHB_ORDER ); } - lsf_diff[0] = lsf_diff[sub( LPC_SHB_ORDER, 1 )] = 16384; /*Q15*/ + lsf_diff[0] = lsf_diff[LPC_SHB_ORDER - 1] = 16384; /*Q15*/ + move16(); FOR( i = 1; i < LPC_SHB_ORDER - 1; i++ ) { - lsf_diff[i] = sub( lsf_shb_fx[i], lsf_shb_fx[sub( i, 1 )] ); + lsf_diff[i] = sub( lsf_shb_fx[i], lsf_shb_fx[i - 1] ); + move16(); } a2rc_fx( hBWE_TD->cur_sub_Aq_fx + 1, refl, M ); @@ -2187,6 +2244,7 @@ void swb_tbe_enc_fx( FOR( i = 1; i < LPC_SHB_ORDER - 1; i++ ) { hBWE_TD->prev_lsf_diff_fx[i - 1] = mult( lsf_diff[i], 16384 ); /*Q15*/ + move16(); } } @@ -2208,6 +2266,7 @@ void swb_tbe_enc_fx( tmp = div_s( tmp, hBWE_TD->prev_lsf_diff_fx[i - 1] ); tmp = s_max( tmp, 16384 ); w[i] = s_min( tmp, 32767 ); + move16(); } ELSE { @@ -2215,16 +2274,20 @@ void swb_tbe_enc_fx( tmp = div_s( tmp, lsf_diff[i] ); tmp = s_max( tmp, 16384 ); w[i] = s_min( tmp, 32767 ); + move16(); } } w[0] = w[1]; - w[sub( LPC_SHB_ORDER, 1 )] = w[sub( LPC_SHB_ORDER, 2 )]; + move16(); + w[LPC_SHB_ORDER - 1] = w[LPC_SHB_ORDER - 2]; + move16(); FOR( i = 0; i < LPC_SHB_ORDER; i++ ) { tmp1 = mult( lsp_shb_1_fx[i], sub( 32767, w[i] ) ); tmp2 = mult( lsp_shb_2_fx[i], w[i] ); lsp_temp_fx[i] = add( tmp1, tmp2 ); + move16(); } } ELSE @@ -2235,6 +2298,7 @@ void swb_tbe_enc_fx( Copy( lsf_diff + 1, hBWE_TD->prev_lsf_diff_fx, LPC_SHB_ORDER - 2 ); hBWE_TD->prev_tilt_para_fx = tilt_para; + move16(); shb_ener_sf_Q31 = 0; move16(); @@ -2267,11 +2331,7 @@ void swb_tbe_enc_fx( FOR( i = L_SHB_LAHEAD; i < L_FRAME16k + L_SHB_LAHEAD; i++ ) { /* shbEner = shbEner + in[i] * in[i] */ -#ifdef BASOP_NOGLOB shb_ener_sf_Q31 = L_mac0_sat( shb_ener_sf_Q31, shb_frame_fx[i], shb_frame_fx[i] ); -#else - shb_ener_sf_Q31 = L_mac0( shb_ener_sf_Q31, shb_frame_fx[i], shb_frame_fx[i] ); -#endif /* o: shb_ener_sf_Q31 in (2*Q_shb) */ } shb_ener_sf_Q31 = Mult_32_16( shb_ener_sf_Q31, 102 /*0.003125f Q15*/ ); @@ -2291,6 +2351,7 @@ void swb_tbe_enc_fx( FOR( i = 0; i < NB_SUBFR16k; i++ ) { shb_res_gshape_fx_32[i] = sum2_fx( shb_res_fx + i * 64, 64 ); + move32(); } /* o: shb_res_gshape_fx_32 in (2*Q_shb+1) */ @@ -2308,14 +2369,17 @@ void swb_tbe_enc_fx( exp = norm_l( L_tmp ); tmp = extract_h( L_shl( L_tmp, exp ) ); recip = div_s( 16384, tmp ); - Q_recip = 31 - ( exp - 14 ); /* = 31-(exp+2*Q_shb+1-14), but adjusted by (2*Q_shb+1) for use at Mult_32_16 below */ + // Q_recip = 31 - ( exp - 14 ); /* = 31-(exp+2*Q_shb+1-14), but adjusted by (2*Q_shb+1) for use at Mult_32_16 below */ + Q_recip = sub( 31 + 14, exp ); /* = 31-(exp+2*Q_shb+1-14), but adjusted by (2*Q_shb+1) for use at Mult_32_16 below */ + move16(); } FOR( i = 0; i < NB_SUBFR16k; i++ ) { L_tmp1 = Mult_32_16( shb_res_gshape_fx_32[i], recip ); /*Q = Q_recip+1-16*/ - L_tmp = root_a_fx( L_tmp1, Q_recip + 1 - 16, &exp ); - shb_res_gshape_fx[i] = round_fx( L_shl( L_tmp, exp - 1 ) ); /* Q14 */ + L_tmp = root_a_fx( L_tmp1, add( Q_recip, 1 - 16 ), &exp ); + shb_res_gshape_fx[i] = round_fx( L_shl( L_tmp, sub( exp, 1 ) ) ); /* Q14 */ + move16(); } Quant_shb_res_gshape_fx( st_fx, shb_res_gshape_fx ); @@ -2339,6 +2403,7 @@ void swb_tbe_enc_fx( if ( Lmax == 0 ) { Q_bwe_exc = 31; + move16(); } Q_bwe_exc = add( Q_bwe_exc, add( Q_new, Q_new ) ); @@ -2349,6 +2414,7 @@ void swb_tbe_enc_fx( if ( GT_16( Q_bwe_exc, tmp2 ) ) { Q_bwe_exc = tmp2; + move16(); } /* rescale the memories if Q_bwe_exc is different from previous frame */ @@ -2364,11 +2430,8 @@ void swb_tbe_enc_fx( FOR( cnt = 0; cnt < L_FRAME32k; cnt++ ) { -#ifdef BASOP_NOGLOB bwe_exc_extended_16[cnt + NL_BUFF_OFFSET] = round_fx_sat( L_shl_sat( bwe_exc_extended[cnt], sc ) ); -#else - bwe_exc_extended_16[cnt + NL_BUFF_OFFSET] = round_fx( L_shl( bwe_exc_extended[cnt], sc ) ); -#endif + move16(); } Copy( bwe_exc_extended_16 + L_FRAME32k, hBWE_TD->old_bwe_exc_extended_fx, NL_BUFF_OFFSET ); @@ -2400,9 +2463,11 @@ void swb_tbe_enc_fx( &( hBWE_TD->fb_tbe_demph_fx ), &Q_bwe_exc, &Q_bwe_exc_fb, Q_shb, n_mem2, st_fx->prev_Q_bwe_syn, st_fx->total_brate, 0 ); *Q_white_exc = Q_bwe_exc_fb; + move16(); IF( EQ_16( st_fx->extl, FB_TBE ) ) { hBWE_TD->prev_Q_bwe_exc_fb = Q_bwe_exc_fb; + move16(); } ELSE { @@ -2429,6 +2494,7 @@ void swb_tbe_enc_fx( FOR( i = 0; i < LPC_SHB_ORDER; i++ ) { hBWE_TD->mem_stp_swb_fx[i] = shl( hBWE_TD->mem_stp_swb_fx[i], sub( Q_bwe_exc, st_fx->prev_Q_bwe_syn ) ); + move16(); } FOR( i = 0; i < L_FRAME16k; i += L_SUBFR16k ) @@ -2446,13 +2512,8 @@ void swb_tbe_enc_fx( curr_pow_fx = L_shl( 21475l /*0.00001f Q31*/, tmp ); /* 2*(Q_bwe_exc) */ FOR( i = 0; i < L_SHB_LAHEAD + 10; i++ ) { -#ifdef BASOP_NOGLOB prev_pow_fx = L_mac0_o( prev_pow_fx, shaped_shb_excitation_fx[i], shaped_shb_excitation_fx[i], &Overflow ); /* 2*Q_bwe_exc */ curr_pow_fx = L_mac0_o( curr_pow_fx, shaped_shb_excitation_fx[i + L_SHB_LAHEAD + 10], shaped_shb_excitation_fx[i + L_SHB_LAHEAD + 10], &Overflow ); /* 2*Q_bwe_exc */ -#else - prev_pow_fx = L_mac0( prev_pow_fx, shaped_shb_excitation_fx[i], shaped_shb_excitation_fx[i] ); /* 2*Q_bwe_exc */ - curr_pow_fx = L_mac0( curr_pow_fx, shaped_shb_excitation_fx[i + L_SHB_LAHEAD + 10], shaped_shb_excitation_fx[i + L_SHB_LAHEAD + 10] ); /* 2*Q_bwe_exc */ -#endif } if ( GT_16( voice_factors_fx[0], 24576 /*0.75f Q15*/ ) ) @@ -2468,35 +2529,25 @@ void swb_tbe_enc_fx( &exp ); FOR( i = 0; i < L_SHB_LAHEAD; i++ ) { - L_tmp = Mult_32_16( Lscale, shaped_shb_excitation_fx[i] ); /* Q(16-exp+Q_bwe_exc) */ -#ifdef BASOP_NOGLOB + L_tmp = Mult_32_16( Lscale, shaped_shb_excitation_fx[i] ); /* Q(16-exp+Q_bwe_exc) */ shaped_shb_excitation_fx[i] = round_fx_sat( L_shl_sat( L_tmp, exp ) ); /* Q_bwe_exc */ -#else - shaped_shb_excitation_fx[i] = round_fx( L_shl( L_tmp, exp ) ); /* Q_bwe_exc */ -#endif + move16(); } IF( exp < 0 ) { Lscale = L_shl( Lscale, exp ); exp = 0; + move16(); } FOR( ; i < L_SHB_LAHEAD + 10; i++ ) { -#ifdef BASOP_NOGLOB tmp = i_mult_o( sub( i, 19 ), 3277 /*0.1f Q15*/, &Overflow ); /* Q15 */ L_tmp1 = Mult_32_16( L_shl_o( 1, sub( 31, exp ), &Overflow ), tmp ); /* Q31-exp */ -#else - tmp = i_mult( sub( i, 19 ), 3277 /*0.1f Q15*/ ); /* Q15 */ - L_tmp1 = Mult_32_16( L_shl( 1, sub( 31, exp ) ), tmp ); /* Q31-exp */ -#endif tmp = sub( 32767 /*1.0f Q15*/, tmp ); Lscale = L_add( Mult_32_16( Lscale, tmp ), L_tmp1 ); - L_tmp = Mult_32_16( Lscale, shaped_shb_excitation_fx[i] ); /* Q_bwe_exc + (31-exp) - 15 */ -#ifdef BASOP_NOGLOB + L_tmp = Mult_32_16( Lscale, shaped_shb_excitation_fx[i] ); /* Q_bwe_exc + (31-exp) - 15 */ shaped_shb_excitation_fx[i] = round_fx_o( L_shl_o( L_tmp, exp, &Overflow ), &Overflow ); /* Q_bwe_exc */ -#else - shaped_shb_excitation_fx[i] = round_fx( L_shl( L_tmp, exp ) ); /* Q_bwe_exc */ -#endif + move16(); } /* Update SHB excitation */ @@ -2517,6 +2568,7 @@ void swb_tbe_enc_fx( /* 0.35f +/- delta variation; delta = 0.1*(GS-0.35)*/ /* GainShape[i] = 0.315f + 0.1f * GainShape[i]; */ GainShape_fx[i] = mac_r( 676457349l /*0.315 Q31*/, 3277 /*0.1 Q15*/, GainShape_fx[i] ); + move16(); } } @@ -2605,10 +2657,12 @@ void swb_tbe_enc_fx( { temp_swb_fac = hBWE_TD->prev_swb_GainShape_fx; + move16(); FOR( i = 0; i < NUM_SHB_SUBGAINS; i++ ) { /*GainShape_fx[i] = (1 - feedback) * GainShape[i] + feedback * temp_swb_fac; */ GainShape_fx[i] = round_fx( L_mac( L_mult( sub( 32767, feedback ), GainShape_fx[i] ), feedback, temp_swb_fac ) ); + move16(); temp_swb_fac = GainShape_fx[i]; move16(); } @@ -2648,6 +2702,7 @@ void swb_tbe_enc_fx( GainFrame_fx = L_add( L_shr( hBWE_TD->prev_gainFr_SHB_fx, 1 ), L_shr( GainFrame_fx, 1 ) ); /* Q18 */ } + test(); test(); IF( EQ_16( frGainAttenuate, 1 ) && LE_16( MA_lsp_shb_spacing, 79 /*0.0024f Q15*/ ) ) { @@ -2658,7 +2713,7 @@ void swb_tbe_enc_fx( frac = L_Extract_lc( L_tmp, &exp ); GainFrame_fx = Pow2( 30, frac ); exp = sub( exp, 30 ); - GainFrame_fx = L_shl( GainFrame_fx, exp + 18 ); /* Q18 */ + GainFrame_fx = L_shl( GainFrame_fx, add( exp, 18 ) ); /* Q18 */ } ELSE IF( EQ_16( hBWE_TD->prev_frGainAtten, 1 ) && GT_32( Mult_32_16( GainFrame_fx, 10923 ), hBWE_TD->prev_gainFr_SHB_fx ) ) { @@ -2698,9 +2753,11 @@ void swb_tbe_enc_fx( /* voicingBufAvg = (sum_f(voice_factors, 4)=sum2 > 0.6f) ? 0.333f : 0.1667f; */ tmp2 = 5462 /*0.1667f Q15*/; + move16(); if ( GT_16( sum2, 4915 /*0.6f Q13*/ ) ) { tmp2 = 10912 /*0.333f Q15*/; /* Q15 */ + move16(); } voicingBufAvg_fx = shl( mult( tmp2, sum1 ), 2 ); /* Q15 */ @@ -2717,13 +2774,9 @@ void swb_tbe_enc_fx( tmp = div_s( shl( 1, sub( 14, exp ) ), voicingBufAvg_fx ); /* (14-exp) */ /* sd_uq_q*pitBufAvg */ - L_tmp = Mult_32_16( L_tmp, pitBufAvg_fx ); /* Q13 * Q10 + 1 -16 => Q8 */ - L_tmp = Mult_32_16( L_tmp, tmp ); /* Q8 + (14 - exp) - 15 => Q7 - exp */ -#ifdef BASOP_NOGLOB + L_tmp = Mult_32_16( L_tmp, pitBufAvg_fx ); /* Q13 * Q10 + 1 -16 => Q8 */ + L_tmp = Mult_32_16( L_tmp, tmp ); /* Q8 + (14 - exp) - 15 => Q7 - exp */ tmp = round_fx_o( L_shl_o( L_tmp, 31 - ( 7 - exp ), &Overflow ), &Overflow ); /* Q15 */ -#else - tmp = round_fx( L_shl( L_tmp, 31 - ( 7 - exp ) ) ); /* Q15 */ -#endif } tmp = s_min( tmp, 32767 /*1.0f Q15*/ ); @@ -2748,16 +2801,19 @@ void swb_tbe_enc_fx( if ( GainFrame_fx == 0 ) { tmp = 31; + move16(); } L_tmp = L_shl( GainFrame_fx, tmp ); /* 18 + tmp */ tmp1 = 0; + move16(); FOR( i = 0; i < L_FRAME16k; i++ ) { L_tmp1 = Mult_32_16( L_tmp, GainShape_fx[NUM_SHB_SUBFR * i / L_FRAME16k] ); /* Q : 18 + tmp +15 -15*/ /*White_exc16k_fx[i] = round_fx( L_shl(Mult_32_16( L_tmp1, White_exc16k_fx[i]),(23 - tmp -*Q_white_exc)) );*/ /*18 + tmp +*Q_white_exc -15 + 23 - tmp -*Q_white_exc -16 = 10*/ White_exc16k_fx[i] = round_fx( Mult_32_16( L_tmp1, White_exc16k_fx[i] ) ); /* 18 + tmp +*Q_white_exc -15 -16 */ + move16(); /*Lmax = L_max(Lmax,White_exc16k_fx[i]);*/ tmp1 = s_max( tmp1, abs_s( White_exc16k_fx[i] ) ); /*White_exc16k_fx[i] =32767;*/ @@ -2768,6 +2824,7 @@ void swb_tbe_enc_fx( if ( tmp1 == 0 ) { tmp = 15; + move16(); } FOR( i = 0; i < L_FRAME16k; i++ ) @@ -2881,7 +2938,7 @@ void swb_tbe_enc_ivas_fx( Word16 formant_fac_fx; // int16_t stab_check = 1; Word16 MSFlag; - Word16 *nlExc16k_fx, *mixExc16k_fx; + Word16 *nlExc16k_fx, *nlExc16k_e, *mixExc16k_fx, *mixExc16k_e; Word16 shaped_shb_excitationTemp_fx[L_FRAME16k]; @@ -2889,6 +2946,9 @@ void swb_tbe_enc_ivas_fx( Word16 acorr_EnvSHBres[ENVSHBRES_ACORR_MAX - ENVSHBRES_ACORR_MIN], *p_acorr, shb_env_tilt_fx; Word16 buf_EnvSHBres_fx[2 * L_FRAME4k], *p_buf, EnvSHBres_fx[L_FRAME16k], EnvSHBres_4k_fx[L_FRAME4k], EnvSHBres_4k_norm_fx[L_FRAME4k], env_mean_normf_fx[L_FRAME4k]; + Word32 tmp_buf[L_FRAME4k]; + Word16 Q_EnvSHBres_4k_norm = Q31; + move16(); Word16 GainShape_Interp_fx[NUM_SHB_SUBGAINS], GainShape_tilt_fx; /* Q15 */ Word16 seg_mean[4], den_seg_mean[4], *p_env, step; Word16 temp, scale_fx, scale_e, pow_e, tmp_e, tmp1_e; @@ -2906,7 +2966,7 @@ void swb_tbe_enc_ivas_fx( Word16 n_subfr_saturation; #ifdef BASOP_NOGLOB_DECLARE_LOCAL Flag Overflow = 0; - move32(); + move16(); #endif Env_error_fx = 0; @@ -2931,17 +2991,22 @@ void swb_tbe_enc_ivas_fx( exp1 = 0; /* to avoid compilation warnings */ move16(); + test(); IF( st_fx->element_mode >= IVAS_CPE_DFT && hStereoICBWE != NULL ) { nlExc16k_fx = hStereoICBWE->nlExc16k_fx; + nlExc16k_e = &hStereoICBWE->nlExc16k_e; mixExc16k_fx = hStereoICBWE->mixExc16k_fx; + mixExc16k_e = &hStereoICBWE->mixExc16k_e; MSFlag = hStereoICBWE->MSFlag; move16(); } ELSE { nlExc16k_fx = NULL; + nlExc16k_e = NULL; mixExc16k_fx = NULL; + mixExc16k_e = NULL; MSFlag = 0; move16(); } @@ -3081,7 +3146,7 @@ void swb_tbe_enc_ivas_fx( test(); IF( st_fx->rf_mode || EQ_32( st_fx->extl_brate, SWB_TBE_0k95 ) || EQ_32( st_fx->extl_brate, SWB_TBE_1k10 ) ) { - lsp_weights_fx( lsf_shb_fx, weights_lsp, LPC_SHB_ORDER, &Q_out ); + lsp_weights_ivas_fx( lsf_shb_fx, weights_lsp, LPC_SHB_ORDER, &Q_out ); /* to compensate for the 1.1* weighting done inside the function lsp_weights */ /*weights_lsp[3]*=0.909091f; weights_lsp[4]*=0.909091f; */ @@ -3226,7 +3291,7 @@ void swb_tbe_enc_ivas_fx( } w_fx[0] = w_fx[1]; move16(); - w_fx[sub( LPC_SHB_ORDER, 1 )] = w_fx[sub( LPC_SHB_ORDER, 2 )]; + w_fx[LPC_SHB_ORDER - 1] = w_fx[LPC_SHB_ORDER - 2]; move16(); FOR( i = 0; i < LPC_SHB_ORDER; i++ ) @@ -3278,11 +3343,7 @@ void swb_tbe_enc_ivas_fx( FOR( i = L_SHB_LAHEAD; i < L_FRAME16k + L_SHB_LAHEAD; i++ ) { /* shbEner = shbEner + in[i] * in[i] */ -#ifdef BASOP_NOGLOB shb_ener_sf_Q31 = L_mac0_sat( shb_ener_sf_Q31, shb_frame_fx[i], shb_frame_fx[i] ); -#else - shb_ener_sf_Q31 = L_mac0( shb_ener_sf_Q31, shb_frame_fx[i], shb_frame_fx[i] ); -#endif /* o: shb_ener_sf_Q31 in (2*Q_shb) */ } shb_ener_sf_Q31 = Mult_32_16( shb_ener_sf_Q31, 102 /*0.003125f Q15*/ ); @@ -3322,7 +3383,8 @@ void swb_tbe_enc_ivas_fx( exp = norm_l( L_tmp ); tmp = extract_h( L_shl( L_tmp, exp ) ); recip = div_s( 16384, tmp ); - Q_recip = sub( 31, sub( exp, 14 ) ); /* = 31-(exp+2*Q_shb+1-14), but adjusted by (2*Q_shb+1) for use at Mult_32_16 below */ + // Q_recip = sub( 31, sub( exp, 14 ) ); /* = 31-(exp+2*Q_shb+1-14), but adjusted by (2*Q_shb+1) for use at Mult_32_16 below */ + Q_recip = sub( 31 + 14, exp ); /* = 31-(exp+2*Q_shb+1-14), but adjusted by (2*Q_shb+1) for use at Mult_32_16 below */ } FOR( i = 0; i < NB_SUBFR16k; i++ ) @@ -3381,6 +3443,7 @@ void swb_tbe_enc_ivas_fx( FOR( k = 0; k < L_FRAME4k; k++ ) { EnvSHBres_4k_fx[k] = EnvSHBres_fx[4 * k]; /* Q_shb */ + move16(); } /* calculate long-term mean envelope over four consecutive segments using linear interpolation */ @@ -3427,7 +3490,7 @@ void swb_tbe_enc_ivas_fx( FOR( k = 1; k < 4; k++ ) { // step = ( den_seg_mean[k] - den_seg_mean[k - 1] ) * den_seg_len; - step = mult( den_seg_mean[k] - den_seg_mean[k - 1], den_seg_len ); + step = mult( sub( den_seg_mean[k], den_seg_mean[k - 1] ), den_seg_len ); FOR( i = 0; i < seg_len; i++ ) { *p_env = add_sat( *( p_env - 1 ), step ); @@ -3445,7 +3508,13 @@ void swb_tbe_enc_ivas_fx( /* normalize residual SHB envelope with its long-term mean envelope */ FOR( k = 0; k < L_FRAME4k; k++ ) { - EnvSHBres_4k_norm_fx[k] = mult( EnvSHBres_4k_fx[k], env_mean_normf_fx[k] ); + tmp_buf[k] = L_mult( EnvSHBres_4k_fx[k], env_mean_normf_fx[k] ); // Q_shb + Q15 + Q1 => Q_shb + Q16 + move32(); + } + Q_EnvSHBres_4k_norm = sub( getScaleFactor32( tmp_buf, L_FRAME4k ), 1 /* Guard bit */ ); + FOR( k = 0; k < L_FRAME4k; k++ ) + { + EnvSHBres_4k_norm_fx[k] = extract_h( L_shl( tmp_buf[k], Q_EnvSHBres_4k_norm ) ); // Q_shb + Q16 + Q_EnvSHBres_4k_norm - Q16 => Q_EnvSHBres_4k_norm + Q_shb move16(); } @@ -3457,15 +3526,16 @@ void swb_tbe_enc_ivas_fx( /* subtract mean value from the normalized SHB residual envelope */ p_buf = &buf_EnvSHBres_fx[L_FRAME4k]; - temp = mean_no_sat_fx( EnvSHBres_4k_norm_fx, L_FRAME4k ); + temp = mean_no_sat_fx( EnvSHBres_4k_norm_fx, L_FRAME4k ); // Q_EnvSHBres_4k_norm + Q_shb FOR( k = 0; k < L_FRAME4k; k++ ) { - *p_buf++ = sub( EnvSHBres_4k_norm_fx[k], temp ); + *p_buf++ = shr( sub( EnvSHBres_4k_norm_fx[k], temp ), Q_EnvSHBres_4k_norm ); // Q_shb move16(); } + Q_EnvSHBres_4k_norm = add( Q_EnvSHBres_4k_norm, Q_shb ); /* update memory */ - Copy( &buf_EnvSHBres_fx[L_FRAME4k], hBWE_TD->old_EnvSHBres_fx, L_FRAME4k ); + Copy( &buf_EnvSHBres_fx[L_FRAME4k], hBWE_TD->old_EnvSHBres_fx, L_FRAME4k ); // Q_shb /* calculate energy normalization factor for the auto-correlation function */ // pow0 = sum2_f( &buf_EnvSHBres[L_FRAME4k], L_FRAME4k ) + 1.0f; @@ -3615,13 +3685,9 @@ void swb_tbe_enc_ivas_fx( sc = sub( Q_bwe_exc, add( Q_new, Q_new ) ); /* rescale the bwe_exc_extended and bring it to 16-bit single precision with dynamic norm */ - FOR( cnt = 0; cnt < L_FRAME32k; cnt++ ) + FOR( cnt = 0; cnt < L_FRAME32k + NL_BUFF_OFFSET; cnt++ ) { -#ifdef BASOP_NOGLOB bwe_exc_extended_16[cnt] = round_fx_sat( L_shl_sat( bwe_exc_extended[cnt], sc ) ); -#else - bwe_exc_extended_16[cnt] = round_fx( L_shl( bwe_exc_extended[cnt], sc ) ); -#endif move16(); } @@ -3638,14 +3704,13 @@ void swb_tbe_enc_ivas_fx( Q_bwe_exc_fb = hBWE_TD->prev_Q_bwe_exc_fb; move16(); - // Replace with IVAS equivalent - GenShapedSHBExcitation_ivas_enc_fx( shaped_shb_excitation_fx + L_SHB_LAHEAD, lpc_shb_fx, White_exc16k_fx, - hBWE_TD->mem_csfilt_fx, hBWE_TD->mem_genSHBexc_filt_down_shb_fx, hBWE_TD->state_lpc_syn_fx, - st_fx->coder_type, bwe_exc_extended_16, hBWE_TD->bwe_seed, vf_modified_fx, st_fx->extl, - &( hBWE_TD->tbe_demph_fx ), &( hBWE_TD->tbe_premph_fx ), lpc_shb_sf_fx, shb_ener_sf_Q31, - shb_res_gshape_fx, shb_res_fx, &vf_ind_fx, formant_fac_fx, hBWE_TD->fb_state_lpc_syn_fx, - &( hBWE_TD->fb_tbe_demph_fx ), &Q_bwe_exc, &Q_bwe_exc_fb, Q_shb, n_mem2, st_fx->prev_Q_bwe_syn, st_fx->total_brate, 0, st_fx->element_mode, st_fx->flag_ACELP16k, nlExc16k_fx, mixExc16k_fx, st_fx->extl_brate, MSFlag, - EnvSHBres_4k_norm_fx, &( hBWE_TD->prev_pow_exc16kWhtnd_fx32 ), &( hBWE_TD->prev_mix_factor_fx ), &Env_error_fx, Env_error_part_fx ); + GenShapedSHBExcitation_ivas_enc_fx( shaped_shb_excitation_fx + L_SHB_LAHEAD, lpc_shb_fx, White_exc16k_fx, hBWE_TD->mem_csfilt_fx, + hBWE_TD->mem_genSHBexc_filt_down_shb_fx, hBWE_TD->state_lpc_syn_fx, st_fx->coder_type, bwe_exc_extended_16, hBWE_TD->bwe_seed, + vf_modified_fx, st_fx->extl, &( hBWE_TD->tbe_demph_fx ), &( hBWE_TD->tbe_premph_fx ), lpc_shb_sf_fx, shb_ener_sf_Q31, + shb_res_gshape_fx, shb_res_fx, &vf_ind_fx, formant_fac_fx, hBWE_TD->fb_state_lpc_syn_fx, &( hBWE_TD->fb_tbe_demph_fx ), &Q_bwe_exc, + &Q_bwe_exc_fb, Q_shb, n_mem2, st_fx->prev_Q_bwe_syn, st_fx->total_brate, 0, st_fx->element_mode, st_fx->flag_ACELP16k, nlExc16k_fx, + nlExc16k_e, mixExc16k_fx, mixExc16k_e, st_fx->extl_brate, MSFlag, EnvSHBres_4k_norm_fx, Q_EnvSHBres_4k_norm, + &( hBWE_TD->prev_pow_exc16kWhtnd_fx32 ), &( hBWE_TD->prev_mix_factor_fx ), &Env_error_fx, Env_error_part_fx ); *Q_white_exc = Q_bwe_exc_fb; move16(); @@ -3675,6 +3740,7 @@ void swb_tbe_enc_ivas_fx( { Copy( shaped_shb_excitation_fx + L_SHB_LAHEAD, hStereoICBWE->shbSynthRef_fx, L_FRAME16k ); hStereoICBWE->shbSynthRef_e = sub( 15, Q_bwe_exc ); + move16(); } test(); @@ -3738,7 +3804,7 @@ void swb_tbe_enc_ivas_fx( curr_pow_64fx = W_mac0_16_16( curr_pow_64fx, shaped_shb_excitation_fx[i + L_SHB_LAHEAD + 10], shaped_shb_excitation_fx[i + L_SHB_LAHEAD + 10] ); /* 2*Q_bwe_exc */ } - if ( GT_16( voice_factors_fx[0], 24576 /*0.75f Q15*/ ) ) + IF( GT_16( voice_factors_fx[0], 24576 /*0.75f Q15*/ ) ) { /*curr_pow_fx = Mult_32_16( curr_pow_fx, 8192);*/ /* Q(2*Q_bwe_exc) */ curr_pow_64fx = W_shr( curr_pow_64fx, 2 ); /* scale by 0.25 */ @@ -3758,12 +3824,8 @@ void swb_tbe_enc_ivas_fx( FOR( i = 0; i < L_SHB_LAHEAD; i++ ) { - L_tmp = Mult_32_16( Lscale, shaped_shb_excitation_fx[i] ); /* Q(16-exp+Q_bwe_exc) */ -#ifdef BASOP_NOGLOB + L_tmp = Mult_32_16( Lscale, shaped_shb_excitation_fx[i] ); /* Q(16-exp+Q_bwe_exc) */ shaped_shb_excitation_fx[i] = round_fx_o( L_shl_o( L_tmp, exp, &Overflow ), &Overflow ); /* Q_bwe_exc */ -#else - shaped_shb_excitation_fx[i] = round_fx( L_shl( L_tmp, exp ) ); /* Q_bwe_exc */ -#endif move16(); } IF( exp < 0 ) @@ -3774,21 +3836,12 @@ void swb_tbe_enc_ivas_fx( } FOR( ; i < L_SHB_LAHEAD + 10; i++ ) { -#ifdef BASOP_NOGLOB tmp = i_mult_o( sub( i, 19 ), 3277 /*0.1f Q15*/, &Overflow ); /* Q15 */ L_tmp1 = Mult_32_16( L_shl_o( 1, sub( 31, exp ), &Overflow ), tmp ); /* Q31-exp */ -#else - tmp = i_mult( sub( i, 19 ), 3277 /*0.1f Q15*/ ); /* Q15 */ - L_tmp1 = Mult_32_16( L_shl( 1, sub( 31, exp ) ), tmp ); /* Q31-exp */ -#endif tmp = sub( 32767 /*1.0f Q15*/, tmp ); Lscale = L_add( Mult_32_16( Lscale, tmp ), L_tmp1 ); - L_tmp = Mult_32_16( Lscale, shaped_shb_excitation_fx[i] ); /* Q_bwe_exc + (31-exp) - 15 */ -#ifdef BASOP_NOGLOB + L_tmp = Mult_32_16( Lscale, shaped_shb_excitation_fx[i] ); /* Q_bwe_exc + (31-exp) - 15 */ shaped_shb_excitation_fx[i] = round_fx_o( L_shl_o( L_tmp, exp, &Overflow ), &Overflow ); /* Q_bwe_exc */ -#else - shaped_shb_excitation_fx[i] = round_fx( L_shl( L_tmp, exp ) ); /* Q_bwe_exc */ -#endif move16(); } } @@ -3863,47 +3916,48 @@ void swb_tbe_enc_ivas_fx( /* Gain frame adjustment factor */ /* log( (GainShape[0]) / (st->prev_wb_GainShape) )*/ - test(); - IF( GainShape_fx[0] && hBWE_TD->prev_swb_GainShape_fx ) + IF( hBWE_TD->prev_swb_GainShape_fx == 0 ) { - exp = norm_s( hBWE_TD->prev_swb_GainShape_fx ); - tmp = div_s( shl( 1, sub( 14, exp ) ), hBWE_TD->prev_swb_GainShape_fx ); - L_tmp = L_mult( GainShape_fx[0], tmp ); /*Q(30 - exp) */ - - exp1 = norm_l( L_tmp ); - frac = Log2_norm_lc( L_shl( L_tmp, exp1 ) ); /*move16(); */ - exp1 = sub( exp, exp1 ); /*move16(); */ - L_tmp = Mpy_32_16( exp1, frac, 22713 ); - temp_swb_fac = round_fx( L_shl( L_tmp, 10 ) ); + exp = 13 /* norm_s(3) */; + tmp = 21845 /* div_s( shl(1, sub(14, exp)), 3 /\* 0.0001 in Q15 *\/ ) */; } ELSE { - temp_swb_fac = 0; - move16(); + exp = norm_s( hBWE_TD->prev_swb_GainShape_fx ); + tmp = div_s( shl( 1, sub( 14, exp ) ), hBWE_TD->prev_swb_GainShape_fx ); } - L_feedback = L_mult0( temp_swb_fac, temp_swb_fac ); + + L_tmp = L_mult( GainShape_fx[0], tmp ); /*Q(30 - exp) */ + + exp1 = norm_l( L_tmp ); + frac = Log2_norm_lc( L_shl( L_tmp, exp1 ) ); /*move16(); */ + exp1 = sub( exp, exp1 ); /*move16(); */ + L_tmp = Mpy_32_16( exp1, frac, 22713 ); + temp_swb_fac = round_fx( L_shl( L_tmp, 10 ) ); + + L_feedback = L_mult( temp_swb_fac, temp_swb_fac ); FOR( i = 1; i < NUM_SHB_SUBGAINS; i++ ) { test(); - IF( GainShape_fx[i] && GainShape_fx[i - 1] ) + IF( GainShape_fx[i - 1] == 0 ) { - exp = norm_s( GainShape_fx[i - 1] ); - tmp = div_s( shl( 1, sub( 14, exp ) ), GainShape_fx[i - 1] ); - L_tmp = L_mult( GainShape_fx[i], tmp ); /* Q(30 - exp) */ - - exp1 = norm_l( L_tmp ); - frac = Log2_norm_lc( L_shl( L_tmp, exp1 ) ); - exp1 = sub( exp, exp1 ); - L_tmp = Mpy_32_16( exp1, frac, 22713 ); - temp_swb_fac = round_fx( L_shl( L_tmp, 10 ) ); + exp = 13 /* norm_s(3) */; + tmp = 21845 /* div_s( shl(1, sub(14, exp)), 3 /\* 0.0001 in Q15 *\/ ) */; } ELSE { - temp_swb_fac = 0; - move16(); + exp = norm_s( GainShape_fx[i - 1] ); + tmp = div_s( shl( 1, sub( 14, exp ) ), GainShape_fx[i - 1] ); } + L_tmp = L_mult( GainShape_fx[i], tmp ); /* Q(30 - exp) */ + + exp1 = norm_l( L_tmp ); + frac = Log2_norm_lc( L_shl( L_tmp, exp1 ) ); + exp1 = sub( exp, exp1 ); + L_tmp = Mpy_32_16( exp1, frac, 22713 ); + temp_swb_fac = round_fx( L_shl( L_tmp, 10 ) ); L_feedback = L_mac( L_feedback, temp_swb_fac, temp_swb_fac ); } @@ -3929,6 +3983,7 @@ void swb_tbe_enc_ivas_fx( Copy( GainShape_fx, GainShape_Interp_fx, NUM_SHB_SUBGAINS ); lls_interp_n_fx( GainShape_Interp_fx, NUM_SHB_SUBGAINS, &GainShape_tilt_fx, &temp, 1 ); + test(); IF( EQ_32( st_fx->extl_brate, SWB_TBE_1k10 ) || EQ_32( st_fx->extl_brate, SWB_TBE_1k75 ) ) { // if (acorr_v2a < 0.4f && vf_ind >= 5 && fabs(GainShape_tilt) < 0.2f && shb_env_tilt < 500.0f && hBWE_TD->prev_shb_env_tilt < 500.0f) @@ -3980,6 +4035,7 @@ void swb_tbe_enc_ivas_fx( { /*GainShape_fx[i] = (1 - feedback) * GainShape[i] + feedback * temp_swb_fac; */ GainShape_fx[i] = round_fx( L_mac( L_mult( sub( 32767, feedback ), GainShape_fx[i] ), feedback, temp_swb_fac ) ); + move16(); temp_swb_fac = GainShape_fx[i]; move16(); } @@ -3991,7 +4047,9 @@ void swb_tbe_enc_ivas_fx( { /* Re-normalize gain shape before quantization */ // sum_gain = sum2_f(GainShape, NUM_SHB_SUBGAINS); - sum_gain_fx = sum16_32_fx( GainShape_fx, NUM_SHB_SUBGAINS ); + tmp = 0; + move16(); + sum_gain_fx = sum2_16_exp_fx( GainShape_fx, NUM_SHB_SUBGAINS, &tmp, 2 ); IF( sum_gain_fx == 0 ) { normFact_fx = 0; @@ -4000,8 +4058,6 @@ void swb_tbe_enc_ivas_fx( ELSE { // normFact = (float) sqrt( 1.0f / sum_gain ); - tmp = Q16; - move16(); normFact_fx = ISqrt32( sum_gain_fx, &tmp ); } @@ -4075,8 +4131,8 @@ void swb_tbe_enc_ivas_fx( } /* Estimate the gain parameter */ - EstimateSHBFrameGain_fx( SHB_OVERLAP_LEN, shb_frame_fx, Q_shb, shaped_shb_excitation_fx, Q_bwe_exc, - GainShape_fx, &GainFrame_fx, window_shb_fx, subwin_shb_fx, n_subfr_saturation ); + EstimateSHBFrameGain_ivas_fx( SHB_OVERLAP_LEN, shb_frame_fx, Q_shb, shaped_shb_excitation_fx, Q_bwe_exc, + GainShape_fx, &GainFrame_fx, window_shb_fx, subwin_shb_fx, n_subfr_saturation ); IF( EQ_16( st_fx->tec_tfa, 1 ) ) { @@ -4168,7 +4224,7 @@ void swb_tbe_enc_ivas_fx( frac = L_Extract_lc( L_tmp, &exp ); GainFrame_fx = Pow2( 30, frac ); exp = sub( exp, 30 ); - GainFrame_fx = L_shl( GainFrame_fx, exp + 18 ); /* Q18 */ + GainFrame_fx = L_shl( GainFrame_fx, add( exp, 18 ) ); /* Q18 */ } ELSE IF( EQ_16( hBWE_TD->prev_frGainAtten, 1 ) && GT_32( Mult_32_16( GainFrame_fx, 10923 ), hBWE_TD->prev_gainFr_SHB_fx ) ) { @@ -4291,13 +4347,9 @@ void swb_tbe_enc_ivas_fx( tmp = div_s( shl( 1, sub( 14, exp ) ), voicingBufAvg_fx ); /* (14-exp) */ /* sd_uq_q*pitBufAvg */ - L_tmp = Mult_32_16( L_tmp, pitBufAvg_fx ); /* Q13 * Q10 + 1 -16 => Q8 */ - L_tmp = Mult_32_16( L_tmp, tmp ); /* Q8 + (14 - exp) - 15 => Q7 - exp */ -#ifdef BASOP_NOGLOB + L_tmp = Mult_32_16( L_tmp, pitBufAvg_fx ); /* Q13 * Q10 + 1 -16 => Q8 */ + L_tmp = Mult_32_16( L_tmp, tmp ); /* Q8 + (14 - exp) - 15 => Q7 - exp */ tmp = round_fx_o( L_shl_o( L_tmp, 31 - ( 7 - exp ), &Overflow ), &Overflow ); /* Q15 */ -#else - tmp = round_fx( L_shl( L_tmp, 31 - ( 7 - exp ) ) ); /* Q15 */ -#endif } tmp = s_min( tmp, 32767 /*1.0f Q15*/ ); tmp = s_max( tmp, 19661 /*0.6f Q15*/ ); @@ -4344,7 +4396,7 @@ void swb_tbe_enc_ivas_fx( IF( GE_16( st_fx->element_mode, IVAS_CPE_DFT ) && hStereoICBWE != NULL ) { // Check Qs - Copy_Scale_sig_16_32( lpc_shb_fx, hStereoICBWE->lpSHBRef_fx, LPC_SHB_ORDER + 1, 0 ); + Copy_Scale_sig_16_32_DEPREC( lpc_shb_fx, hStereoICBWE->lpSHBRef_fx, LPC_SHB_ORDER + 1, 0 ); hStereoICBWE->lpSHBRef_e = 31 - Q12; move16(); } @@ -4428,7 +4480,6 @@ void swb_tbe_enc_ivas_fx( /* RETURN ARGUMENTS : */ /* _ None */ /*--------------------------------------------------------------------------*/ - static void EstimateSHBFrameGain_fx( const Word16 length, /* i : SHB overlap length */ const Word16 *oriSHB, /* i : target original SHB frame Q(Q_oriSHB) */ @@ -4455,7 +4506,7 @@ static void EstimateSHBFrameGain_fx( Word16 scaling = 0; #ifdef BASOP_NOGLOB_DECLARE_LOCAL Flag Overflow = 0; - move32(); + move16(); #endif move16(); @@ -4526,7 +4577,7 @@ static void EstimateSHBFrameGain_fx( sum_gain = mult_r( subwin_shb_local[k + 1], subgain[0] ); /* Q15 */ mod_syn[j] = L_mult( synSHB[j], sum_gain ); move32(); /* Q(16+Q_synSHB) */ - j = add( j, 1 ); + j++; } FOR( i = 0; i < NUM_SHB_SUBGAINS - 1; i++ ) { @@ -4534,7 +4585,7 @@ static void EstimateSHBFrameGain_fx( { mod_syn[j] = L_mult( synSHB[j], subgain[i * num_join] ); move32(); /* Q(16+Q_synSHB) */ - j = add( j, 1 ); + j++; } FOR( k = 0; k < length; k++ ) @@ -4543,21 +4594,21 @@ static void EstimateSHBFrameGain_fx( tmp = round_fx( L_mac0( L_tmp, subwin_shb_local[k + 1], subgain[( i + 1 ) * num_join] ) ); /* Q14 */ mod_syn[j] = L_shl( L_mult( tmp, synSHB[j] ), 1 ); move32(); /* Q(16+Q_synSHB) */ - j = add( j, 1 ); + j++; } } FOR( k = 0; k < join_length - length; k++ ) { mod_syn[j] = L_mult( synSHB[j], subgain[( NUM_SHB_SUBGAINS - 1 ) * num_join] ); move32(); /* Q(16+Q_synSHB)*/ - j = add( j, 1 ); + j++; } FOR( k = 0; k < length; k++ ) { tmp = mult_r( subwin_shb_local[length - k - 1], subgain[( NUM_SHB_SUBGAINS - 1 ) * num_join] ); /* Q15 */ mod_syn[j] = L_mult( tmp, synSHB[j] ); move32(); /* Q(16+Q_synSHB ) */ - j = add( j, 1 ); + j++; } } /* adjust frame energy */ @@ -4566,48 +4617,27 @@ static void EstimateSHBFrameGain_fx( FOR( i = 0; i < l_shb_lahead; i++ ) { -#ifdef BASOP_NOGLOB sig = mult_ro( oriSHB[i], win_shb[i], &Overflow ); /* Q_oriSHB */ oriNrg = L_mac0_o( oriNrg, sig, sig, &Overflow ); /* 2*Q_orisHB*/ sig = round_fx_o( Mult_32_16( mod_syn[i], win_shb[i] ), &Overflow ); /*Q_synSHB */ synNrg = L_mac0_o( synNrg, sig, sig, &Overflow ); /* 2*Q_synSHB */ -#else - sig = mult_r( oriSHB[i], win_shb[i] ); /* Q_oriSHB */ - oriNrg = L_mac0( oriNrg, sig, sig ); /* 2*Q_orisHB*/ - sig = round_fx( Mult_32_16( mod_syn[i], win_shb[i] ) ); /*Q_synSHB */ - synNrg = L_mac0( synNrg, sig, sig ); /* 2*Q_synSHB */ -#endif } FOR( ; i < l_frame; i++ ) { -#ifdef BASOP_NOGLOB oriNrg = L_mac0_o( oriNrg, oriSHB[i], oriSHB[i], &Overflow ); /* 2*Q_oriSHB */ sig = round_fx_o( mod_syn[i], &Overflow ); /* Q_oriSHB */ synNrg = L_mac0_o( synNrg, sig, sig, &Overflow ); /* 2*Q_oriSHB */ -#else - oriNrg = L_mac0( oriNrg, oriSHB[i], oriSHB[i] ); /* 2*Q_oriSHB */ - sig = round_fx( mod_syn[i] ); /* Q_oriSHB */ - synNrg = L_mac0( synNrg, sig, sig ); /* 2*Q_oriSHB */ -#endif } tmp = add( l_frame, l_shb_lahead ); FOR( ; i < tmp; i++ ) { -#ifdef BASOP_NOGLOB sig = mult_ro( oriSHB[i], win_shb[l_frame + l_shb_lahead - 1 - i], &Overflow ); /* Q_oriSHB */ oriNrg = L_mac0_o( oriNrg, sig, sig, &Overflow ); /* 2*Q_oriSHB */ sig = round_fx_o( Mult_32_16( mod_syn[i], win_shb[l_frame + l_shb_lahead - 1 - i] ), &Overflow ); /* Q_oriSHB */ synNrg = L_mac0_o( synNrg, sig, sig, &Overflow ); /* 2*Q_oriSHB */ -#else - sig = mult_r( oriSHB[i], win_shb[l_frame + l_shb_lahead - 1 - i] ); /* Q_oriSHB */ - oriNrg = L_mac0( oriNrg, sig, sig ); /* 2*Q_oriSHB */ - - sig = round_fx( Mult_32_16( mod_syn[i], win_shb[l_frame + l_shb_lahead - 1 - i] ) ); /* Q_oriSHB */ - synNrg = L_mac0( synNrg, sig, sig ); /* 2*Q_oriSHB */ -#endif } IF( EQ_32( oriNrg, MAX_32 ) ) { @@ -4616,58 +4646,228 @@ static void EstimateSHBFrameGain_fx( move32(); FOR( i = 0; i < l_shb_lahead; i++ ) { -#ifdef BASOP_NOGLOB sig = mult_r( shl_o( oriSHB[i], scaling, &Overflow ), win_shb[i] ); oriNrg = L_mac0_o( oriNrg, sig, sig, &Overflow ); /* 2*Q_oriSHB + 2*scaling */ -#else - sig = mult_r( shl( oriSHB[i], scaling ), win_shb[i] ); - oriNrg = L_mac0( oriNrg, sig, sig ); /* 2*Q_oriSHB + 2*scaling */ -#endif } FOR( ; i < l_frame; i++ ) { -#ifdef BASOP_NOGLOB sig = shl_o( oriSHB[i], scaling, &Overflow ); oriNrg = L_mac0_o( oriNrg, sig, sig, &Overflow ); /* 2*Q_oriSHB + 2*scaling */ -#else - sig = shl( oriSHB[i], scaling ); - oriNrg = L_mac0( oriNrg, sig, sig ); /* 2*Q_oriSHB + 2*scaling */ -#endif } FOR( ; i < tmp; i++ ) { -#ifdef BASOP_NOGLOB sig = mult_r( shl_o( oriSHB[i], scaling, &Overflow ), win_shb[l_frame + l_shb_lahead - 1 - i] ); oriNrg = L_mac0_o( oriNrg, sig, sig, &Overflow ); /* 2*Q_oriSHB + 2*scaling */ -#else - sig = mult_r( shl( oriSHB[i], scaling ), win_shb[l_frame + l_shb_lahead - 1 - i] ); - oriNrg = L_mac0( oriNrg, sig, sig ); /* 2*Q_oriSHB + 2*scaling */ -#endif } } L_tmp = root_a_over_b_fx( oriNrg, 2 * Q_oriSHB, synNrg, 2 * Q_synSHB, &exp_out ); exp_out = sub( exp_out, scaling ); -#ifdef BASOP_NOGLOB frame_gain = L_shl_sat( L_tmp, sub( exp_out, 13 ) ); /* Q18 */ -#else - frame_gain = L_shl( L_tmp, sub( exp_out, 13 ) ); /* Q18 */ -#endif *GainFrame = frame_gain; move32(); return; } - -static Word32 pow_off_pk_fx( Word16 a[], Word16 len, Word16 step ) -{ - Word16 i, j; - Word32 sum, L_tmp; - - sum = L_shr( L_mult0( a[0], a[0] ), 1 ); /* Q29 */ - - j = 0; - move16(); +static void EstimateSHBFrameGain_ivas_fx( + const Word16 length, /* i : SHB overlap length */ + const Word16 *oriSHB, /* i : target original SHB frame Q(Q_oriSHB) */ + const Word16 Q_oriSHB, /* i : Q of arget original SHB frame */ + const Word16 *synSHB, /* i : shaped SHB excitation Q(Q_synSHB) */ + const Word16 Q_synSHB, /* i : Q of shaped SHB excitation */ + Word16 *subgain, /* i : estimate of gain shape Q15 */ + Word32 *GainFrame, /* o : estimat of gain frame Q18 */ + const Word16 *win_shb, /* i : SHB window Q15 */ + const Word16 *subwin_shb_local, /* i : SHB subframe window Q15 */ + const Word16 n_subfr_saturation /* i : Number of subframes which saturated in GainShape oriNrg calculation */ +) +{ + const Word16 *skip; + Word16 i, j, k, l_shb_lahead, l_frame; + Word16 join_length, num_join, sig; + Word32 mod_syn[L_FRAME16k + L_SHB_LAHEAD]; + Word32 oriNrg, synNrg; + Word16 sum_gain; + Word32 frame_gain; + Word32 L_tmp; + Word16 exp_out; + Word16 tmp; + Word16 scaling = 0; +#ifdef BASOP_NOGLOB_DECLARE_LOCAL + Flag Overflow = 0; + move32(); +#endif + move16(); + + /* initilaization */ + l_frame = L_FRAME16k; + move16(); + l_shb_lahead = L_SHB_LAHEAD; + move16(); + skip = skip_bands_SWB_TBE; + + IF( EQ_16( length, SHB_OVERLAP_LEN / 2 ) ) + { + skip = skip_bands_WB_TBE; + l_frame = L_FRAME16k / 4; + move16(); + l_shb_lahead = L_SHB_LAHEAD / 4; + move16(); + } + + /* apply gain for each subframe, and store noise output signal using overlap-add*/ + set32_fx( mod_syn, 0, l_frame + l_shb_lahead ); + + IF( EQ_16( length, SHB_OVERLAP_LEN / 2 ) ) + { + sum_gain = 0; + move16(); + j = skip[0]; + move16(); + FOR( k = 0; k < length / 2; k++ ) + { + sum_gain = mult_r( subwin_shb_local[2 * k + 2], subgain[0] ); /* Q15 */ + mod_syn[j + k] = L_mult0( synSHB[j + k], sum_gain ); + move32(); /* Q(16+Q_synSHB) */ + mod_syn[j + k + length / 2] = L_mult0( synSHB[j + k + length / 2], subgain[0] ); + move32(); /* Q(16+Q_synSHB) */ + } + + FOR( i = 1; i < NUM_SHB_SUBFR / 2; i++ ) + { + j = skip[i]; + move16(); + FOR( k = 0; k < length; k++ ) + { + L_tmp = L_mult0( subwin_shb_local[k + 1], subgain[i] ); /* Q30 */ + sum_gain = round_fx( L_mac0( L_tmp, subwin_shb_local[length - k - 1], subgain[i - 1] ) ); /* Q14 */ + mod_syn[j + k] = L_mult( sum_gain, synSHB[j + k] ); + move32(); /* Q(16+Q_synSHB) */ + } + } + FOR( k = 0; k < length / 2; k++ ) + { + j = skip[i]; + move16(); + sum_gain = mult_r( subwin_shb_fx[length - 2 * k - 2], subgain[i - 1] ); /* Q15 */ + mod_syn[j + k] = L_mult0( synSHB[j + k], sum_gain ); + move32(); /* Q(16+Q_synSHB) */ + } + } + ELSE + { + num_join = NUM_SHB_SUBFR / NUM_SHB_SUBGAINS; + move16(); + join_length = i_mult2( num_join, length ); + j = 0; + move16(); + FOR( k = 0; k < length; k++ ) + { + sum_gain = mult_r( subwin_shb_local[k + 1], subgain[0] ); /* Q15 */ + mod_syn[j] = L_mult0( synSHB[j], sum_gain ); + move32(); /* Q(16+Q_synSHB) */ + j++; + } + FOR( i = 0; i < NUM_SHB_SUBGAINS - 1; i++ ) + { + FOR( k = 0; k < join_length - length; k++ ) + { + mod_syn[j] = L_mult0( synSHB[j], subgain[i * num_join] ); + move32(); /* Q(16+Q_synSHB) */ + j++; + } + + FOR( k = 0; k < length; k++ ) + { + L_tmp = L_mult0( subwin_shb_local[length - k - 1], subgain[i * num_join] ); + tmp = round_fx( L_mac0( L_tmp, subwin_shb_local[k + 1], subgain[( i + 1 ) * num_join] ) ); /* Q14 */ + mod_syn[j] = L_mult( tmp, synSHB[j] ); + move32(); /* Q(16+Q_synSHB) */ + j++; + } + } + FOR( k = 0; k < join_length - length; k++ ) + { + mod_syn[j] = L_mult0( synSHB[j], subgain[( NUM_SHB_SUBGAINS - 1 ) * num_join] ); + move32(); /* Q(16+Q_synSHB)*/ + j++; + } + FOR( k = 0; k < length; k++ ) + { + tmp = mult_r( subwin_shb_local[length - k - 1], subgain[( NUM_SHB_SUBGAINS - 1 ) * num_join] ); /* Q15 */ + mod_syn[j] = L_mult0( tmp, synSHB[j] ); + move32(); /* Q(16+Q_synSHB ) */ + j++; + } + } + /* adjust frame energy */ + oriNrg = L_deposit_l( 0 ); + synNrg = L_deposit_l( 0 ); + + FOR( i = 0; i < l_shb_lahead; i++ ) + { + sig = mult_ro( oriSHB[i], win_shb[i], &Overflow ); /* Q_oriSHB */ + oriNrg = L_mac0_o( oriNrg, sig, sig, &Overflow ); /* 2*Q_orisHB*/ + sig = round_fx_o( Mult_32_16( mod_syn[i], win_shb[i] ), &Overflow ); /*Q_synSHB */ + synNrg = L_mac0_o( synNrg, sig, sig, &Overflow ); /* 2*Q_synSHB - 2*/ + } + + FOR( ; i < l_frame; i++ ) + { + oriNrg = L_mac0_o( oriNrg, oriSHB[i], oriSHB[i], &Overflow ); /* 2*Q_oriSHB */ + sig = round_fx_o( mod_syn[i], &Overflow ); /* Q_oriSHB */ + synNrg = L_mac0_o( synNrg, sig, sig, &Overflow ); /* 2*Q_oriSHB - 2*/ + } + + tmp = add( l_frame, l_shb_lahead ); + FOR( ; i < tmp; i++ ) + { + sig = mult_ro( oriSHB[i], win_shb[l_frame + l_shb_lahead - 1 - i], &Overflow ); /* Q_oriSHB */ + oriNrg = L_mac0_o( oriNrg, sig, sig, &Overflow ); /* 2*Q_oriSHB */ + + sig = round_fx_o( Mult_32_16( mod_syn[i], win_shb[l_frame + l_shb_lahead - 1 - i] ), &Overflow ); /* Q_oriSHB */ + synNrg = L_mac0_o( synNrg, sig, sig, &Overflow ); /* 2*Q_oriSHB - 2*/ + } + IF( EQ_32( oriNrg, MAX_32 ) ) + { + scaling = negate( add( shr( n_subfr_saturation, 1 ), 1 ) ); + oriNrg = 0; + move32(); + FOR( i = 0; i < l_shb_lahead; i++ ) + { + sig = mult_r( shl_o( oriSHB[i], scaling, &Overflow ), win_shb[i] ); + oriNrg = L_mac0_o( oriNrg, sig, sig, &Overflow ); /* 2*Q_oriSHB + 2*scaling */ + } + FOR( ; i < l_frame; i++ ) + { + sig = shl_o( oriSHB[i], scaling, &Overflow ); + oriNrg = L_mac0_o( oriNrg, sig, sig, &Overflow ); /* 2*Q_oriSHB + 2*scaling */ + } + FOR( ; i < tmp; i++ ) + { + sig = mult_r( shl_o( oriSHB[i], scaling, &Overflow ), win_shb[l_frame + l_shb_lahead - 1 - i] ); + oriNrg = L_mac0_o( oriNrg, sig, sig, &Overflow ); /* 2*Q_oriSHB + 2*scaling */ + } + } + L_tmp = root_a_over_b_fx( oriNrg, shl( Q_oriSHB, 1 ), synNrg, sub( shl( Q_synSHB, 1 ), 2 ), &exp_out ); + exp_out = sub( exp_out, scaling ); + frame_gain = L_shl_sat( L_tmp, sub( exp_out, 13 ) ); /* Q18 */ + *GainFrame = frame_gain; + move32(); + + return; +} + + +static Word32 pow_off_pk_fx( Word16 a[], Word16 len, Word16 step ) +{ + Word16 i, j; + Word32 sum, L_tmp; + + sum = L_shr( L_mult0( a[0], a[0] ), 1 ); /* Q29 */ + + j = 0; + move16(); FOR( i = 1; i < len; i += step ) { L_tmp = L_shr( L_mult0( a[i], a[i] ), 1 ); /* Q29 */ @@ -4790,7 +4990,7 @@ static void EstimateSHBGainShape_fx( FOR( i = 0; i < NUM_SHB_SUBFR / 2; i++ ) { logic16(); - IF( ( i & 0x1 ) == 0 ) + IF( s_and( i, 0x1 ) == 0 ) { oriNrg = 0; move32(); @@ -4804,31 +5004,18 @@ static void EstimateSHBGainShape_fx( FOR( k = 0; k < length / 2; k++ ) { sig = mult_r( oriSHB[j + k], subwin[2 * k + 2] ); /* Q_oriSHB */ -#ifdef BASOP_NOGLOB oriNrg = L_mac0_sat( oriNrg, sig, sig ); /* 2* Q_oriSHB */ sig = mult_r( synSHB[j + k], subwin[2 * k + 2] ); /* Q_synSHB */ synNrg = L_mac0_sat( synNrg, sig, sig ); /* 2* Q_synSHB */ -#else - oriNrg = L_mac0( oriNrg, sig, sig ); /* 2* Q_oriSHB */ - sig = mult_r( synSHB[j + k], subwin[2 * k + 2] ); /* Q_synSHB */ - synNrg = L_mac0( synNrg, sig, sig ); /* 2* Q_synSHB */ -#endif } FOR( k = length / 2; k < length; k++ ) { sig = oriSHB[j + k]; move16(); -#ifdef BASOP_NOGLOB oriNrg = L_mac0_sat( oriNrg, sig, sig ); /* 2* Q_oriSHB */ sig = synSHB[j + k]; move16(); synNrg = L_mac0_sat( synNrg, sig, sig ); /* 2* Q_synSHB */ -#else - oriNrg = L_mac0( oriNrg, sig, sig ); /* 2* Q_oriSHB */ - sig = synSHB[j + k]; - move16(); - synNrg = L_mac0( synNrg, sig, sig ); /* 2* Q_synSHB */ -#endif } } ELSE @@ -4836,17 +5023,9 @@ static void EstimateSHBGainShape_fx( FOR( k = 0; k < length; k++ ) { sig = mult_r( oriSHB[j + k], subwin[k + 1] ); /* Q_oriSHB */ -#ifdef BASOP_NOGLOB - oriNrg = L_mac0_sat( oriNrg, sig, sig ); /* 2* Q_oriSHB */ -#else - oriNrg = L_mac0( oriNrg, sig, sig ); /* 2* Q_oriSHB */ -#endif + oriNrg = L_mac0_sat( oriNrg, sig, sig ); /* 2* Q_oriSHB */ sig = mult_r( synSHB[j + k], subwin[k + 1] ); /* Q_synSHB */ -#ifdef BASOP_NOGLOB - synNrg = L_mac0_sat( synNrg, sig, sig ); /* 2* Q_synSHB */ -#else - synNrg = L_mac0( synNrg, sig, sig ); /* 2* Q_synSHB */ -#endif + synNrg = L_mac0_sat( synNrg, sig, sig ); /* 2* Q_synSHB */ } } IF( EQ_16( i, NUM_SHB_SUBFR / 2 - 1 ) ) @@ -4855,18 +5034,10 @@ static void EstimateSHBGainShape_fx( FOR( ; k < length_tmp; k++ ) { sig = mult_r( oriSHB[j + k], subwin[3 * length - 2 * k - 2] ); /* Q_oriSHB */ -#ifdef BASOP_NOGLOB - oriNrg = L_mac0_sat( oriNrg, sig, sig ); /* 2* Q_oriSHB */ -#else - oriNrg = L_mac0( oriNrg, sig, sig ); /* 2* Q_oriSHB */ -#endif + oriNrg = L_mac0_sat( oriNrg, sig, sig ); /* 2* Q_oriSHB */ sig = mult_r( synSHB[j + k], subwin[3 * length - 2 * k - 2] ); /* Q_synSHB */ -#ifdef BASOP_NOGLOB - synNrg = L_mac0_sat( synNrg, sig, sig ); /* 2* Q_synSHB */ -#else - synNrg = L_mac0( synNrg, sig, sig ); /* 2* Q_synSHB */ -#endif + synNrg = L_mac0_sat( synNrg, sig, sig ); /* 2* Q_synSHB */ } } ELSE @@ -4874,28 +5045,20 @@ static void EstimateSHBGainShape_fx( FOR( ; k < length2; k++ ) { sig = mult_r( oriSHB[j + k], subwin[2 * length - k - 1] ); /* Q_oriSHB */ -#ifdef BASOP_NOGLOB - oriNrg = L_mac0_sat( oriNrg, sig, sig ); /* 2* Q_oriSHB */ -#else - oriNrg = L_mac0( oriNrg, sig, sig ); /* 2* Q_oriSHB */ -#endif + oriNrg = L_mac0_sat( oriNrg, sig, sig ); /* 2* Q_oriSHB */ sig = mult_r( synSHB[j + k], subwin[2 * length - k - 1] ); /* Q_synSHB */ -#ifdef BASOP_NOGLOB - synNrg = L_mac0_sat( synNrg, sig, sig ); /* 2* Q_synSHB */ -#else - synNrg = L_mac0( synNrg, sig, sig ); /* 2* Q_synSHB */ -#endif + synNrg = L_mac0_sat( synNrg, sig, sig ); /* 2* Q_synSHB */ } } logic16(); - IF( EQ_16( ( i & 0x1 ), 1 ) ) + IF( EQ_16( s_and( i, 0x1 ), 1 ) ) { L_subgain[i / 2] = root_a_over_b_fx( oriNrg, shl( Q_oriSHB, 1 ), synNrg, shl( Q_synSHB, 1 ), &n ); move16(); /* Q(31-n) */ norm[i / 2] = n; move16(); - IF( GT_16( norm[i / 2], n_max ) ) + if ( GT_16( norm[i / 2], n_max ) ) { n_max = norm[i / 2]; move16(); @@ -4916,50 +5079,26 @@ static void EstimateSHBGainShape_fx( j = i_mult2( join_length, i ); FOR( k = 0; k < length; k++ ) { - sig = mult_r( oriSHB[j + k], subwin[k + 1] ); /* Q_oriSHB */ -#ifdef BASOP_NOGLOB + sig = mult_r( oriSHB[j + k], subwin[k + 1] ); /* Q_oriSHB */ oriNrg = L_mac0_o( oriNrg, sig, sig, &Overflow ); /* 2* Q_oriSHB */ -#else - oriNrg = L_mac0( oriNrg, sig, sig ); /* 2* Q_oriSHB */ -#endif - sig = mult_r( synSHB[j + k], subwin[k + 1] ); /* Q_oriSHB */ -#ifdef BASOP_NOGLOB + sig = mult_r( synSHB[j + k], subwin[k + 1] ); /* Q_oriSHB */ synNrg = L_mac0_o( synNrg, sig, sig, &Overflow ); /* 2* Q_oriSHB */ -#else - synNrg = L_mac0( synNrg, sig, sig ); /* 2* Q_oriSHB */ -#endif } FOR( k = 0; k < ( join_length - length ); k++ ) { - sig = mult_r( oriSHB[length + j + k], 32767 ); /* Q_oriSHB */ -#ifdef BASOP_NOGLOB + sig = mult_r( oriSHB[length + j + k], 32767 ); /* Q_oriSHB */ oriNrg = L_mac0_o( oriNrg, sig, sig, &Overflow ); /* 2* Q_oriSHB */ -#else - oriNrg = L_mac0( oriNrg, sig, sig ); /* 2* Q_oriSHB */ -#endif - sig = mult_r( synSHB[length + j + k], 32767 ); /* Q_oriSHB */ -#ifdef BASOP_NOGLOB + sig = mult_r( synSHB[length + j + k], 32767 ); /* Q_oriSHB */ synNrg = L_mac0_o( synNrg, sig, sig, &Overflow ); /* 2* Q_oriSHB */ -#else - synNrg = L_mac0( synNrg, sig, sig ); /* 2* Q_oriSHB */ -#endif } FOR( k = 0; k < length; k++ ) { sig = mult_r( oriSHB[j + join_length + k], subwin[length - k - 1] ); /* Q_oriSHB */ -#ifdef BASOP_NOGLOB - oriNrg = L_mac0_o( oriNrg, sig, sig, &Overflow ); /* 2* Q_oriSHB */ -#else - oriNrg = L_mac0( oriNrg, sig, sig ); /* 2* Q_oriSHB */ -#endif + oriNrg = L_mac0_o( oriNrg, sig, sig, &Overflow ); /* 2* Q_oriSHB */ sig = mult_r( synSHB[j + join_length + k], subwin[length - k - 1] ); /* Q_oriSHB */ -#ifdef BASOP_NOGLOB - synNrg = L_mac0_o( synNrg, sig, sig, &Overflow ); /* 2* Q_oriSHB */ -#else - synNrg = L_mac0( synNrg, sig, sig ); /* 2* Q_oriSHB */ -#endif + synNrg = L_mac0_o( synNrg, sig, sig, &Overflow ); /* 2* Q_oriSHB */ } /* Only implemented in SWB because the length of samples in SWB frame is longer, more likely to saturate */ scaling = 0; @@ -4978,29 +5117,17 @@ static void EstimateSHBGainShape_fx( FOR( k = 0; k < length; k++ ) { sig = mult_r( oriSHB[j + k], subwin[k + 1] ); -#ifdef BASOP_NOGLOB oriNrg = L_mac0_sat( oriNrg, sig, sig ); /* 2*Q_oriSHB - 2*/ -#else - oriNrg = L_mac0( oriNrg, sig, sig ); /* 2*Q_oriSHB - 2*/ -#endif } FOR( k = 0; k < ( join_length - length ); k++ ) { sig = shr( oriSHB[length + j + k], 1 ); -#ifdef BASOP_NOGLOB oriNrg = L_mac0_sat( oriNrg, sig, sig ); /* 2*Q_oriSHB - 2*/ -#else - oriNrg = L_mac0( oriNrg, sig, sig ); /* 2*Q_oriSHB - 2*/ -#endif } FOR( k = 0; k < length; k++ ) { sig = mult_r( shr( oriSHB[j + join_length + k], 1 ), subwin[length - k - 1] ); /* Q_oriSHB - 1(scaling) */ -#ifdef BASOP_NOGLOB - oriNrg = L_mac0_sat( oriNrg, sig, sig ); /* 2*Q_oriSHB - 2 */ -#else - oriNrg = L_mac0( oriNrg, sig, sig ); /* 2*Q_oriSHB - 2 */ -#endif + oriNrg = L_mac0_sat( oriNrg, sig, sig ); /* 2*Q_oriSHB - 2 */ } } L_subgain[i] = root_a_over_b_fx( oriNrg, shl( Q_oriSHB, 1 ), synNrg, shl( Q_synSHB, 1 ), &n ); @@ -5008,7 +5135,7 @@ static void EstimateSHBGainShape_fx( n = sub( n, scaling ); norm[i] = n; move16(); - IF( GT_16( norm[i], n_max ) ) + if ( GT_16( norm[i], n_max ) ) { n_max = norm[i]; move16(); @@ -5018,13 +5145,8 @@ static void EstimateSHBGainShape_fx( FOR( i = 0; i < num_gains; i++ ) { -#ifdef BASOP_NOGLOB subgain[i] = round_fx_o( L_shl_o( L_subgain[i], sub( norm[i], n_max + 1 ), &Overflow ), &Overflow ); /* Q(14-n_max) */ L_sum_gain = L_mac0_o( L_sum_gain, subgain[i], subgain[i], &Overflow ); /* Q(28-2*n_max) */ -#else - subgain[i] = round_fx( L_shl( L_subgain[i], sub( norm[i], n_max + 1 ) ) ); /* Q(14-n_max) */ - L_sum_gain = L_mac0( L_sum_gain, subgain[i], subgain[i] ); /* Q(28-2*n_max) */ -#endif move16(); } @@ -5036,12 +5158,8 @@ static void EstimateSHBGainShape_fx( FOR( i = 0; i < num_gains; i++ ) { - L_tmp = Mpy_32_16_1( normFact, subgain[i] ); /*Q(31-n) * Q(31-norm[i]) */ /* Q(30-n-n_max) */ -#ifdef BASOP_NOGLOB + L_tmp = Mpy_32_16_1( normFact, subgain[i] ); /*Q(31-n) * Q(31-norm[i]) */ /* Q(30-n-n_max) */ subgain[i] = s_max( round_fx_o( L_shl_o( L_tmp, add( n, n_max + 1 ), &Overflow ), &Overflow ), 3277 /*0.1f Q15*/ ); /* Q15 */ -#else - subgain[i] = s_max( round_fx( L_shl( L_tmp, add( n, n_max + 1 ) ) ), 3277 /*0.1f Q15*/ ); /* Q15 */ -#endif move16(); } @@ -5210,6 +5328,7 @@ static void QuantizeSHBsubgains_fx( exp = sub( -1, exp ); L_tmp = Mpy_32_16( exp, frac, 24660 ); /* Q13 ; 20.0 * log10(2) in Q12*/ subgains[i + NUM_SHB_SUBFR / 4] = round_fx( L_shl( L_tmp, 11 ) ); /* Q8 */ + move16(); } } idxSubGain = closest_centroid_lc_fx( subgains + NUM_SHB_SUBFR / 4, HBCB_SubGain5bit_fx, 1 << NUM_BITS_SHB_SUBGAINS ); @@ -5223,10 +5342,11 @@ static void QuantizeSHBsubgains_fx( L_tmp = L_shr( L_tmp, 10 ); /* From Q26 to Q16 */ frac = L_Extract_lc( L_tmp, &exp ); subgains[i] = extract_l( Pow2( 14, frac ) ); + move16(); /* Put 14 as exponent so that */ /* output of Pow2() will be: */ /* 16384 < Pow2() <= 32767 */ - subgains[i] = shl( subgains[i], exp + 1 ); + subgains[i] = shl( subgains[i], add( exp, 1 ) ); move16(); /*Q15 */ } @@ -5255,6 +5375,7 @@ static void QuantizeSHBsubgains_fx( L_tmp = Mpy_32_16( exp, frac, 9864 ); /*move32(); // Q16 ; log10(2) in Q15 */ subgains[i] = round_fx( L_shl( L_tmp, 12 ) ); /*Q12 */ + move16(); } } @@ -5266,10 +5387,11 @@ static void QuantizeSHBsubgains_fx( L_tmp = L_shr( L_tmp, 10 ); /* From Q26 to Q16 */ frac = L_Extract_lc( L_tmp, &exp ); subgains[i] = extract_l( Pow2( 14, frac ) ); + move16(); /* Put 14 as exponent so that */ /* output of Pow2() will be: */ /* 16384 < Pow2() <= 32767 */ - subgains[i] = shl( subgains[i], exp + 1 ); + subgains[i] = shl( subgains[i], add( exp, 1 ) ); move16(); /*Q15 */ } @@ -5359,7 +5481,7 @@ static void QuantizeSHBsubgains_ivas_fx( /* Put 14 as exponent so that */ /* output of Pow2() will be: */ /* 16384 < Pow2() <= 32767 */ - subgains[i] = shl( subgains[i], exp + 1 ); + subgains[i] = shl( subgains[i], add( exp, 1 ) ); move16(); /*Q15 */ } @@ -5404,7 +5526,7 @@ static void QuantizeSHBsubgains_ivas_fx( /* Put 14 as exponent so that */ /* output of Pow2() will be: */ /* 16384 < Pow2() <= 32767 */ - subgains[i] = shl( subgains[i], exp + 1 ); + subgains[i] = shl( subgains[i], add( exp, 1 ) ); move16(); /*Q15 */ } @@ -5450,6 +5572,7 @@ static void Quant_shb_ener_sf_fx( /* shb_ener_sf_fx[0] = log10(0.003125*shb_ener_sf[0:319]); */ sum = *shb_ener_sf_Q31; /* L_tmp in Q_ener = (2*Q_shb+1) */ + move32(); exp = norm_l( sum ); frac = Log2_norm_lc( L_shl( sum, exp ) ); @@ -5469,7 +5592,9 @@ static void Quant_shb_ener_sf_fx( L_tmp = L_shl( L_tmp, -10 ); /* bring L_tmp from Q26 to Q16 */ frac = L_Extract_lc( L_tmp, &exp ); /* Extract exponent */ L_tmp = Pow2( 14, frac ); - *shb_ener_sf_Q31 = L_shl( L_tmp, exp - 14 + Q_ener ); /* In Q_ener */ + // *shb_ener_sf_Q31 = L_shl( L_tmp, exp - 14 + Q_ener ); /* In Q_ener */ + *shb_ener_sf_Q31 = L_shl( L_tmp, add( sub( exp, 14 ), Q_ener ) ); /* In Q_ener */ + move32(); hBWE_TD->idx_shb_fr_gain = idxSubEner_fx; move16(); @@ -5513,7 +5638,7 @@ static void Quant_shb_ener_sf_ivas_fx( temp_shb_ener_sf_fx = 0; move16(); - idxSubEner_fx = usquant_fx( tmp, &temp_shb_ener_sf_fx, 0, 43, shl( 1, NUM_BITS_SHB_ENER_SF ) ); /* 43 = 0.042f in Q10 = Qin-1 */ + idxSubEner_fx = usquant_fx( tmp, &temp_shb_ener_sf_fx, 0, 43, 1 << NUM_BITS_SHB_ENER_SF ); /* 43 = 0.042f in Q10 = Qin-1 */ /* o: temp_shb_ener_sf_fx in Q11 */ /* shb_ener_sf_fx[0] = pow(10.0, temp_shb_ener_sf_fx ); */ @@ -5556,8 +5681,10 @@ static void Quant_shb_res_gshape_fx( 2048 /*0.125f Q14*/, /*2048 = 0.125 in Q14 */ 1024 /*0.125f Q13*/, /*1024 = 0.125 in Q13 */ shl( 1, NUM_BITS_SHB_RES_GS ) ); + move16(); hBWE_TD->idx_res_gs[i] = idxSubGain_fx[i]; + move16(); IF( NE_16( st_fx->codec_mode, MODE2 ) ) { push_indice_fx( st_fx->hBstr, IND_SHB_RES_GS1 + i, idxSubGain_fx[i], NUM_BITS_SHB_RES_GS ); @@ -5589,7 +5716,7 @@ static void Quant_shb_res_gshape_ivas_fx( shl( 1, NUM_BITS_SHB_RES_GS ) ); move16(); - IF( st->codec_mode == MODE2 ) + IF( EQ_16( st->codec_mode, MODE2 ) ) { hBWE_TD->idx_res_gs[i] = idxSubGain_fx[i]; move16(); @@ -5633,6 +5760,7 @@ static void QuantizeSHBframegain_fx( Word16 idxFrameGain; Word32 Q_GainFrame; Word16 Unit_weights1 = 1; + move16(); Word16 exp, frac, tmp; Word32 L_tmp; Word32 GainFrameLog; @@ -5679,7 +5807,8 @@ static void QuantizeSHBframegain_fx( { exp = norm_l( *GainFrame ); frac = Log2_norm_lc( L_shl( *GainFrame, exp ) ); - exp = ( 30 - exp - 18 ); + // exp = ( 30 - exp - 18 ); + exp = sub( 30 - 18, exp ); GainFrameLog = Mpy_32_16( exp, frac, 9864 ); /*GainFrameLog= round_fx(L_shl(L_tmp,12)); //Q12 */ } @@ -5690,7 +5819,8 @@ static void QuantizeSHBframegain_fx( idxFrameGain = extract_l( L_shr( L_add( L_tmp, shl( 1, sub( 14, exp ) ) ), sub( 15, exp ) ) ); /*Q0*/ IF( GT_16( idxFrameGain, ( 1 << NUM_BITS_SHB_FRAMEGAIN ) - 1 ) ) { - idxFrameGain = sub( ( 1 << NUM_BITS_SHB_FRAMEGAIN ), 1 ); + idxFrameGain = ( 1 << NUM_BITS_SHB_FRAMEGAIN ) - 1; + move16(); } ELSE { @@ -5704,9 +5834,11 @@ static void QuantizeSHBframegain_fx( L_tmp = SHB_GAIN_QLOW_FX_16; Q_GainFrame = L_mac( L_tmp, idxFrameGain, SHB_GAIN_QDELTA_FX_15 ); + test(); WHILE( GT_32( Q_GainFrame, L_add( GainFrameLog, 4866 ) ) && idxFrameGain != 0 ) { + test(); idxFrameGain = sub( idxFrameGain, 1 ); Q_GainFrame = L_mac0( SHB_GAIN_QLOW_FX_16, idxFrameGain, SHB_GAIN_QDELTA_FX_16 ); } @@ -5718,7 +5850,7 @@ static void QuantizeSHBframegain_fx( frac = L_Extract_lc( L_tmp, &exp ); Q_GainFrame = Pow2( 30, frac ); exp = sub( exp, 30 ); - Q_GainFrame = L_shl( Q_GainFrame, exp + 18 ); /* Q18 */ + Q_GainFrame = L_shl( Q_GainFrame, add( exp, 18 ) ); /* Q18 */ hBWE_TD->idxFrameGain = idxFrameGain; move16(); @@ -5727,12 +5859,14 @@ static void QuantizeSHBframegain_fx( push_indice_fx( st_fx->hBstr, IND_SHB_FRAMEGAIN, idxFrameGain, NUM_BITS_SHB_FRAMEGAIN ); } *rf_gainFrame_ind = idxFrameGain; + move16(); } IF( EQ_16( st_fx->rf_mode, 1 ) ){ /*Currently intended for SWB only. Modify for WB is needed later!*/ IF( EQ_16( hRF->rf_frame_type, RF_NELP ) ){ *rf_gainFrame_ind = idxFrameGain; /* NELP Frame uses full 5 bits */ + move16(); } ELSE /*RF_ALLPRED, RF_GENPRED, RF_NOPRED modes*/ { @@ -5752,6 +5886,7 @@ ELSE /*RF_ALLPRED, RF_GENPRED, RF_NOPRED modes*/ { *rf_gainFrame_ind = 3; } + move16(); } } @@ -5812,7 +5947,7 @@ static void QuantizeSHBframegain_ivas_fx( 1 << NUM_BITS_SHB_FrameGain_LBR_WB, &idxFrameGain, &Q_GainFrame, SHBCB_FrameGain16_fx ); test(); - IF( GT_32( Q_GainFrame, L_shl( Mult_32_16( *GainFrame, 17367 ), 1 ) ) && idxFrameGain > 0 ) /* 1.06 = +0.5 dB */ + IF( GT_64( W_deposit32_l( Q_GainFrame ), W_shl( W_mult_32_16( *GainFrame, 17367 ), 15 ) ) && idxFrameGain > 0 ) /* 1.06 = +0.5 dB */ { idxFrameGain--; Q_GainFrame = L_add( SHBCB_FrameGain16_fx[idxFrameGain], 0 ); /* Q18 */ @@ -5860,7 +5995,7 @@ static void QuantizeSHBframegain_ivas_fx( { exp = norm_l( *GainFrame ); frac = Log2_norm_lc( L_shl( *GainFrame, exp ) ); - exp = ( 30 - exp - 18 ); + exp = sub( 30 - 18, exp ); GainFrameLog = Mpy_32_16( exp, frac, 9864 ); /*GainFrameLog= round_fx(L_shl(L_tmp,12)); //Q12 */ } @@ -5914,10 +6049,11 @@ static void QuantizeSHBframegain_ivas_fx( Q_GainFrame = L_mac( L_tmp, idxFrameGain, SHB_GAIN_QDELTA_FX_15 ); } - + test(); WHILE( GT_32( Q_GainFrame, L_add( GainFrameLog, 4866 ) ) && idxFrameGain != 0 ) { + test(); idxFrameGain = sub( idxFrameGain, 1 ); Q_GainFrame = L_mac0( SHB_GAIN_QLOW_FX_16, idxFrameGain, SHB_GAIN_QDELTA_FX_16 ); } @@ -5938,7 +6074,7 @@ static void QuantizeSHBframegain_ivas_fx( frac = L_Extract_lc( L_tmp, &exp ); Q_GainFrame = Pow2( 30, frac ); exp = sub( exp, 30 ); - Q_GainFrame = L_shl( Q_GainFrame, exp + 18 ); /* Q18 */ + Q_GainFrame = L_shl( Q_GainFrame, add( exp, 18 ) ); /* Q18 */ IF( EQ_16( st_fx->codec_mode, MODE2 ) ) { @@ -6030,6 +6166,7 @@ static void determine_gain_weights_fx( Word32 L_tmp; #ifdef BASOP_NOGLOB_DECLARE_LOCAL Flag Overflow = 0; + move16(); #endif FOR( j = 0; j < dims; j++ ) @@ -6040,22 +6177,18 @@ static void determine_gain_weights_fx( exp1 = norm_l( gain[j] ); frac = Log2_norm_lc( L_shl( gain[j], exp1 ) ); move16(); - exp = 30 - exp1 - 18; + exp = sub( 30 - 18, exp1 ); move16(); L_tmp = Mpy_32_16( exp, frac, -29491 ); /* Q16 */ frac = L_Extract_lc( L_tmp, &exp ); tmp = extract_l( Pow2( 14, frac ) ); /* Q14 */ exp2 = sub( exp, 8 ); - if ( LE_16( exp1, 21 ) ) + IF( LE_16( exp1, 21 ) ) { exp2 = sub( exp, 2 ); } -#ifdef BASOP_NOGLOB weights[j] = shl_o( tmp, exp2, &Overflow ); -#else - weights[j] = shl( tmp, exp2 ); -#endif move16(); /* Q12 */ } ELSE @@ -6331,7 +6464,7 @@ static Word16 Find_LSF_grid_fx( exp = norm_s( m ); tmp = div_s( shl( 1, sub( 14, exp ) ), m ); L_tmp = L_mult( sub( MAX_LSF_FX, m ), tmp ); - scale = round_fx( L_shl( L_tmp, exp + 1 ) ); + scale = round_fx( L_shl( L_tmp, add( exp, 1 ) ) ); FOR( i = 0; i < NUM_MAP_LSF; i++ ) { @@ -6476,6 +6609,7 @@ static void gainFrSmooth_En_fx( Encoder_State *st_fx, tempQ31 = L_mac( tempQ31, hBWE_TD->lsp_shb_spacing_fx[1], 6553 ); /* 0.2f */ tempQ31 = L_mac( tempQ31, hBWE_TD->lsp_shb_spacing_fx[2], 9830 ); /* 0.3f */ *MA_lsp_shb_spacing = mac_r( tempQ31, lsp_spacing, 13107 ); /* 0.4f */ + move16(); hBWE_TD->lsp_shb_spacing_fx[0] = hBWE_TD->lsp_shb_spacing_fx[1]; move16(); @@ -6503,7 +6637,7 @@ static void gainFrSmooth_En_fx( Encoder_State *st_fx, } test(); - IF( LT_32( lsp_slow_evol_rate, 2147484l /*0.001f Q31*/ ) && LT_32( lsp_fast_evol_rate, 2147484l /*0.001f Q31*/ ) ) + if ( LT_32( lsp_slow_evol_rate, 2147484l /*0.001f Q31*/ ) && LT_32( lsp_fast_evol_rate, 2147484l /*0.001f Q31*/ ) ) { *frGainSmoothEn = 1; move16(); @@ -6602,6 +6736,7 @@ static void gainFrSmooth_En_ivas_fx( Encoder_State *st_fx, tempQ31 = L_mac( tempQ31, hBWE_TD->lsp_shb_spacing_fx[1], 6553 ); /* 0.2f in Q15 */ tempQ31 = L_mac( tempQ31, hBWE_TD->lsp_shb_spacing_fx[2], 9830 ); /* 0.3f in Q15 */ *MA_lsp_shb_spacing = mac_r( tempQ31, lsp_spacing, 13107 ); /* 0.4f in Q15 */ + move16(); hBWE_TD->lsp_shb_spacing_fx[0] = hBWE_TD->lsp_shb_spacing_fx[1]; move16(); @@ -6629,7 +6764,7 @@ static void gainFrSmooth_En_ivas_fx( Encoder_State *st_fx, } test(); - IF( ( BASOP_Util_Cmp_Mant32Exp( lsp_slow_evol_rate, lsp_slow_evol_rate_e, 2147484l /*0.001f in Q31*/, 0 ) < 0 ) && ( BASOP_Util_Cmp_Mant32Exp( lsp_fast_evol_rate, lsp_fast_evol_rate_e, 2147484l /*0.001f in Q31*/, 0 ) < 0 ) ) + if ( ( BASOP_Util_Cmp_Mant32Exp( lsp_slow_evol_rate, lsp_slow_evol_rate_e, 2147484l /*0.001f in Q31*/, 0 ) < 0 ) && ( BASOP_Util_Cmp_Mant32Exp( lsp_fast_evol_rate, lsp_fast_evol_rate_e, 2147484l /*0.001f in Q31*/, 0 ) < 0 ) ) { *frGainSmoothEn = 1; move16(); @@ -6686,11 +6821,7 @@ static void first_VQstages_fx( L_tmp = L_deposit_l( 0 ); FOR( j = 0; j < N; j++ ) { -#ifdef BASOP_NOGLOB L_tmp1 = L_shl_o( L_mult0( u[j], w[j] ), 7, &Overflow ); /*x2.56 + Q8 + Q7 */ -#else /* BASOP_NOGLOB */ - L_tmp1 = L_shl( L_mult0( u[j], w[j] ), 7 ); /*x2.56 + Q8 + Q7 */ -#endif /* BASOP_NOGLOB */ L_tmp1 = Mult_32_16( L_tmp1, u[j] ); /*x2.56 + Q15 + x2.56 -Q15 */ L_tmp = L_add( L_tmp, L_tmp1 ); /*Q0 + x2.56 +x2.56 */ } @@ -6698,7 +6829,6 @@ static void first_VQstages_fx( /* Set up initial error (residual) vectors */ pTmp = resid[1]; - move16(); FOR( c = 0; c < maxC; c++ ) { Copy( u, pTmp, N ); @@ -6723,21 +6853,15 @@ static void first_VQstages_fx( /* swap pointers to parent and current nodes */ pTmp_short = indices[0]; indices[0] = indices[1]; - move16(); indices[1] = pTmp_short; - move16(); pTmp = resid[0]; resid[0] = resid[1]; - move16(); resid[1] = pTmp; - move16(); pTmp32 = dist[0]; dist[0] = dist[1]; - move32(); dist[1] = pTmp32; - move32(); /* p_max points to maximum distortion node (worst of best) */ p_max = 0; @@ -6768,7 +6892,6 @@ static void first_VQstages_fx( FOR( c = 0; c < m; c++ ) { pTmp = &resid[0][c * N]; - move16(); L_tmp = L_mult( pTmp[0], Tmp[0] ); FOR( c2 = 1; c2 < N; c2++ ) { @@ -6815,7 +6938,7 @@ static void first_VQstages_fx( { /* subtract codebook entry from the residual vector of the parent node */ pTmp = resid[1] + c * N; - move16(); + Copy( resid[0] + parents[c] * N, pTmp, N ); Vr_subt( pTmp, cb_stage + ( indices[1][cs + s] ) * N, pTmp, N ); @@ -6888,15 +7011,11 @@ static void LVQQuant_BWE_LSF_fx( empty_bits = 0; /* This is the difference to 21 bits, if we want lower number of bits */ move16(); nbits = sub( nbits, empty_bits ); /* THIS IS TO SIMULATE DIFFERENT NUMBER OF input BITS - should be removed */ - move16(); c2 = sub( NUM_BITS_SHB_MSLVQ, nbits ); - move16(); numbits_VQ = config_LSF_BWE[c2 * 3]; - move16(); levels[0] = config_LSF_BWE[c2 * 3 + 1]; move16(); predictor_bits = config_LSF_BWE[c2 * 3 + 2]; - move16(); IF( LT_16( nbits, 19 ) ) { cb_stage_fx = cb_LSF_BWE_fx[1]; @@ -7193,6 +7312,7 @@ void fb_tbe_enc_fx( TD_BWE_ENC_HANDLE hBWE_TD = st->hBWE_TD; #ifdef BASOP_NOGLOB_DECLARE_LOCAL Flag Overflow = 0; + move16(); #endif s_max_value = 0; FOR( i = 0; i < L_FRAME48k; i++ ) @@ -7203,6 +7323,7 @@ void fb_tbe_enc_fx( if ( s_max_value == 0 ) { exp_temp = 15; + move16(); } exp_temp = sub( exp_temp, 1 ); @@ -7223,13 +7344,9 @@ void fb_tbe_enc_fx( Copy( hBWE_TD->old_input_fhb_fx, input_fhb, Sample_Delay_HP ); Copy( tmp_vec, input_fhb + Sample_Delay_HP, L_FRAME48k - Sample_Delay_HP ); Copy( tmp_vec + L_FRAME48k - Sample_Delay_HP, hBWE_TD->old_input_fhb_fx, Sample_Delay_HP ); - temp2 = sum2_fx_mod( input_fhb, L_FRAME48k / 2 ); /* Q11 */ -#ifdef BASOP_NOGLOB + temp2 = sum2_fx_mod( input_fhb, L_FRAME48k / 2 ); /* Q11 */ temp2 = L_add_o( temp2, L_shl_o( hBWE_TD->prev_fb_energy_fx, sub( sub( add( exp_temp, exp_temp ), 6 ), hBWE_TD->prev_fb_energy_fx_Q ), &Overflow ), &Overflow ); /* Q11 */ -#else - temp2 = L_add( temp2, L_shl( hBWE_TD->prev_fb_energy_fx, sub( sub( add( exp_temp, exp_temp ), 6 ), hBWE_TD->prev_fb_energy_fx_Q ) ) ); /* Q11 */ -#endif - hBWE_TD->prev_fb_energy_fx = sum2_fx_mod( input_fhb + L_FRAME48k / 2, L_FRAME48k / 2 ); /*Q11*/ + hBWE_TD->prev_fb_energy_fx = sum2_fx_mod( input_fhb + L_FRAME48k / 2, L_FRAME48k / 2 ); /*Q11*/ hBWE_TD->prev_fb_energy_fx_Q = sub( add( exp_temp, exp_temp ), 6 ); fb_exc_energy = sum2_fx_mod( fb_exc, L_FRAME16k ); /* Q(2*Q_fb_exc+1 -7) */ @@ -7254,12 +7371,8 @@ void fb_tbe_enc_fx( { tmp = div_s( tmp2, tmp ); L_tmp = L_deposit_h( tmp ); - L_tmp = Isqrt_lc( L_tmp, &exp ); /*Q(31-exp)*/ -#ifdef BASOP_NOGLOB + L_tmp = Isqrt_lc( L_tmp, &exp ); /*Q(31-exp)*/ L_tmp = L_max( L_shr_o( L_tmp, sub( 31, exp ), &Overflow ), 0x1 ); /* Q0 */ -#else - L_tmp = L_max( L_shr( L_tmp, sub( 31, exp ) ), 0x1 ); /* Q0 */ -#endif } ELSE { @@ -7269,9 +7382,11 @@ void fb_tbe_enc_fx( /* idxGain = (short)( log2_f ((float)ratio) + 0.5f ); idxGain = max( 0, min(15,idxGain) ); */ ratio = 0; + move16(); IF( GE_32( L_tmp, 32768 ) ) { idxGain = 15; + move16(); } ELSE { @@ -7280,6 +7395,9 @@ void fb_tbe_enc_fx( idxGain = sub( 14, exp_norm ); idxGain = s_max( 0, idxGain ); } + + test(); + test(); IF( GT_16( idxGain, 2 ) && LT_16( idxGain, 15 ) && GT_16( ratio, add( shl( 2, sub( idxGain, 1 ) ), shl( 2, sub( idxGain, 2 ) ) ) ) ) { idxGain = add( idxGain, 1 ); @@ -7289,6 +7407,7 @@ void fb_tbe_enc_fx( IF( st->codec_mode == MODE2 ) { hBWE_TD->idxGain = idxGain; + move16(); } ELSE { @@ -7310,15 +7429,13 @@ void fb_tbe_enc_ivas_fx( Word16 input_fhb_new[L_FRAME48k + NS2SA( 48000, DELAY_FIR_RESAMPL_NS )]; Word16 input_fhb[L_FRAME48k]; Word16 Sample_Delay_HP; - Word32 fb_exc_energy, temp2; - Word32 L_tmp; - Word16 tmp, tmp1, tmp2, exp, exp2, exp_norm; + Word64 fb_exc_energy; + Word16 tmp, tmp2, exp, exp2; Word16 s_max_value, exp_temp, i; TD_BWE_ENC_HANDLE hBWE_TD = st->hBWE_TD; -#ifdef BASOP_NOGLOB_DECLARE_LOCAL - Flag Overflow = 0; - move32(); -#endif + Word16 q_diff, q_input_fhb; + Word64 temp1, temp2; + s_max_value = 0; move16(); FOR( i = 0; i < L_FRAME48k + NS2SA( 48000, DELAY_FIR_RESAMPL_NS ); i++ ) @@ -7350,18 +7467,15 @@ void fb_tbe_enc_ivas_fx( IF( EQ_16( st->L_frame, L_FRAME ) ) { Sample_Delay_HP = NS2SA( 48000, ACELP_LOOK_NS + DELAY_FD_BWE_ENC_12k8_NS ) - L_FRAME48k / 2; - move16(); } ELSE { Sample_Delay_HP = NS2SA( 48000, ACELP_LOOK_NS + DELAY_FD_BWE_ENC_16k_NS ) - L_FRAME48k / 2; - move16(); } } ELSE { Sample_Delay_HP = NS2SA( 48000, ACELP_LOOK_NS + DELAY_FD_BWE_ENC_12k8_NS + DELAY_FIR_RESAMPL_NS ) - L_FRAME48k / 2; - move16(); } IF( NE_16( st->last_extl, FB_TBE ) ) @@ -7371,79 +7485,72 @@ void fb_tbe_enc_ivas_fx( move16(); set16_fx( tmp_vec, 0, L_FRAME16k ); } - Copy_Scale_sig( hBWE_TD->old_input_fhb_fx, hBWE_TD->old_input_fhb_fx, Sample_Delay_HP, sub( exp_temp, hBWE_TD->old_input_fhb_fx_Q ) ); + + q_diff = sub( exp_temp, hBWE_TD->old_input_fhb_fx_Q ); + Copy( hBWE_TD->old_input_fhb_fx, input_fhb, Sample_Delay_HP ); // hBWE_TD->old_input_fhb_fx_Q + Copy( tmp_vec, input_fhb + Sample_Delay_HP, sub( L_FRAME48k, Sample_Delay_HP ) ); // exp_temp + IF( q_diff > 0 ) + { + scale_sig( input_fhb + Sample_Delay_HP, sub( L_FRAME48k, Sample_Delay_HP ), negate( q_diff ) ); // hBWE_TD->old_input_fhb_fx_Q + q_input_fhb = hBWE_TD->old_input_fhb_fx_Q; + move16(); + } + ELSE + { + scale_sig( input_fhb, Sample_Delay_HP, q_diff ); // exp_temp + q_input_fhb = exp_temp; + move16(); + } + Copy( tmp_vec + L_FRAME48k - Sample_Delay_HP, hBWE_TD->old_input_fhb_fx, Sample_Delay_HP ); hBWE_TD->old_input_fhb_fx_Q = exp_temp; move16(); - Copy( hBWE_TD->old_input_fhb_fx, input_fhb, Sample_Delay_HP ); - Copy( tmp_vec, input_fhb + Sample_Delay_HP, sub( L_FRAME48k, Sample_Delay_HP ) ); - Copy( tmp_vec + L_FRAME48k - Sample_Delay_HP, hBWE_TD->old_input_fhb_fx, Sample_Delay_HP ); - temp2 = sum2_fx_mod( input_fhb, L_FRAME48k / 2 ); /* Q(2*Q_input_fhb-8) */ -#ifdef BASOP_NOGLOB - temp2 = L_add_o( temp2, L_shl_o( hBWE_TD->prev_fb_energy_fx, sub( sub( add( exp_temp, exp_temp ), 8 ), hBWE_TD->prev_fb_energy_fx_Q ), &Overflow ), &Overflow ); /* Q(2*(exp_temp)-8) */ -#else - temp2 = L_add( temp2, L_shl( hBWE_TD->prev_fb_energy_fx, sub( sub( add( exp_temp, exp_temp ), 8 ), hBWE_TD->prev_fb_energy_fx_Q ) ) ); /* Q(2*(exp_temp)-8) */ -#endif - hBWE_TD->prev_fb_energy_fx = sum2_fx_mod( input_fhb + L_FRAME48k / 2, L_FRAME48k / 2 ); /*Q(2*(Q_input_fhb)-8) */ + + temp2 = sum2_fx_no_sat( input_fhb, L_FRAME48k / 2 ); // 2*q_input_fhb /* Q(2*Q_input_fhb-8) */ + temp2 = W_add( temp2, W_shl( hBWE_TD->prev_fb_energy_fx, sub( q_input_fhb, hBWE_TD->prev_fb_energy_fx_Q ) ) ); // 2*q_input_fhb + + temp1 = sum2_fx_no_sat( input_fhb + L_FRAME48k / 2, L_FRAME48k / 2 ); // 2*q_input_fhb + exp = W_norm( temp1 ); + temp1 = W_shl( temp1, exp ); // 2*q_input_fhb+exp + hBWE_TD->prev_fb_energy_fx = W_extract_h( temp1 ); // 2*q_input_fhb+exp-32 move32(); - hBWE_TD->prev_fb_energy_fx_Q = sub( add( exp_temp, exp_temp ), 8 ); + hBWE_TD->prev_fb_energy_fx_Q = sub( add( shl( q_input_fhb, 1 ), exp ), 32 ); move16(); - fb_exc_energy = sum2_fx_mod( fb_exc, L_FRAME16k ); /* Q(2*Q_fb_exc-8) */ - /*ratio = (float) sqrt( temp2 / fb_exc_energy );*/ - L_tmp = L_max( 1, temp2 ); /*Q(2*(exp_temp)-8)*/ - exp = norm_l( L_tmp ); - tmp = extract_h( L_shl( L_tmp, exp ) ); - exp = sub( sub( 31, sub( add( exp_temp, exp_temp ), 8 ) ), exp ); /* (L_tmp in Q(2*(exp_temp)-8))*/ + fb_exc_energy = sum2_fx_no_sat( fb_exc, L_FRAME16k ); // 2*Q_fb_exc - exp2 = norm_l( fb_exc_energy ); - tmp2 = extract_h( L_shl( fb_exc_energy, exp2 ) ); - tmp1 = sub( add( Q_fb_exc, Q_fb_exc ), 8 ); /*1 - 9*/ - exp2 = sub( sub( 31, tmp1 ), exp2 ); /* (L_tmp in Q(2*(exp_temp)-8))*/ + /*ratio = (float) sqrt( temp2 / fb_exc_energy );*/ + exp = sub( W_norm( temp2 ), 1 ); + tmp = extract_h( W_extract_h( W_shl( temp2, exp ) ) ); // 2*q_input_fhb+exp-48 + exp = sub( 63, add( shl( q_input_fhb, 1 ), exp ) ); // 15-(2*q_input_fhb+exp-48) - exp = sub( exp2, exp ); /* Denormalize and substract */ - IF( GT_16( tmp2, tmp ) ) - { - tmp2 = shr( tmp2, 1 ); - exp = add( exp, 1 ); - } - IF( 0 != tmp ) - { - tmp = div_s( tmp2, tmp ); - L_tmp = L_deposit_h( tmp ); - L_tmp = Isqrt_lc( L_tmp, &exp ); /*Q(31-exp)*/ -#ifdef BASOP_NOGLOB - L_tmp = L_max( L_shr_o( L_tmp, sub( 31, exp ), &Overflow ), 0x1 ); /* Q0 */ -#else - L_tmp = L_max( L_shr( L_tmp, sub( 31, exp ) ), 0x1 ); /* Q0 */ -#endif - } - ELSE - { - L_tmp = 0; - move32(); - } + exp2 = W_norm( fb_exc_energy ); + tmp2 = extract_h( W_extract_h( W_shl( fb_exc_energy, exp2 ) ) ); // 2*Q_fb_exc+exp2-48 + exp2 = sub( 63, add( shl( Q_fb_exc, 1 ), exp2 ) ); // 15-(2*Q_fb_exc+exp2-48) - /* idxGain = (short)( log2_f ((float)ratio) + 0.5f ); - idxGain = max( 0, min(15,idxGain) ); */ ratio = 0; + idxGain = 0; + move16(); move16(); - IF( GE_32( L_tmp, 32768 ) ) - { - idxGain = 15; - move16(); - } - ELSE - { - ratio = extract_l( L_tmp ); - exp_norm = norm_s( ratio ); - idxGain = sub( 14, exp_norm ); - idxGain = s_max( 0, idxGain ); - } - test(); test(); - IF( GT_16( idxGain, 2 ) && LT_16( idxGain, 15 ) && GT_16( ratio, add( shl( 2, sub( idxGain, 1 ) ), shl( 2, sub( idxGain, 2 ) ) ) ) ) - { - idxGain = add( idxGain, 1 ); + IF( tmp != 0 && tmp2 != 0 ) + { + ratio = div_s( tmp, tmp2 ); // exp: exp-exp2 + exp = sub( exp, exp2 ); + /* ratio = (float) sqrt( temp2 / fb_exc_energy ); + idxGain = (short)( log2_f ((float)ratio) + 0.5f ); + + => idxGain = (short)( log2_f (sqrt( temp2 / fb_exc_energy )) + 0.5f ) + = (short)(log2f(sqrt(temp2 / fb_exc_energy)) + log2f(sqrt(2))) + = (short)log2f(sqrt(2 * (temp2 / fb_exc_energy))) + increase the exp of division result by one, two accommodate the multiplication with 2 in sqrt + */ + exp = add( exp, 1 ); + ratio = Sqrt16( ratio, &exp ); + /* Since ratio always lie betwwen 16384 and 32767, subtract the Q of sqrt result from 14 to get the integral part of log value */ + idxGain = sub( exp, 1 ); // 14 - (15-exp) + + /* idxGain = max( 0, min( 15, idxGain ) ); */ + idxGain = s_max( 0, s_min( 15, idxGain ) ); } /* ratio = (float)(1 << idxGain);*/ @@ -7551,6 +7658,7 @@ void TBEreset_enc_fx( { set16_fx( hBWE_TD->old_bwe_exc_fx, 0, PIT16k_MAX * 2 ); hBWE_TD->bwe_non_lin_prev_scale_fx = L_deposit_l( 0 ); + move32(); st_fx->prev_Q_bwe_exc = 31; move16(); } diff --git a/lib_enc/tcq_core_enc.c b/lib_enc/tcq_core_enc.c deleted file mode 100644 index d54084f0bc6c24a06147b1d7ab2b249bc7ca568d..0000000000000000000000000000000000000000 --- a/lib_enc/tcq_core_enc.c +++ /dev/null @@ -1,50 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include "rom_com.h" -#include "prot.h" -#include "cnst.h" -#include "basop_util.h" -#include "basop_proto_func.h" -#include "wmc_auto.h" - -/*---------------------------------------------------------------------* - * tcq_core_LR_enc() - * - * Main Generic Audio Encoder Routine for LR-MDCT - *---------------------------------------------------------------------*/ diff --git a/lib_enc/tcq_core_enc_fx.c b/lib_enc/tcq_core_enc_fx.c index 7ff5a9637a1fa02501ee46d79b99fab7d3b9f4db..82088be5088b04dcb55b92c2b5fb48aee23dd3e9 100644 --- a/lib_enc/tcq_core_enc_fx.c +++ b/lib_enc/tcq_core_enc_fx.c @@ -10,7 +10,6 @@ #include "ivas_error.h" #include "prot_fx.h" /* Function prototypes */ #include "prot_fx_enc.h" /* Function prototypes */ -#include "prot.h" #define IVAS_FLOAT ivas_error tcq_core_LR_enc_fx( @@ -57,6 +56,13 @@ ivas_error tcq_core_LR_enc_fx( Word32 Rk_sort_fx[NB_SFM]; Word32 step_scale_fx[NB_SFM]; Word16 pulses_fx, nzp_fx; + move16(); + move16(); + move16(); + move16(); + move16(); + move16(); + move32(); Word32 gain_fx, crosscorr_fx, selfcorr_fx; Word16 hi, lo, exp; @@ -66,6 +72,9 @@ ivas_error tcq_core_LR_enc_fx( Word32 sepbits = 0; Word32 divider = 0; ivas_error error; + move32(); + move32(); + move32(); error = IVAS_ERR_OK; move16(); @@ -82,7 +91,7 @@ ivas_error tcq_core_LR_enc_fx( test(); test(); - IF( input_frame <= L_FRAME16k && adjustFlag == 0 && is_transient == 0 ) + IF( LE_16( input_frame, L_FRAME16k ) && adjustFlag == 0 && is_transient == 0 ) { flag_wbnb = 1; move16(); @@ -100,6 +109,8 @@ ivas_error tcq_core_LR_enc_fx( move16(); pbs_fx->numbits = L_deposit_l( 0 ); pbs_fx->numByte = L_deposit_l( 0 ); + move32(); + move32(); FOR( i = 0; i < MAX_SIZEBUF_PBITSTREAM; i++ ) { pbs_fx->buf[i] = 0; @@ -134,7 +145,7 @@ ivas_error tcq_core_LR_enc_fx( { IF( R_fx[j] > 0 ) { - nzb++; + nzb = add( nzb, 1 ); } } @@ -148,11 +159,13 @@ ivas_error tcq_core_LR_enc_fx( IF( R_fx[j] > 0 ) { R_fx[j] = L_sub( R_fx[j], ar_div( bsub_fx, nzb ) ); + move32(); IF( R_fx[j] < 0 ) { bsub_fx = L_sub( bsub_fx, L_add( ar_div( bsub_fx, nzb ), R_fx[j] ) ); R_fx[j] = L_deposit_l( 0 ); + move32(); } ELSE { @@ -186,10 +199,11 @@ ivas_error tcq_core_LR_enc_fx( move16(); FOR( j = 0; j < BANDS; j++ ) { + test(); IF( NE_16( j, k_num[0] ) && NE_16( j, k_num[1] ) ) { leftbits = L_add( leftbits, R_fx[k_sort[j]] ); - if ( R_fx[k_sort[j]] > 0 ) + IF( R_fx[k_sort[j]] > 0 ) { nzbands = add( nzbands, 1 ); } @@ -226,7 +240,7 @@ ivas_error tcq_core_LR_enc_fx( encode_position_ari_fx( parenc_fx, &coefs_norm_dec_fx[sfm_start[k_sort[k]]], size, &est_frame_bits_fx ); encode_magnitude_tcq_fx( parenc_fx, &coefs_norm_dec_fx[sfm_start[k_sort[k]]], size, npulses[k_sort[k]], nzp_fx, savedstates, &est_frame_bits_fx ); encode_signs_fx( parenc_fx, &coefs_norm_dec_fx[sfm_start[k_sort[k]]], size, nzp_fx, &est_frame_bits_fx ); - nzbands--; + nzbands = sub( nzbands, 1 ); } /* Have USQ coded band */ ELSE IF( R_fx[k_sort[k]] > 0 && EQ_16( USQ_TCQ[k_sort[k]], 1 ) ) @@ -245,7 +259,7 @@ ivas_error tcq_core_LR_enc_fx( encode_position_ari_fx( parenc_fx, &coefs_norm_dec_fx[sfm_start[k_sort[k]]], size, &est_frame_bits_fx ); encode_magnitude_usq_fx( parenc_fx, &coefs_norm_dec_fx[sfm_start[k_sort[k]]], size, npulses[k_sort[k]], nzp_fx, &est_frame_bits_fx ); encode_signs_fx( parenc_fx, &coefs_norm_dec_fx[sfm_start[k_sort[k]]], size, nzp_fx, &est_frame_bits_fx ); - nzbands--; + nzbands = sub( nzbands, 1 ); } ELSE /* Then have zero block */ { @@ -260,13 +274,15 @@ ivas_error tcq_core_LR_enc_fx( IF( R_fx[k_sort[k]] > 0 && surplus_fx < 0 ) { /* delta_fx = L_deposit_h( div_l( surplus_fx, nzbands ) ); */ - IF( nzbands <= 1 ) + IF( LE_16( nzbands, 1 ) ) { divider = 0; + move32(); } ELSE { divider = 2; + move32(); } IF( L_add( L_add( surplus_fx, sepbits ), ar_div( leftbits, divider ) ) < 0 ) @@ -274,7 +290,7 @@ ivas_error tcq_core_LR_enc_fx( /* Overflow possible => start to distribute negative surplus */ delta_fx = ar_div( surplus_fx + sepbits, nzbands ); } - else + ELSE { delta_fx = 0; } @@ -290,12 +306,15 @@ ivas_error tcq_core_LR_enc_fx( { bit_surplus_fx[0] = Mult_32_16( surplus_fx, 24576 ); /* Q16 */ bit_surplus_fx[1] = Mult_32_16( surplus_fx, 8192 ); /* Q16 */ + move32(); + move32(); } ELSE { bit_surplus_fx[0] = surplus_fx; move32(); bit_surplus_fx[1] = L_deposit_l( 0 ); + move32(); } FOR( k = 0; k < BANDS; k++ ) @@ -305,6 +324,7 @@ ivas_error tcq_core_LR_enc_fx( IF( EQ_16( k, k_num[j] ) ) { R_fx[k_sort[k]] = L_add( R_fx[k_sort[k]], bit_surplus_fx[j] ); + move32(); test(); test(); @@ -409,7 +429,9 @@ ivas_error tcq_core_LR_enc_fx( FOR( i = 0; i < L_FRAME32k; i++ ) { coefs_norm_dec_fx[i] = extract_l( L_mult0( coefs_norm_dec_fx[i], 5 ) ); + move16(); } + IF( !flag_wbnb ) { FOR( k = 0; k < BANDS; k++ ) @@ -454,11 +476,7 @@ ivas_error tcq_core_LR_enc_fx( exp = sub( norm_l( crosscorr_fx ), 1 ); gain_fx = ar_div( L_shl( crosscorr_fx, exp ), selfcorr_fx ); /* 1 + exp */ -#ifdef BASOP_NOGLOB - gain_fx = L_shl_sat( gain_fx, sub( 16, 1 + exp ) + 2 ); /* 0.2 * Q16 */ -#else - gain_fx = L_shl( gain_fx, sub( 16, 1 + exp ) + 2 ); /* 0.2 * Q16 */ -#endif + gain_fx = L_shl_sat( gain_fx, sub( 16, 1 + exp ) + 2 ); /* 0.2 * Q16 */ lo = L_Extract_lc( gain_fx, &hi ); /* Use optimal gain */ FOR( j = 0; j < sfmsize[k_sort[i]]; j++ ) @@ -467,6 +485,7 @@ ivas_error tcq_core_LR_enc_fx( move16(); coefs_quant_fx[sfm_start[k_sort[i]] + j] = L_add( L_shl( L_mult0( hi, coefs_norm_dec_fx[sfm_start[k_sort[i]] + j] ), 12 ), L_shr( L_mult0( lo, coefs_norm_dec_fx[sfm_start[k_sort[i]] + j] ), 3 ) ); /* Q12 */ + move32(); } } } @@ -518,7 +537,7 @@ ivas_error tcq_core_LR_enc_ivas_fx( move16(); move16(); move16(); - move16(); + move32(); Word32 abuffer_fx[MAX_PULSES]; Word16 mbuffer_fx[MAX_PULSES]; Word32 sbuffer_fx[MAX_PULSES]; @@ -534,9 +553,9 @@ ivas_error tcq_core_LR_enc_ivas_fx( Word32 leftbits = 0; Word32 sepbits = 0; Word32 divider = 0; - move16(); - move16(); - move16(); + move32(); + move32(); + move32(); ivas_error error; error = IVAS_ERR_OK; @@ -622,11 +641,13 @@ ivas_error tcq_core_LR_enc_ivas_fx( IF( R_fx[j] > 0 ) { R_fx[j] = L_sub( R_fx[j], ar_div( bsub_fx, nzb ) ); + move32(); IF( R_fx[j] < 0 ) { bsub_fx = L_sub( bsub_fx, L_add( ar_div( bsub_fx, nzb ), R_fx[j] ) ); R_fx[j] = L_deposit_l( 0 ); + move32(); } ELSE { @@ -660,10 +681,11 @@ ivas_error tcq_core_LR_enc_ivas_fx( move16(); FOR( j = 0; j < BANDS; j++ ) { + test(); IF( NE_16( j, k_num[0] ) && NE_16( j, k_num[1] ) ) { leftbits = L_add( leftbits, R_fx[k_sort[j]] ); - if ( R_fx[k_sort[j]] > 0 ) + IF( R_fx[k_sort[j]] > 0 ) { nzbands = add( nzbands, 1 ); } @@ -734,13 +756,15 @@ ivas_error tcq_core_LR_enc_ivas_fx( IF( R_fx[k_sort[k]] > 0 && surplus_fx < 0 ) { /* delta_fx = L_deposit_h( div_l( surplus_fx, nzbands ) ); */ - IF( nzbands <= 1 ) + IF( LE_16( nzbands, 1 ) ) { divider = 0; + move32(); } ELSE { divider = 2; + move32(); } IF( L_add( L_add( surplus_fx, sepbits ), ar_div( leftbits, divider ) ) < 0 ) @@ -888,7 +912,9 @@ ivas_error tcq_core_LR_enc_ivas_fx( FOR( i = 0; i < L_FRAME32k; i++ ) { coefs_norm_dec_fx[i] = extract_l( L_mult0( coefs_norm_dec_fx[i], 5 ) ); + move16(); } + IF( !flag_wbnb ) { FOR( k = 0; k < BANDS; k++ ) @@ -903,6 +929,7 @@ ivas_error tcq_core_LR_enc_ivas_fx( } nb_bytes = shr( bit_budget, 3 ); + j = sub( bit_budget, shl( nb_bytes, 3 ) ); FOR( i = 0; i < nb_bytes; i++ ) { @@ -933,11 +960,7 @@ ivas_error tcq_core_LR_enc_ivas_fx( exp = sub( norm_l( crosscorr_fx ), 1 ); gain_fx = ar_div( L_shl( crosscorr_fx, exp ), selfcorr_fx ); /* 1 + exp */ -#ifdef BASOP_NOGLOB - gain_fx = L_shl_sat( gain_fx, sub( 16, 1 + exp ) + 2 ); /* 0.2 * Q16 */ -#else - gain_fx = L_shl( gain_fx, sub( 16, 1 + exp ) + 2 ); /* 0.2 * Q16 */ -#endif + gain_fx = L_shl_sat( gain_fx, sub( 16, 1 + exp ) + 2 ); /* 0.2 * Q16 */ lo = L_Extract_lc( gain_fx, &hi ); /* Use optimal gain */ FOR( j = 0; j < sfmsize[k_sort[i]]; j++ ) diff --git a/lib_enc/tcx_ltp_enc.c b/lib_enc/tcx_ltp_enc.c deleted file mode 100644 index 8c3c60e18ff0099bcd3230c9c2514dc481606cc6..0000000000000000000000000000000000000000 --- a/lib_enc/tcx_ltp_enc.c +++ /dev/null @@ -1,43 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include -#include "prot.h" -#include "rom_enc.h" -#include "rom_com.h" -#include "wmc_auto.h" diff --git a/lib_enc/tcx_ltp_enc_fx.c b/lib_enc/tcx_ltp_enc_fx.c index aec8479076a504c4d71e04b9bff08fcaeba8b063..e1d478e954f3c24e06f61037b353e87727f1e15d 100644 --- a/lib_enc/tcx_ltp_enc_fx.c +++ b/lib_enc/tcx_ltp_enc_fx.c @@ -88,6 +88,7 @@ static void tcx_ltp_pitch_search( Word16 wsp2[L_FRAME_PLUS + PIT_MAX_MAX + L_INTERPOL1]; #ifdef BASOP_NOGLOB_DECLARE_LOCAL Flag Overflow = 0; + move32(); #endif @@ -129,12 +130,15 @@ static void tcx_ltp_pitch_search( move16(); } wsp = wsp2 + t_max; + move16(); pt_cor = cor; + move32(); FOR( t = t_min; t <= t_max; t++ ) { *pt_cor = dot( wsp, wsp - t, len ); + move32(); pt_cor++; } @@ -142,13 +146,16 @@ static void tcx_ltp_pitch_search( cor_max = L_add( *pt_cor++, 0 ); t1 = t0_min; move16(); + move32(); - FOR( t = add( t0_min, 1 ); t <= t0_max; t++ ) + FOR( t = t0_min + 1; t <= t0_max; t++ ) { - IF( *pt_cor > cor_max ) + IF( GT_32( *pt_cor, cor_max ) ) { cor_max = *pt_cor; + move32(); t1 = t; + move16(); } pt_cor++; } @@ -174,13 +181,7 @@ static void tcx_ltp_pitch_search( temp_m = divide1616( extract_h( L_shl( cor_max, s ) ), temp_m ); temp_e = sub( negate( s ), temp_e ); -#ifdef BASOP_NOGLOB *norm_corr = shl_o( temp_m, temp_e, &Overflow ); -#else - BASOP_SATURATE_WARNING_OFF_EVS - *norm_corr = shl( temp_m, temp_e ); - BASOP_SATURATE_WARNING_ON_EVS -#endif IF( GE_16( t1, pitfr1 ) ) { @@ -227,7 +228,7 @@ static void tcx_ltp_pitch_search( t0 = sub( t0, 1 ); cor_max = interpolate_corr( &pt_cor[t0], fraction, pitres ); - FOR( i = add( fraction, step ); i < pitres; i += step ) + FOR( i = fraction + step; i < pitres; i += step ) { temp = interpolate_corr( &pt_cor[t0], i, pitres ); @@ -241,6 +242,7 @@ static void tcx_ltp_pitch_search( } i = 0; + move16(); FOR( i = 0; i < pitres; i += step ) /* Process positive fractions */ { temp = interpolate_corr( &pt_cor[t1], i, pitres ); @@ -341,6 +343,7 @@ static void tcx_ltp_pitch_search_ivas_fx( FOR( t = t_min; t <= t_max; t++ ) { *pt_cor = dot( wsp, wsp - t, len ); // 2*(x + s_wsp) + move32(); pt_cor++; } @@ -349,7 +352,7 @@ static void tcx_ltp_pitch_search_ivas_fx( t1 = t0_min; move16(); - FOR( t = add( t0_min, 1 ); t <= t0_max; t++ ) + FOR( t = t0_min + 1; t <= t0_max; t++ ) { IF( GT_32( *pt_cor, cor_max ) ) { @@ -382,13 +385,7 @@ static void tcx_ltp_pitch_search_ivas_fx( temp_m = divide1616( extract_h( L_shl( cor_max, s ) ), temp_m ); temp_e = sub( negate( s ), temp_e ); -#ifdef BASOP_NOGLOB *norm_corr = shl_o( temp_m, temp_e, &Overflow ); -#else - BASOP_SATURATE_WARNING_OFF_EVS - *norm_corr = shl( temp_m, temp_e ); - BASOP_SATURATE_WARNING_ON_EVS -#endif test(); IF( check_border_case && EQ_16( t1, t0_min ) ) @@ -415,6 +412,7 @@ static void tcx_ltp_pitch_search_ivas_fx( *index = add( sub( t1, pitfr1 ), extract_l( L_mac0( L_mult0( sub( pitfr2, pitmin ), pitres ), sub( pitfr1, pitfr2 ), shr( pitres, 1 ) ) ) ); + move16(); return; } @@ -450,7 +448,7 @@ static void tcx_ltp_pitch_search_ivas_fx( t0 = sub( t0, 1 ); cor_max = interpolate_corr( &pt_cor[t0], fraction, pitres ); - FOR( i = add( fraction, step ); i < pitres; i += step ) + FOR( i = fraction + step; i < pitres; i += step ) { temp = interpolate_corr( &pt_cor[t0], i, pitres ); @@ -487,10 +485,12 @@ static void tcx_ltp_pitch_search_ivas_fx( *index = add( extract_l( L_mac0( L_mult0( sub( t0, pitfr2 ), shr( pitres, 1 ) ), sub( pitfr2, pitmin ), pitres ) ), shr( fraction, 1 ) ); + move16(); } ELSE { *index = add( imult1616( sub( t0, pitmin ), pitres ), fraction ); + move16(); } } @@ -501,6 +501,7 @@ static void tcx_ltp_find_gain( Word16 *speech, Word16 *pred_speech, Word16 L_fra Word16 i, g, s1, s2, tmp; #ifdef BASOP_NOGLOB_DECLARE_LOCAL Flag Overflow = 0; + move32(); #endif @@ -513,15 +514,9 @@ static void tcx_ltp_find_gain( Word16 *speech, Word16 *pred_speech, Word16 L_fra FOR( i = 0; i < L_frame; i++ ) { -#ifdef BASOP_NOGLOB tmp = shl_sat( pred_speech[i], s2 ); corr = L_mac0_sat( corr, shl( speech[i], s1 ), tmp ); ener = L_mac0_sat( ener, tmp, tmp ); -#else - tmp = shl( pred_speech[i], s2 ); - corr = L_mac0( corr, shl( speech[i], s1 ), tmp ); - ener = L_mac0( ener, tmp, tmp ); -#endif } s1 = sub( 1, add( s1, s2 ) ); @@ -535,21 +530,17 @@ static void tcx_ltp_find_gain( Word16 *speech, Word16 *pred_speech, Word16 L_fra ener = L_shl( ener, tmp ); s2 = sub( s2, tmp ); -#ifdef BASOP_NOGLOB g = divide1616( round_fx_o( corr, &Overflow ), round_fx_o( ener, &Overflow ) ); -#else - g = divide1616( round_fx( corr ), round_fx( ener ) ); -#endif BASOP_SATURATE_WARNING_OFF_EVS -#ifdef BASOP_NOGLOB g = shl_o( g, sub( s1, s2 ), &Overflow ); -#else /* BASOP_NOGLOB */ - g = shl( g, sub( s1, s2 ) ); -#endif /* BASOP_NOGLOB */ BASOP_SATURATE_WARNING_ON_EVS /* Quantize gain */ +#ifdef FIX_ISSUE_1150 + g = shr( sub_o( g, 0x1000, &Overflow ), 13 ); +#else g = shr( sub( g, 0x1000 ), 13 ); +#endif g = s_max( g, -1 ); *gain_index = g; @@ -578,15 +569,9 @@ static void tcx_ltp_find_gain_ivas_fx( Word16 *speech /*Qx*/, Word16 *pred_speec FOR( i = 0; i < L_frame; i++ ) { -#ifdef BASOP_NOGLOB tmp = shl_sat( pred_speech[i], s2 ); // Qx + s2 corr = L_mac0_sat( corr, shl( speech[i], s1 ), tmp ); // 2*Qx + s1 + s2 ener = L_mac0_sat( ener, tmp, tmp ); // 2*(Qx+s2) -#else - tmp = shl( pred_speech[i], s2 ); - corr = L_mac0( corr, shl( speech[i], s1 ), tmp ); - ener = L_mac0( ener, tmp, tmp ); -#endif } s1 = sub( 1, add( s1, s2 ) ); @@ -600,17 +585,9 @@ static void tcx_ltp_find_gain_ivas_fx( Word16 *speech /*Qx*/, Word16 *pred_speec ener = L_shl( ener, tmp ); s2 = sub( s2, tmp ); -#ifdef BASOP_NOGLOB g = divide1616( round_fx_o( corr, &Overflow ), round_fx_o( ener, &Overflow ) ); -#else - g = divide1616( round_fx( corr ), round_fx( ener ) ); -#endif BASOP_SATURATE_WARNING_OFF_EVS -#ifdef BASOP_NOGLOB g = shl_o( g, sub( s1, s2 ), &Overflow ); /*Q15*/ -#else /* BASOP_NOGLOB */ - g = shl( g, sub( s1, s2 ) ); -#endif /* BASOP_NOGLOB */ BASOP_SATURATE_WARNING_ON_EVS /* Quantize gain */ @@ -664,6 +641,7 @@ void tcx_ltp_encode_fx( Word16 tcxltp_on, Word16 alpha, step; #ifdef BASOP_NOGLOB_DECLARE_LOCAL Flag Overflow = 0; + move32(); #endif @@ -793,14 +771,14 @@ void tcx_ltp_encode_fx( Word16 tcxltp_on, *ltp_bits = 0; move16(); test(); - if ( tcxltp_on != 0 || SideInfoOnly != 0 ) + IF( tcxltp_on != 0 || SideInfoOnly != 0 ) { *ltp_bits = 1; move16(); } } - if ( SideInfoOnly != 0 ) + IF( SideInfoOnly != 0 ) { *gain = 0; move16(); @@ -818,25 +796,17 @@ void tcx_ltp_encode_fx( Word16 tcxltp_on, /* step = 1.f/(float)(L_subfr); */ step = shl( 2, norm_s( L_subfr ) ); - if ( s_and( L_subfr, sub( L_subfr, 1 ) ) != 0 ) + IF( s_and( L_subfr, sub( L_subfr, 1 ) ) != 0 ) { step = mult_r( step, 26214 /*64.f/80.f Q15*/ ); } FOR( n = 0; n < L_subfr; n++ ) { -#ifdef BASOP_NOGLOB speech_ltp[n] = sub_o( speech[n], mult_ro( *gain, mult_ro( alpha, pred_speech[n], &Overflow ), &Overflow ), &Overflow ); -#else - speech_ltp[n] = sub( speech[n], mult_r( *gain, mult_r( alpha, pred_speech[n] ) ) ); -#endif move16(); BASOP_SATURATE_WARNING_OFF_EVS; -#ifdef BASOP_NOGLOB alpha = add_o( alpha, step, &Overflow ); -#else /* BASOP_NOGLOB */ - alpha = add( alpha, step ); -#endif BASOP_SATURATE_WARNING_ON_EVS; } } @@ -859,11 +829,7 @@ void tcx_ltp_encode_fx( Word16 tcxltp_on, FOR( n = 0; n < lpcorder; n++ ) { -#ifdef BASOP_NOGLOB buf_zir[n] = add_sat( sub_sat( speech_ltp[n - lpcorder], speech[n - lpcorder] ), mult_r( *gain, buf_zir[n] ) ); -#else - buf_zir[n] = add( sub( speech_ltp[n - lpcorder], speech[n - lpcorder] ), mult_r( *gain, buf_zir[n] ) ); -#endif move16(); } @@ -874,14 +840,15 @@ void tcx_ltp_encode_fx( Word16 tcxltp_on, E_UTIL_synthesis( 0, A, zir, zir, L_subfr, buf_zir, 0, lpcorder ); alpha = 0x7FFF; + move16(); /* step = 1.f/(float)(L_subfr/2); */ step = shl( 4, norm_s( L_subfr ) ); - if ( s_and( L_subfr, sub( L_subfr, 1 ) ) != 0 ) + IF( s_and( L_subfr, sub( L_subfr, 1 ) ) != 0 ) { step = mult_r( step, 26214 /*64.f/80.f Q15*/ ); } - FOR( n = shr( L_subfr, 1 ); n < L_subfr; n++ ) + FOR( n = ( L_subfr >> 1 ); n < L_subfr; n++ ) { zir[n] = mult_r( zir[n], alpha ); move16(); @@ -890,11 +857,7 @@ void tcx_ltp_encode_fx( Word16 tcxltp_on, FOR( n = 0; n < L_subfr; n++ ) { -#ifdef BASOP_NOGLOB speech_ltp[n] = add_o( sub_o( speech[n], mult_ro( *gain, pred_speech[n], &Overflow ), &Overflow ), zir[n], &Overflow ); -#else - speech_ltp[n] = add( sub( speech[n], mult_r( *gain, pred_speech[n] ) ), zir[n] ); -#endif move16(); } } @@ -912,11 +875,7 @@ void tcx_ltp_encode_fx( Word16 tcxltp_on, { FOR( n = L_subfr; n < L_frame; n++ ) { -#ifdef BASOP_NOGLOB speech_ltp[n] = sub_o( speech[n], mult( *gain, pred_speech[n] ), &Overflow ); -#else - speech_ltp[n] = sub( speech[n], mult( *gain, pred_speech[n] ) ); -#endif move16(); } } @@ -1032,13 +991,12 @@ void tcx_ltp_encode_ivas_fx( IF( GT_16( norm_corr_2_fx[1], norm_corr_2_fx[0] ) ) { i = 1; - move16(); } ELSE { i = 0; - move16(); } + move16(); hTcxEnc->tcxltp_pitch_int = pitch_int_2[i]; move16(); @@ -1047,6 +1005,7 @@ void tcx_ltp_encode_ivas_fx( ltp_param[1] = pit_param_2[i]; move16(); norm_corr_fx = norm_corr_2_fx[i]; + move16(); } } ELSE @@ -1146,8 +1105,7 @@ void tcx_ltp_encode_ivas_fx( move16(); sqr = Sqrt16( hTcxEnc->tcxltp_on_mem, &exponent ); move16(); - sqr = shl_sat( sqr, exponent ); - IF( ( EQ_16( tcxOnly, 1 ) && EQ_16( st->element_mode, IVAS_CPE_MDCT ) && ( GT_16( ( mult( sqr, mult( ( norm_corr_fx ), 29492 ) ) ), 14419 ) && ( LT_16( tempFlatness_fx, 768 ) || ( LT_16( tempFlatness_fx, 896 ) && LT_16( maxEnergyChange_fx, 176 ) ) ) ) ) ) // 0.9f Q15, 6.0f Q7, 7.0f Q7, 22.0f Q3 + IF( ( EQ_16( tcxOnly, 1 ) && EQ_16( st->element_mode, IVAS_CPE_MDCT ) && ( GT_16( ( mult( sqr, mult( ( norm_corr_fx ), 29492 ) ) ), shr( 14419, exponent ) ) && ( LT_16( tempFlatness_fx, 768 ) || ( LT_16( tempFlatness_fx, 896 ) && LT_16( maxEnergyChange_fx, 176 ) ) ) ) ) ) // 0.9f Q15, 6.0f Q7, 7.0f Q7, 22.0f Q3 { ltp_on = 1; move16(); @@ -1297,7 +1255,7 @@ void tcx_ltp_encode_ivas_fx( step_fx = mult_r( step_fx, 26214 /*64.f/80.f Q15*/ ); } - FOR( n = shr( L_subfr, 1 ); n < L_subfr; n++ ) + FOR( n = L_subfr >> 1; n < L_subfr; n++ ) { zir_fx[n] = mult_r( zir_fx[n], alpha_fx ); move16(); diff --git a/lib_enc/tcx_utils_enc.c b/lib_enc/tcx_utils_enc.c deleted file mode 100644 index 2db3ce73a3890e278355d9034025edc1776653c1..0000000000000000000000000000000000000000 --- a/lib_enc/tcx_utils_enc.c +++ /dev/null @@ -1,258 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include -#include "options.h" -#include -#include "prot.h" -#include "prot_fx.h" -#include "prot_fx_enc.h" -#include "rom_com.h" -#include "cnst.h" -#include "wmc_auto.h" -#include "ivas_prot.h" - -#define ONE_POINT_ONE_FIVE_Q7 147 -#define ONE_POINT_ONE_FIVE_Q23 9646899 - - -/*---------------------------------------------------------------------* - * AdaptLowFreqEmph() - * - * - *---------------------------------------------------------------------*/ - - -/*---------------------------------------------------------------------* - * ProcessIGF_ivas_fx() - * - * - *---------------------------------------------------------------------*/ -void ProcessIGF_ivas_fx( - Encoder_State *st, /* i : Encoder state */ - Word32 *pMDCTSpectrum, /* i : MDCT spectrum (*q_spectrum) */ - const Word32 *pITFMDCTSpectrum, /* i : MDCT spectrum fir ITF */ - Word16 *q_spectrum, /* i/o: Q of spectrum */ - Word32 *pPowerSpectrum, /* i : MDCT^2 + MDST^2 spectrum, or estimate (*q_powerSpec) */ - Word16 *q_powerSpec, /* i/o: Q of power spectrum */ - const Word16 isTCX20, /* i : flag indicating if the input is TCX20 or TCX10/2xTCX5 */ - const Word16 frameno, /* i : flag indicating index of current subframe */ - const Word16 sp_aud_decision0, /* i : first stage switching decision */ - const Word16 vad_hover_flag /* i : VAD hangover flag */ -) -{ - Word16 igfGridIdx, isIndepFlag, bsBits, pBsStart, curr_order; - Word16 predictionGain; - Word16 A[ITF_MAX_FILTER_ORDER + 1]; - Word16 q_A; - - IGF_ENC_INSTANCE_HANDLE hIGFEnc = st->hIGFEnc; - BSTR_ENC_HANDLE hBstr = st->hBstr; - - isIndepFlag = 1; - move16(); - test(); - IF( st->last_core == ACELP_CORE && isTCX20 ) - { - igfGridIdx = IGF_GRID_LB_TRAN; - move16(); - } - ELSE IF( isTCX20 ) - { - igfGridIdx = IGF_GRID_LB_NORM; - move16(); - } - ELSE - { - /* It is short block */ - igfGridIdx = IGF_GRID_LB_SHORT; - move16(); - if ( EQ_16( frameno, 1 ) ) - { - isIndepFlag = 0; - move16(); - } - } - - IGFSaveSpectrumForITF_ivas_fx( hIGFEnc, igfGridIdx, pITFMDCTSpectrum ); - - IGFEncApplyMono_ivas_fx( st, igfGridIdx, pMDCTSpectrum, sub( Q31, *q_spectrum ), pPowerSpectrum, sub( Q31, *q_powerSpec ), isTCX20, st->hTcxEnc->fUseTns[frameno], sp_aud_decision0, vad_hover_flag ); - - curr_order = 0; - move16(); - predictionGain = 0; - move16(); - q_A = 0; - move16(); - - ITF_Detect_fx( hIGFEnc->spec_be_igf, hIGFEnc->infoStartLine, hIGFEnc->infoStopLine, 8 /*maxOrder*/, A, &q_A, &predictionGain, &curr_order, sub( 31, hIGFEnc->spec_be_igf_e ) ); - - test(); - IF( LT_32( L_deposit_l( hIGFEnc->tns_predictionGain ), 9646899 /* 1.15 in Q23 */ ) && LT_32( L_deposit_l( predictionGain ), 9646899 /* 1.15 in Q23 */ ) ) - { - hIGFEnc->flatteningTrigger = 1; - move16(); - } - ELSE - { - hIGFEnc->flatteningTrigger = 0; - move16(); - } - - hIGFEnc->infoTotalBitsPerFrameWritten = 0; - move16(); - - IF( isTCX20 ) - { - IGFEncWriteBitstream_ivas_fx( hIGFEnc, NULL, &hIGFEnc->infoTotalBitsPerFrameWritten, igfGridIdx, isIndepFlag ); - } - ELSE - { - pBsStart = hBstr->nb_ind_tot; - move16(); - - IGFEncWriteBitstream_ivas_fx( hIGFEnc, hBstr, &hIGFEnc->infoTotalBitsPerFrameWritten, igfGridIdx, isIndepFlag ); - - bsBits = sub( hBstr->nb_ind_tot, pBsStart ); - IGFEncConcatenateBitstream( hIGFEnc, bsBits, hBstr ); - } - - return; -} - - -/*---------------------------------------------------------------------* - * ProcessStereoIGF() - * - * - *---------------------------------------------------------------------*/ - -void ProcessStereoIGF_fx( - STEREO_MDCT_ENC_DATA_HANDLE hStereoMdct, - Encoder_State *sts[CPE_CHANNELS], /* i : Encoder state */ - Word16 ms_mask[2][MAX_SFB], /* i : bandwise MS mask */ - Word32 *pITFMDCTSpectrum_fx[CPE_CHANNELS][NB_DIV], /* i : MDCT spectrum fir ITF */ - Word32 *pPowerSpectrum_fx[CPE_CHANNELS], /* i/o: MDCT^2 + MDST^2 spectrum, or estimate */ - Word32 *pPowerSpectrumMsInv_fx[CPE_CHANNELS][NB_DIV], /* i : inverse power spectrum */ - Word32 *inv_spectrum_fx[CPE_CHANNELS][NB_DIV], /* i : inverse spectrum */ - const Word16 frameno, /* i : flag indicating index of current subfr. */ - const Word16 sp_aud_decision0, /* i : sp_aud_decision0 */ - const Word32 element_brate /* i : element bitrate */ -) -{ - Word16 ch, igfGridIdx, isIndepFlag, bsBits, pBsStart, curr_order; - Word16 predictionGain; - Word16 A[ITF_MAX_FILTER_ORDER + 1]; - Word16 Q_A; - IGF_ENC_INSTANCE_HANDLE hIGFEnc[CPE_CHANNELS]; - BSTR_ENC_HANDLE hBstr; - hIGFEnc[0] = sts[0]->hIGFEnc; - hIGFEnc[1] = sts[1]->hIGFEnc; - - isIndepFlag = 1; - move16(); - - test(); - IF( sts[0]->last_core == ACELP_CORE && EQ_16( sts[0]->core, TCX_20_CORE ) ) - { - igfGridIdx = IGF_GRID_LB_TRAN; - } - ELSE IF( EQ_16( sts[0]->core, TCX_20_CORE ) ) - { - igfGridIdx = IGF_GRID_LB_NORM; - } - ELSE - { - /* It is short block */ - igfGridIdx = IGF_GRID_LB_SHORT; - if ( EQ_16( frameno, 1 ) ) - { - isIndepFlag = 0; - move16(); - } - } - move16(); - - IGFSaveSpectrumForITF_ivas_fx( hIGFEnc[0], igfGridIdx, pITFMDCTSpectrum_fx[0][frameno] ); - - IGFSaveSpectrumForITF_ivas_fx( hIGFEnc[1], igfGridIdx, pITFMDCTSpectrum_fx[1][frameno] ); - - - IGFEncApplyStereo_fx( hStereoMdct, ms_mask, hIGFEnc, igfGridIdx, sts, pPowerSpectrum_fx, pPowerSpectrumMsInv_fx, inv_spectrum_fx, frameno, sp_aud_decision0, element_brate ); - - FOR( ch = 0; ch < CPE_CHANNELS; ch++ ) - { - curr_order = 0; - move16(); - - Q_A = 0; - move16(); - - predictionGain = 0; - move16(); - - ITF_Detect_fx( hIGFEnc[ch]->spec_be_igf, hIGFEnc[ch]->infoStartLine, hIGFEnc[ch]->infoStopLine, 8 /*maxOrder*/, A, &Q_A, &predictionGain, &curr_order, sub( 31, hIGFEnc[ch]->spec_be_igf_e ) ); - - test(); - hIGFEnc[ch]->flatteningTrigger = LT_32( hIGFEnc[ch]->tns_predictionGain, ONE_POINT_ONE_FIVE_Q23 ) && LT_32( predictionGain, ONE_POINT_ONE_FIVE_Q7 ); - move16(); - - hIGFEnc[ch]->infoTotalBitsPerFrameWritten = 0; - move16(); - - IF( EQ_16( sts[ch]->core, TCX_20_CORE ) ) - { - IGFEncWriteBitstream_ivas_fx( hIGFEnc[ch], NULL, &hIGFEnc[ch]->infoTotalBitsPerFrameWritten, igfGridIdx, isIndepFlag ); - } - ELSE - { - hBstr = sts[ch]->hBstr; - pBsStart = hBstr->nb_ind_tot; - move16(); - - if ( ch > 0 ) - { - hBstr->ind_list = sts[0]->hBstr->ind_list + sts[0]->hBstr->nb_ind_tot; - } - IGFEncWriteBitstream_ivas_fx( hIGFEnc[ch], hBstr, &hIGFEnc[ch]->infoTotalBitsPerFrameWritten, igfGridIdx, isIndepFlag ); - - bsBits = sub( hBstr->nb_ind_tot, pBsStart ); - IGFEncConcatenateBitstream( hIGFEnc[ch], bsBits, hBstr ); - } - } - return; -} diff --git a/lib_enc/tcx_utils_enc_fx.c b/lib_enc/tcx_utils_enc_fx.c index 576f98d41fb85d5d9280cec00e10853079c859af..ce7f0e6a6e446c94e058f7d9f2336cda1d28a8a7 100644 --- a/lib_enc/tcx_utils_enc_fx.c +++ b/lib_enc/tcx_utils_enc_fx.c @@ -15,10 +15,14 @@ #include "rom_com.h" #include "prot_fx.h" /* Function prototypes */ #include "prot_fx_enc.h" /* Function prototypes */ +#include "ivas_prot_fx.h" #define inv_int InvIntTable extern const Word16 int_sqr[17]; +#define ONE_POINT_ONE_FIVE_Q7 147 +#define ONE_POINT_ONE_FIVE_Q23 9646899 + static Word16 quantize( Word32 x, Word16 invGain, Word16 shift, Word32 offset ) { Word16 tmp16; @@ -28,8 +32,10 @@ static Word16 quantize( Word32 x, Word16 invGain, Word16 shift, Word32 offset ) tmp32 = L_shl( tmp32, shift ); /* convert to 15Q16 */ tmp32 = L_add( tmp32, offset ); /* add offset */ tmp16 = extract_h( tmp32 ); /* truncate */ - if ( x < 0 ) + IF( x < 0 ) + { tmp16 = negate( tmp16 ); /* restore sign */ + } return tmp16; } @@ -42,12 +48,11 @@ void ComputeSpectrumNoiseMeasure_fx( const Word32 *powerSpec, Word8 *noiseFlags, Word16 lowpassLine ) { - Word16 i, lastTone; + Word16 i, lastTone, j; Word32 s, c; Word16 tmp16; Word32 tmp1, tmp2 = 0; /* initialization only to avoid compiler warning, not counted */ - - int j; + move32(); IF( resetMemory != 0 ) { @@ -74,12 +79,12 @@ void ComputeSpectrumNoiseMeasure_fx( const Word32 *powerSpec, i = sub( startLine, 1 ); s = 0; move32(); - for ( j = -7; j < 8; j++ ) + FOR( j = -7; j < 8; j++ ) { s = L_add( s, L_shr( powerSpec[i + j], 4 ) ); } tmp16 = sub( lowpassLine, 7 ); - FOR( i = add( i, 1 ); i < tmp16; i++ ) + FOR( i = i + 1; i < tmp16; i++ ) { c = L_shr( powerSpec[i - 1], 4 ); c = L_add( c, L_shr( powerSpec[i], 4 ) ); @@ -89,12 +94,18 @@ void ComputeSpectrumNoiseMeasure_fx( const Word32 *powerSpec, s = L_add( s, L_shr( powerSpec[i + 7], 4 ) ); tmp1 = L_shr( c, 2 ); - if ( noiseFlags[i] == 0 ) + IF( noiseFlags[i] == 0 ) + { c = L_shl( c, 1 ); - if ( noiseFlags[i] == 0 ) + } + IF( noiseFlags[i] == 0 ) + { tmp2 = L_sub( c, tmp1 ); /* 1.75 * c */ - if ( noiseFlags[i] != 0 ) + } + IF( noiseFlags[i] != 0 ) + { tmp2 = L_add( c, tmp1 ); /* 1.25 * c */ + } tmp2 = L_sub( s, tmp2 ); if ( tmp2 >= 0 ) @@ -123,12 +134,18 @@ void ComputeSpectrumNoiseMeasure_fx( const Word32 *powerSpec, c = L_add( c, L_shr( powerSpec[i + 1], 4 ) ); tmp1 = L_shr( c, 2 ); - if ( noiseFlags[i] == 0 ) + IF( noiseFlags[i] == 0 ) + { c = L_shl( c, 1 ); - if ( noiseFlags[i] == 0 ) + } + IF( noiseFlags[i] == 0 ) + { tmp2 = L_sub( c, tmp1 ); /* 1.75 * c */ - if ( noiseFlags[i] != 0 ) + } + IF( noiseFlags[i] != 0 ) + { tmp2 = L_add( c, tmp1 ); /* 1.25 * c */ + } /* running sum can't be updated any more, just use the latest one */ tmp2 = L_sub( s, tmp2 ); @@ -161,30 +178,24 @@ static void detectLowpassFac( const Word32 *powerSpec, Word16 powerSpec_e, Word1 Word32 threshold; #ifdef BASOP_NOGLOB_DECLARE_LOCAL Flag Overflow = 0; + move32(); #endif threshold = 256l /*0.1f * 2*NORM_MDCT_FACTOR Q3*/; /* Q3 */ - BASOP_SATURATE_WARNING_OFF_EVS /* Allow saturation, because threshold is being compared to powerSpec[i] below. */ -#ifdef BASOP_NOGLOB + move32(); + BASOP_SATURATE_WARNING_OFF_EVS /* Allow saturation, because threshold is being compared to powerSpec[i] below. */ threshold = L_shl_o( threshold, sub( 28, powerSpec_e ), &Overflow ); -#else /* BASOP_NOGLOB */ - threshold = L_shl( threshold, sub( 28, powerSpec_e ) ); -#endif /* BASOP_NOGLOB */ - if ( rectWin != 0 ) + IF( rectWin != 0 ) { /* compensate for bad side-lobe attenuation with asymmetric windows */ -#ifdef BASOP_NOGLOB threshold = L_shl_o( threshold, 1, &Overflow ); -#else - threshold = L_shl( threshold, 1 ); -#endif } BASOP_SATURATE_WARNING_ON_EVS tmp = shr( lowpassLine, 1 ); - FOR( i = sub( lowpassLine, 1 ); i >= tmp; i-- ) + FOR( i = lowpassLine - 1; i >= tmp; i-- ) { IF( GT_32( powerSpec[i], threshold ) ) { @@ -245,7 +256,7 @@ void AnalyzePowerSpectrum_fx( s2 = 0; move16(); tmp = sub( mdctSpectrum_e, *powerSpec_e ); - if ( tmp > 0 ) + IF( tmp > 0 ) { s2 = negate( tmp ); } @@ -264,18 +275,10 @@ void AnalyzePowerSpectrum_fx( /* power spectrum: MDCT^2 + MDST^2 */ FOR( i = iStart; i < iEnd; i++ ) { -#ifdef BASOP_NOGLOB tmp = round_fx_sat( L_shl_sat( mdctSpectrum[i], s1 ) ); -#else - tmp = round_fx( L_shl( mdctSpectrum[i], s1 ) ); -#endif tmp32 = L_mult0( tmp, tmp ); -#ifdef BASOP_NOGLOB tmp = round_fx_sat( L_shl_sat( powerSpec[i], s2 ) ); -#else - tmp = round_fx( L_shl( powerSpec[i], s2 ) ); -#endif tmp32 = L_mac0( tmp32, tmp, tmp ); powerSpec[i] = tmp32; @@ -305,7 +308,6 @@ void AnalyzePowerSpectrum_fx( { lowpassLine = shl( mult( st->hTcxCfg->bandwidth, L_frame ), 1 ); - test(); detectLowpassFac( powerSpec, *powerSpec_e, L_frame, sub( st->last_core, ACELP_CORE ) == 0, @@ -319,6 +321,105 @@ void AnalyzePowerSpectrum_fx( } } +void AnalyzePowerSpectrum_ivas_fx( + Encoder_State *st, /* i/o: encoder states */ + Word16 L_frame, /* input: frame length */ + Word16 L_frameTCX, /* input: full band frame length */ + Word16 left_overlap, /* input: left overlap length */ + Word16 right_overlap, /* input: right overlap length */ + Word32 const mdctSpectrum[], /* input: MDCT spectrum */ + Word16 mdctSpectrum_e, + Word16 const signal[], /* input: windowed signal corresponding to mdctSpectrum */ + Word32 powerSpec[], /* output: Power spectrum. Can point to signal */ + Word16 powerSpec_e[] ) +{ + Word16 i, iStart, iEnd, lowpassLine; + Word16 shift; + Word32 tmp32; + Word8 tmp8; + TCX_ENC_HANDLE hTcxEnc = st->hTcxEnc; + Word32 common_powerSpec[N_MAX + L_MDCT_OVLP_MAX]; + lowpassLine = L_frameTCX; + move16(); + + Word16 temp_powerSpec_e = 16; + move16(); + TCX_MDST( signal, powerSpec, &temp_powerSpec_e, left_overlap, sub( L_frameTCX, shr( add( left_overlap, right_overlap ), 1 ) ), right_overlap, st->element_mode ); + + shift = L_norm_arr( powerSpec, N_MAX + L_MDCT_OVLP_MAX ); + scale_sig32( powerSpec, N_MAX + L_MDCT_OVLP_MAX, shift ); + set16_fx( powerSpec_e, sub( temp_powerSpec_e, shift ), N_MAX + L_MDCT_OVLP_MAX ); + + iStart = 0; + move16(); + iEnd = L_frameTCX; + move16(); + + IF( st->narrowBand != 0 ) + { + attenuateNbSpectrum_fx( L_frameTCX, powerSpec ); + } + + temp_powerSpec_e = MIN16B; + move16(); + /* power spectrum: MDCT^2 + MDST^2 */ + FOR( i = iStart; i < iEnd; i++ ) + { + powerSpec[i] = Mpy_32_32( powerSpec[i], powerSpec[i] ); + move32(); + shift = norm_l( mdctSpectrum[i] ); + tmp32 = L_shl( mdctSpectrum[i], shift ); + powerSpec[i] = BASOP_Util_Add_Mant32Exp( powerSpec[i], shl( powerSpec_e[i], 1 ), Mpy_32_32( tmp32, tmp32 ), shl( sub( mdctSpectrum_e, shift ), 1 ), &powerSpec_e[i] ); + move32(); + IF( LT_16( powerSpec_e[i], -31 ) ) + { + powerSpec[i] = L_shl( powerSpec[i], sub( powerSpec_e[i], -31 ) ); + move32(); + powerSpec_e[i] = -31; + move16(); + } + temp_powerSpec_e = s_max( temp_powerSpec_e, powerSpec_e[i] ); + } + + FOR( i = 0; i < N_MAX + L_MDCT_OVLP_MAX; i++ ) + { + common_powerSpec[i] = L_shl( powerSpec[i], sub( powerSpec_e[i], temp_powerSpec_e ) ); + move32(); + } + + tmp8 = 0; + move16(); + test(); + if ( L_msu0( L_mult0( st->L_frame, extract_l( st->last_sr_core ) ), st->L_frame_past, extract_l( st->sr_core ) ) != 0 || NE_16( st->last_core, TCX_20_CORE ) ) + { + tmp8 = 1; + move16(); + } + + ComputeSpectrumNoiseMeasure_fx( common_powerSpec, + L_frameTCX, + divide3216( L_mult( hTcxEnc->nmStartLine, L_frame ), st->L_frame ), + tmp8, + hTcxEnc->memQuantZeros, + lowpassLine ); + + IF( LE_32( st->total_brate, ACELP_24k40 ) ) + { + lowpassLine = shl( mult( st->hTcxCfg->bandwidth, L_frame ), 1 ); + + detectLowpassFac( common_powerSpec, temp_powerSpec_e, + L_frame, + sub( st->last_core, ACELP_CORE ) == 0, + &hTcxEnc->measuredBwRatio, + lowpassLine ); + } + ELSE + { + hTcxEnc->measuredBwRatio = 0x4000; + move16(); + } +} + void AdaptLowFreqEmph_fx( Word32 x[], Word16 x_e, Word16 xq[], @@ -353,6 +454,7 @@ void AdaptLowFreqEmph_fx( Word32 x[], /* Debug initialization to catch illegal cases of xq[i] */ tmp16 = 0; + move16(); if ( xq[i] > 0 ) { @@ -406,6 +508,7 @@ void AdaptLowFreqEmph_fx( Word32 x[], /* Debug initialization to catch illegal cases of xq[i] */ tmp16 = 0; + move16(); if ( xq[i] > 0 ) { @@ -459,6 +562,7 @@ void AdaptLowFreqEmph_fx( Word32 x[], /* Debug initialization to catch illegal cases of xq[i] */ tmp16 = 0; + move16(); if ( xq[i] > 0 ) { @@ -491,6 +595,7 @@ void AdaptLowFreqEmph_fx( Word32 x[], /* Debug initialization to catch illegal cases of xq[i] */ tmp16 = 0; + move16(); if ( xq[i] > 0 ) { @@ -609,20 +714,27 @@ Word16 SQ_gain_fx( /* output: SQ gain */ move16(); tmp16 = norm_l( x[0] ); - if ( x[0] != 0 ) + IF( x[0] != 0 ) + { s = s_min( s, tmp16 ); + } tmp16 = norm_l( x[1] ); - if ( x[1] != 0 ) + IF( x[1] != 0 ) + { s = s_min( s, tmp16 ); + } tmp16 = norm_l( x[2] ); - if ( x[2] != 0 ) + IF( x[2] != 0 ) + { s = s_min( s, tmp16 ); - + } tmp16 = norm_l( x[3] ); - if ( x[3] != 0 ) + IF( x[3] != 0 ) + { s = s_min( s, tmp16 ); + } s = sub( s, 2 ); /* 2 bits headroom */ @@ -667,7 +779,130 @@ Word16 SQ_gain_fx( /* output: SQ gain */ tmp32 = L_sub( en[i], offset ); /* avoid SV with 1 bin of amp < 0.5f */ - if ( GT_32( tmp32, 0xFF20 ) ) /* 0xFF20 -> 0.3*log2(10); */ + IF( GT_32( tmp32, 0xFF20 ) ) /* 0xFF20 -> 0.3*log2(10); */ + { + ener = L_add( ener, tmp32 ); + } + + /* if ener is above target -> break and increase offset */ + IF( GT_32( ener, target ) ) + { + offset = L_add( offset, fac ); + BREAK; + } + } + } + + offset = L_add( L_shr( offset, 1 ), 0x17EB0 ); /* 0x17EB0 -> 0.45*log2(10) */ + + *gain_e = add( extract_h( offset ), 1 ); + move16(); + offset = L_sub( L_and( offset, 0xFFFF ), 0x10000 ); + tmp16 = extract_h( BASOP_Util_InvLog2( L_shl( offset, 9 ) ) ); + + /* return gain */ + + return tmp16; +} + +Word16 SQ_gain_ivas_fx( /* output: SQ gain */ + Word32 x[], /* input: vector to quantize */ + Word16 x_e, /* input: exponent */ + Word16 nbitsSQ, /* input: number of bits targeted */ + Word16 lg, /* input: vector size (2048 max) */ + Word16 *gain_e ) /* output: SQ gain exponent */ +{ + Word16 i, iter, lg_4, s, tmp16; + Word32 ener, tmp32; + Word32 target, fac, offset; + Word32 en[N_MAX / 4]; + + + lg_4 = shr( lg, 2 ); + + /* energy of quadruples with 9dB offset */ + FOR( i = 0; i < lg_4; i++ ) + { + /* normalization */ + s = 15; + move16(); + + tmp16 = norm_l( x[0] ); + IF( x[0] != 0 ) + { + s = s_min( s, tmp16 ); + } + + tmp16 = norm_l( x[1] ); + IF( x[1] != 0 ) + { + s = s_min( s, tmp16 ); + } + + tmp16 = norm_l( x[2] ); + IF( x[2] != 0 ) + { + s = s_min( s, tmp16 ); + } + + tmp16 = norm_l( x[3] ); + IF( x[3] != 0 ) + { + s = s_min( s, tmp16 ); + } + + s = sub( s, 2 ); /* 2 bits headroom */ + + /* calc quadruple energy */ + ener = L_deposit_l( 1 ); + + tmp16 = extract_h( L_shl( x[0], s ) ); + ener = L_mac( ener, tmp16, tmp16 ); + + tmp16 = extract_h( L_shl( x[1], s ) ); + ener = L_mac( ener, tmp16, tmp16 ); + + tmp16 = extract_h( L_shl( x[2], s ) ); + ener = L_mac( ener, tmp16, tmp16 ); + + tmp16 = extract_h( L_shl( x[3], s ) ); + ener = L_mac( ener, tmp16, tmp16 ); + + s = shl( sub( x_e, s ), 1 ); + + /* log */ + IF( EQ_32( ener, 1 ) ) + { + en[i] = -131072; /* log10(0.01) in Q16 */ + move32(); + } + ELSE + { + tmp32 = L_add( BASOP_Util_Log2( ener ), L_shl( L_deposit_l( s ), 25 ) ); /* log2, 6Q25 */ + en[i] = L_shr( tmp32, 9 ); /* 15Q16 */ + move32(); + } + x += 4; + } + + /* SQ scale: 4 bits / 6 dB per quadruple */ + target = L_mult( 0x3FC8, sub( nbitsSQ, shr( lg, 4 ) ) ); /* 0x3FC8 -> 0.15*log2(10) */ + fac = L_add( 0x2A854B, 0 ); /* -> 12.8f*log2(10); */ + offset = L_add( fac, 0 ); + + /* find offset (0 to 128 dB with step of 0.125dB) */ + FOR( iter = 0; iter < 10; iter++ ) + { + fac = L_shr( fac, 1 ); + offset = L_sub( offset, fac ); + ener = L_deposit_l( 0 ); + + FOR( i = 0; i < lg_4; i++ ) + { + tmp32 = L_sub( en[i], offset ); + + /* avoid SV with 1 bin of amp < 0.5f */ + IF( GT_32( tmp32, 0xFF20 ) ) /* 0xFF20 -> 0.3*log2(10); */ { ener = L_add( ener, tmp32 ); } @@ -728,6 +963,7 @@ Word16 SQ_gain_estimate_fx( /* output: SQ gain tmp = 204644; tmpp = 0; move32(); + move32(); BREAK; case 200: tmp = 215192; @@ -827,20 +1063,28 @@ Word16 SQ_gain_estimate_fx( /* output: SQ gain move16(); tmp16 = norm_l( x[0] ); - if ( x[0] != 0 ) + IF( x[0] != 0 ) + { s = s_min( s, tmp16 ); + } tmp16 = norm_l( x[1] ); - if ( x[1] != 0 ) + IF( x[1] != 0 ) + { s = s_min( s, tmp16 ); + } tmp16 = norm_l( x[2] ); - if ( x[2] != 0 ) + IF( x[2] != 0 ) + { s = s_min( s, tmp16 ); + } tmp16 = norm_l( x[3] ); - if ( x[3] != 0 ) + IF( x[3] != 0 ) + { s = s_min( s, tmp16 ); + } s = sub( s, 2 ); /* 2 bits headroom */ @@ -933,6 +1177,8 @@ void tcx_scalar_quantization_fx( tmp16 = negate( s_max( tmp16, 0 ) ); i = sub( L_frame, 1 ); + + test(); WHILE( ( memQuantZeros_fx[i] != 0 ) && ( LT_32( L_abs( L_shl( x[i], tmp16 ) ), tmp32 ) ) ) { test(); @@ -952,6 +1198,8 @@ void tcx_scalar_quantization_fx( /* Limit the inverse gain to maximal possible value=sqrtL_spec/NORM_MDCT_FACTOR)*/ gain = 22435; /*sqrt(1200/NORM_MDCT_FACTOR) in 2Q13*/ gain_e = 2; + move16(); + move16(); s = sub( add( x_e, gain_e ), 15 ); } @@ -964,15 +1212,12 @@ void tcx_scalar_quantization_fx( FOR( ; i >= 0; i-- ) { offs32 = Mpy_32_16_1( L_abs( x[i] ), gain ); /* multiply */ -#ifdef BASOP_NOGLOB - offs32 = L_shl_sat( offs32, s ); /* convert to 15Q16 */ - tmp16 = mac_r_sat( offs32, offset, 1 ); /* add offset and truncate */ -#else - offs32 = L_shl( offs32, s ); /* convert to 15Q16 */ - tmp16 = mac_r( offs32, offset, 1 ); /* add offset and truncate */ -#endif - if ( x[i] < 0 ) + offs32 = L_shl_sat( offs32, s ); /* convert to 15Q16 */ + tmp16 = mac_r_sat( offs32, offset, 1 ); /* add offset and truncate */ + IF( x[i] < 0 ) + { tmp16 = negate( tmp16 ); /* restore sign */ + } xq[i] = tmp16; move16(); @@ -1029,7 +1274,9 @@ void tcx_scalar_quantization_ivas_fx( { /* Limit the inverse gain to maximal possible value=sqrtL_spec/NORM_MDCT_FACTOR)*/ gain = 22435; /*sqrt(1200/NORM_MDCT_FACTOR) in 2Q13*/ + move16(); gain_e = 2; + move16(); s = sub( add( x_e, gain_e ), 15 ); } @@ -1042,15 +1289,12 @@ void tcx_scalar_quantization_ivas_fx( FOR( ; i >= 0; i-- ) { offs32 = Mpy_32_16_1( L_abs( x[i] ), gain ); /* multiply */ -#ifdef BASOP_NOGLOB - offs32 = L_shl_sat( offs32, s ); /* convert to 15Q16 */ - tmp16 = mac_r_sat( offs32, offset, 1 ); /* add offset and truncate */ -#else - offs32 = L_shl( offs32, s ); /* convert to 15Q16 */ - tmp16 = mac_r( offs32, offset, 1 ); /* add offset and truncate */ -#endif - if ( x[i] < 0 ) + offs32 = L_shl_sat( offs32, s ); /* convert to 15Q16 */ + tmp16 = mac_r_sat( offs32, offset, 1 ); /* add offset and truncate */ + IF( x[i] < 0 ) + { tmp16 = negate( tmp16 ); /* restore sign */ + } xq[i] = tmp16; move16(); @@ -1104,6 +1348,10 @@ Word16 tcx_scalar_quantization_rateloop_fx( Word16 tmp, fac1, fac2; Word32 tmp32; Word16 lastnz; + move16(); + move16(); + move16(); + move16(); /* Init */ @@ -1178,11 +1426,7 @@ Word16 tcx_scalar_quantization_rateloop_fx( /* convert to normalized 16 bit */ tmp = norm_l( tmp32 ); -#ifdef BASOP_NOGLOB sqGain = round_fx_sat( L_shl( tmp32, tmp ) ); -#else - sqGain = round_fx( L_shl( tmp32, tmp ) ); -#endif sqGain_e = sub( sqGain_e, tmp ); /* divide */ @@ -1218,11 +1462,7 @@ Word16 tcx_scalar_quantization_rateloop_fx( /* convert to normalized 16 bit */ tmp = norm_l( tmp32 ); -#ifdef BASOP_NOGLOB sqGain = round_fx_sat( L_shl_sat( tmp32, tmp ) ); -#else - sqGain = round_fx( L_shl( tmp32, tmp ) ); -#endif sqGain_e = sub( sqGain_e, tmp ); /* divide */ @@ -1546,11 +1786,7 @@ Word16 tcx_scalar_quantization_rateloop_ivas_fx( /* convert to normalized 16 bit */ tmp = norm_l( tmp32 ); -#ifdef BASOP_NOGLOB sqGain = round_fx_sat( L_shl( tmp32, tmp ) ); -#else - sqGain = round_fx( L_shl( tmp32, tmp ) ); -#endif sqGain_e = sub( sqGain_e, tmp ); /* divide */ @@ -1586,11 +1822,7 @@ Word16 tcx_scalar_quantization_rateloop_ivas_fx( /* convert to normalized 16 bit */ tmp = norm_l( tmp32 ); -#ifdef BASOP_NOGLOB sqGain = round_fx_sat( L_shl_sat( tmp32, tmp ) ); -#else - sqGain = round_fx( L_shl( tmp32, tmp ) ); -#endif sqGain_e = sub( sqGain_e, tmp ); /* divide */ @@ -1605,6 +1837,7 @@ Word16 tcx_scalar_quantization_rateloop_ivas_fx( } Word16 shift_tmp = s_max( sqGain_e, 1 ); + move16(); test(); IF( LT_16( shl( sqGain, sub( sqGain_e, shift_tmp ) ), shl( minSqGain, sub( 1, shift_tmp ) ) ) && EQ_16( tcxRateLoopOpt, 3 ) ) { @@ -1690,7 +1923,7 @@ Word16 tcx_scalar_quantization_rateloop_ivas_fx( IF( GT_16( element_mode, EVS_MONO ) ) { - sqBits = RCcontextMapping_encode2_estimate_no_mem_s17_LCS( xq, L_frame, &lastnz, nEncoded, target, &stopFlag, 0, hm_cfg ); + sqBits = RCcontextMapping_encode2_estimate_no_mem_s17_LCS_fx( xq, L_frame, &lastnz, nEncoded, target, &stopFlag, 0, hm_cfg ); } ELSE { @@ -1768,11 +2001,7 @@ void QuantizeGain( Word16 n, Word16 *pGain, Word16 *pGain_e, Word16 *pQuantizedG move32(); #endif -#ifdef BASOP_NOGLOB ener = mult_r( shl_o( n, 5, &Overflow ), 26214 /*128.f/NORM_MDCT_FACTOR Q15*/ ); -#else - ener = mult_r( shl( n, 5 ), 26214 /*128.f/NORM_MDCT_FACTOR Q15*/ ); -#endif ener_e = 15 - 5 - 7; move16(); IF( GE_16( n, 1024 ) ) @@ -1844,6 +2073,7 @@ void tcx_noise_factor_fx( Word32 xMax; #ifdef BASOP_NOGLOB_DECLARE_LOCAL Flag Overflow = 0; + move32(); #endif @@ -1928,19 +2158,19 @@ void tcx_noise_factor_fx( k = 0; move16(); - if ( accu1 == 0 ) + IF( accu1 == 0 ) + { accu1 = L_deposit_l( 1 ); - if ( accu2 == 0 ) + } + IF( accu2 == 0 ) + { accu2 = L_deposit_l( 1 ); + } att = BASOP_Util_Divide3232_Scale( L_shl( L_min( accu1, accu2 ), 1 ), L_add( accu1, accu2 ), &s ); att = Sqrt16( att, &s ); BASOP_SATURATE_WARNING_OFF_EVS; /* att is always <= 1.0 */ -#ifdef BASOP_NOGLOB att = shl_o( att, s, &Overflow ); -#else - att = shl( att, s ); -#endif BASOP_SATURATE_WARNING_ON_EVS; } ELSE @@ -1965,22 +2195,34 @@ void tcx_noise_factor_fx( IF( LE_16( nTransWidth, 3 ) ) { tmp2 = sub( k, c1 ); - if ( tmp2 > 0 ) + IF( tmp2 > 0 ) + { n = L_msu( n, k, (Word16) 0x8000 ); - if ( tmp2 > 0 ) + } + IF( tmp2 > 0 ) + { n = L_mac( n, nTransWidth_1, (Word16) 0x8000 ); - if ( tmp2 <= 0 ) + } + IF( tmp2 <= 0 ) + { n = L_mac( n, int_sqr[k], c2 ); + } } ELSE { tmp2 = sub( k, 12 ); - if ( tmp2 > 0 ) + IF( tmp2 > 0 ) + { n = L_msu( n, k, (Word16) 0x8000 ); - if ( tmp2 > 0 ) + } + IF( tmp2 > 0 ) + { n = L_sub( n, 0x70000 ); - if ( tmp2 <= 0 ) + } + IF( tmp2 <= 0 ) + { n = L_mac( n, int_sqr[k], 1152 /*0.03515625f Q15*/ ); + } } sqErrorNrg = L_add( sqErrorNrg, accu1 ); accu1 = L_deposit_l( 0 ); /* segment ended here, so reset segment sum */ @@ -1999,19 +2241,19 @@ void tcx_noise_factor_fx( } ELSE /* current line is zero, so update pointers & segment sum */ { - if ( LT_16( k, nTransWidth ) ) + IF( LT_16( k, nTransWidth ) ) { k = add( k, 1 ); } tmp2 = sub( maxK, nTransWidth ); - if ( tmp2 < 0 ) + IF( tmp2 < 0 ) { maxK = sub( maxK, 1 ); } test(); - if ( ( tmp2 >= 0 ) && ( sqQ[i + sub( nTransWidth, 1 )] != 0 ) ) + IF( ( tmp2 >= 0 ) && ( sqQ[i + sub( nTransWidth, 1 )] != 0 ) ) { maxK = sub( nTransWidth, 1 ); } @@ -2036,22 +2278,34 @@ void tcx_noise_factor_fx( IF( LE_16( nTransWidth, 3 ) ) { tmp2 = sub( k, c1 ); - if ( tmp2 > 0 ) + IF( tmp2 > 0 ) + { n = L_msu( n, k, (Word16) 0x8000 ); - if ( tmp2 > 0 ) + } + IF( tmp2 > 0 ) + { n = L_mac( n, nTransWidth_1, (Word16) 0x8000 ); - if ( tmp2 <= 0 ) + } + IF( tmp2 <= 0 ) + { n = L_mac( n, int_sqr[k], c2 ); + } } ELSE { tmp2 = sub( k, 12 ); - if ( tmp2 > 0 ) + IF( tmp2 > 0 ) + { n = L_msu( n, k, (Word16) 0x8000 ); - if ( tmp2 > 0 ) + } + IF( tmp2 > 0 ) + { n = L_sub( n, 0x70000 ); - if ( tmp2 <= 0 ) + } + IF( tmp2 <= 0 ) + { n = L_mac( n, int_sqr[k], 1152 /*0.03515625f Q15*/ ); + } } sqErrorNrg = L_add( sqErrorNrg, accu1 ); } @@ -2059,11 +2313,11 @@ void tcx_noise_factor_fx( } ELSE /* current line is zero, so update pointers & energy sum */ { - if ( LT_16( k, nTransWidth ) ) + IF( LT_16( k, nTransWidth ) ) { k = add( k, 1 ); } - if ( LT_16( maxK, nTransWidth ) ) + IF( LT_16( maxK, nTransWidth ) ) { maxK = sub( maxK, 1 ); } @@ -2081,22 +2335,34 @@ void tcx_noise_factor_fx( IF( LE_16( nTransWidth, 3 ) ) { tmp2 = sub( k, c1 ); - if ( tmp2 > 0 ) + IF( tmp2 > 0 ) + { n = L_msu( n, k, (Word16) 0x8000 ); - if ( tmp2 > 0 ) + } + IF( tmp2 > 0 ) + { n = L_mac( n, nTransWidth_1, (Word16) 0x8000 ); - if ( tmp2 <= 0 ) + } + IF( tmp2 <= 0 ) + { n = L_mac( n, int_sqr[k], c2 ); + } } ELSE { tmp2 = sub( k, 12 ); - if ( tmp2 > 0 ) + IF( tmp2 > 0 ) + { n = L_msu( n, k, (Word16) 0x8000 ); - if ( tmp2 > 0 ) + } + IF( tmp2 > 0 ) + { n = L_sub( n, 0x70000 ); - if ( tmp2 <= 0 ) + } + IF( tmp2 <= 0 ) + { n = L_mac( n, int_sqr[k], 1152 /*0.03515625f Q15*/ ); + } } sqErrorNrg = L_add( sqErrorNrg, accu1 ); } @@ -2107,11 +2373,7 @@ void tcx_noise_factor_fx( tmp1 = BASOP_Util_Divide3232_Scale( Mpy_32_16_1( sqErrorNrg, att ), n, &s ); s = add( add( add( s, x_orig_e ), inv_gain2_e ), 7 - 15 ); BASOP_SATURATE_WARNING_OFF_EVS; -#ifdef BASOP_NOGLOB tmp1 = shl_o( tmp1, s, &Overflow ); -#else /* BASOP_NOGLOB */ - tmp1 = shl( tmp1, s ); -#endif BASOP_SATURATE_WARNING_ON_EVS; } ELSE @@ -2135,6 +2397,7 @@ void tcx_noise_factor_fx( *fac_ns = extract_l( L_mult0( *quantized_fac_ns, shr( 24576 /*0.75f Q15*/, NBITS_NOISE_FILL_LEVEL ) ) ); } + void tcx_noise_factor_ivas_fx( Word32 *x_orig, /* i: unquantized mdct coefficients */ Word16 x_orig_e, /* i: exponent */ @@ -2151,29 +2414,32 @@ void tcx_noise_factor_ivas_fx( Word16 element_mode /* i: element mode */ ) { - Word16 i, k = 0, maxK, segmentOffset; - Word32 sqErrorNrg, n; - Word16 inv_gain2, inv_gain2_e, tilt_factor, nTransWidth_1; + Word16 i, k, win, segmentOffset, j; + Word32 sqErrorNrg = 0, n; + move32(); + Word16 inv_gain2, inv_gain2_e, tilt_factor, nTransWidth_1, exp_sqErrorNrg = 0; + move16(); Word32 accu1, accu2, tmp32; Word16 tmp1, tmp2, s; Word16 c1, c2; Word16 att; /* noise level attenuation factor for transient windows */ Word32 xMax; + Word16 exp_spQ[N_MAX]; #ifdef BASOP_NOGLOB_DECLARE_LOCAL Flag Overflow = 0; move32(); #endif - move16(); assert( nTransWidth <= 16 ); + set16_fx( exp_spQ, x_orig_e, N_MAX ); c1 = sub( shl( nTransWidth, 1 ), 4 ); c2 = mult( 9216 /*0.28125f Q15*/, inv_int[nTransWidth] ); nTransWidth_1 = sub( nTransWidth, 1 ); /*Adjust noise filling level*/ - sqErrorNrg = L_deposit_l( 0 ); - n = L_deposit_l( 0 ); + n = 0; + move32(); /* get inverse frame length */ tmp1 = getInvFrameLen( L_frame ); @@ -2185,10 +2451,8 @@ void tcx_noise_factor_ivas_fx( /* inv_gain2 = 1.0f / ((float)(nTransWidth * nTransWidth) * gain_tcx); */ tmp32 = L_mult( imult1616( nTransWidth, nTransWidth ), gain_tcx ); /* 15Q16 */ - tmp1 = norm_l( tmp32 ); - inv_gain2 = round_fx( L_shl( tmp32, tmp1 ) ); - inv_gain2_e = add( sub( 15, tmp1 ), gain_tcx_e ); - inv_gain2 = Inv16( inv_gain2, &inv_gain2_e ); + inv_gain2 = BASOP_Util_Divide3232_Scale( MAX_32, tmp32, &inv_gain2_e ); + inv_gain2_e = add( inv_gain2_e, sub( 0, add( 15, gain_tcx_e ) ) ); inv_gain2 = shr( inv_gain2, 2 ); /* 2 bits headroom */ inv_gain2_e = add( inv_gain2_e, 2 ); @@ -2199,15 +2463,13 @@ void tcx_noise_factor_ivas_fx( IF( EQ_16( element_mode, IVAS_CPE_MDCT ) ) /* ... but only in mono or parametric stereo since it may cause binaural unmasking in discrete stereo */ { segmentOffset = i; - maxK = 1; - move16(); move16(); } ELSE { /* find last nonzero line below iFirstLine, use it as start offset */ tmp1 = shr( iFirstLine, 1 ); - FOR( i = iFirstLine; i > tmp1; i-- ) + FOR( ; i > tmp1; i-- ) { IF( sqQ[i] != 0 ) { @@ -2220,16 +2482,6 @@ void tcx_noise_factor_ivas_fx( inv_gain2 = shl( mult( inv_gain2, tilt_factor ), 1 ); } - /* initialize left (k) and right (maxK) non-zero neighbor pointers */ - k = 0; - move16(); - FOR( maxK = 1; maxK < nTransWidth; maxK++ ) - { - IF( sqQ[i + maxK] != 0 ) - { - BREAK; - } - } i = add( i, 1 ); segmentOffset = i; move16(); @@ -2237,17 +2489,20 @@ void tcx_noise_factor_ivas_fx( IF( LE_16( nTransWidth, 3 ) ) { - accu1 = L_deposit_l( 0 ); - accu2 = L_deposit_l( 0 ); - xMax = L_deposit_l( 0 ); + accu1 = 0; + move32(); + accu2 = 0; + move32(); + xMax = 0; + move32(); - FOR( k = s_and( i, (Word16) 0xFFFE ); k < lowpassLine; k++ ) + FOR( k = i & 0xFFFE; k < lowpassLine; k++ ) { xMax = L_max( xMax, L_abs( x_orig[k] ) ); } s = sub( norm_l( xMax ), 4 ); - FOR( k = s_and( i, (Word16) 0xFFFE ); k < lowpassLine; k += 2 ) + FOR( k = i & 0xFFFE; k < lowpassLine; k += 2 ) { /* even-index bins, left sub-win */ tmp1 = round_fx( L_shl( x_orig[k], s ) ); @@ -2261,18 +2516,20 @@ void tcx_noise_factor_ivas_fx( move16(); if ( accu1 == 0 ) - accu1 = L_deposit_l( 1 ); + { + accu1 = 1; + move32(); + } if ( accu2 == 0 ) - accu2 = L_deposit_l( 1 ); + { + accu2 = 1; + move32(); + } att = BASOP_Util_Divide3232_Scale( L_shl( L_min( accu1, accu2 ), 1 ), L_add( accu1, accu2 ), &s ); att = Sqrt16( att, &s ); BASOP_SATURATE_WARNING_OFF_EVS; /* att is always <= 1.0 */ -#ifdef BASOP_NOGLOB att = shl_o( att, s, &Overflow ); -#else - att = shl( att, s ); -#endif BASOP_SATURATE_WARNING_ON_EVS; } ELSE @@ -2281,181 +2538,161 @@ void tcx_noise_factor_ivas_fx( move16(); } - accu1 = L_deposit_l( 0 ); + win = 0; + move16(); - tmp1 = sub( lowpassLine, nTransWidth ); - FOR( ; i <= tmp1; i++ ) + FOR( ; i < lowpassLine; i++ ) { inv_gain2 = shl( mult( inv_gain2, tilt_factor ), 1 ); - IF( EQ_16( maxK, 1 ) ) /* current line is not zero, so reset pointers */ + IF( sqQ[i] != 0 ) /* current line is not zero, so reset pointers */ { - k = sub( i, segmentOffset ); - - IF( k > 0 ) /* add segment sum to sum of segment magnitudes */ + IF( win > 0 ) { + k = sub( i, segmentOffset ); + IF( LE_16( nTransWidth, 3 ) ) { tmp2 = sub( k, c1 ); - if ( tmp2 > 0 ) + IF( tmp2 > 0 ) + { n = L_msu( n, k, (Word16) 0x8000 ); - if ( tmp2 > 0 ) + } + IF( tmp2 > 0 ) + { n = L_mac( n, nTransWidth_1, (Word16) 0x8000 ); - if ( tmp2 <= 0 ) + } + IF( tmp2 <= 0 ) + { n = L_mac( n, int_sqr[k], c2 ); + } } ELSE { tmp2 = sub( k, 12 ); - if ( tmp2 > 0 ) + IF( tmp2 > 0 ) + { n = L_msu( n, k, (Word16) 0x8000 ); - if ( tmp2 > 0 ) + } + IF( tmp2 > 0 ) + { n = L_sub( n, 0x70000 ); - if ( tmp2 <= 0 ) + } + IF( tmp2 <= 0 ) + { n = L_mac( n, int_sqr[k], 1152 /*0.03515625f Q15*/ ); + } } - sqErrorNrg = L_add( sqErrorNrg, accu1 ); - accu1 = L_deposit_l( 0 ); /* segment ended here, so reset segment sum */ - k = 0; - move16(); - } - - FOR( ; maxK < nTransWidth; maxK++ ) - { - IF( sqQ[i + maxK] != 0 ) + FOR( k = segmentOffset; k < i - win; k++ ) { - BREAK; + tmp1 = norm_l( sqQ[k] ); + sqErrorNrg = BASOP_Util_Add_Mant32Exp( sqErrorNrg, exp_sqErrorNrg, Mpy_32_16_1( L_shl( sqQ[k], tmp1 ), nTransWidth ), add( 15, sub( exp_spQ[k], tmp1 ) ), &exp_sqErrorNrg ); + sqQ[k] = 0; + move32(); + exp_spQ[k] = 0; + move16(); + } + FOR( ; win > 0; win-- ) + { + tmp1 = norm_l( sqQ[k] ); + sqErrorNrg = BASOP_Util_Add_Mant32Exp( sqErrorNrg, exp_sqErrorNrg, Mpy_32_16_1( L_shl( sqQ[k], tmp1 ), win ), add( 15, sub( exp_spQ[k], tmp1 ) ), &exp_sqErrorNrg ); + exp_spQ[k] = 0; + move16(); + sqQ[k++] = 0; + move32(); } } segmentOffset = add( i, 1 ); /* new segment might start at next line */ } ELSE /* current line is zero, so update pointers & segment sum */ { - if ( LT_16( k, nTransWidth ) ) + IF( LT_16( win, nTransWidth ) ) { - k = add( k, 1 ); + win = add( win, 1 ); } - - tmp2 = sub( maxK, nTransWidth ); - test(); - if ( tmp2 < 0 && NE_16( element_mode, IVAS_CPE_MDCT ) ) - { - maxK = sub( maxK, 1 ); - } - - test(); - if ( ( tmp2 >= 0 ) && ( sqQ[i + sub( nTransWidth, 1 )] != 0 ) ) - { - maxK = sub( nTransWidth, 1 ); - } - /* update segment sum: magnitudes scaled by smoothing function */ - /*accu1 += (float)fabs(x_orig[i]) * inv_gain2 * (float)(k * maxK);*/ - tmp2 = mult( inv_gain2, shl( imult1616( k, maxK ), 8 ) ); - accu1 = L_add( accu1, L_abs( Mpy_32_16_1( x_orig[i], tmp2 ) ) ); + sqQ[i] = Mpy_32_16_1( imult3216( L_abs( x_orig[i] ), win ), inv_gain2 ); + move32(); + exp_spQ[i] = add( x_orig_e, inv_gain2_e ); + move16(); } } - - FOR( ; i < lowpassLine; i++ ) + IF( win > 0 ) /* add last segment sum to sum of segment magnitudes */ { - inv_gain2 = shl( mult( inv_gain2, tilt_factor ), 1 ); - - IF( EQ_16( maxK, 1 ) ) /* current line is not zero, so reset pointers */ + k = sub( i, segmentOffset ); + IF( LE_16( nTransWidth, 3 ) ) { - k = sub( i, segmentOffset ); - - IF( k > 0 ) /* add segment sum to sum of segment magnitudes */ + tmp2 = sub( k, c1 ); + IF( tmp2 > 0 ) { - IF( LE_16( nTransWidth, 3 ) ) - { - tmp2 = sub( k, c1 ); - if ( tmp2 > 0 ) - n = L_msu( n, k, (Word16) 0x8000 ); - if ( tmp2 > 0 ) - n = L_mac( n, nTransWidth_1, (Word16) 0x8000 ); - if ( tmp2 <= 0 ) - n = L_mac( n, int_sqr[k], c2 ); - } - ELSE - { - tmp2 = sub( k, 12 ); - if ( tmp2 > 0 ) - n = L_msu( n, k, (Word16) 0x8000 ); - if ( tmp2 > 0 ) - n = L_sub( n, 0x70000 ); - if ( tmp2 <= 0 ) - n = L_mac( n, int_sqr[k], 1152 /*0.03515625f Q15*/ ); - } - sqErrorNrg = L_add( sqErrorNrg, accu1 ); + n = L_msu( n, k, (Word16) 0x8000 ); } - segmentOffset = add( i, 1 ); /* no new segments since maxK remains 1 */ - } - ELSE /* current line is zero, so update pointers & energy sum */ - { - if ( LT_16( k, nTransWidth ) ) + IF( tmp2 > 0 ) { - k = add( k, 1 ); + n = L_mac( n, nTransWidth_1, (Word16) 0x8000 ); } - if ( LT_16( maxK, nTransWidth ) ) + IF( tmp2 <= 0 ) { - maxK = sub( maxK, 1 ); - } - - /* update segment sum: magnitudes scaled by smoothing function */ - /*accu1 += (float)fabs(x_orig[i]) * inv_gain2 * (float)(k * maxK);*/ - tmp2 = mult( inv_gain2, shl( imult1616( k, maxK ), 8 ) ); - accu1 = L_add( accu1, L_abs( Mpy_32_16_1( x_orig[i], tmp2 ) ) ); - } - } - - k = sub( i, segmentOffset ); - IF( k > 0 ) /* add last segment sum to sum of segment magnitudes */ - { - IF( LE_16( nTransWidth, 3 ) ) - { - tmp2 = sub( k, c1 ); - if ( tmp2 > 0 ) - n = L_msu( n, k, (Word16) 0x8000 ); - if ( tmp2 > 0 ) - n = L_mac( n, nTransWidth_1, (Word16) 0x8000 ); - if ( tmp2 <= 0 ) n = L_mac( n, int_sqr[k], c2 ); + } } ELSE { tmp2 = sub( k, 12 ); - if ( tmp2 > 0 ) + IF( tmp2 > 0 ) + { n = L_msu( n, k, (Word16) 0x8000 ); - if ( tmp2 > 0 ) + } + IF( tmp2 > 0 ) + { n = L_sub( n, 0x70000 ); - if ( tmp2 <= 0 ) + } + IF( tmp2 <= 0 ) + { n = L_mac( n, int_sqr[k], 1152 /*0.03515625f Q15*/ ); + } + } + FOR( k = segmentOffset; k < i - win; k++ ) + { + tmp1 = norm_l( sqQ[k] ); + sqErrorNrg = BASOP_Util_Add_Mant32Exp( sqErrorNrg, exp_sqErrorNrg, Mpy_32_16_1( L_shl( sqQ[k], tmp1 ), nTransWidth ), add( 15, sub( exp_spQ[k], tmp1 ) ), &exp_sqErrorNrg ); + exp_spQ[k] = 0; + move16(); + sqQ[k] = 0; + move32(); + } + FOR( ; win > 0; win-- ) + { + tmp1 = norm_l( sqQ[k] ); + sqErrorNrg = BASOP_Util_Add_Mant32Exp( sqErrorNrg, exp_sqErrorNrg, Mpy_32_16_1( L_shl( sqQ[k], tmp1 ), win ), add( 15, sub( exp_spQ[k], tmp1 ) ), &exp_sqErrorNrg ); + exp_spQ[k] = 0; + move16(); + sqQ[k++] = 0; + move32(); } - sqErrorNrg = L_add( sqErrorNrg, accu1 ); } - + Word32 tmp4; /* noise level factor: average of segment magnitudes of noise bins */ IF( n > 0 ) { - tmp1 = BASOP_Util_Divide3232_Scale( Mpy_32_16_1( sqErrorNrg, att ), n, &s ); - s = add( add( add( s, x_orig_e ), inv_gain2_e ), 7 - 15 ); + tmp4 = BASOP_Util_Divide3232_Scale_cadence( Mpy_32_16_1( sqErrorNrg, att ), n, &s ); + s = add( add( exp_sqErrorNrg, -15 ), s ); BASOP_SATURATE_WARNING_OFF_EVS; -#ifdef BASOP_NOGLOB - tmp1 = shl_o( tmp1, s, &Overflow ); -#else /* BASOP_NOGLOB */ - tmp1 = shl( tmp1, s ); -#endif + tmp4 = L_shl_o( tmp4, s, &Overflow ); BASOP_SATURATE_WARNING_ON_EVS; } ELSE { - tmp1 = 0; + tmp4 = 0; move16(); } - + FOR( j = 0; j < N_MAX; j++ ) + { + sqQ[j] = L_shl( sqQ[j], sub( x_orig_e, exp_spQ[j] ) ); + move32(); + } /* quantize, dequantize noise level factor (range 0.09375 - 0.65625) */ - tmp2 = round_fx( L_shr( L_mult( tmp1, 22016 /*1.34375f Q14*/ ), 14 - NBITS_NOISE_FILL_LEVEL ) ); - + tmp2 = round_fx( L_shr( Mpy_32_16_1( tmp4, 22016 /*1.34375f Q14*/ ), 14 - NBITS_NOISE_FILL_LEVEL ) ); if ( GT_16( tmp2, ( 1 << NBITS_NOISE_FILL_LEVEL ) - 1 ) ) { tmp2 = ( 1 << NBITS_NOISE_FILL_LEVEL ) - 1; @@ -2466,8 +2703,10 @@ void tcx_noise_factor_ivas_fx( move16(); *fac_ns = extract_l( L_mult0( *quantized_fac_ns, shr( 24576 /*0.75f Q15*/, NBITS_NOISE_FILL_LEVEL ) ) ); + move16(); } + void tcx_encoder_memory_update_fx( Word16 *wsig, /* i : target weighted signal */ Word16 *xn_buf, /* i/o: mdct output buffer/time domain weigthed synthesis */ @@ -2503,11 +2742,8 @@ void tcx_encoder_memory_update_fx( Residu3_fx( Ai + ( st->nb_subfr - 1 ) * ( M + 1 ), synth + sub( L_frame_glob, 1 ), &tmp, 1, Q_new + shift - 1 ); LPDmem->mem_w0 = sub( wsig[sub( L_frame_glob, 1 )], tmp ); move16(); -#ifdef BASOP_NOGLOB LPDmem->mem_w0 = shr_sat( LPDmem->mem_w0, shift ); /*Qnew-1*/ -#else - LPDmem->mem_w0 = shr( LPDmem->mem_w0, shift ); /*Qnew-1*/ -#endif + move16(); } @@ -2576,11 +2812,13 @@ void tcx_encoder_memory_update_ivas_fx( /* Emphasis of synth -> synth_pe */ tmp = synth[-( M + 1 )]; move16(); - E_UTIL_f_preemph2( Q_new - 1, synth - M, preemph, add( M, L_frame_glob ), &tmp ); + E_UTIL_f_preemph2( 0, synth - M, preemph, add( M, L_frame_glob ), &tmp ); // Q_new Copy( synth + sub( L_frame_glob, M ), LPDmem->mem_syn, M ); Copy( synth + sub( L_frame_glob, M ), LPDmem->mem_syn2, M ); Copy( synth + sub( L_frame_glob, L_SYN_MEM ), LPDmem->mem_syn_r, L_SYN_MEM ); + LPDmem->q_mem_syn = Q_new; // resultant q of synth after E_UTIL_f_preemph2 + move16(); test(); IF( st->tcxonly == 0 || LE_16( L_frame_glob, L_FRAME16k ) ) @@ -2588,12 +2826,27 @@ void tcx_encoder_memory_update_ivas_fx( /* Update excitation */ IF( LT_16( L_frame_glob, L_EXC_MEM ) ) { - Copy( LPDmem->old_exc + L_frame_glob, LPDmem->old_exc, sub( L_EXC_MEM, L_frame_glob ) ); - Residu3_fx( A, synth, LPDmem->old_exc + sub( L_EXC_MEM, L_frame_glob ), L_frame_glob, 1 ); + Word16 shift = norm_arr( LPDmem->old_exc + L_frame_glob, sub( L_EXC_MEM, L_frame_glob ) ); + IF( LT_16( shift, sub( Q_new, LPDmem->q_lpd_old_exc ) ) ) + { + Copy_Scale_sig( LPDmem->old_exc + L_frame_glob, LPDmem->old_exc, sub( L_EXC_MEM, L_frame_glob ), shift ); + LPDmem->q_lpd_old_exc = add( LPDmem->q_lpd_old_exc, shift ); + move16(); + Residu3_fx( A, synth, LPDmem->old_exc + sub( L_EXC_MEM, L_frame_glob ), L_frame_glob, sub( LPDmem->q_lpd_old_exc, Q_new ) ); // LPDmem->q_lpd_old_exc + } + ELSE + { + Copy_Scale_sig( LPDmem->old_exc + L_frame_glob, LPDmem->old_exc, sub( L_EXC_MEM, L_frame_glob ), sub( Q_new, LPDmem->q_lpd_old_exc ) ); + Residu3_fx( A, synth, LPDmem->old_exc + sub( L_EXC_MEM, L_frame_glob ), L_frame_glob, 0 ); // Q_new + LPDmem->q_lpd_old_exc = Q_new; + move16(); + } } ELSE { - Residu3_fx( A, synth + sub( L_frame_glob, L_EXC_MEM ), LPDmem->old_exc, L_EXC_MEM, 1 ); + Residu3_fx( A, synth + sub( L_frame_glob, L_EXC_MEM ), LPDmem->old_exc, L_EXC_MEM, 0 ); // Q_new + LPDmem->q_lpd_old_exc = Q_new; + move16(); } } } @@ -2650,8 +2903,10 @@ Word16 tcx_ari_res_Q_spec_fx( { sign = x_fac[i]; move16(); - if ( signs[i] != 0 ) + IF( signs[i] != 0 ) + { sign = negate( sign ); + } /* x_Q_m = x_Q[i] - sign*fac_m; x_Q_p = x_Q[i] + sign*fac_p; */ @@ -2719,8 +2974,10 @@ Word16 tcx_ari_res_Q_spec_fx( bits = add( bits, 1 ); L_tmp = L_shr( thres, s2 ); - if ( signs[i] ) + IF( signs[i] ) + { L_tmp = L_negate( L_tmp ); + } x_Q[i] = L_tmp; move32(); } @@ -2850,8 +3107,10 @@ Word16 tcx_ari_res_Q_spec_ivas_fx( bits = add( bits, 1 ); L_tmp = L_shr( thres, s2 ); - if ( signs[i] ) + IF( signs[i] ) + { L_tmp = L_negate( L_tmp ); + } x_Q[i] = L_tmp; move32(); } @@ -2878,8 +3137,10 @@ Word16 tcx_ari_res_Q_spec_ivas_fx( { sign = x_fac[i]; move16(); - if ( signs[i] != 0 ) + IF( signs[i] != 0 ) + { sign = negate( sign ); + } /* x_Q_m = x_Q[i] - sign*fac_m; x_Q_p = x_Q[i] + sign*fac_p; */ @@ -2947,8 +3208,10 @@ Word16 tcx_ari_res_Q_spec_ivas_fx( bits = add( bits, 1 ); L_tmp = L_shr( thres, s2 ); - if ( signs[i] ) + IF( signs[i] ) + { L_tmp = L_negate( L_tmp ); + } x_Q[i] = L_tmp; move32(); } @@ -2993,11 +3256,7 @@ Word16 tcx_res_Q_gain_fx( } /* bring sqGain to same exponent */ -#ifdef BASOP_NOGLOB sqGain = shr_sat( sqGain, sub( gain_reQ_e, sqGain_e ) ); -#else - sqGain = shr( sqGain, sub( gain_reQ_e, sqGain_e ) ); -#endif FOR( bits = 0; bits < TCX_RES_Q_BITS_GAIN; bits++ ) { IF( LT_16( sqGain, gain_reQ ) ) @@ -3084,10 +3343,14 @@ Word16 tcx_res_Q_spec_fx( { tmp1 = L_add( x_orig[i], 0 ); tmp2 = Mpy_32_16_1( x_Q[i], sqGain ); - if ( s > 0 ) + IF( s > 0 ) + { tmp2 = L_shr( tmp2, s ); - if ( s < 0 ) + } + IF( s < 0 ) + { tmp1 = L_shl( tmp1, s ); + } if ( lf_deemph_factors != NULL ) { @@ -3101,10 +3364,14 @@ Word16 tcx_res_Q_spec_fx( move16(); bits = add( bits, 1 ); - if ( x_Q[i] > 0 ) + IF( x_Q[i] > 0 ) + { tmp1 = L_mult( fac_m, lf_deemph_factor ); - if ( x_Q[i] < 0 ) + } + IF( x_Q[i] < 0 ) + { tmp1 = L_mult( fac_p, lf_deemph_factor ); + } x_Q[i] = L_sub( x_Q[i], L_shr( tmp1, s2 ) ); move32(); } @@ -3114,10 +3381,14 @@ Word16 tcx_res_Q_spec_fx( move16(); bits = add( bits, 1 ); - if ( x_Q[i] > 0 ) + IF( x_Q[i] > 0 ) + { tmp1 = L_mult( fac_p, lf_deemph_factor ); - if ( x_Q[i] < 0 ) + } + IF( x_Q[i] < 0 ) + { tmp1 = L_mult( fac_m, lf_deemph_factor ); + } x_Q[i] = L_add( x_Q[i], L_shr( tmp1, s2 ) ); move32(); } @@ -3251,10 +3522,14 @@ Word16 tcx_res_Q_spec_ivas_fx( { tmp1 = L_add( x_orig[i], 0 ); tmp2 = Mpy_32_16_1( x_Q[i], sqGain ); - if ( s > 0 ) + IF( s > 0 ) + { tmp2 = L_shr( tmp2, s ); - if ( s < 0 ) + } + IF( s < 0 ) + { tmp1 = L_shl( tmp1, s ); + } if ( lf_deemph_factors != NULL ) { @@ -3268,10 +3543,14 @@ Word16 tcx_res_Q_spec_ivas_fx( move16(); bits = add( bits, 1 ); - if ( x_Q[i] > 0 ) + IF( x_Q[i] > 0 ) + { tmp1 = L_mult( fac_m, lf_deemph_factor ); - if ( x_Q[i] < 0 ) + } + IF( x_Q[i] < 0 ) + { tmp1 = L_mult( fac_p, lf_deemph_factor ); + } x_Q[i] = L_sub( x_Q[i], L_shr( tmp1, s2 ) ); move32(); } @@ -3281,10 +3560,14 @@ Word16 tcx_res_Q_spec_ivas_fx( move16(); bits = add( bits, 1 ); - if ( x_Q[i] > 0 ) + IF( x_Q[i] > 0 ) + { tmp1 = L_mult( fac_p, lf_deemph_factor ); - if ( x_Q[i] < 0 ) + } + IF( x_Q[i] < 0 ) + { tmp1 = L_mult( fac_m, lf_deemph_factor ); + } x_Q[i] = L_add( x_Q[i], L_shr( tmp1, s2 ) ); move32(); } @@ -3431,18 +3714,26 @@ void ProcessIGF_fx( Word16 Q_A; Word16 predictionGain = 0; Word16 *flatteningTrigger = &( st->hIGFEnc->flatteningTrigger ); + move32(); + move16(); + move16(); + move16(); + move32(); + move16(); + move16(); ITF_Detect_fx( spec_before, startLine, endLine, maxOrder, A, &Q_A, &predictionGain, &curr_order, shl( st->hIGFEnc->spec_be_igf_e, 1 ) ); *flatteningTrigger = 0; + move16(); test(); IF( LT_32( tns_predictionGain, 9646899l /*1.15 Q23*/ ) && LT_16( predictionGain, 147 /*1.15 Q7*/ ) ) { *flatteningTrigger = 1; + move16(); } } - // IVAS_CODE_BITSTREAM bsStart = hBstr->next_ind_fx; move16(); @@ -3457,21 +3748,11 @@ void ProcessIGF_fx( IGFEncWriteBitstream_fx( hInstance, st->hBstr, &hInstance->infoTotalBitsPerFrameWritten, igfGridIdx, isIndepFlag ); } -#ifndef IVAS_CODE_BITSTREAM bsBits = sub( hBstr->next_ind_fx, bsStart ); IF( !isTCX20 ) { IGFEncConcatenateBitstream_fx( hInstance, bsBits, &hBstr->next_ind_fx, &hBstr->nb_bits_tot, hBstr->ind_list ); } -#else - PMT( "New bit stream implementation to be checked" ) - bsBits = sub( hBstr->next_ind_fx, bsStart ); - IF( !isTCX20 ) - { - IGFEncConcatenateBitstream_fx( hInstance, bsBits, &hBstr->next_ind_fx, &hBstr->nb_bits_tot_fx, hBstr->ind_list_fx ); - } - -#endif } void attenuateNbSpectrum_fx( Word16 L_frame, Word32 *spectrum ) @@ -3496,3 +3777,211 @@ void attenuateNbSpectrum_fx( Word16 L_frame, Word32 *spectrum ) att = mult_r( att, att ); } } + +/*---------------------------------------------------------------------* + * ProcessIGF_ivas_fx() + * + * + *---------------------------------------------------------------------*/ +void ProcessIGF_ivas_fx( + Encoder_State *st, /* i : Encoder state */ +#ifdef MSAN_FIX + Word16 powerSpec_len, /* i : length of pPowerSpectrum buffer */ +#endif + Word32 *pMDCTSpectrum, /* i : MDCT spectrum (*q_spectrum) */ + const Word32 *pITFMDCTSpectrum, /* i : MDCT spectrum fir ITF */ + Word16 *q_spectrum, /* i/o: Q of spectrum */ + Word32 *pPowerSpectrum, /* i : MDCT^2 + MDST^2 spectrum, or estimate (*q_powerSpec) */ + Word16 *exp_powerSpec, /* i/o: Q of power spectrum */ + const Word16 isTCX20, /* i : flag indicating if the input is TCX20 or TCX10/2xTCX5 */ + const Word16 frameno, /* i : flag indicating index of current subframe */ + const Word16 sp_aud_decision0, /* i : first stage switching decision */ + const Word16 vad_hover_flag /* i : VAD hangover flag */ +) +{ + Word16 igfGridIdx, isIndepFlag, bsBits, pBsStart, curr_order; + Word16 predictionGain; + Word16 A[ITF_MAX_FILTER_ORDER + 1]; + Word16 q_A; + + IGF_ENC_INSTANCE_HANDLE hIGFEnc = st->hIGFEnc; + BSTR_ENC_HANDLE hBstr = st->hBstr; + + isIndepFlag = 1; + move16(); + test(); + IF( st->last_core == ACELP_CORE && isTCX20 ) + { + igfGridIdx = IGF_GRID_LB_TRAN; + move16(); + } + ELSE IF( isTCX20 ) + { + igfGridIdx = IGF_GRID_LB_NORM; + move16(); + } + ELSE + { + /* It is short block */ + igfGridIdx = IGF_GRID_LB_SHORT; + move16(); + if ( EQ_16( frameno, 1 ) ) + { + isIndepFlag = 0; + move16(); + } + } + + IGFSaveSpectrumForITF_ivas_fx( hIGFEnc, igfGridIdx, pITFMDCTSpectrum, sub( Q31, *q_spectrum ) ); + +#ifndef MSAN_FIX + IGFEncApplyMono_ivas_fx( st, igfGridIdx, pMDCTSpectrum, sub( Q31, *q_spectrum ), pPowerSpectrum, exp_powerSpec, isTCX20, st->hTcxEnc->fUseTns[frameno], sp_aud_decision0, vad_hover_flag ); +#else + IGFEncApplyMono_ivas_fx( st, powerSpec_len, igfGridIdx, pMDCTSpectrum, sub( Q31, *q_spectrum ), pPowerSpectrum, exp_powerSpec, isTCX20, st->hTcxEnc->fUseTns[frameno], sp_aud_decision0, vad_hover_flag ); +#endif + + curr_order = 0; + move16(); + predictionGain = 0; + move16(); + q_A = 0; + move16(); + + ITF_Detect_ivas_fx( hIGFEnc->spec_be_igf, hIGFEnc->infoStartLine, hIGFEnc->infoStopLine, 8 /*maxOrder*/, A, &q_A, &predictionGain, &curr_order, sub( 31, hIGFEnc->spec_be_igf_e ) ); + + test(); + IF( LT_16( hIGFEnc->tns_predictionGain, ONE_POINT_ONE_FIVE_Q7 ) && LT_16( predictionGain, ONE_POINT_ONE_FIVE_Q7 ) ) + { + hIGFEnc->flatteningTrigger = 1; + move16(); + } + ELSE + { + hIGFEnc->flatteningTrigger = 0; + move16(); + } + + hIGFEnc->infoTotalBitsPerFrameWritten = 0; + move16(); + + IF( isTCX20 ) + { + IGFEncWriteBitstream_ivas_fx( hIGFEnc, NULL, &hIGFEnc->infoTotalBitsPerFrameWritten, igfGridIdx, isIndepFlag ); + } + ELSE + { + pBsStart = hBstr->nb_ind_tot; + move16(); + + IGFEncWriteBitstream_ivas_fx( hIGFEnc, hBstr, &hIGFEnc->infoTotalBitsPerFrameWritten, igfGridIdx, isIndepFlag ); + + bsBits = sub( hBstr->nb_ind_tot, pBsStart ); + IGFEncConcatenateBitstream( hIGFEnc, bsBits, hBstr ); + } + + return; +} + +/*---------------------------------------------------------------------* + * ProcessStereoIGF() + * + * + *---------------------------------------------------------------------*/ + +void ProcessStereoIGF_fx( + STEREO_MDCT_ENC_DATA_HANDLE hStereoMdct, + Encoder_State *sts[CPE_CHANNELS], /* i : Encoder state */ + Word16 ms_mask[2][MAX_SFB], /* i : bandwise MS mask */ + Word32 *pITFMDCTSpectrum_fx[CPE_CHANNELS][NB_DIV], /* i : MDCT spectrum fir ITF */ + Word16 q_pITFMDCTSpectrum_1, + Word16 q_pITFMDCTSpectrum_2, + Word32 *pPowerSpectrum_fx[CPE_CHANNELS], /* i/o: MDCT^2 + MDST^2 spectrum, or estimate */ + Word32 *pPowerSpectrumMsInv_fx[CPE_CHANNELS][NB_DIV], /* i : inverse power spectrum */ + Word32 *inv_spectrum_fx[CPE_CHANNELS][NB_DIV], /* i : inverse spectrum */ + const Word16 frameno, /* i : flag indicating index of current subfr. */ + const Word16 sp_aud_decision0, /* i : sp_aud_decision0 */ + const Word32 element_brate, /* i : element bitrate */ + const Word16 mct_on ) +{ + Word16 ch, igfGridIdx, isIndepFlag, bsBits, pBsStart, curr_order; + Word16 predictionGain; + Word16 A[ITF_MAX_FILTER_ORDER + 1]; + Word16 Q_A; + IGF_ENC_INSTANCE_HANDLE hIGFEnc[CPE_CHANNELS]; + BSTR_ENC_HANDLE hBstr; + hIGFEnc[0] = sts[0]->hIGFEnc; + hIGFEnc[1] = sts[1]->hIGFEnc; + + isIndepFlag = 1; + move16(); + + test(); + IF( sts[0]->last_core == ACELP_CORE && EQ_16( sts[0]->core, TCX_20_CORE ) ) + { + igfGridIdx = IGF_GRID_LB_TRAN; + } + ELSE IF( EQ_16( sts[0]->core, TCX_20_CORE ) ) + { + igfGridIdx = IGF_GRID_LB_NORM; + } + ELSE + { + /* It is short block */ + igfGridIdx = IGF_GRID_LB_SHORT; + if ( EQ_16( frameno, 1 ) ) + { + isIndepFlag = 0; + move16(); + } + } + move16(); + + IGFSaveSpectrumForITF_ivas_fx( hIGFEnc[0], igfGridIdx, pITFMDCTSpectrum_fx[0][frameno], sub( Q31, q_pITFMDCTSpectrum_1 ) ); + + IGFSaveSpectrumForITF_ivas_fx( hIGFEnc[1], igfGridIdx, pITFMDCTSpectrum_fx[1][frameno], sub( Q31, q_pITFMDCTSpectrum_2 ) ); + + + IGFEncApplyStereo_fx( hStereoMdct, ms_mask, hIGFEnc, igfGridIdx, sts, pPowerSpectrum_fx, pPowerSpectrumMsInv_fx, inv_spectrum_fx, frameno, sp_aud_decision0, element_brate, mct_on ); + + FOR( ch = 0; ch < CPE_CHANNELS; ch++ ) + { + curr_order = 0; + move16(); + + Q_A = 0; + move16(); + + predictionGain = 0; + move16(); + + ITF_Detect_ivas_fx( hIGFEnc[ch]->spec_be_igf, hIGFEnc[ch]->infoStartLine, hIGFEnc[ch]->infoStopLine, 8 /*maxOrder*/, A, &Q_A, &predictionGain, &curr_order, sub( 31, hIGFEnc[ch]->spec_be_igf_e ) ); + + test(); + hIGFEnc[ch]->flatteningTrigger = LT_16( hIGFEnc[ch]->tns_predictionGain, ONE_POINT_ONE_FIVE_Q7 ) && LT_16( predictionGain, ONE_POINT_ONE_FIVE_Q7 ); + move16(); + + hIGFEnc[ch]->infoTotalBitsPerFrameWritten = 0; + move16(); + + IF( EQ_16( sts[ch]->core, TCX_20_CORE ) ) + { + IGFEncWriteBitstream_ivas_fx( hIGFEnc[ch], NULL, &hIGFEnc[ch]->infoTotalBitsPerFrameWritten, igfGridIdx, isIndepFlag ); + } + ELSE + { + hBstr = sts[ch]->hBstr; + pBsStart = hBstr->nb_ind_tot; + move16(); + + if ( ch > 0 ) + { + hBstr->ind_list = sts[0]->hBstr->ind_list + sts[0]->hBstr->nb_ind_tot; + } + IGFEncWriteBitstream_ivas_fx( hIGFEnc[ch], hBstr, &hIGFEnc[ch]->infoTotalBitsPerFrameWritten, igfGridIdx, isIndepFlag ); + + bsBits = sub( hBstr->nb_ind_tot, pBsStart ); + IGFEncConcatenateBitstream( hIGFEnc[ch], bsBits, hBstr ); + } + } + return; +} diff --git a/lib_enc/tfa_enc.c b/lib_enc/tfa_enc.c deleted file mode 100644 index 825401325748d89d4db5894372ff8dd2e53d76ec..0000000000000000000000000000000000000000 --- a/lib_enc/tfa_enc.c +++ /dev/null @@ -1,41 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include -#include "prot.h" -#include "wmc_auto.h" diff --git a/lib_enc/tfa_enc_fx.c b/lib_enc/tfa_enc_fx.c index cfb48aaeca8a479efd03489958158bead7ccedbb..a6a1eaa8501e54e4fca18402b1ee6c759fbd53da 100644 --- a/lib_enc/tfa_enc_fx.c +++ b/lib_enc/tfa_enc_fx.c @@ -27,13 +27,11 @@ void tfaCalcEnv_fx( FOR( i = 0; i < N_TEC_TFA_SUBFR; i++ ) { enr[i] = L_deposit_l( 0 ); + move32(); FOR( j = 0; j < L_TEC_TFA_SUBFR16k; j++ ) { -#ifdef BASOP_NOGLOB enr[i] = L_mac0_sat( enr[i], shb_speech[k], shb_speech[k] ); -#else - enr[i] = L_mac0( enr[i], shb_speech[k], shb_speech[k] ); -#endif + move32(); k = add( k, 1 ); } } @@ -104,8 +102,8 @@ Word16 tfaEnc_TBE_fx( test(); test(); test(); - IF( ( GT_32( m_g, L_tmp ) && GT_16( pitch_buf_sum, 7040 /*110 Q6*/ ) && GT_16( voicing_sum, 22938 /*0.70 Q15*/ ) ) || - ( EQ_16( last_core, TCX_20_CORE ) && GT_32( m_g, L_tmp1 ) && LT_16( voicing_sum, 22938 /*0.70 Q15*/ ) ) ) + if ( ( GT_32( m_g, L_tmp ) && GT_16( pitch_buf_sum, 7040 /*110 Q6*/ ) && GT_16( voicing_sum, 22938 /*0.70 Q15*/ ) ) || + ( EQ_16( last_core, TCX_20_CORE ) && GT_32( m_g, L_tmp1 ) && LT_16( voicing_sum, 22938 /*0.70 Q15*/ ) ) ) { tfa_flag = 1; move16(); diff --git a/lib_enc/tns_base_enc.c b/lib_enc/tns_base_enc.c deleted file mode 100644 index b3f3a90b7702920cfd9566005e7f7d543a794b94..0000000000000000000000000000000000000000 --- a/lib_enc/tns_base_enc.c +++ /dev/null @@ -1,103 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include -#include "options.h" -#include "wmc_auto.h" -#include "cnst.h" -#include "rom_com.h" -#include "prot.h" -#include "stat_com.h" - -/*---------------------------------------------------------------------------- - * Local constants - *---------------------------------------------------------------------------*/ - -#define HLM_MIN_NRG ( PCM16_TO_FLT_FAC * 2 * NORM_MDCT_FACTOR / ( 640 * 640 ) ) - -#define MAX_SUBDIVISIONS 3 - - -/*---------------------------------------------------------------------* - * EncodeTnsData() - * - * - *---------------------------------------------------------------------*/ - -void EncodeTnsData( - STnsConfig const *pTnsConfig, /* i : TNS Configuration struct */ - STnsData const *pTnsData, /* i : TNS data struct (quantized param) */ - int16_t *stream, /* o : internal data stream */ - int16_t *pnSize, /* o : number of written parameters */ - int16_t *pnBits /* o : number of written bits */ -) -{ - *pnSize = 0; - *pnBits = 0; - - if ( pTnsConfig->nMaxFilters > 1 ) - { - if ( pTnsConfig->allowTnsOnWhite ) - { - if ( pTnsConfig->iFilterBorders[0] < 512 ) - { - GetParameters( &tnsEnabledOnWhiteSWBTCX10BitMap, 1, pTnsData, &stream, pnSize, pnBits ); - } - else - { - GetParameters( &tnsEnabledOnWhiteSWBTCX20BitMap, 1, pTnsData, &stream, pnSize, pnBits ); - } - } - else - { - if ( pTnsConfig->iFilterBorders[0] < 512 ) - { - GetParameters( &tnsEnabledSWBTCX10BitMap, 1, pTnsData, &stream, pnSize, pnBits ); - } - else - { - GetParameters( &tnsEnabledSWBTCX20BitMap, 1, pTnsData, &stream, pnSize, pnBits ); - } - } - } - else - { - GetParameters( &tnsEnabledWBTCX20BitMap, 1, pTnsData, &stream, pnSize, pnBits ); - } - - return; -} diff --git a/lib_enc/tns_base_enc_fx.c b/lib_enc/tns_base_enc_fx.c index 9790bbae23e59b711aff1559f789e2d700f3eb1f..cf6e5dd6417827061efc67503270a95395ab65a2 100644 --- a/lib_enc/tns_base_enc_fx.c +++ b/lib_enc/tns_base_enc_fx.c @@ -12,11 +12,10 @@ #include #include "rom_com_fx.h" #include "rom_com.h" -#include "prot.h" /* Function prototypes */ #include "prot_fx.h" /* Function prototypes */ #include "prot_fx_enc.h" /* Function prototypes */ -#define HLM_MIN_NRG ( 32768.0f * 2 * NORM_MDCT_FACTOR / ( 640 * 640 ) ) +#define HLM_MIN_NRG_FX 858993459 // ( 32768.0f * 2 * NORM_MDCT_FACTOR / ( 640 * 640 ) ) in Q26 /** Get TNS filter parameters from autocorrelation. * @@ -26,6 +25,8 @@ */ static void GetFilterParameters( Word32 rxx[], Word16 maxOrder, STnsFilter *pTnsFilter ); +static void GetFilterParameters_ivas( Word32 rxx[], Word16 maxOrder, STnsFilter *pTnsFilter ); + /** Quantization for reflection coefficients. * * @param parCoeff input reflection coefficients. @@ -59,6 +60,7 @@ Word16 DetectTnsFilt_fx( STnsConfig const *pTnsConfig, Word16 facs_e[TNS_MAX_NUM_OF_FILTERS][MAX_SUBDIVISIONS]; /* exponents of facs[][] */ Word16 shifts[TNS_MAX_NUM_OF_FILTERS][MAX_SUBDIVISIONS]; Word16 iFilter = 0; + move16(); ResetTnsData( pTnsData ); @@ -76,6 +78,7 @@ Word16 DetectTnsFilt_fx( STnsConfig const *pTnsConfig, Word16 iSubdivisions; #ifdef BASOP_NOGLOB_DECLARE_LOCAL Flag Overflow = 0; + move32(); #endif move16(); @@ -102,12 +105,16 @@ Word16 DetectTnsFilt_fx( STnsConfig const *pTnsConfig, iStartLine = imult1616( tmp, iSubdivisions ); iEndLine = add( iStartLine, tmp ); - if ( EQ_16( nSubdivisions, 3 ) ) + IF( EQ_16( nSubdivisions, 3 ) ) + { iStartLine = mult( iStartLine, 0x2AAB ); + } iStartLine = add( iStartLine, idx0 ); - if ( EQ_16( nSubdivisions, 3 ) ) + IF( EQ_16( nSubdivisions, 3 ) ) + { iEndLine = mult( iEndLine, 0x2AAB ); + } iEndLine = add( iEndLine, idx0 ); /*norms[iFilter][iSubdivisions] = norm2FLOAT(pSpectrum+iStartLine, iEndLine-iStartLine);*/ @@ -118,11 +125,7 @@ Word16 DetectTnsFilt_fx( STnsConfig const *pTnsConfig, /* Check threshold HLM_MIN_NRG */ BASOP_SATURATE_WARNING_OFF_EVS; -#ifdef BASOP_NOGLOB tmp32 = L_sub( L_shl_o( L_tmp, s_min( 31, sub( shift, 24 - 31 * 2 ) ), &Overflow ), 3277l /*HLM_MIN_NRG Q7*/ ); -#else /* BASOP_NOGLOB */ - tmp32 = L_sub( L_shl( L_tmp, s_min( 31, sub( shift, 24 - 31 * 2 ) ) ), 3277l /*HLM_MIN_NRG Q7*/ ); -#endif BASOP_SATURATE_WARNING_ON_EVS; /* get pre-shift for autocorrelation */ @@ -149,20 +152,12 @@ Word16 DetectTnsFilt_fx( STnsConfig const *pTnsConfig, move16(); facs_e[iFilter][iSubdivisions] = shl( sub( tmp, shifts[iFilter][iSubdivisions] ), 1 ); - tmp = sub( 1, shl( tmp, 1 ) ); /* exponent of autocorrelation */ -#ifdef BASOP_NOGLOB + tmp = sub( 1, shl( tmp, 1 ) ); /* exponent of autocorrelation */ L_tmp = L_shl_sat( L_tmp, sub( shift, tmp ) ); /* shift L_tmp to that exponent */ /* calc factor (with 2 bits headroom for sum of 3 subdivisions) */ move16(); facs[iFilter][iSubdivisions] = div_s( 0x2000, round_fx_sat( L_tmp ) ); /* L_tmp is >= 0x2000000 */ -#else - L_tmp = L_shl( L_tmp, sub( shift, tmp ) ); /* shift L_tmp to that exponent */ - - /* calc factor (with 2 bits headroom for sum of 3 subdivisions) */ - move16(); - facs[iFilter][iSubdivisions] = div_s( 0x2000, round_fx( L_tmp ) ); /* L_tmp is >= 0x2000000 */ -#endif } } } @@ -211,12 +206,16 @@ Word16 DetectTnsFilt_fx( STnsConfig const *pTnsConfig, iStartLine = imult1616( spectrumLength, iSubdivisions ); iEndLine = add( iStartLine, spectrumLength ); - if ( EQ_16( nSubdivisions, 3 ) ) + IF( EQ_16( nSubdivisions, 3 ) ) + { iStartLine = mult( iStartLine, 0x2AAB ); + } iStartLine = add( iStartLine, idx0 ); - if ( EQ_16( nSubdivisions, 3 ) ) + IF( EQ_16( nSubdivisions, 3 ) ) + { iEndLine = mult( iEndLine, 0x2AAB ); + } iEndLine = add( iEndLine, idx0 ); @@ -230,7 +229,12 @@ Word16 DetectTnsFilt_fx( STnsConfig const *pTnsConfig, assert( n < (Word16) ( sizeof( tmpbuf ) / sizeof( Word16 ) ) ); FOR( i = 0; i < n; i++ ) { +#ifdef FIX_ISSUE_1147 + tmpbuf[i] = round_fx_sat( L_shl( pSpectrum[iStartLine + i], shift ) ); +#else tmpbuf[i] = round_fx( L_shl( pSpectrum[iStartLine + i], shift ) ); +#endif + move16(); } FOR( lag = 0; lag <= pTnsConfig->maxOrder; lag++ ) @@ -240,15 +244,11 @@ Word16 DetectTnsFilt_fx( STnsConfig const *pTnsConfig, L_tmp = L_deposit_l( 0 ); FOR( i = 0; i < n; i++ ) { -#ifdef BASOP_NOGLOB L_tmp = L_mac0_sat( L_tmp, tmpbuf[i], tmpbuf[i + lag] ); -#else - L_tmp = L_mac0( L_tmp, tmpbuf[i], tmpbuf[i + lag] ); -#endif } - if ( lag != 0 ) - L_tmp = Mpy_32_16_1( L_tmp, *pWindow++ ); + IF( lag != 0 ) + L_tmp = Mpy_32_16_1( L_tmp, *pWindow++ ); L_tmp = Mpy_32_16_1( L_tmp, facs[iFilter][iSubdivisions] ); L_tmp = L_shl( L_tmp, facs_e[iFilter][iSubdivisions] ); @@ -307,119 +307,59 @@ Word16 DetectTnsFilt_fx( STnsConfig const *pTnsConfig, } - test(); return ( pTnsData->nFilters > 0 ); } void CalculateTnsFilt_fx( STnsConfig const *pTnsConfig, /* i : TNS Configuration struct */ - const Word32 pSpectrum[], /* i : MDCT spectrum Qx*/ - STnsData *pTnsData, /* o : TNS data struct */ - Word16 *predictionGain /* o : TNS prediction gain Q7*/ + const Word32 pSpectrum[], /* i : MDCT spectrum */ + const Word16 pSpectrum_e, + STnsData *pTnsData /* o : TNS data struct */ ) { - Word16 idx0, idx1, nSubdivisions, iSubdivisions, spectrumLength; - STnsFilter *pFilter; - Word16 iStartLine, n, i, iEndLine, tmp, headroom, shift, lag; - Word16 facs[TNS_MAX_NUM_OF_FILTERS][MAX_SUBDIVISIONS]; - Word16 facs_e[TNS_MAX_NUM_OF_FILTERS][MAX_SUBDIVISIONS]; /* exponents of facs[][] */ - Word16 shifts[TNS_MAX_NUM_OF_FILTERS][MAX_SUBDIVISIONS]; - Word16 iFilter = 0; - move16(); + Word32 norms[TNS_MAX_NUM_OF_FILTERS][MAX_SUBDIVISIONS]; + Word16 norms_exp[TNS_MAX_NUM_OF_FILTERS][MAX_SUBDIVISIONS]; + Word16 i, iFilter, idx0, idx1, nSubdivisions, iSubdivisions, spectrumLength; + Word16 iStartLine, iEndLine, lag; + Word16 fac, fac_e, exp; + Word32 rxx[TNS_MAX_FILTER_ORDER + 1]; + Word64 W_tmp; const Word16 *pWindow; - Word32 L_tmp, tmp32; + STnsFilter *pFilter; - /* Calculate norms for each spectrum part */ + FOR( i = 0; i < TNS_MAX_NUM_OF_FILTERS; i++ ) + { + set32_fx( norms[i], 0, MAX_SUBDIVISIONS ); + } + /* Calculate norms for each spectrum part */ FOR( iFilter = 0; iFilter < pTnsConfig->nMaxFilters; iFilter++ ) { -#ifdef BASOP_NOGLOB_DECLARE_LOCAL - Flag Overflow = 0; - move32(); -#endif idx0 = pTnsConfig->iFilterBorders[iFilter + 1]; move16(); idx1 = pTnsConfig->iFilterBorders[iFilter]; move16(); nSubdivisions = pTnsConfig->pTnsParameters[iFilter].nSubdivisions; move16(); - assert( pTnsConfig->pTnsParameters[iFilter].nSubdivisions <= MAX_SUBDIVISIONS ); + /* Variable initialization */ + assert( pTnsConfig->pTnsParameters[iFilter].nSubdivisions <= MAX_SUBDIVISIONS ); FOR( iSubdivisions = 0; iSubdivisions < nSubdivisions; iSubdivisions++ ) { - /* iStartLine = idx0 + (idx1-idx0)*iSubdivisions/nSubdivisions; - iEndLine = idx0 + (idx1-idx0)*(iSubdivisions+1)/nSubdivisions; */ - assert( ( nSubdivisions == 1 ) || ( nSubdivisions == 3 ) ); + iStartLine = add( idx0, idiv1616U( i_mult( sub( idx1, idx0 ), iSubdivisions ), nSubdivisions ) ); + iEndLine = add( idx0, idiv1616U( i_mult( sub( idx1, idx0 ), add( iSubdivisions, 1 ) ), nSubdivisions ) ); - tmp = sub( idx1, idx0 ); - iStartLine = imult1616( tmp, iSubdivisions ); - iEndLine = add( iStartLine, tmp ); - - if ( EQ_16( nSubdivisions, 3 ) ) - iStartLine = mult( iStartLine, 0x2AAB ); - iStartLine = add( iStartLine, idx0 ); - - if ( EQ_16( nSubdivisions, 3 ) ) - iEndLine = mult( iEndLine, 0x2AAB ); - iEndLine = add( iEndLine, idx0 ); - - /*norms[iFilter][iSubdivisions] = norm2FLOAT(pSpectrum+iStartLine, iEndLine-iStartLine);*/ - headroom = getScaleFactor32( &pSpectrum[iStartLine], sub( iEndLine, iStartLine ) ); - - /* Calculate norm of spectrum band */ - L_tmp = Norm32Norm( pSpectrum + iStartLine, headroom, sub( iEndLine, iStartLine ), &shift ); - - /* Check threshold HLM_MIN_NRG */ - BASOP_SATURATE_WARNING_OFF_EVS; -#ifdef BASOP_NOGLOB - tmp32 = L_sub( L_shl_o( L_tmp, s_min( 31, sub( shift, 24 - 31 * 2 ) ), &Overflow ), 3277l /*HLM_MIN_NRG Q7*/ ); -#else /* BASOP_NOGLOB */ - tmp32 = L_sub( L_shl( L_tmp, s_min( 31, sub( shift, 24 - 31 * 2 ) ) ), 3277l /*HLM_MIN_NRG Q7*/ ); -#endif - BASOP_SATURATE_WARNING_ON_EVS; - - /* get pre-shift for autocorrelation */ - tmp = sub( shift, norm_l( L_tmp ) ); /* exponent for normalized L_tmp */ - tmp = shr( sub( 1, tmp ), 1 ); /* pre-shift to apply before autocorrelation */ - shifts[iFilter][iSubdivisions] = s_min( tmp, headroom ); - move16(); - - /* calc normalization factor */ - facs[iFilter][iSubdivisions] = 0; + /* Variable initialization */ + norms_exp[iFilter][iSubdivisions] = pSpectrum_e; move16(); - facs_e[iFilter][iSubdivisions] = 0; - move16(); - - if ( tmp32 > 0 ) - { - facs[iFilter][iSubdivisions] = 0x7FFF; - move16(); /* normalization not needed for one subdivision */ - } - - test(); - IF( ( tmp32 > 0 ) && ( GT_16( nSubdivisions, 1 ) ) ) - { - move16(); - facs_e[iFilter][iSubdivisions] = shl( sub( tmp, shifts[iFilter][iSubdivisions] ), 1 ); - move16(); - tmp = sub( 1, shl( tmp, 1 ) ); /* exponent of autocorrelation */ - L_tmp = L_shl_sat( L_tmp, sub( shift, tmp ) ); /* shift L_tmp to that exponent */ - - /* calc factor (with 2 bits headroom for sum of 3 subdivisions) */ - move16(); - facs[iFilter][iSubdivisions] = div_s( 0x2000, round_fx_sat( L_tmp ) ); /* L_tmp is >= 0x2000000 */ - } + norms[iFilter][iSubdivisions] = sum2_32_exp_fx( pSpectrum + iStartLine, sub( iEndLine, iStartLine ), &norms_exp[iFilter][iSubdivisions], 8 ); // norms_exp[iFilter][iSubdivisions] + move32(); } } + /* Calculate normalized autocorrelation for spectrum subdivision and get TNS filter parameters based on it */ FOR( iFilter = 0; iFilter < pTnsConfig->nMaxFilters; iFilter++ ) { -#define RXX_E ( 3 ) - Word32 rxx[TNS_MAX_FILTER_ORDER + 1]; - Word16 tmpbuf[350]; - - set32_fx( rxx, 0, TNS_MAX_FILTER_ORDER + 1 ); - idx0 = pTnsConfig->iFilterBorders[iFilter + 1]; move16(); idx1 = pTnsConfig->iFilterBorders[iFilter]; @@ -428,83 +368,51 @@ void CalculateTnsFilt_fx( pFilter = pTnsData->filter + iFilter; nSubdivisions = pTnsConfig->pTnsParameters[iFilter].nSubdivisions; move16(); - FOR( iSubdivisions = 0; iSubdivisions < nSubdivisions; iSubdivisions++ ) - { - IF( facs[iFilter][iSubdivisions] == 0 ) - { - BREAK; - } - - - /* iStartLine = idx0 + (idx1-idx0)*iSubdivisions/nSubdivisions; - iEndLine = idx0 + (idx1-idx0)*(iSubdivisions+1)/nSubdivisions; */ - assert( ( nSubdivisions == 1 ) || ( nSubdivisions == 3 ) ); - - iStartLine = imult1616( spectrumLength, iSubdivisions ); - iEndLine = add( iStartLine, spectrumLength ); - - if ( EQ_16( nSubdivisions, 3 ) ) - iStartLine = mult( iStartLine, 0x2AAB ); - iStartLine = add( iStartLine, idx0 ); - - if ( EQ_16( nSubdivisions, 3 ) ) - iEndLine = mult( iEndLine, 0x2AAB ); - iEndLine = add( iEndLine, idx0 ); - - - move16(); - shift = shifts[iFilter][iSubdivisions]; - move16(); - pWindow = tnsAcfWindow_fx; - - n = sub( iEndLine, iStartLine ); - assert( n < (Word16) ( sizeof( tmpbuf ) / sizeof( Word16 ) ) ); - FOR( i = 0; i < n; i++ ) - { - tmpbuf[i] = round_fx_sat( L_shl_sat( pSpectrum[iStartLine + i], shift ) ); - move16(); - } + set32_fx( rxx, 0, TNS_MAX_FILTER_ORDER + 1 ); /* WMOPS: This initialization is required */ - FOR( lag = 0; lag <= pTnsConfig->maxOrder; lag++ ) + /* Variable initialization */ + test(); + FOR( iSubdivisions = 0; ( iSubdivisions < nSubdivisions ) && ( L_shr_sat( norms[iFilter][iSubdivisions], sub( 6, norms_exp[iFilter][iSubdivisions] ) ) > HLM_MIN_NRG_FX ); iSubdivisions++ ) + { + test(); + fac = BASOP_Util_Divide3232_Scale( 1, norms[iFilter][iSubdivisions], &fac_e ); + fac_e = add( sub( Q31, norms_exp[iFilter][iSubdivisions] ), fac_e ); + iStartLine = add( idx0, idiv1616U( i_mult( spectrumLength, iSubdivisions ), nSubdivisions ) ); + iEndLine = add( idx0, idiv1616U( i_mult( spectrumLength, add( iSubdivisions, 1 ) ), nSubdivisions ) ); + pWindow = tnsAcfWindow_fx; // Q15 + + /* For additional loop condition */ + /* Variable initialization */ + FOR( lag = 1; lag <= pTnsConfig->maxOrder; lag++ ) { - n = sub( sub( iEndLine, lag ), iStartLine ); - - L_tmp = L_deposit_l( 0 ); - FOR( i = 0; i < n; i++ ) + W_tmp = 0; + move64(); + FOR( i = 0; i < iEndLine - iStartLine - lag; i++ ) { -#ifdef BASOP_NOGLOB - L_tmp = L_mac0_sat( L_tmp, tmpbuf[i], tmpbuf[i + lag] ); -#else - L_tmp = L_mac0( L_tmp, tmpbuf[i], tmpbuf[i + lag] ); -#endif + W_tmp = W_mac_32_32( W_tmp, pSpectrum[iStartLine + i], pSpectrum[iStartLine + lag + i] ); } - - if ( lag != 0 ) - L_tmp = Mpy_32_16_1( L_tmp, *pWindow++ ); - - L_tmp = Mpy_32_16_1( L_tmp, facs[iFilter][iSubdivisions] ); - L_tmp = L_shl( L_tmp, facs_e[iFilter][iSubdivisions] ); - - rxx[lag] = L_add( rxx[lag], L_tmp ); + exp = W_norm( W_tmp ); + W_tmp = W_shl( W_tmp, exp ); + exp = sub( shl( pSpectrum_e, 1 ), exp ); + W_tmp = W_mult_32_32( L_mult( fac, ( *pWindow ) ), W_extract_h( W_tmp ) ); // exp + fac_e + rxx[lag] = L_add( rxx[lag], W_extract_h( W_shl( W_tmp, sub( add( fac_e, exp ), 2 ) ) ) ); // Q29 move32(); + pWindow++; } } IF( EQ_16( iSubdivisions, nSubdivisions ) ) /* meaning there is no subdivision with low energy */ { + // To be checked + rxx[0] = L_shl( pTnsConfig->pTnsParameters[iFilter].nSubdivisions, Q29 ); // Q29 + move32(); pFilter->spectrumLength = spectrumLength; move16(); /* Limit the maximum order to spectrum length/4 */ - GetFilterParameters( rxx, s_min( pTnsConfig->maxOrder, shr( pFilter->spectrumLength, 2 ) ), pFilter ); + GetFilterParameters_ivas( rxx, s_min( pTnsConfig->maxOrder, shr( pFilter->spectrumLength, 2 ) ), pFilter ); } } - if ( predictionGain ) - { - assert( pTnsConfig->nMaxFilters == 1 ); - move16(); - *predictionGain = pTnsData->filter->predictionGain; - } return; } @@ -539,6 +447,7 @@ Word16 DetectTnsFilt_ivas_fx( STnsConfig const *pTnsConfig, /* i : TNS Configur Word16 iSubdivisions; #ifdef BASOP_NOGLOB_DECLARE_LOCAL Flag Overflow = 0; + move32(); #endif move16(); @@ -565,12 +474,16 @@ Word16 DetectTnsFilt_ivas_fx( STnsConfig const *pTnsConfig, /* i : TNS Configur iStartLine = imult1616( tmp, iSubdivisions ); iEndLine = add( iStartLine, tmp ); - if ( EQ_16( nSubdivisions, 3 ) ) + IF( EQ_16( nSubdivisions, 3 ) ) + { iStartLine = mult( iStartLine, 0x2AAB ); + } iStartLine = add( iStartLine, idx0 ); - if ( EQ_16( nSubdivisions, 3 ) ) + IF( EQ_16( nSubdivisions, 3 ) ) + { iEndLine = mult( iEndLine, 0x2AAB ); + } iEndLine = add( iEndLine, idx0 ); /*norms[iFilter][iSubdivisions] = norm2FLOAT(pSpectrum+iStartLine, iEndLine-iStartLine);*/ @@ -581,11 +494,7 @@ Word16 DetectTnsFilt_ivas_fx( STnsConfig const *pTnsConfig, /* i : TNS Configur /* Check threshold HLM_MIN_NRG */ BASOP_SATURATE_WARNING_OFF_EVS; -#ifdef BASOP_NOGLOB tmp32 = L_sub( L_shl_o( L_tmp, s_min( 31, sub( shift, 24 - 31 * 2 ) ), &Overflow ), 3277l /*HLM_MIN_NRG Q7*/ ); -#else /* BASOP_NOGLOB */ - tmp32 = L_sub( L_shl( L_tmp, s_min( 31, sub( shift, 24 - 31 * 2 ) ) ), 3277l /*HLM_MIN_NRG Q7*/ ); -#endif BASOP_SATURATE_WARNING_ON_EVS; /* get pre-shift for autocorrelation */ @@ -612,20 +521,12 @@ Word16 DetectTnsFilt_ivas_fx( STnsConfig const *pTnsConfig, /* i : TNS Configur move16(); facs_e[iFilter][iSubdivisions] = shl( sub( tmp, shifts[iFilter][iSubdivisions] ), 1 ); - tmp = sub( 1, shl( tmp, 1 ) ); /* exponent of autocorrelation */ -#ifdef BASOP_NOGLOB + tmp = sub( 1, shl( tmp, 1 ) ); /* exponent of autocorrelation */ L_tmp = L_shl_sat( L_tmp, sub( shift, tmp ) ); /* shift L_tmp to that exponent */ /* calc factor (with 2 bits headroom for sum of 3 subdivisions) */ move16(); facs[iFilter][iSubdivisions] = div_s( 0x2000, round_fx_sat( L_tmp ) ); /* L_tmp is >= 0x2000000 */ -#else - L_tmp = L_shl( L_tmp, sub( shift, tmp ) ); /* shift L_tmp to that exponent */ - - /* calc factor (with 2 bits headroom for sum of 3 subdivisions) */ - move16(); - facs[iFilter][iSubdivisions] = div_s( 0x2000, round_fx( L_tmp ) ); /* L_tmp is >= 0x2000000 */ -#endif } } } @@ -674,12 +575,16 @@ Word16 DetectTnsFilt_ivas_fx( STnsConfig const *pTnsConfig, /* i : TNS Configur iStartLine = imult1616( spectrumLength, iSubdivisions ); iEndLine = add( iStartLine, spectrumLength ); - if ( EQ_16( nSubdivisions, 3 ) ) + IF( EQ_16( nSubdivisions, 3 ) ) + { iStartLine = mult( iStartLine, 0x2AAB ); + } iStartLine = add( iStartLine, idx0 ); - if ( EQ_16( nSubdivisions, 3 ) ) + IF( EQ_16( nSubdivisions, 3 ) ) + { iEndLine = mult( iEndLine, 0x2AAB ); + } iEndLine = add( iEndLine, idx0 ); @@ -704,15 +609,13 @@ Word16 DetectTnsFilt_ivas_fx( STnsConfig const *pTnsConfig, /* i : TNS Configur L_tmp = L_deposit_l( 0 ); FOR( i = 0; i < n; i++ ) { -#ifdef BASOP_NOGLOB L_tmp = L_mac0_sat( L_tmp, tmpbuf[i], tmpbuf[i + lag] ); -#else - L_tmp = L_mac0( L_tmp, tmpbuf[i], tmpbuf[i + lag] ); -#endif } - if ( lag != 0 ) + IF( lag != 0 ) + { L_tmp = Mpy_32_16_1( L_tmp, *pWindow++ ); + } L_tmp = Mpy_32_16_1( L_tmp, facs[iFilter][iSubdivisions] ); L_tmp = L_shl( L_tmp, facs_e[iFilter][iSubdivisions] ); @@ -731,7 +634,7 @@ Word16 DetectTnsFilt_ivas_fx( STnsConfig const *pTnsConfig, /* i : TNS Configur } } - if ( predictionGain ) + IF( predictionGain ) { assert( pTnsConfig->nMaxFilters == 1 ); move16(); @@ -739,7 +642,7 @@ Word16 DetectTnsFilt_ivas_fx( STnsConfig const *pTnsConfig, /* i : TNS Configur } /* We check the filter's decisions in the opposite direction */ - FOR( iFilter = sub( pTnsConfig->nMaxFilters, 1 ); iFilter >= 0; iFilter-- ) + FOR( iFilter = ( pTnsConfig->nMaxFilters - 1 ); iFilter >= 0; iFilter-- ) { STnsFilter *pFilter; struct TnsParameters const *pTnsParameters; @@ -752,7 +655,6 @@ Word16 DetectTnsFilt_ivas_fx( STnsConfig const *pTnsConfig, /* i : TNS Configur IF( s_or( (Word16) GT_16( pFilter->predictionGain, pTnsParameters->minPredictionGain ), sub( pFilter->avgSqrCoef, pTnsParameters->minAvgSqrCoef ) > 0 ) ) { - move16(); // pTnsData->nFilters > 0 || isTCX10 || ltp_gain < 0.6f || hTranDet == NULL // .6f = 19660, Q=15 test(); @@ -766,7 +668,7 @@ Word16 DetectTnsFilt_ivas_fx( STnsConfig const *pTnsConfig, /* i : TNS Configur ELSE { maxEnergyChange = GetTCXMaxenergyChange_ivas_fx( hTranDet, isTCX10, NSUBBLOCKS, 3 ); - IF( sub( maxEnergyChange, pTnsParameters->minEnergyChange ) >= 0 ) + IF( sub( maxEnergyChange, shl( pTnsParameters->minEnergyChange, Q3 - Q7 ) ) >= 0 ) { pTnsData->nFilters = add( pTnsData->nFilters, 1 ); @@ -936,7 +838,69 @@ Word16 WriteTnsData_ivas_fx( STnsConfig const *pTnsConfig, Word16 const *stream, /********************************/ /* Private functions */ /********************************/ +static void GetFilterParameters_ivas( Word32 rxx[], Word16 maxOrder, STnsFilter *pTnsFilter ) +{ + Word16 i; + Word16 parCoeff[TNS_MAX_FILTER_ORDER + 1]; + Word32 rxx_0; + Word32 L_tmp; +#if TNS_COEF_RES == 5 + Word16 const *values = tnsCoeff5; +#elif TNS_COEF_RES == 4 + Word16 const *values = tnsCoeff4; +#elif TNS_COEF_RES == 3 + Word16 const *values = tnsCoeff3; +#endif + Word16 *indexes = pTnsFilter->coefIndex; + + rxx_0 = rxx[0]; + move32(); + /* compute TNS filter in lattice (ParCor) form with LeRoux-Gueguen algorithm */ + L_tmp = E_LPC_schur_ivas( rxx, parCoeff, maxOrder ); + BASOP_SATURATE_WARNING_OFF_EVS /* Allow saturation, this value is compared against a threshold. */ + Word16 temp_e = 0; + move16(); + Word16 temp = BASOP_Util_Divide3232_Scale( rxx_0, L_tmp, &temp_e ); + pTnsFilter->predictionGain32 = L_deposit_h( temp ); + move32(); + pTnsFilter->predictionGain_e = temp_e; + move16(); + pTnsFilter->predictionGain = shl_sat( temp, sub( temp_e, PRED_GAIN_E ) ); // Q7 + move16(); + BASOP_SATURATE_WARNING_ON_EVS + /* non-linear quantization of TNS lattice coefficients with given resolution */ + Parcor2Index( parCoeff, indexes, maxOrder ); + /* reduce filter order by truncating trailing zeros */ + i = sub( maxOrder, 1 ); + + test(); + WHILE( ( i >= 0 ) && ( indexes[i] == 0 ) ) + { + i = sub( i, 1 ); + } + + + pTnsFilter->order = add( i, 1 ); + move16(); + + /* compute avg(coef*coef) */ + L_tmp = L_deposit_l( 0 ); + + FOR( i = pTnsFilter->order - 1; i >= 0; i-- ) + { + Word16 value; + + value = shr( values[indexes[i] + INDEX_SHIFT], 1 ); + + L_tmp = L_mac0( L_tmp, value, value ); + } + + pTnsFilter->avgSqrCoef = round_fx( L_tmp ); + move16(); + /* assert(maxOrder == 8); + pTnsFilter->avgSqrCoef = shr(pTnsFilter->avgSqrCoef, 3); */ +} static void GetFilterParameters( Word32 rxx[], Word16 maxOrder, STnsFilter *pTnsFilter ) { Word16 i; @@ -963,8 +927,10 @@ static void GetFilterParameters( Word32 rxx[], Word16 maxOrder, STnsFilter *pTns /* reduce filter order by truncating trailing zeros */ i = sub( maxOrder, 1 ); + test(); WHILE( ( i >= 0 ) && ( indexes[i] == 0 ) ) { + test(); i = sub( i, 1 ); } @@ -978,10 +944,8 @@ static void GetFilterParameters( Word32 rxx[], Word16 maxOrder, STnsFilter *pTns { Word16 value; - move16(); value = shr( values[indexes[i] + INDEX_SHIFT], 1 ); - move16(); L_tmp = L_mac0( L_tmp, value, value ); } move16(); @@ -1000,7 +964,6 @@ static void Parcor2Index( const Word16 parCoeff[] /*Q15*/, Word16 index[], Word1 Word16 x; - move16(); move16(); nValues = 1 << TNS_COEF_RES; #if TNS_COEF_RES == 5 @@ -1021,10 +984,13 @@ static void Parcor2Index( const Word16 parCoeff[] /*Q15*/, Word16 index[], Word1 /* parCoeff is in the range of -1.0 ... 1.0 by definition */ /* assert((x >= FL2WORD16(-1.0f)) && (x <= FL2WORD16(1.0f))); */ + test(); WHILE( ( iIndex < nValues ) && ( x > add( shr( values[iIndex - 1], 1 ), shr( values[iIndex], 1 ) ) ) ) { + test(); iIndex = add( iIndex, 1 ); } index[i] = sub( iIndex, 1 + INDEX_SHIFT ); + move16(); } } diff --git a/lib_enc/transient_detection.c b/lib_enc/transient_detection.c deleted file mode 100644 index 8e87e5685392d3f3d073201ea23f756e0c7592f3..0000000000000000000000000000000000000000 --- a/lib_enc/transient_detection.c +++ /dev/null @@ -1,183 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include "stat_enc.h" -#include "cnst.h" -#include "prot.h" -#include "ivas_prot.h" -#include -#include "wmc_auto.h" - -#include "prot_fx.h" -#include "ivas_prot_fx.h" -/*---------------------------------------------------------------* - * Local constants - *---------------------------------------------------------------*/ - -#define MIN_BLOCK_ENERGY 107.37f - -#define THR_HIGH 8.5f -#define THR_NORM_HIGH 8.0f -#define THR_NORM_LOW 4.5f -#define THR_LOW 4.25f -#define THR_LOW_STEP 1.0f - -/*---------------------------------------------------------------* - * Local function prototypes - *---------------------------------------------------------------*/ - - -/*-------------------------------------------------------------------* - * InitTransientDetection() - * - * - *-------------------------------------------------------------------*/ - - -/*-------------------------------------------------------------------* - * GetTCXAvgTemporalFlatnessMeasure() - * - * - *-------------------------------------------------------------------*/ - - -/*-------------------------------------------------------------------* - * GetTCXMaxenergyChange() - * - * - *-------------------------------------------------------------------*/ - - -/*---------------------------------------------------------------* - * Local functions - *---------------------------------------------------------------*/ - -/** TCX decision. - * Check if there is an attack in a subblock. Version for TCX Long/Short decision. - * See TCheckSubblocksForAttack for definition of parameters. - * It is assumed that the delay of MDCT overlap was not taken into account, so that the last subblock corresponds to the newest input subblock. - */ - - -/** Init transient detector. - * Fills TransientDetector structure with sensible content and enable it. - * @param pSubblockEnergies Subblock energies used in this transient detector. - * @param nDelay Delay for this transient detector. - * @param nSubblocksToCheck Number of subblocks to check in this transient detector. - * @param pCheckSubblockForAttack Attack detection function for this transient detector. - * @param pSetAttackPosition Function for finalizing this transient detector. - * @param attackRatioThreshold Attack ratio threshold. - * @param pTransientDetector Structure to be initialized. - */ - - -/*-------------------------------------------------------------------* - * set_transient_stereo() - * - * - *-------------------------------------------------------------------*/ -void set_transient_stereo_fx( - CPE_ENC_HANDLE hCPE, /* i : CPE structure */ - Word16 currFlatness[] /* i/o: current flatness */ -) -{ - Word16 n, attackIsPresent; - Word16 currFlatnessMax; - Encoder_State **sts; - - sts = hCPE->hCoreCoder; - - /* for DFT/TD based stereo ,map avg. flatness to individual stereo channels (M/S or X/Y) */ - maximum_fx( currFlatness, CPE_CHANNELS, &currFlatnessMax ); - attackIsPresent = 0; - move16(); - - FOR( n = 0; n < CPE_CHANNELS; n++ ) - { - attackIsPresent = s_max( attackIsPresent, sts[n]->hTranDet->transientDetector.bIsAttackPresent ); - } - - set16_fx( currFlatness, currFlatnessMax, CPE_CHANNELS ); - - FOR( n = 0; n < CPE_CHANNELS; n++ ) - { - sts[n]->hTranDet->transientDetector.bIsAttackPresent = attackIsPresent; - move16(); - } - - IF( hCPE->hStereoDft != NULL ) - { - IF( hCPE->hStereoDft->attackPresent ) - { - hCPE->hStereoDft->wasTransient = 1; - move16(); - } - ELSE IF( hCPE->hStereoDft->wasTransient ) - { - hCPE->hStereoDft->wasTransient = 0; - move16(); - } - - hCPE->hStereoDft->attackPresent = attackIsPresent; - move16(); - - hCPE->hStereoDft->hItd->currFlatness_fx = 0; - move16(); - FOR( n = 0; n < CPE_CHANNELS; n++ ) - { - hCPE->hStereoDft->hItd->currFlatness_fx = s_max( hCPE->hStereoDft->hItd->currFlatness_fx, currFlatness[n] ); - } - } - - IF( hCPE->hStereoMdct != NULL ) - { - hCPE->hStereoMdct->hItd->currFlatness_fx = 0; - move16(); - FOR( n = 0; n < CPE_CHANNELS; n++ ) - { - hCPE->hStereoMdct->hItd->currFlatness_fx = s_max( hCPE->hStereoMdct->hItd->currFlatness_fx, currFlatness[n] ); - } - } - - return; -} -/*-------------------------------------------------------------------* - * transient_analysis() - * - * - *-------------------------------------------------------------------*/ diff --git a/lib_enc/transient_detection_fx.c b/lib_enc/transient_detection_fx.c index a68053993c7c4d84af5b75561598ce870001955c..3c88ca2244c8da1e362e90c87c6c80c8b4b5eb2e 100644 --- a/lib_enc/transient_detection_fx.c +++ b/lib_enc/transient_detection_fx.c @@ -16,6 +16,7 @@ #include "ivas_prot_fx.h" /* Function prototypes */ #include "prot_fx_enc.h" /* Function prototypes */ + /* Exponent of attack threshold. Picked according to current threshold values. */ #define ATTACKTHRESHOLD_E 4 /* Exponent of subblock energies and accumulated subblock energies. @@ -141,6 +142,107 @@ static void GetAttackForTCXDecision( Word32 const *pSubblockNrg, Word32 const *p *pbIsAttackPresent = bIsAttackPresent; } +static void GetAttackForTCXDecision_ivas_fx( Word32 const *pSubblockNrg, Word32 const *pAccSubblockNrg, Word16 nSubblocks, Word16 nPastSubblocks, Word16 attackRatioThreshold, Word16 *pbIsAttackPresent, Word16 *pAttackIndex ) +{ + Word16 i; + Word16 bIsAttackPresent, attackIndex; + Word16 attackRatioThreshold_1_5; + Word64 W_tmp1, W_tmp2, W_tmp3; + + (void) nPastSubblocks; + (void) nSubblocks; + assert( nSubblocks >= NSUBBLOCKS ); + assert( nPastSubblocks >= 2 ); + + /* attackRatioThreshold_1_5 = attackRatioThreshold * 1.5, exponent is ATTACKTHRESHOLD_E+1 */ + attackRatioThreshold_1_5 = add( shr( attackRatioThreshold, 2 ), shr( attackRatioThreshold, 1 ) ); + + move16(); + move16(); + bIsAttackPresent = FALSE; + attackIndex = -1; + /* Search for the last attack in the subblocks */ + IF( s_or( (Word16) GT_32( L_shr( pSubblockNrg[-1], ATTACKTHRESHOLD_E ), Mpy_32_16_1( pAccSubblockNrg[-1], attackRatioThreshold ) ), + L_sub( L_shr( pSubblockNrg[-2], ATTACKTHRESHOLD_E ), Mpy_32_16_1( pAccSubblockNrg[-2], attackRatioThreshold ) ) > 0 ) ) + { + move16(); + bIsAttackPresent = TRUE; + attackIndex = 0; + move16(); + } + + FOR( i = 0; i < NSUBBLOCKS; i++ ) + { + W_tmp2 = W_shr( W_mult_32_16( pAccSubblockNrg[i], attackRatioThreshold ), 1 ); + W_tmp1 = W_shl( pSubblockNrg[i], ( 15 - ATTACKTHRESHOLD_E ) ); + + IF( GT_64( W_tmp1, W_tmp2 ) ) + { + if ( i < 6 ) + { + move16(); + bIsAttackPresent = TRUE; + } + + IF( s_and( (Word16) NE_16( attackIndex, 2 ), (Word16) NE_16( attackIndex, 6 ) ) ) + { + move16(); + attackIndex = i; + W_tmp2 = W_shr( W_mult_32_16( pAccSubblockNrg[i], attackRatioThreshold ), 1 ); + W_tmp2 = W_add( W_tmp2, W_shr( W_tmp2, 3 ) ); // pAccSubblockNrg[i] * 1.125f + W_tmp1 = W_shl( pSubblockNrg[i], ( 15 - ATTACKTHRESHOLD_E ) ); + if ( s_and( (Word16) LT_64( W_tmp1, W_tmp2 ), s_or( (Word16) EQ_16( i, 2 ), (Word16) EQ_16( i, 6 ) ) ) ) + { + attackIndex = add( attackIndex, 1 ); /* avoid minimum overlap to prevent clicks */ + } + } + } + ELSE /* no attack, but set index anyway in case of strong energy increase */ + { + W_tmp2 = W_shr( W_mult_32_16( pSubblockNrg[i - 1], attackRatioThreshold_1_5 ), 1 ); + W_tmp1 = W_shl( pSubblockNrg[i], ( 15 - ( ATTACKTHRESHOLD_E + 1 ) ) ); + W_tmp3 = W_shr( W_mult_32_16( pSubblockNrg[i - 2], attackRatioThreshold_1_5 ), 1 ); + + IF( s_and( ( (Word16) GT_64( W_tmp1, W_tmp2 ) ), + ( W_sub( W_tmp1, W_tmp3 ) > 0 ) ) ) + { + + IF( s_and( (Word16) NE_16( attackIndex, 2 ), (Word16) NE_16( attackIndex, 6 ) ) ) + { + move16(); + attackIndex = i; + + W_tmp2 = W_mult_32_16( pSubblockNrg[i - 1], attackRatioThreshold ); + W_tmp3 = W_mult_32_16( pSubblockNrg[i - 2], attackRatioThreshold ); + W_tmp1 = W_shl( pSubblockNrg[i], ( 15 - ATTACKTHRESHOLD_E ) ); + + if ( s_and( (Word16) s_or( (Word16) LT_64( W_tmp1, W_tmp2 ), (Word16) + LT_64( W_tmp1, W_tmp3 ) ), + s_or( (Word16) EQ_16( i, 2 ), (Word16) EQ_16( i, 6 ) ) ) ) + { + attackIndex = add( attackIndex, 1 ); /* avoid minimum overlap to prevent clicks */ + } + } + } + } + } + /* avoid post-echos on click sounds (very short transients) due to TNS aliasing */ + if ( EQ_16( attackIndex, 4 ) ) + { + move16(); + attackIndex = 7; + } + if ( EQ_16( attackIndex, 5 ) ) + { + move16(); + attackIndex = 6; + } + + move16(); + move16(); + *pAttackIndex = attackIndex; + *pbIsAttackPresent = bIsAttackPresent; +} void GetAttackForTCXDecision_fx( Word32 const *pSubblockNrg, Word32 const *pAccSubblockNrg, Word16 nSubblocks, Word16 nPastSubblocks, Word16 attackRatioThreshold, Word16 *pbIsAttackPresent, Word16 *pAttackIndex ) { @@ -256,7 +358,7 @@ void InitTransientDetection_ivas_fx( Word16 nFrameLength, /* Init a subblock energies buffer used for the TCX Short/Long decision. */ InitSubblockEnergies_ivas_fx( nFrameLength, nTCXDelay, &pTransientDetection->delayBuffer, &pTransientDetection->subblockEnergies ); /* Init the TCX Short/Long transient detector. */ - InitTransientDetector_ivas_fx( &pTransientDetection->subblockEnergies, nTCXDelay, NSUBBLOCKS, GetAttackForTCXDecision, 17408 /*8.5f/(1<transientDetector ); + InitTransientDetector_ivas_fx( &pTransientDetection->subblockEnergies, nTCXDelay, NSUBBLOCKS, GetAttackForTCXDecision_ivas_fx, 17408 /*8.5f/(1<transientDetector ); /* We need two past subblocks for the TCX TD and NSUBBLOCKS+1 for the temporal flatness measure FOR the TCX LTP. */ IF( ext_mem_flag ) { @@ -377,9 +479,11 @@ Word16 GetTCXMaxenergyChange_fx( struct TransientDetection const *pTransientDete nRelativeDelay = sub( pSubblockEnergies->nDelay, nDelay ); pSubblockNrgChange = NULL; nTotBlocks = nCurrentSubblocks + nPrevSubblocks; + move16(); assert( nTotBlocks > 0 ); maxEnergyChange = 0 /*0.0f Q7*/; + move16(); assert( ( nPrevSubblocks <= nRelativeDelay ) && ( nCurrentSubblocks <= NSUBBLOCKS + nDelay ) ); pSubblockNrgChange = &pSubblockEnergies->subblockNrgChange[nRelativeDelay - nPrevSubblocks]; @@ -565,16 +669,27 @@ void RunTransientDetection_ivas_fx( IF( GT_16( sub( q_input, pSubblockEnergies->q_firState ), shift ) ) { Scale_sig( input_fx, length, add( sub( pSubblockEnergies->q_firState, q_input ), shift ) ); // q_firState + shift - pSubblockEnergies->firState1 = shl( pSubblockEnergies->firState1, shift ); // q_firState + shift +#ifdef FIX_ISSUE_1186 + q_input = add( pSubblockEnergies->q_firState, shift ); // q_firState + shift +#endif + pSubblockEnergies->firState1 = shl( pSubblockEnergies->firState1, shift ); // q_firState + shift move16(); pSubblockEnergies->firState2 = shl( pSubblockEnergies->firState2, shift ); // q_firState + shift move16(); pSubblockEnergies->q_firState = add( pSubblockEnergies->q_firState, shift ); // q_firState + shift move16(); +#ifndef FIX_ISSUE_1186 q_input = add( pSubblockEnergies->q_firState, shift ); // q_firState + shift +#endif } ELSE { + Word16 norm = norm_arr( input_fx, length ); + IF( norm == 0 ) + { + Scale_sig( input_fx, length, -1 ); + q_input = sub( q_input, 1 ); + } pSubblockEnergies->firState1 = shl( pSubblockEnergies->firState1, sub( q_input, pSubblockEnergies->q_firState ) ); // q_input move16(); pSubblockEnergies->firState2 = shl( pSubblockEnergies->firState2, sub( q_input, pSubblockEnergies->q_firState ) ); // q_input @@ -611,7 +726,7 @@ void RunTransientDetection_ivas_fx( e0_fx = dotp_fx( filteredInput_fx + /* length / 2 */ shr( length, 1 ), filteredInput_fx + /* length / 2 */ shr( length, 1 ), shr( pSubblockEnergies->pDelayBuffer->nSubblockSize, 1 ) /* pSubblockEnergies->pDelayBuffer->nSubblockSize / 2 */, &exp ); exp = sub( exp, 2 * 0 - 1 ); // Q = 2*0 + (30-exp), E = 31 - (2*0 + 30 - exp) = 1 + exp - 2*0 = exp - (2*0-1) e0_fx = BASOP_Util_Add_Mant32Exp( MIN_BLOCK_ENERGY_IVAS_FX_Q7 / 2, 31 - Q7, e0_fx, exp, &exp ); - e1_fx = BASOP_Util_Add_Mant32Exp( pSubblockEnergies->subblockNrg[pSubblockEnergies->nDelay + 4], 31 - 0, L_negate( e0_fx ), exp, &exp1 ); + e1_fx = BASOP_Util_Add_Mant32Exp( pSubblockEnergies->subblockNrg[pSubblockEnergies->nDelay + 4], 32, L_negate( e0_fx ), exp, &exp1 ); IF( BASOP_Util_Cmp_Mant32Exp( e1_fx, exp1, e0_fx, exp ) > 0 ) { pSubblockEnergies->ramp_up_flag = (UWord16) L_or( pSubblockEnergies->ramp_up_flag, 0x0001 ); @@ -678,7 +793,7 @@ void SetTCXModeInfo_ivas_fx( test(); test(); /* window switching based on transient detector output */ - IF( ( ( hTranDet->transientDetector.bIsAttackPresent ) || ( GT_32( Mpy_32_32( st->currEnergyHF_fx, 55063683 /*1.0f/39.0f Q31*/ ), st->prevEnergyHF_fx ) && NE_16( st->element_mode, IVAS_CPE_MDCT ) ) ) && + IF( ( ( hTranDet->transientDetector.bIsAttackPresent ) || ( EQ_32( BASOP_Util_Cmp_Mant32Exp( Mpy_32_32( st->currEnergyHF_fx, 55063683 /*1.0f/39.0f Q31*/ ), st->currEnergyHF_e_fx, st->prevEnergyHF_fx, 17 ), 1 ) && NE_16( st->element_mode, IVAS_CPE_MDCT ) ) ) && ( ( NE_16( st->last_core, ACELP_CORE ) ) && ( NE_16( st->last_core, AMR_WB_CORE ) ) ) ) { hTcxEnc->tcxMode = TCX_10; @@ -709,6 +824,20 @@ void SetTCXModeInfo_ivas_fx( move16(); } } + +#ifdef SUPPORT_FORCE_TCX10_TCX20 +#ifdef DEBUGGING + if ( st->force == FORCE_TCX10 ) + { + hTcxEnc->tcxMode = TCX_10; + } + else if ( st->force == FORCE_TCX20 ) + { + hTcxEnc->tcxMode = TCX_20; + } +#endif +#endif + /* set the left window overlap */ test(); test(); @@ -752,7 +881,7 @@ void SetTCXModeInfo_ivas_fx( IF( isLongTermTransient_fx( L_deposit_h( tmp ), &hTcxEnc->tfm_mem_fx ) && EQ_16( st->element_mode, IVAS_CPE_MDCT ) ) { test(); - if ( NE_16( *tcxModeOverlap, MIN_OVERLAP ) && LT_16( hTcxEnc->tcxltp_norm_corr_past, 18432 /* 0.5625f in Q15 */ ) ) + IF( NE_16( *tcxModeOverlap, MIN_OVERLAP ) && LT_16( hTcxEnc->tcxltp_norm_corr_past, 18432 /* 0.5625f in Q15 */ ) ) { *tcxModeOverlap = HALF_OVERLAP; move16(); @@ -803,7 +932,7 @@ void SetTCXModeInfo_ivas_fx( /* for the ACELP -> TCX transition frames use full right window overlap */ test(); - if ( ( EQ_16( st->hTcxCfg->tcx_last_overlap_mode, TRANSITION_OVERLAP ) ) && ( EQ_16( *tcxModeOverlap, ALDO_WINDOW ) ) ) + IF( ( EQ_16( st->hTcxCfg->tcx_last_overlap_mode, TRANSITION_OVERLAP ) ) && ( EQ_16( *tcxModeOverlap, ALDO_WINDOW ) ) ) { *tcxModeOverlap = FULL_OVERLAP; move16(); @@ -961,6 +1090,7 @@ static void InitDelayBuffer( Word16 nFrameLength, Word16 nDelay, DelayBuffer *pD static void InitSubblockEnergies( Word16 nFrameLength, Word16 nDelay, DelayBuffer *pDelayBuffer, SubblockEnergies *pSubblockEnergies ) { Word16 const nMaxBuffSize = sizeof( pSubblockEnergies->subblockNrg ) / sizeof( pSubblockEnergies->subblockNrg[0] ); + move16(); (void) nFrameLength; @@ -969,12 +1099,17 @@ static void InitSubblockEnergies( Word16 nFrameLength, Word16 nDelay, DelayBuffe set32_fx( pSubblockEnergies->subblockNrg, MIN_BLOCK_ENERGY, nMaxBuffSize ); set32_fx( pSubblockEnergies->accSubblockNrg, MIN_BLOCK_ENERGY, nMaxBuffSize + 1 ); set16_fx( pSubblockEnergies->subblockNrgChange, 0x7fff, nMaxBuffSize ); - pSubblockEnergies->nDelay = nDelay / pDelayBuffer->nSubblockSize; + pSubblockEnergies->nDelay = idiv1616_1( nDelay, pDelayBuffer->nSubblockSize ); assert( pSubblockEnergies->nDelay < nMaxBuffSize ); pSubblockEnergies->nPartialDelay = nDelay % pDelayBuffer->nSubblockSize; pSubblockEnergies->facAccSubblockNrg = 26624 /*0.8125f Q15*/; /* Energy accumulation factor */ pSubblockEnergies->firState1 = 0; pSubblockEnergies->firState2 = 0; + move16(); + move16(); + move16(); + move16(); + move16(); pSubblockEnergies->pDelayBuffer = pDelayBuffer; pDelayBuffer->nDelay = s_max( pDelayBuffer->nDelay, pSubblockEnergies->nPartialDelay ); @@ -987,8 +1122,8 @@ static void InitSubblockEnergies_ivas_fx( Word16 nFrameLength, Word16 nDelay, De assert( ( pDelayBuffer != NULL ) && ( pSubblockEnergies != NULL ) && ( pDelayBuffer->nSubblockSize * NSUBBLOCKS == nFrameLength ) && ( pDelayBuffer->nSubblockSize > 0 ) ); - set32_fx( pSubblockEnergies->subblockNrg, 107 /* 107.37 in Q0 */, nMaxBuffSize ); - set32_fx( pSubblockEnergies->accSubblockNrg, 107 /* 107.37 in Q0 */, nMaxBuffSize + 1 ); + set32_fx( pSubblockEnergies->subblockNrg, 54 /* 107.37 in Q(-1) */, nMaxBuffSize ); + set32_fx( pSubblockEnergies->accSubblockNrg, 54 /* 107.37 in Q(-1) */, nMaxBuffSize + 1 ); set16_fx( pSubblockEnergies->subblockNrgChange, ONE_IN_Q3, nMaxBuffSize ); IF( nDelay != 0 ) { @@ -1037,16 +1172,22 @@ static void InitTransientDetector_fx( SubblockEnergies *pSubblockEnergies, Word1 assert( ( pSubblockEnergies != NULL ) && ( pSubblockEnergies->pDelayBuffer != NULL ) && ( pTransientDetector != NULL ) && ( pSubblockEnergies->pDelayBuffer->nSubblockSize != 0 ) ); pTransientDetector->pSubblockEnergies = pSubblockEnergies; pTransientDetector->nDelay = ( nDelay - pSubblockEnergies->nPartialDelay ) / pSubblockEnergies->pDelayBuffer->nSubblockSize; + move16(); assert( nDelay == pTransientDetector->nDelay * pSubblockEnergies->pDelayBuffer->nSubblockSize + pSubblockEnergies->nPartialDelay ); assert( pTransientDetector->nDelay < nMaxBuffSize ); pSubblockEnergies->nDelay = s_max( pSubblockEnergies->nDelay, pTransientDetector->nDelay ); assert( nSubblocksToCheck <= NSUBBLOCKS + pTransientDetector->nDelay ); pTransientDetector->nSubblocksToCheck = nSubblocksToCheck; + move16(); pTransientDetector->CheckSubblocksForAttack_fx = pCheckSubblocksForAttack; pTransientDetector->attackRatioThreshold = attackRatioThreshold; + move16(); pTransientDetector->prev_bIsAttackPresent = FALSE; + move16(); pTransientDetector->bIsAttackPresent = FALSE; + move16(); pTransientDetector->attackIndex = -1; + move16(); } static void InitTransientDetector_ivas_fx( SubblockEnergies *pSubblockEnergies, Word16 nDelay, Word16 nSubblocksToCheck, TCheckSubblocksForAttack_fx pCheckSubblocksForAttack, Word16 attackRatioThreshold, TransientDetector *pTransientDetector ) @@ -1147,10 +1288,10 @@ static void UpdateDelayBuffer( Word16 const *input, Word16 nSamplesAvailable, De move16(); nDelay = pDelayBuffer->nDelay; - assert( ( nDelay >= 0 ) && ( nDelay <= (int) sizeof( pDelayBuffer->buffer ) / (int) sizeof( pDelayBuffer->buffer[0] ) ) ); + assert( ( nDelay >= 0 ) && ( nDelay <= (Word32) sizeof( pDelayBuffer->buffer ) / (Word32) sizeof( pDelayBuffer->buffer[0] ) ) ); assert( nSamplesAvailable <= NSUBBLOCKS * pDelayBuffer->nSubblockSize ); /* If this is not the last frame */ - IF( nSamplesAvailable == NSUBBLOCKS * pDelayBuffer->nSubblockSize ) + IF( EQ_16( nSamplesAvailable, imult1616( NSUBBLOCKS, pDelayBuffer->nSubblockSize ) ) ) { /* Store the newest samples into the delay buffer */ FOR( i = 0; i < nDelay; i++ ) @@ -1166,7 +1307,7 @@ static void UpdateSubblockEnergies( Word16 const *input, Word16 nSamplesAvailabl Word16 i; - assert( ( pSubblockEnergies->nDelay >= 0 ) && ( pSubblockEnergies->nDelay + NSUBBLOCKS <= (int) sizeof( pSubblockEnergies->subblockNrg ) / (int) sizeof( pSubblockEnergies->subblockNrg[0] ) ) ); + assert( ( pSubblockEnergies->nDelay >= 0 ) && ( pSubblockEnergies->nDelay + NSUBBLOCKS <= (Word32) sizeof( pSubblockEnergies->subblockNrg ) / (Word32) sizeof( pSubblockEnergies->subblockNrg[0] ) ) ); assert( pSubblockEnergies->nPartialDelay <= pSubblockEnergies->pDelayBuffer->nDelay ); /* At least one block delay is required when subblock energy change is required */ assert( pSubblockEnergies->nDelay >= 1 ); @@ -1191,7 +1332,7 @@ static void UpdateSubblockEnergies_ivas_fx( Word16 const *input, Word16 nSamples Word16 i; - assert( ( pSubblockEnergies->nDelay >= 0 ) && ( pSubblockEnergies->nDelay + NSUBBLOCKS <= (int) sizeof( pSubblockEnergies->subblockNrg ) / (int) sizeof( pSubblockEnergies->subblockNrg[0] ) ) ); + assert( ( pSubblockEnergies->nDelay >= 0 ) && ( pSubblockEnergies->nDelay + NSUBBLOCKS <= (Word32) sizeof( pSubblockEnergies->subblockNrg ) / (Word32) sizeof( pSubblockEnergies->subblockNrg[0] ) ) ); assert( pSubblockEnergies->nPartialDelay <= pSubblockEnergies->pDelayBuffer->nDelay ); /* At least one block delay is required when subblock energy change is required */ assert( pSubblockEnergies->nDelay >= 1 ); @@ -1286,11 +1427,7 @@ static void CalculateSubblockEnergies( Word16 const *input, Word16 nSamplesAvail FOR( k = 0; k < w; k++ ) { tmp = shr( input[k], SUBBLOCK_NRG_E / 2 ); -#ifdef BASOP_NOGLOB accu = L_mac0_sat( accu, tmp, tmp ); -#else - accu = L_mac0( accu, tmp, tmp ); -#endif } move32(); @@ -1307,11 +1444,7 @@ static void CalculateSubblockEnergies( Word16 const *input, Word16 nSamplesAvail FOR( ; k < k2; k++ ) { tmp = shr( input[k], SUBBLOCK_NRG_E / 2 ); -#ifdef BASOP_NOGLOB accu = L_mac0_sat( accu, tmp, tmp ); -#else - accu = L_mac0( accu, tmp, tmp ); -#endif } move32(); pSubblockNrg[w] = accu; @@ -1362,9 +1495,9 @@ static void CalculateSubblockEnergies_ivas_fx( Word16 const *input, Word16 nSamp Word16 *pSubblockNrgChange; Word32 *pAccSubblockTmp; Word16 nWindows; - Word16 w, k, k2, tmp; + Word16 w, k, k2; Word32 w0, w1; - Word32 accu; + Word64 accu; move16(); pDelayBuffer = pSubblockEnergies->pDelayBuffer; @@ -1389,53 +1522,35 @@ static void CalculateSubblockEnergies_ivas_fx( Word16 const *input, Word16 nSamp IF( nWindows > 0 ) { /* Process left over samples from the previous frame. */ - accu = 107; // 107.37f in Q0 - move32(); - assert( ( SUBBLOCK_NRG_E & 1 ) == 0 ); + accu = 215; // 107.37f in Q1 + move64(); FOR( k = 0; k < nPartialDelay; k++ ) { - tmp = delayBuffer[k]; // Q0 - move16(); - accu = L_mac0( accu, tmp, tmp ); // Q0 + accu = W_mac_16_16( accu, delayBuffer[k], delayBuffer[k] ); // Q1 } /* Process new samples in the 0. subblock. */ - w = sub( nSubblockSize, nPartialDelay ); - assert( ( SUBBLOCK_NRG_E & 1 ) == 0 ); - FOR( k = 0; k < w; k++ ) + FOR( k = 0; k < ( nSubblockSize - nPartialDelay ); k++ ) { - tmp = input[k]; // Q0 - move16(); -#ifdef BASOP_NOGLOB - accu = L_mac0_sat( accu, tmp, tmp ); // Q0 -#else - accu = L_mac0( accu, tmp, tmp ); -#endif + accu = W_mac_16_16( accu, input[k], input[k] ); // Q1 } - pSubblockNrg[0] = accu; // Q0 + pSubblockNrg[0] = W_shl_sat_l( accu, -2 ); // Q(-1) move32(); /* Set accumulated subblock energy at this point. */ UpdatedAndStoreAccWindowNrg( pSubblockNrg[0], pAccSubblockTmp, facAccSubblockNrg, &pAccSubblockNrg[0] ); FOR( w = 1; w < nWindows; w++ ) { - accu = 107; // 107.37f in Q0 - move32(); + accu = 215; // 107.37f in Q1 + move64(); /* Process new samples in the w. subblock. */ k2 = add( k, nSubblockSize ); - assert( ( SUBBLOCK_NRG_E & 1 ) == 0 ); FOR( ; k < k2; k++ ) { - tmp = input[k]; // Q0 - move16(); -#ifdef BASOP_NOGLOB - accu = L_mac0_sat( accu, tmp, tmp ); // Q0 -#else - accu = L_mac0( accu, tmp, tmp ); -#endif + accu = W_mac_16_16( accu, input[k], input[k] ); // Q1 } - pSubblockNrg[w] = accu; // Q0 + pSubblockNrg[w] = W_shl_sat_l( accu, -2 ); // Q(-1) move32(); /* Set accumulated subblock energy at this point. */ UpdatedAndStoreAccWindowNrg( pSubblockNrg[w], pAccSubblockTmp, facAccSubblockNrg, &pAccSubblockNrg[w] ); @@ -1555,7 +1670,7 @@ Word16 transient_analysis_ivas_fx( const Word16 nRelativeDelay = sub( hTranDet->subblockEnergies.nDelay, hTranDet->transientDetector.nDelay ); Word16 prel_force_td; Word32 cor_map_LT_sum = 0; - move16(); + move32(); /* Set pointer to the reverse accumulator buffer */ pTmp_fx = &accSubblockNrgRev_fx[NSUBBLOCKS - 1]; @@ -1618,7 +1733,7 @@ Word16 transient_analysis_ivas_fx( /* Forward attack analysis */ FOR( i = -2; i < 7; i++ ) { - IF( BASOP_Util_Cmp_Mant32Exp( hTranDet->subblockEnergies.subblockNrg[nRelativeDelay + i], 31, Mpy_32_16_1( hTranDet->subblockEnergies.accSubblockNrg[nRelativeDelay + i], thr_fwd_fx ), ( 31 + 4 ) ) > 0 ) + IF( BASOP_Util_Cmp_Mant32Exp( hTranDet->subblockEnergies.subblockNrg[nRelativeDelay + i], 32, Mpy_32_16_1( hTranDet->subblockEnergies.accSubblockNrg[nRelativeDelay + i], thr_fwd_fx ), ( 32 + 4 ) ) > 0 ) { prel_force_td = s_or( prel_force_td, 0x0001 ); } @@ -1655,7 +1770,7 @@ Word16 transient_analysis_ivas_fx( /* -3 check */ test(); - IF( BASOP_Util_Cmp_Mant32Exp( pSubblockNrg[1 + offset], 31, Mpy_32_16_1( accSubblockNrgRev_fx[1], thr_rev_fx ), ( 31 + 4 ) ) > 0 ) + IF( BASOP_Util_Cmp_Mant32Exp( pSubblockNrg[1 + offset], 32, Mpy_32_16_1( accSubblockNrgRev_fx[1], thr_rev_fx ), ( 32 + 4 ) ) > 0 ) { prel_force_td = s_or( prel_force_td, 0x0002 ); move16(); @@ -1663,10 +1778,10 @@ Word16 transient_analysis_ivas_fx( /* -4 check */ test(); - IF( prel_force_td == 0 && BASOP_Util_Cmp_Mant32Exp( pSubblockNrg[offset], 31, Mpy_32_16_1( accSubblockNrgRev_fx[0], thr_rev_fx ), ( 31 + 4 ) ) > 0 ) + IF( prel_force_td == 0 && BASOP_Util_Cmp_Mant32Exp( pSubblockNrg[offset], 32, Mpy_32_16_1( accSubblockNrgRev_fx[0], thr_rev_fx ), ( 32 + 4 ) ) > 0 ) { - IF( BASOP_Util_Cmp_Mant32Exp( pSubblockNrg[offset], 31, Mpy_32_16_1( accSubblockNrgRev_fx[0], add( thr_rev_fx, THR_LOW_STEP_FX ) ), ( 31 + 4 ) ) > 0 ) + IF( BASOP_Util_Cmp_Mant32Exp( pSubblockNrg[offset], 32, Mpy_32_16_1( accSubblockNrgRev_fx[0], add( thr_rev_fx, THR_LOW_STEP_FX ) ), ( 32 + 4 ) ) > 0 ) { prel_force_td = s_or( prel_force_td, 0x0004 ); } @@ -1680,3 +1795,76 @@ Word16 transient_analysis_ivas_fx( return prel_force_td != 0; } + +/*-------------------------------------------------------------------* + * set_transient_stereo() + * + * + *-------------------------------------------------------------------*/ +void set_transient_stereo_fx( + CPE_ENC_HANDLE hCPE, /* i : CPE structure */ + Word16 currFlatness[] /* i/o: current flatness */ +) +{ + Word16 n, attackIsPresent; + Word16 currFlatnessMax; + Encoder_State **sts; + + sts = hCPE->hCoreCoder; + + /* for DFT/TD based stereo ,map avg. flatness to individual stereo channels (M/S or X/Y) */ + maximum_fx( currFlatness, CPE_CHANNELS, &currFlatnessMax ); + attackIsPresent = 0; + move16(); + + FOR( n = 0; n < CPE_CHANNELS; n++ ) + { + attackIsPresent = s_max( attackIsPresent, sts[n]->hTranDet->transientDetector.bIsAttackPresent ); + } + + set16_fx( currFlatness, currFlatnessMax, CPE_CHANNELS ); + + FOR( n = 0; n < CPE_CHANNELS; n++ ) + { + sts[n]->hTranDet->transientDetector.bIsAttackPresent = attackIsPresent; + move16(); + } + + IF( hCPE->hStereoDft != NULL ) + { + IF( hCPE->hStereoDft->attackPresent ) + { + hCPE->hStereoDft->wasTransient = 1; + move16(); + } + ELSE IF( hCPE->hStereoDft->wasTransient ) + { + hCPE->hStereoDft->wasTransient = 0; + move16(); + } + + hCPE->hStereoDft->attackPresent = attackIsPresent; + move16(); + + hCPE->hStereoDft->hItd->currFlatness_fx = 0; + move16(); + FOR( n = 0; n < CPE_CHANNELS; n++ ) + { + hCPE->hStereoDft->hItd->currFlatness_fx = s_max( hCPE->hStereoDft->hItd->currFlatness_fx, currFlatness[n] ); + move16(); + } + } + + IF( hCPE->hStereoMdct != NULL ) + { + hCPE->hStereoMdct->hItd->currFlatness_fx = 0; + move16(); + FOR( n = 0; n < CPE_CHANNELS; n++ ) + { + hCPE->hStereoMdct->hItd->currFlatness_fx = s_max( hCPE->hStereoMdct->hItd->currFlatness_fx, currFlatness[n] ); + move16(); + } + } + + return; +} diff --git a/lib_enc/transition_enc.c b/lib_enc/transition_enc.c deleted file mode 100644 index 5f6981ef6a10eb4df6842d5c37d90c5468adf943..0000000000000000000000000000000000000000 --- a/lib_enc/transition_enc.c +++ /dev/null @@ -1,44 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include -#include "cnst.h" -#include "rom_com.h" -#include "prot.h" -#include "wmc_auto.h" -#include "prot_fx.h" diff --git a/lib_enc/transition_enc_fx.c b/lib_enc/transition_enc_fx.c index 513ea4098f52e70eda4a8039eac7f4274b9d7101..9911d766ae7790b70d3e26b7a5cbe1b37b0d5063 100644 --- a/lib_enc/transition_enc_fx.c +++ b/lib_enc/transition_enc_fx.c @@ -7,7 +7,6 @@ #include "cnst.h" /* Common constants */ #include "rom_com_fx.h" /* Static table prototypes */ #include "rom_com.h" /* Static table prototypes */ -#include "prot.h" /* Function prototypes */ #include "prot_fx.h" /* Function prototypes */ #include "prot_fx_enc.h" /* Function prototypes */ @@ -114,6 +113,8 @@ void transition_enc_fx( T_op[1] = (int16_t)(pitch[1] * 1.25f + 0.5f);*/ T_op[0] = add( st_fx->pitch[0], mult_r( st_fx->pitch[0], 8192 /*0.25f Q15*/ ) ); T_op[1] = add( st_fx->pitch[1], mult_r( st_fx->pitch[1], 8192 /*0.25f Q15*/ ) ); + move16(); + move16(); } shift_wsp = add( Q_new, shift ); @@ -132,6 +133,7 @@ void transition_enc_fx( IF( i_subfr == 0 ) { mult_Top = 1; + move16(); IF( limit_flag == 0 ) { test(); @@ -166,6 +168,7 @@ void transition_enc_fx( g_corr_fx[2] = -16384; move16(); g_corr_fx[3] = shl( sub( shift_wsp, 1 ), 1 ); + move16(); set16_fx( &exc_fx[i_subfr], 0, L_SUBFR ); /* set excitation for current subrame to 0 */ @@ -210,11 +213,16 @@ void transition_enc_fx( { /* this is called only to compute unused bits */ config_acelp1( ENC, st_fx->total_brate, st_fx->core_brate, st_fx->core, st_fx->extl, st_fx->extl_brate, +#ifdef NONBE_FIX_GSC_BSTR + L_FRAME, -1, &( st_fx->acelp_cfg ), hBstr->nb_bits_tot, TRANSITION, -1, TC_0_0, 3, NULL, unbits_ACELP, +#else L_FRAME, -1, &( st_fx->acelp_cfg ), hBstr->nb_bits_tot, TRANSITION, TC_0_0, 3, NULL, unbits_ACELP, +#endif st_fx->element_mode, &i /*dummy*/, 0 /*tdm_lp_reuse_flag*/, 0 /*tdm_low_rate_mode*/, st_fx->idchan, st_fx->active_fr_cnt_fx, 0 /*tdm_Pitch_reuse_flag*/, st_fx->tdm_LRTD_flag, 0 /*GSC_IVAS_mode*/ ); } *clip_gain = gp_clip_fx( st_fx->element_mode, st_fx->core_brate, st_fx->voicing_fx, i_subfr, TRANSITION, xn_fx, gp_cl_fx, sub( shift_wsp, 1 ) ); + move16(); updt_tar_fx( xn_fx, xn2_fx, y1_fx, *gain_pit_fx, L_SUBFR ); **pt_pitch_fx = shl( add( shl( *T0, 2 ), *T0_frac ), 4 ); @@ -282,6 +290,7 @@ void transition_enc_fx( /* Find the closed loop pitch period */ *T0 = pitch_fr4_fx( &exc_fx[i_subfr], xn_fx, h1_fx, *T0_min, *T0_max, T0_frac, pit_flag, limit_flag, pit_start, pit_limit, L_FRAME, L_SUBFR ); + move16(); offset = tbe_celp_exc_offset( *T0, *T0_frac, st_fx->L_frame ); @@ -289,6 +298,7 @@ void transition_enc_fx( FOR( i = 0; i < L_SUBFR * HIBND_ACB_L_FAC; i++ ) { bwe_exc_fx[i + i_subfr * HIBND_ACB_L_FAC] = bwe_exc_fx[i + i_subfr * HIBND_ACB_L_FAC - offset]; + move16(); } @@ -319,7 +329,11 @@ void transition_enc_fx( IF( LE_16( sub( i_subfr, *tc_subfr ), L_SUBFR ) ) { config_acelp1( ENC, st_fx->total_brate, st_fx->core_brate, st_fx->core, st_fx->extl, st_fx->extl_brate, +#ifdef NONBE_FIX_GSC_BSTR + st_fx->L_frame, -1, &( st_fx->acelp_cfg ), hBstr->nb_bits_tot, TRANSITION, -1, *tc_subfr, 2, NULL, +#else st_fx->L_frame, -1, &( st_fx->acelp_cfg ), hBstr->nb_bits_tot, TRANSITION, *tc_subfr, 2, NULL, +#endif unbits_ACELP, st_fx->element_mode, &i /*dummy*/, 0 /*tdm_lp_reuse_flag*/, 0 /*tdm_low_rate_mode*/, st_fx->idchan, st_fx->active_fr_cnt_fx, 0 /*tdm_Pitch_reuse_flag*/, st_fx->tdm_LRTD_flag, 0 /*GSC_IVAS_mode*/ ); } /*-----------------------------------------------------------------* @@ -394,6 +408,7 @@ void transition_enc_fx( FOR( i = 0; i < L_SUBFR * HIBND_ACB_L_FAC; i++ ) { bwe_exc_fx[i + i_subfr * HIBND_ACB_L_FAC] = bwe_exc_fx[i + i_subfr * HIBND_ACB_L_FAC - offset]; + move16(); } } ELSE IF( ( EQ_16( i_subfr, 2 * L_SUBFR ) ) && ( EQ_16( *tc_subfr, TC_0_128 ) ) ) @@ -408,6 +423,7 @@ void transition_enc_fx( move16(); *T0 = pitch_fr4_fx( &exc_fx[i_subfr], xn_fx, h1_fx, *T0_min, *T0_max, T0_frac, pit_flag, limit_flag, pit_start, 3 * L_SUBFR, L_FRAME, L_SUBFR ); + move16(); IF( LT_16( add( ( *T0 ), ( *position ) ), 2 * L_SUBFR ) ) { @@ -441,6 +457,7 @@ void transition_enc_fx( FOR( i = 0; i < L_SUBFR * HIBND_ACB_L_FAC; i++ ) { bwe_exc_fx[i + i_subfr * HIBND_ACB_L_FAC] = bwe_exc_fx[i + i_subfr * HIBND_ACB_L_FAC - offset]; + move16(); } } ELSE IF( ( EQ_16( i_subfr, 2 * L_SUBFR ) ) && ( EQ_16( *tc_subfr, TC_0_192 ) ) ) @@ -469,6 +486,7 @@ void transition_enc_fx( move16(); *T0 = pitch_fr4_fx( &exc_fx[i_subfr], xn_fx, h1_fx, *T0_min, *T0_max, T0_frac, pit_flag, limit_flag, PIT_MIN, PIT_FR1_8b, L_FRAME, L_SUBFR ); + move16(); IF( LT_16( add( *T0, *position ), 3 * L_SUBFR ) ) { @@ -514,6 +532,7 @@ void transition_enc_fx( pit_flag = L_SUBFR; move16(); *T0 = pitch_fr4_fx( &exc_fx[i_subfr], xn_fx, h1_fx, *T0_min, *T0_max, T0_frac, pit_flag, limit_flag, PIT_MIN, PIT_FR1_8b, L_FRAME, L_SUBFR ); + move16(); index = delta_pit_enc_fx( 2, *T0, *T0_frac, *T0_min ); push_indice_fx( hBstr, IND_PITCH, index, nBits ); @@ -526,6 +545,7 @@ void transition_enc_fx( FOR( i = 0; i < L_SUBFR * HIBND_ACB_L_FAC; i++ ) { bwe_exc_fx[i + i_subfr * HIBND_ACB_L_FAC] = bwe_exc_fx[i + i_subfr * HIBND_ACB_L_FAC - offset]; + move16(); } } @@ -538,15 +558,18 @@ void transition_enc_fx( test(); IF( EQ_16( nBits, 8 ) || EQ_16( nBits, 5 ) ) { + test(); test(); IF( !( ( *tc_subfr == 0 ) && ( EQ_16( i_subfr, L_SUBFR ) ) ) ) { *T0 = pitch_fr4_fx( &exc_fx[i_subfr], xn_fx, h1_fx, *T0_min, *T0_max, T0_frac, pit_flag, limit_flag, PIT_MIN, PIT_FR1_8b, L_FRAME, L_SUBFR ); + move16(); } } ELSE { *T0 = pitch_fr4_fx( &exc_fx[i_subfr], xn_fx, h1_fx, *T0_min, *T0_max, T0_frac, pit_flag, limit_flag, PIT_FR2_9b, PIT_FR1_9b, L_FRAME, L_SUBFR ); + move16(); } pit_Q_enc_fx( hBstr, 0, nBits, 8, pit_flag, limit_flag, *T0, *T0_frac, T0_min, T0_max ); @@ -558,6 +581,7 @@ void transition_enc_fx( FOR( i = 0; i < L_SUBFR * HIBND_ACB_L_FAC; i++ ) { bwe_exc_fx[i + i_subfr * HIBND_ACB_L_FAC] = bwe_exc_fx[i + i_subfr * HIBND_ACB_L_FAC - offset]; + move16(); } } @@ -584,6 +608,7 @@ void transition_enc_fx( ELSE { *clip_gain = gp_clip_fx( st_fx->element_mode, st_fx->core_brate, st_fx->voicing_fx, i_subfr, TRANSITION, xn_fx, gp_cl_fx, ( Q_new + shift - 1 ) ); + move16(); lp_select = lp_filt_exc_enc_fx( MODE1, TRANSITION, i_subfr, exc_fx, h1_fx, xn_fx, y1_fx, xn2_fx, L_SUBFR, st_fx->L_frame, g_corr_fx, *clip_gain, gain_pit_fx, &lp_flag ); @@ -604,7 +629,7 @@ void transition_enc_fx( test(); test(); test(); - IF( ( *tc_subfr >= 2 * L_SUBFR ) && ( i_subfr == 3 * L_SUBFR ) ) + IF( ( GE_16( *tc_subfr, 2 * L_SUBFR ) ) && ( EQ_16( i_subfr, 3 * L_SUBFR ) ) ) { tmp = shl( add( shl( *T0, 2 ), *T0_frac ), 4 ); ( *pt_pitch_fx ) -= 3; @@ -620,8 +645,9 @@ void transition_enc_fx( **pt_pitch_fx = tmp; move16(); ( *pt_pitch_fx )++; + move16(); } - ELSE IF( ( *tc_subfr == L_SUBFR ) && ( i_subfr == 2 * L_SUBFR ) ) + ELSE IF( ( EQ_16( *tc_subfr, L_SUBFR ) ) && ( EQ_16( i_subfr, 2 * L_SUBFR ) ) ) { tmp = shl( add( shl( *T0, 2 ), *T0_frac ), 4 ); ( *pt_pitch_fx ) -= 2; @@ -635,7 +661,7 @@ void transition_enc_fx( ( *pt_pitch_fx )++; move16(); } - ELSE IF( ( *tc_subfr == TC_0_64 ) && ( i_subfr == L_SUBFR ) ) + ELSE IF( ( EQ_16( *tc_subfr, TC_0_64 ) ) && ( EQ_16( i_subfr, L_SUBFR ) ) ) { tmp = shl( add( shl( *T0, 2 ), *T0_frac ), 4 ); ( *pt_pitch_fx ) -= 1; @@ -645,7 +671,7 @@ void transition_enc_fx( ( *pt_pitch_fx )++; move16(); } - ELSE IF( ( *tc_subfr == TC_0_128 ) && ( i_subfr == 2 * L_SUBFR ) ) + ELSE IF( ( EQ_16( *tc_subfr, TC_0_128 ) ) && ( EQ_16( i_subfr, 2 * L_SUBFR ) ) ) { tmp = shl( add( shl( *T0, 2 ), *T0_frac ), 4 ); ( *pt_pitch_fx ) -= 2; @@ -659,7 +685,7 @@ void transition_enc_fx( ( *pt_pitch_fx )++; move16(); } - ELSE IF( ( *tc_subfr == TC_0_192 ) && ( i_subfr == 3 * L_SUBFR ) ) + ELSE IF( ( EQ_16( *tc_subfr, TC_0_192 ) ) && ( EQ_16( i_subfr, 3 * L_SUBFR ) ) ) { tmp = shl( add( shl( *T0, 2 ), *T0_frac ), 4 ); ( *pt_pitch_fx ) -= 3; @@ -719,6 +745,7 @@ void transition_enc_fx( IF( EQ_16( nBits, 10 ) ) { *T0 = pitch_fr4_fx( &exc_fx[i_subfr], xn_fx, h1_fx, *T0_min, *T0_max, T0_frac, 0, limit_flag, PIT16k_FR2_EXTEND_10b, PIT16k_MAX, st_fx->L_frame, L_SUBFR ); + move16(); pit16k_Q_enc_fx( hBstr, nBits, limit_flag, *T0, *T0_frac, T0_min, T0_max ); } ELSE IF( EQ_16( nBits, 8 ) ) /* tc_subfr==0 && i_subfr==L_SUBFR */ @@ -729,6 +756,7 @@ void transition_enc_fx( * PIT16k_FR2_TC0_2SUBFR to 2*L_SUBFR resolution 1/2 (frac = 0 or 2) *-----------------------------------------------------------------------------*/ *T0 = pitch_fr4_fx( &exc_fx[i_subfr], xn_fx, h1_fx, *T0_min, *T0_max, T0_frac, 0, limit_flag, PIT16k_FR2_TC0_2SUBFR, 2 * L_SUBFR, st_fx->L_frame, L_SUBFR ); + move16(); IF( GT_16( *T0_max, 2 * L_SUBFR ) ) { @@ -754,6 +782,7 @@ void transition_enc_fx( { /* delta search */ *T0 = pitch_fr4_fx( &exc_fx[i_subfr], xn_fx, h1_fx, *T0_min, *T0_max, T0_frac, L_SUBFR, limit_flag, PIT16k_FR2_EXTEND_9b, PIT16k_FR1_EXTEND_9b, st_fx->L_frame, L_SUBFR ); + move16(); index = delta_pit_enc_fx( 4, *T0, *T0_frac, *T0_min ); push_indice_fx( hBstr, IND_PITCH, index, nBits ); @@ -807,9 +836,11 @@ void transition_enc_fx( { /* bwe_exc_fx[i + i_subfr * 2] = bwe_exc_fx[i + i_subfr * 2 - *T0 * 2 - (int) ((float) *T0_frac * 0.5f + 4 + 0.5f) + 4];move16();*/ bwe_exc_fx[i + i_subfr * 2] = bwe_exc_fx[i + i_subfr * 2 - offset + 4]; + move16(); } *clip_gain = gp_clip_fx( st_fx->element_mode, st_fx->core_brate, st_fx->voicing_fx, i_subfr, TRANSITION, xn_fx, gp_cl_fx, Q_new ); + move16(); lp_select = lp_filt_exc_enc_fx( MODE1, TRANSITION, i_subfr, exc_fx, h1_fx, xn_fx, y1_fx, xn2_fx, L_SUBFR, st_fx->L_frame, g_corr_fx, *clip_gain, gain_pit_fx, &lp_flag ); @@ -845,6 +876,7 @@ void transition_enc_fx( **pt_pitch_fx = tmp; move16(); ( *pt_pitch_fx )++; + move16(); } } } @@ -891,7 +923,8 @@ void transition_enc_ivas_fx( /* set limit_flag to 0 for restrained limits, and 1 for extended limits */ limit_flag = 0; move16(); - + Word16 h1_fx_q15[L_SUBFR + ( M + 1 )]; + Copy_Scale_sig( h1_fx, h1_fx_q15, L_SUBFR + ( M + 1 ), 0 ); pit_start = PIT_MIN; move16(); @@ -908,7 +941,9 @@ void transition_enc_ivas_fx( /*T_op[0] = (int16_t)(pitch[0] * 1.25f + 0.5f); T_op[1] = (int16_t)(pitch[1] * 1.25f + 0.5f);*/ T_op[0] = add( st_fx->pitch[0], mult_r( st_fx->pitch[0], 8192 /*0.25f Q15*/ ) ); + move16(); T_op[1] = add( st_fx->pitch[1], mult_r( st_fx->pitch[1], 8192 /*0.25f Q15*/ ) ); + move16(); } shift_wsp = add( Q_new, shift ); @@ -927,6 +962,7 @@ void transition_enc_ivas_fx( IF( i_subfr == 0 ) { mult_Top = 1; + move16(); IF( limit_flag == 0 ) { test(); @@ -954,13 +990,14 @@ void transition_enc_ivas_fx( move16(); *clip_gain = 0; move16(); - g_corr_fx[0] = 16384; + g_corr_fx[0] = MAX16B /* 1.0f in Q15 */; move16(); - g_corr_fx[1] = add( shl( sub( shift_wsp, 1 ), 1 ), 1 ); + g_corr_fx[1] = 0; move16(); - g_corr_fx[2] = -16384; + g_corr_fx[2] = MAX16B /* 1.0f in Q15 */; + move16(); + g_corr_fx[3] = 0; move16(); - g_corr_fx[3] = shl( sub( shift_wsp, 1 ), 1 ); set16_fx( &exc_fx[i_subfr], 0, L_SUBFR ); /* set excitation for current subrame to 0 */ @@ -1005,11 +1042,16 @@ void transition_enc_ivas_fx( { /* this is called only to compute unused bits */ config_acelp1( ENC, st_fx->total_brate, st_fx->core_brate, st_fx->core, st_fx->extl, st_fx->extl_brate, +#ifdef NONBE_FIX_GSC_BSTR + L_FRAME, -1, &( st_fx->acelp_cfg ), hBstr->nb_bits_tot, TRANSITION, -1, TC_0_0, 3, NULL, unbits_ACELP, +#else L_FRAME, -1, &( st_fx->acelp_cfg ), hBstr->nb_bits_tot, TRANSITION, TC_0_0, 3, NULL, unbits_ACELP, +#endif st_fx->element_mode, &i /*dummy*/, 0 /*tdm_lp_reuse_flag*/, 0 /*tdm_low_rate_mode*/, st_fx->idchan, st_fx->active_fr_cnt_fx, 0 /*tdm_Pitch_reuse_flag*/, st_fx->tdm_LRTD_flag, 0 /*GSC_IVAS_mode*/ ); } *clip_gain = gp_clip_fx( st_fx->element_mode, st_fx->core_brate, st_fx->voicing_fx, i_subfr, TRANSITION, xn_fx, gp_cl_fx, sub( shift_wsp, 1 ) ); + move16(); updt_tar_fx( xn_fx, xn2_fx, y1_fx, *gain_pit_fx, L_SUBFR ); **pt_pitch_fx = shl( add( shl( *T0, 2 ), *T0_frac ), 4 ); @@ -1077,6 +1119,7 @@ void transition_enc_ivas_fx( /* Find the closed loop pitch period */ *T0 = pitch_fr4_fx( &exc_fx[i_subfr], xn_fx, h1_fx, *T0_min, *T0_max, T0_frac, pit_flag, limit_flag, pit_start, pit_limit, L_FRAME, L_SUBFR ); + move16(); offset = tbe_celp_exc_offset( *T0, *T0_frac, st_fx->L_frame ); @@ -1084,6 +1127,7 @@ void transition_enc_ivas_fx( FOR( i = 0; i < L_SUBFR * HIBND_ACB_L_FAC; i++ ) { bwe_exc_fx[i + i_subfr * HIBND_ACB_L_FAC] = bwe_exc_fx[i + i_subfr * HIBND_ACB_L_FAC - offset]; + move16(); } @@ -1114,7 +1158,11 @@ void transition_enc_ivas_fx( IF( LE_16( sub( i_subfr, *tc_subfr ), L_SUBFR ) ) { config_acelp1( ENC, st_fx->total_brate, st_fx->core_brate, st_fx->core, st_fx->extl, st_fx->extl_brate, +#ifdef NONBE_FIX_GSC_BSTR + st_fx->L_frame, -1, &( st_fx->acelp_cfg ), hBstr->nb_bits_tot, TRANSITION, -1, *tc_subfr, 2, NULL, +#else st_fx->L_frame, -1, &( st_fx->acelp_cfg ), hBstr->nb_bits_tot, TRANSITION, *tc_subfr, 2, NULL, +#endif unbits_ACELP, st_fx->element_mode, &i /*dummy*/, 0 /*tdm_lp_reuse_flag*/, 0 /*tdm_low_rate_mode*/, st_fx->idchan, st_fx->active_fr_cnt_fx, 0 /*tdm_Pitch_reuse_flag*/, st_fx->tdm_LRTD_flag, 0 /*GSC_IVAS_mode*/ ); } /*-----------------------------------------------------------------* @@ -1189,6 +1237,7 @@ void transition_enc_ivas_fx( FOR( i = 0; i < L_SUBFR * HIBND_ACB_L_FAC; i++ ) { bwe_exc_fx[i + i_subfr * HIBND_ACB_L_FAC] = bwe_exc_fx[i + i_subfr * HIBND_ACB_L_FAC - offset]; + move16(); } } ELSE IF( ( EQ_16( i_subfr, 2 * L_SUBFR ) ) && ( EQ_16( *tc_subfr, TC_0_128 ) ) ) @@ -1203,6 +1252,7 @@ void transition_enc_ivas_fx( move16(); *T0 = pitch_fr4_fx( &exc_fx[i_subfr], xn_fx, h1_fx, *T0_min, *T0_max, T0_frac, pit_flag, limit_flag, pit_start, 3 * L_SUBFR, L_FRAME, L_SUBFR ); + move16(); IF( LT_16( add( ( *T0 ), ( *position ) ), 2 * L_SUBFR ) ) { @@ -1236,6 +1286,7 @@ void transition_enc_ivas_fx( FOR( i = 0; i < L_SUBFR * HIBND_ACB_L_FAC; i++ ) { bwe_exc_fx[i + i_subfr * HIBND_ACB_L_FAC] = bwe_exc_fx[i + i_subfr * HIBND_ACB_L_FAC - offset]; + move16(); } } ELSE IF( ( EQ_16( i_subfr, 2 * L_SUBFR ) ) && ( EQ_16( *tc_subfr, TC_0_192 ) ) ) @@ -1264,6 +1315,7 @@ void transition_enc_ivas_fx( move16(); *T0 = pitch_fr4_fx( &exc_fx[i_subfr], xn_fx, h1_fx, *T0_min, *T0_max, T0_frac, pit_flag, limit_flag, PIT_MIN, PIT_FR1_8b, L_FRAME, L_SUBFR ); + move16(); IF( LT_16( add( *T0, *position ), 3 * L_SUBFR ) ) { @@ -1308,7 +1360,9 @@ void transition_enc_ivas_fx( *--------------------------------------------------------*/ pit_flag = L_SUBFR; move16(); + *T0 = pitch_fr4_fx( &exc_fx[i_subfr], xn_fx, h1_fx, *T0_min, *T0_max, T0_frac, pit_flag, limit_flag, PIT_MIN, PIT_FR1_8b, L_FRAME, L_SUBFR ); + move16(); index = delta_pit_enc_fx( 2, *T0, *T0_frac, *T0_min ); push_indice( hBstr, IND_PITCH, index, nBits ); @@ -1321,6 +1375,7 @@ void transition_enc_ivas_fx( FOR( i = 0; i < L_SUBFR * HIBND_ACB_L_FAC; i++ ) { bwe_exc_fx[i + i_subfr * HIBND_ACB_L_FAC] = bwe_exc_fx[i + i_subfr * HIBND_ACB_L_FAC - offset]; + move16(); } } @@ -1337,11 +1392,13 @@ void transition_enc_ivas_fx( IF( !( ( *tc_subfr == 0 ) && ( EQ_16( i_subfr, L_SUBFR ) ) ) ) { *T0 = pitch_fr4_fx( &exc_fx[i_subfr], xn_fx, h1_fx, *T0_min, *T0_max, T0_frac, pit_flag, limit_flag, PIT_MIN, PIT_FR1_8b, L_FRAME, L_SUBFR ); + move16(); } } ELSE { *T0 = pitch_fr4_fx( &exc_fx[i_subfr], xn_fx, h1_fx, *T0_min, *T0_max, T0_frac, pit_flag, limit_flag, PIT_FR2_9b, PIT_FR1_9b, L_FRAME, L_SUBFR ); + move16(); } pit_Q_enc_ivas_fx( hBstr, 0, nBits, 8, pit_flag, limit_flag, *T0, *T0_frac, T0_min, T0_max ); @@ -1353,6 +1410,7 @@ void transition_enc_ivas_fx( FOR( i = 0; i < L_SUBFR * HIBND_ACB_L_FAC; i++ ) { bwe_exc_fx[i + i_subfr * HIBND_ACB_L_FAC] = bwe_exc_fx[i + i_subfr * HIBND_ACB_L_FAC - offset]; + move16(); } } @@ -1379,9 +1437,11 @@ void transition_enc_ivas_fx( ELSE { *clip_gain = gp_clip_fx( st_fx->element_mode, st_fx->core_brate, st_fx->voicing_fx, i_subfr, TRANSITION, xn_fx, gp_cl_fx, ( Q_new + shift - 1 ) ); + move16(); - lp_select = lp_filt_exc_enc_fx( MODE1, TRANSITION, i_subfr, exc_fx, h1_fx, - xn_fx, y1_fx, xn2_fx, L_SUBFR, st_fx->L_frame, g_corr_fx, *clip_gain, gain_pit_fx, &lp_flag ); + Copy_Scale_sig( h1_fx, h1_fx_q15, L_SUBFR + ( M + 1 ), 1 ); + lp_select = lp_filt_exc_enc_ivas_fx( MODE1, TRANSITION, i_subfr, exc_fx, h1_fx_q15, + xn_fx, y1_fx, xn2_fx, L_SUBFR, st_fx->L_frame, g_corr_fx, *clip_gain, gain_pit_fx, &lp_flag ); IF( EQ_16( lp_flag, NORMAL_OPERATION ) ) { @@ -1415,6 +1475,7 @@ void transition_enc_ivas_fx( **pt_pitch_fx = tmp; move16(); ( *pt_pitch_fx )++; + move16(); } ELSE IF( ( *tc_subfr == L_SUBFR ) && ( i_subfr == 2 * L_SUBFR ) ) { @@ -1514,6 +1575,7 @@ void transition_enc_ivas_fx( IF( EQ_16( nBits, 10 ) ) { *T0 = pitch_fr4_fx( &exc_fx[i_subfr], xn_fx, h1_fx, *T0_min, *T0_max, T0_frac, 0, limit_flag, PIT16k_FR2_EXTEND_10b, PIT16k_MAX, st_fx->L_frame, L_SUBFR ); + move16(); pit16k_Q_enc_ivas_fx( hBstr, nBits, limit_flag, *T0, *T0_frac, T0_min, T0_max ); } ELSE IF( EQ_16( nBits, 8 ) ) /* tc_subfr==0 && i_subfr==L_SUBFR */ @@ -1524,6 +1586,7 @@ void transition_enc_ivas_fx( * PIT16k_FR2_TC0_2SUBFR to 2*L_SUBFR resolution 1/2 (frac = 0 or 2) *-----------------------------------------------------------------------------*/ *T0 = pitch_fr4_fx( &exc_fx[i_subfr], xn_fx, h1_fx, *T0_min, *T0_max, T0_frac, 0, limit_flag, PIT16k_FR2_TC0_2SUBFR, 2 * L_SUBFR, st_fx->L_frame, L_SUBFR ); + move16(); IF( GT_16( *T0_max, 2 * L_SUBFR ) ) { @@ -1549,6 +1612,7 @@ void transition_enc_ivas_fx( { /* delta search */ *T0 = pitch_fr4_fx( &exc_fx[i_subfr], xn_fx, h1_fx, *T0_min, *T0_max, T0_frac, L_SUBFR, limit_flag, PIT16k_FR2_EXTEND_9b, PIT16k_FR1_EXTEND_9b, st_fx->L_frame, L_SUBFR ); + move16(); index = delta_pit_enc_fx( 4, *T0, *T0_frac, *T0_min ); push_indice( hBstr, IND_PITCH, index, nBits ); @@ -1570,10 +1634,14 @@ void transition_enc_ivas_fx( move16(); *clip_gain = 0; move16(); - g_corr_fx[0] = 0; + g_corr_fx[0] = 328 /* 0.01f in Q15 */; move16(); g_corr_fx[1] = 0; move16(); + g_corr_fx[2] = 328 /* 0.01f in Q15 */; + move16(); + g_corr_fx[3] = 0; + move16(); *Jopt_flag = 0; move16(); @@ -1602,13 +1670,15 @@ void transition_enc_ivas_fx( { /* bwe_exc_fx[i + i_subfr * 2] = bwe_exc_fx[i + i_subfr * 2 - *T0 * 2 - (int) ((float) *T0_frac * 0.5f + 4 + 0.5f) + 4];move16();*/ bwe_exc_fx[i + i_subfr * 2] = bwe_exc_fx[i + i_subfr * 2 - offset + 4]; + move16(); } *clip_gain = gp_clip_fx( st_fx->element_mode, st_fx->core_brate, st_fx->voicing_fx, i_subfr, TRANSITION, xn_fx, gp_cl_fx, Q_new ); + move16(); - lp_select = lp_filt_exc_enc_fx( MODE1, TRANSITION, i_subfr, exc_fx, h1_fx, - xn_fx, y1_fx, xn2_fx, L_SUBFR, st_fx->L_frame, g_corr_fx, *clip_gain, gain_pit_fx, &lp_flag ); - + Copy_Scale_sig( h1_fx, h1_fx_q15, L_SUBFR + ( M + 1 ), 1 ); + lp_select = lp_filt_exc_enc_ivas_fx( MODE1, TRANSITION, i_subfr, exc_fx, h1_fx_q15, + xn_fx, y1_fx, xn2_fx, L_SUBFR, st_fx->L_frame, g_corr_fx, *clip_gain, gain_pit_fx, &lp_flag ); IF( EQ_16( lp_flag, NORMAL_OPERATION ) ) { push_indice( hBstr, IND_LP_FILT_SELECT, lp_select, 1 ); @@ -1640,6 +1710,7 @@ void transition_enc_ivas_fx( **pt_pitch_fx = tmp; move16(); ( *pt_pitch_fx )++; + move16(); } } } @@ -1689,6 +1760,7 @@ static void tc_enc_fx( BSTR_ENC_HANDLE hBstr = st_fx->hBstr; #ifdef BASOP_NOGLOB_DECLARE_LOCAL Flag Overflow = 0; + move32(); #endif imp_pos = sub( *position, i_subfr ); FOR( i = 0; i < L_SUBFR; i++ ) @@ -1701,6 +1773,7 @@ static void tc_enc_fx( *-----------------------------------------------------------------*/ nBits = st_fx->acelp_cfg.pitch_bits[shr( i_subfr, 6 )]; + move16(); /*--------------------------------------------------------------* * Closed loop pitch search @@ -1717,14 +1790,17 @@ static void tc_enc_fx( IF( EQ_16( nBits, 9 ) ) { *T0 = pitch_fr4_fx( &exc_fx[i_subfr], xn_fx, h1_fx, *T0_min, *T0_max, T0_frac, 0, 0, PIT_FR2_9b, PIT_FR1_9b, L_FRAME, L_SUBFR ); + move16(); } ELSE IF( EQ_16( nBits, 6 ) ) { *T0 = pitch_fr4_fx( &exc_fx[i_subfr], xn_fx, h1_fx, *T0_min, *T0_max, T0_frac, 0, 0, PIT_MIN, L_SUBFR, L_FRAME, L_SUBFR ); + move16(); } ELSE { *T0 = pitch_fr4_fx( &exc_fx[i_subfr], xn_fx, h1_fx, *T0_min, *T0_max, T0_frac, 0, 0, PIT_MAX, PIT_MIN, L_FRAME, L_SUBFR ); + move16(); } } ELSE @@ -1744,11 +1820,13 @@ static void tc_enc_fx( IF( EQ_16( nBits, 10 ) ) { *T0 = pitch_fr4_fx( &exc_fx[i_subfr], xn_fx, h1_fx, *T0_min, *T0_max, T0_frac, 0, 1, PIT16k_FR2_EXTEND_10b, PIT16k_MAX, L_FRAME16k, L_SUBFR ); + move16(); } ELSE IF( EQ_16( nBits, 6 ) ) { /* T0_frac with 1/2 sample resolution */ *T0 = pitch_fr4_fx( &exc_fx[i_subfr], xn_fx, h1_fx, *T0_min, *T0_max, T0_frac, 0, 0, PIT16k_MIN, L_SUBFR, L_FRAME16k, L_SUBFR ); + move16(); IF( *T0 > L_SUBFR ) { *T0 = L_SUBFR; @@ -1809,11 +1887,8 @@ static void tc_enc_fx( conv_fx( &exc_fx[i_subfr], h1_fx, yy1_fx, L_SUBFR ); /* gain_pit computation */ -#ifdef BASOP_NOGLOB *gain_pit_fx = corr_xy1_fx( xn_fx, yy1_fx, g_corr_fx, L_SUBFR, 0, &Overflow ); -#else - *gain_pit_fx = corr_xy1_fx( xn_fx, yy1_fx, g_corr_fx, L_SUBFR, 0 ); -#endif + move16(); /*--------------------------------------------------------------* * Encode parameters and write indices *--------------------------------------------------------------*/ @@ -1885,7 +1960,7 @@ static void tc_enc_ivas_fx( const Word16 i_subfr, /* i : subrame index */ Word16 *tc_subfr, /* i/o: TC subframe index */ Word16 *position, /* i/o: index of the residual signal maximum */ - const Word16 *h1_fx, /* i : weighted filter input response Q(14+shift)*/ + const Word16 *h1, /* i : weighted filter input response Q(14+shift)*/ const Word16 *xn_fx, /* i : target signal Q_new-1+shift*/ Word16 *exc_fx, /* o : glottal codebook contribution Q_new*/ Word16 *yy1_fx, /* o : filtered glottal codebook contribution */ @@ -1899,24 +1974,23 @@ static void tc_enc_ivas_fx( Word16 Q_new /* i : input scaling */ ) { - Word16 i, imp_shape, imp_pos, index, nBits, h1_tmp_fx[L_SUBFR]; + + Word16 h1_fx[L_SUBFR + ( M + 1 )]; + Word16 imp_shape, imp_pos, index, nBits; Word16 pitch_index, pitch_sign_fx; Word32 gain_trans32; BSTR_ENC_HANDLE hBstr = st_fx->hBstr; #ifdef BASOP_NOGLOB_DECLARE_LOCAL Flag Overflow = 0; + move32(); #endif imp_pos = sub( *position, i_subfr ); - FOR( i = 0; i < L_SUBFR; i++ ) - { - h1_tmp_fx[i] = h1_fx[i]; - move16(); - } /*-----------------------------------------------------------------* * get number of bits for pitch encoding *-----------------------------------------------------------------*/ nBits = st_fx->acelp_cfg.pitch_bits[shr( i_subfr, 6 )]; + move16(); /*--------------------------------------------------------------* * Closed loop pitch search @@ -1932,15 +2006,18 @@ static void tc_enc_ivas_fx( { IF( EQ_16( nBits, 9 ) ) { - *T0 = pitch_fr4_fx( &exc_fx[i_subfr], xn_fx, h1_fx, *T0_min, *T0_max, T0_frac, 0, 0, PIT_FR2_9b, PIT_FR1_9b, L_FRAME, L_SUBFR ); + *T0 = pitch_fr4_fx( &exc_fx[i_subfr], xn_fx, h1, *T0_min, *T0_max, T0_frac, 0, 0, PIT_FR2_9b, PIT_FR1_9b, L_FRAME, L_SUBFR ); + move16(); } ELSE IF( EQ_16( nBits, 6 ) ) { - *T0 = pitch_fr4_fx( &exc_fx[i_subfr], xn_fx, h1_fx, *T0_min, *T0_max, T0_frac, 0, 0, PIT_MIN, L_SUBFR, L_FRAME, L_SUBFR ); + *T0 = pitch_fr4_fx( &exc_fx[i_subfr], xn_fx, h1, *T0_min, *T0_max, T0_frac, 0, 0, PIT_MIN, L_SUBFR, L_FRAME, L_SUBFR ); + move16(); } ELSE { - *T0 = pitch_fr4_fx( &exc_fx[i_subfr], xn_fx, h1_fx, *T0_min, *T0_max, T0_frac, 0, 0, PIT_MAX, PIT_MIN, L_FRAME, L_SUBFR ); + *T0 = pitch_fr4_fx( &exc_fx[i_subfr], xn_fx, h1, *T0_min, *T0_max, T0_frac, 0, 0, PIT_MAX, PIT_MIN, L_FRAME, L_SUBFR ); + move16(); } } ELSE @@ -1959,12 +2036,13 @@ static void tc_enc_ivas_fx( { IF( EQ_16( nBits, 10 ) ) { - *T0 = pitch_fr4_fx( &exc_fx[i_subfr], xn_fx, h1_fx, *T0_min, *T0_max, T0_frac, 0, 1, PIT16k_FR2_EXTEND_10b, PIT16k_MAX, L_FRAME16k, L_SUBFR ); + *T0 = pitch_fr4_fx( &exc_fx[i_subfr], xn_fx, h1, *T0_min, *T0_max, T0_frac, 0, 1, PIT16k_FR2_EXTEND_10b, PIT16k_MAX, L_FRAME16k, L_SUBFR ); + move16(); } ELSE IF( EQ_16( nBits, 6 ) ) { /* T0_frac with 1/2 sample resolution */ - *T0 = pitch_fr4_fx( &exc_fx[i_subfr], xn_fx, h1_fx, *T0_min, *T0_max, T0_frac, 0, 0, PIT16k_MIN, L_SUBFR, L_FRAME16k, L_SUBFR ); + *T0 = pitch_fr4_fx( &exc_fx[i_subfr], xn_fx, h1, *T0_min, *T0_max, T0_frac, 0, 0, PIT16k_MIN, L_SUBFR, L_FRAME16k, L_SUBFR ); IF( *T0 > L_SUBFR ) { *T0 = L_SUBFR; @@ -1990,7 +2068,7 @@ static void tc_enc_ivas_fx( * Builds glottal codebook contribution *--------------------------------------------------------------*/ - set_impulse_fx( xn_fx, h1_tmp_fx, &exc_fx[i_subfr], yy1_fx, &imp_shape, &imp_pos, &gain_trans32, Q_new ); /*chk h1_tmp_fx*/ + set_impulse_fx( xn_fx, h1, &exc_fx[i_subfr], yy1_fx, &imp_shape, &imp_pos, &gain_trans32, Q_new ); /*--------------------------------------------------------------* * quantize gain_trans and scale glottal codebook contribution @@ -2020,16 +2098,13 @@ static void tc_enc_ivas_fx( /*--------------------------------------------------------------* * compute glottal-shape codebook excitation *--------------------------------------------------------------*/ - + Copy_Scale_sig( h1, h1_fx, L_SUBFR + ( M + 1 ), 1 ); /* create filtered glottal codebook contribution */ conv_fx( &exc_fx[i_subfr], h1_fx, yy1_fx, L_SUBFR ); /* gain_pit computation */ -#ifdef BASOP_NOGLOB *gain_pit_fx = corr_xy1_fx( xn_fx, yy1_fx, g_corr_fx, L_SUBFR, 0, &Overflow ); -#else - *gain_pit_fx = corr_xy1_fx( xn_fx, yy1_fx, g_corr_fx, L_SUBFR, 0 ); -#endif + move16(); /*--------------------------------------------------------------* * Encode parameters and write indices *--------------------------------------------------------------*/ @@ -2115,6 +2190,7 @@ static void gain_trans_enc_fx( Word16 i, imax, istart, tmp16, gain_trans, gscale; #ifdef BASOP_NOGLOB_DECLARE_LOCAL Flag Overflow = 0; + move32(); #endif istart = 0; @@ -2123,19 +2199,11 @@ static void gain_trans_enc_fx( move16(); gscale = 7; move16(); -#ifdef BASOP_NOGLOB gain_trans = extract_h( L_shl_o( gain_trans32, 16, &Overflow ) ); /* Q7 */ -#else /* BASOP_NOGLOB */ - gain_trans = extract_h( L_shl( gain_trans32, 16 ) ); /* Q7 */ -#endif /* BASOP_NOGLOB */ IF( GT_32( L_abs( gain_trans32 ), 29862L ) ) { -#ifdef BASOP_NOGLOB gain_trans = extract_h( L_shl_o( gain_trans32, 16 - 3, &Overflow ) ); /* Q4 */ -#else /* BASOP_NOGLOB */ - gain_trans = extract_h( L_shl( gain_trans32, 16 - 3 ) ); /* Q4 */ -#endif /* BASOP_NOGLOB */ istart = 4; move16(); imax = N_GAIN_TC - 1; @@ -2168,11 +2236,8 @@ static void gain_trans_enc_fx( FOR( i = 0; i < L_SUBFR; i++ ) { /*exc[i] *= (*gain_trans);*/ -#ifdef BASOP_NOGLOB exc[i] = round_fx_o( L_shl_o( L_mult( exc[i], gain_trans ), tmp16, &Overflow ), &Overflow ); -#else - exc[i] = round_fx( L_shl( L_mult( exc[i], gain_trans ), tmp16 ) ); -#endif + move16(); } } @@ -2196,6 +2261,7 @@ void tc_classif_enc_fx( Word16 T_op, i; #ifdef BASOP_NOGLOB_DECLARE_LOCAL Flag Overflow = 0; + move32(); #endif T_op = pitch; @@ -2252,6 +2318,7 @@ void tc_classif_enc_fx( ELSE { *position = emaximum_fx( Q_new, res, add( T_op, 2 ), &temp ); + move16(); /* correction in case of possibly wrong T_op (double-pitch values) */ test(); @@ -2260,24 +2327,20 @@ void tc_classif_enc_fx( IF( ( EQ_16( L_frame, L_FRAME ) && GT_16( T_op, 2 * PIT_MIN ) ) || ( EQ_16( L_frame, L_FRAME16k ) && GT_16( T_op, 2 * PIT16k_MIN ) ) ) { Word16 position_tmp, len, exp_aver = 0, exp = 0, exp2 = 0; + move16(); + move16(); + move16(); Word32 aver, temp2, L_sum, L_temp1, L_temp2; len = add( shr( T_op, 1 ), 2 ); position_tmp = emaximum_fx( Q_new, res, len, &temp2 ); -#ifdef BASOP_NOGLOB L_sum = L_mac_sat( 1L, res[0], res[0] ); -#else - L_sum = L_mac( 1L, res[0], res[0] ); -#endif FOR( i = 1; i < len; i++ ) { -#ifdef BASOP_NOGLOB L_sum = L_mac0_o( L_sum, res[i], res[i], &Overflow ); -#else /* BASOP_NOGLOB */ - L_sum = L_mac0( L_sum, res[i], res[i] ); -#endif /* BASOP_NOGLOB */ } - aver = L_sum; /*Q = 2*Q_new */ + aver = L_sum; /*Q = 2*Q_new */ + move32(); aver = root_a_over_b_fx( aver, 2 * Q_new, L_shl( len, 15 ), 15, &exp_aver ); /*Q = 31-exp_aver*/ temp = root_a_fx( temp, 0, &exp ); /* Q=31-exp */ @@ -2287,15 +2350,11 @@ void tc_classif_enc_fx( L_temp1 = Mult_32_16( temp, 8192 ); /* Q=31-exp */ test(); -#ifdef BASOP_NOGLOB IF( GT_32( temp2, L_shl_o( L_temp2, ( 31 - exp2 ) - ( 31 - exp ), &Overflow ) ) && LT_32( aver, L_shl_o( L_temp1, ( 31 - exp_aver ) - ( 31 - exp ), &Overflow ) ) ) -#else /* BASOP_NOGLOB */ - IF( GT_32( temp2, L_shl( L_temp2, ( 31 - exp2 ) - ( 31 - exp ) ) ) && - LT_32( aver, L_shl( L_temp1, ( 31 - exp_aver ) - ( 31 - exp ) ) ) ) -#endif { *position = position_tmp; + move16(); } } *tc_subfr = s_and( *position, 0x7FC0 ); diff --git a/lib_enc/update_decision.c b/lib_enc/update_decision.c deleted file mode 100644 index 825401325748d89d4db5894372ff8dd2e53d76ec..0000000000000000000000000000000000000000 --- a/lib_enc/update_decision.c +++ /dev/null @@ -1,41 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include -#include "prot.h" -#include "wmc_auto.h" diff --git a/lib_enc/update_decision_fx.c b/lib_enc/update_decision_fx.c index 7fda8e5d2047fbc60d3bccab140d6b336b54c85c..315adcf819d9061691879a2b3c4c3f4752bdba94 100644 --- a/lib_enc/update_decision_fx.c +++ b/lib_enc/update_decision_fx.c @@ -253,7 +253,7 @@ Word16 update_decision_fx( hVAD_CLDFB->tonality_rate3 = mult( hVAD_CLDFB->tonality_rate3, 32211 ); move16(); - if ( tonality_flag ) + IF( tonality_flag ) { hVAD_CLDFB->tonality_rate3 = add( mult( hVAD_CLDFB->tonality_rate3, 32211 ), 557 ); move16(); @@ -274,8 +274,7 @@ Word16 update_decision_fx( test(); test(); - IF( ( GT_16( f_tonality_rate[1], 7536 /* 0.46 Q14 */ ) ) && ( ( GT_16( sSFM[1], 30473 /* 0.93 Q15 */ ) ) || ( GT_16( ltd_stable_rate[0], 2949 /* 0.09 Q15 */ ) ) ) ) - + if ( ( GT_16( f_tonality_rate[1], 7536 /* 0.46 Q14 */ ) ) && ( ( GT_16( sSFM[1], 30473 /* 0.93 Q15 */ ) ) || ( GT_16( ltd_stable_rate[0], 2949 /* 0.09 Q15 */ ) ) ) ) { update_flag = 0; move16(); @@ -284,7 +283,7 @@ Word16 update_decision_fx( test(); test(); test(); - IF( ( LT_16( sSFM[1], 30473 /* 0.93 Q15 */ ) && LT_16( sSFM[0], 30146 /* 0.92 Q15 */ ) && LT_16( sSFM[2], 31784 /* 0.97 Q15 */ ) ) && ( GT_16( f_tonality_rate[1], 8192 /* 0.5 Q14 */ ) ) ) + if ( ( LT_16( sSFM[1], 30473 /* 0.93 Q15 */ ) && LT_16( sSFM[0], 30146 /* 0.92 Q15 */ ) && LT_16( sSFM[2], 31784 /* 0.97 Q15 */ ) ) && ( GT_16( f_tonality_rate[1], 8192 /* 0.5 Q14 */ ) ) ) { update_flag = 0; move16(); @@ -292,7 +291,7 @@ Word16 update_decision_fx( test(); test(); - IF( ( f_tonality_rate[1] > 7045 /* 0.43 Q14 */ ) && ( sSFM[0] < 31129 /* 0.95 Q15 */ ) && ( sp_center[1] > 1985 /* 1.94 Q10 */ ) ) + if ( ( f_tonality_rate[1] > 7045 /* 0.43 Q14 */ ) && ( sSFM[0] < 31129 /* 0.95 Q15 */ ) && ( sp_center[1] > 1985 /* 1.94 Q10 */ ) ) { update_flag = 0; move16(); @@ -300,9 +299,10 @@ Word16 update_decision_fx( IF( EQ_16( update_flag, 1 ) ) { - if ( LT_16( hVAD_CLDFB->update_count, 1000 ) ) + IF( LT_16( hVAD_CLDFB->update_count, 1000 ) ) { hVAD_CLDFB->update_count = add( hVAD_CLDFB->update_count, 1 ); + move16(); } } @@ -342,23 +342,26 @@ Word16 update_decision_fx( test(); test(); test(); - IF( vad_flag && GT_32( snr, 33554431 /* 1.0 Q25 */ ) && EQ_16( bw, CLDFBVAD_SWB_ID ) && tmpout > 0 ) + if ( vad_flag && GT_32( snr, 33554431 /* 1.0 Q25 */ ) && EQ_16( bw, CLDFBVAD_SWB_ID ) && tmpout > 0 ) { update_flag = 0; + move16(); } test(); test(); test(); - IF( vad_flag && GT_32( snr, 50331647 /* 1.5 Q25 */ ) && NE_16( bw, CLDFBVAD_SWB_ID ) && tmpout > 0 ) + if ( vad_flag && GT_32( snr, 50331647 /* 1.5 Q25 */ ) && NE_16( bw, CLDFBVAD_SWB_ID ) && tmpout > 0 ) { update_flag = 0; + move16(); } IF( update_flag == 0 ) { hVAD_CLDFB->update_num_with_snr = 0; + move16(); } ELSE { @@ -369,6 +372,7 @@ Word16 update_decision_fx( update_flag = 0; move16(); hVAD_CLDFB->update_num_with_snr = add( hVAD_CLDFB->update_num_with_snr, 1 ); + move16(); } } @@ -397,8 +401,6 @@ Word16 update_decision_fx( move32(); } - move16(); - move16(); IF( GT_16( (Word16) abs_s( sub( hVAD_CLDFB->sp_center[0], hVAD_CLDFB->lt_noise_sp_center0 ) ), 2455 /* 2.4 Q10 */ ) ) { hVAD_CLDFB->lt_noise_sp_center0 = add( mult( hVAD_CLDFB->lt_noise_sp_center0, 32637 ), mult( hVAD_CLDFB->sp_center[0], 131 ) ); diff --git a/lib_enc/updt_enc.c b/lib_enc/updt_enc.c deleted file mode 100644 index cb36dd4b04c94cce04cb194654b8bf337ab9c5cd..0000000000000000000000000000000000000000 --- a/lib_enc/updt_enc.c +++ /dev/null @@ -1,274 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include "cnst.h" -#include "rom_com.h" -#include "prot.h" -#include "prot_fx.h" -#include "prot_fx_enc.h" -#include "ivas_prot_fx.h" -#include "wmc_auto.h" - -/*-------------------------------------------------------------------* - * updt_enc() - * - * Common updates (all frame types) - *-------------------------------------------------------------------*/ - - -void updt_enc_common_ivas_fx( - Encoder_State *st, /* i/o: encoder state structure */ - const Word16 Q_new /* i : CUrrent frame scaling */ -) -{ - /*---------------------------------------------------------------------* - * Updates - main main codec parameters - *---------------------------------------------------------------------*/ - st->last_sr_core = st->sr_core; - move32(); - st->last_codec_mode = st->codec_mode; - move16(); - st->last_L_frame = st->L_frame; - move16(); - st->last_core = st->core; - move16(); - - st->last_total_brate = st->total_brate; - move32(); - st->last_bits_frame_nominal = st->bits_frame_nominal; - move16(); - st->last_core_brate = st->core_brate; - move32(); - st->last_extl = st->extl; - move16(); - st->last_input_bwidth = st->input_bwidth; - move16(); - st->last_bwidth = st->bwidth; - move16(); - st->last_coder_type_raw = st->coder_type_raw; - move16(); - st->prev_Q_new = Q_new; - move16(); - - test(); - IF( GT_32( st->core_brate, SID_2k40 ) && st->hDtxEnc != NULL ) - { - st->hDtxEnc->last_active_brate = st->total_brate; - move32(); - } - - IF( st->hBWE_TD != NULL ) - { - IF( EQ_16( st->core, HQ_CORE ) ) - { - /* in the HQ core, coder_type is not used so it could have been set to anything */ - st->hBWE_TD->prev_coder_type = GENERIC; - move16(); - } - ELSE - { - st->hBWE_TD->prev_coder_type = st->coder_type; - move16(); - } - } - - test(); - IF( st->Opt_DTX_ON && st->hTdCngEnc != NULL ) - { - IF( GT_32( st->core_brate, SID_2k40 ) ) - { - IF( EQ_16( st->hDtxEnc->first_CNG, 1 ) ) - { - IF( GE_16( st->hTdCngEnc->act_cnt, BUF_DEC_RATE ) ) - { - st->hTdCngEnc->act_cnt = 0; - move16(); - } - st->hTdCngEnc->act_cnt = add( st->hTdCngEnc->act_cnt, 1 ); - move16(); - - test(); - IF( EQ_16( st->hTdCngEnc->act_cnt, BUF_DEC_RATE ) && st->hTdCngEnc->ho_hist_size > 0 ) - { - st->hTdCngEnc->ho_hist_size = sub( st->hTdCngEnc->ho_hist_size, 1 ); - move16(); - } - } - - test(); - test(); - test(); - IF( EQ_16( st->element_mode, IVAS_SCE ) || EQ_16( st->element_mode, IVAS_CPE_DFT ) || EQ_16( st->element_mode, IVAS_CPE_TD ) || EQ_16( st->hDtxEnc->first_CNG, 1 ) ) - { - IF( GE_16( ++( st->hTdCngEnc->act_cnt2 ), MIN_ACT_CNG_UPD ) ) - { - st->hTdCngEnc->act_cnt2 = MIN_ACT_CNG_UPD; - move16(); - } - - test(); - test(); - test(); - test(); - IF( ( EQ_16( st->element_mode, IVAS_SCE ) || EQ_16( st->element_mode, IVAS_CPE_DFT ) || EQ_16( st->element_mode, IVAS_CPE_TD ) ) && GE_16( st->hTdCngEnc->act_cnt2, MIN_ACT_CNG_UPD ) ) - { - Word32 cng_att_fx32 = 0; - - apply_scale( &cng_att_fx32, st->hFdCngEnc->hFdCngCom->CngBandwidth, st->hFdCngEnc->hFdCngCom->CngBitrate, scaleTableStereo, SIZE_SCALE_TABLE_STEREO ); - - st->hTdCngEnc->CNG_att_fx = extract_l( L_shr( cng_att_fx32, Q16 ) ); // Q23 - } - } - } - - test(); - test(); - test(); - IF( ( EQ_32( st->core_brate, SID_2k40 ) || EQ_32( st->core_brate, FRAME_NO_DATA ) ) && st->hDtxEnc->first_CNG == 0 && EQ_16( st->cng_type, LP_CNG ) ) - { - st->hDtxEnc->first_CNG = 1; - move16(); - } - } - - /*-----------------------------------------------------------------* - * Increase the counter of initialization frames - * Limit the max number of init. frames - *-----------------------------------------------------------------*/ - - IF( LT_16( st->ini_frame, MAX_FRAME_COUNTER ) ) - { - st->ini_frame = add( st->ini_frame, 1 ); - } - - /* synchronisation of CNG seeds */ - test(); - test(); - IF( st->hTdCngEnc != NULL && NE_32( st->core_brate, FRAME_NO_DATA ) && NE_32( st->core_brate, SID_2k40 ) && NE_16( st->core, AMR_WB_CORE ) ) - { - Random( &( st->hTdCngEnc->cng_seed ) ); - Random( &( st->hTdCngEnc->cng_ener_seed ) ); - } - - /*---------------------------------------------------------------------* - * Updates - MODE2 - *---------------------------------------------------------------------*/ - - test(); - IF( EQ_16( st->element_mode, EVS_MONO ) && EQ_16( st->mdct_sw, MODE2 ) ) - { - st->codec_mode = MODE2; - move16(); - - st->sr_core = getCoreSamplerateMode2( EVS_MONO, st->total_brate, st->bwidth, st->flag_ACELP16k, st->rf_mode, 0 ); - move16(); - - Word16 exp; - st->L_frame = BASOP_Util_Divide3232_Scale( st->sr_core, FRAMES_PER_SEC, &exp ); - st->L_frame = shr( st->L_frame, sub( 15, exp ) ); - move16(); - - IF( EQ_32( st->sr_core, INT_FS_12k8 ) ) - { - st->preemph_fac = PREEMPH_FAC; - st->gamma = GAMMA1; - } - ELSE - { - - st->preemph_fac = PREEMPH_FAC_16k; - st->gamma = GAMMA16k; - } - - st->igf = getIgfPresent_fx( EVS_MONO, st->total_brate, st->bwidth, st->rf_mode ); - } - - /* update FER clas */ - IF( NE_16( st->core, AMR_WB_CORE ) ) - { - st->last_clas = st->clas; - move16(); - } - - /* Update Core */ - core_encode_update_ivas_fx( st ); - - /*---------------------------------------------------------------------* - * RF mode updates - *---------------------------------------------------------------------*/ - - IF( st->rf_mode ) - { - IF( st->hSC_VBR != NULL ) - { - IF( st->hRF->rf_frame_type == RF_NELP ) - { - st->hSC_VBR->last_nelp_mode = 1; - move16(); - } - ELSE - { - st->hSC_VBR->last_nelp_mode = 0; - move16(); - } - } - } - - st->rf_mode_last = st->rf_mode; - move16(); - - IF( st->Opt_RF_ON ) - { - st->L_frame = L_FRAME; - st->rf_mode = 1; - move16(); - move16(); - } - - /*---------------------------------------------------------------------* - * Other updates - *---------------------------------------------------------------------*/ - - test(); - IF( st->element_mode > EVS_MONO && st->hTcxEnc != NULL ) - { - st->hTcxEnc->tcxltp_norm_corr_mem = st->hTcxEnc->tcxltp_norm_corr_past; - } - - return; -} diff --git a/lib_enc/updt_enc_fx.c b/lib_enc/updt_enc_fx.c index 6a3202a1595650cd87d2d6cc049bafe6db557b4e..fb2a6215b4509732b14ab9dcada955c97c4b8e3d 100644 --- a/lib_enc/updt_enc_fx.c +++ b/lib_enc/updt_enc_fx.c @@ -10,6 +10,7 @@ #include "prot_fx.h" /* Function prototypes */ #include "prot_fx_enc.h" /* Function prototypes */ #include "basop_util.h" /* Function prototypes */ +#include "ivas_prot_fx.h" /*-------------------------------------------------------------------* * updt_enc() @@ -37,6 +38,7 @@ void updt_enc_fx( /* update old excitation buffer */ Copy( &old_exc[st->L_frame], hLPDmem->old_exc, L_EXC_MEM ); test(); + test(); IF( !st->Opt_AMR_WB && st->hBWE_TD != NULL ) { Copy( &old_bwe_exc[L_FRAME32k], hBWE_TD->old_bwe_exc_fx, PIT16k_MAX * 2 ); @@ -89,6 +91,7 @@ void updt_enc_fx( move16(); /* tends to speech */ /*st->mid_dyn_fx = 40.0f * 0.5f + st->mid_dyn * 0.5f;*/ hGSCEnc->mid_dyn_fx = add( 20 * 128, mult_r( hGSCEnc->mid_dyn_fx, 16384 ) ); /*Q7*/ + move16(); } /* convert old LSP vector from 12kHz domain to 16kHz domain (needed in case of ACELP@12k8 <-> ACELP@16kHz switching) */ @@ -96,6 +99,7 @@ void updt_enc_fx( { Copy( st->lsp_old_fx, st->lsp_old16k_fx, M ); st->rate_switching_reset_16kHz = lsp_convert_poly_fx( st->lsp_old16k_fx, L_FRAME16k, st->Opt_AMR_WB ); + move16(); } /* update buffer of old subframe pitch values */ @@ -139,6 +143,7 @@ void updt_enc_fx( /* core switching updates */ Copy( &Aq[( st->L_frame / L_SUBFR - 1 ) * ( M + 1 )], st->old_Aq_12_8_fx, M + 1 ); st->old_Es_pred_fx = Es_pred; + move16(); return; } @@ -167,6 +172,7 @@ void updt_IO_switch_enc_fx( { /* reset onset detection counter */ st->tc_cnt = -1; + move16(); /* force safety-net LSFQ in the first frames after the switching */ st->Nb_ACELP_frames = 0; @@ -186,6 +192,7 @@ void updt_IO_switch_enc_fx( { /* old index is initialized to -1, and may only be updated after it has been calculated properly at least once once */ hTdCngEnc->old_enr_index = s_min( mult( shl( hTdCngEnc->old_enr_index, 1 ), 32459 ), 127 ); /*32459 = 2/(STEP_SID/STEP_AMR_WB_SID)*/ + move16(); } /* Perform preemphasis of the old input signal @16kHz */ st->mem_preemph16k_fx = 0; @@ -325,7 +332,7 @@ void updt_IO_switch_enc_fx( * * Common updates for MODE1 and MODE2 *-------------------------------------------------------------------*/ -#if 1 + void updt_enc_common_fx( Encoder_State *st, /* i/o: encoder state structure */ const Word16 Etot, /* i : total energy */ @@ -336,27 +343,24 @@ void updt_enc_common_fx( * Updates - main main codec parameters *---------------------------------------------------------------------*/ - st->last_sr_core = st->sr_core; //## + st->last_sr_core = st->sr_core; move32(); st->last_codec_mode = st->codec_mode; move16(); - st->last_L_frame = st->L_frame; // + st->last_L_frame = st->L_frame; move16(); st->last_core = st->core; move16(); st->last_core_brate = st->core_brate; move32(); -#ifdef IVAS_CODE - st->last_bits_frame_nominal_fx = st->bits_frame_nominal; -#endif st->last_total_brate = st->total_brate; move32(); - st->last_extl = st->extl; // + st->last_extl = st->extl; move16(); - st->last_input_bwidth = st->input_bwidth; //## + st->last_input_bwidth = st->input_bwidth; move16(); - st->last_bwidth = st->bwidth; //## + st->last_bwidth = st->bwidth; move16(); st->hNoiseEst->Etot_last_fx = Etot; move16(); @@ -367,7 +371,7 @@ void updt_enc_common_fx( move16(); test(); - if ( GT_32( st->core_brate, SID_2k40 ) && st->hDtxEnc != NULL ) + IF( GT_32( st->core_brate, SID_2k40 ) && st->hDtxEnc != NULL ) { st->hDtxEnc->last_active_brate = st->total_brate; move32(); @@ -377,7 +381,7 @@ void updt_enc_common_fx( { st->hBWE_TD->prev_coder_type = st->coder_type; move16(); - if ( EQ_16( st->core, HQ_CORE ) ) + IF( EQ_16( st->core, HQ_CORE ) ) { /* in the HQ core, coder_type is not used so it could have been set to anything */ st->hBWE_TD->prev_coder_type = GENERIC; @@ -392,17 +396,19 @@ void updt_enc_common_fx( { IF( EQ_16( st->hDtxEnc->first_CNG, 1 ) ) { - if ( GE_16( st->hTdCngEnc->act_cnt, BUF_DEC_RATE ) ) + IF( GE_16( st->hTdCngEnc->act_cnt, BUF_DEC_RATE ) ) { st->hTdCngEnc->act_cnt = 0; move16(); } st->hTdCngEnc->act_cnt = add( st->hTdCngEnc->act_cnt, 1 ); + move16(); test(); - if ( EQ_16( st->hTdCngEnc->act_cnt, BUF_DEC_RATE ) && st->hTdCngEnc->ho_hist_size > 0 ) + IF( EQ_16( st->hTdCngEnc->act_cnt, BUF_DEC_RATE ) && st->hTdCngEnc->ho_hist_size > 0 ) { st->hTdCngEnc->ho_hist_size = sub( st->hTdCngEnc->ho_hist_size, 1 ); + move16(); } } @@ -413,26 +419,22 @@ void updt_enc_common_fx( { st->hTdCngEnc->act_cnt2 = add( st->hTdCngEnc->act_cnt2, 1 ); st->hTdCngEnc->act_cnt2 = s_min( st->hTdCngEnc->act_cnt2, MIN_ACT_CNG_UPD ); + move16(); + move16(); -#ifdef IVAS_CODE test(); test(); test(); IF( ( EQ_16( st->element_mode, IVAS_SCE ) || EQ_16( st->element_mode, IVAS_CPE_DFT ) || EQ_16( st->element_mode, IVAS_CPE_TD ) ) && GE_16( st->hTdCngEnc->act_cnt2, MIN_ACT_CNG_UPD ) ) { - st->hTdCngEnc->CNG_att_fx = 0; - move16(); - - apply_scale( &st->hTdCngEnc->CNG_att, st->hFdCngEnc->hFdCngCom->CngBandwidth, st->hFdCngEnc->hFdCngCom->CngBitrate, scaleTableStereo, SIZE_SCALE_TABLE_STEREO ); } -#endif } } test(); test(); test(); - if ( ( EQ_32( st->core_brate, SID_2k40 ) || EQ_32( st->core_brate, FRAME_NO_DATA ) ) && st->hDtxEnc->first_CNG == 0 && EQ_16( st->cng_type, LP_CNG ) ) + IF( ( EQ_32( st->core_brate, SID_2k40 ) || EQ_32( st->core_brate, FRAME_NO_DATA ) ) && st->hDtxEnc->first_CNG == 0 && EQ_16( st->cng_type, LP_CNG ) ) { st->hDtxEnc->first_CNG = 1; move16(); @@ -447,6 +449,7 @@ void updt_enc_common_fx( if ( LT_16( st->ini_frame, MAX_FRAME_COUNTER ) ) { st->ini_frame = add( st->ini_frame, 1 ); + move16(); } /* synchronisation of CNG seeds */ @@ -469,6 +472,7 @@ void updt_enc_common_fx( move16(); st->sr_core = getCoreSamplerateMode2( EVS_MONO, st->total_brate, st->bwidth, st->flag_ACELP16k, st->rf_mode, 0 ); + move32(); // st->L_frame = extract_l(Mult_32_16(st->sr_core, 0x0290)); /*(int16_t)(st->sr_core / FRAMES_PER_SEC);*/ @@ -492,10 +496,11 @@ void updt_enc_common_fx( } st->igf = getIgfPresent_fx( EVS_MONO, st->total_brate, st->bwidth, st->rf_mode ); + move16(); } /* update FER clas */ - if ( NE_16( st->core, AMR_WB_CORE ) ) + IF( NE_16( st->core, AMR_WB_CORE ) ) { st->last_clas = st->clas; move16(); @@ -514,7 +519,7 @@ void updt_enc_common_fx( { st->hSC_VBR->last_nelp_mode = 0; move16(); - if ( EQ_16( st->hRF->rf_frame_type, RF_NELP ) ) + IF( EQ_16( st->hRF->rf_frame_type, RF_NELP ) ) { st->hSC_VBR->last_nelp_mode = 1; move16(); @@ -536,14 +541,240 @@ void updt_enc_common_fx( /*---------------------------------------------------------------------* * Other updates *---------------------------------------------------------------------*/ -#ifdef IVAS_CODE + test(); - if ( GT_16( st->element_mode, EVS_MONO ) && st->hTcxEnc != NULL ) + IF( GT_16( st->element_mode, EVS_MONO ) && st->hTcxEnc != NULL ) + { + } + return; +} + + +void updt_enc_common_ivas_fx( + Encoder_State *st, /* i/o: encoder state structure */ + const Word16 Q_new /* i : CUrrent frame scaling */ +) +{ + /*---------------------------------------------------------------------* + * Updates - main main codec parameters + *---------------------------------------------------------------------*/ + st->last_sr_core = st->sr_core; + move32(); + st->last_codec_mode = st->codec_mode; + move16(); + st->last_L_frame = st->L_frame; + move16(); + st->last_core = st->core; + move16(); + + st->last_total_brate = st->total_brate; + move32(); + st->last_bits_frame_nominal = st->bits_frame_nominal; + move16(); + st->last_core_brate = st->core_brate; + move32(); + st->last_extl = st->extl; + move16(); + st->last_input_bwidth = st->input_bwidth; + move16(); + st->last_bwidth = st->bwidth; + move16(); + st->last_coder_type_raw = st->coder_type_raw; + move16(); + st->prev_Q_new = Q_new; + move16(); + + test(); + if ( GT_32( st->core_brate, SID_2k40 ) && st->hDtxEnc != NULL ) + { + st->hDtxEnc->last_active_brate = st->total_brate; + move32(); + } + + IF( st->hBWE_TD != NULL ) + { + IF( EQ_16( st->core, HQ_CORE ) ) + { + /* in the HQ core, coder_type is not used so it could have been set to anything */ + st->hBWE_TD->prev_coder_type = GENERIC; + move16(); + } + ELSE + { + st->hBWE_TD->prev_coder_type = st->coder_type; + move16(); + } + } + + test(); + IF( st->Opt_DTX_ON && st->hTdCngEnc != NULL ) + { + IF( GT_32( st->core_brate, SID_2k40 ) ) + { + IF( EQ_16( st->hDtxEnc->first_CNG, 1 ) ) + { + if ( GE_16( st->hTdCngEnc->act_cnt, BUF_DEC_RATE ) ) + { + st->hTdCngEnc->act_cnt = 0; + move16(); + } + st->hTdCngEnc->act_cnt = add( st->hTdCngEnc->act_cnt, 1 ); + move16(); + + test(); + IF( EQ_16( st->hTdCngEnc->act_cnt, BUF_DEC_RATE ) && st->hTdCngEnc->ho_hist_size > 0 ) + { + st->hTdCngEnc->ho_hist_size = sub( st->hTdCngEnc->ho_hist_size, 1 ); + move16(); + } + } + + test(); + test(); + test(); + IF( EQ_16( st->element_mode, IVAS_SCE ) || EQ_16( st->element_mode, IVAS_CPE_DFT ) || EQ_16( st->element_mode, IVAS_CPE_TD ) || EQ_16( st->hDtxEnc->first_CNG, 1 ) ) + { + if ( GE_16( ++( st->hTdCngEnc->act_cnt2 ), MIN_ACT_CNG_UPD ) ) + { + st->hTdCngEnc->act_cnt2 = MIN_ACT_CNG_UPD; + move16(); + } + + test(); + test(); + test(); + IF( ( EQ_16( st->element_mode, IVAS_SCE ) || EQ_16( st->element_mode, IVAS_CPE_DFT ) || EQ_16( st->element_mode, IVAS_CPE_TD ) ) && GE_16( st->hTdCngEnc->act_cnt2, MIN_ACT_CNG_UPD ) ) + { + Word32 cng_att_fx32 = 0; + move32(); + + apply_scale( &cng_att_fx32, st->hFdCngEnc->hFdCngCom->CngBandwidth, st->hFdCngEnc->hFdCngCom->CngBitrate, scaleTableStereo, SIZE_SCALE_TABLE_STEREO ); + + st->hTdCngEnc->CNG_att_fx = extract_l( L_shr( cng_att_fx32, Q16 ) ); // Q23 + move16(); + } + } + } + + test(); + test(); + test(); + if ( ( EQ_32( st->core_brate, SID_2k40 ) || EQ_32( st->core_brate, FRAME_NO_DATA ) ) && st->hDtxEnc->first_CNG == 0 && EQ_16( st->cng_type, LP_CNG ) ) + { + st->hDtxEnc->first_CNG = 1; + move16(); + } + } + + /*-----------------------------------------------------------------* + * Increase the counter of initialization frames + * Limit the max number of init. frames + *-----------------------------------------------------------------*/ + + IF( LT_16( st->ini_frame, MAX_FRAME_COUNTER ) ) + { + st->ini_frame = add( st->ini_frame, 1 ); + } + + /* synchronisation of CNG seeds */ + test(); + test(); + test(); + IF( st->hTdCngEnc != NULL && ( st->core_brate != FRAME_NO_DATA ) && NE_32( st->core_brate, SID_2k40 ) && NE_16( st->core, AMR_WB_CORE ) ) + { + Random( &( st->hTdCngEnc->cng_seed ) ); + Random( &( st->hTdCngEnc->cng_ener_seed ) ); + } + + /*---------------------------------------------------------------------* + * Updates - MODE2 + *---------------------------------------------------------------------*/ + + test(); + IF( ( st->element_mode == EVS_MONO ) && EQ_16( st->mdct_sw, MODE2 ) ) + { + st->codec_mode = MODE2; + move16(); + + st->sr_core = getCoreSamplerateMode2( EVS_MONO, st->total_brate, st->bwidth, st->flag_ACELP16k, st->rf_mode, 0 ); + move16(); + + Word16 exp; + st->L_frame = BASOP_Util_Divide3232_Scale( st->sr_core, FRAMES_PER_SEC, &exp ); + move16(); + st->L_frame = shr( st->L_frame, sub( 15, exp ) ); + move16(); + + IF( EQ_32( st->sr_core, INT_FS_12k8 ) ) + { + st->preemph_fac = PREEMPH_FAC; + st->gamma = GAMMA1; + } + ELSE + { + + st->preemph_fac = PREEMPH_FAC_16k; + st->gamma = GAMMA16k; + } + move16(); + move16(); + + st->igf = getIgfPresent_fx( EVS_MONO, st->total_brate, st->bwidth, st->rf_mode ); + move16(); + } + + /* update FER clas */ + if ( NE_16( st->core, AMR_WB_CORE ) ) + { + st->last_clas = st->clas; + move16(); + } + + /* Update Core */ + core_encode_update_ivas_fx( st ); + + /*---------------------------------------------------------------------* + * RF mode updates + *---------------------------------------------------------------------*/ + + IF( st->rf_mode ) + { + IF( st->hSC_VBR != NULL ) + { + IF( EQ_16( st->hRF->rf_frame_type, RF_NELP ) ) + { + st->hSC_VBR->last_nelp_mode = 1; + move16(); + } + ELSE + { + st->hSC_VBR->last_nelp_mode = 0; + move16(); + } + } + } + + st->rf_mode_last = st->rf_mode; + move16(); + + IF( st->Opt_RF_ON ) + { + st->L_frame = L_FRAME; + st->rf_mode = 1; + move16(); + move16(); + } + + /*---------------------------------------------------------------------* + * Other updates + *---------------------------------------------------------------------*/ + + test(); + if ( st->element_mode > EVS_MONO && st->hTcxEnc != NULL ) { st->hTcxEnc->tcxltp_norm_corr_mem = st->hTcxEnc->tcxltp_norm_corr_past; move16(); } -#endif + return; } -#endif diff --git a/lib_enc/updt_tar.c b/lib_enc/updt_tar.c deleted file mode 100644 index e748899a9667996f0776eb65127752b66796a660..0000000000000000000000000000000000000000 --- a/lib_enc/updt_tar.c +++ /dev/null @@ -1,40 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include "prot.h" -#include "wmc_auto.h" diff --git a/lib_enc/updt_tar_fx.c b/lib_enc/updt_tar_fx.c index d62daff20038c9207323d924910626d50d587404..9d6b5d2d6751c852216a6801f7aa9d4af97801d2 100644 --- a/lib_enc/updt_tar_fx.c +++ b/lib_enc/updt_tar_fx.c @@ -14,10 +14,10 @@ * Update the target vector for codebook search. *----------------------------------------------------------------------------------*/ void updt_tar_fx( - const Word16 *x, /* i : old target (for pitch search) */ - Word16 *x2, /* o : new target (for codebook search) */ - const Word16 *y, /* i : filtered adaptive codebook vector */ - const Word16 gain, /* i : adaptive codebook gain */ + const Word16 *x, /* i : old target (for pitch search) Qz */ + Word16 *x2, /* o : new target (for codebook search) Qz */ + const Word16 *y, /* i : filtered adaptive codebook vector Qz */ + const Word16 gain, /* i : adaptive codebook gain Q14 */ const Word16 L /* i : subframe size */ ) { @@ -25,20 +25,17 @@ void updt_tar_fx( Word32 L_tmp; #ifdef BASOP_NOGLOB_DECLARE_LOCAL Flag Overflow = 0; + move32(); #endif FOR( i = 0; i < L; i++ ) { /*x2[i] = x[i] - gain*y[i];*/ - L_tmp = L_mult( x[i], 16384 ); -#ifdef BASOP_NOGLOB + L_tmp = L_mult( x[i], 16384 ); /* (Qz*Q14) -> (Qz+15) */ L_tmp = L_msu_sat( L_tmp, y[i], gain ); x2[i] = extract_h( L_shl_o( L_tmp, 1, &Overflow ) ); -#else /* BASOP_NOGLOB */ - L_tmp = L_msu( L_tmp, y[i], gain ); - x2[i] = extract_h( L_shl( L_tmp, 1 ) ); -#endif + move16(); } return; } @@ -48,9 +45,9 @@ void updt_tar_fx( * Update the target vector for codebook search. *----------------------------------------------------------------------------------*/ void updt_tar_HR_fx( - const Word16 *x, /* i : old target (for pitch search) */ - Word16 *x2, /* o : new target (for codebook search) */ - const Word16 *y, /* i : filtered adaptive codebook vector */ + const Word16 *x, /* i : old target (for pitch search) Qz */ + Word16 *x2, /* o : new target (for codebook search) Qz */ + const Word16 *y, /* i : filtered adaptive codebook vector Qz */ const Word16 gain, /* i : adaptive codebook gain Q2 */ const Word16 Qx, /* i : Scaling factor to adapt output to input */ const Word16 L /* i : subframe size */ @@ -60,20 +57,17 @@ void updt_tar_HR_fx( Word32 L_tmp, L_tmp1; #ifdef BASOP_NOGLOB_DECLARE_LOCAL Flag Overflow = 0; + move32(); #endif FOR( i = 0; i < L; i++ ) { /*x2[i] = x[i] - gain*y[i];*/ - L_tmp = L_mult( x[i], 32767 ); -#ifdef BASOP_NOGLOB - L_tmp1 = L_shl_o( L_mult_o( y[i], gain, &Overflow ), Qx, &Overflow ); + L_tmp = L_mult( x[i], 32767 ); /* (Qz*Q15) = (Qz+16) */ + L_tmp1 = L_shl_o( L_mult_o( y[i], gain, &Overflow ), Qx, &Overflow ); /* ((Qz+2+1)< -#include "options.h" -#include -#include "cnst.h" -#include "prot.h" -#include "rom_enc.h" -#include "wmc_auto.h" -#include "ivas_prot.h" - -/*-----------------------------------------------------------------* - * Local constants - *-----------------------------------------------------------------*/ - -#define HANGOVER_LONG 10 /* Hangover for CNG */ -#define HANGOVER_LONG_HE 20 /* Hangover of CNG */ -#define HANGOVER_LONG_MUSIC 20 /* Hangover of CNG */ -#define HANGOVER_LONG_NB 8 /* Hangover for CNG */ -#define ACTIVE_FRAMES 3 /* Number of consecutive active SPEECH frames necessary to trigger HO */ - -#define TH16_2 35.0f /* long-term SNR that separates the curves for clean speech and noisy speech */ -#define TH8_1 20.0f /* long-term SNR that separates the curves for clean speech and noisy speech */ -#define TH16_2_NFLAG 35.0f -#define TH8_1_NFLAG 35.0f - - -#define SNR_OUTLIER_WGHT_1 1.00f -#define SNR_OUTLIER_WGHT_2 1.01f -#define SNR_OUTLIER_WGHT_3 1.02f -#define OUTLIER_THR_1 10.0f -#define OUTLIER_THR_2 6.0f -#define MAX_SNR_OUTLIER_IND 17 -#define MAX_SNR_OUTLIER_1 10.0f -#define MAX_SNR_OUTLIER_2 25.0f -#define MAX_SNR_OUTLIER_3 50.0f - -/*---------------------------------------------------------------------* - * wb_vad_init() - * - * VAD initializations - *---------------------------------------------------------------------*/ -/*-----------------------------------------------------------------* - * sing_thr_snr_acc() - * - * accumulate snr_sum with significance thresholds - *-----------------------------------------------------------------*/ -/*-----------------------------------------------------------------* - * dtx_hangover_addition() - * - * accumulate snr_sum with significance thresholds - *-----------------------------------------------------------------*/ - -/*-----------------------------------------------------------------* - * wb_vad() - * - * Voice Activity Detector - *-----------------------------------------------------------------*/ diff --git a/lib_enc/vad_basop_fx.c b/lib_enc/vad_basop_fx.c index f8f528c0e512c75cb9568d47512aae54374ed686..d6d0783105621e70b314ab8a971be27bd4d60434 100644 --- a/lib_enc/vad_basop_fx.c +++ b/lib_enc/vad_basop_fx.c @@ -114,11 +114,7 @@ Word16 FixSqrt( Word32 i_s32Val, Word16 *io_s16Q ) Word16 result, exp; exp = sub( 31, *io_s16Q ); -#ifdef BASOP_NOGLOB result = round_fx_sat( Sqrt32( i_s32Val, &exp ) ); -#else - result = round_fx( Sqrt32( i_s32Val, &exp ) ); -#endif move16(); *io_s16Q = sub( 15, exp ); diff --git a/lib_enc/vad_fx.c b/lib_enc/vad_fx.c index 21bf1608745ddaddd816c9de7981645131e4c991..1fdcb94fac335e5852dc782acc3a47dd2c9705c3 100644 --- a/lib_enc/vad_fx.c +++ b/lib_enc/vad_fx.c @@ -102,8 +102,11 @@ void wb_vad_init_fx( /* is set to max (-> start with hangover) */ hVAD->vad_flag_reg_H = L_deposit_l( 0 ); + move32(); hVAD->vad_flag_reg_L = L_deposit_l( 0 ); + move32(); hVAD->vad_prim_reg = L_deposit_l( 0 ); + move32(); hVAD->vad_flag_cnt_50 = 0; move16(); hVAD->vad_prim_cnt_16 = 0; @@ -221,19 +224,17 @@ static void sign_thr_snr_acc_fx( Word32 L_tmp; #ifdef BASOP_NOGLOB_DECLARE_LOCAL Flag Overflow = 0; + move32(); #endif L_tmp = L_deposit_l( min_snr ); - if ( GE_32( L_snr, L_deposit_l( sign_thr ) ) ) + IF( GE_32( L_snr, L_deposit_l( sign_thr ) ) ) { - L_tmp = L_add( L_snr, 0 ); + L_tmp = L_add( L_snr, 0 ); /* Q4 */ } - BASOP_SATURATE_WARNING_OFF_EVS /* may saturate in BASOP */ -#ifdef BASOP_NOGLOB + BASOP_SATURATE_WARNING_OFF_EVS /* may saturate in BASOP */ *L_snr_sum = L_add_o( *L_snr_sum, L_tmp, &Overflow ); /* Q4 */ -#else /* BASOP_NOGLOB */ - *L_snr_sum = L_add( *L_snr_sum, L_tmp ); /* Q4 */ -#endif /* BASOP_NOGLOB */ + move32(); BASOP_SATURATE_WARNING_ON_EVS } @@ -252,9 +253,9 @@ Word16 dtx_hangover_addition_fx( NOISE_EST_HANDLE hNoiseEst /* i : Noise estimation handle */ ) { - Word16 hangover_short_dtx; - Word16 flag_dtx; - Word16 tmp; + Word16 hangover_short_dtx; /* Q0 */ + Word16 flag_dtx; /* Q0 */ + Word16 tmp; /* Q0 */ if ( hNoiseEst == NULL ) { hNoiseEst = st_fx->hNoiseEst; @@ -277,19 +278,19 @@ Word16 dtx_hangover_addition_fx( test(); test(); - if ( ( ( LT_16( lp_snr, ( 16 * 256 ) ) ) && ( NE_16( st_fx->input_bwidth, NB ) ) ) || ( GT_16( hVAD->prim_act_he_fx, 31130 ) ) ) /*.95*Q15*/ + if ( ( ( LT_16( lp_snr, ( 16 * 256 ) ) ) && ( st_fx->input_bwidth != NB ) ) || ( GT_16( hVAD->prim_act_he_fx, 31130 ) ) ) /*.95*Q15*/ { hangover_short_dtx = 3; move16(); } /* Adjust hangover according to activity history */ - if ( GT_16( hVAD->vad_prim_cnt_16, 12 ) ) /* 12 requires roughly > 80% primary activity */ + IF( GT_16( hVAD->vad_prim_cnt_16, 12 ) ) /* 12 requires roughly > 80% primary activity */ { hangover_short_dtx = add( hangover_short_dtx, 2 ); } - if ( GT_16( hVAD->vad_flag_cnt_50, 40 ) ) /* 40 requires roughtly > 80% flag activity */ + IF( GT_16( hVAD->vad_flag_cnt_50, 40 ) ) /* 40 requires roughtly > 80% flag activity */ { hangover_short_dtx = add( hangover_short_dtx, 5 ); } @@ -339,7 +340,7 @@ Word16 dtx_hangover_addition_fx( /* hangover adjustment from combined FFT+CLDFBVAD */ IF( NE_16( st_fx->core, AMR_WB_CORE ) ) { - hangover_short_dtx = sub( hangover_short_dtx, cldfb_subtraction ); + hangover_short_dtx = sub( hangover_short_dtx, cldfb_subtraction ); /* Q0 */ hangover_short_dtx = s_max( hangover_short_dtx, 0 ); } @@ -358,9 +359,10 @@ Word16 dtx_hangover_addition_fx( /* inside HO period */ test(); - if ( ( LT_16( hVAD->hangover_cnt_dtx, HANGOVER_LONG_FX ) ) && ( hVAD->hangover_cnt_dtx != 0 ) ) + IF( ( LT_16( hVAD->hangover_cnt_dtx, HANGOVER_LONG_FX ) ) && ( hVAD->hangover_cnt_dtx != 0 ) ) { - hVAD->hangover_cnt_dtx = add( hVAD->hangover_cnt_dtx, 1 ); + hVAD->hangover_cnt_dtx = add( hVAD->hangover_cnt_dtx, 1 ); /* Q0 */ + move16(); } hVAD->hangover_terminate_flag = 0; move16(); /* float fix FIX_HO_TERMINATE */ @@ -377,21 +379,24 @@ Word16 dtx_hangover_addition_fx( /* inside Music HO period */ test(); - if ( ( LT_16( hVAD->hangover_cnt_music, HANGOVER_LONG_MUSIC_FX ) ) && ( hVAD->hangover_cnt_music != 0 ) ) + IF( ( LT_16( hVAD->hangover_cnt_music, HANGOVER_LONG_MUSIC_FX ) ) && ( hVAD->hangover_cnt_music != 0 ) ) { hVAD->hangover_cnt_music = add( hVAD->hangover_cnt_music, 1 ); + move16(); } } ELSE { /* Reset the counter of speech frames necessary to start hangover algorithm */ - if ( LT_16( hVAD->hangover_cnt_dtx, HANGOVER_LONG_FX ) ) /* inside HO period */ + IF( LT_16( hVAD->hangover_cnt_dtx, HANGOVER_LONG_FX ) ) /* inside HO period */ { hVAD->hangover_cnt_dtx = add( hVAD->hangover_cnt_dtx, 1 ); + move16(); } - if ( LT_16( hVAD->hangover_cnt_music, HANGOVER_LONG_MUSIC_FX ) ) /* inside HO period */ + IF( LT_16( hVAD->hangover_cnt_music, HANGOVER_LONG_MUSIC_FX ) ) /* inside HO period */ { hVAD->hangover_cnt_music = add( hVAD->hangover_cnt_music, 1 ); + move16(); } /* fast terminate DTX hangover if st->hangover_terminate_flag is set */ @@ -444,9 +449,9 @@ Word16 ivas_dtx_hangover_addition_fx( NOISE_EST_HANDLE hNoiseEst, /* i : Noise estimation handle */ Word16 *rem_dtx_ho ) { - Word16 hangover_short_dtx; - Word16 flag_dtx; - Word16 tmp; + Word16 hangover_short_dtx; /* Q0 */ + Word16 flag_dtx; /* Q0 */ + Word16 tmp; /* Q0 */ if ( hNoiseEst == NULL ) { hNoiseEst = st_fx->hNoiseEst; @@ -476,12 +481,12 @@ Word16 ivas_dtx_hangover_addition_fx( } /* Adjust hangover according to activity history */ - if ( GT_16( hVAD->vad_prim_cnt_16, 12 ) ) /* 12 requires roughly > 80% primary activity */ + IF( GT_16( hVAD->vad_prim_cnt_16, 12 ) ) /* 12 requires roughly > 80% primary activity */ { hangover_short_dtx = add( hangover_short_dtx, 2 ); } - if ( GT_16( hVAD->vad_flag_cnt_50, 40 ) ) /* 40 requires roughtly > 80% flag activity */ + IF( GT_16( hVAD->vad_flag_cnt_50, 40 ) ) /* 40 requires roughtly > 80% flag activity */ { hangover_short_dtx = add( hangover_short_dtx, 5 ); } @@ -506,7 +511,7 @@ Word16 ivas_dtx_hangover_addition_fx( /* need to be a bit stricter with the DTXHO in very clean WB, SWB cond for EVS12k8VAD section */ test(); test(); - if ( ( NE_16( st_fx->input_bwidth, NB ) ) /* WB or SWB or FB */ + if ( ( st_fx->input_bwidth != NB ) /* WB or SWB or FB */ && ( NE_16( st_fx->core, AMR_WB_CORE ) ) && ( GT_16( lp_snr, 25 * 256 ) ) ) { tmp = 2; @@ -531,7 +536,7 @@ Word16 ivas_dtx_hangover_addition_fx( /* hangover adjustment from combined FFT+CLDFBVAD */ IF( NE_16( st_fx->core, AMR_WB_CORE ) ) { - hangover_short_dtx = sub( hangover_short_dtx, cldfb_subtraction ); + hangover_short_dtx = sub( hangover_short_dtx, cldfb_subtraction ); /*Q0*/ hangover_short_dtx = s_max( hangover_short_dtx, 0 ); } IF( vad_flag != 0 ) /* Speech present */ @@ -549,9 +554,10 @@ Word16 ivas_dtx_hangover_addition_fx( /* inside HO period */ test(); - if ( ( LT_16( hVAD->hangover_cnt_dtx, HANGOVER_LONG_FX ) ) && ( hVAD->hangover_cnt_dtx != 0 ) ) + IF( ( LT_16( hVAD->hangover_cnt_dtx, HANGOVER_LONG_FX ) ) && ( hVAD->hangover_cnt_dtx != 0 ) ) { - hVAD->hangover_cnt_dtx = add( hVAD->hangover_cnt_dtx, 1 ); + hVAD->hangover_cnt_dtx = add( hVAD->hangover_cnt_dtx, 1 ); /*Q0*/ + move16(); } hVAD->hangover_terminate_flag = 0; move16(); /* float fix FIX_HO_TERMINATE */ @@ -560,7 +566,7 @@ Word16 ivas_dtx_hangover_addition_fx( test(); test(); test(); - if ( ( GT_16( hVAD->prim_act_he_fx, 31129 ) ) && ( GT_16( hNoiseEst->Etot_lp_fx, 40 * 256 ) ) && ( GT_16( hVAD->vad_prim_cnt_16, 14 ) ) && ( GT_16( hVAD->vad_flag_cnt_50, 48 ) ) ) /* 45 requires roughly > 95% flag activity */ + if ( ( GT_16( hVAD->prim_act_he_fx, 32113 ) ) && ( GT_16( hNoiseEst->Etot_lp_fx, 40 * 256 ) ) && ( GT_16( hVAD->vad_prim_cnt_16, 14 ) ) && ( GT_16( hVAD->vad_flag_cnt_50, 48 ) ) ) /* 45 requires roughly > 95% flag activity */ { hVAD->hangover_cnt_music = 0; move16(); @@ -568,7 +574,7 @@ Word16 ivas_dtx_hangover_addition_fx( /* inside Music HO period */ test(); - if ( ( LT_16( hVAD->hangover_cnt_music, HANGOVER_LONG_MUSIC_FX ) ) && ( hVAD->hangover_cnt_music != 0 ) ) + IF( ( LT_16( hVAD->hangover_cnt_music, HANGOVER_LONG_MUSIC_FX ) ) && ( hVAD->hangover_cnt_music != 0 ) ) { hVAD->hangover_cnt_music = add( hVAD->hangover_cnt_music, 1 ); move16(); @@ -577,12 +583,12 @@ Word16 ivas_dtx_hangover_addition_fx( ELSE { /* Reset the counter of speech frames necessary to start hangover algorithm */ - if ( LT_16( hVAD->hangover_cnt_dtx, HANGOVER_LONG_FX ) ) /* inside HO period */ + IF( LT_16( hVAD->hangover_cnt_dtx, HANGOVER_LONG_FX ) ) /* inside HO period */ { hVAD->hangover_cnt_dtx = add( hVAD->hangover_cnt_dtx, 1 ); move16(); } - if ( LT_16( hVAD->hangover_cnt_music, HANGOVER_LONG_MUSIC_FX ) ) /* inside HO period */ + IF( LT_16( hVAD->hangover_cnt_music, HANGOVER_LONG_MUSIC_FX ) ) /* inside HO period */ { hVAD->hangover_cnt_music = add( hVAD->hangover_cnt_music, 1 ); move16(); @@ -652,8 +658,8 @@ Word16 wb_vad_fx( const Word16 Q_new, /* i : scaling factor Q0 */ VAD_HANDLE hVAD, /* i/o: VAD data handle */ NOISE_EST_HANDLE hNoiseEst, /* i : Noise estimation handle */ - Word16 lp_speech_fx, /* i : long term active speech energy average */ - Word16 lp_noise_fx /* i : long term noise energy */ + Word16 lp_speech_fx, /* i : long term active speech energy average Q8 */ + Word16 lp_noise_fx /* i : long term noise energy Q8 */ ) { Word16 i, flag = 0, hangover_short; @@ -705,6 +711,7 @@ Word16 wb_vad_fx( Word16 last_7k2_coder_type; #ifdef BASOP_NOGLOB_DECLARE_LOCAL Flag Overflow = 0; + move32(); #endif if ( hNoiseEst == NULL ) @@ -738,14 +745,12 @@ Word16 wb_vad_fx( move16(); L_accum_ener_L = L_deposit_l( 0 ); L_accum_ener_H = L_deposit_l( 0 ); - L_snr18 = L_deposit_l( 0 ); /* Q4*/ L_snr19 = L_deposit_l( 0 ); /* Q4 */ L_msnr18 = L_deposit_l( 8192 ); /* 1.0 Q13*/ L_msnr19 = L_deposit_l( 8192 ); /* 1.0 Q13 */ - - IF( EQ_16( vad_bwidth_fx, NB ) ) + IF( vad_bwidth_fx == NB ) { st_fx->min_band = 1; move16(); @@ -978,19 +983,13 @@ Word16 wb_vad_fx( { e_num = norm_l( L_tmp1 ); m_num = extract_h( L_shl( L_tmp1, e_num ) ); - e_noise = norm_l( ftmp2 ); m_noise_local = extract_h( L_shl( ftmp2, e_noise ) ); m_num = shr( m_num, 1 ); shift_snr = add( sub( e_num, e_noise ), 15 - 4 ); - snr_tmp = div_s( m_num, m_noise_local ); -#ifdef BASOP_NOGLOB L_snr = L_shr_o( snr_tmp, shift_snr, &Overflow ); /* L_snr in Q4 */ -#else /* BASOP_NOGLOB */ - L_snr = L_shr( snr_tmp, shift_snr ); /* L_snr in Q4 */ -#endif /* BASOP_NOGLOB */ } ELSE { @@ -1023,11 +1022,7 @@ Word16 wb_vad_fx( shift_snr = add( sub( e_num, e_noise ), 15 - 4 ); snr_tmp = div_s( m_num, m_noise_local ); -#ifdef BASOP_NOGLOB L_snr = L_shr_o( snr_tmp, shift_snr, &Overflow ); /* L_snr in Q4 */ -#else /* BASOP_NOGLOB */ - L_snr = L_shr( snr_tmp, shift_snr ); /* L_snr in Q4 */ -#endif /* BASOP_NOGLOB */ } ELSE { @@ -1059,54 +1054,30 @@ Word16 wb_vad_fx( snr_sumt = add( snr_sumt, shr( snr, 4 ) ); /*Q4 */ -#ifdef BASOP_NOGLOB tmp = shl_o( snr, 5, &Overflow ); /* Q8 -> Q13 */ -#else /* BASOP_NOGLOB */ - tmp = shl( snr, 5 ); /* Q8 -> Q13 */ -#endif /* BASOP_NOGLOB */ IF( LT_16( i, 2 ) ) { -#ifdef BASOP_NOGLOB tmp = add_o( tmp, delta1, &Overflow ); /*Q13 */ -#else /* BASOP_NOGLOB */ - tmp = add( tmp, delta1 ); /*Q13 */ -#endif /* BASOP_NOGLOB */ } ELSE IF( LT_16( i, 7 ) ) { -#ifdef BASOP_NOGLOB tmp = add_o( tmp, delta2, &Overflow ); /*Q13 */ -#else /* BASOP_NOGLOB */ - tmp = add( tmp, delta2 ); /*Q13 */ -#endif /* BASOP_NOGLOB */ } ELSE IF( LT_16( i, 18 ) ) { -#ifdef BASOP_NOGLOB tmp = add_o( tmp, delta3, &Overflow ); /*Q13 */ -#else /* BASOP_NOGLOB */ - tmp = add( tmp, delta3 ); /*Q13 */ -#endif /* BASOP_NOGLOB */ } ELSE { -#ifdef BASOP_NOGLOB tmp = add_o( tmp, delta4, &Overflow ); /*Q13 */ -#else /* BASOP_NOGLOB */ - tmp = add( tmp, delta4 ); /*Q13 */ -#endif /* BASOP_NOGLOB */ } tmp1 = tmp; move16(); /* ftmp1 = ftmp; */ sub( 0, 0 ); - if ( i < 7 ) + if ( LT_16( i, 7 ) ) { -#ifdef BASOP_NOGLOB tmp1 = add_o( tmp, 3277, &Overflow ); /*.4 in Q13 ftmp1 = ftmp + 0.4f; */ -#else /* BASOP_NOGLOB */ - tmp1 = add( tmp, 3277 ); /*.4 in Q13 ftmp1 = ftmp + 0.4f; */ -#endif /* BASOP_NOGLOB */ } tmp = s_min( tmp, 16384 ); /* Q13, ftmp = min(ftmp, 2.0f); */ @@ -1152,11 +1123,7 @@ Word16 wb_vad_fx( shift_snr = add( sub( e_num, e_noise ), 15 - 4 ); snr_tmp = div_s( m_num, m_noise_local ); -#ifdef BASOP_NOGLOB L_snr = L_shr_o( snr_tmp, shift_snr, &Overflow ); /* L_snr in Q4 */ -#else /* BASOP_NOGLOB */ - L_snr = L_shr( snr_tmp, shift_snr ); /* L_snr in Q4 */ -#endif /* BASOP_NOGLOB */ } ELSE { @@ -1194,19 +1161,11 @@ Word16 wb_vad_fx( /* accumulate background noise energy in bands [0-2] and in bands [3-19]*/ IF( LT_16( i, 3 ) ) { -#ifdef BASOP_NOGLOB L_accum_ener_L = L_add_o( L_accum_ener_L, hNoiseEst->bckr_fx[i], &Overflow ); /*Q_new+QSCALE */ -#else - L_accum_ener_L = L_add( L_accum_ener_L, hNoiseEst->bckr_fx[i] ); /*Q_new+QSCALE */ -#endif } ELSE { -#ifdef BASOP_NOGLOB L_accum_ener_H = L_add_o( L_accum_ener_H, hNoiseEst->bckr_fx[i], &Overflow ); /*Q_new+QSCALE */ -#else - L_accum_ener_H = L_add( L_accum_ener_H, hNoiseEst->bckr_fx[i] ); /*Q_new+QSCALE */ -#endif } /* Identify the outlier band */ @@ -1230,7 +1189,7 @@ Word16 wb_vad_fx( L_tmp = L_add( L_tmp1, L_tmp ); if ( GT_32( L_tmp, L_mssnr ) ) { - L_mssnr = L_tmp; + L_mssnr = L_tmp; /*Q13*/ } } ELSE IF( ( snr_idx != 0 ) && GT_16( nb_sig_snr, 13 ) ) @@ -1300,11 +1259,8 @@ Word16 wb_vad_fx( } } /*st_fx->snr_sum_vad_fx = 0.5f * st->snr_sum_vad + 0.5f * snr_sum_ol;*/ -#ifdef BASOP_NOGLOB hVAD->L_snr_sum_vad_fx = L_shr( L_add_o( hVAD->L_snr_sum_vad_fx, L_snr_sum_ol, &Overflow ), 1 ); /*Q4*/ -#else /* BASOP_NOGLOB */ - hVAD->L_snr_sum_vad_fx = L_shr( L_add( hVAD->L_snr_sum_vad_fx, L_snr_sum_ol ), 1 ); /*Q4*/ -#endif /* BASOP_NOGLOB */ + move32(); /* snr_sum_ol = 10.0f * (float)log10( snr_sum_ol ); */ snr_sum_ol = vad_snr_log_fx( L_snr_sum_ol, LG10 ); @@ -1340,19 +1296,9 @@ Word16 wb_vad_fx( L_tmp = L_shl( L_mult( sub( hNoiseEst->Etot_v_h2_fx, nv_ofs ), nv ), 7 ); /* Q8+Q8+1 +7 --> Q24 */ L_tmp = L_mac( L_tmp, nc, (Word16) 32767 ); /* Q8+Q15+1 = Q24 */ thr1 = mac_r( L_tmp, lp_snr, nk ); /* Q8+Q15+1 - 16 --> Q8 */ -#ifdef IVAS_CODE - if ( st->element_mode > EVS_MONO && hNoiseEst->first_noise_updt_cnt < 100 ) - { - /* lower threshold during warmup time */ - thr1 -= 10.0f; - vad_thr = 0.f; - } -#endif + IF( GT_16( lp_snr, (Word16) 20 * ( 1 << 8 ) ) ) /* if (lp_snr > 20.0f )*/ { -#ifdef IVAS_CODE - if ( st->element_mode == EVS_MONO || hNoiseEst->first_noise_updt_cnt >= 100 ) -#endif { /* thr1 = thr1 + 0.3f * (lp_snr - 20.0f); */ thr1 = add( thr1, mult( 9830, sub( lp_snr, (Word16) 20 * ( 1 << 8 ) ) ) ); /* Q15*Q8+1 -16 --> Q8 */ @@ -1363,6 +1309,7 @@ Word16 wb_vad_fx( if ( EQ_16( st_fx->max_band, 16 ) && GT_16( lp_snr, 40 * 256 ) && GT_16( thr1, 6600 ) && LT_16( lp_speech_fx, 11520 ) ) { thr1 = 6600; + move16(); } } } @@ -1401,7 +1348,7 @@ Word16 wb_vad_fx( test(); test(); /*_DIFF_FLOAT_FIX_ -> the conditions around Opt_SC_VBR_fx are invertered compared to float ### st_fx->Opt_SC_VBR!=0 vs !st_fx->Opt_SC_VBR #####*/ - test(); + // test(); IF( LE_16( snr_outlier_index, 4 ) && ( ( GT_16( st_fx->last_coder_type, UNVOICED ) && ( st_fx->Opt_SC_VBR != 0 ) ) || ( GT_16( last_7k2_coder_type, UNVOICED ) && ( st_fx->Opt_SC_VBR == 0 ) ) ) ) @@ -1426,12 +1373,8 @@ Word16 wb_vad_fx( thr1_ol = thr1; move16(); L_tmp2 = Msub_32_16( (Word32) 614, L_snr_outlier, 20972 ); /* .6*1024= */ /* 0.6 Q26(Q10 in high word) - Q4*Q21+1 */ -#ifdef BASOP_NOGLOB - tmp2 = round_fx( L_shl_o( L_tmp2, 14, &Overflow ) ); /* Q10(high word)+ 14 -16 --> Q8*/ -#else /* BASOP_NOGLOB */ - tmp2 = round_fx( L_shl( L_tmp2, 14 ) ); /* Q10(high word)+ 14 -16 --> Q8*/ -#endif - if ( L_tmp2 > 0 ) + tmp2 = round_fx( L_shl_o( L_tmp2, 14, &Overflow ) ); /* Q10(high word)+ 14 -16 --> Q8*/ + IF( L_tmp2 > 0 ) { thr1_ol = add( thr1_ol, tmp2 ); /* Q24 >>16 + Q8 */ } @@ -1453,7 +1396,7 @@ Word16 wb_vad_fx( flag_he1 = 1; move16(); /* he1 primary decision */ hVAD->nb_active_frames_he1 = add( hVAD->nb_active_frames_he1, 1 ); /* Counter of consecutive active speech frames */ - + move16(); IF( GE_16( hVAD->nb_active_frames_he1, ACTIVE_FRAMES_FX ) ) { hVAD->nb_active_frames_he1 = ACTIVE_FRAMES_FX; @@ -1464,14 +1407,16 @@ Word16 wb_vad_fx( /* inside HO period */ test(); - if ( sub( hVAD->hangover_cnt_he1, HANGOVER_LONG_HE_FX ) < 0 && hVAD->hangover_cnt_he1 != 0 ) + IF( sub( hVAD->hangover_cnt_he1, HANGOVER_LONG_HE_FX ) < 0 && hVAD->hangover_cnt_he1 != 0 ) { hVAD->hangover_cnt_he1 = add( hVAD->hangover_cnt_he1, 1 ); + move16(); } - if ( hVAD->soft_hangover > 0 ) + IF( hVAD->soft_hangover > 0 ) { hVAD->soft_hangover = sub( hVAD->soft_hangover, 1 ); + move16(); } } ELSE @@ -1503,7 +1448,7 @@ Word16 wb_vad_fx( IF( LT_16( hVAD->bcg_flux_fx, 640 ) ) { hangover_hd = add( shr( hangover_hd, 1 ), 1 ); - move16(); + // move16(); } /* VAD hangover for he1 */ @@ -1515,6 +1460,7 @@ Word16 wb_vad_fx( flag_he1 = 1; move16(); hVAD->soft_hangover = sub( hVAD->soft_hangover, 1 ); + move16(); } ELSE { @@ -1536,6 +1482,7 @@ Word16 wb_vad_fx( flag_he1 = 1; move16(); hVAD->hangover_cnt_he1 = add( hVAD->hangover_cnt_he1, 1 ); + move16(); } @@ -1551,11 +1498,13 @@ Word16 wb_vad_fx( { /*st->bcg_flux = 0.9f * st->bcg_flux + (1-0.9f)*(st->bcg_flux+50);*/ hVAD->bcg_flux_fx = mac_r( L_mult( hVAD->bcg_flux_fx, 29491 ), add( hVAD->bcg_flux_fx, 800 ), 3277 ); /*Q4 */ + move16(); } ELSE { /*st->bcg_flux = 0.9f * st->bcg_flux + (1-0.9f)*snr_sumt*/ hVAD->bcg_flux_fx = mac_r( L_mult( hVAD->bcg_flux_fx, 29491 ), snr_sumt, 3277 ); /*Q4 */ + move16(); } } ELSE @@ -1564,11 +1513,13 @@ Word16 wb_vad_fx( { /*st->bcg_flux = 0.99f * st->bcg_flux + (1-0.99f)*(st->bcg_flux+10);*/ hVAD->bcg_flux_fx = mac_r( L_mult( hVAD->bcg_flux_fx, 32440 ), add( hVAD->bcg_flux_fx, 160 ), 328 ); /*Q4 */ + move16(); } ELSE { /*st->bcg_flux = 0.99f * st->bcg_flux + (1-0.99f)*snr_sumt;*/ hVAD->bcg_flux_fx = mac_r( L_mult( hVAD->bcg_flux_fx, 32440 ), snr_sumt, 328 ); /*Q4 */ + move16(); } } } @@ -1580,11 +1531,13 @@ Word16 wb_vad_fx( { /*st->bcg_flux = 0.95f * st->bcg_flux + (1-0.95f)*(st->bcg_flux-30);*/ hVAD->bcg_flux_fx = mac_r( L_mult( hVAD->bcg_flux_fx, 31130 ), sub( hVAD->bcg_flux_fx, 480 ), 1638 ); /*Q4 */ + move16(); } ELSE { /*st->bcg_flux = 0.95f * st->bcg_flux + (1-0.95f)*snr_sumt;*/ hVAD->bcg_flux_fx = mac_r( L_mult( hVAD->bcg_flux_fx, 31130 ), snr_sumt, 1638 ); /*Q4 */ + move16(); } } ELSE @@ -1593,16 +1546,19 @@ Word16 wb_vad_fx( { /*st->bcg_flux = 0.9992f * st->bcg_flux + (1-0.9992f)*(st->bcg_flux-10);*/ hVAD->bcg_flux_fx = mac_r( L_mult( hVAD->bcg_flux_fx, 32742 ), sub( hVAD->bcg_flux_fx, 160 ), 26 ); /*Q4 */ + move16(); } ELSE { /*st->bcg_flux = 0.9992f * st->bcg_flux + (1-0.9992f)*snr_sumt;*/ hVAD->bcg_flux_fx = mac_r( L_mult( hVAD->bcg_flux_fx, 32742 ), snr_sumt, 26 ); /*Q4 */ + move16(); } } } - hVAD->bcg_flux_init = s_max( hVAD->bcg_flux_init, 0 ); + hVAD->bcg_flux_init = s_max( hVAD->bcg_flux_init, 0 ); /*Q0*/ + move16(); } flag = 0; @@ -1620,6 +1576,7 @@ Word16 wb_vad_fx( move16(); hVAD->nb_active_frames = add( hVAD->nb_active_frames, 1 ); /* Counter of consecutive active speech frames */ + move16(); IF( GE_16( hVAD->nb_active_frames, ACTIVE_FRAMES_FX ) ) { @@ -1631,9 +1588,10 @@ Word16 wb_vad_fx( /* inside HO period */ test(); - if ( LT_16( hVAD->hangover_cnt, HANGOVER_LONG_FX ) && hVAD->hangover_cnt != 0 ) + IF( LT_16( hVAD->hangover_cnt, HANGOVER_LONG_FX ) && hVAD->hangover_cnt != 0 ) { hVAD->hangover_cnt = add( hVAD->hangover_cnt, 1 ); + move16(); } } ELSE @@ -1642,9 +1600,10 @@ Word16 wb_vad_fx( hVAD->nb_active_frames = 0; move16(); - if ( LT_16( hVAD->hangover_cnt, HANGOVER_LONG_FX ) ) /* inside HO period */ + IF( LT_16( hVAD->hangover_cnt, HANGOVER_LONG_FX ) ) /* inside HO period */ { hVAD->hangover_cnt = add( hVAD->hangover_cnt, 1 ); + move16(); } @@ -1652,14 +1611,16 @@ Word16 wb_vad_fx( { test(); test(); - if ( EQ_16( st_fx->element_mode, EVS_MONO ) && ( LT_16( lp_snr, th_clean ) ) && ( st_fx->Opt_SC_VBR != 0 ) && ( GE_16( hVAD->hangover_cnt, 2 ) ) ) + test(); + if ( st_fx->element_mode == EVS_MONO && ( LT_16( lp_snr, th_clean ) ) && ( st_fx->Opt_SC_VBR != 0 ) && ( GE_16( hVAD->hangover_cnt, 2 ) ) ) { *noisy_speech_HO = 1; move16(); } test(); test(); - if ( EQ_16( st_fx->element_mode, EVS_MONO ) && ( GE_16( lp_snr, th_clean ) ) && ( st_fx->Opt_SC_VBR != 0 ) && ( GE_16( hVAD->hangover_cnt, 2 ) ) ) + test(); + if ( st_fx->element_mode == EVS_MONO && ( GE_16( lp_snr, th_clean ) ) && ( st_fx->Opt_SC_VBR != 0 ) && ( GE_16( hVAD->hangover_cnt, 2 ) ) ) { *clean_speech_HO = 1; move16(); @@ -1706,6 +1667,7 @@ Word16 wb_vad_fx( IF( GT_16( snr_sum, thr1 ) ) /* Speech present, possibly in hangover */ { hVAD->nb_active_frames = add( hVAD->nb_active_frames, 1 ); /* Counter of consecutive active speech frames */ + move16(); IF( GE_16( hVAD->nb_active_frames, ACTIVE_FRAMES_FX ) ) { hVAD->nb_active_frames = ACTIVE_FRAMES_FX; @@ -1729,7 +1691,7 @@ Word16 wb_vad_fx( IF( LT_16( hVAD->hangover_cnt, HANGOVER_LONG_NB_FX ) ) { hVAD->hangover_cnt = add( hVAD->hangover_cnt, 1 ); - + move16(); IF( LT_16( lp_snr, 4864 ) ) /*19.0f Q8*/ /* very low SNR */ { @@ -1752,7 +1714,7 @@ Word16 wb_vad_fx( tmp = 282; move16(); /* 1.10f; */ } - if ( LT_16( lp_snr, th_clean ) ) + IF( LT_16( lp_snr, th_clean ) ) { thr2 = sub( thr1_nb_mod, tmp ); /*thr2 = thr1 - [ 1.10 || 1.3 ];*/ } @@ -1760,7 +1722,7 @@ Word16 wb_vad_fx( flag = 0; move16(); - IF( GT_16( snr_sum, thr1_nb_mod ) ) /* Speech assumed present, even though lowered thr1 */ + if ( GT_16( snr_sum, thr1_nb_mod ) ) /* Speech assumed present, even though lowered thr1 */ { flag = 1; move16(); @@ -1778,8 +1740,8 @@ Word16 wb_vad_fx( if ( EQ_16( st_fx->element_mode, EVS_MONO ) ) { *NB_speech_HO = 1; + move16(); } - move16(); } thr1 = thr1_nb_mod; move16(); /* needed for st_fx->vadnoise_fx update below */ @@ -1806,7 +1768,7 @@ Word16 wb_vad_fx( } } - if ( st_fx->hSC_VBR != NULL ) + IF( st_fx->hSC_VBR != NULL ) { /* SC-VBR */ st_fx->hSC_VBR->vadsnr_fx = snr_sum; @@ -1817,20 +1779,23 @@ Word16 wb_vad_fx( /* Updates */ hVAD->prim_act_quick_fx = mult_r( 26214, hVAD->prim_act_quick_fx ); /*Q15 */ - - if ( st_fx->localVAD != 0 ) + move16(); + IF( st_fx->localVAD != 0 ) { hVAD->prim_act_quick_fx = add( 6554, hVAD->prim_act_quick_fx ); /*Q15 */ + move16(); } hVAD->prim_act_slow_fx = mult_r( 32440, hVAD->prim_act_slow_fx ); /*Q15 */ + move16(); - if ( st_fx->localVAD != 0 ) + IF( st_fx->localVAD != 0 ) { hVAD->prim_act_slow_fx = add( 328, hVAD->prim_act_slow_fx ); /*Q15 */ + move16(); } - tmp = hVAD->prim_act_slow_fx; + tmp = hVAD->prim_act_slow_fx; /*Q15*/ move16(); if ( LE_16( hVAD->prim_act_quick_fx, hVAD->prim_act_slow_fx ) ) { @@ -1838,19 +1803,23 @@ Word16 wb_vad_fx( move16(); } /*st->prim_act = 0.1f * tmp + (1.0f-0.1f)* st->prim_act;*/ - hVAD->prim_act_fx = mac_r( L_mult( 3277, tmp ), 29491, hVAD->prim_act_fx ); - + hVAD->prim_act_fx = mac_r( L_mult( 3277, tmp ), 29491, hVAD->prim_act_fx ); /*Q15 */ + move16(); hVAD->prim_act_quick_he_fx = mult_r( 26214, hVAD->prim_act_quick_he_fx ); /*Q15 */ - if ( *localVAD_HE_SAD != 0 ) + move16(); + IF( *localVAD_HE_SAD != 0 ) { hVAD->prim_act_quick_he_fx = add( 6554, hVAD->prim_act_quick_he_fx ); /*Q15 */ + move16(); } hVAD->prim_act_slow_he_fx = mult_r( 32440, hVAD->prim_act_slow_he_fx ); /*Q15 */ - if ( *localVAD_HE_SAD != 0 ) + move16(); + IF( *localVAD_HE_SAD != 0 ) { hVAD->prim_act_slow_he_fx = add( 328, hVAD->prim_act_slow_he_fx ); /*Q15 */ + move16(); } tmp = hVAD->prim_act_slow_he_fx; @@ -1861,42 +1830,49 @@ Word16 wb_vad_fx( move16(); } hVAD->prim_act_he_fx = mac_r( L_mult( 3277, tmp ), 29491, hVAD->prim_act_he_fx ); + move16(); - - if ( L_and( hVAD->vad_flag_reg_H, (Word32) 0x40000L ) != 0 ) /* 0x4000L = 0x01L << 18 */ + IF( L_and( hVAD->vad_flag_reg_H, (Word32) 0x40000L ) != 0 ) /* 0x4000L = 0x01L << 18 */ { hVAD->vad_flag_cnt_50 = sub( hVAD->vad_flag_cnt_50, 1 ); + move16(); } hVAD->vad_flag_reg_H = L_shl( L_and( hVAD->vad_flag_reg_H, (Word32) 0x3fffffffL ), 1 ); + move32(); - - if ( L_and( hVAD->vad_flag_reg_L, (Word32) 0x40000000L ) != 0 ) + IF( L_and( hVAD->vad_flag_reg_L, (Word32) 0x40000000L ) != 0 ) { hVAD->vad_flag_reg_H = L_or( hVAD->vad_flag_reg_H, 0x01L ); + move32(); } hVAD->vad_flag_reg_L = L_shl( L_and( hVAD->vad_flag_reg_L, (Word32) 0x3fffffffL ), 1 ); - + move32(); IF( flag != 0 ) /* should not include the extra DTX hangover */ { hVAD->vad_flag_reg_L = L_or( hVAD->vad_flag_reg_L, 0x01L ); + move32(); hVAD->vad_flag_cnt_50 = add( hVAD->vad_flag_cnt_50, 1 ); + move16(); } - if ( L_and( hVAD->vad_prim_reg, (Word32) 0x8000L ) != 0 ) /* 0x8000L = 1L << 15 */ + IF( L_and( hVAD->vad_prim_reg, (Word32) 0x8000L ) != 0 ) /* 0x8000L = 1L << 15 */ { hVAD->vad_prim_cnt_16 = sub( hVAD->vad_prim_cnt_16, 1 ); + move16(); } hVAD->vad_prim_reg = L_shl( L_and( hVAD->vad_prim_reg, (Word32) 0x3fffffffL ), 1 ); - + move32(); IF( st_fx->localVAD != 0 ) { hVAD->vad_prim_reg = L_or( hVAD->vad_prim_reg, 0x01L ); + move32(); hVAD->vad_prim_cnt_16 = add( hVAD->vad_prim_cnt_16, 1 ); + move16(); } return flag; @@ -1904,22 +1880,21 @@ Word16 wb_vad_fx( Word16 wb_vad_ivas_fx( Encoder_State *st_fx, /* i/o: encoder state structure */ - const Word32 fr_bands[], /* i : per band input energy (contains 2 vectors) Q_new+QSCALE*/ + const Word32 fr_bands[], /* i : per band i energy (contains 2 vectors) Qx + QSCALE */ + const Word16 q_fr_bands, /* i : Q of fr_bands */ Word16 *noisy_speech_HO, /* o : SC-VBR noisy speech HO flag */ Word16 *clean_speech_HO, /* o : SC-VBR clean speech HO flag */ Word16 *NB_speech_HO, /* o : SC-VBR NB speech HO flag */ Word16 *snr_sum_he, /* o : Output snr_sum as weighted spectral measure*/ Word16 *localVAD_HE_SAD, Word16 *flag_noisy_speech_snr, /* o : */ - const Word16 Q_new, /* i : scaling factor Q0 */ VAD_HANDLE hVAD, /* i/o: VAD data handle */ NOISE_EST_HANDLE hNoiseEst, /* i : Noise estimation handle */ - Word16 lp_speech_fx, /* i : long term active speech energy average */ - Word16 lp_noise_fx /* i : long term noise energy */ + Word16 lp_speech_fx, /* i : long term active speech energy average Q8 */ + Word16 lp_noise_fx /* i : long term noise energy Q8 */ ) { Word16 i, flag = 0, hangover_short; - Word16 snr_sum, thr1 = 0, thr1_nb_mod, thr2 = 0, nk = 0, nc = 0, th_clean = 0; Word16 lp_snr; /* Q8 */ const Word32 *pt1; @@ -1930,18 +1905,18 @@ Word16 wb_vad_ivas_fx( Word32 L_snr, L_snr_sum; Word32 ftmp, ftmp1, ftmp2; - Word16 m_noise_local, e_noise, e_num, m_num, snr, snr_tmp, shift_snr; - + Word16 m_noise_local, e_noise, e_num, m_num, snr_tmp, shift_snr, q_snr_tmp, q_snr; + Word32 L_snr_tmp; Word16 snr_sumt; Word32 L_vad_thr; Word16 hangover_hd; Word16 snr_idx; - Word16 delta1, delta2, delta3, delta4; + Word32 delta1, delta2, delta3, delta4; Word16 flag_he1; Word16 stmp; Word32 L_msnr, L_mssnr = 0, L_mssnr_hov; - Word16 j, tmp, tmp1, tmp2; + Word16 j, tmp, tmp2; Word32 L_tmp, L_tmp1, L_tmp2; Word32 L_snr18, L_snr19; /* Q4 */ @@ -1953,7 +1928,7 @@ Word16 wb_vad_ivas_fx( Word32 L_snr_sum_HE_SAD; /* Q4 */ Word16 snr_sum_HE_SAD; /*Q8 log */ Word16 sign_thr_HE_SAD, min_snr_HE_SAD; - + Word32 L_snr_sumt; Word16 thr1_ol; Word32 L_snr_sum_ol; @@ -1965,8 +1940,10 @@ Word16 wb_vad_ivas_fx( Word32 L_accum_ener_H; Word16 vad_bwidth_fx; Word16 last_7k2_coder_type; + Word16 q_shift; #ifdef BASOP_NOGLOB_DECLARE_LOCAL Flag Overflow = 0; + move32(); #endif Word16 L_msnr_e = 0, L_mssnr_e = 0, L_mssnr_hov_e = 0, L_msnr18_e = 0, L_msnr19_e = 0; move16(); /*L_msnr_e*/ @@ -1974,7 +1951,6 @@ Word16 wb_vad_ivas_fx( move16(); /*L_mssnr_hov_e*/ move16(); /*L_msnr18_e*/ move16(); /*L_msnr19_e*/ - move16(); /*Overflow*/ move32(); /*L_mssnr*/ move16(); /*thr1*/ move16(); /*thr2*/ @@ -1994,13 +1970,13 @@ Word16 wb_vad_ivas_fx( } if ( LT_16( lp_speech_fx, -100 * 256 ) ) { - lp_speech_fx = st_fx->lp_speech_fx; + lp_speech_fx = st_fx->lp_speech_fx; /*Q8*/ move16(); } if ( LT_16( lp_noise_fx, -100 * 256 ) ) { - lp_noise_fx = st_fx->lp_noise_fx; + lp_noise_fx = st_fx->lp_noise_fx; /*Q8*/ move16(); } @@ -2083,7 +2059,7 @@ Word16 wb_vad_ivas_fx( } ELSE /* NB input */ { - move16(); + // move16(); nk = 3277; move16(); /* 0.1 Q15 */ nc = 4096; @@ -2140,15 +2116,15 @@ Word16 wb_vad_ivas_fx( IF( snr_idx == 0 ) { stmp = 6; - move16(); + move32(); delta1 = 0; - move16(); /*0.0f in Q13 */ + move32(); /*0.0f in Q16 */ delta2 = 0; - move16(); /*0.0f in Q13 */ + move32(); /*0.0f in Q16 */ delta3 = 0; - move16(); /*0.0f in Q13 */ + move32(); /*0.0f in Q16 */ delta4 = 0; - move16(); + move32(); /*0.0f in Q16 */ /*vad_thr = 2.4f*lp_snr - 42.2f; @@ -2162,15 +2138,15 @@ Word16 wb_vad_ivas_fx( ELSE IF( EQ_16( snr_idx, 1 ) ) { stmp = 6; - move16(); - delta1 = 819; - move16(); /*0.1f in Q13 */ - delta2 = 1638; - move16(); /*0.2f in Q13 */ - delta3 = 1638; - move16(); /*0.2f in Q13 */ - delta4 = 1638; - move16(); /*0.2f in Q13 */ + move32(); + delta1 = 6554; + move32(); /*0.1f in Q16 */ + delta2 = 13107; + move32(); /*0.2f in Q16 */ + delta3 = 13107; + move32(); /*0.2f in Q16 */ + delta4 = 13107; + move32(); /*0.2f in Q16 */ /* vad_thr = 2.4f*lp_snr - 40.2f; vad_thr = min(vad_thr, 80); @@ -2183,15 +2159,15 @@ Word16 wb_vad_ivas_fx( ELSE { stmp = 9; - move16(); - delta1 = 1638; - move16(); /*0.2f in Q13 */ - delta2 = 3277; - move16(); /*0.4f in Q13 */ - delta3 = 2458; - move16(); /*0.3f in Q13 */ - delta4 = 3277; - move16(); /*0.4f in Q13 */ + move32(); + delta1 = 13107; + move32(); /*0.2f in Q16 */ + delta2 = 26214; + move32(); /*0.4f in Q16 */ + delta3 = 19661; + move32(); /*0.3f in Q16 */ + delta4 = 26214; + move32(); /*0.4f in Q16 */ /* vad_thr = 2.5f*lp_snr - 10.0f; vad_thr = max(vad_thr, 1); */ @@ -2218,7 +2194,12 @@ Word16 wb_vad_ivas_fx( snr_sum_HE_SAD = 0; move16(); - + L_snr_sumt = 0; + move32(); + q_snr = 0; + move16(); + move16(); + q_shift = add( sub( q_fr_bands, hNoiseEst->q_bckr ), 15 - 4 ); FOR( i = st_fx->min_band; i <= st_fx->max_band; i++ ) { ftmp = L_add( *pt1++, 0 ); @@ -2240,34 +2221,20 @@ Word16 wb_vad_ivas_fx( IF( ftmp2 != 0 ) { e_num = norm_l( L_tmp1 ); - m_num = extract_h( L_shl( L_tmp1, e_num ) ); + m_num = extract_h( L_shl( L_tmp1, e_num ) ); // q_fr_bands+1+e_num-16 e_noise = norm_l( ftmp2 ); - m_noise_local = extract_h( L_shl( ftmp2, e_noise ) ); + m_noise_local = extract_h( L_shl( ftmp2, e_noise ) ); // hNoiseEst->q_bckr+e_noise-16 - m_num = shr( m_num, 1 ); - shift_snr = add( sub( e_num, e_noise ), 15 - 4 ); + m_num = shr( m_num, 1 ); // q_fr_bands+e_num-16 + shift_snr = add( sub( e_num, e_noise ), q_shift ); - snr_tmp = div_s( m_num, m_noise_local ); -#ifdef BASOP_NOGLOB + snr_tmp = div_s( m_num, m_noise_local ); // q_fr_bands+e_num-hNoiseEst->q_bckr-e_noise L_snr = L_shr_o( snr_tmp, shift_snr, &Overflow ); /* L_snr in Q4 */ -#else /* BASOP_NOGLOB */ - L_snr = L_shr( snr_tmp, shift_snr ); /* L_snr in Q4 */ -#endif /* BASOP_NOGLOB */ } ELSE { - e_num = norm_l( L_tmp1 ); - m_num = extract_h( L_shl( L_tmp1, e_num ) ); - - /* if bckr[i] == 0; approx. L_snr */ - e_noise = add( 30 + 1, abs_s( Q_new ) ); - - m_num = shr( m_num, 1 ); - shift_snr = add( sub( e_num, e_noise ), 15 - 4 ); - - snr_tmp = div_s( m_num, 32767 ); - L_snr = L_shr_o( snr_tmp, shift_snr, &Overflow ); /*L_snr in Q4*/ + L_snr = L_shr_o( L_tmp1, sub( Q3, q_fr_bands ), &Overflow ); // q_fr_bands+1 -> Q4 } } ELSE @@ -2277,34 +2244,20 @@ Word16 wb_vad_ivas_fx( IF( ftmp2 != 0 ) { e_num = norm_l( L_tmp2 ); - m_num = extract_h( L_shl( L_tmp2, e_num ) ); + m_num = extract_h( L_shl( L_tmp2, e_num ) ); // q_fr_bands+1+e_num-16 e_noise = norm_l( ftmp2 ); - m_noise_local = extract_h( L_shl( ftmp2, e_noise ) ); + m_noise_local = extract_h( L_shl( ftmp2, e_noise ) ); // hNoiseEst->q_bckr+e_noise-16 - m_num = shr( m_num, 1 ); - shift_snr = add( sub( e_num, e_noise ), 15 - 4 ); + m_num = shr( m_num, 1 ); // q_fr_bands+e_num-16 + shift_snr = add( sub( e_num, e_noise ), q_shift ); - snr_tmp = div_s( m_num, m_noise_local ); -#ifdef BASOP_NOGLOB + snr_tmp = div_s( m_num, m_noise_local ); // q_fr_bands+e_num-hNoiseEst->q_bckr-e_noise L_snr = L_shr_o( snr_tmp, shift_snr, &Overflow ); /* L_snr in Q4 */ -#else /* BASOP_NOGLOB */ - L_snr = L_shr( snr_tmp, shift_snr ); /* L_snr in Q4 */ -#endif /* BASOP_NOGLOB */ } ELSE { - e_num = norm_l( L_tmp2 ); - m_num = extract_h( L_shl( L_tmp2, e_num ) ); - - /* if bckr[i] == 0; approx. L_snr */ - e_noise = add( 30 + 1, abs_s( Q_new ) ); - - m_num = shr( m_num, 1 ); - shift_snr = add( sub( e_num, e_noise ), 15 - 4 ); - - snr_tmp = div_s( m_num, 32767 ); - L_snr = L_shr_o( snr_tmp, shift_snr, &Overflow ); /*L_snr in Q4*/ + L_snr = L_shr_o( L_tmp2, sub( Q3, q_fr_bands ), &Overflow ); // q_fr_bands+1 -> Q4 } } @@ -2316,70 +2269,48 @@ Word16 wb_vad_ivas_fx( /* snr[i] = (float)log10(snr[i]); */ - snr = vad_snr_log_fx( L_snr, ONE_LG10 ); + Word16 exp = norm_l( L_snr ); + Word16 val = Log2_norm_lc( L_shl( L_snr, exp ) ); + exp = sub( sub( 30, exp ), Q4 ); + L_snr = L_mac( L_deposit_h( exp ), val, 1 ); // Q16 + L_snr = Mpy_32_16_1( L_snr, 9864 /* log2 in Q15 */ ); // Q16 /* snr_sumt += snr[i];*/ - snr_sumt = add( snr_sumt, shr( snr, 4 ) ); /*Q4 */ + L_snr_sumt = L_add( L_snr_sumt, L_snr ); // Q16 - -#ifdef BASOP_NOGLOB - tmp = shl_o( snr, 5, &Overflow ); /* Q8 -> Q13 */ -#else /* BASOP_NOGLOB */ - tmp = shl( snr, 5 ); /* Q8 -> Q13 */ -#endif /* BASOP_NOGLOB */ IF( LT_16( i, 2 ) ) { -#ifdef BASOP_NOGLOB - tmp = add_o( tmp, delta1, &Overflow ); /*Q13 */ -#else /* BASOP_NOGLOB */ - tmp = add( tmp, delta1 ); /*Q13 */ -#endif /* BASOP_NOGLOB */ + ftmp = L_add( L_snr, delta1 ); // Q16 } ELSE IF( LT_16( i, 7 ) ) { -#ifdef BASOP_NOGLOB - tmp = add_o( tmp, delta2, &Overflow ); /*Q13 */ -#else /* BASOP_NOGLOB */ - tmp = add( tmp, delta2 ); /*Q13 */ -#endif /* BASOP_NOGLOB */ + ftmp = L_add( L_snr, delta2 ); // Q16 } ELSE IF( LT_16( i, 18 ) ) { -#ifdef BASOP_NOGLOB - tmp = add_o( tmp, delta3, &Overflow ); /*Q13 */ -#else /* BASOP_NOGLOB */ - tmp = add( tmp, delta3 ); /*Q13 */ -#endif /* BASOP_NOGLOB */ + ftmp = L_add( L_snr, delta3 ); // Q16 } ELSE { -#ifdef BASOP_NOGLOB - tmp = add_o( tmp, delta4, &Overflow ); /*Q13 */ -#else /* BASOP_NOGLOB */ - tmp = add( tmp, delta4 ); /*Q13 */ -#endif /* BASOP_NOGLOB */ + ftmp = L_add( L_snr, delta4 ); // Q16 } - tmp1 = tmp; - move16(); /* ftmp1 = ftmp; */ - sub( 0, 0 ); - IF( i < 7 ) + ftmp1 = ftmp; // Q16 + move32(); + + if ( LT_16( i, 7 ) ) { -#ifdef BASOP_NOGLOB - tmp1 = add_o( tmp, 3277, &Overflow ); /*.4 in Q13 ftmp1 = ftmp + 0.4f; */ -#else /* BASOP_NOGLOB */ - tmp1 = add( tmp, 3277 ); /*.4 in Q13 ftmp1 = ftmp + 0.4f; */ -#endif /* BASOP_NOGLOB */ + ftmp1 = L_add( ftmp, 26214 /*0.4 in Q16*/ ); // Q16 } - tmp = s_min( tmp, 16384 ); /* Q13, ftmp = min(ftmp, 2.0f); */ - tmp1 = s_min( tmp1, 16384 ); /* Q13, ftmp1 = min(ftmp1, 2.0f); */ + ftmp = L_min( ftmp, 2 << 16 ); // Q16 + ftmp1 = L_min( ftmp1, 2 << 16 ); // Q16 - Word16 norm_tmp = norm_l( tmp ); - Word32 scaled_tmp = L_shl( tmp, norm_tmp ); /*13+norm_tmp*/ + Word16 norm_tmp = norm_l( ftmp ); + Word32 scaled_tmp = L_shl( ftmp, norm_tmp ); /*16+norm_tmp*/ L_msnr = scaled_tmp; move32(); - L_msnr_e = sub( 18, norm_tmp ); + L_msnr_e = sub( 15, norm_tmp ); FOR( j = 1; j < stmp; j++ ) { /* Q13*Q13 +1 -16 +2 = Q13 */ @@ -2402,8 +2333,8 @@ Word16 wb_vad_ivas_fx( move16(); } - norm_tmp = norm_l( tmp1 ); - scaled_tmp = L_shl( tmp1, norm_tmp ); /*13+norm_tmp*/ + norm_tmp = norm_l( ftmp1 ); + scaled_tmp = L_shl( ftmp1, norm_tmp ); /*13+norm_tmp*/ L_msnr = scaled_tmp; move32(); L_msnr_e = sub( 18, norm_tmp ); @@ -2418,82 +2349,74 @@ Word16 wb_vad_ivas_fx( /* snr[i] = fr_enr / st->bckr[i] = L_tmp1/st->bckr[i];*/ IF( hNoiseEst->bckr_fx[i] != 0 ) { - e_num = norm_l( L_tmp1 ); - m_num = extract_h( L_shl( L_tmp1, e_num ) ); + e_num = sub( norm_l( L_tmp1 ), 1 ); + m_num = extract_h( L_shl( L_tmp1, e_num ) ); // q_fr_bands+1+e_num-16 e_noise = norm_l( hNoiseEst->bckr_fx[i] ); - m_noise_local = extract_h( L_shl( hNoiseEst->bckr_fx[i], e_noise ) ); + m_noise_local = extract_h( L_shl( hNoiseEst->bckr_fx[i], e_noise ) ); // hNoiseEst->q_bckr+e_noise-16 - m_num = shr( m_num, 1 ); - shift_snr = add( sub( e_num, e_noise ), 15 - 4 ); - - snr_tmp = div_s( m_num, m_noise_local ); -#ifdef BASOP_NOGLOB - L_snr = L_shr_o( snr_tmp, shift_snr, &Overflow ); /* L_snr in Q4 */ -#else /* BASOP_NOGLOB */ - L_snr = L_shr( snr_tmp, shift_snr ); /* L_snr in Q4 */ -#endif /* BASOP_NOGLOB */ + L_snr_tmp = L_deposit_h( div_s( m_num, m_noise_local ) ); // 32+q_fr_bands+e_num-hNoiseEst->q_bckr-e_noise + q_snr_tmp = add( 32, sub( add( q_fr_bands, e_num ), add( hNoiseEst->q_bckr, e_noise ) ) ); } ELSE { - e_num = norm_l( L_tmp1 ); - m_num = extract_h( L_shl( L_tmp1, e_num ) ); - - /* if bckr[i] == 0; approx. L_snr */ - e_noise = add( 30 + 1, abs_s( Q_new ) ); - - m_num = shr( m_num, 1 ); - shift_snr = add( sub( e_num, e_noise ), 15 - 4 ); - - snr_tmp = div_s( m_num, 32767 ); - L_snr = L_shr_o( snr_tmp, shift_snr, &Overflow ); /*L_snr in Q4*/ + L_snr_tmp = Mpy_32_16_1( L_tmp1, 18286 /* 1/E_MIN in Q6 */ ); // q_fr_bands-8 + q_snr_tmp = sub( q_fr_bands, 8 ); } - /* conditional snrsum, snr_sum = snr_sum + snr[i];*/ + exp = sub( Q4, q_snr_tmp ); + L_snr = L_shl_sat( L_snr_tmp, exp ); // Q4 sign_thr_snr_acc_fx( &L_snr_sum_HE_SAD, L_snr, sign_thr_HE_SAD, min_snr_HE_SAD ); sign_thr_snr_acc_fx( &L_snr_sum, L_snr, sign_thr, min_snr ); - L_snr = L_max( L_snr, 16 ); /*Q4, if( snr[i] < 1.0f ) { snr[i] = 1.0f;} */ + /* if( snr[i] < 1.0f ) { snr[i] = 1.0f;} */ + IF( LT_32( L_snr, 16 /* 1.0 in Q4 */ ) ) + { + L_snr_tmp = 16; + q_snr_tmp = Q4; + move32(); + move16(); + exp = 0; + move16(); + } /* float saves all snrs in an snr[] vector , in fix we only save two bands */ - IF( EQ_16( i, 18 ) ) + if ( EQ_16( i, 18 ) ) { - L_snr18 = L_add( L_snr, 0 ); /*Q4 */ + L_snr18 = L_shl_sat( L_snr_tmp, exp ); /*Q4 */ } - IF( EQ_16( i, 19 ) ) + if ( EQ_16( i, 19 ) ) { - L_snr19 = L_add( L_snr, 0 ); /* Q4 */ + L_snr19 = L_shl_sat( L_snr_tmp, exp ); /* Q4 */ } /* accumulate background noise energy in bands [0-2] and in bands [3-19]*/ IF( LT_16( i, 3 ) ) { -#ifdef BASOP_NOGLOB - L_accum_ener_L = L_add_o( L_accum_ener_L, hNoiseEst->bckr_fx[i], &Overflow ); /*Q_new+QSCALE */ -#else - L_accum_ener_L = L_add( L_accum_ener_L, hNoiseEst->bckr_fx[i] ); /*Q_new+QSCALE */ -#endif + L_accum_ener_L = L_add_o( L_accum_ener_L, hNoiseEst->bckr_fx[i], &Overflow ); /* hNoiseEst->q_bckr */ } ELSE { -#ifdef BASOP_NOGLOB - L_accum_ener_H = L_add_o( L_accum_ener_H, hNoiseEst->bckr_fx[i], &Overflow ); /*Q_new+QSCALE */ -#else - L_accum_ener_H = L_add( L_accum_ener_H, hNoiseEst->bckr_fx[i] ); /*Q_new+QSCALE */ -#endif + L_accum_ener_H = L_add_o( L_accum_ener_H, hNoiseEst->bckr_fx[i], &Overflow ); /*hNoiseEst->q_bckr */ } /* Identify the outlier band */ - IF( GT_32( L_snr, L_snr_outlier ) ) + IF( GT_32( L_snr_tmp, L_shl_sat( L_snr_outlier, sub( q_snr_tmp, q_snr ) ) ) ) { - L_snr_outlier = L_add( L_snr, 0 ); /*Q4*/ + L_snr_outlier = L_snr_tmp; + q_snr = q_snr_tmp; snr_outlier_index = i; + move32(); + move16(); move16(); } } /* end of band loop */ + L_snr_outlier = L_shl_sat( L_snr_outlier, sub( Q4, q_snr ) ); // q_snr -> Q4 + snr_sumt = extract_h( L_shl( L_snr_sumt, Q4 ) ); // Q16 -> Q4 + test(); test(); test(); /* one additional test for ELSE IF */ @@ -2564,11 +2487,8 @@ Word16 wb_vad_ivas_fx( } } /*st_fx->snr_sum_vad_fx = 0.5f * st->snr_sum_vad + 0.5f * snr_sum_ol;*/ -#ifdef BASOP_NOGLOB hVAD->L_snr_sum_vad_fx = L_shr( L_add_o( hVAD->L_snr_sum_vad_fx, L_snr_sum_ol, &Overflow ), 1 ); /*Q4*/ -#else /* BASOP_NOGLOB */ - hVAD->L_snr_sum_vad_fx = L_shr( L_add( hVAD->L_snr_sum_vad_fx, L_snr_sum_ol ), 1 ); /*Q4*/ -#endif /* BASOP_NOGLOB */ + move32(); /* snr_sum_ol = 10.0f * (float)log10( snr_sum_ol ); */ snr_sum_ol = vad_snr_log_fx( L_snr_sum_ol, LG10 ); @@ -2605,7 +2525,7 @@ Word16 wb_vad_ivas_fx( thr1 = mac_r( L_tmp, lp_snr, nk ); /* Q8+Q15+1 - 16 --> Q8 */ test(); - IF( st_fx->element_mode > EVS_MONO && hNoiseEst->first_noise_updt_cnt < 100 ) + IF( st_fx->element_mode > EVS_MONO && LT_16( hNoiseEst->first_noise_updt_cnt, 100 ) ) { /* lower threshold during warmup time */ thr1 = sub( thr1, 2560 ); @@ -2639,7 +2559,7 @@ Word16 wb_vad_ivas_fx( * Hangover control & final VAD decision *---------------------------------------------------------------------*/ - IF( NE_16( vad_bwidth_fx, NB ) ) + IF( vad_bwidth_fx != NB ) { /* Outlier Detection first calculates thr1_ol and snr_sum_ol instead of @@ -2691,11 +2611,7 @@ Word16 wb_vad_ivas_fx( thr1_ol = thr1; move16(); L_tmp2 = Msub_32_16( (Word32) 614, L_snr_outlier, 20972 ); /* .6*1024= */ /* 0.6 Q26(Q10 in high word) - Q4*Q21+1 */ -#ifdef BASOP_NOGLOB - tmp2 = round_fx( L_shl_o( L_tmp2, 14, &Overflow ) ); /* Q10(high word)+ 14 -16 --> Q8*/ -#else /* BASOP_NOGLOB */ - tmp2 = round_fx( L_shl( L_tmp2, 14 ) ); /* Q10(high word)+ 14 -16 --> Q8*/ -#endif + tmp2 = round_fx( L_shl_o( L_tmp2, 14, &Overflow ) ); /* Q10(high word)+ 14 -16 --> Q8*/ IF( L_tmp2 > 0 ) { thr1_ol = add( thr1_ol, tmp2 ); /* Q24 >>16 + Q8 */ @@ -2712,11 +2628,15 @@ Word16 wb_vad_ivas_fx( /* DTX HANGOVER is in pre_proc_fx() */ flag_he1 = 0; move16(); - + st_fx->localVAD = 0; + move16(); IF( EQ_16( BASOP_Util_Cmp_Mant32Exp( L_mssnr, L_mssnr_e, L_vad_thr, 18 ), 1 ) ) { flag_he1 = 1; - move16(); /* he1 primary decision */ + move16(); + st_fx->localVAD = 1; + move16(); + /* he1 primary decision */ hVAD->nb_active_frames_he1 = add( hVAD->nb_active_frames_he1, 1 ); /* Counter of consecutive active speech frames */ move16(); @@ -3104,7 +3024,7 @@ Word16 wb_vad_ivas_fx( hVAD->prim_act_quick_fx = mult_r( 26214, hVAD->prim_act_quick_fx ); /*Q15 */ move16(); - if ( st_fx->localVAD != 0 ) + IF( st_fx->localVAD != 0 ) { hVAD->prim_act_quick_fx = add( 6554, hVAD->prim_act_quick_fx ); /*Q15 */ move16(); @@ -3113,13 +3033,13 @@ Word16 wb_vad_ivas_fx( hVAD->prim_act_slow_fx = mult_r( 32440, hVAD->prim_act_slow_fx ); /*Q15 */ move16(); - if ( st_fx->localVAD != 0 ) + IF( st_fx->localVAD != 0 ) { hVAD->prim_act_slow_fx = add( 328, hVAD->prim_act_slow_fx ); /*Q15 */ move16(); } - tmp = hVAD->prim_act_slow_fx; + tmp = hVAD->prim_act_slow_fx; /*Q15*/ move16(); if ( LE_16( hVAD->prim_act_quick_fx, hVAD->prim_act_slow_fx ) ) { @@ -3132,7 +3052,7 @@ Word16 wb_vad_ivas_fx( hVAD->prim_act_quick_he_fx = mult_r( 26214, hVAD->prim_act_quick_he_fx ); /*Q15 */ move16(); - if ( *localVAD_HE_SAD != 0 ) + IF( *localVAD_HE_SAD != 0 ) { hVAD->prim_act_quick_he_fx = add( 6554, hVAD->prim_act_quick_he_fx ); /*Q15 */ move16(); @@ -3140,7 +3060,7 @@ Word16 wb_vad_ivas_fx( hVAD->prim_act_slow_he_fx = mult_r( 32440, hVAD->prim_act_slow_he_fx ); /*Q15 */ move16(); - if ( *localVAD_HE_SAD != 0 ) + IF( *localVAD_HE_SAD != 0 ) { hVAD->prim_act_slow_he_fx = add( 328, hVAD->prim_act_slow_he_fx ); /*Q15 */ move16(); @@ -3156,7 +3076,7 @@ Word16 wb_vad_ivas_fx( hVAD->prim_act_he_fx = mac_r( L_mult( 3277, tmp ), 29491, hVAD->prim_act_he_fx ); move16(); - if ( L_and( hVAD->vad_flag_reg_H, (Word32) 0x40000L ) != 0 ) /* 0x4000L = 0x01L << 18 */ + IF( L_and( hVAD->vad_flag_reg_H, (Word32) 0x40000L ) != 0 ) /* 0x4000L = 0x01L << 18 */ { hVAD->vad_flag_cnt_50 = sub( hVAD->vad_flag_cnt_50, 1 ); move16(); @@ -3165,7 +3085,7 @@ Word16 wb_vad_ivas_fx( hVAD->vad_flag_reg_H = L_shl( L_and( hVAD->vad_flag_reg_H, (Word32) 0x3fffffffL ), 1 ); move32(); - if ( L_and( hVAD->vad_flag_reg_L, (Word32) 0x40000000L ) != 0 ) + IF( L_and( hVAD->vad_flag_reg_L, (Word32) 0x40000000L ) != 0 ) { hVAD->vad_flag_reg_H = L_or( hVAD->vad_flag_reg_H, 0x01L ); move32(); @@ -3183,9 +3103,9 @@ Word16 wb_vad_ivas_fx( } - if ( L_and( hVAD->vad_prim_reg, (Word32) 0x8000L ) != 0 ) /* 0x8000L = 1L << 15 */ + IF( L_and( hVAD->vad_prim_reg, (Word32) 0x8000L ) != 0 ) /* 0x8000L = 1L << 15 */ { - hVAD->vad_prim_cnt_16 = sub( hVAD->vad_prim_cnt_16, 1 ); + hVAD->vad_prim_cnt_16 = sub( hVAD->vad_prim_cnt_16, 1 ); /*Q0*/ move16(); } @@ -3194,9 +3114,9 @@ Word16 wb_vad_ivas_fx( IF( st_fx->localVAD != 0 ) { - hVAD->vad_prim_reg = L_or( hVAD->vad_prim_reg, 0x01L ); + hVAD->vad_prim_reg = L_or( hVAD->vad_prim_reg, 0x01L ); /*Q0*/ move32(); - hVAD->vad_prim_cnt_16 = add( hVAD->vad_prim_cnt_16, 1 ); + hVAD->vad_prim_cnt_16 = add( hVAD->vad_prim_cnt_16, 1 ); /*Q0*/ move16(); } diff --git a/lib_enc/vad_param_updt.c b/lib_enc/vad_param_updt.c deleted file mode 100644 index e82b4595f4c7202482ab5eee40ff59257442ab77..0000000000000000000000000000000000000000 --- a/lib_enc/vad_param_updt.c +++ /dev/null @@ -1,48 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include -#include "cnst.h" -#include "prot.h" -#include "wmc_auto.h" - -/*-------------------------------------------------------------------* - * vad_param_updt() - * - * Update parameters used by the VAD or DTX - *--------------------------------------------------------------------*/ diff --git a/lib_enc/vad_param_updt_fx.c b/lib_enc/vad_param_updt_fx.c index e0b607c5a68015d07f0af5774686659f67f828c4..464903a03a6b45a7e9e241b4c900901bd290b801 100644 --- a/lib_enc/vad_param_updt_fx.c +++ b/lib_enc/vad_param_updt_fx.c @@ -17,10 +17,10 @@ *--------------------------------------------------------------------*/ void vad_param_updt_fx( - Encoder_State *st_fx, /* i/o: state structure */ - const Word16 old_pitch1, /* i : OL pitch value from last frame */ - const Word16 corr_shift, /* i : correlation shift Q15*/ - const Word16 corr_shiftR, /* i : correlation shift */ + Encoder_State *st_fx, /* i/o: state structure */ + const Word16 old_pitch1, /* i : OL pitch value from last frame Q0 */ + const Word16 corr_shift, /* i : correlation shift Q15*/ + const Word16 corr_shiftR, /* i : correlation shift Q15 */ const Word16 Az[], /* i: a coeffs Q12 */ FRONT_VAD_ENC_HANDLE hFrontVad[], /* i/o: front-VAD handles */ const Word16 n_channels /* i : number of channels */ @@ -36,31 +36,29 @@ void vad_param_updt_fx( DTX_ENC_HANDLE hDtxEnc = st_fx->hDtxEnc; #ifdef BASOP_NOGLOB_DECLARE_LOCAL Flag Overflow = 0; + move32(); #endif - corr_shift_temp[0] = corr_shift; - corr_shift_temp[1] = corr_shiftR; + corr_shift_temp[0] = corr_shift; /*Q15*/ + corr_shift_temp[1] = corr_shiftR; /*Q15*/ move16(); move16(); hVAD = st_fx->hVAD; ini_frame = st_fx->ini_frame; move16(); - move16(); IF( hFrontVad != NULL ) { hVAD = hFrontVad[0]->hVAD; ini_frame = hFrontVad[0]->ini_frame; move16(); - move16(); } FOR( i = 0; i < n_channels; i++ ) { if ( EQ_16( i, 1 ) ) { hVAD = hFrontVad[1]->hVAD; - move16(); } IF( !st_fx->Opt_AMR_WB ) { @@ -85,7 +83,8 @@ void vad_param_updt_fx( { /* update the counter of consecutive inactive frames in DTX */ hVAD->consec_inactive = add( hVAD->consec_inactive, 1 ); - IF( GT_16( hVAD->consec_inactive, 5 ) ) + move16(); + if ( GT_16( hVAD->consec_inactive, 5 ) ) { hVAD->consec_inactive = 5; move16(); @@ -115,7 +114,7 @@ void vad_param_updt_fx( hVAD->ra_deltasum_fx = add( hVAD->ra_deltasum_fx, sub( tmp2, tmp1 ) ); move16(); - tmp1 = mult( 26214, hVAD->running_avg_fx ); + tmp1 = mult( 26214, hVAD->running_avg_fx ); /* (0.8 in Q15 * Q15) = Q(30 - 15)*/ hVAD->running_avg_fx = add( tmp1, tmp2 ); move16(); @@ -148,7 +147,7 @@ void vad_param_updt_fx( hDtxEnc->cnt_SID = 1; move16(); st_fx->core_brate = SID_2k40; - move16(); + move32(); hVAD->trigger_SID = 0; move16(); } @@ -165,14 +164,9 @@ void vad_param_updt_fx( /* (voicing[0] + voicing[1] + voicing[2]) / 3 + corr_shift */ L_tmp = L_mult( st_fx->voicing_fx[0], 10923 ); L_tmp = L_mac( L_tmp, st_fx->voicing_fx[1], 10923 ); - L_tmp = L_mac( L_tmp, st_fx->voicing_fx[2], 10923 ); /*Q15 */ -#ifdef BASOP_NOGLOB + L_tmp = L_mac( L_tmp, st_fx->voicing_fx[2], 10923 ); /*Q15 */ L_tmp = L_mac_o( L_tmp, corr_shift_temp[i], 32767, &Overflow ); /*Q15 */ voice_tmp = round_fx_o( L_tmp, &Overflow ); /*Q15 */ -#else /* BASOP_NOGLOB */ - L_tmp = L_mac( L_tmp, corr_shift_temp[i], 32767 ); /*Q15 */ - voice_tmp = round_fx( L_tmp ); /*Q15 */ -#endif /* abs(pitch[0] - *pitO) + abs(pitch[1] - pitch[0]) + abs(pitch[2] - pitch[1]) */ pitch_tmp = abs_s( sub( st_fx->pitch[0], old_pitch1 ) ); /*Q0 */ diff --git a/lib_enc/vad_proc.c b/lib_enc/vad_proc.c deleted file mode 100644 index 661cc4b7b44a35c09c0ee29a47f1b5d01df6c3fe..0000000000000000000000000000000000000000 --- a/lib_enc/vad_proc.c +++ /dev/null @@ -1,42 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include -#include "options.h" -#include "prot.h" -#include "rom_enc.h" -#include "wmc_auto.h" diff --git a/lib_enc/vad_proc_fx.c b/lib_enc/vad_proc_fx.c index 2c12ec9963d302a67c8be4af01c4e3d35b1563cd..2c9273ff54824969fec1d5297c9bf322fd20cee4 100644 --- a/lib_enc/vad_proc_fx.c +++ b/lib_enc/vad_proc_fx.c @@ -25,8 +25,8 @@ Word16 vad_init_fx( ) { Word16 i = 0; - - IF( hVAD_CLDFB == NULL ) + move16(); + if ( hVAD_CLDFB == NULL ) { return -1; } @@ -177,7 +177,7 @@ Word16 vad_init_fx( return 0; } -static void UpdateState( +static void UpdateState_fx( VAD_CLDFB_HANDLE hVAD_CLDFB, /* i/o: CLDFB VAD state */ Word16 vad_flag, /* i : VAD flag */ Word32 frame_energy, /* i : current frame energy */ @@ -205,7 +205,7 @@ static void UpdateState( hVAD_CLDFB->lt_bg_highf_eng = L_add( MUL_F( hVAD_CLDFB->lt_bg_highf_eng, 31130 ), L_shr( MUL_F( HB_Power, 1638 ), sub( HB_Power_Q, lt_bg_highf_eng_Q ) ) ); } - if ( LT_16( hVAD_CLDFB->frameloop, 1000 ) ) + IF( LT_16( hVAD_CLDFB->frameloop, 1000 ) ) { hVAD_CLDFB->frameloop = add( hVAD_CLDFB->frameloop, 1 ); move16(); @@ -242,7 +242,9 @@ static void UpdateState( move16(); hVAD_CLDFB->continuous_speech_num2 = add( hVAD_CLDFB->continuous_speech_num2, 1 ); + move16(); hVAD_CLDFB->continuous_speech_num = add( hVAD_CLDFB->continuous_speech_num, 1 ); + move16(); if ( GT_16( hVAD_CLDFB->continuous_speech_num, 2048 ) ) { hVAD_CLDFB->continuous_speech_num = 2048; @@ -357,7 +359,7 @@ Word16 vad_proc_fx( HB_Power_Q, snr, tsnr, hVAD_CLDFB->vad_flag_for_bk_update, music_backgound_f ); - UpdateState( hVAD_CLDFB, hVAD_CLDFB->vad_flag_for_bk_update, frame_energy2, frame_energy2_Q, update_flag, music_backgound_f, HB_Power, HB_Power_Q, snr ); + UpdateState_fx( hVAD_CLDFB, hVAD_CLDFB->vad_flag_for_bk_update, frame_energy2, frame_energy2_Q, update_flag, music_backgound_f, HB_Power, HB_Power_Q, snr ); return vad_flag; diff --git a/lib_enc/vbr_average_rate.c b/lib_enc/vbr_average_rate.c deleted file mode 100644 index ee4d0477acb81ddd3b7e06486a85b5a601a73d2a..0000000000000000000000000000000000000000 --- a/lib_enc/vbr_average_rate.c +++ /dev/null @@ -1,54 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include "cnst.h" -#include "prot.h" -#include "rom_com.h" -#include "wmc_auto.h" - -/*------------------------------------------------------------------* - * Local constants - *------------------------------------------------------------------*/ - -#define RATEWIN 600 /* length of the rate control window. This is 600 active speech frames. This equals roughly 12s of active speech */ - -/*------------------------------------------------------------------* - * update_average_rate() - * - * SC-VBR update average data rate - *------------------------------------------------------------------*/ diff --git a/lib_enc/vbr_average_rate_fx.c b/lib_enc/vbr_average_rate_fx.c index 931333ebe264c01ecdf50d5a276127413b5ad34f..28371b2d716d2cd26f8cba81e5bdc40929ed02cb 100644 --- a/lib_enc/vbr_average_rate_fx.c +++ b/lib_enc/vbr_average_rate_fx.c @@ -41,7 +41,7 @@ /*=================================================================================*/ void update_average_rate_fx( SC_VBR_ENC_HANDLE hSC_VBR, /* i/o: SC-VBR state structure */ - const Word32 core_brate_fx /* i : core bitrate */ + const Word32 core_brate_fx /* i : core bitrate Q0 */ ) { Word32 avratetarg_fx; /* target rate for next RATEWIN active frames */ @@ -69,7 +69,7 @@ void update_average_rate_fx( /*st->global_avr_rate = (st->global_avr_rate * (st->global_frame_cnt-1) + st->sum_of_rates) / st->global_frame_cnt; */ exp = norm_s( hSC_VBR->global_frame_cnt ); - tmp = shl( hSC_VBR->global_frame_cnt, exp ); + tmp = shl( hSC_VBR->global_frame_cnt, exp ); /*Q0 + exp = exp*/ recip = div_s( 16384, tmp ); Qrecip = sub( 15, sub( exp, 14 ) ); @@ -218,11 +218,11 @@ void update_average_rate_fx( st->pattern_m=100 . Later this value is used in voiced.enc to bump up 10% of PPP frames to F frames. */ /* st->pattern_m = (short)(1000 * (avratetarg - 6.15f * RATEWIN * 10)/(10 * RATEWIN * 0.1f) ); */ - L_tmp = L_mult0( RATEWIN, VBR_ADR_MAX_TARGET_x10_Q1 ); - L_tmp = L_shl( L_tmp, 12 ); + L_tmp = RATEWIN * VBR_ADR_MAX_TARGET_x10_Q1; /* Q0 * Q1 = Q1 */ + L_tmp = L_shl( L_tmp, 12 ); /* Q1<<12 = Q13*/ L_tmp = L_sub( avratetarg_fx, L_tmp ); /*27307=(1000/(RATEWIN))Q14 */ - tmp = extract_h( L_shl( Mult_32_16( L_tmp, 27307 ), 4 ) ); + tmp = extract_h( L_shl( Mult_32_16( L_tmp, 27307 ), 4 ) ); /*(((Q13*Q0)<<4)>>16) = Q18>>16 = Q2*/ hSC_VBR->pattern_m = tmp; move16(); @@ -257,12 +257,8 @@ void update_average_rate_fx( move16(); /* sum the total number of bits (in kbytes) * 10 here */ /*st->sum_of_rates += (hSC_VBR->core_brate / 1000.0f) * 10; */ - L_tmp = L_shl( Mult_32_16( core_brate_fx, 20972 ), 7 ); -#ifdef BASOP_NOGLOB + L_tmp = L_shl( Mult_32_16( core_brate_fx, 20972 ), 7 ); /*Q13*/ hSC_VBR->sum_of_rates_fx = L_add_o( hSC_VBR->sum_of_rates_fx, L_tmp, &Overflow ); -#else - hSC_VBR->sum_of_rates_fx = L_add( hSC_VBR->sum_of_rates_fx, L_tmp ); -#endif move32(); return; } diff --git a/lib_enc/vlpc_1st_cod.c b/lib_enc/vlpc_1st_cod.c deleted file mode 100644 index 0fe8682daace6673130ca2ca05de2a188e8e2ae0..0000000000000000000000000000000000000000 --- a/lib_enc/vlpc_1st_cod.c +++ /dev/null @@ -1,42 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include "cnst.h" -#include "prot.h" -#include "rom_com.h" -#include "wmc_auto.h" diff --git a/lib_enc/vlpc_1st_cod_fx.c b/lib_enc/vlpc_1st_cod_fx.c index deddb5023f050e318989567a1101cc9c99a90c54..9bfe0d8ae90c59aa69f96b024678e1fbd341760a 100644 --- a/lib_enc/vlpc_1st_cod_fx.c +++ b/lib_enc/vlpc_1st_cod_fx.c @@ -14,12 +14,12 @@ #define ISF_ONE 3 /*1.0f*1.28f Q1*/ /*=1.0f in 14Q1*1.28*/ /*------------------------------------------------------------------* - * lsf_weight() + * lsf_weight_fx() * * outputs only the weightings, doesn't do anything with the lsfq *------------------------------------------------------------------*/ /*outputs only the weightings, doesn't do anything with the lsfq*/ -static void lsf_weight( +static void lsf_weight_fx( const Word16 *lsfq, /* i : quantized lsf coefficients (14Q1*1.28)*/ Word16 *w /* o : lsf weighting vector (0Q15) */ ) @@ -31,7 +31,7 @@ static void lsf_weight( /* weighting function */ /*use the second element as the base to avoid the following division by 0*/ /*this happens when the ac function is nearly flat*/ - i = lsfq[0]; + i = lsfq[0]; /* (14Q1*1.28)*/ move16(); if ( lsfq[0] == 0 ) { @@ -40,7 +40,7 @@ static void lsf_weight( } inv_di0 = 0x7fff; move16(); - if ( GT_16( i, ISF_ONE ) ) + IF( GT_16( i, ISF_ONE ) ) { inv_di0 = div_s( ISF_ONE, i ); /*0Q15*/ /*inv_di0 = 1.0f / lsfq[0];*/ } @@ -52,33 +52,17 @@ static void lsf_weight( FOR( i = 1; i < ( M - 2 ); i += 2 ) /*for (i=1; i<(M-2); i+=2)*/ { inv_di1 = div_s( ISF_ONE, s_max( ISF_ONE, sub( lsfq[i], lsfq[i - 1] ) ) ); /*0Q15*/ /*inv_di1 = 1.0f / (lsfq[i] - lsfq[i-1]);*/ -#ifdef BASOP_NOGLOB w[i - 1] = add_sat( inv_di0, inv_di1 ); -#else - w[i - 1] = add( inv_di0, inv_di1 ); -#endif move16(); /*0Q15*/ /*w[i-1] = inv_di0 + inv_di1;*/ inv_di0 = div_s( ISF_ONE, s_max( ISF_ONE, sub( lsfq[i + 1], lsfq[i] ) ) ); /*0Q15*/ /*inv_di0 = 1.0f / (lsfq[i+1] - lsfq[i]);*/ -#ifdef BASOP_NOGLOB w[i] = add_sat( inv_di1, inv_di0 ); -#else - w[i] = add( inv_di1, inv_di0 ); -#endif move16(); /*0Q15*/ /*w[i] = inv_di1 + inv_di0;*/ } inv_di1 = div_s( ISF_ONE, s_max( ISF_ONE, sub( lsfq[i], lsfq[i - 1] ) ) ); /*inv_di1 = 1.0f / (lsfq[i] - lsfq[i-1]);*/ -#ifdef BASOP_NOGLOB w[i - 1] = add_sat( inv_di0, inv_di1 ); -#else - w[i - 1] = add( inv_di0, inv_di1 ); -#endif move16(); /*w[i-1] = inv_di0 + inv_di1;*/ inv_di0 = div_s( ISF_ONE, s_max( ISF_ONE, sub( FREQ_MAX, lsfq[i] ) ) ); /*inv_di0 = 1.0f / (FREQ_MAX - lsfq[i]);*/ -#ifdef BASOP_NOGLOB w[i] = add_sat( inv_di1, inv_di0 ); -#else - w[i] = add( inv_di1, inv_di0 ); -#endif move16(); /*w[i] = inv_di1 + inv_di0;*/ BASOP_SATURATE_WARNING_ON_EVS @@ -104,7 +88,7 @@ Word16 vlpc_1st_cod_fx( /* o : codebook index /* weighting */ - lsf_weight( lsf, w ); /*lsf:14Q1*1.28=>w:0Q15*/ + lsf_weight_fx( lsf, w ); /*lsf:14Q1*1.28=>w:0Q15*/ IF( EQ_16( rf_mode, 1 ) ) { Word16 s; diff --git a/lib_enc/vlpc_2st_cod.c b/lib_enc/vlpc_2st_cod.c deleted file mode 100644 index e7a8ca967132cf8896fc4a231dbaf74eed596840..0000000000000000000000000000000000000000 --- a/lib_enc/vlpc_2st_cod.c +++ /dev/null @@ -1,41 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include "cnst.h" -#include "prot.h" -#include "wmc_auto.h" diff --git a/lib_enc/vlpc_2st_cod_fx.c b/lib_enc/vlpc_2st_cod_fx.c index 6334684d25f9fb78871a516aaa4d94fb537afb8d..2ea4df5a991b85e437dfbd9b55c4367637077a2d 100644 --- a/lib_enc/vlpc_2st_cod_fx.c +++ b/lib_enc/vlpc_2st_cod_fx.c @@ -18,9 +18,9 @@ *------------------------------------------------------------------*/ Word16 vlpc_2st_cod_fx( /* output: number of allocated bits */ - const Word16 *lsf, /* i : normalized vector to quantize */ - Word16 *lsfq, /* i/o: i:1st stage o:1st+2nd stage */ - Word16 *indx, /* o : index[] (4 bits per words) */ + const Word16 *lsf, /* i : normalized vector to quantize (14Q1*1.28) */ + Word16 *lsfq, /* i/o: i:1st stage o:1st+2nd stage (14Q1*1.28) */ + Word16 *indx, /* o : index[] (4 bits per words) Q0 */ const Word16 mode, /* i : 0=abs, >0=rel */ const Word32 sr_core /* i : internal sampling rate */ ) @@ -32,6 +32,7 @@ Word16 vlpc_2st_cod_fx( /* output: number of allocated bits Word16 gap; #ifdef BASOP_NOGLOB_DECLARE_LOCAL Flag Overflow = 0; + move32(); #endif @@ -56,11 +57,7 @@ Word16 vlpc_2st_cod_fx( /* output: number of allocated bits BASOP_SATURATE_WARNING_OFF_EVS /* Allow saturate because we only need to know if the result is smaller than 8.0f */ FOR( i = 1; i < M; i++ ) { -#ifdef BASOP_NOGLOB L_tmp = L_mac_o( L_tmp, x[i], x[i], &Overflow ); /*10Q21*/ -#else /* BASOP_NOGLOB */ - L_tmp = L_mac( L_tmp, x[i], x[i] ); /*10Q21*/ -#endif } BASOP_SATURATE_WARNING_ON_EVS @@ -158,6 +155,7 @@ Word16 vlpc_2st_cod_fx( /* output: number of allocated bits { gap = 34; } + move16(); reorder_lsf_fx( lsfq, gap, M, INT_FS_FX ); diff --git a/lib_enc/voiced_enc.c b/lib_enc/voiced_enc.c deleted file mode 100644 index 5bfe6bfc099df4c4d4931c3c31b6c94162a7f88d..0000000000000000000000000000000000000000 --- a/lib_enc/voiced_enc.c +++ /dev/null @@ -1,44 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include -#include "prot.h" -#include "cnst.h" -#include "rom_com.h" -#include "wmc_auto.h" -#include "prot_fx.h" diff --git a/lib_enc/voiced_enc_fx.c b/lib_enc/voiced_enc_fx.c index cf08ebe5af47d25336b81e8abc4dc077fc654f87..b0dba61de4752b160164a6ad70f5612adcc6a100 100644 --- a/lib_enc/voiced_enc_fx.c +++ b/lib_enc/voiced_enc_fx.c @@ -74,15 +74,21 @@ ivas_error ppp_voiced_encoder_fx( { Word16 i; Word16 spike_near_edge = 0; + move16(); Word16 flag; Word16 delta_lag_E = 0, PPP_MODE_E, Q_delta_lag = 0; + move16(); /*delta_lag_E*/ + move16(); /*Q_delta_lag*/ Word16 out_of_bound = 0; + move16(); Word16 tmp, tmptmp, tmptmp1; Word16 pl, l; Word16 interp_delay[3], temp_pl, temp_l; Word16 upper_cut_off_freq_of_interest_fx = 0; + move16(); /*upper_cut_off_freq_of_interest_fx*/ Word16 upper_cut_off_freq_of_interest_norm_fx = 0, upper_cut_off_freq_norm_fx = 0; - + move16(); /*upper_cut_off_freq_of_interest_norm_fx*/ + move16(); /*upper_cut_off_freq_norm_fx*/ Word16 S_fx[PIT_MAX * 4 + 1], C_fx[PIT_MAX * 4 + 1]; Word16 Qtmpres; Word32 Ltemp, logLag, Ltemp_q; @@ -101,18 +107,24 @@ ivas_error ppp_voiced_encoder_fx( Word16 exp_ee, frac_ee; Word16 Qtmp; Word32 res_enratio_fx = 0; + move32(); Word16 mem_fx[10]; Word32 energy_impz_fx = 0, tmpres_fx; + move32(); /*energy_impz_fx*/ Word32 pos_nq0_fx, neg_nq0_fx, Ltmp; Word32 Ltmp_32, Ltmp1_32, Ltemp1, Ltemp2, Ltemp_fx; Word16 Qadj; Word32 tmp_fx = 0, sp_hb_enratio_fx = 0, sp_enratio_fx = 0; + move32(); /*tmp_fx*/ + move32(); /*sp_hb_enratio_fx*/ + move32(); /*sp_enratio_fx*/ Word32 low_band_en_fx; Word32 curr_Engy, prev_Engy; Word16 temp_Fs; #ifdef BASOP_NOGLOB_DECLARE_LOCAL Flag Overflow = 0; + move32(); #endif DTFS_STRUCTURE *CURRP_NQ_FX; DTFS_STRUCTURE *TMPDTFS_FX; @@ -171,7 +183,7 @@ ivas_error ppp_voiced_encoder_fx( upper_cut_off_freq_norm_fx = 16384; move16(); /*value normalized by 12800 */ } - ELSE IF( EQ_16( bwidth_fx, NB ) ) + ELSE IF( bwidth_fx == NB ) { upper_cut_off_freq_of_interest_fx = 3300; move16(); @@ -219,19 +231,20 @@ ivas_error ppp_voiced_encoder_fx( if ( hSC_VBR->last_ppp_mode == 1 ) { hSC_VBR->rate_control = 0; + move16(); } PPP_MODE_E = 'Q'; move16(); pl = s_min( MAX_LAG_PIT, rint_new_fx( L_shl( old_pitch_buf[( 2 * NB_SUBFR ) - 1], 10 ) ) ); - move16(); l = s_min( MAX_LAG_PIT, rint_new_fx( L_deposit_h( delay_fx ) ) ); - move16(); /* old_pitch_buf in Q6*/ /* Bump up if the lag is out_fx of range */ test(); + test(); + test(); IF( GT_16( sub( l, pl ), 13 ) || LT_16( sub( l, pl ), -11 ) || LT_16( l, 19 ) || LT_16( pl, 19 ) ) { hSC_VBR->bump_up = 1; @@ -259,7 +272,7 @@ ivas_error ppp_voiced_encoder_fx( } /* Use the out_fx array as a temp storage for currp */ - spike_near_edge = ppp_extract_pitch_period_fx( in_fx, out_fx, l, &out_of_bound, Qres ); + spike_near_edge = ppp_extract_pitch_period_fx( in_fx, out_fx, l, &out_of_bound, Qres ); /*Q0*/ move16(); /* out_fx in Qres */ @@ -310,7 +323,7 @@ ivas_error ppp_voiced_encoder_fx( move16(); /* pitch_fx in Q6 */ } curr_Engy = DTFS_getEngy_P2A_fx( CURRP_NQ_FX ); /*2Q where Q=CURRP_NQ_FX->Q */ - + move32(); /* Restoring PPP memories when the last frame is non-PPP */ IF( NE_16( hSC_VBR->last_ppp_mode, 1 ) ) { @@ -325,7 +338,7 @@ ivas_error ppp_voiced_encoder_fx( prev_Engy = L_add( Lacc, 0 ); hSC_VBR->Q_prev_cw_en_fx = norm_l( Lacc ); /* = K = headroom */ - + move16(); /*hSC_VBR->Q_prev_cw_en_fx = (Lacc==0)?31: hSC_VBR->Q_prev_cw_en_fx; */ if ( Lacc == 0 ) { @@ -334,7 +347,9 @@ ivas_error ppp_voiced_encoder_fx( } hSC_VBR->prev_cw_en_fx = (Word32) L_shl( Lacc, hSC_VBR->Q_prev_cw_en_fx ); /*2Q+K */ + move32(); hSC_VBR->Q_prev_cw_en_fx = add( hSC_VBR->Q_prev_cw_en_fx, shl( dtfs_temp_fx->Q, 1 ) ); + move16(); /* hSC_VBR->Q_prev_cw_en_fx = 2*(dtfs_temp_fx->Q) + K */ DTFS_copy_fx( TMPDTFS_FX, *dtfs_temp_fx ); /* output = TMPDTFS_FX */ @@ -346,19 +361,21 @@ ivas_error ppp_voiced_encoder_fx( /* Process low band */ Ltemp = DTFS_setEngyHarm_fx( 236, 2828, 0, 2828, 1, 0, &Ql, TMPDTFS_FX ); /* Q of Ltemp = 2*(TMPDTFS_FX->Q) = Ql ? */ + move32(); /* Compensate for Q factor of energy to get log10(lag*eng) */ Ltemp = log10_fx( Ltemp ); /* Ltemp=10log10(eng), Q23 */ Ltemp = L_add( L_sub( Ltemp, Ltemp_q ), logLag ); /* Ltemp=10*log10(lag*eng), Q23 */ /*hSC_VBR->lastLgainE_fx=round_fx(L_shl((Word32)Mpy_32_16(extract_h(Ltemp),extract_l(Ltemp),0x6666),1)); // Q11, 0x6666 = 0.1 in Q18 */ hSC_VBR->lastLgainE_fx = round_fx( L_shl( Mult_32_16( Ltemp, 0x6666 ), 1 ) ); /* Q11, 0x6666 = 0.1 in Q18 */ - + move16(); /* Process high band */ Ltemp = DTFS_setEngyHarm_fx( 2828, upper_cut_off_freq_of_interest_norm_fx, 2828, upper_cut_off_freq_norm_fx, 1, 0, &Qh, TMPDTFS_FX ); + move32(); Ltemp = log10_fx( Ltemp ); Ltemp = L_add( L_sub( Ltemp, Ltemp_q ), logLag ); /* Ltemp=10*log10(lag*eng), Q23 */ hSC_VBR->lastHgainE_fx = round_fx( L_shl( Mult_32_16( Ltemp, 0x6666 ), 1 ) ); /* Q11 */ - + move16(); /* Need to unify the Q factors of both bands */ TMPDTFS_FX->Q = s_min( Ql, Qh ); move16(); /* set Q factor to be the smaller one of Ql and Qh */ @@ -380,11 +397,11 @@ ivas_error ppp_voiced_encoder_fx( { /* Copy DTFS related parameters from 'st_fx' to 'dtfs_temp' structure */ dtfs_temp_fx->lag_fx = hSC_VBR->dtfs_enc_lag; - move16(); + move16(); /*Q0*/ dtfs_temp_fx->nH_fx = hSC_VBR->dtfs_enc_nH; - move16(); + move16(); /*Q0*/ dtfs_temp_fx->nH_4kHz_fx = hSC_VBR->dtfs_enc_nH_4kHz; - move16(); + move16(); /*Q0*/ dtfs_temp_fx->upper_cut_off_freq_of_interest_fx = hSC_VBR->dtfs_enc_upper_cut_off_freq_of_interest_fx; move16(); dtfs_temp_fx->upper_cut_off_freq_fx = hSC_VBR->dtfs_enc_upper_cut_off_freq_fx; @@ -396,6 +413,7 @@ ivas_error ppp_voiced_encoder_fx( dtfs_temp_fx->Q = hSC_VBR->dtfs_enc_Q; move16(); Lacc1 = DTFS_getEngy_P2A_fx( dtfs_temp_fx ); + move32(); prev_Engy = L_add( Lacc1, 0 ); } @@ -457,14 +475,14 @@ ivas_error ppp_voiced_encoder_fx( DTFS_copy_fx( TMPDTFS2_FX, *dtfs_temp_fx ); /* output = TMPDTFS2_FX with Q = dtfs_temp_fx->Q */ tmptmp = DTFS_alignment_full_fx( *TMPDTFS2_FX, *TMPDTFS_FX, hSC_VBR->ph_offset_E_fx, S_fx, C_fx, 0 ); - + move16(); tmptmp1 = sub( shl( TMPDTFS_FX->lag_fx, 1 ), tmptmp ); /* (C_l-tmptmp) , Q1 */ Q2phaseShift_fx( TMPDTFS_FX, negate( shl( tmptmp1, 1 ) ), TMPDTFS_FX->lag_fx, S_fx, C_fx ); /* fixed bug , phase shift by tmp computed in_fx TMP.lag domain (above) */ /*tmpres = (float)(DTFS_freq_corr(*TMPDTFS, *TMPDTFS2, 100.0f, 3700.0f));*/ tmpres_fx = DTFS_freq_corr_fx( *TMPDTFS_FX, *TMPDTFS2_FX, 100, 3700, &Qtmpres ); /* tmpres_fx has Q factor tmpres */ - + move32(); poleFilter_setup_fx( lpc2_fx, M + 1, *TMPDTFS_FX, S_fx, C_fx, pf_temp1, pf_temp2, pf_temp, pf_n2 ); DTFS_poleFilter_fx_9( TMPDTFS_FX, pf_temp1, pf_temp2, pf_temp, pf_n2 ); @@ -475,6 +493,7 @@ ivas_error ppp_voiced_encoder_fx( DTFS_poleFilter_fx( TMPDTFS2_FX, lpc1_fx, M + 1, S_fx, C_fx ); /* lpc1_fx in Q12 */ tmp_fx = DTFS_freq_corr_fx( *TMPDTFS_FX, *TMPDTFS2_FX, 100, 3700, &Qtmp ); + move32(); /* tmp_fx Q = Qtmp */ @@ -489,11 +508,14 @@ ivas_error ppp_voiced_encoder_fx( } *******************************************************************************/ Ltmp_32 = ( DTFS_getEngy_fx( TMPDTFS2_FX ) ); /* Output Q=2*(TMPDTFS2_FX->Q) */ + move32(); IF( Ltmp_32 > 0 ) { /*sp_enratio = DTFS_getEngy(*TMPDTFS)/DTFS_getEngy(*TMPDTFS2); in Q15 */ Lacc = DTFS_getEngy_P2A_fx( TMPDTFS_FX ); + move32(); Lacc1 = Ltmp_32; + move32(); /* IF (L_sub(sp_enratio_fx,0x7FFF)!=0) */ { expb = norm_l( Lacc ); @@ -512,11 +534,7 @@ ivas_error ppp_voiced_encoder_fx( tmp = div_s( fracb, fraca ); exp = sub( expb, expa ); -#ifdef BASOP_NOGLOB sp_enratio_fx = L_shl_sat( tmp, exp ); /* Q15 */ -#else - sp_enratio_fx = L_shl( tmp, exp ); /* Q15 */ -#endif } } ELSE @@ -540,20 +558,12 @@ ivas_error ppp_voiced_encoder_fx( } /* Bump up if big change between the previous and the current CWs */ -#ifdef BASOP_NOGLOB IF( LT_16( shl_o( hSC_VBR->vadsnr_fx, 1, &Overflow ), hSC_VBR->SNR_THLD_fx ) ) /*Q8 */ -#else - IF( LT_16( shl( hSC_VBR->vadsnr_fx, 1 ), hSC_VBR->SNR_THLD_fx ) ) /*Q8 */ -#endif { /*if ( res_enratio > 5.0 && tmp < 0.65 ) */ /* 5 in Q11, 0.65 in Q15 // L_shl(tmp_fx,sub(31,Qtmp)) makes tmp_fx FIXED Q31 */ test(); -#ifdef BASOP_NOGLOB - IF( ( GT_32( res_enratio_fx, 10240 ) ) && ( LT_16( extract_h( L_shl_o( tmp_fx, sub( 31, Qtmp ), &Overflow ) ), 21299 ) ) ) -#else - IF( ( GT_32( res_enratio_fx, 10240 ) ) && ( LT_16( extract_h( L_shl( tmp_fx, sub( 31, Qtmp ) ) ), 21299 ) ) ) -#endif + if ( ( GT_32( res_enratio_fx, 10240 ) ) && ( LT_16( extract_h( L_shl_o( tmp_fx, sub( 31, Qtmp ), &Overflow ) ), 21299 ) ) ) { PPP_MODE_E = 'B'; move16(); @@ -564,11 +574,7 @@ ivas_error ppp_voiced_encoder_fx( /* if ( res_enratio > 3.0 && tmp < 1.2 ) */ /*3 in Q11, 1.2 in Q14 // L_shl(tmp_fx,sub(31,Qtmp)) makes tmp_fx FIXED Q14 */ test(); -#ifdef BASOP_NOGLOB - IF( ( GT_32( res_enratio_fx, 6144 ) ) && ( LT_16( extract_h( L_shl_o( tmp_fx, sub( 30, Qtmp ), &Overflow ) ), 19661 ) ) ) -#else - IF( ( GT_32( res_enratio_fx, 6144 ) ) && ( LT_16( extract_h( L_shl( tmp_fx, sub( 30, Qtmp ) ) ), 19661 ) ) ) -#endif + if ( ( GT_32( res_enratio_fx, 6144 ) ) && ( LT_16( extract_h( L_shl_o( tmp_fx, sub( 30, Qtmp ), &Overflow ) ), 19661 ) ) ) { PPP_MODE_E = 'B'; move16(); @@ -579,18 +585,10 @@ ivas_error ppp_voiced_encoder_fx( /* Rapid rampdown frame where time resolution is important */ /* Not a suitable PPP frame -> Bump to CELP */ -#ifdef BASOP_NOGLOB IF( LT_16( shl_o( hSC_VBR->vadsnr_fx, 1, &Overflow ), hSC_VBR->SNR_THLD_fx ) ) /*Q8 */ -#else - IF( LT_16( shl( hSC_VBR->vadsnr_fx, 1 ), hSC_VBR->SNR_THLD_fx ) ) /*Q8 */ -#endif { /* if (res_enratio < 0.025) */ -#ifdef BASOP_NOGLOB IF( LT_32( L_shl_o( res_enratio_fx, 4, &Overflow ), 819 ) ) /*0x0333 = 0.025 in Q15, res_enratio_fx in Q15 after shl 4 */ -#else - IF( LT_32( L_shl( res_enratio_fx, 4 ), 819 ) ) /*0x0333 = 0.025 in Q15, res_enratio_fx in Q15 after shl 4 */ -#endif { hSC_VBR->bump_up = 1; move16(); @@ -606,11 +604,7 @@ ivas_error ppp_voiced_encoder_fx( ELSE { /* if ( res_enratio < 0.092f) */ -#ifdef BASOP_NOGLOB if ( LT_32( L_shl_o( res_enratio_fx, 4, &Overflow ), 3015 ) ) /*3015 = 0.092 in Q15, res_enratio_fx in Q15 after shl 4 */ -#else - if ( LT_32( L_shl( res_enratio_fx, 4 ), 3015 ) ) /*3015 = 0.092 in Q15, res_enratio_fx in Q15 after shl 4 */ -#endif { hSC_VBR->bump_up = 1; move16(); @@ -619,11 +613,7 @@ ivas_error ppp_voiced_encoder_fx( /* if (min(res_enratio, sp_enratio) < 0.075 && tmp < -0.5f)) : 2458 = 0.075 in Q15 */ test(); -#ifdef BASOP_NOGLOB if ( LT_32( L_min( L_shl_o( res_enratio_fx, 4, &Overflow ), sp_enratio_fx ), 2458 ) && LT_32( tmp_fx, shl_o( -1, sub( Qtmp, 1 ), &Overflow ) ) ) -#else - if ( LT_32( L_min( L_shl( res_enratio_fx, 4 ), sp_enratio_fx ), 2458 ) && LT_32( tmp_fx, shl( -1, sub( Qtmp, 1 ) ) ) ) -#endif { hSC_VBR->bump_up = 1; move16(); @@ -631,11 +621,7 @@ ivas_error ppp_voiced_encoder_fx( /* Rapid rampup frame where time resolution is important */ /* Not a suitable PPP frame -> Bump to CELP */ -#ifdef BASOP_NOGLOB IF( LT_16( shl_o( hSC_VBR->vadsnr_fx, 1, &Overflow ), hSC_VBR->SNR_THLD_fx ) ) /*Q8 */ -#else - IF( LT_16( shl( hSC_VBR->vadsnr_fx, 1 ), hSC_VBR->SNR_THLD_fx ) ) /*Q8 */ -#endif { IF( GT_32( res_enratio_fx, 29696 ) ) /*14.5 in Q11 */ { @@ -659,7 +645,7 @@ ivas_error ppp_voiced_encoder_fx( } } - IF( hSC_VBR->bump_up == 1 ) + IF( EQ_16( hSC_VBR->bump_up, 1 ) ) { free( CURRP_NQ_FX ); free( TMPDTFS_FX ); @@ -692,7 +678,7 @@ ivas_error ppp_voiced_encoder_fx( move16(); IF( EQ_16( PPP_MODE_E, 'Q' ) ) { - if ( ( error = ppp_quarter_encoder_fx( &flag, CURRP_Q_E_FX, TMPDTFS_FX, dtfs_temp_fx->lag_fx, *CURRP_NQ_FX, lpc2_fx, &hSC_VBR->lastLgainE_fx, &hSC_VBR->lastHgainE_fx, hSC_VBR->lasterbE_fx, *dtfs_temp_fx, S_fx, C_fx, hBstr ) ) != IVAS_ERR_OK ) + IF( ( error = ppp_quarter_encoder_fx( &flag, CURRP_Q_E_FX, TMPDTFS_FX, dtfs_temp_fx->lag_fx, *CURRP_NQ_FX, lpc2_fx, &hSC_VBR->lastLgainE_fx, &hSC_VBR->lastHgainE_fx, hSC_VBR->lasterbE_fx, *dtfs_temp_fx, S_fx, C_fx, hBstr ) ) != IVAS_ERR_OK ) { free( CURRP_NQ_FX ); free( TMPDTFS_FX ); @@ -728,11 +714,13 @@ ivas_error ppp_voiced_encoder_fx( IF( GT_16( CURRP_Q_E_FX->upper_cut_off_freq_fx, 4000 ) ) { Ltemp2 = DTFS_getEngy_band_wb_fx( *CURRP_Q_E_FX, 0, 2000 ); + move32(); /* Use this bump-up only for WB signals */ IF( Ltemp2 > 0 ) { /* sp_hb_enratio = DTFS_getEngy_band_wb(*CURRP_Q_E, 2000.0, 6400.0)/DTFS_getEngy_band_wb(*CURRP_Q_E, 0.0, 2000.0); */ Ltemp1 = DTFS_getEngy_band_wb_fx( *CURRP_Q_E_FX, 2000, 6400 ); /*Q13 */ + move32(); /*sp_hb_enratio_fx = divide_dp(Ltemp1,Ltemp2,0, 1);//Q29 */ Qadj = 0; move16(); @@ -744,11 +732,7 @@ ivas_error ppp_voiced_encoder_fx( Ltemp1 = L_negate( Ltemp1 ); } expa = norm_l( Ltemp2 ); -#ifdef BASOP_NOGLOB fraca = extract_h( L_shl_o( Ltemp2, expa, &Overflow ) ); -#else - fraca = extract_h( L_shl( Ltemp2, expa ) ); -#endif expa = sub( 30, expa ); expb = norm_l( Ltemp1 ); @@ -756,20 +740,12 @@ ivas_error ppp_voiced_encoder_fx( expb = sub( 30, add( expb, Qadj ) ); scale = shr( sub( fraca, fracb ), 15 ); -#ifdef BASOP_NOGLOB fracb = shl_o( fracb, scale, &Overflow ); -#else - fracb = shl( fracb, scale ); -#endif expb = sub( expb, scale ); tmp = div_s( fracb, fraca ); exp = sub( expb, expa ); -#ifdef BASOP_NOGLOB Ltemp_fx = L_shl_o( tmp, add( exp, 14 ), &Overflow ); -#else - Ltemp_fx = L_shl( tmp, add( exp, 14 ) ); -#endif /*-------------------------------------------*/ sp_hb_enratio_fx = L_add( Ltemp_fx, 0 ); /* Q29 */ } @@ -778,11 +754,11 @@ ivas_error ppp_voiced_encoder_fx( sp_hb_enratio_fx = L_deposit_l( 0 ); } low_band_en_fx = Ltemp2; /*Q13 */ - + move32(); /* if ( low_band_en < 25.0f && sp_hb_enratio < 1.6f ) */ /* 25.0 in Q13 = 204800, 1.6 in Q29 = 858993459 */ test(); - IF( LT_32( low_band_en_fx, 204800 ) && LT_32( sp_hb_enratio_fx, 858993459 ) ) + if ( LT_32( low_band_en_fx, 204800 ) && LT_32( sp_hb_enratio_fx, 858993459 ) ) { PPP_MODE_E = 'B'; move16(); @@ -790,21 +766,14 @@ ivas_error ppp_voiced_encoder_fx( } Ltmp_32 = DTFS_getEngy_fx( CURRP_NQ_FX ); /*Q = 2*(CURRP_NQ_FX->Q) */ + move32(); Qadj = sub( hSC_VBR->Q_prev_cw_en_fx, shl( CURRP_NQ_FX->Q, 1 ) ); -#ifdef BASOP_NOGLOB Ltmp_32 = L_shl_o( Ltmp_32, Qadj, &Overflow ); /* shift left required to adjust Q of CURRP_NQ_FX = Q_prev_cw_en_fx */ -#else - Ltmp_32 = L_shl( Ltmp_32, Qadj ); /* shift left required to adjust Q of CURRP_NQ_FX = Q_prev_cw_en_fx */ -#endif /* Ltmp1_32 = 0.8f * st->prev_cw_en */ Ltmp1_32 = Mult_32_16( hSC_VBR->prev_cw_en_fx, 26214 ); /* Q = (Q_prev_cw_en_fx + Q15+1)-Q16 = Q_prev_cw_en_fx */ -#ifdef BASOP_NOGLOB IF( LT_16( shl_o( hSC_VBR->vadsnr_fx, 1, &Overflow ), hSC_VBR->SNR_THLD_fx ) ) /*Q8 */ -#else - IF( LT_16( shl( hSC_VBR->vadsnr_fx, 1 ), hSC_VBR->SNR_THLD_fx ) ) /*Q8 */ -#endif { /* if ( DTFS_getEngy(*CURRP_NQ) > 0.8f * st->prev_cw_en && max(pos_nq, neg_nq) > 3.0f && st->rate_control ) */ /* pos_nq_fx and neg_nq_fx in Q28 ???? */ @@ -814,7 +783,7 @@ ivas_error ppp_voiced_encoder_fx( { /*if ( pos_nq > neg_nq && pos_nq > 2.0f * pos_q ) */ test(); - IF( GT_32( pos_nq_fx, neg_nq_fx ) && GT_32( Mult_32_16( pos_nq_fx, 16384 ), pos_q_fx ) ) + if ( GT_32( pos_nq_fx, neg_nq_fx ) && GT_32( Mult_32_16( pos_nq_fx, 16384 ), pos_q_fx ) ) { PPP_MODE_E = 'B'; move16(); @@ -822,7 +791,7 @@ ivas_error ppp_voiced_encoder_fx( test(); /*if ( pos_nq < neg_nq && neg_nq > 2.0f * neg_q ) */ - IF( LT_32( pos_nq_fx, neg_nq_fx ) && GT_32( Mult_32_16( neg_nq_fx, 16384 ), neg_q_fx ) ) + if ( LT_32( pos_nq_fx, neg_nq_fx ) && GT_32( Mult_32_16( neg_nq_fx, 16384 ), neg_q_fx ) ) { PPP_MODE_E = 'B'; move16(); @@ -849,8 +818,8 @@ ivas_error ppp_voiced_encoder_fx( test(); test(); test(); - IF( ( GT_32( pos_nq_fx, neg_nq_fx ) && GT_32( Mult_32_16( pos_nq_fx, 13107 ), pos_q_fx ) && ( hSC_VBR->rate_control ) ) || - ( GT_32( pos_nq_fx, neg_nq_fx ) && GT_32( Mult_32_16( pos_nq_fx, 16384 ), pos_q_fx ) && ( !hSC_VBR->rate_control ) ) ) + if ( ( GT_32( pos_nq_fx, neg_nq_fx ) && GT_32( Mult_32_16( pos_nq_fx, 13107 ), pos_q_fx ) && ( hSC_VBR->rate_control ) ) || + ( GT_32( pos_nq_fx, neg_nq_fx ) && GT_32( Mult_32_16( pos_nq_fx, 16384 ), pos_q_fx ) && ( !hSC_VBR->rate_control ) ) ) { PPP_MODE_E = 'B'; move16(); @@ -863,8 +832,8 @@ ivas_error ppp_voiced_encoder_fx( test(); test(); test(); - IF( ( LT_32( pos_nq_fx, neg_nq_fx ) && GT_32( Mult_32_16( neg_nq_fx, 13107 ), neg_q_fx ) && ( hSC_VBR->rate_control ) ) || - ( LT_32( pos_nq_fx, neg_nq_fx ) && GT_32( Mult_32_16( neg_nq_fx, 16384 ), neg_q_fx ) && ( !hSC_VBR->rate_control ) ) ) + if ( ( LT_32( pos_nq_fx, neg_nq_fx ) && GT_32( Mult_32_16( neg_nq_fx, 13107 ), neg_q_fx ) && ( hSC_VBR->rate_control ) ) || + ( LT_32( pos_nq_fx, neg_nq_fx ) && GT_32( Mult_32_16( neg_nq_fx, 16384 ), neg_q_fx ) && ( !hSC_VBR->rate_control ) ) ) { PPP_MODE_E = 'B'; move16(); @@ -905,11 +874,7 @@ ivas_error ppp_voiced_encoder_fx( /* compute energy of impz */ FOR( x_fx = 0; x_fx < 160; x_fx++ ) { -#ifdef BASOP_NOGLOB energy_impz_fx = L_add_o( energy_impz_fx, L_mult0( impzo_fx[x_fx], impzo_fx[x_fx] ), &Overflow ); -#else - energy_impz_fx = L_add( energy_impz_fx, L_mult0( impzo_fx[x_fx], impzo_fx[x_fx] ) ); -#endif } /*energy_impz = (float)(10*log10((float)energy_impz)); */ @@ -921,27 +886,20 @@ ivas_error ppp_voiced_encoder_fx( /* energy_impz_fx is Q11 */ Ltmp_32 = DTFS_getEngy_fx( CURRP_Q_E_FX ); /*Q = 2*(CURRP_Q_E_FX->Q) */ + move32(); Qadj = sub( hSC_VBR->Q_prev_cw_en_fx, shl( CURRP_Q_E_FX->Q, 1 ) ); -#ifdef BASOP_NOGLOB Ltmp_32 = L_shl_o( Ltmp_32, Qadj, &Overflow ); /* shift left required to adjust Q of CURRP_Q_E_FX = Q_prev_cw_en_fx */ -#else - Ltmp_32 = L_shl( Ltmp_32, Qadj ); /* shift left required to adjust Q of CURRP_Q_E_FX = Q_prev_cw_en_fx */ -#endif /* if ((DTFS_getEngy(*CURRP_Q_E) > st->prev_cw_en)&&(max(pos_q,neg_q)>3.5) && energy_impz>15.0 && tmpres>0.7) */ test(); test(); test(); -#ifdef BASOP_NOGLOB IF( ( GT_32( Ltmp_32, hSC_VBR->prev_cw_en_fx ) ) && ( GT_32( L_max( pos_q_fx, neg_q_fx ), 939524096 ) ) && ( GT_32( energy_impz_fx, 30720 ) ) && ( GT_32( Mult_32_16( tmpres_fx, 23265 ), shl_o( 1, sub( Qtmpres, 1 ), &Overflow ) ) ) ) -#else - IF( ( GT_32( Ltmp_32, hSC_VBR->prev_cw_en_fx ) ) && ( GT_32( L_max( pos_q_fx, neg_q_fx ), 939524096 ) ) && ( GT_32( energy_impz_fx, 30720 ) ) && ( GT_32( Mult_32_16( tmpres_fx, 23265 ), shl( 1, sub( Qtmpres, 1 ) ) ) ) ) -#endif { /* if ((pos_q > neg_q) && ((pos_q>3.0*pos_nq0) || ((pos_q > 1.5*pos_nq0) && (neg_q < 1.5*neg_nq0)))) */ test(); test(); test(); - IF( ( GT_32( pos_q_fx, neg_q_fx ) ) && ( ( GT_32( Mult_32_16( pos_q_fx, 10923 ), L_shr( pos_nq0_fx, sub( Qposnq, 28 ) ) ) ) || ( ( GT_32( Mult_32_16( pos_q_fx, 21845 ), L_shr( pos_nq0_fx, sub( Qposnq, 28 ) ) ) ) && ( LT_32( Mult_32_16( neg_q_fx, 21846 ), L_shr( neg_nq0_fx, sub( Qnegnq, 28 ) ) ) ) ) ) ) + if ( ( GT_32( pos_q_fx, neg_q_fx ) ) && ( ( GT_32( Mult_32_16( pos_q_fx, 10923 ), L_shr( pos_nq0_fx, sub( Qposnq, 28 ) ) ) ) || ( ( GT_32( Mult_32_16( pos_q_fx, 21845 ), L_shr( pos_nq0_fx, sub( Qposnq, 28 ) ) ) ) && ( LT_32( Mult_32_16( neg_q_fx, 21846 ), L_shr( neg_nq0_fx, sub( Qnegnq, 28 ) ) ) ) ) ) ) /* 10923 = (1/3) oin Q15, pos_q_fx is Q28, so result of Mult_32_16(pos_q_fx,10923) = Q28 */ /* L_shr(pos_nq0_fx,sub(Qposnq,28)) brings pos_nq0_fx with variable Q to fixed Q28 */ { @@ -952,7 +910,7 @@ ivas_error ppp_voiced_encoder_fx( test(); test(); /* if ((pos_q <= neg_q) && ((neg_q>3.0*neg_nq0)|| ((neg_q > 1.5*neg_nq0) && (pos_q < 1.5*pos_nq0)))) */ - IF( ( LE_32( pos_q_fx, neg_q_fx ) ) && ( ( GT_32( Mult_32_16( neg_q_fx, 10923 ), L_shr( neg_nq0_fx, sub( Qnegnq, 28 ) ) ) ) || ( ( GT_32( Mult_32_16( neg_q_fx, 21846 ), L_shr( neg_nq0_fx, sub( Qnegnq, 28 ) ) ) ) && ( LT_32( Mult_32_16( pos_q_fx, 21846 ), L_shr( pos_nq0_fx, sub( Qposnq, 28 ) ) ) ) ) ) ) + if ( ( LE_32( pos_q_fx, neg_q_fx ) ) && ( ( GT_32( Mult_32_16( neg_q_fx, 10923 ), L_shr( neg_nq0_fx, sub( Qnegnq, 28 ) ) ) ) || ( ( GT_32( Mult_32_16( neg_q_fx, 21846 ), L_shr( neg_nq0_fx, sub( Qnegnq, 28 ) ) ) ) && ( LT_32( Mult_32_16( pos_q_fx, 21846 ), L_shr( pos_nq0_fx, sub( Qposnq, 28 ) ) ) ) ) ) ) { PPP_MODE_E = 'B'; move16(); @@ -971,11 +929,13 @@ ivas_error ppp_voiced_encoder_fx( /* operate in ADR mode only the rate control is active. This adds some bumpups to improve the speech quality */ /* if ((DTFS_getEngy_band(*TMPDTFS, 1500.0, upper_cut_off_freq_of_interest)/DTFS_getEngy(*TMPDTFS) > 0.05)&&(!st->rate_control)) */ Ltemp1 = DTFS_getEngy_band_fx( *TMPDTFS_FX, 1500, upper_cut_off_freq_of_interest_fx ); /* Q = 2*TMPDTFS_FX->Q*/ - Ltemp2 = DTFS_getEngy_fx( TMPDTFS_FX ); /* Q = 2*TMPDTFS_FX->Q */ - + move32(); + Ltemp2 = DTFS_getEngy_fx( TMPDTFS_FX ); /* Q = 2*TMPDTFS_FX->Q */ + move32(); IF( Ltemp2 == 0 ) { Ltemp_fx = 0; + move32(); } ELSE { @@ -990,13 +950,9 @@ ivas_error ppp_voiced_encoder_fx( fracb = shl( fracb, scale ); expb = sub( expb, scale ); - tmp = div_s( fracb, fraca ); /* tmp in Q15 */ - exp = sub( expb, expa ); /* ans = tmp*2^(exp) */ -#ifdef BASOP_NOGLOB + tmp = div_s( fracb, fraca ); /* tmp in Q15 */ + exp = sub( expb, expa ); /* ans = tmp*2^(exp) */ Ltemp_fx = L_shl_o( tmp, add( exp, 12 ), &Overflow ); /* make tmp Q27 */ -#else - Ltemp_fx = L_shl( tmp, add( exp, 12 ) ); /* make tmp Q27 */ -#endif } test(); IF( GT_32( Ltemp_fx, 6710886 ) && ( !hSC_VBR->rate_control ) ) /* 0.05 in Q27 = 6710886 */ @@ -1005,14 +961,16 @@ ivas_error ppp_voiced_encoder_fx( /*DTFS_getEngy_band(*TMPDTFS3,1500.0,upper_cut_off_freq_of_interest)) < 0.1) */ Ltemp1 = DTFS_getEngy_band_fx( *TMPDTFS_FX, 1500, upper_cut_off_freq_of_interest_fx ); + move32(); Ltemp2 = DTFS_getEngy_band_fx( *TMPDTFS3_FX, 1500, upper_cut_off_freq_of_interest_fx ); - + move32(); /*--------------------------------------------------------------*/ /* Ltemp_fx = (Word32)divide_dp(Ltemp1, Ltemp2, Qadj,1);//Q29+1 */ /*--------------------------------------------------------------*/ IF( Ltemp2 == 0 ) { Ltemp_fx = 0; + move32(); } ELSE { @@ -1030,11 +988,7 @@ ivas_error ppp_voiced_encoder_fx( tmp = div_s( fracb, fraca ); exp = sub( expb, expa ); -#ifdef BASOP_NOGLOB Ltemp_fx = L_shl_o( tmp, add( exp, 14 ), &Overflow ); /* answer in Q29 */ -#else - Ltemp_fx = L_shl( tmp, add( exp, 14 ) ); /* answer in Q29 */ -#endif } /*-------------------------------------------*/ @@ -1057,9 +1011,10 @@ ivas_error ppp_voiced_encoder_fx( /* To increase bump up, raise first threshold, lower second */ /*tmp = (float)(10.0*log10(DTFS_getEngy(*TMPDTFS)/DTFS_getEngy(*TMPDTFS3)));*/ - Lacc = DTFS_getEngy_P2A_fx( TMPDTFS_FX ); /* Q = 2*(TMPDTFS_FX->Q) */ + Lacc = DTFS_getEngy_P2A_fx( TMPDTFS_FX ); /* Q = 2*(TMPDTFS_FX->Q) */ + move32(); Lacc1 = DTFS_getEngy_P2A_fx( TMPDTFS3_FX ); /* Q = 2*(TMPDTFS3_FX->Q) */ - + move32(); sft = shl( sub( TMPDTFS_FX->Q, TMPDTFS3_FX->Q ), 1 ); /* to check if Lacc<=2*Lacc1 */ flag1 = 0; @@ -1100,12 +1055,8 @@ ivas_error ppp_voiced_encoder_fx( L_tmp = L_shl( L_tmp, expa ); exp = sub( 30, add( expa, sub( 31, exp ) ) ); frac = Log2_norm_lc( L_tmp ); - L_tmp = Mpy_32_16( exp, frac, 12330 ); /* L_tmp is always Q13 */ -#ifdef BASOP_NOGLOB + L_tmp = Mpy_32_16( exp, frac, 12330 ); /* L_tmp is always Q13 */ Ltemp = L_shl_o( L_tmp, 10, &Overflow ); /* Ltemp is always Q23 */ -#else - Ltemp = L_shl( L_tmp, 10 ); /* Ltemp is always Q23 */ -#endif } ELSE { @@ -1119,11 +1070,7 @@ ivas_error ppp_voiced_encoder_fx( move16(); } -#ifdef BASOP_NOGLOB IF( LT_16( shl_o( hSC_VBR->vadsnr_fx, 1, &Overflow ), hSC_VBR->SNR_THLD_fx ) ) /* Q8 */ -#else - IF( LT_16( shl( hSC_VBR->vadsnr_fx, 1 ), hSC_VBR->SNR_THLD_fx ) ) /* Q8 */ -#endif { /* if ((( tmp < 3.05 && max(res_enratio,sp_enratio) > 0.8 ) && (st->rate_control))|| (( tmp < 2.8 && max(res_enratio,sp_enratio) > 0.65 ) && (!st->rate_control))) */ @@ -1168,7 +1115,7 @@ ivas_error ppp_voiced_encoder_fx( ELSE { } - if ( PPP_MODE_E == 'B' ) + IF( PPP_MODE_E == 'B' ) { hSC_VBR->bump_up = 1; move16(); @@ -1184,10 +1131,12 @@ ivas_error ppp_voiced_encoder_fx( IF( hSC_VBR->Q_to_F ) { hSC_VBR->patterncount = add( hSC_VBR->patterncount, hSC_VBR->pattern_m ); + move16(); IF( GE_16( hSC_VBR->patterncount, 1000 ) ) { hSC_VBR->patterncount = sub( hSC_VBR->patterncount, 1000 ); + move16(); PPP_MODE_E = 'B'; move16(); hSC_VBR->bump_up = 1; @@ -1216,8 +1165,9 @@ ivas_error ppp_voiced_encoder_fx( DTFS_copy_fx( dtfs_temp_fx, *CURRP_Q_E_FX ); Lacc = DTFS_getEngy_P2A_fx( CURRP_NQ_FX ); + move32(); hSC_VBR->Q_prev_cw_en_fx = norm_l( Lacc ); - + move16(); /* hSC_VBR->Q_prev_cw_en_fx = (Lacc==0)?31: hSC_VBR->Q_prev_cw_en_fx;move16(); */ if ( Lacc == 0 ) { @@ -1226,7 +1176,9 @@ ivas_error ppp_voiced_encoder_fx( } hSC_VBR->prev_cw_en_fx = (Word32) L_shl( Lacc, hSC_VBR->Q_prev_cw_en_fx ); /*2Q+Q_prev_cw_en_fx */ + move32(); hSC_VBR->Q_prev_cw_en_fx = add( hSC_VBR->Q_prev_cw_en_fx, shl( CURRP_NQ_FX->Q, 1 ) ); + move16(); /* Copy DTFS related parameters from 'dtfs_temp' to 'st_fx' structure */ hSC_VBR->dtfs_enc_lag = dtfs_temp_fx->lag_fx; move16(); @@ -1289,6 +1241,7 @@ static void synthesis_filter_fx( Word16 b[], Word16 x[], Word16 y[], Word16 buf[ Word16 i, j; #ifdef BASOP_NOGLOB_DECLARE_LOCAL Flag Overflow = 0; + move32(); #endif FOR( i = 0; i < N; i++ ) { @@ -1298,28 +1251,18 @@ static void synthesis_filter_fx( Word16 b[], Word16 x[], Word16 y[], Word16 buf[ FOR( j = P - 1; j > 0; j-- ) { /* acc = L_sub(acc, L_mult(memory[j], coef[j])); */ -#ifdef BASOP_NOGLOB acc = L_msu_o( acc, buf[j], b[j], &Overflow ); /*Q13 */ -#else - acc = L_msu( acc, buf[j], b[j] ); /*Q13 */ -#endif buf[j] = buf[j - 1]; move16(); } /* acc = L_sub(acc, L_mult(memory[0], coef[0])); */ -#ifdef BASOP_NOGLOB acc = L_msu_o( acc, buf[0], b[0], &Overflow ); acc = L_shl_o( acc, 3, &Overflow ); *y++ = round_fx_o( acc, &Overflow ); + move16(); buf[0] = round_fx_o( acc, &Overflow ); -#else - acc = L_msu( acc, buf[0], b[0] ); - acc = L_shl( acc, 3 ); - - *y++ = round_fx( acc ); - buf[0] = round_fx( acc ); -#endif + move16(); } } /*==============================================================================*/ @@ -1364,6 +1307,7 @@ static Word32 DTFS_freq_corr_fx( Word16 Q_num, Q_den; #ifdef BASOP_NOGLOB_DECLARE_LOCAL Flag Overflow = 0; + move32(); #endif IF( LT_16( X1_DTFS_fx.lag_fx, X2_DTFS_fx.lag_fx ) ) { @@ -1372,15 +1316,15 @@ static Word32 DTFS_freq_corr_fx( corr_fx = L_deposit_l( 0 ); - L_lband = L_mult( lband, X2_DTFS_fx.lag_fx ); - L_hband = L_mult( hband, X2_DTFS_fx.lag_fx ); + L_lband = L_mult( lband, X2_DTFS_fx.lag_fx ); /* Q0 * Q0 -> Q1 */ + L_hband = L_mult( hband, X2_DTFS_fx.lag_fx ); /* Q0 * Q0 -> Q1 */ HalfLag = s_min( shr( X2_DTFS_fx.lag_fx, 1 ), X2_DTFS_fx.nH_4kHz_fx ); /* get lband and hband */ FOR( k = 0; k <= HalfLag; k++ ) { freq_fx = L_mult( k, 12800 ); - IF( GE_32( freq_fx, L_lband ) ) + if ( GE_32( freq_fx, L_lband ) ) { BREAK; } @@ -1389,7 +1333,7 @@ static Word32 DTFS_freq_corr_fx( FOR( k = 0; k <= HalfLag; k++ ) { freq_fx = L_mult( k, 12800 ); - IF( GE_32( freq_fx, L_hband ) ) + if ( GE_32( freq_fx, L_hband ) ) { BREAK; } @@ -1399,13 +1343,8 @@ static Word32 DTFS_freq_corr_fx( FOR( k = lk; k < hk; k++ ) { -#ifdef BASOP_NOGLOB corr_fx = L_mac0_o( corr_fx, X1_DTFS_fx.a_fx[k], X2_DTFS_fx.a_fx[k], &Overflow ); /* Q(1) */ corr_fx = L_mac0_o( corr_fx, X1_DTFS_fx.b_fx[k], X2_DTFS_fx.b_fx[k], &Overflow ); /* Q(1) */ -#else - corr_fx = L_mac0( corr_fx, X1_DTFS_fx.a_fx[k], X2_DTFS_fx.a_fx[k] ); /* Q(1) */ - corr_fx = L_mac0( corr_fx, X1_DTFS_fx.b_fx[k], X2_DTFS_fx.b_fx[k] ); /* Q(1) */ -#endif } Qr = norm_l( corr_fx ); @@ -1415,16 +1354,13 @@ static Word32 DTFS_freq_corr_fx( move16(); } -#ifdef BASOP_NOGLOB E1_fx = round_fx_o( L_shl_o( corr_fx, Qr, &Overflow ), &Overflow ); /* Q(Qr-16) */ -#else - E1_fx = round_fx( L_shl( corr_fx, Qr ) ); /* Q(Qr-16) */ -#endif - Num = L_mult0( E1_fx, E1_fx ); /* Q(2+2*Qr-32+1) */ + Num = L_mult0( E1_fx, E1_fx ); /* Q(2+2*Qr-32+1) */ Q_num = sub( shl( add( add( X1_DTFS_fx.Q, X2_DTFS_fx.Q ), Qr ), 1 ), 32 ); /* PORTING: Handling the functions with variable no. of arguments */ E_fx = DTFS_getEngy_band_fx( X1_DTFS_fx, lband, hband ); /* Q(1) */ + move32(); q1 = norm_l( E_fx ); if ( E_fx == 0 ) { @@ -1432,11 +1368,7 @@ static Word32 DTFS_freq_corr_fx( move16(); } -#ifdef BASOP_NOGLOB E1_fx = round_fx_o( L_shl_o( E_fx, q1, &Overflow ), &Overflow ); /* Q(1+q1-16) */ -#else - E1_fx = round_fx( L_shl( E_fx, q1 ) ); /* Q(1+q1-16) */ -#endif /* PORTING: Handling the functions with variable no. of arguments */ E_fx = DTFS_getEngy_band_fx( X2_DTFS_fx, lband, hband ); /* Q(1) */ q2 = norm_l( E_fx ); @@ -1446,12 +1378,8 @@ static Word32 DTFS_freq_corr_fx( move16(); } -#ifdef BASOP_NOGLOB E2_fx = round_fx_o( L_shl_o( E_fx, q2, &Overflow ), &Overflow ); /* Q(1+q2-16) */ -#else - E2_fx = round_fx( L_shl( E_fx, q2 ) ); /* Q(1+q2-16) */ -#endif - Den = L_mult0( E1_fx, E2_fx ); /* Q(2+q1+q2-32+1) */ + Den = L_mult0( E1_fx, E2_fx ); /* Q(2+q1+q2-32+1) */ Q_den = sub( add( shl( add( X2_DTFS_fx.Q, X1_DTFS_fx.Q ), 1 ), add( q1, q2 ) ), 32 ); Num = L_max( Num, 1 ); @@ -1459,35 +1387,25 @@ static Word32 DTFS_freq_corr_fx( IF( Num == 0 ) { Result = 0; + move32(); *Qout = 31; + move16(); } ELSE { expa = norm_l( Num ); -#ifdef BASOP_NOGLOB fraca = extract_h( L_shl_o( Num, expa, &Overflow ) ); -#else - fraca = extract_h( L_shl( Num, expa ) ); -#endif expa = sub( 30, add( expa, Q_num ) ); expb = norm_l( Den ); -#ifdef BASOP_NOGLOB fracb = round_fx_o( L_shl_o( Den, expb, &Overflow ), &Overflow ); -#else - fracb = round_fx( L_shl( Den, expb ) ); -#endif expb = sub( 30, add( expb, Q_den ) ); scale = shr( sub( fraca, fracb ), 15 ); -#ifdef BASOP_NOGLOB fracb = shl_o( fracb, scale, &Overflow ); -#else - fracb = shl( fracb, scale ); -#endif expb = sub( expb, scale ); tmp = div_s( fracb, fraca ); @@ -1503,6 +1421,7 @@ static Word32 DTFS_freq_corr_fx( Result = L_negate( L_tmp ); } *Qout = sub( 30, exp ); + move16(); } return Result; } @@ -1532,6 +1451,7 @@ static Word16 DTFS_alignment_extract_td_fx( Word16 *x1, Word16 *x2, Word16 lag ) Word32 maxcorr, corr; #ifdef BASOP_NOGLOB_DECLARE_LOCAL Flag Overflow = 0; + move32(); #endif maxcorr = L_add( MIN_32, 0 ); Adiff_fx = (Word16) ( s_max( 4, shr( lag, 3 ) ) ); @@ -1543,13 +1463,9 @@ static Word16 DTFS_alignment_extract_td_fx( Word16 *x1, Word16 *x2, Word16 lag ) corr = L_deposit_l( 0 ); FOR( k = 0; k < lag; k++ ) { -#ifdef BASOP_NOGLOB corr = L_mac_o( corr, x1[k], x2[( k - j + lag ) % lag], &Overflow ); -#else - corr = L_mac( corr, x1[k], x2[( k - j + lag ) % lag] ); -#endif } - if ( GT_32( corr, maxcorr ) ) + IF( GT_32( corr, maxcorr ) ) { idx = j; move16(); @@ -1589,17 +1505,19 @@ static Word32 DTFS_getEngy_band_fx( Word16 k, lk, hk, HalfLag; Word32 freq_fx, L_lband, L_hband; Word32 en_fx = 0; + move32(); #ifdef BASOP_NOGLOB_DECLARE_LOCAL Flag Overflow = 0; + move32(); #endif - L_lband = L_mult( lband, X_fx.lag_fx ); - L_hband = L_mult( hband, X_fx.lag_fx ); + L_lband = L_mult( lband, X_fx.lag_fx ); /* Q0 * Q0 -> Q1 */ + L_hband = L_mult( hband, X_fx.lag_fx ); /* Q0 * Q0 -> Q1 */ HalfLag = s_min( shr( sub( X_fx.lag_fx, 1 ), 1 ), X_fx.nH_4kHz_fx ); /* get lband and hband */ FOR( k = 1; k <= HalfLag; k++ ) { freq_fx = L_mult( k, 12800 ); - IF( GE_32( freq_fx, L_lband ) ) + if ( GE_32( freq_fx, L_lband ) ) { BREAK; } @@ -1609,7 +1527,7 @@ static Word32 DTFS_getEngy_band_fx( FOR( k = 1; k <= HalfLag; k++ ) { freq_fx = L_mult( k, 12800 ); - IF( GE_32( freq_fx, L_hband ) ) + if ( GE_32( freq_fx, L_hband ) ) { BREAK; } @@ -1619,13 +1537,8 @@ static Word32 DTFS_getEngy_band_fx( FOR( k = lk; k < hk; k++ ) { -#ifdef BASOP_NOGLOB en_fx = L_mac0_o( en_fx, X_fx.a_fx[k], X_fx.a_fx[k], &Overflow ); /* 2*X1.Q+1 */ en_fx = L_mac0_o( en_fx, X_fx.b_fx[k], X_fx.b_fx[k], &Overflow ); -#else - en_fx = L_mac0( en_fx, X_fx.a_fx[k], X_fx.a_fx[k] ); /* 2*X1.Q+1 */ - en_fx = L_mac0( en_fx, X_fx.b_fx[k], X_fx.b_fx[k] ); -#endif } if ( lband == 0 ) @@ -1637,13 +1550,8 @@ static Word32 DTFS_getEngy_band_fx( test(); IF( ( s_and( X_fx.lag_fx, 1 ) == 0 ) && ( hband == X_fx.upper_cut_off_freq_fx ) ) { -#ifdef BASOP_NOGLOB en_fx = L_mac0_o( en_fx, X_fx.a_fx[k], X_fx.a_fx[k], &Overflow ); en_fx = L_mac0_o( en_fx, X_fx.b_fx[k], X_fx.b_fx[k], &Overflow ); -#else - en_fx = L_mac0( en_fx, X_fx.a_fx[k], X_fx.a_fx[k] ); - en_fx = L_mac0( en_fx, X_fx.b_fx[k], X_fx.b_fx[k] ); -#endif } return en_fx; /* 2*X1.Q */ @@ -1688,10 +1596,13 @@ void sc_vbr_enc_init_fx( hSC_VBR->Q_to_F = 0; move16(); - hSC_VBR->numactive = 0; /* keep the count of the frames inside current 600 frame bloack.*/ - hSC_VBR->sum_of_rates_fx = 0; /* sum of the rates of past 600 active frames*/ + hSC_VBR->numactive = 0; /* keep the count of the frames inside current 600 frame bloack.*/ + move16(); + hSC_VBR->sum_of_rates_fx = 0; /* sum of the rates of past 600 active frames*/ + move32(); hSC_VBR->global_avr_rate_fx = 0; /* global rate upto current time. recorded a (rate in kbps) *6000*/ - hSC_VBR->global_frame_cnt = 0; /* 600 active frame block count. Used to update the global rate*/ + move32(); + hSC_VBR->global_frame_cnt = 0; /* 600 active frame block count. Used to update the global rate*/ move16(); hSC_VBR->rate_control = 0; move16(); @@ -1703,10 +1614,11 @@ void sc_vbr_enc_init_fx( hSC_VBR->vbr_generic_ho = 0; move16(); hSC_VBR->Local_VAD = 0; - + move16(); hSC_VBR->Last_Resort = 0; + move16(); hSC_VBR->set_ppp_generic = 0; - + move16(); hSC_VBR->last_7k2_coder_type = GENERIC; move16(); diff --git a/lib_enc/waveadjust_fec_cod.c b/lib_enc/waveadjust_fec_cod.c deleted file mode 100644 index 825401325748d89d4db5894372ff8dd2e53d76ec..0000000000000000000000000000000000000000 --- a/lib_enc/waveadjust_fec_cod.c +++ /dev/null @@ -1,41 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include -#include "prot.h" -#include "wmc_auto.h" diff --git a/lib_enc/waveadjust_fec_cod_fx.c b/lib_enc/waveadjust_fec_cod_fx.c index 378898522fefbf0ed6ee27e78f76e00a9e7db40a..f10a1bd0b2d1fff339dc2c8f93ef7ffdbbee9067 100644 --- a/lib_enc/waveadjust_fec_cod_fx.c +++ b/lib_enc/waveadjust_fec_cod_fx.c @@ -18,7 +18,10 @@ * *--------------------------------------------------------------------*/ -Word32 SFM_Cal_fx( Word32 magn[], Word16 n ) +Word32 SFM_Cal_fx( + Word32 magn[], /*Q = Qx*/ + Word16 n /*Q = Q0*/ +) { /* Counted Dymamic RAM: 16 words */ Word32 logCurFlatness; @@ -38,11 +41,7 @@ Word32 SFM_Cal_fx( Word32 magn[], Word16 n ) /* sum(log2(magn(i))) */ sumLogMagn = L_add( sumLogMagn, logMagn ); /* Q8 */ -#ifdef BASOP_NOGLOB - sumMagn = L_add_sat( sumMagn, magn_abs ); -#else - sumMagn = L_add( sumMagn, magn_abs ); -#endif + sumMagn = L_add_sat( sumMagn, magn_abs ); /*Qx*/ } IF( EQ_32( sumMagn, MAX_32 ) ) @@ -50,7 +49,7 @@ Word32 SFM_Cal_fx( Word32 magn[], Word16 n ) sumMagn = L_deposit_l( 0 ); FOR( i = 0; i < n; i++ ) { - magn_abs = L_shr( L_abs( magn[i] ), 8 ); + magn_abs = L_shr( L_abs( magn[i] ), 8 ); /* Qx-8 */ sumMagn = L_add( sumMagn, magn_abs ); } /* log2(sumMagn) */ @@ -78,7 +77,6 @@ Word32 SFM_Cal_fx( Word32 magn[], Word16 n ) logCurFlatness = L_deposit_l( div_l( L_shl( logMagn, 1 ), n ) ); frac = L_and( logCurFlatness, 0xFF ); norm_value = (Word16) L_shr( logCurFlatness, 8 ); - move16(); logCurFlatness = L_sub( kExp2TableFrac_x[frac], 33 ); logCurFlatness = L_shl( logCurFlatness, sub( 16, norm_value ) ); /* Q31 */ diff --git a/lib_isar/isar_MSPred.c b/lib_isar/isar_MSPred.c new file mode 100644 index 0000000000000000000000000000000000000000..1df47d695c796fd6d5ece3eb4c14ebf3677914bb --- /dev/null +++ b/lib_isar/isar_MSPred.c @@ -0,0 +1,550 @@ +/****************************************************************************************************** + + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository. All Rights Reserved. + + This software is protected by copyright law and by international treaties. + The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository retain full ownership rights in their respective contributions in + the software. This notice grants no license of any kind, including but not limited to patent + license, nor is any license granted by implication, estoppel or otherwise. + + Contributors are required to enter into the IVAS codec Public Collaboration agreement before making + contributions. + + This software is provided "AS IS", without any express or implied warranties. The software is in the + development stage. It is intended exclusively for experts who have experience with such software and + solely for the purpose of inspection. All implied warranties of non-infringement, merchantability + and fitness for a particular purpose are hereby disclaimed and excluded. + + Any dispute, controversy or claim arising under or in relation to providing this software shall be + submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in + accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and + the United Nations Convention on Contracts on the International Sales of Goods. + +*******************************************************************************************************/ + +#include "options.h" +#include +#ifdef SPLIT_REND_WITH_HEAD_ROT +#include "isar_lcld_rom_tables.h" +#include "isar_lcld_prot.h" +#include "isar_prot.h" +#include "wmc_auto.h" +#include "basop_util.h" +#include "enh64.h" +#include +/*-------------------------------------------------------------------* + * Function _round() + * + * + *-------------------------------------------------------------------*/ + +static int32_t _round( + float val ) +{ + return ( val > 0.0f ? (int32_t) ( val + 0.5f ) : (int32_t) ( val - 0.5f ) ); +} + + +/*-------------------------------------------------------------------* + * Function quantPhase() + * + * + *-------------------------------------------------------------------*/ + +Word32 quantPhase_fx( + Word32 phase, + Word16 exp ) // i:31? +{ + Word32 phaseQ; + + // phaseQ = _round(phase * PHASE_QUANT_FACTOR); + phaseQ = L_shr_r( Mpy_32_32( phase, PHASE_QUANT_FACTOR_FX_Q29 ), 29 - exp ); // Q60 + if ( phaseQ == PHASE_MAX_VAL ) + { + phaseQ = PHASE_MIN_VAL; + } + return phaseQ; +} + +int32_t quantPhase( + float phase ) +{ + int32_t phaseQ; + + phaseQ = _round( phase * PHASE_QUANT_FACTOR ); + if ( phaseQ == PHASE_MAX_VAL ) + { + phaseQ = PHASE_MIN_VAL; + } + return phaseQ; +} + + +/*-------------------------------------------------------------------* + * Function cplxmult() + * + * + *-------------------------------------------------------------------*/ +void cplxmult_fx( + Word32 *pr1, + Word32 *pi1, + Word32 r2, + Word32 i2 ) +{ + Word32 r1 = *pr1, i1 = *pi1; + + *pr1 = L_sub( Mpy_32_32( r1, r2 ), Mpy_32_32( i1, i2 ) ); + *pi1 = L_add( Mpy_32_32( r1, i2 ), Mpy_32_32( i1, r2 ) ); + + return; +} +void cplxmult( + float *pr1, + float *pi1, + float r2, + float i2 ) +{ + float r1 = *pr1, i1 = *pi1; + + *pr1 = r1 * r2 - i1 * i2; + *pi1 = r1 * i2 + i1 * r2; + + return; +} +/*-------------------------------------------------------------------* + * Function requantPhase() + * + * + *-------------------------------------------------------------------*/ + +Word32 requantPhase( + Word32 phaseQ ) +{ + + IF( GE_32( phaseQ, PHASE_MAX_VAL ) ) + { + phaseQ = L_add( phaseQ, PHASE_MAX_VAL ); + phaseQ %= ( L_shl( PHASE_MAX_VAL, 1 ) ); + phaseQ = L_sub( phaseQ, PHASE_MAX_VAL ); + } + ELSE IF( LT_32( phaseQ, PHASE_MIN_VAL ) ) + { + phaseQ = L_sub( phaseQ, PHASE_MAX_VAL ); + phaseQ %= ( L_shl( PHASE_MAX_VAL, 1 ) ); + phaseQ = L_add( phaseQ, PHASE_MAX_VAL ); + IF( EQ_32( phaseQ, PHASE_MAX_VAL ) ) + { + phaseQ = PHASE_MIN_VAL; + move32(); + } + } + + return phaseQ; +} + + +/*-------------------------------------------------------------------* + * Function quantPred() + * + * + *-------------------------------------------------------------------*/ + +Word32 quantPred_fx( + const Word32 pred, + Word16 exp ) // i:Q31 +{ + // int32_t predQ = _round(pred * PRED_QUANT_FACTOR); + Word32 predQ = W_round32_s( W_shl( W_mult_32_32( pred, (Word32) PRED_QUANT_FACTOR ), exp ) ); + predQ = predQ > PRED_MAX_VAL ? PRED_MAX_VAL : predQ; + predQ = predQ < PRED_MIN_VAL ? PRED_MIN_VAL : predQ; + + return predQ; +} +int32_t quantPred( + const float pred ) +{ + int32_t predQ = _round( pred * PRED_QUANT_FACTOR ); + predQ = predQ > PRED_MAX_VAL ? PRED_MAX_VAL : predQ; + predQ = predQ < PRED_MIN_VAL ? PRED_MIN_VAL : predQ; + + return predQ; +} + + +/*-------------------------------------------------------------------* + * Function dequantPhase() + * + * + *-------------------------------------------------------------------*/ + +float dequantPhase( + const int32_t phaseQ ) +{ + return (float) phaseQ / PHASE_QUANT_FACTOR; +} + + +/*-------------------------------------------------------------------* + * Function dequantPred() + * + * + *-------------------------------------------------------------------*/ +Word32 dequantPred_fx( Word32 predQ ) +{ + if ( predQ == 12 ) + { + return MAX_32; + } + Word16 tmp_e; + Word32 tmp, value; + if ( predQ == 0 ) + { + return predQ; + } + tmp = BASOP_Util_Divide3216_Scale( predQ, PRED_QUANT_FACTOR_FX, &tmp_e ); + value = L_shl( tmp, sub( 31, negate( add( 1, tmp_e ) ) ) ); // Q31 + return value; +} +float dequantPred( int32_t predQ ) +{ + return (float) predQ / PRED_QUANT_FACTOR; +} + + +/*-------------------------------------------------------------------* + * Function PrepEncode() + * + * + *-------------------------------------------------------------------*/ + +Word32 PrepEncode( + Word32 *piQuant, + const Word32 *piMSFlags, + const Word32 numBands ) +{ + Word32 b, numMSBands; + numMSBands = 0; + move32(); + + FOR( b = 0; b < numBands; b++ ) + { + IF( piMSFlags[b] ) + { + piQuant[numMSBands++] = piQuant[b]; + move32(); + } + } + + FOR( b = numMSBands; b < numBands; b++ ) + { + piQuant[b] = 0; + move32(); + } + + return numMSBands; +} + + +/*-------------------------------------------------------------------* + * Function EncodePhase() + * + * + *-------------------------------------------------------------------*/ + +void EncodePhase( + Word32 *phaseQuant, + const Word32 numMSBands, + const Word32 diffDim ) +{ + Word32 b; + + IF( GT_32( diffDim, 0 ) ) + { + Word32 tmp1, tmp2; + tmp1 = phaseQuant[0]; + move32(); + FOR( b = 1; b < numMSBands; b++ ) + { + tmp2 = phaseQuant[b]; + move32(); + phaseQuant[b] = L_sub( phaseQuant[b], tmp1 ); + tmp1 = tmp2; + move32(); + } + } + + IF( GT_32( diffDim, 1 ) ) + { + Word32 tmp1, tmp2; + tmp1 = phaseQuant[1]; + move32(); + FOR( b = 2; b < numMSBands; b++ ) + { + tmp2 = phaseQuant[b]; + move32(); + phaseQuant[b] = L_sub( phaseQuant[b], tmp1 ); + tmp1 = tmp2; + move32(); + } + } + FOR( b = 1; b < numMSBands; b++ ) + { + phaseQuant[b] = requantPhase( phaseQuant[b] ); + } + + return; +} + + +/*-------------------------------------------------------------------* + * Function DecodePhase() + * + * + *-------------------------------------------------------------------*/ + +void DecodePhase( + Word32 *phaseQuant, + const Word32 numMSBands, + const Word32 diffDim ) +{ + Word32 b; + + IF( GT_32( diffDim, 1 ) ) + { + FOR( b = 2; b < numMSBands; b++ ) + { + phaseQuant[b] = L_add( phaseQuant[b], phaseQuant[b - 1] ); + move32(); + } + } + + IF( GT_32( diffDim, 0 ) ) + { + FOR( b = 1; b < numMSBands; b++ ) + { + phaseQuant[b] = L_add( phaseQuant[b], phaseQuant[b - 1] ); + move32(); + } + } + + FOR( b = 1; b < numMSBands; b++ ) + { + phaseQuant[b] = requantPhase( phaseQuant[b] ); + move32(); + } + + return; +} + + +/*-------------------------------------------------------------------* + * Function EncodePredCoef() + * + * + *-------------------------------------------------------------------*/ + +Word32 EncodePredCoef( + Word32 *predQuant, + const Word32 numMSBands ) +{ + Word32 b, tmp1, tmp2; + + tmp1 = predQuant[0]; + move32(); + FOR( b = 1; b < numMSBands; b++ ) + { + tmp2 = predQuant[b]; + move32(); + predQuant[b] = L_sub( predQuant[b], tmp1 ); + tmp1 = tmp2; + move32(); + } + + return numMSBands; +} + + +/*-------------------------------------------------------------------* + * Function DecodePredCoef() + * + * + *-------------------------------------------------------------------*/ + +void DecodePredCoef( + Word32 *phaseQuant, + const Word32 numMSBands ) +{ + Word32 b; + + FOR( b = 1; b < numMSBands; b++ ) + { + phaseQuant[b] = L_add( phaseQuant[b], phaseQuant[b - 1] ); + } + + return; +} + + +/*-------------------------------------------------------------------* + * Function CountMSBits() + * + * + *-------------------------------------------------------------------*/ + +Word32 CountMSBits( + Word32 iNumBands, + const Word32 iMSMode, + const Word32 *piMSFlags, + const Word32 *piLRPhaseDiff, + const Word32 *piMSPredCoef ) +{ + Word32 iBitsWritten = 0; + move32(); + Word32 b; + Word32 anyNonZero; + Word32 iNumMSBands = 0; + move32(); + Word32 piPhaseCopy[MAX_BANDS_48]; + Word32 piPredCopy[MAX_BANDS_48]; + + FOR( b = 0; b < MAX_BANDS_48; b++ ) + { + piPhaseCopy[b] = 0; + move32(); + piPredCopy[b] = 0; + move32(); + } + + iBitsWritten = L_add( iBitsWritten, 2 ); /* iMSMode */ + FOR( b = 0; b < iNumBands; b++ ) + { + iNumMSBands = L_add( iNumMSBands, NE_32( piMSFlags[b], 0 ) ); + } + + IF( EQ_32( iNumMSBands, 0 ) ) + { + return iBitsWritten; + } + + IF( LT_32( iNumMSBands, iNumBands ) ) + { + iBitsWritten = L_add( iBitsWritten, iNumBands ); /* piMSFlags */ + } + + IF( LT_32( iMSMode, 3 ) ) + { + return iBitsWritten; + } + + /* prepare arrays for coding evaluation */ + FOR( b = 0; b < iNumBands; b++ ) + { + piPhaseCopy[b] = piLRPhaseDiff[b]; + move32(); + piPredCopy[b] = piMSPredCoef[b]; + move32(); + } + + /* Differential Coding of Phase Data*/ + PrepEncode( piPhaseCopy, piMSFlags, iNumBands ); + PrepEncode( piPredCopy, piMSFlags, iNumBands ); + EncodePhase( piPhaseCopy, iNumMSBands, PHASE_DIFF_DIM ); + EncodePredCoef( piPredCopy, iNumMSBands ); + + iBitsWritten = L_add( iBitsWritten, 1 ); /* iMSPredAll */ + anyNonZero = 0; /* phase */ + move32(); + FOR( b = 0; b < iNumMSBands; b++ ) + { + IF( NE_32( piPhaseCopy[b], 0 ) ) + { + anyNonZero = 1; + move32(); + BREAK; + } + } + iBitsWritten = L_add( iBitsWritten, 1 ); /*anyNonZero Phase*/ + IF( anyNonZero ) + { + iBitsWritten = L_add( iBitsWritten, PHASE_BAND0_BITS ); + FOR( b = 1; b < iNumMSBands; b++ ) + { + Word32 tabIdx = L_sub( piPhaseCopy[b], ENV_DELTA_MIN ); + iBitsWritten = L_add( iBitsWritten, c_aaiRMSEnvHuffEnc[tabIdx][0] ); + } + } + anyNonZero = 0; /* prediction */ + move32(); + FOR( b = 0; b < iNumMSBands; b++ ) + { + IF( NE_32( piPredCopy[b], 0 ) ) + { + anyNonZero = 1; + move32(); + break; + } + } + + iBitsWritten = L_add( iBitsWritten, 1 ); /* any nonZero Pred */ + IF( anyNonZero ) + { + iBitsWritten = L_add( iBitsWritten, PRED_BAND0_BITS ); + FOR( b = 1; b < iNumMSBands; b++ ) + { + Word32 tabIdx = L_sub( piPredCopy[b], ENV_DELTA_MIN ); + iBitsWritten = L_add( iBitsWritten, c_aaiRMSEnvHuffEnc[tabIdx][0] ); + } + } + + return iBitsWritten; +} + + +#ifdef DEBUG_WRITE_MS_PRED +void writeMSPred( + int32_t *phaseQuant, + int32_t *predQuant, + int32_t MSMode, + int32_t numMSBands, + int32_t numBands, + void *fid, + int32_t *piMsFlags ) +{ + int32_t b; + + fid = (FILE *) fid; + fprintf( fid, "%d %d", MSMode, numMSBands ); + for ( b = 0; b < numMSBands; b++ ) + { + fprintf( fid, " %d", phaseQuant[b] ); + } + for ( b = numMSBands; b < numBands; b++ ) + { + fprintf( fid, " %d", 0 ); + } + for ( b = 0; b < numMSBands; b++ ) + { + fprintf( fid, " %d", predQuant[b] ); + } + for ( b = numMSBands; b < numBands; b++ ) + { + fprintf( fid, " %d", 0 ); + } + for ( b = 0; b < numBands; b++ ) + { + fprintf( fid, " %d", piMsFlags[b] ); + } + fprintf( fid, "\n" ); + + return; +} +#endif +#endif diff --git a/lib_dec/ivas_lfe_plc.c b/lib_isar/isar_NoiseGen.c similarity index 86% rename from lib_dec/ivas_lfe_plc.c rename to lib_isar/isar_NoiseGen.c index 8ae40e2be906937951de7741851c9baccf4370e3..7273b0e817dc4014bbd0e76cea9c127b4ec754c6 100644 --- a/lib_dec/ivas_lfe_plc.c +++ b/lib_isar/isar_NoiseGen.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other @@ -32,15 +32,27 @@ #include #include "options.h" -#include "prot.h" -#include "ivas_prot.h" -#include "ivas_rom_com.h" +#ifdef SPLIT_REND_WITH_HEAD_ROT #include -#ifdef DEBUGGING -#include "debug.h" -#endif +#include "prot_fx.h" +#include "isar_lcld_prot.h" #include "wmc_auto.h" + /*------------------------------------------------------------------------------------------* - * Local constants + * Function DeleteNoiseGen() + * + * *------------------------------------------------------------------------------------------*/ + +void DeleteNoiseGen( NoiseGen *psNoiseGen ) +{ + free( psNoiseGen->pfNoiseBuffer ); + free( psNoiseGen ); + + return; +} + +extern float GetNoise( NoiseGen *psNoiseGen ); +extern Word32 GetNoise_fx( NoiseGen *psNoiseGen ); +#endif diff --git a/lib_isar/isar_PerceptualModel.c b/lib_isar/isar_PerceptualModel.c new file mode 100644 index 0000000000000000000000000000000000000000..16558dd36f2532f3dd185d39e82492448dc9157c --- /dev/null +++ b/lib_isar/isar_PerceptualModel.c @@ -0,0 +1,469 @@ +/****************************************************************************************************** + + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository. All Rights Reserved. + + This software is protected by copyright law and by international treaties. + The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository retain full ownership rights in their respective contributions in + the software. This notice grants no license of any kind, including but not limited to patent + license, nor is any license granted by implication, estoppel or otherwise. + + Contributors are required to enter into the IVAS codec Public Collaboration agreement before making + contributions. + + This software is provided "AS IS", without any express or implied warranties. The software is in the + development stage. It is intended exclusively for experts who have experience with such software and + solely for the purpose of inspection. All implied warranties of non-infringement, merchantability + and fitness for a particular purpose are hereby disclaimed and excluded. + + Any dispute, controversy or claim arising under or in relation to providing this software shall be + submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in + accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and + the United Nations Convention on Contracts on the International Sales of Goods. + +*******************************************************************************************************/ + +#include +#include "options.h" +#ifdef SPLIT_REND_WITH_HEAD_ROT +#include "isar_lcld_prot.h" +#include "prot_fx.h" +#include "isar_lcld_rom_tables.h" +#include +#include "wmc_auto.h" + + +/*------------------------------------------------------------------------------------------* + * Local constants + *------------------------------------------------------------------------------------------*/ +#define PERCEPTUAL_MODEL_SCALE_SHIFT ( 6 ) +#define PERCEPTUAL_MODEL_SCALE ( 64 ) +#define PERCEPTUAL_MODEL_SCALE_SHIFT ( 6 ) +#define PERCEPTUAL_MODEL_ALPHA_SCALE ( 614 ) +#define PERCEPTUAL_MODEL_ALPHA_INV_SCALE ( 6827 ) +#define PERCEPTUAL_MODEL_ALPHA_SHIFT ( 11 ) + +/*------------------------------------------------------------------------------------------* + * Function LogAdd() + * + * + *------------------------------------------------------------------------------------------*/ + +static inline Word16 LogAdd_fx( + const Word16 iVal1, + const Word16 iVal2 ) +{ + Word16 iRetVal; + + IF( iVal1 > iVal2 ) + { + iRetVal = sub( iVal1, iVal2 ); + move16(); + iRetVal = ( iRetVal < sub( LOG_ADD_TABLE_LENGTH, 1 ) ) ? iRetVal : sub( LOG_ADD_TABLE_LENGTH, 1 ); + move16(); + iRetVal = add( iVal1, c_aiLogAddTable_fx[iRetVal] ); + move16(); + } + ELSE + { + iRetVal = sub( iVal2, iVal1 ); + move16(); + iRetVal = ( iRetVal < sub( LOG_ADD_TABLE_LENGTH, 1 ) ) ? iRetVal : sub( LOG_ADD_TABLE_LENGTH, 1 ); + move16(); + iRetVal = add( iVal2, c_aiLogAddTable_fx[iRetVal] ); + move16(); + } + + return iRetVal; +} +/*------------------------------------------------------------------------------------------* + * Function LogAdd() + * + * + *------------------------------------------------------------------------------------------*/ + +static inline int32_t LogAdd( + const int32_t iVal1, + const int32_t iVal2 ) +{ + int32_t iRetVal; + + if ( iVal1 > iVal2 ) + { + iRetVal = iVal1 - iVal2; + iRetVal = ( iRetVal < ( LOG_ADD_TABLE_LENGTH - 1 ) ) ? iRetVal : ( LOG_ADD_TABLE_LENGTH - 1 ); + iRetVal = iVal1 + c_aiLogAddTable[iRetVal]; + } + else + { + iRetVal = iVal2 - iVal1; + iRetVal = ( iRetVal < ( LOG_ADD_TABLE_LENGTH - 1 ) ) ? iRetVal : ( LOG_ADD_TABLE_LENGTH - 1 ); + iRetVal = iVal2 + c_aiLogAddTable[iRetVal]; + } + + return iRetVal; +} +/*------------------------------------------------------------------------------------------* + * Function PerceptualModel() + * + * + *------------------------------------------------------------------------------------------*/ + +void PerceptualModel_fx( + const Word32 iMaxQuantBands, + const Word32 *piRMSEnvelope, + Word32 *piExcitation, + Word32 *piSMR ) +{ + Word16 n; + + FOR( n = 0; n < iMaxQuantBands; n++ ) + { + Word16 iSLOffset; + + piExcitation[n] = shl( add( extract_l( piRMSEnvelope[n] ), c_aiBandwidthAdjust48_fx[n] ), PERCEPTUAL_MODEL_SCALE_SHIFT ); // shift instead of multiplying by PERCEPTUAL_MODEL_SCALE + move16(); + /* Calculate sensation level offset */ + iSLOffset = (Word16) extract_l( L_shr( L_mult0( c_aiDefaultTheta48_fx[n], sub( extract_l( piExcitation[n] ), c_aiAbsoluteThresh48_fx[n] ) ), PERCEPTUAL_MODEL_SLGAIN_SHIFT ) ); + // iSLOffset = (iSLOffset > 0) ? iSLOffset : 0; + move16(); + /* Offset envelope by sensation level offset */ + piExcitation[n] = sub( extract_l( piExcitation[n] ), iSLOffset ); + move16(); + /* Convert to loudness domain (x^0.3) */ + piExcitation[n] = extract_l( L_shr( L_mult0( PERCEPTUAL_MODEL_ALPHA_SCALE, extract_l( piExcitation[n] ) ), PERCEPTUAL_MODEL_ALPHA_SHIFT ) ); + move16(); + } + + /* Spread excitation function */ + FOR( n = 0; n < iMaxQuantBands; n++ ) + { + Word16 k; + const Word16 *piSpread; + + piSpread = &c_aaiSpreadFunction48_fx[n * MAX_BANDS_48]; + move16(); + piSMR[n] = add( extract_l( piExcitation[n] ), piSpread[n] ); + move16(); + FOR( k = 0; k < iMaxQuantBands; k++ ) + { + IF( NE_16( k, n ) ) + { + piSMR[n] = L_deposit_l( LogAdd_fx( extract_l( piSMR[n] ), add( extract_l( piExcitation[k] ), piSpread[k] ) ) ); + move16(); + } + } + } + + FOR( n = 0; n < iMaxQuantBands; n++ ) + { + piSMR[n] = extract_l( L_shr( L_mult0( PERCEPTUAL_MODEL_ALPHA_INV_SCALE, extract_l( piSMR[n] ) ), PERCEPTUAL_MODEL_ALPHA_SHIFT ) ); + move16(); + piSMR[n] = shl( sub( add( extract_l( piRMSEnvelope[n] ), c_aiBandwidthAdjust48_fx[n] ), extract_l( piSMR[n] ) ), PERCEPTUAL_MODEL_SCALE_SHIFT ); + move16(); + } + + return; +} +/*------------------------------------------------------------------------------------------* + * Function PerceptualModel() + * + * + *------------------------------------------------------------------------------------------*/ + +void PerceptualModel( + const int32_t iMaxQuantBands, + const int32_t *piRMSEnvelope, + int32_t *piExcitation, + int32_t *piSMR ) +{ + int32_t n; + + for ( n = 0; n < iMaxQuantBands; n++ ) + { + int32_t iSLOffset; + + piExcitation[n] = PERCEPTUAL_MODEL_SCALE * piRMSEnvelope[n] + c_aiBandwidthAdjust48[n]; + + /* Calculate sensation level offset */ + iSLOffset = c_aiDefaultTheta48[n] * ( piExcitation[n] - c_aiAbsoluteThresh48[n] ) >> PERCEPTUAL_MODEL_SLGAIN_SHIFT; + // iSLOffset = (iSLOffset > 0) ? iSLOffset : 0; + + /* Offset envelope by sensation level offset */ + piExcitation[n] -= iSLOffset; + + /* Convert to loudness domain (x^0.3) */ + piExcitation[n] = PERCEPTUAL_MODEL_ALPHA_SCALE * piExcitation[n] >> PERCEPTUAL_MODEL_ALPHA_SHIFT; + } + + /* Spread excitation function */ + for ( n = 0; n < iMaxQuantBands; n++ ) + { + int32_t k; + const int32_t *piSpread; + + piSpread = &c_aaiSpreadFunction48[n * MAX_BANDS_48]; + piSMR[n] = piExcitation[n] + piSpread[n]; + for ( k = 0; k < iMaxQuantBands; k++ ) + { + if ( k != n ) + { + piSMR[n] = LogAdd( piSMR[n], piExcitation[k] + piSpread[k] ); + } + } + } + + for ( n = 0; n < iMaxQuantBands; n++ ) + { + piSMR[n] = PERCEPTUAL_MODEL_ALPHA_INV_SCALE * piSMR[n] >> PERCEPTUAL_MODEL_ALPHA_SHIFT; + piSMR[n] = PERCEPTUAL_MODEL_SCALE * piRMSEnvelope[n] + c_aiBandwidthAdjust48[n] - piSMR[n]; + } + + return; +} +/*------------------------------------------------------------------------------------------* + * Function PerceptualModelStereo() + * + * + *------------------------------------------------------------------------------------------*/ + +void PerceptualModelStereo( + const int32_t iMaxQuantBands, + const int32_t *piMSFlags, + const int32_t *piRMSEnvelope0, + const int32_t *piRMSEnvelope1, + int32_t *piExcitation0, + int32_t *piExcitation1, + int32_t *piSMR0, + int32_t *piSMR1 ) +{ + int32_t n; + + for ( n = 0; n < iMaxQuantBands; n++ ) + { + int32_t iMaxRMSEnv; + int32_t iSLOffset; + + iMaxRMSEnv = piRMSEnvelope0[n]; + + piExcitation0[n] = PERCEPTUAL_MODEL_SCALE * iMaxRMSEnv + c_aiBandwidthAdjust48[n]; /* piRMSEnvelope0[n] */ + + /* Calculate sensation level offset */ + iSLOffset = c_aiDefaultTheta48[n] * ( piExcitation0[n] - c_aiAbsoluteThresh48[n] ) >> PERCEPTUAL_MODEL_SLGAIN_SHIFT; + // iSLOffset = (iSLOffset > 0) ? iSLOffset : 0; + + /* Offset envelope by sensation level offset */ + piExcitation0[n] -= iSLOffset; + + /* Convert to loudness domain (x^0.3) */ + piExcitation0[n] = PERCEPTUAL_MODEL_ALPHA_SCALE * piExcitation0[n] >> PERCEPTUAL_MODEL_ALPHA_SHIFT; + } + + /* Spread excitation function */ + for ( n = 0; n < iMaxQuantBands; n++ ) + { + int32_t k; + const int32_t *piSpread; + + piSpread = &c_aaiSpreadFunction48[n * MAX_BANDS_48]; + piSMR0[n] = piExcitation0[n] + piSpread[n]; + for ( k = 0; k < iMaxQuantBands; k++ ) + { + if ( k != n ) + { + piSMR0[n] = LogAdd( piSMR0[n], piExcitation0[k] + piSpread[k] ); + } + } + } + + for ( n = 0; n < iMaxQuantBands; n++ ) + { + int32_t iMaxRMSEnv; + int32_t iSLOffset; + + iMaxRMSEnv = piRMSEnvelope1[n]; + + piExcitation1[n] = PERCEPTUAL_MODEL_SCALE * iMaxRMSEnv + c_aiBandwidthAdjust48[n]; /* piRMSEnvelope1[n] */ + + /* Calculate sensation level offset */ + iSLOffset = c_aiDefaultTheta48[n] * ( piExcitation1[n] - c_aiAbsoluteThresh48[n] ) >> PERCEPTUAL_MODEL_SLGAIN_SHIFT; + // iSLOffset = (iSLOffset > 0) ? iSLOffset : 0; + + /* Offset envelope by sensation level offset */ + piExcitation1[n] -= iSLOffset; + + /* Convert to loudness domain (x^0.3) */ + piExcitation1[n] = PERCEPTUAL_MODEL_ALPHA_SCALE * piExcitation1[n] >> PERCEPTUAL_MODEL_ALPHA_SHIFT; + } + + /* Spread excitation function */ + for ( n = 0; n < iMaxQuantBands; n++ ) + { + int32_t k; + const int32_t *piSpread; + + piSpread = &c_aaiSpreadFunction48[n * MAX_BANDS_48]; + piSMR1[n] = piExcitation1[n] + piSpread[n]; + for ( k = 0; k < iMaxQuantBands; k++ ) + { + if ( k != n ) + { + piSMR1[n] = LogAdd( piSMR1[n], piExcitation1[k] + piSpread[k] ); + } + } + } + + for ( n = 0; n < iMaxQuantBands; n++ ) + { + if ( piMSFlags[n] == 1 ) + { + piSMR0[n] = ( piSMR0[n] > piSMR1[n] ) ? piSMR0[n] : piSMR1[n]; + piSMR1[n] = piSMR0[n]; + } + } + + for ( n = 0; n < iMaxQuantBands; n++ ) + { + piSMR0[n] = PERCEPTUAL_MODEL_ALPHA_INV_SCALE * piSMR0[n] >> PERCEPTUAL_MODEL_ALPHA_SHIFT; + piSMR0[n] = PERCEPTUAL_MODEL_SCALE * piRMSEnvelope0[n] + c_aiBandwidthAdjust48[n] - piSMR0[n]; + } + + for ( n = 0; n < iMaxQuantBands; n++ ) + { + piSMR1[n] = PERCEPTUAL_MODEL_ALPHA_INV_SCALE * piSMR1[n] >> PERCEPTUAL_MODEL_ALPHA_SHIFT; + piSMR1[n] = PERCEPTUAL_MODEL_SCALE * piRMSEnvelope1[n] + c_aiBandwidthAdjust48[n] - piSMR1[n]; + } + + return; +} +void PerceptualModelStereo_fx( + const Word32 iMaxQuantBands, + const Word32 *piMSFlags, + const Word32 *piRMSEnvelope0, + const Word32 *piRMSEnvelope1, + Word32 *piExcitation0, + Word32 *piExcitation1, + Word32 *piSMR0, + Word32 *piSMR1 ) +{ + Word16 n; + + FOR( n = 0; n < iMaxQuantBands; n++ ) + { + Word16 iMaxRMSEnv; + Word16 iSLOffset; + + iMaxRMSEnv = extract_l( piRMSEnvelope0[n] ); + move16(); + piExcitation0[n] = add( shl( iMaxRMSEnv, PERCEPTUAL_MODEL_SCALE_SHIFT ), c_aiBandwidthAdjust48_fx[n] ); /* piRMSEnvelope0[n] */ + move16(); + /* Calculate sensation level offset */ + iSLOffset = extract_l( L_shr( L_mult0( c_aiDefaultTheta48_fx[n], sub( extract_l( piExcitation0[n] ), c_aiAbsoluteThresh48_fx[n] ) ), PERCEPTUAL_MODEL_SLGAIN_SHIFT ) ); + // iSLOffset = (iSLOffset > 0) ? iSLOffset : 0; + move16(); + /* Offset envelope by sensation level offset */ + piExcitation0[n] = sub( extract_l( piExcitation0[n] ), iSLOffset ); + move16(); + /* Convert to loudness domain (x^0.3) */ + piExcitation0[n] = extract_l( L_shr( L_mult0( PERCEPTUAL_MODEL_ALPHA_SCALE, extract_l( piExcitation0[n] ) ), PERCEPTUAL_MODEL_ALPHA_SHIFT ) ); + move16(); + } + + /* Spread excitation function */ + for ( n = 0; n < iMaxQuantBands; n++ ) + { + Word16 k; + const Word16 *piSpread; + + piSpread = &c_aaiSpreadFunction48_fx[n * MAX_BANDS_48]; + move16(); + piSMR0[n] = add( extract_l( piExcitation0[n] ), piSpread[n] ); + move16(); + FOR( k = 0; k < iMaxQuantBands; k++ ) + { + IF( NE_16( k, n ) ) + { + piSMR0[n] = L_deposit_l( LogAdd_fx( extract_l( piSMR0[n] ), add( extract_l( piExcitation0[k] ), piSpread[k] ) ) ); + move16(); + } + } + } + + FOR( n = 0; n < iMaxQuantBands; n++ ) + { + Word16 iMaxRMSEnv; + Word16 iSLOffset; + + iMaxRMSEnv = extract_l( piRMSEnvelope1[n] ); + move16(); + piExcitation1[n] = add( shl( iMaxRMSEnv, PERCEPTUAL_MODEL_SCALE_SHIFT ), c_aiBandwidthAdjust48_fx[n] ); /* piRMSEnvelope1[n] */ + move16(); + /* Calculate sensation level offset */ + iSLOffset = extract_l( L_shr( L_mult0( c_aiDefaultTheta48_fx[n], sub( extract_l( piExcitation1[n] ), c_aiAbsoluteThresh48_fx[n] ) ), PERCEPTUAL_MODEL_SLGAIN_SHIFT ) ); + // iSLOffset = (iSLOffset > 0) ? iSLOffset : 0; + move16(); + /* Offset envelope by sensation level offset */ + piExcitation1[n] = sub( extract_l( piExcitation1[n] ), iSLOffset ); + move16(); + /* Convert to loudness domain (x^0.3) */ + piExcitation1[n] = extract_l( L_shr( L_mult0( PERCEPTUAL_MODEL_ALPHA_SCALE, extract_l( piExcitation1[n] ) ), PERCEPTUAL_MODEL_ALPHA_SHIFT ) ); + move16(); + } + + /* Spread excitation function */ + FOR( n = 0; n < iMaxQuantBands; n++ ) + { + Word16 k; + const Word16 *piSpread; + + piSpread = &c_aaiSpreadFunction48_fx[n * MAX_BANDS_48]; + move16(); + piSMR1[n] = add( extract_l( piExcitation1[n] ), piSpread[n] ); + move16(); + FOR( k = 0; k < iMaxQuantBands; k++ ) + { + IF( NE_16( k, n ) ) + { + piSMR1[n] = LogAdd_fx( extract_l( piSMR1[n] ), add( extract_l( piExcitation1[k] ), piSpread[k] ) ); + move16(); + } + } + } + + FOR( n = 0; n < iMaxQuantBands; n++ ) + { + IF( EQ_16( extract_l( piMSFlags[n] ), 1 ) ) + { + piSMR0[n] = ( piSMR0[n] > piSMR1[n] ) ? piSMR0[n] : piSMR1[n]; + move16(); + piSMR1[n] = piSMR0[n]; + move16(); + } + } + + FOR( n = 0; n < iMaxQuantBands; n++ ) + { + piSMR0[n] = extract_l( L_shr( L_mult0( PERCEPTUAL_MODEL_ALPHA_INV_SCALE, extract_l( piSMR0[n] ) ), PERCEPTUAL_MODEL_ALPHA_SHIFT ) ); + move16(); + piSMR0[n] = sub( add( shl( extract_l( piRMSEnvelope0[n] ), PERCEPTUAL_MODEL_SCALE_SHIFT ), c_aiBandwidthAdjust48_fx[n] ), extract_l( piSMR0[n] ) ); + move16(); + } + + FOR( n = 0; n < iMaxQuantBands; n++ ) + { + piSMR1[n] = extract_l( L_shr( L_mult0( PERCEPTUAL_MODEL_ALPHA_INV_SCALE, extract_l( piSMR1[n] ) ), PERCEPTUAL_MODEL_ALPHA_SHIFT ) ); + move16(); + piSMR1[n] = sub( add( shl( extract_l( piRMSEnvelope1[n] ), PERCEPTUAL_MODEL_SCALE_SHIFT ), c_aiBandwidthAdjust48_fx[n] ), extract_l( piSMR1[n] ) ); + move16(); + } + + return; +} +#endif diff --git a/lib_isar/isar_PredDecoder.c b/lib_isar/isar_PredDecoder.c new file mode 100644 index 0000000000000000000000000000000000000000..b30a6e0a8c1fedd176a9cfd606d39e69357c43f3 --- /dev/null +++ b/lib_isar/isar_PredDecoder.c @@ -0,0 +1,495 @@ +/****************************************************************************************************** + + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository. All Rights Reserved. + + This software is protected by copyright law and by international treaties. + The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository retain full ownership rights in their respective contributions in + the software. This notice grants no license of any kind, including but not limited to patent + license, nor is any license granted by implication, estoppel or otherwise. + + Contributors are required to enter into the IVAS codec Public Collaboration agreement before making + contributions. + + This software is provided "AS IS", without any express or implied warranties. The software is in the + development stage. It is intended exclusively for experts who have experience with such software and + solely for the purpose of inspection. All implied warranties of non-infringement, merchantability + and fitness for a particular purpose are hereby disclaimed and excluded. + + Any dispute, controversy or claim arising under or in relation to providing this software shall be + submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in + accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and + the United Nations Convention on Contracts on the International Sales of Goods. + +*******************************************************************************************************/ + +#include +#include "options.h" +#ifdef SPLIT_REND_WITH_HEAD_ROT +#include +#include "prot_fx.h" +#include "isar_prot.h" +#include "isar_lcld_prot.h" +#include "isar_lcld_rom_tables.h" +#include "wmc_auto.h" + +/*-------------------------------------------------------------------* + * Function CreatePredictionDecoder() + * + * + *-------------------------------------------------------------------*/ + +ivas_error CreatePredictionDecoder_fx( + PredictionDecoder **psPredictionDecoder_out, + const Word32 iChannels, + const Word32 iNumBlocks ) +{ + Word16 n; + Word16 m; + PredictionDecoder *psPredictionDecoder = NULL; + + IF( ( psPredictionDecoder = (PredictionDecoder *) malloc( sizeof( PredictionDecoder ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); + } + + psPredictionDecoder->iChannels = iChannels; + move32(); + psPredictionDecoder->iNumBlocks = iNumBlocks; + move32(); + psPredictionDecoder->iNumSubSets = LCLD_BLOCKS_PER_FRAME / psPredictionDecoder->iNumBlocks; + move32(); + psPredictionDecoder->iSubSetId = 0; + move32(); + /* PLC_IMPROVEMENT */ + IF( ( psPredictionDecoder->ppiDecodingFailedPrev = (Word32 **) malloc( sizeof( Word32 * ) * iChannels ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD decoder Module \n" ) ); + } + IF( ( psPredictionDecoder->ppiDecodingFailed = (Word32 **) malloc( sizeof( Word32 * ) * iChannels ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD decoder Module \n" ) ); + } + IF( ( psPredictionDecoder->ppiDecodingUnresolved = (Word32 **) malloc( sizeof( Word32 * ) * iChannels ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD decoder Module \n" ) ); + } + FOR( n = 0; n < iChannels; n++ ) + { + Word32 k; + IF( ( psPredictionDecoder->ppiDecodingUnresolved[n] = (Word32 *) malloc( sizeof( Word32 ) * LCLD_MAX_NUM_PRED_SUBSETS ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD decoder Module \n" ) ); + } + IF( ( psPredictionDecoder->ppiDecodingFailed[n] = (Word32 *) malloc( sizeof( Word32 ) * LCLD_MAX_NUM_PRED_SUBSETS ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD decoder Module \n" ) ); + } + IF( ( psPredictionDecoder->ppiDecodingFailedPrev[n] = (Word32 *) malloc( sizeof( Word32 ) * LCLD_MAX_NUM_PRED_SUBSETS ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD decoder Module \n" ) ); + } + FOR( k = 0; k < LCLD_MAX_NUM_PRED_SUBSETS; k++ ) + { + psPredictionDecoder->ppiDecodingUnresolved[n][k] = 0; + move32(); + psPredictionDecoder->ppiDecodingFailed[n][k] = 0; + move32(); + psPredictionDecoder->ppiDecodingFailedPrev[n][k] = 0; + move32(); + } + } + IF( ( psPredictionDecoder->piPredChanEnable = (Word32 *) malloc( sizeof( Word32 ) * iChannels ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); + } + IF( ( psPredictionDecoder->ppiPredBandEnable = (Word32 **) malloc( sizeof( Word32 * ) * iChannels ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); + } + IF( ( psPredictionDecoder->ppfA1Real_fx = (Word32 **) malloc( sizeof( Word32 * ) * iChannels ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); + } + IF( ( psPredictionDecoder->ppfA1Imag_fx = (Word32 **) malloc( sizeof( Word32 * ) * iChannels ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); + } + IF( ( psPredictionDecoder->ppiA1Mag = (Word32 **) malloc( sizeof( Word32 * ) * iChannels ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); + } + IF( ( psPredictionDecoder->ppiA1Phase = (Word32 **) malloc( sizeof( Word32 * ) * iChannels ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); + } + IF( ( psPredictionDecoder->ppfPredStateReal_fx = (Word32 **) malloc( sizeof( Word32 * ) * iChannels ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD decoder Module \n" ) ); + } + IF( ( psPredictionDecoder->ppfPredStateImag_fx = (Word32 **) malloc( sizeof( Word32 * ) * 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++ ) + { + psPredictionDecoder->piPredChanEnable[n] = 0; + move32(); + IF( ( psPredictionDecoder->ppiPredBandEnable[n] = (Word32 *) malloc( LCLD_BANDS * sizeof( Word32 ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); + } + FOR( m = 0; m < LCLD_BANDS; m++ ) + { + psPredictionDecoder->ppiPredBandEnable[n][m] = 0; + move32(); + } + IF( ( psPredictionDecoder->ppfA1Real_fx[n] = (Word32 *) malloc( sizeof( Word32 ) * LCLD_BANDS ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); + } + IF( ( psPredictionDecoder->ppfA1Imag_fx[n] = (Word32 *) malloc( sizeof( Word32 ) * LCLD_BANDS ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); + } + IF( ( psPredictionDecoder->ppiA1Mag[n] = (Word32 *) malloc( sizeof( Word32 ) * LCLD_BANDS ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); + } + IF( ( psPredictionDecoder->ppiA1Phase[n] = (Word32 *) malloc( sizeof( Word32 ) * LCLD_BANDS ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); + } + IF( ( psPredictionDecoder->ppfPredStateReal_fx[n] = (Word32 *) malloc( LCLD_BANDS * sizeof( Word32 ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionDecoder Module \n" ) ); + } + IF( ( psPredictionDecoder->ppfPredStateImag_fx[n] = (Word32 *) malloc( LCLD_BANDS * sizeof( Word32 ) ) ) == 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_fx[n][m] = 0; + move32(); + psPredictionDecoder->ppfPredStateImag_fx[n][m] = 0; + move32(); + } + } + + /* pre-define these tables? */ + + FOR( n = 0; n < ( 1 << PRED_QUNAT_FILTER_MAG_BITS ); n++ ) + { + psPredictionDecoder->pfMagLUT_fx[n] = c_pfMagLUT[n]; /* Q31 */ + move32(); + } + + FOR( n = 0; n < ( 1 << PRED_QUANT_FILTER_PHASE_BITS ); n++ ) + { + psPredictionDecoder->pfP2RRealLUT_fx[n] = c_pfP2RRealLUT[n]; /* Q31 */ + move32(); + psPredictionDecoder->pfP2RImagLUT_fx[n] = c_pfP2RImagLUT[n]; /* Q31 */ + move32(); + } + + *psPredictionDecoder_out = psPredictionDecoder; + + return IVAS_ERR_OK; +} + +/*-------------------------------------------------------------------* + * Function DeletePredictionDecoder() + * + * + *-------------------------------------------------------------------*/ + +void DeletePredictionDecoder_fx( + PredictionDecoder *psPredictionDecoder ) +{ + Word32 n; + + FOR( n = 0; n < psPredictionDecoder->iChannels; n++ ) + { + free( psPredictionDecoder->ppiPredBandEnable[n] ); + free( psPredictionDecoder->ppfA1Real_fx[n] ); + free( psPredictionDecoder->ppfA1Imag_fx[n] ); + free( psPredictionDecoder->ppiA1Mag[n] ); + free( psPredictionDecoder->ppiA1Phase[n] ); + free( psPredictionDecoder->ppfPredStateReal_fx[n] ); + free( psPredictionDecoder->ppfPredStateImag_fx[n] ); + free( psPredictionDecoder->ppiDecodingUnresolved[n] ); + free( psPredictionDecoder->ppiDecodingFailed[n] ); + free( psPredictionDecoder->ppiDecodingFailedPrev[n] ); + } + free( psPredictionDecoder->piPredChanEnable ); + free( psPredictionDecoder->ppiPredBandEnable ); + free( psPredictionDecoder->ppfA1Real_fx ); + free( psPredictionDecoder->ppfA1Imag_fx ); + free( psPredictionDecoder->ppiA1Mag ); + free( psPredictionDecoder->ppiA1Phase ); + free( psPredictionDecoder->ppfPredStateReal_fx ); + free( psPredictionDecoder->ppfPredStateImag_fx ); + /* PLC_IMPROVEMENT */ + free( psPredictionDecoder->ppiDecodingUnresolved ); + free( psPredictionDecoder->ppiDecodingFailed ); + free( psPredictionDecoder->ppiDecodingFailedPrev ); + + free( psPredictionDecoder ); + psPredictionDecoder = NULL; + + return; +} +/*-------------------------------------------------------------------* + * Function ReadPredictors() + * + * + *-------------------------------------------------------------------*/ + +Word32 ReadPredictors_fx( + PredictionDecoder *psPredictionDecoder, + ISAR_SPLIT_REND_BITS_HANDLE pBits ) +{ + Word16 iBitsRead = 0; + Word32 c; + Word32 b; + Word16 iNumPredBandBits = 6; + const Word16 iSubSetBits = ( GT_32( LCLD_MAX_NUM_PRED_SUBSETS, 4 ) ? 3 : 2 ); + move16(); + move16(); + move16(); + + psPredictionDecoder->iNumSubSets = L_add( ISAR_SPLIT_REND_BITStream_read_int32( pBits, iSubSetBits ), 1 ); + iBitsRead = add( iBitsRead, iSubSetBits ); + + IF( GT_32( psPredictionDecoder->iNumSubSets, 1 ) ) + { + psPredictionDecoder->iSubSetId = ISAR_SPLIT_REND_BITStream_read_int32( pBits, iSubSetBits ); + iBitsRead = add( iBitsRead, iSubSetBits ); + iNumPredBandBits = ( GE_32( psPredictionDecoder->iNumSubSets, 4 ) ? 4 : 5 ); + move16(); + } + ELSE + { + psPredictionDecoder->iSubSetId = 0; + move32(); + } + FOR( c = 0; c < psPredictionDecoder->iChannels; c++ ) + { + psPredictionDecoder->piPredChanEnable[c] = ISAR_SPLIT_REND_BITStream_read_int32( pBits, psPredictionDecoder->iNumSubSets ); + move32(); + iBitsRead = add( iBitsRead, (Word16) psPredictionDecoder->iNumSubSets ); + + IF( get_bit( psPredictionDecoder->piPredChanEnable[c], psPredictionDecoder->iSubSetId ) ) + { + Word32 b0 = psPredictionDecoder->iSubSetId; + Word32 bstep = psPredictionDecoder->iNumSubSets; + Word32 iNumPredBands; + move32(); + move32(); + + FOR( b = b0; b < LCLD_BANDS; b = L_add( b, bstep ) ) + { + psPredictionDecoder->ppiPredBandEnable[c][b] = 0; + move32(); + } + iNumPredBands = ISAR_SPLIT_REND_BITStream_read_int32( pBits, iNumPredBandBits ); + iBitsRead = add( iBitsRead, iNumPredBandBits ); + iNumPredBands = L_add( L_mult0( (Word16) iNumPredBands, (Word16) psPredictionDecoder->iNumSubSets ), b0 ); + + FOR( b = b0; b < iNumPredBands; b = L_add( b, bstep ) ) + { + psPredictionDecoder->ppiPredBandEnable[c][b] = ISAR_SPLIT_REND_BITStream_read_int32( pBits, 1 ); + move32(); + iBitsRead = add( iBitsRead, 1 ); + + IF( EQ_32( psPredictionDecoder->ppiPredBandEnable[c][b], 1 ) ) + { + Word32 iA1Mag; + Word32 iA1Phase; + Word32 fA1Real; + Word32 fA1Imag; + iA1Mag = ISAR_SPLIT_REND_BITStream_read_int32( pBits, PRED_QUNAT_FILTER_MAG_BITS ); + iBitsRead = add( iBitsRead, PRED_QUNAT_FILTER_MAG_BITS ); + iA1Phase = ISAR_SPLIT_REND_BITStream_read_int32( pBits, PRED_QUANT_FILTER_PHASE_BITS ); + iBitsRead = add( iBitsRead, PRED_QUANT_FILTER_PHASE_BITS ); + + psPredictionDecoder->ppiA1Mag[c][b] = iA1Mag; + move32(); + psPredictionDecoder->ppiA1Phase[c][b] = L_add( iA1Phase, PRED_QUANT_FILTER_PHASE_MIN ); + move32(); + + fA1Real = Mpy_32_32( psPredictionDecoder->pfMagLUT_fx[iA1Mag], psPredictionDecoder->pfP2RRealLUT_fx[iA1Phase] ); /* Q31 */ + fA1Imag = Mpy_32_32( psPredictionDecoder->pfMagLUT_fx[iA1Mag], psPredictionDecoder->pfP2RImagLUT_fx[iA1Phase] ); /* Q31 */ + + psPredictionDecoder->ppfA1Real_fx[c][b] = fA1Real; /* Q31 */ + move32(); + psPredictionDecoder->ppfA1Imag_fx[c][b] = fA1Imag; /* Q31 */ + move32(); + } + } + } + } + + /* disable any inactive prediction bands */ + FOR( c = 0; c < psPredictionDecoder->iChannels; c++ ) + { + Word32 set; + FOR( set = 0; set < psPredictionDecoder->iNumSubSets; set++ ) + { + IF( !get_bit( psPredictionDecoder->piPredChanEnable[c], set ) ) + { + FOR( b = set; b < LCLD_BANDS; b = L_add( b, psPredictionDecoder->iNumSubSets ) ) + { + psPredictionDecoder->ppiPredBandEnable[c][b] = 0; + move32(); + } + } + } + } + + return iBitsRead; +} +/* PLC_IMPROVEMENT */ +void SetDecodingPassed( PredictionDecoder *psPredictionDecoder ) +{ + int32_t n, ch; + for ( ch = 0; ch < psPredictionDecoder->iChannels; ch++ ) + { + for ( n = 0; n < psPredictionDecoder->iNumSubSets; n++ ) + { + psPredictionDecoder->ppiDecodingFailed[ch][n] = 0; + } + } +} +int32_t AnyDecodingUnresolved( PredictionDecoder *psPredictionDecoder ) +{ + int32_t n, ch; + for ( ch = 0; ch < psPredictionDecoder->iChannels; ch++ ) + { + for ( n = 0; n < psPredictionDecoder->iNumSubSets; n++ ) + { + if ( psPredictionDecoder->ppiDecodingUnresolved[ch][n] == 1 ) + { + return 1; + } + } + } + return 0; +} + +void UpdateDecodingFailedStatus( PredictionDecoder *psPredictionDecoder ) +{ + int32_t n, ch; + for ( ch = 0; ch < psPredictionDecoder->iChannels; ch++ ) + { + for ( n = 0; n < psPredictionDecoder->iNumSubSets; n++ ) + { + psPredictionDecoder->ppiDecodingFailedPrev[ch][n] = psPredictionDecoder->ppiDecodingFailed[ch][n]; + } + } +} + +void UpdateDecodingUnresolved( PredictionDecoder *psPredictionDecoder ) +{ + int32_t n, ch; + + int32_t iCurrentSubSet = psPredictionDecoder->iSubSetId; + + for ( ch = 0; ch < psPredictionDecoder->iChannels; ch++ ) + { + /* Prediction data always available for current subset */ + psPredictionDecoder->ppiDecodingUnresolved[ch][iCurrentSubSet] = 0; + + for ( n = 0; n < psPredictionDecoder->iNumSubSets; n++ ) + { + int32_t iSubSetActive = get_bit( psPredictionDecoder->piPredChanEnable[ch], n ); + if ( iSubSetActive == 0 ) + { + /* Prediction information available inactive subsets (e.g. no Prediction) */ + psPredictionDecoder->ppiDecodingUnresolved[ch][n] = 0; + } + } + } +} + +/*-------------------------------------------------------------------* + * Function ApplyInversePredictors() + * + * + *-------------------------------------------------------------------*/ + +void ApplyInversePredictors_fx( + PredictionDecoder *psPredictionDecoder, + Word32 ***pppfReal, + Word32 ***pppfImag ) +{ + Word32 c; + FOR( c = 0; c < psPredictionDecoder->iChannels; c++ ) + { + IF( GT_32( psPredictionDecoder->piPredChanEnable[c], 0 ) ) + { + Word32 b; + FOR( b = 0; b < LCLD_BANDS; b++ ) + { + IF( EQ_32( psPredictionDecoder->ppiPredBandEnable[c][b], 1 ) ) + { + Word32 n; + Word32 fA1Real; + Word32 fA1Imag; + Word32 fPrevReal = 0; + move32(); + Word32 fPrevImag = 0; + move32(); + Word32 iSubset = b % psPredictionDecoder->iNumSubSets; + + IF( NE_32( iSubset, psPredictionDecoder->iSubSetId ) ) + { + fPrevReal = psPredictionDecoder->ppfPredStateReal_fx[c][b]; + move32(); + fPrevImag = psPredictionDecoder->ppfPredStateImag_fx[c][b]; + move32(); + } + + fA1Real = psPredictionDecoder->ppfA1Real_fx[c][b]; + move32(); + fA1Imag = psPredictionDecoder->ppfA1Imag_fx[c][b]; + move32(); + FOR( n = 0; n < psPredictionDecoder->iNumBlocks; n++ ) + { + Word32 fReal; + Word32 fImag; + + fReal = L_add( L_sub( pppfReal[c][n][b], Mpy_32_32( fA1Real, fPrevReal ) ), Mpy_32_32( fA1Imag, fPrevImag ) ); + fImag = L_sub( L_sub( pppfImag[c][n][b], Mpy_32_32( fA1Real, fPrevImag ) ), Mpy_32_32( fA1Imag, fPrevReal ) ); + + pppfReal[c][n][b] = fReal; + move32(); + pppfImag[c][n][b] = fImag; + move32(); + + fPrevReal = fReal; + move32(); + fPrevImag = fImag; + move32(); + } + psPredictionDecoder->ppfPredStateReal_fx[c][b] = fPrevReal; + move32(); + psPredictionDecoder->ppfPredStateImag_fx[c][b] = fPrevImag; + move32(); + } + } + } + } + + return; +} +#endif diff --git a/lib_isar/isar_PredEncoder.c b/lib_isar/isar_PredEncoder.c new file mode 100644 index 0000000000000000000000000000000000000000..0cd32b70cb625f7d6ea0e22b8a864cebf15c5d60 --- /dev/null +++ b/lib_isar/isar_PredEncoder.c @@ -0,0 +1,1215 @@ +/****************************************************************************************************** + + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository. All Rights Reserved. + + This software is protected by copyright law and by international treaties. + The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository retain full ownership rights in their respective contributions in + the software. This notice grants no license of any kind, including but not limited to patent + license, nor is any license granted by implication, estoppel or otherwise. + + Contributors are required to enter into the IVAS codec Public Collaboration agreement before making + contributions. + + This software is provided "AS IS", without any express or implied warranties. The software is in the + development stage. It is intended exclusively for experts who have experience with such software and + solely for the purpose of inspection. All implied warranties of non-infringement, merchantability + and fitness for a particular purpose are hereby disclaimed and excluded. + + Any dispute, controversy or claim arising under or in relation to providing this software shall be + submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in + accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and + the United Nations Convention on Contracts on the International Sales of Goods. + +*******************************************************************************************************/ + +#include +#include "options.h" +#ifdef SPLIT_REND_WITH_HEAD_ROT +#include +#include "isar_lcld_prot.h" +#include "isar_lcld_rom_tables.h" +#include "prot_fx.h" +#include "isar_prot.h" +#include "wmc_auto.h" +#include "prot_fx.h" +#include "basop_util.h" +#include "enh64.h" +#include "basop32.h" + + +/*-------------------------------------------------------------------* + * Function activate_bit() + * + * + *-------------------------------------------------------------------*/ +static void activate_bit( + Word32 *state, + const Word32 bit_id ) +{ + ( *state ) = L_or( ( *state ), L_shl( 1, extract_l( bit_id ) ) ); +} + +/*-------------------------------------------------------------------* + * Function deactivate_bit() + * + * + *-------------------------------------------------------------------*/ + +static void deactivate_bit( + Word32 *state, + const Word32 bit_id ) +{ + ( *state ) = L_and( ( *state ), ~L_shl( 1, extract_l( bit_id ) ) ); +} +void UpdatePredictionSubSetId( PredictionEncoder *psPredictionEncoder ) +{ + IF( EQ_32( ++psPredictionEncoder->iSubSetId, psPredictionEncoder->iNumSubSets ) ) + { + psPredictionEncoder->iSubSetId = 0; + move32(); + } +} +/*-------------------------------------------------------------------* + * Function CreatePredictionEncoder() + * + * + *-------------------------------------------------------------------*/ + +ivas_error CreatePredictionEncoder_fx( + PredictionEncoder **psPredictionEncoder_out, + const Word32 iChannels, + const Word32 iNumBlocks, + const Word32 iNumSubSets, + const Word32 iMaxNumPredBands ) +{ + Word32 k, n; + PredictionEncoder *psPredictionEncoder = NULL; + + IF( ( psPredictionEncoder = (PredictionEncoder *) malloc( sizeof( PredictionEncoder ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) ); + } + + psPredictionEncoder->iChannels = iChannels; + move32(); + psPredictionEncoder->iNumBlocks = iNumBlocks; + move32(); + psPredictionEncoder->iSubSetId = 0; + move32(); + psPredictionEncoder->iMaxNumPredBands = iMaxNumPredBands; + move32(); + psPredictionEncoder->iNumSubSets = iNumSubSets; + move32(); + IF( ( psPredictionEncoder->piPredChanEnable = (Word32 *) malloc( sizeof( Word32 ) * iChannels ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) ); + } + + IF( ( psPredictionEncoder->piNumPredBands = (Word32 *) malloc( sizeof( Word32 ) * 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++ ) + { + psPredictionEncoder->piPredChanEnable[n] = 0; + move32(); + psPredictionEncoder->piNumPredBands[n] = 40; // Will need to be set correctly + move32(); + } + + IF( ( psPredictionEncoder->ppiPredBandEnable = (Word32 **) malloc( sizeof( Word32 * ) * iChannels ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) ); + } + IF( ( psPredictionEncoder->ppfA1Real_fx = (Word32 **) malloc( sizeof( Word32 * ) * iChannels ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) ); + } + IF( ( psPredictionEncoder->ppfA1Imag_fx = (Word32 **) malloc( sizeof( Word32 * ) * iChannels ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) ); + } + IF( ( psPredictionEncoder->ppiA1Mag = (Word32 **) malloc( sizeof( Word32 * ) * iChannels ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) ); + } + IF( ( psPredictionEncoder->ppiA1Phase = (Word32 **) malloc( sizeof( Word32 * ) * iChannels ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) ); + } + IF( ( psPredictionEncoder->pppfInpBufReal_fx = (Word32 ***) malloc( sizeof( Word32 ** ) * iChannels ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) ); + } + IF( ( psPredictionEncoder->pppfInpBufImag_fx = (Word32 ***) malloc( sizeof( Word32 ** ) * iChannels ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) ); + } + IF( ( psPredictionEncoder->ppfInpPrevReal_fx = (Word32 **) malloc( sizeof( Word32 * ) * iChannels ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) ); + } + IF( ( psPredictionEncoder->ppfInpPrevImag_fx = (Word32 **) malloc( sizeof( Word32 * ) * iChannels ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) ); + } + IF( ( psPredictionEncoder->ppfPredStateReal_fx = (Word32 **) malloc( sizeof( Word32 * ) * iChannels ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) ); + } + IF( ( psPredictionEncoder->ppfPredStateImag_fx = (Word32 **) malloc( sizeof( Word32 * ) * iChannels ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) ); + } + IF( ( psPredictionEncoder->ppfPredStateRealTmp_fx = (Word32 **) malloc( sizeof( Word32 * ) * iChannels ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) ); + } + IF( ( psPredictionEncoder->ppfPredStateImagTmp_fx = (Word32 **) malloc( sizeof( Word32 * ) * 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->ppiPredBandEnable[n] = (Word32 *) malloc( sizeof( Word32 ) * LCLD_BANDS ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) ); + } + IF( ( psPredictionEncoder->ppfA1Real_fx[n] = (Word32 *) malloc( sizeof( Word32 ) * LCLD_BANDS ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) ); + } + IF( ( psPredictionEncoder->ppfA1Imag_fx[n] = (Word32 *) malloc( sizeof( Word32 ) * LCLD_BANDS ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) ); + } + IF( ( psPredictionEncoder->ppiA1Mag[n] = (Word32 *) malloc( sizeof( Word32 ) * LCLD_BANDS ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) ); + } + IF( ( psPredictionEncoder->ppiA1Phase[n] = (Word32 *) malloc( sizeof( Word32 ) * LCLD_BANDS ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) ); + } + IF( ( psPredictionEncoder->pppfInpBufReal_fx[n] = (Word32 **) malloc( sizeof( Word32 * ) * LCLD_PRED_WIN_LEN ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) ); + } + IF( ( psPredictionEncoder->pppfInpBufImag_fx[n] = (Word32 **) malloc( sizeof( Word32 * ) * 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_fx[n][k] = (Word32 *) malloc( LCLD_BANDS * sizeof( Word32 ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) ); + } + IF( ( psPredictionEncoder->pppfInpBufImag_fx[n][k] = (Word32 *) malloc( LCLD_BANDS * sizeof( Word32 ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) ); + } + set32_fx( psPredictionEncoder->pppfInpBufReal_fx[n][k], 0, LCLD_BANDS ); + set32_fx( psPredictionEncoder->pppfInpBufImag_fx[n][k], 0, LCLD_BANDS ); + } + IF( ( psPredictionEncoder->ppfPredStateReal_fx[n] = (Word32 *) malloc( LCLD_BANDS * sizeof( Word32 ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) ); + } + IF( ( psPredictionEncoder->ppfPredStateImag_fx[n] = (Word32 *) malloc( LCLD_BANDS * sizeof( Word32 ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) ); + } + set32_fx( psPredictionEncoder->ppfPredStateReal_fx[n], 0, LCLD_BANDS ); + set32_fx( psPredictionEncoder->ppfPredStateImag_fx[n], 0, LCLD_BANDS ); + + IF( ( psPredictionEncoder->ppfInpPrevReal_fx[n] = (Word32 *) malloc( LCLD_BANDS * sizeof( Word32 ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) ); + } + IF( ( psPredictionEncoder->ppfInpPrevImag_fx[n] = (Word32 *) malloc( LCLD_BANDS * sizeof( Word32 ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) ); + } + + set32_fx( psPredictionEncoder->ppfInpPrevReal_fx[n], 0, LCLD_BANDS ); + set32_fx( psPredictionEncoder->ppfInpPrevImag_fx[n], 0, LCLD_BANDS ); + + IF( ( psPredictionEncoder->ppfPredStateRealTmp_fx[n] = (Word32 *) malloc( LCLD_BANDS * sizeof( Word32 ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) ); + } + IF( ( psPredictionEncoder->ppfPredStateImagTmp_fx[n] = (Word32 *) malloc( LCLD_BANDS * sizeof( Word32 ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) ); + } + set32_fx( psPredictionEncoder->ppfPredStateRealTmp_fx[n], 0, LCLD_BANDS ); + set32_fx( psPredictionEncoder->ppfPredStateImagTmp_fx[n], 0, LCLD_BANDS ); + FOR( k = 0; k < LCLD_BANDS; k++ ) + { + psPredictionEncoder->ppiPredBandEnable[n][k] = 0; + move32(); + psPredictionEncoder->ppfA1Real_fx[n][k] = 0; + move32(); + psPredictionEncoder->ppfA1Imag_fx[n][k] = 0; + move32(); + } + } + + *psPredictionEncoder_out = psPredictionEncoder; + + return IVAS_ERR_OK; +} +ivas_error CreatePredictionEncoder( + PredictionEncoder **psPredictionEncoder_out, + const int32_t iChannels, + const int32_t iNumBlocks, + const int32_t iNumSubSets, + const int32_t iMaxNumPredBands ) +{ + int32_t k, n; + PredictionEncoder *psPredictionEncoder = NULL; + + if ( ( psPredictionEncoder = (PredictionEncoder *) malloc( sizeof( PredictionEncoder ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) ); + } + + psPredictionEncoder->iChannels = iChannels; + psPredictionEncoder->iNumBlocks = iNumBlocks; + psPredictionEncoder->iSubSetId = 0; + psPredictionEncoder->iMaxNumPredBands = iMaxNumPredBands; + psPredictionEncoder->iNumSubSets = iNumSubSets; + + 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" ) ); + } + + if ( ( psPredictionEncoder->piNumPredBands = (int32_t *) malloc( sizeof( int32_t ) * 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++ ) + { + psPredictionEncoder->piPredChanEnable[n] = 0; + psPredictionEncoder->piNumPredBands[n] = 40; // Will need to be set correctly + } + + 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->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->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->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->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->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->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->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->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->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->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->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->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->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.0f; + psPredictionEncoder->ppfA1Imag[n][k] = 0.0f; + } + } + + *psPredictionEncoder_out = psPredictionEncoder; + + return IVAS_ERR_OK; +} + + +/*-------------------------------------------------------------------* + * Function DeletePredictionEncoder() + * + * + *-------------------------------------------------------------------*/ + +void DeletePredictionEncoder_fx( + PredictionEncoder *psPredictionEncoder ) +{ + Word32 n; + FOR( n = 0; n < psPredictionEncoder->iChannels; n++ ) + { + Word32 k; + free( psPredictionEncoder->ppiPredBandEnable[n] ); + free( psPredictionEncoder->ppfA1Real_fx[n] ); + free( psPredictionEncoder->ppfA1Imag_fx[n] ); + free( psPredictionEncoder->ppiA1Mag[n] ); + free( psPredictionEncoder->ppiA1Phase[n] ); + FOR( k = 0; k < LCLD_PRED_WIN_LEN; k++ ) + { + free( psPredictionEncoder->pppfInpBufReal_fx[n][k] ); + free( psPredictionEncoder->pppfInpBufImag_fx[n][k] ); + } + free( psPredictionEncoder->pppfInpBufReal_fx[n] ); + free( psPredictionEncoder->pppfInpBufImag_fx[n] ); + free( psPredictionEncoder->ppfInpPrevReal_fx[n] ); + free( psPredictionEncoder->ppfInpPrevImag_fx[n] ); + free( psPredictionEncoder->ppfPredStateReal_fx[n] ); + free( psPredictionEncoder->ppfPredStateImag_fx[n] ); + free( psPredictionEncoder->ppfPredStateRealTmp_fx[n] ); + free( psPredictionEncoder->ppfPredStateImagTmp_fx[n] ); + } + free( psPredictionEncoder->piPredChanEnable ); + free( psPredictionEncoder->piNumPredBands ); + free( psPredictionEncoder->ppiPredBandEnable ); + free( psPredictionEncoder->ppfA1Real_fx ); + free( psPredictionEncoder->ppfA1Imag_fx ); + free( psPredictionEncoder->ppiA1Mag ); + free( psPredictionEncoder->ppiA1Phase ); + free( psPredictionEncoder->pppfInpBufReal_fx ); + free( psPredictionEncoder->pppfInpBufImag_fx ); + free( psPredictionEncoder->ppfInpPrevReal_fx ); + free( psPredictionEncoder->ppfInpPrevImag_fx ); + free( psPredictionEncoder->ppfPredStateReal_fx ); + free( psPredictionEncoder->ppfPredStateImag_fx ); + free( psPredictionEncoder->ppfPredStateRealTmp_fx ); + free( psPredictionEncoder->ppfPredStateImagTmp_fx ); + + + free( psPredictionEncoder ); + + return; +} +void DeletePredictionEncoder( + PredictionEncoder *psPredictionEncoder ) +{ + int32_t n; + for ( n = 0; n < psPredictionEncoder->iChannels; 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->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 ); + + return; +} + + +/*-------------------------------------------------------------------* + * Function ComputePredictors() + * + * + *-------------------------------------------------------------------*/ + +void ComputePredictors( + PredictionEncoder *psPredictionEncoder, + float ***pppfReal, + float ***pppfImag ) +{ + int32_t c; + + 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; + for ( b = b0; b < psPredictionEncoder->iMaxNumPredBands; b += bstep ) + { + int32_t n; + float fGain = 0.0; + float fBitGain = 0.0; + float *pfRxxReal; + float *pfRxxImag; + float fA1Real; + float fA1Imag; + int32_t iA1Mag; + int32_t iA1Phase; + + pfRxxReal = psPredictionEncoder->pfRxxReal; + pfRxxImag = psPredictionEncoder->pfRxxImag; + + pfRxxReal[0] = 0.0; + pfRxxImag[0] = 0.0; + for ( n = 0; n < LCLD_PRED_WIN_LEN; n++ ) + { + 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 < LCLD_PRED_WIN_LEN; n++ ) + { + 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 ) + { + float fA1Mag; + 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 ); + const float fPhaseScale = (float) ( 1 << ( PRED_QUANT_FILTER_PHASE_BITS - 1 ) ) / M_PI; + const float fInvPhaseScale = M_PI / (float) ( 1 << ( PRED_QUANT_FILTER_PHASE_BITS - 1 ) ); + + /* Compute filter coefficeints */ + fA1Real = -pfRxxReal[1] / pfRxxReal[0]; + fA1Imag = -pfRxxImag[1] / pfRxxReal[0]; + + /* compute these before quant */ + /* Compute est coding gain based on quantized filter coefficients */ + fGain = 1.0f / ( 1.0f - fA1Real * fA1Real - fA1Imag * fA1Imag ); + fBitGain = 0.65f * log2f( fGain ) * (float) ( iNumBlocksPerPredCoef ) - (float) ( PRED_QUNAT_FILTER_MAG_BITS + PRED_QUANT_FILTER_PHASE_BITS ); // Wrong fix (iNumBlocks-1) + fA1Mag = sqrtf( fA1Real * fA1Real + fA1Imag * fA1Imag ); + fA1Mag = fMagScale * asinf( fA1Mag ); + iA1Mag = (int32_t) ( fA1Mag + 0.5f ); + iA1Mag = ( iA1Mag > PRED_QUANT_FILTER_MAG_MIN ) ? iA1Mag : PRED_QUANT_FILTER_MAG_MIN; + iA1Mag = ( iA1Mag < PRED_QUANT_FILTER_MAG_MAX ) ? iA1Mag : PRED_QUANT_FILTER_MAG_MAX; + fA1Mag = sinf( fInvMagScale * (float) iA1Mag ); + + fA1Phase = atan2f( fA1Imag, fA1Real ); + fA1Phase = fPhaseScale * fA1Phase; + iA1Phase = ( fA1Phase > 0.0f ) ? (int32_t) ( fA1Phase + 0.5f ) : (int32_t) ( fA1Phase - 0.5f ); + iA1Phase = ( iA1Phase > PRED_QUANT_FILTER_PHASE_MIN ) ? iA1Phase : PRED_QUANT_FILTER_PHASE_MIN; + iA1Phase = ( iA1Phase < PRED_QUANT_FILTER_PHASE_MAX ) ? iA1Phase : PRED_QUANT_FILTER_PHASE_MAX; // Is this the correct way to deal with this? should wrap? + fA1Phase = fInvPhaseScale * (float) iA1Phase; + + fA1Real = fA1Mag * cosf( fA1Phase ); + fA1Imag = fA1Mag * sinf( fA1Phase ); + + fGain2 = 1.0f / ( 1.0f - fA1Real * fA1Real - fA1Imag * fA1Imag ); + fBitGain2 = 0.65f * log2f( fGain ) * (float) ( iNumBlocksPerPredCoef ) - (float) ( PRED_QUNAT_FILTER_MAG_BITS + PRED_QUANT_FILTER_PHASE_BITS ); // Wrong fix (iNumBlocks-1) + fGain = ( fGain < fGain2 ) ? fGain : fGain2; + fBitGain = ( fBitGain < fBitGain2 ) ? fBitGain : fBitGain2; + } + else + { + fA1Real = 0.0f; + fA1Imag = 0.0f; + iA1Mag = 0; + iA1Phase = 0; + fGain = -10.0f; // Fix this + } + + 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; + psPredictionEncoder->ppiA1Phase[c][b] = iA1Phase; + } + + { + float fBestCost; + int32_t iPredBands; + float fBitGain; + int32_t iPredChanEnable = 0; + + fBestCost = 0.0; + iPredBands = 0; + fBitGain = -7.0; + for ( b = b0; b < psPredictionEncoder->iMaxNumPredBands; b += bstep ) + { // still getting this decision wrong! + fBitGain -= 1.0; + if ( psPredictionEncoder->ppiPredBandEnable[c][b] == 1 ) + { + fBitGain += pfEstPredBitGain[b]; + } + if ( fBitGain > fBestCost ) + { + fBestCost = fBitGain; + iPredBands = b; + iPredChanEnable = 1; + } + } + + if ( iPredChanEnable == 1 ) + { + for ( b = iPredBands + bstep; b < LCLD_BANDS; b += bstep ) + { + psPredictionEncoder->ppiPredBandEnable[c][b] = 0; + } + activate_bit( &psPredictionEncoder->piPredChanEnable[c], psPredictionEncoder->iSubSetId ); + psPredictionEncoder->piNumPredBands[c] = iPredBands + bstep; + } + else + { + for ( b = b0; b < LCLD_BANDS; b += bstep ) + { + psPredictionEncoder->ppiPredBandEnable[c][b] = 0; + } + deactivate_bit( &psPredictionEncoder->piPredChanEnable[c], psPredictionEncoder->iSubSetId ); + psPredictionEncoder->piNumPredBands[c] = 0; + } + } + } +} + +void ComputePredictors_fx( + PredictionEncoder *psPredictionEncoder, + Word32 ***pppfReal_fx, // Q12? + Word32 ***pppfImag_fx ) // Q12? +{ + Word32 c; + + Word32 b0 = psPredictionEncoder->iSubSetId; + Word32 bstep = psPredictionEncoder->iNumSubSets; + Word32 iNumBlocks = psPredictionEncoder->iNumBlocks; + /*float ***pppfRealBuf; + float ***pppfImagBuf;*/ + Word32 ***pppfRealBuf_fx; + Word32 ***pppfImagBuf_fx; + // float pfEstPredBitGain[LCLD_BANDS] = { 0 }; + Word32 pfEstPredBitGain_fx[LCLD_BANDS] = { 0 }; + + IF( LT_32( iNumBlocks, LCLD_PRED_WIN_LEN ) ) + { + /*pppfRealBuf = psPredictionEncoder->pppfInpBufReal; + pppfImagBuf = psPredictionEncoder->pppfInpBufImag;*/ + pppfRealBuf_fx = psPredictionEncoder->pppfInpBufReal_fx; + move32(); + pppfImagBuf_fx = psPredictionEncoder->pppfInpBufImag_fx; + move32(); + FOR( c = 0; c < psPredictionEncoder->iChannels; c++ ) + { + Word32 n; + FOR( n = 0; n < L_sub( 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);*/ + mvl2l( pppfRealBuf_fx[c][n + iNumBlocks], pppfRealBuf_fx[c][n], LCLD_BANDS ); + mvl2l( pppfImagBuf_fx[c][n + iNumBlocks], pppfImagBuf_fx[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);*/ + mvl2l( pppfReal_fx[c][n], pppfRealBuf_fx[c][n + LCLD_PRED_WIN_LEN - iNumBlocks], LCLD_BANDS ); + mvl2l( pppfImag_fx[c][n], pppfImagBuf_fx[c][n + LCLD_PRED_WIN_LEN - iNumBlocks], LCLD_BANDS ); + } + } + } + ELSE + { + /*pppfRealBuf = pppfReal; + pppfImagBuf = pppfImag;*/ + pppfRealBuf_fx = pppfReal_fx; + move32(); + pppfImagBuf_fx = pppfImag_fx; + move32(); + } + + FOR( c = 0; c < psPredictionEncoder->iChannels; c++ ) + { + Word32 b; + FOR( b = b0; b < psPredictionEncoder->iMaxNumPredBands; b += bstep ) + { + Word32 n; + /*float fGain = 0.0; + float fBitGain = 0.0; + float *pfRxxReal; + float *pfRxxImag; + float fA1Real; + float fA1Imag;*/ + Word32 fGain_fx = 0; + Word32 fBitGain_fx = 0; + Word32 *pfRxxReal_fx; + Word32 *pfRxxImag_fx; + Word32 fA1Real_fx; + Word32 fA1Imag_fx; + Word32 L_temp; + Word64 W_temp1, W_temp2; + Word32 iA1Mag; + Word32 iA1Phase; + + /*pfRxxReal = psPredictionEncoder->pfRxxReal; + pfRxxImag = psPredictionEncoder->pfRxxImag;*/ + pfRxxReal_fx = psPredictionEncoder->pfRxxReal_fx; + move32(); + pfRxxImag_fx = psPredictionEncoder->pfRxxImag_fx; + move32(); + /*pfRxxReal[0] = 0.0; + pfRxxImag[0] = 0.0;*/ + pfRxxReal_fx[0] = 0; + move32(); + pfRxxImag_fx[0] = 0; + move32(); + W_temp1 = 0; + FOR( n = 0; n < LCLD_PRED_WIN_LEN; n++ ) + { + // pfRxxReal[0] += (pppfRealBuf[c][n][b] * pppfRealBuf[c][n][b] + pppfImagBuf[c][n][b] * pppfImagBuf[c][n][b]); + W_temp1 = W_add( W_temp1, W_add( W_mult0_32_32( pppfRealBuf_fx[c][n][b], pppfRealBuf_fx[c][n][b] ), + W_mult0_32_32( pppfImagBuf_fx[c][n][b], pppfImagBuf_fx[c][n][b] ) ) ); // Q40 + } + Word16 w_norm1 = W_norm( W_temp1 ); + W_temp1 = W_shr( W_temp1, 32 - w_norm1 ); + pfRxxReal_fx[0] = W_extract_l( W_temp1 ); + /*pfRxxReal[1] = 0.0; + pfRxxImag[1] = 0.0;*/ + pfRxxReal_fx[1] = 0; + move32(); + pfRxxImag_fx[1] = 0; + move32(); + W_temp1 = 0; + W_temp2 = 0; + FOR( n = 1; n < LCLD_PRED_WIN_LEN; n++ ) + { + /*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]);*/ + W_temp1 = W_add( W_temp1, W_add( W_mult0_32_32( pppfRealBuf_fx[c][n][b], pppfRealBuf_fx[c][n - 1][b] ), + W_mult0_32_32( pppfImagBuf_fx[c][n][b], pppfImagBuf_fx[c][n - 1][b] ) ) ); // Q40 + W_temp2 = W_add( W_temp2, W_sub( W_mult0_32_32( pppfImagBuf_fx[c][n][b], pppfRealBuf_fx[c][n - 1][b] ), + W_mult0_32_32( pppfRealBuf_fx[c][n][b], pppfImagBuf_fx[c][n - 1][b] ) ) ); // Q40 + } + + Word16 w_norm2 = W_norm( W_temp1 ); + W_temp1 = W_shr( W_temp1, 32 - w_norm2 ); + pfRxxReal_fx[1] = W_extract_l( W_temp1 ); + Word16 w_norm3 = W_norm( W_temp2 ); + W_temp2 = W_shr( W_temp2, 32 - w_norm3 ); + pfRxxImag_fx[1] = W_extract_l( W_temp2 ); + Word16 final_w_norm = min( w_norm1, min( w_norm2, w_norm3 ) ); + pfRxxReal_fx[0] = L_shr( pfRxxReal_fx[0], w_norm1 - final_w_norm ); // Q8 + final_w_norm + pfRxxReal_fx[1] = L_shr( pfRxxReal_fx[1], w_norm2 - final_w_norm ); // Q8 + final_w_norm + pfRxxImag_fx[1] = L_shr( pfRxxImag_fx[1], w_norm3 - final_w_norm ); // Q8 + final_w_norm + // if (pfRxxReal[0] > 1e-12f) + IF( GT_32( pfRxxReal_fx[0], 0 ) ) + { + /*float fA1Mag; + float fA1Phase; + float fGain2; + float fBitGain2;*/ + Word32 fA1Mag_fx; + Word32 fA1Phase_fx; + Word32 fGain2_fx; + Word32 fBitGain2_fx; + Word32 iNumBlocksPerPredCoef = L_min( iNumBlocks * psPredictionEncoder->iNumSubSets, LCLD_PRED_WIN_LEN ); + const Word32 fMagScale_fx32 = 1452576210; // Q28 + move32(); + // const float fInvMagScale = M_PI / (2.0f * (float)(1 << (PRED_QUNAT_FILTER_MAG_BITS)) + 1.0f); + const Word16 fInvMagScale_fx = 6055; // Q15 + move16(); + // const float fPhaseScale = (float)(1 << (PRED_QUANT_FILTER_PHASE_BITS - 1)) / M_PI + const Word32 fPhaseScale_fx32 = 1367130551; // Q28 + // const float fInvPhaseScale = M_PI / (float)(1 << (PRED_QUANT_FILTER_PHASE_BITS - 1)); + const Word16 fInvPhaseScale_fx = 6434; // Q15 + move16(); + + /* Compute filter coefficeints */ + // fA1Real = -pfRxxReal[1] / pfRxxReal[0]; + Word16 sf_r, sf_i; + fA1Real_fx = BASOP_Util_Divide3232_Scale( -pfRxxReal_fx[1], pfRxxReal_fx[0], &sf_r ); + // fA1Imag = -pfRxxImag[1] / pfRxxReal[0]; + fA1Imag_fx = BASOP_Util_Divide3232_Scale( -pfRxxImag_fx[1], pfRxxReal_fx[0], &sf_i ); + + IF( GT_16( sf_r, sf_i ) ) + { + fA1Imag_fx = L_shr( fA1Imag_fx, sub( sf_r, sf_i ) ); + sf_i = sf_r; + move16(); + } + ELSE IF( LT_16( sf_r, sf_i ) ) + { + fA1Real_fx = L_shr( fA1Real_fx, sub( sf_i, sf_r ) ); + sf_r = sf_i; + move16(); + } + Word32 L_temp_1; + IF( LT_16( sf_r, -7 ) ) + { + fA1Real_fx = L_shr( fA1Real_fx, sub( -8, sf_r ) ); + fA1Imag_fx = L_shr( fA1Imag_fx, sub( -8, sf_i ) ); + sf_r = sf_i = -8; + move16(); + L_temp_1 = MAX_32; + move32(); + } + ELSE + { + L_temp_1 = L_shl( 1, sub( 15, shl( sf_r, 1 ) ) ); + } + /* compute these before quant */ + /* Compute est coding gain based on quantized filter coefficients */ + // fGain = 1.0f / (1.0f - fA1Real * fA1Real - fA1Imag * fA1Imag); + L_temp = L_sub( L_sub( L_temp_1, mult_r( extract_l( fA1Real_fx ), extract_l( fA1Real_fx ) ) ), mult_r( extract_l( fA1Imag_fx ), extract_l( fA1Imag_fx ) ) ); + Word16 exp = norm_l( L_temp ); + IF( LT_16( exp, 16 ) ) + { + L_temp = L_shr( L_temp, sub( 16, exp ) ); + exp = add( sub( 16, exp ), shl( sf_r, 1 ) ); + } + else + { + exp = shl( sf_r, 1 ); + } + // fGain_fx = sub(sub(32767, extract_h(Mpy_32_32(fA1Real_fx, fA1Real_fx))), extract_h(Mpy_32_32(fA1Imag_fx, fA1Imag_fx))); + // fGain_fx = extract_l(L_shl(L_temp, 2*sf_r)); + fGain_fx = extract_l( L_temp ); + fGain_fx = max( 1, fGain_fx ); + fGain_fx = Inv16( extract_l( fGain_fx ), &exp ); // Q15 - exp + // fGain_fx = L_shl(fGain_fx, exp); //Q15 + // fBitGain = 0.65f * log2f(fGain) * (float)(iNumBlocksPerPredCoef)-(float)(PRED_QUNAT_FILTER_MAG_BITS + PRED_QUANT_FILTER_PHASE_BITS); // Wrong fix (iNumBlocks-1) + // fBitGain_fx = L_sub(L_mult0(L_shr(L_mult0(21299, L_shr(L_add(BASOP_Util_Log2(fGain_fx), 335544320), 10)), 15), (Word16)iNumBlocksPerPredCoef), 262144); // Wrong fix (iNumBlocks-1) Q15 + W_temp1 = W_mult0_32_32( L_shr( Mpy_32_32( 1395864371, L_add( BASOP_Util_Log2( fGain_fx ), L_shl( add( 16, exp ), 25 ) ) ), 10 ), iNumBlocksPerPredCoef ); + Word16 w_norm4 = W_norm( W_temp1 ); + IF( LT_16( w_norm4, 32 ) ) + { + W_temp1 = W_shr( W_temp1, 32 - w_norm4 ); + w_norm4 = sub( 32, w_norm4 ); + } + ELSE + { + w_norm4 = 0; + move16(); + } + fBitGain_fx = L_sub( W_extract_l( W_temp1 ), L_shr( 262144, w_norm4 ) ); // Wrong fix (iNumBlocks-1) Q15 + // fA1Mag = sqrtf(fA1Real * fA1Real + fA1Imag * fA1Imag); + fA1Mag_fx = L_add( mult_r( extract_l( fA1Real_fx ), extract_l( fA1Real_fx ) ), mult_r( extract_l( fA1Imag_fx ), extract_l( fA1Imag_fx ) ) ); // Q15 - 2*sf_r + // fA1Mag = fMagScale * asinf(fA1Mag); + exp = 0; + move16(); + L_temp = L_sub( L_temp_1, fA1Mag_fx ); // Q15 - 2*sf_r + IF( NE_32( L_temp, 0 ) ) + { + fA1Mag_fx = BASOP_Util_Divide3232_Scale( fA1Mag_fx, L_temp, &exp ); + } + ELSE + { + fA1Mag_fx = 0; + move32(); + exp = 0; + move16(); + } + fA1Mag_fx = L_shl( fA1Mag_fx, 16 ); + IF( fA1Mag_fx > 0 ) + { + fA1Mag_fx = Sqrt32( fA1Mag_fx, &exp ); + } + ELSE + { + fA1Mag_fx = 0; + move32(); + exp = 0; + move16(); + } + + fA1Mag_fx = BASOP_util_atan( L_shr_r_sat( fA1Mag_fx, 6 - exp ) ); // Q14 + fA1Mag_fx = Mpy_32_16_1( fMagScale_fx32, extract_l( fA1Mag_fx ) ); // Q27 + + // iA1Mag = (int32_t)(fA1Mag + 0.5f); + IF( GE_32( fA1Mag_fx, 0 ) ) + { + iA1Mag = L_shr( L_add( fA1Mag_fx, 67108864 ), Q27 ); // Q27 -> Q0 + } + ELSE + { + fA1Mag_fx = L_negate( fA1Mag_fx ); + iA1Mag = L_shr( L_add( fA1Mag_fx, 67108864 ), Q27 ); // Q27 -> Q0 + iA1Mag = L_negate( iA1Mag ); + } + iA1Mag = ( iA1Mag > PRED_QUANT_FILTER_MAG_MIN ) ? iA1Mag : PRED_QUANT_FILTER_MAG_MIN; + iA1Mag = ( iA1Mag < PRED_QUANT_FILTER_MAG_MAX ) ? iA1Mag : PRED_QUANT_FILTER_MAG_MAX; + // fA1Mag = sinf(fInvMagScale * (float)iA1Mag); + fA1Mag_fx = L_deposit_l( shr( getSinWord16( extract_l( L_shr( L_mult0( extract_l( fInvMagScale_fx ), extract_l( iA1Mag ) ), 2 ) ) ), 1 ) ); // Q14 + + // fA1Phase = atan2f(fA1Imag, fA1Real); + fA1Phase_fx = BASOP_util_atan2( fA1Imag_fx, fA1Real_fx, 0 ); // Q13 + // fA1Phase = fPhaseScale * fA1Phase; + fA1Phase_fx = Mpy_32_16_1( fPhaseScale_fx32, extract_l( fA1Phase_fx ) ); // Q26 + // iA1Phase = (fA1Phase > 0.0f) ? (int32_t)(fA1Phase + 0.5f) : (int32_t)(fA1Phase - 0.5f); + // iA1Phase = (fA1Phase_fx > 0) ? shr(add(fA1Phase_fx, 512), 10) : shr(sub(fA1Phase_fx, 512), 10); + IF( GE_32( fA1Phase_fx, 0 ) ) + { + iA1Phase = L_shr( L_add( fA1Phase_fx, 33554432 ), Q26 ); // Q26 -> Q0 + } + ELSE + { + fA1Phase_fx = L_negate( fA1Phase_fx ); + iA1Phase = L_shr( L_add( fA1Phase_fx, 33554432 ), Q26 ); // Q26 -> Q0 + iA1Phase = L_negate( iA1Phase ); + } + iA1Phase = ( iA1Phase > PRED_QUANT_FILTER_PHASE_MIN ) ? iA1Phase : PRED_QUANT_FILTER_PHASE_MIN; + iA1Phase = ( iA1Phase < PRED_QUANT_FILTER_PHASE_MAX ) ? iA1Phase : PRED_QUANT_FILTER_PHASE_MAX; // Is this the correct way to deal with this? should wrap? + // fA1Phase = fInvPhaseScale * (float)iA1Phase; + L_temp = L_mult0( fInvPhaseScale_fx, (Word16) iA1Phase ); // Q15 + + // fA1Real = fA1Mag * cosf(fA1Phase); + fA1Real_fx = L_mult0( extract_l( fA1Mag_fx ), getCosWord16( extract_l( L_shr( L_temp, 2 ) ) ) ); // Q28 + // fA1Imag = fA1Mag * sinf(fA1Phase); + fA1Imag_fx = L_mult0( extract_l( fA1Mag_fx ), shr( getSinWord16( extract_l( L_shr( L_temp, 2 ) ) ), 1 ) ); // Q28 + + // fGain2 = 1.0f / (1.0f - fA1Real * fA1Real - fA1Imag * fA1Imag); + exp = 0; + fGain2_fx = sub( sub( 32767, mult_r( extract_l( L_shr( fA1Real_fx, 13 ) ), extract_l( L_shr( fA1Real_fx, 13 ) ) ) ), mult_r( extract_l( L_shr( fA1Imag_fx, 13 ) ), extract_l( L_shr( fA1Imag_fx, 13 ) ) ) ); + fGain2_fx = L_max( 1, fGain2_fx ); + fGain2_fx = Inv16( extract_l( fGain2_fx ), &exp ); // Q15-exp + fGain2_fx = L_shl( fGain2_fx, exp ); + // fBitGain2 = 0.65f * log2f(fGain) * (float)(iNumBlocksPerPredCoef)-(float)(PRED_QUNAT_FILTER_MAG_BITS + PRED_QUANT_FILTER_PHASE_BITS); // Wrong fix (iNumBlocks-1) + // fBitGain2_fx = L_sub(L_mult0(L_shr(L_mult0(21299, L_shr(L_add(BASOP_Util_Log2(fGain_fx), 335544320), 10)), 15), (Word16)iNumBlocksPerPredCoef), 262144); // Wrong fix (iNumBlocks-1) Q15 + fBitGain2_fx = L_sub( W_extract_l( W_temp1 ), L_shr( 262144, w_norm4 ) ); // Wrong fix (iNumBlocks-1) Q15 + // fGain = (fGain < fGain2) ? fGain : fGain2; + fGain_fx = ( fGain_fx < fGain2_fx ) ? fGain_fx : fGain2_fx; + // fBitGain = (fBitGain < fBitGain2) ? fBitGain : fBitGain2; + fBitGain_fx = ( fBitGain_fx < fBitGain2_fx ) ? fBitGain_fx : fBitGain2_fx; + } + ELSE + { + /*fA1Real = 0.0f; + fA1Imag = 0.0f;*/ + fA1Real_fx = 0; + move32(); + fA1Imag_fx = 0; + move32(); + iA1Mag = 0; + move32(); + iA1Phase = 0; + move32(); + // fGain = -10.0f; // Fix this + fGain_fx = -327680; // Fix this + move32(); + } + + // pfEstPredBitGain[b] = fBitGain; + // psPredictionEncoder->ppiPredBandEnable[c][b] = (fBitGain > 0.0f); // Initial prediction enable + // psPredictionEncoder->ppfA1Real[c][b] = fA1Real; + // psPredictionEncoder->ppfA1Imag[c][b] = fA1Imag; + pfEstPredBitGain_fx[b] = fBitGain_fx; // Q15 + move32(); + // printf("\n %d %d %f %f %f ", iA1Mag, iA1Phase, (float)fBitGain_fx / 32768, (float)fA1Real_fx / ONE_IN_Q28, (float)fA1Imag_fx / ONE_IN_Q28); + psPredictionEncoder->ppiPredBandEnable[c][b] = ( fBitGain_fx > 0 ); // Initial prediction enable + psPredictionEncoder->ppfA1Real_fx[c][b] = L_shl( fA1Real_fx, Q3 ); // Q31 + psPredictionEncoder->ppfA1Imag_fx[c][b] = L_shl( fA1Imag_fx, Q3 ); // Q31 + psPredictionEncoder->ppiA1Mag[c][b] = iA1Mag; + move32(); + psPredictionEncoder->ppiA1Phase[c][b] = iA1Phase; + move32(); + } + + { + // float fBestCost; + Word32 fBestCost_fx; + Word32 iPredBands; + // float fBitGain; + Word32 fBitGain_fx; + Word32 iPredChanEnable = 0; + + // fBestCost = 0.0; + fBestCost_fx = 0; + move32(); + iPredBands = 0; + move32(); + // fBitGain = -7.0; + fBitGain_fx = -229376; // Q15 + move32(); + FOR( b = b0; b < psPredictionEncoder->iMaxNumPredBands; b += bstep ) + { // still getting this decision wrong! + // fBitGain -= 1.0; + fBitGain_fx = L_sub( fBitGain_fx, 32768 ); + IF( EQ_32( psPredictionEncoder->ppiPredBandEnable[c][b], 1 ) ) + { + // fBitGain += pfEstPredBitGain[b]; + fBitGain_fx = L_add( fBitGain_fx, pfEstPredBitGain_fx[b] ); + } + // if (fBitGain > fBestCost) + IF( GT_32( fBitGain_fx, fBestCost_fx ) ) + { + fBestCost_fx = fBitGain_fx; + iPredBands = b; + iPredChanEnable = 1; + } + } + + IF( EQ_32( iPredChanEnable, 1 ) ) + { + FOR( b = iPredBands + bstep; b < LCLD_BANDS; b += bstep ) + { + psPredictionEncoder->ppiPredBandEnable[c][b] = 0; + } + activate_bit( &psPredictionEncoder->piPredChanEnable[c], psPredictionEncoder->iSubSetId ); + psPredictionEncoder->piNumPredBands[c] = iPredBands + bstep; + } + ELSE + { + FOR( b = b0; b < LCLD_BANDS; b += bstep ) + { + psPredictionEncoder->ppiPredBandEnable[c][b] = 0; + } + deactivate_bit( &psPredictionEncoder->piPredChanEnable[c], psPredictionEncoder->iSubSetId ); + psPredictionEncoder->piNumPredBands[c] = 0; + move32(); + } + } + } +} + +/*-------------------------------------------------------------------* + * Function ApplyForwardPredictors() + * + * + *-------------------------------------------------------------------*/ + +/*-------------------------------------------------------------------* + * Function WritePredictors() + * + * + *-------------------------------------------------------------------*/ + +Word32 WritePredictors( + PredictionEncoder *psPredictionEncoder, + ISAR_SPLIT_REND_BITS_HANDLE pBits ) +{ + Word32 iBitsWritten = 0; + Word32 c; + Word32 iNumSubSets = psPredictionEncoder->iNumSubSets; + Word32 iSubSetId = psPredictionEncoder->iSubSetId; + Word32 iNumPredBandBits = 6; + const Word16 iSubSetBits = ( GT_16( LCLD_MAX_NUM_PRED_SUBSETS, 4 ) ? 3 : 2 ); + move32(); + move32(); + move16(); + + /* number of subsets */ + ISAR_SPLIT_REND_BITStream_write_int32( pBits, L_sub( iNumSubSets, 1 ), iSubSetBits ); /* otherwise use default */ + iBitsWritten = L_add( iBitsWritten, iSubSetBits ); + + IF( GT_32( iNumSubSets, 1 ) ) + { + /* write current subset */ + ISAR_SPLIT_REND_BITStream_write_int32( pBits, iSubSetId, iSubSetBits ); + iBitsWritten = L_add( iBitsWritten, iSubSetBits ); + iNumPredBandBits = ( GE_32( iNumSubSets, 4 ) ? 4 : 5 ); + move32(); + } + + FOR( c = 0; c < psPredictionEncoder->iChannels; c++ ) + { + Word32 b; + Word32 b0 = iSubSetId; + move32(); + + ISAR_SPLIT_REND_BITStream_write_int32( pBits, psPredictionEncoder->piPredChanEnable[c], iNumSubSets ); + iBitsWritten = L_add( iBitsWritten, iNumSubSets ); + + IF( get_bit( psPredictionEncoder->piPredChanEnable[c], iSubSetId ) ) + { + Word32 iNumPredBands = L_sub( psPredictionEncoder->piNumPredBands[c], b0 ) / iNumSubSets; + + ISAR_SPLIT_REND_BITStream_write_int32( pBits, iNumPredBands, iNumPredBandBits ); + iBitsWritten = L_add( iBitsWritten, iNumPredBandBits ); + + FOR( b = b0; b < psPredictionEncoder->piNumPredBands[c]; b += iNumSubSets ) + { + ISAR_SPLIT_REND_BITStream_write_int32( pBits, psPredictionEncoder->ppiPredBandEnable[c][b], 1 ); + iBitsWritten = L_add( iBitsWritten, 1 ); + + IF( EQ_32( psPredictionEncoder->ppiPredBandEnable[c][b], 1 ) ) + { + Word32 iA1Mag; + Word32 iA1Phase; + + iA1Mag = psPredictionEncoder->ppiA1Mag[c][b]; + move32(); + iA1Phase = L_sub( psPredictionEncoder->ppiA1Phase[c][b], PRED_QUANT_FILTER_PHASE_MIN ); + + ISAR_SPLIT_REND_BITStream_write_int32( pBits, iA1Mag, PRED_QUNAT_FILTER_MAG_BITS ); + iBitsWritten = L_add( iBitsWritten, PRED_QUNAT_FILTER_MAG_BITS ); + + ISAR_SPLIT_REND_BITStream_write_int32( pBits, iA1Phase, PRED_QUANT_FILTER_PHASE_BITS ); + iBitsWritten = L_add( iBitsWritten, PRED_QUANT_FILTER_PHASE_BITS ); + } + } + } + } + + return iBitsWritten; +} +#endif diff --git a/lib_isar/isar_RMSEnvGrouping.c b/lib_isar/isar_RMSEnvGrouping.c new file mode 100644 index 0000000000000000000000000000000000000000..9b5de2574e70af2087769539a52211f7ceb26bdf --- /dev/null +++ b/lib_isar/isar_RMSEnvGrouping.c @@ -0,0 +1,964 @@ +/****************************************************************************************************** + + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository. All Rights Reserved. + + This software is protected by copyright law and by international treaties. + The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository retain full ownership rights in their respective contributions in + the software. This notice grants no license of any kind, including but not limited to patent + license, nor is any license granted by implication, estoppel or otherwise. + + Contributors are required to enter into the IVAS codec Public Collaboration agreement before making + contributions. + + This software is provided "AS IS", without any express or implied warranties. The software is in the + development stage. It is intended exclusively for experts who have experience with such software and + solely for the purpose of inspection. All implied warranties of non-infringement, merchantability + and fitness for a particular purpose are hereby disclaimed and excluded. + + Any dispute, controversy or claim arising under or in relation to providing this software shall be + submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in + accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and + the United Nations Convention on Contracts on the International Sales of Goods. + +*******************************************************************************************************/ + +/* Double check cost function calculation */ + +#include +#include "options.h" +#ifdef SPLIT_REND_WITH_HEAD_ROT +#include +#include "prot_fx.h" +#include "isar_lcld_prot.h" +#include "isar_lcld_rom_tables.h" +#include "wmc_auto.h" +#include "prot_fx.h" +#include "basop_util.h" +#include "enh64.h" +Word32 Inv_grp_length[17] = { + // Q31 + 0, + 2147483647, + 1073741823, + 715827882, + 536870911, + 429496729, + 357913941, + 306783378, + 268435455, + 238609294, + 214748364, + 195225786, + 178956970, + 165191049, + 153391689, + 143165576, + 134217727, + +}; + +/*-------------------------------------------------------------------* + * Local ROM tables + * + * + *-------------------------------------------------------------------*/ +static const Word32 c_afThreshQuiet48_fx[23] = { + // Q23 + -705191424, + -705191424, + -705191424, + -705191424, + -705191424, + -705191424, + -705191424, + -705191424, + -703021824, + -694920256, + -685375488, + -662531840, + -646432768, + -636262784, + -627448000, + -618652544, + -598245120, + -575579520, + -550540736, + -508787360, + -264583456, + -161516096, + -158042848, +}; +static const Word32 c_fiDefaultTheta48_fx[MAX_BANDS_48] = { + // Q31 + 939524096, + 939524096, + 805306368, + 671088640, + 671088640, + 536870912, + 536870912, + 536870912, + 536870912, + 536870912, + 536870912, + 536870912, + 536870912, + 536870912, + 536870912, + 536870912, + 536870912, + 536870912, + 536870912, + 536870912, + 536870912, + 536870912, + 536870912, +}; +typedef struct GMNODE +{ + int32_t iGroupStart; + int32_t iGroupLength; + Word32 *pfMergedEnergydB_fx; + int32_t *piQRMSEnvelope; + + int32_t iGroupRMSEnvelopeCost; + Word32 fGroupSNRPenalty_fx; + Word16 fGroupSNRPenalty_exp; + struct GMNODE *psNext; +} GMNode; + +struct RMS_ENVELOPE_GROUPING +{ + int32_t iNumBlocks; + int32_t iMaxGroups; + Word32 **ppfWeight_man; + Word16 **ppfWeight_exp; + Word32 **ppfBandEnergy_man; + Word16 **ppfBandEnergy_exp; + Word32 **ppfBandEnergydB_fx; + // Word32 **ppfWeight_fx; + GMNode *psGMNodes; +}; + + +/*-------------------------------------------------------------------* + * Function CreateRMSEnvelopeGrouping() + * + * + *-------------------------------------------------------------------*/ + +RMSEnvelopeGrouping *CreateRMSEnvelopeGrouping( + const Word32 iNumBlocks ) +{ + Word32 n; + + RMSEnvelopeGrouping *psRMSEnvelopeGrouping; + + psRMSEnvelopeGrouping = (RMSEnvelopeGrouping *) malloc( sizeof( RMSEnvelopeGrouping ) ); + psRMSEnvelopeGrouping->iNumBlocks = iNumBlocks; + + psRMSEnvelopeGrouping->iMaxGroups = iNumBlocks >> 1; + psRMSEnvelopeGrouping->ppfBandEnergy_man = (Word32 **) malloc( psRMSEnvelopeGrouping->iNumBlocks * sizeof( Word32 * ) ); + psRMSEnvelopeGrouping->ppfBandEnergy_exp = (Word16 **) malloc( psRMSEnvelopeGrouping->iNumBlocks * sizeof( Word16 * ) ); + psRMSEnvelopeGrouping->ppfBandEnergydB_fx = (Word32 **) malloc( psRMSEnvelopeGrouping->iNumBlocks * sizeof( Word32 * ) ); + psRMSEnvelopeGrouping->ppfWeight_man = (Word32 **) malloc( psRMSEnvelopeGrouping->iNumBlocks * sizeof( Word32 * ) ); + psRMSEnvelopeGrouping->ppfWeight_exp = (Word16 **) malloc( psRMSEnvelopeGrouping->iNumBlocks * sizeof( Word16 * ) ); + + for ( n = 0; n < psRMSEnvelopeGrouping->iNumBlocks; n++ ) + { + psRMSEnvelopeGrouping->ppfBandEnergy_man[n] = (Word32 *) malloc( MAX_BANDS * 2 * sizeof( Word32 ) ); /* 2 for stereo joint group calc */ + psRMSEnvelopeGrouping->ppfBandEnergy_exp[n] = (Word16 *) malloc( MAX_BANDS * 2 * sizeof( Word16 ) ); /* 2 for stereo joint group calc */ + psRMSEnvelopeGrouping->ppfBandEnergydB_fx[n] = (Word32 *) malloc( MAX_BANDS * 2 * sizeof( Word32 ) ); + psRMSEnvelopeGrouping->ppfWeight_man[n] = (Word32 *) malloc( MAX_BANDS * 2 * sizeof( Word32 ) ); + psRMSEnvelopeGrouping->ppfWeight_exp[n] = (Word16 *) malloc( MAX_BANDS * 2 * sizeof( Word16 ) ); + } + + psRMSEnvelopeGrouping->psGMNodes = (GMNode *) malloc( psRMSEnvelopeGrouping->iNumBlocks * sizeof( GMNode ) ); + for ( n = 0; n < psRMSEnvelopeGrouping->iNumBlocks; n++ ) + { + psRMSEnvelopeGrouping->psGMNodes[n].pfMergedEnergydB_fx = (Word32 *) malloc( MAX_BANDS * 2 * sizeof( float ) ); + psRMSEnvelopeGrouping->psGMNodes[n].piQRMSEnvelope = (Word32 *) malloc( MAX_BANDS * 2 * sizeof( int32_t ) ); + psRMSEnvelopeGrouping->psGMNodes[n].iGroupRMSEnvelopeCost = -1; + psRMSEnvelopeGrouping->psGMNodes[n].fGroupSNRPenalty_fx = L_negate( ONE_IN_Q30 ); + psRMSEnvelopeGrouping->psGMNodes[n].fGroupSNRPenalty_exp = 1; + } + + return psRMSEnvelopeGrouping; +} + + +/*-------------------------------------------------------------------* + * Function DeleteRMSEnvelopeGrouping() + * + * + *-------------------------------------------------------------------*/ + +void DeleteRMSEnvelopeGrouping( + RMSEnvelopeGrouping *psRMSEnvelopeGrouping ) +{ + int32_t n; + + for ( n = 0; n < psRMSEnvelopeGrouping->iNumBlocks; n++ ) + { + free( psRMSEnvelopeGrouping->ppfBandEnergy_man[n] ); + free( psRMSEnvelopeGrouping->ppfBandEnergy_exp[n] ); + free( psRMSEnvelopeGrouping->ppfBandEnergydB_fx[n] ); + free( psRMSEnvelopeGrouping->ppfWeight_man[n] ); + free( psRMSEnvelopeGrouping->ppfWeight_exp[n] ); + } + free( psRMSEnvelopeGrouping->ppfBandEnergy_man ); + free( psRMSEnvelopeGrouping->ppfBandEnergy_exp ); + free( psRMSEnvelopeGrouping->ppfBandEnergydB_fx ); + free( psRMSEnvelopeGrouping->ppfWeight_man ); + free( psRMSEnvelopeGrouping->ppfWeight_exp ); + + + for ( n = 0; n < psRMSEnvelopeGrouping->iNumBlocks; n++ ) + { + free( psRMSEnvelopeGrouping->psGMNodes[n].pfMergedEnergydB_fx ); + free( psRMSEnvelopeGrouping->psGMNodes[n].piQRMSEnvelope ); + } + free( psRMSEnvelopeGrouping->psGMNodes ); + + free( psRMSEnvelopeGrouping ); + + return; +} + + +/*-------------------------------------------------------------------* + * Function ComputeBandEnergy() + * + * + *-------------------------------------------------------------------*/ +static void ComputeBandEnergy( + const Word32 iChannels, + const Word32 iNumBlocks, + const Word32 iNumBands, + const Word32 *piBandwidths, + Word32 ***pppfReal_fx, + Word32 ***pppfImag_fx, + Word32 **ppfBandEnergy_man, + Word16 **ppfBandEnergy_exp, + Word32 **ppfBandEnergydB_fx, + Word32 **ppfWeight_man, + Word16 **ppfWeight_exp, + Word16 q_final ) +{ + + Word32 n; + Word32 constant = 1616142483; // Q29 of(1/log2(10))*10 + Word32 const_comp3, const_comp1; + Word16 exp3 = 0, exp1 = 0, Flag1, Flag2, Flag3; + Word16 div_exp; + /*For 0.33f*/ + const_comp3 = 1417339264; + move32(); + exp3 = -1; + move16(); + // f2me( 0.33, &const_comp3, &exp3 );// + // f2me( 1.0, &const_comp1, &exp1 );// + /*For 1.0f*/ + Word32 mul_32; + Word16 mul_exp; + const_comp1 = 1073741824; + move32(); + exp1 = 1; + move16(); + FOR( n = 0; n < iChannels; n++ ) + { + Word32 k; + Word32 iChanOffset; + + iChanOffset = L_mult0( extract_l( n ), extract_l( iNumBands ) ); + FOR( k = 0; k < iNumBlocks; k++ ) + { + Word32 b; + Word32 iFBOffset; + Word32 fMaxWeight_fx = 0; + move32(); + Word16 fMaxWeight_exp = 0; + move16(); + iFBOffset = 0; + move32(); + FOR( b = 0; b < iNumBands; b++ ) + { + Word32 m; + Word16 fEnergy_exp; + Word32 fEnergy_fx, fWeight_temp; + Word16 shift_value; + Word32 fEnergy_log_fx, fEnergy_log_fx1; + fEnergy_exp = 0; + move16(); + /*For 1e-12f in Q63*/ + Word32 fWeight_fx; + Word64 Wmult_value; + Word16 exp_pow = 0; + move16(); + Word16 guard_bits = find_guarded_bits_fx( piBandwidths[b] + 1 ); + // fEnergy_f64 = W_shr( fEnergy_f64, ( 63 - ( 2 * ( q_final - guard_bits ) + 1 ) ) ); + fEnergy_fx = 1180591616; + fEnergy_exp = -39; + FOR( m = 0; m < piBandwidths[b]; m++ ) + { + Wmult_value = W_add( W_mult_32_32( L_shr( pppfReal_fx[n][k][iFBOffset], guard_bits ), L_shr( pppfReal_fx[n][k][iFBOffset], guard_bits ) ), W_mult_32_32( L_shr( pppfImag_fx[n][k][iFBOffset], guard_bits ), L_shr( pppfImag_fx[n][k][iFBOffset], guard_bits ) ) ); + shift_value = W_norm( Wmult_value ); + mul_32 = W_extract_h( W_shl( Wmult_value, shift_value ) ); + mul_exp = 31 - ( 2 * ( q_final - guard_bits ) + 1 + shift_value - 32 ); + fEnergy_fx = BASOP_Util_Add_Mant32Exp( fEnergy_fx, fEnergy_exp, mul_32, mul_exp, &fEnergy_exp ); // Some large number to prevent clipping + iFBOffset++; + } + IF( EQ_32( fEnergy_fx, 0 ) ) + { + // f2me( 1e-12f, &fEnergy_fx, &fEnergy_exp ); // + fEnergy_fx = 1180591616; + fEnergy_exp = -39; + fEnergy_fx = Mpy_32_32( fEnergy_fx, Inv_grp_length[piBandwidths[b]] ); // Correction removed normalization by 2 + ppfBandEnergy_man[k][iChanOffset + b] = fEnergy_fx; + move32(); + ppfBandEnergy_exp[k][iChanOffset + b] = fEnergy_exp; + move16(); + fEnergy_fx = Mpy_32_32( fEnergy_fx, Inv_grp_length[piBandwidths[b]] ); // Correction removed normalization by 2 + ppfBandEnergy_man[k][iChanOffset + b] = fEnergy_fx; + move32(); + ppfBandEnergy_exp[k][iChanOffset + b] = fEnergy_exp; + move16(); + fEnergy_log_fx1 = -1006632960; // Q23 + fWeight_fx = 403727488; // Q31 + exp_pow = 0; + } + ELSE + { + fEnergy_fx = Mpy_32_32( fEnergy_fx, Inv_grp_length[piBandwidths[b]] ); // Correction removed normalization by 2 + ppfBandEnergy_man[k][iChanOffset + b] = fEnergy_fx; + move32(); + ppfBandEnergy_exp[k][iChanOffset + b] = fEnergy_exp; + move16(); + fEnergy_fx = BASOP_Util_Log2( fEnergy_fx ); + move32(); + fEnergy_log_fx = L_add( fEnergy_fx, L_shl( L_deposit_l( fEnergy_exp ), WORD32_BITS - 1 - LD_DATA_SCALE ) ); /*Q25*/ // log2f( fEnergy ) + fEnergy_log_fx1 = Mpy_32_32( fEnergy_log_fx, constant ); + fEnergy_log_fx = L_sub( fEnergy_log_fx1, c_afThreshQuiet48_fx[b] ); // Q23 of ( 10.0f * log10f( fEnergy ) - c_afThreshQuiet48[b] ) ) + fWeight_fx = Mpy_32_32( 48509336, fEnergy_log_fx ); // 0.0068f*3.3219 in Q31, result in Q23 + fWeight_temp = BASOP_util_Pow2( fWeight_fx, 8, &exp_pow ); + fWeight_fx = Mpy_32_32( 708669604, fWeight_temp ); // 708669604 = Q31 0f 0.33 + } + Flag1 = BASOP_Util_Cmp_Mant32Exp( fWeight_fx, exp_pow, const_comp3, exp3 ); + IF( NE_16( Flag1, 1 ) ) + { + fWeight_fx = const_comp3; + move32(); + exp_pow = exp3; + move16(); + } + Flag2 = BASOP_Util_Cmp_Mant32Exp( const_comp1, exp1, fWeight_fx, exp_pow ); + IF( NE_16( Flag2, 1 ) ) + { + fWeight_fx = const_comp1; + move32(); + exp_pow = exp1; + move16(); + } + Flag3 = BASOP_Util_Cmp_Mant32Exp( fMaxWeight_fx, fMaxWeight_exp, fWeight_fx, exp_pow ); + IF( NE_16( Flag3, 1 ) ) + { + fMaxWeight_fx = fWeight_fx; + move32(); + fMaxWeight_exp = exp_pow; + move16(); + } +#ifdef APPLY_TEMPORAL_SMOOTHING + if ( k > 0 ) + { + float fSmoothEnergy; + fSmoothEnergy = 0.7f * ppfBandEnergy[k - 1][iChanOffset + b] + 0.3f * fEnergy; + + fEnergy = ( fEnergy > fSmoothEnergy ) ? fEnergy : fSmoothEnergy; + } +#endif + ppfWeight_man[k][iChanOffset + b] = fWeight_fx; + ppfWeight_exp[k][iChanOffset + b] = exp_pow; + ppfBandEnergydB_fx[k][iChanOffset + b] = fEnergy_log_fx1; // Q23 + } + FOR( b = 0; b < iNumBands; b++ ) + { + ppfWeight_man[k][iChanOffset + b] = L_deposit_h( BASOP_Util_Divide3232_Scale( ppfWeight_man[k][iChanOffset + b], fMaxWeight_fx, &div_exp ) ); + ppfWeight_exp[k][iChanOffset + b] = div_exp + ppfWeight_exp[k][iChanOffset + b] - fMaxWeight_exp; + } + } + } + /* fclose( fp ); + fclose( fp1 );*/ + return; +} +/*-------------------------------------------------------------------* + * Function ComputeMergeRMS() + * + * + *-------------------------------------------------------------------*/ +static void ComputeMergeRMS( + const Word32 iNumBands, + const Word32 iStartBlock, + const Word32 iGroupLength, + Word32 *pfMergedEnergydB, + Word32 *piQRMSEnvelope, + Word32 **ppfBandEnergy_man, + Word16 **ppfBandEnergy_exp ) +{ + Word32 b; + /* FILE *fp = fopen( "float_fGroupEnergy.txt","ab+" ); + FILE *fp1 = fopen( "fixed_fGroupEnergy.txt","ab+" );*/ + Word32 constant = 1616142483; // Q29 of(1/log2(10))*10 // Note epsolon was added when computing BandEnergy; + move32(); + Word32 fGroupEnergy32_fx; + + FOR( b = 0; b < iNumBands; b++ ) + { + Word32 n; + Word32 fGroupEnergy_fx = 0; + move32(); + Word16 fGroupEnergy_exp = 0; + move16(); + Word32 fRMSEnvelope_fx; + Word32 iQRMSEnvelope_fx; + FOR( n = iStartBlock; n < ( iStartBlock + iGroupLength ); n++ ) + { + fGroupEnergy_fx = BASOP_Util_Add_Mant32Exp( ppfBandEnergy_man[n][b], ppfBandEnergy_exp[n][b], fGroupEnergy_fx, fGroupEnergy_exp, &fGroupEnergy_exp ); + } + fGroupEnergy_fx = Mpy_32_32( fGroupEnergy_fx, Inv_grp_length[iGroupLength] ); // Division by iGroupLength + move32(); + IF( NE_32( fGroupEnergy_fx, 0 ) ) + { + fRMSEnvelope_fx = BASOP_Util_Log2( fGroupEnergy_fx ); + move32(); + fRMSEnvelope_fx = L_add( fRMSEnvelope_fx, L_shl( L_deposit_l( fGroupEnergy_exp ), WORD32_BITS - 1 - LD_DATA_SCALE ) ); /*Q25*/ + } + ELSE + { + fRMSEnvelope_fx = 0; + fGroupEnergy_exp = 0; + } + iQRMSEnvelope_fx = ( fRMSEnvelope_fx > 0 ) ? L_add( fRMSEnvelope_fx, ONE_IN_Q24 ) : L_negate( L_add( L_negate( fRMSEnvelope_fx ), ONE_IN_Q24 ) ); + iQRMSEnvelope_fx = L_shr( iQRMSEnvelope_fx, 25 ); + + fGroupEnergy32_fx = fRMSEnvelope_fx; /*Q25*/ // BASOP_Util_Log2( fGroupEnergy_fx ); + fGroupEnergy32_fx = Mpy_32_32( fGroupEnergy32_fx, constant ); // Q23 + pfMergedEnergydB[b] = fGroupEnergy32_fx; // Q23 + piQRMSEnvelope[b] = iQRMSEnvelope_fx; // Q25 + } + return; +} +/*-------------------------------------------------------------------* + * Function ComputeRMSEnvelopeBits() + * + * + *-------------------------------------------------------------------*/ +static Word32 ComputeRMSEnvelopeBits( + const Word32 iChannels, + const Word32 iNumBands, + const Word32 *piQRMSEnevelope ) +{ + Word32 n; + Word32 iRMSEnvelopeBits = 0; + move32(); + Word32 iChanOffset = 0; + move32(); + + FOR( n = 0; n < iChannels; n++ ) + { + Word32 b; + Word32 iLastRMSVal; + + iRMSEnvelopeBits = L_add( iRMSEnvelopeBits, ENV0_BITS ); + iLastRMSVal = piQRMSEnevelope[iChanOffset]; + move32(); + FOR( b = 1; b < iNumBands; b++ ) + { + Word32 iDelta; + + iDelta = L_sub( piQRMSEnevelope[iChanOffset + b], iLastRMSVal ); + iDelta = ( iDelta > ENV_DELTA_MIN ) ? iDelta : ENV_DELTA_MIN; + iDelta = ( iDelta < ENV_DELTA_MAX ) ? iDelta : ENV_DELTA_MAX; + iDelta = L_sub( iDelta, ENV_DELTA_MIN ); + iRMSEnvelopeBits = L_add( iRMSEnvelopeBits, c_aaiRMSEnvHuffEnc[iDelta][0] ); + + iLastRMSVal = piQRMSEnevelope[iChanOffset + b]; + move32(); + } + + iChanOffset = L_add( iChanOffset, iNumBands ); + } + + return iRMSEnvelopeBits; +} +/*-------------------------------------------------------------------* + * Function ComputeSNRPenalty() + * + * + *-------------------------------------------------------------------*/ +static Word32 ComputeSNRPenalty( + const Word32 iChannels, + const Word32 iNumBands, + const Word32 *piBandwidths, + const Word32 iStartBlock, + const Word32 iGroupLength, + Word32 **ppfBandEnergy_dB_fx, + const Word32 *piRMSEnvelope, + Word16 *fSNRPenalty_exp ) +{ + Word32 n; + Word32 iChanOffset; + Word32 temp; + Word32 fSNRPenalty_fx = 0; + move32(); + Word32 fSNRPenaltyconst_fx = 0; + move32(); + Word32 mul_temp; + Word16 fSNRPenaltycnst_exp = 0, exp = 0; + /*FILE *fp = fopen( "float_SNRpenalty.txt", "ab+" ); + FILE *fp1 = fopen( "fixed_SNRpenalty.txt", "ab+" );*/ + // f2me( 1e10f, &fSNRPenaltyconst_fx, &fSNRPenaltycnst_exp );// + /*For 1e10f*/ + fSNRPenaltyconst_fx = 1250000000; + fSNRPenaltycnst_exp = 34; + iChanOffset = 0; + move32(); + FOR( n = 0; n < iChannels; n++ ) + { + Word32 b; + FOR( b = 0; b < iNumBands; b++ ) + { + Word32 k; + Word32 fRMSVal_fx; + Word32 RMS_value_fx; + // RMS_value = piRMSEnvelope[iChanOffset + b]; + RMS_value_fx = L_shl( piRMSEnvelope[iChanOffset + b], 25 ); + move32(); + // fRMSVal = 3.0103f * (float) RMS_value; + fRMSVal_fx = Mpy_32_32( 1616142506, RMS_value_fx ); // Q23 + move32(); + FOR( k = iStartBlock; k < ( iStartBlock + iGroupLength ); k++ ) + { + Word32 fDeltadB_fx; + fDeltadB_fx = L_sub( fRMSVal_fx, ppfBandEnergy_dB_fx[k][iChanOffset + b] ); + IF( LT_32( fDeltadB_fx, -75756680 ) ) + { + fSNRPenalty_fx = BASOP_Util_Add_Mant32Exp( fSNRPenalty_fx, *fSNRPenalty_exp, fSNRPenaltyconst_fx, fSNRPenaltycnst_exp, fSNRPenalty_exp ); // Some large number to prevent clipping + } + ELSE + { + mul_temp = L_abs( L_sub( Mpy_32_32( c_fiDefaultTheta48_fx[b], fDeltadB_fx ), fDeltadB_fx ) ); + temp = Mpy_32_32( mul_temp, Mpy_32_32( 715827883, L_shl( piBandwidths[b], 27 ) ) ); // Q27+23 -31=19 + exp = Q12; // Q31 - Q19 + fSNRPenalty_fx = BASOP_Util_Add_Mant32Exp( fSNRPenalty_fx, *fSNRPenalty_exp, temp, exp, fSNRPenalty_exp ); + } + } + } + + iChanOffset = L_add( iChanOffset, iNumBands ); + } + // fprintf( fp,"%f\n", fSNRPenalty ); + // fprintf( fp1,"%f\n", fSNRPenalty ); + /* fclose( fp ); + fclose( fp1 );*/ + return fSNRPenalty_fx; +} +/*-------------------------------------------------------------------* + * Function TryMerge2() + * + * + *-------------------------------------------------------------------*/ +static Word32 TryMerge2( + const Word32 iChannels, + const Word32 iNumBands, + const Word32 *piBandwidths, + Word32 **ppfBandEnergy_man, + Word16 **ppfBandEnergy_exp, + Word32 **ppfBandEnergydB_fx, + GMNode *psGMNode1, + GMNode *psGMNode2, + Word16 *fMergedCost_exp ) +{ + Word32 iRMSEnvBits1; + Word32 iRMSEnvBits2; + Word32 iRMSEnvBitsMerged; + Word32 temp = 0; + move32(); + Word16 temp_exp = 0; + move16(); + Word32 fMergedCost_fx = 0; + move32(); + Word32 RMSEnvBits_fx; + Word32 fSNRPenalty1_fx; + Word32 fSNRPenalty2_fx; + Word32 fSNRPenaltyMerged_fx; + Word16 fSNRPenalty1_exp = 0; + move16(); + Word16 fSNRPenalty2_exp = 0; + move16(); + Word16 fSNRPenaltyMerged_exp = 0; + move16(); + Word32 one_in_mant = L_negate( ONE_IN_Q30 ); + Word16 one_in_exp = 1; + move16(); + *fMergedCost_exp = 0; + move16(); + Word16 flag = 0; + move16(); + IF( EQ_32( psGMNode1->fGroupSNRPenalty_fx, one_in_mant ) && EQ_16( psGMNode1->fGroupSNRPenalty_exp, one_in_exp ) ) + { + flag = 1; + move16(); + } + /* First compute current RMS Envelope for each group */ + IF( EQ_32( psGMNode1->iGroupRMSEnvelopeCost, -1 ) || flag ) + { + ComputeMergeRMS( iNumBands * iChannels, psGMNode1->iGroupStart, psGMNode1->iGroupLength, psGMNode1->pfMergedEnergydB_fx, psGMNode1->piQRMSEnvelope, ppfBandEnergy_man, ppfBandEnergy_exp ); + iRMSEnvBits1 = ComputeRMSEnvelopeBits( iChannels, iNumBands, psGMNode1->piQRMSEnvelope ); + fSNRPenalty1_fx = ComputeSNRPenalty( iChannels, iNumBands, piBandwidths, psGMNode1->iGroupStart, psGMNode1->iGroupLength, ppfBandEnergydB_fx, psGMNode1->piQRMSEnvelope, &fSNRPenalty1_exp ); + psGMNode1->iGroupRMSEnvelopeCost = iRMSEnvBits1; + move32(); + psGMNode1->fGroupSNRPenalty_fx = fSNRPenalty1_fx; + move32(); + psGMNode1->fGroupSNRPenalty_exp = fSNRPenalty1_exp; + move16(); + } + ELSE + { + iRMSEnvBits1 = psGMNode1->iGroupRMSEnvelopeCost; + move32(); + fSNRPenalty1_fx = psGMNode1->fGroupSNRPenalty_fx; + move32(); + fSNRPenalty1_exp = psGMNode1->fGroupSNRPenalty_exp; + move16(); + } + IF( EQ_32( psGMNode2->fGroupSNRPenalty_fx, one_in_mant ) && EQ_16( psGMNode2->fGroupSNRPenalty_exp, one_in_exp ) ) + { + flag = 1; + move16(); + } + IF( EQ_32( psGMNode2->iGroupRMSEnvelopeCost, -1 ) || flag ) + { + + ComputeMergeRMS( iNumBands * iChannels, psGMNode2->iGroupStart, psGMNode2->iGroupLength, psGMNode2->pfMergedEnergydB_fx, psGMNode2->piQRMSEnvelope, ppfBandEnergy_man, ppfBandEnergy_exp ); + iRMSEnvBits2 = ComputeRMSEnvelopeBits( iChannels, iNumBands, psGMNode2->piQRMSEnvelope ); + fSNRPenalty2_fx = ComputeSNRPenalty( iChannels, iNumBands, piBandwidths, psGMNode2->iGroupStart, psGMNode2->iGroupLength, ppfBandEnergydB_fx, psGMNode2->piQRMSEnvelope, &fSNRPenalty2_exp ); + psGMNode2->iGroupRMSEnvelopeCost = iRMSEnvBits2; + move32(); + psGMNode2->fGroupSNRPenalty_fx = fSNRPenalty2_fx; + move32(); + psGMNode2->fGroupSNRPenalty_exp = fSNRPenalty2_exp; + move16(); + } + ELSE + { + iRMSEnvBits2 = psGMNode2->iGroupRMSEnvelopeCost; + move32(); + fSNRPenalty2_fx = psGMNode2->fGroupSNRPenalty_fx; + move32(); + fSNRPenalty2_exp = psGMNode2->fGroupSNRPenalty_exp; + move16(); + } + ComputeMergeRMS( iNumBands * iChannels, psGMNode1->iGroupStart, psGMNode1->iGroupLength + psGMNode2->iGroupLength, psGMNode1->pfMergedEnergydB_fx, psGMNode1->piQRMSEnvelope, ppfBandEnergy_man, ppfBandEnergy_exp ); + + /* Compute the RMS Envelope cost for merged group */ + iRMSEnvBitsMerged = ComputeRMSEnvelopeBits( iChannels, iNumBands, psGMNode1->piQRMSEnvelope ); + // fSNRPenalty_exp = 0; + /* Compute an approximation of the bit cost based on SNR increase/decrease due to merging */ + fSNRPenaltyMerged_fx = ComputeSNRPenalty( iChannels, iNumBands, piBandwidths, psGMNode1->iGroupStart, psGMNode1->iGroupLength + psGMNode2->iGroupLength, ppfBandEnergydB_fx, psGMNode1->piQRMSEnvelope, &fSNRPenaltyMerged_exp ); + RMSEnvBits_fx = L_sub( L_sub( iRMSEnvBitsMerged, iRMSEnvBits1 ), iRMSEnvBits2 ); + RMSEnvBits_fx = L_shl( RMSEnvBits_fx, 10 ); // Converting to Q10 + temp = BASOP_Util_Add_Mant32Exp( fSNRPenaltyMerged_fx, fSNRPenaltyMerged_exp, L_negate( fSNRPenalty1_fx ), fSNRPenalty1_exp, &temp_exp ); + fMergedCost_fx = BASOP_Util_Add_Mant32Exp( temp, temp_exp, L_negate( fSNRPenalty2_fx ), fSNRPenalty2_exp, fMergedCost_exp ); + fMergedCost_fx = BASOP_Util_Add_Mant32Exp( fMergedCost_fx, *fMergedCost_exp, RMSEnvBits_fx, 21, fMergedCost_exp ); + // fMergedCost = fSNRPenaltyMerged - fSNRPenalty1 - fSNRPenalty2 + (float) iRMSEnvBitsMerged - (float) iRMSEnvBits1 - (float) iRMSEnvBits2; + return fMergedCost_fx; +} + +/*-------------------------------------------------------------------* + * Function ComputeGreedyGroups3() + * + * + *-------------------------------------------------------------------*/ +static void ComputeGreedyGroups3( + RMSEnvelopeGrouping *psRMSEnvelopeGrouping, + const int32_t iChannels, + const int32_t iNumBands, + const int32_t *piBandwidths, + const int32_t iMaxGroups ) +{ + + Word32 iDone = 0; + Word32 iNumGroups = psRMSEnvelopeGrouping->iMaxGroups; + WHILE( EQ_32( iDone, 0 ) ) + { + GMNode *psGMNode; + GMNode *psBestGMNode; + /* Instead of 1e20f*/ + Word32 fBestMergeCost_fx = 1455191552; // mantissa of 1e20f + move32(); + Word16 fBestMergeCost_exp = 67; // exp of 1e20f + move16(); + Word16 Flag = 0; + move16(); + psGMNode = &psRMSEnvelopeGrouping->psGMNodes[0]; + psBestGMNode = NULL; + WHILE( psGMNode->psNext != NULL ) + { + Word32 fMergeCost_fx = 0; + move32(); + Word16 fMergeCost_exp = 0; + move16(); + fMergeCost_fx = TryMerge2( iChannels, iNumBands, piBandwidths, psRMSEnvelopeGrouping->ppfBandEnergy_man, psRMSEnvelopeGrouping->ppfBandEnergy_exp, psRMSEnvelopeGrouping->ppfBandEnergydB_fx, psGMNode, psGMNode->psNext, &fMergeCost_exp ); + IF( LT_32( fMergeCost_fx, 0 ) && ( GT_32( fBestMergeCost_fx, 0 ) ) ) + { + + Flag = 1; + move16(); + } + ELSE IF( ( GT_32( fMergeCost_fx, 0 ) && ( LT_32( fBestMergeCost_fx, 0 ) ) ) ) + { + Flag = -1; + move16(); + } + ELSE + { + Flag = BASOP_Util_Cmp_Mant32Exp( fBestMergeCost_fx, fBestMergeCost_exp, fMergeCost_fx, fMergeCost_exp ); + } + IF( EQ_32( Flag, 1 ) ) + { + fBestMergeCost_fx = fMergeCost_fx; + move32(); + fBestMergeCost_exp = fMergeCost_exp; + move16(); + psBestGMNode = psGMNode; + } + + psGMNode = psGMNode->psNext; + } + + IF( ( GT_32( fBestMergeCost_fx, 0 ) && ( LE_32( iNumGroups, iMaxGroups ) ) ) ) + { + iDone++; + } + ELSE IF( ( psBestGMNode != NULL ) && ( psBestGMNode->psNext != NULL ) ) + { + psBestGMNode->iGroupLength = L_add( psBestGMNode->psNext->iGroupLength, psBestGMNode->iGroupLength ); + psBestGMNode->fGroupSNRPenalty_fx = L_negate( ONE_IN_Q30 ); + psBestGMNode->fGroupSNRPenalty_exp = 1; + move16(); + psBestGMNode->psNext = psBestGMNode->psNext->psNext; + iNumGroups--; + } + ELSE + { + iDone++; // This only catches a problem + } + } + return; +} +/*-------------------------------------------------------------------* + * Function ComputeRMSEnvelope() + * + * + *-------------------------------------------------------------------*/ +static void ComputeRMSEnvelope( + const Word32 iChannels, + const Word32 iNumBands, + const Word32 iNumGroups, + const Word32 *piGroupLengths, + Word32 **ppfBandEnergy_man, + Word16 **ppfBandEnergy_exp, + Word32 ***pppiRMSEnvelope ) +{ + Word32 n; + Word32 fGroupEnergy_fx; + Word16 fGroupEnergy_exp; + Word32 temp; + // FILE *fp = fopen( "RmsEnvelope_fixed", "ab+" ); + // FILE *fp1 = fopen( "RmsEnvelope_float", "ab+" ); + FOR( n = 0; n < iChannels; n++ ) + { + Word32 b; + Word32 iChanOffset; + + iChanOffset = L_mult0( extract_l( n ), extract_l( iNumBands ) ); + + FOR( b = 0; b < iNumBands; b++ ) + { + Word32 k; + Word32 iBlockOffset; + iBlockOffset = 0; + FOR( k = 0; k < iNumGroups; k++ ) + { + Word32 m; + fGroupEnergy_exp = 0; + move16(); + fGroupEnergy_fx = 0; + move32(); + FOR( m = 0; m < piGroupLengths[k]; m++ ) + { + fGroupEnergy_fx = BASOP_Util_Add_Mant32Exp( ppfBandEnergy_man[iBlockOffset][b + iChanOffset], ppfBandEnergy_exp[iBlockOffset][b + iChanOffset], fGroupEnergy_fx, fGroupEnergy_exp, &fGroupEnergy_exp ); + iBlockOffset++; + } + fGroupEnergy_fx = Mpy_32_32( fGroupEnergy_fx, Inv_grp_length[piGroupLengths[k]] ); // Division by iGroupLength + fGroupEnergy_fx = BASOP_Util_Log2( fGroupEnergy_fx ); + move32(); + fGroupEnergy_fx = L_add( fGroupEnergy_fx, L_shl( L_deposit_l( fGroupEnergy_exp ), WORD32_BITS - 1 - LD_DATA_SCALE ) ); /*Q25*/ + temp = ( fGroupEnergy_fx > 0 ) ? L_add( fGroupEnergy_fx, ONE_IN_Q24 ) : L_negate( L_add( L_negate( fGroupEnergy_fx ), ONE_IN_Q24 ) ); // Q25 + temp = L_shr( temp, 25 ); + temp = ( temp > ENV_MIN ) ? temp : ENV_MIN; + temp = ( temp < ENV_MAX ) ? temp : ENV_MAX; + pppiRMSEnvelope[n][k][b] = temp; + // fprintf( fp,"%d\n", pppiRMSEnvelope[n][k][b] ); + } + } + } + // fclose( fp ); + /* fclose( fp1 );*/ + return; +} + +/*-------------------------------------------------------------------* + * Function LimitRMSEnvelope() + * + * + *-------------------------------------------------------------------*/ +static void LimitRMSEnvelope( + const Word32 iBandCount, + const Word32 iRMSDeltaMax, + const Word32 iRMSDeltaMin, + Word32 *piRMSEnvelope ) +{ + Word32 iBand; + Word32 iLastSCF; + + /* Increase low envelope values to ensure that the scale factors traces the large values correctly (checking for max deltas) */ + iLastSCF = piRMSEnvelope[iBandCount - 1]; + move32(); + for ( iBand = iBandCount - 2; iBand > -1; iBand-- ) + { + Word32 iDelta; + + iDelta = L_sub( iLastSCF, piRMSEnvelope[iBand] ); + + IF( GT_32( iDelta, iRMSDeltaMax ) ) + { +#ifdef DEBUG_VERBOSE + printf( "WARNING RMS envelope delta limited\n" ); +#endif + piRMSEnvelope[iBand] = L_add( L_sub( iDelta, iRMSDeltaMax ), piRMSEnvelope[iBand] ); + } + + iLastSCF = piRMSEnvelope[iBand]; + move32(); + } + + /* Increase low envelope values to ensure that the envelope traces the large values correctly (checking for min deltas)*/ + iLastSCF = piRMSEnvelope[0]; + FOR( iBand = 1; iBand < iBandCount; iBand++ ) + { + Word32 iDelta; + + iDelta = L_sub( piRMSEnvelope[iBand], iLastSCF ); + + IF( LT_32( iDelta, iRMSDeltaMin ) ) + { +#ifdef DEBUG_VERBOSE + printf( "WARNING RMS envelope delta limited\n" ); +#endif + piRMSEnvelope[iBand] = L_add( piRMSEnvelope[iBand], L_sub( iRMSDeltaMin, iDelta ) ); + } + + iLastSCF = piRMSEnvelope[iBand]; + move32(); + } + + return; +} + +/*-------------------------------------------------------------------* + * Function ComputeEnvelopeGrouping() + * + * + *-------------------------------------------------------------------*/ +void ComputeEnvelopeGrouping( + RMSEnvelopeGrouping *psRMSEnvelopeGrouping, + const Word32 iChannels, + const Word32 iNumBands, + const Word32 *piBandwidths, + Word32 ***pppfReal_fx, + Word32 ***pppfImag_fx, + Word32 *piNumGroups, + Word32 *piGroupLengths, + Word32 ***pppiRMSEnvelope, + Word16 q_final ) +{ + Word32 n; + GMNode *psGMNode; + + /* Compute Band Energies */ + ComputeBandEnergy( iChannels, psRMSEnvelopeGrouping->iNumBlocks, iNumBands, piBandwidths, pppfReal_fx, pppfImag_fx, psRMSEnvelopeGrouping->ppfBandEnergy_man, psRMSEnvelopeGrouping->ppfBandEnergy_exp, psRMSEnvelopeGrouping->ppfBandEnergydB_fx, psRMSEnvelopeGrouping->ppfWeight_man, psRMSEnvelopeGrouping->ppfWeight_exp, q_final ); + /* Init GMNodes */ + psRMSEnvelopeGrouping->psGMNodes[0].iGroupStart = 0; + move32(); + psRMSEnvelopeGrouping->psGMNodes[0].iGroupLength = 2; + move32(); + psRMSEnvelopeGrouping->psGMNodes[0].psNext = NULL; + psRMSEnvelopeGrouping->psGMNodes[0].iGroupRMSEnvelopeCost = -1; + move32(); + psRMSEnvelopeGrouping->psGMNodes[0].fGroupSNRPenalty_fx = L_negate( ONE_IN_Q30 ); + psRMSEnvelopeGrouping->psGMNodes[0].fGroupSNRPenalty_exp = 1; + move16(); + FOR( n = 1; n < psRMSEnvelopeGrouping->iMaxGroups; n++ ) + { + psRMSEnvelopeGrouping->psGMNodes[n - 1].psNext = &psRMSEnvelopeGrouping->psGMNodes[n]; + psRMSEnvelopeGrouping->psGMNodes[n].iGroupStart = L_shl( n, 1 ); + move32(); + psRMSEnvelopeGrouping->psGMNodes[n].iGroupLength = 2; + move32(); + psRMSEnvelopeGrouping->psGMNodes[n].iGroupRMSEnvelopeCost = -1; + move32(); + psRMSEnvelopeGrouping->psGMNodes[n].fGroupSNRPenalty_fx = L_negate( ONE_IN_Q30 ); + psRMSEnvelopeGrouping->psGMNodes[n].fGroupSNRPenalty_exp = 1; + move16(); + psRMSEnvelopeGrouping->psGMNodes[n].psNext = NULL; + } + /* 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, psRMSEnvelopeGrouping->iNumBlocks ); + /* Calc Groups from Merge Results */ + *piNumGroups = 0; + move32(); + psGMNode = &psRMSEnvelopeGrouping->psGMNodes[0]; + WHILE( psGMNode != NULL ) + { + piGroupLengths[*piNumGroups] = psGMNode->iGroupLength; + move32(); + *piNumGroups = L_add( *piNumGroups, 1 ); + psGMNode = psGMNode->psNext; + } + /* Compute RMS Envelope given group lengths */ + ComputeRMSEnvelope( iChannels, iNumBands, *piNumGroups, piGroupLengths, psRMSEnvelopeGrouping->ppfBandEnergy_man, psRMSEnvelopeGrouping->ppfBandEnergy_exp, pppiRMSEnvelope ); + + /* Envelope Tenting */ + FOR( n = 0; n < iChannels; n++ ) + { + Word32 k; + FOR( k = 0; k < *piNumGroups; k++ ) + { + LimitRMSEnvelope( iNumBands, ENV_DELTA_MAX, ENV_DELTA_MIN, pppiRMSEnvelope[n][k] ); + } + } + + return; +} +#endif diff --git a/lib_isar/isar_cnst.h b/lib_isar/isar_cnst.h new file mode 100644 index 0000000000000000000000000000000000000000..046beabdcd60ce2abf0196f51574d78e53daf74b --- /dev/null +++ b/lib_isar/isar_cnst.h @@ -0,0 +1,159 @@ +/****************************************************************************************************** + + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository. All Rights Reserved. + + This software is protected by copyright law and by international treaties. + The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository retain full ownership rights in their respective contributions in + the software. This notice grants no license of any kind, including but not limited to patent + license, nor is any license granted by implication, estoppel or otherwise. + + Contributors are required to enter into the IVAS codec Public Collaboration agreement before making + contributions. + + This software is provided "AS IS", without any express or implied warranties. The software is in the + development stage. It is intended exclusively for experts who have experience with such software and + solely for the purpose of inspection. All implied warranties of non-infringement, merchantability + and fitness for a particular purpose are hereby disclaimed and excluded. + + Any dispute, controversy or claim arising under or in relation to providing this software shall be + submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in + accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and + the United Nations Convention on Contracts on the International Sales of Goods. + +*******************************************************************************************************/ + +#ifndef ISAR_CNST_H +#define ISAR_CNST_H + +#include +#include "options.h" + +/* clang-format off */ + +#ifdef SPLIT_REND_WITH_HEAD_ROT + +/*----------------------------------------------------------------------------------* + * Split Binaural Rendering Constants + *----------------------------------------------------------------------------------*/ + +typedef enum +{ + PCM_INT16, + PCM_FLOAT32, + PCM_NOT_KNOW = 0xffff +} PCM_RESOLUTION; + +typedef enum +{ + ANY_YAW, + PITCH_ONLY, + ANY_ROLL, + PRED_ONLY, + PRED_ROLL_ONLY, + COM_GAIN_ONLY, + LR_GAIN_ONLY +} ISAR_SPLIT_REND_POSE_TYPE; + + +#define CLDFB_PLC_XF 2 /* Length of cross-fade into first good frame after frame loss in CLDFB cols. */ + +#define SPLIT_REND_MAX_YAW_ONLY_POSES 2 +#define SPLIT_REND_MAX_PITCH_ONLY_POSES 2 +#define SPLIT_REND_MAX_ROLL_ONLY_POSES 2 +#define SPLIT_REND_MAX_ONE_AXIS_MD_POSES 2 +#define MAX_EXTRAPOLATION_ANGLE 15.0f /* this means additional 15 degrees can be extrapolated on top of MD probing poses*/ +#define MAX_EXTRAPOLATION_ANGLE_Q22 (62914560) /* this means additional 15 degrees can be extrapolated on top of MD probing poses*/ + +#define MAX_HEAD_ROT_POSES ( 2 + SPLIT_REND_MAX_YAW_ONLY_POSES + SPLIT_REND_MAX_PITCH_ONLY_POSES + SPLIT_REND_MAX_ROLL_ONLY_POSES ) +#define MAX_SPLIT_REND_MD_BANDS 20 +#define MAX_SPLIT_MD_SUBFRAMES 1 +#define COMPLEX_MD_BAND_THRESH MAX_SPLIT_REND_MD_BANDS +#ifdef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS +#define COMPLEX_MD_BAND_THRESH_LOW 4 +#define COMPLEX_MD_BAND_THRESH_HIGH 10 +#else +#define COMPLEX_MD_BAND_THRESH_LOW 5 +#endif +#define SPLIT_REND_RO_MD_BAND_THRESH 4 + +#define ISAR_SPLIT_REND_PRED_63QUANT_PNTS_LOG2_CEIL 6 +#define ISAR_SPLIT_REND_PRED_31QUANT_PNTS_LOG2_CEIL 5 +#define ISAR_SPLIT_REND_ROLL_PRED_QUANT_PNTS_LOG2_CEIL 5 +#define ISAR_SPLIT_REND_D_QUANT_PNTS_LOG2_CEIL 4 + +#define ISAR_SPLIT_REND_PRED_MIN_VAL_Q30 -1503238553 //Q30 +#define ISAR_SPLIT_REND_PRED_MAX_VAL_Q30 1503238553 //Q30 + +#define ISAR_SPLIT_REND_NUM_QUANT_STRATS 4 +#define ISAR_SPLIT_REND_PRED_63QUANT_PNTS 63 +#define ISAR_SPLIT_REND_PRED_31QUANT_PNTS 31 +#define ISAR_SPLIT_REND_ROLL_PRED_QUANT_PNTS 31 +#define ISAR_SPLIT_REND_D_QUANT_PNTS 15 +#define ISAR_SPLIT_REND_PRED_MIN_VAL -1.4f +#define ISAR_SPLIT_REND_PRED_MAX_VAL 1.4f + +#define ISAR_SPLIT_REND_PITCH_G_MIN_VAL 0.5f +#define ISAR_SPLIT_REND_PITCH_G_MAX_VAL 1.5f +#define ISAR_SPLIT_REND_PITCH_G_MIN_VAL_Q30 (1<<29) //0.5f in Q30 +#define ISAR_SPLIT_REND_PITCH_G_MAX_VAL_Q30 1610612736 //1.5f in Q30 +#define ISAR_SPLIT_REND_PITCH_G_QUANT_PNTS ISAR_SPLIT_REND_D_QUANT_PNTS +#define ISAR_SPLIT_REND_D_MIN_VAL 0.0f +#define ISAR_SPLIT_REND_D_MAX_VAL 1.0f +#define ISAR_SPLIT_REND_D_MIN_VAL_FX 0 //Q31 +#define ISAR_SPLIT_REND_D_MAX_VAL_FX MAX_32 //Q31 + +#define ISAR_SPLIT_REND_PRED_ROLL_Q_STEP ( ( ISAR_SPLIT_REND_PRED_MAX_VAL - ISAR_SPLIT_REND_PRED_MIN_VAL ) / ( ISAR_SPLIT_REND_ROLL_PRED_QUANT_PNTS - 1 ) ) +#define ISAR_SPLIT_REND_PRED_ROLL_Q_STEP_Q31 200431807 +#define ISAR_SPLIT_REND_PRED_ROLL_1BYQ_STEP_Q26 719023543 +#define ISAR_SPLIT_REND_PRED_ROLL_1BYQ_STEP ( ( ISAR_SPLIT_REND_ROLL_PRED_QUANT_PNTS - 1 ) / ( ISAR_SPLIT_REND_PRED_MAX_VAL - ISAR_SPLIT_REND_PRED_MIN_VAL ) ) +#define ISAR_SPLIT_REND_PRED31_Q_STEP ( ( ISAR_SPLIT_REND_PRED_MAX_VAL - ISAR_SPLIT_REND_PRED_MIN_VAL ) / ( ISAR_SPLIT_REND_PRED_31QUANT_PNTS - 1 ) ) +#define ISAR_SPLIT_REND_PRED31_1BYQ_STEP ( ( ISAR_SPLIT_REND_PRED_31QUANT_PNTS - 1 ) / ( ISAR_SPLIT_REND_PRED_MAX_VAL - ISAR_SPLIT_REND_PRED_MIN_VAL ) ) +#define ISAR_SPLIT_REND_PRED63_Q_STEP ( ( ISAR_SPLIT_REND_PRED_MAX_VAL - ISAR_SPLIT_REND_PRED_MIN_VAL ) / ( ISAR_SPLIT_REND_PRED_63QUANT_PNTS - 1 ) ) +#define ISAR_SPLIT_REND_PRED63_1BYQ_STEP ( ( ISAR_SPLIT_REND_PRED_63QUANT_PNTS - 1 ) / ( ISAR_SPLIT_REND_PRED_MAX_VAL - ISAR_SPLIT_REND_PRED_MIN_VAL ) ) + +#define ISAR_SPLIT_REND_PRED31_Q_STEP_FX_Q31 200431807 +#define ISAR_SPLIT_REND_PRED31_1BYQ_STEP_FX_Q26 719023543 +#define ISAR_SPLIT_REND_PRED63_Q_STEP_FX_Q31 96983132 +#define ISAR_SPLIT_REND_PRED63_1BYQ_STEP_FX_Q26 1485981989 + +#define ISAR_SPLIT_REND_D_Q_STEP ( ( ISAR_SPLIT_REND_D_MAX_VAL - ISAR_SPLIT_REND_D_MIN_VAL ) / ( ISAR_SPLIT_REND_D_QUANT_PNTS - 1 ) ) +#define ISAR_SPLIT_REND_D_1BYQ_STEP ( ( ISAR_SPLIT_REND_D_QUANT_PNTS - 1 ) / ( ISAR_SPLIT_REND_D_MAX_VAL - ISAR_SPLIT_REND_D_MIN_VAL ) ) +#define ISAR_SPLIT_REND_PITCH_G_Q_STEP ( ( ISAR_SPLIT_REND_PITCH_G_MAX_VAL - ISAR_SPLIT_REND_PITCH_G_MIN_VAL ) / ( ISAR_SPLIT_REND_PITCH_G_QUANT_PNTS - 1 ) ) +#define ISAR_SPLIT_REND_PITCH_G_1BYQ_STEP ( ( ISAR_SPLIT_REND_PITCH_G_QUANT_PNTS - 1 ) / ( ISAR_SPLIT_REND_PITCH_G_MAX_VAL - ISAR_SPLIT_REND_PITCH_G_MIN_VAL ) ) +#define ISAR_SPLIT_REND_D_Q_STEP_Q31 153391689 +#define ISAR_SPLIT_REND_D_1BYQ_STEP_Q27 (14 << 27) //Q27 +#define ISAR_SPLIT_REND_PITCH_G_Q_STEP_Q31 153391689 +#define ISAR_SPLIT_REND_PITCH_G_1BYQ_STEP_Q27 (14 << 27) //Q27 + + +#define ISAR_SPLIT_REND_HEAD_POSE_BITS 9 +#define ISAR_SPLIT_REND_DOF_BITS 2 +#define ISAR_SPLIT_REND_HQ_MODE_BITS 1 +#define ISAR_SPLIT_REND_ROT_AXIS_BITS 3 +#define ISAR_SPLIT_REND_RO_FLAG_BITS 1 + +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS +#define IVAS_LC3PLUS_MAX_NUM_DECODERS 2 +#endif +/*----------------------------------------------------------------------------------* + * Split rendering bitrate constants + *----------------------------------------------------------------------------------*/ + +#define SPLIT_REND_256k 256000 +#define SPLIT_REND_320k 320000 +#define SPLIT_REND_384k 384000 +#define SPLIT_REND_512k 512000 +#define SPLIT_REND_768k 768000 + +#endif /*SPLIT_REND_WITH_HEAD_ROT */ + +#endif /*ISAR_CNST_H */ +/* clang-format on */ diff --git a/lib_dec/init_dec.c b/lib_isar/isar_lc3plus_common.c similarity index 59% rename from lib_dec/init_dec.c rename to lib_isar/isar_lc3plus_common.c index 3c20d7b2772ebb4c060c1ce80cad73b411b229d2..2e5a31cb6e9af5ea6748a1422d7c83c7781ab5a3 100644 --- a/lib_dec/init_dec.c +++ b/lib_isar/isar_lc3plus_common.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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,47 +30,60 @@ *******************************************************************************************************/ -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include #include "options.h" -#include "cnst.h" -#include "ivas_cnst.h" -#include "rom_com.h" -#include "prot.h" -#include "wmc_auto.h" -#include "prot_fx.h" +#include "isar_lc3plus_common.h" +#include "ivas_error.h" +#include "lc3.h" -/*----------------------------------------------------------------------* - * init_decoder() +#ifdef SPLIT_REND_WITH_HEAD_ROT +/*-----------------------------------------------------------------------------------------* + * Function ISAR_LC3PLUS_LC3plusErrToIvasErr() * - * Initialization of static variables for the decoder - *----------------------------------------------------------------------*/ - -/*----------------------------------------------------------------------* - * reset_preecho_dec() * - * Initialization of static variables for pre-echo - *----------------------------------------------------------------------*/ + *-----------------------------------------------------------------------------------------*/ -/*----------------------------------------------------------------------* - * destroy_cldfb_decoder_flt() - * - * Free memory which was allocated in init_decoder() - *----------------------------------------------------------------------*/ -void destroy_cldfb_decoder_ivas_fx( - Decoder_State *st /* o : Decoder static variables structure */ -) +ivas_error ISAR_LC3PLUS_LC3plusErrToIvasErr( + const LC3PLUS_Error lc3PlusError ) { - /* CLDFB BPF & resampling tools */ - deleteCldfb_ivas_fx( &st->cldfbAna ); /* delete analysis at max. sampling rate 48kHz */ - deleteCldfb_ivas_fx( &st->cldfbBPF ); /* delete analysis BPF at max. internal sampling rate 16kHz */ - deleteCldfb_ivas_fx( &st->cldfbSyn ); /* delete synthesis at output sampling rate */ - deleteCldfb_ivas_fx( &st->cldfbSynHB ); + switch ( lc3PlusError ) + { + case LC3PLUS_OK: + return IVAS_ERR_OK; + case LC3PLUS_BITRATE_ERROR: + return IVAS_ERR_LC3PLUS_INVALID_BITRATE; + default: + break; + } - deleteFdCngDec_fx( &st->hFdCngDec ); + return IVAS_ERR_INTERNAL; +} +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS +ivas_error IVAS_LC3PLUS_LC3plusRtpErrToIvasErr( const LC3PLUS_RTP_ERR lc3PlusRtpError ) +{ + switch ( lc3PlusRtpError ) + { + case LC3PLUS_RTP_ERR_NO_ERROR: + return IVAS_ERR_OK; + case LC3PLUS_RTP_ERR_NULL_PTR: + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + case LC3PLUS_RTP_ERR_INVALID_PARAMETERS: + return IVAS_ERR_WRONG_PARAMS; + case LC3PLUS_RTP_ERR_NOT_IMPLEMENTED: + return IVAS_ERR_NOT_IMPLEMENTED; + case LC3PLUS_RTP_ERR_UNSUPPORTED_CONFIGURATION: + return IVAS_ERR_INTERNAL; + case LC3PLUS_RTP_ERR_INVALID_BITSTREAM: + return IVAS_ERR_UNEXPECTED_LC3PLUS_BITSTREAM; + case LC3PLUS_RTP_ERR_INVALID_BITSTREAM_SIZE: + return IVAS_ERR_INVALID_BUFFER_SIZE; + case LC3PLUS_RTP_ERR_NOT_ENOUGH_FTDS_ALLOCATED: + return IVAS_ERR_INTERNAL; + case LC3PLUS_RTP_ERR_GENERIC_ERROR: + default: + break; + } - return; + return IVAS_ERR_UNKNOWN; } +#endif +#endif diff --git a/lib_enc/bw_detect.c b/lib_isar/isar_lc3plus_common.h similarity index 63% rename from lib_enc/bw_detect.c rename to lib_isar/isar_lc3plus_common.h index 2cba6f3283c2d99f57ad08f54ccbc75d283cfc11..57060944273cbb46aa0dbfc2ccf684414ae367f9 100644 --- a/lib_enc/bw_detect.c +++ b/lib_isar/isar_lc3plus_common.h @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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,35 +30,43 @@ *******************************************************************************************************/ -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ +#ifndef ISAR_LC3PLUS_COM_H +#define ISAR_LC3PLUS_COM_H + -#include #include #include "options.h" -#include -#include "cnst.h" -#include "rom_enc.h" -#include "rom_com.h" -#include "prot.h" -#include "ivas_prot.h" -#include "wmc_auto.h" - -/*-------------------------------------------------------------------* - * Local constants - *-------------------------------------------------------------------*/ +#include "ivas_error.h" +#ifdef SPLIT_REND_WITH_HEAD_ROT +#include "lc3.h" +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS +#include "isar_lc3plus_payload.h" +#endif -#define BWD_MIN_BRATE_WIDER_BW_MDCT IVAS_48k -#define BWD_MIN_BRATE_WIDER_BW_ISM IVAS_32k -#define BWD_MAX_BRATE_WIDER_BW_MDCT IVAS_80k -#define BWD_MAX_BRATE_WIDER_BW_ISM IVAS_64k +/*! common configuration parameters between encoder and decoder */ +typedef struct LC3PLUS_CONFIG +{ + /*! frame duration in microseconds [10000, 5000, 2500] */ + int16_t lc3plus_frame_duration_us; + /*! isar frame duration in microseconds [20000, 10000, 5000] */ + int16_t isar_frame_duration_us; + /*! sampling rate*/ + int32_t samplerate; + /*! number of channels */ + int16_t channels; +#if defined ISAR_BITSTREAM_UPDATE_LC3PLUS || defined ISAR_BITSTREAM_UPDATE_LC3PLUS + /*! high resolution mode enabled (1) or disabled (0)*/ + int16_t high_res_mode_enabled; +#endif +} LC3PLUS_CONFIG; -#define ALPHA_BWD 0.75f -#define BWD_LT_THRESH 0.6f +/*! utility function to convert LC3PLUS_Errors to the suitable ivas_error */ +ivas_error ISAR_LC3PLUS_LC3plusErrToIvasErr( const LC3PLUS_Error lc3PlusError ); -#define BWD_COUNT_MAX 100 -#define BWD_COUNT_WIDER_BW 10 -#define BWD_COUNT_WIDER_BW_MDCT 0 +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS +/*! utility function to convert LC3PLUS_Errors to the suitable ivas_error */ +ivas_error IVAS_LC3PLUS_LC3plusRtpErrToIvasErr( const LC3PLUS_RTP_ERR lc3PlusRtpError ); +#endif -#define CLDFB_ENER_OFFSET 1.6f +#endif /* SPLIT_REND_WITH_HEAD_ROT */ +#endif /* ISAR_LC3PLUS_COM_H */ diff --git a/lib_isar/isar_lc3plus_dec.c b/lib_isar/isar_lc3plus_dec.c new file mode 100644 index 0000000000000000000000000000000000000000..fd1adb157297496d5ee95e28015732691cbcbd51 --- /dev/null +++ b/lib_isar/isar_lc3plus_dec.c @@ -0,0 +1,858 @@ +/****************************************************************************************************** + + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository. All Rights Reserved. + + This software is protected by copyright law and by international treaties. + The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository retain full ownership rights in their respective contributions in + the software. This notice grants no license of any kind, including but not limited to patent + license, nor is any license granted by implication, estoppel or otherwise. + + Contributors are required to enter into the IVAS codec Public Collaboration agreement before making + contributions. + + This software is provided "AS IS", without any express or implied warranties. The software is in the + development stage. It is intended exclusively for experts who have experience with such software and + solely for the purpose of inspection. All implied warranties of non-infringement, merchantability + and fitness for a particular purpose are hereby disclaimed and excluded. + + Any dispute, controversy or claim arising under or in relation to providing this software shall be + submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in + accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and + the United Nations Convention on Contracts on the International Sales of Goods. + +*******************************************************************************************************/ + +#include +#include "options.h" +#include "prot_fx.h" +#include "ivas_prot_fx.h" +#include "isar_lc3plus_dec.h" +#include "isar_lc3plus_common.h" +#include "lc3.h" +#include "ivas_error_utils.h" +#include "wmc_auto.h" + +#ifdef SPLIT_REND_WITH_HEAD_ROT + +#ifndef ISAR_BITSTREAM_UPDATE_LC3PLUS +/*------------------------------------------------------------------------- + * isar_LC3PLUS_AllocateSubframeDecodingMatrix() + * + * + *------------------------------------------------------------------------*/ + +static void isar_LC3PLUS_DEC_FreeSubframeDecodingMatrix( + int16_t **subframeChannelMatrix ) +{ + for ( int16_t i = 0; i < MAX_PARAM_SPATIAL_SUBFRAMES; i++ ) + { + free( subframeChannelMatrix[i] ); + } + + free( subframeChannelMatrix ); + + return; +} +#endif + + +/*------------------------------------------------------------------------- + * ISAR_LC3PLUS_DEC_Open() + * + * + *------------------------------------------------------------------------*/ + +ivas_error ISAR_LC3PLUS_DEC_Open( + const LC3PLUS_CONFIG config, /* i : LC3plus decoder configuration */ + ISAR_LC3PLUS_DEC_HANDLE *handle /* o : decoder handle */ +) +{ + LC3PLUS_Error err; + int32_t decoder_size; + Word32 scratch_size; +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + int16_t i; + + if ( 0 == config.lc3plus_frame_duration_us ) + { + return IVAS_ERROR( IVAS_ERR_WRONG_PARAMS, "Invalid lc3plus_frame_duration_us (0)\n" ); + } +#else + int16_t lc3plusFrameIdx; + int16_t numLC3plusFramesPerIvasFrame; + int16_t i; +#endif + + if ( ( *handle = malloc( sizeof( struct ISAR_LC3PLUS_DEC_HANDLE ) ) ) == NULL ) + { + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LC3plus wrapper handle\n" ); + } + +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + if ( config.channels > IVAS_LC3PLUS_MAX_NUM_DECODERS ) + { + return IVAS_ERROR( IVAS_ERR_INIT_ERROR, "Maximum number of channels exceeds IVAS_LC3PLUS_MAX_NUM_DECODERS\n" ); + } +#else + + if ( 0 == config.lc3plus_frame_duration_us ) + { + return IVAS_ERROR( IVAS_ERR_WRONG_PARAMS, "Invalid lc3plus_frame_duration_us (0)\n" ); + } + numLC3plusFramesPerIvasFrame = (int16_t) ( config.isar_frame_duration_us / config.lc3plus_frame_duration_us ); +#endif + + + ( *handle )->num_decs = 0; + ( *handle )->pcm_conversion_buffer = NULL; + ( *handle )->handles = NULL; + ( *handle )->selective_decoding_states = NULL; + ( *handle )->bitstream_caches = NULL; + ( *handle )->scratch = NULL; + + if ( ( ( *handle )->handles = malloc( config.channels * sizeof( ISAR_LC3PLUS_DEC_HANDLE ) ) ) == NULL ) + { + ISAR_LC3PLUS_DEC_Close( handle ); + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LC3plus wrapper handle\n" ); + } + + if ( ( ( *handle )->selective_decoding_states = malloc( config.channels * sizeof( ISAR_LC3PLUS_DEC_SELECTIVE_DECODING_STATE * ) ) ) == NULL ) + { + ISAR_LC3PLUS_DEC_Close( handle ); + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LC3plus wrapper handle\n" ); + } + + for ( i = 0; i < config.channels; ++i ) + { + ( *handle )->handles[i] = NULL; + ( *handle )->selective_decoding_states[i] = NULL; + } + + if ( ( ( *handle )->bitstream_caches = malloc( config.channels * sizeof( ISAR_LC3PLUS_DEC_BITSTREAM_CACHE * ) ) ) == NULL ) + { + ISAR_LC3PLUS_DEC_Close( handle ); + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LC3plus wrapper handle\n" ); + } + for ( i = 0; i < config.channels; ++i ) + { + ( *handle )->bitstream_caches[i] = NULL; + } + + ( *handle )->num_decs = config.channels; + for ( int32_t iCh = 0; iCh < config.channels; iCh++ ) + { + ( *handle )->selective_decoding_states[iCh] = NULL; + if ( NULL != ( *handle )->bitstream_caches ) + { + ( *handle )->bitstream_caches[iCh] = NULL; + } + /* allocate and configure LC3plus decoder */ + decoder_size = lc3plus_dec_get_size( config.samplerate, 1, LC3PLUS_PLC_ADVANCED ); + if ( 0 == decoder_size ) + { + ISAR_LC3PLUS_DEC_Close( handle ); + return IVAS_ERROR( IVAS_ERR_INTERNAL, "lc3plus_dec_get_size failed\n" ); + } + + if ( ( ( *handle )->handles[iCh] = malloc( decoder_size ) ) == NULL ) + { + ISAR_LC3PLUS_DEC_Close( handle ); + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LC3plus decoder\n" ); + } + +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + err = lc3plus_dec_init( ( *handle )->handles[iCh], config.samplerate, 1, LC3PLUS_PLC_ADVANCED, config.high_res_mode_enabled ); +#else + err = lc3plus_dec_init( ( *handle )->handles[iCh], config.samplerate, 1, LC3PLUS_PLC_ADVANCED, 0 ); +#endif + if ( LC3PLUS_OK != err ) + { + ISAR_LC3PLUS_DEC_Close( handle ); + return IVAS_ERROR( ISAR_LC3PLUS_LC3plusErrToIvasErr( err ), "lc3plus_dec_init failed\n" ); + } + + err = lc3plus_dec_set_frame_dms( ( *handle )->handles[iCh], config.lc3plus_frame_duration_us / 100 ); + if ( LC3PLUS_OK != err ) + { + ISAR_LC3PLUS_DEC_Close( handle ); + return IVAS_ERROR( ISAR_LC3PLUS_LC3plusErrToIvasErr( err ), "lc3plus_dec_set_frame_dms failed\n" ); + } + + /* allocate and configure per LC3plus decoder skip state */ + if ( ( ( *handle )->selective_decoding_states[iCh] = malloc( sizeof( ISAR_LC3PLUS_DEC_SELECTIVE_DECODING_STATE ) ) ) == NULL ) + { + ISAR_LC3PLUS_DEC_Close( handle ); + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LC3plus decoder\n" ); + } + +#ifndef ISAR_BITSTREAM_UPDATE_LC3PLUS + if ( ( ( *handle )->selective_decoding_states[iCh]->frame_actions = malloc( numLC3plusFramesPerIvasFrame * sizeof( SelectiveDecAction ) ) ) == NULL ) + { + ISAR_LC3PLUS_DEC_Close( handle ); + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LC3plus decoder\n" ); + } +#endif + + ( *handle )->selective_decoding_states[iCh]->has_skipped_a_frame = 0; + ( *handle )->selective_decoding_states[iCh]->shall_decode_cached_frame = 0; +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + ( *handle )->selective_decoding_states[iCh]->frame_action = DEC_ACTION_DECODE_AND_USE; +#else + for ( lc3plusFrameIdx = 0; lc3plusFrameIdx < numLC3plusFramesPerIvasFrame; lc3plusFrameIdx++ ) + { + ( *handle )->selective_decoding_states[iCh]->frame_actions[lc3plusFrameIdx] = DEC_ACTION_DECODE_AND_USE; + } +#endif + + /* allocate and configure per LC3plus decoder bitstream cache */ + if ( ( ( *handle )->bitstream_caches[iCh] = malloc( sizeof( ISAR_LC3PLUS_DEC_BITSTREAM_CACHE ) ) ) == NULL ) + { + ISAR_LC3PLUS_DEC_Close( handle ); + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LC3plus decoder\n" ); + } +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + ( *handle )->bitstream_caches[iCh]->bitstream_cache_capacity = 400 /*LC3plus max non-HR octet count*/; +#else + ( *handle )->bitstream_caches[iCh]->bitstream_cache_capacity = 400 /*LC3plus max non-HR octet count*/ * numLC3plusFramesPerIvasFrame; +#endif + if ( ( ( *handle )->bitstream_caches[iCh]->bitstream_cache = malloc( ( *handle )->bitstream_caches[iCh]->bitstream_cache_capacity ) ) == NULL ) + { + ISAR_LC3PLUS_DEC_Close( handle ); + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LC3plus decoder\n" ); + } + ( *handle )->bitstream_caches[iCh]->bitstream_cache_size = 0; + } + + ( *handle )->config = config; + if ( config.isar_frame_duration_us < config.lc3plus_frame_duration_us || config.isar_frame_duration_us % config.lc3plus_frame_duration_us != 0 ) + { + ISAR_LC3PLUS_DEC_Close( handle ); + return IVAS_ERROR( IVAS_ERR_NOT_IMPLEMENTED, "Current pcm_conversion_buffer sizing requires that lc3plus uses a shorter or equal frame duration than ivas\n" ); + } + + if ( ( ( *handle )->pcm_conversion_buffer = malloc( sizeof( int16_t ) * config.samplerate * config.lc3plus_frame_duration_us / 1000000 ) ) == NULL ) + { + ISAR_LC3PLUS_DEC_Close( handle ); + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LC3plus decoder wrapper pcm_conversion_buffer\n" ); + } + + scratch_size = lc3plus_dec_get_scratch_size( ( *handle )->handles[0] ); + if ( ( ( *handle )->scratch = malloc( sizeof( uint8_t ) * scratch_size ) ) == NULL ) + { + ISAR_LC3PLUS_DEC_Close( handle ); + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LC3plus decoder wrapper scratch\n" ); + } + + return IVAS_ERR_OK; +} + +#ifndef ISAR_BITSTREAM_UPDATE_LC3PLUS +/*------------------------------------------------------------------------- + * ISAR_LC3PLUS_DEC_AllocateSubframeDecodingMatrix() + * + * + *------------------------------------------------------------------------*/ + +ivas_error ISAR_LC3PLUS_DEC_AllocateSubframeDecodingMatrix( + int16_t ***subframeChannelMatrix, + const uint32_t num_decs ) +{ + int16_t i; + + if ( ( *subframeChannelMatrix = malloc( MAX_PARAM_SPATIAL_SUBFRAMES * sizeof( int16_t * ) ) ) == NULL ) + { + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "subframeChannelMatrix allocation failed\n" ); + } + + for ( i = 0; i < MAX_PARAM_SPATIAL_SUBFRAMES; i++ ) + { + ( *subframeChannelMatrix )[i] = NULL; + } + + for ( i = 0; i < MAX_PARAM_SPATIAL_SUBFRAMES; i++ ) + { + if ( ( ( *subframeChannelMatrix )[i] = malloc( num_decs * sizeof( int16_t ) ) ) == NULL ) + { + isar_LC3PLUS_DEC_FreeSubframeDecodingMatrix( *subframeChannelMatrix ); + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "subframeChannelMatrix allocation failed\n" ); + } + } + + return IVAS_ERR_OK; +} + + +/*------------------------------------------------------------------------- + * ISAR_LC3PLUS_DEC_SetSelectiveDecodingMatrix() + * + * + *------------------------------------------------------------------------*/ + +ivas_error ISAR_LC3PLUS_DEC_SetSelectiveDecodingMatrix( + ISAR_LC3PLUS_DEC_HANDLE handle, /* i : LC3plus decoder handle */ + int16_t *subframeChannelMatrix[MAX_PARAM_SPATIAL_SUBFRAMES] ) +{ + int16_t numIvasSubFramesPerLC3frame; + uint32_t decIdx; + int16_t ivasSubframeIdx; + int16_t effectiveIsarSubframeDuration; + int16_t actual_num_spatial_subframes; + + if ( NULL == handle ) + { + return IVAS_ERROR( IVAS_ERR_UNEXPECTED_NULL_POINTER, "ISAR_LC3PLUS_DEC_HANDLE is NULL\n" ); + } + + if ( NULL == subframeChannelMatrix ) + { + return IVAS_ERROR( IVAS_ERR_UNEXPECTED_NULL_POINTER, "subframeChannelMatrix is NULL\n" ); + } + + if ( handle->config.lc3plus_frame_duration_us == 0 || handle->config.isar_frame_duration_us % handle->config.lc3plus_frame_duration_us != 0 ) + { + return IVAS_ERROR( IVAS_ERR_WRONG_PARAMS, "invalid isar_frame_duration_us/lc3plus_frame_duration_us values\n" ); + } + + effectiveIsarSubframeDuration = (int16_t) ( handle->config.isar_frame_duration_us == 20000 ? handle->config.isar_frame_duration_us / MAX_PARAM_SPATIAL_SUBFRAMES : handle->config.isar_frame_duration_us ); + numIvasSubFramesPerLC3frame = (int16_t) handle->config.lc3plus_frame_duration_us / effectiveIsarSubframeDuration; + actual_num_spatial_subframes = (int16_t) handle->config.isar_frame_duration_us / effectiveIsarSubframeDuration; + /* 0.5(0) = 10ms lc3plus, 5ms subframe */ + if ( numIvasSubFramesPerLC3frame != 1 ) + { + return IVAS_ERROR( IVAS_ERR_NOT_IMPLEMENTED, "Selective decoding is only implemented for aligned IVAS-Subframes & LC3plus \n" ); + } + + /* map subframeChannelMatrix to lc3plus skip states */ + /* 1st pass: Flag the required frames */ + for ( decIdx = 0; decIdx < handle->num_decs; decIdx++ ) + { + for ( ivasSubframeIdx = 0; ivasSubframeIdx < actual_num_spatial_subframes; ivasSubframeIdx++ ) + { + if ( 1 == subframeChannelMatrix[ivasSubframeIdx][decIdx] ) + { + /* subframe needed by the user, definitely decode */ + handle->selective_decoding_states[decIdx]->frame_actions[ivasSubframeIdx] = DEC_ACTION_DECODE_AND_USE; + } + else + { + + /* subframe not needed by the user, but might be required to re-initialize a decoder after inactivity */ + if ( + ( ivasSubframeIdx != actual_num_spatial_subframes - 1 ) && 1 == subframeChannelMatrix[ivasSubframeIdx + 1][decIdx] ) + { + /* ... but if the following subframe is required, it needs to be decoded and dropped */ + handle->selective_decoding_states[decIdx]->frame_actions[ivasSubframeIdx] = DEC_ACTION_DECODE_AND_DROP; + } + else + { + handle->selective_decoding_states[decIdx]->frame_actions[ivasSubframeIdx] = DEC_ACTION_SKIP; + } + } + } + } + + /* if a decoder was paused before, it needs to either: + * - Decode the cached frame (if available) and the first required frame OR + * - Decode the previous LC3plus subframe, even if it isn't needed by the user */ + for ( decIdx = 0; decIdx < handle->num_decs; decIdx++ ) + { + if ( handle->selective_decoding_states[decIdx]->has_skipped_a_frame ) + { + /* find the first frame required by the user */ + for ( ivasSubframeIdx = 0; ivasSubframeIdx < actual_num_spatial_subframes; ivasSubframeIdx++ ) + { + if ( DEC_ACTION_DECODE_AND_USE == handle->selective_decoding_states[decIdx]->frame_actions[ivasSubframeIdx] ) + { + /* The first required frame is the first subframe. To flush the decoder, the cached frame must be decoded and dropped */ + if ( 0 == ivasSubframeIdx ) + { + handle->selective_decoding_states[decIdx]->shall_decode_cached_frame = 1; + break; + } + /* The first required frame is not the first frame, so the cache is useless. Instead we decode & drop the previous frame*/ + else + { + handle->selective_decoding_states[decIdx]->frame_actions[ivasSubframeIdx - 1] = DEC_ACTION_DECODE_AND_DROP; + break; + } + } + } + } + } + + /* if a dec gets paused & caching is activated we need to flag the last useful LC3plus frame for caching */ + for ( decIdx = 0; decIdx < handle->num_decs; decIdx++ ) + { + for ( ivasSubframeIdx = 0; ivasSubframeIdx < actual_num_spatial_subframes; ivasSubframeIdx++ ) + { + if ( handle->selective_decoding_states[decIdx]->frame_actions[ivasSubframeIdx] == DEC_ACTION_SKIP && handle->selective_decoding_states[decIdx]->frame_actions[actual_num_spatial_subframes - 1] != DEC_ACTION_DECODE_AND_USE ) + { + handle->selective_decoding_states[decIdx]->frame_actions[actual_num_spatial_subframes - 1] = DEC_ACTION_CACHE; + } + } + } + + return IVAS_ERR_OK; +} +#endif + + +/*------------------------------------------------------------------------- + * ISAR_LC3PLUS_DEC_GetDelay() + * + * + *------------------------------------------------------------------------*/ + +ivas_error ISAR_LC3PLUS_DEC_GetDelay( + ISAR_LC3PLUS_DEC_HANDLE handle, /* i : LC3plus decoder handle */ + int32_t *delayInSamples /* o : decoder delay in number of samples per channel */ +) +{ + int32_t tmpDelayInSamples; + + if ( NULL == handle ) + { + return IVAS_ERROR( IVAS_ERR_UNEXPECTED_NULL_POINTER, "ISAR_LC3PLUS_DEC_HANDLE is NULL\n" ); + } + if ( NULL == delayInSamples ) + { + return IVAS_ERROR( IVAS_ERR_UNEXPECTED_NULL_POINTER, "delayInSamples is NULL\n" ); + } + + *delayInSamples = 0; + /* sanity check whether all encoders are actually configured identically */ + for ( uint32_t iDec = 0; iDec < handle->num_decs; iDec++ ) + { + if ( NULL == handle->handles[iDec] ) + { + return IVAS_ERROR( IVAS_ERR_UNEXPECTED_NULL_POINTER, "LC3plus decoder handle is NULL\n" ); + } + + tmpDelayInSamples = lc3plus_dec_get_delay( handle->handles[iDec] ); + if ( 0 != *delayInSamples && tmpDelayInSamples != *delayInSamples ) + { + return IVAS_ERROR( IVAS_ERR_INTERNAL, "Not all mono LC3plus decoders are configured identically\n" ); + } + + *delayInSamples = tmpDelayInSamples; + } + + return IVAS_ERR_OK; +} + + +/*------------------------------------------------------------------------- + * ISAR_LC3PLUS_DEC_Close() + * + * + *------------------------------------------------------------------------*/ + +void ISAR_LC3PLUS_DEC_Close( + ISAR_LC3PLUS_DEC_HANDLE *handle /* i/o: Pointer to LC3plus decoder handle */ +) +{ + if ( NULL == handle || NULL == *handle ) + { + return; + } + for ( uint32_t iDec = 0; iDec < ( *handle )->num_decs; iDec++ ) + { + if ( NULL != ( *handle )->handles && NULL != ( *handle )->handles[iDec] ) + { + free( ( *handle )->handles[iDec] ); + } + + if ( NULL != ( *handle )->selective_decoding_states && NULL != ( *handle )->selective_decoding_states[iDec] ) + { +#ifndef ISAR_BITSTREAM_UPDATE_LC3PLUS + free( ( *handle )->selective_decoding_states[iDec]->frame_actions ); +#endif + free( ( *handle )->selective_decoding_states[iDec] ); + } + + if ( NULL != ( *handle )->bitstream_caches && NULL != ( *handle )->bitstream_caches[iDec] ) + { + free( ( *handle )->bitstream_caches[iDec]->bitstream_cache ); + free( ( *handle )->bitstream_caches[iDec] ); + } + } + + if ( NULL != ( *handle )->pcm_conversion_buffer ) + { + free( ( *handle )->pcm_conversion_buffer ); + } + if ( NULL != ( *handle )->scratch ) + { + free( ( *handle )->scratch ); + } + + free( ( *handle )->handles ); + + if ( NULL != ( *handle )->bitstream_caches ) + { + free( ( *handle )->bitstream_caches ); + } + free( ( *handle )->selective_decoding_states ); + + free( *handle ); + *handle = NULL; + + return; +} + + +/*------------------------------------------------------------------------- + * decode_or_conceal_one_lc3plus_frame() + * + * + *------------------------------------------------------------------------*/ + +static ivas_error decode_or_conceal_one_lc3plus_frame( + LC3PLUS_Dec *dec, + uint8_t *bitstream_in, + const int32_t bitstream_in_length, + int16_t **pcm_out_buffer, + const int32_t badFrameIndicator, + uint8_t *scratch ) +{ + LC3PLUS_Error err; + + push_wmops( "lc3plus_dec16" ); + err = lc3plus_dec16( dec, bitstream_in, bitstream_in_length, pcm_out_buffer, scratch, badFrameIndicator ); + pop_wmops(); + + if ( err == LC3PLUS_DECODE_ERROR && 1 == badFrameIndicator ) + { + /* LC3PLUS_DECODE_ERROR && badFrameIndicator means that the decoder has successfully concealed, which is actually OK. */ + err = LC3PLUS_OK; + } + + if ( err != LC3PLUS_OK ) + { + return IVAS_ERROR( ISAR_LC3PLUS_LC3plusErrToIvasErr( err ), "lc3plus_dec16 failed\n" ); + } + + return IVAS_ERR_OK; +} + + +/*------------------------------------------------------------------------- + * isar_LC3PLUS_DEC_Decode_or_Conceal_internal() + * + * + *------------------------------------------------------------------------*/ + +static ivas_error isar_LC3PLUS_DEC_Decode_or_Conceal_internal( + ISAR_LC3PLUS_DEC_HANDLE handle, /* i : LC3plus decoder configuration */ + uint8_t *bitstream_in, /* i : pointer to input bitstream */ + int32_t bitstream_in_size, /* i : size of bitstream_in */ + const int16_t badFrameIndicator, /* i : bad frame indicator. If set to 1, triggers concealment */ + Word32 **pcm_out /* o : decoded samples */ +) +{ + uint32_t iDec; +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + int32_t config_num_media_times; + int32_t iMediaTime; + int32_t iFtd; + LC3PLUS_RTP_PAYLOAD payload; +#else + int32_t iLc3plusFrame; + int32_t lc3framesPerIvasFrame; + int32_t bitstreamOffsetPerCoder; + uint8_t *bitstream_in_iter = bitstream_in; +#endif + int32_t ivasSampleIndex; + int16_t numSamplesPerLC3plusChannel; + ivas_error err; + + if ( NULL == handle ) + { + return IVAS_ERROR( IVAS_ERR_UNEXPECTED_NULL_POINTER, "LC3PLUS_Dec_Wrap_Handle is NULL\n" ); + } + if ( NULL == bitstream_in ) + { + return IVAS_ERROR( IVAS_ERR_UNEXPECTED_NULL_POINTER, "bitstream_in is NULL\n" ); + } + if ( NULL == pcm_out ) + { + return IVAS_ERROR( IVAS_ERR_UNEXPECTED_NULL_POINTER, "pcm_out is NULL\n" ); + } + if ( badFrameIndicator != 0 && badFrameIndicator != 1 ) + { + return IVAS_ERROR( IVAS_ERR_WRONG_PARAMS, "badFrameIndicator must be 1 or 0\n" ); + } + if ( badFrameIndicator == 0 && bitstream_in_size <= 0 ) + { + return IVAS_ERROR( IVAS_ERR_WRONG_PARAMS, "bitstream_in_size must be positive\n" ); + } + + if ( handle->config.isar_frame_duration_us % handle->config.lc3plus_frame_duration_us != 0 ) + { + return IVAS_ERROR( IVAS_ERR_NOT_IMPLEMENTED, "isar_frame_duration_us must be equal or multiple of lc3plus_frame_duration_us \n" ); + } + +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + config_num_media_times = handle->config.isar_frame_duration_us / handle->config.lc3plus_frame_duration_us; + if ( !badFrameIndicator ) + { + if ( LC3PLUS_RTP_payload_deserialize( &payload, bitstream_in, bitstream_in_size ) != LC3PLUS_RTP_ERR_NO_ERROR ) + { + return IVAS_ERROR( IVAS_ERR_INTERNAL, "LC3PLUS_RTP_payload_deserialize failed\n" ); + } + if ( payload.sampling_rate_hz != handle->config.samplerate ) + { + return IVAS_ERROR( IVAS_ERR_NOT_IMPLEMENTED, "LC3plus config change (samplerate) in bitstream is not supported\n" ); + } + if ( payload.num_channels != handle->config.channels ) + { + return IVAS_ERROR( IVAS_ERR_NOT_IMPLEMENTED, "LC3plus config change (number of channels) in bitstream is not supported\n" ); + } + if ( payload.frame_duration_us != handle->config.lc3plus_frame_duration_us ) + { + return IVAS_ERROR( IVAS_ERR_NOT_IMPLEMENTED, "LC3plus config change (frame duration) in bitstream is not supported\n" ); + } + if ( payload.high_resolution_enabled != handle->config.high_res_mode_enabled ) + { + return IVAS_ERROR( IVAS_ERR_NOT_IMPLEMENTED, "LC3plus config change (high resolution mode) in bitstream is not supported\n" ); + } + if ( payload.num_media_times != config_num_media_times ) + { + return IVAS_ERROR( IVAS_ERR_NOT_IMPLEMENTED, "LC3plus config change (number of media times per frame data block) in bitstream is not supported\n" ); + } + } +#endif + +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + numSamplesPerLC3plusChannel = (int16_t) ( handle->config.samplerate / ( 1000000 / handle->config.isar_frame_duration_us ) / config_num_media_times ); + for ( iDec = 0; iDec < handle->num_decs; iDec++ ) + { + for ( iMediaTime = 0; iMediaTime < config_num_media_times; iMediaTime++ ) + { + iFtd = iDec + iMediaTime * handle->num_decs; +#else + lc3framesPerIvasFrame = handle->config.isar_frame_duration_us / handle->config.lc3plus_frame_duration_us; + + numSamplesPerLC3plusChannel = (int16_t) ( handle->config.samplerate / ( 1000000 / handle->config.isar_frame_duration_us ) / lc3framesPerIvasFrame ); + bitstreamOffsetPerCoder = bitstream_in_size / handle->num_decs / lc3framesPerIvasFrame; + for ( iDec = 0; iDec < handle->num_decs; iDec++ ) + { + for ( iLc3plusFrame = 0; iLc3plusFrame < lc3framesPerIvasFrame; iLc3plusFrame++ ) + { +#endif + if ( handle->selective_decoding_states[iDec]->shall_decode_cached_frame ) + { + if ( 0 == handle->bitstream_caches[iDec]->bitstream_cache_size ) + { + return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "LC3plus cache is empty\n" ); + } + + err = decode_or_conceal_one_lc3plus_frame( handle->handles[iDec], handle->bitstream_caches[iDec]->bitstream_cache, handle->bitstream_caches[iDec]->bitstream_cache_size, &handle->pcm_conversion_buffer, badFrameIndicator, handle->scratch ); + if ( err != IVAS_ERR_OK ) + { + return IVAS_ERROR( err, "lc3plus decoding failed\n" ); + } + handle->selective_decoding_states[iDec]->shall_decode_cached_frame = 0; + handle->selective_decoding_states[iDec]->has_skipped_a_frame = 0; + } + + /* reset cache if caching is enabled - it has either been decoded or is not needed */ + if ( NULL != handle->bitstream_caches ) + { + handle->bitstream_caches[iDec]->bitstream_cache_size = 0; + } + +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + switch ( handle->selective_decoding_states[iDec]->frame_action ) +#else + switch ( handle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] ) +#endif + { +#ifndef ISAR_BITSTREAM_UPDATE_LC3PLUS + case DEC_ACTION_DECODE_AND_DROP: + { + err = decode_or_conceal_one_lc3plus_frame( handle->handles[iDec], bitstream_in_iter, bitstreamOffsetPerCoder, &handle->pcm_conversion_buffer, badFrameIndicator, handle->scratch ); + if ( err != IVAS_ERR_OK ) + { + return IVAS_ERROR( err, "lc3plus decoding failed\n" ); + } + handle->selective_decoding_states[iDec]->has_skipped_a_frame = 0; + break; + } +#endif + case DEC_ACTION_DECODE_AND_USE: + { +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + if ( badFrameIndicator ) + { + err = decode_or_conceal_one_lc3plus_frame( handle->handles[iDec], bitstream_in, bitstream_in_size, &handle->pcm_conversion_buffer, badFrameIndicator, handle->scratch ); + } + else if ( payload.ftds[iFtd].frame_data_length == LC3PLUS_RTP_FDL_SPEECH_BAD ) + { + return IVAS_ERR_NOT_IMPLEMENTED; + /* Untested therefore disabled. Would probably only need to call concealment, + * but the LC3plus API requires a non-NULL ptr for this which is not available here */ + } + else + { + err = decode_or_conceal_one_lc3plus_frame( handle->handles[iDec], payload.ftds[iFtd].frame_data, payload.ftds[iFtd].frame_data_length, &handle->pcm_conversion_buffer, badFrameIndicator, handle->scratch ); + } + if ( err != IVAS_ERR_OK ) + { + return IVAS_ERROR( err, "lc3plus decoding failed\n" ); + } + + for ( int16_t iSampleInt16 = 0; iSampleInt16 < numSamplesPerLC3plusChannel; iSampleInt16++ ) + { + ivasSampleIndex = iSampleInt16 + iMediaTime * numSamplesPerLC3plusChannel; + pcm_out[iDec][ivasSampleIndex] = handle->pcm_conversion_buffer[iSampleInt16]; + } + handle->selective_decoding_states[iDec]->has_skipped_a_frame = 0; + break; +#else + err = decode_or_conceal_one_lc3plus_frame( handle->handles[iDec], bitstream_in_iter, bitstreamOffsetPerCoder, &handle->pcm_conversion_buffer, badFrameIndicator ); + if ( err != IVAS_ERR_OK ) + { + return IVAS_ERROR( err, "lc3plus decoding failed\n" ); + } + + for ( int32_t iSampleInt16 = 0; iSampleInt16 < numSamplesPerLC3plusChannel; iSampleInt16++ ) + { + ivasSampleIndex = iSampleInt16 + iLc3plusFrame * numSamplesPerLC3plusChannel; + pcm_out[iDec][ivasSampleIndex] = handle->pcm_conversion_buffer[iSampleInt16]; + } + handle->selective_decoding_states[iDec]->has_skipped_a_frame = 0; + break; +#endif + } +#ifndef ISAR_BITSTREAM_UPDATE_LC3PLUS + case DEC_ACTION_SKIP: + { + /* log that this instance has skipped a frame and must decode twice once reactivated */ + handle->selective_decoding_states[iDec]->has_skipped_a_frame = 1; + break; + } +#endif + case DEC_ACTION_CACHE: + { +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + if ( handle->bitstream_caches[iDec]->bitstream_cache_capacity < (int32_t) payload.ftds[iFtd].frame_data_length ) + { + return IVAS_ERROR( IVAS_ERR_INVALID_BUFFER_SIZE, "bitstream_cache_capacity is too low for LC3plus frame size\n" ); + } + /* store bit rate of cached frame */ + mvc2c( payload.ftds[iFtd].frame_data, handle->bitstream_caches[iDec]->bitstream_cache, (int16_t) payload.ftds[iFtd].frame_data_length ); + handle->bitstream_caches[iDec]->bitstream_cache_size = payload.ftds[iFtd].frame_data_length; + /* log that this instance has skipped a frame and must decode twice once reactivated */ + handle->selective_decoding_states[iDec]->has_skipped_a_frame = 1; + break; +#else + if ( handle->bitstream_caches[iDec]->bitstream_cache_capacity < bitstreamOffsetPerCoder ) + { + return IVAS_ERROR( IVAS_ERR_INVALID_BUFFER_SIZE, "bitstream_cache_capacity is too low for LC3plus frame size\n" ); + } + /* store bit rate of cached frame */ + mvc2c( bitstream_in_iter, handle->bitstream_caches[iDec]->bitstream_cache, (int16_t) bitstreamOffsetPerCoder ); + handle->bitstream_caches[iDec]->bitstream_cache_size = bitstreamOffsetPerCoder; + /* log that this instance has skipped a frame and must decode twice once reactivated */ + handle->selective_decoding_states[iDec]->has_skipped_a_frame = 1; + break; +#endif + } + case DEC_ACTION_NUM_ENUMS: + default: + return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "invalid LC3plus decoder state\n" ); + } +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + } /* for each media time */ + /* reset skipping state, must be set by the user before each decode call*/ + handle->selective_decoding_states[iDec]->frame_action = DEC_ACTION_DECODE_AND_USE; + } /* for each dec/channel */ +#else + + bitstream_in_iter += bitstreamOffsetPerCoder; + } + + /* reset skipping state, must be set by the user before each decode call*/ + for ( iLc3plusFrame = 0; iLc3plusFrame < lc3framesPerIvasFrame; iLc3plusFrame++ ) + { + handle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] = DEC_ACTION_DECODE_AND_USE; + } + } + +#endif + return IVAS_ERR_OK; +} + + +/*------------------------------------------------------------------------- + * ISAR_LC3PLUS_DEC_Decode() + * + * + *------------------------------------------------------------------------*/ + +ivas_error ISAR_LC3PLUS_DEC_Decode( + ISAR_LC3PLUS_DEC_HANDLE handle, /* i : LC3plus decoder configuration */ + uint8_t *bitstream_in, /* i : pointer to input bitstream */ + const int32_t bitstream_in_size, /* i : size of bitstream_in */ + Word32 **pcm_out /* o : decoded samples */ +) +{ + int16_t badFrameIndicator; + + if ( NULL == handle ) + { + return IVAS_ERROR( IVAS_ERR_UNEXPECTED_NULL_POINTER, "LC3PLUS_Dec_Wrap_Handle is NULL\n" ); + } + if ( NULL == bitstream_in ) + { + return IVAS_ERROR( IVAS_ERR_UNEXPECTED_NULL_POINTER, "bitstream_in is NULL\n" ); + } + if ( NULL == pcm_out ) + { + return IVAS_ERROR( IVAS_ERR_UNEXPECTED_NULL_POINTER, "pcm_out is NULL\n" ); + } + badFrameIndicator = 0; + + return isar_LC3PLUS_DEC_Decode_or_Conceal_internal( handle, bitstream_in, bitstream_in_size, badFrameIndicator, pcm_out ); +} + + +/*------------------------------------------------------------------------- + * ISAR_LC3PLUS_DEC_Conceal() + * + * + *------------------------------------------------------------------------*/ + +ivas_error ISAR_LC3PLUS_DEC_Conceal( + ISAR_LC3PLUS_DEC_HANDLE handle, /* i : LC3plus decoder handle */ + Word32 **pcm_out /* o : decoded samples */ +) +{ + uint8_t bitstream_in[LC3PLUS_MAX_BYTES]; + int16_t badFrameIndicator; + + if ( NULL == handle ) + { + return IVAS_ERROR( IVAS_ERR_UNEXPECTED_NULL_POINTER, "LC3PLUS_Dec_Wrap_Handle is NULL\n" ); + } + + if ( NULL == pcm_out ) + { + return IVAS_ERROR( IVAS_ERR_UNEXPECTED_NULL_POINTER, "pcm_out is NULL\n" ); + } + + /* LC3plus API requires a non-NULL bitstream pointer, even when triggering concealment */ + badFrameIndicator = 1; + + return isar_LC3PLUS_DEC_Decode_or_Conceal_internal( handle, bitstream_in, 0, badFrameIndicator, pcm_out ); +} +#endif /* SPLIT_REND_WITH_HEAD_ROT */ diff --git a/lib_isar/isar_lc3plus_dec.h b/lib_isar/isar_lc3plus_dec.h new file mode 100644 index 0000000000000000000000000000000000000000..5e297a40714f2e3687997889273a2f9ca23d2b00 --- /dev/null +++ b/lib_isar/isar_lc3plus_dec.h @@ -0,0 +1,136 @@ +/****************************************************************************************************** + + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository. All Rights Reserved. + + This software is protected by copyright law and by international treaties. + The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository retain full ownership rights in their respective contributions in + the software. This notice grants no license of any kind, including but not limited to patent + license, nor is any license granted by implication, estoppel or otherwise. + + Contributors are required to enter into the IVAS codec Public Collaboration agreement before making + contributions. + + This software is provided "AS IS", without any express or implied warranties. The software is in the + development stage. It is intended exclusively for experts who have experience with such software and + solely for the purpose of inspection. All implied warranties of non-infringement, merchantability + and fitness for a particular purpose are hereby disclaimed and excluded. + + Any dispute, controversy or claim arising under or in relation to providing this software shall be + submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in + accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and + the United Nations Convention on Contracts on the International Sales of Goods. + +*******************************************************************************************************/ + +#ifndef ISAR_LC3PLUS_DEC_H +#define ISAR_LC3PLUS_DEC_H + +#include +#include "options.h" +#ifdef SPLIT_REND_WITH_HEAD_ROT +#include "lc3.h" +#include "ivas_error.h" +#include "ivas_cnst.h" +#include "isar_lc3plus_common.h" + + +typedef enum +{ +#ifndef ISAR_BITSTREAM_UPDATE_LC3PLUS + DEC_ACTION_DECODE_AND_DROP = 0, +#endif + DEC_ACTION_DECODE_AND_USE, +#ifndef ISAR_BITSTREAM_UPDATE_LC3PLUS + DEC_ACTION_SKIP, +#endif + DEC_ACTION_CACHE, + DEC_ACTION_NUM_ENUMS +} SelectiveDecAction; + + +typedef struct ISAR_LC3PLUS_DEC_SELECTIVE_DECODING_STATE +{ + /*! indicates that the decoder has skipped one or more frames. This means it must decode two frames to flush algorithmic delay when re-activated */ + int16_t has_skipped_a_frame; +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + /*! action to execute for the next frame */ + SelectiveDecAction frame_action; +#else + /*! if set to 1, decoder will skip decoding for the next frame */ + SelectiveDecAction *frame_actions; +#endif + /*! if set to 1, decoder will decode the cache before decoding any of current frames */ + int16_t shall_decode_cached_frame; +} ISAR_LC3PLUS_DEC_SELECTIVE_DECODING_STATE; + +typedef struct ISAR_LC3PLUS_DEC_BITSTREAM_CACHE +{ + uint8_t *bitstream_cache; + int32_t bitstream_cache_capacity; + int32_t bitstream_cache_size; +} ISAR_LC3PLUS_DEC_BITSTREAM_CACHE; + +/* decoder wrapper */ +typedef struct ISAR_LC3PLUS_DEC_HANDLE +{ + LC3PLUS_Dec **handles; + ISAR_LC3PLUS_DEC_SELECTIVE_DECODING_STATE **selective_decoding_states; + ISAR_LC3PLUS_DEC_BITSTREAM_CACHE **bitstream_caches; + uint32_t num_decs; + int16_t *pcm_conversion_buffer; + uint8_t *scratch; + LC3PLUS_CONFIG config; +} * ISAR_LC3PLUS_DEC_HANDLE; + +ivas_error ISAR_LC3PLUS_DEC_Open( + const LC3PLUS_CONFIG config, /* i : decoder configuration */ + ISAR_LC3PLUS_DEC_HANDLE *handle /* o : decoder handle */ +); + +ivas_error ISAR_LC3PLUS_DEC_GetDelay( + ISAR_LC3PLUS_DEC_HANDLE handle, /* i : decoder handle */ + int32_t *delayInSamples /* o : algorithmic delay of encoding and decoding in number of samples per channel */ +); + +void ISAR_LC3PLUS_DEC_Close( + ISAR_LC3PLUS_DEC_HANDLE *handle /* i/o: pointer to decoder handle */ +); + +#ifndef ISAR_BITSTREAM_UPDATE_LC3PLUS +/*! Sets a matrix[MAX_PARAM_SPATIAL_SUBFRAMES][numLC3plusDecoders] where all require subframes must be flagged with 1, frames that are not required with 0 */ +ivas_error ISAR_LC3PLUS_DEC_SetSelectiveDecodingMatrix( + ISAR_LC3PLUS_DEC_HANDLE handle, /* i : decoder handle */ + int16_t *subframeChannelMatrix[MAX_PARAM_SPATIAL_SUBFRAMES] /* i : */ +); +#endif + +ivas_error ISAR_LC3PLUS_DEC_Decode( + ISAR_LC3PLUS_DEC_HANDLE handle, /* i : decoder handle */ + uint8_t *bitstream_in, /* i : pointer to input bitstream */ + const int32_t bitstream_in_size, /* i : size of bitstream_in */ + Word32 **pcm_out /* o : decoded samples */ +); + +ivas_error ISAR_LC3PLUS_DEC_Conceal( + ISAR_LC3PLUS_DEC_HANDLE handle, /* i : decoder handle */ + Word32 **pcm_out /* o : decoded samples */ +); + +#ifndef ISAR_BITSTREAM_UPDATE_LC3PLUS +ivas_error ISAR_LC3PLUS_DEC_AllocateSubframeDecodingMatrix( + int16_t ***subframeChannelMatrix, + const uint32_t num_decs ); + +void isar_LC3PLUS_DEC_FreeSubframeDecodingMatrix( int16_t **subframeChannelMatrix ); +#endif + +#endif /* SPLIT_REND_WITH_HEAD_ROT */ +#endif /* ISAR_LC3PLUS_DEC_H */ diff --git a/lib_isar/isar_lc3plus_enc.c b/lib_isar/isar_lc3plus_enc.c new file mode 100644 index 0000000000000000000000000000000000000000..08ec7c0a8b120ac8ecf95918e806ad3b2012c2cb --- /dev/null +++ b/lib_isar/isar_lc3plus_enc.c @@ -0,0 +1,698 @@ +/****************************************************************************************************** + + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository. All Rights Reserved. + + This software is protected by copyright law and by international treaties. + The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository retain full ownership rights in their respective contributions in + the software. This notice grants no license of any kind, including but not limited to patent + license, nor is any license granted by implication, estoppel or otherwise. + + Contributors are required to enter into the IVAS codec Public Collaboration agreement before making + contributions. + + This software is provided "AS IS", without any express or implied warranties. The software is in the + development stage. It is intended exclusively for experts who have experience with such software and + solely for the purpose of inspection. All implied warranties of non-infringement, merchantability + and fitness for a particular purpose are hereby disclaimed and excluded. + + Any dispute, controversy or claim arising under or in relation to providing this software shall be + submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in + accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and + the United Nations Convention on Contracts on the International Sales of Goods. + +*******************************************************************************************************/ + +#include "isar_lc3plus_enc.h" +#include "isar_lc3plus_common.h" +#include "lc3.h" +#include "ivas_error_utils.h" +#include "prot_fx.h" +#include "wmc_auto.h" +#include "options.h" + +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS +static const LC3PLUS_RTP_FDL s_fdl_request = LC3PLUS_RTP_FDL_NO_REQ_OR_NO_DATA; +#endif + +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS +static int32_t limit_per_channel_bitrate( LC3PLUS_CONFIG config, + int32_t per_channel_bitrate ) +{ + if ( config.high_res_mode_enabled ) + { + switch ( config.lc3plus_frame_duration_us ) + { + case 10000: + return min( per_channel_bitrate, 500000 ); + case 5000: + return min( per_channel_bitrate, 600000 ); + case 2500: + return min( per_channel_bitrate, 672000 ); + default: + assert( false && "unreachable" ); + } + } + + switch ( config.samplerate ) + { + case 48000: + case 32000: + return min( per_channel_bitrate, 320000 ); + case 24000: + return min( per_channel_bitrate, 314400 ); + case 16000: + return min( per_channel_bitrate, 221600 ); + case 8000: + return min( per_channel_bitrate, 114400 ); + default: + assert( false && "unreachable" ); + } + + assert( false && "unreachable" ); + return -1; +} +#endif + +#ifdef SPLIT_REND_WITH_HEAD_ROT +/*-------------------------------------------------------------------* + * Function ISAR_LC3PLUS_ENC_Open() + * + * + *-------------------------------------------------------------------*/ +ivas_error ISAR_LC3PLUS_ENC_Open( + const LC3PLUS_CONFIG config, /* i : LC3plus encoder configuration */ + const UWord32 bitsPerSecond, /* i : bit rate */ + ISAR_LC3PLUS_ENC_HANDLE *handle /* o : encoder handle */ +) +{ +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + int32_t num_lc3plus_media_times_per_ivas_frame; +#ifndef ISAR_BITSTREAM_UPDATE_LC3PLUS + int32_t lc3plus_num_bytes_per_frame; +#endif + bool is_last_media_time, is_last_channel; +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + ivas_error ivas_err; +#endif +#endif +#ifndef ISAR_BITSTREAM_UPDATE_LC3PLUS + int32_t bitsPerSecondPerChannel; +#endif + Word32 scratch_size; + int32_t encoder_size; + LC3PLUS_Error err; + int32_t lfeChans[1]; + int16_t i; + + lfeChans[0] = 0; + + if ( 0U == config.channels ) + { + return IVAS_ERROR( IVAS_ERR_INTERNAL, "Invalid number of channels\n" ); + } +#ifndef ISAR_BITSTREAM_UPDATE_LC3PLUS + bitsPerSecondPerChannel = bitsPerSecond / config.channels; +#endif +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + if ( config.lc3plus_frame_duration_us != 2500 && config.lc3plus_frame_duration_us != 5000 && config.lc3plus_frame_duration_us != 10000 ) + { + return IVAS_ERROR( IVAS_ERR_INTERNAL, "Invalid lc3plus_frame_duration_us\n" ); + } + if ( config.isar_frame_duration_us != 20000 && config.isar_frame_duration_us != 10000 && config.isar_frame_duration_us != 5000 ) + { + return IVAS_ERROR( IVAS_ERR_INTERNAL, "Invalid isar_frame_duration_us\n" ); + } +#endif + encoder_size = lc3plus_enc_get_size( config.samplerate, 1 ); + if ( 0 == encoder_size ) + { + return IVAS_ERROR( IVAS_ERR_INTERNAL, "lc3plus_enc_get_size failed\n" ); + } + + if ( ( *handle = malloc( sizeof( struct ISAR_LC3PLUS_ENC_HANDLE ) ) ) == NULL ) + { + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LC3plus wrapper handle\n" ); + } +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + ( *handle )->config = config; + ( *handle )->frame_type_descriptors = NULL; +#endif + + ( *handle )->pcm_conversion_buffer = NULL; + ( *handle )->scratch = NULL; + ( *handle )->num_encs = 0; + if ( ( ( *handle )->handles = malloc( config.channels * sizeof( ISAR_LC3PLUS_ENC_HANDLE ) ) ) == NULL ) + { + ISAR_LC3PLUS_ENC_Close( handle ); + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LC3plus wrapper handle\n" ); + } + + for ( i = 0; i < config.channels; ++i ) + { + ( *handle )->handles[i] = NULL; + } + ( *handle )->num_encs = config.channels; +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + num_lc3plus_media_times_per_ivas_frame = config.isar_frame_duration_us / config.lc3plus_frame_duration_us; + ( *handle )->fdl_request = s_fdl_request; + ( *handle )->num_ftds = config.channels * num_lc3plus_media_times_per_ivas_frame; + ( *handle )->frame_type_descriptors = malloc( ( *handle )->num_ftds * sizeof( LC3PLUS_RTP_FTD ) ); + if ( NULL == ( *handle )->frame_type_descriptors ) + { + ISAR_LC3PLUS_ENC_Close( handle ); + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LC3plus frame_type_descriptors\n" ); + } +#endif + + for ( int32_t iCh = 0; iCh < config.channels; iCh++ ) + { + if ( ( ( *handle )->handles[iCh] = malloc( encoder_size ) ) == NULL ) + { + ISAR_LC3PLUS_ENC_Close( handle ); + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LC3plus encoder\n" ); + } + +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + err = lc3plus_enc_init( ( *handle )->handles[iCh], config.samplerate, 1, config.high_res_mode_enabled, lfeChans ); +#else + err = lc3plus_enc_init( ( *handle )->handles[iCh], config.samplerate, 1, 0, lfeChans ); +#endif + if ( err != LC3PLUS_OK ) + { + ISAR_LC3PLUS_ENC_Close( handle ); + return IVAS_ERROR( ISAR_LC3PLUS_LC3plusErrToIvasErr( err ), "lc3plus_enc_init failed\n" ); + } + + err = lc3plus_enc_set_frame_dms( ( *handle )->handles[iCh], config.lc3plus_frame_duration_us / 100 ); + if ( err != LC3PLUS_OK ) + { + ISAR_LC3PLUS_ENC_Close( handle ); + return IVAS_ERROR( ISAR_LC3PLUS_LC3plusErrToIvasErr( err ), "lc3plus_enc_set_frame_dms failed\n" ); + } +#ifndef ISAR_BITSTREAM_UPDATE_LC3PLUS + err = lc3plus_enc_set_bitrate( ( *handle )->handles[iCh], bitsPerSecondPerChannel ); + if ( err != LC3PLUS_OK ) + { + ISAR_LC3PLUS_ENC_Close( handle ); + return IVAS_ERROR( ISAR_LC3PLUS_LC3plusErrToIvasErr( err ), "lc3plus_enc_set_bitrate failed\n" ); + } +#endif + } + + if ( config.isar_frame_duration_us < config.lc3plus_frame_duration_us || config.isar_frame_duration_us % config.lc3plus_frame_duration_us != 0 ) + { + ISAR_LC3PLUS_ENC_Close( handle ); + return IVAS_ERROR( IVAS_ERR_NOT_IMPLEMENTED, "Current pcm_conversion_buffer sizing requires that lc3plus uses a shorter or equal frame duration than ivas\n" ); + } + +#ifndef ISAR_BITSTREAM_UPDATE_LC3PLUS + ( *handle )->config = config; +#endif + ( *handle )->pcm_conversion_buffer = malloc( sizeof( int16_t ) * config.samplerate * config.lc3plus_frame_duration_us / 1000000 ); + if ( NULL == ( *handle )->pcm_conversion_buffer ) + { + ISAR_LC3PLUS_ENC_Close( handle ); + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LC3plus encoder wrapper pcm_conversion_buffer\n" ); + } + +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + /* update FDI fields */ + for ( int32_t iMediaTime = 0; iMediaTime < num_lc3plus_media_times_per_ivas_frame; ++iMediaTime ) + { + for ( uint32_t iEnc = 0; iEnc < ( *handle )->num_encs; ++iEnc ) + { + int32_t ftd_index = iEnc + iMediaTime * ( *handle )->num_encs; +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + ( *handle )->frame_type_descriptors[ftd_index].frame_data_length = 0; /* will be set to the correct value in IVAS_LC3PLUS_ENC_SetBitrate */ +#else + lc3plus_num_bytes_per_frame = lc3plus_enc_get_num_bytes( ( *handle )->handles[iEnc] ); + if ( lc3plus_num_bytes_per_frame <= 0 ) + { + ISAR_LC3PLUS_ENC_Close( handle ); + return IVAS_ERROR( IVAS_ERR_INTERNAL, "lc3plus_enc_get_num_bytes reported invalid result failed\n" ); + } + ( *handle )->frame_type_descriptors[ftd_index].frame_data_length = lc3plus_num_bytes_per_frame; +#endif + if ( 0 != LC3PLUS_RTP_ftd_bwr_from_samplerate( &( *handle )->frame_type_descriptors[ftd_index].bwr, config.samplerate, config.high_res_mode_enabled ) ) + { + ISAR_LC3PLUS_ENC_Close( handle ); + return IVAS_ERROR( IVAS_ERR_INTERNAL, "LC3PLUS_RTP_ftd_bwr_from_samplerate failed\n" ); + } + if ( 0 != LC3PLUS_RTP_ftd_fdi_from_frame_duration_us( &( *handle )->frame_type_descriptors[ftd_index].fdi, config.lc3plus_frame_duration_us ) ) + { + ISAR_LC3PLUS_ENC_Close( handle ); + return IVAS_ERROR( IVAS_ERR_INTERNAL, "LC3PLUS_RTP_ftd_fdi_from_frame_duration_us failed\n" ); + } + ( *handle )->frame_type_descriptors[ftd_index].h = LC3PLUS_RTP_FTD_H_PRIMARY; + ( *handle )->frame_type_descriptors[ftd_index].frame_data = NULL; + + /* The FTDs in the ToC are included in the following order: + * 1) First the FTD for the first channel of the first FDB (oldest frame) + * 2) Then the FTDs for the remaining channels for the first FDB in increasing CC order + * 3) Then the FTD for the first channel of the second FDB + * 4) Then the FTDs for the remaining channels for the second FDB + * 5) Etc. to the last FDB */ + is_last_media_time = num_lc3plus_media_times_per_ivas_frame - 1 == iMediaTime; + is_last_channel = ( *handle )->num_encs - 1 == iEnc; + if ( is_last_media_time && is_last_channel ) + { + ( *handle )->frame_type_descriptors[ftd_index].fc = LC3PLUS_RTP_FTD_FC_LAST_OVERALL; + } + else if ( !is_last_media_time && is_last_channel ) + { + ( *handle )->frame_type_descriptors[ftd_index].fc = LC3PLUS_RTP_FTD_FC_LAST_IN_MEDIATIME; + } + else + { + ( *handle )->frame_type_descriptors[ftd_index].fc = LC3PLUS_RTP_FTD_FC_SUBSEQUENT_CHANNEL; + } + } + } + +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + ivas_err = IVAS_LC3PLUS_ENC_SetBitrate( *handle, bitsPerSecond ); + if ( ivas_err != IVAS_ERR_OK ) + { + ISAR_LC3PLUS_ENC_Close( handle ); + return ivas_err; + } +#endif +#endif + scratch_size = lc3plus_enc_get_scratch_size( ( *handle )->handles[0] ); + ( *handle )->scratch = malloc( sizeof( uint8_t ) * scratch_size ); + IF( NULL == ( *handle )->scratch ) + { + ISAR_LC3PLUS_ENC_Close( handle ); + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LC3plus encoder wrapper scratch\n" ); + } + + return IVAS_ERR_OK; +} + +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS +/*-------------------------------------------------------------------* + * Function IVAS_LC3PLUS_ENC_SetBitrate() + * + * + *-------------------------------------------------------------------*/ + +ivas_error IVAS_LC3PLUS_ENC_SetBitrate( + ISAR_LC3PLUS_ENC_HANDLE handle, /* o : LC3plus encoder handle */ + const uint32_t bitsPerSecond /* i : new target bit rate */ +) +{ + int32_t numLc3plusMediaTimesPerIvasFrame; + int32_t lc3plus_num_bytes_per_frame; + int32_t availableOctetsPerIsarFrame; + int32_t actualOctetsPerFrame; + LC3PLUS_Error err; + int32_t iFtd; + int32_t fdrLength; + int32_t lc3plusPacketRate; + int32_t numSubframes; + int32_t minPayloadOverhead; + int32_t targetLc3PlusBitratePerChannel; + int32_t targetLc3PlusOctetCount; + int32_t lc3plusFdlLength; + + if ( NULL == handle ) + { + return IVAS_ERROR( IVAS_ERR_UNEXPECTED_NULL_POINTER, "LC3PLUS_Enc_Wrap_Handle is NULL\n" ); + } + + availableOctetsPerIsarFrame = bitsPerSecond / ( 1000000 / handle->config.isar_frame_duration_us ) / 8; + lc3plusPacketRate = 1000 * 1000 / handle->config.lc3plus_frame_duration_us; + numLc3plusMediaTimesPerIvasFrame = handle->config.isar_frame_duration_us / handle->config.lc3plus_frame_duration_us; + numSubframes = numLc3plusMediaTimesPerIvasFrame * handle->config.channels; + + /* subtract minimum required payload bytes & calculate a first per-channel target bit rate */ + if ( LC3PLUS_RTP_frame_data_length_get_size( &fdrLength, s_fdl_request ) != LC3PLUS_RTP_ERR_NO_ERROR ) + { + return IVAS_ERROR( IVAS_ERR_INTERNAL, "LC3PLUS_RTP_frame_data_length_get_size failed\n" ); + } + minPayloadOverhead = fdrLength + ( numSubframes * LC3PLUS_RTP_FTD_MIN_SIZE ); + targetLc3PlusBitratePerChannel = ( availableOctetsPerIsarFrame - minPayloadOverhead ) / handle->config.channels * 8 * lc3plusPacketRate / numLc3plusMediaTimesPerIvasFrame; +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + if ( targetLc3PlusBitratePerChannel <= 0 ) + { + return IVAS_ERROR( IVAS_ERR_LC3PLUS_INVALID_BITRATE, "available LC3plus bitrate <= 0\n" ); + } +#endif + targetLc3PlusBitratePerChannel = limit_per_channel_bitrate( handle->config, targetLc3PlusBitratePerChannel ); + targetLc3PlusOctetCount = targetLc3PlusBitratePerChannel / 8 / lc3plusPacketRate; + /* check resulting octet count. If it requires larger than 1-byte length fields, decrease the bitrate by enough to make room for the additional length field */ + if ( LC3PLUS_RTP_frame_data_length_get_size( &lc3plusFdlLength, targetLc3PlusOctetCount ) != LC3PLUS_RTP_ERR_NO_ERROR ) + { + return IVAS_ERROR( IVAS_ERR_INTERNAL, "LC3PLUS_RTP_frame_data_length_get_size failed\n" ); + } + if ( lc3plusFdlLength != LC3PLUS_RTP_FDL_MIN_LENGTH ) + { + /* reduce bitrate to allow for the required fdl field */ + targetLc3PlusBitratePerChannel = ( targetLc3PlusOctetCount - ( lc3plusFdlLength - LC3PLUS_RTP_FDL_MIN_LENGTH ) ) / handle->config.channels * 8 * lc3plusPacketRate; + } + + for ( int32_t iCh = 0; iCh < handle->config.channels; iCh++ ) + { + err = lc3plus_enc_set_bitrate( handle->handles[iCh], targetLc3PlusBitratePerChannel ); + if ( err != LC3PLUS_OK ) + { + return IVAS_ERROR( ISAR_LC3PLUS_LC3plusErrToIvasErr( err ), "lc3plus_enc_set_bitrate failed\n" ); + } + } + + // update FTD settings after bitrate change + for ( int32_t iMediaTime = 0; iMediaTime < numLc3plusMediaTimesPerIvasFrame; ++iMediaTime ) + { + for ( uint32_t iEnc = 0; iEnc < handle->num_encs; ++iEnc ) + { + iFtd = iEnc + iMediaTime * handle->num_encs; + lc3plus_num_bytes_per_frame = lc3plus_enc_get_num_bytes( handle->handles[iEnc] ); + if ( lc3plus_num_bytes_per_frame <= 0 ) + { + return IVAS_ERROR( IVAS_ERR_INTERNAL, "lc3plus_enc_get_num_bytes reported invalid result failed\n" ); + } + handle->frame_type_descriptors[iFtd].frame_data_length = lc3plus_num_bytes_per_frame; + } + } + + // TODO: remove sanity checks? + if ( ISAR_LC3PLUS_ENC_GetOutputBitstreamSize( handle, &actualOctetsPerFrame ) != IVAS_ERR_OK ) + { + return IVAS_ERROR( IVAS_ERR_INTERNAL, "ISAR_LC3PLUS_ENC_GetOutputBitstreamSize failed\n" ); + } + if ( actualOctetsPerFrame > availableOctetsPerIsarFrame ) + { + return IVAS_ERROR( IVAS_ERR_INTERNAL, "Bitrate reduction logic failed\n" ); + } + return IVAS_ERR_OK; +} +#endif + + +/*-------------------------------------------------------------------* + * Function ISAR_LC3PLUS_ENC_GetDelay() + * + * + *-------------------------------------------------------------------*/ + +ivas_error ISAR_LC3PLUS_ENC_GetDelay( + ISAR_LC3PLUS_ENC_HANDLE handle, /* i : LC3plus encoder handle */ + int32_t *delayInSamples /* o : encoder delay in number of samples per channel */ +) +{ + int32_t tmpDelayInSamples; + + if ( NULL == handle ) + { + return IVAS_ERROR( IVAS_ERR_UNEXPECTED_NULL_POINTER, "LC3PLUS_Enc_Wrap_Handle is NULL\n" ); + } + if ( NULL == delayInSamples ) + { + return IVAS_ERROR( IVAS_ERR_UNEXPECTED_NULL_POINTER, "delayInSamples is NULL\n" ); + } + + *delayInSamples = 0; + /* sanity check whether all encoders are actually configured identically */ + for ( uint32_t iEnc = 0; iEnc < handle->num_encs; iEnc++ ) + { + if ( NULL == handle->handles[iEnc] ) + { + return IVAS_ERROR( IVAS_ERR_UNEXPECTED_NULL_POINTER, "LC3plus encoder handle is NULL\n" ); + } + + tmpDelayInSamples = lc3plus_enc_get_delay( handle->handles[iEnc] ); + if ( 0 != *delayInSamples && tmpDelayInSamples != *delayInSamples ) + { + return IVAS_ERROR( IVAS_ERR_INTERNAL, "Not all mono LC3plus encoders are configured identically\n" ); + } + *delayInSamples = tmpDelayInSamples; + } + + return IVAS_ERR_OK; +} + + +/*-------------------------------------------------------------------* + * Function ISAR_LC3PLUS_ENC_GetOutputBitstreamSize() + * + * + *-------------------------------------------------------------------*/ + +ivas_error ISAR_LC3PLUS_ENC_GetOutputBitstreamSize( + ISAR_LC3PLUS_ENC_HANDLE handle, /* i : LC3plus encoder handle */ + Word32 *bsSize /* o : size of each bitstream frame in bytes */ +) +{ +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + LC3PLUS_RTP_ERR rtp_err; + int32_t num_lc3plus_media_times_per_ivas_frame; + int32_t iMediaTime; + int32_t ftd_frame_data_length_size, lc3plus_frame_data_length; + int32_t ftd_index; +#else + int32_t bitstreamSizeMultiplier; +#endif + if ( NULL == handle ) + { + return IVAS_ERROR( IVAS_ERR_UNEXPECTED_NULL_POINTER, "LC3PLUS_Enc_Wrap_Handle is NULL\n" ); + } + if ( NULL == bsSize ) + { + return IVAS_ERROR( IVAS_ERR_UNEXPECTED_NULL_POINTER, "bsSize is NULL\n" ); + } + +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + if ( 0 == handle->config.lc3plus_frame_duration_us ) + { + return IVAS_ERROR( IVAS_ERR_INIT_ERROR, "lc3plus_frame_duration_us is 0\n" ); + } + if ( handle->config.isar_frame_duration_us % handle->config.lc3plus_frame_duration_us != 0 ) + { + return IVAS_ERROR( IVAS_ERR_NOT_IMPLEMENTED, "isar_frame_duration_us must be equal or multiple of lc3plus_frame_duration_us \n" ); + } + + num_lc3plus_media_times_per_ivas_frame = handle->config.isar_frame_duration_us / handle->config.lc3plus_frame_duration_us; +#endif + *bsSize = 0; +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + int32_t fdl_request_length; + rtp_err = LC3PLUS_RTP_frame_data_length_get_size( &fdl_request_length, handle->fdl_request ); + if ( rtp_err != LC3PLUS_RTP_ERR_NO_ERROR ) + { + return IVAS_ERROR( IVAS_ERR_WRONG_PARAMS, "Invalid LC3plus frame_data_length request\n" ); + } + *bsSize += fdl_request_length; +#endif + for ( uint32_t iEnc = 0; iEnc < handle->num_encs; iEnc++ ) + { + if ( NULL == handle->handles[iEnc] ) + { + return IVAS_ERROR( IVAS_ERR_UNEXPECTED_NULL_POINTER, "LC3plus encoder handle is NULL\n" ); + } +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + lc3plus_frame_data_length = lc3plus_enc_get_num_bytes( handle->handles[iEnc] ); + for ( iMediaTime = 0; iMediaTime < num_lc3plus_media_times_per_ivas_frame; ++iMediaTime ) + { + ftd_index = iEnc + iMediaTime * handle->num_encs; + if ( lc3plus_frame_data_length != (int32_t) handle->frame_type_descriptors[ftd_index].frame_data_length ) + { + return IVAS_ERROR( IVAS_ERR_WRONG_PARAMS, "LC3plus FTD data not synchronised with encoder bitrate\n" ); + } + rtp_err = LC3PLUS_RTP_frame_data_length_get_size( &ftd_frame_data_length_size, handle->frame_type_descriptors[ftd_index].frame_data_length ); + if ( rtp_err != LC3PLUS_RTP_ERR_NO_ERROR ) + { + return IVAS_ERROR( IVAS_ERR_WRONG_PARAMS, "Invalid LC3plus frame_data_length\n" ); + } + *bsSize += LC3PLUS_RTP_FTD_LENGTH_EXCLUDING_FDL; + *bsSize += handle->frame_type_descriptors[ftd_index].frame_data_length; + *bsSize += ftd_frame_data_length_size; + } + } +#else + *bsSize += lc3plus_enc_get_num_bytes( handle->handles[iEnc] ); + } + + if ( handle->config.isar_frame_duration_us % handle->config.lc3plus_frame_duration_us != 0 ) + { + return IVAS_ERROR( IVAS_ERR_NOT_IMPLEMENTED, "isar_frame_duration_us must be equal or multiple of lc3plus_frame_duration_us \n" ); + } + bitstreamSizeMultiplier = handle->config.isar_frame_duration_us / handle->config.lc3plus_frame_duration_us; + + *bsSize *= bitstreamSizeMultiplier; +#endif + + return IVAS_ERR_OK; +} + + +/*-------------------------------------------------------------------* + * Function ISAR_LC3PLUS_ENC_Close() + * + * + *-------------------------------------------------------------------*/ + +void ISAR_LC3PLUS_ENC_Close( + ISAR_LC3PLUS_ENC_HANDLE *handle /* i/o: pointer to LC3plus encoder handle */ +) +{ + if ( NULL == handle || NULL == *handle ) + { + return; + } +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + if ( NULL != ( *handle )->frame_type_descriptors ) + { + free( ( *handle )->frame_type_descriptors ); + } +#endif + for ( uint32_t iEnc = 0; iEnc < ( *handle )->num_encs; iEnc++ ) + { + if ( NULL != ( *handle )->handles[iEnc] ) + { + free( ( *handle )->handles[iEnc] ); + } + } + if ( NULL != ( *handle )->pcm_conversion_buffer ) + { + free( ( *handle )->pcm_conversion_buffer ); + } + + if ( NULL != ( *handle )->scratch ) + { + free( ( *handle )->scratch ); + } + + free( ( *handle )->handles ); + free( *handle ); + + *handle = NULL; + + return; +} + + +/*-------------------------------------------------------------------* + * Function ISAR_LC3PLUS_ENC_Encode() + * + * + *-------------------------------------------------------------------*/ +ivas_error ISAR_LC3PLUS_ENC_Encode( + ISAR_LC3PLUS_ENC_HANDLE handle, /* i : LC3plus encoder handle */ + Word32 **pcm_in, /* i : pointer input samples */ +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + void *bitstream_out, /* o : pointer to bitstream frame */ + const Word32 bitstream_out_size, /* i : size of the bitstream_out buffer in bytes. Must be equal to ISAR_LC3PLUS_ENC_GetOutputBitstreamSize. */ +#else + void *bitstream_out /* o : pointer to bitstream frame */ +#endif + Word16 q_in[16] ) +{ +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + int32_t ftdIndex; + LC3PLUS_RTP_ERR rtpErr; + uint32_t num_media_times; +#else + uint32_t lc3framesPerIvasFrame; + uint8_t *bitstream_out_iter = bitstream_out; +#endif + uint32_t numSamplesPerLC3plusChannel; + int32_t ivasSampleIndex; + int32_t num_bytes = 0; + LC3PLUS_Error err; + + push_wmops( "ISAR_LC3PLUS_ENC_Encode" ); + + if ( NULL == handle ) + { + return IVAS_ERROR( IVAS_ERR_UNEXPECTED_NULL_POINTER, "LC3PLUS_Enc_Wrap_Handle is NULL\n" ); + } + if ( NULL == pcm_in ) + { + return IVAS_ERROR( IVAS_ERR_UNEXPECTED_NULL_POINTER, "pcm_in is NULL\n" ); + } + if ( NULL == bitstream_out ) + { + return IVAS_ERROR( IVAS_ERR_UNEXPECTED_NULL_POINTER, "bitstream_out is NULL\n" ); + } + + if ( handle->config.isar_frame_duration_us % handle->config.lc3plus_frame_duration_us != 0 ) + { + return IVAS_ERROR( IVAS_ERR_NOT_IMPLEMENTED, "isar_frame_duration_us must be equal or multiple of lc3plus_frame_duration_us \n" ); + } +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + num_media_times = handle->config.isar_frame_duration_us / handle->config.lc3plus_frame_duration_us; + numSamplesPerLC3plusChannel = handle->config.samplerate / ( 1000000 / handle->config.isar_frame_duration_us ) / num_media_times; + + size_t actual_size; + rtpErr = LC3PLUS_RTP_payload_serialize( bitstream_out, bitstream_out_size, &actual_size, s_fdl_request, handle->frame_type_descriptors, handle->num_ftds ); + if ( rtpErr != LC3PLUS_RTP_ERR_NO_ERROR ) + { + return IVAS_ERROR( IVAS_LC3PLUS_LC3plusRtpErrToIvasErr( rtpErr ), "LC3PLUS_RTP_payload_serialize failed\n" ); + } +#else + lc3framesPerIvasFrame = handle->config.isar_frame_duration_us / handle->config.lc3plus_frame_duration_us; + + numSamplesPerLC3plusChannel = handle->config.samplerate / ( 1000000 / handle->config.isar_frame_duration_us ) / lc3framesPerIvasFrame; +#endif + for ( uint32_t iEnc = 0; iEnc < handle->num_encs; iEnc++ ) + { +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + for ( uint32_t iMediaTime = 0; iMediaTime < num_media_times; iMediaTime++ ) +#else + for ( uint32_t iLc3plusFrame = 0; iLc3plusFrame < lc3framesPerIvasFrame; iLc3plusFrame++ ) +#endif + { + for ( uint32_t iSampleInt16 = 0; iSampleInt16 < numSamplesPerLC3plusChannel; iSampleInt16++ ) + { +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + ivasSampleIndex = iSampleInt16 + iMediaTime * numSamplesPerLC3plusChannel; +#else + ivasSampleIndex = iSampleInt16 + iLc3plusFrame * numSamplesPerLC3plusChannel; +#endif + handle->pcm_conversion_buffer[iSampleInt16] = (Word16) max( INT16_MIN, min( L_shr( pcm_in[iEnc][ivasSampleIndex], q_in[iEnc] ), INT16_MAX ) ); + } + +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + ftdIndex = iMediaTime * handle->num_encs + iEnc; +#endif + num_bytes = 0; + push_wmops( "lc3plus_enc16" ); +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + err = lc3plus_enc16( handle->handles[iEnc], &handle->pcm_conversion_buffer, handle->frame_type_descriptors[ftdIndex].frame_data, &num_bytes, handle->scratch ); +#else + err = lc3plus_enc16( handle->handles[iEnc], &handle->pcm_conversion_buffer, bitstream_out_iter, &num_bytes, NULL ); +#endif + pop_wmops(); + if ( err != LC3PLUS_OK ) + { + return IVAS_ERROR( ISAR_LC3PLUS_LC3plusErrToIvasErr( err ), "lc3plus_enc16 failed\n" ); + } + if ( 0 == num_bytes ) + { + return IVAS_ERROR( IVAS_ERR_INTERNAL, "lc3plus_enc16 did not produce output\n" ); + } +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + if ( num_bytes != (int32_t) handle->frame_type_descriptors[ftdIndex].frame_data_length ) + { + return IVAS_ERROR( IVAS_ERR_INTERNAL, "payload format and lc3plus enc bitrate are not aligned\n" ); + } +#else + + bitstream_out_iter += num_bytes; +#endif + } + } + + pop_wmops(); + + return IVAS_ERR_OK; +} +#endif /* SPLIT_REND_WITH_HEAD_ROT */ diff --git a/lib_isar/isar_lc3plus_enc.h b/lib_isar/isar_lc3plus_enc.h new file mode 100644 index 0000000000000000000000000000000000000000..6d0f47030d09b8594f25b73fea448eb725658f6a --- /dev/null +++ b/lib_isar/isar_lc3plus_enc.h @@ -0,0 +1,104 @@ +/****************************************************************************************************** + + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository. All Rights Reserved. + + This software is protected by copyright law and by international treaties. + The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository retain full ownership rights in their respective contributions in + the software. This notice grants no license of any kind, including but not limited to patent + license, nor is any license granted by implication, estoppel or otherwise. + + Contributors are required to enter into the IVAS codec Public Collaboration agreement before making + contributions. + + This software is provided "AS IS", without any express or implied warranties. The software is in the + development stage. It is intended exclusively for experts who have experience with such software and + solely for the purpose of inspection. All implied warranties of non-infringement, merchantability + and fitness for a particular purpose are hereby disclaimed and excluded. + + Any dispute, controversy or claim arising under or in relation to providing this software shall be + submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in + accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and + the United Nations Convention on Contracts on the International Sales of Goods. + +*******************************************************************************************************/ + +#ifndef ISAR_LC3PLUS_ENC_H +#define ISAR_LC3PLUS_ENC_H + +#include +#include "ivas_error.h" +#ifdef SPLIT_REND_WITH_HEAD_ROT +#include "lc3.h" +#include "isar_lc3plus_common.h" +#include "typedef.h" +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS +#include "isar_lc3plus_payload.h" +#endif + +/* encoder wrapper */ +typedef struct ISAR_LC3PLUS_ENC_HANDLE +{ + LC3PLUS_CONFIG config; + LC3PLUS_Enc **handles; + uint32_t num_encs; + int16_t *pcm_conversion_buffer; +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + LC3PLUS_RTP_FTD *frame_type_descriptors; + int32_t num_ftds; + LC3PLUS_RTP_FDL fdl_request; +#endif + uint8_t *scratch; +} * ISAR_LC3PLUS_ENC_HANDLE; + +ivas_error ISAR_LC3PLUS_ENC_Open( + const LC3PLUS_CONFIG config, /* i : encoder configuration */ +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + const uint32_t initialBitsPerSecond, /* i : initial target bit rate */ +#else + const uint32_t bitsPerSecond, /* i : bit rate */ +#endif + ISAR_LC3PLUS_ENC_HANDLE *handle /* o : LC3plus encoder handle */ +); + +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS +ivas_error IVAS_LC3PLUS_ENC_SetBitrate( + ISAR_LC3PLUS_ENC_HANDLE handle, /* o : LC3plus encoder handle */ + const uint32_t bitsPerSecond /* i : new target bit rate */ +); +#endif + +ivas_error ISAR_LC3PLUS_ENC_GetDelay( + ISAR_LC3PLUS_ENC_HANDLE handle, /* i : LC3plus encoder handle */ + int32_t *delayInSamples /* o : algorithmic delay of encoding and decoding in number of samples per channel */ +); + +ivas_error ISAR_LC3PLUS_ENC_GetOutputBitstreamSize( + ISAR_LC3PLUS_ENC_HANDLE handle, /* i : LC3plus encoder handle */ + int32_t *bsSize /* o : size of next bitstream frame in bytes */ +); + +void ISAR_LC3PLUS_ENC_Close( + ISAR_LC3PLUS_ENC_HANDLE *handle /* i/o: pointer to LC3plus encoder handle */ +); + +ivas_error ISAR_LC3PLUS_ENC_Encode( + ISAR_LC3PLUS_ENC_HANDLE handle, /* i : LC3plus encoder handle */ + Word32 **pcm_in, /* i : pointer input samples */ +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + void *bitstream_out, /* o : pointer to bitstream frame */ + const Word32 bitstream_out_size, /* i : size of the bitstream_out buffer in bytes. Must be equal to ISAR_LC3PLUS_ENC_GetOutputBitstreamSize. */ +#else + void *bitstream_out /* o : pointer to bitstream frame */ +#endif + Word16 q_in[16] ); +#endif + +#endif /* ISAR_LC3PLUS_ENC_H */ diff --git a/lib_isar/isar_lc3plus_payload.c b/lib_isar/isar_lc3plus_payload.c new file mode 100644 index 0000000000000000000000000000000000000000..cd053978d1ca7a5ffdc914a853e4e829e6be592f --- /dev/null +++ b/lib_isar/isar_lc3plus_payload.c @@ -0,0 +1,823 @@ +/****************************************************************************************************** + + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository. All Rights Reserved. + + This software is protected by copyright law and by international treaties. + The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository retain full ownership rights in their respective contributions in + the software. This notice grants no license of any kind, including but not limited to patent + license, nor is any license granted by implication, estoppel or otherwise. + + Contributors are required to enter into the IVAS codec Public Collaboration agreement before making + contributions. + + This software is provided "AS IS", without any express or implied warranties. The software is in the + development stage. It is intended exclusively for experts who have experience with such software and + solely for the purpose of inspection. All implied warranties of non-infringement, merchantability + and fitness for a particular purpose are hereby disclaimed and excluded. + + Any dispute, controversy or claim arising under or in relation to providing this software shall be + submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in + accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and + the United Nations Convention on Contracts on the International Sales of Goods. + +*******************************************************************************************************/ + +#include +#include +#include +#include "isar_lc3plus_payload.h" +#include "options.h" + +#ifdef SPLIT_REND_WITH_HEAD_ROT +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS +static LC3PLUS_RTP_ERR s_frame_duration_ms_from_fdi( int32_t *frame_duration_us, const LC3PLUS_RTP_FTD_FDI fdi ) +{ + if ( NULL == frame_duration_us ) + { + return LC3PLUS_RTP_ERR_NULL_PTR; + } + switch ( fdi ) + { + case LC3PLUS_RTP_FTD_FDI_2500_US: + *frame_duration_us = 2500; + break; + case LC3PLUS_RTP_FTD_FDI_5000_US: + *frame_duration_us = 5000; + break; + case LC3PLUS_RTP_FTD_FDI_10000_US: + *frame_duration_us = 10000; + break; + case LC3PLUS_RTP_FTD_FDI_RESERVED: + default: + return LC3PLUS_RTP_ERR_INVALID_PARAMETERS; + } + return LC3PLUS_RTP_ERR_NO_ERROR; +} + +static LC3PLUS_RTP_ERR s_sampling_rate_hz_from_bwr( int32_t *sample_rate_hz, const LC3PLUS_RTP_FTD_BWR bwr ) +{ + if ( NULL == sample_rate_hz ) + { + return LC3PLUS_RTP_ERR_NULL_PTR; + } + switch ( bwr ) + { + case LC3PLUS_RTP_FTD_BWR_NB: + *sample_rate_hz = 8000; + break; + case LC3PLUS_RTP_FTD_BWR_WB: + *sample_rate_hz = 16000; + break; + case LC3PLUS_RTP_FTD_BWR_SSWB: + *sample_rate_hz = 24000; + break; + case LC3PLUS_RTP_FTD_BWR_SWB: + *sample_rate_hz = 32000; + break; + case LC3PLUS_RTP_FTD_BWR_FBCD: + *sample_rate_hz = 44100; + break; + case LC3PLUS_RTP_FTD_BWR_FB: + *sample_rate_hz = 48000; + break; + case LC3PLUS_RTP_FTD_BWR_FBHR: + *sample_rate_hz = 48000; + break; + case LC3PLUS_RTP_FTD_BWR_UBHR: + *sample_rate_hz = 96000; + break; + default: + return LC3PLUS_RTP_ERR_INVALID_PARAMETERS; + } + return LC3PLUS_RTP_ERR_NO_ERROR; +} + +static LC3PLUS_RTP_ERR s_high_resolution_flag_from_bwr( int16_t *high_resolution_flag, const LC3PLUS_RTP_FTD_BWR bwr ) +{ + if ( NULL == high_resolution_flag ) + { + return LC3PLUS_RTP_ERR_NULL_PTR; + } + switch ( bwr ) + { + case LC3PLUS_RTP_FTD_BWR_NB: + *high_resolution_flag = 0; + break; + case LC3PLUS_RTP_FTD_BWR_WB: + *high_resolution_flag = 0; + break; + case LC3PLUS_RTP_FTD_BWR_SSWB: + *high_resolution_flag = 0; + break; + case LC3PLUS_RTP_FTD_BWR_SWB: + *high_resolution_flag = 0; + break; + case LC3PLUS_RTP_FTD_BWR_FBCD: + *high_resolution_flag = 0; + break; + case LC3PLUS_RTP_FTD_BWR_FB: + *high_resolution_flag = 0; + break; + case LC3PLUS_RTP_FTD_BWR_FBHR: + *high_resolution_flag = 1; + break; + case LC3PLUS_RTP_FTD_BWR_UBHR: + *high_resolution_flag = 1; + break; + default: + return LC3PLUS_RTP_ERR_INVALID_PARAMETERS; + } + return LC3PLUS_RTP_ERR_NO_ERROR; +} + +LC3PLUS_RTP_ERR LC3PLUS_RTP_frame_data_length_get_size( int32_t *length, const LC3PLUS_RTP_FDL frameDataLengthValue ) +{ + if ( frameDataLengthValue == LC3PLUS_RTP_FDL_NO_REQ_OR_NO_DATA || frameDataLengthValue == LC3PLUS_RTP_FDL_SPEECH_BAD || frameDataLengthValue == LC3PLUS_RTP_FDL_SPEECH_SID ) + { + *length = 1; + } + else if ( frameDataLengthValue >= LC3PLUS_RTP_FDL_LENGTH_1_MIN && frameDataLengthValue <= LC3PLUS_RTP_FDL_LENGTH_1_MAX ) + { + *length = 1; + } + else if ( frameDataLengthValue >= LC3PLUS_RTP_FDL_LENGTH_2_MIN && frameDataLengthValue <= LC3PLUS_RTP_FDL_LENGTH_2_MAX ) + { + *length = 2; + } + else if ( frameDataLengthValue >= LC3PLUS_RTP_FDL_LENGTH_3_MIN && frameDataLengthValue <= LC3PLUS_RTP_FDL_LENGTH_3_MAX ) + { + *length = 3; + } + else + { + return LC3PLUS_RTP_ERR_INVALID_PARAMETERS; + } + return LC3PLUS_RTP_ERR_NO_ERROR; +} + +static LC3PLUS_RTP_ERR s_frame_data_length_pack( const LC3PLUS_RTP_FDL frameDataLengthValue, uint8_t *dst ) +{ + int32_t frame_data_length_size; + LC3PLUS_RTP_ERR err; + + if ( NULL == dst ) + { + return LC3PLUS_RTP_ERR_NULL_PTR; + } + + err = LC3PLUS_RTP_frame_data_length_get_size( &frame_data_length_size, frameDataLengthValue ); + if ( err != LC3PLUS_RTP_ERR_NO_ERROR ) + { + return err; + } + if ( 1 == frame_data_length_size ) + { + *dst++ = frameDataLengthValue >> 0 & LC3PLUS_RTP_FDL_EXTENSION_VALUE; + } + else if ( 2 == frame_data_length_size ) + { + const int32_t frameDataLengthValueToWrite = frameDataLengthValue - LC3PLUS_RTP_FDL_EXTENSION_VALUE; + *dst++ = LC3PLUS_RTP_FDL_EXTENSION_VALUE; + *dst = frameDataLengthValueToWrite >> 0 & LC3PLUS_RTP_FDL_EXTENSION_VALUE; + } + else if ( 3 == frame_data_length_size ) + { + const int32_t frameDataLengthValueToWrite = frameDataLengthValue - ( 2 * LC3PLUS_RTP_FDL_EXTENSION_VALUE ); + *dst++ = LC3PLUS_RTP_FDL_EXTENSION_VALUE; + *dst++ = LC3PLUS_RTP_FDL_EXTENSION_VALUE; + *dst = frameDataLengthValueToWrite >> 0 & LC3PLUS_RTP_FDL_EXTENSION_VALUE; + } + return LC3PLUS_RTP_ERR_NO_ERROR; +} + +static int32_t s_get_size_from_fdl( const LC3PLUS_RTP_FDL fdl ) +{ + if ( fdl >= LC3PLUS_RTP_FDL_LENGTH_1_MIN && fdl <= LC3PLUS_RTP_FDL_LENGTH_3_MAX ) + { + return fdl; + } + return 0; +} + +static bool s_fdl_is_magic_value( const LC3PLUS_RTP_FDL fdl ) +{ + if ( fdl == LC3PLUS_RTP_FDL_NO_REQ_OR_NO_DATA || fdl == LC3PLUS_RTP_FDL_SPEECH_SID || fdl == LC3PLUS_RTP_FDL_SPEECH_BAD ) + { + return true; + } + return false; +} + +static bool s_fdl_value_is_valid_request( const LC3PLUS_RTP_FDL fdl_request ) +{ + /* LC3PLUS_RTP_FDL_SPEECH_SID && LC3PLUS_RTP_FDL_SPEECH_SID are not valid values for the FDL request */ + if ( fdl_request == LC3PLUS_RTP_FDL_NO_REQ_OR_NO_DATA || ( fdl_request >= LC3PLUS_RTP_FDL_LENGTH_1_MIN && fdl_request <= LC3PLUS_RTP_FDL_LENGTH_3_MAX ) ) + { + return true; + } + return false; +} + +static LC3PLUS_RTP_ERR s_frame_data_length_parse( LC3PLUS_RTP_FDL *frame_data_length_value, const uint8_t *src, const size_t remaining_capacity ) +{ + int32_t frame_data_length_size; + LC3PLUS_RTP_ERR err; + if ( NULL == src || NULL == frame_data_length_value || remaining_capacity < 1 ) + { + return LC3PLUS_RTP_ERR_NULL_PTR; + } + + if ( remaining_capacity > 2 && LC3PLUS_RTP_FDL_EXTENSION_VALUE == *src && LC3PLUS_RTP_FDL_EXTENSION_VALUE == *( src + 1 ) ) + { + *frame_data_length_value = *( src + 2 ) + 2 * LC3PLUS_RTP_FDL_EXTENSION_VALUE; + } + else if ( remaining_capacity > 1 && LC3PLUS_RTP_FDL_EXTENSION_VALUE == *src ) + { + *frame_data_length_value = *( src + 1 ) + 1 * LC3PLUS_RTP_FDL_EXTENSION_VALUE; + } + else if ( remaining_capacity > 0 ) + { + *frame_data_length_value = *src << 0; + } + else + { + return LC3PLUS_RTP_ERR_INVALID_BITSTREAM_SIZE; + } + + /* sanity check */ + err = LC3PLUS_RTP_frame_data_length_get_size( &frame_data_length_size, *frame_data_length_value ); + if ( err != LC3PLUS_RTP_ERR_NO_ERROR ) + { + return err; + } + return LC3PLUS_RTP_ERR_NO_ERROR; +} + +static LC3PLUS_RTP_ERR s_parse_ftd( const uint8_t *p_read, LC3PLUS_RTP_FTD *receiver_ftd, int32_t *num_bytes_read, const size_t remaining_capacity ) +{ + int32_t frame_data_block_size; + LC3PLUS_RTP_FDL fdl; + LC3PLUS_RTP_ERR err; + if ( NULL == p_read || NULL == receiver_ftd || NULL == num_bytes_read || remaining_capacity < LC3PLUS_RTP_FTD_MIN_SIZE ) + { + return LC3PLUS_RTP_ERR_NULL_PTR; + } + + *num_bytes_read = 0; + receiver_ftd->fc = 0; + receiver_ftd->fdi = 0; + receiver_ftd->bwr = 0; + receiver_ftd->h = 0; + receiver_ftd->fc |= *p_read & LC3PLUS_RTP_FTD_FC_MASK; + receiver_ftd->fdi |= ( *p_read & LC3PLUS_RTP_FTD_FDI_MASK ); + receiver_ftd->bwr |= ( *p_read & LC3PLUS_RTP_FTD_BWR_MASK ); + receiver_ftd->h |= ( *p_read & LC3PLUS_RTP_FTD_H_MASK ); + p_read++; + *num_bytes_read = 1; + + err = s_frame_data_length_parse( &fdl, p_read, remaining_capacity - *num_bytes_read ); + if ( LC3PLUS_RTP_ERR_NO_ERROR != err ) + { + return err; + } + frame_data_block_size = s_get_size_from_fdl( fdl ); + + receiver_ftd->frame_data_length = frame_data_block_size; + int32_t length_field_size; + err = LC3PLUS_RTP_frame_data_length_get_size( &length_field_size, receiver_ftd->frame_data_length ); + if ( LC3PLUS_RTP_ERR_NO_ERROR != err ) + { + return err; + } + *num_bytes_read += length_field_size; + return LC3PLUS_RTP_ERR_NO_ERROR; +} + +LC3PLUS_RTP_ERR LC3PLUS_RTP_payload_serialize( + uint8_t *serialized_buffer, + const size_t serialized_buffer_capacity, + size_t *packed_buffer_actual_size, + const LC3PLUS_RTP_FDL fdl_request, + LC3PLUS_RTP_FTD *sender_ftds, + const size_t sender_ftds_num ) +{ + LC3PLUS_RTP_ERR err; + uint8_t *p_write = serialized_buffer; + uint32_t i; + int32_t bytes_written = 0; + int32_t lc3plus_frame_size_sum; + uint8_t *p_frame_data; + int32_t fdl_request_length; + + if ( NULL == serialized_buffer || NULL == packed_buffer_actual_size || NULL == sender_ftds ) + { + return LC3PLUS_RTP_ERR_NULL_PTR; + } + + *packed_buffer_actual_size = 0; + err = LC3PLUS_RTP_frame_data_length_get_size( &fdl_request_length, fdl_request ); + if ( LC3PLUS_RTP_ERR_NO_ERROR != err ) + { + return err; + } + if ( !s_fdl_value_is_valid_request( fdl_request ) ) + { + return LC3PLUS_RTP_ERR_INVALID_FDL_REQUEST; + } + if ( (int32_t) serialized_buffer_capacity < bytes_written + fdl_request_length ) + { + return LC3PLUS_RTP_ERR_INVALID_BITSTREAM_SIZE; + } + err = s_frame_data_length_pack( fdl_request, p_write ); + if ( LC3PLUS_RTP_ERR_NO_ERROR != err ) + { + return err; + } + bytes_written += fdl_request_length; + p_write += bytes_written; + + for ( i = 0; i < sender_ftds_num; ++i ) + { + /* only the last ftd may have the LC3PLUS_RTP_FTD_FC_LAST_OVERALL value */ + if ( sender_ftds[i].fc == LC3PLUS_RTP_FTD_FC_LAST_OVERALL && i != ( sender_ftds_num - 1 ) ) + { + return LC3PLUS_RTP_ERR_INVALID_PARAMETERS; + } + /* the last ftd must have the LC3PLUS_RTP_FTD_FC_LAST_OVERALL value */ + if ( sender_ftds[i].fc != LC3PLUS_RTP_FTD_FC_LAST_OVERALL && i == ( sender_ftds_num - 1 ) ) + { + return LC3PLUS_RTP_ERR_INVALID_PARAMETERS; + } + if ( (int32_t) serialized_buffer_capacity < bytes_written + LC3PLUS_RTP_FTD_LENGTH_EXCLUDING_FDL ) + { + return LC3PLUS_RTP_ERR_INVALID_BITSTREAM_SIZE; + } + *p_write = 0x00; + *p_write |= LC3PLUS_RTP_FTD_FC_MASK & (uint8_t) sender_ftds[i].fc; + *p_write |= LC3PLUS_RTP_FTD_FDI_MASK & (uint8_t) sender_ftds[i].fdi; + *p_write |= LC3PLUS_RTP_FTD_BWR_MASK & (uint8_t) sender_ftds[i].bwr; + *p_write |= LC3PLUS_RTP_FTD_H_MASK & (uint8_t) sender_ftds[i].h; + p_write++; + bytes_written += LC3PLUS_RTP_FTD_LENGTH_EXCLUDING_FDL; + + int32_t fdl_length; + err = LC3PLUS_RTP_frame_data_length_get_size( &fdl_length, sender_ftds[i].frame_data_length ); + if ( LC3PLUS_RTP_ERR_NO_ERROR != err ) + { + return err; + } + if ( (int32_t) serialized_buffer_capacity < bytes_written + fdl_length ) + { + return LC3PLUS_RTP_ERR_INVALID_BITSTREAM_SIZE; + } + err = s_frame_data_length_pack( sender_ftds[i].frame_data_length, p_write ); + if ( LC3PLUS_RTP_ERR_NO_ERROR != err ) + { + return err; + } + p_write += fdl_length; + bytes_written += fdl_length; + } + + lc3plus_frame_size_sum = 0; + p_frame_data = serialized_buffer + bytes_written; + for ( i = 0; i < sender_ftds_num; ++i ) + { + sender_ftds[i].frame_data = p_frame_data; + p_frame_data += sender_ftds[i].frame_data_length; + lc3plus_frame_size_sum += sender_ftds[i].frame_data_length; + } + *packed_buffer_actual_size = bytes_written + lc3plus_frame_size_sum; + assert( *packed_buffer_actual_size <= serialized_buffer_capacity ); + return LC3PLUS_RTP_ERR_NO_ERROR; +} + +static LC3PLUS_RTP_ERR s_ftds_parse( + LC3PLUS_RTP_FTD *receiver_ftds, + const int32_t receiver_ftds_num_max, + int16_t *receiver_ftds_num, + uint8_t *serialized_buffer, + const size_t serialized_buffer_size ) +{ + int32_t diff; + uint8_t *p_read; + uint32_t ftds_offset_sum = 0; + int16_t i; + LC3PLUS_RTP_ERR error; + int32_t frame_offset_counter; + int32_t size; + + p_read = serialized_buffer; + if ( NULL == receiver_ftds || NULL == receiver_ftds_num || NULL == serialized_buffer ) + { + return LC3PLUS_RTP_ERR_NULL_PTR; + } + if ( 0 == serialized_buffer_size ) + { + return LC3PLUS_RTP_ERR_EMPTY_TOC; + } + if ( receiver_ftds_num_max <= 0 ) + { + return LC3PLUS_RTP_ERR_INVALID_PARAMETERS; + } + { + int32_t num_bytes_read_sum = 0; + const int32_t min_num_bytes_per_ftd = 2; + int16_t receiver_ftds_index = 0; + bool another_ftd = true; + int32_t num_bytes_read_per_ftd; + + while ( another_ftd ) + { + if ( (int32_t) serialized_buffer_size < min_num_bytes_per_ftd ) + { + return LC3PLUS_RTP_ERR_INVALID_BITSTREAM_SIZE; + } + if ( num_bytes_read_sum >= (int32_t) serialized_buffer_size - min_num_bytes_per_ftd ) + { + return LC3PLUS_RTP_ERR_INVALID_BITSTREAM_SIZE; + } + num_bytes_read_per_ftd = 0; + error = s_parse_ftd( p_read, &receiver_ftds[receiver_ftds_index], &num_bytes_read_per_ftd, serialized_buffer_size - num_bytes_read_sum ); + if ( LC3PLUS_RTP_ERR_NO_ERROR != error ) + { + return error; + } + p_read += num_bytes_read_per_ftd; + num_bytes_read_sum += num_bytes_read_per_ftd; + + if ( receiver_ftds[receiver_ftds_index].fc == LC3PLUS_RTP_FTD_FC_RESERVED ) + { + return LC3PLUS_RTP_ERR_INVALID_BITSTREAM; + } + else if ( receiver_ftds[receiver_ftds_index].fc == LC3PLUS_RTP_FTD_FC_LAST_OVERALL ) + { + another_ftd = false; + } + + if ( another_ftd ) + { + if ( receiver_ftds_index >= receiver_ftds_num_max ) + { + return LC3PLUS_RTP_ERR_NOT_ENOUGH_FTDS_ALLOCATED; + } + ( receiver_ftds_index )++; + } + } + *receiver_ftds_num = receiver_ftds_index + 1; + } + + /* set frame-data pointers into serialized_buffer */ + for ( i = 0; i < *receiver_ftds_num; ++i ) + { + error = LC3PLUS_RTP_frame_data_length_get_size( &size, receiver_ftds[i].frame_data_length ); + if ( error != LC3PLUS_RTP_ERR_NO_ERROR ) + { + return error; + } + ftds_offset_sum += LC3PLUS_RTP_FTD_LENGTH_EXCLUDING_FDL + size; + } + + frame_offset_counter = 0; + for ( i = 0; i < *receiver_ftds_num; ++i ) + { + if ( s_fdl_is_magic_value( receiver_ftds[i].frame_data_length ) ) + { + receiver_ftds[i].frame_data = NULL; + } + else + { + receiver_ftds[i].frame_data = serialized_buffer + ftds_offset_sum + frame_offset_counter; + frame_offset_counter += receiver_ftds[i].frame_data_length; + } + } + + if ( ftds_offset_sum + frame_offset_counter != serialized_buffer_size ) + { + /* parsed content & size n bytes of input buffer do not line up */ + /* if the buffer capacity is larger and the remaining bytes are zero, we don't treat this as an error since it's due to the IVAS-Split rendering zero padding */ + diff = serialized_buffer_size - ( ftds_offset_sum + frame_offset_counter ); + if ( diff < 0 ) + { + return LC3PLUS_RTP_ERR_INVALID_BITSTREAM_SIZE; + } + /* verify that all bytes are zero */ + p_read += frame_offset_counter; + for ( i = 0; i < diff; ++i ) + { + if ( *p_read != 0 ) + { + /* non-zero byte in padding region */ + return LC3PLUS_RTP_ERR_NONZERO_PADDING_BYTES; + } + p_read++; + } + } + return LC3PLUS_RTP_ERR_NO_ERROR; +} + +LC3PLUS_RTP_ERR LC3PLUS_RTP_payload_deserialize( + LC3PLUS_RTP_PAYLOAD *payload, + uint8_t *serialized_buffer, + const size_t serialized_buffer_size ) +{ + int32_t new_frame_duration_us; + int32_t new_sampling_rate_hz; + int16_t new_high_resolution_flag; + int16_t i = 0; + int16_t channel_id = 0; + int16_t media_time_id = 0; + const int16_t invalid_value = -1; + int16_t media_times_per_channel[LC3PLUS_RTP_PAYLOAD_MAX_NUM_CHANNELS]; + int16_t channels_per_media_time[LC3PLUS_RTP_PAYLOAD_MAX_NUM_MEDIA_TIMES]; + LC3PLUS_RTP_ERR err; + + if ( NULL == payload || NULL == serialized_buffer ) + { + return LC3PLUS_RTP_ERR_NULL_PTR; + } + if ( 0 == serialized_buffer_size ) + { + return LC3PLUS_RTP_ERR_INVALID_PARAMETERS; + } + + for ( media_time_id = 0; media_time_id < LC3PLUS_RTP_PAYLOAD_MAX_NUM_MEDIA_TIMES; ++media_time_id ) + { + channels_per_media_time[media_time_id] = invalid_value; + } + media_time_id = 0; + for ( channel_id = 0; channel_id < LC3PLUS_RTP_PAYLOAD_MAX_NUM_CHANNELS; ++channel_id ) + { + media_times_per_channel[channel_id] = invalid_value; + } + channel_id = 0; + + err = s_frame_data_length_parse( &payload->fdl_request, serialized_buffer, serialized_buffer_size ); + if ( LC3PLUS_RTP_ERR_NO_ERROR != err ) + { + return err; + } + int32_t fdl_request_length; + err = LC3PLUS_RTP_frame_data_length_get_size( &fdl_request_length, payload->fdl_request ); + if ( LC3PLUS_RTP_ERR_NO_ERROR != err ) + { + return err; + } + if ( !s_fdl_value_is_valid_request( payload->fdl_request ) ) + { + return LC3PLUS_RTP_ERR_INVALID_FDL_REQUEST; + } + + err = s_ftds_parse( payload->ftds, sizeof( payload->ftds ) / sizeof( LC3PLUS_RTP_FTD ), &payload->num_ftds, serialized_buffer + fdl_request_length, serialized_buffer_size - fdl_request_length ); + if ( LC3PLUS_RTP_ERR_NO_ERROR != err ) + { + return err; + } + if ( 0 == payload->num_ftds ) + { + return LC3PLUS_RTP_ERR_GENERIC_ERROR; + } + /* verify shared setting between all FTDs [samplerate, frame_duration, channel count] */ + + /* initialize on the first FTD, use this as reference */ + err = s_frame_duration_ms_from_fdi( &payload->frame_duration_us, payload->ftds[0].fdi ); + if ( LC3PLUS_RTP_ERR_NO_ERROR != err ) + { + return err; + } + err = s_sampling_rate_hz_from_bwr( &payload->sampling_rate_hz, payload->ftds[0].bwr ); + if ( LC3PLUS_RTP_ERR_NO_ERROR != err ) + { + return err; + } + err = s_high_resolution_flag_from_bwr( &payload->high_resolution_enabled, payload->ftds[0].bwr ); + if ( LC3PLUS_RTP_ERR_NO_ERROR != err ) + { + return err; + } + payload->num_channels = 0; + payload->num_media_times = 0; + for ( i = 0; i < payload->num_ftds; ++i ) + { + if ( payload->ftds[i].h != LC3PLUS_RTP_FTD_H_PRIMARY ) + { + /* not implemented */ + return LC3PLUS_RTP_ERR_NOT_IMPLEMENTED; + } + + err = s_frame_duration_ms_from_fdi( &new_frame_duration_us, payload->ftds[i].fdi ); + if ( LC3PLUS_RTP_ERR_NO_ERROR != err ) + { + return err; + } + if ( payload->frame_duration_us != new_frame_duration_us ) + { + /* mixed frame durations not supported */ + return LC3PLUS_RTP_ERR_UNSUPPORTED_CONFIGURATION; + } + + err = s_sampling_rate_hz_from_bwr( &new_sampling_rate_hz, payload->ftds[i].bwr ); + if ( LC3PLUS_RTP_ERR_NO_ERROR != err ) + { + return err; + } + if ( payload->sampling_rate_hz != new_sampling_rate_hz ) + { + /* mixed sampling frequencies not supported */ + return LC3PLUS_RTP_ERR_UNSUPPORTED_CONFIGURATION; + } + + + err = s_high_resolution_flag_from_bwr( &new_high_resolution_flag, payload->ftds[i].bwr ); + if ( LC3PLUS_RTP_ERR_NO_ERROR != err ) + { + return err; + } + if ( payload->high_resolution_enabled != new_high_resolution_flag ) + { + /* mixed high resolution mode not supported */ + return LC3PLUS_RTP_ERR_UNSUPPORTED_CONFIGURATION; + } + + switch ( payload->ftds[i].fc ) + { + case LC3PLUS_RTP_FTD_FC_LAST_OVERALL: + channels_per_media_time[media_time_id]++; + media_times_per_channel[channel_id]++; + channel_id = 0; + media_time_id = 0; + break; + case LC3PLUS_RTP_FTD_FC_SUBSEQUENT_CHANNEL: + media_times_per_channel[channel_id]++; + channels_per_media_time[media_time_id]++; + channel_id++; + break; + case LC3PLUS_RTP_FTD_FC_LAST_IN_MEDIATIME: + media_times_per_channel[channel_id]++; + channels_per_media_time[media_time_id]++; + channel_id = 0; + media_time_id++; + break; + case LC3PLUS_RTP_FTD_FC_RESERVED: + default: + return LC3PLUS_RTP_ERR_INVALID_BITSTREAM; + } + } + + { + int32_t valid_num_media_times_per_channel; + int32_t iCh; + /* check whether all channels exist for each media time */ + if ( media_times_per_channel[0] == invalid_value ) + { + return LC3PLUS_RTP_ERR_NOT_IMPLEMENTED; + } + valid_num_media_times_per_channel = media_times_per_channel[0]; + for ( iCh = 0; iCh < LC3PLUS_RTP_PAYLOAD_MAX_NUM_CHANNELS; ++iCh ) + { + if ( media_times_per_channel[iCh] == invalid_value ) + { + break; + } + if ( valid_num_media_times_per_channel != media_times_per_channel[iCh] ) + { + return LC3PLUS_RTP_ERR_NOT_IMPLEMENTED; + } + } + } + { + /* whether all media times exist for each channel */ + int32_t iMediaTime; + int32_t valid_num_channels_per_media_time; + if ( channels_per_media_time[0] == invalid_value ) + { + return LC3PLUS_RTP_ERR_NOT_IMPLEMENTED; + } + valid_num_channels_per_media_time = channels_per_media_time[0]; + for ( iMediaTime = 0; iMediaTime < LC3PLUS_RTP_PAYLOAD_MAX_NUM_MEDIA_TIMES; ++iMediaTime ) + { + if ( channels_per_media_time[iMediaTime] == invalid_value ) + { + break; + } + if ( valid_num_channels_per_media_time != channels_per_media_time[iMediaTime] ) + { + return LC3PLUS_RTP_ERR_NOT_IMPLEMENTED; + } + } + } + + /* convert zero-index to count */ + payload->num_channels = channels_per_media_time[0] + 1; + payload->num_media_times = media_times_per_channel[0] + 1; + + /* verify that all media times have the same number of channels, partial packets are not supported */ + if ( payload->num_ftds != payload->num_channels * payload->num_media_times ) + { + return LC3PLUS_RTP_ERR_GENERIC_ERROR; + } + return LC3PLUS_RTP_ERR_NO_ERROR; +} + +LC3PLUS_RTP_ERR LC3PLUS_RTP_ftd_bwr_from_samplerate( LC3PLUS_RTP_FTD_BWR *bwr, const int32_t sampling_rate, const int32_t high_res_enabled ) +{ + if ( NULL == bwr ) + { + return LC3PLUS_RTP_ERR_NULL_PTR; + } + switch ( sampling_rate ) + { + case 8000: + if ( high_res_enabled ) + { + return LC3PLUS_RTP_ERR_INVALID_PARAMETERS; + } + *bwr = LC3PLUS_RTP_FTD_BWR_NB; + return LC3PLUS_RTP_ERR_NO_ERROR; + case 16000: + if ( high_res_enabled ) + { + return LC3PLUS_RTP_ERR_INVALID_PARAMETERS; + } + *bwr = LC3PLUS_RTP_FTD_BWR_WB; + return LC3PLUS_RTP_ERR_NO_ERROR; + case 24000: + if ( high_res_enabled ) + { + return LC3PLUS_RTP_ERR_INVALID_PARAMETERS; + } + *bwr = LC3PLUS_RTP_FTD_BWR_SSWB; + return LC3PLUS_RTP_ERR_NO_ERROR; + case 32000: + if ( high_res_enabled ) + { + return LC3PLUS_RTP_ERR_INVALID_PARAMETERS; + } + *bwr = LC3PLUS_RTP_FTD_BWR_SWB; + return LC3PLUS_RTP_ERR_NO_ERROR; + case 44100: + if ( high_res_enabled ) + { + return LC3PLUS_RTP_ERR_INVALID_PARAMETERS; + } + *bwr = LC3PLUS_RTP_FTD_BWR_FBCD; + return LC3PLUS_RTP_ERR_NO_ERROR; + case 48000: + if ( 0 == high_res_enabled ) + { + *bwr = LC3PLUS_RTP_FTD_BWR_FB; + return LC3PLUS_RTP_ERR_NO_ERROR; + } + else + { + *bwr = LC3PLUS_RTP_FTD_BWR_FBHR; + return LC3PLUS_RTP_ERR_NO_ERROR; + } + case 96000: + if ( 0 == high_res_enabled ) + { + return LC3PLUS_RTP_ERR_INVALID_PARAMETERS; + } + *bwr = LC3PLUS_RTP_FTD_BWR_UBHR; + return LC3PLUS_RTP_ERR_NO_ERROR; + default: + break; + } + + return LC3PLUS_RTP_ERR_INVALID_PARAMETERS; +} + +LC3PLUS_RTP_ERR LC3PLUS_RTP_ftd_fdi_from_frame_duration_us( LC3PLUS_RTP_FTD_FDI *fdi, const int32_t frame_duration_us ) +{ + if ( NULL == fdi ) + { + return LC3PLUS_RTP_ERR_NULL_PTR; + } + switch ( frame_duration_us ) + { + case 2500: + *fdi = LC3PLUS_RTP_FTD_FDI_2500_US; + return LC3PLUS_RTP_ERR_NO_ERROR; + case 5000: + *fdi = LC3PLUS_RTP_FTD_FDI_5000_US; + return LC3PLUS_RTP_ERR_NO_ERROR; + case 10000: + *fdi = LC3PLUS_RTP_FTD_FDI_10000_US; + return LC3PLUS_RTP_ERR_NO_ERROR; + default: + break; + } + + return LC3PLUS_RTP_ERR_INVALID_PARAMETERS; +} + +#endif /* ISAR_BITSTREAM_UPDATE_LC3PLUS */ +#endif /* SPLIT_REND_WITH_HEAD_ROT */ diff --git a/lib_isar/isar_lc3plus_payload.h b/lib_isar/isar_lc3plus_payload.h new file mode 100644 index 0000000000000000000000000000000000000000..c225c91591685f0f55f9d906d9719cb89a9fd136 --- /dev/null +++ b/lib_isar/isar_lc3plus_payload.h @@ -0,0 +1,216 @@ +/****************************************************************************************************** + + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository. All Rights Reserved. + + This software is protected by copyright law and by international treaties. + The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository retain full ownership rights in their respective contributions in + the software. This notice grants no license of any kind, including but not limited to patent + license, nor is any license granted by implication, estoppel or otherwise. + + Contributors are required to enter into the IVAS codec Public Collaboration agreement before making + contributions. + + This software is provided "AS IS", without any express or implied warranties. The software is in the + development stage. It is intended exclusively for experts who have experience with such software and + solely for the purpose of inspection. All implied warranties of non-infringement, merchantability + and fitness for a particular purpose are hereby disclaimed and excluded. + + Any dispute, controversy or claim arising under or in relation to providing this software shall be + submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in + accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and + the United Nations Convention on Contracts on the International Sales of Goods. + +*******************************************************************************************************/ + +#ifndef ISAR_LC3PLUS_PAYLOAD_H +#define ISAR_LC3PLUS_PAYLOAD_H + +#include +#include +#include "lc3.h" +#include "options.h" + +#ifdef SPLIT_REND_WITH_HEAD_ROT +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + +/* Implementation of the "B.2.6 Table of contents" part of the RTP payload format + * for LC3plus as specified in ETSI TS 103 634. */ + +typedef enum LC3PLUS_RTP_ERR +{ + LC3PLUS_RTP_ERR_NO_ERROR, + LC3PLUS_RTP_ERR_NULL_PTR, + LC3PLUS_RTP_ERR_INVALID_PARAMETERS, + LC3PLUS_RTP_ERR_EMPTY_TOC, + LC3PLUS_RTP_ERR_NOT_IMPLEMENTED, + LC3PLUS_RTP_ERR_UNSUPPORTED_CONFIGURATION, + LC3PLUS_RTP_ERR_INVALID_BITSTREAM, + LC3PLUS_RTP_ERR_INVALID_BITSTREAM_SIZE, + LC3PLUS_RTP_ERR_NOT_ENOUGH_FTDS_ALLOCATED, + LC3PLUS_RTP_ERR_INVALID_FDL_REQUEST, + LC3PLUS_RTP_ERR_NONZERO_PADDING_BYTES, + LC3PLUS_RTP_ERR_GENERIC_ERROR +} LC3PLUS_RTP_ERR; + +/* + * The content of the FTD is shown in Figure B.6. + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * |FC |FDI| BWR |H| FDL1 | (FDL2) | (FDL3) | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + */ + +/* FC (2 bits): + * Frame and Channel (FC) indicator for subsequent frame data (if available). The meaning of the FC + * indicator is shown in Table B.2. The FC value defines the media time stamp (in integer increments + * of TSI) and the channel counter (CC, starting from 1 for the first channel) for the subsequent + * FTD (if available). */ +typedef enum LC3PLUS_RTP_FTD_FC +{ + LC3PLUS_RTP_FTD_FC_LAST_OVERALL = 0x00, /* Last FDL in ToC, no FDL follows the current FDL */ + LC3PLUS_RTP_FTD_FC_SUBSEQUENT_CHANNEL = 0x01, /* The next FDL is for the next channel for the same media time */ + LC3PLUS_RTP_FTD_FC_LAST_IN_MEDIATIME = 0x02, /* The next FDL is for first channel for next media time, channel counter is reset */ + LC3PLUS_RTP_FTD_FC_RESERVED = 0x03, /* Reserved */ +} LC3PLUS_RTP_FTD_FC; +#define LC3PLUS_RTP_FTD_FC_MASK 0x03 + +/* FDI (2 bits): + * Frame Duration Index, with encoding as shown in Table B.3. The FDI shall be static for a given + * payload type during the session. The FDI also dictates the TSI, needed for deriving the media + * time in case of more than one frame in the payload. */ +typedef enum LC3PLUS_RTP_FTD_FDI +{ + LC3PLUS_RTP_FTD_FDI_2500_US = 0x00, + LC3PLUS_RTP_FTD_FDI_5000_US = 0x04, + LC3PLUS_RTP_FTD_FDI_10000_US = 0x08, + LC3PLUS_RTP_FTD_FDI_RESERVED = 0x0C, +} LC3PLUS_RTP_FTD_FDI; +#define LC3PLUS_RTP_FTD_FDI_MASK 0x0C +LC3PLUS_RTP_ERR LC3PLUS_RTP_ftd_fdi_from_frame_duration_us( LC3PLUS_RTP_FTD_FDI *fdi, const int32_t frame_duration_us ); + +/* BWR (3 bits): + * Bandwidth and resolution combination used by the codec is jointly encoded into a bandwidth and + * resolution (BWR) index. The BWR index is encoded as shown in Table B.4. The BWR encoding is + * defined in Table B.4. The BWR index shall be static for a given payload type during the session. */ +typedef enum LC3PLUS_RTP_FTD_BWR +{ + LC3PLUS_RTP_FTD_BWR_NB = 0x00, + LC3PLUS_RTP_FTD_BWR_WB = 0x10, + LC3PLUS_RTP_FTD_BWR_SSWB = 0x20, + LC3PLUS_RTP_FTD_BWR_SWB = 0x30, + LC3PLUS_RTP_FTD_BWR_FBCD = 0x40, + LC3PLUS_RTP_FTD_BWR_FB = 0x50, + LC3PLUS_RTP_FTD_BWR_FBHR = 0x60, + LC3PLUS_RTP_FTD_BWR_UBHR = 0x70, +} LC3PLUS_RTP_FTD_BWR; +#define LC3PLUS_RTP_FTD_BWR_MASK 0x70 +LC3PLUS_RTP_ERR LC3PLUS_RTP_ftd_bwr_from_samplerate( LC3PLUS_RTP_FTD_BWR *bwr, const int32_t sampling_rate, const int32_t high_res_enabled ); + +/* H (1 bit): + * Indicates whether the corresponding frame is a normal frame (primary encoding) or a helper frame + * (secondary encoding). 0 indicates a primary frame, 1 indicates secondary (redundant) frame */ +typedef enum LC3PLUS_RTP_FTD_H +{ + LC3PLUS_RTP_FTD_H_PRIMARY = 0x00, + LC3PLUS_RTP_FTD_H_SECONDARY = 0x80, +} LC3PLUS_RTP_FTD_H; +#define LC3PLUS_RTP_FTD_H_MASK 0x80 + +typedef enum LC3PLUS_RTP_FDL +{ + LC3PLUS_RTP_FDL_NO_REQ_OR_NO_DATA = 0, + LC3PLUS_RTP_FDL_SPEECH_BAD = 1, + LC3PLUS_RTP_FDL_SPEECH_SID = 2, + LC3PLUS_RTP_FDL_RESERVED_MIN = 3, + LC3PLUS_RTP_FDL_RESERVED_MAX = 19, + LC3PLUS_RTP_FDL_LENGTH_1_MIN = 20, + LC3PLUS_RTP_FDL_LENGTH_1_MAX = 254, + LC3PLUS_RTP_FDL_LENGTH_2_MIN = 255, + LC3PLUS_RTP_FDL_LENGTH_2_MAX = 509, + LC3PLUS_RTP_FDL_LENGTH_3_MIN = 510, + LC3PLUS_RTP_FDL_LENGTH_3_MAX = 765 +} LC3PLUS_RTP_FDL; +/* value used to indicate that the Frame Data Length (FDL) extends to the next byte */ +#define LC3PLUS_RTP_FDL_EXTENSION_VALUE 0xFF + +typedef struct LC3PLUS_RTP_FTD +{ + LC3PLUS_RTP_FTD_FC fc; + LC3PLUS_RTP_FTD_FDI fdi; + LC3PLUS_RTP_FTD_BWR bwr; + LC3PLUS_RTP_FTD_H h; + uint8_t *frame_data; + LC3PLUS_RTP_FDL frame_data_length; +} LC3PLUS_RTP_FTD; +#define LC3PLUS_RTP_FTD_LENGTH_EXCLUDING_FDL 1 +#define LC3PLUS_RTP_FDL_MIN_LENGTH 1 +#define LC3PLUS_RTP_FTD_MIN_SIZE ( LC3PLUS_RTP_FTD_LENGTH_EXCLUDING_FDL + LC3PLUS_RTP_FDL_MIN_LENGTH ) + +/*! Serialize the sender_ftds structs and fdl_request into a linear compact buffer + * @param[out] serialized_buffer pointer to the start of the memory location where the serialized buffer will be written to + * @param[in] serialized_buffer_capacity capacity of the serialized_buffer in bytes + * @param[out] packed_buffer_actual_size actually used size of in bytes of the packed_buffer (<=serialized_buffer_capacity) + * @param[in] fdl_request frame data length request + * @param[in,out] sender_ftds the function will overwrite the frame_data pointer with the correct memory location in + * the packed_buffer (so it can subsequently be used as input for the LC3plus encode call) + * @param[in] sender_ftds_num number of sender_ftds + * @return LC3PLUS_RTP_ERR_NO_ERROR in case of success */ +LC3PLUS_RTP_ERR LC3PLUS_RTP_payload_serialize( + uint8_t *serialized_buffer, + const size_t serialized_buffer_capacity, + size_t *packed_buffer_actual_size, + const LC3PLUS_RTP_FDL fdl_request, + LC3PLUS_RTP_FTD *sender_ftds, + const size_t sender_ftds_num ); + +/*! Get size of the frame data length field for a certain frame data length value in bytes. + * @param[out] length size of the frame data length field in bytes [1,2,3] + * @param[in] frameDataLengthValue frame data length value + * @return LC3PLUS_RTP_ERR_NO_ERROR in case of success */ +LC3PLUS_RTP_ERR LC3PLUS_RTP_frame_data_length_get_size( int32_t *length, const LC3PLUS_RTP_FDL frameDataLengthValue ); + +#define LC3PLUS_RTP_PAYLOAD_MAX_NUM_CHANNELS 16 +#define LC3PLUS_RTP_PAYLOAD_MAX_NUM_MEDIA_TIMES 8 /* max ivas frame duration/min lc3plus frame duration: 20000/2500 */ +#define LC3PLUS_RTP_PAYLOAD_MAX_NUM_FTDS LC3PLUS_RTP_PAYLOAD_MAX_NUM_CHANNELS *LC3PLUS_RTP_PAYLOAD_MAX_NUM_MEDIA_TIMES + +typedef struct LC3PLUS_RTP_PAYLOAD_CONFIG +{ + /* frame duration in us shared among all FTDs */ + int32_t frame_duration_us; + /* high resolution flag shared among all FTDs */ + int16_t high_resolution_enabled; + /* sampling frequency shared among all FTDs */ + int32_t sampling_rate_hz; + /* number of individual channels in the payload */ + int16_t num_channels; + /* number of individual media times in the payload */ + int16_t num_media_times; + /* frame data length request */ + LC3PLUS_RTP_FDL fdl_request; + /* FTD data with pointer to raw frame data */ + LC3PLUS_RTP_FTD ftds[LC3PLUS_RTP_PAYLOAD_MAX_NUM_FTDS]; + /* actual number of ftds */ + int16_t num_ftds; +} LC3PLUS_RTP_PAYLOAD; + +/*! Deserialized a serialized buffer into a LC3PLUS_RTP_PAYLOAD struct + * @param payload pointer to target LC3PLUS_RTP_PAYLOAD object. Note: frame_data pointers in the struct will point to the respective memory locations in the serialized_buffer. + * @param serialized_buffer pointer to the start of the serialized input buffer + * @param serialized_buffer_size size of the serialized input buffer in bytes + * @return LC3PLUS_RTP_ERR_NO_ERROR in case of success */ +LC3PLUS_RTP_ERR LC3PLUS_RTP_payload_deserialize( + LC3PLUS_RTP_PAYLOAD *payload, + uint8_t *serialized_buffer, + const size_t serialized_buffer_size ); + +#endif /* ISAR_BITSTREAM_UPDATE_LC3PLUS */ +#endif /* #ifdef SPLIT_REND_WITH_HEAD_ROT */ +#endif /* ISAR_LC3PLUS_PAYLOAD_H */ diff --git a/lib_isar/isar_lcld_decoder.c b/lib_isar/isar_lcld_decoder.c new file mode 100644 index 0000000000000000000000000000000000000000..a64a12aead2cf63dcd1e648ce57fb1e6fd6cdfbf --- /dev/null +++ b/lib_isar/isar_lcld_decoder.c @@ -0,0 +1,1995 @@ +/****************************************************************************************************** + + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository. All Rights Reserved. + + This software is protected by copyright law and by international treaties. + The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository retain full ownership rights in their respective contributions in + the software. This notice grants no license of any kind, including but not limited to patent + license, nor is any license granted by implication, estoppel or otherwise. + + Contributors are required to enter into the IVAS codec Public Collaboration agreement before making + contributions. + + This software is provided "AS IS", without any express or implied warranties. The software is in the + development stage. It is intended exclusively for experts who have experience with such software and + solely for the purpose of inspection. All implied warranties of non-infringement, merchantability + and fitness for a particular purpose are hereby disclaimed and excluded. + + Any dispute, controversy or claim arising under or in relation to providing this software shall be + submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in + accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and + the United Nations Convention on Contracts on the International Sales of Goods. + +*******************************************************************************************************/ + +#include +#include "options.h" +#ifdef SPLIT_REND_WITH_HEAD_ROT +#include "isar_lcld_prot.h" +#include "isar_lcld_rom_tables.h" +#include "prot_fx.h" +#include +#include "isar_prot.h" +#include "wmc_auto.h" +#include "basop_util.h" +#include "prot_fx.h" +// #define DEBUG_WRITE +#include "debug.h" +#include "enh64.h" + +/*------------------------------------------------------------------------------------------* + * Local constants + *------------------------------------------------------------------------------------------*/ + +#define HUFF_READ_SIZE ( 4 ) + +/*------------------------------------------------------------------------------------------* + * Local structures + *------------------------------------------------------------------------------------------*/ + +typedef struct TableNode +{ + struct TableNode **ppoNextTable; + struct TableNode *poOrderedNext; + + Word32 *piCodeIndex; + Word32 *piDifference; + Word32 *piLength; +} TableNode; + +typedef struct TableList +{ + TableNode *poOrderedTop; + TableNode *poOrderedBottom; + +} TableList; + +struct LCLD_DECODER +{ + Word32 iSampleRate; + Word32 iChannels; + Word32 iNumBlocks; + + Word32 iNumBands; + const Word32 *piBandwidths; + + Word32 iMSMode; + Word32 *piMSFlags; + TableList *ptable_list; + UWord32 ( *c_apauiHuffDecTable_RAM[2 * ALLOC_TABLE_SIZE] )[HUFF_DEC_TABLE_SIZE]; + UWord32 num_decode_table[2 * ALLOC_TABLE_SIZE]; + Word32 piMSPredCoefs[MAX_BANDS]; + Word32 piLRPhaseDiffs[MAX_BANDS]; + Word32 iCommonGrouping; + Word32 *piNumGroups; + Word32 **ppiGroupLengths; + + Word32 ***pppiRMSEnvelope; + Word32 ***pppiSMR; + Word32 ***pppiExcitation; + Word32 ***pppiAlloc; + + Word32 iAllocOffset; + Word32 iRealOnlyOut; + + Word32 ***pppiLCLDSignReal; + Word32 ***pppiLCLDSignImag; + Word32 ***pppiQLCLDReal; + Word32 ***pppiQLCLDImag; + + PredictionDecoder *psPredictionDecoder; + + + NoiseGen *psNoiseGen; +}; + +static void CreateDecodeTable( LCLDDecoder *psLCLDDecoder, Word32 num, const UWord16 ( *ppuiEncTable )[2], Word32 iSize, Word32 iReadLength, UWord32 *iTables ); +static TableNode *CreateTableList( Word32 iReadLength ); +static void DeleteTableList( TableList *ptable_list, Word32 iTables ); +static TableNode *GetNextTable( Word32 iIndex, TableList *table_list, TableNode *poParent, Word32 iReadLength, UWord32 *iTablesCreated ); +static void AddcodeTableList( TableList *ptable_list, Word32 iLength, Word32 iCode, Word32 iCodeIndex, Word32 iReadLength, UWord32 *iTables ); +static void CompleteTables( LCLDDecoder *psLCLDDecoder, Word32 n, TableList *ptable_list, Word32 iReadLength, Word32 iTablesCreated ); + +static TableNode *CreateTableList( Word32 iReadLength ) +{ + Word32 n; + Word32 iMaxTables; + TableNode *ptable_top; + iMaxTables = L_shl( 1, (Word16) iReadLength ); + ptable_top = (TableNode *) malloc( sizeof( TableNode ) ); + ptable_top->ppoNextTable = + (TableNode **) malloc( iMaxTables * sizeof( TableNode * ) ); + ptable_top->piCodeIndex = (Word32 *) malloc( iMaxTables * sizeof( Word32 ) ); + ptable_top->piDifference = (Word32 *) malloc( iMaxTables * sizeof( Word32 ) ); + ptable_top->piLength = (Word32 *) malloc( iMaxTables * sizeof( Word32 ) ); + FOR( n = 0; n < iMaxTables; n++ ) + { + ptable_top->ppoNextTable[n] = NULL; + ptable_top->piCodeIndex[n] = 0xffff; + move32(); + ptable_top->piDifference[n] = 0; + move32(); + ptable_top->piLength[n] = 0; + move32(); + } + + return ptable_top; +} + +static void DeleteTableList( TableList *ptable_list, Word32 iTables ) +{ + + TableNode *node; + node = ptable_list->poOrderedTop; + + WHILE( ( iTables ) ) + { + + TableNode *node1 = node; + node = node1->poOrderedNext; + IF( node1->piCodeIndex != NULL ) + { + free( node1->piCodeIndex ); + } + IF( node1->piLength != NULL ) + { + free( node1->piLength ); + } + IF( node1->piDifference != NULL ) + { + free( node1->piDifference ); + } + IF( node1->ppoNextTable != NULL ) + { + free( node1->ppoNextTable ); + } + IF( node1 != NULL ) + { + free( node1 ); + } + iTables--; + } + IF( ptable_list != NULL ) + { + free( ptable_list ); + } +} + +static TableNode *GetNextTable( Word32 iIndex, TableList *table_list, TableNode *poParent, Word32 iReadLength, UWord32 *iTablesCreated ) +{ + TableNode *poNextNode; + + IF( poParent->ppoNextTable[iIndex] == NULL ) + { + poNextNode = CreateTableList( iReadLength ); + poParent->ppoNextTable[iIndex] = poNextNode; + poParent->piDifference[iIndex] = *iTablesCreated; /* this is a link to the next table rather than the difference */ + move32(); + table_list->poOrderedBottom->poOrderedNext = poNextNode; + table_list->poOrderedBottom = poNextNode; + + ( *iTablesCreated )++; + } + ELSE + { + poNextNode = poParent->ppoNextTable[iIndex]; + } + + return poNextNode; +} + +static void CompleteTables( LCLDDecoder *psLCLDDecoder, Word32 n, TableList *ptable_list, Word32 iReadLength, Word32 iTablesCreated ) +{ + + Word32 iMaxTables; + Word32 j; + TableNode *poNode; + + iMaxTables = L_shl( 1, (Word16) iReadLength ); + psLCLDDecoder->c_apauiHuffDecTable_RAM[n] = + malloc( iTablesCreated * iMaxTables * sizeof( UWord32 * ) ); + + poNode = ptable_list->poOrderedTop; + FOR( j = 0; j < iTablesCreated; j++ ) + { + Word32 k; + IF( poNode != NULL ) + { + FOR( k = 0; k < iMaxTables; k++ ) + { + UWord32 uiCode; + uiCode = poNode->piDifference[k]; + move32(); + uiCode = (UWord32) L_shl( (Word32) uiCode, 16 ); + uiCode = (UWord32) L_or( (Word32) uiCode, poNode->piCodeIndex[k] ); + psLCLDDecoder->c_apauiHuffDecTable_RAM[n][j][k] = uiCode; + move32(); + } + } + poNode = poNode->poOrderedNext; + } +} + +static void AddcodeTableList( TableList *ptable_list, Word32 iLength, Word32 iCode, Word32 iCodeIndex, Word32 iReadLength, UWord32 *iTables ) +{ + Word32 iDifference; + Word32 iMask; + Word32 iCurrentLength; + Word32 iIndex; + Word32 iCodeLow; + Word32 iCodeHigh; + + TableNode *poNode; + poNode = ptable_list->poOrderedTop; + iMask = L_sub( L_shl( 1, (Word16) iReadLength ), 1 ); + iCurrentLength = iLength; + move32(); + WHILE( GT_32( iCurrentLength, iReadLength ) ) + { + iDifference = L_sub( iCurrentLength, iReadLength ); + iIndex = L_shr( iCode, (Word16) iDifference ); + iIndex = L_and( iIndex, iMask ); + poNode = GetNextTable( iIndex, ptable_list, poNode, iReadLength, iTables ); + iCurrentLength = L_sub( iCurrentLength, iReadLength ); + } + + iMask = L_sub( L_shl( 1, (Word16) iCurrentLength ), 1 ); + iDifference = L_sub( iReadLength, iCurrentLength ); + iCodeLow = L_shl( L_and( iCode, iMask ), (Word16) iDifference ); + iMask = L_sub( L_shl( 1, (Word16) iDifference ), 1 ); + iCodeHigh = L_or( iCodeLow, iMask ); + FOR( iIndex = iCodeLow; iIndex <= iCodeHigh; iIndex++ ) + { + poNode->piCodeIndex[iIndex] = iCodeIndex; + move32(); + poNode->piDifference[iIndex] = iDifference; + move32(); + poNode->piLength[iIndex] = iLength; + move32(); + } +} + +static void CreateDecodeTable( LCLDDecoder *psLCLDDecoder, Word32 num, const UWord16 ( *ppuiEncTable )[2], Word32 iSize, Word32 iReadLength, UWord32 *iTables ) +{ + Word32 n; + UWord32 **ppsort_enc_table; + TableList *ptable_list; + ptable_list = (TableList *) malloc( sizeof( TableList ) ); + + ppsort_enc_table = (UWord32 **) malloc( iSize * sizeof( Word32 * ) ); + FOR( n = 0; n < iSize; n++ ) + { + ppsort_enc_table[n] = (UWord32 *) malloc( 3 * sizeof( Word32 ) ); + ppsort_enc_table[n][0] = (UWord32) ppuiEncTable[n][0]; + move32(); + ppsort_enc_table[n][1] = (UWord32) ppuiEncTable[n][1]; + move32(); + ppsort_enc_table[n][2] = (UWord32) n; + move32(); + } + + FOR( n = 0; n < iSize; n++ ) + { + UWord32 iMin; + Word32 iMinIndex; + Word32 k; + + iMin = ppsort_enc_table[n][0]; + move32(); + iMinIndex = n; + move32(); + FOR( k = n; k < iSize; k++ ) + { + IF( ppsort_enc_table[k][0] < iMin ) + { + iMin = ppsort_enc_table[k][0]; + move32(); + iMinIndex = k; + move32(); + } + } + + IF( NE_32( iMinIndex, n ) ) + { + UWord32 uiLength; + UWord32 uiCode; + UWord32 uiCodeIndex; + + uiLength = ppsort_enc_table[n][0]; + move32(); + uiCode = ppsort_enc_table[n][1]; + move32(); + uiCodeIndex = ppsort_enc_table[n][2]; + move32(); + + ppsort_enc_table[n][0] = ppsort_enc_table[iMinIndex][0]; + move32(); + ppsort_enc_table[n][1] = ppsort_enc_table[iMinIndex][1]; + move32(); + ppsort_enc_table[n][2] = ppsort_enc_table[iMinIndex][2]; + move32(); + + ppsort_enc_table[iMinIndex][0] = uiLength; + move32(); + ppsort_enc_table[iMinIndex][1] = uiCode; + move32(); + ppsort_enc_table[iMinIndex][2] = uiCodeIndex; + move32(); + } + } + ptable_list->poOrderedTop = CreateTableList( iReadLength ); + ptable_list->poOrderedBottom = ptable_list->poOrderedTop; + FOR( n = 0; n < iSize; n++ ) + { + Word32 iLength; + Word32 iCode; + Word32 iCodeIndex; + + iLength = ppsort_enc_table[n][0]; + move32(); + iCode = ppsort_enc_table[n][1]; + move32(); + iCodeIndex = ppsort_enc_table[n][2]; + move32(); + AddcodeTableList( ptable_list, iLength, iCode, iCodeIndex, iReadLength, + iTables ); + } + + CompleteTables( psLCLDDecoder, num, ptable_list, iReadLength, *iTables ); + DeleteTableList( ptable_list, *iTables ); + FOR( n = 0; n < iSize; n++ ) + { + free( ppsort_enc_table[n] ); + } + free( ppsort_enc_table ); +} + + +/*------------------------------------------------------------------------------------------* + * Function CreateLCLDDecoder() + * + * + *------------------------------------------------------------------------------------------*/ + +ivas_error CreateLCLDDecoder( + LCLDDecoder **psLCLDDecoder_out, + const Word32 iSampleRate, + const Word32 iChannels, + const Word32 iNumBlocks, + const Word32 iRealOnlyOut ) +{ + Word32 n; + Word32 read_length; + ivas_error error; + LCLDDecoder *psLCLDDecoder = NULL; + + 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; + move32(); + psLCLDDecoder->iChannels = iChannels; + psLCLDDecoder->iAllocOffset = 0; + psLCLDDecoder->iRealOnlyOut = iRealOnlyOut; + if ( iRealOnlyOut == 1 ) + { + psLCLDDecoder->iNumBlocks = L_shr( iNumBlocks, 1 ); + } + else + { + psLCLDDecoder->iNumBlocks = iNumBlocks; + } + psLCLDDecoder->iNumBands = 0; /* read from bitstream*/ + move32(); + psLCLDDecoder->piBandwidths = c_aiBandwidths48; + + psLCLDDecoder->iMSMode = 0; + move32(); + IF( ( psLCLDDecoder->piMSFlags = (Word32 *) malloc( MAX_BANDS * sizeof( Word32 ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); + } + FOR( n = 0; n < MAX_BANDS; n++ ) + { + psLCLDDecoder->piLRPhaseDiffs[n] = 0; + move32(); + psLCLDDecoder->piMSPredCoefs[n] = 0; + move32(); + } + + psLCLDDecoder->iCommonGrouping = 1; /* Common grouping always on only impacts stereo */ + move32(); + IF( ( psLCLDDecoder->piNumGroups = (Word32 *) malloc( psLCLDDecoder->iChannels * sizeof( Word32 ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); + } + IF( ( psLCLDDecoder->ppiGroupLengths = (Word32 **) malloc( psLCLDDecoder->iChannels * sizeof( Word32 * ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); + } + IF( ( psLCLDDecoder->pppiRMSEnvelope = (Word32 ***) malloc( psLCLDDecoder->iChannels * sizeof( Word32 ** ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); + } + IF( ( psLCLDDecoder->pppiSMR = (Word32 ***) malloc( psLCLDDecoder->iChannels * sizeof( Word32 ** ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); + } + IF( ( psLCLDDecoder->pppiExcitation = (Word32 ***) malloc( psLCLDDecoder->iChannels * sizeof( Word32 ** ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); + } + IF( ( psLCLDDecoder->pppiAlloc = (Word32 ***) malloc( psLCLDDecoder->iChannels * sizeof( Word32 ** ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); + } + + IF( ( psLCLDDecoder->pppiLCLDSignReal = (Word32 ***) malloc( psLCLDDecoder->iChannels * sizeof( Word32 ** ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); + } + IF( ( psLCLDDecoder->pppiLCLDSignImag = (Word32 ***) malloc( psLCLDDecoder->iChannels * sizeof( Word32 ** ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); + } + IF( ( psLCLDDecoder->pppiQLCLDReal = (Word32 ***) malloc( psLCLDDecoder->iChannels * sizeof( Word32 ** ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); + } + IF( ( psLCLDDecoder->pppiQLCLDImag = (Word32 ***) malloc( psLCLDDecoder->iChannels * sizeof( Word32 ** ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); + } + + FOR( n = 0; n < iChannels; n++ ) + { + Word16 k; + IF( ( psLCLDDecoder->ppiGroupLengths[n] = (Word32 *) malloc( LCLD_BLOCKS_PER_FRAME * sizeof( Word32 ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); + } + IF( ( psLCLDDecoder->pppiRMSEnvelope[n] = (Word32 **) malloc( LCLD_BLOCKS_PER_FRAME * sizeof( Word32 * ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); + } + IF( ( psLCLDDecoder->pppiSMR[n] = (Word32 **) malloc( LCLD_BLOCKS_PER_FRAME * sizeof( Word32 * ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); + } + IF( ( psLCLDDecoder->pppiExcitation[n] = (Word32 **) malloc( LCLD_BLOCKS_PER_FRAME * sizeof( Word32 * ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); + } + IF( ( psLCLDDecoder->pppiAlloc[n] = (Word32 **) malloc( LCLD_BLOCKS_PER_FRAME * sizeof( Word32 * ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); + } + + IF( ( psLCLDDecoder->pppiLCLDSignReal[n] = (Word32 **) malloc( LCLD_BLOCKS_PER_FRAME * sizeof( Word32 * ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); + } + IF( ( psLCLDDecoder->pppiLCLDSignImag[n] = (Word32 **) malloc( LCLD_BLOCKS_PER_FRAME * sizeof( Word32 * ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); + } + IF( ( psLCLDDecoder->pppiQLCLDReal[n] = (Word32 **) malloc( LCLD_BLOCKS_PER_FRAME * sizeof( Word32 * ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); + } + IF( ( psLCLDDecoder->pppiQLCLDImag[n] = (Word32 **) malloc( LCLD_BLOCKS_PER_FRAME * sizeof( Word32 * ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); + } + + FOR( k = 0; k < LCLD_BLOCKS_PER_FRAME; k++ ) + { + IF( ( psLCLDDecoder->pppiRMSEnvelope[n][k] = (Word32 *) malloc( MAX_BANDS * sizeof( Word32 ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); + } + IF( ( psLCLDDecoder->pppiSMR[n][k] = (Word32 *) malloc( MAX_BANDS * sizeof( Word32 ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); + } + IF( ( psLCLDDecoder->pppiExcitation[n][k] = (Word32 *) malloc( MAX_BANDS * sizeof( Word32 ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); + } + IF( ( psLCLDDecoder->pppiAlloc[n][k] = (Word32 *) malloc( MAX_BANDS * sizeof( Word32 ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); + } + + IF( ( psLCLDDecoder->pppiLCLDSignReal[n][k] = (Word32 *) malloc( LCLD_BANDS * sizeof( Word32 ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); + } + IF( ( psLCLDDecoder->pppiLCLDSignImag[n][k] = (Word32 *) malloc( LCLD_BANDS * sizeof( Word32 ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); + } + IF( ( psLCLDDecoder->pppiQLCLDReal[n][k] = (Word32 *) malloc( LCLD_BANDS * sizeof( Word32 ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); + } + IF( ( psLCLDDecoder->pppiQLCLDImag[n][k] = (Word32 *) malloc( LCLD_BANDS * sizeof( Word32 ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); + } + } + } + + read_length = READ_LENGTH; + move32(); + FOR( n = 0; n < shl( ALLOC_TABLE_SIZE, 1 ); n++ ) + { + psLCLDDecoder->num_decode_table[n] = 1; + move32(); + IF( c_apauiHuffEncTabels[n] != NULL ) + { + CreateDecodeTable( psLCLDDecoder, n, c_apauiHuffEncTabels[n], num_row_aauiLCLDHuff[n], read_length, &psLCLDDecoder->num_decode_table[n] ); + } + ELSE + { + psLCLDDecoder->c_apauiHuffDecTable_RAM[n] = NULL; + } + } + + IF( ( error = CreatePredictionDecoder_fx( &psLCLDDecoder->psPredictionDecoder, iChannels, psLCLDDecoder->iNumBlocks ) ) != IVAS_ERR_OK ) + { + return error; + } + psLCLDDecoder->psNoiseGen = NULL; /* CreateNoiseGen(); No noise fill for now*/ + *psLCLDDecoder_out = psLCLDDecoder; + + return IVAS_ERR_OK; +} + + +/*------------------------------------------------------------------------------------------* + * Function DeleteLCLDDecoder() + * + * + *------------------------------------------------------------------------------------------*/ + +void DeleteLCLDDecoder( LCLDDecoder *psLCLDDecoder ) +{ + Word32 k, n; + + IF( psLCLDDecoder != NULL ) + { + IF( psLCLDDecoder->piMSFlags != NULL ) + { + free( psLCLDDecoder->piMSFlags ); + } + + IF( psLCLDDecoder->piNumGroups != NULL ) + { + free( psLCLDDecoder->piNumGroups ); + } + + IF( psLCLDDecoder->ppiGroupLengths != NULL ) + { + FOR( n = 0; n < psLCLDDecoder->iChannels; n++ ) + { + free( psLCLDDecoder->ppiGroupLengths[n] ); + } + free( psLCLDDecoder->ppiGroupLengths ); + } + + IF( psLCLDDecoder->pppiRMSEnvelope != NULL ) + { + FOR( n = 0; n < psLCLDDecoder->iChannels; n++ ) + { + FOR( k = 0; k < LCLD_BLOCKS_PER_FRAME; k++ ) + { + free( psLCLDDecoder->pppiRMSEnvelope[n][k] ); + } + free( psLCLDDecoder->pppiRMSEnvelope[n] ); + } + free( psLCLDDecoder->pppiRMSEnvelope ); + } + + IF( psLCLDDecoder->pppiSMR != NULL ) + { + FOR( n = 0; n < psLCLDDecoder->iChannels; n++ ) + { + FOR( k = 0; k < LCLD_BLOCKS_PER_FRAME; k++ ) + { + free( psLCLDDecoder->pppiSMR[n][k] ); + } + free( psLCLDDecoder->pppiSMR[n] ); + } + free( psLCLDDecoder->pppiSMR ); + } + + IF( psLCLDDecoder->pppiExcitation != NULL ) + { + FOR( n = 0; n < psLCLDDecoder->iChannels; n++ ) + { + FOR( k = 0; k < LCLD_BLOCKS_PER_FRAME; k++ ) + { + free( psLCLDDecoder->pppiExcitation[n][k] ); + } + free( psLCLDDecoder->pppiExcitation[n] ); + } + free( psLCLDDecoder->pppiExcitation ); + } + + + IF( psLCLDDecoder->pppiAlloc != NULL ) + { + FOR( n = 0; n < psLCLDDecoder->iChannels; n++ ) + { + FOR( k = 0; k < LCLD_BLOCKS_PER_FRAME; k++ ) + { + free( psLCLDDecoder->pppiAlloc[n][k] ); + } + free( psLCLDDecoder->pppiAlloc[n] ); + } + free( psLCLDDecoder->pppiAlloc ); + } + + IF( psLCLDDecoder->pppiLCLDSignReal != NULL ) + { + FOR( n = 0; n < psLCLDDecoder->iChannels; n++ ) + { + FOR( k = 0; k < LCLD_BLOCKS_PER_FRAME; k++ ) + { + free( psLCLDDecoder->pppiLCLDSignReal[n][k] ); + } + free( psLCLDDecoder->pppiLCLDSignReal[n] ); + } + free( psLCLDDecoder->pppiLCLDSignReal ); + } + + IF( psLCLDDecoder->pppiLCLDSignImag != NULL ) + { + FOR( n = 0; n < psLCLDDecoder->iChannels; n++ ) + { + FOR( k = 0; k < LCLD_BLOCKS_PER_FRAME; k++ ) + { + free( psLCLDDecoder->pppiLCLDSignImag[n][k] ); + } + free( psLCLDDecoder->pppiLCLDSignImag[n] ); + } + free( psLCLDDecoder->pppiLCLDSignImag ); + } + + IF( psLCLDDecoder->pppiQLCLDReal != NULL ) + { + FOR( n = 0; n < psLCLDDecoder->iChannels; n++ ) + { + FOR( k = 0; k < LCLD_BLOCKS_PER_FRAME; k++ ) + { + free( psLCLDDecoder->pppiQLCLDReal[n][k] ); + } + free( psLCLDDecoder->pppiQLCLDReal[n] ); + } + free( psLCLDDecoder->pppiQLCLDReal ); + } + + IF( psLCLDDecoder->pppiQLCLDImag != NULL ) + { + FOR( n = 0; n < psLCLDDecoder->iChannels; n++ ) + { + FOR( k = 0; k < LCLD_BLOCKS_PER_FRAME; k++ ) + { + free( psLCLDDecoder->pppiQLCLDImag[n][k] ); + } + free( psLCLDDecoder->pppiQLCLDImag[n] ); + } + free( psLCLDDecoder->pppiQLCLDImag ); + } + + FOR( n = 0; n < ALLOC_TABLE_SIZE * 2; n++ ) + { + IF( psLCLDDecoder->num_decode_table[n] > 1 ) + { + + IF( psLCLDDecoder->c_apauiHuffDecTable_RAM[n] != NULL ) + { + free( psLCLDDecoder->c_apauiHuffDecTable_RAM[n] ); + } + } + } + + IF( psLCLDDecoder->psPredictionDecoder != NULL ) + { + DeletePredictionDecoder_fx( psLCLDDecoder->psPredictionDecoder ); + psLCLDDecoder->psPredictionDecoder = NULL; + } + + IF( psLCLDDecoder->psNoiseGen != NULL ) + { + DeleteNoiseGen( psLCLDDecoder->psNoiseGen ); + } + + free( psLCLDDecoder ); + } +} + +/*------------------------------------------------------------------------------------------* + * Local function declarations + * + * + *------------------------------------------------------------------------------------------*/ + +static void ApplyRMSEnvelope_fx( const int32_t iNumBands, const int32_t *piBandwidths, const int32_t iNumGroups, const int32_t *piGroupLengths, int32_t **ppiRMSEnvelope, Word32 **ppfReal_fx, Word32 **ppfImag_fx ); +static void ReplaceSign_fx( const Word32 iNumBlocks, const Word32 iNumLCLDBands, Word32 **ppiSignReal, Word32 **ppiSignImag, Word32 **ppfReal, Word32 **ppfImag, const Word32 *piBandwidths ); + +static void InvQuantizeSpectrum_fx( const Word32 iNumGroups, const Word32 *piGroupLengths, const Word32 iNumBands, const Word32 *piBandwidths, Word32 **ppiAlloc, Word32 **ppiQReal, Word32 **ppiQImag, Word32 **ppfReal, Word32 **ppfImag, NoiseGen *psNoiseGen ); +static void InvMSCoding_fx( const Word32 iNumBlocks, const Word32 iNumBands, const Word32 *piBandwidths, const Word32 iMSMode, const Word32 *piMSFlags, const Word32 *piLRPhaseDiffs, const Word32 *piMSPredCoefs, Word32 ***pppfReal, Word32 ***pppfImag ); +// static void InvMSCoding_fx( const int32_t iNumBlocks, const int32_t iNumBands, const int32_t *piBandwidths, const int32_t iMSMode, const int32_t *piMSFlags, const int32_t *piLRPhaseDiffs, const int32_t *piMSPredCoefs, float ***pppfReal, float ***pppfImag, Word32 ***pppfReal_fx, Word32 ***pppfImag_fx,Word16 exp ); + +static Word32 ReadHeaderInformation( Word32 *piNumBands, ISAR_SPLIT_REND_BITS_HANDLE pBits ); + +static Word32 ReadMSInformation( const Word32 iNumBands, Word32 *piMSMode, Word32 *piMSFlags, Word32 *piLRPhaseDiffs, Word32 *piMSPredCoefs, ISAR_SPLIT_REND_BITS_HANDLE pBits ); + +static Word32 ReadGroupInformation( const Word32 iChannels, const Word32 iNumBlocks, Word32 *piCommonGrouping, Word32 *piNumGroups, Word32 **ppiGroupLengths, ISAR_SPLIT_REND_BITS_HANDLE pBits ); + +static Word32 ReadHuff( const UWord32 ( *pauiHuffDecTable )[HUFF_DEC_TABLE_SIZE], Word32 *piSymbol, ISAR_SPLIT_REND_BITS_HANDLE pBits ); + +static Word32 ReadRMSEnvelope( const Word32 iChannels, const Word32 *piNumGroups, const Word32 iNumBands, Word32 ***pppiRMSEnvelope, ISAR_SPLIT_REND_BITS_HANDLE pBits ); + +static Word32 ReadAllocInformation( Word32 *piAllocOffset, ISAR_SPLIT_REND_BITS_HANDLE pBits ); + +// static int32_t +// ReadLCLDData( const int32_t iNumGroups, const int32_t *piGroupLengths, const int32_t iNumBands, const int32_t *piBandwidths, const int32_t *piPredEnable, int32_t **ppiAlloc, int32_t **ppiSignReal, int32_t **ppiSignImag, int32_t **ppiQReal, int32_t **ppiQImag, ISAR_SPLIT_REND_BITS_HANDLE pBits, uint32_t ( *c_apauiHuffDecTables[2 * ALLOC_TABLE_SIZE] )[HUFF_DEC_TABLE_SIZE] ); +static Word32 ReadLCLDData_fx( const Word32 *piNumGroups, Word32 **ppiGroupLengths, const Word32 iNumBands, const Word32 iNumChannels, Word32 **ppiDecodingUnresolved, Word32 **ppiPredEnable, const Word32 iNumSubSets, const Word32 iSubSetId, Word32 ***pppiAlloc, Word32 ***pppiSignReal, Word32 ***pppiSignImag, Word32 ***pppiQReal, Word32 ***pppiQImag, Word32 **ppiDecodingFailed, ISAR_SPLIT_REND_BITS_HANDLE pBits, UWord32 ( *c_apauiHuffDecTables[2 * ALLOC_TABLE_SIZE] )[HUFF_DEC_TABLE_SIZE] ); +static void ComputeAllocation( const Word32 iChannels, const Word32 *piNumGroups, const Word32 iNumBands, Word32 ***pppiSMR, const Word32 iAllocOffset, Word32 ***pppiAlloc ); + +void SetDecodingUnresolved( LCLDDecoder *psLCLDDecoder ) +{ + int32_t n, ch; + PredictionDecoder *psPredictionDecoder = psLCLDDecoder->psPredictionDecoder; + for ( ch = 0; ch < psPredictionDecoder->iChannels; ch++ ) + { + for ( n = 0; n < psPredictionDecoder->iNumSubSets; n++ ) + { + psPredictionDecoder->ppiDecodingUnresolved[ch][n] = 1; + psPredictionDecoder->ppiDecodingFailed[ch][n] = 1; + psPredictionDecoder->ppiDecodingFailedPrev[ch][n] = 1; + } + } +} + +int32_t AnyDecodingFailedPrev( LCLDDecoder *psLCLDDecoder ) +{ + int32_t n, ch; + PredictionDecoder *psPredictionDecoder = psLCLDDecoder->psPredictionDecoder; + for ( ch = 0; ch < psPredictionDecoder->iChannels; ch++ ) + { + for ( n = 0; n < psPredictionDecoder->iNumSubSets; n++ ) + { + if ( psPredictionDecoder->ppiDecodingFailedPrev[ch][n] == 1 ) + { + return 1; + } + } + } + return 0; +} + +int32_t AnyDecodingFailed( LCLDDecoder *psLCLDDecoder ) +{ + int32_t n, ch; + PredictionDecoder *psPredictionDecoder = psLCLDDecoder->psPredictionDecoder; + for ( ch = 0; ch < psPredictionDecoder->iChannels; ch++ ) + { + for ( n = 0; n < psPredictionDecoder->iNumSubSets; n++ ) + { + if ( psPredictionDecoder->ppiDecodingFailed[ch][n] == 1 ) + { + return 1; + } + } + } + return 0; +} + +int32_t **GetDecodingFailedStatus( LCLDDecoder *psLCLDDecoder ) +{ + return psLCLDDecoder->psPredictionDecoder->ppiDecodingFailed; +} + +int16_t GetNumSubSets( LCLDDecoder *psLCLDDecoder ) +{ + return (int16_t) psLCLDDecoder->psPredictionDecoder->iNumSubSets; +} + +int32_t **GetDecodingFailedPrevStatus( LCLDDecoder *psLCLDDecoder ) +{ + return psLCLDDecoder->psPredictionDecoder->ppiDecodingFailedPrev; +} + +static void UnpackReal_fx( + const Word32 iChannels, + const Word32 iNumBlocks, + Word32 ***pppfReal_fx, + Word32 ***pppfImag_fx ) +{ + Word32 ch, b, n; + FOR( ch = 0; ch < iChannels; ch++ ) + { + FOR( b = 0; b < LCLD_BANDS; b++ ) + { + Word32 iRealBlock = iNumBlocks - 1; + FOR( n = iNumBlocks / 2 - 1; n >= 0; n-- ) + { + pppfReal_fx[ch][iRealBlock][b] = L_shl( pppfImag_fx[ch][n][b], 1 ); + pppfReal_fx[ch][iRealBlock - 1][b] = L_shl( pppfReal_fx[ch][n][b], 1 ); + pppfImag_fx[ch][iRealBlock][b] = 0; + pppfImag_fx[ch][iRealBlock - 1][b] = 0; + iRealBlock -= 2; + } + } + } +} +/*------------------------------------------------------------------------------------------* + * Function DecodeLCLDFrame() + * + * + *------------------------------------------------------------------------------------------*/ + +Word32 DecodeLCLDFrame( + LCLDDecoder *psLCLDDecoder, + ISAR_SPLIT_REND_BITS_HANDLE pBits, + Word32 ***pppfLCLDReal_fx, + Word32 ***pppfLCLDImag_fx, + Word16 Q_in, + Word16 *Q_out ) +{ + Word32 k, n; + // FILE *ptr = fopen( "cldfb_real.txt", "ab+" ); + // FILE *ptr1 = fopen( "cldfb_imag.txt", "ab+" ); + ReadHeaderInformation( &psLCLDDecoder->iNumBands, pBits ); + + IF( EQ_32( psLCLDDecoder->iChannels, 2 ) ) + { + ReadMSInformation( psLCLDDecoder->iNumBands, &psLCLDDecoder->iMSMode, psLCLDDecoder->piMSFlags, psLCLDDecoder->piLRPhaseDiffs, psLCLDDecoder->piMSPredCoefs, pBits ); + } + + Word16 i, j; + + ReadPredictors_fx( psLCLDDecoder->psPredictionDecoder, pBits ); + + UpdateDecodingUnresolved( psLCLDDecoder->psPredictionDecoder ); + UpdateDecodingFailedStatus( psLCLDDecoder->psPredictionDecoder ); + + ReadGroupInformation( psLCLDDecoder->iChannels, psLCLDDecoder->iNumBlocks, &psLCLDDecoder->iCommonGrouping, psLCLDDecoder->piNumGroups, psLCLDDecoder->ppiGroupLengths, pBits ); + + ReadRMSEnvelope( psLCLDDecoder->iChannels, (const Word32 *) psLCLDDecoder->piNumGroups, psLCLDDecoder->iNumBands, psLCLDDecoder->pppiRMSEnvelope, pBits ); + + + ReadAllocInformation( &psLCLDDecoder->iAllocOffset, pBits ); + + IF( EQ_32( psLCLDDecoder->iChannels, 2 ) && EQ_32( psLCLDDecoder->iCommonGrouping, 1 ) ) + { /* MS Mode? */ + FOR( k = 0; k < psLCLDDecoder->piNumGroups[0]; k++ ) + { + PerceptualModelStereo_fx( psLCLDDecoder->iNumBands, psLCLDDecoder->piMSFlags, + psLCLDDecoder->pppiRMSEnvelope[0][k], + psLCLDDecoder->pppiRMSEnvelope[1][k], + psLCLDDecoder->pppiExcitation[0][k], + psLCLDDecoder->pppiExcitation[1][k], + psLCLDDecoder->pppiSMR[0][k], + psLCLDDecoder->pppiSMR[1][k] ); + } + } + ELSE + { + FOR( n = 0; n < psLCLDDecoder->iChannels; n++ ) + { /* This will be updated to support multiple sample rates*/ + FOR( k = 0; k < psLCLDDecoder->piNumGroups[n]; k++ ) + { + PerceptualModel_fx( (Word16) psLCLDDecoder->iNumBands, psLCLDDecoder->pppiRMSEnvelope[n][k], psLCLDDecoder->pppiExcitation[n][k], psLCLDDecoder->pppiSMR[n][k] ); + } + } + } + + ComputeAllocation( psLCLDDecoder->iChannels, (const Word32 *) psLCLDDecoder->piNumGroups, psLCLDDecoder->iNumBands, psLCLDDecoder->pppiSMR, psLCLDDecoder->iAllocOffset, psLCLDDecoder->pppiAlloc ); + + ReadLCLDData_fx( + psLCLDDecoder->piNumGroups, + psLCLDDecoder->ppiGroupLengths, + psLCLDDecoder->iNumBands, + psLCLDDecoder->iChannels, + psLCLDDecoder->psPredictionDecoder->ppiDecodingUnresolved, + psLCLDDecoder->psPredictionDecoder->ppiPredBandEnable, + psLCLDDecoder->psPredictionDecoder->iNumSubSets, + psLCLDDecoder->psPredictionDecoder->iSubSetId, + psLCLDDecoder->pppiAlloc, + psLCLDDecoder->pppiLCLDSignReal, + psLCLDDecoder->pppiLCLDSignImag, + psLCLDDecoder->pppiQLCLDReal, + psLCLDDecoder->pppiQLCLDImag, + psLCLDDecoder->psPredictionDecoder->ppiDecodingFailed, + pBits, + psLCLDDecoder->c_apauiHuffDecTable_RAM ); + Word16 q_LCLD = Q_in; + + FOR( n = 0; n < psLCLDDecoder->iChannels; n++ ) + { + InvQuantizeSpectrum_fx( psLCLDDecoder->piNumGroups[n], + (const Word32 *) psLCLDDecoder->ppiGroupLengths[n], + psLCLDDecoder->iNumBands, psLCLDDecoder->piBandwidths, + psLCLDDecoder->pppiAlloc[n], + psLCLDDecoder->pppiQLCLDReal[n], + psLCLDDecoder->pppiQLCLDImag[n], + pppfLCLDReal_fx[n], pppfLCLDImag_fx[n], + psLCLDDecoder->psNoiseGen ); + + ReplaceSign_fx( psLCLDDecoder->iNumBlocks, psLCLDDecoder->iNumBands, + psLCLDDecoder->pppiLCLDSignReal[n], + psLCLDDecoder->pppiLCLDSignImag[n], + pppfLCLDReal_fx[n], pppfLCLDImag_fx[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 + + ApplyInversePredictors_fx( psLCLDDecoder->psPredictionDecoder, pppfLCLDReal_fx, pppfLCLDImag_fx ); + +#ifdef DEBUG_WRITE + FOR( n = 0; n < psLCLDDecoder->psPredictionDecoder->iChannels; ++n ) + { + FOR( Word16 i = 0; i < psLCLDDecoder->iNumBlocks; i++ ) + { + dbgwrite_txt( pppfLCLDReal[n][i], LCLD_BANDS, "LCLD_real_ApplyInversePredictors_fix.txt", NULL ); + dbgwrite_txt( pppfLCLDImag[n][i], LCLD_BANDS, "LCLD_imag_ApplyInversePredictors_fix.txt", NULL ); + } + } + + FOR( i = 0; i < psLCLDDecoder->psPredictionDecoder->iChannels; ++i ) + { + dbgwrite_txt( psLCLDDecoder->psPredictionDecoder->ppfPredStateReal[i], LCLD_BANDS, "LCLD_Pred_stat_real_ApplyInversePredictors_fix.txt", NULL ); + dbgwrite_txt( psLCLDDecoder->psPredictionDecoder->ppfPredStateImag[i], LCLD_BANDS, "LCLD_Pred_stat_imag_ApplyInversePredictors_fix.txt", NULL ); + } + +#endif + + Word16 Q = 7; + *Q_out = Q; + FOR( n = 0; n < psLCLDDecoder->iChannels; n++ ) + { + FOR( i = 0; i < psLCLDDecoder->iNumBlocks; i++ ) + { + FOR( j = 0; j < CLDFB_NO_CHANNELS_MAX; j++ ) + { + pppfLCLDReal_fx[n][i][j] = L_shl( pppfLCLDReal_fx[n][i][j], Q - q_LCLD ); + pppfLCLDImag_fx[n][i][j] = L_shl( pppfLCLDImag_fx[n][i][j], Q - q_LCLD ); + } + } + ApplyRMSEnvelope_fx( psLCLDDecoder->iNumBands, psLCLDDecoder->piBandwidths, + psLCLDDecoder->piNumGroups[n], + (const Word32 *) psLCLDDecoder->ppiGroupLengths[n], + psLCLDDecoder->pppiRMSEnvelope[n], + pppfLCLDReal_fx[n], pppfLCLDImag_fx[n] ); + } + + IF( EQ_32( psLCLDDecoder->iChannels, 2 ) && GT_32( psLCLDDecoder->iMSMode, 0 ) ) + { + Word16 exp1 = Q31 - *Q_out; + Word16 exp2 = Q31 - *Q_out; + Word32 real_max = 0; + Word32 imag_max = 0; + Word16 exp; + FOR( n = 0; n < psLCLDDecoder->iChannels; n++ ) + { + FOR( i = 0; i < psLCLDDecoder->iNumBlocks; i++ ) + { + FOR( j = 0; j < CLDFB_NO_CHANNELS_MAX; j++ ) + { + real_max = L_max( real_max, L_abs( pppfLCLDReal_fx[n][i][j] ) ); + imag_max = L_max( imag_max, L_abs( pppfLCLDImag_fx[n][i][j] ) ); + } + } + } + IF( NE_32( real_max, 0 ) ) + { + exp1 = s_min( exp1, norm_l( real_max ) ); + } + IF( NE_32( imag_max, 0 ) ) + { + exp2 = s_min( exp2, norm_l( imag_max ) ); + } + IF( NE_32( real_max, 0 ) || NE_32( imag_max, 0 ) ) + { + exp = min( exp2, exp1 ); + *Q_out = add( *Q_out, sub( exp, 3 ) ); + FOR( n = 0; n < psLCLDDecoder->iChannels; n++ ) + { + FOR( i = 0; i < psLCLDDecoder->iNumBlocks; i++ ) + { + FOR( j = 0; j < CLDFB_NO_CHANNELS_MAX; j++ ) + { + pppfLCLDReal_fx[n][i][j] = L_shl( pppfLCLDReal_fx[n][i][j], exp - 3 ); + pppfLCLDImag_fx[n][i][j] = L_shl( pppfLCLDImag_fx[n][i][j], exp - 3 ); + } + } + } + } + InvMSCoding_fx( psLCLDDecoder->iNumBlocks, psLCLDDecoder->iNumBands, + psLCLDDecoder->piBandwidths, psLCLDDecoder->iMSMode, + (const Word32 *) psLCLDDecoder->piMSFlags, + (const Word32 *) psLCLDDecoder->piLRPhaseDiffs, + (const Word32 *) psLCLDDecoder->piMSPredCoefs, + pppfLCLDReal_fx, pppfLCLDImag_fx ); + +#ifdef DEBUG_WRITE + for ( n = 0; n < psLCLDDecoder->iChannels; n++ ) + { + Word32 pppfLCLDReal_dbg[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX]; + Word32 pppfLCLDImag_dbg[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX]; + for ( i = 0; i < psLCLDDecoder->iNumBlocks; i++ ) + { + for ( j = 0; j < CLDFB_NO_CHANNELS_MAX; j++ ) + { + pppfLCLDReal_dbg[n][i][j] = (float) pppfLCLDReal_fx[n][i][j] / ( 1 << ( exp - 3 ) ); + pppfLCLDImag_dbg[n][i][j] = (float) pppfLCLDImag_fx[n][i][j] / ( 1 << ( exp - 3 ) ); + } + } + { + for ( Word16 i = 0; i < psLCLDDecoder->iNumBlocks; i++ ) + { + dbgwrite_txt( pppfLCLDReal_dbg[n][i], CLDFB_NO_CHANNELS_MAX, "LCLD_real_Inv_MS.txt", NULL ); + dbgwrite_txt( pppfLCLDImag_dbg[n][i], CLDFB_NO_CHANNELS_MAX, "LCLD_imag_Inv_MS.txt", NULL ); + } + } + } +#endif + } + IF( EQ_32( psLCLDDecoder->iRealOnlyOut, 1 ) ) + { + UnpackReal_fx( psLCLDDecoder->iChannels, + psLCLDDecoder->iNumBlocks * 2, + pppfLCLDReal_fx, + pppfLCLDImag_fx ); + } + + return AnyDecodingUnresolved( psLCLDDecoder->psPredictionDecoder ); +} +/*------------------------------------------------------------------------------------------* + * Local functions + * + * + *------------------------------------------------------------------------------------------*/ +static void ApplyRMSEnvelope_fx( + const Word32 iNumBands, + const Word32 *piBandwidths, + const Word32 iNumGroups, + const Word32 *piGroupLengths, + Word32 **ppiRMSEnvelope, + Word32 **ppfReal_fx, + Word32 **ppfImag_fx ) +{ + Word32 b, k, n; + +#ifdef DEBUG + FILE *fp_real, *fp_imag, *fp_real_fx, *fp_imag_fx, *fp_real_inp, *fp_imag_inp, *fp_real_inp_fx, *fp_imag_inp_fx; + fp_real = fopen( "Float_code_real1.txt", "ab+" ); + fp_imag = fopen( "Float_code_imag1.txt", "ab+" ); + fp_real_fx = fopen( "Fixed_code_real1.txt", "ab+" ); + fp_imag_fx = fopen( "Fixed_code_imag1.txt", "ab+" ); + fp_real_inp = fopen( "real_input.txt", "ab+" ); + fp_imag_inp = fopen( "imag_input.txt", "ab+" ); +#endif + + Word32 iBlockOffset, iFBOffset; + + iBlockOffset = 0; + FOR( n = 0; n < iNumGroups; n++ ) + { + FOR( k = 0; k < piGroupLengths[n]; k++ ) + { + iFBOffset = 0; + FOR( b = 0; b < iNumBands; b++ ) + { + Word32 m; + Word32 iRMSEnv; + Word32 fGain_fx; + Word16 fGain_exp; + + iRMSEnv = ppiRMSEnvelope[n][b]; + IF( ( ENV_RECONSTRUCT_TABLE_CENTER + iRMSEnv ) % 2 == 0 ) + { + fGain_fx = 1073741824; // 2 ^ 30 + } + ELSE + { + fGain_fx = 1518500249; // sqrt(2) * 2 ^ 30 + } + fGain_exp = c_afRMSEnvReconstructTable_exp[ENV_RECONSTRUCT_TABLE_CENTER + iRMSEnv]; + FOR( m = 0; m < piBandwidths[b]; m++ ) + { + Word64 tmp; +#ifdef DEBUG + fprintf( fp_real_inp, "%.6f\n", ppfReal[iBlockOffset][iFBOffset] ); + fprintf( fp_imag_inp, "%.6f\n", ppfImag[iBlockOffset][iFBOffset] ); +#endif + +#ifdef DEBUG + fprintf( fp_real, "%.6f\n", ppfReal[iBlockOffset][iFBOffset] ); + fprintf( fp_imag, "%.6f\n", ppfImag[iBlockOffset][iFBOffset] ); +#endif + tmp = W_mult_32_32( fGain_fx, ppfReal_fx[iBlockOffset][iFBOffset] ); + tmp = W_shr( tmp, fGain_exp + 1 ); + ppfReal_fx[iBlockOffset][iFBOffset] = W_extract_l( tmp ); + + tmp = W_mult_32_32( fGain_fx, ppfImag_fx[iBlockOffset][iFBOffset] ); + tmp = W_shr( tmp, fGain_exp + 1 ); + ppfImag_fx[iBlockOffset][iFBOffset] = W_extract_l( tmp ); + +#ifdef DEBUG + fprintf( fp_real_fx, "%.6f\n", (float) ppfReal_fx[iBlockOffset][iFBOffset] / ( 1 << Q ) ); + fprintf( fp_imag_fx, "%.6f\n", (float) ppfImag_fx[iBlockOffset][iFBOffset] / ( 1 << Q ) ); +#endif + + iFBOffset++; + } + } + iBlockOffset++; + } + } +#ifdef DEBUG + fclose( fp_real ); + fclose( fp_imag ); + fclose( fp_imag_fx ); + fclose( fp_real_fx ); + fclose( fp_real_inp ); + fclose( fp_imag_inp ); +#endif + + return; +} + +static void ReplaceSign_fx( + const Word32 iNumBlocks, + const Word32 iNumLCLDBands, + Word32 **ppiSignReal, + Word32 **ppiSignImag, + Word32 **ppfReal, + Word32 **ppfImag, + const Word32 *piBandwidths ) +{ + Word32 b, n; + Word32 m, idx; + + FOR( n = 0; n < iNumBlocks; n++ ) + { + idx = 0; + move32(); + FOR( b = 0; b < iNumLCLDBands; b++ ) + { + FOR( m = 0; m < piBandwidths[b]; m++ ) + { + IF( EQ_32( ppiSignReal[n][idx], 1 ) ) + { + ppfReal[n][idx] = L_negate( ppfReal[n][idx] ); + move32(); + } + + IF( EQ_32( ppiSignImag[n][idx], 1 ) ) + { + ppfImag[n][idx] = L_negate( ppfImag[n][idx] ); + move32(); + } + idx++; + } + } + } + return; +} + +static void InvQuantizeSpectrum_fx( + const Word32 iNumGroups, + const Word32 *piGroupLengths, + const Word32 iNumBands, + const Word32 *piBandwidths, + Word32 **ppiAlloc, + Word32 **ppiQReal, + Word32 **ppiQImag, + Word32 **ppfReal, + Word32 **ppfImag, + NoiseGen *psNoiseGen /* Pass in NULL to switch off noise gen */ +) +{ + Word32 b, k, n; + Word32 iBlockOffest, iFBOffset; + + iBlockOffest = 0; + move32(); + FOR( n = 0; n < iNumGroups; n++ ) + { + FOR( k = 0; k < piGroupLengths[n]; k++ ) + { + iFBOffset = 0; + FOR( b = 0; b < iNumBands; b++ ) + { + Word32 m; + Word32 iAlloc; + Word32 fInvSCFGain; + + iAlloc = ppiAlloc[n][b]; + move32(); + fInvSCFGain = c_afInvScaleFactor_fx[iAlloc]; // Q29 + move32(); + IF( GT_32( iAlloc, 0 ) ) + { + FOR( m = 0; m < piBandwidths[b]; m++ ) + { + Word16 iQuantValue; + + iQuantValue = (Word16) ppiQReal[iBlockOffest][iFBOffset]; + move16(); + ppfReal[iBlockOffest][iFBOffset] = Mpy_32_16_1( fInvSCFGain, iQuantValue ); // Q14 + move32(); + iQuantValue = (Word16) ppiQImag[iBlockOffest][iFBOffset]; + move16(); + ppfImag[iBlockOffest][iFBOffset] = Mpy_32_16_1( fInvSCFGain, iQuantValue ); // Q14 + move32(); + iFBOffset++; + } + } + ELSE IF( psNoiseGen != NULL ) + { + FOR( m = 0; m < piBandwidths[b]; m++ ) + { + ppfReal[iBlockOffest][iFBOffset] = Mpy_32_16_1( GetNoise_fx( psNoiseGen ), 22938 ); // Q(14 + 15 -15 )=Q14 + move32(); + ppfImag[iBlockOffest][iFBOffset] = Mpy_32_16_1( GetNoise_fx( psNoiseGen ), 22938 ); // Q(14+ 15 -15 )=Q14 + move32(); + iFBOffset++; + } + } + ELSE + { + iFBOffset = L_add( iFBOffset, piBandwidths[b] ); + move32(); + } + } + + iBlockOffest++; + } + } + + return; +} + +static void InvMSCoding_fx( + const Word32 iNumBlocks, + const Word32 iNumBands, + const Word32 *piBandwidths, + const Word32 iMSMode, + const Word32 *piMSFlags, + const Word32 *piLRPhaseDiffs, + const Word32 *piMSPredCoefs, + Word32 ***pppfReal, + Word32 ***pppfImag ) +{ + + IF( GT_32( iMSMode, 0 ) ) + { + Word32 b; + Word32 iFBOffset; + Word32 bMSPred = 0; + move32(); + + iFBOffset = 0; + move32(); + FOR( b = 0; b < iNumBands; b++ ) + { + IF( EQ_32( piMSFlags[b], 1 ) ) + { + Word32 n; + Word32 phaseIdx; + + Word32 fPred; + + phaseIdx = piLRPhaseDiffs[bMSPred] - PHASE_MIN_VAL; + move32(); + fPred = dequantPred_fx( piMSPredCoefs[bMSPred] ); + move32(); + FOR( n = 0; n < piBandwidths[b]; n++ ) + { + Word32 k; + FOR( k = 0; k < iNumBlocks; k++ ) + { + Word32 fLeftReal; + Word32 fLeftImag; + Word32 fRightReal; + Word32 fRightImag; + + IF( EQ_32( iMSMode, 3 ) ) + { + pppfReal[1][k][iFBOffset] = L_add( pppfReal[1][k][iFBOffset], Mpy_32_32( fPred, pppfReal[0][k][iFBOffset] ) ); + move32(); + pppfImag[1][k][iFBOffset] = L_add( pppfImag[1][k][iFBOffset], Mpy_32_32( fPred, pppfImag[0][k][iFBOffset] ) ); + move32(); + } + + fLeftReal = L_add( pppfReal[0][k][iFBOffset], pppfReal[1][k][iFBOffset] ); + fLeftImag = L_add( pppfImag[0][k][iFBOffset], pppfImag[1][k][iFBOffset] ); + fRightReal = L_sub( pppfReal[0][k][iFBOffset], pppfReal[1][k][iFBOffset] ); + fRightImag = L_sub( pppfImag[0][k][iFBOffset], pppfImag[1][k][iFBOffset] ); + + IF( EQ_32( iMSMode, 3 ) ) + { + cplxmult_fx( &fRightReal, &fRightImag, c_afRotRealImag_fx[phaseIdx][0], -c_afRotRealImag_fx[phaseIdx][1] ); + } + + pppfReal[0][k][iFBOffset] = fLeftReal; + move32(); + pppfReal[1][k][iFBOffset] = fRightReal; + move32(); + pppfImag[0][k][iFBOffset] = fLeftImag; + move32(); + pppfImag[1][k][iFBOffset] = fRightImag; + move32(); + } + iFBOffset++; + } + bMSPred++; + } + ELSE + { + iFBOffset = L_add( iFBOffset, piBandwidths[b] ); + move32(); + } + } + } + + return; +} + +/* Currently only the number of bands in frame */ +static Word32 ReadHeaderInformation( + Word32 *piNumBands, + ISAR_SPLIT_REND_BITS_HANDLE pBits ) +{ + Word32 iBitsRead; + + iBitsRead = 0; + move32(); + *piNumBands = ISAR_SPLIT_REND_BITStream_read_int32( pBits, 5 ); + iBitsRead = L_add( iBitsRead, 5 ); + + return iBitsRead; +} + + +static Word32 ReadMSInformation( + const Word32 iNumBands, + Word32 *piMSMode, + Word32 *piMSFlags, + Word32 *piLRPhaseDiffs, + Word32 *piMSPredCoefs, + ISAR_SPLIT_REND_BITS_HANDLE pBits ) +{ + Word32 iBitsRead; + + iBitsRead = 0; + move32(); + *piMSMode = ISAR_SPLIT_REND_BITStream_read_int32( pBits, 2 ); + iBitsRead = L_add( iBitsRead, 2 ); + + IF( EQ_32( *piMSMode, 0 ) ) + { + Word32 n; + FOR( n = 0; n < iNumBands; n++ ) + { + piMSFlags[n] = 0; + move32(); + } + } + ELSE IF( EQ_32( *piMSMode, 1 ) ) + { + Word32 n; + FOR( n = 0; n < iNumBands; n++ ) + { + piMSFlags[n] = 1; + move32(); + } + } + ELSE IF( EQ_32( *piMSMode, 2 ) ) + { + Word32 n; + FOR( n = 0; n < iNumBands; n++ ) + { + piMSFlags[n] = ISAR_SPLIT_REND_BITStream_read_int32( pBits, 1 ); + move32(); + iBitsRead = L_add( iBitsRead, 1 ); + } + } + ELSE IF( EQ_32( *piMSMode, 3 ) ) + { + Word32 n; + Word32 iMSPredAll; + Word32 iNumMSPredBands = 0; + Word32 anyNonZero; + move32(); + iMSPredAll = ISAR_SPLIT_REND_BITStream_read_int32( pBits, 1 ); + iBitsRead = L_add( iBitsRead, 1 ); + IF( iMSPredAll ) + { + iNumMSPredBands = iNumBands; + move32(); + FOR( n = 0; n < iNumBands; n++ ) + { + piMSFlags[n] = 1; + move32(); + } + } + ELSE + { + FOR( n = 0; n < iNumBands; n++ ) + { + piMSFlags[n] = ISAR_SPLIT_REND_BITStream_read_int32( pBits, 1 ); + move32(); + iBitsRead = L_add( iBitsRead, 1 ); + IF( piMSFlags[n] ) + { + iNumMSPredBands++; + } + } + } + anyNonZero = ISAR_SPLIT_REND_BITStream_read_int32( pBits, 1 ); + IF( anyNonZero ) + { + piLRPhaseDiffs[0] = ISAR_SPLIT_REND_BITStream_read_int32( pBits, PHASE_BAND0_BITS ); + move32(); + piLRPhaseDiffs[0] = L_add( piLRPhaseDiffs[0], PHASE_MIN_VAL ); + move32(); + iBitsRead = L_add( iBitsRead, PHASE_BAND0_BITS ); + FOR( n = 1; n < iNumMSPredBands; n++ ) + { + Word32 tabIdx; + iBitsRead = L_add( iBitsRead, ReadHuff( c_aaiRMSEnvHuffDec, &tabIdx, pBits ) ); + piLRPhaseDiffs[n] = L_add( tabIdx, ENV_DELTA_MIN ); + move32(); + } + DecodePhase( piLRPhaseDiffs, iNumMSPredBands, PHASE_DIFF_DIM ); + } + ELSE + { + FOR( n = 0; n < iNumMSPredBands; n++ ) + { + piLRPhaseDiffs[n] = 0; + move32(); + } + } + anyNonZero = ISAR_SPLIT_REND_BITStream_read_int32( pBits, 1 ); + IF( anyNonZero ) + { + piMSPredCoefs[0] = ISAR_SPLIT_REND_BITStream_read_int32( pBits, PRED_BAND0_BITS ); + move32(); + piMSPredCoefs[0] = L_add( piMSPredCoefs[0], PRED_MIN_VAL ); + move32(); + iBitsRead = L_add( iBitsRead, PRED_BAND0_BITS ); + FOR( n = 1; n < iNumMSPredBands; n++ ) + { + Word32 tabIdx; + iBitsRead = L_add( iBitsRead, ReadHuff( c_aaiRMSEnvHuffDec, &tabIdx, pBits ) ); + piMSPredCoefs[n] = L_add( tabIdx, ENV_DELTA_MIN ); + move32(); + } + DecodePredCoef( piMSPredCoefs, iNumMSPredBands ); + } + ELSE + { + FOR( n = 0; n < iNumMSPredBands; n++ ) + { + piMSPredCoefs[n] = 0; + move32(); + } + } +#ifdef DEBUG_WRITE_MS_PRED + { + static FILE *fid; + IF( !fid ) + fid = fopen( "ms_pred_dec.txt", "wt" ); + writeMSPred( piLRPhaseDiffs, piMSPredCoefs, *piMSMode, iNumMSPredBands, iNumBands, fid, piMSFlags ); + } +#endif + } + ELSE + { + printf( "ERROR UNSUPPORTED MS MODE\n" ); + } + + return iBitsRead; +} + +static Word32 ReadGroupInformation( + const Word32 iChannels, + const Word32 iNumBlocks, + Word32 *piCommonGrouping, + Word32 *piNumGroups, + Word32 **ppiGroupLengths, + ISAR_SPLIT_REND_BITS_HANDLE pBits ) +{ + Word32 c, k, iBitsRead; + + iBitsRead = 0; + move32(); + IF( EQ_32( iChannels, 2 ) ) + { + *piCommonGrouping = ISAR_SPLIT_REND_BITStream_read_int32( pBits, 1 ); + move32(); + iBitsRead = L_add( iBitsRead, 1 ); + + IF( EQ_32( *piCommonGrouping, 1 ) ) + { + piNumGroups[0] = 0; + move32(); + ppiGroupLengths[0][piNumGroups[0]] = 1; + move32(); + FOR( k = 0; k < L_sub( iNumBlocks, 1 ); k++ ) + { + Word32 iGroupStart; + + iGroupStart = ISAR_SPLIT_REND_BITStream_read_int32( pBits, 1 ); + iBitsRead = L_add( iBitsRead, 1 ); + + IF( EQ_32( iGroupStart, 1 ) ) + { + piNumGroups[0] = L_add( piNumGroups[0], 1 ); + move32(); + ppiGroupLengths[0][piNumGroups[0]] = 1; + move32(); + } + ELSE + { + ppiGroupLengths[0][piNumGroups[0]] = L_add( ppiGroupLengths[0][piNumGroups[0]], 1 ); + move32(); + } + } + piNumGroups[0] = L_add( piNumGroups[0], 1 ); + move32(); + + piNumGroups[1] = piNumGroups[0]; + move32(); + FOR( k = 0; k < piNumGroups[1]; k++ ) + { + ppiGroupLengths[1][k] = ppiGroupLengths[0][k]; + move32(); + } + } + ELSE + { + FOR( c = 0; c < iChannels; c++ ) + { + piNumGroups[c] = 0; + move32(); + ppiGroupLengths[c][piNumGroups[c]] = 1; + move32(); + FOR( k = 0; k < L_sub( iNumBlocks, 1 ); k++ ) + { + Word32 iGroupStart; + + iGroupStart = ISAR_SPLIT_REND_BITStream_read_int32( pBits, 1 ); + iBitsRead = L_add( iBitsRead, 1 ); + + IF( EQ_32( iGroupStart, 1 ) ) + { + piNumGroups[c] = L_add( piNumGroups[c], 1 ); + move32(); + ppiGroupLengths[c][piNumGroups[c]] = 1; + move32(); + } + ELSE + { + ppiGroupLengths[c][piNumGroups[c]] = L_add( ppiGroupLengths[c][piNumGroups[c]], 1 ); + move32(); + } + } + piNumGroups[c] = L_add( piNumGroups[c], 1 ); + move32(); + } + } + } + ELSE + { + FOR( c = 0; c < iChannels; c++ ) + { + piNumGroups[c] = 0; + move32(); + ppiGroupLengths[c][piNumGroups[c]] = 1; + move32(); + FOR( k = 0; k < L_sub( iNumBlocks, 1 ); k++ ) + { + Word32 iGroupStart; + + iGroupStart = ISAR_SPLIT_REND_BITStream_read_int32( pBits, 1 ); + iBitsRead = L_add( iBitsRead, 1 ); + + IF( EQ_32( iGroupStart, 1 ) ) + { + piNumGroups[c] = L_add( piNumGroups[c], 1 ); + move32(); + ppiGroupLengths[c][piNumGroups[c]] = 1; + move32(); + } + ELSE + { + ppiGroupLengths[c][piNumGroups[c]] = L_add( ppiGroupLengths[c][piNumGroups[c]], 1 ); + } + } + piNumGroups[c] = L_add( piNumGroups[c], 1 ); + } + } + + return iBitsRead; +} + +static Word32 BSForceBack( + ISAR_SPLIT_REND_BITS_HANDLE pBits, + Word32 iValue, + Word32 iBitCount ) +{ + pBits->bits_read = L_sub( pBits->bits_read, iBitCount ); + + return ( L_shr( iValue, (Word16) iBitCount ) ); +} + + +static Word32 ReadHuff( + const UWord32 ( *pauiHuffDecTable )[HUFF_DEC_TABLE_SIZE], + Word32 *piSymbol, + ISAR_SPLIT_REND_BITS_HANDLE pBits ) +{ + Word32 iBitsRead; + Word32 iSymbol; + Word32 iIndex; + Word32 iVal; + + iVal = 0; + move32(); + iIndex = 0; + move32(); + iSymbol = 0xFFFF; + move32(); + iBitsRead = 0; + move32(); + WHILE( iSymbol == 0xFFFF ) + { + iIndex = ISAR_SPLIT_REND_BITStream_read_int32( pBits, HUFF_READ_SIZE ); + iBitsRead = L_add( iBitsRead, HUFF_READ_SIZE ); + + iIndex = pauiHuffDecTable[iVal][iIndex]; + iSymbol = ( L_and( iIndex, 0xFFFF ) ); + + iVal = ( L_shr( iIndex, 16 ) ); + } + + IF( iVal ) + { + BSForceBack( pBits, iIndex, iVal ); + iBitsRead = L_sub( iBitsRead, iVal ); + } + + *piSymbol = iSymbol; + move32(); + + return iBitsRead; +} + + +static Word32 ReadRMSEnvelope( + const Word32 iChannels, + const Word32 *piNumGroups, + const Word32 iNumBands, + Word32 ***pppiRMSEnvelope, + ISAR_SPLIT_REND_BITS_HANDLE pBits ) +{ + Word32 b, k, n; + Word32 iBitsRead, iLastRMSVal; + + iBitsRead = 0; + move32(); + FOR( n = 0; n < iChannels; n++ ) + { + FOR( k = 0; k < piNumGroups[n]; k++ ) + { + iLastRMSVal = ISAR_SPLIT_REND_BITStream_read_int32( pBits, ENV0_BITS ); + iBitsRead = L_add( iBitsRead, ENV0_BITS ); + + iLastRMSVal = L_add( iLastRMSVal, ENV_MIN ); + pppiRMSEnvelope[n][k][0] = iLastRMSVal; + move32(); + FOR( b = 1; b < iNumBands; b++ ) + { + Word32 iDelta; + + iBitsRead = L_add( iBitsRead, ReadHuff( c_aaiRMSEnvHuffDec, &iDelta, pBits ) ); + + iDelta = L_add( iDelta, ENV_DELTA_MIN ); + iLastRMSVal = L_add( iDelta, iLastRMSVal ); + pppiRMSEnvelope[n][k][b] = iLastRMSVal; + move32(); + } + } + } + + return iBitsRead; +} + + +static Word32 ReadAllocInformation( + Word32 *piAllocOffset, + ISAR_SPLIT_REND_BITS_HANDLE pBits ) +{ + Word32 iBitsRead; + + iBitsRead = 0; + move32(); + *piAllocOffset = ISAR_SPLIT_REND_BITStream_read_int32( pBits, ALLOC_OFFSET_BITS ); + *piAllocOffset = L_add( *piAllocOffset, MIN_ALLOC_OFFSET ); + iBitsRead = L_add( iBitsRead, ALLOC_OFFSET_BITS ); + + return iBitsRead; +} + +static Word32 ReadLCLDData_fx( + const Word32 *piNumGroups, + Word32 **ppiGroupLengths, + const Word32 iNumBands, + const Word32 iNumChannels, + Word32 **ppiDecodingUnresolved, + Word32 **ppiPredEnable, + const Word32 iNumSubSets, + const Word32 iSubSetId, + Word32 ***pppiAlloc, + Word32 ***pppiSignReal, + Word32 ***pppiSignImag, + Word32 ***pppiQReal, + Word32 ***pppiQImag, + Word32 **ppiDecodingFailed, + ISAR_SPLIT_REND_BITS_HANDLE pBits, + UWord32 ( *c_apauiHuffDecTables[2 * ALLOC_TABLE_SIZE] )[HUFF_DEC_TABLE_SIZE] ) +{ + Word32 iBitsRead; + Word32 iDecodingStopped = 0; + Word32 iNumLcldBands = c_aiNumLcldBandsPerBand[iNumBands - 1]; + Word32 s; + Word32 iSet = iSubSetId; + Word16 tmp, tmp_e; + iBitsRead = 0; + for ( s = 0; s < iNumSubSets; s++, iSet-- ) + { + Word32 ch; + + IF( LT_32( iSet, 0 ) ) + { + iSet = L_sub( iNumSubSets, 1 ); + } + + FOR( ch = 0; ch < iNumChannels; ch++ ) + { + Word32 n; + Word32 iBlockOffest; + + IF( EQ_32( ppiDecodingUnresolved[ch][iSet], 1 ) ) + { + iDecodingStopped = 1; + ppiDecodingFailed[ch][iSet] = 1; /* mark as not decoded (is also initialized like that when a frame is lost */ + } + ELSE + { + ppiDecodingFailed[ch][iSet] = 0; /* mark as correctly decoded */ + } + iBlockOffest = 0; + FOR( n = 0; n < piNumGroups[ch]; n++ ) + { + Word32 k; + FOR( k = 0; k < ppiGroupLengths[ch][n]; k++ ) + { + Word32 iFBOffset; + + FOR( iFBOffset = iSet; iFBOffset < iNumLcldBands; iFBOffset += iNumSubSets ) + { + Word32 b; + Word32 iAlloc; + Word32 iHuffDim; + Word32 iHuffMod; + + b = c_aiBandIdPerLcldBand[iFBOffset]; + + iAlloc = pppiAlloc[ch][n][b]; + + iHuffDim = c_aiHuffmanDim_fx[iAlloc]; + iHuffMod = c_aiHuffmanMod_fx[iAlloc]; + + IF( EQ_32( iDecodingStopped, 1 ) ) + { + pppiQReal[ch][iBlockOffest][iFBOffset] = 0; + pppiQImag[ch][iBlockOffest][iFBOffset] = 0; + pppiSignReal[ch][iBlockOffest][iFBOffset] = 0; + pppiSignImag[ch][iBlockOffest][iFBOffset] = 0; + } + ELSE IF( GT_32( iAlloc, 0 ) ) + { + const UWord32( *pauiHuffmanTable )[HUFF_DEC_TABLE_SIZE] = NULL; + const UWord32( *pauiHuffmanTableDPCM )[HUFF_DEC_TABLE_SIZE] = NULL; + Word32 iQuantValue1 = 0; + Word32 iQuantValue2 = 0; +#ifdef USE_DEMOD_TABLES + const int32_t( *paiDemodTable )[2] = NULL; +#endif +#define WMC_TOOL_SKIP + pauiHuffmanTable = (const UWord32( * )[HUFF_DEC_TABLE_SIZE]) c_apauiHuffDecTables[iAlloc]; + pauiHuffmanTableDPCM = (const UWord32( * )[HUFF_DEC_TABLE_SIZE]) c_apauiHuffDecTables[ALLOC_TABLE_SIZE + iAlloc]; +#undef WMC_TOOL_SKIP +#ifdef USE_DEMOD_TABLES + paiDemodTable = c_apaiDemodTables[iAlloc]; +#endif +#ifdef LCLD_HANDLE_PRED_START_SAMPLE + if ( ppiPredEnable[ch][iFBOffset] == 1 && ( iBlockOffest > 0 || iSet != iSubSetId ) ) +#else + IF( EQ_32( ppiPredEnable[ch][iFBOffset], 1 ) ) +#endif + { + IF( EQ_32( iHuffDim, 2 ) ) + { + Word32 iSymbol; + iBitsRead = L_add( iBitsRead, ReadHuff( pauiHuffmanTableDPCM, &iSymbol, pBits ) ); +#ifdef USE_DEMOD_TABLES + iQuantValue1 = paiDemodTable[iSymbol][0]; + iQuantValue2 = paiDemodTable[iSymbol][1]; +#else + tmp = BASOP_Util_Divide1616_Scale( (Word16) iSymbol, (Word16) iHuffMod, &tmp_e ); + iQuantValue1 = L_deposit_l( shr( tmp, add( 15, negate( tmp_e ) ) ) ); + // iQuantValue1 = iSymbol / iHuffMod; + iQuantValue2 = iSymbol % iHuffMod; +#endif + } + ELSE + { + iBitsRead = L_add( iBitsRead, ReadHuff( pauiHuffmanTableDPCM, &iQuantValue1, pBits ) ); + iBitsRead = L_add( iBitsRead, ReadHuff( pauiHuffmanTableDPCM, &iQuantValue2, pBits ) ); + } + } + ELSE + { + IF( EQ_32( iHuffDim, 2 ) ) + { + Word32 iSymbol; + + iBitsRead = L_add( iBitsRead, ReadHuff( pauiHuffmanTable, &iSymbol, pBits ) ); +#ifdef USE_DEMOD_TABLES + iQuantValue1 = paiDemodTable[iSymbol][0]; + iQuantValue2 = paiDemodTable[iSymbol][1]; +#else + tmp = BASOP_Util_Divide1616_Scale( (Word16) iSymbol, (Word16) iHuffMod, &tmp_e ); + iQuantValue1 = L_deposit_l( shr( tmp, add( 15, negate( tmp_e ) ) ) ); + iQuantValue2 = iSymbol % iHuffMod; +#endif + } + ELSE + { + iBitsRead = L_add( iBitsRead, ReadHuff( pauiHuffmanTable, &iQuantValue1, pBits ) ); + move32(); + iBitsRead = L_add( iBitsRead, ReadHuff( pauiHuffmanTable, &iQuantValue2, pBits ) ); + move32(); + /*iBitsRead += ReadHuff( pauiHuffmanTable, &iQuantValue1, pBits ); + iBitsRead += ReadHuff( pauiHuffmanTable, &iQuantValue2, pBits );*/ + } + } + + pppiQReal[ch][iBlockOffest][iFBOffset] = iQuantValue1; + move32(); + pppiQImag[ch][iBlockOffest][iFBOffset] = iQuantValue2; + move32(); + IF( GT_32( iQuantValue1, 0 ) ) + { + pppiSignReal[ch][iBlockOffest][iFBOffset] = ISAR_SPLIT_REND_BITStream_read_int32( pBits, 1 ); + move32(); + iBitsRead = L_add( iBitsRead, 1 ); + move32(); + } + ELSE + { + pppiSignReal[ch][iBlockOffest][iFBOffset] = 0; + } + IF( GT_32( iQuantValue2, 0 ) ) + { + pppiSignImag[ch][iBlockOffest][iFBOffset] = ISAR_SPLIT_REND_BITStream_read_int32( pBits, 1 ); + move32(); + iBitsRead = L_add( iBitsRead, 1 ); + move32(); + } + ELSE + { + pppiSignImag[ch][iBlockOffest][iFBOffset] = 0; + } + } + ELSE + { + pppiSignReal[ch][iBlockOffest][iFBOffset] = 0; + move32(); + pppiSignImag[ch][iBlockOffest][iFBOffset] = 0; + move32(); + } + } + iBlockOffest++; + } + } + } + } + + return iBitsRead; +} + +static void ComputeAllocation( + const Word32 iChannels, + const Word32 *piNumGroups, + const Word32 iNumBands, + Word32 ***pppiSMR, + const Word32 iAllocOffset, + Word32 ***pppiAlloc ) +{ + Word32 b, k, n, iAlloc; + + FOR( n = 0; n < iChannels; n++ ) + { + FOR( k = 0; k < piNumGroups[n]; k++ ) + { + FOR( b = 0; b < iNumBands; b++ ) + { + iAlloc = L_shr( L_add( pppiSMR[n][k][b], L_mult0( (Word16) iAllocOffset, ALLOC_OFFSET_SCALE ) ), 5 ); + iAlloc = ( iAlloc > MIN_ALLOC ) ? iAlloc : MIN_ALLOC; + iAlloc = ( iAlloc < MAX_ALLOC ) ? iAlloc : MAX_ALLOC; + pppiAlloc[n][k][b] = iAlloc; + move32(); + } + } + } + + return; +} + +#endif diff --git a/lib_isar/isar_lcld_encoder.c b/lib_isar/isar_lcld_encoder.c new file mode 100644 index 0000000000000000000000000000000000000000..48445d08024b8b01cefa578719ab31a79441988f --- /dev/null +++ b/lib_isar/isar_lcld_encoder.c @@ -0,0 +1,2142 @@ +/****************************************************************************************************** + + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository. All Rights Reserved. + + This software is protected by copyright law and by international treaties. + The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository retain full ownership rights in their respective contributions in + the software. This notice grants no license of any kind, including but not limited to patent + license, nor is any license granted by implication, estoppel or otherwise. + + Contributors are required to enter into the IVAS codec Public Collaboration agreement before making + contributions. + + This software is provided "AS IS", without any express or implied warranties. The software is in the + development stage. It is intended exclusively for experts who have experience with such software and + solely for the purpose of inspection. All implied warranties of non-infringement, merchantability + and fitness for a particular purpose are hereby disclaimed and excluded. + + Any dispute, controversy or claim arising under or in relation to providing this software shall be + submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in + accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and + the United Nations Convention on Contracts on the International Sales of Goods. + +*******************************************************************************************************/ + +#include +#include "options.h" +#ifdef SPLIT_REND_WITH_HEAD_ROT +#include +#include +#include "isar_lcld_prot.h" +#include "isar_lcld_rom_tables.h" +#include "prot_fx.h" +#include "prot_fx.h" +#include "isar_prot.h" +#include "wmc_auto.h" +#include "basop_util.h" +#include "enh64.h" +#include "basop32.h" + +#define LOG10_2_FX ( 646456993 ) +/*------------------------------------------------------------------------------------------* + * Local structures + *------------------------------------------------------------------------------------------*/ +struct LCLD_ENCODER +{ + Word32 iSampleRate; + Word32 iChannels; + Word32 iNumBlocks; + + Word32 iTargetBitRate; + + Word32 iNumBands; + const Word32 *piBandwidths; + + Word32 iMSMode; + Word32 *piMSFlags; + Word32 piMSPredCoefs[MAX_BANDS]; + Word32 piLRPhaseDiffs[MAX_BANDS]; + Word32 iAllowSidePred; + + Word32 iRealOnlyOut; + + RMSEnvelopeGrouping *psRMSEnvelopeGrouping; + + Word32 iCommonGrouping; + Word32 *piNumGroups; + Word32 **ppiGroupLengths; + + Word32 ***pppiRMSEnvelope; + Word32 ***pppiSMR; + Word32 ***pppiExcitation; + Word32 ***pppiAlloc; + + Word32 iAllocOffset; + + Word32 ***pppiLCLDSignReal; + Word32 ***pppiLCLDSignImag; + Word32 ***pppiQLCLDReal; + Word32 ***pppiQLCLDImag; + + + PredictionEncoder *psPredictionEncoder; +}; +/*------------------------------------------------------------------------------------------* + * Function Quantize() + * + * + *------------------------------------------------------------------------------------------*/ +static Word32 Quantize_fx( + const Word32 fVal_fx, + const Word32 fScale_fx, + Word32 *iSign, + const Word32 iMaxVal ) +{ + Word32 iVal_fx; + IF( GT_32( fVal_fx, 0 ) ) + { + iVal_fx = (Word32) L_add( Mpy_32_32( fScale_fx, fVal_fx ), ONE_IN_Q20 ); + *iSign = 0; + } + ELSE + { + iVal_fx = (Word32) L_add( Mpy_32_32( -fScale_fx, fVal_fx ), ONE_IN_Q20 ); + *iSign = 1; + } + iVal_fx = ( iVal_fx < iMaxVal ) ? iVal_fx : iMaxVal; + + return iVal_fx; +} +/*------------------------------------------------------------------------------------------* + * Function UnQuantize() + * + * + *------------------------------------------------------------------------------------------*/ +static Word32 UnQuantize_fx( + const Word32 iVal_fx, + const Word32 fScale_fx, + const Word32 iSign ) +{ + + Word32 fVal_fx; + IF( EQ_32( iSign, 0 ) ) + { + fVal_fx = Mpy_32_32( fScale_fx, iVal_fx ); // Q19 + } + ELSE + { + fVal_fx = Mpy_32_32( -fScale_fx, iVal_fx ); // Q19 + } + return fVal_fx; +} +static void PackReal( + const Word32 iChannels, + const Word32 iNumBlocks, + Word32 ***pppfReal, + Word32 ***pppfImag ) +{ + Word32 ch, b, n; + FOR( ch = 0; ch < iChannels; ch++ ) + { + FOR( b = 0; b < LCLD_BANDS; b++ ) + { + Word32 iRealBlock = 0; + move32(); + FOR( n = 0; n < iNumBlocks; n += 2 ) + { + pppfImag[ch][iRealBlock][b] = pppfReal[ch][n + 1][b]; + move32(); + pppfReal[ch][iRealBlock][b] = pppfReal[ch][n][b]; + move32(); + iRealBlock++; + } + } + } +} +/*------------------------------------------------------------------------------------------* + * Function CreateLCLDEncoder() + * + * + *------------------------------------------------------------------------------------------*/ + +ivas_error CreateLCLDEncoder( + LCLDEncoder **psLCLDEncoder_out, + const Word32 iSampleRate, + const Word32 iChannels, + const Word32 iTargetBitRate, + const Word32 iAllowSidePred, + const Word16 iNumBlocks, + const Word16 iNumSubSets, + const Word32 iRealOnlyOut ) +{ + Word32 n; + LCLDEncoder *psLCLDEncoder; + ivas_error error; + Word32 iMaxNumPredBands = 0; + move32(); + + 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 ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); + } + + psLCLDEncoder->iSampleRate = iSampleRate; + move32(); + psLCLDEncoder->iChannels = iChannels; + move32(); + psLCLDEncoder->iRealOnlyOut = iRealOnlyOut; + move32(); + psLCLDEncoder->iAllocOffset = 0; + move32(); + + psLCLDEncoder->iTargetBitRate = iTargetBitRate; + move32(); + + psLCLDEncoder->piBandwidths = c_aiBandwidths48; + psLCLDEncoder->iNumBands = DEF_BANDS_48; /* 22 bands = 50 CLDFB bands (rather than 23 bands) */ + move32(); + iMaxNumPredBands = L_min( c_aiNumLcldBandsPerBand[psLCLDEncoder->iNumBands - 1], 50 ); + IF( EQ_32( iRealOnlyOut, 1 ) ) + { + iMaxNumPredBands = 0; + move32(); + assert( iNumSubSets == 1 ); + psLCLDEncoder->iNumBlocks = L_deposit_l( shr( iNumBlocks, 1 ) ); + } + ELSE + { + psLCLDEncoder->iNumBlocks = iNumBlocks; + move32(); + } + + psLCLDEncoder->iMSMode = 0; + move32(); + IF( ( psLCLDEncoder->piMSFlags = (Word32 *) malloc( MAX_BANDS * sizeof( Word32 ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); + } + + FOR( n = 0; n < MAX_BANDS; n++ ) + { + psLCLDEncoder->piLRPhaseDiffs[n] = 0; + move32(); + psLCLDEncoder->piMSPredCoefs[n] = 0; + move32(); + } + psLCLDEncoder->iAllowSidePred = iAllowSidePred; + move32(); + + psLCLDEncoder->psRMSEnvelopeGrouping = CreateRMSEnvelopeGrouping( psLCLDEncoder->iNumBlocks ); + + psLCLDEncoder->iCommonGrouping = 1; //*Common grouping always on only impacts stereo */ + move32(); + IF( ( psLCLDEncoder->piNumGroups = (Word32 *) malloc( psLCLDEncoder->iChannels * sizeof( Word32 ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); + } + + IF( ( psLCLDEncoder->ppiGroupLengths = (Word32 **) malloc( psLCLDEncoder->iChannels * sizeof( Word32 * ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); + } + + IF( ( psLCLDEncoder->pppiRMSEnvelope = (Word32 ***) malloc( psLCLDEncoder->iChannels * sizeof( Word32 ** ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); + } + + IF( ( psLCLDEncoder->pppiSMR = (Word32 ***) malloc( psLCLDEncoder->iChannels * sizeof( Word32 ** ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); + } + + IF( ( psLCLDEncoder->pppiExcitation = (Word32 ***) malloc( psLCLDEncoder->iChannels * sizeof( Word32 ** ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); + } + + IF( ( psLCLDEncoder->pppiAlloc = (Word32 ***) malloc( psLCLDEncoder->iChannels * sizeof( Word32 ** ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); + } + + + IF( ( psLCLDEncoder->pppiLCLDSignReal = (Word32 ***) malloc( psLCLDEncoder->iChannels * sizeof( Word32 ** ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); + } + + IF( ( psLCLDEncoder->pppiLCLDSignImag = (Word32 ***) malloc( psLCLDEncoder->iChannels * sizeof( Word32 ** ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); + } + + IF( ( psLCLDEncoder->pppiQLCLDReal = (Word32 ***) malloc( psLCLDEncoder->iChannels * sizeof( Word32 ** ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); + } + + IF( ( psLCLDEncoder->pppiQLCLDImag = (Word32 ***) malloc( psLCLDEncoder->iChannels * sizeof( Word32 ** ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); + } + + + FOR( n = 0; n < iChannels; n++ ) + { + Word32 k; + IF( ( psLCLDEncoder->ppiGroupLengths[n] = (Word32 *) malloc( LCLD_BLOCKS_PER_FRAME * sizeof( Word32 ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); + } + + IF( ( psLCLDEncoder->pppiRMSEnvelope[n] = (Word32 **) malloc( LCLD_BLOCKS_PER_FRAME * sizeof( Word32 * ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); + } + + IF( ( psLCLDEncoder->pppiSMR[n] = (Word32 **) malloc( LCLD_BLOCKS_PER_FRAME * sizeof( Word32 * ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); + } + + IF( ( psLCLDEncoder->pppiExcitation[n] = (Word32 **) malloc( LCLD_BLOCKS_PER_FRAME * sizeof( Word32 * ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); + } + + IF( ( psLCLDEncoder->pppiAlloc[n] = (Word32 **) malloc( LCLD_BLOCKS_PER_FRAME * sizeof( Word32 * ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); + } + + + IF( ( psLCLDEncoder->pppiLCLDSignReal[n] = (Word32 **) malloc( LCLD_BLOCKS_PER_FRAME * sizeof( Word32 * ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); + } + + IF( ( psLCLDEncoder->pppiLCLDSignImag[n] = (Word32 **) malloc( LCLD_BLOCKS_PER_FRAME * sizeof( Word32 * ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); + } + + IF( ( psLCLDEncoder->pppiQLCLDReal[n] = (Word32 **) malloc( LCLD_BLOCKS_PER_FRAME * sizeof( Word32 * ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); + } + + IF( ( psLCLDEncoder->pppiQLCLDImag[n] = (Word32 **) malloc( LCLD_BLOCKS_PER_FRAME * sizeof( Word32 * ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); + } + + FOR( k = 0; k < LCLD_BLOCKS_PER_FRAME; k++ ) + { + IF( ( psLCLDEncoder->pppiRMSEnvelope[n][k] = (Word32 *) malloc( MAX_BANDS * sizeof( Word32 ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); + } + + IF( ( psLCLDEncoder->pppiSMR[n][k] = (Word32 *) malloc( MAX_BANDS * sizeof( Word32 ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); + } + + IF( ( psLCLDEncoder->pppiExcitation[n][k] = (Word32 *) malloc( MAX_BANDS * sizeof( Word32 ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); + } + + IF( ( psLCLDEncoder->pppiAlloc[n][k] = (Word32 *) malloc( MAX_BANDS * sizeof( Word32 ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); + } + + + IF( ( psLCLDEncoder->pppiLCLDSignReal[n][k] = (Word32 *) malloc( LCLD_BANDS * sizeof( Word32 ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); + } + + IF( ( psLCLDEncoder->pppiLCLDSignImag[n][k] = (Word32 *) malloc( LCLD_BANDS * sizeof( Word32 ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); + } + + IF( ( psLCLDEncoder->pppiQLCLDReal[n][k] = (Word32 *) malloc( LCLD_BANDS * sizeof( Word32 ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); + } + + IF( ( psLCLDEncoder->pppiQLCLDImag[n][k] = (Word32 *) malloc( LCLD_BANDS * sizeof( Word32 ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); + } + } + } + + IF( ( error = CreatePredictionEncoder_fx( &( psLCLDEncoder->psPredictionEncoder ), iChannels, psLCLDEncoder->iNumBlocks, L_deposit_l( iNumSubSets ), iMaxNumPredBands ) ) != IVAS_ERR_OK ) + { + return error; + } + + *psLCLDEncoder_out = psLCLDEncoder; + + return IVAS_ERR_OK; +} + + +/*------------------------------------------------------------------------------------------* + * Function DeleteLCLDEncoder() + * + * + *------------------------------------------------------------------------------------------*/ + +void DeleteLCLDEncoder( + LCLDEncoder *psLCLDEncoder ) +{ + Word32 k, n; + + IF( psLCLDEncoder != NULL ) + { + + IF( psLCLDEncoder->piMSFlags != NULL ) + { + free( psLCLDEncoder->piMSFlags ); + } + + IF( psLCLDEncoder->piNumGroups != NULL ) + { + free( psLCLDEncoder->piNumGroups ); + } + + IF( psLCLDEncoder->psRMSEnvelopeGrouping != NULL ) + { + DeleteRMSEnvelopeGrouping( psLCLDEncoder->psRMSEnvelopeGrouping ); + } + + IF( psLCLDEncoder->ppiGroupLengths != NULL ) + { + FOR( n = 0; n < psLCLDEncoder->iChannels; n++ ) + { + free( psLCLDEncoder->ppiGroupLengths[n] ); + } + free( psLCLDEncoder->ppiGroupLengths ); + } + IF( psLCLDEncoder->pppiRMSEnvelope != NULL ) + { + FOR( n = 0; n < psLCLDEncoder->iChannels; n++ ) + { + FOR( k = 0; k < LCLD_BLOCKS_PER_FRAME; k++ ) + { + free( psLCLDEncoder->pppiRMSEnvelope[n][k] ); + } + free( psLCLDEncoder->pppiRMSEnvelope[n] ); + } + free( psLCLDEncoder->pppiRMSEnvelope ); + } + + IF( psLCLDEncoder->pppiSMR != NULL ) + { + FOR( n = 0; n < psLCLDEncoder->iChannels; n++ ) + { + FOR( k = 0; k < LCLD_BLOCKS_PER_FRAME; k++ ) + { + free( psLCLDEncoder->pppiSMR[n][k] ); + } + free( psLCLDEncoder->pppiSMR[n] ); + } + free( psLCLDEncoder->pppiSMR ); + } + + IF( psLCLDEncoder->pppiExcitation != NULL ) + { + FOR( n = 0; n < psLCLDEncoder->iChannels; n++ ) + { + FOR( k = 0; k < LCLD_BLOCKS_PER_FRAME; k++ ) + { + free( psLCLDEncoder->pppiExcitation[n][k] ); + } + free( psLCLDEncoder->pppiExcitation[n] ); + } + free( psLCLDEncoder->pppiExcitation ); + } + + IF( psLCLDEncoder->pppiAlloc != NULL ) + { + FOR( n = 0; n < psLCLDEncoder->iChannels; n++ ) + { + FOR( k = 0; k < LCLD_BLOCKS_PER_FRAME; k++ ) + { + free( psLCLDEncoder->pppiAlloc[n][k] ); + } + free( psLCLDEncoder->pppiAlloc[n] ); + } + free( psLCLDEncoder->pppiAlloc ); + } + + IF( psLCLDEncoder->pppiLCLDSignReal != NULL ) + { + FOR( n = 0; n < psLCLDEncoder->iChannels; n++ ) + { + FOR( k = 0; k < LCLD_BLOCKS_PER_FRAME; k++ ) + { + free( psLCLDEncoder->pppiLCLDSignReal[n][k] ); + } + free( psLCLDEncoder->pppiLCLDSignReal[n] ); + } + free( psLCLDEncoder->pppiLCLDSignReal ); + } + + IF( psLCLDEncoder->pppiLCLDSignImag != NULL ) + { + FOR( n = 0; n < psLCLDEncoder->iChannels; n++ ) + { + FOR( k = 0; k < LCLD_BLOCKS_PER_FRAME; k++ ) + { + free( psLCLDEncoder->pppiLCLDSignImag[n][k] ); + } + free( psLCLDEncoder->pppiLCLDSignImag[n] ); + } + free( psLCLDEncoder->pppiLCLDSignImag ); + } + + IF( psLCLDEncoder->pppiQLCLDReal != NULL ) + { + FOR( n = 0; n < psLCLDEncoder->iChannels; n++ ) + { + FOR( k = 0; k < LCLD_BLOCKS_PER_FRAME; k++ ) + { + free( psLCLDEncoder->pppiQLCLDReal[n][k] ); + } + free( psLCLDEncoder->pppiQLCLDReal[n] ); + } + free( psLCLDEncoder->pppiQLCLDReal ); + } + + IF( psLCLDEncoder->pppiQLCLDImag != NULL ) + { + FOR( n = 0; n < psLCLDEncoder->iChannels; n++ ) + { + FOR( k = 0; k < LCLD_BLOCKS_PER_FRAME; k++ ) + { + free( psLCLDEncoder->pppiQLCLDImag[n][k] ); + } + free( psLCLDEncoder->pppiQLCLDImag[n] ); + } + free( psLCLDEncoder->pppiQLCLDImag ); + } + + DeletePredictionEncoder_fx( psLCLDEncoder->psPredictionEncoder ); + free( psLCLDEncoder ); + } + + return; +} + +/*------------------------------------------------------------------------------------------* + * Local function declarations + *------------------------------------------------------------------------------------------*/ + +static Word32 MSModeCalculation_fx( const Word32 iNumBlocks, const Word32 iNumBands, const Word32 *piBandwidths, Word32 ***pppfReal_fx, Word32 ***pppfImag_fx, Word16 Q_in, Word32 *piMSMode, Word32 *piLRPhaseDiff, Word32 *piMSPredCoef, const Word32 iAllowSidePred, const Word32 iRealOnlyOut, Word32 *piMSFlags ); +static void RemoveRMSEnvelope( const Word32 iNumBands, const Word32 *piBandwidths, const Word32 iNumGroups, const Word32 *piGroupLengths, Word32 **ppiRMSEnvelope, Word32 **ppfReal_fx, Word32 **ppfImag_fx ); +static Word32 CountLCLDBits( const Word32 iNumGroups, const Word32 *piGroupLengths, const Word32 iNumBands, const Word32 *piBandwidths, const Word32 *piPredEnable, Word32 **ppiAlloc, Word32 **ppiQReal, Word32 **ppiQImag ); + +static Word32 WriteHeaderInformation( const Word32 iNumBands, ISAR_SPLIT_REND_BITS_HANDLE pBits ); + +static Word32 WriteMSInformation( const Word32 iNumBands, const Word32 iMSMode, const Word32 *piMSFlags, const Word32 *piLRPhaseDiff, const Word32 *piMSPredCoef, Word32 iNumMSPredBands, ISAR_SPLIT_REND_BITS_HANDLE pBits ); + +static Word32 WriteGroupInformation( const Word32 iChannels, const Word32 iCommonGrouping, const Word32 *piNumGroups, Word32 **ppiGroupLengths, ISAR_SPLIT_REND_BITS_HANDLE pBits ); + +static Word32 WriteRMSEnvelope( const Word32 iChannels, const Word32 *piNumGroups, const Word32 iNumBands, Word32 ***pppiRMSEnvelope, ISAR_SPLIT_REND_BITS_HANDLE pBits ); + +static Word32 WriteAllocInformation( const Word32 iAllocOffset, ISAR_SPLIT_REND_BITS_HANDLE pBits ); + +static Word32 WriteLCLDData( const Word32 *piNumGroups, Word32 **ppiGroupLengths, const Word32 iNumBands, const Word32 iNumChannels, Word32 **ppiPredEnable, const Word32 iNumSubSets, const Word32 iSubSetId, Word32 ***pppiAlloc, Word32 ***pppiSignReal, Word32 ***pppiSignImag, Word32 ***pppiQReal, Word32 ***pppiQImag, ISAR_SPLIT_REND_BITS_HANDLE pBits ); +static Word32 ComputeAllocation( const Word32 iChannels, const Word32 *piNumGroups, Word32 **ppiGroupLengths, const Word32 iNumBands, const Word32 *piBandwidths, Word32 ***pppfReal_fx, Word32 ***pppfImag_fx, Word16 q_final, Word32 ***pppiSMR, const Word32 iAvailableBits, Word32 *piAllocOffset, Word32 ***pppiAlloc, Word32 ***pppiQReal, Word32 ***pppiQImag, Word32 ***pppiSignReal, Word32 ***pppiSignImag, PredictionEncoder *psPredictionEncoder ); +/*------------------------------------------------------------------------------------------* + * Function EncodeLCLDFrame() + * + * + *------------------------------------------------------------------------------------------*/ +Word32 EncodeLCLDFrame( + LCLDEncoder *psLCLDEncoder, + Word32 ***pppfLCLDReal_fx, + Word32 ***pppfLCLDImag_fx, + Word32 *piBitsWritten, + const Word32 available_bits, + ISAR_SPLIT_REND_BITS_HANDLE pBits, + Word16 *q_final ) +{ + Word32 n; + Word32 iAvailableBits, iBitsWritten; + Word32 iNumMSBands = 0; + Word32 iAudioBitsWritten; + + iAvailableBits = available_bits; // HCBR for now + iBitsWritten = 0; + assert( available_bits <= pBits->buf_len * 8 ); + IF( EQ_32( psLCLDEncoder->iRealOnlyOut, 1 ) ) + { + PackReal( psLCLDEncoder->iChannels, psLCLDEncoder->iNumBlocks * 2, pppfLCLDReal_fx, pppfLCLDImag_fx ); + } + /* Do MS calc here */ + IF( EQ_32( psLCLDEncoder->iChannels, 2 ) ) + { + iNumMSBands = MSModeCalculation_fx( psLCLDEncoder->iNumBlocks, + psLCLDEncoder->iNumBands, + psLCLDEncoder->piBandwidths, + pppfLCLDReal_fx, + pppfLCLDImag_fx, + *q_final, + &psLCLDEncoder->iMSMode, + psLCLDEncoder->piLRPhaseDiffs, + psLCLDEncoder->piMSPredCoefs, + psLCLDEncoder->iAllowSidePred, + psLCLDEncoder->iRealOnlyOut, + psLCLDEncoder->piMSFlags ); + IF( GT_32( psLCLDEncoder->iMSMode, 0 ) ) + { + psLCLDEncoder->iCommonGrouping = 1; // Make sure common grouping is enabled when MS is in use + } + } + /* Compute Grouping and RMS Envelopes */ + IF( EQ_32( psLCLDEncoder->iChannels, 2 ) && EQ_32( psLCLDEncoder->iCommonGrouping, 1 ) ) + { + ComputeEnvelopeGrouping( psLCLDEncoder->psRMSEnvelopeGrouping, + psLCLDEncoder->iChannels, + psLCLDEncoder->iNumBands, + psLCLDEncoder->piBandwidths, + pppfLCLDReal_fx, + pppfLCLDImag_fx, + &psLCLDEncoder->piNumGroups[0], + psLCLDEncoder->ppiGroupLengths[0], + psLCLDEncoder->pppiRMSEnvelope, + *q_final ); + psLCLDEncoder->piNumGroups[1] = psLCLDEncoder->piNumGroups[0]; + FOR( n = 0; n < psLCLDEncoder->piNumGroups[0]; n++ ) + { + psLCLDEncoder->ppiGroupLengths[1][n] = psLCLDEncoder->ppiGroupLengths[0][n]; + move32(); + } + } + ELSE + { + FOR( n = 0; n < psLCLDEncoder->iChannels; n++ ) + { + ComputeEnvelopeGrouping( psLCLDEncoder->psRMSEnvelopeGrouping, + psLCLDEncoder->iChannels, + psLCLDEncoder->iNumBands, + psLCLDEncoder->piBandwidths, + &pppfLCLDReal_fx[n], + &pppfLCLDImag_fx[n], + &psLCLDEncoder->piNumGroups[n], + psLCLDEncoder->ppiGroupLengths[n], + &psLCLDEncoder->pppiRMSEnvelope[n], *q_final ); + } + } + + FOR( n = 0; n < psLCLDEncoder->iChannels; n++ ) + { + RemoveRMSEnvelope( psLCLDEncoder->iNumBands, + psLCLDEncoder->piBandwidths, + psLCLDEncoder->piNumGroups[n], + (const Word32 *) psLCLDEncoder->ppiGroupLengths[n], + psLCLDEncoder->pppiRMSEnvelope[n], + pppfLCLDReal_fx[n], + pppfLCLDImag_fx[n] ); + } + *q_final = add( *q_final, 9 ); // Increasing the Q as it has changed inside the RemoveRMSEnvelope + + ComputePredictors_fx( psLCLDEncoder->psPredictionEncoder, pppfLCLDReal_fx, pppfLCLDImag_fx ); + + iBitsWritten = L_add( iBitsWritten, WriteHeaderInformation( psLCLDEncoder->iNumBands, pBits ) ); + + IF( EQ_32( psLCLDEncoder->iChannels, 2 ) ) + { + iBitsWritten = L_add( iBitsWritten, WriteMSInformation( psLCLDEncoder->iNumBands, + psLCLDEncoder->iMSMode, + (const Word32 *) psLCLDEncoder->piMSFlags, + (const Word32 *) psLCLDEncoder->piLRPhaseDiffs, + (const Word32 *) psLCLDEncoder->piMSPredCoefs, + iNumMSBands, + pBits ) ); + } + + + iBitsWritten = L_add( iBitsWritten, WritePredictors( psLCLDEncoder->psPredictionEncoder, pBits ) ); + + iBitsWritten = L_add( iBitsWritten, WriteGroupInformation( psLCLDEncoder->iChannels, psLCLDEncoder->iCommonGrouping, (const Word32 *) psLCLDEncoder->piNumGroups, psLCLDEncoder->ppiGroupLengths, pBits ) ); + + iBitsWritten = L_add( iBitsWritten, WriteRMSEnvelope( psLCLDEncoder->iChannels, (const Word32 *) psLCLDEncoder->piNumGroups, psLCLDEncoder->iNumBands, psLCLDEncoder->pppiRMSEnvelope, pBits ) ); + + + IF( EQ_32( psLCLDEncoder->iChannels, 2 ) && EQ_32( psLCLDEncoder->iCommonGrouping, 1 ) ) + { + Word32 k; + FOR( k = 0; k < psLCLDEncoder->piNumGroups[0]; k++ ) + { + PerceptualModelStereo_fx( psLCLDEncoder->iNumBands, + psLCLDEncoder->piMSFlags, + psLCLDEncoder->pppiRMSEnvelope[0][k], + psLCLDEncoder->pppiRMSEnvelope[1][k], + psLCLDEncoder->pppiExcitation[0][k], + psLCLDEncoder->pppiExcitation[1][k], + psLCLDEncoder->pppiSMR[0][k], + psLCLDEncoder->pppiSMR[1][k] ); + } + } + ELSE + { + FOR( n = 0; n < psLCLDEncoder->iChannels; n++ ) + { + Word32 k; + FOR( k = 0; k < psLCLDEncoder->piNumGroups[n]; k++ ) + { + PerceptualModel_fx( psLCLDEncoder->iNumBands, + psLCLDEncoder->pppiRMSEnvelope[n][k], + psLCLDEncoder->pppiExcitation[n][k], + psLCLDEncoder->pppiSMR[n][k] ); + } + } + } +#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 = L_sub( iAvailableBits, iBitsWritten ); + + ComputeAllocation( psLCLDEncoder->iChannels, + (const Word32 *) psLCLDEncoder->piNumGroups, + psLCLDEncoder->ppiGroupLengths, + psLCLDEncoder->iNumBands, + psLCLDEncoder->piBandwidths, + pppfLCLDReal_fx, + pppfLCLDImag_fx, + *q_final, + psLCLDEncoder->pppiSMR, + iAvailableBits, + &psLCLDEncoder->iAllocOffset, + psLCLDEncoder->pppiAlloc, + psLCLDEncoder->pppiQLCLDReal, + psLCLDEncoder->pppiQLCLDImag, + psLCLDEncoder->pppiLCLDSignReal, + psLCLDEncoder->pppiLCLDSignImag, + psLCLDEncoder->psPredictionEncoder ); + + iBitsWritten = L_add( iBitsWritten, WriteAllocInformation( psLCLDEncoder->iAllocOffset, + pBits ) ); + iAudioBitsWritten = iBitsWritten; + iBitsWritten = L_add( iBitsWritten, WriteLCLDData( psLCLDEncoder->piNumGroups, + psLCLDEncoder->ppiGroupLengths, + psLCLDEncoder->iNumBands, + psLCLDEncoder->iChannels, + psLCLDEncoder->psPredictionEncoder->ppiPredBandEnable, + psLCLDEncoder->psPredictionEncoder->iNumSubSets, + psLCLDEncoder->psPredictionEncoder->iSubSetId, + psLCLDEncoder->pppiAlloc, + psLCLDEncoder->pppiLCLDSignReal, + psLCLDEncoder->pppiLCLDSignImag, + psLCLDEncoder->pppiQLCLDReal, + psLCLDEncoder->pppiQLCLDImag, + pBits ) ); + *piBitsWritten = iBitsWritten; + move32(); + iAudioBitsWritten = L_sub( iBitsWritten, iAudioBitsWritten ); + + UpdatePredictionSubSetId( psLCLDEncoder->psPredictionEncoder ); + + return 0; +} + +/*------------------------------------------------------------------------------------------* + * Function GetNumGroups() + * + * + *------------------------------------------------------------------------------------------*/ + +Word32 GetNumGroups( LCLDEncoder *psLCLDEncoder ) +{ + return psLCLDEncoder->piNumGroups[0]; +} + + +/*------------------------------------------------------------------------------------------* + * Local functions + * + * + *------------------------------------------------------------------------------------------*/ + +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 Word32 MSModeCalculation_fx( + const Word32 iNumBlocks, + const Word32 iNumBands, + const Word32 *piBandwidths, + /*float ***pppfReal, + float ***pppfImag,*/ + Word32 ***pppfReal_fx, + Word32 ***pppfImag_fx, + Word16 Q_in, + Word32 *piMSMode, + Word32 *piLRPhaseDiffs, + Word32 *piMSPredCoefs, + const Word32 iAllowSidePred, + const Word32 iRealOnlyOut, + Word32 *piMSFlags ) +{ + Word32 b; + Word32 iFBOffset; + Word32 iNumMSBands; + Word32 iMSPredType; + /*float fMSBitGain = 0.0f; + float pfMSPredBitGain[3] = { 0.0f }; + float fPred;*/ + Word32 fMSBitGain_fx = 0; + Word32 pfMSPredBitGain_fx[3] = { 0 }; + Word32 fPred_fx; + Word32 piMSPredFlags0[MAX_BANDS] = { 0 }; + Word32 piMSPredFlags1[MAX_BANDS] = { 0 }; + Word32 piMSPredFlags2[MAX_BANDS] = { 0 }; + Word32 *ppiMSPredFlags[3]; + Word32 piMSPredCoefs0[MAX_BANDS] = { 0 }; + Word32 piMSPredCoefs1[MAX_BANDS] = { 0 }; + Word32 piMSPredCoefs2[MAX_BANDS] = { 0 }; + Word32 *ppiMSPredCoefs[3]; + Word32 piMSPredPhase0[MAX_BANDS] = { 0 }; + Word32 piMSPredPhase1[MAX_BANDS] = { 0 }; + Word32 piMSPredPhase2[MAX_BANDS] = { 0 }; + Word32 *ppiMSPredPhase[3]; + Word32 iMsInfoBits; + Word32 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 */ + const Word32 feps_fx = 1; // is this correct? + move32(); + Word32 fBitsFactor_fx = 1783446565; /* = 1/log10(2) (Q29), from dB/10 to bits assuming 1 bit per log2(SNR) or 1 bit per 3dB SNR */ + move32(); + IF( LT_32( 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 */ + fBitsFactor_fx = Mpy_32_32( fBitsFactor_fx, L_add( 1503238553, W_extract_l( W_mult0_32_32( L_sub( iNumBlocks, 4 ), 596523235 ) ) ) ); /* Tuning for relatively higher side rate due to shorter frame length */ + } + + ppiMSPredFlags[0] = piMSPredFlags0; + move32(); + ppiMSPredFlags[1] = piMSPredFlags1; + move32(); + ppiMSPredFlags[2] = piMSPredFlags2; + move32(); + ppiMSPredCoefs[0] = piMSPredCoefs0; + move32(); + ppiMSPredCoefs[1] = piMSPredCoefs1; + move32(); + ppiMSPredCoefs[2] = piMSPredCoefs2; + move32(); + ppiMSPredPhase[0] = piMSPredPhase0; + move32(); + ppiMSPredPhase[1] = piMSPredPhase1; + move32(); + ppiMSPredPhase[2] = piMSPredPhase2; + move32(); + *piMSMode = MS_OFF; + move32(); + iFBOffset = 0; + move32(); + iNumMSBands = 0; + move32(); + FOR( b = 0; b < iNumBands; b++ ) + { + Word32 n; + /*float fLeftEnergy; + float fRightEnergy; + float fMidEnergy; + float fSideEnergy; + float fLRRatio; + float fMSRatio; + float pfMSPredRatio[3] = { 0.0f }; + float fMidEnergyPred; + float fSideEnergyPred; + float fLRCovReal = 0.0f; + float fLRCovImag = 0.0f;*/ + Word32 fLeftEnergy_fx; + Word32 fRightEnergy_fx; + Word32 fMidEnergy_fx; + Word32 fSideEnergy_fx; + Word64 fLeftEnergy_fx64; + Word64 fRightEnergy_fx64; + Word64 fMidEnergy_fx64; + Word64 fSideEnergy_fx64; + Word32 fLRRatio_fx; + Word32 fMSRatio_fx; + Word32 pfMSPredRatio_fx[3] = { 0 }; + Word32 fMidEnergyPred_fx; + Word32 fSideEnergyPred_fx; + Word32 fLRCovReal_fx = 0; + Word32 fLRCovImag_fx = 0; + Word64 fLRCovReal_fx64 = 0; + Word64 fLRCovImag_fx64 = 0; + Word32 iPhase; + Word32 iPred; + Word32 tabIdx = 0; + // float fNumLines = (float)(iRealOnlyOut == 1 ? iNumBlocks * piBandwidths[b] * 4 : iNumBlocks * piBandwidths[b] * 2); /* per band per channel */ + // float fLevelToSMRdBFactor = (float) c_aiDefaultTheta48[b] / (float) ( 1 << PERCEPTUAL_MODEL_SLGAIN_SHIFT ); /* frequency dependent SMR slope in psy model */ + Word32 fNumLines_fx = iRealOnlyOut == 1 ? L_shl( iNumBlocks * piBandwidths[b], 2 ) : L_shl( iNumBlocks * piBandwidths[b], 1 ); /* per band per channel */ + Word32 fLevelToSMRdBFactor_fx = L_shl( c_aiDefaultTheta48[b], 23 ); /* frequency dependent SMR slope in psy model Q23:sub(Q31, PERCEPTUAL_MODEL_SLGAIN_SHIFT) */ + fLeftEnergy_fx = 0; + fRightEnergy_fx = 0; + fMidEnergy_fx = 0; + fSideEnergy_fx = 0; + fLeftEnergy_fx64 = 0; + fRightEnergy_fx64 = 0; + fMidEnergy_fx64 = 0; + fSideEnergy_fx64 = 0; + Word16 Q_en_tmp = 63; + + FOR( n = 0; n < piBandwidths[b]; n++ ) + { + Word32 k; + FOR( k = 0; k < iNumBlocks; k++ ) + { + /*float fMidReal; + float fMidImag; + float fSideReal; + float fSideImag;*/ + Word32 fMidReal_fx; + Word32 fMidImag_fx; + Word32 fSideReal_fx; + Word32 fSideImag_fx; + + // fMidReal = 0.5f * ( pppfReal[0][k][iFBOffset] + pppfReal[1][k][iFBOffset] ); + fMidReal_fx = L_shr( L_add( pppfReal_fx[0][k][iFBOffset], pppfReal_fx[1][k][iFBOffset] ), 1 ); + // fMidImag = 0.5f * ( pppfImag[0][k][iFBOffset] + pppfImag[1][k][iFBOffset] ); + fMidImag_fx = L_shr( L_add( pppfImag_fx[0][k][iFBOffset], pppfImag_fx[1][k][iFBOffset] ), 1 ); + // fSideReal = 0.5f * ( pppfReal[0][k][iFBOffset] - pppfReal[1][k][iFBOffset] ); + fSideReal_fx = L_shr( L_sub( pppfReal_fx[0][k][iFBOffset], pppfReal_fx[1][k][iFBOffset] ), 1 ); + // fSideImag = 0.5f * ( pppfImag[0][k][iFBOffset] - pppfImag[1][k][iFBOffset] ); + fSideImag_fx = L_shr( L_sub( pppfImag_fx[0][k][iFBOffset], pppfImag_fx[1][k][iFBOffset] ), 1 ); + + // fLeftEnergy += ( pppfReal[0][k][iFBOffset] * pppfReal[0][k][iFBOffset] + pppfImag[0][k][iFBOffset] * pppfImag[0][k][iFBOffset] ); + fLeftEnergy_fx64 = W_add( fLeftEnergy_fx64, W_add( W_mult0_32_32( pppfReal_fx[0][k][iFBOffset], pppfReal_fx[0][k][iFBOffset] ), W_mult0_32_32( pppfImag_fx[0][k][iFBOffset], pppfImag_fx[0][k][iFBOffset] ) ) ); + // fRightEnergy += ( pppfReal[1][k][iFBOffset] * pppfReal[1][k][iFBOffset] + pppfImag[1][k][iFBOffset] * pppfImag[1][k][iFBOffset] ); + fRightEnergy_fx64 = W_add( fRightEnergy_fx64, W_add( W_mult0_32_32( pppfReal_fx[1][k][iFBOffset], pppfReal_fx[1][k][iFBOffset] ), W_mult0_32_32( pppfImag_fx[1][k][iFBOffset], pppfImag_fx[1][k][iFBOffset] ) ) ); + // fMidEnergy += ( fMidReal * fMidReal + fMidImag * fMidImag ); + fMidEnergy_fx64 = W_add( fMidEnergy_fx64, W_add( W_mult0_32_32( fMidReal_fx, fMidReal_fx ), W_mult0_32_32( fMidImag_fx, fMidImag_fx ) ) ); + // fSideEnergy += ( fSideReal * fSideReal + fSideImag * fSideImag ); + fSideEnergy_fx64 = W_add( fSideEnergy_fx64, W_add( W_mult0_32_32( fSideReal_fx, fSideReal_fx ), W_mult0_32_32( fSideImag_fx, fSideImag_fx ) ) ); + + // fLRCovReal += ( pppfReal[0][k][iFBOffset] * pppfReal[1][k][iFBOffset] + pppfImag[0][k][iFBOffset] * pppfImag[1][k][iFBOffset] ); + fLRCovReal_fx64 = W_add( fLRCovReal_fx64, W_add( W_mult0_32_32( pppfReal_fx[0][k][iFBOffset], pppfReal_fx[1][k][iFBOffset] ), W_mult0_32_32( pppfImag_fx[0][k][iFBOffset], pppfImag_fx[1][k][iFBOffset] ) ) ); + // fLRCovImag += ( pppfImag[0][k][iFBOffset] * pppfReal[1][k][iFBOffset] - pppfImag[1][k][iFBOffset] * pppfReal[0][k][iFBOffset] ); + fLRCovImag_fx64 = W_add( fLRCovImag_fx64, W_sub( W_mult0_32_32( pppfImag_fx[0][k][iFBOffset], pppfReal_fx[1][k][iFBOffset] ), W_mult0_32_32( pppfImag_fx[1][k][iFBOffset], pppfReal_fx[0][k][iFBOffset] ) ) ); + } + + iFBOffset++; + } + Q_en_tmp = min( Q_en_tmp, W_norm( fLeftEnergy_fx64 ) ); + Q_en_tmp = min( Q_en_tmp, W_norm( fRightEnergy_fx64 ) ); + Q_en_tmp = min( Q_en_tmp, W_norm( fMidEnergy_fx64 ) ); + Q_en_tmp = min( Q_en_tmp, W_norm( fSideEnergy_fx64 ) ); + Q_en_tmp = min( Q_en_tmp, W_norm( fLRCovReal_fx64 ) ); + Q_en_tmp = min( Q_en_tmp, W_norm( fLRCovImag_fx64 ) ); + Q_en_tmp = sub( Q_en_tmp, 2 ); + fLeftEnergy_fx = W_extract_h( W_shl( fLeftEnergy_fx64, Q_en_tmp ) ); + fRightEnergy_fx = W_extract_h( W_shl( fRightEnergy_fx64, Q_en_tmp ) ); + fMidEnergy_fx = W_extract_h( W_shl( fMidEnergy_fx64, Q_en_tmp ) ); + fSideEnergy_fx = W_extract_h( W_shl( fSideEnergy_fx64, Q_en_tmp ) ); + fLRCovReal_fx = W_extract_h( W_shl( fLRCovReal_fx64, Q_en_tmp ) ); + fLRCovImag_fx = W_extract_h( W_shl( fLRCovImag_fx64, Q_en_tmp ) ); + Word16 Q_en = add( shl( Q_in, 1 ), sub( Q_en_tmp, 32 ) ) /*2 * Q_in - 31 - 2*/; + /* M/S prediction without phase alignment*/ + // fPred = 0.25f * ( fLeftEnergy - fRightEnergy ) / ( fMidEnergy + feps ); + // iPred = quantPred(fPred); + // fPred = dequantPred(iPred); + Word16 exp; + fPred_fx = BASOP_Util_Divide3232_Scale( L_sub( fLeftEnergy_fx, fRightEnergy_fx ), L_add( fMidEnergy_fx, feps_fx ), &exp ); + exp = sub( exp, 2 ); //*0.25f + fPred_fx = L_shl( fPred_fx, 16 ); + iPred = quantPred_fx( fPred_fx, exp ); + fPred_fx = dequantPred_fx( iPred ); // Q31 + // fSideEnergyPred = fSideEnergy + ( fPred * fPred * fMidEnergy - 2.0f * fPred * 0.25f * ( fLeftEnergy - fRightEnergy ) ); + fSideEnergyPred_fx = L_add( fSideEnergy_fx, + L_sub( Mpy_32_32( Mpy_32_32( fPred_fx, fPred_fx ), fMidEnergy_fx ), + L_shr( Mpy_32_32( fPred_fx, L_sub( fLeftEnergy_fx, fRightEnergy_fx ) ), 1 ) ) ); + fSideEnergyPred_fx = max( fSideEnergyPred_fx, 0 ); + + ppiMSPredCoefs[MS_PRED_ONLY][b] = iPred; + move32(); + ppiMSPredPhase[MS_PRED_ONLY][b] = 0; + move32(); + // pfMSPredRatio[MS_PRED_ONLY] = log10f( ( fMidEnergy + feps ) / ( fSideEnergyPred + feps ) ); + pfMSPredRatio_fx[MS_PRED_ONLY] = Mpy_32_32( L_sub( BASOP_Util_Log2( L_add( fMidEnergy_fx, feps_fx ) ), BASOP_Util_Log2( L_add( fSideEnergyPred_fx, feps_fx ) ) ), LOG10_2_FX ); // Q25 + // printf("%f ", (float)pfMSPredRatio_fx[MS_PRED_ONLY] / (1 << 25)); + + /* Phase alignment*/ + iPhase = 0; + move32(); + // if ( fLRCovReal * fLRCovReal + fLRCovImag * fLRCovImag > 0.5f * fLeftEnergy * fRightEnergy ) + IF( GT_32( L_add( Mpy_32_32( fLRCovReal_fx, fLRCovReal_fx ), Mpy_32_32( fLRCovImag_fx, fLRCovImag_fx ) ), L_shr( Mpy_32_32( fLeftEnergy_fx, fRightEnergy_fx ), 1 ) ) ) + { + // float fPhase = atan2f( fLRCovImag, fLRCovReal ); + Word32 fPhase_fx = BASOP_util_atan2( fLRCovImag_fx, fLRCovReal_fx, 0 ); + exp = sub( 18, norm_l( fPhase_fx ) ); + fPhase_fx = L_shl( fPhase_fx, norm_l( fPhase_fx ) ); // Q31 + // iPhase = quantPhase( fPhase ); + iPhase = quantPhase_fx( fPhase_fx, exp ); + } + + /* adjust covariance */ + tabIdx = L_sub( iPhase, PHASE_MIN_VAL ); + // cplxmult( &fLRCovReal, &fLRCovImag, c_afRotRealImag[tabIdx][0], -c_afRotRealImag[tabIdx][1] ); + cplxmult_fx( &fLRCovReal_fx, &fLRCovImag_fx, c_afRotRealImag_fx[tabIdx][0], -c_afRotRealImag_fx[tabIdx][1] ); + + /* compute MS prediction coefficient based on adjusted covariance */ + // fMidEnergyPred = 0.25f * ( fLeftEnergy + fRightEnergy + 2.0f * fLRCovReal ); + fMidEnergyPred_fx = L_add( L_add( L_shr_r( fLeftEnergy_fx, 2 ), L_shr_r( fRightEnergy_fx, 2 ) ), L_shr( fLRCovReal_fx, 1 ) ); // Q_en + // fSideEnergyPred = 0.25f * ( fLeftEnergy + fRightEnergy - 2.0f * fLRCovReal ); + fSideEnergyPred_fx = L_sub( L_add( L_shr_r( fLeftEnergy_fx, 2 ), L_shr_r( fRightEnergy_fx, 2 ) ), L_shr( fLRCovReal_fx, 1 ) ); // Q_en + fSideEnergyPred_fx = L_max( fSideEnergyPred_fx, 0 ); + + /* M/S with LR phase alignment but without prediction */ + ppiMSPredCoefs[MS_PHASE_ONLY][b] = 0; + move32(); + ppiMSPredPhase[MS_PHASE_ONLY][b] = iPhase; + move32(); + // pfMSPredRatio[MS_PHASE_ONLY] = log10f( ( fMidEnergyPred + feps ) / ( fSideEnergyPred + feps ) ); + pfMSPredRatio_fx[MS_PHASE_ONLY] = Mpy_32_32( L_sub( BASOP_Util_Log2( L_add( fMidEnergyPred_fx, feps_fx ) ), BASOP_Util_Log2( L_add( fSideEnergyPred_fx, feps_fx ) ) ), LOG10_2_FX ); // Q25 + // printf("%f ", (float)pfMSPredRatio_fx[MS_PHASE_ONLY] / (1 << 25)); + + /* M/S with LR phase alignment and prediction */ + // fPred = fMidEnergyPred == 0.0f ? 0.0f : 0.25f * ( fLeftEnergy - fRightEnergy ) / fMidEnergyPred; + fPred_fx = fMidEnergyPred_fx == 0 ? 0 : BASOP_Util_Divide3232_Scale( L_sub( fLeftEnergy_fx, fRightEnergy_fx ), fMidEnergyPred_fx, &exp ); + exp = sub( exp, 2 ); //*0.25f + fPred_fx = L_shl( fPred_fx, 16 ); + // iPred = quantPred( fPred ); + iPred = quantPred_fx( fPred_fx, exp ); + // fPred = dequantPred( iPred ); + fPred_fx = dequantPred_fx( iPred ); + // fSideEnergyPred += ( fPred * fPred * fMidEnergyPred - 2.0f * fPred * 0.25f * ( fLeftEnergy - fRightEnergy ) ); + fSideEnergyPred_fx = L_add( fSideEnergyPred_fx, + L_sub( Mpy_32_32( Mpy_32_32( fPred_fx, fPred_fx ), fMidEnergyPred_fx ), + L_shr( Mpy_32_32( fPred_fx, L_sub( fLeftEnergy_fx, fRightEnergy_fx ) ), 1 ) ) ); + fSideEnergyPred_fx = max( fSideEnergyPred_fx, 0 ); + /* -= fPred * fPred * fMidEnergyPred doesn't work because fPred is quantized and does not match MS/MM exactly */ + ppiMSPredCoefs[MS_PHASE_AND_PRED][b] = iPred; + move32(); + ppiMSPredPhase[MS_PHASE_AND_PRED][b] = iPhase; + move32(); + // pfMSPredRatio[MS_PHASE_AND_PRED] = log10f( ( fMidEnergyPred + feps ) / ( fSideEnergyPred + feps ) ); + pfMSPredRatio_fx[MS_PHASE_AND_PRED] = Mpy_32_32( L_sub( BASOP_Util_Log2( L_add( fMidEnergyPred_fx, feps_fx ) ), BASOP_Util_Log2( L_add( fSideEnergyPred_fx, feps_fx ) ) ), LOG10_2_FX ); // Q25 + // printf("%f ", (float)pfMSPredRatio_fx[MS_PHASE_AND_PRED] / (1 << 25)); + + /* Plain M/S */ + // fLeftEnergy = log10f( fLeftEnergy + feps ); + exp = sub( 31, Q_en ); // 31 - Q + fLeftEnergy_fx = Mpy_32_32( L_add( BASOP_Util_Log2( L_add( fLeftEnergy_fx, feps_fx ) ), L_shl( exp, 25 ) ), LOG10_2_FX ); // Q25 + // fRightEnergy = log10f( fRightEnergy + feps ); + fRightEnergy_fx = Mpy_32_32( L_add( BASOP_Util_Log2( L_add( fRightEnergy_fx, feps_fx ) ), L_shl( exp, 25 ) ), LOG10_2_FX ); // Q25 + // fMidEnergy = log10f( fMidEnergy + feps ); + fMidEnergy_fx = Mpy_32_32( L_add( BASOP_Util_Log2( L_add( fMidEnergy_fx, feps_fx ) ), L_shl( exp, 25 ) ), LOG10_2_FX ); // Q25 + // fSideEnergy = log10f( fSideEnergy + feps ); + fSideEnergy_fx = Mpy_32_32( L_add( BASOP_Util_Log2( L_add( fSideEnergy_fx, feps_fx ) ), L_shl( exp, 25 ) ), LOG10_2_FX ); // Q25 + + // fLRRatio = ( fLeftEnergy > fRightEnergy ? fLeftEnergy - fRightEnergy : fRightEnergy - fLeftEnergy ); + fLRRatio_fx = ( fLeftEnergy_fx > fRightEnergy_fx ? L_sub( fLeftEnergy_fx, fRightEnergy_fx ) : L_sub( fRightEnergy_fx, fLeftEnergy_fx ) ); // Q25 + // fMSRatio = ( fMidEnergy > fSideEnergy ? fMidEnergy - fSideEnergy : fSideEnergy - fMidEnergy ); + fMSRatio_fx = ( fMidEnergy_fx > fSideEnergy_fx ? L_sub( fMidEnergy_fx, fSideEnergy_fx ) : L_sub( fSideEnergy_fx, fMidEnergy_fx ) ); // Q25 + + // if ( fMSRatio > fLRRatio ) + IF( GT_32( fMSRatio_fx, fLRRatio_fx ) ) + { + iNumMSBands++; + piMSFlags[b] = 1; + move32(); + // fMSBitGain += fNumLines * ( fMSRatio - fLRRatio ) * fLevelToSMRdBFactor * fBitsFactor; + fMSBitGain_fx = L_add( fMSBitGain_fx, W_extract_l( W_shr( W_mult0_32_32( fNumLines_fx, Mpy_32_32( Mpy_32_32( L_sub( fMSRatio_fx, fLRRatio_fx ), fLevelToSMRdBFactor_fx ), fBitsFactor_fx ) ), 7 ) ) ); // Q16 + } + ELSE + { + piMSFlags[b] = 0; + move32(); + } + piLRPhaseDiffs[b] = 0; + move32(); + piMSPredCoefs[b] = 0; + move32(); + + /* 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++ ) + { + // if ( pfMSPredRatio[iMSPredType] > fLRRatio ) + IF( GT_32( pfMSPredRatio_fx[iMSPredType], fLRRatio_fx ) ) + { + ppiMSPredFlags[iMSPredType][b] = 1; + move32(); + // pfMSPredBitGain[iMSPredType] += fNumLines * ( pfMSPredRatio[iMSPredType] - fLRRatio ) * fLevelToSMRdBFactor * fBitsFactor; + pfMSPredBitGain_fx[iMSPredType] = L_add( pfMSPredBitGain_fx[iMSPredType], + W_extract_l( W_shr( W_mult0_32_32( fNumLines_fx, + Mpy_32_32( Mpy_32_32( L_sub( pfMSPredRatio_fx[iMSPredType], fLRRatio_fx ), fLevelToSMRdBFactor_fx ), + fBitsFactor_fx ) ), + 7 ) ) ); // Q16 + } + } + } + Word16 q_fMSBitGain_fx = Q16; + move16(); + Word16 q_pfMSPredBitGain_fx = Q16; // Q23-7 + move16(); + /* remove signalling cost from bit gains */ + FOR( iMSPredType = 0; iMSPredType < 3; iMSPredType++ ) + { + piMsPredInfoBits[iMSPredType] = CountMSBits( iNumBands, MS_PRED, ppiMSPredFlags[iMSPredType], ppiMSPredPhase[iMSPredType], ppiMSPredCoefs[iMSPredType] ); + // pfMSPredBitGain[iMSPredType] = max( pfMSPredBitGain[iMSPredType] - piMsPredInfoBits[iMSPredType], 0.0f ); + pfMSPredBitGain_fx[iMSPredType] = max( pfMSPredBitGain_fx[iMSPredType] - L_shl( piMsPredInfoBits[iMSPredType], q_pfMSPredBitGain_fx ), 0 ); + } + + /* find the best M/S Pred type */ + IF( EQ_32( iRealOnlyOut, 1 ) ) + { + iMSPredType = MS_PRED_ONLY; + move32(); + } + ELSE + { + iMSPredType = MS_PHASE_AND_PRED; + move32(); + // iMSPredType = ( pfMSPredBitGain[MS_PRED_ONLY] > pfMSPredBitGain[iMSPredType] ? MS_PRED_ONLY : iMSPredType ); + iMSPredType = ( pfMSPredBitGain_fx[MS_PRED_ONLY] > pfMSPredBitGain_fx[iMSPredType] ? MS_PRED_ONLY : iMSPredType ); + // iMSPredType = ( pfMSPredBitGain[MS_PHASE_ONLY] > pfMSPredBitGain[iMSPredType] ? MS_PHASE_ONLY : iMSPredType ); + iMSPredType = ( pfMSPredBitGain_fx[MS_PHASE_ONLY] > pfMSPredBitGain_fx[iMSPredType] ? MS_PHASE_ONLY : iMSPredType ); + } + + /* plain M/S */ + iMsInfoBits = CountMSBits( iNumBands, MS_SOME, piMSFlags, NULL, NULL ); + // fMSBitGain = max( fMSBitGain - iMsInfoBits, 0.0f ); + fMSBitGain_fx = L_max( L_sub( fMSBitGain_fx, L_shl( iMsInfoBits, q_fMSBitGain_fx ) ), 0 ); // Q_en -2 + // if ( iAllowSidePred && pfMSPredBitGain[iMSPredType] > 1.1f * fMSBitGain ) + test(); + IF( iAllowSidePred && GT_32( L_shr_r( pfMSPredBitGain_fx[iMSPredType], sub( q_pfMSPredBitGain_fx, q_fMSBitGain_fx ) ), L_add( fMSBitGain_fx, Mpy_32_32( fMSBitGain_fx, 214748364 ) ) ) ) + { + *piMSMode = MS_PRED; + move32(); + iNumMSBands = 0; + move32(); + FOR( b = 0; b < iNumBands; b++ ) + { + piMSFlags[b] = ppiMSPredFlags[iMSPredType][b]; + IF( EQ_32( piMSFlags[b], 1 ) ) + { + piMSPredCoefs[b] = ppiMSPredCoefs[iMSPredType][b]; + move32(); + piLRPhaseDiffs[b] = ppiMSPredPhase[iMSPredType][b]; + move32(); + iNumMSBands++; + } + ELSE + { + piMSPredCoefs[b] = 0; + move32(); + piLRPhaseDiffs[b] = 0; + move32(); + } + } + } + ELSE IF( EQ_32( iNumMSBands, iNumBands ) ) + { + *piMSMode = MS_ALL; + move32(); + } + ELSE IF( GT_32( iNumMSBands, 0 ) ) + { + *piMSMode = MS_SOME; + move32(); + } + ELSE + { + *piMSMode = MS_OFF; + move32(); + } +#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( NE_32( *piMSMode, MS_OFF ) ) + { + iFBOffset = 0; + move32(); + FOR( b = 0; b < iNumBands; b++ ) + { + IF( EQ_32( piMSFlags[b], 1 ) ) + { + Word32 n; + Word32 phaseIdx; + phaseIdx = L_sub( piLRPhaseDiffs[b], PHASE_MIN_VAL ); + // fPred = dequantPred( piMSPredCoefs[b] ); + fPred_fx = dequantPred_fx( piMSPredCoefs[b] ); // Q31 + FOR( n = 0; n < piBandwidths[b]; n++ ) + { + Word32 k; + FOR( k = 0; k < iNumBlocks; k++ ) + { + /*float fMidReal; + float fMidImag; + float fSideReal; + float fSideImag;*/ + Word32 fMidReal_fx; + Word32 fMidImag_fx; + Word32 fSideReal_fx; + Word32 fSideImag_fx; + + IF( EQ_32( *piMSMode, MS_PRED ) ) + { + // cplxmult( &pppfReal[1][k][iFBOffset], &pppfImag[1][k][iFBOffset], c_afRotRealImag[phaseIdx][0], c_afRotRealImag[phaseIdx][1] ); + cplxmult_fx( &pppfReal_fx[1][k][iFBOffset], &pppfImag_fx[1][k][iFBOffset], c_afRotRealImag_fx[phaseIdx][0], c_afRotRealImag_fx[phaseIdx][1] ); + } + + // fMidReal = 0.5f * ( pppfReal[0][k][iFBOffset] + pppfReal[1][k][iFBOffset] ); + fMidReal_fx = L_shr( L_add( pppfReal_fx[0][k][iFBOffset], pppfReal_fx[1][k][iFBOffset] ), 1 ); + // fMidImag = 0.5f * ( pppfImag[0][k][iFBOffset] + pppfImag[1][k][iFBOffset] ); + fMidImag_fx = L_shr( L_add( pppfImag_fx[0][k][iFBOffset], pppfImag_fx[1][k][iFBOffset] ), 1 ); + // fSideReal = 0.5f * ( pppfReal[0][k][iFBOffset] - pppfReal[1][k][iFBOffset] ); + fSideReal_fx = L_shr( L_sub( pppfReal_fx[0][k][iFBOffset], pppfReal_fx[1][k][iFBOffset] ), 1 ); + // fSideImag = 0.5f * ( pppfImag[0][k][iFBOffset] - pppfImag[1][k][iFBOffset] ); + fSideImag_fx = L_shr( L_sub( pppfImag_fx[0][k][iFBOffset], pppfImag_fx[1][k][iFBOffset] ), 1 ); + + IF( EQ_32( *piMSMode, MS_PRED ) ) + { + // fSideReal -= fPred * fMidReal; + fSideReal_fx = L_sub( fSideReal_fx, Mpy_32_32( fPred_fx, fMidReal_fx ) ); + // fSideImag -= fPred * fMidImag; + fSideImag_fx = L_sub( fSideImag_fx, Mpy_32_32( fPred_fx, fMidImag_fx ) ); + } + + pppfReal_fx[0][k][iFBOffset] = fMidReal_fx; + move32(); + pppfReal_fx[1][k][iFBOffset] = fSideReal_fx; + move32(); + pppfImag_fx[0][k][iFBOffset] = fMidImag_fx; + move32(); + pppfImag_fx[1][k][iFBOffset] = fSideImag_fx; + move32(); + } + iFBOffset++; + } + } + ELSE + { + iFBOffset = L_add( iFBOffset, piBandwidths[b] ); + } + } + } +#ifdef DEBUG_WRITE_MS_PRED + { + static FILE *fid; + if ( !fid ) + fid = fopen( "ms_enc.txt", "wt" ); + writeMSPred( piLRPhaseDiffs, piMSPredCoefs, *piMSMode, iNumMSBands, iNumBands, fid, piMSFlags ); + } +#endif + IF( EQ_32( *piMSMode, MS_PRED ) ) + { + /* Differential Coding of Phase Data*/ + PrepEncode( piLRPhaseDiffs, piMSFlags, iNumBands ); + PrepEncode( piMSPredCoefs, piMSFlags, iNumBands ); +#ifdef DEBUG_WRITE_MS_PRED + { + static FILE *fid; + if ( !fid ) + fid = fopen( "ms_pred_enc.txt", "wt" ); + writeMSPred( piLRPhaseDiffs, piMSPredCoefs, *piMSMode, iNumMSBands, iNumBands, fid, piMSFlags ); + } +#endif + /* Differential Coding*/ + EncodePhase( piLRPhaseDiffs, iNumMSBands, PHASE_DIFF_DIM ); + EncodePredCoef( piMSPredCoefs, iNumMSBands ); + } + + return iNumMSBands; +} +static void RemoveRMSEnvelope( + const Word32 iNumBands, + const Word32 *piBandwidths, + const Word32 iNumGroups, + const Word32 *piGroupLengths, + Word32 **ppiRMSEnvelope, + Word32 **ppfReal_fx, + Word32 **ppfImag_fx ) +{ + Word32 k, n, b, iFBOffset, m, iRMSEnv; + Word32 iBlockOffset; + Word32 fGain_fx; + Word16 fGain_exp; + iBlockOffset = 0; + move32(); + Word64 tmp; + FOR( n = 0; n < iNumGroups; n++ ) + { + FOR( k = 0; k < piGroupLengths[n]; k++ ) + { + iFBOffset = 0; + move32(); + FOR( b = 0; b < iNumBands; b++ ) + { + iRMSEnv = ppiRMSEnvelope[n][b]; + IF( EQ_32( L_add( ENV_RECONSTRUCT_TABLE_CENTER, iRMSEnv ) % 2, 0 ) ) + { + fGain_fx = 1073741824; // 2 ^ 30 + move32(); + } + ELSE + { + fGain_fx = 1518500249; // sqrt(2) * 2 ^ 30 + move32(); + } + fGain_exp = c_afRMSEnvReconstructTable_exp[ENV_RECONSTRUCT_TABLE_CENTER - iRMSEnv]; + move16(); + FOR( m = 0; m < piBandwidths[b]; m++ ) + { + tmp = W_mult_32_32( fGain_fx, ppfReal_fx[iBlockOffset][iFBOffset] ); + tmp = W_shr( tmp, sub( fGain_exp, 8 ) ); // Q to (input_q -9) + ppfReal_fx[iBlockOffset][iFBOffset] = W_extract_l( tmp ); + move32(); + tmp = W_mult_32_32( fGain_fx, ppfImag_fx[iBlockOffset][iFBOffset] ); + tmp = W_shr( tmp, sub( fGain_exp, 8 ) ); // Q to (input_q -9) + ppfImag_fx[iBlockOffset][iFBOffset] = W_extract_l( tmp ); + move32(); + iFBOffset++; + } + } + iBlockOffset++; + } + } + + return; +} +static void QuantizeSpectrumDPCM_Opt( + const Word32 iNumGroups, + const Word32 *piGroupLengths, + const Word32 iNumBands, + const Word32 *piBandwidths, + Word32 **ppiAlloc, + Word32 **ppfReal_fx, + Word32 **ppfImag_fx, + Word16 q_final, + Word32 **ppiQReal, + Word32 **ppiQImag, + Word32 **ppiSignReal, + Word32 **ppiSignImag, + Word32 iNumSubSets, + Word32 iSubSetId, + Word32 *piPredEnable, + Word32 *pfA1Real_fx, + Word32 *pfA1Imag_fx, + Word32 *pfPredStateReal_fx, + Word32 *pfPredStateImag_fx ) +{ + Word32 b, n; + Word32 iFBOffset; + Word32 k, iAlloc; + Word32 iMaxQuantVal_fx; + Word32 fSCFGain_fx, fInvSCFGain_fx; + iFBOffset = 0; + Word32 ppiQReal_fx, ppiQImag_fx; + FOR( b = 0; b < iNumBands; b++ ) + { + Word32 m; + FOR( m = 0; m < piBandwidths[b]; m++ ) + { + Word32 iBlockOffset = 0; + IF( EQ_32( piPredEnable[iFBOffset], 1 ) ) + { + Word32 fReal_fx; + Word32 fImag_fx; + Word32 iSubset = iFBOffset % iNumSubSets; + Word32 fPrevReal_fx = 0; + Word32 fPrevImag_fx = 0; + IF( NE_32( iSubset, iSubSetId ) ) + { + /* run predictors across sub-frames */ + fPrevReal_fx = pfPredStateReal_fx[iFBOffset]; + move32(); + fPrevImag_fx = pfPredStateImag_fx[iFBOffset]; + move32(); + } + FOR( n = 0; n < iNumGroups; n++ ) + { + iAlloc = ppiAlloc[n][b]; + iMaxQuantVal_fx = c_aiQuantMaxValues_fx[iAlloc]; + fSCFGain_fx = c_afScaleFactor_fx[iAlloc]; + fInvSCFGain_fx = c_afInvScaleFactor_fx[iAlloc]; + FOR( k = 0; k < piGroupLengths[n]; k++ ) + { + /* prediction */ + fReal_fx = L_sub( Mpy_32_32( pfA1Real_fx[iFBOffset], fPrevReal_fx ), Mpy_32_32( pfA1Imag_fx[iFBOffset], fPrevImag_fx ) ); + fImag_fx = L_add( Mpy_32_32( pfA1Real_fx[iFBOffset], fPrevImag_fx ), Mpy_32_32( pfA1Imag_fx[iFBOffset], fPrevReal_fx ) ); + ppiQReal_fx = Quantize_fx( L_add_sat( L_shr_r_sat( ppfReal_fx[iBlockOffset][iFBOffset], sub( q_final, Q28 ) ), fReal_fx ), /* quantize residual */ + fSCFGain_fx, + &ppiSignReal[iBlockOffset][iFBOffset], + iMaxQuantVal_fx ); + ppiQImag_fx = Quantize_fx( L_add_sat( L_shr_r_sat( ppfImag_fx[iBlockOffset][iFBOffset], sub( q_final, Q28 ) ), fImag_fx ), + fSCFGain_fx, + &ppiSignImag[iBlockOffset][iFBOffset], + iMaxQuantVal_fx ); + ppiQReal[iBlockOffset][iFBOffset] = L_shr( ppiQReal_fx, 21 ); + + ppiQImag[iBlockOffset][iFBOffset] = L_shr( ppiQImag_fx, 21 ); + + ppiQReal_fx = L_shl( ppiQReal[iBlockOffset][iFBOffset], 21 ); + fPrevReal_fx = L_sub( L_shl( UnQuantize_fx( ppiQReal_fx, + fInvSCFGain_fx, + ppiSignReal[iBlockOffset][iFBOffset] ), + 9 ), + fReal_fx ); + /* add prediction to quantized residual = reconstructed sample */ + + ppiQImag_fx = L_shl( ppiQImag[iBlockOffset][iFBOffset], 21 ); + fPrevImag_fx = L_sub( L_shl( UnQuantize_fx( ppiQImag_fx, + fInvSCFGain_fx, + ppiSignImag[iBlockOffset][iFBOffset] ), + 9 ), + fImag_fx ); + iBlockOffset++; + } /* group length */ + } /* groups */ + pfPredStateReal_fx[iFBOffset] = fPrevReal_fx; + move32(); + pfPredStateImag_fx[iFBOffset] = fPrevImag_fx; + move32(); + } /* predEnable */ + ELSE + { /* no prediction */ + FOR( n = 0; n < iNumGroups; n++ ) + { + iAlloc = ppiAlloc[n][b]; + move32(); + iMaxQuantVal_fx = c_aiQuantMaxValues_fx[iAlloc]; + move32(); + fSCFGain_fx = c_afScaleFactor_fx[iAlloc]; + move32(); + fInvSCFGain_fx = c_afInvScaleFactor_fx[iAlloc]; + move32(); + FOR( k = 0; k < piGroupLengths[n]; k++ ) + { + ppiQReal_fx = Quantize_fx( L_shr_r_sat( ppfReal_fx[iBlockOffset][iFBOffset], sub( q_final, Q28 ) ), + fSCFGain_fx, + &ppiSignReal[iBlockOffset][iFBOffset], + iMaxQuantVal_fx ); + ppiQImag_fx = Quantize_fx( L_shr_r_sat( ppfImag_fx[iBlockOffset][iFBOffset], sub( q_final, Q28 ) ), + fSCFGain_fx, + &ppiSignImag[iBlockOffset][iFBOffset], + iMaxQuantVal_fx ); + + ppiQReal[iBlockOffset][iFBOffset] = L_shr( ppiQReal_fx, 21 ); + + ppiQImag[iBlockOffset][iFBOffset] = L_shr( ppiQImag_fx, 21 ); + + iBlockOffset++; + } /* group length */ + } /* groups */ + } /* predEnable */ + iFBOffset++; + } /* bandwidth */ + } +} +static Word32 CountLCLDBits( + const Word32 iNumGroups, + const Word32 *piGroupLengths, + const Word32 iNumBands, + const Word32 *piBandwidths, + const Word32 *piPredEnable, + Word32 **ppiAlloc, + Word32 **ppiQReal, + Word32 **ppiQImag ) +{ + Word32 k, n, b, iFBOffset; + Word32 iBits, iBlockOffest; + Word32 m, iAlloc, iHuffDim, iHuffMod; + + iBits = 0; + move32(); + iBlockOffest = 0; + move32(); + FOR( n = 0; n < iNumGroups; n++ ) + { + FOR( k = 0; k < piGroupLengths[n]; k++ ) + { + iFBOffset = 0; + move32(); + FOR( b = 0; b < iNumBands; b++ ) + { + iAlloc = ppiAlloc[n][b]; + move32(); + + iHuffDim = c_aiHuffmanDim[iAlloc]; + move32(); + iHuffMod = c_aiHuffmanMod[iAlloc]; + move32(); + + IF( GT_32( iAlloc, 0 ) ) + { + const UWord16( *pauiHuffmanTable )[2] = NULL; + const UWord16( *pauiHuffmanTableDPCM )[2] = NULL; + pauiHuffmanTable = c_apauiHuffEncTabels[iAlloc]; + pauiHuffmanTableDPCM = c_apauiHuffEncTabels[ALLOC_TABLE_SIZE + iAlloc]; + FOR( m = 0; m < piBandwidths[b]; m++ ) + { + Word32 iQuantValue1; + Word32 iQuantValue2; + + iQuantValue1 = ppiQReal[iBlockOffest][iFBOffset]; + move32(); + iQuantValue2 = ppiQImag[iBlockOffest][iFBOffset]; + move32(); + + iBits = L_add( iBits, GT_32( iQuantValue1, 0 ) ? 1 : 0 ); /* Sign bit for vals > 0 */ + iBits = L_add( iBits, GT_32( iQuantValue2, 0 ) ? 1 : 0 ); /* Sign bit for vals > 0 */ + + IF( EQ_32( piPredEnable[iFBOffset], 1 ) ) + { + IF( EQ_32( iHuffDim, 2 ) ) + { + iQuantValue1 *= iHuffMod; + iQuantValue1 = L_add( iQuantValue1, iQuantValue2 ); + iBits = L_add( iBits, pauiHuffmanTableDPCM[iQuantValue1][0] ); + } + ELSE + { + iBits = L_add( iBits, pauiHuffmanTableDPCM[iQuantValue1][0] ); + iBits = L_add( iBits, pauiHuffmanTableDPCM[iQuantValue2][0] ); + } + } + ELSE + { + IF( EQ_32( iHuffDim, 2 ) ) + { + iQuantValue1 *= iHuffMod; + iQuantValue1 = L_add( iQuantValue1, iQuantValue2 ); + iBits = L_add( iBits, pauiHuffmanTable[iQuantValue1][0] ); + } + ELSE + { + iBits = L_add( iBits, pauiHuffmanTable[iQuantValue1][0] ); + iBits = L_add( iBits, pauiHuffmanTable[iQuantValue2][0] ); + } + } + + iFBOffset++; + } + } + ELSE + { + iFBOffset = L_add( iFBOffset, piBandwidths[b] ); + } + } + + iBlockOffest++; + } + } + + return iBits; +} + + +/* Currently only the number of bands in frame */ +static Word32 WriteHeaderInformation( + const Word32 iNumBands, + ISAR_SPLIT_REND_BITS_HANDLE pBits ) +{ + Word32 iBitsWritten; + + iBitsWritten = 0; + move32(); + ISAR_SPLIT_REND_BITStream_write_int32( pBits, iNumBands, 5 ); + iBitsWritten = L_add( iBitsWritten, 5 ); + + return iBitsWritten; +} + + +static Word32 WriteMSInformation( + const Word32 iNumBands, + const Word32 iMSMode, + const Word32 *piMSFlags, + const Word32 *piLRPhaseDiff, + const Word32 *piMSPredCoef, + Word32 iNumMSPredBands, + ISAR_SPLIT_REND_BITS_HANDLE pBits ) +{ + Word32 iBitsWritten; + Word32 iMSPredAll = (Word32) EQ_32( iNumMSPredBands, iNumBands ); + move32(); +#ifdef DEBUG_WRITE_MS_PRED + Word32 iBitsWrittenTmp = 0; + move32(); +#endif + iBitsWritten = 0; + move32(); + ISAR_SPLIT_REND_BITStream_write_int32( pBits, iMSMode, 2 ); + iBitsWritten = L_add( iBitsWritten, 2 ); + + IF( EQ_32( iMSMode, 3 ) ) + { + ISAR_SPLIT_REND_BITStream_write_int32( pBits, iMSPredAll, 1 ); + iBitsWritten = L_add( iBitsWritten, 1 ); + } + + test(); + test(); + IF( EQ_32( iMSMode, 2 ) || ( EQ_32( iMSMode, 3 ) && !iMSPredAll ) ) + { + Word32 n; + FOR( n = 0; n < iNumBands; n++ ) + { + ISAR_SPLIT_REND_BITStream_write_int32( pBits, piMSFlags[n], 1 ); + iBitsWritten = L_add( iBitsWritten, 1 ); + } + } + +#ifdef DEBUG_WRITE_MS_PRED + iBitsWrittenTmp = iBitsWritten; +#endif + IF( EQ_32( iMSMode, 3 ) ) + { + Word32 b; + Word32 anyNonZero; + anyNonZero = 0; + move32(); + FOR( b = 0; b < iNumMSPredBands; b++ ) + { + IF( NE_32( piLRPhaseDiff[b], 0 ) ) + { + anyNonZero = 1; + move32(); + BREAK; + } + } + ISAR_SPLIT_REND_BITStream_write_int32( pBits, anyNonZero, 1 ); + iBitsWritten++; + + IF( anyNonZero ) + { + ISAR_SPLIT_REND_BITStream_write_int32( pBits, L_sub( piLRPhaseDiff[0], PHASE_MIN_VAL ), PHASE_BAND0_BITS ); + iBitsWritten = L_add( iBitsWritten, PHASE_BAND0_BITS ); + FOR( b = 1; b < iNumMSPredBands; b++ ) + { + Word32 tabIdx = L_sub( piLRPhaseDiff[b], ENV_DELTA_MIN ); + ISAR_SPLIT_REND_BITStream_write_int32( pBits, c_aaiRMSEnvHuffEnc[tabIdx][1], c_aaiRMSEnvHuffEnc[tabIdx][0] ); + iBitsWritten = L_add( iBitsWritten, c_aaiRMSEnvHuffEnc[tabIdx][0] ); + } + } + + anyNonZero = 0; + move32(); + FOR( b = 0; b < iNumMSPredBands; b++ ) + { + IF( NE_32( piMSPredCoef[b], 0 ) ) + { + anyNonZero = 1; + move32(); + BREAK; + } + } + + ISAR_SPLIT_REND_BITStream_write_int32( pBits, anyNonZero, 1 ); + iBitsWritten++; + + IF( anyNonZero ) + { + ISAR_SPLIT_REND_BITStream_write_int32( pBits, L_sub( piMSPredCoef[0], PRED_MIN_VAL ), PRED_BAND0_BITS ); + iBitsWritten = L_add( iBitsWritten, PRED_BAND0_BITS ); + FOR( b = 1; b < iNumMSPredBands; b++ ) + { + Word32 tabIdx = L_sub( piMSPredCoef[b], ENV_DELTA_MIN ); + ISAR_SPLIT_REND_BITStream_write_int32( pBits, c_aaiRMSEnvHuffEnc[tabIdx][1], c_aaiRMSEnvHuffEnc[tabIdx][0] ); + iBitsWritten = L_add( iBitsWritten, c_aaiRMSEnvHuffEnc[tabIdx][0] ); + } + } + } +#ifdef DEBUG_WRITE_MS_PRED + { + static FILE *fid = 0; + IF( !fid ) + { + fid = fopen( "ms_pred_bitrate.txt", "wt" ); + } + fprintf( fid, "%f\n", (float) ( ( iBitsWritten - iBitsWrittenTmp ) * ( iMSMode == 3 ) * 50 ) / 1000.0f ); /*kb/s*/ + } +#endif + + return iBitsWritten; +} + + +static Word32 WriteGroupInformation( + const Word32 iChannels, + const Word32 iCommonGrouping, + const Word32 *piNumGroups, + Word32 **ppiGroupLengths, + ISAR_SPLIT_REND_BITS_HANDLE pBits ) +{ + Word32 c, k, n, iBitsWritten; + + iBitsWritten = 0; + move32(); + test(); + IF( EQ_32( iChannels, 2 ) && EQ_32( iCommonGrouping, 1 ) ) + { + ISAR_SPLIT_REND_BITStream_write_int32( pBits, iCommonGrouping, 1 ); + iBitsWritten = L_add( iBitsWritten, 1 ); + + FOR( n = 0; n < piNumGroups[0]; n++ ) + { + FOR( k = 1; k < ppiGroupLengths[0][n]; k++ ) + { + ISAR_SPLIT_REND_BITStream_write_int32( pBits, 0, 1 ); + iBitsWritten = L_add( iBitsWritten, 1 ); + } + IF( LT_32( n, L_sub( piNumGroups[0], 1 ) ) ) + { + ISAR_SPLIT_REND_BITStream_write_int32( pBits, 1, 1 ); + iBitsWritten = L_add( iBitsWritten, 1 ); + } + } + } + ELSE IF( EQ_32( iChannels, 2 ) ) + { + ISAR_SPLIT_REND_BITStream_write_int32( pBits, iCommonGrouping, 1 ); + iBitsWritten = L_add( iBitsWritten, 1 ); + + FOR( c = 0; c < iChannels; c++ ) + { + FOR( n = 0; n < piNumGroups[c]; n++ ) + { + FOR( k = 1; k < ppiGroupLengths[c][n]; k++ ) + { + ISAR_SPLIT_REND_BITStream_write_int32( pBits, 0, 1 ); + iBitsWritten = L_add( iBitsWritten, 1 ); + } + IF( LT_32( n, L_sub( piNumGroups[c], 1 ) ) ) + { + ISAR_SPLIT_REND_BITStream_write_int32( pBits, 1, 1 ); + iBitsWritten = L_add( iBitsWritten, 1 ); + } + } + } + } + ELSE + { + FOR( c = 0; c < iChannels; c++ ) + { + FOR( n = 0; n < piNumGroups[c]; n++ ) + { + FOR( k = 1; k < ppiGroupLengths[c][n]; k++ ) + { + ISAR_SPLIT_REND_BITStream_write_int32( pBits, 0, 1 ); + iBitsWritten = L_add( iBitsWritten, 1 ); + } + + IF( LT_32( n, L_sub( piNumGroups[c], 1 ) ) ) + { + ISAR_SPLIT_REND_BITStream_write_int32( pBits, 1, 1 ); + iBitsWritten = L_add( iBitsWritten, 1 ); + } + } + } + } + + return iBitsWritten; +} + + +static Word32 WriteRMSEnvelope( + const Word32 iChannels, + const Word32 *piNumGroups, + const Word32 iNumBands, + Word32 ***pppiRMSEnvelope, + ISAR_SPLIT_REND_BITS_HANDLE pBits ) +{ + Word32 k, n; + Word32 iBitsWritten; + + iBitsWritten = 0; + move32(); + FOR( n = 0; n < iChannels; n++ ) + { + FOR( k = 0; k < piNumGroups[n]; k++ ) + { + Word32 b; + Word32 iLastRMSVal; + + iLastRMSVal = pppiRMSEnvelope[n][k][0]; + move32(); + iLastRMSVal = GT_32( iLastRMSVal, ENV_MIN ) ? iLastRMSVal : ENV_MIN; + move32(); + iLastRMSVal = LT_32( iLastRMSVal, ENV_MAX ) ? iLastRMSVal : ENV_MAX; + move32(); + ISAR_SPLIT_REND_BITStream_write_int32( pBits, L_sub( iLastRMSVal, ENV_MIN ), ENV0_BITS ); + iBitsWritten = L_add( iBitsWritten, ENV0_BITS ); + + FOR( b = 1; b < iNumBands; b++ ) + { + Word32 iDelta; + + iDelta = L_sub( pppiRMSEnvelope[n][k][b], iLastRMSVal ); + iDelta = GT_32( iDelta, ENV_DELTA_MIN ) ? iDelta : ENV_DELTA_MIN; + move32(); + iDelta = LT_32( iDelta, ENV_DELTA_MAX ) ? iDelta : ENV_DELTA_MAX; + move32(); + iDelta = L_sub( iDelta, ENV_DELTA_MIN ); + ISAR_SPLIT_REND_BITStream_write_int32( pBits, c_aaiRMSEnvHuffEnc[iDelta][1], c_aaiRMSEnvHuffEnc[iDelta][0] ); + iBitsWritten = L_add( iBitsWritten, c_aaiRMSEnvHuffEnc[iDelta][0] ); + + iLastRMSVal = pppiRMSEnvelope[n][k][b]; + move32(); + } + } + } + + return iBitsWritten; +} + + +static Word32 WriteAllocInformation( + const Word32 iAllocOffset, + ISAR_SPLIT_REND_BITS_HANDLE pBits ) +{ + Word32 iBitsWritten; + + iBitsWritten = 0; + move32(); + + IF( LT_32( iAllocOffset, MIN_ALLOC_OFFSET ) || GT_32( iAllocOffset, MAX_ALLOC_OFFSET ) ) + { + printf( "Serious error\n" ); + } + + ISAR_SPLIT_REND_BITStream_write_int32( pBits, L_sub( iAllocOffset, MIN_ALLOC_OFFSET ), ALLOC_OFFSET_BITS ); + iBitsWritten = L_add( iBitsWritten, ALLOC_OFFSET_BITS ); + + return iBitsWritten; +} + + +static Word32 WriteLCLDData( + const Word32 *piNumGroups, + Word32 **ppiGroupLengths, + const Word32 iNumBands, + const Word32 iNumChannels, + Word32 **ppiPredEnable, + const Word32 iNumSubSets, + const Word32 iSubSetId, + Word32 ***pppiAlloc, + Word32 ***pppiSignReal, + Word32 ***pppiSignImag, + Word32 ***pppiQReal, + Word32 ***pppiQImag, + ISAR_SPLIT_REND_BITS_HANDLE pBits ) +{ + Word32 iBitsWritten; + Word32 iNumLcldBands = c_aiNumLcldBandsPerBand[iNumBands - 1]; + Word32 s; + Word32 iSet = iSubSetId; + + iBitsWritten = 0; + move32(); + FOR( s = 0; s < iNumSubSets; ( s++, iSet-- ) ) + { + Word32 ch; + IF( LT_32( iSet, 0 ) ) + { + iSet = L_sub( iNumSubSets, 1 ); + } + + FOR( ch = 0; ch < iNumChannels; ch++ ) + { + Word32 iBlockOffest = 0; + move32(); + Word32 n; + FOR( n = 0; n < piNumGroups[ch]; n++ ) + { + Word32 k; + FOR( k = 0; k < ppiGroupLengths[ch][n]; k++ ) + { + Word32 iFBOffset; + FOR( iFBOffset = iSet; iFBOffset < iNumLcldBands; iFBOffset += iNumSubSets ) + { + Word32 b; + Word32 iAlloc; + Word32 iHuffDim; + Word32 iHuffMod; + + b = c_aiBandIdPerLcldBand[iFBOffset]; + move32(); + + iAlloc = pppiAlloc[ch][n][b]; + move32(); + + iHuffDim = c_aiHuffmanDim[iAlloc]; + move32(); + iHuffMod = c_aiHuffmanMod[iAlloc]; + move32(); + + IF( GT_32( iAlloc, 0 ) ) + { + const UWord16( *pauiHuffmanTable )[2] = NULL; + const UWord16( *pauiHuffmanTableDPCM )[2] = NULL; + Word32 iQuantValue1; + Word32 iQuantValue2; + pauiHuffmanTable = c_apauiHuffEncTabels[iAlloc]; + pauiHuffmanTableDPCM = c_apauiHuffEncTabels[ALLOC_TABLE_SIZE + iAlloc]; + + iQuantValue1 = pppiQReal[ch][iBlockOffest][iFBOffset]; + move32(); + iQuantValue2 = pppiQImag[ch][iBlockOffest][iFBOffset]; + move32(); +#ifdef LCLD_HANDLE_PRED_START_SAMPLE + IF( ppiPredEnable[ch][iFBOffset] == 1 && ( iBlockOffest > 0 || iSet != iSubSetId ) ) +#else + IF( EQ_32( ppiPredEnable[ch][iFBOffset], 1 ) ) +#endif + { + IF( EQ_32( iHuffDim, 2 ) ) + { + Word32 iSymbol; + iSymbol = iQuantValue1; + move32(); + iSymbol *= iHuffMod; + iSymbol = L_add( iSymbol, iQuantValue2 ); + ISAR_SPLIT_REND_BITStream_write_int32( pBits, pauiHuffmanTableDPCM[iSymbol][1], pauiHuffmanTableDPCM[iSymbol][0] ); + iBitsWritten = L_add( iBitsWritten, pauiHuffmanTableDPCM[iSymbol][0] ); + } + ELSE + { + ISAR_SPLIT_REND_BITStream_write_int32( pBits, pauiHuffmanTableDPCM[iQuantValue1][1], pauiHuffmanTableDPCM[iQuantValue1][0] ); + iBitsWritten = L_add( iBitsWritten, pauiHuffmanTableDPCM[iQuantValue1][0] ); + + ISAR_SPLIT_REND_BITStream_write_int32( pBits, pauiHuffmanTableDPCM[iQuantValue2][1], pauiHuffmanTableDPCM[iQuantValue2][0] ); + iBitsWritten = L_add( iBitsWritten, pauiHuffmanTableDPCM[iQuantValue2][0] ); + } + } + ELSE + { + IF( EQ_32( iHuffDim, 2 ) ) + { + Word32 iSymbol; + iSymbol = iQuantValue1; + move32(); + iSymbol *= iHuffMod; + iSymbol = L_add( iSymbol, iQuantValue2 ); + ISAR_SPLIT_REND_BITStream_write_int32( pBits, pauiHuffmanTable[iSymbol][1], pauiHuffmanTable[iSymbol][0] ); + iBitsWritten = L_add( iBitsWritten, pauiHuffmanTable[iSymbol][0] ); + } + ELSE + { + ISAR_SPLIT_REND_BITStream_write_int32( pBits, pauiHuffmanTable[iQuantValue1][1], pauiHuffmanTable[iQuantValue1][0] ); + iBitsWritten = L_add( iBitsWritten, pauiHuffmanTable[iQuantValue1][0] ); + + ISAR_SPLIT_REND_BITStream_write_int32( pBits, pauiHuffmanTable[iQuantValue2][1], pauiHuffmanTable[iQuantValue2][0] ); + iBitsWritten = L_add( iBitsWritten, pauiHuffmanTable[iQuantValue2][0] ); + } + } + + IF( GT_32( iQuantValue1, 0 ) ) + { + ISAR_SPLIT_REND_BITStream_write_int32( pBits, pppiSignReal[ch][iBlockOffest][iFBOffset], 1 ); + iBitsWritten = L_add( iBitsWritten, 1 ); + } + IF( GT_32( iQuantValue2, 0 ) ) + { + ISAR_SPLIT_REND_BITStream_write_int32( pBits, pppiSignImag[ch][iBlockOffest][iFBOffset], 1 ); + iBitsWritten = L_add( iBitsWritten, 1 ); + } + } + } + iBlockOffest++; + } + } + } + } + + return iBitsWritten; +} +static Word32 ComputeAllocation( + const Word32 iChannels, + const Word32 *piNumGroups, + Word32 **ppiGroupLengths, + const Word32 iNumBands, + const Word32 *piBandwidths, + Word32 ***pppfReal_fx, + Word32 ***pppfImag_fx, + Word16 q_final, + Word32 ***pppiSMR, + const Word32 iAvailableBits, + Word32 *piAllocOffset, + Word32 ***pppiAlloc, + Word32 ***pppiQReal, + Word32 ***pppiQImag, + Word32 ***pppiSignReal, + Word32 ***pppiSignImag, + PredictionEncoder *psPredictionEncoder ) +{ + Word32 iBitsUsed, iDone, iDelta; + Word32 b, k, n; + Word32 iLimitAllocOffset; + + iBitsUsed = ALLOC_OFFSET_BITS; /* Bits used for Alloc Offset */ + move32(); + iDone = 0; + move32(); + iDelta = -MIN_ALLOC_OFFSET; + move32(); + *piAllocOffset = 0; + move32(); + WHILE( EQ_32( iDone, 0 ) ) + { + iBitsUsed = ALLOC_OFFSET_BITS; + move32(); + iLimitAllocOffset = *piAllocOffset; + move32(); + iLimitAllocOffset = GT_32( iLimitAllocOffset, MIN_ALLOC_OFFSET ) ? iLimitAllocOffset : MIN_ALLOC_OFFSET; + iLimitAllocOffset = LT_32( iLimitAllocOffset, MAX_ALLOC_OFFSET ) ? iLimitAllocOffset : MAX_ALLOC_OFFSET; + + FOR( n = 0; n < iChannels; n++ ) + { + FOR( k = 0; k < piNumGroups[n]; k++ ) + { + FOR( b = 0; b < iNumBands; b++ ) + { + Word32 iAlloc; + iAlloc = ( L_shr( L_add( pppiSMR[n][k][b], L_mult0( extract_l( iLimitAllocOffset ), ALLOC_OFFSET_SCALE ) ), 5 ) ); + iAlloc = GT_32( iAlloc, MIN_ALLOC ) ? iAlloc : MIN_ALLOC; + iAlloc = LT_32( iAlloc, MAX_ALLOC ) ? iAlloc : MAX_ALLOC; + pppiAlloc[n][k][b] = iAlloc; + move32(); + } + } + IF( psPredictionEncoder->iNumSubSets > 1 ) + { + mvl2l( psPredictionEncoder->ppfPredStateReal_fx[n], psPredictionEncoder->ppfPredStateRealTmp_fx[n], LCLD_BANDS ); + mvl2l( psPredictionEncoder->ppfPredStateImag_fx[n], psPredictionEncoder->ppfPredStateImagTmp_fx[n], LCLD_BANDS ); + } + + QuantizeSpectrumDPCM_Opt( piNumGroups[n], + (const Word32 *) ppiGroupLengths[n], + iNumBands, + piBandwidths, + pppiAlloc[n], + pppfReal_fx[n], + pppfImag_fx[n], + q_final, + pppiQReal[n], + pppiQImag[n], + pppiSignReal[n], + pppiSignImag[n], + psPredictionEncoder->iNumSubSets, + psPredictionEncoder->iSubSetId, + psPredictionEncoder->ppiPredBandEnable[n], + psPredictionEncoder->ppfA1Real_fx[n], + psPredictionEncoder->ppfA1Imag_fx[n], + psPredictionEncoder->ppfPredStateRealTmp_fx[n], + psPredictionEncoder->ppfPredStateImagTmp_fx[n] ); + iBitsUsed = L_add( iBitsUsed, CountLCLDBits( piNumGroups[n], + (const Word32 *) ppiGroupLengths[n], + iNumBands, + piBandwidths, + (const Word32 *) psPredictionEncoder->ppiPredBandEnable[n], + pppiAlloc[n], + pppiQReal[n], + pppiQImag[n] ) ); + } + + IF( LE_32( *piAllocOffset, MIN_ALLOC_OFFSET ) && GT_32( iBitsUsed, iAvailableBits ) ) + { +#ifdef DEBUG_VERBOSE + printf( "Frame can not be coded with the number of bits available\n" ); +#endif + // iLastError = ENC_ERROR_STREAM_FAILURE; + return -1; + } + ELSE IF( GE_32( *piAllocOffset, MAX_ALLOC_OFFSET ) && LT_32( iBitsUsed, iAvailableBits ) ) + { + *piAllocOffset = MAX_ALLOC_OFFSET; + iDone++; + } + ELSE + { + IF( EQ_32( iDelta, 0 ) && GT_32( iBitsUsed, iAvailableBits ) ) + { + iDelta = 1; + } + ELSE IF( EQ_32( iDelta, 0 ) && LT_32( iBitsUsed, iAvailableBits ) ) + { + iDone++; + } + ELSE IF( EQ_32( iBitsUsed, iAvailableBits ) ) + { + iDone++; + } + + IF( GT_32( iBitsUsed, iAvailableBits ) ) + { + *piAllocOffset -= iDelta; + iDelta = L_shr( iDelta, 1 ); + } + ELSE IF( LT_32( iBitsUsed, iAvailableBits ) ) + { + *piAllocOffset += iDelta; + iDelta = L_shr( iDelta, 1 ); + } + } + } + IF( GT_32( psPredictionEncoder->iNumSubSets, 1 ) ) + { + FOR( n = 0; n < iChannels; n++ ) + { + mvl2l( psPredictionEncoder->ppfPredStateRealTmp_fx[n], psPredictionEncoder->ppfPredStateReal_fx[n], LCLD_BANDS ); + mvl2l( psPredictionEncoder->ppfPredStateImagTmp_fx[n], psPredictionEncoder->ppfPredStateImag_fx[n], LCLD_BANDS ); + } + } + return iBitsUsed; +} +#endif diff --git a/lib_isar/isar_lcld_prot.h b/lib_isar/isar_lcld_prot.h new file mode 100644 index 0000000000000000000000000000000000000000..49e03f5ef5fc1d31a475e63bcc787beef25bf58a --- /dev/null +++ b/lib_isar/isar_lcld_prot.h @@ -0,0 +1,456 @@ +/****************************************************************************************************** + + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository. All Rights Reserved. + + This software is protected by copyright law and by international treaties. + The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository retain full ownership rights in their respective contributions in + the software. This notice grants no license of any kind, including but not limited to patent + license, nor is any license granted by implication, estoppel or otherwise. + + Contributors are required to enter into the IVAS codec Public Collaboration agreement before making + contributions. + + This software is provided "AS IS", without any express or implied warranties. The software is in the + development stage. It is intended exclusively for experts who have experience with such software and + solely for the purpose of inspection. All implied warranties of non-infringement, merchantability + and fitness for a particular purpose are hereby disclaimed and excluded. + + Any dispute, controversy or claim arising under or in relation to providing this software shall be + submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in + accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and + the United Nations Convention on Contracts on the International Sales of Goods. + +*******************************************************************************************************/ + +#ifndef ISAR_LCLD_PROT_H +#define ISAR_LCLD_PROT_H + +#include "options.h" +#ifdef SPLIT_REND_WITH_HEAD_ROT +#include "typedef.h" +#include "common_api_types.h" +#include "isar_lcld_rom_tables.h" +/* clang-format off */ + +typedef struct LCLD_ENCODER LCLDEncoder; + +ivas_error CreateLCLDEncoder( + LCLDEncoder **psLCLDEncoder_out, + const Word32 iSampleRate, + const Word32 iChannels, + const Word32 iTargetBitRate, + const Word32 iAllowSidePred, + const Word16 iNumBlocks, + const Word16 iNumSubSets, + const Word32 iRealOnlyOut); +void DeleteLCLDEncoder( + LCLDEncoder *psLCLDEncoder +); + +Word32 EncodeLCLDFrame( + LCLDEncoder *psLCLDEncoder, + Word32 ***pppfLCLDReal_fx, + Word32 ***pppfLCLDImag_fx, + Word32 *piNumiBites, + const Word32 available_bits, + ISAR_SPLIT_REND_BITS_HANDLE pBits, + Word16 *q_final); + +Word32 GetNumGroups( + LCLDEncoder *psLCLDEncoder +); + + +typedef struct LCLD_DECODER LCLDDecoder; + +ivas_error CreateLCLDDecoder( + LCLDDecoder **psLCLDDecoder_out, + const Word32 iSampleRate, + const Word32 iChannels, + const Word32 iNumBlocks, + const Word32 iRealOnlyOut); + + +void DeleteLCLDDecoder( + LCLDDecoder *psLCLDDecoder +); + +Word32 DecodeLCLDFrame( + LCLDDecoder *psLCLDDecoder, + ISAR_SPLIT_REND_BITS_HANDLE pBits, + Word32 ***pppfLCLDReal_fx, + Word32 ***pppfLCLDImag_fx, + Word16 Q_in, + Word16 *Q_out +); + +/*----------------------------------------------------------------------------------* + * MSPred prototypes + *----------------------------------------------------------------------------------*/ +Word32 quantPhase_fx( + Word32 phase, + Word16 exp); + +int32_t quantPhase( + float phase +); + +void cplxmult( + float *pr1, + float *pi1, + float r2, + float i2 +); +void cplxmult_fx( + Word32 *pr1, + Word32 *pi1, + Word32 r2, + Word32 i2 +); + +Word32 requantPhase( + Word32 phaseQ +); + +Word32 quantPred_fx( + const Word32 pred, + Word16 exp); +int32_t quantPred( + const float pred +); + +float dequantPhase( + const int32_t phaseQ +); + +float dequantPred( + int32_t predQ +); +Word32 dequantPred_fx( + Word32 predQ +); +Word32 PrepEncode( + Word32 *piQuant, + const Word32 *piMSFlags, + const Word32 numBands +); + +void EncodePhase( + Word32 *phaseQuant, + const Word32 numMSBands, + const Word32 diffDim +); + +void DecodePhase( + Word32 *phaseQuant, + const Word32 numMSBands, + const Word32 diffDim +); + +Word32 EncodePredCoef( + Word32 *predQuant, + const Word32 numMSBands +); + +void DecodePredCoef( + Word32 *phaseQuant, + const Word32 numMSBands +); + +void writeMSPred( + int32_t *phaseQuant, + int32_t *predQuant, + const int32_t MSMode, + const int32_t numMSBands, + int32_t numBands, + void *fid, + int32_t *piMsFlags +); + +Word32 CountMSBits( + Word32 iNumBands, + const Word32 iMSMode, + const Word32 *piMSFlags, + const Word32 *piLRPhaseDiff, + const Word32 *piMSPredCoef +); + + +/*----------------------------------------------------------------------------------* + * NoiseGen prototypes + *----------------------------------------------------------------------------------*/ + +typedef struct NOISE_GEN +{ + int32_t iNoiseBufferLength; + int32_t iNoiseBufferMask; + int32_t iNoiseBufferIndex; + float *pfNoiseBuffer; +} NoiseGen; + +void DeleteNoiseGen( + NoiseGen *psNoiseGen +); + +inline float GetNoise( NoiseGen *psNoiseGen ) +{ + float fNoiseSample; + + fNoiseSample = psNoiseGen->pfNoiseBuffer[psNoiseGen->iNoiseBufferIndex]; + psNoiseGen->iNoiseBufferIndex++; + psNoiseGen->iNoiseBufferIndex &= psNoiseGen->iNoiseBufferMask; + + return fNoiseSample; +} +inline Word32 GetNoise_fx( NoiseGen *psNoiseGen ) +{ + Word32 fNoiseSample; + + fNoiseSample = (Word32) (psNoiseGen->pfNoiseBuffer[psNoiseGen->iNoiseBufferIndex]* (1<<14)); + psNoiseGen->iNoiseBufferIndex++; + psNoiseGen->iNoiseBufferIndex &= psNoiseGen->iNoiseBufferMask; + + return fNoiseSample; +} + +/*----------------------------------------------------------------------------------* + * PereptualModel prototypes + *----------------------------------------------------------------------------------*/ + +extern void PerceptualModel( + const int32_t iMaxQuantBands, + const int32_t *piRMSEnvelope, + int32_t *piExcitation, + int32_t *piSMR +); +extern void PerceptualModel_fx( + const Word32 iMaxQuantBands, + const Word32 *piRMSEnvelope, + Word32 *piExcitation, + Word32 *piSMR +); + +extern void PerceptualModelStereo_fx( + const Word32 iMaxQuantBands, + const Word32 *piMSFlags, + const Word32 *piRMSEnvelope0, + const Word32 *piRMSEnvelope1, + Word32 *piExcitation0, + Word32 *piExcitation1, + Word32 *piSMR0, + Word32 *piSMR1 +); +extern void PerceptualModelStereo( + const int32_t iMaxQuantBands, + const int32_t *piMSFlags, + const int32_t *piRMSEnvelope0, + const int32_t *piRMSEnvelope1, + int32_t *piExcitation0, + int32_t *piExcitation1, + int32_t *piSMR0, + int32_t *piSMR1 +); + + +/*----------------------------------------------------------------------------------* + * PredEncoder/PredDecoder prototypes + *----------------------------------------------------------------------------------*/ + +typedef struct PREDICTION_ENCODER +{ + int32_t iChannels; + int32_t iNumBlocks; + + int32_t iSubSetId; + int32_t iNumSubSets; + int32_t iMaxNumPredBands; + Word32 ***pppfInpBufReal_fx; /* channels, LCLD_PRED_WIN_LEN, bands */ + Word32 ***pppfInpBufImag_fx; + Word32 **ppfPredStateReal_fx; /* channels, bands */ + Word32 **ppfPredStateImag_fx; + Word32 **ppfPredStateRealTmp_fx; + Word32 **ppfPredStateImagTmp_fx; + Word32 **ppfInpPrevReal_fx; /* channels, bands */ + Word32 **ppfInpPrevImag_fx; + 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; + Word32 pfRxxReal_fx[2]; + Word32 pfRxxImag_fx[2]; + float pfRxxReal[2]; + float pfRxxImag[2]; + + int32_t *piPredChanEnable; + int32_t *piNumPredBands; + int32_t **ppiPredBandEnable; + + Word32 **ppfA1Real_fx; + Word32 **ppfA1Imag_fx; + float **ppfA1Real; + float **ppfA1Imag; + + int32_t **ppiA1Mag; + int32_t **ppiA1Phase; +} PredictionEncoder; + +ivas_error CreatePredictionEncoder_fx( + PredictionEncoder **psPredictionEncoder_out, + const Word32 iChannels, + const Word32 iNumBlocks, + const Word32 iNumSubSets, + const Word32 iMaxNumPredBands ); + +void DeletePredictionEncoder_fx( + PredictionEncoder *psPredictionEncoder ); +ivas_error CreatePredictionEncoder( + PredictionEncoder **psPredictionEncoder_out, + const int32_t iChannels, + const int32_t iNumBlocks, + const int32_t iNumSubSets, + const int32_t iMaxNumPredBands +); + +void DeletePredictionEncoder( + PredictionEncoder *psPredictionEncoder +); + +void ComputePredictors( + PredictionEncoder *psPredictionEncoder, + float ***pppfReal, + float ***pppfImag +); +void ComputePredictors_fx( + PredictionEncoder *psPredictionEncoder, + Word32 ***pppfReal_fx, //Q12? + Word32 ***pppfImag_fx); //Q12? + + +Word32 WritePredictors( + PredictionEncoder *psPredictionEncoder, + ISAR_SPLIT_REND_BITS_HANDLE pBits ); + +typedef struct PREDICTION_DECODER +{ + int32_t iChannels; + int32_t iNumBlocks; + int32_t iSubSetId; + int32_t iNumSubSets; + Word32 **ppfPredStateReal_fx; + Word32 **ppfPredStateImag_fx; + + int32_t *piPredChanEnable; + int32_t **ppiPredBandEnable; + /* PLC_IMPROVEMENT */ + int32_t **ppiDecodingUnresolved; + int32_t **ppiDecodingFailed; + int32_t **ppiDecodingFailedPrev; + Word32 **ppfA1Real_fx; /* Q31 */ + Word32 **ppfA1Imag_fx; /* Q31 */ + + int32_t **ppiA1Mag; + int32_t **ppiA1Phase; + + Word32 pfMagLUT_fx[1 << PRED_QUNAT_FILTER_MAG_BITS]; /* Q31 */ + Word32 pfP2RRealLUT_fx[1 << PRED_QUANT_FILTER_PHASE_BITS]; /* Q31 */ + Word32 pfP2RImagLUT_fx[1 << PRED_QUANT_FILTER_PHASE_BITS]; /* Q31 */ + +} PredictionDecoder; + + +ivas_error CreatePredictionDecoder_fx( + PredictionDecoder **psPredictionDecoder_out, + const Word32 iChannels, + const Word32 iNumBlocks ); + +void DeletePredictionDecoder_fx( + PredictionDecoder *psPredictionDecoder ); + +Word32 ReadPredictors_fx( + PredictionDecoder *psPredictionDecoder, + ISAR_SPLIT_REND_BITS_HANDLE pBits +); + +/* PLC_IMPROVEMENT */ +void UpdatePredictionSubSetId( + PredictionEncoder *psPredictionEncoder); + +void SetDecodingUnresolved( + LCLDDecoder *psLCLDDecoder); + +int32_t AnyDecodingFailedPrev( + LCLDDecoder *psLCLDDecoder); + +int32_t AnyDecodingFailed( + LCLDDecoder *psLCLDDecoder); + +int32_t **GetDecodingFailedStatus( + LCLDDecoder *psLCLDDecoder); + +int16_t GetNumSubSets( + LCLDDecoder *psLCLDDecoder); + +int32_t **GetDecodingFailedPrevStatus( + LCLDDecoder *psLCLDDecoder); + +void SetDecodingPassed( + PredictionDecoder *psPredictionDecoder); + +void UpdateDecodingUnresolved( + PredictionDecoder *psPredictionDecoder); + +void UpdateDecodingFailedStatus( + PredictionDecoder *psPredictionDecoder); + +int32_t AnyDecodingUnresolved( + PredictionDecoder *psPredictionDecoder); + +void ApplyInversePredictors_fx( + PredictionDecoder *psPredictionDecoder, + Word32 ***pppfReal, + Word32 ***pppfImag +); + + +/*----------------------------------------------------------------------------------* + * RMSEnvGrouping prototypes + *----------------------------------------------------------------------------------*/ + +typedef struct RMS_ENVELOPE_GROUPING RMSEnvelopeGrouping; + +RMSEnvelopeGrouping *CreateRMSEnvelopeGrouping( + const int32_t iNumBlocks +); + +void DeleteRMSEnvelopeGrouping( + RMSEnvelopeGrouping *psRMSEnvelopeGrouping +); +void ComputeEnvelopeGrouping( + RMSEnvelopeGrouping *psRMSEnvelopeGrouping, + const int32_t iChannels, + const int32_t iNumBands, + const int32_t *piBandwidths, + Word32 ***pppfReal_fx, + Word32 ***pppfImag_fx, + int32_t *piNumGroups, + int32_t *piGroupLengths, + int32_t ***pppiRMSEnvelope , + Word16 q_final +); + +#endif +/* clang-format on */ + +#endif /* _LCLD_ENCODER_H_ */ diff --git a/lib_isar/isar_lcld_rom_tables.c b/lib_isar/isar_lcld_rom_tables.c new file mode 100644 index 0000000000000000000000000000000000000000..8ecf743363a2a4de7584df44b28eb841e83809f0 --- /dev/null +++ b/lib_isar/isar_lcld_rom_tables.c @@ -0,0 +1,21207 @@ +/****************************************************************************************************** + + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository. All Rights Reserved. + + This software is protected by copyright law and by international treaties. + The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository retain full ownership rights in their respective contributions in + the software. This notice grants no license of any kind, including but not limited to patent + license, nor is any license granted by implication, estoppel or otherwise. + + Contributors are required to enter into the IVAS codec Public Collaboration agreement before making + contributions. + + This software is provided "AS IS", without any express or implied warranties. The software is in the + development stage. It is intended exclusively for experts who have experience with such software and + solely for the purpose of inspection. All implied warranties of non-infringement, merchantability + and fitness for a particular purpose are hereby disclaimed and excluded. + + Any dispute, controversy or claim arising under or in relation to providing this software shall be + submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in + accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and + the United Nations Convention on Contracts on the International Sales of Goods. + +*******************************************************************************************************/ + +#include "isar_lcld_rom_tables.h" +#include "options.h" +#ifdef SPLIT_REND_WITH_HEAD_ROT +#include "wmc_auto.h" +#include "prot_fx.h" +#include "isar_lcld_prot.h" +#include + +/* clang-format off */ +const int32_t c_aiNumLcldBandsPerBand[MAX_BANDS_48] = { + 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 21, 24, 27, 31, 37, 43, 50, 60 +}; + +const int32_t c_aiBandIdPerLcldBand[LCLD_BANDS] = { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15, 16, 16, 16, 17, 17, 17, 18, 18, 18, + 18, 19, 19, 19, 19, 19, 19, 20, 20, 20, 20, 20, 20, 21, 21, 21, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22 +}; +/* phi = (-12:12)'/12 *pi; tmp = [cos(phi),sin(phi)]; tmp = tmp';sprintf('{%.8ff, %.8ff},\n',tmp(:)) */ +const float c_afRotRealImag[PHASE_MAX_VAL - PHASE_MIN_VAL + 1][2] = +{ + { -1.00000000f, -0.00000000f }, + { -0.96592583f, -0.25881905f }, + { -0.86602540f, -0.50000000f }, + { -0.70710678f, -0.70710678f }, + { -0.50000000f, -0.86602540f }, + { -0.25881905f, -0.96592583f }, + { 0.00000000f, -1.00000000f }, + { 0.25881905f, -0.96592583f }, + { 0.50000000f, -0.86602540f }, + { 0.70710678f, -0.70710678f }, + { 0.86602540f, -0.50000000f }, + { 0.96592583f, -0.25881905f }, + { 1.00000000f, 0.00000000f }, + { 0.96592583f, 0.25881905f }, + { 0.86602540f, 0.50000000f }, + { 0.70710678f, 0.70710678f }, + { 0.50000000f, 0.86602540f }, + { 0.25881905f, 0.96592583f }, + { 0.00000000f, 1.00000000f }, + { -0.25881905f, 0.96592583f }, + { -0.50000000f, 0.86602540f }, + { -0.70710678f, 0.70710678f }, + { -0.86602540f, 0.50000000f }, + { -0.96592583f, 0.25881905f }, + { -1.00000000f, 0.00000000f } +}; + +const Word32 c_afRotRealImag_fx[PHASE_MAX_VAL - PHASE_MIN_VAL + 1][2] = /*Q31*/ +{ + {-2147483647,0,}, + {-2074309888,-555809664,}, + {-1859775360,-1073741824,}, + {-1518500224,-1518500224,}, + {-1073741824,-1859775360,}, + {-555809664,-2074309888,}, + {0,-2147483647,}, + {555809664,-2074309888,}, + {1073741824,-1859775360,}, + {1518500224,-1518500224,}, + {1859775360,-1073741824,}, + {2074309888,-555809664,}, + {2147483647,0,}, + {2074309888,555809664,}, + {1859775360,1073741824,}, + {1518500224,1518500224,}, + {1073741824,1859775360,}, + {555809664,2074309888,}, + {0,2147483647,}, + {-555809664,2074309888,}, + {-1073741824,1859775360,}, + {-1518500224,1518500224,}, + {-1859775360,1073741824,}, + {-2074309888,555809664,}, + {-2147483647,0,}, + +}; +/* Move this to perceptual model ? */ +const int32_t c_aiBandwidths48[MAX_BANDS_48] = +{ + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 2, + 2, + 2, + 2, + 2, + 3, + 3, + 4, + 6, + 6, + 7, + 10, +}; + + +const float c_afScaleFactor[ALLOC_TABLE_SIZE] = { + 0.0f, + 0.353553390593f, + 0.420448207627f, + 0.500000000000f, + 0.594603557501f, + 0.707106781187f, + 0.840896415254f, + 1.000000000000f, + 1.189207115003f, + 1.414213562373f, + 1.681792830507f, + 2.000000000000f, + 2.378414230005f, + 2.828427124746f, + 3.363585661015f, + 4.0f, + 4.756828460011f, + 5.656854249492f, + 6.727171322030f, + 8.0f, + 9.513656920022f, + 11.31370849898f, + 13.45434264406f, + 16.00000000000f, + 19.02731384004f, + 22.62741699797f, + 26.90868528812f, + 32.000000000000000f, + 38.054627680087073f, + 45.254833995939038f, + 53.817370576237735f, + 64.000000000000000f, +}; +const Word32 c_afScaleFactor_fx[ALLOC_TABLE_SIZE] = { + //Q24 + 0, + 5931641, + 7053950, + 8388608, + 9975792, + 11863283, + 14107901, + 16777216, + 19951584, + 23726566, + 28215802, + 33554432, + 39903168, + 47453132, + 56431604, + 67108864, + 79806336, + 94906264, + 112863208, + 134217728, + 159612672, + 189812528, + 225726416, + 268435456, + 319225344, + 379625056, + 451452832, + 536870912, + 638450688, + 759250112, + 902905664, + 1073741824, +}; +const float c_afInvScaleFactor[ALLOC_TABLE_SIZE] = { + 0.0f, + 2.367513562373095f, + 2.046407115002721f, + 1.775900000000000f, + 1.536446415253715f, + 1.323056781186548f, + 1.132903557501360f, + 0.965800000000000f, + 0.821348207626857f, + 0.695103390593274f, + 0.587801778750680f, + 0.495800000000000f, + 0.418124103813429f, + 0.352176695296637f, + 0.296200889375340f, + 0.249400000000000f, + 0.209812051906714f, + 0.176538347648318f, + 0.148525444687670f, + 0.124900000000000f, + 0.105056025953357f, + 0.088388347648318f, + 0.074325444687670f, + 0.062500000000000f, + 0.052556025953357f, + 0.044194173824159f, + 0.037162722343835f, + 0.031250000000000f, + 0.026278012976679f, + 0.022097086912080f, + 0.018581361171918f, + 0.015625000000000f, +}; +const Word32 c_afInvScaleFactor_fx[ALLOC_TABLE_SIZE] = { + //Q29 + 0, + 1271049216, + 1098656512, + 953429056, + 824873408, + 710310720, + 608222976, + 518509920, + 440957952, + 373180800, + 315573664, + 266180592, + 224478672, + 189073424, + 159021648, + 133895608, + 112641984, + 94778304, + 79738992, + 67055176, + 56401524, + 47453132, + 39903168, + 33554432, + 28215802, + 23726566, + 19951584, + 16777216, + 14107901, + 11863283, + 9975792, + 8388608, +}; +const float c_afRMSEnvReconstructTable[ENV_RECONSTRUCT_TABLE_SIZE] = { + 2.32830644e-10f, + 3.29272254e-10f, + 4.65661287e-10f, + 6.58544508e-10f, + 9.31322575e-10f, + 1.31708902e-09f, + 1.86264515e-09f, + 2.63417803e-09f, + 3.72529030e-09f, + 5.26835606e-09f, + 7.45058060e-09f, + 1.05367121e-08f, + 1.49011612e-08f, + 2.10734243e-08f, + 2.98023224e-08f, + 4.21468485e-08f, + 5.96046448e-08f, + 8.42936970e-08f, + 1.19209290e-07f, + 1.68587394e-07f, + 2.38418579e-07f, + 3.37174788e-07f, + 4.76837158e-07f, + 6.74349576e-07f, + 9.53674316e-07f, + 1.34869915e-06f, + 1.90734863e-06f, + 2.69739830e-06f, + 3.81469727e-06f, + 5.39479661e-06f, + 7.62939453e-06f, + 1.07895932e-05f, + 1.52587891e-05f, + 2.15791864e-05f, + 3.05175781e-05f, + 4.31583729e-05f, + 6.10351562e-05f, + 8.63167458e-05f, + 1.22070312e-04f, + 1.72633492e-04f, + 2.44140625e-04f, + 3.45266983e-04f, + 4.88281250e-04f, + 6.90533966e-04f, + 9.76562500e-04f, + 1.38106793e-03f, + 1.95312500e-03f, + 2.76213586e-03f, + 3.90625000e-03f, + 5.52427173e-03f, + 7.81250000e-03f, + 1.10485435e-02f, + 1.56250000e-02f, + 2.20970869e-02f, + 3.12500000e-02f, + 4.41941738e-02f, + 6.25000000e-02f, + 8.83883476e-02f, + 1.25000000e-01f, + 1.76776695e-01f, + 2.50000000e-01f, + 3.53553391e-01f, + 5.00000000e-01f, + 7.07106781e-01f, + 1.00000000e+00f, + 1.41421356e+00f, + 2.00000000e+00f, + 2.82842712e+00f, + 4.00000000e+00f, + 5.65685425e+00f, + 8.00000000e+00f, + 1.13137085e+01f, + 1.60000000e+01f, + 2.26274170e+01f, + 3.20000000e+01f, + 4.52548340e+01f, + 6.40000000e+01f, + 9.05096680e+01f, + 1.28000000e+02f, + 1.81019336e+02f, + 2.56000000e+02f, + 3.62038672e+02f, + 5.12000000e+02f, + 7.24077344e+02f, + 1.02400000e+03f, + 1.44815469e+03f, + 2.04800000e+03f, + 2.89630938e+03f, + 4.09600000e+03f, + 5.79261875e+03f, + 8.19200000e+03f, + 1.15852375e+04f, + 1.63840000e+04f, + 2.31704750e+04f, + 3.27680000e+04f, + 4.63409500e+04f, + 6.55360000e+04f, + 9.26819000e+04f, + 1.31072000e+05f, + 1.85363800e+05f, + 2.62144000e+05f, + 3.70727600e+05f, + 5.24288000e+05f, + 7.41455200e+05f, + 1.04857600e+06f, + 1.48291040e+06f, + 2.09715200e+06f, + 2.96582080e+06f, + 4.19430400e+06f, + 5.93164160e+06f, + 8.38860800e+06f, + 1.18632832e+07f, + 1.67772160e+07f, + 2.37265664e+07f, + 3.35544320e+07f, + 4.74531328e+07f, + 6.71088640e+07f, + 9.49062656e+07f, + 1.34217728e+08f, + 1.89812531e+08f, + 2.68435456e+08f, + 3.79625062e+08f, + 5.36870912e+08f, + 7.59250125e+08f, + 1.07374182e+09f, + 1.51850025e+09f, + 2.14748365e+09f, + 3.03700050e+09f, + 4.29496730e+09f, +}; + +const int16_t c_afRMSEnvReconstructTable_exp[ENV_RECONSTRUCT_TABLE_SIZE] = +{ + 62, 62, 61, 61, 60, 60, 59, 59, 58, 58, 57, 57, 56, 56, 55, 55, 54, 54, 53, 53, 52, 52, 51, 51, 50, 50, 49, 49, 48, 48, 47, 47, 46, 46, 45, 45, 44, 44, 43, 43, 42, 42, 41, 41, 40, 40, 39, 39, 38, 38, 37, 37, 36, 36, 35, 35, 34, 34, 33, 33, 32, 32, 31, 31, 30, 30, 29, 29, 28, 28, 27, 27, 26, 26, 25, 25, 24, 24, 23, 23, 22, 22, 21, 21, 20, 20, 19, 19, 18, 18, 17, 17, 16, 16, 15, 15, 14, 14, 13, 13, 12, 12, 11, 11, 10, 10, 9, 9, 8, 8, 7, 7, 6, 6, 5, 5, 4, 4, 3, 3, 2, 2, 1, 1, 0, 0, -1, -1, -2 +}; +const Word32 c_aiQuantMaxValues_fx[ALLOC_TABLE_SIZE] = { + //Q21 + 0, +6291456, +6291456, +8388608, +10485760, +10485760, +12582912, +14680064, +16777216, +18874368, +25165824, +27262976, +33554432, +35651584, +39845888, +48234496, +54525952, +54525952, +56623104, +58720256, +65011712, +75497472, +79691776, +94371840, +113246208, +134217728, +159383552, +188743680, +226492416, +268435456, +318767104, +377487360, +}; +const int32_t c_aiQuantMaxValues[ALLOC_TABLE_SIZE] = { + 0, + 3, + 3, + 4, + 5, + 5, + 6, + 7, + 8, + 9, + 12, + 13, + 16, + 17, + 19, + 23, + 26, + 26, + 27, + 28, + 31, + 36, + 38, + 45, + 54, + 64, + 76, + 90, + 108, + 128, + 152, + 180, +}; +const Word32 c_aiHuffmanDim_fx[ALLOC_TABLE_SIZE] = { + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, +}; + +const Word32 c_aiHuffmanMod_fx[ALLOC_TABLE_SIZE] = { + 0, + 4, + 4, + 5, + 6, + 6, + 7, + 8, + 9, + 10, + 13, + 14, + 17, + 18, + 20, + 24, + 27, + 27, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, +}; + +const int32_t c_aiHuffmanDim[ALLOC_TABLE_SIZE] = { + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, +}; + +const int32_t c_aiHuffmanMod[ALLOC_TABLE_SIZE] = { + 0, + 4, + 4, + 5, + 6, + 6, + 7, + 8, + 9, + 10, + 13, + 14, + 17, + 18, + 20, + 24, + 27, + 27, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, +}; +const int32_t c_aiHuffmanSize[ALLOC_TABLE_SIZE] = { + 1, + 16, + 16, + 25, + 36, + 36, + 49, + 64, + 81, + 100, + 169, + 196, + 289, + 324, + 400, + 576, + 729, + 729, + 28, + 29, + 32, + 37, + 39, + 46, + 55, + 65, + 77, + 91, + 109, + 129, + 153, + 181, +}; + +const uint32_t c_aaiRMSEnvHuffEnc[64][2] = { + { 0x0014, 0x0000 }, + { 0x0014, 0x0001 }, + { 0x0014, 0x0002 }, + { 0x0014, 0x0003 }, + { 0x0014, 0x0004 }, + { 0x0014, 0x0005 }, + { 0x0013, 0x0003 }, + { 0x0013, 0x0004 }, + { 0x0013, 0x0005 }, + { 0x0013, 0x0006 }, + { 0x0013, 0x0007 }, + { 0x0012, 0x000b }, + { 0x000d, 0x0002 }, + { 0x000e, 0x0001 }, + { 0x000e, 0x0002 }, + { 0x000d, 0x0003 }, + { 0x000b, 0x0002 }, + { 0x000a, 0x0003 }, + { 0x000a, 0x0004 }, + { 0x000a, 0x0005 }, + { 0x0009, 0x0004 }, + { 0x0009, 0x0005 }, + { 0x0009, 0x0006 }, + { 0x0008, 0x0005 }, + { 0x0008, 0x0006 }, + { 0x0007, 0x0004 }, + { 0x0006, 0x0003 }, + { 0x0006, 0x0004 }, + { 0x0005, 0x0003 }, + { 0x0004, 0x0002 }, + { 0x0003, 0x0002 }, + { 0x0002, 0x0002 }, + { 0x0002, 0x0003 }, + { 0x0003, 0x0003 }, + { 0x0004, 0x0003 }, + { 0x0006, 0x0005 }, + { 0x0007, 0x0005 }, + { 0x0008, 0x0007 }, + { 0x0009, 0x0007 }, + { 0x0009, 0x0008 }, + { 0x0009, 0x0009 }, + { 0x000a, 0x0006 }, + { 0x000a, 0x0007 }, + { 0x000b, 0x0003 }, + { 0x000c, 0x0002 }, + { 0x000c, 0x0003 }, + { 0x000b, 0x0004 }, + { 0x000b, 0x0005 }, + { 0x000e, 0x0003 }, + { 0x0010, 0x0003 }, + { 0x0013, 0x0008 }, + { 0x0013, 0x0009 }, + { 0x0013, 0x000a }, + { 0x0013, 0x000b }, + { 0x0013, 0x000c }, + { 0x0013, 0x000d }, + { 0x0013, 0x000e }, + { 0x0013, 0x000f }, + { 0x0013, 0x0010 }, + { 0x0013, 0x0011 }, + { 0x0013, 0x0012 }, + { 0x0013, 0x0013 }, + { 0x0013, 0x0014 }, + { 0x0013, 0x0015 }, +}; + +const uint32_t c_aaiRMSEnvHuffDec[13][HUFF_DEC_TABLE_SIZE] = { + { + 0x0002ffff, + 0x0001ffff, + 0x0000001d, + 0x00000022, + 0x0001001e, + 0x0001001e, + 0x00010021, + 0x00010021, + 0x0002001f, + 0x0002001f, + 0x0002001f, + 0x0002001f, + 0x00020020, + 0x00020020, + 0x00020020, + 0x00020020, + }, + { + 0x0002001b, + 0x0002001b, + 0x0002001b, + 0x0002001b, + 0x00020023, + 0x00020023, + 0x00020023, + 0x00020023, + 0x0003001c, + 0x0003001c, + 0x0003001c, + 0x0003001c, + 0x0003001c, + 0x0003001c, + 0x0003001c, + 0x0003001c, + }, + { + 0x0006ffff, + 0x0007ffff, + 0x0003ffff, + 0x0004ffff, + 0x0005ffff, + 0x00000017, + 0x00000018, + 0x00000025, + 0x00010019, + 0x00010019, + 0x00010024, + 0x00010024, + 0x0002001a, + 0x0002001a, + 0x0002001a, + 0x0002001a, + }, + { + 0x00030014, + 0x00030014, + 0x00030014, + 0x00030014, + 0x00030014, + 0x00030014, + 0x00030014, + 0x00030014, + 0x00030015, + 0x00030015, + 0x00030015, + 0x00030015, + 0x00030015, + 0x00030015, + 0x00030015, + 0x00030015, + }, + { + 0x00030016, + 0x00030016, + 0x00030016, + 0x00030016, + 0x00030016, + 0x00030016, + 0x00030016, + 0x00030016, + 0x00030026, + 0x00030026, + 0x00030026, + 0x00030026, + 0x00030026, + 0x00030026, + 0x00030026, + 0x00030026, + }, + { + 0x00030027, + 0x00030027, + 0x00030027, + 0x00030027, + 0x00030027, + 0x00030027, + 0x00030027, + 0x00030027, + 0x00030028, + 0x00030028, + 0x00030028, + 0x00030028, + 0x00030028, + 0x00030028, + 0x00030028, + 0x00030028, + }, + { + 0x0009ffff, + 0x0008ffff, + 0x0000002c, + 0x0000002d, + 0x00010010, + 0x00010010, + 0x0001002b, + 0x0001002b, + 0x0001002e, + 0x0001002e, + 0x0001002f, + 0x0001002f, + 0x00020011, + 0x00020011, + 0x00020011, + 0x00020011, + }, + { + 0x00020012, + 0x00020012, + 0x00020012, + 0x00020012, + 0x00020013, + 0x00020013, + 0x00020013, + 0x00020013, + 0x00020029, + 0x00020029, + 0x00020029, + 0x00020029, + 0x0002002a, + 0x0002002a, + 0x0002002a, + 0x0002002a, + }, + { + 0x0003000c, + 0x0003000c, + 0x0003000c, + 0x0003000c, + 0x0003000c, + 0x0003000c, + 0x0003000c, + 0x0003000c, + 0x0003000f, + 0x0003000f, + 0x0003000f, + 0x0003000f, + 0x0003000f, + 0x0003000f, + 0x0003000f, + 0x0003000f, + }, + { + 0x000bffff, + 0x000cffff, + 0x000affff, + 0x00000031, + 0x0002000d, + 0x0002000d, + 0x0002000d, + 0x0002000d, + 0x0002000e, + 0x0002000e, + 0x0002000e, + 0x0002000e, + 0x00020030, + 0x00020030, + 0x00020030, + 0x00020030, + }, + { + 0x0001003a, + 0x0001003a, + 0x0001003b, + 0x0001003b, + 0x0001003c, + 0x0001003c, + 0x0001003d, + 0x0001003d, + 0x0001003e, + 0x0001003e, + 0x0001003f, + 0x0001003f, + 0x0002000b, + 0x0002000b, + 0x0002000b, + 0x0002000b, + }, + { + 0x00000000, + 0x00000001, + 0x00000002, + 0x00000003, + 0x00000004, + 0x00000005, + 0x00010006, + 0x00010006, + 0x00010007, + 0x00010007, + 0x00010008, + 0x00010008, + 0x00010009, + 0x00010009, + 0x0001000a, + 0x0001000a, + }, + { + 0x00010032, + 0x00010032, + 0x00010033, + 0x00010033, + 0x00010034, + 0x00010034, + 0x00010035, + 0x00010035, + 0x00010036, + 0x00010036, + 0x00010037, + 0x00010037, + 0x00010038, + 0x00010038, + 0x00010039, + 0x00010039, + }, +}; + +const uint16_t c_aauiLCLDHuffEnc1[16][2] = + { + { 0x0001, 0x0001 }, + { 0x0003, 0x0001 }, + { 0x0005, 0x0001 }, + { 0x000b, 0x0000 }, + { 0x0002, 0x0001 }, + { 0x0004, 0x0001 }, + { 0x0007, 0x0001 }, + { 0x000b, 0x0001 }, + { 0x0006, 0x0001 }, + { 0x0008, 0x0001 }, + { 0x000b, 0x0002 }, + { 0x000b, 0x0003 }, + { 0x000b, 0x0004 }, + { 0x000b, 0x0005 }, + { 0x000b, 0x0006 }, + { 0x000b, 0x0007 }, + }; + +const uint16_t c_aauiLCLDHuffEnc2[16][2] = + { + { 0x0001, 0x0001 }, + { 0x0003, 0x0001 }, + { 0x0005, 0x0001 }, + { 0x000c, 0x0000 }, + { 0x0002, 0x0001 }, + { 0x0004, 0x0001 }, + { 0x0007, 0x0001 }, + { 0x000c, 0x0001 }, + { 0x0006, 0x0001 }, + { 0x0008, 0x0001 }, + { 0x0009, 0x0001 }, + { 0x000c, 0x0002 }, + { 0x000c, 0x0003 }, + { 0x000c, 0x0004 }, + { 0x000c, 0x0005 }, + { 0x000b, 0x0003 }, + }; + +const uint16_t c_aauiLCLDHuffEnc3[25][2] = + { + { 0x0001, 0x0001 }, + { 0x0003, 0x0001 }, + { 0x0006, 0x0001 }, + { 0x000d, 0x0000 }, + { 0x000d, 0x0001 }, + { 0x0002, 0x0001 }, + { 0x0004, 0x0001 }, + { 0x0007, 0x0001 }, + { 0x000d, 0x0002 }, + { 0x000d, 0x0003 }, + { 0x0006, 0x0002 }, + { 0x0006, 0x0003 }, + { 0x0008, 0x0001 }, + { 0x000d, 0x0004 }, + { 0x000d, 0x0005 }, + { 0x0009, 0x0001 }, + { 0x000c, 0x0007 }, + { 0x000d, 0x0006 }, + { 0x000d, 0x0007 }, + { 0x000d, 0x0008 }, + { 0x000d, 0x0009 }, + { 0x000d, 0x000a }, + { 0x000d, 0x000b }, + { 0x000d, 0x000c }, + { 0x000d, 0x000d }, + + }; + +const uint16_t c_aauiLCLDHuffEnc4[36][2] = + { + { 0x0001, 0x0001 }, + { 0x0003, 0x0001 }, + { 0x0006, 0x0001 }, + { 0x000b, 0x0001 }, + { 0x0010, 0x0000 }, + { 0x0010, 0x0001 }, + { 0x0002, 0x0001 }, + { 0x0004, 0x0001 }, + { 0x0007, 0x0001 }, + { 0x000a, 0x0001 }, + { 0x0010, 0x0002 }, + { 0x0010, 0x0003 }, + { 0x0006, 0x0002 }, + { 0x0006, 0x0003 }, + { 0x0008, 0x0001 }, + { 0x000e, 0x0006 }, + { 0x0010, 0x0004 }, + { 0x0010, 0x0005 }, + { 0x000a, 0x0002 }, + { 0x000a, 0x0003 }, + { 0x000e, 0x0007 }, + { 0x0010, 0x0006 }, + { 0x0010, 0x0007 }, + { 0x0010, 0x0008 }, + { 0x0010, 0x0009 }, + { 0x0010, 0x000a }, + { 0x0010, 0x000b }, + { 0x0010, 0x000c }, + { 0x0010, 0x000d }, + { 0x0010, 0x000e }, + { 0x0010, 0x000f }, + { 0x0010, 0x0010 }, + { 0x0010, 0x0011 }, + { 0x000f, 0x0009 }, + { 0x000f, 0x000a }, + { 0x000f, 0x000b }, + + }; + +const uint16_t c_aauiLCLDHuffEnc5[36][2] = + { + { 0x0001, 0x0001 }, + { 0x0003, 0x0001 }, + { 0x0006, 0x0001 }, + { 0x000a, 0x0001 }, + { 0x000f, 0x0003 }, + { 0x0012, 0x0000 }, + { 0x0002, 0x0001 }, + { 0x0004, 0x0001 }, + { 0x0007, 0x0001 }, + { 0x000b, 0x0001 }, + { 0x0011, 0x0008 }, + { 0x0012, 0x0001 }, + { 0x0006, 0x0002 }, + { 0x0006, 0x0003 }, + { 0x0008, 0x0001 }, + { 0x000c, 0x0001 }, + { 0x0012, 0x0002 }, + { 0x0012, 0x0003 }, + { 0x000a, 0x0002 }, + { 0x000a, 0x0003 }, + { 0x000d, 0x0001 }, + { 0x0012, 0x0004 }, + { 0x0012, 0x0005 }, + { 0x0012, 0x0006 }, + { 0x0011, 0x0009 }, + { 0x0011, 0x000a }, + { 0x0012, 0x0007 }, + { 0x0012, 0x0008 }, + { 0x0012, 0x0009 }, + { 0x0012, 0x000a }, + { 0x0012, 0x000b }, + { 0x0012, 0x000c }, + { 0x0012, 0x000d }, + { 0x0012, 0x000e }, + { 0x0012, 0x000f }, + { 0x0011, 0x000b }, + + }; + +const uint16_t c_aauiLCLDHuffEnc6[49][2] = + { + { 0x0001, 0x0001 }, + { 0x0003, 0x0001 }, + { 0x0006, 0x0001 }, + { 0x000a, 0x0001 }, + { 0x0010, 0x0003 }, + { 0x0014, 0x0000 }, + { 0x0014, 0x0001 }, + { 0x0002, 0x0001 }, + { 0x0004, 0x0001 }, + { 0x0007, 0x0001 }, + { 0x000a, 0x0002 }, + { 0x0010, 0x0004 }, + { 0x0014, 0x0002 }, + { 0x0014, 0x0003 }, + { 0x0006, 0x0002 }, + { 0x0006, 0x0003 }, + { 0x0008, 0x0001 }, + { 0x000d, 0x0001 }, + { 0x0012, 0x0007 }, + { 0x0014, 0x0004 }, + { 0x0014, 0x0005 }, + { 0x000a, 0x0003 }, + { 0x000b, 0x0001 }, + { 0x000c, 0x0001 }, + { 0x0011, 0x0004 }, + { 0x0014, 0x0006 }, + { 0x0014, 0x0007 }, + { 0x0014, 0x0008 }, + { 0x0010, 0x0005 }, + { 0x000f, 0x0003 }, + { 0x0011, 0x0005 }, + { 0x0014, 0x0009 }, + { 0x0014, 0x000a }, + { 0x0014, 0x000b }, + { 0x0014, 0x000c }, + { 0x0014, 0x000d }, + { 0x0013, 0x000d }, + { 0x0014, 0x000e }, + { 0x0014, 0x000f }, + { 0x0014, 0x0010 }, + { 0x0014, 0x0011 }, + { 0x0014, 0x0012 }, + { 0x0014, 0x0013 }, + { 0x0014, 0x0014 }, + { 0x0014, 0x0015 }, + { 0x0014, 0x0016 }, + { 0x0014, 0x0017 }, + { 0x0014, 0x0018 }, + { 0x0014, 0x0019 }, + + }; + +const uint16_t c_aauiLCLDHuffEnc7[64][2] = + { + { 0x0002, 0x0001 }, + { 0x0002, 0x0002 }, + { 0x0005, 0x0001 }, + { 0x0009, 0x0001 }, + { 0x000f, 0x0002 }, + { 0x0015, 0x0000 }, + { 0x0015, 0x0001 }, + { 0x0015, 0x0002 }, + { 0x0002, 0x0003 }, + { 0x0003, 0x0001 }, + { 0x0006, 0x0001 }, + { 0x0009, 0x0002 }, + { 0x000f, 0x0003 }, + { 0x0014, 0x0011 }, + { 0x0015, 0x0003 }, + { 0x0015, 0x0004 }, + { 0x0005, 0x0002 }, + { 0x0005, 0x0003 }, + { 0x0007, 0x0001 }, + { 0x000b, 0x0001 }, + { 0x0010, 0x0002 }, + { 0x0015, 0x0005 }, + { 0x0015, 0x0006 }, + { 0x0015, 0x0007 }, + { 0x000a, 0x0001 }, + { 0x0009, 0x0003 }, + { 0x000c, 0x0001 }, + { 0x000f, 0x0004 }, + { 0x0012, 0x0006 }, + { 0x0015, 0x0008 }, + { 0x0015, 0x0009 }, + { 0x0015, 0x000a }, + { 0x000f, 0x0005 }, + { 0x000e, 0x0003 }, + { 0x0010, 0x0003 }, + { 0x0012, 0x0007 }, + { 0x0014, 0x0012 }, + { 0x0015, 0x000b }, + { 0x0015, 0x000c }, + { 0x0015, 0x000d }, + { 0x0014, 0x0013 }, + { 0x0014, 0x0014 }, + { 0x0013, 0x000b }, + { 0x0014, 0x0015 }, + { 0x0015, 0x000e }, + { 0x0015, 0x000f }, + { 0x0015, 0x0010 }, + { 0x0015, 0x0011 }, + { 0x0015, 0x0012 }, + { 0x0015, 0x0013 }, + { 0x0015, 0x0014 }, + { 0x0015, 0x0015 }, + { 0x0015, 0x0016 }, + { 0x0015, 0x0017 }, + { 0x0015, 0x0018 }, + { 0x0015, 0x0019 }, + { 0x0015, 0x001a }, + { 0x0015, 0x001b }, + { 0x0015, 0x001c }, + { 0x0015, 0x001d }, + { 0x0015, 0x001e }, + { 0x0015, 0x001f }, + { 0x0015, 0x0020 }, + { 0x0015, 0x0021 }, + }; + +const uint16_t c_aauiLCLDHuffEnc8[81][2] = + { + { 0x0001, 0x0001 }, + { 0x0003, 0x0001 }, + { 0x0006, 0x0001 }, + { 0x000a, 0x0001 }, + { 0x000f, 0x0002 }, + { 0x0014, 0x0008 }, + { 0x0017, 0x0000 }, + { 0x0017, 0x0001 }, + { 0x0017, 0x0002 }, + { 0x0003, 0x0002 }, + { 0x0003, 0x0003 }, + { 0x0005, 0x0001 }, + { 0x0009, 0x0001 }, + { 0x000f, 0x0003 }, + { 0x0012, 0x0004 }, + { 0x0015, 0x000d }, + { 0x0017, 0x0003 }, + { 0x0017, 0x0004 }, + { 0x0005, 0x0002 }, + { 0x0005, 0x0003 }, + { 0x0007, 0x0001 }, + { 0x000c, 0x0001 }, + { 0x0010, 0x0002 }, + { 0x0013, 0x0005 }, + { 0x0017, 0x0005 }, + { 0x0017, 0x0006 }, + { 0x0017, 0x0007 }, + { 0x0009, 0x0002 }, + { 0x0009, 0x0003 }, + { 0x000b, 0x0001 }, + { 0x000f, 0x0004 }, + { 0x0012, 0x0005 }, + { 0x0016, 0x0015 }, + { 0x0017, 0x0008 }, + { 0x0017, 0x0009 }, + { 0x0017, 0x000a }, + { 0x000f, 0x0005 }, + { 0x000e, 0x0003 }, + { 0x0010, 0x0003 }, + { 0x0012, 0x0006 }, + { 0x0014, 0x0009 }, + { 0x0017, 0x000b }, + { 0x0017, 0x000c }, + { 0x0017, 0x000d }, + { 0x0017, 0x000e }, + { 0x0013, 0x0006 }, + { 0x0012, 0x0007 }, + { 0x0013, 0x0007 }, + { 0x0015, 0x000e }, + { 0x0017, 0x000f }, + { 0x0017, 0x0010 }, + { 0x0017, 0x0011 }, + { 0x0017, 0x0012 }, + { 0x0017, 0x0013 }, + { 0x0016, 0x0016 }, + { 0x0016, 0x0017 }, + { 0x0015, 0x000f }, + { 0x0016, 0x0018 }, + { 0x0017, 0x0014 }, + { 0x0017, 0x0015 }, + { 0x0017, 0x0016 }, + { 0x0017, 0x0017 }, + { 0x0017, 0x0018 }, + { 0x0017, 0x0019 }, + { 0x0017, 0x001a }, + { 0x0017, 0x001b }, + { 0x0017, 0x001c }, + { 0x0017, 0x001d }, + { 0x0017, 0x001e }, + { 0x0017, 0x001f }, + { 0x0017, 0x0020 }, + { 0x0017, 0x0021 }, + { 0x0017, 0x0022 }, + { 0x0017, 0x0023 }, + { 0x0017, 0x0024 }, + { 0x0017, 0x0025 }, + { 0x0017, 0x0026 }, + { 0x0017, 0x0027 }, + { 0x0017, 0x0028 }, + { 0x0017, 0x0029 }, + { 0x0016, 0x0019 }, + + }; + +const uint16_t c_aauiLCLDHuffEnc9[100][2] = + { + { 0x0001, 0x0001 }, + { 0x0003, 0x0001 }, + { 0x0006, 0x0001 }, + { 0x0009, 0x0001 }, + { 0x000d, 0x0002 }, + { 0x0011, 0x0004 }, + { 0x0014, 0x000a }, + { 0x0017, 0x0000 }, + { 0x0017, 0x0001 }, + { 0x0017, 0x0002 }, + { 0x0003, 0x0002 }, + { 0x0003, 0x0003 }, + { 0x0005, 0x0001 }, + { 0x0009, 0x0002 }, + { 0x000d, 0x0003 }, + { 0x0010, 0x0004 }, + { 0x0013, 0x0007 }, + { 0x0016, 0x0018 }, + { 0x0017, 0x0003 }, + { 0x0017, 0x0004 }, + { 0x0005, 0x0002 }, + { 0x0005, 0x0003 }, + { 0x0008, 0x0002 }, + { 0x000b, 0x0002 }, + { 0x000e, 0x0002 }, + { 0x0011, 0x0005 }, + { 0x0014, 0x000b }, + { 0x0016, 0x0019 }, + { 0x0017, 0x0005 }, + { 0x0017, 0x0006 }, + { 0x0009, 0x0003 }, + { 0x0008, 0x0003 }, + { 0x000b, 0x0003 }, + { 0x000d, 0x0004 }, + { 0x0010, 0x0005 }, + { 0x0012, 0x0006 }, + { 0x0015, 0x000f }, + { 0x0017, 0x0007 }, + { 0x0017, 0x0008 }, + { 0x0017, 0x0009 }, + { 0x000d, 0x0005 }, + { 0x000c, 0x0003 }, + { 0x000e, 0x0003 }, + { 0x0010, 0x0006 }, + { 0x0012, 0x0007 }, + { 0x0014, 0x000c }, + { 0x0017, 0x000a }, + { 0x0016, 0x001a }, + { 0x0017, 0x000b }, + { 0x0017, 0x000c }, + { 0x0011, 0x0006 }, + { 0x0010, 0x0007 }, + { 0x0011, 0x0007 }, + { 0x0013, 0x0008 }, + { 0x0013, 0x0009 }, + { 0x0015, 0x0010 }, + { 0x0017, 0x000d }, + { 0x0017, 0x000e }, + { 0x0017, 0x000f }, + { 0x0017, 0x0010 }, + { 0x0013, 0x000a }, + { 0x0013, 0x000b }, + { 0x0014, 0x000d }, + { 0x0015, 0x0011 }, + { 0x0017, 0x0011 }, + { 0x0016, 0x001b }, + { 0x0017, 0x0012 }, + { 0x0017, 0x0013 }, + { 0x0017, 0x0014 }, + { 0x0017, 0x0015 }, + { 0x0017, 0x0016 }, + { 0x0015, 0x0012 }, + { 0x0015, 0x0013 }, + { 0x0017, 0x0017 }, + { 0x0016, 0x001c }, + { 0x0017, 0x0018 }, + { 0x0017, 0x0019 }, + { 0x0017, 0x001a }, + { 0x0017, 0x001b }, + { 0x0017, 0x001c }, + { 0x0017, 0x001d }, + { 0x0017, 0x001e }, + { 0x0017, 0x001f }, + { 0x0017, 0x0020 }, + { 0x0017, 0x0021 }, + { 0x0017, 0x0022 }, + { 0x0017, 0x0023 }, + { 0x0017, 0x0024 }, + { 0x0017, 0x0025 }, + { 0x0017, 0x0026 }, + { 0x0017, 0x0027 }, + { 0x0017, 0x0028 }, + { 0x0017, 0x0029 }, + { 0x0017, 0x002a }, + { 0x0017, 0x002b }, + { 0x0017, 0x002c }, + { 0x0017, 0x002d }, + { 0x0017, 0x002e }, + { 0x0017, 0x002f }, + { 0x0016, 0x001d }, + + }; + +const uint16_t c_aauiLCLDHuffEnc10[169][2] = + { + { 0x0001, 0x0001 }, + { 0x0004, 0x0002 }, + { 0x0005, 0x0002 }, + { 0x0007, 0x0002 }, + { 0x000a, 0x0002 }, + { 0x000e, 0x0004 }, + { 0x0011, 0x0007 }, + { 0x0013, 0x0012 }, + { 0x0016, 0x0000 }, + { 0x0016, 0x0001 }, + { 0x0016, 0x0002 }, + { 0x0016, 0x0003 }, + { 0x0016, 0x0004 }, + { 0x0004, 0x0003 }, + { 0x0003, 0x0003 }, + { 0x0004, 0x0004 }, + { 0x0007, 0x0003 }, + { 0x000a, 0x0003 }, + { 0x000d, 0x0004 }, + { 0x0010, 0x0007 }, + { 0x0013, 0x0013 }, + { 0x0015, 0x0035 }, + { 0x0016, 0x0005 }, + { 0x0016, 0x0006 }, + { 0x0016, 0x0007 }, + { 0x0016, 0x0008 }, + { 0x0005, 0x0003 }, + { 0x0004, 0x0005 }, + { 0x0006, 0x0003 }, + { 0x0008, 0x0002 }, + { 0x000b, 0x0002 }, + { 0x000e, 0x0005 }, + { 0x0010, 0x0008 }, + { 0x0013, 0x0014 }, + { 0x0014, 0x001d }, + { 0x0016, 0x0009 }, + { 0x0016, 0x000a }, + { 0x0016, 0x000b }, + { 0x0016, 0x000c }, + { 0x0007, 0x0004 }, + { 0x0007, 0x0005 }, + { 0x0008, 0x0003 }, + { 0x000a, 0x0004 }, + { 0x000d, 0x0005 }, + { 0x000f, 0x0005 }, + { 0x0011, 0x0008 }, + { 0x0014, 0x001e }, + { 0x0014, 0x001f }, + { 0x0016, 0x000d }, + { 0x0016, 0x000e }, + { 0x0016, 0x000f }, + { 0x0016, 0x0010 }, + { 0x000a, 0x0005 }, + { 0x0009, 0x0003 }, + { 0x000b, 0x0003 }, + { 0x000d, 0x0006 }, + { 0x000f, 0x0006 }, + { 0x0011, 0x0009 }, + { 0x0013, 0x0015 }, + { 0x0014, 0x0020 }, + { 0x0016, 0x0011 }, + { 0x0016, 0x0012 }, + { 0x0016, 0x0013 }, + { 0x0016, 0x0014 }, + { 0x0016, 0x0015 }, + { 0x000e, 0x0006 }, + { 0x000d, 0x0007 }, + { 0x000e, 0x0007 }, + { 0x000f, 0x0007 }, + { 0x0011, 0x000a }, + { 0x0012, 0x000c }, + { 0x0016, 0x0016 }, + { 0x0016, 0x0017 }, + { 0x0016, 0x0018 }, + { 0x0016, 0x0019 }, + { 0x0016, 0x001a }, + { 0x0016, 0x001b }, + { 0x0016, 0x001c }, + { 0x0011, 0x000b }, + { 0x0010, 0x0009 }, + { 0x0011, 0x000c }, + { 0x0011, 0x000d }, + { 0x0013, 0x0016 }, + { 0x0016, 0x001d }, + { 0x0016, 0x001e }, + { 0x0016, 0x001f }, + { 0x0016, 0x0020 }, + { 0x0016, 0x0021 }, + { 0x0016, 0x0022 }, + { 0x0016, 0x0023 }, + { 0x0016, 0x0024 }, + { 0x0014, 0x0021 }, + { 0x0014, 0x0022 }, + { 0x0012, 0x000d }, + { 0x0013, 0x0017 }, + { 0x0016, 0x0025 }, + { 0x0016, 0x0026 }, + { 0x0016, 0x0027 }, + { 0x0016, 0x0028 }, + { 0x0016, 0x0029 }, + { 0x0016, 0x002a }, + { 0x0016, 0x002b }, + { 0x0016, 0x002c }, + { 0x0016, 0x002d }, + { 0x0015, 0x0036 }, + { 0x0015, 0x0037 }, + { 0x0014, 0x0023 }, + { 0x0015, 0x0038 }, + { 0x0016, 0x002e }, + { 0x0016, 0x002f }, + { 0x0016, 0x0030 }, + { 0x0016, 0x0031 }, + { 0x0016, 0x0032 }, + { 0x0016, 0x0033 }, + { 0x0016, 0x0034 }, + { 0x0016, 0x0035 }, + { 0x0016, 0x0036 }, + { 0x0016, 0x0037 }, + { 0x0016, 0x0038 }, + { 0x0016, 0x0039 }, + { 0x0016, 0x003a }, + { 0x0016, 0x003b }, + { 0x0016, 0x003c }, + { 0x0016, 0x003d }, + { 0x0016, 0x003e }, + { 0x0016, 0x003f }, + { 0x0016, 0x0040 }, + { 0x0016, 0x0041 }, + { 0x0016, 0x0042 }, + { 0x0016, 0x0043 }, + { 0x0016, 0x0044 }, + { 0x0016, 0x0045 }, + { 0x0016, 0x0046 }, + { 0x0016, 0x0047 }, + { 0x0016, 0x0048 }, + { 0x0016, 0x0049 }, + { 0x0016, 0x004a }, + { 0x0016, 0x004b }, + { 0x0016, 0x004c }, + { 0x0016, 0x004d }, + { 0x0016, 0x004e }, + { 0x0016, 0x004f }, + { 0x0016, 0x0050 }, + { 0x0016, 0x0051 }, + { 0x0016, 0x0052 }, + { 0x0016, 0x0053 }, + { 0x0016, 0x0054 }, + { 0x0016, 0x0055 }, + { 0x0016, 0x0056 }, + { 0x0016, 0x0057 }, + { 0x0016, 0x0058 }, + { 0x0016, 0x0059 }, + { 0x0016, 0x005a }, + { 0x0016, 0x005b }, + { 0x0016, 0x005c }, + { 0x0016, 0x005d }, + { 0x0016, 0x005e }, + { 0x0016, 0x005f }, + { 0x0016, 0x0060 }, + { 0x0016, 0x0061 }, + { 0x0016, 0x0062 }, + { 0x0016, 0x0063 }, + { 0x0016, 0x0064 }, + { 0x0016, 0x0065 }, + { 0x0016, 0x0066 }, + { 0x0016, 0x0067 }, + { 0x0016, 0x0068 }, + { 0x0016, 0x0069 }, + { 0x0015, 0x0039 }, + + }; + +const uint16_t c_aauiLCLDHuffEnc11[196][2] = + { + { 0x0001, 0x0001 }, + { 0x0004, 0x0003 }, + { 0x0005, 0x0003 }, + { 0x0007, 0x0002 }, + { 0x0009, 0x0003 }, + { 0x000c, 0x0004 }, + { 0x000f, 0x0005 }, + { 0x0012, 0x000d }, + { 0x0014, 0x001f }, + { 0x0016, 0x0000 }, + { 0x0016, 0x0001 }, + { 0x0016, 0x0002 }, + { 0x0016, 0x0003 }, + { 0x0016, 0x0004 }, + { 0x0004, 0x0004 }, + { 0x0003, 0x0003 }, + { 0x0005, 0x0004 }, + { 0x0006, 0x0003 }, + { 0x0009, 0x0004 }, + { 0x000b, 0x0004 }, + { 0x000e, 0x0005 }, + { 0x0010, 0x0007 }, + { 0x0012, 0x000e }, + { 0x0014, 0x0020 }, + { 0x0016, 0x0005 }, + { 0x0016, 0x0006 }, + { 0x0016, 0x0007 }, + { 0x0016, 0x0008 }, + { 0x0005, 0x0005 }, + { 0x0004, 0x0005 }, + { 0x0006, 0x0004 }, + { 0x0007, 0x0003 }, + { 0x000a, 0x0004 }, + { 0x000c, 0x0005 }, + { 0x000e, 0x0006 }, + { 0x0011, 0x000a }, + { 0x0012, 0x000f }, + { 0x0015, 0x003b }, + { 0x0016, 0x0009 }, + { 0x0016, 0x000a }, + { 0x0016, 0x000b }, + { 0x0016, 0x000c }, + { 0x0007, 0x0004 }, + { 0x0006, 0x0005 }, + { 0x0007, 0x0005 }, + { 0x0009, 0x0005 }, + { 0x000b, 0x0005 }, + { 0x000d, 0x0005 }, + { 0x000f, 0x0006 }, + { 0x0012, 0x0010 }, + { 0x0014, 0x0021 }, + { 0x0016, 0x000d }, + { 0x0016, 0x000e }, + { 0x0016, 0x000f }, + { 0x0016, 0x0010 }, + { 0x0016, 0x0011 }, + { 0x0009, 0x0006 }, + { 0x0009, 0x0007 }, + { 0x000a, 0x0005 }, + { 0x000b, 0x0006 }, + { 0x000d, 0x0006 }, + { 0x000f, 0x0007 }, + { 0x0011, 0x000b }, + { 0x0013, 0x0017 }, + { 0x0014, 0x0022 }, + { 0x0016, 0x0012 }, + { 0x0016, 0x0013 }, + { 0x0016, 0x0014 }, + { 0x0016, 0x0015 }, + { 0x0016, 0x0016 }, + { 0x000c, 0x0006 }, + { 0x000b, 0x0007 }, + { 0x000c, 0x0007 }, + { 0x000d, 0x0007 }, + { 0x000e, 0x0007 }, + { 0x0010, 0x0008 }, + { 0x0012, 0x0011 }, + { 0x0014, 0x0023 }, + { 0x0015, 0x003c }, + { 0x0016, 0x0017 }, + { 0x0016, 0x0018 }, + { 0x0016, 0x0019 }, + { 0x0016, 0x001a }, + { 0x0016, 0x001b }, + { 0x000f, 0x0008 }, + { 0x000e, 0x0008 }, + { 0x000e, 0x0009 }, + { 0x000f, 0x0009 }, + { 0x0011, 0x000c }, + { 0x0013, 0x0018 }, + { 0x0014, 0x0024 }, + { 0x0016, 0x001c }, + { 0x0016, 0x001d }, + { 0x0016, 0x001e }, + { 0x0016, 0x001f }, + { 0x0016, 0x0020 }, + { 0x0016, 0x0021 }, + { 0x0016, 0x0022 }, + { 0x0011, 0x000d }, + { 0x0010, 0x0009 }, + { 0x0012, 0x0012 }, + { 0x0012, 0x0013 }, + { 0x0014, 0x0025 }, + { 0x0015, 0x003d }, + { 0x0014, 0x0026 }, + { 0x0016, 0x0023 }, + { 0x0016, 0x0024 }, + { 0x0016, 0x0025 }, + { 0x0016, 0x0026 }, + { 0x0016, 0x0027 }, + { 0x0016, 0x0028 }, + { 0x0016, 0x0029 }, + { 0x0014, 0x0027 }, + { 0x0013, 0x0019 }, + { 0x0014, 0x0028 }, + { 0x0014, 0x0029 }, + { 0x0014, 0x002a }, + { 0x0016, 0x002a }, + { 0x0016, 0x002b }, + { 0x0016, 0x002c }, + { 0x0016, 0x002d }, + { 0x0016, 0x002e }, + { 0x0016, 0x002f }, + { 0x0016, 0x0030 }, + { 0x0016, 0x0031 }, + { 0x0016, 0x0032 }, + { 0x0014, 0x002b }, + { 0x0014, 0x002c }, + { 0x0014, 0x002d }, + { 0x0016, 0x0033 }, + { 0x0016, 0x0034 }, + { 0x0016, 0x0035 }, + { 0x0016, 0x0036 }, + { 0x0016, 0x0037 }, + { 0x0016, 0x0038 }, + { 0x0016, 0x0039 }, + { 0x0016, 0x003a }, + { 0x0016, 0x003b }, + { 0x0016, 0x003c }, + { 0x0016, 0x003d }, + { 0x0016, 0x003e }, + { 0x0016, 0x003f }, + { 0x0016, 0x0040 }, + { 0x0016, 0x0041 }, + { 0x0016, 0x0042 }, + { 0x0016, 0x0043 }, + { 0x0016, 0x0044 }, + { 0x0016, 0x0045 }, + { 0x0016, 0x0046 }, + { 0x0016, 0x0047 }, + { 0x0016, 0x0048 }, + { 0x0016, 0x0049 }, + { 0x0016, 0x004a }, + { 0x0016, 0x004b }, + { 0x0016, 0x004c }, + { 0x0016, 0x004d }, + { 0x0016, 0x004e }, + { 0x0016, 0x004f }, + { 0x0016, 0x0050 }, + { 0x0016, 0x0051 }, + { 0x0016, 0x0052 }, + { 0x0016, 0x0053 }, + { 0x0016, 0x0054 }, + { 0x0016, 0x0055 }, + { 0x0016, 0x0056 }, + { 0x0016, 0x0057 }, + { 0x0016, 0x0058 }, + { 0x0016, 0x0059 }, + { 0x0016, 0x005a }, + { 0x0016, 0x005b }, + { 0x0016, 0x005c }, + { 0x0016, 0x005d }, + { 0x0016, 0x005e }, + { 0x0016, 0x005f }, + { 0x0016, 0x0060 }, + { 0x0016, 0x0061 }, + { 0x0016, 0x0062 }, + { 0x0016, 0x0063 }, + { 0x0016, 0x0064 }, + { 0x0016, 0x0065 }, + { 0x0016, 0x0066 }, + { 0x0016, 0x0067 }, + { 0x0016, 0x0068 }, + { 0x0016, 0x0069 }, + { 0x0016, 0x006a }, + { 0x0016, 0x006b }, + { 0x0016, 0x006c }, + { 0x0016, 0x006d }, + { 0x0016, 0x006e }, + { 0x0016, 0x006f }, + { 0x0016, 0x0070 }, + { 0x0016, 0x0071 }, + { 0x0016, 0x0072 }, + { 0x0016, 0x0073 }, + { 0x0016, 0x0074 }, + { 0x0016, 0x0075 }, + + }; + +const uint16_t c_aauiLCLDHuffEnc12[289][2] = + { + { 0x0001, 0x0001 }, + { 0x0004, 0x0004 }, + { 0x0005, 0x0004 }, + { 0x0007, 0x0004 }, + { 0x0008, 0x0002 }, + { 0x000b, 0x0004 }, + { 0x000e, 0x0006 }, + { 0x0010, 0x0009 }, + { 0x0012, 0x0014 }, + { 0x0013, 0x001f }, + { 0x0016, 0x0000 }, + { 0x0016, 0x0001 }, + { 0x0016, 0x0002 }, + { 0x0016, 0x0003 }, + { 0x0016, 0x0004 }, + { 0x0016, 0x0005 }, + { 0x0016, 0x0006 }, + { 0x0004, 0x0005 }, + { 0x0004, 0x0006 }, + { 0x0005, 0x0005 }, + { 0x0006, 0x0003 }, + { 0x0008, 0x0003 }, + { 0x000a, 0x0004 }, + { 0x000d, 0x0006 }, + { 0x000f, 0x0008 }, + { 0x0011, 0x000c }, + { 0x0013, 0x0020 }, + { 0x0016, 0x0007 }, + { 0x0015, 0x0063 }, + { 0x0016, 0x0008 }, + { 0x0016, 0x0009 }, + { 0x0016, 0x000a }, + { 0x0016, 0x000b }, + { 0x0016, 0x000c }, + { 0x0005, 0x0006 }, + { 0x0004, 0x0007 }, + { 0x0005, 0x0007 }, + { 0x0006, 0x0004 }, + { 0x0008, 0x0004 }, + { 0x000b, 0x0005 }, + { 0x000d, 0x0007 }, + { 0x0010, 0x000a }, + { 0x0012, 0x0015 }, + { 0x0015, 0x0064 }, + { 0x0016, 0x000d }, + { 0x0016, 0x000e }, + { 0x0016, 0x000f }, + { 0x0016, 0x0010 }, + { 0x0016, 0x0011 }, + { 0x0016, 0x0012 }, + { 0x0016, 0x0013 }, + { 0x0006, 0x0005 }, + { 0x0006, 0x0006 }, + { 0x0006, 0x0007 }, + { 0x0008, 0x0005 }, + { 0x000a, 0x0005 }, + { 0x000c, 0x0005 }, + { 0x000e, 0x0007 }, + { 0x0010, 0x000b }, + { 0x0012, 0x0016 }, + { 0x0014, 0x0037 }, + { 0x0015, 0x0065 }, + { 0x0016, 0x0014 }, + { 0x0016, 0x0015 }, + { 0x0016, 0x0016 }, + { 0x0016, 0x0017 }, + { 0x0016, 0x0018 }, + { 0x0016, 0x0019 }, + { 0x0008, 0x0006 }, + { 0x0007, 0x0005 }, + { 0x0008, 0x0007 }, + { 0x000a, 0x0006 }, + { 0x000c, 0x0006 }, + { 0x000e, 0x0008 }, + { 0x0010, 0x000c }, + { 0x0011, 0x000d }, + { 0x0013, 0x0021 }, + { 0x0015, 0x0066 }, + { 0x0016, 0x001a }, + { 0x0016, 0x001b }, + { 0x0016, 0x001c }, + { 0x0016, 0x001d }, + { 0x0016, 0x001e }, + { 0x0016, 0x001f }, + { 0x0016, 0x0020 }, + { 0x000b, 0x0006 }, + { 0x000a, 0x0007 }, + { 0x000b, 0x0007 }, + { 0x000c, 0x0007 }, + { 0x000e, 0x0009 }, + { 0x000f, 0x0009 }, + { 0x0011, 0x000e }, + { 0x0013, 0x0022 }, + { 0x0015, 0x0067 }, + { 0x0015, 0x0068 }, + { 0x0016, 0x0021 }, + { 0x0016, 0x0022 }, + { 0x0016, 0x0023 }, + { 0x0016, 0x0024 }, + { 0x0016, 0x0025 }, + { 0x0016, 0x0026 }, + { 0x0016, 0x0027 }, + { 0x000e, 0x000a }, + { 0x000d, 0x0008 }, + { 0x000d, 0x0009 }, + { 0x000e, 0x000b }, + { 0x000f, 0x000a }, + { 0x0011, 0x000f }, + { 0x0013, 0x0023 }, + { 0x0014, 0x0038 }, + { 0x0016, 0x0028 }, + { 0x0016, 0x0029 }, + { 0x0016, 0x002a }, + { 0x0016, 0x002b }, + { 0x0016, 0x002c }, + { 0x0016, 0x002d }, + { 0x0016, 0x002e }, + { 0x0016, 0x002f }, + { 0x0016, 0x0030 }, + { 0x0010, 0x000d }, + { 0x000f, 0x000b }, + { 0x0010, 0x000e }, + { 0x0010, 0x000f }, + { 0x0012, 0x0017 }, + { 0x0013, 0x0024 }, + { 0x0014, 0x0039 }, + { 0x0016, 0x0031 }, + { 0x0016, 0x0032 }, + { 0x0016, 0x0033 }, + { 0x0016, 0x0034 }, + { 0x0016, 0x0035 }, + { 0x0016, 0x0036 }, + { 0x0016, 0x0037 }, + { 0x0016, 0x0038 }, + { 0x0016, 0x0039 }, + { 0x0016, 0x003a }, + { 0x0013, 0x0025 }, + { 0x0011, 0x0010 }, + { 0x0011, 0x0011 }, + { 0x0013, 0x0026 }, + { 0x0013, 0x0027 }, + { 0x0014, 0x003a }, + { 0x0014, 0x003b }, + { 0x0016, 0x003b }, + { 0x0016, 0x003c }, + { 0x0016, 0x003d }, + { 0x0016, 0x003e }, + { 0x0016, 0x003f }, + { 0x0016, 0x0040 }, + { 0x0016, 0x0041 }, + { 0x0016, 0x0042 }, + { 0x0016, 0x0043 }, + { 0x0016, 0x0044 }, + { 0x0015, 0x0069 }, + { 0x0014, 0x003c }, + { 0x0014, 0x003d }, + { 0x0015, 0x006a }, + { 0x0015, 0x006b }, + { 0x0015, 0x006c }, + { 0x0016, 0x0045 }, + { 0x0016, 0x0046 }, + { 0x0016, 0x0047 }, + { 0x0016, 0x0048 }, + { 0x0016, 0x0049 }, + { 0x0016, 0x004a }, + { 0x0016, 0x004b }, + { 0x0016, 0x004c }, + { 0x0016, 0x004d }, + { 0x0016, 0x004e }, + { 0x0016, 0x004f }, + { 0x0016, 0x0050 }, + { 0x0016, 0x0051 }, + { 0x0015, 0x006d }, + { 0x0016, 0x0052 }, + { 0x0016, 0x0053 }, + { 0x0016, 0x0054 }, + { 0x0016, 0x0055 }, + { 0x0016, 0x0056 }, + { 0x0016, 0x0057 }, + { 0x0016, 0x0058 }, + { 0x0016, 0x0059 }, + { 0x0016, 0x005a }, + { 0x0016, 0x005b }, + { 0x0016, 0x005c }, + { 0x0016, 0x005d }, + { 0x0016, 0x005e }, + { 0x0016, 0x005f }, + { 0x0016, 0x0060 }, + { 0x0016, 0x0061 }, + { 0x0016, 0x0062 }, + { 0x0016, 0x0063 }, + { 0x0016, 0x0064 }, + { 0x0016, 0x0065 }, + { 0x0016, 0x0066 }, + { 0x0016, 0x0067 }, + { 0x0016, 0x0068 }, + { 0x0016, 0x0069 }, + { 0x0016, 0x006a }, + { 0x0016, 0x006b }, + { 0x0016, 0x006c }, + { 0x0016, 0x006d }, + { 0x0016, 0x006e }, + { 0x0016, 0x006f }, + { 0x0016, 0x0070 }, + { 0x0016, 0x0071 }, + { 0x0016, 0x0072 }, + { 0x0016, 0x0073 }, + { 0x0016, 0x0074 }, + { 0x0016, 0x0075 }, + { 0x0016, 0x0076 }, + { 0x0016, 0x0077 }, + { 0x0016, 0x0078 }, + { 0x0016, 0x0079 }, + { 0x0016, 0x007a }, + { 0x0016, 0x007b }, + { 0x0016, 0x007c }, + { 0x0016, 0x007d }, + { 0x0016, 0x007e }, + { 0x0016, 0x007f }, + { 0x0016, 0x0080 }, + { 0x0016, 0x0081 }, + { 0x0016, 0x0082 }, + { 0x0016, 0x0083 }, + { 0x0016, 0x0084 }, + { 0x0016, 0x0085 }, + { 0x0016, 0x0086 }, + { 0x0016, 0x0087 }, + { 0x0016, 0x0088 }, + { 0x0016, 0x0089 }, + { 0x0016, 0x008a }, + { 0x0016, 0x008b }, + { 0x0016, 0x008c }, + { 0x0016, 0x008d }, + { 0x0016, 0x008e }, + { 0x0016, 0x008f }, + { 0x0016, 0x0090 }, + { 0x0016, 0x0091 }, + { 0x0016, 0x0092 }, + { 0x0016, 0x0093 }, + { 0x0016, 0x0094 }, + { 0x0016, 0x0095 }, + { 0x0016, 0x0096 }, + { 0x0016, 0x0097 }, + { 0x0016, 0x0098 }, + { 0x0016, 0x0099 }, + { 0x0016, 0x009a }, + { 0x0016, 0x009b }, + { 0x0016, 0x009c }, + { 0x0016, 0x009d }, + { 0x0016, 0x009e }, + { 0x0016, 0x009f }, + { 0x0016, 0x00a0 }, + { 0x0016, 0x00a1 }, + { 0x0016, 0x00a2 }, + { 0x0016, 0x00a3 }, + { 0x0016, 0x00a4 }, + { 0x0016, 0x00a5 }, + { 0x0016, 0x00a6 }, + { 0x0016, 0x00a7 }, + { 0x0016, 0x00a8 }, + { 0x0016, 0x00a9 }, + { 0x0016, 0x00aa }, + { 0x0016, 0x00ab }, + { 0x0016, 0x00ac }, + { 0x0016, 0x00ad }, + { 0x0016, 0x00ae }, + { 0x0016, 0x00af }, + { 0x0016, 0x00b0 }, + { 0x0016, 0x00b1 }, + { 0x0016, 0x00b2 }, + { 0x0016, 0x00b3 }, + { 0x0016, 0x00b4 }, + { 0x0016, 0x00b5 }, + { 0x0016, 0x00b6 }, + { 0x0016, 0x00b7 }, + { 0x0016, 0x00b8 }, + { 0x0016, 0x00b9 }, + { 0x0016, 0x00ba }, + { 0x0016, 0x00bb }, + { 0x0016, 0x00bc }, + { 0x0016, 0x00bd }, + { 0x0016, 0x00be }, + { 0x0016, 0x00bf }, + { 0x0016, 0x00c0 }, + { 0x0016, 0x00c1 }, + { 0x0016, 0x00c2 }, + { 0x0016, 0x00c3 }, + { 0x0016, 0x00c4 }, + { 0x0016, 0x00c5 }, + + }; + +const uint16_t c_aauiLCLDHuffEnc13[324][2] = + { + { 0x0004, 0x0006 }, + { 0x0004, 0x0007 }, + { 0x0005, 0x0005 }, + { 0x0005, 0x0006 }, + { 0x0006, 0x0004 }, + { 0x0008, 0x0005 }, + { 0x000a, 0x0005 }, + { 0x000c, 0x0007 }, + { 0x000e, 0x000b }, + { 0x0010, 0x0011 }, + { 0x0012, 0x002d }, + { 0x0015, 0x0000 }, + { 0x0014, 0x0035 }, + { 0x0015, 0x0001 }, + { 0x0015, 0x0002 }, + { 0x0015, 0x0003 }, + { 0x0015, 0x0004 }, + { 0x0015, 0x0005 }, + { 0x0004, 0x0008 }, + { 0x0003, 0x0007 }, + { 0x0004, 0x0009 }, + { 0x0004, 0x000a }, + { 0x0006, 0x0005 }, + { 0x0008, 0x0006 }, + { 0x0009, 0x0006 }, + { 0x000c, 0x0008 }, + { 0x000d, 0x0009 }, + { 0x0010, 0x0012 }, + { 0x0011, 0x001a }, + { 0x0015, 0x0006 }, + { 0x0015, 0x0007 }, + { 0x0015, 0x0008 }, + { 0x0015, 0x0009 }, + { 0x0015, 0x000a }, + { 0x0015, 0x000b }, + { 0x0015, 0x000c }, + { 0x0005, 0x0007 }, + { 0x0004, 0x000b }, + { 0x0004, 0x000c }, + { 0x0005, 0x0008 }, + { 0x0006, 0x0006 }, + { 0x0008, 0x0007 }, + { 0x000a, 0x0006 }, + { 0x000c, 0x0009 }, + { 0x000e, 0x000c }, + { 0x0010, 0x0013 }, + { 0x0012, 0x002e }, + { 0x0015, 0x000d }, + { 0x0015, 0x000e }, + { 0x0015, 0x000f }, + { 0x0015, 0x0010 }, + { 0x0015, 0x0011 }, + { 0x0015, 0x0012 }, + { 0x0015, 0x0013 }, + { 0x0005, 0x0009 }, + { 0x0004, 0x000d }, + { 0x0005, 0x000a }, + { 0x0006, 0x0007 }, + { 0x0007, 0x0005 }, + { 0x0009, 0x0007 }, + { 0x000b, 0x0008 }, + { 0x000d, 0x000a }, + { 0x000f, 0x000e }, + { 0x0010, 0x0014 }, + { 0x0011, 0x001b }, + { 0x0014, 0x0036 }, + { 0x0015, 0x0014 }, + { 0x0015, 0x0015 }, + { 0x0015, 0x0016 }, + { 0x0015, 0x0017 }, + { 0x0015, 0x0018 }, + { 0x0015, 0x0019 }, + { 0x0006, 0x0008 }, + { 0x0005, 0x000b }, + { 0x0006, 0x0009 }, + { 0x0007, 0x0006 }, + { 0x0009, 0x0008 }, + { 0x000a, 0x0007 }, + { 0x000c, 0x000a }, + { 0x000e, 0x000d }, + { 0x0010, 0x0015 }, + { 0x0011, 0x001c }, + { 0x0013, 0x0053 }, + { 0x0015, 0x001a }, + { 0x0015, 0x001b }, + { 0x0015, 0x001c }, + { 0x0015, 0x001d }, + { 0x0015, 0x001e }, + { 0x0015, 0x001f }, + { 0x0015, 0x0020 }, + { 0x0008, 0x0008 }, + { 0x0007, 0x0007 }, + { 0x0008, 0x0009 }, + { 0x0009, 0x0009 }, + { 0x000a, 0x0008 }, + { 0x000c, 0x000b }, + { 0x000d, 0x000b }, + { 0x000f, 0x000f }, + { 0x0010, 0x0016 }, + { 0x0011, 0x001d }, + { 0x0014, 0x0037 }, + { 0x0015, 0x0021 }, + { 0x0015, 0x0022 }, + { 0x0015, 0x0023 }, + { 0x0015, 0x0024 }, + { 0x0015, 0x0025 }, + { 0x0015, 0x0026 }, + { 0x0015, 0x0027 }, + { 0x000a, 0x0009 }, + { 0x000a, 0x000a }, + { 0x000a, 0x000b }, + { 0x000b, 0x0009 }, + { 0x000c, 0x000c }, + { 0x000d, 0x000c }, + { 0x000f, 0x0010 }, + { 0x0010, 0x0017 }, + { 0x0012, 0x002f }, + { 0x0015, 0x0028 }, + { 0x0015, 0x0029 }, + { 0x0015, 0x002a }, + { 0x0015, 0x002b }, + { 0x0015, 0x002c }, + { 0x0015, 0x002d }, + { 0x0015, 0x002e }, + { 0x0015, 0x002f }, + { 0x0015, 0x0030 }, + { 0x000c, 0x000d }, + { 0x000c, 0x000e }, + { 0x000c, 0x000f }, + { 0x000d, 0x000d }, + { 0x000e, 0x000e }, + { 0x000f, 0x0011 }, + { 0x0010, 0x0018 }, + { 0x0011, 0x001e }, + { 0x0014, 0x0038 }, + { 0x0015, 0x0031 }, + { 0x0015, 0x0032 }, + { 0x0015, 0x0033 }, + { 0x0015, 0x0034 }, + { 0x0015, 0x0035 }, + { 0x0015, 0x0036 }, + { 0x0015, 0x0037 }, + { 0x0015, 0x0038 }, + { 0x0015, 0x0039 }, + { 0x000f, 0x0012 }, + { 0x000e, 0x000f }, + { 0x000e, 0x0010 }, + { 0x000e, 0x0011 }, + { 0x000f, 0x0013 }, + { 0x0010, 0x0019 }, + { 0x0011, 0x001f }, + { 0x0013, 0x0054 }, + { 0x0015, 0x003a }, + { 0x0014, 0x0039 }, + { 0x0015, 0x003b }, + { 0x0015, 0x003c }, + { 0x0015, 0x003d }, + { 0x0015, 0x003e }, + { 0x0015, 0x003f }, + { 0x0015, 0x0040 }, + { 0x0015, 0x0041 }, + { 0x0015, 0x0042 }, + { 0x0010, 0x001a }, + { 0x000f, 0x0014 }, + { 0x000f, 0x0015 }, + { 0x0010, 0x001b }, + { 0x0011, 0x0020 }, + { 0x0012, 0x0030 }, + { 0x0013, 0x0055 }, + { 0x0015, 0x0043 }, + { 0x0015, 0x0044 }, + { 0x0014, 0x003a }, + { 0x0015, 0x0045 }, + { 0x0015, 0x0046 }, + { 0x0015, 0x0047 }, + { 0x0015, 0x0048 }, + { 0x0015, 0x0049 }, + { 0x0015, 0x004a }, + { 0x0015, 0x004b }, + { 0x0015, 0x004c }, + { 0x0012, 0x0031 }, + { 0x0011, 0x0021 }, + { 0x0013, 0x0056 }, + { 0x0013, 0x0057 }, + { 0x0012, 0x0032 }, + { 0x0015, 0x004d }, + { 0x0015, 0x004e }, + { 0x0015, 0x004f }, + { 0x0015, 0x0050 }, + { 0x0015, 0x0051 }, + { 0x0015, 0x0052 }, + { 0x0015, 0x0053 }, + { 0x0015, 0x0054 }, + { 0x0015, 0x0055 }, + { 0x0015, 0x0056 }, + { 0x0015, 0x0057 }, + { 0x0015, 0x0058 }, + { 0x0015, 0x0059 }, + { 0x0015, 0x005a }, + { 0x0014, 0x003b }, + { 0x0012, 0x0033 }, + { 0x0013, 0x0058 }, + { 0x0013, 0x0059 }, + { 0x0015, 0x005b }, + { 0x0015, 0x005c }, + { 0x0015, 0x005d }, + { 0x0015, 0x005e }, + { 0x0015, 0x005f }, + { 0x0015, 0x0060 }, + { 0x0015, 0x0061 }, + { 0x0015, 0x0062 }, + { 0x0015, 0x0063 }, + { 0x0015, 0x0064 }, + { 0x0015, 0x0065 }, + { 0x0015, 0x0066 }, + { 0x0015, 0x0067 }, + { 0x0015, 0x0068 }, + { 0x0015, 0x0069 }, + { 0x0014, 0x003c }, + { 0x0014, 0x003d }, + { 0x0014, 0x003e }, + { 0x0014, 0x003f }, + { 0x0014, 0x0040 }, + { 0x0014, 0x0041 }, + { 0x0014, 0x0042 }, + { 0x0014, 0x0043 }, + { 0x0014, 0x0044 }, + { 0x0014, 0x0045 }, + { 0x0014, 0x0046 }, + { 0x0014, 0x0047 }, + { 0x0014, 0x0048 }, + { 0x0014, 0x0049 }, + { 0x0014, 0x004a }, + { 0x0014, 0x004b }, + { 0x0014, 0x004c }, + { 0x0014, 0x004d }, + { 0x0014, 0x004e }, + { 0x0014, 0x004f }, + { 0x0014, 0x0050 }, + { 0x0014, 0x0051 }, + { 0x0014, 0x0052 }, + { 0x0014, 0x0053 }, + { 0x0014, 0x0054 }, + { 0x0014, 0x0055 }, + { 0x0014, 0x0056 }, + { 0x0014, 0x0057 }, + { 0x0014, 0x0058 }, + { 0x0014, 0x0059 }, + { 0x0014, 0x005a }, + { 0x0014, 0x005b }, + { 0x0014, 0x005c }, + { 0x0014, 0x005d }, + { 0x0014, 0x005e }, + { 0x0014, 0x005f }, + { 0x0014, 0x0060 }, + { 0x0014, 0x0061 }, + { 0x0014, 0x0062 }, + { 0x0014, 0x0063 }, + { 0x0014, 0x0064 }, + { 0x0014, 0x0065 }, + { 0x0014, 0x0066 }, + { 0x0014, 0x0067 }, + { 0x0014, 0x0068 }, + { 0x0014, 0x0069 }, + { 0x0014, 0x006a }, + { 0x0014, 0x006b }, + { 0x0014, 0x006c }, + { 0x0014, 0x006d }, + { 0x0014, 0x006e }, + { 0x0014, 0x006f }, + { 0x0014, 0x0070 }, + { 0x0014, 0x0071 }, + { 0x0014, 0x0072 }, + { 0x0014, 0x0073 }, + { 0x0014, 0x0074 }, + { 0x0014, 0x0075 }, + { 0x0014, 0x0076 }, + { 0x0014, 0x0077 }, + { 0x0014, 0x0078 }, + { 0x0014, 0x0079 }, + { 0x0014, 0x007a }, + { 0x0014, 0x007b }, + { 0x0014, 0x007c }, + { 0x0014, 0x007d }, + { 0x0014, 0x007e }, + { 0x0014, 0x007f }, + { 0x0014, 0x0080 }, + { 0x0014, 0x0081 }, + { 0x0014, 0x0082 }, + { 0x0014, 0x0083 }, + { 0x0014, 0x0084 }, + { 0x0014, 0x0085 }, + { 0x0014, 0x0086 }, + { 0x0014, 0x0087 }, + { 0x0014, 0x0088 }, + { 0x0014, 0x0089 }, + { 0x0014, 0x008a }, + { 0x0014, 0x008b }, + { 0x0014, 0x008c }, + { 0x0014, 0x008d }, + { 0x0014, 0x008e }, + { 0x0014, 0x008f }, + { 0x0014, 0x0090 }, + { 0x0014, 0x0091 }, + { 0x0014, 0x0092 }, + { 0x0014, 0x0093 }, + { 0x0014, 0x0094 }, + { 0x0014, 0x0095 }, + { 0x0014, 0x0096 }, + { 0x0014, 0x0097 }, + { 0x0014, 0x0098 }, + { 0x0014, 0x0099 }, + { 0x0014, 0x009a }, + { 0x0014, 0x009b }, + { 0x0014, 0x009c }, + { 0x0014, 0x009d }, + { 0x0014, 0x009e }, + { 0x0014, 0x009f }, + { 0x0014, 0x00a0 }, + { 0x0014, 0x00a1 }, + { 0x0014, 0x00a2 }, + { 0x0014, 0x00a3 }, + { 0x0014, 0x00a4 }, + { 0x0014, 0x00a5 }, + + }; + +const uint16_t c_aauiLCLDHuffEnc14[400][2] = + { + { 0x0005, 0x0007 }, + { 0x0004, 0x0009 }, + { 0x0005, 0x0008 }, + { 0x0005, 0x0009 }, + { 0x0006, 0x0006 }, + { 0x0007, 0x0006 }, + { 0x0009, 0x0007 }, + { 0x000b, 0x0008 }, + { 0x000d, 0x000c }, + { 0x000f, 0x0013 }, + { 0x0010, 0x001b }, + { 0x0013, 0x0082 }, + { 0x0013, 0x0083 }, + { 0x0014, 0x0000 }, + { 0x0014, 0x0001 }, + { 0x0014, 0x0002 }, + { 0x0014, 0x0003 }, + { 0x0014, 0x0004 }, + { 0x0014, 0x0005 }, + { 0x0014, 0x0006 }, + { 0x0004, 0x000a }, + { 0x0004, 0x000b }, + { 0x0004, 0x000c }, + { 0x0005, 0x000a }, + { 0x0005, 0x000b }, + { 0x0006, 0x0007 }, + { 0x0008, 0x0006 }, + { 0x000a, 0x0007 }, + { 0x000c, 0x000a }, + { 0x000e, 0x000e }, + { 0x000f, 0x0014 }, + { 0x0011, 0x002a }, + { 0x0012, 0x004a }, + { 0x0013, 0x0084 }, + { 0x0014, 0x0007 }, + { 0x0014, 0x0008 }, + { 0x0014, 0x0009 }, + { 0x0014, 0x000a }, + { 0x0014, 0x000b }, + { 0x0014, 0x000c }, + { 0x0005, 0x000c }, + { 0x0004, 0x000d }, + { 0x0004, 0x000e }, + { 0x0005, 0x000d }, + { 0x0006, 0x0008 }, + { 0x0007, 0x0007 }, + { 0x0008, 0x0007 }, + { 0x000a, 0x0008 }, + { 0x000c, 0x000b }, + { 0x000e, 0x000f }, + { 0x000f, 0x0015 }, + { 0x0012, 0x004b }, + { 0x0013, 0x0085 }, + { 0x0014, 0x000d }, + { 0x0014, 0x000e }, + { 0x0014, 0x000f }, + { 0x0014, 0x0010 }, + { 0x0014, 0x0011 }, + { 0x0014, 0x0012 }, + { 0x0014, 0x0013 }, + { 0x0005, 0x000e }, + { 0x0004, 0x000f }, + { 0x0005, 0x000f }, + { 0x0005, 0x0010 }, + { 0x0006, 0x0009 }, + { 0x0008, 0x0008 }, + { 0x0009, 0x0008 }, + { 0x000b, 0x0009 }, + { 0x000d, 0x000d }, + { 0x000e, 0x0010 }, + { 0x0010, 0x001c }, + { 0x0011, 0x002b }, + { 0x0014, 0x0014 }, + { 0x0014, 0x0015 }, + { 0x0014, 0x0016 }, + { 0x0014, 0x0017 }, + { 0x0014, 0x0018 }, + { 0x0014, 0x0019 }, + { 0x0014, 0x001a }, + { 0x0014, 0x001b }, + { 0x0006, 0x000a }, + { 0x0005, 0x0011 }, + { 0x0006, 0x000b }, + { 0x0006, 0x000c }, + { 0x0007, 0x0008 }, + { 0x0008, 0x0009 }, + { 0x000a, 0x0009 }, + { 0x000c, 0x000c }, + { 0x000e, 0x0011 }, + { 0x000f, 0x0016 }, + { 0x0010, 0x001d }, + { 0x0012, 0x004c }, + { 0x0014, 0x001c }, + { 0x0014, 0x001d }, + { 0x0014, 0x001e }, + { 0x0014, 0x001f }, + { 0x0014, 0x0020 }, + { 0x0014, 0x0021 }, + { 0x0014, 0x0022 }, + { 0x0014, 0x0023 }, + { 0x0007, 0x0009 }, + { 0x0006, 0x000d }, + { 0x0007, 0x000a }, + { 0x0007, 0x000b }, + { 0x0009, 0x0009 }, + { 0x000a, 0x000a }, + { 0x000b, 0x000a }, + { 0x000d, 0x000e }, + { 0x000f, 0x0017 }, + { 0x0011, 0x002c }, + { 0x0010, 0x001e }, + { 0x0014, 0x0024 }, + { 0x0014, 0x0025 }, + { 0x0014, 0x0026 }, + { 0x0014, 0x0027 }, + { 0x0014, 0x0028 }, + { 0x0014, 0x0029 }, + { 0x0014, 0x002a }, + { 0x0014, 0x002b }, + { 0x0014, 0x002c }, + { 0x0009, 0x000a }, + { 0x0008, 0x000a }, + { 0x0008, 0x000b }, + { 0x0009, 0x000b }, + { 0x000a, 0x000b }, + { 0x000b, 0x000b }, + { 0x000d, 0x000f }, + { 0x000e, 0x0012 }, + { 0x000f, 0x0018 }, + { 0x0011, 0x002d }, + { 0x0011, 0x002e }, + { 0x0013, 0x0086 }, + { 0x0014, 0x002d }, + { 0x0014, 0x002e }, + { 0x0014, 0x002f }, + { 0x0014, 0x0030 }, + { 0x0014, 0x0031 }, + { 0x0014, 0x0032 }, + { 0x0014, 0x0033 }, + { 0x0014, 0x0034 }, + { 0x000b, 0x000c }, + { 0x000a, 0x000c }, + { 0x000a, 0x000d }, + { 0x000b, 0x000d }, + { 0x000c, 0x000d }, + { 0x000d, 0x0010 }, + { 0x000e, 0x0013 }, + { 0x000f, 0x0019 }, + { 0x0010, 0x001f }, + { 0x0013, 0x0087 }, + { 0x0014, 0x0035 }, + { 0x0014, 0x0036 }, + { 0x0013, 0x0088 }, + { 0x0014, 0x0037 }, + { 0x0014, 0x0038 }, + { 0x0014, 0x0039 }, + { 0x0014, 0x003a }, + { 0x0014, 0x003b }, + { 0x0014, 0x003c }, + { 0x0014, 0x003d }, + { 0x000d, 0x0011 }, + { 0x000c, 0x000e }, + { 0x000c, 0x000f }, + { 0x000d, 0x0012 }, + { 0x000d, 0x0013 }, + { 0x000e, 0x0014 }, + { 0x0010, 0x0020 }, + { 0x0010, 0x0021 }, + { 0x0012, 0x004d }, + { 0x0011, 0x002f }, + { 0x0014, 0x003e }, + { 0x0014, 0x003f }, + { 0x0014, 0x0040 }, + { 0x0014, 0x0041 }, + { 0x0014, 0x0042 }, + { 0x0014, 0x0043 }, + { 0x0014, 0x0044 }, + { 0x0014, 0x0045 }, + { 0x0014, 0x0046 }, + { 0x0014, 0x0047 }, + { 0x000f, 0x001a }, + { 0x000e, 0x0015 }, + { 0x000e, 0x0016 }, + { 0x000e, 0x0017 }, + { 0x000f, 0x001b }, + { 0x0011, 0x0030 }, + { 0x0011, 0x0031 }, + { 0x0013, 0x0089 }, + { 0x0013, 0x008a }, + { 0x0013, 0x008b }, + { 0x0014, 0x0048 }, + { 0x0014, 0x0049 }, + { 0x0014, 0x004a }, + { 0x0014, 0x004b }, + { 0x0014, 0x004c }, + { 0x0014, 0x004d }, + { 0x0014, 0x004e }, + { 0x0014, 0x004f }, + { 0x0014, 0x0050 }, + { 0x0014, 0x0051 }, + { 0x0010, 0x0022 }, + { 0x0010, 0x0023 }, + { 0x0010, 0x0024 }, + { 0x0010, 0x0025 }, + { 0x0011, 0x0032 }, + { 0x0011, 0x0033 }, + { 0x0012, 0x004e }, + { 0x0012, 0x004f }, + { 0x0014, 0x0052 }, + { 0x0013, 0x008c }, + { 0x0013, 0x008d }, + { 0x0014, 0x0053 }, + { 0x0014, 0x0054 }, + { 0x0014, 0x0055 }, + { 0x0014, 0x0056 }, + { 0x0014, 0x0057 }, + { 0x0014, 0x0058 }, + { 0x0014, 0x0059 }, + { 0x0014, 0x005a }, + { 0x0014, 0x005b }, + { 0x0011, 0x0034 }, + { 0x0011, 0x0035 }, + { 0x0012, 0x0050 }, + { 0x0012, 0x0051 }, + { 0x0013, 0x008e }, + { 0x0014, 0x005c }, + { 0x0014, 0x005d }, + { 0x0014, 0x005e }, + { 0x0014, 0x005f }, + { 0x0014, 0x0060 }, + { 0x0014, 0x0061 }, + { 0x0014, 0x0062 }, + { 0x0014, 0x0063 }, + { 0x0014, 0x0064 }, + { 0x0014, 0x0065 }, + { 0x0014, 0x0066 }, + { 0x0014, 0x0067 }, + { 0x0014, 0x0068 }, + { 0x0014, 0x0069 }, + { 0x0014, 0x006a }, + { 0x0012, 0x0052 }, + { 0x0013, 0x008f }, + { 0x0013, 0x0090 }, + { 0x0014, 0x006b }, + { 0x0013, 0x0091 }, + { 0x0014, 0x006c }, + { 0x0014, 0x006d }, + { 0x0014, 0x006e }, + { 0x0014, 0x006f }, + { 0x0014, 0x0070 }, + { 0x0014, 0x0071 }, + { 0x0014, 0x0072 }, + { 0x0014, 0x0073 }, + { 0x0014, 0x0074 }, + { 0x0014, 0x0075 }, + { 0x0014, 0x0076 }, + { 0x0014, 0x0077 }, + { 0x0014, 0x0078 }, + { 0x0014, 0x0079 }, + { 0x0014, 0x007a }, + { 0x0014, 0x007b }, + { 0x0014, 0x007c }, + { 0x0013, 0x0092 }, + { 0x0012, 0x0053 }, + { 0x0014, 0x007d }, + { 0x0014, 0x007e }, + { 0x0014, 0x007f }, + { 0x0014, 0x0080 }, + { 0x0014, 0x0081 }, + { 0x0014, 0x0082 }, + { 0x0014, 0x0083 }, + { 0x0014, 0x0084 }, + { 0x0014, 0x0085 }, + { 0x0014, 0x0086 }, + { 0x0014, 0x0087 }, + { 0x0014, 0x0088 }, + { 0x0014, 0x0089 }, + { 0x0014, 0x008a }, + { 0x0014, 0x008b }, + { 0x0014, 0x008c }, + { 0x0014, 0x008d }, + { 0x0014, 0x008e }, + { 0x0013, 0x0093 }, + { 0x0014, 0x008f }, + { 0x0014, 0x0090 }, + { 0x0014, 0x0091 }, + { 0x0014, 0x0092 }, + { 0x0014, 0x0093 }, + { 0x0014, 0x0094 }, + { 0x0014, 0x0095 }, + { 0x0014, 0x0096 }, + { 0x0014, 0x0097 }, + { 0x0014, 0x0098 }, + { 0x0014, 0x0099 }, + { 0x0014, 0x009a }, + { 0x0014, 0x009b }, + { 0x0014, 0x009c }, + { 0x0014, 0x009d }, + { 0x0014, 0x009e }, + { 0x0014, 0x009f }, + { 0x0014, 0x00a0 }, + { 0x0014, 0x00a1 }, + { 0x0014, 0x00a2 }, + { 0x0014, 0x00a3 }, + { 0x0014, 0x00a4 }, + { 0x0014, 0x00a5 }, + { 0x0014, 0x00a6 }, + { 0x0014, 0x00a7 }, + { 0x0014, 0x00a8 }, + { 0x0014, 0x00a9 }, + { 0x0014, 0x00aa }, + { 0x0014, 0x00ab }, + { 0x0014, 0x00ac }, + { 0x0014, 0x00ad }, + { 0x0014, 0x00ae }, + { 0x0014, 0x00af }, + { 0x0014, 0x00b0 }, + { 0x0014, 0x00b1 }, + { 0x0014, 0x00b2 }, + { 0x0014, 0x00b3 }, + { 0x0014, 0x00b4 }, + { 0x0014, 0x00b5 }, + { 0x0014, 0x00b6 }, + { 0x0014, 0x00b7 }, + { 0x0014, 0x00b8 }, + { 0x0014, 0x00b9 }, + { 0x0014, 0x00ba }, + { 0x0014, 0x00bb }, + { 0x0014, 0x00bc }, + { 0x0014, 0x00bd }, + { 0x0014, 0x00be }, + { 0x0014, 0x00bf }, + { 0x0014, 0x00c0 }, + { 0x0014, 0x00c1 }, + { 0x0014, 0x00c2 }, + { 0x0014, 0x00c3 }, + { 0x0014, 0x00c4 }, + { 0x0014, 0x00c5 }, + { 0x0014, 0x00c6 }, + { 0x0014, 0x00c7 }, + { 0x0014, 0x00c8 }, + { 0x0014, 0x00c9 }, + { 0x0014, 0x00ca }, + { 0x0014, 0x00cb }, + { 0x0014, 0x00cc }, + { 0x0014, 0x00cd }, + { 0x0014, 0x00ce }, + { 0x0014, 0x00cf }, + { 0x0014, 0x00d0 }, + { 0x0014, 0x00d1 }, + { 0x0014, 0x00d2 }, + { 0x0014, 0x00d3 }, + { 0x0014, 0x00d4 }, + { 0x0014, 0x00d5 }, + { 0x0014, 0x00d6 }, + { 0x0014, 0x00d7 }, + { 0x0014, 0x00d8 }, + { 0x0014, 0x00d9 }, + { 0x0014, 0x00da }, + { 0x0014, 0x00db }, + { 0x0014, 0x00dc }, + { 0x0014, 0x00dd }, + { 0x0014, 0x00de }, + { 0x0014, 0x00df }, + { 0x0014, 0x00e0 }, + { 0x0014, 0x00e1 }, + { 0x0014, 0x00e2 }, + { 0x0014, 0x00e3 }, + { 0x0014, 0x00e4 }, + { 0x0014, 0x00e5 }, + { 0x0014, 0x00e6 }, + { 0x0014, 0x00e7 }, + { 0x0014, 0x00e8 }, + { 0x0014, 0x00e9 }, + { 0x0014, 0x00ea }, + { 0x0014, 0x00eb }, + { 0x0014, 0x00ec }, + { 0x0014, 0x00ed }, + { 0x0014, 0x00ee }, + { 0x0014, 0x00ef }, + { 0x0014, 0x00f0 }, + { 0x0014, 0x00f1 }, + { 0x0014, 0x00f2 }, + { 0x0014, 0x00f3 }, + { 0x0014, 0x00f4 }, + { 0x0014, 0x00f5 }, + { 0x0014, 0x00f6 }, + { 0x0014, 0x00f7 }, + { 0x0014, 0x00f8 }, + { 0x0014, 0x00f9 }, + { 0x0014, 0x00fa }, + { 0x0014, 0x00fb }, + { 0x0014, 0x00fc }, + { 0x0014, 0x00fd }, + { 0x0014, 0x00fe }, + { 0x0014, 0x00ff }, + { 0x0014, 0x0100 }, + { 0x0014, 0x0101 }, + { 0x0014, 0x0102 }, + { 0x0014, 0x0103 }, + }; + +const uint16_t c_aauiLCLDHuffEnc15[576][2] = + { + { 0x0005, 0x000a }, + { 0x0005, 0x000b }, + { 0x0005, 0x000c }, + { 0x0006, 0x0009 }, + { 0x0006, 0x000a }, + { 0x0007, 0x0008 }, + { 0x0008, 0x0009 }, + { 0x0009, 0x0008 }, + { 0x000b, 0x000b }, + { 0x000d, 0x000e }, + { 0x000e, 0x0011 }, + { 0x000f, 0x001a }, + { 0x0012, 0x006e }, + { 0x0014, 0x0000 }, + { 0x0013, 0x00cc }, + { 0x0014, 0x0001 }, + { 0x0014, 0x0002 }, + { 0x0014, 0x0003 }, + { 0x0014, 0x0004 }, + { 0x0014, 0x0005 }, + { 0x0014, 0x0006 }, + { 0x0014, 0x0007 }, + { 0x0014, 0x0008 }, + { 0x0014, 0x0009 }, + { 0x0005, 0x000d }, + { 0x0004, 0x000c }, + { 0x0004, 0x000d }, + { 0x0005, 0x000e }, + { 0x0005, 0x000f }, + { 0x0006, 0x000b }, + { 0x0007, 0x0009 }, + { 0x0008, 0x000a }, + { 0x000a, 0x000a }, + { 0x000c, 0x000c }, + { 0x000d, 0x000f }, + { 0x000f, 0x001b }, + { 0x0011, 0x003d }, + { 0x0011, 0x003e }, + { 0x0013, 0x00cd }, + { 0x0014, 0x000a }, + { 0x0014, 0x000b }, + { 0x0014, 0x000c }, + { 0x0014, 0x000d }, + { 0x0014, 0x000e }, + { 0x0014, 0x000f }, + { 0x0014, 0x0010 }, + { 0x0014, 0x0011 }, + { 0x0014, 0x0012 }, + { 0x0005, 0x0010 }, + { 0x0004, 0x000e }, + { 0x0004, 0x000f }, + { 0x0005, 0x0011 }, + { 0x0005, 0x0012 }, + { 0x0006, 0x000c }, + { 0x0007, 0x000a }, + { 0x0009, 0x0009 }, + { 0x000a, 0x000b }, + { 0x000c, 0x000d }, + { 0x000e, 0x0012 }, + { 0x0010, 0x0027 }, + { 0x0011, 0x003f }, + { 0x0012, 0x006f }, + { 0x0014, 0x0013 }, + { 0x0014, 0x0014 }, + { 0x0014, 0x0015 }, + { 0x0014, 0x0016 }, + { 0x0014, 0x0017 }, + { 0x0014, 0x0018 }, + { 0x0014, 0x0019 }, + { 0x0014, 0x001a }, + { 0x0014, 0x001b }, + { 0x0014, 0x001c }, + { 0x0006, 0x000d }, + { 0x0005, 0x0013 }, + { 0x0005, 0x0014 }, + { 0x0005, 0x0015 }, + { 0x0006, 0x000e }, + { 0x0007, 0x000b }, + { 0x0008, 0x000b }, + { 0x0009, 0x000a }, + { 0x000b, 0x000c }, + { 0x000c, 0x000e }, + { 0x000e, 0x0013 }, + { 0x000f, 0x001c }, + { 0x0011, 0x0040 }, + { 0x0012, 0x0070 }, + { 0x0014, 0x001d }, + { 0x0014, 0x001e }, + { 0x0014, 0x001f }, + { 0x0014, 0x0020 }, + { 0x0014, 0x0021 }, + { 0x0014, 0x0022 }, + { 0x0014, 0x0023 }, + { 0x0014, 0x0024 }, + { 0x0014, 0x0025 }, + { 0x0014, 0x0026 }, + { 0x0006, 0x000f }, + { 0x0005, 0x0016 }, + { 0x0005, 0x0017 }, + { 0x0006, 0x0010 }, + { 0x0006, 0x0011 }, + { 0x0007, 0x000c }, + { 0x0009, 0x000b }, + { 0x000a, 0x000c }, + { 0x000b, 0x000d }, + { 0x000d, 0x0010 }, + { 0x000e, 0x0014 }, + { 0x0010, 0x0028 }, + { 0x0011, 0x0041 }, + { 0x0013, 0x00ce }, + { 0x0014, 0x0027 }, + { 0x0014, 0x0028 }, + { 0x0014, 0x0029 }, + { 0x0014, 0x002a }, + { 0x0014, 0x002b }, + { 0x0014, 0x002c }, + { 0x0014, 0x002d }, + { 0x0014, 0x002e }, + { 0x0014, 0x002f }, + { 0x0014, 0x0030 }, + { 0x0007, 0x000d }, + { 0x0006, 0x0012 }, + { 0x0006, 0x0013 }, + { 0x0007, 0x000e }, + { 0x0007, 0x000f }, + { 0x0008, 0x000c }, + { 0x0009, 0x000c }, + { 0x000b, 0x000e }, + { 0x000c, 0x000f }, + { 0x000e, 0x0015 }, + { 0x0010, 0x0029 }, + { 0x0011, 0x0042 }, + { 0x0014, 0x0031 }, + { 0x0014, 0x0032 }, + { 0x0014, 0x0033 }, + { 0x0014, 0x0034 }, + { 0x0014, 0x0035 }, + { 0x0014, 0x0036 }, + { 0x0014, 0x0037 }, + { 0x0014, 0x0038 }, + { 0x0014, 0x0039 }, + { 0x0014, 0x003a }, + { 0x0014, 0x003b }, + { 0x0014, 0x003c }, + { 0x0008, 0x000d }, + { 0x0007, 0x0010 }, + { 0x0007, 0x0011 }, + { 0x0008, 0x000e }, + { 0x0009, 0x000d }, + { 0x0009, 0x000e }, + { 0x000b, 0x000f }, + { 0x000c, 0x0010 }, + { 0x000d, 0x0011 }, + { 0x000f, 0x001d }, + { 0x0010, 0x002a }, + { 0x0011, 0x0043 }, + { 0x0014, 0x003d }, + { 0x0013, 0x00cf }, + { 0x0014, 0x003e }, + { 0x0014, 0x003f }, + { 0x0014, 0x0040 }, + { 0x0014, 0x0041 }, + { 0x0014, 0x0042 }, + { 0x0014, 0x0043 }, + { 0x0014, 0x0044 }, + { 0x0014, 0x0045 }, + { 0x0014, 0x0046 }, + { 0x0014, 0x0047 }, + { 0x0009, 0x000f }, + { 0x0008, 0x000f }, + { 0x0009, 0x0010 }, + { 0x0009, 0x0011 }, + { 0x000a, 0x000d }, + { 0x000b, 0x0010 }, + { 0x000c, 0x0011 }, + { 0x000d, 0x0012 }, + { 0x000e, 0x0016 }, + { 0x0010, 0x002b }, + { 0x0011, 0x0044 }, + { 0x0012, 0x0071 }, + { 0x0014, 0x0048 }, + { 0x0014, 0x0049 }, + { 0x0014, 0x004a }, + { 0x0014, 0x004b }, + { 0x0014, 0x004c }, + { 0x0014, 0x004d }, + { 0x0014, 0x004e }, + { 0x0014, 0x004f }, + { 0x0014, 0x0050 }, + { 0x0014, 0x0051 }, + { 0x0014, 0x0052 }, + { 0x0014, 0x0053 }, + { 0x000b, 0x0011 }, + { 0x000a, 0x000e }, + { 0x000a, 0x000f }, + { 0x000b, 0x0012 }, + { 0x000b, 0x0013 }, + { 0x000c, 0x0012 }, + { 0x000d, 0x0013 }, + { 0x000e, 0x0017 }, + { 0x0010, 0x002c }, + { 0x0012, 0x0072 }, + { 0x0011, 0x0045 }, + { 0x0013, 0x00d0 }, + { 0x0013, 0x00d1 }, + { 0x0014, 0x0054 }, + { 0x0014, 0x0055 }, + { 0x0014, 0x0056 }, + { 0x0014, 0x0057 }, + { 0x0014, 0x0058 }, + { 0x0014, 0x0059 }, + { 0x0014, 0x005a }, + { 0x0014, 0x005b }, + { 0x0014, 0x005c }, + { 0x0014, 0x005d }, + { 0x0014, 0x005e }, + { 0x000c, 0x0013 }, + { 0x000c, 0x0014 }, + { 0x000c, 0x0015 }, + { 0x000d, 0x0014 }, + { 0x000d, 0x0015 }, + { 0x000e, 0x0018 }, + { 0x000f, 0x001e }, + { 0x0010, 0x002d }, + { 0x0011, 0x0046 }, + { 0x0011, 0x0047 }, + { 0x0011, 0x0048 }, + { 0x0014, 0x005f }, + { 0x0014, 0x0060 }, + { 0x0014, 0x0061 }, + { 0x0014, 0x0062 }, + { 0x0014, 0x0063 }, + { 0x0014, 0x0064 }, + { 0x0014, 0x0065 }, + { 0x0014, 0x0066 }, + { 0x0014, 0x0067 }, + { 0x0014, 0x0068 }, + { 0x0014, 0x0069 }, + { 0x0014, 0x006a }, + { 0x0014, 0x006b }, + { 0x000e, 0x0019 }, + { 0x000d, 0x0016 }, + { 0x000d, 0x0017 }, + { 0x000e, 0x001a }, + { 0x000e, 0x001b }, + { 0x000f, 0x001f }, + { 0x0010, 0x002e }, + { 0x0011, 0x0049 }, + { 0x0012, 0x0073 }, + { 0x0014, 0x006c }, + { 0x0014, 0x006d }, + { 0x0014, 0x006e }, + { 0x0014, 0x006f }, + { 0x0014, 0x0070 }, + { 0x0014, 0x0071 }, + { 0x0014, 0x0072 }, + { 0x0014, 0x0073 }, + { 0x0014, 0x0074 }, + { 0x0014, 0x0075 }, + { 0x0014, 0x0076 }, + { 0x0014, 0x0077 }, + { 0x0014, 0x0078 }, + { 0x0014, 0x0079 }, + { 0x0014, 0x007a }, + { 0x0010, 0x002f }, + { 0x000f, 0x0020 }, + { 0x0010, 0x0030 }, + { 0x000f, 0x0021 }, + { 0x0010, 0x0031 }, + { 0x0011, 0x004a }, + { 0x0011, 0x004b }, + { 0x0012, 0x0074 }, + { 0x0014, 0x007b }, + { 0x0014, 0x007c }, + { 0x0013, 0x00d2 }, + { 0x0014, 0x007d }, + { 0x0014, 0x007e }, + { 0x0014, 0x007f }, + { 0x0014, 0x0080 }, + { 0x0014, 0x0081 }, + { 0x0014, 0x0082 }, + { 0x0014, 0x0083 }, + { 0x0014, 0x0084 }, + { 0x0014, 0x0085 }, + { 0x0014, 0x0086 }, + { 0x0014, 0x0087 }, + { 0x0014, 0x0088 }, + { 0x0014, 0x0089 }, + { 0x0012, 0x0075 }, + { 0x0010, 0x0032 }, + { 0x0010, 0x0033 }, + { 0x0011, 0x004c }, + { 0x0011, 0x004d }, + { 0x0013, 0x00d3 }, + { 0x0013, 0x00d4 }, + { 0x0012, 0x0076 }, + { 0x0013, 0x00d5 }, + { 0x0014, 0x008a }, + { 0x0014, 0x008b }, + { 0x0014, 0x008c }, + { 0x0014, 0x008d }, + { 0x0014, 0x008e }, + { 0x0014, 0x008f }, + { 0x0014, 0x0090 }, + { 0x0014, 0x0091 }, + { 0x0014, 0x0092 }, + { 0x0014, 0x0093 }, + { 0x0014, 0x0094 }, + { 0x0014, 0x0095 }, + { 0x0014, 0x0096 }, + { 0x0014, 0x0097 }, + { 0x0014, 0x0098 }, + { 0x0013, 0x00d6 }, + { 0x0013, 0x00d7 }, + { 0x0012, 0x0077 }, + { 0x0012, 0x0078 }, + { 0x0014, 0x0099 }, + { 0x0014, 0x009a }, + { 0x0013, 0x00d8 }, + { 0x0014, 0x009b }, + { 0x0014, 0x009c }, + { 0x0014, 0x009d }, + { 0x0014, 0x009e }, + { 0x0014, 0x009f }, + { 0x0014, 0x00a0 }, + { 0x0014, 0x00a1 }, + { 0x0014, 0x00a2 }, + { 0x0014, 0x00a3 }, + { 0x0014, 0x00a4 }, + { 0x0014, 0x00a5 }, + { 0x0014, 0x00a6 }, + { 0x0014, 0x00a7 }, + { 0x0014, 0x00a8 }, + { 0x0014, 0x00a9 }, + { 0x0014, 0x00aa }, + { 0x0014, 0x00ab }, + { 0x0014, 0x00ac }, + { 0x0014, 0x00ad }, + { 0x0014, 0x00ae }, + { 0x0014, 0x00af }, + { 0x0012, 0x0079 }, + { 0x0014, 0x00b0 }, + { 0x0014, 0x00b1 }, + { 0x0014, 0x00b2 }, + { 0x0014, 0x00b3 }, + { 0x0014, 0x00b4 }, + { 0x0014, 0x00b5 }, + { 0x0014, 0x00b6 }, + { 0x0014, 0x00b7 }, + { 0x0014, 0x00b8 }, + { 0x0014, 0x00b9 }, + { 0x0014, 0x00ba }, + { 0x0014, 0x00bb }, + { 0x0014, 0x00bc }, + { 0x0014, 0x00bd }, + { 0x0014, 0x00be }, + { 0x0014, 0x00bf }, + { 0x0014, 0x00c0 }, + { 0x0014, 0x00c1 }, + { 0x0014, 0x00c2 }, + { 0x0014, 0x00c3 }, + { 0x0014, 0x00c4 }, + { 0x0014, 0x00c5 }, + { 0x0014, 0x00c6 }, + { 0x0013, 0x00d9 }, + { 0x0013, 0x00da }, + { 0x0014, 0x00c7 }, + { 0x0014, 0x00c8 }, + { 0x0014, 0x00c9 }, + { 0x0014, 0x00ca }, + { 0x0014, 0x00cb }, + { 0x0014, 0x00cc }, + { 0x0014, 0x00cd }, + { 0x0014, 0x00ce }, + { 0x0014, 0x00cf }, + { 0x0014, 0x00d0 }, + { 0x0014, 0x00d1 }, + { 0x0014, 0x00d2 }, + { 0x0014, 0x00d3 }, + { 0x0014, 0x00d4 }, + { 0x0014, 0x00d5 }, + { 0x0014, 0x00d6 }, + { 0x0014, 0x00d7 }, + { 0x0014, 0x00d8 }, + { 0x0014, 0x00d9 }, + { 0x0014, 0x00da }, + { 0x0014, 0x00db }, + { 0x0014, 0x00dc }, + { 0x0014, 0x00dd }, + { 0x0014, 0x00de }, + { 0x0014, 0x00df }, + { 0x0014, 0x00e0 }, + { 0x0014, 0x00e1 }, + { 0x0014, 0x00e2 }, + { 0x0014, 0x00e3 }, + { 0x0014, 0x00e4 }, + { 0x0014, 0x00e5 }, + { 0x0014, 0x00e6 }, + { 0x0014, 0x00e7 }, + { 0x0014, 0x00e8 }, + { 0x0014, 0x00e9 }, + { 0x0014, 0x00ea }, + { 0x0014, 0x00eb }, + { 0x0014, 0x00ec }, + { 0x0014, 0x00ed }, + { 0x0014, 0x00ee }, + { 0x0014, 0x00ef }, + { 0x0014, 0x00f0 }, + { 0x0014, 0x00f1 }, + { 0x0014, 0x00f2 }, + { 0x0014, 0x00f3 }, + { 0x0014, 0x00f4 }, + { 0x0014, 0x00f5 }, + { 0x0014, 0x00f6 }, + { 0x0014, 0x00f7 }, + { 0x0014, 0x00f8 }, + { 0x0014, 0x00f9 }, + { 0x0014, 0x00fa }, + { 0x0014, 0x00fb }, + { 0x0014, 0x00fc }, + { 0x0014, 0x00fd }, + { 0x0014, 0x00fe }, + { 0x0014, 0x00ff }, + { 0x0014, 0x0100 }, + { 0x0014, 0x0101 }, + { 0x0014, 0x0102 }, + { 0x0014, 0x0103 }, + { 0x0014, 0x0104 }, + { 0x0014, 0x0105 }, + { 0x0014, 0x0106 }, + { 0x0014, 0x0107 }, + { 0x0014, 0x0108 }, + { 0x0014, 0x0109 }, + { 0x0014, 0x010a }, + { 0x0014, 0x010b }, + { 0x0014, 0x010c }, + { 0x0014, 0x010d }, + { 0x0014, 0x010e }, + { 0x0014, 0x010f }, + { 0x0014, 0x0110 }, + { 0x0014, 0x0111 }, + { 0x0014, 0x0112 }, + { 0x0014, 0x0113 }, + { 0x0014, 0x0114 }, + { 0x0014, 0x0115 }, + { 0x0014, 0x0116 }, + { 0x0014, 0x0117 }, + { 0x0014, 0x0118 }, + { 0x0014, 0x0119 }, + { 0x0014, 0x011a }, + { 0x0014, 0x011b }, + { 0x0014, 0x011c }, + { 0x0014, 0x011d }, + { 0x0014, 0x011e }, + { 0x0014, 0x011f }, + { 0x0014, 0x0120 }, + { 0x0014, 0x0121 }, + { 0x0014, 0x0122 }, + { 0x0014, 0x0123 }, + { 0x0014, 0x0124 }, + { 0x0014, 0x0125 }, + { 0x0014, 0x0126 }, + { 0x0014, 0x0127 }, + { 0x0014, 0x0128 }, + { 0x0014, 0x0129 }, + { 0x0014, 0x012a }, + { 0x0014, 0x012b }, + { 0x0014, 0x012c }, + { 0x0014, 0x012d }, + { 0x0014, 0x012e }, + { 0x0014, 0x012f }, + { 0x0014, 0x0130 }, + { 0x0014, 0x0131 }, + { 0x0014, 0x0132 }, + { 0x0014, 0x0133 }, + { 0x0014, 0x0134 }, + { 0x0014, 0x0135 }, + { 0x0014, 0x0136 }, + { 0x0014, 0x0137 }, + { 0x0014, 0x0138 }, + { 0x0014, 0x0139 }, + { 0x0014, 0x013a }, + { 0x0014, 0x013b }, + { 0x0014, 0x013c }, + { 0x0014, 0x013d }, + { 0x0014, 0x013e }, + { 0x0014, 0x013f }, + { 0x0014, 0x0140 }, + { 0x0014, 0x0141 }, + { 0x0014, 0x0142 }, + { 0x0014, 0x0143 }, + { 0x0014, 0x0144 }, + { 0x0014, 0x0145 }, + { 0x0014, 0x0146 }, + { 0x0014, 0x0147 }, + { 0x0014, 0x0148 }, + { 0x0014, 0x0149 }, + { 0x0014, 0x014a }, + { 0x0014, 0x014b }, + { 0x0014, 0x014c }, + { 0x0014, 0x014d }, + { 0x0014, 0x014e }, + { 0x0014, 0x014f }, + { 0x0014, 0x0150 }, + { 0x0014, 0x0151 }, + { 0x0014, 0x0152 }, + { 0x0014, 0x0153 }, + { 0x0014, 0x0154 }, + { 0x0014, 0x0155 }, + { 0x0014, 0x0156 }, + { 0x0014, 0x0157 }, + { 0x0014, 0x0158 }, + { 0x0014, 0x0159 }, + { 0x0014, 0x015a }, + { 0x0014, 0x015b }, + { 0x0014, 0x015c }, + { 0x0014, 0x015d }, + { 0x0014, 0x015e }, + { 0x0014, 0x015f }, + { 0x0014, 0x0160 }, + { 0x0014, 0x0161 }, + { 0x0014, 0x0162 }, + { 0x0014, 0x0163 }, + { 0x0014, 0x0164 }, + { 0x0014, 0x0165 }, + { 0x0014, 0x0166 }, + { 0x0014, 0x0167 }, + { 0x0014, 0x0168 }, + { 0x0014, 0x0169 }, + { 0x0014, 0x016a }, + { 0x0014, 0x016b }, + { 0x0014, 0x016c }, + { 0x0014, 0x016d }, + { 0x0014, 0x016e }, + { 0x0014, 0x016f }, + { 0x0014, 0x0170 }, + { 0x0014, 0x0171 }, + { 0x0014, 0x0172 }, + { 0x0014, 0x0173 }, + { 0x0014, 0x0174 }, + { 0x0014, 0x0175 }, + { 0x0014, 0x0176 }, + { 0x0014, 0x0177 }, + { 0x0014, 0x0178 }, + { 0x0014, 0x0179 }, + { 0x0014, 0x017a }, + { 0x0014, 0x017b }, + { 0x0014, 0x017c }, + { 0x0014, 0x017d }, + { 0x0014, 0x017e }, + { 0x0014, 0x017f }, + { 0x0014, 0x0180 }, + { 0x0014, 0x0181 }, + { 0x0014, 0x0182 }, + { 0x0014, 0x0183 }, + { 0x0014, 0x0184 }, + { 0x0014, 0x0185 }, + { 0x0014, 0x0186 }, + { 0x0014, 0x0187 }, + { 0x0014, 0x0188 }, + { 0x0014, 0x0189 }, + { 0x0014, 0x018a }, + { 0x0014, 0x018b }, + { 0x0014, 0x018c }, + { 0x0014, 0x018d }, + { 0x0014, 0x018e }, + { 0x0014, 0x018f }, + { 0x0014, 0x0190 }, + { 0x0014, 0x0191 }, + { 0x0014, 0x0192 }, + { 0x0014, 0x0193 }, + { 0x0014, 0x0194 }, + { 0x0014, 0x0195 }, + { 0x0014, 0x0196 }, + { 0x0014, 0x0197 }, + { 0x0013, 0x00db }, + }; + +const uint16_t c_aauiLCLDHuffEnc16[729][2] = + { + { 0x0006, 0x000d }, + { 0x0005, 0x0010 }, + { 0x0006, 0x000e }, + { 0x0006, 0x000f }, + { 0x0006, 0x0010 }, + { 0x0007, 0x000a }, + { 0x0007, 0x000b }, + { 0x0008, 0x000a }, + { 0x0009, 0x000b }, + { 0x000b, 0x000d }, + { 0x000c, 0x000e }, + { 0x000e, 0x0016 }, + { 0x0010, 0x002d }, + { 0x0011, 0x0051 }, + { 0x0012, 0x008c }, + { 0x0014, 0x0000 }, + { 0x0014, 0x0001 }, + { 0x0014, 0x0002 }, + { 0x0014, 0x0003 }, + { 0x0014, 0x0004 }, + { 0x0014, 0x0005 }, + { 0x0014, 0x0006 }, + { 0x0014, 0x0007 }, + { 0x0014, 0x0008 }, + { 0x0014, 0x0009 }, + { 0x0014, 0x000a }, + { 0x0014, 0x000b }, + { 0x0005, 0x0011 }, + { 0x0004, 0x000f }, + { 0x0005, 0x0012 }, + { 0x0005, 0x0013 }, + { 0x0005, 0x0014 }, + { 0x0006, 0x0011 }, + { 0x0006, 0x0012 }, + { 0x0007, 0x000c }, + { 0x0008, 0x000b }, + { 0x000a, 0x000c }, + { 0x000b, 0x000e }, + { 0x000d, 0x0010 }, + { 0x000e, 0x0017 }, + { 0x000f, 0x001c }, + { 0x0013, 0x010b }, + { 0x0013, 0x010c }, + { 0x0014, 0x000c }, + { 0x0014, 0x000d }, + { 0x0014, 0x000e }, + { 0x0014, 0x000f }, + { 0x0014, 0x0010 }, + { 0x0014, 0x0011 }, + { 0x0014, 0x0012 }, + { 0x0014, 0x0013 }, + { 0x0014, 0x0014 }, + { 0x0014, 0x0015 }, + { 0x0014, 0x0016 }, + { 0x0006, 0x0013 }, + { 0x0005, 0x0015 }, + { 0x0005, 0x0016 }, + { 0x0005, 0x0017 }, + { 0x0005, 0x0018 }, + { 0x0006, 0x0014 }, + { 0x0007, 0x000d }, + { 0x0007, 0x000e }, + { 0x0009, 0x000c }, + { 0x000a, 0x000d }, + { 0x000c, 0x000f }, + { 0x000d, 0x0011 }, + { 0x000f, 0x001d }, + { 0x0011, 0x0052 }, + { 0x0012, 0x008d }, + { 0x0012, 0x008e }, + { 0x0014, 0x0017 }, + { 0x0014, 0x0018 }, + { 0x0014, 0x0019 }, + { 0x0014, 0x001a }, + { 0x0014, 0x001b }, + { 0x0014, 0x001c }, + { 0x0014, 0x001d }, + { 0x0014, 0x001e }, + { 0x0014, 0x001f }, + { 0x0014, 0x0020 }, + { 0x0014, 0x0021 }, + { 0x0006, 0x0015 }, + { 0x0005, 0x0019 }, + { 0x0005, 0x001a }, + { 0x0005, 0x001b }, + { 0x0006, 0x0016 }, + { 0x0006, 0x0017 }, + { 0x0007, 0x000f }, + { 0x0008, 0x000c }, + { 0x0009, 0x000d }, + { 0x000b, 0x000f }, + { 0x000c, 0x0010 }, + { 0x000d, 0x0012 }, + { 0x000f, 0x001e }, + { 0x0012, 0x008f }, + { 0x0014, 0x0022 }, + { 0x0014, 0x0023 }, + { 0x0014, 0x0024 }, + { 0x0014, 0x0025 }, + { 0x0014, 0x0026 }, + { 0x0014, 0x0027 }, + { 0x0014, 0x0028 }, + { 0x0014, 0x0029 }, + { 0x0014, 0x002a }, + { 0x0014, 0x002b }, + { 0x0014, 0x002c }, + { 0x0014, 0x002d }, + { 0x0014, 0x002e }, + { 0x0006, 0x0018 }, + { 0x0005, 0x001c }, + { 0x0005, 0x001d }, + { 0x0006, 0x0019 }, + { 0x0006, 0x001a }, + { 0x0007, 0x0010 }, + { 0x0007, 0x0011 }, + { 0x0008, 0x000d }, + { 0x000a, 0x000e }, + { 0x000b, 0x0010 }, + { 0x000c, 0x0011 }, + { 0x000e, 0x0018 }, + { 0x0010, 0x002e }, + { 0x0012, 0x0090 }, + { 0x0013, 0x010d }, + { 0x0013, 0x010e }, + { 0x0014, 0x002f }, + { 0x0014, 0x0030 }, + { 0x0014, 0x0031 }, + { 0x0014, 0x0032 }, + { 0x0014, 0x0033 }, + { 0x0014, 0x0034 }, + { 0x0014, 0x0035 }, + { 0x0014, 0x0036 }, + { 0x0014, 0x0037 }, + { 0x0014, 0x0038 }, + { 0x0014, 0x0039 }, + { 0x0007, 0x0012 }, + { 0x0006, 0x001b }, + { 0x0006, 0x001c }, + { 0x0006, 0x001d }, + { 0x0007, 0x0013 }, + { 0x0007, 0x0014 }, + { 0x0008, 0x000e }, + { 0x0009, 0x000e }, + { 0x000b, 0x0011 }, + { 0x000c, 0x0012 }, + { 0x000d, 0x0013 }, + { 0x000e, 0x0019 }, + { 0x0010, 0x002f }, + { 0x0012, 0x0091 }, + { 0x0014, 0x003a }, + { 0x0014, 0x003b }, + { 0x0014, 0x003c }, + { 0x0014, 0x003d }, + { 0x0014, 0x003e }, + { 0x0014, 0x003f }, + { 0x0014, 0x0040 }, + { 0x0014, 0x0041 }, + { 0x0014, 0x0042 }, + { 0x0014, 0x0043 }, + { 0x0014, 0x0044 }, + { 0x0014, 0x0045 }, + { 0x0014, 0x0046 }, + { 0x0007, 0x0015 }, + { 0x0006, 0x001e }, + { 0x0006, 0x001f }, + { 0x0007, 0x0016 }, + { 0x0007, 0x0017 }, + { 0x0008, 0x000f }, + { 0x0009, 0x000f }, + { 0x000a, 0x000f }, + { 0x000b, 0x0012 }, + { 0x000d, 0x0014 }, + { 0x000e, 0x001a }, + { 0x000f, 0x001f }, + { 0x0013, 0x010f }, + { 0x0011, 0x0053 }, + { 0x0014, 0x0047 }, + { 0x0014, 0x0048 }, + { 0x0014, 0x0049 }, + { 0x0014, 0x004a }, + { 0x0014, 0x004b }, + { 0x0014, 0x004c }, + { 0x0014, 0x004d }, + { 0x0014, 0x004e }, + { 0x0014, 0x004f }, + { 0x0014, 0x0050 }, + { 0x0014, 0x0051 }, + { 0x0014, 0x0052 }, + { 0x0014, 0x0053 }, + { 0x0008, 0x0010 }, + { 0x0007, 0x0018 }, + { 0x0007, 0x0019 }, + { 0x0008, 0x0011 }, + { 0x0008, 0x0012 }, + { 0x0009, 0x0010 }, + { 0x000a, 0x0010 }, + { 0x000b, 0x0013 }, + { 0x000c, 0x0013 }, + { 0x000e, 0x001b }, + { 0x000f, 0x0020 }, + { 0x0010, 0x0030 }, + { 0x0012, 0x0092 }, + { 0x0014, 0x0054 }, + { 0x0014, 0x0055 }, + { 0x0014, 0x0056 }, + { 0x0014, 0x0057 }, + { 0x0014, 0x0058 }, + { 0x0014, 0x0059 }, + { 0x0014, 0x005a }, + { 0x0014, 0x005b }, + { 0x0014, 0x005c }, + { 0x0014, 0x005d }, + { 0x0014, 0x005e }, + { 0x0014, 0x005f }, + { 0x0014, 0x0060 }, + { 0x0014, 0x0061 }, + { 0x0009, 0x0011 }, + { 0x0008, 0x0013 }, + { 0x0009, 0x0012 }, + { 0x0009, 0x0013 }, + { 0x000a, 0x0011 }, + { 0x000a, 0x0012 }, + { 0x000b, 0x0014 }, + { 0x000c, 0x0014 }, + { 0x000d, 0x0015 }, + { 0x000e, 0x001c }, + { 0x000f, 0x0021 }, + { 0x0013, 0x0110 }, + { 0x0012, 0x0093 }, + { 0x0012, 0x0094 }, + { 0x0014, 0x0062 }, + { 0x0014, 0x0063 }, + { 0x0014, 0x0064 }, + { 0x0014, 0x0065 }, + { 0x0014, 0x0066 }, + { 0x0014, 0x0067 }, + { 0x0014, 0x0068 }, + { 0x0014, 0x0069 }, + { 0x0014, 0x006a }, + { 0x0014, 0x006b }, + { 0x0014, 0x006c }, + { 0x0014, 0x006d }, + { 0x0014, 0x006e }, + { 0x000b, 0x0015 }, + { 0x000a, 0x0013 }, + { 0x000a, 0x0014 }, + { 0x000a, 0x0015 }, + { 0x000b, 0x0016 }, + { 0x000c, 0x0015 }, + { 0x000d, 0x0016 }, + { 0x000d, 0x0017 }, + { 0x000f, 0x0022 }, + { 0x0010, 0x0031 }, + { 0x0012, 0x0095 }, + { 0x0012, 0x0096 }, + { 0x0014, 0x006f }, + { 0x0013, 0x0111 }, + { 0x0014, 0x0070 }, + { 0x0014, 0x0071 }, + { 0x0014, 0x0072 }, + { 0x0014, 0x0073 }, + { 0x0014, 0x0074 }, + { 0x0014, 0x0075 }, + { 0x0014, 0x0076 }, + { 0x0014, 0x0077 }, + { 0x0014, 0x0078 }, + { 0x0014, 0x0079 }, + { 0x0014, 0x007a }, + { 0x0014, 0x007b }, + { 0x0014, 0x007c }, + { 0x000c, 0x0016 }, + { 0x000b, 0x0017 }, + { 0x000c, 0x0017 }, + { 0x000c, 0x0018 }, + { 0x000c, 0x0019 }, + { 0x000d, 0x0018 }, + { 0x000e, 0x001d }, + { 0x000f, 0x0023 }, + { 0x000f, 0x0024 }, + { 0x0011, 0x0054 }, + { 0x0012, 0x0097 }, + { 0x0014, 0x007d }, + { 0x0014, 0x007e }, + { 0x0014, 0x007f }, + { 0x0014, 0x0080 }, + { 0x0014, 0x0081 }, + { 0x0014, 0x0082 }, + { 0x0014, 0x0083 }, + { 0x0014, 0x0084 }, + { 0x0014, 0x0085 }, + { 0x0014, 0x0086 }, + { 0x0014, 0x0087 }, + { 0x0014, 0x0088 }, + { 0x0014, 0x0089 }, + { 0x0014, 0x008a }, + { 0x0014, 0x008b }, + { 0x0014, 0x008c }, + { 0x000e, 0x001e }, + { 0x000d, 0x0019 }, + { 0x000d, 0x001a }, + { 0x000d, 0x001b }, + { 0x000e, 0x001f }, + { 0x000f, 0x0025 }, + { 0x000f, 0x0026 }, + { 0x0010, 0x0032 }, + { 0x0010, 0x0033 }, + { 0x0012, 0x0098 }, + { 0x0013, 0x0112 }, + { 0x0014, 0x008d }, + { 0x0014, 0x008e }, + { 0x0014, 0x008f }, + { 0x0014, 0x0090 }, + { 0x0014, 0x0091 }, + { 0x0014, 0x0092 }, + { 0x0014, 0x0093 }, + { 0x0014, 0x0094 }, + { 0x0014, 0x0095 }, + { 0x0014, 0x0096 }, + { 0x0014, 0x0097 }, + { 0x0014, 0x0098 }, + { 0x0014, 0x0099 }, + { 0x0014, 0x009a }, + { 0x0014, 0x009b }, + { 0x0014, 0x009c }, + { 0x000f, 0x0027 }, + { 0x000f, 0x0028 }, + { 0x000f, 0x0029 }, + { 0x000f, 0x002a }, + { 0x0010, 0x0034 }, + { 0x000f, 0x002b }, + { 0x0011, 0x0055 }, + { 0x0012, 0x0099 }, + { 0x0012, 0x009a }, + { 0x0012, 0x009b }, + { 0x0014, 0x009d }, + { 0x0013, 0x0113 }, + { 0x0014, 0x009e }, + { 0x0014, 0x009f }, + { 0x0014, 0x00a0 }, + { 0x0014, 0x00a1 }, + { 0x0014, 0x00a2 }, + { 0x0014, 0x00a3 }, + { 0x0014, 0x00a4 }, + { 0x0014, 0x00a5 }, + { 0x0014, 0x00a6 }, + { 0x0014, 0x00a7 }, + { 0x0014, 0x00a8 }, + { 0x0014, 0x00a9 }, + { 0x0014, 0x00aa }, + { 0x0014, 0x00ab }, + { 0x0014, 0x00ac }, + { 0x0011, 0x0056 }, + { 0x0010, 0x0035 }, + { 0x0010, 0x0036 }, + { 0x0010, 0x0037 }, + { 0x0011, 0x0057 }, + { 0x0012, 0x009c }, + { 0x0012, 0x009d }, + { 0x0012, 0x009e }, + { 0x0014, 0x00ad }, + { 0x0014, 0x00ae }, + { 0x0014, 0x00af }, + { 0x0014, 0x00b0 }, + { 0x0014, 0x00b1 }, + { 0x0014, 0x00b2 }, + { 0x0014, 0x00b3 }, + { 0x0014, 0x00b4 }, + { 0x0014, 0x00b5 }, + { 0x0014, 0x00b6 }, + { 0x0014, 0x00b7 }, + { 0x0014, 0x00b8 }, + { 0x0014, 0x00b9 }, + { 0x0014, 0x00ba }, + { 0x0014, 0x00bb }, + { 0x0014, 0x00bc }, + { 0x0014, 0x00bd }, + { 0x0014, 0x00be }, + { 0x0014, 0x00bf }, + { 0x0012, 0x009f }, + { 0x0011, 0x0058 }, + { 0x0012, 0x00a0 }, + { 0x0014, 0x00c0 }, + { 0x0011, 0x0059 }, + { 0x0013, 0x0114 }, + { 0x0012, 0x00a1 }, + { 0x0014, 0x00c1 }, + { 0x0013, 0x0115 }, + { 0x0014, 0x00c2 }, + { 0x0014, 0x00c3 }, + { 0x0014, 0x00c4 }, + { 0x0014, 0x00c5 }, + { 0x0014, 0x00c6 }, + { 0x0014, 0x00c7 }, + { 0x0014, 0x00c8 }, + { 0x0014, 0x00c9 }, + { 0x0014, 0x00ca }, + { 0x0014, 0x00cb }, + { 0x0014, 0x00cc }, + { 0x0014, 0x00cd }, + { 0x0014, 0x00ce }, + { 0x0014, 0x00cf }, + { 0x0014, 0x00d0 }, + { 0x0014, 0x00d1 }, + { 0x0014, 0x00d2 }, + { 0x0014, 0x00d3 }, + { 0x0014, 0x00d4 }, + { 0x0014, 0x00d5 }, + { 0x0014, 0x00d6 }, + { 0x0014, 0x00d7 }, + { 0x0014, 0x00d8 }, + { 0x0014, 0x00d9 }, + { 0x0014, 0x00da }, + { 0x0014, 0x00db }, + { 0x0014, 0x00dc }, + { 0x0014, 0x00dd }, + { 0x0014, 0x00de }, + { 0x0014, 0x00df }, + { 0x0014, 0x00e0 }, + { 0x0014, 0x00e1 }, + { 0x0014, 0x00e2 }, + { 0x0014, 0x00e3 }, + { 0x0014, 0x00e4 }, + { 0x0014, 0x00e5 }, + { 0x0014, 0x00e6 }, + { 0x0014, 0x00e7 }, + { 0x0014, 0x00e8 }, + { 0x0014, 0x00e9 }, + { 0x0014, 0x00ea }, + { 0x0014, 0x00eb }, + { 0x0014, 0x00ec }, + { 0x0014, 0x00ed }, + { 0x0014, 0x00ee }, + { 0x0014, 0x00ef }, + { 0x0014, 0x00f0 }, + { 0x0014, 0x00f1 }, + { 0x0014, 0x00f2 }, + { 0x0014, 0x00f3 }, + { 0x0014, 0x00f4 }, + { 0x0014, 0x00f5 }, + { 0x0014, 0x00f6 }, + { 0x0014, 0x00f7 }, + { 0x0014, 0x00f8 }, + { 0x0014, 0x00f9 }, + { 0x0014, 0x00fa }, + { 0x0014, 0x00fb }, + { 0x0014, 0x00fc }, + { 0x0014, 0x00fd }, + { 0x0014, 0x00fe }, + { 0x0014, 0x00ff }, + { 0x0014, 0x0100 }, + { 0x0014, 0x0101 }, + { 0x0014, 0x0102 }, + { 0x0014, 0x0103 }, + { 0x0014, 0x0104 }, + { 0x0014, 0x0105 }, + { 0x0014, 0x0106 }, + { 0x0014, 0x0107 }, + { 0x0014, 0x0108 }, + { 0x0014, 0x0109 }, + { 0x0014, 0x010a }, + { 0x0014, 0x010b }, + { 0x0014, 0x010c }, + { 0x0014, 0x010d }, + { 0x0014, 0x010e }, + { 0x0014, 0x010f }, + { 0x0014, 0x0110 }, + { 0x0014, 0x0111 }, + { 0x0014, 0x0112 }, + { 0x0014, 0x0113 }, + { 0x0014, 0x0114 }, + { 0x0014, 0x0115 }, + { 0x0014, 0x0116 }, + { 0x0014, 0x0117 }, + { 0x0014, 0x0118 }, + { 0x0014, 0x0119 }, + { 0x0014, 0x011a }, + { 0x0014, 0x011b }, + { 0x0014, 0x011c }, + { 0x0014, 0x011d }, + { 0x0014, 0x011e }, + { 0x0014, 0x011f }, + { 0x0014, 0x0120 }, + { 0x0014, 0x0121 }, + { 0x0014, 0x0122 }, + { 0x0014, 0x0123 }, + { 0x0014, 0x0124 }, + { 0x0014, 0x0125 }, + { 0x0013, 0x0116 }, + { 0x0014, 0x0126 }, + { 0x0014, 0x0127 }, + { 0x0014, 0x0128 }, + { 0x0014, 0x0129 }, + { 0x0014, 0x012a }, + { 0x0014, 0x012b }, + { 0x0014, 0x012c }, + { 0x0014, 0x012d }, + { 0x0014, 0x012e }, + { 0x0014, 0x012f }, + { 0x0014, 0x0130 }, + { 0x0014, 0x0131 }, + { 0x0014, 0x0132 }, + { 0x0014, 0x0133 }, + { 0x0014, 0x0134 }, + { 0x0014, 0x0135 }, + { 0x0014, 0x0136 }, + { 0x0014, 0x0137 }, + { 0x0014, 0x0138 }, + { 0x0014, 0x0139 }, + { 0x0014, 0x013a }, + { 0x0014, 0x013b }, + { 0x0014, 0x013c }, + { 0x0014, 0x013d }, + { 0x0014, 0x013e }, + { 0x0014, 0x013f }, + { 0x0014, 0x0140 }, + { 0x0014, 0x0141 }, + { 0x0014, 0x0142 }, + { 0x0014, 0x0143 }, + { 0x0014, 0x0144 }, + { 0x0014, 0x0145 }, + { 0x0014, 0x0146 }, + { 0x0014, 0x0147 }, + { 0x0014, 0x0148 }, + { 0x0014, 0x0149 }, + { 0x0014, 0x014a }, + { 0x0014, 0x014b }, + { 0x0014, 0x014c }, + { 0x0014, 0x014d }, + { 0x0014, 0x014e }, + { 0x0014, 0x014f }, + { 0x0014, 0x0150 }, + { 0x0014, 0x0151 }, + { 0x0014, 0x0152 }, + { 0x0014, 0x0153 }, + { 0x0014, 0x0154 }, + { 0x0014, 0x0155 }, + { 0x0014, 0x0156 }, + { 0x0014, 0x0157 }, + { 0x0014, 0x0158 }, + { 0x0014, 0x0159 }, + { 0x0014, 0x015a }, + { 0x0014, 0x015b }, + { 0x0014, 0x015c }, + { 0x0014, 0x015d }, + { 0x0014, 0x015e }, + { 0x0014, 0x015f }, + { 0x0014, 0x0160 }, + { 0x0014, 0x0161 }, + { 0x0014, 0x0162 }, + { 0x0014, 0x0163 }, + { 0x0014, 0x0164 }, + { 0x0014, 0x0165 }, + { 0x0014, 0x0166 }, + { 0x0014, 0x0167 }, + { 0x0014, 0x0168 }, + { 0x0014, 0x0169 }, + { 0x0014, 0x016a }, + { 0x0014, 0x016b }, + { 0x0014, 0x016c }, + { 0x0014, 0x016d }, + { 0x0014, 0x016e }, + { 0x0014, 0x016f }, + { 0x0014, 0x0170 }, + { 0x0014, 0x0171 }, + { 0x0014, 0x0172 }, + { 0x0014, 0x0173 }, + { 0x0014, 0x0174 }, + { 0x0014, 0x0175 }, + { 0x0014, 0x0176 }, + { 0x0014, 0x0177 }, + { 0x0014, 0x0178 }, + { 0x0014, 0x0179 }, + { 0x0014, 0x017a }, + { 0x0014, 0x017b }, + { 0x0014, 0x017c }, + { 0x0014, 0x017d }, + { 0x0014, 0x017e }, + { 0x0014, 0x017f }, + { 0x0014, 0x0180 }, + { 0x0014, 0x0181 }, + { 0x0014, 0x0182 }, + { 0x0014, 0x0183 }, + { 0x0014, 0x0184 }, + { 0x0014, 0x0185 }, + { 0x0014, 0x0186 }, + { 0x0014, 0x0187 }, + { 0x0014, 0x0188 }, + { 0x0014, 0x0189 }, + { 0x0014, 0x018a }, + { 0x0014, 0x018b }, + { 0x0014, 0x018c }, + { 0x0014, 0x018d }, + { 0x0014, 0x018e }, + { 0x0014, 0x018f }, + { 0x0014, 0x0190 }, + { 0x0014, 0x0191 }, + { 0x0014, 0x0192 }, + { 0x0014, 0x0193 }, + { 0x0014, 0x0194 }, + { 0x0014, 0x0195 }, + { 0x0014, 0x0196 }, + { 0x0014, 0x0197 }, + { 0x0014, 0x0198 }, + { 0x0014, 0x0199 }, + { 0x0014, 0x019a }, + { 0x0014, 0x019b }, + { 0x0014, 0x019c }, + { 0x0014, 0x019d }, + { 0x0014, 0x019e }, + { 0x0014, 0x019f }, + { 0x0014, 0x01a0 }, + { 0x0014, 0x01a1 }, + { 0x0014, 0x01a2 }, + { 0x0014, 0x01a3 }, + { 0x0014, 0x01a4 }, + { 0x0014, 0x01a5 }, + { 0x0014, 0x01a6 }, + { 0x0014, 0x01a7 }, + { 0x0014, 0x01a8 }, + { 0x0014, 0x01a9 }, + { 0x0014, 0x01aa }, + { 0x0014, 0x01ab }, + { 0x0014, 0x01ac }, + { 0x0014, 0x01ad }, + { 0x0014, 0x01ae }, + { 0x0014, 0x01af }, + { 0x0014, 0x01b0 }, + { 0x0014, 0x01b1 }, + { 0x0014, 0x01b2 }, + { 0x0014, 0x01b3 }, + { 0x0014, 0x01b4 }, + { 0x0014, 0x01b5 }, + { 0x0014, 0x01b6 }, + { 0x0014, 0x01b7 }, + { 0x0014, 0x01b8 }, + { 0x0014, 0x01b9 }, + { 0x0014, 0x01ba }, + { 0x0014, 0x01bb }, + { 0x0014, 0x01bc }, + { 0x0014, 0x01bd }, + { 0x0014, 0x01be }, + { 0x0014, 0x01bf }, + { 0x0014, 0x01c0 }, + { 0x0014, 0x01c1 }, + { 0x0014, 0x01c2 }, + { 0x0014, 0x01c3 }, + { 0x0014, 0x01c4 }, + { 0x0014, 0x01c5 }, + { 0x0014, 0x01c6 }, + { 0x0014, 0x01c7 }, + { 0x0014, 0x01c8 }, + { 0x0014, 0x01c9 }, + { 0x0014, 0x01ca }, + { 0x0014, 0x01cb }, + { 0x0014, 0x01cc }, + { 0x0014, 0x01cd }, + { 0x0014, 0x01ce }, + { 0x0014, 0x01cf }, + { 0x0014, 0x01d0 }, + { 0x0014, 0x01d1 }, + { 0x0014, 0x01d2 }, + { 0x0014, 0x01d3 }, + { 0x0014, 0x01d4 }, + { 0x0014, 0x01d5 }, + { 0x0014, 0x01d6 }, + { 0x0014, 0x01d7 }, + { 0x0014, 0x01d8 }, + { 0x0014, 0x01d9 }, + { 0x0014, 0x01da }, + { 0x0014, 0x01db }, + { 0x0014, 0x01dc }, + { 0x0014, 0x01dd }, + { 0x0014, 0x01de }, + { 0x0014, 0x01df }, + { 0x0014, 0x01e0 }, + { 0x0014, 0x01e1 }, + { 0x0014, 0x01e2 }, + { 0x0014, 0x01e3 }, + { 0x0014, 0x01e4 }, + { 0x0014, 0x01e5 }, + { 0x0014, 0x01e6 }, + { 0x0014, 0x01e7 }, + { 0x0014, 0x01e8 }, + { 0x0014, 0x01e9 }, + { 0x0014, 0x01ea }, + { 0x0014, 0x01eb }, + { 0x0014, 0x01ec }, + { 0x0014, 0x01ed }, + { 0x0014, 0x01ee }, + { 0x0014, 0x01ef }, + { 0x0014, 0x01f0 }, + { 0x0014, 0x01f1 }, + { 0x0014, 0x01f2 }, + { 0x0014, 0x01f3 }, + { 0x0014, 0x01f4 }, + { 0x0014, 0x01f5 }, + { 0x0014, 0x01f6 }, + { 0x0014, 0x01f7 }, + { 0x0014, 0x01f8 }, + { 0x0014, 0x01f9 }, + { 0x0014, 0x01fa }, + { 0x0014, 0x01fb }, + { 0x0014, 0x01fc }, + { 0x0014, 0x01fd }, + { 0x0014, 0x01fe }, + { 0x0014, 0x01ff }, + { 0x0014, 0x0200 }, + { 0x0014, 0x0201 }, + { 0x0014, 0x0202 }, + { 0x0014, 0x0203 }, + { 0x0014, 0x0204 }, + { 0x0014, 0x0205 }, + { 0x0014, 0x0206 }, + { 0x0014, 0x0207 }, + { 0x0014, 0x0208 }, + { 0x0014, 0x0209 }, + { 0x0014, 0x020a }, + { 0x0014, 0x020b }, + { 0x0014, 0x020c }, + { 0x0014, 0x020d }, + { 0x0014, 0x020e }, + { 0x0014, 0x020f }, + { 0x0014, 0x0210 }, + { 0x0014, 0x0211 }, + { 0x0014, 0x0212 }, + { 0x0014, 0x0213 }, + { 0x0014, 0x0214 }, + { 0x0014, 0x0215 }, + { 0x0013, 0x0117 }, + + }; + + +const uint16_t c_aauiLCLDHuffEnc17[729][2] = + { + { 0x0006, 0x0012 }, + { 0x0006, 0x0013 }, + { 0x0006, 0x0014 }, + { 0x0006, 0x0015 }, + { 0x0007, 0x000f }, + { 0x0007, 0x0010 }, + { 0x0007, 0x0011 }, + { 0x0008, 0x000e }, + { 0x0008, 0x000f }, + { 0x0009, 0x000f }, + { 0x000a, 0x000f }, + { 0x000c, 0x0011 }, + { 0x000d, 0x0014 }, + { 0x000e, 0x0017 }, + { 0x0010, 0x002d }, + { 0x0011, 0x004c }, + { 0x0012, 0x008a }, + { 0x0014, 0x0000 }, + { 0x0014, 0x0001 }, + { 0x0014, 0x0002 }, + { 0x0014, 0x0003 }, + { 0x0014, 0x0004 }, + { 0x0014, 0x0005 }, + { 0x0014, 0x0006 }, + { 0x0014, 0x0007 }, + { 0x0014, 0x0008 }, + { 0x0014, 0x0009 }, + { 0x0006, 0x0016 }, + { 0x0005, 0x0018 }, + { 0x0005, 0x0019 }, + { 0x0005, 0x001a }, + { 0x0006, 0x0017 }, + { 0x0006, 0x0018 }, + { 0x0006, 0x0019 }, + { 0x0007, 0x0012 }, + { 0x0007, 0x0013 }, + { 0x0008, 0x0010 }, + { 0x000a, 0x0010 }, + { 0x000b, 0x0011 }, + { 0x000c, 0x0012 }, + { 0x000e, 0x0018 }, + { 0x000f, 0x0020 }, + { 0x0011, 0x004d }, + { 0x0013, 0x00e4 }, + { 0x0014, 0x000a }, + { 0x0014, 0x000b }, + { 0x0014, 0x000c }, + { 0x0014, 0x000d }, + { 0x0014, 0x000e }, + { 0x0014, 0x000f }, + { 0x0014, 0x0010 }, + { 0x0014, 0x0011 }, + { 0x0014, 0x0012 }, + { 0x0014, 0x0013 }, + { 0x0006, 0x001a }, + { 0x0005, 0x001b }, + { 0x0005, 0x001c }, + { 0x0005, 0x001d }, + { 0x0006, 0x001b }, + { 0x0006, 0x001c }, + { 0x0006, 0x001d }, + { 0x0007, 0x0014 }, + { 0x0008, 0x0011 }, + { 0x0009, 0x0010 }, + { 0x000a, 0x0011 }, + { 0x000b, 0x0012 }, + { 0x000c, 0x0013 }, + { 0x000e, 0x0019 }, + { 0x000f, 0x0021 }, + { 0x0010, 0x002e }, + { 0x0013, 0x00e5 }, + { 0x0013, 0x00e6 }, + { 0x0014, 0x0014 }, + { 0x0014, 0x0015 }, + { 0x0014, 0x0016 }, + { 0x0014, 0x0017 }, + { 0x0014, 0x0018 }, + { 0x0014, 0x0019 }, + { 0x0014, 0x001a }, + { 0x0014, 0x001b }, + { 0x0014, 0x001c }, + { 0x0006, 0x001e }, + { 0x0005, 0x001e }, + { 0x0005, 0x001f }, + { 0x0006, 0x001f }, + { 0x0006, 0x0020 }, + { 0x0006, 0x0021 }, + { 0x0006, 0x0022 }, + { 0x0007, 0x0015 }, + { 0x0008, 0x0012 }, + { 0x0009, 0x0011 }, + { 0x000a, 0x0012 }, + { 0x000b, 0x0013 }, + { 0x000c, 0x0014 }, + { 0x000e, 0x001a }, + { 0x000f, 0x0022 }, + { 0x0010, 0x002f }, + { 0x0013, 0x00e7 }, + { 0x0013, 0x00e8 }, + { 0x0014, 0x001d }, + { 0x0014, 0x001e }, + { 0x0014, 0x001f }, + { 0x0014, 0x0020 }, + { 0x0014, 0x0021 }, + { 0x0014, 0x0022 }, + { 0x0014, 0x0023 }, + { 0x0014, 0x0024 }, + { 0x0014, 0x0025 }, + { 0x0006, 0x0023 }, + { 0x0006, 0x0024 }, + { 0x0006, 0x0025 }, + { 0x0006, 0x0026 }, + { 0x0006, 0x0027 }, + { 0x0006, 0x0028 }, + { 0x0007, 0x0016 }, + { 0x0007, 0x0017 }, + { 0x0008, 0x0013 }, + { 0x0009, 0x0012 }, + { 0x000a, 0x0013 }, + { 0x000c, 0x0015 }, + { 0x000d, 0x0015 }, + { 0x000f, 0x0023 }, + { 0x0010, 0x0030 }, + { 0x0011, 0x004e }, + { 0x0014, 0x0026 }, + { 0x0014, 0x0027 }, + { 0x0014, 0x0028 }, + { 0x0014, 0x0029 }, + { 0x0014, 0x002a }, + { 0x0014, 0x002b }, + { 0x0014, 0x002c }, + { 0x0014, 0x002d }, + { 0x0014, 0x002e }, + { 0x0014, 0x002f }, + { 0x0014, 0x0030 }, + { 0x0007, 0x0018 }, + { 0x0006, 0x0029 }, + { 0x0006, 0x002a }, + { 0x0006, 0x002b }, + { 0x0006, 0x002c }, + { 0x0007, 0x0019 }, + { 0x0007, 0x001a }, + { 0x0008, 0x0014 }, + { 0x0009, 0x0013 }, + { 0x000a, 0x0014 }, + { 0x000b, 0x0014 }, + { 0x000c, 0x0016 }, + { 0x000d, 0x0016 }, + { 0x000f, 0x0024 }, + { 0x0010, 0x0031 }, + { 0x0011, 0x004f }, + { 0x0014, 0x0031 }, + { 0x0014, 0x0032 }, + { 0x0014, 0x0033 }, + { 0x0014, 0x0034 }, + { 0x0014, 0x0035 }, + { 0x0014, 0x0036 }, + { 0x0014, 0x0037 }, + { 0x0014, 0x0038 }, + { 0x0014, 0x0039 }, + { 0x0014, 0x003a }, + { 0x0014, 0x003b }, + { 0x0007, 0x001b }, + { 0x0006, 0x002d }, + { 0x0006, 0x002e }, + { 0x0006, 0x002f }, + { 0x0007, 0x001c }, + { 0x0007, 0x001d }, + { 0x0008, 0x0015 }, + { 0x0009, 0x0014 }, + { 0x000a, 0x0015 }, + { 0x000a, 0x0016 }, + { 0x000c, 0x0017 }, + { 0x000d, 0x0017 }, + { 0x000e, 0x001b }, + { 0x000f, 0x0025 }, + { 0x0011, 0x0050 }, + { 0x0011, 0x0051 }, + { 0x0014, 0x003c }, + { 0x0014, 0x003d }, + { 0x0014, 0x003e }, + { 0x0014, 0x003f }, + { 0x0014, 0x0040 }, + { 0x0014, 0x0041 }, + { 0x0014, 0x0042 }, + { 0x0014, 0x0043 }, + { 0x0014, 0x0044 }, + { 0x0014, 0x0045 }, + { 0x0014, 0x0046 }, + { 0x0008, 0x0016 }, + { 0x0007, 0x001e }, + { 0x0007, 0x001f }, + { 0x0007, 0x0020 }, + { 0x0007, 0x0021 }, + { 0x0008, 0x0017 }, + { 0x0008, 0x0018 }, + { 0x0009, 0x0015 }, + { 0x000a, 0x0017 }, + { 0x000b, 0x0015 }, + { 0x000c, 0x0018 }, + { 0x000e, 0x001c }, + { 0x000e, 0x001d }, + { 0x0010, 0x0032 }, + { 0x0012, 0x008b }, + { 0x0012, 0x008c }, + { 0x0014, 0x0047 }, + { 0x0014, 0x0048 }, + { 0x0014, 0x0049 }, + { 0x0014, 0x004a }, + { 0x0014, 0x004b }, + { 0x0014, 0x004c }, + { 0x0014, 0x004d }, + { 0x0014, 0x004e }, + { 0x0014, 0x004f }, + { 0x0014, 0x0050 }, + { 0x0014, 0x0051 }, + { 0x0008, 0x0019 }, + { 0x0007, 0x0022 }, + { 0x0007, 0x0023 }, + { 0x0008, 0x001a }, + { 0x0008, 0x001b }, + { 0x0009, 0x0016 }, + { 0x0009, 0x0017 }, + { 0x000a, 0x0018 }, + { 0x000b, 0x0016 }, + { 0x000c, 0x0019 }, + { 0x000d, 0x0018 }, + { 0x000e, 0x001e }, + { 0x0010, 0x0033 }, + { 0x0011, 0x0052 }, + { 0x0014, 0x0052 }, + { 0x0013, 0x00e9 }, + { 0x0014, 0x0053 }, + { 0x0014, 0x0054 }, + { 0x0014, 0x0055 }, + { 0x0014, 0x0056 }, + { 0x0014, 0x0057 }, + { 0x0014, 0x0058 }, + { 0x0014, 0x0059 }, + { 0x0014, 0x005a }, + { 0x0014, 0x005b }, + { 0x0014, 0x005c }, + { 0x0014, 0x005d }, + { 0x0009, 0x0018 }, + { 0x0008, 0x001c }, + { 0x0008, 0x001d }, + { 0x0009, 0x0019 }, + { 0x0009, 0x001a }, + { 0x000a, 0x0019 }, + { 0x000a, 0x001a }, + { 0x000b, 0x0017 }, + { 0x000c, 0x001a }, + { 0x000d, 0x0019 }, + { 0x000e, 0x001f }, + { 0x000f, 0x0026 }, + { 0x0010, 0x0034 }, + { 0x0012, 0x008d }, + { 0x0013, 0x00ea }, + { 0x0014, 0x005e }, + { 0x0014, 0x005f }, + { 0x0014, 0x0060 }, + { 0x0014, 0x0061 }, + { 0x0014, 0x0062 }, + { 0x0014, 0x0063 }, + { 0x0014, 0x0064 }, + { 0x0014, 0x0065 }, + { 0x0014, 0x0066 }, + { 0x0014, 0x0067 }, + { 0x0014, 0x0068 }, + { 0x0014, 0x0069 }, + { 0x000b, 0x0018 }, + { 0x0009, 0x001b }, + { 0x000a, 0x001b }, + { 0x000a, 0x001c }, + { 0x000a, 0x001d }, + { 0x000b, 0x0019 }, + { 0x000b, 0x001a }, + { 0x000c, 0x001b }, + { 0x000d, 0x001a }, + { 0x000e, 0x0020 }, + { 0x000f, 0x0027 }, + { 0x0012, 0x008e }, + { 0x0011, 0x0053 }, + { 0x0013, 0x00eb }, + { 0x0014, 0x006a }, + { 0x0014, 0x006b }, + { 0x0014, 0x006c }, + { 0x0014, 0x006d }, + { 0x0014, 0x006e }, + { 0x0014, 0x006f }, + { 0x0014, 0x0070 }, + { 0x0014, 0x0071 }, + { 0x0014, 0x0072 }, + { 0x0014, 0x0073 }, + { 0x0014, 0x0074 }, + { 0x0014, 0x0075 }, + { 0x0014, 0x0076 }, + { 0x000c, 0x001c }, + { 0x000b, 0x001b }, + { 0x000b, 0x001c }, + { 0x000b, 0x001d }, + { 0x000c, 0x001d }, + { 0x000c, 0x001e }, + { 0x000d, 0x001b }, + { 0x000d, 0x001c }, + { 0x000e, 0x0021 }, + { 0x0010, 0x0035 }, + { 0x0010, 0x0036 }, + { 0x0011, 0x0054 }, + { 0x0013, 0x00ec }, + { 0x0014, 0x0077 }, + { 0x0014, 0x0078 }, + { 0x0014, 0x0079 }, + { 0x0014, 0x007a }, + { 0x0014, 0x007b }, + { 0x0014, 0x007c }, + { 0x0014, 0x007d }, + { 0x0014, 0x007e }, + { 0x0014, 0x007f }, + { 0x0014, 0x0080 }, + { 0x0014, 0x0081 }, + { 0x0014, 0x0082 }, + { 0x0014, 0x0083 }, + { 0x0014, 0x0084 }, + { 0x000d, 0x001d }, + { 0x000c, 0x001f }, + { 0x000c, 0x0020 }, + { 0x000c, 0x0021 }, + { 0x000d, 0x001e }, + { 0x000d, 0x001f }, + { 0x000e, 0x0022 }, + { 0x000f, 0x0028 }, + { 0x0010, 0x0037 }, + { 0x0010, 0x0038 }, + { 0x0010, 0x0039 }, + { 0x0012, 0x008f }, + { 0x0013, 0x00ed }, + { 0x0014, 0x0085 }, + { 0x0014, 0x0086 }, + { 0x0014, 0x0087 }, + { 0x0014, 0x0088 }, + { 0x0014, 0x0089 }, + { 0x0014, 0x008a }, + { 0x0014, 0x008b }, + { 0x0014, 0x008c }, + { 0x0014, 0x008d }, + { 0x0014, 0x008e }, + { 0x0014, 0x008f }, + { 0x0014, 0x0090 }, + { 0x0014, 0x0091 }, + { 0x0014, 0x0092 }, + { 0x000e, 0x0023 }, + { 0x000d, 0x0020 }, + { 0x000d, 0x0021 }, + { 0x000e, 0x0024 }, + { 0x000e, 0x0025 }, + { 0x000e, 0x0026 }, + { 0x000f, 0x0029 }, + { 0x0010, 0x003a }, + { 0x0010, 0x003b }, + { 0x0012, 0x0090 }, + { 0x0014, 0x0093 }, + { 0x0014, 0x0094 }, + { 0x0014, 0x0095 }, + { 0x0014, 0x0096 }, + { 0x0014, 0x0097 }, + { 0x0014, 0x0098 }, + { 0x0014, 0x0099 }, + { 0x0014, 0x009a }, + { 0x0014, 0x009b }, + { 0x0014, 0x009c }, + { 0x0014, 0x009d }, + { 0x0014, 0x009e }, + { 0x0014, 0x009f }, + { 0x0014, 0x00a0 }, + { 0x0014, 0x00a1 }, + { 0x0014, 0x00a2 }, + { 0x0014, 0x00a3 }, + { 0x000f, 0x002a }, + { 0x000e, 0x0027 }, + { 0x000f, 0x002b }, + { 0x000f, 0x002c }, + { 0x000f, 0x002d }, + { 0x0010, 0x003c }, + { 0x0010, 0x003d }, + { 0x0011, 0x0055 }, + { 0x0011, 0x0056 }, + { 0x0014, 0x00a4 }, + { 0x0014, 0x00a5 }, + { 0x0014, 0x00a6 }, + { 0x0014, 0x00a7 }, + { 0x0014, 0x00a8 }, + { 0x0014, 0x00a9 }, + { 0x0014, 0x00aa }, + { 0x0014, 0x00ab }, + { 0x0014, 0x00ac }, + { 0x0014, 0x00ad }, + { 0x0014, 0x00ae }, + { 0x0014, 0x00af }, + { 0x0014, 0x00b0 }, + { 0x0014, 0x00b1 }, + { 0x0014, 0x00b2 }, + { 0x0014, 0x00b3 }, + { 0x0014, 0x00b4 }, + { 0x0014, 0x00b5 }, + { 0x0012, 0x0091 }, + { 0x0010, 0x003e }, + { 0x0010, 0x003f }, + { 0x0011, 0x0057 }, + { 0x0011, 0x0058 }, + { 0x0011, 0x0059 }, + { 0x0012, 0x0092 }, + { 0x0013, 0x00ee }, + { 0x0013, 0x00ef }, + { 0x0012, 0x0093 }, + { 0x0014, 0x00b6 }, + { 0x0014, 0x00b7 }, + { 0x0014, 0x00b8 }, + { 0x0014, 0x00b9 }, + { 0x0014, 0x00ba }, + { 0x0014, 0x00bb }, + { 0x0014, 0x00bc }, + { 0x0014, 0x00bd }, + { 0x0014, 0x00be }, + { 0x0014, 0x00bf }, + { 0x0014, 0x00c0 }, + { 0x0014, 0x00c1 }, + { 0x0014, 0x00c2 }, + { 0x0014, 0x00c3 }, + { 0x0014, 0x00c4 }, + { 0x0014, 0x00c5 }, + { 0x0014, 0x00c6 }, + { 0x0013, 0x00f0 }, + { 0x0012, 0x0094 }, + { 0x0012, 0x0095 }, + { 0x0012, 0x0096 }, + { 0x0014, 0x00c7 }, + { 0x0014, 0x00c8 }, + { 0x0014, 0x00c9 }, + { 0x0014, 0x00ca }, + { 0x0014, 0x00cb }, + { 0x0014, 0x00cc }, + { 0x0014, 0x00cd }, + { 0x0014, 0x00ce }, + { 0x0014, 0x00cf }, + { 0x0014, 0x00d0 }, + { 0x0014, 0x00d1 }, + { 0x0014, 0x00d2 }, + { 0x0014, 0x00d3 }, + { 0x0014, 0x00d4 }, + { 0x0014, 0x00d5 }, + { 0x0014, 0x00d6 }, + { 0x0014, 0x00d7 }, + { 0x0014, 0x00d8 }, + { 0x0014, 0x00d9 }, + { 0x0014, 0x00da }, + { 0x0014, 0x00db }, + { 0x0014, 0x00dc }, + { 0x0014, 0x00dd }, + { 0x0014, 0x00de }, + { 0x0012, 0x0097 }, + { 0x0014, 0x00df }, + { 0x0014, 0x00e0 }, + { 0x0014, 0x00e1 }, + { 0x0014, 0x00e2 }, + { 0x0014, 0x00e3 }, + { 0x0014, 0x00e4 }, + { 0x0014, 0x00e5 }, + { 0x0014, 0x00e6 }, + { 0x0014, 0x00e7 }, + { 0x0014, 0x00e8 }, + { 0x0014, 0x00e9 }, + { 0x0014, 0x00ea }, + { 0x0014, 0x00eb }, + { 0x0014, 0x00ec }, + { 0x0014, 0x00ed }, + { 0x0014, 0x00ee }, + { 0x0014, 0x00ef }, + { 0x0014, 0x00f0 }, + { 0x0014, 0x00f1 }, + { 0x0014, 0x00f2 }, + { 0x0014, 0x00f3 }, + { 0x0014, 0x00f4 }, + { 0x0014, 0x00f5 }, + { 0x0014, 0x00f6 }, + { 0x0014, 0x00f7 }, + { 0x0014, 0x00f8 }, + { 0x0014, 0x00f9 }, + { 0x0014, 0x00fa }, + { 0x0014, 0x00fb }, + { 0x0014, 0x00fc }, + { 0x0014, 0x00fd }, + { 0x0014, 0x00fe }, + { 0x0014, 0x00ff }, + { 0x0014, 0x0100 }, + { 0x0014, 0x0101 }, + { 0x0014, 0x0102 }, + { 0x0014, 0x0103 }, + { 0x0014, 0x0104 }, + { 0x0014, 0x0105 }, + { 0x0014, 0x0106 }, + { 0x0014, 0x0107 }, + { 0x0014, 0x0108 }, + { 0x0014, 0x0109 }, + { 0x0014, 0x010a }, + { 0x0014, 0x010b }, + { 0x0014, 0x010c }, + { 0x0014, 0x010d }, + { 0x0014, 0x010e }, + { 0x0014, 0x010f }, + { 0x0014, 0x0110 }, + { 0x0014, 0x0111 }, + { 0x0014, 0x0112 }, + { 0x0014, 0x0113 }, + { 0x0014, 0x0114 }, + { 0x0014, 0x0115 }, + { 0x0014, 0x0116 }, + { 0x0014, 0x0117 }, + { 0x0014, 0x0118 }, + { 0x0014, 0x0119 }, + { 0x0014, 0x011a }, + { 0x0014, 0x011b }, + { 0x0014, 0x011c }, + { 0x0014, 0x011d }, + { 0x0014, 0x011e }, + { 0x0014, 0x011f }, + { 0x0014, 0x0120 }, + { 0x0014, 0x0121 }, + { 0x0014, 0x0122 }, + { 0x0014, 0x0123 }, + { 0x0014, 0x0124 }, + { 0x0014, 0x0125 }, + { 0x0014, 0x0126 }, + { 0x0014, 0x0127 }, + { 0x0014, 0x0128 }, + { 0x0014, 0x0129 }, + { 0x0014, 0x012a }, + { 0x0014, 0x012b }, + { 0x0014, 0x012c }, + { 0x0014, 0x012d }, + { 0x0014, 0x012e }, + { 0x0014, 0x012f }, + { 0x0014, 0x0130 }, + { 0x0014, 0x0131 }, + { 0x0014, 0x0132 }, + { 0x0014, 0x0133 }, + { 0x0014, 0x0134 }, + { 0x0014, 0x0135 }, + { 0x0014, 0x0136 }, + { 0x0014, 0x0137 }, + { 0x0014, 0x0138 }, + { 0x0014, 0x0139 }, + { 0x0014, 0x013a }, + { 0x0014, 0x013b }, + { 0x0014, 0x013c }, + { 0x0014, 0x013d }, + { 0x0014, 0x013e }, + { 0x0014, 0x013f }, + { 0x0014, 0x0140 }, + { 0x0014, 0x0141 }, + { 0x0014, 0x0142 }, + { 0x0014, 0x0143 }, + { 0x0014, 0x0144 }, + { 0x0014, 0x0145 }, + { 0x0014, 0x0146 }, + { 0x0014, 0x0147 }, + { 0x0014, 0x0148 }, + { 0x0014, 0x0149 }, + { 0x0014, 0x014a }, + { 0x0014, 0x014b }, + { 0x0014, 0x014c }, + { 0x0014, 0x014d }, + { 0x0014, 0x014e }, + { 0x0014, 0x014f }, + { 0x0014, 0x0150 }, + { 0x0014, 0x0151 }, + { 0x0014, 0x0152 }, + { 0x0014, 0x0153 }, + { 0x0014, 0x0154 }, + { 0x0014, 0x0155 }, + { 0x0014, 0x0156 }, + { 0x0014, 0x0157 }, + { 0x0014, 0x0158 }, + { 0x0014, 0x0159 }, + { 0x0014, 0x015a }, + { 0x0014, 0x015b }, + { 0x0014, 0x015c }, + { 0x0014, 0x015d }, + { 0x0014, 0x015e }, + { 0x0014, 0x015f }, + { 0x0014, 0x0160 }, + { 0x0014, 0x0161 }, + { 0x0014, 0x0162 }, + { 0x0014, 0x0163 }, + { 0x0014, 0x0164 }, + { 0x0014, 0x0165 }, + { 0x0014, 0x0166 }, + { 0x0014, 0x0167 }, + { 0x0014, 0x0168 }, + { 0x0014, 0x0169 }, + { 0x0014, 0x016a }, + { 0x0014, 0x016b }, + { 0x0014, 0x016c }, + { 0x0014, 0x016d }, + { 0x0014, 0x016e }, + { 0x0014, 0x016f }, + { 0x0014, 0x0170 }, + { 0x0014, 0x0171 }, + { 0x0014, 0x0172 }, + { 0x0014, 0x0173 }, + { 0x0014, 0x0174 }, + { 0x0014, 0x0175 }, + { 0x0014, 0x0176 }, + { 0x0014, 0x0177 }, + { 0x0014, 0x0178 }, + { 0x0014, 0x0179 }, + { 0x0014, 0x017a }, + { 0x0014, 0x017b }, + { 0x0014, 0x017c }, + { 0x0014, 0x017d }, + { 0x0014, 0x017e }, + { 0x0014, 0x017f }, + { 0x0014, 0x0180 }, + { 0x0014, 0x0181 }, + { 0x0014, 0x0182 }, + { 0x0014, 0x0183 }, + { 0x0014, 0x0184 }, + { 0x0014, 0x0185 }, + { 0x0014, 0x0186 }, + { 0x0014, 0x0187 }, + { 0x0014, 0x0188 }, + { 0x0014, 0x0189 }, + { 0x0014, 0x018a }, + { 0x0014, 0x018b }, + { 0x0014, 0x018c }, + { 0x0014, 0x018d }, + { 0x0014, 0x018e }, + { 0x0014, 0x018f }, + { 0x0014, 0x0190 }, + { 0x0014, 0x0191 }, + { 0x0014, 0x0192 }, + { 0x0014, 0x0193 }, + { 0x0014, 0x0194 }, + { 0x0014, 0x0195 }, + { 0x0014, 0x0196 }, + { 0x0014, 0x0197 }, + { 0x0014, 0x0198 }, + { 0x0014, 0x0199 }, + { 0x0014, 0x019a }, + { 0x0014, 0x019b }, + { 0x0014, 0x019c }, + { 0x0014, 0x019d }, + { 0x0014, 0x019e }, + { 0x0014, 0x019f }, + { 0x0014, 0x01a0 }, + { 0x0014, 0x01a1 }, + { 0x0014, 0x01a2 }, + { 0x0014, 0x01a3 }, + { 0x0014, 0x01a4 }, + { 0x0014, 0x01a5 }, + { 0x0014, 0x01a6 }, + { 0x0014, 0x01a7 }, + { 0x0014, 0x01a8 }, + { 0x0014, 0x01a9 }, + { 0x0014, 0x01aa }, + { 0x0014, 0x01ab }, + { 0x0014, 0x01ac }, + { 0x0014, 0x01ad }, + { 0x0014, 0x01ae }, + { 0x0014, 0x01af }, + { 0x0014, 0x01b0 }, + { 0x0014, 0x01b1 }, + { 0x0014, 0x01b2 }, + { 0x0014, 0x01b3 }, + { 0x0014, 0x01b4 }, + { 0x0014, 0x01b5 }, + { 0x0014, 0x01b6 }, + { 0x0014, 0x01b7 }, + { 0x0014, 0x01b8 }, + { 0x0014, 0x01b9 }, + { 0x0014, 0x01ba }, + { 0x0014, 0x01bb }, + { 0x0014, 0x01bc }, + { 0x0014, 0x01bd }, + { 0x0014, 0x01be }, + { 0x0014, 0x01bf }, + { 0x0014, 0x01c0 }, + { 0x0014, 0x01c1 }, + { 0x0014, 0x01c2 }, + { 0x0014, 0x01c3 }, + { 0x0014, 0x01c4 }, + { 0x0014, 0x01c5 }, + { 0x0014, 0x01c6 }, + { 0x0014, 0x01c7 }, + { 0x0013, 0x00f1 }, + { 0x0013, 0x00f2 }, + { 0x0013, 0x00f3 }, + { 0x0013, 0x00f4 }, + { 0x0013, 0x00f5 }, + { 0x0013, 0x00f6 }, + { 0x0013, 0x00f7 }, + { 0x0013, 0x00f8 }, + { 0x0013, 0x00f9 }, + { 0x0013, 0x00fa }, + { 0x0013, 0x00fb }, + { 0x0013, 0x00fc }, + { 0x0013, 0x00fd }, + { 0x0013, 0x00fe }, + { 0x0013, 0x00ff }, + { 0x0013, 0x0100 }, + { 0x0013, 0x0101 }, + { 0x0013, 0x0102 }, + { 0x0013, 0x0103 }, + { 0x0013, 0x0104 }, + { 0x0013, 0x0105 }, + { 0x0013, 0x0106 }, + { 0x0013, 0x0107 }, + { 0x0013, 0x0108 }, + { 0x0013, 0x0109 }, + { 0x0013, 0x010a }, + { 0x0013, 0x010b }, + { 0x0013, 0x010c }, + { 0x0013, 0x010d }, + { 0x0013, 0x010e }, + { 0x0013, 0x010f }, + { 0x0013, 0x0110 }, + { 0x0013, 0x0111 }, + { 0x0013, 0x0112 }, + { 0x0013, 0x0113 }, + + }; + +const uint16_t c_aauiLCLDHuffEnc18[28][2] = + { + { 0x0004, 0x0001 }, + { 0x0003, 0x0002 }, + { 0x0003, 0x0003 }, + { 0x0003, 0x0004 }, + { 0x0003, 0x0005 }, + { 0x0003, 0x0006 }, + { 0x0003, 0x0007 }, + { 0x0004, 0x0002 }, + { 0x0004, 0x0003 }, + { 0x0005, 0x0001 }, + { 0x0006, 0x0001 }, + { 0x0007, 0x0001 }, + { 0x0008, 0x0001 }, + { 0x0009, 0x0001 }, + { 0x000a, 0x0001 }, + { 0x000b, 0x0001 }, + { 0x000c, 0x0001 }, + { 0x000d, 0x0001 }, + { 0x000e, 0x0001 }, + { 0x000f, 0x0001 }, + { 0x0011, 0x0003 }, + { 0x0012, 0x0001 }, + { 0x0012, 0x0002 }, + { 0x0012, 0x0003 }, + { 0x0013, 0x0000 }, + { 0x0013, 0x0001 }, + { 0x0012, 0x0004 }, + { 0x0012, 0x0005 }, + + }; + + +const uint16_t c_aauiLCLDHuffEnc19[29][2] = + { + { 0x0004, 0x0002 }, + { 0x0003, 0x0003 }, + { 0x0003, 0x0004 }, + { 0x0003, 0x0005 }, + { 0x0003, 0x0006 }, + { 0x0003, 0x0007 }, + { 0x0004, 0x0003 }, + { 0x0004, 0x0004 }, + { 0x0004, 0x0005 }, + { 0x0005, 0x0001 }, + { 0x0005, 0x0002 }, + { 0x0005, 0x0003 }, + { 0x0006, 0x0001 }, + { 0x0007, 0x0001 }, + { 0x0008, 0x0001 }, + { 0x0009, 0x0001 }, + { 0x000a, 0x0001 }, + { 0x000b, 0x0001 }, + { 0x000c, 0x0001 }, + { 0x000d, 0x0001 }, + { 0x000e, 0x0001 }, + { 0x000f, 0x0001 }, + { 0x0010, 0x0001 }, + { 0x0012, 0x0002 }, + { 0x0013, 0x0000 }, + { 0x0013, 0x0001 }, + { 0x0013, 0x0002 }, + { 0x0013, 0x0003 }, + { 0x0012, 0x0003 }, + + }; + +const uint16_t c_aauiLCLDHuffEnc20[32][2] = + { + { 0x0004, 0x0002 }, + { 0x0003, 0x0005 }, + { 0x0003, 0x0006 }, + { 0x0003, 0x0007 }, + { 0x0004, 0x0003 }, + { 0x0004, 0x0004 }, + { 0x0004, 0x0005 }, + { 0x0004, 0x0006 }, + { 0x0004, 0x0007 }, + { 0x0004, 0x0008 }, + { 0x0004, 0x0009 }, + { 0x0005, 0x0002 }, + { 0x0005, 0x0003 }, + { 0x0006, 0x0001 }, + { 0x0006, 0x0002 }, + { 0x0006, 0x0003 }, + { 0x0007, 0x0001 }, + { 0x0008, 0x0001 }, + { 0x0009, 0x0001 }, + { 0x000a, 0x0001 }, + { 0x000b, 0x0001 }, + { 0x000c, 0x0001 }, + { 0x000d, 0x0001 }, + { 0x000e, 0x0001 }, + { 0x000f, 0x0001 }, + { 0x0010, 0x0001 }, + { 0x0011, 0x0001 }, + { 0x0014, 0x0000 }, + { 0x0014, 0x0001 }, + { 0x0013, 0x0001 }, + { 0x0013, 0x0002 }, + { 0x0013, 0x0003 }, + }; + +const uint16_t c_aauiLCLDHuffEnc21[37][2] = + { + { 0x0005, 0x0002 }, + { 0x0003, 0x0006 }, + { 0x0003, 0x0007 }, + { 0x0004, 0x0003 }, + { 0x0004, 0x0004 }, + { 0x0004, 0x0005 }, + { 0x0004, 0x0006 }, + { 0x0004, 0x0007 }, + { 0x0004, 0x0008 }, + { 0x0004, 0x0009 }, + { 0x0004, 0x000a }, + { 0x0004, 0x000b }, + { 0x0005, 0x0003 }, + { 0x0005, 0x0004 }, + { 0x0005, 0x0005 }, + { 0x0006, 0x0002 }, + { 0x0006, 0x0003 }, + { 0x0007, 0x0002 }, + { 0x0007, 0x0003 }, + { 0x0008, 0x0001 }, + { 0x0008, 0x0002 }, + { 0x0008, 0x0003 }, + { 0x0009, 0x0001 }, + { 0x000b, 0x0001 }, + { 0x000b, 0x0002 }, + { 0x000b, 0x0003 }, + { 0x000c, 0x0001 }, + { 0x000d, 0x0001 }, + { 0x000e, 0x0001 }, + { 0x000f, 0x0001 }, + { 0x0010, 0x0001 }, + { 0x0011, 0x0001 }, + { 0x0014, 0x0000 }, + { 0x0014, 0x0001 }, + { 0x0013, 0x0001 }, + { 0x0013, 0x0002 }, + { 0x0013, 0x0003 }, + + }; + +const uint16_t c_aauiLCLDHuffEnc22[39][2] = + { + { 0x0005, 0x0002 }, + { 0x0004, 0x0004 }, + { 0x0004, 0x0005 }, + { 0x0004, 0x0006 }, + { 0x0004, 0x0007 }, + { 0x0004, 0x0008 }, + { 0x0004, 0x0009 }, + { 0x0004, 0x000a }, + { 0x0004, 0x000b }, + { 0x0004, 0x000c }, + { 0x0004, 0x000d }, + { 0x0004, 0x000e }, + { 0x0004, 0x000f }, + { 0x0005, 0x0003 }, + { 0x0005, 0x0004 }, + { 0x0005, 0x0005 }, + { 0x0005, 0x0006 }, + { 0x0005, 0x0007 }, + { 0x0006, 0x0002 }, + { 0x0006, 0x0003 }, + { 0x0007, 0x0002 }, + { 0x0007, 0x0003 }, + { 0x0008, 0x0002 }, + { 0x0008, 0x0003 }, + { 0x0009, 0x0002 }, + { 0x0009, 0x0003 }, + { 0x000a, 0x0001 }, + { 0x000a, 0x0002 }, + { 0x000a, 0x0003 }, + { 0x000c, 0x0001 }, + { 0x000c, 0x0002 }, + { 0x000c, 0x0003 }, + { 0x000e, 0x0001 }, + { 0x000e, 0x0002 }, + { 0x000f, 0x0001 }, + { 0x000e, 0x0003 }, + { 0x0011, 0x0000 }, + { 0x0010, 0x0001 }, + { 0x0011, 0x0001 }, + + }; + +const uint16_t c_aauiLCLDHuffEnc23[46][2] = + { + { 0x0005, 0x0003 }, + { 0x0004, 0x0006 }, + { 0x0004, 0x0007 }, + { 0x0004, 0x0008 }, + { 0x0004, 0x0009 }, + { 0x0004, 0x000a }, + { 0x0004, 0x000b }, + { 0x0004, 0x000c }, + { 0x0004, 0x000d }, + { 0x0004, 0x000e }, + { 0x0004, 0x000f }, + { 0x0005, 0x0004 }, + { 0x0005, 0x0005 }, + { 0x0005, 0x0006 }, + { 0x0005, 0x0007 }, + { 0x0005, 0x0008 }, + { 0x0005, 0x0009 }, + { 0x0005, 0x000a }, + { 0x0005, 0x000b }, + { 0x0006, 0x0003 }, + { 0x0006, 0x0004 }, + { 0x0006, 0x0005 }, + { 0x0007, 0x0002 }, + { 0x0007, 0x0003 }, + { 0x0007, 0x0004 }, + { 0x0007, 0x0005 }, + { 0x0008, 0x0002 }, + { 0x0008, 0x0003 }, + { 0x0009, 0x0002 }, + { 0x0009, 0x0003 }, + { 0x000a, 0x0002 }, + { 0x000a, 0x0003 }, + { 0x000b, 0x0002 }, + { 0x000b, 0x0003 }, + { 0x000c, 0x0002 }, + { 0x000c, 0x0003 }, + { 0x000d, 0x0002 }, + { 0x000d, 0x0003 }, + { 0x000e, 0x0001 }, + { 0x000e, 0x0002 }, + { 0x000e, 0x0003 }, + { 0x000f, 0x0001 }, + { 0x0010, 0x0001 }, + { 0x0012, 0x0000 }, + { 0x0012, 0x0001 }, + { 0x0011, 0x0001 }, + + }; + +const uint16_t c_aauiLCLDHuffEnc24[55][2] = + { + { 0x0005, 0x0004 }, + { 0x0004, 0x0009 }, + { 0x0004, 0x000a }, + { 0x0004, 0x000b }, + { 0x0004, 0x000c }, + { 0x0004, 0x000d }, + { 0x0004, 0x000e }, + { 0x0004, 0x000f }, + { 0x0005, 0x0005 }, + { 0x0005, 0x0006 }, + { 0x0005, 0x0007 }, + { 0x0005, 0x0008 }, + { 0x0005, 0x0009 }, + { 0x0005, 0x000a }, + { 0x0005, 0x000b }, + { 0x0005, 0x000c }, + { 0x0005, 0x000d }, + { 0x0005, 0x000e }, + { 0x0005, 0x000f }, + { 0x0005, 0x0010 }, + { 0x0005, 0x0011 }, + { 0x0006, 0x0003 }, + { 0x0006, 0x0004 }, + { 0x0006, 0x0005 }, + { 0x0006, 0x0006 }, + { 0x0006, 0x0007 }, + { 0x0007, 0x0003 }, + { 0x0007, 0x0004 }, + { 0x0007, 0x0005 }, + { 0x0008, 0x0003 }, + { 0x0008, 0x0004 }, + { 0x0008, 0x0005 }, + { 0x0009, 0x0002 }, + { 0x0009, 0x0003 }, + { 0x0009, 0x0004 }, + { 0x0009, 0x0005 }, + { 0x000a, 0x0002 }, + { 0x000a, 0x0003 }, + { 0x000b, 0x0002 }, + { 0x000b, 0x0003 }, + { 0x000c, 0x0003 }, + { 0x000d, 0x0002 }, + { 0x000d, 0x0003 }, + { 0x000d, 0x0004 }, + { 0x000d, 0x0005 }, + { 0x000e, 0x0002 }, + { 0x000e, 0x0003 }, + { 0x000f, 0x0001 }, + { 0x000f, 0x0002 }, + { 0x000f, 0x0003 }, + { 0x0010, 0x0001 }, + { 0x0011, 0x0001 }, + { 0x0013, 0x0000 }, + { 0x0012, 0x0001 }, + { 0x0013, 0x0001 }, + + }; + +const uint16_t c_aauiLCLDHuffEnc25[65][2] = + { + { 0x0005, 0x0005 }, + { 0x0004, 0x000c }, + { 0x0004, 0x000d }, + { 0x0004, 0x000e }, + { 0x0005, 0x0006 }, + { 0x0004, 0x000f }, + { 0x0005, 0x0007 }, + { 0x0005, 0x0008 }, + { 0x0005, 0x0009 }, + { 0x0005, 0x000a }, + { 0x0005, 0x000b }, + { 0x0005, 0x000c }, + { 0x0005, 0x000d }, + { 0x0005, 0x000e }, + { 0x0005, 0x000f }, + { 0x0005, 0x0010 }, + { 0x0005, 0x0011 }, + { 0x0005, 0x0012 }, + { 0x0005, 0x0013 }, + { 0x0005, 0x0014 }, + { 0x0005, 0x0015 }, + { 0x0005, 0x0016 }, + { 0x0005, 0x0017 }, + { 0x0006, 0x0004 }, + { 0x0006, 0x0005 }, + { 0x0006, 0x0006 }, + { 0x0006, 0x0007 }, + { 0x0006, 0x0008 }, + { 0x0006, 0x0009 }, + { 0x0007, 0x0003 }, + { 0x0007, 0x0004 }, + { 0x0007, 0x0005 }, + { 0x0007, 0x0006 }, + { 0x0007, 0x0007 }, + { 0x0008, 0x0003 }, + { 0x0008, 0x0004 }, + { 0x0008, 0x0005 }, + { 0x0009, 0x0003 }, + { 0x0009, 0x0004 }, + { 0x0009, 0x0005 }, + { 0x000a, 0x0003 }, + { 0x000a, 0x0004 }, + { 0x000a, 0x0005 }, + { 0x000b, 0x0003 }, + { 0x000b, 0x0004 }, + { 0x000b, 0x0005 }, + { 0x000c, 0x0002 }, + { 0x000c, 0x0003 }, + { 0x000c, 0x0004 }, + { 0x000c, 0x0005 }, + { 0x000d, 0x0003 }, + { 0x000e, 0x0003 }, + { 0x000e, 0x0004 }, + { 0x000f, 0x0003 }, + { 0x000e, 0x0005 }, + { 0x000f, 0x0004 }, + { 0x0010, 0x0001 }, + { 0x000f, 0x0005 }, + { 0x0010, 0x0002 }, + { 0x0010, 0x0003 }, + { 0x0010, 0x0004 }, + { 0x0010, 0x0005 }, + { 0x0011, 0x0001 }, + { 0x0012, 0x0000 }, + { 0x0012, 0x0001 }, + + }; + +const uint16_t c_aauiLCLDHuffEnc26[77][2] = + { + { 0x0006, 0x0004 }, + { 0x0005, 0x0007 }, + { 0x0005, 0x0008 }, + { 0x0005, 0x0009 }, + { 0x0005, 0x000a }, + { 0x0005, 0x000b }, + { 0x0005, 0x000c }, + { 0x0005, 0x000d }, + { 0x0005, 0x000e }, + { 0x0005, 0x000f }, + { 0x0005, 0x0010 }, + { 0x0005, 0x0011 }, + { 0x0005, 0x0012 }, + { 0x0005, 0x0013 }, + { 0x0005, 0x0014 }, + { 0x0005, 0x0015 }, + { 0x0005, 0x0016 }, + { 0x0005, 0x0017 }, + { 0x0005, 0x0018 }, + { 0x0005, 0x0019 }, + { 0x0005, 0x001a }, + { 0x0005, 0x001b }, + { 0x0005, 0x001c }, + { 0x0005, 0x001d }, + { 0x0005, 0x001e }, + { 0x0005, 0x001f }, + { 0x0006, 0x0005 }, + { 0x0006, 0x0006 }, + { 0x0006, 0x0007 }, + { 0x0006, 0x0008 }, + { 0x0006, 0x0009 }, + { 0x0006, 0x000a }, + { 0x0006, 0x000b }, + { 0x0006, 0x000c }, + { 0x0006, 0x000d }, + { 0x0007, 0x0004 }, + { 0x0007, 0x0005 }, + { 0x0007, 0x0006 }, + { 0x0007, 0x0007 }, + { 0x0008, 0x0004 }, + { 0x0008, 0x0005 }, + { 0x0008, 0x0006 }, + { 0x0008, 0x0007 }, + { 0x0009, 0x0003 }, + { 0x0009, 0x0004 }, + { 0x0009, 0x0005 }, + { 0x0009, 0x0006 }, + { 0x0009, 0x0007 }, + { 0x000a, 0x0003 }, + { 0x000a, 0x0004 }, + { 0x000a, 0x0005 }, + { 0x000b, 0x0004 }, + { 0x000b, 0x0005 }, + { 0x000c, 0x0003 }, + { 0x000c, 0x0004 }, + { 0x000c, 0x0005 }, + { 0x000c, 0x0006 }, + { 0x000c, 0x0007 }, + { 0x000d, 0x0003 }, + { 0x000d, 0x0004 }, + { 0x000e, 0x0002 }, + { 0x000d, 0x0005 }, + { 0x000e, 0x0003 }, + { 0x000e, 0x0004 }, + { 0x000f, 0x0003 }, + { 0x000e, 0x0005 }, + { 0x0010, 0x0002 }, + { 0x0010, 0x0003 }, + { 0x0010, 0x0004 }, + { 0x0011, 0x0002 }, + { 0x0012, 0x0001 }, + { 0x0010, 0x0005 }, + { 0x0012, 0x0002 }, + { 0x0011, 0x0003 }, + { 0x0012, 0x0003 }, + { 0x0013, 0x0000 }, + { 0x0013, 0x0001 }, + + }; + + +const uint16_t c_aauiLCLDHuffEnc27[91][2] = + { + { 0x0006, 0x0006 }, + { 0x0005, 0x000b }, + { 0x0005, 0x000c }, + { 0x0005, 0x000d }, + { 0x0005, 0x000e }, + { 0x0005, 0x000f }, + { 0x0005, 0x0010 }, + { 0x0005, 0x0011 }, + { 0x0005, 0x0012 }, + { 0x0005, 0x0013 }, + { 0x0005, 0x0014 }, + { 0x0005, 0x0015 }, + { 0x0005, 0x0016 }, + { 0x0005, 0x0017 }, + { 0x0005, 0x0018 }, + { 0x0005, 0x0019 }, + { 0x0005, 0x001a }, + { 0x0005, 0x001b }, + { 0x0005, 0x001c }, + { 0x0005, 0x001d }, + { 0x0005, 0x001e }, + { 0x0005, 0x001f }, + { 0x0006, 0x0007 }, + { 0x0006, 0x0008 }, + { 0x0006, 0x0009 }, + { 0x0006, 0x000a }, + { 0x0006, 0x000b }, + { 0x0006, 0x000c }, + { 0x0006, 0x000d }, + { 0x0006, 0x000e }, + { 0x0006, 0x000f }, + { 0x0006, 0x0010 }, + { 0x0006, 0x0011 }, + { 0x0006, 0x0012 }, + { 0x0006, 0x0013 }, + { 0x0006, 0x0014 }, + { 0x0006, 0x0015 }, + { 0x0007, 0x0005 }, + { 0x0007, 0x0006 }, + { 0x0007, 0x0007 }, + { 0x0007, 0x0008 }, + { 0x0007, 0x0009 }, + { 0x0007, 0x000a }, + { 0x0007, 0x000b }, + { 0x0008, 0x0004 }, + { 0x0008, 0x0005 }, + { 0x0008, 0x0006 }, + { 0x0008, 0x0007 }, + { 0x0008, 0x0008 }, + { 0x0008, 0x0009 }, + { 0x0009, 0x0004 }, + { 0x0009, 0x0005 }, + { 0x0009, 0x0006 }, + { 0x0009, 0x0007 }, + { 0x000a, 0x0004 }, + { 0x000a, 0x0005 }, + { 0x000a, 0x0006 }, + { 0x000a, 0x0007 }, + { 0x000b, 0x0004 }, + { 0x000b, 0x0005 }, + { 0x000b, 0x0006 }, + { 0x000b, 0x0007 }, + { 0x000c, 0x0004 }, + { 0x000c, 0x0005 }, + { 0x000c, 0x0006 }, + { 0x000c, 0x0007 }, + { 0x000d, 0x0004 }, + { 0x000d, 0x0005 }, + { 0x000d, 0x0006 }, + { 0x000d, 0x0007 }, + { 0x000e, 0x0003 }, + { 0x000e, 0x0004 }, + { 0x000e, 0x0005 }, + { 0x000e, 0x0006 }, + { 0x000e, 0x0007 }, + { 0x000f, 0x0003 }, + { 0x000f, 0x0004 }, + { 0x0010, 0x0003 }, + { 0x000f, 0x0005 }, + { 0x0012, 0x0000 }, + { 0x0010, 0x0004 }, + { 0x0010, 0x0005 }, + { 0x0012, 0x0001 }, + { 0x0012, 0x0002 }, + { 0x0011, 0x0004 }, + { 0x0011, 0x0005 }, + { 0x0012, 0x0003 }, + { 0x0012, 0x0004 }, + { 0x0012, 0x0005 }, + { 0x0012, 0x0006 }, + { 0x0012, 0x0007 }, + + }; + +const uint16_t c_aauiLCLDHuffEnc28[109][2] = + { + { 0x0006, 0x0008 }, + { 0x0005, 0x0010 }, + { 0x0005, 0x0011 }, + { 0x0005, 0x0012 }, + { 0x0005, 0x0013 }, + { 0x0005, 0x0014 }, + { 0x0005, 0x0015 }, + { 0x0005, 0x0016 }, + { 0x0005, 0x0017 }, + { 0x0005, 0x0018 }, + { 0x0005, 0x0019 }, + { 0x0005, 0x001a }, + { 0x0005, 0x001b }, + { 0x0005, 0x001c }, + { 0x0005, 0x001d }, + { 0x0005, 0x001e }, + { 0x0006, 0x0009 }, + { 0x0005, 0x001f }, + { 0x0006, 0x000a }, + { 0x0006, 0x000b }, + { 0x0006, 0x000c }, + { 0x0006, 0x000d }, + { 0x0006, 0x000e }, + { 0x0006, 0x000f }, + { 0x0006, 0x0010 }, + { 0x0006, 0x0011 }, + { 0x0006, 0x0012 }, + { 0x0006, 0x0013 }, + { 0x0006, 0x0014 }, + { 0x0006, 0x0015 }, + { 0x0006, 0x0016 }, + { 0x0006, 0x0017 }, + { 0x0006, 0x0018 }, + { 0x0006, 0x0019 }, + { 0x0006, 0x001a }, + { 0x0006, 0x001b }, + { 0x0006, 0x001c }, + { 0x0006, 0x001d }, + { 0x0006, 0x001e }, + { 0x0006, 0x001f }, + { 0x0007, 0x0006 }, + { 0x0007, 0x0007 }, + { 0x0007, 0x0008 }, + { 0x0007, 0x0009 }, + { 0x0007, 0x000a }, + { 0x0007, 0x000b }, + { 0x0007, 0x000c }, + { 0x0007, 0x000d }, + { 0x0007, 0x000e }, + { 0x0007, 0x000f }, + { 0x0008, 0x0005 }, + { 0x0008, 0x0006 }, + { 0x0008, 0x0007 }, + { 0x0008, 0x0008 }, + { 0x0008, 0x0009 }, + { 0x0008, 0x000a }, + { 0x0008, 0x000b }, + { 0x0009, 0x0004 }, + { 0x0009, 0x0005 }, + { 0x0009, 0x0006 }, + { 0x0009, 0x0007 }, + { 0x0009, 0x0008 }, + { 0x0009, 0x0009 }, + { 0x000a, 0x0005 }, + { 0x000a, 0x0006 }, + { 0x000a, 0x0007 }, + { 0x000b, 0x0005 }, + { 0x000b, 0x0006 }, + { 0x000b, 0x0007 }, + { 0x000b, 0x0008 }, + { 0x000b, 0x0009 }, + { 0x000c, 0x0004 }, + { 0x000c, 0x0005 }, + { 0x000c, 0x0006 }, + { 0x000c, 0x0007 }, + { 0x000c, 0x0008 }, + { 0x000c, 0x0009 }, + { 0x000d, 0x0004 }, + { 0x000d, 0x0005 }, + { 0x000d, 0x0006 }, + { 0x000d, 0x0007 }, + { 0x000e, 0x0004 }, + { 0x000e, 0x0005 }, + { 0x000e, 0x0006 }, + { 0x000e, 0x0007 }, + { 0x0010, 0x0004 }, + { 0x000f, 0x0005 }, + { 0x0010, 0x0005 }, + { 0x000f, 0x0006 }, + { 0x000f, 0x0007 }, + { 0x0010, 0x0006 }, + { 0x0011, 0x0006 }, + { 0x0010, 0x0007 }, + { 0x0013, 0x0000 }, + { 0x0010, 0x0008 }, + { 0x0010, 0x0009 }, + { 0x0013, 0x0001 }, + { 0x0011, 0x0007 }, + { 0x0012, 0x0001 }, + { 0x0012, 0x0002 }, + { 0x0012, 0x0003 }, + { 0x0012, 0x0004 }, + { 0x0012, 0x0005 }, + { 0x0012, 0x0006 }, + { 0x0012, 0x0007 }, + { 0x0012, 0x0008 }, + { 0x0012, 0x0009 }, + { 0x0012, 0x000a }, + { 0x0012, 0x000b }, + + }; + +const uint16_t c_aauiLCLDHuffEnc29[129][2] = + { + { 0x0006, 0x0009 }, + { 0x0005, 0x0019 }, + { 0x0006, 0x000a }, + { 0x0005, 0x001a }, + { 0x0005, 0x001b }, + { 0x0005, 0x001c }, + { 0x0006, 0x000b }, + { 0x0005, 0x001d }, + { 0x0005, 0x001e }, + { 0x0006, 0x000c }, + { 0x0006, 0x000d }, + { 0x0005, 0x001f }, + { 0x0006, 0x000e }, + { 0x0006, 0x000f }, + { 0x0006, 0x0010 }, + { 0x0006, 0x0011 }, + { 0x0006, 0x0012 }, + { 0x0006, 0x0013 }, + { 0x0006, 0x0014 }, + { 0x0006, 0x0015 }, + { 0x0006, 0x0016 }, + { 0x0006, 0x0017 }, + { 0x0006, 0x0018 }, + { 0x0006, 0x0019 }, + { 0x0006, 0x001a }, + { 0x0006, 0x001b }, + { 0x0006, 0x001c }, + { 0x0006, 0x001d }, + { 0x0006, 0x001e }, + { 0x0006, 0x001f }, + { 0x0006, 0x0020 }, + { 0x0006, 0x0021 }, + { 0x0006, 0x0022 }, + { 0x0006, 0x0023 }, + { 0x0006, 0x0024 }, + { 0x0006, 0x0025 }, + { 0x0006, 0x0026 }, + { 0x0006, 0x0027 }, + { 0x0006, 0x0028 }, + { 0x0006, 0x0029 }, + { 0x0006, 0x002a }, + { 0x0006, 0x002b }, + { 0x0006, 0x002c }, + { 0x0006, 0x002d }, + { 0x0006, 0x002e }, + { 0x0006, 0x002f }, + { 0x0006, 0x0030 }, + { 0x0006, 0x0031 }, + { 0x0007, 0x0007 }, + { 0x0007, 0x0008 }, + { 0x0007, 0x0009 }, + { 0x0007, 0x000a }, + { 0x0007, 0x000b }, + { 0x0007, 0x000c }, + { 0x0007, 0x000d }, + { 0x0007, 0x000e }, + { 0x0007, 0x000f }, + { 0x0007, 0x0010 }, + { 0x0007, 0x0011 }, + { 0x0008, 0x0006 }, + { 0x0008, 0x0007 }, + { 0x0008, 0x0008 }, + { 0x0008, 0x0009 }, + { 0x0008, 0x000a }, + { 0x0008, 0x000b }, + { 0x0008, 0x000c }, + { 0x0008, 0x000d }, + { 0x0009, 0x0006 }, + { 0x0009, 0x0007 }, + { 0x0009, 0x0008 }, + { 0x0009, 0x0009 }, + { 0x0009, 0x000a }, + { 0x0009, 0x000b }, + { 0x000a, 0x0005 }, + { 0x000a, 0x0006 }, + { 0x000a, 0x0007 }, + { 0x000a, 0x0008 }, + { 0x000a, 0x0009 }, + { 0x000a, 0x000a }, + { 0x000a, 0x000b }, + { 0x000b, 0x0006 }, + { 0x000b, 0x0007 }, + { 0x000b, 0x0008 }, + { 0x000b, 0x0009 }, + { 0x000c, 0x0006 }, + { 0x000c, 0x0007 }, + { 0x000c, 0x0008 }, + { 0x000c, 0x0009 }, + { 0x000c, 0x000a }, + { 0x000c, 0x000b }, + { 0x000d, 0x0005 }, + { 0x000d, 0x0006 }, + { 0x000d, 0x0007 }, + { 0x000d, 0x0008 }, + { 0x000d, 0x0009 }, + { 0x000d, 0x000a }, + { 0x000d, 0x000b }, + { 0x000e, 0x0006 }, + { 0x000e, 0x0007 }, + { 0x000e, 0x0008 }, + { 0x000e, 0x0009 }, + { 0x000f, 0x0004 }, + { 0x000f, 0x0005 }, + { 0x000f, 0x0006 }, + { 0x000f, 0x0007 }, + { 0x0011, 0x0007 }, + { 0x000f, 0x0008 }, + { 0x0012, 0x0000 }, + { 0x000f, 0x0009 }, + { 0x0010, 0x0005 }, + { 0x000f, 0x000a }, + { 0x000f, 0x000b }, + { 0x0012, 0x0001 }, + { 0x0010, 0x0006 }, + { 0x0010, 0x0007 }, + { 0x0012, 0x0002 }, + { 0x0012, 0x0003 }, + { 0x0012, 0x0004 }, + { 0x0012, 0x0005 }, + { 0x0012, 0x0006 }, + { 0x0012, 0x0007 }, + { 0x0012, 0x0008 }, + { 0x0011, 0x0008 }, + { 0x0012, 0x0009 }, + { 0x0012, 0x000a }, + { 0x0012, 0x000b }, + { 0x0012, 0x000c }, + { 0x0012, 0x000d }, + { 0x0011, 0x0009 }, + + }; + +const uint16_t c_aauiLCLDHuffEnc30[153][2] = + { + { 0x0007, 0x0009 }, + { 0x0006, 0x000e }, + { 0x0006, 0x000f }, + { 0x0006, 0x0010 }, + { 0x0006, 0x0011 }, + { 0x0006, 0x0012 }, + { 0x0006, 0x0013 }, + { 0x0006, 0x0014 }, + { 0x0006, 0x0015 }, + { 0x0006, 0x0016 }, + { 0x0006, 0x0017 }, + { 0x0006, 0x0018 }, + { 0x0006, 0x0019 }, + { 0x0006, 0x001a }, + { 0x0006, 0x001b }, + { 0x0006, 0x001c }, + { 0x0006, 0x001d }, + { 0x0006, 0x001e }, + { 0x0006, 0x001f }, + { 0x0006, 0x0020 }, + { 0x0006, 0x0021 }, + { 0x0006, 0x0022 }, + { 0x0006, 0x0023 }, + { 0x0006, 0x0024 }, + { 0x0006, 0x0025 }, + { 0x0006, 0x0026 }, + { 0x0006, 0x0027 }, + { 0x0006, 0x0028 }, + { 0x0006, 0x0029 }, + { 0x0006, 0x002a }, + { 0x0006, 0x002b }, + { 0x0006, 0x002c }, + { 0x0006, 0x002d }, + { 0x0006, 0x002e }, + { 0x0006, 0x002f }, + { 0x0006, 0x0030 }, + { 0x0006, 0x0031 }, + { 0x0006, 0x0032 }, + { 0x0006, 0x0033 }, + { 0x0006, 0x0034 }, + { 0x0006, 0x0035 }, + { 0x0006, 0x0036 }, + { 0x0006, 0x0037 }, + { 0x0006, 0x0038 }, + { 0x0006, 0x0039 }, + { 0x0006, 0x003a }, + { 0x0006, 0x003b }, + { 0x0006, 0x003c }, + { 0x0006, 0x003d }, + { 0x0006, 0x003e }, + { 0x0006, 0x003f }, + { 0x0007, 0x000a }, + { 0x0007, 0x000b }, + { 0x0007, 0x000c }, + { 0x0007, 0x000d }, + { 0x0007, 0x000e }, + { 0x0007, 0x000f }, + { 0x0007, 0x0010 }, + { 0x0007, 0x0011 }, + { 0x0007, 0x0012 }, + { 0x0007, 0x0013 }, + { 0x0007, 0x0014 }, + { 0x0007, 0x0015 }, + { 0x0007, 0x0016 }, + { 0x0007, 0x0017 }, + { 0x0007, 0x0018 }, + { 0x0007, 0x0019 }, + { 0x0007, 0x001a }, + { 0x0007, 0x001b }, + { 0x0008, 0x0008 }, + { 0x0008, 0x0009 }, + { 0x0008, 0x000a }, + { 0x0008, 0x000b }, + { 0x0008, 0x000c }, + { 0x0008, 0x000d }, + { 0x0008, 0x000e }, + { 0x0008, 0x000f }, + { 0x0008, 0x0010 }, + { 0x0008, 0x0011 }, + { 0x0009, 0x0007 }, + { 0x0009, 0x0008 }, + { 0x0009, 0x0009 }, + { 0x0009, 0x000a }, + { 0x0009, 0x000b }, + { 0x0009, 0x000c }, + { 0x0009, 0x000d }, + { 0x0009, 0x000e }, + { 0x000a, 0x0008 }, + { 0x0009, 0x000f }, + { 0x000a, 0x0009 }, + { 0x000a, 0x000a }, + { 0x000a, 0x000b }, + { 0x000a, 0x000c }, + { 0x000a, 0x000d }, + { 0x000b, 0x0007 }, + { 0x000b, 0x0008 }, + { 0x000b, 0x0009 }, + { 0x000b, 0x000a }, + { 0x000b, 0x000b }, + { 0x000b, 0x000c }, + { 0x000b, 0x000d }, + { 0x000c, 0x0008 }, + { 0x000b, 0x000e }, + { 0x000b, 0x000f }, + { 0x000c, 0x0009 }, + { 0x000c, 0x000a }, + { 0x000d, 0x0008 }, + { 0x000c, 0x000b }, + { 0x000c, 0x000c }, + { 0x000d, 0x0009 }, + { 0x000c, 0x000d }, + { 0x000d, 0x000a }, + { 0x000d, 0x000b }, + { 0x000d, 0x000c }, + { 0x000d, 0x000d }, + { 0x000e, 0x0008 }, + { 0x000d, 0x000e }, + { 0x000d, 0x000f }, + { 0x000e, 0x0009 }, + { 0x000e, 0x000a }, + { 0x000e, 0x000b }, + { 0x000e, 0x000c }, + { 0x000f, 0x0006 }, + { 0x000f, 0x0007 }, + { 0x000f, 0x0008 }, + { 0x0010, 0x0006 }, + { 0x000e, 0x000d }, + { 0x000e, 0x000e }, + { 0x000e, 0x000f }, + { 0x0010, 0x0007 }, + { 0x000f, 0x0009 }, + { 0x0010, 0x0008 }, + { 0x000f, 0x000a }, + { 0x000f, 0x000b }, + { 0x000f, 0x000c }, + { 0x000f, 0x000d }, + { 0x0010, 0x0009 }, + { 0x0011, 0x0000 }, + { 0x0011, 0x0001 }, + { 0x0011, 0x0002 }, + { 0x000f, 0x000e }, + { 0x0010, 0x000a }, + { 0x0011, 0x0003 }, + { 0x0011, 0x0004 }, + { 0x0011, 0x0005 }, + { 0x000f, 0x000f }, + { 0x0011, 0x0006 }, + { 0x0011, 0x0007 }, + { 0x0011, 0x0008 }, + { 0x0011, 0x0009 }, + { 0x0011, 0x000a }, + { 0x0011, 0x000b }, + { 0x0010, 0x000b }, + + }; + +const uint16_t c_aauiLCLDHuffEnc31[181][2] = + { + { 0x0007, 0x000b }, + { 0x0006, 0x0015 }, + { 0x0006, 0x0016 }, + { 0x0006, 0x0017 }, + { 0x0006, 0x0018 }, + { 0x0006, 0x0019 }, + { 0x0006, 0x001a }, + { 0x0006, 0x001b }, + { 0x0006, 0x001c }, + { 0x0006, 0x001d }, + { 0x0006, 0x001e }, + { 0x0006, 0x001f }, + { 0x0006, 0x0020 }, + { 0x0006, 0x0021 }, + { 0x0006, 0x0022 }, + { 0x0006, 0x0023 }, + { 0x0006, 0x0024 }, + { 0x0006, 0x0025 }, + { 0x0006, 0x0026 }, + { 0x0006, 0x0027 }, + { 0x0006, 0x0028 }, + { 0x0006, 0x0029 }, + { 0x0006, 0x002a }, + { 0x0006, 0x002b }, + { 0x0006, 0x002c }, + { 0x0006, 0x002d }, + { 0x0006, 0x002e }, + { 0x0006, 0x002f }, + { 0x0006, 0x0030 }, + { 0x0006, 0x0031 }, + { 0x0006, 0x0032 }, + { 0x0006, 0x0033 }, + { 0x0006, 0x0034 }, + { 0x0006, 0x0035 }, + { 0x0006, 0x0036 }, + { 0x0006, 0x0037 }, + { 0x0006, 0x0038 }, + { 0x0006, 0x0039 }, + { 0x0006, 0x003a }, + { 0x0006, 0x003b }, + { 0x0006, 0x003c }, + { 0x0006, 0x003d }, + { 0x0006, 0x003e }, + { 0x0007, 0x000c }, + { 0x0006, 0x003f }, + { 0x0007, 0x000d }, + { 0x0007, 0x000e }, + { 0x0007, 0x000f }, + { 0x0007, 0x0010 }, + { 0x0007, 0x0011 }, + { 0x0007, 0x0012 }, + { 0x0007, 0x0013 }, + { 0x0007, 0x0014 }, + { 0x0007, 0x0015 }, + { 0x0007, 0x0016 }, + { 0x0007, 0x0017 }, + { 0x0007, 0x0018 }, + { 0x0007, 0x0019 }, + { 0x0007, 0x001a }, + { 0x0007, 0x001b }, + { 0x0007, 0x001c }, + { 0x0007, 0x001d }, + { 0x0007, 0x001e }, + { 0x0007, 0x001f }, + { 0x0007, 0x0020 }, + { 0x0007, 0x0021 }, + { 0x0007, 0x0022 }, + { 0x0007, 0x0023 }, + { 0x0007, 0x0024 }, + { 0x0007, 0x0025 }, + { 0x0007, 0x0026 }, + { 0x0007, 0x0027 }, + { 0x0007, 0x0028 }, + { 0x0007, 0x0029 }, + { 0x0008, 0x0009 }, + { 0x0008, 0x000a }, + { 0x0008, 0x000b }, + { 0x0008, 0x000c }, + { 0x0008, 0x000d }, + { 0x0008, 0x000e }, + { 0x0008, 0x000f }, + { 0x0008, 0x0010 }, + { 0x0008, 0x0011 }, + { 0x0008, 0x0012 }, + { 0x0008, 0x0013 }, + { 0x0008, 0x0014 }, + { 0x0008, 0x0015 }, + { 0x0009, 0x0008 }, + { 0x0009, 0x0009 }, + { 0x0009, 0x000a }, + { 0x0009, 0x000b }, + { 0x0009, 0x000c }, + { 0x0009, 0x000d }, + { 0x0009, 0x000e }, + { 0x0009, 0x000f }, + { 0x0009, 0x0010 }, + { 0x0009, 0x0011 }, + { 0x000a, 0x0008 }, + { 0x000a, 0x0009 }, + { 0x000a, 0x000a }, + { 0x000a, 0x000b }, + { 0x000a, 0x000c }, + { 0x000a, 0x000d }, + { 0x000a, 0x000e }, + { 0x000a, 0x000f }, + { 0x000b, 0x0008 }, + { 0x000b, 0x0009 }, + { 0x000b, 0x000a }, + { 0x000b, 0x000b }, + { 0x000b, 0x000c }, + { 0x000b, 0x000d }, + { 0x000b, 0x000e }, + { 0x000c, 0x0008 }, + { 0x000c, 0x0009 }, + { 0x000b, 0x000f }, + { 0x000c, 0x000a }, + { 0x000c, 0x000b }, + { 0x000c, 0x000c }, + { 0x000c, 0x000d }, + { 0x000d, 0x0008 }, + { 0x000c, 0x000e }, + { 0x000d, 0x0009 }, + { 0x000d, 0x000a }, + { 0x000c, 0x000f }, + { 0x000d, 0x000b }, + { 0x000d, 0x000c }, + { 0x000d, 0x000d }, + { 0x000d, 0x000e }, + { 0x000d, 0x000f }, + { 0x000e, 0x0008 }, + { 0x000e, 0x0009 }, + { 0x000e, 0x000a }, + { 0x000e, 0x000b }, + { 0x000e, 0x000c }, + { 0x000e, 0x000d }, + { 0x000e, 0x000e }, + { 0x000e, 0x000f }, + { 0x000f, 0x0009 }, + { 0x000f, 0x000a }, + { 0x000f, 0x000b }, + { 0x000f, 0x000c }, + { 0x0010, 0x0009 }, + { 0x000f, 0x000d }, + { 0x000f, 0x000e }, + { 0x0010, 0x000a }, + { 0x0010, 0x000b }, + { 0x0010, 0x000c }, + { 0x0010, 0x000d }, + { 0x0011, 0x000a }, + { 0x0010, 0x000e }, + { 0x000f, 0x000f }, + { 0x0010, 0x000f }, + { 0x0012, 0x0000 }, + { 0x0012, 0x0001 }, + { 0x0011, 0x000b }, + { 0x0011, 0x000c }, + { 0x0010, 0x0010 }, + { 0x0012, 0x0002 }, + { 0x0012, 0x0003 }, + { 0x0011, 0x000d }, + { 0x0011, 0x000e }, + { 0x0011, 0x000f }, + { 0x0011, 0x0010 }, + { 0x0011, 0x0011 }, + { 0x0010, 0x0011 }, + { 0x0012, 0x0004 }, + { 0x0012, 0x0005 }, + { 0x0012, 0x0006 }, + { 0x0012, 0x0007 }, + { 0x0012, 0x0008 }, + { 0x0012, 0x0009 }, + { 0x0012, 0x000a }, + { 0x0012, 0x000b }, + { 0x0012, 0x000c }, + { 0x0012, 0x000d }, + { 0x0012, 0x000e }, + { 0x0012, 0x000f }, + { 0x0012, 0x0010 }, + { 0x0012, 0x0011 }, + { 0x0012, 0x0012 }, + { 0x0012, 0x0013 }, + + }; + +const uint16_t c_aauiLCLDHuffEnc33[16][2] = + { + { 0x0001, 0x0001 }, + { 0x0003, 0x0001 }, + { 0x0008, 0x0000 }, + { 0x0008, 0x0001 }, + { 0x0002, 0x0001 }, + { 0x0004, 0x0001 }, + { 0x0008, 0x0002 }, + { 0x0008, 0x0003 }, + { 0x0008, 0x0004 }, + { 0x0008, 0x0005 }, + { 0x0008, 0x0006 }, + { 0x0008, 0x0007 }, + { 0x0007, 0x0004 }, + { 0x0007, 0x0005 }, + { 0x0007, 0x0006 }, + { 0x0007, 0x0007 }, + }; + +const uint16_t c_aauiLCLDHuffEnc34[16][2] = + { + { 0x0001, 0x0001 }, + { 0x0003, 0x0001 }, + { 0x0008, 0x0000 }, + { 0x0008, 0x0001 }, + { 0x0002, 0x0001 }, + { 0x0004, 0x0001 }, + { 0x0008, 0x0002 }, + { 0x0008, 0x0003 }, + { 0x0008, 0x0004 }, + { 0x0008, 0x0005 }, + { 0x0008, 0x0006 }, + { 0x0008, 0x0007 }, + { 0x0007, 0x0004 }, + { 0x0007, 0x0005 }, + { 0x0007, 0x0006 }, + { 0x0007, 0x0007 }, + }; + +const uint16_t c_aauiLCLDHuffEnc35[25][2] = + { + { 0x0001, 0x0001 }, + { 0x0003, 0x0001 }, + { 0x0007, 0x0006 }, + { 0x0009, 0x0000 }, + { 0x0009, 0x0001 }, + { 0x0002, 0x0001 }, + { 0x0004, 0x0001 }, + { 0x0009, 0x0002 }, + { 0x0009, 0x0003 }, + { 0x0009, 0x0004 }, + { 0x0007, 0x0007 }, + { 0x0009, 0x0005 }, + { 0x0009, 0x0006 }, + { 0x0009, 0x0007 }, + { 0x0009, 0x0008 }, + { 0x0009, 0x0009 }, + { 0x0009, 0x000a }, + { 0x0009, 0x000b }, + { 0x0009, 0x000c }, + { 0x0009, 0x000d }, + { 0x0008, 0x0007 }, + { 0x0008, 0x0008 }, + { 0x0008, 0x0009 }, + { 0x0008, 0x000a }, + { 0x0008, 0x000b }, + + }; + +const uint16_t c_aauiLCLDHuffEnc36[36][2] = + { + { 0x0001, 0x0001 }, + { 0x0002, 0x0001 }, + { 0x0006, 0x0002 }, + { 0x000b, 0x0000 }, + { 0x000b, 0x0001 }, + { 0x000b, 0x0002 }, + { 0x0003, 0x0001 }, + { 0x0004, 0x0001 }, + { 0x0008, 0x0005 }, + { 0x000b, 0x0003 }, + { 0x000b, 0x0004 }, + { 0x000b, 0x0005 }, + { 0x0006, 0x0003 }, + { 0x0007, 0x0003 }, + { 0x000b, 0x0006 }, + { 0x000b, 0x0007 }, + { 0x000b, 0x0008 }, + { 0x000b, 0x0009 }, + { 0x000b, 0x000a }, + { 0x000b, 0x000b }, + { 0x000b, 0x000c }, + { 0x000b, 0x000d }, + { 0x000b, 0x000e }, + { 0x000b, 0x000f }, + { 0x000a, 0x0008 }, + { 0x000a, 0x0009 }, + { 0x000a, 0x000a }, + { 0x000a, 0x000b }, + { 0x000a, 0x000c }, + { 0x000a, 0x000d }, + { 0x000a, 0x000e }, + { 0x000a, 0x000f }, + { 0x000a, 0x0010 }, + { 0x000a, 0x0011 }, + { 0x000a, 0x0012 }, + { 0x000a, 0x0013 }, + + }; + +const uint16_t c_aauiLCLDHuffEnc37[36][2] = + { + { 0x0001, 0x0001 }, + { 0x0002, 0x0001 }, + { 0x0006, 0x0001 }, + { 0x000c, 0x0000 }, + { 0x000c, 0x0001 }, + { 0x000c, 0x0002 }, + { 0x0003, 0x0001 }, + { 0x0004, 0x0001 }, + { 0x0006, 0x0002 }, + { 0x000c, 0x0003 }, + { 0x000c, 0x0004 }, + { 0x000c, 0x0005 }, + { 0x0006, 0x0003 }, + { 0x0007, 0x0001 }, + { 0x000a, 0x0007 }, + { 0x000c, 0x0006 }, + { 0x000c, 0x0007 }, + { 0x000c, 0x0008 }, + { 0x000c, 0x0009 }, + { 0x000c, 0x000a }, + { 0x000c, 0x000b }, + { 0x000c, 0x000c }, + { 0x000c, 0x000d }, + { 0x000c, 0x000e }, + { 0x000c, 0x000f }, + { 0x000c, 0x0010 }, + { 0x000c, 0x0011 }, + { 0x000c, 0x0012 }, + { 0x000c, 0x0013 }, + { 0x000c, 0x0014 }, + { 0x000c, 0x0015 }, + { 0x000c, 0x0016 }, + { 0x000c, 0x0017 }, + { 0x000c, 0x0018 }, + { 0x000c, 0x0019 }, + { 0x000b, 0x000d }, + + }; + +const uint16_t c_aauiLCLDHuffEnc38[49][2] = + { + { 0x0001, 0x0001 }, + { 0x0003, 0x0001 }, + { 0x0006, 0x0001 }, + { 0x000c, 0x0012 }, + { 0x000d, 0x0000 }, + { 0x000d, 0x0001 }, + { 0x000d, 0x0002 }, + { 0x0002, 0x0001 }, + { 0x0004, 0x0001 }, + { 0x0007, 0x0001 }, + { 0x000b, 0x000a }, + { 0x000d, 0x0003 }, + { 0x000d, 0x0004 }, + { 0x000d, 0x0005 }, + { 0x0006, 0x0002 }, + { 0x0006, 0x0003 }, + { 0x0009, 0x0003 }, + { 0x000d, 0x0006 }, + { 0x000d, 0x0007 }, + { 0x000d, 0x0008 }, + { 0x000d, 0x0009 }, + { 0x000c, 0x0013 }, + { 0x000b, 0x000b }, + { 0x000d, 0x000a }, + { 0x000d, 0x000b }, + { 0x000d, 0x000c }, + { 0x000d, 0x000d }, + { 0x000d, 0x000e }, + { 0x000d, 0x000f }, + { 0x000d, 0x0010 }, + { 0x000d, 0x0011 }, + { 0x000d, 0x0012 }, + { 0x000d, 0x0013 }, + { 0x000d, 0x0014 }, + { 0x000d, 0x0015 }, + { 0x000d, 0x0016 }, + { 0x000d, 0x0017 }, + { 0x000d, 0x0018 }, + { 0x000d, 0x0019 }, + { 0x000d, 0x001a }, + { 0x000d, 0x001b }, + { 0x000d, 0x001c }, + { 0x000d, 0x001d }, + { 0x000d, 0x001e }, + { 0x000d, 0x001f }, + { 0x000d, 0x0020 }, + { 0x000d, 0x0021 }, + { 0x000d, 0x0022 }, + { 0x000d, 0x0023 }, + + }; + +const uint16_t c_aauiLCLDHuffEnc39[64][2] = + { + { 0x0001, 0x0001 }, + { 0x0002, 0x0001 }, + { 0x0006, 0x0001 }, + { 0x000a, 0x0002 }, + { 0x000f, 0x0000 }, + { 0x000f, 0x0001 }, + { 0x000f, 0x0002 }, + { 0x000f, 0x0003 }, + { 0x0003, 0x0001 }, + { 0x0004, 0x0001 }, + { 0x0007, 0x0001 }, + { 0x000a, 0x0003 }, + { 0x000f, 0x0004 }, + { 0x000f, 0x0005 }, + { 0x000f, 0x0006 }, + { 0x000f, 0x0007 }, + { 0x0006, 0x0002 }, + { 0x0006, 0x0003 }, + { 0x0009, 0x0003 }, + { 0x000d, 0x000e }, + { 0x000f, 0x0008 }, + { 0x000f, 0x0009 }, + { 0x000f, 0x000a }, + { 0x000f, 0x000b }, + { 0x000a, 0x0004 }, + { 0x000a, 0x0005 }, + { 0x000d, 0x000f }, + { 0x000f, 0x000c }, + { 0x000f, 0x000d }, + { 0x000f, 0x000e }, + { 0x000f, 0x000f }, + { 0x000f, 0x0010 }, + { 0x000f, 0x0011 }, + { 0x000f, 0x0012 }, + { 0x000f, 0x0013 }, + { 0x000f, 0x0014 }, + { 0x000f, 0x0015 }, + { 0x000f, 0x0016 }, + { 0x000f, 0x0017 }, + { 0x000f, 0x0018 }, + { 0x000f, 0x0019 }, + { 0x000f, 0x001a }, + { 0x000f, 0x001b }, + { 0x000f, 0x001c }, + { 0x000f, 0x001d }, + { 0x000f, 0x001e }, + { 0x000f, 0x001f }, + { 0x000f, 0x0020 }, + { 0x000f, 0x0021 }, + { 0x000f, 0x0022 }, + { 0x000f, 0x0023 }, + { 0x000f, 0x0024 }, + { 0x000f, 0x0025 }, + { 0x000f, 0x0026 }, + { 0x000f, 0x0027 }, + { 0x000f, 0x0028 }, + { 0x000f, 0x0029 }, + { 0x000e, 0x0015 }, + { 0x000e, 0x0016 }, + { 0x000e, 0x0017 }, + { 0x000e, 0x0018 }, + { 0x000e, 0x0019 }, + { 0x000e, 0x001a }, + { 0x000e, 0x001b }, + }; + +const uint16_t c_aauiLCLDHuffEnc40[81][2] = + { + { 0x0001, 0x0001 }, + { 0x0002, 0x0001 }, + { 0x0006, 0x0001 }, + { 0x000b, 0x0002 }, + { 0x000f, 0x0011 }, + { 0x0011, 0x0000 }, + { 0x0011, 0x0001 }, + { 0x0011, 0x0002 }, + { 0x0011, 0x0003 }, + { 0x0003, 0x0001 }, + { 0x0004, 0x0001 }, + { 0x0007, 0x0001 }, + { 0x000a, 0x0002 }, + { 0x000e, 0x0009 }, + { 0x0011, 0x0004 }, + { 0x0011, 0x0005 }, + { 0x0011, 0x0006 }, + { 0x0011, 0x0007 }, + { 0x0006, 0x0002 }, + { 0x0006, 0x0003 }, + { 0x0008, 0x0001 }, + { 0x000d, 0x0005 }, + { 0x0011, 0x0008 }, + { 0x0011, 0x0009 }, + { 0x0011, 0x000a }, + { 0x0011, 0x000b }, + { 0x0011, 0x000c }, + { 0x000b, 0x0003 }, + { 0x000a, 0x0003 }, + { 0x000c, 0x0003 }, + { 0x0011, 0x000d }, + { 0x0011, 0x000e }, + { 0x0011, 0x000f }, + { 0x0011, 0x0010 }, + { 0x0011, 0x0011 }, + { 0x0011, 0x0012 }, + { 0x0011, 0x0013 }, + { 0x0011, 0x0014 }, + { 0x0011, 0x0015 }, + { 0x0011, 0x0016 }, + { 0x0011, 0x0017 }, + { 0x0011, 0x0018 }, + { 0x0011, 0x0019 }, + { 0x0011, 0x001a }, + { 0x0011, 0x001b }, + { 0x0011, 0x001c }, + { 0x0011, 0x001d }, + { 0x0011, 0x001e }, + { 0x0011, 0x001f }, + { 0x0011, 0x0020 }, + { 0x0011, 0x0021 }, + { 0x0011, 0x0022 }, + { 0x0011, 0x0023 }, + { 0x0011, 0x0024 }, + { 0x0011, 0x0025 }, + { 0x0011, 0x0026 }, + { 0x0011, 0x0027 }, + { 0x0011, 0x0028 }, + { 0x0011, 0x0029 }, + { 0x0011, 0x002a }, + { 0x0011, 0x002b }, + { 0x0011, 0x002c }, + { 0x0011, 0x002d }, + { 0x0011, 0x002e }, + { 0x0011, 0x002f }, + { 0x0011, 0x0030 }, + { 0x0011, 0x0031 }, + { 0x0011, 0x0032 }, + { 0x0011, 0x0033 }, + { 0x0011, 0x0034 }, + { 0x0011, 0x0035 }, + { 0x0011, 0x0036 }, + { 0x0011, 0x0037 }, + { 0x0011, 0x0038 }, + { 0x0011, 0x0039 }, + { 0x0011, 0x003a }, + { 0x0011, 0x003b }, + { 0x0010, 0x001e }, + { 0x0010, 0x001f }, + { 0x0010, 0x0020 }, + { 0x0010, 0x0021 }, + + }; + +const uint16_t c_aauiLCLDHuffEnc41[100][2] = + { + { 0x0001, 0x0001 }, + { 0x0003, 0x0001 }, + { 0x0006, 0x0001 }, + { 0x000b, 0x0001 }, + { 0x0011, 0x0014 }, + { 0x0013, 0x0000 }, + { 0x0013, 0x0001 }, + { 0x0013, 0x0002 }, + { 0x0013, 0x0003 }, + { 0x0013, 0x0004 }, + { 0x0002, 0x0001 }, + { 0x0004, 0x0001 }, + { 0x0007, 0x0001 }, + { 0x000a, 0x0001 }, + { 0x0010, 0x000b }, + { 0x0013, 0x0005 }, + { 0x0013, 0x0006 }, + { 0x0013, 0x0007 }, + { 0x0013, 0x0008 }, + { 0x0013, 0x0009 }, + { 0x0006, 0x0002 }, + { 0x0006, 0x0003 }, + { 0x0008, 0x0001 }, + { 0x000d, 0x0002 }, + { 0x0011, 0x0015 }, + { 0x0013, 0x000a }, + { 0x0013, 0x000b }, + { 0x0013, 0x000c }, + { 0x0013, 0x000d }, + { 0x0013, 0x000e }, + { 0x000a, 0x0002 }, + { 0x000a, 0x0003 }, + { 0x000d, 0x0003 }, + { 0x0010, 0x000c }, + { 0x0013, 0x000f }, + { 0x0013, 0x0010 }, + { 0x0013, 0x0011 }, + { 0x0013, 0x0012 }, + { 0x0013, 0x0013 }, + { 0x0013, 0x0014 }, + { 0x0010, 0x000d }, + { 0x000f, 0x0007 }, + { 0x0012, 0x0027 }, + { 0x0013, 0x0015 }, + { 0x0013, 0x0016 }, + { 0x0013, 0x0017 }, + { 0x0013, 0x0018 }, + { 0x0013, 0x0019 }, + { 0x0013, 0x001a }, + { 0x0013, 0x001b }, + { 0x0013, 0x001c }, + { 0x0013, 0x001d }, + { 0x0013, 0x001e }, + { 0x0013, 0x001f }, + { 0x0013, 0x0020 }, + { 0x0013, 0x0021 }, + { 0x0013, 0x0022 }, + { 0x0013, 0x0023 }, + { 0x0013, 0x0024 }, + { 0x0013, 0x0025 }, + { 0x0013, 0x0026 }, + { 0x0013, 0x0027 }, + { 0x0013, 0x0028 }, + { 0x0013, 0x0029 }, + { 0x0013, 0x002a }, + { 0x0013, 0x002b }, + { 0x0013, 0x002c }, + { 0x0013, 0x002d }, + { 0x0013, 0x002e }, + { 0x0013, 0x002f }, + { 0x0013, 0x0030 }, + { 0x0013, 0x0031 }, + { 0x0013, 0x0032 }, + { 0x0013, 0x0033 }, + { 0x0013, 0x0034 }, + { 0x0013, 0x0035 }, + { 0x0013, 0x0036 }, + { 0x0013, 0x0037 }, + { 0x0013, 0x0038 }, + { 0x0013, 0x0039 }, + { 0x0013, 0x003a }, + { 0x0013, 0x003b }, + { 0x0013, 0x003c }, + { 0x0013, 0x003d }, + { 0x0013, 0x003e }, + { 0x0013, 0x003f }, + { 0x0013, 0x0040 }, + { 0x0013, 0x0041 }, + { 0x0013, 0x0042 }, + { 0x0013, 0x0043 }, + { 0x0013, 0x0044 }, + { 0x0013, 0x0045 }, + { 0x0013, 0x0046 }, + { 0x0013, 0x0047 }, + { 0x0013, 0x0048 }, + { 0x0013, 0x0049 }, + { 0x0013, 0x004a }, + { 0x0013, 0x004b }, + { 0x0013, 0x004c }, + { 0x0013, 0x004d }, + + }; + +const uint16_t c_aauiLCLDHuffEnc42[169][2] = + { + { 0x0001, 0x0001 }, + { 0x0003, 0x0001 }, + { 0x0006, 0x0001 }, + { 0x0009, 0x0001 }, + { 0x000e, 0x0006 }, + { 0x0013, 0x0000 }, + { 0x0013, 0x0001 }, + { 0x0013, 0x0002 }, + { 0x0013, 0x0003 }, + { 0x0013, 0x0004 }, + { 0x0013, 0x0005 }, + { 0x0013, 0x0006 }, + { 0x0013, 0x0007 }, + { 0x0003, 0x0002 }, + { 0x0003, 0x0003 }, + { 0x0005, 0x0001 }, + { 0x0009, 0x0002 }, + { 0x000d, 0x0004 }, + { 0x0010, 0x0013 }, + { 0x0013, 0x0008 }, + { 0x0013, 0x0009 }, + { 0x0013, 0x000a }, + { 0x0013, 0x000b }, + { 0x0013, 0x000c }, + { 0x0013, 0x000d }, + { 0x0013, 0x000e }, + { 0x0005, 0x0002 }, + { 0x0005, 0x0003 }, + { 0x0008, 0x0002 }, + { 0x000b, 0x0002 }, + { 0x000f, 0x000b }, + { 0x0011, 0x0025 }, + { 0x0013, 0x000f }, + { 0x0013, 0x0010 }, + { 0x0013, 0x0011 }, + { 0x0013, 0x0012 }, + { 0x0013, 0x0013 }, + { 0x0013, 0x0014 }, + { 0x0013, 0x0015 }, + { 0x0009, 0x0003 }, + { 0x0008, 0x0003 }, + { 0x000b, 0x0003 }, + { 0x000d, 0x0005 }, + { 0x0010, 0x0014 }, + { 0x0013, 0x0016 }, + { 0x0013, 0x0017 }, + { 0x0013, 0x0018 }, + { 0x0013, 0x0019 }, + { 0x0013, 0x001a }, + { 0x0013, 0x001b }, + { 0x0013, 0x001c }, + { 0x0013, 0x001d }, + { 0x000d, 0x0006 }, + { 0x000d, 0x0007 }, + { 0x000e, 0x0007 }, + { 0x0010, 0x0015 }, + { 0x0013, 0x001e }, + { 0x0013, 0x001f }, + { 0x0013, 0x0020 }, + { 0x0013, 0x0021 }, + { 0x0013, 0x0022 }, + { 0x0013, 0x0023 }, + { 0x0013, 0x0024 }, + { 0x0013, 0x0025 }, + { 0x0013, 0x0026 }, + { 0x0012, 0x0045 }, + { 0x0013, 0x0027 }, + { 0x0013, 0x0028 }, + { 0x0013, 0x0029 }, + { 0x0013, 0x002a }, + { 0x0013, 0x002b }, + { 0x0013, 0x002c }, + { 0x0013, 0x002d }, + { 0x0013, 0x002e }, + { 0x0013, 0x002f }, + { 0x0013, 0x0030 }, + { 0x0013, 0x0031 }, + { 0x0013, 0x0032 }, + { 0x0013, 0x0033 }, + { 0x0013, 0x0034 }, + { 0x0013, 0x0035 }, + { 0x0013, 0x0036 }, + { 0x0013, 0x0037 }, + { 0x0013, 0x0038 }, + { 0x0013, 0x0039 }, + { 0x0013, 0x003a }, + { 0x0013, 0x003b }, + { 0x0013, 0x003c }, + { 0x0013, 0x003d }, + { 0x0013, 0x003e }, + { 0x0013, 0x003f }, + { 0x0013, 0x0040 }, + { 0x0013, 0x0041 }, + { 0x0013, 0x0042 }, + { 0x0013, 0x0043 }, + { 0x0013, 0x0044 }, + { 0x0013, 0x0045 }, + { 0x0013, 0x0046 }, + { 0x0013, 0x0047 }, + { 0x0013, 0x0048 }, + { 0x0013, 0x0049 }, + { 0x0013, 0x004a }, + { 0x0013, 0x004b }, + { 0x0013, 0x004c }, + { 0x0013, 0x004d }, + { 0x0013, 0x004e }, + { 0x0013, 0x004f }, + { 0x0013, 0x0050 }, + { 0x0013, 0x0051 }, + { 0x0013, 0x0052 }, + { 0x0013, 0x0053 }, + { 0x0013, 0x0054 }, + { 0x0013, 0x0055 }, + { 0x0013, 0x0056 }, + { 0x0013, 0x0057 }, + { 0x0013, 0x0058 }, + { 0x0013, 0x0059 }, + { 0x0013, 0x005a }, + { 0x0013, 0x005b }, + { 0x0013, 0x005c }, + { 0x0013, 0x005d }, + { 0x0013, 0x005e }, + { 0x0013, 0x005f }, + { 0x0013, 0x0060 }, + { 0x0013, 0x0061 }, + { 0x0013, 0x0062 }, + { 0x0013, 0x0063 }, + { 0x0013, 0x0064 }, + { 0x0013, 0x0065 }, + { 0x0013, 0x0066 }, + { 0x0013, 0x0067 }, + { 0x0013, 0x0068 }, + { 0x0013, 0x0069 }, + { 0x0013, 0x006a }, + { 0x0013, 0x006b }, + { 0x0013, 0x006c }, + { 0x0013, 0x006d }, + { 0x0013, 0x006e }, + { 0x0013, 0x006f }, + { 0x0013, 0x0070 }, + { 0x0013, 0x0071 }, + { 0x0013, 0x0072 }, + { 0x0013, 0x0073 }, + { 0x0013, 0x0074 }, + { 0x0013, 0x0075 }, + { 0x0013, 0x0076 }, + { 0x0013, 0x0077 }, + { 0x0013, 0x0078 }, + { 0x0013, 0x0079 }, + { 0x0013, 0x007a }, + { 0x0013, 0x007b }, + { 0x0013, 0x007c }, + { 0x0013, 0x007d }, + { 0x0013, 0x007e }, + { 0x0013, 0x007f }, + { 0x0013, 0x0080 }, + { 0x0013, 0x0081 }, + { 0x0013, 0x0082 }, + { 0x0013, 0x0083 }, + { 0x0013, 0x0084 }, + { 0x0013, 0x0085 }, + { 0x0013, 0x0086 }, + { 0x0013, 0x0087 }, + { 0x0013, 0x0088 }, + { 0x0013, 0x0089 }, + { 0x0012, 0x0046 }, + { 0x0012, 0x0047 }, + { 0x0012, 0x0048 }, + { 0x0012, 0x0049 }, + + }; + +const uint16_t c_aauiLCLDHuffEnc43[196][2] = + { + { 0x0001, 0x0001 }, + { 0x0003, 0x0001 }, + { 0x0006, 0x0001 }, + { 0x0009, 0x0002 }, + { 0x000c, 0x0003 }, + { 0x0010, 0x0017 }, + { 0x0013, 0x0000 }, + { 0x0013, 0x0001 }, + { 0x0013, 0x0002 }, + { 0x0013, 0x0003 }, + { 0x0013, 0x0004 }, + { 0x0013, 0x0005 }, + { 0x0013, 0x0006 }, + { 0x0013, 0x0007 }, + { 0x0003, 0x0002 }, + { 0x0003, 0x0003 }, + { 0x0005, 0x0001 }, + { 0x0009, 0x0003 }, + { 0x000c, 0x0004 }, + { 0x0010, 0x0018 }, + { 0x0012, 0x0050 }, + { 0x0013, 0x0008 }, + { 0x0013, 0x0009 }, + { 0x0013, 0x000a }, + { 0x0013, 0x000b }, + { 0x0013, 0x000c }, + { 0x0013, 0x000d }, + { 0x0013, 0x000e }, + { 0x0005, 0x0002 }, + { 0x0005, 0x0003 }, + { 0x0008, 0x0003 }, + { 0x000a, 0x0002 }, + { 0x000d, 0x0004 }, + { 0x0011, 0x002a }, + { 0x0013, 0x000f }, + { 0x0013, 0x0010 }, + { 0x0013, 0x0011 }, + { 0x0013, 0x0012 }, + { 0x0013, 0x0013 }, + { 0x0013, 0x0014 }, + { 0x0013, 0x0015 }, + { 0x0013, 0x0016 }, + { 0x0009, 0x0004 }, + { 0x0009, 0x0005 }, + { 0x000a, 0x0003 }, + { 0x000c, 0x0005 }, + { 0x000f, 0x000d }, + { 0x0012, 0x0051 }, + { 0x0013, 0x0017 }, + { 0x0013, 0x0018 }, + { 0x0013, 0x0019 }, + { 0x0013, 0x001a }, + { 0x0013, 0x001b }, + { 0x0013, 0x001c }, + { 0x0013, 0x001d }, + { 0x0013, 0x001e }, + { 0x000c, 0x0006 }, + { 0x000c, 0x0007 }, + { 0x000d, 0x0005 }, + { 0x000f, 0x000e }, + { 0x0011, 0x002b }, + { 0x0013, 0x001f }, + { 0x0013, 0x0020 }, + { 0x0013, 0x0021 }, + { 0x0013, 0x0022 }, + { 0x0013, 0x0023 }, + { 0x0013, 0x0024 }, + { 0x0013, 0x0025 }, + { 0x0013, 0x0026 }, + { 0x0013, 0x0027 }, + { 0x0011, 0x002c }, + { 0x000f, 0x000f }, + { 0x0010, 0x0019 }, + { 0x0012, 0x0052 }, + { 0x0012, 0x0053 }, + { 0x0013, 0x0028 }, + { 0x0013, 0x0029 }, + { 0x0013, 0x002a }, + { 0x0013, 0x002b }, + { 0x0013, 0x002c }, + { 0x0013, 0x002d }, + { 0x0013, 0x002e }, + { 0x0013, 0x002f }, + { 0x0013, 0x0030 }, + { 0x0013, 0x0031 }, + { 0x0011, 0x002d }, + { 0x0013, 0x0032 }, + { 0x0013, 0x0033 }, + { 0x0013, 0x0034 }, + { 0x0013, 0x0035 }, + { 0x0013, 0x0036 }, + { 0x0013, 0x0037 }, + { 0x0013, 0x0038 }, + { 0x0013, 0x0039 }, + { 0x0013, 0x003a }, + { 0x0013, 0x003b }, + { 0x0013, 0x003c }, + { 0x0013, 0x003d }, + { 0x0013, 0x003e }, + { 0x0013, 0x003f }, + { 0x0013, 0x0040 }, + { 0x0013, 0x0041 }, + { 0x0013, 0x0042 }, + { 0x0013, 0x0043 }, + { 0x0013, 0x0044 }, + { 0x0013, 0x0045 }, + { 0x0013, 0x0046 }, + { 0x0013, 0x0047 }, + { 0x0013, 0x0048 }, + { 0x0013, 0x0049 }, + { 0x0013, 0x004a }, + { 0x0013, 0x004b }, + { 0x0013, 0x004c }, + { 0x0013, 0x004d }, + { 0x0013, 0x004e }, + { 0x0013, 0x004f }, + { 0x0013, 0x0050 }, + { 0x0013, 0x0051 }, + { 0x0013, 0x0052 }, + { 0x0013, 0x0053 }, + { 0x0013, 0x0054 }, + { 0x0013, 0x0055 }, + { 0x0013, 0x0056 }, + { 0x0013, 0x0057 }, + { 0x0013, 0x0058 }, + { 0x0013, 0x0059 }, + { 0x0013, 0x005a }, + { 0x0013, 0x005b }, + { 0x0013, 0x005c }, + { 0x0013, 0x005d }, + { 0x0013, 0x005e }, + { 0x0013, 0x005f }, + { 0x0013, 0x0060 }, + { 0x0013, 0x0061 }, + { 0x0013, 0x0062 }, + { 0x0013, 0x0063 }, + { 0x0013, 0x0064 }, + { 0x0013, 0x0065 }, + { 0x0013, 0x0066 }, + { 0x0013, 0x0067 }, + { 0x0013, 0x0068 }, + { 0x0013, 0x0069 }, + { 0x0013, 0x006a }, + { 0x0013, 0x006b }, + { 0x0013, 0x006c }, + { 0x0013, 0x006d }, + { 0x0013, 0x006e }, + { 0x0013, 0x006f }, + { 0x0013, 0x0070 }, + { 0x0013, 0x0071 }, + { 0x0013, 0x0072 }, + { 0x0013, 0x0073 }, + { 0x0013, 0x0074 }, + { 0x0013, 0x0075 }, + { 0x0013, 0x0076 }, + { 0x0013, 0x0077 }, + { 0x0013, 0x0078 }, + { 0x0013, 0x0079 }, + { 0x0013, 0x007a }, + { 0x0013, 0x007b }, + { 0x0013, 0x007c }, + { 0x0013, 0x007d }, + { 0x0013, 0x007e }, + { 0x0013, 0x007f }, + { 0x0013, 0x0080 }, + { 0x0013, 0x0081 }, + { 0x0013, 0x0082 }, + { 0x0013, 0x0083 }, + { 0x0013, 0x0084 }, + { 0x0013, 0x0085 }, + { 0x0013, 0x0086 }, + { 0x0013, 0x0087 }, + { 0x0013, 0x0088 }, + { 0x0013, 0x0089 }, + { 0x0013, 0x008a }, + { 0x0013, 0x008b }, + { 0x0013, 0x008c }, + { 0x0013, 0x008d }, + { 0x0013, 0x008e }, + { 0x0013, 0x008f }, + { 0x0013, 0x0090 }, + { 0x0013, 0x0091 }, + { 0x0013, 0x0092 }, + { 0x0013, 0x0093 }, + { 0x0013, 0x0094 }, + { 0x0013, 0x0095 }, + { 0x0013, 0x0096 }, + { 0x0013, 0x0097 }, + { 0x0013, 0x0098 }, + { 0x0013, 0x0099 }, + { 0x0013, 0x009a }, + { 0x0013, 0x009b }, + { 0x0013, 0x009c }, + { 0x0013, 0x009d }, + { 0x0013, 0x009e }, + { 0x0013, 0x009f }, + + }; + +const uint16_t c_aauiLCLDHuffEnc44[289][2] = + { + { 0x0001, 0x0001 }, + { 0x0003, 0x0001 }, + { 0x0006, 0x0002 }, + { 0x0008, 0x0002 }, + { 0x000b, 0x0002 }, + { 0x000f, 0x000a }, + { 0x0011, 0x0022 }, + { 0x0014, 0x0000 }, + { 0x0014, 0x0001 }, + { 0x0014, 0x0002 }, + { 0x0014, 0x0003 }, + { 0x0014, 0x0004 }, + { 0x0014, 0x0005 }, + { 0x0014, 0x0006 }, + { 0x0014, 0x0007 }, + { 0x0014, 0x0008 }, + { 0x0014, 0x0009 }, + { 0x0003, 0x0002 }, + { 0x0003, 0x0003 }, + { 0x0005, 0x0002 }, + { 0x0008, 0x0003 }, + { 0x000b, 0x0003 }, + { 0x000e, 0x0007 }, + { 0x0012, 0x003f }, + { 0x0014, 0x000a }, + { 0x0014, 0x000b }, + { 0x0014, 0x000c }, + { 0x0014, 0x000d }, + { 0x0014, 0x000e }, + { 0x0014, 0x000f }, + { 0x0014, 0x0010 }, + { 0x0014, 0x0011 }, + { 0x0014, 0x0012 }, + { 0x0014, 0x0013 }, + { 0x0006, 0x0003 }, + { 0x0005, 0x0003 }, + { 0x0007, 0x0003 }, + { 0x0009, 0x0002 }, + { 0x000c, 0x0003 }, + { 0x000f, 0x000b }, + { 0x0012, 0x0040 }, + { 0x0014, 0x0014 }, + { 0x0014, 0x0015 }, + { 0x0014, 0x0016 }, + { 0x0014, 0x0017 }, + { 0x0014, 0x0018 }, + { 0x0014, 0x0019 }, + { 0x0014, 0x001a }, + { 0x0014, 0x001b }, + { 0x0014, 0x001c }, + { 0x0014, 0x001d }, + { 0x0008, 0x0004 }, + { 0x0008, 0x0005 }, + { 0x0009, 0x0003 }, + { 0x000b, 0x0004 }, + { 0x000d, 0x0005 }, + { 0x0010, 0x0013 }, + { 0x0014, 0x001e }, + { 0x0014, 0x001f }, + { 0x0014, 0x0020 }, + { 0x0014, 0x0021 }, + { 0x0014, 0x0022 }, + { 0x0014, 0x0023 }, + { 0x0014, 0x0024 }, + { 0x0014, 0x0025 }, + { 0x0014, 0x0026 }, + { 0x0014, 0x0027 }, + { 0x0014, 0x0028 }, + { 0x000b, 0x0005 }, + { 0x000b, 0x0006 }, + { 0x000b, 0x0007 }, + { 0x000e, 0x0008 }, + { 0x0011, 0x0023 }, + { 0x0012, 0x0041 }, + { 0x0014, 0x0029 }, + { 0x0014, 0x002a }, + { 0x0013, 0x007b }, + { 0x0014, 0x002b }, + { 0x0014, 0x002c }, + { 0x0014, 0x002d }, + { 0x0014, 0x002e }, + { 0x0014, 0x002f }, + { 0x0014, 0x0030 }, + { 0x0014, 0x0031 }, + { 0x0014, 0x0032 }, + { 0x000f, 0x000c }, + { 0x000e, 0x0009 }, + { 0x000f, 0x000d }, + { 0x0011, 0x0024 }, + { 0x0012, 0x0042 }, + { 0x0014, 0x0033 }, + { 0x0014, 0x0034 }, + { 0x0014, 0x0035 }, + { 0x0014, 0x0036 }, + { 0x0014, 0x0037 }, + { 0x0014, 0x0038 }, + { 0x0014, 0x0039 }, + { 0x0014, 0x003a }, + { 0x0014, 0x003b }, + { 0x0014, 0x003c }, + { 0x0014, 0x003d }, + { 0x0014, 0x003e }, + { 0x0013, 0x007c }, + { 0x0011, 0x0025 }, + { 0x0012, 0x0043 }, + { 0x0014, 0x003f }, + { 0x0014, 0x0040 }, + { 0x0014, 0x0041 }, + { 0x0014, 0x0042 }, + { 0x0014, 0x0043 }, + { 0x0014, 0x0044 }, + { 0x0014, 0x0045 }, + { 0x0014, 0x0046 }, + { 0x0014, 0x0047 }, + { 0x0014, 0x0048 }, + { 0x0014, 0x0049 }, + { 0x0014, 0x004a }, + { 0x0014, 0x004b }, + { 0x0014, 0x004c }, + { 0x0014, 0x004d }, + { 0x0014, 0x004e }, + { 0x0014, 0x004f }, + { 0x0014, 0x0050 }, + { 0x0014, 0x0051 }, + { 0x0014, 0x0052 }, + { 0x0014, 0x0053 }, + { 0x0014, 0x0054 }, + { 0x0014, 0x0055 }, + { 0x0014, 0x0056 }, + { 0x0014, 0x0057 }, + { 0x0014, 0x0058 }, + { 0x0014, 0x0059 }, + { 0x0014, 0x005a }, + { 0x0014, 0x005b }, + { 0x0014, 0x005c }, + { 0x0014, 0x005d }, + { 0x0014, 0x005e }, + { 0x0014, 0x005f }, + { 0x0014, 0x0060 }, + { 0x0014, 0x0061 }, + { 0x0014, 0x0062 }, + { 0x0014, 0x0063 }, + { 0x0014, 0x0064 }, + { 0x0014, 0x0065 }, + { 0x0014, 0x0066 }, + { 0x0014, 0x0067 }, + { 0x0014, 0x0068 }, + { 0x0014, 0x0069 }, + { 0x0014, 0x006a }, + { 0x0014, 0x006b }, + { 0x0014, 0x006c }, + { 0x0014, 0x006d }, + { 0x0014, 0x006e }, + { 0x0014, 0x006f }, + { 0x0014, 0x0070 }, + { 0x0014, 0x0071 }, + { 0x0014, 0x0072 }, + { 0x0014, 0x0073 }, + { 0x0014, 0x0074 }, + { 0x0014, 0x0075 }, + { 0x0014, 0x0076 }, + { 0x0014, 0x0077 }, + { 0x0014, 0x0078 }, + { 0x0014, 0x0079 }, + { 0x0014, 0x007a }, + { 0x0014, 0x007b }, + { 0x0014, 0x007c }, + { 0x0014, 0x007d }, + { 0x0014, 0x007e }, + { 0x0014, 0x007f }, + { 0x0014, 0x0080 }, + { 0x0014, 0x0081 }, + { 0x0014, 0x0082 }, + { 0x0014, 0x0083 }, + { 0x0014, 0x0084 }, + { 0x0014, 0x0085 }, + { 0x0014, 0x0086 }, + { 0x0014, 0x0087 }, + { 0x0014, 0x0088 }, + { 0x0014, 0x0089 }, + { 0x0014, 0x008a }, + { 0x0014, 0x008b }, + { 0x0014, 0x008c }, + { 0x0014, 0x008d }, + { 0x0014, 0x008e }, + { 0x0014, 0x008f }, + { 0x0014, 0x0090 }, + { 0x0014, 0x0091 }, + { 0x0014, 0x0092 }, + { 0x0014, 0x0093 }, + { 0x0014, 0x0094 }, + { 0x0014, 0x0095 }, + { 0x0014, 0x0096 }, + { 0x0014, 0x0097 }, + { 0x0014, 0x0098 }, + { 0x0014, 0x0099 }, + { 0x0014, 0x009a }, + { 0x0014, 0x009b }, + { 0x0014, 0x009c }, + { 0x0014, 0x009d }, + { 0x0014, 0x009e }, + { 0x0014, 0x009f }, + { 0x0014, 0x00a0 }, + { 0x0014, 0x00a1 }, + { 0x0014, 0x00a2 }, + { 0x0014, 0x00a3 }, + { 0x0014, 0x00a4 }, + { 0x0014, 0x00a5 }, + { 0x0014, 0x00a6 }, + { 0x0014, 0x00a7 }, + { 0x0014, 0x00a8 }, + { 0x0014, 0x00a9 }, + { 0x0014, 0x00aa }, + { 0x0014, 0x00ab }, + { 0x0014, 0x00ac }, + { 0x0014, 0x00ad }, + { 0x0014, 0x00ae }, + { 0x0014, 0x00af }, + { 0x0014, 0x00b0 }, + { 0x0014, 0x00b1 }, + { 0x0014, 0x00b2 }, + { 0x0014, 0x00b3 }, + { 0x0014, 0x00b4 }, + { 0x0014, 0x00b5 }, + { 0x0014, 0x00b6 }, + { 0x0014, 0x00b7 }, + { 0x0014, 0x00b8 }, + { 0x0014, 0x00b9 }, + { 0x0014, 0x00ba }, + { 0x0014, 0x00bb }, + { 0x0014, 0x00bc }, + { 0x0014, 0x00bd }, + { 0x0014, 0x00be }, + { 0x0014, 0x00bf }, + { 0x0014, 0x00c0 }, + { 0x0014, 0x00c1 }, + { 0x0014, 0x00c2 }, + { 0x0014, 0x00c3 }, + { 0x0014, 0x00c4 }, + { 0x0014, 0x00c5 }, + { 0x0014, 0x00c6 }, + { 0x0014, 0x00c7 }, + { 0x0014, 0x00c8 }, + { 0x0014, 0x00c9 }, + { 0x0014, 0x00ca }, + { 0x0014, 0x00cb }, + { 0x0014, 0x00cc }, + { 0x0014, 0x00cd }, + { 0x0014, 0x00ce }, + { 0x0014, 0x00cf }, + { 0x0014, 0x00d0 }, + { 0x0014, 0x00d1 }, + { 0x0014, 0x00d2 }, + { 0x0014, 0x00d3 }, + { 0x0014, 0x00d4 }, + { 0x0014, 0x00d5 }, + { 0x0014, 0x00d6 }, + { 0x0014, 0x00d7 }, + { 0x0014, 0x00d8 }, + { 0x0014, 0x00d9 }, + { 0x0014, 0x00da }, + { 0x0014, 0x00db }, + { 0x0014, 0x00dc }, + { 0x0014, 0x00dd }, + { 0x0014, 0x00de }, + { 0x0014, 0x00df }, + { 0x0014, 0x00e0 }, + { 0x0014, 0x00e1 }, + { 0x0014, 0x00e2 }, + { 0x0014, 0x00e3 }, + { 0x0014, 0x00e4 }, + { 0x0014, 0x00e5 }, + { 0x0014, 0x00e6 }, + { 0x0014, 0x00e7 }, + { 0x0014, 0x00e8 }, + { 0x0014, 0x00e9 }, + { 0x0014, 0x00ea }, + { 0x0014, 0x00eb }, + { 0x0014, 0x00ec }, + { 0x0014, 0x00ed }, + { 0x0014, 0x00ee }, + { 0x0014, 0x00ef }, + { 0x0014, 0x00f0 }, + { 0x0014, 0x00f1 }, + { 0x0014, 0x00f2 }, + { 0x0014, 0x00f3 }, + { 0x0014, 0x00f4 }, + { 0x0014, 0x00f5 }, + { 0x0013, 0x007d }, + + }; + + +const uint16_t c_aauiLCLDHuffEnc45[324][2] = + { + { 0x0002, 0x0002 }, + { 0x0003, 0x0002 }, + { 0x0005, 0x0003 }, + { 0x0007, 0x0002 }, + { 0x0009, 0x0003 }, + { 0x000c, 0x0005 }, + { 0x0010, 0x0025 }, + { 0x0012, 0x0088 }, + { 0x0013, 0x0000 }, + { 0x0013, 0x0001 }, + { 0x0013, 0x0002 }, + { 0x0013, 0x0003 }, + { 0x0013, 0x0004 }, + { 0x0013, 0x0005 }, + { 0x0013, 0x0006 }, + { 0x0013, 0x0007 }, + { 0x0013, 0x0008 }, + { 0x0013, 0x0009 }, + { 0x0002, 0x0003 }, + { 0x0003, 0x0003 }, + { 0x0005, 0x0004 }, + { 0x0006, 0x0003 }, + { 0x0009, 0x0004 }, + { 0x000b, 0x0004 }, + { 0x000f, 0x0014 }, + { 0x0011, 0x0048 }, + { 0x0013, 0x000a }, + { 0x0013, 0x000b }, + { 0x0013, 0x000c }, + { 0x0013, 0x000d }, + { 0x0013, 0x000e }, + { 0x0013, 0x000f }, + { 0x0013, 0x0010 }, + { 0x0013, 0x0011 }, + { 0x0013, 0x0012 }, + { 0x0013, 0x0013 }, + { 0x0005, 0x0005 }, + { 0x0004, 0x0003 }, + { 0x0006, 0x0004 }, + { 0x0007, 0x0003 }, + { 0x000a, 0x0004 }, + { 0x000d, 0x0007 }, + { 0x000f, 0x0015 }, + { 0x0013, 0x0014 }, + { 0x0013, 0x0015 }, + { 0x0013, 0x0016 }, + { 0x0013, 0x0017 }, + { 0x0013, 0x0018 }, + { 0x0013, 0x0019 }, + { 0x0013, 0x001a }, + { 0x0013, 0x001b }, + { 0x0013, 0x001c }, + { 0x0013, 0x001d }, + { 0x0013, 0x001e }, + { 0x0007, 0x0004 }, + { 0x0006, 0x0005 }, + { 0x0007, 0x0005 }, + { 0x0009, 0x0005 }, + { 0x000b, 0x0005 }, + { 0x000d, 0x0008 }, + { 0x0010, 0x0026 }, + { 0x0012, 0x0089 }, + { 0x0012, 0x008a }, + { 0x0013, 0x001f }, + { 0x0013, 0x0020 }, + { 0x0013, 0x0021 }, + { 0x0013, 0x0022 }, + { 0x0013, 0x0023 }, + { 0x0013, 0x0024 }, + { 0x0013, 0x0025 }, + { 0x0013, 0x0026 }, + { 0x0013, 0x0027 }, + { 0x0009, 0x0006 }, + { 0x0009, 0x0007 }, + { 0x000a, 0x0005 }, + { 0x000b, 0x0006 }, + { 0x000d, 0x0009 }, + { 0x000f, 0x0016 }, + { 0x0011, 0x0049 }, + { 0x0013, 0x0028 }, + { 0x0013, 0x0029 }, + { 0x0013, 0x002a }, + { 0x0013, 0x002b }, + { 0x0013, 0x002c }, + { 0x0013, 0x002d }, + { 0x0013, 0x002e }, + { 0x0013, 0x002f }, + { 0x0013, 0x0030 }, + { 0x0013, 0x0031 }, + { 0x0013, 0x0032 }, + { 0x000c, 0x0006 }, + { 0x000b, 0x0007 }, + { 0x000c, 0x0007 }, + { 0x000e, 0x000d }, + { 0x0010, 0x0027 }, + { 0x0012, 0x008b }, + { 0x0012, 0x008c }, + { 0x0013, 0x0033 }, + { 0x0013, 0x0034 }, + { 0x0013, 0x0035 }, + { 0x0013, 0x0036 }, + { 0x0013, 0x0037 }, + { 0x0013, 0x0038 }, + { 0x0013, 0x0039 }, + { 0x0013, 0x003a }, + { 0x0013, 0x003b }, + { 0x0013, 0x003c }, + { 0x0013, 0x003d }, + { 0x000f, 0x0017 }, + { 0x000f, 0x0018 }, + { 0x000f, 0x0019 }, + { 0x0012, 0x008d }, + { 0x0013, 0x003e }, + { 0x0013, 0x003f }, + { 0x0013, 0x0040 }, + { 0x0013, 0x0041 }, + { 0x0013, 0x0042 }, + { 0x0013, 0x0043 }, + { 0x0013, 0x0044 }, + { 0x0013, 0x0045 }, + { 0x0013, 0x0046 }, + { 0x0013, 0x0047 }, + { 0x0013, 0x0048 }, + { 0x0013, 0x0049 }, + { 0x0013, 0x004a }, + { 0x0013, 0x004b }, + { 0x0013, 0x004c }, + { 0x0012, 0x008e }, + { 0x0012, 0x008f }, + { 0x0013, 0x004d }, + { 0x0013, 0x004e }, + { 0x0013, 0x004f }, + { 0x0013, 0x0050 }, + { 0x0013, 0x0051 }, + { 0x0013, 0x0052 }, + { 0x0013, 0x0053 }, + { 0x0013, 0x0054 }, + { 0x0013, 0x0055 }, + { 0x0013, 0x0056 }, + { 0x0013, 0x0057 }, + { 0x0013, 0x0058 }, + { 0x0013, 0x0059 }, + { 0x0013, 0x005a }, + { 0x0013, 0x005b }, + { 0x0013, 0x005c }, + { 0x0013, 0x005d }, + { 0x0013, 0x005e }, + { 0x0013, 0x005f }, + { 0x0013, 0x0060 }, + { 0x0013, 0x0061 }, + { 0x0013, 0x0062 }, + { 0x0013, 0x0063 }, + { 0x0013, 0x0064 }, + { 0x0013, 0x0065 }, + { 0x0013, 0x0066 }, + { 0x0013, 0x0067 }, + { 0x0013, 0x0068 }, + { 0x0013, 0x0069 }, + { 0x0013, 0x006a }, + { 0x0013, 0x006b }, + { 0x0013, 0x006c }, + { 0x0013, 0x006d }, + { 0x0013, 0x006e }, + { 0x0013, 0x006f }, + { 0x0013, 0x0070 }, + { 0x0013, 0x0071 }, + { 0x0013, 0x0072 }, + { 0x0013, 0x0073 }, + { 0x0013, 0x0074 }, + { 0x0013, 0x0075 }, + { 0x0013, 0x0076 }, + { 0x0013, 0x0077 }, + { 0x0013, 0x0078 }, + { 0x0013, 0x0079 }, + { 0x0013, 0x007a }, + { 0x0013, 0x007b }, + { 0x0013, 0x007c }, + { 0x0013, 0x007d }, + { 0x0013, 0x007e }, + { 0x0013, 0x007f }, + { 0x0013, 0x0080 }, + { 0x0013, 0x0081 }, + { 0x0013, 0x0082 }, + { 0x0013, 0x0083 }, + { 0x0013, 0x0084 }, + { 0x0013, 0x0085 }, + { 0x0013, 0x0086 }, + { 0x0013, 0x0087 }, + { 0x0013, 0x0088 }, + { 0x0013, 0x0089 }, + { 0x0013, 0x008a }, + { 0x0013, 0x008b }, + { 0x0013, 0x008c }, + { 0x0013, 0x008d }, + { 0x0013, 0x008e }, + { 0x0013, 0x008f }, + { 0x0013, 0x0090 }, + { 0x0013, 0x0091 }, + { 0x0013, 0x0092 }, + { 0x0013, 0x0093 }, + { 0x0013, 0x0094 }, + { 0x0013, 0x0095 }, + { 0x0013, 0x0096 }, + { 0x0013, 0x0097 }, + { 0x0013, 0x0098 }, + { 0x0013, 0x0099 }, + { 0x0013, 0x009a }, + { 0x0013, 0x009b }, + { 0x0013, 0x009c }, + { 0x0013, 0x009d }, + { 0x0013, 0x009e }, + { 0x0013, 0x009f }, + { 0x0013, 0x00a0 }, + { 0x0013, 0x00a1 }, + { 0x0013, 0x00a2 }, + { 0x0013, 0x00a3 }, + { 0x0013, 0x00a4 }, + { 0x0013, 0x00a5 }, + { 0x0013, 0x00a6 }, + { 0x0013, 0x00a7 }, + { 0x0013, 0x00a8 }, + { 0x0013, 0x00a9 }, + { 0x0013, 0x00aa }, + { 0x0013, 0x00ab }, + { 0x0013, 0x00ac }, + { 0x0013, 0x00ad }, + { 0x0013, 0x00ae }, + { 0x0013, 0x00af }, + { 0x0013, 0x00b0 }, + { 0x0013, 0x00b1 }, + { 0x0013, 0x00b2 }, + { 0x0013, 0x00b3 }, + { 0x0013, 0x00b4 }, + { 0x0013, 0x00b5 }, + { 0x0013, 0x00b6 }, + { 0x0013, 0x00b7 }, + { 0x0013, 0x00b8 }, + { 0x0013, 0x00b9 }, + { 0x0013, 0x00ba }, + { 0x0013, 0x00bb }, + { 0x0013, 0x00bc }, + { 0x0013, 0x00bd }, + { 0x0013, 0x00be }, + { 0x0013, 0x00bf }, + { 0x0013, 0x00c0 }, + { 0x0013, 0x00c1 }, + { 0x0013, 0x00c2 }, + { 0x0013, 0x00c3 }, + { 0x0013, 0x00c4 }, + { 0x0013, 0x00c5 }, + { 0x0013, 0x00c6 }, + { 0x0013, 0x00c7 }, + { 0x0013, 0x00c8 }, + { 0x0013, 0x00c9 }, + { 0x0013, 0x00ca }, + { 0x0013, 0x00cb }, + { 0x0013, 0x00cc }, + { 0x0013, 0x00cd }, + { 0x0013, 0x00ce }, + { 0x0013, 0x00cf }, + { 0x0013, 0x00d0 }, + { 0x0013, 0x00d1 }, + { 0x0013, 0x00d2 }, + { 0x0013, 0x00d3 }, + { 0x0013, 0x00d4 }, + { 0x0013, 0x00d5 }, + { 0x0013, 0x00d6 }, + { 0x0013, 0x00d7 }, + { 0x0013, 0x00d8 }, + { 0x0013, 0x00d9 }, + { 0x0013, 0x00da }, + { 0x0013, 0x00db }, + { 0x0013, 0x00dc }, + { 0x0013, 0x00dd }, + { 0x0013, 0x00de }, + { 0x0013, 0x00df }, + { 0x0013, 0x00e0 }, + { 0x0013, 0x00e1 }, + { 0x0013, 0x00e2 }, + { 0x0013, 0x00e3 }, + { 0x0013, 0x00e4 }, + { 0x0013, 0x00e5 }, + { 0x0013, 0x00e6 }, + { 0x0013, 0x00e7 }, + { 0x0013, 0x00e8 }, + { 0x0013, 0x00e9 }, + { 0x0013, 0x00ea }, + { 0x0013, 0x00eb }, + { 0x0013, 0x00ec }, + { 0x0013, 0x00ed }, + { 0x0013, 0x00ee }, + { 0x0013, 0x00ef }, + { 0x0013, 0x00f0 }, + { 0x0013, 0x00f1 }, + { 0x0013, 0x00f2 }, + { 0x0013, 0x00f3 }, + { 0x0013, 0x00f4 }, + { 0x0013, 0x00f5 }, + { 0x0013, 0x00f6 }, + { 0x0013, 0x00f7 }, + { 0x0013, 0x00f8 }, + { 0x0013, 0x00f9 }, + { 0x0013, 0x00fa }, + { 0x0013, 0x00fb }, + { 0x0013, 0x00fc }, + { 0x0013, 0x00fd }, + { 0x0013, 0x00fe }, + { 0x0013, 0x00ff }, + { 0x0013, 0x0100 }, + { 0x0013, 0x0101 }, + { 0x0013, 0x0102 }, + { 0x0013, 0x0103 }, + { 0x0013, 0x0104 }, + { 0x0013, 0x0105 }, + { 0x0013, 0x0106 }, + { 0x0013, 0x0107 }, + { 0x0013, 0x0108 }, + { 0x0013, 0x0109 }, + { 0x0013, 0x010a }, + { 0x0013, 0x010b }, + { 0x0013, 0x010c }, + { 0x0013, 0x010d }, + { 0x0013, 0x010e }, + { 0x0013, 0x010f }, + + }; + +const uint16_t c_aauiLCLDHuffEnc46[400][2] = + { + { 0x0002, 0x0002 }, + { 0x0003, 0x0002 }, + { 0x0005, 0x0003 }, + { 0x0007, 0x0004 }, + { 0x0009, 0x0005 }, + { 0x000b, 0x0006 }, + { 0x000d, 0x000a }, + { 0x000f, 0x0018 }, + { 0x0012, 0x00a6 }, + { 0x0013, 0x0000 }, + { 0x0013, 0x0001 }, + { 0x0013, 0x0002 }, + { 0x0013, 0x0003 }, + { 0x0013, 0x0004 }, + { 0x0013, 0x0005 }, + { 0x0013, 0x0006 }, + { 0x0013, 0x0007 }, + { 0x0013, 0x0008 }, + { 0x0013, 0x0009 }, + { 0x0013, 0x000a }, + { 0x0002, 0x0003 }, + { 0x0003, 0x0003 }, + { 0x0005, 0x0004 }, + { 0x0006, 0x0004 }, + { 0x0008, 0x0004 }, + { 0x000a, 0x0006 }, + { 0x000c, 0x0008 }, + { 0x000e, 0x0011 }, + { 0x0012, 0x00a7 }, + { 0x0013, 0x000b }, + { 0x0013, 0x000c }, + { 0x0013, 0x000d }, + { 0x0013, 0x000e }, + { 0x0013, 0x000f }, + { 0x0013, 0x0010 }, + { 0x0013, 0x0011 }, + { 0x0013, 0x0012 }, + { 0x0013, 0x0013 }, + { 0x0013, 0x0014 }, + { 0x0013, 0x0015 }, + { 0x0005, 0x0005 }, + { 0x0005, 0x0006 }, + { 0x0005, 0x0007 }, + { 0x0007, 0x0005 }, + { 0x0009, 0x0006 }, + { 0x000b, 0x0007 }, + { 0x000d, 0x000b }, + { 0x000f, 0x0019 }, + { 0x0013, 0x0016 }, + { 0x0013, 0x0017 }, + { 0x0013, 0x0018 }, + { 0x0013, 0x0019 }, + { 0x0013, 0x001a }, + { 0x0013, 0x001b }, + { 0x0013, 0x001c }, + { 0x0013, 0x001d }, + { 0x0013, 0x001e }, + { 0x0013, 0x001f }, + { 0x0013, 0x0020 }, + { 0x0013, 0x0021 }, + { 0x0007, 0x0006 }, + { 0x0006, 0x0005 }, + { 0x0007, 0x0007 }, + { 0x0008, 0x0005 }, + { 0x000a, 0x0007 }, + { 0x000c, 0x0009 }, + { 0x000e, 0x0012 }, + { 0x000f, 0x001a }, + { 0x0012, 0x00a8 }, + { 0x0013, 0x0022 }, + { 0x0013, 0x0023 }, + { 0x0013, 0x0024 }, + { 0x0013, 0x0025 }, + { 0x0013, 0x0026 }, + { 0x0013, 0x0027 }, + { 0x0013, 0x0028 }, + { 0x0013, 0x0029 }, + { 0x0013, 0x002a }, + { 0x0013, 0x002b }, + { 0x0013, 0x002c }, + { 0x0009, 0x0007 }, + { 0x0008, 0x0006 }, + { 0x0008, 0x0007 }, + { 0x000a, 0x0008 }, + { 0x000b, 0x0008 }, + { 0x000d, 0x000c }, + { 0x000e, 0x0013 }, + { 0x0010, 0x002c }, + { 0x0013, 0x002d }, + { 0x0013, 0x002e }, + { 0x0013, 0x002f }, + { 0x0013, 0x0030 }, + { 0x0013, 0x0031 }, + { 0x0013, 0x0032 }, + { 0x0013, 0x0033 }, + { 0x0013, 0x0034 }, + { 0x0013, 0x0035 }, + { 0x0013, 0x0036 }, + { 0x0013, 0x0037 }, + { 0x0013, 0x0038 }, + { 0x000b, 0x0009 }, + { 0x000a, 0x0009 }, + { 0x000b, 0x000a }, + { 0x000b, 0x000b }, + { 0x000d, 0x000d }, + { 0x000f, 0x001b }, + { 0x0010, 0x002d }, + { 0x0013, 0x0039 }, + { 0x0013, 0x003a }, + { 0x0013, 0x003b }, + { 0x0013, 0x003c }, + { 0x0013, 0x003d }, + { 0x0013, 0x003e }, + { 0x0013, 0x003f }, + { 0x0013, 0x0040 }, + { 0x0013, 0x0041 }, + { 0x0013, 0x0042 }, + { 0x0013, 0x0043 }, + { 0x0013, 0x0044 }, + { 0x0013, 0x0045 }, + { 0x000d, 0x000e }, + { 0x000c, 0x000a }, + { 0x000c, 0x000b }, + { 0x000d, 0x000f }, + { 0x000f, 0x001c }, + { 0x000f, 0x001d }, + { 0x0013, 0x0046 }, + { 0x0013, 0x0047 }, + { 0x0013, 0x0048 }, + { 0x0013, 0x0049 }, + { 0x0013, 0x004a }, + { 0x0013, 0x004b }, + { 0x0013, 0x004c }, + { 0x0013, 0x004d }, + { 0x0013, 0x004e }, + { 0x0013, 0x004f }, + { 0x0013, 0x0050 }, + { 0x0013, 0x0051 }, + { 0x0013, 0x0052 }, + { 0x0013, 0x0053 }, + { 0x000f, 0x001e }, + { 0x000f, 0x001f }, + { 0x000f, 0x0020 }, + { 0x000f, 0x0021 }, + { 0x0010, 0x002e }, + { 0x0012, 0x00a9 }, + { 0x0013, 0x0054 }, + { 0x0013, 0x0055 }, + { 0x0012, 0x00aa }, + { 0x0013, 0x0056 }, + { 0x0013, 0x0057 }, + { 0x0013, 0x0058 }, + { 0x0013, 0x0059 }, + { 0x0013, 0x005a }, + { 0x0013, 0x005b }, + { 0x0013, 0x005c }, + { 0x0013, 0x005d }, + { 0x0013, 0x005e }, + { 0x0013, 0x005f }, + { 0x0013, 0x0060 }, + { 0x0013, 0x0061 }, + { 0x0010, 0x002f }, + { 0x0013, 0x0062 }, + { 0x0011, 0x0057 }, + { 0x0013, 0x0063 }, + { 0x0013, 0x0064 }, + { 0x0013, 0x0065 }, + { 0x0013, 0x0066 }, + { 0x0013, 0x0067 }, + { 0x0013, 0x0068 }, + { 0x0013, 0x0069 }, + { 0x0013, 0x006a }, + { 0x0013, 0x006b }, + { 0x0013, 0x006c }, + { 0x0013, 0x006d }, + { 0x0013, 0x006e }, + { 0x0013, 0x006f }, + { 0x0013, 0x0070 }, + { 0x0013, 0x0071 }, + { 0x0013, 0x0072 }, + { 0x0013, 0x0073 }, + { 0x0013, 0x0074 }, + { 0x0013, 0x0075 }, + { 0x0013, 0x0076 }, + { 0x0013, 0x0077 }, + { 0x0013, 0x0078 }, + { 0x0013, 0x0079 }, + { 0x0013, 0x007a }, + { 0x0013, 0x007b }, + { 0x0013, 0x007c }, + { 0x0013, 0x007d }, + { 0x0013, 0x007e }, + { 0x0013, 0x007f }, + { 0x0013, 0x0080 }, + { 0x0013, 0x0081 }, + { 0x0013, 0x0082 }, + { 0x0013, 0x0083 }, + { 0x0013, 0x0084 }, + { 0x0013, 0x0085 }, + { 0x0013, 0x0086 }, + { 0x0013, 0x0087 }, + { 0x0013, 0x0088 }, + { 0x0013, 0x0089 }, + { 0x0013, 0x008a }, + { 0x0013, 0x008b }, + { 0x0013, 0x008c }, + { 0x0013, 0x008d }, + { 0x0013, 0x008e }, + { 0x0013, 0x008f }, + { 0x0013, 0x0090 }, + { 0x0013, 0x0091 }, + { 0x0013, 0x0092 }, + { 0x0013, 0x0093 }, + { 0x0013, 0x0094 }, + { 0x0013, 0x0095 }, + { 0x0013, 0x0096 }, + { 0x0013, 0x0097 }, + { 0x0013, 0x0098 }, + { 0x0013, 0x0099 }, + { 0x0013, 0x009a }, + { 0x0013, 0x009b }, + { 0x0013, 0x009c }, + { 0x0013, 0x009d }, + { 0x0013, 0x009e }, + { 0x0013, 0x009f }, + { 0x0013, 0x00a0 }, + { 0x0013, 0x00a1 }, + { 0x0013, 0x00a2 }, + { 0x0013, 0x00a3 }, + { 0x0013, 0x00a4 }, + { 0x0013, 0x00a5 }, + { 0x0013, 0x00a6 }, + { 0x0013, 0x00a7 }, + { 0x0013, 0x00a8 }, + { 0x0013, 0x00a9 }, + { 0x0013, 0x00aa }, + { 0x0013, 0x00ab }, + { 0x0013, 0x00ac }, + { 0x0013, 0x00ad }, + { 0x0013, 0x00ae }, + { 0x0013, 0x00af }, + { 0x0013, 0x00b0 }, + { 0x0013, 0x00b1 }, + { 0x0013, 0x00b2 }, + { 0x0013, 0x00b3 }, + { 0x0013, 0x00b4 }, + { 0x0013, 0x00b5 }, + { 0x0013, 0x00b6 }, + { 0x0013, 0x00b7 }, + { 0x0013, 0x00b8 }, + { 0x0013, 0x00b9 }, + { 0x0013, 0x00ba }, + { 0x0013, 0x00bb }, + { 0x0013, 0x00bc }, + { 0x0013, 0x00bd }, + { 0x0013, 0x00be }, + { 0x0013, 0x00bf }, + { 0x0013, 0x00c0 }, + { 0x0013, 0x00c1 }, + { 0x0013, 0x00c2 }, + { 0x0013, 0x00c3 }, + { 0x0013, 0x00c4 }, + { 0x0013, 0x00c5 }, + { 0x0013, 0x00c6 }, + { 0x0013, 0x00c7 }, + { 0x0013, 0x00c8 }, + { 0x0013, 0x00c9 }, + { 0x0013, 0x00ca }, + { 0x0013, 0x00cb }, + { 0x0013, 0x00cc }, + { 0x0013, 0x00cd }, + { 0x0013, 0x00ce }, + { 0x0013, 0x00cf }, + { 0x0013, 0x00d0 }, + { 0x0013, 0x00d1 }, + { 0x0013, 0x00d2 }, + { 0x0013, 0x00d3 }, + { 0x0013, 0x00d4 }, + { 0x0013, 0x00d5 }, + { 0x0013, 0x00d6 }, + { 0x0013, 0x00d7 }, + { 0x0013, 0x00d8 }, + { 0x0013, 0x00d9 }, + { 0x0013, 0x00da }, + { 0x0013, 0x00db }, + { 0x0013, 0x00dc }, + { 0x0013, 0x00dd }, + { 0x0013, 0x00de }, + { 0x0013, 0x00df }, + { 0x0013, 0x00e0 }, + { 0x0013, 0x00e1 }, + { 0x0013, 0x00e2 }, + { 0x0013, 0x00e3 }, + { 0x0013, 0x00e4 }, + { 0x0013, 0x00e5 }, + { 0x0013, 0x00e6 }, + { 0x0013, 0x00e7 }, + { 0x0013, 0x00e8 }, + { 0x0013, 0x00e9 }, + { 0x0013, 0x00ea }, + { 0x0013, 0x00eb }, + { 0x0013, 0x00ec }, + { 0x0013, 0x00ed }, + { 0x0013, 0x00ee }, + { 0x0013, 0x00ef }, + { 0x0013, 0x00f0 }, + { 0x0013, 0x00f1 }, + { 0x0013, 0x00f2 }, + { 0x0013, 0x00f3 }, + { 0x0013, 0x00f4 }, + { 0x0013, 0x00f5 }, + { 0x0013, 0x00f6 }, + { 0x0013, 0x00f7 }, + { 0x0013, 0x00f8 }, + { 0x0013, 0x00f9 }, + { 0x0013, 0x00fa }, + { 0x0013, 0x00fb }, + { 0x0013, 0x00fc }, + { 0x0013, 0x00fd }, + { 0x0013, 0x00fe }, + { 0x0013, 0x00ff }, + { 0x0013, 0x0100 }, + { 0x0013, 0x0101 }, + { 0x0013, 0x0102 }, + { 0x0013, 0x0103 }, + { 0x0013, 0x0104 }, + { 0x0013, 0x0105 }, + { 0x0013, 0x0106 }, + { 0x0013, 0x0107 }, + { 0x0013, 0x0108 }, + { 0x0013, 0x0109 }, + { 0x0013, 0x010a }, + { 0x0013, 0x010b }, + { 0x0013, 0x010c }, + { 0x0013, 0x010d }, + { 0x0013, 0x010e }, + { 0x0013, 0x010f }, + { 0x0013, 0x0110 }, + { 0x0013, 0x0111 }, + { 0x0013, 0x0112 }, + { 0x0013, 0x0113 }, + { 0x0013, 0x0114 }, + { 0x0013, 0x0115 }, + { 0x0013, 0x0116 }, + { 0x0013, 0x0117 }, + { 0x0013, 0x0118 }, + { 0x0013, 0x0119 }, + { 0x0013, 0x011a }, + { 0x0013, 0x011b }, + { 0x0013, 0x011c }, + { 0x0013, 0x011d }, + { 0x0013, 0x011e }, + { 0x0013, 0x011f }, + { 0x0013, 0x0120 }, + { 0x0013, 0x0121 }, + { 0x0013, 0x0122 }, + { 0x0013, 0x0123 }, + { 0x0013, 0x0124 }, + { 0x0013, 0x0125 }, + { 0x0013, 0x0126 }, + { 0x0013, 0x0127 }, + { 0x0013, 0x0128 }, + { 0x0013, 0x0129 }, + { 0x0013, 0x012a }, + { 0x0013, 0x012b }, + { 0x0013, 0x012c }, + { 0x0013, 0x012d }, + { 0x0013, 0x012e }, + { 0x0013, 0x012f }, + { 0x0013, 0x0130 }, + { 0x0013, 0x0131 }, + { 0x0013, 0x0132 }, + { 0x0013, 0x0133 }, + { 0x0013, 0x0134 }, + { 0x0013, 0x0135 }, + { 0x0013, 0x0136 }, + { 0x0013, 0x0137 }, + { 0x0013, 0x0138 }, + { 0x0013, 0x0139 }, + { 0x0013, 0x013a }, + { 0x0013, 0x013b }, + { 0x0013, 0x013c }, + { 0x0013, 0x013d }, + { 0x0013, 0x013e }, + { 0x0013, 0x013f }, + { 0x0013, 0x0140 }, + { 0x0013, 0x0141 }, + { 0x0013, 0x0142 }, + { 0x0013, 0x0143 }, + { 0x0013, 0x0144 }, + { 0x0013, 0x0145 }, + { 0x0013, 0x0146 }, + { 0x0013, 0x0147 }, + { 0x0013, 0x0148 }, + { 0x0013, 0x0149 }, + { 0x0013, 0x014a }, + { 0x0013, 0x014b }, + { 0x0012, 0x00ab }, + { 0x0012, 0x00ac }, + { 0x0012, 0x00ad }, + }; + +const uint16_t c_aauiLCLDHuffEnc47[576][2] = + { + { 0x0002, 0x0003 }, + { 0x0003, 0x0003 }, + { 0x0005, 0x0005 }, + { 0x0006, 0x0004 }, + { 0x0008, 0x0006 }, + { 0x000a, 0x0007 }, + { 0x000c, 0x000b }, + { 0x000d, 0x000d }, + { 0x0010, 0x0041 }, + { 0x0013, 0x0000 }, + { 0x0013, 0x0001 }, + { 0x0013, 0x0002 }, + { 0x0013, 0x0003 }, + { 0x0013, 0x0004 }, + { 0x0013, 0x0005 }, + { 0x0013, 0x0006 }, + { 0x0013, 0x0007 }, + { 0x0013, 0x0008 }, + { 0x0013, 0x0009 }, + { 0x0013, 0x000a }, + { 0x0013, 0x000b }, + { 0x0013, 0x000c }, + { 0x0013, 0x000d }, + { 0x0013, 0x000e }, + { 0x0003, 0x0004 }, + { 0x0003, 0x0005 }, + { 0x0004, 0x0004 }, + { 0x0006, 0x0005 }, + { 0x0007, 0x0005 }, + { 0x0009, 0x0006 }, + { 0x000b, 0x0007 }, + { 0x000d, 0x000e }, + { 0x000f, 0x0025 }, + { 0x000f, 0x0026 }, + { 0x0012, 0x00f6 }, + { 0x0013, 0x000f }, + { 0x0013, 0x0010 }, + { 0x0013, 0x0011 }, + { 0x0013, 0x0012 }, + { 0x0013, 0x0013 }, + { 0x0013, 0x0014 }, + { 0x0013, 0x0015 }, + { 0x0013, 0x0016 }, + { 0x0013, 0x0017 }, + { 0x0013, 0x0018 }, + { 0x0013, 0x0019 }, + { 0x0013, 0x001a }, + { 0x0013, 0x001b }, + { 0x0005, 0x0006 }, + { 0x0004, 0x0005 }, + { 0x0005, 0x0007 }, + { 0x0006, 0x0006 }, + { 0x0008, 0x0007 }, + { 0x0009, 0x0007 }, + { 0x000b, 0x0008 }, + { 0x000d, 0x000f }, + { 0x000f, 0x0027 }, + { 0x0012, 0x00f7 }, + { 0x0013, 0x001c }, + { 0x0013, 0x001d }, + { 0x0013, 0x001e }, + { 0x0013, 0x001f }, + { 0x0013, 0x0020 }, + { 0x0013, 0x0021 }, + { 0x0013, 0x0022 }, + { 0x0013, 0x0023 }, + { 0x0013, 0x0024 }, + { 0x0013, 0x0025 }, + { 0x0013, 0x0026 }, + { 0x0013, 0x0027 }, + { 0x0013, 0x0028 }, + { 0x0013, 0x0029 }, + { 0x0006, 0x0007 }, + { 0x0006, 0x0008 }, + { 0x0006, 0x0009 }, + { 0x0007, 0x0006 }, + { 0x0009, 0x0008 }, + { 0x000a, 0x0008 }, + { 0x000c, 0x000c }, + { 0x000e, 0x0017 }, + { 0x0010, 0x0042 }, + { 0x0012, 0x00f8 }, + { 0x0013, 0x002a }, + { 0x0013, 0x002b }, + { 0x0013, 0x002c }, + { 0x0013, 0x002d }, + { 0x0013, 0x002e }, + { 0x0013, 0x002f }, + { 0x0013, 0x0030 }, + { 0x0013, 0x0031 }, + { 0x0013, 0x0032 }, + { 0x0013, 0x0033 }, + { 0x0013, 0x0034 }, + { 0x0013, 0x0035 }, + { 0x0013, 0x0036 }, + { 0x0013, 0x0037 }, + { 0x0008, 0x0008 }, + { 0x0007, 0x0007 }, + { 0x0008, 0x0009 }, + { 0x0009, 0x0009 }, + { 0x000a, 0x0009 }, + { 0x000b, 0x0009 }, + { 0x000d, 0x0010 }, + { 0x000f, 0x0028 }, + { 0x000f, 0x0029 }, + { 0x0011, 0x007f }, + { 0x0013, 0x0038 }, + { 0x0013, 0x0039 }, + { 0x0013, 0x003a }, + { 0x0013, 0x003b }, + { 0x0013, 0x003c }, + { 0x0013, 0x003d }, + { 0x0013, 0x003e }, + { 0x0013, 0x003f }, + { 0x0013, 0x0040 }, + { 0x0013, 0x0041 }, + { 0x0013, 0x0042 }, + { 0x0013, 0x0043 }, + { 0x0013, 0x0044 }, + { 0x0013, 0x0045 }, + { 0x000a, 0x000a }, + { 0x0009, 0x000a }, + { 0x0009, 0x000b }, + { 0x000a, 0x000b }, + { 0x000b, 0x000a }, + { 0x000d, 0x0011 }, + { 0x000f, 0x002a }, + { 0x0010, 0x0043 }, + { 0x0012, 0x00f9 }, + { 0x0013, 0x0046 }, + { 0x0013, 0x0047 }, + { 0x0013, 0x0048 }, + { 0x0013, 0x0049 }, + { 0x0013, 0x004a }, + { 0x0013, 0x004b }, + { 0x0013, 0x004c }, + { 0x0013, 0x004d }, + { 0x0013, 0x004e }, + { 0x0013, 0x004f }, + { 0x0013, 0x0050 }, + { 0x0013, 0x0051 }, + { 0x0013, 0x0052 }, + { 0x0013, 0x0053 }, + { 0x0013, 0x0054 }, + { 0x000b, 0x000b }, + { 0x000b, 0x000c }, + { 0x000b, 0x000d }, + { 0x000c, 0x000d }, + { 0x000d, 0x0012 }, + { 0x000e, 0x0018 }, + { 0x0010, 0x0044 }, + { 0x0013, 0x0055 }, + { 0x0013, 0x0056 }, + { 0x0013, 0x0057 }, + { 0x0013, 0x0058 }, + { 0x0013, 0x0059 }, + { 0x0013, 0x005a }, + { 0x0013, 0x005b }, + { 0x0013, 0x005c }, + { 0x0013, 0x005d }, + { 0x0013, 0x005e }, + { 0x0013, 0x005f }, + { 0x0013, 0x0060 }, + { 0x0013, 0x0061 }, + { 0x0013, 0x0062 }, + { 0x0013, 0x0063 }, + { 0x0013, 0x0064 }, + { 0x0013, 0x0065 }, + { 0x000e, 0x0019 }, + { 0x000d, 0x0013 }, + { 0x000d, 0x0014 }, + { 0x000d, 0x0015 }, + { 0x000f, 0x002b }, + { 0x0010, 0x0045 }, + { 0x0013, 0x0066 }, + { 0x0012, 0x00fa }, + { 0x0013, 0x0067 }, + { 0x0013, 0x0068 }, + { 0x0013, 0x0069 }, + { 0x0013, 0x006a }, + { 0x0013, 0x006b }, + { 0x0013, 0x006c }, + { 0x0013, 0x006d }, + { 0x0013, 0x006e }, + { 0x0013, 0x006f }, + { 0x0013, 0x0070 }, + { 0x0013, 0x0071 }, + { 0x0013, 0x0072 }, + { 0x0013, 0x0073 }, + { 0x0013, 0x0074 }, + { 0x0013, 0x0075 }, + { 0x0013, 0x0076 }, + { 0x0010, 0x0046 }, + { 0x000f, 0x002c }, + { 0x000f, 0x002d }, + { 0x0010, 0x0047 }, + { 0x0011, 0x0080 }, + { 0x0013, 0x0077 }, + { 0x0013, 0x0078 }, + { 0x0013, 0x0079 }, + { 0x0013, 0x007a }, + { 0x0013, 0x007b }, + { 0x0013, 0x007c }, + { 0x0013, 0x007d }, + { 0x0013, 0x007e }, + { 0x0013, 0x007f }, + { 0x0013, 0x0080 }, + { 0x0013, 0x0081 }, + { 0x0013, 0x0082 }, + { 0x0013, 0x0083 }, + { 0x0013, 0x0084 }, + { 0x0013, 0x0085 }, + { 0x0013, 0x0086 }, + { 0x0013, 0x0087 }, + { 0x0013, 0x0088 }, + { 0x0013, 0x0089 }, + { 0x0013, 0x008a }, + { 0x0010, 0x0048 }, + { 0x0010, 0x0049 }, + { 0x0011, 0x0081 }, + { 0x0013, 0x008b }, + { 0x0012, 0x00fb }, + { 0x0013, 0x008c }, + { 0x0013, 0x008d }, + { 0x0013, 0x008e }, + { 0x0013, 0x008f }, + { 0x0013, 0x0090 }, + { 0x0013, 0x0091 }, + { 0x0013, 0x0092 }, + { 0x0013, 0x0093 }, + { 0x0013, 0x0094 }, + { 0x0013, 0x0095 }, + { 0x0013, 0x0096 }, + { 0x0013, 0x0097 }, + { 0x0013, 0x0098 }, + { 0x0013, 0x0099 }, + { 0x0013, 0x009a }, + { 0x0013, 0x009b }, + { 0x0013, 0x009c }, + { 0x0013, 0x009d }, + { 0x0013, 0x009e }, + { 0x0013, 0x009f }, + { 0x0013, 0x00a0 }, + { 0x0012, 0x00fc }, + { 0x0013, 0x00a1 }, + { 0x0013, 0x00a2 }, + { 0x0013, 0x00a3 }, + { 0x0013, 0x00a4 }, + { 0x0013, 0x00a5 }, + { 0x0013, 0x00a6 }, + { 0x0013, 0x00a7 }, + { 0x0013, 0x00a8 }, + { 0x0013, 0x00a9 }, + { 0x0013, 0x00aa }, + { 0x0013, 0x00ab }, + { 0x0013, 0x00ac }, + { 0x0013, 0x00ad }, + { 0x0013, 0x00ae }, + { 0x0013, 0x00af }, + { 0x0013, 0x00b0 }, + { 0x0013, 0x00b1 }, + { 0x0013, 0x00b2 }, + { 0x0013, 0x00b3 }, + { 0x0013, 0x00b4 }, + { 0x0013, 0x00b5 }, + { 0x0013, 0x00b6 }, + { 0x0013, 0x00b7 }, + { 0x0013, 0x00b8 }, + { 0x0013, 0x00b9 }, + { 0x0013, 0x00ba }, + { 0x0013, 0x00bb }, + { 0x0013, 0x00bc }, + { 0x0013, 0x00bd }, + { 0x0013, 0x00be }, + { 0x0013, 0x00bf }, + { 0x0013, 0x00c0 }, + { 0x0013, 0x00c1 }, + { 0x0013, 0x00c2 }, + { 0x0013, 0x00c3 }, + { 0x0013, 0x00c4 }, + { 0x0013, 0x00c5 }, + { 0x0013, 0x00c6 }, + { 0x0013, 0x00c7 }, + { 0x0013, 0x00c8 }, + { 0x0013, 0x00c9 }, + { 0x0013, 0x00ca }, + { 0x0013, 0x00cb }, + { 0x0013, 0x00cc }, + { 0x0013, 0x00cd }, + { 0x0013, 0x00ce }, + { 0x0013, 0x00cf }, + { 0x0013, 0x00d0 }, + { 0x0013, 0x00d1 }, + { 0x0013, 0x00d2 }, + { 0x0013, 0x00d3 }, + { 0x0013, 0x00d4 }, + { 0x0013, 0x00d5 }, + { 0x0013, 0x00d6 }, + { 0x0013, 0x00d7 }, + { 0x0013, 0x00d8 }, + { 0x0013, 0x00d9 }, + { 0x0013, 0x00da }, + { 0x0013, 0x00db }, + { 0x0013, 0x00dc }, + { 0x0013, 0x00dd }, + { 0x0013, 0x00de }, + { 0x0013, 0x00df }, + { 0x0013, 0x00e0 }, + { 0x0013, 0x00e1 }, + { 0x0013, 0x00e2 }, + { 0x0013, 0x00e3 }, + { 0x0013, 0x00e4 }, + { 0x0013, 0x00e5 }, + { 0x0013, 0x00e6 }, + { 0x0013, 0x00e7 }, + { 0x0013, 0x00e8 }, + { 0x0013, 0x00e9 }, + { 0x0013, 0x00ea }, + { 0x0013, 0x00eb }, + { 0x0013, 0x00ec }, + { 0x0013, 0x00ed }, + { 0x0013, 0x00ee }, + { 0x0013, 0x00ef }, + { 0x0013, 0x00f0 }, + { 0x0013, 0x00f1 }, + { 0x0013, 0x00f2 }, + { 0x0013, 0x00f3 }, + { 0x0013, 0x00f4 }, + { 0x0013, 0x00f5 }, + { 0x0013, 0x00f6 }, + { 0x0013, 0x00f7 }, + { 0x0013, 0x00f8 }, + { 0x0013, 0x00f9 }, + { 0x0013, 0x00fa }, + { 0x0013, 0x00fb }, + { 0x0013, 0x00fc }, + { 0x0013, 0x00fd }, + { 0x0013, 0x00fe }, + { 0x0013, 0x00ff }, + { 0x0013, 0x0100 }, + { 0x0013, 0x0101 }, + { 0x0013, 0x0102 }, + { 0x0013, 0x0103 }, + { 0x0013, 0x0104 }, + { 0x0013, 0x0105 }, + { 0x0013, 0x0106 }, + { 0x0013, 0x0107 }, + { 0x0013, 0x0108 }, + { 0x0013, 0x0109 }, + { 0x0013, 0x010a }, + { 0x0013, 0x010b }, + { 0x0013, 0x010c }, + { 0x0013, 0x010d }, + { 0x0013, 0x010e }, + { 0x0013, 0x010f }, + { 0x0013, 0x0110 }, + { 0x0013, 0x0111 }, + { 0x0013, 0x0112 }, + { 0x0013, 0x0113 }, + { 0x0013, 0x0114 }, + { 0x0013, 0x0115 }, + { 0x0013, 0x0116 }, + { 0x0013, 0x0117 }, + { 0x0013, 0x0118 }, + { 0x0013, 0x0119 }, + { 0x0013, 0x011a }, + { 0x0013, 0x011b }, + { 0x0013, 0x011c }, + { 0x0013, 0x011d }, + { 0x0013, 0x011e }, + { 0x0013, 0x011f }, + { 0x0013, 0x0120 }, + { 0x0013, 0x0121 }, + { 0x0013, 0x0122 }, + { 0x0013, 0x0123 }, + { 0x0013, 0x0124 }, + { 0x0013, 0x0125 }, + { 0x0013, 0x0126 }, + { 0x0013, 0x0127 }, + { 0x0013, 0x0128 }, + { 0x0013, 0x0129 }, + { 0x0013, 0x012a }, + { 0x0013, 0x012b }, + { 0x0013, 0x012c }, + { 0x0013, 0x012d }, + { 0x0013, 0x012e }, + { 0x0013, 0x012f }, + { 0x0013, 0x0130 }, + { 0x0013, 0x0131 }, + { 0x0013, 0x0132 }, + { 0x0013, 0x0133 }, + { 0x0013, 0x0134 }, + { 0x0013, 0x0135 }, + { 0x0013, 0x0136 }, + { 0x0013, 0x0137 }, + { 0x0013, 0x0138 }, + { 0x0013, 0x0139 }, + { 0x0013, 0x013a }, + { 0x0013, 0x013b }, + { 0x0013, 0x013c }, + { 0x0013, 0x013d }, + { 0x0013, 0x013e }, + { 0x0013, 0x013f }, + { 0x0013, 0x0140 }, + { 0x0013, 0x0141 }, + { 0x0013, 0x0142 }, + { 0x0013, 0x0143 }, + { 0x0013, 0x0144 }, + { 0x0013, 0x0145 }, + { 0x0013, 0x0146 }, + { 0x0013, 0x0147 }, + { 0x0013, 0x0148 }, + { 0x0013, 0x0149 }, + { 0x0013, 0x014a }, + { 0x0013, 0x014b }, + { 0x0013, 0x014c }, + { 0x0013, 0x014d }, + { 0x0013, 0x014e }, + { 0x0013, 0x014f }, + { 0x0013, 0x0150 }, + { 0x0013, 0x0151 }, + { 0x0013, 0x0152 }, + { 0x0013, 0x0153 }, + { 0x0013, 0x0154 }, + { 0x0013, 0x0155 }, + { 0x0013, 0x0156 }, + { 0x0013, 0x0157 }, + { 0x0013, 0x0158 }, + { 0x0013, 0x0159 }, + { 0x0013, 0x015a }, + { 0x0013, 0x015b }, + { 0x0013, 0x015c }, + { 0x0013, 0x015d }, + { 0x0013, 0x015e }, + { 0x0013, 0x015f }, + { 0x0013, 0x0160 }, + { 0x0013, 0x0161 }, + { 0x0013, 0x0162 }, + { 0x0013, 0x0163 }, + { 0x0013, 0x0164 }, + { 0x0013, 0x0165 }, + { 0x0013, 0x0166 }, + { 0x0013, 0x0167 }, + { 0x0013, 0x0168 }, + { 0x0013, 0x0169 }, + { 0x0013, 0x016a }, + { 0x0013, 0x016b }, + { 0x0013, 0x016c }, + { 0x0013, 0x016d }, + { 0x0013, 0x016e }, + { 0x0013, 0x016f }, + { 0x0013, 0x0170 }, + { 0x0013, 0x0171 }, + { 0x0013, 0x0172 }, + { 0x0013, 0x0173 }, + { 0x0013, 0x0174 }, + { 0x0013, 0x0175 }, + { 0x0013, 0x0176 }, + { 0x0013, 0x0177 }, + { 0x0013, 0x0178 }, + { 0x0013, 0x0179 }, + { 0x0013, 0x017a }, + { 0x0013, 0x017b }, + { 0x0013, 0x017c }, + { 0x0013, 0x017d }, + { 0x0013, 0x017e }, + { 0x0013, 0x017f }, + { 0x0013, 0x0180 }, + { 0x0013, 0x0181 }, + { 0x0013, 0x0182 }, + { 0x0013, 0x0183 }, + { 0x0013, 0x0184 }, + { 0x0013, 0x0185 }, + { 0x0013, 0x0186 }, + { 0x0013, 0x0187 }, + { 0x0013, 0x0188 }, + { 0x0013, 0x0189 }, + { 0x0013, 0x018a }, + { 0x0013, 0x018b }, + { 0x0013, 0x018c }, + { 0x0013, 0x018d }, + { 0x0013, 0x018e }, + { 0x0013, 0x018f }, + { 0x0013, 0x0190 }, + { 0x0013, 0x0191 }, + { 0x0013, 0x0192 }, + { 0x0013, 0x0193 }, + { 0x0013, 0x0194 }, + { 0x0013, 0x0195 }, + { 0x0013, 0x0196 }, + { 0x0013, 0x0197 }, + { 0x0013, 0x0198 }, + { 0x0013, 0x0199 }, + { 0x0013, 0x019a }, + { 0x0013, 0x019b }, + { 0x0013, 0x019c }, + { 0x0013, 0x019d }, + { 0x0013, 0x019e }, + { 0x0013, 0x019f }, + { 0x0013, 0x01a0 }, + { 0x0013, 0x01a1 }, + { 0x0013, 0x01a2 }, + { 0x0013, 0x01a3 }, + { 0x0013, 0x01a4 }, + { 0x0013, 0x01a5 }, + { 0x0013, 0x01a6 }, + { 0x0013, 0x01a7 }, + { 0x0013, 0x01a8 }, + { 0x0013, 0x01a9 }, + { 0x0013, 0x01aa }, + { 0x0013, 0x01ab }, + { 0x0013, 0x01ac }, + { 0x0013, 0x01ad }, + { 0x0013, 0x01ae }, + { 0x0013, 0x01af }, + { 0x0013, 0x01b0 }, + { 0x0013, 0x01b1 }, + { 0x0013, 0x01b2 }, + { 0x0013, 0x01b3 }, + { 0x0013, 0x01b4 }, + { 0x0013, 0x01b5 }, + { 0x0013, 0x01b6 }, + { 0x0013, 0x01b7 }, + { 0x0013, 0x01b8 }, + { 0x0013, 0x01b9 }, + { 0x0013, 0x01ba }, + { 0x0013, 0x01bb }, + { 0x0013, 0x01bc }, + { 0x0013, 0x01bd }, + { 0x0013, 0x01be }, + { 0x0013, 0x01bf }, + { 0x0013, 0x01c0 }, + { 0x0013, 0x01c1 }, + { 0x0013, 0x01c2 }, + { 0x0013, 0x01c3 }, + { 0x0013, 0x01c4 }, + { 0x0013, 0x01c5 }, + { 0x0013, 0x01c6 }, + { 0x0013, 0x01c7 }, + { 0x0013, 0x01c8 }, + { 0x0013, 0x01c9 }, + { 0x0013, 0x01ca }, + { 0x0013, 0x01cb }, + { 0x0013, 0x01cc }, + { 0x0013, 0x01cd }, + { 0x0013, 0x01ce }, + { 0x0013, 0x01cf }, + { 0x0013, 0x01d0 }, + { 0x0013, 0x01d1 }, + { 0x0013, 0x01d2 }, + { 0x0013, 0x01d3 }, + { 0x0013, 0x01d4 }, + { 0x0013, 0x01d5 }, + { 0x0013, 0x01d6 }, + { 0x0013, 0x01d7 }, + { 0x0013, 0x01d8 }, + { 0x0013, 0x01d9 }, + { 0x0013, 0x01da }, + { 0x0013, 0x01db }, + { 0x0013, 0x01dc }, + { 0x0013, 0x01dd }, + { 0x0013, 0x01de }, + { 0x0013, 0x01df }, + { 0x0013, 0x01e0 }, + { 0x0013, 0x01e1 }, + { 0x0013, 0x01e2 }, + { 0x0013, 0x01e3 }, + { 0x0013, 0x01e4 }, + { 0x0013, 0x01e5 }, + { 0x0013, 0x01e6 }, + { 0x0013, 0x01e7 }, + { 0x0013, 0x01e8 }, + { 0x0013, 0x01e9 }, + { 0x0013, 0x01ea }, + { 0x0013, 0x01eb }, + { 0x0012, 0x00fd }, + }; + +const uint16_t c_aauiLCLDHuffEnc48[729][2] = + { + { 0x0002, 0x0003 }, + { 0x0003, 0x0003 }, + { 0x0005, 0x0006 }, + { 0x0006, 0x0006 }, + { 0x0008, 0x0006 }, + { 0x0009, 0x0007 }, + { 0x000b, 0x000b }, + { 0x000c, 0x000d }, + { 0x000f, 0x0030 }, + { 0x0010, 0x0055 }, + { 0x0012, 0x0136 }, + { 0x0013, 0x0000 }, + { 0x0013, 0x0001 }, + { 0x0013, 0x0002 }, + { 0x0013, 0x0003 }, + { 0x0013, 0x0004 }, + { 0x0013, 0x0005 }, + { 0x0013, 0x0006 }, + { 0x0013, 0x0007 }, + { 0x0013, 0x0008 }, + { 0x0013, 0x0009 }, + { 0x0013, 0x000a }, + { 0x0013, 0x000b }, + { 0x0013, 0x000c }, + { 0x0013, 0x000d }, + { 0x0013, 0x000e }, + { 0x0013, 0x000f }, + { 0x0003, 0x0004 }, + { 0x0003, 0x0005 }, + { 0x0005, 0x0007 }, + { 0x0006, 0x0007 }, + { 0x0007, 0x0007 }, + { 0x0008, 0x0007 }, + { 0x000a, 0x0008 }, + { 0x000c, 0x000e }, + { 0x000d, 0x0012 }, + { 0x000f, 0x0031 }, + { 0x0011, 0x00a0 }, + { 0x0013, 0x0010 }, + { 0x0013, 0x0011 }, + { 0x0013, 0x0012 }, + { 0x0013, 0x0013 }, + { 0x0013, 0x0014 }, + { 0x0013, 0x0015 }, + { 0x0013, 0x0016 }, + { 0x0013, 0x0017 }, + { 0x0013, 0x0018 }, + { 0x0013, 0x0019 }, + { 0x0013, 0x001a }, + { 0x0013, 0x001b }, + { 0x0013, 0x001c }, + { 0x0013, 0x001d }, + { 0x0013, 0x001e }, + { 0x0013, 0x001f }, + { 0x0005, 0x0008 }, + { 0x0004, 0x0005 }, + { 0x0005, 0x0009 }, + { 0x0006, 0x0008 }, + { 0x0007, 0x0008 }, + { 0x0008, 0x0008 }, + { 0x000a, 0x0009 }, + { 0x000c, 0x000f }, + { 0x000d, 0x0013 }, + { 0x000f, 0x0032 }, + { 0x0011, 0x00a1 }, + { 0x0013, 0x0020 }, + { 0x0013, 0x0021 }, + { 0x0013, 0x0022 }, + { 0x0013, 0x0023 }, + { 0x0013, 0x0024 }, + { 0x0013, 0x0025 }, + { 0x0013, 0x0026 }, + { 0x0013, 0x0027 }, + { 0x0013, 0x0028 }, + { 0x0013, 0x0029 }, + { 0x0013, 0x002a }, + { 0x0013, 0x002b }, + { 0x0013, 0x002c }, + { 0x0013, 0x002d }, + { 0x0013, 0x002e }, + { 0x0013, 0x002f }, + { 0x0006, 0x0009 }, + { 0x0006, 0x000a }, + { 0x0006, 0x000b }, + { 0x0007, 0x0009 }, + { 0x0008, 0x0009 }, + { 0x0009, 0x0008 }, + { 0x000b, 0x000c }, + { 0x000d, 0x0014 }, + { 0x000e, 0x001d }, + { 0x000f, 0x0033 }, + { 0x0012, 0x0137 }, + { 0x0013, 0x0030 }, + { 0x0013, 0x0031 }, + { 0x0013, 0x0032 }, + { 0x0013, 0x0033 }, + { 0x0013, 0x0034 }, + { 0x0013, 0x0035 }, + { 0x0013, 0x0036 }, + { 0x0013, 0x0037 }, + { 0x0013, 0x0038 }, + { 0x0013, 0x0039 }, + { 0x0013, 0x003a }, + { 0x0013, 0x003b }, + { 0x0013, 0x003c }, + { 0x0013, 0x003d }, + { 0x0013, 0x003e }, + { 0x0013, 0x003f }, + { 0x0008, 0x000a }, + { 0x0007, 0x000a }, + { 0x0007, 0x000b }, + { 0x0008, 0x000b }, + { 0x0009, 0x0009 }, + { 0x000a, 0x000a }, + { 0x000c, 0x0010 }, + { 0x000d, 0x0015 }, + { 0x000f, 0x0034 }, + { 0x0010, 0x0056 }, + { 0x0012, 0x0138 }, + { 0x0013, 0x0040 }, + { 0x0013, 0x0041 }, + { 0x0013, 0x0042 }, + { 0x0013, 0x0043 }, + { 0x0013, 0x0044 }, + { 0x0013, 0x0045 }, + { 0x0013, 0x0046 }, + { 0x0013, 0x0047 }, + { 0x0013, 0x0048 }, + { 0x0013, 0x0049 }, + { 0x0013, 0x004a }, + { 0x0013, 0x004b }, + { 0x0013, 0x004c }, + { 0x0013, 0x004d }, + { 0x0013, 0x004e }, + { 0x0013, 0x004f }, + { 0x0009, 0x000a }, + { 0x0008, 0x000c }, + { 0x0008, 0x000d }, + { 0x0009, 0x000b }, + { 0x000a, 0x000b }, + { 0x000c, 0x0011 }, + { 0x000d, 0x0016 }, + { 0x000e, 0x001e }, + { 0x0010, 0x0057 }, + { 0x0011, 0x00a2 }, + { 0x0011, 0x00a3 }, + { 0x0013, 0x0050 }, + { 0x0013, 0x0051 }, + { 0x0013, 0x0052 }, + { 0x0013, 0x0053 }, + { 0x0013, 0x0054 }, + { 0x0013, 0x0055 }, + { 0x0013, 0x0056 }, + { 0x0013, 0x0057 }, + { 0x0013, 0x0058 }, + { 0x0013, 0x0059 }, + { 0x0013, 0x005a }, + { 0x0013, 0x005b }, + { 0x0013, 0x005c }, + { 0x0013, 0x005d }, + { 0x0013, 0x005e }, + { 0x0013, 0x005f }, + { 0x000b, 0x000d }, + { 0x000a, 0x000c }, + { 0x000a, 0x000d }, + { 0x000b, 0x000e }, + { 0x000c, 0x0012 }, + { 0x000d, 0x0017 }, + { 0x000e, 0x001f }, + { 0x0010, 0x0058 }, + { 0x0012, 0x0139 }, + { 0x0011, 0x00a4 }, + { 0x0012, 0x013a }, + { 0x0013, 0x0060 }, + { 0x0013, 0x0061 }, + { 0x0013, 0x0062 }, + { 0x0013, 0x0063 }, + { 0x0013, 0x0064 }, + { 0x0013, 0x0065 }, + { 0x0013, 0x0066 }, + { 0x0013, 0x0067 }, + { 0x0013, 0x0068 }, + { 0x0013, 0x0069 }, + { 0x0013, 0x006a }, + { 0x0013, 0x006b }, + { 0x0013, 0x006c }, + { 0x0013, 0x006d }, + { 0x0013, 0x006e }, + { 0x0013, 0x006f }, + { 0x000c, 0x0013 }, + { 0x000b, 0x000f }, + { 0x000c, 0x0014 }, + { 0x000c, 0x0015 }, + { 0x000d, 0x0018 }, + { 0x000e, 0x0020 }, + { 0x000f, 0x0035 }, + { 0x0012, 0x013b }, + { 0x0013, 0x0070 }, + { 0x0013, 0x0071 }, + { 0x0013, 0x0072 }, + { 0x0013, 0x0073 }, + { 0x0013, 0x0074 }, + { 0x0013, 0x0075 }, + { 0x0013, 0x0076 }, + { 0x0013, 0x0077 }, + { 0x0013, 0x0078 }, + { 0x0013, 0x0079 }, + { 0x0013, 0x007a }, + { 0x0013, 0x007b }, + { 0x0013, 0x007c }, + { 0x0013, 0x007d }, + { 0x0013, 0x007e }, + { 0x0013, 0x007f }, + { 0x0013, 0x0080 }, + { 0x0013, 0x0081 }, + { 0x0013, 0x0082 }, + { 0x000e, 0x0021 }, + { 0x000d, 0x0019 }, + { 0x000e, 0x0022 }, + { 0x000e, 0x0023 }, + { 0x000f, 0x0036 }, + { 0x0010, 0x0059 }, + { 0x0011, 0x00a5 }, + { 0x0013, 0x0083 }, + { 0x0011, 0x00a6 }, + { 0x0012, 0x013c }, + { 0x0013, 0x0084 }, + { 0x0013, 0x0085 }, + { 0x0013, 0x0086 }, + { 0x0013, 0x0087 }, + { 0x0013, 0x0088 }, + { 0x0013, 0x0089 }, + { 0x0013, 0x008a }, + { 0x0013, 0x008b }, + { 0x0013, 0x008c }, + { 0x0013, 0x008d }, + { 0x0013, 0x008e }, + { 0x0013, 0x008f }, + { 0x0013, 0x0090 }, + { 0x0013, 0x0091 }, + { 0x0013, 0x0092 }, + { 0x0013, 0x0093 }, + { 0x0013, 0x0094 }, + { 0x0010, 0x005a }, + { 0x000f, 0x0037 }, + { 0x000f, 0x0038 }, + { 0x000f, 0x0039 }, + { 0x0010, 0x005b }, + { 0x0010, 0x005c }, + { 0x0013, 0x0095 }, + { 0x0011, 0x00a7 }, + { 0x0013, 0x0096 }, + { 0x0013, 0x0097 }, + { 0x0013, 0x0098 }, + { 0x0013, 0x0099 }, + { 0x0013, 0x009a }, + { 0x0013, 0x009b }, + { 0x0013, 0x009c }, + { 0x0013, 0x009d }, + { 0x0013, 0x009e }, + { 0x0013, 0x009f }, + { 0x0013, 0x00a0 }, + { 0x0013, 0x00a1 }, + { 0x0013, 0x00a2 }, + { 0x0013, 0x00a3 }, + { 0x0013, 0x00a4 }, + { 0x0013, 0x00a5 }, + { 0x0013, 0x00a6 }, + { 0x0013, 0x00a7 }, + { 0x0013, 0x00a8 }, + { 0x0010, 0x005d }, + { 0x0010, 0x005e }, + { 0x0013, 0x00a9 }, + { 0x0010, 0x005f }, + { 0x0013, 0x00aa }, + { 0x0012, 0x013d }, + { 0x0013, 0x00ab }, + { 0x0013, 0x00ac }, + { 0x0013, 0x00ad }, + { 0x0013, 0x00ae }, + { 0x0013, 0x00af }, + { 0x0013, 0x00b0 }, + { 0x0013, 0x00b1 }, + { 0x0013, 0x00b2 }, + { 0x0013, 0x00b3 }, + { 0x0013, 0x00b4 }, + { 0x0013, 0x00b5 }, + { 0x0013, 0x00b6 }, + { 0x0013, 0x00b7 }, + { 0x0013, 0x00b8 }, + { 0x0013, 0x00b9 }, + { 0x0013, 0x00ba }, + { 0x0013, 0x00bb }, + { 0x0013, 0x00bc }, + { 0x0013, 0x00bd }, + { 0x0013, 0x00be }, + { 0x0013, 0x00bf }, + { 0x0013, 0x00c0 }, + { 0x0011, 0x00a8 }, + { 0x0013, 0x00c1 }, + { 0x0011, 0x00a9 }, + { 0x0013, 0x00c2 }, + { 0x0013, 0x00c3 }, + { 0x0013, 0x00c4 }, + { 0x0013, 0x00c5 }, + { 0x0013, 0x00c6 }, + { 0x0013, 0x00c7 }, + { 0x0013, 0x00c8 }, + { 0x0013, 0x00c9 }, + { 0x0013, 0x00ca }, + { 0x0013, 0x00cb }, + { 0x0013, 0x00cc }, + { 0x0013, 0x00cd }, + { 0x0013, 0x00ce }, + { 0x0013, 0x00cf }, + { 0x0013, 0x00d0 }, + { 0x0013, 0x00d1 }, + { 0x0013, 0x00d2 }, + { 0x0013, 0x00d3 }, + { 0x0013, 0x00d4 }, + { 0x0013, 0x00d5 }, + { 0x0013, 0x00d6 }, + { 0x0013, 0x00d7 }, + { 0x0013, 0x00d8 }, + { 0x0013, 0x00d9 }, + { 0x0013, 0x00da }, + { 0x0012, 0x013e }, + { 0x0013, 0x00db }, + { 0x0013, 0x00dc }, + { 0x0013, 0x00dd }, + { 0x0013, 0x00de }, + { 0x0013, 0x00df }, + { 0x0013, 0x00e0 }, + { 0x0013, 0x00e1 }, + { 0x0013, 0x00e2 }, + { 0x0013, 0x00e3 }, + { 0x0013, 0x00e4 }, + { 0x0013, 0x00e5 }, + { 0x0013, 0x00e6 }, + { 0x0013, 0x00e7 }, + { 0x0013, 0x00e8 }, + { 0x0013, 0x00e9 }, + { 0x0013, 0x00ea }, + { 0x0013, 0x00eb }, + { 0x0013, 0x00ec }, + { 0x0013, 0x00ed }, + { 0x0013, 0x00ee }, + { 0x0013, 0x00ef }, + { 0x0013, 0x00f0 }, + { 0x0013, 0x00f1 }, + { 0x0013, 0x00f2 }, + { 0x0013, 0x00f3 }, + { 0x0013, 0x00f4 }, + { 0x0013, 0x00f5 }, + { 0x0013, 0x00f6 }, + { 0x0013, 0x00f7 }, + { 0x0013, 0x00f8 }, + { 0x0013, 0x00f9 }, + { 0x0013, 0x00fa }, + { 0x0013, 0x00fb }, + { 0x0013, 0x00fc }, + { 0x0013, 0x00fd }, + { 0x0013, 0x00fe }, + { 0x0013, 0x00ff }, + { 0x0013, 0x0100 }, + { 0x0013, 0x0101 }, + { 0x0013, 0x0102 }, + { 0x0013, 0x0103 }, + { 0x0013, 0x0104 }, + { 0x0013, 0x0105 }, + { 0x0013, 0x0106 }, + { 0x0013, 0x0107 }, + { 0x0013, 0x0108 }, + { 0x0013, 0x0109 }, + { 0x0013, 0x010a }, + { 0x0013, 0x010b }, + { 0x0013, 0x010c }, + { 0x0013, 0x010d }, + { 0x0013, 0x010e }, + { 0x0013, 0x010f }, + { 0x0013, 0x0110 }, + { 0x0013, 0x0111 }, + { 0x0013, 0x0112 }, + { 0x0013, 0x0113 }, + { 0x0013, 0x0114 }, + { 0x0013, 0x0115 }, + { 0x0013, 0x0116 }, + { 0x0013, 0x0117 }, + { 0x0013, 0x0118 }, + { 0x0013, 0x0119 }, + { 0x0013, 0x011a }, + { 0x0013, 0x011b }, + { 0x0013, 0x011c }, + { 0x0013, 0x011d }, + { 0x0013, 0x011e }, + { 0x0013, 0x011f }, + { 0x0013, 0x0120 }, + { 0x0013, 0x0121 }, + { 0x0013, 0x0122 }, + { 0x0013, 0x0123 }, + { 0x0013, 0x0124 }, + { 0x0013, 0x0125 }, + { 0x0013, 0x0126 }, + { 0x0013, 0x0127 }, + { 0x0013, 0x0128 }, + { 0x0013, 0x0129 }, + { 0x0013, 0x012a }, + { 0x0013, 0x012b }, + { 0x0013, 0x012c }, + { 0x0013, 0x012d }, + { 0x0013, 0x012e }, + { 0x0013, 0x012f }, + { 0x0013, 0x0130 }, + { 0x0013, 0x0131 }, + { 0x0013, 0x0132 }, + { 0x0013, 0x0133 }, + { 0x0013, 0x0134 }, + { 0x0013, 0x0135 }, + { 0x0013, 0x0136 }, + { 0x0013, 0x0137 }, + { 0x0013, 0x0138 }, + { 0x0013, 0x0139 }, + { 0x0013, 0x013a }, + { 0x0013, 0x013b }, + { 0x0013, 0x013c }, + { 0x0013, 0x013d }, + { 0x0013, 0x013e }, + { 0x0013, 0x013f }, + { 0x0013, 0x0140 }, + { 0x0013, 0x0141 }, + { 0x0013, 0x0142 }, + { 0x0013, 0x0143 }, + { 0x0013, 0x0144 }, + { 0x0013, 0x0145 }, + { 0x0013, 0x0146 }, + { 0x0013, 0x0147 }, + { 0x0013, 0x0148 }, + { 0x0013, 0x0149 }, + { 0x0013, 0x014a }, + { 0x0013, 0x014b }, + { 0x0013, 0x014c }, + { 0x0013, 0x014d }, + { 0x0013, 0x014e }, + { 0x0013, 0x014f }, + { 0x0013, 0x0150 }, + { 0x0013, 0x0151 }, + { 0x0013, 0x0152 }, + { 0x0013, 0x0153 }, + { 0x0013, 0x0154 }, + { 0x0013, 0x0155 }, + { 0x0013, 0x0156 }, + { 0x0013, 0x0157 }, + { 0x0013, 0x0158 }, + { 0x0013, 0x0159 }, + { 0x0013, 0x015a }, + { 0x0013, 0x015b }, + { 0x0013, 0x015c }, + { 0x0013, 0x015d }, + { 0x0013, 0x015e }, + { 0x0013, 0x015f }, + { 0x0013, 0x0160 }, + { 0x0013, 0x0161 }, + { 0x0013, 0x0162 }, + { 0x0013, 0x0163 }, + { 0x0013, 0x0164 }, + { 0x0013, 0x0165 }, + { 0x0013, 0x0166 }, + { 0x0013, 0x0167 }, + { 0x0013, 0x0168 }, + { 0x0013, 0x0169 }, + { 0x0013, 0x016a }, + { 0x0013, 0x016b }, + { 0x0013, 0x016c }, + { 0x0013, 0x016d }, + { 0x0013, 0x016e }, + { 0x0013, 0x016f }, + { 0x0013, 0x0170 }, + { 0x0013, 0x0171 }, + { 0x0013, 0x0172 }, + { 0x0013, 0x0173 }, + { 0x0013, 0x0174 }, + { 0x0013, 0x0175 }, + { 0x0013, 0x0176 }, + { 0x0013, 0x0177 }, + { 0x0013, 0x0178 }, + { 0x0013, 0x0179 }, + { 0x0013, 0x017a }, + { 0x0013, 0x017b }, + { 0x0013, 0x017c }, + { 0x0013, 0x017d }, + { 0x0013, 0x017e }, + { 0x0013, 0x017f }, + { 0x0013, 0x0180 }, + { 0x0013, 0x0181 }, + { 0x0013, 0x0182 }, + { 0x0013, 0x0183 }, + { 0x0013, 0x0184 }, + { 0x0013, 0x0185 }, + { 0x0013, 0x0186 }, + { 0x0013, 0x0187 }, + { 0x0013, 0x0188 }, + { 0x0013, 0x0189 }, + { 0x0013, 0x018a }, + { 0x0013, 0x018b }, + { 0x0013, 0x018c }, + { 0x0013, 0x018d }, + { 0x0013, 0x018e }, + { 0x0013, 0x018f }, + { 0x0013, 0x0190 }, + { 0x0013, 0x0191 }, + { 0x0013, 0x0192 }, + { 0x0013, 0x0193 }, + { 0x0013, 0x0194 }, + { 0x0013, 0x0195 }, + { 0x0013, 0x0196 }, + { 0x0013, 0x0197 }, + { 0x0013, 0x0198 }, + { 0x0013, 0x0199 }, + { 0x0013, 0x019a }, + { 0x0013, 0x019b }, + { 0x0013, 0x019c }, + { 0x0013, 0x019d }, + { 0x0013, 0x019e }, + { 0x0013, 0x019f }, + { 0x0013, 0x01a0 }, + { 0x0013, 0x01a1 }, + { 0x0013, 0x01a2 }, + { 0x0013, 0x01a3 }, + { 0x0013, 0x01a4 }, + { 0x0013, 0x01a5 }, + { 0x0013, 0x01a6 }, + { 0x0013, 0x01a7 }, + { 0x0013, 0x01a8 }, + { 0x0013, 0x01a9 }, + { 0x0013, 0x01aa }, + { 0x0013, 0x01ab }, + { 0x0013, 0x01ac }, + { 0x0013, 0x01ad }, + { 0x0013, 0x01ae }, + { 0x0013, 0x01af }, + { 0x0013, 0x01b0 }, + { 0x0013, 0x01b1 }, + { 0x0013, 0x01b2 }, + { 0x0013, 0x01b3 }, + { 0x0013, 0x01b4 }, + { 0x0013, 0x01b5 }, + { 0x0013, 0x01b6 }, + { 0x0013, 0x01b7 }, + { 0x0013, 0x01b8 }, + { 0x0013, 0x01b9 }, + { 0x0013, 0x01ba }, + { 0x0013, 0x01bb }, + { 0x0013, 0x01bc }, + { 0x0013, 0x01bd }, + { 0x0013, 0x01be }, + { 0x0013, 0x01bf }, + { 0x0013, 0x01c0 }, + { 0x0013, 0x01c1 }, + { 0x0013, 0x01c2 }, + { 0x0013, 0x01c3 }, + { 0x0013, 0x01c4 }, + { 0x0013, 0x01c5 }, + { 0x0013, 0x01c6 }, + { 0x0013, 0x01c7 }, + { 0x0013, 0x01c8 }, + { 0x0013, 0x01c9 }, + { 0x0013, 0x01ca }, + { 0x0013, 0x01cb }, + { 0x0013, 0x01cc }, + { 0x0013, 0x01cd }, + { 0x0013, 0x01ce }, + { 0x0013, 0x01cf }, + { 0x0013, 0x01d0 }, + { 0x0013, 0x01d1 }, + { 0x0013, 0x01d2 }, + { 0x0013, 0x01d3 }, + { 0x0013, 0x01d4 }, + { 0x0013, 0x01d5 }, + { 0x0013, 0x01d6 }, + { 0x0013, 0x01d7 }, + { 0x0013, 0x01d8 }, + { 0x0013, 0x01d9 }, + { 0x0013, 0x01da }, + { 0x0013, 0x01db }, + { 0x0013, 0x01dc }, + { 0x0013, 0x01dd }, + { 0x0013, 0x01de }, + { 0x0013, 0x01df }, + { 0x0013, 0x01e0 }, + { 0x0013, 0x01e1 }, + { 0x0013, 0x01e2 }, + { 0x0013, 0x01e3 }, + { 0x0013, 0x01e4 }, + { 0x0013, 0x01e5 }, + { 0x0013, 0x01e6 }, + { 0x0013, 0x01e7 }, + { 0x0013, 0x01e8 }, + { 0x0013, 0x01e9 }, + { 0x0013, 0x01ea }, + { 0x0013, 0x01eb }, + { 0x0013, 0x01ec }, + { 0x0013, 0x01ed }, + { 0x0013, 0x01ee }, + { 0x0013, 0x01ef }, + { 0x0013, 0x01f0 }, + { 0x0013, 0x01f1 }, + { 0x0013, 0x01f2 }, + { 0x0013, 0x01f3 }, + { 0x0013, 0x01f4 }, + { 0x0013, 0x01f5 }, + { 0x0013, 0x01f6 }, + { 0x0013, 0x01f7 }, + { 0x0013, 0x01f8 }, + { 0x0013, 0x01f9 }, + { 0x0013, 0x01fa }, + { 0x0013, 0x01fb }, + { 0x0013, 0x01fc }, + { 0x0013, 0x01fd }, + { 0x0013, 0x01fe }, + { 0x0013, 0x01ff }, + { 0x0013, 0x0200 }, + { 0x0013, 0x0201 }, + { 0x0013, 0x0202 }, + { 0x0013, 0x0203 }, + { 0x0013, 0x0204 }, + { 0x0013, 0x0205 }, + { 0x0013, 0x0206 }, + { 0x0013, 0x0207 }, + { 0x0013, 0x0208 }, + { 0x0013, 0x0209 }, + { 0x0013, 0x020a }, + { 0x0013, 0x020b }, + { 0x0013, 0x020c }, + { 0x0013, 0x020d }, + { 0x0013, 0x020e }, + { 0x0013, 0x020f }, + { 0x0013, 0x0210 }, + { 0x0013, 0x0211 }, + { 0x0013, 0x0212 }, + { 0x0013, 0x0213 }, + { 0x0013, 0x0214 }, + { 0x0013, 0x0215 }, + { 0x0013, 0x0216 }, + { 0x0013, 0x0217 }, + { 0x0013, 0x0218 }, + { 0x0013, 0x0219 }, + { 0x0013, 0x021a }, + { 0x0013, 0x021b }, + { 0x0013, 0x021c }, + { 0x0013, 0x021d }, + { 0x0013, 0x021e }, + { 0x0013, 0x021f }, + { 0x0013, 0x0220 }, + { 0x0013, 0x0221 }, + { 0x0013, 0x0222 }, + { 0x0013, 0x0223 }, + { 0x0013, 0x0224 }, + { 0x0013, 0x0225 }, + { 0x0013, 0x0226 }, + { 0x0013, 0x0227 }, + { 0x0013, 0x0228 }, + { 0x0013, 0x0229 }, + { 0x0013, 0x022a }, + { 0x0013, 0x022b }, + { 0x0013, 0x022c }, + { 0x0013, 0x022d }, + { 0x0013, 0x022e }, + { 0x0013, 0x022f }, + { 0x0013, 0x0230 }, + { 0x0013, 0x0231 }, + { 0x0013, 0x0232 }, + { 0x0013, 0x0233 }, + { 0x0013, 0x0234 }, + { 0x0013, 0x0235 }, + { 0x0013, 0x0236 }, + { 0x0013, 0x0237 }, + { 0x0013, 0x0238 }, + { 0x0013, 0x0239 }, + { 0x0013, 0x023a }, + { 0x0013, 0x023b }, + { 0x0013, 0x023c }, + { 0x0013, 0x023d }, + { 0x0013, 0x023e }, + { 0x0013, 0x023f }, + { 0x0013, 0x0240 }, + { 0x0013, 0x0241 }, + { 0x0013, 0x0242 }, + { 0x0013, 0x0243 }, + { 0x0013, 0x0244 }, + { 0x0013, 0x0245 }, + { 0x0013, 0x0246 }, + { 0x0013, 0x0247 }, + { 0x0013, 0x0248 }, + { 0x0013, 0x0249 }, + { 0x0013, 0x024a }, + { 0x0013, 0x024b }, + { 0x0013, 0x024c }, + { 0x0013, 0x024d }, + { 0x0013, 0x024e }, + { 0x0013, 0x024f }, + { 0x0013, 0x0250 }, + { 0x0013, 0x0251 }, + { 0x0013, 0x0252 }, + { 0x0013, 0x0253 }, + { 0x0013, 0x0254 }, + { 0x0013, 0x0255 }, + { 0x0013, 0x0256 }, + { 0x0013, 0x0257 }, + { 0x0013, 0x0258 }, + { 0x0013, 0x0259 }, + { 0x0013, 0x025a }, + { 0x0013, 0x025b }, + { 0x0013, 0x025c }, + { 0x0013, 0x025d }, + { 0x0013, 0x025e }, + { 0x0013, 0x025f }, + { 0x0013, 0x0260 }, + { 0x0013, 0x0261 }, + { 0x0013, 0x0262 }, + { 0x0013, 0x0263 }, + { 0x0013, 0x0264 }, + { 0x0013, 0x0265 }, + { 0x0013, 0x0266 }, + { 0x0013, 0x0267 }, + { 0x0013, 0x0268 }, + { 0x0013, 0x0269 }, + { 0x0013, 0x026a }, + { 0x0013, 0x026b }, + { 0x0012, 0x013f }, + + }; + +const uint16_t c_aauiLCLDHuffEnc49[729][2] = + { + { 0x0002, 0x0003 }, + { 0x0003, 0x0003 }, + { 0x0005, 0x0007 }, + { 0x0007, 0x000a }, + { 0x0008, 0x0009 }, + { 0x0008, 0x000a }, + { 0x0009, 0x0009 }, + { 0x000b, 0x000d }, + { 0x000d, 0x0014 }, + { 0x000d, 0x0015 }, + { 0x0010, 0x0052 }, + { 0x0011, 0x0098 }, + { 0x0013, 0x0000 }, + { 0x0013, 0x0001 }, + { 0x0013, 0x0002 }, + { 0x0013, 0x0003 }, + { 0x0013, 0x0004 }, + { 0x0013, 0x0005 }, + { 0x0013, 0x0006 }, + { 0x0013, 0x0007 }, + { 0x0013, 0x0008 }, + { 0x0013, 0x0009 }, + { 0x0013, 0x000a }, + { 0x0013, 0x000b }, + { 0x0013, 0x000c }, + { 0x0013, 0x000d }, + { 0x0013, 0x000e }, + { 0x0003, 0x0004 }, + { 0x0003, 0x0005 }, + { 0x0005, 0x0008 }, + { 0x0006, 0x000a }, + { 0x0007, 0x000b }, + { 0x0008, 0x000b }, + { 0x0008, 0x000c }, + { 0x000a, 0x000a }, + { 0x000b, 0x000e }, + { 0x000d, 0x0016 }, + { 0x000f, 0x0031 }, + { 0x0010, 0x0053 }, + { 0x0012, 0x012a }, + { 0x0013, 0x000f }, + { 0x0013, 0x0010 }, + { 0x0013, 0x0011 }, + { 0x0013, 0x0012 }, + { 0x0013, 0x0013 }, + { 0x0013, 0x0014 }, + { 0x0013, 0x0015 }, + { 0x0013, 0x0016 }, + { 0x0013, 0x0017 }, + { 0x0013, 0x0018 }, + { 0x0013, 0x0019 }, + { 0x0013, 0x001a }, + { 0x0013, 0x001b }, + { 0x0013, 0x001c }, + { 0x0005, 0x0009 }, + { 0x0005, 0x000a }, + { 0x0005, 0x000b }, + { 0x0006, 0x000b }, + { 0x0007, 0x000c }, + { 0x0008, 0x000d }, + { 0x0009, 0x000a }, + { 0x000a, 0x000b }, + { 0x000c, 0x000f }, + { 0x000d, 0x0017 }, + { 0x000f, 0x0032 }, + { 0x0010, 0x0054 }, + { 0x0013, 0x001d }, + { 0x0013, 0x001e }, + { 0x0013, 0x001f }, + { 0x0013, 0x0020 }, + { 0x0013, 0x0021 }, + { 0x0013, 0x0022 }, + { 0x0013, 0x0023 }, + { 0x0013, 0x0024 }, + { 0x0013, 0x0025 }, + { 0x0013, 0x0026 }, + { 0x0013, 0x0027 }, + { 0x0013, 0x0028 }, + { 0x0013, 0x0029 }, + { 0x0013, 0x002a }, + { 0x0013, 0x002b }, + { 0x0007, 0x000d }, + { 0x0006, 0x000c }, + { 0x0006, 0x000d }, + { 0x0007, 0x000e }, + { 0x0007, 0x000f }, + { 0x0008, 0x000e }, + { 0x0009, 0x000b }, + { 0x000b, 0x000f }, + { 0x000c, 0x0010 }, + { 0x000e, 0x001d }, + { 0x000f, 0x0033 }, + { 0x0011, 0x0099 }, + { 0x0013, 0x002c }, + { 0x0013, 0x002d }, + { 0x0013, 0x002e }, + { 0x0013, 0x002f }, + { 0x0013, 0x0030 }, + { 0x0013, 0x0031 }, + { 0x0013, 0x0032 }, + { 0x0013, 0x0033 }, + { 0x0013, 0x0034 }, + { 0x0013, 0x0035 }, + { 0x0013, 0x0036 }, + { 0x0013, 0x0037 }, + { 0x0013, 0x0038 }, + { 0x0013, 0x0039 }, + { 0x0013, 0x003a }, + { 0x0008, 0x000f }, + { 0x0007, 0x0010 }, + { 0x0007, 0x0011 }, + { 0x0007, 0x0012 }, + { 0x0008, 0x0010 }, + { 0x0009, 0x000c }, + { 0x000a, 0x000c }, + { 0x000c, 0x0011 }, + { 0x000d, 0x0018 }, + { 0x000e, 0x001e }, + { 0x0011, 0x009a }, + { 0x0011, 0x009b }, + { 0x0013, 0x003b }, + { 0x0013, 0x003c }, + { 0x0013, 0x003d }, + { 0x0013, 0x003e }, + { 0x0013, 0x003f }, + { 0x0013, 0x0040 }, + { 0x0013, 0x0041 }, + { 0x0013, 0x0042 }, + { 0x0013, 0x0043 }, + { 0x0013, 0x0044 }, + { 0x0013, 0x0045 }, + { 0x0013, 0x0046 }, + { 0x0013, 0x0047 }, + { 0x0013, 0x0048 }, + { 0x0013, 0x0049 }, + { 0x0008, 0x0011 }, + { 0x0007, 0x0013 }, + { 0x0008, 0x0012 }, + { 0x0008, 0x0013 }, + { 0x0009, 0x000d }, + { 0x000a, 0x000d }, + { 0x000b, 0x0010 }, + { 0x000c, 0x0012 }, + { 0x000e, 0x001f }, + { 0x000e, 0x0020 }, + { 0x0010, 0x0055 }, + { 0x0011, 0x009c }, + { 0x0013, 0x004a }, + { 0x0013, 0x004b }, + { 0x0013, 0x004c }, + { 0x0013, 0x004d }, + { 0x0013, 0x004e }, + { 0x0013, 0x004f }, + { 0x0013, 0x0050 }, + { 0x0013, 0x0051 }, + { 0x0013, 0x0052 }, + { 0x0013, 0x0053 }, + { 0x0013, 0x0054 }, + { 0x0013, 0x0055 }, + { 0x0013, 0x0056 }, + { 0x0013, 0x0057 }, + { 0x0013, 0x0058 }, + { 0x0009, 0x000e }, + { 0x0009, 0x000f }, + { 0x0009, 0x0010 }, + { 0x0009, 0x0011 }, + { 0x000a, 0x000e }, + { 0x000b, 0x0011 }, + { 0x000c, 0x0013 }, + { 0x000d, 0x0019 }, + { 0x000e, 0x0021 }, + { 0x0010, 0x0056 }, + { 0x0010, 0x0057 }, + { 0x0013, 0x0059 }, + { 0x0013, 0x005a }, + { 0x0013, 0x005b }, + { 0x0013, 0x005c }, + { 0x0013, 0x005d }, + { 0x0013, 0x005e }, + { 0x0013, 0x005f }, + { 0x0013, 0x0060 }, + { 0x0013, 0x0061 }, + { 0x0013, 0x0062 }, + { 0x0013, 0x0063 }, + { 0x0013, 0x0064 }, + { 0x0013, 0x0065 }, + { 0x0013, 0x0066 }, + { 0x0013, 0x0067 }, + { 0x0013, 0x0068 }, + { 0x000b, 0x0012 }, + { 0x000a, 0x000f }, + { 0x000a, 0x0010 }, + { 0x000a, 0x0011 }, + { 0x000c, 0x0014 }, + { 0x000c, 0x0015 }, + { 0x000d, 0x001a }, + { 0x000e, 0x0022 }, + { 0x0010, 0x0058 }, + { 0x0010, 0x0059 }, + { 0x0013, 0x0069 }, + { 0x0013, 0x006a }, + { 0x0013, 0x006b }, + { 0x0013, 0x006c }, + { 0x0013, 0x006d }, + { 0x0013, 0x006e }, + { 0x0013, 0x006f }, + { 0x0013, 0x0070 }, + { 0x0013, 0x0071 }, + { 0x0013, 0x0072 }, + { 0x0013, 0x0073 }, + { 0x0013, 0x0074 }, + { 0x0013, 0x0075 }, + { 0x0013, 0x0076 }, + { 0x0013, 0x0077 }, + { 0x0013, 0x0078 }, + { 0x0013, 0x0079 }, + { 0x000c, 0x0016 }, + { 0x000b, 0x0013 }, + { 0x000c, 0x0017 }, + { 0x000c, 0x0018 }, + { 0x000c, 0x0019 }, + { 0x000e, 0x0023 }, + { 0x000e, 0x0024 }, + { 0x000f, 0x0034 }, + { 0x0010, 0x005a }, + { 0x0011, 0x009d }, + { 0x0013, 0x007a }, + { 0x0013, 0x007b }, + { 0x0013, 0x007c }, + { 0x0013, 0x007d }, + { 0x0013, 0x007e }, + { 0x0013, 0x007f }, + { 0x0013, 0x0080 }, + { 0x0013, 0x0081 }, + { 0x0013, 0x0082 }, + { 0x0013, 0x0083 }, + { 0x0013, 0x0084 }, + { 0x0013, 0x0085 }, + { 0x0013, 0x0086 }, + { 0x0013, 0x0087 }, + { 0x0013, 0x0088 }, + { 0x0013, 0x0089 }, + { 0x0013, 0x008a }, + { 0x000e, 0x0025 }, + { 0x000d, 0x001b }, + { 0x000d, 0x001c }, + { 0x000d, 0x001d }, + { 0x000e, 0x0026 }, + { 0x000f, 0x0035 }, + { 0x0010, 0x005b }, + { 0x0011, 0x009e }, + { 0x0011, 0x009f }, + { 0x0012, 0x012b }, + { 0x0013, 0x008b }, + { 0x0013, 0x008c }, + { 0x0013, 0x008d }, + { 0x0013, 0x008e }, + { 0x0013, 0x008f }, + { 0x0013, 0x0090 }, + { 0x0013, 0x0091 }, + { 0x0013, 0x0092 }, + { 0x0013, 0x0093 }, + { 0x0013, 0x0094 }, + { 0x0013, 0x0095 }, + { 0x0013, 0x0096 }, + { 0x0013, 0x0097 }, + { 0x0013, 0x0098 }, + { 0x0013, 0x0099 }, + { 0x0013, 0x009a }, + { 0x0013, 0x009b }, + { 0x0010, 0x005c }, + { 0x000f, 0x0036 }, + { 0x000e, 0x0027 }, + { 0x000f, 0x0037 }, + { 0x000f, 0x0038 }, + { 0x0010, 0x005d }, + { 0x0011, 0x00a0 }, + { 0x0013, 0x009c }, + { 0x0012, 0x012c }, + { 0x0013, 0x009d }, + { 0x0013, 0x009e }, + { 0x0013, 0x009f }, + { 0x0013, 0x00a0 }, + { 0x0013, 0x00a1 }, + { 0x0013, 0x00a2 }, + { 0x0013, 0x00a3 }, + { 0x0013, 0x00a4 }, + { 0x0013, 0x00a5 }, + { 0x0013, 0x00a6 }, + { 0x0013, 0x00a7 }, + { 0x0013, 0x00a8 }, + { 0x0013, 0x00a9 }, + { 0x0013, 0x00aa }, + { 0x0013, 0x00ab }, + { 0x0013, 0x00ac }, + { 0x0013, 0x00ad }, + { 0x0013, 0x00ae }, + { 0x0010, 0x005e }, + { 0x000f, 0x0039 }, + { 0x0010, 0x005f }, + { 0x0010, 0x0060 }, + { 0x0011, 0x00a1 }, + { 0x0010, 0x0061 }, + { 0x0013, 0x00af }, + { 0x0013, 0x00b0 }, + { 0x0012, 0x012d }, + { 0x0013, 0x00b1 }, + { 0x0013, 0x00b2 }, + { 0x0013, 0x00b3 }, + { 0x0013, 0x00b4 }, + { 0x0013, 0x00b5 }, + { 0x0013, 0x00b6 }, + { 0x0013, 0x00b7 }, + { 0x0013, 0x00b8 }, + { 0x0013, 0x00b9 }, + { 0x0013, 0x00ba }, + { 0x0013, 0x00bb }, + { 0x0013, 0x00bc }, + { 0x0013, 0x00bd }, + { 0x0013, 0x00be }, + { 0x0013, 0x00bf }, + { 0x0013, 0x00c0 }, + { 0x0013, 0x00c1 }, + { 0x0013, 0x00c2 }, + { 0x0012, 0x012e }, + { 0x0011, 0x00a2 }, + { 0x0011, 0x00a3 }, + { 0x0013, 0x00c3 }, + { 0x0013, 0x00c4 }, + { 0x0013, 0x00c5 }, + { 0x0013, 0x00c6 }, + { 0x0013, 0x00c7 }, + { 0x0013, 0x00c8 }, + { 0x0013, 0x00c9 }, + { 0x0013, 0x00ca }, + { 0x0013, 0x00cb }, + { 0x0013, 0x00cc }, + { 0x0013, 0x00cd }, + { 0x0013, 0x00ce }, + { 0x0013, 0x00cf }, + { 0x0013, 0x00d0 }, + { 0x0013, 0x00d1 }, + { 0x0013, 0x00d2 }, + { 0x0013, 0x00d3 }, + { 0x0013, 0x00d4 }, + { 0x0013, 0x00d5 }, + { 0x0013, 0x00d6 }, + { 0x0013, 0x00d7 }, + { 0x0013, 0x00d8 }, + { 0x0013, 0x00d9 }, + { 0x0013, 0x00da }, + { 0x0013, 0x00db }, + { 0x0013, 0x00dc }, + { 0x0013, 0x00dd }, + { 0x0013, 0x00de }, + { 0x0013, 0x00df }, + { 0x0012, 0x012f }, + { 0x0013, 0x00e0 }, + { 0x0013, 0x00e1 }, + { 0x0013, 0x00e2 }, + { 0x0013, 0x00e3 }, + { 0x0013, 0x00e4 }, + { 0x0013, 0x00e5 }, + { 0x0013, 0x00e6 }, + { 0x0013, 0x00e7 }, + { 0x0013, 0x00e8 }, + { 0x0013, 0x00e9 }, + { 0x0013, 0x00ea }, + { 0x0013, 0x00eb }, + { 0x0013, 0x00ec }, + { 0x0013, 0x00ed }, + { 0x0013, 0x00ee }, + { 0x0013, 0x00ef }, + { 0x0013, 0x00f0 }, + { 0x0013, 0x00f1 }, + { 0x0013, 0x00f2 }, + { 0x0013, 0x00f3 }, + { 0x0013, 0x00f4 }, + { 0x0013, 0x00f5 }, + { 0x0013, 0x00f6 }, + { 0x0013, 0x00f7 }, + { 0x0013, 0x00f8 }, + { 0x0013, 0x00f9 }, + { 0x0013, 0x00fa }, + { 0x0013, 0x00fb }, + { 0x0013, 0x00fc }, + { 0x0013, 0x00fd }, + { 0x0013, 0x00fe }, + { 0x0013, 0x00ff }, + { 0x0013, 0x0100 }, + { 0x0013, 0x0101 }, + { 0x0013, 0x0102 }, + { 0x0013, 0x0103 }, + { 0x0013, 0x0104 }, + { 0x0013, 0x0105 }, + { 0x0013, 0x0106 }, + { 0x0013, 0x0107 }, + { 0x0013, 0x0108 }, + { 0x0013, 0x0109 }, + { 0x0013, 0x010a }, + { 0x0013, 0x010b }, + { 0x0013, 0x010c }, + { 0x0013, 0x010d }, + { 0x0013, 0x010e }, + { 0x0013, 0x010f }, + { 0x0013, 0x0110 }, + { 0x0013, 0x0111 }, + { 0x0013, 0x0112 }, + { 0x0013, 0x0113 }, + { 0x0013, 0x0114 }, + { 0x0013, 0x0115 }, + { 0x0013, 0x0116 }, + { 0x0013, 0x0117 }, + { 0x0013, 0x0118 }, + { 0x0013, 0x0119 }, + { 0x0013, 0x011a }, + { 0x0013, 0x011b }, + { 0x0013, 0x011c }, + { 0x0013, 0x011d }, + { 0x0013, 0x011e }, + { 0x0013, 0x011f }, + { 0x0013, 0x0120 }, + { 0x0013, 0x0121 }, + { 0x0013, 0x0122 }, + { 0x0013, 0x0123 }, + { 0x0013, 0x0124 }, + { 0x0013, 0x0125 }, + { 0x0013, 0x0126 }, + { 0x0013, 0x0127 }, + { 0x0013, 0x0128 }, + { 0x0013, 0x0129 }, + { 0x0013, 0x012a }, + { 0x0013, 0x012b }, + { 0x0013, 0x012c }, + { 0x0013, 0x012d }, + { 0x0013, 0x012e }, + { 0x0013, 0x012f }, + { 0x0013, 0x0130 }, + { 0x0013, 0x0131 }, + { 0x0013, 0x0132 }, + { 0x0013, 0x0133 }, + { 0x0013, 0x0134 }, + { 0x0013, 0x0135 }, + { 0x0013, 0x0136 }, + { 0x0013, 0x0137 }, + { 0x0013, 0x0138 }, + { 0x0013, 0x0139 }, + { 0x0013, 0x013a }, + { 0x0013, 0x013b }, + { 0x0013, 0x013c }, + { 0x0013, 0x013d }, + { 0x0013, 0x013e }, + { 0x0013, 0x013f }, + { 0x0013, 0x0140 }, + { 0x0013, 0x0141 }, + { 0x0013, 0x0142 }, + { 0x0013, 0x0143 }, + { 0x0013, 0x0144 }, + { 0x0013, 0x0145 }, + { 0x0013, 0x0146 }, + { 0x0013, 0x0147 }, + { 0x0013, 0x0148 }, + { 0x0013, 0x0149 }, + { 0x0013, 0x014a }, + { 0x0013, 0x014b }, + { 0x0013, 0x014c }, + { 0x0013, 0x014d }, + { 0x0013, 0x014e }, + { 0x0013, 0x014f }, + { 0x0013, 0x0150 }, + { 0x0013, 0x0151 }, + { 0x0013, 0x0152 }, + { 0x0013, 0x0153 }, + { 0x0013, 0x0154 }, + { 0x0013, 0x0155 }, + { 0x0013, 0x0156 }, + { 0x0013, 0x0157 }, + { 0x0013, 0x0158 }, + { 0x0013, 0x0159 }, + { 0x0013, 0x015a }, + { 0x0013, 0x015b }, + { 0x0013, 0x015c }, + { 0x0013, 0x015d }, + { 0x0013, 0x015e }, + { 0x0013, 0x015f }, + { 0x0013, 0x0160 }, + { 0x0013, 0x0161 }, + { 0x0013, 0x0162 }, + { 0x0013, 0x0163 }, + { 0x0013, 0x0164 }, + { 0x0013, 0x0165 }, + { 0x0013, 0x0166 }, + { 0x0013, 0x0167 }, + { 0x0013, 0x0168 }, + { 0x0013, 0x0169 }, + { 0x0013, 0x016a }, + { 0x0013, 0x016b }, + { 0x0013, 0x016c }, + { 0x0013, 0x016d }, + { 0x0013, 0x016e }, + { 0x0013, 0x016f }, + { 0x0013, 0x0170 }, + { 0x0013, 0x0171 }, + { 0x0013, 0x0172 }, + { 0x0013, 0x0173 }, + { 0x0013, 0x0174 }, + { 0x0013, 0x0175 }, + { 0x0013, 0x0176 }, + { 0x0013, 0x0177 }, + { 0x0013, 0x0178 }, + { 0x0013, 0x0179 }, + { 0x0013, 0x017a }, + { 0x0013, 0x017b }, + { 0x0013, 0x017c }, + { 0x0013, 0x017d }, + { 0x0013, 0x017e }, + { 0x0013, 0x017f }, + { 0x0013, 0x0180 }, + { 0x0013, 0x0181 }, + { 0x0013, 0x0182 }, + { 0x0013, 0x0183 }, + { 0x0013, 0x0184 }, + { 0x0013, 0x0185 }, + { 0x0013, 0x0186 }, + { 0x0013, 0x0187 }, + { 0x0013, 0x0188 }, + { 0x0013, 0x0189 }, + { 0x0013, 0x018a }, + { 0x0013, 0x018b }, + { 0x0013, 0x018c }, + { 0x0013, 0x018d }, + { 0x0013, 0x018e }, + { 0x0013, 0x018f }, + { 0x0013, 0x0190 }, + { 0x0013, 0x0191 }, + { 0x0013, 0x0192 }, + { 0x0013, 0x0193 }, + { 0x0013, 0x0194 }, + { 0x0013, 0x0195 }, + { 0x0013, 0x0196 }, + { 0x0013, 0x0197 }, + { 0x0013, 0x0198 }, + { 0x0013, 0x0199 }, + { 0x0013, 0x019a }, + { 0x0013, 0x019b }, + { 0x0013, 0x019c }, + { 0x0013, 0x019d }, + { 0x0013, 0x019e }, + { 0x0013, 0x019f }, + { 0x0013, 0x01a0 }, + { 0x0013, 0x01a1 }, + { 0x0013, 0x01a2 }, + { 0x0013, 0x01a3 }, + { 0x0013, 0x01a4 }, + { 0x0013, 0x01a5 }, + { 0x0013, 0x01a6 }, + { 0x0013, 0x01a7 }, + { 0x0013, 0x01a8 }, + { 0x0013, 0x01a9 }, + { 0x0013, 0x01aa }, + { 0x0013, 0x01ab }, + { 0x0013, 0x01ac }, + { 0x0013, 0x01ad }, + { 0x0013, 0x01ae }, + { 0x0013, 0x01af }, + { 0x0013, 0x01b0 }, + { 0x0013, 0x01b1 }, + { 0x0013, 0x01b2 }, + { 0x0013, 0x01b3 }, + { 0x0013, 0x01b4 }, + { 0x0013, 0x01b5 }, + { 0x0013, 0x01b6 }, + { 0x0013, 0x01b7 }, + { 0x0013, 0x01b8 }, + { 0x0013, 0x01b9 }, + { 0x0013, 0x01ba }, + { 0x0013, 0x01bb }, + { 0x0013, 0x01bc }, + { 0x0013, 0x01bd }, + { 0x0013, 0x01be }, + { 0x0013, 0x01bf }, + { 0x0013, 0x01c0 }, + { 0x0013, 0x01c1 }, + { 0x0013, 0x01c2 }, + { 0x0013, 0x01c3 }, + { 0x0013, 0x01c4 }, + { 0x0013, 0x01c5 }, + { 0x0013, 0x01c6 }, + { 0x0013, 0x01c7 }, + { 0x0013, 0x01c8 }, + { 0x0013, 0x01c9 }, + { 0x0013, 0x01ca }, + { 0x0013, 0x01cb }, + { 0x0013, 0x01cc }, + { 0x0013, 0x01cd }, + { 0x0013, 0x01ce }, + { 0x0013, 0x01cf }, + { 0x0013, 0x01d0 }, + { 0x0013, 0x01d1 }, + { 0x0013, 0x01d2 }, + { 0x0013, 0x01d3 }, + { 0x0013, 0x01d4 }, + { 0x0013, 0x01d5 }, + { 0x0013, 0x01d6 }, + { 0x0013, 0x01d7 }, + { 0x0013, 0x01d8 }, + { 0x0013, 0x01d9 }, + { 0x0013, 0x01da }, + { 0x0013, 0x01db }, + { 0x0013, 0x01dc }, + { 0x0013, 0x01dd }, + { 0x0013, 0x01de }, + { 0x0013, 0x01df }, + { 0x0013, 0x01e0 }, + { 0x0013, 0x01e1 }, + { 0x0013, 0x01e2 }, + { 0x0013, 0x01e3 }, + { 0x0013, 0x01e4 }, + { 0x0013, 0x01e5 }, + { 0x0013, 0x01e6 }, + { 0x0013, 0x01e7 }, + { 0x0013, 0x01e8 }, + { 0x0013, 0x01e9 }, + { 0x0013, 0x01ea }, + { 0x0013, 0x01eb }, + { 0x0013, 0x01ec }, + { 0x0013, 0x01ed }, + { 0x0013, 0x01ee }, + { 0x0013, 0x01ef }, + { 0x0013, 0x01f0 }, + { 0x0013, 0x01f1 }, + { 0x0013, 0x01f2 }, + { 0x0013, 0x01f3 }, + { 0x0013, 0x01f4 }, + { 0x0013, 0x01f5 }, + { 0x0013, 0x01f6 }, + { 0x0013, 0x01f7 }, + { 0x0013, 0x01f8 }, + { 0x0013, 0x01f9 }, + { 0x0013, 0x01fa }, + { 0x0013, 0x01fb }, + { 0x0013, 0x01fc }, + { 0x0013, 0x01fd }, + { 0x0013, 0x01fe }, + { 0x0013, 0x01ff }, + { 0x0013, 0x0200 }, + { 0x0013, 0x0201 }, + { 0x0013, 0x0202 }, + { 0x0013, 0x0203 }, + { 0x0013, 0x0204 }, + { 0x0013, 0x0205 }, + { 0x0013, 0x0206 }, + { 0x0013, 0x0207 }, + { 0x0013, 0x0208 }, + { 0x0013, 0x0209 }, + { 0x0013, 0x020a }, + { 0x0013, 0x020b }, + { 0x0013, 0x020c }, + { 0x0013, 0x020d }, + { 0x0013, 0x020e }, + { 0x0013, 0x020f }, + { 0x0013, 0x0210 }, + { 0x0013, 0x0211 }, + { 0x0013, 0x0212 }, + { 0x0013, 0x0213 }, + { 0x0013, 0x0214 }, + { 0x0013, 0x0215 }, + { 0x0013, 0x0216 }, + { 0x0013, 0x0217 }, + { 0x0013, 0x0218 }, + { 0x0013, 0x0219 }, + { 0x0013, 0x021a }, + { 0x0013, 0x021b }, + { 0x0013, 0x021c }, + { 0x0013, 0x021d }, + { 0x0013, 0x021e }, + { 0x0013, 0x021f }, + { 0x0013, 0x0220 }, + { 0x0013, 0x0221 }, + { 0x0013, 0x0222 }, + { 0x0013, 0x0223 }, + { 0x0013, 0x0224 }, + { 0x0013, 0x0225 }, + { 0x0013, 0x0226 }, + { 0x0013, 0x0227 }, + { 0x0013, 0x0228 }, + { 0x0013, 0x0229 }, + { 0x0013, 0x022a }, + { 0x0013, 0x022b }, + { 0x0013, 0x022c }, + { 0x0013, 0x022d }, + { 0x0013, 0x022e }, + { 0x0013, 0x022f }, + { 0x0013, 0x0230 }, + { 0x0013, 0x0231 }, + { 0x0013, 0x0232 }, + { 0x0013, 0x0233 }, + { 0x0013, 0x0234 }, + { 0x0013, 0x0235 }, + { 0x0013, 0x0236 }, + { 0x0013, 0x0237 }, + { 0x0013, 0x0238 }, + { 0x0013, 0x0239 }, + { 0x0013, 0x023a }, + { 0x0013, 0x023b }, + { 0x0013, 0x023c }, + { 0x0013, 0x023d }, + { 0x0013, 0x023e }, + { 0x0013, 0x023f }, + { 0x0013, 0x0240 }, + { 0x0013, 0x0241 }, + { 0x0013, 0x0242 }, + { 0x0013, 0x0243 }, + { 0x0013, 0x0244 }, + { 0x0013, 0x0245 }, + { 0x0013, 0x0246 }, + { 0x0013, 0x0247 }, + { 0x0013, 0x0248 }, + { 0x0013, 0x0249 }, + { 0x0013, 0x024a }, + { 0x0013, 0x024b }, + { 0x0013, 0x024c }, + { 0x0013, 0x024d }, + { 0x0013, 0x024e }, + { 0x0013, 0x024f }, + { 0x0013, 0x0250 }, + { 0x0013, 0x0251 }, + { 0x0013, 0x0252 }, + { 0x0013, 0x0253 }, + + }; + +const uint16_t c_aauiLCLDHuffEnc50[28][2] = + { + { 0x0002, 0x0001 }, + { 0x0002, 0x0002 }, + { 0x0002, 0x0003 }, + { 0x0003, 0x0001 }, + { 0x0004, 0x0001 }, + { 0x0005, 0x0001 }, + { 0x0006, 0x0001 }, + { 0x0007, 0x0001 }, + { 0x0008, 0x0001 }, + { 0x0009, 0x0001 }, + { 0x000a, 0x0001 }, + { 0x000b, 0x0001 }, + { 0x000c, 0x0001 }, + { 0x000d, 0x0001 }, + { 0x000e, 0x0001 }, + { 0x000f, 0x0001 }, + { 0x0011, 0x0003 }, + { 0x0012, 0x0005 }, + { 0x0013, 0x0000 }, + { 0x0013, 0x0001 }, + { 0x0013, 0x0002 }, + { 0x0013, 0x0003 }, + { 0x0013, 0x0004 }, + { 0x0013, 0x0005 }, + { 0x0013, 0x0006 }, + { 0x0013, 0x0007 }, + { 0x0013, 0x0008 }, + { 0x0013, 0x0009 }, + + }; + +const uint16_t c_aauiLCLDHuffEnc51[29][2] = + { + { 0x0002, 0x0002 }, + { 0x0002, 0x0003 }, + { 0x0003, 0x0002 }, + { 0x0003, 0x0003 }, + { 0x0004, 0x0001 }, + { 0x0004, 0x0002 }, + { 0x0004, 0x0003 }, + { 0x0005, 0x0001 }, + { 0x0006, 0x0001 }, + { 0x0007, 0x0001 }, + { 0x0008, 0x0001 }, + { 0x0009, 0x0001 }, + { 0x000a, 0x0001 }, + { 0x000b, 0x0001 }, + { 0x000c, 0x0001 }, + { 0x000d, 0x0001 }, + { 0x000e, 0x0001 }, + { 0x0010, 0x0002 }, + { 0x0010, 0x0003 }, + { 0x0012, 0x0002 }, + { 0x0012, 0x0003 }, + { 0x0013, 0x0000 }, + { 0x0013, 0x0001 }, + { 0x0013, 0x0002 }, + { 0x0013, 0x0003 }, + { 0x0012, 0x0004 }, + { 0x0012, 0x0005 }, + { 0x0012, 0x0006 }, + { 0x0012, 0x0007 }, + + }; + +const uint16_t c_aauiLCLDHuffEnc52[32][2] = + { + { 0x0002, 0x0002 }, + { 0x0002, 0x0003 }, + { 0x0003, 0x0002 }, + { 0x0003, 0x0003 }, + { 0x0004, 0x0002 }, + { 0x0004, 0x0003 }, + { 0x0005, 0x0001 }, + { 0x0005, 0x0002 }, + { 0x0005, 0x0003 }, + { 0x0006, 0x0001 }, + { 0x0007, 0x0001 }, + { 0x0008, 0x0001 }, + { 0x0009, 0x0001 }, + { 0x000a, 0x0001 }, + { 0x000b, 0x0001 }, + { 0x000c, 0x0001 }, + { 0x000e, 0x0001 }, + { 0x000e, 0x0002 }, + { 0x000e, 0x0003 }, + { 0x000f, 0x0001 }, + { 0x0011, 0x0002 }, + { 0x0011, 0x0003 }, + { 0x0012, 0x0003 }, + { 0x0014, 0x0000 }, + { 0x0013, 0x0003 }, + { 0x0014, 0x0001 }, + { 0x0014, 0x0002 }, + { 0x0014, 0x0003 }, + { 0x0014, 0x0004 }, + { 0x0014, 0x0005 }, + { 0x0013, 0x0004 }, + { 0x0013, 0x0005 }, + }; + +const uint16_t c_aauiLCLDHuffEnc53[37][2] = + { + { 0x0002, 0x0002 }, + { 0x0002, 0x0003 }, + { 0x0003, 0x0002 }, + { 0x0003, 0x0003 }, + { 0x0004, 0x0002 }, + { 0x0004, 0x0003 }, + { 0x0005, 0x0002 }, + { 0x0005, 0x0003 }, + { 0x0006, 0x0002 }, + { 0x0006, 0x0003 }, + { 0x0007, 0x0001 }, + { 0x0007, 0x0002 }, + { 0x0007, 0x0003 }, + { 0x0008, 0x0001 }, + { 0x0009, 0x0001 }, + { 0x000b, 0x0002 }, + { 0x000b, 0x0003 }, + { 0x000c, 0x0002 }, + { 0x000c, 0x0003 }, + { 0x000d, 0x0002 }, + { 0x000d, 0x0003 }, + { 0x000e, 0x0002 }, + { 0x000e, 0x0003 }, + { 0x000f, 0x0002 }, + { 0x000f, 0x0003 }, + { 0x0011, 0x0004 }, + { 0x0010, 0x0003 }, + { 0x0011, 0x0005 }, + { 0x0013, 0x0000 }, + { 0x0013, 0x0001 }, + { 0x0012, 0x0001 }, + { 0x0012, 0x0002 }, + { 0x0012, 0x0003 }, + { 0x0012, 0x0004 }, + { 0x0012, 0x0005 }, + { 0x0012, 0x0006 }, + { 0x0012, 0x0007 }, + + }; + +const uint16_t c_aauiLCLDHuffEnc54[39][2] = + { + { 0x0002, 0x0002 }, + { 0x0002, 0x0003 }, + { 0x0003, 0x0002 }, + { 0x0003, 0x0003 }, + { 0x0004, 0x0003 }, + { 0x0005, 0x0003 }, + { 0x0005, 0x0004 }, + { 0x0005, 0x0005 }, + { 0x0006, 0x0002 }, + { 0x0006, 0x0003 }, + { 0x0006, 0x0004 }, + { 0x0006, 0x0005 }, + { 0x0007, 0x0002 }, + { 0x0007, 0x0003 }, + { 0x0008, 0x0001 }, + { 0x0008, 0x0002 }, + { 0x0008, 0x0003 }, + { 0x000a, 0x0002 }, + { 0x000a, 0x0003 }, + { 0x000b, 0x0002 }, + { 0x000b, 0x0003 }, + { 0x000c, 0x0002 }, + { 0x000c, 0x0003 }, + { 0x000d, 0x0002 }, + { 0x000d, 0x0003 }, + { 0x000e, 0x0002 }, + { 0x000e, 0x0003 }, + { 0x000f, 0x0002 }, + { 0x000f, 0x0003 }, + { 0x0011, 0x0002 }, + { 0x0010, 0x0002 }, + { 0x0010, 0x0003 }, + { 0x0011, 0x0003 }, + { 0x0012, 0x0002 }, + { 0x0012, 0x0003 }, + { 0x0013, 0x0000 }, + { 0x0013, 0x0001 }, + { 0x0013, 0x0002 }, + { 0x0013, 0x0003 }, + + }; + +const uint16_t c_aauiLCLDHuffEnc55[46][2] = + { + { 0x0003, 0x0003 }, + { 0x0002, 0x0003 }, + { 0x0003, 0x0004 }, + { 0x0003, 0x0005 }, + { 0x0004, 0x0003 }, + { 0x0004, 0x0004 }, + { 0x0004, 0x0005 }, + { 0x0005, 0x0003 }, + { 0x0005, 0x0004 }, + { 0x0005, 0x0005 }, + { 0x0006, 0x0003 }, + { 0x0006, 0x0004 }, + { 0x0006, 0x0005 }, + { 0x0007, 0x0002 }, + { 0x0007, 0x0003 }, + { 0x0007, 0x0004 }, + { 0x0007, 0x0005 }, + { 0x0008, 0x0002 }, + { 0x0008, 0x0003 }, + { 0x0009, 0x0002 }, + { 0x0009, 0x0003 }, + { 0x000a, 0x0002 }, + { 0x000a, 0x0003 }, + { 0x000b, 0x0002 }, + { 0x000b, 0x0003 }, + { 0x000c, 0x0002 }, + { 0x000c, 0x0003 }, + { 0x000d, 0x0002 }, + { 0x000d, 0x0003 }, + { 0x000e, 0x0002 }, + { 0x000e, 0x0003 }, + { 0x000f, 0x0003 }, + { 0x0010, 0x0002 }, + { 0x0010, 0x0003 }, + { 0x0010, 0x0004 }, + { 0x0010, 0x0005 }, + { 0x0011, 0x0003 }, + { 0x0012, 0x0003 }, + { 0x0012, 0x0004 }, + { 0x0012, 0x0005 }, + { 0x0013, 0x0000 }, + { 0x0013, 0x0001 }, + { 0x0013, 0x0002 }, + { 0x0013, 0x0003 }, + { 0x0013, 0x0004 }, + { 0x0013, 0x0005 }, + + }; + +const uint16_t c_aauiLCLDHuffEnc56[55][2] = + { + { 0x0003, 0x0003 }, + { 0x0002, 0x0003 }, + { 0x0003, 0x0004 }, + { 0x0003, 0x0005 }, + { 0x0004, 0x0004 }, + { 0x0004, 0x0005 }, + { 0x0005, 0x0003 }, + { 0x0005, 0x0004 }, + { 0x0005, 0x0005 }, + { 0x0005, 0x0006 }, + { 0x0005, 0x0007 }, + { 0x0006, 0x0003 }, + { 0x0006, 0x0004 }, + { 0x0006, 0x0005 }, + { 0x0007, 0x0003 }, + { 0x0007, 0x0004 }, + { 0x0007, 0x0005 }, + { 0x0008, 0x0002 }, + { 0x0008, 0x0003 }, + { 0x0008, 0x0004 }, + { 0x0008, 0x0005 }, + { 0x0009, 0x0002 }, + { 0x0009, 0x0003 }, + { 0x000a, 0x0002 }, + { 0x000a, 0x0003 }, + { 0x000b, 0x0003 }, + { 0x000c, 0x0003 }, + { 0x000c, 0x0004 }, + { 0x000c, 0x0005 }, + { 0x000d, 0x0003 }, + { 0x000d, 0x0004 }, + { 0x000d, 0x0005 }, + { 0x000e, 0x0003 }, + { 0x000e, 0x0004 }, + { 0x000e, 0x0005 }, + { 0x000f, 0x0004 }, + { 0x000f, 0x0005 }, + { 0x0010, 0x0002 }, + { 0x0010, 0x0003 }, + { 0x0010, 0x0004 }, + { 0x0010, 0x0005 }, + { 0x0010, 0x0006 }, + { 0x0010, 0x0007 }, + { 0x0013, 0x0000 }, + { 0x0011, 0x0003 }, + { 0x0012, 0x0005 }, + { 0x0013, 0x0001 }, + { 0x0013, 0x0002 }, + { 0x0013, 0x0003 }, + { 0x0013, 0x0004 }, + { 0x0013, 0x0005 }, + { 0x0013, 0x0006 }, + { 0x0013, 0x0007 }, + { 0x0013, 0x0008 }, + { 0x0013, 0x0009 }, + + }; + +const uint16_t c_aauiLCLDHuffEnc57[65][2] = + { + { 0x0003, 0x0004 }, + { 0x0002, 0x0003 }, + { 0x0003, 0x0005 }, + { 0x0004, 0x0004 }, + { 0x0004, 0x0005 }, + { 0x0004, 0x0006 }, + { 0x0004, 0x0007 }, + { 0x0005, 0x0004 }, + { 0x0005, 0x0005 }, + { 0x0005, 0x0006 }, + { 0x0005, 0x0007 }, + { 0x0006, 0x0004 }, + { 0x0006, 0x0005 }, + { 0x0006, 0x0006 }, + { 0x0006, 0x0007 }, + { 0x0007, 0x0003 }, + { 0x0007, 0x0004 }, + { 0x0007, 0x0005 }, + { 0x0007, 0x0006 }, + { 0x0007, 0x0007 }, + { 0x0008, 0x0003 }, + { 0x0008, 0x0004 }, + { 0x0008, 0x0005 }, + { 0x0009, 0x0003 }, + { 0x0009, 0x0004 }, + { 0x0009, 0x0005 }, + { 0x000a, 0x0003 }, + { 0x000a, 0x0004 }, + { 0x000a, 0x0005 }, + { 0x000b, 0x0003 }, + { 0x000b, 0x0004 }, + { 0x000b, 0x0005 }, + { 0x000c, 0x0003 }, + { 0x000c, 0x0004 }, + { 0x000d, 0x0003 }, + { 0x000c, 0x0005 }, + { 0x000d, 0x0004 }, + { 0x000d, 0x0005 }, + { 0x000e, 0x0003 }, + { 0x000e, 0x0004 }, + { 0x000e, 0x0005 }, + { 0x000f, 0x0003 }, + { 0x0010, 0x0003 }, + { 0x000f, 0x0004 }, + { 0x000f, 0x0005 }, + { 0x0010, 0x0004 }, + { 0x0010, 0x0005 }, + { 0x0013, 0x0000 }, + { 0x0011, 0x0005 }, + { 0x0013, 0x0001 }, + { 0x0013, 0x0002 }, + { 0x0012, 0x0007 }, + { 0x0013, 0x0003 }, + { 0x0013, 0x0004 }, + { 0x0012, 0x0008 }, + { 0x0012, 0x0009 }, + { 0x0013, 0x0005 }, + { 0x0013, 0x0006 }, + { 0x0013, 0x0007 }, + { 0x0013, 0x0008 }, + { 0x0013, 0x0009 }, + { 0x0013, 0x000a }, + { 0x0013, 0x000b }, + { 0x0013, 0x000c }, + { 0x0013, 0x000d }, + + }; + +const uint16_t c_aauiLCLDHuffEnc58[77][2] = + { + { 0x0004, 0x0005 }, + { 0x0003, 0x0005 }, + { 0x0003, 0x0006 }, + { 0x0003, 0x0007 }, + { 0x0004, 0x0006 }, + { 0x0004, 0x0007 }, + { 0x0004, 0x0008 }, + { 0x0004, 0x0009 }, + { 0x0005, 0x0005 }, + { 0x0005, 0x0006 }, + { 0x0005, 0x0007 }, + { 0x0005, 0x0008 }, + { 0x0005, 0x0009 }, + { 0x0006, 0x0004 }, + { 0x0006, 0x0005 }, + { 0x0006, 0x0006 }, + { 0x0006, 0x0007 }, + { 0x0006, 0x0008 }, + { 0x0006, 0x0009 }, + { 0x0007, 0x0004 }, + { 0x0007, 0x0005 }, + { 0x0007, 0x0006 }, + { 0x0007, 0x0007 }, + { 0x0008, 0x0003 }, + { 0x0008, 0x0004 }, + { 0x0008, 0x0005 }, + { 0x0008, 0x0006 }, + { 0x0008, 0x0007 }, + { 0x0009, 0x0003 }, + { 0x0009, 0x0004 }, + { 0x0009, 0x0005 }, + { 0x000a, 0x0003 }, + { 0x000a, 0x0004 }, + { 0x000a, 0x0005 }, + { 0x000b, 0x0004 }, + { 0x000b, 0x0005 }, + { 0x000c, 0x0004 }, + { 0x000c, 0x0005 }, + { 0x000c, 0x0006 }, + { 0x000c, 0x0007 }, + { 0x000d, 0x0004 }, + { 0x000d, 0x0005 }, + { 0x000d, 0x0006 }, + { 0x000d, 0x0007 }, + { 0x000e, 0x0004 }, + { 0x000e, 0x0005 }, + { 0x000e, 0x0006 }, + { 0x000e, 0x0007 }, + { 0x000f, 0x0004 }, + { 0x000f, 0x0005 }, + { 0x000f, 0x0006 }, + { 0x0010, 0x0004 }, + { 0x000f, 0x0007 }, + { 0x0010, 0x0005 }, + { 0x0010, 0x0006 }, + { 0x0010, 0x0007 }, + { 0x0013, 0x0000 }, + { 0x0013, 0x0001 }, + { 0x0012, 0x0006 }, + { 0x0011, 0x0007 }, + { 0x0013, 0x0002 }, + { 0x0013, 0x0003 }, + { 0x0013, 0x0004 }, + { 0x0013, 0x0005 }, + { 0x0012, 0x0007 }, + { 0x0013, 0x0006 }, + { 0x0013, 0x0007 }, + { 0x0013, 0x0008 }, + { 0x0013, 0x0009 }, + { 0x0013, 0x000a }, + { 0x0013, 0x000b }, + { 0x0012, 0x0008 }, + { 0x0012, 0x0009 }, + { 0x0012, 0x000a }, + { 0x0012, 0x000b }, + { 0x0012, 0x000c }, + { 0x0012, 0x000d }, + + }; + +const uint16_t c_aauiLCLDHuffEnc59[91][2] = + { + { 0x0003, 0x0005 }, + { 0x0003, 0x0006 }, + { 0x0003, 0x0007 }, + { 0x0004, 0x0006 }, + { 0x0004, 0x0007 }, + { 0x0004, 0x0008 }, + { 0x0004, 0x0009 }, + { 0x0005, 0x0006 }, + { 0x0005, 0x0007 }, + { 0x0005, 0x0008 }, + { 0x0005, 0x0009 }, + { 0x0005, 0x000a }, + { 0x0005, 0x000b }, + { 0x0006, 0x0006 }, + { 0x0006, 0x0007 }, + { 0x0006, 0x0008 }, + { 0x0006, 0x0009 }, + { 0x0006, 0x000a }, + { 0x0006, 0x000b }, + { 0x0007, 0x0005 }, + { 0x0007, 0x0006 }, + { 0x0007, 0x0007 }, + { 0x0007, 0x0008 }, + { 0x0007, 0x0009 }, + { 0x0007, 0x000a }, + { 0x0007, 0x000b }, + { 0x0008, 0x0003 }, + { 0x0008, 0x0004 }, + { 0x0008, 0x0005 }, + { 0x0008, 0x0006 }, + { 0x0008, 0x0007 }, + { 0x0008, 0x0008 }, + { 0x0008, 0x0009 }, + { 0x0009, 0x0004 }, + { 0x0009, 0x0005 }, + { 0x000a, 0x0004 }, + { 0x000a, 0x0005 }, + { 0x000a, 0x0006 }, + { 0x000a, 0x0007 }, + { 0x000b, 0x0004 }, + { 0x000b, 0x0005 }, + { 0x000b, 0x0006 }, + { 0x000b, 0x0007 }, + { 0x000c, 0x0004 }, + { 0x000c, 0x0005 }, + { 0x000c, 0x0006 }, + { 0x000c, 0x0007 }, + { 0x000d, 0x0003 }, + { 0x000d, 0x0004 }, + { 0x000d, 0x0005 }, + { 0x000d, 0x0006 }, + { 0x000d, 0x0007 }, + { 0x000e, 0x0003 }, + { 0x000e, 0x0004 }, + { 0x000e, 0x0005 }, + { 0x000f, 0x0003 }, + { 0x000f, 0x0004 }, + { 0x000f, 0x0005 }, + { 0x0011, 0x0008 }, + { 0x0011, 0x0009 }, + { 0x0013, 0x0000 }, + { 0x0011, 0x000a }, + { 0x0013, 0x0001 }, + { 0x0013, 0x0002 }, + { 0x0012, 0x000d }, + { 0x0012, 0x000e }, + { 0x0013, 0x0003 }, + { 0x0013, 0x0004 }, + { 0x0013, 0x0005 }, + { 0x0011, 0x000b }, + { 0x0013, 0x0006 }, + { 0x0013, 0x0007 }, + { 0x0013, 0x0008 }, + { 0x0013, 0x0009 }, + { 0x0013, 0x000a }, + { 0x0013, 0x000b }, + { 0x0013, 0x000c }, + { 0x0013, 0x000d }, + { 0x0013, 0x000e }, + { 0x0013, 0x000f }, + { 0x0013, 0x0010 }, + { 0x0013, 0x0011 }, + { 0x0013, 0x0012 }, + { 0x0013, 0x0013 }, + { 0x0013, 0x0014 }, + { 0x0013, 0x0015 }, + { 0x0013, 0x0016 }, + { 0x0013, 0x0017 }, + { 0x0013, 0x0018 }, + { 0x0013, 0x0019 }, + { 0x0012, 0x000f }, + + }; + +const uint16_t c_aauiLCLDHuffEnc60[109][2] = + { + { 0x0004, 0x0007 }, + { 0x0002, 0x0003 }, + { 0x0003, 0x0005 }, + { 0x0004, 0x0008 }, + { 0x0004, 0x0009 }, + { 0x0005, 0x0007 }, + { 0x0005, 0x0008 }, + { 0x0005, 0x0009 }, + { 0x0005, 0x000a }, + { 0x0005, 0x000b }, + { 0x0005, 0x000c }, + { 0x0005, 0x000d }, + { 0x0006, 0x0007 }, + { 0x0006, 0x0008 }, + { 0x0006, 0x0009 }, + { 0x0006, 0x000a }, + { 0x0006, 0x000b }, + { 0x0006, 0x000c }, + { 0x0006, 0x000d }, + { 0x0007, 0x0006 }, + { 0x0007, 0x0007 }, + { 0x0007, 0x0008 }, + { 0x0007, 0x0009 }, + { 0x0007, 0x000a }, + { 0x0007, 0x000b }, + { 0x0007, 0x000c }, + { 0x0007, 0x000d }, + { 0x0008, 0x0006 }, + { 0x0008, 0x0007 }, + { 0x0008, 0x0008 }, + { 0x0008, 0x0009 }, + { 0x0008, 0x000a }, + { 0x0008, 0x000b }, + { 0x0009, 0x0004 }, + { 0x0009, 0x0005 }, + { 0x0009, 0x0006 }, + { 0x0009, 0x0007 }, + { 0x0009, 0x0008 }, + { 0x0009, 0x0009 }, + { 0x0009, 0x000a }, + { 0x0009, 0x000b }, + { 0x000a, 0x0004 }, + { 0x000a, 0x0005 }, + { 0x000a, 0x0006 }, + { 0x000a, 0x0007 }, + { 0x000b, 0x0004 }, + { 0x000b, 0x0005 }, + { 0x000b, 0x0006 }, + { 0x000b, 0x0007 }, + { 0x000c, 0x0004 }, + { 0x000c, 0x0005 }, + { 0x000c, 0x0006 }, + { 0x000d, 0x0005 }, + { 0x000d, 0x0006 }, + { 0x000d, 0x0007 }, + { 0x000c, 0x0007 }, + { 0x000e, 0x0005 }, + { 0x000e, 0x0006 }, + { 0x000e, 0x0007 }, + { 0x000e, 0x0008 }, + { 0x000f, 0x0005 }, + { 0x000e, 0x0009 }, + { 0x000f, 0x0006 }, + { 0x0010, 0x0006 }, + { 0x000f, 0x0007 }, + { 0x000f, 0x0008 }, + { 0x000f, 0x0009 }, + { 0x0010, 0x0007 }, + { 0x0010, 0x0008 }, + { 0x0010, 0x0009 }, + { 0x0011, 0x000a }, + { 0x0013, 0x0000 }, + { 0x0011, 0x000b }, + { 0x0013, 0x0001 }, + { 0x0013, 0x0002 }, + { 0x0012, 0x0011 }, + { 0x0012, 0x0012 }, + { 0x0013, 0x0003 }, + { 0x0013, 0x0004 }, + { 0x0013, 0x0005 }, + { 0x0013, 0x0006 }, + { 0x0013, 0x0007 }, + { 0x0013, 0x0008 }, + { 0x0013, 0x0009 }, + { 0x0013, 0x000a }, + { 0x0013, 0x000b }, + { 0x0013, 0x000c }, + { 0x0013, 0x000d }, + { 0x0013, 0x000e }, + { 0x0013, 0x000f }, + { 0x0013, 0x0010 }, + { 0x0013, 0x0011 }, + { 0x0013, 0x0012 }, + { 0x0013, 0x0013 }, + { 0x0013, 0x0014 }, + { 0x0013, 0x0015 }, + { 0x0013, 0x0016 }, + { 0x0013, 0x0017 }, + { 0x0013, 0x0018 }, + { 0x0013, 0x0019 }, + { 0x0013, 0x001a }, + { 0x0013, 0x001b }, + { 0x0013, 0x001c }, + { 0x0013, 0x001d }, + { 0x0013, 0x001e }, + { 0x0013, 0x001f }, + { 0x0013, 0x0020 }, + { 0x0013, 0x0021 }, + { 0x0012, 0x0013 }, + + }; + +const uint16_t c_aauiLCLDHuffEnc61[129][2] = + { + { 0x0004, 0x0008 }, + { 0x0003, 0x0006 }, + { 0x0003, 0x0007 }, + { 0x0004, 0x0009 }, + { 0x0004, 0x000a }, + { 0x0004, 0x000b }, + { 0x0005, 0x0008 }, + { 0x0005, 0x0009 }, + { 0x0005, 0x000a }, + { 0x0005, 0x000b }, + { 0x0005, 0x000c }, + { 0x0005, 0x000d }, + { 0x0005, 0x000e }, + { 0x0005, 0x000f }, + { 0x0006, 0x0008 }, + { 0x0006, 0x0009 }, + { 0x0006, 0x000a }, + { 0x0006, 0x000b }, + { 0x0006, 0x000c }, + { 0x0006, 0x000d }, + { 0x0006, 0x000e }, + { 0x0006, 0x000f }, + { 0x0007, 0x0008 }, + { 0x0007, 0x0009 }, + { 0x0007, 0x000a }, + { 0x0007, 0x000b }, + { 0x0007, 0x000c }, + { 0x0007, 0x000d }, + { 0x0007, 0x000e }, + { 0x0007, 0x000f }, + { 0x0008, 0x0006 }, + { 0x0008, 0x0007 }, + { 0x0008, 0x0008 }, + { 0x0008, 0x0009 }, + { 0x0008, 0x000a }, + { 0x0008, 0x000b }, + { 0x0008, 0x000c }, + { 0x0008, 0x000d }, + { 0x0008, 0x000e }, + { 0x0008, 0x000f }, + { 0x0009, 0x0006 }, + { 0x0009, 0x0007 }, + { 0x0009, 0x0008 }, + { 0x0009, 0x0009 }, + { 0x0009, 0x000a }, + { 0x0009, 0x000b }, + { 0x000a, 0x0005 }, + { 0x000a, 0x0006 }, + { 0x000a, 0x0007 }, + { 0x000a, 0x0008 }, + { 0x000a, 0x0009 }, + { 0x000a, 0x000a }, + { 0x000a, 0x000b }, + { 0x000b, 0x0005 }, + { 0x000b, 0x0006 }, + { 0x000b, 0x0007 }, + { 0x000b, 0x0008 }, + { 0x000b, 0x0009 }, + { 0x000c, 0x0006 }, + { 0x000c, 0x0007 }, + { 0x000c, 0x0008 }, + { 0x000c, 0x0009 }, + { 0x000d, 0x0005 }, + { 0x000d, 0x0006 }, + { 0x000d, 0x0007 }, + { 0x000d, 0x0008 }, + { 0x000d, 0x0009 }, + { 0x000d, 0x000a }, + { 0x000e, 0x0008 }, + { 0x000d, 0x000b }, + { 0x000e, 0x0009 }, + { 0x000f, 0x0009 }, + { 0x000f, 0x000a }, + { 0x000f, 0x000b }, + { 0x000f, 0x000c }, + { 0x000f, 0x000d }, + { 0x000f, 0x000e }, + { 0x0010, 0x000c }, + { 0x0011, 0x0015 }, + { 0x0010, 0x000d }, + { 0x000f, 0x000f }, + { 0x0010, 0x000e }, + { 0x0010, 0x000f }, + { 0x0012, 0x0000 }, + { 0x0011, 0x0016 }, + { 0x0010, 0x0010 }, + { 0x0010, 0x0011 }, + { 0x0011, 0x0017 }, + { 0x0012, 0x0001 }, + { 0x0012, 0x0002 }, + { 0x0012, 0x0003 }, + { 0x0012, 0x0004 }, + { 0x0012, 0x0005 }, + { 0x0012, 0x0006 }, + { 0x0012, 0x0007 }, + { 0x0012, 0x0008 }, + { 0x0012, 0x0009 }, + { 0x0012, 0x000a }, + { 0x0012, 0x000b }, + { 0x0012, 0x000c }, + { 0x0012, 0x000d }, + { 0x0012, 0x000e }, + { 0x0012, 0x000f }, + { 0x0012, 0x0010 }, + { 0x0012, 0x0011 }, + { 0x0012, 0x0012 }, + { 0x0012, 0x0013 }, + { 0x0012, 0x0014 }, + { 0x0012, 0x0015 }, + { 0x0012, 0x0016 }, + { 0x0012, 0x0017 }, + { 0x0012, 0x0018 }, + { 0x0012, 0x0019 }, + { 0x0012, 0x001a }, + { 0x0012, 0x001b }, + { 0x0012, 0x001c }, + { 0x0012, 0x001d }, + { 0x0012, 0x001e }, + { 0x0012, 0x001f }, + { 0x0012, 0x0020 }, + { 0x0012, 0x0021 }, + { 0x0012, 0x0022 }, + { 0x0012, 0x0023 }, + { 0x0012, 0x0024 }, + { 0x0012, 0x0025 }, + { 0x0012, 0x0026 }, + { 0x0012, 0x0027 }, + { 0x0012, 0x0028 }, + { 0x0012, 0x0029 }, + + }; + +const uint16_t c_aauiLCLDHuffEnc62[153][2] = + { + { 0x0004, 0x0009 }, + { 0x0003, 0x0006 }, + { 0x0003, 0x0007 }, + { 0x0004, 0x000a }, + { 0x0004, 0x000b }, + { 0x0005, 0x000a }, + { 0x0005, 0x000b }, + { 0x0005, 0x000c }, + { 0x0005, 0x000d }, + { 0x0005, 0x000e }, + { 0x0005, 0x000f }, + { 0x0005, 0x0010 }, + { 0x0005, 0x0011 }, + { 0x0006, 0x000a }, + { 0x0006, 0x000b }, + { 0x0006, 0x000c }, + { 0x0006, 0x000d }, + { 0x0006, 0x000e }, + { 0x0006, 0x000f }, + { 0x0006, 0x0010 }, + { 0x0006, 0x0011 }, + { 0x0006, 0x0012 }, + { 0x0006, 0x0013 }, + { 0x0007, 0x0009 }, + { 0x0007, 0x000a }, + { 0x0007, 0x000b }, + { 0x0007, 0x000c }, + { 0x0007, 0x000d }, + { 0x0007, 0x000e }, + { 0x0007, 0x000f }, + { 0x0007, 0x0010 }, + { 0x0007, 0x0011 }, + { 0x0007, 0x0012 }, + { 0x0007, 0x0013 }, + { 0x0008, 0x0009 }, + { 0x0008, 0x000a }, + { 0x0008, 0x000b }, + { 0x0008, 0x000c }, + { 0x0008, 0x000d }, + { 0x0008, 0x000e }, + { 0x0008, 0x000f }, + { 0x0008, 0x0010 }, + { 0x0008, 0x0011 }, + { 0x0009, 0x0007 }, + { 0x0009, 0x0008 }, + { 0x0009, 0x0009 }, + { 0x0009, 0x000a }, + { 0x0009, 0x000b }, + { 0x0009, 0x000c }, + { 0x0009, 0x000d }, + { 0x0009, 0x000e }, + { 0x0009, 0x000f }, + { 0x0009, 0x0010 }, + { 0x0009, 0x0011 }, + { 0x000a, 0x0004 }, + { 0x000a, 0x0005 }, + { 0x000a, 0x0006 }, + { 0x000a, 0x0007 }, + { 0x000a, 0x0008 }, + { 0x000a, 0x0009 }, + { 0x000a, 0x000a }, + { 0x000a, 0x000b }, + { 0x000a, 0x000c }, + { 0x000a, 0x000d }, + { 0x000b, 0x0007 }, + { 0x000c, 0x0007 }, + { 0x000c, 0x0008 }, + { 0x000c, 0x0009 }, + { 0x000c, 0x000a }, + { 0x000c, 0x000b }, + { 0x000c, 0x000c }, + { 0x000d, 0x0007 }, + { 0x000c, 0x000d }, + { 0x000d, 0x0008 }, + { 0x000d, 0x0009 }, + { 0x000d, 0x000a }, + { 0x000d, 0x000b }, + { 0x000e, 0x0008 }, + { 0x000d, 0x000c }, + { 0x000d, 0x000d }, + { 0x000e, 0x0009 }, + { 0x000e, 0x000a }, + { 0x000e, 0x000b }, + { 0x000e, 0x000c }, + { 0x000f, 0x000c }, + { 0x000e, 0x000d }, + { 0x000f, 0x000d }, + { 0x000f, 0x000e }, + { 0x000f, 0x000f }, + { 0x0010, 0x000f }, + { 0x0010, 0x0010 }, + { 0x0011, 0x0019 }, + { 0x0010, 0x0011 }, + { 0x0010, 0x0012 }, + { 0x0010, 0x0013 }, + { 0x0010, 0x0014 }, + { 0x0010, 0x0015 }, + { 0x0012, 0x0000 }, + { 0x0010, 0x0016 }, + { 0x0011, 0x001a }, + { 0x0010, 0x0017 }, + { 0x0012, 0x0001 }, + { 0x0012, 0x0002 }, + { 0x0012, 0x0003 }, + { 0x0011, 0x001b }, + { 0x0012, 0x0004 }, + { 0x0012, 0x0005 }, + { 0x0012, 0x0006 }, + { 0x0012, 0x0007 }, + { 0x0012, 0x0008 }, + { 0x0012, 0x0009 }, + { 0x0012, 0x000a }, + { 0x0012, 0x000b }, + { 0x0012, 0x000c }, + { 0x0012, 0x000d }, + { 0x0012, 0x000e }, + { 0x0012, 0x000f }, + { 0x0012, 0x0010 }, + { 0x0012, 0x0011 }, + { 0x0012, 0x0012 }, + { 0x0012, 0x0013 }, + { 0x0012, 0x0014 }, + { 0x0012, 0x0015 }, + { 0x0012, 0x0016 }, + { 0x0012, 0x0017 }, + { 0x0012, 0x0018 }, + { 0x0011, 0x001c }, + { 0x0012, 0x0019 }, + { 0x0012, 0x001a }, + { 0x0012, 0x001b }, + { 0x0012, 0x001c }, + { 0x0012, 0x001d }, + { 0x0012, 0x001e }, + { 0x0012, 0x001f }, + { 0x0012, 0x0020 }, + { 0x0012, 0x0021 }, + { 0x0012, 0x0022 }, + { 0x0012, 0x0023 }, + { 0x0012, 0x0024 }, + { 0x0012, 0x0025 }, + { 0x0012, 0x0026 }, + { 0x0012, 0x0027 }, + { 0x0012, 0x0028 }, + { 0x0012, 0x0029 }, + { 0x0012, 0x002a }, + { 0x0012, 0x002b }, + { 0x0012, 0x002c }, + { 0x0012, 0x002d }, + { 0x0012, 0x002e }, + { 0x0012, 0x002f }, + { 0x0012, 0x0030 }, + { 0x0012, 0x0031 }, + { 0x0011, 0x001d }, + + }; + +const uint16_t c_aauiLCLDHuffEnc63[181][2] = + { + { 0x0004, 0x0008 }, + { 0x0003, 0x0005 }, + { 0x0002, 0x0003 }, + { 0x0004, 0x0009 }, + { 0x0005, 0x000c }, + { 0x0005, 0x000d }, + { 0x0005, 0x000e }, + { 0x0005, 0x000f }, + { 0x0006, 0x000c }, + { 0x0006, 0x000d }, + { 0x0006, 0x000e }, + { 0x0006, 0x000f }, + { 0x0006, 0x0010 }, + { 0x0006, 0x0011 }, + { 0x0006, 0x0012 }, + { 0x0006, 0x0013 }, + { 0x0006, 0x0014 }, + { 0x0006, 0x0015 }, + { 0x0006, 0x0016 }, + { 0x0006, 0x0017 }, + { 0x0007, 0x000b }, + { 0x0007, 0x000c }, + { 0x0007, 0x000d }, + { 0x0007, 0x000e }, + { 0x0007, 0x000f }, + { 0x0007, 0x0010 }, + { 0x0007, 0x0011 }, + { 0x0007, 0x0012 }, + { 0x0007, 0x0013 }, + { 0x0007, 0x0014 }, + { 0x0007, 0x0015 }, + { 0x0007, 0x0016 }, + { 0x0007, 0x0017 }, + { 0x0008, 0x000c }, + { 0x0008, 0x000d }, + { 0x0008, 0x000e }, + { 0x0008, 0x000f }, + { 0x0008, 0x0010 }, + { 0x0008, 0x0011 }, + { 0x0008, 0x0012 }, + { 0x0008, 0x0013 }, + { 0x0008, 0x0014 }, + { 0x0008, 0x0015 }, + { 0x0009, 0x0008 }, + { 0x0009, 0x0009 }, + { 0x0009, 0x000a }, + { 0x0009, 0x000b }, + { 0x0009, 0x000c }, + { 0x0009, 0x000d }, + { 0x0009, 0x000e }, + { 0x0009, 0x000f }, + { 0x0009, 0x0010 }, + { 0x0009, 0x0011 }, + { 0x0009, 0x0012 }, + { 0x0009, 0x0013 }, + { 0x0009, 0x0014 }, + { 0x0009, 0x0015 }, + { 0x000a, 0x0007 }, + { 0x0009, 0x0016 }, + { 0x0009, 0x0017 }, + { 0x000a, 0x0008 }, + { 0x000a, 0x0009 }, + { 0x000a, 0x000a }, + { 0x000a, 0x000b }, + { 0x000a, 0x000c }, + { 0x000a, 0x000d }, + { 0x000a, 0x000e }, + { 0x000b, 0x0008 }, + { 0x000b, 0x0009 }, + { 0x000b, 0x000a }, + { 0x000a, 0x000f }, + { 0x000b, 0x000b }, + { 0x000b, 0x000c }, + { 0x000b, 0x000d }, + { 0x000c, 0x0009 }, + { 0x000c, 0x000a }, + { 0x000c, 0x000b }, + { 0x000c, 0x000c }, + { 0x000c, 0x000d }, + { 0x000c, 0x000e }, + { 0x000c, 0x000f }, + { 0x000d, 0x0008 }, + { 0x000d, 0x0009 }, + { 0x000d, 0x000a }, + { 0x000d, 0x000b }, + { 0x000d, 0x000c }, + { 0x000d, 0x000d }, + { 0x000d, 0x000e }, + { 0x000d, 0x000f }, + { 0x000d, 0x0010 }, + { 0x000d, 0x0011 }, + { 0x000e, 0x0007 }, + { 0x000e, 0x0008 }, + { 0x000e, 0x0009 }, + { 0x000e, 0x000a }, + { 0x000e, 0x000b }, + { 0x000e, 0x000c }, + { 0x000e, 0x000d }, + { 0x000e, 0x000e }, + { 0x000e, 0x000f }, + { 0x000f, 0x0008 }, + { 0x000f, 0x0009 }, + { 0x000f, 0x000a }, + { 0x000f, 0x000b }, + { 0x000f, 0x000c }, + { 0x0010, 0x0009 }, + { 0x0010, 0x000a }, + { 0x000f, 0x000d }, + { 0x0010, 0x000b }, + { 0x0010, 0x000c }, + { 0x0010, 0x000d }, + { 0x0011, 0x000e }, + { 0x0011, 0x000f }, + { 0x0010, 0x000e }, + { 0x0011, 0x0010 }, + { 0x0011, 0x0011 }, + { 0x0012, 0x0014 }, + { 0x0014, 0x0000 }, + { 0x0010, 0x000f }, + { 0x0012, 0x0015 }, + { 0x0012, 0x0016 }, + { 0x0014, 0x0001 }, + { 0x0012, 0x0017 }, + { 0x0012, 0x0018 }, + { 0x0012, 0x0019 }, + { 0x0013, 0x0010 }, + { 0x0012, 0x001a }, + { 0x0014, 0x0002 }, + { 0x0012, 0x001b }, + { 0x0014, 0x0003 }, + { 0x0014, 0x0004 }, + { 0x0014, 0x0005 }, + { 0x0013, 0x0011 }, + { 0x0014, 0x0006 }, + { 0x0013, 0x0012 }, + { 0x0014, 0x0007 }, + { 0x0014, 0x0008 }, + { 0x0014, 0x0009 }, + { 0x0014, 0x000a }, + { 0x0014, 0x000b }, + { 0x0014, 0x000c }, + { 0x0014, 0x000d }, + { 0x0014, 0x000e }, + { 0x0013, 0x0013 }, + { 0x0014, 0x000f }, + { 0x0014, 0x0010 }, + { 0x0014, 0x0011 }, + { 0x0014, 0x0012 }, + { 0x0014, 0x0013 }, + { 0x0014, 0x0014 }, + { 0x0014, 0x0015 }, + { 0x0014, 0x0016 }, + { 0x0014, 0x0017 }, + { 0x0014, 0x0018 }, + { 0x0014, 0x0019 }, + { 0x0014, 0x001a }, + { 0x0014, 0x001b }, + { 0x0014, 0x001c }, + { 0x0014, 0x001d }, + { 0x0014, 0x001e }, + { 0x0014, 0x001f }, + { 0x0013, 0x0014 }, + { 0x0013, 0x0015 }, + { 0x0013, 0x0016 }, + { 0x0013, 0x0017 }, + { 0x0013, 0x0018 }, + { 0x0013, 0x0019 }, + { 0x0013, 0x001a }, + { 0x0013, 0x001b }, + { 0x0013, 0x001c }, + { 0x0013, 0x001d }, + { 0x0013, 0x001e }, + { 0x0013, 0x001f }, + { 0x0013, 0x0020 }, + { 0x0013, 0x0021 }, + { 0x0013, 0x0022 }, + { 0x0013, 0x0023 }, + { 0x0013, 0x0024 }, + { 0x0013, 0x0025 }, + { 0x0013, 0x0026 }, + { 0x0013, 0x0027 }, + + }; + +const uint16_t ( *c_apauiHuffEncTabels[2 * ALLOC_TABLE_SIZE] )[2] = + { + NULL, + c_aauiLCLDHuffEnc1, + c_aauiLCLDHuffEnc2, + c_aauiLCLDHuffEnc3, + c_aauiLCLDHuffEnc4, + c_aauiLCLDHuffEnc5, + c_aauiLCLDHuffEnc6, + c_aauiLCLDHuffEnc7, + c_aauiLCLDHuffEnc8, + c_aauiLCLDHuffEnc9, + c_aauiLCLDHuffEnc10, + c_aauiLCLDHuffEnc11, + c_aauiLCLDHuffEnc12, + c_aauiLCLDHuffEnc13, + c_aauiLCLDHuffEnc14, + c_aauiLCLDHuffEnc15, + c_aauiLCLDHuffEnc16, + c_aauiLCLDHuffEnc17, + c_aauiLCLDHuffEnc18, + c_aauiLCLDHuffEnc19, + c_aauiLCLDHuffEnc20, + c_aauiLCLDHuffEnc21, + c_aauiLCLDHuffEnc22, + c_aauiLCLDHuffEnc23, + c_aauiLCLDHuffEnc24, + c_aauiLCLDHuffEnc25, + c_aauiLCLDHuffEnc26, + c_aauiLCLDHuffEnc27, + c_aauiLCLDHuffEnc28, + c_aauiLCLDHuffEnc29, + c_aauiLCLDHuffEnc30, + c_aauiLCLDHuffEnc31, + NULL, + c_aauiLCLDHuffEnc33, + c_aauiLCLDHuffEnc34, + c_aauiLCLDHuffEnc35, + c_aauiLCLDHuffEnc36, + c_aauiLCLDHuffEnc37, + c_aauiLCLDHuffEnc38, + c_aauiLCLDHuffEnc39, + c_aauiLCLDHuffEnc40, + c_aauiLCLDHuffEnc41, + c_aauiLCLDHuffEnc42, + c_aauiLCLDHuffEnc43, + c_aauiLCLDHuffEnc44, + c_aauiLCLDHuffEnc45, + c_aauiLCLDHuffEnc46, + c_aauiLCLDHuffEnc47, + c_aauiLCLDHuffEnc48, + c_aauiLCLDHuffEnc49, + c_aauiLCLDHuffEnc50, + c_aauiLCLDHuffEnc51, + c_aauiLCLDHuffEnc52, + c_aauiLCLDHuffEnc53, + c_aauiLCLDHuffEnc54, + c_aauiLCLDHuffEnc55, + c_aauiLCLDHuffEnc56, + c_aauiLCLDHuffEnc57, + c_aauiLCLDHuffEnc58, + c_aauiLCLDHuffEnc59, + c_aauiLCLDHuffEnc60, + c_aauiLCLDHuffEnc61, + c_aauiLCLDHuffEnc62, + c_aauiLCLDHuffEnc63, + }; + +const uint32_t num_row_aauiLCLDHuff[2 * ALLOC_TABLE_SIZE] = { 0, 16, 16, 25, 36, 36, 49, 64, 81, 100, + 169, 196, 289, 324, 400, 576, 729, 729, 28, 29, + 32, 37, 39, 46, 55, 65, 77, 91, 109, 129, + 153, 181, 0, 16, 16, 25, 36, 36, 49, 64, 81, + 100, 169, 196, 289, 324, 400, 576, 729, 729, 28, + 29, 32, 37, 39, 46, 55, 65, 77, 91, 109, + 129, 153, 181 }; +#ifdef USE_DEMOD_TABLES +const int32_t c_aaiHuffDemod1[16][2] = { + 0, + 0, + 0, + 1, + 0, + 2, + 0, + 3, + 1, + 0, + 1, + 1, + 1, + 2, + 1, + 3, + 2, + 0, + 2, + 1, + 2, + 2, + 2, + 3, + 3, + 0, + 3, + 1, + 3, + 2, + 3, + 3, +}; + +const int32_t c_aaiHuffDemod2[16][2] = { + 0, + 0, + 0, + 1, + 0, + 2, + 0, + 3, + 1, + 0, + 1, + 1, + 1, + 2, + 1, + 3, + 2, + 0, + 2, + 1, + 2, + 2, + 2, + 3, + 3, + 0, + 3, + 1, + 3, + 2, + 3, + 3, +}; + +const int32_t c_aaiHuffDemod3[25][2] = { + 0, + 0, + 0, + 1, + 0, + 2, + 0, + 3, + 0, + 4, + 1, + 0, + 1, + 1, + 1, + 2, + 1, + 3, + 1, + 4, + 2, + 0, + 2, + 1, + 2, + 2, + 2, + 3, + 2, + 4, + 3, + 0, + 3, + 1, + 3, + 2, + 3, + 3, + 3, + 4, + 4, + 0, + 4, + 1, + 4, + 2, + 4, + 3, + 4, + 4, +}; + +const int32_t c_aaiHuffDemod4[36][2] = { + 0, + 0, + 0, + 1, + 0, + 2, + 0, + 3, + 0, + 4, + 0, + 5, + 1, + 0, + 1, + 1, + 1, + 2, + 1, + 3, + 1, + 4, + 1, + 5, + 2, + 0, + 2, + 1, + 2, + 2, + 2, + 3, + 2, + 4, + 2, + 5, + 3, + 0, + 3, + 1, + 3, + 2, + 3, + 3, + 3, + 4, + 3, + 5, + 4, + 0, + 4, + 1, + 4, + 2, + 4, + 3, + 4, + 4, + 4, + 5, + 5, + 0, + 5, + 1, + 5, + 2, + 5, + 3, + 5, + 4, + 5, + 5, +}; + +const int32_t c_aaiHuffDemod5[36][2] = { + 0, + 0, + 0, + 1, + 0, + 2, + 0, + 3, + 0, + 4, + 0, + 5, + 1, + 0, + 1, + 1, + 1, + 2, + 1, + 3, + 1, + 4, + 1, + 5, + 2, + 0, + 2, + 1, + 2, + 2, + 2, + 3, + 2, + 4, + 2, + 5, + 3, + 0, + 3, + 1, + 3, + 2, + 3, + 3, + 3, + 4, + 3, + 5, + 4, + 0, + 4, + 1, + 4, + 2, + 4, + 3, + 4, + 4, + 4, + 5, + 5, + 0, + 5, + 1, + 5, + 2, + 5, + 3, + 5, + 4, + 5, + 5, +}; + +const int32_t c_aaiHuffDemod6[49][2] = { + 0, + 0, + 0, + 1, + 0, + 2, + 0, + 3, + 0, + 4, + 0, + 5, + 0, + 6, + 1, + 0, + 1, + 1, + 1, + 2, + 1, + 3, + 1, + 4, + 1, + 5, + 1, + 6, + 2, + 0, + 2, + 1, + 2, + 2, + 2, + 3, + 2, + 4, + 2, + 5, + 2, + 6, + 3, + 0, + 3, + 1, + 3, + 2, + 3, + 3, + 3, + 4, + 3, + 5, + 3, + 6, + 4, + 0, + 4, + 1, + 4, + 2, + 4, + 3, + 4, + 4, + 4, + 5, + 4, + 6, + 5, + 0, + 5, + 1, + 5, + 2, + 5, + 3, + 5, + 4, + 5, + 5, + 5, + 6, + 6, + 0, + 6, + 1, + 6, + 2, + 6, + 3, + 6, + 4, + 6, + 5, + 6, + 6, +}; + +const int32_t c_aaiHuffDemod7[64][2] = { + 0, + 0, + 0, + 1, + 0, + 2, + 0, + 3, + 0, + 4, + 0, + 5, + 0, + 6, + 0, + 7, + 1, + 0, + 1, + 1, + 1, + 2, + 1, + 3, + 1, + 4, + 1, + 5, + 1, + 6, + 1, + 7, + 2, + 0, + 2, + 1, + 2, + 2, + 2, + 3, + 2, + 4, + 2, + 5, + 2, + 6, + 2, + 7, + 3, + 0, + 3, + 1, + 3, + 2, + 3, + 3, + 3, + 4, + 3, + 5, + 3, + 6, + 3, + 7, + 4, + 0, + 4, + 1, + 4, + 2, + 4, + 3, + 4, + 4, + 4, + 5, + 4, + 6, + 4, + 7, + 5, + 0, + 5, + 1, + 5, + 2, + 5, + 3, + 5, + 4, + 5, + 5, + 5, + 6, + 5, + 7, + 6, + 0, + 6, + 1, + 6, + 2, + 6, + 3, + 6, + 4, + 6, + 5, + 6, + 6, + 6, + 7, + 7, + 0, + 7, + 1, + 7, + 2, + 7, + 3, + 7, + 4, + 7, + 5, + 7, + 6, + 7, + 7, +}; + +const int32_t c_aaiHuffDemod8[81][2] = { + 0, + 0, + 0, + 1, + 0, + 2, + 0, + 3, + 0, + 4, + 0, + 5, + 0, + 6, + 0, + 7, + 0, + 8, + 1, + 0, + 1, + 1, + 1, + 2, + 1, + 3, + 1, + 4, + 1, + 5, + 1, + 6, + 1, + 7, + 1, + 8, + 2, + 0, + 2, + 1, + 2, + 2, + 2, + 3, + 2, + 4, + 2, + 5, + 2, + 6, + 2, + 7, + 2, + 8, + 3, + 0, + 3, + 1, + 3, + 2, + 3, + 3, + 3, + 4, + 3, + 5, + 3, + 6, + 3, + 7, + 3, + 8, + 4, + 0, + 4, + 1, + 4, + 2, + 4, + 3, + 4, + 4, + 4, + 5, + 4, + 6, + 4, + 7, + 4, + 8, + 5, + 0, + 5, + 1, + 5, + 2, + 5, + 3, + 5, + 4, + 5, + 5, + 5, + 6, + 5, + 7, + 5, + 8, + 6, + 0, + 6, + 1, + 6, + 2, + 6, + 3, + 6, + 4, + 6, + 5, + 6, + 6, + 6, + 7, + 6, + 8, + 7, + 0, + 7, + 1, + 7, + 2, + 7, + 3, + 7, + 4, + 7, + 5, + 7, + 6, + 7, + 7, + 7, + 8, + 8, + 0, + 8, + 1, + 8, + 2, + 8, + 3, + 8, + 4, + 8, + 5, + 8, + 6, + 8, + 7, + 8, + 8, +}; + +const int32_t c_aaiHuffDemod9[100][2] = { + 0, + 0, + 0, + 1, + 0, + 2, + 0, + 3, + 0, + 4, + 0, + 5, + 0, + 6, + 0, + 7, + 0, + 8, + 0, + 9, + 1, + 0, + 1, + 1, + 1, + 2, + 1, + 3, + 1, + 4, + 1, + 5, + 1, + 6, + 1, + 7, + 1, + 8, + 1, + 9, + 2, + 0, + 2, + 1, + 2, + 2, + 2, + 3, + 2, + 4, + 2, + 5, + 2, + 6, + 2, + 7, + 2, + 8, + 2, + 9, + 3, + 0, + 3, + 1, + 3, + 2, + 3, + 3, + 3, + 4, + 3, + 5, + 3, + 6, + 3, + 7, + 3, + 8, + 3, + 9, + 4, + 0, + 4, + 1, + 4, + 2, + 4, + 3, + 4, + 4, + 4, + 5, + 4, + 6, + 4, + 7, + 4, + 8, + 4, + 9, + 5, + 0, + 5, + 1, + 5, + 2, + 5, + 3, + 5, + 4, + 5, + 5, + 5, + 6, + 5, + 7, + 5, + 8, + 5, + 9, + 6, + 0, + 6, + 1, + 6, + 2, + 6, + 3, + 6, + 4, + 6, + 5, + 6, + 6, + 6, + 7, + 6, + 8, + 6, + 9, + 7, + 0, + 7, + 1, + 7, + 2, + 7, + 3, + 7, + 4, + 7, + 5, + 7, + 6, + 7, + 7, + 7, + 8, + 7, + 9, + 8, + 0, + 8, + 1, + 8, + 2, + 8, + 3, + 8, + 4, + 8, + 5, + 8, + 6, + 8, + 7, + 8, + 8, + 8, + 9, + 9, + 0, + 9, + 1, + 9, + 2, + 9, + 3, + 9, + 4, + 9, + 5, + 9, + 6, + 9, + 7, + 9, + 8, + 9, + 9, +}; + +const int32_t c_aaiHuffDemod10[169][2] = { + 0, + 0, + 0, + 1, + 0, + 2, + 0, + 3, + 0, + 4, + 0, + 5, + 0, + 6, + 0, + 7, + 0, + 8, + 0, + 9, + 0, + 10, + 0, + 11, + 0, + 12, + 1, + 0, + 1, + 1, + 1, + 2, + 1, + 3, + 1, + 4, + 1, + 5, + 1, + 6, + 1, + 7, + 1, + 8, + 1, + 9, + 1, + 10, + 1, + 11, + 1, + 12, + 2, + 0, + 2, + 1, + 2, + 2, + 2, + 3, + 2, + 4, + 2, + 5, + 2, + 6, + 2, + 7, + 2, + 8, + 2, + 9, + 2, + 10, + 2, + 11, + 2, + 12, + 3, + 0, + 3, + 1, + 3, + 2, + 3, + 3, + 3, + 4, + 3, + 5, + 3, + 6, + 3, + 7, + 3, + 8, + 3, + 9, + 3, + 10, + 3, + 11, + 3, + 12, + 4, + 0, + 4, + 1, + 4, + 2, + 4, + 3, + 4, + 4, + 4, + 5, + 4, + 6, + 4, + 7, + 4, + 8, + 4, + 9, + 4, + 10, + 4, + 11, + 4, + 12, + 5, + 0, + 5, + 1, + 5, + 2, + 5, + 3, + 5, + 4, + 5, + 5, + 5, + 6, + 5, + 7, + 5, + 8, + 5, + 9, + 5, + 10, + 5, + 11, + 5, + 12, + 6, + 0, + 6, + 1, + 6, + 2, + 6, + 3, + 6, + 4, + 6, + 5, + 6, + 6, + 6, + 7, + 6, + 8, + 6, + 9, + 6, + 10, + 6, + 11, + 6, + 12, + 7, + 0, + 7, + 1, + 7, + 2, + 7, + 3, + 7, + 4, + 7, + 5, + 7, + 6, + 7, + 7, + 7, + 8, + 7, + 9, + 7, + 10, + 7, + 11, + 7, + 12, + 8, + 0, + 8, + 1, + 8, + 2, + 8, + 3, + 8, + 4, + 8, + 5, + 8, + 6, + 8, + 7, + 8, + 8, + 8, + 9, + 8, + 10, + 8, + 11, + 8, + 12, + 9, + 0, + 9, + 1, + 9, + 2, + 9, + 3, + 9, + 4, + 9, + 5, + 9, + 6, + 9, + 7, + 9, + 8, + 9, + 9, + 9, + 10, + 9, + 11, + 9, + 12, + 10, + 0, + 10, + 1, + 10, + 2, + 10, + 3, + 10, + 4, + 10, + 5, + 10, + 6, + 10, + 7, + 10, + 8, + 10, + 9, + 10, + 10, + 10, + 11, + 10, + 12, + 11, + 0, + 11, + 1, + 11, + 2, + 11, + 3, + 11, + 4, + 11, + 5, + 11, + 6, + 11, + 7, + 11, + 8, + 11, + 9, + 11, + 10, + 11, + 11, + 11, + 12, + 12, + 0, + 12, + 1, + 12, + 2, + 12, + 3, + 12, + 4, + 12, + 5, + 12, + 6, + 12, + 7, + 12, + 8, + 12, + 9, + 12, + 10, + 12, + 11, + 12, + 12, +}; + +const int32_t c_aaiHuffDemod11[196][2] = { + 0, + 0, + 0, + 1, + 0, + 2, + 0, + 3, + 0, + 4, + 0, + 5, + 0, + 6, + 0, + 7, + 0, + 8, + 0, + 9, + 0, + 10, + 0, + 11, + 0, + 12, + 0, + 13, + 1, + 0, + 1, + 1, + 1, + 2, + 1, + 3, + 1, + 4, + 1, + 5, + 1, + 6, + 1, + 7, + 1, + 8, + 1, + 9, + 1, + 10, + 1, + 11, + 1, + 12, + 1, + 13, + 2, + 0, + 2, + 1, + 2, + 2, + 2, + 3, + 2, + 4, + 2, + 5, + 2, + 6, + 2, + 7, + 2, + 8, + 2, + 9, + 2, + 10, + 2, + 11, + 2, + 12, + 2, + 13, + 3, + 0, + 3, + 1, + 3, + 2, + 3, + 3, + 3, + 4, + 3, + 5, + 3, + 6, + 3, + 7, + 3, + 8, + 3, + 9, + 3, + 10, + 3, + 11, + 3, + 12, + 3, + 13, + 4, + 0, + 4, + 1, + 4, + 2, + 4, + 3, + 4, + 4, + 4, + 5, + 4, + 6, + 4, + 7, + 4, + 8, + 4, + 9, + 4, + 10, + 4, + 11, + 4, + 12, + 4, + 13, + 5, + 0, + 5, + 1, + 5, + 2, + 5, + 3, + 5, + 4, + 5, + 5, + 5, + 6, + 5, + 7, + 5, + 8, + 5, + 9, + 5, + 10, + 5, + 11, + 5, + 12, + 5, + 13, + 6, + 0, + 6, + 1, + 6, + 2, + 6, + 3, + 6, + 4, + 6, + 5, + 6, + 6, + 6, + 7, + 6, + 8, + 6, + 9, + 6, + 10, + 6, + 11, + 6, + 12, + 6, + 13, + 7, + 0, + 7, + 1, + 7, + 2, + 7, + 3, + 7, + 4, + 7, + 5, + 7, + 6, + 7, + 7, + 7, + 8, + 7, + 9, + 7, + 10, + 7, + 11, + 7, + 12, + 7, + 13, + 8, + 0, + 8, + 1, + 8, + 2, + 8, + 3, + 8, + 4, + 8, + 5, + 8, + 6, + 8, + 7, + 8, + 8, + 8, + 9, + 8, + 10, + 8, + 11, + 8, + 12, + 8, + 13, + 9, + 0, + 9, + 1, + 9, + 2, + 9, + 3, + 9, + 4, + 9, + 5, + 9, + 6, + 9, + 7, + 9, + 8, + 9, + 9, + 9, + 10, + 9, + 11, + 9, + 12, + 9, + 13, + 10, + 0, + 10, + 1, + 10, + 2, + 10, + 3, + 10, + 4, + 10, + 5, + 10, + 6, + 10, + 7, + 10, + 8, + 10, + 9, + 10, + 10, + 10, + 11, + 10, + 12, + 10, + 13, + 11, + 0, + 11, + 1, + 11, + 2, + 11, + 3, + 11, + 4, + 11, + 5, + 11, + 6, + 11, + 7, + 11, + 8, + 11, + 9, + 11, + 10, + 11, + 11, + 11, + 12, + 11, + 13, + 12, + 0, + 12, + 1, + 12, + 2, + 12, + 3, + 12, + 4, + 12, + 5, + 12, + 6, + 12, + 7, + 12, + 8, + 12, + 9, + 12, + 10, + 12, + 11, + 12, + 12, + 12, + 13, + 13, + 0, + 13, + 1, + 13, + 2, + 13, + 3, + 13, + 4, + 13, + 5, + 13, + 6, + 13, + 7, + 13, + 8, + 13, + 9, + 13, + 10, + 13, + 11, + 13, + 12, + 13, + 13, +}; + +const int32_t c_aaiHuffDemod12[289][2] = { + 0, + 0, + 0, + 1, + 0, + 2, + 0, + 3, + 0, + 4, + 0, + 5, + 0, + 6, + 0, + 7, + 0, + 8, + 0, + 9, + 0, + 10, + 0, + 11, + 0, + 12, + 0, + 13, + 0, + 14, + 0, + 15, + 0, + 16, + 1, + 0, + 1, + 1, + 1, + 2, + 1, + 3, + 1, + 4, + 1, + 5, + 1, + 6, + 1, + 7, + 1, + 8, + 1, + 9, + 1, + 10, + 1, + 11, + 1, + 12, + 1, + 13, + 1, + 14, + 1, + 15, + 1, + 16, + 2, + 0, + 2, + 1, + 2, + 2, + 2, + 3, + 2, + 4, + 2, + 5, + 2, + 6, + 2, + 7, + 2, + 8, + 2, + 9, + 2, + 10, + 2, + 11, + 2, + 12, + 2, + 13, + 2, + 14, + 2, + 15, + 2, + 16, + 3, + 0, + 3, + 1, + 3, + 2, + 3, + 3, + 3, + 4, + 3, + 5, + 3, + 6, + 3, + 7, + 3, + 8, + 3, + 9, + 3, + 10, + 3, + 11, + 3, + 12, + 3, + 13, + 3, + 14, + 3, + 15, + 3, + 16, + 4, + 0, + 4, + 1, + 4, + 2, + 4, + 3, + 4, + 4, + 4, + 5, + 4, + 6, + 4, + 7, + 4, + 8, + 4, + 9, + 4, + 10, + 4, + 11, + 4, + 12, + 4, + 13, + 4, + 14, + 4, + 15, + 4, + 16, + 5, + 0, + 5, + 1, + 5, + 2, + 5, + 3, + 5, + 4, + 5, + 5, + 5, + 6, + 5, + 7, + 5, + 8, + 5, + 9, + 5, + 10, + 5, + 11, + 5, + 12, + 5, + 13, + 5, + 14, + 5, + 15, + 5, + 16, + 6, + 0, + 6, + 1, + 6, + 2, + 6, + 3, + 6, + 4, + 6, + 5, + 6, + 6, + 6, + 7, + 6, + 8, + 6, + 9, + 6, + 10, + 6, + 11, + 6, + 12, + 6, + 13, + 6, + 14, + 6, + 15, + 6, + 16, + 7, + 0, + 7, + 1, + 7, + 2, + 7, + 3, + 7, + 4, + 7, + 5, + 7, + 6, + 7, + 7, + 7, + 8, + 7, + 9, + 7, + 10, + 7, + 11, + 7, + 12, + 7, + 13, + 7, + 14, + 7, + 15, + 7, + 16, + 8, + 0, + 8, + 1, + 8, + 2, + 8, + 3, + 8, + 4, + 8, + 5, + 8, + 6, + 8, + 7, + 8, + 8, + 8, + 9, + 8, + 10, + 8, + 11, + 8, + 12, + 8, + 13, + 8, + 14, + 8, + 15, + 8, + 16, + 9, + 0, + 9, + 1, + 9, + 2, + 9, + 3, + 9, + 4, + 9, + 5, + 9, + 6, + 9, + 7, + 9, + 8, + 9, + 9, + 9, + 10, + 9, + 11, + 9, + 12, + 9, + 13, + 9, + 14, + 9, + 15, + 9, + 16, + 10, + 0, + 10, + 1, + 10, + 2, + 10, + 3, + 10, + 4, + 10, + 5, + 10, + 6, + 10, + 7, + 10, + 8, + 10, + 9, + 10, + 10, + 10, + 11, + 10, + 12, + 10, + 13, + 10, + 14, + 10, + 15, + 10, + 16, + 11, + 0, + 11, + 1, + 11, + 2, + 11, + 3, + 11, + 4, + 11, + 5, + 11, + 6, + 11, + 7, + 11, + 8, + 11, + 9, + 11, + 10, + 11, + 11, + 11, + 12, + 11, + 13, + 11, + 14, + 11, + 15, + 11, + 16, + 12, + 0, + 12, + 1, + 12, + 2, + 12, + 3, + 12, + 4, + 12, + 5, + 12, + 6, + 12, + 7, + 12, + 8, + 12, + 9, + 12, + 10, + 12, + 11, + 12, + 12, + 12, + 13, + 12, + 14, + 12, + 15, + 12, + 16, + 13, + 0, + 13, + 1, + 13, + 2, + 13, + 3, + 13, + 4, + 13, + 5, + 13, + 6, + 13, + 7, + 13, + 8, + 13, + 9, + 13, + 10, + 13, + 11, + 13, + 12, + 13, + 13, + 13, + 14, + 13, + 15, + 13, + 16, + 14, + 0, + 14, + 1, + 14, + 2, + 14, + 3, + 14, + 4, + 14, + 5, + 14, + 6, + 14, + 7, + 14, + 8, + 14, + 9, + 14, + 10, + 14, + 11, + 14, + 12, + 14, + 13, + 14, + 14, + 14, + 15, + 14, + 16, + 15, + 0, + 15, + 1, + 15, + 2, + 15, + 3, + 15, + 4, + 15, + 5, + 15, + 6, + 15, + 7, + 15, + 8, + 15, + 9, + 15, + 10, + 15, + 11, + 15, + 12, + 15, + 13, + 15, + 14, + 15, + 15, + 15, + 16, + 16, + 0, + 16, + 1, + 16, + 2, + 16, + 3, + 16, + 4, + 16, + 5, + 16, + 6, + 16, + 7, + 16, + 8, + 16, + 9, + 16, + 10, + 16, + 11, + 16, + 12, + 16, + 13, + 16, + 14, + 16, + 15, + 16, + 16, +}; + +const int32_t c_aaiHuffDemod13[324][2] = { + 0, + 0, + 0, + 1, + 0, + 2, + 0, + 3, + 0, + 4, + 0, + 5, + 0, + 6, + 0, + 7, + 0, + 8, + 0, + 9, + 0, + 10, + 0, + 11, + 0, + 12, + 0, + 13, + 0, + 14, + 0, + 15, + 0, + 16, + 0, + 17, + 1, + 0, + 1, + 1, + 1, + 2, + 1, + 3, + 1, + 4, + 1, + 5, + 1, + 6, + 1, + 7, + 1, + 8, + 1, + 9, + 1, + 10, + 1, + 11, + 1, + 12, + 1, + 13, + 1, + 14, + 1, + 15, + 1, + 16, + 1, + 17, + 2, + 0, + 2, + 1, + 2, + 2, + 2, + 3, + 2, + 4, + 2, + 5, + 2, + 6, + 2, + 7, + 2, + 8, + 2, + 9, + 2, + 10, + 2, + 11, + 2, + 12, + 2, + 13, + 2, + 14, + 2, + 15, + 2, + 16, + 2, + 17, + 3, + 0, + 3, + 1, + 3, + 2, + 3, + 3, + 3, + 4, + 3, + 5, + 3, + 6, + 3, + 7, + 3, + 8, + 3, + 9, + 3, + 10, + 3, + 11, + 3, + 12, + 3, + 13, + 3, + 14, + 3, + 15, + 3, + 16, + 3, + 17, + 4, + 0, + 4, + 1, + 4, + 2, + 4, + 3, + 4, + 4, + 4, + 5, + 4, + 6, + 4, + 7, + 4, + 8, + 4, + 9, + 4, + 10, + 4, + 11, + 4, + 12, + 4, + 13, + 4, + 14, + 4, + 15, + 4, + 16, + 4, + 17, + 5, + 0, + 5, + 1, + 5, + 2, + 5, + 3, + 5, + 4, + 5, + 5, + 5, + 6, + 5, + 7, + 5, + 8, + 5, + 9, + 5, + 10, + 5, + 11, + 5, + 12, + 5, + 13, + 5, + 14, + 5, + 15, + 5, + 16, + 5, + 17, + 6, + 0, + 6, + 1, + 6, + 2, + 6, + 3, + 6, + 4, + 6, + 5, + 6, + 6, + 6, + 7, + 6, + 8, + 6, + 9, + 6, + 10, + 6, + 11, + 6, + 12, + 6, + 13, + 6, + 14, + 6, + 15, + 6, + 16, + 6, + 17, + 7, + 0, + 7, + 1, + 7, + 2, + 7, + 3, + 7, + 4, + 7, + 5, + 7, + 6, + 7, + 7, + 7, + 8, + 7, + 9, + 7, + 10, + 7, + 11, + 7, + 12, + 7, + 13, + 7, + 14, + 7, + 15, + 7, + 16, + 7, + 17, + 8, + 0, + 8, + 1, + 8, + 2, + 8, + 3, + 8, + 4, + 8, + 5, + 8, + 6, + 8, + 7, + 8, + 8, + 8, + 9, + 8, + 10, + 8, + 11, + 8, + 12, + 8, + 13, + 8, + 14, + 8, + 15, + 8, + 16, + 8, + 17, + 9, + 0, + 9, + 1, + 9, + 2, + 9, + 3, + 9, + 4, + 9, + 5, + 9, + 6, + 9, + 7, + 9, + 8, + 9, + 9, + 9, + 10, + 9, + 11, + 9, + 12, + 9, + 13, + 9, + 14, + 9, + 15, + 9, + 16, + 9, + 17, + 10, + 0, + 10, + 1, + 10, + 2, + 10, + 3, + 10, + 4, + 10, + 5, + 10, + 6, + 10, + 7, + 10, + 8, + 10, + 9, + 10, + 10, + 10, + 11, + 10, + 12, + 10, + 13, + 10, + 14, + 10, + 15, + 10, + 16, + 10, + 17, + 11, + 0, + 11, + 1, + 11, + 2, + 11, + 3, + 11, + 4, + 11, + 5, + 11, + 6, + 11, + 7, + 11, + 8, + 11, + 9, + 11, + 10, + 11, + 11, + 11, + 12, + 11, + 13, + 11, + 14, + 11, + 15, + 11, + 16, + 11, + 17, + 12, + 0, + 12, + 1, + 12, + 2, + 12, + 3, + 12, + 4, + 12, + 5, + 12, + 6, + 12, + 7, + 12, + 8, + 12, + 9, + 12, + 10, + 12, + 11, + 12, + 12, + 12, + 13, + 12, + 14, + 12, + 15, + 12, + 16, + 12, + 17, + 13, + 0, + 13, + 1, + 13, + 2, + 13, + 3, + 13, + 4, + 13, + 5, + 13, + 6, + 13, + 7, + 13, + 8, + 13, + 9, + 13, + 10, + 13, + 11, + 13, + 12, + 13, + 13, + 13, + 14, + 13, + 15, + 13, + 16, + 13, + 17, + 14, + 0, + 14, + 1, + 14, + 2, + 14, + 3, + 14, + 4, + 14, + 5, + 14, + 6, + 14, + 7, + 14, + 8, + 14, + 9, + 14, + 10, + 14, + 11, + 14, + 12, + 14, + 13, + 14, + 14, + 14, + 15, + 14, + 16, + 14, + 17, + 15, + 0, + 15, + 1, + 15, + 2, + 15, + 3, + 15, + 4, + 15, + 5, + 15, + 6, + 15, + 7, + 15, + 8, + 15, + 9, + 15, + 10, + 15, + 11, + 15, + 12, + 15, + 13, + 15, + 14, + 15, + 15, + 15, + 16, + 15, + 17, + 16, + 0, + 16, + 1, + 16, + 2, + 16, + 3, + 16, + 4, + 16, + 5, + 16, + 6, + 16, + 7, + 16, + 8, + 16, + 9, + 16, + 10, + 16, + 11, + 16, + 12, + 16, + 13, + 16, + 14, + 16, + 15, + 16, + 16, + 16, + 17, + 17, + 0, + 17, + 1, + 17, + 2, + 17, + 3, + 17, + 4, + 17, + 5, + 17, + 6, + 17, + 7, + 17, + 8, + 17, + 9, + 17, + 10, + 17, + 11, + 17, + 12, + 17, + 13, + 17, + 14, + 17, + 15, + 17, + 16, + 17, + 17, +}; + +const int32_t c_aaiHuffDemod14[400][2] = { + 0, + 0, + 0, + 1, + 0, + 2, + 0, + 3, + 0, + 4, + 0, + 5, + 0, + 6, + 0, + 7, + 0, + 8, + 0, + 9, + 0, + 10, + 0, + 11, + 0, + 12, + 0, + 13, + 0, + 14, + 0, + 15, + 0, + 16, + 0, + 17, + 0, + 18, + 0, + 19, + 1, + 0, + 1, + 1, + 1, + 2, + 1, + 3, + 1, + 4, + 1, + 5, + 1, + 6, + 1, + 7, + 1, + 8, + 1, + 9, + 1, + 10, + 1, + 11, + 1, + 12, + 1, + 13, + 1, + 14, + 1, + 15, + 1, + 16, + 1, + 17, + 1, + 18, + 1, + 19, + 2, + 0, + 2, + 1, + 2, + 2, + 2, + 3, + 2, + 4, + 2, + 5, + 2, + 6, + 2, + 7, + 2, + 8, + 2, + 9, + 2, + 10, + 2, + 11, + 2, + 12, + 2, + 13, + 2, + 14, + 2, + 15, + 2, + 16, + 2, + 17, + 2, + 18, + 2, + 19, + 3, + 0, + 3, + 1, + 3, + 2, + 3, + 3, + 3, + 4, + 3, + 5, + 3, + 6, + 3, + 7, + 3, + 8, + 3, + 9, + 3, + 10, + 3, + 11, + 3, + 12, + 3, + 13, + 3, + 14, + 3, + 15, + 3, + 16, + 3, + 17, + 3, + 18, + 3, + 19, + 4, + 0, + 4, + 1, + 4, + 2, + 4, + 3, + 4, + 4, + 4, + 5, + 4, + 6, + 4, + 7, + 4, + 8, + 4, + 9, + 4, + 10, + 4, + 11, + 4, + 12, + 4, + 13, + 4, + 14, + 4, + 15, + 4, + 16, + 4, + 17, + 4, + 18, + 4, + 19, + 5, + 0, + 5, + 1, + 5, + 2, + 5, + 3, + 5, + 4, + 5, + 5, + 5, + 6, + 5, + 7, + 5, + 8, + 5, + 9, + 5, + 10, + 5, + 11, + 5, + 12, + 5, + 13, + 5, + 14, + 5, + 15, + 5, + 16, + 5, + 17, + 5, + 18, + 5, + 19, + 6, + 0, + 6, + 1, + 6, + 2, + 6, + 3, + 6, + 4, + 6, + 5, + 6, + 6, + 6, + 7, + 6, + 8, + 6, + 9, + 6, + 10, + 6, + 11, + 6, + 12, + 6, + 13, + 6, + 14, + 6, + 15, + 6, + 16, + 6, + 17, + 6, + 18, + 6, + 19, + 7, + 0, + 7, + 1, + 7, + 2, + 7, + 3, + 7, + 4, + 7, + 5, + 7, + 6, + 7, + 7, + 7, + 8, + 7, + 9, + 7, + 10, + 7, + 11, + 7, + 12, + 7, + 13, + 7, + 14, + 7, + 15, + 7, + 16, + 7, + 17, + 7, + 18, + 7, + 19, + 8, + 0, + 8, + 1, + 8, + 2, + 8, + 3, + 8, + 4, + 8, + 5, + 8, + 6, + 8, + 7, + 8, + 8, + 8, + 9, + 8, + 10, + 8, + 11, + 8, + 12, + 8, + 13, + 8, + 14, + 8, + 15, + 8, + 16, + 8, + 17, + 8, + 18, + 8, + 19, + 9, + 0, + 9, + 1, + 9, + 2, + 9, + 3, + 9, + 4, + 9, + 5, + 9, + 6, + 9, + 7, + 9, + 8, + 9, + 9, + 9, + 10, + 9, + 11, + 9, + 12, + 9, + 13, + 9, + 14, + 9, + 15, + 9, + 16, + 9, + 17, + 9, + 18, + 9, + 19, + 10, + 0, + 10, + 1, + 10, + 2, + 10, + 3, + 10, + 4, + 10, + 5, + 10, + 6, + 10, + 7, + 10, + 8, + 10, + 9, + 10, + 10, + 10, + 11, + 10, + 12, + 10, + 13, + 10, + 14, + 10, + 15, + 10, + 16, + 10, + 17, + 10, + 18, + 10, + 19, + 11, + 0, + 11, + 1, + 11, + 2, + 11, + 3, + 11, + 4, + 11, + 5, + 11, + 6, + 11, + 7, + 11, + 8, + 11, + 9, + 11, + 10, + 11, + 11, + 11, + 12, + 11, + 13, + 11, + 14, + 11, + 15, + 11, + 16, + 11, + 17, + 11, + 18, + 11, + 19, + 12, + 0, + 12, + 1, + 12, + 2, + 12, + 3, + 12, + 4, + 12, + 5, + 12, + 6, + 12, + 7, + 12, + 8, + 12, + 9, + 12, + 10, + 12, + 11, + 12, + 12, + 12, + 13, + 12, + 14, + 12, + 15, + 12, + 16, + 12, + 17, + 12, + 18, + 12, + 19, + 13, + 0, + 13, + 1, + 13, + 2, + 13, + 3, + 13, + 4, + 13, + 5, + 13, + 6, + 13, + 7, + 13, + 8, + 13, + 9, + 13, + 10, + 13, + 11, + 13, + 12, + 13, + 13, + 13, + 14, + 13, + 15, + 13, + 16, + 13, + 17, + 13, + 18, + 13, + 19, + 14, + 0, + 14, + 1, + 14, + 2, + 14, + 3, + 14, + 4, + 14, + 5, + 14, + 6, + 14, + 7, + 14, + 8, + 14, + 9, + 14, + 10, + 14, + 11, + 14, + 12, + 14, + 13, + 14, + 14, + 14, + 15, + 14, + 16, + 14, + 17, + 14, + 18, + 14, + 19, + 15, + 0, + 15, + 1, + 15, + 2, + 15, + 3, + 15, + 4, + 15, + 5, + 15, + 6, + 15, + 7, + 15, + 8, + 15, + 9, + 15, + 10, + 15, + 11, + 15, + 12, + 15, + 13, + 15, + 14, + 15, + 15, + 15, + 16, + 15, + 17, + 15, + 18, + 15, + 19, + 16, + 0, + 16, + 1, + 16, + 2, + 16, + 3, + 16, + 4, + 16, + 5, + 16, + 6, + 16, + 7, + 16, + 8, + 16, + 9, + 16, + 10, + 16, + 11, + 16, + 12, + 16, + 13, + 16, + 14, + 16, + 15, + 16, + 16, + 16, + 17, + 16, + 18, + 16, + 19, + 17, + 0, + 17, + 1, + 17, + 2, + 17, + 3, + 17, + 4, + 17, + 5, + 17, + 6, + 17, + 7, + 17, + 8, + 17, + 9, + 17, + 10, + 17, + 11, + 17, + 12, + 17, + 13, + 17, + 14, + 17, + 15, + 17, + 16, + 17, + 17, + 17, + 18, + 17, + 19, + 18, + 0, + 18, + 1, + 18, + 2, + 18, + 3, + 18, + 4, + 18, + 5, + 18, + 6, + 18, + 7, + 18, + 8, + 18, + 9, + 18, + 10, + 18, + 11, + 18, + 12, + 18, + 13, + 18, + 14, + 18, + 15, + 18, + 16, + 18, + 17, + 18, + 18, + 18, + 19, + 19, + 0, + 19, + 1, + 19, + 2, + 19, + 3, + 19, + 4, + 19, + 5, + 19, + 6, + 19, + 7, + 19, + 8, + 19, + 9, + 19, + 10, + 19, + 11, + 19, + 12, + 19, + 13, + 19, + 14, + 19, + 15, + 19, + 16, + 19, + 17, + 19, + 18, + 19, + 19, +}; + +const int32_t c_aaiHuffDemod15[576][2] = { + 0, + 0, + 0, + 1, + 0, + 2, + 0, + 3, + 0, + 4, + 0, + 5, + 0, + 6, + 0, + 7, + 0, + 8, + 0, + 9, + 0, + 10, + 0, + 11, + 0, + 12, + 0, + 13, + 0, + 14, + 0, + 15, + 0, + 16, + 0, + 17, + 0, + 18, + 0, + 19, + 0, + 20, + 0, + 21, + 0, + 22, + 0, + 23, + 1, + 0, + 1, + 1, + 1, + 2, + 1, + 3, + 1, + 4, + 1, + 5, + 1, + 6, + 1, + 7, + 1, + 8, + 1, + 9, + 1, + 10, + 1, + 11, + 1, + 12, + 1, + 13, + 1, + 14, + 1, + 15, + 1, + 16, + 1, + 17, + 1, + 18, + 1, + 19, + 1, + 20, + 1, + 21, + 1, + 22, + 1, + 23, + 2, + 0, + 2, + 1, + 2, + 2, + 2, + 3, + 2, + 4, + 2, + 5, + 2, + 6, + 2, + 7, + 2, + 8, + 2, + 9, + 2, + 10, + 2, + 11, + 2, + 12, + 2, + 13, + 2, + 14, + 2, + 15, + 2, + 16, + 2, + 17, + 2, + 18, + 2, + 19, + 2, + 20, + 2, + 21, + 2, + 22, + 2, + 23, + 3, + 0, + 3, + 1, + 3, + 2, + 3, + 3, + 3, + 4, + 3, + 5, + 3, + 6, + 3, + 7, + 3, + 8, + 3, + 9, + 3, + 10, + 3, + 11, + 3, + 12, + 3, + 13, + 3, + 14, + 3, + 15, + 3, + 16, + 3, + 17, + 3, + 18, + 3, + 19, + 3, + 20, + 3, + 21, + 3, + 22, + 3, + 23, + 4, + 0, + 4, + 1, + 4, + 2, + 4, + 3, + 4, + 4, + 4, + 5, + 4, + 6, + 4, + 7, + 4, + 8, + 4, + 9, + 4, + 10, + 4, + 11, + 4, + 12, + 4, + 13, + 4, + 14, + 4, + 15, + 4, + 16, + 4, + 17, + 4, + 18, + 4, + 19, + 4, + 20, + 4, + 21, + 4, + 22, + 4, + 23, + 5, + 0, + 5, + 1, + 5, + 2, + 5, + 3, + 5, + 4, + 5, + 5, + 5, + 6, + 5, + 7, + 5, + 8, + 5, + 9, + 5, + 10, + 5, + 11, + 5, + 12, + 5, + 13, + 5, + 14, + 5, + 15, + 5, + 16, + 5, + 17, + 5, + 18, + 5, + 19, + 5, + 20, + 5, + 21, + 5, + 22, + 5, + 23, + 6, + 0, + 6, + 1, + 6, + 2, + 6, + 3, + 6, + 4, + 6, + 5, + 6, + 6, + 6, + 7, + 6, + 8, + 6, + 9, + 6, + 10, + 6, + 11, + 6, + 12, + 6, + 13, + 6, + 14, + 6, + 15, + 6, + 16, + 6, + 17, + 6, + 18, + 6, + 19, + 6, + 20, + 6, + 21, + 6, + 22, + 6, + 23, + 7, + 0, + 7, + 1, + 7, + 2, + 7, + 3, + 7, + 4, + 7, + 5, + 7, + 6, + 7, + 7, + 7, + 8, + 7, + 9, + 7, + 10, + 7, + 11, + 7, + 12, + 7, + 13, + 7, + 14, + 7, + 15, + 7, + 16, + 7, + 17, + 7, + 18, + 7, + 19, + 7, + 20, + 7, + 21, + 7, + 22, + 7, + 23, + 8, + 0, + 8, + 1, + 8, + 2, + 8, + 3, + 8, + 4, + 8, + 5, + 8, + 6, + 8, + 7, + 8, + 8, + 8, + 9, + 8, + 10, + 8, + 11, + 8, + 12, + 8, + 13, + 8, + 14, + 8, + 15, + 8, + 16, + 8, + 17, + 8, + 18, + 8, + 19, + 8, + 20, + 8, + 21, + 8, + 22, + 8, + 23, + 9, + 0, + 9, + 1, + 9, + 2, + 9, + 3, + 9, + 4, + 9, + 5, + 9, + 6, + 9, + 7, + 9, + 8, + 9, + 9, + 9, + 10, + 9, + 11, + 9, + 12, + 9, + 13, + 9, + 14, + 9, + 15, + 9, + 16, + 9, + 17, + 9, + 18, + 9, + 19, + 9, + 20, + 9, + 21, + 9, + 22, + 9, + 23, + 10, + 0, + 10, + 1, + 10, + 2, + 10, + 3, + 10, + 4, + 10, + 5, + 10, + 6, + 10, + 7, + 10, + 8, + 10, + 9, + 10, + 10, + 10, + 11, + 10, + 12, + 10, + 13, + 10, + 14, + 10, + 15, + 10, + 16, + 10, + 17, + 10, + 18, + 10, + 19, + 10, + 20, + 10, + 21, + 10, + 22, + 10, + 23, + 11, + 0, + 11, + 1, + 11, + 2, + 11, + 3, + 11, + 4, + 11, + 5, + 11, + 6, + 11, + 7, + 11, + 8, + 11, + 9, + 11, + 10, + 11, + 11, + 11, + 12, + 11, + 13, + 11, + 14, + 11, + 15, + 11, + 16, + 11, + 17, + 11, + 18, + 11, + 19, + 11, + 20, + 11, + 21, + 11, + 22, + 11, + 23, + 12, + 0, + 12, + 1, + 12, + 2, + 12, + 3, + 12, + 4, + 12, + 5, + 12, + 6, + 12, + 7, + 12, + 8, + 12, + 9, + 12, + 10, + 12, + 11, + 12, + 12, + 12, + 13, + 12, + 14, + 12, + 15, + 12, + 16, + 12, + 17, + 12, + 18, + 12, + 19, + 12, + 20, + 12, + 21, + 12, + 22, + 12, + 23, + 13, + 0, + 13, + 1, + 13, + 2, + 13, + 3, + 13, + 4, + 13, + 5, + 13, + 6, + 13, + 7, + 13, + 8, + 13, + 9, + 13, + 10, + 13, + 11, + 13, + 12, + 13, + 13, + 13, + 14, + 13, + 15, + 13, + 16, + 13, + 17, + 13, + 18, + 13, + 19, + 13, + 20, + 13, + 21, + 13, + 22, + 13, + 23, + 14, + 0, + 14, + 1, + 14, + 2, + 14, + 3, + 14, + 4, + 14, + 5, + 14, + 6, + 14, + 7, + 14, + 8, + 14, + 9, + 14, + 10, + 14, + 11, + 14, + 12, + 14, + 13, + 14, + 14, + 14, + 15, + 14, + 16, + 14, + 17, + 14, + 18, + 14, + 19, + 14, + 20, + 14, + 21, + 14, + 22, + 14, + 23, + 15, + 0, + 15, + 1, + 15, + 2, + 15, + 3, + 15, + 4, + 15, + 5, + 15, + 6, + 15, + 7, + 15, + 8, + 15, + 9, + 15, + 10, + 15, + 11, + 15, + 12, + 15, + 13, + 15, + 14, + 15, + 15, + 15, + 16, + 15, + 17, + 15, + 18, + 15, + 19, + 15, + 20, + 15, + 21, + 15, + 22, + 15, + 23, + 16, + 0, + 16, + 1, + 16, + 2, + 16, + 3, + 16, + 4, + 16, + 5, + 16, + 6, + 16, + 7, + 16, + 8, + 16, + 9, + 16, + 10, + 16, + 11, + 16, + 12, + 16, + 13, + 16, + 14, + 16, + 15, + 16, + 16, + 16, + 17, + 16, + 18, + 16, + 19, + 16, + 20, + 16, + 21, + 16, + 22, + 16, + 23, + 17, + 0, + 17, + 1, + 17, + 2, + 17, + 3, + 17, + 4, + 17, + 5, + 17, + 6, + 17, + 7, + 17, + 8, + 17, + 9, + 17, + 10, + 17, + 11, + 17, + 12, + 17, + 13, + 17, + 14, + 17, + 15, + 17, + 16, + 17, + 17, + 17, + 18, + 17, + 19, + 17, + 20, + 17, + 21, + 17, + 22, + 17, + 23, + 18, + 0, + 18, + 1, + 18, + 2, + 18, + 3, + 18, + 4, + 18, + 5, + 18, + 6, + 18, + 7, + 18, + 8, + 18, + 9, + 18, + 10, + 18, + 11, + 18, + 12, + 18, + 13, + 18, + 14, + 18, + 15, + 18, + 16, + 18, + 17, + 18, + 18, + 18, + 19, + 18, + 20, + 18, + 21, + 18, + 22, + 18, + 23, + 19, + 0, + 19, + 1, + 19, + 2, + 19, + 3, + 19, + 4, + 19, + 5, + 19, + 6, + 19, + 7, + 19, + 8, + 19, + 9, + 19, + 10, + 19, + 11, + 19, + 12, + 19, + 13, + 19, + 14, + 19, + 15, + 19, + 16, + 19, + 17, + 19, + 18, + 19, + 19, + 19, + 20, + 19, + 21, + 19, + 22, + 19, + 23, + 20, + 0, + 20, + 1, + 20, + 2, + 20, + 3, + 20, + 4, + 20, + 5, + 20, + 6, + 20, + 7, + 20, + 8, + 20, + 9, + 20, + 10, + 20, + 11, + 20, + 12, + 20, + 13, + 20, + 14, + 20, + 15, + 20, + 16, + 20, + 17, + 20, + 18, + 20, + 19, + 20, + 20, + 20, + 21, + 20, + 22, + 20, + 23, + 21, + 0, + 21, + 1, + 21, + 2, + 21, + 3, + 21, + 4, + 21, + 5, + 21, + 6, + 21, + 7, + 21, + 8, + 21, + 9, + 21, + 10, + 21, + 11, + 21, + 12, + 21, + 13, + 21, + 14, + 21, + 15, + 21, + 16, + 21, + 17, + 21, + 18, + 21, + 19, + 21, + 20, + 21, + 21, + 21, + 22, + 21, + 23, + 22, + 0, + 22, + 1, + 22, + 2, + 22, + 3, + 22, + 4, + 22, + 5, + 22, + 6, + 22, + 7, + 22, + 8, + 22, + 9, + 22, + 10, + 22, + 11, + 22, + 12, + 22, + 13, + 22, + 14, + 22, + 15, + 22, + 16, + 22, + 17, + 22, + 18, + 22, + 19, + 22, + 20, + 22, + 21, + 22, + 22, + 22, + 23, + 23, + 0, + 23, + 1, + 23, + 2, + 23, + 3, + 23, + 4, + 23, + 5, + 23, + 6, + 23, + 7, + 23, + 8, + 23, + 9, + 23, + 10, + 23, + 11, + 23, + 12, + 23, + 13, + 23, + 14, + 23, + 15, + 23, + 16, + 23, + 17, + 23, + 18, + 23, + 19, + 23, + 20, + 23, + 21, + 23, + 22, + 23, + 23, +}; + +const int32_t c_aaiHuffDemod16[729][2] = { + 0, + 0, + 0, + 1, + 0, + 2, + 0, + 3, + 0, + 4, + 0, + 5, + 0, + 6, + 0, + 7, + 0, + 8, + 0, + 9, + 0, + 10, + 0, + 11, + 0, + 12, + 0, + 13, + 0, + 14, + 0, + 15, + 0, + 16, + 0, + 17, + 0, + 18, + 0, + 19, + 0, + 20, + 0, + 21, + 0, + 22, + 0, + 23, + 0, + 24, + 0, + 25, + 0, + 26, + 1, + 0, + 1, + 1, + 1, + 2, + 1, + 3, + 1, + 4, + 1, + 5, + 1, + 6, + 1, + 7, + 1, + 8, + 1, + 9, + 1, + 10, + 1, + 11, + 1, + 12, + 1, + 13, + 1, + 14, + 1, + 15, + 1, + 16, + 1, + 17, + 1, + 18, + 1, + 19, + 1, + 20, + 1, + 21, + 1, + 22, + 1, + 23, + 1, + 24, + 1, + 25, + 1, + 26, + 2, + 0, + 2, + 1, + 2, + 2, + 2, + 3, + 2, + 4, + 2, + 5, + 2, + 6, + 2, + 7, + 2, + 8, + 2, + 9, + 2, + 10, + 2, + 11, + 2, + 12, + 2, + 13, + 2, + 14, + 2, + 15, + 2, + 16, + 2, + 17, + 2, + 18, + 2, + 19, + 2, + 20, + 2, + 21, + 2, + 22, + 2, + 23, + 2, + 24, + 2, + 25, + 2, + 26, + 3, + 0, + 3, + 1, + 3, + 2, + 3, + 3, + 3, + 4, + 3, + 5, + 3, + 6, + 3, + 7, + 3, + 8, + 3, + 9, + 3, + 10, + 3, + 11, + 3, + 12, + 3, + 13, + 3, + 14, + 3, + 15, + 3, + 16, + 3, + 17, + 3, + 18, + 3, + 19, + 3, + 20, + 3, + 21, + 3, + 22, + 3, + 23, + 3, + 24, + 3, + 25, + 3, + 26, + 4, + 0, + 4, + 1, + 4, + 2, + 4, + 3, + 4, + 4, + 4, + 5, + 4, + 6, + 4, + 7, + 4, + 8, + 4, + 9, + 4, + 10, + 4, + 11, + 4, + 12, + 4, + 13, + 4, + 14, + 4, + 15, + 4, + 16, + 4, + 17, + 4, + 18, + 4, + 19, + 4, + 20, + 4, + 21, + 4, + 22, + 4, + 23, + 4, + 24, + 4, + 25, + 4, + 26, + 5, + 0, + 5, + 1, + 5, + 2, + 5, + 3, + 5, + 4, + 5, + 5, + 5, + 6, + 5, + 7, + 5, + 8, + 5, + 9, + 5, + 10, + 5, + 11, + 5, + 12, + 5, + 13, + 5, + 14, + 5, + 15, + 5, + 16, + 5, + 17, + 5, + 18, + 5, + 19, + 5, + 20, + 5, + 21, + 5, + 22, + 5, + 23, + 5, + 24, + 5, + 25, + 5, + 26, + 6, + 0, + 6, + 1, + 6, + 2, + 6, + 3, + 6, + 4, + 6, + 5, + 6, + 6, + 6, + 7, + 6, + 8, + 6, + 9, + 6, + 10, + 6, + 11, + 6, + 12, + 6, + 13, + 6, + 14, + 6, + 15, + 6, + 16, + 6, + 17, + 6, + 18, + 6, + 19, + 6, + 20, + 6, + 21, + 6, + 22, + 6, + 23, + 6, + 24, + 6, + 25, + 6, + 26, + 7, + 0, + 7, + 1, + 7, + 2, + 7, + 3, + 7, + 4, + 7, + 5, + 7, + 6, + 7, + 7, + 7, + 8, + 7, + 9, + 7, + 10, + 7, + 11, + 7, + 12, + 7, + 13, + 7, + 14, + 7, + 15, + 7, + 16, + 7, + 17, + 7, + 18, + 7, + 19, + 7, + 20, + 7, + 21, + 7, + 22, + 7, + 23, + 7, + 24, + 7, + 25, + 7, + 26, + 8, + 0, + 8, + 1, + 8, + 2, + 8, + 3, + 8, + 4, + 8, + 5, + 8, + 6, + 8, + 7, + 8, + 8, + 8, + 9, + 8, + 10, + 8, + 11, + 8, + 12, + 8, + 13, + 8, + 14, + 8, + 15, + 8, + 16, + 8, + 17, + 8, + 18, + 8, + 19, + 8, + 20, + 8, + 21, + 8, + 22, + 8, + 23, + 8, + 24, + 8, + 25, + 8, + 26, + 9, + 0, + 9, + 1, + 9, + 2, + 9, + 3, + 9, + 4, + 9, + 5, + 9, + 6, + 9, + 7, + 9, + 8, + 9, + 9, + 9, + 10, + 9, + 11, + 9, + 12, + 9, + 13, + 9, + 14, + 9, + 15, + 9, + 16, + 9, + 17, + 9, + 18, + 9, + 19, + 9, + 20, + 9, + 21, + 9, + 22, + 9, + 23, + 9, + 24, + 9, + 25, + 9, + 26, + 10, + 0, + 10, + 1, + 10, + 2, + 10, + 3, + 10, + 4, + 10, + 5, + 10, + 6, + 10, + 7, + 10, + 8, + 10, + 9, + 10, + 10, + 10, + 11, + 10, + 12, + 10, + 13, + 10, + 14, + 10, + 15, + 10, + 16, + 10, + 17, + 10, + 18, + 10, + 19, + 10, + 20, + 10, + 21, + 10, + 22, + 10, + 23, + 10, + 24, + 10, + 25, + 10, + 26, + 11, + 0, + 11, + 1, + 11, + 2, + 11, + 3, + 11, + 4, + 11, + 5, + 11, + 6, + 11, + 7, + 11, + 8, + 11, + 9, + 11, + 10, + 11, + 11, + 11, + 12, + 11, + 13, + 11, + 14, + 11, + 15, + 11, + 16, + 11, + 17, + 11, + 18, + 11, + 19, + 11, + 20, + 11, + 21, + 11, + 22, + 11, + 23, + 11, + 24, + 11, + 25, + 11, + 26, + 12, + 0, + 12, + 1, + 12, + 2, + 12, + 3, + 12, + 4, + 12, + 5, + 12, + 6, + 12, + 7, + 12, + 8, + 12, + 9, + 12, + 10, + 12, + 11, + 12, + 12, + 12, + 13, + 12, + 14, + 12, + 15, + 12, + 16, + 12, + 17, + 12, + 18, + 12, + 19, + 12, + 20, + 12, + 21, + 12, + 22, + 12, + 23, + 12, + 24, + 12, + 25, + 12, + 26, + 13, + 0, + 13, + 1, + 13, + 2, + 13, + 3, + 13, + 4, + 13, + 5, + 13, + 6, + 13, + 7, + 13, + 8, + 13, + 9, + 13, + 10, + 13, + 11, + 13, + 12, + 13, + 13, + 13, + 14, + 13, + 15, + 13, + 16, + 13, + 17, + 13, + 18, + 13, + 19, + 13, + 20, + 13, + 21, + 13, + 22, + 13, + 23, + 13, + 24, + 13, + 25, + 13, + 26, + 14, + 0, + 14, + 1, + 14, + 2, + 14, + 3, + 14, + 4, + 14, + 5, + 14, + 6, + 14, + 7, + 14, + 8, + 14, + 9, + 14, + 10, + 14, + 11, + 14, + 12, + 14, + 13, + 14, + 14, + 14, + 15, + 14, + 16, + 14, + 17, + 14, + 18, + 14, + 19, + 14, + 20, + 14, + 21, + 14, + 22, + 14, + 23, + 14, + 24, + 14, + 25, + 14, + 26, + 15, + 0, + 15, + 1, + 15, + 2, + 15, + 3, + 15, + 4, + 15, + 5, + 15, + 6, + 15, + 7, + 15, + 8, + 15, + 9, + 15, + 10, + 15, + 11, + 15, + 12, + 15, + 13, + 15, + 14, + 15, + 15, + 15, + 16, + 15, + 17, + 15, + 18, + 15, + 19, + 15, + 20, + 15, + 21, + 15, + 22, + 15, + 23, + 15, + 24, + 15, + 25, + 15, + 26, + 16, + 0, + 16, + 1, + 16, + 2, + 16, + 3, + 16, + 4, + 16, + 5, + 16, + 6, + 16, + 7, + 16, + 8, + 16, + 9, + 16, + 10, + 16, + 11, + 16, + 12, + 16, + 13, + 16, + 14, + 16, + 15, + 16, + 16, + 16, + 17, + 16, + 18, + 16, + 19, + 16, + 20, + 16, + 21, + 16, + 22, + 16, + 23, + 16, + 24, + 16, + 25, + 16, + 26, + 17, + 0, + 17, + 1, + 17, + 2, + 17, + 3, + 17, + 4, + 17, + 5, + 17, + 6, + 17, + 7, + 17, + 8, + 17, + 9, + 17, + 10, + 17, + 11, + 17, + 12, + 17, + 13, + 17, + 14, + 17, + 15, + 17, + 16, + 17, + 17, + 17, + 18, + 17, + 19, + 17, + 20, + 17, + 21, + 17, + 22, + 17, + 23, + 17, + 24, + 17, + 25, + 17, + 26, + 18, + 0, + 18, + 1, + 18, + 2, + 18, + 3, + 18, + 4, + 18, + 5, + 18, + 6, + 18, + 7, + 18, + 8, + 18, + 9, + 18, + 10, + 18, + 11, + 18, + 12, + 18, + 13, + 18, + 14, + 18, + 15, + 18, + 16, + 18, + 17, + 18, + 18, + 18, + 19, + 18, + 20, + 18, + 21, + 18, + 22, + 18, + 23, + 18, + 24, + 18, + 25, + 18, + 26, + 19, + 0, + 19, + 1, + 19, + 2, + 19, + 3, + 19, + 4, + 19, + 5, + 19, + 6, + 19, + 7, + 19, + 8, + 19, + 9, + 19, + 10, + 19, + 11, + 19, + 12, + 19, + 13, + 19, + 14, + 19, + 15, + 19, + 16, + 19, + 17, + 19, + 18, + 19, + 19, + 19, + 20, + 19, + 21, + 19, + 22, + 19, + 23, + 19, + 24, + 19, + 25, + 19, + 26, + 20, + 0, + 20, + 1, + 20, + 2, + 20, + 3, + 20, + 4, + 20, + 5, + 20, + 6, + 20, + 7, + 20, + 8, + 20, + 9, + 20, + 10, + 20, + 11, + 20, + 12, + 20, + 13, + 20, + 14, + 20, + 15, + 20, + 16, + 20, + 17, + 20, + 18, + 20, + 19, + 20, + 20, + 20, + 21, + 20, + 22, + 20, + 23, + 20, + 24, + 20, + 25, + 20, + 26, + 21, + 0, + 21, + 1, + 21, + 2, + 21, + 3, + 21, + 4, + 21, + 5, + 21, + 6, + 21, + 7, + 21, + 8, + 21, + 9, + 21, + 10, + 21, + 11, + 21, + 12, + 21, + 13, + 21, + 14, + 21, + 15, + 21, + 16, + 21, + 17, + 21, + 18, + 21, + 19, + 21, + 20, + 21, + 21, + 21, + 22, + 21, + 23, + 21, + 24, + 21, + 25, + 21, + 26, + 22, + 0, + 22, + 1, + 22, + 2, + 22, + 3, + 22, + 4, + 22, + 5, + 22, + 6, + 22, + 7, + 22, + 8, + 22, + 9, + 22, + 10, + 22, + 11, + 22, + 12, + 22, + 13, + 22, + 14, + 22, + 15, + 22, + 16, + 22, + 17, + 22, + 18, + 22, + 19, + 22, + 20, + 22, + 21, + 22, + 22, + 22, + 23, + 22, + 24, + 22, + 25, + 22, + 26, + 23, + 0, + 23, + 1, + 23, + 2, + 23, + 3, + 23, + 4, + 23, + 5, + 23, + 6, + 23, + 7, + 23, + 8, + 23, + 9, + 23, + 10, + 23, + 11, + 23, + 12, + 23, + 13, + 23, + 14, + 23, + 15, + 23, + 16, + 23, + 17, + 23, + 18, + 23, + 19, + 23, + 20, + 23, + 21, + 23, + 22, + 23, + 23, + 23, + 24, + 23, + 25, + 23, + 26, + 24, + 0, + 24, + 1, + 24, + 2, + 24, + 3, + 24, + 4, + 24, + 5, + 24, + 6, + 24, + 7, + 24, + 8, + 24, + 9, + 24, + 10, + 24, + 11, + 24, + 12, + 24, + 13, + 24, + 14, + 24, + 15, + 24, + 16, + 24, + 17, + 24, + 18, + 24, + 19, + 24, + 20, + 24, + 21, + 24, + 22, + 24, + 23, + 24, + 24, + 24, + 25, + 24, + 26, + 25, + 0, + 25, + 1, + 25, + 2, + 25, + 3, + 25, + 4, + 25, + 5, + 25, + 6, + 25, + 7, + 25, + 8, + 25, + 9, + 25, + 10, + 25, + 11, + 25, + 12, + 25, + 13, + 25, + 14, + 25, + 15, + 25, + 16, + 25, + 17, + 25, + 18, + 25, + 19, + 25, + 20, + 25, + 21, + 25, + 22, + 25, + 23, + 25, + 24, + 25, + 25, + 25, + 26, + 26, + 0, + 26, + 1, + 26, + 2, + 26, + 3, + 26, + 4, + 26, + 5, + 26, + 6, + 26, + 7, + 26, + 8, + 26, + 9, + 26, + 10, + 26, + 11, + 26, + 12, + 26, + 13, + 26, + 14, + 26, + 15, + 26, + 16, + 26, + 17, + 26, + 18, + 26, + 19, + 26, + 20, + 26, + 21, + 26, + 22, + 26, + 23, + 26, + 24, + 26, + 25, + 26, + 26, +}; + +const int32_t c_aaiHuffDemod17[729][2] = { + 0, + 0, + 0, + 1, + 0, + 2, + 0, + 3, + 0, + 4, + 0, + 5, + 0, + 6, + 0, + 7, + 0, + 8, + 0, + 9, + 0, + 10, + 0, + 11, + 0, + 12, + 0, + 13, + 0, + 14, + 0, + 15, + 0, + 16, + 0, + 17, + 0, + 18, + 0, + 19, + 0, + 20, + 0, + 21, + 0, + 22, + 0, + 23, + 0, + 24, + 0, + 25, + 0, + 26, + 1, + 0, + 1, + 1, + 1, + 2, + 1, + 3, + 1, + 4, + 1, + 5, + 1, + 6, + 1, + 7, + 1, + 8, + 1, + 9, + 1, + 10, + 1, + 11, + 1, + 12, + 1, + 13, + 1, + 14, + 1, + 15, + 1, + 16, + 1, + 17, + 1, + 18, + 1, + 19, + 1, + 20, + 1, + 21, + 1, + 22, + 1, + 23, + 1, + 24, + 1, + 25, + 1, + 26, + 2, + 0, + 2, + 1, + 2, + 2, + 2, + 3, + 2, + 4, + 2, + 5, + 2, + 6, + 2, + 7, + 2, + 8, + 2, + 9, + 2, + 10, + 2, + 11, + 2, + 12, + 2, + 13, + 2, + 14, + 2, + 15, + 2, + 16, + 2, + 17, + 2, + 18, + 2, + 19, + 2, + 20, + 2, + 21, + 2, + 22, + 2, + 23, + 2, + 24, + 2, + 25, + 2, + 26, + 3, + 0, + 3, + 1, + 3, + 2, + 3, + 3, + 3, + 4, + 3, + 5, + 3, + 6, + 3, + 7, + 3, + 8, + 3, + 9, + 3, + 10, + 3, + 11, + 3, + 12, + 3, + 13, + 3, + 14, + 3, + 15, + 3, + 16, + 3, + 17, + 3, + 18, + 3, + 19, + 3, + 20, + 3, + 21, + 3, + 22, + 3, + 23, + 3, + 24, + 3, + 25, + 3, + 26, + 4, + 0, + 4, + 1, + 4, + 2, + 4, + 3, + 4, + 4, + 4, + 5, + 4, + 6, + 4, + 7, + 4, + 8, + 4, + 9, + 4, + 10, + 4, + 11, + 4, + 12, + 4, + 13, + 4, + 14, + 4, + 15, + 4, + 16, + 4, + 17, + 4, + 18, + 4, + 19, + 4, + 20, + 4, + 21, + 4, + 22, + 4, + 23, + 4, + 24, + 4, + 25, + 4, + 26, + 5, + 0, + 5, + 1, + 5, + 2, + 5, + 3, + 5, + 4, + 5, + 5, + 5, + 6, + 5, + 7, + 5, + 8, + 5, + 9, + 5, + 10, + 5, + 11, + 5, + 12, + 5, + 13, + 5, + 14, + 5, + 15, + 5, + 16, + 5, + 17, + 5, + 18, + 5, + 19, + 5, + 20, + 5, + 21, + 5, + 22, + 5, + 23, + 5, + 24, + 5, + 25, + 5, + 26, + 6, + 0, + 6, + 1, + 6, + 2, + 6, + 3, + 6, + 4, + 6, + 5, + 6, + 6, + 6, + 7, + 6, + 8, + 6, + 9, + 6, + 10, + 6, + 11, + 6, + 12, + 6, + 13, + 6, + 14, + 6, + 15, + 6, + 16, + 6, + 17, + 6, + 18, + 6, + 19, + 6, + 20, + 6, + 21, + 6, + 22, + 6, + 23, + 6, + 24, + 6, + 25, + 6, + 26, + 7, + 0, + 7, + 1, + 7, + 2, + 7, + 3, + 7, + 4, + 7, + 5, + 7, + 6, + 7, + 7, + 7, + 8, + 7, + 9, + 7, + 10, + 7, + 11, + 7, + 12, + 7, + 13, + 7, + 14, + 7, + 15, + 7, + 16, + 7, + 17, + 7, + 18, + 7, + 19, + 7, + 20, + 7, + 21, + 7, + 22, + 7, + 23, + 7, + 24, + 7, + 25, + 7, + 26, + 8, + 0, + 8, + 1, + 8, + 2, + 8, + 3, + 8, + 4, + 8, + 5, + 8, + 6, + 8, + 7, + 8, + 8, + 8, + 9, + 8, + 10, + 8, + 11, + 8, + 12, + 8, + 13, + 8, + 14, + 8, + 15, + 8, + 16, + 8, + 17, + 8, + 18, + 8, + 19, + 8, + 20, + 8, + 21, + 8, + 22, + 8, + 23, + 8, + 24, + 8, + 25, + 8, + 26, + 9, + 0, + 9, + 1, + 9, + 2, + 9, + 3, + 9, + 4, + 9, + 5, + 9, + 6, + 9, + 7, + 9, + 8, + 9, + 9, + 9, + 10, + 9, + 11, + 9, + 12, + 9, + 13, + 9, + 14, + 9, + 15, + 9, + 16, + 9, + 17, + 9, + 18, + 9, + 19, + 9, + 20, + 9, + 21, + 9, + 22, + 9, + 23, + 9, + 24, + 9, + 25, + 9, + 26, + 10, + 0, + 10, + 1, + 10, + 2, + 10, + 3, + 10, + 4, + 10, + 5, + 10, + 6, + 10, + 7, + 10, + 8, + 10, + 9, + 10, + 10, + 10, + 11, + 10, + 12, + 10, + 13, + 10, + 14, + 10, + 15, + 10, + 16, + 10, + 17, + 10, + 18, + 10, + 19, + 10, + 20, + 10, + 21, + 10, + 22, + 10, + 23, + 10, + 24, + 10, + 25, + 10, + 26, + 11, + 0, + 11, + 1, + 11, + 2, + 11, + 3, + 11, + 4, + 11, + 5, + 11, + 6, + 11, + 7, + 11, + 8, + 11, + 9, + 11, + 10, + 11, + 11, + 11, + 12, + 11, + 13, + 11, + 14, + 11, + 15, + 11, + 16, + 11, + 17, + 11, + 18, + 11, + 19, + 11, + 20, + 11, + 21, + 11, + 22, + 11, + 23, + 11, + 24, + 11, + 25, + 11, + 26, + 12, + 0, + 12, + 1, + 12, + 2, + 12, + 3, + 12, + 4, + 12, + 5, + 12, + 6, + 12, + 7, + 12, + 8, + 12, + 9, + 12, + 10, + 12, + 11, + 12, + 12, + 12, + 13, + 12, + 14, + 12, + 15, + 12, + 16, + 12, + 17, + 12, + 18, + 12, + 19, + 12, + 20, + 12, + 21, + 12, + 22, + 12, + 23, + 12, + 24, + 12, + 25, + 12, + 26, + 13, + 0, + 13, + 1, + 13, + 2, + 13, + 3, + 13, + 4, + 13, + 5, + 13, + 6, + 13, + 7, + 13, + 8, + 13, + 9, + 13, + 10, + 13, + 11, + 13, + 12, + 13, + 13, + 13, + 14, + 13, + 15, + 13, + 16, + 13, + 17, + 13, + 18, + 13, + 19, + 13, + 20, + 13, + 21, + 13, + 22, + 13, + 23, + 13, + 24, + 13, + 25, + 13, + 26, + 14, + 0, + 14, + 1, + 14, + 2, + 14, + 3, + 14, + 4, + 14, + 5, + 14, + 6, + 14, + 7, + 14, + 8, + 14, + 9, + 14, + 10, + 14, + 11, + 14, + 12, + 14, + 13, + 14, + 14, + 14, + 15, + 14, + 16, + 14, + 17, + 14, + 18, + 14, + 19, + 14, + 20, + 14, + 21, + 14, + 22, + 14, + 23, + 14, + 24, + 14, + 25, + 14, + 26, + 15, + 0, + 15, + 1, + 15, + 2, + 15, + 3, + 15, + 4, + 15, + 5, + 15, + 6, + 15, + 7, + 15, + 8, + 15, + 9, + 15, + 10, + 15, + 11, + 15, + 12, + 15, + 13, + 15, + 14, + 15, + 15, + 15, + 16, + 15, + 17, + 15, + 18, + 15, + 19, + 15, + 20, + 15, + 21, + 15, + 22, + 15, + 23, + 15, + 24, + 15, + 25, + 15, + 26, + 16, + 0, + 16, + 1, + 16, + 2, + 16, + 3, + 16, + 4, + 16, + 5, + 16, + 6, + 16, + 7, + 16, + 8, + 16, + 9, + 16, + 10, + 16, + 11, + 16, + 12, + 16, + 13, + 16, + 14, + 16, + 15, + 16, + 16, + 16, + 17, + 16, + 18, + 16, + 19, + 16, + 20, + 16, + 21, + 16, + 22, + 16, + 23, + 16, + 24, + 16, + 25, + 16, + 26, + 17, + 0, + 17, + 1, + 17, + 2, + 17, + 3, + 17, + 4, + 17, + 5, + 17, + 6, + 17, + 7, + 17, + 8, + 17, + 9, + 17, + 10, + 17, + 11, + 17, + 12, + 17, + 13, + 17, + 14, + 17, + 15, + 17, + 16, + 17, + 17, + 17, + 18, + 17, + 19, + 17, + 20, + 17, + 21, + 17, + 22, + 17, + 23, + 17, + 24, + 17, + 25, + 17, + 26, + 18, + 0, + 18, + 1, + 18, + 2, + 18, + 3, + 18, + 4, + 18, + 5, + 18, + 6, + 18, + 7, + 18, + 8, + 18, + 9, + 18, + 10, + 18, + 11, + 18, + 12, + 18, + 13, + 18, + 14, + 18, + 15, + 18, + 16, + 18, + 17, + 18, + 18, + 18, + 19, + 18, + 20, + 18, + 21, + 18, + 22, + 18, + 23, + 18, + 24, + 18, + 25, + 18, + 26, + 19, + 0, + 19, + 1, + 19, + 2, + 19, + 3, + 19, + 4, + 19, + 5, + 19, + 6, + 19, + 7, + 19, + 8, + 19, + 9, + 19, + 10, + 19, + 11, + 19, + 12, + 19, + 13, + 19, + 14, + 19, + 15, + 19, + 16, + 19, + 17, + 19, + 18, + 19, + 19, + 19, + 20, + 19, + 21, + 19, + 22, + 19, + 23, + 19, + 24, + 19, + 25, + 19, + 26, + 20, + 0, + 20, + 1, + 20, + 2, + 20, + 3, + 20, + 4, + 20, + 5, + 20, + 6, + 20, + 7, + 20, + 8, + 20, + 9, + 20, + 10, + 20, + 11, + 20, + 12, + 20, + 13, + 20, + 14, + 20, + 15, + 20, + 16, + 20, + 17, + 20, + 18, + 20, + 19, + 20, + 20, + 20, + 21, + 20, + 22, + 20, + 23, + 20, + 24, + 20, + 25, + 20, + 26, + 21, + 0, + 21, + 1, + 21, + 2, + 21, + 3, + 21, + 4, + 21, + 5, + 21, + 6, + 21, + 7, + 21, + 8, + 21, + 9, + 21, + 10, + 21, + 11, + 21, + 12, + 21, + 13, + 21, + 14, + 21, + 15, + 21, + 16, + 21, + 17, + 21, + 18, + 21, + 19, + 21, + 20, + 21, + 21, + 21, + 22, + 21, + 23, + 21, + 24, + 21, + 25, + 21, + 26, + 22, + 0, + 22, + 1, + 22, + 2, + 22, + 3, + 22, + 4, + 22, + 5, + 22, + 6, + 22, + 7, + 22, + 8, + 22, + 9, + 22, + 10, + 22, + 11, + 22, + 12, + 22, + 13, + 22, + 14, + 22, + 15, + 22, + 16, + 22, + 17, + 22, + 18, + 22, + 19, + 22, + 20, + 22, + 21, + 22, + 22, + 22, + 23, + 22, + 24, + 22, + 25, + 22, + 26, + 23, + 0, + 23, + 1, + 23, + 2, + 23, + 3, + 23, + 4, + 23, + 5, + 23, + 6, + 23, + 7, + 23, + 8, + 23, + 9, + 23, + 10, + 23, + 11, + 23, + 12, + 23, + 13, + 23, + 14, + 23, + 15, + 23, + 16, + 23, + 17, + 23, + 18, + 23, + 19, + 23, + 20, + 23, + 21, + 23, + 22, + 23, + 23, + 23, + 24, + 23, + 25, + 23, + 26, + 24, + 0, + 24, + 1, + 24, + 2, + 24, + 3, + 24, + 4, + 24, + 5, + 24, + 6, + 24, + 7, + 24, + 8, + 24, + 9, + 24, + 10, + 24, + 11, + 24, + 12, + 24, + 13, + 24, + 14, + 24, + 15, + 24, + 16, + 24, + 17, + 24, + 18, + 24, + 19, + 24, + 20, + 24, + 21, + 24, + 22, + 24, + 23, + 24, + 24, + 24, + 25, + 24, + 26, + 25, + 0, + 25, + 1, + 25, + 2, + 25, + 3, + 25, + 4, + 25, + 5, + 25, + 6, + 25, + 7, + 25, + 8, + 25, + 9, + 25, + 10, + 25, + 11, + 25, + 12, + 25, + 13, + 25, + 14, + 25, + 15, + 25, + 16, + 25, + 17, + 25, + 18, + 25, + 19, + 25, + 20, + 25, + 21, + 25, + 22, + 25, + 23, + 25, + 24, + 25, + 25, + 25, + 26, + 26, + 0, + 26, + 1, + 26, + 2, + 26, + 3, + 26, + 4, + 26, + 5, + 26, + 6, + 26, + 7, + 26, + 8, + 26, + 9, + 26, + 10, + 26, + 11, + 26, + 12, + 26, + 13, + 26, + 14, + 26, + 15, + 26, + 16, + 26, + 17, + 26, + 18, + 26, + 19, + 26, + 20, + 26, + 21, + 26, + 22, + 26, + 23, + 26, + 24, + 26, + 25, + 26, + 26, +}; + +const int32_t ( *c_apaiDemodTables[ALLOC_TABLE_SIZE] )[2] = { + NULL, + c_aaiHuffDemod1, + c_aaiHuffDemod2, + c_aaiHuffDemod3, + c_aaiHuffDemod4, + c_aaiHuffDemod5, + c_aaiHuffDemod6, + c_aaiHuffDemod7, + c_aaiHuffDemod8, + c_aaiHuffDemod9, + c_aaiHuffDemod10, + c_aaiHuffDemod11, + c_aaiHuffDemod12, + c_aaiHuffDemod13, + c_aaiHuffDemod14, + c_aaiHuffDemod15, + c_aaiHuffDemod16, + c_aaiHuffDemod17, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, +}; +#endif +const Word16 c_aiLogAddTable_fx[LOG_ADD_TABLE_LENGTH] = { + 0x40, + 0x40, + 0x3F, + 0x3F, + 0x3E, + 0x3E, + 0x3D, + 0x3D, + 0x3C, + 0x3C, + 0x3B, + 0x3B, + 0x3A, + 0x3A, + 0x39, + 0x39, + 0x38, + 0x38, + 0x37, + 0x37, + 0x37, + 0x36, + 0x36, + 0x35, + 0x35, + 0x34, + 0x34, + 0x33, + 0x33, + 0x33, + 0x32, + 0x32, + 0x31, + 0x31, + 0x31, + 0x30, + 0x30, + 0x2F, + 0x2F, + 0x2F, + 0x2E, + 0x2E, + 0x2D, + 0x2D, + 0x2D, + 0x2C, + 0x2C, + 0x2B, + 0x2B, + 0x2B, + 0x2A, + 0x2A, + 0x2A, + 0x29, + 0x29, + 0x29, + 0x28, + 0x28, + 0x27, + 0x27, + 0x27, + 0x26, + 0x26, + 0x26, + 0x25, + 0x25, + 0x25, + 0x24, + 0x24, + 0x24, + 0x23, + 0x23, + 0x23, + 0x23, + 0x22, + 0x22, + 0x22, + 0x21, + 0x21, + 0x21, + 0x20, + 0x20, + 0x20, + 0x20, + 0x1F, + 0x1F, + 0x1F, + 0x1E, + 0x1E, + 0x1E, + 0x1E, + 0x1D, + 0x1D, + 0x1D, + 0x1C, + 0x1C, + 0x1C, + 0x1C, + 0x1B, + 0x1B, + 0x1B, + 0x1B, + 0x1A, + 0x1A, + 0x1A, + 0x1A, + 0x19, + 0x19, + 0x19, + 0x19, + 0x18, + 0x18, + 0x18, + 0x18, + 0x18, + 0x17, + 0x17, + 0x17, + 0x17, + 0x16, + 0x16, + 0x16, + 0x16, + 0x16, + 0x15, + 0x15, + 0x15, + 0x15, + 0x15, + 0x14, + 0x14, + 0x14, + 0x14, + 0x14, + 0x13, + 0x13, + 0x13, + 0x13, + 0x13, + 0x13, + 0x12, + 0x12, + 0x12, + 0x12, + 0x12, + 0x11, + 0x11, + 0x11, + 0x11, + 0x11, + 0x11, + 0x10, + 0x10, + 0x10, + 0x10, + 0x10, + 0x10, + 0x0F, + 0x0F, + 0x0F, + 0x0F, + 0x0F, + 0x0F, + 0x0F, + 0x0E, + 0x0E, + 0x0E, + 0x0E, + 0x0E, + 0x0E, + 0x0E, + 0x0D, + 0x0D, + 0x0D, + 0x0D, + 0x0D, + 0x0D, + 0x0D, + 0x0D, + 0x0C, + 0x0C, + 0x0C, + 0x0C, + 0x0C, + 0x0C, + 0x0C, + 0x0C, + 0x0B, + 0x0B, + 0x0B, + 0x0B, + 0x0B, + 0x0B, + 0x0B, + 0x0B, + 0x0B, + 0x0A, + 0x0A, + 0x0A, + 0x0A, + 0x0A, + 0x0A, + 0x0A, + 0x0A, + 0x0A, + 0x0A, + 0x09, + 0x09, + 0x09, + 0x09, + 0x09, + 0x09, + 0x09, + 0x09, + 0x09, + 0x09, + 0x08, + 0x08, + 0x08, + 0x08, + 0x08, + 0x08, + 0x08, + 0x08, + 0x08, + 0x08, + 0x08, + 0x08, + 0x08, + 0x07, + 0x07, + 0x07, + 0x07, + 0x07, + 0x07, + 0x07, + 0x07, + 0x07, + 0x07, + 0x07, + 0x07, + 0x07, + 0x06, + 0x06, + 0x06, + 0x06, + 0x06, + 0x06, + 0x06, + 0x06, + 0x06, + 0x06, + 0x06, + 0x06, + 0x06, + 0x06, + 0x06, + 0x06, + 0x05, + 0x05, + 0x05, + 0x05, + 0x05, + 0x05, + 0x05, + 0x05, + 0x05, + 0x05, + 0x05, + 0x05, + 0x05, + 0x05, + 0x05, + 0x05, + 0x05, + 0x05, + 0x05, + 0x04, + 0x04, + 0x04, + 0x04, + 0x04, + 0x04, + 0x04, + 0x04, + 0x04, + 0x04, + 0x04, + 0x04, + 0x04, + 0x04, + 0x04, + 0x04, + 0x04, + 0x04, + 0x04, + 0x04, + 0x04, + 0x04, + 0x04, + 0x04, + 0x03, + 0x03, + 0x03, + 0x03, + 0x03, + 0x03, + 0x03, + 0x03, + 0x03, + 0x03, + 0x03, + 0x03, + 0x03, + 0x03, + 0x03, + 0x03, + 0x03, + 0x03, + 0x03, + 0x03, + 0x03, + 0x03, + 0x03, + 0x03, + 0x03, + 0x03, + 0x03, + 0x03, + 0x03, + 0x03, + 0x03, + 0x02, + 0x02, + 0x02, + 0x02, + 0x02, + 0x02, + 0x02, + 0x02, + 0x02, + 0x02, + 0x02, + 0x02, + 0x02, + 0x02, + 0x02, + 0x02, + 0x02, + 0x02, + 0x02, + 0x02, + 0x02, + 0x02, + 0x02, + 0x02, + 0x02, + 0x02, + 0x02, + 0x02, + 0x02, + 0x02, + 0x02, + 0x02, + 0x02, + 0x02, + 0x02, + 0x02, + 0x02, + 0x02, + 0x02, + 0x02, + 0x02, + 0x02, + 0x02, + 0x02, + 0x02, + 0x02, + 0x02, + 0x02, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, +}; +const int32_t c_aiLogAddTable[LOG_ADD_TABLE_LENGTH] = { + 0x40, + 0x40, + 0x3F, + 0x3F, + 0x3E, + 0x3E, + 0x3D, + 0x3D, + 0x3C, + 0x3C, + 0x3B, + 0x3B, + 0x3A, + 0x3A, + 0x39, + 0x39, + 0x38, + 0x38, + 0x37, + 0x37, + 0x37, + 0x36, + 0x36, + 0x35, + 0x35, + 0x34, + 0x34, + 0x33, + 0x33, + 0x33, + 0x32, + 0x32, + 0x31, + 0x31, + 0x31, + 0x30, + 0x30, + 0x2F, + 0x2F, + 0x2F, + 0x2E, + 0x2E, + 0x2D, + 0x2D, + 0x2D, + 0x2C, + 0x2C, + 0x2B, + 0x2B, + 0x2B, + 0x2A, + 0x2A, + 0x2A, + 0x29, + 0x29, + 0x29, + 0x28, + 0x28, + 0x27, + 0x27, + 0x27, + 0x26, + 0x26, + 0x26, + 0x25, + 0x25, + 0x25, + 0x24, + 0x24, + 0x24, + 0x23, + 0x23, + 0x23, + 0x23, + 0x22, + 0x22, + 0x22, + 0x21, + 0x21, + 0x21, + 0x20, + 0x20, + 0x20, + 0x20, + 0x1F, + 0x1F, + 0x1F, + 0x1E, + 0x1E, + 0x1E, + 0x1E, + 0x1D, + 0x1D, + 0x1D, + 0x1C, + 0x1C, + 0x1C, + 0x1C, + 0x1B, + 0x1B, + 0x1B, + 0x1B, + 0x1A, + 0x1A, + 0x1A, + 0x1A, + 0x19, + 0x19, + 0x19, + 0x19, + 0x18, + 0x18, + 0x18, + 0x18, + 0x18, + 0x17, + 0x17, + 0x17, + 0x17, + 0x16, + 0x16, + 0x16, + 0x16, + 0x16, + 0x15, + 0x15, + 0x15, + 0x15, + 0x15, + 0x14, + 0x14, + 0x14, + 0x14, + 0x14, + 0x13, + 0x13, + 0x13, + 0x13, + 0x13, + 0x13, + 0x12, + 0x12, + 0x12, + 0x12, + 0x12, + 0x11, + 0x11, + 0x11, + 0x11, + 0x11, + 0x11, + 0x10, + 0x10, + 0x10, + 0x10, + 0x10, + 0x10, + 0x0F, + 0x0F, + 0x0F, + 0x0F, + 0x0F, + 0x0F, + 0x0F, + 0x0E, + 0x0E, + 0x0E, + 0x0E, + 0x0E, + 0x0E, + 0x0E, + 0x0D, + 0x0D, + 0x0D, + 0x0D, + 0x0D, + 0x0D, + 0x0D, + 0x0D, + 0x0C, + 0x0C, + 0x0C, + 0x0C, + 0x0C, + 0x0C, + 0x0C, + 0x0C, + 0x0B, + 0x0B, + 0x0B, + 0x0B, + 0x0B, + 0x0B, + 0x0B, + 0x0B, + 0x0B, + 0x0A, + 0x0A, + 0x0A, + 0x0A, + 0x0A, + 0x0A, + 0x0A, + 0x0A, + 0x0A, + 0x0A, + 0x09, + 0x09, + 0x09, + 0x09, + 0x09, + 0x09, + 0x09, + 0x09, + 0x09, + 0x09, + 0x08, + 0x08, + 0x08, + 0x08, + 0x08, + 0x08, + 0x08, + 0x08, + 0x08, + 0x08, + 0x08, + 0x08, + 0x08, + 0x07, + 0x07, + 0x07, + 0x07, + 0x07, + 0x07, + 0x07, + 0x07, + 0x07, + 0x07, + 0x07, + 0x07, + 0x07, + 0x06, + 0x06, + 0x06, + 0x06, + 0x06, + 0x06, + 0x06, + 0x06, + 0x06, + 0x06, + 0x06, + 0x06, + 0x06, + 0x06, + 0x06, + 0x06, + 0x05, + 0x05, + 0x05, + 0x05, + 0x05, + 0x05, + 0x05, + 0x05, + 0x05, + 0x05, + 0x05, + 0x05, + 0x05, + 0x05, + 0x05, + 0x05, + 0x05, + 0x05, + 0x05, + 0x04, + 0x04, + 0x04, + 0x04, + 0x04, + 0x04, + 0x04, + 0x04, + 0x04, + 0x04, + 0x04, + 0x04, + 0x04, + 0x04, + 0x04, + 0x04, + 0x04, + 0x04, + 0x04, + 0x04, + 0x04, + 0x04, + 0x04, + 0x04, + 0x03, + 0x03, + 0x03, + 0x03, + 0x03, + 0x03, + 0x03, + 0x03, + 0x03, + 0x03, + 0x03, + 0x03, + 0x03, + 0x03, + 0x03, + 0x03, + 0x03, + 0x03, + 0x03, + 0x03, + 0x03, + 0x03, + 0x03, + 0x03, + 0x03, + 0x03, + 0x03, + 0x03, + 0x03, + 0x03, + 0x03, + 0x02, + 0x02, + 0x02, + 0x02, + 0x02, + 0x02, + 0x02, + 0x02, + 0x02, + 0x02, + 0x02, + 0x02, + 0x02, + 0x02, + 0x02, + 0x02, + 0x02, + 0x02, + 0x02, + 0x02, + 0x02, + 0x02, + 0x02, + 0x02, + 0x02, + 0x02, + 0x02, + 0x02, + 0x02, + 0x02, + 0x02, + 0x02, + 0x02, + 0x02, + 0x02, + 0x02, + 0x02, + 0x02, + 0x02, + 0x02, + 0x02, + 0x02, + 0x02, + 0x02, + 0x02, + 0x02, + 0x02, + 0x02, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, +}; +const Word16 c_aiBandwidthAdjust48_fx[MAX_BANDS_48] = { + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 64, + 64, + 64, + 64, + 64, + 101, + 101, + 128, + 165, + 165, + 180, + 213, +}; +const int32_t c_aiBandwidthAdjust48[MAX_BANDS_48] = { + + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 64, + 64, + 64, + 64, + 64, + 101, + 101, + 128, + 165, + 165, + 180, + 213, +}; + +const Word16 c_aiAbsoluteThresh48_fx[MAX_BANDS_48] = { + -1787, + -1787, + -1787, + -1787, + -1787, + -1787, + -1787, + -1787, + -1782, + -1761, + -1737, + -1679, + -1638, + -1613, + -1590, + -1568, + -1516, + -1459, + -1395, + -1289, + -671, + -409, + -401, +}; +const int32_t c_aiAbsoluteThresh48[MAX_BANDS_48] = { + -1787, + -1787, + -1787, + -1787, + -1787, + -1787, + -1787, + -1787, + -1782, + -1761, + -1737, + -1679, + -1638, + -1613, + -1590, + -1568, + -1516, + -1459, + -1395, + -1289, + -671, + -409, + -401, +}; +#if PERCEPTUAL_MODEL_SLGAIN_SHIFT == 4 +const int32_t c_aiDefaultTheta48[MAX_BANDS_48] = { + 7, + 7, + 6, + 5, + 5, + 4, + 4, + 4, + 4, + 4, + 4, + 4, + 4, + 4, + 4, + 4, + 4, + 4, + 4, + 4, + 4, + 4, + 4, +}; +#elif PERCEPTUAL_MODEL_SLGAIN_SHIFT == 8 +const Word16 c_aiDefaultTheta48_fx[MAX_BANDS_48] = { + + 112, + 112, + 96, + 80, + 80, + 64, + 64, + 64, + 64, + 64, + 64, + 64, + 64, + 64, + 64, + 64, + 64, + 64, + 64, + 64, + 64, + 64, + 64, +}; +#endif +const int32_t c_aiDefaultTheta48[MAX_BANDS_48] = { + + 112, + 112, + 96, + 80, + 80, + 64, + 64, + 64, + 64, + 64, + 64, + 64, + 64, + 64, + 64, + 64, + 64, + 64, + 64, + 64, + 64, + 64, + 64, +}; +const Word16 c_aaiSpreadFunction48_fx[MAX_BANDS_48 * MAX_BANDS_48] = { + 0, + -1561, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -289, + -4, + -1234, + -2295, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -569, + -229, + -8, + -905, + -1705, + -2324, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -789, + -445, + -173, + -16, + -656, + -1271, + -1765, + -2172, + -2520, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -961, + -616, + -340, + -136, + -28, + -488, + -976, + -1382, + -1729, + -2032, + -2305, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -1088, + -743, + -465, + -257, + -148, + -31, + -371, + -769, + -1114, + -1417, + -1689, + -2054, + -2483, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -1198, + -852, + -574, + -364, + -209, + -148, + -42, + -300, + -635, + -936, + -1207, + -1572, + -2000, + -2376, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -1293, + -948, + -669, + -458, + -301, + -183, + -145, + -56, + -258, + -547, + -816, + -1179, + -1606, + -1982, + -2311, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -1375, + -1029, + -750, + -539, + -381, + -260, + -180, + -142, + -68, + -231, + -487, + -846, + -1272, + -1647, + -1976, + -2261, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -1444, + -1099, + -820, + -608, + -449, + -328, + -233, + -194, + -138, + -77, + -213, + -555, + -978, + -1352, + -1681, + -1966, + -2268, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -1501, + -1155, + -876, + -665, + -505, + -383, + -287, + -210, + -193, + -130, + -79, + -298, + -711, + -1083, + -1411, + -1696, + -1997, + -2288, + -2550, + -2552, + -2552, + -2552, + -2552, + -1567, + -1221, + -942, + -730, + -570, + -448, + -351, + -272, + -206, + -189, + -151, + -72, + -349, + -713, + -1039, + -1324, + -1625, + -1915, + -2177, + -2448, + -2552, + -2552, + -2552, + -1650, + -1304, + -1025, + -813, + -653, + -530, + -432, + -352, + -285, + -227, + -177, + -163, + -69, + -297, + -613, + -895, + -1195, + -1485, + -1746, + -2017, + -2238, + -2401, + -2545, + -1727, + -1381, + -1102, + -890, + -730, + -607, + -509, + -428, + -360, + -301, + -249, + -180, + -153, + -72, + -257, + -527, + -824, + -1112, + -1373, + -1643, + -1865, + -2028, + -2171, + -1798, + -1452, + -1173, + -960, + -800, + -677, + -579, + -498, + -430, + -370, + -317, + -246, + -192, + -145, + -76, + -224, + -505, + -790, + -1050, + -1320, + -1540, + -1703, + -1847, + -1860, + -1514, + -1234, + -1022, + -862, + -738, + -640, + -559, + -490, + -430, + -377, + -306, + -224, + -197, + -136, + -81, + -242, + -515, + -771, + -1040, + -1260, + -1422, + -1566, + -1923, + -1577, + -1297, + -1085, + -925, + -801, + -703, + -621, + -553, + -492, + -439, + -367, + -284, + -213, + -198, + -144, + -83, + -235, + -479, + -744, + -963, + -1125, + -1268, + -1986, + -1640, + -1360, + -1148, + -988, + -864, + -766, + -684, + -615, + -555, + -501, + -429, + -345, + -273, + -211, + -204, + -146, + -89, + -216, + -465, + -680, + -841, + -984, + -2043, + -1697, + -1417, + -1205, + -1044, + -921, + -822, + -741, + -672, + -611, + -557, + -485, + -401, + -328, + -264, + -211, + -205, + -140, + -93, + -227, + -430, + -588, + -729, + -2104, + -1758, + -1479, + -1266, + -1106, + -982, + -884, + -802, + -733, + -673, + -619, + -546, + -461, + -388, + -324, + -269, + -212, + -211, + -151, + -100, + -195, + -336, + -472, + -2163, + -1817, + -1537, + -1324, + -1164, + -1040, + -942, + -860, + -791, + -731, + -676, + -604, + -519, + -445, + -380, + -325, + -268, + -226, + -219, + -147, + -114, + -167, + -280, + -2203, + -1857, + -1577, + -1365, + -1205, + -1081, + -982, + -901, + -831, + -771, + -717, + -644, + -559, + -485, + -420, + -364, + -306, + -252, + -239, + -206, + -132, + -122, + -163, + -2224, + -1878, + -1598, + -1386, + -1225, + -1102, + -1003, + -921, + -852, + -792, + -737, + -665, + -580, + -505, + -441, + -385, + -326, + -271, + -222, + -224, + -176, + -121, + -114, +}; +const int32_t c_aaiSpreadFunction48[MAX_BANDS_48 * MAX_BANDS_48] = { + 0, + -1561, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -289, + -4, + -1234, + -2295, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -569, + -229, + -8, + -905, + -1705, + -2324, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -789, + -445, + -173, + -16, + -656, + -1271, + -1765, + -2172, + -2520, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -961, + -616, + -340, + -136, + -28, + -488, + -976, + -1382, + -1729, + -2032, + -2305, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -1088, + -743, + -465, + -257, + -148, + -31, + -371, + -769, + -1114, + -1417, + -1689, + -2054, + -2483, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -1198, + -852, + -574, + -364, + -209, + -148, + -42, + -300, + -635, + -936, + -1207, + -1572, + -2000, + -2376, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -1293, + -948, + -669, + -458, + -301, + -183, + -145, + -56, + -258, + -547, + -816, + -1179, + -1606, + -1982, + -2311, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -1375, + -1029, + -750, + -539, + -381, + -260, + -180, + -142, + -68, + -231, + -487, + -846, + -1272, + -1647, + -1976, + -2261, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -1444, + -1099, + -820, + -608, + -449, + -328, + -233, + -194, + -138, + -77, + -213, + -555, + -978, + -1352, + -1681, + -1966, + -2268, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -1501, + -1155, + -876, + -665, + -505, + -383, + -287, + -210, + -193, + -130, + -79, + -298, + -711, + -1083, + -1411, + -1696, + -1997, + -2288, + -2550, + -2552, + -2552, + -2552, + -2552, + -1567, + -1221, + -942, + -730, + -570, + -448, + -351, + -272, + -206, + -189, + -151, + -72, + -349, + -713, + -1039, + -1324, + -1625, + -1915, + -2177, + -2448, + -2552, + -2552, + -2552, + -1650, + -1304, + -1025, + -813, + -653, + -530, + -432, + -352, + -285, + -227, + -177, + -163, + -69, + -297, + -613, + -895, + -1195, + -1485, + -1746, + -2017, + -2238, + -2401, + -2545, + -1727, + -1381, + -1102, + -890, + -730, + -607, + -509, + -428, + -360, + -301, + -249, + -180, + -153, + -72, + -257, + -527, + -824, + -1112, + -1373, + -1643, + -1865, + -2028, + -2171, + -1798, + -1452, + -1173, + -960, + -800, + -677, + -579, + -498, + -430, + -370, + -317, + -246, + -192, + -145, + -76, + -224, + -505, + -790, + -1050, + -1320, + -1540, + -1703, + -1847, + -1860, + -1514, + -1234, + -1022, + -862, + -738, + -640, + -559, + -490, + -430, + -377, + -306, + -224, + -197, + -136, + -81, + -242, + -515, + -771, + -1040, + -1260, + -1422, + -1566, + -1923, + -1577, + -1297, + -1085, + -925, + -801, + -703, + -621, + -553, + -492, + -439, + -367, + -284, + -213, + -198, + -144, + -83, + -235, + -479, + -744, + -963, + -1125, + -1268, + -1986, + -1640, + -1360, + -1148, + -988, + -864, + -766, + -684, + -615, + -555, + -501, + -429, + -345, + -273, + -211, + -204, + -146, + -89, + -216, + -465, + -680, + -841, + -984, + -2043, + -1697, + -1417, + -1205, + -1044, + -921, + -822, + -741, + -672, + -611, + -557, + -485, + -401, + -328, + -264, + -211, + -205, + -140, + -93, + -227, + -430, + -588, + -729, + -2104, + -1758, + -1479, + -1266, + -1106, + -982, + -884, + -802, + -733, + -673, + -619, + -546, + -461, + -388, + -324, + -269, + -212, + -211, + -151, + -100, + -195, + -336, + -472, + -2163, + -1817, + -1537, + -1324, + -1164, + -1040, + -942, + -860, + -791, + -731, + -676, + -604, + -519, + -445, + -380, + -325, + -268, + -226, + -219, + -147, + -114, + -167, + -280, + -2203, + -1857, + -1577, + -1365, + -1205, + -1081, + -982, + -901, + -831, + -771, + -717, + -644, + -559, + -485, + -420, + -364, + -306, + -252, + -239, + -206, + -132, + -122, + -163, + -2224, + -1878, + -1598, + -1386, + -1225, + -1102, + -1003, + -921, + -852, + -792, + -737, + -665, + -580, + -505, + -441, + -385, + -326, + -271, + -222, + -224, + -176, + -121, + -114, +}; + +const Word32 c_pfMagLUT[8] = /* Q31 */ +{ + 0, 394599072, 775760576, 1130504448, 1446750336, 1713728896, 1922348544, 2065504896 +}; + +const Word32 c_pfP2RRealLUT[32] = /* Q31 */ +{ + INT_MIN, -2106220416, -1984016384, -1785567488, -1518500224, -1193078272, + -821806592, -418953280, -94, 418953088, 821806400, 1193077888, + 1518500224, 1785567360, 1984016128, 2106220288, 2147483647, 2106220288, + 1984016128, 1785567360, 1518500224, 1193077888, 821806400, 418953088, + -94, -418953280, -821806592, -1193078272, -1518500224, -1785567488, + -1984016384, -2106220416 +}; + +const Word32 c_pfP2RImagLUT[32] = /* Q31 */ +{ + 188, -418953248, -821806080, -1193077888, -1518500224, -1785567232, + -1984016128, -2106220288, INT_MIN, -2106220416, -1984016128, -1785567488, + -1518500224, -1193078016, -821806464, -418953280, 0, 418953280, + 821806464, 1193078016, 1518500224, 1785567488, 1984016128, 2106220416, + 2147483647, 2106220288, 1984016128, 1785567232, 1518500224, 1193077888, + 821806080, 418953248 +}; + +const Word32 c_pfWindowLUT[LCLD_PRED_WIN_LEN] = /* Q31 */ +{ + 190779840, 338280192, 610825408, 966922816, 1352359680, 1708457216, 1981002240, 2128502656, 2128502528, 1981002240, 1708456960, 1352359808, 966922624, 610825152, 338280192, 190779776 +}; +#endif diff --git a/lib_isar/isar_lcld_rom_tables.h b/lib_isar/isar_lcld_rom_tables.h new file mode 100644 index 0000000000000000000000000000000000000000..19d40751fb9e16a7d9c723e0d745f37cfdad7f66 --- /dev/null +++ b/lib_isar/isar_lcld_rom_tables.h @@ -0,0 +1,245 @@ +/****************************************************************************************************** + + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository. All Rights Reserved. + + This software is protected by copyright law and by international treaties. + The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository retain full ownership rights in their respective contributions in + the software. This notice grants no license of any kind, including but not limited to patent + license, nor is any license granted by implication, estoppel or otherwise. + + Contributors are required to enter into the IVAS codec Public Collaboration agreement before making + contributions. + + This software is provided "AS IS", without any express or implied warranties. The software is in the + development stage. It is intended exclusively for experts who have experience with such software and + solely for the purpose of inspection. All implied warranties of non-infringement, merchantability + and fitness for a particular purpose are hereby disclaimed and excluded. + + Any dispute, controversy or claim arising under or in relation to providing this software shall be + submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in + accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and + the United Nations Convention on Contracts on the International Sales of Goods. + +*******************************************************************************************************/ + +#ifndef _ISAR_LCLD_ROM_TABLES_H_ +#define _ISAR_LCLD_ROM_TABLES_H_ + +#include +#include "options.h" +#include "typedef.h" +#ifndef M_PI + +#define M_PI 3.14159265358979323846264338327950288f // todo: replace by EVS_PI +#define M_ONE_BY_PI_FX 10430 // 1/pi in Q15 + +#endif + +#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 ) + +#define ENV0_BITS ( 7 ) + +#define ENV_DELTA_MIN ( -32 ) +#define ENV_DELTA_MIN_FX ( -1073741824 ) +#define ENV_DELTA_MAX ( 31 ) +#define ENV_DELTA_MAX_FX ( 1040187392 ) + +#define ENV_RECONSTRUCT_TABLE_SIZE ( 129 ) + +#define ENV_RECONSTRUCT_TABLE_CENTER ( 64 ) + +#define MIN_ALLOC ( 0 ) +#define MAX_ALLOC ( 31 ) + +#define ALLOC_OFFSET_SCALE ( 8 ) + +#define ALLOC_OFFSET_BITS ( 8 ) + +#define MIN_ALLOC_OFFSET ( -128 ) +#define MAX_ALLOC_OFFSET ( 127 ) +#define READ_LENGTH ( 4 ) + +#define ALLOC_TABLE_SIZE ( 32 ) + +#ifndef _PI_ +#define _PI_ ( 3.14159265358979f ) +#endif +#define PRED_MAX_VAL ( 12 ) +#define PRED_MIN_VAL ( -PRED_MAX_VAL ) +#define PRED_QUANT_FACTOR ( (float) PRED_MAX_VAL ) +#define PRED_QUANT_FACTOR_FX ( PRED_MAX_VAL ) +#define PRED_BAND0_BITS ( 5 ) + +#define PHASE_MAX_VAL ( 12 ) +#define PHASE_MIN_VAL ( -PHASE_MAX_VAL ) +#define PHASE_QUANT_FACTOR ( (float) PHASE_MAX_VAL / _PI_ ) +#define PHASE_QUANT_FACTOR_FX_Q29 ( 2050695826 ) +#define PHASE_DIFF_DIM ( 2 ) +#define PHASE_BAND0_BITS ( 5 ) + +#define PERCEPTUAL_MODEL_SLGAIN_SHIFT ( 8 ) + +// #define USE_DEMOD_TABLES + +#define HUFF_DEC_TABLE_SIZE ( 16 ) + +extern const int32_t c_aiNumLcldBandsPerBand[MAX_BANDS_48]; +extern const int32_t c_aiBandIdPerLcldBand[LCLD_BANDS]; +extern const float c_afRotRealImag[PRED_MAX_VAL - PRED_MIN_VAL + 1][2]; +extern const Word32 c_afRotRealImag_fx[PRED_MAX_VAL - PRED_MIN_VAL + 1][2]; +extern const Word16 c_aiDefaultTheta48_fx[MAX_BANDS_48]; +extern const int32_t c_aiDefaultTheta48[MAX_BANDS_48]; + +extern const float c_afScaleFactor[ALLOC_TABLE_SIZE]; +extern const float c_afInvScaleFactor[ALLOC_TABLE_SIZE]; +extern const Word32 c_afInvScaleFactor_fx[ALLOC_TABLE_SIZE]; +extern const float c_afRMSEnvReconstructTable[ENV_RECONSTRUCT_TABLE_SIZE]; +extern const int16_t c_afRMSEnvReconstructTable_exp[ENV_RECONSTRUCT_TABLE_SIZE]; +extern const int32_t c_aiQuantMaxValues[ALLOC_TABLE_SIZE]; +extern const int32_t c_aiHuffmanDim[ALLOC_TABLE_SIZE]; +extern const int32_t c_aiHuffmanMod[ALLOC_TABLE_SIZE]; +extern const Word32 c_aiHuffmanDim_fx[ALLOC_TABLE_SIZE]; +extern const Word32 c_aiHuffmanMod_fx[ALLOC_TABLE_SIZE]; +extern const Word32 c_afScaleFactor_fx[ALLOC_TABLE_SIZE]; +extern const Word32 c_aiQuantMaxValues_fx[ALLOC_TABLE_SIZE]; +extern const int32_t c_aiHuffmanSize[ALLOC_TABLE_SIZE]; + + +#define LOG_ADD_TABLE_LENGTH ( 512 ) + +extern const int32_t c_aiBandwidths48[MAX_BANDS_48]; +extern const Word16 c_aiLogAddTable_fx[LOG_ADD_TABLE_LENGTH]; +extern const Word16 c_aiBandwidthAdjust48_fx[MAX_BANDS_48]; +extern const int32_t c_aiLogAddTable[LOG_ADD_TABLE_LENGTH]; +extern const int32_t c_aiBandwidthAdjust48[MAX_BANDS_48]; + + +extern const Word16 c_aiAbsoluteThresh48_fx[MAX_BANDS_48]; +extern const Word16 c_aiDefaultTheta48_fx[MAX_BANDS_48]; +extern const Word16 c_aaiSpreadFunction48_fx[MAX_BANDS_48 * MAX_BANDS_48]; +extern const int32_t c_aiAbsoluteThresh48[MAX_BANDS_48]; +extern const int32_t c_aiDefaultTheta48[MAX_BANDS_48]; +extern const int32_t c_aaiSpreadFunction48[MAX_BANDS_48 * MAX_BANDS_48]; + + +#define PRED_QUNAT_FILTER_MAG_BITS ( 3 ) +#define PRED_QUANT_FILTER_PHASE_BITS ( 5 ) +#define PRED_QUANT_FILTER_MAG_MIN ( 0 ) +#define PRED_QUANT_FILTER_MAG_MAX ( 7 ) +#define PRED_QUANT_FILTER_PHASE_MIN ( -16 ) +#define PRED_QUANT_FILTER_PHASE_MAX ( 15 ) + +extern const uint16_t c_aauiLCLDHuffEnc1[16][2]; +extern const uint16_t c_aauiLCLDHuffEnc2[16][2]; +extern const uint16_t c_aauiLCLDHuffEnc3[25][2]; +extern const uint16_t c_aauiLCLDHuffEnc4[36][2]; +extern const uint16_t c_aauiLCLDHuffEnc5[36][2]; +extern const uint16_t c_aauiLCLDHuffEnc6[49][2]; +extern const uint16_t c_aauiLCLDHuffEnc7[64][2]; +extern const uint16_t c_aauiLCLDHuffEnc8[81][2]; +extern const uint16_t c_aauiLCLDHuffEnc9[100][2]; +extern const uint16_t c_aauiLCLDHuffEnc10[169][2]; +extern const uint16_t c_aauiLCLDHuffEnc11[196][2]; +extern const uint16_t c_aauiLCLDHuffEnc12[289][2]; +extern const uint16_t c_aauiLCLDHuffEnc13[324][2]; +extern const uint16_t c_aauiLCLDHuffEnc14[400][2]; +extern const uint16_t c_aauiLCLDHuffEnc15[576][2]; +extern const uint16_t c_aauiLCLDHuffEnc16[729][2]; +extern const uint16_t c_aauiLCLDHuffEnc17[729][2]; +extern const uint16_t c_aauiLCLDHuffEnc18[28][2]; +extern const uint16_t c_aauiLCLDHuffEnc19[29][2]; +extern const uint16_t c_aauiLCLDHuffEnc20[32][2]; +extern const uint16_t c_aauiLCLDHuffEnc21[37][2]; +extern const uint16_t c_aauiLCLDHuffEnc22[39][2]; +extern const uint16_t c_aauiLCLDHuffEnc23[46][2]; +extern const uint16_t c_aauiLCLDHuffEnc24[55][2]; +extern const uint16_t c_aauiLCLDHuffEnc25[65][2]; +extern const uint16_t c_aauiLCLDHuffEnc26[77][2]; +extern const uint16_t c_aauiLCLDHuffEnc27[91][2]; +extern const uint16_t c_aauiLCLDHuffEnc28[109][2]; +extern const uint16_t c_aauiLCLDHuffEnc29[129][2]; +extern const uint16_t c_aauiLCLDHuffEnc30[153][2]; +extern const uint16_t c_aauiLCLDHuffEnc31[181][2]; +extern const uint16_t c_aauiLCLDHuffEnc33[16][2]; +extern const uint16_t c_aauiLCLDHuffEnc34[16][2]; +extern const uint16_t c_aauiLCLDHuffEnc35[25][2]; +extern const uint16_t c_aauiLCLDHuffEnc36[36][2]; +extern const uint16_t c_aauiLCLDHuffEnc37[36][2]; +extern const uint16_t c_aauiLCLDHuffEnc38[49][2]; +extern const uint16_t c_aauiLCLDHuffEnc39[64][2]; +extern const uint16_t c_aauiLCLDHuffEnc40[81][2]; +extern const uint16_t c_aauiLCLDHuffEnc41[100][2]; +extern const uint16_t c_aauiLCLDHuffEnc42[169][2]; +extern const uint16_t c_aauiLCLDHuffEnc43[196][2]; +extern const uint16_t c_aauiLCLDHuffEnc44[289][2]; +extern const uint16_t c_aauiLCLDHuffEnc45[324][2]; +extern const uint16_t c_aauiLCLDHuffEnc46[400][2]; +extern const uint16_t c_aauiLCLDHuffEnc47[576][2]; +extern const uint16_t c_aauiLCLDHuffEnc48[729][2]; +extern const uint16_t c_aauiLCLDHuffEnc49[729][2]; +extern const uint16_t c_aauiLCLDHuffEnc50[28][2]; +extern const uint16_t c_aauiLCLDHuffEnc51[29][2]; +extern const uint16_t c_aauiLCLDHuffEnc52[32][2]; +extern const uint16_t c_aauiLCLDHuffEnc53[37][2]; +extern const uint16_t c_aauiLCLDHuffEnc54[39][2]; +extern const uint16_t c_aauiLCLDHuffEnc55[46][2]; +extern const uint16_t c_aauiLCLDHuffEnc56[55][2]; +extern const uint16_t c_aauiLCLDHuffEnc57[65][2]; +extern const uint16_t c_aauiLCLDHuffEnc58[77][2]; +extern const uint16_t c_aauiLCLDHuffEnc59[91][2]; +extern const uint16_t c_aauiLCLDHuffEnc60[109][2]; +extern const uint16_t c_aauiLCLDHuffEnc61[129][2]; +extern const uint16_t c_aauiLCLDHuffEnc62[153][2]; +extern const uint16_t c_aauiLCLDHuffEnc63[181][2]; +extern const uint16_t ( *c_apauiHuffEncTabels[2 * ALLOC_TABLE_SIZE] )[2]; +extern const uint32_t num_row_aauiLCLDHuff[2 * ALLOC_TABLE_SIZE]; + +#ifdef USE_DEMOD_TABLES +extern const int32_t c_aaiHuffDemod1[16][2]; +extern const int32_t c_aaiHuffDemod2[16][2]; +extern const int32_t c_aaiHuffDemod3[25][2]; +extern const int32_t c_aaiHuffDemod4[36][2]; +extern const int32_t c_aaiHuffDemod5[36][2]; +extern const int32_t c_aaiHuffDemod6[49][2]; +extern const int32_t c_aaiHuffDemod7[64][2]; +extern const int32_t c_aaiHuffDemod8[81][2]; +extern const int32_t c_aaiHuffDemod9[100][2]; +extern const int32_t c_aaiHuffDemod10[169][2]; +extern const int32_t c_aaiHuffDemod11[196][2]; +extern const int32_t c_aaiHuffDemod12[289][2]; +extern const int32_t c_aaiHuffDemod13[324][2]; +extern const int32_t c_aaiHuffDemod14[400][2]; +extern const int32_t c_aaiHuffDemod15[576][2]; +extern const int32_t c_aaiHuffDemod16[729][2]; +extern const int32_t c_aaiHuffDemod17[729][2]; +extern const int32_t ( *c_apaiDemodTables[ALLOC_TABLE_SIZE] )[2]; +#endif + +extern const uint32_t c_aaiRMSEnvHuffEnc[64][2]; +extern const uint32_t c_aaiRMSEnvHuffDec[13][HUFF_DEC_TABLE_SIZE]; + +extern const Word32 c_pfMagLUT[8]; /* Q31 */ +extern const Word32 c_pfP2RRealLUT[32]; /* Q31 */ +extern const Word32 c_pfP2RImagLUT[32]; /* Q31 */ +extern const Word32 c_pfWindowLUT[LCLD_PRED_WIN_LEN]; /* Q31 */ + + +#endif /* _TABLES_H_ */ diff --git a/lib_isar/isar_prot.h b/lib_isar/isar_prot.h new file mode 100644 index 0000000000000000000000000000000000000000..90a9d2763af145b16d1fc659f0f5fd1921c66b55 --- /dev/null +++ b/lib_isar/isar_prot.h @@ -0,0 +1,473 @@ +/****************************************************************************************************** + + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository. All Rights Reserved. + + This software is protected by copyright law and by international treaties. + The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository retain full ownership rights in their respective contributions in + the software. This notice grants no license of any kind, including but not limited to patent + license, nor is any license granted by implication, estoppel or otherwise. + + Contributors are required to enter into the IVAS codec Public Collaboration agreement before making + contributions. + + This software is provided "AS IS", without any express or implied warranties. The software is in the + development stage. It is intended exclusively for experts who have experience with such software and + solely for the purpose of inspection. All implied warranties of non-infringement, merchantability + and fitness for a particular purpose are hereby disclaimed and excluded. + + Any dispute, controversy or claim arising under or in relation to providing this software shall be + submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in + accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and + the United Nations Convention on Contracts on the International Sales of Goods. + +*******************************************************************************************************/ + +#ifndef ISAR_PROT_H +#define ISAR_PROT_H + + +#include "isar_stat.h" + +#ifdef SPLIT_REND_WITH_HEAD_ROT + +#include +#include "options.h" +#include "ivas_error.h" +#include "lib_isar_post_rend.h" +#include "enh64.h" + +Word32 ISAR_SPLIT_REND_BITStream_read_int32( + ISAR_SPLIT_REND_BITS_HANDLE pBits, + const Word32 bits ); + +void ISAR_SPLIT_REND_BITStream_write_int32( + ISAR_SPLIT_REND_BITS_HANDLE pBits, + const Word32 val, + const Word32 bits ); + +ivas_error isar_splitBinLCLDEncOpen( + ISAR_BIN_HR_SPLIT_LCLD_ENC_HANDLE *hSplitBinLCLDEnc, + const int32_t iSampleRate, + const int16_t iChannels, + const int32_t iDataRate, + const int16_t iNumBlocks, + const int16_t iNumIterations ); + +ivas_error isar_splitBinRendPLCOpen( + ISAR_SPLIT_REND_PLC_HANDLE *phSplitRendPLC, + int16_t iNumSubSets ); + +void isar_splitBinRendPLCClose( + ISAR_SPLIT_REND_PLC_HANDLE *phSplitRendPLC ); +ivas_error isar_splitBinLCLDDecOpen( + ISAR_BIN_HR_SPLIT_LCLD_DEC_HANDLE *hSplitBinLCLDDec, + const Word32 iSampleRate, + const Word16 iChannels, + const Word16 iNumBlocks, + const Word16 iNumIterations ); +void isar_splitBinLCLDDecClose( + ISAR_BIN_HR_SPLIT_LCLD_DEC_HANDLE *hSplitBinLCLDDec ); + +void isar_splitBinRendPLCsaveState( + ISAR_SPLIT_REND_PLC_HANDLE hSplitRendPLC, + Word32 Cldfb_RealBuffer_Binaural_fx[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + Word32 Cldfb_ImagBuffer_Binaural_fx[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + const int16_t num_chs, + const int16_t iNumBlocks, + const int16_t iNumIterations ); + +void isar_splitBinRendPLC_xf_fx( + ISAR_SPLIT_REND_PLC_HANDLE hSplitRendPLC, + Word32 Cldfb_RealBuffer_Binaural_fx[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + Word32 Cldfb_ImagBuffer_Binaural_fx[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + const Word16 num_chs, + const Word16 iNumBlocks, + const Word16 iNumIterations, + Word32 **ppiDecodingFailed, + Word32 **ppiDecodingFailedPrev, + Word16 exp ); + +void isar_splitBinRendPLC( + ISAR_SPLIT_REND_PLC_HANDLE hSplitRendPLC, + Word32 Cldfb_RealBuffer_Binaural_fx[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + Word32 Cldfb_ImagBuffer_Binaural_fx[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + const Word16 num_chs, + const Word16 iNumBlocks, + const Word16 iNumIterations, + Word32 **ppiDecodingFailed, + Word16 exp ); + +#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG +void isar_log_cldfb2wav_data( + float Cldfb_In_Real[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + float Cldfb_In_Imag[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + HANDLE_CLDFB_FILTER_BANK *cldfbSyn, + const int16_t num_chs, + const int16_t num_freq_bands, + const int32_t output_Fs, + const int16_t start_slot_idx, + const int16_t md_band_idx, + const char *filename ); +#endif + +void isar_SplitRenderer_PostRenderer( + ISAR_BIN_HR_SPLIT_POST_REND_HANDLE hBinPostRenderer, /* i/o: binaural renderer handle */ + MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, + Word32 Cldfb_RealBuffer_Ref_Binaural_fx[][CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* i/o : Reference/out Binaural signals */ + Word32 Cldfb_ImagBuffer_Ref_Binaural_fx[][CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* i/o : Reference/out Binaural signals */ + const IVAS_QUATERNION Quaternion_act ); + +void isar_splitBinLCLDDecProcess( + ISAR_BIN_HR_SPLIT_LCLD_DEC_HANDLE hSplitBinLCLDDec, + ISAR_SPLIT_REND_BITS_HANDLE pBits, + Word32 Cldfb_Out_Real_fx[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + Word32 Cldfb_Out_Imag_fx[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + Word16 *Q_cldfb_final, + const Word16 bfi ); + +void set_fix_rotation_mat_fx( + Word32 fix_pos_rot_mat[][BINAURAL_CHANNELS][BINAURAL_CHANNELS], + MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData ); + +void isar_splitBinLCLDEncClose( + ISAR_BIN_HR_SPLIT_LCLD_ENC_HANDLE *hSplitBinLCLDEnc ); +void isar_splitBinLCLDEncProcess( + ISAR_BIN_HR_SPLIT_LCLD_ENC_HANDLE hSplitBinLCLDEnc, + Word32 Cldfb_In_Real[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + Word32 Cldfb_In_Imag[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + const Word32 available_bits, + ISAR_SPLIT_REND_BITS_HANDLE pBits, + Word16 *q_final ); + +void set_pose_types_fx( + ISAR_SPLIT_REND_POSE_TYPE pose_type[MAX_HEAD_ROT_POSES - 1], + MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData ); + +void isar_split_rend_init_huff_cfg( + ISAR_BIN_HR_SPLIT_REND_HUFF_HANDLE pHuff_cfg ); + +ivas_error isar_splitBinPostRendOpen( + ISAR_BIN_HR_SPLIT_POST_REND_HANDLE *hBinHrSplitPostRend, + MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, + const int32_t output_Fs ); + +void isar_splitBinPostRendClose( + ISAR_BIN_HR_SPLIT_POST_REND_HANDLE *hBinHrSplitPostRend ); + +void isar_SplitRenderer_getdiagdiff( + Word16 in_idx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], + Word16 out_idx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], + const Word16 sign, + const Word16 min_val, + const Word16 max_val ); + +void isar_renderSplitGetMultiBinPoseData_fx( + const ISAR_SPLIT_REND_CONFIG_DATA *pSplit_rend_config, + MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, + const ISAR_SPLIT_REND_ROT_AXIS rot_axis ); +void isar_renderSplitGetMultiBinPoseData( + const ISAR_SPLIT_REND_CONFIG_DATA *pSplit_rend_config, + MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, + const ISAR_SPLIT_REND_ROT_AXIS rot_axis ); + +void isar_split_rend_get_quant_params_fx( + const Word16 num_md_bands, + Word16 pred_real_bands_yaw[ISAR_SPLIT_REND_NUM_QUANT_STRATS], + Word16 pred_imag_bands_yaw[ISAR_SPLIT_REND_NUM_QUANT_STRATS], + Word16 pred_quant_pnts_yaw[ISAR_SPLIT_REND_NUM_QUANT_STRATS], + Word32 pred_quantstep_yaw[ISAR_SPLIT_REND_NUM_QUANT_STRATS], + Word32 pred_1byquantstep_yaw[ISAR_SPLIT_REND_NUM_QUANT_STRATS], + Word16 d_bands_yaw[ISAR_SPLIT_REND_NUM_QUANT_STRATS], + Word16 bands_pitch[ISAR_SPLIT_REND_NUM_QUANT_STRATS], + Word16 pred_real_bands_roll[ISAR_SPLIT_REND_NUM_QUANT_STRATS], + Word16 pred_imag_bands_roll[ISAR_SPLIT_REND_NUM_QUANT_STRATS], +#ifdef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS + const Word16 ro_flag, +#endif + Word16 *num_quant_strats +#ifndef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS + , + Word16 *num_complex_bands +#endif +); + +void isar_split_rend_get_quant_params( + const int16_t num_md_bands, + int16_t pred_real_bands_yaw[ISAR_SPLIT_REND_NUM_QUANT_STRATS], + int16_t pred_imag_bands_yaw[ISAR_SPLIT_REND_NUM_QUANT_STRATS], + int16_t pred_quant_pnts_yaw[ISAR_SPLIT_REND_NUM_QUANT_STRATS], + float pred_quantstep_yaw[ISAR_SPLIT_REND_NUM_QUANT_STRATS], + float pred_1byquantstep_yaw[ISAR_SPLIT_REND_NUM_QUANT_STRATS], + int16_t d_bands_yaw[ISAR_SPLIT_REND_NUM_QUANT_STRATS], + int16_t bands_pitch[ISAR_SPLIT_REND_NUM_QUANT_STRATS], + int16_t pred_real_bands_roll[ISAR_SPLIT_REND_NUM_QUANT_STRATS], + int16_t pred_imag_bands_roll[ISAR_SPLIT_REND_NUM_QUANT_STRATS], + int16_t *num_quant_strats, + int16_t *num_complex_bands ); + +void isar_splitBinPostRendMdDec_fx( + ISAR_SPLIT_REND_BITS_HANDLE pBits, + ISAR_BIN_HR_SPLIT_POST_REND_HANDLE hBinHrSplitPostRend, + MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData +#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG + , + BIN_HR_SPLIT_PRE_REND_HANDLE hBinHrSplitPreRend +#endif +); + +void Quat2EulerDegree( + const IVAS_QUATERNION quat, /* i : quaternion describing the rotation */ + float *yaw, /* o : yaw */ + float *pitch, /* o : pitch */ + float *roll /* o : roll */ +); + +void ivas_mat_mult_2by2_complex( + float in_re1[2][2], + float in_im1[2][2], + float in_re2[2][2], + float in_im2[2][2], + float out_re2[2][2], + float out_im2[2][2] ); + +void isar_mat_mult_2by2_complex_fx( + Word32 in_re1_fx[2][2], + Word16 exp_re1, + Word32 in_im1_fx[2][2], + Word16 exp_im1, + Word32 in_re2_fx[2][2], + Word16 exp_re2, + Word32 in_im2_fx[2][2], + Word16 exp_im2, + Word32 out_re2_fx[2][2], + Word16 *final_exp_re_1, + Word32 out_im2_fx[2][2], + Word16 *final_exp_im_1 ); + +void isar_rend_CldfbSplitPostRendProcess( + ISAR_BIN_HR_SPLIT_POST_REND_HANDLE hBinHrSplitPostRend, + MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, + const IVAS_QUATERNION QuaternionPost, + Word32 Cldfb_RealBuffer_Binaural_fx[][CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], + Word32 Cldfb_ImagBuffer_Binaural_fx[][CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], + Word16 Q_cldfb_in, + Word32 output_fx[][L_FRAME48k], + Word16 *Q_out, + const Word16 cldfb_in_flag ); + +void isar_init_multi_bin_pose_data_fx( + MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData ); + +/* Copy for encoder, to be removed */ +void isar_init_multi_bin_pose_data_fx_enc( + MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData ); + +void isar_rend_CldfbSplitPreRendProcess( + const ISAR_BIN_HR_SPLIT_PRE_REND_HANDLE hBinHrSplitPreRend, + const IVAS_QUATERNION headPosition, + MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, + Word32 Cldfb_In_BinReal_fx[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + Word16 exp_cldfb_re, + Word32 Cldfb_In_BinImag_fx[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + Word16 exp_cldfb_im, + ISAR_SPLIT_REND_BITS_HANDLE pBits, + const Word32 target_md_bits, + const Word16 low_res_pre_rend_rot, + const Word16 ro_md_flag ); + +#ifdef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS +Word16 isar_renderSplitGetRot_axisNumBits( + const Word16 dof ); + +ISAR_SPLIT_REND_ROT_AXIS isar_renderSplitGetRot_axisFromCode( + const Word16 dof, + const Word16 code ); + +Word16 isar_renderSplitGetCodeFromRot_axis( + const Word16 dof, + const ISAR_SPLIT_REND_ROT_AXIS rot_axis, + Word16 *num_bits ); +#endif + +void isar_init_split_post_rend_handles( + ISAR_SPLIT_POST_REND_WRAPPER *hSplitRendWrapper ); + +ivas_error isar_splitBinPreRendOpen( + ISAR_BIN_HR_SPLIT_PRE_REND_HANDLE *hBinHrSplitPreRend, +#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG + MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, + const int32_t output_Fs +#else + MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData +#endif +); + +void isar_splitBinPreRendClose( + ISAR_BIN_HR_SPLIT_PRE_REND_HANDLE *hBinHrSplitPreRend ); + +void isar_set_split_rend_ht_setup_fx( + SPLIT_REND_WRAPPER *hSplitrend, + IVAS_QUATERNION Quaternions[MAX_PARAM_SPATIAL_SUBFRAMES], + Word32 Rmat_fx[MAX_PARAM_SPATIAL_SUBFRAMES][3][3] ); + + +#ifndef ISAR_BITSTREAM_UPDATE_LC3PLUS +Word32 isar_get_lc3plus_bitrate( + const Word32 SplitRendBitRate, + const ISAR_SPLIT_REND_POSE_CORRECTION_MODE poseCorrectionMode, + const Word16 split_prerender_frame_size_ms ); +#endif + +ivas_error isar_split_rend_validate_config( + const ISAR_SPLIT_REND_CONFIG_DATA *pSplitRendConfig, + const Word16 is_pcm_out ); + +Word32 isar_get_lcld_bitrate( + const Word32 SplitRendBitRate, + const ISAR_SPLIT_REND_POSE_CORRECTION_MODE poseCorrectionMode ); + +#ifndef ISAR_BITSTREAM_UPDATE_LC3PLUS +Word8 isar_get_lc3plus_bitrate_id( + const Word32 SplitRendBitRate ); +#endif + +ivas_error splitRendLc3plusEncodeAndWrite( + SPLIT_REND_WRAPPER *hSplitBin, + ISAR_SPLIT_REND_BITS_HANDLE pBits, +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + const int32_t available_bits, +#else + const int32_t SplitRendBitRate, +#endif + Word32 *in[], + Word16 Q_sig ); + +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS +ivas_error isar_framesize_to_ms( + const IVAS_RENDER_FRAMESIZE frame_size, /* i : frame size enum */ + Word16 *ms /* o : frame size in ms */ +); +#endif +Word32 isar_get_split_rend_md_target_brate( + const Word32 SplitRendBitRate, + const Word16 pcm_out_flag ); + +ivas_error isar_split_rend_choose_default_codec( + ISAR_SPLIT_REND_CODEC *pCodec, /* i/o: pointer to codec setting */ +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + Word16 *pIsar_frame_size_ms, /* i/o: pointer to isar frame size setting */ +#endif + Word16 *pCodec_frame_size_ms, /* i/o: pointer to codec frame size setting */ + const Word16 cldfb_in_flag, /* i : flag indicating rendering in TD */ + const Word16 pcm_out_flag, /* i : flag to indicate PCM output */ + const Word16 num_subframes /* i : number of subframes */ +); + +void ISAR_SPLIT_REND_BITStream_init( + ISAR_SPLIT_REND_BITS_HANDLE pBits, + const Word32 buf_len_bytes, + UWord8 *pbuf ); + +void isar_split_rend_huffman_dec_init_min_max_len( + isar_split_rend_huffman_cfg_t *p_huff_cfg ); + +Word16 wrap_a( + Word16 val, + const Word16 min_val, + const Word16 max_val ); +#ifndef ISAR_BITSTREAM_UPDATE_LC3PLUS +Word32 isar_get_lc3plus_size_from_id( + const Word8 SplitRendBitRateId, + const ISAR_SPLIT_REND_POSE_CORRECTION_MODE poseCorrectionMode, + const Word16 split_prerender_frame_size_ms ); +#endif + +void isar_renderSplitUpdateNoCorrectionPoseData( + const ISAR_SPLIT_REND_CONFIG_DATA *pSplit_rend_config, + MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData ); + +Word32 get_bit( + const Word32 state, + const Word32 bit_id ); + +ivas_error split_renderer_open_lc3plus( + SPLIT_REND_WRAPPER *hSplitRendWrapper, + const ISAR_SPLIT_REND_CONFIG_DATA *pSplitRendConfig, + const Word32 OutSampleRate, +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + const IVAS_RENDER_FRAMESIZE ivas_frame_size +#else + const int16_t num_subframes +#endif +); + +ISAR_POST_REND_AudioConfigType isar_getAudioConfigType( + const IVAS_AUDIO_CONFIG config ); + +void isar_init_split_rend_handles( + SPLIT_REND_WRAPPER *hSplitRendWrapper ); + +ivas_error isar_renderMultiTDBinToSplitBinaural( + SPLIT_REND_WRAPPER *hSplitBin, + const IVAS_QUATERNION headPosition, + const Word32 SplitRendBitRate, +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + const Word16 isar_frame_size_ms, +#endif + const Word16 codec_frame_size_ms, + ISAR_SPLIT_REND_BITS_HANDLE pBits, + const Word16 max_bands, + // float *in[], + Word32 *in_fx[], // Q11 + Word16 Q_sig, + const Word16 low_res_pre_rend_rot, + const Word16 pcm_out_flag, + const Word16 ro_md_flag ); + +void lc3plusTimeAlignCldfbPoseCorr( SPLIT_REND_WRAPPER *hSplitBin, + Word32 Cldfb_In_BinReal_fx[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + Word32 Cldfb_In_BinImag_fx[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + Word16 *Q_in ); + +#endif + +void ivas_cmult_fix( Word32 in1_re_fx, Word16 exp_re1, Word32 in1_im_fx, Word16 exp_im1, Word32 in2_re_fx, Word16 exp_re2, Word32 in2_im_fx, Word16 exp_im2, Word32 *out1_re_fx, Word32 *out1_im_fx, Word16 *exp_out1_re, Word16 *exp_out1_im ); + +void ivas_calculate_abs_fx( Word32 re_fx, Word16 exp_re, Word32 im_fx, Word16 exp_im, Word32 *out_fx, Word16 *exp_out ); + +void ivas_calculate_rabs_fx( Word32 re_fx, Word16 exp_re, Word32 *out_fx, Word16 *exp_out ); + +#define IVAS_CMULT_FLOAT( in1_re, in1_im, in2_re, in2_im, out1_re, out1_im ) \ + out1_re = ( in1_re * in2_re ) - ( in1_im * in2_im ); \ + out1_im = ( in1_re * in2_im ) + ( in2_re * in1_im ); + +#define IVAS_CALCULATE_ABS( re, im, out ) \ + out = sqrtf( ( re * re ) + ( im * im ) ); + +#define IVAS_CALCULATE_RABS( re, out ) \ + out = sqrtf( re * re ); + +#define IVAS_CALCULATE_SQ_ABS( re, im, out ) \ + out = (float) ( ( re * re ) + ( im * im ) ); + +#define IVAS_RMULT_DOUBLE( in1_re, in2_re, out1_re ) \ + out1_re = ( in1_re * in2_re ); + +#define IVAS_CALCULATE_SQ_ABS_N( re, out ) \ + out = (float) ( re * re ); + +#define IVAS_RMULT_FLOAT( in1_re, in2_re, out1_re ) \ + out1_re = ( in1_re * in2_re ); + + +/* clang-format on */ + +#endif /* IVAS_PROT_REND_H */ diff --git a/lib_isar/isar_rom_post_rend.c b/lib_isar/isar_rom_post_rend.c new file mode 100644 index 0000000000000000000000000000000000000000..99742bc4f28f85d176637967b41495f82ec08f17 --- /dev/null +++ b/lib_isar/isar_rom_post_rend.c @@ -0,0 +1,196 @@ +/****************************************************************************************************** + + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository. All Rights Reserved. + + This software is protected by copyright law and by international treaties. + The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository retain full ownership rights in their respective contributions in + the software. This notice grants no license of any kind, including but not limited to patent + license, nor is any license granted by implication, estoppel or otherwise. + + Contributors are required to enter into the IVAS codec Public Collaboration agreement before making + contributions. + + This software is provided "AS IS", without any express or implied warranties. The software is in the + development stage. It is intended exclusively for experts who have experience with such software and + solely for the purpose of inspection. All implied warranties of non-infringement, merchantability + and fitness for a particular purpose are hereby disclaimed and excluded. + + Any dispute, controversy or claim arising under or in relation to providing this software shall be + submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in + accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and + the United Nations Convention on Contracts on the International Sales of Goods. + +*******************************************************************************************************/ + +#include +#include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif +#include "cnst.h" +#include "isar_cnst.h" +#include +#include "wmc_auto.h" + +/* clang-format off */ + + +#ifdef SPLIT_REND_WITH_HEAD_ROT +/*----------------------------------------------------------------------* + * Binuaral split rendering ROM tables + *-----------------------------------------------------------------------*/ + +/* rotations in this array are relative to ref rotation */ +const Word32 ivas_split_rend_relative_yaw_pos_angles_fx[SPLIT_REND_MAX_YAW_ONLY_POSES] = { -62914560, 62914560 }; /* Q22 */ +const Word32 ivas_split_rend_relative_pitch_pos_angles_fx[SPLIT_REND_MAX_PITCH_ONLY_POSES] = { 41943040, 41943040 }; /* Q22 */ +const Word32 ivas_split_rend_relative_roll_pos_angles_fx[SPLIT_REND_MAX_PITCH_ONLY_POSES] = { 41943040, 41943040 }; /* Q22 */ +const float ivas_split_rend_relative_yaw_pos_angles[SPLIT_REND_MAX_YAW_ONLY_POSES] = {-15.0f, 15.0f}; +const float ivas_split_rend_relative_pitch_pos_angles[SPLIT_REND_MAX_PITCH_ONLY_POSES] = {10.0f, 10.0f}; +const float ivas_split_rend_relative_roll_pos_angles[SPLIT_REND_MAX_PITCH_ONLY_POSES] = {10.0f, 10.0f}; +const float ivas_split_rend_relative_one_axis_pos_angles[SPLIT_REND_MAX_ONE_AXIS_MD_POSES] = {-15.0f, 15.0f}; + +const Word32 ivas_split_rend_relative_yaw_pos_angles_hq_fx[SPLIT_REND_MAX_YAW_ONLY_POSES] = { -62914560, 62914560 }; /* Q22 */ +const Word32 ivas_split_rend_relative_pitch_pos_angles_hq_fx[SPLIT_REND_MAX_PITCH_ONLY_POSES] = { -62914560, 62914560 }; /* Q22 */ +const Word32 ivas_split_rend_relative_roll_pos_angles_hq_fx[SPLIT_REND_MAX_PITCH_ONLY_POSES] = { -62914560, 62914560 }; /* Q22 */ +const float ivas_split_rend_relative_yaw_pos_angles_hq[SPLIT_REND_MAX_YAW_ONLY_POSES] = {-15.0f, 15.0f}; +const float ivas_split_rend_relative_pitch_pos_angles_hq[SPLIT_REND_MAX_PITCH_ONLY_POSES] = {-15.0f, 15.0f}; +const float ivas_split_rend_relative_roll_pos_angles_hq[SPLIT_REND_MAX_PITCH_ONLY_POSES] = {-15.0f, 15.0f}; +const float ivas_split_rend_relative_one_axis_pos_angles_hq[SPLIT_REND_MAX_ONE_AXIS_MD_POSES] = {-15.0f, 15.0f}; + +/* Values in degrees : -30, -22.5, -15, 0, 15, 22.5 and 30 */ +const Word32 ivas_split_rend_fix_pos_rot_mat_cos_fx[4] = { ONE_IN_Q31, 2074309917, 1984016189, 1859775393 }; /* Q31 */ + +const int16_t isar_split_rend_band_grouping[MAX_SPLIT_REND_MD_BANDS + 1] = +{ + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 20, 25, 30, 35, 40, 50, 60 +}; + +const int32_t ivas_split_rend_huff_p_d_consts[ISAR_SPLIT_REND_D_QUANT_PNTS][3] = +{ + {0,8,252},{1,8,253},{2,7,124},{3,6,60},{4,5,28},{5,4,12}, + {6,3,4},{7,1,0},{8,3,5},{9,4,13},{10,5,29},{11,6,61}, + {12,7,125},{13,8,254},{14,8,255} +}; + +const int32_t ivas_split_rend_huff_p_d_diff_consts[ISAR_SPLIT_REND_D_QUANT_PNTS][3] = +{ + { 0, 1, 0 },{ 1, 2, 2 },{ 2, 3, 6 },{ 3, 4, 14 }, + { 4, 5, 30 },{ 5, 6, 62 },{ 6, 7, 126 },{ 7, 8, 254 }, + { 8, 9, 510 },{ 9, 10, 1022 },{ 10, 11, 2046 },{ 11, 12, 4094 }, + { 12, 13, 8190 },{ 13, 14, 16382 },{ 14, 14, 16383 } +}; + +const int32_t ivas_split_rend_huff_d_consts[ISAR_SPLIT_REND_D_QUANT_PNTS][3] = +{ + { 0, 1, 0 },{ 1, 2, 2 },{ 2, 3, 6 },{ 3, 4, 14 }, + { 4, 5, 30 },{ 5, 6, 62 },{ 6, 7, 126 },{ 7, 8, 254 }, + { 8, 9, 510 },{ 9, 10, 1022 },{ 10, 11, 2046 },{ 11, 12, 4094 }, + { 12, 13, 8190 },{ 13, 14, 16382 },{ 14, 14, 16383 } +}; + +const int32_t ivas_split_rend_huff_pred63_consts[ISAR_SPLIT_REND_PRED_63QUANT_PNTS][3] = +{ + {-31,11,2040}, + {-30,11,2041}, + {-29,11,2042}, + {-28,11,2043}, + {-27,10,1012}, + {-26,10,1013}, + {-25,10,1014}, + {-24,10,1015}, + {-23,9,498}, + {-22,9,499}, + {-21,9,500}, + {-20,9,501}, + {-19,8,242}, + {-18,8,243}, + {-17,8,244}, + {-16,8,245}, + {-15,7,112}, + {-14,7,113}, + {-13,7,114}, + {-12,7,115}, + {-11,6,48}, + {-10,6,49}, + {-9,6,50}, + {-8,6,51}, + {-7,5,16}, + {-6,5,17}, + {-5,5,18}, + {-4,5,19}, + {-3,4,2}, + {-2,4,3}, + {-1,4,4}, + {0,3,0}, + {1,4,5}, + {2,4,6}, + {3,4,7}, + {4,5,20}, + {5,5,21}, + {6,5,22}, + {7,5,23}, + {8,6,52}, + {9,6,53}, + {10,6,54}, + {11,6,55}, + {12,7,116}, + {13,7,117}, + {14,7,118}, + {15,7,119}, + {16,7,120}, + {17,8,246}, + {18,8,247}, + {19,8,248}, + {20,9,502}, + {21,9,503}, + {22,9,504}, + {23,9,505}, + {24,10,1016}, + {25,10,1017}, + {26,10,1018}, + {27,10,1019}, + {28,11,2044}, + {29,11,2045}, + {30,11,2046}, + {31,11,2047}, +}; + +const int32_t ivas_split_rend_huff_pred31_consts[ISAR_SPLIT_REND_PRED_31QUANT_PNTS][3] = +{ + {-15,10,1020},{-14,10,1021},{-13,9,506},{-12,9,507}, + {-11,8,250},{-10,8,251},{-9,7,120},{-8,7,121}, + {-7,6,56},{-6,6,57},{-5,5,24},{-4,5,25},{-3,4,8}, + {-2,4,9},{-1,3,2},{0,2,0},{1,3,3}, + {2,4,10},{3,4,11},{4,5,26},{5,5,27}, + {6,6,58},{7,6,59},{8,7,122},{9,7,123}, + {10,7,124},{11,8,252},{12,9,508},{13,9,509}, + {14,10,1022},{15,10,1023}, +}; + +const int32_t ivas_split_rend_huff_roll_pred_consts[ISAR_SPLIT_REND_ROLL_PRED_QUANT_PNTS][3] = +{ + {-15,10,1020},{-14,10,1021},{-13,9,506},{-12,9,507}, + {-11,8,250},{-10,8,251},{-9,7,120},{-8,7,121}, + {-7,6,56},{-6,6,57},{-5,5,24},{-4,5,25},{-3,4,8}, + {-2,4,9},{-1,3,2},{0,2,0},{1,3,3}, + {2,4,10},{3,4,11},{4,5,26},{5,5,27}, + {6,6,58},{7,6,59},{8,7,122},{9,7,123}, + {10,7,124},{11,8,252},{12,9,508},{13,9,509}, +{14,10,1022},{15,10,1023}, +}; + +#endif + +/* Tables for split renderer fixed converison */ +const Word16 fade_table_fx[4] = +{ 8192, 16384, 24576, 32767 }; + +/* clang-format on */ diff --git a/lib_isar/isar_rom_post_rend.h b/lib_isar/isar_rom_post_rend.h new file mode 100644 index 0000000000000000000000000000000000000000..b9acd75e1e16af8a9cbd036d472d327033629c01 --- /dev/null +++ b/lib_isar/isar_rom_post_rend.h @@ -0,0 +1,82 @@ +/****************************************************************************************************** + + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository. All Rights Reserved. + + This software is protected by copyright law and by international treaties. + The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository retain full ownership rights in their respective contributions in + the software. This notice grants no license of any kind, including but not limited to patent + license, nor is any license granted by implication, estoppel or otherwise. + + Contributors are required to enter into the IVAS codec Public Collaboration agreement before making + contributions. + + This software is provided "AS IS", without any express or implied warranties. The software is in the + development stage. It is intended exclusively for experts who have experience with such software and + solely for the purpose of inspection. All implied warranties of non-infringement, merchantability + and fitness for a particular purpose are hereby disclaimed and excluded. + + Any dispute, controversy or claim arising under or in relation to providing this software shall be + submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in + accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and + the United Nations Convention on Contracts on the International Sales of Goods. + +*******************************************************************************************************/ + +#ifndef ISAR_ROM_POST_REND_H +#define ISAR_ROM_POST_REND_H + +#include +#include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif +#include "cnst.h" +#include "isar_cnst.h" + +#ifdef SPLIT_REND_WITH_HEAD_ROT +/*----------------------------------------------------------------------* + * Binuaral split rendering ROM tables + *-----------------------------------------------------------------------*/ + +extern const Word32 ivas_split_rend_relative_yaw_pos_angles_fx[SPLIT_REND_MAX_YAW_ONLY_POSES]; +extern const Word32 ivas_split_rend_relative_pitch_pos_angles_fx[SPLIT_REND_MAX_PITCH_ONLY_POSES]; +extern const Word32 ivas_split_rend_relative_roll_pos_angles_fx[SPLIT_REND_MAX_PITCH_ONLY_POSES]; +extern const float ivas_split_rend_relative_yaw_pos_angles[SPLIT_REND_MAX_YAW_ONLY_POSES]; +extern const float ivas_split_rend_relative_pitch_pos_angles[SPLIT_REND_MAX_PITCH_ONLY_POSES]; +extern const float ivas_split_rend_relative_roll_pos_angles[SPLIT_REND_MAX_PITCH_ONLY_POSES]; +extern const float ivas_split_rend_relative_one_axis_pos_angles[SPLIT_REND_MAX_ONE_AXIS_MD_POSES]; +extern const float ivas_split_rend_relative_one_axis_pos_angles_hq[SPLIT_REND_MAX_ONE_AXIS_MD_POSES]; + +extern const Word32 ivas_split_rend_relative_yaw_pos_angles_hq_fx[SPLIT_REND_MAX_YAW_ONLY_POSES]; +extern const Word32 ivas_split_rend_relative_pitch_pos_angles_hq_fx[SPLIT_REND_MAX_PITCH_ONLY_POSES]; +extern const Word32 ivas_split_rend_relative_roll_pos_angles_hq_fx[SPLIT_REND_MAX_PITCH_ONLY_POSES]; +extern const float ivas_split_rend_relative_yaw_pos_angles_hq[SPLIT_REND_MAX_YAW_ONLY_POSES]; +extern const float ivas_split_rend_relative_pitch_pos_angles_hq[SPLIT_REND_MAX_PITCH_ONLY_POSES]; +extern const float ivas_split_rend_relative_roll_pos_angles_hq[SPLIT_REND_MAX_PITCH_ONLY_POSES]; + +/* Values in degrees : -30, -22.5, -15, 0, 15, 22.5 and 30 */ +extern const Word32 ivas_split_rend_fix_pos_rot_mat_cos_fx[4]; /* Q31 */ + +extern const float ivas_split_rend_relative_pos_angles[MAX_HEAD_ROT_POSES][3]; +extern const int16_t isar_split_rend_band_grouping[MAX_SPLIT_REND_MD_BANDS + 1]; +extern const int32_t ivas_split_rend_huff_d_consts[ISAR_SPLIT_REND_D_QUANT_PNTS][3]; +extern const int32_t ivas_split_rend_huff_pred63_consts[ISAR_SPLIT_REND_PRED_31QUANT_PNTS][3]; +extern const int32_t ivas_split_rend_huff_pred31_consts[ISAR_SPLIT_REND_PRED_31QUANT_PNTS][3]; +extern const int32_t ivas_split_rend_huff_roll_pred_consts[ISAR_SPLIT_REND_ROLL_PRED_QUANT_PNTS][3]; +extern const int32_t ivas_split_rend_huff_p_d_consts[ISAR_SPLIT_REND_D_QUANT_PNTS][3]; +extern const int32_t ivas_split_rend_huff_p_d_diff_consts[ISAR_SPLIT_REND_D_QUANT_PNTS][3]; +extern const int32_t split_rend_brate_tbl[]; +#endif + +/* Tables for fixed point conversion */ +extern const Word16 fade_table_fx[4]; + +#endif diff --git a/lib_isar/isar_splitRend_lcld_dec.c b/lib_isar/isar_splitRend_lcld_dec.c new file mode 100644 index 0000000000000000000000000000000000000000..ddf9515b9d59e71dc4c762e748a0cf1c9572a42c --- /dev/null +++ b/lib_isar/isar_splitRend_lcld_dec.c @@ -0,0 +1,285 @@ +/****************************************************************************************************** + + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository. All Rights Reserved. + + This software is protected by copyright law and by international treaties. + The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository retain full ownership rights in their respective contributions in + the software. This notice grants no license of any kind, including but not limited to patent + license, nor is any license granted by implication, estoppel or otherwise. + + Contributors are required to enter into the IVAS codec Public Collaboration agreement before making + contributions. + + This software is provided "AS IS", without any express or implied warranties. The software is in the + development stage. It is intended exclusively for experts who have experience with such software and + solely for the purpose of inspection. All implied warranties of non-infringement, merchantability + and fitness for a particular purpose are hereby disclaimed and excluded. + + Any dispute, controversy or claim arising under or in relation to providing this software shall be + submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in + accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and + the United Nations Convention on Contracts on the International Sales of Goods. + +*******************************************************************************************************/ + +#include +#include "options.h" +#ifdef SPLIT_REND_WITH_HEAD_ROT +#include "isar_prot.h" +#include "ivas_prot_fx.h" +#include "prot_fx.h" +#include "prot_fx.h" +//#include "control.h" +#ifdef DEBUGGING +#include "debug.h" +#endif +#include "wmc_auto.h" + + +/*------------------------------------------------------------------------- + * Function isar_splitBinLCLDDecOpen() + * + * + *------------------------------------------------------------------------*/ +ivas_error isar_splitBinLCLDDecOpen( + ISAR_BIN_HR_SPLIT_LCLD_DEC_HANDLE *hSplitBinLCLDDec, + const Word32 iSampleRate, + const Word16 iChannels, + const Word16 iNumBlocks, + const Word16 iNumIterations ) +{ + int16_t n; + ISAR_BIN_HR_SPLIT_LCLD_DEC_HANDLE splitBinLCLDDec; + ivas_error error; + + IF( ( splitBinLCLDDec = (ISAR_BIN_HR_SPLIT_LCLD_DEC_HANDLE) malloc( sizeof( ISAR_BIN_HR_SPLIT_LCLD_DEC ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD decoder Module \n" ) ); + } + + splitBinLCLDDec->pLcld_dec = NULL; /* place holder for CLDFB decoder handle */ + + splitBinLCLDDec->iChannels = iChannels; + + IF( ( error = CreateLCLDDecoder( &splitBinLCLDDec->psLCLDDecoder, iSampleRate, iChannels, iNumBlocks, 0 ) ) != IVAS_ERR_OK ) + { + return error; + } + + IF( ( splitBinLCLDDec->pppfDecLCLDReal_fx = (Word32 ***) malloc( iChannels * sizeof( Word32 ** ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD decoder Module \n" ) ); + } + IF( ( splitBinLCLDDec->pppfDecLCLDImag_fx = (Word32 ***) malloc( iChannels * sizeof( Word32 ** ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD decoder Module \n" ) ); + } + + FOR( n = 0; n < splitBinLCLDDec->iChannels; n++ ) + { + IF( ( splitBinLCLDDec->pppfDecLCLDReal_fx[n] = (Word32 **) malloc( CLDFB_NO_COL_MAX * sizeof( Word32 * ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD decoder Module \n" ) ); + } + IF( ( splitBinLCLDDec->pppfDecLCLDImag_fx[n] = (Word32 **) malloc( CLDFB_NO_COL_MAX * sizeof( Word32 * ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD decoder Module \n" ) ); + } + } +#ifdef CLDFB_DEBUG + splitBinLCLDDec->numFrame = 0; + char cldfbFilename[50] = "cldfb_out.bin"; + if ( ( splitBinLCLDDec->cldfbOut = fopen( cldfbFilename, "wb" ) ) == NULL ) + { + fprintf( stderr, "Error: CLDFB bitstream file %s could not be opened\n\n", cldfbFilename ); + exit( -1 ); + } + int16_t num_bands = CLDFB_NO_CHANNELS_MAX; + fwrite( &iChannels, sizeof( int16_t ), 1, splitBinLCLDDec->cldfbOut ); + fwrite( &num_bands, sizeof( int16_t ), 1, splitBinLCLDDec->cldfbOut ); +#endif + + IF( ( error = isar_splitBinRendPLCOpen( &splitBinLCLDDec->hSplitRendPLC, GetNumSubSets( splitBinLCLDDec->psLCLDDecoder ) ) ) != IVAS_ERR_OK ) + { + return error; + } + splitBinLCLDDec->iNumBlocks = iNumBlocks; + splitBinLCLDDec->iNumIterations = iNumIterations; + + *hSplitBinLCLDDec = splitBinLCLDDec; + + return IVAS_ERR_OK; +} + +/*------------------------------------------------------------------------- + * Function isar_splitBinLCLDDecClose() + * + * + *------------------------------------------------------------------------*/ + +void isar_splitBinLCLDDecClose( + ISAR_BIN_HR_SPLIT_LCLD_DEC_HANDLE *hSplitBinLCLDDec ) +{ + Word16 n; + + IF( ( *hSplitBinLCLDDec ) != NULL ) + { + IF( ( *hSplitBinLCLDDec )->psLCLDDecoder != NULL ) + { + DeleteLCLDDecoder( ( *hSplitBinLCLDDec )->psLCLDDecoder ); + } + + FOR( n = 0; n < ( *hSplitBinLCLDDec )->iChannels; n++ ) + { + free( ( *hSplitBinLCLDDec )->pppfDecLCLDReal_fx[n] ); + free( ( *hSplitBinLCLDDec )->pppfDecLCLDImag_fx[n] ); + } + free( ( *hSplitBinLCLDDec )->pppfDecLCLDReal_fx ); + free( ( *hSplitBinLCLDDec )->pppfDecLCLDImag_fx ); + +#ifdef CLDFB_DEBUG + if ( ( *hSplitBinLCLDDec )->cldfbOut != NULL ) + { + fclose( ( *hSplitBinLCLDDec )->cldfbOut ); + } +#endif + isar_splitBinRendPLCClose( &( *hSplitBinLCLDDec )->hSplitRendPLC ); + + free( *hSplitBinLCLDDec ); + *hSplitBinLCLDDec = NULL; + } + + return; +} + +/*------------------------------------------------------------------------- + * Function isar_splitBinLCLDDecProcess() + * + * + *------------------------------------------------------------------------*/ +void isar_splitBinLCLDDecProcess( + ISAR_BIN_HR_SPLIT_LCLD_DEC_HANDLE hSplitBinLCLDDec, + ISAR_SPLIT_REND_BITS_HANDLE pBits, + Word32 Cldfb_Out_Real_fx[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + Word32 Cldfb_Out_Imag_fx[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + Word16 *Q_cldfb_final, + const Word16 bfi ) +{ + Word16 k, n; + Word16 itr; + *Q_cldfb_final = 11; + push_wmops( "isar_splitBinLCLDDecProcess" ); + + assert( hSplitBinLCLDDec != NULL ); + assert( Cldfb_Out_Real_fx != NULL ); + assert( Cldfb_Out_Imag_fx != NULL ); + assert( pBits != NULL ); +#ifdef CLDFB_DEBUG + printf( "Bytes read = %d\n", iBytesWritten ); +#endif + IF( !bfi ) + { + FOR( itr = 0; itr < hSplitBinLCLDDec->iNumIterations; itr++ ) + { + /* Initialized with zeros....... */ + FOR( n = 0; n < hSplitBinLCLDDec->iChannels; n++ ) + { + FOR( k = 0; k < hSplitBinLCLDDec->iNumBlocks; k++ ) + { + hSplitBinLCLDDec->pppfDecLCLDReal_fx[n][k] = Cldfb_Out_Real_fx[n][hSplitBinLCLDDec->iNumBlocks * itr + k]; + hSplitBinLCLDDec->pppfDecLCLDImag_fx[n][k] = Cldfb_Out_Imag_fx[n][hSplitBinLCLDDec->iNumBlocks * itr + k]; + set_l( hSplitBinLCLDDec->pppfDecLCLDReal_fx[n][k], 0, CLDFB_NO_CHANNELS_MAX ); + set_l( hSplitBinLCLDDec->pppfDecLCLDImag_fx[n][k], 0, CLDFB_NO_CHANNELS_MAX ); + } + } + + Word16 Q_in = 14; + DecodeLCLDFrame( hSplitBinLCLDDec->psLCLDDecoder, pBits, hSplitBinLCLDDec->pppfDecLCLDReal_fx, hSplitBinLCLDDec->pppfDecLCLDImag_fx, Q_in, Q_cldfb_final ); + +#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++ ) + { + 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( AnyDecodingFailed( hSplitBinLCLDDec->psLCLDDecoder ) ) + { + IF( NE_16( *Q_cldfb_final, 11 ) ) + { + FOR( n = 0; n < hSplitBinLCLDDec->iChannels; n++ ) + { + FOR( k = 0; k < hSplitBinLCLDDec->iNumBlocks; k++ ) + { + FOR( Word16 j = 0; j < CLDFB_NO_CHANNELS_MAX; j++ ) + { + hSplitBinLCLDDec->pppfDecLCLDReal_fx[n][k][j] = L_shl_r( hSplitBinLCLDDec->pppfDecLCLDReal_fx[n][k][j], sub( 11, *Q_cldfb_final ) ); // Q11 + hSplitBinLCLDDec->pppfDecLCLDImag_fx[n][k][j] = L_shl_r( hSplitBinLCLDDec->pppfDecLCLDImag_fx[n][k][j], sub( 11, *Q_cldfb_final ) ); // Q11 + } + } + } + *Q_cldfb_final = 11; + } + /* continue concealing */ + isar_splitBinRendPLC( hSplitBinLCLDDec->hSplitRendPLC, Cldfb_Out_Real_fx, Cldfb_Out_Imag_fx, (int16_t) hSplitBinLCLDDec->iChannels, hSplitBinLCLDDec->iNumBlocks, hSplitBinLCLDDec->iNumIterations, GetDecodingFailedStatus( hSplitBinLCLDDec->psLCLDDecoder ), *Q_cldfb_final ); + } + IF( AnyDecodingFailedPrev( hSplitBinLCLDDec->psLCLDDecoder ) ) + { + IF( NE_16( *Q_cldfb_final, 11 ) ) + { + FOR( n = 0; n < hSplitBinLCLDDec->iChannels; n++ ) + { + FOR( k = 0; k < hSplitBinLCLDDec->iNumBlocks; k++ ) + { + FOR( Word16 j = 0; j < CLDFB_NO_CHANNELS_MAX; j++ ) + { + hSplitBinLCLDDec->pppfDecLCLDReal_fx[n][k][j] = L_shl_r( hSplitBinLCLDDec->pppfDecLCLDReal_fx[n][k][j], sub( 11, *Q_cldfb_final ) ); // Q11 + hSplitBinLCLDDec->pppfDecLCLDImag_fx[n][k][j] = L_shl_r( hSplitBinLCLDDec->pppfDecLCLDImag_fx[n][k][j], sub( 11, *Q_cldfb_final ) ); // Q11 + } + } + } + *Q_cldfb_final = 11; + } + /* cross-fade recovered frame into good frame */ + isar_splitBinRendPLC_xf_fx( hSplitBinLCLDDec->hSplitRendPLC, Cldfb_Out_Real_fx, Cldfb_Out_Imag_fx, (int16_t) hSplitBinLCLDDec->iChannels, hSplitBinLCLDDec->iNumBlocks, hSplitBinLCLDDec->iNumIterations, GetDecodingFailedStatus( hSplitBinLCLDDec->psLCLDDecoder ), GetDecodingFailedPrevStatus( hSplitBinLCLDDec->psLCLDDecoder ), *Q_cldfb_final ); + } + } + } + ELSE + { + /* set states in decoder */ + SetDecodingUnresolved( hSplitBinLCLDDec->psLCLDDecoder ); + + /* do PLC for lost split renderer frame */ + isar_splitBinRendPLC( hSplitBinLCLDDec->hSplitRendPLC, Cldfb_Out_Real_fx, Cldfb_Out_Imag_fx, (int16_t) hSplitBinLCLDDec->iChannels, hSplitBinLCLDDec->iNumBlocks, hSplitBinLCLDDec->iNumIterations, GetDecodingFailedStatus( hSplitBinLCLDDec->psLCLDDecoder ), *Q_cldfb_final ); + } + + /* save PLC state */ + isar_splitBinRendPLCsaveState( hSplitBinLCLDDec->hSplitRendPLC, Cldfb_Out_Real_fx, Cldfb_Out_Imag_fx, (int16_t) hSplitBinLCLDDec->iChannels, hSplitBinLCLDDec->iNumBlocks, hSplitBinLCLDDec->iNumIterations ); + hSplitBinLCLDDec->hSplitRendPLC->CldfbPLC_state.Q_Prev_Bin_fx = *Q_cldfb_final; + move16(); + pop_wmops(); + + return; +} +#endif diff --git a/lib_isar/isar_splitRend_lcld_enc.c b/lib_isar/isar_splitRend_lcld_enc.c new file mode 100644 index 0000000000000000000000000000000000000000..6804e97a408d1d52d0b65a80b8262c220b9a07b5 --- /dev/null +++ b/lib_isar/isar_splitRend_lcld_enc.c @@ -0,0 +1,239 @@ +/****************************************************************************************************** + + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository. All Rights Reserved. + + This software is protected by copyright law and by international treaties. + The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository retain full ownership rights in their respective contributions in + the software. This notice grants no license of any kind, including but not limited to patent + license, nor is any license granted by implication, estoppel or otherwise. + + Contributors are required to enter into the IVAS codec Public Collaboration agreement before making + contributions. + + This software is provided "AS IS", without any express or implied warranties. The software is in the + development stage. It is intended exclusively for experts who have experience with such software and + solely for the purpose of inspection. All implied warranties of non-infringement, merchantability + and fitness for a particular purpose are hereby disclaimed and excluded. + + Any dispute, controversy or claim arising under or in relation to providing this software shall be + submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in + accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and + the United Nations Convention on Contracts on the International Sales of Goods. + +*******************************************************************************************************/ + +#include +#include "options.h" +#ifdef SPLIT_REND_WITH_HEAD_ROT +#include "isar_prot.h" +#include "ivas_prot_fx.h" +#ifdef DEBUGGING +#include "debug.h" +#endif +#include "wmc_auto.h" + +/*------------------------------------------------------------------------- + * Function isar_splitBinLCLDEncOpen() + * + * + *------------------------------------------------------------------------*/ +ivas_error isar_splitBinLCLDEncOpen( + ISAR_BIN_HR_SPLIT_LCLD_ENC_HANDLE *hSplitBinLCLDEnc, + const Word32 iSampleRate, + const Word16 iChannels, + const Word32 iDataRate, + const Word16 iNumBlocks, + const Word16 iNumIterations ) +{ + ISAR_BIN_HR_SPLIT_LCLD_ENC_HANDLE splitBinLCLDEnc; + ivas_error error; + + IF( ( splitBinLCLDEnc = (ISAR_BIN_HR_SPLIT_LCLD_ENC_HANDLE) malloc( sizeof( ISAR_BIN_HR_SPLIT_LCLD_ENC ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); + } + + splitBinLCLDEnc->pLcld_enc = NULL; /* place holder for CLDFB encoder handle*/ + + splitBinLCLDEnc->iChannels = iChannels; + IF( ( error = CreateLCLDEncoder( &( splitBinLCLDEnc->psLCLDEncoder ), iSampleRate, iChannels, iDataRate, 1, iNumBlocks, (Word16) CLDFB_NO_COL_MAX / iNumBlocks, 0 ) ) != IVAS_ERR_OK ) + { + return error; + } + + IF( ( splitBinLCLDEnc->pppfLCLDReal_fx = (Word32 ***) malloc( iChannels * sizeof( Word32 ** ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); + } + IF( ( splitBinLCLDEnc->pppfLCLDImag_fx = (Word32 ***) malloc( iChannels * sizeof( Word32 ** ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); + } + + FOR( Word16 n = 0; n < splitBinLCLDEnc->iChannels; n++ ) + { + IF( ( splitBinLCLDEnc->pppfLCLDReal_fx[n] = (Word32 **) malloc( CLDFB_NO_COL_MAX * sizeof( Word32 * ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); + } + IF( ( splitBinLCLDEnc->pppfLCLDImag_fx[n] = (Word32 **) malloc( CLDFB_NO_COL_MAX * sizeof( Word32 * ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); + } + } + + splitBinLCLDEnc->iNumIterations = iNumIterations; + splitBinLCLDEnc->iNumBlocks = iNumBlocks; + +#ifdef CLDFB_DEBUG + splitBinLCLDEnc->numFrame = 0; + char cldfbFilename[50] = "cldfb_in_ref.qmf"; + if ( ( splitBinLCLDEnc->cldfbIn = fopen( cldfbFilename, "rb" ) ) == NULL ) + { + fprintf( stderr, "Error: CLDFB bitstream file %s could not be opened\n\n", cldfbFilename ); + exit( -1 ); + } + int16_t chan, band; + fread( &chan, sizeof( int16_t ), 1, splitBinLCLDEnc->cldfbIn ); + fread( &band, sizeof( int16_t ), 1, splitBinLCLDEnc->cldfbIn ); +#endif + + *hSplitBinLCLDEnc = splitBinLCLDEnc; + + return IVAS_ERR_OK; +} + + +/*------------------------------------------------------------------------- + * Function isar_splitBinLCLDEncClose() + * + * + *------------------------------------------------------------------------*/ + +void isar_splitBinLCLDEncClose( + ISAR_BIN_HR_SPLIT_LCLD_ENC_HANDLE *hSplitBinLCLDEnc ) +{ + IF( ( *hSplitBinLCLDEnc ) != NULL ) + { + DeleteLCLDEncoder( ( *hSplitBinLCLDEnc )->psLCLDEncoder ); + + FOR( int16_t n = 0; n < ( *hSplitBinLCLDEnc )->iChannels; n++ ) + { + free( ( *hSplitBinLCLDEnc )->pppfLCLDReal_fx[n] ); + free( ( *hSplitBinLCLDEnc )->pppfLCLDImag_fx[n] ); + } + free( ( *hSplitBinLCLDEnc )->pppfLCLDReal_fx ); + free( ( *hSplitBinLCLDEnc )->pppfLCLDImag_fx ); +#ifdef CLDFB_DEBUG + if ( ( *hSplitBinLCLDEnc )->cldfbIn != NULL ) + { + fclose( ( *hSplitBinLCLDEnc )->cldfbIn ); + } +#endif + + free( *hSplitBinLCLDEnc ); + *hSplitBinLCLDEnc = NULL; + } + + return; +} + +/*------------------------------------------------------------------------- + * Function isar_splitBinLCLDEncProcess() + * + * + *------------------------------------------------------------------------*/ +void isar_splitBinLCLDEncProcess( + ISAR_BIN_HR_SPLIT_LCLD_ENC_HANDLE hSplitBinLCLDEnc, + Word32 Cldfb_In_Real_fx[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + Word32 Cldfb_In_Imag_fx[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + const Word32 available_bits, + ISAR_SPLIT_REND_BITS_HANDLE pBits, + Word16 *q_final ) +{ + Word32 iBitsWritten, itr, available_bits_itr, rem_itr, available_bits_local; + push_wmops( "isar_splitBinLCLDEncProcess" ); + assert( hSplitBinLCLDEnc != NULL ); + assert( Cldfb_In_Real_fx != NULL ); + assert( Cldfb_In_Imag_fx != NULL ); + assert( pBits != NULL ); + + available_bits_local = available_bits; + move32(); + Word16 tmp, tmp_e; + /* A conversion is needed for the 3d pointer interface here ........ */ + FOR( itr = 0; itr < hSplitBinLCLDEnc->iNumIterations; itr++ ) + { + + rem_itr = L_sub( hSplitBinLCLDEnc->iNumIterations, itr ); + tmp = BASOP_Util_Divide3232_Scale( available_bits_local, rem_itr, &tmp_e ); + available_bits_itr = shr( tmp, sub( 15, tmp_e ) ); // Q0 + // available_bits_itr = available_bits_local / rem_itr; + FOR( Word32 n = 0; n < hSplitBinLCLDEnc->iChannels; n++ ) + { + FOR( Word32 k = 0; k < hSplitBinLCLDEnc->iNumBlocks; k++ ) + { + hSplitBinLCLDEnc->pppfLCLDReal_fx[n][k] = Cldfb_In_Real_fx[n][hSplitBinLCLDEnc->iNumBlocks * itr + k]; + hSplitBinLCLDEnc->pppfLCLDImag_fx[n][k] = Cldfb_In_Imag_fx[n][hSplitBinLCLDEnc->iNumBlocks * itr + k]; + } + } +#ifdef CLDFB_DEBUG + int16_t readByte = 0; + for ( int16_t k = 0; k < hSplitBinLCLDEnc->iNumBlocks; k++ ) + { + for ( int16_t b = 0; b < CLDFB_NO_CHANNELS_MAX; b++ ) + { + 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 < hSplitBinLCLDEnc->iNumBlocks; k++ ) + { + for ( int16_t b = 0; b < CLDFB_NO_CHANNELS_MAX; b++ ) + { + 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_fx, hSplitBinLCLDEnc->pppfLCLDImag_fx, &iBitsWritten, available_bits_itr, pBits, q_final ); + + available_bits_local = L_sub( available_bits_local, iBitsWritten ); +#ifdef DEBUGGING + assert( available_bits_local >= 0 ); +#endif + +#ifdef CLDFB_DEBUG + printf( "Bits written = %d\n", iBitsWritten ); +#endif + } + pop_wmops(); + + return; +} +#endif diff --git a/lib_isar/isar_splitRendererPLC.c b/lib_isar/isar_splitRendererPLC.c new file mode 100644 index 0000000000000000000000000000000000000000..e3a0ce0e8b4bff86eafd047de36493b2893a57bb --- /dev/null +++ b/lib_isar/isar_splitRendererPLC.c @@ -0,0 +1,1297 @@ +/****************************************************************************************************** + + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository. All Rights Reserved. + + This software is protected by copyright law and by international treaties. + The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository retain full ownership rights in their respective contributions in + the software. This notice grants no license of any kind, including but not limited to patent + license, nor is any license granted by implication, estoppel or otherwise. + + Contributors are required to enter into the IVAS codec Public Collaboration agreement before making + contributions. + + This software is provided "AS IS", without any express or implied warranties. The software is in the + development stage. It is intended exclusively for experts who have experience with such software and + solely for the purpose of inspection. All implied warranties of non-infringement, merchantability + and fitness for a particular purpose are hereby disclaimed and excluded. + + Any dispute, controversy or claim arising under or in relation to providing this software shall be + submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in + accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and + the United Nations Convention on Contracts on the International Sales of Goods. + +*******************************************************************************************************/ + +#include +#include "options.h" +#ifdef SPLIT_REND_WITH_HEAD_ROT +#include +#include "ivas_prot_fx.h" +#include "prot_fx.h" +#include "isar_cnst.h" +#include "isar_prot.h" +#include "enh64.h" +#ifdef DEBUGGING +#include "debug.h" +#endif +#include "wmc_auto.h" +#include "prot_fx.h" +#include "basop_util.h" +#include "enh64.h" + +/*------------------------------------------------------------------------- + * Local constants + *------------------------------------------------------------------------*/ +#define PI_CONST ( 341782638 ) // Q31 +#define DO_PERTURB 1 +#define PH_PERT_ONLY 1 +#define START_VAL_AVG_LEN 2 +#define SR_PLC_FADE_START 10 /* start fading at this number of bad frames in row */ +#define SR_PLC_MUTE 30 /* Total mute at this number of bad frames in row */ +#define SR_PLC_FADE_DEGREE -3 /* fading degree per frame in dB */ +#define SRHO_THRESH ( 2.f / 3.f * 0.1f ) +#define SRHO_THRESH_FX ( 143165584 ) +#define STH_THRESH_FX ( 749613227 ) +#define STH_THRESH ( 2.f / 3.f * PI2 / 12 ) +#define PLC_FADE_CNST SR_PLC_FADE_START *CLDFB_NO_COL_MAX +#define PLC_MUTE_CNST SR_PLC_MUTE *CLDFB_NO_COL_MAX +Word32 xf_alp_tab[CLDFB_PLC_XF] = { 1431655680, 715827840 }; + +/*------------------------------------------------------------------------- + * Function adaptive_polar_ext_plc() + * + * + *------------------------------------------------------------------------*/ +static void adaptive_polar_ext_plc_fx( + const Word32 *prev_real_fx, + const Word32 *prev_imag_fx, + Word32 *rec_real_fx, + Word32 *rec_imag_fx, + Word16 *rec_real_exp, + Word16 *rec_imag_exp +#if CLDFB_PLC_XF > 0 + , + Word32 xf_alp_fx[CLDFB_PLC_XF], + Word32 xf_bet_fx[CLDFB_PLC_XF] +#endif + , + Word16 exp, + const Word16 iNumCols ) + +{ + /*TODO: Add basops and instrumentation where ever possible*/ + Word32 uth_fx[CLDFB_NO_COL_MAX], urh_fx[CLDFB_NO_COL_MAX]; + Word64 uthu_fx[CLDFB_NO_COL_MAX], drho_fx, srho_fx, diff_fx, dth_fx, sth_fx, ph_adj_fx, rat_real_fx, rat_imag_fx; + Word32 ph_diff_fx, ph_adj_t_fx, quot_fx, dth32, fac_real_fx, fac_imag_fx, rat_real32_fx, rat_imag32_fx, abs2inv_fx; + Word16 srho_q, sth_q, dth16, drho_q, rat_real_q, rat_imag_q, temp_16, rat_real_sum_q, rat_imag_sum_q, start_q, fac_real_q, fac_imag_q; + Word64 Ruu_real_fx[2], Ruu_imag_fx[2], abs_fac_fx; + Word32 Ruu_real_fx_1, Ruu_imag_fx_1, Ruu_real_fx_0, abs_fac_32, abs_fac_powj_32, comp_fac_fx; + Word16 Ruu_real_fx_1_q, Ruu_imag_fx_1_q, Ruu_real_fx_0_q, dth_q, urh_exp[CLDFB_NO_COL_MAX]; + Word32 fac_ph_real_fx, fac_ph_imag_fx, abs_temp_fx; + Word32 start_real_fx, start_imag_fx, fac_powj_real_fx, fac_powj_imag_fx, temp_fx; + Word32 k, j; + Word16 quot_exp[CLDFB_NO_COL_MAX]; + Word16 drho_exp[CLDFB_NO_COL_MAX]; + Word16 srho_exp[CLDFB_NO_COL_MAX]; + /* Word16 rec_real_exp[CLDFB_NO_COL_MAX + CLDFB_PLC_XF]; + Word16 rec_imag_exp[CLDFB_NO_COL_MAX + CLDFB_PLC_XF];*/ + /* reset of accumulators */ + ph_adj_fx = 0; + drho_fx = 0; + srho_fx = 0; + dth_fx = 0; + sth_fx = 0; + Word16 sqrt_exp = 0, sqrt_exp1; + Word32 temp_32; + Word16 lshift; + Word64 temp_64, real_sum, imag_sum; + /* calculate per-sample phase and magnitude evolution in preceding frame */ + FOR( k = 0; k < iNumCols; k++ ) + { + real_sum = W_mult_32_32( prev_real_fx[k], prev_real_fx[k] ); + rat_real_sum_q = add( shl( exp, 1 ), 1 ); + imag_sum = W_mult_32_32( prev_imag_fx[k], prev_imag_fx[k] ); + rat_imag_sum_q = add( shl( exp, 1 ), 1 ); + temp_64 = W_add( real_sum, imag_sum ); + lshift = W_norm( temp_64 ); + temp_32 = W_extract_h( W_shl( temp_64, lshift ) ); + sqrt_exp = sub( add( shl( exp, 1 ), lshift ), 31 ); + sqrt_exp = sub( 31, sqrt_exp ); + urh_fx[k] = Sqrt32( temp_32, &sqrt_exp ); + urh_exp[k] = sub( 31, sqrt_exp ); + // In Float the condition is if ( urh[k] < EPSILON ) + IF( EQ_32( urh_fx[k], 0 ) ) + { + /* zero encountered */ + BREAK; + } + + uth_fx[k] = L_shl( BASOP_util_atan2( prev_imag_fx[k], prev_real_fx[k], 0 ), 15 ); // Q28 + /* phase unwrap */ + IF( EQ_32( k, 0 ) ) + { + uthu_fx[0] = uth_fx[0]; + } + ELSE + { + /* phase unwrap */ + ph_diff_fx = L_sub( uth_fx[k], uth_fx[k - 1] ); + + uthu_fx[k] = uth_fx[k]; + Word32 quot_fx_durho; + Word16 s = 0, s_diff; + Word32 add_fact, quo_sq; + IF( GE_32( L_abs( ph_diff_fx ), L_shr( PI2_FX, 2 ) ) ) + { + temp_32 = L_deposit_h( BASOP_Util_Divide3232_Scale( ph_diff_fx, PI2_FX, &s ) ); // Q(31) + ph_adj_t_fx = ( temp_32 == ONE_IN_Q30 ) ? L_sub( ONE_IN_Q31, 1 ) : L_shl( temp_32, s ); + IF( EQ_32( L_abs( L_sub( L_add( ph_adj_t_fx, 1 ), L_shr( ph_adj_t_fx, 31 ) ) ), ONE_IN_Q30 ) ) + { + ph_adj_t_fx = L_shr( ph_adj_t_fx, 31 ); + } + add_fact = ( L_abs( ph_adj_t_fx ) >= ONE_IN_Q30 ) ? ( ( ph_adj_t_fx < 0 ) ? 1686629713 : -1686629713 ) : 0; + ph_adj_fx = W_add( add_fact, ph_adj_fx ); // Q28 + } + /* unwrapped phase in uthu */ + uthu_fx[k] = W_add( uthu_fx[k], ph_adj_fx ); // Q28 + /* mean and stdev of per-sample magnitude ratios */ + s_diff = sub( urh_exp[k - 1], urh_exp[k] ); + temp_16 = BASOP_Util_Divide3232_Scale( urh_fx[k], urh_fx[k - 1], &s ); + quot_fx = L_shl( temp_16, 16 ); // Q(31-s) + quot_exp[k] = sub( sub( 31, s_diff ), s ); + quot_fx_durho = quot_fx; + drho_exp[k] = quot_exp[k]; + IF( GE_32( k, 2 ) ) + { + IF( LT_16( drho_exp[k - 1], drho_exp[k] ) ) + { + quot_fx_durho = L_shr( quot_fx_durho, sub( drho_exp[k], drho_exp[k - 1] ) ); + drho_exp[k] = drho_exp[k - 1]; + } + ELSE IF( GT_16( drho_exp[k - 1], drho_exp[k] ) ) + { + drho_fx = W_shr( drho_fx, sub( drho_exp[k - 1], drho_exp[k] ) ); + } + } + drho_fx = W_add( quot_fx_durho, drho_fx ); // Q(31-s) + srho_exp[k] = sub( 31, shl( add( s_diff, s ), 1 ) ); + quo_sq = Mpy_32_32( quot_fx, quot_fx ); + IF( GE_32( k, 2 ) ) + { + IF( LT_16( srho_exp[k - 1], srho_exp[k] ) ) + { + quo_sq = L_shr( quo_sq, sub( srho_exp[k], srho_exp[k - 1] ) ); + srho_exp[k] = srho_exp[k - 1]; + } + ELSE IF( GT_16( srho_exp[k - 1], srho_exp[k] ) ) + { + srho_fx = W_shr( srho_fx, sub( srho_exp[k - 1], srho_exp[k] ) ); + } + } + srho_fx = W_add( srho_fx, quo_sq ); // Q(31-s) + diff_fx = W_sub( uthu_fx[k], uthu_fx[k - 1] ); // Q28 /* the mean value calculation could be optimized */ + + dth_fx = W_add( dth_fx, diff_fx ); // Q28 + temp_32 = W_extract_l( diff_fx ); + sth_fx = W_add( sth_fx, (Word64) Mpy_32_32( temp_32, temp_32 ) ); // Q25 + + /* mean and stdev of per-sample phase differences */ + } + } + + Word16 tmp_e, tmp, drho_sqr_q, temp_q; + Word32 divide_fact, drho_32, drho_sqr, dth_sqr; + IF( EQ_32( k, iNumCols ) ) + { + + tmp = BASOP_Util_Divide1616_Scale( 1, sub( iNumCols, 1 ), &tmp_e ); + divide_fact = L_shl( tmp, sub( 31, add( 15, negate( tmp_e ) ) ) ); // Q31 + /* mean and stdev of per-sample magnitude ratios */ + lshift = W_norm( drho_fx ); + tmp_e = drho_exp[k - 1]; + IF( LT_16( lshift, 32 ) ) + { + drho_fx = W_shl( drho_fx, lshift ); + tmp_e = add( tmp_e, lshift ); + } + drho_32 = W_extract_h( drho_fx ); // Qtmp_e-32 + drho_32 = Mpy_32_32( drho_32, divide_fact ); + drho_sqr = Mpy_32_32( drho_32, drho_32 ); // Q(2*(tmp_e -32) - 31) + temp_64 = W_mult_32_32( sub( iNumCols, 1 ), drho_sqr ); // Q(2*(tmp_e -32) - 30) + drho_sqr_q = sub( shl( sub( tmp_e, 32 ), 1 ), 30 ); + temp_q = srho_exp[k - 1]; + IF( GT_16( srho_exp[k - 1], drho_sqr_q ) ) + { + temp_64 = W_shl( temp_64, sub( srho_exp[k - 1], drho_sqr_q ) ); + temp_q = srho_exp[k - 1]; + } + ELSE IF( GT_16( drho_sqr_q, srho_exp[k - 1] ) ) + { + srho_fx = W_shl( srho_fx, sub( drho_sqr_q, srho_exp[k - 1] ) ); + temp_q = drho_sqr_q; + } + temp_64 = W_sub( srho_fx, temp_64 ); + drho_q = sub( tmp_e, 32 ); + IF( GT_64( temp_64, 0 ) ) + { + lshift = W_norm( temp_64 ); + temp_32 = W_extract_h( W_shl( temp_64, lshift ) ); + sqrt_exp = sub( add( temp_q, lshift ), 32 ); + tmp = BASOP_Util_Divide1616_Scale( 1, sub( iNumCols, 2 ), &tmp_e ); + divide_fact = L_shl( tmp, sub( 31, add( 15, negate( tmp_e ) ) ) ); // Q31 + temp_32 = Mpy_32_32( temp_32, divide_fact ); // Qsqrt_exp + sqrt_exp1 = sub( 31, sqrt_exp ); + srho_fx = Sqrt32( temp_32, &sqrt_exp1 ); + srho_q = sub( 31, sqrt_exp1 ); + } + ELSE + { + srho_q = 31; + srho_fx = 0; + } + /* mean and stdev of per-sample phase differences */ + tmp = BASOP_Util_Divide1616_Scale( 1, sub( iNumCols, 1 ), &tmp_e ); + divide_fact = L_shl( tmp, sub( 31, add( 15, negate( tmp_e ) ) ) ); // Q31 + /* mean and stdev of per-sample phase differences */ + lshift = W_norm( dth_fx ); + dth_fx = W_shl( dth_fx, lshift ); // Q28+lshift + dth32 = W_extract_h( dth_fx ); // Q28+lshift-32 + dth_q = sub( add( 28, lshift ), 32 ); + dth32 = Mpy_32_32( dth32, divide_fact ); + dth_sqr = Mpy_32_32( dth32, dth32 ); // Q28+lshift-32 + temp_64 = W_mult_32_32( sub( iNumCols, 1 ), dth_sqr ); // Q(2*lshift-39) + temp_q = sub( sub( shl( lshift, 1 ), 8 ), 30 ); + // printf( "%f \t", temp ); + IF( GT_16( temp_q, 25 ) ) + { + + sth_fx = W_shl( sth_fx, sub( temp_q, 25 ) ); + } + ELSE IF( GT_16( 25, temp_q ) ) + { + temp_64 = W_shl( temp_64, sub( 25, temp_q ) ); + temp_q = 25; + } + + temp_64 = W_sub( sth_fx, temp_64 ); + IF( GT_64( temp_64, 0 ) ) + { + lshift = W_norm( temp_64 ); + temp_32 = W_extract_h( W_shl( temp_64, lshift ) ); + sqrt_exp = sub( add( temp_q, lshift ), 32 ); + tmp = BASOP_Util_Divide1616_Scale( 1, sub( iNumCols, 2 ), &tmp_e ); + divide_fact = L_shl( tmp, sub( 31, add( 15, negate( tmp_e ) ) ) ); // Q31 + temp_32 = Mpy_32_32( temp_32, divide_fact ); // Qsqrt_exp + sqrt_exp1 = sub( 31, sqrt_exp ); + sth_fx = Sqrt32( temp_32, &sqrt_exp1 ); + sth_q = sub( 31, sqrt_exp1 ); + } + ELSE + { + sth_fx = 0; + sth_q = 31; + } + + /* do phase extension only IF the std deviations are small */ + IF( LT_64( srho_fx, W_shl( SRHO_THRESH_FX, sub( srho_q, 31 ) ) ) || LT_64( sth_fx, W_shl( STH_THRESH_FX, sub( sth_q, 31 ) ) ) ) + { + dth32 = L_shl( Mpy_32_32( dth32, PI_CONST ), sub( 31, dth_q ) ); // Q28+lshift-32-16 + dth16 = extract_h( dth32 ); + fac_ph_real_fx = L_deposit_h( getCosWord16R2( dth16 ) ); + fac_ph_imag_fx = L_deposit_h( getSineWord16R2( dth16 ) ); + ///* calculate complex evolution factor */ + fac_real_fx = Mpy_32_32( min( L_shl( 1, drho_q ), drho_32 ), fac_ph_real_fx ); // Qdrho_exp + fac_imag_fx = Mpy_32_32( min( L_shl( 1, drho_q ), drho_32 ), fac_ph_imag_fx ); // Qdrho_exp +#if START_VAL_AVG_LEN > 1 + /* Calculate start value FOR evolution from last samples of previous frame */ + fac_powj_real_fx = fac_real_fx; + fac_powj_imag_fx = fac_imag_fx; + start_real_fx = prev_real_fx[iNumCols - 1]; + start_imag_fx = prev_imag_fx[iNumCols - 1]; + FOR( j = 1; j < START_VAL_AVG_LEN; j++ ) + { + start_real_fx = L_add( L_shr( start_real_fx, sub( exp, sub( add( drho_q, exp ), 31 ) ) ), L_sub( Mpy_32_32( fac_powj_real_fx, prev_real_fx[iNumCols - j - 1] ), Mpy_32_32( fac_powj_imag_fx, prev_imag_fx[iNumCols - j - 1] ) ) ); // Q(drho_q+exp-31) + start_imag_fx = L_add( L_shr( start_imag_fx, sub( exp, sub( add( drho_q, exp ), 31 ) ) ), L_add( Mpy_32_32( fac_powj_imag_fx, prev_real_fx[iNumCols - j - 1] ), Mpy_32_32( fac_powj_real_fx, prev_imag_fx[iNumCols - j - 1] ) ) ); // Q(drho_q+exp-31) + temp_fx = L_shl( L_sub( Mpy_32_32( fac_powj_real_fx, fac_real_fx ), Mpy_32_32( fac_powj_imag_fx, fac_imag_fx ) ), sub( sub( drho_q, shl( drho_q, 1 ) ), 31 ) ); // Qdrho_q + fac_powj_imag_fx = L_shl( L_add( Mpy_32_32( fac_powj_imag_fx, fac_real_fx ), Mpy_32_32( fac_powj_real_fx, fac_imag_fx ) ), sub( sub( drho_q, shl( drho_q, 1 ) ), 31 ) ); // Qdrho_q + fac_powj_real_fx = temp_fx; + } + start_q = sub( add( drho_q, exp ), 30 ); +#else + /* take last sample of previous frame as start value */ + start_real = prev_real[iNumCols - 1]; + start_imag = prev_imag[iNumCols - 1]; +#endif + +#if DO_PERTURB != 0 + + /* make evolution less static: apply per samples differences as in preceding frame */ + rat_real_fx = W_add( W_mult_32_32( prev_real_fx[1], prev_real_fx[0] ), W_mult_32_32( prev_imag_fx[1], prev_imag_fx[0] ) ); // 2*exp + rat_imag_fx = W_add( W_mult_32_32( -prev_real_fx[1], prev_imag_fx[0] ), W_mult_32_32( prev_imag_fx[1], prev_real_fx[0] ) ); // 2*exp + +#if PH_PERT_ONLY != 0 + + lshift = W_norm( rat_real_fx ); + temp_64 = W_shl( rat_real_fx, lshift ); // Q2*exp+lshift + rat_real32_fx = W_extract_h( temp_64 ); // Q2*exp+lshift-31 + rat_real_q = sub( add( shl( exp, 1 ), lshift ), 31 ); + lshift = W_norm( rat_imag_fx ); + temp_64 = W_shl( rat_imag_fx, lshift ); // Q2*exp+lshift + rat_imag32_fx = W_extract_h( temp_64 ); // Q2*exp+lshift-31 + rat_imag_q = sub( add( shl( exp, 1 ), lshift ), 31 ); + real_sum = W_mult_32_32( rat_real32_fx, rat_real32_fx ); + rat_real_sum_q = add( shl( rat_real_q, 1 ), 1 ); + imag_sum = W_mult_32_32( rat_imag32_fx, rat_imag32_fx ); + rat_imag_sum_q = add( shl( rat_imag_q, 1 ), 1 ); + IF( GT_16( rat_real_sum_q, rat_imag_sum_q ) ) + { + real_sum = W_shr( real_sum, sub( rat_real_sum_q, rat_imag_sum_q ) ); + sqrt_exp = rat_imag_sum_q; + } + ELSE + { + imag_sum = W_shr( imag_sum, sub( rat_imag_sum_q, rat_real_sum_q ) ); + sqrt_exp = rat_real_sum_q; + } + temp_64 = W_add( W_shr( real_sum, 1 ), W_shr( imag_sum, 1 ) ); + lshift = W_norm( temp_64 ); + temp_64 = W_shl( temp_64, lshift ); + temp_32 = W_extract_h( temp_64 ); + sqrt_exp = sub( add( sub( sqrt_exp, 1 ), lshift ), 32 ); + /* only phase perturbation */ + sqrt_exp = sub( 31, sqrt_exp ); + tmp_e = 0; + abs_temp_fx = Sqrt32( temp_32, &sqrt_exp ); // Q(31-sqrt_exp) + + lshift = norm_l( drho_32 ); + drho_32 = L_shl( drho_32, lshift ); + drho_q = add( drho_q, lshift ); + IF( EQ_16( drho_q, 31 ) ) + { + abs2inv_fx = L_deposit_h( BASOP_Util_Divide3232_Scale( L_min( ONE_IN_Q31, drho_32 ), L_max( 1, abs_temp_fx ), &tmp_e ) ); // +drho_q +sqrt_exp-tmp_e + } + ELSE + { + abs2inv_fx = L_deposit_h( BASOP_Util_Divide3232_Scale( L_min( L_shl( 1, drho_q ), drho_32 ), L_max( 1, abs_temp_fx ), &tmp_e ) ); // +drho_q +sqrt_exp-tmp_e + } + temp_16 = sub( add( drho_q, sqrt_exp ), tmp_e ); + + rat_real_fx = W_mult_32_32( rat_real32_fx, abs2inv_fx ); + + rat_imag_fx = W_mult_32_32( rat_imag32_fx, abs2inv_fx ); + rat_real_q = add( add( rat_real_q, temp_16 ), 1 ); + + rat_imag_q = add( add( rat_imag_q, temp_16 ), 1 ); + +#else + /* phase and magnitude perturbation */ + abs2inv = 1 / ( max( 1, drho ) * ( SQR( prev_real[0] ) + SQR( prev_imag[0] ) ) ); + rat_real *= abs2inv; + rat_imag *= abs2inv; +#endif + lshift = W_norm( rat_real_fx ); + temp_64 = W_shl( rat_real_fx, lshift ); // Q2*exp+lshift + rat_real32_fx = W_extract_h( temp_64 ); // Q2*exp+lshift-31 + rat_real_q = sub( add( rat_real_q, lshift ), 32 ); + lshift = W_norm( rat_imag_fx ); + temp_64 = W_shl( rat_imag_fx, lshift ); // Q2*exp+lshift + rat_imag32_fx = W_extract_h( temp_64 ); // Q2*exp+lshift-31 + rat_imag_q = sub( add( rat_imag_q, lshift ), 32 ); + + /* apply complex evolution FOR first substitution sample */ + + real_sum = W_mult_32_32( rat_real32_fx, start_real_fx ); + rat_real_sum_q = add( add( rat_real_q, start_q ), 1 ); + imag_sum = W_mult_32_32( rat_imag32_fx, start_imag_fx ); + rat_imag_sum_q = add( add( rat_imag_q, start_q ), 1 ); + IF( GT_16( rat_real_sum_q, rat_imag_sum_q ) ) + { + real_sum = W_shr( real_sum, sub( rat_real_sum_q, rat_imag_sum_q ) ); + sqrt_exp = rat_imag_sum_q; + } + ELSE + { + imag_sum = W_shr( imag_sum, sub( rat_imag_sum_q, rat_real_sum_q ) ); + sqrt_exp = rat_real_sum_q; + } + temp_64 = W_sub( real_sum, imag_sum ); + lshift = W_norm( temp_64 ); + temp_64 = W_shl( temp_64, lshift ); + rec_real_fx[0] = W_extract_h( temp_64 ); // sqrt_exp + lshift-32 + rec_real_exp[0] = sub( add( sqrt_exp, lshift ), 32 ); + + real_sum = W_mult_32_32( rat_imag32_fx, start_real_fx ); + rat_real_sum_q = add( add( rat_imag_q, start_q ), 1 ); + imag_sum = W_mult_32_32( rat_real32_fx, start_imag_fx ); + rat_imag_sum_q = add( add( rat_real_q, start_q ), 1 ); + IF( GT_16( rat_real_sum_q, rat_imag_sum_q ) ) + { + real_sum = W_shr( real_sum, sub( rat_real_sum_q, rat_imag_sum_q ) ); + sqrt_exp = rat_imag_sum_q; + } + ELSE + { + imag_sum = W_shr( imag_sum, sub( rat_imag_sum_q, rat_real_sum_q ) ); + sqrt_exp = rat_real_sum_q; + } + temp_64 = W_add( real_sum, imag_sum ); + lshift = W_norm( temp_64 ); + temp_64 = W_shl( temp_64, lshift ); + rec_imag_fx[0] = W_extract_h( temp_64 ); // sqrt_exp + lshift-32 + rec_imag_exp[0] = sub( add( sqrt_exp, lshift ), 32 ); + FOR( j = 2; j < iNumCols; j++ ) + { + rat_real_fx = W_add( W_mult_32_32( prev_real_fx[j], prev_real_fx[j - 1] ), W_mult_32_32( prev_imag_fx[j], prev_imag_fx[j - 1] ) ); // 2*exp + rat_imag_fx = W_add( W_mult_32_32( -prev_real_fx[j], prev_imag_fx[j - 1] ), W_mult_32_32( prev_imag_fx[j], prev_real_fx[j - 1] ) ); // 2*exp +#if PH_PERT_ONLY != 0 + lshift = W_norm( rat_real_fx ); + temp_64 = W_shl( rat_real_fx, lshift ); // Q2*exp+lshift + rat_real32_fx = W_extract_h( temp_64 ); // Q2*exp+lshift-31 + rat_real_q = sub( add( shl( exp, 1 ), lshift ), 31 ); + lshift = W_norm( rat_imag_fx ); + temp_64 = W_shl( rat_imag_fx, lshift ); // Q2*exp+lshift + rat_imag32_fx = W_extract_h( temp_64 ); // Q2*exp+lshift-31 + rat_imag_q = sub( add( shl( exp, 1 ), lshift ), 31 ); + real_sum = W_mult_32_32( rat_real32_fx, rat_real32_fx ); + rat_real_sum_q = add( shl( rat_real_q, 1 ), 1 ); + imag_sum = W_mult_32_32( rat_imag32_fx, rat_imag32_fx ); + rat_imag_sum_q = add( shl( rat_imag_q, 1 ), 1 ); + + IF( GT_16( rat_real_sum_q, rat_imag_sum_q ) ) + { + real_sum = W_shr( real_sum, sub( rat_real_sum_q, rat_imag_sum_q ) ); + sqrt_exp = rat_imag_sum_q; + } + ELSE + { + imag_sum = W_shr( imag_sum, sub( rat_imag_sum_q, rat_real_sum_q ) ); + sqrt_exp = rat_real_sum_q; + } + + temp_64 = W_add( W_shr( real_sum, 1 ), W_shr( imag_sum, 1 ) ); + lshift = W_norm( temp_64 ); + temp_64 = W_shl( temp_64, lshift ); + temp_32 = W_extract_h( temp_64 ); + sqrt_exp = sub( add( sub( sqrt_exp, 1 ), lshift ), 32 ); + /* only phase perturbation */ + sqrt_exp = sub( 31, sqrt_exp ); + tmp_e = 0; + abs_temp_fx = Sqrt32( temp_32, &sqrt_exp ); // Q(31-sqrt_exp) + + IF( EQ_16( drho_q, 31 ) ) + { + abs2inv_fx = L_deposit_h( BASOP_Util_Divide3232_Scale( min( ONE_IN_Q31, drho_32 ), max( 1, abs_temp_fx ), &tmp_e ) ); // +drho_q +sqrt_exp-tmp_e + } + ELSE + { + abs2inv_fx = L_deposit_h( BASOP_Util_Divide3232_Scale( min( L_shl( 1, drho_q ), drho_32 ), max( 1, abs_temp_fx ), &tmp_e ) ); // +drho_q +sqrt_exp-tmp_e + } + temp_16 = sub( add( drho_q, sqrt_exp ), tmp_e ); + + rat_real_fx = W_mult_32_32( rat_real32_fx, abs2inv_fx ); + rat_imag_fx = W_mult_32_32( rat_imag32_fx, abs2inv_fx ); + rat_real_q = add( add( rat_real_q, temp_16 ), 1 ); + rat_imag_q = add( add( rat_imag_q, temp_16 ), 1 ); + +#else + /* phase and magnitude perturbation */ + abs2inv = 1 / ( max( 1, drho ) * ( SQR( prev_real[j - 1] ) + SQR( prev_imag[j - 1] ) ) ); +#endif + + lshift = W_norm( rat_real_fx ); + temp_64 = W_shl( rat_real_fx, lshift ); // Q2*exp+lshift + rat_real32_fx = W_extract_h( temp_64 ); // Q2*exp+lshift-31 + rat_real_q = sub( add( rat_real_q, lshift ), 32 ); + lshift = W_norm( rat_imag_fx ); + temp_64 = W_shl( rat_imag_fx, lshift ); // Q2*exp+lshift + rat_imag32_fx = W_extract_h( temp_64 ); // Q2*exp+lshift-31 + rat_imag_q = sub( add( rat_imag_q, lshift ), 32 ); + + + real_sum = W_mult_32_32( rat_real32_fx, rec_real_fx[j - 2] ); + rat_real_sum_q = add( add( rat_real_q, rec_real_exp[j - 2] ), 1 ); + imag_sum = W_mult_32_32( rat_imag32_fx, rec_imag_fx[j - 2] ); + rat_imag_sum_q = add( add( rat_imag_q, rec_imag_exp[j - 2] ), 1 ); + IF( GT_16( rat_real_sum_q, rat_imag_sum_q ) ) + { + real_sum = W_shr( real_sum, sub( rat_real_sum_q, rat_imag_sum_q ) ); + sqrt_exp = rat_imag_sum_q; + } + ELSE + { + imag_sum = W_shr( imag_sum, sub( rat_imag_sum_q, rat_real_sum_q ) ); + sqrt_exp = rat_real_sum_q; + } + temp_64 = W_sub( W_shr( real_sum, 1 ), W_shr( imag_sum, 1 ) ); + lshift = W_norm( temp_64 ); + temp_64 = W_shl( temp_64, lshift ); + rec_real_fx[j - 1] = W_extract_h( temp_64 ); // sqrt_exp + lshift-32 + rec_real_exp[j - 1] = sub( add( sub( sqrt_exp, 1 ), lshift ), 32 ); + + real_sum = W_mult_32_32( rat_imag32_fx, rec_real_fx[j - 2] ); + rat_real_sum_q = add( add( rat_imag_q, rec_real_exp[j - 2] ), 1 ); + imag_sum = W_mult_32_32( rat_real32_fx, rec_imag_fx[j - 2] ); + rat_imag_sum_q = add( add( rat_real_q, rec_imag_exp[j - 2] ), 1 ); + IF( GT_16( rat_real_sum_q, rat_imag_sum_q ) ) + { + real_sum = W_shr( real_sum, sub( rat_real_sum_q, rat_imag_sum_q ) ); + sqrt_exp = rat_imag_sum_q; + } + ELSE + { + imag_sum = W_shr( imag_sum, sub( rat_imag_sum_q, rat_real_sum_q ) ); + sqrt_exp = rat_real_sum_q; + } + temp_64 = W_add( W_shr( real_sum, 1 ), W_shr( imag_sum, 1 ) ); + lshift = W_norm( temp_64 ); + temp_64 = W_shl( temp_64, lshift ); + rec_imag_fx[j - 1] = W_extract_h( temp_64 ); // sqrt_exp + lshift-32 + rec_imag_exp[j - 1] = sub( add( sub( sqrt_exp, 1 ), lshift ), 32 ); + } + + /* do the same FOR samples of crossfade region */ + FOR( j = 1; j < CLDFB_PLC_XF + 2; j++ ) + { + rat_real_fx = W_add( W_mult_32_32( prev_real_fx[j], prev_real_fx[j - 1] ), W_mult_32_32( prev_imag_fx[j], prev_imag_fx[j - 1] ) ); // 2*exp + rat_imag_fx = W_add( W_mult_32_32( -prev_real_fx[j], prev_imag_fx[j - 1] ), W_mult_32_32( prev_imag_fx[j], prev_real_fx[j - 1] ) ); // 2*exp + +#if PH_PERT_ONLY != 0 + + lshift = W_norm( rat_real_fx ); + temp_64 = W_shl( rat_real_fx, lshift ); // Q2*exp+lshift + rat_real32_fx = W_extract_h( temp_64 ); // Q2*exp+lshift-31 + rat_real_q = sub( add( shl( exp, 1 ), lshift ), 31 ); + lshift = W_norm( rat_imag_fx ); + temp_64 = W_shl( rat_imag_fx, lshift ); // Q2*exp+lshift + rat_imag32_fx = W_extract_h( temp_64 ); // Q2*exp+lshift-31 + rat_imag_q = sub( add( shl( exp, 1 ), lshift ), 31 ); + real_sum = W_mult_32_32( rat_real32_fx, rat_real32_fx ); + rat_real_sum_q = add( shl( rat_real_q, 1 ), 1 ); + imag_sum = W_mult_32_32( rat_imag32_fx, rat_imag32_fx ); + rat_imag_sum_q = add( shl( rat_imag_q, 1 ), 1 ); + + IF( GT_16( rat_real_sum_q, rat_imag_sum_q ) ) + { + real_sum = W_shr( real_sum, sub( rat_real_sum_q, rat_imag_sum_q ) ); + sqrt_exp = rat_imag_sum_q; + } + ELSE + { + imag_sum = W_shr( imag_sum, sub( rat_imag_sum_q, rat_real_sum_q ) ); + sqrt_exp = rat_real_sum_q; + } + temp_64 = W_add( W_shr( real_sum, 1 ), W_shr( imag_sum, 1 ) ); + lshift = W_norm( temp_64 ); + temp_64 = W_shl( temp_64, lshift ); + temp_32 = W_extract_h( temp_64 ); + sqrt_exp = sub( add( sub( sqrt_exp, 1 ), lshift ), 32 ); + /* only phase perturbation */ + sqrt_exp = sub( 31, sqrt_exp ); + tmp_e = 0; + abs_temp_fx = Sqrt32( temp_32, &sqrt_exp ); // Q(31-sqrt_exp) + + IF( EQ_16( drho_q, 31 ) ) + { + abs2inv_fx = L_deposit_h( BASOP_Util_Divide3232_Scale( min( ONE_IN_Q31, drho_32 ), max( 1, abs_temp_fx ), &tmp_e ) ); // +drho_q +sqrt_exp-tmp_e + } + ELSE + { + abs2inv_fx = L_deposit_h( BASOP_Util_Divide3232_Scale( min( L_shl( 1, drho_q ), drho_32 ), max( 1, abs_temp_fx ), &tmp_e ) ); // +drho_q +sqrt_exp-tmp_e + } + temp_16 = sub( add( drho_q, sqrt_exp ), tmp_e ); + rat_real_fx = W_mult_32_32( rat_real32_fx, abs2inv_fx ); + rat_imag_fx = W_mult_32_32( rat_imag32_fx, abs2inv_fx ); + rat_real_q = add( add( rat_real_q, temp_16 ), 1 ); + rat_imag_q = add( add( rat_imag_q, temp_16 ), 1 ); +#else + abs2inv = 1 / ( max( 1, drho ) * ( SQR( prev_real[j - 1] ) + SQR( prev_imag[j - 1] ) ) ); +#endif + lshift = W_norm( rat_real_fx ); + temp_64 = W_shl( rat_real_fx, lshift ); // Q2*exp+lshift + rat_real32_fx = W_extract_h( temp_64 ); // Q2*exp+lshift-31 + rat_real_q = sub( add( rat_real_q, lshift ), 32 ); + lshift = W_norm( rat_imag_fx ); + temp_64 = W_shl( rat_imag_fx, lshift ); // Q2*exp+lshift + rat_imag32_fx = W_extract_h( temp_64 ); // Q2*exp+lshift-31 + rat_imag_q = sub( add( rat_imag_q, lshift ), 32 ); + + + real_sum = W_mult_32_32( rat_real32_fx, rec_real_fx[j + iNumCols - 3] ); + rat_real_sum_q = add( add( rat_real_q, rec_real_exp[j + iNumCols - 3] ), 1 ); + imag_sum = W_mult_32_32( rat_imag32_fx, rec_imag_fx[j + iNumCols - 3] ); + rat_imag_sum_q = add( add( rat_imag_q, rec_imag_exp[j + iNumCols - 3] ), 1 ); + IF( GT_16( rat_real_sum_q, rat_imag_sum_q ) ) + { + real_sum = W_shr( real_sum, sub( rat_real_sum_q, rat_imag_sum_q ) ); + sqrt_exp = rat_imag_sum_q; + } + ELSE + { + imag_sum = W_shr( imag_sum, sub( rat_imag_sum_q, rat_real_sum_q ) ); + sqrt_exp = rat_real_sum_q; + } + temp_64 = W_sub( W_shr( real_sum, 1 ), W_shr( imag_sum, 1 ) ); + lshift = W_norm( temp_64 ); + temp_64 = W_shl( temp_64, lshift ); + rec_real_fx[j + iNumCols - 2] = W_extract_h( temp_64 ); // sqrt_exp + lshift-32 + rec_real_exp[j + iNumCols - 2] = sub( add( sub( sqrt_exp, 1 ), lshift ), 32 ); + + real_sum = W_mult_32_32( rat_imag32_fx, rec_real_fx[j + iNumCols - 3] ); + rat_real_sum_q = add( add( rat_imag_q, rec_real_exp[j + iNumCols - 3] ), 1 ); + imag_sum = W_mult_32_32( rat_real32_fx, rec_imag_fx[j + iNumCols - 3] ); + rat_imag_sum_q = add( add( rat_real_q, rec_imag_exp[j + iNumCols - 3] ), 1 ); + IF( GT_16( rat_real_sum_q, rat_imag_sum_q ) ) + { + real_sum = W_shr( real_sum, sub( rat_real_sum_q, rat_imag_sum_q ) ); + sqrt_exp = rat_imag_sum_q; + } + ELSE + { + imag_sum = W_shr( imag_sum, sub( rat_imag_sum_q, rat_real_sum_q ) ); + sqrt_exp = rat_real_sum_q; + } + temp_64 = W_add( W_shr( real_sum, 1 ), W_shr( imag_sum, 1 ) ); + lshift = W_norm( temp_64 ); + temp_64 = W_shl( temp_64, lshift ); + rec_imag_fx[j + iNumCols - 2] = W_extract_h( temp_64 ); // sqrt_exp + lshift-32 + rec_imag_exp[j + iNumCols - 2] = sub( add( sub( sqrt_exp, 1 ), lshift ), 32 ); + } +#else + rec_real[0] = fac_real * start_real - fac_imag * start_imag; + rec_imag[0] = fac_imag * start_real + fac_real * start_imag; + FOR( j = 1; j < iNumCols + CLDFB_PLC_XF; j++ ) + { + rec_real[j] = fac_real * rec_real[j - 1] - fac_imag * rec_imag[j - 1]; + rec_imag[j] = fac_imag * rec_real[j - 1] + fac_real * rec_imag[j - 1]; + } +#endif + +#if CLDFB_PLC_XF > 0 + /* apply crossfade */ + FOR( j = 0; j < CLDFB_PLC_XF; j++ ) + { + rec_real_fx[iNumCols + j] = Mpy_32_32( xf_alp_fx[j], rec_real_fx[iNumCols + j] ); + rec_imag_fx[iNumCols + j] = Mpy_32_32( xf_alp_fx[j], rec_imag_fx[iNumCols + j] ); + xf_bet_fx[j] = L_sub( ONE_IN_Q31, xf_alp_fx[j] ); + } +#endif + } + ELSE + { + Word16 guard_bits = find_guarded_bits_fx( iNumCols ); + /* do complex lpc combined with frame repetition */ + Ruu_real_fx[0] = W_add( W_shr( W_mult_32_32( prev_real_fx[0], prev_real_fx[0] ), guard_bits ), W_shr( W_mult_32_32( prev_imag_fx[0], prev_imag_fx[0] ), guard_bits ) ); + Ruu_real_fx[1] = 0; + Ruu_imag_fx[1] = 0; + FOR( j = 1; j < iNumCols; j++ ) + { + Ruu_real_fx[0] = W_add( Ruu_real_fx[0], W_add( W_shr( W_mult_32_32( prev_real_fx[j], prev_real_fx[j] ), guard_bits ), W_shr( W_mult_32_32( prev_imag_fx[j], prev_imag_fx[j] ), guard_bits ) ) ); + Ruu_real_fx[1] = W_add( Ruu_real_fx[1], W_add( W_shr( W_mult_32_32( prev_real_fx[j], prev_real_fx[j - 1] ), guard_bits ), W_shr( W_mult_32_32( prev_imag_fx[j], prev_imag_fx[j - 1] ), guard_bits ) ) ); + Ruu_imag_fx[1] = W_add( Ruu_imag_fx[1], W_sub( W_shr( W_mult_32_32( prev_imag_fx[j], prev_real_fx[j - 1] ), guard_bits ), W_shr( W_mult_32_32( prev_real_fx[j], prev_imag_fx[j - 1] ), guard_bits ) ) ); + } + // printf( "%.7f \t", Ruu_real[1] + lshift = W_norm( Ruu_real_fx[0] ); + Ruu_real_fx_0 = W_extract_h( W_shl( Ruu_real_fx[0], lshift ) ); + Ruu_real_fx_0_q = sub( add( sub( add( shl( exp, 1 ), 1 ), guard_bits ), lshift ), 32 ); + lshift = W_norm( Ruu_real_fx[0] ); + Ruu_real_fx_1 = W_extract_h( W_shl( Ruu_real_fx[1], lshift ) ); + Ruu_real_fx_1_q = sub( add( sub( add( shl( exp, 1 ), 1 ), guard_bits ), lshift ), 32 ); + lshift = W_norm( Ruu_real_fx[0] ); + Ruu_imag_fx_1 = W_extract_h( W_shl( Ruu_imag_fx[1], lshift ) ); + Ruu_imag_fx_1_q = sub( add( sub( add( shl( exp, 1 ), 1 ), guard_bits ), lshift ), 32 ); + IF( GT_64( Ruu_real_fx[0], 0 ) ) + { + /* prediction coefficient */ + fac_real_fx = L_deposit_h( BASOP_Util_Divide3232_Scale( Ruu_real_fx_1, Ruu_real_fx_0, &tmp_e ) ); + fac_real_q = sub( add( sub( 31, tmp_e ), Ruu_real_fx_1_q ), Ruu_real_fx_0_q ); + fac_imag_fx = L_deposit_h( BASOP_Util_Divide3232_Scale( Ruu_imag_fx_1, Ruu_real_fx_0, &tmp_e ) ); + fac_imag_q = sub( add( sub( 31, tmp_e ), Ruu_imag_fx_1_q ), Ruu_real_fx_0_q ); + } + ELSE + { + fac_imag_fx = 0; + fac_imag_q = 31; + fac_real_fx = 0; + fac_real_q = 31; + } + + /* apply prediction using last sample of preceding frame as start value and combine with previous frame samples */ + fac_powj_real_fx = fac_real_fx; + fac_powj_imag_fx = fac_imag_fx; + + Word16 powj_real_q = fac_real_q; + Word16 powj_imag_q = fac_imag_q; + + real_sum = W_mult_32_32( fac_real_fx, fac_real_fx ); + rat_real_sum_q = add( shl( fac_real_q, 1 ), 1 ); + imag_sum = W_mult_32_32( fac_imag_fx, fac_imag_fx ); + rat_imag_sum_q = add( shl( fac_imag_q, 1 ), 1 ); + + IF( GT_16( rat_real_sum_q, rat_imag_sum_q ) ) + { + real_sum = W_shr( real_sum, sub( rat_real_sum_q, rat_imag_sum_q ) ); + sqrt_exp = rat_imag_sum_q; + } + ELSE + { + imag_sum = W_shr( imag_sum, sub( rat_imag_sum_q, rat_real_sum_q ) ); + sqrt_exp = rat_real_sum_q; + } + abs_fac_fx = W_add( W_shr( real_sum, 1 ), W_shr( imag_sum, 1 ) ); + lshift = W_norm( abs_fac_fx ); + abs_fac_32 = W_extract_h( W_shl( abs_fac_fx, lshift ) ); + sqrt_exp = sub( 31, ( sub( add( sub( sqrt_exp, 1 ), lshift ), 32 ) ) ); + abs_fac_32 = Sqrt32( abs_fac_32, &sqrt_exp ); + sqrt_exp = sub( 31, sqrt_exp ); + abs_fac_32 = L_shr( abs_fac_32, sub( sqrt_exp, 31 ) ); // Q31 + sqrt_exp = 31; + abs_fac_powj_32 = L_shr( abs_fac_32, 1 ); // Q30 + sqrt_exp = 30; + + FOR( j = 0; j < iNumCols; j++ ) + { + comp_fac_fx = L_sub( L_shl( 1, sqrt_exp ), abs_fac_powj_32 ); + real_sum = W_mult_32_32( prev_real_fx[iNumCols - 1], fac_powj_real_fx ); + rat_real_sum_q = add( add( exp, powj_real_q ), 1 ); + imag_sum = W_mult_32_32( prev_imag_fx[iNumCols - 1], fac_powj_imag_fx ); + rat_imag_sum_q = add( add( exp, powj_imag_q ), 1 ); + IF( GT_16( rat_real_sum_q, rat_imag_sum_q ) ) + { + real_sum = W_shr( real_sum, sub( rat_real_sum_q, rat_imag_sum_q ) ); + rat_real_sum_q = rat_imag_sum_q; + } + ELSE + { + imag_sum = W_shr( imag_sum, sub( rat_imag_sum_q, rat_real_sum_q ) ); + /*sqrt_exp = rat_real_sum_q;*/ + } + real_sum = W_sub( W_shr( real_sum, guard_bits ), W_shr( imag_sum, guard_bits ) ); + rat_real_sum_q = sub( rat_real_sum_q, guard_bits ); + imag_sum = W_mult_32_32( prev_real_fx[j], comp_fac_fx ); + rat_imag_sum_q = add( add( exp, sqrt_exp ), 1 ); + + IF( GT_16( rat_real_sum_q, rat_imag_sum_q ) ) + { + real_sum = W_shr( real_sum, sub( rat_real_sum_q, rat_imag_sum_q ) ); + rat_real_sum_q = rat_imag_sum_q; + } + ELSE + { + imag_sum = W_shr( imag_sum, sub( rat_imag_sum_q, rat_real_sum_q ) ); + /*sqrt_exp = rat_real_sum_q;*/ + } + real_sum = W_add( W_shr( real_sum, guard_bits ), W_shr( imag_sum, guard_bits ) ); + lshift = W_norm( real_sum ); + rec_real_fx[j] = W_extract_h( W_shl( real_sum, lshift ) ); + rec_real_exp[j] = sub( add( sub( rat_real_sum_q, guard_bits ), lshift ), 32 ); + real_sum = W_mult_32_32( prev_real_fx[iNumCols - 1], fac_powj_imag_fx ); + rat_real_sum_q = add( add( exp, powj_imag_q ), 1 ); + imag_sum = W_mult_32_32( prev_imag_fx[iNumCols - 1], fac_powj_real_fx ); + rat_imag_sum_q = add( add( exp, powj_real_q ), 1 ); + IF( GT_16( rat_real_sum_q, rat_imag_sum_q ) ) + { + real_sum = W_shr( real_sum, sub( rat_real_sum_q, rat_imag_sum_q ) ); + rat_real_sum_q = rat_imag_sum_q; + } + ELSE + { + imag_sum = W_shr( imag_sum, sub( rat_imag_sum_q, rat_real_sum_q ) ); + /*sqrt_exp = rat_real_sum_q;*/ + } + real_sum = W_add( W_shr( real_sum, guard_bits ), W_shr( imag_sum, guard_bits ) ); + rat_real_sum_q = sub( rat_real_sum_q, guard_bits ); + imag_sum = W_mult_32_32( prev_imag_fx[j], comp_fac_fx ); + rat_imag_sum_q = add( add( exp, sqrt_exp ), 1 ); + + IF( GT_16( rat_real_sum_q, rat_imag_sum_q ) ) + { + real_sum = W_shr( real_sum, sub( rat_real_sum_q, rat_imag_sum_q ) ); + rat_real_sum_q = rat_imag_sum_q; + } + ELSE + { + imag_sum = W_shr( imag_sum, sub( rat_imag_sum_q, rat_real_sum_q ) ); + /*sqrt_exp = rat_real_sum_q;*/ + } + real_sum = W_add( W_shr( real_sum, guard_bits ), W_shr( imag_sum, guard_bits ) ); + + lshift = W_norm( real_sum ); + rec_imag_fx[j] = W_extract_h( W_shl( real_sum, lshift ) ); + rec_imag_exp[j] = sub( add( sub( rat_real_sum_q, guard_bits ), lshift ), 32 ); + + abs_fac_powj_32 = Mpy_32_32( abs_fac_powj_32, abs_fac_32 ); + + + real_sum = W_mult_32_32( fac_powj_real_fx, fac_real_fx ); + rat_real_sum_q = add( add( fac_real_q, powj_real_q ), 1 ); + imag_sum = W_mult_32_32( fac_powj_imag_fx, fac_imag_fx ); + rat_imag_sum_q = add( add( fac_imag_q, powj_imag_q ), 1 ); + + IF( GT_16( rat_real_sum_q, rat_imag_sum_q ) ) + { + real_sum = W_shr( real_sum, sub( rat_real_sum_q, rat_imag_sum_q ) ); + rat_real_sum_q = rat_imag_sum_q; + } + ELSE + { + imag_sum = W_shr( imag_sum, sub( rat_imag_sum_q, rat_real_sum_q ) ); + /*sqrt_exp = rat_real_sum_q;*/ + } + real_sum = W_sub( W_shr( real_sum, guard_bits ), W_shr( imag_sum, guard_bits ) ); + // rat_real_sum_q = rat_real_sum_q - 1; + lshift = W_norm( real_sum ); + temp_32 = W_extract_h( W_shl( real_sum, lshift ) ); + temp_16 = sub( add( sub( rat_real_sum_q, guard_bits ), lshift ), 32 ); + + real_sum = W_mult_32_32( fac_powj_real_fx, fac_imag_fx ); + rat_real_sum_q = fac_imag_q + powj_real_q + 1; + imag_sum = W_mult_32_32( fac_powj_imag_fx, fac_real_fx ); + rat_imag_sum_q = fac_real_q + powj_imag_q + 1; + + IF( GT_16( rat_real_sum_q, rat_imag_sum_q ) ) + { + real_sum = W_shr( real_sum, sub( rat_real_sum_q, rat_imag_sum_q ) ); + rat_real_sum_q = rat_imag_sum_q; + } + ELSE + { + imag_sum = W_shr( imag_sum, sub( rat_imag_sum_q, rat_real_sum_q ) ); + /*sqrt_exp = rat_real_sum_q;*/ + } + real_sum = W_add( W_shr( real_sum, guard_bits ), W_shr( imag_sum, guard_bits ) ); + // rat_real_sum_q = rat_real_sum_q - 1; + lshift = W_norm( real_sum ); + fac_powj_imag_fx = W_extract_h( W_shl( real_sum, lshift ) ); + powj_imag_q = sub( add( sub( rat_real_sum_q, guard_bits ), lshift ), 32 ); + + fac_powj_real_fx = temp_32; + powj_real_q = temp_16; + } + + + /* prepare XF to next frame using prediction */ + fac_powj_real_fx = fac_real_fx; + fac_powj_imag_fx = fac_imag_fx; + powj_real_q = fac_real_q; + powj_imag_q = fac_imag_q; + abs_fac_powj_32 = abs_fac_32; // Q30 + sqrt_exp = 31; +#if CLDFB_PLC_XF > 0 + guard_bits = find_guarded_bits_fx( CLDFB_PLC_XF ); + FOR( j = 0; j < CLDFB_PLC_XF; j++ ) + { + + + xf_bet_fx[j] = L_sub( ONE_IN_Q31, abs_fac_powj_32 ); + real_sum = W_mult_32_32( rec_real_fx[iNumCols - 1], fac_powj_real_fx ); + rat_real_sum_q = add( add( rec_real_exp[iNumCols - 1], powj_real_q ), 1 ); + imag_sum = W_mult_32_32( rec_imag_fx[iNumCols - 1], fac_powj_imag_fx ); + rat_imag_sum_q = add( add( rec_imag_exp[iNumCols - 1], powj_imag_q ), 1 ); + IF( GT_16( rat_real_sum_q, rat_imag_sum_q ) ) + { + real_sum = W_shr( real_sum, sub( rat_real_sum_q, rat_imag_sum_q ) ); + rat_real_sum_q = rat_imag_sum_q; + } + ELSE + { + imag_sum = W_shr( imag_sum, sub( rat_imag_sum_q, rat_real_sum_q ) ); + /*sqrt_exp = rat_real_sum_q;*/ + } + real_sum = W_sub( W_shr( real_sum, guard_bits ), W_shr( imag_sum, guard_bits ) ); + rat_real_sum_q = sub( rat_real_sum_q, guard_bits ); + + lshift = W_norm( real_sum ); + rec_real_fx[j + iNumCols] = W_extract_h( W_shl( real_sum, lshift ) ); + rec_real_exp[j + iNumCols] = sub( add( rat_real_sum_q, lshift ), 32 ); + + real_sum = W_mult_32_32( rec_real_fx[iNumCols - 1], fac_powj_imag_fx ); + rat_real_sum_q = add( add( rec_real_exp[iNumCols - 1], powj_imag_q ), 1 ); + imag_sum = W_mult_32_32( rec_imag_fx[iNumCols - 1], fac_powj_real_fx ); + rat_imag_sum_q = add( add( rec_imag_exp[iNumCols - 1], powj_real_q ), 1 ); + IF( GT_16( rat_real_sum_q, rat_imag_sum_q ) ) + { + real_sum = W_shr( real_sum, sub( rat_real_sum_q, rat_imag_sum_q ) ); + rat_real_sum_q = rat_imag_sum_q; + } + ELSE + { + imag_sum = W_shr( imag_sum, sub( rat_imag_sum_q, rat_real_sum_q ) ); + /*sqrt_exp = rat_real_sum_q;*/ + } + real_sum = W_add( W_shr( real_sum, guard_bits ), W_shr( imag_sum, guard_bits ) ); + rat_real_sum_q = sub( rat_real_sum_q, guard_bits ); + + lshift = W_norm( real_sum ); + rec_imag_fx[j + iNumCols] = W_extract_h( W_shl( real_sum, lshift ) ); + rec_imag_exp[j + iNumCols] = sub( add( rat_real_sum_q, lshift ), 32 ); + + abs_fac_powj_32 = W_extract_h( W_mult_32_32( abs_fac_powj_32, abs_fac_32 ) ); // Q31 + + real_sum = W_mult_32_32( fac_powj_real_fx, fac_real_fx ); + rat_real_sum_q = add( add( fac_real_q, powj_real_q ), 1 ); + imag_sum = W_mult_32_32( fac_powj_imag_fx, fac_imag_fx ); + rat_imag_sum_q = add( add( fac_imag_q, powj_imag_q ), 1 ); + + IF( GT_16( rat_real_sum_q, rat_imag_sum_q ) ) + { + real_sum = W_shr( real_sum, sub( rat_real_sum_q, rat_imag_sum_q ) ); + rat_real_sum_q = rat_imag_sum_q; + } + ELSE + { + imag_sum = W_shr( imag_sum, sub( rat_imag_sum_q, rat_real_sum_q ) ); + } + real_sum = W_sub( W_shr( real_sum, guard_bits ), W_shr( imag_sum, guard_bits ) ); + lshift = W_norm( real_sum ); + temp_32 = W_extract_h( W_shl( real_sum, lshift ) ); + temp_16 = sub( add( sub( rat_real_sum_q, guard_bits ), lshift ), 32 ); + + real_sum = W_mult_32_32( fac_powj_real_fx, fac_imag_fx ); + rat_real_sum_q = add( add( fac_imag_q, powj_real_q ), 1 ); + imag_sum = W_mult_32_32( fac_powj_imag_fx, fac_real_fx ); + rat_imag_sum_q = add( add( fac_real_q, powj_imag_q ), 1 ); + + IF( GT_16( rat_real_sum_q, rat_imag_sum_q ) ) + { + real_sum = W_shr( real_sum, sub( rat_real_sum_q, rat_imag_sum_q ) ); + rat_real_sum_q = rat_imag_sum_q; + } + ELSE + { + imag_sum = W_shr( imag_sum, sub( rat_imag_sum_q, rat_real_sum_q ) ); + } + real_sum = W_add( W_shr( real_sum, guard_bits ), W_shr( imag_sum, guard_bits ) ); + lshift = W_norm( real_sum ); + fac_powj_imag_fx = W_extract_h( W_shl( real_sum, lshift ) ); + powj_imag_q = sub( add( sub( rat_real_sum_q, guard_bits ), lshift ), 32 ); + + fac_powj_real_fx = temp_32; + powj_real_q = temp_16; + } +#endif + } + } + ELSE + { + FOR( j = 0; j < iNumCols; j++ ) + { + rec_real_fx[j] = prev_real_fx[j]; + rec_real_exp[j] = exp; + rec_imag_fx[j] = prev_imag_fx[j]; + rec_imag_exp[j] = exp; + } +#if CLDFB_PLC_XF > 0 + FOR( j = 0; j < CLDFB_PLC_XF; j++ ) + { + xf_bet_fx[j] = ONE_IN_Q31; + rec_real_fx[j + iNumCols] = 0; + rec_real_exp[j + iNumCols] = 31; + rec_imag_fx[j + iNumCols] = 0; + rec_imag_exp[j + iNumCols] = 31; + } +#endif + } + return; +} +/*------------------------------------------------------------------------- + * Function isar_splitBinRendPLCOpen() + * + * + *------------------------------------------------------------------------*/ + +ivas_error isar_splitBinRendPLCOpen( + ISAR_SPLIT_REND_PLC_HANDLE *phSplitRendPLC, + Word16 iNumSubSets ) +{ + ivas_error error; + ISAR_SPLIT_REND_PLC_HANDLE hSplitRendPLC; + + error = IVAS_ERR_OK; + IF( ( hSplitRendPLC = (ISAR_SPLIT_REND_PLC_HANDLE) malloc( sizeof( ISAR_SPLIT_REND_PLC_STRUCT ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for bin split renderer PLC Module \n" ) ); + } + + hSplitRendPLC->prev_bfi = 0; + hSplitRendPLC->bf_count = 0; + hSplitRendPLC->iNumSubSets = iNumSubSets; + + set_l( &hSplitRendPLC->CldfbPLC_state.Cldfb_Prev_BinReal_fx[0][0][0], 0, 2 * ( CLDFB_NO_COL_MAX + CLDFB_PLC_XF ) * CLDFB_NO_CHANNELS_MAX ); + set_l( &hSplitRendPLC->CldfbPLC_state.Cldfb_Prev_BinImag_fx[0][0][0], 0, 2 * ( CLDFB_NO_COL_MAX + CLDFB_PLC_XF ) * CLDFB_NO_CHANNELS_MAX ); + + *phSplitRendPLC = hSplitRendPLC; + + return error; +} + +/*------------------------------------------------------------------------- + * Function isar_splitBinRendPLCClose() + * + * + *------------------------------------------------------------------------*/ + +void isar_splitBinRendPLCClose( + ISAR_SPLIT_REND_PLC_HANDLE *phSplitRendPLC ) +{ + if ( ( *phSplitRendPLC ) != NULL ) + { + free( ( *phSplitRendPLC ) ); + ( *phSplitRendPLC ) = NULL; + } + + return; +} + + +/*------------------------------------------------------------------------- + * Function isar_splitBinRendPLCsaveState() + * + * + *------------------------------------------------------------------------*/ + +void isar_splitBinRendPLCsaveState( + ISAR_SPLIT_REND_PLC_HANDLE hSplitRendPLC, + Word32 Cldfb_RealBuffer_Binaural_fx[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + Word32 Cldfb_ImagBuffer_Binaural_fx[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + const Word16 num_chs, + const Word16 iNumBlocks, + const Word16 iNumIterations ) +{ + Word16 k, n; + + /* Save Cldfb frame */ + FOR( k = 0; k < ( iNumBlocks * iNumIterations ); k++ ) + { + FOR( n = 0; n < num_chs; n++ ) + { + mvl2l( &Cldfb_RealBuffer_Binaural_fx[n][k][0], &hSplitRendPLC->CldfbPLC_state.Cldfb_Prev_BinReal_fx[n][k][0], CLDFB_NO_CHANNELS_MAX ); + mvl2l( &Cldfb_ImagBuffer_Binaural_fx[n][k][0], &hSplitRendPLC->CldfbPLC_state.Cldfb_Prev_BinImag_fx[n][k][0], CLDFB_NO_CHANNELS_MAX ); + } + } + + return; +} + + +/*------------------------------------------------------------------------- + * Function isar_splitBinRendPLC_xf() + * + * Cross-fade of preceding bad frame into good frame + *------------------------------------------------------------------------*/ + +void isar_splitBinRendPLC_xf_fx( + ISAR_SPLIT_REND_PLC_HANDLE hSplitRendPLC, + Word32 Cldfb_RealBuffer_Binaural_fx[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + Word32 Cldfb_ImagBuffer_Binaural_fx[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + const Word16 num_chs, + const Word16 iNumBlocks, + const Word16 iNumIterations, + Word32 **ppiDecodingFailed, + Word32 **ppiDecodingFailedPrev, + Word16 exp ) +{ + Word16 n, i, k; + /* Indicate that next transition will be from a good frame */ + hSplitRendPLC->prev_bfi = 0; + move16(); + + /* Reset bf conter */ + hSplitRendPLC->bf_count = 0; + move16(); + + /* Do the cross fade */ + FOR( n = 0; n < num_chs; n++ ) + { + FOR( i = 0; i < CLDFB_NO_CHANNELS_MAX; i++ ) + { + Word32 iSubSet = i % hSplitRendPLC->iNumSubSets; + test(); + IF( EQ_32( ppiDecodingFailedPrev[n][iSubSet], 1 ) && EQ_32( ppiDecodingFailed[n][iSubSet], 0 ) ) + { +#if CLDFB_PLC_XF > 0 + FOR( k = 0; k < CLDFB_PLC_XF; k++ ) + { + Word32 L_tmp; + Word64 W_tmp; + Word16 shift; + W_tmp = W_shr( W_mult_32_32( hSplitRendPLC->CldfbPLC_state.xf_bet_fx[n][i][k], Cldfb_RealBuffer_Binaural_fx[n][k][i] ), 1 ); + W_tmp = W_add( W_tmp, W_shl( L_shl_r( hSplitRendPLC->CldfbPLC_state.Cldfb_Prev_BinReal_fx[n][k + ( iNumBlocks * iNumIterations )][i], exp - hSplitRendPLC->CldfbPLC_state.Q_Prev_Bin_fx ), 31 ) ); + + shift = W_norm( W_tmp ); + W_tmp = W_shl( W_tmp, shift ); + L_tmp = W_extract_h( W_tmp ); + L_tmp = L_shr( L_tmp, 31 + shift - 32 ); + Cldfb_RealBuffer_Binaural_fx[n][k][i] = L_tmp; + + W_tmp = W_shr( W_mult_32_32( hSplitRendPLC->CldfbPLC_state.xf_bet_fx[n][i][k], Cldfb_ImagBuffer_Binaural_fx[n][k][i] ), 1 ); + W_tmp = W_add( W_tmp, W_shl( L_shl_r( hSplitRendPLC->CldfbPLC_state.Cldfb_Prev_BinImag_fx[n][k + ( iNumBlocks * iNumIterations )][i], exp - hSplitRendPLC->CldfbPLC_state.Q_Prev_Bin_fx ), 31 ) ); + + shift = W_norm( W_tmp ); + W_tmp = W_shl( W_tmp, shift ); + L_tmp = W_extract_h( W_tmp ); + L_tmp = L_shr( L_tmp, 31 + shift - 32 ); + Cldfb_ImagBuffer_Binaural_fx[n][k][i] = L_tmp; + } +#endif + } + } + } + + return; +} + + +/*------------------------------------------------------------------------- + * Function isar_splitBinRendPLC() + * + * Conceal bad frame + *------------------------------------------------------------------------*/ +void isar_splitBinRendPLC( + ISAR_SPLIT_REND_PLC_HANDLE hSplitRendPLC, + Word32 Cldfb_RealBuffer_Binaural_fx[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + Word32 Cldfb_ImagBuffer_Binaural_fx[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + const Word16 num_chs, + const Word16 iNumBlocks, + const Word16 iNumIterations, + int32_t **ppiDecodingFailed, + Word16 exp ) +{ + Word32 i, n, k; + Word32 temp_32, fade_fac_fx; + Word16 div_exp = 0, tmp, exp_fade, frac; + Word32 prev_real_fx[CLDFB_NO_COL_MAX], prev_imag_fx[CLDFB_NO_COL_MAX], rec_real_fx[CLDFB_NO_COL_MAX + CLDFB_PLC_XF], rec_imag_fx[CLDFB_NO_COL_MAX + CLDFB_PLC_XF]; + Word16 rec_real_exp[CLDFB_NO_COL_MAX + CLDFB_PLC_XF], rec_imag_exp[CLDFB_NO_COL_MAX + CLDFB_PLC_XF]; +#if CLDFB_PLC_XF > 0 + Word32 xf_alp_fx[CLDFB_PLC_XF]; +#endif + Word16 iNumCols, fade_start_cntr, mute_cntr, fade_val; + + iNumCols = extract_l( L_mult0( iNumBlocks, iNumIterations ) ); + + /* Indicate that next transition will be from a bad frame */ + hSplitRendPLC->prev_bfi = 1; + + +#if CLDFB_PLC_XF > 0 + FOR( i = 0; i < CLDFB_PLC_XF; i++ ) + { + xf_alp_fx[i] = xf_alp_tab[i]; + } +#endif + Word16 exp1 = exp; + + FOR( n = 0; n < num_chs; n++ ) + { + FOR( i = 0; i < CLDFB_NO_CHANNELS_MAX; i++ ) + { + Word32 iSubSet = i % hSplitRendPLC->iNumSubSets; + FOR( k = 0; k < iNumCols; k++ ) + { + prev_real_fx[k] = L_shl_r( hSplitRendPLC->CldfbPLC_state.Cldfb_Prev_BinReal_fx[n][k][i], exp - hSplitRendPLC->CldfbPLC_state.Q_Prev_Bin_fx ); + prev_imag_fx[k] = L_shl_r( hSplitRendPLC->CldfbPLC_state.Cldfb_Prev_BinImag_fx[n][k][i], exp - hSplitRendPLC->CldfbPLC_state.Q_Prev_Bin_fx ); + } + adaptive_polar_ext_plc_fx( + prev_real_fx, prev_imag_fx, rec_real_fx, rec_imag_fx, + rec_real_exp, rec_imag_exp +#if CLDFB_PLC_XF > 0 + , + xf_alp_fx, hSplitRendPLC->CldfbPLC_state.xf_bet_fx[n][i], +#endif + exp, + iNumCols ); + + Word16 temp16; + + FOR( k = 0; k < iNumCols; k++ ) + { + temp16 = sub( rec_real_exp[k], exp1 ); + rec_real_fx[k] = L_shr_r_sat( rec_real_fx[k], temp16 ); + rec_real_exp[k] = sub( rec_real_exp[k], temp16 ); + + temp16 = sub( rec_imag_exp[k], exp1 ); + rec_imag_fx[k] = L_shr_r_sat( rec_imag_fx[k], temp16 ); + rec_imag_exp[k] = sub( rec_imag_exp[k], temp16 ); + // Cldfb_RealBuffer_Binaural_fx[n][k][i] = rec_real_fx[k]; + hSplitRendPLC->CldfbPLC_state.Cldfb_Prev_BinReal_fx[n][k][i] = rec_real_fx[k]; // exp + // Cldfb_ImagBuffer_Binaural_fx[n][k][i] = rec_imag_fx[k] ; + hSplitRendPLC->CldfbPLC_state.Cldfb_Prev_BinImag_fx[n][k][i] = rec_imag_fx[k]; // exp + if ( ppiDecodingFailed[n][iSubSet] == 1 ) + { /* only then copy to output */ + Cldfb_RealBuffer_Binaural_fx[n][k][i] = rec_real_fx[k]; + Cldfb_ImagBuffer_Binaural_fx[n][k][i] = rec_imag_fx[k]; + } + } + +#if CLDFB_PLC_XF > 0 + FOR( k = iNumCols; k < iNumCols + CLDFB_PLC_XF; k++ ) + { + + temp16 = sub( rec_real_exp[k], exp1 ); + rec_real_fx[k] = L_shr_r_sat( rec_real_fx[k], temp16 ); + rec_real_exp[k] = sub( rec_real_exp[k], temp16 ); + + temp16 = sub( rec_imag_exp[k], exp1 ); + rec_imag_fx[k] = L_shr_r_sat( rec_imag_fx[k], temp16 ); + rec_imag_exp[k] = sub( rec_imag_exp[k], temp16 ); + /*TODO: Will remove the inter conversion later*/ + hSplitRendPLC->CldfbPLC_state.Cldfb_Prev_BinReal_fx[n][k][i] = rec_real_fx[k]; // exp + hSplitRendPLC->CldfbPLC_state.Cldfb_Prev_BinImag_fx[n][k][i] = rec_imag_fx[k]; // exp + } +#endif + } + } + + + /* Check bf counter */ + tmp = BASOP_Util_Divide1616_Scale( PLC_FADE_CNST, iNumCols, &div_exp ); + fade_start_cntr = shr( tmp, ( 15 - div_exp ) ); + tmp = BASOP_Util_Divide1616_Scale( PLC_MUTE_CNST, iNumCols, &div_exp ); + mute_cntr = shr( tmp, ( 15 - div_exp ) ); + + IF( GE_16( hSplitRendPLC->bf_count++, fade_start_cntr ) ) + { + IF( LT_16( hSplitRendPLC->bf_count, mute_cntr ) ) + { + fade_val = extract_l( L_shr( L_mult0( sub( hSplitRendPLC->bf_count, fade_start_cntr ), iNumCols ), 4 ) ); // Q0 + temp_32 = L_mult( -16328, fade_val ); // Q15 + temp_32 = L_shl( temp_32, 1 ); // Q16 + + frac = L_Extract_lc( temp_32, &exp_fade ); /* Extract exponent of temp_32 */ + fade_fac_fx = Pow2( 14, frac ); /* Put 14 as exponent so that */ + exp_fade = 31 - add( sub( exp_fade, 14 ), 16 ); + fade_fac_fx = L_shl( fade_fac_fx, 31 - exp_fade ); // Q31 + + FOR( n = 0; n < num_chs; n++ ) + { + FOR( k = 0; k < iNumCols; k++ ) + { + v_multc_fixed( &Cldfb_RealBuffer_Binaural_fx[n][k][0], fade_fac_fx, &Cldfb_RealBuffer_Binaural_fx[n][k][0], (int16_t) CLDFB_NO_CHANNELS_MAX ); + v_multc_fixed( &Cldfb_ImagBuffer_Binaural_fx[n][k][0], fade_fac_fx, &Cldfb_ImagBuffer_Binaural_fx[n][k][0], (int16_t) CLDFB_NO_CHANNELS_MAX ); + } + } + } + ELSE + { + FOR( n = 0; n < num_chs; n++ ) + { + FOR( k = 0; k < iNumCols; k++ ) + { + set_val_Word32( &Cldfb_RealBuffer_Binaural_fx[n][k][0], 0, (int16_t) CLDFB_NO_CHANNELS_MAX ); + set_val_Word32( &Cldfb_ImagBuffer_Binaural_fx[n][k][0], 0, (int16_t) CLDFB_NO_CHANNELS_MAX ); + } + } + hSplitRendPLC->bf_count = mute_cntr; + } + } + + return; +} +#endif diff --git a/lib_isar/isar_splitRendererPost.c b/lib_isar/isar_splitRendererPost.c new file mode 100644 index 0000000000000000000000000000000000000000..ac04868328d22f9d0c84fb5b4edc0616ae2d287b --- /dev/null +++ b/lib_isar/isar_splitRendererPost.c @@ -0,0 +1,2136 @@ +/****************************************************************************************************** + + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository. All Rights Reserved. + + This software is protected by copyright law and by international treaties. + The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository retain full ownership rights in their respective contributions in + the software. This notice grants no license of any kind, including but not limited to patent + license, nor is any license granted by implication, estoppel or otherwise. + + Contributors are required to enter into the IVAS codec Public Collaboration agreement before making + contributions. + + This software is provided "AS IS", without any express or implied warranties. The software is in the + development stage. It is intended exclusively for experts who have experience with such software and + solely for the purpose of inspection. All implied warranties of non-infringement, merchantability + and fitness for a particular purpose are hereby disclaimed and excluded. + + Any dispute, controversy or claim arising under or in relation to providing this software shall be + submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in + accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and + the United Nations Convention on Contracts on the International Sales of Goods. + +*******************************************************************************************************/ + +#include +#include "options.h" +#ifdef SPLIT_REND_WITH_HEAD_ROT +#include +#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG +#include +#endif +#include "ivas_prot_fx.h" +#include "prot_fx.h" +#include "isar_rom_post_rend.h" +#include "isar_prot.h" +#ifdef DEBUGGING +#include "debug.h" +#endif +#include "prot_fx.h" +#include "wmc_auto.h" +#include "basop_util.h" +#define Q31_BY_360 ( 5965232 ) // Q31 + + +/*------------------------------------------------------------------------- + * isar_splitBinPostRendOpen() + * + * + *------------------------------------------------------------------------*/ +ivas_error isar_splitBinPostRendOpen( + ISAR_BIN_HR_SPLIT_POST_REND_HANDLE *hBinHrSplitPostRend, + MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, + const Word32 output_Fs ) +{ + ISAR_BIN_HR_SPLIT_POST_REND_HANDLE hBinRend; + ivas_error error; + Word16 ch; + + IF( ( hBinRend = (ISAR_BIN_HR_SPLIT_POST_REND_HANDLE) malloc( sizeof( ISAR_BIN_HR_SPLIT_POST_REND ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for bin split post renderer Module \n" ) ); + } + + FOR( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) + { + hBinRend->cldfbSyn[ch] = NULL; + hBinRend->cldfbAna[ch] = NULL; + } +#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG + for ( int16_t i = 0; i < MAX_HEAD_ROT_POSES; i++ ) + { + for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) + { + hBinRend->cldfbSynReconsBinDec[i][ch] = NULL; + } + } +#endif + + FOR( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) + { + IF( ( error = openCldfb_ivas_fx( &( hBinRend->cldfbSyn[ch] ), CLDFB_SYNTHESIS, output_Fs, CLDFB_PROTOTYPE_5_00MS, DEC ) ) != IVAS_ERR_OK ) + { + return error; + } + IF( ( error = openCldfb_ivas_fx( &( hBinRend->cldfbAna[ch] ), CLDFB_ANALYSIS, output_Fs, CLDFB_PROTOTYPE_5_00MS, DEC ) ) != IVAS_ERR_OK ) + { + return error; + } + } + +#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG + for ( int16_t i = 0; i < MAX_HEAD_ROT_POSES; i++ ) + { + for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) + { + if ( ( error = openCldfb( &( hBinRend->cldfbSynReconsBinDec[i][ch] ), CLDFB_SYNTHESIS, output_Fs, CLDFB_PROTOTYPE_5_00MS, DEC ) ) != IVAS_ERR_OK ) + { + return error; + } + } + } +#endif + hBinRend->cf_flag = 0; + set_fix_rotation_mat_fx( hBinRend->fix_pos_rot_mat_fx, pMultiBinPoseData ); + set_pose_types_fx( hBinRend->pose_type, pMultiBinPoseData ); + isar_split_rend_init_huff_cfg( &hBinRend->huff_cfg ); + *hBinHrSplitPostRend = hBinRend; + + return IVAS_ERR_OK; +} + +/*------------------------------------------------------------------------- + * isar_splitBinPostRendClose() + * + * + *------------------------------------------------------------------------*/ + +void isar_splitBinPostRendClose( + ISAR_BIN_HR_SPLIT_POST_REND_HANDLE *hBinHrSplitPostRend ) +{ + Word16 ch; + + IF( ( *hBinHrSplitPostRend ) != NULL ) + { + FOR( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) + { + IF( ( *hBinHrSplitPostRend )->cldfbSyn[ch] != NULL ) + { + deleteCldfb_ivas_fx( &( ( *hBinHrSplitPostRend )->cldfbSyn[ch] ) ); + ( *hBinHrSplitPostRend )->cldfbSyn[ch] = NULL; + } + IF( ( *hBinHrSplitPostRend )->cldfbAna[ch] != NULL ) + { + deleteCldfb_ivas_fx( &( ( *hBinHrSplitPostRend )->cldfbAna[ch] ) ); + ( *hBinHrSplitPostRend )->cldfbAna[ch] = NULL; + } + } +#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG + for ( int16_t i = 0; i < MAX_HEAD_ROT_POSES; i++ ) + { + for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) + { + if ( ( *hBinHrSplitPostRend )->cldfbSynReconsBinDec[i][ch] != NULL ) + { + deleteCldfb( &( ( *hBinHrSplitPostRend )->cldfbSynReconsBinDec[i][ch] ) ); + ( *hBinHrSplitPostRend )->cldfbSynReconsBinDec[i][ch] = NULL; + } + } + } +#endif + + free( ( *hBinHrSplitPostRend ) ); + ( *hBinHrSplitPostRend ) = NULL; + } + + return; +} + +/*-----------------------------------------------------------------------------------------* + * Function ivas_split_rend_huffman_decode_opt() + * + * + *-----------------------------------------------------------------------------------------*/ + +static Word16 ivas_split_rend_huffman_decode_opt( + isar_split_rend_huffman_cfg_t *huff_cfg, + ISAR_SPLIT_REND_BITS_HANDLE pBits, + const Word16 *idx_trav_list ) +{ + Word32 i, ind, code, num_bits, code_b, num_bits_read; + const Word32 *codebook; + + codebook = huff_cfg->codebook; + num_bits_read = 0; + move32(); + ind = L_sub( huff_cfg->codebook[0], 1 ); + code = 0; + move32(); + FOR( i = 0; i < huff_cfg->sym_len; i++ ) + { + codebook = codebook + idx_trav_list[i] * 3; + num_bits = codebook[1]; + move32(); + code_b = codebook[2]; + move32(); + num_bits_read = L_sub( num_bits, num_bits_read ); + code = L_shl( code, extract_l( num_bits_read ) ); + IF( GT_32( num_bits_read, 0 ) ) + { + code = L_or( code, ISAR_SPLIT_REND_BITStream_read_int32( pBits, num_bits_read ) ); + } + + IF( EQ_32( code, code_b ) ) + { + ind = codebook[0]; + move32(); + BREAK; + } + + num_bits_read = num_bits; + move32(); + codebook = huff_cfg->codebook; + } + +#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG + assert( ind >= huff_cfg->codebook[0] ); +#endif + return extract_l( ind ); +} + +/*-----------------------------------------------------------------------------------------* + * Function ivas_split_rend_unquant_md() + * + * + *-----------------------------------------------------------------------------------------*/ + +static void ivas_split_rend_unquant_md_fx( + ISAR_BIN_HR_SPLIT_REND_MD_HANDLE hMd, + ISAR_SPLIT_REND_POSE_TYPE pose_type, + Word16 real_only, + Word32 fix_pos_rot_mat[][BINAURAL_CHANNELS], + const Word32 pred_quant_step ) +{ + Word16 ch1, ch2; + Word16 gd_idx_min; + + test(); + IF( EQ_32( pose_type, PRED_ONLY ) || EQ_32( pose_type, PRED_ROLL_ONLY ) ) + { + Word32 quantstep; + + quantstep = pred_quant_step; + move32(); +#ifndef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS + FOR( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + { + FOR( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) + { + hMd->pred_mat_re_fx[ch1][ch2] = Mpy_32_16_1( quantstep, extract_l( L_shl( hMd->pred_mat_re_idx[ch1][ch2], Q9 ) ) ); /* Q25 */ + move32(); + hMd->pred_mat_re_fx[ch1][ch2] = L_add( hMd->pred_mat_re_fx[ch1][ch2], L_shr( fix_pos_rot_mat[ch1][ch2], Q6 ) ); /* Q25 */ + move32(); + } + } +#endif + + IF( real_only ) + { +#ifdef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS + FOR( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + { + FOR( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) + { + hMd->pred_mat_re_fx[ch1][ch2] = Mpy_32_16_1( quantstep, extract_l( L_shl( hMd->pred_mat_re_idx[ch1][ch2], Q9 ) ) ); /* Q25 */ + move32(); + hMd->pred_mat_re_fx[ch1][ch2] = L_add( hMd->pred_mat_re_fx[ch1][ch2], L_shr( ( ch1 == ch2 ) ? ONE_IN_Q31 : 0, Q6 ) ); /* Q25 */ + move32(); + } + } +#endif + + FOR( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + { + FOR( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) + { + hMd->pred_mat_im_fx[ch1][ch2] = 0; /* Q25 */ + move32(); + } + } + } + ELSE + { +#ifdef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS + FOR( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + { + FOR( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) + { + hMd->pred_mat_re_fx[ch1][ch2] = Mpy_32_16_1( quantstep, extract_l( L_shl( hMd->pred_mat_re_idx[ch1][ch2], Q9 ) ) ); /* Q25 */ + move32(); + hMd->pred_mat_re_fx[ch1][ch2] = L_add( hMd->pred_mat_re_fx[ch1][ch2], L_shr( fix_pos_rot_mat[ch1][ch2], Q6 ) ); /* Q25 */ + move32(); + } + } +#endif + + FOR( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + { + FOR( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) + { + hMd->pred_mat_im_fx[ch1][ch2] = Mpy_32_16_1( quantstep, extract_l( L_shl( hMd->pred_mat_im_idx[ch1][ch2], Q9 ) ) ); /* Q25 */ + move32(); + } + } + } + } + ELSE IF( EQ_32( pose_type, COM_GAIN_ONLY ) ) + { + gd_idx_min = 0; + move16(); + hMd->gd_idx = add( hMd->gd_idx, gd_idx_min ); + hMd->gd_fx = Mpy_32_16_1( ISAR_SPLIT_REND_D_Q_STEP_Q31, extract_l( L_shl( hMd->gd_idx, Q9 ) ) ); /* Q25 */ + } + ELSE IF( EQ_32( pose_type, LR_GAIN_ONLY ) ) + { + gd_idx_min = 7; + move16(); + hMd->gd_idx = add( hMd->gd_idx, gd_idx_min ); + hMd->gd_fx = Mpy_32_16_1( ISAR_SPLIT_REND_PITCH_G_Q_STEP_Q31, extract_l( L_shl( hMd->gd_idx, Q9 ) ) ); /* Q25 */ + + hMd->gd2_idx = add( hMd->gd2_idx, gd_idx_min ); + hMd->gd2_fx = Mpy_32_16_1( ISAR_SPLIT_REND_PITCH_G_Q_STEP_Q31, extract_l( L_shl( hMd->gd2_idx, Q9 ) ) ); /* Q25 */ + } + ELSE + { + hMd->gd_fx = 0; /* Q25 */ + move32(); + } + + return; +} + +/*-----------------------------------------------------------------------------------------* + * Function isar_splitBinPostRendMdBase2Dec() + * + * + *-----------------------------------------------------------------------------------------*/ + +static void isar_splitBinPostRendMdBase2Dec( + ISAR_SPLIT_REND_BITS_HANDLE pBits, + ISAR_BIN_HR_SPLIT_POST_REND_HANDLE hBinHrSplitPostRend, + MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, + const Word16 num_subframes, + const Word16 pred_real_bands_yaw, + const Word16 pred_imag_bands_yaw, + const Word16 pred_quant_pnts_yaw, + const Word16 d_bands_yaw, + const Word16 bands_pitch, + const Word16 pred_real_bands_roll, + const Word16 pred_imag_bands_roll ) +{ + Word16 sf_idx, pos_idx, b, ch1, ch2; + Word16 min_pred_idx, min_gd_idx, min_p_gd_idx, pred_code_len, gd_code_len, p_gd_code_len; + Word16 min_pred_roll_idx, pred_roll_code_len; + Word16 pred_cb_idx; + Word16 code; + ISAR_BIN_HR_SPLIT_REND_MD_HANDLE hMd; + ISAR_BIN_HR_SPLIT_REND_HUFF_HANDLE pHuff_cfg; + + pHuff_cfg = &hBinHrSplitPostRend->huff_cfg; + + IF( EQ_16( pred_quant_pnts_yaw, ISAR_SPLIT_REND_PRED_63QUANT_PNTS ) ) + { + pred_cb_idx = 1; + move16(); + } + ELSE + { + pred_cb_idx = 0; + move16(); + } + min_pred_idx = extract_l( pHuff_cfg->pred[pred_cb_idx].codebook[0] ); + min_pred_roll_idx = extract_l( pHuff_cfg->pred_roll.codebook[0] ); + min_gd_idx = extract_l( pHuff_cfg->gd.codebook[0] ); + min_p_gd_idx = extract_l( pHuff_cfg->p_gd.codebook[0] ); + pred_code_len = pHuff_cfg->pred_base2_code_len[pred_cb_idx]; + move16(); + pred_roll_code_len = pHuff_cfg->pred_roll_base2_code_len; + move16(); + gd_code_len = pHuff_cfg->gd_base2_code_len; + move16(); + p_gd_code_len = pHuff_cfg->p_gd_base2_code_len; + move16(); + + FOR( sf_idx = 0; sf_idx < num_subframes; sf_idx++ ) + { + FOR( pos_idx = 0; pos_idx < sub( pMultiBinPoseData->num_poses, 1 ); pos_idx++ ) + { + IF( EQ_32( hBinHrSplitPostRend->pose_type[pos_idx], ANY_YAW ) ) + { +#ifndef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS + FOR( b = 0; b < pred_real_bands_yaw; b++ ) + { + hMd = &hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b]; + FOR( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + { + FOR( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) + { + code = extract_l( ISAR_SPLIT_REND_BITStream_read_int32( pBits, pred_code_len ) ); + hMd->pred_mat_re_idx[ch1][ch2] = add( code, min_pred_idx ); + move16(); + } + } + } + FOR( b = 0; b < pred_imag_bands_yaw; b++ ) + { + hMd = &hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b]; + FOR( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + { + FOR( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) + { + code = extract_l( ISAR_SPLIT_REND_BITStream_read_int32( pBits, pred_code_len ) ); + hMd->pred_mat_im_idx[ch1][ch2] = add( code, min_pred_idx ); + move16(); + } + } + } +#else + FOR( b = 0; b < pred_imag_bands_yaw; b++ ) + { + hMd = &hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b]; + FOR( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + { + FOR( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) + { + code = extract_l( ISAR_SPLIT_REND_BITStream_read_int32( pBits, pred_code_len ) ); + hMd->pred_mat_re_idx[ch1][ch2] = add( code, min_pred_idx ); + move16(); + } + } + + FOR( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + { + FOR( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) + { + code = extract_l( ISAR_SPLIT_REND_BITStream_read_int32( pBits, pred_code_len ) ); + hMd->pred_mat_im_idx[ch1][ch2] = add( code, min_pred_idx ); + move16(); + } + } + } + FOR( ; b < pred_real_bands_yaw; b++ ) + { + hMd = &hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b]; + FOR( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + { + code = extract_l( ISAR_SPLIT_REND_BITStream_read_int32( pBits, pred_code_len ) ); + hMd->pred_mat_re_idx[ch1][ch1] = add( code, min_pred_idx ); + move16(); + } + hMd->pred_mat_re_idx[0][1] = 0; + move16(); + hMd->pred_mat_re_idx[1][0] = 0; + move16(); + } +#endif + FOR( b = 0; b < d_bands_yaw; b++ ) + { + hMd = &hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b]; + code = extract_l( ISAR_SPLIT_REND_BITStream_read_int32( pBits, gd_code_len ) ); + hMd->gd_idx = add( code, min_gd_idx ); + move16(); + } + } + ELSE IF( EQ_32( hBinHrSplitPostRend->pose_type[pos_idx], PITCH_ONLY ) ) + { + FOR( b = 0; b < bands_pitch; b++ ) + { + hMd = &hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b]; + code = extract_l( ISAR_SPLIT_REND_BITStream_read_int32( pBits, p_gd_code_len ) ); + hMd->gd_idx = add( code, min_p_gd_idx ); + move16(); + code = extract_l( ISAR_SPLIT_REND_BITStream_read_int32( pBits, p_gd_code_len ) ); + hMd->gd2_idx = add( code, min_p_gd_idx ); + move16(); + } + } + ELSE + { +#ifndef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS + FOR( b = 0; b < pred_real_bands_roll; b++ ) + { + hMd = &hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b]; + FOR( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + { + FOR( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) + { + code = extract_l( ISAR_SPLIT_REND_BITStream_read_int32( pBits, pred_roll_code_len ) ); + hMd->pred_mat_re_idx[ch1][ch2] = add( code, min_pred_roll_idx ); + move16(); + } + } + } + FOR( b = 0; b < pred_imag_bands_roll; b++ ) + { + hMd = &hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b]; + FOR( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + { + FOR( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) + { + code = extract_l( ISAR_SPLIT_REND_BITStream_read_int32( pBits, pred_roll_code_len ) ); + hMd->pred_mat_im_idx[ch1][ch2] = add( code, min_pred_roll_idx ); + move16(); + } + } + } +#else + FOR( b = 0; b < pred_imag_bands_roll; b++ ) + { + hMd = &hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b]; + FOR( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + { + FOR( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) + { + code = extract_l( ISAR_SPLIT_REND_BITStream_read_int32( pBits, pred_roll_code_len ) ); + hMd->pred_mat_re_idx[ch1][ch2] = add( code, min_pred_roll_idx ); + move16(); + } + } + + FOR( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + { + FOR( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) + { + code = extract_l( ISAR_SPLIT_REND_BITStream_read_int32( pBits, pred_roll_code_len ) ); + hMd->pred_mat_im_idx[ch1][ch2] = add( code, min_pred_roll_idx ); + move16(); + } + } + } + FOR( ; b < pred_real_bands_roll; b++ ) + { + hMd = &hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b]; + FOR( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + { + code = extract_l( ISAR_SPLIT_REND_BITStream_read_int32( pBits, pred_roll_code_len ) ); + hMd->pred_mat_re_idx[ch1][ch1] = add( code, min_pred_roll_idx ); + move16(); + } + hMd->pred_mat_re_idx[0][1] = 0; + move16(); + hMd->pred_mat_re_idx[1][0] = 0; + move16(); + } +#endif + } + } + } + + return; +} + + +/*-----------------------------------------------------------------------------------------* + * Function ivas_splitBinPostRendMdHuffDec() + * + * + *-----------------------------------------------------------------------------------------*/ + +static void ivas_splitBinPostRendMdHuffDec( + ISAR_SPLIT_REND_BITS_HANDLE pBits, + ISAR_BIN_HR_SPLIT_POST_REND_HANDLE hBinHrSplitPostRend, + MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, + const Word16 num_subframes, + const Word16 pred_real_bands_yaw, + const Word16 pred_imag_bands_yaw, + const Word16 pred_quant_pnts_yaw, + const Word16 d_bands_yaw, + const Word16 bands_pitch, + const Word16 pred_real_bands_roll, + const Word16 pred_imag_bands_roll ) +{ + Word16 pos_idx, b, sf_idx; + Word16 ch1, ch2; + Word16 sym_adj_idx[BINAURAL_CHANNELS][BINAURAL_CHANNELS]; + Word16 min_pred_idx, max_pred_idx; + Word16 min_pred_roll_idx, max_pred_roll_idx, pred_cb_idx; + ISAR_BIN_HR_SPLIT_REND_MD_HANDLE hMd; + ISAR_BIN_HR_SPLIT_REND_HUFF_HANDLE pHuff_cfg; + + pHuff_cfg = &hBinHrSplitPostRend->huff_cfg; + + IF( EQ_16( pred_quant_pnts_yaw, ISAR_SPLIT_REND_PRED_63QUANT_PNTS ) ) + { + pred_cb_idx = 1; + move16(); + } + ELSE + { + pred_cb_idx = 0; + move16(); + } + min_pred_idx = extract_l( pHuff_cfg->pred[pred_cb_idx].codebook[0] ); + max_pred_idx = extract_l( pHuff_cfg->pred[pred_cb_idx].codebook[( pred_quant_pnts_yaw - 1 ) * 3] ); + + min_pred_roll_idx = extract_l( pHuff_cfg->pred_roll.codebook[0] ); + max_pred_roll_idx = extract_l( pHuff_cfg->pred_roll.codebook[( ISAR_SPLIT_REND_ROLL_PRED_QUANT_PNTS - 1 ) * 3] ); + + FOR( sf_idx = 0; sf_idx < num_subframes; sf_idx++ ) + { + FOR( pos_idx = 0; pos_idx < sub( pMultiBinPoseData->num_poses, 1 ); pos_idx++ ) + { + IF( EQ_32( hBinHrSplitPostRend->pose_type[pos_idx], ANY_YAW ) ) + { +#ifndef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS + FOR( b = 0; b < pred_real_bands_yaw; b++ ) + { + hMd = &hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b]; + FOR( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + { + FOR( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) + { + sym_adj_idx[ch1][ch2] = ivas_split_rend_huffman_decode_opt( &pHuff_cfg->pred[pred_cb_idx], pBits, pHuff_cfg->pred_idx_trav[pred_cb_idx] ); + move16(); + // sym_adj_idx[ch1][ch2] = ivas_split_rend_huffman_decode( &pHuff_cfg->pred, pBits ); + } + } + isar_SplitRenderer_getdiagdiff( sym_adj_idx, hMd->pred_mat_re_idx, 1, min_pred_idx, max_pred_idx ); + } + FOR( b = 0; b < pred_imag_bands_yaw; b++ ) + { + hMd = &hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b]; + FOR( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + { + FOR( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) + { + sym_adj_idx[ch1][ch2] = ivas_split_rend_huffman_decode_opt( &pHuff_cfg->pred[pred_cb_idx], pBits, pHuff_cfg->pred_idx_trav[pred_cb_idx] ); + move16(); + // sym_adj_idx[ch1][ch2] = ivas_split_rend_huffman_decode( &pHuff_cfg->pred, pBits ); + } + } + isar_SplitRenderer_getdiagdiff( sym_adj_idx, hMd->pred_mat_im_idx, -1, min_pred_idx, max_pred_idx ); + } +#else + FOR( b = 0; b < pred_imag_bands_yaw; b++ ) + { + hMd = &hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b]; + FOR( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + { + FOR( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) + { + sym_adj_idx[ch1][ch2] = ivas_split_rend_huffman_decode_opt( &pHuff_cfg->pred[pred_cb_idx], pBits, pHuff_cfg->pred_idx_trav[pred_cb_idx] ); + move16(); + // sym_adj_idx[ch1][ch2] = ivas_split_rend_huffman_decode( &pHuff_cfg->pred, pBits ); + } + } + isar_SplitRenderer_getdiagdiff( sym_adj_idx, hMd->pred_mat_re_idx, 1, min_pred_idx, max_pred_idx ); + + FOR( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + { + FOR( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) + { + sym_adj_idx[ch1][ch2] = ivas_split_rend_huffman_decode_opt( &pHuff_cfg->pred[pred_cb_idx], pBits, pHuff_cfg->pred_idx_trav[pred_cb_idx] ); + move16(); + // sym_adj_idx[ch1][ch2] = ivas_split_rend_huffman_decode( &pHuff_cfg->pred, pBits ); + } + } + isar_SplitRenderer_getdiagdiff( sym_adj_idx, hMd->pred_mat_im_idx, -1, min_pred_idx, max_pred_idx ); + } + FOR( ; b < pred_real_bands_yaw; b++ ) + { + hMd = &hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b]; + FOR( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + { + sym_adj_idx[ch1][ch1] = ivas_split_rend_huffman_decode_opt( &pHuff_cfg->pred[pred_cb_idx], pBits, pHuff_cfg->pred_idx_trav[pred_cb_idx] ); + move16(); + } + sym_adj_idx[1][0] = 0; + move16(); + sym_adj_idx[0][1] = 0; + move16(); + isar_SplitRenderer_getdiagdiff( sym_adj_idx, hMd->pred_mat_re_idx, -1, min_pred_idx, max_pred_idx ); + } +#endif + FOR( b = 0; b < d_bands_yaw; b++ ) + { + hMd = &hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b]; + hMd->gd_idx = ivas_split_rend_huffman_decode_opt( &pHuff_cfg->gd, pBits, pHuff_cfg->gd_idx_trav ); + // hMd->gd_idx = ivas_split_rend_huffman_decode( &pHuff_cfg->gd, pBits ); + } + } + ELSE IF( hBinHrSplitPostRend->pose_type[pos_idx] == PITCH_ONLY ) + { + FOR( b = 0; b < bands_pitch; b++ ) + { + hMd = &hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b]; + hMd->gd_idx = ivas_split_rend_huffman_decode_opt( &pHuff_cfg->p_gd, pBits, pHuff_cfg->p_gd_idx_trav ); + // hMd->gd_idx = ivas_split_rend_huffman_decode( &pHuff_cfg->gd, pBits ); + + hMd->gd2_idx = ivas_split_rend_huffman_decode_opt( &pHuff_cfg->p_gd, pBits, pHuff_cfg->p_gd_idx_trav ); + } + } + ELSE + { +#ifndef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS + FOR( b = 0; b < pred_real_bands_roll; b++ ) + { + hMd = &hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b]; + + FOR( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + { + FOR( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) + { + sym_adj_idx[ch1][ch2] = ivas_split_rend_huffman_decode_opt( &pHuff_cfg->pred_roll, pBits, pHuff_cfg->pred_roll_idx_trav ); + move16(); + // sym_adj_idx[ch1][ch2] = ivas_split_rend_huffman_decode( &pHuff_cfg->pred_roll, pBits ); + } + } + isar_SplitRenderer_getdiagdiff( sym_adj_idx, hMd->pred_mat_re_idx, 1, min_pred_roll_idx, max_pred_roll_idx ); + } + FOR( b = 0; b < pred_imag_bands_roll; b++ ) + { + hMd = &hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b]; + FOR( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + { + FOR( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) + { + sym_adj_idx[ch1][ch2] = ivas_split_rend_huffman_decode_opt( &pHuff_cfg->pred_roll, pBits, pHuff_cfg->pred_roll_idx_trav ); + move16(); + // sym_adj_idx[ch1][ch2] = ivas_split_rend_huffman_decode( &pHuff_cfg->pred_roll, pBits ); + } + } + isar_SplitRenderer_getdiagdiff( sym_adj_idx, hMd->pred_mat_im_idx, -1, min_pred_roll_idx, max_pred_roll_idx ); + } +#else + FOR( b = 0; b < pred_imag_bands_roll; b++ ) + { + hMd = &hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b]; + FOR( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + { + FOR( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) + { + sym_adj_idx[ch1][ch2] = ivas_split_rend_huffman_decode_opt( &pHuff_cfg->pred_roll, pBits, pHuff_cfg->pred_roll_idx_trav ); + move16(); + // sym_adj_idx[ch1][ch2] = ivas_split_rend_huffman_decode( &pHuff_cfg->pred_roll, pBits ); + } + } + isar_SplitRenderer_getdiagdiff( sym_adj_idx, hMd->pred_mat_re_idx, 1, min_pred_roll_idx, max_pred_roll_idx ); + + FOR( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + { + FOR( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) + { + sym_adj_idx[ch1][ch2] = ivas_split_rend_huffman_decode_opt( &pHuff_cfg->pred_roll, pBits, pHuff_cfg->pred_roll_idx_trav ); + move16(); + // sym_adj_idx[ch1][ch2] = ivas_split_rend_huffman_decode( &pHuff_cfg->pred_roll, pBits ); + } + } + isar_SplitRenderer_getdiagdiff( sym_adj_idx, hMd->pred_mat_im_idx, -1, min_pred_roll_idx, max_pred_roll_idx ); + } + FOR( ; b < pred_real_bands_roll; b++ ) + { + hMd = &hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b]; + + FOR( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + { + sym_adj_idx[ch1][ch1] = ivas_split_rend_huffman_decode_opt( &pHuff_cfg->pred_roll, pBits, pHuff_cfg->pred_roll_idx_trav ); + move16(); + } + sym_adj_idx[1][0] = 0; + move16(); + sym_adj_idx[0][1] = 0; + move16(); + isar_SplitRenderer_getdiagdiff( sym_adj_idx, hMd->pred_mat_re_idx, -1, min_pred_roll_idx, max_pred_roll_idx ); + } +#endif + } + } + } + + return; +} + + +/*-----------------------------------------------------------------------------------------* + * Function isar_splitBinPostRendMdDec() + * + * + *-----------------------------------------------------------------------------------------*/ + +void isar_splitBinPostRendMdDec_fx( + ISAR_SPLIT_REND_BITS_HANDLE pBits, + ISAR_BIN_HR_SPLIT_POST_REND_HANDLE hBinHrSplitPostRend, + MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData +#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG + , + BIN_HR_SPLIT_PRE_REND_HANDLE hBinHrSplitPreRend +#endif +) +{ + Word16 pos_idx, b, sf_idx, num_subframes, ch1; + Word16 pred_real_bands_yaw[ISAR_SPLIT_REND_NUM_QUANT_STRATS], pred_real_bands_roll[ISAR_SPLIT_REND_NUM_QUANT_STRATS]; + Word16 pred_imag_bands_yaw[ISAR_SPLIT_REND_NUM_QUANT_STRATS], pred_imag_bands_roll[ISAR_SPLIT_REND_NUM_QUANT_STRATS]; + Word16 d_bands_yaw[ISAR_SPLIT_REND_NUM_QUANT_STRATS], bands_pitch[ISAR_SPLIT_REND_NUM_QUANT_STRATS]; +#ifdef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS + Word16 num_quant_strats; +#else + Word16 num_complex_bands, num_quant_strats; +#endif + Word32 quant_strat_bits, is_huff_coding, quant_strat; + Word16 pred_quant_pnts_yaw[ISAR_SPLIT_REND_NUM_QUANT_STRATS]; + Word32 pred_1byquantstep_yaw_fx[ISAR_SPLIT_REND_NUM_QUANT_STRATS]; // Q26 + Word32 pred_quantstep_yaw_fx[ISAR_SPLIT_REND_NUM_QUANT_STRATS]; // Q31 +#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG + Word16 ch1, ch2; +#endif + ISAR_BIN_HR_SPLIT_REND_MD_HANDLE hMd; + ISAR_SPLIT_REND_CONFIG_DATA split_rend_config; + ISAR_SPLIT_REND_ROT_AXIS rot_axis; +#ifdef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS + Word16 ro_md_flag, num_bits, axis_code; +#endif + + hBinHrSplitPostRend->low_Res = 1; + move16(); + + split_rend_config.dof = extract_l( ISAR_SPLIT_REND_BITStream_read_int32( pBits, ISAR_SPLIT_REND_DOF_BITS ) ); + split_rend_config.hq_mode = extract_l( ISAR_SPLIT_REND_BITStream_read_int32( pBits, ISAR_SPLIT_REND_HQ_MODE_BITS ) ); + +#ifdef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS + num_bits = isar_renderSplitGetRot_axisNumBits( split_rend_config.dof ); + if ( num_bits > 0 ) + { + axis_code = (int16_t) ISAR_SPLIT_REND_BITStream_read_int32( pBits, (int32_t) num_bits ); + } + else + { + axis_code = 0; + } + rot_axis = isar_renderSplitGetRot_axisFromCode( split_rend_config.dof, axis_code ); + ro_md_flag = (int16_t) ISAR_SPLIT_REND_BITStream_read_int32( pBits, ISAR_SPLIT_REND_RO_FLAG_BITS ); +#else + rot_axis = (ISAR_SPLIT_REND_ROT_AXIS) ISAR_SPLIT_REND_BITStream_read_int32( pBits, ISAR_SPLIT_REND_ROT_AXIS_BITS ); +#endif + isar_renderSplitGetMultiBinPoseData_fx( &split_rend_config, pMultiBinPoseData, rot_axis ); + + set_fix_rotation_mat_fx( hBinHrSplitPostRend->fix_pos_rot_mat_fx, pMultiBinPoseData ); + set_pose_types_fx( hBinHrSplitPostRend->pose_type, pMultiBinPoseData ); + + num_subframes = EQ_16( hBinHrSplitPostRend->low_Res, 0 ) ? MAX_PARAM_SPATIAL_SUBFRAMES : 1; + move16(); + FOR( sf_idx = 0; sf_idx < num_subframes; sf_idx++ ) + { + Word16 angle; + + hBinHrSplitPostRend->QuaternionsPre[sf_idx].w_fx = -12582912; /* -3.0f in Q22 */ + move32(); + + angle = extract_l( ISAR_SPLIT_REND_BITStream_read_int32( pBits, ISAR_SPLIT_REND_HEAD_POSE_BITS ) ); + angle = sub( angle, 180 ); + hBinHrSplitPostRend->QuaternionsPre[sf_idx].x_fx = L_shl( angle, Q22 ); /* Q22 */ + move32(); + + angle = extract_l( ISAR_SPLIT_REND_BITStream_read_int32( pBits, ISAR_SPLIT_REND_HEAD_POSE_BITS ) ); + angle = sub( angle, 180 ); + hBinHrSplitPostRend->QuaternionsPre[sf_idx].y_fx = L_shl( angle, Q22 ); /* Q22 */ + move32(); + + angle = extract_l( ISAR_SPLIT_REND_BITStream_read_int32( pBits, ISAR_SPLIT_REND_HEAD_POSE_BITS ) ); + angle = sub( angle, 180 ); + hBinHrSplitPostRend->QuaternionsPre[sf_idx].z_fx = L_shl( angle, Q22 ); /* Q22 */ + move32(); + + hBinHrSplitPostRend->QuaternionsPre[sf_idx].q_fact = Q22; + move32(); + } + +#ifdef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS + isar_split_rend_get_quant_params_fx( + MAX_SPLIT_REND_MD_BANDS, + pred_real_bands_yaw, + pred_imag_bands_yaw, + pred_quant_pnts_yaw, + pred_quantstep_yaw_fx, + pred_1byquantstep_yaw_fx, + d_bands_yaw, + bands_pitch, + pred_real_bands_roll, + pred_imag_bands_roll, + ro_md_flag, + &num_quant_strats ); +#else + isar_split_rend_get_quant_params_fx( + MAX_SPLIT_REND_MD_BANDS, + pred_real_bands_yaw, + pred_imag_bands_yaw, + pred_quant_pnts_yaw, + pred_quantstep_yaw_fx, + pred_1byquantstep_yaw_fx, + d_bands_yaw, + bands_pitch, + pred_real_bands_roll, + pred_imag_bands_roll, + &num_quant_strats, + &num_complex_bands ); +#endif + quant_strat_bits = L_deposit_l( ceil_log_2( num_quant_strats ) ); + is_huff_coding = ISAR_SPLIT_REND_BITStream_read_int32( pBits, 1 ); + quant_strat = ISAR_SPLIT_REND_BITStream_read_int32( pBits, quant_strat_bits ); + + IF( EQ_32( is_huff_coding, 0 ) ) + { + isar_splitBinPostRendMdBase2Dec( + pBits, hBinHrSplitPostRend, + pMultiBinPoseData, + num_subframes, + pred_real_bands_yaw[quant_strat], + pred_imag_bands_yaw[quant_strat], + pred_quant_pnts_yaw[quant_strat], + d_bands_yaw[quant_strat], + bands_pitch[quant_strat], + pred_real_bands_roll[quant_strat], + pred_imag_bands_roll[quant_strat] ); + } + ELSE + { + ivas_splitBinPostRendMdHuffDec( + pBits, hBinHrSplitPostRend, + pMultiBinPoseData, + num_subframes, + pred_real_bands_yaw[quant_strat], + pred_imag_bands_yaw[quant_strat], + pred_quant_pnts_yaw[quant_strat], + d_bands_yaw[quant_strat], + bands_pitch[quant_strat], + pred_real_bands_roll[quant_strat], + pred_imag_bands_roll[quant_strat] ); + } +#ifdef SPLIT_MD_CODING_DEBUG + for ( sf_idx = 0; sf_idx < num_subframes; sf_idx++ ) + { + int16_t val, ch2, val_ref; + char filename[200] = "split_md_debug_indices.bin"; + for ( pos_idx = 0; pos_idx < pMultiBinPoseData->num_poses - 1; pos_idx++ ) + { + if ( hBinHrSplitPostRend->pose_type[pos_idx] == ANY_YAW ) + { + for ( b = 0; b < pred_real_bands_yaw[quant_strat]; b++ ) + { + for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + { + for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) + { + val = hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b].pred_mat_re_idx[ch1][ch2]; + dbgread( &val_ref, sizeof( int16_t ), 1, filename ); + if ( abs( val_ref - val ) > 0 ) + { + assert( 0 ); + } + } + } + } + for ( b = 0; b < pred_imag_bands_yaw[quant_strat]; b++ ) + { + for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + { + for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) + { + val = hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b].pred_mat_im_idx[ch1][ch2]; + dbgread( &val_ref, sizeof( int16_t ), 1, filename ); + if ( abs( val_ref - val ) > 0 ) + { + assert( 0 ); + } + } + } + } + for ( b = 0; b < d_bands_yaw[quant_strat]; b++ ) + { + val = hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b].gd_idx; + dbgread( &val_ref, sizeof( int16_t ), 1, filename ); + if ( abs( val_ref - val ) > 0 ) + { + assert( 0 ); + } + } + } + else if ( hBinHrSplitPostRend->pose_type[pos_idx] == PITCH_ONLY ) + { + for ( b = 0; b < bands_pitch[quant_strat]; b++ ) + { + val = hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b].gd_idx; + dbgread( &val_ref, sizeof( int16_t ), 1, filename ); + if ( abs( val_ref - val ) > 0 ) + { + assert( 0 ); + } + val = hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b].gd2_idx; + dbgread( &val_ref, sizeof( int16_t ), 1, filename ); + if ( abs( val_ref - val ) > 0 ) + { + assert( 0 ); + } + } + } + else + { + for ( b = 0; b < pred_real_bands_roll[quant_strat]; b++ ) + { + for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + { + for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) + { + val = hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b].pred_mat_re_idx[ch1][ch2]; + dbgread( &val_ref, sizeof( int16_t ), 1, filename ); + if ( abs( val_ref - val ) > 0 ) + { + assert( 0 ); + } + } + } + } + for ( b = 0; b < pred_imag_bands_roll[quant_strat]; b++ ) + { + for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + { + for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) + { + val = hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b].pred_mat_im_idx[ch1][ch2]; + dbgread( &val_ref, sizeof( int16_t ), 1, filename ); + if ( abs( val_ref - val ) > 0 ) + { + assert( 0 ); + } + } + } + } + } + } + } +#endif + + FOR( sf_idx = 0; sf_idx < num_subframes; sf_idx++ ) + { + FOR( pos_idx = 0; pos_idx < sub( pMultiBinPoseData->num_poses, 1 ); pos_idx++ ) + { + IF( EQ_32( hBinHrSplitPostRend->pose_type[pos_idx], ANY_YAW ) ) + { + FOR( b = 0; b < pred_imag_bands_yaw[quant_strat]; b++ ) + { + hMd = &hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b]; + ivas_split_rend_unquant_md_fx( hMd, PRED_ONLY, 0, hBinHrSplitPostRend->fix_pos_rot_mat_fx[pos_idx], pred_quantstep_yaw_fx[quant_strat] ); + } + FOR( ; b < pred_real_bands_yaw[quant_strat]; b++ ) + { + hMd = &hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b]; + ivas_split_rend_unquant_md_fx( hMd, PRED_ONLY, 1, hBinHrSplitPostRend->fix_pos_rot_mat_fx[pos_idx], pred_quantstep_yaw_fx[quant_strat] ); + } + FOR( ; b < MAX_SPLIT_REND_MD_BANDS; b++ ) + { + hMd = &hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b]; + FOR( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + { + set32_fx( hMd->pred_mat_re_fx[ch1], 0, BINAURAL_CHANNELS ); + set32_fx( hMd->pred_mat_im_fx[ch1], 0, BINAURAL_CHANNELS ); + hMd->pred_mat_re_fx[ch1][ch1] = L_shl( 1, Q25 ); /* 1.0f in Q25 */ + move32(); + } + } + FOR( b = 0; b < d_bands_yaw[quant_strat]; b++ ) + { + hMd = &hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b]; + ivas_split_rend_unquant_md_fx( hMd, COM_GAIN_ONLY, 1, hBinHrSplitPostRend->fix_pos_rot_mat_fx[pos_idx], 0 ); + } + FOR( ; b < MAX_SPLIT_REND_MD_BANDS; b++ ) + { + hMd = &hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b]; + hMd->gd_fx = 0; + move32(); + } + } + ELSE IF( EQ_32( hBinHrSplitPostRend->pose_type[pos_idx], PITCH_ONLY ) ) + { + FOR( b = 0; b < bands_pitch[quant_strat]; b++ ) + { + hMd = &hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b]; + ivas_split_rend_unquant_md_fx( hMd, LR_GAIN_ONLY, 1, hBinHrSplitPostRend->fix_pos_rot_mat_fx[pos_idx], 0 ); + } + FOR( ; b < MAX_SPLIT_REND_MD_BANDS; b++ ) + { + hMd = &hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b]; + hMd->gd_fx = L_shl( 1, Q25 ); /* 1.0f in Q25 */ + move32(); + hMd->gd2_fx = L_shl( 1, Q25 ); /* 1.0f in Q25 */ + move32(); + } + } + ELSE + { + FOR( b = 0; b < pred_imag_bands_roll[quant_strat]; b++ ) + { + hMd = &hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b]; + ivas_split_rend_unquant_md_fx( hMd, PRED_ROLL_ONLY, 0, hBinHrSplitPostRend->fix_pos_rot_mat_fx[pos_idx], ISAR_SPLIT_REND_PRED_ROLL_Q_STEP_Q31 ); + } + FOR( ; b < pred_real_bands_roll[quant_strat]; b++ ) + { + hMd = &hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b]; + ivas_split_rend_unquant_md_fx( hMd, PRED_ROLL_ONLY, 1, hBinHrSplitPostRend->fix_pos_rot_mat_fx[pos_idx], ISAR_SPLIT_REND_PRED_ROLL_Q_STEP_Q31 ); + } + FOR( ; b < MAX_SPLIT_REND_MD_BANDS; b++ ) + { + hMd = &hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b]; + FOR( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + { + set32_fx( hMd->pred_mat_re_fx[ch1], 0, BINAURAL_CHANNELS ); + set32_fx( hMd->pred_mat_im_fx[ch1], 0, BINAURAL_CHANNELS ); + hMd->pred_mat_re_fx[ch1][ch1] = L_shl( 1, Q25 ); /* 1.0f in Q25 */ + move32(); + } + } + } + } + } +#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG + for ( sf_idx = 0; sf_idx < num_subframes; sf_idx++ ) + { + float val; + for ( pos_idx = 0; pos_idx < pMultiBinPoseData->num_poses - 1; pos_idx++ ) + { + if ( hBinHrSplitPostRend->pose_type[pos_idx] == ANY_YAW ) + { + for ( b = 0; b < pred_real_bands_yaw[quant_strat]; b++ ) + { + for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + { + for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) + { + val = hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].pred_mat_re_idx[ch1][ch2]; + if ( fabsf( hMd->pred_mat_re_idx[ch1][ch2] - val ) > 1e-20 ) + { + assert( 0 ); + } + } + } + } + for ( b = 0; b < pred_imag_bands_yaw[quant_strat]; b++ ) + { + for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + { + for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) + { + val = hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].pred_mat_im_idx[ch1][ch2]; + if ( fabsf( hMd->pred_mat_im_idx[ch1][ch2] - val ) > 1e-20 ) + { + assert( 0 ); + } + } + } + } + for ( b = 0; b < d_bands_yaw[quant_strat]; b++ ) + { + val = hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].gd_idx; + if ( fabsf( hMd->gd_idx - val ) > 1e-20 ) + { + assert( 0 ); + } + } + } + else if ( hBinHrSplitPostRend->pose_type[pos_idx] == PITCH_ONLY ) + { + for ( b = 0; b < bands_pitch[quant_strat]; b++ ) + { + val = hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].gd_idx; + if ( fabsf( hMd->gd_idx - val ) > 1e-20 ) + { + assert( 0 ); + } + val = hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].gd2_idx; + if ( fabsf( hMd->gd2_idx - val ) > 1e-20 ) + { + assert( 0 ); + } + } + } + else + { + for ( b = 0; b < pred_real_bands_roll[quant_strat]; b++ ) + { + for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + { + for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) + { + val = hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].pred_mat_re_idx[ch1][ch2]; + if ( fabsf( hMd->pred_mat_re_idx[ch1][ch2] - val ) > 1e-20 ) + { + assert( 0 ); + } + } + } + } + for ( b = 0; b < pred_imag_bands_roll[quant_strat]; b++ ) + { + for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + { + for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) + { + val = hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].pred_mat_im_idx[ch1][ch2]; + if ( fabsf( hMd->pred_mat_im_idx[ch1][ch2] - val ) > 1e-20 ) + { + assert( 0 ); + } + } + } + } + } + } + } +#endif + + return; +} + +/*-----------------------------------------------------------------------------------------* + * Function wrap_around_angle() + * + * + *-----------------------------------------------------------------------------------------*/ +static void wrap_around_angle_fx( + Word32 *a_fx ) +{ + IF( GT_32( ( *a_fx ), 754974720 /*180.f in Q22*/ ) ) + { + *a_fx = L_sub( ( *a_fx ), 1509949440 /*360.f in Q22*/ ); + } + ELSE IF( LT_32( ( *a_fx ), L_negate( 754974720 /*180.f in Q22*/ ) ) ) + { + *a_fx = L_add( *a_fx, 1509949440 /*360.f in Q22*/ ); + } + return; +} + +/*-----------------------------------------------------------------------------------------* + * Function wrap_around_angle() + * + * + *-----------------------------------------------------------------------------------------*/ +static void wrap_around_ypr_fx( + IVAS_QUATERNION *Quaternions ) +{ + /*only if quat is actually yaw, pitch , roll angles*/ + IF( EQ_32( Quaternions->w_fx, L_negate( 12582912 /*3.0f in Q22*/ ) ) ) + { + wrap_around_angle_fx( &Quaternions->x_fx ); + wrap_around_angle_fx( &Quaternions->y_fx ); + wrap_around_angle_fx( &Quaternions->z_fx ); + } + return; +} + +/*-----------------------------------------------------------------------------------------* + * Function wrap_around_angle() + * + * + *-----------------------------------------------------------------------------------------*/ +static Word32 get_interp_fact_fx( + Word32 p_fx[MAX_HEAD_ROT_POSES], + const Word32 p_t_fx, + const Word16 ind[2], + Word16 *exp ) +{ + Word32 n_fx, d_fx, interp_fact_fx; + *exp = 31; + move16(); + IF( NE_16( ind[0], ind[1] ) ) + { + n_fx = L_sub( p_fx[ind[0]], p_fx[ind[1]] ); + move32(); + d_fx = L_sub( p_fx[ind[0]], p_t_fx ); + move32(); + interp_fact_fx = L_deposit_h( BASOP_Util_Divide3232_Scale( d_fx, n_fx, exp ) ); // Q31-exp + move32(); + IF( LT_32( interp_fact_fx, 0 ) ) + { + d_fx = max( -( MAX_EXTRAPOLATION_ANGLE_Q22 ), ( min( ( MAX_EXTRAPOLATION_ANGLE_Q22 ), d_fx ) ) ); + move32(); + n_fx = L_deposit_h( getSineWord16R2( extract_l( L_shr( Mpy_32_32( n_fx, Q31_BY_360 ), 7 ) ) ) ); + move32(); + d_fx = L_deposit_h( getSineWord16R2( extract_l( L_shr( Mpy_32_32( d_fx, Q31_BY_360 ), 7 ) ) ) ); + move32(); + interp_fact_fx = L_deposit_h( BASOP_Util_Divide3232_Scale( d_fx, n_fx, exp ) ); // Q31-exp + move32(); + } + } + ELSE + { + interp_fact_fx = 0; + move32(); + } + return interp_fact_fx; +} + +/*-----------------------------------------------------------------------------------------* + * Function get_nearest_pose_ind() + * + * + *-----------------------------------------------------------------------------------------*/ +static void get_nearest_pose_ind_fx( + Word32 p[MAX_HEAD_ROT_POSES], + const Word32 p_t, + Word16 ind[2], + const Word16 num_poses ) +{ + Word32 min_diff, diff; + Word16 pos_idx; + + ind[0] = 0; + ind[1] = 0; + min_diff = 1509949440; // 360 in Q22 + + /*find the closest pose from assumed poses*/ + FOR( pos_idx = 0; pos_idx < num_poses; pos_idx++ ) + { + diff = L_abs( L_sub( p_t, p[pos_idx] ) ); + IF( LT_32( diff, min_diff ) ) + { + ind[0] = pos_idx; + min_diff = diff; + } + } + + min_diff = 1509949440; // 360 in Q22 + FOR( pos_idx = 0; pos_idx < num_poses; pos_idx++ ) + { + diff = L_abs( L_sub( p_t, p[pos_idx] ) ); + IF( LT_32( diff, min_diff ) && + GT_32( L_abs( L_sub( p[pos_idx], p[ind[0]] ) ), EPSILON_FX ) ) + { + ind[1] = pos_idx; + min_diff = diff; + } + } + + return; +} + +/*-----------------------------------------------------------------------------------------* + * Function get_interpolation_vars() + * + * + *-----------------------------------------------------------------------------------------*/ +static void get_interpolation_vars( + MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, + const IVAS_QUATERNION *Quaternions_ref, + const IVAS_QUATERNION *Quaternions_act, + int16_t interp_yaw_pose_idx[2], + int16_t interp_pitch_pose_idx[2], + int16_t interp_roll_pose_idx[2], + Word32 *interp_yaw_fact_fx, + Word32 *interp_pitch_fact_fx, + Word32 *interp_roll_fact_fx, + Word16 *q_yaw, + Word16 *q_pitch, + Word16 *q_roll ) +{ + IVAS_QUATERNION quaternions_diff, quaternions_ref_euler, quaternions_act_euler, quaternions_ref_q22, quaternions_act_q22; + Word32 y_fx[MAX_HEAD_ROT_POSES], p_fx[MAX_HEAD_ROT_POSES], r_fx[MAX_HEAD_ROT_POSES]; + + int16_t pos_idx, num_poses; + Word16 exp; + + quaternions_diff.x_fx = 0; + quaternions_diff.y_fx = 0; + quaternions_diff.z_fx = 0; + + num_poses = pMultiBinPoseData->num_poses; + + FOR( pos_idx = 0; pos_idx < num_poses; pos_idx++ ) + { + quaternions_diff.x_fx = pMultiBinPoseData->relative_head_poses_fx[pos_idx][0]; + quaternions_diff.y_fx = pMultiBinPoseData->relative_head_poses_fx[pos_idx][1]; + quaternions_diff.z_fx = pMultiBinPoseData->relative_head_poses_fx[pos_idx][2]; + y_fx[pos_idx] = quaternions_diff.x_fx; + p_fx[pos_idx] = quaternions_diff.y_fx; + r_fx[pos_idx] = quaternions_diff.z_fx; + } + + /*interpolation if actual pose is not same as one of assumed poses*/ + /*get the deviation*/ + modify_Quat_q_fx( Quaternions_ref, &quaternions_ref_q22, Q22 ); + modify_Quat_q_fx( Quaternions_act, &quaternions_act_q22, Q22 ); + Quat2EulerDegree_fx( quaternions_ref_q22, &quaternions_ref_euler.z_fx, &quaternions_ref_euler.y_fx, &quaternions_ref_euler.x_fx ); /*order in Quat2Euler seems to be reversed ?*/ + Quat2EulerDegree_fx( quaternions_act_q22, &quaternions_act_euler.z_fx, &quaternions_act_euler.y_fx, &quaternions_act_euler.x_fx ); + + /*order in Quat2Euler seems to be reversed ?*/ + quaternions_diff.w_fx = -12582912; /*euler*/ //-3 in Q22 + quaternions_diff.x_fx = L_sub( quaternions_act_euler.x_fx, quaternions_ref_euler.x_fx ); + quaternions_diff.y_fx = L_sub( quaternions_act_euler.y_fx, quaternions_ref_euler.y_fx ); + quaternions_diff.z_fx = L_sub( quaternions_act_euler.z_fx, quaternions_ref_euler.z_fx ); + wrap_around_ypr_fx( &quaternions_diff ); + interp_yaw_pose_idx[0] = 0; + interp_yaw_pose_idx[1] = 0; + IF( GT_32( L_abs( quaternions_diff.x_fx ), EPSILON_FX ) ) + { + get_nearest_pose_ind_fx( y_fx, quaternions_diff.x_fx, interp_yaw_pose_idx, num_poses ); + } + *interp_yaw_fact_fx = get_interp_fact_fx( y_fx, quaternions_diff.x_fx, interp_yaw_pose_idx, &exp ); + *q_yaw = Q31 - exp; + + interp_pitch_pose_idx[0] = 0; + interp_pitch_pose_idx[1] = 0; + IF( GT_32( L_abs( quaternions_diff.y_fx ), EPSILON_FX ) ) + { + get_nearest_pose_ind_fx( p_fx, quaternions_diff.y_fx, interp_pitch_pose_idx, num_poses ); + } + *interp_pitch_fact_fx = get_interp_fact_fx( p_fx, quaternions_diff.y_fx, interp_pitch_pose_idx, &exp ); + *q_pitch = Q31 - exp; + + interp_roll_pose_idx[0] = 0; + interp_roll_pose_idx[1] = 0; + IF( GT_32( L_abs( quaternions_diff.z_fx ), EPSILON_FX ) ) + { + get_nearest_pose_ind_fx( r_fx, quaternions_diff.z_fx, interp_roll_pose_idx, num_poses ); + } + *interp_roll_fact_fx = get_interp_fact_fx( r_fx, quaternions_diff.z_fx, interp_roll_pose_idx, &exp ); + *q_roll = Q31 - exp; + + return; +} + +/*-----------------------------------------------------------------------------------------* + * Function interpolate_pred_matrix() + * + * + *-----------------------------------------------------------------------------------------*/ +static void interpolate_pred_matrix_fx( + ISAR_BIN_HR_SPLIT_REND_MD rot_md[][MAX_SPLIT_MD_SUBFRAMES][MAX_SPLIT_REND_MD_BANDS], + const Word16 sf_idx, + const Word16 band_idx, + const Word16 ind[2], + const Word32 interp_fact_fx, + Word16 intrep_norm, + Word32 mat_re_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], + Word16 *exp_mat_re, + Word32 mat_im_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], + Word16 *exp_mat_im ) +{ + Word16 ch_idx1, ch_idx2; + ISAR_BIN_HR_SPLIT_REND_MD *pRot_md; + // ord16 intrep_norm = Q_factor_L(interp_fact); + // ord32 interp_fact_fx = floatToFixed(interp_fact, intrep_norm); + Word32 diff_fx; + Word32 mix_mat_re1_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS]; + Word32 mix_mat_im1_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS]; + Word32 mix_mat_re2_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS]; + Word32 mix_mat_im2_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS]; + Word16 buff_exp_re[BINAURAL_CHANNELS][BINAURAL_CHANNELS], buff_exp_im[BINAURAL_CHANNELS][BINAURAL_CHANNELS]; + + FOR( ch_idx1 = 0; ch_idx1 < BINAURAL_CHANNELS; ch_idx1++ ) + { + set32_fx( mix_mat_re1_fx[ch_idx1], 0, BINAURAL_CHANNELS ); + set32_fx( mix_mat_im1_fx[ch_idx1], 0, BINAURAL_CHANNELS ); + mix_mat_re1_fx[ch_idx1][ch_idx1] = ONE_IN_Q25; + + set32_fx( mix_mat_re2_fx[ch_idx1], 0, BINAURAL_CHANNELS ); + set32_fx( mix_mat_im2_fx[ch_idx1], 0, BINAURAL_CHANNELS ); + mix_mat_re2_fx[ch_idx1][ch_idx1] = ONE_IN_Q25; + } + + IF( ind[0] != 0 ) + { + pRot_md = &rot_md[ind[0] - 1][sf_idx][band_idx]; + + FOR( ch_idx1 = 0; ch_idx1 < BINAURAL_CHANNELS; ch_idx1++ ) + { + FOR( ch_idx2 = 0; ch_idx2 < BINAURAL_CHANNELS; ch_idx2++ ) + { + mix_mat_re1_fx[ch_idx1][ch_idx2] = pRot_md->pred_mat_re_fx[ch_idx1][ch_idx2]; + mix_mat_im1_fx[ch_idx1][ch_idx2] = pRot_md->pred_mat_im_fx[ch_idx1][ch_idx2]; + } + } + } + + IF( ind[1] != 0 ) + { + pRot_md = &rot_md[ind[1] - 1][sf_idx][band_idx]; + + FOR( ch_idx1 = 0; ch_idx1 < BINAURAL_CHANNELS; ch_idx1++ ) + { + FOR( ch_idx2 = 0; ch_idx2 < BINAURAL_CHANNELS; ch_idx2++ ) + { + mix_mat_re2_fx[ch_idx1][ch_idx2] = pRot_md->pred_mat_re_fx[ch_idx1][ch_idx2]; + mix_mat_im2_fx[ch_idx1][ch_idx2] = pRot_md->pred_mat_im_fx[ch_idx1][ch_idx2]; + } + } + } + + Word16 final_exp = 0, mat_re_exp = 0, mat_im_exp = 0; + FOR( ch_idx1 = 0; ch_idx1 < BINAURAL_CHANNELS; ch_idx1++ ) + { + FOR( ch_idx2 = 0; ch_idx2 < BINAURAL_CHANNELS; ch_idx2++ ) + { + final_exp = 0; + diff_fx = BASOP_Util_Add_Mant32Exp( mix_mat_re1_fx[ch_idx1][ch_idx2], 31 - Q25, L_negate( mix_mat_re2_fx[ch_idx1][ch_idx2] ), 31 - Q25, &final_exp ); + Word64 tmp1 = W_mult_32_32( diff_fx, interp_fact_fx ); // final_exp + (31 - intrep_norm) + Word16 tmp1_nrm = W_norm( tmp1 ); + Word32 tmp1_final = W_extract_h( W_shl( tmp1, tmp1_nrm ) ); // final_exp + (31 - intrep_norm) - tmp1_nrm + mat_re_exp = 0; + mat_re_fx[ch_idx1][ch_idx2] = BASOP_Util_Add_Mant32Exp( mix_mat_re1_fx[ch_idx1][ch_idx2], 31 - Q25, L_negate( tmp1_final ), final_exp + ( 31 - intrep_norm ) - tmp1_nrm, &mat_re_exp ); + buff_exp_re[ch_idx1][ch_idx2] = mat_re_exp; + + final_exp = 0; + diff_fx = BASOP_Util_Add_Mant32Exp( mix_mat_im1_fx[ch_idx1][ch_idx2], 31 - Q25, L_negate( mix_mat_im2_fx[ch_idx1][ch_idx2] ), 31 - Q25, &final_exp ); + Word64 tmp2 = W_mult_32_32( diff_fx, interp_fact_fx ); // final_exp + (31 - intrep_norm) + Word16 tmp2_nrm = W_norm( tmp2 ); + Word32 tmp2_final = W_extract_h( W_shl( tmp2, tmp2_nrm ) ); // final_exp + (31 - intrep_norm) - tmp1_nrm + mat_im_exp = 0; + mat_im_fx[ch_idx1][ch_idx2] = BASOP_Util_Add_Mant32Exp( mix_mat_im1_fx[ch_idx1][ch_idx2], 31 - Q25, L_negate( tmp2_final ), final_exp + ( 31 - intrep_norm ) - tmp2_nrm, &mat_im_exp ); + buff_exp_im[ch_idx1][ch_idx2] = mat_im_exp; + } + } + + Word16 max_exp_re = MIN16B; + Word16 max_exp_im = MIN16B; + FOR( Word16 i = 0; i < BINAURAL_CHANNELS; i++ ) + { + FOR( Word16 j = 0; j < BINAURAL_CHANNELS; j++ ) + { + max_exp_re = max( max_exp_re, buff_exp_re[i][j] ); + max_exp_im = max( max_exp_im, buff_exp_im[i][j] ); + } + } + FOR( Word16 i = 0; i < BINAURAL_CHANNELS; i++ ) + { + FOR( Word16 j = 0; j < BINAURAL_CHANNELS; j++ ) + { + mat_re_fx[i][j] = L_shr( mat_re_fx[i][j], max_exp_re - buff_exp_re[i][j] ); + mat_im_fx[i][j] = L_shr( mat_im_fx[i][j], max_exp_im - buff_exp_im[i][j] ); + } + } + + *exp_mat_re = max_exp_re; + *exp_mat_im = max_exp_im; + + return; +} +/*-----------------------------------------------------------------------------------------* + * Function interpolate_rend_md() + * + * + *-----------------------------------------------------------------------------------------*/ + +static void interpolate_rend_md_fx( + ISAR_BIN_HR_SPLIT_REND_MD rot_md[][MAX_SPLIT_MD_SUBFRAMES][MAX_SPLIT_REND_MD_BANDS], + Word32 mix_mat_re_fx[][BINAURAL_CHANNELS], + Word16 *exp_mix_mat_re, + Word32 mix_mat_im_fx[][BINAURAL_CHANNELS], + Word16 *exp_mix_mat_im, + Word32 *gd_int_fx, + Word16 *exp_gd_int, + const Word16 sf_idx, + const Word16 band_idx, + const Word16 interp_yaw_pose_idx[2], + const Word16 interp_pitch_pose_idx[2], + const Word16 interp_roll_pose_idx[2], + const Word32 interp_yaw_fact_fx, + Word16 Q_yaw, + const Word32 interp_pitch_fact_fx, + Word16 Q_pitch, + const Word32 interp_roll_fact_fx, + Word16 Q_roll ) +{ + Word16 ch_idx1, idx1, idx2; + + Word32 mix_mat_re1_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS]; + Word32 mix_mat_im1_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS]; + Word32 mix_mat_re3_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS]; + Word32 mix_mat_im3_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS]; + + Word16 exp_mix_mat_re1 = 0; + Word16 exp_mix_mat_im1 = 0; + Word16 exp_mix_mat_re3 = 0; + Word16 exp_mix_mat_im3 = 0; + + Word16 ch_idx2; + Word16 exp_pitch_gain_r, exp_pitch_gain_l; + Word32 gd1_fx = 0, gd2_fx = 0; + Word32 gd3_fx = 0, gd4_fx = 0; + Word32 pitch_gain_r_fx, pitch_gain_l_fx; + Word32 diff_fx; + + Word16 exp_mat_re[BINAURAL_CHANNELS][BINAURAL_CHANNELS]; + Word16 exp_mat_im[BINAURAL_CHANNELS][BINAURAL_CHANNELS]; + + idx1 = interp_yaw_pose_idx[0]; + idx2 = interp_yaw_pose_idx[1]; + + + IF( NE_16( idx1, 0 ) || NE_16( idx2, 0 ) ) + { + interpolate_pred_matrix_fx( rot_md, sf_idx, band_idx, interp_yaw_pose_idx, interp_yaw_fact_fx, Q_yaw, mix_mat_re_fx, exp_mix_mat_re, mix_mat_im_fx, exp_mix_mat_im ); + + IF( NE_16( idx1, 0 ) ) + { + gd1_fx = rot_md[idx1 - 1][sf_idx][band_idx].gd_fx; // Q25 + } + + IF( NE_16( idx2, 0 ) ) + { + gd2_fx = rot_md[idx2 - 1][sf_idx][band_idx].gd_fx; + } + diff_fx = L_sub( gd1_fx, gd2_fx ); // Q25 + Word32 tmp1 = Mpy_32_32( diff_fx, interp_yaw_fact_fx ); // 6+Q_yaw + Word16 exp_tmp2 = 0; + Word32 tmp2 = BASOP_Util_Add_Mant32Exp( diff_fx, 31 - Q25, L_negate( tmp1 ), 6 + Q_yaw, &exp_tmp2 ); + *gd_int_fx = tmp2; + *exp_gd_int = exp_tmp2; + } + ELSE + { + /*P = P'*/ + FOR( ch_idx1 = 0; ch_idx1 < BINAURAL_CHANNELS; ch_idx1++ ) + { + FOR( Word16 j = 0; j < BINAURAL_CHANNELS; j++ ) + { + mix_mat_re_fx[ch_idx1][j] = 0; + mix_mat_im_fx[ch_idx1][j] = 0; + mix_mat_re_fx[ch_idx1][ch_idx1] = ONE_IN_Q25; + } + } + + *exp_mix_mat_re = 6; + *exp_mix_mat_im = 6; + + *gd_int_fx = 0; + *exp_gd_int = 0; + } + + idx1 = interp_pitch_pose_idx[0]; + idx2 = interp_pitch_pose_idx[1]; + IF( NE_16( idx1, 0 ) || NE_16( idx2, 0 ) ) + { + gd1_fx = ONE_IN_Q25; + gd2_fx = ONE_IN_Q25; + + gd3_fx = ONE_IN_Q25; + gd4_fx = ONE_IN_Q25; + + IF( NE_16( idx1, 0 ) ) + { + gd1_fx = rot_md[idx1 - 1][sf_idx][band_idx].gd_fx; + gd3_fx = rot_md[idx1 - 1][sf_idx][band_idx].gd2_fx; + } + IF( NE_16( idx2, 0 ) ) + { + gd2_fx = rot_md[idx2 - 1][sf_idx][band_idx].gd_fx; + gd4_fx = rot_md[idx2 - 1][sf_idx][band_idx].gd2_fx; + } + + diff_fx = L_sub( gd1_fx, gd2_fx ); // Q25 + IF( EQ_32( diff_fx, -1 ) ) + { + diff_fx = 0; + } + Word32 tmp = Mpy_32_32( diff_fx, interp_pitch_fact_fx ); // 6 + Q_pitch + Word16 exp_tmp1 = 0; + Word32 tmp1 = BASOP_Util_Add_Mant32Exp( gd1_fx, 31 - Q25, L_negate( tmp ), 6 + 31 - Q_pitch, &exp_tmp1 ); + pitch_gain_l_fx = tmp1; + pitch_gain_l_fx = max( 0, pitch_gain_l_fx ); + exp_pitch_gain_l = exp_tmp1; + + diff_fx = L_sub( gd3_fx, gd4_fx ); + IF( EQ_32( diff_fx, -1 ) ) + { + diff_fx = 0; + } + tmp = Mpy_32_32( diff_fx, interp_pitch_fact_fx ); + exp_tmp1 = 0; + tmp1 = BASOP_Util_Add_Mant32Exp( gd3_fx, 31 - Q25, L_negate( tmp ), 6 + 31 - Q_pitch, &exp_tmp1 ); + pitch_gain_r_fx = tmp1; + pitch_gain_r_fx = max( 0, pitch_gain_r_fx ); + exp_pitch_gain_r = exp_tmp1; + + FOR( ch_idx1 = 0; ch_idx1 < BINAURAL_CHANNELS; ch_idx1++ ) + { + mix_mat_re_fx[ch_idx1][0] = Mpy_32_32( mix_mat_re_fx[ch_idx1][0], pitch_gain_l_fx ); // exp_mix_mat_re + exp_pitch_gain_l + exp_mat_re[ch_idx1][0] = *exp_mix_mat_re + exp_pitch_gain_l; + mix_mat_re_fx[ch_idx1][1] = Mpy_32_32( mix_mat_re_fx[ch_idx1][1], pitch_gain_r_fx ); // exp_mix_mat_re + exp_pitch_gain_r + exp_mat_re[ch_idx1][1] = *exp_mix_mat_re + exp_pitch_gain_r; + mix_mat_im_fx[ch_idx1][0] = Mpy_32_32( mix_mat_im_fx[ch_idx1][0], pitch_gain_l_fx ); // exp_mix_mat_im + exp_pitch_gain_l + exp_mat_im[ch_idx1][0] = *exp_mix_mat_im + exp_pitch_gain_l; + mix_mat_im_fx[ch_idx1][1] = Mpy_32_32( mix_mat_im_fx[ch_idx1][1], pitch_gain_r_fx ); // exp_mix_mat_im + exp_pitch_gain_r + exp_mat_im[ch_idx1][1] = *exp_mix_mat_im + exp_pitch_gain_r; + } + + Word16 max_exp_re = MIN16B, max_exp_im = MIN16B; + FOR( Word16 i = 0; i < BINAURAL_CHANNELS; i++ ) + { + FOR( Word16 j = 0; j < BINAURAL_CHANNELS; j++ ) + { + max_exp_re = max( max_exp_re, exp_mat_re[i][j] ); + max_exp_im = max( max_exp_im, exp_mat_im[i][j] ); + } + } + + FOR( Word16 i = 0; i < BINAURAL_CHANNELS; i++ ) + { + FOR( Word16 j = 0; j < BINAURAL_CHANNELS; j++ ) + { + mix_mat_re_fx[i][j] = L_shr( mix_mat_re_fx[i][j], max_exp_re - exp_mat_re[i][j] ); + mix_mat_im_fx[i][j] = L_shr( mix_mat_im_fx[i][j], max_exp_im - exp_mat_im[i][j] ); + } + } + + *exp_mix_mat_re = max_exp_re; + *exp_mix_mat_im = max_exp_im; + } + ELSE + { + pitch_gain_l_fx = ONE_IN_Q25; + pitch_gain_r_fx = ONE_IN_Q25; + } + + + idx1 = interp_roll_pose_idx[0]; + idx2 = interp_roll_pose_idx[1]; + IF( NE_16( idx1, 0 ) || NE_16( idx2, 0 ) ) + { + interpolate_pred_matrix_fx( rot_md, sf_idx, band_idx, interp_roll_pose_idx, interp_roll_fact_fx, Q_roll, mix_mat_re3_fx, &exp_mix_mat_re3, mix_mat_im3_fx, &exp_mix_mat_im3 ); + + isar_mat_mult_2by2_complex_fx( mix_mat_re_fx, *exp_mix_mat_re, mix_mat_im_fx, *exp_mix_mat_im, mix_mat_re3_fx, exp_mix_mat_re3, + mix_mat_im3_fx, exp_mix_mat_im3, mix_mat_re1_fx, &exp_mix_mat_re1, mix_mat_im1_fx, &exp_mix_mat_im1 ); + + FOR( ch_idx1 = 0; ch_idx1 < BINAURAL_CHANNELS; ch_idx1++ ) + { + FOR( ch_idx2 = 0; ch_idx2 < BINAURAL_CHANNELS; ch_idx2++ ) + { + mix_mat_re_fx[ch_idx1][ch_idx2] = mix_mat_re1_fx[ch_idx1][ch_idx2]; + mix_mat_im_fx[ch_idx1][ch_idx2] = mix_mat_im1_fx[ch_idx1][ch_idx2]; + } + } + *exp_mix_mat_re = exp_mix_mat_re1; + *exp_mix_mat_im = exp_mix_mat_im1; + } + + return; +} + +/*-----------------------------------------------------------------------------------------* + * Function isar_SplitRenderer_PostRenderer() + * + * + *-----------------------------------------------------------------------------------------*/ +void isar_SplitRenderer_PostRenderer( + ISAR_BIN_HR_SPLIT_POST_REND_HANDLE hBinPostRenderer, /* i/o: binaural renderer handle */ + MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, + Word32 Cldfb_RealBuffer_Ref_Binaural_fx[][CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* i/o : Reference/out Binaural signals */ + Word32 Cldfb_ImagBuffer_Ref_Binaural_fx[][CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* i/o : Reference/out Binaural signals */ + const IVAS_QUATERNION Quaternion_act ) +{ + int16_t pos_idx, b, brange[2], ch_idx1; + int16_t num_md_bands, slot_idx, b2, index_slot, num_slots, sf_idx_md; + Word32 pred_out_re_fx[BINAURAL_CHANNELS], pred_out_im_fx[BINAURAL_CHANNELS], tmp_re_fx, tmp_im_fx, gd_int_fx; +#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG + ISAR_BIN_HR_SPLIT_REND_MD rot_md_act[MAX_HEAD_ROT_POSES][MAX_SPLIT_REND_MD_BANDS]; +#else + ISAR_BIN_HR_SPLIT_REND_MD rot_md_act[1][MAX_SPLIT_REND_MD_BANDS]; +#endif + int16_t interp_yaw_pose_idx[2], interp_pitch_pose_idx[2], interp_roll_pose_idx[2]; + Word32 interp_yaw_fact_fx, interp_pitch_fact_fx, interp_roll_fact_fx; + Word16 Q_yaw = Q31, Q_pitch = Q31, Q_roll = Q31; + Word32 mix_mat_re_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS]; + Word32 mix_mat_im_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS]; +#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG + float Cldfb_RealBuffer_Recons_Binaural[MAX_HEAD_ROT_POSES][BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX]; + float Cldfb_ImagBuffer_Recons_Binaural[MAX_HEAD_ROT_POSES][BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX]; +#endif + Word16 fade_fx; + Word32 *pMix_mat_re_prev_fx[BINAURAL_CHANNELS]; + Word32 *pMix_mat_im_prev_fx[BINAURAL_CHANNELS]; + const int16_t *pBand_grouping = isar_split_rend_band_grouping; + + num_md_bands = MAX_SPLIT_REND_MD_BANDS; + + push_wmops( "isar_SplitRenderer_PostRenderer" ); + + num_slots = MAX_PARAM_SPATIAL_SUBFRAMES; +#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG + pos_idx = MAX_HEAD_ROT_POSES - 1; +#else + pos_idx = 0; +#endif + + sf_idx_md = 0; + + get_interpolation_vars( pMultiBinPoseData, &hBinPostRenderer->QuaternionsPre[sf_idx_md], &Quaternion_act, interp_yaw_pose_idx, interp_pitch_pose_idx, interp_roll_pose_idx, &interp_yaw_fact_fx, &interp_pitch_fact_fx, &interp_roll_fact_fx, &Q_yaw, &Q_pitch, &Q_roll ); + + FOR( b = 0; b < num_md_bands; b++ ) + { + FOR( ch_idx1 = 0; ch_idx1 < BINAURAL_CHANNELS; ch_idx1++ ) + { + set_l( mix_mat_re_fx[ch_idx1], 0, BINAURAL_CHANNELS ); + set_l( mix_mat_im_fx[ch_idx1], 0, BINAURAL_CHANNELS ); + mix_mat_re_fx[ch_idx1][ch_idx1] = L_shl( 1, Q25 ); + } + + Word16 exp_gd_int = 0; + + Word16 exp_mix_mat_re = 6, exp_mix_mat_im = 6; + + interpolate_rend_md_fx( hBinPostRenderer->rot_md, mix_mat_re_fx, &exp_mix_mat_re, mix_mat_im_fx, &exp_mix_mat_im, &gd_int_fx, &exp_gd_int, sf_idx_md, b, interp_yaw_pose_idx, + interp_pitch_pose_idx, interp_roll_pose_idx, interp_yaw_fact_fx, Q_yaw, interp_pitch_fact_fx, Q_pitch, interp_roll_fact_fx, Q_roll ); + + FOR( ch_idx1 = 0; ch_idx1 < BINAURAL_CHANNELS; ch_idx1++ ) + { + /*update the prediction matrix with interpolated matrix*/ + rot_md_act[pos_idx][b].pred_mat_re_fx[ch_idx1][0] = L_shl( mix_mat_re_fx[ch_idx1][0], exp_mix_mat_re - 6 ); // Q25 + rot_md_act[pos_idx][b].pred_mat_re_fx[ch_idx1][1] = L_shl( mix_mat_re_fx[ch_idx1][1], exp_mix_mat_re - 6 ); // Q25 + rot_md_act[pos_idx][b].pred_mat_im_fx[ch_idx1][0] = L_shl( mix_mat_im_fx[ch_idx1][0], exp_mix_mat_im - 6 ); // Q25 + rot_md_act[pos_idx][b].pred_mat_im_fx[ch_idx1][1] = L_shl( mix_mat_im_fx[ch_idx1][1], exp_mix_mat_im - 6 ); // Q25 + rot_md_act[pos_idx][b].gd_fx = L_shl( gd_int_fx, exp_gd_int - 6 ); // Q25 + } + } + + +#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG + for ( pos_idx = 0; pos_idx < MAX_HEAD_ROT_POSES - 1; pos_idx++ ) + { + for ( b = 0; b < num_md_bands; b++ ) + { + if ( hBinPostRenderer->pose_type[pos_idx] == PITCH_ONLY ) + { + + for ( ch_idx1 = 0; ch_idx1 < BINAURAL_CHANNELS; ch_idx1++ ) + { + set_zero( hBinPostRenderer->rot_md[pos_idx][sf_idx][b].pred_mat_re[ch_idx1], BINAURAL_CHANNELS ); + set_zero( hBinPostRenderer->rot_md[pos_idx][sf_idx][b].pred_mat_im[ch_idx1], BINAURAL_CHANNELS ); + hBinPostRenderer->rot_md[pos_idx][sf_idx][b].pred_mat_re[ch_idx1][ch_idx1] = 1.0f; + } + hBinPostRenderer->rot_md[pos_idx][sf_idx][b].pred_mat_re[0][0] *= hBinPostRenderer->rot_md[pos_idx][sf_idx][b].gd; + hBinPostRenderer->rot_md[pos_idx][sf_idx][b].pred_mat_re[1][1] *= hBinPostRenderer->rot_md[pos_idx][sf_idx][b].gd2; + hBinPostRenderer->rot_md[pos_idx][sf_idx][b].gd = 0.0f; + } + else if ( hBinPostRenderer->pose_type[pos_idx] == ANY_ROLL ) + { + hBinPostRenderer->rot_md[pos_idx][sf_idx][b].gd = 0.0f; + } + + for ( ch_idx1 = 0; ch_idx1 < BINAURAL_CHANNELS; ch_idx1++ ) + { + + /*update the prediction matrix with interpolated matrix*/ + rot_md_act[pos_idx][b].pred_mat_re[ch_idx1][0] = hBinPostRenderer->rot_md[pos_idx][sf_idx][b].pred_mat_re[ch_idx1][0]; + rot_md_act[pos_idx][b].pred_mat_re[ch_idx1][1] = hBinPostRenderer->rot_md[pos_idx][sf_idx][b].pred_mat_re[ch_idx1][1]; + rot_md_act[pos_idx][b].pred_mat_im[ch_idx1][0] = hBinPostRenderer->rot_md[pos_idx][sf_idx][b].pred_mat_im[ch_idx1][0]; + rot_md_act[pos_idx][b].pred_mat_im[ch_idx1][1] = hBinPostRenderer->rot_md[pos_idx][sf_idx][b].pred_mat_im[ch_idx1][1]; + rot_md_act[pos_idx][b].gd = hBinPostRenderer->rot_md[pos_idx][sf_idx][b].gd; + } + } + } + +#endif + +#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG + for ( pos_idx = 0; pos_idx < MAX_HEAD_ROT_POSES; pos_idx++ ) +#else + pos_idx = 0; +#endif + { + FOR( slot_idx = 0; slot_idx < num_slots; slot_idx++ ) + { + index_slot = slot_idx; /* TODO: can be cleaned up */ + fade_fx = fade_table_fx[slot_idx]; + fade_fx = min( fade_fx, MAX_16 ); + FOR( b = 0; b < num_md_bands; b++ ) + { + FOR( ch_idx1 = 0; ch_idx1 < BINAURAL_CHANNELS; ch_idx1++ ) + { + IF( hBinPostRenderer->cf_flag ) + { + pMix_mat_re_prev_fx[ch_idx1] = hBinPostRenderer->mixer_mat_re_fx[pos_idx][b][ch_idx1]; + pMix_mat_im_prev_fx[ch_idx1] = hBinPostRenderer->mixer_mat_im_fx[pos_idx][b][ch_idx1]; + mix_mat_re_fx[ch_idx1][0] = L_add( Mpy_32_16_1( rot_md_act[pos_idx][b].pred_mat_re_fx[ch_idx1][0], fade_fx ), + Mpy_32_16_1( pMix_mat_re_prev_fx[ch_idx1][0], sub( 32767, fade_fx ) ) ); + mix_mat_re_fx[ch_idx1][1] = L_add( Mpy_32_16_1( rot_md_act[pos_idx][b].pred_mat_re_fx[ch_idx1][1], fade_fx ), + Mpy_32_16_1( pMix_mat_re_prev_fx[ch_idx1][1], sub( 32767, fade_fx ) ) ); + + mix_mat_im_fx[ch_idx1][0] = L_add( Mpy_32_16_1( rot_md_act[pos_idx][b].pred_mat_im_fx[ch_idx1][0], fade_fx ), + Mpy_32_16_1( pMix_mat_im_prev_fx[ch_idx1][0], sub( 32767, fade_fx ) ) ); + mix_mat_im_fx[ch_idx1][1] = L_add( Mpy_32_16_1( rot_md_act[pos_idx][b].pred_mat_im_fx[ch_idx1][1], fade_fx ), + Mpy_32_16_1( pMix_mat_im_prev_fx[ch_idx1][1], sub( 32767, fade_fx ) ) ); + } + ELSE + { + mix_mat_re_fx[ch_idx1][0] = rot_md_act[pos_idx][b].pred_mat_re_fx[ch_idx1][0]; + mix_mat_re_fx[ch_idx1][1] = rot_md_act[pos_idx][b].pred_mat_re_fx[ch_idx1][1]; + mix_mat_im_fx[ch_idx1][0] = rot_md_act[pos_idx][b].pred_mat_im_fx[ch_idx1][0]; + mix_mat_im_fx[ch_idx1][1] = rot_md_act[pos_idx][b].pred_mat_im_fx[ch_idx1][1]; + } + } + + brange[0] = pBand_grouping[b]; + brange[1] = pBand_grouping[b + 1]; + Word16 exp_tmp1, exp_tmp2; + FOR( b2 = brange[0]; b2 < brange[1]; b2++ ) + { + FOR( ch_idx1 = 0; ch_idx1 < BINAURAL_CHANNELS; ch_idx1++ ) + { + /* Apply prediction matrix */ + ivas_cmult_fix( Cldfb_RealBuffer_Ref_Binaural_fx[0][index_slot][b2], 25, Cldfb_ImagBuffer_Ref_Binaural_fx[0][index_slot][b2], 25, mix_mat_re_fx[0][ch_idx1], 6, mix_mat_im_fx[0][ch_idx1], 6, &tmp_re_fx, &tmp_im_fx, &exp_tmp1, &exp_tmp2 ); + // tmp_re_fx = L_shl(tmp_re_fx, sub(exp_tmp1, 6)); //Q25 + // tmp_im_fx = L_shl(tmp_im_fx, sub(exp_tmp1, 6)); //Q25 + + pred_out_re_fx[ch_idx1] = tmp_re_fx; + pred_out_im_fx[ch_idx1] = tmp_im_fx; + Word16 exp_re = exp_tmp1; + Word16 exp_im = exp_tmp2; + + ivas_cmult_fix( Cldfb_RealBuffer_Ref_Binaural_fx[1][index_slot][b2], 25, Cldfb_ImagBuffer_Ref_Binaural_fx[1][index_slot][b2], 25, mix_mat_re_fx[1][ch_idx1], 6, mix_mat_im_fx[1][ch_idx1], 6, &tmp_re_fx, &tmp_im_fx, &exp_tmp1, &exp_tmp2 ); + // tmp_re_fx = L_shl(tmp_re_fx, sub(exp_tmp1, 6)); //Q25 + // tmp_im_fx = L_shl(tmp_im_fx, sub(exp_tmp1, 6)); //Q25 + + pred_out_re_fx[ch_idx1] = BASOP_Util_Add_Mant32Exp( pred_out_re_fx[ch_idx1], exp_re, tmp_re_fx, exp_tmp1, &exp_re ); + pred_out_re_fx[ch_idx1] = L_shl( pred_out_re_fx[ch_idx1], exp_re - 25 ); + pred_out_im_fx[ch_idx1] = BASOP_Util_Add_Mant32Exp( pred_out_im_fx[ch_idx1], exp_im, tmp_im_fx, exp_tmp2, &exp_im ); + pred_out_im_fx[ch_idx1] = L_shl( pred_out_im_fx[ch_idx1], exp_im - 25 ); + } + + + FOR( ch_idx1 = 0; ch_idx1 < BINAURAL_CHANNELS; ch_idx1++ ) + { +#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG + Cldfb_RealBuffer_Recons_Binaural[pos_idx][ch_idx1][index_slot][b2] = pred_out_re[ch_idx1]; + Cldfb_ImagBuffer_Recons_Binaural[pos_idx][ch_idx1][index_slot][b2] = pred_out_im[ch_idx1]; +#else + Cldfb_RealBuffer_Ref_Binaural_fx[ch_idx1][index_slot][b2] = pred_out_re_fx[ch_idx1]; + Cldfb_ImagBuffer_Ref_Binaural_fx[ch_idx1][index_slot][b2] = pred_out_im_fx[ch_idx1]; +#endif + } + } + } + } + } + +#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG + for ( pos_idx = 0; pos_idx < MAX_HEAD_ROT_POSES; pos_idx++ ) +#else + pos_idx = 0; +#endif + { + FOR( b = 0; b < num_md_bands; b++ ) + { + FOR( ch_idx1 = 0; ch_idx1 < BINAURAL_CHANNELS; ch_idx1++ ) + { + hBinPostRenderer->mixer_mat_re_fx[pos_idx][b][ch_idx1][0] = rot_md_act[pos_idx][b].pred_mat_re_fx[ch_idx1][0]; // Q25 + hBinPostRenderer->mixer_mat_re_fx[pos_idx][b][ch_idx1][1] = rot_md_act[pos_idx][b].pred_mat_re_fx[ch_idx1][1]; // Q25 + hBinPostRenderer->mixer_mat_im_fx[pos_idx][b][ch_idx1][0] = rot_md_act[pos_idx][b].pred_mat_im_fx[ch_idx1][0]; // Q25 + hBinPostRenderer->mixer_mat_im_fx[pos_idx][b][ch_idx1][1] = rot_md_act[pos_idx][b].pred_mat_im_fx[ch_idx1][1]; // Q25 + } + hBinPostRenderer->gd_mem_fx[pos_idx][b] = rot_md_act[pos_idx][b].gd_fx; // Q25 + } + } + hBinPostRenderer->cf_flag = 1; + +#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG + { + int16_t num_cldfb_bands; + num_cldfb_bands = CLDFB_NO_CHANNELS_MAX; + for ( slot_idx = 0; slot_idx < num_slots; slot_idx++ ) + { + index_slot = sf_idx * num_slots + slot_idx; + for ( ch_idx1 = 0; ch_idx1 < BINAURAL_CHANNELS; ch_idx1++ ) + { + mvr2r( Cldfb_RealBuffer_Recons_Binaural[MAX_HEAD_ROT_POSES - 1][ch_idx1][index_slot], Cldfb_RealBuffer_Ref_Binaural[ch_idx1][index_slot], num_cldfb_bands ); + mvr2r( Cldfb_ImagBuffer_Recons_Binaural[MAX_HEAD_ROT_POSES - 1][ch_idx1][index_slot], Cldfb_ImagBuffer_Ref_Binaural[ch_idx1][index_slot], num_cldfb_bands ); + } + } + + for ( pos_idx = 0; pos_idx < MAX_HEAD_ROT_POSES; pos_idx++ ) + { + char fname[200] = "recons_out_pos"; + char tag[2]; + tag[0] = (char) ( '0' + pos_idx ); + tag[1] = '\0'; + strcat( fname, tag ); + strcat( fname, ".wav" ); + isar_log_cldfb2wav_data( + Cldfb_RealBuffer_Recons_Binaural[pos_idx], + Cldfb_ImagBuffer_Recons_Binaural[pos_idx], + hBinPostRenderer->cldfbSynReconsBinDec[pos_idx], + BINAURAL_CHANNELS, + num_cldfb_bands, + 48000, + num_slots, + sf_idx * num_slots, + fname ); + } + } +#endif + + pop_wmops(); + return; +} + +/*-----------------------------------------------------------------------------------------* + * Function isar_rend_CldfbSplitPostRendProcessTdIn() + * + * + *-----------------------------------------------------------------------------------------*/ +static void isar_rend_CldfbSplitPostRendProcessTdIn( + ISAR_BIN_HR_SPLIT_POST_REND_HANDLE hBinHrSplitPostRend, + MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, + const IVAS_QUATERNION QuaternionPost, + Word32 output_fx[][L_FRAME48k], + Word16 *Q_out ) +{ + int16_t ch_idx, slot_idx, num_cldfb_bands; + Word32 Cldfb_RealBuffer_Binaural_fx[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX] = { 0 }; + Word32 Cldfb_ImagBuffer_Binaural_fx[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX] = { 0 }; + num_cldfb_bands = hBinHrSplitPostRend->cldfbSyn[0]->no_channels; + Word16 Q_output = 11; + + /* Implement CLDFB analysis */ + FOR( ch_idx = 0; ch_idx < BINAURAL_CHANNELS; ch_idx++ ) + { + Scale_sig32( output_fx[ch_idx], L_FRAME48k, Q_output - Q_out[ch_idx] ); + FOR( slot_idx = 0; slot_idx < CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES; slot_idx++ ) + { + Word16 Q_cldfb = Q_output; + cldfbAnalysis_ts_fx_fixed_q( &( output_fx[ch_idx][num_cldfb_bands * slot_idx] ), + Cldfb_RealBuffer_Binaural_fx[ch_idx][slot_idx], + Cldfb_ImagBuffer_Binaural_fx[ch_idx][slot_idx], + num_cldfb_bands, + hBinHrSplitPostRend->cldfbAna[ch_idx], + &Q_cldfb ); // Q_cldfb - 5 + } + } + + isar_SplitRenderer_PostRenderer( hBinHrSplitPostRend, pMultiBinPoseData, Cldfb_RealBuffer_Binaural_fx, Cldfb_ImagBuffer_Binaural_fx, QuaternionPost ); + + /* Implement CLDFB synthesis */ + FOR( ch_idx = 0; ch_idx < BINAURAL_CHANNELS; ch_idx++ ) + { + Word32 *RealBuffer_fx[CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES]; + Word32 *ImagBuffer_fx[CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES]; + Word16 scaleFactor = 31, Q_cldfb; + + FOR( slot_idx = 0; slot_idx < CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES; slot_idx++ ) + { + RealBuffer_fx[slot_idx] = Cldfb_RealBuffer_Binaural_fx[ch_idx][slot_idx]; + ImagBuffer_fx[slot_idx] = Cldfb_ImagBuffer_Binaural_fx[ch_idx][slot_idx]; + scaleFactor = s_min( scaleFactor, s_min( getScaleFactor32( RealBuffer_fx[slot_idx], CLDFB_NO_CHANNELS_MAX ), getScaleFactor32( ImagBuffer_fx[slot_idx], CLDFB_NO_CHANNELS_MAX ) ) ); + } + + scaleFactor = s_min( sub( scaleFactor, 3 ), Q24 ); // guarded bits + FOR( slot_idx = 0; slot_idx < CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES; slot_idx++ ) + { + Scale_sig32( RealBuffer_fx[slot_idx], CLDFB_NO_CHANNELS_MAX, scaleFactor ); + Scale_sig32( ImagBuffer_fx[slot_idx], CLDFB_NO_CHANNELS_MAX, scaleFactor ); + } + Q_cldfb = add( scaleFactor, sub( Q_output, Q5 ) ); + Scale_sig32( hBinHrSplitPostRend->cldfbSyn[ch_idx]->cldfb_state_fx, hBinHrSplitPostRend->cldfbSyn[ch_idx]->p_filter_length, sub( sub( Q_cldfb, 1 ), Q11 ) ); + cldfbSynthesis_ivas_fx( RealBuffer_fx, ImagBuffer_fx, &( output_fx[ch_idx][0] ), num_cldfb_bands * CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES, hBinHrSplitPostRend->cldfbSyn[ch_idx] ); // Q_cldfb - 1 + Scale_sig32( hBinHrSplitPostRend->cldfbSyn[ch_idx]->cldfb_state_fx, hBinHrSplitPostRend->cldfbSyn[ch_idx]->p_filter_length, sub( Q11, sub( Q_cldfb, 1 ) ) ); + Q_out[ch_idx] = sub( Q_cldfb, 1 ); + } + + return; +} +/*-----------------------------------------------------------------------------------------* + * Function isar_rend_CldfbSplitPostRendProcess() + * + * + *-----------------------------------------------------------------------------------------*/ +void isar_rend_CldfbSplitPostRendProcess( + ISAR_BIN_HR_SPLIT_POST_REND_HANDLE hBinHrSplitPostRend, + MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, + const IVAS_QUATERNION QuaternionPost, + Word32 Cldfb_RealBuffer_Binaural_fx[][CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], + Word32 Cldfb_ImagBuffer_Binaural_fx[][CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], + Word16 Q_cldfb_in, + Word32 output_fx[][L_FRAME48k], + Word16 *Q_out, + const Word16 cldfb_in_flag ) +{ + int16_t ch_idx, slot_idx, num_cldfb_bands; + + push_wmops( "isar_rend_CldfbSplitPostRendProcess" ); + + num_cldfb_bands = hBinHrSplitPostRend->cldfbSyn[0]->no_channels; + + IF( EQ_16( cldfb_in_flag, 0 ) ) + { + isar_rend_CldfbSplitPostRendProcessTdIn( hBinHrSplitPostRend, pMultiBinPoseData, QuaternionPost, output_fx, Q_out ); + pop_wmops(); + return; + } + + isar_SplitRenderer_PostRenderer( hBinHrSplitPostRend, pMultiBinPoseData, Cldfb_RealBuffer_Binaural_fx, Cldfb_ImagBuffer_Binaural_fx, QuaternionPost ); + + /* Implement CLDFB synthesis */ + FOR( ch_idx = 0; ch_idx < BINAURAL_CHANNELS; ch_idx++ ) + { + Word32 *RealBuffer_fx[CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES]; + Word32 *ImagBuffer_fx[CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES]; + Word16 scaleFactor = 31, Q_cldfb; + + FOR( slot_idx = 0; slot_idx < CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES; slot_idx++ ) + { + RealBuffer_fx[slot_idx] = Cldfb_RealBuffer_Binaural_fx[ch_idx][slot_idx]; + ImagBuffer_fx[slot_idx] = Cldfb_ImagBuffer_Binaural_fx[ch_idx][slot_idx]; + scaleFactor = s_min( scaleFactor, s_min( getScaleFactor32( RealBuffer_fx[slot_idx], CLDFB_NO_CHANNELS_MAX ), getScaleFactor32( ImagBuffer_fx[slot_idx], CLDFB_NO_CHANNELS_MAX ) ) ); + } + + scaleFactor = s_min( sub( scaleFactor, 3 ), Q24 ); // guarded bits + FOR( slot_idx = 0; slot_idx < CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES; slot_idx++ ) + { + Scale_sig32( RealBuffer_fx[slot_idx], CLDFB_NO_CHANNELS_MAX, scaleFactor ); + Scale_sig32( ImagBuffer_fx[slot_idx], CLDFB_NO_CHANNELS_MAX, scaleFactor ); + } + Q_cldfb = scaleFactor + Q_cldfb_in; + Scale_sig32( hBinHrSplitPostRend->cldfbSyn[ch_idx]->cldfb_state_fx, hBinHrSplitPostRend->cldfbSyn[ch_idx]->p_filter_length, sub( sub( Q_cldfb, 1 ), Q11 ) ); + cldfbSynthesis_ivas_fx( RealBuffer_fx, ImagBuffer_fx, &( output_fx[ch_idx][0] ), num_cldfb_bands * CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES, hBinHrSplitPostRend->cldfbSyn[ch_idx] ); // Q_cldfb - 1 + Scale_sig32( hBinHrSplitPostRend->cldfbSyn[ch_idx]->cldfb_state_fx, hBinHrSplitPostRend->cldfbSyn[ch_idx]->p_filter_length, sub( Q11, sub( Q_cldfb, 1 ) ) ); + Q_out[ch_idx] = sub( Q_cldfb, 1 ); + } + + pop_wmops(); + return; +} + +/*-----------------------------------------------------------------------------------------* + * Function isar_init_split_post_rend_handles() + * + * + *-----------------------------------------------------------------------------------------*/ + +void isar_init_split_post_rend_handles( + ISAR_SPLIT_POST_REND_WRAPPER *hSplitRendWrapper ) +{ + hSplitRendWrapper->hBinHrSplitPostRend = NULL; + hSplitRendWrapper->hSplitBinLCLDDec = NULL; + hSplitRendWrapper->hLc3plusDec = NULL; + isar_init_multi_bin_pose_data_fx( &hSplitRendWrapper->multiBinPoseData ); + hSplitRendWrapper->first_good_frame_received = 0; + + return; +} + +#endif diff --git a/lib_isar/isar_splitRendererPre.c b/lib_isar/isar_splitRendererPre.c new file mode 100644 index 0000000000000000000000000000000000000000..0d2515e35b1f24d9d670a93017fcc03183db961a --- /dev/null +++ b/lib_isar/isar_splitRendererPre.c @@ -0,0 +1,3449 @@ +/****************************************************************************************************** + + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository. All Rights Reserved. + + This software is protected by copyright law and by international treaties. + The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository retain full ownership rights in their respective contributions in + the software. This notice grants no license of any kind, including but not limited to patent + license, nor is any license granted by implication, estoppel or otherwise. + + Contributors are required to enter into the IVAS codec Public Collaboration agreement before making + contributions. + + This software is provided "AS IS", without any express or implied warranties. The software is in the + development stage. It is intended exclusively for experts who have experience with such software and + solely for the purpose of inspection. All implied warranties of non-infringement, merchantability + and fitness for a particular purpose are hereby disclaimed and excluded. + + Any dispute, controversy or claim arising under or in relation to providing this software shall be + submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in + accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and + the United Nations Convention on Contracts on the International Sales of Goods. + +*******************************************************************************************************/ + +#include +#include "options.h" +#ifdef SPLIT_REND_WITH_HEAD_ROT +#include +#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG +#include +#endif +#include "ivas_prot_fx.h" +#include "prot_fx.h" +#include "lib_isar_pre_rend.h" +#include "isar_rom_post_rend.h" +#include "isar_prot.h" +#ifdef DEBUGGING +#include "debug.h" +#endif +#include "wmc_auto.h" +#ifdef DBG_WAV_WRITER +#include "string.h" +#endif +#include "prot_fx.h" +#include "basop_util.h" + +/*---------------------------------------------------------------------* + * Local function declarations + *---------------------------------------------------------------------*/ +static void isar_SplitRenderer_GetRotMd_fx( + ISAR_BIN_HR_SPLIT_PRE_REND_HANDLE hBinHrSplitPreRend, /* i/o: binaural renderer handle */ + MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, + Word32 Cldfb_RealBuffer_Ref_Binaural_fx[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], /* o : Reference Binaural signals */ + Word16 exp_cldfb_re, + Word32 Cldfb_ImagBuffer_Ref_Binaural_fx[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], /* o : Reference Binaural signals */ + Word16 exp_cldfb_im, + const Word16 low_res, + const Word16 ro_md_flag ); + +/*------------------------------------------------------------------------- + * Local functions + * + * + *------------------------------------------------------------------------*/ + +static void isar_calc_mat_det_2by2_complex_fx( + Word32 in_re_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], + Word16 exp_in_re, + Word32 in_im_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], + Word16 exp_in_im, + Word32 *det_re, + Word16 *exp_det_re, + Word32 *det_im, + Word16 *exp_det_im ) +{ + Word32 re1_fx, im1_fx, re2_fx, im2_fx; + + Word16 exp_re_1 = 0, exp_re_2 = 0; + Word16 exp_im_1 = 0, exp_im_2 = 0; + ivas_cmult_fix( in_re_fx[0][0], exp_in_re, in_im_fx[0][0], exp_in_im, in_re_fx[1][1], exp_in_re, in_im_fx[1][1], exp_in_im, &re1_fx, &im1_fx, &exp_re_1, &exp_im_1 ); + ivas_cmult_fix( in_re_fx[0][1], exp_in_re, in_im_fx[0][1], exp_in_im, in_re_fx[1][0], exp_in_re, in_im_fx[1][0], exp_in_im, &re2_fx, &im2_fx, &exp_re_2, &exp_im_2 ); + + Word16 exp_re_final = 0, exp_im_final = 0; + *det_re = BASOP_Util_Add_Mant32Exp( re1_fx, exp_re_1, L_negate( re2_fx ), exp_re_2, &exp_re_final ); + *det_im = BASOP_Util_Add_Mant32Exp( im1_fx, exp_im_1, L_negate( im2_fx ), exp_im_2, &exp_im_final ); + *exp_det_re = exp_re_final; + *exp_det_im = exp_im_final; + + return; +} + +static Word16 isar_is_mat_inv_2by2_complex_fx( + Word32 in_re[BINAURAL_CHANNELS][BINAURAL_CHANNELS], + Word16 exp_in_re, + Word32 in_im[BINAURAL_CHANNELS][BINAURAL_CHANNELS], + Word16 exp_in_im ) +{ + Word16 is_det_zero = 1; + Word32 det, det_re, det_im; + Word16 exp_det = 0, exp_det_re = 0, exp_det_im = 0; + isar_calc_mat_det_2by2_complex_fx( in_re, exp_in_re, in_im, exp_in_im, &det_re, &exp_det_re, &det_im, &exp_det_im ); + + Word64 det_re_sq = W_mult_32_32( det_re, det_re ); + Word16 det_sq_re_nrm = W_norm( det_re_sq ); + Word32 tmp1 = W_extract_h( W_shl( det_re_sq, det_sq_re_nrm ) ); + + Word64 det_im_sq = W_mult_32_32( det_im, det_im ); + Word16 det_im_nrm = W_norm( det_im_sq ); + Word32 tmp2 = W_extract_h( W_shl( det_im_sq, det_im_nrm ) ); + + det = BASOP_Util_Add_Mant32Exp( tmp1, exp_det_re + exp_det_re - det_sq_re_nrm, tmp2, exp_det_im + exp_det_im - det_im_nrm, &exp_det ); + + Word16 res = BASOP_Util_Cmp_Mant32Exp( det, exp_det, EPSILON_FX, 31 ); + IF( EQ_16( res, -1 ) ) + { + is_det_zero = 0; + } + + return is_det_zero; +} +static void isar_calc_mat_inv_2by2_complex_fx( + Word32 in_re_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], + Word16 exp_in_re, + Word32 in_im_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], + Word16 exp_in_im, + Word32 out_re_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], + Word16 *exp_out_re, + Word32 out_im_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], + Word16 *exp_out_im ) +{ + Word16 exp_buffer_re[BINAURAL_CHANNELS][BINAURAL_CHANNELS], exp_buffer_im[BINAURAL_CHANNELS][BINAURAL_CHANNELS]; + + FOR( int i = 0; i < BINAURAL_CHANNELS; i++ ) + { + FOR( int j = 0; j < BINAURAL_CHANNELS; j++ ) + { + exp_buffer_re[i][j] = MIN16B; + move16(); + exp_buffer_im[i][j] = MIN16B; + move16(); + } + } + Word32 det_re_fx, det_im_fx; + Word16 exp_det_re = 0, exp_det_im = 0; + move16(); + move16(); + Word32 re_fx, im_fx, det_fx; + Word16 exp_re = 0, exp_im = 0; + move16(); + move16(); + + isar_calc_mat_det_2by2_complex_fx( in_re_fx, exp_in_re, in_im_fx, exp_in_im, &det_re_fx, &exp_det_re, &det_im_fx, &exp_det_im ); + + Word16 tmp1 = W_norm( W_mult_32_32( det_re_fx, det_re_fx ) ); + Word32 tmp2 = W_extract_h( W_shl( W_mult_32_32( det_re_fx, det_re_fx ), tmp1 ) ); // 2*exp_det_re - tmp1 + Word16 tmp3 = W_norm( W_mult_32_32( det_im_fx, det_im_fx ) ); + Word32 tmp4 = W_extract_h( W_shl( W_mult_32_32( det_im_fx, det_im_fx ), tmp3 ) ); // 2*exp_im_re - tmp3 + Word16 exp_det = 0; + det_fx = BASOP_Util_Add_Mant32Exp( tmp2, 2 * exp_det_re - tmp1, tmp4, 2 * exp_det_im - tmp3, &exp_det ); + + Word16 exp_tmp5 = 0; + Word16 tmp5 = BASOP_Util_Divide3232_Scale( ONE_IN_Q30, det_fx, &exp_tmp5 ); + exp_det = add( exp_tmp5, sub( 1, exp_det ) ); + det_fx = L_deposit_h( tmp5 ); + +#ifdef DEBUGGING + /* assert to catch cases when input is singular matrix */ + assert( GT_32( det_fx, 0 ) ); +#endif + + exp_re = 0; + exp_im = 0; + move16(); + move16(); + ivas_cmult_fix( det_re_fx, exp_det_re, L_negate( det_im_fx ), exp_det_im, in_re_fx[1][1], exp_in_re, in_im_fx[1][1], exp_in_im, &re_fx, &im_fx, &exp_re, &exp_im ); + + Word64 tmp7 = W_mult_32_32( re_fx, det_fx ); + Word16 tmp7_nrm = W_norm( tmp7 ); + out_re_fx[0][0] = W_extract_h( W_shl( tmp7, tmp7_nrm ) ); // exp_re + exp_det - tmp7_nrm + move32(); + Word64 tmp8 = W_mult_32_32( im_fx, det_fx ); + Word16 tmp8_nrm = W_norm( tmp8 ); + out_im_fx[0][0] = W_extract_h( W_shl( tmp8, tmp8_nrm ) ); // exp_im + exp_det - tmp8_nrm + move32(); + + exp_buffer_re[0][0] = add( exp_re, sub( exp_det, tmp7_nrm ) ); + move16(); + exp_buffer_im[0][0] = add( exp_im, sub( exp_det, tmp8_nrm ) ); + move16(); + + ivas_cmult_fix( det_re_fx, exp_det_re, L_negate( det_im_fx ), exp_det_im, in_re_fx[0][1], exp_in_re, in_im_fx[0][1], exp_in_im, &re_fx, &im_fx, &exp_re, &exp_im ); + + Word64 tmp9 = W_mult_32_32( L_negate( re_fx ), det_fx ); + Word16 tmp9_nrm = W_norm( tmp9 ); + out_re_fx[0][1] = W_extract_h( W_shl( tmp9, tmp9_nrm ) ); + Word64 tmp10 = W_mult_32_32( L_negate( im_fx ), det_fx ); + Word16 tmp10_nrm = W_norm( tmp10 ); + out_im_fx[0][1] = W_extract_h( W_shl( tmp10, tmp10_nrm ) ); + + exp_buffer_re[0][1] = add( exp_re, sub( exp_det, tmp9_nrm ) ); + exp_buffer_im[0][1] = add( exp_im, sub( exp_det, tmp10_nrm ) ); + + ivas_cmult_fix( det_re_fx, exp_det_re, L_negate( det_im_fx ), exp_det_im, in_re_fx[1][0], exp_in_re, in_im_fx[1][0], exp_in_im, &re_fx, &im_fx, &exp_re, &exp_im ); + + + Word64 tmp11 = W_mult_32_32( L_negate( re_fx ), det_fx ); + Word16 tmp11_nrm = W_norm( tmp11 ); + out_re_fx[1][0] = W_extract_h( W_shl( tmp11, tmp11_nrm ) ); + Word64 tmp12 = W_mult_32_32( L_negate( im_fx ), det_fx ); + Word16 tmp12_nrm = W_norm( tmp12 ); + out_im_fx[1][0] = W_extract_h( W_shl( tmp12, tmp12_nrm ) ); + + exp_buffer_re[1][0] = add( exp_re, sub( exp_det, tmp11_nrm ) ); + move16(); + exp_buffer_im[1][0] = add( exp_im, sub( exp_det, tmp12_nrm ) ); + move16(); + + ivas_cmult_fix( det_re_fx, exp_det_re, L_negate( det_im_fx ), exp_det_im, in_re_fx[0][0], exp_in_re, in_im_fx[0][0], exp_in_im, &re_fx, &im_fx, &exp_re, &exp_im ); + + Word64 tmp13 = W_mult_32_32( re_fx, det_fx ); + Word16 tmp13_nrm = W_norm( tmp13 ); + out_re_fx[1][1] = W_extract_h( W_shl( tmp13, tmp13_nrm ) ); + move32(); + + Word64 tmp14 = W_mult_32_32( im_fx, det_fx ); + Word16 tmp14_nrm = W_norm( tmp14 ); + out_im_fx[1][1] = W_extract_h( W_shl( tmp14, tmp14_nrm ) ); + move32(); + + exp_buffer_re[1][1] = add( exp_re, sub( exp_det, tmp13_nrm ) ); + move16(); + exp_buffer_im[1][1] = add( exp_im, sub( exp_det, tmp14_nrm ) ); + move16(); + + Word16 max_exp_re = MIN16B, max_exp_im = MIN16B; + FOR( int i = 0; i < BINAURAL_CHANNELS; i++ ) + { + FOR( int j = 0; j < BINAURAL_CHANNELS; j++ ) + { + max_exp_re = s_max( max_exp_re, exp_buffer_re[i][j] ); + max_exp_im = s_max( max_exp_im, exp_buffer_im[i][j] ); + } + } + + FOR( int i = 0; i < BINAURAL_CHANNELS; i++ ) + { + FOR( int j = 0; j < BINAURAL_CHANNELS; j++ ) + { + out_re_fx[i][j] = L_shr( out_re_fx[i][j], max_exp_re - exp_buffer_re[i][j] ); + move32(); + out_im_fx[i][j] = L_shr( out_im_fx[i][j], max_exp_im - exp_buffer_im[i][j] ); + move32(); + } + } + + *exp_out_re = max_exp_re; + move16(); + *exp_out_im = max_exp_im; + move16(); + + return; +} +static void ComputePredMat_fx( + Word32 cov_ii_re_fx[][BINAURAL_CHANNELS], + Word16 exp_cov_ii_re, + Word32 cov_ii_im_fx[][BINAURAL_CHANNELS], + Word16 exp_cov_ii_im, + Word32 cov_io_re_fx[][BINAURAL_CHANNELS], + Word16 exp_cov_io_re, + Word32 cov_io_im_fx[][BINAURAL_CHANNELS], + Word16 exp_cov_io_im, + Word32 pred_mat_re_fx[][BINAURAL_CHANNELS], + Word16 *exp_pred_mat_re, + Word32 pred_mat_im_fx[][BINAURAL_CHANNELS], + Word16 *exp_pred_mat_im, + const Word16 num_chs, + const Word16 real_only ) +{ + Word32 cov_ii_local_re_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS]; + Word32 cov_ii_inv_re_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS]; + Word32 cov_ii_inv_im_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS]; + Word16 exp_cov_ii_local_re = 0, exp_cov_ii_inv_re = 0, exp_cov_ii_inv_im = 0; + Word32 trace_cov_fx; + + Word16 i, j; + + trace_cov_fx = 0; + Word16 exp_trace_cov = 0; + FOR( i = 0; i < num_chs; i++ ) + { + trace_cov_fx = L_add( trace_cov_fx, L_shr( cov_ii_re_fx[i][i], 1 ) ); + } + exp_trace_cov = add( exp_cov_ii_re, 1 ); + + trace_cov_fx = L_max( 0, trace_cov_fx ); + Word16 flag = BASOP_Util_Cmp_Mant32Exp( trace_cov_fx, exp_cov_ii_re, EPSILON_FX, 0 ); + IF( EQ_16( flag, negate( 1 ) ) ) + { + FOR( i = 0; i < num_chs; i++ ) + { + /* protection from cases when variance of ref channels is very small */ + set32_fx( pred_mat_re_fx[i], 0, BINAURAL_CHANNELS ); + set32_fx( pred_mat_im_fx[i], 0, BINAURAL_CHANNELS ); + } + return; + } + + Word16 buff_exp[BINAURAL_CHANNELS][BINAURAL_CHANNELS]; + FOR( i = 0; i < BINAURAL_CHANNELS; i++ ) + { + FOR( j = 0; j < BINAURAL_CHANNELS; j++ ) + { + buff_exp[i][j] = 0; + move16(); + } + } + + FOR( i = 0; i < num_chs; i++ ) + { + Copy32( cov_ii_re_fx[i], cov_ii_local_re_fx[i], num_chs ); + set16_fx( buff_exp[i], exp_cov_ii_re, num_chs ); + } + + Word32 tmp = 0; + FOR( i = 0; i < num_chs; i++ ) + { + tmp = Mpy_32_32( trace_cov_fx, 214748 ); // exp_trace_cov + Word16 exp_tmp = 0; + cov_ii_local_re_fx[i][i] = BASOP_Util_Add_Mant32Exp( cov_ii_re_fx[i][i], exp_cov_ii_re, tmp, exp_trace_cov, &exp_tmp ); + move32(); + buff_exp[i][i] = exp_tmp; + move16(); + } + + Word16 max_exp = MIN16B; + FOR( i = 0; i < 2; i++ ) + { + FOR( j = 0; j < 2; j++ ) + { + max_exp = max( max_exp, buff_exp[i][j] ); + } + } + + FOR( i = 0; i < num_chs; i++ ) + { + FOR( j = 0; j < num_chs; j++ ) + { + cov_ii_local_re_fx[i][j] = L_shr( cov_ii_local_re_fx[i][j], max_exp - buff_exp[i][j] ); + move32(); + } + } + + exp_cov_ii_local_re = max_exp; + move16(); + + IF( isar_is_mat_inv_2by2_complex_fx( cov_ii_local_re_fx, exp_cov_ii_local_re, cov_ii_im_fx, exp_cov_ii_im ) ) + { + isar_calc_mat_inv_2by2_complex_fx( cov_ii_local_re_fx, exp_cov_ii_local_re, cov_ii_im_fx, exp_cov_ii_im, cov_ii_inv_re_fx, &exp_cov_ii_inv_re, cov_ii_inv_im_fx, &exp_cov_ii_inv_im ); + isar_mat_mult_2by2_complex_fx( cov_ii_inv_re_fx, exp_cov_ii_inv_re, cov_ii_inv_im_fx, exp_cov_ii_inv_im, cov_io_re_fx, exp_cov_io_re, cov_io_im_fx, exp_cov_io_im, pred_mat_re_fx, exp_pred_mat_re, pred_mat_im_fx, exp_pred_mat_im ); + } + ELSE + { + Word16 max_var_idx; + FOR( i = 0; i < num_chs; i++ ) + { + set32_fx( pred_mat_re_fx[i], 0, BINAURAL_CHANNELS ); + set32_fx( pred_mat_im_fx[i], 0, BINAURAL_CHANNELS ); + } + + max_var_idx = 0; + move16(); + IF( GT_32( cov_ii_local_re_fx[1][1], cov_ii_local_re_fx[0][0] ) ) + { + max_var_idx = 1; + } + + Word16 tmp1 = 0, exp_tmp1 = 0; + move16(); + move16(); + Word16 tmp2 = 0, exp_tmp2 = 0; + move16(); + move16(); + Word16 flag1 = BASOP_Util_Cmp_Mant32Exp( cov_ii_local_re_fx[max_var_idx][max_var_idx], exp_cov_ii_local_re, EPSILON_FX, 0 ); + IF( EQ_16( flag1, 1 ) ) + { + Word16 pred_mat_buf_re[BINAURAL_CHANNELS][BINAURAL_CHANNELS], pred_mat_buf_im[BINAURAL_CHANNELS][BINAURAL_CHANNELS]; + FOR( i = 0; i < BINAURAL_CHANNELS; i++ ) + { + set16_fx( pred_mat_buf_re[i], *exp_pred_mat_re, BINAURAL_CHANNELS ); + set16_fx( pred_mat_buf_im[i], *exp_pred_mat_im, BINAURAL_CHANNELS ); + } + FOR( j = 0; j < num_chs; j++ ) + { + tmp1 = BASOP_Util_Divide3232_Scale( cov_io_re_fx[max_var_idx][j], cov_ii_local_re_fx[max_var_idx][max_var_idx], &exp_tmp1 ); + exp_tmp1 = exp_tmp1 + ( exp_cov_io_re - exp_cov_ii_local_re ); + tmp2 = BASOP_Util_Divide3232_Scale( cov_io_im_fx[max_var_idx][j], cov_ii_local_re_fx[max_var_idx][max_var_idx], &exp_tmp2 ); + exp_tmp2 = exp_tmp2 + ( exp_cov_io_im - exp_cov_ii_local_re ); + pred_mat_re_fx[max_var_idx][j] = tmp1; + move32(); + pred_mat_im_fx[max_var_idx][j] = tmp2; + move32(); + pred_mat_buf_re[max_var_idx][j] = exp_tmp1; + move16(); + pred_mat_buf_im[max_var_idx][j] = exp_tmp2; + move16(); + } + + Word16 max_re = MIN16B, max_im = MIN16B; + FOR( i = 0; i < BINAURAL_CHANNELS; i++ ) + { + FOR( j = 0; j < BINAURAL_CHANNELS; j++ ) + { + + max_re = s_max( max_re, pred_mat_buf_re[i][j] ); + move16(); + max_im = s_max( max_im, pred_mat_buf_im[i][j] ); + move16(); + } + } + FOR( i = 0; i < BINAURAL_CHANNELS; i++ ) + { + FOR( j = 0; j < BINAURAL_CHANNELS; j++ ) + { + + pred_mat_re_fx[i][j] = L_shr( pred_mat_re_fx[i][j], max_re - pred_mat_buf_re[i][j] ); + move32(); + pred_mat_im_fx[i][j] = L_shr( pred_mat_im_fx[i][j], max_im - pred_mat_buf_im[i][j] ); + move32(); + } + } + + *exp_pred_mat_re = max_re; + move16(); + *exp_pred_mat_im = max_im; + move16(); + } + } + + IF( real_only ) + { + FOR( i = 0; i < num_chs; i++ ) + { + set32_fx( pred_mat_im_fx[i], 0, BINAURAL_CHANNELS ); + } + } + + return; +} +static void ComputePostPredCov_fx( + Word32 cov_ii_re_fx[][BINAURAL_CHANNELS], + Word16 exp_cov_ii_re, + Word32 cov_ii_im_fx[][BINAURAL_CHANNELS], + Word16 exp_cov_ii_im, + Word32 pred_mat_re_fx[][BINAURAL_CHANNELS], + Word16 exp_pred_mat_re, + Word32 pred_mat_im_fx[][BINAURAL_CHANNELS], + Word16 exp_pred_mat_im, + Word32 postpred_cov_re_fx[][BINAURAL_CHANNELS], + Word16 *exp_postpred_cov_re, + Word16 num_chs ) +{ + Word16 i, j; + Word32 dmx_mat_conj_re_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS]; + Word32 dmx_mat_conj_im_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS]; + Word32 temp_mat_re_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS]; + Word32 temp_mat_im_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS]; + Word32 postpred_cov_im_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS]; + Word16 exp_postpred_cov_im = 0; + Word16 exp_temp_mat_re = 0, exp_temp_mat_im = 0; + + assert( num_chs == BINAURAL_CHANNELS ); + + FOR( i = 0; i < num_chs; i++ ) + { + FOR( j = 0; j < num_chs; j++ ) + { + dmx_mat_conj_re_fx[i][j] = pred_mat_re_fx[j][i]; + move32(); + dmx_mat_conj_im_fx[i][j] = L_negate( pred_mat_im_fx[j][i] ); + move32(); + + temp_mat_re_fx[i][j] = pred_mat_re_fx[i][j]; + move32(); + temp_mat_im_fx[i][j] = pred_mat_im_fx[i][j]; + move32(); + } + set32_fx( postpred_cov_re_fx[i], 0, BINAURAL_CHANNELS ); + } + isar_mat_mult_2by2_complex_fx( dmx_mat_conj_re_fx, exp_pred_mat_re, dmx_mat_conj_im_fx, exp_pred_mat_im, cov_ii_re_fx, exp_cov_ii_re, cov_ii_im_fx, exp_cov_ii_im, temp_mat_re_fx, &exp_temp_mat_re, temp_mat_im_fx, &exp_temp_mat_im ); + isar_mat_mult_2by2_complex_fx( temp_mat_re_fx, exp_temp_mat_re, temp_mat_im_fx, exp_temp_mat_im, pred_mat_re_fx, exp_pred_mat_re, pred_mat_im_fx, exp_pred_mat_im, postpred_cov_re_fx, exp_postpred_cov_re, postpred_cov_im_fx, &exp_postpred_cov_im ); + + /* 2x2 mult */ + + FOR( i = 0; i < BINAURAL_CHANNELS; i++ ) + { + FOR( j = 0; j < i; j++ ) + { + postpred_cov_re_fx[i][j] = postpred_cov_re_fx[j][i]; + move32(); + } + } + + return; +} +static void ComputeBandedCrossCov_fx( + Word32 Cldfb_RealBuffer1_fx[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + Word16 exp_cldfb_re_1, + Word32 Cldfb_ImagBuffer1_fx[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + Word16 exp_cldfb_im_1, + const Word16 ch_start_idx1, + Word32 Cldfb_RealBuffer2_fx[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + Word16 exp_cldfb_re_2, + Word32 Cldfb_ImagBuffer2_fx[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + Word16 exp_cldfb_im_2, + const Word16 ch_start_idx2, + Word32 out_cov_re_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], + Word16 *exp_out_cov_re, + Word32 out_cov_im_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], + Word16 *exp_out_cov_im, + const Word16 num_chs, + const Word16 *pBand_grouping, + const Word16 num_slots, + const Word16 start_slot_idx, + const Word16 md_band_idx, + const Word16 real_only ) +{ + Word16 sf, cldfb_band_idx, ch_idx1, ch_idx2; + Word16 brange[2]; + + FOR( ch_idx1 = 0; ch_idx1 < num_chs; ch_idx1++ ) + { + set_l( out_cov_re_fx[ch_idx1], 0, num_chs ); + set_l( out_cov_im_fx[ch_idx1], 0, num_chs ); + } + + brange[0] = pBand_grouping[md_band_idx]; + move16(); + brange[1] = pBand_grouping[md_band_idx + 1]; + move16(); + Word16 exp_buff_re[BINAURAL_CHANNELS][BINAURAL_CHANNELS], exp_buff_im[BINAURAL_CHANNELS][BINAURAL_CHANNELS]; + FOR( ch_idx1 = 0; ch_idx1 < num_chs; ch_idx1++ ) + { + FOR( ch_idx2 = 0; ch_idx2 < num_chs; ch_idx2++ ) + { + Word32 tmp_a = out_cov_re_fx[ch_idx1][ch_idx2], tmp_b = out_cov_im_fx[ch_idx1][ch_idx2]; + Word16 exp_tmp_a = 0, exp_tmp_b = 0; + IF( EQ_16( real_only, 0 ) ) + { + FOR( sf = start_slot_idx; sf < add( start_slot_idx, num_slots ); sf++ ) + { + FOR( cldfb_band_idx = brange[0]; cldfb_band_idx < brange[1]; cldfb_band_idx++ ) + { + Word64 tmp1 = W_mult_32_32( Cldfb_RealBuffer1_fx[ch_start_idx1 + ch_idx1][sf][cldfb_band_idx], Cldfb_RealBuffer2_fx[ch_start_idx2 + ch_idx2][sf][cldfb_band_idx] ); + Word16 tmp1_nrm = W_norm( tmp1 ); + Word32 tmp1_final = W_extract_h( W_shl( tmp1, tmp1_nrm ) ); + + Word64 tmp2 = W_mult_32_32( Cldfb_ImagBuffer1_fx[ch_start_idx1 + ch_idx1][sf][cldfb_band_idx], Cldfb_ImagBuffer2_fx[ch_start_idx2 + ch_idx2][sf][cldfb_band_idx] ); + Word16 tmp2_nrm = W_norm( tmp2 ); + Word32 tmp2_final = W_extract_h( W_shl( tmp2, tmp2_nrm ) ); + + Word16 exp_tmp3 = 0; + Word32 tmp3 = BASOP_Util_Add_Mant32Exp( tmp1_final, exp_cldfb_re_1 + exp_cldfb_re_2 - tmp1_nrm, tmp2_final, exp_cldfb_im_1 + exp_cldfb_im_2 - tmp2_nrm, &exp_tmp3 ); + Word16 exp_tmp_a_tmp = 0; + tmp_a = BASOP_Util_Add_Mant32Exp( tmp_a, exp_tmp_a, tmp3, exp_tmp3, &exp_tmp_a_tmp ); + exp_tmp_a = exp_tmp_a_tmp; + + Word64 tmp4 = W_mult_32_32( Cldfb_RealBuffer1_fx[ch_start_idx1 + ch_idx1][sf][cldfb_band_idx], Cldfb_ImagBuffer2_fx[ch_start_idx2 + ch_idx2][sf][cldfb_band_idx] ); + Word16 tmp4_nrm = W_norm( tmp4 ); + Word32 tmp4_final = W_extract_h( W_shl( tmp4, tmp4_nrm ) ); // exp_cldfb_re_1 + exp_cldfb_im_2 - tmp4_nrm + + Word64 tmp5 = W_mult_32_32( Cldfb_ImagBuffer1_fx[ch_start_idx1 + ch_idx1][sf][cldfb_band_idx], Cldfb_RealBuffer2_fx[ch_start_idx2 + ch_idx2][sf][cldfb_band_idx] ); + Word16 tmp5_nrm = W_norm( tmp5 ); + Word32 tmp5_final = W_extract_h( W_shl( tmp5, tmp5_nrm ) ); // exp_cldfb_im_1 + exp_cldfb_re_2 - tmp5_nrm + + Word16 exp_tmp6 = 0; + Word32 tmp6 = BASOP_Util_Add_Mant32Exp( tmp4_final, exp_cldfb_re_1 + exp_cldfb_im_2 - tmp4_nrm, L_negate( tmp5_final ), exp_cldfb_im_1 + exp_cldfb_re_2 - tmp5_nrm, &exp_tmp6 ); + Word16 exp_tmp_b_tmp = 0; + tmp_b = BASOP_Util_Add_Mant32Exp( tmp_b, exp_tmp_b, tmp6, exp_tmp6, &exp_tmp_b_tmp ); + exp_tmp_b = exp_tmp_b_tmp; + } + } + } + ELSE + { + FOR( sf = start_slot_idx; sf < add( start_slot_idx, num_slots ); sf++ ) + { + FOR( cldfb_band_idx = brange[0]; cldfb_band_idx < brange[1]; cldfb_band_idx++ ) + { + Word64 tmp1 = W_mult_32_32( Cldfb_RealBuffer1_fx[ch_start_idx1 + ch_idx1][sf][cldfb_band_idx], Cldfb_RealBuffer2_fx[ch_start_idx2 + ch_idx2][sf][cldfb_band_idx] ); + Word16 tmp1_nrm = W_norm( tmp1 ); + Word32 tmp1_final = W_extract_h( W_shl( tmp1, tmp1_nrm ) ); + + Word64 tmp2 = W_mult_32_32( Cldfb_ImagBuffer1_fx[ch_start_idx1 + ch_idx1][sf][cldfb_band_idx], Cldfb_ImagBuffer2_fx[ch_start_idx2 + ch_idx2][sf][cldfb_band_idx] ); + Word16 tmp2_nrm = W_norm( tmp2 ); + Word32 tmp2_final = W_extract_h( W_shl( tmp2, tmp2_nrm ) ); + + Word16 exp_tmp3 = 0; + Word32 tmp3 = BASOP_Util_Add_Mant32Exp( tmp1_final, exp_cldfb_re_1 + exp_cldfb_re_2 - tmp1_nrm, tmp2_final, exp_cldfb_im_1 + exp_cldfb_im_2 - tmp2_nrm, &exp_tmp3 ); + Word16 exp_tmp_a_tmp = 0; + tmp_a = BASOP_Util_Add_Mant32Exp( tmp_a, exp_tmp_a, tmp3, exp_tmp3, &exp_tmp_a_tmp ); + exp_tmp_a = exp_tmp_a_tmp; + + tmp_b = 0; + exp_tmp_b = 0; + } + } + } + out_cov_re_fx[ch_idx1][ch_idx2] = tmp_a; + move32(); + out_cov_im_fx[ch_idx1][ch_idx2] = tmp_b; + move32(); + exp_buff_re[ch_idx1][ch_idx2] = exp_tmp_a; + move32(); + exp_buff_im[ch_idx1][ch_idx2] = exp_tmp_b; + move32(); + } + } + /*make common exponent*/ + Word16 max_cov_re = 0, max_cov_im = 0; + FOR( int i = 0; i < num_chs; i++ ) + { + FOR( int j = 0; j < num_chs; j++ ) + { + max_cov_re = max( max_cov_re, exp_buff_re[i][j] ); + max_cov_im = max( max_cov_im, exp_buff_im[i][j] ); + } + } + FOR( int i = 0; i < num_chs; i++ ) + { + FOR( int j = 0; j < num_chs; j++ ) + { + out_cov_re_fx[i][j] = L_shr( out_cov_re_fx[i][j], max_cov_re - exp_buff_re[i][j] ); + move32(); + out_cov_im_fx[i][j] = L_shr( out_cov_im_fx[i][j], max_cov_im - exp_buff_im[i][j] ); + move32(); + } + } + + *exp_out_cov_re = max_cov_re; + *exp_out_cov_im = max_cov_im; + + return; +} +static void ComputeBandedCov_fx( + Word32 Cldfb_RealBuffer_fx[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + Word16 exp_cldfb_re, + Word32 Cldfb_ImagBuffer_fx[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + Word16 exp_cldfb_im, + const Word16 ch_start_idx, + Word32 out_cov_re_fx[][BINAURAL_CHANNELS], + Word16 *exp_cov_re, + Word32 out_cov_im_fx[][BINAURAL_CHANNELS], + Word16 *exp_cov_im, + const Word16 num_chs, + const Word16 *pBand_grouping, + const Word16 num_slots, + const Word16 start_slot_idx, + const Word16 md_band_idx, + const Word16 real_only ) +{ + Word16 sf, cldfb_band_idx, ch_idx1, ch_idx2; + Word16 brange[2]; + + FOR( ch_idx1 = 0; ch_idx1 < num_chs; ch_idx1++ ) + { + set32_fx( out_cov_re_fx[ch_idx1], 0, num_chs ); + set32_fx( out_cov_im_fx[ch_idx1], 0, num_chs ); + } + + brange[0] = pBand_grouping[md_band_idx]; + move16(); + brange[1] = pBand_grouping[md_band_idx + 1]; + move16(); + + Word16 exp_buff_re[BINAURAL_CHANNELS][BINAURAL_CHANNELS], exp_buff_im[BINAURAL_CHANNELS][BINAURAL_CHANNELS]; + FOR( int i = 0; i < BINAURAL_CHANNELS; i++ ) + { + FOR( int j = 0; j < BINAURAL_CHANNELS; j++ ) + { + exp_buff_re[i][j] = 0; + move16(); + exp_buff_im[i][j] = 0; + move16(); + } + } + + FOR( ch_idx1 = 0; ch_idx1 < num_chs; ch_idx1++ ) + { + FOR( ch_idx2 = 0; ch_idx2 <= ch_idx1; ch_idx2++ ) + { + Word32 tmp_a = out_cov_re_fx[ch_idx1][ch_idx2]; + Word32 tmp_b = out_cov_im_fx[ch_idx1][ch_idx2]; + Word16 exp_tmp_a = 0, exp_tmp_b = 0; + test(); + IF( ( NE_16( ch_idx2, ch_idx1 ) ) && ( EQ_16( real_only, 0 ) ) ) + { + FOR( sf = start_slot_idx; sf < add( start_slot_idx, num_slots ); sf++ ) + { + FOR( cldfb_band_idx = brange[0]; cldfb_band_idx < brange[1]; cldfb_band_idx++ ) + { + Word64 tmp1 = W_mult_32_32( Cldfb_RealBuffer_fx[ch_start_idx + ch_idx1][sf][cldfb_band_idx], Cldfb_RealBuffer_fx[ch_start_idx + ch_idx2][sf][cldfb_band_idx] ); + Word16 tmp1_nrm = W_norm( tmp1 ); + Word32 tmp1_final = W_extract_h( W_shl( tmp1, tmp1_nrm ) ); // exp_cldfb_re + exp_cldfb_re - tmp1_nrm + + Word64 tmp2 = W_mult_32_32( Cldfb_ImagBuffer_fx[ch_start_idx + ch_idx1][sf][cldfb_band_idx], Cldfb_ImagBuffer_fx[ch_start_idx + ch_idx2][sf][cldfb_band_idx] ); + Word16 tmp2_nrm = W_norm( tmp2 ); + Word32 tmp2_final = W_extract_h( W_shl( tmp2, tmp2_nrm ) ); // exp_cldfb_im + exp_cldfb_im - tmp2_nrm + + Word16 exp_tmp3 = 0; + Word32 tmp3 = BASOP_Util_Add_Mant32Exp( tmp1_final, exp_cldfb_re + exp_cldfb_re - tmp1_nrm, tmp2_final, exp_cldfb_im + exp_cldfb_im - tmp2_nrm, &exp_tmp3 ); + Word16 exp_tmp_a_tmp = 0; + tmp_a = BASOP_Util_Add_Mant32Exp( tmp_a, exp_tmp_a, tmp3, exp_tmp3, &exp_tmp_a_tmp ); + exp_tmp_a = exp_tmp_a_tmp; + + Word64 tmp4 = W_mult_32_32( Cldfb_RealBuffer_fx[ch_start_idx + ch_idx1][sf][cldfb_band_idx], Cldfb_ImagBuffer_fx[ch_start_idx + ch_idx2][sf][cldfb_band_idx] ); + Word16 tmp4_nrm = W_norm( tmp4 ); + Word32 tmp4_final = W_extract_h( W_shl( tmp4, tmp4_nrm ) ); // exp_cldfb_re + exp_cldfb_im - tmp4_nrm + + Word64 tmp5 = W_mult_32_32( Cldfb_ImagBuffer_fx[ch_start_idx + ch_idx1][sf][cldfb_band_idx], Cldfb_RealBuffer_fx[ch_start_idx + ch_idx2][sf][cldfb_band_idx] ); + Word16 tmp5_nrm = W_norm( tmp5 ); + Word32 tmp5_final = W_extract_h( W_shl( tmp5, tmp5_nrm ) ); // exp_cldfb_im + exp_cldfb_re - tmp5_nrm + + Word16 exp_tmp6 = 0; + Word32 tmp6 = BASOP_Util_Add_Mant32Exp( tmp4_final, exp_cldfb_re + exp_cldfb_im - tmp4_nrm, L_negate( tmp5_final ), exp_cldfb_im + exp_cldfb_re - tmp5_nrm, &exp_tmp6 ); + Word16 exp_tmp_b_tmp = 0; + tmp_b = BASOP_Util_Add_Mant32Exp( tmp_b, exp_tmp_b, tmp6, exp_tmp6, &exp_tmp_b_tmp ); + exp_tmp_b = exp_tmp_b_tmp; + } + } + } + ELSE + { + FOR( sf = start_slot_idx; sf < add( start_slot_idx, num_slots ); sf++ ) + { + FOR( cldfb_band_idx = brange[0]; cldfb_band_idx < brange[1]; cldfb_band_idx++ ) + { + Word64 tmp1 = W_mult_32_32( Cldfb_RealBuffer_fx[ch_start_idx + ch_idx1][sf][cldfb_band_idx], Cldfb_RealBuffer_fx[ch_start_idx + ch_idx2][sf][cldfb_band_idx] ); + Word16 tmp1_nrm = W_norm( tmp1 ); + Word32 tmp1_final = W_extract_h( W_shl( tmp1, tmp1_nrm ) ); // exp_cldfb_re + exp_cldfb_re - tmp1_nrm + + Word64 tmp2 = W_mult_32_32( Cldfb_ImagBuffer_fx[ch_start_idx + ch_idx1][sf][cldfb_band_idx], Cldfb_ImagBuffer_fx[ch_start_idx + ch_idx2][sf][cldfb_band_idx] ); + Word16 tmp2_nrm = W_norm( tmp2 ); + Word32 tmp2_final = W_extract_h( W_shl( tmp2, tmp2_nrm ) ); // exp_cldfb_im + exp_cldfb_im - tmp2_nrm + + Word16 exp_tmp3 = 0; + Word32 tmp3 = BASOP_Util_Add_Mant32Exp( tmp1_final, exp_cldfb_re + exp_cldfb_re - tmp1_nrm, tmp2_final, exp_cldfb_im + exp_cldfb_im - tmp2_nrm, &exp_tmp3 ); + + Word16 exp_tmp_a_tmp = 0; + tmp_a = BASOP_Util_Add_Mant32Exp( tmp_a, exp_tmp_a, tmp3, exp_tmp3, &exp_tmp_a_tmp ); + exp_tmp_a = exp_tmp_a_tmp; + + tmp_b = 0; + exp_tmp_b = 0; + } + } + } + out_cov_re_fx[ch_idx1][ch_idx2] = tmp_a; + move32(); + exp_buff_re[ch_idx1][ch_idx2] = exp_tmp_a; + move32(); + + out_cov_im_fx[ch_idx1][ch_idx2] = tmp_b; + move32(); + exp_buff_im[ch_idx1][ch_idx2] = exp_tmp_b; + move32(); + } + } + + Word16 exp_max_re = MIN16B, exp_max_im = MIN16B; + FOR( int i = 0; i < BINAURAL_CHANNELS; i++ ) + { + FOR( int j = 0; j < BINAURAL_CHANNELS; j++ ) + { + exp_max_re = max( exp_max_re, exp_buff_re[i][j] ); + exp_max_im = max( exp_max_im, exp_buff_im[i][j] ); + } + } + + FOR( int i = 0; i < BINAURAL_CHANNELS; i++ ) + { + FOR( int j = 0; j < BINAURAL_CHANNELS; j++ ) + { + out_cov_re_fx[i][j] = L_shr( out_cov_re_fx[i][j], exp_max_re - exp_buff_re[i][j] ); + move32(); + out_cov_im_fx[i][j] = L_shr( out_cov_im_fx[i][j], exp_max_im - exp_buff_im[i][j] ); + move32(); + } + } + + FOR( ch_idx1 = 0; ch_idx1 < num_chs; ch_idx1++ ) + { + FOR( ch_idx2 = add( ch_idx1, 1 ); ch_idx2 < num_chs; ch_idx2++ ) + { + out_cov_re_fx[ch_idx1][ch_idx2] = out_cov_re_fx[ch_idx2][ch_idx1]; + move32(); + out_cov_im_fx[ch_idx1][ch_idx2] = L_negate( out_cov_im_fx[ch_idx2][ch_idx1] ); + move32(); + } + } + + *exp_cov_re = exp_max_re; + *exp_cov_im = exp_max_im; + + return; +} +static Word32 GetNormFact_fx( + Word32 cov_ii_re_fx[][BINAURAL_CHANNELS], + Word16 exp_cov_ii_re, + Word32 cov_ii_im_fx[][BINAURAL_CHANNELS], + Word16 exp_cov_ii_im, + Word32 cov_io_re_fx[][BINAURAL_CHANNELS], + Word16 exp_cov_io_re, + Word32 cov_io_im_fx[][BINAURAL_CHANNELS], + Word16 exp_cov_io_im, + Word32 cov_oo_re_fx[][BINAURAL_CHANNELS], + Word16 exp_cov_oo_re, + Word16 *exp_norm_fact_fx ) +{ + Word16 i, j; + Word32 norm_fact_fx = 0, abs_val_fx; + Word16 exp_abs_val = 0, exp_norm_fact = 0; + + FOR( i = 0; i < BINAURAL_CHANNELS; i++ ) + { + FOR( j = 0; j < BINAURAL_CHANNELS; j++ ) + { + ivas_calculate_abs_fx( cov_ii_re_fx[i][j], exp_cov_ii_re, cov_ii_im_fx[i][j], exp_cov_ii_im, &abs_val_fx, &exp_abs_val ); + Word16 res_1 = BASOP_Util_Cmp_Mant32Exp( norm_fact_fx, exp_norm_fact, abs_val_fx, exp_abs_val ); + IF( EQ_16( res_1, negate( 1 ) ) ) + { + norm_fact_fx = abs_val_fx; + exp_norm_fact = exp_abs_val; + } + + ivas_calculate_abs_fx( cov_io_re_fx[i][j], exp_cov_io_re, cov_io_im_fx[i][j], exp_cov_io_im, &abs_val_fx, &exp_abs_val ); + res_1 = BASOP_Util_Cmp_Mant32Exp( norm_fact_fx, exp_norm_fact, abs_val_fx, exp_abs_val ); + IF( EQ_16( res_1, negate( 1 ) ) ) + { + norm_fact_fx = abs_val_fx; + exp_norm_fact = exp_abs_val; + } + ivas_calculate_rabs_fx( cov_oo_re_fx[i][j], exp_cov_oo_re, &abs_val_fx, &exp_abs_val ); + res_1 = BASOP_Util_Cmp_Mant32Exp( norm_fact_fx, exp_norm_fact, abs_val_fx, exp_abs_val ); + IF( EQ_16( res_1, negate( 1 ) ) ) + { + norm_fact_fx = abs_val_fx; + exp_norm_fact = exp_abs_val; + } + } + } + + Word16 flag = BASOP_Util_Cmp_Mant32Exp( norm_fact_fx, exp_norm_fact, EPSILON_FX, 0 ); + IF( EQ_16( flag, negate( 1 ) ) ) + { + norm_fact_fx = ONE_IN_Q30; + exp_norm_fact = 1; + } + + Word16 exp_tmp = 0; + Word16 tmp = BASOP_Util_Divide3232_Scale( PCM16_TO_FLT_FAC_FX_Q15, norm_fact_fx, &exp_tmp ); + exp_tmp = add( exp_tmp, sub( 16, exp_norm_fact ) ); + norm_fact_fx = L_deposit_h( tmp ); + exp_norm_fact = exp_tmp; + + *exp_norm_fact_fx = exp_norm_fact; + + return norm_fact_fx; +} + +static void isar_split_rend_huffman_encode( + isar_split_rend_huffman_cfg_t *huff_cfg, + const Word16 in, + Word32 *hcode, + Word32 *hlen ) +{ + Word32 min_sym_val; + const Word32 *codebook; + + min_sym_val = huff_cfg->codebook[0]; + move32(); + + codebook = &huff_cfg->codebook[3 * ( in - min_sym_val )]; + *hlen = codebook[1]; + move32(); + *hcode = codebook[2]; + move32(); + + return; +} + +static void isar_split_rend_quant_md_fx( + ISAR_BIN_HR_SPLIT_REND_MD_HANDLE hMd, + const ISAR_SPLIT_REND_POSE_TYPE pose_type, + const int16_t real_only, + Word32 fix_pos_rot_mat[][BINAURAL_CHANNELS], + const Word32 pred_1byquantstep, // Q26 + const Word16 Q_frame +#ifdef DEBUG_QUANT_MD_FX + , + float fix_pos_rot_mat_flt[][BINAURAL_CHANNELS], + const float pred_1byquantstep_flt // Q26 +#endif +) +{ + int16_t ch1, ch2; + int16_t gd_idx_min; +#ifdef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS + Word32 quant_val; +#else + Word32 sign, quant_val; +#endif +#ifdef DEBUG_QUANT_MD_FX + float quant_val_flt; + Word16 tmp; +#endif + if ( pose_type == PRED_ONLY || pose_type == PRED_ROLL_ONLY ) + { + Word32 onebyquantstep; + + onebyquantstep = pred_1byquantstep; +#ifdef DEBUG_QUANT_MD_FX + float onebyquantstep_flt = pred_1byquantstep_flt; +#endif + IF( real_only == 1 ) + { +#ifdef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS + FOR( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + { + hMd->pred_mat_re_fx[ch1][ch1] = hMd->pred_mat_re2[ch1]; + } + hMd->pred_mat_re_fx[1][0] = 0; + hMd->pred_mat_re_fx[0][1] = 0; + + FOR( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + { + FOR( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) + { + quant_val = L_sub_sat( hMd->pred_mat_re_fx[ch1][ch2], L_shr_r( ( ch1 == ch2 ) ? ONE_IN_Q31 : 0, sub( Q31, Q_frame ) ) ); + quant_val = L_min( L_shr_r( ISAR_SPLIT_REND_PRED_MAX_VAL_Q30, sub( Q30, Q_frame ) ), L_max( quant_val, L_shr_r( ISAR_SPLIT_REND_PRED_MIN_VAL_Q30, sub( Q30, Q_frame ) ) ) ); + hMd->pred_mat_re_idx[ch1][ch2] = (Word16) L_shr_r( Mpy_32_32( onebyquantstep, quant_val ), sub( Q_frame, 5 ) ); // Q25*Q26 = Q20 -> Q16 -> Q0 + } + } +#else + for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + { + for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) + { + sign = GE_32( hMd->pred_mat_re_fx[ch1][ch2], 0 ) ? 1 : -1; + Word16 exp_out; + ivas_calculate_abs_fx( hMd->pred_mat_re_fx[ch1][ch2], Q31 - Q_frame, hMd->pred_mat_im_fx[ch1][ch2], Q31 - Q_frame, &hMd->pred_mat_re_fx[ch1][ch2], &exp_out ); + hMd->pred_mat_re_fx[ch1][ch2] = L_shr_r( hMd->pred_mat_re_fx[ch1][ch2], sub( sub( Q31, Q_frame ), exp_out ) ); // Q_frame + hMd->pred_mat_re_fx[ch1][ch2] = (Word32) W_mult0_32_32( hMd->pred_mat_re_fx[ch1][ch2], sign ); + hMd->pred_mat_im_fx[ch1][ch2] = 0; + } + } +#endif + } +#ifdef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS + else + { +#endif + for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + { + for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) + { + quant_val = L_sub_sat( hMd->pred_mat_re_fx[ch1][ch2], L_shr_r( fix_pos_rot_mat[ch1][ch2], sub( Q31, Q_frame ) ) ); + quant_val = L_min( L_shr_r( ISAR_SPLIT_REND_PRED_MAX_VAL_Q30, sub( Q30, Q_frame ) ), L_max( quant_val, L_shr_r( ISAR_SPLIT_REND_PRED_MIN_VAL_Q30, sub( Q30, Q_frame ) ) ) ); + hMd->pred_mat_re_idx[ch1][ch2] = (Word16) L_shr_r( Mpy_32_32( onebyquantstep, quant_val ), sub( Q_frame, 5 ) ); // Q25*Q26 = Q20 -> Q16 -> Q0 + +#ifdef DEBUG_QUANT_MD_FX + quant_val_flt = hMd->pred_mat_re[ch1][ch2] - fix_pos_rot_mat_flt[ch1][ch2]; + quant_val_flt = min( ISAR_SPLIT_REND_PRED_MAX_VAL, max( quant_val_flt, ISAR_SPLIT_REND_PRED_MIN_VAL ) ); + tmp = (int16_t) roundf( onebyquantstep_flt * quant_val_flt ); + if ( hMd->pred_mat_re_idx[ch1][ch2] != tmp ) + { + printf( "\nUNEQUAL INDEX\n" ); + } +#endif + } + } +#ifdef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS + } +#endif + + if ( real_only == 0 ) + { + for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + { + for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) + { + quant_val = L_min( L_shr_r( ISAR_SPLIT_REND_PRED_MAX_VAL_Q30, sub( Q30, Q_frame ) ), L_max( hMd->pred_mat_im_fx[ch1][ch2], L_shr_r( ISAR_SPLIT_REND_PRED_MIN_VAL_Q30, sub( Q30, Q_frame ) ) ) ); + hMd->pred_mat_im_idx[ch1][ch2] = (Word16) L_shr_r( Mpy_32_32( onebyquantstep, quant_val ), sub( Q_frame, 5 ) ); + // hMd->pred_mat_im[ch1][ch2] = hMd->pred_mat_im_idx[ch1][ch2] * IVAS_SPLIT_REND_PRED_Q_STEP; + + +#ifdef DEBUG_QUANT_MD_FX + quant_val_flt = min( ISAR_SPLIT_REND_PRED_MAX_VAL, max( hMd->pred_mat_im[ch1][ch2], ISAR_SPLIT_REND_PRED_MIN_VAL ) ); + tmp = (int16_t) roundf( onebyquantstep_flt * quant_val_flt ); + if ( hMd->pred_mat_im_idx[ch1][ch2] != tmp ) + { + printf( "\nUNEQUAL INDEX\n" ); + } +#endif + } + } + } + } + else if ( pose_type == COM_GAIN_ONLY ) + { + quant_val = L_min( L_shl_r( 1, Q_frame ) /*ISAR_SPLIT_REND_D_MAX_VAL_FX*/, L_max( hMd->gd_fx, ISAR_SPLIT_REND_D_MIN_VAL_FX ) ); //_frame + gd_idx_min = 0; //(int16_t)roundf(ISAR_SPLIT_REND_D_1BYQ_STEP * ISAR_SPLIT_REND_D_MIN_VAL) + hMd->gd_idx = (Word16) L_shr_r( Mpy_32_32( ISAR_SPLIT_REND_D_1BYQ_STEP_Q27, quant_val ), sub( Q_frame, 4 ) ); + hMd->gd_fx = W_extract_l( W_shr( W_mult0_32_32( hMd->gd_idx, ISAR_SPLIT_REND_D_Q_STEP_Q31 ), sub( Q31, Q_frame ) ) ); + hMd->gd_idx = sub( hMd->gd_idx, gd_idx_min ); + +#ifdef DEBUG_QUANT_MD_FX + quant_val_flt = min( ISAR_SPLIT_REND_D_MAX_VAL, max( hMd->gd, ISAR_SPLIT_REND_D_MIN_VAL ) ); + gd_idx_min = (int16_t) roundf( ISAR_SPLIT_REND_D_1BYQ_STEP * ISAR_SPLIT_REND_D_MIN_VAL ); + tmp = (int16_t) roundf( ISAR_SPLIT_REND_D_1BYQ_STEP * quant_val_flt ); + tmp = tmp - gd_idx_min; + if ( hMd->gd_idx != tmp ) + { + printf( "\nUNEQUAL INDEX\n" ); + } +#endif + } + else if ( pose_type == LR_GAIN_ONLY ) + { + quant_val = L_min( L_shr_r( ISAR_SPLIT_REND_PITCH_G_MAX_VAL_Q30, sub( Q30, Q_frame ) ), L_max( L_add( hMd->gd_fx, shr( 20, sub( Q30, Q_frame ) ) ), L_shr_r( ISAR_SPLIT_REND_PITCH_G_MIN_VAL_Q30, sub( Q30, Q_frame ) ) ) ); // Q25 + gd_idx_min = 7; // (int16_t)roundf(ISAR_SPLIT_REND_PITCH_G_1BYQ_STEP * ISAR_SPLIT_REND_PRED_MAX_VAL) + hMd->gd_idx = (Word16) L_shr_r( Mpy_32_32( ISAR_SPLIT_REND_PITCH_G_1BYQ_STEP_Q27, quant_val ), sub( Q_frame, 4 ) ); + hMd->gd_idx = sub( hMd->gd_idx, gd_idx_min ); + +#ifdef DEBUG_QUANT_MD_FX + quant_val_flt = min( ISAR_SPLIT_REND_PITCH_G_MAX_VAL, max( hMd->gd, ISAR_SPLIT_REND_PRED_MAX_VAL ) ); + gd_idx_min = (int16_t) roundf( ISAR_SPLIT_REND_PITCH_G_1BYQ_STEP * ISAR_SPLIT_REND_PRED_MAX_VAL ); + tmp = (int16_t) roundf( ISAR_SPLIT_REND_PITCH_G_1BYQ_STEP * quant_val_flt ); + tmp = tmp - gd_idx_min; + if ( hMd->gd_idx != tmp ) + { + printf( "\nUNEQUAL INDEX\n" ); + } +#endif + quant_val = L_min( L_shr_r( ISAR_SPLIT_REND_PITCH_G_MAX_VAL_Q30, sub( Q30, Q_frame ) ), L_max( L_add( hMd->gd2_fx, shr( 20, sub( Q30, Q_frame ) ) ), L_shr_r( ISAR_SPLIT_REND_PITCH_G_MIN_VAL_Q30, sub( Q30, Q_frame ) ) ) ); // Q25 + hMd->gd2_idx = (Word16) L_shr_r( Mpy_32_32( ISAR_SPLIT_REND_PITCH_G_1BYQ_STEP_Q27, quant_val ), sub( Q_frame, 4 ) ); + hMd->gd2_idx = sub( hMd->gd2_idx, gd_idx_min ); + +#ifdef DEBUG_QUANT_MD_FX + quant_val_flt = min( ISAR_SPLIT_REND_PITCH_G_MAX_VAL, max( hMd->gd2, ISAR_SPLIT_REND_PRED_MAX_VAL ) ); + tmp = (int16_t) roundf( ISAR_SPLIT_REND_PITCH_G_1BYQ_STEP * quant_val_flt ); + tmp = tmp - gd_idx_min; + if ( hMd->gd2_idx != tmp ) + { + printf( "\nUNEQUAL INDEX\n" ); + } +#endif + } + return; +} + + +#ifdef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS +static void get_lr_gains( Word32 cov_ii_re_fx[][BINAURAL_CHANNELS], + const Word16 exp_cov_ii_re, + Word32 cov_oo_re_fx[][BINAURAL_CHANNELS], + const Word16 exp_cov_oo_re, + Word32 gains_fx[BINAURAL_CHANNELS], + Word16 *exp_gains_fx ) +{ + Word16 exp_gd_tmp_buf[BINAURAL_CHANNELS] = { 0 }; + Word16 exp_gd_tmp = 0, i; + + FOR( i = 0; i < BINAURAL_CHANNELS; i++ ) + { + gains_fx[i] = cov_ii_re_fx[i][i]; + move32(); + exp_gd_tmp_buf[i] = exp_cov_ii_re; + move16(); + + Word16 flag = BASOP_Util_Cmp_Mant32Exp( gains_fx[i], exp_gd_tmp_buf[i], EPSILON_FX, 0 ); + IF( EQ_16( flag, negate( 1 ) ) ) + { + gains_fx[i] = ONE_IN_Q25; + move32(); + exp_gd_tmp_buf[i] = 6; + move16(); + } + ELSE + { + Word16 tmp, tmp_sqrt, exp_tmp = 0; + tmp = BASOP_Util_Divide3232_Scale( cov_oo_re_fx[i][i], gains_fx[i], &exp_tmp ); + exp_tmp = exp_tmp + ( exp_cov_oo_re - exp_gd_tmp_buf[i] ); + tmp_sqrt = Sqrt16( tmp, &exp_tmp ); + gains_fx[i] = L_deposit_h( tmp_sqrt ); + move32(); + exp_gd_tmp_buf[i] = exp_tmp; + move16(); + } + } + + Word16 max_gd_exp = MIN16B; + FOR( i = 0; i < BINAURAL_CHANNELS; i++ ) + { + max_gd_exp = max( max_gd_exp, exp_gd_tmp_buf[i] ); + } + exp_gd_tmp = max_gd_exp; + + FOR( i = 0; i < BINAURAL_CHANNELS; i++ ) + { + gains_fx[i] = L_shr( gains_fx[i], max_gd_exp - exp_gd_tmp_buf[i] ); + move32(); + } + + *exp_gains_fx = exp_gd_tmp; + move16(); + return; +} +#endif + +static void ComputeCoeffs_fx( + Word32 cov_ii_re_fx[][BINAURAL_CHANNELS], + Word16 exp_cov_ii_re, + Word32 cov_ii_im_fx[][BINAURAL_CHANNELS], + Word16 exp_cov_ii_im, + Word32 cov_io_re_fx[][BINAURAL_CHANNELS], + Word16 exp_cov_io_re, + Word32 cov_io_im_fx[][BINAURAL_CHANNELS], + Word16 exp_cov_io_im, + Word32 cov_oo_re_fx[][BINAURAL_CHANNELS], + Word16 exp_cov_oo_re, + ISAR_BIN_HR_SPLIT_REND_MD_HANDLE hMd, + const ISAR_SPLIT_REND_POSE_TYPE pose_type, + const Word16 real_only ) +{ + Word16 i, j; + Word32 gd_fx, gl2_fx, gr2_fx, cov_norm_fact_fx; + Word16 exp_gd = 0; + + Word32 postpred_cov_re_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS]; + Word16 exp_postpred_cov_re = 0; + + Word32 cov_ii_norm_re_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS]; + Word32 cov_ii_norm_im_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS]; + Word32 cov_io_norm_re_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS]; + Word32 cov_io_norm_im_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS]; + Word32 cov_oo_norm_re_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS]; + + Word16 exp_cov_ii_norm_re = 0, exp_cov_ii_norm_im = 0, exp_cov_io_norm_re = 0, exp_cov_io_norm_im = 0, exp_cov_oo_norm_re = 0; + Word16 exp_pred_re = 0, exp_pred_im = 0; + + IF( EQ_16( pose_type, PITCH_ONLY ) ) + { + Word32 gd_tmp_fx[BINAURAL_CHANNELS]; + Word16 exp_gd_tmp_buf[BINAURAL_CHANNELS] = { 0 }; + Word16 exp_gd_tmp = 0; + + FOR( i = 0; i < BINAURAL_CHANNELS; i++ ) + { + gd_tmp_fx[i] = cov_ii_re_fx[i][i]; + move32(); + exp_gd_tmp_buf[i] = exp_cov_ii_re; + move16(); + exp_gd_tmp = exp_cov_ii_re; + + Word16 flag = BASOP_Util_Cmp_Mant32Exp( gd_tmp_fx[i], exp_gd_tmp, EPSILON_FX, 0 ); + IF( EQ_16( flag, negate( 1 ) ) ) + { + gd_tmp_fx[i] = ONE_IN_Q25; + move32(); + exp_gd_tmp_buf[i] = 6; + move16(); + } + ELSE + { + Word16 tmp, tmp_sqrt, exp_tmp = 0; + tmp = BASOP_Util_Divide3232_Scale( cov_oo_re_fx[i][i], gd_tmp_fx[i], &exp_tmp ); + exp_tmp = add( exp_tmp, sub( exp_cov_oo_re, exp_gd_tmp ) ); + tmp_sqrt = Sqrt16( tmp, &exp_tmp ); + gd_tmp_fx[i] = L_deposit_h( tmp_sqrt ); + move32(); + exp_gd_tmp_buf[i] = exp_tmp; + move16(); + } + } + + Word16 max_gd_exp = MIN16B; + FOR( i = 0; i < BINAURAL_CHANNELS; i++ ) + { + max_gd_exp = s_max( max_gd_exp, exp_gd_tmp_buf[i] ); + } + FOR( i = 0; i < BINAURAL_CHANNELS; i++ ) + { + gd_tmp_fx[i] = L_shr( gd_tmp_fx[i], max_gd_exp - exp_gd_tmp_buf[i] ); + move32(); + } + exp_gd_tmp = max_gd_exp; + move16(); + hMd->gd_fx = gd_tmp_fx[0]; + move16(); + hMd->gd2_fx = gd_tmp_fx[1]; + move16(); + hMd->exp_gd = exp_gd_tmp; + move16(); + hMd->exp_gd2 = exp_gd_tmp; + move16(); + } + ELSE + { + IF( real_only ) + { +#ifdef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS + Word32 gd_tmp_fx[BINAURAL_CHANNELS]; + get_lr_gains( cov_ii_re_fx, exp_cov_ii_re, + cov_oo_re_fx, exp_cov_oo_re, + gd_tmp_fx, &hMd->exp_pred_mat_re2 ); + hMd->pred_mat_re_fx[1][0] = 0; + move32(); + hMd->pred_mat_re_fx[0][1] = 0; + move32(); + hMd->exp_pred_mat_re = hMd->exp_pred_mat_re2; + move16(); + hMd->exp_pred_mat_im = hMd->exp_pred_mat_re; + move16(); + for ( i = 0; i < BINAURAL_CHANNELS; i++ ) + { + hMd->pred_mat_re_fx[i][i] = gd_tmp_fx[i]; + hMd->pred_mat_re2[i] = gd_tmp_fx[i]; + set32_fx( hMd->pred_mat_im_fx[i], 0, BINAURAL_CHANNELS ); + } + + +#else + Word32 gd_tmp_fx[BINAURAL_CHANNELS]; + Word16 exp_gd_tmp_buf[BINAURAL_CHANNELS] = { 0 }; + Word16 exp_gd_tmp = 0; + + FOR( i = 0; i < BINAURAL_CHANNELS; i++ ) + { + gd_tmp_fx[i] = cov_ii_re_fx[i][i]; + move32(); + exp_gd_tmp_buf[i] = exp_cov_ii_re; + move16(); + + Word16 flag = BASOP_Util_Cmp_Mant32Exp( gd_tmp_fx[i], exp_gd_tmp_buf[i], EPSILON_FX, 0 ); + IF( EQ_16( flag, negate( 1 ) ) ) + { + gd_tmp_fx[i] = ONE_IN_Q25; + move32(); + exp_gd_tmp_buf[i] = 6; + move16(); + } + ELSE + { + Word16 tmp, tmp_sqrt, exp_tmp = 0; + tmp = BASOP_Util_Divide3232_Scale( cov_oo_re_fx[i][i], gd_tmp_fx[i], &exp_tmp ); + exp_tmp = exp_tmp + ( exp_cov_oo_re - exp_gd_tmp_buf[i] ); + tmp_sqrt = Sqrt16( tmp, &exp_tmp ); + gd_tmp_fx[i] = L_deposit_h( tmp_sqrt ); + move32(); + exp_gd_tmp_buf[i] = exp_tmp; + move16(); + } + hMd->pred_mat_re_fx[i][i] = gd_tmp_fx[i]; + move32(); + set32_fx( hMd->pred_mat_im_fx[i], 0, BINAURAL_CHANNELS ); + } + hMd->pred_mat_re_fx[1][0] = 0; + move32(); + hMd->pred_mat_re_fx[0][1] = 0; + move32(); + + Word16 max_gd_exp = MIN16B; + FOR( i = 0; i < BINAURAL_CHANNELS; i++ ) + { + max_gd_exp = max( max_gd_exp, exp_gd_tmp_buf[i] ); + } + exp_gd_tmp = max_gd_exp; + + FOR( i = 0; i < BINAURAL_CHANNELS; i++ ) + { + hMd->pred_mat_re_fx[i][i] = L_shr( hMd->pred_mat_re_fx[i][i], max_gd_exp - exp_gd_tmp_buf[i] ); + move32(); + } + + exp_pred_re = exp_gd_tmp; + move16(); + exp_pred_im = exp_gd_tmp; + move16(); + + hMd->exp_pred_mat_re = exp_pred_re; + move16(); + hMd->exp_pred_mat_im = exp_pred_im; + move16(); +#endif + } + ELSE + { +#ifdef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS + get_lr_gains( cov_ii_re_fx, exp_cov_ii_re, + cov_oo_re_fx, exp_cov_oo_re, + hMd->pred_mat_re2, &hMd->exp_pred_mat_re2 ); +#endif + Word16 exp_norm_fact = 0; + cov_norm_fact_fx = GetNormFact_fx( cov_ii_re_fx, exp_cov_ii_re, cov_ii_im_fx, exp_cov_ii_im, cov_io_re_fx, exp_cov_io_re, cov_io_im_fx, exp_cov_io_im, cov_oo_re_fx, exp_cov_oo_re, &exp_norm_fact ); + + FOR( i = 0; i < BINAURAL_CHANNELS; i++ ) + { + FOR( j = 0; j < BINAURAL_CHANNELS; j++ ) + { + cov_ii_norm_re_fx[i][j] = Mpy_32_32( cov_ii_re_fx[i][j], cov_norm_fact_fx ); + move32(); + cov_ii_norm_im_fx[i][j] = Mpy_32_32( cov_ii_im_fx[i][j], cov_norm_fact_fx ); + move32(); + cov_io_norm_re_fx[i][j] = Mpy_32_32( cov_io_re_fx[i][j], cov_norm_fact_fx ); + move32(); + cov_io_norm_im_fx[i][j] = Mpy_32_32( cov_io_im_fx[i][j], cov_norm_fact_fx ); + move32(); + cov_oo_norm_re_fx[i][j] = Mpy_32_32( cov_oo_re_fx[i][j], cov_norm_fact_fx ); + move32(); + } + } + + exp_cov_ii_norm_re = add( exp_cov_ii_re, exp_norm_fact ); + exp_cov_ii_norm_im = add( exp_cov_ii_im, exp_norm_fact ); + exp_cov_io_norm_re = add( exp_cov_io_re, exp_norm_fact ); + exp_cov_io_norm_im = add( exp_cov_io_im, exp_norm_fact ); + exp_cov_oo_norm_re = add( exp_cov_oo_re, exp_norm_fact ); + + ComputePredMat_fx( cov_ii_norm_re_fx, exp_cov_ii_norm_re, cov_ii_norm_im_fx, exp_cov_ii_norm_im, cov_io_norm_re_fx, exp_cov_io_norm_re, cov_io_norm_im_fx, exp_cov_io_norm_im, hMd->pred_mat_re_fx, &exp_pred_re, hMd->pred_mat_im_fx, &exp_pred_im, BINAURAL_CHANNELS, real_only ); + hMd->exp_pred_mat_re = exp_pred_re; + move16(); + hMd->exp_pred_mat_im = exp_pred_im; + move16(); + + /*TODO : change this function to real only as thats what is needed*/ + ComputePostPredCov_fx( cov_ii_norm_re_fx, exp_cov_ii_norm_re, cov_ii_norm_im_fx, exp_cov_ii_norm_im, hMd->pred_mat_re_fx, exp_pred_re, hMd->pred_mat_im_fx, exp_pred_im, postpred_cov_re_fx, &exp_postpred_cov_re, BINAURAL_CHANNELS ); + + /* normalize everything to +-1 range */ + Word16 gd_16_fx = BASOP_Util_Divide3232_Scale( ONE_IN_Q30, PCM16_TO_FLT_FAC_FX_Q15, &exp_gd ); + gd_fx = L_deposit_h( gd_16_fx ); + exp_gd = add( exp_gd, sub( 1, 16 ) ); + + Word16 tmp_buff_2[BINAURAL_CHANNELS][BINAURAL_CHANNELS], tmp_buff_3[BINAURAL_CHANNELS][BINAURAL_CHANNELS]; + FOR( i = 0; i < BINAURAL_CHANNELS; i++ ) + { + FOR( j = 0; j < BINAURAL_CHANNELS; j++ ) + { + Word64 tmp_2 = W_mult_32_32( cov_ii_norm_re_fx[i][j], gd_fx ); + Word64 tmp_3 = W_mult_32_32( cov_oo_norm_re_fx[i][j], gd_fx ); + Word16 shift_2 = W_norm( tmp_2 ); + Word16 shift_3 = W_norm( tmp_3 ); + + postpred_cov_re_fx[i][j] = Mpy_32_32( postpred_cov_re_fx[i][j], gd_fx ); + move32(); + cov_ii_norm_re_fx[i][j] = W_extract_h( W_shl( tmp_2, shift_2 ) ); + move32(); + cov_oo_norm_re_fx[i][j] = W_extract_h( W_shl( tmp_3, shift_3 ) ); + move32(); + + tmp_buff_2[i][j] = exp_cov_ii_norm_re + exp_gd - shift_2; + move16(); + tmp_buff_3[i][j] = exp_cov_oo_norm_re + exp_gd - shift_3; + move16(); + } + } + Word16 max_2 = MIN16B, max_3 = MIN16B; + FOR( i = 0; i < BINAURAL_CHANNELS; i++ ) + { + FOR( j = 0; j < BINAURAL_CHANNELS; j++ ) + { + max_2 = s_max( max_2, tmp_buff_2[i][j] ); + max_3 = s_max( max_3, tmp_buff_3[i][j] ); + } + } + + FOR( i = 0; i < BINAURAL_CHANNELS; i++ ) + { + FOR( j = 0; j < BINAURAL_CHANNELS; j++ ) + { + cov_ii_norm_re_fx[i][j] = L_shr( cov_ii_norm_re_fx[i][j], max_2 - tmp_buff_2[i][j] ); + move32(); + cov_oo_norm_re_fx[i][j] = L_shr( cov_oo_norm_re_fx[i][j], max_3 - tmp_buff_3[i][j] ); + move32(); + } + } + + exp_postpred_cov_re = add( exp_postpred_cov_re, exp_gd ); + exp_cov_ii_norm_re = max_2; + move16(); + exp_cov_oo_norm_re = max_3; + move16(); + + hMd->gd_fx = 0; + move16(); + Word16 exp_gl2 = 0; + move16(); + Word16 check_postPred = BASOP_Util_Cmp_Mant32Exp( postpred_cov_re_fx[0][0], exp_postpred_cov_re, EPSILON_FX, 0 ); + IF( EQ_16( check_postPred, 1 ) ) + { + Word16 exp_div_res = 0; + Word16 div_res = BASOP_Util_Divide3232_Scale( cov_oo_norm_re_fx[0][0], postpred_cov_re_fx[0][0], &exp_div_res ); + exp_div_res = exp_div_res + ( exp_cov_oo_norm_re - exp_postpred_cov_re ); + gl2_fx = L_deposit_h( div_res ); + exp_gl2 = exp_div_res; + move16(); + + Word16 Cmp1 = BASOP_Util_Cmp_Mant32Exp( gl2_fx, exp_gl2, ONE_IN_Q30, 1 ); + IF( EQ_16( Cmp1, negate( 1 ) ) ) + { + gl2_fx = ONE_IN_Q30; + exp_gl2 = 1; + move16(); + move16(); + } + + gl2_fx = Sqrt32( gl2_fx, &exp_gl2 ); + } + ELSE + { + gl2_fx = ONE_IN_Q30; + exp_gl2 = 1; + move16(); + move16(); + } + + Word16 exp_gr2 = 0; + check_postPred = BASOP_Util_Cmp_Mant32Exp( postpred_cov_re_fx[1][1], exp_postpred_cov_re, EPSILON_FX, 0 ); + IF( EQ_16( check_postPred, 1 ) ) + { + Word16 exp_div_res = 0; + Word16 div_res = BASOP_Util_Divide3232_Scale( cov_oo_norm_re_fx[1][1], postpred_cov_re_fx[1][1], &exp_div_res ); + exp_div_res = exp_div_res + ( exp_cov_oo_norm_re - exp_postpred_cov_re ); + gr2_fx = L_deposit_h( div_res ); + exp_gr2 = exp_div_res; + + Word16 Cmp1 = BASOP_Util_Cmp_Mant32Exp( gr2_fx, exp_gr2, ONE_IN_Q30, 1 ); + IF( EQ_16( Cmp1, negate( 1 ) ) ) + { + gr2_fx = ONE_IN_Q30; + move16(); + exp_gr2 = 1; + move16(); + } + + gr2_fx = Sqrt32( gr2_fx, &exp_gr2 ); + } + ELSE + { + gr2_fx = ONE_IN_Q30; + move16(); + exp_gr2 = 1; + move16(); + } + + Word16 pred_mat_buf_re[BINAURAL_CHANNELS][BINAURAL_CHANNELS]; + Word16 pred_mat_buf_im[BINAURAL_CHANNELS][BINAURAL_CHANNELS]; + FOR( i = 0; i < BINAURAL_CHANNELS; i++ ) + { + FOR( j = 0; j < BINAURAL_CHANNELS; j++ ) + { + pred_mat_buf_re[i][j] = exp_pred_re; + move16(); + pred_mat_buf_im[i][j] = exp_pred_im; + move16(); + } + } + FOR( i = 0; i < BINAURAL_CHANNELS; i++ ) + { + hMd->pred_mat_re_fx[i][0] = Mpy_32_32( hMd->pred_mat_re_fx[i][0], gl2_fx ); + move32(); + hMd->pred_mat_re_fx[i][1] = Mpy_32_32( hMd->pred_mat_re_fx[i][1], gr2_fx ); + move32(); + pred_mat_buf_re[i][0] = add( exp_pred_re, exp_gl2 ); + move16(); + pred_mat_buf_re[i][1] = add( exp_pred_re, exp_gr2 ); + move16(); + } + + IF( EQ_16( real_only, 0 ) ) + { + FOR( i = 0; i < BINAURAL_CHANNELS; i++ ) + { + hMd->pred_mat_im_fx[i][0] = Mpy_32_32( hMd->pred_mat_im_fx[i][0], gl2_fx ); + move32(); + hMd->pred_mat_im_fx[i][1] = Mpy_32_32( hMd->pred_mat_im_fx[i][1], gr2_fx ); + move32(); + + pred_mat_buf_im[i][0] = add( exp_pred_im, exp_gl2 ); + move16(); + pred_mat_buf_im[i][1] = add( exp_pred_im, exp_gr2 ); + move16(); + } + } + + Word16 max_exp_pred_re = MIN16B, max_exp_pred_im = MIN16B; + FOR( i = 0; i < BINAURAL_CHANNELS; i++ ) + { + FOR( j = 0; j < BINAURAL_CHANNELS; j++ ) + { + max_exp_pred_re = s_max( max_exp_pred_re, pred_mat_buf_re[i][j] ); + max_exp_pred_im = s_max( max_exp_pred_im, pred_mat_buf_im[i][j] ); + } + } + + FOR( i = 0; i < BINAURAL_CHANNELS; i++ ) + { + FOR( j = 0; j < BINAURAL_CHANNELS; j++ ) + { + hMd->pred_mat_re_fx[i][j] = L_shr( hMd->pred_mat_re_fx[i][j], max_exp_pred_re - pred_mat_buf_re[i][j] ); + move32(); + hMd->pred_mat_im_fx[i][j] = L_shr( hMd->pred_mat_im_fx[i][j], max_exp_pred_im - pred_mat_buf_im[i][j] ); + move32(); + } + } + + hMd->exp_pred_mat_re = max_exp_pred_re; + move16(); + hMd->exp_pred_mat_im = max_exp_pred_im; + move16(); + } + } + + return; +} + +static void get_base2_bits( + const ISAR_BIN_HR_SPLIT_PRE_REND_HANDLE hBinHrSplitPreRend, + MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, + const Word16 num_subframes, + const Word16 num_quant_strats, + const Word16 pred_real_bands_yaw[ISAR_SPLIT_REND_NUM_QUANT_STRATS], + const Word16 pred_imag_bands_yaw[ISAR_SPLIT_REND_NUM_QUANT_STRATS], + Word16 pred_quant_pnts_yaw[ISAR_SPLIT_REND_NUM_QUANT_STRATS], + const Word16 d_bands_yaw[ISAR_SPLIT_REND_NUM_QUANT_STRATS], + const Word16 bands_pitch[ISAR_SPLIT_REND_NUM_QUANT_STRATS], + const Word16 pred_real_bands_roll[ISAR_SPLIT_REND_NUM_QUANT_STRATS], + const Word16 pred_imag_bands_roll[ISAR_SPLIT_REND_NUM_QUANT_STRATS], + Word32 base2bits[ISAR_SPLIT_REND_NUM_QUANT_STRATS] ) +{ + Word16 pred_roll_bits; + Word16 d_gain_bits, pitch_gain_bits, pose_idx, q; + Word16 pred_yaw_bits[ISAR_SPLIT_REND_NUM_QUANT_STRATS]; + Word16 bin_ch_2, bin_ch_2_num_sf, bin_ch_num_sf; + + ISAR_SPLIT_REND_POSE_TYPE pose_type; + + FOR( q = 0; q < num_quant_strats; q++ ) + { + pred_yaw_bits[q] = ceil_log_2( pred_quant_pnts_yaw[q] ); + move16(); + } + pred_roll_bits = ceil_log_2( ISAR_SPLIT_REND_ROLL_PRED_QUANT_PNTS ); + + d_gain_bits = ceil_log_2( ISAR_SPLIT_REND_D_QUANT_PNTS ); + pitch_gain_bits = d_gain_bits; + move16(); + + FOR( q = 0; q < num_quant_strats; q++ ) + { + base2bits[q] = 0; + move32(); + } + + bin_ch_2 = DEPR_i_mult( BINAURAL_CHANNELS, BINAURAL_CHANNELS ); + bin_ch_2_num_sf = DEPR_i_mult( bin_ch_2, num_subframes ); + bin_ch_num_sf = DEPR_i_mult( BINAURAL_CHANNELS, num_subframes ); + + FOR( q = 0; q < num_quant_strats; q++ ) + { + FOR( pose_idx = 0; pose_idx < sub( pMultiBinPoseData->num_poses, 1 ); pose_idx++ ) + { + pose_type = hBinHrSplitPreRend->pose_type[pose_idx]; + IF( EQ_32( pose_type, ANY_YAW ) ) + { +#ifndef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS + base2bits[q] = L_add( base2bits[q], L_mult0( DEPR_i_mult( pred_yaw_bits[q], pred_real_bands_yaw[q] ), bin_ch_2_num_sf ) ); + move32(); + base2bits[q] = L_add( base2bits[q], L_mult0( DEPR_i_mult( pred_yaw_bits[q], pred_imag_bands_yaw[q] ), bin_ch_2_num_sf ) ); + move32(); +#else + base2bits[q] = L_add( base2bits[q], L_mult0( DEPR_i_mult( pred_yaw_bits[q], pred_real_bands_yaw[q] ), bin_ch_num_sf ) ); + move32(); + base2bits[q] = L_add( base2bits[q], L_mult0( DEPR_i_mult( pred_yaw_bits[q], pred_imag_bands_yaw[q] ), bin_ch_num_sf ) ); + move32(); + base2bits[q] = L_add( base2bits[q], L_mult0( DEPR_i_mult( pred_yaw_bits[q], pred_imag_bands_yaw[q] ), bin_ch_2_num_sf ) ); + move32(); +#endif + + + base2bits[q] = L_add( base2bits[q], L_mult0( DEPR_i_mult( d_gain_bits, d_bands_yaw[q] ), num_subframes ) ); + move32(); + } + ELSE IF( EQ_32( pose_type, PITCH_ONLY ) ) + { + base2bits[q] = L_add( base2bits[q], L_mult0( DEPR_i_mult( pitch_gain_bits, bands_pitch[q] ), num_subframes ) ); + move32(); + base2bits[q] = L_add( base2bits[q], L_mult0( DEPR_i_mult( pitch_gain_bits, bands_pitch[q] ), num_subframes ) ); + move32(); + } + ELSE + { +#ifndef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS + base2bits[q] = L_add( base2bits[q], L_mult0( DEPR_i_mult( pred_roll_bits, pred_real_bands_roll[q] ), bin_ch_2_num_sf ) ); + move32(); + base2bits[q] = L_add( base2bits[q], L_mult0( DEPR_i_mult( pred_roll_bits, pred_imag_bands_roll[q] ), bin_ch_2_num_sf ) ); + move32(); +#else + base2bits[q] = L_add( base2bits[q], L_mult0( DEPR_i_mult( pred_roll_bits, pred_real_bands_roll[q] ), bin_ch_num_sf ) ); + move32(); + base2bits[q] = L_add( base2bits[q], L_mult0( DEPR_i_mult( pred_roll_bits, pred_imag_bands_roll[q] ), bin_ch_num_sf ) ); + move32(); + base2bits[q] = L_add( base2bits[q], L_mult0( DEPR_i_mult( pred_roll_bits, pred_imag_bands_roll[q] ), bin_ch_2_num_sf ) ); + move32(); +#endif + } + } + } + + return; +} + + +static void isar_SplitRenderer_code_md_base2( + const ISAR_BIN_HR_SPLIT_PRE_REND_HANDLE hBinHrSplitPreRend, + MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, + const Word16 num_subframes, + const Word16 pred_real_bands_yaw, + const Word16 pred_imag_bands_yaw, + const Word16 pred_quant_pnts_yaw, + const Word16 d_bands_yaw, + const Word16 bands_pitch, + const Word16 pred_real_bands_roll, + const Word16 pred_imag_bands_roll, + ISAR_SPLIT_REND_BITS_HANDLE pBits ) +{ + Word16 pos_idx, b, ch1, ch2, sf_idx; + Word16 min_pred_idx, min_gd_idx, min_p_gd_idx, pred_code_len, gd_code_len, p_gd_code_len, num_poses; + Word16 min_pred_roll_idx, pred_roll_code_len; + Word16 pred_cb_idx; + Word32 code; + ISAR_BIN_HR_SPLIT_REND_MD_HANDLE hMd; + ISAR_BIN_HR_SPLIT_REND_HUFF_HANDLE pHuff_cfg; + + pHuff_cfg = &hBinHrSplitPreRend->huff_cfg; + IF( EQ_16( pred_quant_pnts_yaw, ISAR_SPLIT_REND_PRED_63QUANT_PNTS ) ) + { + pred_cb_idx = 1; + move16(); + } + ELSE + { + pred_cb_idx = 0; + move16(); + } + min_pred_idx = extract_l( pHuff_cfg->pred[pred_cb_idx].codebook[0] ); + min_pred_roll_idx = extract_l( pHuff_cfg->pred_roll.codebook[0] ); + min_gd_idx = extract_l( pHuff_cfg->gd.codebook[0] ); + min_p_gd_idx = extract_l( pHuff_cfg->p_gd.codebook[0] ); + + pred_code_len = pHuff_cfg->pred_base2_code_len[pred_cb_idx]; + move16(); + pred_roll_code_len = pHuff_cfg->pred_roll_base2_code_len; + move16(); + gd_code_len = pHuff_cfg->gd_base2_code_len; + move16(); + p_gd_code_len = pHuff_cfg->p_gd_base2_code_len; + move16(); + + num_poses = pMultiBinPoseData->num_poses; + move16(); + + FOR( sf_idx = 0; sf_idx < num_subframes; sf_idx++ ) + { + FOR( pos_idx = 0; pos_idx < sub( num_poses, 1 ); pos_idx++ ) + { + IF( EQ_32( hBinHrSplitPreRend->pose_type[pos_idx], ANY_YAW ) ) + { +#ifndef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS + FOR( b = 0; b < pred_real_bands_yaw; b++ ) + { + hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b]; + FOR( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + { + FOR( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) + { + code = L_sub( hMd->pred_mat_re_idx[ch1][ch2], min_pred_idx ); + ISAR_SPLIT_REND_BITStream_write_int32( pBits, code, pred_code_len ); + } + } + } + + FOR( b = 0; b < pred_imag_bands_yaw; b++ ) + { + hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b]; + FOR( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + { + FOR( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) + { + code = L_sub( hMd->pred_mat_im_idx[ch1][ch2], min_pred_idx ); + ISAR_SPLIT_REND_BITStream_write_int32( pBits, code, pred_code_len ); + } + } + } +#else + FOR( b = 0; b < pred_imag_bands_yaw; b++ ) + { + hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b]; + FOR( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + { + FOR( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) + { + code = L_sub( hMd->pred_mat_re_idx[ch1][ch2], min_pred_idx ); + ISAR_SPLIT_REND_BITStream_write_int32( pBits, code, pred_code_len ); + } + } + + FOR( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + { + FOR( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) + { + code = L_sub( hMd->pred_mat_im_idx[ch1][ch2], min_pred_idx ); + ISAR_SPLIT_REND_BITStream_write_int32( pBits, code, pred_code_len ); + } + } + } + FOR( ; b < pred_real_bands_yaw; b++ ) + { + hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b]; + FOR( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + { + code = L_sub( hMd->pred_mat_re_idx[ch1][ch1], min_pred_idx ); + ISAR_SPLIT_REND_BITStream_write_int32( pBits, code, pred_code_len ); + } + } +#endif + FOR( b = 0; b < d_bands_yaw; b++ ) + { + hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b]; + code = L_sub( hMd->gd_idx, min_gd_idx ); + ISAR_SPLIT_REND_BITStream_write_int32( pBits, code, gd_code_len ); + } + } + ELSE IF( EQ_32( hBinHrSplitPreRend->pose_type[pos_idx], PITCH_ONLY ) ) + { + FOR( b = 0; b < bands_pitch; b++ ) + { + hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b]; + code = L_sub( hMd->gd_idx, min_p_gd_idx ); + ISAR_SPLIT_REND_BITStream_write_int32( pBits, code, p_gd_code_len ); + + code = L_sub( hMd->gd2_idx, min_p_gd_idx ); + ISAR_SPLIT_REND_BITStream_write_int32( pBits, code, p_gd_code_len ); + } + } + ELSE + { +#ifndef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS + FOR( b = 0; b < pred_real_bands_roll; b++ ) + { + hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b]; + FOR( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + { + FOR( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) + { + code = L_sub( hMd->pred_mat_re_idx[ch1][ch2], min_pred_roll_idx ); + ISAR_SPLIT_REND_BITStream_write_int32( pBits, code, pred_roll_code_len ); + } + } + } + + FOR( b = 0; b < pred_imag_bands_roll; b++ ) + { + hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b]; + FOR( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + { + FOR( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) + { + code = L_sub( hMd->pred_mat_im_idx[ch1][ch2], min_pred_roll_idx ); + ISAR_SPLIT_REND_BITStream_write_int32( pBits, code, pred_roll_code_len ); + } + } + } +#else + FOR( b = 0; b < pred_imag_bands_roll; b++ ) + { + hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b]; + FOR( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + { + FOR( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) + { + code = L_sub( hMd->pred_mat_re_idx[ch1][ch2], min_pred_roll_idx ); + ISAR_SPLIT_REND_BITStream_write_int32( pBits, code, pred_roll_code_len ); + } + } + + FOR( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + { + FOR( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) + { + code = L_sub( hMd->pred_mat_im_idx[ch1][ch2], min_pred_roll_idx ); + ISAR_SPLIT_REND_BITStream_write_int32( pBits, code, pred_roll_code_len ); + } + } + } + FOR( ; b < pred_real_bands_roll; b++ ) + { + hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b]; + FOR( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + { + code = L_sub( hMd->pred_mat_re_idx[ch1][ch1], min_pred_roll_idx ); + ISAR_SPLIT_REND_BITStream_write_int32( pBits, code, pred_roll_code_len ); + } + } +#endif + } + } + } + +#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG + { + static int16_t num_bits = 0; + static int16_t cntr = 0; + float fnum_bits; + + cntr++; + + num_bits += pBits->bits_written; + /* collect bits for every second */ + if ( cntr == 50 ) + { + cntr = 0; + fnum_bits = (float) num_bits / 1000.0f; + dbgwrite_txt( &fnum_bits, 1, "split_rend_MD_bitrate.txt", "MD bitrate (kbps)" ); + num_bits = 0; + } + } +#endif + return; +} + + +static void isar_SplitRenderer_code_md_huff( + const ISAR_BIN_HR_SPLIT_PRE_REND_HANDLE hBinHrSplitPreRend, + MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, + const Word16 num_subframes, + const Word16 pred_real_bands_yaw, + const Word16 pred_imag_bands_yaw, + const Word16 pred_quant_pnts_yaw, + const Word16 d_bands_yaw, + const Word16 bands_pitch, + const Word16 pred_real_bands_roll, + const Word16 pred_imag_bands_roll, + ISAR_SPLIT_REND_BITS_HANDLE pBits ) +{ + Word16 pos_idx, b, ch1, ch2, sf_idx, num_poses; + Word16 sym_adj_idx[BINAURAL_CHANNELS][BINAURAL_CHANNELS]; + Word16 min_pred_idx, max_pred_idx; + Word16 min_pred_roll_idx, max_pred_roll_idx, pred_cb_idx; + Word32 code, len; + ISAR_BIN_HR_SPLIT_REND_MD_HANDLE hMd; + ISAR_BIN_HR_SPLIT_REND_HUFF_HANDLE pHuff_cfg; + + pHuff_cfg = &hBinHrSplitPreRend->huff_cfg; + + IF( EQ_16( pred_quant_pnts_yaw, ISAR_SPLIT_REND_PRED_63QUANT_PNTS ) ) + { + pred_cb_idx = 1; + move16(); + } + ELSE + { + pred_cb_idx = 0; + move16(); + } + + min_pred_idx = extract_l( pHuff_cfg->pred[pred_cb_idx].codebook[0] ); + max_pred_idx = extract_l( pHuff_cfg->pred[pred_cb_idx].codebook[DEPR_i_mult( sub( pred_quant_pnts_yaw, 1 ), 3 )] ); + min_pred_roll_idx = extract_l( pHuff_cfg->pred_roll.codebook[0] ); + max_pred_roll_idx = extract_l( pHuff_cfg->pred_roll.codebook[DEPR_i_mult( sub( ISAR_SPLIT_REND_ROLL_PRED_QUANT_PNTS, 1 ), 3 )] ); + + num_poses = pMultiBinPoseData->num_poses; + move16(); + + FOR( sf_idx = 0; sf_idx < num_subframes; sf_idx++ ) + { + FOR( pos_idx = 0; pos_idx < sub( num_poses, 1 ); pos_idx++ ) + { + IF( EQ_32( hBinHrSplitPreRend->pose_type[pos_idx], ANY_YAW ) ) + { +#ifndef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS + FOR( b = 0; b < pred_real_bands_yaw; b++ ) + { + hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b]; + isar_SplitRenderer_getdiagdiff( hMd->pred_mat_re_idx, sym_adj_idx, -1, min_pred_idx, max_pred_idx ); + FOR( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + { + FOR( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) + { + isar_split_rend_huffman_encode( &pHuff_cfg->pred[pred_cb_idx], sym_adj_idx[ch1][ch2], &code, &len ); + ISAR_SPLIT_REND_BITStream_write_int32( pBits, code, len ); + } + } + } + FOR( b = 0; b < pred_imag_bands_yaw; b++ ) + { + hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b]; + isar_SplitRenderer_getdiagdiff( hMd->pred_mat_im_idx, sym_adj_idx, 1, min_pred_idx, max_pred_idx ); + FOR( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + { + FOR( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) + { + isar_split_rend_huffman_encode( &pHuff_cfg->pred[pred_cb_idx], sym_adj_idx[ch1][ch2], &code, &len ); + + ISAR_SPLIT_REND_BITStream_write_int32( pBits, code, len ); + } + } + } +#else + FOR( b = 0; b < pred_imag_bands_yaw; b++ ) + { + hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b]; + isar_SplitRenderer_getdiagdiff( hMd->pred_mat_re_idx, sym_adj_idx, -1, min_pred_idx, max_pred_idx ); + FOR( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + { + FOR( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) + { + isar_split_rend_huffman_encode( &pHuff_cfg->pred[pred_cb_idx], sym_adj_idx[ch1][ch2], &code, &len ); + ISAR_SPLIT_REND_BITStream_write_int32( pBits, code, len ); + } + } + + isar_SplitRenderer_getdiagdiff( hMd->pred_mat_im_idx, sym_adj_idx, 1, min_pred_idx, max_pred_idx ); + FOR( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + { + FOR( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) + { + isar_split_rend_huffman_encode( &pHuff_cfg->pred[pred_cb_idx], sym_adj_idx[ch1][ch2], &code, &len ); + + ISAR_SPLIT_REND_BITStream_write_int32( pBits, code, len ); + } + } + } + FOR( ; b < pred_real_bands_yaw; b++ ) + { + hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b]; + isar_SplitRenderer_getdiagdiff( hMd->pred_mat_re_idx, sym_adj_idx, 1, min_pred_idx, max_pred_idx ); + FOR( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + { + isar_split_rend_huffman_encode( &pHuff_cfg->pred[pred_cb_idx], sym_adj_idx[ch1][ch1], &code, &len ); + ISAR_SPLIT_REND_BITStream_write_int32( pBits, code, len ); + } + } +#endif + FOR( b = 0; b < d_bands_yaw; b++ ) + { + hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b]; + isar_split_rend_huffman_encode( &pHuff_cfg->gd, hMd->gd_idx, &code, &len ); + ISAR_SPLIT_REND_BITStream_write_int32( pBits, code, len ); + } + } + ELSE IF( EQ_32( hBinHrSplitPreRend->pose_type[pos_idx], PITCH_ONLY ) ) + { + FOR( b = 0; b < bands_pitch; b++ ) + { + hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b]; + isar_split_rend_huffman_encode( &pHuff_cfg->p_gd, hMd->gd_idx, &code, &len ); + ISAR_SPLIT_REND_BITStream_write_int32( pBits, code, len ); + + isar_split_rend_huffman_encode( &pHuff_cfg->p_gd, hMd->gd2_idx, &code, &len ); + ISAR_SPLIT_REND_BITStream_write_int32( pBits, code, len ); + } + } + ELSE + { +#ifndef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS + FOR( b = 0; b < pred_real_bands_roll; b++ ) + { + hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b]; + isar_SplitRenderer_getdiagdiff( hMd->pred_mat_re_idx, sym_adj_idx, -1, min_pred_roll_idx, max_pred_roll_idx ); + FOR( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + { + FOR( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) + { + isar_split_rend_huffman_encode( &pHuff_cfg->pred_roll, sym_adj_idx[ch1][ch2], &code, &len ); + ISAR_SPLIT_REND_BITStream_write_int32( pBits, code, len ); + } + } + } + FOR( b = 0; b < pred_imag_bands_roll; b++ ) + { + hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b]; + isar_SplitRenderer_getdiagdiff( hMd->pred_mat_im_idx, sym_adj_idx, 1, min_pred_roll_idx, max_pred_roll_idx ); + FOR( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + { + FOR( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) + { + isar_split_rend_huffman_encode( &pHuff_cfg->pred_roll, sym_adj_idx[ch1][ch2], &code, &len ); + ISAR_SPLIT_REND_BITStream_write_int32( pBits, code, len ); + } + } + } +#else + FOR( b = 0; b < pred_imag_bands_roll; b++ ) + { + hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b]; + isar_SplitRenderer_getdiagdiff( hMd->pred_mat_re_idx, sym_adj_idx, -1, min_pred_roll_idx, max_pred_roll_idx ); + FOR( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + { + FOR( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) + { + isar_split_rend_huffman_encode( &pHuff_cfg->pred_roll, sym_adj_idx[ch1][ch2], &code, &len ); + ISAR_SPLIT_REND_BITStream_write_int32( pBits, code, len ); + } + } + + isar_SplitRenderer_getdiagdiff( hMd->pred_mat_im_idx, sym_adj_idx, 1, min_pred_roll_idx, max_pred_roll_idx ); + FOR( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + { + FOR( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) + { + isar_split_rend_huffman_encode( &pHuff_cfg->pred_roll, sym_adj_idx[ch1][ch2], &code, &len ); + ISAR_SPLIT_REND_BITStream_write_int32( pBits, code, len ); + } + } + } + FOR( ; b < pred_real_bands_roll; b++ ) + { + hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b]; + isar_SplitRenderer_getdiagdiff( hMd->pred_mat_re_idx, sym_adj_idx, 1, min_pred_roll_idx, max_pred_roll_idx ); + FOR( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + { + isar_split_rend_huffman_encode( &pHuff_cfg->pred_roll, sym_adj_idx[ch1][ch1], &code, &len ); + ISAR_SPLIT_REND_BITStream_write_int32( pBits, code, len ); + } + } +#endif + } + } + } + +#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG + { + static int16_t num_bits = 0; + static int16_t cntr = 0; + float fnum_bits; + + cntr++; + num_bits += pBits->bits_written; + /* collect bits for every second */ + IF( cntr == 50 ) + { + cntr = 0; + fnum_bits = (float) num_bits / 1000.0f; + dbgwrite_txt( &fnum_bits, 1, "split_rend_MD_bitrate.txt", "MD bitrate (kbps)" ); + num_bits = 0; + } + } +#endif + return; +} + +static void isar_SplitRenderer_quant_code( + const ISAR_BIN_HR_SPLIT_PRE_REND_HANDLE hBinHrSplitPreRend, + const IVAS_QUATERNION headPosition, + MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, + ISAR_SPLIT_REND_BITS_HANDLE pBits, + const Word16 low_res_pre_rend_rot, +#ifdef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS + const int16_t ro_md_flag, +#endif + const Word32 target_md_bits, + Word16 Q_frame ) +{ +#ifdef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS + Word16 q, num_subframes, sf_idx, pos_idx, b, num_quant_strats; +#else + Word16 num_complex_bands, q, num_subframes, sf_idx, pos_idx, b, num_quant_strats; +#endif + Word32 overhead_bits, quant_strat_bits, huff_bits, start_bit; + Word16 pred_real_bands_yaw[ISAR_SPLIT_REND_NUM_QUANT_STRATS], pred_real_bands_roll[ISAR_SPLIT_REND_NUM_QUANT_STRATS]; + Word16 pred_imag_bands_yaw[ISAR_SPLIT_REND_NUM_QUANT_STRATS], pred_imag_bands_roll[ISAR_SPLIT_REND_NUM_QUANT_STRATS]; + Word16 d_bands_yaw[ISAR_SPLIT_REND_NUM_QUANT_STRATS], bands_pitch[ISAR_SPLIT_REND_NUM_QUANT_STRATS]; + Word32 base2bits[ISAR_SPLIT_REND_NUM_QUANT_STRATS]; + Word16 pred_quant_pnts_yaw[ISAR_SPLIT_REND_NUM_QUANT_STRATS]; + Word32 pred_1byquantstep_yaw_fx[ISAR_SPLIT_REND_NUM_QUANT_STRATS]; + Word32 pred_quantstep_yaw_fx[ISAR_SPLIT_REND_NUM_QUANT_STRATS]; +#ifdef DEBUG_QUANT_MD_FX + float pred_1byquantstep_yaw[ISAR_SPLIT_REND_NUM_QUANT_STRATS]; + float pred_quantstep_yaw[ISAR_SPLIT_REND_NUM_QUANT_STRATS]; +#endif + ISAR_BIN_HR_SPLIT_REND_MD_HANDLE hMd; +#ifdef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS + Word16 rot_axis_code, num_bits; +#endif + + IF( low_res_pre_rend_rot ) + { + num_subframes = 1; + } + ELSE + { + num_subframes = MAX_PARAM_SPATIAL_SUBFRAMES; + } + + overhead_bits = pBits->bits_written; + + ISAR_SPLIT_REND_BITStream_write_int32( pBits, pMultiBinPoseData->dof, ISAR_SPLIT_REND_DOF_BITS ); + ISAR_SPLIT_REND_BITStream_write_int32( pBits, pMultiBinPoseData->hq_mode, ISAR_SPLIT_REND_HQ_MODE_BITS ); +#ifdef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS + rot_axis_code = isar_renderSplitGetCodeFromRot_axis( pMultiBinPoseData->dof, pMultiBinPoseData->rot_axis, &num_bits ); + if ( num_bits > 0 ) + { + ISAR_SPLIT_REND_BITStream_write_int32( pBits, (int32_t) rot_axis_code, num_bits ); + } + ISAR_SPLIT_REND_BITStream_write_int32( pBits, (int32_t) ro_md_flag, ISAR_SPLIT_REND_RO_FLAG_BITS ); +#else + ISAR_SPLIT_REND_BITStream_write_int32( pBits, (int32_t) pMultiBinPoseData->rot_axis, ISAR_SPLIT_REND_ROT_AXIS_BITS ); +#endif + + /* code ref pose*/ + FOR( sf_idx = 0; sf_idx < num_subframes; sf_idx++ ) + { + Word16 angle; + IVAS_QUATERNION head_pos_euler, headPosition_q22; + + modify_Quat_q_fx( &headPosition, &headPosition_q22, Q22 ); + Quat2EulerDegree_fx( headPosition_q22, &head_pos_euler.z_fx, &head_pos_euler.y_fx, &head_pos_euler.x_fx ); + angle = (Word16) L_shr_r( head_pos_euler.x_fx, Q22 ); + angle = add( angle, 180 ); + ISAR_SPLIT_REND_BITStream_write_int32( pBits, angle, ISAR_SPLIT_REND_HEAD_POSE_BITS ); + + angle = (Word16) L_shr_r( head_pos_euler.y_fx, Q22 ); + angle = add( angle, 180 ); + ISAR_SPLIT_REND_BITStream_write_int32( pBits, angle, ISAR_SPLIT_REND_HEAD_POSE_BITS ); + + angle = (Word16) L_shr_r( head_pos_euler.z_fx, Q22 ); + angle = add( angle, 180 ); + + ISAR_SPLIT_REND_BITStream_write_int32( pBits, angle, ISAR_SPLIT_REND_HEAD_POSE_BITS ); + } + +#ifdef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS + isar_split_rend_get_quant_params_fx( MAX_SPLIT_REND_MD_BANDS, pred_real_bands_yaw, pred_imag_bands_yaw, + pred_quant_pnts_yaw, pred_quantstep_yaw_fx, pred_1byquantstep_yaw_fx, + d_bands_yaw, bands_pitch, pred_real_bands_roll, pred_imag_bands_roll, ro_md_flag, &num_quant_strats ); +#else + isar_split_rend_get_quant_params_fx( MAX_SPLIT_REND_MD_BANDS, pred_real_bands_yaw, pred_imag_bands_yaw, + pred_quant_pnts_yaw, pred_quantstep_yaw_fx, pred_1byquantstep_yaw_fx, + d_bands_yaw, bands_pitch, pred_real_bands_roll, pred_imag_bands_roll, &num_quant_strats, &num_complex_bands ); +#endif +#ifdef DEBUG_QUANT_MD_FX + fixedToFloat_arrL( pred_quantstep_yaw_fx, pred_quantstep_yaw, Q31, ISAR_SPLIT_REND_NUM_QUANT_STRATS ); + fixedToFloat_arrL( pred_1byquantstep_yaw_fx, pred_1byquantstep_yaw, Q26, ISAR_SPLIT_REND_NUM_QUANT_STRATS ); +#endif + + quant_strat_bits = ceil_log_2( num_quant_strats ); + + overhead_bits = L_add( L_add( L_sub( pBits->bits_written, overhead_bits ), quant_strat_bits ), 1 ); /* 1 for base2 vs huff */ + + get_base2_bits( hBinHrSplitPreRend, pMultiBinPoseData, num_subframes, num_quant_strats, pred_real_bands_yaw, pred_imag_bands_yaw, + pred_quant_pnts_yaw, + d_bands_yaw, bands_pitch, pred_real_bands_roll, pred_imag_bands_roll, base2bits ); + + FOR( q = 0; q < num_quant_strats; q++ ) + { + FOR( sf_idx = 0; sf_idx < num_subframes; sf_idx++ ) + { + FOR( pos_idx = 0; pos_idx < pMultiBinPoseData->num_poses - 1; pos_idx++ ) + { + IF( hBinHrSplitPreRend->pose_type[pos_idx] == ANY_YAW ) + { + FOR( b = 0; b < pred_imag_bands_yaw[q]; b++ ) + { + hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b]; + isar_split_rend_quant_md_fx( hMd, PRED_ONLY, 0, hBinHrSplitPreRend->fix_pos_rot_mat_fx[pos_idx], pred_1byquantstep_yaw_fx[q], Q_frame +#ifdef DEBUG_QUANT_MD_FX + , + hBinHrSplitPreRend->fix_pos_rot_mat[pos_idx], pred_1byquantstep_yaw[q] +#endif + ); + } + FOR( ; b < pred_real_bands_yaw[q]; b++ ) + { + hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b]; + isar_split_rend_quant_md_fx( hMd, PRED_ONLY, 1, hBinHrSplitPreRend->fix_pos_rot_mat_fx[pos_idx], pred_1byquantstep_yaw_fx[q], Q_frame +#ifdef DEBUG_QUANT_MD_FX + , + hBinHrSplitPreRend->fix_pos_rot_mat[pos_idx], pred_1byquantstep_yaw[q] +#endif + ); + } + + FOR( b = 0; b < d_bands_yaw[q]; b++ ) + { + hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b]; + isar_split_rend_quant_md_fx( hMd, COM_GAIN_ONLY, 1, hBinHrSplitPreRend->fix_pos_rot_mat_fx[pos_idx], 0, Q_frame +#ifdef DEBUG_QUANT_MD_FX + , + hBinHrSplitPreRend->fix_pos_rot_mat[pos_idx], 0.0f +#endif + ); + } + } + ELSE IF( hBinHrSplitPreRend->pose_type[pos_idx] == PITCH_ONLY ) + { + FOR( b = 0; b < bands_pitch[q]; b++ ) + { + hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b]; + isar_split_rend_quant_md_fx( hMd, LR_GAIN_ONLY, 1, hBinHrSplitPreRend->fix_pos_rot_mat_fx[pos_idx], 0, Q_frame +#ifdef DEBUG_QUANT_MD_FX + , + hBinHrSplitPreRend->fix_pos_rot_mat[pos_idx], 0.0f +#endif + ); + } + } + ELSE + { + FOR( b = 0; b < pred_imag_bands_roll[q]; b++ ) + { + hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b]; + isar_split_rend_quant_md_fx( hMd, PRED_ROLL_ONLY, 0, hBinHrSplitPreRend->fix_pos_rot_mat_fx[pos_idx], ISAR_SPLIT_REND_PRED_ROLL_1BYQ_STEP_Q26, Q_frame +#ifdef DEBUG_QUANT_MD_FX + , + hBinHrSplitPreRend->fix_pos_rot_mat[pos_idx], ISAR_SPLIT_REND_PRED_ROLL_1BYQ_STEP +#endif + ); + } + FOR( ; b < pred_real_bands_roll[q]; b++ ) + { + hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b]; + isar_split_rend_quant_md_fx( hMd, PRED_ROLL_ONLY, 1, hBinHrSplitPreRend->fix_pos_rot_mat_fx[pos_idx], ISAR_SPLIT_REND_PRED_ROLL_1BYQ_STEP_Q26, Q_frame +#ifdef DEBUG_QUANT_MD_FX + , + hBinHrSplitPreRend->fix_pos_rot_mat[pos_idx], ISAR_SPLIT_REND_PRED_ROLL_1BYQ_STEP +#endif + ); + } + } + } + } + + /*get base2 bits and check if its within target. if yes then code with base2 to save complexity on post renderer*/ + start_bit = pBits->bits_written; + + ISAR_SPLIT_REND_BITStream_write_int32( pBits, 1, 1 ); + ISAR_SPLIT_REND_BITStream_write_int32( pBits, q, quant_strat_bits ); + + huff_bits = pBits->bits_written; + isar_SplitRenderer_code_md_huff( + hBinHrSplitPreRend, + pMultiBinPoseData, + num_subframes, + pred_real_bands_yaw[q], + pred_imag_bands_yaw[q], + pred_quant_pnts_yaw[q], + d_bands_yaw[q], + bands_pitch[q], + pred_real_bands_roll[q], + pred_imag_bands_roll[q], + pBits ); + + huff_bits = L_sub( pBits->bits_written, huff_bits ); + test(); + test(); + test(); + IF( GE_32( target_md_bits, ( base2bits[q] + overhead_bits ) ) || GE_32( target_md_bits, ( huff_bits + overhead_bits ) ) || EQ_16( q, sub( num_quant_strats, 1 ) ) ) + { + IF( GT_32( huff_bits, base2bits[q] ) ) + { + pBits->bits_written = start_bit; + + ISAR_SPLIT_REND_BITStream_write_int32( pBits, 0, 1 ); + ISAR_SPLIT_REND_BITStream_write_int32( pBits, q, quant_strat_bits ); + + isar_SplitRenderer_code_md_base2( hBinHrSplitPreRend, pMultiBinPoseData, num_subframes, pred_real_bands_yaw[q], pred_imag_bands_yaw[q], + pred_quant_pnts_yaw[q], + d_bands_yaw[q], bands_pitch[q], pred_real_bands_roll[q], pred_imag_bands_roll[q], pBits ); + } + BREAK; + } + + pBits->bits_written = start_bit; + } + +#ifdef SPLIT_MD_CODING_DEBUG + for ( sf_idx = 0; sf_idx < num_subframes; sf_idx++ ) + { + int16_t val, quant_strat, ch1, ch2; + char filename[200] = "split_md_debug_indices.bin"; + quant_strat = q; + for ( pos_idx = 0; pos_idx < pMultiBinPoseData->num_poses - 1; pos_idx++ ) + { + if ( hBinHrSplitPreRend->pose_type[pos_idx] == ANY_YAW ) + { + for ( b = 0; b < pred_real_bands_yaw[quant_strat]; b++ ) + { + for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + { + for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) + { + val = hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].pred_mat_re_idx[ch1][ch2]; + dbgwrite( &val, sizeof( int16_t ), 1, 1, filename ); + } + } + } + for ( b = 0; b < pred_imag_bands_yaw[quant_strat]; b++ ) + { + for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + { + for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) + { + val = hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].pred_mat_im_idx[ch1][ch2]; + dbgwrite( &val, sizeof( int16_t ), 1, 1, filename ); + } + } + } + for ( b = 0; b < d_bands_yaw[quant_strat]; b++ ) + { + val = hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].gd_idx; + dbgwrite( &val, sizeof( int16_t ), 1, 1, filename ); + } + } + else if ( hBinHrSplitPreRend->pose_type[pos_idx] == PITCH_ONLY ) + { + for ( b = 0; b < bands_pitch[quant_strat]; b++ ) + { + val = hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].gd_idx; + dbgwrite( &val, sizeof( int16_t ), 1, 1, filename ); + val = hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].gd2_idx; + dbgwrite( &val, sizeof( int16_t ), 1, 1, filename ); + } + } + else + { + for ( b = 0; b < pred_real_bands_roll[quant_strat]; b++ ) + { + for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + { + for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) + { + val = hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].pred_mat_re_idx[ch1][ch2]; + dbgwrite( &val, sizeof( int16_t ), 1, 1, filename ); + } + } + } + for ( b = 0; b < pred_imag_bands_roll[quant_strat]; b++ ) + { + for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + { + for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) + { + val = hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].pred_mat_im_idx[ch1][ch2]; + dbgwrite( &val, sizeof( int16_t ), 1, 1, filename ); + } + } + } + } + } + } +#endif + + return; +} +/*------------------------------------------------------------------------- + * Function isar_SplitRenderer_GetRotMd() + * + * + *------------------------------------------------------------------------*/ + +static void isar_SplitRenderer_GetRotMd_fx( + ISAR_BIN_HR_SPLIT_PRE_REND_HANDLE hBinHrSplitPreRend, /* i/o: binaural renderer handle */ + MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, + Word32 Cldfb_RealBuffer_Ref_Binaural_fx[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], /* o : Reference Binaural signals */ + Word16 exp_cldfb_re, + Word32 Cldfb_ImagBuffer_Ref_Binaural_fx[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], /* o : Reference Binaural signals */ + Word16 exp_cldfb_im, + const Word16 low_res, + const Word16 ro_md_flag ) +{ + Word32 cov_ii_re_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS] = { 0 }; + Word32 cov_oo_re_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS] = { 0 }; + Word32 cov_io_re_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS] = { 0 }; + Word32 cov_ii_im_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS] = { 0 }; + Word32 cov_oo_im_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS] = { 0 }; + Word32 cov_io_im_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS] = { 0 }; + Word16 exp_cov_io_re = 0, exp_cov_io_im = 0; + Word16 exp_cov_ii_re = 0, exp_cov_ii_im = 0; + Word16 exp_cov_oo_re = 0, exp_cov_oo_im = 0; + + Word16 real_only = 0; + Word16 pos_idx, b, sf_idx, start_slot_idx, num_slots, num_subframes, ch_s_idx1, ch_s_idx2; + Word16 num_md_bands, num_poses; + const Word16 *pBand_grouping = isar_split_rend_band_grouping; + + push_wmops( "isar_SplitRenderer_GetRotMd_fx" ); + + num_md_bands = MAX_SPLIT_REND_MD_BANDS; + move16(); + num_poses = pMultiBinPoseData->num_poses; + move16(); + + IF( low_res ) + { + num_slots = CLDFB_NO_COL_MAX; + move16(); + num_subframes = 1; + move16(); + } + ELSE + { + num_slots = MAX_PARAM_SPATIAL_SUBFRAMES; + move16(); + num_subframes = MAX_PARAM_SPATIAL_SUBFRAMES; + move16(); + } + + /* compute reference signal covariance */ + FOR( sf_idx = 0; sf_idx < num_subframes; sf_idx++ ) + { + start_slot_idx = imult1616( sf_idx, num_slots ); + FOR( b = 0; b < num_md_bands; b++ ) + { + test(); + IF( LT_16( b, SPLIT_REND_RO_MD_BAND_THRESH ) || ( !ro_md_flag && b < COMPLEX_MD_BAND_THRESH ) ) + { + real_only = 0; + move16(); + } + ELSE + { + real_only = 1; + move16(); + } + + ch_s_idx1 = 0; + + ComputeBandedCov_fx( Cldfb_RealBuffer_Ref_Binaural_fx, exp_cldfb_re, Cldfb_ImagBuffer_Ref_Binaural_fx, exp_cldfb_im, ch_s_idx1, cov_ii_re_fx, &exp_cov_ii_re, cov_ii_im_fx, &exp_cov_ii_im, BINAURAL_CHANNELS, pBand_grouping, num_slots, start_slot_idx, b, real_only ); + + /* compute rotated signal covariance */ + FOR( pos_idx = 0; pos_idx < num_poses - 1; pos_idx++ ) + { + IF( hBinHrSplitPreRend->pose_type[pos_idx] == ANY_ROLL ) + { + IF( GE_16( b, SPLIT_REND_RO_MD_BAND_THRESH ) ) + { + real_only = 1; + } + } + ch_s_idx2 = imult1616( add( pos_idx, 1 ), BINAURAL_CHANNELS ); + + ComputeBandedCrossCov_fx( Cldfb_RealBuffer_Ref_Binaural_fx, exp_cldfb_re, Cldfb_ImagBuffer_Ref_Binaural_fx, exp_cldfb_im, ch_s_idx1, Cldfb_RealBuffer_Ref_Binaural_fx, exp_cldfb_re, Cldfb_ImagBuffer_Ref_Binaural_fx, exp_cldfb_im, ch_s_idx2, cov_io_re_fx, &exp_cov_io_re, cov_io_im_fx, &exp_cov_io_im, BINAURAL_CHANNELS, pBand_grouping, num_slots, start_slot_idx, b, real_only ); + + ComputeBandedCov_fx( Cldfb_RealBuffer_Ref_Binaural_fx, exp_cldfb_re, Cldfb_ImagBuffer_Ref_Binaural_fx, exp_cldfb_im, ch_s_idx2, cov_oo_re_fx, &exp_cov_oo_re, cov_oo_im_fx, &exp_cov_oo_im, BINAURAL_CHANNELS, pBand_grouping, num_slots, start_slot_idx, b, real_only ); + + ComputeCoeffs_fx( cov_ii_re_fx, exp_cov_ii_re, cov_ii_im_fx, exp_cov_ii_im, cov_io_re_fx, exp_cov_io_re, cov_io_im_fx, exp_cov_io_im, cov_oo_re_fx, exp_cov_oo_re, &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b], hBinHrSplitPreRend->pose_type[pos_idx], real_only ); + } + } + } + + pop_wmops(); + return; +} +/*------------------------------------------------------------------------- + * Function isar_rend_CldfbSplitPreRendProcess() + * + * + *------------------------------------------------------------------------*/ +void isar_rend_CldfbSplitPreRendProcess( + const ISAR_BIN_HR_SPLIT_PRE_REND_HANDLE hBinHrSplitPreRend, + const IVAS_QUATERNION headPosition, + MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, + Word32 Cldfb_In_BinReal_fx[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + Word16 exp_cldfb_re, + Word32 Cldfb_In_BinImag_fx[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + Word16 exp_cldfb_im, + ISAR_SPLIT_REND_BITS_HANDLE pBits, + const Word32 target_md_bits, + const Word16 low_res_pre_rend_rot, + const Word16 ro_md_flag ) +{ + push_wmops( "isar_rend_CldfbSplitPreRendProcess" ); + + isar_SplitRenderer_GetRotMd_fx( hBinHrSplitPreRend, pMultiBinPoseData, Cldfb_In_BinReal_fx, exp_cldfb_re, Cldfb_In_BinImag_fx, exp_cldfb_im, low_res_pre_rend_rot, ro_md_flag ); + + Word16 num_md_bands, num_poses; + Word16 pos_idx, b, sf_idx, num_subframes; + + num_md_bands = MAX_SPLIT_REND_MD_BANDS; + num_poses = pMultiBinPoseData->num_poses; + + IF( low_res_pre_rend_rot ) + { + num_subframes = 1; + } + ELSE + { + num_subframes = MAX_PARAM_SPATIAL_SUBFRAMES; + } + + /*FILE *filePointer_gd, *filePointer_gd2; + FILE *filePointer_re, *filePointer_im; + filePointer_gd = fopen("Fixed_code_cov_gd_complete.txt", "a"); + filePointer_gd2 = fopen("Fixed_code_cov_gd2_complete.txt", "a"); + filePointer_re = fopen("Fixed_code_re_complete.txt", "a"); + filePointer_im = fopen("Fixed_code_im_complete.txt", "a");*/ + +#ifdef DUMP_GETROTMD_OUTPUT + for ( sf_idx = 0; sf_idx < num_subframes; sf_idx++ ) + { + for ( b = 0; b < num_md_bands; b++ ) + { + for ( pos_idx = 0; pos_idx < num_poses - 1; pos_idx++ ) + { + if ( hBinHrSplitPreRend->pose_type[pos_idx] == PITCH_ONLY ) + { + hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].gd = me2f( hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].gd_fx, hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].exp_gd ); + hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].gd2 = me2f( hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].gd2_fx, hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].exp_gd2 ); + /*fprintf(filePointer_gd, "%f\n", hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].gd); + fprintf(filePointer_gd2, "%f\n", hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].gd2);*/ + } + else + { + for ( int i = 0; i < BINAURAL_CHANNELS; i++ ) + { + for ( int j = 0; j < BINAURAL_CHANNELS; j++ ) + { + hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].pred_mat_re[i][j] = me2f( hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].pred_mat_re_fx[i][j], hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].exp_pred_mat_re ); + hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].pred_mat_im[i][j] = me2f( hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].pred_mat_im_fx[i][j], hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].exp_pred_mat_im ); + /*fprintf(filePointer_re, "%f\n", hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].pred_mat_re[i][j]); + fprintf(filePointer_im, "%f\n", hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].pred_mat_im[i][j]);*/ + } + } + } + } + } + } +#endif + + /*fclose(filePointer_gd); + fclose(filePointer_gd2); + fclose(filePointer_re); + fclose(filePointer_im);*/ + + /* Check if rescaling can be simplified/avoid */ + + Word16 exp_frame = 0; + // Word32 L_temp_max = 0; + FOR( sf_idx = 0; sf_idx < num_subframes; sf_idx++ ) + { + FOR( b = 0; b < num_md_bands; b++ ) + { + FOR( pos_idx = 0; pos_idx < num_poses - 1; pos_idx++ ) + { + IF( hBinHrSplitPreRend->pose_type[pos_idx] == PITCH_ONLY ) + { + exp_frame = s_max( exp_frame, hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].exp_gd ); + exp_frame = s_max( exp_frame, hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].exp_gd2 ); + } + ELSE + { + exp_frame = s_max( exp_frame, hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].exp_pred_mat_re ); +#ifdef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS + exp_frame = s_max( exp_frame, hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].exp_pred_mat_re2 ); +#endif + exp_frame = s_max( exp_frame, hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].exp_pred_mat_im ); + } + } + } + } + // exp_frame = s_min( exp_frame, sub( 31, norm_l( L_temp_max ) ) ); + exp_frame = s_min( exp_frame, 15 ); // Considering the max value as of prediction matrices as 300 + + Word16 Q_frame = sub( Q31, exp_frame ); + FOR( sf_idx = 0; sf_idx < num_subframes; sf_idx++ ) + { + FOR( b = 0; b < num_md_bands; b++ ) + { + FOR( pos_idx = 0; pos_idx < num_poses - 1; pos_idx++ ) + { + IF( hBinHrSplitPreRend->pose_type[pos_idx] == PITCH_ONLY ) + { + hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].gd_fx = L_shr_r( hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].gd_fx, sub( exp_frame, hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].exp_gd ) ); + hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].gd2_fx = L_shr_r( hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].gd2_fx, sub( exp_frame, hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].exp_gd2 ) ); + /*fprintf(filePointer_gd, "%f\n", hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].gd); + fprintf(filePointer_gd2, "%f\n", hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].gd2);*/ + } + ELSE + { + FOR( Word16 i = 0; i < BINAURAL_CHANNELS; i++ ) + { + Scale_sig32( hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].pred_mat_re_fx[i], BINAURAL_CHANNELS, sub( hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].exp_pred_mat_re, exp_frame ) ); + Scale_sig32( hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].pred_mat_im_fx[i], BINAURAL_CHANNELS, sub( hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].exp_pred_mat_im, exp_frame ) ); + } +#ifdef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS + Scale_sig32( hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].pred_mat_re2, BINAURAL_CHANNELS, sub( hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].exp_pred_mat_re2, exp_frame ) ); +#endif + } + } + } + } + +#ifdef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS + isar_SplitRenderer_quant_code( hBinHrSplitPreRend, headPosition, pMultiBinPoseData, pBits, low_res_pre_rend_rot, ro_md_flag, target_md_bits, Q_frame ); +#else + isar_SplitRenderer_quant_code( hBinHrSplitPreRend, headPosition, pMultiBinPoseData, pBits, low_res_pre_rend_rot, target_md_bits, Q_frame ); +#endif +#ifdef DEBUG_QUANT_CODE_OUT + for ( sf_idx = 0; sf_idx < num_subframes; sf_idx++ ) + { + for ( b = 0; b < num_md_bands; b++ ) + { + for ( pos_idx = 0; pos_idx < num_poses - 1; pos_idx++ ) + { + if ( hBinHrSplitPreRend->pose_type[pos_idx] == PITCH_ONLY ) + { + hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].gd = fixedToFloat( hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].gd_fx, Q_frame ); + hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].gd2 = fixedToFloat( hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].gd2_fx, Q_frame ); + /*fprintf(filePointer_gd, "%f\n", hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].gd); + fprintf(filePointer_gd2, "%f\n", hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].gd2);*/ + } + else + { + for ( int i = 0; i < BINAURAL_CHANNELS; i++ ) + { + fixedToFloat_arrL( hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].pred_mat_re_fx[i], hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].pred_mat_re[i], Q_frame, BINAURAL_CHANNELS ); + fixedToFloat_arrL( hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].pred_mat_im_fx[i], hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].pred_mat_im[i], Q_frame, BINAURAL_CHANNELS ); + // for ( int j = 0; j < BINAURAL_CHANNELS; j++ ) + //{ + // hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].pred_mat_re[i][j] = me2f( hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].pred_mat_re_fx[i][j], Q6 ); + // hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].pred_mat_im[i][j] = me2f( hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].pred_mat_im_fx[i][j], Q6 ); + // /*fprintf(filePointer_re, "%f\n", hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].pred_mat_re[i][j]); + // fprintf(filePointer_im, "%f\n", hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].pred_mat_im[i][j]);*/ + // } + } + } + } + } + } +#endif +#ifdef SPLIT_POSE_CORRECTION_DEBUG + float tmpCrendBuffer[2][L_FRAME48k], quant_val, step, minv, maxv; + IVAS_QUATERNION QuaternionsPost[MAX_PARAM_SPATIAL_SUBFRAMES], head_pos_euler; + float Cldfb_RealBuffer_Binaural_5ms[BINAURAL_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX]; + float Cldfb_ImagBuffer_Binaural_5ms[BINAURAL_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX]; + int16_t sf_idx, pos_idx, b, ch1, ch2; + int32_t read_off, write_off; + for ( sf_idx = 0; sf_idx < MAX_PARAM_SPATIAL_SUBFRAMES; sf_idx++ ) + { + QuaternionsPost[sf_idx].w = -3.0f; + QuaternionsPost[sf_idx].x = 0.0f; + QuaternionsPost[sf_idx].y = 0.0f; + QuaternionsPost[sf_idx].z = 0.0f; + } + + hBinHrSplitPreRend->hBinHrSplitPostRend->low_Res = 1; + set_fix_rotation_mat( hBinHrSplitPreRend->hBinHrSplitPostRend->fix_pos_rot_mat, pMultiBinPoseData ); + set_pose_types( hBinHrSplitPreRend->hBinHrSplitPostRend->pose_type, pMultiBinPoseData ); + for ( sf_idx = 0; sf_idx < MAX_PARAM_SPATIAL_SUBFRAMES; sf_idx++ ) + { + Quat2EulerDegree( headPosition, &head_pos_euler.z, &head_pos_euler.y, &head_pos_euler.x ); + hBinHrSplitPreRend->hBinHrSplitPostRend->QuaternionsPre[sf_idx].w = -3.0f; + hBinHrSplitPreRend->hBinHrSplitPostRend->QuaternionsPre[sf_idx].x = roundf( head_pos_euler.x ); + hBinHrSplitPreRend->hBinHrSplitPostRend->QuaternionsPre[sf_idx].y = roundf( head_pos_euler.y ); + hBinHrSplitPreRend->hBinHrSplitPostRend->QuaternionsPre[sf_idx].z = roundf( head_pos_euler.z ); + } + for ( sf_idx = 0; sf_idx < 1; sf_idx++ ) + { + for ( pos_idx = 0; pos_idx < pMultiBinPoseData->num_poses - 1; pos_idx++ ) + { + 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]; + BIN_HR_SPLIT_REND_MD_HANDLE hMd; + hMd = &hBinHrSplitPreRend->hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b]; + minv = -1.4f; + maxv = 1.4f; + step = ( maxv - minv ) / 62.0f; + if ( b >= 20 ) + { + float sign; + for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + { + for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) + { + sign = ( hMd->pred_mat_re[ch1][ch2] >= 0.0f ) ? 1.0f : -1.0f; + IVAS_CALCULATE_ABS( hMd->pred_mat_re[ch1][ch2], hMd->pred_mat_im[ch1][ch2], hMd->pred_mat_re[ch1][ch2] ); + hMd->pred_mat_re[ch1][ch2] *= sign; + hMd->pred_mat_im[ch1][ch2] = 0.0f; + } + } + } + + for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + { + for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) + { + quant_val = hMd->pred_mat_re[ch1][ch2] - hBinHrSplitPreRend->fix_pos_rot_mat[pos_idx][ch1][ch2]; + quant_val = min( maxv, max( quant_val, minv ) ); + quant_val = (int16_t) roundf( quant_val / step ); + hMd->pred_mat_re[ch1][ch2] = quant_val * step; + hMd->pred_mat_re[ch1][ch2] += hBinHrSplitPreRend->fix_pos_rot_mat[pos_idx][ch1][ch2]; + + quant_val = hMd->pred_mat_im[ch1][ch2]; + quant_val = min( maxv, max( quant_val, minv ) ); + quant_val = (int16_t) roundf( quant_val / step ); + hMd->pred_mat_im[ch1][ch2] = quant_val * step; + } + } + } + } + } + + 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 ); + mvr2r( (float *) Cldfb_In_BinReal[1][sf_idx * MAX_PARAM_SPATIAL_SUBFRAMES], (float *) Cldfb_RealBuffer_Binaural_5ms[1], MAX_PARAM_SPATIAL_SUBFRAMES * CLDFB_NO_CHANNELS_MAX ); + mvr2r( (float *) Cldfb_In_BinImag[0][sf_idx * MAX_PARAM_SPATIAL_SUBFRAMES], (float *) Cldfb_ImagBuffer_Binaural_5ms[0], MAX_PARAM_SPATIAL_SUBFRAMES * CLDFB_NO_CHANNELS_MAX ); + mvr2r( (float *) Cldfb_In_BinImag[1][sf_idx * MAX_PARAM_SPATIAL_SUBFRAMES], (float *) Cldfb_ImagBuffer_Binaural_5ms[1], MAX_PARAM_SPATIAL_SUBFRAMES * CLDFB_NO_CHANNELS_MAX ); + isar_rend_CldfbSplitPostRendProcess( hBinHrSplitPreRend->hBinHrSplitPostRend, pMultiBinPoseData, QuaternionsPost[0], Cldfb_RealBuffer_Binaural_5ms, Cldfb_ImagBuffer_Binaural_5ms, tmpCrendBuffer, 1 ); + + { + float *pOut[2]; + char fname[200] = "ref_act_pos.wav"; + pOut[0] = tmpCrendBuffer[0]; + pOut[1] = tmpCrendBuffer[1]; + dbgwrite_wav( pOut, CLDFB_NO_COL_MAX * hBinHrSplitPreRend->hBinHrSplitPostRend->cldfbSyn[0]->no_channels, fname, 48000, 2 ); + } + } +#endif + + pop_wmops(); + return; +} + +/*------------------------------------------------------------------------- + * Function isar_splitBinPreRendOpen() + * + * + *------------------------------------------------------------------------*/ +ivas_error isar_splitBinPreRendOpen( + ISAR_BIN_HR_SPLIT_PRE_REND_HANDLE *hBinHrSplitPreRend, + MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData +#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG + , + const int32_t output_Fs +#endif +) +{ + ISAR_BIN_HR_SPLIT_PRE_REND_HANDLE hBinRend; +#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG + ivas_error error; + int16_t ch; +#endif + Word16 pos_idx, sf_idx, bandIdx; + + IF( ( hBinRend = (ISAR_BIN_HR_SPLIT_PRE_REND_HANDLE) malloc( sizeof( ISAR_BIN_HR_SPLIT_PRE_REND ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for bin split pre renderer Module \n" ) ); + } + +#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG + for ( int16_t i = 0; i < MAX_HEAD_ROT_POSES + 1; i++ ) + { + for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) + { + hBinRend->cldfbSynRotBinDec[i][ch] = NULL; + } + } + + for ( int16_t i = 0; i < MAX_HEAD_ROT_POSES + 1; i++ ) + { + for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) + { + if ( ( error = openCldfb( &( hBinRend->cldfbSynRotBinDec[i][ch] ), CLDFB_SYNTHESIS, output_Fs, CLDFB_PROTOTYPE_5_00MS ) ) != IVAS_ERR_OK ) + { + return error; + } + } + } +#endif + + FOR( pos_idx = 0; pos_idx < pMultiBinPoseData->num_poses - 1; pos_idx++ ) + { + FOR( sf_idx = 0; sf_idx < MAX_SPLIT_MD_SUBFRAMES; sf_idx++ ) + { + FOR( bandIdx = 0; bandIdx < MAX_SPLIT_REND_MD_BANDS; bandIdx++ ) + { + hBinRend->rot_md[pos_idx][sf_idx][bandIdx].gd_fx = 0; + } + } + } + set_fix_rotation_mat_fx( hBinRend->fix_pos_rot_mat_fx, pMultiBinPoseData ); + set_pose_types_fx( hBinRend->pose_type, pMultiBinPoseData ); + + isar_split_rend_init_huff_cfg( &hBinRend->huff_cfg ); + +#ifdef SPLIT_POSE_CORRECTION_DEBUG + ivas_error error; + if ( ( error = isar_splitBinPostRendOpen( &hBinRend->hBinHrSplitPostRend, pMultiBinPoseData, 48000 ) ) != IVAS_ERR_OK ) + { + return error; + } +#endif + + *hBinHrSplitPreRend = hBinRend; + + return IVAS_ERR_OK; +} + +/*------------------------------------------------------------------------- + * Function isar_splitBinPreRendClose() + * + * + *------------------------------------------------------------------------*/ + +void isar_splitBinPreRendClose( + ISAR_BIN_HR_SPLIT_PRE_REND_HANDLE *hBinHrSplitPreRend ) +{ + IF( ( *hBinHrSplitPreRend ) != NULL ) + { +#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG + { + Word16 i, n; + FOR( i = 0; i < MAX_HEAD_ROT_POSES + 1; i++ ) + { + FOR( n = 0; n < BINAURAL_CHANNELS; n++ ) + { + IF( ( *hBinHrSplitPreRend )->cldfbSynRotBinDec[i][n] != NULL ) + { + deleteCldfb( &( ( *hBinHrSplitPreRend )->cldfbSynRotBinDec[i][n] ) ); + ( *hBinHrSplitPreRend )->cldfbSynRotBinDec[i][n] = NULL; + } + } + } + } +#endif +#ifdef SPLIT_POSE_CORRECTION_DEBUG + isar_splitBinPostRendClose( &( *hBinHrSplitPreRend )->hBinHrSplitPostRend ); +#endif + + free( ( *hBinHrSplitPreRend ) ); + ( *hBinHrSplitPreRend ) = NULL; + } + + return; +} + + +/*-------------------------------------------------------------------------* + * isar_set_split_rend_ht_setup() + * + * + *-------------------------------------------------------------------------*/ +void isar_set_split_rend_ht_setup_fx( + SPLIT_REND_WRAPPER *hSplitrend, + IVAS_QUATERNION Quaternions[MAX_PARAM_SPATIAL_SUBFRAMES], + Word32 Rmat_fx[MAX_PARAM_SPATIAL_SUBFRAMES][3][3] ) +{ + Word16 sf, i, j; + IF( hSplitrend->multiBinPoseData.poseCorrectionMode == ISAR_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB ) + { + FOR( sf = 1; sf < MAX_PARAM_SPATIAL_SUBFRAMES; sf++ ) + { + Quaternions[sf] = Quaternions[0]; + + FOR( i = 0; i < 3; i++ ) + { + FOR( j = 0; j < 3; j++ ) + { + Rmat_fx[sf][i][j] = Rmat_fx[0][i][j]; + move32(); + } + } + } + } + + return; +} + +/*------------------------------------------------------------------------- + * Function isar_init_split_rend_handles() + * + * + *------------------------------------------------------------------------*/ + +void isar_init_split_rend_handles( + SPLIT_REND_WRAPPER *hSplitRendWrapper ) +{ + Word16 i; + + hSplitRendWrapper->hBinHrSplitPreRend = NULL; + hSplitRendWrapper->hCldfbHandles = NULL; + hSplitRendWrapper->hSplitBinLCLDEnc = NULL; + hSplitRendWrapper->hLc3plusEnc = NULL; + + FOR( i = 0; i < MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS; ++i ) + { + hSplitRendWrapper->lc3plusDelayBuffers_fx[i] = NULL; + } + hSplitRendWrapper->lc3plusDelaySamples = 0; + move32(); + + isar_init_multi_bin_pose_data_fx_enc( &hSplitRendWrapper->multiBinPoseData ); + + return; +} + + +/*------------------------------------------------------------------------- + * Function split_renderer_open_lc3plus() + * + * + *------------------------------------------------------------------------*/ + +ivas_error split_renderer_open_lc3plus( + SPLIT_REND_WRAPPER *hSplitRendWrapper, + const ISAR_SPLIT_REND_CONFIG_DATA *pSplitRendConfig, + const Word32 OutSampleRate, +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + const IVAS_RENDER_FRAMESIZE isar_frame_size +#else + const int16_t num_subframes +#endif +) +{ + ivas_error error; + Word16 i, delayBufferLength; + LC3PLUS_CONFIG config; +#if defined ISAR_BITSTREAM_UPDATE_LC3PLUS + int16_t isar_frame_size_ms; + + if ( ( error = isar_framesize_to_ms( isar_frame_size, &isar_frame_size_ms ) ) != IVAS_ERR_OK ) + { + return error; + } +#endif +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + /* Check configuration validity */ + if ( isar_frame_size_ms < pSplitRendConfig->codec_frame_size_ms ) + { + return IVAS_ERROR( IVAS_ERR_INVALID_SPLIT_REND_CONFIG, "SR codec frame doesn't fit in one output frame" ); + } +#endif + + config.lc3plus_frame_duration_us = pSplitRendConfig->codec_frame_size_ms * 1000; +#ifndef ISAR_BITSTREAM_UPDATE_LC3PLUS + config.ivas_frame_duration_us = ( pSplitRendConfig->dof == 0 ) ? config.lc3plus_frame_duration_us * num_subframes : 20000; +#endif + config.samplerate = OutSampleRate; +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + config.isar_frame_duration_us = isar_frame_size_ms * 1000; +#endif +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + config.high_res_mode_enabled = ( pSplitRendConfig->lc3plus_highres != 0 ); +#endif + config.channels = BINAURAL_CHANNELS; + + if ( ( error = ISAR_LC3PLUS_ENC_Open( config, +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + isar_get_lcld_bitrate( pSplitRendConfig->splitRendBitRate, pSplitRendConfig->poseCorrectionMode ), +#else + isar_get_lc3plus_bitrate( pSplitRendConfig->splitRendBitRate, pSplitRendConfig->poseCorrectionMode, (int16_t) ( config.isar_frame_duration_us / 1000 ) ), +#endif + &hSplitRendWrapper->hLc3plusEnc ) ) != IVAS_ERR_OK ) + { + return error; + } + + /* This returns delay of entire LC3plus chain (enc + dec) */ + IF( ( error = ISAR_LC3PLUS_ENC_GetDelay( hSplitRendWrapper->hLc3plusEnc, &hSplitRendWrapper->lc3plusDelaySamples ) ) != IVAS_ERR_OK ) + { + return error; + } + + /* Alocate buffers for delay compensation */ + IF( pSplitRendConfig->codec == ISAR_SPLIT_REND_CODEC_LC3PLUS ) + { + delayBufferLength = (Word16) ( OutSampleRate / (int32_t) FRAMES_PER_SEC + hSplitRendWrapper->lc3plusDelaySamples ); + FOR( i = 0; i < hSplitRendWrapper->multiBinPoseData.num_poses * BINAURAL_CHANNELS; ++i ) + { + IF( ( hSplitRendWrapper->lc3plusDelayBuffers_fx[i] = malloc( delayBufferLength * sizeof( Word32 ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for multiBinPoseData handle\n" ) ); + } + + set32_fx( hSplitRendWrapper->lc3plusDelayBuffers_fx[i], 0, delayBufferLength ); + } + hSplitRendWrapper->lc3plusDelayBuffers_q = 31; + } + ELSE + { + /* Delay is always expected to be exactly 2 CLDFB columns */ + assert( hSplitRendWrapper->lc3plusDelaySamples % ( OutSampleRate / FRAMES_PER_SEC / CLDFB_NO_COL_MAX ) == 0 ); + assert( hSplitRendWrapper->lc3plusDelaySamples / ( OutSampleRate / FRAMES_PER_SEC / CLDFB_NO_COL_MAX ) == 2 ); + + delayBufferLength = 2 /* Columns */ * 2 /* real and imag */ * CLDFB_NO_CHANNELS_MAX; + FOR( i = 0; i < hSplitRendWrapper->multiBinPoseData.num_poses * BINAURAL_CHANNELS; ++i ) + { + IF( ( hSplitRendWrapper->lc3plusDelayBuffers_fx[i] = malloc( delayBufferLength * sizeof( Word32 ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for multiBinPoseData handle\n" ) ); + } + + set32_fx( hSplitRendWrapper->lc3plusDelayBuffers_fx[i], 0, delayBufferLength ); + } + hSplitRendWrapper->lc3plusDelayBuffers_q = 31; + } + + return IVAS_ERR_OK; +} + + +/*------------------------------------------------------------------------- + * Function splitRendLc3plusEncodeAndWrite() + * + * + *------------------------------------------------------------------------*/ +ivas_error splitRendLc3plusEncodeAndWrite( + SPLIT_REND_WRAPPER *hSplitBin, + ISAR_SPLIT_REND_BITS_HANDLE pBits, +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + const int32_t available_bits, +#endif +#else + const int32_t SplitRendBitRate, +#endif + Word32 *in[], + Word16 Q_sig ) +{ + ivas_error error; + int16_t i; + int32_t lc3plusBitstreamSize; + Word32 *channel_ptrs[MAX_HEAD_ROT_POSES * 2]; + Word16 Q_in[16]; + assert( hSplitBin->hLc3plusEnc != NULL ); + + /* Find next byte boundary and zero-pad to it */ + while ( pBits->bits_written % 8 != 0 ) + { + ISAR_SPLIT_REND_BITStream_write_int32( pBits, 0L, 1 ); + } + + for ( i = 0; i < BINAURAL_CHANNELS * hSplitBin->multiBinPoseData.num_poses; ++i ) + { + channel_ptrs[i] = in[i]; + } + +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + if ( ( error = IVAS_LC3PLUS_ENC_SetBitrate( hSplitBin->hLc3plusEnc, available_bits * FRAMES_PER_SEC ) ) != IVAS_ERR_OK ) + { + return error; + } +#endif + + if ( ( error = ISAR_LC3PLUS_ENC_GetOutputBitstreamSize( hSplitBin->hLc3plusEnc, &lc3plusBitstreamSize ) ) != IVAS_ERR_OK ) + { + return error; + } + +#ifndef ISAR_BITSTREAM_UPDATE_LC3PLUS + ISAR_SPLIT_REND_BITStream_write_int32( pBits, isar_get_lc3plus_bitrate_id( SplitRendBitRate ), 8 ); +#endif + /* Write bitstream */ +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + set16_fx( Q_in, Q_sig, 16 ); + move16(); + if ( ( error = ISAR_LC3PLUS_ENC_Encode( hSplitBin->hLc3plusEnc, channel_ptrs, &pBits->bits_buf[pBits->bits_written / 8], lc3plusBitstreamSize, Q_in ) ) != IVAS_ERR_OK ) +#else + if ( ( error = ISAR_LC3PLUS_ENC_Encode( hSplitBin->hLc3plusEnc, channel_ptrs, &pBits->bits_buf[pBits->bits_written / 8] ) ) != IVAS_ERR_OK ) +#endif + { + return error; + } + + pBits->bits_written += 8 * lc3plusBitstreamSize; + pBits->codec = ISAR_SPLIT_REND_CODEC_LC3PLUS; + pBits->pose_correction = hSplitBin->multiBinPoseData.poseCorrectionMode; + pBits->codec_frame_size_ms = (int16_t) ( hSplitBin->hLc3plusEnc->config.lc3plus_frame_duration_us / 1000 ); +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + pBits->isar_frame_size_ms = (int16_t) ( hSplitBin->hLc3plusEnc->config.isar_frame_duration_us / 1000 ); +#endif + return IVAS_ERR_OK; +} + + +/*------------------------------------------------------------------------- + * Function isar_renderMultiTDBinToSplitBinaural() + * + * + *------------------------------------------------------------------------*/ +ivas_error isar_renderMultiTDBinToSplitBinaural( + SPLIT_REND_WRAPPER *hSplitBin, + const IVAS_QUATERNION headPosition, + const Word32 SplitRendBitRate, +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + const int16_t isar_frame_size_ms, +#endif + const Word16 codec_frame_size_ms, + ISAR_SPLIT_REND_BITS_HANDLE pBits, + const Word16 max_bands, + // float *in[], + Word32 *in_fx[], // Q11 + Word16 Q_sig, + const Word16 low_res_pre_rend_rot, + const Word16 pcm_out_flag, + const Word16 ro_md_flag ) +{ + ivas_error error; +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + int32_t bit_len, available_bits, target_md_bits, tmp_32; +#else + Word32 bit_len, available_bits, target_md_bits, actual_md_bits, tmp_32; +#endif + Word16 num_cldfb_bands, ch, slot_idx, pos_idx, num_poses; + Word16 tmp, tmp_e; + Word32 Cldfb_In_BinReal_fx[MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX] = { 0 }; + Word32 Cldfb_In_BinImag_fx[MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX] = { 0 }; + Word16 Q_in = Q_sig, q_final = 0; + move16(); + move16(); + UWord8 useLc3plus; + Word32 *in_delayed_fx[MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS]; + Word16 i; + Word32 num_slots; + + push_wmops( "isar_renderMultiTDBinToSplitBinaural" ); + + error = IVAS_ERR_OK; + num_poses = hSplitBin->multiBinPoseData.num_poses; + + useLc3plus = hSplitBin->hLc3plusEnc != NULL; + + IF( useLc3plus ) + { + /*this should always have the time resolution of pose correction MD. Note that this does not change frame size of LC3plus*/ + // Word16 frame_size = (Word16) ( hSplitBin->hLc3plusEnc->config.samplerate / (Word32) FRAMES_PER_SECOND ); + tmp_e = 0; + tmp = BASOP_Util_Divide3232_Scale( hSplitBin->hLc3plusEnc->config.samplerate, FRAMES_PER_SEC, &tmp_e ); + Word16 frame_size = shr( tmp, sub( 15, tmp_e ) ); // Q0 + FOR( i = 0; i < num_poses * BINAURAL_CHANNELS; ++i ) + { + /* Artificially delay input to head pose correction analysis by LC3plus coding delay, so that audio and metadata are in sync after decoding */ + mvl2l( hSplitBin->lc3plusDelayBuffers_fx[i] + frame_size, hSplitBin->lc3plusDelayBuffers_fx[i], (Word16) hSplitBin->lc3plusDelaySamples ); + in_delayed_fx[i] = hSplitBin->lc3plusDelayBuffers_fx[i]; + Scale_sig32( hSplitBin->lc3plusDelayBuffers_fx[i], (Word16) hSplitBin->lc3plusDelaySamples, sub( Q_in, hSplitBin->lc3plusDelayBuffers_q ) ); + mvl2l( in_fx[i], hSplitBin->lc3plusDelayBuffers_fx[i] + hSplitBin->lc3plusDelaySamples, frame_size ); + } + hSplitBin->lc3plusDelayBuffers_q = Q_in; + } + ELSE + { + FOR( i = 0; i < num_poses * BINAURAL_CHANNELS; ++i ) + { + in_delayed_fx[i] = in_fx[i]; + move32(); + } + } + +#ifndef ISAR_BITSTREAM_UPDATE_LC3PLUS + actual_md_bits = pBits->bits_written; + move32(); +#endif + + test(); + test(); + IF( ( hSplitBin->multiBinPoseData.poseCorrectionMode == ISAR_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB ) || ( !useLc3plus && !pcm_out_flag ) ) + { + Word32 in_delayed_cldfb[MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS][L_FRAME48k] = { 0 }; + Word16 gd_bits = sub( Q_sig, Q11 ); + FOR( i = 0; i < num_poses * BINAURAL_CHANNELS; i++ ) + { + Copy32( in_delayed_fx[i], in_delayed_cldfb[i], L_FRAME48k ); + Scale_sig32( in_delayed_cldfb[i], L_FRAME48k, -gd_bits ); + } + Q_sig = sub( Q_sig, gd_bits ); + num_slots = ( hSplitBin->multiBinPoseData.poseCorrectionMode == ISAR_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB ) ? CLDFB_NO_COL_MAX : ( hSplitBin->hSplitBinLCLDEnc->iNumBlocks * hSplitBin->hSplitBinLCLDEnc->iNumIterations ); + move32(); + num_cldfb_bands = hSplitBin->hCldfbHandles->cldfbAna[0]->no_channels; + move16(); + /* CLDFB Analysis*/ + FOR( pos_idx = 0; pos_idx < num_poses; pos_idx++ ) + { +#ifdef SPLIT_POSE_CORRECTION_DEBUG + { + float *pOut[2]; + char fname[200] = "ref_out_pos"; + char tag[2]; + tag[0] = (char) ( '0' + pos_idx ); + tag[1] = '\0'; + strcat( fname, tag ); + strcat( fname, ".wav" ); + + pOut[0] = in_delayed[2 * pos_idx]; + pOut[1] = in_delayed[2 * pos_idx + 1]; + dbgwrite_wav( pOut, CLDFB_NO_COL_MAX * max_bands, fname, 48000, 2 ); + } + +#endif + FOR( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) + { + HANDLE_CLDFB_FILTER_BANK temp_cldfbAna = hSplitBin->hCldfbHandles->cldfbAna[pos_idx * BINAURAL_CHANNELS + ch]; + Scale_sig32( temp_cldfbAna->cldfb_state_fx, + sub( temp_cldfbAna->p_filter_length, temp_cldfbAna->no_channels ), sub( Q_sig, temp_cldfbAna->Q_cldfb_state ) ); + temp_cldfbAna->Q_cldfb_state = Q_sig; + move16(); + FOR( slot_idx = 0; slot_idx < num_slots; slot_idx++ ) + { + Word16 Q_cldfb = Q_sig; + // floatToFixed_arrL(hSplitBin->hCldfbHandles->cldfbAna[pos_idx * BINAURAL_CHANNELS + ch]->cldfb_state, hSplitBin->hCldfbHandles->cldfbAna[pos_idx * BINAURAL_CHANNELS + ch]->cldfb_state_fx, Q_output, hSplitBin->hCldfbHandles->cldfbAna[pos_idx * BINAURAL_CHANNELS + ch]->p_filter_length - hSplitBin->hCldfbHandles->cldfbAna[pos_idx * BINAURAL_CHANNELS + ch]->no_channels); + cldfbAnalysis_ts_fx_fixed_q( &( in_delayed_cldfb[pos_idx * BINAURAL_CHANNELS + ch][num_cldfb_bands * slot_idx] ), + Cldfb_In_BinReal_fx[pos_idx * BINAURAL_CHANNELS + ch][slot_idx], + Cldfb_In_BinImag_fx[pos_idx * BINAURAL_CHANNELS + ch][slot_idx], + max_bands, + temp_cldfbAna, + &Q_cldfb ); + /*fixedToFloat_arrL(hSplitBin->hCldfbHandles->cldfbAna[pos_idx * BINAURAL_CHANNELS + ch]->cldfb_state_fx, hSplitBin->hCldfbHandles->cldfbAna[pos_idx * BINAURAL_CHANNELS + ch]->cldfb_state, Q_output, hSplitBin->hCldfbHandles->cldfbAna[pos_idx * BINAURAL_CHANNELS + ch]->p_filter_length - hSplitBin->hCldfbHandles->cldfbAna[pos_idx * BINAURAL_CHANNELS + ch]->no_channels); + fixedToFloat_arrL(Cldfb_In_BinReal_fx[pos_idx * BINAURAL_CHANNELS + ch][slot_idx], Cldfb_In_BinReal[pos_idx * BINAURAL_CHANNELS + ch][slot_idx], Q_cldfb, max_bands); + fixedToFloat_arrL(Cldfb_In_BinImag_fx[pos_idx * BINAURAL_CHANNELS + ch][slot_idx], Cldfb_In_BinImag[pos_idx * BINAURAL_CHANNELS + ch][slot_idx], Q_cldfb, max_bands);*/ + /*for (int k = 0; k < max_bands; k++) { + printf("\n%f %f ", Cldfb_In_BinReal[pos_idx * BINAURAL_CHANNELS + ch][slot_idx][k], Cldfb_In_BinImag[pos_idx * BINAURAL_CHANNELS + ch][slot_idx][k]); + }*/ + } + } + } + q_final = sub( Q_sig, 5 ); + } + + IF( hSplitBin->multiBinPoseData.poseCorrectionMode == ISAR_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB ) + { + // target_md_bits = isar_get_split_rend_md_target_brate( SplitRendBitRate, pcm_out_flag ) * L_FRAME48k / 48000; + target_md_bits = W_extract_l( W_mult0_32_32( isar_get_split_rend_md_target_brate( SplitRendBitRate, pcm_out_flag ), L_FRAME48k ) ); + tmp_e = 0; + tmp_32 = BASOP_Util_Divide3232_Scale_cadence( target_md_bits, 48000, &tmp_e ); + target_md_bits = L_shr( tmp_32, sub( 31, tmp_e ) ); // Q0 + +#ifndef ISAR_BITSTREAM_UPDATE_LC3PLUS + actual_md_bits = pBits->bits_written; +#endif + /*scaling to max Q*/ + Word16 scale_factor = 31; + move32(); + FOR( i = 0; i < num_poses * BINAURAL_CHANNELS; i++ ) + { + FOR( Word16 j = 0; j < CLDFB_NO_COL_MAX; j++ ) + { + scale_factor = s_min( scale_factor, s_min( getScaleFactor32( Cldfb_In_BinReal_fx[i][j], CLDFB_NO_CHANNELS_MAX ), getScaleFactor32( Cldfb_In_BinImag_fx[i][j], CLDFB_NO_CHANNELS_MAX ) ) ); + } + } + scale_factor = sub( scale_factor, 2 ); + FOR( i = 0; i < num_poses * BINAURAL_CHANNELS; i++ ) + { + FOR( Word16 j = 0; j < CLDFB_NO_COL_MAX; j++ ) + { + Scale_sig32( Cldfb_In_BinReal_fx[i][j], CLDFB_NO_CHANNELS_MAX, scale_factor ); + Scale_sig32( Cldfb_In_BinImag_fx[i][j], CLDFB_NO_CHANNELS_MAX, scale_factor ); + } + } + q_final = add( q_final, scale_factor ); + Word16 exp_cldfb_re = sub( 31, q_final ); + Word16 exp_cldfb_im = sub( 31, q_final ); + isar_rend_CldfbSplitPreRendProcess( hSplitBin->hBinHrSplitPreRend, headPosition, &hSplitBin->multiBinPoseData, Cldfb_In_BinReal_fx, exp_cldfb_re, Cldfb_In_BinImag_fx, exp_cldfb_im, pBits, target_md_bits, low_res_pre_rend_rot, ro_md_flag ); + } + + IF( EQ_16( pcm_out_flag, 0 ) ) + { + pBits->pose_correction = hSplitBin->multiBinPoseData.poseCorrectionMode; + pBits->codec = useLc3plus ? ISAR_SPLIT_REND_CODEC_LC3PLUS : ISAR_SPLIT_REND_CODEC_LCLD; + + IF( !useLc3plus ) + { + // available_bits = ( SplitRendBitRate * hSplitBin->hSplitBinLCLDEnc->iNumBlocks * hSplitBin->hSplitBinLCLDEnc->iNumIterations ) / ( 16 * FRAMES_PER_SEC ); + available_bits = W_extract_l( W_mult0_32_32( SplitRendBitRate, L_mult0( hSplitBin->hSplitBinLCLDEnc->iNumBlocks, hSplitBin->hSplitBinLCLDEnc->iNumIterations ) ) ); + tmp_e = 0; + tmp_32 = BASOP_Util_Divide3232_Scale_cadence( available_bits, L_mult0( 16, FRAMES_PER_SEC ), &tmp_e ); + available_bits = L_shr( tmp_32, sub( 31, tmp_e ) ); // Q0 +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + available_bits = L_sub( available_bits, pBits->bits_written ); +#else + actual_md_bits = L_sub( pBits->bits_written, actual_md_bits ); + available_bits = L_sub( available_bits, actual_md_bits ); +#endif + pBits->codec_frame_size_ms = codec_frame_size_ms; + move16(); +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + pBits->isar_frame_size_ms = isar_frame_size_ms; + move16(); +#endif + isar_splitBinLCLDEncProcess( hSplitBin->hSplitBinLCLDEnc, Cldfb_In_BinReal_fx, Cldfb_In_BinImag_fx, available_bits, pBits, &q_final ); + } + ELSE + { +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + available_bits = ( SplitRendBitRate / FRAMES_PER_SEC ) - pBits->bits_written; + IF( ( error = splitRendLc3plusEncodeAndWrite( hSplitBin, pBits, available_bits, in_fx, Q_in ) ) != IVAS_ERR_OK ) + { + return error; + } +#else + IF( ( error = splitRendLc3plusEncodeAndWrite( hSplitBin, pBits, SplitRendBitRate, in_flt ) ) != IVAS_ERR_OK ) + { + return error; + } +#endif + } + } + ELSE + { + pBits->pose_correction = hSplitBin->multiBinPoseData.poseCorrectionMode; + pBits->codec = ISAR_SPLIT_REND_CODEC_NONE; + } + + /*zero pad*/ + IF( pcm_out_flag ) + { + tmp_e = 0; + tmp = BASOP_Util_Divide3232_Scale( SplitRendBitRate, FRAMES_PER_SEC, &tmp_e ); + bit_len = L_deposit_l( shr( tmp, sub( 15, tmp_e ) ) ); // Q0 + // bit_len = SplitRendBitRate / FRAMES_PER_SEC; + } + ELSE + { + IF( !useLc3plus ) + { + // bit_len = ( SplitRendBitRate * hSplitBin->hSplitBinLCLDEnc->iNumBlocks * hSplitBin->hSplitBinLCLDEnc->iNumIterations ) / ( 16 * FRAMES_PER_SEC ); + + bit_len = W_extract_l( W_mult0_32_32( SplitRendBitRate, L_mult0( hSplitBin->hSplitBinLCLDEnc->iNumBlocks, hSplitBin->hSplitBinLCLDEnc->iNumIterations ) ) ); + tmp_e = 0; + tmp_32 = BASOP_Util_Divide3232_Scale_cadence( bit_len, L_mult0( 16, FRAMES_PER_SEC ), &tmp_e ); + bit_len = L_shr( tmp_32, sub( 31, tmp_e ) ); // Q0 + } + ELSE + { + tmp_e = 0; + tmp = BASOP_Util_Divide3232_Scale( (Word32) hSplitBin->hLc3plusEnc->config.isar_frame_duration_us, 1000, &tmp_e ); + bit_len = L_deposit_l( shr( tmp, sub( 15, tmp_e ) ) ); // Q0 + // bit_len = hSplitBin->hLc3plusEnc->config.ivas_frame_duration_us / 1000; + // bit_len = SplitRendBitRate * bit_len / 1000; + tmp_e = 0; + tmp_32 = BASOP_Util_Divide3232_Scale_cadence( W_extract_l( W_mult0_32_32( SplitRendBitRate, bit_len ) ), 1000, &tmp_e ); + bit_len = L_shr( tmp_32, sub( 31, tmp_e ) ); // Q0 + } + } + + + WHILE( LT_32( pBits->bits_written, bit_len ) ) + { + ISAR_SPLIT_REND_BITStream_write_int32( pBits, 0L, 1 ); + } + + pop_wmops(); + + return error; +} + +/*------------------------------------------------------------------------- + * Function lc3plusTimeAlignCldfbPoseCorr() + * + * + *------------------------------------------------------------------------*/ +void lc3plusTimeAlignCldfbPoseCorr( + SPLIT_REND_WRAPPER *hSplitBin, + Word32 Cldfb_In_BinReal_fx[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + Word32 Cldfb_In_BinImag_fx[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + Word16 *Q_in ) +{ + Word32 Cldfb_In_BinReal_tmp_fx[MAX_HEAD_ROT_POSES][BINAURAL_CHANNELS][2][CLDFB_NO_CHANNELS_MAX]; + Word32 Cldfb_In_BinImag_tmp_fx[MAX_HEAD_ROT_POSES][BINAURAL_CHANNELS][2][CLDFB_NO_CHANNELS_MAX]; + Word16 pose, ch, slot_idx; + Word32 *bufRead_fx, *bufWrite_fx; + + IF( GT_16( hSplitBin->lc3plusDelayBuffers_q, *Q_in ) ) + { + // hSplitBin->lc3plusDelayBuffers_q[0] = *Q_in; + FOR( Word16 i = 0; i < hSplitBin->multiBinPoseData.num_poses * BINAURAL_CHANNELS; i++ ) + { + + Scale_sig32( hSplitBin->lc3plusDelayBuffers_fx[i], 4 * CLDFB_NO_CHANNELS_MAX, sub( *Q_in, hSplitBin->lc3plusDelayBuffers_q ) ); + } + hSplitBin->lc3plusDelayBuffers_q = *Q_in; + } + ELSE + { + FOR( Word16 i = 0; i < CLDFB_NO_COL_MAX; i++ ) + { + for ( Word16 j = 0; j < CLDFB_NO_COL_MAX; j++ ) + { + Scale_sig32( Cldfb_In_BinReal_fx[i][j], CLDFB_NO_CHANNELS_MAX, sub( hSplitBin->lc3plusDelayBuffers_q, *Q_in ) ); + Scale_sig32( Cldfb_In_BinImag_fx[i][j], CLDFB_NO_CHANNELS_MAX, sub( hSplitBin->lc3plusDelayBuffers_q, *Q_in ) ); + } + } + *Q_in = hSplitBin->lc3plusDelayBuffers_q; + } + + FOR( pose = 0; pose < hSplitBin->multiBinPoseData.num_poses; ++pose ) + { + FOR( ch = 0; ch < BINAURAL_CHANNELS; ++ch ) + { + bufRead_fx = hSplitBin->lc3plusDelayBuffers_fx[pose * BINAURAL_CHANNELS + ch]; + bufWrite_fx = bufRead_fx; + + /* Save last 2 columns for next frame */ + FOR( slot_idx = 0; slot_idx < 2; ++slot_idx ) + { + Copy32( Cldfb_In_BinReal_fx[pose * BINAURAL_CHANNELS + ch][CLDFB_NO_COL_MAX - 2 + slot_idx], Cldfb_In_BinReal_tmp_fx[pose][ch][slot_idx], CLDFB_NO_CHANNELS_MAX ); + Copy32( Cldfb_In_BinImag_fx[pose * BINAURAL_CHANNELS + ch][CLDFB_NO_COL_MAX - 2 + slot_idx], Cldfb_In_BinImag_tmp_fx[pose][ch][slot_idx], CLDFB_NO_CHANNELS_MAX ); + } + + /* Delay existing columns by 2 slots */ + /*TODO : shouldnt the delay be 7.5 ms ? 5ms + LC3plus delay */ + FOR( slot_idx = CLDFB_NO_COL_MAX - 2 - 1; slot_idx >= 0; --slot_idx ) + { + Copy32( Cldfb_In_BinReal_fx[pose * BINAURAL_CHANNELS + ch][slot_idx], Cldfb_In_BinReal_fx[pose * BINAURAL_CHANNELS + ch][slot_idx + 2], CLDFB_NO_CHANNELS_MAX ); + Copy32( Cldfb_In_BinImag_fx[pose * BINAURAL_CHANNELS + ch][slot_idx], Cldfb_In_BinImag_fx[pose * BINAURAL_CHANNELS + ch][slot_idx + 2], CLDFB_NO_CHANNELS_MAX ); + } + + /* Fill 2 first columns from buffer */ + FOR( slot_idx = 0; slot_idx < 2; ++slot_idx ) + { + Copy32( bufRead_fx, Cldfb_In_BinReal_fx[pose * BINAURAL_CHANNELS + ch][slot_idx], CLDFB_NO_CHANNELS_MAX ); + bufRead_fx += CLDFB_NO_CHANNELS_MAX; + Copy32( bufRead_fx, Cldfb_In_BinImag_fx[pose * BINAURAL_CHANNELS + ch][slot_idx], CLDFB_NO_CHANNELS_MAX ); + bufRead_fx += CLDFB_NO_CHANNELS_MAX; + } + + /* Copy last 2 columns to buffer */ + FOR( slot_idx = 0; slot_idx < 2; ++slot_idx ) + { + Copy32( Cldfb_In_BinReal_tmp_fx[pose][ch][slot_idx], bufWrite_fx, CLDFB_NO_CHANNELS_MAX ); + bufWrite_fx += CLDFB_NO_CHANNELS_MAX; + Copy32( Cldfb_In_BinImag_tmp_fx[pose][ch][slot_idx], bufWrite_fx, CLDFB_NO_CHANNELS_MAX ); + bufWrite_fx += CLDFB_NO_CHANNELS_MAX; + } + } + } + + return; +} + +#endif diff --git a/lib_isar/isar_splitRenderer_utils.c b/lib_isar/isar_splitRenderer_utils.c new file mode 100644 index 0000000000000000000000000000000000000000..7f21a40c7cdafc2f51b4c7cf8e7f4d0f1305d57c --- /dev/null +++ b/lib_isar/isar_splitRenderer_utils.c @@ -0,0 +1,1565 @@ +/****************************************************************************************************** + + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository. All Rights Reserved. + + This software is protected by copyright law and by international treaties. + The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository retain full ownership rights in their respective contributions in + the software. This notice grants no license of any kind, including but not limited to patent + license, nor is any license granted by implication, estoppel or otherwise. + + Contributors are required to enter into the IVAS codec Public Collaboration agreement before making + contributions. + + This software is provided "AS IS", without any express or implied warranties. The software is in the + development stage. It is intended exclusively for experts who have experience with such software and + solely for the purpose of inspection. All implied warranties of non-infringement, merchantability + and fitness for a particular purpose are hereby disclaimed and excluded. + + Any dispute, controversy or claim arising under or in relation to providing this software shall be + submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in + accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and + the United Nations Convention on Contracts on the International Sales of Goods. + +*******************************************************************************************************/ + +#include +#include "options.h" +#ifdef SPLIT_REND_WITH_HEAD_ROT +#include +#include "ivas_prot_fx.h" +#include "prot_fx.h" +#include "cnst.h" +#include "isar_cnst.h" +#include "ivas_rom_rend.h" +#include "ivas_rom_com.h" +#include "isar_rom_post_rend.h" +#include "ivas_rom_binauralRenderer.h" +#include "lib_isar_post_rend.h" +#include "isar_prot.h" +#ifdef DEBUGGING +#include "debug.h" +#endif +#include "wmc_auto.h" +#include "basop_settings.h" +#include "prot_fx.h" + +#include "basop_util.h" + + +/*------------------------------------------------------------------------- + * Function ivas_mat_mult_2by2_complex() + * + * + *------------------------------------------------------------------------*/ +void ivas_cmult_fix( Word32 in1_re_fx, Word16 exp_re1, Word32 in1_im_fx, Word16 exp_im1, Word32 in2_re_fx, Word16 exp_re2, Word32 in2_im_fx, Word16 exp_im2, Word32 *out1_re_fx, Word32 *out1_im_fx, Word16 *exp_out1_re, Word16 *exp_out1_im ) +{ + Word16 shift_1 = W_norm( W_mult_32_32( in1_re_fx, in2_re_fx ) ); + Word16 shift_2 = W_norm( W_mult_32_32( in1_im_fx, in2_im_fx ) ); + Word32 tmp1 = W_extract_h( W_shl( W_mult_32_32( in1_re_fx, in2_re_fx ), shift_1 ) ); + Word32 tmp2 = W_extract_h( W_shl( W_mult_32_32( in1_im_fx, in2_im_fx ), shift_2 ) ); + Word16 exp_tmp1 = 0; + move16(); + *out1_re_fx = BASOP_Util_Add_Mant32Exp( tmp1, exp_re1 + exp_re2 - shift_1, L_negate( tmp2 ), exp_im1 + exp_im2 - shift_2, &exp_tmp1 ); + *exp_out1_re = exp_tmp1; + Word16 shift_3 = W_norm( W_mult_32_32( in1_re_fx, in2_im_fx ) ); + Word16 shift_4 = W_norm( W_mult_32_32( in2_re_fx, in1_im_fx ) ); + Word32 tmp3 = W_extract_h( W_shl( W_mult_32_32( in1_re_fx, in2_im_fx ), shift_3 ) ); + Word32 tmp4 = W_extract_h( W_shl( W_mult_32_32( in2_re_fx, in1_im_fx ), shift_4 ) ); + Word16 exp_tmp2 = 0; + move16(); + *out1_im_fx = BASOP_Util_Add_Mant32Exp( tmp3, exp_re1 + exp_im2 - shift_3, tmp4, exp_re2 + exp_im1 - shift_4, &exp_tmp2 ); + *exp_out1_im = exp_tmp2; + move16(); +} + +void ivas_calculate_abs_fx( Word32 re_fx, Word16 exp_re, Word32 im_fx, Word16 exp_im, Word32 *out_fx, Word16 *exp_out ) +{ + Word16 shift_1 = W_norm( W_mult_32_32( re_fx, re_fx ) ); + Word16 shift_2 = W_norm( W_mult_32_32( im_fx, im_fx ) ); + Word32 tmp1 = W_extract_h( W_shl( W_mult_32_32( re_fx, re_fx ), shift_1 ) ); + Word32 tmp2 = W_extract_h( W_shl( W_mult_32_32( im_fx, im_fx ), shift_2 ) ); + Word16 exp_tmp1 = 0; + Word32 tmp3 = BASOP_Util_Add_Mant32Exp( tmp1, exp_re + exp_re - shift_1, tmp2, exp_im + exp_im - shift_2, &exp_tmp1 ); + *out_fx = Sqrt32( tmp3, &exp_tmp1 ); + *exp_out = exp_tmp1; +} + +void ivas_calculate_rabs_fx( Word32 re_fx, Word16 exp_re, Word32 *out_fx, Word16 *exp_out ) +{ + Word16 shift_1 = W_norm( W_mult_32_32( re_fx, re_fx ) ); + Word32 tmp1 = W_extract_h( W_shl( W_mult_32_32( re_fx, re_fx ), shift_1 ) ); + Word16 exp_tmp1 = exp_re + exp_re - shift_1; + Word32 tmp2 = Sqrt32( tmp1, &exp_tmp1 ); + *out_fx = tmp2; + *exp_out = exp_tmp1; +} + +void isar_mat_mult_2by2_complex_fx( + Word32 in_re1_fx[2][2], + Word16 exp_re1, + Word32 in_im1_fx[2][2], + Word16 exp_im1, + Word32 in_re2_fx[2][2], + Word16 exp_re2, + Word32 in_im2_fx[2][2], + Word16 exp_im2, + Word32 out_re2_fx[2][2], + Word16 *final_exp_re_1, + Word32 out_im2_fx[2][2], + Word16 *final_exp_im_1 ) +{ + Word16 i, j; + Word32 tmp_re_fx, tmp_im_fx; + + Word16 exp_tmp1 = 0, exp_tmp2 = 0, exp_tmp3 = 0, exp_tmp4 = 0; + Word16 final_exp_re = 0, final_exp_im = 0; + Word16 BuffExp_re[2][2]; + Word16 BuffExp_im[2][2]; + + FOR( i = 0; i < 2; i++ ) + { + FOR( j = 0; j < 2; j++ ) + { + ivas_cmult_fix( in_re1_fx[i][0], exp_re1, in_im1_fx[i][0], exp_im1, in_re2_fx[0][j], exp_re2, in_im2_fx[0][j], exp_im2, &tmp_re_fx, &tmp_im_fx, &exp_tmp1, &exp_tmp2 ); + + out_re2_fx[i][j] = tmp_re_fx; + move32(); + out_im2_fx[i][j] = tmp_im_fx; + move32(); + + ivas_cmult_fix( in_re1_fx[i][1], exp_re1, in_im1_fx[i][1], exp_im1, in_re2_fx[1][j], exp_re2, in_im2_fx[1][j], exp_im2, &tmp_re_fx, &tmp_im_fx, &exp_tmp3, &exp_tmp4 ); + + out_re2_fx[i][j] = BASOP_Util_Add_Mant32Exp( out_re2_fx[i][j], exp_tmp1, tmp_re_fx, exp_tmp3, &final_exp_re ); + move32(); + out_im2_fx[i][j] = BASOP_Util_Add_Mant32Exp( out_im2_fx[i][j], exp_tmp2, tmp_im_fx, exp_tmp4, &final_exp_im ); + move32(); + + BuffExp_re[i][j] = final_exp_re; + move16(); + BuffExp_im[i][j] = final_exp_im; + move16(); + } + } + + Word16 max_exp_re = 0; + Word16 max_exp_im = 0; + move16(); + move16(); + FOR( i = 0; i < 2; i++ ) + { + FOR( j = 0; j < 2; j++ ) + { + max_exp_re = s_max( max_exp_re, BuffExp_re[i][j] ); + max_exp_im = s_max( max_exp_im, BuffExp_im[i][j] ); + } + } + + FOR( i = 0; i < 2; i++ ) + { + FOR( j = 0; j < 2; j++ ) + { + out_re2_fx[i][j] = L_shr( out_re2_fx[i][j], max_exp_re - BuffExp_re[i][j] ); + move32(); + out_im2_fx[i][j] = L_shr( out_im2_fx[i][j], max_exp_im - BuffExp_im[i][j] ); + move32(); + } + } + *final_exp_re_1 = max_exp_re; + move16(); + *final_exp_im_1 = max_exp_im; + move16(); + + return; +} + +void ivas_mat_mult_2by2_complex( + float in_re1[2][2], + float in_im1[2][2], + float in_re2[2][2], + float in_im2[2][2], + float out_re2[2][2], + float out_im2[2][2] ) +{ + int16_t i, j; + float tmp_re, tmp_im; + + for ( i = 0; i < 2; i++ ) + { + for ( j = 0; j < 2; j++ ) + { + IVAS_CMULT_FLOAT( in_re1[i][0], in_im1[i][0], in_re2[0][j], in_im2[0][j], tmp_re, tmp_im ); + out_re2[i][j] = tmp_re; + out_im2[i][j] = tmp_im; + + IVAS_CMULT_FLOAT( in_re1[i][1], in_im1[i][1], in_re2[1][j], in_im2[1][j], tmp_re, tmp_im ); + out_re2[i][j] += tmp_re; + out_im2[i][j] += tmp_im; + } + } + + return; +} + + +/*------------------------------------------------------------------------- + * Function ISAR_SPLIT_REND_BITStream_init() + * + * + *------------------------------------------------------------------------*/ + +void ISAR_SPLIT_REND_BITStream_init( + ISAR_SPLIT_REND_BITS_HANDLE pBits, + const Word32 buf_len_bytes, + UWord8 *pbuf ) +{ + pBits->bits_buf = pbuf; + pBits->buf_len = buf_len_bytes; + move32(); + pBits->bits_read = 0; + move32(); + pBits->bits_written = 0; + move32(); + + return; +} + + +/*------------------------------------------------------------------------- + * Function isar_split_rend_huffman_dec_init_min_max_len() + * + * + *------------------------------------------------------------------------*/ + +void isar_split_rend_huffman_dec_init_min_max_len( + isar_split_rend_huffman_cfg_t *p_huff_cfg ) +{ + Word16 i, code_len; + const Word32 *codebook; + + codebook = p_huff_cfg->codebook; + + p_huff_cfg->min_len = p_huff_cfg->sym_len; + move16(); + p_huff_cfg->max_len = 0; + move16(); + + FOR( i = 0; i < p_huff_cfg->sym_len; i++ ) + { + code_len = extract_l( codebook[1] ); + IF( GT_16( p_huff_cfg->min_len, code_len ) ) + { + p_huff_cfg->min_len = code_len; + move16(); + } + IF( LT_16( p_huff_cfg->max_len, code_len ) ) + { + p_huff_cfg->max_len = code_len; + move16(); + } + codebook = codebook + 3; + } + + return; +} + + +/*------------------------------------------------------------------------- + * Function is_idx_present() + * + * + *------------------------------------------------------------------------*/ + +static Word16 is_idx_present( + Word16 *idx_list, + const Word16 idx, + const Word16 len ) +{ + Word16 i; + + FOR( i = 0; i < len; i++ ) + { + IF( EQ_16( idx_list[i], idx ) ) + { + return 1; + } + } + + return 0; +} + + +/*------------------------------------------------------------------------- + * Function ivas_split_huff_get_idx_trav_list() + * + * + *------------------------------------------------------------------------*/ + +static void ivas_split_huff_get_idx_trav_list( + Word16 *idx_list, + isar_split_rend_huffman_cfg_t *p_huff_cfg ) +{ + Word16 i, j, min_idx; + Word32 min_bits; + const Word32 *codebook; + + FOR( i = 0; i < p_huff_cfg->sym_len; i++ ) + { + idx_list[i] = -1; + move16(); + } + + FOR( i = 0; i < p_huff_cfg->sym_len; i++ ) + { + codebook = p_huff_cfg->codebook; + min_bits = p_huff_cfg->max_len; + move16(); + min_idx = -1; + move16(); + FOR( j = 0; j < p_huff_cfg->sym_len; j++ ) + { + test(); + IF( GE_32( min_bits, codebook[1] ) && EQ_16( is_idx_present( idx_list, j, i + 1 ), 0 ) ) + { + min_bits = codebook[1]; + move16(); + min_idx = j; + move16(); + } + codebook += 3; + } + idx_list[i] = min_idx; + move16(); + } + + return; +} + + +/*------------------------------------------------------------------------- + * Function isar_split_rend_init_huff_cfg() + * + * + *------------------------------------------------------------------------*/ + +void isar_split_rend_init_huff_cfg( + ISAR_BIN_HR_SPLIT_REND_HUFF_HANDLE pHuff_cfg ) +{ + pHuff_cfg->pred[0].codebook = &ivas_split_rend_huff_pred31_consts[0][0]; + pHuff_cfg->pred[0].sym_len = ISAR_SPLIT_REND_PRED_31QUANT_PNTS; + move16(); + isar_split_rend_huffman_dec_init_min_max_len( &pHuff_cfg->pred[0] ); + ivas_split_huff_get_idx_trav_list( pHuff_cfg->pred_idx_trav[0], &pHuff_cfg->pred[0] ); + pHuff_cfg->pred_base2_code_len[0] = ISAR_SPLIT_REND_PRED_31QUANT_PNTS_LOG2_CEIL; + move16(); + + pHuff_cfg->pred[1].codebook = &ivas_split_rend_huff_pred63_consts[0][0]; + pHuff_cfg->pred[1].sym_len = ISAR_SPLIT_REND_PRED_63QUANT_PNTS; + move16(); + isar_split_rend_huffman_dec_init_min_max_len( &pHuff_cfg->pred[1] ); + ivas_split_huff_get_idx_trav_list( pHuff_cfg->pred_idx_trav[1], &pHuff_cfg->pred[1] ); + pHuff_cfg->pred_base2_code_len[1] = ISAR_SPLIT_REND_PRED_63QUANT_PNTS_LOG2_CEIL; + move16(); + + + pHuff_cfg->pred_roll.codebook = &ivas_split_rend_huff_roll_pred_consts[0][0]; + pHuff_cfg->pred_roll.sym_len = ISAR_SPLIT_REND_ROLL_PRED_QUANT_PNTS; + move16(); + isar_split_rend_huffman_dec_init_min_max_len( &pHuff_cfg->pred_roll ); + ivas_split_huff_get_idx_trav_list( pHuff_cfg->pred_roll_idx_trav, &pHuff_cfg->pred_roll ); + pHuff_cfg->pred_roll_base2_code_len = ISAR_SPLIT_REND_ROLL_PRED_QUANT_PNTS_LOG2_CEIL; + move16(); + + pHuff_cfg->gd.codebook = &ivas_split_rend_huff_d_consts[0][0]; + pHuff_cfg->gd.sym_len = ISAR_SPLIT_REND_D_QUANT_PNTS; + move16(); + isar_split_rend_huffman_dec_init_min_max_len( &pHuff_cfg->gd ); + ivas_split_huff_get_idx_trav_list( pHuff_cfg->gd_idx_trav, &pHuff_cfg->gd ); + pHuff_cfg->gd_base2_code_len = ISAR_SPLIT_REND_D_QUANT_PNTS_LOG2_CEIL; + move16(); + + pHuff_cfg->p_gd.codebook = &ivas_split_rend_huff_p_d_consts[0][0]; + pHuff_cfg->p_gd.sym_len = ISAR_SPLIT_REND_D_QUANT_PNTS; + move16(); + isar_split_rend_huffman_dec_init_min_max_len( &pHuff_cfg->p_gd ); + ivas_split_huff_get_idx_trav_list( pHuff_cfg->p_gd_idx_trav, &pHuff_cfg->p_gd ); + pHuff_cfg->p_gd_base2_code_len = ISAR_SPLIT_REND_D_QUANT_PNTS_LOG2_CEIL; + move16(); + + pHuff_cfg->p_gd_diff.codebook = &ivas_split_rend_huff_p_d_diff_consts[0][0]; + pHuff_cfg->p_gd_diff.sym_len = ISAR_SPLIT_REND_D_QUANT_PNTS; + move16(); + isar_split_rend_huffman_dec_init_min_max_len( &pHuff_cfg->p_gd_diff ); + ivas_split_huff_get_idx_trav_list( pHuff_cfg->p_gd_diff_idx_trav, &pHuff_cfg->p_gd_diff ); + pHuff_cfg->p_gd_diff_base2_code_len = ISAR_SPLIT_REND_D_QUANT_PNTS_LOG2_CEIL; + move16(); + + return; +} + + +/*------------------------------------------------------------------------- + * Function set_fix_rotation_mat() + * + * + *------------------------------------------------------------------------*/ + +void set_fix_rotation_mat_fx( + Word32 fix_pos_rot_mat[][BINAURAL_CHANNELS][BINAURAL_CHANNELS], + MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData ) +{ + Word32 cos_yaw, sin_yaw; + Word16 pos_idx; + Word16 ind = 0; + + // pMultiBinPoseData->relative_head_poses can take only take -30, -22.5, -15, 0, 15, 22.5 and 30 degrees. + // cos(180 - theta) = cos(theta). + // Need only 4 values in LUT + + FOR( pos_idx = 0; pos_idx < sub( pMultiBinPoseData->num_poses, 1 ); pos_idx++ ) + { + ind = extract_l( L_shr( L_abs( pMultiBinPoseData->relative_head_poses_fx[pos_idx + 1][0] ), Q22 ) ); + + ind = shr( ind, 3 ); /* Values: 0, 1, 2 and 3 */ + cos_yaw = ivas_split_rend_fix_pos_rot_mat_cos_fx[ind]; /* Q31 */ + sin_yaw = 0; + + fix_pos_rot_mat[pos_idx][0][0] = cos_yaw; /* Q31 */ + fix_pos_rot_mat[pos_idx][1][1] = cos_yaw; /* Q31 */ + fix_pos_rot_mat[pos_idx][0][1] = sin_yaw; /* Q31 */ + fix_pos_rot_mat[pos_idx][1][0] = L_negate( sin_yaw ); /* Q31 */ + } + + return; +} + +/*------------------------------------------------------------------------- + * Function set_pose_types() + * + * + *------------------------------------------------------------------------*/ + +void set_pose_types_fx( + ISAR_SPLIT_REND_POSE_TYPE pose_type[MAX_HEAD_ROT_POSES - 1], + MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData ) +{ + Word16 pos_idx; + + FOR( pos_idx = 0; pos_idx < pMultiBinPoseData->num_poses - 1; pos_idx++ ) + { + IF( GT_32( L_abs( pMultiBinPoseData->relative_head_poses_fx[pos_idx + 1][0] ), EPSILON_FX ) ) + { + pose_type[pos_idx] = ANY_YAW; + move32(); + } + ELSE IF( GT_32( L_abs( pMultiBinPoseData->relative_head_poses_fx[pos_idx + 1][2] ), EPSILON_FX ) ) + { + pose_type[pos_idx] = ANY_ROLL; + move32(); + } + ELSE + { + pose_type[pos_idx] = PITCH_ONLY; + move32(); + } + } + + return; +} + + +/*------------------------------------------------------------------------- + * Function wrap_a() + * + * + *------------------------------------------------------------------------*/ + +Word16 wrap_a( + Word16 val, + const Word16 min_val, + const Word16 max_val ) +{ + IF( LT_16( val, min_val ) ) + { + val = add( add( sub( max_val, min_val ), val ), 1 ); + } + + IF( GT_16( val, max_val ) ) + { + val = sub( sub( add( min_val, val ), max_val ), 1 ); + } + + return val; +} + + +/*------------------------------------------------------------------------- + * Function isar_SplitRenderer_getdiagdiff() + * + * + *------------------------------------------------------------------------*/ + +void isar_SplitRenderer_getdiagdiff( + Word16 in_idx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], + Word16 out_idx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], + const Word16 sign, + const Word16 min_val, + const Word16 max_val ) +{ + out_idx[0][0] = in_idx[0][0]; + move16(); + out_idx[0][1] = in_idx[0][1]; + move16(); + // DEPR_i_mult used instead of i_mult becuase it is not available + out_idx[1][1] = add( in_idx[1][1], DEPR_i_mult( sign, out_idx[0][0] ) ); + move16(); + out_idx[1][1] = wrap_a( out_idx[1][1], min_val, max_val ); + move16(); + out_idx[1][0] = add( in_idx[1][0], DEPR_i_mult( sign, out_idx[0][1] ) ); + move16(); + out_idx[1][0] = wrap_a( out_idx[1][0], min_val, max_val ); + move16(); + + return; +} + + +/*------------------------------------------------------------------------- + * Function ISAR_SPLIT_REND_BITStream_read_int32() + * + * + *------------------------------------------------------------------------*/ +Word32 ISAR_SPLIT_REND_BITStream_read_int32( + ISAR_SPLIT_REND_BITS_HANDLE pBits, + const Word32 bits ) +{ + Word32 val, k, bit_val; + +#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG + assert( ( pBits->bits_written - pBits->bits_read ) >= bits ); + assert( bits <= 32 ); +#endif + + /* write bit by bit */ + val = 0; + move32(); + FOR( k = L_sub( bits, 1 ); k >= 0; k-- ) + { + bit_val = NE_32( L_and( pBits->bits_buf[L_shr( pBits->bits_read, 3 )], ( L_shl( 1, (Word16) ( L_and( pBits->bits_read, 7 ) ) ) ) ), 0 ); + val = L_or( val, L_shl( bit_val, (Word16) k ) ); + pBits->bits_read = L_add( pBits->bits_read, 1 ); + } + + return val; +} + + +/*------------------------------------------------------------------------- + * Function ISAR_SPLIT_REND_BITStream_write_int32() + * + * + *------------------------------------------------------------------------*/ + +void ISAR_SPLIT_REND_BITStream_write_int32( + ISAR_SPLIT_REND_BITS_HANDLE pBits, + const Word32 val, + const Word32 bits ) +{ + Word32 mask, k; + +#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG + /*protection check*/ + if ( ( pBits->buf_len << 3 ) < ( pBits->bits_written + bits ) ) + { + assert( 0 ); + } +#endif + + mask = L_shl( 1, extract_l( L_sub( bits, 1 ) ) ); + /* write bit by bit */ + FOR( k = 0; k < bits; k++ ) + { + IF( L_and( val, mask ) ) + { + pBits->bits_buf[L_shr( pBits->bits_written, 3 )] = (UWord8) L_or( pBits->bits_buf[L_shr( pBits->bits_written, 3 )], L_shl( 1, extract_l( L_and( pBits->bits_written, 7 ) ) ) ); + } + ELSE + { + pBits->bits_buf[L_shr( pBits->bits_written, 3 )] = (UWord8) L_and( pBits->bits_buf[L_shr( pBits->bits_written, 3 )], ~L_shl( 1, extract_l( L_and( pBits->bits_written, 7 ) ) ) ); + } + pBits->bits_written++; + mask = L_shr( mask, 1 ); + } + + return; +} + + +#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG +/*------------------------------------------------------------------------- + * ivas_mat_mult_2by2_complex() + * + * + *------------------------------------------------------------------------*/ + +void isar_log_cldfb2wav_data( + float Cldfb_In_Real[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + float Cldfb_In_Imag[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + HANDLE_CLDFB_FILTER_BANK *cldfbSyn, + const int16_t num_chs, + const int16_t num_freq_bands, + const int32_t output_Fs, + const int16_t num_slots, + const int16_t start_slot_idx, + const char *filename ) +{ + float *RealBuffer[CLDFB_NO_COL_MAX]; + float *ImagBuffer[CLDFB_NO_COL_MAX]; + float pcm_out[BINAURAL_CHANNELS][L_FRAME48k]; + float *pPcm[BINAURAL_CHANNELS]; + float Cldfb_local_Real[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX]; + float Cldfb_local_Imag[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX]; + int16_t sf, ch; + + assert( num_chs <= BINAURAL_CHANNELS ); + for ( ch = 0; ch < num_chs; ch++ ) + { + for ( sf = start_slot_idx; sf < start_slot_idx + num_slots; sf++ ) + { + mvr2r( Cldfb_In_Real[ch][sf], Cldfb_local_Real[ch][sf], num_freq_bands ); + mvr2r( Cldfb_In_Imag[ch][sf], Cldfb_local_Imag[ch][sf], num_freq_bands ); + RealBuffer[sf - start_slot_idx] = Cldfb_local_Real[ch][sf]; + ImagBuffer[sf - start_slot_idx] = Cldfb_local_Imag[ch][sf]; + } + cldfbSynthesis( RealBuffer, ImagBuffer, &( pcm_out[ch][0] ), num_freq_bands * num_slots, cldfbSyn[ch] ); + pPcm[ch] = pcm_out[ch]; + } + dbgwrite_wav( pPcm, num_freq_bands * num_slots, filename, output_Fs, num_chs ); + + return; +} +#endif + + +/*------------------------------------------------------------------------- + * Function isar_get_split_rend_md_target_brate() + * + * + *------------------------------------------------------------------------*/ + +Word32 isar_get_split_rend_md_target_brate( + const Word32 SplitRendBitRate, + const Word16 pcm_out_flag ) +{ + Word32 md_bitrate; + + IF( EQ_16( pcm_out_flag, 1 ) ) + { + md_bitrate = SplitRendBitRate; + move32(); + } + ELSE + { + SWITCH( SplitRendBitRate ) + { + case SPLIT_REND_768k: + { + md_bitrate = 256000; + move32(); + BREAK; + } + case SPLIT_REND_512k: + { + md_bitrate = 128000; + move32(); + BREAK; + } + case SPLIT_REND_384k: + { + md_bitrate = 128000; + move32(); + BREAK; + } + default: + { + return -1; + } + } + } + + return md_bitrate; +} + + +/*------------------------------------------------------------------------- + * Function isar_get_lcld_bitrate() + * + * + *------------------------------------------------------------------------*/ + +Word32 isar_get_lcld_bitrate( + const Word32 SplitRendBitRate, + const ISAR_SPLIT_REND_POSE_CORRECTION_MODE poseCorrectionMode ) +{ + IF( EQ_32( poseCorrectionMode, ISAR_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB ) ) + { + SWITCH( SplitRendBitRate ) + { + case SPLIT_REND_768k: + { + return IVAS_512k; + } + case SPLIT_REND_512k: + { + return IVAS_384k; + } + case SPLIT_REND_384k: + { + return IVAS_256k; + } + default: + { + assert( 0 ); + } + } + } + ELSE + { + return SplitRendBitRate; + } + + return -1; +} + +#ifndef ISAR_BITSTREAM_UPDATE_LC3PLUS +/*------------------------------------------------------------------------- + * Function isar_get_lc3plus_bitrate() + * + * + *------------------------------------------------------------------------*/ + +Word32 isar_get_lc3plus_bitrate( + const Word32 SplitRendBitRate, + ISAR_SPLIT_REND_POSE_CORRECTION_MODE poseCorrectionMode, + const Word16 split_prerender_frame_size_ms ) +{ + IF( EQ_32( poseCorrectionMode, ISAR_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB ) ) + { + Word32 inBandMdBps = (Word32) ( 8 * 1000 / split_prerender_frame_size_ms ); + return L_sub( isar_get_lcld_bitrate( SplitRendBitRate, poseCorrectionMode ), inBandMdBps ); + } + + IF( EQ_32( poseCorrectionMode, ISAR_SPLIT_REND_POSE_CORRECTION_MODE_NONE ) ) + { + return SplitRendBitRate; + } + + /* Should not be reached */ + assert( 0 ); + return -1; +} + + +/*------------------------------------------------------------------------- + * Function isar_get_lc3plus_bitrate_id() + * + * + *------------------------------------------------------------------------*/ + +Word8 isar_get_lc3plus_bitrate_id( + const Word32 SplitRendBitRate ) +{ + SWITCH( SplitRendBitRate ) + { + case SPLIT_REND_768k: + { + return 4; + } + case SPLIT_REND_512k: + { + return 3; + } + case SPLIT_REND_384k: + { + return 2; + } + case SPLIT_REND_320k: + { + return 1; + } + case SPLIT_REND_256k: + { + return 0; + } + default: + { + BREAK; + } + } + + return -1; +} + + +/*------------------------------------------------------------------------- + * Function ivas_mat_mult_2by2_complex() + * + * + *------------------------------------------------------------------------*/ + +Word32 isar_get_lc3plus_size_from_id( + const Word8 SplitRendBitRateId, + const ISAR_SPLIT_REND_POSE_CORRECTION_MODE poseCorrectionMode, + const Word16 split_prerender_frame_size_ms ) +{ + Word32 bitrate; + + SWITCH( SplitRendBitRateId ) + { + case 4: + { + bitrate = SPLIT_REND_768k; + move32(); + BREAK; + } + case 3: + { + bitrate = SPLIT_REND_512k; + move32(); + BREAK; + } + case 2: + { + bitrate = SPLIT_REND_384k; + move32(); + BREAK; + } + case 1: + { + bitrate = SPLIT_REND_320k; + move32(); + BREAK; + } + case 0: + { + bitrate = SPLIT_REND_256k; + move32(); + BREAK; + } + default: + { + bitrate = -1; + move32(); + BREAK; + } + } + + bitrate = isar_get_lc3plus_bitrate( bitrate, poseCorrectionMode, split_prerender_frame_size_ms ); + + /* Return size in bytes */ + return (Word32) ( bitrate * split_prerender_frame_size_ms / 1000 / 8 ); +} +#endif + +/*------------------------------------------------------------------------- + * Function isar_split_rend_validate_config() + * + * + *------------------------------------------------------------------------*/ + +ivas_error isar_split_rend_validate_config( + const ISAR_SPLIT_REND_CONFIG_DATA *pSplitRendConfig, + const Word16 is_pcm_out ) +{ + /* Valid DOF range is 0-3 */ + test(); + IF( LT_16( pSplitRendConfig->dof, 0 ) || GT_16( pSplitRendConfig->dof, 3 ) ) + { + return IVAS_ERROR( IVAS_ERR_INVALID_SPLIT_REND_CONFIG, "Valid DOF range is 0-3" ); + } + + /* Only CLDFB pose correction supports HQ mode */ + test(); + IF( NE_32( pSplitRendConfig->poseCorrectionMode, ISAR_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB ) && NE_16( pSplitRendConfig->hq_mode, 0 ) ) + { + return IVAS_ERROR( IVAS_ERR_INVALID_SPLIT_REND_CONFIG, "Only CLDFB pose correction supports HQ mode" ); + } + + /* Split rendering with no pose correction - 0 DOF and pose correction NONE must only ever be set together */ + test(); + test(); + test(); + IF( ( EQ_32( pSplitRendConfig->poseCorrectionMode, ISAR_SPLIT_REND_POSE_CORRECTION_MODE_NONE ) && NE_16( pSplitRendConfig->dof, 0 ) ) || + ( NE_32( pSplitRendConfig->poseCorrectionMode, ISAR_SPLIT_REND_POSE_CORRECTION_MODE_NONE ) && EQ_16( pSplitRendConfig->dof, 0 ) ) ) + { + return IVAS_ERROR( IVAS_ERR_INVALID_SPLIT_REND_CONFIG, "0 DOF and pose correction NONE must only ever be set together" ); + } + + IF( NE_16( pSplitRendConfig->codec_frame_size_ms, 0 ) ) /* 0 means "default for current codec", will be set to actual value at a later stage */ + { + test(); + test(); + test(); + IF( EQ_32( pSplitRendConfig->codec, ISAR_SPLIT_REND_CODEC_LCLD ) && NE_16( pSplitRendConfig->codec_frame_size_ms, 5 ) && NE_16( pSplitRendConfig->codec_frame_size_ms, 10 ) && NE_16( pSplitRendConfig->codec_frame_size_ms, 20 ) ) + { + return IVAS_ERROR( IVAS_ERR_INVALID_SPLIT_REND_CONFIG, "Invalid framing for LCLD codec" ); + } + + test(); + test(); + IF( EQ_32( pSplitRendConfig->codec, ISAR_SPLIT_REND_CODEC_LC3PLUS ) && NE_16( pSplitRendConfig->codec_frame_size_ms, 5 ) && NE_16( pSplitRendConfig->codec_frame_size_ms, 10 ) ) + { + return IVAS_ERROR( IVAS_ERR_INVALID_SPLIT_REND_CONFIG, "Invalid framing for LC3plus codec" ); + } + } + + /* Validate bitrate */ + IF( EQ_16( is_pcm_out, 0 ) ) + { + SWITCH( pSplitRendConfig->splitRendBitRate ) + { + case SPLIT_REND_256k: + IF( NE_16( pSplitRendConfig->dof, 0 ) ) + { + return IVAS_ERROR( IVAS_ERR_INVALID_SPLIT_REND_CONFIG, "Bitrates of 320 kbps and lower are only valid with 0 DOF" ); + } + BREAK; + case SPLIT_REND_320k: + /* Only valid with 0 DOF */ + IF( NE_16( pSplitRendConfig->dof, 0 ) ) + { + return IVAS_ERROR( IVAS_ERR_INVALID_SPLIT_REND_CONFIG, "Bitrates of 320 kbps and lower are only valid with 0 DOF" ); + } + BREAK; + case SPLIT_REND_384k: + case SPLIT_REND_512k: +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + case SPLIT_REND_768k: +#endif + /* Always valid */ + BREAK; +#ifndef ISAR_BITSTREAM_UPDATE_LC3PLUS + case SPLIT_REND_768k: + test(); + IF( EQ_16( pSplitRendConfig->dof, 0 ) && EQ_32( pSplitRendConfig->codec, ISAR_SPLIT_REND_CODEC_LC3PLUS ) ) + { + return IVAS_ERROR( IVAS_ERR_INVALID_SPLIT_REND_CONFIG, "Bitrate is too high for LC3plus with 0 DOF" ); + } + BREAK; +#endif + default: + return IVAS_ERR_LC3PLUS_INVALID_BITRATE; + } + } + ELSE + { + IF( EQ_16( pSplitRendConfig->dof, 1 ) ){ +#ifdef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS + IF( LT_32( pSplitRendConfig->splitRendBitRate, 34000 ) ){ + return IVAS_ERROR( IVAS_ERR_INVALID_SPLIT_REND_CONFIG, "1DOF metadata needs atleast 34 kbps" ); + } +#else + IF( LT_32( pSplitRendConfig->splitRendBitRate, 50000 ) ){ + return IVAS_ERROR( IVAS_ERR_INVALID_SPLIT_REND_CONFIG, "1DOF metadata needs atleast 50 kbps" ); + } +#endif +} +ELSE IF( EQ_16( pSplitRendConfig->dof, 2 ) ){ +#ifdef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS + IF( LT_32( pSplitRendConfig->splitRendBitRate, 50000 ) ){ + return IVAS_ERROR( IVAS_ERR_INVALID_SPLIT_REND_CONFIG, "2DOF metadata needs atleast 50 kbps" ); +} +#else + IF( LT_32( pSplitRendConfig->splitRendBitRate, 66000 ) ){ + return IVAS_ERROR( IVAS_ERR_INVALID_SPLIT_REND_CONFIG, "2DOF metadata needs atleast 66 kbps" ); +} +#endif +} +ELSE IF( EQ_16( pSplitRendConfig->dof, 3 ) ) +{ +#ifdef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS + IF( LT_32( pSplitRendConfig->splitRendBitRate, 82000 ) ) + { + return IVAS_ERROR( IVAS_ERR_INVALID_SPLIT_REND_CONFIG, "3DOF metadata needs atleast 128 kbps" ); + } +#else + IF( LT_32( pSplitRendConfig->splitRendBitRate, 128000 ) ) + { + return IVAS_ERROR( IVAS_ERR_INVALID_SPLIT_REND_CONFIG, "3DOF metadata needs atleast 128 kbps" ); + } +#endif +} +} + +return IVAS_ERR_OK; +} + + +/*------------------------------------------------------------------------- + * Function isar_split_rend_get_quant_params() + * + * + *------------------------------------------------------------------------*/ + +void isar_split_rend_get_quant_params_fx( + const Word16 num_md_bands, + Word16 pred_real_bands_yaw[ISAR_SPLIT_REND_NUM_QUANT_STRATS], + Word16 pred_imag_bands_yaw[ISAR_SPLIT_REND_NUM_QUANT_STRATS], + Word16 pred_quant_pnts_yaw[ISAR_SPLIT_REND_NUM_QUANT_STRATS], + Word32 pred_quantstep_yaw[ISAR_SPLIT_REND_NUM_QUANT_STRATS], + Word32 pred_1byquantstep_yaw[ISAR_SPLIT_REND_NUM_QUANT_STRATS], + Word16 d_bands_yaw[ISAR_SPLIT_REND_NUM_QUANT_STRATS], + Word16 bands_pitch[ISAR_SPLIT_REND_NUM_QUANT_STRATS], + Word16 pred_real_bands_roll[ISAR_SPLIT_REND_NUM_QUANT_STRATS], + Word16 pred_imag_bands_roll[ISAR_SPLIT_REND_NUM_QUANT_STRATS], +#ifdef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS + const Word16 ro_flag, +#endif + Word16 *num_quant_strats +#ifndef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS + , + Word16 *num_complex_bands +#endif +) +{ + Word16 q; + + *num_quant_strats = ISAR_SPLIT_REND_NUM_QUANT_STRATS; + move16(); +#ifndef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS + *num_complex_bands = COMPLEX_MD_BAND_THRESH_LOW; + move16(); + assert( *num_complex_bands <= num_md_bands ); +#endif + + pred_quant_pnts_yaw[0] = ISAR_SPLIT_REND_PRED_63QUANT_PNTS; + move16(); + pred_quantstep_yaw[0] = ISAR_SPLIT_REND_PRED63_Q_STEP_FX_Q31; + move32(); + pred_1byquantstep_yaw[0] = ISAR_SPLIT_REND_PRED63_1BYQ_STEP_FX_Q26; + move32(); + FOR( q = 1; q < *num_quant_strats; q++ ) + { + pred_quant_pnts_yaw[q] = ISAR_SPLIT_REND_PRED_31QUANT_PNTS; + move16(); + pred_quantstep_yaw[q] = ISAR_SPLIT_REND_PRED31_Q_STEP_FX_Q31; + move32(); + pred_1byquantstep_yaw[q] = ISAR_SPLIT_REND_PRED31_1BYQ_STEP_FX_Q26; + move32(); + } + + FOR( q = 0; q < *num_quant_strats; q++ ) + { + pred_real_bands_yaw[q] = num_md_bands; + move16(); + pred_real_bands_roll[q] = num_md_bands; + move16(); + } + +#ifndef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS + pred_imag_bands_yaw[0] = num_md_bands; + move16(); + pred_imag_bands_roll[0] = num_md_bands; + move16(); + pred_imag_bands_yaw[1] = num_md_bands; + move16(); + pred_imag_bands_roll[1] = num_md_bands; + move16(); + + FOR( q = 2; q < *num_quant_strats; q++ ) + { + pred_imag_bands_yaw[q] = LT_16( q, sub( *num_quant_strats, 1 ) ) ? num_md_bands : *num_complex_bands; + move16(); + pred_imag_bands_roll[q] = *num_complex_bands; + move16(); + } +#else + IF( ro_flag ) + { + FOR( q = 0; q < *num_quant_strats; q++ ) + { + pred_imag_bands_yaw[q] = SPLIT_REND_RO_MD_BAND_THRESH; + move16(); + } + } + ELSE + { + FOR( q = 0; q < *num_quant_strats - 2; q++ ) + { + pred_imag_bands_yaw[q] = num_md_bands; + move16(); + } + pred_imag_bands_yaw[( *num_quant_strats - 2 )] = COMPLEX_MD_BAND_THRESH_HIGH; + move16(); + pred_imag_bands_yaw[( *num_quant_strats - 1 )] = COMPLEX_MD_BAND_THRESH_LOW; + move16(); + } + + FOR( q = 0; q < *num_quant_strats; q++ ) + { + pred_imag_bands_roll[q] = SPLIT_REND_RO_MD_BAND_THRESH; + move16(); + } +#endif + + FOR( q = 0; q < *num_quant_strats; q++ ) + { + d_bands_yaw[q] = 0; + move16(); + bands_pitch[q] = num_md_bands; + move16(); + } + + return; +} + +#ifdef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS +/*------------------------------------------------------------------------- + * Function isar_renderSplitGetRot_axisNumBits() + * + * + *------------------------------------------------------------------------*/ + +Word16 isar_renderSplitGetRot_axisNumBits( + const Word16 dof ) +{ + Word16 num_bits; + IF( dof < 3 ) + { + num_bits = 2; + } + ELSE + { + num_bits = 0; + } + return num_bits; +} + +/*------------------------------------------------------------------------- + * Function isar_renderSplitGetRot_axisFromCode() + * + * + *------------------------------------------------------------------------*/ + +ISAR_SPLIT_REND_ROT_AXIS isar_renderSplitGetRot_axisFromCode( + const Word16 dof, + const Word16 code ) +{ + ISAR_SPLIT_REND_ROT_AXIS rot_axis; + + IF( dof == 1 ) + { + rot_axis = (ISAR_SPLIT_REND_ROT_AXIS) code; + } + else if ( dof == 2 ) + { + IF( code == 0 ) + { + rot_axis = (ISAR_SPLIT_REND_ROT_AXIS) code; + } + ELSE + { + rot_axis = (ISAR_SPLIT_REND_ROT_AXIS) ( code - 1 ) + YAW_PITCH; + } + } + ELSE + { + rot_axis = (ISAR_SPLIT_REND_ROT_AXIS) DEFAULT_AXIS; + } + + return rot_axis; +} + +/*------------------------------------------------------------------------- + * Function isar_renderSplitGetCodeFromRot_axis() + * + * + *------------------------------------------------------------------------*/ + +Word16 isar_renderSplitGetCodeFromRot_axis( + const Word16 dof, + const ISAR_SPLIT_REND_ROT_AXIS rot_axis, + Word16 *num_bits ) +{ + Word16 code = 0; + IF( dof == 1 ) + { + code = (Word16) rot_axis; + } + else if ( dof == 2 ) + { + IF( rot_axis == DEFAULT_AXIS ) + { + code = (Word16) rot_axis; + } + ELSE + { + code = (Word16) ( rot_axis - YAW_PITCH ) + 1; + } + } + ELSE + { + code = (Word16) DEFAULT_AXIS; + } + *num_bits = isar_renderSplitGetRot_axisNumBits( dof ); + + return code; +} +#endif + +/*------------------------------------------------------------------------- + * Function isar_renderSplitGetMultiBinPoseData() + * + * + *------------------------------------------------------------------------*/ + +void isar_renderSplitGetMultiBinPoseData_fx( + const ISAR_SPLIT_REND_CONFIG_DATA *pSplit_rend_config, + MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, + const ISAR_SPLIT_REND_ROT_AXIS rot_axis ) +{ + Word16 pos_idx, num_yaw_poses, num_pitch_poses, num_roll_poses; + const Word32 *relative_yaw_angles; + const Word32 *relative_pitch_angles; + const Word32 *relative_roll_angles; + + FOR( pos_idx = 0; pos_idx < MAX_HEAD_ROT_POSES; pos_idx++ ) + { + pMultiBinPoseData->relative_head_poses_fx[pos_idx][0] = 0; + move32(); + pMultiBinPoseData->relative_head_poses_fx[pos_idx][1] = 0; + move32(); + pMultiBinPoseData->relative_head_poses_fx[pos_idx][2] = 0; + move32(); + } + + /* 0 DOF defaults */ + num_yaw_poses = 0; + move16(); + num_pitch_poses = 0; + move16(); + num_roll_poses = 0; + move16(); + + /* defaults for all DOF except 3DOF HQ */ + relative_yaw_angles = ivas_split_rend_relative_yaw_pos_angles_hq_fx; + relative_pitch_angles = ivas_split_rend_relative_pitch_pos_angles_hq_fx; + relative_roll_angles = ivas_split_rend_relative_roll_pos_angles_hq_fx; + + IF( EQ_16( pSplit_rend_config->dof, 1 ) ) + { + SWITCH( rot_axis ) + { + case DEFAULT_AXIS: + case YAW: + { + num_yaw_poses = SPLIT_REND_MAX_YAW_ONLY_POSES; + move16(); + BREAK; + } + case PITCH: + { + num_pitch_poses = SPLIT_REND_MAX_PITCH_ONLY_POSES; + move16(); + BREAK; + } + case ROLL: + { + num_roll_poses = SPLIT_REND_MAX_ROLL_ONLY_POSES; + move16(); + BREAK; + } + default: + { + assert( 0 && "unsupported rotation axis value" ); + } + } + } + ELSE IF( EQ_16( pSplit_rend_config->dof, 2 ) ) + { + SWITCH( rot_axis ) + { + case DEFAULT_AXIS: +#ifndef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS + case YAW: + case PITCH: +#endif + case YAW_PITCH: + { + num_yaw_poses = SPLIT_REND_MAX_YAW_ONLY_POSES; + move16(); + num_pitch_poses = SPLIT_REND_MAX_PITCH_ONLY_POSES; + move16(); + BREAK; + } +#ifndef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS + case ROLL: +#endif + case YAW_ROLL: + { + num_yaw_poses = SPLIT_REND_MAX_YAW_ONLY_POSES; + move16(); + num_roll_poses = SPLIT_REND_MAX_ROLL_ONLY_POSES; + move16(); + BREAK; + } + case PITCH_ROLL: + { + num_pitch_poses = SPLIT_REND_MAX_PITCH_ONLY_POSES; + move16(); + num_roll_poses = SPLIT_REND_MAX_ROLL_ONLY_POSES; + move16(); + BREAK; + } + default: + { + assert( 0 && "unsupported rotation axis value" ); + } + } + } + ELSE IF( EQ_16( pSplit_rend_config->dof, 3 ) ) + { + IF( EQ_16( pSplit_rend_config->hq_mode, 1 ) ) + { + relative_yaw_angles = ivas_split_rend_relative_yaw_pos_angles_hq_fx; + relative_pitch_angles = ivas_split_rend_relative_pitch_pos_angles_hq_fx; + relative_roll_angles = ivas_split_rend_relative_roll_pos_angles_hq_fx; + num_yaw_poses = SPLIT_REND_MAX_YAW_ONLY_POSES; + move16(); + num_pitch_poses = SPLIT_REND_MAX_PITCH_ONLY_POSES; + move16(); + num_roll_poses = SPLIT_REND_MAX_ROLL_ONLY_POSES; + move16(); + } + ELSE + { + relative_yaw_angles = ivas_split_rend_relative_yaw_pos_angles_fx; + relative_pitch_angles = ivas_split_rend_relative_pitch_pos_angles_fx; + relative_roll_angles = ivas_split_rend_relative_roll_pos_angles_fx; + num_yaw_poses = SPLIT_REND_MAX_YAW_ONLY_POSES; + move16(); + num_pitch_poses = 1; + move16(); + num_roll_poses = 1; + move16(); + } + } + + pMultiBinPoseData->num_poses = add( add( num_yaw_poses, num_pitch_poses ), add( num_roll_poses, 1 ) ); + assert( LE_16( pMultiBinPoseData->num_poses, MAX_HEAD_ROT_POSES ) ); + + FOR( pos_idx = 0; pos_idx < num_yaw_poses; pos_idx++ ) + { + pMultiBinPoseData->relative_head_poses_fx[pos_idx + 1][0] = relative_yaw_angles[pos_idx]; + move32(); + } + + FOR( pos_idx = 0; pos_idx < num_pitch_poses; pos_idx++ ) + { + pMultiBinPoseData->relative_head_poses_fx[pos_idx + num_yaw_poses + 1][1] = relative_pitch_angles[pos_idx]; + move32(); + } + + FOR( pos_idx = 0; pos_idx < num_roll_poses; pos_idx++ ) + { + pMultiBinPoseData->relative_head_poses_fx[pos_idx + num_yaw_poses + num_pitch_poses + 1][2] = relative_roll_angles[pos_idx]; + move32(); + } + pMultiBinPoseData->dof = pSplit_rend_config->dof; + move16(); + pMultiBinPoseData->hq_mode = pSplit_rend_config->hq_mode; + move16(); + pMultiBinPoseData->rot_axis = rot_axis; + move32(); + pMultiBinPoseData->poseCorrectionMode = pSplit_rend_config->poseCorrectionMode; + move32(); + + return; +} + +/*------------------------------------------------------------------------- + * Function isar_renderSplitUpdateNoCorrectionPoseData() + * + * + *------------------------------------------------------------------------*/ + +void isar_renderSplitUpdateNoCorrectionPoseData( + const ISAR_SPLIT_REND_CONFIG_DATA *pSplit_rend_config, + MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData ) +{ + pMultiBinPoseData->num_poses = 1; + move16(); + assert( pSplit_rend_config->dof == 0 ); + pMultiBinPoseData->dof = pSplit_rend_config->dof; + move16(); + assert( pSplit_rend_config->poseCorrectionMode == ISAR_SPLIT_REND_POSE_CORRECTION_MODE_NONE ); + pMultiBinPoseData->poseCorrectionMode = pSplit_rend_config->poseCorrectionMode; + move32(); + + return; +} + + +/*------------------------------------------------------------------------- + * Function isar_init_multi_bin_pose_data() + * + * + *------------------------------------------------------------------------*/ + +void isar_init_multi_bin_pose_data_fx( + MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData ) +{ + Word16 pos_idx; + + FOR( pos_idx = 0; pos_idx < MAX_HEAD_ROT_POSES; pos_idx++ ) + { + pMultiBinPoseData->relative_head_poses_fx[pos_idx][0] = 0; + move32(); + pMultiBinPoseData->relative_head_poses_fx[pos_idx][1] = 0; + move32(); + pMultiBinPoseData->relative_head_poses_fx[pos_idx][2] = 0; + move32(); + } + pMultiBinPoseData->num_poses = 1; + move16(); + pMultiBinPoseData->dof = 3; + move16(); + pMultiBinPoseData->hq_mode = 0; + move16(); + pMultiBinPoseData->rot_axis = DEFAULT_AXIS; + move32(); + + return; +} + +/* Copy for encoder, to be removed */ +void isar_init_multi_bin_pose_data_fx_enc( + MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData ) +{ + Word16 pos_idx; + + FOR( pos_idx = 0; pos_idx < MAX_HEAD_ROT_POSES; pos_idx++ ) + { + pMultiBinPoseData->relative_head_poses_fx[pos_idx][0] = 0; + move32(); + pMultiBinPoseData->relative_head_poses_fx[pos_idx][1] = 0; + move32(); + pMultiBinPoseData->relative_head_poses_fx[pos_idx][2] = 0; + move32(); + } + pMultiBinPoseData->num_poses = 1; + move16(); + pMultiBinPoseData->dof = 3; + move16(); + pMultiBinPoseData->hq_mode = 0; + move16(); + pMultiBinPoseData->rot_axis = DEFAULT_AXIS; + move32(); + + return; +} + +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS +ivas_error isar_framesize_to_ms( + const IVAS_RENDER_FRAMESIZE frame_size, /* i : frame size enum */ + int16_t *ms /* o : frame size in ms */ +) +{ + switch ( frame_size ) + { + case IVAS_RENDER_FRAMESIZE_5MS: + *ms = 5; + break; + case IVAS_RENDER_FRAMESIZE_10MS: + *ms = 10; + break; + case IVAS_RENDER_FRAMESIZE_20MS: + *ms = 20; + break; + default: + return IVAS_ERROR( IVAS_ERR_INTERNAL, "Unsupported ISAR frame size" ); + } + + return IVAS_ERR_OK; +} +#endif + +/*------------------------------------------------------------------------- + * Function isar_split_rend_choose_default_codec() + * + * + *------------------------------------------------------------------------*/ + +ivas_error isar_split_rend_choose_default_codec( + ISAR_SPLIT_REND_CODEC *pCodec, /* i/o: pointer to codec setting */ +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + int16_t *pIsar_frame_size_ms, /* i/o: pointer to isar frame size setting */ +#endif + Word16 *pCodec_frame_size_ms, /* i/o: pointer to codec frame size setting */ + const Word16 cldfb_in_flag, /* i : flag indicating rendering in TD */ + const Word16 pcm_out_flag, /* i : flag to indicate PCM output */ + const Word16 num_subframes /* i : number of subframes */ +) +{ + IF( EQ_16( pcm_out_flag, 0 ) ) + { + IF( EQ_32( *pCodec, ISAR_SPLIT_REND_CODEC_DEFAULT ) ) + { + *pCodec = cldfb_in_flag ? ISAR_SPLIT_REND_CODEC_LCLD : ISAR_SPLIT_REND_CODEC_LC3PLUS; + move32(); + } + } + ELSE + { + *pCodec = ISAR_SPLIT_REND_CODEC_NONE; + move32(); + } + + IF( EQ_16( *pCodec_frame_size_ms, 0 ) ) /* codec frame size hasn't been set yet - use default for current configuration */ + { + SWITCH( *pCodec ) + { + case ISAR_SPLIT_REND_CODEC_LCLD: + *pCodec_frame_size_ms = DEPR_i_mult( num_subframes, 5 ); + BREAK; + case ISAR_SPLIT_REND_CODEC_LC3PLUS: + case ISAR_SPLIT_REND_CODEC_NONE: + *pCodec_frame_size_ms = 5; + move16(); + BREAK; + default: + return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "Unknown split codec value" ); + } + } +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + IF( *pIsar_frame_size_ms == 0 ) /* isar frame size hasn't been set yet - use default for current configuration */ + { + *pIsar_frame_size_ms = 20; + } +#endif + + return IVAS_ERR_OK; +} + +/*-------------------------------------------------------------------* + * Function get_bit() + * + * + *-------------------------------------------------------------------*/ + +Word32 get_bit( + const Word32 state, + const Word32 bit_id ) +{ + return L_and( state, ( L_shl( 1, (Word16) bit_id ) ) ); +} + + +#endif diff --git a/lib_isar/isar_stat.h b/lib_isar/isar_stat.h new file mode 100644 index 0000000000000000000000000000000000000000..fec4a5d807680260fd15bec8d3c859960b12c84a --- /dev/null +++ b/lib_isar/isar_stat.h @@ -0,0 +1,260 @@ +/****************************************************************************************************** + + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository. All Rights Reserved. + + This software is protected by copyright law and by international treaties. + The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository retain full ownership rights in their respective contributions in + the software. This notice grants no license of any kind, including but not limited to patent + license, nor is any license granted by implication, estoppel or otherwise. + + Contributors are required to enter into the IVAS codec Public Collaboration agreement before making + contributions. + + This software is provided "AS IS", without any express or implied warranties. The software is in the + development stage. It is intended exclusively for experts who have experience with such software and + solely for the purpose of inspection. All implied warranties of non-infringement, merchantability + and fitness for a particular purpose are hereby disclaimed and excluded. + + Any dispute, controversy or claim arising under or in relation to providing this software shall be + submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in + accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and + the United Nations Convention on Contracts on the International Sales of Goods. + +*******************************************************************************************************/ + +#ifndef ISAR_STAT_H +#define ISAR_STAT_H + + +#include +#include "options.h" +#include "stat_com.h" +#include "ivas_stat_com.h" +#ifdef SPLIT_REND_WITH_HEAD_ROT +#include "isar_lcld_prot.h" +#include "isar_lc3plus_enc.h" +#include "isar_lc3plus_dec.h" +#include "isar_cnst.h" + + +/*-------------------------------------------------------------------* + * ISAR post rend constants + *-------------------------------------------------------------------*/ + +#define MAX_CLDFB_BUFFER_LENGTH_PER_CHANNEL ( MAX_BUFFER_LENGTH_PER_CHANNEL * 2 ) +#define MAX_CLDFB_BUFFER_LENGTH ( MAX_CLDFB_BUFFER_LENGTH_PER_CHANNEL * MAX_INPUT_CHANNELS ) +#define MAX_BIN_BUFFER_LENGTH ( MAX_BUFFER_LENGTH_PER_CHANNEL * BINAURAL_CHANNELS ) +#define MAX_CLDFB_BIN_BUFFER_LENGTH ( MAX_CLDFB_BUFFER_LENGTH_PER_CHANNEL * BINAURAL_CHANNELS ) + +/*-------------------------------------------------------------------* + * ISAR post rend structs + *-------------------------------------------------------------------*/ + +typedef struct +{ + int8_t headRotEnabled; + IVAS_QUATERNION headPositions[IVAS_MAX_PARAM_SPATIAL_SUBFRAMES]; + IVAS_VECTOR3 Pos[IVAS_MAX_PARAM_SPATIAL_SUBFRAMES]; + Word32 crossfade_fx[L_FRAME48k / IVAS_MAX_PARAM_SPATIAL_SUBFRAMES]; + ISAR_SPLIT_REND_ROT_AXIS sr_pose_pred_axis; + +} ISAR_POST_REND_HeadRotData; + +typedef struct +{ +#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG + HANDLE_CLDFB_FILTER_BANK cldfbAna[( 1 + MAX_HEAD_ROT_POSES ) * BINAURAL_CHANNELS]; +#else + HANDLE_CLDFB_FILTER_BANK cldfbAna[MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS]; +#endif + HANDLE_CLDFB_FILTER_BANK cldfbSyn[BINAURAL_CHANNELS]; + +} CLDFB_HANDLES_WRAPPER, *CLDFB_HANDLES_WRAPPER_HANDLE; + +typedef struct isar_split_rend_huffman_cfg_t +{ + const int32_t *codebook; + int16_t min_len; + int16_t max_len; + int16_t sym_len; + +} isar_split_rend_huffman_cfg_t; + +typedef struct isar_binaural_head_rot_split_rendering_huff_struct +{ + isar_split_rend_huffman_cfg_t pred[2]; + int16_t pred_idx_trav[2][ISAR_SPLIT_REND_PRED_63QUANT_PNTS]; + int16_t pred_base2_code_len[2]; + isar_split_rend_huffman_cfg_t pred_roll; + int16_t pred_roll_idx_trav[ISAR_SPLIT_REND_ROLL_PRED_QUANT_PNTS]; + int16_t pred_roll_base2_code_len; + isar_split_rend_huffman_cfg_t gd; + int16_t gd_base2_code_len; + int16_t gd_idx_trav[ISAR_SPLIT_REND_D_QUANT_PNTS]; + isar_split_rend_huffman_cfg_t p_gd; + int16_t p_gd_base2_code_len; + int16_t p_gd_idx_trav[ISAR_SPLIT_REND_D_QUANT_PNTS]; + isar_split_rend_huffman_cfg_t p_gd_diff; + int16_t p_gd_diff_base2_code_len; + int16_t p_gd_diff_idx_trav[ISAR_SPLIT_REND_D_QUANT_PNTS]; + +} ISAR_BIN_HR_SPLIT_REND_HUFF, *ISAR_BIN_HR_SPLIT_REND_HUFF_HANDLE; + +/* binaural split rendering head rotation data structure */ +typedef struct isar_binaural_head_rot_split_rendering_md_struct +{ + Word32 pred_mat_re_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS]; /* Q25 */ + Word16 exp_pred_mat_re; + Word32 pred_mat_im_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS]; /* Q25 */ + Word16 exp_pred_mat_im; +#ifdef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS + Word32 pred_mat_re2[BINAURAL_CHANNELS]; + Word16 exp_pred_mat_re2; +#endif + Word32 gd_fx; /* Q25 */ + Word32 gd2_fx; /* Q25 */ + Word16 exp_gd; + Word16 exp_gd2; + int16_t pred_mat_re_idx[BINAURAL_CHANNELS][BINAURAL_CHANNELS]; + int16_t pred_mat_im_idx[BINAURAL_CHANNELS][BINAURAL_CHANNELS]; + int16_t gd_idx; + int16_t gd2_idx; + +} ISAR_BIN_HR_SPLIT_REND_MD, *ISAR_BIN_HR_SPLIT_REND_MD_HANDLE; +typedef struct isar_binaural_head_rot_split_pre_rendering_struct +{ + ISAR_BIN_HR_SPLIT_REND_MD rot_md[MAX_HEAD_ROT_POSES - 1][MAX_SPLIT_MD_SUBFRAMES][MAX_SPLIT_REND_MD_BANDS]; + Word32 fix_pos_rot_mat_fx[MAX_HEAD_ROT_POSES - 1][BINAURAL_CHANNELS][BINAURAL_CHANNELS]; + float fix_pos_rot_mat[MAX_HEAD_ROT_POSES - 1][BINAURAL_CHANNELS][BINAURAL_CHANNELS]; + ISAR_SPLIT_REND_POSE_TYPE pose_type[MAX_HEAD_ROT_POSES - 1]; + ISAR_BIN_HR_SPLIT_REND_HUFF huff_cfg; +} ISAR_BIN_HR_SPLIT_PRE_REND, *ISAR_BIN_HR_SPLIT_PRE_REND_HANDLE; +/*----------------------------------------------------------------------------------* + * Output configuration for renderer (e.g. DirAC, MASA, Binaural Renderer...) + *----------------------------------------------------------------------------------*/ + +typedef struct isar_binaural_head_rot_split_rendering_lcld_enc_struct +{ + void *pLcld_enc; + Word16 iChannels; + LCLDEncoder *psLCLDEncoder; + Word32 ***pppfLCLDReal_fx; + Word32 ***pppfLCLDImag_fx; +#ifdef CLDFB_DEBUG + FILE *cldfbIn; + int16_t numFrame; +#endif + Word16 iNumIterations; + Word16 iNumBlocks; + +} ISAR_BIN_HR_SPLIT_LCLD_ENC, *ISAR_BIN_HR_SPLIT_LCLD_ENC_HANDLE; + +typedef struct +{ + Word32 Cldfb_Prev_BinReal_fx[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX + CLDFB_PLC_XF][CLDFB_NO_CHANNELS_MAX]; + Word32 Cldfb_Prev_BinImag_fx[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX + CLDFB_PLC_XF][CLDFB_NO_CHANNELS_MAX]; + Word16 Q_Prev_Bin_fx; + Word32 xf_bet_fx[2][CLDFB_NO_CHANNELS_MAX][CLDFB_PLC_XF]; + +} ISAR_CLDFB_PLC, *ISAR_CLDFB_PLC_HANDLE; +typedef struct +{ + ISAR_CLDFB_PLC CldfbPLC_state; + Word16 prev_bfi; + Word16 bf_count; + Word16 iNumSubSets; + +} ISAR_SPLIT_REND_PLC_STRUCT, *ISAR_SPLIT_REND_PLC_HANDLE; +typedef struct isar_binaural_head_rot_split_rendering_lcld_dec_struct +{ + void *pLcld_dec; + Word32 iChannels; + LCLDDecoder *psLCLDDecoder; + Word32 ***pppfDecLCLDReal_fx; + Word32 ***pppfDecLCLDImag_fx; +#ifdef CLDFB_DEBUG + FILE *cldfbOut; + int16_t numFrame; +#endif + ISAR_SPLIT_REND_PLC_HANDLE hSplitRendPLC; + + Word16 iNumBlocks; + Word16 iNumIterations; + +} ISAR_BIN_HR_SPLIT_LCLD_DEC, *ISAR_BIN_HR_SPLIT_LCLD_DEC_HANDLE; +typedef struct isar_binaural_head_rot_split_post_rendering_struct +{ + ISAR_BIN_HR_SPLIT_REND_MD rot_md[MAX_HEAD_ROT_POSES][MAX_SPLIT_MD_SUBFRAMES][MAX_SPLIT_REND_MD_BANDS]; + IVAS_QUATERNION QuaternionsPre[MAX_PARAM_SPATIAL_SUBFRAMES]; + int16_t low_Res; + + float fix_pos_rot_mat[MAX_HEAD_ROT_POSES - 1][BINAURAL_CHANNELS][BINAURAL_CHANNELS]; + Word32 fix_pos_rot_mat_fx[MAX_HEAD_ROT_POSES - 1][BINAURAL_CHANNELS][BINAURAL_CHANNELS]; /* Q31 */ + ISAR_SPLIT_REND_POSE_TYPE pose_type[MAX_HEAD_ROT_POSES - 1]; + ISAR_BIN_HR_SPLIT_REND_HUFF huff_cfg; +#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG + Word32 mixer_mat_re_fx[MAX_HEAD_ROT_POSES][MAX_SPLIT_REND_MD_BANDS][BINAURAL_CHANNELS][BINAURAL_CHANNELS]; + Word32 mixer_mat_im_fx[MAX_HEAD_ROT_POSES][MAX_SPLIT_REND_MD_BANDS][BINAURAL_CHANNELS][BINAURAL_CHANNELS]; + Word32 gd_mem_fx[MAX_HEAD_ROT_POSES][MAX_SPLIT_REND_MD_BANDS]; +#else + Word32 mixer_mat_re_fx[1][MAX_SPLIT_REND_MD_BANDS][BINAURAL_CHANNELS][BINAURAL_CHANNELS]; + Word32 mixer_mat_im_fx[1][MAX_SPLIT_REND_MD_BANDS][BINAURAL_CHANNELS][BINAURAL_CHANNELS]; + Word32 gd_mem_fx[1][MAX_SPLIT_REND_MD_BANDS]; +#endif + int16_t cf_flag; + HANDLE_CLDFB_FILTER_BANK cldfbAna[BINAURAL_CHANNELS]; + HANDLE_CLDFB_FILTER_BANK cldfbSyn[BINAURAL_CHANNELS]; +#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG + HANDLE_CLDFB_FILTER_BANK cldfbSynReconsBinDec[MAX_HEAD_ROT_POSES][BINAURAL_CHANNELS]; +#endif + +} ISAR_BIN_HR_SPLIT_POST_REND, *ISAR_BIN_HR_SPLIT_POST_REND_HANDLE; + +typedef struct +{ + int16_t num_poses; + // float relative_head_poses[MAX_HEAD_ROT_POSES][3]; + Word32 relative_head_poses_fx[MAX_HEAD_ROT_POSES][3]; /* Q22 */ + int16_t dof; + int16_t hq_mode; + ISAR_SPLIT_REND_ROT_AXIS rot_axis; + ISAR_SPLIT_REND_POSE_CORRECTION_MODE poseCorrectionMode; + +} MULTI_BIN_REND_POSE_DATA; + +typedef struct +{ + MULTI_BIN_REND_POSE_DATA multiBinPoseData; + ISAR_BIN_HR_SPLIT_POST_REND_HANDLE hBinHrSplitPostRend; + ISAR_BIN_HR_SPLIT_LCLD_DEC_HANDLE hSplitBinLCLDDec; + int16_t first_good_frame_received; + ISAR_LC3PLUS_DEC_HANDLE hLc3plusDec; + Word16 Q_last; + +} ISAR_SPLIT_POST_REND_WRAPPER; + + +typedef struct +{ + MULTI_BIN_REND_POSE_DATA multiBinPoseData; + ISAR_BIN_HR_SPLIT_PRE_REND_HANDLE hBinHrSplitPreRend; + ISAR_BIN_HR_SPLIT_LCLD_ENC_HANDLE hSplitBinLCLDEnc; + CLDFB_HANDLES_WRAPPER_HANDLE hCldfbHandles; + ISAR_LC3PLUS_ENC_HANDLE hLc3plusEnc; + // float *lc3plusDelayBuffers[MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS]; /* Used to time-align head pose correction metadata with LC3plus-coded reference audio */ + Word32 *lc3plusDelayBuffers_fx[MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS]; /* Used to time-align head pose correction metadata with LC3plus-coded reference audio */ + Word16 lc3plusDelayBuffers_q; + Word32 lc3plusDelaySamples; +} SPLIT_REND_WRAPPER; + +#endif + +#endif /* ISAR_STAT_H */ diff --git a/lib_isar/lib_isar_post_rend.c b/lib_isar/lib_isar_post_rend.c new file mode 100644 index 0000000000000000000000000000000000000000..4e302cfa922187029188e490573ba6505e962da2 --- /dev/null +++ b/lib_isar/lib_isar_post_rend.c @@ -0,0 +1,1918 @@ +/****************************************************************************************************** + + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository. All Rights Reserved. + + This software is protected by copyright law and by international treaties. + The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository retain full ownership rights in their respective contributions in + the software. This notice grants no license of any kind, including but not limited to patent + license, nor is any license granted by implication, estoppel or otherwise. + + Contributors are required to enter into the IVAS codec Public Collaboration agreement before making + contributions. + + This software is provided "AS IS", without any express or implied warranties. The software is in the + development stage. It is intended exclusively for experts who have experience with such software and + solely for the purpose of inspection. All implied warranties of non-infringement, merchantability + and fitness for a particular purpose are hereby disclaimed and excluded. + + Any dispute, controversy or claim arising under or in relation to providing this software shall be + submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in + accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and + the United Nations Convention on Contracts on the International Sales of Goods. + +*******************************************************************************************************/ + + +#include "options.h" +#include "lib_isar_post_rend.h" +#include "isar_stat.h" +#include "isar_prot.h" +#include "prot_fx.h" +#include "ivas_prot_fx.h" +#include "prot_fx.h" +#ifndef SPLIT_REND_WITH_HEAD_ROT + +int32_t ISAR_POST_REND_void_func( void ) +{ + return 0; +} + +#else + +#include "ivas_prot_rend_fx.h" +#include +#include +#include "wmc_auto.h" +#include "prot_fx.h" + + +/*-------------------------------------------------------------------* + * Local constants + *-------------------------------------------------------------------*/ + +/*-------------------------------------------------------------------* + * Local types + *-------------------------------------------------------------------*/ + +/* EFAP wrapper to simplify writing panning gains to a vector that includes LFE channels */ +typedef struct +{ + EFAP_HANDLE hEfap; + AUDIO_CONFIG speakerConfig; + const LSSETUP_CUSTOM_STRUCT *pCustomLsSetup; /* Pointer to main custom LS struct from renderer handle - doesn't need freeing */ +} EFAP_WRAPPER; + +/* Lightweight helper struct that gathers all information required for rendering + * any config to any other config. Used to simplify signatures of rendering functions. + * + * This struct should store ONLY CONST POINTERS to data existing elsewhere. + * Storing pointers instead of data itself ensures that no additional updates + * are required when any of these are changed in the renderer. Making the pointers + * const ensures that this data is only read, but not modified by the rendering functions. */ +typedef struct +{ + const int32_t *pOutSampleRate; + const AUDIO_CONFIG *pOutConfig; +#ifndef ISAR_BITSTREAM_UPDATE_LC3PLUS + const LSSETUP_CUSTOM_STRUCT *pCustomLsOut; + const EFAP_WRAPPER *pEfapOutWrapper; +#endif + const ISAR_POST_REND_HeadRotData *pHeadRotData; +#ifndef ISAR_BITSTREAM_UPDATE_LC3PLUS + const RENDER_CONFIG_HANDLE *hhRendererConfig; +#endif + const int16_t *pSplitRendBFI; +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + const ISAR_SPLIT_REND_CONFIG_DATA *pSplitRenderConfig; +#endif +} rendering_context; + +/* Common base for input structs */ +typedef struct +{ + AUDIO_CONFIG inConfig; + ISAR_POST_REND_InputId id; + IVAS_REND_AudioBuffer inputBuffer; + Word32 gain_fx; /* Linear, not in dB */ + rendering_context ctx; + int32_t numNewSamplesPerChannel; /* Used to keep track how much new audio was fed before rendering current frame */ +} input_base; + +typedef struct +{ + input_base base; + ISAR_SPLIT_POST_REND_WRAPPER splitPostRendWrapper; + Word32 *bufferData_fx; + int16_t numCachedSamples; /* Number of decoded samples in bufferData that have not yet been played out */ + ISAR_POST_REND_BitstreamBuffer *hBits; +} input_split_post_rend; + +struct ISAR_POST_REND +{ + int32_t sampleRateOut; + + IVAS_LIMITER_HANDLE hLimiter; +#ifdef DEBUGGING + int32_t numClipping; /* Counter of clipped output samples */ +#endif + + input_split_post_rend inputsSplitPost[RENDERER_MAX_BIN_INPUTS]; + + AUDIO_CONFIG inputConfig; + AUDIO_CONFIG outputConfig; + + ISAR_POST_REND_HeadRotData headRotData; + int16_t splitRendBFI; + + int8_t rendererConfigEnabled; + ISAR_SPLIT_REND_CONFIG_DATA splitRenderConfig; + + int16_t num_subframes; +}; + +/*-------------------------------------------------------------------* + * getAudioConfigType() + * + * + *-------------------------------------------------------------------*/ +ISAR_POST_REND_AudioConfigType isar_getAudioConfigType( + const AUDIO_CONFIG config ) +{ + ISAR_POST_REND_AudioConfigType type; + + SWITCH( config ) + { + case IVAS_AUDIO_CONFIG_BINAURAL: + case IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM: + case IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED: + type = ISAR_POST_REND_AUDIO_CONFIG_TYPE_BINAURAL; + BREAK; + default: + type = ISAR_POST_REND_AUDIO_CONFIG_TYPE_UNKNOWN; + BREAK; + } + + return type; +} + +/*-------------------------------------------------------------------* + * Local function prototypes + *-------------------------------------------------------------------*/ + +/*-------------------------------------------------------------------* + * Local functions + *-------------------------------------------------------------------*/ + +static ivas_error allocateInputBaseBufferData_fx( + Word32 **data, + const Word16 data_size ) +{ + *data = (Word32 *) malloc( data_size * sizeof( Word32 ) ); + IF( *data == NULL ) + { + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for input base buffer data" ); + } + + return IVAS_ERR_OK; +} +static void freeInputBaseBufferData_fx( + Word32 **data ) +{ + IF( *data != NULL ) + { + free( *data ); + *data = NULL; + } + + return; +} + +static IVAS_QUATERNION quaternionInit( + void ) +{ + IVAS_QUATERNION q; + q.w_fx = ONE_IN_Q22; + q.x_fx = q.y_fx = q.z_fx = 0; + return q; +} + +static void convertBitsBufferToInternalBitsBuff( + const ISAR_POST_REND_BitstreamBuffer outBits, + ISAR_SPLIT_REND_BITS_HANDLE hBits ) +{ + hBits->bits_buf = outBits.bits; + hBits->bits_read = outBits.config.bitsRead; + hBits->bits_written = outBits.config.bitsWritten; + hBits->buf_len = outBits.config.bufLenInBytes; + hBits->codec = outBits.config.codec; + hBits->pose_correction = outBits.config.poseCorrection; + hBits->codec_frame_size_ms = outBits.config.codec_frame_size_ms; +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + hBits->isar_frame_size_ms = outBits.config.isar_frame_size_ms; + hBits->lc3plus_highres = outBits.config.lc3plusHighRes; +#endif + + return; +} + +static void convertInternalBitsBuffToBitsBuffer( + ISAR_POST_REND_BitstreamBuffer *hOutBits, + const ISAR_SPLIT_REND_BITS_DATA bits ) +{ + hOutBits->bits = bits.bits_buf; + hOutBits->config.bitsRead = bits.bits_read; + hOutBits->config.bitsWritten = bits.bits_written; + hOutBits->config.bufLenInBytes = bits.buf_len; + hOutBits->config.codec = bits.codec; + hOutBits->config.poseCorrection = bits.pose_correction; + hOutBits->config.codec_frame_size_ms = bits.codec_frame_size_ms; +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + hOutBits->config.isar_frame_size_ms = bits.isar_frame_size_ms; + hOutBits->config.lc3plusHighRes = bits.lc3plus_highres; +#endif + + return; +} + +static void copyBufferTo2dArray_fx( + const IVAS_REND_AudioBuffer buffer, + Word32 array[][L_FRAME48k] ) +{ + UWord32 smplIdx; + UWord32 chnlIdx; + const Word32 *readPtr; + + assert( ( buffer.config.is_cldfb == 0 ) && "for CLDFB input call copyBufferToCLDFBarray()" ); + readPtr = buffer.data_fx; + + FOR( chnlIdx = 0; chnlIdx < (UWord32) buffer.config.numChannels; ++chnlIdx ) + { + FOR( smplIdx = 0; smplIdx < (UWord32) buffer.config.numSamplesPerChannel; ++smplIdx ) + { + array[chnlIdx][smplIdx] = *readPtr++; + } + } + + return; +} + +static void accumulate2dArrayToBuffer_fx( + Word32 array[][L_FRAME48k], + Word16 Q_out[][BINAURAL_CHANNELS], + Word16 Q_max, + const IVAS_REND_AudioBuffer *buffer, + Word16 num_subframes, + Word16 subframe_length ) +{ + Word16 smplIdx, chnlIdx; + Word32 *writePtr; + + writePtr = buffer->data_fx; + FOR( chnlIdx = 0; chnlIdx < buffer->config.numChannels; ++chnlIdx ) + { + FOR( Word16 sf_idx = 0; sf_idx < num_subframes; sf_idx++ ) + { + FOR( smplIdx = 0; smplIdx < subframe_length; ++smplIdx ) + { + //*writePtr++ += (float) array[chnlIdx][( sf_idx * subframe_length ) + smplIdx] / powf( 2, Q_out[sf_idx][chnlIdx] ); + *writePtr++ += L_shl( array[chnlIdx][( sf_idx * subframe_length ) + smplIdx], sub( Q_max, Q_out[sf_idx][chnlIdx] ) ); + } + } + } + + return; +} + +/*-------------------------------------------------------------------* + * limitRendererOutput() + * + * In-place saturation control for multichannel buffers with adaptive release time + *-------------------------------------------------------------------*/ + +#ifndef DISABLE_LIMITER +/*! r: number of clipped output samples */ +static Word32 limitRendererOutput_fx( + IVAS_LIMITER_HANDLE hLimiter, /* i/o: limiter struct handle */ + Word32 *output, /* i/o: I/O buffer */ + const Word16 output_frame, /* i : number of samples per channel in the buffer */ + const Word32 threshold, /* i : signal amplitude above which limiting starts to be applied */ + Word16 q_factor ) /* i : q factor of output samples */ +{ + Word16 i; + Word32 **channels; + Word16 num_channels; + Word32 numClipping = 0; + + /* return early if given bad parameters */ + IF( hLimiter == NULL || output == NULL || output_frame <= 0 ) + { + return 0; + } + + channels = hLimiter->channel_ptrs_fx; + num_channels = hLimiter->num_channels; + + FOR( i = 0; i < num_channels; ++i ) + { + channels[i] = output + i * output_frame; + } + + limiter_process_fx( hLimiter, output_frame, threshold, 0, NULL, q_factor ); + + /* Apply clipping to buffer in case the limiter let through some samples > 1.0f */ + FOR( i = 0; i < output_frame * num_channels; ++i ) + { + + output[i] = min( max( L_shl( INT16_MIN, q_factor ), output[i] ), L_shl( INT16_MAX, q_factor ) ); + } + + return numClipping; +} + +#endif + + +/*-------------------------------------------------------------------* + * validateOutputSampleRate() + * + * + *-------------------------------------------------------------------*/ +static ivas_error validateOutputSampleRate( + const Word32 sampleRate, + const AUDIO_CONFIG outConfig ) +{ + IF( ( outConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || outConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) && NE_32( sampleRate, 48000 ) ) + { + return IVAS_ERROR( IVAS_ERR_INVALID_SAMPLING_RATE, "Error: Only 48kHz output sampling rate is supported for split rendering." ); + } + ELSE + { + /* Otherwise rendering to binaural, support the same set as IVAS decoder */ + SWITCH( sampleRate ) + { + case 8000: + case 16000: + case 32000: + case 48000: + return IVAS_ERR_OK; + } + + return IVAS_ERR_INVALID_SAMPLING_RATE; + } +} + +/*-------------------------------------------------------------------* + * Local functions + *-------------------------------------------------------------------*/ +static ivas_error initLimiter( + IVAS_LIMITER_HANDLE *phLimiter, + const Word16 numChannels, + const Word32 sampleRate ) +{ + ivas_error error; + + /* If re-initializing with unchanged values, return early */ + IF( *phLimiter != NULL && ( *phLimiter )->num_channels == numChannels && ( *phLimiter )->sampling_rate == sampleRate ) + { + return IVAS_ERR_OK; + } + + /* Support re-init: close if already allocated */ + IF( *phLimiter != NULL ) + { + ivas_limiter_close_fx( phLimiter ); + } + + IF( ( error = ivas_limiter_open_fx( phLimiter, numChannels, sampleRate ) ) != IVAS_ERR_OK ) + { + return error; + } + + return IVAS_ERR_OK; +} + +static ivas_error initHeadRotation( + ISAR_POST_REND_HANDLE hIvasRend ) +{ + Word16 i, crossfade_len; + Word32 tmp; + + /* Head rotation is enabled by default */ + hIvasRend->headRotData.headRotEnabled = 1; + + /* Initialize 5ms crossfade */ + crossfade_len = 240 /*L_FRAME48k / MAX_PARAM_SPATIAL_SUBFRAMES*/; + tmp = 8985287 /*1.f / ( crossfade_len - 1 )*/; + FOR( i = 0; i < crossfade_len; i++ ) + { + hIvasRend->headRotData.crossfade_fx[i] = W_extract_l( W_mult0_32_32( i, tmp ) ); + } + + /* Initialize with unit quaternions */ + FOR( i = 0; i < hIvasRend->num_subframes; ++i ) + { + hIvasRend->headRotData.headPositions[i] = quaternionInit(); + } + + hIvasRend->headRotData.sr_pose_pred_axis = DEFAULT_AXIS; + + return IVAS_ERR_OK; +} +static void initRendInputBase_fx( + input_base *inputBase, + const AUDIO_CONFIG inConfig, + const IVAS_REND_InputId id, + const rendering_context rendCtx, + Word32 *dataBuf, + const Word16 dataBufSize ) +{ + inputBase->inConfig = inConfig; + inputBase->id = id; + inputBase->gain_fx = MAX_32; + inputBase->ctx = rendCtx; + inputBase->numNewSamplesPerChannel = 0; + + inputBase->inputBuffer.config.numSamplesPerChannel = 0; + inputBase->inputBuffer.config.numChannels = 0; + inputBase->inputBuffer.data_fx = dataBuf; + IF( inputBase->inputBuffer.data_fx != NULL ) + { + set_l( inputBase->inputBuffer.data_fx, 0, dataBufSize ); + } + + return; +} + +static rendering_context getRendCtx( + ISAR_POST_REND_HANDLE hIvasRend ) +{ + rendering_context ctx; + + /* Note: when refactoring this, always take the ADDRESS of a member of the + * renderer struct, so that the context stores a POINTER to the member, even + * if the member is a pointer or handle itself. */ + ctx.pOutConfig = &hIvasRend->outputConfig; + ctx.pOutSampleRate = &hIvasRend->sampleRateOut; + ctx.pHeadRotData = &hIvasRend->headRotData; + ctx.pSplitRendBFI = &hIvasRend->splitRendBFI; +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + ctx.pSplitRenderConfig = &hIvasRend->splitRenderConfig; +#endif + + return ctx; +} + + +static ivas_error getRendInputNumChannels( + const void *rendInput, + Word16 *numInChannels ) +{ + /* Using a void pointer for this function to be reusable for any input type (input_ism, input_mc, input_sba). + Assumptions: - input_base is always the first member in the input struct */ + (void) rendInput; + + *numInChannels = 2; + + return IVAS_ERR_OK; +} + +static ivas_error updateSplitPostRendPanGains( + input_split_post_rend *inputSplitPostRend, + const AUDIO_CONFIG outConfig, + ISAR_SPLIT_REND_CONFIG_DATA *hRendCfg +#ifndef ISAR_BITSTREAM_UPDATE_LC3PLUS + , + int16_t num_subframes +#endif +) +{ + ivas_error error; + rendering_context rendCtx; + LC3PLUS_CONFIG config; + Word16 iNumBlocksPerFrame, iNumLCLDIterationsPerFrame; + + (void) outConfig; + + rendCtx = inputSplitPostRend->base.ctx; + isar_renderSplitGetMultiBinPoseData_fx( hRendCfg, &inputSplitPostRend->splitPostRendWrapper.multiBinPoseData, rendCtx.pHeadRotData->sr_pose_pred_axis ); + +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + config.high_res_mode_enabled = ( hRendCfg->lc3plus_highres != 0 ); +#endif + config.lc3plus_frame_duration_us = hRendCfg->codec_frame_size_ms * 1000; +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + config.isar_frame_duration_us = hRendCfg->isar_frame_size_ms * 1000; +#else + IF( NE_16( num_subframes, MAX_PARAM_SPATIAL_SUBFRAMES ) ) + { + IF( hRendCfg->codec == ISAR_SPLIT_REND_CODEC_LC3PLUS ) + { + config.ivas_frame_duration_us = ( hRendCfg->poseCorrectionMode == ISAR_SPLIT_REND_POSE_CORRECTION_MODE_NONE ) ? config.lc3plus_frame_duration_us * num_subframes : 20000; + } + ELSE + { + config.ivas_frame_duration_us = ( hRendCfg->poseCorrectionMode == ISAR_SPLIT_REND_POSE_CORRECTION_MODE_NONE ) ? config.lc3plus_frame_duration_us : 20000; + } + iNumLCLDIterationsPerFrame = 1; + } + ELSE + { + config.ivas_frame_duration_us = 20000; + } +#endif + + IF( GT_16( hRendCfg->codec_frame_size_ms, 0 ) ) + { + iNumLCLDIterationsPerFrame = (Word16) config.isar_frame_duration_us / ( 1000 * hRendCfg->codec_frame_size_ms ); + iNumLCLDIterationsPerFrame = max( 1, iNumLCLDIterationsPerFrame ); + iNumBlocksPerFrame = CLDFB_NO_COL_MAX * hRendCfg->codec_frame_size_ms / 20; + } + ELSE + { + iNumLCLDIterationsPerFrame = 1; + iNumBlocksPerFrame = CLDFB_NO_COL_MAX; + } + + config.channels = BINAURAL_CHANNELS; + config.samplerate = *inputSplitPostRend->base.ctx.pOutSampleRate; + + IF( hRendCfg->codec == ISAR_SPLIT_REND_CODEC_LCLD ) + { + IF( ( error = isar_splitBinLCLDDecOpen( &inputSplitPostRend->splitPostRendWrapper.hSplitBinLCLDDec, *inputSplitPostRend->base.ctx.pOutSampleRate, BINAURAL_CHANNELS, iNumBlocksPerFrame, iNumLCLDIterationsPerFrame ) ) != IVAS_ERR_OK ) + { + return error; + } + } + ELSE IF( hRendCfg->codec == ISAR_SPLIT_REND_CODEC_LC3PLUS ) + { + IF( ( error = ISAR_LC3PLUS_DEC_Open( config, + &inputSplitPostRend->splitPostRendWrapper.hLc3plusDec ) ) != IVAS_ERR_OK ) + { + return error; + } + } + + IF( ( error = isar_splitBinPostRendOpen( &inputSplitPostRend->splitPostRendWrapper.hBinHrSplitPostRend, &inputSplitPostRend->splitPostRendWrapper.multiBinPoseData, *rendCtx.pOutSampleRate ) ) != IVAS_ERR_OK ) + { + return error; + } + + return IVAS_ERR_OK; +} + +static ivas_error setRendInputActiveSplitPostRend( + void *input, + const AUDIO_CONFIG inConfig, + const IVAS_REND_InputId id, + ISAR_SPLIT_REND_CONFIG_DATA *hRendCfg +#ifndef ISAR_BITSTREAM_UPDATE_LC3PLUS + , + const int16_t num_subframes +#endif +) +{ + ivas_error error; + rendering_context rendCtx; + AUDIO_CONFIG outConfig; + input_split_post_rend *inputSplitPostRend; + + inputSplitPostRend = (input_split_post_rend *) input; + rendCtx = inputSplitPostRend->base.ctx; + outConfig = *rendCtx.pOutConfig; + + IF( ( error = allocateInputBaseBufferData_fx( &inputSplitPostRend->bufferData_fx, MAX_CLDFB_BIN_BUFFER_LENGTH ) ) != IVAS_ERR_OK ) + { + return error; + } + + initRendInputBase_fx( &inputSplitPostRend->base, inConfig, id, rendCtx, inputSplitPostRend->bufferData_fx, MAX_CLDFB_BIN_BUFFER_LENGTH ); + + inputSplitPostRend->numCachedSamples = 0; + + if ( ( error = updateSplitPostRendPanGains( inputSplitPostRend, outConfig, hRendCfg +#ifndef ISAR_BITSTREAM_UPDATE_LC3PLUS + , + num_subframes +#endif + ) ) != IVAS_ERR_OK ) + { + return error; + } + + return IVAS_ERR_OK; +} + +static void clearInputSplitRend( + input_split_post_rend *inputSplitRend ) +{ + rendering_context rendCtx; + + rendCtx = inputSplitRend->base.ctx; + + freeInputBaseBufferData_fx( &inputSplitRend->bufferData_fx ); + + initRendInputBase_fx( &inputSplitRend->base, IVAS_AUDIO_CONFIG_INVALID, 0, rendCtx, NULL, 0 ); + + IF( inputSplitRend->splitPostRendWrapper.hBinHrSplitPostRend != NULL ) + { + isar_splitBinPostRendClose( &inputSplitRend->splitPostRendWrapper.hBinHrSplitPostRend ); + } + + IF( inputSplitRend->splitPostRendWrapper.hSplitBinLCLDDec != NULL ) + { + isar_splitBinLCLDDecClose( &inputSplitRend->splitPostRendWrapper.hSplitBinLCLDDec ); + } + + IF( inputSplitRend->splitPostRendWrapper.hLc3plusDec != NULL ) + { + ISAR_LC3PLUS_DEC_Close( &inputSplitRend->splitPostRendWrapper.hLc3plusDec ); + } + + return; +} + + +/*------------------------------------------------------------------------- + * ISAR_POST_REND_open() + * + * + *------------------------------------------------------------------------*/ +ivas_error ISAR_POST_REND_open( + ISAR_POST_REND_HANDLE *phIvasRend, /* i/o: Pointer to renderer handle */ + const Word32 outputSampleRate, /* i : output sampling rate */ + const AUDIO_CONFIG outConfig, /* i : output audio config */ + const bool asHrtfBinary, /* i : load hrtf binary file */ + const Word16 nonDiegeticPan, /* i : non-diegetic object flag */ + const Word32 nonDiegeticPanGain, /* i : non-diegetic panning gain */ + const Word16 num_subframes ) /* i : number of subframes */ +{ + Word16 i; + ISAR_POST_REND_HANDLE hIvasRend; + ivas_error error; + Word16 numOutChannels; + + (void) asHrtfBinary; + (void) nonDiegeticPan; + (void) nonDiegeticPanGain; + + /* Validate function arguments */ + IF( phIvasRend == NULL ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } + + IF( ( error = validateOutputSampleRate( outputSampleRate, outConfig ) ) != IVAS_ERR_OK ) + { + return error; + } + + *phIvasRend = (ISAR_POST_REND_HANDLE) malloc( sizeof( struct ISAR_POST_REND ) ); + IF( *phIvasRend == NULL ) + { + return IVAS_ERR_FAILED_ALLOC; + } + + hIvasRend = *phIvasRend; + hIvasRend->sampleRateOut = outputSampleRate; + hIvasRend->outputConfig = outConfig; + hIvasRend->hLimiter = NULL; + hIvasRend->num_subframes = 1; +#ifdef DEBUGGING + hIvasRend->numClipping = 0; +#endif + hIvasRend->num_subframes = num_subframes; + + /* Initialize limiter */ + IF( ( error = ISAR_POST_REND_NumOutChannels( hIvasRend, &numOutChannels ) ) != IVAS_ERR_OK ) + { + return error; + } + + IF( ( error = initLimiter( &hIvasRend->hLimiter, numOutChannels, outputSampleRate ) ) != IVAS_ERR_OK ) + { + return error; + } + + /* Initialize headrotation data */ + IF( ( error = initHeadRotation( hIvasRend ) ) != IVAS_ERR_OK ) + { + return error; + } + + /* Initialize inputs */ + + FOR( i = 0; i < RENDERER_MAX_BIN_INPUTS; ++i ) + { + initRendInputBase_fx( &hIvasRend->inputsSplitPost[i].base, IVAS_AUDIO_CONFIG_INVALID, 0, getRendCtx( hIvasRend ), NULL, 0 ); + + isar_init_split_post_rend_handles( &hIvasRend->inputsSplitPost[i].splitPostRendWrapper ); + + hIvasRend->splitRendBFI = 0; + hIvasRend->inputsSplitPost[i].bufferData_fx = NULL; + } + + return IVAS_ERR_OK; +} + +/*-------------------------------------------------------------------* + * ISAR_POST_REND_NumOutChannels() + * + * + *-------------------------------------------------------------------*/ +ivas_error ISAR_POST_REND_NumOutChannels( + ISAR_POST_REND_CONST_HANDLE hIvasRend, /* i : Renderer handle */ + Word16 *numOutChannels /* o : number of output channels */ +) +{ + /* Validate function arguments */ + IF( hIvasRend == NULL || numOutChannels == NULL ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } + + *numOutChannels = 2; + + return IVAS_ERR_OK; +} + +static IVAS_REND_InputId makeInputId( + AUDIO_CONFIG config, + const Word32 inputIndex ) +{ + /* Put config type in second byte (from LSB), put index + 1 in first byte + * + * Index is incremented here so that a valid ID can never be 0. */ + return (IVAS_REND_InputId) ( ( ( (UWord32) isar_getAudioConfigType( config ) ) << 8 ) | ( inputIndex + 1 ) ); +} + +static ivas_error getInputById( + ISAR_POST_REND_HANDLE hIvasRend, + const IVAS_REND_InputId inputId, + void **ppInput ) +{ + Word32 inputIndex; + IVAS_REND_AudioConfigType configType; + input_base *pInputBase; + + /* Reverse makeInputId() */ + inputIndex = ( inputId & 0xFF ) - 1; + configType = ( inputId & 0xFF00 ) >> 8; + + /* Validate values derived from input ID */ + IF( inputIndex < 0 ) + { + return IVAS_ERR_INVALID_INPUT_ID; + } + SWITCH( configType ) + { + case ISAR_POST_REND_AUDIO_CONFIG_TYPE_BINAURAL: + if ( inputIndex > RENDERER_MAX_BIN_INPUTS ) + { + return IVAS_ERR_INVALID_INPUT_ID; + } + pInputBase = &hIvasRend->inputsSplitPost[inputIndex].base; + BREAK; + default: + return IVAS_ERR_INVALID_INPUT_ID; + } + + /* Ensure input ID matches and that input is active */ + IF( pInputBase->id != inputId || pInputBase->inConfig == IVAS_AUDIO_CONFIG_INVALID ) + { + return IVAS_ERR_INVALID_INPUT_ID; + } + + /* Validation done, set value via output parameter */ + *ppInput = pInputBase; + + return IVAS_ERR_OK; +} + +/*-------------------------------------------------------------------* + * ISAR_POST_REND_SetInputGain() + * + * + *-------------------------------------------------------------------*/ +ivas_error ISAR_POST_REND_SetInputGain( + ISAR_POST_REND_HANDLE hIvasRend, /* i/o: Renderer handle */ + const ISAR_POST_REND_InputId inputId, /* i : ID of the input */ + const Word32 gain /* i : linear gain (not in dB) */ +) +{ + input_base *inputBase; + ivas_error error; + + /* Validate function arguments */ + IF( hIvasRend == NULL ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } + + IF( ( error = getInputById( hIvasRend, inputId, (void **) &inputBase ) ) != IVAS_ERR_OK ) + { + printf( "Hoo\n" ); + return error; + } + + inputBase->gain_fx = gain; + + return IVAS_ERR_OK; +} + +static ivas_error getConstInputById( + ISAR_POST_REND_CONST_HANDLE hIvasRend, + const ISAR_POST_REND_InputId inputId, + const void **ppInput ) +{ + Word32 inputIndex; + IVAS_REND_AudioConfigType configType; + const input_base *pInputBase; + + /* Reverse makeInputId() */ + inputIndex = ( inputId & 0xFF ) - 1; + configType = ( inputId & 0xFF00 ) >> 8; + + /* Validate values derived from input ID */ + IF( inputIndex < 0 ) + { + return IVAS_ERR_INVALID_INPUT_ID; + } + SWITCH( configType ) + { + case ISAR_POST_REND_AUDIO_CONFIG_TYPE_BINAURAL: + IF( inputIndex > RENDERER_MAX_BIN_INPUTS ) + { + return IVAS_ERR_INVALID_INPUT_ID; + } + pInputBase = &hIvasRend->inputsSplitPost[inputIndex].base; + BREAK; + default: + return IVAS_ERR_INVALID_INPUT_ID; + } + + /* Ensure input ID matches and that input is active */ + IF( pInputBase->id != inputId || pInputBase->inConfig == IVAS_AUDIO_CONFIG_INVALID ) + { + return IVAS_ERR_INVALID_INPUT_ID; + } + + /* Validation done, set value via output parameter */ + *ppInput = pInputBase; + + return IVAS_ERR_OK; +} + +static ivas_error findFreeInputSlot( + const void *inputs, + const Word32 inputStructSize, + const Word32 maxInputs, + Word32 *inputIndex ) +{ + /* Using a void pointer and a separately provided size is a hack for this function + to be reusable for arrays of any input type (input_ism, input_mc, input_sba, input_masa). + Assumptions: + - input_base is always the first member in the input struct + - provided size is correct + */ + + Word32 i; + bool canAddInput; + const UWord8 *pByte; + const input_base *pInputBase; + + canAddInput = false; + pByte = inputs; + /* Find first unused input in array */ + FOR( i = 0; i < maxInputs; ++i ) + { + pInputBase = (const input_base *) pByte; + + IF( pInputBase->inConfig == IVAS_AUDIO_CONFIG_INVALID ) + { + *inputIndex = i; + canAddInput = true; + BREAK; + } + pByte += inputStructSize; + } + + IF( !canAddInput ) + { + return IVAS_ERR_TOO_MANY_INPUTS; + } + + return IVAS_ERR_OK; +} + +/*-------------------------------------------------------------------* + * ISAR_POST_REND_AddInput() + * + * + *-------------------------------------------------------------------*/ + +ivas_error ISAR_POST_REND_AddInput( + ISAR_POST_REND_HANDLE hIvasRend, /* i/o: Renderer handle */ + const IVAS_AUDIO_CONFIG inConfig, /* i : audio config for a new input */ + ISAR_POST_REND_InputId *inputId /* o : ID of the new input */ +) +{ + ivas_error error; + Word32 maxNumInputsOfType; + void *inputsArray; + Word32 inputStructSize; + ivas_error ( *activateInput )( void *, AUDIO_CONFIG, IVAS_REND_InputId, ISAR_SPLIT_REND_CONFIG_DATA * +#ifndef ISAR_BITSTREAM_UPDATE_LC3PLUS + , + int16_t +#endif + ); + Word32 inputIndex; + + /* Validate function arguments */ + IF( hIvasRend == NULL || inputId == NULL ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } + + SWITCH( isar_getAudioConfigType( inConfig ) ) + { + case ISAR_POST_REND_AUDIO_CONFIG_TYPE_BINAURAL: + maxNumInputsOfType = RENDERER_MAX_BIN_INPUTS; + inputsArray = hIvasRend->inputsSplitPost; + inputStructSize = sizeof( *hIvasRend->inputsSplitPost ); + activateInput = setRendInputActiveSplitPostRend; + BREAK; + default: + return IVAS_ERR_INVALID_INPUT_FORMAT; + } + + /* Find first free input in array corresponding to input type */ + IF( ( error = findFreeInputSlot( inputsArray, inputStructSize, maxNumInputsOfType, &inputIndex ) ) != IVAS_ERR_OK ) + { + return error; + } + + *inputId = makeInputId( inConfig, inputIndex ); + if ( ( error = activateInput( (uint8_t *) inputsArray + inputStructSize * inputIndex, inConfig, *inputId, &hIvasRend->splitRenderConfig +#ifndef ISAR_BITSTREAM_UPDATE_LC3PLUS + , + hIvasRend->num_subframes +#endif + ) ) != IVAS_ERR_OK ) + { + return error; + } + + return IVAS_ERR_OK; +} + +/*-------------------------------------------------------------------* + * ISAR_POST_REND_GetInputNumChannels() + * + * + *-------------------------------------------------------------------*/ + +ivas_error ISAR_POST_REND_GetInputNumChannels( + ISAR_POST_REND_CONST_HANDLE hIvasRend, /* i : Renderer handle */ + const ISAR_POST_REND_InputId inputId, /* i : ID of the input */ + Word16 *numChannels /* o : number of channels of the input */ +) +{ + ivas_error error; + const input_base *pInput; + + /* Validate function arguments */ + IF( hIvasRend == NULL || numChannels == NULL ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } + + IF( ( error = getConstInputById( hIvasRend, inputId, (const void **) &pInput ) ) != IVAS_ERR_OK ) + { + return error; + } + + IF( ( error = getRendInputNumChannels( pInput, numChannels ) ) != IVAS_ERR_OK ) + { + return error; + } + + return IVAS_ERR_OK; +} + +/*-------------------------------------------------------------------* + * ISAR_POST_REND_GetDelay() + * + * + *-------------------------------------------------------------------*/ + +ivas_error ISAR_POST_REND_GetDelay( + ISAR_POST_REND_CONST_HANDLE hIvasRend, /* i : Renderer state */ + Word16 *nSamples, /* o : Renderer delay in samples */ + Word32 *timeScale /* o : Time scale of the delay, equal to renderer output sampling rate */ +) +{ + Word16 i; + Word32 latency_ns; + Word32 max_latency_ns; + + /* Validate function arguments */ + IF( hIvasRend == NULL || nSamples == NULL || timeScale == NULL ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } + + *timeScale = hIvasRend->sampleRateOut; + *nSamples = 0; + max_latency_ns = 0; + + /* Compute the maximum delay across all inputs */ + FOR( i = 0; i < RENDERER_MAX_BIN_INPUTS; i++ ){ + IF( hIvasRend->inputsSplitPost[i].base.inConfig != IVAS_AUDIO_CONFIG_INVALID ){ + latency_ns = 0; + IF( hIvasRend->inputsSplitPost[i].splitPostRendWrapper.hLc3plusDec != NULL ) + { + int32_t lc3plusDelaySamples; + ISAR_LC3PLUS_DEC_GetDelay( hIvasRend->inputsSplitPost[i].splitPostRendWrapper.hLc3plusDec, &lc3plusDelaySamples ); + latency_ns = (Word32) ( ( ( (Word64) lc3plusDelaySamples * 1000000000 ) + ( *timeScale / 2 ) ) / *timeScale ); + } + IF( hIvasRend->inputsSplitPost[i].splitPostRendWrapper.multiBinPoseData.poseCorrectionMode == ISAR_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB ) + { + latency_ns += IVAS_FB_DEC_DELAY_NS; + } + ELSE IF( hIvasRend->inputsSplitPost[i].splitPostRendWrapper.hSplitBinLCLDDec != NULL ) + { + latency_ns += IVAS_FB_DEC_DELAY_NS; + } + max_latency_ns = max( max_latency_ns, latency_ns ); +} +} + +*nSamples = (Word16) ( ( ( (Word64) max_latency_ns * *timeScale ) + 500000000 ) / 1000000000 ); + +return IVAS_ERR_OK; +} + +/*-------------------------------------------------------------------* + * ISAR_POST_REND_FeedInputAudio() + * + * + *-------------------------------------------------------------------*/ +ivas_error ISAR_POST_REND_FeedInputAudio( + ISAR_POST_REND_HANDLE hIvasRend, /* i/o: Renderer handle */ + const ISAR_POST_REND_InputId inputId, /* i : ID of the input */ + const ISAR_POST_REND_ReadOnlyAudioBuffer inputAudio /* i : buffer with input audio */ +) +{ + ivas_error error; + input_base *inputBase; + Word16 numInputChannels; + Word16 cldfb2tdSampleFact; + + /* Validate function arguments */ + IF( hIvasRend == NULL || inputAudio.data_fx == NULL ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } + + cldfb2tdSampleFact = ( inputAudio.config.is_cldfb ) ? 2 : 1; + + IF( LE_16( inputAudio.config.numSamplesPerChannel, 0 ) || ( LT_16( MAX_BUFFER_LENGTH_PER_CHANNEL, inputAudio.config.numSamplesPerChannel ) && EQ_16( inputAudio.config.is_cldfb, 0 ) ) || + ( LT_16( DEPR_i_mult( MAX_BUFFER_LENGTH_PER_CHANNEL, cldfb2tdSampleFact ), inputAudio.config.numSamplesPerChannel ) && EQ_16( inputAudio.config.is_cldfb, 1 ) ) ) + { + return IVAS_ERROR( IVAS_ERR_INVALID_BUFFER_SIZE, "Buffer size outside of supported range" ); + } + + IF( LE_16( inputAudio.config.numChannels, 0 ) || LT_16( MAX_INPUT_CHANNELS, inputAudio.config.numChannels ) ) + { + return IVAS_ERR_WRONG_NUM_CHANNELS; + } + + IF( isar_getAudioConfigType( hIvasRend->outputConfig ) == ISAR_POST_REND_AUDIO_CONFIG_TYPE_BINAURAL && + hIvasRend->outputConfig != IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED && + hIvasRend->outputConfig != IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM && + ( inputAudio.config.numSamplesPerChannel * 1000 / cldfb2tdSampleFact ) != ( BINAURAL_RENDERING_FRAME_SIZE_MS * hIvasRend->num_subframes ) * hIvasRend->sampleRateOut ) + { + return IVAS_ERROR( IVAS_ERR_INVALID_BUFFER_SIZE, "Binaural rendering requires specific frame size" ); + } + + IF( ( error = getInputById( hIvasRend, inputId, (void **) &inputBase ) ) != IVAS_ERR_OK ) + { + printf( "Foo\n" ); + return error; + } + + IF( ( error = getRendInputNumChannels( inputBase, &numInputChannels ) ) != IVAS_ERR_OK ) + { + return error; + } + + IF( numInputChannels != inputAudio.config.numChannels ) + { + return IVAS_ERR_WRONG_NUM_CHANNELS; + } + + inputBase->inputBuffer.config = inputAudio.config; + + mvl2l( inputAudio.data_fx, inputBase->inputBuffer.data_fx, inputAudio.config.numSamplesPerChannel * inputAudio.config.numChannels ); + + inputBase->numNewSamplesPerChannel = inputAudio.config.numSamplesPerChannel / cldfb2tdSampleFact; + + return IVAS_ERR_OK; +} + +/*-------------------------------------------------------------------* + * ISAR_POST_REND_InitConfig() + * + * + *-------------------------------------------------------------------*/ +ivas_error ISAR_POST_REND_InitConfig( + ISAR_POST_REND_HANDLE hIvasRend, /* i/o: Renderer handle */ + const AUDIO_CONFIG outAudioConfig /* i : output audioConfig */ +) +{ + bool rendererConfigEnabled; + + rendererConfigEnabled = ( isar_getAudioConfigType( outAudioConfig ) == ISAR_POST_REND_AUDIO_CONFIG_TYPE_BINAURAL ); + + IF( rendererConfigEnabled ) + { + hIvasRend->rendererConfigEnabled = 1; + } + ELSE + { + hIvasRend->rendererConfigEnabled = 0; + } + + IF( rendererConfigEnabled ) + { + hIvasRend->splitRenderConfig.splitRendBitRate = SPLIT_REND_768k; + hIvasRend->splitRenderConfig.dof = 3; + hIvasRend->splitRenderConfig.hq_mode = 0; + hIvasRend->splitRenderConfig.codec_delay_ms = 0; + hIvasRend->splitRenderConfig.codec_frame_size_ms = 0; /* 0 means "use default for selected codec" */ +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + hIvasRend->splitRenderConfig.isar_frame_size_ms = 0; /* 0 means "use default for selected codec" */ +#endif + hIvasRend->splitRenderConfig.codec = ISAR_SPLIT_REND_CODEC_DEFAULT; + hIvasRend->splitRenderConfig.poseCorrectionMode = ISAR_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB; + hIvasRend->splitRenderConfig.rendererSelection = ISAR_SPLIT_REND_RENDERER_SELECTION_DEFAULT; + } + + return IVAS_ERR_OK; +} + +/*-------------------------------------------------------------------* + * ISAR_POST_REND_GetRenderConfig() + * + * + *-------------------------------------------------------------------*/ +Word16 ISAR_POST_REND_GetRenderConfig( + ISAR_POST_REND_HANDLE hIvasRend, /* i/o: IVAS decoder handle */ + const ISAR_SPLIT_REND_CONFIG_HANDLE splitRenderConfig /* o : Render configuration handle */ +) +{ + ISAR_SPLIT_REND_CONFIG_DATA hRCin; + + IF( hIvasRend == NULL ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } + + hRCin = hIvasRend->splitRenderConfig; + + splitRenderConfig->splitRendBitRate = SPLIT_REND_768k; + splitRenderConfig->dof = 3; + splitRenderConfig->hq_mode = 0; + splitRenderConfig->codec_delay_ms = 0; + splitRenderConfig->codec_frame_size_ms = 0; /* 0 means "use default for selected codec" */ +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + splitRenderConfig->isar_frame_size_ms = 0; /* 0 means "use default for selected codec" */ +#endif + splitRenderConfig->codec = ISAR_SPLIT_REND_CODEC_DEFAULT; + splitRenderConfig->poseCorrectionMode = ISAR_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB; + splitRenderConfig->rendererSelection = hRCin.rendererSelection; + + return IVAS_ERR_OK; +} +/*-------------------------------------------------------------------* + * ISAR_POST_REND_FeedSplitBinauralBitstream() + * + * + *-------------------------------------------------------------------*/ +ivas_error ISAR_POST_REND_FeedSplitBinauralBitstream( + ISAR_POST_REND_HANDLE hIvasRend, /* i/o: Renderer handle */ + const IVAS_REND_InputId inputId, /* i : ID of the input */ + ISAR_POST_REND_BitstreamBuffer *hBits /* i : buffer for input bitstream */ +) +{ + ivas_error error; + input_base *inputBase; + input_split_post_rend *inputSplitPostRend; + + /* Validate function arguments */ + IF( hIvasRend == NULL || hBits == NULL ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } + + IF( ( error = getInputById( hIvasRend, inputId, (void **) &inputBase ) ) != IVAS_ERR_OK ) + { + printf( "Goo\n" ); + return error; + } + + inputSplitPostRend = (input_split_post_rend *) inputBase; + inputSplitPostRend->hBits = hBits; + + return IVAS_ERR_OK; +} + +/*-------------------------------------------------------------------* + * ISAR_POST_REND_SetHeadRotation() + * + * + *-------------------------------------------------------------------*/ + +ivas_error ISAR_POST_REND_SetHeadRotation( + ISAR_POST_REND_HANDLE hIvasRend, /* i/o: Renderer handle */ + const IVAS_QUATERNION headRot, /* i : head orientations for next rendering call */ + const IVAS_VECTOR3 Pos, /* i : listener positions for next rendering call */ + const ISAR_SPLIT_REND_ROT_AXIS rot_axis, /* i : external control for rotation axis for split rendering */ + const Word16 sf_idx /* i : subframe index */ +) +{ + IVAS_QUATERNION rotQuat; + + /* Validate function arguments */ + IF( hIvasRend == NULL ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } + + IF( isar_getAudioConfigType( hIvasRend->outputConfig ) != ISAR_POST_REND_AUDIO_CONFIG_TYPE_BINAURAL ) + { + /* Head rotation can be set only with binaural output */ + return IVAS_ERR_INVALID_OUTPUT_FORMAT; + } + + hIvasRend->headRotData.headRotEnabled = 1; + + /* check for Euler angle signaling */ + IF( EQ_32( headRot.w_fx, -12582912 ) && EQ_32( headRot.q_fact, Q22 ) ) + { + Euler2Quat_fx( deg2rad_fx( headRot.x_fx ), deg2rad_fx( headRot.y_fx ), deg2rad_fx( headRot.z_fx ), &rotQuat ); + modify_Quat_q_fx( &rotQuat, &rotQuat, Q29 ); + } + ELSE + { + rotQuat = headRot; + } + + hIvasRend->headRotData.headPositions[sf_idx] = rotQuat; + hIvasRend->headRotData.Pos[sf_idx] = Pos; + hIvasRend->headRotData.sr_pose_pred_axis = rot_axis; + + return IVAS_ERR_OK; +} + + +/*-------------------------------------------------------------------* + * ISAR_POST_REND_SetSplitRendBFI() + * + * + *-------------------------------------------------------------------*/ + +ivas_error ISAR_POST_REND_SetSplitRendBFI( + ISAR_POST_REND_HANDLE hIvasRend, /* i/o: Renderer handle */ + const Word16 bfi /* i: BFI flag */ +) +{ + hIvasRend->splitRendBFI = bfi; + + return IVAS_ERR_OK; +} + + +/*-------------------------------------------------------------------* + * Local functions + *-------------------------------------------------------------------*/ + +static ivas_error splitBinLc3plusDecode( + ISAR_SPLIT_POST_REND_WRAPPER *hSplitBin, + ISAR_SPLIT_REND_BITS_HANDLE bits, + Word32 outputBuffer[BINAURAL_CHANNELS][L_FRAME48k], +#ifndef ISAR_BITSTREAM_UPDATE_LC3PLUS + ISAR_SPLIT_REND_POSE_CORRECTION_MODE pose_correction, +#endif + const int16_t SplitRendBFI ) +{ + ivas_error error; + Word32 *channel_ptrs[MAX_HEAD_ROT_POSES * 2]; +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + Word32 lc3plusBitstreamSize; +#else + Word32 lc3plusBitrateId, lc3plusBitstreamSize; +#endif + + push_wmops( "splitBinLc3plusDecode" ); + assert( hSplitBin->hLc3plusDec != NULL ); + + for ( Word16 i = 0; i < BINAURAL_CHANNELS * hSplitBin->multiBinPoseData.num_poses; ++i ) + { + channel_ptrs[i] = outputBuffer[i]; + } + + if ( SplitRendBFI == 0 ) + { + /* Find next byte boundary */ + while ( bits->bits_read % 8 != 0 ) + { + ++bits->bits_read; + } +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + /* Size is in bytes */ + assert( ( bits->bits_written - bits->bits_read ) % 8 == 0 ); + lc3plusBitstreamSize = ( bits->bits_written - bits->bits_read ) / 8; +#else + /* Read LC3plus bitstream size info */ + lc3plusBitrateId = ISAR_SPLIT_REND_BITStream_read_int32( bits, 8 ); + lc3plusBitstreamSize = isar_get_lc3plus_size_from_id( (Word8) lc3plusBitrateId, pose_correction, (Word16) ( hSplitBin->hLc3plusDec->config.ivas_frame_duration_us / 1000 ) ); +#endif + + if ( ( error = ISAR_LC3PLUS_DEC_Decode( hSplitBin->hLc3plusDec, &bits->bits_buf[bits->bits_read / 8], lc3plusBitstreamSize, channel_ptrs ) ) != IVAS_ERR_OK ) + { + return error; + } + } + else + { + if ( ( error = ISAR_LC3PLUS_DEC_Conceal( hSplitBin->hLc3plusDec, channel_ptrs ) ) != IVAS_ERR_OK ) + { + return error; + } + } + + pop_wmops(); + return IVAS_ERR_OK; +} + +static ivas_error renderSplitBinauralWithPostRot( + input_split_post_rend *splitBinInput, + IVAS_REND_AudioBuffer outAudio, + const Word16 SplitRendBFI, + const Word16 num_subframes ) +{ + Word32 Cldfb_RealBuffer_Binaural_fx[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX]; + Word32 Cldfb_ImagBuffer_Binaural_fx[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX]; + ivas_error error; + Word32 Cldfb_RealBuffer_Binaural_5ms_fx[MAX_PARAM_SPATIAL_SUBFRAMES][BINAURAL_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX] = { 0 }; + Word32 Cldfb_ImagBuffer_Binaural_5ms_fx[MAX_PARAM_SPATIAL_SUBFRAMES][BINAURAL_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX] = { 0 }; + + IVAS_QUATERNION QuaternionsPost[MAX_PARAM_SPATIAL_SUBFRAMES]; + int16_t sf_idx, ch_idx; + ISAR_SPLIT_REND_BITS_DATA bits; + Word32 tmpCrendBuffer_fx[BINAURAL_CHANNELS][L_FRAME48k] = { 0 }; + Word32 tmpCrendBuffer_sf_fx[BINAURAL_CHANNELS][L_FRAME48k] = { 0 }; + + ISAR_SPLIT_POST_REND_WRAPPER *hSplitBin; + Word8 isPostRendInputCldfb; + Word16 chnlIdx, slotIdx, smplIdx; + Word16 preRendFrameSize_ms; + Word16 outBufNumSamplesPerChannel, outBufNumColPerChannel; + Word16 numSamplesPerChannelCacheSize, numColPerChannelCacheSize; + + Word32 *readPtr_fx, *writePtr_fx; + Word16 Q_cldfb_final[MAX_PARAM_SPATIAL_SUBFRAMES] = { 0 }; + Word16 Q_out[MAX_PARAM_SPATIAL_SUBFRAMES][BINAURAL_CHANNELS] = { 0 }; + +#ifndef ISAR_BITSTREAM_UPDATE_LC3PLUS + uint32_t ivas_frame_duration_us; +#endif + Word16 iNumBlocksPerFrame, iNumLCLDIterationsPerFrame; + const ISAR_POST_REND_HeadRotData *pHeadRotData; + + isPostRendInputCldfb = 0; + push_wmops( "renderSplitBinauralWithPostRot" ); + error = IVAS_ERR_OK; + +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + if ( outAudio.config.numSamplesPerChannel / *splitBinInput->base.ctx.pOutSampleRate > splitBinInput->hBits->config.isar_frame_size_ms ) + { + return IVAS_ERR_INTERNAL_FATAL; + } +#endif + + pHeadRotData = splitBinInput->base.ctx.pHeadRotData; + hSplitBin = &splitBinInput->splitPostRendWrapper; + convertBitsBufferToInternalBitsBuff( *splitBinInput->hBits, &bits ); + +#ifndef ISAR_BITSTREAM_UPDATE_LC3PLUS + ivas_frame_duration_us = 20000; + if ( splitBinInput->splitPostRendWrapper.hLc3plusDec != NULL ) + { + ivas_frame_duration_us = splitBinInput->splitPostRendWrapper.hLc3plusDec->config.isar_frame_duration_us; + } +#endif + + iNumLCLDIterationsPerFrame = 1; + iNumBlocksPerFrame = CLDFB_NO_COL_MAX; + IF( splitBinInput->splitPostRendWrapper.hSplitBinLCLDDec != NULL ) + { + iNumBlocksPerFrame = splitBinInput->splitPostRendWrapper.hSplitBinLCLDDec->iNumBlocks; + iNumLCLDIterationsPerFrame = splitBinInput->splitPostRendWrapper.hSplitBinLCLDDec->iNumIterations; + } + + outBufNumSamplesPerChannel = outAudio.config.numSamplesPerChannel / num_subframes; + FOR( sf_idx = 0; sf_idx < num_subframes; sf_idx++ ) + { + QuaternionsPost[sf_idx] = pHeadRotData->headPositions[sf_idx]; + } + + IF( !SplitRendBFI ) + { + hSplitBin->first_good_frame_received = 1; + } + + IF( EQ_16( hSplitBin->first_good_frame_received, 1 ) ) + { + IF( bits.pose_correction == ISAR_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB ) + { + IF( !SplitRendBFI ) + { +#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG + isar_splitBinPostRendMdDec_fx( &bits, hSplitBin->hBinHrSplitPostRend, &hSplitBin->multiBinPoseData, hSplitBin->hBinHrSplitPreRend ); +#else + isar_splitBinPostRendMdDec_fx( &bits, hSplitBin->hBinHrSplitPostRend, &hSplitBin->multiBinPoseData ); +#endif + } + } + + /*copy pose correction after MD is parsed*/ + hSplitBin->multiBinPoseData.poseCorrectionMode = bits.pose_correction; + + /* decode audio */ + IF( splitBinInput->base.inConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) + { + IF( bits.codec == ISAR_SPLIT_REND_CODEC_LCLD ) + { + isPostRendInputCldfb = 1; + } +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + numSamplesPerChannelCacheSize = (int16_t) ( *splitBinInput->base.ctx.pOutSampleRate * bits.isar_frame_size_ms / 1000 ) - outBufNumSamplesPerChannel; +#else + preRendFrameSize_ms = (int16_t) ( ivas_frame_duration_us ) / 1000; + + numSamplesPerChannelCacheSize = (int16_t) ( *splitBinInput->base.ctx.pOutSampleRate * ( preRendFrameSize_ms - bits.codec_frame_size_ms ) / 1000 ); +#endif + + outBufNumColPerChannel = MAX_PARAM_SPATIAL_SUBFRAMES; + numColPerChannelCacheSize = sub( DEPR_i_mult( iNumBlocksPerFrame, iNumLCLDIterationsPerFrame ), outBufNumColPerChannel ); + + FOR( sf_idx = 0; sf_idx < num_subframes; sf_idx++ ) + { + IF( splitBinInput->numCachedSamples == 0 ) + { + IF( bits.codec == ISAR_SPLIT_REND_CODEC_LCLD ) + { + isar_splitBinLCLDDecProcess( hSplitBin->hSplitBinLCLDDec, &bits, Cldfb_RealBuffer_Binaural_fx, Cldfb_ImagBuffer_Binaural_fx, &Q_cldfb_final[sf_idx], SplitRendBFI ); // Q_cldfb_final + + hSplitBin->Q_last = Q_cldfb_final[sf_idx]; + /* copy data over to 5ms buffer */ + FOR( chnlIdx = 0; chnlIdx < BINAURAL_CHANNELS; ++chnlIdx ) + { + FOR( slotIdx = 0; slotIdx < 4 /*CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES*/; ++slotIdx ) + { + mvl2l( Cldfb_RealBuffer_Binaural_fx[chnlIdx][slotIdx], Cldfb_RealBuffer_Binaural_5ms_fx[sf_idx][chnlIdx][slotIdx], CLDFB_NO_CHANNELS_MAX ); + mvl2l( Cldfb_ImagBuffer_Binaural_fx[chnlIdx][slotIdx], Cldfb_ImagBuffer_Binaural_5ms_fx[sf_idx][chnlIdx][slotIdx], CLDFB_NO_CHANNELS_MAX ); + } + } + + /* cache the remaining 15ms */ + splitBinInput->numCachedSamples = numColPerChannelCacheSize; + writePtr_fx = splitBinInput->bufferData_fx; + FOR( slotIdx = 4 /*CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES*/; slotIdx < DEPR_i_mult( iNumBlocksPerFrame, iNumLCLDIterationsPerFrame ); ++slotIdx ) + { + FOR( chnlIdx = 0; chnlIdx < BINAURAL_CHANNELS; ++chnlIdx ) + { + FOR( smplIdx = 0; smplIdx < CLDFB_NO_CHANNELS_MAX; ++smplIdx ) + { + *writePtr_fx++ = Cldfb_RealBuffer_Binaural_fx[chnlIdx][slotIdx][smplIdx]; + } + FOR( smplIdx = 0; smplIdx < CLDFB_NO_CHANNELS_MAX; ++smplIdx ) + { + *writePtr_fx++ = Cldfb_ImagBuffer_Binaural_fx[chnlIdx][slotIdx][smplIdx]; + } + } + } + } + ELSE + { + Q_out[sf_idx][0] = 0; + Q_out[sf_idx][1] = 0; + if ( ( error = splitBinLc3plusDecode( hSplitBin, &bits, tmpCrendBuffer_fx, +#ifndef ISAR_BITSTREAM_UPDATE_LC3PLUS + bits.pose_correction, +#endif + SplitRendBFI ) ) != IVAS_ERR_OK ) // Q0 + { + return error; + } + hSplitBin->Q_last = Q_out[sf_idx][0]; + + /* cache the remaining 15ms */ + splitBinInput->numCachedSamples = numSamplesPerChannelCacheSize; + mvl2l( &tmpCrendBuffer_fx[0][outBufNumSamplesPerChannel], splitBinInput->bufferData_fx, numSamplesPerChannelCacheSize ); + mvl2l( &tmpCrendBuffer_fx[1][outBufNumSamplesPerChannel], splitBinInput->bufferData_fx + numSamplesPerChannelCacheSize, numSamplesPerChannelCacheSize ); + } + } + ELSE + { + /* copy from cache */ + IF( bits.codec == ISAR_SPLIT_REND_CODEC_LCLD ) + { + Word16 readOffset = sub( numColPerChannelCacheSize, splitBinInput->numCachedSamples ); + readPtr_fx = splitBinInput->bufferData_fx; + Q_cldfb_final[sf_idx] = hSplitBin->Q_last; + isPostRendInputCldfb = 1; + + readPtr_fx += 2 * readOffset * CLDFB_NO_CHANNELS_MAX * BINAURAL_CHANNELS; + FOR( slotIdx = 0; slotIdx < 4 /*CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES*/; ++slotIdx ) + { + FOR( chnlIdx = 0; chnlIdx < BINAURAL_CHANNELS; ++chnlIdx ) + { + FOR( smplIdx = 0; smplIdx < CLDFB_NO_CHANNELS_MAX; ++smplIdx ) + { + Cldfb_RealBuffer_Binaural_5ms_fx[sf_idx][chnlIdx][slotIdx][smplIdx] = *readPtr_fx++; + } + FOR( smplIdx = 0; smplIdx < CLDFB_NO_CHANNELS_MAX; ++smplIdx ) + { + Cldfb_ImagBuffer_Binaural_5ms_fx[sf_idx][chnlIdx][slotIdx][smplIdx] = *readPtr_fx++; + } + } + } + + splitBinInput->numCachedSamples -= outBufNumColPerChannel; + } + ELSE + { + Word16 readOffset = numSamplesPerChannelCacheSize - splitBinInput->numCachedSamples; + mvl2l( splitBinInput->bufferData_fx + readOffset, &tmpCrendBuffer_fx[0][sf_idx * outBufNumSamplesPerChannel], outBufNumSamplesPerChannel ); + mvl2l( splitBinInput->bufferData_fx + readOffset + numSamplesPerChannelCacheSize, &tmpCrendBuffer_fx[1][sf_idx * outBufNumSamplesPerChannel], outBufNumSamplesPerChannel ); + Q_out[sf_idx][0] = hSplitBin->Q_last; + Q_out[sf_idx][1] = hSplitBin->Q_last; + splitBinInput->numCachedSamples -= outBufNumSamplesPerChannel; + } + } + } + } + ELSE + { + copyBufferTo2dArray_fx( splitBinInput->base.inputBuffer, tmpCrendBuffer_fx ); + IF( splitBinInput->numCachedSamples == 0 ) + { +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + preRendFrameSize_ms = splitBinInput->base.ctx.pSplitRenderConfig->isar_frame_size_ms; +#else + preRendFrameSize_ms = (int16_t) ( ivas_frame_duration_us ) / 1000; +#endif + numSamplesPerChannelCacheSize = (Word16) ( *splitBinInput->base.ctx.pOutSampleRate * preRendFrameSize_ms / 1000 ); + numSamplesPerChannelCacheSize -= outAudio.config.numSamplesPerChannel; + splitBinInput->numCachedSamples = numSamplesPerChannelCacheSize; + } + ELSE + { + splitBinInput->numCachedSamples -= outAudio.config.numSamplesPerChannel; + } + } + + /* apply pose correction if enabled */ + FOR( sf_idx = 0; sf_idx < num_subframes; sf_idx++ ) + { + IF( bits.pose_correction == ISAR_SPLIT_REND_POSE_CORRECTION_MODE_NONE && isPostRendInputCldfb ) + { + /* 0DOF with LCLD codec requires CLDFB synthesis */ + Word16 slot_idx; + + FOR( ch_idx = 0; ch_idx < BINAURAL_CHANNELS; ch_idx++ ) + { + Word32 *RealBuffer_fx[CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES]; + Word32 *ImagBuffer_fx[CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES]; + Word16 scaleFactor = 31, Q_cldfb; + + FOR( slot_idx = 0; slot_idx < CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES; slot_idx++ ) + { + RealBuffer_fx[slot_idx] = Cldfb_RealBuffer_Binaural_5ms_fx[sf_idx][ch_idx][slot_idx]; + ImagBuffer_fx[slot_idx] = Cldfb_ImagBuffer_Binaural_5ms_fx[sf_idx][ch_idx][slot_idx]; + + scaleFactor = s_min( scaleFactor, s_min( getScaleFactor32( RealBuffer_fx[slot_idx], CLDFB_NO_CHANNELS_MAX ), getScaleFactor32( ImagBuffer_fx[slot_idx], CLDFB_NO_CHANNELS_MAX ) ) ); + } + scaleFactor = sub( scaleFactor, 3 ); // guarded bits + + FOR( slot_idx = 0; slot_idx < CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES; slot_idx++ ) + { + Scale_sig32( RealBuffer_fx[slot_idx], CLDFB_NO_CHANNELS_MAX, scaleFactor ); + Scale_sig32( ImagBuffer_fx[slot_idx], CLDFB_NO_CHANNELS_MAX, scaleFactor ); + } + Q_cldfb = scaleFactor + Q_cldfb_final[sf_idx]; + Scale_sig32( hSplitBin->hBinHrSplitPostRend->cldfbSyn[ch_idx]->cldfb_state_fx, hSplitBin->hBinHrSplitPostRend->cldfbSyn[ch_idx]->p_filter_length, sub( sub( Q_cldfb, 1 ), Q11 ) ); + cldfbSynthesis_ivas_fx( RealBuffer_fx, + ImagBuffer_fx, + &( tmpCrendBuffer_fx[ch_idx][sf_idx * outBufNumSamplesPerChannel] ), + hSplitBin->hBinHrSplitPostRend->cldfbSyn[0]->no_channels * CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES, + hSplitBin->hBinHrSplitPostRend->cldfbSyn[ch_idx] ); // Q_cldfb - 1 + Scale_sig32( hSplitBin->hBinHrSplitPostRend->cldfbSyn[ch_idx]->cldfb_state_fx, hSplitBin->hBinHrSplitPostRend->cldfbSyn[ch_idx]->p_filter_length, sub( Q11, sub( Q_cldfb, 1 ) ) ); + Q_out[sf_idx][ch_idx] = sub( Q_cldfb, 1 ); + } + } + ELSE IF( bits.pose_correction == ISAR_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB ) + { + mvl2l( &tmpCrendBuffer_fx[0][sf_idx * outBufNumSamplesPerChannel], tmpCrendBuffer_sf_fx[0], outBufNumSamplesPerChannel ); + mvl2l( &tmpCrendBuffer_fx[1][sf_idx * outBufNumSamplesPerChannel], tmpCrendBuffer_sf_fx[1], outBufNumSamplesPerChannel ); + + isar_rend_CldfbSplitPostRendProcess( hSplitBin->hBinHrSplitPostRend, &hSplitBin->multiBinPoseData, QuaternionsPost[sf_idx], Cldfb_RealBuffer_Binaural_5ms_fx[sf_idx], Cldfb_ImagBuffer_Binaural_5ms_fx[sf_idx], Q_cldfb_final[sf_idx], tmpCrendBuffer_sf_fx, Q_out[sf_idx], isPostRendInputCldfb ); // Q_out[2] + + mvl2l( tmpCrendBuffer_sf_fx[0], &tmpCrendBuffer_fx[0][sf_idx * outBufNumSamplesPerChannel], outBufNumSamplesPerChannel ); + mvl2l( tmpCrendBuffer_sf_fx[1], &tmpCrendBuffer_fx[1][sf_idx * outBufNumSamplesPerChannel], outBufNumSamplesPerChannel ); + } + } + } + ELSE + { + IF( splitBinInput->base.inConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) + { + FOR( ch_idx = 0; ch_idx < BINAURAL_CHANNELS; ch_idx++ ) + { + set_l( tmpCrendBuffer_fx[ch_idx], 0, outAudio.config.numSamplesPerChannel ); + } + } + ELSE + { + copyBufferTo2dArray_fx( splitBinInput->base.inputBuffer, tmpCrendBuffer_fx ); + } + } + + convertInternalBitsBuffToBitsBuffer( splitBinInput->hBits, bits ); + + Word16 Q_max = 0, Q_temp; + FOR( Word16 i = 0; i < num_subframes; i++ ) + { + maximum_s( Q_out[i], BINAURAL_CHANNELS, &Q_temp ); + Q_max = s_max( Q_max, Q_temp ); + } + Q_max = s_min( Q_max, Q13 ); + accumulate2dArrayToBuffer_fx( tmpCrendBuffer_fx, Q_out, Q_max, &outAudio, num_subframes, outBufNumSamplesPerChannel ); + *outAudio.pq_fact = Q_max; + + pop_wmops(); + return error; +} + +static ivas_error renderInputSplitBin( + input_split_post_rend *splitBinInput, + const AUDIO_CONFIG outConfig, + IVAS_REND_AudioBuffer outAudio, + const Word16 SplitRendBFI, + const Word16 num_subframes ) +{ + ivas_error error; + IVAS_REND_AudioBuffer inAudio; + + inAudio = splitBinInput->base.inputBuffer; + + splitBinInput->base.numNewSamplesPerChannel = 0; + + /* Apply input gain to new audio */ + v_multc_fixed( inAudio.data_fx, + splitBinInput->base.gain_fx, + inAudio.data_fx, + inAudio.config.numSamplesPerChannel * inAudio.config.numChannels ); + + SWITCH( outConfig ) + { + case IVAS_AUDIO_CONFIG_BINAURAL: + error = renderSplitBinauralWithPostRot( splitBinInput, outAudio, SplitRendBFI, num_subframes ); + BREAK; + default: + return IVAS_ERR_INVALID_OUTPUT_FORMAT; + } + + return error; +} + +static ivas_error renderActiveInputsSplitBin( + ISAR_POST_REND_HANDLE hIvasRend, + IVAS_REND_AudioBuffer outAudio ) +{ + int16_t i; + input_split_post_rend *pCurrentInput; + ivas_error error; + pCurrentInput = hIvasRend->inputsSplitPost; + FOR( i = 0; i < RENDERER_MAX_BIN_INPUTS; ++i ) + { + IF( pCurrentInput->base.inConfig == IVAS_AUDIO_CONFIG_INVALID ) + { + /* Skip inactive inputs */ + ++pCurrentInput; + continue; + } + + IF( ( error = renderInputSplitBin( pCurrentInput, hIvasRend->outputConfig, outAudio, hIvasRend->splitRendBFI, hIvasRend->num_subframes ) ) != IVAS_ERR_OK ) + { + return error; + } + ++pCurrentInput; + } + + return IVAS_ERR_OK; +} + +/*-------------------------------------------------------------------* + * ISAR_POST_REND_getSamples() + * + * + *-------------------------------------------------------------------*/ + +ivas_error ISAR_POST_REND_getSamples( + ISAR_POST_REND_HANDLE hIvasRend, /* i/o: Renderer handle */ + IVAS_REND_AudioBuffer outAudio /* i/o: buffer for output audio */ +) +{ + ivas_error error; + Word16 numOutChannels; + Word16 cldfb2tdSampleFact; + + /* Validate function arguments */ + IF( hIvasRend == NULL || outAudio.data_fx == NULL ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } + + cldfb2tdSampleFact = ( outAudio.config.is_cldfb ) ? 2 : 1; + + IF( outAudio.config.numSamplesPerChannel <= 0 || ( MAX_BUFFER_LENGTH_PER_CHANNEL < outAudio.config.numSamplesPerChannel && outAudio.config.is_cldfb == 0 ) || + ( ( MAX_BUFFER_LENGTH_PER_CHANNEL * cldfb2tdSampleFact ) < outAudio.config.numSamplesPerChannel && outAudio.config.is_cldfb == 1 ) ) + { + return IVAS_ERR_INVALID_BUFFER_SIZE; + } + + IF( LT_16( outAudio.config.numChannels, 0 ) || LT_16( MAX_OUTPUT_CHANNELS, outAudio.config.numChannels ) ) + { + return IVAS_ERR_WRONG_NUM_CHANNELS; + } + + IF( isar_getAudioConfigType( hIvasRend->outputConfig ) == ISAR_POST_REND_AUDIO_CONFIG_TYPE_BINAURAL && + ( outAudio.config.numSamplesPerChannel * 1000 / cldfb2tdSampleFact ) != ( hIvasRend->num_subframes * BINAURAL_RENDERING_FRAME_SIZE_MS ) * hIvasRend->sampleRateOut ) + { + return IVAS_ERROR( IVAS_ERR_INVALID_BUFFER_SIZE, "Binaural rendering requires specific frame size" ); + } + + IF( ( error = ISAR_POST_REND_NumOutChannels( hIvasRend, &numOutChannels ) ) != IVAS_ERR_OK ) + { + return error; + } + + IF( numOutChannels != outAudio.config.numChannels && hIvasRend->outputConfig != IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED && hIvasRend->outputConfig != IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) + { + return IVAS_ERR_WRONG_NUM_CHANNELS; + } + + /* Clear original output buffer */ + set_l( outAudio.data_fx, 0, outAudio.config.numChannels * outAudio.config.numSamplesPerChannel ); + + IF( ( error = renderActiveInputsSplitBin( hIvasRend, outAudio ) ) != IVAS_ERR_OK ) + { + return error; + } + +#ifndef DISABLE_LIMITER + Word32 limiter_thresold; +#ifdef DEBUGGING + hIvasRend->numClipping += +#endif + limiter_thresold = L_shl( IVAS_LIMITER_THRESHOLD, *outAudio.pq_fact ); + limitRendererOutput_fx( hIvasRend->hLimiter, outAudio.data_fx, outAudio.config.numSamplesPerChannel, limiter_thresold, *outAudio.pq_fact ); +#endif + + return IVAS_ERR_OK; +} + +/*-------------------------------------------------------------------* + * ISAR_POST_REND_GetSplitBinauralSamples() + * + * + *-------------------------------------------------------------------*/ + +ivas_error ISAR_POST_REND_GetSplitBinauralSamples( + ISAR_POST_REND_HANDLE hIvasRend, /* i/o: Renderer handle */ + IVAS_REND_AudioBuffer outAudio, /* i/o: buffer for output audio */ + bool *needNewFrame ) +{ + ivas_error error; + + IF( ( error = ISAR_POST_REND_getSamples( hIvasRend, outAudio ) ) != IVAS_ERR_OK ) + { + return error; + } + *needNewFrame = hIvasRend->inputsSplitPost[0].numCachedSamples == 0; + + return IVAS_ERR_OK; +} + + +/*-------------------------------------------------------------------* + * ISAR_POST_REND_Close() + * + * + *-------------------------------------------------------------------*/ +void ISAR_POST_REND_Close( + ISAR_POST_REND_HANDLE *phIvasRend /* i/o: Pointer to renderer handle */ +) +{ + UWord16 i; + ISAR_POST_REND_HANDLE hIvasRend; + + /* Validate function arguments */ + IF( phIvasRend == NULL || *phIvasRend == NULL ) + { + return; + } + hIvasRend = *phIvasRend; + + FOR( i = 0; i < RENDERER_MAX_BIN_INPUTS; ++i ) + { + clearInputSplitRend( &hIvasRend->inputsSplitPost[i] ); + } + + ivas_limiter_close_fx( &hIvasRend->hLimiter ); + + free( hIvasRend ); + *phIvasRend = NULL; + + return; +} + + +ivas_error ISAR_REND_SetSplitRendBitstreamHeader( + ISAR_POST_REND_HANDLE hIvasRend, /* i/o: IVAS renderer handle */ + const ISAR_SPLIT_REND_CODEC codec, /* o: codec setting */ + const ISAR_SPLIT_REND_POSE_CORRECTION_MODE poseCorrection, /* o: pose correction mode */ + const int16_t codec_frame_size_ms /* i: codec frame size setting */ +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + , + const int16_t isar_frame_size_ms, /* i: isar codec frame size setting */ + const int16_t lc3plus_highres /* i: LC3plus Hig-Res setting. Ignored if codec is not LC3plus */ +#endif +) +{ + IF( hIvasRend == NULL ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } + hIvasRend->splitRenderConfig.codec = codec; +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + hIvasRend->splitRenderConfig.isar_frame_size_ms = isar_frame_size_ms; +#endif + hIvasRend->splitRenderConfig.codec_frame_size_ms = codec_frame_size_ms; + hIvasRend->splitRenderConfig.poseCorrectionMode = poseCorrection; +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + hIvasRend->splitRenderConfig.lc3plus_highres = lc3plus_highres; +#endif + return IVAS_ERR_OK; +} + +#ifdef DEBUGGING +/*-------------------------------------------------------------------* + * ISAR_POST_REND_GetNoCLipping() + * + * + *-------------------------------------------------------------------*/ + +int32_t ISAR_POST_REND_GetNoCLipping( + ISAR_POST_REND_HANDLE hIvasRend ) +{ + return hIvasRend->numClipping; +} + +int32_t ISAR_POST_REND_GetCntFramesLimited( + ISAR_POST_REND_CONST_HANDLE hIvasRend ) +{ + if ( hIvasRend->hLimiter == NULL ) + { + return 0; + } + + return hIvasRend->hLimiter->cnt_frames_limited; +} +#endif + + +#endif diff --git a/lib_isar/lib_isar_post_rend.h b/lib_isar/lib_isar_post_rend.h new file mode 100644 index 0000000000000000000000000000000000000000..ef437eaa3a314b6808545e3260c9207cdf5c8466 --- /dev/null +++ b/lib_isar/lib_isar_post_rend.h @@ -0,0 +1,225 @@ +/****************************************************************************************************** + + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository. All Rights Reserved. + + This software is protected by copyright law and by international treaties. + The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository retain full ownership rights in their respective contributions in + the software. This notice grants no license of any kind, including but not limited to patent + license, nor is any license granted by implication, estoppel or otherwise. + + Contributors are required to enter into the IVAS codec Public Collaboration agreement before making + contributions. + + This software is provided "AS IS", without any express or implied warranties. The software is in the + development stage. It is intended exclusively for experts who have experience with such software and + solely for the purpose of inspection. All implied warranties of non-infringement, merchantability + and fitness for a particular purpose are hereby disclaimed and excluded. + + Any dispute, controversy or claim arising under or in relation to providing this software shall be + submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in + accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and + the United Nations Convention on Contracts on the International Sales of Goods. + +*******************************************************************************************************/ + +#ifndef LIB_ISAR_POST_REND_H +#define LIB_ISAR_POST_REND_H + +#include "common_api_types.h" +#include + +#ifndef SPLIT_REND_WITH_HEAD_ROT + +int32_t ISAR_POST_REND_void_func( void ); + +#else + +/*---------------------------------------------------------------------* + * Renderer constants + *---------------------------------------------------------------------*/ + +#define RENDERER_MAX_ISAR_MD_INPUTS 1 +#define RENDERER_MAX_BIN_INPUTS 1 + +/*---------------------------------------------------------------------* + * Renderer structures + *---------------------------------------------------------------------*/ + +typedef struct +{ + int32_t bufLenInBytes; + int32_t bitsWritten; + int32_t bitsRead; + ISAR_SPLIT_REND_CODEC codec; + ISAR_SPLIT_REND_POSE_CORRECTION_MODE poseCorrection; + int16_t codec_frame_size_ms; +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + int16_t isar_frame_size_ms; + int16_t lc3plusHighRes; +#endif +} ISAR_POST_REND_BitstreamBufferConfig; + +typedef struct +{ + ISAR_POST_REND_BitstreamBufferConfig config; + uint8_t *bits; +} ISAR_POST_REND_BitstreamBuffer; + +typedef enum +{ + ISAR_POST_REND_AUDIO_CONFIG_TYPE_BINAURAL = 0, + ISAR_POST_REND_AUDIO_CONFIG_TYPE_UNKNOWN, +} ISAR_POST_REND_AudioConfigType; + +typedef struct +{ + IVAS_REND_AudioBufferConfig config; + const Word32 *data_fx; +} ISAR_POST_REND_ReadOnlyAudioBuffer; + +typedef struct ISAR_POST_REND *ISAR_POST_REND_HANDLE; +typedef struct ISAR_POST_REND const *ISAR_POST_REND_CONST_HANDLE; + +typedef uint16_t ISAR_POST_REND_InputId; + +typedef enum _ISAR_POST_REND_COMPLEXITY_LEVEL +{ + ISAR_POST_REND_COMPLEXITY_LEVEL_ONE = 1, + ISAR_POST_REND_COMPLEXITY_LEVEL_TWO = 2, + ISAR_POST_REND_COMPLEXITY_LEVEL_THREE = 3 +} ISAR_POST_REND_COMPLEXITY_LEVEL; + + +/* clang-format off */ +/*----------------------------------------------------------------------------------* + * Renderer function prototypes + *----------------------------------------------------------------------------------*/ + +/* Functions to be called before rendering */ +ivas_error ISAR_POST_REND_open( + ISAR_POST_REND_HANDLE *phIvasRend, /* i/o: Pointer to renderer handle */ + const Word32 outputSampleRate, /* i : output sampling rate */ + const IVAS_AUDIO_CONFIG outConfig, /* i : output audio config */ + const bool asHrtfBinary, /* i : load hrtf binary file */ + const Word16 nonDiegeticPan, /* i : non-diegetic object flag */ + const Word32 nonDiegeticPanGain, /* i : non-diegetic panning gain */ + const Word16 num_subframes /* i : number of subframes */ +); + +/* Functions to be called before/during rendering */ +ivas_error ISAR_POST_REND_NumOutChannels( + ISAR_POST_REND_CONST_HANDLE hIvasRend, /* i : Renderer handle */ + Word16 *numOutChannels /* o : number of output channels */ +); + +ivas_error ISAR_POST_REND_AddInput( + ISAR_POST_REND_HANDLE hIvasRend, /* i/o: Renderer handle */ + const IVAS_AUDIO_CONFIG inConfig, /* i : audio config for a new input */ + ISAR_POST_REND_InputId *inputId /* o : ID of the new input */ +); + +ivas_error ISAR_POST_REND_SetInputGain( + ISAR_POST_REND_HANDLE hIvasRend, /* i/o: Renderer handle */ + const ISAR_POST_REND_InputId inputId, /* i : ID of the input */ + const Word32 gain /* i : linear gain (not in dB) */ +); + +ivas_error ISAR_POST_REND_GetInputNumChannels( + ISAR_POST_REND_CONST_HANDLE hIvasRend, /* i : Renderer handle */ + const ISAR_POST_REND_InputId inputId, /* i : ID of the input */ + Word16 *numChannels /* o : number of channels of the input */ +); +ivas_error ISAR_POST_REND_GetDelay( + ISAR_POST_REND_CONST_HANDLE hIvasRend, /* i : Renderer state */ + Word16 *nSamples, /* o : Renderer delay in samples */ + Word32 *timeScale /* o : Time scale of the delay, equal to renderer output sampling rate */ +); + +/* Functions to be called during rendering */ + +ivas_error ISAR_POST_REND_FeedInputAudio( + ISAR_POST_REND_HANDLE hIvasRend, /* i/o: Renderer handle */ + const ISAR_POST_REND_InputId inputId, /* i : ID of the input */ + const ISAR_POST_REND_ReadOnlyAudioBuffer inputAudio /* i : buffer with input audio */ +); + +ivas_error ISAR_POST_REND_InitConfig( + ISAR_POST_REND_HANDLE hIvasRend, /* i/o: Renderer handle */ + const IVAS_AUDIO_CONFIG outAudioConfig /* i : output audioConfig */ +); +Word16 ISAR_POST_REND_GetRenderConfig( + ISAR_POST_REND_HANDLE hIvasRend, /* i/o: IVAS decoder handle */ + const ISAR_SPLIT_REND_CONFIG_HANDLE splitRenderConfig /* o : Render configuration handle */ +); +ivas_error ISAR_POST_REND_FeedSplitBinauralBitstream( + ISAR_POST_REND_HANDLE hIvasRend, /* i/o: Renderer handle */ + const ISAR_POST_REND_InputId inputId, /* i : ID of the input */ + ISAR_POST_REND_BitstreamBuffer *hBits /* i : buffer for input bitstream */ +); + +ivas_error ISAR_POST_REND_GetSplitBinauralSamples( + ISAR_POST_REND_HANDLE hIvasRend, /* i/o: Renderer handle */ + IVAS_REND_AudioBuffer outAudio, /* i/o: buffer for output audio */ + bool* needNewFrame +); + +ivas_error ISAR_POST_REND_SetHeadRotation( + ISAR_POST_REND_HANDLE hIvasRend, /* i/o: Renderer handle */ + const IVAS_QUATERNION headRot, /* i : head orientations for next rendering call */ + const IVAS_VECTOR3 Pos, /* i : listener positions for next rendering call */ + const ISAR_SPLIT_REND_ROT_AXIS rot_axis, /* i : external control for rotation axis for split rendering */ + const Word16 sf_idx /* i : subframe index */ +); + +ivas_error ISAR_POST_REND_SetSplitRendBFI( + ISAR_POST_REND_HANDLE hIvasRend, /* i/o: Renderer handle */ + const Word16 bfi /* i: BFI flag */ +); + +ivas_error ISAR_POST_REND_getSamples( + ISAR_POST_REND_HANDLE hIvasRend, /* i/o: Renderer handle */ + IVAS_REND_AudioBuffer outAudio /* i/o: buffer for output audio */ +); + +/* Functions to be called after rendering */ + +void ISAR_POST_REND_Close( + ISAR_POST_REND_HANDLE* phIvasRend /* i/o: Pointer to renderer handle */ +); + +ivas_error ISAR_REND_SetSplitRendBitstreamHeader( + ISAR_POST_REND_HANDLE hIvasRend, /* i/o: IVAS renderer handle */ + const ISAR_SPLIT_REND_CODEC codec, /* o: codec setting */ + const ISAR_SPLIT_REND_POSE_CORRECTION_MODE poseCorrection, /* o: pose correction mode */ + const int16_t codec_frame_size_ms /* i: codec frame size setting */ +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + , + const int16_t isar_frame_size_ms, /* i: isar frame size setting */ + const int16_t lc3plus_highres /* i: LC3plus Hig-Res setting. Ignored if codec is not LC3plus */ +#endif +); + + +#ifdef DEBUGGING +int32_t ISAR_POST_REND_GetNoCLipping( + ISAR_POST_REND_HANDLE hIvasRend /* i : Renderer handle */ +); + +int32_t ISAR_POST_REND_GetCntFramesLimited( + ISAR_POST_REND_CONST_HANDLE hIvasRend /* i : Renderer handle */ +); +#endif + +#endif /* SPLIT_REND_WITH_HEAD_ROT */ + +/* clang-format on */ + +#endif /* LIB_ISAR_POST_REND_H */ diff --git a/lib_isar/lib_isar_pre_rend.c b/lib_isar/lib_isar_pre_rend.c new file mode 100644 index 0000000000000000000000000000000000000000..49e52ad97f14bb5509d797d18e019f664d89eee4 --- /dev/null +++ b/lib_isar/lib_isar_pre_rend.c @@ -0,0 +1,634 @@ +/****************************************************************************************************** + + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository. All Rights Reserved. + + This software is protected by copyright law and by international treaties. + The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository retain full ownership rights in their respective contributions in + the software. This notice grants no license of any kind, including but not limited to patent + license, nor is any license granted by implication, estoppel or otherwise. + + Contributors are required to enter into the IVAS codec Public Collaboration agreement before making + contributions. + + This software is provided "AS IS", without any express or implied warranties. The software is in the + development stage. It is intended exclusively for experts who have experience with such software and + solely for the purpose of inspection. All implied warranties of non-infringement, merchantability + and fitness for a particular purpose are hereby disclaimed and excluded. + + Any dispute, controversy or claim arising under or in relation to providing this software shall be + submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in + accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and + the United Nations Convention on Contracts on the International Sales of Goods. + +*******************************************************************************************************/ + + +#include +#include "options.h" +#include +#include "ivas_prot_fx.h" +#include "prot_fx.h" +#include "prot_fx.h" +#include "isar_cnst.h" +#include "isar_rom_post_rend.h" +#include "lib_isar_pre_rend.h" +#include "isar_prot.h" +#ifdef DEBUGGING +#include "debug.h" +#endif +#include "wmc_auto.h" + + +#ifndef SPLIT_REND_WITH_HEAD_ROT +int32_t ISAR_PRE_REND_void_func( void ) +{ + return 0; +} + +#else + +/*-------------------------------------------------------------------* + * Local constants + *-------------------------------------------------------------------*/ + +/*-------------------------------------------------------------------* + * Local types + *-------------------------------------------------------------------*/ + +/*-------------------------------------------------------------------* + * Local function prototypes + *-------------------------------------------------------------------*/ + +/*-------------------------------------------------------------------* + * Local functions + *-------------------------------------------------------------------*/ + +/*------------------------------------------------------------------------- + * Function ISAR_PRE_REND_open() + * + * + *------------------------------------------------------------------------*/ + +ivas_error ISAR_PRE_REND_open( + SPLIT_REND_WRAPPER *hSplitRendWrapper, + ISAR_SPLIT_REND_CONFIG_DATA *pSplitRendConfig, + const Word32 OutSampleRate, + const Word16 cldfb_in_flag, + const Word16 pcm_out_flag, +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + const IVAS_RENDER_FRAMESIZE ivas_frame_size, /* i: IVAS frame size */ +#else + const int16_t num_subframes, /* i: number of subframes */ +#endif + const int16_t mixed_td_cldfb_flag ) +{ + ivas_error error, ch, num_ch; + UWord8 isCldfbNeeded = 0; + Word16 cldfb_in_flag_local = cldfb_in_flag; + + if ( ( error = isar_split_rend_choose_default_codec( &( pSplitRendConfig->codec ), +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + &pSplitRendConfig->isar_frame_size_ms, +#endif + &pSplitRendConfig->codec_frame_size_ms, + cldfb_in_flag_local, + pcm_out_flag, (int16_t) +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + ivas_frame_size +#else + num_subframes +#endif + ) ) != IVAS_ERR_OK ) + { + return error; + } + + if ( mixed_td_cldfb_flag ) + { + cldfb_in_flag_local = 0; + } + + IF( ( error = isar_split_rend_validate_config( pSplitRendConfig, pcm_out_flag ) ) != IVAS_ERR_OK ) + { + return error; + } + + IF( EQ_16( cldfb_in_flag_local, 0 ) ) + { + isCldfbNeeded = 1; + } + ELSE IF( EQ_16( pSplitRendConfig->codec, ISAR_SPLIT_REND_CODEC_LC3PLUS ) && cldfb_in_flag_local ) + { + isCldfbNeeded = 1; + } + ELSE IF( pcm_out_flag && cldfb_in_flag_local ) + { + isCldfbNeeded = 1; + } + + hSplitRendWrapper->hCldfbHandles = NULL; + + IF( isCldfbNeeded ) + { + IF( ( hSplitRendWrapper->hCldfbHandles = (CLDFB_HANDLES_WRAPPER_HANDLE) malloc( sizeof( CLDFB_HANDLES_WRAPPER ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for CLDFB handles\n" ) ); + } + num_ch = MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS; + FOR( ch = 0; ch < num_ch; ch++ ) + { + hSplitRendWrapper->hCldfbHandles->cldfbAna[ch] = NULL; + } + + FOR( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) + { + hSplitRendWrapper->hCldfbHandles->cldfbSyn[ch] = NULL; + } + + num_ch = hSplitRendWrapper->multiBinPoseData.num_poses * BINAURAL_CHANNELS; + + FOR( ch = 0; ch < num_ch; ch++ ) + { + if ( ( error = openCldfb_ivas_fx( &( hSplitRendWrapper->hCldfbHandles->cldfbAna[ch] ), + CLDFB_ANALYSIS, + OutSampleRate, CLDFB_PROTOTYPE_5_00MS, DEC ) ) != IVAS_ERR_OK ) + { + return error; + } + } + + FOR( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) + { + IF( ( error = openCldfb_ivas_fx( &( hSplitRendWrapper->hCldfbHandles->cldfbSyn[ch] ), CLDFB_SYNTHESIS, OutSampleRate, CLDFB_PROTOTYPE_5_00MS, DEC ) ) != IVAS_ERR_OK ) + { + return error; + } + } + } + + IF( EQ_16( pSplitRendConfig->poseCorrectionMode, ISAR_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB ) ) + { + if ( ( error = isar_splitBinPreRendOpen( &hSplitRendWrapper->hBinHrSplitPreRend, &hSplitRendWrapper->multiBinPoseData +#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG + , + OutSampleRate +#endif + ) ) != IVAS_ERR_OK ) + { + return error; + } + } + + IF( EQ_16( pcm_out_flag, 0 ) ) + { + IF( EQ_16( pSplitRendConfig->codec, ISAR_SPLIT_REND_CODEC_LC3PLUS ) ) + { + if ( ( error = split_renderer_open_lc3plus( hSplitRendWrapper, pSplitRendConfig, OutSampleRate, +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + ivas_frame_size +#else + num_subframes +#endif + ) ) != IVAS_ERR_OK ) + { + return error; + } + } + ELSE + { + Word16 iNumBlocksPerFrame; + iNumBlocksPerFrame = ( CLDFB_NO_COL_MAX * pSplitRendConfig->codec_frame_size_ms ) / 20; + + IF( ( error = isar_splitBinLCLDEncOpen( &hSplitRendWrapper->hSplitBinLCLDEnc, OutSampleRate, BINAURAL_CHANNELS, isar_get_lcld_bitrate( pSplitRendConfig->splitRendBitRate, hSplitRendWrapper->multiBinPoseData.poseCorrectionMode ), iNumBlocksPerFrame, 1 ) ) != IVAS_ERR_OK ) + { + return error; + } + } + } + + return IVAS_ERR_OK; +} + +/*------------------------------------------------------------------------- + * Function ISAR_PRE_REND_close() + * + * + *------------------------------------------------------------------------*/ +void ISAR_PRE_REND_close( + SPLIT_REND_WRAPPER *hSplitBinRend, /* i/o: Split renderer pre-renerer handle */ + IVAS_REND_AudioBuffer *pSplitRendEncBuffer /* i/o: Split renderer data buffer */ +) +{ + Word16 i; + + IF( hSplitBinRend->hBinHrSplitPreRend != NULL ) + { + isar_splitBinPreRendClose( &hSplitBinRend->hBinHrSplitPreRend ); + } + + IF( hSplitBinRend->hSplitBinLCLDEnc != NULL ) + { + isar_splitBinLCLDEncClose( &hSplitBinRend->hSplitBinLCLDEnc ); + } + + IF( hSplitBinRend->hCldfbHandles != NULL ) + { + Word16 num_ch, ch; + num_ch = MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS; + FOR( ch = 0; ch < num_ch; ch++ ) + { + IF( hSplitBinRend->hCldfbHandles->cldfbAna[ch] != NULL ) + { + deleteCldfb( &hSplitBinRend->hCldfbHandles->cldfbAna[ch] ); + hSplitBinRend->hCldfbHandles->cldfbAna[ch] = NULL; + } + } + +#ifdef SPLIT_REND_WITH_HEAD_ROT + FOR( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) + { + IF( hSplitBinRend->hCldfbHandles->cldfbSyn[ch] != NULL ) + { + deleteCldfb( &hSplitBinRend->hCldfbHandles->cldfbSyn[ch] ); + hSplitBinRend->hCldfbHandles->cldfbSyn[ch] = NULL; + } + } +#endif + + free( hSplitBinRend->hCldfbHandles ); + hSplitBinRend->hCldfbHandles = NULL; + } + + IF( hSplitBinRend->hLc3plusEnc != NULL ) + { + ISAR_LC3PLUS_ENC_Close( &hSplitBinRend->hLc3plusEnc ); + } + + FOR( i = 0; i < MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS; ++i ) + { + if ( hSplitBinRend->lc3plusDelayBuffers_fx[i] != NULL ) + { + free( hSplitBinRend->lc3plusDelayBuffers_fx[i] ); + hSplitBinRend->lc3plusDelayBuffers_fx[i] = NULL; + } + } + + IF( pSplitRendEncBuffer != NULL ) + { + + IF( pSplitRendEncBuffer->data_fx != NULL ) + { + free( pSplitRendEncBuffer->data_fx ); + pSplitRendEncBuffer->data_fx = NULL; + } + + pSplitRendEncBuffer->config.numChannels = 0; + pSplitRendEncBuffer->config.numSamplesPerChannel = 0; + } + + return; +} + + +/*-------------------------------------------------------------------------* + * ISAR_PRE_REND_GetMultiBinPoseData() + * + * + *-------------------------------------------------------------------------*/ + +void ISAR_PRE_REND_GetMultiBinPoseData( + const ISAR_SPLIT_REND_CONFIG_DATA *pSplit_rend_config, /* i: Split renderer pre-renerer config */ + MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, /* i/o: pose correction data handle */ + const ISAR_SPLIT_REND_ROT_AXIS rot_axis /* i: Rotation axis */ +) +{ + isar_renderSplitGetMultiBinPoseData_fx( pSplit_rend_config, pMultiBinPoseData, rot_axis ); +} + +/*------------------------------------------------------------------------- + * Function ISAR_PRE_REND_MultiBinToSplitBinaural() + * + * + *------------------------------------------------------------------------*/ +ivas_error ISAR_PRE_REND_MultiBinToSplitBinaural( + SPLIT_REND_WRAPPER *hSplitBin, + const IVAS_QUATERNION headPosition, + const Word32 SplitRendBitRate, + ISAR_SPLIT_REND_CODEC splitCodec, +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + const Word16 isar_frame_size_ms, /* i: ISAR framesize */ +#endif + Word16 codec_frame_size_ms, + ISAR_SPLIT_REND_BITS_HANDLE pBits, + Word32 Cldfb_In_BinReal_fx[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + Word32 Cldfb_In_BinImag_fx[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + const Word16 max_bands, + Word32 *pOutput_fx[], + const Word16 low_res_pre_rend_rot, + const Word16 cldfb_in_flag, + const Word16 pcm_out_flag, + const Word16 ro_md_flag, + Word16 Q_buff, + Word16 *Q_out ) +{ + ivas_error error; +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + int32_t bit_len, target_md_bits, available_bits, tmp_32; +#else + Word32 bit_len, target_md_bits, actual_md_bits, available_bits, tmp_32; +#endif + Word16 q1 = 31, q2 = 31, q_final, Q_cldfb, tmp, tmp_e; + Word16 i, j; + error = IVAS_ERR_OK; + Word16 Q_buff_re, Q_buff_im; + push_wmops( "ISAR_PRE_REND_MultiBinToSplitBinaural" ); +#ifdef CLDFB_SYNTH_DEBUG + /* FILE *fp = fopen( "Fixed_code_output.txt", "ab+" ); + FILE *fp1 = fopen( "Fixed_code_cldfb_state.txt", "ab+" ); + FILE *fp = fopen( "Float_code_output.txt", "ab+" ); + FILE *fp1 = fopen( "Float_code_cldfb_state.txt", "ab+" );*/ +#endif + Q_buff_re = Q_buff; + move16(); + Q_buff_im = Q_buff; + move16(); + IF( hSplitBin->multiBinPoseData.poseCorrectionMode == ISAR_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB ) + { + set_fix_rotation_mat_fx( hSplitBin->hBinHrSplitPreRend->fix_pos_rot_mat_fx, &hSplitBin->multiBinPoseData ); + set_pose_types_fx( hSplitBin->hBinHrSplitPreRend->pose_type, &hSplitBin->multiBinPoseData ); + } + + IF( EQ_16( cldfb_in_flag, 0 ) ) + { + error = isar_renderMultiTDBinToSplitBinaural( hSplitBin, headPosition, SplitRendBitRate, +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + isar_frame_size_ms, +#endif + codec_frame_size_ms, pBits, max_bands, pOutput_fx, Q_out[0], low_res_pre_rend_rot, pcm_out_flag, ro_md_flag ); + + Q_out[1] = Q_out[0]; + move16(); + pop_wmops(); + return error; + } + + IF( splitCodec == ISAR_SPLIT_REND_CODEC_LC3PLUS && hSplitBin->multiBinPoseData.poseCorrectionMode == ISAR_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB ) + { + /* Time-align pose correction to delay of LC3plus */ + lc3plusTimeAlignCldfbPoseCorr( hSplitBin, Cldfb_In_BinReal_fx, Cldfb_In_BinImag_fx, &Q_buff ); + Q_buff_re = Q_buff; + move16(); + Q_buff_im = Q_buff; + move16(); + } + +#ifndef ISAR_BITSTREAM_UPDATE_LC3PLUS + actual_md_bits = pBits->bits_written; +#endif + IF( hSplitBin->multiBinPoseData.poseCorrectionMode == ISAR_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB ) + { + target_md_bits = isar_get_split_rend_md_target_brate( SplitRendBitRate, pcm_out_flag ) * L_FRAME48k / 48000; + +#ifndef ISAR_BITSTREAM_UPDATE_LC3PLUS + actual_md_bits = pBits->bits_written; +#endif + /*float2fix, to be removed*/ + Word16 Q_Cldfb_re = 31, Q_Cldfb_im = 31; + move16(); + move16(); + FOR( i = 0; i < hSplitBin->multiBinPoseData.num_poses * BINAURAL_CHANNELS; i++ ) + { + FOR( j = 0; j < CLDFB_NO_COL_MAX; j++ ) + { + Q_Cldfb_re = s_min( getScaleFactor32( Cldfb_In_BinReal_fx[i][j], CLDFB_NO_CHANNELS_MAX ), Q_Cldfb_re ); + Q_Cldfb_im = s_min( getScaleFactor32( Cldfb_In_BinImag_fx[i][j], CLDFB_NO_CHANNELS_MAX ), Q_Cldfb_im ); + } + } + FOR( i = 0; i < hSplitBin->multiBinPoseData.num_poses * BINAURAL_CHANNELS; i++ ) + { + FOR( j = 0; j < CLDFB_NO_COL_MAX; j++ ) + { + Scale_sig32( Cldfb_In_BinReal_fx[i][j], CLDFB_NO_CHANNELS_MAX, Q_Cldfb_re ); + Scale_sig32( Cldfb_In_BinImag_fx[i][j], CLDFB_NO_CHANNELS_MAX, Q_Cldfb_im ); + } + } + Q_buff_re = add( Q_Cldfb_re, Q_buff ); + Q_buff_im = add( Q_Cldfb_im, Q_buff ); + Word16 exp_cldfb_re = sub( 31, Q_buff_re ); + Word16 exp_cldfb_im = sub( 31, Q_buff_im ); + isar_rend_CldfbSplitPreRendProcess( hSplitBin->hBinHrSplitPreRend, headPosition, &hSplitBin->multiBinPoseData, Cldfb_In_BinReal_fx, exp_cldfb_re, Cldfb_In_BinImag_fx, exp_cldfb_im, pBits, target_md_bits, low_res_pre_rend_rot, ro_md_flag ); + } + + IF( EQ_16( pcm_out_flag, 0 ) ) + { + pBits->codec = splitCodec; + pBits->pose_correction = hSplitBin->multiBinPoseData.poseCorrectionMode; + + IF( splitCodec == ISAR_SPLIT_REND_CODEC_LCLD ) + { + // available_bits = ( SplitRendBitRate * hSplitBin->hSplitBinLCLDEnc->iNumBlocks * hSplitBin->hSplitBinLCLDEnc->iNumIterations ) / ( 16 * FRAMES_PER_SEC ); + available_bits = W_extract_l( W_mult0_32_32( SplitRendBitRate, L_mult0( hSplitBin->hSplitBinLCLDEnc->iNumBlocks, hSplitBin->hSplitBinLCLDEnc->iNumIterations ) ) ); + tmp_e = 0; + tmp_32 = BASOP_Util_Divide3232_Scale_cadence( available_bits, L_mult0( 16, FRAMES_PER_SEC ), &tmp_e ); + available_bits = L_shr( tmp_32, sub( 31, tmp_e ) ); // Q0 +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + available_bits = L_sub( available_bits, pBits->bits_written ); +#else + actual_md_bits = L_sub( pBits->bits_written, actual_md_bits ); + available_bits = L_sub( available_bits, actual_md_bits ); +#endif + pBits->codec_frame_size_ms = codec_frame_size_ms; + q_final = sub( s_min( Q_buff_re, Q_buff_im ), 2 ); + FOR( i = 0; i < hSplitBin->hSplitBinLCLDEnc->iChannels; i++ ) + { + FOR( j = 0; j < CLDFB_NO_COL_MAX; j++ ) + { + Scale_sig32( Cldfb_In_BinReal_fx[i][j], CLDFB_NO_CHANNELS_MAX, sub( q_final, Q_buff_re ) ); + Scale_sig32( Cldfb_In_BinImag_fx[i][j], CLDFB_NO_CHANNELS_MAX, sub( q_final, Q_buff_im ) ); + } + } + isar_splitBinLCLDEncProcess( hSplitBin->hSplitBinLCLDEnc, Cldfb_In_BinReal_fx, Cldfb_In_BinImag_fx, available_bits, pBits, &q_final ); + Q_buff_re = q_final; + move16(); + Q_buff_im = q_final; + move16(); + } + ELSE + { + Word16 ch, slot_idx, num_slots, ivas_fs; + tmp_e = 0; + tmp = BASOP_Util_Divide3232_Scale( hSplitBin->hLc3plusEnc->config.isar_frame_duration_us, 1000, &tmp_e ); + ivas_fs = shr( tmp, sub( 15, tmp_e ) ); // Q0 + // ivas_fs = (Word16) hSplitBin->hLc3plusEnc->config.ivas_frame_duration_us / 1000; + + tmp_e = 0; + tmp = BASOP_Util_Divide3232_Scale( L_mult0( CLDFB_NO_COL_MAX, ivas_fs ), 20, &tmp_e ); + num_slots = shr( tmp, sub( 15, tmp_e ) ); // Q0 + // num_slots = (Word16) CLDFB_NO_COL_MAX * ivas_fs / 20; + /* CLDFB synthesis of main pose */ + { + q1 = 31; + q2 = 31; + move16(); + move16(); + FOR( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) + { + FOR( j = 0; j < CLDFB_NO_COL_MAX; j++ ) + { + q1 = s_min( getScaleFactor32( Cldfb_In_BinReal_fx[ch][j], CLDFB_NO_CHANNELS_MAX ), q1 ); + q2 = s_min( getScaleFactor32( Cldfb_In_BinImag_fx[ch][j], CLDFB_NO_CHANNELS_MAX ), q2 ); + } + } + + q_final = s_min( q1, q2 ); + q_final = s_min( add( Q_buff_re, q_final ), add( Q_buff_im, q_final ) ); + q_final = sub( q_final, 3 ); // guard bits + q_final = s_min( q_final, Q25 ); + + FOR( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) + { + FOR( j = 0; j < CLDFB_NO_COL_MAX; j++ ) + { + Scale_sig32( Cldfb_In_BinReal_fx[ch][j], CLDFB_NO_CHANNELS_MAX, sub( q_final, Q_buff_re ) ); + Scale_sig32( Cldfb_In_BinImag_fx[ch][j], CLDFB_NO_CHANNELS_MAX, sub( q_final, Q_buff_im ) ); + } + } + } + + FOR( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) + { + Word32 *Cldfb_In_BinReal_p_fx[CLDFB_NO_COL_MAX]; + Word32 *Cldfb_In_BinImag_p_fx[CLDFB_NO_COL_MAX]; + + + FOR( slot_idx = 0; slot_idx < num_slots; slot_idx++ ) + { + Cldfb_In_BinReal_p_fx[slot_idx] = Cldfb_In_BinReal_fx[ch][slot_idx]; + move32(); + Cldfb_In_BinImag_p_fx[slot_idx] = Cldfb_In_BinImag_fx[ch][slot_idx]; + move32(); + } + + Q_cldfb = q_final; + move16(); + Scale_sig32( hSplitBin->hCldfbHandles->cldfbSyn[ch]->cldfb_state_fx, hSplitBin->hCldfbHandles->cldfbSyn[ch]->p_filter_length, sub( sub( Q_cldfb, 1 ), hSplitBin->hCldfbHandles->cldfbSyn[ch]->Q_cldfb_state ) ); + cldfbSynthesis_ivas_fx( Cldfb_In_BinReal_p_fx, Cldfb_In_BinImag_p_fx, pOutput_fx[ch], hSplitBin->hCldfbHandles->cldfbSyn[0]->no_channels * num_slots, hSplitBin->hCldfbHandles->cldfbSyn[ch] ); // Q_cldfb - 1 + Q_out[ch] = sub( Q_cldfb, 1 ); + move16(); + hSplitBin->hCldfbHandles->cldfbSyn[ch]->Q_cldfb_state = Q_out[ch]; + move16(); + } + assert( Q_out[0] == Q_out[1] ); + +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + available_bits = ( SplitRendBitRate / FRAMES_PER_SEC ) - pBits->bits_written; + IF( ( error = splitRendLc3plusEncodeAndWrite( hSplitBin, pBits, available_bits, pOutput_fx, Q_out[0] ) ) != IVAS_ERR_OK ) +#else + IF( ( error = splitRendLc3plusEncodeAndWrite( hSplitBin, pBits, SplitRendBitRate, pOutput_fx ) ) != IVAS_ERR_OK ) +#endif + { + return error; + } + } + } + ELSE + { + Word16 ch, slot_idx; + /* CLDFB synthesis of main pose */ + FOR( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) + { + Word32 *Cldfb_In_BinReal_p_fx[CLDFB_NO_COL_MAX]; + Word32 *Cldfb_In_BinImag_p_fx[CLDFB_NO_COL_MAX]; + q1 = 31; + move16(); + q2 = 31; + move16(); + FOR( j = 0; j < CLDFB_NO_COL_MAX; j++ ) + { + q1 = s_min( getScaleFactor32( Cldfb_In_BinReal_fx[ch][j], CLDFB_NO_CHANNELS_MAX ), q1 ); + q2 = s_min( getScaleFactor32( Cldfb_In_BinImag_fx[ch][j], CLDFB_NO_CHANNELS_MAX ), q2 ); + } + q_final = s_min( q1, q2 ); + q_final = s_min( add( Q_buff_re, q_final ), add( Q_buff_im, q_final ) ); + q_final = sub( q_final, 3 ); // guard bits + q_final = s_min( q_final, Q25 ); + FOR( j = 0; j < CLDFB_NO_COL_MAX; j++ ) + { + Scale_sig32( Cldfb_In_BinReal_fx[ch][j], CLDFB_NO_CHANNELS_MAX, sub( q_final, Q_buff_re ) ); + Scale_sig32( Cldfb_In_BinImag_fx[ch][j], CLDFB_NO_CHANNELS_MAX, sub( q_final, Q_buff_im ) ); + } + + FOR( slot_idx = 0; slot_idx < CLDFB_NO_COL_MAX; slot_idx++ ) + { + Cldfb_In_BinReal_p_fx[slot_idx] = Cldfb_In_BinReal_fx[ch][slot_idx]; + move32(); + Cldfb_In_BinImag_p_fx[slot_idx] = Cldfb_In_BinImag_fx[ch][slot_idx]; + move32(); + } + + Q_cldfb = q_final; + move16(); + Scale_sig32( hSplitBin->hCldfbHandles->cldfbSyn[ch]->cldfb_state_fx, hSplitBin->hCldfbHandles->cldfbSyn[ch]->p_filter_length, sub( sub( Q_cldfb, 1 ), hSplitBin->hCldfbHandles->cldfbSyn[ch]->Q_cldfb_state ) ); + cldfbSynthesis_ivas_fx( Cldfb_In_BinReal_p_fx, Cldfb_In_BinImag_p_fx, pOutput_fx[ch], hSplitBin->hCldfbHandles->cldfbSyn[0]->no_channels * CLDFB_NO_COL_MAX, hSplitBin->hCldfbHandles->cldfbSyn[ch] ); // Q_cldfb - 1 + Q_out[ch] = sub( Q_cldfb, 1 ); + move16(); + hSplitBin->hCldfbHandles->cldfbSyn[ch]->Q_cldfb_state = Q_out[ch]; + move16(); + } + + pBits->pose_correction = hSplitBin->multiBinPoseData.poseCorrectionMode; + pBits->codec = ISAR_SPLIT_REND_CODEC_NONE; + } + + /*zero pad*/ + IF( pcm_out_flag ) + { + tmp_e = 0; + tmp = BASOP_Util_Divide3232_Scale( SplitRendBitRate, FRAMES_PER_SEC, &tmp_e ); + bit_len = L_deposit_l( shr( tmp, sub( 15, tmp_e ) ) ); // Q0 + // bit_len = SplitRendBitRate / FRAMES_PER_SEC; + } + ELSE + { + IF( splitCodec == ISAR_SPLIT_REND_CODEC_LCLD ) + { + // bit_len = ( SplitRendBitRate * hSplitBin->hSplitBinLCLDEnc->iNumBlocks * hSplitBin->hSplitBinLCLDEnc->iNumIterations ) / ( 16 * FRAMES_PER_SEC ); + + bit_len = W_extract_l( W_mult0_32_32( SplitRendBitRate, L_mult0( hSplitBin->hSplitBinLCLDEnc->iNumBlocks, hSplitBin->hSplitBinLCLDEnc->iNumIterations ) ) ); + tmp_e = 0; + tmp_32 = BASOP_Util_Divide3232_Scale_cadence( bit_len, L_mult0( 16, FRAMES_PER_SEC ), &tmp_e ); + bit_len = L_shr( tmp_32, sub( 31, tmp_e ) ); // Q0 + } + ELSE + { + tmp_e = 0; + tmp = BASOP_Util_Divide3232_Scale( hSplitBin->hLc3plusEnc->config.isar_frame_duration_us, 1000, &tmp_e ); + bit_len = L_deposit_l( shr( tmp, sub( 15, tmp_e ) ) ); // Q0 + // bit_len = hSplitBin->hLc3plusEnc->config.ivas_frame_duration_us / 1000; + // bit_len = SplitRendBitRate * bit_len / 1000; + tmp_e = 0; + tmp_32 = BASOP_Util_Divide3232_Scale_cadence( W_extract_l( W_mult0_32_32( SplitRendBitRate, bit_len ) ), 1000, &tmp_e ); + bit_len = L_shr( tmp_32, sub( 31, tmp_e ) ); // Q0 + } + } + + WHILE( LT_32( pBits->bits_written, bit_len ) ) + { + ISAR_SPLIT_REND_BITStream_write_int32( pBits, 0L, 1 ); + } + + pop_wmops(); + /* fclose(fp); + fclose(fp1);*/ + return error; +} + +#endif diff --git a/lib_isar/lib_isar_pre_rend.h b/lib_isar/lib_isar_pre_rend.h new file mode 100644 index 0000000000000000000000000000000000000000..a4d03e8a59af26e0be87ce0659006e5ea438e6bb --- /dev/null +++ b/lib_isar/lib_isar_pre_rend.h @@ -0,0 +1,91 @@ +/****************************************************************************************************** + + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository. All Rights Reserved. + + This software is protected by copyright law and by international treaties. + The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository retain full ownership rights in their respective contributions in + the software. This notice grants no license of any kind, including but not limited to patent + license, nor is any license granted by implication, estoppel or otherwise. + + Contributors are required to enter into the IVAS codec Public Collaboration agreement before making + contributions. + + This software is provided "AS IS", without any express or implied warranties. The software is in the + development stage. It is intended exclusively for experts who have experience with such software and + solely for the purpose of inspection. All implied warranties of non-infringement, merchantability + and fitness for a particular purpose are hereby disclaimed and excluded. + + Any dispute, controversy or claim arising under or in relation to providing this software shall be + submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in + accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and + the United Nations Convention on Contracts on the International Sales of Goods. + +*******************************************************************************************************/ + +#ifndef LIB_ISAR_PRE_REND_H +#define LIB_ISAR_PRE_REND_H + +#include "isar_stat.h" +#include "isar_prot.h" + +#ifndef SPLIT_REND_WITH_HEAD_ROT + +int32_t ISAR_PRE_REND_void_func( void ); + +#else +ivas_error ISAR_PRE_REND_open( + SPLIT_REND_WRAPPER *hSplitBinRend, /* i/o: Split renderer pre-renerer handle */ + ISAR_SPLIT_REND_CONFIG_DATA *pSplitRendConfig, /* i/o: Split renderer pre-renerer config */ + const int32_t output_Fs, /* i: output sampling rate */ + const int16_t cldfb_in_flag, /* i: Flag to indicate CLDFB or time doamin input */ + const int16_t pcm_out_flag, /* i: Flag to indicate PCM output */ +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + const IVAS_RENDER_FRAMESIZE ivas_frame_size, /* i: IVAS frame size */ +#else + const int16_t num_subframes, /* i: number of subframes */ +#endif + const int16_t mixed_td_cldfb_flag /* i: Flag to indicate combined TD and CLDFB input */ +); + +void ISAR_PRE_REND_close( + SPLIT_REND_WRAPPER *hSplitBinRend, /* i/o: Split renderer pre-renerer handle */ + IVAS_REND_AudioBuffer *pSplitRendEncBuffer /* i/o: Split renderer data buffer */ +); + +void ISAR_PRE_REND_GetMultiBinPoseData( + const ISAR_SPLIT_REND_CONFIG_DATA *pSplit_rend_config, /* i: Split renderer pre-renerer config */ + MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, /* i/o: pose correction data handle */ + const ISAR_SPLIT_REND_ROT_AXIS rot_axis /* i: Rotation axis */ +); + +ivas_error ISAR_PRE_REND_MultiBinToSplitBinaural( + SPLIT_REND_WRAPPER *hSplitBin, /* i/o: Split renderer pre-renerer handle */ + const IVAS_QUATERNION headPosition, /* i: head rotation QUATERNION */ + const Word32 SplitRendBitRate, /* i: Split renderer bitrate */ + ISAR_SPLIT_REND_CODEC splitCodec, /* i/o: Split renderer codec */ +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + const Word16 isar_frame_size_ms, /* i: ISAR framesize */ +#endif + Word16 codec_frame_size_ms, /* i/o: Split renderer codec framesize */ + ISAR_SPLIT_REND_BITS_HANDLE pBits, /* i/o: Split renderer bitstream handle */ + Word32 Cldfb_In_BinReal_fx[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], /* i/o: CLDFB real buffer */ + Word32 Cldfb_In_BinImag_fx[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], /* i/o: CLDFB imag buffer */ + const Word16 max_bands, /* i: CLDFB bands */ + Word32 *pOutput_fx[], /* i: low time resolution pre-renderer flag */ + const Word16 low_res_pre_rend_rot, /* i: low time resolution pre-renderer flag */ + const Word16 cldfb_in_flag, /* i: Flag to indicate CLDFB or time doamin input */ + const Word16 pcm_out_flag, /* i: Flag to indicate PCM output */ + const Word16 ro_md_flag, /* i: Flag to indicate real only metadata for yaw */ + Word16 Q_buff, + Word16 *Q_out ); + +#endif +#endif /* LIB_ISAR_PRE_REND_H */ diff --git a/lib_lc3plus/.clang-format b/lib_lc3plus/.clang-format new file mode 100644 index 0000000000000000000000000000000000000000..47a38a93f2dbdd6d944f9dddc3465e3fb65aec29 --- /dev/null +++ b/lib_lc3plus/.clang-format @@ -0,0 +1,2 @@ +DisableFormat: true +SortIncludes: Never diff --git a/lib_lc3plus/adjust_global_gain_fx.c b/lib_lc3plus/adjust_global_gain_fx.c new file mode 100644 index 0000000000000000000000000000000000000000..c6067b59122b40b106640b462b10d4af167ca80f --- /dev/null +++ b/lib_lc3plus/adjust_global_gain_fx.c @@ -0,0 +1,186 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.5 * +* 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 "functions.h" + + + +void processAdjustGlobalGain_fx(Word16 *gg_idx, Word16 gg_idx_min, Word16 gg_idx_off, +#ifdef ENABLE_HR_MODE + Word32 *gain, +#else + Word16 *gain, +#endif + Word16 *gain_e, + Word16 target, Word16 nBits, Word16 *gainChange, Word16 fs_idx +#ifdef ENABLE_HR_MODE + , Word16 hrmode, Word16 frame_dms +#endif + ) +{ + + Word32 L_tmp; + Word16 delta, delta2; +#ifdef ENABLE_HR_MODE + Word16 gg_idx_inc; + Word16 gg_idx_inc_max; + Word16 gg_idx_inc_s; +# ifdef CR8_G_ADD_75MS + Word32 factor; +# else + Word16 factor; +# endif +#endif + +#ifdef DYNMEM_COUNT +#if defined(ENABLE_HR_MODE) + Dyn_Mem_In("processAdjustGlobalGain_fx", sizeof(struct { + Word32 L_tmp; + Word16 delta, delta2; + Word16 gg_idx_inc; + Word16 gg_idx_inc_max; + Word16 gg_idx_inc_s; + Word16 factor; + })); +#else + Dyn_Mem_In("processAdjustGlobalGain_fx", sizeof(struct { + Word32 L_tmp; + Word16 delta, delta2; + })); +#endif /* ENABLE_HR_MODE */ +#endif /* DYNMEM_COUNT */ + +#ifdef ENABLE_HR_MODE + IF (sub(frame_dms, 25) == 0) + { + IF (sub(target, 520) < 0) + { + factor = 3; move16(); + gg_idx_inc_max = 30; move16(); + } ELSE { + factor = 4; move16(); + gg_idx_inc_max = 40; move16(); + } + } + ELSE IF (sub(frame_dms, 50) == 0) + { + factor = 2; move16(); + gg_idx_inc_max = 20; move16(); + } +#ifdef CR8_G_ADD_75MS + ELSE IF (sub(frame_dms, 75) == 0) + { + factor = 40265318; move16(); // factor = 1.2 * 2^25 + gg_idx_inc_max = 12 ; move16(); + } +#endif + ELSE + { + factor = 1; move16(); + gg_idx_inc_max = 10; move16(); + } +#endif + + IF (sub(nBits, adjust_global_gain_tables[0][fs_idx]) < 0) + { + delta = mult_r(add(nBits, 48), 2048); + } + ELSE IF (sub(nBits, adjust_global_gain_tables[1][fs_idx]) < 0) + { + delta = mult_r(add(nBits, adjust_global_gain_tables[4][fs_idx]), adjust_global_gain_tables[3][fs_idx]); + } + ELSE IF (sub(nBits, adjust_global_gain_tables[2][fs_idx]) < 0) + { + delta = mult_r(nBits, 683); + } + ELSE + { + delta = mult_r(adjust_global_gain_tables[2][fs_idx], 683); + } + delta2 = add(delta, 2); + + *gainChange = 0; move16(); + + test(); + IF (sub(*gg_idx, 255) == 0 && sub(nBits, target) > 0) + { + *gainChange = 1; move16(); + } + + test(); test(); test(); + IF ((sub(*gg_idx, 255) < 0 && sub(nBits, target) > 0) || (*gg_idx > 0 && sub(nBits, sub(target, delta2)) < 0)) + { +#ifdef ENABLE_HR_MODE + IF (hrmode) + { + IF (sub(nBits, target) > 0) + { + gg_idx_inc = sub(nBits, target); +#ifdef CR8_G_ADD_75MS + IF (sub(frame_dms, 75) == 0) + { + gg_idx_inc = extract_l(L_shr_pos(Mpy_32_16_lc3plus(factor, gg_idx_inc), 10)); // Mpy_32_16_lc3plus(1.2*2^25, gg_idx_inc), 25 - 15) + gg_idx_inc = BASOP_Util_Divide1616_Scale_lc3plus(gg_idx_inc, delta, &gg_idx_inc_s); + gg_idx_inc = shr_sat(gg_idx_inc, sub(15, gg_idx_inc_s)); + gg_idx_inc = add(gg_idx_inc, 1); // adding 1 instead of 1.2 + } + ELSE +#endif + { + gg_idx_inc = extract_l(L_mult0(gg_idx_inc, factor)); + gg_idx_inc = BASOP_Util_Divide1616_Scale_lc3plus(gg_idx_inc, delta, &gg_idx_inc_s); + gg_idx_inc = shr_sat(gg_idx_inc, sub(15, gg_idx_inc_s)); + gg_idx_inc = add(gg_idx_inc, factor); + } + gg_idx_inc = s_min(gg_idx_inc, gg_idx_inc_max); + + *gg_idx = add(*gg_idx, gg_idx_inc); move16(); + } + + *gg_idx = s_min(*gg_idx, 255); move16(); + } + ELSE +#endif + { + test(); + IF (sub(nBits, sub(target, delta2)) < 0) + { + *gg_idx = sub(*gg_idx, 1); move16(); + } + ELSE IF (sub(*gg_idx, 254) == 0 || sub(nBits, add(target, delta)) < 0) + { + *gg_idx = add(*gg_idx, 1); move16(); + } + ELSE + { + *gg_idx = add(*gg_idx, 2); move16(); + } + } + + *gg_idx = s_max(*gg_idx, sub(gg_idx_min, gg_idx_off)); move16(); + +#ifdef ENABLE_HR_MODE + L_tmp = Mpy_32_16_lc3plus(0x3CBE6B83, L_shl_pos(add(*gg_idx, gg_idx_off), 7)); +#else + L_tmp = L_shl_pos(L_mult0(add(*gg_idx, gg_idx_off), 0x797D), 7); /* 6Q25; 0x797D -> log2(10)/28 (Q18) */ +#endif + *gain_e = add(extract_l(L_shr_pos(L_tmp, 25)), 1); /* get exponent */ +#ifdef ENABLE_HR_MODE + *gain = BASOP_Util_InvLog2_lc3plus(L_or(L_tmp, (Word32)0xFE000000)); +#else + *gain = round_fx(BASOP_Util_InvLog2_lc3plus(L_or(L_tmp, (Word32)0xFE000000))); +#endif + *gainChange = 1; move16(); + } + +#ifdef DYNMEM_COUNT + Dyn_Mem_Out(); +#endif +} + diff --git a/lib_lc3plus/al_fec.c b/lib_lc3plus/al_fec.c new file mode 100644 index 0000000000000000000000000000000000000000..c659a90e0521f35ab0e6b5873e0d8c778b7ddf66 --- /dev/null +++ b/lib_lc3plus/al_fec.c @@ -0,0 +1,2379 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.5 * +* 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 "defines.h" + + +#include "functions.h" +#include "rom_basop_util_lc3plus.h" +#include +#include +#include +#include + +/* channel coder specific constants and macros */ +#define RS16_CW_LEN_MAX 15 + +#define FEC_N_MODES 4 +#define FEC_N_SYNDROMES_MAX 6 +#define FEC_N_ERR_POS_MAX 3 +#define FEC_N_ELP_COEFF_MAX 4 +#define FEC_N_ERR_SYMB_MAX 3 +#define FEC_N_MODE_DETECTION_CW 6 + +#define SYNDROME_IDX(mode_index, cw_index) (((mode_index)*FEC_N_MODE_DETECTION_CW + (cw_index)) * FEC_N_SYNDROMES_MAX) +#define ELP_IDX(mode_index, cw_index) (((mode_index)*FEC_N_MODE_DETECTION_CW + (cw_index)) * FEC_N_ELP_COEFF_MAX) +#define ERR_POS_IDX(mode_index, cw_index) (((mode_index)*FEC_N_MODE_DETECTION_CW + (cw_index)) * FEC_N_ERR_POS_MAX) +#define ERR_SYMB_IDX(mode_index, cw_index) (((mode_index)*FEC_N_MODE_DETECTION_CW + (cw_index)) * FEC_N_ERR_SYMB_MAX) +#define DEG_ELP_IDX(mode_index, cw_index) ((mode_index)*FEC_N_MODE_DETECTION_CW + (cw_index)) + +#define FEC_TOTAL_SYNDROME_SIZE (FEC_N_SYNDROMES_MAX * FEC_N_MODES * FEC_N_MODE_DETECTION_CW) +#define FEC_TOTAL_ELP_SIZE (FEC_N_ELP_COEFF_MAX * FEC_N_MODES * FEC_N_MODE_DETECTION_CW) +#define FEC_TOTAL_ERR_POS_SIZE (FEC_N_ERR_POS_MAX * FEC_N_MODES * FEC_N_MODE_DETECTION_CW) +#define FEC_TOTAL_ERROR_SIZE (FEC_N_ERR_SYMB_MAX * FEC_N_MODES * FEC_N_MODE_DETECTION_CW) +#define FEC_TOTAL_DEG_ELP_SIZE (FEC_N_MODES * FEC_N_MODE_DETECTION_CW) + +#define ERROR_REPORT_BEC_MASK ((0x0FFF)>>1) +#define ERROR_REPORT_EP1_OK ((0x1000)>>1) +#define ERROR_REPORT_EP2_OK ((0x2000)>>1) +#define ERROR_REPORT_EP3_OK ((0x4000)>>1) +#define ERROR_REPORT_EP4_OK ((0x8000)>>1) +#define ERROR_REPORT_ALL_OK (ERROR_REPORT_EP1_OK | ERROR_REPORT_EP2_OK | ERROR_REPORT_EP3_OK | ERROR_REPORT_EP4_OK) + +/* debugging switches */ + +/* constants concerning mode detection */ +#define EP_RISK_THRESH_NS_M 21990 +#define EP_RISK_THRESH_NS_E -23 +#define EP_RISK_THRESH_OS_M 25166 +#define EP_RISK_THRESH_OS_E -10 + +#define SIMPLE_FLOAT_1_MANTISSA 16384 + +#define FEC_STATIC static + +/* DISCLAIMER: Strict instrumentation of GF16 arithmetic would have to take into account + * the initial conversion of the arguments from UWord8 to Word16 (one move16() per argument). + * Behind this is the assumption that one would store GF16 elements in Word16 for strict BASOP + * implementation. + */ + +#define GF16_MUL(a, b) (UWord8)(move16(), gf16_mult_table[s_or((a), shl((b), 4))]) +#define GF16_MUL0(a, b) (UWord8)(move16(), gf16_mult_table[s_or((a), (b))]) +#define GF16_ADD(a, b) (UWord8) s_xor((a), (b)) + +/* tables for finite field arithmetic */ +/* tables for arithmetic in GF(16) * + * generator polynomial: 19 + * unit group generator (g): 2 + */ + +static const UWord8 gf16_g_pow[16] = {1, 2, 4, 8, 3, 6, 12, 11, 5, 10, 7, 14, 15, 13, 9, 1}; +/* g_pow[i] contains g^i*/ + +static const UWord8 gf16_log_g[16] = {255, 0, 1, 4, 2, 8, 5, 10, 3, 14, 9, 7, 6, 13, 11, 12}; +/* log_g[n] contains contains the value i such that g^i = n for n=1, 2, ..., 15, log_g[0] is set to 255 */ + +static const UWord8 gf16_inv_table[16] = {255, 1, 9, 14, 13, 11, 7, 6, 15, 2, 12, 5, 10, 4, 3, 8}; +/* gf16_inv_table[n] contains the multiplicative inverse of n in GF(16) (1/0 is set to 255)*/ + +/* RS16 generating polynomials (from lowest to highest coefficient without leading 1)*/ + +static const UWord8 rs16_gp_d3[] = {8, 6}; +static const UWord8 rs16_gp_d5[] = {7, 8, 12, 13}; +static const UWord8 rs16_gp_d7[] = {12, 10, 12, 3, 9, 7}; + +/* FEC mode signaling polynomials */ + +#define EP_SIG_POLY_DEG 12 + +static const UWord8 sig_polys[4][15] = {{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {7, 15, 5, 6, 14, 9, 1, 3, 12, 10, 13, 3, 2, 0, 0}, + {7, 11, 14, 1, 2, 3, 12, 11, 6, 15, 7, 6, 12, 0, 0}, + {6, 15, 12, 2, 9, 15, 2, 8, 12, 3, 10, 5, 4, 0, 0}}; + +static const UWord8 sig_poly_syndr[4][6] = { + {0, 0, 0, 0, 0, 0}, {0, 4, 5, 11, 5, 8}, {0, 5, 9, 0, 1, 7}, {0, 12, 5, 12, 9, 8}}; + +/* bit count table for error report (0000 0001 0010 0011 0100 0101 0110 0111 1000 1001 1010 1011 1100 1101 1110 1111) */ + +static const UWord8 rs16_bit_count_table[] = {0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4}; + +/* List of RS16 generators by Hamming distance */ + +static const UWord8 *const rs16_gp_by_hd[8] = {NULL, NULL, NULL, rs16_gp_d3, NULL, rs16_gp_d5, NULL, rs16_gp_d7}; + +/* fec config data */ + +static const UWord8 hamming_distance_by_mode0[] = {1, 3, 3, 5, 7}; +static const UWord8 hamming_distance_by_mode1[] = {1, 1, 3, 5, 7}; + +static const UWord8 crc1_bytes_by_mode0[] = {0, 3, 2, 2, 2}; +static const UWord8 crc1_bytes_by_mode1[] = {0, 3, 3, 3, 3}; +static const UWord8 crc2_bytes_by_mode[] = {0, 0, 2, 2, 2}; + +/* fec mode risk table */ +typedef struct +{ + UWord32 mantissa; + Word16 exponent; +} simple_float; + +static const simple_float risk_table_f[4][4] = {{{16384, 0}, {16384, 0}, {16384, 0}, {16384, 0}}, + {{16384, -8}, {26880, -1}, {16384, 0}, {16384, 0}}, + {{16384, -16}, {26880, -9}, {20475, -2}, {16384, 0}}, + {{16384, -24}, {26880, -17}, {20475, -10}, {19195, -4}}}; +/* bit error limits for slot size 40 */ +static Word16 const low_br_max_bit_errors_by_mode[] = {0, 0, 3, 9, 18}; + +/* +corresponding float values: + {1.f, 1.f, 1.f, 1.f}, + {0.00390625f, 0.820312f, 1.f, 1.f}, + {1.52588e-05f, 0.00320435f, 0.312424f, 1.f}, + {5.96046e-08f, 1.2517e-05f, 0.00122041f, 0.0732243f} +*/ + +/* internal encoder routines */ + +FEC_STATIC void fec_interleave_pack(UWord8 *out, UWord8 *in, Word16 n_nibbles, Word16 n_codewords); + +FEC_STATIC void rs16_enc(UWord8 *iobuf, Word16 codeword_length, Word16 hamming_distance, Word16 fec_mode, + Word16 signal_mode); + +/* internal decoder routines */ + +FEC_STATIC void fec_deinterleave_unpack(UWord8 *out, UWord8 *in, Word16 n_nibbles, Word16 n_codewords); + +FEC_STATIC Word16 fec_data_preproc(Word16 mode, Word16 epmr, UWord8 *iobuf, UWord8 *cw_buf, Word16 data_bytes, + Word16 slot_bytes, Word16 pc_split); + +FEC_STATIC void fec_data_postproc(Word16 mode, Word16 *epmr, UWord8 *iobuf, Word16 data_bytes, UWord8 *cw_buf, + Word16 slot_bytes, Word16 pc_split, int *bfi); + +FEC_STATIC int rs16_detect_and_correct(UWord8 *iobuf, int n_symb, int n_codewords, Word16 *epmr, Word16 *error_report, + int *bfi, UWord8 *array_of_trust, int ccc_flag_flag, Word16 *n_pccw, void *scratch); + +FEC_STATIC void rs16_calculate_six_syndromes(UWord8 *syndromes, UWord8 *cw, int cw_poly_deg); + +FEC_STATIC void rs16_calculate_four_syndromes(UWord8 *syndromes, UWord8 *cw, int cw_poly_deg); + +FEC_STATIC void rs16_calculate_two_syndromes(UWord8 *syndromes, UWord8 *cw, int cw_poly_deg); + +FEC_STATIC Word8 rs16_calculate_elp(UWord8 *elp, UWord8 *syndromes, Word16 hamming_distance); + +FEC_STATIC Word16 rs16_factorize_elp(UWord8 *error_locations, UWord8 *elp, Word16 deg_elp, Word16 max_pos); + +FEC_STATIC void rs16_calculate_errors(UWord8 *errors, UWord8 *err_pos, UWord8 *syndromes, Word8 deg_elp, Word8 t); + +/* auxiliary routines */ + +FEC_STATIC Word16 crc1(UWord8 *data, Word16 data_size, Word16 epmr, UWord8 *hash, Word16 hash_size, Word16 check); + +FEC_STATIC Word16 fec_estimate_epmr_from_cw0(UWord8 *cw0, Word8 *t, UWord8 *syndromes, UWord8 *elp, Word8 *deg_elp, + UWord8 *err_pos, UWord8 *err_symb, Word16 n_codewords, Word16 n_symb); + +FEC_STATIC void dw0_bitswap(UWord8 *dw0, Word16 mode, Word16 slot_bytes); + +FEC_STATIC Word16 cw0_get_epmr(UWord8 *cw0, Word16 epmr_position); + +FEC_STATIC Word16 dw0_get_epmr(UWord8 *dw0, Word16 mode, Word16 slot_size); + +FEC_STATIC Word16 crc2(UWord8 *data, Word16 data_size, UWord8 *hash, Word16 hash_size, Word16 check); + +FEC_STATIC simple_float simple_float_mul(simple_float op1, simple_float op2); + +FEC_STATIC Word16 simple_float_cmp(simple_float op1, simple_float op2); + +FEC_STATIC Word16 get_total_crc_size(Word16 slot_bytes, Word16 fec_mode, Word16 pc_split); + +FEC_STATIC Word16 get_n_codewords(Word16 slot_bytes); + +FEC_STATIC Word16 get_codeword_length(Word16 n_codewords, Word16 slot_nibbles, Word16 codeword_index); + + + +Word16 fec_get_n_pccw(Word16 slot_bytes, Word16 fec_mode, Word16 ccc_flag) +{ + Dyn_Mem_Deluxe_In( + Word16 n_pccw; + ); + + IF (sub(fec_mode, 3) == 0) + { + n_pccw = round_fx(L_sub(L_mult(2636, slot_bytes), 117377)); + } + ELSE IF (sub(fec_mode, 4) == 0) + { + n_pccw = round_fx(L_sub(L_mult(2178, slot_bytes), 129115)); + } + ELSE + { + n_pccw = 0; move16(); + } + + if (ccc_flag == 1 || sub(slot_bytes, 80) < 0) + { + n_pccw = 0; move16(); + } + + Dyn_Mem_Deluxe_Out(); + return n_pccw; +} + +FEC_STATIC Word16 get_total_crc_size(Word16 slot_bytes, Word16 fec_mode, Word16 pc_split) +{ + Dyn_Mem_Deluxe_In( + Word16 n_crc; + ); + + n_crc = crc1_bytes_by_mode1[fec_mode]; move16(); + if (sub(slot_bytes, 40) == 0) + { + n_crc = crc1_bytes_by_mode0[fec_mode]; move16(); + } + + IF (pc_split > 0) + { + n_crc = add(n_crc, crc2_bytes_by_mode[fec_mode]); + } + Dyn_Mem_Deluxe_Out(); + return n_crc; +} + +FEC_STATIC Word16 get_n_codewords(Word16 slot_bytes) +{ + Dyn_Mem_Deluxe_In( + Word16 i; + ); + + slot_bytes = shl(slot_bytes, 1); + + FOR (i = 0; slot_bytes > 0; i++) + { + slot_bytes = sub(slot_bytes, RS16_CW_LEN_MAX); + } + + Dyn_Mem_Deluxe_Out(); + return i; +} + +FEC_STATIC Word16 get_codeword_length(Word16 n_codewords, Word16 slot_nibbles, Word16 codeword_index) +{ + Dyn_Mem_Deluxe_In( + Word16 i; + ); + + slot_nibbles = sub(slot_nibbles, add(codeword_index, 1)); + slot_nibbles = sub(slot_nibbles, DEPR_i_mult(n_codewords, 13)); + + FOR (i = 12; slot_nibbles >= 0; i++) + { + slot_nibbles = sub(slot_nibbles, n_codewords); + } + + Dyn_Mem_Deluxe_Out(); + return add(i, 1); +} + +/* Encoder */ + +Word16 fec_get_data_size(Word16 fec_mode, Word16 ccc_flag, Word16 slot_bytes) +/* not time critical */ +{ + Dyn_Mem_Deluxe_In( + Word16 n_codewords, payload_size; + ); + + n_codewords = get_n_codewords(slot_bytes); + + assert(n_codewords == (2 * slot_bytes + RS16_CW_LEN_MAX - 1) / RS16_CW_LEN_MAX); + payload_size = slot_bytes; move16(); + + IF (fec_mode > 0) + { + IF (fec_mode == 1) + { + payload_size = sub(payload_size, 1); + } + ELSE + { + payload_size = sub(payload_size, DEPR_i_mult(sub(fec_mode, 1), n_codewords)); + } + IF (slot_bytes == 40) + { + payload_size = sub(payload_size, crc1_bytes_by_mode0[fec_mode]); move16(); + } + ELSE + { + payload_size = sub(payload_size, crc1_bytes_by_mode1[fec_mode]); move16(); + } + + IF (ccc_flag == 0 && fec_mode > 2 && slot_bytes >= 80) + { + payload_size = sub(payload_size, crc2_bytes_by_mode[fec_mode]); + } + } + + Dyn_Mem_Deluxe_Out(); + return payload_size; +} + +Word16 fec_get_n_pc(Word16 fec_mode, Word16 n_pccw, Word16 slot_bytes) +/* not time critical */ +{ + Dyn_Mem_Deluxe_In( + Word16 n_codewords, pc_split, tmp; + int i; + ); + + n_codewords = get_n_codewords(slot_bytes); + + assert(n_codewords == (2 * slot_bytes + RS16_CW_LEN_MAX - 1) / RS16_CW_LEN_MAX); + pc_split = DEPR_i_mult(DEPR_i_mult(n_pccw, -2), sub(fec_mode, 1)); + + IF (fec_mode == 1 || slot_bytes < 80) + { + pc_split = 0; move16(); + } + ELSE + { + FOR (i = 0; i < n_pccw; i++) + { + tmp = get_codeword_length(n_codewords, add(slot_bytes, slot_bytes), sub(n_codewords, i + 1)); + assert(tmp == (2 * slot_bytes + i) / n_codewords); + pc_split = add(pc_split, tmp); + } + } + + Dyn_Mem_Deluxe_Out(); + return pc_split; +} + +/* functions for EPMR handling */ +FEC_STATIC void dw0_bitswap(UWord8 *dw0, Word16 mode, Word16 slot_bytes) +/* swap epmr bits with bits that will be positioned at 30 and 32 in code word 0 */ +{ + Dyn_Mem_Deluxe_In( + UWord8 tmp; + int ind0, ind1, position; + ); + + position = sub(get_codeword_length(get_n_codewords(slot_bytes), shl(slot_bytes, 1), 0), 1); + + IF (sub(slot_bytes, 40) == 0) + { + ind0 = sub(shl(crc1_bytes_by_mode0[mode], 1), 1); + } + ELSE + { + ind0 = sub(shl(crc1_bytes_by_mode1[mode], 1), 1); + } + + ind1 = sub(position, sub(hamming_distance_by_mode0[mode], 1)); + + /* swap bits 2 and 3 of dw0[ind0] with bits 0 and 1 of dw0[ind1] */ + tmp = (UWord8) s_and(shr(dw0[ind0],2), 3); + dw0[ind0] = (UWord8) s_and(dw0[ind0], 3); + dw0[ind0] = (UWord8) s_or(dw0[ind0], shl(s_and(dw0[ind1], 3),2)); + dw0[ind1] = (UWord8) s_and(dw0[ind1], 12); + dw0[ind1] = (UWord8) s_or(dw0[ind1], tmp); + + Dyn_Mem_Deluxe_Out(); +} + +FEC_STATIC Word16 cw0_get_epmr(UWord8 *cw0, Word16 position) +{ + Dyn_Mem_Deluxe_In( + Word16 epmr; + ); + epmr = s_and(cw0[position], 3); + + Dyn_Mem_Deluxe_Out(); + return epmr; +} + +FEC_STATIC Word16 dw0_get_epmr(UWord8 *dw0, Word16 mode, Word16 slot_size) +{ + Dyn_Mem_Deluxe_In( + int ncrc1; + Word16 epmr; + ); + + ncrc1 = crc1_bytes_by_mode1[mode]; + + if (sub(slot_size, 40) == 0) + { + ncrc1 = crc1_bytes_by_mode0[mode]; + } + + epmr = shr(dw0[2 * ncrc1 - 1], 2); + + Dyn_Mem_Deluxe_Out(); + return epmr; +} + + +FEC_STATIC Word16 fec_data_preproc(Word16 mode, Word16 epmr, UWord8 *iobuf, UWord8 *cw_buf, Word16 data_bytes, + Word16 slot_bytes, Word16 pc_split) +{ + Dyn_Mem_Deluxe_In( + Word16 data_offset, n_crc1, n_crc2, tmp; + int i, j; + ); + + tmp = sub(slot_bytes, data_bytes); + data_offset = add(tmp, tmp); + + /* extract and reverse data*/ + j = sub(add(slot_bytes, slot_bytes), 1); + FOR (i = 0; i < data_bytes; i++) + { + cw_buf[j--] = (UWord8)s_and(iobuf[i], 15); move16(); + cw_buf[j--] = (UWord8)shr(iobuf[i], 4); move16(); + } + + /* add crc hashes */ + IF (sub(slot_bytes, 40) == 0) + { + n_crc1 = crc1_bytes_by_mode0[mode]; move16(); + } + ELSE + { + n_crc1 = crc1_bytes_by_mode1[mode]; move16(); + } + + IF (pc_split > 0 && sub(mode, 1) > 0) + { + n_crc2 = crc2_bytes_by_mode[mode]; move16(); + } + ELSE + { + n_crc2 = 0; move16(); + } + + IF (n_crc2) + { + crc2(cw_buf + data_offset + 2 * data_bytes - pc_split, pc_split, cw_buf + data_offset - 2 * n_crc2, n_crc2, 0); + } + IF (n_crc1) + { + crc1(cw_buf + data_offset, 2 * data_bytes - pc_split, epmr, cw_buf + data_offset - 2 * (n_crc1 + n_crc2), n_crc1, + 0); + } + + tmp = add(n_crc1, n_crc2); + data_offset = sub(data_offset, add(tmp, tmp)); + + dw0_bitswap(cw_buf + data_offset, mode, slot_bytes); + + Dyn_Mem_Deluxe_Out(); + return data_offset; +} + +void fec_encoder(Word16 mode, Word16 epmr, UWord8 *iobuf, Word16 data_bytes, Word16 slot_bytes, Word16 n_pccw, + void *scratch) +{ + Dyn_Mem_Deluxe_In( + Word16 n_codewords, codeword_length, hd, redundancy_nibbles, cw_offset, dw_offset, pc_split; + int i, j; + UWord8 *cw_buf; + ); + + cw_offset = 0; move16(); + dw_offset = 0; move16(); + pc_split = 0; move16(); + cw_buf = scratch; + + n_codewords = get_n_codewords(slot_bytes); + assert(n_codewords == (2 * slot_bytes + RS16_CW_LEN_MAX - 1) / RS16_CW_LEN_MAX); + + /* some sanity checks */ + { + int tmp = slot_bytes; + assert((slot_bytes >= FEC_SLOT_BYTES_MIN && slot_bytes <= FEC_SLOT_BYTES_MAX) && + "fec_encoder: slot_bytes out of range"); + tmp -= mode == 1 ? 1 : n_codewords * (mode - 1); // reed solomon redundancy + tmp -= slot_bytes == 40 ? crc1_bytes_by_mode0[mode] : crc1_bytes_by_mode1[mode]; // crc1 + tmp -= (n_pccw > 0) && (mode > 1) ? crc2_bytes_by_mode[mode] : 0; // crc2 + assert(data_bytes == tmp && "fec_encoder: inconsistent payload size"); + assert(n_codewords - n_pccw >= 6); + } + + /* data preproc: re-ordering and hash extension */ + pc_split = fec_get_n_pc(mode, n_pccw, slot_bytes); + + dw_offset = fec_data_preproc(mode, epmr, iobuf, cw_buf, data_bytes, slot_bytes, pc_split); + + /* encoding of first data word*/ + hd = hamming_distance_by_mode0[mode]; move16(); + redundancy_nibbles = sub(hd, 1); + codeword_length = get_codeword_length(n_codewords, add(slot_bytes, slot_bytes), 0); + + assert(codeword_length == (2 * slot_bytes - 1) / n_codewords + 1); + + FOR (j = redundancy_nibbles; j < codeword_length; (j++, dw_offset++)) + { + cw_buf[j] = cw_buf[dw_offset]; move16(); + } + + rs16_enc(cw_buf, codeword_length, hd, mode, 1); + + cw_offset = add(cw_offset, codeword_length); + + /* encoding of remaining data words */ + hd = hamming_distance_by_mode1[mode]; move16(); + redundancy_nibbles = sub(hd, 1); + + FOR (i = 1; i < n_codewords; i++) + { + codeword_length = get_codeword_length(n_codewords, add(slot_bytes, slot_bytes), i); + + assert(codeword_length == (2 * slot_bytes - i - 1) / n_codewords + 1); + FOR (j = redundancy_nibbles; j < codeword_length; (j++, dw_offset++)) + { + cw_buf[cw_offset + j] = cw_buf[dw_offset]; move16(); + } + + rs16_enc(cw_buf + cw_offset, codeword_length, hd, mode, sub(i, 6) < 0); + + cw_offset = add(cw_offset, codeword_length); + } + + assert(cw_offset == 2 * slot_bytes && dw_offset == 2 * slot_bytes); + + fec_interleave_pack(iobuf, cw_buf, add(slot_bytes, slot_bytes), n_codewords); + + + Dyn_Mem_Deluxe_Out(); +} + +FEC_STATIC void rs16_enc(UWord8 *iobuf, Word16 codeword_length, Word16 hamming_distance, Word16 fec_mode, + Word16 signal_mode) +/* expects (data polynomial) * x^(hamming_distance - 1) in iobuf */ +{ + + Dyn_Mem_Deluxe_In( + UWord8 const *gp; + UWord8 shift_buffer[RS16_CW_LEN_MAX + 1], lc; + int i, j, deg_gp; + ); + + basop_memset(shift_buffer, 0, sizeof(shift_buffer)); + gp = rs16_gp_by_hd[hamming_distance]; move16(); + deg_gp = sub(hamming_distance, 1); + + IF (sub(hamming_distance, 1) > 0) + { + assert(codeword_length > deg_gp); + + /* initialize redundancy part to zero */ + basop_memset(iobuf, 0, deg_gp); + + /* initialize shift_buffer */ + basop_memmove(shift_buffer + 1, iobuf + codeword_length - deg_gp, deg_gp); + + /* calculate remainder */ + FOR (i = codeword_length - deg_gp - 1; i >= 0; i--) + { + shift_buffer[0] = iobuf[i]; move16(); + lc = (UWord8)shl(shift_buffer[deg_gp], 4); move16(); + FOR (j = deg_gp - 1; j >= 0; j--) + { + shift_buffer[j + 1] = GF16_ADD(shift_buffer[j], GF16_MUL0(gp[j], lc)); move16(); + } + } + + /* add remainder to shifted data polynomial */ + FOR (i = 0; i < deg_gp; i++) + { + iobuf[i] = shift_buffer[i + 1]; move16(); + } + + /* add signaling polynomial */ + IF (signal_mode) + { + assert(codeword_length > EP_SIG_POLY_DEG); + FOR (i = 0; i <= EP_SIG_POLY_DEG; i++) + { + iobuf[i] = GF16_ADD(iobuf[i], sig_polys[fec_mode - 1][i]); move16(); + } + } + } + + Dyn_Mem_Deluxe_Out(); +} + +FEC_STATIC void fec_interleave_pack(UWord8 *out, UWord8 *in, Word16 n_nibbles, Word16 n_codewords) +{ + Dyn_Mem_Deluxe_In( + Word16 out_offset, cw_offset, codeword_length; + int i, j; + ); + + out_offset = 0; move16(); + cw_offset = 0; move16(); + + /* initialize output buffer to zero */ + basop_memset(out, 0, shr(n_nibbles, 1)); + + /* interleave and pack codewords */ + FOR (i = 0; i < n_codewords; i++) + { + codeword_length = get_codeword_length(n_codewords, n_nibbles, i); + + assert(codeword_length == (n_nibbles - i - 1) / n_codewords + 1); + FOR (j = 0; j < codeword_length; j++) + { + out_offset = add(DEPR_i_mult(j, n_codewords), i); + out_offset = sub(n_nibbles, add(out_offset, 1)); + out[out_offset >> 1] = + (UWord8)s_or(out[out_offset >> 1], shl(in[cw_offset], shl(s_and(out_offset, 1), 2))); move16(); + cw_offset = add(cw_offset, 1); + } + } + + assert(cw_offset == n_nibbles); + Dyn_Mem_Deluxe_Out(); +} + +/* Decoder */ +FEC_STATIC void fec_data_postproc(Word16 mode, Word16 *epmr, UWord8 *obuf, Word16 data_bytes, UWord8 *cw_buf, + Word16 slot_bytes, Word16 pc_split, int *bfi) +{ + Dyn_Mem_Deluxe_In( + Word16 i; + Word16 n_crc1, n_crc2; + Word16 cw_buf_len; + Word16 tmp_epmr; + ); + + n_crc1 = crc1_bytes_by_mode1[mode]; move16(); + if (sub(slot_bytes, 40) == 0) + { + n_crc1 = crc1_bytes_by_mode0[mode]; move16(); + } + + n_crc2 = 0; move16(); + if (pc_split > 0) + { + n_crc2 = crc2_bytes_by_mode[mode]; move16(); + } + + assert(n_crc1 == (slot_bytes == 40 ? crc1_bytes_by_mode0[mode] : crc1_bytes_by_mode1[mode])); + assert(n_crc2 == ((pc_split > 0) && (mode > 1) ? crc2_bytes_by_mode[mode] : 0)); + + cw_buf_len = 2 * (data_bytes + n_crc1 + n_crc2); + + IF (sub(mode, 1)) + { + /* reverse bit-swap */ + dw0_bitswap(cw_buf, mode, slot_bytes); + tmp_epmr = dw0_get_epmr(cw_buf, mode, slot_bytes); + + IF (crc1(cw_buf + shl(add(n_crc1, n_crc2), 1), sub(shl(data_bytes, 1), pc_split), tmp_epmr, cw_buf, n_crc1, 1)) + { + *bfi = 1; move32(); + + Dyn_Mem_Deluxe_Out(); + return; + } + else + { + *epmr = tmp_epmr; + } + } + + test(); + IF (pc_split > 0 && sub(*bfi, 2) != 0) + { + IF (crc2(cw_buf + sub(shl(add(data_bytes, add(n_crc1, n_crc2)), 1), pc_split), pc_split, + cw_buf + shl(n_crc1, 1), n_crc2, 1)) + { + *bfi = 2; move32(); + } + } + + FOR (i = 0; i < data_bytes; i++) + { + obuf[i] = (UWord8)s_or(cw_buf[cw_buf_len - 2 * i - 1], shl(cw_buf[cw_buf_len - 2 * i - 2], 4)); move16(); + } + Dyn_Mem_Deluxe_Out(); +} + +int fec_decoder(UWord8 *iobuf, Word16 slot_bytes, int *data_bytes, Word16 *epmr, Word16 ccc_flag, Word16 *n_pccw, + int *bfi, Word16 *be_bp_left, Word16 *be_bp_right, Word16 *n_pc, Word16 *m_fec, void *scratch) +{ + Dyn_Mem_Deluxe_In( + UWord8 *my_scratch; + UWord8 *cw_buf; + UWord8 *array_of_trust; + Word16 i, j; + Word16 cw_offset, dw_offset; + Word16 n_codewords, redundancy_nibbles, codeword_length; + Word16 mode, error_report; + Word16 n_crc; + Word16 first_bad_cw; + Word16 pc_split; + ); + + IF (*bfi == 1) + { + Dyn_Mem_Deluxe_Out(); + return ERROR_REPORT_BEC_MASK; + } + + if (slot_bytes < FEC_SLOT_BYTES_MIN || slot_bytes > FEC_SLOT_BYTES_MAX) + { + *bfi = 1; + return ERROR_REPORT_BEC_MASK; + } + + my_scratch = (UWord8 *)scratch; move32(); + cw_buf = my_scratch; move32(); + my_scratch += 2 * slot_bytes; + + IF (ccc_flag == 0) + { + *be_bp_left = -1; move16(); + *be_bp_right = -1; move16(); + } + + n_codewords = get_n_codewords(slot_bytes); + + array_of_trust = my_scratch; move32(); + my_scratch += n_codewords; + + /* extract and de-interleave nibbles */ + fec_deinterleave_unpack(cw_buf, iobuf, 2 * slot_bytes, n_codewords); + + /* mode detection and error correction */ + mode = rs16_detect_and_correct(cw_buf, 2 * slot_bytes, n_codewords, epmr, &error_report, bfi, array_of_trust, + ccc_flag, n_pccw, (void *)my_scratch); + + /* for normal slots the maximal number of bit errors is limited */ + test(); +#ifndef APPLY_MAX_ERRORS + IF (sub(slot_bytes, 40) == 0 && mode > 0) + { + IF (sub(error_report & ERROR_REPORT_BEC_MASK, low_br_max_bit_errors_by_mode[mode]) > 0) + { + error_report &= ERROR_REPORT_BEC_MASK; + mode = -1; move16(); + *bfi = 1; move32(); + } + ELSE + { + IF (sub(error_report & ERROR_REPORT_BEC_MASK, low_br_max_bit_errors_by_mode[2]) > 0) + { + error_report &= ~ERROR_REPORT_EP2_OK; + } + IF (sub(error_report & ERROR_REPORT_BEC_MASK, low_br_max_bit_errors_by_mode[3])>0) + { + error_report &= ~ERROR_REPORT_EP3_OK; + } + } + } +#endif + + IF (sub(*bfi, 1) == 0) + { + *data_bytes = 0; move16(); + + Dyn_Mem_Deluxe_Out(); + return error_report; + } + + /* initialization for decoding */ + *data_bytes = fec_get_data_size(mode, ccc_flag, slot_bytes); move32(); + pc_split = fec_get_n_pc(mode, *n_pccw, slot_bytes); + n_crc = get_total_crc_size(slot_bytes, mode, pc_split); + + /* decoding of first code word */ + redundancy_nibbles = sub(hamming_distance_by_mode0[mode], 1); + codeword_length = get_codeword_length(n_codewords, add(slot_bytes, slot_bytes), 0); + + dw_offset = 0; move16(); + cw_offset = 0; move16(); + + FOR (j = redundancy_nibbles; j < codeword_length; j++) + { + cw_buf[dw_offset++] = cw_buf[j]; move16(); + } + cw_offset = add(cw_offset, codeword_length); + + /* decoding of remaining code words */ + redundancy_nibbles = sub(hamming_distance_by_mode1[mode], 1); + + FOR (i = 1; i < n_codewords; i++) + { + codeword_length = get_codeword_length(n_codewords, add(slot_bytes, slot_bytes), i); + + FOR (j = redundancy_nibbles; j < codeword_length; j++) + { + cw_buf[dw_offset++] = cw_buf[j + cw_offset]; move16(); + } + + cw_offset = add(cw_offset, codeword_length); + } + + assert(2 * (*data_bytes + n_crc) == dw_offset && 2 * slot_bytes == cw_offset); + + /* data postproc: hash validation and re-ordering */ + + fec_data_postproc(mode, epmr, iobuf, *data_bytes, cw_buf, slot_bytes, pc_split, bfi); + + IF (sub(*bfi, 1) == 0) + { + *data_bytes = 0; move32(); + error_report &= ERROR_REPORT_BEC_MASK; + Dyn_Mem_Deluxe_Out(); + return error_report; + } + + IF (*bfi == 2) + { + first_bad_cw = 0; move16(); + array_of_trust[*n_pccw] = 0; move16(); + WHILE (array_of_trust[first_bad_cw] != 0) + { + first_bad_cw = add(first_bad_cw, 1); + } + IF (sub(first_bad_cw, *n_pccw) == 0) + { + /* this is the case when CRC failed */ + *be_bp_left = 0; move16(); + } + ELSE + { + *be_bp_left = extract_l(L_mult0(fec_get_n_pc(mode, first_bad_cw, slot_bytes), 4)); move16(); + } + + FOR (i = *n_pccw - 1; i >= 0; i--) + { + if (!array_of_trust[i]) + { + BREAK; + } + } + IF (i < 0) + { + i = sub(*n_pccw, 1); + } + *be_bp_right = sub(extract_l(L_mult0(fec_get_n_pc(mode, i+1, slot_bytes), 4)), 1); move16(); + + } + + IF (ccc_flag == 0) + { + *n_pc = pc_split; move16(); + *m_fec = mode; move16(); + } + + + Dyn_Mem_Deluxe_Out(); + return error_report; +} + +FEC_STATIC void fec_deinterleave_unpack(UWord8 *out, UWord8 *in, Word16 n_nibbles, Word16 n_codewords) +{ + Dyn_Mem_Deluxe_In( + Word16 in_offset, out_offset, codeword_length; + int i, j; + ); + + in_offset = 0; move16(); + out_offset = 0; move16(); + + /* unpack nibbles in input buffer and deinterleave codewords */ + FOR (i = 0; i < n_codewords; i++) + { + codeword_length = get_codeword_length(n_codewords, n_nibbles, i); + FOR (j = 0; j < codeword_length; (j++, out_offset++)) + { + in_offset = add(DEPR_i_mult(j, n_codewords), i); + in_offset = sub(n_nibbles, add(in_offset, 1)); + out[out_offset] = (UWord8)s_and(shr(in[in_offset >> 1], shl(s_and(in_offset, 1), 2)), 15); move16(); + } + } + + assert(out_offset == n_nibbles); + Dyn_Mem_Deluxe_Out(); +} + +FEC_STATIC Word16 fec_estimate_epmr_from_cw0(UWord8 *cw0, Word8 *t, UWord8 *syndromes, UWord8 *elp, Word8 *deg_elp, + UWord8 *err_pos, UWord8 *err_symb, Word16 n_codewords, Word16 n_symb) +{ + Dyn_Mem_Deluxe_In( + int epmr_lowest_risk_exp; + int start, inc, i, n_candidates; + int first_codeword_length; + int mode_counter; + Word16 epmr; + ); + + epmr_lowest_risk_exp = 0; + first_codeword_length = get_codeword_length(n_codewords, n_symb, 0); + start = 2; + inc = 1; + n_candidates = 0; + + /* test if first code word decodes in mode 0 or 1 without error correction */ + test(); + IF (s_or(syndromes[SYNDROME_IDX(0, 0)], syndromes[SYNDROME_IDX(0, 0) + 1]) == 0 || + s_or(syndromes[SYNDROME_IDX(1, 0)], syndromes[SYNDROME_IDX(1, 0) + 1]) == 0) + { + epmr_lowest_risk_exp = risk_table_f[1][0].exponent; move16(); + } + /* test if first code word decodes in mode 2 or 3 with lower risk */ + IF (sub(deg_elp[DEG_ELP_IDX(2, 0)], t[2]) <= 0) + { + IF (add(risk_table_f[2][deg_elp[DEG_ELP_IDX(2, 0)]].exponent, 8) <= 0) + { + n_candidates++; + start = 2; + } + } + + IF (sub(deg_elp[DEG_ELP_IDX(3, 0)], t[3]) <= 0) + { + IF (add(risk_table_f[3][deg_elp[DEG_ELP_IDX(3, 0)]].exponent, 8) <= 0) + { + n_candidates++; + start = 3; + } + } + + IF (sub(n_candidates, 1) > 0) + { + /* decide on order if mode 2 and 3 are considered */ + IF (simple_float_cmp(risk_table_f[2][deg_elp[DEG_ELP_IDX(2, 0)]], risk_table_f[3][deg_elp[DEG_ELP_IDX(3, 0)]]) < + 0) + { + start = 2; + inc = 1; + } + ELSE + { + start = 3; + inc = -1; + } + } + + FOR ((mode_counter = start, i = 0); i < n_candidates; (mode_counter += inc, i++)) + { + IF (sub(risk_table_f[mode_counter][deg_elp[DEG_ELP_IDX(mode_counter, 0)]].exponent, epmr_lowest_risk_exp) < 0) + { + IF (!rs16_factorize_elp(err_pos + ERR_POS_IDX(mode_counter, 0), elp + ELP_IDX(mode_counter, 0), + deg_elp[DEG_ELP_IDX(mode_counter, 0)], sub(first_codeword_length, 1))) + { + /* code word is decodable with error correction */ + epmr_lowest_risk_exp = risk_table_f[mode_counter][deg_elp[DEG_ELP_IDX(mode_counter, 0)]].exponent; + + rs16_calculate_errors(err_symb + ERR_SYMB_IDX(mode_counter, 0), err_pos + ERR_POS_IDX(mode_counter, 0), + syndromes + SYNDROME_IDX(mode_counter, 0), deg_elp[DEG_ELP_IDX(mode_counter, 0)], + t[mode_counter]); + + FOR (i = 0; i < deg_elp[DEG_ELP_IDX(mode_counter, 0)]; i++) + { + cw0[err_pos[ERR_POS_IDX(mode_counter, 0) + i]] = GF16_ADD( + cw0[err_pos[ERR_POS_IDX(mode_counter, 0) + i]], err_symb[ERR_SYMB_IDX(mode_counter, 0) + i]); + } + BREAK; + } + } + } + + epmr = cw0_get_epmr(cw0, sub(first_codeword_length, 1)); + + IF (add(epmr_lowest_risk_exp, 16) > 0) + { + epmr = add(epmr, 4); move16(); + } + IF (add(epmr_lowest_risk_exp, 8) > 0) + { + epmr = add(epmr, 4); move16(); + } + + Dyn_Mem_Deluxe_Out(); + return epmr; +} + +FEC_STATIC int rs16_detect_and_correct(UWord8 *iobuf, int n_symb, int n_codewords, Word16 *epmr, Word16 *error_report, + int *bfi, UWord8 *array_of_trust, int ccc_flag, Word16 *n_pccw, void *scratch) +{ + Dyn_Mem_Deluxe_In( + UWord8 * syndromes; + UWord8 * elp; + UWord8 * err_pos; + UWord8 * err_symb; + Word8 t[FEC_N_MODES]; + Word8 * deg_elp; + UWord8 * my_scratch; + UWord8 blacklist[FEC_N_MODES]; + UWord8 const *hamming_distance; + + Word16 i, cw_counter, mode_counter, cw_offset; + Word16 codeword_length; + Word16 mode; + Word16 mode_candidates[4]; + Word16 mode_broken[4]; + Word16 error_report_ep_ok[4]; + Word16 n_mode_candidates; + Word16 broken_cw, n_broken_cw; + Word16 j, idx_min; + Word16 n_pccw0; + simple_float val_min_f; + Word16 tmp; + Word16 epmr_position; + simple_float dec_risk_f[FEC_N_MODES]; + simple_float risk_min_f; + simple_float ep_risk_thresh; + + int epmr_dec_fail_increment; + + void (*syndr_calc[3])(UWord8 *, UWord8 *, int); + ); + + /* initialization */ + blacklist[0] = 0; move16(); + blacklist[1] = 0; move16(); + blacklist[2] = 0; move16(); + blacklist[3] = 0; move16(); + mode_broken[0] = 0; move16(); + mode_broken[1] = 0; move16(); + mode_broken[2] = 0; move16(); + mode_broken[3] = 0; move16(); + error_report_ep_ok[0] = ERROR_REPORT_EP1_OK; + error_report_ep_ok[1] = ERROR_REPORT_EP2_OK; + error_report_ep_ok[2] = ERROR_REPORT_EP3_OK; + error_report_ep_ok[3] = ERROR_REPORT_EP4_OK; + my_scratch = (UWord8 *)scratch; + hamming_distance = &hamming_distance_by_mode0[1]; + mode = -1; move16(); + n_mode_candidates = 0; move16(); + risk_min_f.mantissa = SIMPLE_FLOAT_1_MANTISSA; move16(); + risk_min_f.exponent = 0; move16(); + + IF (n_symb <= 80) + { + ep_risk_thresh.mantissa = EP_RISK_THRESH_NS_M; move16(); + ep_risk_thresh.exponent = EP_RISK_THRESH_NS_E; move16(); + } + ELSE + { + ep_risk_thresh.mantissa = EP_RISK_THRESH_OS_M; move16(); + ep_risk_thresh.exponent = EP_RISK_THRESH_OS_E; move16(); + } + + syndr_calc[0] = &rs16_calculate_two_syndromes; + syndr_calc[1] = &rs16_calculate_four_syndromes; + syndr_calc[2] = &rs16_calculate_six_syndromes; + + FOR (i = 0; i < FEC_N_MODES; i++) + { + t[i] = (Word8)shr(sub(hamming_distance[i], 1), 1); move16(); + } + + syndromes = my_scratch; + my_scratch += FEC_TOTAL_SYNDROME_SIZE; + elp = my_scratch; + my_scratch += FEC_TOTAL_ELP_SIZE; + err_pos = my_scratch; + my_scratch += FEC_TOTAL_ERR_POS_SIZE; + err_symb = my_scratch; + my_scratch += FEC_TOTAL_ERROR_SIZE; + deg_elp = (Word8 *)my_scratch; + my_scratch += FEC_TOTAL_DEG_ELP_SIZE; + + *error_report = 0; move16(); + *bfi = 0; move32(); + + /* mode detection (stage 1) */ + codeword_length = get_codeword_length(n_codewords, n_symb, 0); + + epmr_position = sub(codeword_length, 1); + + rs16_calculate_two_syndromes(syndromes + SYNDROME_IDX(0, 0), iobuf, sub(codeword_length, 1)); + + IF (s_or(syndromes[0 + SYNDROME_IDX(0, 0)], syndromes[1 + SYNDROME_IDX(0, 0)]) == 0) + { + + /* data validation for fec mode 1 */ + *epmr = cw0_get_epmr(iobuf, epmr_position); + + dw0_bitswap(iobuf + 2, 1, n_symb / 2); + + IF (!crc1(iobuf + 8, sub(n_symb, 8), *epmr, iobuf + 2, 3, 1)) + { + mode = 0; move16(); + *error_report |= ERROR_REPORT_ALL_OK; + Dyn_Mem_Deluxe_Out(); + return add(mode, 1); + } + ELSE + { + /* reverse bit swap */ + dw0_bitswap(iobuf + 2, 1, n_symb / 2); + + *epmr = add(*epmr, 4); move16(); + } + } + + blacklist[0] = 1; move16(); + + /* mode detection (stage 2) */ + + /* calculate syndromes of code words 0 to 5 and modes 1 to 3 */ + cw_offset = 0; move16(); + + FOR (cw_counter = 0; cw_counter < 6; cw_counter++) + { + codeword_length = get_codeword_length(n_codewords, n_symb, cw_counter); + + rs16_calculate_six_syndromes(syndromes + SYNDROME_IDX(1, cw_counter), iobuf + cw_offset, + sub(codeword_length, 1)); + + cw_offset = add(cw_offset, codeword_length); + + FOR (mode_counter = FEC_N_MODES - 1; mode_counter >= 1; mode_counter--) + { + FOR (i = 0; i < sub(hamming_distance[mode_counter], 1); i++) + { + syndromes[SYNDROME_IDX(mode_counter, cw_counter) + i] = GF16_ADD( + syndromes[SYNDROME_IDX(1, cw_counter) + i], sig_poly_syndr[mode_counter][i]); move16(); + } + } + } + + /* check for valid code words */ + FOR (mode_counter = 1; mode_counter < FEC_N_MODES; mode_counter++) + { + n_broken_cw = 0; + FOR (cw_counter = 0; cw_counter < 6; cw_counter++) + { + broken_cw = 0; + FOR (i = 0; i < sub(hamming_distance[mode_counter], 1); i++) + { + broken_cw = s_or(broken_cw, syndromes[SYNDROME_IDX(mode_counter, cw_counter) + i]); move16(); + } + IF (broken_cw != 0) + { + n_broken_cw = add(n_broken_cw, 1); + } + } + + IF (n_broken_cw == 0) + { + mode = mode_counter; move16(); + cw_offset = 0; move16(); + + *epmr = cw0_get_epmr(iobuf, epmr_position); + + FOR (cw_counter = 0; cw_counter < 6; cw_counter++) + { + codeword_length = get_codeword_length(n_codewords, n_symb, cw_counter); + FOR (i = 0; i <= EP_SIG_POLY_DEG; i++) + { + iobuf[cw_offset + i] = GF16_ADD(iobuf[cw_offset + i], sig_polys[mode][i]); + } + cw_offset = add(cw_offset, codeword_length); + } + } + } + + IF (mode < 0) /* mode hasn't been detected so far -> errors occurred in transmission */ + { + /* calculate error locator polynomials for code words 0 to 5 */ + FOR (mode_counter = 1; mode_counter < FEC_N_MODES; mode_counter++) + { + FOR (cw_counter = 0; cw_counter < 6; cw_counter++) + { + deg_elp[DEG_ELP_IDX(mode_counter, cw_counter)] = rs16_calculate_elp( + elp + ELP_IDX(mode_counter, cw_counter), syndromes + SYNDROME_IDX(mode_counter, cw_counter), + t[mode_counter]); move16(); + IF (sub(deg_elp[DEG_ELP_IDX(mode_counter, cw_counter)], t[mode_counter]) > 0) + { + blacklist[mode_counter] = 1; move16(); + BREAK; + } + } + } + + /* risk analysis for mode candidate selection */ + FOR (mode_counter = 1; mode_counter < FEC_N_MODES; mode_counter++) + { + dec_risk_f[mode_counter].mantissa = SIMPLE_FLOAT_1_MANTISSA; move16(); + dec_risk_f[mode_counter].exponent = 0; move16(); + + IF (blacklist[mode_counter] == 0) + { + FOR (cw_counter = 0; cw_counter < 6; cw_counter++) + { + dec_risk_f[mode_counter] = simple_float_mul( + dec_risk_f[mode_counter], + risk_table_f[mode_counter][deg_elp[DEG_ELP_IDX(mode_counter, cw_counter)]]); move16(); + } + + IF (simple_float_cmp(dec_risk_f[mode_counter], ep_risk_thresh) <= 0) + { + mode_candidates[n_mode_candidates++] = mode_counter; move16(); + } + + IF (simple_float_cmp(dec_risk_f[mode_counter], risk_min_f) < 0) + { + risk_min_f = dec_risk_f[mode_counter]; move16(); + } + } + } + assert(n_mode_candidates <= 4); // suppress false gcc warning when OPTIM=3 + + /* sort mode candidates by risk */ + FOR (i = 0; i < n_mode_candidates; i++) + { + idx_min = i; move16(); + val_min_f = dec_risk_f[mode_candidates[i]]; move16(); + + FOR (j = i + 1; j < n_mode_candidates; j++) + { + IF (simple_float_cmp(dec_risk_f[mode_candidates[j]], val_min_f) < 0) + { + val_min_f = dec_risk_f[mode_candidates[j]]; move16(); + idx_min = j; move16(); + } + } + + IF (sub(idx_min, i) > 0) + { + tmp = mode_candidates[i]; move16(); + mode_candidates[i] = mode_candidates[idx_min]; move16(); + mode_candidates[idx_min] = tmp; move16(); + } + } + + /* try out candidate modes */ + FOR (i = 0; i < n_mode_candidates; i++) + { + mode = mode_candidates[i]; move16(); + + FOR (cw_counter = 0; cw_counter < 6; cw_counter++) + { + codeword_length = get_codeword_length(n_codewords, n_symb, cw_counter); + + IF (deg_elp[DEG_ELP_IDX(mode, cw_counter)]) + { + IF (rs16_factorize_elp(err_pos + ERR_POS_IDX(mode, cw_counter), elp + ELP_IDX(mode, cw_counter), + deg_elp[DEG_ELP_IDX(mode, cw_counter)], sub(codeword_length, 1))) + { + /* elp did not split into distinct linear factors or error position was out of range */ + mode = -1; move16(); + BREAK; + } + } + } + IF (mode > 0) + { + /* decodable mode with lowest risk has been found */ + BREAK; + } + } + + IF (mode < 0) + { + /* no decodable mode has been found */ + *error_report = ERROR_REPORT_BEC_MASK; move16(); + *bfi = 1; move32(); + mode = -1; move16(); + + *epmr = fec_estimate_epmr_from_cw0(iobuf, t, syndromes, elp, deg_elp, err_pos, err_symb, n_codewords, + n_symb); + + Dyn_Mem_Deluxe_Out(); + return mode; + } + + /* perform error correction */ + cw_offset = 0; move16(); + *error_report = 0; move16(); + FOR (cw_counter = 0; cw_counter < 6; cw_counter++) + { + codeword_length = get_codeword_length(n_codewords, n_symb, cw_counter); + + IF (deg_elp[DEG_ELP_IDX(mode, cw_counter)]) + { + rs16_calculate_errors( + err_symb + ERR_SYMB_IDX(mode, cw_counter), err_pos + ERR_POS_IDX(mode, cw_counter), + syndromes + SYNDROME_IDX(mode, cw_counter), deg_elp[DEG_ELP_IDX(mode, cw_counter)], t[mode]); + + /* correct errors and sum up number of corrected bits */ + FOR (i = 0; i < deg_elp[DEG_ELP_IDX(mode, cw_counter)]; i++) + { + iobuf[err_pos[ERR_POS_IDX(mode, cw_counter) + i] + cw_offset] = + GF16_ADD(iobuf[err_pos[ERR_POS_IDX(mode, cw_counter) + i] + cw_offset], + err_symb[ERR_SYMB_IDX(mode, cw_counter) + i]); + *error_report = add(*error_report, + rs16_bit_count_table[err_symb[ERR_SYMB_IDX(mode, cw_counter) + i]]); move16(); + } + + FOR (i = 0; i < mode; i ++) + { + IF(deg_elp[DEG_ELP_IDX(mode, cw_counter)] > i) + { + mode_broken[i] = 1; + } + } + } + + FOR (i = 0; i <= EP_SIG_POLY_DEG; i++) + { + iobuf[cw_offset + i] = GF16_ADD(iobuf[cw_offset + i], sig_polys[mode][i]); + } + cw_offset = add(cw_offset, codeword_length); + } + + /* set epmr according to risk value of cw0 */ + epmr_dec_fail_increment = 8; + + IF (add(risk_table_f[mode][deg_elp[DEG_ELP_IDX(mode, 0)]].exponent, 8) <= 0) + { + epmr_dec_fail_increment = sub(epmr_dec_fail_increment, 4); + } + IF (add(risk_table_f[mode][deg_elp[DEG_ELP_IDX(mode, 0)]].exponent, 16) <= 0) + { + epmr_dec_fail_increment = sub(epmr_dec_fail_increment, 4); + } + + *epmr = cw0_get_epmr(iobuf, epmr_position) + epmr_dec_fail_increment; + } + + /* mode has been successfully detected -> now check and try to correct remaining code words*/ + *n_pccw = fec_get_n_pccw(n_symb / 2, mode + 1, ccc_flag); + IF (ccc_flag == 0) + { + n_pccw0 = fec_get_n_pccw(n_symb / 2, mode + 1, ccc_flag); + *n_pccw = n_pccw0; + } + ELSE + { + n_pccw0 = 0; + } + + FOR (cw_counter = 6; cw_counter < n_codewords; cw_counter++) + { + /* usual error correction scheme: syndromes -> elp's, errors, etc. */ + codeword_length = get_codeword_length(n_codewords, n_symb, cw_counter); + array_of_trust[n_codewords - 1 - cw_counter] = 1; move16(); + + syndr_calc[sub(t[mode], 1)](syndromes, iobuf + cw_offset, sub(codeword_length, 1)); + + deg_elp[0] = rs16_calculate_elp(elp, syndromes, t[mode]); move16(); + + FOR (i = 0; i < mode; i ++) + { + IF(deg_elp[0] > i) + { + mode_broken[i] = 1; + } + } + IF (sub(deg_elp[0], t[mode]) > 0) + { + FOR (i = 0; i < 4; i ++) + { + mode_broken[i] = 1; + } + cw_offset = add(cw_offset, codeword_length); + IF (cw_counter < n_codewords - n_pccw0) + { + *error_report = ERROR_REPORT_BEC_MASK; move16(); + mode = -1; move16(); + *bfi = 1; move32(); + + BREAK; + } + ELSE + { + *bfi = 2; move32(); + array_of_trust[n_codewords - 1 - cw_counter] = 0; move16(); + CONTINUE; + } + } + + IF (deg_elp[0]) + { + IF (rs16_factorize_elp(err_pos, elp, deg_elp[0], sub(codeword_length, 1))) + { + cw_offset = add(cw_offset, codeword_length); + FOR (i = 0; i < 4; i ++) + { + mode_broken[i] = 1; + } + IF (add(n_pccw0, sub(cw_counter, n_codewords)) < 0) + { + *error_report = ERROR_REPORT_BEC_MASK; move16(); + mode = -1; move16(); + *bfi = 1; move32(); + + BREAK; + } + ELSE + { + *bfi = 2; move32(); + array_of_trust[n_codewords - 1 - cw_counter] = 0; move16(); + CONTINUE; + } + } + + rs16_calculate_errors(err_symb, err_pos, syndromes, deg_elp[0], t[mode]); + + /* correct errors and sum up number of corrected bits */ + FOR (i = 0; i < deg_elp[0]; i++) + { + iobuf[err_pos[i] + cw_offset] = GF16_ADD(iobuf[err_pos[i] + cw_offset], err_symb[i]); + *error_report = add(*error_report, rs16_bit_count_table[err_symb[i]]); + } + } + cw_offset = add(cw_offset, codeword_length); + if (add(risk_table_f[mode][deg_elp[0]].exponent, 16) > 0) + { + array_of_trust[n_codewords - 1 - cw_counter] = 0; move16(); + } + } + + *error_report &= ERROR_REPORT_BEC_MASK; + FOR (i = 0; i < 4; i ++) + { + IF (!mode_broken[i]) + { + *error_report |= error_report_ep_ok[i]; + } + } + + Dyn_Mem_Deluxe_Out(); + IF (mode >= 0) + { + return add(mode, 1); + } + + return -1; +} + +FEC_STATIC void rs16_calculate_six_syndromes(UWord8 *syndromes, UWord8 *cw, int cw_poly_deg) +{ + Dyn_Mem_Deluxe_In( + int i; + UWord8 buffer[15]; + ); + + assert(cw_poly_deg >= 12); + + FOR (i = 0; i <= cw_poly_deg; i++) + { + buffer[i] = cw[i]; move16(); + } + + syndromes[0] = buffer[0]; move16(); + syndromes[1] = buffer[0]; move16(); + syndromes[2] = buffer[0]; move16(); + syndromes[3] = buffer[0]; move16(); + syndromes[4] = buffer[0]; move16(); + syndromes[5] = buffer[0]; move16(); + + syndromes[0] = GF16_ADD(syndromes[0], GF16_MUL0(buffer[1], 32)); move16(); + syndromes[1] = GF16_ADD(syndromes[1], GF16_MUL0(buffer[1], 64)); move16(); + syndromes[2] = GF16_ADD(syndromes[2], GF16_MUL0(buffer[1], 128)); move16(); + syndromes[3] = GF16_ADD(syndromes[3], GF16_MUL0(buffer[1], 48)); move16(); + syndromes[4] = GF16_ADD(syndromes[4], GF16_MUL0(buffer[1], 96)); move16(); + syndromes[5] = GF16_ADD(syndromes[5], GF16_MUL0(buffer[1], 192)); move16(); + + syndromes[0] = GF16_ADD(syndromes[0], GF16_MUL0(buffer[2], 64)); move16(); + syndromes[1] = GF16_ADD(syndromes[1], GF16_MUL0(buffer[2], 48)); move16(); + syndromes[2] = GF16_ADD(syndromes[2], GF16_MUL0(buffer[2], 192)); move16(); + syndromes[3] = GF16_ADD(syndromes[3], GF16_MUL0(buffer[2], 80)); move16(); + syndromes[4] = GF16_ADD(syndromes[4], GF16_MUL0(buffer[2], 112)); move16(); + syndromes[5] = GF16_ADD(syndromes[5], GF16_MUL0(buffer[2], 240)); move16(); + + syndromes[0] = GF16_ADD(syndromes[0], GF16_MUL0(buffer[3], 128)); move16(); + syndromes[1] = GF16_ADD(syndromes[1], GF16_MUL0(buffer[3], 192)); move16(); + syndromes[2] = GF16_ADD(syndromes[2], GF16_MUL0(buffer[3], 160)); move16(); + syndromes[3] = GF16_ADD(syndromes[3], GF16_MUL0(buffer[3], 240)); move16(); + syndromes[4] = GF16_ADD(syndromes[4], GF16_MUL0(buffer[3], 16)); move16(); + syndromes[5] = GF16_ADD(syndromes[5], GF16_MUL0(buffer[3], 128)); move16(); + + syndromes[0] = GF16_ADD(syndromes[0], GF16_MUL0(buffer[4], 48)); move16(); + syndromes[1] = GF16_ADD(syndromes[1], GF16_MUL0(buffer[4], 80)); move16(); + syndromes[2] = GF16_ADD(syndromes[2], GF16_MUL0(buffer[4], 240)); move16(); + syndromes[3] = GF16_ADD(syndromes[3], GF16_MUL0(buffer[4], 32)); move16(); + syndromes[4] = GF16_ADD(syndromes[4], GF16_MUL0(buffer[4], 96)); move16(); + syndromes[5] = GF16_ADD(syndromes[5], GF16_MUL0(buffer[4], 160)); move16(); + + syndromes[0] = GF16_ADD(syndromes[0], GF16_MUL0(buffer[5], 96)); move16(); + syndromes[1] = GF16_ADD(syndromes[1], GF16_MUL0(buffer[5], 112)); move16(); + syndromes[2] = GF16_ADD(syndromes[2], GF16_MUL0(buffer[5], 16)); move16(); + syndromes[3] = GF16_ADD(syndromes[3], GF16_MUL0(buffer[5], 96)); move16(); + syndromes[4] = GF16_ADD(syndromes[4], GF16_MUL0(buffer[5], 112)); move16(); + syndromes[5] = GF16_ADD(syndromes[5], GF16_MUL0(buffer[5], 16)); move16(); + + syndromes[0] = GF16_ADD(syndromes[0], GF16_MUL0(buffer[6], 192)); move16(); + syndromes[1] = GF16_ADD(syndromes[1], GF16_MUL0(buffer[6], 240)); move16(); + syndromes[2] = GF16_ADD(syndromes[2], GF16_MUL0(buffer[6], 128)); move16(); + syndromes[3] = GF16_ADD(syndromes[3], GF16_MUL0(buffer[6], 160)); move16(); + syndromes[4] = GF16_ADD(syndromes[4], GF16_MUL0(buffer[6], 16)); move16(); + syndromes[5] = GF16_ADD(syndromes[5], GF16_MUL0(buffer[6], 192)); move16(); + + syndromes[0] = GF16_ADD(syndromes[0], GF16_MUL0(buffer[7], 176)); move16(); + syndromes[1] = GF16_ADD(syndromes[1], GF16_MUL0(buffer[7], 144)); move16(); + syndromes[2] = GF16_ADD(syndromes[2], GF16_MUL0(buffer[7], 192)); move16(); + syndromes[3] = GF16_ADD(syndromes[3], GF16_MUL0(buffer[7], 208)); move16(); + syndromes[4] = GF16_ADD(syndromes[4], GF16_MUL0(buffer[7], 96)); move16(); + syndromes[5] = GF16_ADD(syndromes[5], GF16_MUL0(buffer[7], 240)); move16(); + + syndromes[0] = GF16_ADD(syndromes[0], GF16_MUL0(buffer[8], 80)); move16(); + syndromes[1] = GF16_ADD(syndromes[1], GF16_MUL0(buffer[8], 32)); move16(); + syndromes[2] = GF16_ADD(syndromes[2], GF16_MUL0(buffer[8], 160)); move16(); + syndromes[3] = GF16_ADD(syndromes[3], GF16_MUL0(buffer[8], 64)); move16(); + syndromes[4] = GF16_ADD(syndromes[4], GF16_MUL0(buffer[8], 112)); move16(); + syndromes[5] = GF16_ADD(syndromes[5], GF16_MUL0(buffer[8], 128)); move16(); + + syndromes[0] = GF16_ADD(syndromes[0], GF16_MUL0(buffer[9], 160)); move16(); + syndromes[1] = GF16_ADD(syndromes[1], GF16_MUL0(buffer[9], 128)); move16(); + syndromes[2] = GF16_ADD(syndromes[2], GF16_MUL0(buffer[9], 240)); move16(); + syndromes[3] = GF16_ADD(syndromes[3], GF16_MUL0(buffer[9], 192)); move16(); + syndromes[4] = GF16_ADD(syndromes[4], GF16_MUL0(buffer[9], 16)); move16(); + syndromes[5] = GF16_ADD(syndromes[5], GF16_MUL0(buffer[9], 160)); move16(); + + syndromes[0] = GF16_ADD(syndromes[0], GF16_MUL0(buffer[10], 112)); move16(); + syndromes[1] = GF16_ADD(syndromes[1], GF16_MUL0(buffer[10], 96)); move16(); + syndromes[2] = GF16_ADD(syndromes[2], GF16_MUL0(buffer[10], 16)); move16(); + syndromes[3] = GF16_ADD(syndromes[3], GF16_MUL0(buffer[10], 112)); move16(); + syndromes[4] = GF16_ADD(syndromes[4], GF16_MUL0(buffer[10], 96)); move16(); + syndromes[5] = GF16_ADD(syndromes[5], GF16_MUL0(buffer[10], 16)); move16(); + + syndromes[0] = GF16_ADD(syndromes[0], GF16_MUL0(buffer[11], 224)); move16(); + syndromes[1] = GF16_ADD(syndromes[1], GF16_MUL0(buffer[11], 176)); move16(); + syndromes[2] = GF16_ADD(syndromes[2], GF16_MUL0(buffer[11], 128)); move16(); + syndromes[3] = GF16_ADD(syndromes[3], GF16_MUL0(buffer[11], 144)); move16(); + syndromes[4] = GF16_ADD(syndromes[4], GF16_MUL0(buffer[11], 112)); move16(); + syndromes[5] = GF16_ADD(syndromes[5], GF16_MUL0(buffer[11], 192)); move16(); + + syndromes[0] = GF16_ADD(syndromes[0], GF16_MUL0(buffer[12], 240)); move16(); + syndromes[1] = GF16_ADD(syndromes[1], GF16_MUL0(buffer[12], 160)); move16(); + syndromes[2] = GF16_ADD(syndromes[2], GF16_MUL0(buffer[12], 192)); move16(); + syndromes[3] = GF16_ADD(syndromes[3], GF16_MUL0(buffer[12], 128)); move16(); + syndromes[4] = GF16_ADD(syndromes[4], GF16_MUL0(buffer[12], 16)); move16(); + syndromes[5] = GF16_ADD(syndromes[5], GF16_MUL0(buffer[12], 240)); move16(); + + IF (sub(cw_poly_deg, 13) >= 0) + { + syndromes[0] = GF16_ADD(syndromes[0], GF16_MUL0(buffer[13], 208)); move16(); + syndromes[1] = GF16_ADD(syndromes[1], GF16_MUL0(buffer[13], 224)); move16(); + syndromes[2] = GF16_ADD(syndromes[2], GF16_MUL0(buffer[13], 160)); move16(); + syndromes[3] = GF16_ADD(syndromes[3], GF16_MUL0(buffer[13], 176)); move16(); + syndromes[4] = GF16_ADD(syndromes[4], GF16_MUL0(buffer[13], 96)); move16(); + syndromes[5] = GF16_ADD(syndromes[5], GF16_MUL0(buffer[13], 128)); move16(); + } + + IF (sub(cw_poly_deg, 14) >= 0) + { + syndromes[0] = GF16_ADD(syndromes[0], GF16_MUL0(buffer[14], 144)); move16(); + syndromes[1] = GF16_ADD(syndromes[1], GF16_MUL0(buffer[14], 208)); move16(); + syndromes[2] = GF16_ADD(syndromes[2], GF16_MUL0(buffer[14], 240)); move16(); + syndromes[3] = GF16_ADD(syndromes[3], GF16_MUL0(buffer[14], 224)); move16(); + syndromes[4] = GF16_ADD(syndromes[4], GF16_MUL0(buffer[14], 112)); move16(); + syndromes[5] = GF16_ADD(syndromes[5], GF16_MUL0(buffer[14], 160)); move16(); + } + + Dyn_Mem_Deluxe_Out(); +} + +FEC_STATIC void rs16_calculate_four_syndromes(UWord8 *syndromes, UWord8 *cw, int cw_poly_deg) +{ + Dyn_Mem_Deluxe_In( + int i; + UWord8 buffer[15]; + ); + + assert(cw_poly_deg >= 12); + + FOR (i = 0; i <= cw_poly_deg; i++) + { + buffer[i] = cw[i]; move16(); + } + + syndromes[0] = buffer[0]; move16(); + syndromes[1] = buffer[0]; move16(); + syndromes[2] = buffer[0]; move16(); + syndromes[3] = buffer[0]; move16(); + + syndromes[0] = GF16_ADD(syndromes[0], GF16_MUL0(buffer[1], 32)); move16(); + syndromes[1] = GF16_ADD(syndromes[1], GF16_MUL0(buffer[1], 64)); move16(); + syndromes[2] = GF16_ADD(syndromes[2], GF16_MUL0(buffer[1], 128)); move16(); + syndromes[3] = GF16_ADD(syndromes[3], GF16_MUL0(buffer[1], 48)); move16(); + + syndromes[0] = GF16_ADD(syndromes[0], GF16_MUL0(buffer[2], 64)); move16(); + syndromes[1] = GF16_ADD(syndromes[1], GF16_MUL0(buffer[2], 48)); move16(); + syndromes[2] = GF16_ADD(syndromes[2], GF16_MUL0(buffer[2], 192)); move16(); + syndromes[3] = GF16_ADD(syndromes[3], GF16_MUL0(buffer[2], 80)); move16(); + + syndromes[0] = GF16_ADD(syndromes[0], GF16_MUL0(buffer[3], 128)); move16(); + syndromes[1] = GF16_ADD(syndromes[1], GF16_MUL0(buffer[3], 192)); move16(); + syndromes[2] = GF16_ADD(syndromes[2], GF16_MUL0(buffer[3], 160)); move16(); + syndromes[3] = GF16_ADD(syndromes[3], GF16_MUL0(buffer[3], 240)); move16(); + + syndromes[0] = GF16_ADD(syndromes[0], GF16_MUL0(buffer[4], 48)); move16(); + syndromes[1] = GF16_ADD(syndromes[1], GF16_MUL0(buffer[4], 80)); move16(); + syndromes[2] = GF16_ADD(syndromes[2], GF16_MUL0(buffer[4], 240)); move16(); + syndromes[3] = GF16_ADD(syndromes[3], GF16_MUL0(buffer[4], 32)); move16(); + + syndromes[0] = GF16_ADD(syndromes[0], GF16_MUL0(buffer[5], 96)); move16(); + syndromes[1] = GF16_ADD(syndromes[1], GF16_MUL0(buffer[5], 112)); move16(); + syndromes[2] = GF16_ADD(syndromes[2], GF16_MUL0(buffer[5], 16)); move16(); + syndromes[3] = GF16_ADD(syndromes[3], GF16_MUL0(buffer[5], 96)); move16(); + + syndromes[0] = GF16_ADD(syndromes[0], GF16_MUL0(buffer[6], 192)); move16(); + syndromes[1] = GF16_ADD(syndromes[1], GF16_MUL0(buffer[6], 240)); move16(); + syndromes[2] = GF16_ADD(syndromes[2], GF16_MUL0(buffer[6], 128)); move16(); + syndromes[3] = GF16_ADD(syndromes[3], GF16_MUL0(buffer[6], 160)); move16(); + + syndromes[0] = GF16_ADD(syndromes[0], GF16_MUL0(buffer[7], 176)); move16(); + syndromes[1] = GF16_ADD(syndromes[1], GF16_MUL0(buffer[7], 144)); move16(); + syndromes[2] = GF16_ADD(syndromes[2], GF16_MUL0(buffer[7], 192)); move16(); + syndromes[3] = GF16_ADD(syndromes[3], GF16_MUL0(buffer[7], 208)); move16(); + + syndromes[0] = GF16_ADD(syndromes[0], GF16_MUL0(buffer[8], 80)); move16(); + syndromes[1] = GF16_ADD(syndromes[1], GF16_MUL0(buffer[8], 32)); move16(); + syndromes[2] = GF16_ADD(syndromes[2], GF16_MUL0(buffer[8], 160)); move16(); + syndromes[3] = GF16_ADD(syndromes[3], GF16_MUL0(buffer[8], 64)); move16(); + + syndromes[0] = GF16_ADD(syndromes[0], GF16_MUL0(buffer[9], 160)); move16(); + syndromes[1] = GF16_ADD(syndromes[1], GF16_MUL0(buffer[9], 128)); move16(); + syndromes[2] = GF16_ADD(syndromes[2], GF16_MUL0(buffer[9], 240)); move16(); + syndromes[3] = GF16_ADD(syndromes[3], GF16_MUL0(buffer[9], 192)); move16(); + + syndromes[0] = GF16_ADD(syndromes[0], GF16_MUL0(buffer[10], 112)); move16(); + syndromes[1] = GF16_ADD(syndromes[1], GF16_MUL0(buffer[10], 96)); move16(); + syndromes[2] = GF16_ADD(syndromes[2], GF16_MUL0(buffer[10], 16)); move16(); + syndromes[3] = GF16_ADD(syndromes[3], GF16_MUL0(buffer[10], 112)); move16(); + + syndromes[0] = GF16_ADD(syndromes[0], GF16_MUL0(buffer[11], 224)); move16(); + syndromes[1] = GF16_ADD(syndromes[1], GF16_MUL0(buffer[11], 176)); move16(); + syndromes[2] = GF16_ADD(syndromes[2], GF16_MUL0(buffer[11], 128)); move16(); + syndromes[3] = GF16_ADD(syndromes[3], GF16_MUL0(buffer[11], 144)); move16(); + + syndromes[0] = GF16_ADD(syndromes[0], GF16_MUL0(buffer[12], 240)); move16(); + syndromes[1] = GF16_ADD(syndromes[1], GF16_MUL0(buffer[12], 160)); move16(); + syndromes[2] = GF16_ADD(syndromes[2], GF16_MUL0(buffer[12], 192)); move16(); + syndromes[3] = GF16_ADD(syndromes[3], GF16_MUL0(buffer[12], 128)); move16(); + + IF (sub(cw_poly_deg, 13) >= 0) + { + syndromes[0] = GF16_ADD(syndromes[0], GF16_MUL0(buffer[13], 208)); move16(); + syndromes[1] = GF16_ADD(syndromes[1], GF16_MUL0(buffer[13], 224)); move16(); + syndromes[2] = GF16_ADD(syndromes[2], GF16_MUL0(buffer[13], 160)); move16(); + syndromes[3] = GF16_ADD(syndromes[3], GF16_MUL0(buffer[13], 176)); move16(); + } + + IF (sub(cw_poly_deg, 14) >= 0) + { + syndromes[0] = GF16_ADD(syndromes[0], GF16_MUL0(buffer[14], 144)); move16(); + syndromes[1] = GF16_ADD(syndromes[1], GF16_MUL0(buffer[14], 208)); move16(); + syndromes[2] = GF16_ADD(syndromes[2], GF16_MUL0(buffer[14], 240)); move16(); + syndromes[3] = GF16_ADD(syndromes[3], GF16_MUL0(buffer[14], 224)); move16(); + } + + Dyn_Mem_Deluxe_Out(); +} + +FEC_STATIC void rs16_calculate_two_syndromes(UWord8 *syndromes, UWord8 *cw, int cw_poly_deg) +{ + Dyn_Mem_Deluxe_In( + int i; + UWord8 buffer[15]; + ); + + assert(cw_poly_deg >= 12); + + FOR (i = 0; i <= cw_poly_deg; i++) + { + buffer[i] = cw[i]; move16(); + } + + syndromes[0] = buffer[0]; move16(); + syndromes[1] = buffer[0]; move16(); + + syndromes[0] = GF16_ADD(syndromes[0], GF16_MUL0(buffer[1], 32)); move16(); + syndromes[1] = GF16_ADD(syndromes[1], GF16_MUL0(buffer[1], 64)); move16(); + + syndromes[0] = GF16_ADD(syndromes[0], GF16_MUL0(buffer[2], 64)); move16(); + syndromes[1] = GF16_ADD(syndromes[1], GF16_MUL0(buffer[2], 48)); move16(); + + syndromes[0] = GF16_ADD(syndromes[0], GF16_MUL0(buffer[3], 128)); move16(); + syndromes[1] = GF16_ADD(syndromes[1], GF16_MUL0(buffer[3], 192)); move16(); + + syndromes[0] = GF16_ADD(syndromes[0], GF16_MUL0(buffer[4], 48)); move16(); + syndromes[1] = GF16_ADD(syndromes[1], GF16_MUL0(buffer[4], 80)); move16(); + + syndromes[0] = GF16_ADD(syndromes[0], GF16_MUL0(buffer[5], 96)); move16(); + syndromes[1] = GF16_ADD(syndromes[1], GF16_MUL0(buffer[5], 112)); move16(); + + syndromes[0] = GF16_ADD(syndromes[0], GF16_MUL0(buffer[6], 192)); move16(); + syndromes[1] = GF16_ADD(syndromes[1], GF16_MUL0(buffer[6], 240)); move16(); + + syndromes[0] = GF16_ADD(syndromes[0], GF16_MUL0(buffer[7], 176)); move16(); + syndromes[1] = GF16_ADD(syndromes[1], GF16_MUL0(buffer[7], 144)); move16(); + + syndromes[0] = GF16_ADD(syndromes[0], GF16_MUL0(buffer[8], 80)); move16(); + syndromes[1] = GF16_ADD(syndromes[1], GF16_MUL0(buffer[8], 32)); move16(); + + syndromes[0] = GF16_ADD(syndromes[0], GF16_MUL0(buffer[9], 160)); move16(); + syndromes[1] = GF16_ADD(syndromes[1], GF16_MUL0(buffer[9], 128)); move16(); + + syndromes[0] = GF16_ADD(syndromes[0], GF16_MUL0(buffer[10], 112)); move16(); + syndromes[1] = GF16_ADD(syndromes[1], GF16_MUL0(buffer[10], 96)); move16(); + + syndromes[0] = GF16_ADD(syndromes[0], GF16_MUL0(buffer[11], 224)); move16(); + syndromes[1] = GF16_ADD(syndromes[1], GF16_MUL0(buffer[11], 176)); move16(); + + syndromes[0] = GF16_ADD(syndromes[0], GF16_MUL0(buffer[12], 240)); move16(); + syndromes[1] = GF16_ADD(syndromes[1], GF16_MUL0(buffer[12], 160)); move16(); + + IF (sub(cw_poly_deg, 13) >= 0) + { + syndromes[0] = GF16_ADD(syndromes[0], GF16_MUL0(buffer[13], 208)); move16(); + syndromes[1] = GF16_ADD(syndromes[1], GF16_MUL0(buffer[13], 224)); move16(); + } + + IF (sub(cw_poly_deg, 14) >= 0) + { + syndromes[0] = GF16_ADD(syndromes[0], GF16_MUL0(buffer[14], 144)); move16(); + syndromes[1] = GF16_ADD(syndromes[1], GF16_MUL0(buffer[14], 208)); move16(); + } + + Dyn_Mem_Deluxe_Out(); +} + +FEC_STATIC Word8 rs16_calculate_elp(UWord8 *elp, UWord8 *syndromes, Word16 t) +/* calculates error locator polynomial vie Petterson's algorithm */ +{ + Dyn_Mem_Deluxe_In( + Word8 ret; + UWord8 det, det_inv, aux, all_s, *s; + UWord8 s22, s33, s44, s13, s14, s15; + UWord8 s23, s24, s25, s34, s35; + UWord8 a, b, c, d, e, f; + ); + + ret = 0; move16(); + all_s = 0; move16(); + s = syndromes; move16(); + elp[0] = 1; move16(); + basop_memset(elp + 1, 0, 3); + + SWITCH (t) + { + case 3: + { + /* check for errors */ + all_s = (UWord8)s_or(s[0], s_or(s[1], s_or(s[2], s_or(s[3], s_or(s[4], s[5]))))); + + IF (all_s == 0) + { + BREAK; + } + + /* assume 3 errors */ + s22 = GF16_MUL(s[1], s[1]); + s33 = GF16_MUL(s[2], s[2]); + s44 = GF16_MUL(s[3], s[3]); + s13 = GF16_MUL(s[0], s[2]); + + det = GF16_ADD(GF16_ADD(GF16_MUL(s13, s[4]), GF16_MUL(s44, s[0])), + GF16_ADD(GF16_MUL(s22, s[4]), GF16_MUL(s33, s[2]))); + + IF (det) + { + det_inv = (UWord8)shl(gf16_inv_table[det], 4); + + s14 = GF16_MUL(s[0], s[3]); + s15 = GF16_MUL(s[0], s[4]); + + s23 = GF16_MUL(s[1], s[2]); + s24 = GF16_MUL(s[1], s[3]); + s25 = GF16_MUL(s[1], s[4]); + + s34 = GF16_MUL(s[2], s[3]); + s35 = GF16_MUL(s[2], s[4]); + + a = GF16_ADD(s35, s44) << 4; + b = GF16_ADD(s15, s33) << 4; + c = GF16_ADD(s13, s22) << 4; + d = GF16_ADD(s34, s25) << 4; + e = GF16_ADD(s23, s14) << 4; + f = GF16_ADD(s24, s33) << 4; + + aux = GF16_ADD(GF16_ADD(GF16_MUL0(a, s[3]), GF16_MUL0(d, s[4])), GF16_MUL0(f, s[5])); + elp[3] = GF16_MUL0(aux, det_inv); + + aux = GF16_ADD(GF16_ADD(GF16_MUL0(d, s[3]), GF16_MUL0(b, s[4])), GF16_MUL0(e, s[5])); + elp[2] = GF16_MUL0(aux, det_inv); + + aux = GF16_ADD(GF16_ADD(GF16_MUL0(f, s[3]), GF16_MUL0(e, s[4])), GF16_MUL0(c, s[5])); + elp[1] = GF16_MUL0(aux, det_inv); + + IF (elp[3] == 0) + { + ret = (Word8) add(t, 1); + } + ELSE + { + ret = 3; move16(); + } + BREAK; + } + + /* assume two errors */ + det = GF16_ADD(GF16_MUL(syndromes[0], syndromes[2]), GF16_MUL(syndromes[1], syndromes[1])); + + IF (det) + { + det_inv = (UWord8)shl(gf16_inv_table[det], 4); + + aux = GF16_ADD(GF16_MUL(syndromes[1], syndromes[2]), GF16_MUL(syndromes[0], syndromes[3])); + elp[1] = GF16_MUL0(aux, det_inv); + + aux = GF16_ADD(GF16_MUL(syndromes[2], syndromes[2]), GF16_MUL(syndromes[1], syndromes[3])); + elp[2] = GF16_MUL0(aux, det_inv); + + /* check remaining LSF relations */ + aux = (UWord8)s_or(GF16_ADD(GF16_ADD(GF16_MUL(elp[2], s[2]), GF16_MUL(elp[1], s[3])), s[4]), + GF16_ADD(GF16_ADD(GF16_MUL(elp[2], s[3]), GF16_MUL(elp[1], s[4])), s[5])); + + aux = (UWord8)s_or(aux, elp[2] == 0); + + IF (aux != 0) + { + ret = (Word8) add(t, 1); + } + ELSE + { + ret = 2; move16(); + } + BREAK; + } + + /* assume one error */ + IF (syndromes[0] != 0) + { + elp[1] = GF16_MUL(syndromes[1], gf16_inv_table[syndromes[0]]); + + /* check remaining LSF relations */ + aux = (UWord8)s_or(s_or(GF16_ADD(GF16_MUL(elp[1], s[1]), s[2]), GF16_ADD(GF16_MUL(elp[1], s[2]), s[3])), + s_or(GF16_ADD(GF16_MUL(elp[1], s[3]), s[4]), GF16_ADD(GF16_MUL(elp[1], s[4]), s[5]))); + + aux = (UWord8)s_or(aux, elp[1] == 0); + + IF (aux != 0) + { + ret = (Word8) add(t, 1); + } + ELSE + { + ret = 1; move16(); + } + BREAK; + } + + ret = (Word8) add(t, 1); + BREAK; + } + case 2: + { + all_s = (UWord8)s_or(s[0], s_or(s[1], s_or(s[2], s[3]))); + + IF (all_s == 0) + { + BREAK; + } + + /* assume two errors */ + det = GF16_ADD(GF16_MUL(syndromes[0], syndromes[2]), GF16_MUL(syndromes[1], syndromes[1])); + + IF (det) + { + det_inv = (UWord8)shl(gf16_inv_table[det], 4); + + aux = GF16_ADD(GF16_MUL(syndromes[1], syndromes[2]), GF16_MUL(syndromes[0], syndromes[3])); + elp[1] = GF16_MUL0(aux, det_inv); + + aux = GF16_ADD(GF16_MUL(syndromes[2], syndromes[2]), GF16_MUL(syndromes[1], syndromes[3])); + elp[2] = GF16_MUL0(aux, det_inv); + + IF (elp[2] == 0) + { + ret = (Word8) add(t, 1); + } + ELSE + { + ret = 2; move16(); + } + BREAK; + } + + /* assume one error */ + IF (syndromes[0] != 0) + { + elp[1] = GF16_MUL(syndromes[1], gf16_inv_table[syndromes[0]]); + + /* check remaining LSF relation */ + aux = (UWord8)s_or(GF16_ADD(GF16_MUL(elp[1], s[1]), s[2]), GF16_ADD(GF16_MUL(elp[1], s[2]), s[3])); + aux = (UWord8)s_or(aux, elp[1] == 0); + IF (aux != 0) + { + ret = (Word8) add(t, 1); + } + ELSE + { + ret = 1; move16(); + } + BREAK; + } + + ret = (Word8) add(t, 1); + BREAK; + } + case 1: + { + all_s = (UWord8)s_or(s[0], s[1]); + + IF (all_s == 0) + { + BREAK; + } + + IF (syndromes[0] != 0) + { + elp[1] = GF16_MUL(syndromes[1], gf16_inv_table[syndromes[0]]); + IF (elp[1] == 0) + { + ret = (Word8) add(t, 1); + } + ELSE + { + ret = 1; move16(); + } + BREAK; + } + + ret = (Word8) add(t, 1); + BREAK; + } + default: assert(0 && "calculating elp of this degree not implemented"); + } + + Dyn_Mem_Deluxe_Out(); + return ret; +} + +FEC_STATIC Word16 rs16_factorize_elp(UWord8 *err_pos, UWord8 *elp, Word16 deg_elp, Word16 max_pos) +{ + Dyn_Mem_Deluxe_In( + UWord8 beta, gamma; + Word16 zeros, err_pos0, err_pos1, err_pos2, ret; + ); + + beta = 0; move16(); + gamma = 0; move16(); + zeros = 0; move16(); + ret = 0; move16(); + + SWITCH (deg_elp) + { + case 0: BREAK; + + case 1: + err_pos0 = gf16_log_g[elp[1]]; move16(); + IF (sub(err_pos0, max_pos) > 0) + { + ret = 1; move16(); + BREAK; + } + + err_pos[0] = (UWord8)err_pos0; move16(); + BREAK; + + case 2: + zeros = rs16_elp_deg2_table[s_or(elp[1], shl(elp[2], 4))]; move16(); + IF (zeros == 0) + { + Dyn_Mem_Deluxe_Out(); + return 1; + } + + err_pos0 = s_and(zeros, 15); + err_pos1 = s_and(shr(zeros, 4), 15); + + IF (sub(err_pos0, max_pos) > 0 || sub(err_pos1, max_pos) > 0) + { + ret = 1; move16(); + BREAK; + } + + err_pos[0] = (UWord8)err_pos0; move16(); + err_pos[1] = (UWord8)err_pos1; move16(); + BREAK; + + case 3: + /* beta = a*a + b, gamma = a*b + c */ + beta = GF16_ADD(GF16_MUL(elp[1], elp[1]), elp[2]); + gamma = GF16_ADD(GF16_MUL(elp[1], elp[2]), elp[3]); + zeros = rs16_elp_deg3_table[beta | gamma << 4]; + + IF (zeros == 0) + /* elp does not split over GF(16) or has multiple zeros */ + { + ret = 1; move16(); + BREAK; + } + + /* remove shift from zeros */ + err_pos0 = GF16_ADD(s_and(zeros, 15), elp[1]); + err_pos1 = GF16_ADD(s_and(shr(zeros, 4), 15), elp[1]); + err_pos2 = GF16_ADD(s_and(shr(zeros, 8), 15), elp[1]); + + IF (err_pos0 == 0 || err_pos1 == 0 || err_pos2 == 0) + { + test(); test(); + Dyn_Mem_Deluxe_Out(); + return 1; + } + + err_pos0 = gf16_log_g[err_pos0]; + err_pos1 = gf16_log_g[err_pos1]; + err_pos2 = gf16_log_g[err_pos2]; + + IF (sub(err_pos0, max_pos) > 0 || sub(err_pos1, max_pos) > 0 || sub(err_pos2, max_pos) > 0) + { + test(); test(); + ret = 1; move16(); + BREAK; + } + + err_pos[0] = (UWord8)err_pos0; move16(); + err_pos[1] = (UWord8)err_pos1; move16(); + err_pos[2] = (UWord8)err_pos2; move16(); + + BREAK; + + default: assert(0 && "invalid degree in rs16_error_locator"); + } + + Dyn_Mem_Deluxe_Out(); + return ret; +} + +FEC_STATIC void rs16_calculate_errors(UWord8 *err_symb, UWord8 *err_pos, UWord8 *syndromes, Word8 deg_elp, Word8 t) +{ + Dyn_Mem_Deluxe_In( + UWord8 det_inv; + UWord8 x0, x1, x2; + UWord8 x0sq, x1sq, x2sq; + UWord8 c0, c1, c2; + UWord8 s0, s1, s2; + UWord8 tmp; + ); + + assert(deg_elp <= t); + UNUSED(t); + + SWITCH (deg_elp) + { + case 0: BREAK; + + case 1: + err_symb[0] = GF16_MUL(gf16_g_pow[15 - err_pos[0]], syndromes[0]); move16(); + + BREAK; + + case 2: + s0 = (UWord8)shl(syndromes[0], 4); + s1 = (UWord8)shl(syndromes[1], 4); + + x0 = gf16_g_pow[err_pos[0]]; move16(); + x1 = gf16_g_pow[err_pos[1]]; move16(); + + x0sq = GF16_MUL(x0, x0); + x1sq = GF16_MUL(x1, x1); + + tmp = GF16_ADD(GF16_MUL(x0sq, x1), GF16_MUL(x1sq, x0)); + det_inv = (UWord8)shl(gf16_inv_table[tmp], 4); + + tmp = GF16_ADD(GF16_MUL0(x1sq, s0), GF16_MUL0(x1, s1)); + err_symb[0] = GF16_MUL0(tmp, det_inv); move16(); + + tmp = GF16_ADD(GF16_MUL0(x0sq, s0), GF16_MUL0(x0, s1)); + err_symb[1] = GF16_MUL0(tmp, det_inv); move16(); + + BREAK; + + case 3: + s0 = (UWord8)shl(syndromes[0], 4); + s1 = (UWord8)shl(syndromes[1], 4); + s2 = (UWord8)shl(syndromes[2], 4); + + x0 = gf16_g_pow[err_pos[0]]; move16(); + x1 = gf16_g_pow[err_pos[1]]; move16(); + x2 = gf16_g_pow[err_pos[2]]; move16(); + + x0sq = GF16_MUL(x0, x0); + x1sq = GF16_MUL(x1, x1); + x2sq = GF16_MUL(x2, x2); + + tmp = GF16_MUL(GF16_ADD(x1, x0), GF16_ADD(x2, x0)); + tmp = GF16_MUL(GF16_ADD(x2, x1), tmp); + det_inv = (UWord8)shl(gf16_inv_table[tmp], 4); + + c0 = GF16_ADD(GF16_MUL(x1, x2sq), GF16_MUL(x2, x1sq)); + c1 = GF16_ADD(x2sq, x1sq); + c2 = GF16_ADD(x2, x1); + + err_symb[0] = GF16_ADD(GF16_ADD(GF16_MUL0(c0, s0), GF16_MUL0(c1, s1)), GF16_MUL0(c2, s2)); move16(); + + c0 = GF16_ADD(GF16_MUL(x0, x2sq), GF16_MUL(x2, x0sq)); + c1 = GF16_ADD(x2sq, x0sq); + c2 = GF16_ADD(x2, x0); + + err_symb[1] = GF16_ADD(GF16_ADD(GF16_MUL0(c0, s0), GF16_MUL0(c1, s1)), GF16_MUL0(c2, s2)); move16(); + + c0 = GF16_ADD(GF16_MUL(x0, x1sq), GF16_MUL(x1, x0sq)); + c1 = GF16_ADD(x1sq, x0sq); + c2 = GF16_ADD(x1, x0); + + err_symb[2] = GF16_ADD(GF16_ADD(GF16_MUL0(c0, s0), GF16_MUL0(c1, s1)), GF16_MUL0(c2, s2)); move16(); + + tmp = GF16_MUL0(err_symb[0], det_inv); + err_symb[0] = GF16_MUL(tmp, gf16_inv_table[x0]); move16(); + + tmp = GF16_MUL0(err_symb[1], det_inv); + err_symb[1] = GF16_MUL(tmp, gf16_inv_table[x1]); move16(); + + tmp = GF16_MUL0(err_symb[2], det_inv); + err_symb[2] = GF16_MUL(tmp, gf16_inv_table[x2]); move16(); + + BREAK; + + default: assert(0 && "method not implemented\n"); BREAK; + } + + Dyn_Mem_Deluxe_Out(); +} + +/* hash functions for data validation */ + +/* hamming distance 4 */ +static const UWord32 crc14_mask[16] = {0, 17989, 35978, 51919, 71956, 89937, 103838, 119771, + 143912, 160877, 179874, 194791, 207676, 224633, 239542, 254451}; + +/* hamming distance 4 */ +static const UWord32 crc22_mask[16] = {0, 4788009, 9576018, 14356859, 19152036, 23933837, 28713718, 33500639, + 33650273, 38304072, 43214899, 47867674, 52775621, 57427436, 62346391, 67001278}; + +FEC_STATIC Word16 crc1(UWord8 *data, Word16 data_size, Word16 epmr, UWord8 *hash, Word16 hash_size, Word16 check) +{ + Dyn_Mem_Deluxe_In( + UWord32 const *mask; + int shift, i, fail; + UWord32 rem; + ); + + fail = 0; move16(); + rem = 0; move16(); + + assert(hash_size > 0); + + SWITCH (hash_size) + { + case 2: + shift = 14; move16(); + mask = crc14_mask; move32(); + BREAK; + case 3: + shift = 22; move16(); + mask = crc22_mask; move32(); + BREAK; + default: + shift = 0; + mask = 0; + assert(0 && "crc hash size not implemented"); + } + + /* data array contains 4-bit words */ + FOR (i = data_size - 1; i >= 0; i--) + { + rem = UL_xor(UL_lshl(rem, 4), data[i]); move32(); + rem = UL_xor(rem, mask[UL_and(UL_lshr(rem, shift), 15)]); move32(); + } + + rem = UL_xor(UL_lshl(rem, 4), UL_lshl(epmr, 2)); + rem = UL_xor(rem, mask[UL_and(UL_lshr(rem, shift), 15)]); move32(); + + FOR (i = 0; i < 2 * hash_size - 1; i++) + { + rem = UL_lshl(rem, 4); + rem = UL_xor(rem, mask[UL_and(UL_lshr(rem, shift), 15)]); move32(); + } + + rem = UL_xor(rem, UL_lshl((UWord32)epmr, shift)); move32(); + + IF (check) + { + /* test hash value */ + FOR (i = 0; i < 2 * hash_size; i++) + { + fail = s_or(fail, UL_xor(hash[i], UL_and(UL_lshr(rem, shl(i, 2)), 15))); move32(); + } + } + ELSE + { + /* write hash value */ + for (i = 0; i < 2 * hash_size; i++) + { + hash[i] = (UWord8)UL_and(UL_lshr(rem, shl(i, 2)), 15); move32(); + } + } + + Dyn_Mem_Deluxe_Out(); + return fail; +} + +/* hamming distance = 4 */ +static const UWord32 crc16_mask[16] = {0, 107243, 190269, 214486, 289937, 380538, 428972, 469319, + 579874, 621513, 671263, 761076, 832947, 857944, 938638, 1044581}; + +FEC_STATIC Word16 crc2(UWord8 *data, Word16 data_size, UWord8 *hash, Word16 hash_size, Word16 check) +{ + Dyn_Mem_Deluxe_In( + UWord32 const *mask; + int shift, i, fail; + UWord32 rem; + ); + + fail = 0; move16(); + rem = 0; move16(); + + assert(hash_size > 0); + + SWITCH (hash_size) + { + case 2: + shift = 16; move16(); + mask = crc16_mask; move32(); + BREAK; + default: + shift = 0; + mask = 0; + assert(0 && "crc hash size not implemented"); + } + + /* data array contains 4-bit words */ + FOR (i = data_size - 1; i >= 0; i--) + { + rem = UL_xor(UL_lshl(rem, 4), data[i]); move32(); + rem = UL_xor(rem, mask[UL_and(UL_lshr(rem, shift), 15)]); move32(); + } + + FOR (i = 0; i < 2 * hash_size; i++) + { + rem = UL_lshl(rem, 4); + rem = UL_xor(rem, mask[UL_and(UL_lshr(rem, shift), 15)]); move32(); + } + + IF (check) + { + /* test hash value */ + FOR (i = 0; i < 2 * hash_size; i++) + { + fail = s_or(fail, UL_xor(hash[i], UL_and(UL_lshr(rem, shl(i, 2)), 15))); move32(); + } + } + ELSE + { + /* write hash value */ + FOR (i = 0; i < 2 * hash_size; i++) + { + hash[i] = (UWord8)UL_and(UL_lshr(rem, shl(i, 2)), 15); move32(); + } + } + + Dyn_Mem_Deluxe_Out(); + return fail; +} + +/* simple float implementation */ + +FEC_STATIC simple_float simple_float_mul(simple_float op1, simple_float op2) +{ + Dyn_Mem_Deluxe_In( + simple_float rop; + Word32 aux; + ); + aux = L_shr(L_mult0(op1.mantissa, op2.mantissa), 14); + rop.exponent = add(op1.exponent, op2.exponent); + IF (L_and(aux, 32768L)) + { + aux = L_shr(aux, 1); + rop.exponent = add(rop.exponent, 1); + } + rop.mantissa = extract_l(aux); + Dyn_Mem_Deluxe_Out(); + return rop; +} + +/* Auxiliary */ + +FEC_STATIC Word16 simple_float_cmp(simple_float op1, simple_float op2) +/* returns 1 if op1 > op2, 0 if op1 = op2, and -1 if op1 < op2 */ +{ + Dyn_Mem_Deluxe_In( + Word16 rval; + Word16 mdiff; + Word16 ediff; + ); + + rval = 0; move16(); + + ediff = sub(op1.exponent, op2.exponent); + mdiff = sub(op1.mantissa, op2.mantissa); + + IF (ediff == 0) + { + if (mdiff > 0) + { + rval = 1; + } + if (mdiff < 0) + { + rval = -1; + } + } + ELSE + { + if (ediff > 0) + { + rval = 1; + } + if (ediff < 0) + { + rval = -1; + } + } + + Dyn_Mem_Deluxe_Out(); + return rval; +} + + diff --git a/lib_lc3plus/apply_global_gain_fx.c b/lib_lc3plus/apply_global_gain_fx.c new file mode 100644 index 0000000000000000000000000000000000000000..a3299d8630719bb26ffbefd587729cbdfbd8ace5 --- /dev/null +++ b/lib_lc3plus/apply_global_gain_fx.c @@ -0,0 +1,66 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.5 * +* 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 "functions.h" + +void processApplyGlobalGain_fx(Word32 x[], Word16 *x_e, Word16 xLen, Word16 global_gain_idx, Word16 global_gain_off) +{ + Word32 i; +#ifdef ENABLE_HR_MODE + Word32 global_gain; +#else + Word16 global_gain; +#endif + Word16 global_gain_e; + Word32 tmp32; + +#ifdef DYNMEM_COUNT + Dyn_Mem_In("processApplyGlobalGain_fx", sizeof(struct { + Counter i; + Word16 global_gain, global_gain_e; + Word32 tmp32; + })); +#endif + +#ifdef ENABLE_HR_MODE + /* 1 / (28 * log 2) is 0x797D in Q18, L_shl_pos by 7 results in Q25 tmp32 */ + /* round(2^31 / (28 * log10(2))) = 254778081 */ + //tmp32 = L_shl_pos(Mpy_32_16_lc3plus(254778081, add(global_gain_idx, global_gain_off)), 9); + Word32 mh; + UWord16 ml; + + Mpy_32_16_ss(254778081, add(global_gain_idx, global_gain_off), &mh, &ml); + tmp32 = L_shl_pos(mh, 9) | L_deposit_l((shr((Word16)ml, 7)) & 0x1ff); + move16(); + /* Uses an argument in Q25 */ + global_gain = BASOP_Util_InvLog2_lc3plus(L_or(tmp32, (Word32)0xFE000000)); +#else + tmp32 = L_shl_pos(L_mult0(add(global_gain_idx, global_gain_off), 0x797D), 7); + /* Uses an argument in Q25 */ + global_gain = round_fx(BASOP_Util_InvLog2_lc3plus(L_or(tmp32, (Word32)0xFE000000))); +#endif + global_gain_e = add(extract_l(L_shr_pos(tmp32, 25)), 1); + + FOR (i = 0; i < xLen; i++) + { +#ifdef ENABLE_HR_MODE + x[i] = Mpy_32_32_lc3plus(x[i], global_gain); +#else + x[i] = Mpy_32_16_lc3plus(x[i], global_gain); +#endif + move32(); + } + + *x_e = add(*x_e, global_gain_e); move16(); + +#ifdef DYNMEM_COUNT + Dyn_Mem_Out(); +#endif +} + diff --git a/lib_lc3plus/ari_codec.c b/lib_lc3plus/ari_codec.c new file mode 100644 index 0000000000000000000000000000000000000000..46ad0a532fe223f9573dd8da1daac8402d3d4224 --- /dev/null +++ b/lib_lc3plus/ari_codec.c @@ -0,0 +1,2465 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.5 * +* 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 "functions.h" + + +typedef struct +{ + Word16 inv_bin; + Word16 numbytes; + Word16 c_bp; + Word16 c_bp_side; + Word16 bytes; + Word16 b_left; + Word16 b_right; + Word16 enc; + Word16 sim_dec; + Word16 bfi; + Word16 be_bp_left; + Word16 be_bp_right; +} Pc_State_fx; + +typedef struct +{ + UWord32 ac_low_fx; + UWord32 ac_range_fx; + Word16 ac_cache_fx; + Word16 ac_carry_fx; + Word16 ac_carry_count_fx; +} Encoder_State_fx; + +typedef struct +{ + UWord32 ac_low_fx; + UWord32 ac_range_fx; + UWord32 ac_help_fx; + Word16 BER_detect; + Pc_State_fx pc; +} Decoder_State_fx; + +static void ac_dec_init_fx(UWord8 *ptr, Word16 *bp, Word16 *bp_side, Word16 *mask_side, + Decoder_State_fx *st_fx /* i/o: Decoder State */ +); + +static __forceinline void pc_init_fx(Word16 n_pc, Word16 numbytes, Word16 be_bp_left, Word16 be_bp_right, Word16 L_spec, + Word16 enc, Word16 sim_dec, Word16 bfi, Pc_State_fx *pc /* i/o: Pc State */ +); +static __forceinline Word16 check_pc_bytes(Word16 *bp, Word16 *bp_side, Word16 *mask_side, Word16 cur_bin, + Word16 from_left, Pc_State_fx *pc /* i/o: Pc State */ +); + +static void ac_enc_init_fx(Encoder_State_fx *st_fx /* i/o: Encoder state */ +); + +static void ac_enc_shift_fx(UWord8 *ptr, Word16 *bp, Encoder_State_fx *st_fx /* i/o: Encoder state */ +); + +static void write_indice_forward(UWord8 *ptr, Word16 bp, Word16 indice, Word16 numbits); + +static void ac_encode_fx(UWord8 *ptr, Word16 *bp, Encoder_State_fx *st_fx, /* i/o: Encoder state */ + UWord32 cum_freq, /* i : Cumulative frequency up to symbol */ + UWord32 sym_freq /* i : Symbol probability */ +); + +static Word16 ac_enc_finish_fx(UWord8 *ptr, Word16 *bp, Encoder_State_fx *st_fx /* i/o: Encoder state */ +); + +static Word16 ac_decode_fx( /* o : Decoded cumulative frequency */ + Decoder_State_fx *st_fx, /* i/o: Decoder State */ + Word16 pki); +static Word16 ac_decode_tns_order( /* o : Decoded cumulative frequency */ + Decoder_State_fx *st_fx, /* i/o: Decoder State */ + Word16 enable_lpc_weighting); +static Word16 ac_decode_tns_coef( /* o : Decoded cumulative frequency */ + Decoder_State_fx *st_fx, /* i/o: Decoder State */ + Word16 pki); +static Word16 ac_dec_update_fx(UWord8 *ptr, Word16 *bp, Word16 *bp_side, Word16 *mask_side, Word16 cur_bin, + Decoder_State_fx *st_fx, /* i/o: Decoder State */ + UWord32 cum_freq, /* i : Cumulative frequency */ + UWord32 sym_freq /* i : Symbol frequency */ +); + +/*************************************************************************/ + +# ifdef ENABLE_HR_MODE + +Word16 processAriEncoder_fx(UWord8 *bytes, Word16 bp_side_in, Word16 mask_side_in, Word16 nbbits, Word32 xq[], + Word16 *tns_order, Word16 tns_numfilters, Word16 *tns_idx, Word16 lastnz, + Word16 *codingdata, UWord8 *resBits, Word16 numResBits, Word16 lsbMode, + Word16 enable_lpc_weighting, Word8 *scratchBuffer) +{ + Word16 resbit, i1, i2; + + Dyn_Mem_Deluxe_In(Encoder_State_fx st; Word16 bp, bp_side, mask_side, extra_bits; + Word32 a1, b1, a1_i, b1_i, a1_msb, b1_msb; Word16 lev1; Word16 nbits_side; Word16 tmp; + Word16 fill_bits; UWord8 * ptr; Word16 numResBitsEnc; Word16 * lsb, nlsbs; Word32 i, n, k, lev;); + + lsb = (Word16 *)scratchAlign(scratchBuffer, 0); /* size = 2 * lastnz */ + + /* Init */ + a1_i = 0; + move16(); + b1_i = 1; + move16(); + bp = 0; + move16(); + numResBitsEnc = 0; + move16(); + nlsbs = 0; + move16(); + ptr = bytes; + bp_side = bp_side_in; + move16(); + mask_side = mask_side_in; + move16(); + + /*Start Encoding*/ + ac_enc_init_fx(&st); + + /* TNS data */ + FOR (n = 0; n < tns_numfilters; n++) + { + IF (tns_order[n] > 0) + { + ac_encode_fx(ptr, &bp, &st, ac_tns_order_cumfreq[enable_lpc_weighting][tns_order[n] - 1], + ac_tns_order_freq[enable_lpc_weighting][tns_order[n] - 1]); + FOR (k = 0; k < tns_order[n]; k++) + { + ac_encode_fx(ptr, &bp, &st, ac_tns_coef_cumfreq[k][tns_idx[MAXLAG * n + k]], + ac_tns_coef_freq[k][tns_idx[MAXLAG * n + k]]); + } + } + } + + IF (lsbMode == 0) + { + + /*Main Loop through the 2-tuples*/ + FOR (k = 0; k < lastnz; k += 2) + { + IF (codingdata[1] < 0) + { + ac_encode_fx(ptr, &bp, &st, 0, + ari_spec_freq[ari_spec_lookup[codingdata[0]]][0]); + } + ELSE IF (codingdata[1] == 0) + { + ac_encode_fx(ptr, &bp, &st, ari_spec_cumfreq[ari_spec_lookup[codingdata[0]]][codingdata[2]], + ari_spec_freq[ari_spec_lookup[codingdata[0]]][codingdata[2]]); + IF (xq[a1_i] != 0) + { + write_bit_backward(ptr, &bp_side, &mask_side, L_lshr(xq[a1_i], 31)); + } + IF (xq[b1_i] != 0) + { + write_bit_backward(ptr, &bp_side, &mask_side, L_lshr(xq[b1_i], 31)); + } + } + ELSE IF (sub(codingdata[1], 1) == 0) + { + ac_encode_fx(ptr, &bp, &st, ari_spec_cumfreq[ari_spec_lookup[codingdata[0]]][VAL_ESC], + ari_spec_freq[ari_spec_lookup[codingdata[0]]][VAL_ESC]); + ac_encode_fx(ptr, &bp, &st, + ari_spec_cumfreq[ari_spec_lookup[codingdata[0] + Tab_esc_nb[1]]][codingdata[2]], + ari_spec_freq[ari_spec_lookup[codingdata[0] + Tab_esc_nb[1]]][codingdata[2]]); + write_bit_backward(ptr, &bp_side, &mask_side, L_and(xq[a1_i], 1)); + write_bit_backward(ptr, &bp_side, &mask_side, L_and(xq[b1_i], 1)); + IF (xq[a1_i] != 0) + { + write_bit_backward(ptr, &bp_side, &mask_side, L_lshr(xq[a1_i], 31)); + } + IF (xq[b1_i] != 0) + { + write_bit_backward(ptr, &bp_side, &mask_side, L_lshr(xq[b1_i], 31)); + } + } + ELSE + { + a1 = L_abs(xq[a1_i]); + b1 = L_abs(xq[b1_i]); + FOR (lev = 0; lev < codingdata[1]; lev++) + { + lev1 = s_min(lev, 3); + ac_encode_fx(ptr, &bp, &st, + ari_spec_cumfreq[ari_spec_lookup[codingdata[0] + Tab_esc_nb[lev1]]][VAL_ESC], + ari_spec_freq[ari_spec_lookup[codingdata[0] + Tab_esc_nb[lev1]]][VAL_ESC]); + write_bit_backward(ptr, &bp_side, &mask_side, s_and(L_shr_pos(a1, lev), 1)); + write_bit_backward(ptr, &bp_side, &mask_side, s_and(L_shr_pos(b1, lev), 1)); + } + lev1 = s_min(codingdata[1], 3); + ac_encode_fx(ptr, &bp, &st, + ari_spec_cumfreq[ari_spec_lookup[codingdata[0] + Tab_esc_nb[lev1]]][codingdata[2]], + ari_spec_freq[ari_spec_lookup[codingdata[0] + Tab_esc_nb[lev1]]][codingdata[2]]); + IF (xq[a1_i] != 0) + { + write_bit_backward(ptr, &bp_side, &mask_side, L_lshr(xq[a1_i], 31)); + } + IF (xq[b1_i] != 0) + { + write_bit_backward(ptr, &bp_side, &mask_side, L_lshr(xq[b1_i], 31)); + } + } + + a1_i += 2; + b1_i += 2; + codingdata += 3; + + } /*end of the 2-tuples loop*/ + } + ELSE + { + /*Main Loop through the 2-tuples*/ + FOR (k = 0; k < lastnz; k += 2) + { + IF (codingdata[1] < 0) + { + ac_encode_fx(ptr, &bp, &st, 0, + ari_spec_freq[ari_spec_lookup[codingdata[0]]][0]); + } + ELSE IF (codingdata[1] == 0) + { + ac_encode_fx(ptr, &bp, &st, ari_spec_cumfreq[ari_spec_lookup[codingdata[0]]][codingdata[2]], + ari_spec_freq[ari_spec_lookup[codingdata[0]]][codingdata[2]]); + IF (xq[a1_i] != 0) + { + write_bit_backward(ptr, &bp_side, &mask_side, L_lshr(xq[a1_i], 31)); + } + IF (xq[b1_i] != 0) + { + write_bit_backward(ptr, &bp_side, &mask_side, L_lshr(xq[b1_i], 31)); + } + } + ELSE IF (sub(codingdata[1], 1) == 0) + { + ac_encode_fx(ptr, &bp, &st, ari_spec_cumfreq[ari_spec_lookup[codingdata[0]]][VAL_ESC], + ari_spec_freq[ari_spec_lookup[codingdata[0]]][VAL_ESC]); + ac_encode_fx(ptr, &bp, &st, + ari_spec_cumfreq[ari_spec_lookup[codingdata[0] + Tab_esc_nb[1]]][codingdata[2]], + ari_spec_freq[ari_spec_lookup[codingdata[0] + Tab_esc_nb[1]]][codingdata[2]]); + a1_msb = s_and(codingdata[2], 0x3); + tmp = L_and(xq[a1_i], 1); + lsb[nlsbs++] = tmp; + move16(); + test(); + IF (a1_msb == 0 && tmp > 0) + { + if (xq[a1_i] > 0) + { + lsb[nlsbs++] = 0; + move16(); + } + if (xq[a1_i] < 0) + { + lsb[nlsbs++] = 1; + move16(); + } + } + IF (a1_msb != 0) + { + write_bit_backward(ptr, &bp_side, &mask_side, L_lshr(xq[a1_i], 31)); + } + b1_msb = shr_pos(codingdata[2], 2); + tmp = L_and(xq[b1_i], 1); + lsb[nlsbs++] = tmp; + move16(); + test(); + IF (b1_msb == 0 && tmp > 0) + { + if (xq[b1_i] > 0) + { + lsb[nlsbs++] = 0; + move16(); + } + if (xq[b1_i] < 0) + { + lsb[nlsbs++] = 1; + move16(); + } + } + IF (b1_msb != 0) + { + write_bit_backward(ptr, &bp_side, &mask_side, L_lshr(xq[b1_i], 31)); + } + } + ELSE + { + a1 = L_abs(xq[a1_i]); + b1 = L_abs(xq[b1_i]); + a1_msb = L_shr_pos(a1, 1); + tmp = L_and(a1, 1); + lsb[nlsbs++] = tmp; + move16(); + test(); + IF (a1_msb == 0 && tmp > 0) + { + if (xq[a1_i] > 0) + { + lsb[nlsbs++] = 0; + move16(); + } + if (xq[a1_i] < 0) + { + lsb[nlsbs++] = 1; + move16(); + } + } + b1_msb = L_shr_pos(b1, 1); + tmp = s_and(b1, 1); + lsb[nlsbs++] = tmp; + move16(); + test(); + IF (b1_msb == 0 && tmp > 0) + { + if (xq[b1_i] > 0) + { + lsb[nlsbs++] = 0; + move16(); + } + if (xq[b1_i] < 0) + { + lsb[nlsbs++] = 1; + move16(); + } + } + ac_encode_fx(ptr, &bp, &st, ari_spec_cumfreq[ari_spec_lookup[codingdata[0] + Tab_esc_nb[0]]][VAL_ESC], + ari_spec_freq[ari_spec_lookup[codingdata[0] + Tab_esc_nb[0]]][VAL_ESC]); + FOR (lev = 1; lev < codingdata[1]; lev++) + { + lev1 = s_min(lev, 3); + ac_encode_fx(ptr, &bp, &st, + ari_spec_cumfreq[ari_spec_lookup[codingdata[0] + Tab_esc_nb[lev1]]][VAL_ESC], + ari_spec_freq[ari_spec_lookup[codingdata[0] + Tab_esc_nb[lev1]]][VAL_ESC]); + write_bit_backward(ptr, &bp_side, &mask_side, s_and(L_shr_pos(a1, lev), 1)); + write_bit_backward(ptr, &bp_side, &mask_side, s_and(L_shr_pos(b1, lev), 1)); + } + lev1 = s_min(codingdata[1], 3); + ac_encode_fx(ptr, &bp, &st, + ari_spec_cumfreq[ari_spec_lookup[codingdata[0] + Tab_esc_nb[lev1]]][codingdata[2]], + ari_spec_freq[ari_spec_lookup[codingdata[0] + Tab_esc_nb[lev1]]][codingdata[2]]); + IF (a1_msb != 0) + { + write_bit_backward(ptr, &bp_side, &mask_side, L_lshr(xq[a1_i], 31)); + } + IF (b1_msb != 0) + { + write_bit_backward(ptr, &bp_side, &mask_side, L_lshr(xq[b1_i], 31)); + } + } + + a1_i += 2; + b1_i += 2; + codingdata += 3; + + } /*end of the 2-tuples loop*/ + } + + /* Side bits (in sync with the decoder) */ + nbits_side = sub(nbbits, add(shl_pos(bp_side, 3), sub(norm_s(mask_side), 6))); + + /* Residual bits (in sync with the decoder) */ + extra_bits = sub(norm_ul(st.ac_range_fx), 6); + if (st.ac_cache_fx >= 0) + { + extra_bits = add(extra_bits, 8); + } + if (st.ac_carry_count_fx > 0) + { + extra_bits = add(extra_bits, shl_pos(st.ac_carry_count_fx, 3)); + } + + n = s_max(sub(nbbits, add(shl_pos(bp, 3), add(extra_bits, nbits_side))), 0); + move16(); + + IF (lsbMode == 0) + { + numResBitsEnc = s_min(numResBits, n); + FOR (i = 0; i < numResBitsEnc; i++) + { + resbit = 0; move16(); + i1 = shr(i, RESBITS_PACK_SHIFT); + i2 = s_and(i, RESBITS_PACK_MASK); + if (s_and(resBits[i1], shl(1, i2))) + { + resbit = 1; + } + write_bit_backward(ptr, &bp_side, &mask_side, resbit); + } + } + ELSE + { + nlsbs = s_min(nlsbs, n); + FOR (k = 0; k < nlsbs; k++) + { + write_bit_backward(ptr, &bp_side, &mask_side, lsb[k]); + } + } + + /* End arithmetic coder, overflow management */ + extra_bits = ac_enc_finish_fx(ptr, &bp, &st); + + /* Fill bits (for debugging, the exact number of fill bits cannot be computed in the decoder)*/ + fill_bits = nbbits - (bp * 8 + extra_bits + nbits_side + nlsbs + numResBitsEnc); + + Dyn_Mem_Deluxe_Out(); + + return fill_bits; +} + +# else /* ENABLE_HR_MODE */ + +Word16 processAriEncoder_fx(UWord8 *bytes, Word16 bp_side_in, Word16 mask_side_in, Word16 nbbits, Word16 xq[], + Word16 *tns_order, Word16 tns_numfilters, Word16 *tns_idx, Word16 lastnz, + Word16 *codingdata, UWord8 *resBits, Word16 numResBits, Word16 lsbMode, + Word16 enable_lpc_weighting, Word8 *scratchBuffer) +{ +#ifdef ENABLE_HR_MODE + Dyn_Mem_Deluxe_In(Encoder_State_fx st; Word16 bp, bp_side, mask_side, extra_bits; + Word16 a1, b1, a1_i, b1_i, a1_msb, b1_msb; Word16 lev1; Word16 nbits_side; Word16 tmp; + Word16 fill_bits; UWord8 * ptr; Word16 numResBitsEnc; Word16 * lsb, nlsbs; Counter i, n, k, lev; + ); +#else + Dyn_Mem_Deluxe_In(Encoder_State_fx st; Word16 bp, bp_side, mask_side, extra_bits; + Word16 a1, b1, a1_i, b1_i, a1_msb, b1_msb; Word16 lev1; Word16 nbits_side; Word16 tmp; + Word16 fill_bits; UWord8 * ptr; Word16 numResBitsEnc; Word16 * lsb, nlsbs; Counter i, n, k, lev; + ); +#endif + + + lsb = (Word16 *)scratchAlign(scratchBuffer, 0); /* Size = 2 * MAX_LEN * 2 bytes */ + + /* Init */ + a1_i = 0; + move16(); + b1_i = 1; + move16(); + bp = 0; + move16(); + numResBitsEnc = 0; + move16(); + nlsbs = 0; + move16(); + ptr = bytes; + bp_side = bp_side_in; + move16(); + mask_side = mask_side_in; + move16(); + + /*Start Encoding*/ + ac_enc_init_fx(&st); + + /* TNS data */ + FOR (n = 0; n < tns_numfilters; n++) + { + IF (tns_order[n] > 0) + { + ac_encode_fx(ptr, &bp, &st, ac_tns_order_cumfreq[enable_lpc_weighting][tns_order[n] - 1], + ac_tns_order_freq[enable_lpc_weighting][tns_order[n] - 1]); + FOR (k = 0; k < tns_order[n]; k++) + { + ac_encode_fx(ptr, &bp, &st, ac_tns_coef_cumfreq[k][tns_idx[MAXLAG * n + k]], + ac_tns_coef_freq[k][tns_idx[MAXLAG * n + k]]); + } + } + } + + IF (lsbMode == 0) + { + + /*Main Loop through the 2-tuples*/ + FOR (k = 0; k < lastnz; k += 2) + { + IF (codingdata[1] < 0) + { + ac_encode_fx(ptr, &bp, &st, ari_spec_cumfreq[ari_spec_lookup[codingdata[0]]][0], + ari_spec_freq[ari_spec_lookup[codingdata[0]]][0]); + } + ELSE IF (codingdata[1] == 0) + { + ac_encode_fx(ptr, &bp, &st, ari_spec_cumfreq[ari_spec_lookup[codingdata[0]]][codingdata[2]], + ari_spec_freq[ari_spec_lookup[codingdata[0]]][codingdata[2]]); + IF (xq[a1_i] != 0) + { + write_bit_backward(ptr, &bp_side, &mask_side, lshr(xq[a1_i], 15)); + } + IF (xq[b1_i] != 0) + { + write_bit_backward(ptr, &bp_side, &mask_side, lshr(xq[b1_i], 15)); + } + } + ELSE IF (sub(codingdata[1], 1) == 0) + { + ac_encode_fx(ptr, &bp, &st, ari_spec_cumfreq[ari_spec_lookup[codingdata[0]]][VAL_ESC], + ari_spec_freq[ari_spec_lookup[codingdata[0]]][VAL_ESC]); + ac_encode_fx(ptr, &bp, &st, + ari_spec_cumfreq[ari_spec_lookup[codingdata[0] + Tab_esc_nb[1]]][codingdata[2]], + ari_spec_freq[ari_spec_lookup[codingdata[0] + Tab_esc_nb[1]]][codingdata[2]]); + write_bit_backward(ptr, &bp_side, &mask_side, s_and(xq[a1_i], 1)); + write_bit_backward(ptr, &bp_side, &mask_side, s_and(xq[b1_i], 1)); + IF (xq[a1_i] != 0) + { + write_bit_backward(ptr, &bp_side, &mask_side, lshr(xq[a1_i], 15)); + } + IF (xq[b1_i] != 0) + { + write_bit_backward(ptr, &bp_side, &mask_side, lshr(xq[b1_i], 15)); + } + } + ELSE + { + a1 = abs_s(xq[a1_i]); + b1 = abs_s(xq[b1_i]); + FOR (lev = 0; lev < codingdata[1]; lev++) + { + lev1 = s_min(lev, 3); + ac_encode_fx(ptr, &bp, &st, + ari_spec_cumfreq[ari_spec_lookup[codingdata[0] + Tab_esc_nb[lev1]]][VAL_ESC], + ari_spec_freq[ari_spec_lookup[codingdata[0] + Tab_esc_nb[lev1]]][VAL_ESC]); + write_bit_backward(ptr, &bp_side, &mask_side, s_and(shr_pos(a1, lev), 1)); + write_bit_backward(ptr, &bp_side, &mask_side, s_and(shr_pos(b1, lev), 1)); + } + lev1 = s_min(codingdata[1], 3); + ac_encode_fx(ptr, &bp, &st, + ari_spec_cumfreq[ari_spec_lookup[codingdata[0] + Tab_esc_nb[lev1]]][codingdata[2]], + ari_spec_freq[ari_spec_lookup[codingdata[0] + Tab_esc_nb[lev1]]][codingdata[2]]); + IF (xq[a1_i] != 0) + { + write_bit_backward(ptr, &bp_side, &mask_side, lshr(xq[a1_i], 15)); + } + IF (xq[b1_i] != 0) + { + write_bit_backward(ptr, &bp_side, &mask_side, lshr(xq[b1_i], 15)); + } + } + + a1_i += 2; + b1_i += 2; + codingdata += 3; + + } /*end of the 2-tuples loop*/ + } + ELSE + { + /*Main Loop through the 2-tuples*/ + FOR (k = 0; k < lastnz; k += 2) + { + IF (codingdata[1] < 0) + { + ac_encode_fx(ptr, &bp, &st, ari_spec_cumfreq[ari_spec_lookup[codingdata[0]]][0], + ari_spec_freq[ari_spec_lookup[codingdata[0]]][0]); + } + ELSE IF (codingdata[1] == 0) + { + ac_encode_fx(ptr, &bp, &st, ari_spec_cumfreq[ari_spec_lookup[codingdata[0]]][codingdata[2]], + ari_spec_freq[ari_spec_lookup[codingdata[0]]][codingdata[2]]); + IF (xq[a1_i] != 0) + { + write_bit_backward(ptr, &bp_side, &mask_side, lshr(xq[a1_i], 15)); + } + IF (xq[b1_i] != 0) + { + write_bit_backward(ptr, &bp_side, &mask_side, lshr(xq[b1_i], 15)); + } + } + ELSE IF (sub(codingdata[1], 1) == 0) + { + ac_encode_fx(ptr, &bp, &st, ari_spec_cumfreq[ari_spec_lookup[codingdata[0]]][VAL_ESC], + ari_spec_freq[ari_spec_lookup[codingdata[0]]][VAL_ESC]); + ac_encode_fx(ptr, &bp, &st, + ari_spec_cumfreq[ari_spec_lookup[codingdata[0] + Tab_esc_nb[1]]][codingdata[2]], + ari_spec_freq[ari_spec_lookup[codingdata[0] + Tab_esc_nb[1]]][codingdata[2]]); + a1_msb = s_and(codingdata[2], 0x3); + tmp = s_and(xq[a1_i], 1); + lsb[nlsbs++] = tmp; + move16(); + test(); + IF (a1_msb == 0 && tmp > 0) + { + if (xq[a1_i] > 0) + { + lsb[nlsbs++] = 0; + move16(); + } + if (xq[a1_i] < 0) + { + lsb[nlsbs++] = 1; + move16(); + } + } + IF (a1_msb != 0) + { + write_bit_backward(ptr, &bp_side, &mask_side, lshr(xq[a1_i], 15)); + } + b1_msb = shr_pos(codingdata[2], 2); + tmp = s_and(xq[b1_i], 1); + lsb[nlsbs++] = tmp; + move16(); + test(); + IF (b1_msb == 0 && tmp > 0) + { + if (xq[b1_i] > 0) + { + lsb[nlsbs++] = 0; + move16(); + } + if (xq[b1_i] < 0) + { + lsb[nlsbs++] = 1; + move16(); + } + } + IF (b1_msb != 0) + { + write_bit_backward(ptr, &bp_side, &mask_side, lshr(xq[b1_i], 15)); + } + } + ELSE + { + a1 = abs_s(xq[a1_i]); + b1 = abs_s(xq[b1_i]); + a1_msb = shr_pos(a1, 1); + tmp = s_and(a1, 1); + lsb[nlsbs++] = tmp; + move16(); + test(); + IF (a1_msb == 0 && tmp > 0) + { + if (xq[a1_i] > 0) + { + lsb[nlsbs++] = 0; + move16(); + } + if (xq[a1_i] < 0) + { + lsb[nlsbs++] = 1; + move16(); + } + } + b1_msb = shr_pos(b1, 1); + tmp = s_and(b1, 1); + lsb[nlsbs++] = tmp; + move16(); + test(); + IF (b1_msb == 0 && tmp > 0) + { + if (xq[b1_i] > 0) + { + lsb[nlsbs++] = 0; + move16(); + } + if (xq[b1_i] < 0) + { + lsb[nlsbs++] = 1; + move16(); + } + } + ac_encode_fx(ptr, &bp, &st, ari_spec_cumfreq[ari_spec_lookup[codingdata[0] + Tab_esc_nb[0]]][VAL_ESC], + ari_spec_freq[ari_spec_lookup[codingdata[0] + Tab_esc_nb[0]]][VAL_ESC]); + FOR (lev = 1; lev < codingdata[1]; lev++) + { + lev1 = s_min(lev, 3); + ac_encode_fx(ptr, &bp, &st, + ari_spec_cumfreq[ari_spec_lookup[codingdata[0] + Tab_esc_nb[lev1]]][VAL_ESC], + ari_spec_freq[ari_spec_lookup[codingdata[0] + Tab_esc_nb[lev1]]][VAL_ESC]); + write_bit_backward(ptr, &bp_side, &mask_side, s_and(shr_pos(a1, lev), 1)); + write_bit_backward(ptr, &bp_side, &mask_side, s_and(shr_pos(b1, lev), 1)); + } + lev1 = s_min(codingdata[1], 3); + ac_encode_fx(ptr, &bp, &st, + ari_spec_cumfreq[ari_spec_lookup[codingdata[0] + Tab_esc_nb[lev1]]][codingdata[2]], + ari_spec_freq[ari_spec_lookup[codingdata[0] + Tab_esc_nb[lev1]]][codingdata[2]]); + IF (a1_msb != 0) + { + write_bit_backward(ptr, &bp_side, &mask_side, lshr(xq[a1_i], 15)); + } + IF (b1_msb != 0) + { + write_bit_backward(ptr, &bp_side, &mask_side, lshr(xq[b1_i], 15)); + } + } + + a1_i += 2; + b1_i += 2; + codingdata += 3; + + } /*end of the 2-tuples loop*/ + } + + /* Side bits (in sync with the decoder) */ + nbits_side = sub(nbbits, add(shl_pos(bp_side, 3), sub(norm_s(mask_side), 6))); + + /* Residual bits (in sync with the decoder) */ + extra_bits = sub(norm_ul(st.ac_range_fx), 6); + if (st.ac_cache_fx >= 0) + { + extra_bits = add(extra_bits, 8); + } + if (st.ac_carry_count_fx > 0) + { + extra_bits = add(extra_bits, shl_pos(st.ac_carry_count_fx, 3)); + } + + n = s_max(sub(nbbits, add(shl_pos(bp, 3), add(extra_bits, nbits_side))), 0); + move16(); + + IF (lsbMode == 0) + { + numResBitsEnc = s_min(numResBits, n); + FOR (i = 0; i < numResBitsEnc; i++) + { + FOR (i = 0; i < numResBitsEnc; i++) + { + write_bit_backward(ptr, &bp_side, &mask_side, resBits[i]); + } + } + } + ELSE + { + nlsbs = s_min(nlsbs, n); + FOR (k = 0; k < nlsbs; k++) + { + write_bit_backward(ptr, &bp_side, &mask_side, lsb[k]); + } + } + + /* End arithmetic coder, overflow management */ + extra_bits = ac_enc_finish_fx(ptr, &bp, &st); + + /* Fill bits (for debugging, the exact number of fill bits cannot be computed in the decoder)*/ + fill_bits = nbbits - (bp * 8 + extra_bits + nbits_side + nlsbs + numResBitsEnc); + + Dyn_Mem_Deluxe_Out(); + return fill_bits; +} + +#endif /* ENABLE_HR_MODE */ + +void processAriDecoder_fx(UWord8 *bytes, Word16 *bp_side, Word16 *mask_side, Word16 nbbits, Word16 L_spec, + Word16 fs_idx, Word16 enable_lpc_weighting, Word16 tns_numfilters, Word16 lsbMode, + Word16 lastnz, Word16 *bfi, Word16 *tns_order, Word16 fac_ns_idx, Word16 gg_idx, + Word16 frame_dms, + Word16 n_pc, Word16 be_bp_left, Word16 be_bp_right, Word16 mode, Word16 *spec_inv_idx, + Word16 *b_left, + Word16 *resBits, +# ifdef ENABLE_HR_MODE + Word32 *x, +# else + Word16 *x, +# endif + Word16 *nf_seed, UWord8 *resQdata, Word16 *tns_idx, Word16 *zero_frame, Word8 *scratchBuffer +# ifdef ENABLE_HR_MODE + , Word16 hrmode +# endif +) +{ + Decoder_State_fx st; +# ifdef ENABLE_HR_MODE + Word16 resbit, i1, i2; + Word32 a, b; +# else + Word16 a, b; +# endif + Word16 t, a1, b1, a1_i, b1_i, bp; + Word16 esc_nb; + Word16 rateFlag; + Word16 r; + Word16 nt_half; + Word16 c; + Word16 nbits_side, extra_bits, nbits_ari; + UWord8 * ptr; + Word32 tmp32; + Word16 lsb_ind_c; + Word16 * lsb_ind; + Word16 tmp; + Word32 n, k, lev; + Word32 i; + Word16 max_lev = 14; + +#ifdef DYNMEM_COUNT +struct _dynmem +{ +Decoder_State_fx st; + Pc_State_fx pc; + Word16 resbit, i1, i2; +# ifdef ENABLE_HR_MODE + Word32 a, b; +# else + Word16 a, b; +# endif + Word16 t, a1, b1, a1_i, b1_i, bp; + Word16 esc_nb; + Word16 rateFlag; + Word16 r; + Word16 nt_half; + Word16 c; + Word16 nbits_side, extra_bits, nbits_ari; + UWord8 * ptr; + Word32 tmp32; + Word16 lsb_ind_c; + Word16 * lsb_ind; + Word16 tmp; + Counter i, n, k, lev; + }; + Dyn_Mem_In("processAriDecoder_fx", sizeof(struct _dynmem)); +#endif + +# ifdef ENABLE_HR_MODE + if (hrmode == 1) + { + max_lev = max_lev + 8; + } +# endif + + lsb_ind = (Word16 *)scratchAlign(scratchBuffer, 0); /* Size 2 * MAX_LEN bytes */ + + /* Rate flag */ + rateFlag = 0; + move16(); +# ifdef ENABLE_HR_MODE + if (fs_idx != 5) /* Don't update rateFlag for 96000 Hz */ +# endif + { + if (sub(nbbits, add(160, DEPR_i_mult(fs_idx, 160))) > 0) + { + rateFlag = 2 << NBITS_CONTEXT; + move16(); + } + } + + pc_init_fx(n_pc, shr_pos(nbbits, 3), be_bp_left, be_bp_right, L_spec, mode==1, mode==2, *bfi, &st.pc); + + /* Init */ + nt_half = shr_pos(L_spec, 1); + c = 0; + move16(); + t = 0; + move16(); + a1_i = 0; + move16(); + b1_i = 1; + move16(); + bp = 0; + move16(); + if (mode != 1) + { + bp = add(bp, st.pc.bytes); + move16(); + } + *spec_inv_idx = L_spec; + move16(); + *b_left = -1; + move16(); + lsb_ind_c = 0; + move16(); + +ptr = bytes; + +/* Start Decoding */ +ac_dec_init_fx(ptr, &bp, bp_side, mask_side, &st); + + /* Decode TNS data */ + tmp = MAXLAG; +IF (sub(frame_dms, 25) == 0) +{ +tmp = shr_pos(tmp, 1); +} +IF (sub(frame_dms, 50) == 0) +{ +tmp = shr_pos(tmp, 1); +} + + FOR (n = 0; n < tns_numfilters; n++) + { + IF (tns_order[n] > 0) + { + tns_order[n] = ac_decode_tns_order(&st, enable_lpc_weighting); + move16(); + tns_order[n] = add(tns_order[n], 1); + move16(); + IF (tns_order[n] > tmp) + { + GOTO ber_detect; + } + if (ac_dec_update_fx(ptr, &bp, bp_side, mask_side, 0, &st, + ac_tns_order_cumfreq[enable_lpc_weighting][tns_order[n] - 1], + ac_tns_order_freq[enable_lpc_weighting][tns_order[n] - 1]) != 0) + { + GOTO ber_detect; + } + FOR (k = 0; k < tns_order[n]; k++) + { + IF (sub(*bp_side, bp) < 0) + { + GOTO ber_detect; + } + tns_idx[MAXLAG * n + k] = ac_decode_tns_coef(&st, k); + move16(); + if (ac_dec_update_fx(ptr, &bp, bp_side, mask_side, 0, &st, + ac_tns_coef_cumfreq[k][tns_idx[MAXLAG * n + k]], + ac_tns_coef_freq[k][tns_idx[MAXLAG * n + k]]) != 0) + { + GOTO ber_detect; + } + } + } + } + IF (st.BER_detect > 0) + { + GOTO ber_detect; + } + +IF (lsbMode == 0) +{ + +/*Main Loop through the 2-tuples*/ +FOR (k = 0; k < lastnz; k += 2) +{ + +/* Get context */ +t = add(c, rateFlag); +if (sub(k, nt_half) > 0) +{ +t = add(t, 1 << NBITS_CONTEXT); +} + + r = ac_decode_fx(&st, ari_spec_lookup[t]); + if (ac_dec_update_fx(ptr, &bp, bp_side, mask_side, k, &st, ari_spec_cumfreq[ari_spec_lookup[t]][r], + ari_spec_freq[ari_spec_lookup[t]][r]) != 0) + { + GOTO ber_detect; + } + + IF (r == 0) + { + x[a1_i] = 0; + move16(); + x[b1_i] = 0; + move16(); + c = add(shl_pos(s_and(c, 0xf), 4), 1); + } + ELSE IF (sub(r, VAL_ESC) < 0) + { + a = s_and(r, 0x3); + b = shr_pos(r, 2); + c = add(shl_pos(s_and(c, 0xf), 4), add(add(a, b), 1)); + IF (a > 0) + { +if (check_pc_bytes(&bp, bp_side, mask_side, a1_i, 0, &st.pc) != 0) +{ + GOTO ber_detect; +} + if (read_bit(ptr, bp_side, mask_side) != 0) + { + a = negate(a); + } + } + x[a1_i] = a; + move16(); + IF (b > 0) + { +if (check_pc_bytes(&bp, bp_side, mask_side, b1_i, 0, &st.pc) != 0) +{ + GOTO ber_detect; +} + if (read_bit(ptr, bp_side, mask_side) != 0) + { + b = negate(b); + } + } + x[b1_i] = b; + move16(); + } + ELSE + { +if (check_pc_bytes(&bp, bp_side, mask_side, a1_i, 0, &st.pc) != 0) +{ +GOTO ber_detect; +} +a = read_bit(ptr, bp_side, mask_side); +if (check_pc_bytes(&bp, bp_side, mask_side, a1_i, 0, &st.pc) != 0) +{ +GOTO ber_detect; +} + b = read_bit(ptr, bp_side, mask_side); + r = ac_decode_fx(&st, ari_spec_lookup[t + Tab_esc_nb[1]]); + if (ac_dec_update_fx(ptr, &bp, bp_side, mask_side, k, &st, + ari_spec_cumfreq[ari_spec_lookup[t + Tab_esc_nb[1]]][r], + ari_spec_freq[ari_spec_lookup[t + Tab_esc_nb[1]]][r]) != 0) + { + GOTO ber_detect; + } + IF (sub(r, VAL_ESC) < 0) + { + a1 = s_and(r, 0x3); + b1 = shr_pos(r, 2); + a = add(shl_pos(a1, 1), a); + b = add(shl_pos(b1, 1), b); + IF (a > 0) + { + if (check_pc_bytes(&bp, bp_side, mask_side, a1_i, 0, &st.pc) != 0) + { + GOTO ber_detect; + } + if (read_bit(ptr, bp_side, mask_side) != 0) + { + a = negate(a); + } + } + x[a1_i] = a; + move16(); + IF (b > 0) + { + if (check_pc_bytes(&bp, bp_side, mask_side, b1_i, 0, &st.pc) != 0) + { + GOTO ber_detect; + } + if (read_bit(ptr, bp_side, mask_side) != 0) + { + b = negate(b); + } + } + x[b1_i] = b; + move16(); + c = add(shl_pos(s_and(c, 0xf), 4), add(shl_pos(add(a1, b1), 1), 1)); + } + ELSE + { +if (check_pc_bytes(&bp, bp_side, mask_side, a1_i, 0, &st.pc) != 0) +{ + GOTO ber_detect; +} +a = add(shl_pos(read_bit(ptr, bp_side, mask_side), 1), a); +if (check_pc_bytes(&bp, bp_side, mask_side, a1_i, 0, &st.pc) != 0) +{ + GOTO ber_detect; +} + b = add(shl_pos(read_bit(ptr, bp_side, mask_side), 1), b); + FOR (lev = 2; lev < max_lev; lev++) + { + esc_nb = s_min(lev, 3); + r = ac_decode_fx(&st, ari_spec_lookup[t + Tab_esc_nb[esc_nb]]); + if (ac_dec_update_fx(ptr, &bp, bp_side, mask_side, k, &st, + ari_spec_cumfreq[ari_spec_lookup[t + Tab_esc_nb[esc_nb]]][r], + ari_spec_freq[ari_spec_lookup[t + Tab_esc_nb[esc_nb]]][r]) != 0) + { + GOTO ber_detect; + } + IF (sub(r, VAL_ESC) < 0) + { + BREAK; + } + if (check_pc_bytes(&bp, bp_side, mask_side, a1_i, 0, &st.pc) != 0) + { + GOTO ber_detect; + } + +# ifdef ENABLE_HR_MODE + a = L_add(L_shl(read_bit(ptr, bp_side, mask_side), lev), a); +# else + a = add(shl(read_bit(ptr, bp_side, mask_side), lev), a); +# endif + + if (check_pc_bytes(&bp, bp_side, mask_side, a1_i, 0, &st.pc) != 0) + { + GOTO ber_detect; + } +# ifdef ENABLE_HR_MODE + b = L_add(L_shl(read_bit(ptr, bp_side, mask_side), lev), b); +# else + b = add(shl(read_bit(ptr, bp_side, mask_side), lev), b); +# endif + } + /* check for bitflip */ + IF (sub(lev, max_lev) == 0) + { + GOTO ber_detect; + } + + b1 = shr_pos(r, 2); + a1 = s_and(r, 0x3); + +# ifdef ENABLE_HR_MODE + a = L_add(L_shl(a1, lev), a); + b = L_add(L_shl(b1, lev), b); +# else + a = add(shl(a1, lev), a); + b = add(shl(b1, lev), b); +# endif + IF (a > 0) + { + if (check_pc_bytes(&bp, bp_side, mask_side, a1_i, 0, &st.pc) != 0) + { + GOTO ber_detect; + } + if (read_bit(ptr, bp_side, mask_side) != 0) + { +# ifdef ENABLE_HR_MODE + a = L_negate(a); +# else + a = negate(a); +# endif + } + } + x[a1_i] = a; + move16(); + IF (b > 0) + { + if (check_pc_bytes(&bp, bp_side, mask_side, b1_i, 0, &st.pc) != 0) + { + GOTO ber_detect; + } + if (read_bit(ptr, bp_side, mask_side) != 0) + { +# ifdef ENABLE_HR_MODE + b = L_negate(b); +# else + b = negate(b); +# endif + } + } + x[b1_i] = b; + move16(); + c = add(shl_pos(s_and(c, 0xf), 4), add(esc_nb, 12)); + } + } + + test(); + test(); + IF ((sub(sub(bp, *bp_side), 3) > 0 && sub(st.pc.c_bp, st.pc.c_bp_side) == 0) || st.BER_detect > 0) +{ +GOTO ber_detect; +} + +a1_i += 2; +b1_i += 2; +} +} +ELSE +{ +/*Main Loop through the 2-tuples*/ +FOR (k = 0; k < lastnz; k += 2) +{ + +/* Get context */ +t = add(c, rateFlag); +if (sub(k, nt_half) > 0) +{ +t = add(t, 1 << NBITS_CONTEXT); +} + + r = ac_decode_fx(&st, ari_spec_lookup[t]); + if (ac_dec_update_fx(ptr, &bp, bp_side, mask_side, k, &st, ari_spec_cumfreq[ari_spec_lookup[t]][r], + ari_spec_freq[ari_spec_lookup[t]][r]) != 0) + { + GOTO ber_detect; + } + + IF (r == 0) + { + x[a1_i] = 0; + move16(); + x[b1_i] = 0; + move16(); + c = add(shl_pos(s_and(c, 0xf), 4), 1); + } + ELSE IF (sub(r, VAL_ESC) < 0) + { + a = s_and(r, 0x3); + b = shr_pos(r, 2); + c = add(shl_pos(s_and(c, 0xf), 4), add(add(a, b), 1)); + IF (a > 0) + { +if (check_pc_bytes(&bp, bp_side, mask_side, a1_i, 0, &st.pc) != 0) +{ + GOTO ber_detect; +} + if (read_bit(ptr, bp_side, mask_side) != 0) + { + a = negate(a); + } + } + x[a1_i] = a; + move16(); + IF (b > 0) + { +if (check_pc_bytes(&bp, bp_side, mask_side, b1_i, 0, &st.pc) != 0) +{ + GOTO ber_detect; +} + if (read_bit(ptr, bp_side, mask_side) != 0) + { + b = negate(b); + } + } + x[b1_i] = b; + move16(); + } + ELSE + { + r = ac_decode_fx(&st, ari_spec_lookup[t + Tab_esc_nb[1]]); + if (ac_dec_update_fx(ptr, &bp, bp_side, mask_side, k, &st, + ari_spec_cumfreq[ari_spec_lookup[t + Tab_esc_nb[1]]][r], + ari_spec_freq[ari_spec_lookup[t + Tab_esc_nb[1]]][r]) != 0) + { + GOTO ber_detect; + } + IF (sub(r, VAL_ESC) < 0) + { + a1 = s_and(r, 0x3); + b1 = shr_pos(r, 2); + a = shl_pos(a1, 1); + b = shl_pos(b1, 1); + IF (a > 0) + { + if (check_pc_bytes(&bp, bp_side, mask_side, a1_i, 0, &st.pc) != 0) + { + GOTO ber_detect; + } + if (read_bit(ptr, bp_side, mask_side) != 0) + { + a = negate(a); + } + } + x[a1_i] = a; + move16(); + IF (b > 0) + { + if (check_pc_bytes(&bp, bp_side, mask_side, b1_i, 0, &st.pc) != 0) + { + GOTO ber_detect; + } + if (read_bit(ptr, bp_side, mask_side) != 0) + { + b = negate(b); + } + } + x[b1_i] = b; + move16(); + c = add(shl_pos(s_and(c, 0xf), 4), add(shl_pos(add(a1, b1), 1), 1)); + lsb_ind[lsb_ind_c++] = k; + move16(); + } + ELSE + { +if (check_pc_bytes(&bp, bp_side, mask_side, a1_i, 0, &st.pc) != 0) +{ + GOTO ber_detect; +} +a = shl_pos(read_bit(ptr, bp_side, mask_side), 1); +if (check_pc_bytes(&bp, bp_side, mask_side, a1_i, 0, &st.pc) != 0) +{ + GOTO ber_detect; +} + b = shl_pos(read_bit(ptr, bp_side, mask_side), 1); + FOR (lev = 2; lev < max_lev; lev++) + { + esc_nb = s_min(lev, 3); + r = ac_decode_fx(&st, ari_spec_lookup[t + Tab_esc_nb[esc_nb]]); + if (ac_dec_update_fx(ptr, &bp, bp_side, mask_side, k, &st, + ari_spec_cumfreq[ari_spec_lookup[t + Tab_esc_nb[esc_nb]]][r], + ari_spec_freq[ari_spec_lookup[t + Tab_esc_nb[esc_nb]]][r]) != 0) + { + GOTO ber_detect; + } + IF (sub(r, VAL_ESC) < 0) + { + BREAK; + } + if (check_pc_bytes(&bp, bp_side, mask_side, a1_i, 0, &st.pc) != 0) + { + GOTO ber_detect; + } +# ifdef ENABLE_HR_MODE + a = L_add(L_shl(read_bit(ptr, bp_side, mask_side), lev), a); +# else + a = add(shl(read_bit(ptr, bp_side, mask_side), lev), a); +# endif + if (check_pc_bytes(&bp, bp_side, mask_side, a1_i, 0, &st.pc) != 0) + { + GOTO ber_detect; + } +# ifdef ENABLE_HR_MODE + b = L_add(L_shl(read_bit(ptr, bp_side, mask_side), lev), b); +# else + b = add(shl(read_bit(ptr, bp_side, mask_side), lev), b); +# endif + } + /* check for bitflip */ + IF (sub(lev, max_lev) == 0) + { + GOTO ber_detect; + } + + b1 = shr_pos(r, 2); + a1 = s_and(r, 0x3); +# ifdef ENABLE_HR_MODE + a = L_add(L_shl(a1, lev), a); + b = L_add(L_shl(b1, lev), b); +# else + a = add(shl(a1, lev), a); + b = add(shl(b1, lev), b); +# endif + IF (a > 0) + { + if (check_pc_bytes(&bp, bp_side, mask_side, a1_i, 0, &st.pc) != 0) + { + GOTO ber_detect; + } + if (read_bit(ptr, bp_side, mask_side) != 0) + { +# ifdef ENABLE_HR_MODE + a = L_negate(a); +# else + a = negate(a); +# endif + } + } + x[a1_i] = a; + move16(); + IF (b > 0) + { + if (check_pc_bytes(&bp, bp_side, mask_side, b1_i, 0, &st.pc) != 0) + { + GOTO ber_detect; + } + if (read_bit(ptr, bp_side, mask_side) != 0) + { +# ifdef ENABLE_HR_MODE + b = L_negate(b); +# else + b = negate(b); +# endif + } + } + x[b1_i] = b; + move16(); + c = add(shl_pos(s_and(c, 0xf), 4), add(esc_nb, 12)); + lsb_ind[lsb_ind_c++] = k; + move16(); + } + } + + test(); + test(); + IF ((sub(sub(bp, *bp_side), 3) > 0 && sub(st.pc.c_bp, st.pc.c_bp_side) == 0) || st.BER_detect > 0) +{ +GOTO ber_detect; +} + +a1_i += 2; +b1_i += 2; +} +} + +IF (L_spec > k) +{ +basop_memset(&x[k], 0, (L_spec - k) * sizeof(*x)); +} + + nbits_side = sub(nbbits, add(shl_pos(*bp_side, 3), sub(norm_s(*mask_side), 6))); + extra_bits = sub(norm_ul(st.ac_range_fx), 6); + nbits_ari = shl_pos(sub(bp, 3), 3); +IF (mode != 1) +{ +IF (st.pc.c_bp == 0) +{ +nbits_ari = shl_pos(sub(sub(bp, st.pc.bytes), 3), 3); +} +ELSE +{ +nbits_ari = shl_pos(add(bp, sub(sub(st.pc.b_left, st.pc.bytes), 3)), 3); +} + + IF (st.pc.c_bp_side != 0) + { + nbits_side = sub(add(sub(nbbits, shl_pos(st.pc.b_left, 3)), shl_pos(sub(st.pc.bytes, *bp_side), 3)), + sub(norm_s(*mask_side), 6)); + } + } + + n = sub(nbbits, add(nbits_ari, add(extra_bits, nbits_side))); + move16(); + +IF (n < 0) +{ +GOTO ber_detect; +} + + IF (lsbMode == 0) + { + *resBits = n; + move16(); + i=0; + +#ifdef ENABLE_HR_MODE + FOR (k = 0; k < L_spec; k++) + { + IF (x[k] != 0) + { + IF (n == 0) + { + BREAK; + } + if (check_pc_bytes(&bp, bp_side, mask_side, st.pc.inv_bin, 0, &st.pc) != 0) + { + GOTO ber_detect_res; + } + i1 = shr(i, RESBITS_PACK_SHIFT); + i2 = s_and(i, RESBITS_PACK_MASK); + resbit = read_bit(ptr, bp_side, mask_side); + if (resbit) + { + resQdata[i1] = (UWord8) s_or(resQdata[i1], shl(1, i2)); + } + i = add(i, 1); + move16(); + n = sub(n, 1); + } + } +#else + FOR (k = 0; k < L_spec; k++) + { + IF (x[k] != 0) + { + IF (n == 0) + { + BREAK; + } + + if (check_pc_bytes(&bp, bp_side, mask_side, st.pc.inv_bin, 0, &st.pc) != 0) + { + GOTO ber_detect_res; + } + + *resQdata++ = (UWord8) read_bit(ptr, bp_side, mask_side); + move16(); + n = sub(n, 1); + } + } +#endif + +# ifdef ENABLE_HR_MODE + if (hrmode) + { + Word16 idx_len = sub(*resBits, n); /* Number of nonzero bits */ + Word16 idx_len_lim = idx_len * EXT_RES_ITER_MAX; + + Word16 res_bits_hrmode = s_min(idx_len_lim, *resBits) - idx_len; + /* idx_len bits have been read in the previous loop */ + + for (k = 0; k < res_bits_hrmode; k++) + { + if (check_pc_bytes(&bp, bp_side, mask_side, st.pc.inv_bin, 0, &st.pc) != 0) + { + GOTO ber_detect_res; + } + i1 = shr(i, RESBITS_PACK_SHIFT); + i2 = s_and(i, RESBITS_PACK_MASK); + resbit = read_bit(ptr, bp_side, mask_side); + if (resbit) + { + resQdata[i1] = (UWord8) s_or(resQdata[i1], shl(1, i2)); + } + i = add(i, 1); + move16(); + n = sub(n, 1); + } + } +# endif + + *resBits = sub(*resBits, n); + } + ELSE + { + *resBits = 0; + FOR (k = 0; k < lsb_ind_c; k++) + { + a = x[lsb_ind[k]]; + move16(); + IF (n == 0) + { + BREAK; + } +if (check_pc_bytes(&bp, bp_side, mask_side, st.pc.inv_bin, 0, &st.pc) != 0) +{ +GOTO ber_detect_res; +} + tmp = read_bit(ptr, bp_side, mask_side); + n = sub(n, 1); + IF (tmp > 0) + { +# ifdef ENABLE_HR_MODE + if (a > 0) + { + a = L_add(a, 1); + } + if (a < 0) + { + a = L_sub(a, 1); + } +# else + if (a > 0) + { + a = add(a, 1); + } + if (a < 0) + { + a = sub(a, 1); + } +# endif + IF (a == 0) + { + IF (n == 0) + { + BREAK; + } + a = 1; +if (check_pc_bytes(&bp, bp_side, mask_side, st.pc.inv_bin, 0, &st.pc) != 0) +{ + GOTO ber_detect_res; +} +if (read_bit(ptr, bp_side, mask_side) != 0) +{ + a = negate(a); +} +n = sub(n, 1); +} +} + + x[lsb_ind[k]] = a; + move16(); + b = x[lsb_ind[k] + 1]; + move16(); + IF (n == 0) + { + BREAK; + } +if (check_pc_bytes(&bp, bp_side, mask_side, st.pc.inv_bin, 0, &st.pc) != 0) +{ +GOTO ber_detect_res; +} + tmp = read_bit(ptr, bp_side, mask_side); + n = sub(n, 1); + IF (tmp > 0) + { +# ifdef ENABLE_HR_MODE + if (b > 0) + { + b = L_add(b, 1); + } + if (b < 0) + { + b = L_sub(b, 1); + } +# else + if (b > 0) + { + b = add(b, 1); + } + if (b < 0) + { + b = sub(b, 1); + } +# endif + IF (b == 0) + { + IF (n == 0) + { + BREAK; + } + b = 1; +if (check_pc_bytes(&bp, bp_side, mask_side, st.pc.inv_bin, 0, &st.pc) != 0) +{ + GOTO ber_detect_res; +} + if (read_bit(ptr, bp_side, mask_side) != 0) + { + b = negate(b); + } + n = sub(n, 1); + } + } + x[lsb_ind[k] + 1] = b; + move16(); + } + } + +/* Noise Filling seed */ + tmp32 = L_deposit_l(0); + FOR (i = 0; i < L_spec; i++) + { +# ifdef ENABLE_HR_MODE + tmp32 = L_mac0(tmp32, L_and(L_abs(x[i]), 32767), i); +# else + tmp32 = L_mac0(tmp32, abs_s(x[i]), i); +# endif + } + *nf_seed = extract_l(tmp32); + move16(); + + /* Detect zero frame */ + test(); + test(); + test(); + test(); + IF (sub(lastnz, 2) == 0 && sub(x[0], 0) == 0 && sub(x[1], 0) == 0 && sub(gg_idx, 0) == 0 && sub(fac_ns_idx, 7) == 0) + { + *zero_frame = 1; + move16(); + } + ELSE + { + *zero_frame = 0; + move16(); + } + +IF (mode == 1) + { + IF (st.pc.bytes > 0) + { + IF (sub(st.pc.b_left, shr_pos(nbbits, 3)) > 0) + { + *b_left = sub(*bp_side, st.pc.bytes); + } + } + } +IF (mode == 2) +{ +IF (st.pc.bytes > 0) +{ +IF (sub(st.pc.b_left, shr_pos(nbbits,3)) > 0) +{ +*b_left = *bp_side; +} +} +} + +IF (sub(*bfi, 2) == 0) +{ +IF (sub(*spec_inv_idx, L_spec) == 0) +{ +*bfi = 0; +} +} +GOTO bail; + +/* goto for bit error handling */ +ber_detect: + *bfi = 1; + move16(); + *b_left = st.pc.b_left; + move16(); + test(); + IF (st.pc.inv_bin > 0 && sub(st.pc.inv_bin, L_spec) <= 0) + { + *spec_inv_idx = st.pc.inv_bin; + move16(); + *bfi = 2; + move16(); + *resBits = 0; + move16(); + *zero_frame = 0; + move16(); + /* Noise Filling seed */ + tmp32 = L_deposit_l(0); + FOR (i = 0; i < *spec_inv_idx; i++) + { + tmp32 = L_mac0(tmp32, abs_s(x[i]), i); + } + *nf_seed = extract_l(tmp32); + move16(); + } +GOTO bail; + +/* goto for bit error handling in residual signal */ +ber_detect_res: + *b_left = st.pc.b_left; + move16(); + *resBits = 0; + move16(); + *bfi = 0; + move16(); + *zero_frame = 0; + move16(); + /* Noise Filling seed */ + tmp32 = L_deposit_l(0); + FOR (i = 0; i < *spec_inv_idx; i++) + { + tmp32 = L_mac0(tmp32, abs_s(x[i]), i); + } + *nf_seed = extract_l(tmp32); + move16(); + GOTO bail; + +/* goto, because of dynmem out */ +bail: +Dyn_Mem_Deluxe_Out(); +} + + +void processAriDecoderScaling_fx( +# ifdef ENABLE_HR_MODE + Word32 *datain, +# else + Word16 *data16, +# endif + Word16 dataLen, Word32 *data32, Word16 *data_e) +{ + Word32 i; + +# ifdef ENABLE_HR_MODE + Dyn_Mem_Deluxe_In(Word16 shift; Word32 tmp, x_min, x_max;); +# else + Dyn_Mem_Deluxe_In(Word16 shift; Word16 tmp, x_min, x_max;); +# endif + + +#ifdef ENABLE_HR_MODE + x_max = 0; + move32(); + x_min = 0; + move32(); +#else + x_max = 0; + move16(); + x_min = 0; + move16(); +#endif + + FOR (i = 0; i < dataLen; i++) + { +#ifdef ENABLE_HR_MODE + if (datain[i] > 0) + x_max = L_max(x_max, datain[i]); + if (datain[i] < 0) + x_min = L_min(x_min, datain[i]); +#else + if (data16[i] > 0) + x_max = s_max(x_max, data16[i]); + if (data16[i] < 0) + x_min = s_min(x_min, data16[i]); +#endif + } + +#ifdef ENABLE_HR_MODE + tmp = L_max(x_max, L_negate(x_min)); + shift = norm_l(tmp); + if (tmp == 0) + { + shift = 31; + move32(); + } +#else + tmp = s_max(x_max, negate(x_min)); + shift = norm_s(tmp); + if (tmp == 0) + { + shift = 15; + move16(); + } +#endif + + FOR (i = 0; i < dataLen; i++) + { +#ifdef ENABLE_HR_MODE + data32[i] = L_shl_pos(datain[i], shift); +#else + data32[i] = L_shl_pos(L_deposit_h(data16[i]), shift); +#endif + } + +#ifdef ENABLE_HR_MODE + *data_e = sub(31, shift); + move16(); +#else + *data_e = sub(15, shift); + move16(); +#endif + + Dyn_Mem_Deluxe_Out(); +} + + +/*************************************************************************/ +/*************************************************************************/ +/*************************************************************************/ + +/*************************************************************************/ + +static __forceinline UWord32 UL_addNs24(UWord32 UL_var1, UWord32 UL_var2, UWord16 *wrap) +{ + return UL_lshr(UL_addNs(UL_lshl(UL_var1, 8), UL_lshl(UL_var2, 8), wrap), 8); +} +#ifdef ENABLE_HR_MODE +Word16 find_last_nz_pair(const Word32 x[], Word16 length) +#else +Word16 find_last_nz_pair(const Word16 x[], Word16 length) +#endif +{ + Dyn_Mem_Deluxe_In(Word16 last_nz, lobs[4]; Word32 stage, i;); + + lobs[0] = 4; + move16(); + lobs[1] = shr_pos(length, 1); /* length/2 */ + move16(); + lobs[2] = add(lobs[1], shr_pos(length, 2)); + move16(); + lobs[3] = add(lobs[2], shr_pos(length, 3)); + move16(); + + last_nz = 0; + move16(); + i = length; + move16(); + FOR (stage = 3; stage >= 0; --stage) + { + /* unmapped kernel */ + FOR (; i >= lobs[stage]; i -= 2) + { + if (x[i - 2] != 0) + { + last_nz = s_max(last_nz, i); + } + if (x[i - 1] != 0) + { + last_nz = s_max(last_nz, i); + } + } + IF (last_nz > 0) + { + BREAK; + } + } + + Dyn_Mem_Deluxe_Out(); + return s_max(last_nz, 2); +} + + +void write_bit_backward(UWord8 *ptr, Word16 *bp, Word16 *mask, Word16 bit) +{ + if (bit > 0) + { + ptr[*bp] = (UWord8)s_or((Word16)ptr[*bp], *mask); + move16(); + } + *mask = lshl_pos(*mask, 1); + move16(); + if (sub(*mask, 0x100) == 0) + { + *mask = 1; + move16(); + } + if (sub(*mask, 1) == 0) + { + *bp = sub(*bp, 1); + move16(); + } +} + + +void write_indice_backward(UWord8 *ptr, Word16 *bp, Word16 *mask, Word16 indice, Word16 numbits) +{ + Dyn_Mem_Deluxe_In(Word32 k; Word16 bit;); + + FOR (k = 0; k < numbits; k++) + { + bit = s_and(indice, 1); + write_bit_backward(ptr, bp, mask, bit); + indice = lshr(indice, 1); + } + + Dyn_Mem_Deluxe_Out(); +} + + +static __forceinline void write_indice_forward(UWord8 *ptr, Word16 bp, Word16 indice, Word16 numbits) +{ + Dyn_Mem_Deluxe_In(Word32 k; Word16 bit, mask, tmp;); + + tmp = (Word16)ptr[bp]; + move16(); + mask = 0x80; + move16(); + FOR (k = 0; k < numbits; k++) + { + bit = s_and(indice, mask); + tmp = s_or(tmp, mask); + if (bit == 0) + { + tmp = sub(tmp, mask); + } + mask = lshr(mask, 1); + } + ptr[bp] = (UWord8)tmp; + move16(); + + Dyn_Mem_Deluxe_Out(); +} + +static __forceinline void ac_enc_init_fx(Encoder_State_fx *st_fx) /* i/o: Encoder state */ +{ + st_fx->ac_low_fx = L_deposit_l(0); + move32(); + st_fx->ac_range_fx = 0x00ffffff; + move32(); + st_fx->ac_cache_fx = -1; + move16(); + st_fx->ac_carry_fx = 0; + move16(); + st_fx->ac_carry_count_fx = 0; + move16(); +} + +static __forceinline void ac_enc_shift_fx(UWord8 *ptr, Word16 *bp, Encoder_State_fx *st_fx) /* i/o: Encoder state */ +{ + test(); + L_sub(0, 0); /* For comparision in if */ + IF (st_fx->ac_low_fx < (0x00ff0000UL) || sub(st_fx->ac_carry_fx, 1) == 0) + { + IF (st_fx->ac_cache_fx >= 0) + { + ptr[(*bp)++] = (UWord8)add(st_fx->ac_cache_fx, st_fx->ac_carry_fx); + move16(); + } + + WHILE (st_fx->ac_carry_count_fx > 0) + { + ptr[(*bp)++] = (UWord8)s_and(add(st_fx->ac_carry_fx, 0xff), 255); + move16(); + st_fx->ac_carry_count_fx = sub(st_fx->ac_carry_count_fx, 1); + move16(); + } + + st_fx->ac_cache_fx = u_extract_l(UL_lshr_pos(st_fx->ac_low_fx, 16)); + move16(); + st_fx->ac_carry_fx = 0; + move16(); + } + ELSE + { + st_fx->ac_carry_count_fx = add(st_fx->ac_carry_count_fx, 1); + move16(); + } + st_fx->ac_low_fx = UL_and(UL_lshl_pos(st_fx->ac_low_fx, 8), 0x00ffffff); + move32(); +} + +static __forceinline void ac_encode_fx(UWord8 *ptr, Word16 *bp, Encoder_State_fx *st_fx, /* i/o: Encoder state */ + UWord32 cum_freq, /* i : Cumulative frequency up to symbol */ + UWord32 sym_freq) /* i : Symbol probability */ +{ + Dyn_Mem_Deluxe_In(UWord32 r, tmp; UWord16 carry;); + + r = UL_lshr_pos(st_fx->ac_range_fx, 10); + tmp = UL_Mpy_32_32(r, cum_freq); + + assert(r < (1U << 24)); + assert(cum_freq < (1U << 24)); + assert(tmp < (1U << 24)); + assert(st_fx->ac_low_fx < (1U << 24)); + st_fx->ac_low_fx = UL_addNs24(st_fx->ac_low_fx, tmp, &carry); + move32(); + + if (carry != 0) + { + st_fx->ac_carry_fx = carry; + move16(); + } + + st_fx->ac_range_fx = UL_Mpy_32_32(r, sym_freq); + move32(); + + assert(cum_freq < (1U << 24)); + assert(st_fx->ac_range_fx < (1U << 24)); + WHILE (st_fx->ac_range_fx < (1U << 16)) + { + L_sub(0, 0); /* Comparison in while */ + st_fx->ac_range_fx = UL_lshl_pos(st_fx->ac_range_fx, 8); + move32(); + + assert(st_fx->ac_range_fx < (1U << 24)); + + ac_enc_shift_fx(ptr, bp, st_fx); + } + + Dyn_Mem_Deluxe_Out(); +} + +static __forceinline Word16 ac_enc_finish_fx(UWord8 *ptr, Word16 *bp, Encoder_State_fx *st_fx) /* i/o: Encoder state */ +{ + Dyn_Mem_Deluxe_In(UWord32 val, mask, high; Word16 bits; UWord16 over1, over2;); + + /*bits = 24 - log2_i(st->ac_range); */ + bits = sub(norm_ul(st_fx->ac_range_fx), 7); + + mask = UL_lshr(0x00ffffff, bits); + + val = UL_addNs24(st_fx->ac_low_fx, mask, &over1); + high = UL_addNs24(st_fx->ac_low_fx, st_fx->ac_range_fx, &over2); + + L_xor(0, 0); /* For bit not */ + UL_and(1U, 1U); /* added counters */ + val = L_and(val, (~mask) & 0x00ffffff); + + L_xor(0, 0); /* For bit not */ + IF ((L_xor(over1, over2)) == 0) + { + L_sub(0, 0); /* For comparision in if */ + IF (UL_addNsD(val, mask) >= high) + { + bits = add(bits, 1); + mask = UL_lshr_pos(mask, 1); + val = UL_and(UL_addNsD(st_fx->ac_low_fx, mask), (~mask) & 0x00ffffff); + L_xor(0, 0); + UL_and(1, 1); /* For bit not , mask */ + } + + if (val < st_fx->ac_low_fx) + { + st_fx->ac_carry_fx = 1; + move16(); + } + } + + st_fx->ac_low_fx = val; + move32(); + + FOR (; bits > 0; bits -= 8) + { + ac_enc_shift_fx(ptr, bp, st_fx); + } + bits = add(bits, 8); + + assert(st_fx->ac_carry_fx == 0); + + IF (st_fx->ac_carry_count_fx > 0) + { + ptr[(*bp)++] = (UWord8)st_fx->ac_cache_fx; + move16(); + + FOR (; st_fx->ac_carry_count_fx > 1; st_fx->ac_carry_count_fx--) + { + ptr[(*bp)++] = 0xff; + move16(); + } + write_indice_forward(ptr, *bp, lshr(0xff, sub(8, bits)), bits); + } + ELSE + { + write_indice_forward(ptr, *bp, st_fx->ac_cache_fx, bits); + } + + Dyn_Mem_Deluxe_Out(); + return bits; +} + + +__forceinline Word16 read_bit(UWord8 *ptr, Word16 *bp, Word16 *mask) +{ + Dyn_Mem_Deluxe_In(Word16 bit;); + + bit = 0; + move16(); + if (s_and((Word16)ptr[*bp], *mask) > 0) + { + bit = 1; + move16(); + } + *mask = lshl_pos(*mask, 1); + move16(); + if (sub(*mask, 0x100) == 0) + { + *mask = 1; + move16(); + } + if (sub(*mask, 1) == 0) + { + *bp = sub(*bp, 1); + move16(); + } + + Dyn_Mem_Deluxe_Out(); + return bit; +} + + +static __forceinline void ac_dec_init_fx(UWord8 *ptr, Word16 *bp, Word16 *bp_side, Word16 *mask_side, + Decoder_State_fx *st_fx) /* i/o: Decoder State */ +{ + Dyn_Mem_Deluxe_In(Word32 i;); + + + st_fx->ac_low_fx = L_deposit_l(0); + move32(); + + st_fx->ac_range_fx = 0x00ffffff; + move32(); + FOR (i = 0; i < 3; i++) + { + if (check_pc_bytes(bp, bp_side, mask_side, 0, 1, &st_fx->pc) != 0) + { + Dyn_Mem_Deluxe_Out(); + return; + } + st_fx->ac_low_fx = UL_addNsD(UL_lshl_pos(st_fx->ac_low_fx, 8), UL_deposit_l((Word16)ptr[(*bp)++])); + move32(); + assert(st_fx->ac_low_fx < (1U << 24)); + } + + st_fx->BER_detect = 0; + move16(); + + Dyn_Mem_Deluxe_Out(); +} + +/* o : Decoded cumulative frequency */ +static __forceinline Word16 ac_decode_fx(Decoder_State_fx *st_fx, /* i/o: Decoder State */ + Word16 pki) +{ + Dyn_Mem_Deluxe_In(UWord16 sgn; Word16 val, r;); + + st_fx->ac_help_fx = UL_lshr_pos(st_fx->ac_range_fx, 10); + move32(); + val = 0; + move16(); + + r = add(val, 8); + UL_subNs(st_fx->ac_low_fx, UL_Mpy_32_32(st_fx->ac_help_fx, ari_spec_cumfreq[pki][r]), &sgn); + if (sgn == 0) + { + val = r; + move16(); + } + + r = add(val, 4); + UL_subNs(st_fx->ac_low_fx, UL_Mpy_32_32(st_fx->ac_help_fx, ari_spec_cumfreq[pki][r]), &sgn); + if (sgn == 0) + { + val = r; + move16(); + } + + r = add(val, 2); + UL_subNs(st_fx->ac_low_fx, UL_Mpy_32_32(st_fx->ac_help_fx, ari_spec_cumfreq[pki][r]), &sgn); + if (sgn == 0) + { + val = r; + move16(); + } + + r = add(val, 1); + UL_subNs(st_fx->ac_low_fx, UL_Mpy_32_32(st_fx->ac_help_fx, ari_spec_cumfreq[pki][r]), &sgn); + IF (sgn == 0) + { + val = r; + move16(); + IF (sub(val, 15) == 0) + { + UL_subNs(st_fx->ac_low_fx, UL_Mpy_32_32(st_fx->ac_help_fx, ari_spec_cumfreq[pki][16]), &sgn); + if (sgn == 0) + { + val = 16; + move16(); + } + UL_subNs(st_fx->ac_low_fx, UL_lshl(st_fx->ac_help_fx, 10), &sgn); + if (sgn == 0) + { + st_fx->BER_detect = 1; + move16(); + } + } + } + + Dyn_Mem_Deluxe_Out(); + return val; +} + +/* o : Decoded cumulative frequency */ +static __forceinline Word16 ac_decode_tns_order(Decoder_State_fx *st_fx, /* i/o: Decoder State */ + Word16 enable_lpc_weighting) +{ + Dyn_Mem_Deluxe_In(UWord16 sgn; Word16 val, r;); + + st_fx->ac_help_fx = UL_lshr_pos(st_fx->ac_range_fx, 10); + move32(); + val = 0; + move16(); + + r = add(val, 4); + UL_subNs(st_fx->ac_low_fx, UL_Mpy_32_32(st_fx->ac_help_fx, ac_tns_order_cumfreq[enable_lpc_weighting][r]), &sgn); + if (sgn == 0) + { + val = r; + move16(); + } + + r = add(val, 2); + UL_subNs(st_fx->ac_low_fx, UL_Mpy_32_32(st_fx->ac_help_fx, ac_tns_order_cumfreq[enable_lpc_weighting][r]), &sgn); + if (sgn == 0) + { + val = r; + move16(); + } + + r = add(val, 1); + UL_subNs(st_fx->ac_low_fx, UL_Mpy_32_32(st_fx->ac_help_fx, ac_tns_order_cumfreq[enable_lpc_weighting][r]), &sgn); + if (sgn == 0) + { + val = r; + move16(); + } + + UL_subNs(st_fx->ac_low_fx, UL_lshl(st_fx->ac_help_fx, 10), &sgn); + if (sgn == 0) + { + st_fx->BER_detect = 1; + move16(); + } + + Dyn_Mem_Deluxe_Out(); + return val; +} + +/* o : Decoded cumulative frequency */ +static __forceinline Word16 ac_decode_tns_coef(Decoder_State_fx *st_fx, /* i/o: Decoder State */ + Word16 pki) +{ + Dyn_Mem_Deluxe_In(UWord16 sgn; Word16 val, r;); + + st_fx->ac_help_fx = UL_lshr_pos(st_fx->ac_range_fx, 10); + move32(); + val = 0; + move16(); + + r = add(val, 8); + UL_subNs(st_fx->ac_low_fx, UL_Mpy_32_32(st_fx->ac_help_fx, ac_tns_coef_cumfreq[pki][r]), &sgn); + if (sgn == 0) + { + val = r; + move16(); + } + + r = add(val, 4); + UL_subNs(st_fx->ac_low_fx, UL_Mpy_32_32(st_fx->ac_help_fx, ac_tns_coef_cumfreq[pki][r]), &sgn); + if (sgn == 0) + { + val = r; + move16(); + } + + r = add(val, 2); + UL_subNs(st_fx->ac_low_fx, UL_Mpy_32_32(st_fx->ac_help_fx, ac_tns_coef_cumfreq[pki][r]), &sgn); + if (sgn == 0) + { + val = r; + move16(); + } + + r = add(val, 1); + UL_subNs(st_fx->ac_low_fx, UL_Mpy_32_32(st_fx->ac_help_fx, ac_tns_coef_cumfreq[pki][r]), &sgn); + if (sgn == 0) + { + val = r; + move16(); + IF (sub(val, 15) == 0) + { + UL_subNs(st_fx->ac_low_fx, UL_Mpy_32_32(st_fx->ac_help_fx, ac_tns_coef_cumfreq[pki][16]), &sgn); + if (sgn == 0) + { + val = 16; + move16(); + } + UL_subNs(st_fx->ac_low_fx, UL_lshl(st_fx->ac_help_fx, 10), &sgn); + if (sgn == 0) + { + st_fx->BER_detect = 1; + move16(); + } + } + } + + Dyn_Mem_Deluxe_Out(); + return val; +} + +static __forceinline Word16 ac_dec_update_fx(UWord8 *ptr, Word16 *bp, Word16 *bp_side, Word16 *mask_side, + Word16 cur_bin, Decoder_State_fx *st_fx, /* i/o: Decoder State */ + UWord32 cum_freq, /* i : Cumulative frequency */ + UWord32 sym_freq /* i : Symbol frequency */ +) +{ + UWord32 UL_tmp; + + + assert(st_fx->ac_help_fx < (1U << 24)); + assert(cum_freq < (1U << 24)); + + UL_tmp = UL_Mpy_32_32(cum_freq, st_fx->ac_help_fx); + assert(UL_tmp < (1U << 24)); + + st_fx->ac_low_fx = UL_subNsD(st_fx->ac_low_fx, UL_tmp); + move32(); /*0+0*/ + assert(st_fx->ac_low_fx < (1U << 24)); + + st_fx->ac_range_fx = UL_Mpy_32_32(st_fx->ac_help_fx, sym_freq); + move32(); + + assert(st_fx->ac_range_fx < (1U << 24)); + /* updated to 16 from 24 */ + WHILE (st_fx->ac_range_fx < (1U << 16)) + { + L_sub(0, 0); /* For comparision in while*/ + + st_fx->ac_low_fx = + UL_and(st_fx->ac_low_fx, 0x0000ffFF); /* make sure upshift doe not lead to more than 24 bits */ + assert(st_fx->ac_low_fx < 1U << 16); + + if (check_pc_bytes(bp, bp_side, mask_side, cur_bin, 1, &st_fx->pc) != 0) + return 1; + + /*shift in 8 bits */ + st_fx->ac_low_fx = UL_addNsD(UL_lshl_pos(st_fx->ac_low_fx, 8), UL_deposit_l((Word16)ptr[(*bp)++])); + move32(); + + assert(st_fx->ac_low_fx < (1U << 24)); + st_fx->ac_range_fx = UL_lshl_pos(st_fx->ac_range_fx, 8); + move32(); + assert(st_fx->ac_range_fx < (1U << 24)); + } + return 0; +} + +static __forceinline void pc_init_fx(Word16 n_pc, Word16 numbytes, Word16 be_bp_left, Word16 be_bp_right, Word16 L_spec, + Word16 enc, Word16 sim_dec, Word16 bfi, Pc_State_fx *pc /* i/o: Pc State */ +) +{ +pc->inv_bin = add(L_spec, 1); move16(); +pc->numbytes = numbytes; move16(); +pc->c_bp = 0; move16(); +pc->c_bp_side = 0; move16(); +pc->bytes = shr(add(n_pc, 1),1); move16(); +pc->b_left = add(numbytes,1); move16(); +pc->b_right = -1; move16(); +pc->enc = enc; move16(); +pc->sim_dec = sim_dec; move16(); +pc->bfi = bfi; move16(); +pc->be_bp_left = shr(be_bp_left, 3); move16(); +pc->be_bp_right = shr(be_bp_right, 3); move16(); + assert(pc->be_bp_right < pc->bytes || pc->bytes == 0); +} + +static __forceinline Word16 check_pc_bytes(Word16 *bp, Word16 *bp_side, Word16 *mask_side, Word16 cur_bin, + Word16 from_left, Pc_State_fx *pc /* i/o: Pc State */) +{ + Dyn_Mem_Deluxe_In(Word16 bp_local, bp_side_local, offset;); + + IF (pc->bytes > 0) + { + test(); + IF (from_left == 0 && sub(*mask_side, 1) != 0) + { + Dyn_Mem_Deluxe_Out(); + return 0; + } + test(); + IF (pc->c_bp_side > 0 && *bp_side < 0) + { + assert(*mask_side == 1); + assert(pc->b_right != -1); + *bp_side = pc->b_right; + Dyn_Mem_Deluxe_Out(); + return 0; + } + bp_local = *bp; + bp_side_local = *bp_side; + + IF (from_left != 0) + { + if (sub(*mask_side, 1) == 0) + { + bp_side_local = add(bp_side_local, 1); + } + } + ELSE + { + bp_local = sub(bp_local, 1); + } + + IF (pc->b_right < 0) + { + offset = -1; + move16(); + if (pc->enc == 0) + { + offset = add(offset, pc->bytes); + } + + IF (add(bp_side_local, sub(offset, bp_local)) == pc->bytes) + { + pc->b_left = add(bp_local, 1); + pc->b_right = sub(bp_side_local, 1); + IF (pc->enc != 0) + { + assert(pc->b_right - pc->b_left + 1 == pc->bytes); + Dyn_Mem_Deluxe_Out(); + return 1; + } + } + } + + test(); + IF (pc->enc == 0 && pc->b_right >= 0) + { + test(); + IF (from_left != 0 && sub(*bp, pc->b_left) == 0) + { + IF (pc->sim_dec == 1) + { + pc->b_left = *bp; + Dyn_Mem_Deluxe_Out(); + return 1; + } + *bp = 0; move16(); + pc->c_bp = 1; move16(); + } + test(); + IF (from_left == 0 && sub(bp_side_local, pc->b_right) == 0) + { + *bp_side = sub(pc->bytes, 1); + move16(); + pc->c_bp_side = 1; + move16(); + } + IF (sub(pc->bfi, 2) == 0) + { + test(); + test(); + IF ((pc->c_bp != 0 && sub(*bp, pc->be_bp_left) >= 0) || + (pc->c_bp_side != 0 && sub(*bp_side, pc->be_bp_right) <= 0)) + { + pc->inv_bin = cur_bin; + move16(); + Dyn_Mem_Deluxe_Out(); + return 1; + } + ELSE IF ((pc->c_bp != 0 && *bp >= 0) || (pc->c_bp_side != 0 && sub(*bp_side, sub(pc->bytes, 1)) <= 0)) + { + pc->inv_bin = s_min(pc->inv_bin, cur_bin); + Dyn_Mem_Deluxe_Out(); + return 0; + } + } + } + } + + Dyn_Mem_Deluxe_Out(); + return 0; +} + diff --git a/lib_lc3plus/attack_detector_fx.c b/lib_lc3plus/attack_detector_fx.c new file mode 100644 index 0000000000000000000000000000000000000000..3c62f849405daf62e1c5eee0caa2f15c1b9a983f --- /dev/null +++ b/lib_lc3plus/attack_detector_fx.c @@ -0,0 +1,119 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.5 * +* 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 "functions.h" + +void attack_detector_fx(LC3PLUS_Enc *enc, EncSetup *setup, Word16 *input, Word16 input_scaling, void *scratch) +{ + Dyn_Mem_Deluxe_In( + int i, j, position; + Word32 tmp, *block_energy; + Word16 h16, l16, new_scaling, rescale, input_delta_scaling; + Word16 scales[3], *input_16k; + Word16 frame_length_16k; + ); + + block_energy = scratchAlign(scratch, 0); + input_16k = scratchAlign(block_energy, 4 * 4 + 4); + frame_length_16k = DEPR_i_mult(enc->attdec_nblocks, 40); + + IF (setup->attack_handling) + { + /* input scaling */ + scales[0] = add(getScaleFactor16(input, enc->frame_length), input_scaling); + scales[1] = add(getScaleFactor16_0(setup->attdec_filter_mem, 2), setup->attdec_scaling); + scales[2] = + shr(add(add(getScaleFactor32_0(&setup->attdec_acc_energy, 1), shl(setup->attdec_scaling, 1)), 1), 1); + new_scaling = s_min(scales[0], s_min(scales[1], scales[2])); + + new_scaling = sub(new_scaling, 2); /* add overhead for resampler*/ + + /* memory re-scaling */ + rescale = sub(new_scaling, setup->attdec_scaling); + + IF (rescale) + { + rescale = s_min(s_max(rescale, -15), 15); + setup->attdec_filter_mem[0] = shl(setup->attdec_filter_mem[0], rescale); move16(); + setup->attdec_filter_mem[1] = shl(setup->attdec_filter_mem[1], rescale); move16(); + setup->attdec_acc_energy = L_shl(setup->attdec_acc_energy, shl(rescale, 1)); move16(); + } + setup->attdec_scaling = new_scaling; move16(); + + SWITCH (enc->fs) + { + case 32000: + input_delta_scaling = sub(1, sub(new_scaling, input_scaling)); + FOR (i = 0; i < frame_length_16k; i++) + { + input_16k[i] = add(shr(input[2 * i + 0], input_delta_scaling), + shr(input[2 * i + 1], input_delta_scaling)); move16(); + } + break; + case 48000: + input_delta_scaling = sub(2, sub(new_scaling, input_scaling)); + FOR (i = 0; i < frame_length_16k; i++) + { + input_16k[i] = add(shr(input[3 * i + 0], input_delta_scaling), + add(shr(input[3 * i + 1], input_delta_scaling), + shr(input[3 * i + 2], input_delta_scaling))); move16(); + } + break; + default: ASSERT(!"sampling rate not supported in function attack_detector_fx!"); break; + } + + input_16k[-2] = setup->attdec_filter_mem[0]; move16(); + input_16k[-1] = setup->attdec_filter_mem[1]; move16(); + setup->attdec_filter_mem[0] = input_16k[frame_length_16k - 2]; move16(); + setup->attdec_filter_mem[1] = input_16k[frame_length_16k - 1]; move16(); + + FOR (i = frame_length_16k - 1; i >= 0; i--) + { + tmp = L_mult(input_16k[i], 12288); + tmp = L_msu(tmp, input_16k[i - 1], 16384); + tmp = L_mac(tmp, input_16k[i - 2], 4096); + + input_16k[i] = extract_h(tmp); move16(); + } + + basop_memset(block_energy, 0, 4 * sizeof(Word32)); + + FOR (j = 0; j < enc->attdec_nblocks; j++) + { + FOR (i = 0; i < 40; i++) + { + block_energy[j] = L_mac(block_energy[j], input_16k[i + j*40], input_16k[i + j*40]); move16(); + } + } + + setup->attdec_detected = setup->attdec_position >= enc->attdec_hangover_thresh; + test(); move16(); + position = -1; move16(); + + FOR (i = 0; i < enc->attdec_nblocks; i++) + { + /* block_energy[i] / 8.5 */ + l16 = extract_l(L_shr(block_energy[i], 1)); + l16 = s_and(l16, 0x7fff); + h16 = extract_h(block_energy[i]); + tmp = L_shr(L_mult0(l16, 30840), 15); + tmp = L_shr(L_mac0(tmp, h16, 30840), 2); + + IF (tmp > setup->attdec_acc_energy) + { + position = i; move16(); + setup->attdec_detected = 1; move16(); + } + setup->attdec_acc_energy = L_max(L_shr(setup->attdec_acc_energy, 2), block_energy[i]); move16(); + } + setup->attdec_position = position; move16(); + } + + Dyn_Mem_Deluxe_Out(); +} diff --git a/lib_lc3plus/basop_mpy_lc3plus.c b/lib_lc3plus/basop_mpy_lc3plus.c new file mode 100644 index 0000000000000000000000000000000000000000..88a6d336bb1408357c6761888b8bd3e7be2e460d --- /dev/null +++ b/lib_lc3plus/basop_mpy_lc3plus.c @@ -0,0 +1,99 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.5 * +* 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 "defines.h" + +#include "functions.h" + +#ifdef ENABLE_HR_MODE +Word32 Mpy_32_32_0(Word32 x, Word32 y) +{ + Word32 z; + + z = L_shr(L_add(Mpy_32_32_lc3plus(x, y),1), 1); + + return (z); +} + +Word32 Mpy_32_16_0(Word32 x, Word16 y) +{ + Word32 z; + + z = L_shr(L_add(Mpy_32_16_lc3plus(x, y),1), 1); + + return (z); +} +#endif + +Word32 Mpy_32_16_lc3plus(Word32 x, Word16 y) +{ + Word32 mh; + UWord16 ml; + + Mpy_32_16_ss(x, y, &mh, &ml); + + return (mh); +} + + +Word32 Mpy_32_32_lc3plus(Word32 x, Word32 y) +{ + Word32 mh; + UWord32 ml; + + Mpy_32_32_ss(x, y, &mh, &ml); + + return (mh); +} + + +void cplxMpy_32_16(Word32 *c_Re, Word32 *c_Im, const Word32 a_Re, const Word32 a_Im, const Word16 b_Re, + const Word16 b_Im) +{ + *c_Re = L_sub(Mpy_32_16_lc3plus(a_Re, b_Re), Mpy_32_16_lc3plus(a_Im, b_Im)); move32(); + *c_Im = L_add(Mpy_32_16_lc3plus(a_Re, b_Im), Mpy_32_16_lc3plus(a_Im, b_Re)); move32(); +} + +void cplxMpy_32_32(Word32 *c_Re, Word32 *c_Im, const Word32 a_Re, const Word32 a_Im, const Word32 b_Re, + const Word32 b_Im) +{ + *c_Re = L_sub(Mpy_32_32_lc3plus(a_Re, b_Re), Mpy_32_32_lc3plus(a_Im, b_Im)); move32(); + *c_Im = L_add(Mpy_32_32_lc3plus(a_Re, b_Im), Mpy_32_32_lc3plus(a_Im, b_Re)); move32(); +} + +#ifdef ENABLE_HR_MODE +Word32 Mac_32_16_0(Word32 z, Word32 x, Word16 y) +{ + z = L_add(z, Mpy_32_16_0(x, y)); + + return (z); +} + +Word32 Mac_32_32_0(Word32 z, Word32 x, Word32 y) +{ + z = L_add(z, Mpy_32_32_0(x, y)); + + return (z); +} + +Word32 Msu_32_16_0(Word32 z, Word32 x, Word16 y) +{ + z = L_sub(z, Mpy_32_16_0(x, y)); + + return (z); +} + +Word32 Msu_32_32_0(Word32 z, Word32 x, Word32 y) +{ + z = L_sub(z, Mpy_32_32_0(x, y)); + + return (z); +} + +#endif /* #ifdef ENABLE_HR_MODE */ diff --git a/lib_lc3plus/basop_mpy_lc3plus.h b/lib_lc3plus/basop_mpy_lc3plus.h new file mode 100644 index 0000000000000000000000000000000000000000..72c7d91bbf3f94dde0eedce832cf6265dc3f794a --- /dev/null +++ b/lib_lc3plus/basop_mpy_lc3plus.h @@ -0,0 +1,94 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.5 * +* 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 "defines.h" + +#ifndef __BASOP_MPY_LC3PLUS_H +#define __BASOP_MPY_LC3PLUS_H + +#include "functions.h" + +#ifdef ENABLE_HR_MODE +Word32 Mpy_32_16_0(Word32 x, Word16 y); +#endif + +Word32 Mac_32_16_0(Word32 z, Word32 x, Word16 y); +Word32 Mpy_32_32_0(Word32 x, Word32 y); +Word32 Mac_32_32_0(Word32 z, Word32 x, Word32 y); +Word32 Msu_32_16_0(Word32 z, Word32 x, Word16 y); +Word32 Msu_32_32_0(Word32 z, Word32 x, Word32 y); + +/** + * \brief 32*16 Bit fractional Multiplication using 40 bit OPS + * Performs a multiplication of a 32-bit variable x by + * a 16-bit variable y, returning a 32-bit value. + * + * \param[i] x + * \param[i] y + * + * \return x*y + */ +Word32 Mpy_32_16_lc3plus(Word32 x, Word16 y); + +/** + * \brief 32*32 Bit fractional Multiplication using 40 bit OPS + * + * Performs a multiplication of a 32-bit variable x by + * a 32-bit variable y, returning a 32-bit value. + * + * \param[i] x + * \param[i] y + * + * \return x*y + */ +Word32 Mpy_32_32_lc3plus(Word32 x, Word32 y); + +#ifdef CR8_F_ADAPT_MDCT_DCT_PRECISION + +# ifdef ENABLE_HR_MODE +# define cplxMpy32_32_32_2(re, im, a, b, c, d) \ + do \ + { \ + re = L_sub(Mpy_32_32_0(a, c), Mpy_32_32_0(b, d)); \ + im = L_add(Mpy_32_32_0(a, d), Mpy_32_32_0(b, c)); \ + } while (0) +# endif +# define cplxMpy32_32_16_2(re, im, a, b, c, d) \ + do \ + { \ + re = L_sub(L_shr_pos(Mpy_32_16_lc3plus(a, c), 1), L_shr_pos(Mpy_32_16_lc3plus(b, d), 1)); \ + im = L_add(L_shr_pos(Mpy_32_16_lc3plus(a, d), 1), L_shr_pos(Mpy_32_16_lc3plus(b, c), 1)); \ + } while (0) + + +#else /* CR8_F_ADAPT_MDCT_DCT_PRECISION */ + +# ifdef ENABLE_HR_MODE +# define cplxMpy32_32_32_2(re, im, a, b, c, d) \ + do \ + { \ + re = L_sub(Mpy_32_32_0(a, c), Mpy_32_32_0(b, d)); \ + im = L_add(Mpy_32_32_0(a, d), Mpy_32_32_0(b, c)); \ + } while (0) +# endif +# define cplxMpy32_32_16_2(re, im, a, b, c, d) \ + do \ + { \ + re = L_sub(L_shr_pos(Mpy_32_16_lc3plus(a, c), 1), L_shr_pos(Mpy_32_16_lc3plus(b, d), 1)); \ + im = L_add(L_shr_pos(Mpy_32_16_lc3plus(a, d), 1), L_shr_pos(Mpy_32_16_lc3plus(b, c), 1)); \ + } while (0) + +#endif /* CR8_F_ADAPT_MDCT_DCT_PRECISION */ + +void cplxMpy_32_16(Word32 *c_Re, Word32 *c_Im, const Word32 a_Re, const Word32 a_Im, const Word16 b_Re, + const Word16 b_Im); +void cplxMpy_32_32(Word32 *c_Re, Word32 *c_Im, const Word32 a_Re, const Word32 a_Im, const Word32 b_Re, + const Word32 b_Im); + +#endif /* __BASOP_MPY_LC3PLUS_H */ diff --git a/lib_lc3plus/basop_util_lc3plus.c b/lib_lc3plus/basop_util_lc3plus.c new file mode 100644 index 0000000000000000000000000000000000000000..9f2d6be79dd00b5aa8435ece1fa2114f0d6990fe --- /dev/null +++ b/lib_lc3plus/basop_util_lc3plus.c @@ -0,0 +1,1069 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.5 * +* 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 "defines.h" +#include "functions.h" +#include "rom_basop_util_lc3plus.h" +#include "basop_util_lc3plus.h" + +extern const Word32 SqrtTable_lc3plus[32]; +extern const Word16 SqrtDiffTable_lc3plus[32]; + +extern const Word32 ISqrtTable_lc3plus[32]; +extern const Word16 ISqrtDiffTable_lc3plus[32]; + +extern const Word32 InvTable_lc3plus[32]; +extern const Word16 InvDiffTable_lc3plus[32]; + +Word32 BASOP_Util_Log2_lc3plus(Word32 x) +{ + Word32 exp; + Word16 exp_e; + Word16 nIn; + Word16 accuSqr; + Word32 accuRes; + + assert(x >= 0); + + if (x == 0) + { + + return ((Word32)MIN_32); + } + + /* normalize input, calculate integer part */ + exp_e = norm_l(x); + x = L_shl(x, exp_e); + exp = L_deposit_l(exp_e); + + /* calculate (1-normalized_input) */ + nIn = extract_h(L_sub(MAX_32, x)); + + /* approximate ln() for fractional part (nIn *c0 + nIn^2*c1 + nIn^3*c2 + ... + nIn^8 *c7) */ + + /* iteration 1, no need for accumulation */ + accuRes = L_mult(nIn, ldCoeff_lc3plus[0]); /* nIn^i * coeff[0] */ + accuSqr = mult(nIn, nIn); /* nIn^2, nIn^3 .... */ + + /* iteration 2 */ + accuRes = L_mac(accuRes, accuSqr, ldCoeff_lc3plus[1]); /* nIn^i * coeff[1] */ + accuSqr = mult(accuSqr, nIn); /* nIn^2, nIn^3 .... */ + + /* iteration 3 */ + accuRes = L_mac(accuRes, accuSqr, ldCoeff_lc3plus[2]); /* nIn^i * coeff[2] */ + accuSqr = mult(accuSqr, nIn); /* nIn^2, nIn^3 .... */ + + /* iteration 4 */ + accuRes = L_mac(accuRes, accuSqr, ldCoeff_lc3plus[3]); /* nIn^i * coeff[3] */ + accuSqr = mult(accuSqr, nIn); /* nIn^2, nIn^3 .... */ + + /* iteration 5 */ + accuRes = L_mac(accuRes, accuSqr, ldCoeff_lc3plus[4]); /* nIn^i * coeff[4] */ + accuSqr = mult(accuSqr, nIn); /* nIn^2, nIn^3 .... */ + + /* iteration 6 */ + accuRes = L_mac(accuRes, accuSqr, ldCoeff_lc3plus[5]); /* nIn^i * coeff[5] */ + accuSqr = mult(accuSqr, nIn); /* nIn^2, nIn^3 .... */ + + /* iteration 7, no need to calculate accuSqr any more */ + accuRes = L_mac(accuRes, accuSqr, ldCoeff_lc3plus[6]); /* nIn^i * coeff[6] */ + + /* ld(fractional part) = ln(fractional part)/ln(2), 1/ln(2) = (1 + 0.44269504) */ + accuRes = L_mac0(L_shr(accuRes, 1), extract_h(accuRes), 14506); + + accuRes = L_shr(accuRes, LD_DATA_SCALE - 1); /* fractional part/LD_DATA_SCALE */ + exp = L_shl(exp, (31 - LD_DATA_SCALE)); /* integer part/LD_DATA_SCALE */ + accuRes = L_sub(accuRes, exp); /* result = integer part + fractional part */ + + return (accuRes); +} + +Word32 BASOP_Util_InvLog2_lc3plus(Word32 x) +{ +#ifdef ENABLE_HR_MODE + /* Original code was used for negative x and hence the exp was always 0, which is assumed */ + Word16 exp; + return BASOP_Util_InvLog2_pos(x, &exp); +#else + Word16 frac; + Word16 exp; + Word32 retVal; + UWord32 index3; + UWord32 index2; + UWord32 index1; + UWord32 lookup3f; + UWord32 lookup12; + UWord32 lookup; + + if (x < -1040187392l /*-31.0/64.0 Q31*/) + { + + return 0; + } + test(); + if ((L_sub(x, 1040187392l /*31.0/64.0 Q31*/) >= 0) || (x == 0)) + { + + return 0x7FFFFFFF; + } + + frac = extract_l(L_and(x, 0x3FF)); + + index3 = L_and(L_shr_pos(x, 10), 0x1F); + index2 = L_and(L_shr_pos(x, 15), 0x1F); + index1 = L_and(L_shr_pos(x, 20), 0x1F); + + exp = extract_l(L_shr_pos(x, 25)); + if (x > 0) + { + exp = sub(31, exp); + } + if (x < 0) + { + exp = negate(exp); + } + + lookup3f = L_add(exp2x_tab_long_lc3plus[index3], L_shr_pos(Mpy_32_16_lc3plus(0x0016302F, frac), 1)); + lookup12 = Mpy_32_32_lc3plus(exp2_tab_long_lc3plus[index1], exp2w_tab_long_lc3plus[index2]); + lookup = Mpy_32_32_lc3plus(lookup12, lookup3f); + + retVal = L_shr(lookup, sub(exp, 3)); + + return retVal; +#endif +} + +#ifdef ENABLE_HR_MODE +/* New function which works with positive and negative exponents */ +Word32 BASOP_Util_InvLog2_pos(Word32 x, Word16 *exp) +{ + Word16 frac; + Word16 ret_exp; + Word32 retVal; + UWord32 index3; + UWord32 index2; + UWord32 index1; + UWord32 lookup3f; + UWord32 lookup12; + UWord32 lookup; + + /* The usage of exp.mantissa format in LC3plus in Word32 is : floatval = mantissa / (2^(31 - exp)) */ + ret_exp = extract_l(L_shr(x, 25)); + + IF (x < -1040187392l /*-31.0/64.0 Q31*/) + { + *exp = 0; + move16(); + return 0; + } + test(); + IF ((L_sub(x, 1040187392l /*31.0/64.0 Q31*/) >= 0)) + { + *exp = 31; + move16(); + return 0x40000000; + } + ELSE IF(x == 0) + { + *exp = -1; + move16(); + return 0x10000000; + } + + frac = extract_l(L_and(x, 0x3FF)); + + index3 = L_and(L_shr(x, 10), 0x1F); + index2 = L_and(L_shr(x, 15), 0x1F); + index1 = L_and(L_shr(x, 20), 0x1F); + + lookup3f = L_add(exp2x_tab_long_lc3plus[index3], L_shr(Mpy_32_16_lc3plus(0x0016302F, frac), 1)); + lookup12 = Mpy_32_32_lc3plus(exp2_tab_long_lc3plus[index1], exp2w_tab_long_lc3plus[index2]); + lookup = Mpy_32_32_lc3plus(lookup12, lookup3f); + + IF (x > 0) + { + /* The returned exponent is the offset from 31, so the float result is + retVal / 2^(31 - *exp) */ + *exp = add(ret_exp, 3); + retVal = lookup; + } + ELSE + { + /* For negative powers provide the result in Q31 and ignore the exponent */ + *exp = 0; + retVal = L_shr(lookup, sub(negate(ret_exp), 3)); + } + + return retVal; +} +#endif + +/* local function for Sqrt16_lc3plus and Sqrt16norm */ +static Word16 Sqrt16_common(Word16 m, Word16 e) +{ + Word16 index, frac; + + assert((m >= 0x4000) || (m == 0)); + + /* get table index (upper 6 bits minus 32) */ + /* index = (m >> 9) - 32; */ + index = mac_r(-32768 - (32 << 16), m, 1 << 6); + + /* get fractional part for interpolation (lower 9 bits) */ + frac = s_and(m, 0x1FF); /* Q9 */ + + /* interpolate */ + if (m != 0) + { + m = mac_r(SqrtTable_lc3plus[index], SqrtDiffTable_lc3plus[index], frac); + } + + /* handle odd exponents */ + if (s_and(e, 1) != 0) + m = mult_r(m, 0x5a82); + + return m; +} + +/* local function for ISqrt16 and ISqrt16norm */ +static Word16 ISqrt16_common(Word16 m, Word16 e) +{ + Word16 index, frac; + + assert(m >= 0x4000); + + /* get table index (upper 6 bits minus 32) */ + /* index = (m >> 9) - 32; */ + index = mac_r(-32768 - (32 << 16), m, 1 << 6); + + /* get fractional part for interpolation (lower 9 bits) */ + frac = s_and(m, 0x1FF); /* Q9 */ + + /* interpolate */ + m = msu_r(ISqrtTable_lc3plus[index], ISqrtDiffTable_lc3plus[index], frac); + + /* handle even exponents */ + if (s_and(e, 1) == 0) + m = mult_r(m, 0x5a82); + + return m; +} + +Word16 Sqrt16_lc3plus( /*!< output mantissa */ + Word16 mantissa, /*!< input mantissa */ + Word16 *exponent /*!< pointer to exponent */ +) +{ + Word16 preShift, e; + + assert(mantissa >= 0); + + /* normalize */ + preShift = norm_s(mantissa); + + e = sub(*exponent, preShift); + mantissa = shl(mantissa, preShift); + + /* calc mantissa */ + mantissa = Sqrt16_common(mantissa, e); + + /* e = (e + 1) >> 1 */ + *exponent = mult_r(e, 1 << 14); move16(); + + return mantissa; +} + +Word16 ISqrt16( /*!< output mantissa */ + Word16 mantissa, /*!< input mantissa */ + Word16 *exponent /*!< pointer to exponent */ +) +{ + Word16 preShift, e; + + assert(mantissa > 0); + + /* normalize */ + preShift = norm_s(mantissa); + + e = sub(*exponent, preShift); + mantissa = shl(mantissa, preShift); + + /* calc mantissa */ + mantissa = ISqrt16_common(mantissa, e); + + /* e = (2 - e) >> 1 */ + *exponent = msu_r(1L << 15, e, 1 << 14); move16(); + + return mantissa; +} + +Word16 Inv16_lc3plus( /*!< output mantissa */ + Word16 mantissa, /*!< input mantissa */ + Word16 *exponent /*!< pointer to exponent */ +) +{ + Word16 index, frac; + Word16 preShift; + Word16 m, e; + + assert(mantissa != 0); + + /* absolute */ + m = abs_s(s_max(mantissa, MIN_16 + 1)); + + /* normalize */ + preShift = norm_s(m); + + e = sub(*exponent, preShift); + m = shl(m, preShift); + + /* get table index (upper 6 bits minus 32) */ + /* index = (m >> 9) - 32; */ + index = mac_r(-32768 - (32 << 16), m, 1 << 6); + + /* get fractional part for interpolation (lower 9 bits) */ + frac = shl(s_and(m, 0x1FF), 1); /* Q10 */ + + /* interpolate */ + m = msu_r(InvTable_lc3plus[index], InvDiffTable_lc3plus[index], frac); + + /* restore sign */ + if (mantissa < 0) + m = negate(m); + + /* e = 1 - e */ + *exponent = sub(1, e); move16(); + + return m; +} + +/********************************************************************/ +/*! + \brief Calculates the scalefactor needed to normalize input array + + The scalefactor needed to normalize the Word16 input array is returned
+ If the input array contains only '0', a scalefactor 0 is returned
+ Scaling factor is determined wrt a normalized target x: 16384 <= x <= 32767 for positive x
+ and -32768 <= x <= -16384 for negative x +*/ + +Word16 getScaleFactor16( /* o: measured headroom in range [0..15], 0 if all x[i] == 0 */ + const Word16 *x, /* i: array containing 16-bit data */ + const Word16 len_x) /* i: length of the array to scan */ +{ + Counter i; + Word16 i_min, i_max; + Word16 x_min, x_max; + + x_max = 0; move16(); + x_min = 0; move16(); + FOR (i = 0; i < len_x; i++) + { + if (x[i] >= 0) + x_max = s_max(x_max, x[i]); + if (x[i] < 0) + x_min = s_min(x_min, x[i]); + } + + i_max = 0x10; move16(); + i_min = 0x10; move16(); + + if (x_max != 0) + i_max = norm_s(x_max); + + if (x_min != 0) + i_min = norm_s(x_min); + + i = s_and(s_min(i_max, i_min), 0xF); + + return i; +} + +/********************************************************************/ +/*! + \brief Calculates the scalefactor needed to normalize input array + + The scalefactor needed to normalize the Word16 input array is returned
+ If the input array contains only '0', a scalefactor 16 is returned
+ Scaling factor is determined wrt a normalized target x: 16384 <= x <= 32767 for positive x
+ and -32768 <= x <= -16384 for negative x +*/ + +Word16 getScaleFactor16_0( /* o: measured headroom in range [0..15], 16 if all x[i] == 0 */ + const Word16 *x, /* i: array containing 16-bit data */ + const Word16 len_x) /* i: length of the array to scan */ +{ + Counter i; + Word16 i_min, i_max; + Word16 x_min, x_max; + + x_max = 0; move16(); + x_min = 0; move16(); + FOR (i = 0; i < len_x; i++) + { + if (x[i] >= 0) + x_max = s_max(x_max, x[i]); + if (x[i] < 0) + x_min = s_min(x_min, x[i]); + } + + i_max = 0x10; move16(); + i_min = 0x10; move16(); + + if (x_max != 0) + i_max = norm_s(x_max); + + if (x_min != 0) + i_min = norm_s(x_min); + + i = s_min(i_max, i_min); + + return i; +} + +/********************************************************************/ +/*! + \brief Calculates the scalefactor needed to normalize input array + + The scalefactor needed to normalize the Word32 input array is returned
+ If the input array contains only '0', a scalefactor 0 is returned
+ Scaling factor is determined wrt a normalized target x: 1073741824 <= x <= 2147483647 for positive x
+ and -2147483648 <= x <= -1073741824 for negative x +*/ + +Word16 getScaleFactor32_lc3plus( /* o: measured headroom in range [0..31], 0 if all x[i] == 0 */ + const Word32 *x, /* i: array containing 32-bit data */ + const Word16 len_x) /* i: length of the array to scan */ +{ + Counter i; + Word16 i_min, i_max; + Word32 x_min, x_max; + + x_max = L_add(0, 0); + x_min = L_add(0, 0); + FOR (i = 0; i < len_x; i++) + { + if (x[i] >= 0) + x_max = L_max(x_max, x[i]); + if (x[i] < 0) + x_min = L_min(x_min, x[i]); + } + + i_max = 0x20; move16(); + i_min = 0x20; move16(); + + if (x_max != 0) + i_max = norm_l(x_max); + + if (x_min != 0) + i_min = norm_l(x_min); + + i = s_and(s_min(i_max, i_min), 0x1F); + + return i; +} + +/********************************************************************/ +/*! + \brief Calculates the scalefactor needed to normalize input array + + The scalefactor needed to normalize the Word32 input array is returned
+ If the input array contains only '0', a scalefactor 32 is returned
+ Scaling factor is determined wrt a normalized target x: 1073741824 <= x <= 2147483647 for positive x
+ and -2147483648 <= x <= -1073741824 for negative x +*/ + +Word16 getScaleFactor32_0( /* o: measured headroom in range [0..31], 32 if all x[i] == 0 */ + const Word32 *x, /* i: array containing 32-bit data */ + const Word16 len_x) /* i: length of the array to scan */ +{ + Counter i; + Word16 i_min, i_max; + Word32 x_min, x_max; + + x_max = L_add(0, 0); + x_min = L_add(0, 0); + FOR (i = 0; i < len_x; i++) + { + if (x[i] >= 0) + x_max = L_max(x_max, x[i]); + if (x[i] < 0) + x_min = L_min(x_min, x[i]); + } + + i_max = 0x20; move16(); + i_min = 0x20; move16(); + + if (x_max != 0) + i_max = norm_l(x_max); + + if (x_min != 0) + i_min = norm_l(x_min); + + i = s_min(i_max, i_min); + + return i; +} + +Word16 BASOP_Util_Divide3216_Scale_lc3plus( /* o: result of division x/y, not normalized */ + Word32 x, /* i: numerator, signed */ + Word16 y, /* i: denominator, signed */ + Word16 *s) /* o: scaling, 0, if x==0 */ +{ + Word16 z; + Word16 sx; + Word16 sy; + Word16 sign; + + /*assert (x > (Word32)0); + assert (y >= (Word16)0);*/ + + /* check, if numerator equals zero, return zero then */ + IF (x == (Word32)0) + { + *s = 0; move16(); + + return ((Word16)0); + } + + sign = s_xor(extract_h(x), y); /* just to exor the sign bits */ + x = L_abs(L_max(x, MIN_32 + 1)); + y = abs_s(s_max(y, MIN_16 + 1)); + sx = sub(norm_l(x), 1); + x = L_shl(x, sx); + sy = norm_s(y); + y = shl(y, sy); + *s = sub(sy, sx); move16(); + + z = div_s(round_fx(x), y); + + if (sign < 0) /* if sign bits differ, negate the result */ + { + z = negate(z); + } + + return z; +} + +Word16 BASOP_Util_Divide1616_Scale_lc3plus(Word16 x, Word16 y, Word16 *s) +{ + Word16 z; + Word16 sx; + Word16 sy; + Word16 sign; + + /* assert (x >= (Word16)0); */ + assert(y != (Word16)0); + + sign = 0; move16(); + + IF (x < 0) + { + x = negate(x); + sign = s_xor(sign, 1); + } + + IF (y < 0) + { + y = negate(y); + sign = s_xor(sign, 1); + } + + IF (x == (Word16)0) + { + *s = 0; move16(); + + return ((Word16)0); + } + + sx = norm_s(x); + x = shl(x, sx); + x = shr(x, 1); + *s = sub(1, sx); move16(); + + sy = norm_s(y); + y = shl(y, sy); + *s = add(*s, sy); move16(); + + z = div_s(x, y); + + if (sign != 0) + { + z = negate(z); + } + + return z; +} + +Word32 Norm32Norm(const Word32 *x, const Word16 headroom, const Word16 length, Word16 *result_e) +{ + Word32 L_tmp, L_tmp2, inc; + Word16 s, shift, tmp; + Counter i; + + shift = headroom; move16(); + + L_tmp = L_deposit_l(0); + + FOR (i = 0; i < length; i++) + { + L_tmp2 = L_sub(L_tmp, 0x40000000); + if (L_tmp2 >= 0) + shift = sub(shift, 1); + if (L_tmp2 >= 0) + L_tmp = L_shr(L_tmp, 2); + + tmp = round_fx_sat(L_shl_sat(x[i], shift)); + L_tmp = L_mac0(L_tmp, tmp, tmp); /* exponent = (1-shift*2) , Q(30+shift*2) */ + } + + /* Consider an increase of 0xfffd per sample in case that the pre-shift factor + in the acf is 1 bit higher than the shift factor estimated in this function. + This prevent overflows in the acf. */ + IF (L_tmp != 0) + { + s = norm_s(length); + inc = L_shl(Mpy_32_16_lc3plus(0x0000fffd, shl(length, s)), sub(15, s)); + L_tmp = L_add_sat(L_tmp, inc); + } + + *result_e = sub(1, shl(shift, 1)); move16(); + + return L_tmp; +} + +void Scale_sig(Word16 x[], /* i/o: signal to scale Qx */ + const Word16 lg, /* i : size of x[] Q0 */ + const Word16 exp0 /* i : exponent: x = round(x << exp) Qx ?exp */ +) +{ + Counter i; + Word16 tmp; + IF (exp0 > 0) + { + tmp = s_min(exp0, 15); move16(); + FOR (i = 0; i < lg; i++) + { + x[i] = shl(x[i], tmp); move16(); /* saturation can occur here */ + } + return; + } + IF (exp0 < 0) + { + tmp = shl(-32768, s_max(exp0, -15)); /* we use negative to correctly represent 1.0 */ + FOR (i = 0; i < lg; i++) + { + x[i] = msu_r(0, x[i], tmp); move16(); /* msu instead of mac because factor is negative */ + } + return; + } +} + +void Copy_Scale_sig(const Word16 x[], /* i : signal to scale input Qx */ + Word16 y[], /* o : scaled signal output Qx */ + const Word16 lg, /* i : size of x[] Q0 */ + const Word16 exp0 /* i : exponent: x = round(x << exp) Qx ?exp */ +) +{ + Counter i; + Word16 tmp; + + IF (exp0 == 0) + { + basop_memmove(y, x, lg * sizeof(Word16)); + + return; + } + IF (exp0 < 0) + { + tmp = shl(-32768, exp0); /* we use negative to correctly represent 1.0 */ + FOR (i = 0; i < lg; i++) + { + y[i] = msu_r(0, x[i], tmp); move16(); + } + return; + } + FOR (i = 0; i < lg; i++) + { + y[i] = shl_sat(x[i], exp0); move16(); /* saturation can occur here */ + } +} + +Word32 BASOP_Util_Add_Mant32Exp_lc3plus /*!< o: normalized result mantissa */ + (Word32 a_m, /*!< i: Mantissa of 1st operand a */ + Word16 a_e, /*!< i: Exponent of 1st operand a */ + Word32 b_m, /*!< i: Mantissa of 2nd operand b */ + Word16 b_e, /*!< i: Exponent of 2nd operand b */ + Word16 *ptr_e) /*!< o: exponent of result */ +{ + Word32 L_tmp; + Word16 shift; + + /* Compare exponents: the difference is limited to +/- 30 + The Word32 mantissa of the operand with lower exponent is shifted right by the exponent difference. + Then, the unshifted mantissa of the operand with the higher exponent is added. The addition result + is normalized and the result represents the mantissa to return. The returned exponent takes into + account all shift operations. + */ + + if (!a_m) + a_e = add(b_e, 0); + + if (!b_m) + b_e = add(a_e, 0); + + shift = sub(a_e, b_e); + shift = s_max(-31, shift); + shift = s_min(31, shift); + if (shift < 0) + { + /* exponent of b is greater than exponent of a, shr a_m */ + a_m = L_shl(a_m, shift); + } + if (shift > 0) + { + /* exponent of a is greater than exponent of b */ + b_m = L_shr(b_m, shift); + } + a_e = add(s_max(a_e, b_e), 1); + L_tmp = L_add(L_shr(a_m, 1), L_shr(b_m, 1)); + shift = norm_l(L_tmp); + if (shift) + L_tmp = L_shl(L_tmp, shift); + if (L_tmp == 0) + a_e = add(0, 0); + if (L_tmp != 0) + a_e = sub(a_e, shift); + *ptr_e = a_e; + + return (L_tmp); +} + +Word16 BASOP_Util_Cmp_Mant32Exp_lc3plus /*!< o: flag: result of comparison */ + /* 0, if a == b */ + /* 1, if a > b */ + /* -1, if a < b */ + (Word32 a_m, /*!< i: Mantissa of 1st operand a */ + Word16 a_e, /*!< i: Exponent of 1st operand a */ + Word32 b_m, /*!< i: Mantissa of 2nd operand b */ + Word16 b_e) /*!< i: Exponent of 2nd operand b */ + +{ + Word32 diff_m; + Word16 diff_e, shift, result; + + /* + This function compares two input parameters, both represented by a 32-bit mantissa and a 16-bit exponent. + If both values are identical, 0 is returned. + If a is greater b, 1 is returned. + If a is less than b, -1 is returned. + */ + + /* Check, if both mantissa and exponents are identical, when normalized: return 0 */ + shift = norm_l(a_m); + if (shift) + a_m = L_shl(a_m, shift); + if (shift) + a_e = sub(a_e, shift); + + shift = norm_l(b_m); + if (shift) + b_m = L_shl(b_m, shift); + if (shift) + b_e = sub(b_e, shift); + + /* align exponent, if any mantissa is zero */ + if (!a_m) + a_e = add(b_e, 0); + if (!b_m) + b_e = add(a_e, 0); + + IF (a_m > 0 && b_m < 0) + { + diff_m = 1; move16(); + } + ELSE IF (a_m<0 && b_m> 0) + { + diff_m = -1; move16(); + } + ELSE + { + diff_m = L_sub(a_m, b_m); + } + + diff_e = sub(a_e, b_e); + + test(); + IF (diff_m == 0 && diff_e == 0) + { + return 0; + } + + /* Check sign, exponent and mantissa to identify, whether a is greater b or not */ + result = sub(0, 1); + + IF (a_m >= 0) + { + /* a is positive */ + if (b_m < 0) + { + result = add(1, 0); + } + + test(); test(); test(); + if ((b_m >= 0) && ((diff_e > 0) || (diff_e == 0 && diff_m > 0))) + { + result = add(1, 0); + } + } + ELSE + { + /* a is negative */ + test(); test(); test(); + if ((b_m < 0) && ((diff_e < 0) || (diff_e == 0 && diff_m > 0))) + { + result = add(1, 0); + } + } + return result; +} + +/*----------------------------------------------------------------------------------* + * Function: Isqrt + * + * Description: + * + * The function computes 1/sqrt(x). + * The mantissa of the input value must be in the range of 1.0 > x >= 0.5. + * The computation of the inverse square root is an approach with a lookup table + * and linear interpolation. + * + * result = x * 2^x_e + * + * Parameter: + * + * x [i] mantissa (Q31) + * x_e [i/o] pointer to exponent (Q0) + * + * Return value: + * + * mantissa (Q31) + * + *----------------------------------------------------------------------------------*/ +Word32 Isqrt_lc3plus(Word32 x, /* mantissa */ + Word16 *x_e /* pointer to exponent */ +) +{ + Word16 s; + Word32 y; + Word32 idx; + Word32 diff; + Word16 fract; + + IF (x <= 0) + { + *x_e = 0; move16(); + return 0x7FFFFFFF; + } + + /* check if exponent is odd */ + s = s_and(*x_e, 0x0001); + + /* get table index (upper 8 bits) */ + idx = L_and(L_shr(x, (31 - 8)), 0x00000007f); + + /* get fractional part for interpolation (lower 23 bits) */ + fract = extract_h(L_shl(L_and(x, 0x007FFFFF), 8)); + + /* interpolate */ + diff = L_sub(isqrt_table[idx + 1], isqrt_table[idx]); + y = L_add(isqrt_table[idx], Mpy_32_16_lc3plus(diff, fract)); + + /* if exponent is odd apply sqrt(0.5) */ + if (s != 0) + { + y = Mpy_32_16_lc3plus(y, 0x5A82 /*0x5A827999*/); + } + + /* if exponent is odd shift 1 bit left */ + if (s != 0) + { + y = L_shl(y, s); + } + + /* change sign, shift right and add 1 to exponent (implicit exponent of isqrt_table) */ + *x_e = mac_r(32768, *x_e, -16384); move16(); + + return y; +} + +Word16 BASOP_Util_Log2_16(Word32 x, Word16 x_e) +{ + Word16 shift, tmp1, tmp2; + Word16 outInt, outFrac, out; + + assert(x >= 0); + + if (x == 0) + { + return (MIN_16); + } + + /* Scale Input */ + shift = norm_l(x); + x = L_shl(x, sub(shift, 10)); + + /* Integer part */ + outInt = shl(sub(sub(x_e, shift), 1), 9); + + /* Fractional part */ + tmp1 = mac_r(x, -33, 16384); + tmp2 = lshr(extract_l(x), 6); + outFrac = mac_r(Log2_16_table1[tmp1], Log2_16_table2[tmp1], tmp2); + + /* Output */ + out = add(outInt, outFrac); + + return out; +} + +Word16 BASOP_Util_InvLog2_16(Word16 x, Word16 *y_e) +{ + Word16 tmp1, tmp2, y; + + tmp1 = shr(s_and(x, 2047), 5); + tmp2 = shl(s_and(x, 31), 4); + y = mac_r(InvLog2_16_table1[tmp1], InvLog2_16_table2[tmp1], tmp2); + *y_e = add(shr_pos(x, 11), 1); + + return y; +} + +#ifdef ENABLE_HR_MODE +#define DFRACT_BITS 32 /* double precision */ + +#define SQRT_BITS 7 +#define SQRT_BITS_MASK 0x7f +#define SQRT_FRACT_BITS_MASK 0x007FFFFF + +#ifndef Word64 +#define Word64 long long +#endif + +static __inline Word32 Mpy_32_32_noshift(Word32 x1, Word32 x2) +{ + Word64 ret = 0; + ret = ((Word64)x1 * (Word64)x2); + return ((Word32)((ret & (Word64)0xffffffff00000000) >> 32)); +} + +static __inline Word32 fixmadddiv2_DD(const Word32 x, const Word32 a, const Word32 b) +{ + return ((((Word64)x << 32) + (Word64)a * b) >> 32); +} + +/** + * \brief calculate 1.0/sqrt(op) + * \param op_m mantissa of input value. + * \param result_e pointer to return the exponent of the result + * \return mantissa of the result + */ +/***************************************************************************** + delivers 1/sqrt(op) normalized to .5...1 and the shift value of the OUTPUT, + i.e. the denormalized result is 1/sqrt(op) = invSqrtNorm(op) * 2^(shift) + uses Newton-iteration for approximation + Q(n+1) = Q(n) + Q(n) * (0.5 - 2 * V * Q(n)^2) + with Q = 0.5* V ^-0.5; 0.5 <= V < 1.0 +*****************************************************************************/ +static __inline Word32 invSqrtNorm2(Word32 op, Word32 *shift) +{ + Word32 val = op; + Word32 reg1, reg2; + + if (val == 0) + { + *shift = 16; + return ((Word32)0x7FFFFFFF); /* maximum positive value */ + } + +/* #define INVSQRTNORM2_NEWTON_ITERATE */ +#define INVSQRTNORM2_LINEAR_INTERPOLATE +#define INVSQRTNORM2_LINEAR_INTERPOLATE_HQ + + /* normalize input, calculate shift value */ + assert(val > 0); + *shift = norm_l(val); /* CountLeadingBits() is not necessary here since test value is always > 0 */ + val <<= *shift; /* normalized input V */ + *shift += 2; /* bias for exponent */ + +#if defined(INVSQRTNORM2_NEWTON_ITERATE) + /* Newton iteration of 1/sqrt(V) */ + reg1 = invSqrtTab[(Word32)(val >> (DFRACT_BITS - 1 - (SQRT_BITS + 1))) & SQRT_BITS_MASK]; + reg2 = FL2FXCONST_DBL(0.0625f); /* 0.5 >> 3 */ + + Word32 regtmp = fPow2Div2(reg1); /* a = Q^2 */ + regtmp = reg2 - fMultDiv2(regtmp, val); /* b = 0.5 - 2 * V * Q^2 */ + reg1 += (fMultDiv2(regtmp, reg1) << 4); /* Q = Q + Q*b */ +#elif defined(INVSQRTNORM2_LINEAR_INTERPOLATE) + Word32 index = (Word32)(val >> (DFRACT_BITS - 1 - (SQRT_BITS + 1))) & SQRT_BITS_MASK; + Word32 Fract = (Word32)(((Word32)val & SQRT_FRACT_BITS_MASK) << (SQRT_BITS + 1)); + Word32 diff = invSqrtTab[index + 1] - invSqrtTab[index]; + reg1 = invSqrtTab[index] + (Word32)(((UWord32)(Mpy_32_32_noshift(diff, Fract)) << 1)); +#if defined(INVSQRTNORM2_LINEAR_INTERPOLATE_HQ) + /* reg1 = t[i] + (t[i+1]-t[i])*fract ... already computed ... + + (1-fract)fract*(t[i+2]-t[i+1])/2 */ + if (Fract != (Word32)0) + { + /* fract = fract * (1 - fract) */ + Fract = Mpy_32_32_noshift(Fract, (Word32)((UWord32)0x80000000 - (Word32)Fract)) << 1; + diff = diff - (invSqrtTab[index + 2] - invSqrtTab[index + 1]); + reg1 = fixmadddiv2_DD(reg1, Fract, diff); + } +#endif /* INVSQRTNORM2_LINEAR_INTERPOLATE_HQ */ +#else +#error "Either define INVSQRTNORM2_NEWTON_ITERATE or INVSQRTNORM2_LINEAR_INTERPOLATE" +#endif + /* calculate the output exponent = input exp/2 */ + if (*shift & 0x00000001) + { /* odd shift values ? */ + /* Note: Do not use rounded value 0x5A82799A to avoid overflow with shift-by-2 */ + reg2 = (Word32)0x5A827999; /* FL2FXCONST_DBL(0.707106781186547524400844362104849f);*/ /* 1/sqrt(2); */ +#ifdef __ADSP21000__ + reg1 = fMult(reg1, reg2) << 1; /* compiler bug work around (CCES 2.4.0), and better precision */ +#else + reg1 = Mpy_32_32_noshift(reg1, reg2) << 2; +#endif + } + + *shift = *shift >> 1; + + return (reg1); +} + +/** + * \brief calculate 1.0/(op_m * 2^op_e) + * \param op_m mantissa of the input value. + * \param op_e pointer into were the exponent of the input value is stored, and the result will be stored into. + * \return mantissa of the result + */ +Word32 invFixp(Word32 op_m, Word16 *op_e) +{ + if ((op_m == (Word32)0x00000000) || (op_m == (Word32)0x00000001)) + { + *op_e = 31 - *op_e; + return ((Word32)0x7FFFFFFF); + } + + Word32 tmp_exp; + Word32 tmp_inv = invSqrtNorm2(op_m, &tmp_exp); + + *op_e = (tmp_exp << 1) - *op_e + 1; + return Mpy_32_32_noshift(tmp_inv, tmp_inv); +} +#endif diff --git a/lib_lc3plus/basop_util_lc3plus.h b/lib_lc3plus/basop_util_lc3plus.h new file mode 100644 index 0000000000000000000000000000000000000000..d9abc7f5d92020d2ec18e69a41e7e63484080113 --- /dev/null +++ b/lib_lc3plus/basop_util_lc3plus.h @@ -0,0 +1,372 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.5 * +* Low Complexity Communication Codec Plus (LC3plus) * +* * +* Copyright licence is solely granted through ETSI Intellectual Property * +* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * +* estoppel or otherwise. * +******************************************************************************/ + +#ifndef __BASOP_UTIL_LC3PLUS_H__ +#define __BASOP_UTIL_LC3PLUS_H__ + +#include "defines.h" +#include "functions.h" +#include +#include + +#define _LONG long +#define _SHORT short +#ifdef _WIN32 +#define _INT64 __int64 +#else +#define _INT64 long long +#endif + +#define WORD32_BITS 32 +#define MAXVAL_WORD32 ((signed)0x7FFFFFFF) +#define MINVAL_WORD32 ((signed)0x80000000) +#define WORD32_FIX_SCALE ((_INT64)(1) << (WORD32_BITS - 1)) + +#define WORD16_BITS 16 +#define MAXVAL_WORD16 (((signed)0x7FFFFFFF) >> 16) +#define MINVAL_WORD16 (((signed)0x80000000) >> 16) +#define WORD16_FIX_SCALE ((_INT64)(1) << (WORD16_BITS - 1)) + +/*! + \def Macro converts a Word32 fixed point to Word16 fixed point <1 with saturation +*/ +#define WORD322WORD16(val) \ + ((((((val) >> (WORD32_BITS - WORD16_BITS - 1)) + 1) > (((_LONG)1 << WORD16_BITS) - 1)) && ((_LONG)(val) > 0)) \ + ? (Word16)(_SHORT)(((_LONG)1 << (WORD16_BITS - 1)) - 1) \ + : (Word16)(_SHORT)((((val) >> (WORD32_BITS - WORD16_BITS - 1)) + 1) >> 1)) + + +/* Word16 Packed Type */ +typedef struct +{ + struct + { + Word16 re; + Word16 im; + } v; +} PWord16; + +#ifdef ENABLE_HR_MODE +/* Word32 Packed Type */ +typedef struct +{ + struct + { + Word32 re; + Word32 im; + } v; +} PWord32; +#endif + +#define cast16 move16 + +#define LD_DATA_SCALE (6) +#define LD_DATA_SHIFT_I5 (7) + +/************************************************************************/ +/*! + \brief Calculate the squareroot of a number given by mantissa and exponent + + Mantissa is in 16/32-bit-fractional format with values between 0 and 1.
+ For *norm versions mantissa has to be between 0.5 and 1.
+ The base for the exponent is 2. Example: \f$ a = a\_m * 2^{a\_e} \f$
+ The exponent is addressed via pointers and will be overwritten with the result. +*/ + +Word16 Sqrt16_lc3plus( /*!< output mantissa */ + Word16 mantissa, /*!< input mantissa */ + Word16 *exponent /*!< pointer to exponent */ +); + +Word16 ISqrt16( /*!< output mantissa */ + Word16 mantissa, /*!< input mantissa */ + Word16 *exponent /*!< pointer to exponent */ +); + +/*****************************************************************************/ +/*! + \brief Calculate the inverse of a number given by mantissa and exponent + + Mantissa is in 16-bit-fractional format with values between 0 and 1.
+ The base for the exponent is 2. Example: \f$ a = a\_m * 2^{a\_e} \f$
+ The operand is addressed via pointers and will be overwritten with the result. + + The function uses a table lookup and a newton iteration. +*/ +Word16 Inv16_lc3plus( /*!< output mantissa */ + Word16 mantissa, /*!< input mantissa */ + Word16 *exponent /*!< pointer to exponent */ +); + +/********************************************************************/ +/*! + \brief Calculates the scalefactor needed to normalize input array + + The scalefactor needed to normalize the Word16 input array is returned
+ If the input array contains only '0', a scalefactor 0 is returned
+ Scaling factor is determined wrt a normalized target x: 16384 <= x <= 32767 for positive x
+ and -32768 <= x <= -16384 for negative x +*/ + +Word16 getScaleFactor16( /* o: measured headroom in range [0..15], 0 if all x[i] == 0 */ + const Word16 *x, /* i: array containing 16-bit data */ + const Word16 len_x); /* i: length of the array to scan */ + +/********************************************************************/ +/*! + \brief Calculates the scalefactor needed to normalize input array + + The scalefactor needed to normalize the Word16 input array is returned
+ If the input array contains only '0', a scalefactor 16 is returned
+ Scaling factor is determined wrt a normalized target x: 16384 <= x <= 32767 for positive x
+ and -32768 <= x <= -16384 for negative x +*/ + +Word16 getScaleFactor16_0( /* o: measured headroom in range [0..15], 16 if all x[i] == 0 */ + const Word16 *x, /* i: array containing 16-bit data */ + const Word16 len_x); /* i: length of the array to scan */ + +/********************************************************************/ +/*! + \brief Calculates the scalefactor needed to normalize input array + + The scalefactor needed to normalize the Word32 input array is returned
+ If the input array contains only '0', a scalefactor 0 is returned
+ Scaling factor is determined wrt a normalized target x: 1073741824 <= x <= 2147483647 for positive x
+ and -2147483648 <= x <= -1073741824 for negative x +*/ + +Word16 getScaleFactor32_lc3plus( /* o: measured headroom in range [0..31], 0 if all x[i] == 0 */ + const Word32 *x, /* i: array containing 32-bit data */ + const Word16 len_x); /* i: length of the array to scan */ + +/********************************************************************/ +/*! + \brief Calculates the scalefactor needed to normalize input array + + The scalefactor needed to normalize the Word32 input array is returned
+ If the input array contains only '0', a scalefactor 32 is returned
+ Scaling factor is determined wrt a normalized target x: 1073741824 <= x <= 2147483647 for positive x
+ and -2147483648 <= x <= -1073741824 for negative x +*/ + +Word16 getScaleFactor32_0( /* o: measured headroom in range [0..31], 32 if all x[i] == 0 */ + const Word32 *x, /* i: array containing 32-bit data */ + const Word16 len_x); /* i: length of the array to scan */ + +/****************************************************************************/ +/*! + \brief Does fractional integer division of Word32 arg1 by Word16 arg2 + + + \return fractional Word16 integer z = arg1(32bits)/arg2(16bits) , z not normalized +*/ +Word16 BASOP_Util_Divide3216_Scale_lc3plus(Word32 x, /*!< i : Numerator */ + Word16 y, /*!< i : Denominator*/ + Word16 *s); /*!< o : Additional scalefactor difference*/ + +/****************************************************************************/ +/*! + \brief Does fractional division of Word16 arg1 by Word16 arg2 + + + \return fractional Q15 Word16 z = arg1(Q15)/arg2(Q15) with scaling s +*/ +Word16 BASOP_Util_Divide1616_Scale_lc3plus(Word16 x, /*!< i : Numerator*/ + Word16 y, /*!< i : Denominator*/ + Word16 *s); /*!< o : Additional scalefactor difference*/ + +/************************************************************************/ +/*! + \brief Binary logarithm with 7 iterations + + \param x + + \return log2(x)/64 + */ +/************************************************************************/ +Word32 BASOP_Util_Log2_lc3plus(Word32 x); + +/************************************************************************/ +/*! + \brief Binary power + + Date: 06-JULY-2012 Arthur Tritthart, IIS Fraunhofer Erlangen + + Version with 3 table lookup and 1 linear interpolations + + Algorithm: compute power of 2, argument x is in Q7.25 format + result = 2^(x/64) + We split exponent (x/64) into 5 components: + integer part: represented by b31..b25 (exp) + fractional part 1: represented by b24..b20 (lookup1) + fractional part 2: represented by b19..b15 (lookup2) + fractional part 3: represented by b14..b10 (lookup3) + fractional part 4: represented by b09..b00 (frac) + => result = (lookup1*lookup2*(lookup3+C1*frac)<<3)>>exp + + Due to the fact, that all lookup values contain a factor 0.5 + the result has to be shifted by 3 to the right also. + Table exp2_tab_long_lc3plus contains the log2 for 0 to 1.0 in steps + of 1/32, table exp2w_tab_long_lc3plus the log2 for 0 to 1/32 in steps + of 1/1024, table exp2x_tab_long_lc3plus the log2 for 0 to 1/1024 in + steps of 1/32768. Since the 2-logarithm of very very small + negative value is rather linear, we can use interpolation. + + Limitations: + + For x <= 0, the result is fractional positive + For x > 0, the result is integer in range 1...7FFF.FFFF + For x < -31/64, we have to clear the result + For x = 0, the result is ~1.0 (0x7FFF.FFFF) + For x >= 31/64, the result is 0x7FFF.FFFF + + \param x + + \return pow(2,(x/64)) + */ +/************************************************************************/ +Word32 BASOP_Util_InvLog2_lc3plus(Word32 x); + +#ifdef ENABLE_HR_MODE +/* New function which works with positive x, BASOP_Util_InvLog2_lc3plus does not give + accurate results for x > 0 */ +Word32 BASOP_Util_InvLog2_pos(Word32 x, Word16 *exp); +#endif + +/** + * \brief Compute dot product of 1 32 bit vectors with itself + * \param x input vector 1 + * \param headroom amount of headroom bits the input vector + * \param length the length of the input vector + * \param result_e pointer to where the exponent of the result will be stored into + * \return the dot product of x and x. + */ +Word32 Norm32Norm(const Word32 *x, const Word16 headroom, const Word16 length, Word16 *result_e); + +/*!********************************************************************** + \brief Add two values given by mantissa and exponent. + + Mantissas are in 32-bit-fractional format with values between 0 and 1.
+ The base for exponents is 2. Example: \f$ a = a\_m * 2^{a\_e} \f$
+ +************************************************************************/ +Word32 BASOP_Util_Add_Mant32Exp_lc3plus /*!< o: normalized result mantissa */ + (Word32 a_m, /*!< i: Mantissa of 1st operand a */ + Word16 a_e, /*!< i: Exponent of 1st operand a */ + Word32 b_m, /*!< i: Mantissa of 2nd operand b */ + Word16 b_e, /*!< i: Exponent of 2nd operand b */ + Word16 *ptr_e); /*!< o: exponent of result */ + /*!********************************************************************** + \brief Returns the comparison result of two normalized values given by mantissa and exponent. + return value: -1: a < b, 0: a == b, 1; a > b + + Mantissas are in 32-bit-fractional format with values between 0 and 1.
+ The base for exponents is 2. Example: \f$ a = a\_m * 2^{a\_e} \f$
+ + ************************************************************************/ +Word16 BASOP_Util_Cmp_Mant32Exp_lc3plus /*!< o: flag: result of comparison */ + (Word32 a_m, /*!< i: Mantissa of 1st operand a */ + Word16 a_e, /*!< i: Exponent of 1st operand a */ + Word32 b_m, /*!< i: Mantissa of 2nd operand b */ + Word16 b_e); /*!< i: Exponent of 2nd operand b */ + +/* compare two positive normalized 16 bit mantissa/exponent values */ +/* return value: positive if first value greater, negative if second value greater, zero if equal */ +Word16 compMantExp16Unorm(Word16 m1, Word16 e1, Word16 m2, Word16 e2); + +void Scale_sig(Word16 x[], /* i/o: signal to scale Qx */ + const Word16 lg, /* i : size of x[] Q0 */ + const Word16 exp0 /* i : exponent: x = round(x << exp) Qx ?exp */ +); +void Copy_Scale_sig(const Word16 x[], /* i : signal to scale input Qx */ + Word16 y[], /* o : scaled signal output Qx */ + const Word16 lg, /* i : size of x[] Q0 */ + const Word16 exp0 /* i : exponent: x = round(x << exp) Qx ?exp */ +); + +#ifdef ENABLE_HR_MODE +void Copy_Scale_sig_32(const Word32 x[], /* i : signal to scale input Qx */ + Word16 y[], /* o : scaled signal output Qx */ + const Word16 lg, /* i : size of x[] Q0 */ + const Word16 exp0 /* i : exponent: x = round(x << exp) Qx ?exp */ +); +#endif + +Word32 Isqrt_lc3plus(Word32 x, /* (i) Q31: normalized value (1.0 > x >= 0.5) */ + Word16 *x_e /* (i/o) Q0 : pointer to exponent */ +); + +Word16 BASOP_Util_Log2_16(Word32 x, Word16 x_e); + +Word16 BASOP_Util_InvLog2_16(Word16 x, Word16 *y_e); + +#ifdef ENABLE_HR_MODE +Word32 invFixp(Word32 op_m, Word16 *op_e); +#endif + +#define BASOP_CFFT_MAX_LENGTH 480 +void BASOP_cfft_lc3plus(Word32 *re, Word32 *im, Word16 sizeOfFft, Word16 s, Word16 *scale, Word32 *x); +void BASOP_rfftN(Word32 *re, Word16 sizeOfFft, Word16 *scale, Word8 *scratchBuffer); +void BASOP_irfftN(Word32 *re, Word16 sizeOfFft, Word16 *scale, Word8 *scratchBuffer); + +static __inline void basop_memcpy(void *dst, const void *src, size_t n) +{ +#ifdef WMOPS + multiCounter[currCounter].move16 += (UWord32)n / 2; +#endif + /* check for overlapping memory */ + assert((const char *)src + n <= (char *)dst || (char *)dst + n <= (const char *)src); + memcpy(dst, src, n); +} + +static __inline void basop_memmove(void *dst, const void *src, size_t n) +{ +#ifdef WMOPS + multiCounter[currCounter].move16 += (UWord32)n / 2; +#endif + memmove(dst, src, n); +} + +static __inline void basop_memset(void *dst, int val, size_t n) +{ +#ifdef WMOPS + multiCounter[currCounter].move16 += (UWord32)n / 2; +#endif + memset(dst, val, n); +} + +/* Macros around Dyn_Mem that don't require duplicate declarations. */ +#ifdef DYNMEM_COUNT +/* older visual studio doesn't have __func__ */ +#if defined _MSC_VER && _MSC_VER < 1900 +#define __func__ __FUNCTION__ +#endif +#define Dyn_Mem_Deluxe_In(...) __VA_ARGS__ Dyn_Mem_In(__func__, sizeof(struct {__VA_ARGS__})) +#define Dyn_Mem_Deluxe_Out() Dyn_Mem_Out() +#else +#define Dyn_Mem_Deluxe_In(...) __VA_ARGS__ +#define Dyn_Mem_Deluxe_Out() +#endif + +/* Macros missing from IVAS BASOP, used only in LC3plus */ +#define L_shl_pos(x, y) (L_shl((x), (y))) +#define L_shr_pos(x, y) (L_shr((x), (y))) +#define L_shr_pos_pos(x, y) (L_shr((x), (y))) + +#define L_shr_r_pos(x, shift) (L_shr_r(x, shift)) + +#define shl_pos(x, y) (shl((x), (y))) +#define shr_pos(x, y) (shr((x), (y))) +#define shr_pos_pos(x, y) (shr((x), (y))) + +#define lshl_pos(x, y) (lshl(x, y)) +#define UL_lshr_pos(x, y) (UL_lshr(x, y)) +#define UL_lshl_pos(x, y) (UL_lshl(x, y)) +#endif /* __BASOP_UTIL_LC3PLUS_H__ */ diff --git a/lib_lc3plus/constants.c b/lib_lc3plus/constants.c new file mode 100644 index 0000000000000000000000000000000000000000..c02cf5c6918873017de8c0d0fe4fd053a02671d5 --- /dev/null +++ b/lib_lc3plus/constants.c @@ -0,0 +1,5046 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.5 * +* 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 "basop_util_lc3plus.h" +#include "constants.h" +#include "defines.h" + +#ifdef ENABLE_HR_MODE + +#ifdef CR8_G_ADD_75MS +const Word32 LowDelayShapes_n960_N480_HRA_7_5ms_IP[720] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 87, 348, 823, 1614, 2855, 4711, + 7394, 11166, 16346, 23325, 32567, 44630, 60168, 79951, 104871, + 135960, 174404, 221554, 278944, 348306, 431580, 530938, 648792, 787807, + 950923, 1141360, 1362631, 1618557, 1913273, 2251235, 2637225, 3076358, 3574079, + 4136163, 4768712, 5478142, 6271180, 7154844, 8136428, 9223482, 10423785, 11745317, + 13196231, 14784811, 16519438, 18408546, 20460576, 22683925, 25086898, 27677652, 30464139, + 33454048, 36654744, 40073208, 43715977, 47589078, 51697972, 56047490, 60641775, 65484225, + 70577443, 75923181, 81522294, 87374702, 93479345, 99834159, 106436041, 113280836, 120363317, + 127677184, 135215062, 142968508, 150928157, 159083617, 167423428, 175935264, 184605929, 193421420, + 202366999, 211427267, 220586253, 229827503, 239134176, 248489151, 257875132, 267274759, 276670727, + 286045896, 295383416, 304666842, 313880253, 323008369, 332036665, 340951481, 349740127, 358390986, + 366893607, 375238791, 383418672, 391426786, 399258131, 406909219, 414378115, 421664463, 428769507, + 435696092, 442448656, 449033209, 455457302, 461729975, 467861704, 473864325, 479750954, 485535888, + 491234502, 496863130, 502438943, 507979811, 513504165, 519030849, 524578969, 530167737, 535816319, + 541543674, 547368406, 553308608, 559381722, 565604392, 571992342, 578560249, 585321630, 592288748, + 599472521, 606882448, 614526549, 622411321, 630541701, 638921050, 647551149, 656432204, 665562870, + 674940281, 684560092, 694416534, 704502476, 714809492, 725327938, 736047035, 746954953, 758038900, + 769285219, 780679474, 792206554, 803850758, 815595897, 827425384, 839322323, 851269604, 863249984, + 875246176, 887240926, 899217093, 911157723, 923046119, 934865908, 946601106, 958236175, 969756079, + 981146337, 992393068, 1003483035, 1014403685, 1025143183, 1035690443, 1046035156, 1056167806, 1066079698, + 1075762962, 1085210568, 1094416328, 1103374896, 1112081767, 1120533266, 1128726537, 1136659525, 1144330955, + 1151740310, 1158887799, 1165774327, 1172401460, 1178771388, 1184886881, 1190751250, 1196368299, 1201742283, + 1206877859, 1211780040, 1216454151, 1220905777, 1225140726, 1229164983, 1232984668, 1236606003, 1240035271, + 1243278790, 1246342881, 1249233843, 1251957932, 1254521342, 1256930191, 1259190506, 1261308214, 1263289136, + 1265138979, 1266863333, 1268467669, 1269957337, 1271337562, 1272613448, 1273789972, 1274871989, 1275864224, + 1276771276, 1277597614, 1278347576, 1279025364, 1279635046, 1280180548, 1280665658, 1281094017, 1281469123, + 1281794327, 1282072831, 1282307692, 1282501820, 1282657982, 1282778803, 1282866770, 1282924240, 1282953439, + 1282956475, 1282935340, 1282891922, 1282828007, 1282745290, 1282645385, 1282529830, 1282400095, 1282257591, + 1282103675, 1281939658, 1281766811, 1281586369, 1281399536, 1281207489, 1281011380, 1280812338, 1280611471, + 1280409867, 1280208592, 1280008692, 1279811190, 1279617083, 1279427343, 1279242908, 1279064691, 1278893575, + 1278730391, 1278575934, 1278430953, 1278296152, 1278172183, 1278059646, 1277959085, 1277870984, 1277795766, + 1277733793, 1277685360, 1277650698, 1277629970, 1277623272, 1277630630, 1277652006, 1277687290, 1277736307, + 1277798815, 1277874509, 1277963018, 1278063911, 1278176696, 1278300826, 1278435697, 1278580655, 1278734998, + 1278897977, 1279068803, 1279246650, 1279430656, 1279619930, 1279813555, 1280010596, 1280210097, 1280411091, + 1280612606, 1280813664, 1281013290, 1281210515, 1281404382, 1281593947, 1281778291, 1281956514, 1282127749, + 1282291161, 1282445951, 1282591364, 1282726688, 1282851259, 1282964467, 1283065755, 1283154623, 1283230634, + 1283293412, 1283342644, 1283378085, 1283399556, 1283406948, 1283400219, 1283379398, 1283344582, 1283295937, + 1283233697, 1283158163, 1283069704, 1282968748, 1282855789, 1282731378, 1282596123, 1282450686, 1282295780, + 1282132162, 1281960636, 1281782040, 1281597253, 1281407178, 1281212748, 1281014916, 1280814653, 1280612938, + -1280410760, -1280209108, -1280008970, -1279811325, -1279617137, -1279427356, -1279242908, -1279064691, -1278893575, + -1278730391, -1278575934, -1278430953, -1278296152, -1278172183, -1278059646, -1277959085, -1277870984, -1277795766, + -1277733793, -1277685360, -1277650698, -1277629970, -1277623272, -1277630630, -1277652006, -1277687290, -1277736307, + -1277798815, -1277874509, -1277963018, -1278063911, -1278176696, -1278300826, -1278435697, -1278580655, -1278734998, + -1278897977, -1279068803, -1279246650, -1279430656, -1279619930, -1279813555, -1280010596, -1280210097, -1280411091, + -1280612606, -1280813664, -1281013290, -1281210515, -1281404382, -1281593947, -1281778291, -1281956514, -1282127749, + -1282291161, -1282445951, -1282591364, -1282726688, -1282851259, -1282964467, -1283065755, -1283154623, -1283230634, + -1283293412, -1283342644, -1283378085, -1283399556, -1283406948, -1283400219, -1283379398, -1283344582, -1283295937, + -1283233697, -1283158163, -1283069704, -1282968748, -1282855789, -1282731378, -1282596123, -1282450686, -1282295780, + -1282132162, -1281960636, -1281782040, -1281597240, -1281407124, -1281212613, -1281014638, -1280814136, -1280612044, + -1280409293, -1280206794, -1280005436, -1279806071, -1279609505, -1279416489, -1279227704, -1279043754, -1278865148, + -1278692290, -1278525466, -1278364827, -1278210380, -1278061967, -1277919259, -1277781732, -1277648661, -1277519103, + -1277391882, -1277265579, -1277138516, -1277008749, -1276874050, -1276731906, -1276579498, -1276413701, -1276231074, + -1276027848, -1275799922, -1275542858, -1275251868, -1274921816, -1274547202, -1274122161, -1273640454, -1273095459, + -1272480163, -1271787153, -1271008605, -1270136275, -1269161491, -1268075138, -1266867650, -1265529002, -1264048705, + -1262415795, -1260618834, -1258645914, -1256484654, -1254122219, -1251545330, -1248740288, -1245693001, -1242389021, + -1238813588, -1234951678, -1230788064, -1226307382, -1221494200, -1216333106, -1210808785, -1204906119, -1198610276, + -1191906816, -1184781789, -1177221841, -1169214319, -1160747375, -1151810067, -1142392460, -1132485722, -1122082216, + -1111175584, -1099760832, -1087834398, -1075394224, -1062439811, -1048972272, -1034994376, -1020510578, -1005527053, + -990051705, -974094182, -957665874, -940779904, -923451116, -905696046, -887532891, -868981469, -850063169, + -830800896, -811219007, -791343239, -771200631, -750819438, -730229039, -709459838, -688543157, -667511126, + -646396563, -625232849, -604053802, -582893543, -561786350, -540766526, -519868245, -499125406, -478571481, + -458239366, -438161227, -418368350, -398890991, -379758233, -360997846, -342636148, -324697881, -307206093, + -290182024, -273645013, -257612410, -242099504, -227119464, -212683299, -198799827, -185475666, -172715241, + -160520802, -148892465, -137828265, -127324223, -117374432, -107971150, -99104909, -90764635, -82937772, + -75610419, -68767471, -62392760, -56469205, -50978959, -45903556, -41224052, -36921169, -32975429, + -29367284, -26077235, -23085950, -20374365, -17923784, -15715959, -13733175, -11958308, -10374886, + -8967135, -7720017, -6619257, -5651362, -4803637, -4064184, -3421902, -2866477, -2388368, + -1978789, -1629681, -1333688, -1084125, -874947, -700710, -556540, -438092, -341515, + -263414, -200812, -151118, -112086, -81786, -58572, -41046, -28035, -18564, + -11827, -7166, -4052, -2065, -873, -219, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0}; + +const Word32 LowDelayShapes_n960_N960_HRA_7_5ms_IP[1440] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 44, 108, 200, + 327, 496, 716, 997, 1352, 1793, 2334, 2993, 3788, + 4740, 5873, 7210, 8782, 10618, 12754, 15228, 18079, 21354, + 25102, 29375, 34232, 39736, 45954, 52960, 60833, 69657, 79523, + 90531, 102783, 116393, 131479, 148170, 166600, 186913, 209263, 233812, + 260731, 290202, 322417, 357578, 395898, 437601, 482924, 532113, 585429, + 643144, 705541, 772919, 845587, 923872, 1008108, 1098650, 1195861, 1300121, + 1411824, 1531379, 1659208, 1795748, 1941453, 2096787, 2262233, 2438287, 2625458, + 2824273, 3035270, 3259002, 3496037, 3746956, 4012353, 4292837, 4589026, 4901555, + 5231067, 5578220, 5943680, 6328125, 6732242, 7156730, 7602292, 8069643, 8559503, + 9072598, 9609661, 10171429, 10758643, 11372046, 12012385, 12680404, 13376850, 14102468, + 14858000, 15644185, 16461757, 17311444, 18193967, 19110038, 20060361, 21045626, 22066514, + 23123691, 24217808, 25349499, 26519382, 27728053, 28976092, 30264055, 31592472, 32961855, + 34372684, 35825415, 37320475, 38858262, 40439142, 42063449, 43731482, 45443509, 47199758, + 49000423, 50845659, 52735581, 54670266, 56649748, 58674020, 60743031, 62856690, 65014857, + 67217351, 69463943, 71754359, 74088280, 76465337, 78885116, 81347157, 83850949, 86395935, + 88981513, 91607029, 94271785, 96975035, 99715986, 102493800, 105307656, 108156591, 111039641, + 113955799, 116904014, 119883198, 122892222, 125929920, 128995090, 132086493, 135202860, 138342888, + 141505243, 144688567, 147891470, 151112543, 154350350, 157603439, 160870336, 164149553, 167439589, + 170738931, 174046055, 177359434, 180677535, 183998823, 187321766, 190644834, 193966503, 197285258, + 200599596, 203908028, 207209080, 210501300, 213783255, 217053539, 220310770, 223553598, 226780705, + 229990806, 233182654, 236355043, 239506805, 242636819, 245744010, 248827351, 251885864, 254918626, + 257924767, 260903473, 263853991, 266775622, 269667734, 272529755, 275361176, 278161556, 280930518, + 283667753, 286373022, 289046153, 291687043, 294295661, 296872047, 299416309, 301928628, 304409254, + 306858511, 309276789, 311664551, 314022327, 316350717, 318650389, 320922075, 323166575, 325384751, + 327577531, 329745900, 331890905, 334013649, 336115291, 338197045, 340260173, 342305990, 344335852, + 346351165, 348353370, 350343952, 352324427, 354296346, 356261288, 358220860, 360176691, 362130431, + 364083745, 366038312, 367995821, 369957968, 371926451, 373902968, 375889214, 377886876, 379897629, + 381923135, 383965040, 386024966, 388104513, 390205254, 392328729, 394476448, 396649881, 398850460, + 401079575, 403338572, 405628746, 407951345, 410307564, 412698544, 415125367, 417589059, 420090585, + 422630847, 425210685, 427830873, 430492120, 433195067, 435940288, 438728287, 441559502, 444434298, + 447352971, 450315749, 453322788, 456374176, 459469929, 462609996, 465794259, 469022529, 472294553, + 475610011, 478968518, 482369626, 485812825, 489297542, 492823148, 496388953, 499994212, 503638125, + 507319839, 511038449, 514793004, 518582502, 522405897, 526262100, 530149980, 534068367, 538016053, + 541991796, 545994319, 550022317, 554074452, 558149362, 562245659, 566361935, 570496756, 574648675, + 578816224, 582997925, 587192283, 591397795, 595612950, 599836228, 604066106, 608301058, 612539556, + 616780072, 621021084, 625261070, 629498515, 633731914, 637959769, 642180591, 646392905, 650595252, + 654786183, 658964269, 663128098, 667276277, 671407434, 675520217, 679613298, 683685373, 687735163, + 691761414, 695762900, 699738424, 703686816, 707606936, 711497676, 715357958, 719186737, 722983000, + 726745768, 730474096, 734167073, 737823824, 741443507, 745025319, 748568492, 752072293, 755536028, + 758959039, 762340704, 765680440, 768977700, 772231975, 775442794, 778609720, 781732356, 784810341, + 787843351, 790831096, 793773326, 796669823, 799520406, 802324927, 805083276, 807795372, 810461171, + 813080658, 815653853, 818180806, 820661596, 823096332, 825485155, 827828229, 830125749, 832377934, + 834585028, 836747302, 838865047, 840938578, 842968232, 844954366, 846897354, 848797592, 850655491, + 852471478, 854245997, 855979505, 857672472, 859325380, 860938723, 862513004, 864048738, 865546444, + 867006653, 868429898, 869816720, 871167666, 872483283, 873764126, 875010749, 876223709, 877403563, + 878550870, 879666189, 880750077, 881803089, 882825781, 883818705, 884782410, 885717445, 886624352, + 887503671, 888355939, 889181688, 889981445, 890755734, 891505074, 892229977, 892930955, 893608509, + 894263138, 894895337, 895505593, 896094389, 896662203, 897209507, 897736768, 898244447, 898733000, + 899202877, 899654523, 900088379, 900504877, 900904447, 901287510, 901654485, 902005783, 902341811, + 902662967, 902969647, 903262240, 903541129, 903806691, 904059297, 904299312, 904527095, 904742999, + 904947372, 905140554, 905322879, 905494676, 905656265, 905807964, 905950080, 906082916, 906206768, + 906321926, 906428673, 906527284, 906618032, 906701178, 906776980, 906845690, 906907551, 906962802, + 907011675, 907054396, 907091185, 907122257, 907147818, 907168073, 907183217, 907193443, 907198938, + 907199882, 907196451, 907188818, 907177150, 907161608, 907142351, 907119533, 907093305, 907063813, + 907031199, 906995603, 906957162, 906916008, 906872273, 906826083, 906777563, 906726837, 906674025, + 906619245, 906562613, 906504244, 906444251, 906382745, 906319835, 906255629, 906190236, 906123759, + 906056304, 905987975, 905918873, 905849099, 905778755, 905707939, 905636751, 905565287, 905493644, + 905421918, 905350204, 905278596, 905207187, 905136068, 905065331, 904995065, 904925359, 904856301, + 904787977, 904720472, 904653870, 904588254, 904523701, 904460295, 904398114, 904337234, 904277728, + 904219670, 904163129, 904108175, 904054874, 904003290, 903953487, 903905525, 903859462, 903815353, + 903773252, 903733209, 903695274, 903659492, 903625906, 903594557, 903565482, 903538716, 903514291, + 903492237, 903472579, 903455342, 903440546, 903428208, 903418343, 903410963, 903406076, 903403687, + 903403799, 903406411, 903411521, 903419121, 903429201, 903441750, 903456751, 903474186, 903494033, + 903516269, 903540866, 903567793, 903597018, 903628506, 903662217, 903698112, 903736145, 903776272, + 903818442, 903862605, 903908708, 903956694, 904006505, 904058081, 904111359, 904166274, 904222761, + 904280750, 904340172, 904400953, 904463022, 904526303, 904590718, 904656191, 904722641, 904789988, + 904858152, 904927048, 904996594, 905066706, 905137298, 905208286, 905279583, 905351102, 905422757, + 905494462, 905566128, 905637670, 905709001, 905780033, 905850681, 905920859, 905990482, 906059464, + 906127723, 906195175, 906261739, 906327332, 906391876, 906455291, 906517501, 906578429, 906638002, + 906696146, 906752790, 906807866, 906861306, 906913045, 906963019, 907011167, 907057430, 907101752, + 907144078, 907184355, 907222535, 907258571, 907292418, 907324034, 907353381, 907380422, 907405124, + 907427456, 907447391, 907464903, 907479970, 907492575, 907502701, 907510335, 907515468, 907518092, + 907518205, 907515805, 907510896, 907503482, 907493572, 907481179, 907466317, 907449004, 907429261, + 907407111, 907382581, 907355702, 907326506, 907295028, 907261307, 907225384, 907187302, 907147109, + 907104853, 907060585, 907014361, 906966236, 906916270, 906864523, 906811060, 906755944, 906699245, + 906641031, 906581374, 906520347, 906458025, 906394483, 906329801, 906264057, 906197332, 906129707, + 906061266, 905992093, 905922271, 905851888, 905781028, 905709780, 905638230, 905566465, 905494574, + -905422645, -905350765, -905279024, -905207507, -905136304, -905065500, -904995184, -904925439, -904856352, + -904788008, -904720488, -904653877, -904588254, -904523701, -904460295, -904398114, -904337234, -904277728, + -904219670, -904163129, -904108175, -904054874, -904003290, -903953487, -903905525, -903859462, -903815353, + -903773252, -903733209, -903695274, -903659492, -903625906, -903594557, -903565482, -903538716, -903514291, + -903492237, -903472579, -903455342, -903440546, -903428208, -903418343, -903410963, -903406076, -903403687, + -903403799, -903406411, -903411521, -903419121, -903429201, -903441750, -903456751, -903474186, -903494033, + -903516269, -903540866, -903567793, -903597018, -903628506, -903662217, -903698112, -903736145, -903776272, + -903818442, -903862605, -903908708, -903956694, -904006505, -904058081, -904111359, -904166274, -904222761, + -904280750, -904340172, -904400953, -904463022, -904526303, -904590718, -904656191, -904722641, -904789988, + -904858152, -904927048, -904996594, -905066706, -905137298, -905208286, -905279583, -905351102, -905422757, + -905494462, -905566128, -905637670, -905709001, -905780033, -905850681, -905920859, -905990482, -906059464, + -906127723, -906195175, -906261739, -906327332, -906391876, -906455291, -906517501, -906578429, -906638002, + -906696146, -906752790, -906807866, -906861306, -906913045, -906963019, -907011167, -907057430, -907101752, + -907144078, -907184355, -907222535, -907258571, -907292418, -907324034, -907353381, -907380422, -907405124, + -907427456, -907447391, -907464903, -907479970, -907492575, -907502701, -907510335, -907515468, -907518092, + -907518205, -907515805, -907510896, -907503482, -907493572, -907481179, -907466317, -907449004, -907429261, + -907407111, -907382581, -907355702, -907326506, -907295028, -907261307, -907225384, -907187302, -907147109, + -907104853, -907060585, -907014361, -906966236, -906916270, -906864523, -906811060, -906755944, -906699245, + -906641031, -906581374, -906520347, -906458025, -906394483, -906329801, -906264050, -906197315, -906129676, + -906061214, -905992012, -905922152, -905851718, -905780792, -905709459, -905637802, -905565904, -905493847, + -905421715, -905349587, -905277545, -905205668, -905134032, -905062714, -904991788, -904921326, -904851397, + -904782068, -904713403, -904645463, -904578305, -904511983, -904446548, -904382044, -904318513, -904255990, + -904194508, -904134091, -904074760, -904016528, -903959404, -903903387, -903848473, -903794647, -903741889, + -903690170, -903639452, -903589690, -903540829, -903492806, -903445546, -903398968, -903352977, -903307470, + -903262332, -903217440, -903172655, -903127830, -903082805, -903037408, -902991455, -902944749, -902897082, + -902848230, -902797958, -902746017, -902692145, -902636065, -902577487, -902516107, -902451605, -902383649, + -902311891, -902235969, -902155504, -902070104, -901979361, -901882852, -901780138, -901670764, -901554261, + -901430141, -901297903, -901157028, -901006979, -900847206, -900677140, -900496195, -900303767, -900099237, + -899881968, -899651302, -899406566, -899147069, -898872099, -898580929, -898272809, -897946972, -897602633, + -897238985, -896855201, -896450436, -896023825, -895574479, -895101492, -894603937, -894080864, -893531305, + -892954268, -892348742, -891713696, -891048075, -890350805, -889620793, -888856922, -888058059, -887223048, + -886350714, -885439866, -884489291, -883497761, -882464029, -881386834, -880264898, -879096929, -877881622, + -876617661, -875303716, -873938450, -872520516, -871048562, -869521229, -867937155, -866294976, -864593328, + -862830848, -861006177, -859117961, -857164854, -855145521, -853058635, -850902887, -848676980, -846379640, + -844009611, -841565658, -839046575, -836451182, -833778329, -831026896, -828195801, -825283996, -822290474, + -819214267, -816054453, -812810153, -809480538, -806064827, -802562292, -798972258, -795294106, -791527275, + -787671264, -783725629, -779689995, -775564045, -771347531, -767040273, -762642156, -758153138, -753573244, + -748902575, -744141301, -739289667, -734347993, -729316674, -724196178, -718987051, -713689917, -708305473, + -702834496, -697277838, -691636430, -685911277, -680103464, -674214150, -668244572, -662196041, -656069944, + -649867743, -643590972, -637241240, -630820227, -624329685, -617771433, -611147363, -604459432, -597709664, + -590900148, -584033037, -577110543, -570134942, -563108566, -556033804, -548913099, -541748950, -534543903, + -527300554, -520021545, -512709564, -505367338, -497997635, -490603260, -483187052, -475751882, -468300650, + -460836282, -453361728, -445879958, -438393963, -430906743, -423421316, -415940704, -408467938, -401006049, + -393558069, -386127025, -378715938, -371327818, -363965660, -356632445, -349331130, -342064650, -334835913, + -327647796, -320503142, -313404758, -306355410, -299357818, -292414658, -285528555, -278702079, -271937746, + -265238010, -258605264, -252041836, -245549983, -239131895, -232789684, -226525389, -220340970, -214238305, + -208219189, -202285333, -196438360, -190679806, -185011113, -179433635, -173948631, -168557267, -163260612, + -158059640, -152955229, -147948160, -143039115, -138228681, -133517347, -128905505, -124393450, -119981382, + -115669406, -111457534, -107345683, -103333681, -99421264, -95608082, -91893698, -88277589, -84759152, + -81337704, -78012482, -74782650, -71647299, -68605451, -65656059, -62798015, -60030148, -57351228, + -54759972, -52255046, -49835065, -47498599, -45244179, -43070293, -40975397, -38957912, -37016231, + -35148723, -33353731, -31629581, -29974582, -28387030, -26865208, -25407397, -24011868, -22676893, + -21400745, -20181701, -19018041, -17908057, -16850050, -15842335, -14883242, -13971116, -13104325, + -12281255, -11500315, -10759938, -10058585, -9394741, -8766919, -8173665, -7613552, -7085185, + -6587202, -6118273, -5677102, -5262427, -4873021, -4507690, -4165278, -3844660, -3544752, + -3264499, -3002887, -2758933, -2531691, -2320249, -2123731, -1941292, -1772123, -1615446, + -1470519, -1336627, -1213092, -1099261, -994515, -898263, -809943, -729021, -654988, + -587365, -525695, -469547, -418515, -372215, -330284, -292383, -258192, -227410, + -199757, -174969, -152801, -133024, -115424, -99803, -85978, -73777, -63042, + -53629, -45403, -38240, -32028, -26663, -22051, -18104, -14745, -11902, + -9511, -7514, -5860, -4500, -3394, -2503, -1797, -1244, -820, + -502, -271, -109, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0}; +#endif /* #ifdef CR8_G_ADD_75MS */ + +RAM_ALIGN const Word32 LowDelayShapes_n960_N480_HRA_2_5ms_IP[240] = { + 214, 1407, 4144, 9592, 19434, 36052, 62711, 103783, 164992, + 253687, 379148, 552904, 789076, 1104722, 1520198, 2059494, 2750561, 3625602, + 4721314, 6079061, 7744972, 9769942, 12209518, 15123669, 18576419, 22635352, 27370973, + 32855950, 39164229, 46370051, 54546874, 63766241, 74096597, 85602085, 98341344, 112366317, + 127721101, 144440829, 162550610, 182064542, 202984778, 225300694, 248988134, 274008783, 300309659, + 327822776, 356464985, 386138051, 416728983, 448110659, 480142780, 512673177, 545539472, 578571104, + 611591694, 644421704, 676881340, 708793602, 739987407, 770300656, 799583149, 827699226, 854530045, + 879975405, 903955057, 926409465, 947300009, 966608644, 984337071, 1000505451, 1015150768, 1028324899, + 1040092491, 1050528715, 1059716983, 1067746699, 1074711082, 1080705143, 1085823820, 1090160324, 1093804700, + 1096842623, 1099354431, 1101414399, 1103090233, 1104442796, 1105526028, 1106387052, 1107066439, 1107598605, + 1108012308, 1108331223, 1108574556, 1108757676, 1108892731, 1108989242, 1109054637, 1109094735, 1109114155, + 1109116652, 1109105394, 1109083163, 1109052498, 1109015788, 1108975323, 1108933307, 1108891843, 1108852902, + 1108818280, 1108789546, 1108767992, 1108754591, 1108749953, 1108754306, 1108767481, 1108788919, 1108817694, + 1108852552, 1108891964, 1108934195, -1108977380, -1109019614, -1109059032, -1109093898, -1109122681, -1109144125, + -1109157302, -1109161650, -1109156995, -1109143556, -1109121925, -1109093037, -1109058122, -1109018637, -1108976187, + -1108932433, -1108888980, -1108847255, -1108808366, -1108772946, -1108740971, -1108711558, -1108682731, -1108651158, + -1108611855, -1108557851, -1108479820, -1108365676, -1108200143, -1107964292, -1107635083, -1107184891, -1106581062, + -1105785503, -1104754330, -1103437601, -1101779148, -1099716548, -1097181229, -1094098763, -1090389339, -1085968441, + -1080747748, -1074636248, -1067541577, -1059371579, -1050036059, -1039448713, -1027529209, -1014205354, -999415302, + -983109740, -965253961, -945829756, -924837032, -902295070, -878243367, -852741971, -825871301, -797731403, + -768440669, -738134051, -706960817, -675081952, -642667284, -609892453, -576935833, -543975515, -511186440, + -478737764, -446790521, -415495622, -384992199, -355406317, -326850029, -299420751, -273200929, -248257970, + -224644391, -202398148, -181543141, -162089834, -144035993, -127367520, -112059369, -98076525, -85375063, + -73903244, -63602666, -54409446, -46255413, -39069306, -32777951, -27307388, -22583946, -18535216, + -15090941, -12183768, -9749883, -7729511, -6067277, -4712439, -3619003, -2745721, -2055997, + -1517713, -1102987, -787888, -552109, -378629, -253358, -164789, -103664, -62644, + -36017, -19417, -9584, -4141, -1406, -214 }; +RAM_ALIGN const Word32 LowDelayShapes_n960_N480_HRA_5ms_IP[420] = { + 153, 1006, 2962, 6854, 13880, 25735, 44738, 73986, 117524, + 180533, 269534, 392603, 559593, 782368, 1075031, 1454143, 1938937, 2551502, + 3316947, 4263524, 5422707, 6829222, 8521011, 10539137, 12927604, 15733109, 19004698, + 22793344, 27151431, 32132152, 37788816, 44174082, 51339114, 59332667, 68200136, 77982547, + 88715548, 100428385, 113142910, 126872625, 141621804, 157384706, 174144915, 191874817, 210535261, + 230075406, 250432778, 271533559, 293293106, 315616716, 338400617, 361533198, 384896437, 408367524, + 431820627, 455128780, 478165843, 500808481, 522938120, 544442827, 565219197, 585174124, 604225689, + 622304754, 639355717, 655337129, 670221993, 683997778, 696666136, 708242355, 718754575, 728242788, + 736757688, 744359378, 751116012, 757102394, 762398585, 767088551, 771258886, 774997644, 778393288, + 781533768, 784505744, 787393944, 790280637, 793245232, 796363956, 799709608, 803351363, 807354601, + 811780739, 816687064, 822126537, 828147569, 834793773, 842103681, 850110443, 858841520, 868318369, + 878556163, 889563529, 901342346, 913887605, 927187338, 941222645, 955967800, 971390453, 987451937, + 1004107649, 1021307531, 1038996616, 1057115651, 1075601769, 1094389201, 1113410024, 1132594917, 1151873921, + 1171177186, 1190435688, 1209581916, 1228550504, 1247278803, 1265707395, 1283780533, 1301446498, 1318657893, + 1335371854, 1351550191, 1367159457, 1382170967, 1396560748, 1410309460, 1423402271, 1435828702, 1447582463, + 1458661263, 1469066617, 1478803649, 1487880888, 1496310057, 1504105864, 1511285781, 1517869810, 1523880240, + 1529341392, 1534279342, 1538721639, 1542697001, 1546235012, 1549365809, 1552119778, 1554527246, 1556618203, + 1558422028, 1559967247, 1561281317, 1562390436, 1563319395, 1564091445, 1564728213, 1565249633, 1565673917, + 1566017543, 1566295272, 1566520181, 1566703721, 1566855785, 1566984788, 1567097770, 1567200488, 1567297538, + 1567392456, 1567487845, 1567585484, 1567686442, 1567791191, 1567899701, 1568011546, 1568125984, 1568242042, + 1568358534, 1568474289, 1568587995, 1568698311, 1568803945, 1568903672, 1568996349, 1569080932, 1569156484, + 1569222192, 1569277370, 1569321465, 1569354064, 1569374893, 1569383815, 1569380829, 1569366065, 1569339781, + 1569302349, 1569254257, 1569196093, 1569128539, 1569052361, 1568968403, 1568877571, 1568780830, 1568679193, + 1568573710, 1568465461, 1568355548, 1568245083, 1568135185, 1568026967, 1567921528, 1567819946, 1567723271, + 1567632511, 1567548628, 1567472527, 1567405047, 1567346952, 1567298919, 1567261537, 1567235287, 1567220544, + 1567217562, 1567226472, 1567247272, 1567279829, 1567323868, 1567378978, 1567444612, 1567520086, 1567604589, + 1567697189, 1567796846, 1567902419, 1568012687, 1568126359, 1568242097, -1568358534, -1568474289, -1568587995, + -1568698311, -1568803945, -1568903672, -1568996349, -1569080932, -1569156484, -1569222192, -1569277370, -1569321465, + -1569354064, -1569374893, -1569383815, -1569380829, -1569366065, -1569339781, -1569302349, -1569254257, -1569196093, + -1569128539, -1569052361, -1568968403, -1568877571, -1568780830, -1568679193, -1568573710, -1568465461, -1568355548, + -1568245083, -1568135185, -1568026967, -1567921528, -1567819946, -1567723271, -1567632511, -1567548628, -1567472527, + -1567405047, -1567346952, -1567298919, -1567261537, -1567235287, -1567220544, -1567217562, -1567226472, -1567247272, + -1567279829, -1567323868, -1567378978, -1567444612, -1567520086, -1567604589, -1567697189, -1567796846, -1567902419, + -1568012687, -1568126359, -1568242097, -1568358479, -1568473914, -1568586854, -1568695591, -1568798286, -1568892916, + -1568977226, -1569048656, -1569104263, -1569140635, -1569153790, -1569139071, -1569091028, -1569003308, -1568868529, + -1568678156, -1568422382, -1568089999, -1567668277, -1567142834, -1566497514, -1565714254, -1564772952, -1563651331, + -1562324794, -1560766278, -1558946098, -1556831792, -1554387964, -1551576132, -1548354584, -1544678268, -1540498696, + -1535763912, -1530418507, -1524403718, -1517657618, -1510115411, -1501709847, -1492371764, -1482030768, -1470616033, + -1458057247, -1444285654, -1429235205, -1412843785, -1395054486, -1375816907, -1355088440, -1332835519, -1309034797, + -1283674224, -1256753995, -1228287351, -1198301206, -1166836586, -1133948872, -1099707826, -1064197417, -1027515419, + -989772809, -951092956, -911610610, -871470715, -830827045, -789840682, -748678366, -707510713, -666510349, + -625849956, -585700281, -546228117, -507594292, -469951710, -433443460, -398201053, -364342807, -331972440, + -301177891, -272030413, -244583969, -218874947, -194922208, -172727465, -152275991, -133537623, -116468025, + -101010189, -87096098, -74648510, -63582812, -53808877, -45232880, -37759037, -31291209, -25734358, + -20995832, -16986455, -13621428, -10821035, -8511162, -6623645, -5096451, -3873717, -2905668, + -2148423, -1563717, -1118555, -784819, -538834, -360926, -234965, -147925, -89451, + -51458, -27754, -13704, -5923, -2011, -306 }; +RAM_ALIGN const Word32 LowDelayShapes_n960_N480_HRA_IP[780] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 105, 687, 2025, 4688, 9502, 17634, + 30689, 50817, 80838, 124375, 186009, 271432, 387623, 543017, 747676, + 1013467, 1354215, 1785853, 2326545, 2996777, 3819424, 4819763, 6025441, 7466392, + 9174686, 11184326, 13530961, 16251545, 19383921, 22966334, 27036891, 31632957, 36790505, + 42543426, 48922816, 55956247, 63667042, 72073568, 81188571, 91018551, 101563225, 112815065, + 124758945, 137371906, 150623045, 164473553, 178876885, 193779093, 209119296, 224830297, 240839344, + 257069006, 273438164, 289863100, 306258645, 322539389, 338620907, 354420979, 369860792, 384866072, + 399368244, 413305531, 426623420, 439275707, 451224957, 462442920, 472910759, 482619111, 491567983, + 499766479, 507232383, 513991603, 520077504, 525530145, 530395443, 534724296, 538571682, 541995756, + 545056975, 547817267, 550339253, 552685542, 554918106, 557097730, 559283544, 561532631, 563899693, + 566436780, 569193061, 572214618, 575544274, 579221418, 583281849, 587757606, 592676805, 598063482, + 603937430, 610314061, 617204279, 624614388, 632546030, 640996174, 649957147, 659416723, 669358259, + 679760895, 690599795, 701846444, 713468981, 725432569, 737699796, 750231092, 762985159, 775919415, + 788990419, 802154306, 815367198, 828585593, 841766740, 854868978, 867852045, 880677358, 893308258, + 905710214, 917851001, 929700832, 941232469, 952421292, 963245346, 973685357, 983724726, 993349512, + 1002548385, 1011312579, 1019635831, 1027514316, 1034946573, 1041933433, 1048477942, 1054585275, 1060262649, + 1065519228, 1070366010, 1074815711, 1078882625, 1082582470, 1085932219, 1088949913, 1091654462, 1094065430, + 1096202822, 1098086863, 1099737781, 1101175600, 1102419947, 1103489872, 1104403690, 1105178850, 1105831817, + 1106377989, 1106831632, 1107205842, 1107512525, 1107762397, 1107965009, 1108128778, 1108261042, 1108368118, + 1108455375, 1108527311, 1108587638, 1108639366, 1108684891, 1108726077, 1108764338, 1108800715, 1108835945, + 1108870522, 1108904754, 1108938811, 1108972723, 1109006542, 1109040205, 1109073607, 1109106645, 1109139216, + 1109171221, 1109202563, 1109233147, 1109262880, 1109291675, 1109319447, 1109346114, 1109371602, 1109395837, + 1109418753, 1109440288, 1109460385, 1109478991, 1109496061, 1109511552, 1109525430, 1109537663, 1109548227, + 1109557101, 1109564272, 1109569731, 1109573473, 1109575498, 1109575814, 1109574431, 1109571363, 1109566630, + 1109560257, 1109552270, 1109542702, 1109531587, 1109518966, 1109504879, 1109489374, 1109472496, 1109454299, + 1109434835, 1109414161, 1109392335, 1109369417, 1109345469, 1109320555, 1109294742, 1109268095, 1109240684, + 1109212578, 1109183848, 1109154564, 1109124800, 1109094627, 1109064121, 1109033354, 1109002402, 1108971338, + 1108940237, 1108909175, 1108878226, 1108847464, 1108816965, 1108786801, 1108757046, 1108727774, 1108699056, + 1108670963, 1108643567, 1108616936, 1108591139, 1108566243, 1108542312, 1108519412, 1108497603, 1108476946, + 1108457499, 1108439319, 1108422458, 1108406967, 1108392895, 1108380286, 1108369184, 1108359626, 1108351647, + 1108345281, 1108340553, 1108337489, 1108336107, 1108336422, 1108338446, 1108342183, 1108347636, 1108354799, + 1108363664, 1108374217, 1108386437, 1108400301, 1108415777, 1108432830, 1108451419, 1108471498, 1108493014, + 1108515912, 1108540129, 1108565598, 1108592247, 1108620001, 1108648779, 1108678497, 1108709066, 1108740395, + 1108772389, 1108804951, 1108837980, 1108871376, 1108905035, 1108938852, 1108972723, 1109006542, 1109040205, + 1109073607, 1109106645, 1109139216, 1109171221, 1109202563, 1109233147, 1109262880, 1109291675, 1109319447, + 1109346114, 1109371602, 1109395837, 1109418753, 1109440288, 1109460385, 1109478991, 1109496061, 1109511552, + 1109525430, 1109537663, 1109548227, 1109557101, 1109564272, 1109569731, 1109573473, 1109575498, 1109575814, + 1109574431, 1109571363, 1109566630, 1109560257, 1109552270, 1109542702, 1109531587, 1109518966, 1109504879, + 1109489374, 1109472496, 1109454299, 1109434835, 1109414161, 1109392335, 1109369417, 1109345469, 1109320555, + 1109294742, 1109268095, 1109240684, 1109212578, 1109183848, 1109154564, 1109124800, 1109094627, 1109064121, + 1109033354, 1109002402, 1108971338, -1108940237, -1108909175, -1108878226, -1108847464, -1108816965, -1108786801, + -1108757046, -1108727774, -1108699056, -1108670963, -1108643567, -1108616936, -1108591139, -1108566243, -1108542312, + -1108519412, -1108497603, -1108476946, -1108457499, -1108439319, -1108422458, -1108406967, -1108392895, -1108380286, + -1108369184, -1108359626, -1108351647, -1108345281, -1108340553, -1108337489, -1108336107, -1108336422, -1108338446, + -1108342183, -1108347636, -1108354799, -1108363664, -1108374217, -1108386437, -1108400301, -1108415777, -1108432830, + -1108451419, -1108471498, -1108493014, -1108515912, -1108540129, -1108565598, -1108592247, -1108620001, -1108648779, + -1108678497, -1108709066, -1108740395, -1108772389, -1108804951, -1108837980, -1108871376, -1108905035, -1108938852, + -1108972723, -1109006542, -1109040205, -1109073607, -1109106645, -1109139216, -1109171221, -1109202563, -1109233147, + -1109262880, -1109291675, -1109319447, -1109346114, -1109371602, -1109395837, -1109418753, -1109440288, -1109460385, + -1109478991, -1109496061, -1109511552, -1109525430, -1109537663, -1109548227, -1109557101, -1109564272, -1109569731, + -1109573473, -1109575498, -1109575814, -1109574431, -1109571363, -1109566630, -1109560257, -1109552270, -1109542702, + -1109531587, -1109518966, -1109504879, -1109489374, -1109472496, -1109454299, -1109434835, -1109414161, -1109392335, + -1109369417, -1109345469, -1109320555, -1109294742, -1109268095, -1109240684, -1109212578, -1109183848, -1109154564, + -1109124800, -1109094627, -1109064121, -1109033354, -1109002402, -1108971338, -1108940237, -1108909175, -1108878226, + -1108847464, -1108816965, -1108786801, -1108757046, -1108727774, -1108699056, -1108670963, -1108643567, -1108616936, + -1108591139, -1108566243, -1108542312, -1108519412, -1108497603, -1108476946, -1108457499, -1108439319, -1108422458, + -1108406967, -1108392895, -1108380286, -1108369184, -1108359626, -1108351647, -1108345281, -1108340553, -1108337489, + -1108336107, -1108336422, -1108338446, -1108342183, -1108347636, -1108354799, -1108363664, -1108374217, -1108386437, + -1108400301, -1108415777, -1108432830, -1108451419, -1108471498, -1108493014, -1108515912, -1108540129, -1108565598, + -1108592247, -1108620001, -1108648779, -1108678497, -1108709066, -1108740395, -1108772389, -1108804951, -1108837980, + -1108871376, -1108905035, -1108938852, -1108972682, -1109006261, -1109039351, -1109071571, -1109102407, -1109131162, + -1109156896, -1109178374, -1109193989, -1109201688, -1109198891, -1109182406, -1109148336, -1109091993, -1109007805, + -1108889225, -1108728643, -1108517302, -1108245211, -1107901063, -1107472158, -1106944320, -1106301824, -1105527310, + -1104601707, -1103504157, -1102211925, -1100700333, -1098942681, -1096910184, -1094571927, -1091894839, -1088843693, + -1085381150, -1081467851, -1077062556, -1072122362, -1066602975, -1060459071, -1053644721, -1046113898, -1037821043, + -1028721699, -1018773190, -1007935330, -996171157, -983447669, -969736537, -955014802, -939265519, -922478340, + -904650040, -885784954, -865895333, -845001612, -823132583, -800325469, -776625909, -752087844, -726773304, + -700752110, -674101477, -646905528, -619254721, -591245188, -562977986, -534558266, -506094363, -477696807, + -449477265, -421547413, -394017760, -366996430, -340587909, -314891801, -290001587, -266003441, -242975106, + -220984887, -200090776, -180339738, -161767200, -144396752, -128240072, -113297104, -99556455, -86996029, + -75583860, -65279122, -56033278, -47791333, -40493145, -34074759, -28469709, -23610284, -19428682, + -15858075, -12833534, -10292814, -8176993, -6430970, -5003818, -3849000, -2924474, -2192679, + -1620441, -1178790, -842729, -590941, -405483, -271445, -176613, -111130, -67168, + -38622, -20823, -10279, -4442, -1508, -229 }; +RAM_ALIGN const Word32 LowDelayShapes_n960_N960_HRA_2_5ms_IP[480] = { + 214, 718, 1564, 2887, 4850, 7655, 11549, 16828, 23847, + 33024, 44855, 59914, 78870, 102494, 131671, 167412, 210862, 263320, + 326247, 401279, 490246, 595184, 718349, 862234, 1029583, 1223409, 1447008, + 1703973, 1998212, 2333963, 2715805, 3148674, 3637878, 4189104, 4808432, 5502344, + 6277732, 7141903, 8102584, 9167924, 10346495, 11647288, 13079711, 14653577, 16379097, + 18266869, 20327854, 22573365, 25015043, 27664828, 30534935, 33637823, 36986159, 40592781, + 44470665, 48632874, 53092523, 57862728, 62956563, 68387004, 74166887, 80308851, 86825288, + 93728290, 101029595, 108740533, 116871978, 125434289, 134437259, 143890065, 153801219, 164178510, + 175028964, 186358792, 198173341, 210477054, 223273422, 236564945, 250353087, 264638241, 279419691, + 294695574, 310462852, 326717278, 343453367, 360664374, 378342268, 396477718, 415060072, 434077349, + 453516232, 473362064, 493598851, 514209273, 535174695, 556475190, 578089564, 599995393, 622169062, + 644585817, 667219821, 690044217, 713031208, 736152130, 759377547, 782677345, 806020840, 829376886, + 852713991, 876000447, 899204452, 922294246, 945238242, 968005170, 990564209, 1012885127, 1034938418, + 1056695435, 1078128516, 1099211112, 1119917901, 1140224902, 1160109567, 1179550884, 1198529445, 1217027528, + 1235029144, 1252520091, 1269487982, 1285922269, 1301814250, 1317157066, 1331945687, 1346176884, 1359849191, + 1372962859, 1385519797, 1397523511, 1408979025, 1419892807, 1430272680, 1440127732, 1449468226, 1458305498, + 1466651859, 1474520500, 1481925383, 1488881148, 1495403011, 1501506666, 1507208191, 1512523957, 1517470536, + 1522064619, 1526322933, 1530262165, 1533898889, 1537249499, 1540330149, 1543156689, 1545744622, 1548109049, + 1550264632, 1552225553, 1554005489, 1555617576, 1557074399, 1558387963, 1559569689, 1560630404, 1561580336, + 1562429115, 1563185777, 1563858772, 1564455973, 1564984695, 1565451702, 1565863235, 1566225027, 1566542325, + 1566819919, 1567062160, 1567272989, 1567455965, 1567614286, 1567750818, 1567868122, 1567968477, 1568053906, + 1568126199, 1568186936, 1568237509, 1568279142, 1568312908, 1568339752, 1568360503, 1568375889, 1568386553, + 1568393062, 1568395921, 1568395582, 1568392450, 1568386895, 1568379252, 1568369831, 1568358921, 1568346793, + 1568333699, 1568319881, 1568305568, 1568290979, 1568276322, 1568261795, 1568247587, 1568233876, 1568220830, + 1568208605, 1568197346, 1568187184, 1568178237, 1568170607, 1568164384, 1568159638, 1568156425, 1568154783, + 1568154732, 1568156276, 1568159400, 1568164071, 1568170240, 1568177841, 1568186791, 1568196993, 1568208336, + 1568220695, 1568233934, 1568247907, 1568262461, 1568277433, 1568292659, -1568307970, -1568323196, -1568338169, + -1568352723, -1568366698, -1568379938, -1568392298, -1568403642, -1568413846, -1568422797, -1568430399, -1568436568, + -1568441238, -1568444360, -1568445899, -1568445842, -1568444189, -1568440959, -1568436189, -1568429930, -1568422249, + -1568413227, -1568402961, -1568391555, -1568379128, -1568365802, -1568351710, -1568336985, -1568321763, -1568306179, + -1568290362, -1568274432, -1568258500, -1568242658, -1568226981, -1568211514, -1568196277, -1568181247, -1568166364, + -1568151514, -1568136526, -1568121163, -1568105112, -1568087973, -1568069251, -1568048342, -1568024520, -1567996924, + -1567964542, -1567926198, -1567880531, -1567825982, -1567760771, -1567682880, -1567590033, -1567479671, -1567348935, + -1567194644, -1567013268, -1566800908, -1566553276, -1566265667, -1565932945, -1565549513, -1565109302, -1564605744, + -1564031762, -1563379748, -1562641555, -1561808482, -1560871269, -1559820088, -1558644542, -1557333666, -1555875931, + -1554259255, -1552471010, -1550498044, -1548326699, -1545942840, -1543331880, -1540478822, -1537368293, -1533984594, + -1530311749, -1526333557, -1522033659, -1517395595, -1512402882, -1507039082, -1501287884, -1495133187, -1488559185, + -1481550459, -1474092069, -1466169648, -1457769502, -1448878707, -1439485206, -1429577913, -1419146803, -1408183016, + -1396678943, -1384628319, -1372026306, -1358869573, -1345156368, -1330886582, -1316061806, -1300685380, -1284762427, + -1268299884, -1251306514, -1233792909, -1215771486, -1197256464, -1178263828, -1158811290, -1138918228, -1118605615, + -1097895946, -1076813140, -1055382446, -1033630329, -1011584359, -989273085, -966725907, -943972946, -921044904, + -897972934, -874788497, -851523227, -828208798, -804876792, -781558570, -758285150, -735087092, -711994385, + -689036342, -666241506, -643637563, -621251256, -599108313, -577233388, -555649994, -534380464, -513445903, + -492866154, -472659775, -452844015, -433434798, -414446719, -395893041, -377785693, -360135279, -342951091, + -326241124, -310012090, -294269448, -279017421, -264259031, -249996126, -236229411, -222958488, -210181887, + -197897110, -186100669, -174788126, -163954142, -153592518, -143696242, -134257536, -125267909, -116718201, + -108598638, -100898882, -93608083, -86714933, -80207718, -74074369, -68302521, -62879558, -57792672, + -53028908, -48575221, -44418518, -40545711, -36943757, -33599707, -30500746, -27634227, -24987716, + -22549018, -20306212, -18247679, -16362124, -14638601, -13066533, -11635723, -10336374, -9159092, + -8094899, -7135237, -6271969, -5497377, -4804166, -4185453, -3634765, -3146030, -2713568, + -2332079, -1996632, -1702653, -1445912, -1222503, -1028839, -861625, -717855, -594786, + -489927, -401025, -326046, -263164, -210741, -167319, -131601, -102441, -78831, + -59886, -44835, -33011, -23837, -16822, -11545, -7652, -4848, -2886, + -1564, -718, -214 }; +RAM_ALIGN const Word32 LowDelayShapes_n960_N960_HRA_5ms_IP[840] = { + 76, 257, 559, 1032, 1734, 2736, 4127, 6013, 8519, + 11795, 16017, 21388, 28146, 36565, 46958, 59681, 75141, 93793, + 116154, 142798, 174368, 211576, 255213, 306147, 365337, 433830, 512771, + 603404, 707083, 825270, 959545, 1111607, 1283278, 1476512, 1693391, 1936135, + 2207099, 2508779, 2843816, 3214988, 3625222, 4077586, 4575292, 5121693, 5720282, + 6374686, 7088668, 7866117, 8711044, 9627575, 10619947, 11692493, 12849640, 14095892, + 15435823, 16874063, 18415286, 20064193, 21825499, 23703917, 25704138, 27830817, 30088554, + 32481870, 35015193, 37692833, 40518962, 43497594, 46632560, 49927486, 53385775, 57010578, + 60804774, 64770951, 68911378, 73227988, 77722354, 82395670, 87248734, 92281923, 97495181, + 102888003, 108459414, 114207966, 120131717, 126228227, 132494547, 138927218, 145522261, 152275182, + 159180971, 166234104, 173428552, 180757788, 188214801, 195792105, 203481764, 211275403, 219164235, + 227139085, 235190416, 243308359, 251482745, 259703138, 267958873, 276239090, 284532776, 292828806, + 301115982, 309383080, 317618887, 325812253, 333952128, 342027608, 350027981, 357942764, 365761752, + 373475051, 381073123, 388546818, 395887478, 403086861, 410137202, 417031278, 423762414, 430324505, + 436712040, 442920115, 448944445, 454781381, 460427907, 465881653, 471140887, 476204517, 481072084, + 485743749, 490220286, 494503064, 498594029, 502495687, 506211078, 509743756, 513097759, 516277584, + 519288161, 522134817, 524823252, 527359505, 529749922, 532001128, 534119994, 536113606, 537989238, + 539754317, 541416403, 542983151, 544462298, 545861626, 547188947, 548452077, 549658817, 550816937, + 551934153, 553018114, 554076391, 555116460, 556145691, 557171340, 558200539, 559240287, 560297445, + 561378728, 562490702, 563639778, 564832206, 566074075, 567371305, 568729649, 570154682, 571651805, + 573226236, 574883010, 576626970, 578462769, 580394858, 582427488, 584564698, 586810313, 589167940, + 591640954, 594232500, 596945481, 599782552, 602746115, 605838312, 609061015, 612415825, 615904060, + 619526756, 623284658, 627178213, 631207574, 635372590, 639672804, 644107457, 648675483, 653375510, + 658205862, 663164563, 668249336, 673457615, 678786542, 684232980, 689793518, 695464480, 701241935, + 707121707, 713099387, 719170342, 725329733, 731572527, 737893509, 744287298, 750748363, 757271038, + 763849540, 770477982, 777150393, 783860731, 790602903, 797370781, 804158216, 810959059, 817767172, + 824576448, 831380824, 838174297, 844950938, 851704905, 858430460, 865121975, 871773953, 878381029, + 884937988, 891439772, 897881487, 904258415, 910566018, 916799945, 922956036, 929030332, 935019072, + 940918701, 946725867, 952437431, 958050459, 963562228, 968970222, 974272134, 979465863, 984549513, + 989521388, 994379992, 999124027, 1003752385, 1008264148, 1012658583, 1016935141, 1021093445, 1025133296, + 1029054661, 1032857672, 1036542620, 1040109952, 1043560268, 1046894310, 1050112965, 1053217256, 1056208338, + 1059087494, 1061856131, 1064515771, 1067068050, 1069514712, 1071857603, 1074098665, 1076239931, 1078283519, + 1080231627, 1082086525, 1083850551, 1085526101, 1087115629, 1088621631, 1090046648, 1091393252, 1092664044, + 1093861644, 1094988685, 1096047808, 1097041655, 1097972860, 1098844046, 1099657818, 1100416756, 1101123410, + 1101780297, 1102389891, 1102954625, 1103476879, 1103958984, 1104403212, 1104811774, 1105186822, 1105530438, + 1105844638, 1106131370, 1106392508, 1106629854, 1106845137, 1107040012, 1107216060, 1107374784, 1107517617, + 1107645915, 1107760961, 1107863967, 1107956073, 1108038347, 1108111792, 1108177340, 1108235860, 1108288159, + 1108334979, 1108377006, 1108414868, 1108449137, 1108480336, 1108508935, 1108535359, 1108559986, 1108583153, + 1108605158, 1108626260, 1108646685, 1108666625, 1108686243, 1108705675, 1108725031, 1108744398, 1108763843, + 1108783413, 1108803139, 1108823037, 1108843110, 1108863348, 1108883733, 1108904238, 1108924827, 1108945461, + 1108966087, 1108986655, 1109007132, 1109027458, 1109047572, 1109067415, 1109086928, 1109106055, 1109124739, + 1109142927, 1109160566, 1109177606, 1109193997, 1109209694, 1109224653, 1109238833, 1109252194, 1109264701, + 1109276321, 1109287024, 1109296781, 1109305569, 1109313366, 1109320154, 1109325918, 1109330645, 1109334328, + 1109336959, 1109338535, 1109339057, 1109338528, 1109336954, 1109334342, 1109330704, 1109326055, 1109320411, + 1109313791, 1109306216, 1109297711, 1109288301, 1109278014, 1109266881, 1109254934, 1109242206, 1109228734, + 1109214554, 1109199706, 1109184228, 1109168164, 1109151555, 1109134445, 1109116879, 1109098903, 1109080563, + 1109061906, 1109042980, 1109023833, 1109004515, 1108985073, 1108965557, 1108946017, 1108926503, 1108907062, + 1108887746, 1108868601, 1108849679, 1108831026, 1108812690, 1108794719, 1108777158, 1108760054, 1108743451, + 1108727393, 1108711923, 1108697081, 1108682908, 1108669442, 1108656721, 1108644781, 1108633654, 1108623374, + 1108613969, 1108605469, 1108597899, 1108591283, 1108585643, 1108580997, 1108577362, 1108574752, 1108573178, + 1108572650, 1108573172, 1108574747, 1108577376, 1108581056, 1108585780, 1108591541, 1108598324, 1108606116, + 1108614899, 1108624650, 1108635346, 1108646959, 1108659460, 1108672814, 1108686987, 1108701939, 1108717629, + 1108734013, 1108751046, 1108768679, 1108786861, 1108805540, 1108824662, 1108844171, 1108864011, 1108884121, + 1108904445, 1108924921, 1108945488, -1108966087, -1108986655, -1109007132, -1109027458, -1109047572, -1109067415, + -1109086928, -1109106055, -1109124739, -1109142927, -1109160566, -1109177606, -1109193997, -1109209694, -1109224653, + -1109238833, -1109252194, -1109264701, -1109276321, -1109287024, -1109296781, -1109305569, -1109313366, -1109320154, + -1109325918, -1109330645, -1109334328, -1109336959, -1109338535, -1109339057, -1109338528, -1109336954, -1109334342, + -1109330704, -1109326055, -1109320411, -1109313791, -1109306216, -1109297711, -1109288301, -1109278014, -1109266881, + -1109254934, -1109242206, -1109228734, -1109214554, -1109199706, -1109184228, -1109168164, -1109151555, -1109134445, + -1109116879, -1109098903, -1109080563, -1109061906, -1109042980, -1109023833, -1109004515, -1108985073, -1108965557, + -1108946017, -1108926503, -1108907062, -1108887746, -1108868601, -1108849679, -1108831026, -1108812690, -1108794719, + -1108777158, -1108760054, -1108743451, -1108727393, -1108711923, -1108697081, -1108682908, -1108669442, -1108656721, + -1108644781, -1108633654, -1108623374, -1108613969, -1108605469, -1108597899, -1108591283, -1108585643, -1108580997, + -1108577362, -1108574752, -1108573178, -1108572650, -1108573172, -1108574747, -1108577376, -1108581056, -1108585780, + -1108591541, -1108598324, -1108606116, -1108614899, -1108624650, -1108635346, -1108646959, -1108659460, -1108672814, + -1108686987, -1108701939, -1108717629, -1108734013, -1108751046, -1108768679, -1108786861, -1108805540, -1108824662, + -1108844171, -1108864011, -1108884121, -1108904445, -1108924921, -1108945488, -1108966059, -1108986562, -1109006925, + -1109027070, -1109046909, -1109066353, -1109085302, -1109103653, -1109121290, -1109138090, -1109153916, -1109168619, + -1109182038, -1109193990, -1109204280, -1109212687, -1109218972, -1109222869, -1109224086, -1109222302, -1109217164, + -1109208286, -1109195243, -1109177572, -1109154771, -1109126288, -1109091528, -1109049845, -1109000541, -1108942861, + -1108875994, -1108799068, -1108711146, -1108611228, -1108498242, -1108371047, -1108228427, -1108069090, -1107891663, + -1107694692, -1107476636, -1107235870, -1106970675, -1106679239, -1106359654, -1106009912, -1105627904, -1105211414, + -1104758117, -1104265576, -1103731240, -1103152437, -1102526375, -1101850136, -1101120673, -1100334807, -1099489225, + -1098580473, -1097604958, -1096558943, -1095438542, -1094239723, -1092958302, -1091589944, -1090130161, -1088574313, + -1086917606, -1085155099, -1083281700, -1081292171, -1079181138, -1076943086, -1074572374, -1072063243, -1069409818, + -1066606126, -1063646105, -1060523618, -1057232468, -1053766415, -1050119192, -1046284528, -1042256165, -1038027882, + -1033593517, -1028946994, -1024082345, -1018993738, -1013675503, -1008122162, -1002328454, -996289366, -990000160, + -983456402, -976653990, -969589182, -962258626, -954659381, -946788949, -938645296, -930226877, -921532657, + -912562133, -903315354, -893792938, -883996084, -873926592, -863586870, -852979945, -842109472, -830979735, + -819595655, -807962787, -796087320, -783976072, -771636483, -759076610, -746305110, -733331233, -720164799, + -706816188, -693296313, -679616605, -665788980, -651825820, -637739943, -623544570, -609253297, -594880059, + -580439096, -565944918, -551412265, -536856066, -522291404, -507733472, -493197528, -478698857, -464252725, + -449874333, -435578778, -421381001, -407295749, -393337528, -379520558, -365858731, -352365567, -339054174, + -325937207, -313026827, -300334664, -287871784, -275648653, -263675105, -251960314, -240512770, -229340251, + -218449809, -207847746, -197539607, -187530166, -177823422, -168422593, -159330123, -150547678, -142076164, + -133915731, -126065794, -118525050, -111291498, -104362470, -97734652, -91404122, -85366377, -79616373, + -74148557, -68956911, -64034986, -59375949, -54972617, -50817502, -46902854, -43220698, -39762875, + -36521086, -33486923, -30651913, -28007548, -25545325, -23256770, -21133479, -19167136, -17349546, + -15672656, -14128580, -12709614, -11408260, -10217235, -9129491, -8138220, -7236869, -6419144, + -5679019, -5010736, -4408811, -3868031, -3383459, -2950426, -2564532, -2221640, -1917871, + -1649598, -1413439, -1206249, -1025112, -867332, -730423, -612103, -510279, -423042, + -348652, -285533, -232260, -187551, -150254, -119343, -93901, -73120, -56285, + -42770, -32029, -23588, -17037, -12025, -8254, -5472, -3467, -2064, + -1119, -513, -153 }; +RAM_ALIGN const Word32 LowDelayShapes_n960_N960_HRA_IP[1560] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 52, 175, 382, + 705, 1185, 1871, 2823, 4114, 5831, 8077, 10972, 14660, + 19303, 25092, 32244, 41009, 51670, 64545, 79996, 98427, 120290, + 146088, 176379, 211778, 252965, 300685, 355753, 419058, 491567, 574329, + 668476, 775231, 895906, 1031911, 1184750, 1356028, 1547453, 1760836, 1998091, + 2261242, 2552417, 2873848, 3227877, 3616948, 4043606, 4510498, 5020366, 5576047, + 6180463, 6836620, 7547602, 8316559, 9146706, 10041310, 11003683, 12037172, 13145144, + 14330983, 15598071, 16949778, 18389446, 19920381, 21545832, 23268982, 25092926, 27020662, + 29055072, 31198906, 33454766, 35825091, 38312140, 40917976, 43644450, 46493186, 49465569, + 52562726, 55785514, 59134509, 62609992, 66211939, 69940008, 73793535, 77771521, 81872629, + 86095178, 90437137, 94896125, 99469410, 104153908, 108946186, 113842469, 118838639, 123930249, + 129112527, 134380390, 139728454, 145151046, 150642225, 156195792, 161805313, 167464136, 173165413, + 178902121, 184667086, 190453005, 196252476, 202058015, 207862090, 213657145, 219435626, 225190009, + 230912827, 236596697, 242234348, 247818648, 253342624, 258799497, 264182697, 269485893, 274703012, + 279828312, 284856314, 289781856, 294600125, 299306665, 303897390, 308368599, 312716983, 316939635, + 321034059, 324998175, 328830319, 332529248, 336094136, 339524575, 342820570, 345982531, 349011267, + 351907976, 354674236, 357311989, 359823531, 362211496, 364478840, 366628822, 368664989, 370591159, + 372411396, 374129997, 375751467, 377280502, 378721970, 380080887, 381362400, 382571769, 383714343, + 384795547, 385820862, 386795806, 387725921, 388616754, 389473844, 390302710, 391108835, 391897652, + 392674541, 393444809, 394213686, 394986316, 395767747, 396562926, 397376691, 398213764, 399078748, + 399976120, 400910228, 401885285, 402905364, 403974398, 405096172, 406274322, 407512329, 408813519, + 410181054, 411617935, 413126993, 414710888, 416372104, 418112946, 419935539, 421841819, 423833534, + 425912241, 428079300, 430335872, 432682921, 435121205, 437651278, 440273491, 442987985, 445794697, + 448693355, 451683483, 454764399, 457935219, 461194860, 464542039, 467975283, 471492928, 475093126, + 478773851, 482532904, 486367920, 490276375, 494255591, 498302751, 502414896, 506588946, 510821698, + 515109841, 519449966, 523838572, 528272075, 532746823, 537259100, 541805139, 546381131, 550983233, + 555607579, 560250290, 564907481, 569575271, 574249791, 578927195, 583603665, 588275420, 592938724, + 597589893, 602225302, 606841390, 611434670, 616001729, 620539240, 625043960, 629512740, 633942527, + 638330370, 642673418, 646968929, 651214270, 655406919, 659544468, 663624624, 667645211, 671604169, + 675499557, 679329551, 683092449, 686786663, 690410727, 693963289, 697443117, 700849092, 704180212, + 707435589, 710614445, 713716116, 716740046, 719685788, 722553001, 725341451, 728051005, 730681634, + 733233409, 735706498, 738101168, 740417780, 742656787, 744818734, 746904257, 748914076, 750848997, + 752709910, 754497783, 756213660, 757858664, 759433984, 760940881, 762380680, 763754766, 765064584, + 766311629, 767497450, 768623637, 769691823, 770703677, 771660899, 772565218, 773418381, 774222155, + 774978320, 775688661, 776354967, 776979026, 777562617, 778107510, 778615459, 779088198, 779527438, + 779934863, 780312126, 780660846, 780982606, 781278948, 781551373, 781801337, 782030250, 782239474, + 782430322, 782604056, 782761888, 782904976, 783034427, 783151295, 783256582, 783351237, 783436158, + 783512191, 783580133, 783640729, 783694677, 783742630, 783785193, 783822926, 783856349, 783885939, + 783912134, 783935335, 783955909, 783974185, 783990464, 784005015, 784018080, 784029874, 784040589, + 784050394, 784059435, 784067843, 784075728, 784083188, 784090303, 784097145, 784103769, 784110225, + 784116552, 784122782, 784128939, 784135042, 784141107, 784147142, 784153152, 784159138, 784165118, + 784171086, 784177037, 784182968, 784188874, 784194749, 784200591, 784206393, 784212151, 784217862, + 784223520, 784229122, 784234663, 784240139, 784245546, 784250879, 784256136, 784261311, 784266402, + 784271403, 784276313, 784281126, 784285841, 784290452, 784294958, 784299354, 784303638, 784307807, + 784311858, 784315788, 784319595, 784323276, 784326828, 784330250, 784333539, 784336693, 784339710, + 784342589, 784345327, 784347923, 784350376, 784352685, 784354847, 784356862, 784358729, 784360447, + 784362016, 784363434, 784364702, 784365818, 784366783, 784367596, 784368257, 784368766, 784369124, + 784369331, 784369387, 784369292, 784369047, 784368653, 784368111, 784367421, 784366584, 784365602, + 784364475, 784363205, 784361793, 784360241, 784358550, 784356721, 784354756, 784352657, 784350426, + 784348065, 784345575, 784342958, 784340217, 784337354, 784334371, 784331270, 784328053, 784324723, + 784321282, 784317734, 784314079, 784310321, 784306463, 784302507, 784298456, 784294312, 784290078, + 784285758, 784281354, 784276869, 784272306, 784267667, 784262957, 784258177, 784253332, 784248423, + 784243454, 784238429, 784233349, 784228220, 784223043, 784217822, 784212560, 784207260, 784201926, + 784196560, 784191167, 784185749, 784180310, 784174852, 784169380, 784163896, 784158404, 784152907, + 784147408, 784141911, 784136419, 784130935, 784125463, 784120006, 784114567, 784109150, 784103757, + 784098392, 784093059, 784087760, 784082499, 784077278, 784072102, 784066974, 784061896, 784056872, + 784051904, 784046997, 784042152, 784037374, 784032665, 784028028, 784023466, 784018982, 784014580, + 784010261, 784006029, 784001887, 783997837, 783993883, 783990026, 783986270, 783982617, 783979069, + 783975630, 783972302, 783969087, 783965987, 783963005, 783960143, 783957404, 783954788, 783952300, + 783949939, 783947709, 783945612, 783943648, 783941820, 783940130, 783938578, 783937167, 783935898, + 783934772, 783933790, 783932954, 783932264, 783931722, 783931328, 783931084, 783930989, 783931045, + 783931251, 783931609, 783932118, 783932779, 783933592, 783934556, 783935672, 783936938, 783938356, + 783939924, 783941641, 783943507, 783945521, 783947682, 783949989, 783952441, 783955036, 783957773, + 783960650, 783963666, 783966818, 783970106, 783973526, 783977077, 783980756, 783984561, 783988490, + 783992539, 783996706, 784000989, 784005383, 784009887, 784014497, 784019210, 784024022, 784028930, + 784033930, 784039019, 784044193, 784049448, 784054780, 784060186, 784065661, 784071201, 784076801, + 784082459, 784088168, 784093926, 784099727, 784105568, 784111443, 784117348, 784123278, 784129229, + 784135197, 784141176, 784147163, 784153152, 784159138, 784165118, 784171086, 784177037, 784182968, + 784188874, 784194749, 784200591, 784206393, 784212151, 784217862, 784223520, 784229122, 784234663, + 784240139, 784245546, 784250879, 784256136, 784261311, 784266402, 784271403, 784276313, 784281126, + 784285841, 784290452, 784294958, 784299354, 784303638, 784307807, 784311858, 784315788, 784319595, + 784323276, 784326828, 784330250, 784333539, 784336693, 784339710, 784342589, 784345327, 784347923, + 784350376, 784352685, 784354847, 784356862, 784358729, 784360447, 784362016, 784363434, 784364702, + 784365818, 784366783, 784367596, 784368257, 784368766, 784369124, 784369331, 784369387, 784369292, + 784369047, 784368653, 784368111, 784367421, 784366584, 784365602, 784364475, 784363205, 784361793, + 784360241, 784358550, 784356721, 784354756, 784352657, 784350426, 784348065, 784345575, 784342958, + 784340217, 784337354, 784334371, 784331270, 784328053, 784324723, 784321282, 784317734, 784314079, + 784310321, 784306463, 784302507, 784298456, 784294312, 784290078, 784285758, 784281354, 784276869, + 784272306, 784267667, 784262957, 784258177, 784253332, 784248423, 784243454, 784238429, 784233349, + 784228220, 784223043, 784217822, 784212560, 784207260, 784201926, 784196560, 784191167, 784185749, + 784180310, 784174852, 784169380, 784163896, 784158404, 784152907, -784147408, -784141911, -784136419, + -784130935, -784125463, -784120006, -784114567, -784109150, -784103757, -784098392, -784093059, -784087760, + -784082499, -784077278, -784072102, -784066974, -784061896, -784056872, -784051904, -784046997, -784042152, + -784037374, -784032665, -784028028, -784023466, -784018982, -784014580, -784010261, -784006029, -784001887, + -783997837, -783993883, -783990026, -783986270, -783982617, -783979069, -783975630, -783972302, -783969087, + -783965987, -783963005, -783960143, -783957404, -783954788, -783952300, -783949939, -783947709, -783945612, + -783943648, -783941820, -783940130, -783938578, -783937167, -783935898, -783934772, -783933790, -783932954, + -783932264, -783931722, -783931328, -783931084, -783930989, -783931045, -783931251, -783931609, -783932118, + -783932779, -783933592, -783934556, -783935672, -783936938, -783938356, -783939924, -783941641, -783943507, + -783945521, -783947682, -783949989, -783952441, -783955036, -783957773, -783960650, -783963666, -783966818, + -783970106, -783973526, -783977077, -783980756, -783984561, -783988490, -783992539, -783996706, -784000989, + -784005383, -784009887, -784014497, -784019210, -784024022, -784028930, -784033930, -784039019, -784044193, + -784049448, -784054780, -784060186, -784065661, -784071201, -784076801, -784082459, -784088168, -784093926, + -784099727, -784105568, -784111443, -784117348, -784123278, -784129229, -784135197, -784141176, -784147163, + -784153152, -784159138, -784165118, -784171086, -784177037, -784182968, -784188874, -784194749, -784200591, + -784206393, -784212151, -784217862, -784223520, -784229122, -784234663, -784240139, -784245546, -784250879, + -784256136, -784261311, -784266402, -784271403, -784276313, -784281126, -784285841, -784290452, -784294958, + -784299354, -784303638, -784307807, -784311858, -784315788, -784319595, -784323276, -784326828, -784330250, + -784333539, -784336693, -784339710, -784342589, -784345327, -784347923, -784350376, -784352685, -784354847, + -784356862, -784358729, -784360447, -784362016, -784363434, -784364702, -784365818, -784366783, -784367596, + -784368257, -784368766, -784369124, -784369331, -784369387, -784369292, -784369047, -784368653, -784368111, + -784367421, -784366584, -784365602, -784364475, -784363205, -784361793, -784360241, -784358550, -784356721, + -784354756, -784352657, -784350426, -784348065, -784345575, -784342958, -784340217, -784337354, -784334371, + -784331270, -784328053, -784324723, -784321282, -784317734, -784314079, -784310321, -784306463, -784302507, + -784298456, -784294312, -784290078, -784285758, -784281354, -784276869, -784272306, -784267667, -784262957, + -784258177, -784253332, -784248423, -784243454, -784238429, -784233349, -784228220, -784223043, -784217822, + -784212560, -784207260, -784201926, -784196560, -784191167, -784185749, -784180310, -784174852, -784169380, + -784163896, -784158404, -784152907, -784147408, -784141911, -784136419, -784130935, -784125463, -784120006, + -784114567, -784109150, -784103757, -784098392, -784093059, -784087760, -784082499, -784077278, -784072102, + -784066974, -784061896, -784056872, -784051904, -784046997, -784042152, -784037374, -784032665, -784028028, + -784023466, -784018982, -784014580, -784010261, -784006029, -784001887, -783997837, -783993883, -783990026, + -783986270, -783982617, -783979069, -783975630, -783972302, -783969087, -783965987, -783963005, -783960143, + -783957404, -783954788, -783952300, -783949939, -783947709, -783945612, -783943648, -783941820, -783940130, + -783938578, -783937167, -783935898, -783934772, -783933790, -783932954, -783932264, -783931722, -783931328, + -783931084, -783930989, -783931045, -783931251, -783931609, -783932118, -783932779, -783933592, -783934556, + -783935672, -783936938, -783938356, -783939924, -783941641, -783943507, -783945521, -783947682, -783949989, + -783952441, -783955036, -783957773, -783960650, -783963666, -783966818, -783970106, -783973526, -783977077, + -783980756, -783984561, -783988490, -783992539, -783996706, -784000989, -784005383, -784009887, -784014497, + -784019210, -784024022, -784028930, -784033930, -784039019, -784044193, -784049448, -784054780, -784060186, + -784065661, -784071201, -784076801, -784082459, -784088168, -784093926, -784099727, -784105568, -784111443, + -784117348, -784123278, -784129229, -784135197, -784141176, -784147163, -784153131, -784159068, -784164963, + -784170795, -784176541, -784182173, -784187657, -784192951, -784198007, -784202769, -784207169, -784211130, + -784214559, -784217353, -784219391, -784220535, -784220630, -784219497, -784216937, -784212727, -784206617, + -784198327, -784187551, -784173947, -784157141, -784136723, -784112243, -784083213, -784049101, -784009333, + -783963287, -783910294, -783849634, -783780538, -783702180, -783613679, -783514100, -783402445, -783277658, + -783138617, -782984141, -782812977, -782623808, -782415247, -782185834, -781934039, -781658253, -781356794, + -781027899, -780669728, -780280356, -779857776, -779399894, -778904531, -778369419, -777792197, -777170416, + -776501532, -775782908, -775011810, -774185411, -773300787, -772354919, -771344691, -770266894, -769118226, + -767895293, -766594614, -765212620, -763745664, -762190019, -760541889, -758797411, -756952664, -755003678, + -752946440, -750776904, -748491005, -746084664, -743553805, -740894366, -738102311, -735173645, -732104432, + -728890802, -725528974, -722015270, -718346128, -714518120, -710527972, -706372573, -702048997, -697554517, + -692886621, -688043026, -683021694, -677820848, -672438982, -666874876, -661127608, -655196568, -649081463, + -642782332, -636299553, -629633851, -622786302, -615758346, -608551783, -601168786, -593611894, -585884022, + -577988458, -569928861, -561709265, -553334069, -544808041, -536136306, -527324347, -518377994, -509303418, + -500107123, -490795932, -481376983, -471857712, -462245842, -452549370, -442776550, -432935882, -423036090, + -413086109, -403095064, -393072251, -383027119, -372969246, -362908319, -352854112, -342816459, -332805234, + -322830326, -312901609, -303028921, -293222034, -283490629, -273844269, -264292369, -254844170, -245508712, + -236294804, -227211000, -218265568, -209466468, -200821323, -192337394, -184021561, -175880295, -167919639, + -160145191, -152562081, -145174961, -137987988, -131004813, -124228572, -117661879, -111306824, -105164969, + -99237348, -93524475, -88026347, -82742454, -77671790, -72812867, -68163733, -63721988, -59484805, + -55448955, -51610827, -47966456, -44511550, -41241516, -38151492, -35236370, -32490831, -29909374, + -27486341, -25215951, -23092326, -21109518, -19261540, -17542387, -15946062, -14466601, -13098096, + -11834709, -10670701, -9600439, -8618419, -7719279, -6897809, -6148962, -5467868, -4849835, + -4290361, -3785136, -3330046, -2921175, -2554807, -2227423, -1935704, -1676526, -1446955, + -1244248, -1065844, -909363, -772594, -653495, -550182, -460924, -384136, -318370, + -262309, -214759, -174641, -140984, -112917, -89663, -70531, -54908, -42257, + -32104, -24037, -17698, -12781, -9020, -6190, -4103, -2600, -1548, + -839, -385, -115 }; +#endif /* ENABLE_HR_MODE */ + +#ifdef ENABLE_HR_MODE +RAM_ALIGN const Word32 *const LowDelayShapes_n960_HRA_2_5ms[2] = { LowDelayShapes_n960_N480_HRA_2_5ms_IP, + LowDelayShapes_n960_N960_HRA_2_5ms_IP }; + +RAM_ALIGN const Word32 *const LowDelayShapes_n960_HRA_5ms[2] = { LowDelayShapes_n960_N480_HRA_5ms_IP, + LowDelayShapes_n960_N960_HRA_5ms_IP }; + +RAM_ALIGN const Word32 *const LowDelayShapes_n960_HRA[2] = { LowDelayShapes_n960_N480_HRA_IP, + LowDelayShapes_n960_N960_HRA_IP }; + +# ifdef CR8_G_ADD_75MS +RAM_ALIGN const Word32 *const LowDelayShapes_n960_HRA_7_5ms[2] = { LowDelayShapes_n960_N480_HRA_7_5ms_IP, + LowDelayShapes_n960_N960_HRA_7_5ms_IP }; +# endif +#endif /* ENABLE_HR_MODE */ + +RAM_ALIGN const Word16 pitch_max[5] = {MAX_PITCH_8K, MAX_PITCH_16K, MAX_PITCH_24K, MAX_PITCH_32K, MAX_PITCH_48K}; +RAM_ALIGN const Word16 plc_preemph_fac[NUM_SAMP_FREQ] = {20316, 23592, 26869, 30146, 30146 +# ifdef ENABLE_HR_MODE + , 30146 +# endif + }; +/* high pass filter Q15 */ +RAM_ALIGN const Word16 TDC_high_16[11] = {(Word16)0x0000, (Word16)0xfd60, (Word16)0xf7ab, (Word16)0xefec, + (Word16)0xe910, (Word16)0x66c2, (Word16)0xe910, (Word16)0xefec, + (Word16)0xf7ab, (Word16)0xfd60, (Word16)0x0000}; + +RAM_ALIGN const Word16 TDC_high_32[11] = {(Word16)0xf962, (Word16)0xf87d, (Word16)0xf581, (Word16)0xf2e5, + (Word16)0xf11a, (Word16)0x7076, (Word16)0xf11a, (Word16)0xf2e5, + (Word16)0xf581, (Word16)0xf87d, (Word16)0xf962}; + +RAM_ALIGN const Word16 TDC_high_16_harm[11] = {(Word16) 174, (Word16) 0, (Word16) -1442, (Word16) 0, + (Word16) 8641, (Word16) 18022, (Word16) 8641, (Word16) 0, + (Word16) -1442, (Word16) 0, (Word16) 174}; + +RAM_ALIGN const Word16 TDC_high_32_harm[11] = {(Word16) -174, (Word16) -121, (Word16) -459, (Word16) 590, + (Word16) 8743, (Word16) 16355, (Word16) 8743, (Word16) 590, + (Word16) -459, (Word16) -121, (Word16) -174}; + + +#ifdef SUBSET_NB +RAM_ALIGN const Word16 LowDelayShapes_n960_N80[130] = { + -15, -43, -94, -171, -277, -414, -580, -771, -981, -1201, -1423, -1638, -1836, + -2008, -2145, -2240, -2286, -2279, -2214, -2085, -1889, -1621, -1274, -842, -318, 305, + 1034, 1876, 2833, 3906, 5091, 6379, 7754, 9198, 10683, 12179, 13652, 15068, 16390, + 17588, 18634, 19509, 20201, 20712, 21051, 21237, 21297, 21263, 21168, 21044, 20918, 20797, + 20701, 20627, 20571, 20529, 20499, 20479, 20468, 20463, 20464, 20469, 20477, 20486, 20495, + 20503, 20509, 20514, 20516, 20518, 20520, 20524, 20530, 20540, 20556, 20576, 20602, 20633, + 20668, 20705, -20743, -20781, -20816, -20847, -20873, -20894, -20910, -20920, -20927, -20930, -20932, + -20934, -20937, -20942, -20948, -20956, -20966, -20975, -20982, -20988, -20989, -20984, -20972, -20952, + -20921, -20879, -20822, -20747, -20652, -20532, -20359, -20121, -19785, -19318, -18689, -17873, -16855, + -15636, -14231, -12670, -10997, -9266, -7542, -5889, -4373, -3051, -1965, -1136, -560, -207}; +#else +#define LowDelayShapes_n960_N80 NULL +#endif + +#ifdef SUBSET_WB +RAM_ALIGN const Word16 LowDelayShapes_n960_N160[260] = { + -14, -29, -49, -76, -112, -156, -210, -275, -350, -437, -534, -641, -759, -885, + -1020, -1163, -1311, -1464, -1620, -1777, -1935, -2090, -2242, -2390, -2530, -2661, -2783, -2893, + -2990, -3073, -3140, -3191, -3224, -3238, -3233, -3208, -3162, -3094, -3003, -2889, -2751, -2587, + -2397, -2180, -1935, -1661, -1355, -1018, -648, -244, 197, 674, 1190, 1745, 2340, 2976, + 3652, 4370, 5129, 5928, 6766, 7642, 8553, 9496, 10470, 11469, 12490, 13529, 14579, 15637, + 16696, 17750, 18792, 19817, 20819, 21791, 22727, 23621, 24469, 25264, 26004, 26685, 27304, 27858, + 28348, 28773, 29134, 29433, 29672, 29855, 29986, 30070, 30112, 30117, 30092, 30043, 29976, 29895, + 29807, 29716, 29632, 29536, 29451, 29374, 29307, 29247, 29195, 29149, 29109, 29075, 29045, 29020, + 28999, 28982, 28968, 28957, 28949, 28943, 28940, 28939, 28940, 28942, 28946, 28950, 28956, 28962, + 28968, 28975, 28981, 28987, 28993, 28998, 29002, 29006, 29009, 29012, 29014, 29015, 29017, 29018, + 29019, 29021, 29024, 29027, 29031, 29037, 29044, 29053, 29064, 29077, 29091, 29108, 29126, 29146, + 29168, 29192, 29216, 29242, 29268, 29295, -29322, -29349, -29376, -29401, -29426, -29450, -29472, -29492, + -29511, -29527, -29542, -29555, -29566, -29575, -29583, -29589, -29593, -29596, -29599, -29601, -29602, -29603, + -29605, -29606, -29608, -29611, -29614, -29618, -29623, -29628, -29634, -29640, -29646, -29653, -29660, -29666, + -29671, -29676, -29680, -29682, -29683, -29682, -29678, -29673, -29664, -29653, -29639, -29621, -29600, -29574, + -29544, -29509, -29469, -29423, -29370, -29310, -29243, -29167, -29083, -28988, -28861, -28718, -28551, -28351, + -28114, -27834, -27505, -27121, -26677, -26168, -25591, -24943, -24223, -23431, -22569, -21639, -20644, -19592, + -18487, -17338, -16154, -14944, -13719, -12491, -11270, -10068, -8898, -7771, -6698, -5689, -4753, -3898, + -3130, -2452, -1866, -1371, -964, -640, -392, -198}; +#else +#define LowDelayShapes_n960_N160 NULL +#endif +#ifdef SUBSET_SSWB +RAM_ALIGN const Word16 LowDelayShapes_n960_N240[390] = { + -9, -17, -26, -37, -50, -66, -86, -108, -134, -164, -197, -234, -275, -320, + -369, -422, -479, -539, -603, -670, -741, -814, -891, -969, -1050, -1132, -1216, -1301, + -1387, -1473, -1558, -1643, -1728, -1810, -1892, -1971, -2047, -2120, -2190, -2256, -2318, -2376, + -2429, -2477, -2519, -2556, -2586, -2611, -2629, -2640, -2645, -2642, -2632, -2614, -2589, -2556, + -2515, -2466, -2408, -2341, -2266, -2182, -2088, -1985, -1872, -1748, -1615, -1471, -1316, -1150, + -972, -783, -582, -368, -141, 99, 352, 619, 899, 1194, 1503, 1827, 2166, 2519, + 2888, 3271, 3669, 4082, 4510, 4952, 5408, 5878, 6362, 6857, 7365, 7885, 8414, 8954, + 9502, 10058, 10621, 11189, 11761, 12335, 12912, 13488, 14063, 14635, 15203, 15764, 16319, 16864, + 17399, 17922, 18431, 18926, 19405, 19866, 20309, 20732, 21135, 21517, 21876, 22213, 22526, 22817, + 23083, 23326, 23546, 23743, 23916, 24068, 24198, 24308, 24397, 24469, 24522, 24560, 24582, 24592, + 24589, 24575, 24552, 24522, 24485, 24443, 24398, 24349, 24300, 24252, 24209, 24155, 24104, 24058, + 24014, 23974, 23938, 23904, 23873, 23844, 23818, 23794, 23773, 23753, 23735, 23719, 23705, 23692, + 23681, 23670, 23662, 23654, 23647, 23642, 23638, 23634, 23632, 23630, 23629, 23629, 23629, 23630, + 23632, 23634, 23636, 23639, 23642, 23645, 23648, 23652, 23655, 23658, 23662, 23665, 23669, 23672, + 23674, 23677, 23680, 23682, 23684, 23686, 23687, 23688, 23689, 23690, 23691, 23692, 23693, 23693, + 23694, 23695, 23696, 23697, 23699, 23701, 23703, 23706, 23710, 23714, 23718, 23723, 23729, 23736, + 23743, 23751, 23760, 23769, 23779, 23790, 23801, 23813, 23825, 23838, 23851, 23865, 23879, 23894, + 23908, 23923, -23938, -23952, -23967, -23981, -23996, -24010, -24023, -24036, -24049, -24061, -24072, -24083, + -24093, -24102, -24111, -24119, -24127, -24133, -24139, -24145, -24149, -24153, -24157, -24160, -24162, -24164, + -24166, -24167, -24168, -24169, -24170, -24171, -24171, -24172, -24173, -24174, -24175, -24176, -24178, -24179, + -24181, -24184, -24186, -24189, -24192, -24195, -24198, -24202, -24205, -24209, -24213, -24216, -24219, -24223, + -24226, -24228, -24231, -24233, -24234, -24235, -24236, -24236, -24235, -24233, -24230, -24227, -24222, -24217, + -24210, -24202, -24193, -24183, -24171, -24158, -24143, -24127, -24109, -24089, -24067, -24043, -24017, -23988, + -23957, -23923, -23886, -23847, -23804, -23758, -23708, -23655, -23584, -23509, -23427, -23336, -23234, -23119, + -22990, -22846, -22685, -22506, -22307, -22087, -21845, -21580, -21291, -20977, -20638, -20272, -19880, -19462, + -19018, -18549, -18054, -17536, -16995, -16432, -15849, -15248, -14630, -13997, -13353, -12698, -12036, -11369, + -10700, -10032, -9367, -8709, -8059, -7422, -6800, -6196, -5611, -5050, -4513, -4004, -3523, -3073, + -2655, -2269, -1917, -1598, -1312, -1059, -837, -646, -484, -350, -239, -127}; +#else +#define LowDelayShapes_n960_N240 NULL +#endif + +#ifdef SUBSET_SWB +RAM_ALIGN const Word16 LowDelayShapes_n960_N320[520] = { + -6, -12, -17, -23, -30, -39, -48, -60, -72, -86, -102, -119, -138, -159, + -182, -207, -234, -262, -293, -325, -359, -396, -434, -473, -515, -558, -603, -649, + -697, -746, -797, -848, -900, -954, -1008, -1062, -1118, -1173, -1229, -1285, -1340, -1396, + -1451, -1505, -1559, -1612, -1664, -1715, -1764, -1813, -1859, -1904, -1947, -1988, -2027, -2064, + -2098, -2130, -2159, -2186, -2210, -2230, -2248, -2263, -2275, -2283, -2289, -2290, -2289, -2283, + -2274, -2262, -2245, -2225, -2201, -2173, -2141, -2105, -2065, -2020, -1971, -1918, -1860, -1797, + -1730, -1658, -1582, -1500, -1414, -1322, -1225, -1122, -1014, -901, -782, -657, -526, -389, + -246, -97, 59, 221, 390, 565, 748, 937, 1133, 1336, 1547, 1764, 1989, 2221, + 2460, 2707, 2961, 3222, 3490, 3765, 4048, 4338, 4634, 4937, 5246, 5562, 5884, 6212, + 6546, 6885, 7229, 7578, 7932, 8289, 8650, 9014, 9382, 9751, 10123, 10496, 10870, 11244, + 11619, 11992, 12365, 12736, 13105, 13471, 13833, 14192, 14546, 14895, 15239, 15576, 15907, 16231, + 16547, 16856, 17155, 17446, 17727, 17999, 18261, 18512, 18753, 18983, 19202, 19409, 19605, 19790, + 19963, 20125, 20275, 20414, 20541, 20658, 20764, 20858, 20943, 21017, 21082, 21137, 21184, 21221, + 21251, 21273, 21287, 21295, 21297, 21293, 21285, 21271, 21254, 21233, 21209, 21182, 21154, 21124, + 21092, 21060, 21028, 20999, 20972, 20935, 20902, 20870, 20839, 20811, 20784, 20758, 20734, 20712, + 20691, 20671, 20653, 20635, 20619, 20604, 20590, 20577, 20565, 20554, 20543, 20534, 20525, 20517, + 20509, 20502, 20496, 20491, 20486, 20481, 20477, 20474, 20471, 20469, 20467, 20465, 20464, 20464, + 20463, 20463, 20463, 20464, 20465, 20466, 20467, 20468, 20470, 20472, 20474, 20476, 20478, 20480, + 20482, 20485, 20487, 20489, 20491, 20494, 20496, 20498, 20500, 20502, 20504, 20505, 20507, 20508, + 20510, 20511, 20512, 20513, 20514, 20515, 20516, 20516, 20517, 20517, 20518, 20518, 20519, 20519, + 20519, 20520, 20521, 20521, 20522, 20523, 20524, 20526, 20527, 20529, 20531, 20533, 20536, 20539, + 20542, 20546, 20549, 20554, 20558, 20563, 20568, 20573, 20579, 20586, 20592, 20599, 20606, 20613, + 20621, 20629, 20637, 20646, 20655, 20663, 20672, 20682, 20691, 20700, 20710, 20720, -20729, -20739, + -20748, -20758, -20767, -20776, -20785, -20794, -20803, -20812, -20820, -20828, -20836, -20843, -20851, -20857, + -20864, -20870, -20876, -20882, -20887, -20892, -20896, -20901, -20905, -20908, -20911, -20914, -20917, -20919, + -20921, -20923, -20925, -20926, -20927, -20928, -20929, -20930, -20931, -20931, -20932, -20932, -20933, -20933, + -20934, -20934, -20935, -20935, -20936, -20937, -20938, -20939, -20940, -20941, -20943, -20944, -20946, -20947, + -20949, -20951, -20953, -20955, -20958, -20960, -20962, -20964, -20967, -20969, -20971, -20974, -20976, -20978, + -20980, -20982, -20983, -20985, -20986, -20987, -20988, -20989, -20989, -20989, -20988, -20988, -20986, -20985, + -20983, -20980, -20978, -20974, -20970, -20966, -20961, -20955, -20949, -20942, -20934, -20926, -20917, -20907, + -20896, -20885, -20873, -20859, -20845, -20830, -20814, -20796, -20778, -20758, -20737, -20714, -20690, -20665, + -20638, -20610, -20580, -20548, -20515, -20480, -20433, -20384, -20333, -20279, -20220, -20155, -20085, -20008, + -19924, -19833, -19734, -19627, -19511, -19385, -19249, -19103, -18946, -18778, -18598, -18406, -18202, -17986, + -17757, -17515, -17260, -16993, -16713, -16421, -16116, -15799, -15470, -15129, -14778, -14415, -14043, -13661, + -13271, -12872, -12466, -12053, -11634, -11210, -10782, -10351, -9918, -9484, -9049, -8616, -8184, -7755, + -7330, -6910, -6496, -6090, -5691, -5301, -4922, -4553, -4196, -3852, -3521, -3204, -2902, -2615, + -2343, -2087, -1847, -1624, -1417, -1226, -1051, -892, -748, -619, -504, -404, -316, -241, + -175, -92}; +#else +#define LowDelayShapes_n960_N320 NULL +#endif + +#ifdef SUBSET_FB +RAM_ALIGN const Word16 LowDelayShapes_n960_N480[780] = { + -4, -8, -11, -13, -16, -20, -24, -28, -33, -38, -44, -50, -57, -64, + -72, -81, -90, -100, -110, -121, -133, -146, -159, -173, -187, -202, -218, -235, + -252, -270, -289, -308, -328, -349, -370, -392, -415, -438, -462, -486, -511, -537, + -563, -589, -616, -643, -671, -699, -728, -757, -786, -815, -845, -875, -905, -935, + -965, -996, -1026, -1056, -1087, -1117, -1147, -1177, -1207, -1236, -1266, -1295, -1323, -1352, + -1380, -1407, -1434, -1461, -1486, -1512, -1537, -1561, -1584, -1607, -1629, -1650, -1670, -1690, + -1709, -1726, -1743, -1759, -1774, -1788, -1801, -1813, -1824, -1834, -1842, -1850, -1856, -1861, + -1865, -1868, -1870, -1870, -1869, -1867, -1863, -1858, -1852, -1845, -1836, -1826, -1814, -1801, + -1786, -1770, -1753, -1734, -1713, -1691, -1668, -1643, -1616, -1588, -1558, -1527, -1494, -1459, + -1422, -1384, -1344, -1302, -1259, -1213, -1166, -1117, -1066, -1013, -959, -902, -843, -783, + -720, -655, -588, -519, -448, -374, -299, -221, -141, -58, 27, 114, 203, 295, + 389, 486, 585, 687, 791, 898, 1007, 1119, 1234, 1351, 1471, 1593, 1718, 1846, + 1976, 2109, 2244, 2382, 2523, 2667, 2813, 2961, 3113, 3266, 3423, 3582, 3743, 3907, + 4073, 4241, 4412, 4585, 4760, 4938, 5117, 5299, 5483, 5668, 5855, 6045, 6235, 6428, + 6622, 6817, 7013, 7211, 7410, 7610, 7811, 8012, 8215, 8417, 8621, 8824, 9028, 9232, + 9436, 9639, 9843, 10045, 10248, 10449, 10650, 10850, 11048, 11246, 11442, 11636, 11829, 12020, + 12209, 12396, 12581, 12763, 12944, 13121, 13296, 13468, 13638, 13804, 13967, 14127, 14284, 14437, + 14586, 14732, 14875, 15014, 15148, 15280, 15407, 15530, 15649, 15764, 15875, 15981, 16084, 16183, + 16277, 16367, 16453, 16535, 16612, 16686, 16755, 16821, 16882, 16940, 16993, 17043, 17089, 17131, + 17170, 17205, 17237, 17265, 17291, 17313, 17331, 17348, 17361, 17371, 17379, 17385, 17388, 17389, + 17388, 17385, 17380, 17374, 17366, 17356, 17345, 17333, 17320, 17306, 17292, 17276, 17260, 17243, + 17226, 17209, 17191, 17174, 17157, 17142, 17128, 17108, 17089, 17071, 17053, 17036, 17019, 17003, + 16988, 16973, 16959, 16946, 16933, 16920, 16908, 16897, 16886, 16875, 16865, 16856, 16846, 16838, + 16829, 16821, 16814, 16806, 16799, 16793, 16786, 16780, 16775, 16769, 16764, 16759, 16755, 16751, + 16747, 16743, 16739, 16736, 16733, 16730, 16727, 16725, 16722, 16720, 16718, 16717, 16715, 16714, + 16712, 16711, 16711, 16710, 16709, 16709, 16708, 16708, 16708, 16708, 16708, 16708, 16709, 16709, + 16710, 16710, 16711, 16712, 16713, 16714, 16715, 16716, 16717, 16718, 16719, 16720, 16721, 16722, + 16724, 16725, 16726, 16727, 16728, 16730, 16731, 16732, 16733, 16734, 16736, 16737, 16738, 16739, + 16740, 16741, 16742, 16743, 16744, 16744, 16745, 16746, 16747, 16747, 16748, 16748, 16749, 16750, + 16750, 16750, 16751, 16751, 16751, 16752, 16752, 16752, 16753, 16753, 16753, 16753, 16753, 16754, + 16754, 16754, 16755, 16755, 16755, 16756, 16756, 16757, 16757, 16758, 16759, 16759, 16760, 16761, + 16762, 16763, 16765, 16766, 16767, 16769, 16770, 16772, 16774, 16776, 16778, 16780, 16782, 16785, + 16787, 16790, 16793, 16796, 16799, 16802, 16805, 16809, 16812, 16816, 16820, 16824, 16828, 16832, + 16836, 16840, 16845, 16849, 16854, 16858, 16863, 16868, 16873, 16878, 16883, 16888, 16893, 16898, + 16903, 16908, 16914, 16919, -16924, -16929, -16934, -16940, -16945, -16950, -16955, -16960, -16965, -16970, + -16975, -16980, -16984, -16989, -16994, -16998, -17003, -17007, -17011, -17015, -17020, -17023, -17027, -17031, + -17035, -17038, -17041, -17045, -17048, -17051, -17053, -17056, -17059, -17061, -17064, -17066, -17068, -17070, + -17072, -17074, -17075, -17077, -17078, -17080, -17081, -17082, -17083, -17084, -17085, -17086, -17086, -17087, + -17088, -17088, -17089, -17089, -17089, -17090, -17090, -17090, -17091, -17091, -17091, -17091, -17092, -17092, + -17092, -17092, -17093, -17093, -17093, -17094, -17094, -17094, -17095, -17095, -17096, -17097, -17097, -17098, + -17099, -17099, -17100, -17101, -17102, -17103, -17104, -17105, -17106, -17107, -17108, -17109, -17110, -17111, + -17113, -17114, -17115, -17116, -17118, -17119, -17120, -17121, -17123, -17124, -17125, -17126, -17127, -17129, + -17130, -17131, -17132, -17133, -17133, -17134, -17135, -17136, -17136, -17137, -17137, -17137, -17137, -17137, + -17137, -17137, -17137, -17136, -17136, -17135, -17134, -17133, -17132, -17130, -17129, -17127, -17125, -17123, + -17120, -17118, -17115, -17112, -17109, -17105, -17102, -17098, -17094, -17089, -17085, -17080, -17075, -17069, + -17063, -17057, -17051, -17044, -17037, -17030, -17022, -17014, -17005, -16997, -16987, -16978, -16967, -16957, + -16946, -16934, -16922, -16910, -16897, -16883, -16869, -16855, -16840, -16824, -16808, -16791, -16773, -16755, + -16736, -16717, -16690, -16663, -16637, -16609, -16581, -16550, -16518, -16484, -16448, -16409, -16369, -16326, + -16280, -16232, -16181, -16127, -16070, -16010, -15947, -15880, -15810, -15736, -15658, -15577, -15491, -15402, + -15308, -15210, -15108, -15001, -14890, -14775, -14655, -14530, -14401, -14267, -14128, -13985, -13837, -13685, + -13528, -13367, -13201, -13030, -12855, -12676, -12493, -12306, -12114, -11919, -11720, -11517, -11311, -11102, + -10889, -10674, -10455, -10234, -10010, -9784, -9556, -9327, -9095, -8862, -8628, -8393, -8157, -7921, + -7684, -7448, -7211, -6976, -6741, -6507, -6274, -6042, -5813, -5585, -5360, -5137, -4917, -4700, + -4487, -4276, -4070, -3867, -3668, -3474, -3284, -3099, -2919, -2744, -2574, -2410, -2251, -2097, + -1949, -1807, -1671, -1540, -1415, -1297, -1184, -1077, -976, -881, -791, -707, -629, -556, + -489, -427, -369, -317, -269, -226, -188, -151, -114, -59}; +#else +#define LowDelayShapes_n960_N480 NULL +#endif + +#ifdef SUBSET_NB +RAM_ALIGN const Word16 LowDelayShapes_n960_N40_5ms[70] = { + 29, 112, 280, 563, 991, 1590, 2380, 3377, 4587, 6006, 7624, 9416, 11353, 13393, + 15490, 17595, 19657, 21624, 23450, 25092, 26519, 27707, 28645, 29332, 29783, 30021, 30083, 30008, + 29840, 29625, 29408, 29214, 29077, 28993, 28956, 28961, 29000, 29068, 29156, 29256, -29361, -29462, + -29551, -29620, -29661, -29666, -29628, -29542, -29403, -29209, -28923, -28521, -27962, -27210, -26234, -25014, + -23541, -21819, -19874, -17743, -15481, -13149, -10820, -8571, -6479, -4611, -3020, -1753, -842, -284}; +#else +#define LowDelayShapes_n960_N40_5ms NULL +#endif + +#ifdef SUBSET_WB +RAM_ALIGN const Word16 LowDelayShapes_n960_N80_5ms[140] = { + 13, 31, 60, 102, 161, 239, 339, 464, 615, 795, 1006, 1251, 1530, 1845, + 2198, 2588, 3015, 3481, 3983, 4520, 5092, 5697, 6331, 6992, 7677, 8382, 9104, 9838, + 10580, 11326, 12071, 12811, 13540, 14255, 14951, 15624, 16270, 16885, 17466, 18010, 18515, 18978, + 19399, 19775, 20106, 20393, 20636, 20836, 20995, 21115, 21199, 21250, 21271, 21266, 21239, 21194, + 21134, 21064, 20987, 20908, 20836, 20757, 20688, 20630, 20581, 20542, 20513, 20491, 20478, 20473, + 20475, 20483, 20497, 20517, 20541, 20568, 20600, 20633, 20669, 20706, -20743, -20780, -20816, -20850, + -20881, -20910, -20934, -20954, -20968, -20977, -20979, -20973, -20960, -20938, -20908, -20868, -20819, -20761, + -20692, -20613, -20508, -20389, -20248, -20080, -19883, -19653, -19387, -19083, -18738, -18351, -17920, -17444, + -16923, -16358, -15749, -15099, -14410, -13687, -12933, -12154, -11353, -10537, -9712, -8884, -8060, -7246, + -6450, -5679, -4938, -4235, -3574, -2959, -2397, -1889, -1441, -1055, -732, -474, -277, -138}; +#else +#define LowDelayShapes_n960_N80_5ms NULL +#endif + +#ifdef SUBSET_SSWB +RAM_ALIGN const Word16 LowDelayShapes_n960_N120_5ms[210] = { + 9, 17, 28, 44, 65, 91, 123, 161, 208, 262, 325, 398, 480, 572, + 676, 791, 918, 1057, 1209, 1374, 1552, 1744, 1950, 2169, 2402, 2648, 2908, 3181, + 3468, 3767, 4078, 4402, 4736, 5081, 5437, 5801, 6174, 6554, 6942, 7335, 7732, 8134, + 8538, 8943, 9349, 9755, 10159, 10560, 10957, 11349, 11735, 12114, 12485, 12846, 13198, 13539, + 13868, 14184, 14487, 14776, 15051, 15311, 15555, 15784, 15997, 16194, 16374, 16538, 16686, 16818, + 16935, 17036, 17123, 17195, 17254, 17299, 17333, 17355, 17366, 17368, 17361, 17347, 17325, 17297, + 17265, 17228, 17189, 17147, 17104, 17061, 17024, 16979, 16938, 16901, 16867, 16837, 16811, 16788, + 16768, 16752, 16739, 16729, 16722, 16718, 16716, 16717, 16720, 16726, 16734, 16743, 16755, 16768, + 16782, 16798, 16815, 16833, 16852, 16871, 16891, 16911, -16931, -16952, -16972, -16991, -17010, -17028, + -17045, -17061, -17076, -17090, -17101, -17111, -17119, -17125, -17128, -17129, -17127, -17123, -17116, -17106, + -17092, -17076, -17056, -17033, -17006, -16976, -16942, -16905, -16864, -16820, -16760, -16698, -16630, -16553, + -16467, -16370, -16263, -16144, -16013, -15868, -15710, -15537, -15349, -15146, -14927, -14693, -14442, -14175, + -13891, -13591, -13276, -12944, -12597, -12236, -11862, -11474, -11074, -10664, -10244, -9816, -9380, -8938, + -8492, -8043, -7592, -7141, -6692, -6247, -5807, -5374, -4949, -4534, -4131, -3741, -3365, -3005, + -2662, -2337, -2030, -1744, -1478, -1234, -1012, -814, -638, -486, -357, -250, -164, -95}; +#else +#define LowDelayShapes_n960_N120_5ms NULL +#endif + +#ifdef SUBSET_SWB +RAM_ALIGN const Word16 LowDelayShapes_n960_N160_5ms[280] = { + 13, 23, 36, 52, 73, 98, 128, 163, 205, 253, 308, 371, 441, 520, + 608, 705, 812, 929, 1056, 1195, 1344, 1505, 1678, 1863, 2060, 2270, 2493, 2729, + 2978, 3241, 3516, 3805, 4108, 4424, 4753, 5095, 5450, 5818, 6198, 6591, 6995, 7411, + 7839, 8277, 8725, 9184, 9651, 10128, 10612, 11104, 11603, 12108, 12618, 13133, 13653, 14175, + 14700, 15226, 15754, 16281, 16808, 17334, 17857, 18376, 18892, 19403, 19909, 20408, 20901, 21385, + 21861, 22328, 22784, 23231, 23666, 24089, 24500, 24898, 25283, 25654, 26011, 26354, 26681, 26994, + 27291, 27572, 27838, 28089, 28323, 28541, 28744, 28931, 29103, 29259, 29401, 29528, 29640, 29738, + 29823, 29895, 29955, 30002, 30038, 30063, 30078, 30083, 30080, 30068, 30049, 30023, 29991, 29953, + 29911, 29865, 29815, 29763, 29708, 29653, 29597, 29541, 29496, 29437, 29381, 29329, 29280, 29235, + 29194, 29156, 29122, 29091, 29064, 29039, 29018, 29000, 28986, 28974, 28964, 28958, 28954, 28953, + 28954, 28958, 28964, 28972, 28982, 28994, 29007, 29023, 29040, 29058, 29078, 29099, 29121, 29144, + 29168, 29192, 29218, 29243, 29269, 29295, -29322, -29348, -29374, -29400, -29425, -29450, -29474, -29498, + -29520, -29541, -29561, -29580, -29597, -29613, -29627, -29639, -29649, -29657, -29663, -29667, -29668, -29667, + -29663, -29657, -29647, -29635, -29620, -29602, -29580, -29556, -29528, -29496, -29462, -29424, -29382, -29337, + -29288, -29236, -29181, -29122, -29041, -28964, -28880, -28788, -28688, -28579, -28460, -28332, -28193, -28042, + -27879, -27705, -27517, -27315, -27100, -26871, -26627, -26369, -26095, -25806, -25501, -25180, -24844, -24492, + -24123, -23739, -23339, -22924, -22493, -22048, -21588, -21114, -20627, -20128, -19616, -19094, -18561, -18018, + -17467, -16907, -16341, -15769, -15192, -14611, -14028, -13442, -12857, -12272, -11689, -11109, -10533, -9963, + -9400, -8846, -8300, -7765, -7241, -6730, -6232, -5749, -5282, -4830, -4396, -3979, -3581, -3202, + -2843, -2505, -2188, -1893, -1620, -1369, -1141, -936, -753, -593, -454, -336, -237, -155}; +#else +#define LowDelayShapes_n960_N160_5ms NULL +#endif + +#ifdef SUBSET_FB +RAM_ALIGN const Word16 LowDelayShapes_n960_N240_5ms[420] = { + 10, 15, 21, 27, 36, 45, 56, 69, 83, 100, 118, 138, 161, 186, + 214, 244, 276, 312, 350, 392, 436, 484, 535, 590, 648, 710, 775, 845, + 918, 995, 1076, 1162, 1252, 1346, 1444, 1547, 1655, 1767, 1883, 2005, 2131, 2261, + 2397, 2537, 2683, 2833, 2988, 3148, 3312, 3482, 3656, 3835, 4019, 4208, 4401, 4599, + 4801, 5008, 5220, 5436, 5656, 5880, 6109, 6342, 6578, 6818, 7063, 7310, 7562, 7816, + 8074, 8335, 8598, 8865, 9134, 9405, 9679, 9955, 10233, 10513, 10794, 11076, 11360, 11645, + 11931, 12217, 12504, 12791, 13078, 13366, 13652, 13939, 14224, 14509, 14792, 15075, 15356, 15635, + 15912, 16187, 16460, 16731, 16999, 17264, 17526, 17785, 18041, 18293, 18542, 18787, 19028, 19264, + 19497, 19725, 19949, 20168, 20382, 20592, 20796, 20996, 21190, 21379, 21563, 21741, 21914, 22082, + 22243, 22399, 22550, 22695, 22834, 22967, 23095, 23216, 23332, 23443, 23548, 23647, 23740, 23828, + 23910, 23987, 24059, 24125, 24186, 24243, 24294, 24340, 24381, 24418, 24450, 24478, 24502, 24522, + 24537, 24549, 24557, 24562, 24563, 24561, 24556, 24549, 24538, 24525, 24510, 24492, 24473, 24451, + 24428, 24404, 24378, 24351, 24323, 24294, 24264, 24234, 24204, 24173, 24143, 24112, 24093, 24059, + 24027, 23997, 23968, 23940, 23914, 23889, 23865, 23842, 23821, 23801, 23783, 23765, 23749, 23734, + 23720, 23708, 23696, 23686, 23677, 23668, 23661, 23655, 23650, 23647, 23644, 23641, 23640, 23640, + 23641, 23642, 23645, 23648, 23652, 23657, 23662, 23668, 23675, 23682, 23691, 23699, 23708, 23718, + 23728, 23739, 23750, 23762, 23774, 23786, 23799, 23812, 23825, 23839, 23853, 23866, 23881, 23895, + 23909, 23923, -23938, -23952, -23966, -23980, -23994, -24008, -24022, -24036, -24049, -24062, -24075, -24088, + -24100, -24112, -24123, -24134, -24144, -24154, -24164, -24173, -24181, -24189, -24195, -24202, -24207, -24212, + -24216, -24219, -24222, -24223, -24224, -24224, -24223, -24221, -24218, -24214, -24208, -24202, -24195, -24187, + -24177, -24167, -24155, -24142, -24128, -24113, -24097, -24079, -24060, -24040, -24019, -23996, -23972, -23947, + -23921, -23893, -23864, -23834, -23802, -23769, -23721, -23681, -23638, -23592, -23543, -23492, -23438, -23380, + -23319, -23255, -23186, -23115, -23039, -22959, -22875, -22786, -22693, -22596, -22494, -22387, -22275, -22157, + -22035, -21908, -21775, -21637, -21494, -21345, -21190, -21030, -20864, -20692, -20515, -20332, -20143, -19948, + -19748, -19541, -19329, -19112, -18888, -18659, -18425, -18185, -17940, -17690, -17434, -17174, -16909, -16639, + -16365, -16087, -15804, -15518, -15228, -14934, -14637, -14337, -14034, -13728, -13420, -13109, -12797, -12483, + -12167, -11851, -11533, -11215, -10896, -10577, -10258, -9940, -9623, -9307, -8992, -8678, -8367, -8058, + -7752, -7448, -7148, -6851, -6557, -6268, -5983, -5702, -5426, -5156, -4890, -4630, -4375, -4126, + -3884, -3647, -3417, -3194, -2977, -2767, -2565, -2369, -2181, -2001, -1829, -1664, -1507, -1358, + -1218, -1085, -961, -846, -738, -639, -547, -464, -388, -320, -259, -206, -159, -124}; +#else +#define LowDelayShapes_n960_N240_5ms NULL +#endif + +#ifdef SUBSET_NB +RAM_ALIGN const Word16 LowDelayShapes_n960_N40_2_5ms[40] = { + 140, 566, 1277, 2319, 3704, 5404, 7357, 9466, 11616, 13686, 15563, 17163, 18436, 19375, + 20007, 20391, 20594, 20685, 20717, 20724, -20724, -20717, -20685, -20594, -20391, -20007, -19375, -18436, + -17163, -15563, -13686, -11616, -9466, -7357, -5404, -3704, -2319, -1277, -566, -140}; +#else +#define LowDelayShapes_n960_N40_2_5ms NULL +#endif + +#ifdef SUBSET_WB +RAM_ALIGN const Word16 LowDelayShapes_n960_N80_2_5ms[80] = { + 140, 353, 653, 1049, 1553, 2171, 2909, 3768, 4747, 5842, 7043, 8341, 9721, 11165, + 12655, 14170, 15688, 17188, 18649, 20051, 21376, 22610, 23739, 24756, 25656, 26436, 27099, 27650, + 28097, 28450, 28721, 28922, 29065, 29164, 29228, 29267, 29290, 29301, 29306, 29308, -29308, -29306, + -29301, -29290, -29267, -29228, -29164, -29065, -28922, -28721, -28450, -28097, -27650, -27099, -26436, -25656, + -24756, -23739, -22610, -21376, -20051, -18649, -17188, -15688, -14170, -12655, -11165, -9721, -8341, -7043, + -5842, -4747, -3768, -2909, -2171, -1553, -1049, -653, -353, -140}; +#else +#define LowDelayShapes_n960_N80_2_5ms NULL +#endif + +#ifdef SUBSET_SSWB +RAM_ALIGN const Word16 LowDelayShapes_n960_N120_2_5ms[120] = { + 93, 196, 328, 491, 689, 924, 1199, 1514, 1873, 2274, 2720, 3209, 3742, 4318, + 4934, 5588, 6277, 7000, 7750, 8526, 9321, 10132, 10953, 11780, 12606, 13427, 14237, 15032, + 15807, 16557, 17278, 17967, 18620, 19234, 19809, 20341, 20830, 21276, 21680, 22040, 22360, 22641, + 22884, 23092, 23269, 23416, 23538, 23636, 23714, 23775, 23822, 23857, 23882, 23900, 23913, 23920, + 23925, 23928, 23930, 23930, -23930, -23930, -23928, -23925, -23920, -23913, -23900, -23882, -23857, -23822, + -23775, -23714, -23636, -23538, -23416, -23269, -23092, -22884, -22641, -22360, -22040, -21680, -21276, -20830, + -20341, -19809, -19234, -18620, -17967, -17278, -16557, -15807, -15032, -14237, -13427, -12606, -11780, -10953, + -10132, -9321, -8526, -7750, -7000, -6277, -5588, -4934, -4318, -3742, -3209, -2720, -2274, -1873, + -1514, -1199, -924, -689, -491, -328, -196, -93}; +#else +#define LowDelayShapes_n960_N120_2_5ms NULL +#endif + +#ifdef SUBSET_SWB +RAM_ALIGN const Word16 LowDelayShapes_n960_N160_2_5ms[160] = { + 70, 134, 210, 301, 407, 530, 671, 830, 1008, 1206, 1425, 1665, 1926, 2208, + 2512, 2837, 3183, 3550, 3937, 4343, 4768, 5211, 5670, 6143, 6631, 7131, 7642, 8161, + 8688, 9219, 9755, 10292, 10828, 11363, 11893, 12417, 12933, 13440, 13936, 14418, 14887, 15339, + 15775, 16193, 16593, 16972, 17332, 17670, 17988, 18285, 18561, 18816, 19050, 19264, 19459, 19635, + 19793, 19934, 20059, 20168, 20264, 20347, 20418, 20478, 20529, 20572, 20606, 20635, 20657, 20675, + 20689, 20700, 20708, 20713, 20718, 20720, 20722, 20723, 20724, 20724, -20724, -20724, -20723, -20722, + -20720, -20718, -20713, -20708, -20700, -20689, -20675, -20657, -20635, -20606, -20572, -20529, -20478, -20418, + -20347, -20264, -20168, -20059, -19934, -19793, -19635, -19459, -19264, -19050, -18816, -18561, -18285, -17988, + -17670, -17332, -16972, -16593, -16193, -15775, -15339, -14887, -14418, -13936, -13440, -12933, -12417, -11893, + -11363, -10828, -10292, -9755, -9219, -8688, -8161, -7642, -7131, -6631, -6143, -5670, -5211, -4768, + -4343, -3937, -3550, -3183, -2837, -2512, -2208, -1926, -1665, -1425, -1206, -1008, -830, -671, + -530, -407, -301, -210, -134, -70}; +#else +#define LowDelayShapes_n960_N160_2_5ms NULL +#endif + +#ifdef SUBSET_FB +RAM_ALIGN const Word16 LowDelayShapes_n960_N240_2_5ms[240] = { + 47, 81, 118, 160, 207, 259, 317, 381, 452, 528, 611, 701, 799, 903, + 1015, 1134, 1260, 1395, 1537, 1686, 1844, 2009, 2183, 2363, 2552, 2748, 2951, 3162, + 3380, 3604, 3836, 4073, 4317, 4567, 4822, 5083, 5348, 5618, 5892, 6170, 6451, 6735, + 7022, 7311, 7601, 7892, 8185, 8477, 8769, 9060, 9350, 9639, 9926, 10209, 10491, 10768, + 11042, 11312, 11577, 11837, 12092, 12341, 12585, 12822, 13053, 13277, 13494, 13705, 13908, 14103, + 14291, 14472, 14645, 14810, 14968, 15118, 15261, 15396, 15523, 15643, 15756, 15862, 15961, 16054, + 16140, 16220, 16293, 16361, 16424, 16481, 16533, 16580, 16623, 16662, 16697, 16728, 16755, 16780, + 16802, 16821, 16837, 16851, 16864, 16874, 16883, 16891, 16897, 16902, 16907, 16910, 16913, 16915, + 16917, 16918, 16919, 16920, 16921, 16921, 16921, 16921, -16921, -16921, -16921, -16921, -16920, -16919, + -16918, -16917, -16915, -16913, -16910, -16907, -16902, -16897, -16891, -16883, -16874, -16864, -16851, -16837, + -16821, -16802, -16780, -16755, -16728, -16697, -16662, -16623, -16580, -16533, -16481, -16424, -16361, -16293, + -16220, -16140, -16054, -15961, -15862, -15756, -15643, -15523, -15396, -15261, -15118, -14968, -14810, -14645, + -14472, -14291, -14103, -13908, -13705, -13494, -13277, -13053, -12822, -12585, -12341, -12092, -11837, -11577, + -11312, -11042, -10768, -10491, -10209, -9926, -9639, -9350, -9060, -8769, -8477, -8185, -7892, -7601, + -7311, -7022, -6735, -6451, -6170, -5892, -5618, -5348, -5083, -4822, -4567, -4317, -4073, -3836, + -3604, -3380, -3162, -2951, -2748, -2552, -2363, -2183, -2009, -1844, -1686, -1537, -1395, -1260, + -1134, -1015, -903, -799, -701, -611, -528, -452, -381, -317, -259, -207, -160, -118, + -81, -47}; +#else +#define LowDelayShapes_n960_N240_2_5ms NULL +#endif + + +#ifdef SUBSET_NB +RAM_ALIGN const Word32 lag_win_8k[16] = {0x7fdba30b, 0x7f6eca1a, 0x7eba2e4e, 0x7dbf01e8, 0x7c7eecec, 0x7afc0879, + 0x7938d8eb, 0x773846e0, 0x74fd973a, 0x728c623e, 0x6fe889ee, 0x6d162fc8, + 0x6a19aa0b, 0x66f778a7, 0x63b43a09, 0x60549fe1}; +#else +#define lag_win_8k NULL +#endif + +#ifdef SUBSET_WB +RAM_ALIGN const Word32 lag_win_16k[16] = {0x7ff6e7cb, 0x7fdba30b, 0x7fae3d5f, 0x7f6eca1a, 0x7f1d643a, 0x7eba2e4e, + 0x7e455264, 0x7dbf01e8, 0x7d277581, 0x7c7eecec, 0x7bc5aecb, 0x7afc0879, + 0x7a224dcf, 0x7938d8eb, 0x784009f7, 0x773846e0}; +#else +#define lag_win_16k NULL +#endif + +#ifdef SUBSET_SSWB +RAM_ALIGN const Word32 lag_win_24k[16] = {0x7ffbf529, 0x7fefd569, 0x7fdba30b, 0x7fbf61e2, 0x7f9b1748, 0x7f6eca1a, + 0x7f3a82b8, 0x7efe4b00, 0x7eba2e4e, 0x7e6e3976, 0x7e1a7ac1, 0x7dbf01e8, + 0x7d5be00f, 0x7cf127c2, 0x7c7eecec, 0x7c0544d0}; +#else +#define lag_win_24k NULL +#endif + +#ifdef SUBSET_SWB +RAM_ALIGN const Word32 lag_win_32k[16] = {0x7ffdb9e3, 0x7ff6e7cb, 0x7feb8a70, 0x7fdba30b, 0x7fc7334b, 0x7fae3d5f, + 0x7f90c3ed, 0x7f6eca1a, 0x7f485382, 0x7f1d643a, 0x7eee00d1, 0x7eba2e4e, + 0x7e81f22e, 0x7e455264, 0x7e045558, 0x7dbf01e8}; +#else +#define lag_win_32k NULL +#endif + +#ifdef SUBSET_FB +RAM_ALIGN const Word32 lag_win_48k[16] = {0x7ffefd47, 0x7ffbf529, 0x7ff6e7cb, 0x7fefd569, 0x7fe6be59, 0x7fdba30b, + 0x7fce8403, 0x7fbf61e2, 0x7fae3d5f, 0x7f9b1748, 0x7f85f087, 0x7f6eca1a, + 0x7f55a51b, 0x7f3a82b8, 0x7f1d643a, 0x7efe4b00}; +#else +#define lag_win_48k NULL +#endif + +# ifdef ENABLE_HR_MODE +RAM_ALIGN const Word32 lag_win_96k[16] = {0x7fffbf52, 0x7ffefd47, 0x7ffdb9e3, 0x7ffbf529, 0x7ff9af1f, 0x7ff6e7cb, + 0x7ff39f35, 0x7fefd569, 0x7feb8a70, 0x7fe6be59, 0x7fe17132, 0x7fdba30b, + 0x7fd553f5, 0x7fce8403, 0x7fc7334b, 0x7fbf61e2}; +# else +# define lag_win_96k NULL +# endif + +RAM_ALIGN const Word32 *const lag_win[NUM_SAMP_FREQ] = {lag_win_8k, lag_win_16k, lag_win_24k, lag_win_32k, lag_win_48k, lag_win_96k}; + +RAM_ALIGN const Word16 sqrt_table_phecu[49] = {/* used by Sqrt_l */ + 16384, 16888, 17378, 17854, 18318, 18770, 19212, 19644, 20066, 20480, + 20886, 21283, 21674, 22058, 22435, 22806, 23170, 23530, 23884, 24232, + 24576, 24915, 25249, 25580, 25905, 26227, 26545, 26859, 27170, 27477, + 27780, 28081, 28378, 28672, 28963, 29251, 29537, 29819, 30099, 30377, + 30652, 30924, 31194, 31462, 31727, 31991, 32252, 32511, 32767}; + +/* First frequency bin in each subband now adjusted to include last bin * + * which was missed with the previous definition * + * 250 750 1250 2250 4250 8250 12250 16250 20250 ( 24250 ) * + * note that bins over 20000 are zeroed and not used */ +/* [- FB ----------------------------) (Currently limited to 20kHz) + * [- SWB -----------------------) + * [- sWB -------------------) + * [- WB ----------------) + * [- NB -----------) + */ + +RAM_ALIGN const Word16 gw_len_inv_shift_fx[MAX_LGW] = {/* Q0 */ + 1 - 1 /*/1/2*/, 1 - 1, 2 - 1 /*1/4*/, + 3 - 1 /*1/8*/, 4 - 1 /*1/16*/, 4 - 1, + 4 - 1, 4 - 1, 4 - 1}; +RAM_ALIGN const Word16 gwlpr_fx[MAX_LGW + 1] = { + 1, + 3 * QUOT_LPR_LTR, + 5 * QUOT_LPR_LTR, + 9 * QUOT_LPR_LTR, + 17 * QUOT_LPR_LTR, + 33 * QUOT_LPR_LTR, + 49 * QUOT_LPR_LTR, + 65 * QUOT_LPR_LTR, + 81 * QUOT_LPR_LTR, + 97 * QUOT_LPR_LTR}; /* frequency group start bins for transient analysis */ + +#ifdef CR8_A_PLC_FADEOUT_TUNING + /* puretone_ana compressed ATH bandborder weights */ +RAM_ALIGN const Word16 scATHFx[MAX_LGW - 2] = { 14924 , 30499 , 31886 , 32767 , 29770 , 25417 , 16384 }; + /* 0.455444335937500 0.930755615234375 0.973083496093750 0.999969482421875 0.908508300781250 0.775665283203125 0.5*/ +#endif + +RAM_ALIGN const Word16 e_tot_headroom[5] = {3, 3, 4, 4, 4}; /* smallest head room to use for each fs */ + + + +RAM_ALIGN const Word16 xfp_wE_MDCT2FFTQ11[5] = {4077, 8283, 12489, 16698, + 25109}; /* Q11 Mantissa of scale to use for each fs */ + +RAM_ALIGN const Word16 POW_ATT_TABLE0[OFF_FRAMES_LIMIT + 1] = { + 32767, 31293, 29885, 28540, 27255, 26029, 24857, 23738, 22670, 21650, 20675, 19745, 18856, 18007, 17197, 16423, + 8211, 4106, 2053, 1026, 513, 257, 128, 64, 32, 16, 8, 4, 2, 1, 0}; +RAM_ALIGN const Word16 POW_ATT_TABLE1[OFF_FRAMES_LIMIT + 1] = { + 32767, 31656, 30581, 29543, 28540, 27571, 26635, 25731, 24857, 24013, 23198, 22410, 21650, 20915, 20205, 19519, + 9759, 4880, 2440, 1220, 610, 305, 152, 76, 38, 19, 10, 5, 2, 1, 0}; + +#ifdef PLC2_FADEOUT_IN_MS +#if PLC2_FADEOUT_IN_MS == 0 +#ifndef CR8_A_PLC_FADEOUT_TUNING +/*/ default setting only requieres two tables */ +RAM_ALIGN 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 /* PLC2_FADEOUT_IN_MS == 0 */ + +#ifdef CR8_A_PLC_FADEOUT_TUNING +RAM_ALIGN const Word16 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 }; + +RAM_ALIGN const Word16 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 + +RAM_ALIGN const Word16 POW_ATT_TABLE_p3x8_6[OFF_FRAMES_LIMIT + 1] = { + 32767, 31656, 30581, 29543, 28540, 27571, 26635, 25731, 12865, 6433, 3216, 1608, 804, 402, 201, 101, + 50, 25, 13, 6, 3, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0}; +RAM_ALIGN const Word16 POW_ATT_TABLE_p4x8_6[OFF_FRAMES_LIMIT + 1] = { + 32767, 31293, 29885, 28540, 27255, 26029, 24857, 23738, 11869, 5935, 2967, 1484, 742, 371, 185, 93, + 46, 23, 12, 6, 3, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0}; + +RAM_ALIGN const Word16 POW_ATT_TABLE_p3x4_6[OFF_FRAMES_LIMIT + 1] = { + 32767, 31656, 30581, 29543, 14772, 7386, 3693, 1847, 923, 462, 231, 115, 58, 29, 14, 7, + 4, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; +RAM_ALIGN const Word16 POW_ATT_TABLE_p4x4_6[OFF_FRAMES_LIMIT + 1] = { + 32767, 31293, 29885, 28540, 14270, 7135, 3568, 1784, 892, 446, 223, 111, 56, 28, 14, 7, + 3, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + +RAM_ALIGN const Word16 POW_ATT_TABLE_p3x2_6[OFF_FRAMES_LIMIT + 1] = { + 32767, 31656, 15828, 7914, 3957, 1979, 989, 495, 247, 124, 62, 31, 15, 8, 4, 2, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; +RAM_ALIGN const Word16 POW_ATT_TABLE_p4x2_6[OFF_FRAMES_LIMIT + 1] = { + 32767, 31293, 15647, 7823, 3912, 1956, 978, 489, 244, 122, 61, 31, 15, 8, 4, 2, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + +RAM_ALIGN const Word16 POW_ATT_TABLE_p3x1_6[OFF_FRAMES_LIMIT + 1] = { + 32767, 16384, 8192, 4096, 2048, 1024, 512, 256, 128, 64, 32, 16, 8, 4, 2, 1, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; +RAM_ALIGN const Word16 POW_ATT_TABLE_p4x1_6[OFF_FRAMES_LIMIT + 1] = { + 32767, 16384, 8192, 4096, 2048, 1024, 512, 256, 128, 64, 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 +/* POW_ATT_TABLES now ordered logically based on initial slow muting phase time */ +/* POW_ATT_TABLES[ind] is used after teh initial gain==1.0 no energy muting phase */ +RAM_ALIGN const Word16 *const POW_ATT_TABLES[1 + 24 / 2] = +{ 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 */ /* 3GPP original/default curves */ +}; + +/* PLC_FADEOUT_TUNING, extended table nominal muting phases from 30 ms to 140 ms */ +RAM_ALIGN const Word16 fade_scheme_tab_fx[24 / 2][3] = { +/* burst_att_thresh indicates when muting POW_ATT_TABLE[att_per_frame_idx] should be used first time it is 1.0 though */ +/* burst_att_thresh ==2 --> gains [ 1.0, 32767/32768.0(first table value used) , first muted, .... ]*/ +/* burst_att_thresh ==5 --> gains [ 1.0, 1.0, 1,0 1,0, 32767/32768.0(first table value used) , first muted,... ]*/ +/* beta_mute_thr ==4 --> start of final attenuation attenuate AvgMix */ + +/* 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 */ +}; +/*fade_scheme_tab_fx[ind][0] att_per _fram_index , "points" to first column in POW_ATT TABLES */ +/*fade_scheme_tab_fx[ind][1] is burst_att_thresh, the number of non_muted 1.0 gain frames */ +/*fade_scheme_tab_fx[ind][2] is beta_mute_thr, the location of the start of final attenuation */ + +#else +RAM_ALIGN const Word16 *const POW_ATT_TABLES[1 + 10] = { + NULL, + POW_ATT_TABLE1, + POW_ATT_TABLE0, + /* .3dB x16,16 6dB steps */ /* .4dB x16, 16 6dB steps */ /*original/default */ + POW_ATT_TABLE_p3x8_6, + POW_ATT_TABLE_p4x8_6, + /* .3dB x8, 24 6dB steps */ /* .4dB x8, 24 6dB steps */ + POW_ATT_TABLE_p3x4_6, + POW_ATT_TABLE_p4x4_6, + /* .3dB x4, 28 6dB steps */ /* .4dB x4, 28 6dB steps */ + POW_ATT_TABLE_p3x2_6, + POW_ATT_TABLE_p4x2_6, + /* .3dB x2, 30 6dB steps */ /* .4dB x2, 30 6dB steps */ + POW_ATT_TABLE_p3x1_6, + POW_ATT_TABLE_p4x1_6 /* .3dB x1, 30 6dB steps */ /* .4dB x1, 30 6dB steps */ +}; +#endif + +#endif /* PLC2_FADEOUT_IN_MS == 0 */ + +#else /* PLC2_FADEOUT_IN_MS */ +RAM_ALIGN const Word16 *const POW_ATT_TABLES[1 + 2] = { + NULL, + POW_ATT_TABLE1 /*1 .3dB steps */, + POW_ATT_TABLE0 /*2 .4 dB steps*/, +}; +#endif /* PLC2_FADEOUT_IN_MS */ + +RAM_ALIGN const Word16 sin_quarterQ15_fx[256 + 1] = { + 0, 201, 402, 603, 804, 1005, 1206, 1407, 1608, 1809, 2009, 2210, 2411, 2611, 2811, 3012, + 3212, 3412, 3612, 3812, 4011, 4211, 4410, 4609, 4808, 5007, 5205, 5404, 5602, 5800, 5998, 6195, + 6393, 6590, 6787, 6983, 7180, 7376, 7571, 7767, 7962, 8157, 8351, 8546, 8740, 8933, 9127, 9319, + 9512, 9704, 9896, 10088, 10279, 10469, 10660, 10850, 11039, 11228, 11417, 11605, 11793, 11980, 12167, 12354, + 12540, 12725, 12910, 13095, 13279, 13463, 13646, 13828, 14010, 14192, 14373, 14553, 14733, 14912, 15091, 15269, + 15447, 15624, 15800, 15976, 16151, 16326, 16500, 16673, 16846, 17018, 17190, 17361, 17531, 17700, 17869, 18037, + 18205, 18372, 18538, 18703, 18868, 19032, 19195, 19358, 19520, 19681, 19841, 20001, 20160, 20318, 20475, 20632, + 20788, 20943, 21097, 21251, 21403, 21555, 21706, 21856, 22006, 22154, 22302, 22449, 22595, 22740, 22884, 23028, + 23170, 23312, 23453, 23593, 23732, 23870, 24008, 24144, 24279, 24414, 24548, 24680, 24812, 24943, 25073, 25202, + 25330, 25457, 25583, 25708, 25833, 25956, 26078, 26199, 26320, 26439, 26557, 26674, 26791, 26906, 27020, 27133, + 27246, 27357, 27467, 27576, 27684, 27791, 27897, 28002, 28106, 28209, 28311, 28411, 28511, 28610, 28707, 28803, + 28899, 28993, 29086, 29178, 29269, 29359, 29448, 29535, 29622, 29707, 29792, 29875, 29957, 30038, 30118, 30196, + 30274, 30350, 30425, 30499, 30572, 30644, 30715, 30784, 30853, 30920, 30986, 31050, 31114, 31177, 31238, 31298, + 31357, 31415, 31471, 31527, 31581, 31634, 31686, 31737, 31786, 31834, 31881, 31927, 31972, 32015, 32058, 32099, + 32138, 32177, 32214, 32251, 32286, 32319, 32352, 32383, 32413, 32442, 32470, 32496, 32522, 32546, 32568, 32590, + 32610, 32629, 32647, 32664, 32679, 32693, 32706, 32718, 32729, 32738, 32746, 32753, 32758, 32762, 32766, 32767, + 32767}; + +/* 16 ms tables for PHECU fft windowing and post ifft preTda MDCT windowing (window 11) */ +/* 3+3ms tapering for the hamming parts */ +/* temporary ROM solution */ +/* alternatively use values from a single 48 kHz table */ + +/* 3ms rising tapering part @48 kHZ */ +/* only quarter sine hamming part is actually used by the C-function windowing_fx */ +/* OPT: store only one table at 48 or 96 kHz */ +/* OPT2: for this to work one must switch to 'periodic' instead of used 'symetric' windows, * + * the different windows are just sub-sampled windows of a 96kHz window */ + +#ifdef SUBSET_NB +RAM_ALIGN const Word16 PhECU_whr16ms_NB_Q15[Lprot_hamm_len2_8k] = {/* From matlab */ + 2621, 2750, 3135, 3769, 4641, 5736, + 7036, 8519, 10158, 11926, 13793, 15727, + 17695, 19662, 21596, 23463, 25231, 26871, + 28353, 29653, 30749, 31621, 32254, 32639}; +#else +#define PhECU_whr16ms_NB_Q15 NULL +#endif +#ifdef SUBSET_WB +RAM_ALIGN const Word16 PhECU_whr16ms_WB_Q15[Lprot_hamm_len2_16k] = {/* From matlab */ + 2621, 2654, 2750, 2911, 3135, 3421, 3769, + 4176, 4641, 5162, 5736, 6362, 7036, 7756, + 8519, 9320, 10158, 11028, 11926, 12850, 13793, + 14754, 15727, 16709, 17695, 18681, 19662, 20635, + 21596, 22540, 23463, 24361, 25231, 26069, 26871, + 27633, 28353, 29027, 29653, 30228, 30749, 31214, + 31621, 31968, 32254, 32478, 32639, 32736}; +#else +#define PhECU_whr16ms_WB_Q15 NULL +#endif +#ifdef SUBSET_SSWB +RAM_ALIGN const Word16 PhECU_whr16ms_ssWB_Q15[Lprot_hamm_len2_24k] = + {/* From matlab */ + 2621, 2636, 2679, 2750, 2850, 2979, 3135, 3319, 3530, 3769, 4034, 4325, 4641, 4982, 5347, + 5736, 6148, 6582, 7036, 7511, 8006, 8519, 9049, 9596, 10158, 10735, 11324, 11926, 12539, 13162, + 13793, 14432, 15077, 15727, 16381, 17037, 17695, 18352, 19008, 19662, 20312, 20957, 21596, 22227, 22850, + 23463, 24065, 24655, 25231, 25794, 26340, 26871, 27384, 27878, 28353, 28808, 29242, 29653, 30042, 30407, + 30749, 31065, 31356, 31621, 31859, 32070, 32254, 32411, 32539, 32639, 32711, 32754}; +#else +#define PhECU_whr16ms_sWB_Q15 NULL +#endif +#ifdef SUBSET_SWB +RAM_ALIGN const Word16 PhECU_whr16ms_SWB_Q15[Lprot_hamm_len2_32k] = + {/* From matlab */ + 2621, 2630, 2654, 2694, 2750, 2823, 2911, 3015, 3135, 3270, 3421, 3588, 3769, 3965, 4176, 4401, + 4641, 4894, 5162, 5442, 5736, 6043, 6362, 6693, 7036, 7391, 7756, 8132, 8519, 8915, 9320, 9735, + 10158, 10589, 11028, 11474, 11926, 12385, 12850, 13319, 13793, 14272, 14754, 15239, 15727, 16217, 16709, 17202, + 17695, 18188, 18681, 19172, 19662, 20150, 20635, 21118, 21596, 22070, 22540, 23004, 23463, 23916, 24361, 24800, + 25231, 25654, 26069, 26475, 26871, 27257, 27633, 27999, 28353, 28696, 29027, 29347, 29653, 29947, 30228, 30495, + 30749, 30988, 31214, 31424, 31621, 31802, 31968, 32119, 32254, 32374, 32478, 32567, 32639, 32695, 32736, 32760}; +#else +#define PhECU_whr16ms_SWB_Q15 NULL +#endif +#ifdef SUBSET_FB +RAM_ALIGN const Word16 PhECU_whr16ms_FB_Q15[Lprot_hamm_len2_48k] = + {/* From matlab */ + 2621, 2625, 2636, 2654, 2679, 2711, 2750, 2797, 2850, 2911, 2979, 3053, 3135, 3224, 3319, 3421, + 3530, 3646, 3769, 3898, 4034, 4176, 4325, 4480, 4641, 4808, 4982, 5162, 5347, 5539, 5736, 5939, + 6148, 6362, 6582, 6806, 7036, 7271, 7511, 7756, 8006, 8260, 8519, 8782, 9049, 9320, 9596, 9875, + 10158, 10445, 10735, 11028, 11324, 11624, 11926, 12232, 12539, 12850, 13162, 13477, 13793, 14112, 14432, 14754, + 15077, 15402, 15727, 16054, 16381, 16709, 17037, 17366, 17695, 18024, 18352, 18681, 19008, 19336, 19662, 19988, + 20312, 20635, 20957, 21277, 21596, 21913, 22227, 22540, 22850, 23158, 23463, 23765, 24065, 24361, 24655, 24945, + 25231, 25514, 25794, 26069, 26340, 26608, 26871, 27129, 27384, 27633, 27878, 28118, 28353, 28583, 28808, 29027, + 29242, 29450, 29653, 29850, 30042, 30228, 30407, 30581, 30749, 30910, 31065, 31214, 31356, 31491, 31621, 31743, + 31859, 31968, 32070, 32166, 32254, 32336, 32411, 32478, 32539, 32593, 32639, 32678, 32711, 32736, 32754, 32764}; +#else +#define PhECU_whr16ms_FB_Q15 NULL +#endif + +/* initial 2ms for preTda is the LD-MDCT analysis window times the centered inverse whr window */ +#ifdef SUBSET_NB +RAM_ALIGN const Word16 PhECU_preTdaFx16ms_128_pre_Q14[16] = {-12, -34, -74, -135, -219, -327, -459, -610, + -776, -949, -1125, -1295, -1451, -1587, -1696, -1771}; +#else +#define PhECU_preTdaFx16ms_128_pre_Q14 NULL +#endif +#ifdef SUBSET_WB +RAM_ALIGN const Word16 PhECU_preTdaFx16ms_256_pre_Q14[32] = { + -8, -16, -27, -42, -63, -87, -117, -154, -196, -244, -299, -358, -424, -495, -570, -650, + -733, -818, -906, -993, -1082, -1168, -1253, -1336, -1414, -1488, -1556, -1617, -1671, -1718, -1755, -1784}; +#else +#define PhECU_preTdaFx16ms_256_pre_Q14 NULL +#endif +#ifdef SUBSET_SSWB +RAM_ALIGN const Word16 PhECU_preTdaFx16ms_384_pre_Q14[48] = { + -6, -12, -18, -25, -34, -45, -59, -74, -92, -112, -135, -160, -188, -219, -253, -289, + -328, -369, -413, -459, -507, -557, -610, -663, -719, -775, -833, -891, -950, -1008, -1067, -1125, + -1183, -1239, -1295, -1349, -1401, -1451, -1499, -1545, -1587, -1627, -1663, -1696, -1725, -1750, -1771, -1788}; +#else +#define PhECU_preTdaFx16ms_384_pre_Q14 NULL +#endif +#ifdef SUBSET_SWB +RAM_ALIGN const Word16 PhECU_preTdaFx16ms_512_pre_Q14[64] = { + -5, -9, -13, -18, -24, -31, -38, -47, -57, -68, -81, -94, -109, -126, -144, -164, + -185, -207, -232, -257, -284, -313, -343, -374, -407, -441, -477, -513, -551, -590, -630, -670, + -712, -754, -797, -840, -884, -927, -972, -1016, -1059, -1104, -1147, -1190, -1232, -1274, -1316, -1356, + -1395, -1433, -1470, -1505, -1539, -1572, -1602, -1632, -1659, -1684, -1707, -1728, -1747, -1763, -1777, -1789}; +#else +#define PhECU_preTdaFx16ms_512_pre_Q14 NULL +#endif +#ifdef SUBSET_FB +RAM_ALIGN const Word16 PhECU_preTdaFx16ms_768_pre_Q14[96] = { + -4, -8, -11, -13, -15, -19, -23, -27, -32, -37, -43, -48, -55, -62, -70, -78, + -87, -97, -107, -117, -129, -141, -154, -168, -181, -196, -211, -228, -244, -261, -280, -298, + -318, -338, -358, -380, -402, -424, -447, -471, -495, -520, -545, -570, -596, -623, -650, -677, + -705, -733, -761, -789, -818, -847, -876, -905, -934, -964, -993, -1022, -1052, -1082, -1111, -1140, + -1169, -1197, -1226, -1254, -1281, -1309, -1336, -1362, -1388, -1415, -1439, -1464, -1488, -1511, -1534, -1556, + -1577, -1598, -1617, -1636, -1655, -1671, -1688, -1703, -1718, -1731, -1744, -1755, -1766, -1776, -1784, -1791}; +#else +#define PhECU_preTdaFx16ms_768_pre_Q14 NULL +#endif + +/* ROM OPT compute it runtime based on MDCT win and tabled inverse hamming sections */ +/* 16 ms tables for PHECU fft windowing and post ifft preTda MDCT windowing */ +/* OPT2 can be reduced to 14.25 ms, due to 1.75 ms trailing zeroes */ +#ifdef SUBSET_NB +RAM_ALIGN const Word16 PhECU_preTdaFx16ms_NB_Q14[128] = { + -22591, -21465, -18295, -14331, -10544, -7321, -4690, -2561, -811, 662, 1942, 3090, 4148, 5146, 6107, 7043, + 7961, 8868, 9761, 10640, 11502, 12345, 13164, 13959, 14731, 15423, 15970, 16374, 16642, 16789, 16837, 16810, + 16735, 16637, 16537, 16441, 16366, 16307, 16263, 16230, 16206, 16190, 16181, 16177, 16178, 16182, 16188, 16196, + 16203, 16209, 16214, 16218, 16219, 16221, 16222, 16226, 16230, 16238, 16251, 16267, 16287, 16312, 16339, 16369, + 16399, 16429, 16456, 16481, 16502, 16518, 16531, 16539, 16544, 16547, 16548, 16550, 16552, 16556, 16561, 16567, + 16575, 16582, 16588, 16592, 16593, 16589, 16580, 16564, 16540, 16506, 16461, 16402, 16327, 16232, 16095, 15907, + 15641, 15272, 14775, 14130, 13325, 12361, 11251, 10017, 8694, 7354, 6057, 4825, 3684, 2665, 1795, 1095, + 575, 229, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; +#else +#define PhECU_preTdaFx16ms_NB_Q14 NULL +#endif +#ifdef SUBSET_WB +RAM_ALIGN const Word16 PhECU_preTdaFx16ms_WB_Q14[256] = { + -22528, -22351, -21532, -20186, -18475, -16565, -14596, -12673, -10858, -9181, -7654, -6277, -5037, -3923, -2914, + -2001, -1169, -405, 303, 961, 1580, 2166, 2725, 3263, 3781, 4285, 4778, 5262, 5739, 6211, + 6677, 7140, 7601, 8059, 8514, 8968, 9419, 9868, 10314, 10756, 11195, 11630, 12060, 12486, 12907, + 13322, 13733, 14137, 14537, 14917, 15263, 15573, 15847, 16085, 16286, 16454, 16587, 16689, 16763, 16810, + 16833, 16836, 16822, 16795, 16757, 16712, 16663, 16612, 16565, 16511, 16464, 16421, 16383, 16350, 16321, + 16295, 16272, 16253, 16237, 16223, 16211, 16201, 16194, 16187, 16183, 16180, 16178, 16177, 16178, 16179, + 16181, 16184, 16187, 16190, 16194, 16198, 16201, 16204, 16208, 16210, 16213, 16215, 16217, 16218, 16219, + 16220, 16221, 16222, 16222, 16223, 16225, 16227, 16229, 16232, 16236, 16241, 16247, 16255, 16262, 16272, + 16282, 16293, 16305, 16319, 16332, 16347, 16361, 16376, 16391, 16407, 16422, 16436, 16450, 16463, 16475, + 16487, 16497, 16506, 16514, 16522, 16528, 16533, 16537, 16541, 16543, 16545, 16546, 16547, 16548, 16549, + 16550, 16550, 16551, 16553, 16555, 16557, 16560, 16563, 16566, 16569, 16573, 16577, 16580, 16584, 16587, + 16589, 16592, 16593, 16593, 16593, 16591, 16588, 16583, 16577, 16569, 16559, 16547, 16532, 16516, 16496, + 16474, 16448, 16418, 16385, 16347, 16305, 16258, 16205, 16134, 16054, 15960, 15849, 15716, 15560, 15376, + 15161, 14913, 14628, 14306, 13944, 13541, 13098, 12616, 12097, 11540, 10952, 10335, 9692, 9030, 8362, + 7699, 7045, 6400, 5769, 5155, 4560, 3990, 3448, 2936, 2460, 2022, 1625, 1272, 963, 700, + 481, 306, 161, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0}; +#else +#define PhECU_preTdaFx16ms_WB_Q14 NULL +#endif +#ifdef SUBSET_SSWB +RAM_ALIGN const Word16 PhECU_preTdaFx16ms_ssWB_Q14[384] = { + -22499, -22471, -22152, -21551, -20715, -19688, -18527, -17277, -15982, -14679, -13393, -12145, -10954, -9826, + -8760, -7763, -6831, -5958, -5149, -4394, -3688, -3029, -2410, -1831, -1285, -769, -279, 186, + 630, 1055, 1462, 1856, 2236, 2606, 2966, 3317, 3662, 3999, 4330, 4658, 4981, 5301, + 5618, 5933, 6246, 6556, 6866, 7175, 7481, 7788, 8093, 8398, 8702, 9004, 9306, 9606, + 9906, 10205, 10502, 10798, 11092, 11385, 11676, 11965, 12252, 12537, 12820, 13101, 13379, 13655, + 13929, 14200, 14470, 14732, 14977, 15208, 15422, 15622, 15804, 15970, 16121, 16256, 16374, 16478, + 16567, 16643, 16703, 16753, 16789, 16815, 16830, 16837, 16835, 16825, 16810, 16789, 16764, 16735, + 16704, 16671, 16637, 16604, 16575, 16538, 16503, 16471, 16441, 16414, 16389, 16366, 16345, 16325, + 16307, 16291, 16276, 16263, 16250, 16239, 16230, 16221, 16213, 16206, 16200, 16195, 16190, 16187, + 16184, 16181, 16180, 16178, 16178, 16178, 16178, 16178, 16180, 16181, 16182, 16185, 16187, 16189, + 16191, 16193, 16195, 16198, 16200, 16202, 16205, 16207, 16208, 16211, 16213, 16214, 16215, 16217, + 16217, 16218, 16219, 16219, 16220, 16221, 16221, 16221, 16222, 16223, 16224, 16224, 16226, 16227, + 16228, 16230, 16233, 16236, 16239, 16242, 16246, 16251, 16256, 16261, 16267, 16274, 16280, 16288, + 16295, 16304, 16312, 16321, 16330, 16339, 16349, 16359, 16369, 16379, 16389, 16399, 16409, 16419, + 16429, 16439, 16447, 16456, 16465, 16473, 16481, 16489, 16495, 16502, 16508, 16513, 16519, 16523, + 16527, 16531, 16534, 16536, 16539, 16541, 16543, 16544, 16545, 16546, 16547, 16547, 16548, 16549, + 16549, 16549, 16550, 16551, 16551, 16552, 16554, 16554, 16556, 16558, 16559, 16561, 16563, 16565, + 16567, 16570, 16572, 16575, 16578, 16580, 16582, 16584, 16586, 16588, 16590, 16591, 16592, 16593, + 16593, 16593, 16593, 16591, 16589, 16587, 16584, 16580, 16575, 16570, 16564, 16557, 16549, 16540, + 16530, 16519, 16506, 16493, 16478, 16461, 16443, 16423, 16402, 16379, 16354, 16327, 16297, 16266, + 16232, 16195, 16147, 16096, 16039, 15977, 15907, 15828, 15740, 15642, 15531, 15409, 15273, 15122, + 14956, 14775, 14577, 14362, 14130, 13879, 13611, 13325, 13021, 12700, 12361, 12006, 11636, 11250, + 10851, 10440, 10016, 9583, 9142, 8698, 8255, 7815, 7377, 6944, 6515, 6092, 5675, 5266, + 4865, 4475, 4094, 3726, 3370, 3029, 2703, 2393, 2101, 1826, 1571, 1334, 1117, 921, + 744, 588, 451, 335, 235, 128, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0}; +#else +#define PhECU_preTdaFx16ms_sWB_Q14 NULL +#endif +#ifdef SUBSET_SWB +RAM_ALIGN const Word16 PhECU_preTdaFx16ms_SWB_Q14[512] = { + -22482, -22492, -22345, -22020, -21560, -20952, -20236, -19434, -18551, -17624, -16665, -15691, -14716, -13753, + -12810, -11889, -11002, -10152, -9335, -8553, -7813, -7108, -6442, -5806, -5206, -4634, -4091, -3574, + -3084, -2618, -2173, -1748, -1341, -952, -578, -219, 128, 462, 786, 1099, 1405, 1701, + 1989, 2271, 2548, 2818, 3084, 3345, 3601, 3856, 4106, 4354, 4598, 4840, 5082, 5322, + 5559, 5795, 6029, 6263, 6496, 6729, 6961, 7192, 7422, 7652, 7882, 8111, 8339, 8567, + 8795, 9022, 9249, 9475, 9701, 9926, 10151, 10374, 10597, 10819, 11041, 11261, 11481, 11699, + 11917, 12133, 12349, 12563, 12776, 12988, 13198, 13408, 13616, 13823, 14028, 14233, 14437, 14635, + 14826, 15007, 15181, 15344, 15499, 15645, 15782, 15910, 16029, 16139, 16239, 16332, 16415, 16490, + 16557, 16615, 16667, 16710, 16747, 16777, 16800, 16818, 16829, 16835, 16837, 16834, 16827, 16816, + 16803, 16786, 16767, 16746, 16724, 16700, 16675, 16649, 16624, 16601, 16580, 16551, 16524, 16499, + 16475, 16453, 16431, 16411, 16392, 16374, 16358, 16342, 16328, 16313, 16301, 16289, 16278, 16268, + 16258, 16249, 16241, 16234, 16226, 16220, 16214, 16208, 16204, 16200, 16196, 16192, 16188, 16186, + 16184, 16182, 16181, 16179, 16178, 16178, 16177, 16177, 16177, 16178, 16179, 16180, 16181, 16181, + 16183, 16185, 16186, 16188, 16189, 16191, 16192, 16195, 16196, 16198, 16200, 16202, 16204, 16205, + 16207, 16208, 16210, 16211, 16212, 16213, 16215, 16215, 16216, 16217, 16218, 16219, 16219, 16219, + 16220, 16220, 16221, 16221, 16222, 16222, 16222, 16222, 16223, 16223, 16224, 16225, 16226, 16227, + 16228, 16230, 16231, 16233, 16235, 16238, 16240, 16243, 16245, 16249, 16253, 16256, 16260, 16264, + 16269, 16275, 16279, 16285, 16290, 16296, 16302, 16309, 16315, 16322, 16329, 16336, 16343, 16351, + 16358, 16365, 16373, 16381, 16388, 16396, 16403, 16411, 16418, 16425, 16432, 16439, 16446, 16453, + 16460, 16466, 16472, 16478, 16484, 16489, 16494, 16499, 16504, 16509, 16513, 16517, 16520, 16524, + 16527, 16529, 16532, 16534, 16536, 16538, 16540, 16541, 16543, 16543, 16544, 16545, 16546, 16547, + 16547, 16547, 16548, 16548, 16549, 16549, 16550, 16550, 16551, 16551, 16551, 16552, 16553, 16554, + 16555, 16555, 16557, 16558, 16559, 16560, 16562, 16563, 16565, 16566, 16569, 16570, 16572, 16573, + 16576, 16577, 16579, 16581, 16583, 16585, 16586, 16588, 16589, 16590, 16591, 16592, 16592, 16593, + 16593, 16593, 16592, 16592, 16591, 16590, 16589, 16586, 16585, 16581, 16578, 16575, 16571, 16566, + 16562, 16556, 16550, 16543, 16536, 16528, 16520, 16511, 16502, 16490, 16479, 16468, 16455, 16441, + 16426, 16411, 16394, 16376, 16357, 16337, 16316, 16294, 16270, 16245, 16219, 16191, 16154, 16115, + 16075, 16032, 15985, 15934, 15879, 15818, 15751, 15679, 15601, 15517, 15425, 15325, 15218, 15102, + 14978, 14845, 14703, 14551, 14390, 14219, 14038, 13847, 13645, 13434, 13213, 12982, 12741, 12490, + 12230, 11961, 11683, 11396, 11102, 10800, 10492, 10176, 9855, 9529, 9197, 8864, 8532, 8201, + 7872, 7544, 7218, 6894, 6573, 6255, 5940, 5629, 5322, 5020, 4723, 4432, 4147, 3868, + 3596, 3332, 3076, 2828, 2590, 2361, 2141, 1931, 1732, 1543, 1366, 1200, 1044, 901, + 768, 647, 536, 438, 349, 271, 201, 108, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0}; +#else +#define PhECU_preTdaFx16ms_SWB_Q14 NULL +#endif +#ifdef SUBSET_FB +RAM_ALIGN const Word16 PhECU_preTdaFx16ms_FB_Q14[768] = { + -22463, -22493, -22449, -22334, -22148, -21885, -21560, -21179, -20737, -20250, -19726, -19171, -18581, -17972, + -17340, -16701, -16050, -15401, -14757, -14114, -13474, -12848, -12237, -11637, -11048, -10478, -9922, -9386, + -8864, -8357, -7865, -7393, -6936, -6493, -6069, -5654, -5258, -4874, -4503, -4144, -3801, -3465, + -3140, -2829, -2524, -2230, -1944, -1667, -1399, -1136, -884, -636, -395, -158, 72, 296, + 514, 728, 938, 1144, 1346, 1545, 1739, 1931, 2119, 2305, 2489, 2670, 2849, 3025, + 3199, 3373, 3543, 3713, 3879, 4046, 4211, 4376, 4539, 4700, 4862, 5022, 5182, 5341, + 5499, 5657, 5814, 5970, 6126, 6282, 6437, 6592, 6746, 6901, 7056, 7209, 7362, 7517, + 7669, 7823, 7976, 8129, 8281, 8433, 8585, 8738, 8890, 9040, 9193, 9343, 9495, 9645, + 9796, 9946, 10096, 10245, 10395, 10543, 10693, 10841, 10989, 11137, 11284, 11431, 11578, 11723, + 11869, 12014, 12159, 12303, 12446, 12589, 12733, 12874, 13016, 13157, 13298, 13438, 13577, 13716, + 13855, 13992, 14129, 14266, 14403, 14537, 14667, 14795, 14918, 15037, 15152, 15263, 15371, 15474, + 15573, 15669, 15760, 15847, 15931, 16010, 16084, 16156, 16223, 16287, 16346, 16402, 16453, 16502, + 16546, 16587, 16625, 16659, 16690, 16717, 16742, 16763, 16781, 16797, 16810, 16819, 16827, 16833, + 16836, 16837, 16836, 16833, 16828, 16822, 16815, 16805, 16794, 16783, 16770, 16756, 16743, 16727, + 16712, 16695, 16679, 16663, 16645, 16629, 16612, 16598, 16584, 16565, 16546, 16529, 16511, 16495, + 16479, 16463, 16449, 16434, 16420, 16408, 16395, 16383, 16371, 16360, 16350, 16339, 16329, 16321, + 16311, 16303, 16295, 16287, 16280, 16272, 16266, 16260, 16253, 16247, 16242, 16237, 16232, 16227, + 16223, 16219, 16215, 16211, 16207, 16205, 16202, 16199, 16196, 16194, 16191, 16189, 16187, 16186, + 16184, 16183, 16181, 16180, 16180, 16179, 16178, 16178, 16177, 16177, 16177, 16177, 16177, 16177, + 16178, 16178, 16179, 16179, 16180, 16181, 16182, 16183, 16184, 16185, 16186, 16187, 16188, 16189, + 16190, 16191, 16193, 16194, 16195, 16196, 16197, 16199, 16200, 16201, 16202, 16203, 16205, 16206, + 16206, 16207, 16208, 16209, 16210, 16211, 16212, 16212, 16213, 16214, 16215, 16215, 16216, 16216, + 16217, 16218, 16218, 16218, 16219, 16219, 16219, 16220, 16220, 16220, 16221, 16221, 16221, 16221, + 16221, 16222, 16222, 16222, 16223, 16223, 16223, 16224, 16224, 16225, 16225, 16226, 16227, 16227, + 16228, 16229, 16230, 16231, 16233, 16234, 16235, 16237, 16237, 16239, 16241, 16243, 16245, 16247, + 16249, 16252, 16254, 16257, 16260, 16263, 16266, 16268, 16271, 16275, 16278, 16282, 16286, 16290, + 16294, 16298, 16301, 16305, 16310, 16314, 16319, 16323, 16328, 16332, 16337, 16342, 16347, 16352, + 16357, 16361, 16366, 16371, 16377, 16382, 16387, 16391, 16396, 16402, 16407, 16412, 16417, 16421, + 16426, 16431, 16436, 16441, 16445, 16450, 16454, 16458, 16463, 16467, 16471, 16475, 16480, 16482, + 16486, 16490, 16494, 16497, 16500, 16504, 16507, 16510, 16511, 16514, 16517, 16519, 16522, 16524, + 16526, 16528, 16530, 16532, 16533, 16535, 16536, 16538, 16539, 16540, 16541, 16542, 16542, 16543, + 16543, 16544, 16545, 16545, 16546, 16546, 16546, 16547, 16547, 16547, 16548, 16548, 16548, 16548, + 16549, 16549, 16549, 16549, 16550, 16550, 16550, 16551, 16551, 16551, 16552, 16552, 16553, 16554, + 16554, 16555, 16556, 16556, 16557, 16558, 16559, 16560, 16561, 16562, 16563, 16564, 16565, 16566, + 16567, 16568, 16570, 16571, 16572, 16572, 16574, 16575, 16576, 16577, 16579, 16580, 16581, 16582, + 16583, 16585, 16586, 16587, 16588, 16589, 16589, 16590, 16591, 16592, 16592, 16593, 16593, 16593, + 16593, 16593, 16593, 16593, 16593, 16592, 16592, 16591, 16590, 16589, 16588, 16586, 16585, 16583, + 16581, 16579, 16576, 16574, 16572, 16569, 16566, 16562, 16559, 16555, 16551, 16546, 16542, 16538, + 16533, 16527, 16521, 16515, 16510, 16503, 16496, 16489, 16481, 16474, 16465, 16457, 16448, 16439, + 16428, 16419, 16408, 16396, 16385, 16373, 16360, 16347, 16333, 16320, 16305, 16290, 16274, 16258, + 16240, 16223, 16205, 16186, 16160, 16134, 16109, 16082, 16054, 16024, 15993, 15961, 15926, 15888, + 15849, 15808, 15763, 15717, 15667, 15615, 15560, 15502, 15441, 15376, 15308, 15236, 15161, 15082, + 14999, 14913, 14822, 14727, 14628, 14525, 14417, 14306, 14190, 14069, 13944, 13814, 13679, 13541, + 13398, 13250, 13098, 12943, 12782, 12616, 12447, 12273, 12096, 11915, 11729, 11541, 11348, 11151, + 10952, 10749, 10543, 10335, 10123, 9909, 9692, 9473, 9253, 9032, 8810, 8589, 8369, 8149, + 7929, 7711, 7492, 7276, 7059, 6845, 6631, 6418, 6207, 5997, 5789, 5582, 5378, 5175, + 4975, 4777, 4583, 4389, 4200, 4012, 3827, 3646, 3468, 3294, 3123, 2956, 2793, 2634, + 2479, 2328, 2181, 2039, 1902, 1768, 1639, 1517, 1398, 1284, 1176, 1072, 973, 879, + 791, 707, 629, 556, 486, 423, 364, 310, 261, 213, 163, 85, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; +#else +#define PhECU_preTdaFx16ms_FB_Q14 NULL +#endif + +RAM_ALIGN const Word16 *const PhECU_wins[5][3] = { + /* 3ms hamm(left part) , 16ms(center IWHR(periodic)*MDCT-anaQ14) , 2ms(initial MDCT-ana in Q14) */ + /*8 kHz*/ {PhECU_whr16ms_NB_Q15, PhECU_preTdaFx16ms_NB_Q14, PhECU_preTdaFx16ms_128_pre_Q14}, + /*16 kHz*/ {PhECU_whr16ms_WB_Q15, PhECU_preTdaFx16ms_WB_Q14, PhECU_preTdaFx16ms_256_pre_Q14}, + /*24 kHz*/ {PhECU_whr16ms_ssWB_Q15, PhECU_preTdaFx16ms_ssWB_Q14, PhECU_preTdaFx16ms_384_pre_Q14}, + /*32 kHz*/ {PhECU_whr16ms_SWB_Q15, PhECU_preTdaFx16ms_SWB_Q14, PhECU_preTdaFx16ms_512_pre_Q14}, + /*48 kHz*/ {PhECU_whr16ms_FB_Q15, PhECU_preTdaFx16ms_FB_Q14, PhECU_preTdaFx16ms_768_pre_Q14}}; + +/* x=(0:(5*8-1))*(2*pi)/32; y=sin(x);y_int=max(-32768,min(32767,round(y*32768))), y_int/32768 */ +/* 1.25 *2*pi table for low complex and low angle resolution rand_phase_fx */ +RAM_ALIGN const Word16 sincos_lowres_tab_sinQ15_fx[40] = { + 0, 6393, 12540, 18205, 23170, 27246, 30274, 32138, 32767, 32138, 30274, 27246, 23170, 18205, + 12540, 6393, 0, -6393, -12540, -18205, -23170, -27246, -30274, -32138, -32768, -32138, -30274, -27246, + -23170, -18205, -12540, -6393, 0, 6393, 12540, 18205, 23170, 27246, 30274, 32138}; + +/* (PHECU_LA_48K == 0) */ + +#ifdef SUBSET_NB +RAM_ALIGN const Word16 w_new_fs_8_LA_0[OLA_LEN_8K] = {0, 411, 1623, 3574, 6169, 9275, 12738, + 16384, 20030, 23493, 26599, 29194, 31145, 32357}; + + +RAM_ALIGN const Word16 w_old_fs_8_LA_0[OLA_LEN_8K] = { + + /* ( 32768-fliplr(w_new_fs_8_LA_0) ) *[whr3ms(0:13)*/ + 2621, 2721, 3001, 3401, 3836, 4205, 4411, 4377, 4063, 3475, 2673, 1766, 901, 253}; +#else +#define w_new_fs_8_LA_0 NULL +#define w_old_fs_8_LA_0 NULL +#endif /* SUBSET_NB */ + +#ifdef SUBSET_WB +RAM_ALIGN const Word16 w_new_fs_16_LA_0[OLA_LEN_16K] = { + 0, 103, 411, 919, 1623, 2511, 3574, 4799, 6169, 7667, 9275, 10973, 12738, 14550, + 16384, 18218, 20030, 21795, 23493, 25101, 26599, 27969, 29194, 30257, 31145, 31849, 32357, 32665}; + +RAM_ALIGN const Word16 w_old_fs_16_LA_0[OLA_LEN_16K] = {2621, 2646, 2719, 2835, 2990, 3175, 3379, 3592, 3801, 3994, + 4158, 4282, 4355, 4369, 4317, 4196, 4005, 3746, 3425, 3050, + 2635, 2192, 1740, 1299, 889, 531, 250, 66}; +#else +#define w_new_fs_16_LA_0 NULL +#define w_old_fs_16_LA_0 NULL +#endif /* SUBSET_WB */ + +#ifdef SUBSET_SSWB +RAM_ALIGN const Word16 w_new_fs_24_LA_0[OLA_LEN_24K] = { + 0, 46, 183, 411, 728, 1133, 1623, 2195, 2847, 3574, 4374, 5240, 6169, 7155, + 8192, 9275, 10398, 11555, 12738, 13942, 15160, 16384, 17608, 18826, 20030, 21213, 22370, 23493, + 24576, 25613, 26599, 27528, 28394, 29194, 29921, 30573, 31145, 31635, 32040, 32357, 32585, 32722}; + +RAM_ALIGN const Word16 w_old_fs_24_LA_0[OLA_LEN_24K] = { + 2621, 2632, 2665, 2718, 2790, 2881, 2987, 3106, 3235, 3372, 3512, 3653, 3790, 3919, + 4038, 4143, 4229, 4295, 4337, 4353, 4340, 4298, 4225, 4121, 3986, 3821, 3628, 3408, + 3165, 2902, 2622, 2330, 2032, 1732, 1437, 1152, 884, 640, 426, 249, 114, 30}; +#else +#define w_new_fs_24_LA_0 NULL +#define w_old_fs_24_LA_0 NULL +#endif /* SUBSET_SSWB */ + +#ifdef SUBSET_SWB +RAM_ALIGN const Word16 w_new_fs_32_LA_0[OLA_LEN_32K] = { + 0, 26, 103, 231, 411, 640, 919, 1247, 1623, 2044, 2511, 3022, 3574, 4167, + 4799, 5467, 6169, 6903, 7667, 8459, 9275, 10114, 10973, 11848, 12738, 13640, 14550, 15465, + 16384, 17303, 18218, 19128, 20030, 20920, 21795, 22654, 23493, 24309, 25101, 25865, 26599, 27301, + 27969, 28601, 29194, 29746, 30257, 30724, 31145, 31521, 31849, 32128, 32357, 32537, 32665, 32742}; + +RAM_ALIGN const Word16 w_old_fs_32_LA_0[OLA_LEN_32K] = { + 2621, 2628, 2646, 2676, 2717, 2770, 2832, 2904, 2985, 3073, 3167, 3266, 3368, 3473, 3578, 3682, 3784, 3882, 3974, + 4059, 4135, 4202, 4257, 4299, 4328, 4342, 4340, 4323, 4288, 4236, 4167, 4081, 3977, 3856, 3719, 3567, 3400, 3220, + 3028, 2826, 2615, 2398, 2176, 1952, 1728, 1506, 1290, 1081, 882, 697, 528, 377, 248, 143, 65, 17}; +#else +#define w_new_fs_32_LA_0 NULL +#define w_old_fs_32_LA_0 NULL +#endif /* SUBSET_SWB */ + +#ifdef SUBSET_FB +RAM_ALIGN const Word16 w_new_fs_48_LA_0[OLA_LEN_48K] = { + 0, 11, 46, 103, 183, 286, 411, 558, 728, 919, 1133, 1367, 1623, 1899, + 2195, 2511, 2847, 3201, 3574, 3965, 4374, 4799, 5240, 5697, 6169, 6655, 7155, 7667, + 8192, 8728, 9275, 9832, 10398, 10973, 11555, 12144, 12738, 13338, 13942, 14550, 15160, 15771, + 16384, 16997, 17608, 18218, 18826, 19430, 20030, 20624, 21213, 21795, 22370, 22936, 23493, 24040, + 24576, 25101, 25613, 26113, 26599, 27071, 27528, 27969, 28394, 28803, 29194, 29567, 29921, 30257, + 30573, 30869, 31145, 31401, 31635, 31849, 32040, 32210, 32357, 32482, 32585, 32665, 32722, 32757}; + +RAM_ALIGN const Word16 w_old_fs_48_LA_0[OLA_LEN_48K] = { + 2621, 2624, 2632, 2646, 2664, 2688, 2717, 2750, 2789, 2831, 2878, 2929, 2983, 3041, 3101, 3164, 3229, + 3296, 3365, 3434, 3504, 3573, 3643, 3711, 3778, 3844, 3907, 3967, 4024, 4078, 4128, 4173, 4213, 4248, + 4278, 4301, 4319, 4330, 4334, 4331, 4321, 4303, 4278, 4246, 4206, 4158, 4102, 4038, 3967, 3889, 3803, + 3710, 3611, 3505, 3392, 3274, 3150, 3021, 2888, 2750, 2609, 2465, 2319, 2171, 2022, 1873, 1724, 1576, + 1430, 1287, 1147, 1011, 880, 755, 637, 527, 424, 331, 248, 175, 114, 65, 29, 7}; +#else +#define w_new_fs_48_LA_0 NULL +#define w_old_fs_48_LA_0 NULL +#endif /* SUBSET_FB */ + +RAM_ALIGN const Word16 *const w_new[5] = {w_new_fs_8_LA_0, w_new_fs_16_LA_0, w_new_fs_24_LA_0, w_new_fs_32_LA_0, + w_new_fs_48_LA_0}; +RAM_ALIGN const Word16 *const w_old[5] = {w_old_fs_8_LA_0, w_old_fs_16_LA_0, w_old_fs_24_LA_0, w_old_fs_32_LA_0, + w_old_fs_48_LA_0}; + +RAM_ALIGN const Word16 COPY_LEN[5] = {COPY_LEN_8K, COPY_LEN_16K, COPY_LEN_24K, COPY_LEN_32K, COPY_LEN_48K}; /* 2ms */ +RAM_ALIGN const Word16 OLA_LEN[5] = {OLA_LEN_8K, OLA_LEN_16K, OLA_LEN_24K, OLA_LEN_32K, OLA_LEN_48K}; /*1.75 ms mix */ + +RAM_ALIGN const Word16 num_FsByResQ0[5] = {LPROT8K, LPROT16K, LPROT24K, LPROT32K, LPROT48K}; +RAM_ALIGN const Word16 *const LprotSzPtr = num_FsByResQ0; +RAM_ALIGN const Word16 InvLprot_Q22[5] = {INV_LPROT8K_Q22, INV_LPROT16K_Q22, INV_LPROT24K_Q22, INV_LPROT32K_Q22, + INV_LPROT48K_Q22}; +RAM_ALIGN const Word16 PhEcuFftScale[5] = {0, 0, 8, 0, 4}; + +RAM_ALIGN const Word16 oneOverFrameQ15Tab[5] = {INV_L_FRAME8K_Q15, INV_L_FRAME16K_Q15, INV_L_FRAME24K_Q15, + INV_L_FRAME32K_Q15, INV_L_FRAME48K_Q15}; + + +RAM_ALIGN const Word16 PhEcu_Xsav_Flt2FxDnShift[5] = {6, 7, 7, 8, 8}; /* TOTAL FFT adjutmenst shift */ +RAM_ALIGN const Word16 PhEcu_Xsav_Flt2FxScaleQ15[5] = {32767, 32767, 21845, 32767, + 21845}; /* fractional fft adjustment 1./ fft_fs_scale */ + +RAM_ALIGN const Word16 PhEcu_frac_thr_rise_lin_Q15[MAX_LGW] = {3277, 3277, 3277, 3277, 3277, + 3277, 3277, 3277, 3277}; /* for now all fixed to 10dB */ +RAM_ALIGN const Word16 PhEcu_frac_thr_decay_lin_Q15[MAX_LGW] = { + 3277, 3277, 3277, 3277, 3277, + 3277, 3277, 3277, 3277}; /* thresh_rise_dB=10; thresh_lin = 1.0/( 10^(thresh_rise_dB/10) ); */ + +RAM_ALIGN const Word16 mdct_grp_bins_fx[MAX_LGW + 2] = {4, 14, 24, 44, 84, 164, 244, 324, 404, 484}; +RAM_ALIGN const Word16 xavg_N_grp_fx[5] = {4, 5, 6, 7, 8}; + + +RAM_ALIGN const Word16 spec_shape_headroom[5] = {3, 4, 4, 4, 4}; +RAM_ALIGN const Word16 rectLengthTab[NUM_SAMP_FREQ] = {80, 160, 240, 320, 480, 960}; /* 10ms */ +RAM_ALIGN const Word16 hamm_len2Tab[5] = {24, 48, 72, 96, 144}; /* 3 ms*/ + +#ifdef CR10_A_ATTENUATION_CURVE_SELECTOR +RAM_ALIGN const Word16 PLC_FADEOUT_TYPE_2_SELECTOR = 10; /* can take values from 0 to 10, default is 10 for longer fadeout*/ +#else +# ifdef CR9_N_SHORT_FADE_FOR_UNSTABLE_PITCH +RAM_ALIGN const Word16 FADE_OUT_TYPE_2_ALPHA_5MS[30] = { /* 0.5^(nbLostFramesInRow + LC3_ROUND(100.0/frame_dms) - 1) * frame_dms/100.0)*/ + 16384,11585,8192,5792,4096,2896,2048,1448,1024,724,512,362,256,181,128,91,64,45,32,23,16,11,8,6,4,3,2,1,1,1}; +RAM_ALIGN const Word16 FADE_OUT_TYPE_2_ALPHA_2_5MS[60] = { /* 0.5^(nbLostFramesInRow + LC3_ROUND(100.0/frame_dms) - 1) * frame_dms/100.0)*/ + 16384,13777,11585,9742,8192,6889,5793,4871,4096,3444,2896,2435,2048,1722,1448,1218,1024,861,724,609,512,431,362,304,256,215,181,152,128,108,91,76,64,54,45,38,32,27,23,19,16,13,11,10,8,7,6,5,4,3,3,2,2,2,1,1,1,1,1,1}; +# endif +#endif + +RAM_ALIGN const Word16 NN_thresh = 0x7800; /* 30*2^10 */ +RAM_ALIGN const Word16 NN_thresh_exp = -10; +/* Tone detector */ +#ifdef CR8_E_TONE_DETECTOR +# ifdef ENABLE_HR_MODE +RAM_ALIGN const Word32 TD_HR_thresh_10ms = 83402; +# ifdef ENABLE_075_DMS_MODE +RAM_ALIGN const Word32 TD_HR_thresh_7_5ms = 743496; +# endif +RAM_ALIGN const Word32 TD_HR_thresh_5ms = 382564; +RAM_ALIGN const Word32 TD_HR_thresh_2_5ms = 301695; +# endif /* ENABLE_HR_MODE */ +#endif /* CR8_E_TONE_DETECTOR */ +RAM_ALIGN const Word32 BW_thresh_quiet[4] = {0x14000000, 0xA000000, 0xA000000, 0xA000000}; /* [20,10,10,10]*2^24 */ +RAM_ALIGN const Word16 BW_thresh_quiet_exp = 31 - 24; +RAM_ALIGN const Word16 BW_thresh_brickwall[4] = { + 1036, 164, 327, 327}; /* (1/(10^(ctrl.BW_thresh_brickwall/10))*2^15) with [15,23,20,20] dB*/ + +RAM_ALIGN const Word16 BW_brickwall_dist[4] = {4, 4, 3, 1}; +RAM_ALIGN const Word16 BW_warp_idx_start_16k[4] = { + 53, 0, 0, 0}; /* indices for warped bands, with an offset of [17,23,23,23] bins for the start_idx */ +RAM_ALIGN const Word16 BW_warp_idx_stop_16k[4] = { + 63, 0, 0, + 0}; /*'-1' since this is not matlab and another '-1' because of the different formatting of acc_coeff_per_band*/ +RAM_ALIGN const Word16 BW_warp_idx_start_24k[4] = {47, 59, 0, 0}; +RAM_ALIGN const Word16 BW_warp_idx_stop_24k[4] = {56, 63, 0, 0}; +RAM_ALIGN const Word16 BW_warp_idx_start_32k[4] = {44, 54, 60, 0}; +RAM_ALIGN const Word16 BW_warp_idx_stop_32k[4] = {52, 59, 63, 0}; +RAM_ALIGN const Word16 BW_warp_idx_start_48k[4] = {41, 51, 57, 61}; +RAM_ALIGN const Word16 BW_warp_idx_stop_48k[4] = {49, 55, 60, 63}; +RAM_ALIGN const Word16 *const BW_warp_idx_start_all[MAX_BW_BANDS_NUMBER - 1] = { + BW_warp_idx_start_16k, BW_warp_idx_start_24k, BW_warp_idx_start_32k, BW_warp_idx_start_48k}; +RAM_ALIGN const Word16 *const BW_warp_idx_stop_all[MAX_BW_BANDS_NUMBER - 1] = { + BW_warp_idx_stop_16k, BW_warp_idx_stop_24k, BW_warp_idx_stop_32k, BW_warp_idx_stop_48k}; + +RAM_ALIGN const Word16 BW_brickwall_dist_5ms[4] = {4, 4, 3, 1}; +RAM_ALIGN const Word16 BW_warp_idx_start_16k_5ms[4] = {39, 0, 0, 0}; +RAM_ALIGN const Word16 BW_warp_idx_stop_16k_5ms[4] = {49, 0, 0, 0}; +RAM_ALIGN const Word16 BW_warp_idx_start_24k_5ms[4] = {35, 47, 0, 0}; +RAM_ALIGN const Word16 BW_warp_idx_stop_24k_5ms[4] = {44, 51, 0, 0}; +RAM_ALIGN const Word16 BW_warp_idx_start_32k_5ms[4] = {34, 44, 50, 0}; +RAM_ALIGN const Word16 BW_warp_idx_stop_32k_5ms[4] = {42, 49, 53, 0}; +RAM_ALIGN const Word16 BW_warp_idx_start_48k_5ms[4] = {32, 42, 48, 52}; +RAM_ALIGN const Word16 BW_warp_idx_stop_48k_5ms[4] = {40, 46, 51, 54}; +RAM_ALIGN const Word16 *const BW_warp_idx_start_all_5ms[MAX_BW_BANDS_NUMBER - 1] = { + BW_warp_idx_start_16k_5ms, BW_warp_idx_start_24k_5ms, BW_warp_idx_start_32k_5ms, BW_warp_idx_start_48k_5ms}; +RAM_ALIGN const Word16 *const BW_warp_idx_stop_all_5ms[MAX_BW_BANDS_NUMBER - 1] = { + BW_warp_idx_stop_16k_5ms, BW_warp_idx_stop_24k_5ms, BW_warp_idx_stop_32k_5ms, BW_warp_idx_stop_48k_5ms}; + +RAM_ALIGN const Word16 BW_brickwall_dist_2_5ms[4] = {4, 4, 3, 1}; +RAM_ALIGN const Word16 BW_warp_idx_start_16k_2_5ms[4] = {24, 0, 0, 0}; +RAM_ALIGN const Word16 BW_warp_idx_stop_16k_2_5ms[4] = {34, 0, 0, 0}; +RAM_ALIGN const Word16 BW_warp_idx_start_24k_2_5ms[4] = {24, 35, 0, 0}; +RAM_ALIGN const Word16 BW_warp_idx_stop_24k_2_5ms[4] = {32, 39, 0, 0}; +RAM_ALIGN const Word16 BW_warp_idx_start_32k_2_5ms[4] = {24, 33, 39, 0}; +RAM_ALIGN const Word16 BW_warp_idx_stop_32k_2_5ms[4] = {31, 38, 42, 0}; +RAM_ALIGN const Word16 BW_warp_idx_start_48k_2_5ms[4] = {22, 31, 37, 41}; +RAM_ALIGN const Word16 BW_warp_idx_stop_48k_2_5ms[4] = {29, 35, 40, 43}; +RAM_ALIGN const Word16 *const BW_warp_idx_start_all_2_5ms[MAX_BW_BANDS_NUMBER - 1] = { + BW_warp_idx_start_16k_2_5ms, BW_warp_idx_start_24k_2_5ms, BW_warp_idx_start_32k_2_5ms, BW_warp_idx_start_48k_2_5ms}; +RAM_ALIGN const Word16 *const BW_warp_idx_stop_all_2_5ms[MAX_BW_BANDS_NUMBER - 1] = { + BW_warp_idx_stop_16k_2_5ms, BW_warp_idx_stop_24k_2_5ms, BW_warp_idx_stop_32k_2_5ms, BW_warp_idx_stop_48k_2_5ms}; + +# ifdef CR8_G_ADD_75MS +RAM_ALIGN const Word16 BW_brickwall_dist_7_5ms[4] = {4, 4, 3, 2}; +RAM_ALIGN const Word16 BW_warp_idx_start_16k_7_5ms[4] = {51, 0, 0, 0}; +RAM_ALIGN const Word16 BW_warp_idx_stop_16k_7_5ms[4] = {63, 0, 0, 0}; +RAM_ALIGN const Word16 BW_warp_idx_start_24k_7_5ms[4] = {45, 58, 0, 0}; +RAM_ALIGN const Word16 BW_warp_idx_stop_24k_7_5ms[4] = {55, 63, 0, 0}; +RAM_ALIGN const Word16 BW_warp_idx_start_32k_7_5ms[4] = {42, 53, 60, 0}; +RAM_ALIGN const Word16 BW_warp_idx_stop_32k_7_5ms[4] = {51, 58, 63, 0}; +RAM_ALIGN const Word16 BW_warp_idx_start_48k_7_5ms[4] = {40, 51, 57, 61}; +RAM_ALIGN const Word16 BW_warp_idx_stop_48k_7_5ms[4] = {48, 55, 60, 63}; +RAM_ALIGN const Word16 *const BW_warp_idx_start_all_7_5ms[] = { + BW_warp_idx_start_16k_7_5ms, BW_warp_idx_start_24k_7_5ms, BW_warp_idx_start_32k_7_5ms, BW_warp_idx_start_48k_7_5ms}; +RAM_ALIGN const Word16 *const BW_warp_idx_stop_all_7_5ms[] = { + BW_warp_idx_stop_16k_7_5ms, BW_warp_idx_stop_24k_7_5ms, BW_warp_idx_stop_32k_7_5ms, BW_warp_idx_stop_48k_7_5ms}; +# endif + +#ifdef ENABLE_HR_MODE +RAM_ALIGN const Word16 BW_cutoff_bin_all[] = {80, 160, 240, 320, 400, 400}; +RAM_ALIGN const Word16 BW_cutoff_bin_all_HR[] = {80, 160, 240, 320, 400, 400}; +RAM_ALIGN const Word16 BW_cutoff_bits_all[] = {0, 1, 2, 2, 3, 0}; +#else /* ENABLE_HR_MODE */ +RAM_ALIGN const Word16 BW_cutoff_bin_all[] = {80, 160, 240, 320, 400}; +RAM_ALIGN const Word16 BW_cutoff_bits_all[] = {0, 1, 2, 2, 3}; +#endif /* ENABLE_HR_MODE */ + +#ifdef ENABLE_HR_MODE +RAM_ALIGN const Word16 LowDelayShapes_n960_len[6] = {130, 260, 390, 520, 780, 1560}; +#else +RAM_ALIGN const Word16 LowDelayShapes_n960_len[5] = {130, 260, 390, 520, 780}; +#endif +RAM_ALIGN const Word16 LowDelayShapes_n960_la_zeroes[NUM_SAMP_FREQ] = {30, + 60, + 90, + 120, + 180 +#ifdef ENABLE_HR_MODE + , 360 +#endif +}; + +#ifdef CR8_G_ADD_75MS +# ifdef ENABLE_HR_MODE +const Word16 LowDelayShapes_n960_len_7_5ms[6] = {106, 212, 318, 424, 636, 1272}; +# else +const Word16 LowDelayShapes_n960_len_7_5ms[5] = {106, 212, 318, 424, 636}; +# endif +const Word16 LowDelayShapes_n960_la_zeroes_7_5ms[NUM_SAMP_FREQ] = {14, 28, 42, 56, 84 +# ifdef ENABLE_HR_MODE + , 168 +# endif +}; +# ifdef ENABLE_HR_MODE +# ifdef SUBSET_NB +const Word32 MDCT_WINDOW_FS_8000_frame_ms_75[106] = { + 4627440, 11253200, 21594770, 36220454, 55523513, 79715027, 108949241, 143324500, 182870991, + 227518888, 277136190, 331449220, 390143896, 452770029, 518831181, 587821768, 659169189, 732247130, + 806397033, 880930033, 955136210, 1028289061, 1099721013, 1168761191, 1234831373, 1297335398, 1355817068, + 1409866562, 1459158403, 1503372583, 1542341368, 1575958063, 1604141948, 1626962506, 1644516439, 1657006271, + 1664740913, 1668084651, 1667510566, 1663566793, 1656808751, 1647805301, 1637186879, 1625507591, 1613355502, + 1601336341, 1590266842, 1579708994, 1571001708, 1564080946, 1558867236, 1555257286, 1553127519, 1552339115, + 1552734517, 1554146897, 1556401387, 1559318893, 1562715844, 1566405205, -1570197717, -1573904742, -1577333468, + -1580290211, -1582582625, -1584022156, -1584425628, -1583621336, -1581452727, -1577790475, -1572531065, -1565603566, + -1556974029, -1546637213, -1533223967, -1517247857, -1497930249, -1474813741, -1447477329, -1415559391, -1378853853, + -1337198324, -1290524957, -1238912889, -1182546000, -1121735805, -1056935470, -988679598, -917579357, -844370566, + -769774729, -694577976, -619621377, -545775321, -473935196, -404978161, -339758802, -279035319, -223452287, + -173535871, -129697804, -92268521, -61482210, -37424210, -19913685, -8400842}; +# else +# define MDCT_WINDOW_FS_8000_frame_ms_75 NULL +# endif +# ifdef SUBSET_WB +const Word32 MDCT_WINDOW_FS_16000_frame_ms_75[212] = { + 2448850, 4225281, 6560055, 9518849, 13169928, 17558685, 22724572, 28709046, 35532706, + 43206772, 51759643, 61197652, 71531905, 82773688, 94926633, 107995294, 121978042, 136866522, + 152653815, 169326944, 186873869, 205260070, 224464206, 244469708, 265226672, 286694090, 308842566, + 331620399, 354982140, 378884306, 403282899, 428126460, 453358062, 478925896, 504771155, 530831178, + 557056009, 583378298, 609738583, 636071404, 662314239, 688406753, 714278048, 739869110, 765133864, + 789997902, 814413107, 838333634, 861699657, 884456686, 906561215, 927970820, 948653245, 968562870, + 987675635, 1005965699, 1023398499, 1039938064, 1055570884, 1070287165, 1084066983, 1096897234, 1108786027, + 1119713468, 1129673618, 1138691939, 1146759882, 1153881756, 1160087929, 1165385723, 1169796304, 1173355296, + 1176085471, 1178017803, 1179194996, 1179657892, 1179448026, 1178622117, 1177223060, 1175290297, 1172896803, + 1170081494, 1166887472, 1163391971, 1159633509, 1155652038, 1151518603, 1147273273, 1142969676, 1138666561, + 1134412515, 1130255869, 1126558117, 1122496331, 1118765157, 1115363902, 1112285558, 1109526458, 1107080797, + 1104939816, 1103098430, 1101543766, 1100269289, 1099261964, 1098510648, 1098002762, 1097726182, 1097665183, + 1097807233, 1098135900, 1098637579, 1099295163, 1100094642, 1101018650, 1102052611, 1103178569, 1104381936, + 1105644852, 1106951761, 1108284322, -1109627660, -1110963442, -1112276637, -1113548581, -1114763260, -1115902204, + -1116950143, -1117888308, -1118701309, -1119370903, -1119882282, -1120217558, -1120362527, -1120300271, -1120018073, + -1119500244, -1118735095, -1117710865, -1116417682, -1114844247, -1112986355, -1110833953, -1108385410, -1105635984, + -1102584489, -1099232427, -1095578582, -1091628491, -1086655755, -1081531176, -1075887278, -1069676603, -1062851542, + -1055375495, -1047209387, -1038304906, -1028645771, -1018191542, -1006905821, -994788854, -981815515, -967960849, + -953236015, -937625018, -921120793, -903739802, -885489416, -866385515, -846456825, -825718325, -804213946, + -781984241, -759069751, -735509614, -711369811, -686704607, -661557703, -636008311, -610118476, -583941228, + -557562076, -531035554, -504439473, -477846967, -451338312, -424989596, -398869327, -373061710, -347653667, + -322717851, -298330826, -274560095, -251498346, -229196510, -207718889, -187124805, -167466055, -148790641, + -131139192, -114544857, -99042767, -84660988, -71425324, -59356162, -48470733, -38776535, -30272788, + -22943830, -16759108, -11669404, -7602417, -4461896 }; +# else +# define MDCT_WINDOW_FS_16000_frame_ms_75 NULL +# endif +# ifdef SUBSET_SSWB +const Word32 MDCT_WINDOW_FS_24000_frame_ms_75[318] = { + 3569045, 5343308, 7469087, 10008734, 12994076, 16456850, 20430606, 24935492, 29988837, + 35611849, 41823777, 48643571, 56071893, 64113030, 72783590, 82094564, 92046985, 102645585, + 113894977, 125803748, 138373328, 151602749, 165496877, 180058414, 195279760, 211161232, 227698398, + 244884561, 262716182, 281188032, 300290267, 320009308, 340323456, 361229416, 382724592, 404784463, + 427382077, 450499367, 474123138, 498236134, 522813796, 547827872, 573261791, 599094644, 625301687, + 651864990, 678758112, 705953149, 733423301, 761143017, 789088191, 817226769, 845526155, 873965021, + 902516713, 931147088, 959825021, 988524208, 1017210384, 1045855673, 1074425690, 1102896296, 1131233244, + 1159399102, 1187365932, 1215118091, 1242623432, 1269848445, 1296758792, 1323338775, 1349569176, 1375419011, + 1400856664, 1425860452, 1450405500, 1474469418, 1498033883, 1521084216, 1543600669, 1565562699, 1586950362, + 1607758181, 1627973678, 1647578495, 1666558705, 1684890994, 1702569411, 1719588669, 1735945131, 1751628259, + 1766631537, 1780942408, 1794568179, 1807511369, 1819759624, 1831304037, 1842145330, 1852303571, 1861781063, + 1870563512, 1878654482, 1886073254, 1892829269, 1898924017, 1904366694, 1909168622, 1913346034, 1916917451, + 1919887595, 1922277229, 1924098512, 1925377637, 1926138245, 1926390110, 1926159966, 1925475348, 1924365664, + 1922840889, 1920921471, 1918639476, 1916032510, 1913117957, 1909905898, 1906425851, 1902721668, 1898817211, + 1894724624, 1890460570, 1886061947, 1881561147, 1876974490, 1872321669, 1867634952, 1862942467, 1858269659, + 1853636539, 1849063935, 1844532585, 1840901848, 1836281978, 1831977326, 1827914309, 1824090826, 1820508133, + 1817156298, 1814036518, 1811148878, 1808486122, 1806045111, 1803824889, 1801820200, 1800024837, 1798435525, + 1797047955, 1795856425, 1794854508, 1794036436, 1793397182, 1792930395, 1792629275, 1792486811, 1792496288, + 1792650932, 1792943382, 1793366271, 1793912436, 1794574259, 1795343928, 1796214319, 1797177519, 1798225910, + 1799351580, 1800546365, 1801802795, 1803112835, 1804468826, 1805862173, 1807285016, 1808728934, 1810185719, + -1811649011, -1813108149, -1814556719, -1815986412, -1817388652, -1818755380, -1820077746, -1821347804, -1822557195, + -1823698097, -1824761958, -1825740466, -1826625594, -1827409009, -1828083190, -1828639928, -1829071236, -1829369628, + -1829527454, -1829537126, -1829391729, -1829084485, -1828608410, -1827956837, -1827123677, -1826104316, -1824893520, + -1823485537, -1821875510, -1820060164, -1818037432, -1815802468, -1813351581, -1810685587, -1807803281, -1804699559, + -1801376829, -1797838749, -1794078176, -1790099212, -1785902823, -1781420977, -1775757613, -1770414541, -1764657397, + -1758514553, -1751966917, -1744988832, -1737559493, -1729660865, -1721279216, -1712390301, -1702968220, -1693002531, + -1682487980, -1671402851, -1659722977, -1647435681, -1634547191, -1621051754, -1606928538, -1592163286, -1576765074, + -1560734340, -1544063625, -1526744164, -1508774562, -1490169863, -1470931267, -1451061598, -1430573380, -1409469788, + -1387774154, -1365486503, -1342628496, -1319212449, -1295268938, -1270814307, -1245866917, -1220443956, -1194576202, + -1168294208, -1141628864, -1114589888, -1087212858, -1059529377, -1031588154, -1003401722, -974995147, -946412027, + -917694623, -888859295, -859943075, -830987474, -802029563, -773092402, -744234412, -715477138, -686865195, + -658426713, -630207057, -602244426, -574581369, -547253226, -520293544, -493735699, -467628500, -441995738, + -416889401, -392319671, -368337811, -344954670, -322202233, -300117288, -278711744, -258020476, -238052276, + -218834457, -200381964, -182706579, -165829103, -149762124, -134517743, -120107705, -106542511, -93830987, + -81979923, -70993541, -60872925, -51615362, -43213756, -35655914, -28924065, -22994343, -17836407, + -13413907, -9700456, -6939916 }; +# else +# define MDCT_WINDOW_FS_24000_frame_ms_75 NULL +# endif +# ifdef SUBSET_SWB +const Word32 MDCT_WINDOW_FS_32000_frame_ms_75[424] = { + 2898737, 4022405, 5281441, 6723878, 8372060, 10235970, 12328606, 14657777, 17238266, + 20075996, 23180406, 26552429, 30204258, 34141418, 38374110, 42901881, 47726394, 52848657, + 58275464, 64009892, 70057240, 76417471, 83091786, 90080421, 97386522, 105014921, 112964415, + 121235754, 129827911, 138744722, 147986004, 157551876, 167437738, 177647147, 188174741, 199022831, + 210184946, 221662871, 233452811, 245554560, 257961285, 270671503, 283672733, 296964439, 310542664, + 324409414, 338557330, 352975270, 367652577, 382584217, 397764861, 413190770, 428852496, 444742036, + 460850489, 477166934, 493686689, 510401963, 527305552, 544386461, 561639986, 579055156, 596625027, + 614334635, 632177187, 650141962, 668224093, 686407908, 704684687, 723041108, 741470500, 759961912, + 778506953, 797092489, 815707619, 834339025, 852979862, 871616777, 890238991, 908834402, 927390921, + 945902091, 964354406, 982734524, 1001028580, 1019227984, 1037324578, 1055313224, 1073178103, 1090910419, + 1108493143, 1125919532, 1143183321, 1160279970, 1177195986, 1193922020, 1210443853, 1226757428, 1242848720, + 1258716966, 1274346305, 1289734310, 1304873724, 1319761111, 1334385677, 1348742053, 1362821420, 1376620057, + 1390134975, 1403361262, 1416296924, 1428929625, 1441257929, 1453270092, 1464967234, 1476341997, 1487396355, + 1498127704, 1508535547, 1518610856, 1528355951, 1537762901, 1546836443, 1555575202, 1563981756, 1572051527, + 1579779433, 1587162378, 1594203212, 1600912026, 1607289540, 1613333597, 1619037500, 1624404299, 1629439428, + 1634149881, 1638537653, 1642603536, 1646350593, 1649779860, 1652898979, 1655708955, 1658229426, 1660449352, + 1662377545, 1664024217, 1665388315, 1666481709, 1667311651, 1667891108, 1668216427, 1668300198, 1668150304, + 1667777789, 1667191944, 1666404102, 1665413150, 1664228568, 1662860495, 1661323561, 1659629730, 1657785817, + 1655794977, 1653662566, 1651401295, 1649028654, 1646557403, 1643989827, 1641331208, 1638586818, 1635770553, + 1632894967, 1629971201, 1627004437, 1624002536, 1620971847, 1617927153, 1614878122, 1611835451, 1608805100, + 1605795099, 1602815547, 1599884473, 1596942341, 1594771673, 1591702411, 1588839753, 1586088059, 1583448720, + 1580925703, 1578521775, 1576232766, 1574055288, 1571990953, 1570040827, 1568202332, 1566472498, 1564851004, + 1563337829, 1561931261, 1560628909, 1559429084, 1558330506, 1557331359, 1556429824, 1555624516, 1554913143, + 1554292592, 1553760945, 1553317125, 1552958916, 1552683122, 1552487276, 1552369480, 1552327252, 1552357490, + 1552457675, 1552625785, 1552859126, 1553154340, 1553508826, 1553920495, 1554386414, 1554903212, 1555468295, + 1556079427, 1556733719, 1557427851, 1558158741, 1558924090, 1559721218, 1560546581, 1561397206, 1562271110, + 1563165114, 1564075458, 1564999378, 1565934440, 1566877694, 1567825218, -1568775555, -1569724227, -1570669763, + -1571608214, -1572536583, -1573452385, -1574352788, -1575233942, -1576092574, -1576926600, -1577732933, -1578507896, + -1579248680, -1579952850, -1580617181, -1581238194, -1581812847, -1582338764, -1582813204, -1583232638, -1583593989, + -1583895045, -1584133086, -1584304626, -1584406873, -1584437736, -1584394635, -1584274418, -1584074588, -1583793268, + -1583428030, -1582975737, -1582434279, -1581802744, -1581079400, -1580261338, -1579346529, -1578333908, -1577222011, + -1576009429, -1574695339, -1573278552, -1571757228, -1570130264, -1568398303, -1566561731, -1564618340, -1562566382, + -1560407784, -1558145041, -1555775754, -1553296829, -1550712057, -1548026396, -1545242289, -1542268350, -1538423280, + -1535025262, -1531395445, -1527591708, -1523601949, -1519416343, -1515026680, -1510422354, -1505596841, -1500543057, + -1495258714, -1489733930, -1483960441, -1477928294, -1471632952, -1465071334, -1458241898, -1451136236, -1443746092, + -1436060907, -1428079531, -1419805847, -1411239360, -1402373353, -1393199823, -1383713926, -1373917135, -1363813377, + -1353400513, -1342677100, -1331640941, -1320284636, -1308611825, -1296630892, -1284342674, -1271742396, -1258835954, + -1245628407, -1232122065, -1218316234, -1204224404, -1189846207, -1175175506, -1160242956, -1145031655, -1129564821, + -1113844775, -1097879736, -1081675373, -1065238433, -1048578417, -1031707925, -1014636539, -997375667, -979937295, + -962314566, -944532531, -926597437, -908531127, -890341534, -872033654, -853615925, -835103871, -816513734, + -797862235, -779149108, -760390220, -741599202, -722791848, -703980340, -685176354, -666389658, -647646244, + -628944722, -610316405, -591754523, -573282405, -554915396, -536666275, -518550375, -500581949, -482775076, + -465139339, -447692836, -430439482, -413418994, -396596647, -380036004, -363729221, -347677810, -331912032, + -316431125, -301242631, -286354637, -271795849, -257560706, -243655300, -230096441, -216894979, -204043835, + -191560528, -179450345, -167715723, -156363602, -145400931, -134832648, -124663143, -114896281, -105536276, + -96587551, -88053476, -79936384, -72238586, -64962154, -58107752, -51674659, -45661585, -40066372, + -34884913, -30111469, -25739290, -21759792, -18161914, -14933570, -12062384, -9522842, -7254663, + -5656627 }; +# else +# define MDCT_WINDOW_FS_32000_frame_ms_75 NULL +# endif +# ifdef SUBSET_FB +const Word32 MDCT_WINDOW_FS_48000_frame_ms_75[636] = { + 2204435, 2827689, 3443319, 4131102, 4878935, 5703040, 6599364, 7574899, 8628974, + 9768536, 10991420, 12304931, 13709256, 15207323, 16799052, 18489324, 20275023, 22160933, + 24148496, 26240076, 28435235, 30739604, 33150351, 35668955, 38294878, 41029635, 43871618, + 46825882, 49890883, 53068998, 56360550, 59766888, 63284768, 66918075, 70664961, 74526448, + 78503039, 82597929, 86807681, 91135031, 95578822, 100139618, 104816236, 109611835, 114523552, + 119554039, 124702224, 129967749, 135348514, 140848111, 146462751, 152193324, 158039847, 164002831, + 170078327, 176269443, 182573647, 188991411, 195521914, 202165741, 208918745, 215783357, 222755240, + 229832331, 237013913, 244302241, 251692923, 259188940, 266788795, 274490295, 282289304, 290186132, + 298175224, 306257381, 314430505, 322694044, 331045821, 339487261, 348012274, 356620678, 365310317, + 374079074, 382922254, 391842074, 400834178, 409898068, 419031270, 428232881, 437497913, 446828175, + 456219802, 465670981, 475178925, 484743299, 494357854, 504022976, 513735237, 523492799, 533292796, + 543136028, 553015990, 562931887, 572880536, 582859524, 592864355, 602896501, 612951047, 623027190, + 633121825, 643232873, 653354882, 663488155, 673627234, 683771323, 693918098, 704065470, 714207061, + 724344108, 734471992, 744587758, 754688429, 764774608, 774840295, 784884831, 794903648, 804894011, + 814851825, 824777247, 834664477, 844515260, 854327259, 864098094, 873822193, 883500485, 893125924, + 902697010, 912211002, 921668164, 931065070, 940403253, 949676961, 958885223, 968024298, 977093615, + 986086667, 995005058, 1003845874, 1012604766, 1021282611, 1029879030, 1038386135, 1046806723, 1055138039, + 1063379017, 1071528406, 1079585832, 1087546197, 1095410412, 1103175087, 1110839263, 1118400067, 1125861251, + 1133217689, 1140469587, 1147616705, 1154658548, 1161589135, 1168411456, 1175122212, 1181718798, 1188199640, + 1194567214, 1200817042, 1206950737, 1212967954, 1218868269, 1224650873, 1230316551, 1235861165, 1241285527, + 1246589565, 1251772729, 1256831629, 1261771016, 1266587826, 1271284733, 1275860443, 1280315823, 1284645497, + 1288852346, 1292933744, 1296889962, 1300722079, 1304434734, 1308025653, 1311497310, 1314848195, 1318076916, + 1321181451, 1324164254, 1327024207, 1329764950, 1332387885, 1334893025, 1337281173, 1339554157, 1341707740, + 1343747791, 1345671522, 1347481634, 1349179572, 1350764422, 1352239980, 1353613012, 1354873992, 1356030340, + 1357079368, 1358026526, 1358871638, 1359613742, 1360257791, 1360804083, 1361255397, 1361617096, 1361885808, + 1362062609, 1362151603, 1362153995, 1362072233, 1361909271, 1361666938, 1361347766, 1360955593, 1360489817, + 1359950116, 1359340101, 1358660855, 1357916180, 1357108339, 1356243400, 1355321087, 1354344570, 1353313776, + 1352230258, 1351093731, 1349909242, 1348677915, 1347405592, 1346095404, 1344750475, 1343369336, 1341955495, + 1340508098, 1339029437, 1337520955, 1335988076, 1334432030, 1332857982, 1331266254, 1329659151, 1328036799, + 1326403000, 1324757066, 1323104230, 1321446604, 1319787700, 1318127699, 1316471738, 1314818892, 1313173031, + 1311534229, 1309906742, 1308289975, 1306691587, 1305107061, 1303560954, 1302485706, 1300837265, 1299230148, + 1297667349, 1296147118, 1294669845, 1293233008, 1291838729, 1290486465, 1289178223, 1287911298, 1286686132, + 1285500617, 1284356733, 1283253302, 1282192039, 1281170798, 1280190420, 1279248602, 1278346792, 1277483349, + 1276659918, 1275874601, 1275128550, 1274419448, 1273748350, 1273113203, 1272515449, 1271953180, 1271427649, + 1270936717, 1270481540, 1270059928, 1269672963, 1269318382, 1268997326, 1268707731, 1268450837, 1268224483, + 1268029756, 1267864381, 1267729424, 1267622629, 1267545013, 1267494302, 1267471571, 1267474578, 1267504402, + 1267558747, 1267638603, 1267741668, 1267868942, 1268018115, 1268190239, 1268383008, 1268597404, 1268831071, + 1269084943, 1269356717, 1269647473, 1269954877, 1270279875, 1270620090, 1270976496, 1271346828, 1271732058, + 1272129716, 1272540744, 1272962829, 1273396990, 1273840888, 1274295422, 1274758248, 1275230417, 1275709517, + 1276196415, 1276688706, 1277187379, 1277690114, 1278197794, 1278707969, 1279221647, 1279736503, 1280253498, + -1280770244, -1281287656, -1281803343, -1282318265, -1282830085, -1283339807, -1283844964, -1284346432, -1284841866, + -1285332250, -1285815146, -1286291410, -1286758593, -1287217737, -1287666452, -1288105628, -1288532876, -1288949203, + -1289352245, -1289742931, -1290118731, -1290480607, -1290826232, -1291156571, -1291469183, -1291765004, -1292041634, + -1292300151, -1292538184, -1292756663, -1292953166, -1293128674, -1293280819, -1293410658, -1293515818, -1293597309, + -1293652773, -1293683213, -1293686282, -1293663081, -1293611326, -1293532118, -1293423149, -1293285472, -1293116803, + -1292918254, -1292687534, -1292425784, -1292130842, -1291804017, -1291443255, -1291049775, -1290621337, -1290159111, + -1289660945, -1289128099, -1288558489, -1287953483, -1287311252, -1286633366, -1285917866, -1285165943, -1284375393, + -1283547520, -1282680564, -1281776335, -1280833350, -1279853230, -1278833852, -1277776244, -1276678466, -1275542433, + -1274367185, -1273154903, -1271903726, -1270614321, -1269284275, -1267915816, -1266508671, -1265065178, -1263583140, + -1262063220, -1260504007, -1258908698, -1256628331, -1254761985, -1252853377, -1250881358, -1248844632, -1246741358, + -1244569594, -1242327619, -1240012651, -1237623600, -1235156149, -1232610864, -1229984110, -1227275248, -1224482272, + -1221606271, -1218642652, -1215591412, -1212448650, -1209213243, -1205881571, -1202455146, -1198931234, -1195311772, + -1191594196, -1187777826, -1183858288, -1179836046, -1175706321, -1171469469, -1167124636, -1162674694, -1158117379, + -1153454731, -1148683225, -1143802349, -1138808714, -1133702904, -1128481825, -1123149280, -1117704914, -1112149514, + -1106481061, -1100702139, -1094806903, -1088800296, -1082676113, -1076437274, -1070082677, -1063618676, -1057039488, + -1050351248, -1043548836, -1036634133, -1029608325, -1022475106, -1015230021, -1007878923, -1000415821, -992849913, + -985179219, -977404151, -969525479, -961538535, -953457394, -945280420, -936999272, -928626277, -920160734, + -911603664, -902957625, -894223210, -885402362, -876498250, -867508512, -858440255, -849293347, -840074392, + -830781521, -821419104, -811990901, -802499334, -792938179, -783315469, -773636100, -763901035, -754111866, + -744278025, -734399140, -724475975, -714510329, -704504133, -694460237, -684383382, -674277250, -664145566, + -653994294, -643817229, -633622219, -623410967, -613187040, -602954520, -592717105, -582476532, -572238350, + -562002979, -551770150, -541551921, -531349514, -521160592, -510991643, -500852505, -490735715, -480646079, + -470590740, -460574626, -450595871, -440662753, -430774557, -420941335, -411160195, -401435877, -391774603, + -382174290, -372642476, -363180190, -353786746, -344482765, -335253937, -326094163, -317034690, -308063867, + -299187762, -290405275, -281715156, -273134873, -264653333, -256282164, -248014183, -239853113, -231807709, + -223884020, -216073113, -208387006, -200816625, -193373144, -186056104, -178871459, -171808633, -164881963, + -158086310, -151426496, -144902306, -138514809, -132265008, -126156408, -120188845, -114364736, -108683712, + -103148269, -97758088, -92515604, -87420431, -82474860, -77678410, -73033188, -68538592, -64196501, + -60006167, -55969182, -52084610, -48353698, -44775286, -41350196, -38077002, -34956005, -31985545, + -29165263, -26493253, -23968386, -21588587, -19351751, -17255806, -15297341, -13474667, -11782386, + -10220076, -8778515, -7460996, -6246830, -5152154, -4038973 }; +# else +# define MDCT_WINDOW_FS_48000_frame_ms_75 NULL +# endif + +const Word32 *const LowDelayShapes_n960_7_5ms[5] = { + MDCT_WINDOW_FS_8000_frame_ms_75, MDCT_WINDOW_FS_16000_frame_ms_75, MDCT_WINDOW_FS_24000_frame_ms_75, MDCT_WINDOW_FS_32000_frame_ms_75, MDCT_WINDOW_FS_48000_frame_ms_75 }; +# else + +RAM_ALIGN const Word16 LowDelayShapes_n960_N60_7_5ms[106] = { + 71, 172, 330, 553, 847, 1216, 1662, 2187, 2790, 3472, 4229, 5058, 5953, 6909, + 7917, 8969, 10058, 11173, 12305, 13442, 14574, 15690, 16780, 17834, 18842, 19796, 20688, 21513, + 22265, 22940, 23534, 24047, 24477, 24825, 25093, 25284, 25402, 25453, 25444, 25384, 25281, 25144, + 24981, 24803, 24618, 24434, 24266, 24104, 23972, 23866, 23786, 23731, 23699, 23687, 23693, 23714, + 23749, 23793, 23845, 23901, -23959, -24016, -24068, -24113, -24148, -24170, -24176, -24164, -24131, -24075, + -23995, -23889, -23758, -23600, -23395, -23151, -22857, -22504, -22087, -21600, -21040, -20404, -19692, -18904, + -18044, -17116, -16128, -15086, -14001, -12884, -11746, -10598, -9455, -8328, -7232, -6179, -5184, -4258, + -3410, -2648, -1979, -1408, -938, -571, -304, -128}; + +RAM_ALIGN const Word16 LowDelayShapes_n960_N120_7_5ms[212] = { + 37, 64, 100, 145, 201, 268, 347, 438, 542, 659, 790, 934, 1091, 1263, + 1448, 1648, 1861, 2088, 2329, 2584, 2851, 3132, 3425, 3730, 4047, 4375, 4713, 5060, + 5417, 5781, 6154, 6533, 6918, 7308, 7702, 8100, 8500, 8902, 9304, 9706, 10106, 10504, + 10899, 11290, 11675, 12054, 12427, 12792, 13148, 13496, 13833, 14160, 14475, 14779, 15071, 15350, + 15616, 15868, 16107, 16331, 16542, 16737, 16919, 17085, 17237, 17375, 17498, 17607, 17702, 17782, + 17850, 17904, 17946, 17975, 17993, 18000, 17997, 17984, 17963, 17934, 17897, 17854, 17805, 17752, + 17695, 17634, 17571, 17506, 17440, 17375, 17310, 17246, 17190, 17128, 17071, 17019, 16972, 16930, + 16893, 16860, 16832, 16808, 16789, 16773, 16762, 16754, 16750, 16749, 16751, 16756, 16764, 16774, + 16786, 16800, 16816, 16833, 16852, 16871, 16891, 16911, -16932, -16952, -16972, -16991, -17010, -17027, + -17043, -17058, -17070, -17080, -17088, -17093, -17095, -17094, -17090, -17082, -17071, -17055, -17035, -17011, + -16983, -16950, -16913, -16871, -16824, -16773, -16717, -16657, -16581, -16503, -16417, -16322, -16218, -16104, + -15979, -15843, -15696, -15536, -15364, -15179, -14981, -14770, -14545, -14307, -14055, -13790, -13511, -13220, + -12916, -12599, -12271, -11932, -11582, -11223, -10855, -10478, -10095, -9705, -9310, -8910, -8508, -8103, + -7697, -7291, -6887, -6485, -6086, -5692, -5305, -4924, -4552, -4189, -3838, -3497, -3170, -2855, + -2555, -2270, -2001, -1748, -1511, -1292, -1090, -906, -740, -592, -462, -350, -256, -178, + -116, -68}; + +RAM_ALIGN const Word16 LowDelayShapes_n960_N180_7_5ms[318] = { + 54, 82, 114, 153, 198, 251, 312, 380, 458, 543, 638, 742, 856, 978, + 1111, 1253, 1405, 1566, 1738, 1920, 2111, 2313, 2525, 2747, 2980, 3222, 3474, 3737, + 4009, 4291, 4582, 4883, 5193, 5512, 5840, 6177, 6521, 6874, 7235, 7602, 7978, 8359, + 8747, 9141, 9541, 9947, 10357, 10772, 11191, 11614, 12041, 12470, 12902, 13336, 13771, 14208, + 14646, 15084, 15521, 15958, 16394, 16829, 17261, 17691, 18118, 18541, 18961, 19376, 19787, 20193, + 20593, 20987, 21375, 21757, 22131, 22499, 22858, 23210, 23553, 23889, 24215, 24532, 24841, 25140, + 25430, 25709, 25979, 26239, 26488, 26728, 26957, 27175, 27383, 27580, 27767, 27943, 28109, 28264, + 28409, 28543, 28666, 28779, 28882, 28975, 29058, 29132, 29195, 29250, 29295, 29332, 29359, 29379, + 29391, 29394, 29391, 29380, 29363, 29340, 29311, 29276, 29236, 29192, 29143, 29090, 29033, 28974, + 28911, 28846, 28779, 28710, 28640, 28569, 28498, 28426, 28355, 28284, 28214, 28145, 28090, 28019, + 27954, 27892, 27833, 27779, 27728, 27680, 27636, 27595, 27558, 27524, 27494, 27466, 27442, 27421, + 27403, 27387, 27375, 27365, 27358, 27353, 27351, 27351, 27354, 27358, 27365, 27373, 27383, 27395, + 27408, 27423, 27439, 27456, 27474, 27493, 27513, 27534, 27555, 27577, 27599, 27621, -27644, -27666, + -27688, -27710, -27731, -27752, -27772, -27792, -27810, -27827, -27844, -27859, -27872, -27884, -27894, -27903, + -27909, -27914, -27916, -27917, -27914, -27910, -27902, -27892, -27880, -27864, -27846, -27824, -27800, -27772, + -27741, -27707, -27670, -27629, -27585, -27538, -27487, -27433, -27375, -27315, -27251, -27182, -27096, -27014, + -26927, -26833, -26733, -26626, -26513, -26393, -26265, -26129, -25985, -25833, -25673, -25504, -25325, -25138, + -24941, -24735, -24520, -24294, -24060, -23815, -23561, -23296, -23022, -22738, -22445, -22141, -21829, -21507, + -21176, -20836, -20487, -20130, -19764, -19391, -19010, -18622, -18228, -17827, -17420, -17007, -16590, -16167, + -15741, -15311, -14877, -14441, -14003, -13563, -13122, -12680, -12238, -11796, -11356, -10917, -10481, -10047, + -9616, -9190, -8767, -8350, -7939, -7534, -7135, -6744, -6361, -5986, -5620, -5264, -4916, -4579, + -4253, -3937, -3632, -3339, -3058, -2788, -2530, -2285, -2053, -1833, -1626, -1432, -1251, -1083, + -929, -788, -659, -544, -441, -351, -272, -205, -148, -106}; + +RAM_ALIGN const Word16 LowDelayShapes_n960_N240_7_5ms[424] = { + 44, 61, 81, 103, 128, 156, 188, 224, 263, 306, 354, 405, 461, 521, + 586, 655, 728, 806, 889, 977, 1069, 1166, 1268, 1375, 1486, 1602, 1724, 1850, + 1981, 2117, 2258, 2404, 2555, 2711, 2871, 3037, 3207, 3382, 3562, 3747, 3936, 4130, + 4329, 4531, 4739, 4950, 5166, 5386, 5610, 5838, 6069, 6305, 6544, 6786, 7032, 7281, + 7533, 7788, 8046, 8307, 8570, 8836, 9104, 9374, 9646, 9920, 10196, 10474, 10753, 11033, + 11314, 11596, 11879, 12163, 12447, 12731, 13015, 13300, 13584, 13868, 14151, 14433, 14715, 14995, + 15274, 15552, 15828, 16103, 16375, 16646, 16914, 17180, 17444, 17704, 17963, 18218, 18470, 18719, + 18964, 19206, 19445, 19680, 19911, 20138, 20361, 20580, 20795, 21006, 21212, 21414, 21611, 21804, + 21992, 22175, 22354, 22527, 22696, 22860, 23018, 23172, 23321, 23464, 23603, 23736, 23864, 23988, + 24106, 24218, 24326, 24428, 24525, 24618, 24705, 24786, 24863, 24935, 25002, 25064, 25121, 25174, + 25221, 25264, 25303, 25336, 25366, 25391, 25412, 25428, 25441, 25450, 25455, 25456, 25454, 25448, + 25439, 25427, 25412, 25394, 25373, 25350, 25324, 25296, 25265, 25233, 25198, 25162, 25124, 25085, + 25045, 25003, 24960, 24916, 24871, 24826, 24780, 24734, 24688, 24641, 24595, 24548, 24502, 24457, + 24412, 24367, 24334, 24287, 24244, 24202, 24162, 24123, 24086, 24051, 24018, 23987, 23957, 23929, + 23902, 23878, 23855, 23833, 23813, 23795, 23778, 23763, 23749, 23737, 23726, 23717, 23709, 23702, + 23696, 23692, 23689, 23687, 23687, 23687, 23689, 23691, 23695, 23699, 23705, 23711, 23718, 23726, + 23735, 23744, 23754, 23764, 23776, 23787, 23799, 23812, 23825, 23838, 23852, 23866, 23880, 23894, + 23909, 23923, -23938, -23952, -23967, -23981, -23995, -24009, -24023, -24036, -24049, -24062, -24074, -24086, + -24097, -24108, -24118, -24128, -24137, -24145, -24152, -24158, -24164, -24168, -24172, -24175, -24176, -24177, + -24176, -24174, -24171, -24167, -24161, -24154, -24146, -24136, -24125, -24113, -24099, -24083, -24066, -24048, + -24028, -24006, -23983, -23958, -23932, -23904, -23874, -23843, -23810, -23775, -23739, -23701, -23662, -23621, + -23579, -23533, -23474, -23423, -23367, -23309, -23248, -23184, -23117, -23047, -22974, -22896, -22816, -22732, + -22643, -22551, -22455, -22355, -22251, -22143, -22030, -21913, -21791, -21665, -21534, -21399, -21259, -21114, + -20964, -20810, -20651, -20488, -20319, -20146, -19968, -19785, -19598, -19405, -19208, -19007, -18801, -18590, + -18375, -18156, -17932, -17704, -17472, -17236, -16996, -16752, -16505, -16254, -16000, -15743, -15482, -15219, + -14953, -14684, -14412, -14139, -13863, -13586, -13306, -13025, -12743, -12459, -12174, -11889, -11603, -11316, + -11029, -10742, -10455, -10168, -9882, -9597, -9313, -9029, -8748, -8467, -8189, -7912, -7638, -7367, + -7097, -6831, -6568, -6308, -6052, -5799, -5550, -5305, -5065, -4828, -4597, -4369, -4147, -3930, + -3718, -3511, -3310, -3113, -2923, -2738, -2559, -2386, -2219, -2057, -1902, -1753, -1610, -1474, + -1344, -1220, -1102, -991, -887, -788, -697, -611, -532, -459, -393, -332, -277, -228, + -184, -145, -111, -86}; + +RAM_ALIGN const Word16 LowDelayShapes_n960_N360_7_5ms[636] = { + 34, 43, 53, 63, 74, 87, 101, 116, 132, 149, 168, 188, 209, 232, + 256, 282, 309, 338, 368, 400, 434, 469, 506, 544, 584, 626, 669, 715, + 761, 810, 860, 912, 966, 1021, 1078, 1137, 1198, 1260, 1325, 1391, 1458, 1528, + 1599, 1673, 1747, 1824, 1903, 1983, 2065, 2149, 2235, 2322, 2411, 2502, 2595, 2690, + 2786, 2884, 2983, 3085, 3188, 3293, 3399, 3507, 3617, 3728, 3841, 3955, 4071, 4188, + 4307, 4428, 4550, 4673, 4798, 4924, 5051, 5180, 5310, 5442, 5574, 5708, 5843, 5979, + 6116, 6255, 6394, 6534, 6676, 6818, 6961, 7106, 7251, 7397, 7543, 7691, 7839, 7988, + 8137, 8288, 8438, 8590, 8741, 8894, 9046, 9199, 9353, 9507, 9661, 9815, 9969, 10124, + 10279, 10434, 10588, 10743, 10898, 11053, 11207, 11362, 11516, 11670, 11823, 11976, 12129, 12282, + 12434, 12585, 12736, 12886, 13036, 13185, 13333, 13481, 13628, 13774, 13919, 14064, 14207, 14349, + 14491, 14631, 14771, 14909, 15046, 15183, 15317, 15451, 15584, 15715, 15845, 15973, 16100, 16226, + 16350, 16473, 16595, 16715, 16833, 16950, 17065, 17179, 17292, 17402, 17511, 17619, 17724, 17829, + 17931, 18032, 18130, 18228, 18323, 18417, 18508, 18598, 18687, 18773, 18858, 18941, 19021, 19101, + 19178, 19253, 19327, 19398, 19468, 19536, 19602, 19666, 19729, 19789, 19847, 19904, 19959, 20012, + 20063, 20112, 20160, 20205, 20249, 20291, 20331, 20369, 20405, 20440, 20473, 20504, 20533, 20561, + 20587, 20611, 20634, 20654, 20674, 20691, 20707, 20722, 20735, 20746, 20756, 20764, 20771, 20777, + 20781, 20783, 20785, 20785, 20784, 20781, 20777, 20773, 20767, 20759, 20751, 20742, 20732, 20720, + 20708, 20695, 20681, 20666, 20650, 20633, 20616, 20598, 20579, 20560, 20540, 20519, 20498, 20477, + 20455, 20432, 20409, 20386, 20362, 20338, 20314, 20289, 20264, 20239, 20214, 20189, 20164, 20138, + 20113, 20088, 20063, 20037, 20012, 19988, 19963, 19939, 19914, 19891, 19874, 19849, 19825, 19801, + 19778, 19755, 19733, 19712, 19691, 19671, 19652, 19633, 19615, 19598, 19581, 19565, 19549, 19534, + 19520, 19506, 19493, 19480, 19468, 19457, 19446, 19436, 19426, 19417, 19408, 19400, 19393, 19386, + 19380, 19374, 19368, 19363, 19359, 19355, 19352, 19349, 19346, 19344, 19342, 19341, 19340, 19340, + 19340, 19341, 19341, 19343, 19344, 19346, 19348, 19351, 19354, 19357, 19361, 19365, 19369, 19373, + 19378, 19383, 19388, 19394, 19399, 19405, 19411, 19417, 19424, 19430, 19437, 19444, 19451, 19458, + 19466, 19473, 19481, 19488, 19496, 19504, 19512, 19519, 19527, 19535, -19543, -19551, -19559, -19567, + -19574, -19582, -19590, -19598, -19605, -19613, -19620, -19627, -19634, -19641, -19648, -19655, -19661, -19668, + -19674, -19680, -19686, -19691, -19696, -19701, -19706, -19711, -19715, -19719, -19723, -19726, -19729, -19732, + -19734, -19736, -19737, -19739, -19740, -19740, -19740, -19740, -19739, -19738, -19736, -19734, -19731, -19728, + -19725, -19721, -19716, -19711, -19706, -19700, -19693, -19686, -19679, -19671, -19662, -19653, -19643, -19632, + -19622, -19610, -19598, -19585, -19572, -19558, -19544, -19529, -19513, -19497, -19481, -19463, -19445, -19427, + -19408, -19388, -19368, -19347, -19325, -19303, -19281, -19258, -19234, -19209, -19175, -19146, -19117, -19087, + -19056, -19024, -18991, -18956, -18921, -18885, -18847, -18808, -18768, -18727, -18684, -18640, -18595, -18548, + -18500, -18451, -18400, -18348, -18294, -18239, -18182, -18124, -18064, -18003, -17940, -17875, -17809, -17741, + -17671, -17600, -17528, -17453, -17377, -17299, -17219, -17138, -17055, -16970, -16884, -16795, -16705, -16614, + -16520, -16425, -16328, -16230, -16129, -16027, -15923, -15818, -15711, -15602, -15491, -15379, -15265, -15150, + -15033, -14914, -14794, -14672, -14549, -14424, -14297, -14170, -14041, -13910, -13778, -13645, -13510, -13374, + -13237, -13099, -12959, -12819, -12677, -12534, -12390, -12245, -12099, -11952, -11805, -11656, -11507, -11357, + -11206, -11055, -10903, -10750, -10597, -10443, -10289, -10134, -9979, -9824, -9668, -9512, -9356, -9200, + -9044, -8888, -8732, -8575, -8419, -8263, -8108, -7952, -7797, -7642, -7488, -7334, -7181, -7028, + -6876, -6724, -6573, -6423, -6274, -6125, -5978, -5832, -5686, -5542, -5398, -5256, -5116, -4976, + -4838, -4701, -4565, -4431, -4299, -4168, -4038, -3911, -3784, -3660, -3537, -3416, -3297, -3180, + -3064, -2951, -2839, -2729, -2622, -2516, -2412, -2311, -2211, -2114, -2018, -1925, -1834, -1745, + -1658, -1574, -1492, -1412, -1334, -1258, -1185, -1114, -1046, -980, -916, -854, -795, -738, + -683, -631, -581, -533, -488, -445, -404, -366, -329, -295, -263, -233, -206, -180, + -156, -134, -114, -95, -79, -62}; + +const Word16 *const LowDelayShapes_n960_7_5ms[5] = { + LowDelayShapes_n960_N60_7_5ms, LowDelayShapes_n960_N120_7_5ms, LowDelayShapes_n960_N180_7_5ms, + LowDelayShapes_n960_N240_7_5ms, LowDelayShapes_n960_N360_7_5ms}; +# endif +#endif + +# ifdef ENABLE_HR_MODE +# ifdef SUBSET_NB +RAM_ALIGN const Word32 MDCT_WINDOW_FS_8000_frame_ms_100[130] = { + -961400, -2849747, -6146069, -11183287, -18168658, -27159976, -38041614, -50544991, -64266305, + -78702302, -93275005, -107359966, -120331449, -131585369, -140567185, -146788394, -149841031, -149374845, + -145077849, -136659567, -123818556, -106218681, -83483575, -55188103, -20866242, 19967468, 67769998, + 122921021, 185652202, 255975827, 333632994, 418021593, 508185345, 602779388, 700109939, 798161092, + 894722554, 987480940, 1074157272, 1152645644, 1221190247, 1278509567, 1323911980, 1357388583, 1379593462, + 1391784272, 1395720478, 1393489246, 1387290092, 1379158144, 1370909958, 1362952657, 1356680081, 1351822616, + 1348129706, 1345389974, 1343434137, 1342132875, 1341380238, 1341082389, 1341146030, 1341475565, 1341976666, + 1342558820, 1343143270, 1343665484, 1344082633, 1344377759, 1344564351, 1344687981, 1344819951, 1345048163, + 1345462207, 1346140636, 1347141158, 1348493131, 1350195802, 1352216474, 1354492706, 1356936321, -1359440659, + -1361893201, -1364185723, -1366227332, -1367952395, -1369325253, -1370343007, -1371033982, -1371456025, -1371688758, + -1371823378, -1371949513, -1372139932, -1372441219, -1372867302, -1373401073, -1373998949, -1374594994, -1375108467, + -1375446347, -1375511619, -1375206190, -1374435007, -1373103717, -1371107592, -1368321163, -1364583182, -1359697421, + -1353439826, -1345583929, -1334252006, -1318640435, -1296625734, -1266042179, -1224814360, -1171299094, -1104589425, + -1024691930, -932610693, -830326556, -720679178, -607287900, -494260157, -385949065, -286606097, -199964372, + -128792415, -74461791, -36690922, -13577456 }; +# else +# define MDCT_WINDOW_FS_8000_frame_ms_100 NULL +# endif +# ifdef SUBSET_WB +Word32 MDCT_WINDOW_FS_16000_frame_ms_100[260] = { + -887375, -1872204, -3197066, -4988439, -7310990, -10227337, -13783209, -18021567, -22958367, + -28610377, -34970773, -42018157, -49718535, -58023758, -66873408, -76198163, -85910142, -95927481, + -106148057, -116469926, -126789141, -136988509, -146961365, -156599505, -165784108, -174413613, -182384155, + -189593925, -195957243, -201380750, -205787662, -209112092, -211278626, -212225338, -211904063, -210251417, + -207219014, -202758648, -196811500, -189330359, -180258003, -169532917, -157095614, -142881796, -126812734, + -108824087, -88825077, -66738724, -42479347, -15962398, 12903137, 44189991, 77985216, 114347898, + 153341694, 195002709, 239360583, 286415769, 336147305, 388513668, 443439084, 500814289, 560507827, + 622347139, 686131895, 751624641, 818548945, 886612081, 955480469, 1024792378, 1094174334, 1163233060, + 1231563801, 1298756609, 1364398281, 1428080024, 1489417472, 1548030726, 1603570137, 1655722624, 1704220353, + 1748832761, 1789380048, 1825732185, 1857837021, 1885694068, 1909350182, 1928926255, 1944599555, 1956591988, + 1965173692, 1970654814, 1973392048, 1973753741, 1972126549, 1968905622, 1964477747, 1959200677, 1953414096, + 1947497068, 1941982397, 1935699544, 1930081097, 1925079908, 1920651209, 1916744799, 1913315837, 1910318315, + 1907712617, 1905458724, 1903525160, 1901880657, 1900501434, 1899362031, 1898444320, 1897728470, 1897199074, + 1896837448, 1896629442, 1896556474, 1896603942, 1896753023, 1896988900, 1897292512, 1897649018, 1898040860, + 1898455207, 1898875282, 1899290274, 1899686952, 1900057791, 1900392969, 1900688703, 1900940068, 1901148890, + 1901315261, 1901446916, 1901549632, 1901635772, 1901716579, 1901808596, 1901925470, 1902085313, 1902301944, + 1902593430, 1902971628, 1903450623, 1904038863, 1904746055, 1905575675, 1906532421, 1907613683, 1908818837, + 1910139810, 1911570484, 1913097876, 1914709921, 1916389064, 1918119705, 1919880868, -1921655075, -1923419485, + -1925156475, -1926844779, -1928468408, -1930009301, -1931454857, -1932791495, -1934012556, -1935109403, -1936080977, + -1936924245, -1937643651, -1938242459, -1938730331, -1939115713, -1939412840, -1939633721, -1939796733, -1939915942, + -1940009808, -1940092245, -1940180131, -1940284940, -1940419293, -1940589100, -1940802279, -1941058948, -1941361010, + -1941703474, -1942082515, -1942488131, -1942912654, -1943342567, -1943766803, -1944168168, -1944533482, -1944844704, + -1945086561, -1945239453, -1945288139, -1945213300, -1944999989, -1944629251, -1944086772, -1943353711, -1942414745, + -1941250214, -1939842441, -1938166561, -1936199807, -1933912258, -1931274378, -1928248720, -1924799179, -1920884332, + -1916465285, -1911499377, -1905951172, -1899784891, -1891449639, -1882086102, -1871092605, -1858022426, -1842504117, + -1824150091, -1802570281, -1777395508, -1748280284, -1714926445, -1677106435, -1634654127, -1587483810, -1535592652, + -1479074019, -1418108336, -1352953154, -1283959587, -1211573312, -1136287716, -1058670176, -979383239, -899114678, + -818587615, -738568308, -659827651, -583145988, -509279027, -438949979, -372825231, -311497711, -255465040, + -205107348, -160673323, -122260482, -89825442, -63156242, -41931466, -25668784, -12980788 }; +# else +# define MDCT_WINDOW_FS_16000_frame_ms_100 NULL +# endif +# ifdef SUBSET_SSWB +Word32 MDCT_WINDOW_FS_24000_frame_ms_100[390] = { + -566705, -1110129, -1685050, -2404955, -3290604, -4357398, -5620992, -7096870, -8797110, + -10732247, -12913348, -15346312, -18033576, -20979359, -24186040, -27648819, -31361639, -35319387, + -39511857, -43926672, -48550894, -53369201, -58364329, -63516998, -68804773, -74208337, -79706124, + -85271101, -90877590, -96504202, -102123140, -107704698, -113222623, -118652834, -123968611, -129140789, + -134141816, -138946789, -143532274, -147872644, -151941696, -155718471, -159183810, -162313004, -165085094, + -167485061, -169496638, -171101141, -172281631, -173021519, -173310456, -173136812, -172483214, -171335676, + -169686052, -167521471, -164827705, -161591409, -157800875, -153444385, -148507128, -142973353, -136828628, + -130059834, -122650769, -114582255, -105836248, -96398529, -86248633, -75363800, -63725732, -51315501, + -38111620, -24094261, -9239538, 6471742, 23056447, 40536457, 58931280, 78254053, 98521159, + 119745967, 141936970, 165102364, 189247343, 214372698, 240474371, 267544931, 295575426, 324551903, + 354450456, 385246198, 416908490, 449403326, 482689758, 516718794, 551441284, 586801891, 622731215, + 659163373, 696029684, 733249762, 770740975, 808417324, 846185475, 883956761, 921637043, 959124688, + 996324031, 1033136615, 1069460208, 1105195788, 1140244773, 1174510921, 1207903363, 1240329980, 1271701586, + 1301936917, 1330960546, 1358704531, 1385106661, 1410109035, 1433668094, 1455740664, 1476295686, 1495314659, + 1512790051, 1528721877, 1543118961, 1555993720, 1567377327, 1577311901, 1585840140, 1593017314, 1598905809, + 1603572858, 1607094048, 1609553036, 1611038032, 1611639187, 1611445924, 1610554709, 1609062783, 1607062660, + 1604647205, 1601904616, 1598915994, 1595761439, 1592514651, 1589411075, 1586578699, 1582990467, 1579691165, + 1576632996, 1573802167, 1571187222, 1568776964, 1566559220, 1564523108, 1562656830, 1560950303, 1559392538, + 1557974462, 1556686097, 1555520279, 1554467590, 1553522528, 1552677071, 1551926380, 1551264122, 1550685851, + 1550186120, 1549761554, 1549406743, 1549118648, 1548892484, 1548724782, 1548611579, 1548548556, 1548532064, + 1548557824, 1548622043, 1548720068, 1548848512, 1549002557, 1549178941, 1549372811, 1549581179, 1549799479, + 1550025081, 1550253392, 1550482320, 1550707996, 1550928257, 1551140242, 1551341918, 1551531258, 1551707132, + 1551867783, 1552012940, 1552142171, 1552255441, 1552353722, 1552437360, 1552508729, 1552569181, 1552621341, + 1552667742, 1552711935, 1552756861, 1552806540, 1552864321, 1552934727, 1553021212, 1553127838, 1553258419, + 1553416594, 1553605935, 1553829154, 1554089545, 1554389317, 1554730803, 1555115388, 1555544621, 1556019161, + 1556539764, 1557105744, 1557717296, 1558373006, 1559071819, 1559811599, 1560590143, 1561405090, 1562252936, + 1563130339, 1564033457, 1564958401, 1565900358, 1566855101, 1567817123, -1568783655, -1569746861, -1570703949, + -1571649364, -1572578812, -1573487389, -1574371102, -1575225988, -1576048579, -1576835227, -1577583436, -1578290863, + -1578955234, -1579575367, -1580149723, -1580678399, -1581160607, -1581597028, -1581988259, -1582335808, -1582641029, + -1582906248, -1583133678, -1583326640, -1583487877, -1583621010, -1583729737, -1583817938, -1583889747, -1583948684, + -1583999362, -1584045193, -1584090279, -1584137621, -1584190841, -1584252527, -1584325358, -1584410718, -1584511035, + -1584626668, -1584758614, -1584906848, -1585070936, -1585250612, -1585444090, -1585650227, -1585866958, -1586092212, + -1586323072, -1586557326, -1586791018, -1587022005, -1587245580, -1587459040, -1587657701, -1587838487, -1587996409, + -1588128112, -1588228637, -1588294501, -1588320923, -1588304007, -1588239369, -1588123278, -1587951328, -1587719494, + -1587424275, -1587060842, -1586626176, -1586114863, -1585523601, -1584847006, -1584080761, -1583218674, -1582256132, + -1581185350, -1580001184, -1578694604, -1577258975, -1575684935, -1573964180, -1572086641, -1570043344, -1567823810, + -1565418712, -1562817696, -1560011672, -1556991601, -1553746487, -1550232508, -1545614483, -1540661510, -1535326382, + -1529347469, -1522634820, -1515104434, -1506662411, -1497214433, -1486667044, -1474925134, -1461899585, -1447505979, + -1431661421, -1414293801, -1395342396, -1374757780, -1352499694, -1328538688, -1302862307, -1275470003, -1246373968, + -1215606643, -1183212323, -1149244754, -1113774081, -1076886070, -1038679407, -999271421, -958778521, -917331256, + -875071965, -832168635, -788780400, -745078907, -701235665, -657439320, -613872407, -570722470, -528178104, + -486428392, -445655594, -406038238, -367747699, -330944214, -295781070, -262392452, -230898968, -201404745, + -173990773, -148716671, -125619512, -104711740, -85981071, -69390841, -54880490, -42367028, -31748204, + -22909680, -15677896, -8320202 }; +# else +# define MDCT_WINDOW_FS_24000_frame_ms_100 NULL +# endif +# ifdef SUBSET_SWB +Word32 MDCT_WINDOW_FS_32000_frame_ms_100[520] = { + -410329, -796949, -1136328, -1530183, -1997206, -2544529, -3177199, -3900727, -4721409, + -5644580, -6674901, -7816606, -9073542, -10449649, -11947654, -13568981, -15314575, -17185616, + -19183576, -21308469, -23557934, -25929130, -28420717, -31030313, -33753791, -36586142, -39522623, + -42558881, -45688908, -48905915, -52203334, -55573600, -59008578, -62500911, -66043225, -69627153, + -73242249, -76878656, -80528547, -84184130, -87834359, -91467738, -95074499, -98645962, -102173556, + -105646999, -109055430, -112389025, -115637823, -118792264, -121843979, -124784385, -127604158, -130292837, + -132842231, -135246333, -137497670, -139586545, -141504332, -143245396, -144804682, -146175706, -147351477, + -148325994, -149093197, -149646348, -149980871, -150094482, -149982174, -149636889, -149052616, -148226262, + -147155224, -145834061, -144257234, -142420419, -140318794, -137947501, -135302755, -132379903, -129173499, + -125677248, -121885484, -117793976, -113398013, -108690888, -103666131, -98316590, -92636250, -86619948, + -80260566, -73550172, -66480755, -59045143, -51237113, -43048956, -34473252, -25502546, -16127957, + -6341514, 3862818, 14491541, 25552349, 37053485, 49000846, 61399638, 74255377, 87574137, + 101359692, 115615618, 130345077, 145550314, 161232640, 177393068, 194030243, 211141818, 228724496, + 246775667, 265291298, 284263733, 303683434, 323542122, 343829307, 364532416, 385638632, 407133703, + 428999825, 451218622, 473771892, 496640476, 519799290, 543222449, 566886347, 590766871, 614834881, + 639060282, 663412218, 687860455, 712370477, 736908535, 761442526, 785938885, 810359699, 834668800, + 858831376, 882812136, 906573323, 930077938, 953289749, 976173461, 998692986, 1020814305, 1042504195, + 1063729320, 1084456529, 1104654343, 1124293323, 1143346837, 1161788685, 1179595571, 1196744793, 1213214499, + 1228990130, 1244053625, 1258390343, 1271989157, 1284842646, 1296945646, 1308295983, 1318894029, 1328742964, + 1337845893, 1346207620, 1353840346, 1360760354, 1366981286, 1372519590, 1377396138, 1381633759, 1385255026, + 1388285177, 1390752262, 1392686884, 1394119237, 1395082423, 1395609697, 1395734288, 1395488163, 1394907750, + 1394029226, 1392887172, 1391513953, 1389943438, 1388208885, 1386340921, 1384367440, 1382316364, 1380214130, + 1378106162, 1376182641, 1374415552, 1372026612, 1369811233, 1367710559, 1365724178, 1363849407, 1362082203, + 1360417744, 1358852161, 1357381258, 1356001076, 1354706993, 1353494673, 1352361089, 1351302228, 1350313689, + 1349392506, 1348535330, 1347739116, 1347001032, 1346317031, 1345686404, 1345105561, 1344572298, 1344084536, + 1343640384, 1343238137, 1342875748, 1342550922, 1342263301, 1342010831, 1341791477, 1341604203, 1341447356, + 1341320237, 1341220346, 1341146654, 1341097800, 1341072665, 1341069082, 1341085615, 1341121386, 1341174740, + 1341243587, 1341326852, 1341422956, 1341530950, 1341648658, 1341774344, 1341907686, 1342046793, 1342189996, + 1342336371, 1342484315, 1342633509, 1342781772, 1342928111, 1343072442, 1343213120, 1343349339, 1343480101, + 1343605189, 1343724192, 1343836029, 1343940104, 1344037064, 1344126250, 1344207727, 1344281010, 1344347228, + 1344406398, 1344458631, 1344504740, 1344545486, 1344582197, 1344614878, 1344644716, 1344673602, 1344702406, + 1344732123, 1344764116, 1344799913, 1344841581, 1344889533, 1344945396, 1345011275, 1345087987, 1345177164, + 1345279600, 1345397199, 1345531309, 1345682002, 1345850876, 1346039023, 1346247352, 1346476070, 1346725599, + 1346997017, 1347290788, 1347606421, 1347944342, 1348304546, 1348687326, 1349091759, 1349517389, 1349964590, + 1350432001, 1350919119, 1351424549, 1351948150, 1352488782, 1353044492, 1353614173, 1354196920, 1354791164, + 1355395130, 1356006741, 1356625062, 1357248513, 1357874066, -1358501833, -1359127963, -1359752565, -1360372594, + -1360986451, -1361593178, -1362190669, -1362777107, -1363350886, -1363911059, -1364456475, -1364985125, -1365495818, + -1365988370, -1366461329, -1366914145, -1367345397, -1367755425, -1368143727, -1368509329, -1368852492, -1369173176, + -1369471783, -1369747786, -1370001627, -1370234382, -1370446455, -1370638040, -1370810046, -1370963570, -1371100229, + -1371220085, -1371324505, -1371415420, -1371493639, -1371560818, -1371617789, -1371666695, -1371709196, -1371745710, + -1371778346, -1371808661, -1371838047, -1371867517, -1371897959, -1371931304, -1371968763, -1372010342, -1372057396, + -1372110702, -1372171094, -1372238686, -1372313498, -1372396683, -1372487751, -1372586771, -1372693072, -1372807320, + -1372928910, -1373056739, -1373190393, -1373329652, -1373473500, -1373621114, -1373770813, -1373922515, -1374075203, + -1374226645, -1374376513, -1374523166, -1374665655, -1374802265, -1374931057, -1375051695, -1375162397, -1375260925, + -1375346302, -1375416903, -1375471622, -1375508310, -1375525267, -1375521592, -1375495812, -1375445706, -1375370134, + -1375267707, -1375137383, -1374976617, -1374784711, -1374559999, -1374301455, -1374007032, -1373674676, -1373304076, + -1372892947, -1372439276, -1371941405, -1371397503, -1370805562, -1370163465, -1369467701, -1368717718, -1367909588, + -1367040649, -1366108055, -1365108685, -1364039842, -1362897427, -1361677778, -1360378277, -1358995048, -1357523990, + -1355961737, -1354304757, -1352549921, -1350693234, -1348731568, -1346663222, -1344488796, -1342151873, -1339094859, + -1335868526, -1332575618, -1329015998, -1325134514, -1320899332, -1316281926, -1311249778, -1305767783, -1299801189, + -1293316467, -1286278496, -1278652937, -1270407089, -1261510752, -1251931832, -1241641304, -1230612600, -1218823121, + -1206251778, -1192882032, -1178699247, -1163691417, -1147850058, -1131172617, -1113659053, -1095312137, -1076139342, + -1056154695, -1035374650, -1013817533, -991505119, -968465043, -944729088, -920331658, -895311402, -869713787, + -843580319, -816956722, -789893244, -762442487, -734669461, -706629428, -678385082, -649998064, -621530231, + -593051422, -564628794, -536328929, -508220768, -480373259, -452855166, -425735746, -399081503, -372957401, + -347428629, -322556345, -298398778, -275013415, -252453167, -230765335, -209993816, -190178661, -171354066, + -153547820, -136781064, -121069202, -106422336, -92843298, -80326106, -68858674, -58425411, -49003701, + -40559788, -33054527, -26453090, -20722011, -15806421, -11453718, -6043487 }; +# else +# define MDCT_WINDOW_FS_32000_frame_ms_100 NULL +# endif +# ifdef SUBSET_FB +Word32 MDCT_WINDOW_FS_48000_frame_ms_100[780] = { + -260941, -512326, -694531, -879311, -1080918, -1308853, -1562751, -1845827, -2158684, + -2503004, -2880077, -3290946, -3737685, -4221002, -4742864, -5303548, -5904756, -6546614, + -7230857, -7957740, -8729060, -9544323, -10404756, -11309433, -12259734, -13255019, -14296724, + -15384139, -16518209, -17697344, -18921986, -20190385, -21503384, -22859520, -24259194, -25700342, + -27183029, -28705009, -30266328, -31864635, -33500032, -35169872, -36873876, -38609380, -40375887, + -42170731, -43993030, -45839524, -47709533, -49600244, -51511244, -53439376, -55383757, -57340675, + -59308752, -61284610, -63267293, -65253972, -67243943, -69233263, -71220507, -73201745, -75175694, + -77138930, -79090353, -81026756, -82947219, -84848184, -86728232, -88583507, -90412766, -92212306, + -93980997, -95715499, -97414829, -99075933, -100697747, -102276727, -103811934, -105299541, -106738717, + -108126346, -109462104, -110743333, -111969072, -113135967, -114242829, -115286640, -116267230, -117181898, + -118030913, -118811562, -119523250, -120163192, -120730923, -121223904, -121641755, -121981772, -122243774, + -122425704, -122528356, -122549198, -122488317, -122342868, -122112204, -121794056, -121388712, -120894363, + -120311595, -119637953, -118873094, -118014671, -117062760, -116014831, -114871079, -113629173, -112289425, + -110849719, -109309933, -107667532, -105922420, -104072007, -102115976, -100051888, -97879875, -95597465, + -93204875, -90699195, -88080200, -85345024, -82492843, -79520968, -76429175, -73215366, -69879179, + -66417490, -62829616, -59111848, -55264005, -51283182, -47168943, -42918760, -38531620, -34004372, + -29336594, -24525462, -19570192, -14467231, -9215895, -3812888, 1741410, 7449630, 13312759, + 19333517, 25513103, 31854549, 38357631, 45024786, 51855914, 58853769, 66018789, 73353520, + 80857218, 88531868, 96377212, 104395033, 112584867, 120948431, 129484622, 138194897, 147077806, + 156134120, 165362222, 174762717, 184333381, 194074737, 203984869, 214063752, 224308471, 234717970, + 245288658, 256019674, 266907692, 277950967, 289145264, 300489211, 311977987, 323609345, 335378203, + 347280982, 359312288, 371469093, 383745604, 396138434, 408640853, 421247404, 433950689, 446746484, + 459627611, 472589454, 485624370, 498725842, 511885724, 525097999, 538353697, 551646906, 564968308, + 578310445, 591664155, 605022969, 618377829, 631721846, 645044713, 658338326, 671592921, 684801497, + 697954218, 711043692, 724059806, 736994360, 749837478, 762581648, 775216823, 787735715, 800128161, + 812386829, 824502387, 836468309, 848275065, 859915578, 871380881, 882663894, 893755956, 904651429, + 915341669, 925821650, 936083534, 946122397, 955931903, 965507514, 974842174, 983932079, 992771963, + 1001359538, 1009689065, 1017758097, 1025562027, 1033099052, 1040366302, 1047363095, 1054086968, 1060539102, + 1066717272, 1072622704, 1078255082, 1083616279, 1088705978, 1093526428, 1098077639, 1102363841, 1106387711, + 1110154526, 1113666093, 1116927603, 1119941829, 1122715077, 1125251563, 1127558143, 1129638911, 1131501374, + 1133150240, 1134593560, 1135837167, 1136890075, 1137758087, 1138450616, 1138974310, 1139338430, 1139549551, + 1139617253, 1139547254, 1139350624, 1139033981, 1138607794, 1138078811, 1137457063, 1136748191, 1135963275, + 1135107610, 1134191756, 1133220410, 1132203794, 1131145038, 1130056206, 1128938553, 1127804154, 1126651875, + 1125505224, 1124387956, 1123424960, 1122502936, 1121204059, 1119950632, 1118742198, 1117576653, 1116454214, + 1115372925, 1114332841, 1113331819, 1112370092, 1111445403, 1110557933, 1109705650, 1108888492, 1108104203, + 1107353139, 1106633126, 1105944161, 1105284140, 1104653414, 1104049906, 1103473745, 1102922793, 1102397465, + 1101895930, 1101418393, 1100962642, 1100529407, 1100117107, 1099725702, 1099353203, 1099000764, 1098666499, + 1098350488, 1098051309, 1097769862, 1097504226, 1097255015, 1097020632, 1096801846, 1096597180, 1096407228, + 1096230254, 1096067339, 1095917048, 1095779800, 1095654043, 1095540974, 1095438919, 1095348396, 1095268166, + 1095199173, 1095139611, 1095090409, 1095050175, 1095019519, 1094996963, 1094983471, 1094977391, 1094979525, + 1094988385, 1095004796, 1095027271, 1095056499, 1095090869, 1095131425, 1095176627, 1095227052, 1095281232, + 1095340201, 1095402343, 1095468278, 1095536534, 1095608171, 1095681620, 1095757514, 1095834402, 1095913392, + 1095992947, 1096073625, 1096154019, 1096235421, 1096316155, 1096396797, 1096476293, 1096555751, 1096633346, + 1096710075, 1096784773, 1096858327, 1096929351, 1096998877, 1097065514, 1097130458, 1097192392, 1097252182, + 1097308660, 1097363134, 1097414177, 1097462864, 1097508260, 1097551529, 1097591240, 1097628824, 1097663320, + 1097695680, 1097724878, 1097752577, 1097777519, 1097800889, 1097821938, 1097842083, 1097860192, 1097877707, + 1097893767, 1097909925, 1097925238, 1097941056, 1097956579, 1097973457, 1097990704, 1098009705, 1098029761, + 1098052600, 1098077182, 1098104865, 1098135087, 1098169468, 1098206820, 1098248699, 1098294539, 1098345796, + 1098401373, 1098462829, 1098529452, 1098602617, 1098681182, 1098766743, 1098858507, 1098957729, 1099063375, + 1099176931, 1099297350, 1099425943, 1099561602, 1099705648, 1099857107, 1100017184, 1100184629, 1100360829, + 1100544624, 1100737006, 1100936785, 1101145313, 1101361273, 1101585583, 1101817094, 1102057069, 1102303875, + 1102558446, 1102819734, 1103088684, 1103363640, 1103645734, 1103933619, 1104228082, 1104527573, 1104833025, + 1105142974, 1105458288, 1105777328, 1106100968, 1106427742, 1106758401, 1107091175, 1107426928, 1107764262, + 1108103811, 1108443736, 1108785137, -1109126464, -1109468075, -1109808418, -1110148595, -1110486758, -1110823540, + -1111157536, -1111489609, -1111817975, -1112143382, -1112464352, -1112781755, -1113093934, -1113401755, -1113703734, + -1114000803, -1114291390, -1114576277, -1114854097, -1115125982, -1115390248, -1115647841, -1115897690, -1116140732, + -1116375302, -1116602670, -1116821661, -1117033199, -1117235935, -1117431235, -1117617882, -1117796873, -1117967024, + -1118129738, -1118283734, -1118430232, -1118568236, -1118699084, -1118821642, -1118937239, -1119044805, -1119145850, + -1119239316, -1119326479, -1119406526, -1119481081, -1119548979, -1119611618, -1119668271, -1119720525, -1119767262, + -1119809963, -1119848051, -1119883112, -1119913933, -1119942166, -1119967238, -1119990533, -1120010991, -1120030373, + -1120047967, -1120065185, -1120081021, -1120097158, -1120112780, -1120129265, -1120145650, -1120163521, -1120181998, + -1120202553, -1120224032, -1120247880, -1120273333, -1120301601, -1120331401, -1120364428, -1120399639, -1120438004, + -1120478543, -1120522718, -1120569068, -1120618782, -1120670906, -1120726540, -1120784227, -1120845302, -1120908575, + -1120974930, -1121043024, -1121114079, -1121186673, -1121261863, -1121338234, -1121416691, -1121496045, -1121577316, + -1121658638, -1121741144, -1121823756, -1121907065, -1121989354, -1122071945, -1122153400, -1122234287, -1122313032, + -1122390771, -1122466015, -1122539413, -1122609356, -1122676929, -1122740622, -1122801070, -1122856613, -1122908312, + -1122954661, -1122996249, -1123031496, -1123061471, -1123084522, -1123101354, -1123110442, -1123112631, -1123106394, + -1123092556, -1123069422, -1123037982, -1122996721, -1122946267, -1122885196, -1122814464, -1122732221, -1122639444, + -1122534864, -1122419021, -1122290207, -1122149656, -1121995788, -1121829044, -1121647967, -1121453676, -1121244410, + -1121020792, -1120781333, -1120526836, -1120255693, -1119968555, -1119663488, -1119341437, -1119000986, -1118642248, + -1118263342, -1117865480, -1117446686, -1117006965, -1116544763, -1116060878, -1115553126, -1115021782, -1114465065, + -1113883468, -1113274918, -1112639632, -1111975615, -1111283324, -1110560756, -1109808026, -1109023086, -1108206431, + -1107355953, -1106471748, -1105551963, -1104596956, -1103604680, -1102575570, -1101507722, -1100401422, -1099254985, + -1098068882, -1096841318, -1095572135, -1093824443, -1092028958, -1090297711, -1088504795, -1086622918, -1084627237, + -1082515433, -1080275819, -1077903929, -1075390736, -1072729748, -1069911131, -1066927638, -1063770248, -1060430896, + -1056901504, -1053173546, -1049238310, -1045087876, -1040714437, -1036109920, -1031267875, -1026179775, -1020838674, + -1015237521, -1009370093, -1003230227, -996813209, -990113245, -983126698, -975849235, -968277852, -960408557, + -952239544, -943768000, -934993585, -925915442, -916534205, -906849190, -896862428, -886574831, -875990255, + -865111684, -853943783, -842489873, -830755484, -818745230, -806465779, -793923840, -781127868, -768084617, + -754803973, -741294413, -727567055, -713632929, -699502178, -685184041, -670691428, -656036019, -641230326, + -626286760, -611223511, -596053211, -580789367, -565447177, -550042966, -534590207, -519104101, -503600887, + -488098220, -472611780, -457157918, -441752495, -426412611, -411154642, -395995557, -380951672, -366040108, + -351277307, -336679493, -322262126, -308041137, -294032383, -280251079, -266711613, -253427888, -240414233, + -227684137, -215250748, -203125310, -191319486, -179843288, -168707738, -157921160, -147492810, -137428529, + -127735992, -118418783, -109483185, -100930269, -92764786, -84984919, -77594007, -70587122, -63966522, + -57723857, -51860743, -46364893, -41238076, -36463273, -32043815, -27956560, -24209143, -20769591, + -17655994, -14819879, -12293428, -9917917, -7494462, -3886267 }; +# else +# define MDCT_WINDOW_FS_48000_frame_ms_100 NULL +# endif + +# ifdef PACK_MDCT_WINDOWS +RAM_ALIGN const Word16 * LowDelayShapes_n960[6]; +# else +RAM_ALIGN const Word32 *const LowDelayShapes_n960[6] = { MDCT_WINDOW_FS_8000_frame_ms_100, MDCT_WINDOW_FS_16000_frame_ms_100, + MDCT_WINDOW_FS_24000_frame_ms_100, MDCT_WINDOW_FS_32000_frame_ms_100, + MDCT_WINDOW_FS_48000_frame_ms_100, NULL }; +# endif + +#else +RAM_ALIGN const Word16 *const LowDelayShapes_n960[6] = {LowDelayShapes_n960_N80, LowDelayShapes_n960_N160, + LowDelayShapes_n960_N240, LowDelayShapes_n960_N320, + LowDelayShapes_n960_N480, NULL}; +#endif + +# ifdef ENABLE_HR_MODE +RAM_ALIGN const Word16 LowDelayShapes_n960_len_5ms[6] = {70, 140, 210, 280, 420, 840}; +# else +RAM_ALIGN const Word16 LowDelayShapes_n960_len_5ms[5] = {70, 140, 210, 280, 420}; +# endif + +RAM_ALIGN const Word16 LowDelayShapes_n960_la_zeroes_5ms[NUM_SAMP_FREQ] = {10, + 20, + 30, + 40, + 60 +# ifdef ENABLE_HR_MODE + , 120 +# endif +}; + +# ifdef ENABLE_HR_MODE +# ifdef SUBSET_NB +RAM_ALIGN const Word32 MDCT_WINDOW_FS_8000_frame_ms_25[40] = { + 9151354, 37109627, 83712740, 151998210, 242715442, 354150912, 482126354, 620379048, + 761296862, 896901837, 1019922302, 1124767307, 1208223590, 1269735636, 1311202326, 1336324669, + 1349655864, 1355605615, 1357680847, 1358157082, -1358157082, -1357680847, -1355605615, -1349655864, + -1336324669, -1311202326, -1269735636, -1208223590, -1124767307, -1019922302, -896901837, -761296862, + -620379048, -482126354, -354150912, -242715442, -151998210, -83712740, -37109627, -9151354}; +# else +# define MDCT_WINDOW_FS_8000_frame_ms_25 NULL +# endif +# ifdef SUBSET_WB +RAM_ALIGN const Word32 MDCT_WINDOW_FS_16000_frame_ms_25[80] = { + 9151337, 23138265, 42763907, 68767772, 101782534, 142300433, 190643613, 246939893, 311105303, + 382834448, 461599452, 546657840, 637069348, 731721202, 829361019, 928636120, 1028137675, 1126447891, + 1222188210, 1314066414, 1400920509, 1481757333, 1555784035, 1622430811, 1681363664, 1732486397, 1775931558, + 1812040689, 1841334847, 1864477074, 1882229157, 1895405578, 1904827946, 1911283293, 1915489337, 1918069115, + 1919536352, 1920291661, 1920628396, 1920745966, -1920745966, -1920628396, -1920291661, -1919536352, -1918069115, + -1915489337, -1911283293, -1904827946, -1895405578, -1882229157, -1864477074, -1841334847, -1812040689, -1775931558, + -1732486397, -1681363664, -1622430811, -1555784035, -1481757333, -1400920509, -1314066414, -1222188210, -1126447891, + -1028137675, -928636120, -829361019, -731721202, -637069348, -546657840, -461599452, -382834448, -311105303, + -246939893, -190643613, -142300433, -101782534, -68767772, -42763907, -23138265, -9151337 }; +# else +# define MDCT_WINDOW_FS_16000_frame_ms_25 NULL +# endif +# ifdef SUBSET_SSWB +RAM_ALIGN const Word32 MDCT_WINDOW_FS_24000_frame_ms_25[120] = { + 6100899, 12864132, 21489409, 32196712, 45171875, 60580072, 78565098, 99246695, 122717635, + 149041013, 178247915, 210335558, 245265970, 282965259, 323323502, 366195270, 411400805, 458727828, + 507933969, 558749783, 610882290, 664019005, 717832373, 771984525, 826132286, 879932323, 933046345, + 985146249, 1035919114, 1085071930, 1132335985, 1177470792, 1220267489, 1260551623, 1298185265, 1333068386, + 1365139469, 1394375330, 1420790145, 1444433697, 1465388876, 1483768499, 1499711524, 1513378754, 1524948163, + 1534609980, 1542561681, 1549003060, 1554131535, 1558137849, 1561202310, 1563491688, 1565156852, 1566331192, + 1567129839, 1567649635, 1567969785, 1568153080, 1568247554, 1568288448, -1568288448, -1568247554, -1568153080, + -1567969785, -1567649635, -1567129839, -1566331192, -1565156852, -1563491688, -1561202310, -1558137849, -1554131535, + -1549003060, -1542561681, -1534609980, -1524948163, -1513378754, -1499711524, -1483768499, -1465388876, -1444433697, + -1420790145, -1394375330, -1365139469, -1333068386, -1298185265, -1260551623, -1220267489, -1177470792, -1132335985, + -1085071930, -1035919114, -985146249, -933046345, -879932323, -826132286, -771984525, -717832373, -664019005, + -610882290, -558749783, -507933969, -458727828, -411400805, -366195270, -323323502, -282965259, -245265970, + -210335558, -178247915, -149041013, -122717635, -99246695, -78565098, -60580072, -45171875, -32196712, + -21489409, -12864132, -6100899 }; +# else +# define MDCT_WINDOW_FS_24000_frame_ms_25 NULL +# endif +# ifdef SUBSET_SWB +RAM_ALIGN const Word32 MDCT_WINDOW_FS_32000_frame_ms_25[160] = { + 4575679, 8767860, 13776210, 19722611, 26689435, 34747238, 43959497, 54383445, 66069923, + 79062931, 93399091, 109107106, 126207257, 144710958, 164620379, 185928150, 208617151, 232660396, + 258021008, 284652300, 312497943, 341492250, 371560541, 402619617, 434578316, 467338167, 500794115, + 534835326, 569346062, 604206611, 639294264, 674484335, 709651210, 744669409, 779414654, 813764938, + 847601565, 880810169, 913281687, 944913281, 975609194, 1005281536, 1033850982, 1061247376, 1087410241, + 1112289173, 1135844126, 1158045581, 1178874586, 1198322683, 1216391705, 1233093455, 1248449271, 1262489470, + 1275252698, 1286785178, 1297139874, 1306375586, 1314555990, 1321748631, 1328023899, 1333453999, 1338111934, + 1342070524, 1345401476, 1348174521, 1350456644, 1352311405, 1353798377, 1354972700, 1355884752, 1356579954, + 1357098688, 1357476324, 1357743362, 1357925654, 1358044707, 1358118045, 1358159612, 1358180205, -1358180205, + -1358159612, -1358118045, -1358044707, -1357925654, -1357743362, -1357476324, -1357098688, -1356579954, -1355884752, + -1354972700, -1353798377, -1352311405, -1350456644, -1348174521, -1345401476, -1342070524, -1338111934, -1333453999, + -1328023899, -1321748631, -1314555990, -1306375586, -1297139874, -1286785178, -1275252698, -1262489470, -1248449271, + -1233093455, -1216391705, -1198322683, -1178874586, -1158045581, -1135844126, -1112289173, -1087410241, -1061247376, + -1033850982, -1005281536, -975609194, -944913281, -913281687, -880810169, -847601565, -813764938, -779414654, + -744669409, -709651210, -674484335, -639294264, -604206611, -569346062, -534835326, -500794115, -467338167, + -434578316, -402619617, -371560541, -341492250, -312497943, -284652300, -258021008, -232660396, -208617151, + -185928150, -164620379, -144710958, -126207257, -109107106, -93399091, -79062931, -66069923, -54383445, + -43959497, -34747238, -26689435, -19722611, -13776210, -8767860, -4575679 }; +# else +# define MDCT_WINDOW_FS_32000_frame_ms_25 NULL +# endif +# ifdef SUBSET_FB +RAM_ALIGN const Word32 MDCT_WINDOW_FS_48000_frame_ms_25[240] = { + 3050456, 5295536, 7753004, 10501942, 13578229, 17006497, 20806969, 24997575, 29594719, + 34613583, 40068237, 45971662, 52335732, 59171174, 66487516, 74293042, 82594732, 91398213, + 100707709, 110526001, 120854381, 131692624, 143038956, 154890033, 167240926, 180085109, 193414462, + 207219271, 221488240, 236208515, 251365705, 266943917, 282925795, 299292569, 316024108, 333098980, + 350494519, 368186897, 386151203, 404361529, 422791056, 441412148, 460196455, 479115006, 498138325, + 517236531, 536379451, 555536738, 574677975, 593772799, 612791011, 631702693, 650478321, 669088878, + 687505964, 705701904, 723649854, 741323899, 758699157, 775751861, 792459455, 808800673, 824755609, + 840305794, 855434253, 870125559, 884365881, 898143024, 911446458, 924267340, 936598527, 948434586, + 959771781, 970608068, 980943072, 990778052, 1000115868, 1008960932, 1017319150, 1025197865, 1032605778, + 1039552878, 1046050356, 1052110513, 1057746665, 1062973048, 1067804709, 1072257401, 1076347473, 1080091765, + 1083507488, 1086612119, 1089423293, 1091958692, 1094235940, 1096272508, 1098085614, 1099692137, 1101108528, + 1102350741, 1103434158, 1104373531, 1105182928, 1105875693, 1106464406, 1106960861, 1107376047, 1107720140, + 1108002502, 1108231688, 1108415463, 1108560820, 1108674010, 1108760573, 1108825377, 1108872657, 1108906059, + 1108928685, 1108943144, 1108951592, -1108951592, -1108943144, -1108928685, -1108906059, -1108872657, -1108825377, + -1108760573, -1108674010, -1108560820, -1108415463, -1108231688, -1108002502, -1107720140, -1107376047, -1106960861, + -1106464406, -1105875693, -1105182928, -1104373531, -1103434158, -1102350741, -1101108528, -1099692137, -1098085614, + -1096272508, -1094235940, -1091958692, -1089423293, -1086612119, -1083507488, -1080091765, -1076347473, -1072257401, + -1067804709, -1062973048, -1057746665, -1052110513, -1046050356, -1039552878, -1032605778, -1025197865, -1017319150, + -1008960932, -1000115868, -990778052, -980943072, -970608068, -959771781, -948434586, -936598527, -924267340, + -911446458, -898143024, -884365881, -870125559, -855434253, -840305794, -824755609, -808800673, -792459455, + -775751861, -758699157, -741323899, -723649854, -705701904, -687505964, -669088878, -650478321, -631702693, + -612791011, -593772799, -574677975, -555536738, -536379451, -517236531, -498138325, -479115006, -460196455, + -441412148, -422791056, -404361529, -386151203, -368186897, -350494519, -333098980, -316024108, -299292569, + -282925795, -266943917, -251365705, -236208515, -221488240, -207219271, -193414462, -180085109, -167240926, + -154890033, -143038956, -131692624, -120854381, -110526001, -100707709, -91398213, -82594732, -74293042, + -66487516, -59171174, -52335732, -45971662, -40068237, -34613583, -29594719, -24997575, -20806969, + -17006497, -13578229, -10501942, -7753004, -5295536, -3050456 }; +# else +# define MDCT_WINDOW_FS_48000_frame_ms_25 NULL +# endif +#endif + +# ifdef ENABLE_HR_MODE +# ifdef SUBSET_NB +RAM_ALIGN const Word32 MDCT_WINDOW_FS_8000_frame_ms_50[70] = { + 1912909, 7335521, 18325724, 36910622, 64974178, 104198418, 155981280, 221305462, 300589079, + 393635120, 499623692, 617106989, 744004208, 877694270, 1015162828, 1153137249, 1288239038, 1417150998, + 1536791945, 1644447880, 1737962977, 1815833349, 1877263804, 1922306058, 1951829636, 1967471711, 1971505676, + 1966594148, 1955602246, 1941502114, 1927310881, 1914588900, 1905592841, 1900063224, 1897652925, 1897963170, + 1900562354, 1904988644, 1910750498, 1917333371, -1924208315, -1930837552, -1936677590, -1941187989, -1943846368, + -1944164165, -1941697923, -1936063536, -1926966575, -1914246866, -1895468226, -1869147188, -1832534703, -1783214725, + -1719263259, -1639330989, -1542778136, -1429960741, -1302431717, -1162827131, -1014564422, -861762630, -709123640, + -561741289, -424627691, -302165309, -197940066, -114914393, -55161222, -18600494 }; +# else +# define MDCT_WINDOW_FS_8000_frame_ms_50 NULL +# endif +# ifdef SUBSET_WB +RAM_ALIGN const Word32 MDCT_WINDOW_FS_16000_frame_ms_50[140] = { + 834388, 2023133, 3917156, 6701705, 10565521, 15685856, 22235650, 30384241, 40286022, + 52095516, 65948322, 81967398, 100265346, 120927126, 144016301, 169574495, 197607091, 228098907, + 261006859, 296253144, 333742048, 373344049, 414902600, 458235462, 503129294, 549353006, 596652543, + 644762423, 693401311, 742277119, 791098023, 839557429, 887360048, 934211532, 979820668, 1023922652, + 1066251747, 1106569674, 1144656239, 1180316465, 1213396318, 1243758349, 1271300584, 1295946391, 1317664404, + 1336461856, 1352374790, 1365487180, 1375907723, 1383780765, 1389286272, 1392625157, 1394020824, 1393712039, + 1391944281, 1388970703, 1385052050, 1380450904, 1375432870, 1370255673, 1365493257, 1360311818, 1355815371, + 1351987330, 1348809662, 1346259072, 1344307938, 1342925268, 1342077528, 1341729312, 1341843769, 1342382749, + 1343306801, 1344575110, 1346145481, 1347974400, 1350017219, 1352228384, 1354561632, 1356970112, -1359406807, + -1361823903, -1364173707, -1366408059, -1368478813, -1370338075, -1371938535, -1373233878, -1374179166, -1374731135, + -1374848407, -1374491689, -1373624022, -1372211199, -1370222452, -1367631371, -1364416934, -1360564607, -1356067324, + -1350921653, -1344029735, -1336226439, -1326949476, -1315967441, -1303050661, -1287981322, -1270565808, -1250633190, + -1228037147, -1202659404, -1174406746, -1143219019, -1109079369, -1072015866, -1032110341, -989504343, -944386484, + -896992664, -847599093, -796504062, -744037160, -690570612, -636495945, -582226621, -528203723, -474881089, + -422717084, -372160937, -323635430, -277529378, -234193138, -193941056, -157058932, -123809989, -94431397, + -69117849, -47990622, -31057417, -18172622, -9019056 }; +# else +# define MDCT_WINDOW_FS_16000_frame_ms_50 NULL +# endif +# ifdef SUBSET_SSWB +RAM_ALIGN const Word32 MDCT_WINDOW_FS_24000_frame_ms_50[210] = { + 564151, 1104419, 1865494, 2894039, 4235165, 5932159, 8033172, 10580362, 13613959, + 17177173, 21310358, 26053470, 31441110, 37512859, 44302113, 51841191, 60158985, 69285016, + 79244161, 90055834, 101740044, 114307277, 127770768, 142131061, 157390145, 173545185, 190584386, + 208498576, 227265343, 246867205, 267275117, 288457873, 310382420, 333006130, 356286886, 380173162, + 404613227, 429551030, 454926373, 480676280, 506737023, 533041379, 559520739, 586104532, 612719819, + 639298867, 665764101, 692044954, 718069120, 743765156, 769064062, 793893410, 818192510, 841895640, + 864939671, 887267243, 908824605, 929558785, 949422426, 968375342, 986383128, 1003413393, 1019433821, + 1034427350, 1048371873, 1061257817, 1073079562, 1083838763, 1093544388, 1102204732, 1109843920, 1116483171, + 1122153769, 1126889366, 1130731703, 1133726105, 1135920322, 1137368676, 1138125139, 1138249333, 1137797435, + 1136832092, 1135413661, 1133604477, 1131468200, 1129067483, 1126468580, 1123733695, 1120926768, 1118121453, + 1115661504, 1112733456, 1110039679, 1107592275, 1105388417, 1103424195, 1101694785, 1100194540, 1098917076, + 1097855409, 1097002014, 1096348961, 1095887953, 1095610427, 1095507566, 1095570351, 1095789547, 1096155725, + 1096659227, 1097290187, 1098038501, 1098893850, 1099845706, 1100883348, 1101995893, 1103172315, 1104401472, + 1105672121, 1106972938, 1108292669, -1109619302, -1110942189, -1112249205, -1113528884, -1114769580, -1115959638, + -1117087420, -1118141328, -1119109856, -1119981619, -1120745408, -1121390225, -1121905319, -1122280224, -1122504764, + -1122569097, -1122463704, -1122179448, -1121707579, -1121039818, -1120168401, -1119086203, -1117786804, -1116264645, + -1114515111, -1112534671, -1110320979, -1107872954, -1105190944, -1102290376, -1098369607, -1094349090, -1089850335, + -1084803470, -1079152632, -1072839707, -1065811535, -1058014404, -1049399648, -1039922082, -1029539502, -1018216878, + -1005918442, -992617105, -978287110, -962909114, -946468188, -928955851, -910372331, -890723372, -870025772, + -848301812, -825588219, -801924529, -777362543, -751959302, -725776798, -698887464, -671358557, -643273732, + -614708529, -585759042, -556515015, -527075925, -497538887, -468010517, -438598442, -409412725, -380564000, + -352163661, -324321484, -297140687, -270721761, -245158912, -220540161, -196946958, -174455223, -153136078, + -133056674, -114280750, -96868231, -80874056, -66345855, -53320577, -41820223, -31847346, -23380692, + -16371397, -10739000, -6256916 }; +# else +# define MDCT_WINDOW_FS_24000_frame_ms_50 NULL +# endif +# ifdef SUBSET_SWB +RAM_ALIGN const Word32 MDCT_WINDOW_FS_32000_frame_ms_50[280] = { + 882763, 1521118, 2358563, 3425984, 4762639, 6395771, 8362131, 10689006, 13418692, + 16576000, 20193865, 24299300, 28928500, 34104984, 39865074, 46229302, 53228467, 60887056, + 69236180, 78292965, 88087142, 98634050, 109959733, 122081209, 135019424, 148782425, 163392710, + 178855011, 195181305, 212377526, 230451659, 249395809, 269219382, 289915225, 311477904, 333897457, + 357170677, 381274098, 406199848, 431929301, 458441926, 485710203, 513718369, 542430861, 571822196, + 601857045, 632504350, 663719412, 695470641, 727711424, 760403450, 793496784, 826949741, 860710772, + 894737379, 928972875, 963373530, 997882662, 1032450522, 1067021806, 1101552211, 1135977909, 1170251366, + 1204317771, 1238127288, 1271622131, 1304759595, 1337479850, 1369736833, 1401482421, 1432674669, 1463259078, + 1493196881, 1522440628, 1550955893, 1578698536, 1605635690, 1631726882, 1656947594, 1681264014, 1704659250, + 1727103999, 1748576205, 1769054798, 1788533700, 1806990078, 1824418644, 1840812466, 1856170505, 1870488908, + 1883781944, 1896047096, 1907297858, 1917548829, 1926819646, 1935123035, 1942490021, 1948939055, 1954502859, + 1959211322, 1963101243, 1966202102, 1968559589, 1970206964, 1971189283, 1971546464, 1971324022, 1970559672, + 1969305529, 1967600289, 1965492731, 1963026251, 1960251018, 1957207403, 1953949375, 1950518787, 1946965804, + 1943332468, 1939669743, 1936018211, 1933074896, 1929170790, 1925511708, 1922091318, 1918913458, 1915970631, + 1913265545, 1910789617, 1908544525, 1906520767, 1904719178, 1903129502, 1901751868, 1900575443, 1899599816, + 1898813735, 1898216400, 1897796234, 1897552155, 1897472330, 1897555435, 1897789418, 1898172732, 1898693091, + 1899348726, 1900127098, 1901026195, 1902033230, 1903145941, 1904351313, 1905646871, 1907019391, 1908466229, + 1909973977, 1911539869, 1913150363, 1914802598, 1916482920, 1918188394, 1919905292, -1921630629, -1923350609, + -1925062194, -1926751519, -1928415501, -1930040212, -1931622556, -1933148598, -1934615259, -1936008644, -1937325739, + -1938552759, -1939686835, -1940714349, -1941632651, -1942428351, -1943099088, -1943631764, -1944024336, -1944264050, + -1944349204, -1944267410, -1944017355, -1943587051, -1942975631, -1942171601, -1941174620, -1939973809, -1938569504, + -1936951577, -1935121231, -1933069293, -1930798023, -1928299406, -1925576914, -1922623868, -1919445128, -1916035514, + -1912401346, -1908538993, -1903226832, -1898165387, -1892651677, -1886636702, -1880083188, -1872945708, -1865186866, + -1856760038, -1847633035, -1837760249, -1827110036, -1815644193, -1803335041, -1790145270, -1776055593, -1761033530, + -1745059396, -1728108424, -1710167501, -1691212572, -1671237793, -1650226116, -1628174600, -1605075941, -1580936677, + -1555754529, -1529546654, -1502320930, -1474101256, -1444909741, -1414780308, -1383738492, -1351831573, -1319095487, + -1285577912, -1251324682, -1216394344, -1180827594, -1144691880, -1108040592, -1070930654, -1033434550, -995621142, + -957552560, -919309430, -880954958, -842572374, -804234470, -766025822, -728021485, -690307576, -652960034, + -616065598, -579699451, -543943367, -508866771, -474546527, -441046910, -408438534, -376778154, -346129113, + -316541929, -288074358, -260771792, -234687576, -209863469, -186348825, -164181088, -143404068, -124048067, + -106147028, -89718620, -74780184, -61329654, -49360094, -38842904, -29739589, -21991349, -15513048, + -10180154 }; +# else +# define MDCT_WINDOW_FS_32000_frame_ms_50 NULL +# endif +# ifdef SUBSET_FB +RAM_ALIGN const Word32 MDCT_WINDOW_FS_48000_frame_ms_50[420] = { + 641452, 963468, 1344309, 1798864, 2336113, 2963727, 3690212, 4523143, 5470567, + 6539876, 7738462, 9075874, 10560639, 12200013, 14000287, 15968479, 18112467, 20440430, + 22959153, 25675517, 28597257, 31731569, 35084700, 38662325, 42471171, 46518292, 50811124, + 55354756, 60154720, 65216952, 70547205, 76150562, 82031461, 88195322, 94647798, 101393537, + 108435354, 115776449, 123420676, 131372779, 139634617, 148207504, 157093536, 166295700, 175815910, + 185653595, 195807761, 206278987, 217068929, 228177014, 239600679, 251337195, 263385931, 275745715, + 288413583, 301384760, 314655039, 328222340, 342083665, 356233498, 370664518, 385372123, 400351243, + 415596618, 431100575, 446855251, 462853492, 479088256, 495551477, 512233512, 529124734, 546216403, + 563499351, 580963667, 598598648, 616393743, 634338212, 652420945, 670630244, 688955012, 707384418, + 725906000, 744507517, 763176760, 781901922, 800670867, 819470287, 838286395, 857107788, 875922821, + 894718707, 913481313, 932196408, 950852353, 969437415, 987938553, 1006342043, 1024635125, 1042806406, + 1060844237, 1078734559, 1096464849, 1114023247, 1131399453, 1148583332, 1165562052, 1182324038, 1198858240, + 1215154081, 1231201466, 1246990634, 1262512157, 1277756598, 1292714571, 1307377034, 1321735176, 1335781943, + 1349510011, 1362912058, 1375982854, 1388718627, 1401109382, 1413152613, 1424839949, 1436168435, 1447135603, + 1457737882, 1467971469, 1477831821, 1487317959, 1496429995, 1505166563, 1513525606, 1521507797, 1529115290, + 1536350460, 1543213224, 1549704472, 1555827692, 1561587898, 1566989343, 1572034920, 1576728782, 1581076815, + 1585086027, 1588761389, 1592109107, 1595136511, 1597852394, 1600264963, 1602381209, 1604209606, 1605759882, + 1607041997, 1608065019, 1608838122, 1609371538, 1609676596, 1609763199, 1609640908, 1609320042, 1608811796, + 1608127979, 1607278811, 1606274326, 1605125864, 1603845218, 1602443629, 1600931810, 1599320348, 1597621250, + 1595846595, 1594007402, 1592114826, 1590179414, 1588213076, 1586227163, 1584231653, 1582234964, 1580207977, + 1578973545, 1576735799, 1574650444, 1572657612, 1570752789, 1568935343, 1567204832, 1565560739, 1564002460, + 1562529304, 1561140497, 1559835185, 1558612434, 1557471243, 1556410547, 1555429220, 1554526076, 1553699872, + 1552949321, 1552273100, 1551669839, 1551138129, 1550676530, 1550283581, 1549957792, 1549697644, 1549501594, + 1549368091, 1549295559, 1549282400, 1549326998, 1549427723, 1549582929, 1549790946, 1550050083, 1550358639, + 1550714889, 1551117086, 1551563464, 1552052237, 1552581604, 1553149738, 1553754795, 1554394911, 1555068212, + 1555772800, 1556506765, 1557268182, 1558055112, 1558865609, 1559697712, 1560549450, 1561418844, 1562303905, + 1563202640, 1564113045, 1565033113, 1565960825, 1566894119, 1567830370, -1568770400, -1569707772, -1570643299, + -1571574337, -1572498793, -1573414613, -1574319739, -1575212113, -1576089676, -1576950365, -1577792121, -1578612885, + -1579410602, -1580183223, -1580928704, -1581645010, -1582330113, -1582982003, -1583598681, -1584178165, -1584718489, + -1585217707, -1585673898, -1586085163, -1586449622, -1586765423, -1587030743, -1587243787, -1587402781, -1587505982, + -1587551679, -1587538195, -1587463877, -1587327103, -1587126293, -1586859906, -1586526431, -1586124397, -1585652387, + -1585109032, -1584493010, -1583803053, -1583037961, -1582196603, -1581277917, -1580280911, -1579204680, -1578048412, + -1576811384, -1575492968, -1574092640, -1572609980, -1571044684, -1569396562, -1567665543, -1565851670, -1563955090, + -1561975794, -1559909960, -1557699231, -1554579493, -1551951859, -1549122074, -1546121016, -1542941389, -1539572601, + -1536005010, -1532229275, -1528234689, -1524011122, -1519548313, -1514837211, -1509868869, -1504633300, -1499121016, + -1493323395, -1487232726, -1480841309, -1474140699, -1467123022, -1459782240, -1452112311, -1444106817, -1435759114, + -1427063276, -1418015155, -1408610288, -1398843935, -1388711462, -1378209682, -1367336091, -1356088102, -1344462791, + -1332458664, -1320075617, -1307313612, -1294173092, -1280654545, -1266760135, -1252493498, -1237857298, -1222855659, + -1207493934, -1191778366, -1175716859, -1159315327, -1142581197, -1125524357, -1108155092, -1090483582, -1072519662, + -1054273467, -1035757912, -1016986859, -997971439, -978723129, -959255645, -939584189, -919723670, -899686034, + -879484158, -859140109, -838667380, -818082710, -797402257, -776643501, -755824703, -734962210, -714073915, + -693179322, -672297393, -651446511, -630646657, -609917124, -589277150, -568746490, -548345449, -528092326, + -508008241, -488111645, -468421183, -448956496, -429734434, -410773661, -392090517, -373702005, -355624406, + -337873208, -320463322, -303409145, -286724555, -270422942, -254517317, -239020241, -223943842, -209300003, + -195100311, -181356034, -168078124, -155277193, -142963461, -131146681, -119836028, -109039985, -98766166, + -89021184, -79810417, -71137840, -63005796, -55414797, -48363340, -41847826, -35862016, -30397367, + -25442735, -20983937, -17003804, -13482292, -10414308, -8112352 }; +# else +# define MDCT_WINDOW_FS_48000_frame_ms_50 NULL +# endif +#endif + +#ifdef ENABLE_HR_MODE +RAM_ALIGN const Word32 *const LowDelayShapes_n960_5ms[6] = { + MDCT_WINDOW_FS_8000_frame_ms_50, MDCT_WINDOW_FS_16000_frame_ms_50, MDCT_WINDOW_FS_24000_frame_ms_50, MDCT_WINDOW_FS_32000_frame_ms_50, MDCT_WINDOW_FS_48000_frame_ms_50, NULL }; +#else +RAM_ALIGN const Word16 *const LowDelayShapes_n960_5ms[6] = {LowDelayShapes_n960_N40_5ms, LowDelayShapes_n960_N80_5ms, + LowDelayShapes_n960_N120_5ms, LowDelayShapes_n960_N160_5ms, + LowDelayShapes_n960_N240_5ms, NULL}; +#endif + +# ifdef ENABLE_HR_MODE +RAM_ALIGN const Word16 LowDelayShapes_n960_len_2_5ms[6] = {40, 80, 120, 160, 240, 480}; +# else +RAM_ALIGN const Word16 LowDelayShapes_n960_len_2_5ms[5] = {40, 80, 120, 160, 240}; +# endif + +RAM_ALIGN const Word16 LowDelayShapes_n960_la_zeroes_2_5ms[NUM_SAMP_FREQ] = {0, + 0, + 0, + 0, + 0 +}; + +#ifdef ENABLE_HR_MODE +RAM_ALIGN const Word32 *const LowDelayShapes_n960_2_5ms[6] = { + MDCT_WINDOW_FS_8000_frame_ms_25, MDCT_WINDOW_FS_16000_frame_ms_25, MDCT_WINDOW_FS_24000_frame_ms_25, MDCT_WINDOW_FS_32000_frame_ms_25, MDCT_WINDOW_FS_48000_frame_ms_25, NULL }; +#else +RAM_ALIGN const Word16 *const LowDelayShapes_n960_2_5ms[6] = { + LowDelayShapes_n960_N40_2_5ms, LowDelayShapes_n960_N80_2_5ms, LowDelayShapes_n960_N120_2_5ms, + LowDelayShapes_n960_N160_2_5ms, LowDelayShapes_n960_N240_2_5ms, NULL}; +#endif + +# ifdef ENABLE_HR_MODE +RAM_ALIGN const Word16 tns_subdiv_startfreq_48k_HR[6] = {12, 74, 137, 200, 266, 333}; +RAM_ALIGN const Word16 tns_subdiv_stopfreq_48k_HR[6] = {74, 137, 200, 266, 333, 400}; +RAM_ALIGN const Word16 tns_subdiv_startfreq_96k_HR[6] = {12, 74, 137, 200, 266, 333}; +RAM_ALIGN const Word16 tns_subdiv_stopfreq_96k_HR[6] = {74, 137, 200, 266, 333, 400}; +RAM_ALIGN const Word16 *const tns_subdiv_startfreq_HR[2] = {tns_subdiv_startfreq_48k_HR, tns_subdiv_startfreq_96k_HR}; +RAM_ALIGN const Word16 *const tns_subdiv_stopfreq_HR[2] = {tns_subdiv_stopfreq_48k_HR, tns_subdiv_stopfreq_96k_HR}; + +RAM_ALIGN const Word16 tns_subdiv_startfreq_48k_5ms_HR[4] = {6, 53, 100, 150}; +RAM_ALIGN const Word16 tns_subdiv_stopfreq_48k_5ms_HR[4] = {53, 100, 150, 200}; +RAM_ALIGN const Word16 tns_subdiv_startfreq_96k_5ms_HR[4] = {6, 53, 100, 150}; +RAM_ALIGN const Word16 tns_subdiv_stopfreq_96k_5ms_HR[4] = {53, 100, 150, 200}; + +RAM_ALIGN const Word16 *const tns_subdiv_startfreq_5ms_HR[2] = {tns_subdiv_startfreq_48k_5ms_HR, + tns_subdiv_startfreq_96k_5ms_HR}; +RAM_ALIGN const Word16 *const tns_subdiv_stopfreq_5ms_HR[2] = {tns_subdiv_stopfreq_48k_5ms_HR, + tns_subdiv_stopfreq_96k_5ms_HR}; + +RAM_ALIGN const Word16 tns_subdiv_startfreq_48k_2_5ms_HR[2] = {3, 51}; +RAM_ALIGN const Word16 tns_subdiv_stopfreq_48k_2_5ms_HR[2] = {51, 100}; +RAM_ALIGN const Word16 tns_subdiv_startfreq_96k_2_5ms_HR[2] = {3, 51}; +RAM_ALIGN const Word16 tns_subdiv_stopfreq_96k_2_5ms_HR[2] = {51, 100}; + +RAM_ALIGN const Word16 *const tns_subdiv_startfreq_2_5ms_HR[2] = {tns_subdiv_startfreq_48k_2_5ms_HR, + tns_subdiv_startfreq_96k_2_5ms_HR}; +RAM_ALIGN const Word16 *const tns_subdiv_stopfreq_2_5ms_HR[2] = {tns_subdiv_stopfreq_48k_2_5ms_HR, + tns_subdiv_stopfreq_96k_2_5ms_HR}; +# endif + + +RAM_ALIGN const Word16 tns_subdiv_startfreq_8k[6] = {12, 34, 57, 0, 0, 0}; +RAM_ALIGN const Word16 tns_subdiv_stopfreq_8k[6] = {34, 57, 80, 0, 0, 0}; +RAM_ALIGN const Word16 tns_subdiv_startfreq_16k[6] = {12, 61, 110, 0, 0, 0}; +RAM_ALIGN const Word16 tns_subdiv_stopfreq_16k[6] = {61, 110, 160, 0, 0, 0}; +RAM_ALIGN const Word16 tns_subdiv_startfreq_24k[6] = {12, 88, 164, 0, 0, 0}; +RAM_ALIGN const Word16 tns_subdiv_stopfreq_24k[6] = {88, 164, 240, 0, 0, 0}; +RAM_ALIGN const Word16 tns_subdiv_startfreq_32k[6] = {12, 61, 110, 160, 213, 266}; +RAM_ALIGN const Word16 tns_subdiv_stopfreq_32k[6] = {61, 110, 160, 213, 266, 320}; +RAM_ALIGN const Word16 tns_subdiv_startfreq_48k[6] = {12, 74, 137, 200, 266, 333}; +RAM_ALIGN const Word16 tns_subdiv_stopfreq_48k[6] = {74, 137, 200, 266, 333, 400}; +RAM_ALIGN const Word16 *const tns_subdiv_startfreq[MAX_BW_BANDS_NUMBER] = { + tns_subdiv_startfreq_8k, tns_subdiv_startfreq_16k, tns_subdiv_startfreq_24k, tns_subdiv_startfreq_32k, + tns_subdiv_startfreq_48k}; +RAM_ALIGN const Word16 *const tns_subdiv_stopfreq[MAX_BW_BANDS_NUMBER] = { + tns_subdiv_stopfreq_8k, tns_subdiv_stopfreq_16k, tns_subdiv_stopfreq_24k, tns_subdiv_stopfreq_32k, + tns_subdiv_stopfreq_48k}; + + +RAM_ALIGN const Word16 tns_subdiv_startfreq_8k_5ms[4] = {6, 23, 0, 0}; +RAM_ALIGN const Word16 tns_subdiv_stopfreq_8k_5ms[4] = {23, 40, 0, 0}; +RAM_ALIGN const Word16 tns_subdiv_startfreq_16k_5ms[4] = {6, 43, 0, 0}; +RAM_ALIGN const Word16 tns_subdiv_stopfreq_16k_5ms[4] = {43, 80, 0, 0}; +RAM_ALIGN const Word16 tns_subdiv_startfreq_24k_5ms[4] = {6, 63, 0, 0}; +RAM_ALIGN const Word16 tns_subdiv_stopfreq_24k_5ms[4] = {63, 120, 0, 0}; +RAM_ALIGN const Word16 tns_subdiv_startfreq_32k_5ms[4] = {6, 43, 80, 120}; +RAM_ALIGN const Word16 tns_subdiv_stopfreq_32k_5ms[4] = {43, 80, 120, 160}; +RAM_ALIGN const Word16 tns_subdiv_startfreq_48k_5ms[4] = {6, 53, 100, 150}; +RAM_ALIGN const Word16 tns_subdiv_stopfreq_48k_5ms[4] = {53, 100, 150, 200}; +RAM_ALIGN const Word16 *const tns_subdiv_startfreq_5ms[MAX_BW_BANDS_NUMBER] = { + tns_subdiv_startfreq_8k_5ms, tns_subdiv_startfreq_16k_5ms, tns_subdiv_startfreq_24k_5ms, + tns_subdiv_startfreq_32k_5ms, tns_subdiv_startfreq_48k_5ms}; +RAM_ALIGN const Word16 *const tns_subdiv_stopfreq_5ms[MAX_BW_BANDS_NUMBER] = { + tns_subdiv_stopfreq_8k_5ms, tns_subdiv_stopfreq_16k_5ms, tns_subdiv_stopfreq_24k_5ms, tns_subdiv_stopfreq_32k_5ms, + tns_subdiv_stopfreq_48k_5ms}; + +RAM_ALIGN const Word16 tns_subdiv_startfreq_8k_2_5ms[2] = {3, 11}; +RAM_ALIGN const Word16 tns_subdiv_stopfreq_8k_2_5ms[2] = {11, 20}; +RAM_ALIGN const Word16 tns_subdiv_startfreq_16k_2_5ms[2] = {3, 21}; +RAM_ALIGN const Word16 tns_subdiv_stopfreq_16k_2_5ms[2] = {21, 40}; +RAM_ALIGN const Word16 tns_subdiv_startfreq_24k_2_5ms[2] = {3, 31}; +RAM_ALIGN const Word16 tns_subdiv_stopfreq_24k_2_5ms[2] = {31, 60}; +RAM_ALIGN const Word16 tns_subdiv_startfreq_32k_2_5ms[2] = {3, 41}; +RAM_ALIGN const Word16 tns_subdiv_stopfreq_32k_2_5ms[2] = {41, 80}; +RAM_ALIGN const Word16 tns_subdiv_startfreq_48k_2_5ms[2] = {3, 51}; +RAM_ALIGN const Word16 tns_subdiv_stopfreq_48k_2_5ms[2] = {51, 100}; + +RAM_ALIGN const Word16 *const tns_subdiv_startfreq_2_5ms[MAX_BW_BANDS_NUMBER] = { + tns_subdiv_startfreq_8k_2_5ms, tns_subdiv_startfreq_16k_2_5ms, tns_subdiv_startfreq_24k_2_5ms, + tns_subdiv_startfreq_32k_2_5ms, tns_subdiv_startfreq_48k_2_5ms}; +RAM_ALIGN const Word16 *const tns_subdiv_stopfreq_2_5ms[MAX_BW_BANDS_NUMBER] = { + tns_subdiv_stopfreq_8k_2_5ms, tns_subdiv_stopfreq_16k_2_5ms, tns_subdiv_stopfreq_24k_2_5ms, + tns_subdiv_stopfreq_32k_2_5ms, tns_subdiv_stopfreq_48k_2_5ms}; + +#ifdef CR8_G_ADD_75MS +RAM_ALIGN const Word16 tns_subdiv_startfreq_8k_7_5ms[6] = {9, 26, 43, 0, 0, 0}; +RAM_ALIGN const Word16 tns_subdiv_stopfreq_8k_7_5ms[6] = {26, 43, 60, 0, 0, 0}; + +RAM_ALIGN const Word16 tns_subdiv_startfreq_16k_7_5ms[6] = {9, 46, 83, 0, 0, 0}; +RAM_ALIGN const Word16 tns_subdiv_stopfreq_16k_7_5ms[6] = {46, 83, 120, 0, 0, 0}; + +RAM_ALIGN const Word16 tns_subdiv_startfreq_24k_7_5ms[6] = {9, 66, 123, 0, 0, 0}; +RAM_ALIGN const Word16 tns_subdiv_stopfreq_24k_7_5ms[6] = {66, 123, 180, 0, 0, 0}; + +RAM_ALIGN const Word16 tns_subdiv_startfreq_32k_7_5ms[6] = {9, 46, 82, 120, 159, 200}; +RAM_ALIGN const Word16 tns_subdiv_stopfreq_32k_7_5ms[6] = {46, 82, 120, 159, 200, 240}; + +RAM_ALIGN const Word16 tns_subdiv_startfreq_48k_7_5ms[6] = {9, 56, 103, 150, 200, 250}; +RAM_ALIGN const Word16 tns_subdiv_stopfreq_48k_7_5ms[6] = {56, 103, 150, 200, 250, 300}; + +# ifdef ENABLE_HR_MODE +RAM_ALIGN const Word16 tns_subdiv_startfreq_96k_7_5ms[6] = {9, 56, 103, 150, 200, 250}; +RAM_ALIGN const Word16 tns_subdiv_stopfreq_96k_7_5ms[6] = {56, 103, 150, 200, 250, 300}; +# endif + +RAM_ALIGN const Word16 *const tns_subdiv_startfreq_7_5ms[] = { + tns_subdiv_startfreq_8k_7_5ms, tns_subdiv_startfreq_16k_7_5ms, tns_subdiv_startfreq_24k_7_5ms, + tns_subdiv_startfreq_32k_7_5ms, tns_subdiv_startfreq_48k_7_5ms +# ifdef ENABLE_HR_MODE + , tns_subdiv_startfreq_96k_7_5ms +# endif +}; +RAM_ALIGN const Word16 *const tns_subdiv_stopfreq_7_5ms[] = { + tns_subdiv_stopfreq_8k_7_5ms, tns_subdiv_stopfreq_16k_7_5ms, tns_subdiv_stopfreq_24k_7_5ms, + tns_subdiv_stopfreq_32k_7_5ms, tns_subdiv_stopfreq_48k_7_5ms +# ifdef ENABLE_HR_MODE + , tns_subdiv_stopfreq_96k_7_5ms +# endif +}; +# endif + +RAM_ALIGN const Word16 Tab_esc_nb[4] = {0 << (NBITS_CONTEXT + NBITS_RATEQ), 1 << (NBITS_CONTEXT + NBITS_RATEQ), + 2 << (NBITS_CONTEXT + NBITS_RATEQ), 3 << (NBITS_CONTEXT + NBITS_RATEQ)}; +RAM_ALIGN const Word8 ari_spec_lookup[4096] = { + 0x01, 0x27, 0x07, 0x19, 0x16, 0x16, 0x1C, 0x16, 0x16, 0x16, 0x16, 0x1C, 0x1C, 0x1C, 0x22, 0x1F, 0x1F, 0x28, 0x2B, + 0x2E, 0x31, 0x34, 0x0E, 0x11, 0x24, 0x24, 0x24, 0x26, 0x00, 0x39, 0x26, 0x16, 0x00, 0x08, 0x09, 0x0B, 0x2F, 0x0E, + 0x0E, 0x11, 0x24, 0x24, 0x24, 0x26, 0x3B, 0x3B, 0x26, 0x16, 0x16, 0x1A, 0x2E, 0x1D, 0x1E, 0x20, 0x21, 0x23, 0x24, + 0x24, 0x24, 0x26, 0x00, 0x3B, 0x17, 0x16, 0x2E, 0x2E, 0x2D, 0x2F, 0x30, 0x32, 0x32, 0x12, 0x36, 0x36, 0x36, 0x26, + 0x3B, 0x3B, 0x3B, 0x16, 0x00, 0x3E, 0x3F, 0x03, 0x21, 0x02, 0x02, 0x3D, 0x14, 0x14, 0x14, 0x15, 0x3B, 0x3B, 0x27, + 0x1C, 0x1C, 0x3F, 0x3F, 0x03, 0x21, 0x02, 0x02, 0x3D, 0x26, 0x26, 0x26, 0x15, 0x3B, 0x3B, 0x27, 0x1C, 0x1C, 0x06, + 0x06, 0x06, 0x02, 0x12, 0x3D, 0x14, 0x15, 0x15, 0x15, 0x3B, 0x27, 0x27, 0x07, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x33, 0x33, 0x33, 0x35, 0x36, 0x14, 0x26, + 0x26, 0x39, 0x27, 0x27, 0x27, 0x07, 0x18, 0x22, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, + 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x38, 0x26, 0x39, 0x39, 0x3B, 0x07, 0x07, 0x07, 0x2A, + 0x2A, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x05, 0x04, 0x04, 0x05, 0x15, 0x15, 0x3B, 0x07, 0x07, 0x07, 0x07, 0x19, 0x19, 0x19, 0x22, 0x04, 0x04, 0x04, 0x04, + 0x05, 0x17, 0x17, 0x27, 0x07, 0x07, 0x07, 0x2A, 0x19, 0x19, 0x16, 0x1F, 0x1F, 0x27, 0x27, 0x27, 0x27, 0x07, 0x07, + 0x2A, 0x00, 0x19, 0x16, 0x16, 0x16, 0x1C, 0x22, 0x1F, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, + 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x28, 0x08, 0x09, 0x31, 0x31, 0x34, 0x11, 0x11, 0x11, 0x04, 0x00, + 0x14, 0x11, 0x3C, 0x28, 0x28, 0x08, 0x2B, 0x1B, 0x31, 0x31, 0x0E, 0x11, 0x11, 0x11, 0x24, 0x2A, 0x2A, 0x11, 0x39, + 0x39, 0x28, 0x08, 0x1A, 0x1B, 0x31, 0x0C, 0x0E, 0x11, 0x11, 0x11, 0x24, 0x00, 0x26, 0x24, 0x01, 0x08, 0x08, 0x2B, + 0x09, 0x0B, 0x31, 0x0C, 0x0E, 0x0E, 0x21, 0x32, 0x32, 0x32, 0x3D, 0x24, 0x27, 0x08, 0x08, 0x2B, 0x2E, 0x31, 0x34, + 0x1E, 0x0E, 0x0E, 0x21, 0x32, 0x32, 0x32, 0x32, 0x12, 0x19, 0x08, 0x08, 0x2B, 0x2E, 0x31, 0x34, 0x1E, 0x0E, 0x0E, + 0x12, 0x05, 0x05, 0x05, 0x3D, 0x12, 0x17, 0x2B, 0x2B, 0x2B, 0x09, 0x31, 0x34, 0x03, 0x0E, 0x0E, 0x32, 0x32, 0x32, + 0x32, 0x3D, 0x11, 0x18, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, + 0x2B, 0x2B, 0x2B, 0x2B, 0x09, 0x0B, 0x34, 0x34, 0x0E, 0x0E, 0x11, 0x3D, 0x3D, 0x3D, 0x36, 0x11, 0x27, 0x2D, 0x2D, + 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2C, 0x1B, 0x1D, + 0x34, 0x30, 0x34, 0x34, 0x11, 0x11, 0x11, 0x11, 0x02, 0x11, 0x07, 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, + 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x09, 0x1B, 0x1B, 0x0C, 0x34, 0x0E, 0x0E, 0x3A, 0x29, + 0x29, 0x29, 0x06, 0x11, 0x25, 0x09, 0x09, 0x09, 0x1B, 0x0B, 0x31, 0x0C, 0x34, 0x0E, 0x0E, 0x0E, 0x32, 0x00, 0x35, + 0x11, 0x1C, 0x34, 0x34, 0x31, 0x34, 0x0C, 0x34, 0x1E, 0x0E, 0x0E, 0x11, 0x02, 0x02, 0x02, 0x26, 0x26, 0x22, 0x1F, + 0x22, 0x22, 0x1F, 0x1F, 0x1F, 0x1F, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x1F, 0x13, 0x2C, 0x2C, 0x3E, 0x1E, + 0x20, 0x3A, 0x23, 0x24, 0x24, 0x26, 0x00, 0x3B, 0x07, 0x07, 0x27, 0x22, 0x22, 0x2D, 0x2F, 0x30, 0x21, 0x23, 0x23, + 0x24, 0x26, 0x26, 0x26, 0x3B, 0x07, 0x07, 0x27, 0x22, 0x22, 0x3E, 0x1E, 0x0F, 0x32, 0x35, 0x35, 0x36, 0x15, 0x15, + 0x15, 0x3B, 0x07, 0x07, 0x07, 0x22, 0x1E, 0x1E, 0x30, 0x21, 0x3A, 0x12, 0x12, 0x38, 0x17, 0x17, 0x17, 0x3B, 0x07, + 0x07, 0x18, 0x22, 0x22, 0x06, 0x06, 0x3A, 0x35, 0x36, 0x36, 0x15, 0x3B, 0x3B, 0x3B, 0x27, 0x07, 0x07, 0x2A, 0x22, + 0x06, 0x06, 0x21, 0x3A, 0x35, 0x36, 0x3D, 0x15, 0x3B, 0x3B, 0x3B, 0x27, 0x07, 0x07, 0x2A, 0x22, 0x22, 0x33, 0x33, + 0x35, 0x36, 0x38, 0x38, 0x39, 0x27, 0x27, 0x27, 0x07, 0x2A, 0x2A, 0x19, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, + 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x04, 0x04, 0x04, 0x05, 0x17, 0x17, 0x27, 0x07, + 0x07, 0x07, 0x2A, 0x19, 0x19, 0x16, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, + 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x05, 0x05, 0x05, 0x05, 0x39, 0x39, 0x27, 0x18, 0x18, 0x18, 0x2A, 0x16, 0x16, 0x1C, + 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x29, + 0x29, 0x29, 0x29, 0x27, 0x27, 0x07, 0x2A, 0x2A, 0x2A, 0x19, 0x1C, 0x1C, 0x1C, 0x1F, 0x1F, 0x29, 0x29, 0x29, 0x29, + 0x27, 0x27, 0x18, 0x19, 0x19, 0x19, 0x16, 0x1C, 0x1C, 0x22, 0x1F, 0x1F, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x1C, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x1F, 0x13, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, + 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x09, 0x0B, 0x2F, 0x20, 0x32, 0x12, 0x12, 0x14, 0x15, 0x15, 0x15, 0x27, + 0x3B, 0x22, 0x1A, 0x1A, 0x1B, 0x1D, 0x1E, 0x21, 0x32, 0x12, 0x12, 0x14, 0x39, 0x39, 0x39, 0x3B, 0x3B, 0x22, 0x1B, + 0x1B, 0x0B, 0x0C, 0x30, 0x32, 0x3A, 0x3D, 0x3D, 0x38, 0x39, 0x39, 0x39, 0x3B, 0x27, 0x22, 0x2D, 0x2D, 0x0C, 0x1E, + 0x20, 0x02, 0x02, 0x3D, 0x26, 0x26, 0x26, 0x39, 0x00, 0x3B, 0x27, 0x22, 0x3F, 0x3F, 0x03, 0x20, 0x3A, 0x12, 0x12, + 0x14, 0x15, 0x15, 0x15, 0x3B, 0x27, 0x27, 0x07, 0x1F, 0x1F, 0x03, 0x03, 0x21, 0x3A, 0x12, 0x12, 0x14, 0x15, 0x15, + 0x15, 0x3B, 0x07, 0x07, 0x07, 0x1F, 0x06, 0x06, 0x33, 0x33, 0x35, 0x36, 0x36, 0x26, 0x39, 0x39, 0x39, 0x27, 0x07, + 0x07, 0x2A, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, + 0x1F, 0x33, 0x35, 0x35, 0x36, 0x38, 0x38, 0x39, 0x3B, 0x3B, 0x3B, 0x07, 0x18, 0x18, 0x19, 0x1F, 0x1F, 0x1F, 0x1F, + 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x04, 0x04, 0x04, 0x36, 0x15, + 0x15, 0x39, 0x27, 0x27, 0x27, 0x07, 0x2A, 0x2A, 0x16, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, + 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x05, 0x05, 0x05, 0x05, 0x17, 0x17, 0x3B, 0x07, 0x07, 0x07, 0x2A, + 0x16, 0x16, 0x1C, 0x1F, 0x1F, 0x04, 0x04, 0x04, 0x05, 0x17, 0x17, 0x27, 0x18, 0x18, 0x18, 0x19, 0x1C, 0x1C, 0x22, + 0x1F, 0x1F, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x1C, 0x22, 0x22, 0x22, 0x1F, 0x1F, 0x1F, 0x1F, 0x13, 0x0D, 0x0D, + 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x3C, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x0D, 0x0D, 0x0D, 0x3C, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D, + 0x0D, 0x3C, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x3C, 0x3C, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x3C, 0x3C, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, + 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, + 0x3C, 0x3C, 0x3C, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x3C, + 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x3C, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, + 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, + 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x0D, 0x00, + 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x00, 0x3C, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x3C, 0x3C, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x3C, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x0D, 0x3C, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0D, 0x0D, 0x0D, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x0D, 0x00, + 0x0D, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x0D, 0x00, 0x00, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, + 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x3C, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x10, + 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x25, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, + 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, + 0x0D, 0x0D, 0x0D, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, + 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x3C, 0x10, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x3C, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x3C, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, + 0x0D, 0x0D, 0x0D, 0x3C, 0x10, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, + 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x3C, 0x3C, 0x10, 0x0D, + 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, + 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x3C, 0x3C, 0x10, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, + 0x0D, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x10, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, + 0x10, 0x10, 0x10, 0x10, 0x10, 0x25, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x0D, 0x10, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x0D, 0x0D, 0x10, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D, + 0x0D, 0x0D, 0x0D, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x3C, + 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x3C, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x0D, + 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x3C, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, + 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x3C, 0x3C, + 0x3C, 0x10, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x10, 0x10, 0x10, + 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x25, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x0D, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, + 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x0D, + 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, + 0x0D, 0x0D, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x0D, 0x0D, 0x0D, 0x00, 0x0D, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D, + 0x0D, 0x0D, 0x0D, 0x00, 0x0D, 0x0D, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x00, + 0x00, 0x0D, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x0D, 0x00, 0x0D, 0x0D, + 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x00, 0x13, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, + 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x13, 0x0D, 0x0D, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x0D, + 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, 0x0D, 0x0D, 0x0D, 0x0D, + 0x0D, 0x0D, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x0D, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, + 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x3C, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x3C, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, + 0x3C, 0x3C, 0x3C, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, + 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x0D, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x0D, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x3C, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0D, 0x0D, 0x0D, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x3C, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x3C, 0x0D, 0x0D, 0x0D, + 0x0D, 0x0D, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x0D, 0x0D, 0x00, + 0x00, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, + 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, + 0x0D, 0x0D, 0x0D, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x3C, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; + +RAM_ALIGN const UWord16 ari_spec_cumfreq[64][17] = { + {0, 1, 2, 177, 225, 226, 227, 336, 372, 543, 652, 699, 719, 768, 804, 824, 834}, + {0, 18, 44, 61, 71, 98, 135, 159, 175, 197, 229, 251, 265, 282, 308, 328, 341}, + {0, 71, 163, 212, 237, 318, 420, 481, 514, 556, 613, 652, 675, 697, 727, 749, 764}, + {0, 160, 290, 336, 354, 475, 598, 653, 677, 722, 777, 808, 823, 842, 866, 881, 890}, + {0, 71, 144, 177, 195, 266, 342, 385, 411, 445, 489, 519, 539, 559, 586, 607, 622}, + {0, 48, 108, 140, 159, 217, 285, 327, 354, 385, 427, 457, 478, 497, 524, 545, 561}, + {0, 138, 247, 290, 308, 419, 531, 584, 609, 655, 710, 742, 759, 780, 807, 825, 836}, + {0, 16, 40, 62, 79, 103, 139, 170, 195, 215, 245, 270, 290, 305, 327, 346, 362}, + {0, 579, 729, 741, 743, 897, 970, 980, 982, 996, 1007, 1010, 1011, 1014, 1017, 1018, 1019}, + {0, 398, 582, 607, 612, 788, 902, 925, 931, 956, 979, 987, 990, 996, 1002, 1005, 1007}, + {0, 13, 34, 52, 63, 83, 112, 134, 149, 163, 183, 199, 211, 221, 235, 247, 257}, + {0, 281, 464, 501, 510, 681, 820, 857, 867, 902, 938, 953, 959, 968, 978, 984, 987}, + {0, 198, 362, 408, 421, 575, 722, 773, 789, 832, 881, 905, 915, 928, 944, 954, 959}, + {0, 1, 2, 95, 139, 140, 141, 213, 251, 337, 407, 450, 475, 515, 551, 576, 592}, + {0, 133, 274, 338, 366, 483, 605, 664, 691, 730, 778, 807, 822, 837, 857, 870, 878}, + {0, 128, 253, 302, 320, 443, 577, 636, 659, 708, 767, 799, 814, 833, 857, 872, 881}, + {0, 1, 2, 25, 42, 43, 44, 67, 85, 105, 126, 144, 159, 174, 191, 205, 217}, + {0, 70, 166, 229, 267, 356, 468, 533, 569, 606, 653, 685, 705, 722, 745, 762, 774}, + {0, 55, 130, 175, 200, 268, 358, 416, 449, 488, 542, 581, 606, 628, 659, 683, 699}, + {0, 1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31}, + {0, 34, 85, 123, 147, 196, 265, 317, 352, 386, 433, 470, 497, 518, 549, 574, 593}, + {0, 30, 73, 105, 127, 170, 229, 274, 305, 335, 377, 411, 436, 455, 483, 506, 524}, + {0, 9, 24, 38, 51, 65, 87, 108, 126, 139, 159, 177, 193, 204, 221, 236, 250}, + {0, 30, 74, 105, 125, 166, 224, 266, 294, 322, 361, 391, 413, 431, 457, 478, 494}, + {0, 15, 38, 58, 73, 95, 128, 156, 178, 196, 222, 245, 263, 276, 296, 314, 329}, + {0, 11, 28, 44, 57, 74, 100, 123, 142, 157, 179, 199, 216, 228, 246, 262, 276}, + {0, 448, 619, 639, 643, 821, 926, 944, 948, 971, 991, 998, 1000, 1005, 1010, 1012, 1013}, + {0, 332, 520, 549, 555, 741, 874, 903, 910, 940, 970, 981, 985, 991, 998, 1002, 1004}, + {0, 8, 21, 34, 45, 58, 78, 96, 112, 124, 141, 157, 170, 180, 194, 207, 219}, + {0, 239, 415, 457, 468, 631, 776, 820, 833, 872, 914, 933, 940, 951, 964, 971, 975}, + {0, 165, 310, 359, 375, 513, 652, 707, 727, 774, 828, 856, 868, 884, 904, 916, 923}, + {0, 3, 8, 13, 18, 23, 30, 37, 44, 48, 55, 62, 68, 72, 78, 84, 90}, + {0, 115, 237, 289, 311, 422, 547, 608, 635, 680, 737, 771, 788, 807, 832, 849, 859}, + {0, 107, 221, 272, 293, 399, 521, 582, 610, 656, 714, 749, 767, 787, 813, 831, 842}, + {0, 6, 16, 26, 35, 45, 60, 75, 89, 98, 112, 125, 137, 145, 157, 168, 178}, + {0, 72, 160, 210, 236, 320, 422, 482, 514, 555, 608, 644, 665, 685, 712, 732, 745}, + {0, 45, 108, 153, 183, 244, 327, 385, 421, 455, 502, 536, 559, 578, 605, 626, 641}, + {0, 1, 2, 9, 16, 17, 18, 26, 34, 40, 48, 55, 62, 68, 75, 82, 88}, + {0, 29, 73, 108, 132, 174, 236, 284, 318, 348, 391, 426, 452, 471, 500, 524, 543}, + {0, 20, 51, 76, 93, 123, 166, 200, 225, 247, 279, 305, 326, 342, 365, 385, 401}, + {0, 742, 845, 850, 851, 959, 997, 1001, 1002, 1009, 1014, 1016, 1017, 1019, 1020, 1021, 1022}, + {0, 42, 94, 121, 137, 186, 244, 280, 303, 330, 366, 392, 410, 427, 451, 470, 484}, + {0, 13, 33, 51, 66, 85, 114, 140, 161, 178, 203, 225, 243, 256, 275, 292, 307}, + {0, 501, 670, 689, 693, 848, 936, 952, 956, 975, 991, 997, 999, 1004, 1008, 1010, 1011}, + {0, 445, 581, 603, 609, 767, 865, 888, 895, 926, 954, 964, 968, 977, 986, 991, 993}, + {0, 285, 442, 479, 489, 650, 779, 818, 830, 870, 912, 930, 937, 949, 963, 971, 975}, + {0, 349, 528, 561, 569, 731, 852, 883, 892, 923, 953, 965, 970, 978, 987, 992, 994}, + {0, 199, 355, 402, 417, 563, 700, 750, 767, 811, 860, 884, 894, 909, 926, 936, 942}, + {0, 141, 275, 325, 343, 471, 606, 664, 686, 734, 791, 822, 836, 854, 877, 891, 899}, + {0, 243, 437, 493, 510, 649, 775, 820, 836, 869, 905, 923, 931, 941, 953, 960, 964}, + {0, 91, 197, 248, 271, 370, 487, 550, 580, 625, 684, 721, 741, 761, 788, 807, 819}, + {0, 107, 201, 242, 262, 354, 451, 503, 531, 573, 626, 660, 680, 701, 730, 751, 765}, + {0, 168, 339, 407, 432, 553, 676, 731, 755, 789, 830, 854, 866, 879, 895, 906, 912}, + {0, 67, 147, 191, 214, 290, 384, 441, 472, 513, 567, 604, 627, 648, 678, 700, 715}, + {0, 46, 109, 148, 171, 229, 307, 359, 391, 427, 476, 513, 537, 558, 588, 612, 629}, + {0, 848, 918, 920, 921, 996, 1012, 1013, 1014, 1016, 1017, 1018, 1019, 1020, 1021, 1022, 1023}, + {0, 36, 88, 123, 145, 193, 260, 308, 340, 372, 417, 452, 476, 496, 525, 548, 565}, + {0, 24, 61, 90, 110, 145, 196, 237, 266, 292, 330, 361, 385, 403, 430, 453, 471}, + {0, 85, 182, 230, 253, 344, 454, 515, 545, 590, 648, 685, 706, 727, 756, 776, 789}, + {0, 22, 55, 82, 102, 135, 183, 222, 252, 278, 315, 345, 368, 385, 410, 431, 448}, + {0, 1, 2, 56, 89, 90, 91, 140, 172, 221, 268, 303, 328, 358, 388, 412, 430}, + {0, 45, 109, 152, 177, 239, 320, 376, 411, 448, 499, 537, 563, 585, 616, 640, 658}, + {0, 247, 395, 433, 445, 599, 729, 771, 785, 829, 875, 896, 905, 920, 937, 946, 951}, + {0, 231, 367, 408, 423, 557, 676, 723, 742, 786, 835, 860, 872, 889, 909, 921, 928}}; + +RAM_ALIGN const UWord16 ari_spec_freq[64][17] = { + {1, 1, 175, 48, 1, 1, 109, 36, 171, 109, 47, 20, 49, 36, 20, 10, 190}, + {18, 26, 17, 10, 27, 37, 24, 16, 22, 32, 22, 14, 17, 26, 20, 13, 683}, + {71, 92, 49, 25, 81, 102, 61, 33, 42, 57, 39, 23, 22, 30, 22, 15, 260}, + {160, 130, 46, 18, 121, 123, 55, 24, 45, 55, 31, 15, 19, 24, 15, 9, 134}, + {71, 73, 33, 18, 71, 76, 43, 26, 34, 44, 30, 20, 20, 27, 21, 15, 402}, + {48, 60, 32, 19, 58, 68, 42, 27, 31, 42, 30, 21, 19, 27, 21, 16, 463}, + {138, 109, 43, 18, 111, 112, 53, 25, 46, 55, 32, 17, 21, 27, 18, 11, 188}, + {16, 24, 22, 17, 24, 36, 31, 25, 20, 30, 25, 20, 15, 22, 19, 16, 662}, + {579, 150, 12, 2, 154, 73, 10, 2, 14, 11, 3, 1, 3, 3, 1, 1, 5}, + {398, 184, 25, 5, 176, 114, 23, 6, 25, 23, 8, 3, 6, 6, 3, 2, 17}, + {13, 21, 18, 11, 20, 29, 22, 15, 14, 20, 16, 12, 10, 14, 12, 10, 767}, + {281, 183, 37, 9, 171, 139, 37, 10, 35, 36, 15, 6, 9, 10, 6, 3, 37}, + {198, 164, 46, 13, 154, 147, 51, 16, 43, 49, 24, 10, 13, 16, 10, 5, 65}, + {1, 1, 93, 44, 1, 1, 72, 38, 86, 70, 43, 25, 40, 36, 25, 16, 432}, + {133, 141, 64, 28, 117, 122, 59, 27, 39, 48, 29, 15, 15, 20, 13, 8, 146}, + {128, 125, 49, 18, 123, 134, 59, 23, 49, 59, 32, 15, 19, 24, 15, 9, 143}, + {1, 1, 23, 17, 1, 1, 23, 18, 20, 21, 18, 15, 15, 17, 14, 12, 807}, + {70, 96, 63, 38, 89, 112, 65, 36, 37, 47, 32, 20, 17, 23, 17, 12, 250}, + {55, 75, 45, 25, 68, 90, 58, 33, 39, 54, 39, 25, 22, 31, 24, 16, 325}, + {1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 993}, + {34, 51, 38, 24, 49, 69, 52, 35, 34, 47, 37, 27, 21, 31, 25, 19, 431}, + {30, 43, 32, 22, 43, 59, 45, 31, 30, 42, 34, 25, 19, 28, 23, 18, 500}, + {9, 15, 14, 13, 14, 22, 21, 18, 13, 20, 18, 16, 11, 17, 15, 14, 774}, + {30, 44, 31, 20, 41, 58, 42, 28, 28, 39, 30, 22, 18, 26, 21, 16, 530}, + {15, 23, 20, 15, 22, 33, 28, 22, 18, 26, 23, 18, 13, 20, 18, 15, 695}, + {11, 17, 16, 13, 17, 26, 23, 19, 15, 22, 20, 17, 12, 18, 16, 14, 748}, + {448, 171, 20, 4, 178, 105, 18, 4, 23, 20, 7, 2, 5, 5, 2, 1, 11}, + {332, 188, 29, 6, 186, 133, 29, 7, 30, 30, 11, 4, 6, 7, 4, 2, 20}, + {8, 13, 13, 11, 13, 20, 18, 16, 12, 17, 16, 13, 10, 14, 13, 12, 805}, + {239, 176, 42, 11, 163, 145, 44, 13, 39, 42, 19, 7, 11, 13, 7, 4, 49}, + {165, 145, 49, 16, 138, 139, 55, 20, 47, 54, 28, 12, 16, 20, 12, 7, 101}, + {3, 5, 5, 5, 5, 7, 7, 7, 4, 7, 7, 6, 4, 6, 6, 6, 934}, + {115, 122, 52, 22, 111, 125, 61, 27, 45, 57, 34, 17, 19, 25, 17, 10, 165}, + {107, 114, 51, 21, 106, 122, 61, 28, 46, 58, 35, 18, 20, 26, 18, 11, 182}, + {6, 10, 10, 9, 10, 15, 15, 14, 9, 14, 13, 12, 8, 12, 11, 10, 846}, + {72, 88, 50, 26, 84, 102, 60, 32, 41, 53, 36, 21, 20, 27, 20, 13, 279}, + {45, 63, 45, 30, 61, 83, 58, 36, 34, 47, 34, 23, 19, 27, 21, 15, 383}, + {1, 1, 7, 7, 1, 1, 8, 8, 6, 8, 7, 7, 6, 7, 7, 6, 936}, + {29, 44, 35, 24, 42, 62, 48, 34, 30, 43, 35, 26, 19, 29, 24, 19, 481}, + {20, 31, 25, 17, 30, 43, 34, 25, 22, 32, 26, 21, 16, 23, 20, 16, 623}, + {742, 103, 5, 1, 108, 38, 4, 1, 7, 5, 2, 1, 2, 1, 1, 1, 2}, + {42, 52, 27, 16, 49, 58, 36, 23, 27, 36, 26, 18, 17, 24, 19, 14, 540}, + {13, 20, 18, 15, 19, 29, 26, 21, 17, 25, 22, 18, 13, 19, 17, 15, 717}, + {501, 169, 19, 4, 155, 88, 16, 4, 19, 16, 6, 2, 5, 4, 2, 1, 13}, + {445, 136, 22, 6, 158, 98, 23, 7, 31, 28, 10, 4, 9, 9, 5, 2, 31}, + {285, 157, 37, 10, 161, 129, 39, 12, 40, 42, 18, 7, 12, 14, 8, 4, 49}, + {349, 179, 33, 8, 162, 121, 31, 9, 31, 30, 12, 5, 8, 9, 5, 2, 30}, + {199, 156, 47, 15, 146, 137, 50, 17, 44, 49, 24, 10, 15, 17, 10, 6, 82}, + {141, 134, 50, 18, 128, 135, 58, 22, 48, 57, 31, 14, 18, 23, 14, 8, 125}, + {243, 194, 56, 17, 139, 126, 45, 16, 33, 36, 18, 8, 10, 12, 7, 4, 60}, + {91, 106, 51, 23, 99, 117, 63, 30, 45, 59, 37, 20, 20, 27, 19, 12, 205}, + {107, 94, 41, 20, 92, 97, 52, 28, 42, 53, 34, 20, 21, 29, 21, 14, 259}, + {168, 171, 68, 25, 121, 123, 55, 24, 34, 41, 24, 12, 13, 16, 11, 6, 112}, + {67, 80, 44, 23, 76, 94, 57, 31, 41, 54, 37, 23, 21, 30, 22, 15, 309}, + {46, 63, 39, 23, 58, 78, 52, 32, 36, 49, 37, 24, 21, 30, 24, 17, 395}, + {848, 70, 2, 1, 75, 16, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1}, + {36, 52, 35, 22, 48, 67, 48, 32, 32, 45, 35, 24, 20, 29, 23, 17, 459}, + {24, 37, 29, 20, 35, 51, 41, 29, 26, 38, 31, 24, 18, 27, 23, 18, 553}, + {85, 97, 48, 23, 91, 110, 61, 30, 45, 58, 37, 21, 21, 29, 20, 13, 235}, + {22, 33, 27, 20, 33, 48, 39, 30, 26, 37, 30, 23, 17, 25, 21, 17, 576}, + {1, 1, 54, 33, 1, 1, 49, 32, 49, 47, 35, 25, 30, 30, 24, 18, 594}, + {45, 64, 43, 25, 62, 81, 56, 35, 37, 51, 38, 26, 22, 31, 24, 18, 366}, + {247, 148, 38, 12, 154, 130, 42, 14, 44, 46, 21, 9, 15, 17, 9, 5, 73}, + {231, 136, 41, 15, 134, 119, 47, 19, 44, 49, 25, 12, 17, 20, 12, 7, 96}}; + +RAM_ALIGN const UWord16 ari_spec_bits[64][17] = { + {20480, 20480, 5220, 9042, 20480, 20480, 6619, 9892, 5289, 6619, 9105, 11629, 8982, 9892, 11629, 13677, 4977}, + {11940, 10854, 12109, 13677, 10742, 9812, 11090, 12288, 11348, 10240, 11348, 12683, 12109, 10854, 11629, 12902, + 1197}, + {7886, 7120, 8982, 10970, 7496, 6815, 8334, 10150, 9437, 8535, 9656, 11216, 11348, 10431, 11348, 12479, 4051}, + {5485, 6099, 9168, 11940, 6311, 6262, 8640, 11090, 9233, 8640, 10334, 12479, 11781, 11090, 12479, 13988, 6009}, + {7886, 7804, 10150, 11940, 7886, 7685, 9368, 10854, 10061, 9300, 10431, 11629, 11629, 10742, 11485, 12479, 2763}, + {9042, 8383, 10240, 11781, 8483, 8013, 9437, 10742, 10334, 9437, 10431, 11485, 11781, 10742, 11485, 12288, 2346}, + {5922, 6619, 9368, 11940, 6566, 6539, 8750, 10970, 9168, 8640, 10240, 12109, 11485, 10742, 11940, 13396, 5009}, + {12288, 11090, 11348, 12109, 11090, 9892, 10334, 10970, 11629, 10431, 10970, 11629, 12479, 11348, 11781, 12288, + 1289}, + {1685, 5676, 13138, 18432, 5598, 7804, 13677, 18432, 12683, 13396, 17234, 20480, 17234, 17234, 20480, 20480, 15725}, + {2793, 5072, 10970, 15725, 5204, 6487, 11216, 15186, 10970, 11216, 14336, 17234, 15186, 15186, 17234, 18432, 12109}, + {12902, 11485, 11940, 13396, 11629, 10531, 11348, 12479, 12683, 11629, 12288, 13138, 13677, 12683, 13138, 13677, + 854}, + {3821, 5088, 9812, 13988, 5289, 5901, 9812, 13677, 9976, 9892, 12479, 15186, 13988, 13677, 15186, 17234, 9812}, + {4856, 5412, 9168, 12902, 5598, 5736, 8863, 12288, 9368, 8982, 11090, 13677, 12902, 12288, 13677, 15725, 8147}, + {20480, 20480, 7088, 9300, 20480, 20480, 7844, 9733, 7320, 7928, 9368, 10970, 9581, 9892, 10970, 12288, 2550}, + {6031, 5859, 8192, 10635, 6410, 6286, 8433, 10742, 9656, 9042, 10531, 12479, 12479, 11629, 12902, 14336, 5756}, + {6144, 6215, 8982, 11940, 6262, 6009, 8433, 11216, 8982, 8433, 10240, 12479, 11781, 11090, 12479, 13988, 5817}, + {20480, 20480, 11216, 12109, 20480, 20480, 11216, 11940, 11629, 11485, 11940, 12479, 12479, 12109, 12683, 13138, + 704}, + {7928, 6994, 8239, 9733, 7218, 6539, 8147, 9892, 9812, 9105, 10240, 11629, 12109, 11216, 12109, 13138, 4167}, + {8640, 7724, 9233, 10970, 8013, 7185, 8483, 10150, 9656, 8694, 9656, 10970, 11348, 10334, 11090, 12288, 3391}, + {20480, 18432, 18432, 18432, 18432, 18432, 18432, 18432, 18432, 18432, 18432, 18432, 18432, 18432, 18432, 18432, + 91}, + {10061, 8863, 9733, 11090, 8982, 7970, 8806, 9976, 10061, 9105, 9812, 10742, 11485, 10334, 10970, 11781, 2557}, + {10431, 9368, 10240, 11348, 9368, 8433, 9233, 10334, 10431, 9437, 10061, 10970, 11781, 10635, 11216, 11940, 2119}, + {13988, 12479, 12683, 12902, 12683, 11348, 11485, 11940, 12902, 11629, 11940, 12288, 13396, 12109, 12479, 12683, + 828}, + {10431, 9300, 10334, 11629, 9508, 8483, 9437, 10635, 10635, 9656, 10431, 11348, 11940, 10854, 11485, 12288, 1946}, + {12479, 11216, 11629, 12479, 11348, 10150, 10635, 11348, 11940, 10854, 11216, 11940, 12902, 11629, 11940, 12479, + 1146}, + {13396, 12109, 12288, 12902, 12109, 10854, 11216, 11781, 12479, 11348, 11629, 12109, 13138, 11940, 12288, 12683, + 928}, + {2443, 5289, 11629, 16384, 5170, 6730, 11940, 16384, 11216, 11629, 14731, 18432, 15725, 15725, 18432, 20480, 13396}, + {3328, 5009, 10531, 15186, 5040, 6031, 10531, 14731, 10431, 10431, 13396, 16384, 15186, 14731, 16384, 18432, 11629}, + {14336, 12902, 12902, 13396, 12902, 11629, 11940, 12288, 13138, 12109, 12288, 12902, 13677, 12683, 12902, 13138, + 711}, + {4300, 5204, 9437, 13396, 5430, 5776, 9300, 12902, 9656, 9437, 11781, 14731, 13396, 12902, 14731, 16384, 8982}, + {5394, 5776, 8982, 12288, 5922, 5901, 8640, 11629, 9105, 8694, 10635, 13138, 12288, 11629, 13138, 14731, 6844}, + {17234, 15725, 15725, 15725, 15725, 14731, 14731, 14731, 16384, 14731, 14731, 15186, 16384, 15186, 15186, 15186, + 272}, + {6461, 6286, 8806, 11348, 6566, 6215, 8334, 10742, 9233, 8535, 10061, 12109, 11781, 10970, 12109, 13677, 5394}, + {6674, 6487, 8863, 11485, 6702, 6286, 8334, 10635, 9168, 8483, 9976, 11940, 11629, 10854, 11940, 13396, 5105}, + {15186, 13677, 13677, 13988, 13677, 12479, 12479, 12683, 13988, 12683, 12902, 13138, 14336, 13138, 13396, 13677, + 565}, + {7844, 7252, 8922, 10854, 7389, 6815, 8383, 10240, 9508, 8750, 9892, 11485, 11629, 10742, 11629, 12902, 3842}, + {9233, 8239, 9233, 10431, 8334, 7424, 8483, 9892, 10061, 9105, 10061, 11216, 11781, 10742, 11485, 12479, 2906}, + {20480, 20480, 14731, 14731, 20480, 20480, 14336, 14336, 15186, 14336, 14731, 14731, 15186, 14731, 14731, 15186, + 266}, + {10531, 9300, 9976, 11090, 9437, 8286, 9042, 10061, 10431, 9368, 9976, 10854, 11781, 10531, 11090, 11781, 2233}, + {11629, 10334, 10970, 12109, 10431, 9368, 10061, 10970, 11348, 10240, 10854, 11485, 12288, 11216, 11629, 12288, + 1469}, + {952, 6787, 15725, 20480, 6646, 9733, 16384, 20480, 14731, 15725, 18432, 20480, 18432, 20480, 20480, 20480, 18432}, + {9437, 8806, 10742, 12288, 8982, 8483, 9892, 11216, 10742, 9892, 10854, 11940, 12109, 11090, 11781, 12683, 1891}, + {12902, 11629, 11940, 12479, 11781, 10531, 10854, 11485, 12109, 10970, 11348, 11940, 12902, 11781, 12109, 12479, + 1054}, + {2113, 5323, 11781, 16384, 5579, 7252, 12288, 16384, 11781, 12288, 15186, 18432, 15725, 16384, 18432, 20480, 12902}, + {2463, 5965, 11348, 15186, 5522, 6934, 11216, 14731, 10334, 10635, 13677, 16384, 13988, 13988, 15725, 18432, 10334}, + {3779, 5541, 9812, 13677, 5467, 6122, 9656, 13138, 9581, 9437, 11940, 14731, 13138, 12683, 14336, 16384, 8982}, + {3181, 5154, 10150, 14336, 5448, 6311, 10334, 13988, 10334, 10431, 13138, 15725, 14336, 13988, 15725, 18432, 10431}, + {4841, 5560, 9105, 12479, 5756, 5944, 8922, 12109, 9300, 8982, 11090, 13677, 12479, 12109, 13677, 15186, 7460}, + {5859, 6009, 8922, 11940, 6144, 5987, 8483, 11348, 9042, 8535, 10334, 12683, 11940, 11216, 12683, 14336, 6215}, + {4250, 4916, 8587, 12109, 5901, 6191, 9233, 12288, 10150, 9892, 11940, 14336, 13677, 13138, 14731, 16384, 8383}, + {7153, 6702, 8863, 11216, 6904, 6410, 8239, 10431, 9233, 8433, 9812, 11629, 11629, 10742, 11781, 13138, 4753}, + {6674, 7057, 9508, 11629, 7120, 6964, 8806, 10635, 9437, 8750, 10061, 11629, 11485, 10531, 11485, 12683, 4062}, + {5341, 5289, 8013, 10970, 6311, 6262, 8640, 11090, 10061, 9508, 11090, 13138, 12902, 12288, 13396, 15186, 6539}, + {8057, 7533, 9300, 11216, 7685, 7057, 8535, 10334, 9508, 8694, 9812, 11216, 11485, 10431, 11348, 12479, 3541}, + {9168, 8239, 9656, 11216, 8483, 7608, 8806, 10240, 9892, 8982, 9812, 11090, 11485, 10431, 11090, 12109, 2815}, + {558, 7928, 18432, 20480, 7724, 12288, 20480, 20480, 18432, 20480, 20480, 20480, 20480, 20480, 20480, 20480, 20480}, + {9892, 8806, 9976, 11348, 9042, 8057, 9042, 10240, 10240, 9233, 9976, 11090, 11629, 10531, 11216, 12109, 2371}, + {11090, 9812, 10531, 11629, 9976, 8863, 9508, 10531, 10854, 9733, 10334, 11090, 11940, 10742, 11216, 11940, 1821}, + {7354, 6964, 9042, 11216, 7153, 6592, 8334, 10431, 9233, 8483, 9812, 11485, 11485, 10531, 11629, 12902, 4349}, + {11348, 10150, 10742, 11629, 10150, 9042, 9656, 10431, 10854, 9812, 10431, 11216, 12109, 10970, 11485, 12109, 1700}, + {20480, 20480, 8694, 10150, 20480, 20480, 8982, 10240, 8982, 9105, 9976, 10970, 10431, 10431, 11090, 11940, 1610}, + {9233, 8192, 9368, 10970, 8286, 7496, 8587, 9976, 9812, 8863, 9733, 10854, 11348, 10334, 11090, 11940, 3040}, + {4202, 5716, 9733, 13138, 5598, 6099, 9437, 12683, 9300, 9168, 11485, 13988, 12479, 12109, 13988, 15725, 7804}, + {4400, 5965, 9508, 12479, 6009, 6360, 9105, 11781, 9300, 8982, 10970, 13138, 12109, 11629, 13138, 14731, 6994}}; + +RAM_ALIGN const Word32 tnsAcfWindow_lc3plus[MAXLAG] = {0x7FBF61E2, 0x7EFE4B00, 0x7DBF01E8, 0x7C0544D0, + 0x79D636E9, 0x773846E0, 0x74330F61, 0x70CF3251}; +RAM_ALIGN const Word16 tnsQuantPts[TNS_COEF_RES] = {-32628, -31517, -29333, -26149, -22076, -17250, -11837, -6021, 0, + 6021, 11837, 17250, 22076, 26149, 29333, 31517, 32628}; +RAM_ALIGN const Word16 tnsQuantThr[TNS_COEF_RES - 1] = {-32210, -30555, -27860, -24216, -19747, -14606, -8967, -3023, + 3023, 8967, 14606, 19747, 24216, 27860, 30555, 32210}; + +RAM_ALIGN const Word16 ac_tns_order_bits[2][MAXLAG] = {{17234, 13988, 11216, 8694, 6566, 4977, 3961, 3040}, + {12683, 9437, 6874, 5541, 5121, 5170, 5359, 5056}}; +RAM_ALIGN const Word16 ac_tns_order_freq[2][MAXLAG] = {{3, 9, 23, 54, 111, 190, 268, 366}, + {14, 42, 100, 157, 181, 178, 167, 185}}; +RAM_ALIGN const Word16 ac_tns_order_cumfreq[2][MAXLAG] = {{0, 3, 12, 35, 89, 200, 390, 658}, + {0, 14, 56, 156, 313, 494, 672, 839}}; +RAM_ALIGN const Word16 ac_tns_coef_bits[MAXLAG][TNS_COEF_RES] = { + {20480, 15725, 12479, 10334, 8694, 7320, 6964, 6335, 5504, 5637, 6566, 6758, 8433, 11348, 15186, 20480, 20480}, + {20480, 20480, 20480, 20480, 12902, 9368, 7057, 5901, 5254, 5485, 5598, 6076, 7608, 10742, 15186, 20480, 20480}, + {20480, 20480, 20480, 20480, 13988, 9368, 6702, 4841, 4585, 4682, 5859, 7764, 12109, 20480, 20480, 20480, 20480}, + {20480, 20480, 20480, 20480, 18432, 13396, 8982, 4767, 3779, 3658, 6335, 9656, 13988, 20480, 20480, 20480, 20480}, + {20480, 20480, 20480, 20480, 20480, 14731, 9437, 4275, 3249, 3493, 8483, 13988, 17234, 20480, 20480, 20480, 20480}, + {20480, 20480, 20480, 20480, 20480, 20480, 12902, 4753, 3040, 2953, 9105, 15725, 20480, 20480, 20480, 20480, 20480}, + {20480, 20480, 20480, 20480, 20480, 20480, 12902, 3821, 3346, 3000, 12109, 20480, 20480, 20480, 20480, 20480, + 20480}, + {20480, 20480, 20480, 20480, 20480, 20480, 15725, 3658, 20480, 1201, 10854, 18432, 20480, 20480, 20480, 20480, + 20480}}; +RAM_ALIGN const Word16 ac_tns_coef_freq[MAXLAG][TNS_COEF_RES] = { + {1, 5, 15, 31, 54, 86, 97, 120, 159, 152, 111, 104, 59, 22, 6, 1, 1}, + {1, 1, 1, 1, 13, 43, 94, 139, 173, 160, 154, 131, 78, 27, 6, 1, 1}, + {1, 1, 1, 1, 9, 43, 106, 199, 217, 210, 141, 74, 17, 1, 1, 1, 1}, + {1, 1, 1, 1, 2, 11, 49, 204, 285, 297, 120, 39, 9, 1, 1, 1, 1}, + {1, 1, 1, 1, 1, 7, 42, 241, 341, 314, 58, 9, 3, 1, 1, 1, 1}, + {1, 1, 1, 1, 1, 1, 13, 205, 366, 377, 47, 5, 1, 1, 1, 1, 1}, + {1, 1, 1, 1, 1, 1, 13, 281, 330, 371, 17, 1, 1, 1, 1, 1, 1}, + {1, 1, 1, 1, 1, 1, 5, 297, 1, 682, 26, 2, 1, 1, 1, 1, 1}}; +RAM_ALIGN const Word16 ac_tns_coef_cumfreq[MAXLAG][TNS_COEF_RES] = { + {0, 1, 6, 21, 52, 106, 192, 289, 409, 568, 720, 831, 935, 994, 1016, 1022, 1023}, + {0, 1, 2, 3, 4, 17, 60, 154, 293, 466, 626, 780, 911, 989, 1016, 1022, 1023}, + {0, 1, 2, 3, 4, 13, 56, 162, 361, 578, 788, 929, 1003, 1020, 1021, 1022, 1023}, + {0, 1, 2, 3, 4, 6, 17, 66, 270, 555, 852, 972, 1011, 1020, 1021, 1022, 1023}, + {0, 1, 2, 3, 4, 5, 12, 54, 295, 636, 950, 1008, 1017, 1020, 1021, 1022, 1023}, + {0, 1, 2, 3, 4, 5, 6, 19, 224, 590, 967, 1014, 1019, 1020, 1021, 1022, 1023}, + {0, 1, 2, 3, 4, 5, 6, 19, 300, 630, 1001, 1018, 1019, 1020, 1021, 1022, 1023}, + {0, 1, 2, 3, 4, 5, 6, 11, 308, 309, 991, 1017, 1019, 1020, 1021, 1022, 1023}}; + +#ifdef SUBSET_NB +RAM_ALIGN const Word16 lpc_warp_pre_emphasis_64_8000[64] = { + 0x4000, 0x435c, 0x46e5, 0x4a9e, 0x4e89, 0x52a9, 0x5700, 0x5b91, 0x6060, 0x656f, 0x6ac2, 0x705d, 0x7643, + 0x7c79, 0x4181, 0x44f1, 0x4890, 0x4c5f, 0x5061, 0x549a, 0x590b, 0x5db7, 0x62a3, 0x67d1, 0x6d44, 0x7301, + 0x790a, 0x7f65, 0x430b, 0x4690, 0x4a44, 0x4e2a, 0x5245, 0x5696, 0x5b22, 0x5feb, 0x64f4, 0x6a41, 0x6fd5, + 0x75b4, 0x7be2, 0x4131, 0x449e, 0x4838, 0x4c02, 0x5000, 0x5433, 0x589f, 0x5d46, 0x622c, 0x6753, 0x6cc0, + 0x7275, 0x7878, 0x7ecb, 0x42b9, 0x463a, 0x49ea, 0x4dcb, 0x51e1, 0x562d, 0x5ab4, 0x5f77, 0x647a}; + +RAM_ALIGN const Word16 lpc_warp_pre_emphasis_64_e_8000[64] = { + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x03, 0x03, 0x03, 0x03, + 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, + 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05}; +#else +#define lpc_warp_pre_emphasis_64_8000 NULL +#define lpc_warp_pre_emphasis_64_e_8000 NULL +#endif + +#ifdef SUBSET_WB +RAM_ALIGN const Word16 lpc_warp_pre_emphasis_64_16000[64] = { + 0x4000, 0x445a, 0x4900, 0x4df7, 0x5344, 0x58ed, 0x5efa, 0x656f, 0x6c55, 0x73b2, 0x7b91, 0x41fc, 0x4678, + 0x4b43, 0x5061, 0x55d9, 0x5baf, 0x61eb, 0x6894, 0x6fb0, 0x7748, 0x7f65, 0x4407, 0x48a8, 0x4d98, 0x52df, + 0x5882, 0x5e87, 0x64f4, 0x6bd1, 0x7326, 0x7afb, 0x41ac, 0x4623, 0x4ae8, 0x5000, 0x5571, 0x5b40, 0x6174, + 0x6815, 0x6f29, 0x76b8, 0x7ecb, 0x43b5, 0x4850, 0x4d3a, 0x527b, 0x5817, 0x5e14, 0x647a, 0x6b4f, 0x729b, + 0x7a66, 0x415c, 0x45ce, 0x4a8d, 0x4f9f, 0x5509, 0x5ad1, 0x60fe, 0x6797, 0x6ea2, 0x7628, 0x7e31}; + +RAM_ALIGN const Word16 lpc_warp_pre_emphasis_64_e_16000[64] = { + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, + 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x05, 0x05, 0x05, 0x05, 0x05, + 0x05, 0x05, 0x05, 0x05, 0x05, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06}; +#else +#define lpc_warp_pre_emphasis_64_16000 NULL +#define lpc_warp_pre_emphasis_64_e_16000 NULL +#endif + +#ifdef SUBSET_SSWB +RAM_ALIGN const Word16 lpc_warp_pre_emphasis_64_24000[64] = { + 0x4000, 0x455c, 0x4b2a, 0x5176, 0x5848, 0x5fac, 0x67af, 0x705d, 0x79c5, 0x41fc, 0x4782, 0x4d7f, 0x53fc, + 0x5b04, 0x62a3, 0x6ae5, 0x73d9, 0x7d8c, 0x4407, 0x49b9, 0x4fe6, 0x5696, 0x5dd6, 0x65b2, 0x6e35, 0x7770, + 0x40b8, 0x4623, 0x4c02, 0x5260, 0x5945, 0x60bf, 0x68d8, 0x71a0, 0x7b23, 0x42b9, 0x4850, 0x4e5e, 0x54ed, + 0x5c0a, 0x63be, 0x6c18, 0x7525, 0x7ef4, 0x44cb, 0x4a8d, 0x50cb, 0x578f, 0x5ee4, 0x66d6, 0x6f72, 0x78c7, + 0x4172, 0x46ed, 0x4cdd, 0x534c, 0x5a46, 0x61d5, 0x6a06, 0x72e6, 0x7c85, 0x4379, 0x491f, 0x4f3f}; + +RAM_ALIGN const Word16 lpc_warp_pre_emphasis_64_e_24000[64] = { + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, + 0x04, 0x04, 0x04, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x06, 0x06, 0x06, 0x06, + 0x06, 0x06, 0x06, 0x06, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x08, 0x08, 0x08}; +#else +#define lpc_warp_pre_emphasis_64_24000 NULL +#define lpc_warp_pre_emphasis_64_e_24000 NULL +#endif + +#ifdef SUBSET_SWB +RAM_ALIGN const Word16 lpc_warp_pre_emphasis_64_32000[64] = { + 0x4000, 0x4661, 0x4d65, 0x551d, 0x5d99, 0x66ed, 0x7130, 0x7c79, 0x4471, 0x4b43, 0x52c4, 0x5b04, 0x6417, + 0x6e11, 0x790a, 0x428e, 0x4930, 0x507c, 0x5882, 0x6154, 0x6b08, 0x75b4, 0x40b8, 0x472b, 0x4e44, 0x5611, + 0x5ea6, 0x6815, 0x7275, 0x7dde, 0x4535, 0x4c1b, 0x53b2, 0x5c0a, 0x6536, 0x6f4d, 0x7a66, 0x434d, 0x4a02, + 0x5163, 0x5980, 0x626c, 0x6c3c, 0x7706, 0x4172, 0x47f8, 0x4f25, 0x5708, 0x5fb5, 0x6940, 0x73be, 0x7f48, + 0x45fc, 0x4cf6, 0x54a2, 0x5d12, 0x6659, 0x708d, 0x7bc6, 0x440e, 0x4ad7, 0x524d, 0x5a81, 0x6387}; + +RAM_ALIGN const Word16 lpc_warp_pre_emphasis_64_e_32000[64] = { + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x03, + 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x05, 0x05, + 0x05, 0x05, 0x05, 0x05, 0x05, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x07, 0x07, 0x07, 0x07, + 0x07, 0x07, 0x07, 0x07, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x09, 0x09, 0x09, 0x09, 0x09}; +#else +#define lpc_warp_pre_emphasis_64_32000 NULL +#define lpc_warp_pre_emphasis_64_e_32000 NULL +#endif + +#ifdef SUBSET_FB +RAM_ALIGN const Word16 lpc_warp_pre_emphasis_64_48000[64] = { + 0x4000, 0x476b, 0x4fb1, 0x58ed, 0x633c, 0x6ebc, 0x7b91, 0x44f1, 0x4cee, 0x55d9, 0x5fcb, 0x6ae5, 0x7748, + 0x428e, 0x4a44, 0x52df, 0x5c7a, 0x6731, 0x7326, 0x403f, 0x47b1, 0x5000, 0x5945, 0x639e, 0x6f29, 0x7c0b, + 0x4535, 0x4d3a, 0x562d, 0x602a, 0x6b4f, 0x77be, 0x42cf, 0x4a8d, 0x5331, 0x5cd5, 0x6797, 0x7398, 0x407f, + 0x47f8, 0x504f, 0x599d, 0x6400, 0x6f97, 0x7c85, 0x457a, 0x4d87, 0x5683, 0x6089, 0x6bb9, 0x7834, 0x4311, + 0x4ad7, 0x5383, 0x5d31, 0x67fd, 0x740a, 0x40be, 0x483f, 0x509e, 0x59f6, 0x6463, 0x7005, 0x7d00}; + +RAM_ALIGN const Word16 lpc_warp_pre_emphasis_64_e_48000[64] = { + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x03, 0x03, 0x03, + 0x03, 0x03, 0x03, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, + 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x08, 0x08, 0x08, + 0x08, 0x08, 0x08, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a}; +#else +#define lpc_warp_pre_emphasis_64_48000 NULL +#define lpc_warp_pre_emphasis_64_e_48000 NULL +#endif + +#ifdef ENABLE_HR_MODE +RAM_ALIGN const Word16 lpc_warp_pre_emphasis_64_96000[64] = { + 0x4000, 0x4878, 0x520f, 0x5cea, 0x6936, 0x7721, 0x4372, 0x4c5f, 0x567a, 0x61eb, 0x6ee0, 0x7d8c, 0x4714, + 0x507c, 0x5b22, 0x6731, 0x74d8, 0x4227, 0x4ae8, 0x54d1, 0x600a, 0x6cc0, 0x7b23, 0x45b7, 0x4ef1, 0x5963, + 0x6536, 0x729b, 0x40e2, 0x4978, 0x5331, 0x5e33, 0x6aaa, 0x78c7, 0x4461, 0x4d6d, 0x57ac, 0x6346, 0x7068, + 0x7f48, 0x4810, 0x5199, 0x5c64, 0x689e, 0x7676, 0x4311, 0x4bf1, 0x55fd, 0x615e, 0x6e40, 0x7cd7, 0x46ae, + 0x5008, 0x5a9f, 0x669d, 0x7430, 0x41c8, 0x4a7c, 0x5457, 0x5f80, 0x6c23, 0x7a72, 0x4553, 0x4e7f}; + +RAM_ALIGN const Word16 lpc_warp_pre_emphasis_64_e_96000[64] = { + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x03, 0x03, 0x03, 0x03, + 0x03, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x05, 0x05, 0x05, 0x05, 0x05, 0x06, 0x06, 0x06, 0x06, + 0x06, 0x06, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x08, 0x08, 0x08, 0x08, 0x08, 0x09, 0x09, 0x09, + 0x09, 0x09, 0x09, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0c, 0x0c}; +#else +# define lpc_warp_pre_emphasis_64_96000 NULL +# define lpc_warp_pre_emphasis_64_e_96000 NULL +#endif + +RAM_ALIGN const Word16 *const lpc_pre_emphasis[NUM_SAMP_FREQ] = {lpc_warp_pre_emphasis_64_8000, + lpc_warp_pre_emphasis_64_16000, + lpc_warp_pre_emphasis_64_24000, + lpc_warp_pre_emphasis_64_32000, + lpc_warp_pre_emphasis_64_48000, + lpc_warp_pre_emphasis_64_96000 +}; + +RAM_ALIGN const Word16 *const lpc_pre_emphasis_e[NUM_SAMP_FREQ] = {lpc_warp_pre_emphasis_64_e_8000, + lpc_warp_pre_emphasis_64_e_16000, + lpc_warp_pre_emphasis_64_e_24000, + lpc_warp_pre_emphasis_64_e_32000, + lpc_warp_pre_emphasis_64_e_48000, + lpc_warp_pre_emphasis_64_e_96000 +}; + +#ifdef SUBSET_NB +RAM_ALIGN const Word16 lpc_lin_pre_emphasis_20_8000[20] = {0x4be4, 0x5b79, 0x7a43, 0x53bf, 0x7106, 0x4a1f, 0x5e46, + 0x7477, 0x4613, 0x5260, 0x5ed4, 0x6b21, 0x76f9, 0x4109, + 0x4612, 0x4a79, 0x4e22, 0x50f6, 0x52e2, 0x53dc}; +RAM_ALIGN const Word16 lpc_lin_pre_emphasis_20_e_8000[20] = { + (Word16)0xfffe, (Word16)0xfffe, (Word16)0xfffe, (Word16)0xffff, (Word16)0xffff, (Word16)0x0000, (Word16)0x0000, + (Word16)0x0000, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0002, + (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002}; + +RAM_ALIGN const Word16 lpc_lin_pre_emphasis_40_8000[40] = { + 0x4a6c, 0x4e55, 0x5622, 0x61c5, 0x712d, 0x4220, 0x4d71, 0x5a77, 0x691e, 0x794e, 0x4577, 0x4ef1, 0x5906, 0x63a6, + 0x6ec1, 0x7a44, 0x430f, 0x491f, 0x4f46, 0x557c, 0x5bb8, 0x61ee, 0x6815, 0x6e25, 0x7412, 0x79d4, 0x7f61, 0x4259, + 0x44de, 0x473c, 0x4970, 0x4b76, 0x4d4b, 0x4eec, 0x5056, 0x5187, 0x527e, 0x5338, 0x53b5, 0x53f3}; +RAM_ALIGN const Word16 lpc_lin_pre_emphasis_40_e_8000[40] = { + (Word16)0xfffe, (Word16)0xfffe, (Word16)0xfffe, (Word16)0xfffe, (Word16)0xfffe, (Word16)0xffff, (Word16)0xffff, + (Word16)0xffff, (Word16)0xffff, (Word16)0xffff, (Word16)0x0000, (Word16)0x0000, (Word16)0x0000, (Word16)0x0000, + (Word16)0x0000, (Word16)0x0000, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, + (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0002, + (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, + (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002}; + + +RAM_ALIGN const Word16 lpc_lin_pre_emphasis_80_8000[80] = { + 0x4a0e, 0x4b09, 0x4cfd, 0x4fec, 0x53d2, 0x58af, 0x5e81, 0x6545, 0x6cf9, 0x759a, 0x7f25, 0x44ca, 0x4a73, 0x508a, + 0x570e, 0x5dfa, 0x654e, 0x6d06, 0x751e, 0x7d94, 0x4332, 0x47c6, 0x4c83, 0x5168, 0x5673, 0x5ba2, 0x60f2, 0x6662, + 0x6bf0, 0x7199, 0x775b, 0x7d34, 0x4191, 0x4490, 0x4798, 0x4aa7, 0x4dba, 0x50d3, 0x53ee, 0x570b, 0x5a29, 0x5d46, + 0x6061, 0x637a, 0x668e, 0x699c, 0x6ca4, 0x6fa3, 0x729a, 0x7587, 0x7868, 0x7b3c, 0x7e03, 0x405e, 0x41b2, 0x42fd, + 0x4440, 0x4579, 0x46a9, 0x47cd, 0x48e7, 0x49f6, 0x4af9, 0x4bf0, 0x4cdb, 0x4db8, 0x4e89, 0x4f4c, 0x5001, 0x50a8, + 0x5140, 0x51ca, 0x5246, 0x52b2, 0x530f, 0x535d, 0x539b, 0x53ca, 0x53e9, 0x53f9}; +RAM_ALIGN const Word16 lpc_lin_pre_emphasis_80_e_8000[80] = { + (Word16)0xfffe, (Word16)0xfffe, (Word16)0xfffe, (Word16)0xfffe, (Word16)0xfffe, (Word16)0xfffe, (Word16)0xfffe, + (Word16)0xfffe, (Word16)0xfffe, (Word16)0xfffe, (Word16)0xfffe, (Word16)0xffff, (Word16)0xffff, (Word16)0xffff, + (Word16)0xffff, (Word16)0xffff, (Word16)0xffff, (Word16)0xffff, (Word16)0xffff, (Word16)0xffff, (Word16)0x0000, + (Word16)0x0000, (Word16)0x0000, (Word16)0x0000, (Word16)0x0000, (Word16)0x0000, (Word16)0x0000, (Word16)0x0000, + (Word16)0x0000, (Word16)0x0000, (Word16)0x0000, (Word16)0x0000, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, + (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, + (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, + (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, + (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, + (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, + (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, + (Word16)0x0002, (Word16)0x0002, (Word16)0x0002}; +#else +#define lpc_lin_pre_emphasis_20_8000 NULL +#define lpc_lin_pre_emphasis_20_e_8000 NULL +#define lpc_lin_pre_emphasis_40_8000 NULL +#define lpc_lin_pre_emphasis_40_e_8000 NULL +#define lpc_lin_pre_emphasis_80_8000 NULL +#define lpc_lin_pre_emphasis_80_e_8000 NULL +#endif + +#ifdef SUBSET_WB +RAM_ALIGN const Word16 lpc_lin_pre_emphasis_40_16000[40] = { + 0x516b, 0x5a81, 0x6c9d, 0x43d2, 0x55b6, 0x6bdd, 0x4313, 0x5233, 0x6336, 0x7602, 0x453d, 0x503e, 0x5bf4, 0x684b, + 0x7530, 0x4148, 0x4829, 0x4f33, 0x5658, 0x5d8f, 0x64cc, 0x6c03, 0x7328, 0x7a32, 0x408a, 0x43e1, 0x471b, 0x4a31, + 0x4d1e, 0x4fde, 0x526d, 0x54c7, 0x56e7, 0x58cb, 0x5a70, 0x5bd2, 0x5cf0, 0x5dc9, 0x5e59, 0x5ea2}; +RAM_ALIGN const Word16 lpc_lin_pre_emphasis_40_e_16000[40] = { + (Word16)0xfffd, (Word16)0xfffd, (Word16)0xfffd, (Word16)0xfffe, (Word16)0xfffe, (Word16)0xfffe, (Word16)0xffff, + (Word16)0xffff, (Word16)0xffff, (Word16)0xffff, (Word16)0x0000, (Word16)0x0000, (Word16)0x0000, (Word16)0x0000, + (Word16)0x0000, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, + (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, + (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, + (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002}; +RAM_ALIGN const Word16 lpc_lin_pre_emphasis_80_16000[80] = { + 0x5091, 0x52d7, 0x5762, 0x5e30, 0x673f, 0x728b, 0x4008, 0x47e3, 0x50d6, 0x5adb, 0x65ef, 0x720e, 0x7f33, 0x46ac, + 0x4e3c, 0x5647, 0x5ec9, 0x67bf, 0x7126, 0x7afa, 0x429b, 0x47ec, 0x4d6d, 0x531c, 0x58f7, 0x5efb, 0x6527, 0x6b78, + 0x71eb, 0x787d, 0x7f2d, 0x42fc, 0x466d, 0x49e8, 0x4d6d, 0x50fa, 0x548d, 0x5825, 0x5bc1, 0x5f5e, 0x62fd, 0x669a, + 0x6a36, 0x6dce, 0x7161, 0x74ee, 0x7872, 0x7bee, 0x7f5f, 0x4162, 0x430e, 0x44b3, 0x4650, 0x47e4, 0x496f, 0x4af0, + 0x4c67, 0x4dd2, 0x4f33, 0x5087, 0x51ce, 0x5309, 0x5436, 0x5554, 0x5665, 0x5766, 0x5858, 0x593a, 0x5a0d, 0x5acf, + 0x5b80, 0x5c20, 0x5caf, 0x5d2d, 0x5d99, 0x5df4, 0x5e3c, 0x5e72, 0x5e97, 0x5ea9}; +RAM_ALIGN const Word16 lpc_lin_pre_emphasis_80_e_16000[80] = { + (Word16)0xfffd, (Word16)0xfffd, (Word16)0xfffd, (Word16)0xfffd, (Word16)0xfffd, (Word16)0xfffd, (Word16)0xfffe, + (Word16)0xfffe, (Word16)0xfffe, (Word16)0xfffe, (Word16)0xfffe, (Word16)0xfffe, (Word16)0xfffe, (Word16)0xffff, + (Word16)0xffff, (Word16)0xffff, (Word16)0xffff, (Word16)0xffff, (Word16)0xffff, (Word16)0xffff, (Word16)0x0000, + (Word16)0x0000, (Word16)0x0000, (Word16)0x0000, (Word16)0x0000, (Word16)0x0000, (Word16)0x0000, (Word16)0x0000, + (Word16)0x0000, (Word16)0x0000, (Word16)0x0000, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, + (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, + (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, + (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, + (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, + (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, + (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, + (Word16)0x0002, (Word16)0x0002, (Word16)0x0002}; +#else +#define lpc_lin_pre_emphasis_40_16000 NULL +#define lpc_lin_pre_emphasis_40_e_16000 NULL +#define lpc_lin_pre_emphasis_80_16000 NULL +#define lpc_lin_pre_emphasis_80_e_16000 NULL +#endif + +#ifdef SUBSET_SSWB +RAM_ALIGN const Word16 lpc_lin_pre_emphasis_40_24000[40] = { + 0x44f2, 0x59a3, 0x4172, 0x603b, 0x447d, 0x5db8, 0x7ba7, 0x4f0d, 0x626d, 0x77d6, 0x4793, 0x541b, 0x6171, 0x6f7f, + 0x7e2f, 0x46b5, 0x4e8b, 0x568f, 0x5eb2, 0x66ea, 0x6f28, 0x775f, 0x7f83, 0x43c3, 0x47ae, 0x4b7d, 0x4f29, 0x52ac, + 0x5602, 0x5924, 0x5c0e, 0x5ebb, 0x6127, 0x634e, 0x652d, 0x66c1, 0x6807, 0x68fd, 0x69a2, 0x69f5}; +RAM_ALIGN const Word16 lpc_lin_pre_emphasis_40_e_24000[40] = { + (Word16)0xfffc, (Word16)0xfffc, (Word16)0xfffd, (Word16)0xfffd, (Word16)0xfffe, (Word16)0xfffe, (Word16)0xfffe, + (Word16)0xffff, (Word16)0xffff, (Word16)0xffff, (Word16)0x0000, (Word16)0x0000, (Word16)0x0000, (Word16)0x0000, + (Word16)0x0000, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, + (Word16)0x0001, (Word16)0x0001, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, + (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, + (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002}; + +RAM_ALIGN const Word16 lpc_lin_pre_emphasis_60_24000[60] = { + 0x4382, 0x4cb6, 0x5f17, 0x7a99, 0x4f94, 0x6656, 0x40c0, 0x5081, 0x6263, 0x7658, 0x4629, 0x5222, + 0x5f0e, 0x6ce3, 0x7b98, 0x4591, 0x4dbc, 0x5647, 0x5f2b, 0x6862, 0x71e7, 0x7bb2, 0x42de, 0x47ff, + 0x4d39, 0x5288, 0x57e8, 0x5d55, 0x62cc, 0x6849, 0x6dc8, 0x7345, 0x78bc, 0x7e29, 0x41c5, 0x446c, + 0x4709, 0x499a, 0x4c1c, 0x4e8f, 0x50f0, 0x533e, 0x5577, 0x579a, 0x59a4, 0x5b96, 0x5d6c, 0x5f27, + 0x60c4, 0x6243, 0x63a3, 0x64e2, 0x6601, 0x66fd, 0x67d6, 0x688c, 0x691e, 0x698c, 0x69d6, 0x69fb}; +RAM_ALIGN const Word16 lpc_lin_pre_emphasis_60_e_24000[60] = { + (Word16)0xfffc, (Word16)0xfffc, (Word16)0xfffc, (Word16)0xfffc, (Word16)0xfffd, (Word16)0xfffd, (Word16)0xfffe, + (Word16)0xfffe, (Word16)0xfffe, (Word16)0xfffe, (Word16)0xffff, (Word16)0xffff, (Word16)0xffff, (Word16)0xffff, + (Word16)0xffff, (Word16)0x0000, (Word16)0x0000, (Word16)0x0000, (Word16)0x0000, (Word16)0x0000, (Word16)0x0000, + (Word16)0x0000, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, + (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0002, + (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, + (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, + (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, + (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002}; + +RAM_ALIGN const Word16 lpc_lin_pre_emphasis_80_24000[80] = { + 0x4301, 0x482e, 0x5287, 0x6208, 0x76a9, 0x4832, 0x5797, 0x697e, 0x7dde, 0x4a59, 0x56f7, 0x64c5, 0x73bd, 0x41ed, + 0x4a8a, 0x53b2, 0x5d63, 0x6798, 0x724d, 0x7d7e, 0x4493, 0x4aa1, 0x50e5, 0x575e, 0x5e0a, 0x64e4, 0x6beb, 0x731d, + 0x7a75, 0x40f9, 0x44c7, 0x48a5, 0x4c91, 0x5088, 0x548a, 0x5895, 0x5ca7, 0x60bf, 0x64db, 0x68f9, 0x6d18, 0x7136, + 0x7552, 0x796a, 0x7d7c, 0x40c4, 0x42c4, 0x44c0, 0x46b6, 0x48a5, 0x4a8c, 0x4c6b, 0x4e41, 0x500e, 0x51d0, 0x5386, + 0x5531, 0x56cf, 0x5860, 0x59e4, 0x5b59, 0x5cbf, 0x5e16, 0x5f5c, 0x6092, 0x61b7, 0x62cb, 0x63cd, 0x64bc, 0x6599, + 0x6663, 0x671a, 0x67bd, 0x684c, 0x68c7, 0x692e, 0x6980, 0x69be, 0x69e8, 0x69fd}; +RAM_ALIGN const Word16 lpc_lin_pre_emphasis_80_e_24000[80] = { + (Word16)0xfffc, (Word16)0xfffc, (Word16)0xfffc, (Word16)0xfffc, (Word16)0xfffc, (Word16)0xfffd, (Word16)0xfffd, + (Word16)0xfffd, (Word16)0xfffd, (Word16)0xfffe, (Word16)0xfffe, (Word16)0xfffe, (Word16)0xfffe, (Word16)0xffff, + (Word16)0xffff, (Word16)0xffff, (Word16)0xffff, (Word16)0xffff, (Word16)0xffff, (Word16)0xffff, (Word16)0x0000, + (Word16)0x0000, (Word16)0x0000, (Word16)0x0000, (Word16)0x0000, (Word16)0x0000, (Word16)0x0000, (Word16)0x0000, + (Word16)0x0000, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, + (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, + (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, + (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, + (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, + (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, + (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, + (Word16)0x0002, (Word16)0x0002, (Word16)0x0002}; +#else +#define lpc_lin_pre_emphasis_60_24000 NULL +#define lpc_lin_pre_emphasis_60_e_24000 NULL +#define lpc_lin_pre_emphasis_40_24000 NULL +#define lpc_lin_pre_emphasis_40_e_24000 NULL +#define lpc_lin_pre_emphasis_80_24000 NULL +#define lpc_lin_pre_emphasis_80_e_24000 NULL +#endif + +#ifdef SUBSET_SWB +RAM_ALIGN const Word16 lpc_lin_pre_emphasis_80_32000[80] = { + 0x6eab, 0x4e92, 0x7d03, 0x614a, 0x47cb, 0x64a9, 0x439a, 0x57af, 0x6e8c, 0x4414, 0x523c, 0x61b9, 0x7284, 0x424c, + 0x4bf6, 0x563d, 0x611c, 0x6c8f, 0x7892, 0x4290, 0x491a, 0x4fe5, 0x56ed, 0x5e31, 0x65ac, 0x6d5d, 0x753f, 0x7d51, + 0x42c7, 0x46fa, 0x4b40, 0x4f96, 0x53fc, 0x5870, 0x5cef, 0x6178, 0x6609, 0x6aa1, 0x6f3d, 0x73dc, 0x787b, 0x7d1a, + 0x40db, 0x4327, 0x4570, 0x47b4, 0x49f4, 0x4c2d, 0x4e60, 0x508b, 0x52ae, 0x54c8, 0x56d7, 0x58dc, 0x5ad4, 0x5cc0, + 0x5e9f, 0x6070, 0x6232, 0x63e5, 0x6587, 0x6719, 0x689a, 0x6a08, 0x6b64, 0x6cad, 0x6de2, 0x6f03, 0x7010, 0x7108, + 0x71ea, 0x72b7, 0x736e, 0x740f, 0x7499, 0x750c, 0x7569, 0x75ae, 0x75dd, 0x75f4}; +RAM_ALIGN const Word16 lpc_lin_pre_emphasis_80_e_32000[80] = { + (Word16)0xfff9, (Word16)0xfffa, (Word16)0xfffa, (Word16)0xfffb, (Word16)0xfffc, (Word16)0xfffc, (Word16)0xfffd, + (Word16)0xfffd, (Word16)0xfffd, (Word16)0xfffe, (Word16)0xfffe, (Word16)0xfffe, (Word16)0xfffe, (Word16)0xffff, + (Word16)0xffff, (Word16)0xffff, (Word16)0xffff, (Word16)0xffff, (Word16)0xffff, (Word16)0x0000, (Word16)0x0000, + (Word16)0x0000, (Word16)0x0000, (Word16)0x0000, (Word16)0x0000, (Word16)0x0000, (Word16)0x0000, (Word16)0x0000, + (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, + (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, + (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, + (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, + (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, + (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, + (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, + (Word16)0x0002, (Word16)0x0002, (Word16)0x0002}; +#else +#define lpc_lin_pre_emphasis_80_32000 NULL +#define lpc_lin_pre_emphasis_80_e_32000 NULL +#endif + +#ifdef SUBSET_FB +RAM_ALIGN const Word16 lpc_lin_pre_emphasis_60_48000[60] = { + 0x7330, 0x62e5, 0x5ab1, 0x4c35, 0x753a, 0x5425, 0x72a0, 0x4afd, 0x5f0d, 0x7571, 0x470d, 0x547b, + 0x62fa, 0x727f, 0x4180, 0x4a38, 0x5362, 0x5cf7, 0x66f0, 0x7148, 0x7bf5, 0x4379, 0x491b, 0x4edc, + 0x54b9, 0x5aae, 0x60b6, 0x66cd, 0x6cee, 0x7316, 0x7941, 0x7f69, 0x42c5, 0x45d1, 0x48d4, 0x4bcf, + 0x4ebd, 0x519e, 0x546f, 0x572e, 0x59d9, 0x5c6f, 0x5eee, 0x6153, 0x639d, 0x65cb, 0x67dc, 0x69cc, + 0x6b9c, 0x6d4a, 0x6ed4, 0x703b, 0x717c, 0x7296, 0x738a, 0x7457, 0x74fb, 0x7576, 0x75c9, 0x75f2}; +RAM_ALIGN const Word16 lpc_lin_pre_emphasis_60_e_48000[60] = { + (Word16)0xfff9, (Word16)0xfffa, (Word16)0xfffb, (Word16)0xfffc, (Word16)0xfffc, (Word16)0xfffd, (Word16)0xfffd, + (Word16)0xfffe, (Word16)0xfffe, (Word16)0xfffe, (Word16)0xffff, (Word16)0xffff, (Word16)0xffff, (Word16)0xffff, + (Word16)0x0000, (Word16)0x0000, (Word16)0x0000, (Word16)0x0000, (Word16)0x0000, (Word16)0x0000, (Word16)0x0000, + (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, + (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, + (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, + (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, + (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, + (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002}; +RAM_ALIGN const Word16 lpc_lin_pre_emphasis_80_48000[80] = { + 0x6eab, 0x4e92, 0x7d03, 0x614a, 0x47cb, 0x64a9, 0x439a, 0x57af, 0x6e8c, 0x4414, 0x523c, 0x61b9, 0x7284, 0x424c, + 0x4bf6, 0x563d, 0x611c, 0x6c8f, 0x7892, 0x4290, 0x491a, 0x4fe5, 0x56ed, 0x5e31, 0x65ac, 0x6d5d, 0x753f, 0x7d51, + 0x42c7, 0x46fa, 0x4b40, 0x4f96, 0x53fc, 0x5870, 0x5cef, 0x6178, 0x6609, 0x6aa1, 0x6f3d, 0x73dc, 0x787b, 0x7d1a, + 0x40db, 0x4327, 0x4570, 0x47b4, 0x49f4, 0x4c2d, 0x4e60, 0x508b, 0x52ae, 0x54c8, 0x56d7, 0x58dc, 0x5ad4, 0x5cc0, + 0x5e9f, 0x6070, 0x6232, 0x63e5, 0x6587, 0x6719, 0x689a, 0x6a08, 0x6b64, 0x6cad, 0x6de2, 0x6f03, 0x7010, 0x7108, + 0x71ea, 0x72b7, 0x736e, 0x740f, 0x7499, 0x750c, 0x7569, 0x75ae, 0x75dd, 0x75f4}; +RAM_ALIGN const Word16 lpc_lin_pre_emphasis_80_e_48000[80] = { + (Word16)0xfff9, (Word16)0xfffa, (Word16)0xfffa, (Word16)0xfffb, (Word16)0xfffc, (Word16)0xfffc, (Word16)0xfffd, + (Word16)0xfffd, (Word16)0xfffd, (Word16)0xfffe, (Word16)0xfffe, (Word16)0xfffe, (Word16)0xfffe, (Word16)0xffff, + (Word16)0xffff, (Word16)0xffff, (Word16)0xffff, (Word16)0xffff, (Word16)0xffff, (Word16)0x0000, (Word16)0x0000, + (Word16)0x0000, (Word16)0x0000, (Word16)0x0000, (Word16)0x0000, (Word16)0x0000, (Word16)0x0000, (Word16)0x0000, + (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, + (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, + (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, + (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, + (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, + (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, + (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, + (Word16)0x0002, (Word16)0x0002, (Word16)0x0002}; +#else +#define lpc_lin_pre_emphasis_60_48000 NULL +#define lpc_lin_pre_emphasis_60_e_48000 NULL +#define lpc_lin_pre_emphasis_80_48000 NULL +#define lpc_lin_pre_emphasis_80_e_48000 NULL +#endif + +# if defined(SUBSET_SWB) || defined(SUBSET_FB) +RAM_ALIGN const Word16 lpc_lin_pre_emphasis_80_0_92[80] = { + 0x6eab, 0x4e92, 0x7d03, 0x614a, 0x47cb, 0x64a9, 0x439a, 0x57af, 0x6e8c, 0x4414, 0x523c, 0x61b9, 0x7284, 0x424c, + 0x4bf6, 0x563d, 0x611c, 0x6c8f, 0x7892, 0x4290, 0x491a, 0x4fe5, 0x56ed, 0x5e31, 0x65ac, 0x6d5d, 0x753f, 0x7d51, + 0x42c7, 0x46fa, 0x4b40, 0x4f96, 0x53fc, 0x5870, 0x5cef, 0x6178, 0x6609, 0x6aa1, 0x6f3d, 0x73dc, 0x787b, 0x7d1a, + 0x40db, 0x4327, 0x4570, 0x47b4, 0x49f4, 0x4c2d, 0x4e60, 0x508b, 0x52ae, 0x54c8, 0x56d7, 0x58dc, 0x5ad4, 0x5cc0, + 0x5e9f, 0x6070, 0x6232, 0x63e5, 0x6587, 0x6719, 0x689a, 0x6a08, 0x6b64, 0x6cad, 0x6de2, 0x6f03, 0x7010, 0x7108, + 0x71ea, 0x72b7, 0x736e, 0x740f, 0x7499, 0x750c, 0x7569, 0x75ae, 0x75dd, 0x75f4}; +RAM_ALIGN const Word16 lpc_lin_pre_emphasis_80_e_0_92[80] = { + (Word16)0xfff9, (Word16)0xfffa, (Word16)0xfffa, (Word16)0xfffb, (Word16)0xfffc, (Word16)0xfffc, (Word16)0xfffd, + (Word16)0xfffd, (Word16)0xfffd, (Word16)0xfffe, (Word16)0xfffe, (Word16)0xfffe, (Word16)0xfffe, (Word16)0xffff, + (Word16)0xffff, (Word16)0xffff, (Word16)0xffff, (Word16)0xffff, (Word16)0xffff, (Word16)0x0000, (Word16)0x0000, + (Word16)0x0000, (Word16)0x0000, (Word16)0x0000, (Word16)0x0000, (Word16)0x0000, (Word16)0x0000, (Word16)0x0000, + (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, + (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, + (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, + (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, + (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, + (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, + (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, + (Word16)0x0002, (Word16)0x0002, (Word16)0x0002}; +# else +# define lpc_lin_pre_emphasis_80_0_92 NULL +# define lpc_lin_pre_emphasis_80_e_0_92 NULL +# endif + +RAM_ALIGN const Word16 *const lpc_lin_pre_emphasis[NUM_SAMP_FREQ] = {lpc_lin_pre_emphasis_80_8000, lpc_lin_pre_emphasis_80_16000, + lpc_lin_pre_emphasis_80_24000, lpc_lin_pre_emphasis_80_32000, + lpc_lin_pre_emphasis_80_48000 +#ifdef ENABLE_HR_MODE + , lpc_lin_pre_emphasis_80_0_92 +#endif + }; + +RAM_ALIGN const Word16 *const lpc_lin_pre_emphasis_e[NUM_SAMP_FREQ] = { + lpc_lin_pre_emphasis_80_e_8000, lpc_lin_pre_emphasis_80_e_16000, lpc_lin_pre_emphasis_80_e_24000, + lpc_lin_pre_emphasis_80_e_32000, lpc_lin_pre_emphasis_80_e_48000 +#ifdef ENABLE_HR_MODE + , lpc_lin_pre_emphasis_80_e_0_92 +#endif +}; + +RAM_ALIGN const Word16 *const lpc_lin_pre_emphasis_5ms[NUM_SAMP_FREQ] = { + lpc_lin_pre_emphasis_40_8000, lpc_lin_pre_emphasis_80_16000, lpc_lin_pre_emphasis_40_24000, + lpc_lin_pre_emphasis_80_32000, lpc_lin_pre_emphasis_80_48000 +#ifdef ENABLE_HR_MODE + , lpc_lin_pre_emphasis_80_0_92 +#endif +}; + +RAM_ALIGN const Word16 *const lpc_lin_pre_emphasis_e_5ms[NUM_SAMP_FREQ] = { + lpc_lin_pre_emphasis_40_e_8000, lpc_lin_pre_emphasis_80_e_16000, lpc_lin_pre_emphasis_40_e_24000, + lpc_lin_pre_emphasis_80_e_32000, lpc_lin_pre_emphasis_80_e_48000 +#ifdef ENABLE_HR_MODE + , lpc_lin_pre_emphasis_80_e_0_92 +#endif +}; + +RAM_ALIGN const Word16 *const lpc_lin_pre_emphasis_2_5ms[NUM_SAMP_FREQ] = { + lpc_lin_pre_emphasis_20_8000, lpc_lin_pre_emphasis_40_16000, lpc_lin_pre_emphasis_60_24000, + lpc_lin_pre_emphasis_80_32000, lpc_lin_pre_emphasis_60_48000 +#ifdef ENABLE_HR_MODE + , lpc_lin_pre_emphasis_80_0_92 +#endif +}; + +RAM_ALIGN const Word16 *const lpc_lin_pre_emphasis_e_2_5ms[NUM_SAMP_FREQ] = { + lpc_lin_pre_emphasis_20_e_8000, lpc_lin_pre_emphasis_40_e_16000, lpc_lin_pre_emphasis_60_e_24000, + lpc_lin_pre_emphasis_80_e_32000, lpc_lin_pre_emphasis_60_e_48000 +# ifdef ENABLE_HR_MODE + , lpc_lin_pre_emphasis_80_e_0_92 +#endif +}; + +# ifdef ENABLE_075_DMS_MODE +# ifdef CR8_G_ADD_75MS +RAM_ALIGN const Word16 lpc_lin_pre_emphasis_60_0_62[60] = { + 0x4a26, 0x4be4, 0x4f5d, 0x5490, 0x5b79, 0x6414, 0x6e59, 0x7a43, 0x43e4, 0x4b6f, 0x53bf, 0x5ccc, 0x6690, 0x7106, + 0x7c25, 0x43f3, 0x4a1f, 0x5095, 0x574e, 0x5e46, 0x6578, 0x6cdf, 0x7477, 0x7c39, 0x4210, 0x4613, 0x4a24, 0x4e3e, + 0x5260, 0x5686, 0x5aae, 0x5ed4, 0x62f6, 0x6710, 0x6b21, 0x6f24, 0x7318, 0x76f9, 0x7ac4, 0x7e78, 0x4109, 0x42c7, + 0x4475, 0x4612, 0x479d, 0x4915, 0x4a79, 0x4bc8, 0x4d01, 0x4e22, 0x4f2c, 0x501e, 0x50f6, 0x51b4, 0x5259, 0x52e2, + 0x5351, 0x53a4, 0x53dc, 0x53f8}; +RAM_ALIGN const Word16 lpc_lin_pre_emphasis_60_e_0_62[60] = { + (Word16)0xfffe, (Word16)0xfffe, (Word16)0xfffe, (Word16)0xfffe, (Word16)0xfffe, (Word16)0xfffe, (Word16)0xfffe, + (Word16)0xfffe, (Word16)0xffff, (Word16)0xffff, (Word16)0xffff, (Word16)0xffff, (Word16)0xffff, (Word16)0xffff, + (Word16)0xffff, (Word16)0x0000, (Word16)0x0000, (Word16)0x0000, (Word16)0x0000, (Word16)0x0000, (Word16)0x0000, + (Word16)0x0000, (Word16)0x0000, (Word16)0x0000, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, + (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, + (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0002, (Word16)0x0002, + (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, + (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, + (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002}; + +RAM_ALIGN const Word16 lpc_lin_pre_emphasis_60_0_72[60] = { + 0x50c9, 0x54d4, 0x5ce6, 0x68f9, 0x7906, 0x4681, 0x526e, 0x6043, 0x6ff6, 0x40be, 0x4a65, 0x54e8, 0x6040, 0x6c65, + 0x794f, 0x437a, 0x4aa6, 0x5226, 0x59f5, 0x620c, 0x6a68, 0x7301, 0x7bd2, 0x426a, 0x4701, 0x4baa, 0x5062, 0x5526, + 0x59f2, 0x5ec4, 0x6397, 0x6869, 0x6d35, 0x71f9, 0x76b1, 0x7b5a, 0x7ff1, 0x4239, 0x446d, 0x4694, 0x48aa, 0x4ab0, + 0x4ca4, 0x4e84, 0x504f, 0x5204, 0x53a1, 0x5526, 0x5691, 0x57e1, 0x5916, 0x5a2e, 0x5b29, 0x5c07, 0x5cc5, 0x5d65, + 0x5de6, 0x5e46, 0x5e87, 0x5ea7}; +RAM_ALIGN const Word16 lpc_lin_pre_emphasis_60_e_0_72[60] = { + (Word16)0xfffd, (Word16)0xfffd, (Word16)0xfffd, (Word16)0xfffd, (Word16)0xfffd, (Word16)0xfffe, (Word16)0xfffe, + (Word16)0xfffe, (Word16)0xfffe, (Word16)0xffff, (Word16)0xffff, (Word16)0xffff, (Word16)0xffff, (Word16)0xffff, + (Word16)0xffff, (Word16)0x0000, (Word16)0x0000, (Word16)0x0000, (Word16)0x0000, (Word16)0x0000, (Word16)0x0000, + (Word16)0x0000, (Word16)0x0000, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, + (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, + (Word16)0x0001, (Word16)0x0001, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, + (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, + (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, + (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002}; + +RAM_ALIGN const Word16 lpc_lin_pre_emphasis_60_0_82[60] = { + 0x4382, 0x4cb6, 0x5f17, 0x7a99, 0x4f94, 0x6656, 0x40c0, 0x5081, 0x6263, 0x7658, 0x4629, 0x5222, 0x5f0e, 0x6ce3, + 0x7b98, 0x4591, 0x4dbc, 0x5647, 0x5f2b, 0x6862, 0x71e7, 0x7bb2, 0x42de, 0x47ff, 0x4d39, 0x5288, 0x57e8, 0x5d55, + 0x62cc, 0x6849, 0x6dc8, 0x7345, 0x78bc, 0x7e29, 0x41c5, 0x446c, 0x4709, 0x499a, 0x4c1c, 0x4e8f, 0x50f0, 0x533e, + 0x5577, 0x579a, 0x59a4, 0x5b96, 0x5d6c, 0x5f27, 0x60c4, 0x6243, 0x63a3, 0x64e2, 0x6601, 0x66fd, 0x67d6, 0x688c, + 0x691e, 0x698c, 0x69d6, 0x69fb}; +RAM_ALIGN const Word16 lpc_lin_pre_emphasis_60_e_0_82[60] = { + (Word16)0xfffc, (Word16)0xfffc, (Word16)0xfffc, (Word16)0xfffc, (Word16)0xfffd, (Word16)0xfffd, (Word16)0xfffe, + (Word16)0xfffe, (Word16)0xfffe, (Word16)0xfffe, (Word16)0xffff, (Word16)0xffff, (Word16)0xffff, (Word16)0xffff, + (Word16)0xffff, (Word16)0x0000, (Word16)0x0000, (Word16)0x0000, (Word16)0x0000, (Word16)0x0000, (Word16)0x0000, + (Word16)0x0000, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, + (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0002, + (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, + (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, + (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, + (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002}; + +RAM_ALIGN const Word16 lpc_lin_pre_emphasis_60_0_92[60] = { + 0x7330, 0x62e5, 0x5ab1, 0x4c35, 0x753a, 0x5425, 0x72a0, 0x4afd, 0x5f0d, 0x7571, 0x470d, 0x547b, 0x62fa, 0x727f, + 0x4180, 0x4a38, 0x5362, 0x5cf7, 0x66f0, 0x7148, 0x7bf5, 0x4379, 0x491b, 0x4edc, 0x54b9, 0x5aae, 0x60b6, 0x66cd, + 0x6cee, 0x7316, 0x7941, 0x7f69, 0x42c5, 0x45d1, 0x48d4, 0x4bcf, 0x4ebd, 0x519e, 0x546f, 0x572e, 0x59d9, 0x5c6f, + 0x5eee, 0x6153, 0x639d, 0x65cb, 0x67dc, 0x69cc, 0x6b9c, 0x6d4a, 0x6ed4, 0x703b, 0x717c, 0x7296, 0x738a, 0x7457, + 0x74fb, 0x7576, 0x75c9, 0x75f2}; +RAM_ALIGN const Word16 lpc_lin_pre_emphasis_60_e_0_92[60] = { + (Word16)0xfff9, (Word16)0xfffa, (Word16)0xfffb, (Word16)0xfffc, (Word16)0xfffc, (Word16)0xfffd, (Word16)0xfffd, + (Word16)0xfffe, (Word16)0xfffe, (Word16)0xfffe, (Word16)0xffff, (Word16)0xffff, (Word16)0xffff, (Word16)0xffff, + (Word16)0x0000, (Word16)0x0000, (Word16)0x0000, (Word16)0x0000, (Word16)0x0000, (Word16)0x0000, (Word16)0x0000, + (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, + (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0001, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, + (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, + (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, + (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, + (Word16)0x0002, (Word16)0x0002, (Word16)0x0002, (Word16)0x0002}; + +RAM_ALIGN const Word16 *const lpc_lin_pre_emphasis_7_5ms[NUM_SAMP_FREQ] = { + lpc_lin_pre_emphasis_60_0_62, lpc_lin_pre_emphasis_60_0_72, lpc_lin_pre_emphasis_60_0_82, + lpc_lin_pre_emphasis_80_0_92, lpc_lin_pre_emphasis_60_0_92 +# ifdef ENABLE_HR_MODE + , lpc_lin_pre_emphasis_80_0_92 +# endif + }; +RAM_ALIGN const Word16 *const lpc_lin_pre_emphasis_e_7_5ms[NUM_SAMP_FREQ] = { + lpc_lin_pre_emphasis_60_e_0_62, lpc_lin_pre_emphasis_60_e_0_72, lpc_lin_pre_emphasis_60_e_0_82, + lpc_lin_pre_emphasis_80_e_0_92, lpc_lin_pre_emphasis_60_e_0_92 +# ifdef ENABLE_HR_MODE + , lpc_lin_pre_emphasis_80_e_0_92 +# endif + }; +# endif +# endif + +#ifdef SUBSET_NB +RAM_ALIGN const Word16 lpc_warp_dee_emphasis_16_8000[16] = {0x4000, 0x673f, 0x5348, 0x432d, 0x6c5f, 0x576a, + 0x4682, 0x71bf, 0x5bc0, 0x4a02, 0x7764, 0x604d, + 0x4dae, 0x7d50, 0x6514, 0x5188}; + +RAM_ALIGN const Word16 lpc_warp_dee_emphasis_16_e_8000[16] = { + (Word16)0x0001, (Word16)0x0000, (Word16)0x0000, (Word16)0x0000, (Word16)0xffff, (Word16)0xffff, + (Word16)0xffff, (Word16)0xfffe, (Word16)0xfffe, (Word16)0xfffe, (Word16)0xfffd, (Word16)0xfffd, + (Word16)0xfffd, (Word16)0xfffc, (Word16)0xfffc, (Word16)0xfffc}; +#else +#define lpc_warp_dee_emphasis_16_8000 NULL +#define lpc_warp_dee_emphasis_16_e_8000 NULL +#endif + +#ifdef SUBSET_WB +RAM_ALIGN const Word16 lpc_warp_dee_emphasis_16_16000[16] = {0x4000, 0x6119, 0x49a8, 0x6fc0, 0x54c5, 0x404e, + 0x618f, 0x4a02, 0x7048, 0x552c, 0x409c, 0x6206, + 0x4a5c, 0x70d0, 0x5594, 0x40eb}; + +RAM_ALIGN const Word16 lpc_warp_dee_emphasis_16_e_16000[16] = { + (Word16)0x0001, (Word16)0x0000, (Word16)0x0000, (Word16)0xffff, (Word16)0xffff, (Word16)0xffff, + (Word16)0xfffe, (Word16)0xfffe, (Word16)0xfffd, (Word16)0xfffd, (Word16)0xfffd, (Word16)0xfffc, + (Word16)0xfffc, (Word16)0xfffb, (Word16)0xfffb, (Word16)0xfffb}; +#else +#define lpc_warp_dee_emphasis_16_16000 NULL +#define lpc_warp_dee_emphasis_16_e_16000 NULL +#endif + +#ifdef SUBSET_SSWB +RAM_ALIGN const Word16 lpc_warp_dee_emphasis_16_24000[16] = {0x4000, 0x5b51, 0x4125, 0x5cf3, 0x424f, 0x5e9c, + 0x437f, 0x604d, 0x44b4, 0x6206, 0x45ee, 0x63c7, + 0x472e, 0x658f, 0x4874, 0x6760}; + +RAM_ALIGN const Word16 lpc_warp_dee_emphasis_16_e_24000[16] = { + (Word16)0x0001, (Word16)0x0000, (Word16)0x0000, (Word16)0xffff, (Word16)0xffff, (Word16)0xfffe, + (Word16)0xfffe, (Word16)0xfffd, (Word16)0xfffd, (Word16)0xfffc, (Word16)0xfffc, (Word16)0xfffb, + (Word16)0xfffb, (Word16)0xfffa, (Word16)0xfffa, (Word16)0xfff9}; +#else +#define lpc_warp_dee_emphasis_16_24000 NULL +#define lpc_warp_dee_emphasis_16_e_24000 NULL +#endif + +#ifdef SUBSET_SWB +RAM_ALIGN const Word16 lpc_warp_dee_emphasis_16_32000[16] = {0x4000, 0x55e1, 0x733b, 0x4d50, 0x67bd, 0x4599, + 0x5d64, 0x7d50, 0x5413, 0x70d0, 0x4bb0, 0x658f, + 0x4423, 0x5b6e, 0x7aaf, 0x524f}; + +RAM_ALIGN const Word16 lpc_warp_dee_emphasis_16_e_32000[16] = { + (Word16)0x0001, (Word16)0x0000, (Word16)0xffff, (Word16)0xffff, (Word16)0xfffe, (Word16)0xfffe, + (Word16)0xfffd, (Word16)0xfffc, (Word16)0xfffc, (Word16)0xfffb, (Word16)0xfffb, (Word16)0xfffa, + (Word16)0xfffa, (Word16)0xfff9, (Word16)0xfff8, (Word16)0xfff8}; +#else +#define lpc_warp_dee_emphasis_16_32000 NULL +#define lpc_warp_dee_emphasis_16_e_32000 NULL +#endif + +#ifdef SUBSET_FB +RAM_ALIGN const Word16 lpc_warp_dee_emphasis_16_48000[16] = {0x4000, 0x50c3, 0x65ea, 0x404e, 0x5126, 0x6666, + 0x409c, 0x5188, 0x66e3, 0x40eb, 0x51ec, 0x6760, + 0x413a, 0x524f, 0x67de, 0x4189}; + +RAM_ALIGN const Word16 lpc_warp_dee_emphasis_16_e_48000[16] = { + (Word16)0x0001, (Word16)0x0000, (Word16)0xffff, (Word16)0xffff, (Word16)0xfffe, (Word16)0xfffd, + (Word16)0xfffd, (Word16)0xfffc, (Word16)0xfffb, (Word16)0xfffb, (Word16)0xfffa, (Word16)0xfff9, + (Word16)0xfff9, (Word16)0xfff8, (Word16)0xfff7, (Word16)0xfff7}; +#else +#define lpc_warp_dee_emphasis_16_48000 NULL +#define lpc_warp_dee_emphasis_16_e_48000 NULL +#endif + +# ifdef ENABLE_HR_MODE +RAM_ALIGN const Word16 lpc_warp_dee_emphasis_16_96000[16] = {0x4000, 0x4bf4, 0x5a23, 0x6af9, 0x7ef3, 0x4b54, + 0x5966, 0x6a18, 0x7de9, 0x4ab6, 0x58aa, 0x6939, + 0x7ce0, 0x4a19, 0x57f0, 0x685d}; + +RAM_ALIGN const Word16 lpc_warp_dee_emphasis_16_e_96000[16] = { + (Word16)0x0001, (Word16)0x0000, (Word16)0xffff, (Word16)0xfffe, (Word16)0xfffd, (Word16)0xfffd, + (Word16)0xfffc, (Word16)0xfffb, (Word16)0xfffa, (Word16)0xfffa, (Word16)0xfff9, (Word16)0xfff8, + (Word16)0xfff7, (Word16)0xfff7, (Word16)0xfff6, (Word16)0xfff5}; +# else +# define lpc_warp_dee_emphasis_16_96000 NULL +# define lpc_warp_dee_emphasis_16_e_96000 NULL +# endif + +RAM_ALIGN const Word16 *const lpc_warp_dee_emphasis[NUM_SAMP_FREQ] = { + lpc_warp_dee_emphasis_16_8000, lpc_warp_dee_emphasis_16_16000, lpc_warp_dee_emphasis_16_24000, + lpc_warp_dee_emphasis_16_32000, lpc_warp_dee_emphasis_16_48000, lpc_warp_dee_emphasis_16_96000}; +RAM_ALIGN const Word16 *const lpc_warp_dee_emphasis_e[NUM_SAMP_FREQ] = { + lpc_warp_dee_emphasis_16_e_8000, lpc_warp_dee_emphasis_16_e_16000, lpc_warp_dee_emphasis_16_e_24000, + lpc_warp_dee_emphasis_16_e_32000, lpc_warp_dee_emphasis_16_e_48000, lpc_warp_dee_emphasis_16_e_96000}; + +RAM_ALIGN const Word16 bands_nrg_scale[32] = {0, 0, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, + 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4}; + +#ifdef ENABLE_HR_MODE +RAM_ALIGN const Word16 bands_offset_48000_HR[65] = { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 19, 21, 23, 25, + 27, 29, 31, 33, 36, 39, 42, 45, 48, 51, 55, 59, 63, 67, 72, 77, 83, 89, 95, 101, 108, 116, + 124, 133, 142, 152, 163, 174, 187, 200, 214, 229, 244, 262, 280, 299, 320, 343, 367, 392, 419, 449, 480}; + +RAM_ALIGN const Word16 bands_offset_96000_HR[65] = { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, + 33, 36, 39, 42, 46, 50, 54, 59, 64, 69, 75, 82, 89, 96, 104, 113, 122, 132, 143, 155, 168, 181, + 196, 213, 230, 249, 270, 292, 316, 342, 371, 401, 434, 470, 509, 551, 596, 646, 699, 757, 819, 887, 960}; + +RAM_ALIGN const Word16 *const bands_offset_HR[2] = {bands_offset_48000_HR, bands_offset_96000_HR}; + +RAM_ALIGN const Word16 bands_offset_48000_5ms_HR[56] = { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, + 19, 21, 23, 25, 27, 29, 31, 33, 35, 38, 41, 44, 47, 50, 54, 58, 62, 66, 71, + 76, 81, 87, 93, 100, 107, 114, 122, 131, 140, 149, 160, 171, 183, 196, 209, 224, 240}; +RAM_ALIGN const Word16 bands_offset_96000_5ms_HR[59] = { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 19, 21, + 23, 25, 27, 29, 31, 34, 37, 40, 44, 48, 52, 56, 61, 66, 71, 77, 83, 90, 98, 106, + 115, 124, 135, 146, 158, 171, 185, 200, 217, 235, 254, 275, 298, 323, 349, 378, 409, 443, 480}; + +RAM_ALIGN const Word16 *const bands_offset_5ms_HR[2] = {bands_offset_48000_5ms_HR, bands_offset_96000_5ms_HR}; + +RAM_ALIGN const Word16 bands_offset_48000_2_5ms_HR[46] = { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 21, 23, 25, + 27, 29, 31, 33, 35, 37, 40, 43, 46, 49, 53, 57, 61, 65, 69, 74, 79, 85, 91, 97, 104, 112, 120}; +RAM_ALIGN const Word16 bands_offset_96000_2_5ms_HR[50] = { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 18, 20, 22, 24, 26, 28, 30, 32, + 35, 38, 41, 45, 49, 53, 57, 62, 67, 73, 79, 85, 92, 100, 108, 117, 127, 137, 149, 161, 174, 189, 204, 221, 240}; + +RAM_ALIGN const Word16 *const bands_offset_2_5ms_HR[2] = {bands_offset_48000_2_5ms_HR, bands_offset_96000_2_5ms_HR}; + +#ifdef CR8_G_ADD_75MS +RAM_ALIGN const Word16 bands_offset_48000_7_5ms_HR[65] = { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 22, 24, + 26, 28, 30, 32, 34, 36, 38, 41, 44, 47, 50, 53, 56, 60, 64, 68, 73, 78, 83, 89, 95, 101, 108, + 115, 122, 130, 139, 148, 158, 168, 179, 191, 203, 217, 231, 246, 262, 279, 298, 317, 338, 360}; +RAM_ALIGN const Word16 bands_offset_96000_7_5ms_HR[65] = { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 18, 20, 22, 24, 26, 28, + 30, 32, 35, 38, 41, 44, 48, 52, 56, 61, 66, 71, 77, 83, 90, 97, 105, 114, 123, 132, 143, 155, 167, + 180, 195, 210, 227, 245, 265, 286, 309, 334, 360, 389, 420, 454, 490, 529, 572, 617, 667, 720}; + +RAM_ALIGN const Word16 *const bands_offset_7_5ms_HR[2] = {bands_offset_48000_7_5ms_HR, bands_offset_96000_7_5ms_HR}; +# endif +#endif /* ENABLE_HR_MODE */ + +#ifdef SUBSET_NB +RAM_ALIGN const Word16 bands_offset_8000_lpc_warp[65] = { + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, + 0x000d, 0x000e, 0x000f, 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018, 0x0019, + 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, + 0x0027, 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, 0x0030, 0x0031, 0x0033, 0x0035, + 0x0037, 0x0039, 0x003b, 0x003d, 0x003f, 0x0041, 0x0043, 0x0045, 0x0047, 0x0049, 0x004b, 0x004d, 0x0050}; +#else +#define bands_offset_8000_lpc_warp NULL +#endif + +#ifdef SUBSET_WB +RAM_ALIGN const Word16 bands_offset_16000_lpc_warp[65] = { + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, + 0x000d, 0x000e, 0x000f, 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018, 0x0019, + 0x001a, 0x001b, 0x001c, 0x001e, 0x0020, 0x0022, 0x0024, 0x0026, 0x0028, 0x002a, 0x002c, 0x002e, 0x0030, + 0x0032, 0x0034, 0x0037, 0x003a, 0x003d, 0x0040, 0x0043, 0x0046, 0x0049, 0x004c, 0x0050, 0x0054, 0x0058, + 0x005c, 0x0060, 0x0065, 0x006a, 0x006f, 0x0074, 0x0079, 0x007f, 0x0085, 0x008b, 0x0092, 0x0099, 0x00a0}; +#else +#define bands_offset_16000_lpc_warp NULL +#endif + +#ifdef SUBSET_SSWB +RAM_ALIGN const Word16 bands_offset_24000_lpc_warp[65] = { + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, + 0x000d, 0x000e, 0x000f, 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0019, 0x001b, + 0x001d, 0x001f, 0x0021, 0x0023, 0x0025, 0x0027, 0x0029, 0x002b, 0x002e, 0x0031, 0x0034, 0x0037, 0x003a, + 0x003d, 0x0040, 0x0044, 0x0048, 0x004c, 0x0050, 0x0055, 0x005a, 0x005f, 0x0064, 0x006a, 0x0070, 0x0076, + 0x007d, 0x0084, 0x008b, 0x0093, 0x009b, 0x00a4, 0x00ad, 0x00b7, 0x00c1, 0x00cc, 0x00d7, 0x00e3, 0x00f0}; +#else +#define bands_offset_24000_lpc_warp NULL +#endif + +#ifdef SUBSET_SWB +RAM_ALIGN const Word16 bands_offset_32000_lpc_warp[65] = { + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, + 0x000d, 0x000e, 0x000f, 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0016, 0x0018, 0x001a, 0x001c, 0x001e, + 0x0020, 0x0022, 0x0024, 0x0026, 0x0029, 0x002c, 0x002f, 0x0032, 0x0035, 0x0038, 0x003c, 0x0040, 0x0044, + 0x0048, 0x004c, 0x0051, 0x0056, 0x005b, 0x0061, 0x0067, 0x006d, 0x0074, 0x007b, 0x0083, 0x008b, 0x0094, + 0x009d, 0x00a6, 0x00b0, 0x00bb, 0x00c7, 0x00d3, 0x00e0, 0x00ee, 0x00fc, 0x010c, 0x011c, 0x012e, 0x0140}; +#else +#define bands_offset_32000_lpc_warp NULL +#endif + +#ifdef SUBSET_FB +RAM_ALIGN const Word16 bands_offset_48000_lpc_warp[65] = { + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, + 0x000d, 0x000e, 0x000f, 0x0010, 0x0011, 0x0012, 0x0014, 0x0016, 0x0018, 0x001a, 0x001c, 0x001e, 0x0020, + 0x0022, 0x0024, 0x0027, 0x002a, 0x002d, 0x0030, 0x0033, 0x0037, 0x003b, 0x003f, 0x0043, 0x0047, 0x004c, + 0x0051, 0x0056, 0x005c, 0x0062, 0x0069, 0x0070, 0x0077, 0x007f, 0x0087, 0x0090, 0x009a, 0x00a4, 0x00af, + 0x00ba, 0x00c6, 0x00d3, 0x00e1, 0x00f0, 0x0100, 0x0111, 0x0123, 0x0136, 0x014a, 0x0160, 0x0177, 0x0190}; +#else +#define bands_offset_48000_lpc_warp NULL +#endif + +#ifdef SUBSET_NB +RAM_ALIGN const Word16 bands_offset_8000_lpc_lin[81] = { + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, + 0x000e, 0x000f, 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018, 0x0019, 0x001a, 0x001b, + 0x001c, 0x001d, 0x001e, 0x001f, 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, + 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, + 0x0046, 0x0047, 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, 0x0050}; +#else +#define bands_offset_8000_lpc_lin NULL +#endif + +#ifdef SUBSET_WB +RAM_ALIGN const Word16 bands_offset_16000_lpc_lin[81] = { + 0x0000, 0x0002, 0x0004, 0x0006, 0x0008, 0x000a, 0x000c, 0x000e, 0x0010, 0x0012, 0x0014, 0x0016, 0x0018, 0x001a, + 0x001c, 0x001e, 0x0020, 0x0022, 0x0024, 0x0026, 0x0028, 0x002a, 0x002c, 0x002e, 0x0030, 0x0032, 0x0034, 0x0036, + 0x0038, 0x003a, 0x003c, 0x003e, 0x0040, 0x0042, 0x0044, 0x0046, 0x0048, 0x004a, 0x004c, 0x004e, 0x0050, 0x0052, + 0x0054, 0x0056, 0x0058, 0x005a, 0x005c, 0x005e, 0x0060, 0x0062, 0x0064, 0x0066, 0x0068, 0x006a, 0x006c, 0x006e, + 0x0070, 0x0072, 0x0074, 0x0076, 0x0078, 0x007a, 0x007c, 0x007e, 0x0080, 0x0082, 0x0084, 0x0086, 0x0088, 0x008a, + 0x008c, 0x008e, 0x0090, 0x0092, 0x0094, 0x0096, 0x0098, 0x009a, 0x009c, 0x009e, 0x00a0}; +#else +#define bands_offset_16000_lpc_lin NULL +#endif + +#ifdef SUBSET_SSWB +RAM_ALIGN const Word16 bands_offset_24000_lpc_lin[81] = { + 0x0000, 0x0003, 0x0006, 0x0009, 0x000c, 0x000f, 0x0012, 0x0015, 0x0018, 0x001b, 0x001e, 0x0021, 0x0024, 0x0027, + 0x002a, 0x002d, 0x0030, 0x0033, 0x0036, 0x0039, 0x003c, 0x003f, 0x0042, 0x0045, 0x0048, 0x004b, 0x004e, 0x0051, + 0x0054, 0x0057, 0x005a, 0x005d, 0x0060, 0x0063, 0x0066, 0x0069, 0x006c, 0x006f, 0x0072, 0x0075, 0x0078, 0x007b, + 0x007e, 0x0081, 0x0084, 0x0087, 0x008a, 0x008d, 0x0090, 0x0093, 0x0096, 0x0099, 0x009c, 0x009f, 0x00a2, 0x00a5, + 0x00a8, 0x00ab, 0x00ae, 0x00b1, 0x00b4, 0x00b7, 0x00ba, 0x00bd, 0x00c0, 0x00c3, 0x00c6, 0x00c9, 0x00cc, 0x00cf, + 0x00d2, 0x00d5, 0x00d8, 0x00db, 0x00de, 0x00e1, 0x00e4, 0x00e7, 0x00ea, 0x00ed, 0x00f0}; +#else +#define bands_offset_24000_lpc_lin NULL +#endif + +#ifdef SUBSET_SWB +RAM_ALIGN const Word16 bands_offset_32000_lpc_lin[81] = { + 0x0000, 0x0004, 0x0008, 0x000c, 0x0010, 0x0014, 0x0018, 0x001c, 0x0020, 0x0024, 0x0028, 0x002c, 0x0030, 0x0034, + 0x0038, 0x003c, 0x0040, 0x0044, 0x0048, 0x004c, 0x0050, 0x0054, 0x0058, 0x005c, 0x0060, 0x0064, 0x0068, 0x006c, + 0x0070, 0x0074, 0x0078, 0x007c, 0x0080, 0x0084, 0x0088, 0x008c, 0x0090, 0x0094, 0x0098, 0x009c, 0x00a0, 0x00a4, + 0x00a8, 0x00ac, 0x00b0, 0x00b4, 0x00b8, 0x00bc, 0x00c0, 0x00c4, 0x00c8, 0x00cc, 0x00d0, 0x00d4, 0x00d8, 0x00dc, + 0x00e0, 0x00e4, 0x00e8, 0x00ec, 0x00f0, 0x00f4, 0x00f8, 0x00fc, 0x0100, 0x0104, 0x0108, 0x010c, 0x0110, 0x0114, + 0x0118, 0x011c, 0x0120, 0x0124, 0x0128, 0x012c, 0x0130, 0x0134, 0x0138, 0x013c, 0x0140}; +#else +#define bands_offset_32000_lpc_lin NULL +#endif + +#ifdef SUBSET_FB +RAM_ALIGN const Word16 bands_offset_48000_lpc_lin[81] = { + 0x0000, 0x0006, 0x000c, 0x0012, 0x0018, 0x001e, 0x0024, 0x002a, 0x0030, 0x0036, 0x003c, 0x0042, 0x0048, 0x004e, + 0x0054, 0x005a, 0x0060, 0x0066, 0x006c, 0x0072, 0x0078, 0x007e, 0x0084, 0x008a, 0x0090, 0x0096, 0x009c, 0x00a2, + 0x00a8, 0x00ae, 0x00b4, 0x00ba, 0x00c0, 0x00c6, 0x00cc, 0x00d2, 0x00d8, 0x00de, 0x00e4, 0x00ea, 0x00f0, 0x00f6, + 0x00fc, 0x0102, 0x0108, 0x010e, 0x0114, 0x011a, 0x0120, 0x0126, 0x012c, 0x0132, 0x0138, 0x013e, 0x0144, 0x014a, + 0x0150, 0x0156, 0x015c, 0x0162, 0x0168, 0x016e, 0x0174, 0x017a, 0x0180, 0x0186, 0x018c, 0x0192, 0x0198, 0x019e, + 0x01a4, 0x01aa, 0x01b0, 0x01b6, 0x01bc, 0x01c2, 0x01c8, 0x01ce, 0x01d4, 0x01da, 0x01e0}; +#else +#define bands_offset_48000_lpc_lin NULL +#endif + +#ifdef SUBSET_NB +RAM_ALIGN const Word16 bands_offset_8000_lpc_warp_5ms[40] = { + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, + 0x000e, 0x000f, 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018, 0x0019, 0x001a, 0x001b, + 0x001c, 0x001d, 0x001e, 0x001f, 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0028}; +#else +#define bands_offset_8000_lpc_warp_5ms NULL +#endif + +#ifdef SUBSET_WB +RAM_ALIGN const Word16 bands_offset_16000_lpc_warp_5ms[51] = { + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, + 0x000d, 0x000e, 0x000f, 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018, 0x0019, + 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x0020, 0x0022, 0x0024, 0x0026, 0x0028, 0x002a, 0x002c, 0x002e, + 0x0030, 0x0032, 0x0034, 0x0036, 0x0039, 0x003c, 0x003f, 0x0042, 0x0045, 0x0048, 0x004c, 0x0050}; +#else +#define bands_offset_16000_lpc_warp_5ms NULL +#endif + +#ifdef SUBSET_SSWB +RAM_ALIGN const Word16 bands_offset_24000_lpc_warp_5ms[53] = { + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, + 0x000e, 0x000f, 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018, 0x001a, 0x001c, 0x001e, + 0x0020, 0x0022, 0x0024, 0x0026, 0x0028, 0x002a, 0x002c, 0x002f, 0x0032, 0x0035, 0x0038, 0x003b, 0x003e, 0x0041, + 0x0045, 0x0049, 0x004d, 0x0051, 0x0056, 0x005b, 0x0060, 0x0065, 0x006b, 0x0071, 0x0078}; +#else +#define bands_offset_24000_lpc_warp_5ms NULL +#endif + +#ifdef SUBSET_SWB +RAM_ALIGN const Word16 bands_offset_32000_lpc_warp_5ms[55] = { + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, + 0x000e, 0x000f, 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0018, 0x001a, 0x001c, 0x001e, 0x0020, + 0x0022, 0x0024, 0x0026, 0x0028, 0x002a, 0x002d, 0x0030, 0x0033, 0x0036, 0x0039, 0x003d, 0x0041, 0x0045, 0x0049, + 0x004e, 0x0053, 0x0058, 0x005d, 0x0063, 0x0069, 0x0070, 0x0077, 0x007e, 0x0086, 0x008e, 0x0097, 0x00a0}; +#else +#define bands_offset_32000_lpc_warp_5ms NULL +#endif + +#ifdef SUBSET_FB +RAM_ALIGN const Word16 bands_offset_48000_lpc_warp_5ms[56] = { + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, + 0x000e, 0x000f, 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0017, 0x0019, 0x001b, 0x001d, 0x001f, 0x0021, + 0x0023, 0x0025, 0x0028, 0x002b, 0x002e, 0x0031, 0x0034, 0x0037, 0x003b, 0x003f, 0x0043, 0x0048, 0x004d, 0x0052, + 0x0057, 0x005d, 0x0063, 0x0069, 0x0070, 0x0078, 0x0080, 0x0088, 0x0091, 0x009b, 0x00a5, 0x00b0, 0x00bb, 0x00c8}; +#else +#define bands_offset_48000_lpc_warp_5ms NULL +#endif + + +#ifdef SUBSET_NB +RAM_ALIGN const Word16 bands_offset_8000_lpc_warp_2_5ms[21] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, + 11, 12, 13, 14, 15, 16, 17, 18, 19, 20}; +#else +#define bands_offset_8000_lpc_warp_2_5ms NULL +#endif + +#ifdef SUBSET_WB +RAM_ALIGN const Word16 bands_offset_16000_lpc_warp_2_5ms[36] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, + 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, + 24, 25, 26, 27, 28, 29, 30, 32, 34, 36, 38, 40}; +#else +#define bands_offset_16000_lpc_warp_2_5ms NULL +#endif + +#ifdef SUBSET_SSWB +RAM_ALIGN const Word16 bands_offset_24000_lpc_warp_2_5ms[41] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, + 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 28, + 30, 32, 34, 36, 38, 40, 42, 44, 47, 50, 53, 56, 60}; +#else +#define bands_offset_24000_lpc_warp_2_5ms NULL +#endif + +#ifdef SUBSET_SWB +RAM_ALIGN const Word16 bands_offset_32000_lpc_warp_2_5ms[44] = { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, + 22, 23, 24, 26, 28, 30, 32, 34, 36, 38, 40, 43, 46, 49, 52, 55, 59, 63, 67, 71, 75, 80}; +#else +#define bands_offset_32000_lpc_warp_2_5ms NULL +#endif + +#ifdef SUBSET_FB +RAM_ALIGN const Word16 bands_offset_48000_lpc_warp_2_5ms[45] = { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 23, + 25, 27, 29, 31, 33, 35, 37, 40, 43, 46, 49, 52, 56, 60, 64, 68, 72, 77, 82, 87, 93, 100}; +#else +#define bands_offset_48000_lpc_warp_2_5ms NULL +#endif + + + +RAM_ALIGN const Word16 *const bands_offset[6] = {bands_offset_8000_lpc_warp, bands_offset_16000_lpc_warp, + bands_offset_24000_lpc_warp, bands_offset_32000_lpc_warp, + bands_offset_48000_lpc_warp, NULL}; + +#ifdef CR8_G_ADD_75MS +RAM_ALIGN const Word16 bands_offset_with_one_max_7_5ms[NUM_OFFSETS] = {60, 34, 27, 24, 22 +# ifdef ENABLE_HR_MODE + , 20, 16 +# endif +}; +RAM_ALIGN const Word16 bands_offset_with_two_max_7_5ms[NUM_OFFSETS] = {0, 48, 38, 33, 31 +# ifdef ENABLE_HR_MODE + , 29, 24 +# endif +}; +# endif + +RAM_ALIGN const Word16 bands_offset_with_one_max[NUM_OFFSETS] = {49, 28, 23, 20, 18 +# ifdef ENABLE_HR_MODE + , 17, 12 +# endif + }; +RAM_ALIGN const Word16 bands_offset_with_two_max[NUM_OFFSETS] = {63, 40, 33, 29, 27 +# ifdef ENABLE_HR_MODE + , 25, 21 +# endif + }; + +RAM_ALIGN const Word16 *const bands_offset_5ms[6] = {bands_offset_8000_lpc_warp_5ms, bands_offset_16000_lpc_warp_5ms, + bands_offset_24000_lpc_warp_5ms, bands_offset_32000_lpc_warp_5ms, + bands_offset_48000_lpc_warp_5ms, NULL}; +RAM_ALIGN const Word16 bands_offset_with_one_max_5ms[NUM_OFFSETS] = {38, 30, 24, 22, 21 +# ifdef ENABLE_HR_MODE + , 19, 17 +# endif + }; +RAM_ALIGN const Word16 bands_offset_with_two_max_5ms[NUM_OFFSETS] = {39, 42, 34, 32, 29 +# ifdef ENABLE_HR_MODE + , 27, 24 +# endif + }; + +#ifdef CR8_G_ADD_75MS +# ifdef ENABLE_HR_MODE +RAM_ALIGN const Word16 bands_number_7_5ms [] = {60, 64, 64, 64, 64, 64}; +# else +RAM_ALIGN const Word16 bands_number_7_5ms [] = {60, 64, 64, 64, 64}; +# endif +#endif + +#ifdef ENABLE_HR_MODE +RAM_ALIGN const Word16 bands_number_5ms[NUM_SAMP_FREQ] = {39, 50, 52, 54, 55, 58}; +#else +RAM_ALIGN const Word16 bands_number_5ms[NUM_SAMP_FREQ] = {39, 50, 52, 54, 55}; +#endif + +RAM_ALIGN const Word16 *const bands_offset_2_5ms[6] = { + bands_offset_8000_lpc_warp_2_5ms, bands_offset_16000_lpc_warp_2_5ms, bands_offset_24000_lpc_warp_2_5ms, + bands_offset_32000_lpc_warp_2_5ms, bands_offset_48000_lpc_warp_2_5ms, NULL}; + +RAM_ALIGN const Word16 bands_offset_with_one_max_2_5ms[NUM_OFFSETS] = {20, 30, 26, 24, 21 +# ifdef ENABLE_HR_MODE + , 19, 16 +# endif + }; +RAM_ALIGN const Word16 bands_offset_with_two_max_2_5ms[NUM_OFFSETS] = {20, 35, 35, 32, 29 +# ifdef ENABLE_HR_MODE + , 28, 24 +# endif + }; + +# ifdef ENABLE_HR_MODE +RAM_ALIGN const Word16 bands_number_2_5ms_HR[] = {20, 35, 40, 43, 45, 49}; +RAM_ALIGN const Word16 bands_number_2_5ms [] = {20, 35, 40, 43, 44, 49}; +# else +RAM_ALIGN const Word16 bands_number_2_5ms [] = {20, 35, 40, 43, 44}; +# endif + +# ifdef ENABLE_HR_MODE +RAM_ALIGN const Word16 bands_offset_96000_lpc_lin[81] = +{ + 0x0000, 0x000c, 0x0018, 0x0024, 0x0030, 0x003c, 0x0048, 0x0054, 0x0060, 0x006c, 0x0078, 0x0084, 0x0090, 0x009c, + 0x00a8, 0x00b4, 0x00c0, 0x00cc, 0x00d8, 0x00e4, 0x00f0, 0x00fc, 0x0108, 0x0114, 0x0120, 0x012c, 0x0138, 0x0144, + 0x0150, 0x015c, 0x0168, 0x0174, 0x0180, 0x018c, 0x0198, 0x01a4, 0x01b0, 0x01bc, 0x01c8, 0x01d4, 0x01e0, 0x01ec, + 0x01f8, 0x0204, 0x0210, 0x021c, 0x0228, 0x0234, 0x0240, 0x024c, 0x0258, 0x0264, 0x0270, 0x027c, 0x0288, 0x0294, + 0x02a0, 0x02ac, 0x02b8, 0x02c4, 0x02d0, 0x02dc, 0x02e8, 0x02f4, 0x0300, 0x030c, 0x0318, 0x0324, 0x0330, 0x033c, + 0x0348, 0x0354, 0x0360, 0x036c, 0x0378, 0x0384, 0x0390, 0x039c, 0x03a8, 0x03b4, 0x03c0 +}; + +# ifdef CR8_G_ADD_75MS +RAM_ALIGN const Word16 bands_offset_96000_lpc_lin_7_5ms[81] = +{ + 0x0000, 0x0009, 0x0012, 0x001b, 0x0024, 0x002d, 0x0036, 0x003f, 0x0048, 0x0051, 0x005a, 0x0063, 0x006c, 0x0075, + 0x007e, 0x0087, 0x0090, 0x0099, 0x00a2, 0x00ab, 0x00b4, 0x00bd, 0x00c6, 0x00cf, 0x00d8, 0x00e1, 0x00ea, 0x00f3, + 0x00fc, 0x0105, 0x010e, 0x0117, 0x0120, 0x0129, 0x0132, 0x013b, 0x0144, 0x014d, 0x0156, 0x015f, 0x0168, 0x0171, + 0x017a, 0x0183, 0x018c, 0x0195, 0x019e, 0x01a7, 0x01b0, 0x01b9, 0x01c2, 0x01cb, 0x01d4, 0x01dd, 0x01e6, 0x01ef, + 0x01f8, 0x0201, 0x020a, 0x0213, 0x021c, 0x0225, 0x022e, 0x0237, 0x0240, 0x0249, 0x0252, 0x025b, 0x0264, 0x026d, + 0x0276, 0x027f, 0x0288, 0x0291, 0x029a, 0x02a3, 0x02ac, 0x02b5, 0x02be, 0x02c7, 0x02d0 +}; +# endif +# endif + + +RAM_ALIGN const Word16 *const bands_offset_lin[NUM_SAMP_FREQ] = {bands_offset_8000_lpc_lin, bands_offset_16000_lpc_lin, + bands_offset_24000_lpc_lin, bands_offset_32000_lpc_lin, + bands_offset_48000_lpc_lin +# ifdef ENABLE_HR_MODE + , bands_offset_96000_lpc_lin +# endif + }; + +# ifdef CR8_G_ADD_75MS +RAM_ALIGN const Word16 *const bands_offset_lin_7_5ms[NUM_SAMP_FREQ] = {bands_offset_8000_lpc_lin, bands_offset_16000_lpc_lin, + bands_offset_24000_lpc_lin, bands_offset_24000_lpc_lin, + bands_offset_48000_lpc_lin +# ifdef ENABLE_HR_MODE + , bands_offset_96000_lpc_lin_7_5ms +# endif + }; +# endif + +RAM_ALIGN const Word16 *const bands_offset_lin_5ms[NUM_SAMP_FREQ] = {bands_offset_8000_lpc_lin, bands_offset_8000_lpc_lin, + bands_offset_24000_lpc_lin, bands_offset_16000_lpc_lin, + bands_offset_24000_lpc_lin +# ifdef ENABLE_HR_MODE + , bands_offset_48000_lpc_lin +# endif + }; +RAM_ALIGN const Word16 *const bands_offset_lin_2_5ms[NUM_SAMP_FREQ] = {bands_offset_8000_lpc_lin, bands_offset_8000_lpc_lin, + bands_offset_8000_lpc_lin, bands_offset_8000_lpc_lin, + bands_offset_16000_lpc_lin +# ifdef ENABLE_HR_MODE + , bands_offset_24000_lpc_lin +# endif + }; + +RAM_ALIGN const Word16 bands_offset_with_one_max_lin[NUM_SAMP_FREQ] = {80, 0, 0, 0, 0 +# ifdef ENABLE_HR_MODE + , 0 +# endif + }; +RAM_ALIGN const Word16 bands_offset_with_two_max_lin[NUM_SAMP_FREQ] = {0, 80, 0, 0, 0 +# ifdef ENABLE_HR_MODE + , 0 +# endif + }; + +# ifdef CR8_G_ADD_75MS +RAM_ALIGN const Word16 bands_offset_with_one_max_lin_7_5ms[NUM_SAMP_FREQ] = {60, 0, 0, 0, 0 +# ifdef ENABLE_HR_MODE + , 0 +# endif + }; + +RAM_ALIGN const Word16 bands_offset_with_two_max_lin_7_5ms[NUM_SAMP_FREQ] = {0, 60, 0, 0, 0 +# ifdef ENABLE_HR_MODE + , 0 +# endif + }; +#endif + +RAM_ALIGN const Word16 bands_offset_with_one_max_lin_5ms[NUM_SAMP_FREQ] = {40, 80, 0, 0, 0 +# ifdef ENABLE_HR_MODE + , 0 +# endif + }; +RAM_ALIGN const Word16 bands_offset_with_two_max_lin_5ms[NUM_SAMP_FREQ] = {0, 0, 0, 80, 0 +# ifdef ENABLE_HR_MODE + , 0 +# endif + }; +RAM_ALIGN const Word16 bands_offset_with_one_max_lin_2_5ms[NUM_SAMP_FREQ] = {20, 40, 60, 80, 0 +# ifdef ENABLE_HR_MODE + , 0 +# endif + }; +RAM_ALIGN const Word16 bands_offset_with_two_max_lin_2_5ms[NUM_SAMP_FREQ] = {0, 0, 0, 0, 60 +# ifdef ENABLE_HR_MODE + , 0 +# endif + }; +#ifdef CR8_G_ADD_75MS +# ifdef SUBSET_NB +RAM_ALIGN const Word16 bands_offset_8000_lpc_warp_7_5ms[61] = { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, + 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, + 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60}; +# else +# define bands_offset_8000_lpc_warp_7_5ms NULL +# endif + +# ifdef SUBSET_WB +RAM_ALIGN const Word16 bands_offset_16000_lpc_warp_7_5ms[65] = { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, + 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 36, 38, 40, 42, 44, 46, 48, 50, 52, + 54, 56, 58, 60, 62, 65, 68, 71, 74, 77, 80, 83, 86, 90, 94, 98, 102, 106, 110, 115, 120}; +# else +# define bands_offset_16000_lpc_warp_7_5ms NULL +# endif + +# ifdef SUBSET_SSWB +RAM_ALIGN const Word16 bands_offset_24000_lpc_warp_7_5ms[65] = { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, + 22, 23, 24, 25, 26, 27, 29, 31, 33, 35, 37, 39, 41, 43, 45, 47, 49, 52, 55, 58, 61, 64, + 67, 70, 74, 78, 82, 86, 90, 95, 100, 105, 110, 115, 121, 127, 134, 141, 148, 155, 163, 171, 180}; +# else +# define bands_offset_24000_lpc_warp_7_5ms NULL +# endif + +# ifdef SUBSET_SWB +RAM_ALIGN const Word16 bands_offset_32000_lpc_warp_7_5ms[65] = { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, + 22, 23, 24, 26, 28, 30, 32, 34, 36, 38, 40, 42, 45, 48, 51, 54, 57, 60, 63, 67, 71, 75, + 79, 84, 89, 94, 99, 105, 111, 117, 124, 131, 138, 146, 154, 163, 172, 182, 192, 203, 215, 227, 240}; +# else +# define bands_offset_32000_lpc_warp_7_5ms NULL +# endif + +# ifdef SUBSET_FB +RAM_ALIGN const Word16 bands_offset_48000_lpc_warp_7_5ms[65] = { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, + 22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 43, 46, 49, 52, 55, 59, 63, 67, 71, 75, 80, 85, + 90, 96, 102, 108, 115, 122, 129, 137, 146, 155, 165, 175, 186, 197, 209, 222, 236, 251, 266, 283, 300}; +# else +# define bands_offset_48000_lpc_warp_7_5ms NULL +# endif + +RAM_ALIGN const Word16 *const bands_offset_7_5ms[5] = { + bands_offset_8000_lpc_warp_7_5ms, bands_offset_16000_lpc_warp_7_5ms, bands_offset_24000_lpc_warp_7_5ms, + bands_offset_32000_lpc_warp_7_5ms, bands_offset_48000_lpc_warp_7_5ms}; +# endif /* ifdef CR8_G_ADD_75MS */ + +RAM_ALIGN const Word32 inv_odft_twiddle_80_re[M] = { + 0x7ff9af04, 0x7fe6bcb0, 0x7fc72ae2, 0x7f9afcb9, 0x7f62368f, 0x7f1cde01, 0x7ecaf9e5, 0x7e6c9251, + 0x7e01b096, 0x7d8a5f40, 0x7d06aa16, 0x7c769e18, 0x7bda497d, 0x7b31bbb2, 0x7a7d055b, 0x79bc384d}; + +RAM_ALIGN const Word32 inv_odft_twiddle_80_im[M] = { + 0x02835b5a, 0x05067734, 0x07891418, 0x0a0af299, 0x0c8bd35e, 0x0f0b7727, 0x11899ed3, 0x14060b68, + 0x16807e15, 0x18f8b83c, 0x1b6e7b7a, 0x1de189a6, 0x2051a4dd, 0x22be8f87, 0x25280c5e, 0x278dde6e}; + +RAM_ALIGN const Word32 inv_odft_twiddle_60_re[16] = { + 0x7ff4c56f, 0x7fd317b4, 0x7f9afcb9, 0x7f4c7e54, 0x7ee7aa4c, 0x7e6c9251, 0x7ddb4bfc, 0x7d33f0ca, + 0x7c769e18, 0x7ba3751d, 0x7aba9ae6, 0x79bc384d, 0x78a879f4, 0x777f903c, 0x7641af3d, 0x74ef0ebc}; + +RAM_ALIGN const Word32 inv_odft_twiddle_60_im[16] = { + 0x0359c428, 0x06b2f1d2, 0x0a0af299, 0x0d61304e, 0x10b5150f, 0x14060b68, 0x17537e63, 0x1a9cd9ac, + 0x1de189a6, 0x2120fb83, 0x245a9d65, 0x278dde6e, 0x2aba2ee4, 0x2ddf0040, 0x30fbc54d, 0x340ff242}; + +RAM_ALIGN const Word32 inv_odft_twiddle_40_re[16] = { + 0x7fe6bcb0, 0x7f9afcb9, 0x7f1cde01, 0x7e6c9251, 0x7d8a5f40, 0x7c769e18, 0x7b31bbb2, 0x79bc384d, + 0x7816a759, 0x7641af3d, 0x743e0918, 0x720c8075, 0x6fadf2fc, 0x6d23501b, 0x6a6d98a4, 0x678dde6e}; + +RAM_ALIGN const Word32 inv_odft_twiddle_40_im[16] = { + 0x05067734, 0x0a0af299, 0x0f0b7727, 0x14060b68, 0x18f8b83c, 0x1de189a6, 0x22be8f87, 0x278dde6e, + 0x2c4d9050, 0x30fbc54d, 0x3596a46c, 0x3a1c5c57, 0x3e8b240e, 0x42e13ba4, 0x471cece7, 0x4b3c8c12}; + +RAM_ALIGN const Word32 inv_odft_twiddle_20_re[16] = { + 0x7f9afcb9, 0x7e6c9251, 0x7c769e18, 0x79bc384d, 0x7641af3d, 0x720c8075, 0x6d23501b, 0x678dde6e, + 0x6154fb91, 0x5a82799a, 0x53211d18, 0x4b3c8c12, 0x42e13ba4, 0x3a1c5c57, 0x30fbc54d, 0x278dde6e}; + +RAM_ALIGN const Word32 inv_odft_twiddle_20_im[16] = { + 0x0a0af299, 0x14060b68, 0x1de189a6, 0x278dde6e, 0x30fbc54d, 0x3a1c5c57, 0x42e13ba4, 0x4b3c8c12, + 0x53211d18, 0x5a82799a, 0x6154fb91, 0x678dde6e, 0x6d23501b, 0x720c8075, 0x7641af3d, 0x79bc384d}; + +#ifdef SUBSET_NB +RAM_ALIGN const Word16 resamp_filt_8k[240] = { + 214, 417, -1052, -4529, 26233, -4529, -1052, 417, 214, 0, 212, 277, -1281, -3928, 26037, -4979, + -755, 550, 206, -8, 200, 136, -1439, -3214, 25456, -5243, -401, 668, 187, -18, 180, 0, + -1522, -2427, 24506, -5289, 0, 763, 156, -28, 154, -125, -1534, -1605, 23211, -5090, 432, 831, + 114, -39, 124, -234, -1478, -785, 21609, -4626, 877, 865, 61, -50, 92, -323, -1361, 0, + 19741, -3885, 1317, 861, 0, -61, 60, -391, -1194, 720, 17658, -2863, 1729, 815, -68, -69, + 29, -436, -987, 1351, 15414, -1563, 2093, 727, -140, -76, 0, -457, -752, 1873, 13068, 0, + 2389, 598, -213, -79, -25, -457, -501, 2274, 10677, 1803, 2597, 430, -282, -77, -46, -436, + -247, 2545, 8302, 3815, 2700, 229, -345, -72, -61, -398, 0, 2686, 5997, 5997, 2686, 0, + -398, -61, -72, -345, 229, 2700, 3815, 8302, 2545, -247, -436, -46, -77, -282, 430, 2597, + 1803, 10677, 2274, -501, -457, -25, -79, -213, 598, 2389, 0, 13068, 1873, -752, -457, 0, + -76, -140, 727, 2093, -1563, 15414, 1351, -987, -436, 29, -69, -68, 815, 1729, -2863, 17658, + 720, -1194, -391, 60, -61, 0, 861, 1317, -3885, 19741, 0, -1361, -323, 92, -50, 61, + 865, 877, -4626, 21609, -785, -1478, -234, 124, -39, 114, 831, 432, -5090, 23211, -1605, -1534, + -125, 154, -28, 156, 763, 0, -5289, 24506, -2427, -1522, 0, 180, -18, 187, 668, -401, + -5243, 25456, -3214, -1439, 136, 200, -8, 206, 550, -755, -4979, 26037, -3928, -1281, 277, 212}; +#else +#define resamp_filt_8k NULL +#endif + +#ifdef SUBSET_WB +RAM_ALIGN const Word16 resamp_filt_16k[240] = { + -61, 214, -398, 417, 0, -1052, 2686, -4529, 5997, 26233, 5997, -4529, 2686, -1052, 0, 417, + -398, 214, -61, 0, -72, 212, -345, 277, 229, -1281, 2700, -3928, 3815, 26037, 8302, -4979, + 2545, -755, -247, 550, -436, 206, -46, -8, -77, 200, -282, 136, 430, -1439, 2597, -3214, + 1803, 25456, 10677, -5243, 2274, -401, -501, 668, -457, 187, -25, -18, -79, 180, -213, 0, + 598, -1522, 2389, -2427, 0, 24506, 13068, -5289, 1873, 0, -752, 763, -457, 156, 0, -28, + -76, 154, -140, -125, 727, -1534, 2093, -1605, -1563, 23211, 15414, -5090, 1351, 432, -987, 831, + -436, 114, 29, -39, -69, 124, -68, -234, 815, -1478, 1729, -785, -2863, 21609, 17658, -4626, + 720, 877, -1194, 865, -391, 61, 60, -50, -61, 92, 0, -323, 861, -1361, 1317, 0, + -3885, 19741, 19741, -3885, 0, 1317, -1361, 861, -323, 0, 92, -61, -50, 60, 61, -391, + 865, -1194, 877, 720, -4626, 17658, 21609, -2863, -785, 1729, -1478, 815, -234, -68, 124, -69, + -39, 29, 114, -436, 831, -987, 432, 1351, -5090, 15414, 23211, -1563, -1605, 2093, -1534, 727, + -125, -140, 154, -76, -28, 0, 156, -457, 763, -752, 0, 1873, -5289, 13068, 24506, 0, + -2427, 2389, -1522, 598, 0, -213, 180, -79, -18, -25, 187, -457, 668, -501, -401, 2274, + -5243, 10677, 25456, 1803, -3214, 2597, -1439, 430, 136, -282, 200, -77, -8, -46, 206, -436, + 550, -247, -755, 2545, -4979, 8302, 26037, 3815, -3928, 2700, -1281, 229, 277, -345, 212, -72}; +#else +#define resamp_filt_16k NULL +#endif + +#ifdef SUBSET_SSWB +RAM_ALIGN const Word16 resamp_filt_24k[240] = { + -50, 19, 143, -93, -290, 278, 485, -658, -701, 1396, 901, -3019, -1042, 10276, 17488, 10276, + -1042, -3019, 901, 1396, -701, -658, 485, 278, -290, -93, 143, 19, -50, 0, -46, 0, + 141, -45, -305, 185, 543, -501, -854, 1153, 1249, -2619, -1908, 8712, 17358, 11772, 0, -3319, + 480, 1593, -504, -796, 399, 367, -261, -142, 138, 40, -52, -5, -41, -17, 133, 0, + -304, 91, 574, -334, -959, 878, 1516, -2143, -2590, 7118, 16971, 13161, 1202, -3495, 0, 1731, + -267, -908, 287, 445, -215, -188, 125, 62, -52, -12, -34, -30, 120, 41, -291, 0, + 577, -164, -1015, 585, 1697, -1618, -3084, 5534, 16337, 14406, 2544, -3526, -523, 1800, 0, -985, + 152, 509, -156, -230, 104, 83, -48, -19, -26, -41, 103, 76, -265, -83, 554, 0, + -1023, 288, 1791, -1070, -3393, 3998, 15474, 15474, 3998, -3393, -1070, 1791, 288, -1023, 0, 554, + -83, -265, 76, 103, -41, -26, -19, -48, 83, 104, -230, -156, 509, 152, -985, 0, + 1800, -523, -3526, 2544, 14406, 16337, 5534, -3084, -1618, 1697, 585, -1015, -164, 577, 0, -291, + 41, 120, -30, -34, -12, -52, 62, 125, -188, -215, 445, 287, -908, -267, 1731, 0, + -3495, 1202, 13161, 16971, 7118, -2590, -2143, 1516, 878, -959, -334, 574, 91, -304, 0, 133, + -17, -41, -5, -52, 40, 138, -142, -261, 367, 399, -796, -504, 1593, 480, -3319, 0, + 11772, 17358, 8712, -1908, -2619, 1249, 1153, -854, -501, 543, 185, -305, -45, 141, 0, -46}; +#else +#define resamp_filt_24k NULL +#endif + +#ifdef SUBSET_SWB +RAM_ALIGN const Word16 resamp_filt_32k[240] = { + -30, -31, 46, 107, 0, -199, -162, 209, 430, 0, -681, -526, 658, 1343, 0, -2264, + -1943, 2999, 9871, 13116, 9871, 2999, -1943, -2264, 0, 1343, 658, -526, -681, 0, 430, 209, + -162, -199, 0, 107, 46, -31, -30, 0, -25, -36, 30, 106, 31, -173, -195, 139, + 432, 114, -597, -641, 439, 1350, 360, -1964, -2313, 1908, 8829, 13019, 10804, 4151, -1431, -2489, + -393, 1273, 864, -378, -739, -123, 408, 275, -117, -218, -34, 103, 62, -23, -35, -4, + -20, -39, 14, 100, 57, -141, -218, 68, 416, 215, -494, -719, 216, 1298, 676, -1607, + -2545, 902, 7707, 12728, 11606, 5339, -781, -2621, -803, 1137, 1047, -200, -767, -251, 364, 334, + -62, -228, -70, 94, 77, -13, -38, -9, -14, -39, 0, 90, 78, -106, -229, 0, + 382, 299, -376, -761, 0, 1194, 937, -1214, -2644, 0, 6534, 12253, 12253, 6534, 0, -2644, + -1214, 937, 1194, 0, -761, -376, 299, 382, 0, -229, -106, 78, 90, 0, -39, -14, + -9, -38, -13, 77, 94, -70, -228, -62, 334, 364, -251, -767, -200, 1047, 1137, -803, + -2621, -781, 5339, 11606, 12728, 7707, 902, -2545, -1607, 676, 1298, 216, -719, -494, 215, 416, + 68, -218, -141, 57, 100, 14, -39, -20, -4, -35, -23, 62, 103, -34, -218, -117, + 275, 408, -123, -739, -378, 864, 1273, -393, -2489, -1431, 4151, 10804, 13019, 8829, 1908, -2313, + -1964, 360, 1350, 439, -641, -597, 114, 432, 139, -195, -173, 31, 106, 30, -36, -25}; +#else +#define resamp_filt_32k NULL +#endif + +#ifdef ENABLE_HR_MODE +RAM_ALIGN const Word16 resamp_filt_96k[240] = { + -3, -7, -10, -13, -13, -10, -4, 5, 15, 26, 33, 36, 31, 19, 0, -23, -47, -66, -76, + -73, -54, -21, 23, 70, 111, 139, 143, 121, 72, 0, -84, -165, -227, -256, -240, -175, -67, 72, + 219, 349, 433, 448, 379, 225, 0, -268, -536, -755, -874, -848, -648, -260, 301, 1000, 1780, 2569, 3290, + 3869, 4243, 4372, 4243, 3869, 3290, 2569, 1780, 1000, 301, -260, -648, -848, -874, -755, -536, -268, 0, 225, + 379, 448, 433, 349, 219, 72, -67, -175, -240, -256, -227, -165, -84, 0, 72, 121, 143, 139, 111, + 70, 23, -21, -54, -73, -76, -66, -47, -23, 0, 19, 31, 36, 33, 26, 15, 5, -4, -10, + -13, -13, -10, -7, -3, 0, -1, -5, -8, -12, -13, -12, -8, 0, 10, 21, 30, 35, 34, + 26, 10, -11, -35, -58, -73, -76, -65, -39, 0, 46, 92, 127, 144, 136, 100, 38, -41, -125, + -199, -246, -254, -214, -126, 0, 146, 288, 398, 450, 424, 312, 120, -131, -405, -655, -830, -881, -771, + -477, 0, 636, 1384, 2178, 2943, 3601, 4084, 4340, 4340, 4084, 3601, 2943, 2178, 1384, 636, 0, -477, -771, + -881, -830, -655, -405, -131, 120, 312, 424, 450, 398, 288, 146, 0, -126, -214, -254, -246, -199, -125, + -41, 38, 100, 136, 144, 127, 92, 46, 0, -39, -65, -76, -73, -58, -35, -11, 10, 26, 34, + 35, 30, 21, 10, 0, -8, -12, -13, -12, -8, -5, -1}; +#else +# define resamp_filt_96k NULL +#endif + +#ifdef SUBSET_FB +RAM_ALIGN const Word16 resamp_filt_48k[240] = { + -13, -25, -20, 10, 51, 71, 38, -47, -133, -145, -42, 139, 277, 242, 0, -329, + -511, -351, 144, 698, 895, 450, -535, -1510, -1697, -521, 1999, 5138, 7737, 8744, 7737, 5138, + 1999, -521, -1697, -1510, -535, 450, 895, 698, 144, -351, -511, -329, 0, 242, 277, 139, + -42, -145, -133, -47, 38, 71, 51, 10, -20, -25, -13, 0, -9, -23, -24, 0, + 41, 71, 52, -23, -115, -152, -78, 92, 254, 272, 76, -251, -493, -427, 0, 576, + 900, 624, -262, -1309, -1763, -954, 1272, 4356, 7203, 8679, 8169, 5886, 2767, 0, -1542, -1660, + -809, 240, 848, 796, 292, -252, -507, -398, -82, 199, 288, 183, 0, -130, -145, -71, + 20, 69, 60, 20, -15, -26, -17, -3, -6, -20, -26, -8, 31, 67, 62, 0, + -94, -152, -108, 45, 223, 287, 143, -167, -454, -480, -134, 439, 866, 758, 0, -1071, + -1748, -1295, 601, 3559, 6580, 8485, 8485, 6580, 3559, 601, -1295, -1748, -1071, 0, 758, 866, + 439, -134, -480, -454, -167, 143, 287, 223, 45, -108, -152, -94, 0, 62, 67, 31, + -8, -26, -20, -6, -3, -17, -26, -15, 20, 60, 69, 20, -71, -145, -130, 0, + 183, 288, 199, -82, -398, -507, -252, 292, 796, 848, 240, -809, -1660, -1542, 0, 2767, + 5886, 8169, 8679, 7203, 4356, 1272, -954, -1763, -1309, -262, 624, 900, 576, 0, -427, -493, + -251, 76, 272, 254, 92, -78, -152, -115, -23, 52, 71, 41, 0, -24, -23, -9}; +#else +#define resamp_filt_48k NULL +#endif + + +RAM_ALIGN const Word16 *const resamp_filts[NUM_SAMP_FREQ] = {resamp_filt_8k, + resamp_filt_16k, + resamp_filt_24k, + resamp_filt_32k, + resamp_filt_48k, + resamp_filt_96k +}; + +RAM_ALIGN const Word16 resamp_params[NUM_SAMP_FREQ][4] = { +#ifdef SUBSET_NB + {24, 5, 0, 15}, +#else + {0}, +#endif +#ifdef SUBSET_WB + {12, 10, 1, 3}, +#else + {0}, +#endif +#ifdef SUBSET_SSWB + {8, 15, 1, 7}, +#else + {0}, +#endif +#ifdef SUBSET_SWB + {6, 20, 2, 3}, +#else + {0}, +#endif +#ifdef SUBSET_FB + {4, 30, 3, 3}, +#else + {0}, +#endif +#ifdef ENABLE_HR_MODE + {2, 60, 7, 1}, +#endif +}; + +RAM_ALIGN const Word16 highpass50_filt_num[3] = {32204, -32204, 32204}; +RAM_ALIGN const Word16 highpass50_filt_den[2] = {32199, -31650}; + +RAM_ALIGN const Word16 olpa_ac_weighting[98] = { + 32767, 32598, 32429, 32260, 32091, 31922, 31754, 31585, 31416, 31247, 31078, 30909, 30740, 30571, + 30402, 30233, 30065, 29896, 29727, 29558, 29389, 29220, 29051, 28882, 28713, 28544, 28376, 28207, + 28038, 27869, 27700, 27531, 27362, 27193, 27024, 26855, 26687, 26518, 26349, 26180, 26011, 25842, + 25673, 25504, 25335, 25166, 24998, 24829, 24660, 24491, 24322, 24153, 23984, 23815, 23646, 23477, + 23308, 23140, 22971, 22802, 22633, 22464, 22295, 22126, 21957, 21788, 21619, 21451, 21282, 21113, + 20944, 20775, 20606, 20437, 20268, 20099, 19930, 19762, 19593, 19424, 19255, 19086, 18917, 18748, + 18579, 18410, 18241, 18073, 17904, 17735, 17566, 17397, 17228, 17059, 16890, 16721, 16552, 16384}; + +RAM_ALIGN const Word16 ltpf_ac_interp_filt[7][9] = { + {90, 151, -2472, 26787, 10819, -3468, 940, -94, 0}, {-98, 967, -4270, 19769, 19769, -4270, 967, -98, 0}, + {-94, 940, -3468, 10819, 26787, -2472, 151, 90, 0}, {0, 503, -1550, 2739, 29447, 2739, -1550, 503, 0}, + {0, 90, 151, -2472, 26787, 10819, -3468, 940, -94}, {0, -98, 967, -4270, 19769, 19769, -4270, 967, -98}, + {0, -94, 940, -3468, 10819, 26787, -2472, 151, 90}}; + +RAM_ALIGN const Word16 inter_filter[5][4][12] = { + {{6877, 19121, 6877, 0}, {3506, 18025, 11000, 220}, {1300, 15048, 15048, 1300}, {220, 11000, 18025, 3506}}, + {{6877, 19121, 6877, 0}, {3506, 18025, 11000, 220}, {1300, 15048, 15048, 1300}, {220, 11000, 18025, 3506}}, + {{2072, 8216, 12170, 8216, 2072, 0}, + {1134, 6509, 11883, 9787, 3320, 140}, + {503, 4831, 11057, 11057, 4831, 503}, + {140, 3320, 9787, 11883, 6509, 1134}}, + {{950, 3702, 7248, 8926, 7248, 3702, 950, 0}, + {558, 2858, 6427, 8812, 7946, 4606, 1466, 102}, + {281, 2106, 5530, 8479, 8479, 5530, 2106, 281}, + {102, 1466, 4606, 7946, 8812, 6427, 2858, 558}}, + {{355, 1183, 2515, 4068, 5333, 5822, 5333, 4068, 2515, 1183, 355, 0}, + {231, 924, 2145, 3685, 5074, 5791, 5543, 4433, 2900, 1474, 510, 67}, + {136, 700, 1797, 3293, 4771, 5697, 5697, 4771, 3293, 1797, 700, 136}, + {67, 510, 1474, 2900, 4433, 5543, 5791, 5074, 3685, 2145, 924, 231}}}; +RAM_ALIGN const Word16 inter_filter_shift[5] = {1, 1, 2, 3, 5}; +RAM_ALIGN const Word16 inter_filter_len[5] = {4, 4, 6, 8, 12}; + +RAM_ALIGN const Word16 tilt_filter[5][4][11] = { + {{16777, 11692, -525}, {16697, 11692, -444}, {16622, 11692, -369}, {16551, 11692, -298}}, + {{16777, 11692, -525}, {16697, 11692, -444}, {16622, 11692, -369}, {16551, 11692, -298}}, + {{11112, 14323, 2797, -356, -44}, + {10998, 14271, 2906, -304, -38}, + {10890, 14222, 3008, -255, -32}, + {10788, 14175, 3104, -208, -26}}, + {{8307, 12959, 5866, 1049, -283, -71, -9}, + {8199, 12866, 5931, 1133, -242, -61, -8}, + {8098, 12777, 5992, 1212, -203, -51, -6}, + {8002, 12693, 6050, 1287, -166, -42, -5}}, + {{5519, 9817, 7001, 3967, 1589, 259, -201, -88, -31, -8, -1}, + {5433, 9706, 6991, 4014, 1651, 309, -172, -76, -27, -7, -1}, + {5353, 9601, 6981, 4058, 1710, 356, -145, -64, -23, -6, -1}, + {5277, 9501, 6970, 4100, 1767, 402, -118, -52, -19, -5, -1}}}; +RAM_ALIGN const Word16 tilt_filter_len[5] = {2, 2, 4, 6, 10}; + +RAM_ALIGN const Word16 gain_scale_fac[4] = {13108, 11468, 9832, 8192}; + +RAM_ALIGN const UWord16 pitch_scale[NUM_SAMP_FREQ] = {5120, + 10240, + 15360, + 20480, + 30720 +}; + +RAM_ALIGN const Word16 ltpf_overlap_len[NUM_SAMP_FREQ] = {20, 40, 60, 80, 120 +}; + +/* set up of SNS VQ stages 1 ( split VQ) and SNS stage 2(Transformed PVQ) for bit rate 38 bits */ + +/* trained gain set for DCT Q12 */ +RAM_ALIGN const Word16 sns_vq_reg_adj_gains[2] = {8915, 12054}; +RAM_ALIGN const Word16 sns_vq_reg_lf_adj_gains[4] = {6245, 15043, 17861, 21014}; +RAM_ALIGN const Word16 sns_vq_near_adj_gains[4] = {7099, 9132, 11253, 14808}; +RAM_ALIGN const Word16 sns_vq_far_adj_gains[8] = {4336, 5067, 5895, 8149, 10235, 12825, 16868, 19882}; + +RAM_ALIGN const Word16 *const sns_gaintabPtr[4] = {sns_vq_reg_adj_gains, sns_vq_reg_lf_adj_gains, sns_vq_near_adj_gains, + sns_vq_far_adj_gains}; +RAM_ALIGN const Word16 sns_gainSz[4] = {2, 4, 4, 8}; +RAM_ALIGN const Word16 sns_gainMSBbits[4] = {1, 1, 2, 2}; +RAM_ALIGN const Word16 sns_gainLSBbits[4] = {0, 1, 0, 1}; +RAM_ALIGN const Word16 sns_Kval[4][2] = {{10, 1}, {10, 0}, {8, 0}, {6, 0}}; +RAM_ALIGN const UWord32 sns_MPVQ_Sz[4][2] = { + {4780008U >> 1, (2U * 6U)}, {4780008U >> 1, (2U)}, {30316544U >> 1, 0U}, {MPVQ_SZ_OUTL_FAR, 0U}}; + +#ifdef ENABLE_HR_MODE +RAM_ALIGN const Word32 st1SCF0_7_base5_32x8_Q27[256] = { + 303712392, 109160791, -71161366, -182086260, -214684177, -193406093, -153520450, -101361734, 395293327, + 323657083, 128910102, -59488852, -164971858, -208829415, -200908713, -149907762, -293414324, -264613117, + -239872071, -257518046, -240785425, -182185002, -94683128, -6417929, 93105259, 128259784, 77206169, + -15381811, -86711449, -127822437, -144156883, -101748810, -174150364, -99370653, -46355110, -42048494, + -54086690, -49931794, -10514807, 13025043, 122762518, 233932163, 256230537, 207243559, 146760322, + 86903234, 4855873, -39875122, -337462040, -388124479, -269040331, -100785739, 59217144, 161317613, + 178164447, 163811504, -123774032, 84892061, 145943568, 81688751, 17605952, -39748467, -27784884, + 18109316, 106075262, 84342590, 52763395, 64425544, 60104730, 28150050, 881397, -11559399, + 194314494, 365609026, 310154713, 125500457, -36875504, -121074819, -126256135, -85053377, 106482242, + 1931812, -76213503, -87880462, -64351897, -23339746, 9128989, 39611134, 365643112, 397214108, + 248240465, 75602822, 18779354, 48270210, 92537937, 85871184, -71246823, -28546860, 773918, + 57025285, 63502293, 115278828, 159868294, 133706314, 226463440, 326973859, 312753384, 238885783, + 193825560, 204004473, 197567682, 131222320, -396188282, -213934330, -14753048, 52158227, 68844655, + 84303846, 110410429, 117560157, 13673880, 79169310, 83087169, 170095890, 324754621, 302223766, + 70670604, -53229612, 360045196, 178157942, 17473172, -45437142, -49421549, -25728189, -20774539, + -31434755, 647866186, 418689256, 187252080, 33594069, -52829955, -86363494, -86244384, -97065351, + 11789953, -76448652, -153687373, -224101311, -247677903, -210007831, -149983961, -71669806, 186699958, + 265947702, 149338424, -29542330, -104014124, -79733903, 18379464, 109822702, 51618245, -21553862, + -72392588, -71042662, 25559558, 343681831, 378354941, 88136873, 259345425, 404035869, 411436250, + 335692175, 259160465, 76793185, -108950139, -157896166, 23498902, -100733469, -139511132, -152441152, + -139852059, -2040916, 277895647, 460298246, -159473505, 49230106, 175768625, 225929624, 167907618, + 126483532, 110897463, 59049457, 340003306, 283568025, 169501437, 102208613, 70077483, 15928969, + -60712963, -93999711, 536723054, 547476463, 378877401, 231669479, 86858248, -44446002, -118654185, + -151259810, 68169532, 213189358, 232061142, 135146824, 50616355, 63937402, 145968142, 145970189, + 425278032, 437353108, 325116396, 240848448, 204249734, 157298757, 65685431, -8359023, 254228196, + 167918047, 79249020, 81652507, 117866118, 150206430, 136711039, 83275912, 127356599, 286205131, + 365535742, 371764419, 341298198, 271181905, 111406869, -3698627, -252365241, -169692913, 41798753, + 246517983, 302841086, 274903406, 294643934, 272005129, 33067993, 128261383, 204073729, 265277850, + 260441270, 299809987, 266873132, 170768802 }; +RAM_ALIGN const Word32 st1SCF8_15_base5_32x8_Q27[256] = { + 31142327, -135412629, -287525918, -318812488, -299361815, -292052248, -307447065, -339955249, -173817241, + -241497912, -253273077, -242922894, -236679593, -246180047, -242237472, -233108740, 18694612, -34653021, + -87349511, -143365648, -217337078, -293618146, -354009441, -399831591, -42481669, -64122205, -73975722, + -65067182, -31995949, -19196424, 9169576, 11852254, 118046962, 40042530, -122861082, -296146014, + -367947407, -384049364, -387676629, -396187390, -39822658, -130862945, -182344850, -132032812, -87638397, + -132873805, -216717640, -323078583, 45765709, 36091119, 7560964, 6698995, -12806126, -102027773, + -312402661, -506209524, -189555374, -199343014, -159187030, -83886299, 20656444, 77361286, 106715523, + 80069550, -30714319, -44791015, -108625274, -219563932, -252982160, -220783722, -188597085, -196852406, + -143812455, -190276467, -207892204, -195013074, -138489838, -92696486, -57558441, -66432436, -79321135, + -9552782, 46401689, 40339066, -150142954, -327610913, -299110559, -254354980, -113874897, -78279377, + 12085282, 113417337, 143039033, 98996714, 34438988, -66030204, 153101016, 129388157, 51198856, + -64806941, -243783312, -376184794, -434040973, -464270818, -50503881, 5713319, 69329858, 33784868, + -29015184, -71682211, -86004854, -116735202, 89255342, 147358670, 185680385, 180291129, 110458350, + 28974493, -54348215, -143647337, -110899539, -90084420, -30668159, 69656431, 183505023, 292625568, + 340370914, 295441538, 189258173, 101259479, -175222029, -251166616, -166441640, -170071209, -273362338, + -388808843, 48504518, -2952679, -77761569, -118034823, -114177011, -104608901, -98271929, -119232119, + 58716127, 40995519, -991583, -66524997, -108266901, -164325304, -228381893, -301307946, 86986552, + 91576640, 33990299, 9876306, 42173453, 31504911, 19407902, -9155262, 150216257, 165712633, + 79077091, -184136602, -318224471, -269482063, -223725572, -258546087, 19038449, -14852543, -37960074, + -885587, 38376778, 6179995, -80879122, -304095400, 67652037, 110995667, 150298671, 158261551, + 144938274, 93621729, -122480229, -480076341, -67253289, -43711762, 3768810, 35172367, 48397679, + 85311972, 128716474, 175483179, 503277534, 204470792, -61433556, -107201177, -51918012, -50452587, + -88293374, -172018761, -154697999, -148714432, -75512923, -29603347, -46955117, -101124035, -132687189, + -172859645, 138012394, 147331497, 103165859, 27659855, -46010607, -101326252, -139849742, -201777098, + 17291535, 92534989, 150789463, 175737342, 181881080, 191007103, 155298567, 54535272, 179896088, + 186558381, 140214471, 85338684, -36874140, -207934631, -327812990, -405951728, 287015358, 570037814, + 388874539, 125188990, -39301937, -108770623, -105880084, -125540975, 75810265, 213654461, 321816127, + 407615675, 357588710, 186971315, 54201685, -88083199, -56701695, 43775062, 186792575, 299502316, + 350549113, 357744389, 322261535, 236116337 }; +#endif + +RAM_ALIGN const Word16 st1SCF0_7_base5_32x8_Q11[256] = { + 4634, 1666, -1086, -2778, -3276, -2951, -2343, -1547, 6032, 4939, 1967, -908, -2517, -3186, -3066, -2287, + -4477, -4038, -3660, -3929, -3674, -2780, -1445, -98, 1421, 1957, 1178, -235, -1323, -1950, -2200, -1553, + -2657, -1516, -707, -642, -825, -762, -160, 199, 1873, 3570, 3910, 3162, 2239, 1326, 74, -608, + -5149, -5922, -4105, -1538, 904, 2462, 2719, 2500, -1889, 1295, 2227, 1246, 269, -607, -424, 276, + 1619, 1287, 805, 983, 917, 430, 13, -176, 2965, 5579, 4733, 1915, -563, -1847, -1927, -1298, + 1625, 29, -1163, -1341, -982, -356, 139, 604, 5579, 6061, 3788, 1154, 287, 737, 1412, 1310, + -1087, -436, 12, 870, 969, 1759, 2439, 2040, 3456, 4989, 4772, 3645, 2958, 3113, 3015, 2002, + -6045, -3264, -225, 796, 1050, 1286, 1685, 1794, 209, 1208, 1268, 2595, 4955, 4612, 1078, -812, + 5494, 2718, 267, -693, -754, -393, -317, -480, 9886, 6389, 2857, 513, -806, -1318, -1316, -1481, + 180, -1167, -2345, -3420, -3779, -3204, -2289, -1094, 2849, 4058, 2279, -451, -1587, -1217, 280, 1676, + 788, -329, -1105, -1084, 390, 5244, 5773, 1345, 3957, 6165, 6278, 5122, 3954, 1172, -1662, -2409, + 359, -1537, -2129, -2326, -2134, -31, 4240, 7024, -2433, 751, 2682, 3447, 2562, 1930, 1692, 901, + 5188, 4327, 2586, 1560, 1069, 243, -926, -1434, 8190, 8354, 5781, 3535, 1325, -678, -1811, -2308, + 1040, 3253, 3541, 2062, 772, 976, 2227, 2227, 6489, 6673, 4961, 3675, 3117, 2400, 1002, -128, + 3879, 2562, 1209, 1246, 1798, 2292, 2086, 1271, 1943, 4367, 5578, 5673, 5208, 4138, 1700, -56, + -3851, -2589, 638, 3762, 4621, 4195, 4496, 4150, 505, 1957, 3114, 4048, 3974, 4575, 4072, 2606}; + +RAM_ALIGN const Word16 st1SCF8_15_base5_32x8_Q11[256] = { + 475, -2066, -4387, -4865, -4568, -4456, -4691, -5187, -2652, -3685, -3865, -3707, -3611, -3756, -3696, -3557, + 285, -529, -1333, -2188, -3316, -4480, -5402, -6101, -648, -978, -1129, -993, -488, -293, 140, 181, + 1801, 611, -1875, -4519, -5614, -5860, -5915, -6045, -608, -1997, -2782, -2015, -1337, -2027, -3307, -4930, + 698, 551, 115, 102, -195, -1557, -4767, -7724, -2892, -3042, -2429, -1280, 315, 1180, 1628, 1222, + -469, -683, -1657, -3350, -3860, -3369, -2878, -3004, -2194, -2903, -3172, -2976, -2113, -1414, -878, -1014, + -1210, -146, 708, 616, -2291, -4999, -4564, -3881, -1738, -1194, 184, 1731, 2183, 1511, 525, -1008, + 2336, 1974, 781, -989, -3720, -5740, -6623, -7084, -771, 87, 1058, 516, -443, -1094, -1312, -1781, + 1362, 2249, 2833, 2751, 1685, 442, -829, -2192, -1692, -1375, -468, 1063, 2800, 4465, 5194, 4508, + 2888, 1545, -2674, -3832, -2540, -2595, -4171, -5933, 740, -45, -1187, -1801, -1742, -1596, -1500, -1819, + 896, 626, -15, -1015, -1652, -2507, -3485, -4598, 1327, 1397, 519, 151, 644, 481, 296, -140, + 2292, 2529, 1207, -2810, -4856, -4112, -3414, -3945, 291, -227, -579, -14, 586, 94, -1234, -4640, + 1032, 1694, 2293, 2415, 2212, 1429, -1869, -7325, -1026, -667, 58, 537, 738, 1302, 1964, 2678, + 7679, 3120, -937, -1636, -792, -770, -1347, -2625, -2361, -2269, -1152, -452, -716, -1543, -2025, -2638, + 2106, 2248, 1574, 422, -702, -1546, -2134, -3079, 264, 1412, 2301, 2682, 2775, 2915, 2370, 832, + 2745, 2847, 2140, 1302, -563, -3173, -5002, -6194, 4380, 8698, 5934, 1910, -600, -1660, -1616, -1916, + 1157, 3260, 4911, 6220, 5456, 2853, 827, -1344, -865, 668, 2850, 4570, 5349, 5459, 4917, 3603}; + +/* tables for MPVQ pulse enumeration */ + +/* N=16, K=12 31.74 bits */ +RAM_ALIGN const UWord32 h_memN16K12[12 + 2] = { + 0U, 1U, 31U, 481U, 4991U, 39041U, 246047U, + 1303777U, 5984767U, 24331777U, 89129247U, 298199265U, 921406335U, /*U*/ 1326824512U}; + +/*N=16,K=8,h_memN16K8={0U,1U,31U,481U,4991U,39041U,246047U,1303777U,5984767U, 12165888U,}; */ + +/*N=10, K=20 +UWord32 h_memN10K20[20+2] = +{ + 0U,1U,19U,181U,1159U,5641U,22363U,75517U,224143U,598417U,1462563U, + 3317445U,7059735U,14218905U,27298155U,50250765U,89129247U,152951073U,254831667U,413442773U,654862247U, + 507444884U +}; +*/ +/*N=10, K=22 31.84 bits */ +RAM_ALIGN const UWord32 h_memN10K22[22 + 2] = {0U, + 1U, + 19U, + 181U, + 1159U, + 5641U, + 22363U, + 75517U, + 224143U, + 598417U, + 1462563U, + 3317445U, + 7059735U, + 14218905U, + 27298155U, + 50250765U, + 89129247U, + 152951073U, + 254831667U, + 413442773U, + 654862247U, + 1014889769U, + 1541911931U, + /*U*/ 1150204814U}; +/* N=10,K=10,h_memN10K10={0U,1U,19U,181U,1159U,5641U,22363U,75517U,224143U,598417U,1462563U,1658722U,}; */ + +/* N=6,K=2,*/ +RAM_ALIGN const UWord32 h_memN6K2[2 + 2] = {0U, 1U, 11U, /*U*/ 30U}; +/*N=6,K=1, h_memN6K1={0U,1U, 5U,}; */ + +RAM_ALIGN const UWord32 *const MPVQ_offs_ptr[M + 1] = {NULL /*0*/, NULL, NULL, NULL, NULL, NULL, + h_memN6K2, NULL, NULL, NULL, h_memN10K22, NULL, + NULL, NULL, NULL, NULL, h_memN16K12}; + +/*maxK coefficents for MPVQ de-indexing lookup */ +RAM_ALIGN const Word16 tabledKMAX[M + 1] = { + 0, 0, 0, 0, 0, 0, 2 /*N=6*/, 0, 0, 0, 22 /*N=10*/, 0, 0, 0, 0, 0, 12 /*N=16*/ +}; + +RAM_ALIGN const Word16 isqrt_Q16tab[1 + 64] = {/*table generated using ISqrt16 function + shift to Q16 */ + 32767, 32767, 32767, 32767, 32766, 29308, 26754, 24770, 23169, 21844, + 20723, 19759, 18918, 18176, 17515, 16921, 16383, 15894, 15446, 15034, + 14654, 14300, 13972, 13665, 13377, 13107, 12852, 12612, 12385, 12169, + 11965, 11770, 11584, 11407, 11238, 11077, 10922, 10773, 10631, 10493, + 10361, 10234, 10112, 9993, 9879, 9769, 9662, 9559, 9459, 9362, + 9268, 9176, 9088, 9001, 8918, 8836, 8757, 8680, 8605, 8532, + 8460, 8390, 8323, 8256, 8191}; + +#ifdef ENABLE_HR_MODE +RAM_ALIGN const Word32 isqrt_Q31tab[1 + 64] = {/* 2^31 / sqrt(idx) */ + 2147483647, 2147483647, 1518500249, 1239850262, 1073741824, 960383883, + 876706528, 811672525, 759250124, 715827882, 679093956, 647490682, + 619925131, 595604800, 573939146, 554477893, 536870912, 520841288, + 506166749, 492666537, 480191941, 468619350, 457845052, 447781294, + 438353264, 429496729, 421156193, 413283420, 405836262, 398777702, + 392075078, 385699449, 379625062, 373828919, 368290407, 362990988, + 357913941, 353044136, 348367849, 343872591, 339546978, 335380599, + 331363920, 327488186, 323745341, 320127961, 316629189, 313242684, + 309962565, 306783378, 303700049, 300707858, 297802400, 294979564, + 292235509, 289566636, 286969573, 284441157, 281978417, 279578557, + 277238946, 274957105, 272730696, 270557508, 268435456 }; +#endif + +# ifdef ENABLE_HR_MODE +RAM_ALIGN const Word16 adjust_global_gain_tables[5][NUM_SAMP_FREQ] = {{80, 230, 380, 530, 680, 830}, + {500, 1025, 1550, 2075, 2600, 3125}, + {850, 1700, 2550, 3400, 4250, 5100}, + {189, 164, 155, 151, 148, 146}, + {1310, 3241, 5268, 7326, 9400, 11482}}; +# else +RAM_ALIGN const Word16 adjust_global_gain_tables[5][NUM_SAMP_FREQ] = {{80, 230, 380, 530, 680}, + {500, 1025, 1550, 2075, 2600}, + {850, 1700, 2550, 3400, 4250}, + {189, 164, 155, 151, 148}, + {1310, 3241, 5268, 7326, 9400}}; +# endif + +#if defined(CR8_A_PLC_FADEOUT_TUNING) +const Word16 plc_fadeout_param_maxlen[4] = {800, 400, 266, 200}; +const Word16 plc_fadeout_param_maxbytes[4] = {27, 14, 9, 7}; +#endif diff --git a/lib_lc3plus/constants.h b/lib_lc3plus/constants.h new file mode 100644 index 0000000000000000000000000000000000000000..8dee7e6ebae1bfde803fc1787049f0ccced10e3e --- /dev/null +++ b/lib_lc3plus/constants.h @@ -0,0 +1,402 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.5 * +* Low Complexity Communication Codec Plus (LC3plus) * +* * +* Copyright licence is solely granted through ETSI Intellectual Property * +* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * +* estoppel or otherwise. * +******************************************************************************/ + +#ifndef CONSTANTS_H +#define CONSTANTS_H + +#include "defines.h" + +#include "basop_util_lc3plus.h" + + +#ifdef ENABLE_HR_MODE +extern RAM_ALIGN const Word16 BW_cutoff_bin_all_HR[]; + +extern RAM_ALIGN const Word32 *const LowDelayShapes_n960_HRA_2_5ms[2]; +extern RAM_ALIGN const Word32 *const LowDelayShapes_n960_HRA_5ms[2]; +extern RAM_ALIGN const Word32 *const LowDelayShapes_n960_HRA_7_5ms[2]; +extern RAM_ALIGN const Word32 *const LowDelayShapes_n960_HRA[2]; +#endif + +# ifdef ENABLE_HR_MODE +extern RAM_ALIGN const Word16 LowDelayShapes_n960_len[6]; +# else +extern RAM_ALIGN const Word16 LowDelayShapes_n960_len[5]; +# endif +extern RAM_ALIGN const Word16 LowDelayShapes_n960_la_zeroes[NUM_SAMP_FREQ]; +# ifdef ENABLE_HR_MODE +extern RAM_ALIGN const Word32 *const LowDelayShapes_n960[6]; +# else +extern RAM_ALIGN const Word16 *const LowDelayShapes_n960[6]; +# endif + +# ifdef ENABLE_HR_MODE +extern RAM_ALIGN const Word16 LowDelayShapes_n960_len_5ms[6]; +# else +extern RAM_ALIGN const Word16 LowDelayShapes_n960_len_5ms[5]; +# endif +extern RAM_ALIGN const Word16 LowDelayShapes_n960_la_zeroes_5ms[NUM_SAMP_FREQ]; +# ifdef ENABLE_HR_MODE +extern RAM_ALIGN const Word32 *const LowDelayShapes_n960_5ms[6]; +# else +extern RAM_ALIGN const Word16 *const LowDelayShapes_n960_5ms[6]; +# endif +#ifdef ENABLE_HR_MODE +extern RAM_ALIGN const Word16 LowDelayShapes_n960_len_2_5ms[6]; +#else +extern RAM_ALIGN const Word16 LowDelayShapes_n960_len_2_5ms[5]; +#endif +extern RAM_ALIGN const Word16 LowDelayShapes_n960_la_zeroes_2_5ms[NUM_SAMP_FREQ]; +# ifdef ENABLE_HR_MODE +extern RAM_ALIGN const Word32 *const LowDelayShapes_n960_2_5ms[6]; +# else +extern RAM_ALIGN const Word16 *const LowDelayShapes_n960_2_5ms[6]; +# endif + +# ifdef CR8_G_ADD_75MS +# ifdef ENABLE_HR_MODE +extern RAM_ALIGN const Word32 *const LowDelayShapes_n960_7_5ms[5]; +# else +extern RAM_ALIGN const Word16 *const LowDelayShapes_n960_7_5ms[5]; +# endif + +# ifdef ENABLE_HR_MODE +extern RAM_ALIGN const Word16 LowDelayShapes_n960_len_7_5ms[6]; +# else +extern RAM_ALIGN const Word16 LowDelayShapes_n960_len_7_5ms[5]; +# endif +extern RAM_ALIGN const Word16 LowDelayShapes_n960_la_zeroes_7_5ms[NUM_SAMP_FREQ]; +# endif + +extern RAM_ALIGN const Word16 NN_thresh; +extern RAM_ALIGN const Word16 NN_thresh_exp; +#ifdef CR8_E_TONE_DETECTOR +# ifdef ENABLE_HR_MODE +extern RAM_ALIGN const Word32 TD_HR_thresh_10ms; +# ifdef ENABLE_075_DMS_MODE +extern RAM_ALIGN const Word32 TD_HR_thresh_7_5ms; +# endif +extern RAM_ALIGN const Word32 TD_HR_thresh_5ms; +extern RAM_ALIGN const Word32 TD_HR_thresh_2_5ms; +# endif /* ENABLE_HR_MODE */ +#endif /* CR8_E_TONE_DETECTOR */ +extern RAM_ALIGN const Word32 BW_thresh_quiet[4]; +extern RAM_ALIGN const Word16 BW_thresh_quiet_exp; +extern RAM_ALIGN const Word16 BW_thresh_brickwall[4]; + +extern RAM_ALIGN const Word16 BW_cutoff_bin_all[]; +extern RAM_ALIGN const Word16 BW_cutoff_bits_all[]; + +#ifdef ENABLE_HR_MODE +extern RAM_ALIGN const Word16 bands_number_2_5ms_HR[]; +#endif + +extern RAM_ALIGN const Word16 BW_brickwall_dist[4]; +extern RAM_ALIGN const Word16 *const BW_warp_idx_start_all[MAX_BW_BANDS_NUMBER - 1]; +extern RAM_ALIGN const Word16 *const BW_warp_idx_stop_all[MAX_BW_BANDS_NUMBER - 1]; + +extern RAM_ALIGN const Word16 BW_brickwall_dist_5ms[4]; +extern RAM_ALIGN const Word16 *const BW_warp_idx_start_all_5ms[MAX_BW_BANDS_NUMBER - 1]; +extern RAM_ALIGN const Word16 *const BW_warp_idx_stop_all_5ms[MAX_BW_BANDS_NUMBER - 1]; +extern RAM_ALIGN const Word16 BW_brickwall_dist_2_5ms[4]; +extern RAM_ALIGN const Word16 *const BW_warp_idx_start_all_2_5ms[MAX_BW_BANDS_NUMBER - 1]; +extern RAM_ALIGN const Word16 *const BW_warp_idx_stop_all_2_5ms[MAX_BW_BANDS_NUMBER - 1]; + +#ifdef CR8_G_ADD_75MS +# ifdef ENABLE_075_DMS_MODE +extern RAM_ALIGN const Word16 BW_brickwall_dist_7_5ms[4]; +extern RAM_ALIGN const Word16 *const BW_warp_idx_start_all_7_5ms[]; +extern RAM_ALIGN const Word16 *const BW_warp_idx_stop_all_7_5ms[]; +# endif +#endif + +extern RAM_ALIGN const Word16 *const tns_subdiv_startfreq[MAX_BW_BANDS_NUMBER]; +extern RAM_ALIGN const Word16 *const tns_subdiv_stopfreq[MAX_BW_BANDS_NUMBER]; + +# ifdef ENABLE_HR_MODE +extern RAM_ALIGN const Word16 *const tns_subdiv_startfreq_HR[2]; +extern RAM_ALIGN const Word16 *const tns_subdiv_stopfreq_HR[2]; + +extern RAM_ALIGN const Word16 *const tns_subdiv_startfreq_5ms_HR[2]; +extern RAM_ALIGN const Word16 *const tns_subdiv_stopfreq_5ms_HR[2]; + +extern RAM_ALIGN const Word16 *const tns_subdiv_startfreq_2_5ms_HR[2]; +extern RAM_ALIGN const Word16 *const tns_subdiv_stopfreq_2_5ms_HR[2]; +# endif + +extern RAM_ALIGN const Word16 *const tns_subdiv_startfreq_5ms[MAX_BW_BANDS_NUMBER]; +extern RAM_ALIGN const Word16 *const tns_subdiv_stopfreq_5ms[MAX_BW_BANDS_NUMBER]; + + +extern RAM_ALIGN const Word16 *const tns_subdiv_startfreq_2_5ms[MAX_BW_BANDS_NUMBER]; +extern RAM_ALIGN const Word16 *const tns_subdiv_stopfreq_2_5ms[MAX_BW_BANDS_NUMBER]; + +#ifdef CR8_G_ADD_75MS +# ifdef ENABLE_075_DMS_MODE +extern RAM_ALIGN const Word16 *const tns_subdiv_startfreq_7_5ms[]; +extern RAM_ALIGN const Word16 *const tns_subdiv_stopfreq_7_5ms[]; +# endif +#endif + +extern RAM_ALIGN const Word16 Tab_esc_nb[4]; + +extern RAM_ALIGN const Word8 ari_spec_lookup[4096]; +extern RAM_ALIGN const UWord16 ari_spec_cumfreq[64][17]; +extern RAM_ALIGN const UWord16 ari_spec_freq[64][17]; +extern RAM_ALIGN const UWord16 ari_spec_bits[64][17]; + +extern RAM_ALIGN const Word32 tnsAcfWindow_lc3plus[MAXLAG]; +extern RAM_ALIGN const Word16 ac_tns_order_bits[2][MAXLAG]; +extern RAM_ALIGN const Word16 ac_tns_order_freq[2][MAXLAG]; +extern RAM_ALIGN const Word16 ac_tns_order_cumfreq[2][MAXLAG]; +extern RAM_ALIGN const Word16 ac_tns_coef_bits[MAXLAG][TNS_COEF_RES]; +extern RAM_ALIGN const Word16 ac_tns_coef_freq[MAXLAG][TNS_COEF_RES]; +extern RAM_ALIGN const Word16 ac_tns_coef_cumfreq[MAXLAG][TNS_COEF_RES]; +extern RAM_ALIGN const Word16 tnsQuantPts[TNS_COEF_RES]; +extern RAM_ALIGN const Word16 tnsQuantThr[TNS_COEF_RES - 1]; + +extern RAM_ALIGN const Word16 *const lpc_pre_emphasis[NUM_SAMP_FREQ]; +extern RAM_ALIGN const Word16 *const lpc_pre_emphasis_e[NUM_SAMP_FREQ]; + +extern RAM_ALIGN const Word16 *const lpc_lin_pre_emphasis[NUM_SAMP_FREQ]; +extern RAM_ALIGN const Word16 *const lpc_lin_pre_emphasis_e[NUM_SAMP_FREQ]; +extern RAM_ALIGN const Word16 *const lpc_lin_pre_emphasis_5ms[NUM_SAMP_FREQ]; +extern RAM_ALIGN const Word16 *const lpc_lin_pre_emphasis_e_5ms[NUM_SAMP_FREQ]; +extern RAM_ALIGN const Word16 *const lpc_lin_pre_emphasis_2_5ms[NUM_SAMP_FREQ]; +extern RAM_ALIGN const Word16 *const lpc_lin_pre_emphasis_e_2_5ms[NUM_SAMP_FREQ]; + +extern RAM_ALIGN const Word16 *const lpc_warp_dee_emphasis[NUM_SAMP_FREQ]; +extern RAM_ALIGN const Word16 *const lpc_warp_dee_emphasis_e[NUM_SAMP_FREQ]; + +#ifdef CR8_G_ADD_75MS +# ifdef ENABLE_075_DMS_MODE +extern RAM_ALIGN const Word16 *const lpc_lin_pre_emphasis_7_5ms[NUM_SAMP_FREQ]; +extern RAM_ALIGN const Word16 *const lpc_lin_pre_emphasis_e_7_5ms[NUM_SAMP_FREQ]; +# endif +#endif + +extern RAM_ALIGN const Word16 bands_nrg_scale[32]; + +# ifdef ENABLE_HR_MODE +extern RAM_ALIGN const Word16 *const bands_offset_2_5ms_HR[2]; +extern RAM_ALIGN const Word16 *const bands_offset_5ms_HR[2]; +extern RAM_ALIGN const Word16 *const bands_offset_HR[2]; +# endif + +extern RAM_ALIGN const Word16 *const bands_offset[6]; +extern RAM_ALIGN const Word16 bands_offset_with_one_max[NUM_OFFSETS]; +extern RAM_ALIGN const Word16 bands_offset_with_two_max[NUM_OFFSETS]; + +extern RAM_ALIGN const Word16 bands_number_5ms[NUM_SAMP_FREQ]; +extern RAM_ALIGN const Word16 *const bands_offset_5ms[6]; +extern RAM_ALIGN const Word16 bands_offset_with_one_max_5ms[NUM_OFFSETS]; +extern RAM_ALIGN const Word16 bands_offset_with_two_max_5ms[NUM_OFFSETS]; +extern RAM_ALIGN const Word16 bands_number_2_5ms[NUM_SAMP_FREQ]; +extern RAM_ALIGN const Word16 *const bands_offset_2_5ms[6]; +extern RAM_ALIGN const Word16 bands_offset_with_one_max_2_5ms[NUM_OFFSETS]; +extern RAM_ALIGN const Word16 bands_offset_with_two_max_2_5ms[NUM_OFFSETS]; + +#ifdef CR8_G_ADD_75MS +#ifdef ENABLE_075_DMS_MODE +extern RAM_ALIGN const Word16 bands_number_7_5ms[]; +# ifndef GENERATE_BAND_TABLES +extern RAM_ALIGN const Word16 *const bands_offset_7_5ms[5]; +# endif +# ifdef ENABLE_HR_MODE +extern RAM_ALIGN const Word16 bands_number_7_5ms_HR[]; +# ifndef GENERATE_BAND_TABLES +extern RAM_ALIGN const Word16 *const bands_offset_7_5ms_HR[2]; +# endif +# endif +#endif +#endif + +extern RAM_ALIGN const Word16 pitch_max[5]; +extern RAM_ALIGN const Word16 plc_preemph_fac[NUM_SAMP_FREQ]; + +extern RAM_ALIGN const Word16 TDC_high_16[11]; +extern RAM_ALIGN const Word16 TDC_high_32[11]; +extern RAM_ALIGN const Word16 TDC_high_16_harm[11]; +extern RAM_ALIGN const Word16 TDC_high_32_harm[11]; + +extern RAM_ALIGN const Word32 *const lag_win[NUM_SAMP_FREQ]; + +extern RAM_ALIGN const Word16 *const bands_offset_lin[NUM_SAMP_FREQ]; +extern RAM_ALIGN const Word16 bands_offset_with_one_max_lin[NUM_SAMP_FREQ]; +extern RAM_ALIGN const Word16 bands_offset_with_two_max_lin[NUM_SAMP_FREQ]; +extern RAM_ALIGN const Word16 *const bands_offset_lin_5ms[NUM_SAMP_FREQ]; +extern RAM_ALIGN const Word16 bands_offset_with_one_max_lin_5ms[NUM_SAMP_FREQ]; +extern RAM_ALIGN const Word16 bands_offset_with_two_max_lin_5ms[NUM_SAMP_FREQ]; +extern RAM_ALIGN const Word16 *const bands_offset_lin_2_5ms[NUM_SAMP_FREQ]; +extern RAM_ALIGN const Word16 bands_offset_with_one_max_lin_2_5ms[NUM_SAMP_FREQ]; +extern RAM_ALIGN const Word16 bands_offset_with_two_max_lin_2_5ms[NUM_SAMP_FREQ]; + +#ifdef CR8_G_ADD_75MS +# ifdef ENABLE_075_DMS_MODE +extern RAM_ALIGN const Word16 bands_offset_with_one_max_7_5ms[NUM_OFFSETS]; +extern RAM_ALIGN const Word16 bands_offset_with_two_max_7_5ms[NUM_OFFSETS]; +extern RAM_ALIGN const Word16 *const bands_offset_lin_7_5ms[NUM_SAMP_FREQ]; +extern RAM_ALIGN const Word16 bands_offset_with_one_max_lin_7_5ms[NUM_SAMP_FREQ]; +extern RAM_ALIGN const Word16 bands_offset_with_two_max_lin_7_5ms[NUM_SAMP_FREQ]; +# endif +#endif + +extern RAM_ALIGN const Word32 inv_odft_twiddle_80_re[M]; +extern RAM_ALIGN const Word32 inv_odft_twiddle_80_im[M]; +extern RAM_ALIGN const Word32 inv_odft_twiddle_60_re[M]; +extern RAM_ALIGN const Word32 inv_odft_twiddle_60_im[M]; +extern RAM_ALIGN const Word32 inv_odft_twiddle_40_re[M]; +extern RAM_ALIGN const Word32 inv_odft_twiddle_40_im[M]; +extern RAM_ALIGN const Word32 inv_odft_twiddle_20_re[M]; +extern RAM_ALIGN const Word32 inv_odft_twiddle_20_im[M]; + +#ifdef SUBSET_WB +extern RAM_ALIGN const Word16 resamp_filt_16k[240]; +#else +extern RAM_ALIGN const Word16 resamp_filt_16k[1]; +#endif +#ifdef SUBSET_SSWB +extern RAM_ALIGN const Word16 resamp_filt_24k[240]; +#else +extern RAM_ALIGN const Word16 resamp_filt_24k[1]; +#endif +#ifdef SUBSET_SWB +extern RAM_ALIGN const Word16 resamp_filt_32k[240]; +#else +extern RAM_ALIGN const Word16 resamp_filt_32k[1]; +#endif +#ifdef SUBSET_FB +extern RAM_ALIGN const Word16 resamp_filt_48k[240]; +#else +extern RAM_ALIGN const Word16 resamp_filt_48k[1]; +#endif + +extern RAM_ALIGN const Word16 resamp_params[NUM_SAMP_FREQ][4]; +extern RAM_ALIGN const Word16 *const resamp_filts[NUM_SAMP_FREQ]; + +extern RAM_ALIGN const Word16 highpass50_filt_num[3]; +extern RAM_ALIGN const Word16 highpass50_filt_den[2]; + +extern RAM_ALIGN const Word16 olpa_ac_weighting[98]; + +extern RAM_ALIGN const Word16 ltpf_ac_interp_filt[7][9]; +extern RAM_ALIGN const Word16 inter_filter[5][4][12]; +extern RAM_ALIGN const Word16 inter_filter_shift[5]; +extern RAM_ALIGN const Word16 inter_filter_len[5]; +extern RAM_ALIGN const Word16 tilt_filter[5][4][11]; +extern RAM_ALIGN const Word16 tilt_filter_len[5]; +extern RAM_ALIGN const Word16 gain_scale_fac[4]; +extern RAM_ALIGN const UWord16 pitch_scale[NUM_SAMP_FREQ]; +extern RAM_ALIGN const Word16 ltpf_overlap_len[NUM_SAMP_FREQ]; + +extern RAM_ALIGN const Word16 sns_vq_reg_adj_scf[2]; +extern RAM_ALIGN const Word16 sns_vq_reg_lf_adj_scf[4]; +extern RAM_ALIGN const Word16 sns_vq_near_adj_scf[4]; +extern RAM_ALIGN const Word16 sns_vq_far_adj_scf[8]; +extern RAM_ALIGN const Word16 *const sns_gaintabPtr[4]; +extern RAM_ALIGN const Word16 sns_gainSz[4]; +extern RAM_ALIGN const Word16 sns_gainMSBbits[4]; +extern RAM_ALIGN const Word16 sns_gainLSBbits[4]; +extern RAM_ALIGN const Word16 sns_Kval[4][2]; +extern RAM_ALIGN const UWord32 sns_MPVQ_Sz[4][2]; + +extern RAM_ALIGN const Word16 st1SCF0_7_base5_32x8_Q11[256]; +extern RAM_ALIGN const Word16 st1SCF8_15_base5_32x8_Q11[256]; + +#ifdef ENABLE_HR_MODE +extern RAM_ALIGN const Word32 st1SCF0_7_base5_32x8_Q27[256]; +extern RAM_ALIGN const Word32 st1SCF8_15_base5_32x8_Q27[256]; +#endif + +/* PVQ deindexing tables */ +extern RAM_ALIGN const UWord32 h_memN16K12[12 + 2]; +extern RAM_ALIGN const UWord32 h_memN10K22[22 + 2]; +extern RAM_ALIGN const UWord32 h_memN6K2[2 + 2]; +extern RAM_ALIGN const Word16 tabledKMAX[16 + 1]; +extern RAM_ALIGN const UWord32 *const MPVQ_offs_ptr[16 + 1]; + +extern RAM_ALIGN const Word16 isqrt_Q16tab[1 + SQRT_EN_MAX_FX]; +#ifdef ENABLE_HR_MODE +extern RAM_ALIGN const Word32 isqrt_Q31tab[1 + SQRT_EN_MAX_FX]; +#endif + +extern RAM_ALIGN const Word16 adjust_global_gain_tables[5][NUM_SAMP_FREQ]; + +extern RAM_ALIGN const Word16 sqrt_table_phecu[]; +extern RAM_ALIGN const Word16 POW_ATT_TABLE0[]; +extern RAM_ALIGN const Word16 POW_ATT_TABLE1[]; +#ifdef PLC2_FADEOUT_IN_MS +#if PLC2_FADEOUT_IN_MS == 0 +extern RAM_ALIGN const Word16 *const POW_ATT_TABLES[3]; +#else +#ifdef CR8_A_PLC_FADEOUT_TUNING +extern RAM_ALIGN const Word16 fade_scheme_tab_fx[24 / 2][3]; +extern RAM_ALIGN const Word16 *const POW_ATT_TABLES[1+24/2]; +#else +extern RAM_ALIGN const Word16 *const POW_ATT_TABLES[11]; +#endif + +#endif +#else +extern RAM_ALIGN const Word16 *const POW_ATT_TABLES[3]; +#endif + +#ifdef CR8_A_PLC_FADEOUT_TUNING +extern RAM_ALIGN const Word16 scATHFx[7]; +#endif + +extern RAM_ALIGN const Word16 e_tot_headroom[]; +extern RAM_ALIGN const Word16 xfp_wE_MDCT2FFTQ11[]; + +extern RAM_ALIGN const Word16 num_FsByResQ0[5]; +extern RAM_ALIGN const Word16 *const LprotSzPtr; +extern RAM_ALIGN const Word16 InvLprot_Q22[5]; +extern RAM_ALIGN const Word16 PhEcuFftScale[5]; +extern RAM_ALIGN const Word16 oneOverFrameQ15Tab[5]; +extern RAM_ALIGN const Word16 PhEcu_Xsav_Flt2FxDnShift[]; +extern RAM_ALIGN const Word16 PhEcu_Xsav_Flt2FxScaleQ15[]; +extern RAM_ALIGN const Word16 PhEcu_frac_thr_rise_lin_Q15[]; +extern RAM_ALIGN const Word16 PhEcu_frac_thr_decay_lin_Q15[]; + +extern RAM_ALIGN const Word16 mdct_grp_bins_fx[]; +extern RAM_ALIGN const Word16 xavg_N_grp_fx[]; +extern RAM_ALIGN const Word16 spec_shape_headroom[]; +extern RAM_ALIGN const Word16 rectLengthTab[NUM_SAMP_FREQ]; +extern RAM_ALIGN const Word16 hamm_len2Tab[]; + +#ifndef CR10_A_ATTENUATION_CURVE_SELECTOR +#ifdef CR9_N_SHORT_FADE_FOR_UNSTABLE_PITCH +extern RAM_ALIGN const Word16 FADE_OUT_TYPE_2_ALPHA_5MS[30]; +extern RAM_ALIGN const Word16 FADE_OUT_TYPE_2_ALPHA_2_5MS[60]; +#endif +#endif +extern RAM_ALIGN const Word16 gw_len_inv_shift_fx[]; +extern RAM_ALIGN const Word16 gwlpr_fx[]; + +extern RAM_ALIGN const Word16 sin_quarterQ15_fx[]; +extern RAM_ALIGN const Word16 sincos_lowres_tab_sinQ15_fx[]; + +extern RAM_ALIGN const Word16 *const PhECU_wins[5][3]; + +extern RAM_ALIGN const Word16 *const w_new[]; +extern RAM_ALIGN const Word16 *const w_old[]; + +/* extern RAM_ALIGN const Word16 WORK_LEN[]; */ +extern RAM_ALIGN const Word16 COPY_LEN[]; +extern RAM_ALIGN const Word16 OLA_LEN[]; + +#if defined(CR8_A_PLC_FADEOUT_TUNING) +extern const Word16 plc_fadeout_param_maxlen[4]; +extern const Word16 plc_fadeout_param_maxbytes[4]; +#endif +#ifdef CR10_A_ATTENUATION_CURVE_SELECTOR +extern RAM_ALIGN const Word16 PLC_FADEOUT_TYPE_2_SELECTOR; +#endif + +#endif /* CONSTANTS_H */ diff --git a/lib_lc3plus/cutoff_bandwidth.c b/lib_lc3plus/cutoff_bandwidth.c new file mode 100644 index 0000000000000000000000000000000000000000..8ab047c8143107351822bfa8271bd7dd669dcf7c --- /dev/null +++ b/lib_lc3plus/cutoff_bandwidth.c @@ -0,0 +1,26 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.5 * +* 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 "functions.h" + +void process_cutoff_bandwidth(Word32 d_fx[], Word16 len, Word16 bw_bin) +{ + Word32 i = 0; + if (len > bw_bin){ + /* roll off */ + for (i = -1; i < 3; i++) { + d_fx[bw_bin + i] = L_shr(d_fx[bw_bin + i], add(i, 2)); + } + + for (i = bw_bin + 3; i < len; i++) { + d_fx[i] = 0; move32(); + } + } +} + diff --git a/lib_lc3plus/dct2_fx.c b/lib_lc3plus/dct2_fx.c new file mode 100644 index 0000000000000000000000000000000000000000..c301c2aebc7d10e4d4c61522404e1c2f55519c5f --- /dev/null +++ b/lib_lc3plus/dct2_fx.c @@ -0,0 +1,473 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.5 * +* 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 "functions.h" + +void idct16_fx(const Word16 *in, Word16 *out) +{ + Dyn_Mem_Deluxe_In( + Word16 a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15; + Word16 b0, b1, b2, b3, b4, b5, b6, b7, b8, b9, b10, b11, b12, b13, b14, b15; + ); + + a8 = add(mult_r(in[1], 1136), mult_r(in[15], -11529)); /* Sπ/32/√8 -S15π/32/√8 */ + a9 = add(mult_r(in[9], 8956), mult_r(in[7], -7350)); /* S9π/32/√8 -S7π/32/√8 */ + a10 = add(mult_r(in[5], 5461), mult_r(in[11], -10217)); /* S5π/32/√8 -S11π/32/√8 */ + a11 = add(mult_r(in[13], 11086), mult_r(in[3], -3363)); /* S13π/32/√8 -S3π/32/√8 */ + a12 = add(mult_r(in[3], 11086), mult_r(in[13], 3363)); /* C3π/32/√8 C13π/32/√8 */ + a13 = add(mult_r(in[11], 5461), mult_r(in[5], 10217)); /* C11π/32/√8 C5π/32/√8 */ + a14 = add(mult_r(in[7], 8956), mult_r(in[9], 7350)); /* C7π/32/√8 C9π/32/√8 */ + a15 = add(mult_r(in[15], 1136), mult_r(in[1], 11529)); /* C15π/32/√8 Cπ/32/√8 */ + + b4 = add(mult_r(in[2], 2260), mult_r(in[14], -11363)); /* Sπ/16/√8 -S7π/16/√8 */ + b5 = add(mult_r(in[10], 9633), mult_r(in[6], -6436)); /* S5π/16/√8 -S3π/16/√8 */ + b6 = add(mult_r(in[6], 9633), mult_r(in[10], 6436)); /* C3π/16/√8 C5π/16/√8 */ + b7 = add(mult_r(in[14], 2260), mult_r(in[2], 11363)); /* C7π/16/√8 Cπ/16/√8 */ + b8 = add(a9, a8); + b9 = sub(a8, a9); + b10 = sub(a11, a10); + b11 = add(a10, a11); + b12 = add(a13, a12); + b13 = sub(a12, a13); + b14 = sub(a15, a14); + b15 = add(a14, a15); + + a0 = add(mult_r(in[0], 8192), mult_r(in[8], 8192)); /* Cπ/4/√8 Cπ/4/√8 */ + a1 = add(mult_r(in[8], -8192), mult_r(in[0], 8192)); /* -Cπ/4/√8 Cπ/4/√8 */ + a2 = add(mult_r(in[4], 4433), mult_r(in[12], -10703)); /* Sπ/8/√8 -S3π/8/√8 */ + a3 = add(mult_r(in[12], 4433), mult_r(in[4], 10703)); /* C3π/8/√8 Cπ/8/√8 */ + a4 = add(b5, b4); + a5 = sub(b4, b5); + a6 = sub(b7, b6); + a7 = add(b6, b7); + a8 = b8; move16(); + a9 = add(mult_r(b9, -30274), mult_r(b14, 12540)); /* -Cπ/8 C3π/8 */ + a10 = add(mult_r(b10, -12540), mult_r(b13, -30274)); /* -Sπ/8 -S3π/8 */ + a11 = b11; move16(); + a12 = b12; move16(); + a13 = add(mult_r(b13, 12540), mult_r(b10, -30274)); /* C3π/8 -Cπ/8 */ + a14 = add(mult_r(b14, 30274), mult_r(b9, 12540)); /* S3π/8 Sπ/8 */ + a15 = b15; move16(); + + b0 = add(a3, a0); + b1 = add(a2, a1); + b2 = sub(a1, a2); + b3 = sub(a0, a3); + b4 = a4; move16(); + b5 = add(mult_r(a5, -23170), mult_r(a6, 23170)); /* -Cπ/4 Cπ/4 */ + b6 = add(mult_r(a6, 23170), mult_r(a5, 23170)); /* Cπ/4 Cπ/4 */ + b7 = a7; move16(); + b8 = add(a11, a8); + b9 = add(a10, a9); + b10 = sub(a9, a10); + b11 = sub(a8, a11); + b12 = sub(a15, a12); + b13 = sub(a14, a13); + b14 = add(a13, a14); + b15 = add(a12, a15); + + a0 = add(b7, b0); + a1 = add(b6, b1); + a2 = add(b5, b2); + a3 = add(b4, b3); + a4 = sub(b3, b4); + a5 = sub(b2, b5); + a6 = sub(b1, b6); + a7 = sub(b0, b7); + a10 = add(mult_r(b10, -23170), mult_r(b13, 23170)); /* -Cπ/4 Cπ/4 */ + a11 = add(mult_r(b11, -23170), mult_r(b12, 23170)); /* -Cπ/4 Cπ/4 */ + a12 = add(mult_r(b12, 23170), mult_r(b11, 23170)); /* Cπ/4 Cπ/4 */ + a13 = add(mult_r(b13, 23170), mult_r(b10, 23170)); /* Cπ/4 Cπ/4 */ + + out[0] = add(b15, a0); move16(); + out[1] = add(b14, a1); move16(); + out[2] = add(a13, a2); move16(); + out[3] = add(a12, a3); move16(); + out[4] = add(a11, a4); move16(); + out[5] = add(a10, a5); move16(); + out[6] = add(b9, a6); move16(); + out[7] = add(b8, a7); move16(); + out[8] = sub(a7, b8); move16(); + out[9] = sub(a6, b9); move16(); + out[10] = sub(a5, a10); move16(); + out[11] = sub(a4, a11); move16(); + out[12] = sub(a3, a12); move16(); + out[13] = sub(a2, a13); move16(); + out[14] = sub(a1, b14); move16(); + out[15] = sub(a0, b15); move16(); + + Dyn_Mem_Deluxe_Out(); +} + +void dct32_fx(const Word32 *in, Word32 *out) +{ + Dyn_Mem_Deluxe_In(Word32 a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15; + Word32 b0, b1, b2, b3, b4, b5, b6, b7, b8, b9, b10, b11, b12, b13, b14, b15;); + + a0 = L_add(in[15], in[0]); + a1 = L_add(in[14], in[1]); + a2 = L_add(in[13], in[2]); + a3 = L_add(in[12], in[3]); + a4 = L_add(in[11], in[4]); + a5 = L_add(in[10], in[5]); + a6 = L_add(in[9], in[6]); + a7 = L_add(in[8], in[7]); + a10 = L_sub(in[5], in[10]); + a11 = L_sub(in[4], in[11]); + a12 = L_sub(in[3], in[12]); + a13 = L_sub(in[2], in[13]); + + b0 = L_add(a7, a0); + b1 = L_add(a6, a1); + b2 = L_add(a5, a2); + b3 = L_add(a4, a3); + b4 = L_sub(a3, a4); +#ifdef CR9_C_FIX_DCT2_OVERFLOW + b5 = L_sub_sat(a2, a5); +#else + b5 = L_sub(a2, a5); +#endif +#ifdef CR9_C_FIX_DCT2_OVERFLOW + b6 = L_sub_sat(a1, a6); +#else + b6 = L_sub(a1, a6); +#endif + b7 = L_sub(a0, a7); + b8 = L_sub(in[7], in[8]); + b9 = L_sub(in[6], in[9]); + b10 = L_add(Mpy_32_16_lc3plus(a10, -23170), Mpy_32_16_lc3plus(a13, 23170)); /* -Cπ/4 Cπ/4 */ + b11 = L_add(Mpy_32_16_lc3plus(a11, -23170), Mpy_32_16_lc3plus(a12, 23170)); /* -Cπ/4 Cπ/4 */ + b12 = L_add(Mpy_32_16_lc3plus(a12, 23170), Mpy_32_16_lc3plus(a11, 23170)); /* Cπ/4 Cπ/4 */ + b13 = L_add(Mpy_32_16_lc3plus(a13, 23170), Mpy_32_16_lc3plus(a10, 23170)); /* Cπ/4 Cπ/4 */ + b14 = L_sub(in[1], in[14]); + b15 = L_sub(in[0], in[15]); + + a0 = L_add(b3, b0); + a1 = L_add(b2, b1); + a2 = L_sub(b1, b2); + a3 = L_sub_sat(b0, b3); + a4 = b4; + move16(); + a5 = L_add(Mpy_32_16_lc3plus(b5, -23170), Mpy_32_16_lc3plus(b6, 23170)); /* -Cπ/4 Cπ/4 */ + a6 = L_add(Mpy_32_16_lc3plus(b6, 23170), Mpy_32_16_lc3plus(b5, 23170)); /* Cπ/4 Cπ/4 */ + a7 = b7; + move16(); + a8 = L_add(b11, b8); + a9 = L_add(b10, b9); + a10 = L_sub(b9, b10); + a11 = L_sub(b8, b11); + a12 = L_sub(b15, b12); + a13 = L_sub(b14, b13); + a14 = L_add(b13, b14); + a15 = L_add(b12, b15); + + out[0] = L_add(Mpy_32_16_lc3plus(a0, 8192), Mpy_32_16_lc3plus(a1, 8192)); + move16(); /* Cπ/4/√8 Cπ/4/√8 */ + out[8] = L_add(Mpy_32_16_lc3plus(a1, -8192), Mpy_32_16_lc3plus(a0, 8192)); + move16(); /* -Cπ/4/√8 Cπ/4/√8 */ + out[4] = L_add(Mpy_32_16_lc3plus(a2, 4433), Mpy_32_16_lc3plus(a3, 10703)); + move16(); /* Sπ/8/√8 Cπ/8/√8 */ + out[12] = L_add(Mpy_32_16_lc3plus(a3, 4433), Mpy_32_16_lc3plus(a2, -10703)); + move16(); /* C3π/8/√8 -S3π/8/√8 */ + b4 = L_add(a5, a4); + b5 = L_sub(a4, a5); + b6 = L_sub_sat(a7, a6); + b7 = L_add(a6, a7); + b8 = a8; + move16(); + b9 = L_add(Mpy_32_16_lc3plus(a9, -30274), Mpy_32_16_lc3plus(a14, 12540)); /* -Cπ/8 Sπ/8 */ + b10 = L_add(Mpy_32_16_lc3plus(a10, -12540), Mpy_32_16_lc3plus(a13, -30274)); /* -Sπ/8 -Cπ/8 */ + b11 = a11; + move16(); + b12 = a12; + move16(); + b13 = L_add(Mpy_32_16_lc3plus(a13, 12540), Mpy_32_16_lc3plus(a10, -30274)); /* C3π/8 -S3π/8 */ + b14 = L_add(Mpy_32_16_lc3plus(a14, 30274), Mpy_32_16_lc3plus(a9, 12540)); /* S3π/8 C3π/8 */ + b15 = a15; + move16(); + + out[2] = L_add(Mpy_32_16_lc3plus(b4, 2260), Mpy_32_16_lc3plus(b7, 11363)); + move16(); /* Sπ/16/√8 Cπ/16/√8 */ + out[10] = L_add(Mpy_32_16_lc3plus(b5, 9633), Mpy_32_16_lc3plus(b6, 6436)); + move16(); /* S5π/16/√8 C5π/16/√8 */ + out[6] = L_add(Mpy_32_16_lc3plus(b6, 9633), Mpy_32_16_lc3plus(b5, -6436)); + move16(); /* C3π/16/√8 -S3π/16/√8 */ + out[14] = L_add(Mpy_32_16_lc3plus(b7, 2260), Mpy_32_16_lc3plus(b4, -11363)); + move16(); /* C7π/16/√8 -S7π/16/√8 */ + + a8 = L_add_sat(b9, b8); + a9 = L_sub_sat(b8, b9); + a10 = L_sub_sat(b11, b10); + a11 = L_add_sat(b10, b11); + a12 = L_add_sat(b13, b12); + a13 = L_sub_sat(b12, b13); + a14 = L_sub_sat(b15, b14); + a15 = L_add_sat(b14, b15); + + out[1] = L_add(Mpy_32_16_lc3plus(a8, 1136), Mpy_32_16_lc3plus(a15, 11529)); + move16(); /* Sπ/32/√8 Cπ/32/√8 */ + out[9] = L_add(Mpy_32_16_lc3plus(a9, 8956), Mpy_32_16_lc3plus(a14, 7350)); + move16(); /* S9π/32/√8 C9π/32/√8 */ + out[5] = L_add(Mpy_32_16_lc3plus(a10, 5461), Mpy_32_16_lc3plus(a13, 10217)); + move16(); /* S5π/32/√8 C5π/32/√8 */ + out[13] = L_add(Mpy_32_16_lc3plus(a11, 11086), Mpy_32_16_lc3plus(a12, 3363)); + move16(); /* S13π/32/√8 C13π/32/√8 */ + out[3] = L_add(Mpy_32_16_lc3plus(a12, 11086), Mpy_32_16_lc3plus(a11, -3363)); + move16(); /* C3π/32/√8 -S3π/32/√8 */ + out[11] = L_add(Mpy_32_16_lc3plus(a13, 5461), Mpy_32_16_lc3plus(a10, -10217)); + move16(); /* C11π/32/√8 -S11π/32/√8 */ + out[7] = L_add(Mpy_32_16_lc3plus(a14, 8956), Mpy_32_16_lc3plus(a9, -7350)); + move16(); /* C7π/32/√8 -S7π/32/√8 */ + out[15] = L_add(Mpy_32_16_lc3plus(a15, 1136), Mpy_32_16_lc3plus(a8, -11529)); + move16(); /* C15π/32/√8 -S15/32/√8 */ + + Dyn_Mem_Deluxe_Out(); +} + +void idct32_fx(const Word32 *in, Word32 *out) +{ + Dyn_Mem_Deluxe_In(Word32 a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15; + Word32 b0, b1, b2, b3, b4, b5, b6, b7, b8, b9, b10, b11, b12, b13, b14, b15;); + + a8 = L_add(Mpy_32_16_lc3plus(in[1], 1136), Mpy_32_16_lc3plus(in[15], -11529)); /* Sπ/32/√8 -S15π/32/√8 */ + a9 = L_add(Mpy_32_16_lc3plus(in[9], 8956), Mpy_32_16_lc3plus(in[7], -7350)); /* S9π/32/√8 -S7π/32/√8 */ + a10 = L_add(Mpy_32_16_lc3plus(in[5], 5461), Mpy_32_16_lc3plus(in[11], -10217)); /* S5π/32/√8 -S11π/32/√8 */ + a11 = L_add(Mpy_32_16_lc3plus(in[13], 11086), Mpy_32_16_lc3plus(in[3], -3363)); /* S13π/32/√8 -S3π/32/√8 */ + a12 = L_add(Mpy_32_16_lc3plus(in[3], 11086), Mpy_32_16_lc3plus(in[13], 3363)); /* C3π/32/√8 C13π/32/√8 */ + a13 = L_add(Mpy_32_16_lc3plus(in[11], 5461), Mpy_32_16_lc3plus(in[5], 10217)); /* C11π/32/√8 C5π/32/√8 */ + a14 = L_add(Mpy_32_16_lc3plus(in[7], 8956), Mpy_32_16_lc3plus(in[9], 7350)); /* C7π/32/√8 C9π/32/√8 */ + a15 = L_add(Mpy_32_16_lc3plus(in[15], 1136), Mpy_32_16_lc3plus(in[1], 11529)); /* C15π/32/√8 Cπ/32/√8 */ + + b4 = L_add(Mpy_32_16_lc3plus(in[2], 2260), Mpy_32_16_lc3plus(in[14], -11363)); /* Sπ/16/√8 -S7π/16/√8 */ + b5 = L_add(Mpy_32_16_lc3plus(in[10], 9633), Mpy_32_16_lc3plus(in[6], -6436)); /* S5π/16/√8 -S3π/16/√8 */ + b6 = L_add(Mpy_32_16_lc3plus(in[6], 9633), Mpy_32_16_lc3plus(in[10], 6436)); /* C3π/16/√8 C5π/16/√8 */ + b7 = L_add(Mpy_32_16_lc3plus(in[14], 2260), Mpy_32_16_lc3plus(in[2], 11363)); /* C7π/16/√8 Cπ/16/√8 */ + b8 = L_add(a9, a8); + b9 = L_sub(a8, a9); + b10 = L_sub(a11, a10); + b11 = L_add(a10, a11); + b12 = L_add(a13, a12); + b13 = L_sub(a12, a13); + b14 = L_sub(a15, a14); + b15 = L_add(a14, a15); + + a0 = L_add(Mpy_32_16_lc3plus(in[0], 8192), Mpy_32_16_lc3plus(in[8], 8192)); /* Cπ/4/√8 Cπ/4/√8 */ + a1 = L_add(Mpy_32_16_lc3plus(in[8], -8192), Mpy_32_16_lc3plus(in[0], 8192)); /* -Cπ/4/√8 Cπ/4/√8 */ + a2 = L_add(Mpy_32_16_lc3plus(in[4], 4433), Mpy_32_16_lc3plus(in[12], -10703)); /* Sπ/8/√8 -S3π/8/√8 */ + a3 = L_add(Mpy_32_16_lc3plus(in[12], 4433), Mpy_32_16_lc3plus(in[4], 10703)); /* C3π/8/√8 Cπ/8/√8 */ + a4 = L_add(b5, b4); + a5 = L_sub(b4, b5); + a6 = L_sub(b7, b6); + a7 = L_add(b6, b7); + a8 = b8; + move32(); + a9 = L_add(Mpy_32_16_lc3plus(b9, -30274), Mpy_32_16_lc3plus(b14, 12540)); /* -Cπ/8 C3π/8 */ + a10 = L_add(Mpy_32_16_lc3plus(b10, -12540), Mpy_32_16_lc3plus(b13, -30274)); /* -Sπ/8 -S3π/8 */ + a11 = b11; + move32(); + a12 = b12; + move32(); + a13 = L_add(Mpy_32_16_lc3plus(b13, 12540), Mpy_32_16_lc3plus(b10, -30274)); /* C3π/8 -Cπ/8 */ + a14 = L_add(Mpy_32_16_lc3plus(b14, 30274), Mpy_32_16_lc3plus(b9, 12540)); /* S3π/8 Sπ/8 */ + a15 = b15; + move32(); + + b0 = L_add(a3, a0); + b1 = L_add(a2, a1); + b2 = L_sub(a1, a2); + b3 = L_sub(a0, a3); + b4 = a4; + move32(); + b5 = L_add(Mpy_32_16_lc3plus(a5, -23170), Mpy_32_16_lc3plus(a6, 23170)); /* -Cπ/4 Cπ/4 */ + b6 = L_add(Mpy_32_16_lc3plus(a6, 23170), Mpy_32_16_lc3plus(a5, 23170)); /* Cπ/4 Cπ/4 */ + b7 = a7; + move32(); + b8 = L_add(a11, a8); + b9 = L_add(a10, a9); + b10 = L_sub(a9, a10); + b11 = L_sub(a8, a11); + b12 = L_sub(a15, a12); + b13 = L_sub(a14, a13); + b14 = L_add(a13, a14); + b15 = L_add(a12, a15); + + a0 = L_add(b7, b0); + a1 = L_add(b6, b1); + a2 = L_add(b5, b2); + a3 = L_add(b4, b3); + a4 = L_sub(b3, b4); + a5 = L_sub(b2, b5); + a6 = L_sub(b1, b6); + a7 = L_sub(b0, b7); + a10 = L_add(Mpy_32_16_lc3plus(b10, -23170), Mpy_32_16_lc3plus(b13, 23170)); /* -Cπ/4 Cπ/4 */ + a11 = L_add(Mpy_32_16_lc3plus(b11, -23170), Mpy_32_16_lc3plus(b12, 23170)); /* -Cπ/4 Cπ/4 */ + a12 = L_add(Mpy_32_16_lc3plus(b12, 23170), Mpy_32_16_lc3plus(b11, 23170)); /* Cπ/4 Cπ/4 */ + a13 = L_add(Mpy_32_16_lc3plus(b13, 23170), Mpy_32_16_lc3plus(b10, 23170)); /* Cπ/4 Cπ/4 */ + + out[0] = L_add(b15, a0); + move32(); + out[1] = L_add(b14, a1); + move32(); + out[2] = L_add(a13, a2); + move32(); + out[3] = L_add(a12, a3); + move32(); + out[4] = L_add(a11, a4); + move32(); + out[5] = L_add(a10, a5); + move32(); + out[6] = L_add(b9, a6); + move32(); + out[7] = L_add(b8, a7); + move32(); + out[8] = L_sub(a7, b8); + move32(); + out[9] = L_sub(a6, b9); + move32(); + out[10] = L_sub(a5, a10); + move32(); + out[11] = L_sub(a4, a11); + move32(); + out[12] = L_sub(a3, a12); + move32(); + out[13] = L_sub(a2, a13); + move32(); + out[14] = L_sub(a1, b14); + move32(); + out[15] = L_sub(a0, b15); + move32(); + + Dyn_Mem_Deluxe_Out(); +} + +void idct32_32_fx(const Word32 *in, Word32 *out) +{ + Dyn_Mem_Deluxe_In(Word32 a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15; + Word32 b0, b1, b2, b3, b4, b5, b6, b7, b8, b9, b10, b11, b12, b13, b14, b15;); + + /*round(sin(pi*(1:16)/32)/sqrt(8)*2^31) = + 74419526 148122351 220398677 290552444 357908031 421816769 481663180 536870912 + 586908283 631293407 669598830 701455651 726557070 744661347 755594128 759250125 + */ + /*ound(cos(pi*(1:16)/32)/sqrt(8)*2^31) = + 755594128 744661347 726557070 701455651 669598830 631293407 586908283 536870912 + 481663180 421816769 357908031 290552444 220398677 148122351 74419526 0 + */ + + a8 = L_add(Mpy_32_32_lc3plus(in[1], 74419526), Mpy_32_32_lc3plus(in[15], -755594128)); /* Sπ/32/√8 -S15π/32/√8 */ + a9 = L_add(Mpy_32_32_lc3plus(in[9], 586908283), Mpy_32_32_lc3plus(in[7], -481663180)); /* S9π/32/√8 -S7π/32/√8 */ + a10 = L_add(Mpy_32_32_lc3plus(in[5], 357908031), Mpy_32_32_lc3plus(in[11], -669598830)); /* S5π/32/√8 -S11π/32/√8 */ + a11 = L_add(Mpy_32_32_lc3plus(in[13], 726557070), Mpy_32_32_lc3plus(in[3], -220398677)); /* S13π/32/√8 -S3π/32/√8 */ + + a12 = L_add(Mpy_32_32_lc3plus(in[3], 726557070), Mpy_32_32_lc3plus(in[13], 220398677)); /* C3π/32/√8 C13π/32/√8 */ + a13 = L_add(Mpy_32_32_lc3plus(in[11], 357908031), Mpy_32_32_lc3plus(in[5], 669598830)); /* C11π/32/√8 C5π/32/√8 */ + a14 = L_add(Mpy_32_32_lc3plus(in[7], 586908283), Mpy_32_32_lc3plus(in[9], 481663180)); /* C7π/32/√8 C9π/32/√8 */ + a15 = L_add(Mpy_32_32_lc3plus(in[15], 74419526), Mpy_32_32_lc3plus(in[1], 755594128)); /* C15π/32/√8 Cπ/32/√8 */ + + b4 = L_add(Mpy_32_32_lc3plus(in[2], 148122351), Mpy_32_32_lc3plus(in[14], -744661347)); /* Sπ/16/√8 -S7π/16/√8 */ + b5 = L_add(Mpy_32_32_lc3plus(in[10], 631293407), Mpy_32_32_lc3plus(in[6], -421816769)); /* S5π/16/√8 -S3π/16/√8 */ + b6 = L_add(Mpy_32_32_lc3plus(in[6], 631293407), Mpy_32_32_lc3plus(in[10], 421816769)); /* C3π/16/√8 C5π/16/√8 */ + b7 = L_add(Mpy_32_32_lc3plus(in[14], 148122351), Mpy_32_32_lc3plus(in[2], 744661347)); /* C7π/16/√8 Cπ/16/√8 */ + b8 = L_add(a9, a8); + b9 = L_sub(a8, a9); + b10 = L_sub(a11, a10); + b11 = L_add(a10, a11); + b12 = L_add(a13, a12); + b13 = L_sub(a12, a13); + b14 = L_sub(a15, a14); + b15 = L_add(a14, a15); + + a0 = L_add(Mpy_32_32_lc3plus(in[0], 536870912), Mpy_32_32_lc3plus(in[8], 536870912)); /* Cπ/4/√8 Cπ/4/√8 */ + a1 = L_add(Mpy_32_32_lc3plus(in[8], -536870912), Mpy_32_32_lc3plus(in[0], 536870912)); /* -Cπ/4/√8 Cπ/4/√8 */ + a2 = L_add(Mpy_32_32_lc3plus(in[4], 290552444), Mpy_32_32_lc3plus(in[12], -701455651)); /* Sπ/8/√8 -S3π/8/√8 */ + a3 = L_add(Mpy_32_32_lc3plus(in[12], 290552444), Mpy_32_32_lc3plus(in[4], 701455651)); /* C3π/8/√8 Cπ/8/√8 */ + a4 = L_add(b5, b4); + a5 = L_sub(b4, b5); + a6 = L_sub(b7, b6); + a7 = L_add(b6, b7); + a8 = b8; + move32(); + a9 = L_add(Mpy_32_32_lc3plus(b9, -1984016189), Mpy_32_32_lc3plus(b14, 821806413)); /* -Cπ/8 C3π/8 */ + a10 = L_add(Mpy_32_32_lc3plus(b10, -821806413), Mpy_32_32_lc3plus(b13, -1984016189)); /* -Sπ/8 -S3π/8 */ + a11 = b11; + move32(); + a12 = b12; + move32(); + a13 = L_add(Mpy_32_32_lc3plus(b13, 821806413), Mpy_32_32_lc3plus(b10, -1984016189)); /* C3π/8 -Cπ/8 */ + a14 = L_add(Mpy_32_32_lc3plus(b14, 1984016189), Mpy_32_32_lc3plus(b9, 821806413)); /* S3π/8 Sπ/8 */ + a15 = b15; + move32(); + + b0 = L_add(a3, a0); + b1 = L_add(a2, a1); + b2 = L_sub(a1, a2); + b3 = L_sub(a0, a3); + b4 = a4; + move32(); + b5 = L_add(Mpy_32_32_lc3plus(a5, -1518500250), Mpy_32_32_lc3plus(a6, 1518500250)); /* -Cπ/4 Cπ/4 */ + b6 = L_add(Mpy_32_32_lc3plus(a6, 1518500250), Mpy_32_32_lc3plus(a5, 1518500250)); /* Cπ/4 Cπ/4 */ + b7 = a7; + move32(); + b8 = L_add(a11, a8); + b9 = L_add(a10, a9); + b10 = L_sub(a9, a10); + b11 = L_sub(a8, a11); + b12 = L_sub(a15, a12); + b13 = L_sub(a14, a13); + b14 = L_add(a13, a14); + b15 = L_add(a12, a15); + + a0 = L_add(b7, b0); + a1 = L_add(b6, b1); + a2 = L_add(b5, b2); + a3 = L_add(b4, b3); + a4 = L_sub(b3, b4); + a5 = L_sub(b2, b5); + a6 = L_sub(b1, b6); + a7 = L_sub(b0, b7); + a10 = L_add(Mpy_32_32_lc3plus(b10, -1518500250), Mpy_32_32_lc3plus(b13, 1518500250)); /* -Cπ/4 Cπ/4 */ + a11 = L_add(Mpy_32_32_lc3plus(b11, -1518500250), Mpy_32_32_lc3plus(b12, 1518500250)); /* -Cπ/4 Cπ/4 */ + a12 = L_add(Mpy_32_32_lc3plus(b12, 1518500250), Mpy_32_32_lc3plus(b11, 1518500250)); /* Cπ/4 Cπ/4 */ + a13 = L_add(Mpy_32_32_lc3plus(b13, 1518500250), Mpy_32_32_lc3plus(b10, 1518500250)); /* Cπ/4 Cπ/4 */ + + out[0] = L_add(b15, a0); + move32(); + out[1] = L_add(b14, a1); + move32(); + out[2] = L_add(a13, a2); + move32(); + out[3] = L_add(a12, a3); + move32(); + out[4] = L_add(a11, a4); + move32(); + out[5] = L_add(a10, a5); + move32(); + out[6] = L_add(b9, a6); + move32(); + out[7] = L_add(b8, a7); + move32(); + out[8] = L_sub(a7, b8); + move32(); + out[9] = L_sub(a6, b9); + move32(); + out[10] = L_sub(a5, a10); + move32(); + out[11] = L_sub(a4, a11); + move32(); + out[12] = L_sub(a3, a12); + move32(); + out[13] = L_sub(a2, a13); + move32(); + out[14] = L_sub(a1, b14); + move32(); + out[15] = L_sub(a0, b15); + move32(); + + Dyn_Mem_Deluxe_Out(); +} diff --git a/lib_lc3plus/dct4_fx.c b/lib_lc3plus/dct4_fx.c new file mode 100644 index 0000000000000000000000000000000000000000..dca4e382cf1d540fc6736a08d71955091f8411a6 --- /dev/null +++ b/lib_lc3plus/dct4_fx.c @@ -0,0 +1,228 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.5 * +* 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 "functions.h" +#include "rom_basop_util_lc3plus.h" + + +void dct_IV(Word32 *pDat, /* i/o: pointer to data buffer */ + Word16 *pDat_e, /* i/o: pointer to data exponent */ + Word16 L, /* i : length of block */ +#ifdef CR8_F_ADAPT_MDCT_DCT_PRECISION +# ifdef ENABLE_HR_MODE + Word16 hrmode, /* indicate high precision usage */ +# endif +#endif /* CR8_F_ADAPT_MDCT_DCT_PRECISION */ + Word32 *workBuffer) /* : size of L */ + +{ + Word16 sin_step; + Word16 idx; + Word16 M_var; + Word16 M2; + + Word32 *pDat_0; + Word32 *pDat_1; + + Word32 accu1; + Word32 accu2; + Word32 accu3; + Word32 accu4; + + Word32 i; + +#ifdef ENABLE_HR_MODE + const PWord32 *twiddle; + const PWord32 *sin_twiddle; +#else + const PWord16 *twiddle; + const PWord16 *sin_twiddle; +#endif + +#ifdef ENABLE_DCTIV_RESCALE + Word16 scale; +#endif + +#ifdef DYNMEM_COUNT +#ifdef ENABLE_HR_MODE + Dyn_Mem_In("dct_IV", sizeof(struct { + Word16 sin_step; + Word16 idx; + Counter i; + Word16 M_var; + Word16 M2; + + Word32 *pDat_0; + Word32 *pDat_1; + + Word32 accu1; + Word32 accu2; + Word32 accu3; + Word32 accu4; + + const PWord32 *twiddle; + const PWord32 *sin_twiddle; + })); + +#else + Dyn_Mem_In("dct_IV", sizeof(struct { + Word16 sin_step; + Word16 idx; + Counter i; + Word16 M_var; + Word16 M2; + + Word32 *pDat_0; + Word32 *pDat_1; + + Word32 accu1; + Word32 accu2; + Word32 accu3; + Word32 accu4; + + const PWord16 *twiddle; + const PWord16 *sin_twiddle; + })); +#endif /* ENABLE_HR_MODE */ +#endif /* DYNMEM_COUNT */ + + M_var = shr_pos_pos(L, 1); + M2 = sub(M_var, 1); + + BASOP_getTables(&twiddle, &sin_twiddle, &sin_step, L); + + pDat_0 = &pDat[0]; + pDat_1 = &pDat[L - 2]; + + FOR (i = 0; i < M2; i += 2) + { +#ifdef ENABLE_HR_MODE +# ifdef CR8_F_ADAPT_MDCT_DCT_PRECISION + if (hrmode) { + cplxMpy32_32_32_2(accu1, accu2, pDat_1[1], pDat_0[0], twiddle[i].v.re, twiddle[i].v.im); + cplxMpy32_32_32_2(accu3, accu4, pDat_1[0], pDat_0[1], twiddle[i + 1].v.re, twiddle[i + 1].v.im); + } else { + cplxMpy32_32_16_2(accu1, accu2, pDat_1[1], pDat_0[0], round_fx_sat(twiddle[i].v.re), round_fx_sat(twiddle[i].v.im)); + cplxMpy32_32_16_2(accu3, accu4, pDat_1[0], pDat_0[1], round_fx_sat(twiddle[i + 1].v.re), round_fx_sat(twiddle[i + 1].v.im)); + } +# else /* CR8_F_ADAPT_MDCT_DCT_PRECISION */ + cplxMpy32_32_32_2(accu1, accu2, pDat_1[1], pDat_0[0], twiddle[i].v.re, twiddle[i].v.im); + cplxMpy32_32_32_2(accu3, accu4, pDat_1[0], pDat_0[1], twiddle[i + 1].v.re, twiddle[i + 1].v.im); +# endif /* CR8_F_ADAPT_MDCT_DCT_PRECISION */ + +#else + cplxMpy32_32_16_2(accu1, accu2, pDat_1[1], pDat_0[0], twiddle[i].v.re, twiddle[i].v.im); + cplxMpy32_32_16_2(accu3, accu4, pDat_1[0], pDat_0[1], twiddle[i + 1].v.re, twiddle[i + 1].v.im); +#endif + + pDat_0[0] = accu2; move32(); + pDat_0[1] = accu1; move32(); + pDat_1[0] = accu4; move32(); + pDat_1[1] = L_negate(accu3); move32(); + + pDat_0 = pDat_0 + 2; + pDat_1 = pDat_1 - 2; + } + +#ifdef ENABLE_DCTIV_RESCALE +# ifdef CR8_F_ADAPT_MDCT_DCT_PRECISION + if (hrmode) +# endif /* CR8_F_ADAPT_MDCT_DCT_PRECISION */ + { + + scale = s_max(getScaleFactor32_lc3plus(pDat, L), 0); move16(); + + FOR (i = 0; i < L; i++) + { + pDat[i] = L_shl_pos(pDat[i], scale); move32(); + } + + *pDat_e = sub(*pDat_e, scale); move16(); + } +#endif + + BASOP_cfft_lc3plus(&pDat[0], &pDat[1], M_var, 2, pDat_e, workBuffer); + + pDat_0 = &pDat[0]; + pDat_1 = &pDat[L - 2]; + + idx = sin_step; + M2 = sub(shr_pos_pos(add(M_var, 1), 1), 1); + + /* Sin and Cos values are 0.0f and 1.0f */ +#ifdef ENABLE_HR_MODE + cplxMpy32_32_32_2(accu3, accu4, pDat_1[0], pDat_1[1], sin_twiddle[idx].v.re, sin_twiddle[idx].v.im); +#else + cplxMpy32_32_16_2(accu3, accu4, pDat_1[0], pDat_1[1], sin_twiddle[idx].v.re, sin_twiddle[idx].v.im); +#endif + + pDat_1[1] = L_negate(L_shr_pos(pDat_0[1], 1)); move32(); + pDat_0[0] = L_shr_pos(pDat_0[0], 1); move32(); + + FOR (i = 1; i < M2; i++) + { + pDat_0[1] = accu3; move32(); + pDat_1[0] = accu4; move32(); + + pDat_0 = pDat_0 + 2; + pDat_1 = pDat_1 - 2; + +#ifdef ENABLE_HR_MODE + cplxMpy32_32_32_2(accu1, accu2, pDat_0[1], pDat_0[0], sin_twiddle[idx].v.re, sin_twiddle[idx].v.im); +#else + cplxMpy32_32_16_2(accu1, accu2, pDat_0[1], pDat_0[0], sin_twiddle[idx].v.re, sin_twiddle[idx].v.im); +#endif + + idx += sin_step; + +#ifdef ENABLE_HR_MODE + cplxMpy32_32_32_2(accu3, accu4, pDat_1[0], pDat_1[1], sin_twiddle[idx].v.re, sin_twiddle[idx].v.im); +#else + cplxMpy32_32_16_2(accu3, accu4, pDat_1[0], pDat_1[1], sin_twiddle[idx].v.re, sin_twiddle[idx].v.im); +#endif + + pDat_1[1] = L_negate(accu1); move32(); + pDat_0[0] = accu2; move32(); + } + + pDat_0[1] = accu3; move32(); + pDat_1[0] = accu4; move32(); + + pDat_0 = pDat_0 + 2; + pDat_1 = pDat_1 - 2; + +#ifdef ENABLE_HR_MODE + cplxMpy32_32_32_2(accu3, accu4, pDat_0[1], pDat_0[0], sin_twiddle[idx].v.re, sin_twiddle[idx].v.im); +#else + cplxMpy32_32_16_2(accu3, accu4, pDat_0[1], pDat_0[0], sin_twiddle[idx].v.re, sin_twiddle[idx].v.im); +#endif + +/* Last Sin and Cos value pair are the same */ +#ifdef ENABLE_HR_MODE + accu1 = L_shr_pos(Mpy_32_32_lc3plus(pDat_1[0], TWIDDLE), 1); + accu2 = L_shr_pos(Mpy_32_32_lc3plus(pDat_1[1], TWIDDLE), 1); +#else + accu1 = L_shr_pos(Mpy_32_16_lc3plus(pDat_1[0], TWIDDLE), 1); + accu2 = L_shr_pos(Mpy_32_16_lc3plus(pDat_1[1], TWIDDLE), 1); +#endif + + pDat_1[0] = L_add(accu1, accu2); move32(); + pDat_0[1] = L_sub(accu1, accu2); move32(); + + pDat_1[1] = L_negate(accu3); move32(); + pDat_0[0] = accu4; move32(); + + /* twiddeling scale is 2 */ + *pDat_e = add(*pDat_e, 2); move16(); + +#ifdef DYNMEM_COUNT + Dyn_Mem_Out(); +#endif +} + diff --git a/lib_lc3plus/dec_entropy.c b/lib_lc3plus/dec_entropy.c new file mode 100644 index 0000000000000000000000000000000000000000..572438615fd43ca3d3a9a3ce1c4eb4966cf6acc0 --- /dev/null +++ b/lib_lc3plus/dec_entropy.c @@ -0,0 +1,387 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.5 * +* 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 "functions.h" + +static Word16 read_indice(UWord8 *ptr, Word16 *bp, Word16 *mask, Word16 numbits); + +static Word16 ac_dec_split_st2VQ_CW( /* local BER flag */ + const Word32 L_cwRx, /* max 25 bits */ + const Word32 L_szA, const Word32 L_szB, Word32 *L_cwA, Word32 *L_cwB, + Word16 *submodeLSB); + +void processDecoderEntropy_fx(UWord8 *bytes, Word16 *bp_side, Word16 *mask_side, Word16 nbbits, + Word16 L_spec, Word16 fs_idx, Word16 BW_cutoff_bits, Word16 *tns_numfilters, + Word16 *lsbMode, Word16 *lastnz, Word16 *bfi, Word16 *tns_order, Word16 *fac_ns_idx, + Word16 *gg_idx, Word16 *BW_cutoff_idx, Word16 *ltpf_idx, Word32 *L_scf_idx, + Word16 frame_dms) +{ + Dyn_Mem_Deluxe_In( + Word16 L, submodeLSB; + Word32 tmp32, tmp32lim; + Word16 gain_e, gain, submodeMSB, BER_detect; + Word32 n; + UWord8 *ptr; + ); + + ptr = bytes; + *bp_side = shr_pos(sub(nbbits, 1), 3); + *mask_side = shl(1, sub(8, sub(nbbits, shl_pos(*bp_side, 3)))); + + /* Cutoff-detection */ + IF (BW_cutoff_bits > 0) + { + *BW_cutoff_idx = read_indice(ptr, bp_side, mask_side, BW_cutoff_bits); + /* check for bitflips */ + IF (sub(fs_idx, *BW_cutoff_idx) < 0) + { + *BW_cutoff_idx = fs_idx; + *bfi = 1; move16(); + Dyn_Mem_Deluxe_Out(); + return; + } + } + ELSE + { + *BW_cutoff_idx = fs_idx; + } + + /* Number of TNS filters */ + IF (sub(*BW_cutoff_idx, 3) >= 0 && frame_dms >= 50) + { + *tns_numfilters = 2; move16(); + } + ELSE + { + *tns_numfilters = 1; move16(); + } + + /* Decode number of ntuples */ + L = sub(14, norm_s(negate(L_spec))); + n = read_indice(ptr, bp_side, mask_side, L); + n = add(n, 1); + *lastnz = shl_pos(n, 1); + IF (sub(*lastnz, L_spec) > 0) + { + *bfi = 1; move16(); + Dyn_Mem_Deluxe_Out(); + return; + } + + /* Mode bit */ + *lsbMode = read_bit(ptr, bp_side, mask_side); + + /* Decode global-gain */ + *gg_idx = read_indice(ptr, bp_side, mask_side, 8); move16(); + tmp32 = L_shl_pos(L_mult0(*gg_idx, 0x797D), 7); /* 6Q25; 0x797D -> log2(10)/28 (Q18) */ + gain_e = add(extract_l(L_shr_pos(tmp32, 25)), 1); /* get exponent */ + gain = round_fx(BASOP_Util_InvLog2_lc3plus(L_or(tmp32, 0xFE000000))); + assert(gain >= 0); /* JSv, check if shr_pos(gain,1) is more appropriate) */ + gain = shr_r(gain, 1); + gain_e = add(gain_e, 1); + + /* Decode TNS on/off flag */ + tns_order[1] = 0; move16(); /* fix problem with uninitialized memory */ + FOR (n = 0; n < *tns_numfilters; n++) + { + tns_order[n] = read_bit(ptr, bp_side, mask_side); move16(); + } + + /* LTPF on/off */ +#ifdef ENABLE_HR_MODE + ltpf_idx[0] = read_bit(ptr, bp_side, mask_side); move16(); +#else + ltpf_idx[0] = read_indice(ptr, bp_side, mask_side, 1); move16(); +#endif + + /* Decode SNS VQ parameters - 1st stage (10 bits) */ +#ifdef ENABLE_HR_MODE + L = read_indice(ptr, bp_side, mask_side, 5 + 5); + L_scf_idx[0] = L_deposit_l(s_and(L, 0x1F)); /* stage1 LF 5 bits */ + L_scf_idx[1] = L_deposit_l(shr_pos(L, 5)); /* stage1 HF 5 bits */ +#else + L_scf_idx[0] = L_deposit_l(read_indice(ptr, bp_side, mask_side, 5)); /* stage1 LF 5 bits */ + L_scf_idx[1] = L_deposit_l(read_indice(ptr, bp_side, mask_side, 5)); /* stage1 HF 5 bits */ +#endif + + /* Decode SNS VQ parameters - 2nd stage side-info (3-4 bits) */ + submodeMSB = read_bit(ptr, bp_side, mask_side); /* submodeMSB 1 bit */ + L_scf_idx[2] = L_deposit_l(shl_pos(submodeMSB, 1)); + ASSERT(sns_gainMSBbits[L_scf_idx[2]] > 0); + L_scf_idx[3] = L_deposit_l( + read_indice(ptr, bp_side, mask_side, sns_gainMSBbits[L_scf_idx[2]])); /* gains or gain MSBs 1-2 bits */ + L_scf_idx[4] = read_bit(ptr, bp_side, mask_side); /* shape LS 1 bit */ + + /* Decode SNS VQ parameters - 2nd stage data (24-25 bits) */ + IF (submodeMSB == 0) + { /* shape_j = 0, or 1 */ + /* regular mode A,B indexes integer multiplexed, total 24.x bits MPVQ codeword section A and codeword for + * section B */ + /* regular mode mode shape index total 24.9999 bits MPVQ codeword */ + tmp32 = L_deposit_l(read_indice(ptr, bp_side, mask_side, 13)); + tmp32 = L_or(tmp32, L_shl_pos(read_indice(ptr, bp_side, mask_side, 12), 13)); move16(); /*for ber state */ + BER_detect = + ac_dec_split_st2VQ_CW( /* local BER flag */ + tmp32, /* L_cwRx max 25 bits */ + sns_MPVQ_Sz[0][0], UL_addNsD(sns_MPVQ_Sz[0][1], sns_MPVQ_Sz[1][1]), /* 12+2 = 14 */ + (&L_scf_idx[5]), /* shape A */ + (&L_scf_idx[6]), /* shape B or gain LSB */ + &submodeLSB /* total submode update below */ + ); + IF (submodeLSB != 0) + { /* add gainLSB bit */ + L_scf_idx[3] = L_add(L_shl_pos(L_scf_idx[3], 1), L_scf_idx[6]); + L_scf_idx[6] = -2L; + } + } + ELSE + { /* shape_j = 2 or 3 */ + ASSERT(submodeMSB == 1); + /* outlier mode shape index total 23.8536 + 19.5637 (19.5637 < (log2(2.^24 -2.^23.8537)) bits MPVQ + * codeword */ + tmp32 = L_deposit_l(read_indice(ptr, bp_side, mask_side, 12)); + tmp32 = L_or(tmp32, L_shl_pos(read_indice(ptr, bp_side, mask_side, 12), 12)); + L_scf_idx[5] = tmp32; move32(); /*shape outl_near or outl_far */ + submodeLSB = 0; move16(); + BER_detect = 0; move16(); + tmp32lim = L_add(sns_MPVQ_Sz[2][0], L_shl_pos(sns_MPVQ_Sz[3][0], 1)); + IF (L_sub(tmp32, tmp32lim) >= 0) + { + BER_detect = 1; move16(); + } + ELSE + { + tmp32 = L_sub(tmp32, sns_MPVQ_Sz[2][0]); /* a potential high index is computed */ + IF (tmp32 >= 0) + { + submodeLSB = 1; move16(); + ASSERT(tmp32 >= 0 && tmp32 < (Word32)(2 * sns_MPVQ_Sz[3][0])); + L_scf_idx[3] = L_add(L_shl_pos(L_scf_idx[3], 1), L_and(tmp32, 0x1)); /* add LSB_gain bit to gain MSBs */ + L_scf_idx[5] = L_shr_pos(tmp32, 1); /* MPVQ index with offset and gainLSB removed */ + L_scf_idx[6] = -2L; move32(); + } + ELSE + { + L_scf_idx[6] = -1L; move32(); + } + } + } + L_scf_idx[2] = + L_add(L_scf_idx[2], L_deposit_l(submodeLSB)); /* decoder internal signal shape_j = submode 0..3 to VQ */ + + IF (BER_detect > 0) + { + *bfi = 1; move16(); + Dyn_Mem_Deluxe_Out(); + return; + } + + /* LTPF data */ + IF (ltpf_idx[0] != 0) + { +#ifdef ENABLE_HR_MODE + L = read_indice(ptr, bp_side, mask_side, 1+9); move16(); + ltpf_idx[1] = s_and(L, 1); move16(); + ltpf_idx[2] = shr_pos(L, 1); move16(); +#else + ltpf_idx[1] = read_indice(ptr, bp_side, mask_side, 1); move16(); + ltpf_idx[2] = read_indice(ptr, bp_side, mask_side, 9); move16(); + +#endif + } + ELSE + { + ltpf_idx[1] = 0; move16(); + ltpf_idx[2] = 0; move16(); + } + + /* Decode noise-fac */ + *fac_ns_idx = read_indice(ptr, bp_side, mask_side, 3); move16(); + + Dyn_Mem_Deluxe_Out(); +} + +#ifdef ENABLE_PADDING +int paddingDec_fx(UWord8 *bytes, Word16 nbbits, Word16 L_spec, Word16 BW_cutoff_bits, Word16 ep_enabled, + Word16 *total_padding, Word16 *np_zero) +{ + Word16 lastnz_threshold; + Word16 padding_len_bits, padding_len; + + Word16 bp_side; + Word16 nbbytes = shr(nbbits,3); + + Word16 mask_side; + UWord8 *ptr = bytes; + + Word16 lastnz; + Word16 nbits = sub(14, norm_s(negate(L_spec))); + if (sub(nbbits, nbits) < 0) + { + return 1; + } + *np_zero = 0; + + *total_padding = 0; + + bp_side = shr_pos(sub(nbbits, 1), 3); + mask_side = shl(1, sub(8, sub(nbbits, shl_pos(bp_side, 3)))); + + test(); + IF (sub(bp_side, 19) < 0 || sub(bp_side, LC3PLUS_MAX_BYTES ) >= 0) { + return 1; + } + + ptr = bytes; + + IF (BW_cutoff_bits > 0) + { + read_indice(ptr, &bp_side, &mask_side, BW_cutoff_bits); + move16(); + } + + lastnz = read_indice(ptr, &bp_side, &mask_side, nbits); + move16(); + + lastnz_threshold = sub(shl(1, nbits), 2); + + WHILE (lastnz == lastnz_threshold) + { + padding_len_bits = sub(sub(12, nbits), BW_cutoff_bits); + + /*Read padding length*/ + padding_len = read_indice(ptr, &bp_side, &mask_side, padding_len_bits); + move16(); + + /* Read 4 reserved bits */ + read_indice(ptr, &bp_side, &mask_side, 4); + move16(); + + IF (ep_enabled == 0) + { + /* Discard padding length bytes */ + bp_side = sub(bp_side, padding_len); + *total_padding = add(add(*total_padding, padding_len), 2); move16(); + } + ELSE + { + *total_padding = add(*total_padding, 2); move16(); + *np_zero = add(*np_zero, padding_len); move16(); + } + + /* test if we have less than 20 bytes left; if so frame is broken */ + IF (sub(sub(nbbytes,add(*total_padding,*np_zero)),20) < 0) { + return 1; + } + + /* Read bandwidth bits */ + IF (BW_cutoff_bits > 0) + { + read_indice(ptr, &bp_side, &mask_side, BW_cutoff_bits); + move16(); + } + + lastnz = read_indice(ptr, &bp_side, &mask_side, nbits); + move16(); + } + + IF (ep_enabled != 0) + { + *total_padding = add(*total_padding, *np_zero); move16(); + } + return 0; +} +#endif + +static __forceinline Word16 read_indice(UWord8 *ptr, Word16 *bp, Word16 *mask, Word16 numbits) +{ + Dyn_Mem_Deluxe_In( + Word16 indice, bit; + Counter i; + ); + + indice = read_bit(ptr, bp, mask); + + FOR (i = 1; i < numbits; i++) + { + bit = read_bit(ptr, bp, mask); + indice = add(indice, lshl_pos(bit, i)); + } + + Dyn_Mem_Deluxe_Out(); + return indice; +} + +static __forceinline Word16 ac_dec_split_st2VQ_CW( /* local BER flag */ + const Word32 L_cwRx, /* max 25 bits */ + const Word32 L_szA, const Word32 L_szB, Word32 *L_cwA, Word32 *L_cwB, + Word16 *submodeLSB) +{ + /* demultiplex: L_cwRx = L_cwB(21.z bits) * L_szA(3.y bits) + L_cwA(21.x bits)); */ + Word16 start, fin, ind; + Word32 L_tmp, L_max_size; + Counter i; + + L_max_size = (Word32)UL_Mpy_32_32((UWord32)L_szB, (UWord32)L_szA); /* may be tabled */ + + /* section B ind larger than 13 out of the possible 14 = 0..13 */ + IF (L_sub(L_cwRx, L_max_size) >= 0) + { + *L_cwA = L_deposit_l(0); + *L_cwB = L_deposit_l(0); + *submodeLSB = 0; move16(); + return (Word16)1; /* set berFlag and exit */ + } + + /*initial binary split of cw, select top or low half */ + start = 0; move16(); + + ASSERT((L_szB & 0x1L) == 0); /* this middle split only works if L_szB is even */ + if (L_sub(L_cwRx, L_shr_pos(L_max_size, 1)) >= 0) + { + start = L_shr_pos(L_szB, 1); /* top half start index */ + } + + /*linear loop over a low or a high section */ + ind = start; move16(); + L_tmp = L_negate(L_cwRx); /* search from negative side */ + + L_tmp = L_add(L_tmp, (Word32)UL_Mpy_32_32(UL_deposit_l((UWord16)start), (UWord32)L_szA)); + /* start is 0 or 7 */ /*non-fractional mult is (int)start * L_szA */ + + /* a short linear run over ceil(szB/2) = 7 values */ + + fin = add(start, shr_pos(L_szB, 1)); + FOR (i = start; i < fin; i++) + { + ind = add(ind, 1); + L_tmp = L_add(L_tmp, L_szA); + if (L_tmp > 0) + { + ind = sub(ind, 1); /* passed criteria point, keep index */ + } + } + + *L_cwB = L_deposit_l(ind); + *L_cwA = L_sub(L_cwRx, (Word32)UL_Mpy_32_32(UL_deposit_l((UWord16)ind), + (UWord32)L_szA)); /* non-fractional mult; (int)ind * L_szA */ + + ASSERT(*L_cwA >= 0 && *L_cwA < L_szA); + ASSERT(*L_cwB >= 0 && *L_cwB < L_szB); + + *submodeLSB = 0; + *L_cwB = L_sub(*L_cwB, 2); + if (*L_cwB < 0) + { + *submodeLSB = 1; move16(); + } + *L_cwB = L_mac0(*L_cwB, 2, *submodeLSB); /* add back gain ind if needed */ + + return 0; /* no BER */ +} diff --git a/lib_lc3plus/dec_lc3.c b/lib_lc3plus/dec_lc3.c new file mode 100644 index 0000000000000000000000000000000000000000..1b23927c6d3fa5419b1f1e8d9814cb9a936cdf4a --- /dev/null +++ b/lib_lc3plus/dec_lc3.c @@ -0,0 +1,788 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.5 * +* 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 "functions.h" + +static int Dec_LC3PLUS_Channel(LC3PLUS_Dec *decoder, int channel, int bits_per_sample, UWord8 *bs_in, void *s_out, Word16 bfi, + Word8 *scratchBuffer) +{ + Word16 scale; + Word32 offset; + Word16 fill_bits; + Word16 nf_seed, gg_idx, fac_ns_idx, q_fx_exp = 0; + Word16 bp_side, mask_side; + Word16 tns_numfilters, lsbMode, lastnz, BW_cutoff_idx, BW_cutoff_idx_nf; + Word16 zero_frame = 0; +#ifdef ENABLE_RFRAME + Word16 rframe = 0; +#endif + Word16 ltpf_idx[3]; + Word16 spec_inv_idx = 0; + Counter i; + + /* Buffers */ + Word16 *int_scf_fx_exp, tns_order[TNS_NUMFILTERS_MAX]; + UWord8 *resBitBuf; +#ifdef ENABLE_HR_MODE + Word32 *sqQdec; +#else + Word16 * sqQdec; + Word16 * int_scf_fx; +#endif + Word16 * x_fx, *indexes; + Word16 scf_q[M]; + Word32 * L_scf_idx; + Word32 * q_d_fx; + Word8 * currentScratch; + DecSetup *h_DecSetup = decoder->channel_setup[channel]; +#ifdef ENABLE_HR_MODE + Word32 *x_fx_ip; + Word32 *int_scf_fx_ip; + Word32 scf_q_ip[M]; +#endif + +#ifdef DYNMEM_COUNT + struct _dynmem + { + Counter i; + Word16 scale; + Word32 offset; + Word16 fill_bits; + Word16 nf_seed, gg_idx, fac_ns_idx, q_fx_exp; + Word16 bp_side, mask_side; + Word16 tns_numfilters, lsbMode, lastnz, BW_cutoff_idx, BW_cutoff_idx_nf; + Word16 zero_frame; + Word16 ltpf_idx[3]; +#ifdef ENABLE_RFRAME + Word16 rframe; +#endif + Word16 spec_inv_idx; + + /* Buffers */ + Word16 *int_scf_fx_exp, tns_order[TNS_NUMFILTERS_MAX]; + UWord8 *resBitBuf; +#ifdef ENABLE_HR_MODE + Word32 *sqQdec; +#else + Word16 *sqQdec; +#endif + Word16 *int_scf_fx, *x_fx, *indexes; + Word32 *L_scf_idx; + Word32 *q_d_fx; + Word8 * currentScratch; + Word16 scf_q[M]; +#ifdef ENABLE_HR_MODE + Word32 scf_q_ip[M]; +#endif + }; + Dyn_Mem_In("Dec_LC3_Channel", sizeof(struct _dynmem)); +#endif + +#ifdef DISABLE_PLC + UNUSED(decoder->plcMeth); +#endif + + + /* BUFFER INITIALISATION. Some buffers may overlap since they are not used in the whole decoding process */ + q_d_fx = scratchAlign(scratchBuffer, 0); /* Size = 4 * MAX_LEN bytes */ +#ifdef ENABLE_HR_MODE + /* allocate memory for residual bits */ + if (decoder->hrmode) + { + resBitBuf = scratchAlign(q_d_fx, sizeof(*q_d_fx) * + decoder->frame_length); + basop_memset(resBitBuf, 0, sizeof(*resBitBuf) * MAX_RESBITS_LEN); + } + else +#endif + { + resBitBuf = scratchAlign(q_d_fx, sizeof(*q_d_fx) * + decoder->frame_length); /* Size = 2 * NPRM_RESQ = 2 * MAX_LEN bytes for + normal case and 2*MAX_RESBITS_LEN for hrmode */ + basop_memset(resBitBuf, 0, sizeof(*resBitBuf) * 2 * decoder->frame_length); + } + +#ifdef ENABLE_HR_MODE + indexes = scratchAlign(resBitBuf, sizeof(*resBitBuf) * MAX_RESBITS_LEN); +#else + indexes = scratchAlign(resBitBuf, sizeof(*resBitBuf) * 2 * decoder->frame_length); +#endif + memset(indexes, 0, sizeof(*indexes) * TNS_NUMFILTERS_MAX * MAXLAG); + + /* indexes Size = 2 * TNS_NUMFILTERS_MAX * MAXLAG = 32 bytes */ + + L_scf_idx = scratchAlign(indexes, sizeof(*indexes) * TNS_NUMFILTERS_MAX * + MAXLAG); /* Size = 4 * SCF_MAX_PARAM = 28 bytes -> aligned to 32 bytes */ + sqQdec = scratchAlign(L_scf_idx, sizeof(*L_scf_idx) * (SCF_MAX_PARAM)); /* Size = 2 * MAX_LEN bytes */ + int_scf_fx_exp = scratchAlign(sqQdec, sizeof(*sqQdec) * decoder->frame_length); /* Size = 2 * MAX_BANDS_NUMBER = 128 bytes */ +#ifndef ENABLE_HR_MODE + int_scf_fx = scratchAlign(int_scf_fx_exp, + sizeof(*int_scf_fx_exp) * MAX_BANDS_NUMBER); /* Size = 2 * MAX_BANDS_NUMBER = 128 bytes */ +#endif +#ifdef ENABLE_HR_MODE + x_fx = + scratchAlign(int_scf_fx_exp, sizeof(*int_scf_fx_exp) * MAX_BANDS_NUMBER); /* Size = 2 * (MAX_LEN + MDCT_MEM_LEN_MAX) = 2 + * MAX_LEN + 1.25 * MAX_LEN = 3.25 * MAX_LEN */ +#else + x_fx = + scratchAlign(q_d_fx, sizeof(*q_d_fx) * decoder->frame_length); /* Size = 2 * (MAX_LEN + MDCT_MEM_LEN_MAX) = 2 + * MAX_LEN + 1.25 * MAX_LEN = 3.25 * MAX_LEN */ +#endif + +#ifdef ENABLE_HR_MODE + x_fx_ip = scratchAlign(x_fx, sizeof(*x_fx) * (decoder->frame_length + decoder->stDec_ola_mem_fx_len)); + int_scf_fx_ip = scratchAlign(x_fx_ip, sizeof(*x_fx_ip) * (decoder->frame_length + decoder->stDec_ola_mem_fx_len)); + + currentScratch = scratchAlign(int_scf_fx_ip, sizeof(*int_scf_fx_ip) * 2 * MAX_BANDS_NUMBER); /* Size = 4 * MAX_LEN */ +#else + currentScratch = scratchAlign(x_fx, sizeof(*x_fx) * 4 * MAX_LEN); /* Size = 4 * MAX_LEN */ +#endif + +#ifdef DISABLE_PLC + memset(q_d_fx, 0, decoder->frame_length * sizeof(*q_d_fx)); +#endif + +#ifdef WMOPS + push_wmops("Decoder"); +#endif + +#ifdef ENABLE_RFRAME + IF (sub(bfi, 3) == 0) + { + bfi = 2; + move16(); + rframe = 1; + move16(); + } +#endif + + if (bfi != 1) + { +#ifdef WMOPS + push_wmops("Dec(bfi=0)"); +#endif + } + else + { +#ifdef WMOPS + push_wmops("Dec(bfi=1)"); +#endif + } + +#ifdef WMOPS + push_wmops("Entropy dec"); +#endif + IF (sub(bfi, 1) != 0) + { + processDecoderEntropy_fx(bs_in, &bp_side, &mask_side, h_DecSetup->total_bits, decoder->yLen, decoder->fs_idx, + decoder->BW_cutoff_bits, &tns_numfilters, &lsbMode, &lastnz, &bfi, tns_order, + &fac_ns_idx, &gg_idx, &BW_cutoff_idx, ltpf_idx, L_scf_idx, decoder->frame_dms); + BW_cutoff_idx_nf = BW_cutoff_idx; + move16(); + } +#ifdef WMOPS + pop_wmops(); /* Entropy dec */ +#endif + +#ifdef WMOPS + push_wmops("Ari dec"); +#endif + IF (sub(bfi, 1) != 0) + { + processAriDecoder_fx(bs_in, &bp_side, &mask_side, h_DecSetup->total_bits, decoder->yLen, decoder->fs_idx, + h_DecSetup->enable_lpc_weighting, tns_numfilters, lsbMode, lastnz, &bfi, tns_order, + fac_ns_idx, gg_idx, decoder->frame_dms, + decoder->n_pc, decoder->be_bp_left, decoder->be_bp_right, 0, &spec_inv_idx, &scale, + &fill_bits, sqQdec, &nf_seed, resBitBuf, indexes, &zero_frame, currentScratch +#ifdef ENABLE_HR_MODE + , decoder->hrmode +#endif + ); + +#ifdef ENABLE_RFRAME + test();test(); + IF (sub(rframe, 1) == 0 && zero_frame == 0 && sub(bfi, 1) != 0) + { + bfi = 2; + move16(); + Word16 max_bw_stopband = BW_cutoff_bin_all[BW_cutoff_idx]; + SWITCH (decoder->frame_dms) + { +#ifdef ENABLE_025_DMS_MODE + case 25: + max_bw_stopband = shr_pos(max_bw_stopband, 2); + BREAK; +#endif +#ifdef ENABLE_050_DMS_MODE + case 50: + max_bw_stopband = shr_pos(max_bw_stopband, 1); + BREAK; +#endif +#ifdef CR8_G_ADD_75MS + case 75: + max_bw_stopband = add(shr_pos(max_bw_stopband, 2), add(shr_pos(max_bw_stopband, 2), shr_pos(max_bw_stopband, 2))); + BREAK; +#endif + case 100: + BREAK; + } + + spec_inv_idx = s_max(lastnz, max_bw_stopband); + move16(); + } +#endif + + IF (bfi == 0) + { + processAriDecoderScaling_fx(sqQdec, decoder->yLen, q_d_fx, &q_fx_exp); + } + } +#ifdef WMOPS + pop_wmops(); /* Ari dec */ +#endif + +#ifdef WMOPS + push_wmops("SnsQuantScfDec"); +#endif + IF (sub(bfi, 1) != 0) + { + /* currentScratch Size = 96 bytes */ +#ifdef ENABLE_HR_MODE + processSnsQuantizeScfDecoder_fx(L_scf_idx, scf_q_ip, currentScratch); + downshift_w32_arr(scf_q_ip, scf_q, 15, M); /* required for PLC */ +#else + processSnsQuantizeScfDecoder_fx(L_scf_idx, scf_q, currentScratch); +#endif + } +#ifdef WMOPS + pop_wmops(); +#endif + +#ifdef WMOPS + push_wmops("PLC::ComputeStabFac"); +#endif + if (h_DecSetup->plcAd) + { + processPLCcomputeStabFac_main(scf_q, h_DecSetup->plcAd->old_scf_q, h_DecSetup->plcAd->old_old_scf_q, bfi, + h_DecSetup->prev_bfi, h_DecSetup->prev_prev_bfi, &h_DecSetup->plcAd->stab_fac); + } +#ifdef WMOPS + pop_wmops(); +#endif + +#ifdef WMOPS + push_wmops("Partial Concealment"); +#endif + IF (sub(bfi, 1) != 0) + { + scale = 32767; + move16(); + + IF (h_DecSetup->plcAd) + { + scale = h_DecSetup->plcAd->stab_fac; + } + + processPCmain_fx(rframe, &bfi, decoder->yLen, decoder->frame_dms, h_DecSetup->q_old_res_fx, + &h_DecSetup->q_old_res_fx_exp, sqQdec, h_DecSetup->q_old_d_fx, spec_inv_idx, ltpf_idx[0], + scale, q_d_fx, &q_fx_exp, gg_idx, h_DecSetup->quantizedGainOff, &h_DecSetup->prev_gg, + &h_DecSetup->prev_gg_e, &BW_cutoff_idx_nf, &h_DecSetup->prev_BW_cutoff_idx_nf, fac_ns_idx, + &h_DecSetup->prev_fac_ns_fx, &h_DecSetup->pc_nbLostFramesInRow); + } +#ifdef WMOPS + pop_wmops(); +#endif + + IF (sub(bfi, 1) != 0) + { +#ifdef WMOPS + push_wmops("Residual dec"); +#endif + processResidualDecoding_fx(q_d_fx, q_fx_exp, decoder->yLen, resBitBuf, fill_bits +#ifdef ENABLE_HR_MODE + , decoder->hrmode +#endif + ); +#ifdef WMOPS + pop_wmops(); +#endif + +#ifdef WMOPS + push_wmops("Noisefill"); +#endif + /* currentScratch Size = 2 * MAX_LEN bytes */ + IF (zero_frame == 0) + { + processNoiseFilling_fx(q_d_fx, nf_seed, q_fx_exp, fac_ns_idx, BW_cutoff_idx_nf, decoder->frame_dms, + h_DecSetup->prev_fac_ns_fx, spec_inv_idx, currentScratch +#ifdef ENABLE_HR_MODE + , decoder->hrmode +#endif + ); + } +#ifdef WMOPS + pop_wmops(); +#endif + +#ifdef WMOPS + push_wmops("applyGlobalGain"); +#endif + processApplyGlobalGain_fx(q_d_fx, &q_fx_exp, decoder->yLen, gg_idx, h_DecSetup->quantizedGainOff); +#ifdef WMOPS + pop_wmops(); +#endif + +#ifdef WMOPS + push_wmops("Tns_dec"); +#endif + /* currentScratch Size = 48 bytes */ + processTnsDecoder_fx(indexes, q_d_fx, decoder->yLen, tns_order, &q_fx_exp, BW_cutoff_idx, decoder->frame_dms, + currentScratch +#ifdef ENABLE_HR_MODE + , decoder->hrmode +#endif + ); +#ifdef WMOPS + pop_wmops(); +#endif + +#ifdef ENABLE_HR_MODE +#ifdef WMOPS + push_wmops("SnsInterpScfDec"); +#endif + processSnsInterpolateScf_fx(scf_q_ip, int_scf_fx_ip, int_scf_fx_exp, 0, decoder->bands_number, currentScratch); + +#ifdef WMOPS + pop_wmops(); +#endif + +#ifdef WMOPS + push_wmops("Mdct shaping_dec"); +#endif + processScfScaling(int_scf_fx_exp, decoder->bands_number, &q_fx_exp); + + processMdctShaping_fx(q_d_fx, int_scf_fx_ip, int_scf_fx_exp, decoder->bands_offset, decoder->bands_number); +#ifdef WMOPS + pop_wmops(); +#endif +#else +#ifdef WMOPS + push_wmops("SnsInterpScfDec"); +#endif + /* currentScratch Size = 128 bytes */ + processSnsInterpolateScf_fx(scf_q, int_scf_fx, int_scf_fx_exp, 0, decoder->bands_number, currentScratch); +#ifdef WMOPS + pop_wmops(); +#endif + +#ifdef WMOPS + push_wmops("Mdct shaping_dec"); +#endif + processScfScaling(int_scf_fx_exp, decoder->bands_number, &q_fx_exp); + processMdctShaping_fx(q_d_fx, int_scf_fx, int_scf_fx_exp, decoder->bands_offset, decoder->bands_number); +#ifdef WMOPS + pop_wmops(); +#endif + /* end int_scf_fx */ +#endif /* ENABLE_HR_MODE */ + } + + /* x_fx_ip will be used to store h_DecSetup->stDec_ola_mem_fx returned by PLCmain_fx*/ + /* This will be upshifted to 32 bit overlap buffer outside of the PLCmain function */ +#ifdef ENABLE_HR_MODE + Word16 *plc_ola_mem = (Word16 *)x_fx_ip; + IF(sub(bfi, 1) == 0) + { + FOR(i = 0; i < decoder->stDec_ola_mem_fx_len; i++) + { + plc_ola_mem[i] = round_fx(h_DecSetup->stDec_ola_mem_fx[i]); + } + } +#endif + +#ifdef WMOPS + push_wmops("PLC::Main"); +#endif + /* currentScratch Size = 2 * MAX_LGW + 8 * MAX_LPROT + 12 * MAX_L_FRAME */ + processPLCmain_fx(decoder->plcMeth, &h_DecSetup->concealMethod, &h_DecSetup->nbLostFramesInRow, bfi, + h_DecSetup->prev_bfi, decoder->frame_length, decoder->la_zeroes, decoder->W_fx, x_fx, +#ifdef ENABLE_HR_MODE + plc_ola_mem, +#else + h_DecSetup->stDec_ola_mem_fx, +#endif + &h_DecSetup->stDec_ola_mem_fx_exp, h_DecSetup->q_old_d_fx, + &h_DecSetup->q_old_fx_exp, q_d_fx, &q_fx_exp, decoder->yLen, decoder->fs_idx, + decoder->bands_offset, decoder->bands_number, &h_DecSetup->plc_damping, h_DecSetup->ltpf_mem_pitch_int, + h_DecSetup->ltpf_mem_pitch_fr, &h_DecSetup->ns_cum_alpha, &h_DecSetup->ns_seed, h_DecSetup->plcAd, + decoder->frame_dms, currentScratch, &h_DecSetup->pc_nbLostFramesInRow +#ifdef ENABLE_HR_MODE + , decoder->hrmode +#endif +#ifdef CR9_N_SHORT_FADE_FOR_UNSTABLE_PITCH + , h_DecSetup->rel_pitch_change +#endif +#ifdef CR10_A_ATTENUATION_CURVE_SELECTOR + , decoder->alpha_type_2_table +#endif + ); +#ifdef WMOPS + pop_wmops(); +#endif + +#ifdef ENABLE_HR_MODE + IF(sub(bfi, 1) == 0) + { + FOR(i = 0; i < decoder->stDec_ola_mem_fx_len; i++) + { + h_DecSetup->stDec_ola_mem_fx[i] = L_deposit_h(plc_ola_mem[i]); + } + } +#endif + +#ifdef WMOPS + push_wmops("PLC/PC::DampingScrambling"); +#endif + if (h_DecSetup->plcAd) + { + processPLCDampingScrambling_main_fx( + bfi, h_DecSetup->concealMethod, h_DecSetup->nbLostFramesInRow, &h_DecSetup->plcAd->cum_fflcAtten, + h_DecSetup->pc_nbLostFramesInRow, &h_DecSetup->ns_seed, &h_DecSetup->pc_seed, + h_DecSetup->ltpf_mem_pitch_int, ltpf_idx[0], q_d_fx, &q_fx_exp, h_DecSetup->q_old_d_fx, + &h_DecSetup->q_old_fx_exp, decoder->yLen, h_DecSetup->plcAd->stab_fac, decoder->frame_dms, + &h_DecSetup->plcAd->cum_fading_slow, &h_DecSetup->plcAd->cum_fading_fast, spec_inv_idx +#ifdef CR8_A_PLC_FADEOUT_TUNING + , h_DecSetup->plcAd->plc_fadeout_type +#endif + ); + } +#ifdef WMOPS + pop_wmops(); +#endif + +#ifdef WMOPS + push_wmops("Imdct"); +#endif + /* currentScratch Size = 4 * MAX_LEN */ + ProcessingIMDCT(q_d_fx, &q_fx_exp, decoder->W_fx, h_DecSetup->stDec_ola_mem_fx, &h_DecSetup->stDec_ola_mem_fx_exp, +#ifdef ENABLE_HR_MODE + x_fx_ip, +#else + x_fx, +#endif + decoder->W_size, decoder->frame_length, decoder->stDec_ola_mem_fx_len, decoder->frame_dms, + h_DecSetup->concealMethod, bfi, h_DecSetup->prev_bfi, h_DecSetup->nbLostFramesInRow, + h_DecSetup->plcAd, + currentScratch +#ifdef ENABLE_HR_MODE + , decoder->hrmode +#endif + ); + +#ifdef ENABLE_HR_MODE + IF(sub(bfi, 1) != 0 || sub(h_DecSetup->concealMethod, LC3_CON_TEC_NS_STD) == 0 || sub(h_DecSetup->concealMethod, LC3_CON_TEC_NS_ADV) == 0 || sub(h_DecSetup->concealMethod, LC3_CON_TEC_FREQ_MUTING) == 0) + { + round_w32tow16_arr(x_fx_ip, x_fx, decoder->frame_length); + } + ELSE + { + FOR(i = 0; i < decoder->frame_length; i++) + { + x_fx_ip[i] = L_deposit_h(x_fx[i]); + } + } +#endif /* ENABLE_HR_MODE */ + +#ifdef WMOPS + pop_wmops(); +#endif + +#ifdef WMOPS + push_wmops("PLC::Update"); +#endif + + processPLCupdate_fx(h_DecSetup->plcAd, x_fx, q_fx_exp, h_DecSetup->concealMethod, decoder->frame_length, + decoder->fs_idx, &h_DecSetup->nbLostFramesInRow, &h_DecSetup->prev_prev_bfi, + &h_DecSetup->prev_bfi, bfi, scf_q, &h_DecSetup->ns_cum_alpha +#ifdef ENABLE_HR_MODE + , decoder->hrmode +#endif + ); +#ifdef WMOPS + pop_wmops(); +#endif + +#ifdef WMOPS + push_wmops("LtpfDec"); +#endif + /* currentScratch Size = 0.5 * MAX_LEN + 20 bytes */ + process_ltpf_decoder_fx(&q_fx_exp, decoder->frame_length, decoder->ltpf_mem_x_len, decoder->fs_idx, + decoder->ltpf_mem_y_len, &h_DecSetup->ltpf_mem_e, x_fx, h_DecSetup->ltpf_mem_x, x_fx, + h_DecSetup->ltpf_mem_y, ltpf_idx[0], ltpf_idx[1], ltpf_idx[2], + &h_DecSetup->ltpf_mem_pitch_int, &h_DecSetup->ltpf_mem_pitch_fr, &h_DecSetup->ltpf_mem_gain, + &h_DecSetup->ltpf_mem_active, h_DecSetup->ltpf_scale_fac_idx, bfi, + h_DecSetup->concealMethod, + h_DecSetup->plc_damping, &h_DecSetup->ltpf_mem_scale_fac_idx, +#ifdef CR9_N_SHORT_FADE_FOR_UNSTABLE_PITCH + &h_DecSetup->rel_pitch_change, decoder->hrmode, decoder->frame_dms, +#endif + currentScratch); +#ifdef WMOPS + pop_wmops(); +#endif + +#ifdef ENABLE_HR_MODE + IF (!(decoder->hrmode)) + { + FOR (i = 0; i < decoder->frame_length; i++) + { + x_fx_ip[i] = L_deposit_h(x_fx[i]); + } + } +#endif + +#ifdef WMOPS + push_wmops("Output scaling"); +#endif + { + scale = sub(sub(31 + 16, bits_per_sample), q_fx_exp); + offset = L_shr_sat(32768, sub(16, scale)); + IF (bits_per_sample == 16) + { + scale = sub(15, q_fx_exp); + FOR (i = 0; i < decoder->frame_length; i++) + { +#ifdef ENABLE_HR_MODE + ((Word16 *)s_out)[i] = round_fx_sat(L_shr_sat(x_fx_ip[i], scale)); +#else + ((Word16 *)s_out)[i] = round_fx_sat(L_shr_sat(L_deposit_h(x_fx[i]), scale)); +#endif + move16(); + } + } + ELSE + { + FOR (i = 0; i < decoder->frame_length; i++) + { +#ifdef ENABLE_HR_MODE + ((Word32 *)s_out)[i] = L_shr_sat(L_add_sat(x_fx_ip[i], offset), scale); +#else + ((Word32 *)s_out)[i] = L_shr_sat(L_add_sat(L_deposit_h(x_fx[i]), offset), scale); +#endif + move32(); + } + } + } +#ifdef WMOPS + pop_wmops(); /* Output scaling */ +#endif + +#ifdef WMOPS + pop_wmops(); +#endif + +#ifdef WMOPS + pop_wmops(); /* Decoder */ +#endif + + +#ifdef DYNMEM_COUNT + Dyn_Mem_Out(); +#endif + return bfi; +} + +/* num_bytes = 0 -> bad frame */ +LC3PLUS_Error Dec_LC3PLUS(LC3PLUS_Dec *decoder, UWord8 *input, int num_bytes, void **output, int bits_per_sample, void *scratch, + int bfi_ext) +{ + int ch = 0, bfi = bfi_ext; + LC3PLUS_Error err = LC3PLUS_OK; + int fec_num_bytes; + int lc3_num_bytes; + int lc3_channel_num_bytes; + int channel_bfi, out_bfi; + Word16 channel_epmr; + + if (bfi == 0) + { + bfi = !num_bytes; + } + + if (decoder->ep_enabled) + { + decoder->combined_channel_coding = decoder->channels > 1 && num_bytes <= 160; + + if (decoder->combined_channel_coding) + { + fec_num_bytes = num_bytes; + +#ifdef WMOPS + push_wmops("fec_dec"); +#endif + + decoder->error_report = + fec_decoder(input, fec_num_bytes, &lc3_num_bytes, &decoder->epmr, decoder->combined_channel_coding, + &decoder->n_pccw, &bfi, &decoder->be_bp_left, &decoder->be_bp_right, &decoder->n_pc, + &decoder->m_fec, scratch); + +#ifdef WMOPS + pop_wmops(); +#endif + + for (ch = 0; ch < decoder->channels; ch++) + { + lc3_channel_num_bytes = lc3_num_bytes / decoder->channels + (ch < (lc3_num_bytes % decoder->channels)); + + + if (bfi != 1 && lc3_channel_num_bytes != decoder->channel_setup[ch]->last_size) + { + err = update_dec_bitrate(decoder, ch, lc3_channel_num_bytes); + + if (err) + { + bfi = 1; + } + else + { + decoder->channel_setup[ch]->last_size = lc3_channel_num_bytes; + } + } + + bfi = Dec_LC3PLUS_Channel(decoder, ch, bits_per_sample, input, output[ch], bfi, scratch); + input += decoder->channel_setup[ch]->targetBytes; + } + } + else + { + decoder->epmr = 12; + out_bfi = 0; + + for (ch = 0; ch < decoder->channels; ch++) + { + fec_num_bytes = num_bytes / decoder->channels + (ch < (num_bytes % decoder->channels)); + +#ifdef WMOPS + push_wmops("fec_dec"); +#endif + + channel_bfi = bfi; + + decoder->error_report = + fec_decoder(input, fec_num_bytes, &lc3_num_bytes, &channel_epmr, decoder->combined_channel_coding, + &decoder->n_pccw, &channel_bfi, &decoder->be_bp_left, &decoder->be_bp_right, + &decoder->n_pc, &decoder->m_fec, scratch); + +#ifdef WMOPS + pop_wmops(); +#endif + + decoder->epmr = MIN(decoder->epmr, channel_epmr); + + +#ifdef ENABLE_PADDING + if (channel_bfi != 1) + { + Word16 padding_len, np_zero; + + if (paddingDec_fx(input, shl(lc3_num_bytes, 3), decoder->yLen, decoder->BW_cutoff_bits, + decoder->ep_enabled, &padding_len, &np_zero)) + { + channel_bfi = 1; + } + + input = input + np_zero; + decoder->n_pc = s_max(decoder->n_pc - (2 * np_zero), 0); + + if (channel_bfi == 2) + { + if (decoder->be_bp_right < (8 * np_zero)) + { + channel_bfi = 0; + decoder->be_bp_left = -1; + decoder->be_bp_right = -1; + } + else + { + decoder->be_bp_right = decoder->be_bp_right - (8 * np_zero); + decoder->be_bp_left = s_max(decoder->be_bp_left - (8 * np_zero), 0); + } + } + + lc3_num_bytes = lc3_num_bytes - padding_len; + } +#endif + + if (channel_bfi != 1 && lc3_num_bytes != decoder->channel_setup[ch]->last_size) + { + err = update_dec_bitrate(decoder, ch, lc3_num_bytes); + if (err) + { + channel_bfi = 1; + } + else + { + decoder->channel_setup[ch]->last_size = lc3_num_bytes; + } + } + + channel_bfi = Dec_LC3PLUS_Channel(decoder, ch, bits_per_sample, input, output[ch], channel_bfi, scratch); + + out_bfi |= channel_bfi; + input += fec_num_bytes; + } + + bfi = out_bfi & 1; + } + } + else + { + for (ch = 0; ch < decoder->channels; ch++) + { + lc3_num_bytes = num_bytes / decoder->channels + (ch < (num_bytes % decoder->channels)); + +#ifdef ENABLE_PADDING + if (bfi != 1) + { + Word16 padding_len, np_zero; + + if (paddingDec_fx(input, shl(lc3_num_bytes, 3), decoder->yLen, decoder->BW_cutoff_bits, + decoder->ep_enabled, &padding_len, &np_zero)) + { + bfi = 1; + } + + lc3_num_bytes = lc3_num_bytes - padding_len; + if (lc3_num_bytes < 20 || lc3_num_bytes > LC3PLUS_MAX_BYTES) + { + bfi = 1; /* mark frame as broken if frame sizeif below the minimum of 20 bytes */ + } + } +#endif + + if (bfi != 1 && lc3_num_bytes != decoder->channel_setup[ch]->last_size) + { + err = update_dec_bitrate(decoder, ch, lc3_num_bytes); + if (err) + { + bfi = 1; + } + else + { + decoder->channel_setup[ch]->last_size = lc3_num_bytes; + } + } + + bfi = Dec_LC3PLUS_Channel(decoder, ch, bits_per_sample, input, output[ch], bfi, scratch); + input += decoder->channel_setup[ch]->targetBytes; + } + } + + return bfi == 1 ? LC3PLUS_DECODE_ERROR : LC3PLUS_OK; +} diff --git a/lib_lc3plus/defines.h b/lib_lc3plus/defines.h new file mode 100644 index 0000000000000000000000000000000000000000..2d280620f3ee01fcb15d28a7a8b20a01b2a6edf9 --- /dev/null +++ b/lib_lc3plus/defines.h @@ -0,0 +1,761 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.5 * +* Low Complexity Communication Codec Plus (LC3plus) * +* * +* Copyright licence is solely granted through ETSI Intellectual Property * +* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * +* estoppel or otherwise. * +******************************************************************************/ + +#ifndef DEFINES_H +#define DEFINES_H + +#ifndef DISABLE_HR_MODE +# define ENABLE_HR_MODE +#endif + +#ifdef ENABLE_HR_MODE +# define MAX_BW_HR 960 +#endif + +#ifdef ENABLE_HR_MODE +# define extractW16(a) extract_h(a) +#else +# define extractW16(a) (a) +#endif + +#define MAX_BR 320000 /* 400 * 800 */ + +/* FUNCTION MACROS */ +/* NB, divisions in some of these MACROs, use mainly for initial setup, do not use in loops */ +#define CEILING(x, y) (((x) + (y)-1) / (y)) + +#define FRAME2FS_IDX(x) (x / 100) /* 80 -> 0, 160 -> 1, 240 -> 2, 320 -> 3, 480 -> 4 */ +#ifdef ENABLE_HR_MODE +# define FS2FS_IDX(x) ((x) == 96000 ? 5 : (x) / 10000) /* 8000 -> 0, 16000 -> 1, 24000 -> 2, 32000 -> 3, 48000 -> 4, 96000 -> 5 */ +#else +# 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)) +#define STATIC_ASSERTS(cond, s) typedef char assert_##s[(cond) ? 1 : -1] +#define STATIC_ASSERTI(cond, i) STATIC_ASSERTS(cond, i) +#define STATIC_ASSERT(cond) STATIC_ASSERTI(cond, __LINE__) +#define TRACE(x) PRINTF("%s:%i %s = %i\n", __FILE__, __LINE__, #x, (int)(x)) + +/* For dynamic memory calculations */ +#define CODEC_FS(fs) ((fs) == 44100 ? 48000 : (fs)) + +#define DYN_MAX_LEN(fs) (CODEC_FS(fs) / 100) +#define DYN_MAX_LEN_EXT(fs) MAX(CODEC_FS(fs) / 100, 160) /* extension to length 160 for NB(fs=8000) */ +#define DYN_MAX_LPROT(fs) ((512 * (CODEC_FS(fs) / 100)) / 320) + +#define DYN_MAX_PLOCS(fs) (DYN_MAX_LPROT(fs) / 4 + 1) +#define DYN_MAX_MDCT_LEN(fs) (DYN_MAX_LEN(fs) - (180 * DYN_MAX_LEN(fs) / 480)) + +#define MAX_PITCH_FS(fs) (CEILING((MAX_PITCH_12K8 * CODEC_FS(fs)), (12800))) + +/* get the maximum buffer size assuming 10 ms framing */ +/* MAX_PITCH was previously always the highest fs in the current SUBSET , i.e. typically 48 kHz */ +/* now fs(from incoming wav file) adaptive MAX_PITCH_FS(fs) is used instead */ +#define DYN_MAX_LEN_PCM_PLC_CLASSIFIER(fs) \ + (MAX_PITCH_FS(fs) + DYN_MAX_LEN(fs)) /* CLASSIFIER PCM memory requirement */ +#define DYN_MAX_LEN_PCM_PLC_TDCAPPLYFILTER(fs) \ + ((M + 1) + MAX_PITCH_FS(fs) + (DYN_MAX_LEN(fs) / 2)) /* TDC filtering PCM memory requirement */ + +#ifdef ENABLE_HR_MODE +# define DYN_MAX_LEN_PCM_PLC(fs) (MAX_PITCH_FS(fs) + DYN_MAX_LEN(fs)) +#else +# define DYN_MAX_LEN_PCM_PLC(fs) MAX(DYN_MAX_LEN_PCM_PLC_CLASSIFIER(fs), DYN_MAX_LEN_PCM_PLC_TDCAPPLYFILTER(fs)) +#endif + +#define FRAME_MS_BLOCK 25 + +/* OPTIONS */ +#define ENABLE_2_5MS_MODE +#define ENABLE_5MS_MODE +#define ENABLE_075_DMS_MODE +#define ENABLE_10_MS_MODE +#define ENABLE_ADVANCED_PLC +#define ENABLE_ADVANCED_PLC_DEFAULT +#define ENABLE_BW_CONTROLLER +#define ENABLE_ERROR_PROTECTION +#define ENABLE_RFRAME +#define ENABLE_PC +#define ENABLE_PLC +#define ENABLE_PADDING +/* flags */ +#define ENABLE_BANDWIDTH_FLAG +#define ENABLE_RBANDWIDTH_FLAG +#define ENABLE_EP_MODE_FLAG +#define ENABLE_FRAME_MS_FLAG + +#define CR8_A_PLC_FADEOUT_TUNING /* Adapt PLC fadeout to avoid gaps in signal */ +#define CR8_E_TONE_DETECTOR /* Tone detector for hrmode to deactivate TNS - improves SNR and THD+N */ +#define CR8_F_ADAPT_MDCT_DCT_PRECISION +#define CR8_G_ADD_75MS + + +#define CR9_B_FIX_MDCT_OVERFLOW /* Fix overflow */ +#define CR9_C_FIX_DCT2_OVERFLOW /* Fix overflow */ + +#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 +# define CR10_A_ATTENUATION_CURVE_SELECTOR +# ifdef CR10_A_ATTENUATION_CURVE_SELECTOR +# 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 +#define CR9_M_FIX_DIV_ZERO + +#ifndef NO_POST_REL_CHANGES +/* Post-release non-bitexact changes */ + +#define CR11_A_FIX_IN_PLC_LONGTERM_STATISTIC + +#endif /* NO_POST_REL_CHANGES Post-release changes */ + +#ifdef CR8_A_PLC_FADEOUT_TUNING +# 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 6710886 /* 0.2 * 2^25 */ +# define SHIFT1_FADEOUT 25-15 /* 25 - 16 */ +# define FAC2_FADEOUT 50331648 /* 1.5 * 2^25 */ +# define SHIFT2_FADEOUT 25-15 /* 25 - 16 */ +# define FAC3_FADEOUT 58720256 /* 1.75 * 2^25 */ +# define SHIFT3_FADEOUT 25-15 /* 25 - 16 */ +# endif +# define PLC_LONGTERM_ANALYSIS_MS 200 /* Nominal analysis window 2000 ms */ +# define PLC_LONGTERM_ANALYSIS_STARTUP_FILL (Word16)(0.5*32768.0) /* 16384/32768 == 0.5 required buffer fill amount, set to 0.0 to not require any fill at all */ +#endif /* CR8_A_PLC_FADEOUT_TUNING */ + +#define REL_PITCH_THRESH 11796 + +# define MIN_BR_100DMS 16000 /* 20 * 800 * 100/100 */ +# ifdef SUBSET_NB +# define MAX_BR_100DMS_NB 114400 /* for 100ms at 8kHz */ +# endif +# ifdef SUBSET_WB +# define MAX_BR_100DMS_WB 221600 /* for 100ms at 16kHz */ +# endif +# ifdef SUBSET_SSWB +# define MAX_BR_100DMS_SSWB 314400 /* for 100ms at 24kHz */ +# endif + +/* G192 bitstream writing/reading */ +#define G192_GOOD_FRAME 0x6B21 +#define G192_BAD_FRAME 0x6B20 +#define G192_REDUNDANCY_FRAME 0x6B22 +#define G192_ZERO 0x007F +#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 DYNMEM_COUNT +#define STAMEM_COUNT + + +/* +do not change __forceinline for mex compilation using gcc6.3.0 or larger + gcc630 supported by MATLAB 2018b, via Mingw "app" + */ +#ifdef __GNUC__ +# define GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) +#else +# define GCC_VERSION 0 +#endif + +/* Define __forceinline as empty if ARM not activated to avoid any errors */ +#undef __forceinline +/* The above undef is needed to compile using make_mex.m without the following warning in Matlab for windows */ +#define __forceinline + +/* SUBSETS */ +#if !(defined(SUBSET_NB) || defined(SUBSET_WB) || defined(SUBSET_SSWB) || defined(SUBSET_SWB) || defined(SUBSET_FB) || defined(SUBSET_UB)) +# define SUBSET_NB +# define SUBSET_WB +# define SUBSET_SSWB +# define SUBSET_SWB +# define SUBSET_FB +# ifdef ENABLE_HR_MODE +# define SUBSET_UB +# endif +#endif + +# define MIN_BR_100DMS 16000 /* 20 * 800 * 100/100 */ +# define MIN_BR_025DMS 64000 /* 20 * 800 * 100/ 25 */ +# define MIN_BR_050DMS 32000 /* 20 * 800 * 100/ 50 */ +# define MAX_BR_050DMS_NB 260800 /* 163 * 800 * 100/ 50 */ +# ifdef SUBSET_NB +# define MAX_BR_100DMS_NB 114400 /* for 100ms at 8kHz */ +# endif +# ifdef SUBSET_WB +# define MAX_BR_100DMS_WB 221600 /* for 100ms at 16kHz */ +# endif +# ifdef SUBSET_SSWB +# define MAX_BR_100DMS_SSWB 314400 /* for 100ms at 24kHz */ +# endif + +#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) */ + +# define NOISEFILLWIDTH_7_5MS 2 +# define NOISEFILLSTART_7_5MS 18 +#endif + +#define PACK_RESBITS + +/* FRAME/BUFFER */ +#ifdef SUBSET_UB +# define MAX_LEN 960 /* = 10ms at 96kHz */ +#elif defined SUBSET_FB +# define MAX_LEN 480 /* = 10ms at 48kHz */ +#elif defined(SUBSET_SWB) +# define MAX_LEN 320 /* = 10ms at 32kHz */ +#elif defined(SUBSET_SSWB) +# define MAX_LEN 240 /* = 10ms at 24kHz */ +#elif defined(SUBSET_WB) +# define MAX_LEN 160 /* = 10ms at 16kHz */ +#elif defined(SUBSET_NB) +# define MAX_LEN 80 /* = 10ms at 8kHz */ +#endif + +#ifdef ENABLE_HR_MODE +# define ENABLE_FFT_RESCALE +# define ENABLE_FFT_30X16 +# define ENABLE_DCTIV_RESCALE + +# define EXT_RES_ITER_MAX 20 +# define MAX_RESBITS 5000 +# define HR_MODE_SCRATCH_SIZE 60 +#else /* ENABLE_HR_MODE */ +# define MAX_RESBITS MAX_LEN +#endif /* ENABLE_HR_MODE */ + +/* BW Cutoff-Detection */ +#define MAX_BW_BANDS_NUMBER 5 + +#ifdef ENABLE_HR_MODE +# define RESBITS_PACK_SHIFT 3 +# define RESBITS_PACK_N (1<<(RESBITS_PACK_SHIFT)) +# define RESBITS_PACK_MASK (RESBITS_PACK_N - 1) +# define MAX_RESBITS_LEN ((MAX_RESBITS + RESBITS_PACK_MASK) >> RESBITS_PACK_SHIFT) +# define MAX_RESBITS_LEN_32BIT_ALIGN (((MAX_RESBITS_LEN + 3)/4)*4) +#else /* ENABLE_HR_MODE */ +# define MAX_RESBITS_LEN (MAX_RESBITS) +# define MAX_RESBITS_LEN_32BIT_ALIGN (((MAX_RESBITS_LEN + 3)/4)*4) +#endif /* ENABLE_HR_MODE */ + +#define MAX_CHANNELS 2 +#define MIN_NBYTES 20 /* 100dms: 16 kbps at !=44.1kHz, 14.7kbps at 44.1kHz + 50dms: 32 kbps at !=44.1kHz, 29.4kbps at 44.1kHz + 25dms: 64 kbps at !=44.1kHz, 58.8kbps at 44.1kHz */ +#define MAX_NBYTES_025 100 /* any dms: 320 kbps at !=44.1kHz, 294 kbps at 44.1kHz */ +#define MAX_NBYTES_050 200 /* any dms: 320 kbps at !=44.1kHz, 294 kbps at 44.1kHz */ +#define MAX_NBYTES_075 400 /* any dms: 320 kbps at !=44.1kHz, 294 kbps at 44.1kHz */ +#define MAX_NBYTES_100 400 /* any dms: 320 kbps at !=44.1kHz, 294 kbps at 44.1kHz */ +#ifdef ENABLE_HR_MODE +# define MIN_BR_25MS_48KHZ_HR ((int)172800/3200/2)*3200 +# define MIN_BR_25MS_96KHZ_HR ((int)198400/3200/2)*3200 +# define MIN_BR_50MS_48KHZ_HR ((int)148800/1600/2)*1600 +# define MIN_BR_50MS_96KHZ_HR ((int)174400/1600/2)*1600 +# define MIN_BR_100MS_48KHZ_HR ((int)124800/800/2)*800 +# define MIN_BR_100MS_96KHZ_HR ((int)149600/800/2)*800 +# define MAX_NBYTES_RED_HR 625 /* From table 5.2 */ +# define BYTESBUFSIZE (MAX_NBYTES_RED_HR * LC3PLUS_MAX_CHANNELS) +#else +# define BYTESBUFSIZE (MAX_NBYTES_100 * LC3PLUS_MAX_CHANNELS) +#endif +#define MAX_BW_BIN 400 +#define FEC_SLOT_BYTES_MIN 40 +# define FEC_SLOT_BYTES_MAX 400 +#if MAX_BW_BIN > MAX_LEN +# define MAX_BW MAX_LEN +#else +# define MAX_BW MAX_BW_BIN +#endif + +#define NUM_OFFSETS 7 +#define NUM_SAMP_FREQ 6 + +/* SCF */ +#define M 16 /* LPC_ORDER */ +#define MAX_BANDS_NUMBER 64 +#define MAX_BANDS_NUMBER_PLC 80 +#define PVQ_MAX_VEC_SIZE M +#define KMAX_FX 10 /* N=10 */ +#define K_OUTL_FAR 6 +#define MPVQ_SZ_OUTL_FAR (1549824U >> 1) +#define TOTBITS_SHAPE OUTL_FAR(1.0 + 19.5637) +#define SQRT_EN_MAX_FX 64 /* table size, for fast inv_sqrt */ +#define N_SETA 10 +#define N_SETB (PVQ_MAX_VEC_SIZE - N_SETA) + +#define SNS_DAMPING 27853 /* 0.85 in Q15 */ +#ifdef ENABLE_HR_MODE +# define SNS_DAMPING_HRMODE 19661 /* 0.6 in Q15 */ +# define SNS_DAMPING_HRMODE_UB_10MS 6881 /* 0.21 in Q15 */ +# define SNS_DAMPING_HRMODE_UB_7_5MS 5898 /* 0.18 in Q15 */ +# define SNS_DAMPING_HRMODE_UB_5MS 4915 /* 0.15 in Q15 */ +# define SNS_DAMPING_HRMODE_UB_2_5MS 4915 /* 0.15 in Q15 */ +#endif + +/* PVQ VQ setup */ +#define VQMODES26 \ + ((0 << 4) + (1 << 3) + (1 << 2) + (1 << 1) + \ + (1 << 0)) /* select all shapes, including extended lf, and new far \ + shape for MODE26, add extreme far mode not enabled */ +#define SCF_STAGE1_MAX_BITS (5 + 5) /* typically only (5+5) used */ +#define SCF_STAGE1_NBCDKENTRIES 32 +#define SCF_STAGE2_MAX_GAIN_BITS 2 +#define SCF_STAGE2_NB_MODE_BITS 1 +#define SCF_STAGE2_MAX_NB_SHAPES 3 +#define SCF_MAX_PARAM 7 /* (L+H) + submode_MSB +gain+(Ia_leads+Ia_mpvq)+(Ib_joint_mpvq), submode-LSB */ +#define SCF_MAX_PARAM_ST2 (SCF_MAX_PARAM - 2) +#define N_SCF_SHAPES_ST2 4 +#define N_SCF_SHAPE_SETUPS 1 + +/* ARITHMETIC ENCODER */ +#define NBITS_CONTEXT 8 +#define NBITS_RATEQ 2 +#define A_THRES_SHIFT 2 +#define A_THRES (1 << A_THRES_SHIFT) +#define VAL_ESC 16 +#define SYM_BITS_Q 11 + +/* RESIDUAL CODING */ +#define NPRM_RESQ MAX_LEN + +/* NOISE FILLING */ +#define NOISEFILLWIDTH 3 +#define NOISEFILLSTART 24 +#define NOISEFILLWIDTH_5MS 1 +#define NOISEFILLSTART_5MS 12 +#define NOISEFILLWIDTH_2_5MS 1 +#define NOISEFILLSTART_2_5MS 6 + +/* MDCT */ +#ifdef ENABLE_HR_MODE +# define TWIDDLE ((Word32)0x5a82799a) +#else +# define TWIDDLE WORD322WORD16(0x5a82799a) +#endif +#define MDCT_MEM_LEN_MAX (MAX_LEN - ((180 * MAX_LEN) / 480)) + +/* TNS */ +#define TNS_NUMFILTERS_MAX 2 +#define TNS_COEF_RES 17 +#define INDEX_SHIFT 8 +#define NSUBDIV 3 +#define MAXLAG 8 + +/* OLPA/LTPF */ +#define LEN_12K8 128 +#define LEN_6K4 64 +#define MIN_PITCH_6K4 17 +#define MAX_PITCH_6K4 114 +#define RANGE_PITCH_6K4 98 +#define MIN_PITCH_12K8 32 +#define MAX_PITCH_12K8 228 +#define RES2_PITCH_12K8 157 +#define RES4_PITCH_12K8 127 +#define LTPF_MEMIN_LEN (MAX_PITCH_12K8 + 4) +#define M_LTPF 24 +#define LTPF_MEM_X_LEN (MAX_LEN + MAX_LEN / 40 - 2) +#define LTPF_MEM_Y_LEN (MAX_LEN + CEILING(MAX_PITCH_12K8 * MAX_LEN, 128) + (MAX_LEN / 80)) + +/* PLC */ +#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 */ + +# ifdef CR8_A_PLC_FADEOUT_TUNING + /* table 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 fade tables */ + +/* current settings */ +# define PLC2_FADEOUT_LONG_IN_MS 120 +# define PLC2_FADEOUT_IN_MS 30 /* 0 uses original constants for PLC2 + -1 uses TDC::PLC_FADEOUT_IN_MS as basis for a PLC2 macro-re-calculation + 30..140 will use a separate settings for PLC2 fadeout + 30: P800 short fade optimization + 120: Mushra optimized fade */ +#else +# define PLC2_FADEOUT_IN_MS 30 /* 0 uses original fixed values for PLC2 + -1 uses PLC_FADEOUT_IN_MS as basis for a PLC2 macro-re-calculation + 30..100 uses separate setting for PLC2 */ +#endif + + + +#define PLC4_TRANSIT_END_IN_MS PLC_FADEOUT_IN_MS /* end of transition time for noise substitution */ +#define PLC4_TRANSIT_START_IN_MS 20 /* begin of transition time for noise substitution for voiced signals */ +#define PLC34_ATTEN_FAC_100_FX 0x4000 /* attenuation factor for NS and TDC @ 10 ms (0.5000)*/ +#define PLC34_ATTEN_FAC_050_FX 0x5A83 /* attenuation factor for NS and TDC @ 5.0 ms (0.7071)*/ +#define PLC34_ATTEN_FAC_025_FX 0x6BA3 /* attenuation factor for NS and TDC @ 2.5 ms (0.8409)*/ +#ifdef CR8_G_ADD_75MS +#define PLC34_ATTEN_FAC_075_FX 0x4C1C /* attenuation factor for NS and TDC @ 7.5 ms (0.5946) */ +#endif +#define PLC3_HPBLENDTHROTTLE 30 /* higher numbers increase throttled blending from hp filtered to unfiltered uv excitation (0 is no throttle) */ + +#define MAX_PITCH_8K (CEILING((MAX_PITCH_12K8 * 8000), (12800))) /*NB was a risky MACRO at 0.5 border !!, */ +#define MAX_PITCH_16K ((MAX_PITCH_12K8 * 16000) / (12800)) /* exact integer */ +#define MAX_PITCH_24K \ + (CEILING((MAX_PITCH_12K8 * 24000), (12800))) /* was a risky MACRO truncation at 0.5 border !! , */ +#define MAX_PITCH_32K ((MAX_PITCH_12K8 * 32000) / (12800)) /* exact integer */ +#define MAX_PITCH_48K ((MAX_PITCH_12K8 * 48000) / (12800)) /* exact integer */ + +#ifdef ENABLE_HR_MODE +# define MAX_PITCH_96K ((MAX_PITCH_12K8 * 96000) / (12800)) /* exact integer */ +#endif + +#ifdef ENABLE_HR_MODE +# define MAX_PITCH MAX_PITCH_96K +#elif defined(SUBSET_FB) +# define MAX_PITCH MAX_PITCH_48K +#elif defined(SUBSET_SWB) +# define MAX_PITCH MAX_PITCH_32K +#elif defined(SUBSET_SSWB) +# define MAX_PITCH MAX_PITCH_24K +#elif defined(SUBSET_WB) +# define MAX_PITCH MAX_PITCH_16K +#elif defined(SUBSET_NB) +# define MAX_PITCH MAX_PITCH_8K +#endif + + +/* macri MAX_LEN_PCM_PLC is used for WC memory size checking + DYN_MAX_LEN_PCM_PLC(fs) is used by static memory buffers + */ +#define MAX_LEN_PCM_PLC (MAX_PITCH + MAX_LEN) + +#define TDC_L_FIR_HP 11 +#define TDC_L_FIR_LP 11 + +#define BASE_LPROT 512 /* BASE Lprot set to 512 for 32 kHz sampling */ + +#define LPROT48K (BASE_LPROT * 48 / 32) /* Fs based Lprot */ +#define LPROT40K (BASE_LPROT * 40 / 32) /* For Fs == 48000 only use 0 - 20000 Hz in 8 bands */ +#define LPROT32K BASE_LPROT +#define LPROT24K (BASE_LPROT * 24 / 32) +#define LPROT16K (BASE_LPROT * 16 / 32) +#define LPROT8K (BASE_LPROT * 8 / 32) + +/* #define PHECU_XFP_LA 1 */ /* Original soluiton xfp generated with 1ms look ahead into MDCT memory + ctrl.PhECU.LA = 0.001 * ctrl.fs; */ +/* #define PHECU_XFP_LA 4 */ /* Option with some lookahead 1/4 ms look ahead into MDCT memory + ctrl.PhECU.LA = 0.001 * ctrl.fs / 4; */ +#define PHECU_XFP_LA \ + 0 /* Option without lookahead 0 ms look ahead into MDCT memory \ + ctrl.PhECU.LA = 0; */ + +#if (PHECU_XFP_LA == 0) + +# define PHECU_LA_48K 0 /* 0 ms */ +# define PHECU_LA_32K 0 /* 0 ms */ +# define PHECU_LA_24K 0 /* 0 ms */ +# define PHECU_LA_16K 0 /* 0 ms */ +# define PHECU_LA_8K 0 /* 0 ms */ + +# define MAX_PHECU_LA (0) + +#else +# if (PHECU_XFP_LA == 4) + +# define PHECU_LA_48K (48 / 4) /* 0.25 ms */ +# define PHECU_LA_32K (32 / 4) /* 0.25 ms */ +# define PHECU_LA_24K (24 / 4) /* 0.25 ms */ +# define PHECU_LA_16K (16 / 4) /* 0.25 ms */ +# define PHECU_LA_8K (8 / 4) /* 0.25 ms */ + +# define MAX_PHECU_LA (MAX_LEN / 10 / 4) + +# else + +# define PHECU_LA_48K 48 /* 1 ms */ +# define PHECU_LA_32K 32 /* 1 ms */ +# define PHECU_LA_24K 24 /* 1 ms */ +# define PHECU_LA_16K 16 /* 1 ms */ +# define PHECU_LA_8K 8 /* 1 ms */ + +# define MAX_PHECU_LA (MAX_LEN / 10) + +# endif +#endif + + +/* (PHECU_LA_48K == 0) */ + +#define COPY_LEN_8K 16 +#define COPY_LEN_16K 32 +#define COPY_LEN_24K 48 +#define COPY_LEN_32K 64 +#define COPY_LEN_48K 96 + +#define OLA_LEN_8K 14 +#define OLA_LEN_16K 28 +#define OLA_LEN_24K 42 +#define OLA_LEN_32K 56 +#define OLA_LEN_48K 84 + +#define LPROT48K_RED LPROT40K /* limit peak searched part of spectrum for FB */ +#define LPROT32K_RED LPROT32K /* limit peak searched part of spectrum for SWB */ +#define LPROT24K_RED LPROT24K /* limit peak searched part of spectrum for HQ */ +#define LPROT16K_RED LPROT16K /* limit peak searched part of spectrum for SQ */ +#define LPROT8K_RED LPROT8K /* limit peak searched part of spectrum for NB */ + +#define INV_LPROT48K_Q22 5461 /* round(2^22/LPROT48K) , 1/6 */ +#define INV_LPROT32K_Q22 8192 /* round(2^22/LPROT32K) , 1/4 */ +#define INV_LPROT24K_Q22 10923 /* round(2^22/LPROT24K) , 1/3 */ +#define INV_LPROT16K_Q22 16384 /* round(2^22/LPROT16K) , 1/2 */ +#define INV_LPROT8K_Q22 32767 /* round(2^22/LPROT8K) , 1/1 */ + +#define LGW48K 8 /* 8 bands defined , but may the same frequency groups as for SWB(32k) */ +#define LGW32K 7 +#define LGW24K 6 +#define LGW16K 5 +#define LGW8K 4 + +#define MAX_LGW 9 /* LGW48K + 1 !! */ + +#define UNINIT_OR_UNSAFE_OOLD_SENTINEL -32768 +#define LTOT_INIT_FLAG -32768 +#define LTOT_MIN_MAN 1 /* lowest possible energy value */ +#define LTOT_MIN_EXP -61 /* L_tot= LTOT_MIN_MAN*2^(LTOT_MIN_EXP-31) */ +#define GRP_SHAPE_INIT 0 /* Q15 */ + +#define TRANA_TIME 4 /* Transient analysis length in ms */ +#define LTRANA48K (48000 * TRANA_TIME / 1000) +#define LTRANA32K (32000 * TRANA_TIME / 1000) +#define LTRANA24K (24000 * TRANA_TIME / 1000) +#define LTRANA16K (16000 * TRANA_TIME / 1000) +#define LTRANA8K (8000 * TRANA_TIME / 1000) + +#define MAX_PLOCS ((MAX_LPROT / 4) + 1) /* maximum number of spectral peaks to be searched */ +#define QUOT_LPR_LTR 4 + +#define BETA_MUTE_FAC_INI 16384 /* Q15, initial noise attenuation factor */ + +#define OFF_FRAMES_LIMIT 30 /* Hard limit to a maximum of 300ms of burst decay frames */ + +#define Lprot_hamm_len2_48k (3 * 48) +#define Lprot_hamm_len2_32k (3 * 32) +#define Lprot_hamm_len2_24k (3 * 24) +#define Lprot_hamm_len2_16k (3 * 16) +#define Lprot_hamm_len2_8k (3 * 8) + +#define FRAME_TIME 10 /* Frame length in ms */ + +#define L_FRAME48K (48000 * FRAME_TIME / 1000) +#define L_FRAME32K (32000 * FRAME_TIME / 1000) +#define L_FRAME24K (24000 * FRAME_TIME / 1000) +#define L_FRAME16K (16000 * FRAME_TIME / 1000) +#define L_FRAME8K (8000 * FRAME_TIME / 1000) + +#ifdef DISABLE_PLC +# define MAX_LTRANA 0 +# define MAX_LPROT LPROT48K +# define MAX_L_FRAME L_FRAME48K +# define MAX_LPROT_RED LPROT48K_RED +#else + +# ifdef SUBSET_UB +# define MAX_LPROT LPROT48K /* Max length of protype frame for buffer allocation */ +# define MAX_LPROT_RED LPROT48K_RED /* stack alloc peak searched part */ +# define MAX_LTRANA LTRANA48K +# define MAX_L_FRAME L_FRAME48K +# elif defined(SUBSET_FB) +# define MAX_LPROT LPROT48K /* Max length of protype frame for buffer allocation */ +# define MAX_LPROT_RED LPROT48K_RED /* stack alloc peak searched part */ +# define MAX_LTRANA LTRANA48K +# define MAX_L_FRAME L_FRAME48K +# elif defined(SUBSET_SWB) +# define MAX_LPROT LPROT32K +# define MAX_LPROT_RED LPROT32K_RED /* stack alloc peak searched part */ +# define MAX_LTRANA LTRANA32K +# define MAX_L_FRAME L_FRAME32K +# elif defined(SUBSET_SSWB) +# define MAX_LPROT LPROT24K +# define MAX_LPROT_RED LPROT24K_RED /* stack alloc peak searched part */ +# define MAX_LTRANA LTRANA24K +# define MAX_L_FRAME L_FRAME24K +# elif defined(SUBSET_WB) +# define MAX_LPROT LPROT16K +# define MAX_LPROT_RED LPROT16K_RED /* stack alloc peak searched part */ +# define MAX_LTRANA LTRANA16K +# define MAX_L_FRAME L_FRAME16K +# elif defined(SUBSET_NB) +# define MAX_LPROT LPROT8K +# define MAX_LPROT_RED LPROT8K_RED /* stack alloc peak searched part */ +# define MAX_LTRANA LTRANA8K +# define MAX_L_FRAME L_FRAME8K +# endif + +#endif /* #ifdef DISABLE_PLC */ + +#define INV_L_FRAME48K_Q15 32768 / L_FRAME48K +#define INV_L_FRAME32K_Q15 32768 / L_FRAME32K +#define INV_L_FRAME24K_Q15 32768 / L_FRAME24K +#define INV_L_FRAME16K_Q15 32768 / L_FRAME16K +#define INV_L_FRAME8K_Q15 32768 / L_FRAME8K + +#define MDCT_MEM_LEN_48 (L_FRAME48K - ((180 * L_FRAME48K) / 480)) + +#define R1_48 690 +#define R2_48 420 +#define R1_16 230 +#define R2_16 140 +#define R1_25 368 +#define R2_25 224 + +#define MAX_LEN_PCM_PLC_TOT (MAX_LEN_PCM_PLC) /* TDC_pcm_buff */ +#define MAX_WIN_PRE_TDA (0) /* not in RAM any longer , now stored in ROM only as PhECU_wins[fs_idx][1] */ + +#define MAX_PLCMETH 1 + +/* Scratch buffer defines */ +#define scratchBuffer_ACTIVE +#ifdef ENABLE_HR_MODE +# define SCRATCH_BUF_LEN_ENC (4 * MAX_LEN + 32 + 32 + 4 * MAX_LEN + 3 * MAX_LEN + MAX_RESBITS_LEN_32BIT_ALIGN) +# define SCRATCH_BUF_LEN_ENC_CURRENT_SCRATCH (4 * MAX_LEN + 8 * 60 + MAX_LEN) +#else +# define SCRATCH_BUF_LEN_ENC (4 * MAX_LEN + 32 + 32 + 2 * MAX_LEN + 3 * MAX_LEN + MAX_RESBITS_LEN_32BIT_ALIGN) +# define SCRATCH_BUF_LEN_ENC_CURRENT_SCRATCH (4 * MAX_LEN) +#endif + +#define SCRATCH_BUF_LEN_ENC_TOT (SCRATCH_BUF_LEN_ENC + SCRATCH_BUF_LEN_ENC_CURRENT_SCRATCH) + +#ifdef ENABLE_HR_MODE +# define SCRATCH_BUF_LEN_DEC (4 * MAX_LEN + MAX_RESBITS_LEN_32BIT_ALIGN + 32 + 32 + 4 * MAX_LEN + 32 + 128 + 128) +#else +# define SCRATCH_BUF_LEN_DEC (4 * MAX_LEN + 2 * MAX_LEN + 32 + 32 + 2 * MAX_LEN + 32 + 128 + 128) +#endif +#define SCRATCH_BUF_LEN_DEC_CURRENT_SCRATCH (2 * MAX_LGW + 8 * MAX_LPROT + 12 * MAX_L_FRAME) +#ifdef ENABLE_HR_MODE +# define SCRATCH_BUF_LEN_DEC_TOT (SCRATCH_BUF_LEN_DEC + (4 * HR_MODE_SCRATCH_SIZE) + SCRATCH_BUF_LEN_DEC_CURRENT_SCRATCH) +#else +# define SCRATCH_BUF_LEN_DEC_TOT (SCRATCH_BUF_LEN_DEC + SCRATCH_BUF_LEN_DEC_CURRENT_SCRATCH) +#endif + +#define ADVACED_PLC_SIZE \ + (sizeof(AplcSetup) + (4 + 2) * MAX_PLOCS + 2 * MAX_LEN_PCM_PLC_TOT + 0 * MAX_LPROT + 2 * MDCT_MEM_LEN_MAX + \ + 2 * MAX_WIN_PRE_TDA) +/* ERI : Correct this sum after ROM/RAM , joint RAM optimizations */ + + +#define ENC_MAX_SIZE (sizeof(LC3PLUS_Enc) + MAX_CHANNELS * (sizeof(EncSetup) + 6 * MDCT_MEM_LEN_MAX)) +#define DEC_MAX_SIZE \ + (sizeof(LC3PLUS_Dec) + MAX_CHANNELS * (sizeof(DecSetup) + ADVACED_PLC_SIZE + 2 * LTPF_MEM_X_LEN + 2 * LTPF_MEM_Y_LEN + \ + 2 * MDCT_MEM_LEN_MAX + 2 * MAX_BW)) + +#if (defined(_M_ARM) || defined(__CC_ARM) || defined(__TMS470__) || defined(__arm__) || defined(__aarch64__)) && \ + (defined(__TARGET_FEATURE_NEON) || defined(__ARM_NEON) || defined(__ARM_NEON__) || defined(__ARM_AARCH64_NEON__)) +# define ALIGNMENT_DEFAULT 16 +#elif defined(__bfin__) +# define ALIGNMENT_DEFAULT 4 +#else +# define ALIGNMENT_DEFAULT 8 +#endif + +/* RAM_ALIGN keyword causes memory alignment of global variables. */ +#if defined(__GNUC__) +# define RAM_ALIGN __attribute__((aligned(ALIGNMENT_DEFAULT))) +#elif defined(__CC_ARM) +# define RAM_ALIGN __align(ALIGNMENT_DEFAULT) +#elif defined(__ANALOG_EXTENSIONS__) +# define RAM_ALIGN +# pragma pack(ALIGNMENT_DEFAULT) +#elif defined(_MSC_VER) +# define RAM_ALIGN __declspec(align(ALIGNMENT_DEFAULT)) +#else +# define RAM_ALIGN +#endif + +#define scratchAlign(ptr, offset) (void *)(((uintptr_t)(ptr) + (offset) + 0x3) & ~0x3) + + +/* some configurations leave empty translation units. */ +extern int fix_empty_translation_unit_warning; + +#define FIX_IVAS_LC3PLUS_DUPLICATES +#ifdef FIX_IVAS_LC3PLUS_DUPLICATES +#define Tab_esc_nb Tab_esc_nb_lc3plus +#define POW_ATT_TABLE0 POW_ATT_TABLE0_lc3plus +#define POW_ATT_TABLE1 POW_ATT_TABLE1_lc3plus +#define InvIntTable InvIntTable_lc3plus +#define SineTable320 SineTable320_lc3plus +#define RotVector_320 RotVector_320_lc3plus +#define RotVector_480 RotVector_480_lc3plus +#define SineWindow20 SineWindow20_lc3plus +#define SineWindow40 SineWindow40_lc3plus +#define SineWindow60 SineWindow60_lc3plus +#define SineWindow80 SineWindow80_lc3plus +#define SineWindow120 SineWindow120_lc3plus +#define SineWindow160 SineWindow160_lc3plus +#define SineWindow180 SineWindow180_lc3plus +#define SineWindow320 SineWindow320_lc3plus +#define BASOP_getTables BASOP_getTables_lc3plus +#define ISqrt16 ISqrt16_lc3plus +#define getScaleFactor16 getScaleFactor16_lc3plus +#define Norm32Norm Norm32Norm_lc3plus +#define Scale_sig Scale_sig_lc3plus +#define Copy_Scale_sig Copy_Scale_sig_lc3plus +#define get_size_mpvq_calc_offset_fx get_size_mpvq_calc_offset_fx_lc3plus +#endif + +#define FIX_IVAS_LC3PLUS_WARNINGS + +#endif diff --git a/lib_lc3plus/detect_cutoff_warped_fx.c b/lib_lc3plus/detect_cutoff_warped_fx.c new file mode 100644 index 0000000000000000000000000000000000000000..adbf04afad360ad7daafc39ab5eaa1b81836f41b --- /dev/null +++ b/lib_lc3plus/detect_cutoff_warped_fx.c @@ -0,0 +1,124 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.5 * +* 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 "functions.h" +#include "rom_basop_util_lc3plus.h" + +void processDetectCutoffWarped_fx(Word16 *bw_idx, Word32 *d2_fx, Word16 d2_fx_exp, Word16 fs_idx, Word16 frame_dms) +{ + + Dyn_Mem_Deluxe_In( + Counter iBand; + Word32 d2_fx_sum; + Word32 d2_fx_mean; + Word32 delta_energy; + Word16 d2_fx_sum_exp; + Word16 d2_fx_mean_exp; + Word16 nrg_below_thresh; + Word16 counter; + Word16 brickwall; + Word16 stop; + Word16 brickwall_dist; + const Word16 *warp_idx_start, *warp_idx_stop, *bw_brickwall_dist; + ); + + SWITCH (frame_dms) + { + case 25: + warp_idx_start = BW_warp_idx_start_all_2_5ms[fs_idx - 1]; move16(); + warp_idx_stop = BW_warp_idx_stop_all_2_5ms[fs_idx - 1]; move16(); + bw_brickwall_dist = BW_brickwall_dist_2_5ms; + BREAK; + case 50: + warp_idx_start = BW_warp_idx_start_all_5ms[fs_idx - 1]; move16(); + warp_idx_stop = BW_warp_idx_stop_all_5ms[fs_idx - 1]; move16(); + bw_brickwall_dist = BW_brickwall_dist_5ms; + BREAK; +#ifdef CR8_G_ADD_75MS + case 75: + warp_idx_start = BW_warp_idx_start_all_7_5ms[fs_idx - 1]; move16(); + warp_idx_stop = BW_warp_idx_stop_all_7_5ms[fs_idx - 1]; move16(); + bw_brickwall_dist = BW_brickwall_dist_7_5ms; + BREAK; +#endif + default: /* 100 */ + warp_idx_start = BW_warp_idx_start_all[fs_idx - 1]; move16(); + warp_idx_stop = BW_warp_idx_stop_all[fs_idx - 1]; move16(); + bw_brickwall_dist = BW_brickwall_dist; + BREAK; + } + + counter = fs_idx; + DO + { + + /* counter is 0...num_idxs-1 */ + counter = sub(counter, 1); + + /* always code the lowest band (NB), skip check against threshold if counter == -1 */ + IF (counter < 0) + { + BREAK; + } + + d2_fx_mean = 0; move32(); + d2_fx_mean_exp = 0; move16(); + + iBand = warp_idx_start[counter]; move16(); + d2_fx_sum = d2_fx[iBand]; move32(); + d2_fx_sum_exp = d2_fx_exp; move16(); + + iBand++; + FOR (; iBand <= warp_idx_stop[counter]; iBand++) + { + d2_fx_sum = BASOP_Util_Add_Mant32Exp_lc3plus(d2_fx[iBand], d2_fx_exp, d2_fx_sum, d2_fx_sum_exp, &d2_fx_sum_exp); + } + /* Energy-sum */ + d2_fx_mean = Mpy_32_16_lc3plus(d2_fx_sum, InvIntTable[add(sub(warp_idx_stop[counter], warp_idx_start[counter]), 1)]); + d2_fx_mean_exp = d2_fx_sum_exp; move16(); + + /* check if above threshold */ + nrg_below_thresh = BASOP_Util_Cmp_Mant32Exp_lc3plus(BW_thresh_quiet[counter], BW_thresh_quiet_exp, d2_fx_mean, + d2_fx_mean_exp); /* true if firstNumber > secondNumber */ + } + WHILE (nrg_below_thresh > 0) + ; + + *bw_idx = add(1, counter); move16(); + + /* addtional check for brickwall characteristic */ + IF (sub(fs_idx, *bw_idx) > 0) + { + brickwall = 0; move16(); + stop = add(warp_idx_start[counter + 1], 1); + brickwall_dist = bw_brickwall_dist[counter + 1]; + + FOR (iBand = stop; iBand >= sub(stop, brickwall_dist); iBand--) + { + /* Band(x) > Band(x-3)*Thr */ + delta_energy = + L_sub(Mpy_32_16_lc3plus(d2_fx[iBand - brickwall_dist], BW_thresh_brickwall[counter + 1]), d2_fx[iBand]); + if (delta_energy > 0) + { + brickwall = 1; move16(); + } + IF (brickwall) + { + BREAK; + } + } + if (brickwall == 0) + { + *bw_idx = fs_idx; + } + } + + Dyn_Mem_Deluxe_Out(); +} + diff --git a/lib_lc3plus/dynmem.c b/lib_lc3plus/dynmem.c new file mode 100644 index 0000000000000000000000000000000000000000..65e157d0a19674301e84bd729035143ff4f1d153 --- /dev/null +++ b/lib_lc3plus/dynmem.c @@ -0,0 +1,288 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.5 * +* 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. * +******************************************************************************/ + + +/* + Tool for dynamic memory estimation + Anisse Taleb, November 2003 + +*/ + +/* turn off stdlib function warnings in visual studio */ +#ifdef _MSC_VER +#define _CRT_SECURE_NO_WARNINGS +#endif + +#include +#include +#include +#include +#include + +#include "dynmem.h" + +#define MAX_FUNC_NAME_LENGTH 128 + + + +struct C_Path{ + char func_name[MAX_FUNC_NAME_LENGTH]; + long mem_usage; + long mem_usage_acc; + struct C_Path *next; + struct C_Path *parent; +}; + + +typedef struct C_Path C_Path; + +static C_Path *Max_Mem_path; /* Snap shot of the maximum memory usage path */ +static C_Path *Head_path; +static C_Path *Curr_path; /* Current code path */ + + +static long Max_mem_usage; + +static C_Path *Static_mem_head; +static C_Path *Static_mem_curr; + +/* + * initialisation. Must be called at start, sets up all the + * structures and resets counters. + * + * Called externally. + */ + +static void path_free(C_Path * path) +{ + C_Path *path_end,*tmp; + path_end = path; + + if(path == NULL) return; + /* find last node */ + while(path_end->next != NULL) path_end = path_end->next; + + /* walk back */ + while(path_end != NULL) { + tmp = path_end; + path_end = path_end->parent; + free(tmp); + } + +} +static void path_save(void) +{ + C_Path * node; + C_Path * node_save; + C_Path * previous; + /* free the old path */ + path_free(Max_Mem_path); + Max_Mem_path = NULL; + /* */ + + Max_Mem_path = (C_Path *) malloc(sizeof(C_Path)); + + node = Head_path; + node_save = Max_Mem_path; + previous = NULL; + while(node != NULL){ + + strcpy(node_save->func_name,node->func_name); + node_save->mem_usage = node->mem_usage; + node_save->mem_usage_acc = node->mem_usage_acc; + + node_save->parent = previous; + node_save->next = NULL; + + if(node->next != NULL) { + node_save->next = (C_Path *) malloc(sizeof(C_Path)); + } + node = node->next; + previous = node_save; + node_save = node_save->next; + } while(node != NULL); + +} + +void P_Dyn_Mem_Init(void) +{ + + /* initialize the path */ + Head_path = (C_Path *) malloc(sizeof(C_Path)); + strcpy(Head_path->func_name,"---Top---"); + Head_path->mem_usage = 0; + Head_path->mem_usage_acc = 0; /*memory usage accumulator */ + Head_path->parent = NULL; + Head_path->next = NULL; + + Curr_path = Head_path; + /* Initilaize the memory consumptions */ + Max_mem_usage = 0; + Max_Mem_path = NULL; +} + +void P_Dyn_Mem_In(const char *func_name, + long mem_usage) +{ +#ifdef DEBUG_DYNMEM + printf( "Entering: %s\n", func_name ); +#endif + + /* Enter a new function, push on the stack */ + if(Curr_path->next != NULL) { + fprintf(stderr,"\n Something went wrong !!"); + exit(0); + + } + Curr_path->next = (C_Path*) malloc (sizeof(C_Path)); + + if(Curr_path->next == NULL) { + fprintf(stderr,"\n Can't allocate memory"); + exit(0); + } + + Curr_path->next->parent = Curr_path; + Curr_path = Curr_path->next; + Curr_path->next = NULL; + /* save function name */ + strcpy(Curr_path->func_name,func_name); + /* save memory usage */ + Curr_path->mem_usage = mem_usage; + /* update memory usage accumulator */ + Curr_path->mem_usage_acc = Curr_path->parent->mem_usage_acc + mem_usage; +} + +/* Add memory size to current function */ +void P_Dyn_Mem_Add(long mem_usage) +{ +#ifdef DEBUG_DYNMEM + printf( "Staying in: %s\n", Curr_path->func_name); +#endif + + /* Staying in the current function, nothing to push */ + + /* save memory usage */ + Curr_path->mem_usage = Curr_path->mem_usage + mem_usage; + /* update memory usage accumulator */ + Curr_path->mem_usage_acc = Curr_path->mem_usage_acc + mem_usage; +} + + +/* before any return */ + +void P_Dyn_Mem_Out(void) +{ + C_Path *tmp; + if(Curr_path->mem_usage_acc > Max_mem_usage) { + /* set new memory usage record */ + Max_mem_usage = Curr_path->mem_usage_acc; + /* save snap shot */ + path_save(); + } + +#ifdef DEBUG_DYNMEM + printf( "Exiting: %s\n", Curr_path->func_name ); +#endif + + /* delete last node */ + tmp = Curr_path; + + Curr_path = Curr_path->parent; + Curr_path->next = NULL; + free(tmp); +} + + +/* Write data and exit */ + +void P_Dyn_Mem_Exit(void) +{ + /*FILE *f_mem_statistics;*/ + C_Path *node; + /*f_mem_statistics = fopen("mem_stat.txt","wt"); + fprintf(f_mem_statistics,"\n Maximum dynamic memory usage = %ld b, %ld kW \n Critical Memory Usage Path", Max_mem_usage, Max_mem_usage/(1000*2));*/ + /* fprintf(stderr,"\n Maximum dynamic memory usage = %ld kWords (%ld bytes)\n Critical Memory Usage Path", Max_mem_usage/(1000*2),Max_mem_usage); */ + fprintf(stderr,"\n Maximum dynamic memory usage = %.2f kWords (%ld bytes)\n Critical Memory Usage Path", (ceil((float)Max_mem_usage/20.f)/100.f), Max_mem_usage); + + node = Max_Mem_path; + while (node != NULL) { + /*fprintf(f_mem_statistics,"\n %-30s %10ld bytes (+ %10ld bytes)",node->func_name, node->mem_usage_acc, node->mem_usage);*/ + fprintf(stderr,"\n %-30s %10ld bytes (+ %10ld bytes)",node->func_name, node->mem_usage_acc, node->mem_usage); + node=node->next; + } + + /*fclose(f_mem_statistics);*/ + fprintf(stderr,"\n"); + +#ifdef CTEST_MEASUREMENTS + printf("%.3f\n", "dynMem [kWords]", "numeric/float", Max_mem_usage/(1000.0*2)); +#endif + + path_free(Max_Mem_path); + path_free(Head_path); +} + +void P_Dyn_Mem_Exit_noprint(void) +{ + path_free(Max_Mem_path); + path_free(Head_path); +} +void P_Sta_Mem_Init(void) +{ + /* initialize the head object */ + Static_mem_head = (C_Path *) malloc(sizeof(C_Path)); + strcpy(Static_mem_head->func_name,"---Top---"); + Static_mem_head->mem_usage = 0; + Static_mem_head->mem_usage_acc = 0; + Static_mem_head->parent = NULL; + Static_mem_head->next = NULL; + Static_mem_curr = Static_mem_head; +} + +void P_Sta_Mem_Add(const char *func_name, + long mem_usage) +{ + /* Enter a new function, push on the stack */ + Static_mem_curr->next = (C_Path*) malloc (sizeof(C_Path)); + Static_mem_curr->next->parent = Static_mem_curr; + Static_mem_curr = Static_mem_curr->next; + Static_mem_curr->next = NULL; + /* save function name */ + strcpy(Static_mem_curr->func_name,func_name); + /* save memory usage */ + Static_mem_curr->mem_usage = mem_usage; + /* update memory usage accumulator */ + Static_mem_curr->mem_usage_acc = Static_mem_curr->parent->mem_usage_acc + mem_usage; +} + +void P_Sta_Mem_Exit(void) +{ + C_Path *node; + /* fprintf(stderr,"\n Static memory usage = %ld kWords (%ld bytes)\n Detailed Memory Usage", Static_mem_curr->mem_usage_acc/(1000*2),Static_mem_curr->mem_usage_acc); */ + fprintf(stderr,"\n Static memory usage = %.2f kWords (%ld bytes)\n Detailed Memory Usage", (ceil((float)Static_mem_curr->mem_usage_acc/20.f)/100.f),Static_mem_curr->mem_usage_acc); + + node = Static_mem_head->next; + while (node != NULL) { + fprintf(stderr,"\n %-30s %10ld bytes (+ %10ld bytes)",node->func_name, node->mem_usage_acc, node->mem_usage); + node=node->next; + } + + fprintf(stderr,"\n"); + +#ifdef CTEST_MEASUREMENTS + printf("%.3f\n", "statMem [kWords]", "numeric/float", Static_mem_curr->mem_usage_acc/(1000.0*2)); +#endif + + path_free(Static_mem_head); +} + +void P_Sta_Mem_Exit_noprint(void) +{ + path_free(Static_mem_head); +} diff --git a/lib_lc3plus/dynmem.h b/lib_lc3plus/dynmem.h new file mode 100644 index 0000000000000000000000000000000000000000..e81169a3379a3ab3e601f397bccbd00330e00c56 --- /dev/null +++ b/lib_lc3plus/dynmem.h @@ -0,0 +1,80 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.5 * +* Low Complexity Communication Codec Plus (LC3plus) * +* * +* Copyright licence is solely granted through ETSI Intellectual Property * +* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * +* estoppel or otherwise. * +******************************************************************************/ + + +#ifndef DYNMEM_H +#define DYNMEM_H + +#ifdef _MSC_VER +/* This disables warnings about anonymous temporary struct declarations */ +#pragma warning(disable:4115) +#pragma warning(disable:4116) +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +void P_Dyn_Mem_Init(void); +void P_Dyn_Mem_In(const char *func_name, + long mem_usage); +void P_Dyn_Mem_Add(long mem_usage); +void P_Dyn_Mem_Out(void); +void P_Dyn_Mem_Exit(void); +void P_Dyn_Mem_Exit_noprint(void); + +void P_Sta_Mem_Init(void); +void P_Sta_Mem_Add(const char *func_name, + long mem_usage); +void P_Sta_Mem_Exit(void); +void P_Sta_Mem_Exit_noprint(void); + +#ifdef DONT_COUNT_MEM + +#define Dyn_Mem_Init() +#define Dyn_Mem_Exit() +#define Dyn_Mem_Exit_noprint() +#define Dyn_Mem_In(a,b) +#define Dyn_Mem_Add(b) +#define Dyn_Mem_Out() + +#define DYN_MEM_IN Dyn_Mem_In +#define DYN_MEM_ADD Dyn_Mem_Add +#define DYN_MEM_OUT Dyn_Mem_Out + +#define Sta_Mem_Init() +#define Sta_Mem_Exit() +#define Sta_Mem_Exit_noprint() +#define Sta_Mem_Add(a,b) + +#else /* DONT_COUNT_MEM */ + +#define Dyn_Mem_Init P_Dyn_Mem_Init +#define Dyn_Mem_Exit P_Dyn_Mem_Exit +#define Dyn_Mem_Exit_noprint P_Dyn_Mem_Exit_noprint +#define Dyn_Mem_In P_Dyn_Mem_In +#define Dyn_Mem_Add P_Dyn_Mem_Add +#define Dyn_Mem_Out P_Dyn_Mem_Out + +#define DYN_MEM_IN P_Dyn_Mem_In +#define DYN_MEM_ADD P_Dyn_Mem_Add +#define DYN_MEM_OUT P_Dyn_Mem_Out + +#define Sta_Mem_Init P_Sta_Mem_Init +#define Sta_Mem_Exit P_Sta_Mem_Exit +#define Sta_Mem_Exit_noprint P_Sta_Mem_Exit_noprint +#define Sta_Mem_Add P_Sta_Mem_Add + +#endif /* DONT_COUNT_MEM */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/lib_lc3plus/enc_entropy.c b/lib_lc3plus/enc_entropy.c new file mode 100644 index 0000000000000000000000000000000000000000..35dd8d95064901dd5061436dfbb808011ac35b6d --- /dev/null +++ b/lib_lc3plus/enc_entropy.c @@ -0,0 +1,173 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.5 * +* 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 "functions.h" + +static Word32 ac_enc_mux_st2VQ_cws( /* o: max 25 bits total codeword */ + const Word32 L_szA, /* i: max 22 bits */ + const Word32 L_szB, /* i: max 4 bits */ + const Word32 L_cwA, const Word32 L_cwB); + +void processEncoderEntropy(UWord8 *bytes, Word16 *bp_side, Word16 *mask_side, Word16 nbbits, Word16 targetBytes, + Word16 L_spec, Word16 BW_cutoff_bits, Word16 tns_numfilters, + Word16 lsbMode, Word16 lastnz, Word16 *tns_order, Word16 fac_ns_idx, Word16 gg_idx, + Word16 BW_cutoff_idx, Word16 *ltpf_idx, Word32 *L_scf_idx, Word16 bfi_ext, Word16 fs_idx) +{ + Word16 tmp; + Word32 L_tmp; + Word16 submode_LSB, submode_MSB, gain_MSBs; + Word32 L_gain_LSB; + Counter n; + UWord8 *ptr; + + Word16 lastnzTrigger[5] = {63, 127, 127, 255, 255}; + +#ifdef DYNMEM_COUNT + struct _dynmem + { + Word16 tmp; + Word32 L_tmp; + Word16 submode_LSB, submode_MSB, gain_MSBs; + Word32 L_gain_LSB; + Counter n; + UWord8 *ptr; + Word16 lastnzTrigger[5]; + }; + Dyn_Mem_In("processEncoderEntropy", sizeof(struct _dynmem)); +#endif + + /* Init */ + *bp_side = shr_pos(sub(nbbits, 1), 3); + *mask_side = shl(1, sub(8, sub(nbbits, shl_pos(*bp_side, 3)))); + ptr = bytes; + + basop_memset(bytes, 0, targetBytes * sizeof(*bytes)); + + /* Cutoff-detection */ + IF (BW_cutoff_bits > 0) + { + write_indice_backward(ptr, bp_side, mask_side, BW_cutoff_idx, BW_cutoff_bits); + } + + /* Encode last non-zero tuple */ + tmp = sub(14, norm_s(negate(L_spec))); + + IF (sub(bfi_ext, 1) == 0) + { + write_indice_backward(ptr, bp_side, mask_side, lastnzTrigger[fs_idx], tmp); + } + ELSE + { + write_indice_backward(ptr, bp_side, mask_side, sub(shr_pos(lastnz, 1), 1), tmp); + } + + /* Mode bit */ + write_bit_backward(ptr, bp_side, mask_side, lsbMode); + + /* Encode global-gain */ + write_indice_backward(ptr, bp_side, mask_side, gg_idx, 8); + + /* TNS on/off flag */ + FOR (n = 0; n < tns_numfilters; n++) + { + write_bit_backward(ptr, bp_side, mask_side, s_min(tns_order[n], 1)); + } + + /* LTPF on/off*/ + write_indice_backward(ptr, bp_side, mask_side, ltpf_idx[0], 1); + + /* Encode SCF VQ parameters - 1st stage (10 bits) */ + write_indice_backward(ptr, bp_side, mask_side, extract_l(L_scf_idx[0]), 5); /* stage1 LF 5 bits */ + write_indice_backward(ptr, bp_side, mask_side, extract_l(L_scf_idx[1]), 5); /* stage1 HF 5 bits */ + + /* Encode SCF VQ parameters - 2nd stage side-info (3-4 bits) */ + submode_MSB = shr_pos(extract_l(L_scf_idx[2]), 1); /* explicit tx */ + write_bit_backward(ptr, bp_side, mask_side, submode_MSB); /* submode MSB 1 explicit bit */ + submode_LSB = s_and(extract_l(L_scf_idx[2]), 0x1); /* for joint coding with shapeCw */ + gain_MSBs = extract_l(L_scf_idx[3]); /* all gain bits */ + L_gain_LSB = L_and(L_scf_idx[3], 0x1L); + gain_MSBs = shr(gain_MSBs, sns_gainLSBbits[L_scf_idx[2]]); + + ASSERT(gain_MSBs >= 0 && gain_MSBs < (1 << sns_gainMSBbits[L_scf_idx[2]])); /* ASSERT max 2 MSB(s) in gain bits */ + + write_indice_backward(ptr, bp_side, mask_side, gain_MSBs, + sns_gainMSBbits[L_scf_idx[2]]); /* adjgain or MSBs of adjGains 1-2 bits */ + write_bit_backward(ptr, bp_side, mask_side, extract_l(L_scf_idx[4])); /* shape LS 1 bit */ + + /* Encode SCF VQ parameters - 2nd stage data (24-25 bits) */ + IF (submode_MSB == 0) + { /* regular,regular_lf*/ + ASSERT(submode_MSB == 0); + + L_tmp = L_add(L_gain_LSB, 0); /* gain-LSB 0,1 for regular_lf, offset is 0 */ + if (submode_LSB == 0) + { + L_tmp = L_add(L_scf_idx[6], + sns_MPVQ_Sz[1][1]); /* shape B pos offset is 2 , upshifted two positions , 0..11 -> 2..13 */ + } + /* regular mode A,B indexes multiplexed, total 24.x bits MPVQ codeword section A + codeword for section B */ + L_tmp = ac_enc_mux_st2VQ_cws(sns_MPVQ_Sz[0][0], /* max 21.3 bits*/ + UL_addNsD(sns_MPVQ_Sz[0][1], sns_MPVQ_Sz[1][1]), /* max log2(14) bits */ + L_scf_idx[5] /* shapeA */, L_tmp /* shapeB joint with adjGainLSB */); + /* regular mode mode shape index total 1+23.9999 bits MPVQ codeword */ + ASSERT(L_tmp < (1L << 25)); + write_indice_backward(ptr, bp_side, mask_side, extract_l(L_tmp), 13); /* multiplex 13 bits */ + write_indice_backward(ptr, bp_side, mask_side, extract_l(L_shr_pos(L_tmp, 13)), 12); /* multiplex 12 bits */ + } + ELSE + { /* outlier near, outlier far */ + ASSERT(submode_MSB == 1); + L_tmp = L_scf_idx[5]; move32(); /* outlier near section assumed */ + if (submode_LSB != 0) + { /* outl_far */ + L_tmp = L_add(L_shl_pos(L_tmp, 1), L_gain_LSB); /* add lsb bit of Gain */ + L_tmp = L_add(L_tmp, sns_MPVQ_Sz[2][0]); /* outlier far section offset added */ + } + + ASSERT(L_tmp < (1L << 24)); + /* outlier mode shape index total 23.8536 ( + ~.14 ) bits as MPVQ codeword */ + write_indice_backward(ptr, bp_side, mask_side, extract_l(L_tmp), 12); /* multiplex 12 bits LSB*/ + write_indice_backward(ptr, bp_side, mask_side, extract_l(L_shr(L_tmp, 12)), 12); /* multiplex 12 bits MSBs */ + } + + /* LTPF data */ + IF (ltpf_idx[0] != 0) + { + write_indice_backward(ptr, bp_side, mask_side, ltpf_idx[1], 1); + write_indice_backward(ptr, bp_side, mask_side, ltpf_idx[2], 9); + } + + /* Encoder noise-fac */ + write_indice_backward(ptr, bp_side, mask_side, fac_ns_idx, 3); + +#ifdef DYNMEM_COUNT + Dyn_Mem_Out(); +#endif +} + +static __forceinline Word32 +ac_enc_mux_st2VQ_cws( /* o: max 25 bits total codeword */ + const Word32 L_szA, /* i: max 22 bits */ + const Word32 L_szB, /* i: max 4 bits 0..13 */ + const Word32 L_cwA, + const Word32 L_cwB) /* [0..13} corresponding to gains{0,1}, shapeB{0..11} or */ +{ + + Word32 L_cwTx; + /* L_cw_tx = L_cwB(21.z bits) * L_szA(3.y bits) + L_cwA(21.x bits)); */ + L_cwTx = (Word32)UL_Mpy_32_32( + (UWord32)L_cwB, (UWord32)L_szA); /* non-fractional 16x32 -> 32 may possibly also be used if available */ + L_cwTx = L_add(L_cwTx, L_cwA); + + ASSERT((L_szA * L_szB) <= 1 << 25); /* multiplexing only allowed up to 25 bits (+ leading sign) */ + ASSERT(L_cwTx >= 0 && L_cwTx <= 0x01ffFFff); /* max 25 bits allowed */ + UNUSED(L_szB); + + return L_cwTx; +} diff --git a/lib_lc3plus/enc_lc3.c b/lib_lc3plus/enc_lc3.c new file mode 100644 index 0000000000000000000000000000000000000000..f2276a2ed91c6f42f18fa9704e74ff0d0e421ef1 --- /dev/null +++ b/lib_lc3plus/enc_lc3.c @@ -0,0 +1,680 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.5 * +* 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 "functions.h" +#include // ToDo: probably to be removed + +static void Enc_LC3PLUS_Channel(LC3PLUS_Enc *encoder, int channel, int bits_per_sample, Word32 *s_in, UWord8 *bytes, + Word8 *scratchBuffer, int bfi_ext) +{ +#ifdef ENABLE_HR_MODE + Dyn_Mem_Deluxe_In(Word16 d_fx_exp; + Word16 gain_e, gain, quantizedGain, quantizedGainMin; + Word16 ener_fx_exp; + Word16 pitch, normcorr; + Word16 ltpf_bits; + Word16 tns_numfilters; + Word16 lsbMode, lastnz, BW_cutoff_idx; + Word16 gainChange, fac_ns_idx; + Word16 nBits, numResBits; + Word16 bp_side, mask_side; + Word16 s_12k8_len; + Word16 b_left; + Word32 * L_scf_idx; + Word32 * d_fx, *ener_fx; + Word16 * s_12k8, *int_scf_fx_exp, tns_order[TNS_NUMFILTERS_MAX], *indexes; + Word32 * q_d_fx24; + Word16 * scf; + Word16 * codingdata; + Word32 * scf_q, *int_scf_fx; + Word32 * s_in_scaled; + Word16 * s_in_scaled_lp; + UWord8 * resBits; + Word16 ltpf_idx[3]; + EncSetup * h_EncSetup; + Word8 * currentScratch; + Word16 hrmode; + ); +#else + Dyn_Mem_Deluxe_In(Word16 d_fx_exp; Word16 gain_e, gain, quantizedGain, quantizedGainMin; Word16 ener_fx_exp; + Word16 pitch, normcorr; Word16 ltpf_bits; Word16 tns_numfilters; + Word16 lsbMode, lastnz, BW_cutoff_idx; Word16 gainChange, fac_ns_idx; Word16 nBits, numResBits; + Word16 bp_side, mask_side; Word16 s_12k8_len; Word16 b_left; + + Word32 * L_scf_idx; Word32 * d_fx, *ener_fx; + Word16 * s_12k8, *int_scf_fx_exp, *q_d_fx16, *int_scf_fx, tns_order[TNS_NUMFILTERS_MAX], *indexes; + Word16 * scf, *scf_q; Word16 * codingdata; Word16 * s_in_scaled; UWord8 * resBits; + Word8 * currentScratch; Word16 ltpf_idx[3]; EncSetup * h_EncSetup;); +#endif /* ENABLE_HR_MODE */ + + h_EncSetup = encoder->channel_setup[channel]; + +#ifdef ENABLE_HR_MODE +# ifdef CR8_F_ADAPT_MDCT_DCT_PRECISION + hrmode = encoder->hrmode; +# endif +#endif /* CR8_F_ADAPT_MDCT_DCT_PRECISION */ + +#ifdef WMOPS + push_wmops("Encoder"); +#endif + + /* BUFFER INITIALISATION. Some buffers may overlap since they are not used in the whole encoding process */ + d_fx = scratchAlign(scratchBuffer, 0); /* Size = 4 * MAX_LEN bytes */ + L_scf_idx = scratchAlign( + d_fx, sizeof(*d_fx) * s_max(80, encoder->frame_length)); /* Size = 4 * SCF_MAX_PARAM -> aligned to 32 bytes */ + indexes = scratchAlign(L_scf_idx, + sizeof(*L_scf_idx) * SCF_MAX_PARAM); /* Size = 2 * TNS_NUMFILTERS_MAX * MAXLAG = 32 bytes */ + +#ifdef ENABLE_HR_MODE + q_d_fx24 = scratchAlign(indexes, sizeof(*indexes) * (TNS_NUMFILTERS_MAX * MAXLAG)); +#else + q_d_fx16 = scratchAlign(indexes, sizeof(*indexes) * (TNS_NUMFILTERS_MAX * MAXLAG)); /* Size = 2 * MAX_LEN bytes */ +#endif /* ENABLE_HR_MODE */ + +#ifdef ENABLE_HR_MODE + codingdata = + scratchAlign(q_d_fx24, sizeof(*q_d_fx24) * s_max(80, encoder->frame_length)); /* Size = 3 * MAX_LEN bytes */ +#else + codingdata = + scratchAlign(q_d_fx16, sizeof(*q_d_fx16) * s_max(80, encoder->frame_length)); /* Size = 3 * MAX_LEN bytes */ +#endif + +#ifdef ENABLE_HR_MODE + ener_fx = scratchAlign(q_d_fx24, 0); /* Size = 4 * MAX_BANDS_NUMBER = 256 bytes */ + s_in_scaled = scratchAlign(q_d_fx24, 0); /* Size = 2 * MAX_LEN bytes */ +#else + ener_fx = scratchAlign(q_d_fx16, 0); /* Size = 4 * MAX_BANDS_NUMBER = 256 bytes */ + s_in_scaled = scratchAlign(q_d_fx16, 0); /* Size = 2 * MAX_LEN bytes */ +#endif + +#ifdef ENABLE_HR_MODE + s_in_scaled_lp = (Word16 *)s_in_scaled; +#endif + +#ifdef ENABLE_HR_MODE + /* allocate memory for residual bits */ + if (encoder->hrmode) + { + resBits = scratchAlign(codingdata, sizeof(*codingdata) * (3 * s_max(80, encoder->frame_length) / 2)); + } + else +#endif /* #ifdef ENABLE_HR_MODE */ + { + resBits = scratchAlign(codingdata, + sizeof(*codingdata) * (3 * s_max(80, encoder->frame_length) / 2)); /* Size = MAX_LEN bytes */ + } + + { +#ifdef ENABLE_HR_MODE + currentScratch = + scratchAlign(resBits, sizeof(*resBits) * MAX_RESBITS_LEN); /* Size = 4 * MAX_LEN */ +#else + currentScratch = + scratchAlign(resBits, sizeof(*resBits) * s_max(80, encoder->frame_length)); /* Size = 4 * MAX_LEN */ +#endif /* #ifdef ENABLE_HR_MODE */ + } + + s_12k8 = scratchAlign( + s_in_scaled, + sizeof(*s_in_scaled) * + s_max(80, encoder->frame_length)); /* Size = 2 * (LEN_12K8 + 1) = 258 bytes -> aligned to 288 bytes */ + scf_q = scratchAlign(ener_fx, sizeof(*ener_fx) * MAX_BANDS_NUMBER); /* Size = 2 * M */ + scf = scratchAlign(scf_q, sizeof(*scf_q) * M); /* Size = 2 * M */ + int_scf_fx = scratchAlign(scf, sizeof(*scf) * M); /* Size = 2 * MAX_BANDS_NUMBER = 128 bytes */ + int_scf_fx_exp = + scratchAlign(int_scf_fx, sizeof(*int_scf_fx) * MAX_BANDS_NUMBER); /* Size = 2 * MAX_BANDS_NUMBER = 128 bytes */ + + /* Scale 24-bit input data */ + IF (sub(bits_per_sample, 24) == 0) + { +#ifdef WMOPS + push_wmops("Scale_signal24"); +#endif + scale_signal24_fx(s_in, s_in_scaled, &h_EncSetup->x_exp, h_EncSetup->stEnc_mdct_mem, + encoder->stEnc_mdct_mem_len, h_EncSetup->r12k8_mem_in, encoder->r12k8_mem_in_len, + h_EncSetup->r12k8_mem_50, h_EncSetup->r12k8_mem_out, encoder->r12k8_mem_out_len, + h_EncSetup->mdct_mem32, encoder->frame_length, h_EncSetup->resamp_mem32, + h_EncSetup->olpa_mem_s12k8, &h_EncSetup->resamp_exp); +#ifdef WMOPS + pop_wmops(); +#endif + } + ELSE + { +#ifdef ENABLE_HR_MODE + Word16 *ip_buf = (Word16*)s_in; + Word32 i; + FOR(i = 0; i < encoder->frame_length; i++) + { + s_in_scaled[i] = L_deposit_h(ip_buf[i]); + } + h_EncSetup->x_exp = 15; move16(); +#else + memcpy(s_in_scaled, s_in, encoder->frame_length * sizeof(*s_in_scaled)); +#endif + } + +#ifdef WMOPS + push_wmops("Mdct"); +#endif + + /* currentScratch Size = 4 * MAX_LEN */ + processMdct_fx(s_in_scaled, h_EncSetup->x_exp, encoder->frame_length, +#ifdef ENABLE_HR_MODE +# ifdef CR8_F_ADAPT_MDCT_DCT_PRECISION + hrmode, +# endif +#endif + encoder->W_fx, encoder->W_size, + h_EncSetup->stEnc_mdct_mem, encoder->stEnc_mdct_mem_len, d_fx, &d_fx_exp, currentScratch); +#ifdef WMOPS + pop_wmops(); +#endif + + /* begin s_12k8 */ +#ifdef WMOPS + push_wmops("Resamp12k8"); +#endif + /* currentScratch Size = 2.25 * MAX_LEN bytes */ +#ifdef ENABLE_HR_MODE + downshift_w32_arr(s_in_scaled, s_in_scaled_lp, 16, encoder->frame_length); /* s_in_scaled is no longer required */ + + process_resamp12k8_fx(s_in_scaled_lp, encoder->frame_length, h_EncSetup->r12k8_mem_in, encoder->r12k8_mem_in_len, + h_EncSetup->r12k8_mem_50, h_EncSetup->r12k8_mem_out, encoder->r12k8_mem_out_len, s_12k8, + &s_12k8_len, encoder->fs_idx, encoder->frame_dms, currentScratch + , bits_per_sample + ); +#else + process_resamp12k8_fx(s_in_scaled, encoder->frame_length, h_EncSetup->r12k8_mem_in, encoder->r12k8_mem_in_len, + h_EncSetup->r12k8_mem_50, h_EncSetup->r12k8_mem_out, encoder->r12k8_mem_out_len, s_12k8, + &s_12k8_len, encoder->fs_idx, encoder->frame_dms, currentScratch + , bits_per_sample + ); +#endif /* ENABLE_HR_MODE */ +#ifdef WMOPS + pop_wmops(); +#endif + +#ifdef WMOPS + push_wmops("Olpa"); +#endif + /* currentScratch Size = 392 bytes */ + process_olpa_fx(&h_EncSetup->olpa_mem_s6k4_exp, h_EncSetup->olpa_mem_s12k8, h_EncSetup->olpa_mem_s6k4, &pitch, + s_12k8, s_12k8_len, &normcorr, &h_EncSetup->olpa_mem_pitch, +#ifdef CR9_F_PITCH_WIN_LEN_FIX + &h_EncSetup->pitch_flag, +#endif + h_EncSetup->resamp_exp, encoder->frame_dms, currentScratch); +#ifdef WMOPS + pop_wmops(); +#endif + +#ifdef WMOPS + push_wmops("LtpfEnc"); +#endif + /* currentScratch Size = 512 bytes */ + process_ltpf_coder_fx(<pf_bits, pitch, h_EncSetup->ltpf_enable, &h_EncSetup->ltpf_mem_in_exp, + h_EncSetup->ltpf_mem_in, encoder->ltpf_mem_in_len, ltpf_idx, s_12k8, s_12k8_len, + &h_EncSetup->ltpf_mem_normcorr, &h_EncSetup->ltpf_mem_mem_normcorr, normcorr, + &h_EncSetup->ltpf_mem_ltpf_on, &h_EncSetup->ltpf_mem_pitch, h_EncSetup->resamp_exp, + encoder->frame_dms, currentScratch +#ifdef CR9_K_REDUCE_NORM_CORR_TH + ,encoder->hrmode +#endif +); +#ifdef WMOPS + pop_wmops(); +#endif + + /* end s_12k8 */ +#ifdef WMOPS + push_wmops("AttackDetector"); +#endif + /* currentScratch Size = ??? bytes */ +#ifdef ENABLE_HR_MODE + attack_detector_fx(encoder, h_EncSetup, s_in_scaled_lp, sub(h_EncSetup->x_exp, 15), currentScratch); +#else + attack_detector_fx(encoder, h_EncSetup, s_in_scaled, sub(h_EncSetup->x_exp, 15), currentScratch); +#endif +#ifdef WMOPS + pop_wmops(); +#endif + + /* begin ener_fx */ +#ifdef WMOPS + push_wmops("PerBandEnergy"); +#endif + /* currentScratch Size = 160 bytes */ + processPerBandEnergy_fx(ener_fx, &ener_fx_exp, d_fx, d_fx_exp, encoder->bands_offset, encoder->fs_idx, + encoder->bands_number, 0, encoder->frame_dms, currentScratch +#ifdef ENABLE_HR_MODE + , encoder->hrmode +#endif + ); +#ifdef WMOPS + pop_wmops(); +#endif + +#ifdef WMOPS + push_wmops("Near Nyquist Detector"); +#endif + /* Near Nyquist Detector */ + processNearNyquistdetector_fx(&encoder->near_nyquist_flag, encoder->fs_idx, encoder->near_nyquist_index, + encoder->bands_number, ener_fx, ener_fx_exp +#ifdef CR8_E_TONE_DETECTOR +#ifdef ENABLE_HR_MODE + , encoder->frame_dms, encoder->hrmode ); +#else + ); +#endif +#else + ); +#endif + /* Disable LTPF if nyquist detector triggers */ + IF (encoder->near_nyquist_flag != 0 || sub(h_EncSetup->lfe, 1) == 0) + { + h_EncSetup->ltpf_mem_ltpf_on = 0; move16(); + ltpf_idx[1] = 0; move16(); + } +#ifdef WMOPS + pop_wmops(); +#endif +#ifdef WMOPS + push_wmops("BW Cutoff-Detection"); +#endif + IF (h_EncSetup->lfe == 0) + { +#ifdef ENABLE_HR_MODE + /* No BW Cutoff for 8 kHz and 96 kHz */ + IF (encoder->fs_idx > 0 && encoder->hrmode == 0 && encoder->bw_ctrl_active == 0) + { +#else /* ENABLE_HR_MODE */ + IF (encoder->fs_idx > 0 && encoder->bw_ctrl_active == 0) + { +#endif /* ENABLE_HR_MODE */ + processDetectCutoffWarped_fx(&BW_cutoff_idx, ener_fx, ener_fx_exp, encoder->fs_idx, encoder->frame_dms); + } + ELSE + { + BW_cutoff_idx = encoder->fs_idx; + move16(); + } + } + ELSE + { + BW_cutoff_idx = 0; + } +#ifdef WMOPS + pop_wmops(); +#endif + +#ifdef WMOPS + push_wmops("SnsCompScf"); +#endif + + + /* currentScratch Size = 512 bytes */ + processSnsComputeScf_fx(ener_fx, ener_fx_exp, encoder->fs_idx, encoder->bands_number, scf, + h_EncSetup->attdec_detected, encoder->attdec_damping, currentScratch, encoder->sns_damping + ); +#ifdef WMOPS + pop_wmops(); +#endif + +#ifdef WMOPS + push_wmops("SnsQuantScfEnc"); +#endif + /* currentScratch Size = 500 bytes */ + + processSnsQuantizeScfEncoder_fx(scf, L_scf_idx, scf_q, currentScratch); +#ifdef WMOPS + pop_wmops(); +#endif + +#ifdef WMOPS + push_wmops("SnsInterpScfEnc"); +#endif + /* currentScratch Size = 128 bytes */ + processSnsInterpolateScf_fx(scf_q, int_scf_fx, int_scf_fx_exp, 1, encoder->bands_number, currentScratch); +#ifdef WMOPS + pop_wmops(); +#endif + +#ifdef WMOPS + push_wmops("Mdct shaping_enc"); +#endif + processMdctShaping_fx(d_fx, int_scf_fx, int_scf_fx_exp, encoder->bands_offset, encoder->bands_number); + +#ifdef WMOPS + pop_wmops(); +#endif + /* end int_scf_fx_exp */ +#ifdef WMOPS + push_wmops("BandwidthControl_enc"); +#endif + if (encoder->bandwidth < L_shr_pos(encoder->fs, 1)) + { + process_cutoff_bandwidth(d_fx, encoder->yLen, encoder->bw_ctrl_cutoff_bin); + BW_cutoff_idx = s_min(BW_cutoff_idx, encoder->bw_index); + } +#ifdef WMOPS + pop_wmops(); +#endif +#ifdef WMOPS + push_wmops("Tns_enc"); +#endif + /* currentScratch Size = 2 * MAX_LEN + 220 */ + + IF (h_EncSetup->lfe == 0) + { + processTnsCoder_fx(&(h_EncSetup->tns_bits), indexes, d_fx, BW_cutoff_idx, tns_order, &tns_numfilters, + h_EncSetup->enable_lpc_weighting, encoder->nSubdivisions, encoder->frame_dms, + encoder->frame_length, currentScratch +#ifdef ENABLE_HR_MODE + , encoder->hrmode +#endif + , encoder->near_nyquist_flag + ); + } + ELSE + { + tns_numfilters = 1; + move16(); + tns_order[0] = 0; + move16(); + h_EncSetup->tns_bits = tns_numfilters; + move16(); + } +#ifdef WMOPS + pop_wmops(); +#endif + +#ifdef WMOPS + push_wmops("Est. Global Gain"); +#endif + /* currentScratch Size = 4 * MAX_LEN bytes */ + h_EncSetup->targetBitsQuant = sub(h_EncSetup->targetBitsInit, add(h_EncSetup->tns_bits, ltpf_bits)); + + test(); + IF (h_EncSetup->targetBitsQuant < 0 && sub(ltpf_bits, 1) > 0) + { + /* Disable LTPF */ + h_EncSetup->ltpf_mem_ltpf_on = 0; move16(); + ltpf_idx[1] = 0; move16(); + ltpf_bits = 1; move16(); + h_EncSetup->targetBitsQuant = sub(h_EncSetup->targetBitsInit, add(h_EncSetup->tns_bits, ltpf_bits)); + } + +#ifdef ENABLE_HR_MODE + Word32 gain32; +#endif + + processEstimateGlobalGain_fx(d_fx, d_fx_exp, encoder->yLen, h_EncSetup->targetBitsQuant, +#ifdef ENABLE_HR_MODE + &gain32, +#else + &gain, +#endif + &gain_e, + &quantizedGain, &quantizedGainMin, h_EncSetup->quantizedGainOff, + &h_EncSetup->targetBitsOff, &h_EncSetup->mem_targetBits, h_EncSetup->mem_specBits, + currentScratch +#ifdef ENABLE_HR_MODE + , encoder->hrmode, h_EncSetup->regBits, encoder->frame_dms +#endif + ); +#ifdef WMOPS + pop_wmops(); +#endif + /* begin q_d_fx16 */ + +#ifdef WMOPS + push_wmops("Quant. 1"); +#endif +#ifdef ENABLE_HR_MODE + processQuantizeSpec_fx(d_fx, d_fx_exp, gain32, gain_e, q_d_fx24, encoder->yLen, h_EncSetup->targetBitsQuant, + h_EncSetup->targetBitsAri, &h_EncSetup->mem_specBits, &nBits, encoder->fs_idx, &lastnz, + codingdata, &lsbMode, -1, encoder->hrmode); + +#else + processQuantizeSpec_fx(d_fx, d_fx_exp, gain, gain_e, q_d_fx16, encoder->yLen, h_EncSetup->targetBitsQuant, + h_EncSetup->targetBitsAri, &h_EncSetup->mem_specBits, &nBits, encoder->fs_idx, &lastnz, + codingdata, &lsbMode, -1); +#endif /* ENABLE_HR_MODE */ +#ifdef WMOPS + pop_wmops(); +#endif + +#ifdef WMOPS + push_wmops("Adj. Global Gain"); +#endif +#ifdef ENABLE_HR_MODE + //gain32 = L_shl_pos((Word32)gain, 16); + processAdjustGlobalGain_fx(&quantizedGain, quantizedGainMin, h_EncSetup->quantizedGainOff, &gain32, &gain_e, + h_EncSetup->targetBitsQuant, h_EncSetup->mem_specBits, &gainChange, encoder->fs_idx + , encoder->hrmode, encoder->frame_dms + ); + gain = round_fx(gain32); +#else + processAdjustGlobalGain_fx(&quantizedGain, quantizedGainMin, h_EncSetup->quantizedGainOff, &gain, &gain_e, + h_EncSetup->targetBitsQuant, h_EncSetup->mem_specBits, &gainChange, encoder->fs_idx); +#endif /* ENABLE_HR_MODE */ +#ifdef WMOPS + pop_wmops(); +#endif + +#ifdef WMOPS + push_wmops("Quant. 2"); +#endif + IF (sub(gainChange, 1) == 0) + { +#ifdef ENABLE_HR_MODE + processQuantizeSpec_fx(d_fx, d_fx_exp, gain32, gain_e, q_d_fx24, encoder->yLen, h_EncSetup->targetBitsQuant, + h_EncSetup->targetBitsAri, NULL, &nBits, encoder->fs_idx, &lastnz, codingdata, &lsbMode, + 0, encoder->hrmode); +#else + processQuantizeSpec_fx(d_fx, d_fx_exp, gain, gain_e, q_d_fx16, encoder->yLen, h_EncSetup->targetBitsQuant, + h_EncSetup->targetBitsAri, NULL, &nBits, encoder->fs_idx, &lastnz, codingdata, &lsbMode, + 0); +#endif /* ENABLE_HR_MODE */ + } +#ifdef WMOPS + pop_wmops(); +#endif + +#ifdef WMOPS + push_wmops("Res. Cod."); +#endif + IF (lsbMode == 0) + { + processResidualCoding_fx(d_fx_exp, d_fx, +#ifdef ENABLE_HR_MODE + q_d_fx24, +#else + q_d_fx16, +#endif +#ifdef ENABLE_HR_MODE + gain32, +#else + gain, +#endif + gain_e, encoder->yLen, h_EncSetup->targetBitsQuant, nBits, resBits, &numResBits +#ifdef ENABLE_HR_MODE + , encoder->hrmode +#endif + ); + } + ELSE + { + numResBits = 0; + move16(); + } +#ifdef WMOPS + pop_wmops(); +#endif + +#ifdef WMOPS + push_wmops("Noise fac"); +#endif + /* currentScratch Size = 2 * MAX_LEN bytes */ + IF (h_EncSetup->lfe == 0) + { + processNoiseFactor_fx(&fac_ns_idx, d_fx_exp, d_fx, +#ifdef ENABLE_HR_MODE + q_d_fx24, +#else + q_d_fx16, +#endif + gain, gain_e, BW_cutoff_idx, encoder->frame_dms, h_EncSetup->targetBytes, currentScratch +#ifdef ENABLE_HR_MODE + , encoder->hrmode +#endif + ); + } + ELSE + { + fac_ns_idx = 7; + move16(); + } +#ifdef WMOPS + pop_wmops(); +#endif + +#ifdef WMOPS + push_wmops("Entropy cod"); +#endif + processEncoderEntropy(bytes, &bp_side, &mask_side, h_EncSetup->targetBitsAri, h_EncSetup->targetBytes, + encoder->yLen, encoder->BW_cutoff_bits, tns_numfilters, lsbMode, lastnz, tns_order, + fac_ns_idx, quantizedGain, BW_cutoff_idx, ltpf_idx, L_scf_idx, bfi_ext, encoder->fs_idx); +#ifdef WMOPS + pop_wmops(); +#endif + +#ifdef WMOPS + push_wmops("Ari cod"); +#endif + processAriEncoder_fx(bytes, bp_side, mask_side, h_EncSetup->targetBitsAri, +#ifdef ENABLE_HR_MODE + q_d_fx24, +#else + q_d_fx16, +#endif + tns_order, tns_numfilters, indexes, lastnz, codingdata, resBits, numResBits, lsbMode, + h_EncSetup->enable_lpc_weighting, currentScratch); +#ifdef WMOPS + pop_wmops(); +#endif + +#ifdef WMOPS + push_wmops("Reorder Bitstream Enc"); +#endif + test(); + IF (encoder->combined_channel_coding == 0 && h_EncSetup->n_pc > 0) + { +#ifdef WMOPS + push_wmops("Reorder Ari dec"); +#endif + +#ifdef ENABLE_HR_MODE + Word32 *xbuf = (Word32 *) scratchAlign(scratchBuffer, 0); + + processAriDecoder_fx(bytes, &bp_side, &mask_side, h_EncSetup->total_bits, encoder->yLen, encoder->fs_idx, + h_EncSetup->enable_lpc_weighting, tns_numfilters, lsbMode, lastnz, &gain, tns_order, + fac_ns_idx, quantizedGain, encoder->frame_dms, h_EncSetup->n_pc, 0, + shr_pos(h_EncSetup->total_bits, 3), 1, &gain, &b_left, &gain, + xbuf, + &gain, resBits, indexes, &gain, + currentScratch + , encoder->hrmode + ); +#else + + processAriDecoder_fx(bytes, &bp_side, &mask_side, h_EncSetup->total_bits, encoder->yLen, encoder->fs_idx, + h_EncSetup->enable_lpc_weighting, tns_numfilters, lsbMode, lastnz, &gain, tns_order, + fac_ns_idx, quantizedGain, encoder->frame_dms, h_EncSetup->n_pc, 0, + shr_pos(h_EncSetup->total_bits, 3), 1, &gain, &b_left, &gain, + codingdata, + &gain, resBits, indexes, &gain, + currentScratch + ); +#endif + +#ifdef WMOPS + pop_wmops(); /* Ari dec */ +#endif + processReorderBitstream_fx(bytes, h_EncSetup->n_pccw, h_EncSetup->n_pc, b_left, currentScratch); + } +#ifdef WMOPS + pop_wmops(); +#endif + + /* end q_d_fx16 */ +#ifdef WMOPS + pop_wmops(); +#endif + + Dyn_Mem_Deluxe_Out(); +} + +int Enc_LC3PLUS(LC3PLUS_Enc *encoder, void **input, int bits_per_sample, UWord8 *output, void *scratch, Word16 bfi_ext) +{ + int ch = 0, output_size = 0; + int input_size = 0; + int totalBytes = (Word32)encoder->bitrate * encoder->frame_length / (8 * encoder->fs_in); + int output_size2; + + UWord8 *lc3buf = output; + + for (ch = 0; ch < encoder->channels; ch++) + { + Enc_LC3PLUS_Channel(encoder, ch, bits_per_sample, input[ch], lc3buf, scratch, bfi_ext); + if (encoder->epmode && encoder->combined_channel_coding == 0) + { + output_size2 = totalBytes / encoder->channels + (ch < (totalBytes % encoder->channels)); +#ifdef WMOPS + push_wmops("fec_enc"); +#endif + + fec_encoder(encoder->epmode, encoder->epmr, lc3buf, encoder->channel_setup[ch]->targetBytes, output_size2, + encoder->channel_setup[ch]->n_pccw, scratch); + +#ifdef WMOPS + pop_wmops(); +#endif + + lc3buf += output_size2; + output_size += output_size2; + } + else + { + lc3buf += encoder->channel_setup[ch]->targetBytes; + output_size += encoder->channel_setup[ch]->targetBytes; + } + } + + if (encoder->epmode > 0 && encoder->combined_channel_coding) + { + input_size = output_size; + output_size = (Word32)encoder->bitrate * encoder->frame_length / (8 * encoder->fs_in); +#ifdef WMOPS + push_wmops("fec_enc"); +#endif + + fec_encoder(encoder->epmode, encoder->epmr, output, input_size, output_size, encoder->channel_setup[0]->n_pccw, + scratch); + +#ifdef WMOPS + pop_wmops(); +#endif + } + + return output_size; +} + diff --git a/lib_lc3plus/estimate_global_gain_fx.c b/lib_lc3plus/estimate_global_gain_fx.c new file mode 100644 index 0000000000000000000000000000000000000000..c6d1766b43d2fdac7e8500cddde1215766bb671c --- /dev/null +++ b/lib_lc3plus/estimate_global_gain_fx.c @@ -0,0 +1,506 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.5 * +* 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 "functions.h" + +void processEstimateGlobalGain_fx(Word32 x[], Word16 x_e, Word16 lg, Word16 nbitsSQ, +#ifdef ENABLE_HR_MODE + Word32 *gain, +#else + Word16 *gain, +#endif + Word16 *gain_e, + Word16 *quantizedGain, Word16 *quantizedGainMin, Word16 quantizedGainOff, + Word32 *targetBitsOff, Word16 *old_targetBits, Word16 old_specBits, + Word8 *scratchBuffer +#ifdef ENABLE_HR_MODE + , Word16 hrmode, Word16 regBits, Word16 frame_dms +#endif +) +{ + + Word16 lg_4, tmp16, iszero, s; + Word32 ener, tmp32, x_max; + Word32 target, fac, offset; + Word32 *en; + Counter iter, i; + Word32 diff, diff2; +#ifdef ENABLE_HR_MODE + Word16 *en_exp = NULL; + Word32 M0, M1; +#endif + +#ifdef DYNMEM_COUNT + Dyn_Mem_In("processEstimateGlobalGain_fx", sizeof(struct { + Word16 lg_4, s, tmp16, iszero; + Word32 ener, tmp32, x_max; + Word32 target, fac, offset; + Word32 *en; + Counter i, iter; + Word32 diff, diff2; + })); +#endif + + en = (Word32 *)scratchAlign(scratchBuffer, + 0); /* Size = MAX_LEN bytes */ + +#ifdef ENABLE_HR_MODE + if (hrmode) + { + M0 = 1; + M1 = 1; /* Regularization factor; needs´to be 1e-5, but 1e-5 is 0 in Q15 */ + en_exp = (Word16 *) scratchAlign(en, sizeof(*en) * MAX_LEN); + } +#endif + IF (*old_targetBits < 0) + { + *targetBitsOff = 0; + move16(); + } + ELSE + { + tmp32 = L_add(*targetBitsOff, L_deposit_h(sub(*old_targetBits, old_specBits))); + tmp32 = L_min((40 << 16), L_max(-(40 << 16), tmp32)); + *targetBitsOff = L_add(Mpy_32_16_lc3plus(*targetBitsOff, 26214), Mpy_32_16_lc3plus(tmp32, 6554)); + move16(); + } + + *old_targetBits = nbitsSQ; + move16(); + nbitsSQ = add(nbitsSQ, round_fx(*targetBitsOff)); + + lg_4 = shr_pos(lg, 2); + x_max = 0; + move32(); + +/* energy of quadruples with 9dB offset */ +#ifdef ENABLE_HR_MODE + IF (hrmode) + { + FOR (i = 0; i < lg_4; i++) + { + Word32 absval; + Word16 idx; + /* normalization */ + s = 31; + move16(); + + /* M1 requires a 32x16 mult with Q0 i, resulting in Q15. Keeping both M0 and M1 in same Q */ + /* Use Q15 for M0 and M1 calculation */ + idx = shl(i, 2); + + tmp32 = L_abs(x[0]); + absval = L_shr(tmp32, 16); + M0 = L_add(M0, absval); /* M0 += fabs(x[idx])*/ + M1 = L_add(M1, L_mult(absval, idx)); /* M1 += i*fabs(x[idx])*/ + idx = add(idx, 1); + + absval = L_abs(x[1]); + tmp32 = L_max(tmp32, absval); + absval = L_shr(tmp32, 16); + M0 = L_add(M0, absval); /* M0 += fabs(x[idx])*/ + M1 = L_add(M1, L_mult(absval, idx)); /* M1 += idx*fabs(x[idx])*/ + idx = add(idx, 1); + + absval = L_abs(x[2]); + tmp32 = L_max(tmp32, absval); + absval = L_shr(tmp32, 16); + M0 = L_add(M0, absval); /* M0 += fabs(x[idx])*/ + M1 = L_add(M1, L_mult(absval, idx)); /* M1 += idx*fabs(x[idx])*/ + idx = add(idx, 1); + + absval = L_abs(x[3]); + tmp32 = L_max(tmp32, absval); + absval = L_shr(tmp32, 16); + M0 = L_add(M0, absval); /* M0 += fabs(x[idx])*/ + M1 = L_add(M1, L_mult(absval, idx)); /* M1 += idx*fabs(x[idx])*/ + + x_max = L_max(x_max, tmp32); + + if (tmp32 != 0) + s = norm_l(tmp32); + + s = sub(s, 2); /* 2 bits headroom */ + + /* calc quadruple energy */ + ener = L_deposit_l(1); + + tmp16 = round_fx(L_shl(x[0], s)); + ener = L_mac(ener, tmp16, tmp16); + + tmp16 = round_fx(L_shl(x[1], s)); + ener = L_mac(ener, tmp16, tmp16); + + tmp16 = round_fx(L_shl(x[2], s)); + ener = L_mac(ener, tmp16, tmp16); + + tmp16 = round_fx(L_shl(x[3], s)); + ener = L_mac(ener, tmp16, tmp16); + + s = shl_pos(sub(x_e, s), 1); + if (ener == 1 && s < 0) + s = 0; + IF (regBits > 0) + { + en[i] = ener; + en_exp[i] = s; + move32(); + } + ELSE + { + /* log */ + tmp32 = L_add(BASOP_Util_Log2_lc3plus(ener), L_shl_pos(L_deposit_l(s), 25)); /* log2, 6Q25 */ + tmp32 = L_add(L_shr_pos(Mpy_32_16_lc3plus(tmp32, 0x436E), 7), + 0x4E666); /* -> (28/20)*(7+10*tmp32/log2(10)), 16Q15 */ + en[i] = tmp32; + move32(); + } + + x += 4; + } + } + ELSE +#endif + { + FOR (i = 0; i < lg_4; i++) + { + /* normalization */ + s = 31; + move16(); + + tmp32 = L_abs(x[0]); + tmp32 = L_max(tmp32, L_abs(x[1])); + tmp32 = L_max(tmp32, L_abs(x[2])); + tmp32 = L_max(tmp32, L_abs(x[3])); + x_max = L_max(x_max, tmp32); + + if (tmp32 != 0) + s = norm_l(tmp32); + + s = sub(s, 2); /* 2 bits headroom */ + + /* calc quadruple energy */ + ener = L_deposit_l(1); + + tmp16 = round_fx(L_shl(x[0], s)); + ener = L_mac(ener, tmp16, tmp16); + + tmp16 = round_fx(L_shl(x[1], s)); + ener = L_mac(ener, tmp16, tmp16); + + tmp16 = round_fx(L_shl(x[2], s)); + ener = L_mac(ener, tmp16, tmp16); + + tmp16 = round_fx(L_shl(x[3], s)); + ener = L_mac(ener, tmp16, tmp16); + + s = shl_pos(sub(x_e, s), 1); + if (ener == 1 && s < 0) + s = 0; + + /* log */ + tmp32 = L_add_sat(BASOP_Util_Log2_lc3plus(ener), L_shl_sat(L_deposit_l(s), 25)); /* log2, 6Q25 */ + tmp32 = + L_add(L_shr_pos(Mpy_32_16_lc3plus(tmp32, 0x436E), 6), 0x9CCCD); /* -> (28/20)*(7+10*tmp32/log2(10)), 15Q16 */ + en[i] = tmp32; + move32(); + x += 4; + } + } + + IF (x_max == 0) + { + *quantizedGainMin = quantizedGainOff; + move16(); + *quantizedGain = 0; + move16(); + *old_targetBits = -1; + move16(); + } + ELSE + { + Word32 sub_val = 0xFCDD38F; + /*28 * log10(32767 - 0.375) * (1 - 1e-7) in Q21 */ + +#ifdef ENABLE_HR_MODE + if (hrmode) + { + /* + Original float code : + rB_offset = 8 * (1 - MIN(M1/M0, 2*frame_ms)/(2*frame_ms) + */ + Word16 ratio; + Word16 ratio_exp = 0; + Word32 regterm = MAX_32; /* 1 in Q31 */ + Word32 rB_offset, reg_val; + Word32 ratio_prod; + Word16 n_reg_val; + + if (M0 <= 0x7fff) + { + Word16 inv_M0 = Inv16_lc3plus(M0, &ratio_exp); /* Inverse in Q(15 - ratio_exp) */ + ratio = L_shr(Mpy_32_16_lc3plus(M1, inv_M0), 15 - ratio_exp); /* Integer ratio */ + } + else + { + Word16 M0_h = L_shr(M0, 15); + Word32 M1_h = L_shr(M1, 15); + + Word16 inv_M0 = Inv16_lc3plus(M0_h, &ratio_exp); /* Inverse in Q(15 - ratio_exp) */ + ratio = extract_l(L_shr(Mpy_32_16_lc3plus(M1_h, inv_M0), 15 - ratio_exp)); /* Integer ratio */ + } + + /* + regterm = MIN (M1 / M0, 2 *frame_ms) / (2 * frame_ms) + regterm = MIN (M1 * (10 / 2) / M0, frame_dms) / frame_dms + regterm = MIN ( ratio * 5, frame_dms) / frame_dms + */ + + ratio_prod = L_mult(ratio, 5); + + if (ratio_prod < frame_dms) + { + Word16 mult_factor = 0; + + SWITCH (frame_dms) /* 1 / frame_dms in Q15 */ + { + case 25: mult_factor = 1311; break; + case 50: mult_factor = 655; break; +#ifdef CR8_G_ADD_75MS + case 75: mult_factor = 437; break; +#endif + case 100: mult_factor = 328; break; + } + + /* ratio_prod < frame_dms. Hence Word16 can be used */ + + regterm = L_shl(L_mult(extract_l(ratio_prod), mult_factor), 15); /* result in Q31 */ + } + + rB_offset = L_sub(MAX_32, regterm); + /* Calculation in Q28 to prevent overflow. Subtraction result in Q31, downshift by 3 results in Q28. + Multiplication by 8 is implemented as upshift by 3. + */ + + /* + FLOAT code : reg_val = x_max * LC3_POW(2,-regBits - rB_offset); + */ + Word16 reg_val_e = x_e; + + IF(rB_offset > 0) + { + Word32 reg_exp = L_negate(L_add(L_shl(regBits, 25), L_shr(rB_offset, 3))); + reg_val = Mpy_32_32_lc3plus(x_max, BASOP_Util_InvLog2_lc3plus(reg_exp)); /* Product is in Q31 */ + /* reg_val is in Q(31-x_e) */ + } + ELSE + { + reg_val = x_max; + reg_val_e = sub(x_e, regBits); + } + + sub_val = 0x183BA045; + move16(); + /*28 * log10(32768*256 - 2) in Q21 */ + + /* + Adding LC3_POW(2, -31) to reg_val.2^-31 * 2^(31-x_e) = 2^-x_e. + If x_e is positive, this is below precision requirements to be used. + */ + + if (reg_val_e < 0) + { + reg_val = L_add_sat(reg_val, L_shl_sat(1, negate(reg_val_e))); + } + n_reg_val = norm_l(reg_val); + + FOR (i = 0; i < lg_4; i++) + { + ener = en[i]; + move16(); + s = en_exp[i]; + move16(); + + Word16 shift_val = sub(reg_val_e, s); + + IF (sub(n_reg_val, shift_val) > 0) + { + IF(shift_val > -32) + { + ener = L_add(ener, L_shl(reg_val, shift_val)); /* Match q formats */ + } + } + ELSE + { + IF (sub(shift_val, 32) >= 0 ) + { + ener = reg_val; + } + ELSE + { + ener = L_add_sat(reg_val, L_shr(ener, shift_val)); + } + s = reg_val_e; + } + + tmp32 = L_add(BASOP_Util_Log2_lc3plus(ener), L_shl_pos(L_deposit_l(s), 25)); /* log2, 6Q25 */ + tmp32 = L_add(L_shr_pos(Mpy_32_32_lc3plus(tmp32, 0x436E439A), 7), 0x4E666); /* -> (28/20)*(7+10*tmp32/log2(10)), 15Q16 */ + en[i] = tmp32; + move32(); + } + } +#endif + x_max = BASOP_Util_Log2_lc3plus(x_max); + /* Minimum gain */ + x_max = L_add(x_max, L_shl_pos(L_deposit_l(x_e), 25)); /* log2(x_max) in 6Q25 */ + x_max = L_sub( + Mpy_32_32_lc3plus(x_max, 0x436E439A), + sub_val); /* 28*log10(x_max/(32768-0.375)) = log2(x_max)*(28/log2(10))-28*log10(32768-0.375) in 10Q21 */ + /* 28/log1(10) is in Q27 + Mpy_32_32_lc3plus : Q25(x_max) + Q27 + Q1(Mpy_32_32_ss) - Q32 = Q21 */ + *quantizedGainMin = extract_l(L_shr_pos(L_add(x_max, (1 << 21) + (1 << 11)), 21)); + move16(); + ASSERT(*quantizedGainMin <= 255 + quantizedGainOff); + *quantizedGainMin = s_max(quantizedGainOff, s_min(add(255, quantizedGainOff), *quantizedGainMin)); + + offset = L_deposit_h(add(255, quantizedGainOff)); /* -> 127 */ + +#ifdef ENABLE_HR_MODE + IF(hrmode) + { + offset = L_shr_pos(offset, 2); + /* SQ scale: 4 bits / 6 dB per quadruple */ + target = L_mult(0x3EB8, nbitsSQ); /* -> (28/20) * (1.4) * nbitsSQ */ + + fac = L_add(0x400000, 0); /* -> 256 */ + /* find offset (0 to 127) */ + FOR (iter = 0; iter < 8; iter++) + { + fac = L_shr_pos(fac, 1); + offset = L_sub(offset, fac); + + ener = L_deposit_l(0); + iszero = 1; + move16(); + + FOR (i = lg_4 - 1; i >= 0; i--) + { + tmp32 = L_sub(L_shr_pos(en[i], 1), offset); + diff = L_sub(tmp32, 0x27333); /* 0x4E666 -> (28/20)*(7) in Q15 */ + if (diff < 0) + { + if (iszero == 0) + { + ener = L_add(ener, 0xF1EC); /* 0x1E3D7 -> (28/20)*(2.7) in Q15 */ + } + } + else + { + ener = L_add(ener, tmp32); + iszero = 0; + move16(); + + diff2 = L_sub(tmp32, 0x118000); /* 0x230000 -> (28/20)*(50) */ + if (diff2 >= 0) + { + ener = L_add(ener, diff2); + } + } + } + + /* if ener is above target -> increase offset */ + test(); + if (L_sub(ener, target) > 0 && iszero == 0) + { + offset = L_add(offset, fac); + } + } + tmp16 = extract_h(L_shl(offset, 2)); + } + ELSE +#endif + { + /* SQ scale: 4 bits / 6 dB per quadruple */ + target = L_shl_pos(L_mult(0x7D71, nbitsSQ), 1); /* -> (28/20) * (1.4) * nbitsSQ */ + fac = L_add(0x1000000, 0); /* -> 256 */ + + /* find offset (0 to 127) */ + FOR (iter = 0; iter < 8; iter++) + { + fac = L_shr_pos(fac, 1); + offset = L_sub(offset, fac); + + ener = L_deposit_l(0); + iszero = 1; + move16(); + FOR (i = lg_4 - 1; i >= 0; i--) + { + tmp32 = L_sub(en[i], offset); + diff = L_sub(tmp32, 0x9CCCD); /* 0x9CCCD -> (28/20)*(7) in Q16 */ + if (diff < 0) + { + if (iszero == 0) + { + ener = L_add_sat(ener, 0x3C7AE); /* 0x3C7AE -> (28/20)*(2.7) in Q16 */ + } + } + else + { + ener = L_add_sat(ener, tmp32); + iszero = 0; + move16(); + + diff2 = L_sub(tmp32, 0x460000); /* 0x460000 -> (28/20)*(50) in Q16 */ + if (diff2 >= 0) + { + ener = L_add_sat(ener, diff2); + } + } + + } + + /* if ener is above target -> increase offset */ + test(); + if (L_sub(ener, target) > 0 && iszero == 0) + { + offset = L_add(offset, fac); + } + } + tmp16 = extract_h(offset); + + } + + if (sub(tmp16, *quantizedGainMin) < 0) + { + *old_targetBits = -1; + move16(); + } + *quantizedGain = sub(s_max(*quantizedGainMin, tmp16), quantizedGainOff); + move16(); + } + +#ifdef ENABLE_HR_MODE + tmp32 = + Mpy_32_16_lc3plus(0x797CD707, L_shl_pos(add(*quantizedGain, quantizedGainOff), 6)); +#else + tmp32 = + L_shl_pos(L_mult0(add(*quantizedGain, quantizedGainOff), 0x797D), 7); /* 6Q25; 0x797D -> log2(10)/28 (Q18) */ +#endif + *gain_e = add(extract_l(L_shr_pos(tmp32, 25)), 1); /* get exponent */ +#ifdef ENABLE_HR_MODE + *gain = BASOP_Util_InvLog2_lc3plus(L_or(tmp32, (Word32)0xFE000000)); +#else + *gain = round_fx(BASOP_Util_InvLog2_lc3plus(L_or(tmp32,(Word32) 0xFE000000))); +#endif + +#ifdef DYNMEM_COUNT + Dyn_Mem_Out(); +#endif +} + diff --git a/lib_lc3plus/fft_lc3plus.c b/lib_lc3plus/fft_lc3plus.c new file mode 100644 index 0000000000000000000000000000000000000000..6db6de7bb6e7b5a74b6c91d6d44d178a7cc270b7 --- /dev/null +++ b/lib_lc3plus/fft_lc3plus.c @@ -0,0 +1,4537 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.5 * +* 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 "functions.h" +#include "rom_basop_util_lc3plus.h" + +#ifdef ENABLE_FFT_RESCALE +#ifndef FFT_RESCALE_HR +#define FFT_RESCALE_HR 3 +#endif +#endif + +#define SCALEFACTORN2 3 +#define SCALEFACTOR4 3 +#define SCALEFACTOR5 4 +#define SCALEFACTOR8 4 +#define SCALEFACTOR15 5 +#define SCALEFACTOR30_1 5 +#define SCALEFACTOR30_2 1 +#define SCALEFACTOR32_1 5 +#define SCALEFACTOR32_2 1 + +#ifdef ENABLE_HR_MODE +#define Mpy_32_xx Mpy_32_32_lc3plus +#else +#define Mpy_32_xx Mpy_32_16_lc3plus +#endif + +#ifdef CR8_G_ADD_75MS +#define SCALEFACTOR6 4 +#define C61_32 (0x6ed9eba1) +#endif + +#define SCALEFACTOR10 5 +#define SCALEFACTOR16 5 +#define SCALEFACTOR20 5 +#define SCALEFACTOR30 6 +#define SCALEFACTOR32 6 +#define SCALEFACTOR40 7 +#define SCALEFACTOR48 8 +#define SCALEFACTOR60 7 +#define SCALEFACTOR64 7 +#define SCALEFACTOR80 8 +#define SCALEFACTOR90 9 +#define SCALEFACTOR96 9 +#define SCALEFACTOR120 8 +#define SCALEFACTOR128 8 +#define SCALEFACTOR160 8 +#define SCALEFACTOR180 10 +#define SCALEFACTOR192 10 +#define SCALEFACTOR240 9 +#define SCALEFACTOR256 9 +#define SCALEFACTOR384 11 + +#ifdef ENABLE_HR_MODE +#ifdef CR8_G_ADD_75MS +#define SCALEFACTOR360 11 +#endif +#ifndef ENABLE_FFT_30X16 +#define SCALEFACTOR480 10 +#else +#define SCALEFACTOR480 11 +#endif +#endif + +#ifdef ENABLE_HR_MODE +#undef L_shr_pos +#define L_shr_pos(x, y) (L_shr(L_add(L_shr((x), ((y)-1)),1),1)) +#endif + +#ifdef ENABLE_HR_MODE +#define FFTC(x) ((Word32)x) +#else +#define FFTC(x) WORD322WORD16((Word32)x) +#endif + +#define C31 (FFTC(0x91261468)) /* FL2WORD32( -0.86602540) -sqrt(3)/2 */ + +#define C51 (FFTC(0x79bc3854)) /* FL2WORD32( 0.95105652) */ +#define C52 (FFTC(0x9d839db0)) /* FL2WORD32(-1.53884180/2) */ +#define C53 (FFTC(0xd18053ce)) /* FL2WORD32(-0.36327126) */ +#define C54 (FFTC(0x478dde64)) /* FL2WORD32( 0.55901699) */ +#define C55 (FFTC(0xb0000001)) /* FL2WORD32(-1.25/2) */ + +#define C81 (FFTC(0x5a82799a)) /* FL2WORD32( 7.071067811865475e-1) */ +#define C82 (FFTC(0xa57d8666)) /* FL2WORD32(-7.071067811865475e-1) */ + +#define C161 (FFTC(0x5a82799a)) /* FL2WORD32( 7.071067811865475e-1) INV_SQRT2 */ +#define C162 (FFTC(0xa57d8666)) /* FL2WORD32(-7.071067811865475e-1) -INV_SQRT2 */ + +#define C163 (FFTC(0x7641af3d)) /* FL2WORD32( 9.238795325112867e-1) COS_PI_DIV8 */ +#define C164 (FFTC(0x89be50c3)) /* FL2WORD32(-9.238795325112867e-1) -COS_PI_DIV8 */ + +#define C165 (FFTC(0x30fbc54d)) /* FL2WORD32( 3.826834323650898e-1) COS_3PI_DIV8 */ +#define C166 (FFTC(0xcf043ab3)) /* FL2WORD32(-3.826834323650898e-1) -COS_3PI_DIV8 */ + +#define C51_32 (0x79bc3854) /* FL2WORD32( 0.95105652) */ +#define C52_32 (0x9d839db0) /* FL2WORD32(-1.53884180/2) */ +#define C53_32 (0xd18053ce) /* FL2WORD32(-0.36327126) */ +#define C54_32 (0x478dde64) /* FL2WORD32( 0.55901699) */ +#define C55_32 (0xb0000001) /* FL2WORD32(-1.25/2) */ + + +#define C81_32 (0x5a82799a) /* FL2WORD32( 7.071067811865475e-1) */ +#define C82_32 (0xa57d8666) /* FL2WORD32(-7.071067811865475e-1) */ + +#if defined(ENABLE_HR_MODE) + +# define cplxMpy4_16_0(re, im, a, b, c, d) \ + do \ + { \ + re = L_sub(Mpy_32_xx(a, c), Mpy_32_xx(b, d)); \ + move32(); \ + im = L_add(Mpy_32_xx(a, d), Mpy_32_xx(b, c)); \ + move32(); \ + } while (0) + +# define cplxMpy4_16_1(re, im, a, b) \ + do \ + { \ + re = a; \ + move32(); \ + im = b; \ + move32(); \ + } while (0) + +# endif + +#define Mpy3_0(s12, s13, s14, s15, t0, t1, t2, t3) \ + do \ + { \ + s12 = Mpy_32_32_lc3plus(L_add(t0, t2), C81_32); \ + s14 = Mpy_32_32_lc3plus(L_sub(t0, t2), C81_32); \ + s13 = Mpy_32_32_lc3plus(L_sub(t3, t1), C81_32); \ + s15 = Mpy_32_32_lc3plus(L_add(t1, t3), C82_32); \ + } while (0) + +#define cplxMpy3_0(a, b, c, d) \ + do \ + { \ + as = L_shr_pos(a, 1); \ + bs = L_shr_pos(b, 1); \ + a = L_sub(Mpy_32_32_lc3plus(as, c), Mpy_32_32_lc3plus(bs, d)); \ + b = L_add(Mpy_32_32_lc3plus(as, d), Mpy_32_32_lc3plus(bs, c)); \ + } while (0) + +#ifdef ENABLE_HR_MODE +#define cplxMpy4_4_0(re, im, a, b, c, d) \ + re = L_shr_pos(L_sub(Mpy_32_xx(a, c), Mpy_32_xx(b, d)), SCALEFACTOR60 - SCALEFACTOR15); \ + im = L_shr_pos(L_add(Mpy_32_xx(a, d), Mpy_32_xx(b, c)), SCALEFACTOR60 - SCALEFACTOR15); + +# define cplxMpy4_4_1(re, im, a, b) \ + re = L_shr_pos(a, SCALEFACTOR60 - SCALEFACTOR15); \ + im = L_shr_pos(b, SCALEFACTOR60 - SCALEFACTOR15); +#else +#define cplxMpy4_4_0(re, im, a, b, c, d) \ + re = L_shr(L_sub(Mpy_32_xx(a, c), Mpy_32_xx(b, d)), SCALEFACTOR60 - SCALEFACTOR15); \ + im = L_shr(L_add(Mpy_32_xx(a, d), Mpy_32_xx(b, c)), SCALEFACTOR60 - SCALEFACTOR15); + +#define cplxMpy4_4_1(re, im, a, b) \ + re = L_shr(a, SCALEFACTOR60 - SCALEFACTOR15); \ + im = L_shr(b, SCALEFACTOR60 - SCALEFACTOR15); +#endif + +#define cplxMpy4_8_0(re, im, a, b, c, d) \ + do \ + { \ + re = L_shr_pos(L_sub(Mpy_32_xx(a, c), Mpy_32_xx(b, d)), 1); \ + im = L_shr_pos(L_add(Mpy_32_xx(a, d), Mpy_32_xx(b, c)), 1); \ + } while (0) + + +#define cplxMpy4_8_1(re, im, a, b) \ + do \ + { \ + re = L_shr_pos(a, 1); \ + im = L_shr_pos(b, 1); \ + } while (0) + + +#define cplxMpy4_8_2(re, im, a, b, c, d) \ + do \ + { \ + re = L_shr_pos(L_add(Mpy_32_32_lc3plus(a, c), Mpy_32_32_lc3plus(b, d)), 1); \ + im = L_shr_pos(L_sub(Mpy_32_32_lc3plus(b, c), Mpy_32_32_lc3plus(a, d)), 1); \ + } while (0) + + +#define cplxMpy4_12_0(re, im, a, b, c, d) \ + do \ + { \ + re = L_sub(Mpy_32_xx(a, c), Mpy_32_xx(b, d)); \ + move32(); \ + im = L_add(Mpy_32_xx(a, d), Mpy_32_xx(b, c)); \ + move32(); \ + } while (0) + +#define cplxMpy4_12_1(re, im, a, b) \ + do \ + { \ + re = a; \ + move32(); \ + im = b; \ + move32(); \ + } while (0) + + +static void fft4(Word32 *x) +{ + Dyn_Mem_Deluxe_In(Word32 x0, x1, x2, x3, x4, x5, x6, x7; Word32 t0, t1, t2, t3, t4, t5, t6, t7;); + + x0 = L_shr_pos(x[0], SCALEFACTOR4); + x1 = L_shr_pos(x[1], SCALEFACTOR4); + x2 = L_shr_pos(x[2], SCALEFACTOR4); + x3 = L_shr_pos(x[3], SCALEFACTOR4); + x4 = L_shr_pos(x[4], SCALEFACTOR4); + x5 = L_shr_pos(x[5], SCALEFACTOR4); + x6 = L_shr_pos(x[6], SCALEFACTOR4); + x7 = L_shr_pos(x[7], SCALEFACTOR4); + + /* Pre-additions */ + t0 = L_add(x0, x4); + t2 = L_sub(x0, x4); + t1 = L_add(x1, x5); + t3 = L_sub(x1, x5); + t4 = L_add(x2, x6); + t7 = L_sub(x2, x6); + t5 = L_add(x7, x3); + t6 = L_sub(x7, x3); + + /* Post-additions */ + x[0] = L_add(t0, t4); + x[1] = L_add(t1, t5); + x[2] = L_sub(t2, t6); + x[3] = L_sub(t3, t7); + x[4] = L_sub(t0, t4); + x[5] = L_sub(t1, t5); + x[6] = L_add(t2, t6); + x[7] = L_add(t3, t7); + + Dyn_Mem_Deluxe_Out(); +} + +/** + * \brief Function performs a complex 5-point FFT + * The FFT is performed inplace. The result of the FFT + * is scaled by SCALEFACTOR5 bits. + * + * + * \param [i/o] re real input / output + * \param [i/o] im imag input / output + * \param [i ] s stride real and imag input / output + * + * \return void + */ + + + +static void fft5(Word32 *re, Word32 *im, Word16 s) +{ + Dyn_Mem_Deluxe_In(Word32 x0, x1, x2, x3, x4; Word32 r1, r2, r3, r4; Word32 s1, s2, s3, s4; Word32 t;); + + /* real part */ + x0 = L_shr_pos(re[s * 0], SCALEFACTOR5); + x1 = L_shr_pos(re[s * 1], SCALEFACTOR5); + x2 = L_shr_pos(re[s * 2], SCALEFACTOR5); + x3 = L_shr_pos(re[s * 3], SCALEFACTOR5); + x4 = L_shr_pos(re[s * 4], SCALEFACTOR5); + + r1 = L_add(x1, x4); + r4 = L_sub(x1, x4); + r3 = L_add(x2, x3); + r2 = L_sub(x2, x3); + t = Mpy_32_32_lc3plus(L_sub(r1, r3), C54_32); + r1 = L_add(r1, r3); + re[0] = L_add(x0, r1); + move32(); + /* Bit shift left because of the constant C55 which was scaled with the factor 0.5 because of the representation of + the values as fracts */ + r1 = L_add(re[0], (L_shl_pos(Mpy_32_32_lc3plus(r1, C55_32), 1))); + r3 = L_sub(r1, t); + r1 = L_add(r1, t); + t = Mpy_32_32_lc3plus(L_add(r4, r2), C51_32); + /* Bit shift left because of the constant C55 which was scaled with the factor 0.5 because of the representation of + the values as fracts */ + r4 = L_add(t, L_shl_pos(Mpy_32_32_lc3plus(r4, C52_32), 1)); + r2 = L_add(t, Mpy_32_32_lc3plus(r2, C53_32)); + + /* imaginary part */ + x0 = L_shr_pos(im[s * 0], SCALEFACTOR5); + x1 = L_shr_pos(im[s * 1], SCALEFACTOR5); + x2 = L_shr_pos(im[s * 2], SCALEFACTOR5); + x3 = L_shr_pos(im[s * 3], SCALEFACTOR5); + x4 = L_shr_pos(im[s * 4], SCALEFACTOR5); + + s1 = L_add(x1, x4); + s4 = L_sub(x1, x4); + s3 = L_add(x2, x3); + s2 = L_sub(x2, x3); + t = Mpy_32_32_lc3plus(L_sub(s1, s3), C54_32); + s1 = L_add(s1, s3); + im[0] = L_add(x0, s1); + move32(); + /* Bit shift left because of the constant C55 which was scaled with the factor 0.5 because of the representation of + the values as fracts */ + s1 = L_add(im[0], L_shl_pos(Mpy_32_32_lc3plus(s1, C55_32), 1)); + s3 = L_sub(s1, t); + s1 = L_add(s1, t); + t = Mpy_32_32_lc3plus(L_add(s4, s2), C51_32); + /* Bit shift left because of the constant C55 which was scaled with the factor 0.5 because of the representation of + the values as fracts */ + s4 = L_add(t, L_shl_pos(Mpy_32_32_lc3plus(s4, C52_32), 1)); + s2 = L_add(t, Mpy_32_32_lc3plus(s2, C53_32)); + + /* combination */ + re[s * 1] = L_add(r1, s2); + move32(); + re[s * 4] = L_sub(r1, s2); + move32(); + re[s * 2] = L_sub(r3, s4); + move32(); + re[s * 3] = L_add(r3, s4); + move32(); + + im[s * 1] = L_sub(s1, r2); + move32(); + im[s * 4] = L_add(s1, r2); + move32(); + im[s * 2] = L_add(s3, r4); + move32(); + im[s * 3] = L_sub(s3, r4); + move32(); + + Dyn_Mem_Deluxe_Out(); +} + +/** + * \brief Function performs a complex 6-point FFT + * The FFT is performed inplace. The result of the FFT + * is scaled by SCALEFACTOR6 bits. + * + * + * \param [i/o] re real input / output + * \param [i/o] im imag input / output + * \param [i ] st stride real and imag input / output + * + * \return void + */ + +#ifdef CR8_G_ADD_75MS +static void fft6(Word32 *re, Word32 *im, Word16 st) +{ + Dyn_Mem_Deluxe_In(Word32 x0, x1, x2, x3, x4, x5; Word32 r1o, r2o, i1e, i2e, i1o, i2o; Word32 t, s;); + + /* process real parts */ + + x0 = L_shr_pos(re[0 * st], SCALEFACTOR6); + x1 = L_shr_pos(re[1 * st], SCALEFACTOR6); + x2 = L_shr_pos(re[2 * st], SCALEFACTOR6); + x3 = L_shr_pos(re[3 * st], SCALEFACTOR6); + x4 = L_shr_pos(re[4 * st], SCALEFACTOR6); + x5 = L_shr_pos(re[5 * st], SCALEFACTOR6); + + t = L_add(x0, L_add(x2, x4)); + s = L_add(x1, L_add(x3, x5)); + re[0 * st] = L_add(t, s); + move32(); + re[3 * st] = L_sub(t, s); + move32(); + t = L_sub(x0, L_shr_pos(L_add(x2, x4), 1)); + + re[1 * st] = t; + move32(); + re[2 * st] = t; + move32(); + re[4 * st] = t; + move32(); + re[5 * st] = t; + move32(); + + s = Mpy_32_32_lc3plus(L_sub(x4, x2), C61_32); + + i1e = s; + i2e = -s; + + t = L_sub(x1, L_shr_pos(L_add(x3, x5), 1)); + s = Mpy_32_32_lc3plus(L_sub(x5, x3), C61_32); + + r1o = r2o = t; + i1o = s; + i2o = -s; + + x0 = L_shr_pos(im[0 * st], SCALEFACTOR6); + x1 = L_shr_pos(im[1 * st], SCALEFACTOR6); + x2 = L_shr_pos(im[2 * st], SCALEFACTOR6); + x3 = L_shr_pos(im[3 * st], SCALEFACTOR6); + x4 = L_shr_pos(im[4 * st], SCALEFACTOR6); + x5 = L_shr_pos(im[5 * st], SCALEFACTOR6); + + t = L_add(x0, L_add(x2, x4)); + s = L_add(x1, L_add(x3, x5)); + + im[0 * st] = L_add(t, s); + move32(); + im[3 * st] = L_sub(t, s); + move32(); + + t = Mpy_32_32_lc3plus(L_sub(x2, x4), C61_32); + s = L_sub(x0, L_shr_pos(L_add(x2, x4), 1)); + + re[1 * st] = L_add(re[1 * st], t); + move32(); + re[2 * st] = L_sub(re[2 * st], t); + move32(); + re[4 * st] = L_add(re[4 * st], t); + move32(); + re[5 * st] = L_sub(re[5 * st], t); + move32(); + + i1e = L_add(i1e, s); + i2e = L_add(i2e, s); + + t = Mpy_32_32_lc3plus(L_sub(x3, x5), C61_32); + s = L_sub(x1, L_shr_pos(L_add(x5, x3), 1)); + + r1o = L_add(r1o, t); + r2o = L_sub(r2o, t); + + i1o = L_add(i1o, s); + i2o = L_add(i2o, s); + + t = L_add(L_shr_pos(r1o, 1), Mpy_32_32_lc3plus(i1o, C61_32)); + s = L_sub(L_shr_pos(i1o, 1), Mpy_32_32_lc3plus(r1o, C61_32)); + + re[1 * st] = L_add(re[1 * st], t); + move32(); + im[1 * st] = L_add(i1e, s); + move32(); + + re[4 * st] = L_sub(re[4 * st], t); + move32(); + im[4 * st] = L_sub(i1e, s); + move32(); + + t = L_sub(Mpy_32_32_lc3plus(i2o, C61_32), L_shr_pos(r2o, 1)); + s = L_negate(L_add(Mpy_32_32_lc3plus(r2o, C61_32), L_shr_pos(i2o, 1))); + + re[2 * st] = L_add(re[2 * st], t); + move32(); + im[2 * st] = L_add(i2e, s); + move32(); + + re[5 * st] = L_sub(re[5 * st], t); + move32(); + im[5 * st] = L_sub(i2e, s); + move32(); + + Dyn_Mem_Deluxe_Out(); +} +#endif + +/** + * \brief Function performs a complex 8-point FFT + * The FFT is performed inplace. The result of the FFT + * is scaled by SCALEFACTOR8 bits. + * + * WOPS with 32x16 bit multiplications: 108 cycles + * + * \param [i/o] re real input / output + * \param [i/o] im imag input / output + * \param [i ] s stride real and imag input / output + * + * \return void + */ + + +static void fft8(Word32 *re, Word32 *im, Word16 s) +{ + Dyn_Mem_Deluxe_In(Word32 x00, x01, x02, x03, x04, x05, x06, x07; Word32 x08, x09, x10, x11, x12, x13, x14, x15; + Word32 t00, t01, t02, t03, t04, t05, t06, t07; Word32 t08, t09, t10, t11, t12, t13, t14, t15; + Word32 s00, s01, s02, s03, s04, s05, s06, s07; Word32 s08, s09, s10, s11, s12, s13, s14, s15;); + + /* Pre-additions */ + + x00 = L_shr_pos(re[s * 0], SCALEFACTOR8); + x01 = L_shr_pos(im[s * 0], SCALEFACTOR8); + x02 = L_shr_pos(re[s * 1], SCALEFACTOR8); + x03 = L_shr_pos(im[s * 1], SCALEFACTOR8); + x04 = L_shr_pos(re[s * 2], SCALEFACTOR8); + x05 = L_shr_pos(im[s * 2], SCALEFACTOR8); + x06 = L_shr_pos(re[s * 3], SCALEFACTOR8); + x07 = L_shr_pos(im[s * 3], SCALEFACTOR8); + x08 = L_shr_pos(re[s * 4], SCALEFACTOR8); + x09 = L_shr_pos(im[s * 4], SCALEFACTOR8); + x10 = L_shr_pos(re[s * 5], SCALEFACTOR8); + x11 = L_shr_pos(im[s * 5], SCALEFACTOR8); + x12 = L_shr_pos(re[s * 6], SCALEFACTOR8); + x13 = L_shr_pos(im[s * 6], SCALEFACTOR8); + x14 = L_shr_pos(re[s * 7], SCALEFACTOR8); + x15 = L_shr_pos(im[s * 7], SCALEFACTOR8); + + t00 = L_add(x00, x08); + t02 = L_sub(x00, x08); + t01 = L_add(x01, x09); + t03 = L_sub(x01, x09); + t04 = L_add(x02, x10); + t06 = L_sub(x02, x10); + t05 = L_add(x03, x11); + t07 = L_sub(x03, x11); + t08 = L_add(x04, x12); + t10 = L_sub(x04, x12); + t09 = L_add(x05, x13); + t11 = L_sub(x05, x13); + t12 = L_add(x06, x14); + t14 = L_sub(x06, x14); + t13 = L_add(x07, x15); + t15 = L_sub(x07, x15); + + /* Pre-additions and core multiplications */ + + s00 = L_add(t00, t08); + s04 = L_sub(t00, t08); + s01 = L_add(t01, t09); + s05 = L_sub(t01, t09); + s08 = L_sub(t02, t11); + s10 = L_add(t02, t11); + s09 = L_add(t03, t10); + s11 = L_sub(t03, t10); + s02 = L_add(t04, t12); + s07 = L_sub(t04, t12); + s03 = L_add(t05, t13); + s06 = L_sub(t13, t05); + + t01 = L_add(t06, t14); + t02 = L_sub(t06, t14); + t00 = L_add(t07, t15); + t03 = L_sub(t07, t15); + + s12 = Mpy_32_xx(L_add(t00, t02), C81); + s14 = Mpy_32_xx(L_sub(t00, t02), C81); + s13 = Mpy_32_xx(L_sub(t03, t01), C81); + s15 = Mpy_32_xx(L_add(t01, t03), C82); + + /* Post-additions */ + + re[s * 0] = L_add(s00, s02); + move32(); + re[s * 4] = L_sub(s00, s02); + move32(); + im[s * 0] = L_add(s01, s03); + move32(); + im[s * 4] = L_sub(s01, s03); + move32(); + re[s * 2] = L_sub(s04, s06); + move32(); + re[s * 6] = L_add(s04, s06); + move32(); + im[s * 2] = L_sub(s05, s07); + move32(); + im[s * 6] = L_add(s05, s07); + move32(); + re[s * 3] = L_add(s08, s14); + move32(); + re[s * 7] = L_sub(s08, s14); + move32(); + im[s * 3] = L_add(s09, s15); + move32(); + im[s * 7] = L_sub(s09, s15); + move32(); + re[s * 1] = L_add(s10, s12); + move32(); + re[s * 5] = L_sub(s10, s12); + move32(); + im[s * 1] = L_add(s11, s13); + move32(); + im[s * 5] = L_sub(s11, s13); + move32(); + + Dyn_Mem_Deluxe_Out(); +} + +/** + * \brief Function performs a complex 10-point FFT + * The FFT is performed inplace. The result of the FFT + * is scaled by SCALEFACTOR10 bits. + * + * WOPS with 32x16 bit multiplications: 196 cycles + * + * \param [i/o] re real input / output + * \param [i/o] im imag input / output + * \param [i ] s stride real and imag input / output + * + * \return void + */ + + + +static void fft10(Word32 *re, Word32 *im, Word16 s) +{ + Dyn_Mem_Deluxe_In(Word32 t; Word32 x0, x1, x2, x3, x4; Word32 r1, r2, r3, r4; Word32 s1, s2, s3, s4; + Word32 y00, y01, y02, y03, y04, y05, y06, y07, y08, y09; + Word32 y10, y11, y12, y13, y14, y15, y16, y17, y18, y19;); + + /* 2 fft5 stages */ + + /* real part */ + x0 = L_shr_pos(re[s * 0], SCALEFACTOR10); + x1 = L_shr_pos(re[s * 2], SCALEFACTOR10); + x2 = L_shr_pos(re[s * 4], SCALEFACTOR10); + x3 = L_shr_pos(re[s * 6], SCALEFACTOR10); + x4 = L_shr_pos(re[s * 8], SCALEFACTOR10); + + r1 = L_add(x3, x2); + r4 = L_sub(x3, x2); + r3 = L_add(x1, x4); + r2 = L_sub(x1, x4); + t = Mpy_32_xx(L_sub(r1, r3), C54); + r1 = L_add(r1, r3); + y00 = L_add(x0, r1); + r1 = L_add(y00, (L_shl_pos(Mpy_32_xx(r1, C55), 1))); + r3 = L_sub(r1, t); + r1 = L_add(r1, t); + t = Mpy_32_xx((L_add(r4, r2)), C51); + r4 = L_add(t, L_shl_pos(Mpy_32_xx(r4, C52), 1)); + r2 = L_add(t, Mpy_32_xx(r2, C53)); + + /* imaginary part */ + x0 = L_shr_pos(im[s * 0], SCALEFACTOR10); + x1 = L_shr_pos(im[s * 2], SCALEFACTOR10); + x2 = L_shr_pos(im[s * 4], SCALEFACTOR10); + x3 = L_shr_pos(im[s * 6], SCALEFACTOR10); + x4 = L_shr_pos(im[s * 8], SCALEFACTOR10); + + s1 = L_add(x3, x2); + s4 = L_sub(x3, x2); + s3 = L_add(x1, x4); + s2 = L_sub(x1, x4); + t = Mpy_32_xx(L_sub(s1, s3), C54); + s1 = L_add(s1, s3); + y01 = L_add(x0, s1); + s1 = L_add(y01, L_shl_pos(Mpy_32_xx(s1, C55), 1)); + s3 = L_sub(s1, t); + s1 = L_add(s1, t); + t = Mpy_32_xx(L_add(s4, s2), C51); + s4 = L_add(t, L_shl_pos(Mpy_32_xx(s4, C52), 1)); + s2 = L_add(t, Mpy_32_xx(s2, C53)); + + /* combination */ + y04 = L_add(r1, s2); + y16 = L_sub(r1, s2); + y08 = L_sub(r3, s4); + y12 = L_add(r3, s4); + + y05 = L_sub(s1, r2); + y17 = L_add(s1, r2); + y09 = L_add(s3, r4); + y13 = L_sub(s3, r4); + + /* real part */ + x0 = L_shr_pos(re[s * 5], SCALEFACTOR10); + x1 = L_shr_pos(re[s * 1], SCALEFACTOR10); + x2 = L_shr_pos(re[s * 3], SCALEFACTOR10); + x3 = L_shr_pos(re[s * 7], SCALEFACTOR10); + x4 = L_shr_pos(re[s * 9], SCALEFACTOR10); + + r1 = L_add(x1, x4); + r4 = L_sub(x1, x4); + r3 = L_add(x3, x2); + r2 = L_sub(x3, x2); + t = Mpy_32_xx(L_sub(r1, r3), C54); + r1 = L_add(r1, r3); + y02 = L_add(x0, r1); + r1 = L_add(y02, (L_shl_pos(Mpy_32_xx(r1, C55), 1))); + r3 = L_sub(r1, t); + r1 = L_add(r1, t); + t = Mpy_32_xx((L_add(r4, r2)), C51); + r4 = L_add(t, L_shl_pos(Mpy_32_xx(r4, C52), 1)); + r2 = L_add(t, Mpy_32_xx(r2, C53)); + + /* imaginary part */ + x0 = L_shr_pos(im[s * 5], SCALEFACTOR10); + x1 = L_shr_pos(im[s * 1], SCALEFACTOR10); + x2 = L_shr_pos(im[s * 3], SCALEFACTOR10); + x3 = L_shr_pos(im[s * 7], SCALEFACTOR10); + x4 = L_shr_pos(im[s * 9], SCALEFACTOR10); + + s1 = L_add(x1, x4); + s4 = L_sub(x1, x4); + s3 = L_add(x3, x2); + s2 = L_sub(x3, x2); + t = Mpy_32_xx(L_sub(s1, s3), C54); + s1 = L_add(s1, s3); + y03 = L_add(x0, s1); + s1 = L_add(y03, L_shl_pos(Mpy_32_xx(s1, C55), 1)); + s3 = L_sub(s1, t); + s1 = L_add(s1, t); + t = Mpy_32_xx(L_add(s4, s2), C51); + s4 = L_add(t, L_shl_pos(Mpy_32_xx(s4, C52), 1)); + s2 = L_add(t, Mpy_32_xx(s2, C53)); + + /* combination */ + y06 = L_add(r1, s2); + y18 = L_sub(r1, s2); + y10 = L_sub(r3, s4); + y14 = L_add(r3, s4); + + y07 = L_sub(s1, r2); + y19 = L_add(s1, r2); + y11 = L_add(s3, r4); + y15 = L_sub(s3, r4); + + /* 5 fft2 stages */ + re[s * 0] = L_add(y00, y02); + move32(); + im[s * 0] = L_add(y01, y03); + move32(); + re[s * 5] = L_sub(y00, y02); + move32(); + im[s * 5] = L_sub(y01, y03); + move32(); + + re[s * 2] = L_add(y04, y06); + move32(); + im[s * 2] = L_add(y05, y07); + move32(); + re[s * 7] = L_sub(y04, y06); + move32(); + im[s * 7] = L_sub(y05, y07); + move32(); + + re[s * 4] = L_add(y08, y10); + move32(); + im[s * 4] = L_add(y09, y11); + move32(); + re[s * 9] = L_sub(y08, y10); + move32(); + im[s * 9] = L_sub(y09, y11); + move32(); + + re[s * 6] = L_add(y12, y14); + move32(); + im[s * 6] = L_add(y13, y15); + move32(); + re[s * 1] = L_sub(y12, y14); + move32(); + im[s * 1] = L_sub(y13, y15); + move32(); + + re[s * 8] = L_add(y16, y18); + move32(); + im[s * 8] = L_add(y17, y19); + move32(); + re[s * 3] = L_sub(y16, y18); + move32(); + im[s * 3] = L_sub(y17, y19); + move32(); + + Dyn_Mem_Deluxe_Out(); +} + +/** + * \brief Function performs a complex 15-point FFT + * The FFT is performed inplace. The result of the FFT + * is scaled by SCALEFACTOR15 bits. + * + * WOPS with 32x16 bit multiplications: 354 cycles + * + * \param [i/o] re real input / output + * \param [i/o] im imag input / output + * \param [i ] s stride real and imag input / output + * + * \return void + */ + + +static void fft15(Word32 *re, Word32 *im, Word16 s) +{ + Dyn_Mem_Deluxe_In(Word32 t; Word32 r1, r2, r3, r4; Word32 s1, s2, s3, s4; + Word32 x00, x01, x02, x03, x04, x05, x06, x07, x08, x09; + Word32 x10, x11, x12, x13, x14, x15, x16, x17, x18, x19; + Word32 x20, x21, x22, x23, x24, x25, x26, x27, x28, x29; + Word32 y00, y01, y02, y03, y04, y05, y06, y07, y08, y09; + Word32 y10, y11, y12, y13, y14, y15, y16, y17, y18, y19; + Word32 y20, y21, y22, y23, y24, y25, y26, y27, y28, y29;); + + x00 = L_shr_pos(re[s * 0], SCALEFACTOR15); + x01 = L_shr_pos(im[s * 0], SCALEFACTOR15); + x02 = L_shr_pos(re[s * 3], SCALEFACTOR15); + x03 = L_shr_pos(im[s * 3], SCALEFACTOR15); + x04 = L_shr_pos(re[s * 6], SCALEFACTOR15); + x05 = L_shr_pos(im[s * 6], SCALEFACTOR15); + x06 = L_shr_pos(re[s * 9], SCALEFACTOR15); + x07 = L_shr_pos(im[s * 9], SCALEFACTOR15); + x08 = L_shr_pos(re[s * 12], SCALEFACTOR15); + x09 = L_shr_pos(im[s * 12], SCALEFACTOR15); + + x10 = L_shr_pos(re[s * 5], SCALEFACTOR15); + x11 = L_shr_pos(im[s * 5], SCALEFACTOR15); + x12 = L_shr_pos(re[s * 8], SCALEFACTOR15); + x13 = L_shr_pos(im[s * 8], SCALEFACTOR15); + x14 = L_shr_pos(re[s * 11], SCALEFACTOR15); + x15 = L_shr_pos(im[s * 11], SCALEFACTOR15); + x16 = L_shr_pos(re[s * 14], SCALEFACTOR15); + x17 = L_shr_pos(im[s * 14], SCALEFACTOR15); + x18 = L_shr_pos(re[s * 2], SCALEFACTOR15); + x19 = L_shr_pos(im[s * 2], SCALEFACTOR15); + + x20 = L_shr_pos(re[s * 10], SCALEFACTOR15); + x21 = L_shr_pos(im[s * 10], SCALEFACTOR15); + x22 = L_shr_pos(re[s * 13], SCALEFACTOR15); + x23 = L_shr_pos(im[s * 13], SCALEFACTOR15); + x24 = L_shr_pos(re[s * 1], SCALEFACTOR15); + x25 = L_shr_pos(im[s * 1], SCALEFACTOR15); + x26 = L_shr_pos(re[s * 4], SCALEFACTOR15); + x27 = L_shr_pos(im[s * 4], SCALEFACTOR15); + x28 = L_shr_pos(re[s * 7], SCALEFACTOR15); + x29 = L_shr_pos(im[s * 7], SCALEFACTOR15); + + /* 1. FFT5 stage */ + + /* real part */ + r1 = L_add(x02, x08); + r4 = L_sub(x02, x08); + r3 = L_add(x04, x06); + r2 = L_sub(x04, x06); + t = Mpy_32_xx(L_sub(r1, r3), C54); + r1 = L_add(r1, r3); + y00 = L_add(x00, r1); + r1 = L_add(y00, (L_shl_pos(Mpy_32_xx(r1, C55), 1))); + r3 = L_sub(r1, t); + r1 = L_add(r1, t); + t = Mpy_32_xx((L_add(r4, r2)), C51); + r4 = L_add(t, L_shl_pos(Mpy_32_xx(r4, C52), 1)); + r2 = L_add(t, Mpy_32_xx(r2, C53)); + + /* imaginary part */ + s1 = L_add(x03, x09); + s4 = L_sub(x03, x09); + s3 = L_add(x05, x07); + s2 = L_sub(x05, x07); + t = Mpy_32_xx(L_sub(s1, s3), C54); + s1 = L_add(s1, s3); + y01 = L_add(x01, s1); + s1 = L_add(y01, L_shl_pos(Mpy_32_xx(s1, C55), 1)); + s3 = L_sub(s1, t); + s1 = L_add(s1, t); + t = Mpy_32_xx(L_add(s4, s2), C51); + s4 = L_add(t, L_shl_pos(Mpy_32_xx(s4, C52), 1)); + s2 = L_add(t, Mpy_32_xx(s2, C53)); + + /* combination */ + y02 = L_add(r1, s2); + y08 = L_sub(r1, s2); + y04 = L_sub(r3, s4); + y06 = L_add(r3, s4); + + y03 = L_sub(s1, r2); + y09 = L_add(s1, r2); + y05 = L_add(s3, r4); + y07 = L_sub(s3, r4); + + /* 2. FFT5 stage */ + + /* real part */ + r1 = L_add(x12, x18); + r4 = L_sub(x12, x18); + r3 = L_add(x14, x16); + r2 = L_sub(x14, x16); + t = Mpy_32_xx(L_sub(r1, r3), C54); + r1 = L_add(r1, r3); + y10 = L_add(x10, r1); + r1 = L_add(y10, (L_shl_pos(Mpy_32_xx(r1, C55), 1))); + r3 = L_sub(r1, t); + r1 = L_add(r1, t); + t = Mpy_32_xx((L_add(r4, r2)), C51); + r4 = L_add(t, L_shl_pos(Mpy_32_xx(r4, C52), 1)); + r2 = L_add(t, Mpy_32_xx(r2, C53)); + + /* imaginary part */ + s1 = L_add(x13, x19); + s4 = L_sub(x13, x19); + s3 = L_add(x15, x17); + s2 = L_sub(x15, x17); + t = Mpy_32_xx(L_sub(s1, s3), C54); + s1 = L_add(s1, s3); + y11 = L_add(x11, s1); + s1 = L_add(y11, L_shl_pos(Mpy_32_xx(s1, C55), 1)); + s3 = L_sub(s1, t); + s1 = L_add(s1, t); + t = Mpy_32_xx(L_add(s4, s2), C51); + s4 = L_add(t, L_shl_pos(Mpy_32_xx(s4, C52), 1)); + s2 = L_add(t, Mpy_32_xx(s2, C53)); + + /* combination */ + y12 = L_add(r1, s2); + y18 = L_sub(r1, s2); + y14 = L_sub(r3, s4); + y16 = L_add(r3, s4); + + y13 = L_sub(s1, r2); + y19 = L_add(s1, r2); + y15 = L_add(s3, r4); + y17 = L_sub(s3, r4); + + /* 3. FFT5 stage */ + + /* real part */ + r1 = L_add(x22, x28); + r4 = L_sub(x22, x28); + r3 = L_add(x24, x26); + r2 = L_sub(x24, x26); + t = Mpy_32_xx(L_sub(r1, r3), C54); + r1 = L_add(r1, r3); + y20 = L_add(x20, r1); + r1 = L_add(y20, (L_shl_pos(Mpy_32_xx(r1, C55), 1))); + r3 = L_sub(r1, t); + r1 = L_add(r1, t); + t = Mpy_32_xx((L_add(r4, r2)), C51); + r4 = L_add(t, L_shl_pos(Mpy_32_xx(r4, C52), 1)); + r2 = L_add(t, Mpy_32_xx(r2, C53)); + + /* imaginary part */ + s1 = L_add(x23, x29); + s4 = L_sub(x23, x29); + s3 = L_add(x25, x27); + s2 = L_sub(x25, x27); + t = Mpy_32_xx(L_sub(s1, s3), C54); + s1 = L_add(s1, s3); + y21 = L_add(x21, s1); + s1 = L_add(y21, L_shl_pos(Mpy_32_xx(s1, C55), 1)); + s3 = L_sub(s1, t); + s1 = L_add(s1, t); + t = Mpy_32_xx(L_add(s4, s2), C51); + s4 = L_add(t, L_shl_pos(Mpy_32_xx(s4, C52), 1)); + s2 = L_add(t, Mpy_32_xx(s2, C53)); + + /* combination */ + y22 = L_add(r1, s2); + y28 = L_sub(r1, s2); + y24 = L_sub(r3, s4); + y26 = L_add(r3, s4); + + y23 = L_sub(s1, r2); + y29 = L_add(s1, r2); + y25 = L_add(s3, r4); + y27 = L_sub(s3, r4); + + /* 1. FFT3 stage */ + + /* real part */ + r1 = L_add(y10, y20); + r2 = Mpy_32_xx(L_sub(y10, y20), C31); + re[s * 0] = L_add(y00, r1); + move32(); + r1 = L_sub(y00, L_shr_pos(r1, 1)); + + /* imaginary part */ + s1 = L_add(y11, y21); + s2 = Mpy_32_xx(L_sub(y11, y21), C31); + im[s * 0] = L_add(y01, s1); + move32(); + s1 = L_sub(y01, L_shr_pos(s1, 1)); + + /* combination */ + re[s * 10] = L_sub(r1, s2); + move32(); + re[s * 5] = L_add(r1, s2); + move32(); + im[s * 10] = L_add(s1, r2); + move32(); + im[s * 5] = L_sub(s1, r2); + move32(); + + /* 2. FFT3 stage */ + + /* real part */ + r1 = L_add(y12, y22); + r2 = Mpy_32_xx(L_sub(y12, y22), C31); + re[s * 6] = L_add(y02, r1); + move32(); + r1 = L_sub(y02, L_shr_pos(r1, 1)); + + /* imaginary part */ + s1 = L_add(y13, y23); + s2 = Mpy_32_xx(L_sub(y13, y23), C31); + im[s * 6] = L_add(y03, s1); + move32(); + s1 = L_sub(y03, L_shr_pos(s1, 1)); + + /* combination */ + re[s * 1] = L_sub(r1, s2); + move32(); + re[s * 11] = L_add(r1, s2); + move32(); + im[s * 1] = L_add(s1, r2); + move32(); + im[s * 11] = L_sub(s1, r2); + move32(); + + /* 3. FFT3 stage */ + + /* real part */ + r1 = L_add(y14, y24); + r2 = Mpy_32_xx(L_sub(y14, y24), C31); + re[s * 12] = L_add(y04, r1); + move32(); + r1 = L_sub(y04, L_shr_pos(r1, 1)); + + /* imaginary part */ + s1 = L_add(y15, y25); + s2 = Mpy_32_xx(L_sub(y15, y25), C31); + im[s * 12] = L_add(y05, s1); + move32(); + s1 = L_sub(y05, L_shr_pos(s1, 1)); + + /* combination */ + re[s * 7] = L_sub(r1, s2); + move32(); + re[s * 2] = L_add(r1, s2); + move32(); + im[s * 7] = L_add(s1, r2); + move32(); + im[s * 2] = L_sub(s1, r2); + move32(); + + /* 4. FFT3 stage */ + + /* real part */ + r1 = L_add(y16, y26); + r2 = Mpy_32_xx(L_sub(y16, y26), C31); + re[s * 3] = L_add(y06, r1); + move32(); + r1 = L_sub(y06, L_shr_pos(r1, 1)); + + /* imaginary part */ + s1 = L_add(y17, y27); + s2 = Mpy_32_xx(L_sub(y17, y27), C31); + im[s * 3] = L_add(y07, s1); + move32(); + s1 = L_sub(y07, L_shr_pos(s1, 1)); + + /* combination */ + re[s * 13] = L_sub(r1, s2); + move32(); + re[s * 8] = L_add(r1, s2); + move32(); + im[s * 13] = L_add(s1, r2); + move32(); + im[s * 8] = L_sub(s1, r2); + move32(); + + /* 5. FFT3 stage */ + + /* real part */ + r1 = L_add(y18, y28); + r2 = Mpy_32_xx(L_sub(y18, y28), C31); + re[s * 9] = L_add(y08, r1); + move32(); + r1 = L_sub(y08, L_shr_pos(r1, 1)); + + /* imaginary part */ + s1 = L_add(y19, y29); + s2 = Mpy_32_xx(L_sub(y19, y29), C31); + im[s * 9] = L_add(y09, s1); + move32(); + s1 = L_sub(y09, L_shr_pos(s1, 1)); + + /* combination */ + re[s * 4] = L_sub(r1, s2); + move32(); + re[s * 14] = L_add(r1, s2); + move32(); + im[s * 4] = L_add(s1, r2); + move32(); + im[s * 14] = L_sub(s1, r2); + move32(); + + Dyn_Mem_Deluxe_Out(); +} + +#ifdef CR8_G_ADD_75MS + +#define STC(x) (x) +const Word32 RotVectorReal12[] = +{ + STC(0x6ed9eba1), STC(0x40000000), + STC(0x40000000), STC(0xc0000000), +#ifndef FFT12_UNROLLED_ENABLE + STC(0x00000000), STC(0x80000000), +#endif +}; + +const Word32 RotVectorImag12[] = +{ + STC(0x40000000), STC(0x6ed9eba1), + STC(0x6ed9eba1), STC(0x6ed9eba1), +#ifndef FFT12_UNROLLED_ENABLE + STC(0x7fffffff), STC(0x00000000), +#endif +}; + +static void fft12(Word32 *pInput) +{ + Dyn_Mem_Deluxe_In(Word32 aDst[24]; Word32 * pSrc, *pDst; Counter i; Word32 r1, r2, s1, s2, pD; Word32 re, im; + Word32 vre, vim;); + + pSrc = pInput; + move16(); + pDst = aDst; + move16(); + + /* First 3*2 samples are shifted right by 2 before output */ + r1 = L_add(L_shr_pos(pSrc[8], 2), L_shr_pos(pSrc[16], 2)); + r2 = Mpy_32_xx(L_sub(L_shr_pos(pSrc[8], 2), L_shr_pos(pSrc[16], 2)), C31); + pD = L_shr_pos(pSrc[0], 2); + pDst[0] = L_shr_pos(L_add(pD, r1), 1); + r1 = L_sub(pD, L_shr_pos(r1, 1)); + + /* imaginary part */ + s1 = L_add(L_shr_pos(pSrc[9], 2), L_shr_pos(pSrc[17], 2)); + s2 = Mpy_32_xx(L_sub(L_shr_pos(pSrc[9], 2), L_shr_pos(pSrc[17], 2)), C31); + pD = L_shr_pos(pSrc[1], 2); + pDst[1] = L_shr_pos(L_add(pD, s1), 1); + s1 = L_sub(pD, L_shr_pos(s1, 1)); + + r1 = L_shr_pos(r1, 1); + r2 = L_shr_pos(r2, 1); + s1 = L_shr_pos(s1, 1); + s2 = L_shr_pos(s2, 1); + + /* combination */ + pDst[2] = L_sub(r1, s2); + pDst[3] = L_add(s1, r2); + pDst[4] = L_add(r1, s2); + pDst[5] = L_sub(s1, r2); + pSrc += 2; + pDst += 6; + + const Word32 *pVecRe = RotVectorReal12; + const Word32 *pVecIm = RotVectorImag12; + + + + FOR (i = 0; i < 2; i++) + { + /* sample 0,1 are shifted right by 2 before output */ + /* sample 2,3 4,5 are shifted right by 1 and complex multiplied before output */ + + r1 = L_add(L_shr_pos(pSrc[8], 2), L_shr_pos(pSrc[16], 2)); + r2 = Mpy_32_xx(L_sub(L_shr_pos(pSrc[8], 2), L_shr_pos(pSrc[16], 2)), C31); + pD = L_shr_pos(pSrc[0], 2); + pDst[0] = L_shr_pos(L_add(pD, r1), 1); + r1 = L_sub(pD, L_shr_pos(r1, 1)); + + /* imaginary part */ + s1 = L_add(L_shr_pos(pSrc[9], 2), L_shr_pos(pSrc[17], 2)); + s2 = Mpy_32_xx(L_sub(L_shr_pos(pSrc[9], 2), L_shr_pos(pSrc[17], 2)), C31); + pD = L_shr_pos(pSrc[1], 2); + pDst[1] = L_shr_pos(L_add(pD, s1), 1); + s1 = L_sub(pD, L_shr_pos(s1, 1)); + + r1 = L_shr_pos(r1, 1); + r2 = L_shr_pos(r2, 1); + s1 = L_shr_pos(s1, 1); + s2 = L_shr_pos(s2, 1); + + /* combination */ + re = L_sub(r1, s2); + im = L_add(s1, r2); + vre = *pVecRe++; + vim = *pVecIm++; + cplxMpy_32_32(&pDst[3], &pDst[2], im, re, vre, vim); + + re = L_add(r1, s2); + im = L_sub(s1, r2); + + vre = *pVecRe++; + vim = *pVecIm++; + cplxMpy_32_32(&pDst[5], &pDst[4], im, re, vre, vim); + + pDst += 6; + pSrc += 2; + } + /* sample 0,1 are shifted right by 2 before output */ + /* sample 2,3 is shifted right by 1 and complex multiplied with (0.0,+1.0) */ + /* sample 4,5 is shifted right by 1 and complex multiplied with (-1.0,0.0) */ + r1 = L_add(L_shr_pos(pSrc[8], 2), L_shr_pos(pSrc[16], 2)); + r2 = Mpy_32_xx(L_sub(L_shr_pos(pSrc[8], 2), L_shr_pos(pSrc[16], 2)), C31); + pD = L_shr_pos(pSrc[0], 2); + pDst[0] = L_shr_pos(L_add(pD, r1), 1); + r1 = L_sub(pD, L_shr_pos(r1, 1)); + + /* imaginary part */ + s1 = L_add(L_shr_pos(pSrc[9], 2), L_shr_pos(pSrc[17], 2)); + s2 = Mpy_32_xx(L_sub(L_shr_pos(pSrc[9], 2), L_shr_pos(pSrc[17], 2)), C31); + pD = L_shr_pos(pSrc[1], 2); + pDst[1] = L_shr_pos(L_add(pD, s1), 1); + s1 = L_sub(pD, L_shr_pos(s1, 1)); + + r1 = L_shr_pos(r1, 1); + r2 = L_shr_pos(r2, 1); + s1 = L_shr_pos(s1, 1); + s2 = L_shr_pos(s2, 1); + + /* combination */ + + pDst[2] = L_add(s1, r2); + move32(); + pDst[3] = L_sub(s2, r1); + move32(); + pDst[4] = L_negate(L_add(r1, s2)); + move32(); + pDst[5] = L_sub(r2, s1); + move32(); + /* Perform 3 times the fft of length 4. The input samples are at the address of aDst and the + output samples are at the address of pInput. The input vector for the fft of length 4 is built + of the interleaved samples in aDst, the output samples are stored consecutively at the address + of pInput. + */ + move16(); + move16(); + pSrc = aDst; + pDst = pInput; + FOR (i = 0; i < 3; i++) + { + /* inline FFT4 merged with incoming resorting loop */ + r1 = L_add(L_shr_pos(pSrc[0], 2), L_shr_pos(pSrc[12], 2)); /* Re A + Re B */ + r2 = L_add(L_shr_pos(pSrc[6], 2), L_shr_pos(pSrc[18], 2)); /* Re C + Re D */ + s1 = L_add(L_shr_pos(pSrc[1], 2), L_shr_pos(pSrc[13], 2)); /* Im A + Im B */ + s2 = L_add(L_shr_pos(pSrc[7], 2), L_shr_pos(pSrc[19], 2)); /* Im C + Im D */ + + pDst[0] = L_add(r1, r2); /* Re A' = Re A + Re B + Re C + Re D */ + pDst[1] = L_add(s1, s2); /* Im A' = Im A + Im B + Im C + Im D */ + + re = L_sub(r1, L_shr_pos(pSrc[12], 1)); /* Re A - Re B */ + im = L_sub(s1, L_shr_pos(pSrc[13], 1)); /* Im A - Im B */ + + pDst[12] = L_sub(r1, r2); /* Re C' = Re A + Re B - Re C - Re D */ + pDst[13] = L_sub(s1, s2); /* Im C' = Im A + Im B - Im C - Im D */ + + r2 = L_sub(r2, L_shr_pos(pSrc[18], 1)); /* Re C - Re D */ + s2 = L_sub(s2, L_shr_pos(pSrc[19], 1)); /* Im C - Im D */ + + pDst[6] = L_add(re, s2); /* Re B' = Re A - Re B + Im C - Im D */ + pDst[18] = L_sub(re, s2); /* Re D' = Re A - Re B - Im C + Im D */ + pDst[7] = L_sub(im, r2); /* Im B' = Im A - Im B - Re C + Re D */ + pDst[19] = L_add(im, r2); /* Im D' = Im A - Im B + Re C - Re D */ + + pSrc += 2; + pDst += 2; + } + + Dyn_Mem_Deluxe_Out(); +} + +#else /* CR8_G_ADD_75MS */ + +static void fft12(Word32 *pInput) +{ + Dyn_Mem_Deluxe_In(Word32 aDst[24]; Word32 * pSrc, *pDst; Counter i; Word32 r1, r2, s1, s2, pD; Word32 re, im; + Word16 vre, vim;); + + pSrc = pInput; + move16(); + pDst = aDst; + move16(); + + /* First 3*2 samples are shifted right by 2 before output */ + r1 = L_add(L_shr_pos(pSrc[8], 2), L_shr_pos(pSrc[16], 2)); + r2 = Mpy_32_xx(L_sub(L_shr_pos(pSrc[8], 2), L_shr_pos(pSrc[16], 2)), C31); + pD = L_shr_pos(pSrc[0], 2); + pDst[0] = L_shr_pos(L_add(pD, r1), 1); + r1 = L_sub(pD, L_shr_pos(r1, 1)); + + /* imaginary part */ + s1 = L_add(L_shr_pos(pSrc[9], 2), L_shr_pos(pSrc[17], 2)); + s2 = Mpy_32_xx(L_sub(L_shr_pos(pSrc[9], 2), L_shr_pos(pSrc[17], 2)), C31); + pD = L_shr_pos(pSrc[1], 2); + pDst[1] = L_shr_pos(L_add(pD, s1), 1); + s1 = L_sub(pD, L_shr_pos(s1, 1)); + + r1 = L_shr_pos(r1, 1); + r2 = L_shr_pos(r2, 1); + s1 = L_shr_pos(s1, 1); + s2 = L_shr_pos(s2, 1); + + /* combination */ + pDst[2] = L_sub(r1, s2); + pDst[3] = L_add(s1, r2); + pDst[4] = L_add(r1, s2); + pDst[5] = L_sub(s1, r2); + pSrc += 2; + pDst += 6; + + vre = add(0x6eda, 0); + vim = add(0x4000, 0); + + FOR (i = 0; i < 2; i++) + { + /* sample 0,1 are shifted right by 2 before output */ + /* sample 2,3 4,5 are shifted right by 1 and complex multiplied before output */ + + r1 = L_add(L_shr_pos(pSrc[8], 2), L_shr_pos(pSrc[16], 2)); + r2 = Mpy_32_xx(L_sub(L_shr_pos(pSrc[8], 2), L_shr_pos(pSrc[16], 2)), C31); + pD = L_shr_pos(pSrc[0], 2); + pDst[0] = L_shr_pos(L_add(pD, r1), 1); + r1 = L_sub(pD, L_shr_pos(r1, 1)); + + /* imaginary part */ + s1 = L_add(L_shr_pos(pSrc[9], 2), L_shr_pos(pSrc[17], 2)); + s2 = Mpy_32_xx(L_sub(L_shr_pos(pSrc[9], 2), L_shr_pos(pSrc[17], 2)), C31); + pD = L_shr_pos(pSrc[1], 2); + pDst[1] = L_shr_pos(L_add(pD, s1), 1); + s1 = L_sub(pD, L_shr_pos(s1, 1)); + + r1 = L_shr_pos(r1, 1); + r2 = L_shr_pos(r2, 1); + s1 = L_shr_pos(s1, 1); + s2 = L_shr_pos(s2, 1); + + /* combination */ + re = L_sub(r1, s2); + im = L_add(s1, r2); + cplxMpy_32_16(&pDst[3], &pDst[2], im, re, vre, vim); + re = L_add(r1, s2); + im = L_sub(s1, r2); + vre = add(0x4000, 0); + if (i == 1) + vre = negate(vre); /* 0xC000 */ + if (i == 0) + vim = add(0x6eda, 0); + cplxMpy_32_16(&pDst[5], &pDst[4], im, re, vre, vim); + + pDst += 6; + pSrc += 2; + } + /* sample 0,1 are shifted right by 2 before output */ + /* sample 2,3 is shifted right by 1 and complex multiplied with (0.0,+1.0) */ + /* sample 4,5 is shifted right by 1 and complex multiplied with (-1.0,0.0) */ + r1 = L_add(L_shr_pos(pSrc[8], 2), L_shr_pos(pSrc[16], 2)); + r2 = Mpy_32_xx(L_sub(L_shr_pos(pSrc[8], 2), L_shr_pos(pSrc[16], 2)), C31); + pD = L_shr_pos(pSrc[0], 2); + pDst[0] = L_shr_pos(L_add(pD, r1), 1); + r1 = L_sub(pD, L_shr_pos(r1, 1)); + + /* imaginary part */ + s1 = L_add(L_shr_pos(pSrc[9], 2), L_shr_pos(pSrc[17], 2)); + s2 = Mpy_32_xx(L_sub(L_shr_pos(pSrc[9], 2), L_shr_pos(pSrc[17], 2)), C31); + pD = L_shr_pos(pSrc[1], 2); + pDst[1] = L_shr_pos(L_add(pD, s1), 1); + s1 = L_sub(pD, L_shr_pos(s1, 1)); + + r1 = L_shr_pos(r1, 1); + r2 = L_shr_pos(r2, 1); + s1 = L_shr_pos(s1, 1); + s2 = L_shr_pos(s2, 1); + + /* combination */ + + pDst[2] = L_add(s1, r2); + move32(); + pDst[3] = L_sub(s2, r1); + move32(); + pDst[4] = L_negate(L_add(r1, s2)); + move32(); + pDst[5] = L_sub(r2, s1); + move32(); + /* Perform 3 times the fft of length 4. The input samples are at the address of aDst and the + output samples are at the address of pInput. The input vector for the fft of length 4 is built + of the interleaved samples in aDst, the output samples are stored consecutively at the address + of pInput. + */ + move16(); + move16(); + pSrc = aDst; + pDst = pInput; + FOR (i = 0; i < 3; i++) + { + /* inline FFT4 merged with incoming resorting loop */ + r1 = L_add(L_shr_pos(pSrc[0], 2), L_shr_pos(pSrc[12], 2)); /* Re A + Re B */ + r2 = L_add(L_shr_pos(pSrc[6], 2), L_shr_pos(pSrc[18], 2)); /* Re C + Re D */ + s1 = L_add(L_shr_pos(pSrc[1], 2), L_shr_pos(pSrc[13], 2)); /* Im A + Im B */ + s2 = L_add(L_shr_pos(pSrc[7], 2), L_shr_pos(pSrc[19], 2)); /* Im C + Im D */ + + pDst[0] = L_add(r1, r2); /* Re A' = Re A + Re B + Re C + Re D */ + pDst[1] = L_add(s1, s2); /* Im A' = Im A + Im B + Im C + Im D */ + + re = L_sub(r1, L_shr_pos(pSrc[12], 1)); /* Re A - Re B */ + im = L_sub(s1, L_shr_pos(pSrc[13], 1)); /* Im A - Im B */ + + pDst[12] = L_sub(r1, r2); /* Re C' = Re A + Re B - Re C - Re D */ + pDst[13] = L_sub(s1, s2); /* Im C' = Im A + Im B - Im C - Im D */ + + r2 = L_sub(r2, L_shr_pos(pSrc[18], 1)); /* Re C - Re D */ + s2 = L_sub(s2, L_shr_pos(pSrc[19], 1)); /* Im C - Im D */ + + pDst[6] = L_add(re, s2); /* Re B' = Re A - Re B + Im C - Im D */ + pDst[18] = L_sub(re, s2); /* Re D' = Re A - Re B - Im C + Im D */ + pDst[7] = L_sub(im, r2); /* Im B' = Im A - Im B - Re C + Re D */ + pDst[19] = L_add(im, r2); /* Im D' = Im A - Im B + Re C - Re D */ + + pSrc += 2; + pDst += 2; + } + + Dyn_Mem_Deluxe_Out(); +} + +#endif + +/** + * \brief Function performs a complex 16-point FFT + * The FFT is performed inplace. The result of the FFT + * is scaled by SCALEFACTOR16 bits. + * + * WOPS with 32x16 bit multiplications (scale on ): 288 cycles + * WOPS with 32x16 bit multiplications (scale off): 256 cycles + * + * \param [i/o] re real input / output + * \param [i/o] im imag input / output + * \param [i ] s stride real and imag input / output + * + * \return void + */ + + + +static void fft16(Word32 *re, Word32 *im, Word16 s) +{ + Dyn_Mem_Deluxe_In(Word32 x0, x1, x2, x3, x4, x5, x6, x7; Word32 t0, t1, t2, t3, t4, t5, t6, t7; + Word32 y00, y01, y02, y03, y04, y05, y06, y07; Word32 y08, y09, y10, y11, y12, y13, y14, y15; + Word32 y16, y17, y18, y19, y20, y21, y22, y23; Word32 y24, y25, y26, y27, y28, y29, y30, y31;); + + x0 = L_shr_pos(re[s * 0], SCALEFACTOR16); + x1 = L_shr_pos(im[s * 0], SCALEFACTOR16); + x2 = L_shr_pos(re[s * 4], SCALEFACTOR16); + x3 = L_shr_pos(im[s * 4], SCALEFACTOR16); + x4 = L_shr_pos(re[s * 8], SCALEFACTOR16); + x5 = L_shr_pos(im[s * 8], SCALEFACTOR16); + x6 = L_shr_pos(re[s * 12], SCALEFACTOR16); + x7 = L_shr_pos(im[s * 12], SCALEFACTOR16); + + /* Pre-additions */ + t0 = L_add(x0, x4); + t2 = L_sub(x0, x4); + t1 = L_add(x1, x5); + t3 = L_sub(x1, x5); + t4 = L_add(x2, x6); + t7 = L_sub(x2, x6); + t5 = L_add(x7, x3); + t6 = L_sub(x7, x3); + + /* Post-additions */ + y00 = L_add(t0, t4); + y01 = L_add(t1, t5); + y02 = L_sub(t2, t6); + y03 = L_sub(t3, t7); + y04 = L_sub(t0, t4); + y05 = L_sub(t1, t5); + y06 = L_add(t2, t6); + y07 = L_add(t3, t7); + + x0 = L_shr_pos(re[s * 1], SCALEFACTOR16); + x1 = L_shr_pos(im[s * 1], SCALEFACTOR16); + x2 = L_shr_pos(re[s * 5], SCALEFACTOR16); + x3 = L_shr_pos(im[s * 5], SCALEFACTOR16); + x4 = L_shr_pos(re[s * 9], SCALEFACTOR16); + x5 = L_shr_pos(im[s * 9], SCALEFACTOR16); + x6 = L_shr_pos(re[s * 13], SCALEFACTOR16); + x7 = L_shr_pos(im[s * 13], SCALEFACTOR16); + + /* Pre-additions */ + t0 = L_add(x0, x4); + t2 = L_sub(x0, x4); + t1 = L_add(x1, x5); + t3 = L_sub(x1, x5); + t4 = L_add(x2, x6); + t7 = L_sub(x2, x6); + t5 = L_add(x7, x3); + t6 = L_sub(x7, x3); + + /* Post-additions */ + y08 = L_add(t0, t4); + y09 = L_add(t1, t5); + y10 = L_sub(t2, t6); + y11 = L_sub(t3, t7); + y12 = L_sub(t0, t4); + y13 = L_sub(t1, t5); + y14 = L_add(t2, t6); + y15 = L_add(t3, t7); + + x0 = L_shr_pos(re[s * 2], SCALEFACTOR16); + x1 = L_shr_pos(im[s * 2], SCALEFACTOR16); + x2 = L_shr_pos(re[s * 6], SCALEFACTOR16); + x3 = L_shr_pos(im[s * 6], SCALEFACTOR16); + x4 = L_shr_pos(re[s * 10], SCALEFACTOR16); + x5 = L_shr_pos(im[s * 10], SCALEFACTOR16); + x6 = L_shr_pos(re[s * 14], SCALEFACTOR16); + x7 = L_shr_pos(im[s * 14], SCALEFACTOR16); + + /* Pre-additions */ + t0 = L_add(x0, x4); + t2 = L_sub(x0, x4); + t1 = L_add(x1, x5); + t3 = L_sub(x1, x5); + t4 = L_add(x2, x6); + t7 = L_sub(x2, x6); + t5 = L_add(x7, x3); + t6 = L_sub(x7, x3); + + /* Post-additions */ + y16 = L_add(t0, t4); + y17 = L_add(t1, t5); + y18 = L_sub(t2, t6); + y19 = L_sub(t3, t7); + y20 = L_sub(t1, t5); + y21 = L_sub(t4, t0); + y22 = L_add(t2, t6); + y23 = L_add(t3, t7); + + x0 = L_shr_pos(re[s * 3], SCALEFACTOR16); + x1 = L_shr_pos(im[s * 3], SCALEFACTOR16); + x2 = L_shr_pos(re[s * 7], SCALEFACTOR16); + x3 = L_shr_pos(im[s * 7], SCALEFACTOR16); + x4 = L_shr_pos(re[s * 11], SCALEFACTOR16); + x5 = L_shr_pos(im[s * 11], SCALEFACTOR16); + x6 = L_shr_pos(re[s * 15], SCALEFACTOR16); + x7 = L_shr_pos(im[s * 15], SCALEFACTOR16); + + /* Pre-additions */ + t0 = L_add(x0, x4); + t2 = L_sub(x0, x4); + t1 = L_add(x1, x5); + t3 = L_sub(x1, x5); + t4 = L_add(x2, x6); + t7 = L_sub(x2, x6); + t5 = L_add(x7, x3); + t6 = L_sub(x7, x3); + + /* Post-additions */ + y24 = L_add(t0, t4); + y25 = L_add(t1, t5); + y26 = L_sub(t2, t6); + y27 = L_sub(t3, t7); + y28 = L_sub(t0, t4); + y29 = L_sub(t1, t5); + y30 = L_add(t2, t6); + y31 = L_add(t3, t7); + + /* rotation */ + + x0 = Mpy_32_xx(y22, C162); + x1 = Mpy_32_xx(y23, C162); + y22 = L_sub(x0, x1); + y23 = L_add(x0, x1); + + x0 = Mpy_32_xx(y28, C162); + x1 = Mpy_32_xx(y29, C162); + y28 = L_sub(x0, x1); + y29 = L_add(x0, x1); + + x0 = Mpy_32_xx(y12, C161); + x1 = Mpy_32_xx(y13, C161); + y12 = L_add(x0, x1); + y13 = L_sub(x1, x0); + + x0 = Mpy_32_xx(y18, C161); + x1 = Mpy_32_xx(y19, C161); + y18 = L_add(x0, x1); + y19 = L_sub(x1, x0); + + x0 = Mpy_32_xx(y10, C163); + x1 = Mpy_32_xx(y11, C166); + x2 = Mpy_32_xx(y10, C166); + x3 = Mpy_32_xx(y11, C163); + y10 = L_sub(x0, x1); + y11 = L_add(x2, x3); + + x0 = Mpy_32_xx(y14, C165); + x1 = Mpy_32_xx(y15, C164); + x2 = Mpy_32_xx(y14, C164); + x3 = Mpy_32_xx(y15, C165); + y14 = L_sub(x0, x1); + y15 = L_add(x2, x3); + + x0 = Mpy_32_xx(y26, C165); + x1 = Mpy_32_xx(y27, C164); + x2 = Mpy_32_xx(y26, C164); + x3 = Mpy_32_xx(y27, C165); + y26 = L_sub(x0, x1); + y27 = L_add(x2, x3); + + x0 = Mpy_32_xx(y30, C164); + x1 = Mpy_32_xx(y31, C165); + x2 = Mpy_32_xx(y30, C165); + x3 = Mpy_32_xx(y31, C164); + y30 = L_sub(x0, x1); + y31 = L_add(x2, x3); + + /* Pre-additions */ + + t0 = L_add(y00, y16); + t2 = L_sub(y00, y16); + t1 = L_add(y01, y17); + t3 = L_sub(y01, y17); + t4 = L_add(y08, y24); + t7 = L_sub(y08, y24); + t5 = L_add(y25, y09); + t6 = L_sub(y25, y09); + + /* Post-additions */ + + re[s * 0] = L_add(t0, t4); + move32(); + im[s * 0] = L_add(t1, t5); + move32(); + re[s * 4] = L_sub(t2, t6); + move32(); + im[s * 4] = L_sub(t3, t7); + move32(); + re[s * 8] = L_sub(t0, t4); + move32(); + im[s * 8] = L_sub(t1, t5); + move32(); + re[s * 12] = L_add(t2, t6); + move32(); + im[s * 12] = L_add(t3, t7); + move32(); + + /* Pre-additions */ + + t0 = L_add(y02, y18); + t2 = L_sub(y02, y18); + t1 = L_add(y03, y19); + t3 = L_sub(y03, y19); + t4 = L_add(y10, y26); + t7 = L_sub(y10, y26); + t5 = L_add(y27, y11); + t6 = L_sub(y27, y11); + + /* Post-additions */ + + re[s * 1] = L_add(t0, t4); + move32(); + im[s * 1] = L_add(t1, t5); + move32(); + re[s * 5] = L_sub(t2, t6); + move32(); + im[s * 5] = L_sub(t3, t7); + move32(); + re[s * 9] = L_sub(t0, t4); + move32(); + im[s * 9] = L_sub(t1, t5); + move32(); + re[s * 13] = L_add(t2, t6); + move32(); + im[s * 13] = L_add(t3, t7); + move32(); + + /* Pre-additions */ + + t0 = L_add(y04, y20); + t2 = L_sub(y04, y20); + t1 = L_add(y05, y21); + t3 = L_sub(y05, y21); + t4 = L_add(y12, y28); + t7 = L_sub(y12, y28); + t5 = L_add(y29, y13); + t6 = L_sub(y29, y13); + + /* Post-additions */ + + re[s * 2] = L_add(t0, t4); + move32(); + im[s * 2] = L_add(t1, t5); + move32(); + re[s * 6] = L_sub(t2, t6); + move32(); + im[s * 6] = L_sub(t3, t7); + move32(); + re[s * 10] = L_sub(t0, t4); + move32(); + im[s * 10] = L_sub(t1, t5); + move32(); + re[s * 14] = L_add(t2, t6); + move32(); + im[s * 14] = L_add(t3, t7); + move32(); + + /* Pre-additions */ + + t0 = L_add(y06, y22); + t2 = L_sub(y06, y22); + t1 = L_add(y07, y23); + t3 = L_sub(y07, y23); + t4 = L_add(y14, y30); + t7 = L_sub(y14, y30); + t5 = L_add(y31, y15); + t6 = L_sub(y31, y15); + + /* Post-additions */ + + re[s * 3] = L_add(t0, t4); + move32(); + im[s * 3] = L_add(t1, t5); + move32(); + re[s * 7] = L_sub(t2, t6); + move32(); + im[s * 7] = L_sub(t3, t7); + move32(); + re[s * 11] = L_sub(t0, t4); + move32(); + im[s * 11] = L_sub(t1, t5); + move32(); + re[s * 15] = L_add(t2, t6); + move32(); + im[s * 15] = L_add(t3, t7); + move32(); + + Dyn_Mem_Deluxe_Out(); +} + +/** + * \brief Function performs a complex 20-point FFT + * The FFT is performed inplace. The result of the FFT + * is scaled by SCALEFACTOR20 bits. + * + * WOPS with 32x16 bit multiplications: 432 cycles + * + * \param [i/o] re real input / output + * \param [i/o] im imag input / output + * \param [i ] s stride real and imag input / output + * + * \return void + */ + + +static void fft20(Word32 *re, Word32 *im, Word16 s) +{ + Dyn_Mem_Deluxe_In(Word32 r1, r2, r3, r4; Word32 s1, s2, s3, s4; Word32 x0, x1, x2, x3, x4; + Word32 t, t0, t1, t2, t3, t4, t5, t6, t7; Word32 y00, y01, y02, y03, y04, y05, y06, y07, y08, y09; + Word32 y10, y11, y12, y13, y14, y15, y16, y17, y18, y19; + Word32 y20, y21, y22, y23, y24, y25, y26, y27, y28, y29; + Word32 y30, y31, y32, y33, y34, y35, y36, y37, y38, y39;); + + /* 1. FFT5 stage */ + + /* real part */ + x0 = L_shr_pos(re[s * 0], SCALEFACTOR20); + x1 = L_shr_pos(re[s * 16], SCALEFACTOR20); + x2 = L_shr_pos(re[s * 12], SCALEFACTOR20); + x3 = L_shr_pos(re[s * 8], SCALEFACTOR20); + x4 = L_shr_pos(re[s * 4], SCALEFACTOR20); + + r1 = L_add(x1, x4); + r4 = L_sub(x1, x4); + r3 = L_add(x2, x3); + r2 = L_sub(x2, x3); + t = Mpy_32_xx(L_sub(r1, r3), C54); + r1 = L_add(r1, r3); + y00 = L_add(x0, r1); + r1 = L_add(y00, (L_shl_pos(Mpy_32_xx(r1, C55), 1))); + r3 = L_sub(r1, t); + r1 = L_add(r1, t); + t = Mpy_32_xx((L_add(r4, r2)), C51); + r4 = L_add(t, L_shl_pos(Mpy_32_xx(r4, C52), 1)); + r2 = L_add(t, Mpy_32_xx(r2, C53)); + + /* imaginary part */ + x0 = L_shr_pos(im[s * 0], SCALEFACTOR20); + x1 = L_shr_pos(im[s * 16], SCALEFACTOR20); + x2 = L_shr_pos(im[s * 12], SCALEFACTOR20); + x3 = L_shr_pos(im[s * 8], SCALEFACTOR20); + x4 = L_shr_pos(im[s * 4], SCALEFACTOR20); + + s1 = L_add(x1, x4); + s4 = L_sub(x1, x4); + s3 = L_add(x2, x3); + s2 = L_sub(x2, x3); + t = Mpy_32_xx(L_sub(s1, s3), C54); + s1 = L_add(s1, s3); + y01 = L_add(x0, s1); + s1 = L_add(y01, L_shl_pos(Mpy_32_xx(s1, C55), 1)); + s3 = L_sub(s1, t); + s1 = L_add(s1, t); + t = Mpy_32_xx(L_add(s4, s2), C51); + s4 = L_add(t, L_shl_pos(Mpy_32_xx(s4, C52), 1)); + s2 = L_add(t, Mpy_32_xx(s2, C53)); + + /* combination */ + y08 = L_add(r1, s2); + y32 = L_sub(r1, s2); + y16 = L_sub(r3, s4); + y24 = L_add(r3, s4); + + y09 = L_sub(s1, r2); + y33 = L_add(s1, r2); + y17 = L_add(s3, r4); + y25 = L_sub(s3, r4); + + /* 2. FFT5 stage */ + + /* real part */ + x0 = L_shr_pos(re[s * 5], SCALEFACTOR20); + x1 = L_shr_pos(re[s * 1], SCALEFACTOR20); + x2 = L_shr_pos(re[s * 17], SCALEFACTOR20); + x3 = L_shr_pos(re[s * 13], SCALEFACTOR20); + x4 = L_shr_pos(re[s * 9], SCALEFACTOR20); + + r1 = L_add(x1, x4); + r4 = L_sub(x1, x4); + r3 = L_add(x2, x3); + r2 = L_sub(x2, x3); + t = Mpy_32_xx(L_sub(r1, r3), C54); + r1 = L_add(r1, r3); + y02 = L_add(x0, r1); + r1 = L_add(y02, (L_shl_pos(Mpy_32_xx(r1, C55), 1))); + r3 = L_sub(r1, t); + r1 = L_add(r1, t); + t = Mpy_32_xx((L_add(r4, r2)), C51); + r4 = L_add(t, L_shl_pos(Mpy_32_xx(r4, C52), 1)); + r2 = L_add(t, Mpy_32_xx(r2, C53)); + + /* imaginary part */ + x0 = L_shr_pos(im[s * 5], SCALEFACTOR20); + x1 = L_shr_pos(im[s * 1], SCALEFACTOR20); + x2 = L_shr_pos(im[s * 17], SCALEFACTOR20); + x3 = L_shr_pos(im[s * 13], SCALEFACTOR20); + x4 = L_shr_pos(im[s * 9], SCALEFACTOR20); + + s1 = L_add(x1, x4); + s4 = L_sub(x1, x4); + s3 = L_add(x2, x3); + s2 = L_sub(x2, x3); + t = Mpy_32_xx(L_sub(s1, s3), C54); + s1 = L_add(s1, s3); + y03 = L_add(x0, s1); + s1 = L_add(y03, L_shl_pos(Mpy_32_xx(s1, C55), 1)); + s3 = L_sub(s1, t); + s1 = L_add(s1, t); + t = Mpy_32_xx(L_add(s4, s2), C51); + s4 = L_add(t, L_shl_pos(Mpy_32_xx(s4, C52), 1)); + s2 = L_add(t, Mpy_32_xx(s2, C53)); + + /* combination */ + y10 = L_add(r1, s2); + y34 = L_sub(r1, s2); + y18 = L_sub(r3, s4); + y26 = L_add(r3, s4); + + y11 = L_sub(s1, r2); + y35 = L_add(s1, r2); + y19 = L_add(s3, r4); + y27 = L_sub(s3, r4); + + /* 3. FFT5 stage */ + + /* real part */ + x0 = L_shr_pos(re[s * 10], SCALEFACTOR20); + x1 = L_shr_pos(re[s * 6], SCALEFACTOR20); + x2 = L_shr_pos(re[s * 2], SCALEFACTOR20); + x3 = L_shr_pos(re[s * 18], SCALEFACTOR20); + x4 = L_shr_pos(re[s * 14], SCALEFACTOR20); + + r1 = L_add(x1, x4); + r4 = L_sub(x1, x4); + r3 = L_add(x2, x3); + r2 = L_sub(x2, x3); + t = Mpy_32_xx(L_sub(r1, r3), C54); + r1 = L_add(r1, r3); + y04 = L_add(x0, r1); + r1 = L_add(y04, (L_shl_pos(Mpy_32_xx(r1, C55), 1))); + r3 = L_sub(r1, t); + r1 = L_add(r1, t); + t = Mpy_32_xx((L_add(r4, r2)), C51); + r4 = L_add(t, L_shl_pos(Mpy_32_xx(r4, C52), 1)); + r2 = L_add(t, Mpy_32_xx(r2, C53)); + + /* imaginary part */ + x0 = L_shr_pos(im[s * 10], SCALEFACTOR20); + x1 = L_shr_pos(im[s * 6], SCALEFACTOR20); + x2 = L_shr_pos(im[s * 2], SCALEFACTOR20); + x3 = L_shr_pos(im[s * 18], SCALEFACTOR20); + x4 = L_shr_pos(im[s * 14], SCALEFACTOR20); + + s1 = L_add(x1, x4); + s4 = L_sub(x1, x4); + s3 = L_add(x2, x3); + s2 = L_sub(x2, x3); + t = Mpy_32_xx(L_sub(s1, s3), C54); + s1 = L_add(s1, s3); + y05 = L_add(x0, s1); + s1 = L_add(y05, L_shl_pos(Mpy_32_xx(s1, C55), 1)); + s3 = L_sub(s1, t); + s1 = L_add(s1, t); + t = Mpy_32_xx(L_add(s4, s2), C51); + s4 = L_add(t, L_shl_pos(Mpy_32_xx(s4, C52), 1)); + s2 = L_add(t, Mpy_32_xx(s2, C53)); + + /* combination */ + y12 = L_add(r1, s2); + y36 = L_sub(r1, s2); + y20 = L_sub(r3, s4); + y28 = L_add(r3, s4); + + y13 = L_sub(s1, r2); + y37 = L_add(s1, r2); + y21 = L_add(s3, r4); + y29 = L_sub(s3, r4); + + /* 4. FFT5 stage */ + + /* real part */ + x0 = L_shr_pos(re[s * 15], SCALEFACTOR20); + x1 = L_shr_pos(re[s * 11], SCALEFACTOR20); + x2 = L_shr_pos(re[s * 7], SCALEFACTOR20); + x3 = L_shr_pos(re[s * 3], SCALEFACTOR20); + x4 = L_shr_pos(re[s * 19], SCALEFACTOR20); + + r1 = L_add(x1, x4); + r4 = L_sub(x1, x4); + r3 = L_add(x2, x3); + r2 = L_sub(x2, x3); + t = Mpy_32_xx(L_sub(r1, r3), C54); + r1 = L_add(r1, r3); + y06 = L_add(x0, r1); + r1 = L_add(y06, (L_shl_pos(Mpy_32_xx(r1, C55), 1))); + r3 = L_sub(r1, t); + r1 = L_add(r1, t); + t = Mpy_32_xx((L_add(r4, r2)), C51); + r4 = L_add(t, L_shl_pos(Mpy_32_xx(r4, C52), 1)); + r2 = L_add(t, Mpy_32_xx(r2, C53)); + + /* imaginary part */ + x0 = L_shr_pos(im[s * 15], SCALEFACTOR20); + x1 = L_shr_pos(im[s * 11], SCALEFACTOR20); + x2 = L_shr_pos(im[s * 7], SCALEFACTOR20); + x3 = L_shr_pos(im[s * 3], SCALEFACTOR20); + x4 = L_shr_pos(im[s * 19], SCALEFACTOR20); + + s1 = L_add(x1, x4); + s4 = L_sub(x1, x4); + s3 = L_add(x2, x3); + s2 = L_sub(x2, x3); + t = Mpy_32_xx(L_sub(s1, s3), C54); + s1 = L_add(s1, s3); + y07 = L_add(x0, s1); + s1 = L_add(y07, L_shl_pos(Mpy_32_xx(s1, C55), 1)); + s3 = L_sub(s1, t); + s1 = L_add(s1, t); + t = Mpy_32_xx(L_add(s4, s2), C51); + s4 = L_add(t, L_shl_pos(Mpy_32_xx(s4, C52), 1)); + s2 = L_add(t, Mpy_32_xx(s2, C53)); + + /* combination */ + y14 = L_add(r1, s2); + y38 = L_sub(r1, s2); + y22 = L_sub(r3, s4); + y30 = L_add(r3, s4); + + y15 = L_sub(s1, r2); + y39 = L_add(s1, r2); + y23 = L_add(s3, r4); + y31 = L_sub(s3, r4); + + /* 1. FFT4 stage */ + + /* Pre-additions */ + t0 = L_add(y00, y04); + t2 = L_sub(y00, y04); + t1 = L_add(y01, y05); + t3 = L_sub(y01, y05); + t4 = L_add(y02, y06); + t7 = L_sub(y02, y06); + t5 = L_add(y07, y03); + t6 = L_sub(y07, y03); + + /* Post-additions */ + re[s * 0] = L_add(t0, t4); + move32(); + im[s * 0] = L_add(t1, t5); + move32(); + re[s * 5] = L_sub(t2, t6); + move32(); + im[s * 5] = L_sub(t3, t7); + move32(); + re[s * 10] = L_sub(t0, t4); + move32(); + im[s * 10] = L_sub(t1, t5); + move32(); + re[s * 15] = L_add(t2, t6); + move32(); + im[s * 15] = L_add(t3, t7); + move32(); + + /* 2. FFT4 stage */ + + /* Pre-additions */ + t0 = L_add(y08, y12); + t2 = L_sub(y08, y12); + t1 = L_add(y09, y13); + t3 = L_sub(y09, y13); + t4 = L_add(y10, y14); + t7 = L_sub(y10, y14); + t5 = L_add(y15, y11); + t6 = L_sub(y15, y11); + + /* Post-additions */ + re[s * 4] = L_add(t0, t4); + move32(); + im[s * 4] = L_add(t1, t5); + move32(); + re[s * 9] = L_sub(t2, t6); + move32(); + im[s * 9] = L_sub(t3, t7); + move32(); + re[s * 14] = L_sub(t0, t4); + move32(); + im[s * 14] = L_sub(t1, t5); + move32(); + re[s * 19] = L_add(t2, t6); + move32(); + im[s * 19] = L_add(t3, t7); + move32(); + + /* 3. FFT4 stage */ + + /* Pre-additions */ + t0 = L_add(y16, y20); + t2 = L_sub(y16, y20); + t1 = L_add(y17, y21); + t3 = L_sub(y17, y21); + t4 = L_add(y18, y22); + t7 = L_sub(y18, y22); + t5 = L_add(y23, y19); + t6 = L_sub(y23, y19); + + /* Post-additions */ + re[s * 8] = L_add(t0, t4); + move32(); + im[s * 8] = L_add(t1, t5); + move32(); + re[s * 13] = L_sub(t2, t6); + move32(); + im[s * 13] = L_sub(t3, t7); + move32(); + re[s * 18] = L_sub(t0, t4); + move32(); + im[s * 18] = L_sub(t1, t5); + move32(); + re[s * 3] = L_add(t2, t6); + move32(); + im[s * 3] = L_add(t3, t7); + move32(); + + /* 4. FFT4 stage */ + + /* Pre-additions */ + t0 = L_add(y24, y28); + t2 = L_sub(y24, y28); + t1 = L_add(y25, y29); + t3 = L_sub(y25, y29); + t4 = L_add(y26, y30); + t7 = L_sub(y26, y30); + t5 = L_add(y31, y27); + t6 = L_sub(y31, y27); + + /* Post-additions */ + re[s * 12] = L_add(t0, t4); + move32(); + im[s * 12] = L_add(t1, t5); + move32(); + re[s * 17] = L_sub(t2, t6); + move32(); + im[s * 17] = L_sub(t3, t7); + move32(); + re[s * 2] = L_sub(t0, t4); + move32(); + im[s * 2] = L_sub(t1, t5); + move32(); + re[s * 7] = L_add(t2, t6); + move32(); + im[s * 7] = L_add(t3, t7); + move32(); + + /* 5. FFT4 stage */ + + /* Pre-additions */ + t0 = L_add(y32, y36); + t2 = L_sub(y32, y36); + t1 = L_add(y33, y37); + t3 = L_sub(y33, y37); + t4 = L_add(y34, y38); + t7 = L_sub(y34, y38); + t5 = L_add(y39, y35); + t6 = L_sub(y39, y35); + + /* Post-additions */ + re[s * 16] = L_add(t0, t4); + move32(); + im[s * 16] = L_add(t1, t5); + move32(); + re[s * 1] = L_sub(t2, t6); + move32(); + im[s * 1] = L_sub(t3, t7); + move32(); + re[s * 6] = L_sub(t0, t4); + move32(); + im[s * 6] = L_sub(t1, t5); + move32(); + re[s * 11] = L_add(t2, t6); + move32(); + im[s * 11] = L_add(t3, t7); + move32(); + + Dyn_Mem_Deluxe_Out(); +} + +/** + * \brief Function performs a complex 30-point FFT + * The FFT is performed inplace. The result of the FFT + * is scaled by SCALEFACTOR30 bits. + * + * WOPS with 32x16 bit multiplications: 828 cycles + * + * \param [i/o] re real input / output + * \param [i/o] im imag input / output + * \param [i ] s stride real and imag input / output + * + * \return void + */ + + +static void fft30(Word32 *re, Word32 *im, Word16 s) +{ + Dyn_Mem_Deluxe_In(Word32 t; Word32 r1, r2, r3, r4; Word32 s1, s2, s3, s4; + Word32 x00, x01, x02, x03, x04, x05, x06, x07, x08, x09; + Word32 x10, x11, x12, x13, x14, x15, x16, x17, x18, x19; + Word32 x20, x21, x22, x23, x24, x25, x26, x27, x28, x29; + + Word32 y00, y01, y02, y03, y04, y05, y06, y07, y08, y09; + Word32 y10, y11, y12, y13, y14, y15, y16, y17, y18, y19; + Word32 y20, y21, y22, y23, y24, y25, y26, y27, y28, y29; + + Word32 z00, z01, z02, z03, z04, z05, z06, z07, z08, z09; + Word32 z10, z11, z12, z13, z14, z15, z16, z17, z18, z19; + Word32 z20, z21, z22, z23, z24, z25, z26, z27, z28, z29; + Word32 z30, z31, z32, z33, z34, z35, z36, z37, z38, z39; + Word32 z40, z41, z42, z43, z44, z45, z46, z47, z48, z49; + Word32 z50, z51, z52, z53, z54, z55, z56, z57, z58, z59; + + Word32 * rel, *reh, *iml, *imh;); + + rel = &re[s * 0]; + reh = &re[s * 15]; + iml = &im[s * 0]; + imh = &im[s * 15]; + + /* 1. FFT15 stage */ + x00 = L_shr_pos(re[s * 0], SCALEFACTOR30_1); + x01 = L_shr_pos(im[s * 0], SCALEFACTOR30_1); + x02 = L_shr_pos(re[s * 18], SCALEFACTOR30_1); + x03 = L_shr_pos(im[s * 18], SCALEFACTOR30_1); + x04 = L_shr_pos(re[s * 6], SCALEFACTOR30_1); + x05 = L_shr_pos(im[s * 6], SCALEFACTOR30_1); + x06 = L_shr_pos(re[s * 24], SCALEFACTOR30_1); + x07 = L_shr_pos(im[s * 24], SCALEFACTOR30_1); + x08 = L_shr_pos(re[s * 12], SCALEFACTOR30_1); + x09 = L_shr_pos(im[s * 12], SCALEFACTOR30_1); + + x10 = L_shr_pos(re[s * 20], SCALEFACTOR30_1); + x11 = L_shr_pos(im[s * 20], SCALEFACTOR30_1); + x12 = L_shr_pos(re[s * 8], SCALEFACTOR30_1); + x13 = L_shr_pos(im[s * 8], SCALEFACTOR30_1); + x14 = L_shr_pos(re[s * 26], SCALEFACTOR30_1); + x15 = L_shr_pos(im[s * 26], SCALEFACTOR30_1); + x16 = L_shr_pos(re[s * 14], SCALEFACTOR30_1); + x17 = L_shr_pos(im[s * 14], SCALEFACTOR30_1); + x18 = L_shr_pos(re[s * 2], SCALEFACTOR30_1); + x19 = L_shr_pos(im[s * 2], SCALEFACTOR30_1); + + x20 = L_shr_pos(re[s * 10], SCALEFACTOR30_1); + x21 = L_shr_pos(im[s * 10], SCALEFACTOR30_1); + x22 = L_shr_pos(re[s * 28], SCALEFACTOR30_1); + x23 = L_shr_pos(im[s * 28], SCALEFACTOR30_1); + x24 = L_shr_pos(re[s * 16], SCALEFACTOR30_1); + x25 = L_shr_pos(im[s * 16], SCALEFACTOR30_1); + x26 = L_shr_pos(re[s * 4], SCALEFACTOR30_1); + x27 = L_shr_pos(im[s * 4], SCALEFACTOR30_1); + x28 = L_shr_pos(re[s * 22], SCALEFACTOR30_1); + x29 = L_shr_pos(im[s * 22], SCALEFACTOR30_1); + + /* 1. FFT5 stage */ + + /* real part */ + r1 = L_add(x02, x08); + r4 = L_sub(x02, x08); + r3 = L_add(x04, x06); + r2 = L_sub(x04, x06); + t = Mpy_32_xx(L_sub(r1, r3), C54); + r1 = L_add(r1, r3); + y00 = L_add(x00, r1); + r1 = L_add(y00, (L_shl_pos(Mpy_32_xx(r1, C55), 1))); + r3 = L_sub(r1, t); + r1 = L_add(r1, t); + t = Mpy_32_xx((L_add(r4, r2)), C51); + r4 = L_add(t, L_shl_pos(Mpy_32_xx(r4, C52), 1)); + r2 = L_add(t, Mpy_32_xx(r2, C53)); + + /* imaginary part */ + s1 = L_add(x03, x09); + s4 = L_sub(x03, x09); + s3 = L_add(x05, x07); + s2 = L_sub(x05, x07); + t = Mpy_32_xx(L_sub(s1, s3), C54); + s1 = L_add(s1, s3); + y01 = L_add(x01, s1); + s1 = L_add(y01, L_shl_pos(Mpy_32_xx(s1, C55), 1)); + s3 = L_sub(s1, t); + s1 = L_add(s1, t); + t = Mpy_32_xx(L_add(s4, s2), C51); + s4 = L_add(t, L_shl_pos(Mpy_32_xx(s4, C52), 1)); + s2 = L_add(t, Mpy_32_xx(s2, C53)); + + /* combination */ + y02 = L_add(r1, s2); + y08 = L_sub(r1, s2); + y04 = L_sub(r3, s4); + y06 = L_add(r3, s4); + + y03 = L_sub(s1, r2); + y09 = L_add(s1, r2); + y05 = L_add(s3, r4); + y07 = L_sub(s3, r4); + + /* 2. FFT5 stage */ + + /* real part */ + r1 = L_add(x12, x18); + r4 = L_sub(x12, x18); + r3 = L_add(x14, x16); + r2 = L_sub(x14, x16); + t = Mpy_32_xx(L_sub(r1, r3), C54); + r1 = L_add(r1, r3); + y10 = L_add(x10, r1); + r1 = L_add(y10, (L_shl_pos(Mpy_32_xx(r1, C55), 1))); + r3 = L_sub(r1, t); + r1 = L_add(r1, t); + t = Mpy_32_xx((L_add(r4, r2)), C51); + r4 = L_add(t, L_shl_pos(Mpy_32_xx(r4, C52), 1)); + r2 = L_add(t, Mpy_32_xx(r2, C53)); + + /* imaginary part */ + s1 = L_add(x13, x19); + s4 = L_sub(x13, x19); + s3 = L_add(x15, x17); + s2 = L_sub(x15, x17); + t = Mpy_32_xx(L_sub(s1, s3), C54); + s1 = L_add(s1, s3); + y11 = L_add(x11, s1); + s1 = L_add(y11, L_shl_pos(Mpy_32_xx(s1, C55), 1)); + s3 = L_sub(s1, t); + s1 = L_add(s1, t); + t = Mpy_32_xx(L_add(s4, s2), C51); + s4 = L_add(t, L_shl_pos(Mpy_32_xx(s4, C52), 1)); + s2 = L_add(t, Mpy_32_xx(s2, C53)); + + /* combination */ + y12 = L_add(r1, s2); + y18 = L_sub(r1, s2); + y14 = L_sub(r3, s4); + y16 = L_add(r3, s4); + + y13 = L_sub(s1, r2); + y19 = L_add(s1, r2); + y15 = L_add(s3, r4); + y17 = L_sub(s3, r4); + + /* 3. FFT5 stage */ + + /* real part */ + r1 = L_add(x22, x28); + r4 = L_sub(x22, x28); + r3 = L_add(x24, x26); + r2 = L_sub(x24, x26); + t = Mpy_32_xx(L_sub(r1, r3), C54); + r1 = L_add(r1, r3); + y20 = L_add(x20, r1); + r1 = L_add(y20, (L_shl_pos(Mpy_32_xx(r1, C55), 1))); + r3 = L_sub(r1, t); + r1 = L_add(r1, t); + t = Mpy_32_xx((L_add(r4, r2)), C51); + r4 = L_add(t, L_shl_pos(Mpy_32_xx(r4, C52), 1)); + r2 = L_add(t, Mpy_32_xx(r2, C53)); + + /* imaginary part */ + s1 = L_add(x23, x29); + s4 = L_sub(x23, x29); + s3 = L_add(x25, x27); + s2 = L_sub(x25, x27); + t = Mpy_32_xx(L_sub(s1, s3), C54); + s1 = L_add(s1, s3); + y21 = L_add(x21, s1); + s1 = L_add(y21, L_shl_pos(Mpy_32_xx(s1, C55), 1)); + s3 = L_sub(s1, t); + s1 = L_add(s1, t); + t = Mpy_32_xx(L_add(s4, s2), C51); + s4 = L_add(t, L_shl_pos(Mpy_32_xx(s4, C52), 1)); + s2 = L_add(t, Mpy_32_xx(s2, C53)); + + /* combination */ + y22 = L_add(r1, s2); + y28 = L_sub(r1, s2); + y24 = L_sub(r3, s4); + y26 = L_add(r3, s4); + + y23 = L_sub(s1, r2); + y29 = L_add(s1, r2); + y25 = L_add(s3, r4); + y27 = L_sub(s3, r4); + + /* 1. FFT3 stage */ + + /* real part */ + r1 = L_add(y10, y20); + r2 = Mpy_32_xx(L_sub(y10, y20), C31); + z00 = L_add(y00, r1); + r1 = L_sub(y00, L_shr_pos(r1, 1)); + + /* imaginary part */ + s1 = L_add(y11, y21); + s2 = Mpy_32_xx(L_sub(y11, y21), C31); + z01 = L_add(y01, s1); + s1 = L_sub(y01, L_shr_pos(s1, 1)); + + /* combination */ + z20 = L_sub(r1, s2); + z10 = L_add(r1, s2); + z21 = L_add(s1, r2); + z11 = L_sub(s1, r2); + + /* 2. FFT3 stage */ + + /* real part */ + r1 = L_add(y12, y22); + r2 = Mpy_32_xx(L_sub(y12, y22), C31); + z12 = L_add(y02, r1); + r1 = L_sub(y02, L_shr_pos(r1, 1)); + + /* imaginary part */ + s1 = L_add(y13, y23); + s2 = Mpy_32_xx(L_sub(y13, y23), C31); + z13 = L_add(y03, s1); + s1 = L_sub(y03, L_shr_pos(s1, 1)); + + /* combination */ + z02 = L_sub(r1, s2); + z22 = L_add(r1, s2); + z03 = L_add(s1, r2); + z23 = L_sub(s1, r2); + + /* 3. FFT3 stage */ + + /* real part */ + r1 = L_add(y14, y24); + r2 = Mpy_32_xx(L_sub(y14, y24), C31); + z24 = L_add(y04, r1); + r1 = L_sub(y04, L_shr_pos(r1, 1)); + + /* imaginary part */ + s1 = L_add(y15, y25); + s2 = Mpy_32_xx(L_sub(y15, y25), C31); + z25 = L_add(y05, s1); + s1 = L_sub(y05, L_shr_pos(s1, 1)); + + /* combination */ + z14 = L_sub(r1, s2); + z04 = L_add(r1, s2); + z15 = L_add(s1, r2); + z05 = L_sub(s1, r2); + + /* 4. FFT3 stage */ + + /* real part */ + r1 = L_add(y16, y26); + r2 = Mpy_32_xx(L_sub(y16, y26), C31); + z06 = L_add(y06, r1); + r1 = L_sub(y06, L_shr_pos(r1, 1)); + + /* imaginary part */ + s1 = L_add(y17, y27); + s2 = Mpy_32_xx(L_sub(y17, y27), C31); + z07 = L_add(y07, s1); + s1 = L_sub(y07, L_shr_pos(s1, 1)); + + /* combination */ + z26 = L_sub(r1, s2); + z16 = L_add(r1, s2); + z27 = L_add(s1, r2); + z17 = L_sub(s1, r2); + + /* 5. FFT3 stage */ + + /* real part */ + r1 = L_add(y18, y28); + r2 = Mpy_32_xx(L_sub(y18, y28), C31); + z18 = L_add(y08, r1); + r1 = L_sub(y08, L_shr_pos(r1, 1)); + + /* imaginary part */ + s1 = L_add(y19, y29); + s2 = Mpy_32_xx(L_sub(y19, y29), C31); + z19 = L_add(y09, s1); + s1 = L_sub(y09, L_shr_pos(s1, 1)); + + /* combination */ + z08 = L_sub(r1, s2); + z28 = L_add(r1, s2); + z09 = L_add(s1, r2); + z29 = L_sub(s1, r2); + + /* 2. FFT15 stage */ + x00 = L_shr_pos(re[s * 15], SCALEFACTOR30_1); + x01 = L_shr_pos(im[s * 15], SCALEFACTOR30_1); + x02 = L_shr_pos(re[s * 3], SCALEFACTOR30_1); + x03 = L_shr_pos(im[s * 3], SCALEFACTOR30_1); + x04 = L_shr_pos(re[s * 21], SCALEFACTOR30_1); + x05 = L_shr_pos(im[s * 21], SCALEFACTOR30_1); + x06 = L_shr_pos(re[s * 9], SCALEFACTOR30_1); + x07 = L_shr_pos(im[s * 9], SCALEFACTOR30_1); + x08 = L_shr_pos(re[s * 27], SCALEFACTOR30_1); + x09 = L_shr_pos(im[s * 27], SCALEFACTOR30_1); + + x10 = L_shr_pos(re[s * 5], SCALEFACTOR30_1); + x11 = L_shr_pos(im[s * 5], SCALEFACTOR30_1); + x12 = L_shr_pos(re[s * 23], SCALEFACTOR30_1); + x13 = L_shr_pos(im[s * 23], SCALEFACTOR30_1); + x14 = L_shr_pos(re[s * 11], SCALEFACTOR30_1); + x15 = L_shr_pos(im[s * 11], SCALEFACTOR30_1); + x16 = L_shr_pos(re[s * 29], SCALEFACTOR30_1); + x17 = L_shr_pos(im[s * 29], SCALEFACTOR30_1); + x18 = L_shr_pos(re[s * 17], SCALEFACTOR30_1); + x19 = L_shr_pos(im[s * 17], SCALEFACTOR30_1); + + x20 = L_shr_pos(re[s * 25], SCALEFACTOR30_1); + x21 = L_shr_pos(im[s * 25], SCALEFACTOR30_1); + x22 = L_shr_pos(re[s * 13], SCALEFACTOR30_1); + x23 = L_shr_pos(im[s * 13], SCALEFACTOR30_1); + x24 = L_shr_pos(re[s * 1], SCALEFACTOR30_1); + x25 = L_shr_pos(im[s * 1], SCALEFACTOR30_1); + x26 = L_shr_pos(re[s * 19], SCALEFACTOR30_1); + x27 = L_shr_pos(im[s * 19], SCALEFACTOR30_1); + x28 = L_shr_pos(re[s * 7], SCALEFACTOR30_1); + x29 = L_shr_pos(im[s * 7], SCALEFACTOR30_1); + + /* 1. FFT5 stage */ + + /* real part */ + r1 = L_add(x02, x08); + r4 = L_sub(x02, x08); + r3 = L_add(x04, x06); + r2 = L_sub(x04, x06); + t = Mpy_32_xx(L_sub(r1, r3), C54); + r1 = L_add(r1, r3); + y00 = L_add(x00, r1); + r1 = L_add(y00, (L_shl_pos(Mpy_32_xx(r1, C55), 1))); + r3 = L_sub(r1, t); + r1 = L_add(r1, t); + t = Mpy_32_xx((L_add(r4, r2)), C51); + r4 = L_add(t, L_shl_pos(Mpy_32_xx(r4, C52), 1)); + r2 = L_add(t, Mpy_32_xx(r2, C53)); + + /* imaginary part */ + s1 = L_add(x03, x09); + s4 = L_sub(x03, x09); + s3 = L_add(x05, x07); + s2 = L_sub(x05, x07); + t = Mpy_32_xx(L_sub(s1, s3), C54); + s1 = L_add(s1, s3); + y01 = L_add(x01, s1); + s1 = L_add(y01, L_shl_pos(Mpy_32_xx(s1, C55), 1)); + s3 = L_sub(s1, t); + s1 = L_add(s1, t); + t = Mpy_32_xx(L_add(s4, s2), C51); + s4 = L_add(t, L_shl_pos(Mpy_32_xx(s4, C52), 1)); + s2 = L_add(t, Mpy_32_xx(s2, C53)); + + /* combination */ + y02 = L_add(r1, s2); + y08 = L_sub(r1, s2); + y04 = L_sub(r3, s4); + y06 = L_add(r3, s4); + + y03 = L_sub(s1, r2); + y09 = L_add(s1, r2); + y05 = L_add(s3, r4); + y07 = L_sub(s3, r4); + + /* 2. FFT5 stage */ + + /* real part */ + r1 = L_add(x12, x18); + r4 = L_sub(x12, x18); + r3 = L_add(x14, x16); + r2 = L_sub(x14, x16); + t = Mpy_32_xx(L_sub(r1, r3), C54); + r1 = L_add(r1, r3); + y10 = L_add(x10, r1); + r1 = L_add(y10, (L_shl_pos(Mpy_32_xx(r1, C55), 1))); + r3 = L_sub(r1, t); + r1 = L_add(r1, t); + t = Mpy_32_xx((L_add(r4, r2)), C51); + r4 = L_add(t, L_shl_pos(Mpy_32_xx(r4, C52), 1)); + r2 = L_add(t, Mpy_32_xx(r2, C53)); + + /* imaginary part */ + s1 = L_add(x13, x19); + s4 = L_sub(x13, x19); + s3 = L_add(x15, x17); + s2 = L_sub(x15, x17); + t = Mpy_32_xx(L_sub(s1, s3), C54); + s1 = L_add(s1, s3); + y11 = L_add(x11, s1); + s1 = L_add(y11, L_shl_pos(Mpy_32_xx(s1, C55), 1)); + s3 = L_sub(s1, t); + s1 = L_add(s1, t); + t = Mpy_32_xx(L_add(s4, s2), C51); + s4 = L_add(t, L_shl_pos(Mpy_32_xx(s4, C52), 1)); + s2 = L_add(t, Mpy_32_xx(s2, C53)); + + /* combination */ + y12 = L_add(r1, s2); + y18 = L_sub(r1, s2); + y14 = L_sub(r3, s4); + y16 = L_add(r3, s4); + + y13 = L_sub(s1, r2); + y19 = L_add(s1, r2); + y15 = L_add(s3, r4); + y17 = L_sub(s3, r4); + + /* 3. FFT5 stage */ + + /* real part */ + r1 = L_add(x22, x28); + r4 = L_sub(x22, x28); + r3 = L_add(x24, x26); + r2 = L_sub(x24, x26); + t = Mpy_32_xx(L_sub(r1, r3), C54); + r1 = L_add(r1, r3); + y20 = L_add(x20, r1); + r1 = L_add(y20, (L_shl_pos(Mpy_32_xx(r1, C55), 1))); + r3 = L_sub(r1, t); + r1 = L_add(r1, t); + t = Mpy_32_xx((L_add(r4, r2)), C51); + r4 = L_add(t, L_shl_pos(Mpy_32_xx(r4, C52), 1)); + r2 = L_add(t, Mpy_32_xx(r2, C53)); + + /* imaginary part */ + s1 = L_add(x23, x29); + s4 = L_sub(x23, x29); + s3 = L_add(x25, x27); + s2 = L_sub(x25, x27); + t = Mpy_32_xx(L_sub(s1, s3), C54); + s1 = L_add(s1, s3); + y21 = L_add(x21, s1); + s1 = L_add(y21, L_shl_pos(Mpy_32_xx(s1, C55), 1)); + s3 = L_sub(s1, t); + s1 = L_add(s1, t); + t = Mpy_32_xx(L_add(s4, s2), C51); + s4 = L_add(t, L_shl_pos(Mpy_32_xx(s4, C52), 1)); + s2 = L_add(t, Mpy_32_xx(s2, C53)); + + /* combination */ + y22 = L_add(r1, s2); + y28 = L_sub(r1, s2); + y24 = L_sub(r3, s4); + y26 = L_add(r3, s4); + + y23 = L_sub(s1, r2); + y29 = L_add(s1, r2); + y25 = L_add(s3, r4); + y27 = L_sub(s3, r4); + + /* 1. FFT3 stage */ + + /* real part */ + r1 = L_add(y10, y20); + r2 = Mpy_32_xx(L_sub(y10, y20), C31); + z30 = L_add(y00, r1); + r1 = L_sub(y00, L_shr_pos(r1, 1)); + + /* imaginary part */ + s1 = L_add(y11, y21); + s2 = Mpy_32_xx(L_sub(y11, y21), C31); + z31 = L_add(y01, s1); + s1 = L_sub(y01, L_shr_pos(s1, 1)); + + /* combination */ + z50 = L_sub(r1, s2); + z40 = L_add(r1, s2); + z51 = L_add(s1, r2); + z41 = L_sub(s1, r2); + + /* 2. FFT3 stage */ + + /* real part */ + r1 = L_add(y12, y22); + r2 = Mpy_32_xx(L_sub(y12, y22), C31); + z42 = L_add(y02, r1); + r1 = L_sub(y02, L_shr_pos(r1, 1)); + + /* imaginary part */ + s1 = L_add(y13, y23); + s2 = Mpy_32_xx(L_sub(y13, y23), C31); + z43 = L_add(y03, s1); + s1 = L_sub(y03, L_shr_pos(s1, 1)); + + /* combination */ + z32 = L_sub(r1, s2); + z52 = L_add(r1, s2); + z33 = L_add(s1, r2); + z53 = L_sub(s1, r2); + + /* 3. FFT3 stage */ + + /* real part */ + r1 = L_add(y14, y24); + r2 = Mpy_32_xx(L_sub(y14, y24), C31); + z54 = L_add(y04, r1); + r1 = L_sub(y04, L_shr_pos(r1, 1)); + + /* imaginary part */ + s1 = L_add(y15, y25); + s2 = Mpy_32_xx(L_sub(y15, y25), C31); + z55 = L_add(y05, s1); + s1 = L_sub(y05, L_shr_pos(s1, 1)); + + /* combination */ + z44 = L_sub(r1, s2); + z34 = L_add(r1, s2); + z45 = L_add(s1, r2); + z35 = L_sub(s1, r2); + + /* 4. FFT3 stage */ + + /* real part */ + r1 = L_add(y16, y26); + r2 = Mpy_32_xx(L_sub(y16, y26), C31); + z36 = L_add(y06, r1); + r1 = L_sub(y06, L_shr_pos(r1, 1)); + + /* imaginary part */ + s1 = L_add(y17, y27); + s2 = Mpy_32_xx(L_sub(y17, y27), C31); + z37 = L_add(y07, s1); + s1 = L_sub(y07, L_shr_pos(s1, 1)); + + /* combination */ + z56 = L_sub(r1, s2); + z46 = L_add(r1, s2); + z57 = L_add(s1, r2); + z47 = L_sub(s1, r2); + + /* 5. FFT3 stage */ + + /* real part */ + r1 = L_add(y18, y28); + r2 = Mpy_32_xx(L_sub(y18, y28), C31); + z48 = L_add(y08, r1); + r1 = L_sub(y08, L_shr_pos(r1, 1)); + + /* imaginary part */ + s1 = L_add(y19, y29); + s2 = Mpy_32_xx(L_sub(y19, y29), C31); + z49 = L_add(y09, s1); + s1 = L_sub(y09, L_shr_pos(s1, 1)); + + /* combination */ + z38 = L_sub(r1, s2); + z58 = L_add(r1, s2); + z39 = L_add(s1, r2); + z59 = L_sub(s1, r2); + + /* 1. FFT2 stage */ + r1 = L_shr_pos(z00, SCALEFACTOR30_2); + r2 = L_shr_pos(z30, SCALEFACTOR30_2); + r3 = L_shr_pos(z01, SCALEFACTOR30_2); + r4 = L_shr_pos(z31, SCALEFACTOR30_2); + *rel = L_add(r1, r2); + move32(); + *reh = L_sub(r1, r2); + move32(); + *iml = L_add(r3, r4); + move32(); + *imh = L_sub(r3, r4); + move32(); + rel += s, reh += s, iml += s; + imh += s; + + /* 2. FFT2 stage */ + r1 = L_shr_pos(z16, SCALEFACTOR30_2); + r2 = L_shr_pos(z46, SCALEFACTOR30_2); + r3 = L_shr_pos(z17, SCALEFACTOR30_2); + r4 = L_shr_pos(z47, SCALEFACTOR30_2); + *reh = L_add(r1, r2); + move32(); + *rel = L_sub(r1, r2); + move32(); + *imh = L_add(r3, r4); + move32(); + *iml = L_sub(r3, r4); + move32(); + rel += s, reh += s, iml += s; + imh += s; + + /* 3. FFT2 stage */ + r1 = L_shr_pos(z02, SCALEFACTOR30_2); + r2 = L_shr_pos(z32, SCALEFACTOR30_2); + r3 = L_shr_pos(z03, SCALEFACTOR30_2); + r4 = L_shr_pos(z33, SCALEFACTOR30_2); + *rel = L_add(r1, r2); + move32(); + *reh = L_sub(r1, r2); + move32(); + *iml = L_add(r3, r4); + move32(); + *imh = L_sub(r3, r4); + move32(); + rel += s, reh += s, iml += s; + imh += s; + + /* 4. FFT2 stage */ + r1 = L_shr_pos(z18, SCALEFACTOR30_2); + r2 = L_shr_pos(z48, SCALEFACTOR30_2); + r3 = L_shr_pos(z19, SCALEFACTOR30_2); + r4 = L_shr_pos(z49, SCALEFACTOR30_2); + *reh = L_add(r1, r2); + move32(); + *rel = L_sub(r1, r2); + move32(); + *imh = L_add(r3, r4); + move32(); + *iml = L_sub(r3, r4); + move32(); + rel += s, reh += s, iml += s; + imh += s; + + /* 5. FFT2 stage */ + r1 = L_shr_pos(z04, SCALEFACTOR30_2); + r2 = L_shr_pos(z34, SCALEFACTOR30_2); + r3 = L_shr_pos(z05, SCALEFACTOR30_2); + r4 = L_shr_pos(z35, SCALEFACTOR30_2); + *rel = L_add(r1, r2); + move32(); + *reh = L_sub(r1, r2); + move32(); + *iml = L_add(r3, r4); + move32(); + *imh = L_sub(r3, r4); + move32(); + rel += s, reh += s, iml += s; + imh += s; + + /* 6. FFT2 stage */ + r1 = L_shr_pos(z20, SCALEFACTOR30_2); + r2 = L_shr_pos(z50, SCALEFACTOR30_2); + r3 = L_shr_pos(z21, SCALEFACTOR30_2); + r4 = L_shr_pos(z51, SCALEFACTOR30_2); + *reh = L_add(r1, r2); + move32(); + *rel = L_sub(r1, r2); + move32(); + *imh = L_add(r3, r4); + move32(); + *iml = L_sub(r3, r4); + move32(); + rel += s, reh += s, iml += s; + imh += s; + + /* 7. FFT2 stage */ + r1 = L_shr_pos(z06, SCALEFACTOR30_2); + r2 = L_shr_pos(z36, SCALEFACTOR30_2); + r3 = L_shr_pos(z07, SCALEFACTOR30_2); + r4 = L_shr_pos(z37, SCALEFACTOR30_2); + *rel = L_add(r1, r2); + move32(); + *reh = L_sub(r1, r2); + move32(); + *iml = L_add(r3, r4); + move32(); + *imh = L_sub(r3, r4); + move32(); + rel += s, reh += s, iml += s; + imh += s; + + /* 8. FFT2 stage */ + r1 = L_shr_pos(z22, SCALEFACTOR30_2); + r2 = L_shr_pos(z52, SCALEFACTOR30_2); + r3 = L_shr_pos(z23, SCALEFACTOR30_2); + r4 = L_shr_pos(z53, SCALEFACTOR30_2); + *reh = L_add(r1, r2); + move32(); + *rel = L_sub(r1, r2); + move32(); + *imh = L_add(r3, r4); + move32(); + *iml = L_sub(r3, r4); + move32(); + rel += s, reh += s, iml += s; + imh += s; + + /* 9. FFT2 stage */ + r1 = L_shr_pos(z08, SCALEFACTOR30_2); + r2 = L_shr_pos(z38, SCALEFACTOR30_2); + r3 = L_shr_pos(z09, SCALEFACTOR30_2); + r4 = L_shr_pos(z39, SCALEFACTOR30_2); + *rel = L_add(r1, r2); + move32(); + *reh = L_sub(r1, r2); + move32(); + *iml = L_add(r3, r4); + move32(); + *imh = L_sub(r3, r4); + move32(); + rel += s, reh += s, iml += s; + imh += s; + + /* 10. FFT2 stage */ + r1 = L_shr_pos(z24, SCALEFACTOR30_2); + r2 = L_shr_pos(z54, SCALEFACTOR30_2); + r3 = L_shr_pos(z25, SCALEFACTOR30_2); + r4 = L_shr_pos(z55, SCALEFACTOR30_2); + *reh = L_add(r1, r2); + move32(); + *rel = L_sub(r1, r2); + move32(); + *imh = L_add(r3, r4); + move32(); + *iml = L_sub(r3, r4); + move32(); + rel += s, reh += s, iml += s; + imh += s; + + /* 11. FFT2 stage */ + r1 = L_shr_pos(z10, SCALEFACTOR30_2); + r2 = L_shr_pos(z40, SCALEFACTOR30_2); + r3 = L_shr_pos(z11, SCALEFACTOR30_2); + r4 = L_shr_pos(z41, SCALEFACTOR30_2); + *rel = L_add(r1, r2); + move32(); + *reh = L_sub(r1, r2); + move32(); + *iml = L_add(r3, r4); + move32(); + *imh = L_sub(r3, r4); + move32(); + rel += s, reh += s, iml += s; + imh += s; + + /* 12. FFT2 stage */ + r1 = L_shr_pos(z26, SCALEFACTOR30_2); + r2 = L_shr_pos(z56, SCALEFACTOR30_2); + r3 = L_shr_pos(z27, SCALEFACTOR30_2); + r4 = L_shr_pos(z57, SCALEFACTOR30_2); + *reh = L_add(r1, r2); + move32(); + *rel = L_sub(r1, r2); + move32(); + *imh = L_add(r3, r4); + move32(); + *iml = L_sub(r3, r4); + move32(); + rel += s, reh += s, iml += s; + imh += s; + + /* 13. FFT2 stage */ + r1 = L_shr_pos(z12, SCALEFACTOR30_2); + r2 = L_shr_pos(z42, SCALEFACTOR30_2); + r3 = L_shr_pos(z13, SCALEFACTOR30_2); + r4 = L_shr_pos(z43, SCALEFACTOR30_2); + *rel = L_add(r1, r2); + move32(); + *reh = L_sub(r1, r2); + move32(); + *iml = L_add(r3, r4); + move32(); + *imh = L_sub(r3, r4); + move32(); + rel += s, reh += s, iml += s; + imh += s; + + /* 14. FFT2 stage */ + r1 = L_shr_pos(z28, SCALEFACTOR30_2); + r2 = L_shr_pos(z58, SCALEFACTOR30_2); + r3 = L_shr_pos(z29, SCALEFACTOR30_2); + r4 = L_shr_pos(z59, SCALEFACTOR30_2); + *reh = L_add(r1, r2); + move32(); + *rel = L_sub(r1, r2); + move32(); + *imh = L_add(r3, r4); + move32(); + *iml = L_sub(r3, r4); + move32(); + rel += s, reh += s, iml += s; + imh += s; + + /* 15. FFT2 stage */ + r1 = L_shr_pos(z14, SCALEFACTOR30_2); + r2 = L_shr_pos(z44, SCALEFACTOR30_2); + r3 = L_shr_pos(z15, SCALEFACTOR30_2); + r4 = L_shr_pos(z45, SCALEFACTOR30_2); + *rel = L_add(r1, r2); + move32(); + *reh = L_sub(r1, r2); + move32(); + *iml = L_add(r3, r4); + move32(); + *imh = L_sub(r3, r4); + move32(); + rel += s, reh += s, iml += s; + imh += s; + + Dyn_Mem_Deluxe_Out(); +} + +/** + * \brief Function performs a complex 32-point FFT + * The FFT is performed inplace. The result of the FFT + * is scaled by SCALEFACTOR32 bits. + * + * WOPS with 32x16 bit multiplications: 752 cycles + * + * \param [i/o] re real input / output + * \param [i/o] im imag input / output + * \param [i ] s stride real and imag input / output + * + * \return void + */ + + +static void fft32(Word32 *re, Word32 *im, Word16 s) +{ + Dyn_Mem_Deluxe_In(Word32 as, bs; Word32 x00, x01, x02, x03, x04, x05, x06, x07; + Word32 x08, x09, x10, x11, x12, x13, x14, x15; Word32 t00, t01, t02, t03, t04, t05, t06, t07; + Word32 t08, t09, t10, t11, t12, t13, t14, t15; Word32 s00, s01, s02, s03, s04, s05, s06, s07; + Word32 s08, s09, s10, s11, s12, s13, s14, s15; + + Word32 y00, y01, y02, y03, y04, y05, y06, y07; Word32 y08, y09, y10, y11, y12, y13, y14, y15; + Word32 y16, y17, y18, y19, y20, y21, y22, y23; Word32 y24, y25, y26, y27, y28, y29, y30, y31; + Word32 y32, y33, y34, y35, y36, y37, y38, y39; Word32 y40, y41, y42, y43, y44, y45, y46, y47; + Word32 y48, y49, y50, y51, y52, y53, y54, y55; Word32 y56, y57, y58, y59, y60, y61, y62, y63;); + + /* 1. FFT8 stage */ + x00 = L_shr_pos(re[s * 0], SCALEFACTOR32_1); + x01 = L_shr_pos(im[s * 0], SCALEFACTOR32_1); + x02 = L_shr_pos(re[s * 4], SCALEFACTOR32_1); + x03 = L_shr_pos(im[s * 4], SCALEFACTOR32_1); + x04 = L_shr_pos(re[s * 8], SCALEFACTOR32_1); + x05 = L_shr_pos(im[s * 8], SCALEFACTOR32_1); + x06 = L_shr_pos(re[s * 12], SCALEFACTOR32_1); + x07 = L_shr_pos(im[s * 12], SCALEFACTOR32_1); + x08 = L_shr_pos(re[s * 16], SCALEFACTOR32_1); + x09 = L_shr_pos(im[s * 16], SCALEFACTOR32_1); + x10 = L_shr_pos(re[s * 20], SCALEFACTOR32_1); + x11 = L_shr_pos(im[s * 20], SCALEFACTOR32_1); + x12 = L_shr_pos(re[s * 24], SCALEFACTOR32_1); + x13 = L_shr_pos(im[s * 24], SCALEFACTOR32_1); + x14 = L_shr_pos(re[s * 28], SCALEFACTOR32_1); + x15 = L_shr_pos(im[s * 28], SCALEFACTOR32_1); + + t00 = L_add(x00, x08); + t02 = L_sub(x00, x08); + t01 = L_add(x01, x09); + t03 = L_sub(x01, x09); + t04 = L_add(x02, x10); + t06 = L_sub(x02, x10); + t05 = L_add(x03, x11); + t07 = L_sub(x03, x11); + t08 = L_add(x04, x12); + t10 = L_sub(x04, x12); + t09 = L_add(x05, x13); + t11 = L_sub(x05, x13); + t12 = L_add(x06, x14); + t14 = L_sub(x06, x14); + t13 = L_add(x07, x15); + t15 = L_sub(x07, x15); + + /* Pre-additions and core multiplications */ + s00 = L_add(t00, t08); + s04 = L_sub(t00, t08); + s01 = L_add(t01, t09); + s05 = L_sub(t01, t09); + s08 = L_sub(t02, t11); + s10 = L_add(t02, t11); + s09 = L_add(t03, t10); + s11 = L_sub(t03, t10); + s02 = L_add(t04, t12); + s07 = L_sub(t04, t12); + s03 = L_add(t05, t13); + s06 = L_sub(t13, t05); + t01 = L_add(t06, t14); + t02 = L_sub(t06, t14); + t00 = L_add(t07, t15); + t03 = L_sub(t07, t15); + + Mpy3_0(s12, s13, s14, s15, t00, t01, t02, t03); + + /* Post-additions */ + y00 = L_add(s00, s02); + y08 = L_sub(s00, s02); + y01 = L_add(s01, s03); + y09 = L_sub(s01, s03); + y04 = L_sub(s04, s06); + y12 = L_add(s04, s06); + y05 = L_sub(s05, s07); + y13 = L_add(s05, s07); + y06 = L_add(s08, s14); + y14 = L_sub(s08, s14); + y07 = L_add(s09, s15); + y15 = L_sub(s09, s15); + y02 = L_add(s10, s12); + y10 = L_sub(s10, s12); + y03 = L_add(s11, s13); + y11 = L_sub(s11, s13); + + /* 2. FFT8 stage */ + x00 = L_shr_pos(re[s * 1], SCALEFACTOR32_1); + x01 = L_shr_pos(im[s * 1], SCALEFACTOR32_1); + x02 = L_shr_pos(re[s * 5], SCALEFACTOR32_1); + x03 = L_shr_pos(im[s * 5], SCALEFACTOR32_1); + x04 = L_shr_pos(re[s * 9], SCALEFACTOR32_1); + x05 = L_shr_pos(im[s * 9], SCALEFACTOR32_1); + x06 = L_shr_pos(re[s * 13], SCALEFACTOR32_1); + x07 = L_shr_pos(im[s * 13], SCALEFACTOR32_1); + x08 = L_shr_pos(re[s * 17], SCALEFACTOR32_1); + x09 = L_shr_pos(im[s * 17], SCALEFACTOR32_1); + x10 = L_shr_pos(re[s * 21], SCALEFACTOR32_1); + x11 = L_shr_pos(im[s * 21], SCALEFACTOR32_1); + x12 = L_shr_pos(re[s * 25], SCALEFACTOR32_1); + x13 = L_shr_pos(im[s * 25], SCALEFACTOR32_1); + x14 = L_shr_pos(re[s * 29], SCALEFACTOR32_1); + x15 = L_shr_pos(im[s * 29], SCALEFACTOR32_1); + + t00 = L_add(x00, x08); + t02 = L_sub(x00, x08); + t01 = L_add(x01, x09); + t03 = L_sub(x01, x09); + t04 = L_add(x02, x10); + t06 = L_sub(x02, x10); + t05 = L_add(x03, x11); + t07 = L_sub(x03, x11); + t08 = L_add(x04, x12); + t10 = L_sub(x04, x12); + t09 = L_add(x05, x13); + t11 = L_sub(x05, x13); + t12 = L_add(x06, x14); + t14 = L_sub(x06, x14); + t13 = L_add(x07, x15); + t15 = L_sub(x07, x15); + + /* Pre-additions and core multiplications */ + s00 = L_add(t00, t08); + s04 = L_sub(t00, t08); + s01 = L_add(t01, t09); + s05 = L_sub(t01, t09); + s08 = L_sub(t02, t11); + s10 = L_add(t02, t11); + s09 = L_add(t03, t10); + s11 = L_sub(t03, t10); + s02 = L_add(t04, t12); + s07 = L_sub(t04, t12); + s03 = L_add(t05, t13); + s06 = L_sub(t13, t05); + t01 = L_add(t06, t14); + t02 = L_sub(t06, t14); + t00 = L_add(t07, t15); + t03 = L_sub(t07, t15); + + Mpy3_0(s12, s13, s14, s15, t00, t01, t02, t03); + + /* Post-additions */ + y16 = L_add(s00, s02); + y24 = L_sub(s00, s02); + y17 = L_add(s01, s03); + y25 = L_sub(s01, s03); + y20 = L_sub(s04, s06); + y28 = L_add(s04, s06); + y21 = L_sub(s05, s07); + y29 = L_add(s05, s07); + y22 = L_add(s08, s14); + y30 = L_sub(s08, s14); + y23 = L_add(s09, s15); + y31 = L_sub(s09, s15); + y18 = L_add(s10, s12); + y26 = L_sub(s10, s12); + y19 = L_add(s11, s13); + y27 = L_sub(s11, s13); + + /* 3. FFT8 stage */ + x00 = L_shr_pos(re[s * 2], SCALEFACTOR32_1); + x01 = L_shr_pos(im[s * 2], SCALEFACTOR32_1); + x02 = L_shr_pos(re[s * 6], SCALEFACTOR32_1); + x03 = L_shr_pos(im[s * 6], SCALEFACTOR32_1); + x04 = L_shr_pos(re[s * 10], SCALEFACTOR32_1); + x05 = L_shr_pos(im[s * 10], SCALEFACTOR32_1); + x06 = L_shr_pos(re[s * 14], SCALEFACTOR32_1); + x07 = L_shr_pos(im[s * 14], SCALEFACTOR32_1); + x08 = L_shr_pos(re[s * 18], SCALEFACTOR32_1); + x09 = L_shr_pos(im[s * 18], SCALEFACTOR32_1); + x10 = L_shr_pos(re[s * 22], SCALEFACTOR32_1); + x11 = L_shr_pos(im[s * 22], SCALEFACTOR32_1); + x12 = L_shr_pos(re[s * 26], SCALEFACTOR32_1); + x13 = L_shr_pos(im[s * 26], SCALEFACTOR32_1); + x14 = L_shr_pos(re[s * 30], SCALEFACTOR32_1); + x15 = L_shr_pos(im[s * 30], SCALEFACTOR32_1); + + t00 = L_add(x00, x08); + t02 = L_sub(x00, x08); + t01 = L_add(x01, x09); + t03 = L_sub(x01, x09); + t04 = L_add(x02, x10); + t06 = L_sub(x02, x10); + t05 = L_add(x03, x11); + t07 = L_sub(x03, x11); + t08 = L_add(x04, x12); + t10 = L_sub(x04, x12); + t09 = L_add(x05, x13); + t11 = L_sub(x05, x13); + t12 = L_add(x06, x14); + t14 = L_sub(x06, x14); + t13 = L_add(x07, x15); + t15 = L_sub(x07, x15); + + /* Pre-additions and core multiplications */ + s00 = L_add(t00, t08); + s04 = L_sub(t00, t08); + s01 = L_add(t01, t09); + s05 = L_sub(t01, t09); + s08 = L_sub(t02, t11); + s10 = L_add(t02, t11); + s09 = L_add(t03, t10); + s11 = L_sub(t03, t10); + s02 = L_add(t04, t12); + s07 = L_sub(t04, t12); + s03 = L_add(t05, t13); + s06 = L_sub(t13, t05); + t01 = L_add(t06, t14); + t02 = L_sub(t06, t14); + t00 = L_add(t07, t15); + t03 = L_sub(t07, t15); + + Mpy3_0(s12, s13, s14, s15, t00, t01, t02, t03); + + /* Post-additions */ + y32 = L_add(s00, s02); + y40 = L_sub(s00, s02); + y33 = L_add(s01, s03); + y41 = L_sub(s01, s03); + y36 = L_sub(s04, s06); + y44 = L_add(s04, s06); + y37 = L_sub(s05, s07); + y45 = L_add(s05, s07); + y38 = L_add(s08, s14); + y46 = L_sub(s08, s14); + y39 = L_add(s09, s15); + y47 = L_sub(s09, s15); + y34 = L_add(s10, s12); + y42 = L_sub(s10, s12); + y35 = L_add(s11, s13); + y43 = L_sub(s11, s13); + + /* 4. FFT8 stage */ + x00 = L_shr_pos(re[s * 3], SCALEFACTOR32_1); + x01 = L_shr_pos(im[s * 3], SCALEFACTOR32_1); + x02 = L_shr_pos(re[s * 7], SCALEFACTOR32_1); + x03 = L_shr_pos(im[s * 7], SCALEFACTOR32_1); + x04 = L_shr_pos(re[s * 11], SCALEFACTOR32_1); + x05 = L_shr_pos(im[s * 11], SCALEFACTOR32_1); + x06 = L_shr_pos(re[s * 15], SCALEFACTOR32_1); + x07 = L_shr_pos(im[s * 15], SCALEFACTOR32_1); + x08 = L_shr_pos(re[s * 19], SCALEFACTOR32_1); + x09 = L_shr_pos(im[s * 19], SCALEFACTOR32_1); + x10 = L_shr_pos(re[s * 23], SCALEFACTOR32_1); + x11 = L_shr_pos(im[s * 23], SCALEFACTOR32_1); + x12 = L_shr_pos(re[s * 27], SCALEFACTOR32_1); + x13 = L_shr_pos(im[s * 27], SCALEFACTOR32_1); + x14 = L_shr_pos(re[s * 31], SCALEFACTOR32_1); + x15 = L_shr_pos(im[s * 31], SCALEFACTOR32_1); + + t00 = L_add(x00, x08); + t02 = L_sub(x00, x08); + t01 = L_add(x01, x09); + t03 = L_sub(x01, x09); + t04 = L_add(x02, x10); + t06 = L_sub(x02, x10); + t05 = L_add(x03, x11); + t07 = L_sub(x03, x11); + t08 = L_add(x04, x12); + t10 = L_sub(x04, x12); + t09 = L_add(x05, x13); + t11 = L_sub(x05, x13); + t12 = L_add(x06, x14); + t14 = L_sub(x06, x14); + t13 = L_add(x07, x15); + t15 = L_sub(x07, x15); + + /* Pre-additions and core multiplications */ + s00 = L_add(t00, t08); + s04 = L_sub(t00, t08); + s01 = L_add(t01, t09); + s05 = L_sub(t01, t09); + s08 = L_sub(t02, t11); + s10 = L_add(t02, t11); + s09 = L_add(t03, t10); + s11 = L_sub(t03, t10); + s02 = L_add(t04, t12); + s07 = L_sub(t04, t12); + s03 = L_add(t05, t13); + s06 = L_sub(t13, t05); + t01 = L_add(t06, t14); + t02 = L_sub(t06, t14); + t00 = L_add(t07, t15); + t03 = L_sub(t07, t15); + + Mpy3_0(s12, s13, s14, s15, t00, t01, t02, t03); + + /* Post-additions */ + y48 = L_add(s00, s02); + y56 = L_sub(s00, s02); + y49 = L_add(s01, s03); + y57 = L_sub(s01, s03); + y52 = L_sub(s04, s06); + y60 = L_add(s04, s06); + y53 = L_sub(s05, s07); + y61 = L_add(s05, s07); + y54 = L_add(s08, s14); + y62 = L_sub(s08, s14); + y55 = L_add(s09, s15); + y63 = L_sub(s09, s15); + y50 = L_add(s10, s12); + y58 = L_sub(s10, s12); + y51 = L_add(s11, s13); + y59 = L_sub(s11, s13); + + /* apply twiddle factors */ + y00 = L_shr_pos(y00, SCALEFACTOR32_2); + y01 = L_shr_pos(y01, SCALEFACTOR32_2); + y02 = L_shr_pos(y02, SCALEFACTOR32_2); + y03 = L_shr_pos(y03, SCALEFACTOR32_2); + y04 = L_shr_pos(y04, SCALEFACTOR32_2); + y05 = L_shr_pos(y05, SCALEFACTOR32_2); + y06 = L_shr_pos(y06, SCALEFACTOR32_2); + y07 = L_shr_pos(y07, SCALEFACTOR32_2); + y08 = L_shr_pos(y08, SCALEFACTOR32_2); + y09 = L_shr_pos(y09, SCALEFACTOR32_2); + y10 = L_shr_pos(y10, SCALEFACTOR32_2); + y11 = L_shr_pos(y11, SCALEFACTOR32_2); + y12 = L_shr_pos(y12, SCALEFACTOR32_2); + y13 = L_shr_pos(y13, SCALEFACTOR32_2); + y14 = L_shr_pos(y14, SCALEFACTOR32_2); + y15 = L_shr_pos(y15, SCALEFACTOR32_2); + y16 = L_shr_pos(y16, SCALEFACTOR32_2); + y17 = L_shr_pos(y17, SCALEFACTOR32_2); + y32 = L_shr_pos(y32, SCALEFACTOR32_2); + y33 = L_shr_pos(y33, SCALEFACTOR32_2); + y48 = L_shr_pos(y48, SCALEFACTOR32_2); + y49 = L_shr_pos(y49, SCALEFACTOR32_2); + y40 = L_shr_pos(y40, SCALEFACTOR32_2); + y41 = L_shr_pos(y41, SCALEFACTOR32_2); + + cplxMpy3_0(y18, y19, RotVector_32_32[2 * 0 + 0], RotVector_32_32[2 * 0 + 1]); + cplxMpy3_0(y20, y21, RotVector_32_32[2 * 1 + 0], RotVector_32_32[2 * 1 + 1]); + cplxMpy3_0(y22, y23, RotVector_32_32[2 * 2 + 0], RotVector_32_32[2 * 2 + 1]); + cplxMpy3_0(y24, y25, RotVector_32_32[2 * 3 + 0], RotVector_32_32[2 * 3 + 1]); + cplxMpy3_0(y26, y27, RotVector_32_32[2 * 4 + 0], RotVector_32_32[2 * 4 + 1]); + cplxMpy3_0(y28, y29, RotVector_32_32[2 * 5 + 0], RotVector_32_32[2 * 5 + 1]); + cplxMpy3_0(y30, y31, RotVector_32_32[2 * 6 + 0], RotVector_32_32[2 * 6 + 1]); + cplxMpy3_0(y34, y35, RotVector_32_32[2 * 7 + 0], RotVector_32_32[2 * 7 + 1]); + cplxMpy3_0(y36, y37, RotVector_32_32[2 * 8 + 0], RotVector_32_32[2 * 8 + 1]); + cplxMpy3_0(y38, y39, RotVector_32_32[2 * 9 + 0], RotVector_32_32[2 * 9 + 1]); + cplxMpy3_0(y42, y43, RotVector_32_32[2 * 10 + 0], RotVector_32_32[2 * 10 + 1]); + cplxMpy3_0(y44, y45, RotVector_32_32[2 * 11 + 0], RotVector_32_32[2 * 11 + 1]); + cplxMpy3_0(y46, y47, RotVector_32_32[2 * 12 + 0], RotVector_32_32[2 * 12 + 1]); + cplxMpy3_0(y50, y51, RotVector_32_32[2 * 13 + 0], RotVector_32_32[2 * 13 + 1]); + cplxMpy3_0(y52, y53, RotVector_32_32[2 * 14 + 0], RotVector_32_32[2 * 14 + 1]); + cplxMpy3_0(y54, y55, RotVector_32_32[2 * 15 + 0], RotVector_32_32[2 * 15 + 1]); + cplxMpy3_0(y56, y57, RotVector_32_32[2 * 16 + 0], RotVector_32_32[2 * 16 + 1]); + cplxMpy3_0(y58, y59, RotVector_32_32[2 * 17 + 0], RotVector_32_32[2 * 17 + 1]); + cplxMpy3_0(y60, y61, RotVector_32_32[2 * 18 + 0], RotVector_32_32[2 * 18 + 1]); + cplxMpy3_0(y62, y63, RotVector_32_32[2 * 19 + 0], RotVector_32_32[2 * 19 + 1]); + + /* 1. FFT4 stage */ + + /* Pre-additions */ + t00 = L_add(y00, y32); + t02 = L_sub(y00, y32); + t01 = L_add(y01, y33); + t03 = L_sub(y01, y33); + t04 = L_add(y16, y48); + t07 = L_sub(y16, y48); + t05 = L_add(y49, y17); + t06 = L_sub(y49, y17); + + /* Post-additions */ + re[s * 0] = L_add(t00, t04); + move32(); + im[s * 0] = L_add(t01, t05); + move32(); + re[s * 8] = L_sub(t02, t06); + move32(); + im[s * 8] = L_sub(t03, t07); + move32(); + re[s * 16] = L_sub(t00, t04); + move32(); + im[s * 16] = L_sub(t01, t05); + move32(); + re[s * 24] = L_add(t02, t06); + move32(); + im[s * 24] = L_add(t03, t07); + move32(); + + /* 2. FFT4 stage */ + + /* Pre-additions */ + t00 = L_add(y02, y34); + t02 = L_sub(y02, y34); + t01 = L_add(y03, y35); + t03 = L_sub(y03, y35); + t04 = L_add(y18, y50); + t07 = L_sub(y18, y50); + t05 = L_add(y51, y19); + t06 = L_sub(y51, y19); + + /* Post-additions */ + re[s * 1] = L_add(t00, t04); + move32(); + im[s * 1] = L_add(t01, t05); + move32(); + re[s * 9] = L_sub(t02, t06); + move32(); + im[s * 9] = L_sub(t03, t07); + move32(); + re[s * 17] = L_sub(t00, t04); + move32(); + im[s * 17] = L_sub(t01, t05); + move32(); + re[s * 25] = L_add(t02, t06); + move32(); + im[s * 25] = L_add(t03, t07); + move32(); + + /* 3. FFT4 stage */ + + /* Pre-additions */ + t00 = L_add(y04, y36); + t02 = L_sub(y04, y36); + t01 = L_add(y05, y37); + t03 = L_sub(y05, y37); + t04 = L_add(y20, y52); + t07 = L_sub(y20, y52); + t05 = L_add(y53, y21); + t06 = L_sub(y53, y21); + + /* Post-additions */ + re[s * 2] = L_add(t00, t04); + move32(); + im[s * 2] = L_add(t01, t05); + move32(); + re[s * 10] = L_sub(t02, t06); + move32(); + im[s * 10] = L_sub(t03, t07); + move32(); + re[s * 18] = L_sub(t00, t04); + move32(); + im[s * 18] = L_sub(t01, t05); + move32(); + re[s * 26] = L_add(t02, t06); + move32(); + im[s * 26] = L_add(t03, t07); + move32(); + + /* 4. FFT4 stage */ + + /* Pre-additions */ + t00 = L_add(y06, y38); + t02 = L_sub(y06, y38); + t01 = L_add(y07, y39); + t03 = L_sub(y07, y39); + t04 = L_add(y22, y54); + t07 = L_sub(y22, y54); + t05 = L_add(y55, y23); + t06 = L_sub(y55, y23); + + /* Post-additions */ + re[s * 3] = L_add(t00, t04); + move32(); + im[s * 3] = L_add(t01, t05); + move32(); + re[s * 11] = L_sub(t02, t06); + move32(); + im[s * 11] = L_sub(t03, t07); + move32(); + re[s * 19] = L_sub(t00, t04); + move32(); + im[s * 19] = L_sub(t01, t05); + move32(); + re[s * 27] = L_add(t02, t06); + move32(); + im[s * 27] = L_add(t03, t07); + move32(); + + /* 5. FFT4 stage */ + + /* Pre-additions */ + t00 = L_add(y08, y41); + t02 = L_sub(y08, y41); + t01 = L_sub(y09, y40); + t03 = L_add(y09, y40); + t04 = L_add(y24, y56); + t07 = L_sub(y24, y56); + t05 = L_add(y57, y25); + t06 = L_sub(y57, y25); + + /* Post-additions */ + re[s * 4] = L_add(t00, t04); + move32(); + im[s * 4] = L_add(t01, t05); + move32(); + re[s * 12] = L_sub(t02, t06); + move32(); + im[s * 12] = L_sub(t03, t07); + move32(); + re[s * 20] = L_sub(t00, t04); + move32(); + im[s * 20] = L_sub(t01, t05); + move32(); + re[s * 28] = L_add(t02, t06); + move32(); + im[s * 28] = L_add(t03, t07); + move32(); + + /* 6. FFT4 stage */ + + /* Pre-additions */ + t00 = L_add(y10, y42); + t02 = L_sub(y10, y42); + t01 = L_add(y11, y43); + t03 = L_sub(y11, y43); + t04 = L_add(y26, y58); + t07 = L_sub(y26, y58); + t05 = L_add(y59, y27); + t06 = L_sub(y59, y27); + + /* Post-additions */ + re[s * 5] = L_add(t00, t04); + move32(); + im[s * 5] = L_add(t01, t05); + move32(); + re[s * 13] = L_sub(t02, t06); + move32(); + im[s * 13] = L_sub(t03, t07); + move32(); + re[s * 21] = L_sub(t00, t04); + move32(); + im[s * 21] = L_sub(t01, t05); + move32(); + re[s * 29] = L_add(t02, t06); + move32(); + im[s * 29] = L_add(t03, t07); + move32(); + + /* 7. FFT4 stage */ + + /* Pre-additions */ + t00 = L_add(y12, y44); + t02 = L_sub(y12, y44); + t01 = L_add(y13, y45); + t03 = L_sub(y13, y45); + t04 = L_add(y28, y60); + t07 = L_sub(y28, y60); + t05 = L_add(y61, y29); + t06 = L_sub(y61, y29); + + /* Post-additions */ + re[s * 6] = L_add(t00, t04); + move32(); + im[s * 6] = L_add(t01, t05); + move32(); + re[s * 14] = L_sub(t02, t06); + move32(); + im[s * 14] = L_sub(t03, t07); + move32(); + re[s * 22] = L_sub(t00, t04); + move32(); + im[s * 22] = L_sub(t01, t05); + move32(); + re[s * 30] = L_add(t02, t06); + move32(); + im[s * 30] = L_add(t03, t07); + move32(); + + /* 8. FFT4 stage */ + + /* Pre-additions */ + t00 = L_add(y14, y46); + t02 = L_sub(y14, y46); + t01 = L_add(y15, y47); + t03 = L_sub(y15, y47); + t04 = L_add(y30, y62); + t07 = L_sub(y30, y62); + t05 = L_add(y63, y31); + t06 = L_sub(y63, y31); + + /* Post-additions */ + re[s * 7] = L_add(t00, t04); + move32(); + im[s * 7] = L_add(t01, t05); + move32(); + re[s * 15] = L_sub(t02, t06); + move32(); + im[s * 15] = L_sub(t03, t07); + move32(); + re[s * 23] = L_sub(t00, t04); + move32(); + im[s * 23] = L_sub(t01, t05); + move32(); + re[s * 31] = L_add(t02, t06); + move32(); + im[s * 31] = L_add(t03, t07); + move32(); + + Dyn_Mem_Deluxe_Out(); +} + +/** + * \brief Function performs a complex 40-point FFT + * The FFT is performed inplace. The result of the FFT + * is scaled by SCALEFACTOR40 bits. + * + * \param [i/o] re real part + * \param [i/o] im imag part + * \param [i ] sx stride real and imag part + * + * \return void + */ + + + +static void fft40(Word32 *re, Word32 *im, Word16 sx, Word32 *x) +{ + Dyn_Mem_Deluxe_In(const Word32 *W; Word16 dim1, dim2; Counter i, j; + Word32 x00, x01, x02, x03, x04, x05, x06, x07, x08, x09, x10, x11, x12, x13, x14, x15; + Word32 t00, t01, t02, t03, t04, t05, t06, t07, t08, t09, t10, t11, t12, t13, t14, t15; + Word32 s00, s01, s02, s03, s04, s05, s06, s07, s08, s09, s10, s11, s12, s13, s14, s15;); + + dim1 = 5; + move16(); + dim2 = 8; + move16(); + + W = RotVector_40_32; + + FOR (i = 0; i < dim2; i++) + { + FOR (j = 0; j < dim1; j++) + { + x[2 * i * dim1 + 2 * j] = re[sx * i + sx * j * dim2]; + move32(); + x[2 * i * dim1 + 2 * j + 1] = im[sx * i + sx * j * dim2]; + move32(); + } + } + + FOR (i = 0; i < dim2; i++) + { + fft5(&x[i * 2 * dim1], &x[i * 2 * dim1 + 1], 2); + } + + FOR (i = 0; i < dim1; i++) + { + cplxMpy4_8_1(x00, x01, x[2 * i + 2 * 0 * dim1], x[2 * i + 2 * 0 * dim1 + 1]); + + IF (i == 0) + { + cplxMpy4_8_1(x02, x03, x[2 * i + 2 * 1 * dim1], x[2 * i + 2 * 1 * dim1 + 1]); + cplxMpy4_8_1(x04, x05, x[2 * i + 2 * 2 * dim1], x[2 * i + 2 * 2 * dim1 + 1]); + cplxMpy4_8_1(x06, x07, x[2 * i + 2 * 3 * dim1], x[2 * i + 2 * 3 * dim1 + 1]); + cplxMpy4_8_1(x08, x09, x[2 * i + 2 * 4 * dim1], x[2 * i + 2 * 4 * dim1 + 1]); + cplxMpy4_8_1(x10, x11, x[2 * i + 2 * 5 * dim1], x[2 * i + 2 * 5 * dim1 + 1]); + cplxMpy4_8_1(x12, x13, x[2 * i + 2 * 6 * dim1], x[2 * i + 2 * 6 * dim1 + 1]); + cplxMpy4_8_1(x14, x15, x[2 * i + 2 * 7 * dim1], x[2 * i + 2 * 7 * dim1 + 1]); + } + ELSE + { + cplxMpy4_8_2(x02, x03, x[2 * i + 2 * 1 * dim1], x[2 * i + 2 * 1 * dim1 + 1], W[2 * (i - 1) + 0 * 2 * 4], + W[2 * (i - 1) + 0 * 2 * 4 + 1]); + cplxMpy4_8_2(x04, x05, x[2 * i + 2 * 2 * dim1], x[2 * i + 2 * 2 * dim1 + 1], W[2 * (i - 1) + 1 * 2 * 4], + W[2 * (i - 1) + 1 * 2 * 4 + 1]); + cplxMpy4_8_2(x06, x07, x[2 * i + 2 * 3 * dim1], x[2 * i + 2 * 3 * dim1 + 1], W[2 * (i - 1) + 2 * 2 * 4], + W[2 * (i - 1) + 2 * 2 * 4 + 1]); + cplxMpy4_8_2(x08, x09, x[2 * i + 2 * 4 * dim1], x[2 * i + 2 * 4 * dim1 + 1], W[2 * (i - 1) + 3 * 2 * 4], + W[2 * (i - 1) + 3 * 2 * 4 + 1]); + cplxMpy4_8_2(x10, x11, x[2 * i + 2 * 5 * dim1], x[2 * i + 2 * 5 * dim1 + 1], W[2 * (i - 1) + 4 * 2 * 4], + W[2 * (i - 1) + 4 * 2 * 4 + 1]); + cplxMpy4_8_2(x12, x13, x[2 * i + 2 * 6 * dim1], x[2 * i + 2 * 6 * dim1 + 1], W[2 * (i - 1) + 5 * 2 * 4], + W[2 * (i - 1) + 5 * 2 * 4 + 1]); + cplxMpy4_8_2(x14, x15, x[2 * i + 2 * 7 * dim1], x[2 * i + 2 * 7 * dim1 + 1], W[2 * (i - 1) + 6 * 2 * 4], + W[2 * (i - 1) + 6 * 2 * 4 + 1]); + } + + t00 = L_shr_pos(L_add(x00, x08), SCALEFACTORN2 - 1); + t02 = L_shr_pos(L_sub(x00, x08), SCALEFACTORN2 - 1); + t01 = L_shr_pos(L_add(x01, x09), SCALEFACTORN2 - 1); + t03 = L_shr_pos(L_sub(x01, x09), SCALEFACTORN2 - 1); + t04 = L_shr_pos(L_add(x02, x10), SCALEFACTORN2 - 1); + t06 = L_sub(x02, x10); + t05 = L_shr_pos(L_add(x03, x11), SCALEFACTORN2 - 1); + t07 = L_sub(x03, x11); + t08 = L_shr_pos(L_add(x04, x12), SCALEFACTORN2 - 1); + t10 = L_shr_pos(L_sub(x04, x12), SCALEFACTORN2 - 1); + t09 = L_shr_pos(L_add(x05, x13), SCALEFACTORN2 - 1); + t11 = L_shr_pos(L_sub(x05, x13), SCALEFACTORN2 - 1); + t12 = L_shr_pos(L_add(x06, x14), SCALEFACTORN2 - 1); + t14 = L_sub(x06, x14); + t13 = L_shr_pos(L_add(x07, x15), SCALEFACTORN2 - 1); + t15 = L_sub(x07, x15); + + s00 = L_add(t00, t08); + s04 = L_sub(t00, t08); + s01 = L_add(t01, t09); + s05 = L_sub(t01, t09); + s08 = L_sub(t02, t11); + s10 = L_add(t02, t11); + s09 = L_add(t03, t10); + s11 = L_sub(t03, t10); + s02 = L_add(t04, t12); + s07 = L_sub(t04, t12); + s03 = L_add(t05, t13); + s06 = L_sub(t13, t05); + + t01 = L_shr_pos(L_add(t06, t14), SCALEFACTORN2 - 1); + t02 = L_shr_pos(L_sub(t06, t14), SCALEFACTORN2 - 1); + t00 = L_shr_pos(L_add(t07, t15), SCALEFACTORN2 - 1); + t03 = L_shr_pos(L_sub(t07, t15), SCALEFACTORN2 - 1); + + s12 = Mpy_32_32_lc3plus(L_add(t00, t02), C81_32); + s14 = Mpy_32_32_lc3plus(L_sub(t00, t02), C81_32); + s13 = Mpy_32_32_lc3plus(L_sub(t03, t01), C81_32); + s15 = Mpy_32_32_lc3plus(L_add(t01, t03), C82_32); + + re[sx * i + sx * 0 * dim1] = L_add(s00, s02); + move32(); + im[sx * i + sx * 0 * dim1] = L_add(s01, s03); + move32(); + re[sx * i + sx * 1 * dim1] = L_add(s10, s12); + move32(); + im[sx * i + sx * 1 * dim1] = L_add(s11, s13); + move32(); + re[sx * i + sx * 2 * dim1] = L_sub(s04, s06); + move32(); + im[sx * i + sx * 2 * dim1] = L_sub(s05, s07); + move32(); + re[sx * i + sx * 3 * dim1] = L_add(s08, s14); + move32(); + im[sx * i + sx * 3 * dim1] = L_add(s09, s15); + move32(); + re[sx * i + sx * 4 * dim1] = L_sub(s00, s02); + move32(); + im[sx * i + sx * 4 * dim1] = L_sub(s01, s03); + move32(); + re[sx * i + sx * 5 * dim1] = L_sub(s10, s12); + move32(); + im[sx * i + sx * 5 * dim1] = L_sub(s11, s13); + move32(); + re[sx * i + sx * 6 * dim1] = L_add(s04, s06); + move32(); + im[sx * i + sx * 6 * dim1] = L_add(s05, s07); + move32(); + re[sx * i + sx * 7 * dim1] = L_sub(s08, s14); + move32(); + im[sx * i + sx * 7 * dim1] = L_sub(s09, s15); + move32(); + } + + Dyn_Mem_Deluxe_Out(); +} + +/** + * \brief Combined FFT + * + * \param [i/o] re real part + * \param [i/o] im imag part + * \param [i ] W rotation factor + * \param [i ] dim1 length of fft1 + * \param [i ] dim2 length of fft2 + * \param [i ] sx stride real and imag part + * \param [i ] sc stride phase rotation coefficients + * \param [tmp] x 32-bit workbuffer of length=2*len + * \param [i ] Woff offset for addressing the rotation vector table + * + * \return void + */ + + +static void fftN2(Word32 *re, Word32 *im, +#ifdef ENABLE_HR_MODE + const Word32 *W, +#else + const Word16 *W, +#endif + Word16 dim1, Word16 dim2, Word16 sx, Word16 sc, + Word16 Woff + , Word8 *scratchBuffer +#ifdef ENABLE_FFT_RESCALE + , Word16 *scale +#endif + ) +{ + Dyn_Mem_Deluxe_In(Counter i, j;); + + Word32 *x = scratchAlign(scratchBuffer, 0); + + FOR (i = 0; i < dim2; i++) + { + FOR (j = 0; j < dim1; j++) + { + x[2 * i * dim1 + 2 * j] = re[sx * i + sx * j * dim2]; + move32(); + x[2 * i * dim1 + 2 * j + 1] = im[sx * i + sx * j * dim2]; + move32(); + } + } + + SWITCH (dim1) + { + + case 4: + FOR (i = 0; i < dim2; i++) + { + fft4(&x[i * 2 * dim1]); + } + BREAK; + case 8: + FOR (i = 0; i < dim2; i++) + { + fft8(&x[i * 2 * dim1], &x[i * 2 * dim1 + 1], 2); + } + BREAK; + + case 10: + FOR (i = 0; i < dim2; i++) + { + fft10(&x[i * 2 * dim1], &x[i * 2 * dim1 + 1], 2); + } + BREAK; + case 15: + FOR (i = 0; i < dim2; i++) + { + fft15(&x[i * 2 * dim1], &x[i * 2 * dim1 + 1], 2); + } + + BREAK; + case 16: + FOR (i = 0; i < dim2; i++) + { + fft16(&x[i * 2 * dim1], &x[i * 2 * dim1 + 1], 2); + } + BREAK; + case 20: + FOR (i = 0; i < dim2; i++) + { + fft20(&x[i * 2 * dim1], &x[i * 2 * dim1 + 1], 2); + } + BREAK; + case 30: + FOR (i = 0; i < dim2; i++) + { + fft30(&x[i * 2 * dim1], &x[i * 2 * dim1 + 1], 2); + } + BREAK; + case 32: + FOR (i = 0; i < dim2; i++) + { + fft32(&x[i * 2 * dim1], &x[i * 2 * dim1 + 1], 2); + } + BREAK; +#ifdef ENABLE_HR_MODE +#if (defined LC3_FFT15) + case 60: + FOR (i = 0; i < dim2; i++) + { +#ifndef ENABLE_FFT_RESCALE + fftN2(&x[i * 2 * dim1], &x[i * 2 * dim1 + 1], RotVector_480, 15, 4, sx, 4, 60, scratch); +#else + fftN2(&x[i * 2 * dim1], &x[i * 2 * dim1 + 1], RotVector_480, 15, 4, sx, 4, 60, scratch, NULL); +#endif + } + BREAK; +#endif +#endif + default: ASSERT(0); + } + +#ifdef ENABLE_FFT_RESCALE + IF (scale) + { + *scale = s_max(sub(getScaleFactor32_lc3plus(x, dim1 * dim2 * 2), FFT_RESCALE_HR), 0); move16(); + +#if defined(FUNCTION_scaleValues_32) + scaleValues_32(x, dim1 * dim2, *scale); +#else + FOR (i = 0; i < dim1 * dim2 * 2; i++) + { + x[i] = L_shl_pos(x[i], *scale); move32(); + } + } +#endif +#endif + + SWITCH (dim2) + { + case 4: + { + Word32 x00, x01, x02, x03, x04, x05, x06, x07; + Word32 t00, t01, t02, t03, t04, t05, t06, t07; + + j = add(8, 0); + FOR (i = 0; i < dim1; i++) + { + cplxMpy4_4_1(x00, x01, x[2 * i + 2 * 0 * dim1], x[2 * i + 2 * 0 * dim1 + 1]); + IF (i == 0) + { + cplxMpy4_4_1(x02, x03, x[2 * i + 2 * 1 * dim1], x[2 * i + 2 * 1 * dim1 + 1]); + cplxMpy4_4_1(x04, x05, x[2 * i + 2 * 2 * dim1], x[2 * i + 2 * 2 * dim1 + 1]); + cplxMpy4_4_1(x06, x07, x[2 * i + 2 * 3 * dim1], x[2 * i + 2 * 3 * dim1 + 1]); + } + ELSE + { + cplxMpy4_4_0(x02, x03, x[2 * i + 2 * 1 * dim1], x[2 * i + 2 * 1 * dim1 + 1], + W[sc * i + j * 1 * dim1 - Woff], W[sc * i + j * 1 * dim1 + 1 - Woff]); + cplxMpy4_4_0(x04, x05, x[2 * i + 2 * 2 * dim1], x[2 * i + 2 * 2 * dim1 + 1], + W[sc * i + j * 2 * dim1 - Woff], W[sc * i + j * 2 * dim1 + 1 - Woff]); + cplxMpy4_4_0(x06, x07, x[2 * i + 2 * 3 * dim1], x[2 * i + 2 * 3 * dim1 + 1], + W[sc * i + j * 3 * dim1 - Woff], W[sc * i + j * 3 * dim1 + 1 - Woff]); + } + + t00 = L_add(x00, x04); + t02 = L_sub(x00, x04); + t01 = L_add(x01, x05); + t03 = L_sub(x01, x05); + t04 = L_add(x02, x06); + t07 = L_sub(x02, x06); + t05 = L_add(x07, x03); + t06 = L_sub(x07, x03); + + re[sx * i + sx * 0 * dim1] = L_add(t00, t04); + move32(); + im[sx * i + sx * 0 * dim1] = L_add(t01, t05); + move32(); + re[sx * i + sx * 1 * dim1] = L_sub(t02, t06); + move32(); + im[sx * i + sx * 1 * dim1] = L_sub(t03, t07); + move32(); + re[sx * i + sx * 2 * dim1] = L_sub(t00, t04); + move32(); + im[sx * i + sx * 2 * dim1] = L_sub(t01, t05); + move32(); + re[sx * i + sx * 3 * dim1] = L_add(t02, t06); + move32(); + im[sx * i + sx * 3 * dim1] = L_add(t03, t07); + move32(); + } + + BREAK; + } + +#ifdef CR8_G_ADD_75MS + case 6: + { + Word32 y[2 * 10]; + FOR (j = 0; j < dim2; j++) + { + cplxMpy4_12_1(y[2 * j], y[2 * j + 1], x[2 * 0 + 2 * j * dim1], x[2 * 0 + 2 * j * dim1 + 1]); + } + fft6(&y[0], &y[1], 2); + FOR (j = 0; j < dim2; j++) + { + re[sx * 0 + sx * j * dim1] = y[2 * j]; + move32(); + im[sx * 0 + sx * j * dim1] = y[2 * j + 1]; + move32(); + } + + FOR (i = 1; i < dim1; i++) + { + cplxMpy4_12_1(y[2 * (0 + 0)], y[2 * (0 + 0) + 1], x[2 * i + 2 * (0 + 0) * dim1], + x[2 * i + 2 * (0 + 0) * dim1 + 1]); + cplxMpy4_12_0(y[2 * (0 + 1)], y[2 * (0 + 1) + 1], x[2 * i + 2 * (0 + 1) * dim1], + x[2 * i + 2 * (0 + 1) * dim1 + 1], W[sc * i + sc * (0 + 1) * dim1 - Woff], + W[sc * i + sc * (0 + 1) * dim1 + 1 - Woff]); + FOR (j = 2; j < dim2; j = j + 2) + { + cplxMpy4_12_0(y[2 * (j + 0)], y[2 * (j + 0) + 1], x[2 * i + 2 * (j + 0) * dim1], + x[2 * i + 2 * (j + 0) * dim1 + 1], W[sc * i + sc * (j + 0) * dim1 - Woff], + W[sc * i + sc * (j + 0) * dim1 + 1 - Woff]); + cplxMpy4_12_0(y[2 * (j + 1)], y[2 * (j + 1) + 1], x[2 * i + 2 * (j + 1) * dim1], + x[2 * i + 2 * (j + 1) * dim1 + 1], W[sc * i + sc * (j + 1) * dim1 - Woff], + W[sc * i + sc * (j + 1) * dim1 + 1 - Woff]); + } + fft6(&y[0], &y[1], 2); + FOR (j = 0; j < dim2; j++) + { + re[sx * i + sx * j * dim1] = y[2 * j]; + move32(); + im[sx * i + sx * j * dim1] = y[2 * j + 1]; + move32(); + } + } + BREAK; + } +#endif + + case 8: + { + Word32 x00, x01, x02, x03, x04, x05, x06, x07, x08, x09, x10, x11, x12, x13, x14, x15; + Word32 t00, t01, t02, t03, t04, t05, t06, t07, t08, t09, t10, t11, t12, t13, t14, t15; + Word32 s00, s01, s02, s03, s04, s05, s06, s07, s08, s09, s10, s11, s12, s13, s14, s15; + + FOR (i = 0; i < dim1; i++) + { + cplxMpy4_8_1(x00, x01, x[2 * i + 2 * 0 * dim1], x[2 * i + 2 * 0 * dim1 + 1]); + IF (i == 0) + { + cplxMpy4_8_1(x02, x03, x[2 * i + 2 * 1 * dim1], x[2 * i + 2 * 1 * dim1 + 1]); + cplxMpy4_8_1(x04, x05, x[2 * i + 2 * 2 * dim1], x[2 * i + 2 * 2 * dim1 + 1]); + cplxMpy4_8_1(x06, x07, x[2 * i + 2 * 3 * dim1], x[2 * i + 2 * 3 * dim1 + 1]); + cplxMpy4_8_1(x08, x09, x[2 * i + 2 * 4 * dim1], x[2 * i + 2 * 4 * dim1 + 1]); + cplxMpy4_8_1(x10, x11, x[2 * i + 2 * 5 * dim1], x[2 * i + 2 * 5 * dim1 + 1]); + cplxMpy4_8_1(x12, x13, x[2 * i + 2 * 6 * dim1], x[2 * i + 2 * 6 * dim1 + 1]); + cplxMpy4_8_1(x14, x15, x[2 * i + 2 * 7 * dim1], x[2 * i + 2 * 7 * dim1 + 1]); + } + ELSE + { + cplxMpy4_8_0(x02, x03, x[2 * i + 2 * 1 * dim1], x[2 * i + 2 * 1 * dim1 + 1], + W[sc * i + sc * 1 * dim1 - Woff], W[sc * i + sc * 1 * dim1 + 1 - Woff]); + cplxMpy4_8_0(x04, x05, x[2 * i + 2 * 2 * dim1], x[2 * i + 2 * 2 * dim1 + 1], + W[sc * i + sc * 2 * dim1 - Woff], W[sc * i + sc * 2 * dim1 + 1 - Woff]); + cplxMpy4_8_0(x06, x07, x[2 * i + 2 * 3 * dim1], x[2 * i + 2 * 3 * dim1 + 1], + W[sc * i + sc * 3 * dim1 - Woff], W[sc * i + sc * 3 * dim1 + 1 - Woff]); + cplxMpy4_8_0(x08, x09, x[2 * i + 2 * 4 * dim1], x[2 * i + 2 * 4 * dim1 + 1], + W[sc * i + sc * 4 * dim1 - Woff], W[sc * i + sc * 4 * dim1 + 1 - Woff]); + cplxMpy4_8_0(x10, x11, x[2 * i + 2 * 5 * dim1], x[2 * i + 2 * 5 * dim1 + 1], + W[sc * i + sc * 5 * dim1 - Woff], W[sc * i + sc * 5 * dim1 + 1 - Woff]); + cplxMpy4_8_0(x12, x13, x[2 * i + 2 * 6 * dim1], x[2 * i + 2 * 6 * dim1 + 1], + W[sc * i + sc * 6 * dim1 - Woff], W[sc * i + sc * 6 * dim1 + 1 - Woff]); + cplxMpy4_8_0(x14, x15, x[2 * i + 2 * 7 * dim1], x[2 * i + 2 * 7 * dim1 + 1], + W[sc * i + sc * 7 * dim1 - Woff], W[sc * i + sc * 7 * dim1 + 1 - Woff]); + } + + t00 = L_shr_pos(L_add(x00, x08), SCALEFACTORN2 - 1); + t02 = L_shr_pos(L_sub(x00, x08), SCALEFACTORN2 - 1); + t01 = L_shr_pos(L_add(x01, x09), SCALEFACTORN2 - 1); + t03 = L_shr_pos(L_sub(x01, x09), SCALEFACTORN2 - 1); + t04 = L_shr_pos(L_add(x02, x10), SCALEFACTORN2 - 1); + t06 = L_sub(x02, x10); + t05 = L_shr_pos(L_add(x03, x11), SCALEFACTORN2 - 1); + t07 = L_sub(x03, x11); + t08 = L_shr_pos(L_add(x04, x12), SCALEFACTORN2 - 1); + t10 = L_shr_pos(L_sub(x04, x12), SCALEFACTORN2 - 1); + t09 = L_shr_pos(L_add(x05, x13), SCALEFACTORN2 - 1); + t11 = L_shr_pos(L_sub(x05, x13), SCALEFACTORN2 - 1); + t12 = L_shr_pos(L_add(x06, x14), SCALEFACTORN2 - 1); + t14 = L_sub(x06, x14); + t13 = L_shr_pos(L_add(x07, x15), SCALEFACTORN2 - 1); + t15 = L_sub(x07, x15); + + s00 = L_add(t00, t08); + s04 = L_sub(t00, t08); + s01 = L_add(t01, t09); + s05 = L_sub(t01, t09); + s08 = L_sub(t02, t11); + s10 = L_add(t02, t11); + s09 = L_add(t03, t10); + s11 = L_sub(t03, t10); + s02 = L_add(t04, t12); + s07 = L_sub(t04, t12); + s03 = L_add(t05, t13); + s06 = L_sub(t13, t05); + + t01 = L_shr_pos(L_add(t06, t14), SCALEFACTORN2 - 1); + t02 = L_shr_pos(L_sub(t06, t14), SCALEFACTORN2 - 1); + t00 = L_shr_pos(L_add(t07, t15), SCALEFACTORN2 - 1); + t03 = L_shr_pos(L_sub(t07, t15), SCALEFACTORN2 - 1); + + s12 = Mpy_32_xx(L_add(t00, t02), C81); + s14 = Mpy_32_xx(L_sub(t00, t02), C81); + s13 = Mpy_32_xx(L_sub(t03, t01), C81); + s15 = Mpy_32_xx(L_add(t01, t03), C82); + + re[sx * i + sx * 0 * dim1] = L_add(s00, s02); + move32(); + im[sx * i + sx * 0 * dim1] = L_add(s01, s03); + move32(); + re[sx * i + sx * 1 * dim1] = L_add(s10, s12); + move32(); + im[sx * i + sx * 1 * dim1] = L_add(s11, s13); + move32(); + re[sx * i + sx * 2 * dim1] = L_sub(s04, s06); + move32(); + im[sx * i + sx * 2 * dim1] = L_sub(s05, s07); + move32(); + re[sx * i + sx * 3 * dim1] = L_add(s08, s14); + move32(); + im[sx * i + sx * 3 * dim1] = L_add(s09, s15); + move32(); + re[sx * i + sx * 4 * dim1] = L_sub(s00, s02); + move32(); + im[sx * i + sx * 4 * dim1] = L_sub(s01, s03); + move32(); + re[sx * i + sx * 5 * dim1] = L_sub(s10, s12); + move32(); + im[sx * i + sx * 5 * dim1] = L_sub(s11, s13); + move32(); + re[sx * i + sx * 6 * dim1] = L_add(s04, s06); + move32(); + im[sx * i + sx * 6 * dim1] = L_add(s05, s07); + move32(); + re[sx * i + sx * 7 * dim1] = L_sub(s08, s14); + move32(); + im[sx * i + sx * 7 * dim1] = L_sub(s09, s15); + move32(); + } + BREAK; + } + + case 12: + { + Word32 y[2 * 20]; + FOR (j = 0; j < dim2; j++) + { + cplxMpy4_12_1(y[2 * j], y[2 * j + 1], x[2 * 0 + 2 * j * dim1], x[2 * 0 + 2 * j * dim1 + 1]); + } + fft12(y); + FOR (j = 0; j < dim2; j++) + { + re[sx * 0 + sx * j * dim1] = y[2 * j]; + move32(); + im[sx * 0 + sx * j * dim1] = y[2 * j + 1]; + move32(); + } + + FOR (i = 1; i < dim1; i++) + { + cplxMpy4_12_1(y[2 * (0 + 0)], y[2 * (0 + 0) + 1], x[2 * i + 2 * (0 + 0) * dim1], + x[2 * i + 2 * (0 + 0) * dim1 + 1]); + cplxMpy4_12_0(y[2 * (0 + 1)], y[2 * (0 + 1) + 1], x[2 * i + 2 * (0 + 1) * dim1], + x[2 * i + 2 * (0 + 1) * dim1 + 1], W[sc * i + sc * (0 + 1) * dim1 - Woff], + W[sc * i + sc * (0 + 1) * dim1 + 1 - Woff]); + FOR (j = 2; j < dim2; j = j + 2) + { + cplxMpy4_12_0(y[2 * (j + 0)], y[2 * (j + 0) + 1], x[2 * i + 2 * (j + 0) * dim1], + x[2 * i + 2 * (j + 0) * dim1 + 1], W[sc * i + sc * (j + 0) * dim1 - Woff], + W[sc * i + sc * (j + 0) * dim1 + 1 - Woff]); + cplxMpy4_12_0(y[2 * (j + 1)], y[2 * (j + 1) + 1], x[2 * i + 2 * (j + 1) * dim1], + x[2 * i + 2 * (j + 1) * dim1 + 1], W[sc * i + sc * (j + 1) * dim1 - Woff], + W[sc * i + sc * (j + 1) * dim1 + 1 - Woff]); + } + fft12(y); + FOR (j = 0; j < dim2; j++) + { + re[sx * i + sx * j * dim1] = y[2 * j]; + move32(); + im[sx * i + sx * j * dim1] = y[2 * j + 1]; + move32(); + } + } + BREAK; + } + +#if defined(ENABLE_HR_MODE) + case 16: + { + Word32 y[2 * 20]; + FOR (j = 0; j < dim2; j++) + { + cplxMpy4_16_1(y[2 * j], y[2 * j + 1], x[2 * 0 + 2 * j * dim1], x[2 * 0 + 2 * j * dim1 + 1]); + } + + fft16(&y[0], &y[1], 2); + FOR (j = 0; j < dim2; j++) + { + re[sx * 0 + sx * j * dim1] = y[2 * j]; + move32(); + im[sx * 0 + sx * j * dim1] = y[2 * j + 1]; + move32(); + } + + FOR (i = 1; i < dim1; i++) + { + cplxMpy4_16_1(y[2 * (0 + 0)], y[2 * (0 + 0) + 1], x[2 * i + 2 * (0 + 0) * dim1], + x[2 * i + 2 * (0 + 0) * dim1 + 1]); + cplxMpy4_16_0(y[2 * (0 + 1)], y[2 * (0 + 1) + 1], x[2 * i + 2 * (0 + 1) * dim1], + x[2 * i + 2 * (0 + 1) * dim1 + 1], W[sc * i + sc * (0 + 1) * dim1 - Woff], + W[sc * i + sc * (0 + 1) * dim1 + 1 - Woff]); + FOR (j = 2; j < dim2; j = j + 2) + { + cplxMpy4_16_0(y[2 * (j + 0)], y[2 * (j + 0) + 1], x[2 * i + 2 * (j + 0) * dim1], + x[2 * i + 2 * (j + 0) * dim1 + 1], W[sc * i + sc * (j + 0) * dim1 - Woff], + W[sc * i + sc * (j + 0) * dim1 + 1 - Woff]); + cplxMpy4_16_0(y[2 * (j + 1)], y[2 * (j + 1) + 1], x[2 * i + 2 * (j + 1) * dim1], + x[2 * i + 2 * (j + 1) * dim1 + 1], W[sc * i + sc * (j + 1) * dim1 - Woff], + W[sc * i + sc * (j + 1) * dim1 + 1 - Woff]); + } + fft16(&y[0], &y[1], 2); + FOR (j = 0; j < dim2; j++) + { + re[sx * i + sx * j * dim1] = y[2 * j]; + move32(); + im[sx * i + sx * j * dim1] = y[2 * j + 1]; + move32(); + } + } + BREAK; + } +# endif + default: ASSERT(0); + } + + Dyn_Mem_Deluxe_Out(); +} + +/** + * \brief Complex valued FFT + * + * \param [i/o] re real part + * \param [i/o] im imag part + * \param [i ] sizeOfFft length of fft + * \param [i ] s stride real and imag part + * \param [i ] scale scalefactor + * + * \return void + */ + + + +/* x is the scratch buffer */ +void BASOP_cfft_lc3plus(Word32 *re, Word32 *im, Word16 length, Word16 s, Word16 *scale, Word32 *x) +{ +#if (defined ENABLE_FFT_RESCALE) && ((defined LC3_FFT30) || (defined ENABLE_HR_MODE)) + Word16 fftN2scale = 0; +#endif + +#ifdef ENABLE_HR_MODE + Word8 scratch[6128] = {0}; +#else + Word8 scratch[4068] = {0}; +#endif + + SWITCH (length) + { + + case 10: + fft10(re, im, s); + *scale = add(*scale, SCALEFACTOR10); + move16(); + BREAK; + case 16: + fft16(re, im, s); + *scale = add(*scale, SCALEFACTOR16); + move16(); + BREAK; + case 20: + fft20(re, im, s); + *scale = add(*scale, SCALEFACTOR20); + move16(); + BREAK; + case 30: + fft30(re, im, s); + *scale = add(*scale, SCALEFACTOR30); + move16(); + BREAK; + case 32: + fft32(re, im, s); + *scale = add(*scale, SCALEFACTOR32); + move16(); + BREAK; + case 40: + fft40(re, im, s, x); + *scale = add(*scale, SCALEFACTOR40); + move16(); + BREAK; + case 48: +#ifndef ENABLE_FFT_RESCALE + fftN2(re, im, RotVector_32_12, 4, 12, s, 16, 64, scratch); +#else + fftN2(re, im, RotVector_32_12, 4, 12, s, 16, 64, scratch, NULL); +#endif + *scale = add(*scale, SCALEFACTOR48); + move16(); + BREAK; + case 60: +#ifndef ENABLE_FFT_RESCALE + fftN2(re, im, RotVector_480, 15, 4, s, 4, 60, scratch); +#else + fftN2(re, im, RotVector_480, 15, 4, s, 4, 60, scratch, NULL); +#endif + *scale = add(*scale, SCALEFACTOR60); + move16(); + BREAK; + case 64: +#ifndef ENABLE_FFT_RESCALE + fftN2(re, im, RotVector_32_8, 8, 8, s, 8, 64, scratch); +#else + fftN2(re, im, RotVector_32_8, 8, 8, s, 8, 64, scratch, NULL); +#endif + *scale = add(*scale, SCALEFACTOR64); + move16(); + BREAK; + case 80: +#ifndef ENABLE_FFT_RESCALE + fftN2(re, im, RotVector_320, 10, 8, s, 4, 40, scratch); +#else + fftN2(re, im, RotVector_320, 10, 8, s, 4, 40, scratch, NULL); +#endif + *scale = add(*scale, SCALEFACTOR80); + move16(); + BREAK; + case 90: +#ifndef ENABLE_FFT_RESCALE + fftN2(re, im, RotVector_15_6, 15, 6, s, 2, 30, scratch); +#else + fftN2(re, im, RotVector_15_6, 15, 6, s, 2, 30, scratch, NULL); +#endif + *scale = add(*scale, SCALEFACTOR90); + move16(); + BREAK; + + case 120: +#ifndef ENABLE_FFT_RESCALE + fftN2(re, im, RotVector_480, 15, 8, s, 4, 60, scratch); +#else + fftN2(re, im, RotVector_480, 15, 8, s, 4, 60, scratch, NULL); +#endif + *scale = add(*scale, SCALEFACTOR120); + move16(); + BREAK; + case 128: +#ifndef ENABLE_FFT_RESCALE + fftN2(re, im, RotVector_32_8, 16, 8, s, 4, 64, scratch); +#else + fftN2(re, im, RotVector_32_8, 16, 8, s, 4, 64, scratch, NULL); +#endif + *scale = add(*scale, SCALEFACTOR128); + move16(); + BREAK; + case 160: +#ifndef ENABLE_FFT_RESCALE + fftN2(re, im, RotVector_320, 20, 8, s, 2, 40, scratch); +#else + fftN2(re, im, RotVector_320, 20, 8, s, 2, 40, scratch, NULL); +#endif + *scale = add(*scale, SCALEFACTOR160); + move16(); + BREAK; + case 180: +#ifndef ENABLE_FFT_RESCALE + fftN2(re, im, RotVector_360, 15, 12, s, 4, 60, scratch); + *scale = add(*scale, SCALEFACTOR180); +#else + fftN2(re, im, RotVector_360, 15, 12, s, 4, 60, scratch, &fftN2scale); + *scale = add(*scale, SCALEFACTOR180); + *scale = sub(*scale, fftN2scale); move16(); +#endif + + move16(); + BREAK; + case 192: +#ifndef ENABLE_FFT_RESCALE + fftN2(re, im, RotVector_32_12, 16, 12, s, 4, 64, scratch); +#else + fftN2(re, im, RotVector_32_12, 16, 12, s, 4, 64, scratch, NULL); +#endif + *scale = add(*scale, SCALEFACTOR192); + move16(); + BREAK; + case 240: +#ifndef ENABLE_FFT_RESCALE + fftN2(re, im, RotVector_480, 30, 8, s, 2, 60, scratch); + *scale = add(*scale, SCALEFACTOR240); +#else + fftN2(re, im, RotVector_480, 30, 8, s, 2, 60, scratch, &fftN2scale); + *scale = add(*scale, SCALEFACTOR240); + *scale = sub(*scale, fftN2scale); move16(); +#endif + move16(); + BREAK; + case 256: +#ifndef ENABLE_FFT_RESCALE + fftN2(re, im, RotVector_32_8, 32, 8, s, 2, 64, scratch); +#else + fftN2(re, im, RotVector_32_8, 32, 8, s, 2, 64, scratch, NULL); +#endif + *scale = add(*scale, SCALEFACTOR256); + move16(); + BREAK; + case 384: +#ifndef ENABLE_FFT_RESCALE + fftN2(re, im, RotVector_32_12, 32, 12, s, 2, 64, scratch); +#else + fftN2(re, im, RotVector_32_12, 32, 12, s, 2, 64, scratch, NULL); +#endif + *scale = add(*scale, SCALEFACTOR384); + move16(); + BREAK; +#ifdef ENABLE_HR_MODE +#ifdef CR8_G_ADD_75MS + case 360: + fftN2(re, im, RotVector_720, 30, 12, s, 2, 60, scratch, &fftN2scale); + *scale = add(*scale, SCALEFACTOR360); move16(); + *scale = sub(*scale, fftN2scale); move16(); + BREAK; +#endif + case 480: +#ifndef ENABLE_FFT_RESCALE +#ifndef ENABLE_FFT_30X16 + fftN2(re, im, RotVector_960, 60, 8, s, 2, 120, scratch); +#else + fftN2(re, im, RotVector_30_16, 30, 16, s, 2, 60, scratch); +#endif + *scale = add(*scale, SCALEFACTOR480); move16(); +#else +#ifndef ENABLE_FFT_30X16 + fftN2(re, im, RotVector_960, 60, 8, s, 2, 120, scratch, &fftN2scale); +#else + fftN2(re, im, RotVector_30_16, 30, 16, s, 2, 60, scratch, &fftN2scale); +#endif + *scale = add(*scale, SCALEFACTOR480); move16(); + *scale = sub(*scale, fftN2scale); move16(); +#endif + BREAK; +#endif + default: ASSERT(0); + } +} + + +#define RFFT_TWIDDLE1(x, t1, t2, t3, t4, w1, w2, xb0, xb1, xt0, xt1) \ + do \ + { \ + xb0 = L_shr_pos(x[2 * i + 0], 2); \ + xb1 = L_shr_pos(x[2 * i + 1], 2); \ + xt0 = L_shr_pos(x[sizeOfFft - 2 * i + 0], 2); \ + xt1 = L_shr_pos(x[sizeOfFft - 2 * i + 1], 2); \ + t1 = L_sub(xb0, xt0); \ + t2 = L_add(xb1, xt1); \ + t3 = L_sub(Mpy_32_32_lc3plus(t1, w1), Mpy_32_32_lc3plus(t2, w2)); \ + t4 = L_add(Mpy_32_32_lc3plus(t1, w2), Mpy_32_32_lc3plus(t2, w1)); \ + t1 = L_add(xb0, xt0); \ + t2 = L_sub(xb1, xt1); \ + } while (0) + +#define RFFT_TWIDDLE2(x, t1, t2, t3, t4, w1, w2, xb0, xb1, xt0, xt1) \ + do \ + { \ + xb0 = L_shr_pos(x[2 * i + 0], 2); \ + xb1 = L_shr_pos(x[2 * i + 1], 2); \ + xt0 = L_shr_pos(x[sizeOfFft - 2 * i + 0], 2); \ + xt1 = L_shr_pos(x[sizeOfFft - 2 * i + 1], 2); \ + t1 = L_sub(xb0, xt0); \ + t2 = L_add(xb1, xt1); \ + t3 = L_add(Mpy_32_32_lc3plus(t1, w1), Mpy_32_32_lc3plus(t2, w2)); \ + t4 = L_sub(Mpy_32_32_lc3plus(t2, w1), Mpy_32_32_lc3plus(t1, w2)); \ + t1 = L_add(xb0, xt0); \ + t2 = L_sub(xb1, xt1); \ + } while (0) + + + +static const Word32 *rfft_twid(int size) +{ + SWITCH (size) + { + case 32: return RealFFT32_twid; + case 40: return RealFFT40_twid; + case 64: return RealFFT64_twid; + case 80: return RealFFT80_twid; + case 96: return RealFFT96_twid; + case 128: return RealFFT128_twid; + case 192: return RealFFT192_twid; + case 256: return RealFFT256_twid; + case 384: return RealFFT384_twid; + case 512: return RealFFT512_twid; + case 768: return RealFFT768_twid; + default: ASSERT(0); + } + return NULL; +} + + +void BASOP_rfftN(Word32 *x, Word16 sizeOfFft, Word16 *scale, Word8 *scratchBuffer) +{ + Dyn_Mem_Deluxe_In(Counter i; Word16 sizeOfFft2, sizeOfFft4, sizeOfFft8; Word32 t1, t2, t3, t4, xb0, xb1, xt0, xt1; + Word32 * workBuffer; const Word32 *w32;); + + workBuffer = (Word32 *)scratchAlign(scratchBuffer, 0); /* Size = 4 * sizeOfFft */ + w32 = rfft_twid(sizeOfFft); + + sizeOfFft2 = shr_pos(sizeOfFft, 1); + sizeOfFft4 = shr_pos(sizeOfFft, 2); + sizeOfFft8 = shr_pos(sizeOfFft, 3); + + BASOP_cfft_lc3plus(&x[0], &x[1], sizeOfFft2, 2, scale, workBuffer); + + xb0 = L_shr_pos(x[0], 1); + xb1 = L_shr_pos(x[1], 1); + x[0] = L_add(xb0, xb1); + move32(); + x[1] = L_sub(xb0, xb1); + move32(); + + FOR (i = 1; i < sizeOfFft8; i++) + { + RFFT_TWIDDLE1(x, t1, t2, t3, t4, w32[2 * i + 1], w32[2 * i], xb0, xb1, xt0, xt1); + x[2 * i] = L_sub(t1, t3); + move32(); + x[2 * i + 1] = L_sub(t2, t4); + move32(); + x[sizeOfFft - 2 * i] = L_add(t1, t3); + move32(); + x[sizeOfFft - 2 * i + 1] = L_negate(L_add(t2, t4)); + move32(); + } + + FOR (i = sizeOfFft8; i < sizeOfFft4; i++) + { + RFFT_TWIDDLE1(x, t1, t2, t3, t4, w32[(2 * sizeOfFft4 - 2 * i)], w32[(2 * sizeOfFft4 - 2 * i + 1)], xb0, xb1, + xt0, xt1); + x[2 * i] = L_sub(t1, t3); + move32(); + x[2 * i + 1] = L_sub(t2, t4); + move32(); + x[sizeOfFft - 2 * i] = L_add(t1, t3); + move32(); + x[sizeOfFft - 2 * i + 1] = L_negate(L_add(t2, t4)); + move32(); + } + + x[sizeOfFft - 2 * i] = L_shr_pos(x[2 * i + 0], 1); + move32(); + x[sizeOfFft - 2 * i + 1] = L_negate(L_shr_pos(x[2 * i + 1], 1)); + move32(); + + *scale = add(*scale, 1); + move16(); + + Dyn_Mem_Deluxe_Out(); +} + + + +void BASOP_irfftN(Word32 *x, Word16 sizeOfFft, Word16 *scale, Word8 *scratchBuffer) +{ + Dyn_Mem_Deluxe_In(Word16 sizeOfFft2, sizeOfFft4, sizeOfFft8; Word32 t1, t2, t3, t4, xb0, xb1, xt0, xt1; + Word32 * workBuffer; const Word32 *w32; Counter i;); + + workBuffer = (Word32 *)scratchAlign(scratchBuffer, 0); /* Size = 2 * BASOP_CFFT_MAX_LENGTH */ + + w32 = rfft_twid(sizeOfFft); + + sizeOfFft2 = shr_pos(sizeOfFft, 1); + sizeOfFft4 = shr_pos(sizeOfFft, 2); + sizeOfFft8 = shr_pos(sizeOfFft, 3); + + xb0 = L_shr_pos(x[0], 2); + xb1 = L_shr_pos(x[1], 2); + x[0] = L_add(xb0, xb1); + move32(); + x[1] = L_sub(xb1, xb0); + move32(); + + FOR (i = 1; i < sizeOfFft8; i++) + { + RFFT_TWIDDLE2(x, t1, t2, t3, t4, w32[2 * i + 1], w32[2 * i], xb0, xb1, xt0, xt1); + x[2 * i] = L_sub(t1, t3); + move32(); + x[2 * i + 1] = L_sub(t4, t2); + move32(); + x[sizeOfFft - 2 * i] = L_add(t1, t3); + move32(); + x[sizeOfFft - 2 * i + 1] = L_add(t2, t4); + move32(); + } + + FOR (i = sizeOfFft8; i < sizeOfFft4; i++) + { + RFFT_TWIDDLE2(x, t1, t2, t3, t4, w32[(2 * sizeOfFft4 - 2 * i)], w32[(2 * sizeOfFft4 - 2 * i + 1)], xb0, xb1, + xt0, xt1); + x[2 * i] = L_sub(t1, t3); + move32(); + x[2 * i + 1] = L_sub(t4, t2); + move32(); + x[sizeOfFft - 2 * i] = L_add(t1, t3); + move32(); + x[sizeOfFft - 2 * i + 1] = L_add(t2, t4); + move32(); + } + + x[sizeOfFft - 2 * i] = L_shr_pos(x[2 * i + 0], 1); + move32(); + x[sizeOfFft - 2 * i + 1] = L_shr_pos(x[2 * i + 1], 1); + move32(); + + BASOP_cfft_lc3plus(&x[0], &x[1], sizeOfFft2, 2, scale, workBuffer); + + /* If you want BASOP_irfft to be inverse to BASOP_rfft then the result needs + * to be normalised by sizeOfFft */ + FOR (i = 0; i < sizeOfFft2; i++) + { + x[2 * i + 1] = L_negate(x[2 * i + 1]); + move32(); + } + + *scale = add(*scale, 2); + move16(); + + Dyn_Mem_Deluxe_Out(); +} + + diff --git a/lib_lc3plus/functions.h b/lib_lc3plus/functions.h new file mode 100644 index 0000000000000000000000000000000000000000..940c58da7973af05a50bc3dd88ba0461ae2b5c90 --- /dev/null +++ b/lib_lc3plus/functions.h @@ -0,0 +1,837 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.5 * +* Low Complexity Communication Codec Plus (LC3plus) * +* * +* Copyright licence is solely granted through ETSI Intellectual Property * +* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * +* estoppel or otherwise. * +******************************************************************************/ + +#ifndef FUNCTIONS_H +#define FUNCTIONS_H + +#include "defines.h" + +#include "stl.h" +#ifdef DYNMEM_COUNT +#include "dynmem.h" +#endif + +#include "basop_util_lc3plus.h" +#include "basop32.h" +#include "constants.h" +#include "lc3.h" +#include "setup_dec_lc3.h" /* for decoder state handle ptr */ +#include "setup_enc_lc3.h" /* for encoder state handle ptr */ +#include "basop_mpy_lc3plus.h" + +#include +#include +#include +#include +#include + +#define PRINTF printf /* C console debug, */ +#define ASSERT(test) assert(test) + +typedef struct +{ + Word16 lead_sign_ind; /* this MPVQ index is the first part of the total PVQ index */ + UWord32 index, size; /* this MPVQ index is the second part of the total PVQ index */ + Word16 dim, k_val; + Word16 vec[PVQ_MAX_VEC_SIZE]; /* integer vector */ +} PvqEntry_fx; + +typedef enum { + LC3_CON_TEC_NS_STD, /* 0 */ + LC3_CON_TEC_PHASE_ECU, /* 2 */ + LC3_CON_TEC_TDPLC, /* 3 */ + LC3_CON_TEC_NS_ADV, /* 4 */ + LC3_CON_TEC_FREQ_MUTING, /* 5 */ +} LC3_ConcealTechnique; + +void WarnMsg(char *msg); +void ExitMsg(char *msg); +void AssertMsg(int true_flag, char *msg); + +void processTnsDecoder_fx(Word16 rc_idx[], Word32 x[], Word16 xLen, Word16 order[], Word16 *x_e, Word16 BW_stopband_idx, + Word16 frame_dms, Word8 *scratchBuffer +#ifdef ENABLE_HR_MODE + , Word16 hrmode +#endif +); + +void processTnsCoder_fx(Word16 *bits, Word16 indexes[], Word32 x[], Word16 BW_cutoff_idx, Word16 order[], + Word16 *numfilters, Word16 enable_lpc_weighting, Word16 nSubdivisions, Word16 frame_dms, + Word16 max_len, Word8 *scratchBuffer +#ifdef ENABLE_HR_MODE + , Word16 hrmode +#endif + , Word16 near_nyquist_flag +); + +void TnsUpdate_fx(Word16 *tns_numfilters, Word16 *long_startfreq, const Word16 **subdiv_startfreq, + const Word16 **subdiv_stopfreq, Word16 frame_length, Word16 tab_idx); + +void processResidualDecoding_fx(Word32 spectrum[], Word16 spectrum_e, Word16 L_spec, UWord8 prm[], Word16 resQBits +#ifdef ENABLE_HR_MODE + , Word16 hrmode +#endif +); + +void processPreemph_fx(Word16 *x, Word16 len, Word16 mem[], Word16 memLen, Word16 out[], Word16 *outLen, Word16 mu); + +void processNoiseFilling_fx(Word32 xq[], Word16 nfseed, Word16 xq_e, Word16 fac_ns_idx, Word16 BW_cutoff_idx, + Word16 frame_dms, Word16 fac_ns_pc, Word16 spec_inv_idx, Word8 *scratchBuffer +#ifdef ENABLE_HR_MODE + , Word16 hrmode +#endif +); + +void processNoiseFactor_fx(Word16 *fac_ns_idx, Word16 x_e, Word32 x[], +#ifdef ENABLE_HR_MODE + Word32 xq[], +#else + Word16 xq[], +#endif + Word16 gg, Word16 gg_e, Word16 BW_cutoff_idx, Word16 frame_dms, Word16 target_bytes, + Word8 *scratchBuffer +#ifdef ENABLE_HR_MODE + , Word16 hrmode +#endif +); + +void processMdctShaping_fx(Word32 x[], +#ifdef ENABLE_HR_MODE + Word32 scf[], +#else + Word16 scf[], +#endif + Word16 scf_exp[], const Word16 bands_offset[], Word16 fdns_npts); + +void processScfScaling(Word16 scf_exp[], Word16 fdns_npts, Word16 *x_e); + +void processMdct_fx( +#ifdef ENABLE_HR_MODE + Word32 x[], +#else + Word16 x[], +#endif + Word16 x_exp, Word16 N, +#ifdef CR8_F_ADAPT_MDCT_DCT_PRECISION +# ifdef ENABLE_HR_MODE + Word16 hrmode, /* i: indicate high precision */ +# endif +#endif +#ifdef ENABLE_HR_MODE + const Word32 w[], /* i: window coefficients including normalization of sqrt(2/N) and scaled by 2^4 */ +#else + const Word16 w[], /* i: window coefficients including normalization of sqrt(2/N) and scaled by 2^4 */ +#endif + Word16 wLen, +#ifdef ENABLE_HR_MODE + Word32 mem[], /* i/o: last block of input samples */ +#else + Word16 mem[], /* i/o: last block of input samples */ +#endif + Word16 memLen, + Word32 y[], Word16 *y_e, Word8 *scratchBuffer); + +void processLevinson_fx(Word32 *lpc, Word32 *ac, Word16 N, Word16 *rc, Word32 *pred_err, Word8 *scratchBuffer); + +void lpc2rc(Word32 *lpc, Word16 *rc, Word16 N); + +void ProcessingIMDCT(Word32 y[], Word16 *y_e, +#ifdef ENABLE_HR_MODE + const Word32 w[], /* i: window coefficients including normalization of sqrt(2/N) and scaled by 2^4 */ + Word32 mem[], /* i/o: overlap add memory */ +#else + const Word16 w[], /* i: window coefficients including normalization of sqrt(2/N) and scaled by 2^4 */ + Word16 mem[], /* i/o: overlap add memory */ +#endif + Word16 *mem_e, +#ifdef ENABLE_HR_MODE + Word32 x[], /* o: time signal out */ +#else + Word16 x[], /* o: time signal out */ +#endif + Word16 wLen, + Word16 N, Word16 memLen, Word16 frame_dms, + Word16 concealMethod, Word16 bfi, Word16 prev_bfi, Word16 nbLostFramesInRow, AplcSetup *plcAd, + Word8 *scratchBuffer +#ifdef ENABLE_HR_MODE + , Word16 hrmode +#endif +); + +#ifdef ENABLE_HR_MODE +# ifdef CR8_F_ADAPT_MDCT_DCT_PRECISION +void dct_IV(Word32 *pDat, Word16 *pDat_e, Word16 L, Word16 hrmode, Word32 *workBuffer); +# else /* CR8_F_ADAPT_MDCT_DCT_PRECISION */ +void dct_IV(Word32 *pDat, Word16 *pDat_e, Word16 L, Word32 *workBuffer); +# endif /* CR8_F_ADAPT_MDCT_DCT_PRECISION */ +#else +void dct_IV(Word32 *pDat, Word16 *pDat_e, Word16 L, Word32 *workBuffer); +#endif + +#ifdef ENABLE_HR_MODE +Word16 find_last_nz_pair(const Word32 x[], Word16 length); +#else +Word16 find_last_nz_pair(const Word16 x[], Word16 length); +#endif + +PvqEntry_fx mpvq_index_fx(const Word16 *vec_in, Word16 dim_in, Word16 k_val_local); +void mpvq_deindex_fx(const PvqEntry_fx *entry, UWord32 *h_mem, Word16 *vec_out); + +void pvq_enc_search_fx(const Word16 *x, /* i: target vector to quantize Qin */ + Word16 * rt_far, /* o: outl_far o, raw pulses (non-scaled short) Q0 */ + Word16 * rt_near, /* o: outl_near o, raw pulses (non-scaled short) Q0 */ + Word16 * rtA, /* o: A section raw pulses (non-scaled short) Q0 */ + Word16 * rtB, /* o: B section raw pulses (non-scaled short) Q0 */ + Word32 *L_corr, /* o: 4 un-normalized correlation sums for outl_far, near, outl, A, AB */ + Word32 *L_search_en, /* o: 4 energy sums for out_far, outl_near, A, AB */ + Word16 *pulses_fin, /* i: number of allocated pulses to outl A, AB section */ + Word16 *pulses_proj, /* i: number of proj pulses pulses to outl, A , AB section */ + + const Word16 dim, /* i: Length of vector */ + const Word16 dimA /* i: Length of vector A section */ +); + +PvqEntry_fx get_size_mpvq_calc_offset_fx(Word16 dim_in, Word16 k_val_in, UWord32 *h_mem); + +Word16 pvq_dec_deidx_fx( /* out BER detected 1 , ok==0 */ + Word16 * y, /* o: decoded vector (non-scaled int) */ + const Word16 k_val, /* i: number of allocated pulses */ + const Word16 dim, /* i: Length of vector */ + const Word16 LS_ind, /* i; lS index 1 bit */ + const UWord32 UL_MPVQ_ind /* i; MPVQ index */ +); + +void pvq_dec_en1_norm_fx( /* */ +#ifdef ENABLE_HR_MODE + Word32 * xq, /* o: en1 normalized decoded vector (Q14) */ +#else + Word16 * xq, /* o: en1 normalized decoded vector (Q14) */ +#endif + const Word16 *y, /* i: decoded vector (non-scaled int) */ + const Word16 kval_max, /* i: max possible K in Q0 kO or kA */ + const Word16 dim, /* i: Length of vector */ + const Word16 neg_glob_gain /* i: a Global Gain (negated to fit 1.0 in Q15 as -1.0) */ +); + +#ifdef ENABLE_HR_MODE +#ifdef WIN32 +#define mexPrintf(x, y) printf(x, y) +#endif +#endif + +void pvq_dec_en1_normQ14_fx( /* Have to be used by both encoder and decoder */ +#ifdef ENABLE_HR_MODE + Word32 * xq, /* o: en1 normalized decoded vector (Q14) */ +#else + Word16 * xq, /* o: en1 normalized decoded vector (Q14) */ +#endif + const Word16 *y, /* i: decoded vector (non-scaled int) */ + const Word16 k_val_max, /* i: max possible K in Q0 kO or kA */ + const Word16 dim /* i: Length of vector */ +); + + +#ifdef ENABLE_HR_MODE +void pvq_dec_scale_vec_fx(const Word32 *inQ29, Word16 adjGainQ13, Word32 *outQ); +#else +void pvq_dec_scale_vec_fx(const Word16 *inQ14, Word16 adjGainQ13, Word16 *outQ14); +#endif + +Word16 processAriEncoder_fx(UWord8 *bytes, Word16 bp_side, Word16 mask_side, Word16 nbbits, +#ifdef ENABLE_HR_MODE + Word32 xq[], +#else + Word16 xq[], +#endif + Word16 *tns_order, Word16 tns_numfilters, Word16 *tns_idx, Word16 lastnz, + Word16 *codingdata, UWord8 *resBits, Word16 numResBits, Word16 lsbMode, + Word16 enable_lpc_weighting, Word8 *scratchBuffer); + +void processAriDecoder_fx(UWord8 *bytes, Word16 *bp_side, Word16 *mask_side, Word16 nbbits, Word16 L_spec, + Word16 fs_idx, Word16 enable_lpc_weighting, Word16 tns_numfilters, Word16 lsbMode, + Word16 lastnz, Word16 *bfi, Word16 *tns_order, Word16 fac_ns_idx, Word16 gg_idx, + Word16 frame_dms, + Word16 n_pc, Word16 be_bp_left, Word16 be_bp_right, Word16 mode, Word16 *spec_inv_idx, + Word16 *b_left, + Word16 *resBits, +#ifdef ENABLE_HR_MODE + Word32 *x, +#else + Word16 *x, +#endif + Word16 *nf_seed, UWord8 *resQdata, Word16 *tns_idx, Word16 *zero_frame, Word8 *scratchBuffer +#ifdef ENABLE_HR_MODE + , Word16 hrmode +#endif +); + +void processAriDecoderScaling_fx( +#ifdef ENABLE_HR_MODE + Word32 *datain, +#else + Word16 *data16, +#endif + Word16 dataLen, Word32 *data32, Word16 *data_e); + +void processApplyGlobalGain_fx(Word32 x[], Word16 *x_e, Word16 xLen, Word16 global_gain_idx, Word16 global_gain_off); + +void processPerBandEnergy_fx(Word32 *d2_fx, Word16 *d2_fx_exp, Word32 *d_fx, Word16 d_fx_exp, + const Word16 *band_offsets, Word16 fs_idx, Word16 n_bands, Word16 linear, Word16 frame_dms, + Word8 *scratchBuffer +#ifdef ENABLE_HR_MODE + , Word16 hrmode +#endif +); + +void processNearNyquistdetector_fx(Word16 *near_nyquist_flag, const Word16 fs_idx, const Word16 near_nyquist_index, + const Word16 bands_number, const Word32 *ener_fx, const Word16 ener_fx_exp +#ifdef CR8_E_TONE_DETECTOR +#ifdef ENABLE_HR_MODE + , Word16 frame_dms , Word16 hrmode); +#else + ); +#endif +#else + ); +#endif +void processDetectCutoffWarped_fx(Word16 *bw_idx, Word32 *d2_fx, Word16 d2_fx_exp, Word16 fs_idx, Word16 frame_dms); + +void process_resamp12k8_fx(Word16 x[], Word16 x_len, Word16 mem_in[], Word16 mem_in_len, Word32 mem_50[], + Word16 mem_out[], Word16 mem_out_len, Word16 y[], Word16 *y_len, Word16 fs_idx, + Word16 frame_dms, Word8 *scratchBuffer + , Word16 bps + ); + +void process_olpa_fx(Word16 *mem_s6k4_exp, Word16 mem_s12k8[], Word16 mem_s6k4[], Word16 *pitch, Word16 *s12k8, + Word16 len, Word16 *normcorr, Word16 *mem_pitch, +#ifdef CR9_F_PITCH_WIN_LEN_FIX + Word16 *pitch_flag, +#endif + Word16 s12k8_exp, Word16 frame_dms, Word8 *scratchBuffer); + +void process_ltpf_coder_fx(Word16 *bits, Word16 ol_pitch, Word16 ltpf_enable, Word16 *old_wsp_exp, Word16 *old_wsp, + Word16 old_wsplen, Word16 *param, Word16 *wsp, Word16 len, Word16 *mem_normcorr, + Word16 *mem_mem_normcorr, Word16 ol_normcorr, Word16 *mem_ltpf_on, Word16 *mem_ltpf_pitch, + Word16 wsp_exp, Word16 frame_dms, Word8 *scratchBuffer +#ifdef CR9_K_REDUCE_NORM_CORR_TH + ,Word16 hrmode +#endif +); + +void process_ltpf_decoder_fx(Word16 *x_e, Word16 L_frame, Word16 old_x_len, Word16 fs_idx, Word16 old_y_len, + Word16 *old_e, Word16 *x, Word16 *old_x, Word16 *y, Word16 *old_y, Word16 ltpf, + Word16 ltpf_active, Word16 pitch_index, Word16 *old_pitch_int, Word16 *old_pitch_fr, + Word16 *old_gain, Word16 *mem_ltpf_active, Word16 scale_fac_idx, Word16 bfi, + Word16 concealMethod, + Word16 damping, Word16 *old_scale_fac_idx, +#ifdef CR9_N_SHORT_FADE_FOR_UNSTABLE_PITCH + Word32 *rel_pitch_change, Word16 hrmode, Word16 frame_dms, +#endif + Word8 *scratchBuffer); + +void attack_detector_fx(LC3PLUS_Enc *enc, EncSetup *setup, Word16 *input, Word16 input_scaling, void *scratch); + +void processSnsComputeScf_fx(Word32 *d2_fx, Word16 d2_fx_exp, Word16 fs_idx, Word16 n_bands, Word16 *scf, + Word16 scf_smoothing_enabled, Word16 attdec_damping_factor, Word8 *scratchBuffer, Word16 sns_damping + ); + +void processSnsQuantizeScfEncoder_fx(Word16 scf[], /* i: input scf M */ + Word32 *L_prm_idx, /* o: indeces . negative == unused */ +#ifdef ENABLE_HR_MODE + Word32 *scf_q, /* o: quantized scf M */ +#else + Word16 *scf_q, /* o: quantized scf M */ +#endif + Word8 * scratchBuffer); + +Word16 processSnsQuantizeScfDecoder_fx( /* o: BER flag */ + Word32 *L_prm_idx, /* i: indeces */ +#ifdef ENABLE_HR_MODE + Word32 scf_q[], +#else + Word16 scf_q[], +#endif + Word8 *scratchBuffer); /* o: M */ + +void processSnsInterpolateScf_fx( +#ifdef ENABLE_HR_MODE + Word32 *scf_q, Word32 mdct_scf[], +#else + Word16 *scf_q, Word16 mdct_scf[], +#endif + Word16 mdct_scf_exp[], Word16 inv_scf, + Word16 n_bands, Word8 *scratchBuffer); + +void downshift_w32_arr(Word32 *w32_arr, Word16 *w16_arr, Word16 shft_val, Word32 len); +void round_w32tow16_arr(Word32 *w32_arr, Word16 *w16_arr, Word32 len); + +void processPLCmain_fx(Word16 plcMeth, Word16 *concealMethod, Word16 *nbLostFramesInRow, Word16 bfi, Word16 prev_bfi, + Word16 frame_length, Word16 la_zeroes, +#ifdef ENABLE_HR_MODE + const Word32 w[], +#else + const Word16 w[], +#endif + Word16 x_fx[], Word16 ola_mem[], + Word16 *ola_mem_exp, Word16 q_old_d_fx[], Word16 *q_old_fx_exp, Word32 q_d_fx[], + Word16 *q_fx_exp, Word16 yLen, Word16 fs_idx, const Word16 *band_offsets, Word16 bands_number, Word16 *damping, + Word16 old_pitch_int, Word16 old_pitch_fr, Word16 *ns_cum_alpha, Word16 *ns_seed, + AplcSetup *plcAd, Word16 frame_dms, Word8 *scratchBuffer, Word16 *pc_nbLostFramesInRow +#ifdef ENABLE_HR_MODE + , Word16 hrmode +#endif +#ifdef CR9_N_SHORT_FADE_FOR_UNSTABLE_PITCH + , Word32 rel_pitch_change +#endif +#ifdef CR10_A_ATTENUATION_CURVE_SELECTOR + , Word16 *alpha_type_2_table +#endif + ); + +void processPLCupdate_fx(AplcSetup *plcAd, Word16 x_fx[], Word16 q_fx_exp, Word16 concealMethod, Word16 frame_length, + Word16 fs_idx, Word16 *nbLostFramesInRow, Word16 *prev_prev_bfi, Word16 *prev_bfi, Word16 bfi, + Word16 scf_q[], Word16 *ns_cum_alpha +#ifdef ENABLE_HR_MODE + , Word16 hrmode +#endif + ); + +void processPLCupdateSpec_fx(Word16 q_old_d_fx[], Word16 *q_old_fx_exp, Word32 q_d_fx[], Word16 *q_fx_exp, Word16 yLen); + + +void processPLCspec2shape_fx(Word16 prev_bfi, Word16 bfi, Word16 q_old_d_fx[], Word16 yLen, + Word16 *PhECU_oold_grp_shape_fx, Word16 *PhECU_old_grp_shape_fx); + +Word32 winEnCalc(const Word16 *, const Word16, const Word16 *, const Word16, const Word16, Word16 *); + +void processPLCUpdateAfterIMDCT_fx(Word16 x_fx[], Word16 q_fx_exp, Word16 concealMethod, Word16 xLen, Word16 fs_idx, + Word16 *nbLostFramesInRow, Word16 *prev_prev_bfi, Word16 *prev_bfi, Word16 bfi, + Word16 scf_q[], Word16 *ns_cum_alpha, AplcSetup *plcAd); + +void processPLCclassify_fx(Word16 plcMeth, Word16 *concealMethod, Word16 *nbLostFramesInRow, Word16 bfi, + Word16 ltpf_mem_pitch_int, Word16 frame_length, Word16 frame_dms, Word16 fs_idx, Word16 yLen, + Word16 q_old_d_fx[], const Word16 *band_offsets, Word16 bands_number, AplcSetup *plcAd, Word8 *scratchBuffer +# ifdef ENABLE_HR_MODE + , Word16 hrmode +# endif + ); + +void processPLCapply_fx( +#ifdef CR8_A_PLC_FADEOUT_TUNING + Word16 *concealMethod, +#else + Word16 concealMethod, +#endif + Word16 nbLostFramesInRow, Word16 bfi, Word16 prev_bfi, + Word16 frame_length, Word16 la_zeroes, +#ifdef ENABLE_HR_MODE + const Word32 w[], +#else + const Word16 w[], +#endif + Word16 x_fx[], Word16 ola_mem[], + Word16 *ola_mem_exp, Word16 q_old_d_fx[], Word16 *q_old_fx_exp, Word32 q_d_fx[], + Word16 *q_fx_exp, Word16 yLen, Word16 fs_idx, Word16 *damping, Word16 old_pitch_int, + Word16 old_pitch_fr, Word16 *ns_cum_alpha, Word16 *ns_seed, Word16 frame_dms, AplcSetup *plcAd, + Word8 *scratchBuffer +#ifdef ENABLE_HR_MODE + , Word16 hrmode +#endif +#ifdef CR9_N_SHORT_FADE_FOR_UNSTABLE_PITCH + , Word32 rel_pitch_change + +#endif +#ifdef CR10_A_ATTENUATION_CURVE_SELECTOR + , Word16 *alpha_type_2_table +#endif + ); + +void processPLCNoiseSubstitution_fx(Word32 spec[], Word16 spec_prev[], Word16 L_spec); +void processPLCDampingScrambling_main_fx(Word16 bfi, Word16 concealMethod, Word16 ns_nbLostFramesInRow, Word16 *cum_fflcAtten, + Word16 pc_nbLostFramesInRow, Word16 *ns_seed, Word16 *pc_seed, Word16 pitch_present_bfi1, + Word16 pitch_present_bfi2, Word32 spec[], Word16 *q_fx_exp, Word16 *q_old_d_fx, + Word16 *q_old_fx_exp, Word16 L_spec, Word16 stabFac, Word16 frame_dms, + Word16 *cum_fading_slow, Word16 *cum_fading_fast, Word16 spec_inv_idx +#ifdef CR8_A_PLC_FADEOUT_TUNING + , UWord8 plc_fadeout_type +#endif + ); + +void processPLCDampingScrambling_fx(Word32 spec[], Word16 L_spec, Word16 nbLostFramesInRow, Word16 stabFac, Word16 processDampScramb, + Word16 *cum_fflcAtten, Word16 pitch_present, Word16 frame_dms, Word16 *cum_fading_slow, + Word16 *cum_fading_fast, Word16 *seed, Word16 spec_inv_idx +#ifdef CR8_A_PLC_FADEOUT_TUNING + , UWord8 plc_fadeout_type +#endif + ); + +void processLagwin_fx(Word32 r[], const Word32 w[], Word16 m); + +void processInverseODFT_fx(Word32 *r_fx, Word16 *r_fx_exp, Word32 *d2_fx, Word16 d2_fx_exp, Word16 n_bands, + Word16 lpc_order, Word8 *scratchBuffer); + +void processPreEmphasis_fx(Word32 *d2_fx, Word16 *d2_fx_exp, Word16 fs_idx, Word16 n_bands, Word16 frame_dms, + Word8 *scratchBuffer); + +void processPLCLpcScaling_fx(Word32 tdc_A_32[], Word16 tdc_A_16[], Word16 m); + +void processPLCcomputeStabFac_main(Word16 scf_q[], Word16 old_scf_q[], Word16 old_old_scf_q[], Word16 bfi, + Word16 prev_bfi, Word16 prev_prev_bfi, Word16 *stab_fac); + +void processPLCUpdateXFP_w_E_hist_fx(Word16 prev_bfi, Word16 bfi, + Word16 *xfp_fx, Word16 xfp_exp_fx,Word16 margin_xfp, + Word16 fs_idx, + Word32 *L_oold_xfp_w_E_fx, Word16 *oold_xfp_w_E_exp_fx, + Word32 *L_old_xfp_w_E_fx, Word16 *old_xfp_w_E_exp_fx, + Word16 *oold_Ltot_exp_fx, Word16 *old_Ltot_exp_fx); + +void processTimeDomainConcealment_Apply_fx(const Word16 pitch_int, const Word16 preemphFac_fx, const Word16 *A_fx, + const Word16 lpc_order, const Word16 *pcmbufHist_fx, + const Word16 frame_length, const Word16 frame_dms, const Word16 fs_idx, + const Word16 nbLostFramesInRow, const Word16 overlap, + const Word16 stabFac_fx, Word16 *fract, Word16 *seed_fx, + Word32 *gain_c_fx, Word16 *synth_fx, Word16 *Q_syn, + Word16 *alpha, Word16 max_len_pcm_plc, + Word16 harmonicBuf_fx[MAX_PITCH], Word16 synthHist_fx[M], Word16 *const harmonicBuf_Q, + Word8 *scratchBuffer +#ifdef CR9_I_INC_TDC_FADEOUT_LEN + ,UWord8 plc_fadeout_type +#endif +#ifdef CR10_A_ATTENUATION_CURVE_SELECTOR + ,Word16 *alpha_type_2_table +#endif +); + +void processTdac_fx(Word16 *ola_mem, Word16 *ola_mem_exp, const Word16 *synth, const Word16 synth_exp, +#ifdef ENABLE_HR_MODE + const Word32 *win, +#else + const Word16 *win, +#endif + const Word16 la_zeroes, const Word16 frame_len, Word8 *scratchBuffer); + +void plc_phEcu_F0_refine_first_fx(Word16 *plocs, const Word16 n_plocs_in, Word32 *L_f0est, + const Word16 stPhECU_f0hzLtpBinQ7, const Word16 stPhECU_f0gainLtpQ15, + const Word16 nSubm); +void plc_phEcu_LF_peak_analysis_fx(Word16 *plocs, Word16 *n_plocs, Word32 *L_f0estQ16, const Word16 *mag, + const Word16 stPhECU_f0hzLtpBinQ7, const Word16 stPhECU_f0gainLtpQ15, + const Word16 nSubm, Word16 maxPlocs, Word8 *scratchBuffer); + +Word16 plc_phEcuSetF0Hz_fx(Word16 fs_idx, Word16 old_pitch_int, Word16 old_pitch_fr); + +void create_sin2_taper_fx(Word16 *, Word16, Word16); + +void plc_phEcu_initWord16(Word16 * vec, /*i/o : vector pointer */ + const Word16 value, /*i : short initialization value */ + const Word16 len); /*i : number of elements */ + +Word16 plc_phEcu_ratio_fx(const Word32, const Word32, Word16 *); + +void plc_phEcu_minval_fx(const Word16 *inp, /* i : vector */ + const Word16 len, /* i : length */ + Word16 * minvalPtr); /* o : min value Ptr */ + +void plc_phEcu_maxval_fx(const Word16 *inp, /* i : vector */ + const Word16 len, /* i : length */ + Word16 * maxvalPtr); /* o : *maxvalPtr */ + +void Scale_sig_sat(Word16 x[], /* i/o: signal to scale, possibly saturated Qx */ + const Word16 lg, /* i : size of x[] Q0 */ + const Word16 exp0); /* i : exponent: x = round(x << exp) Qx ?exp */ + +void Processing_ITDA_WIN_OLA(Word32 L_x_tda[], Word16 *y_e, +#ifdef ENABLE_HR_MODE + const Word32 w[], +#else + const Word16 w[], +#endif + Word16 mem[], Word16 *mem_e, Word16 x[], + Word16 wLen, Word16 N, Word16 memLen); + +void trans_burst_ana_fx(const Word16 *xfp, /* i : Input signal Qspec */ + Word16 * mag_chg, /* o : Magnitude modification Q15 */ + Word16 *ph_dith, /* o : Phase dither, 2*PI is not included (Q15, i.e., between 0.0 and 1.0) */ + Word16 *mag_chg_1st, /* i/o: per band magnitude modifier for transients Q15 */ + const Word16 output_frame, /* i : Frame length */ + const Word16 time_offs, /* i : Time offset (integral multiple of output_frame) */ + const Word16 est_stab_content, /* i : 0.0=dynamic ... 1.0=stable (==st->env_stab ) */ + Word16 * alpha, /* o : Magnitude modification factors for fade to average */ + Word16 * beta, /* : Magnitude modification factors for fade to average */ + Word16 * beta_mute, /* i/o : Factor for long-term mute */ + Word16 * Xavg, /* o : Frequency group average gain to fade to */ + Word16 Q_spec, Word32 L_oold_xfp_w_E_fx, Word16 oold_xfp_w_E_exp_fx, Word16 oold_Ltot_exp_fx, + Word16 *oold_grp_shape_fx, Word32 L_old_xfp_w_E_fx, Word16 old_xfp_w_E_exp_fx, + Word16 old_Ltot_exp_fx, Word16 *old_grp_shape_fx, +#ifdef CR8_A_PLC_FADEOUT_TUNING + Word16 fadeout, + Word32 *L_Xavg, /* full scale average band amplitudes */ +#endif + Word8 *scratchBuffer); + +void spec_ana_fx(Word16 *xfp, Word16 *, Word32 *, Word16 *, Word16 *, const Word16, const Word16, + const Word16 *, const Word16, const Word16, Word16 maxLprot, Word16 maxPlocs, Word8 *scratchBuffer); + +void subst_spec_fx(const Word16 *, const Word32 *, Word16 *, const Word16, Word16 *, const Word16 *, const Word16, + const Word16 *, const Word16, Word16 *, const Word16 *, const Word16 *, const Word16 *, const Word16 +#ifdef CR8_A_PLC_FADEOUT_TUNING + ,const Word16, + Word16*, + const Word32 * +#endif +); + +void rec_frame_fx(Word16 * X, /* i : FFT spectrum */ + Word32 * L_ecu_rec, /* o : Reconstructed frame in tda domain */ + const Word16 output_frame, /* i : Frame length */ + const Word16 Q, const Word16 *const win2ms_init, /* i: 2 ms initial part of pre_tda window */ + const Word16 *const win16ms_center, /* i: 16 ms combined part of pre_tda IWHR+MDCT-ana */ + + Word16 maxLprot, const Word16 *prevsynth, const Word16 Q_prevsynth, + Word8 * scratchBuffer); + +Word16 rand_phase_fx(const Word16 seed, Word16 *sin_F, Word16 *cos_F); + +void hq_phase_ecu_fx(const Word16 *prevsynth, /* i : buffer of previously synthesized signal */ + Word32 *L_ecu_rec, /* o : reconstructed frame in tda domain , also tmp w32_fft buffer */ + Word16 *time_offs, /* i/o: Sample offset for consecutive frame losses*/ + Word16 *X_sav, /* i/o: Stored spectrum of prototype frame */ + Word16 *Q_spec, /* o: Q value of stored spectrum */ + Word16 *num_p, /* i/o: Number of identified peaks */ + Word16 *plocs, /* i/o: Peak locations */ + Word32 *L_plocsi, /* i/o: Interpolated peak locations Q16 */ + const Word16 env_stab, /* i : Envelope stability parameter */ + const Word16 f0hzLtpBinQ7, /* i: LTP bin frequency in normalized Hz Q7 */ + const Word16 norm_corrQ15_fx, /*i : correlation for lag at f0hzLtpBinQ7 */ + const Word16 prev_bfi, /* i : indicating burst frame error */ + Word16 old_is_transient[2], /* i/o : flags indicating noise generation */ + Word16 * mag_chg_1st, /* i/o: per band magnitude modifier for transients */ + Word16 * mag_chg_gr, /* o: per band magnitude modifier incl burst attenuation */ + Word16 * Xavg, /* i/o: Frequency group average gain to fade to */ + Word16 * beta_mute, /* o : Factor for long-term mute */ + const Word16 bwidth_fx, /* i : Encoded bandwidth */ + const Word16 output_frame, /* i : frame length */ + Word16 * seed_out_fxPtr, /* o: seed synch analysis */ + Word16 * X_out, /* o: utput evolved spectrum */ + const Word16 t_adv, /* i : time adjustment including time_offs */ + const Word16 *const win2ms_init, /* i: 2 ms initial part of pre_tda window */ + const Word16 *const win16ms_center, /* i: 16 ms combined part of pre_tda IWHR+MDCT-ana */ + const Word16 * sp_ana_win, /* i : whr hamming window */ + Word16 q_fx_old_exp, Word16 maxLprot, Word16 maxPlocs, + Word32 L_oold_xfp_w_E_fx, Word16 oold_xfp_w_E_exp_fx, /* exp of time signal */ + Word16 oold_Ltot_exp_fx, /*true exp of energy */ + Word16 *oold_grp_shape_fx, Word32 L_old_xfp_w_E_fx, + Word16 old_xfp_w_E_exp_fx, /* exp of time signal */ + Word16 old_Ltot_exp_fx, /*true exp of energy */ + Word16 *old_grp_shape_fx, + Word16 margin_prev_synth, /* i: margin in prev_synth(16ms for first bfi , 3.75 ms for other bfi + frames ) , from plcAd.PhECU_margin_xfp */ +#ifdef CR8_A_PLC_FADEOUT_TUNING + const Word16 fadeout, /*i: fadeout length indicator */ + Word16 *nonpure_tone_flag_ptr, /* i/o : non-pure single tone indicator state */ +#endif + Word8 *scratchBuffer /* Size = 2 * MAX_LGW + 8 * MAX_LPROT + 12 * MAX_L_FRAME */ +); + +Word16 +plc_xcorr_lc_fx(/* o: quantized output xcorr in Q15 [ 0 ..32767 ] = [0. 1.0[ */ + Word16 * + pcmbuf_fx, /* NB should be an already dynamically upscaled buffer with about 0...1 bits margin */ + Word16 max_len_pcm_plc, /* Q0 size of pcmbuf_fx */ + Word16 pitch_int, /* Q0 in Fs, lag value to evaluate, corresponding to the current f0 fr pcm_buf */ + Word16 fs_idx); + +void plc_phEcu_peak_locator_fx(const Word16 *, const Word16, Word16 *, Word16 *, const Word16, const Word16, + const Word16, Word16, Word8 *); + +Word16 plc_phEcu_find_ind_fx(const Word16 *, const Word16, const Word16); + + +Word16 initQV(Word16 SR_idx, Word32 BR); + +void processEstimateGlobalGain_fx(Word32 x[], Word16 x_e, Word16 lg, Word16 sqTargetBits, +#ifdef ENABLE_HR_MODE + Word32 *gain, +#else + Word16 *gain, +#endif + Word16 *gain_e, + Word16 *quantizedGain, Word16 *quantizedGainMin, Word16 quantizedGainOff, + Word32 *targetBitsOff, Word16 *old_targetBits, Word16 old_specBits, + Word8 *scratchBuffer +#ifdef ENABLE_HR_MODE + , Word16 hrmode, Word16 regBits, Word16 frame_dms +#endif +); + +void processAdjustGlobalGain_fx(Word16 *gg_idx, Word16 gg_idx_min, Word16 gg_idx_off, +#ifdef ENABLE_HR_MODE + Word32 *gain, +#else + Word16 *gain, +#endif + Word16 *gain_e, + Word16 target, Word16 nBits, Word16 *gainChange, Word16 fs_idx +#ifdef ENABLE_HR_MODE + , Word16 hrmode, Word16 frame_dms +#endif + ); + +void processScalarQuant_fx(Word32 x[], Word16 x_e, Word16 xq[], Word16 L_frame, Word16 gain, Word16 gain_e); + +#ifdef ENABLE_HR_MODE +void processQuantizeSpec_fx(Word32 x[], Word16 x_e, Word32 gain, Word16 gain_e, Word32 xq[], Word16 nt, Word16 target, + Word16 totalBits, Word16 *nBits, Word16 *nBits2, Word16 fs_idx, Word16 *lastnz, + Word16 *codingdata, Word16 *lsbMode, Word16 mode, Word16 hrmode); +#else +void processQuantizeSpec_fx(Word32 x[], Word16 x_e, Word16 gain, Word16 gain_e, Word16 xq[], Word16 nt, + Word16 target, + Word16 totalBits, Word16 *nBits, Word16 *nBits2, Word16 fs_idx, Word16 *lastnz, + Word16 *codingdata, Word16 *lsbMode, Word16 mode); + +#endif /* ENABLE_HR_MODE */ + +void processResidualCoding_fx(Word16 x_e, Word32 x[], +#ifdef ENABLE_HR_MODE + Word32 xq[], Word32 gain, +#else + Word16 xq[], Word16 gain, +#endif + Word16 gain_e, Word16 L_spec, Word16 targetBits, Word16 nBits, + UWord8 *resBits, Word16 *numResBits +#ifdef ENABLE_HR_MODE + , Word16 hrmode +#endif +); + +void scale_signal24_fx(Word32 x[], /* i: time input signal */ +#ifdef ENABLE_HR_MODE + Word32 x_scaled[], +#else + Word16 x_scaled[], +#endif + Word16 *x_exp, +#ifdef ENABLE_HR_MODE + Word32 mdct_mem[], +#else + Word16 mdct_mem[], +#endif + Word16 mdct_mem_len, + Word16 resample_mem_in[], Word16 resample_mem_in_len, Word32 resample_mem_in50[], + Word16 resample_mem_out[], Word16 resample_mem_out_len, Word32 mdct_mem32[], Word16 N, + Word32 resamp_mem32[], Word16 mem_s12k8[], Word16 *resamp_scale); + +void processReorderBitstream_fx(UWord8 *bytes, Word16 n_pccw, Word16 n_pc, Word16 b_left, Word8 *scratchBuffer); + +/* al_fec.c */ +Word16 fec_get_n_pccw(Word16 slot_bytes, Word16 fec_mode, Word16 ccc_flag); +Word16 fec_get_data_size(Word16 fec_mode, Word16 ccc_flag, Word16 slot_bytes); +Word16 fec_get_n_pc(Word16 fec_mode, Word16 n_pccw, Word16 slot_bytes); + +void fec_encoder(Word16 mode, Word16 epmr, UWord8 *iobuf, Word16 data_bytes, Word16 slot_bytes, Word16 n_pccw, + void *scratch); + +int fec_decoder(UWord8 *iobuf, Word16 slot_bytes, int *data_bytes, Word16 *epmr, Word16 ccc_flag, Word16 *n_pccw, + int *bfi, Word16 *be_bp_left, Word16 *be_bp_right, Word16 *n_pc, Word16 *m_fec, void *scratch); + +void processPCmain_fx(Word16 rframe, Word16 *bfi, Word16 yLen, Word16 frame_dms, Word16 q_old_res_fx[], + Word16 *q_old_res_fx_exp, +#ifdef ENABLE_HR_MODE + Word32 q_res_fx[], +#else + Word16 q_res_fx[], +#endif + Word16 q_old_d_fx[], Word16 spec_inv_idx, + Word16 pitch_present, Word16 stab_fac, Word32 q_d_fx[], Word16 *q_fx_exp, + Word16 gg_idx, Word16 gg_idx_off, Word16 *prev_gg, Word16 *prev_gg_e, Word16 *BW_cutoff_idx_nf, + Word16 *prev_BW_cutoff_idx_nf, Word16 fac_ns_idx, Word16 *prev_fac_ns_fx, Word16 *pc_nbLostFramesInRow); +void processPCclassify_fx(Word16 pitch_present, Word16 frame_dms, Word16 q_old_d_fx[], Word16 q_old_res_fx[], + Word16 yLen, Word16 spec_inv_idx, Word16 stab_fac, Word16 *bfi); +void processPCapply_fx(Word16 yLen, Word16 q_old_res_fx[], Word16 *q_old_res_fx_exp, +#ifdef ENABLE_HR_MODE + Word32 q_res_fx[], +#else + Word16 q_res_fx[], +#endif + Word16 q_old_d_fx[], Word16 spec_inv_idx, Word16 *fac, Word16 *fac_e, Word32 q_d_fx[], + Word16 *q_fx_exp, Word16 gg_idx, Word16 gg_idx_off, Word16 prev_gg, Word16 prev_gg_e, + Word16 *pc_nbLostFramesInRow); +void processPCupdate_fx(Word16 bfi, Word16 yLen, Word16 q_old_res_fx[], Word16 *q_old_res_fx_exp, +#ifdef ENABLE_HR_MODE + Word32 q_res_fx[], +#else + Word16 q_res_fx[], +#endif + Word16 spec_inv_idx, Word16 gg_idx, Word16 gg_idx_off, Word16 *prev_gg, Word16 *prev_gg_e, + Word16 rframe, Word16 *BW_cutoff_idx_nf, Word16 *prev_BW_cutoff_idx_nf, Word16 fac_ns_idx, + Word16 *prev_fac_ns_fx, Word16 fac, Word16 fac_e); +void processPcApplyDamping_fx(Word32 x[], Word16 xLen, Word16 fac, Word16 spec_inv_idx); + +void process_cutoff_bandwidth(Word32 d_fx[], Word16 len, Word16 bw_bin); + +void idct16_fx(const Word16 *in, Word16 *out); + +void dct32_fx(const Word32 *in, Word32 *out); +void idct32_fx(const Word32 *in, Word32 *out); +void idct32_32_fx(const Word32 *in, Word32 *out); + +/* Functions used in arithmetic coder */ + +void write_bit_backward(UWord8 *ptr, Word16 *bp, Word16 *mask, Word16 bit); +void write_indice_backward(UWord8 *ptr, Word16 *bp, Word16 *mask, Word16 indice, Word16 numbits); + +void processEncoderEntropy(UWord8 *bytes, Word16 *bp_side, Word16 *mask_side, Word16 nbbits, Word16 targetBytes, + Word16 L_spec, Word16 BW_cutoff_bits, Word16 tns_numfilters, Word16 lsbMode, Word16 lastnz, + Word16 *tns_order, Word16 fac_ns_idx, Word16 gg_idx, Word16 BW_cutoff_idx, Word16 *ltpf_idx, + Word32 *L_scf_idx, Word16 bfi_ext, Word16 fs_idx); + +void processDecoderEntropy_fx(UWord8 *bytes, Word16 *bp_side, Word16 *mask_side, Word16 nbbits, Word16 L_spec, + Word16 fs_idx, Word16 BW_cutoff_bits, Word16 *tns_numfilters, Word16 *lsbMode, + Word16 *lastnz, Word16 *bfi, Word16 *tns_order, Word16 *fac_ns_idx, Word16 *gg_idx, + Word16 *BW_cutoff_idx, Word16 *ltpf_idx, Word32 *L_scf_idx, Word16 frame_dms); + +#ifdef ENABLE_PADDING +int paddingDec_fx(UWord8 *bytes, Word16 nbbits, Word16 L_spec, Word16 BW_cutoff_bits, Word16 ep_enabled, + Word16 *total_padding, Word16 *np_zero); +#endif + +Word16 read_bit(UWord8 *ptr, Word16 *bp, Word16 *mask); + +/* setup_enc_lc3.c */ +int alloc_encoder(LC3PLUS_Enc *encoder, int samplerate, int channels); +void set_enc_frame_params(LC3PLUS_Enc *encoder); +LC3PLUS_Error update_enc_bitrate(LC3PLUS_Enc *encoder, int bitrate); +LC3PLUS_Error FillEncSetup(LC3PLUS_Enc *encoder, int samplerate, int channels +#ifdef ENABLE_HR_MODE + , int hrmode +#endif + , int32_t lfe_channel_array[] + ); + +/* setup_dec_lc3.c */ +int alloc_decoder(LC3PLUS_Dec *decoder, int samplerate, int channels); +void set_dec_frame_params(LC3PLUS_Dec *decoder); +LC3PLUS_Error update_dec_bitrate(LC3PLUS_Dec *decoder, int ch, Word16 nBytes); +LC3PLUS_Error FillDecSetup(LC3PLUS_Dec *decoder, int samplerate, int channels, LC3PLUS_PlcMode plc_mode +#ifdef ENABLE_HR_MODE + , int hrmode +#endif + ); + +int Enc_LC3PLUS(LC3PLUS_Enc *encoder, void **input, int bits_per_sample, UWord8 *output, void *scratch, Word16 bfi_ext); +LC3PLUS_Error Dec_LC3PLUS(LC3PLUS_Dec *decoder, UWord8 *input, int input_bytes, void **output, int bits_per_sample, void *scratch, + int bfi_ext); + +void *balloc(void *base, size_t *base_size, size_t size); + +#ifdef CR10_A_ATTENUATION_CURVE_SELECTOR +Word16 type_2_fadeout_fx(Word16 nbLostFramesInRow, Word16 frame_dms); +#endif + + +#endif diff --git a/lib_lc3plus/imdct_fx.c b/lib_lc3plus/imdct_fx.c new file mode 100644 index 0000000000000000000000000000000000000000..50ad2b257c6f2b9a9b3b4272c3c4e1929490b27b --- /dev/null +++ b/lib_lc3plus/imdct_fx.c @@ -0,0 +1,387 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.5 * +* 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 "functions.h" + +void ProcessingIMDCT( + Word32 y[], /* i: spectra data */ + Word16 * y_e, /* i: spectral data exponent */ +#ifdef ENABLE_HR_MODE + const Word32 w[], /* i: window coefficients including normalization of sqrt(2/N) and scaled by 2^4 */ + Word32 mem[], /* i/o: overlap add memory */ +#else + const Word16 w[], /* i: window coefficients including normalization of sqrt(2/N) and scaled by 2^4 */ + Word16 mem[], /* i/o: overlap add memory */ +#endif + Word16 * mem_e, /* i/o: overlap add exponent */ +#ifdef ENABLE_HR_MODE + Word32 x[], /* o: time signal out */ +#else + Word16 x[], /* o: time signal out */ +#endif + Word16 wLen, /* i: window length */ + Word16 N, /* i: block size */ + Word16 memLen, /* i: overlap add buffer size */ + Word16 frame_dms, /* i: frame size in ms */ + Word16 concealMethod, /* i: concealment method */ + Word16 bfi, /* i: bad frame indicator */ + Word16 prev_bfi, /* i: previous bad frame indicator */ + Word16 nbLostFramesInRow, /* i: number of consecutive lost frames */ + AplcSetup *plcAd, /* i: advanced plc struct */ + Word8 *scratchBuffer +#ifdef ENABLE_HR_MODE + , Word16 hrmode +#endif +) +{ + Counter i; + Word16 o, z, m, s; + Word16 y_s, mem_s, max_bw; + Word32 L_tmp; + Word32 *workBuffer; + +#ifdef DYNMEM_COUNT + struct _dynmem + { + Word16 o, z, m, s; + Word16 y_s, mem_s, max_bw; + Word32 L_tmp; + Counter i; + Word32 *workBuffer; + Word16 mem_i_win; + Word16 w_taper_win; + }; + Dyn_Mem_In("ProcessingIMDCT", sizeof(struct _dynmem)); +#endif + + + test(); test(); test(); + IF (sub(bfi, 1) != 0 || sub(concealMethod, LC3_CON_TEC_NS_STD) == 0 || sub(concealMethod, LC3_CON_TEC_NS_ADV) == 0 || sub(concealMethod, LC3_CON_TEC_FREQ_MUTING) == 0) + { + workBuffer = (Word32 *)scratchAlign(scratchBuffer, 0); /* Size = 4 * MAX_LEN bytes */ + + /* Init (constant per sample rate) */ + z = 2 * N - wLen; /* number of leading zeros in window */ + m = N >> 1; /* half block size */ + o = m - z; + max_bw = 0; + +#ifdef ENABLE_HR_MODE + if (hrmode) + { + max_bw = N; + } + else +#endif + { + SWITCH (frame_dms) + { + case 25: + max_bw = MAX_BW >> 2; move16(); + BREAK; + case 50: + max_bw = MAX_BW >> 1; move16(); + BREAK; +#ifdef CR8_G_ADD_75MS + case 75: + max_bw = (MAX_BW >> 2) * 3; move16(); + BREAK; +#endif + case 100: + max_bw = MAX_BW; move16(); + BREAK; + } + } + + if (N > max_bw) + basop_memset(&y[max_bw], 0, (N - max_bw) * sizeof(*y)); + + /* Start Processing */ + y_s = getScaleFactor32_0(y, N); + IF (sub(y_s, 32) < 0) + { + FOR (i = 0; i < N; i++) + { + y[i] = L_shl(y[i], y_s); + } + *y_e = sub(*y_e, y_s); +#ifdef ENABLE_HR_MODE + dct_IV(y, y_e, N, +# ifdef CR8_F_ADAPT_MDCT_DCT_PRECISION + hrmode, +# endif + workBuffer); +#else + dct_IV(y, y_e, N, workBuffer); +#endif + y_s = getScaleFactor32_lc3plus(y, N); + y_s = sub(y_s, 1); + *y_e = sub(*y_e, y_s + 3); /* mdct window is scaled by pow(2,x) */ + /* N<=20 only happens for 2.5ms frames in NB */ + if (sub(N, 20) <= 0) + { + *y_e = add(*y_e, 2); + } + else if (sub(N, 120) <= 0) + { + *y_e = add(*y_e, 1); + } + } + ELSE + { + *y_e = 0; move16(); + } + +#ifdef ENABLE_HR_MODE + mem_s = getScaleFactor32_0(mem, memLen); +#else + mem_s = getScaleFactor16_0(mem, memLen); +#endif + +#ifdef ENABLE_HR_MODE + IF (sub(mem_s, 32) < 0) +#else + IF (sub(mem_s, 16) < 0) +#endif + { + mem_s = sub(mem_s, 1); + *mem_e = sub(*mem_e, mem_s); + } + ELSE + { + *mem_e = *y_e; move16(); + } + + s = sub(*mem_e, *y_e); + + IF (s > 0) + { + y_s = sub(y_s, s); + *y_e = add(*y_e, s); + } + ELSE + { + mem_s = add(mem_s, s); + *mem_e = sub(*mem_e, s); + } + + mem_s = s_max(mem_s, -31); + y_s = s_max(y_s, -31); + + if (sub(y_s, 32) >= 0) + { + y_s = 0; move16(); + } +#ifdef ENABLE_HR_MODE + if (sub(mem_s, 32) >= 0) + { + mem_s = 0; move16(); + } +#else + if (sub(mem_s, 16) >= 0) + { + mem_s = 0; move16(); + } +#endif + + UNUSED(prev_bfi); + UNUSED(nbLostFramesInRow); + UNUSED(plcAd); + + { /* regular operation */ + FOR (i = 0; i < o; i++) + { +#ifdef ENABLE_HR_MODE + L_tmp = L_sub(L_shl(mem[i], mem_s), Mpy_32_32_lc3plus(L_shl(y[m + i + z], y_s), w[4 * m - 1 - i - z])); + x[i] = L_tmp; + move32(); +#else + L_tmp = L_sub(L_shl(L_deposit_h(mem[i]), mem_s), Mpy_32_16_lc3plus(L_shl(y[m + i + z], y_s), w[4 * m - 1 - i - z])); + x[i] = round_fx(L_tmp); + move16(); +#endif + } + FOR (i = 0; i < m; i++) + { +#ifdef ENABLE_HR_MODE + L_tmp = L_add(L_shl(mem[i + o], mem_s), Mpy_32_32_lc3plus(L_shl(y[2 * m - 1 - i], y_s), w[3 * m - 1 - i])); + x[i + o] = L_tmp; + move32(); +#else + L_tmp = L_add(L_shl(L_deposit_h(mem[i + o]), mem_s), Mpy_32_16_lc3plus(L_shl(y[2 * m - 1 - i], y_s), w[3 * m - 1 - i])); + x[i + o] = round_fx(L_tmp); + move16(); +#endif + } + } + + FOR (i = 0; i < m; i++) + { +#ifdef ENABLE_HR_MODE + L_tmp = L_negate(Mpy_32_32_lc3plus(L_shl(y[i], y_s), w[m - 1 - i])); + x[3 * m - z + i] = L_tmp; + move32(); +#else + L_tmp = L_negate(Mpy_32_16_lc3plus(L_shl(y[i], y_s), w[m - 1 - i])); + x[3 * m - z + i] = round_fx(L_tmp); + move16(); +#endif + } + + FOR (i = 0; i < m; i++) + { +#ifdef ENABLE_HR_MODE + L_tmp = L_negate(Mpy_32_32_lc3plus(L_shl(y[i], y_s), w[m + i])); + x[3 * m - z - 1 - i] = L_tmp; + move32(); +#else + L_tmp = L_negate(Mpy_32_16_lc3plus(L_shl(y[i], y_s), w[m + i])); + x[3 * m - z - 1 - i] = round_fx(L_tmp); + move16(); +#endif + } + +#ifdef ENABLE_HR_MODE + basop_memmove(mem, &x[N], memLen * sizeof(Word32)); +#else + basop_memmove(mem, &x[N], memLen * sizeof(Word16)); +#endif + + *mem_e = *y_e; move16(); + } + +#ifdef DYNMEM_COUNT + Dyn_Mem_Out(); +#endif +} +/* End Processing */ + +void Processing_ITDA_WIN_OLA( + Word32 L_x_tda[], /* i: X_TDA buffer data = "y" DCT-IV output */ + Word16 * y_e, /* i/o: x_tda input exponent "y_e" , x output exponent */ +#ifdef ENABLE_HR_MODE + const Word32 w[], /* i: window coefficients including normalization of sqrt(2/N) and scaled by 2^4 */ +#else + const Word16 w[], /* i: window coefficients including normalization of sqrt(2/N) and scaled by 2^4 */ +#endif + Word16 mem[], /* i/o: overlap add memory */ + Word16 * mem_e, /* i/o: overlap add exponent */ + Word16 x[], /* o: time signal out */ + Word16 wLen, /* i: window length */ + Word16 N, /* i: block size */ + Word16 memLen /* i: overlap add buffer size */ + ) +{ + /* Declarations */ + Word16 i, o, z, m, s; + Word16 y_s, mem_s; + Word32 L_tmp; + Word32 *L_y; + Word16 fs_idx, tmp_w, w_factor; + Word16 factorITDA[5]= { 25905 , 18318 , 22435 , 25905 , 31727}; + +#ifdef DYNMEM_COUNT + Dyn_Mem_In("Processing_ITDA_WIN_OLA", sizeof(struct { + Word16 i, o, z, m, s; + Word16 y_s, mem_s; + Word32 L_tmp; + Word32 *L_y; + })); +#endif + + + /* Init (constants per sample rate) */ + z = 2 * N - wLen; /* number of leading zeros in window */ + m = N >> 1; /* half block size */ + o = m - z; + + + L_y = L_x_tda; /* use same variables naming as in IMDCT for DCT-IV output signal y */ + + y_s = getScaleFactor32_lc3plus(L_y, N); + + y_s = sub(y_s, 1); /* add 1 bit margin , y_s is now initial tda upscaling factor */ + + + *y_e = sub(add(*y_e,1),y_s); /* handle W scale down by 2^(3) , as mdct synthesis window was upscaled by pow(2,x) x=2 for NB otherwise 3 */ + + + + mem_s = getScaleFactor16_0(mem, memLen); + + IF (sub(mem_s, 16) < 0) + { + mem_s = sub(mem_s, 1); /* one bit margin */ + *mem_e = sub(*mem_e, mem_s); /*adjusted mem exponent due to new scale */ + } + ELSE + { + *mem_e = 0; move16(); + } + + s = sub(*mem_e, *y_e); /* */ + + IF (s > 0) + { + y_s = sub(y_s, s); /* new , reduced upshift of TDA in window application loop */ + *y_e = add(*y_e, s); /* resulting new exp y_e for output signal */ + } + ELSE + { + mem_s = add(mem_s, s); /* s negative or zero, new , decreased upshift of OLAmem in loop */ + *mem_e = sub(*mem_e, s); /* resulting new exp mem_e for OLA_mem output signal */ + } + + fs_idx = mult(N,(Word16)(32768.0/99.0)); /* truncation needed , i.e no rounding can be applied here */ + w_factor = factorITDA[fs_idx]; move16(); + y_s = s_max(s_min(y_s, 31), -31); + + FOR (i = 0; i < o; i++) + { + tmp_w = mult_r(extractW16(w[4 * m - 1 - i - z]), w_factor); + L_tmp = L_sub(L_shl_sat(L_deposit_h(mem[i]), mem_s), Mpy_32_16_lc3plus(L_shl(L_y[m + i + z], y_s), tmp_w)); + x[i] = round_fx_sat(L_tmp); + move16(); + } + + FOR (i = 0; i < m; i++) + { + tmp_w = mult_r(extractW16(w[3 * m - 1 - i]), w_factor); + L_tmp = L_add(L_shl_sat(L_deposit_h(mem[i + o]), mem_s), Mpy_32_16_lc3plus(L_shl(L_y[2 * m - 1 - i], y_s), tmp_w)); + x[i + o] = round_fx_sat(L_tmp); + move16(); + } + + FOR (i = 0; i < m; i++) + { + tmp_w = mult_r(extractW16(w[m - 1 - i]), w_factor); + L_tmp = L_negate(Mpy_32_16_lc3plus(L_shl(L_y[i], y_s), tmp_w)); + x[3 * m - z + i] = round_fx(L_tmp); move16(); + } + + FOR (i = 0; i < m; i++) + { + tmp_w = mult_r(extractW16(w[m + i]), w_factor); + L_tmp = L_negate(Mpy_32_16_lc3plus(L_shl(L_y[i], y_s), tmp_w )); + x[3 * m - z - 1 - i] = round_fx(L_tmp); move16(); + } + + FOR (i = 0; i < memLen; i++) + { + mem[i] = x[N + i]; move16(); + } + *mem_e = *y_e; move16(); /* set OLA mem exp to x_Fx exponent*/ + + + +#ifdef DYNMEM_COUNT + Dyn_Mem_Out(); +#endif +} + diff --git a/lib_lc3plus/lc3.c b/lib_lc3plus/lc3.c new file mode 100644 index 0000000000000000000000000000000000000000..88ccc186e52eb2268cce564c2366a7ee85ef6bad --- /dev/null +++ b/lib_lc3plus/lc3.c @@ -0,0 +1,434 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.5 * +* 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 "defines.h" +#include "functions.h" +#include "lc3.h" +#include "setup_dec_lc3.h" +#include "setup_enc_lc3.h" + +#define RETURN_IF(cond, error) \ + if (cond) \ + return (error) + +#ifndef FIX_IVAS_LC3PLUS_WARNINGS +#ifdef SUBSET_NB +#pragma message("- SUBSET_NB") +#endif +#ifdef SUBSET_WB +#pragma message("- SUBSET_WB") +#endif +#ifdef SUBSET_SSWB +#pragma message("- SUBSET_SSWB") +#endif +#ifdef SUBSET_SWB +#pragma message("- SUBSET_SWB") +#endif +#ifdef SUBSET_FB +#pragma message("- SUBSET_FB") +#endif +#ifdef SUBSET_UB +#pragma message("- SUBSET_UB") +#endif +#endif + +/* ensure api header constants are up to date */ +STATIC_ASSERT(LC3PLUS_MAX_SAMPLES >= MAX_LEN); +STATIC_ASSERT(LC3PLUS_MAX_CHANNELS >= MAX_CHANNELS); +STATIC_ASSERT(LC3PLUS_MAX_BYTES >= BYTESBUFSIZE); +STATIC_ASSERT(LC3PLUS_ENC_MAX_SIZE >= ENC_MAX_SIZE); +STATIC_ASSERT(LC3PLUS_DEC_MAX_SIZE >= DEC_MAX_SIZE); +STATIC_ASSERT(LC3PLUS_ENC_MAX_SCRATCH_SIZE >= SCRATCH_BUF_LEN_ENC_TOT); +STATIC_ASSERT(LC3PLUS_DEC_MAX_SCRATCH_SIZE >= SCRATCH_BUF_LEN_DEC_TOT); +STATIC_ASSERT(PLC_FADEOUT_IN_MS >= 20); + + +/* misc functions ************************************************************/ + +int lc3plus_version(void) +{ + return LC3PLUS_VERSION; +} + +int lc3plus_channels_supported(int channels) +{ + return channels >= 1 && channels <= MAX_CHANNELS; +} + +int lc3plus_samplerate_supported(int samplerate) +{ + switch (samplerate) + { +#ifdef SUBSET_NB + case 8000: return 1; +#endif +#ifdef SUBSET_WB + case 16000: return 1; +#endif +#ifdef SUBSET_SSWB + case 24000: return 1; +#endif +#ifdef SUBSET_SWB + case 32000: return 1; +#endif +#ifdef SUBSET_FB + case 44100: return 1; + case 48000: return 1; +#endif +#ifdef ENABLE_HR_MODE + case 96000: return 1; +#endif + default: return 0; + } + assert("should not be reached, added to avoid issues with WMC tool instrumentation"); + return 0; /* should not be reached, added to avoid issues with WMC tool instrumentation */ +} + +static int lc3plus_plc_mode_supported(LC3PLUS_PlcMode plc_mode) +{ + switch ((int)plc_mode) + { + case LC3PLUS_PLC_ADVANCED: /* fallthru */ + return 1; + default: return 0; + } + assert("should not be reached, added to avoid issues with WMC tool instrumentation"); + return 0; /* should not be reached, added to avoid issues with WMC tool instrumentation */ +} + +static int lc3plus_frame_size_supported(int frame_dms) +{ + switch (frame_dms) + { + case 25: /* fallthru */ + case 50: /* fallthru */ +#ifdef CR8_G_ADD_75MS + case 75: /* fallthru */ +#endif + case 100: + return 1; + default: return 0; + } + assert("should not be reached, added to avoid issues with WMC tool instrumentation"); + return 0; /* should not be reached, added to avoid issues with WMC tool instrumentation */ +} + +static int null_in_list(void **list, int n) +{ + while (--n >= 0) + RETURN_IF(list[n] == NULL, 1); + return 0; +} + +/* return pointer to aligned base + base_size, *base_size += size + 4 bytes align */ +void *balloc(void *base, size_t *base_size, size_t size) +{ + uintptr_t ptr = ((uintptr_t)base + *base_size + 3) & ~3; + assert((uintptr_t)base % 4 == 0); /* base must be 4-byte aligned */ + *base_size = (*base_size + size + 3) & ~3; + return (void *)ptr; +} + +int32_t lc3_enc_supported_lfe(void) +{ + return 1; +} + +/* encoder functions *********************************************************/ + +LC3PLUS_Error lc3plus_enc_init(LC3PLUS_Enc *encoder, int samplerate, int channels +#ifdef ENABLE_HR_MODE + , int hrmode +#endif + , int32_t lfe_channel_array[] + ) +{ + int ch = 0; + + RETURN_IF(encoder == NULL, LC3PLUS_NULL_ERROR); + RETURN_IF((uintptr_t)encoder % 4 != 0, LC3PLUS_ALIGN_ERROR); + RETURN_IF(!lc3plus_samplerate_supported(samplerate), LC3PLUS_SAMPLERATE_ERROR); + RETURN_IF(!lc3plus_channels_supported(channels), LC3PLUS_CHANNELS_ERROR); +#ifdef ENABLE_HR_MODE + RETURN_IF(samplerate==96000 && hrmode == 0, LC3PLUS_HRMODE_ERROR); +#endif + + for (ch = 0; ch < channels; ch++) + { + RETURN_IF(!lc3_enc_supported_lfe() && lfe_channel_array[ch], LC3PLUS_LFE_MODE_NOT_SUPPORTED); + } + +#ifdef ENABLE_HR_MODE + return FillEncSetup(encoder, samplerate, channels, hrmode + , lfe_channel_array + ); /* real bitrate check happens here */ +#else + return FillEncSetup(encoder, samplerate, channels + , lfe_channel_array + ); /* real bitrate check happens here */ +#endif +} + +int lc3plus_enc_get_size(int samplerate, int channels) +{ + RETURN_IF(!lc3plus_samplerate_supported(samplerate), 0); + RETURN_IF(!lc3plus_channels_supported(channels), 0); + return alloc_encoder(NULL, samplerate, channels); +} + +int lc3plus_enc_get_scratch_size(const LC3PLUS_Enc *encoder) +{ + int size = 0; + RETURN_IF(encoder == NULL, 0); + +#ifdef ENABLE_HR_MODE + size = 47 * MAX(encoder->frame_length, 160) + 64; +#else + size = 14 * MAX(encoder->frame_length, 160) + 64; +#endif + assert(size <= LC3PLUS_ENC_MAX_SCRATCH_SIZE); + return size; +} + +int lc3plus_enc_get_input_samples(const LC3PLUS_Enc *encoder) +{ + RETURN_IF(encoder == NULL, 0); + return encoder->frame_length; +} + +int lc3plus_enc_get_num_bytes(const LC3PLUS_Enc *encoder) +{ + RETURN_IF(encoder == NULL, 0); + return (Word32)encoder->bitrate * encoder->frame_length / (8 * encoder->fs_in); +} + +int lc3plus_enc_get_real_bitrate(const LC3PLUS_Enc *encoder) +{ + int ch = 0, totalBytes = 0; + RETURN_IF(encoder == NULL, 0); + RETURN_IF(!encoder->lc3_br_set, LC3PLUS_BITRATE_UNSET_ERROR); + + for (ch = 0; ch < encoder->channels; ch++) + { + totalBytes += encoder->channel_setup[ch]->targetBytes; + } + + int bitrate = (totalBytes * 80000.0 + encoder->frame_dms - 1) / encoder->frame_dms; + + if (encoder->fs_in == 44100) + { + int rem = bitrate % 480; + bitrate = ((bitrate - rem) / 480) * 441 + (rem * 441) / 480; + } + + return bitrate; +} + +LC3PLUS_Error lc3plus_enc_set_bitrate(LC3PLUS_Enc *encoder, int bitrate) +{ + RETURN_IF(encoder == NULL, LC3PLUS_NULL_ERROR); + RETURN_IF(bitrate <= 0, LC3PLUS_BITRATE_ERROR); + return update_enc_bitrate(encoder, bitrate); +} + +int lc3plus_enc_get_delay(const LC3PLUS_Enc *encoder) +{ + RETURN_IF(encoder == NULL, 0); + return encoder->frame_length - 2 * encoder->la_zeroes; +} + +LC3PLUS_Error lc3plus_enc_set_ep_mode(LC3PLUS_Enc *encoder, LC3PLUS_EpMode epmode) +{ + RETURN_IF(encoder == NULL, LC3PLUS_NULL_ERROR); + RETURN_IF((unsigned)epmode > LC3PLUS_EP_HIGH, LC3PLUS_EPMODE_ERROR); + encoder->epmode = epmode; + return encoder->lc3_br_set ? update_enc_bitrate(encoder, encoder->bitrate) : LC3PLUS_OK; +} + +LC3PLUS_Error lc3plus_enc_set_ep_mode_request(LC3PLUS_Enc *encoder, LC3PLUS_EpModeRequest epmr) +{ + RETURN_IF(encoder == NULL, LC3PLUS_NULL_ERROR); + RETURN_IF((unsigned)epmr > LC3PLUS_EPMR_HIGH, LC3PLUS_EPMR_ERROR); + encoder->epmr = epmr; + return LC3PLUS_OK; +} + +LC3PLUS_Error lc3plus_enc_set_frame_dms(LC3PLUS_Enc *encoder, int frame_dms) +{ + RETURN_IF(encoder == NULL, LC3PLUS_NULL_ERROR); + RETURN_IF(!lc3plus_frame_size_supported(frame_dms), LC3PLUS_FRAMEMS_ERROR); + RETURN_IF(encoder->lc3_br_set, LC3PLUS_BITRATE_SET_ERROR); + encoder->frame_dms = frame_dms; + set_enc_frame_params(encoder); + return LC3PLUS_OK; +} + + +LC3PLUS_Error lc3plus_enc_set_bandwidth(LC3PLUS_Enc *encoder, int bandwidth) +{ + RETURN_IF(encoder == NULL, LC3PLUS_NULL_ERROR); + Word32 effective_fs = encoder->fs_in; + if (encoder->bandwidth != bandwidth) { + if (encoder->fs_in > 40000) { + effective_fs = 40000; + } + if ((bandwidth * 2) > effective_fs) { + return LC3PLUS_BW_WARNING; + } + else { + encoder->bandwidth = bandwidth; + encoder->bandwidth_preset = bandwidth; + encoder->bw_ctrl_active = 1; + update_enc_bitrate(encoder, encoder->bitrate); + } + } + return LC3PLUS_OK; +} + + +static LC3PLUS_Error lc3plus_enc(LC3PLUS_Enc *encoder, void **input_samples, int bitdepth, void *output_bytes, int *num_bytes, + void *scratch) +{ + RETURN_IF(!encoder || !input_samples || !output_bytes || !num_bytes || !scratch, LC3PLUS_NULL_ERROR); + RETURN_IF(null_in_list(input_samples, encoder->channels), LC3PLUS_NULL_ERROR); + RETURN_IF(bitdepth != 16 && bitdepth != 24, LC3PLUS_ERROR); + RETURN_IF(!encoder->lc3_br_set, LC3PLUS_BITRATE_UNSET_ERROR); + *num_bytes = Enc_LC3PLUS(encoder, input_samples, bitdepth, output_bytes, scratch, *num_bytes == -1); + + assert(*num_bytes == lc3plus_enc_get_num_bytes(encoder)); + return LC3PLUS_OK; +} + +LC3PLUS_Error lc3plus_enc16(LC3PLUS_Enc *encoder, int16_t **input_samples, void *output_bytes, int *num_bytes, void *scratch) +{ + return lc3plus_enc(encoder, (void **)input_samples, 16, output_bytes, num_bytes, scratch); +} + +LC3PLUS_Error lc3plus_enc24(LC3PLUS_Enc *encoder, int32_t **input_samples, void *output_bytes, int *num_bytes, void *scratch) +{ + return lc3plus_enc(encoder, (void **)input_samples, 24, output_bytes, num_bytes, scratch); +} + +/* decoder functions *********************************************************/ + +LC3PLUS_Error lc3plus_dec_init(LC3PLUS_Dec *decoder, int samplerate, int channels, LC3PLUS_PlcMode plc_mode +#ifdef ENABLE_HR_MODE + , int hrmode +#endif +) +{ + RETURN_IF(decoder == NULL, LC3PLUS_NULL_ERROR); + RETURN_IF(!lc3plus_samplerate_supported(samplerate), LC3PLUS_SAMPLERATE_ERROR); + RETURN_IF(!lc3plus_channels_supported(channels), LC3PLUS_CHANNELS_ERROR); + RETURN_IF(!lc3plus_plc_mode_supported(plc_mode), LC3PLUS_PLCMODE_ERROR); +#ifdef ENABLE_HR_MODE + RETURN_IF(samplerate==96000 && hrmode == 0, LC3PLUS_HRMODE_ERROR); +#endif + + return FillDecSetup(decoder, samplerate, channels, plc_mode +#ifdef ENABLE_HR_MODE + , hrmode +#endif + ); +} + +int lc3plus_dec_get_size(int samplerate, int channels, LC3PLUS_PlcMode plc_mode) +{ + RETURN_IF(!lc3plus_samplerate_supported(samplerate), 0); + RETURN_IF(!lc3plus_channels_supported(channels), 0); + RETURN_IF(!lc3plus_plc_mode_supported(plc_mode), 0); + return alloc_decoder(NULL, samplerate, channels); +} + +int lc3plus_dec_get_scratch_size(const LC3PLUS_Dec *decoder) +{ + int size = 0; + RETURN_IF(decoder == NULL, 0); + +#ifdef ENABLE_HR_MODE + size = 30 * DYN_MAX_LEN(decoder->fs) + 2866; + size += 4 * MAX_LGW + 8 * DYN_MAX_LPROT(decoder->fs) + 16 * DYN_MAX_LEN(decoder->fs); +#else + size = 12 * DYN_MAX_LEN(decoder->fs) + 752; + size += 2 * MAX_LGW + 8 * DYN_MAX_LPROT(decoder->fs) + 8 * DYN_MAX_LEN(decoder->fs); + size += 3720; +#endif + + assert(size <= LC3PLUS_DEC_MAX_SCRATCH_SIZE); + return size; +} + +LC3PLUS_Error lc3plus_dec_set_ep_enabled(LC3PLUS_Dec *decoder, int ep_enabled) +{ + RETURN_IF(decoder == NULL, LC3PLUS_NULL_ERROR); + decoder->ep_enabled = ep_enabled != 0; + decoder->epmr = LC3PLUS_EPMR_ZERO; + return LC3PLUS_OK; +} + +int lc3plus_dec_get_error_report(const LC3PLUS_Dec *decoder) +{ + RETURN_IF(decoder == NULL, 0); + return decoder->error_report == 2047 ? -1 : decoder->error_report & 0x07FF; +} + +int lc3plus_dec_get_epok_flags(const LC3PLUS_Dec *decoder) +{ + RETURN_IF(decoder == NULL, 0); + return decoder->error_report >> 11; +} + +LC3PLUS_EpModeRequest lc3plus_dec_get_ep_mode_request(const LC3PLUS_Dec *decoder) +{ + RETURN_IF(decoder == NULL, LC3PLUS_EPMR_ZERO); + return (LC3PLUS_EpModeRequest)decoder->epmr; +} + +LC3PLUS_Error lc3plus_dec_set_frame_dms(LC3PLUS_Dec *decoder, int frame_dms) +{ + RETURN_IF(decoder == NULL, LC3PLUS_NULL_ERROR); + RETURN_IF(!lc3plus_frame_size_supported(frame_dms), LC3PLUS_FRAMEMS_ERROR); + RETURN_IF(decoder->plcMeth == 2 && frame_dms != 100, LC3PLUS_FRAMEMS_ERROR); + + decoder->frame_dms = frame_dms; + set_dec_frame_params(decoder); + return LC3PLUS_OK; +} + + +int lc3plus_dec_get_output_samples(const LC3PLUS_Dec *decoder) +{ + RETURN_IF(decoder == NULL, 0); + return decoder->frame_length; +} + +int lc3plus_dec_get_delay(const LC3PLUS_Dec *decoder) +{ + RETURN_IF(decoder == NULL, 0); + return decoder->frame_length - 2 * decoder->la_zeroes; +} + +static LC3PLUS_Error lc3plus_dec(LC3PLUS_Dec *decoder, void *input_bytes, int num_bytes, void **output_samples, int bitdepth, + void *scratch, int bfi_ext) +{ + RETURN_IF(!decoder || !input_bytes || !output_samples || !scratch, LC3PLUS_NULL_ERROR); + RETURN_IF(null_in_list(output_samples, decoder->channels), LC3PLUS_NULL_ERROR); + RETURN_IF(bitdepth != 16 && bitdepth != 24, LC3PLUS_ERROR); + return Dec_LC3PLUS(decoder, input_bytes, num_bytes, output_samples, bitdepth, scratch, bfi_ext); +} + +LC3PLUS_Error lc3plus_dec16(LC3PLUS_Dec *decoder, void *input_bytes, int num_bytes, int16_t **output_samples, void *scratch, int bfi_ext) +{ + return lc3plus_dec(decoder, input_bytes, num_bytes, (void **)output_samples, 16, scratch, bfi_ext); +} + +LC3PLUS_Error lc3plus_dec24(LC3PLUS_Dec *decoder, void *input_bytes, int num_bytes, int32_t **output_samples, void *scratch, int bfi_ext) +{ + return lc3plus_dec(decoder, input_bytes, num_bytes, (void **)output_samples, 24, scratch, bfi_ext); +} diff --git a/lib_lc3plus/lc3.h b/lib_lc3plus/lc3.h new file mode 100644 index 0000000000000000000000000000000000000000..64d8cc590c5fc66c9fa711086e86ced5be081e72 --- /dev/null +++ b/lib_lc3plus/lc3.h @@ -0,0 +1,520 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.5 * +* Low Complexity Communication Codec Plus (LC3plus) * +* * +* Copyright licence is solely granted through ETSI Intellectual Property * +* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * +* estoppel or otherwise. * +******************************************************************************/ + +/*! \file lc3.h + * This header provides the API for LC3plus. + * + * This library is targeting devices with extreme memory limitations, so memory management + * must be handeled by the user. This includes allocating memory for the structs and scratch + * memory. The structs are persistent between function calls. The scratch memory is working + * memory that does not persist between function calls. + * + * The amount of memory needed for various configurations can be obtained from the lc3plus_*_get_size + * and lc3plus_*_get_scratch_size functions. If memory usage is not a concern the LC3PLUS_*_MAX_SIZE + * LC3PLUS_*_MAX_SCRATCH_SIZE macros can be used for all configurations. + * + * Depending on the build configuration some functions might not be available. + */ + +#ifndef LC3PLUS_H +#define LC3PLUS_H + +#define ENABLE_HR_MODE + +#ifndef _MSC_VER +#include +#else +typedef __int16 int16_t; +typedef __int32 int32_t; +#endif + +/*! Construct version number from major/minor/micro values. */ +#define LC3PLUS_VERSION_INT(major, minor, micro) (((major) << 16) | ((minor) << 8) | (micro)) + +/*! Version number to ensure header and binary are matching. */ +#define LC3PLUS_VERSION LC3PLUS_VERSION_INT(1, 7, 3) + +/*! Maximum number of supported channels. The actual binary might support + * less, use lc3plus_channels_supported() to check. */ +#define LC3PLUS_MAX_CHANNELS 2 + +/*! Maximum number of samples per channel that can be stored in one LC3plus frame. */ +#ifdef ENABLE_HR_MODE +#define LC3PLUS_MAX_SAMPLES 960 +#else +#define LC3PLUS_MAX_SAMPLES 480 +#endif + +/*! Maximum number of bytes of one LC3plus frame. */ +#ifdef ENABLE_HR_MODE +#define LC3PLUS_MAX_BYTES (625 * LC3PLUS_MAX_CHANNELS) +#else +#define LC3PLUS_MAX_BYTES 870 +#endif + +/*! Maximum size needed to store encoder state. */ +#ifdef ENABLE_HR_MODE +#define LC3PLUS_ENC_MAX_SIZE 12628 +#else +#define LC3PLUS_ENC_MAX_SIZE 7226 +#endif + +/*! Maximum size needed to store decoder state. */ +#ifdef ENABLE_HR_MODE +#define LC3PLUS_DEC_MAX_SIZE 42488 +#else +#define LC3PLUS_DEC_MAX_SIZE 28446 +#endif + +/*! Maximum scratch size needed by lc3plus_enc16() or lc3plus_enc24().*/ +#ifdef ENABLE_HR_MODE +# define LC3PLUS_ENC_MAX_SCRATCH_SIZE 45624 +#else +# define LC3PLUS_ENC_MAX_SCRATCH_SIZE 6784 +#endif + +/*! Maximum scratch size needed by lc3plus_dec16() or lc3plus_dec24(). */ +#ifdef ENABLE_HR_MODE +#define LC3PLUS_DEC_MAX_SCRATCH_SIZE 59768 +#else +#define LC3PLUS_DEC_MAX_SCRATCH_SIZE 27474 +#endif +/*! Decoder packet loss concealment mode */ +typedef enum +{ + LC3PLUS_PLC_ADVANCED = 1 /*!< Enhanced concealment method */ +} LC3PLUS_PlcMode; + +/*! Error protection mode. LC3PLUS_EP_ZERO differs to LC3PLUS_EP_OFF in that + * errors can be detected but not corrected. */ +typedef enum +{ + LC3PLUS_EP_OFF = 0, /*!< Error protection is disabled */ + LC3PLUS_EP_ZERO = 1, /*!< Error protection with 0 bit correction */ + LC3PLUS_EP_LOW = 2, /*!< Error protection correcting one symbol per codeword */ + LC3PLUS_EP_MEDIUM = 3, /*!< Error protection correcting two symbols per codeword */ + LC3PLUS_EP_HIGH = 4 /*!< Error protection correcting three symbols per codeword */ +} LC3PLUS_EpMode; + +/*! Error protection mode request. On the encoder sidem, LC3PLUS_EPMR_ZERO to LC3PLUS_EPMR_HIGH + * can be set. The decoder returns mode requests with different confidences. */ +typedef enum +{ + LC3PLUS_EPMR_ZERO = 0, /*!< Request no error correction. High confidence if returned by decoder. */ + LC3PLUS_EPMR_LOW = 1, /*!< Request low error correction. High confidence if returned by decoder. */ + LC3PLUS_EPMR_MEDIUM = 2, /*!< Request medium error correction. High confidence if returned by decoder. */ + LC3PLUS_EPMR_HIGH = 3, /*!< Request high error correction. High confidence if returned by decoder. */ + LC3PLUS_EPMR_ZERO_MC = 4, /*!< No error correction requested, medium confidence. */ + LC3PLUS_EPMR_LOW_MC = 5, /*!< Low error correction requested, medium confidence. */ + LC3PLUS_EPMR_MEDIUM_MC = 6, /*!< Medium error correction requested, medium confidence. */ + LC3PLUS_EPMR_HIGH_MC = 7, /*!< High error correction requested, medium confidence. */ + LC3PLUS_EPMR_ZERO_NC = 8, /*!< No error correction requested, unvalidated. */ + LC3PLUS_EPMR_LOW_NC = 9, /*!< Low error correction requested, unvalidated. */ + LC3PLUS_EPMR_MEDIUM_NC = 10, /*!< Medium error correction requested, unvalidated. */ + LC3PLUS_EPMR_HIGH_NC = 11 /*!< High error correction requested, unvalidated. */ +} LC3PLUS_EpModeRequest; + +/*! Error codes returned by functions. */ +typedef enum +{ + LC3PLUS_OK = 0, /*!< No error occurred */ + LC3PLUS_ERROR = 1, /*!< Function call failed */ + LC3PLUS_DECODE_ERROR = 2, /*!< Frame failed to decode and was concealed */ + LC3PLUS_NULL_ERROR = 3, /*!< Pointer argument is null */ + LC3PLUS_SAMPLERATE_ERROR = 4, /*!< Invalid samplerate value */ + LC3PLUS_CHANNELS_ERROR = 5, /*!< Invalid channels value */ + LC3PLUS_BITRATE_ERROR = 6, /*!< Invalid bitrate value */ + LC3PLUS_NUMBYTES_ERROR = 7, /*!< Invalid num_bytes value */ + LC3PLUS_EPMODE_ERROR = 8, /*!< Invalid plc_method value */ + LC3PLUS_FRAMEMS_ERROR = 9, /*!< Invalid epmode value */ + LC3PLUS_ALIGN_ERROR = 10, /*!< Invalid frame_ms value */ + LC3PLUS_HRMODE_ERROR = 11, /*!< Unaligned pointer */ + LC3PLUS_BITRATE_UNSET_ERROR = 12, /*!< Invalid epmr value */ + LC3PLUS_BITRATE_SET_ERROR = 13, /*!< Invalid usage of hrmode, sampling rate and frame size */ + LC3PLUS_HRMODE_BW_ERROR = 14, /*!< Function called before bitrate has been set */ + LC3PLUS_PLCMODE_ERROR = 15, /*!< Function called after bitrate has been set */ + LC3PLUS_EPMR_ERROR = 16, /*!< Invalid external bad frame index */ + LC3PLUS_PADDING_ERROR = 17, /*!< Incorrect padding value */ + FRAMESIZE_ERROR = 18, /*!< Incorrect frame size during decoding */ + LC3PLUS_LFE_MODE_NOT_SUPPORTED = 19, /*!< LFE support not available */ + + /* START WARNING */ + LC3PLUS_WARNING = 20, + LC3PLUS_BW_WARNING = 21 /*!< Invalid bandwidth cutoff frequency */ + +} LC3PLUS_Error; + +typedef struct LC3PLUS_Enc LC3PLUS_Enc; /*!< Opaque encoder struct. */ +typedef struct LC3PLUS_Dec LC3PLUS_Dec; /*!< Opaque decoder struct. */ + +/*! \addtogroup Misc + * \{ */ + +/*! Test LFE mode support. + * + * Tests the support of the LFE mode. + * + * \return 1 for true, 0 for false. + */ +int32_t lc3_enc_supported_lfe(void); + +/*! Return library version number. It should match LC3PLUS_VERSION. */ +int lc3plus_version(void); + +/*! Tests if the library supports number of channels. + * + * \param[in] channels Number of channels. + * \return 1 for true, 0 for false. + */ +int lc3plus_channels_supported(int channels); + +/*! Tests if the library supports a sampling rate. + * + * \param[in] samplerate Sampling rate + * \return 1 for true, 0 for false + */ +int lc3plus_samplerate_supported(int samplerate); + +/*! \} + * \addtogroup Encoder + * \{ */ + +/*! + * Initialize LC3plus encoder. + * + * This function is used to fill a user-allocated encoder struct. This is typically + * called once for a samplerate / channel configuration. After init and before encoding + * the first frame you must call lc3plus_enc_set_bitrate(). + * + * \param[out] encoder Pointer to allocated encoder memory. It must have a size provided + * by lc3plus_enc_get_size() for matching samplerate / channels + * configuration or LC3PLUS_ENC_MAX_SIZE. + * \param[in] channels Number of channels. + * \param[in] samplerate Input sampling rate. Allowed sampling rates are: + * 8000, 16000, 24000, 32000, 44100, 48000 + * \param[in] hrmode High resolution mode. + * \return LC3PLUS_OK on success or appropriate error code. + */ +LC3PLUS_Error lc3plus_enc_init(LC3PLUS_Enc *encoder, int samplerate, int channels +#ifdef ENABLE_HR_MODE + , int hrmode +#endif + , int32_t lfe_channel_array[] + ); + +/*! + * Encode LC3plus frame with 16 bit input. + * + * Each call consumes a fixed number of samples. The number of input samples + * can be obtained from lc3plus_enc_get_input_samples(). + * + * \param[in] encoder Encoder handle initialized by lc3plus_enc_init(). + * \param[in] input_samples Input samples. The left channel is stored in input_samples[0], + * the right channel in input_samples[1]. The input is not changed + * by the encoder. + * \param[out] output_bytes Output buffer. It must have a at least lc3plus_enc_get_num_bytes() + * or at most LC3PLUS_MAX_BYTES. + * \param[out] num_bytes Number of bytes written to output_bytes. + * \param scratch A pointer to an allocated work buffer of at least + * lc3plus_enc_get_scratch_size() or at most LC3PLUS_ENC_SCRATCH_SIZE bytes. + * The buffer does not have to persist, so it can be used for other + * purposes in between calls. + * \return LC3PLUS_OK on success or appropriate error code. + */ +LC3PLUS_Error lc3plus_enc16(LC3PLUS_Enc *encoder, int16_t **input_samples, void *output_bytes, int *num_bytes, void *scratch); + +/*! Encode LC3plus frame with 24 bit input. + * + * The input samples are expected to be 24-bit values, sign-extended to 32-bit. + * See lc3plus_enc16() for parameter documentation. + */ +LC3PLUS_Error lc3plus_enc24(LC3PLUS_Enc *encoder, int32_t **input_samples, void *output_bytes, int *num_bytes, void *scratch); + +/*! Get the size of the LC3plus encoder struct for a samplerate / channel configuration. + * If memory is not restricted LC3PLUS_ENC_MAX_SIZE can be used for all configurations. + * + * \param[in] samplerate Sampling rate. + * \param[in] channels Number of channels. + * \return Size in bytes or 0 on error. + */ +int lc3plus_enc_get_size(int samplerate, int channels); + +/*! Get the size of the scratch buffer required by lc3plus_enc16() or lc3plus_enc24() for the current + * encoder configuration. If memory is not restricted, LC3PLUS_ENC_MAX_SCRATCH_SIZE can be used for + * all configurations. + * + * \param[in] encoder Encoder handle. + * \return Size in bytes or 0 on error. + */ +int lc3plus_enc_get_scratch_size(const LC3PLUS_Enc *encoder); + +/*! Get number of samples per channel expected by lc3plus_enc16() or lc3plus_enc24(). + * + * \param[in] encoder Encoder handle. + * \return Number of samples or 0 on error. + */ +int lc3plus_enc_get_input_samples(const LC3PLUS_Enc *encoder); + +/*! Get real internal bitrate of the encoder. It might differ from the requested bitrate due + * to error protection or 44.1 kHz input. + * + * \param[in] encoder Encoder handle. + * \return Bitrate in bits per second or 0 on error. + */ +int lc3plus_enc_get_real_bitrate(const LC3PLUS_Enc *encoder); + +/*! Get the maximum number of bytes produced by lc3plus_enc16() or lc3plus_enc24() for the current + * bitrate. It should be equal to the num_bytes output of lc3plus_enc16(). + * + * \param[in] encoder Encoder handle. + * \return Size in bytes or 0 on error. + */ +int lc3plus_enc_get_num_bytes(const LC3PLUS_Enc *encoder); + +/*! Set encoder bitrate for all channels. + * This function must be called at least once before encoding the first frame, but + * after other configuration functions such as lc3plus_enc_set_frame_dms(). + * + * Recommended bitrates for input sampling rates with 10 ms framing: + * kHz | kbps + * --------|----- + * 8 | 24 + * 16 | 32 + * 24 | 48 + * 32 | 64 + * 44.1/48 | 80(voice) 128(music) + * + * \param[in] encoder Encoder handle. + * \param[in] bitrate Bitrate in bits per second. + * \return LC3PLUS_OK on success or appropriate error code. + */ +LC3PLUS_Error lc3plus_enc_set_bitrate(LC3PLUS_Enc *encoder, int bitrate); + +/*! Set encoder Low-frequency effect moded. deactivates LTPF, TNS, NF. + * + * \param[in] encoder Encoder handle. + * \param[in] lfe LFE mode flag + * \return LC3PLUS_OK on success or appropriate error code. + */ +LC3PLUS_Error lc3plus_enc_set_lfe(LC3PLUS_Enc* encoder, int lfe); + +/*! Get the encoder delay in number of samples. + * + * \param[in] encoder Encoder handle. + * \return Encoder in samples or 0 on error. + */ +int lc3plus_enc_get_delay(const LC3PLUS_Enc *encoder); + +/*! Set the frame length for LC3plus encoder in deci milliseconds. + * Not all lengths may be enabled, in that case LC3PLUS_FRAMEMS_ERROR is returned. + * This function must be called before lc3plus_enc_set_bitrate(). The decoder must be + * configured with lc3plus_dec_set_frame_dms() with the same value. + * + * \param[in] encoder Encoder handle. + * \param[in] frame_ms Frame length in ms. + * \return LC3PLUS_OK on success or appropriate error code. + */ +LC3PLUS_Error lc3plus_enc_set_frame_dms(LC3PLUS_Enc *encoder, int frame_ms); + +/*! Set error protection mode. The default is LC3PLUS_EP_OFF. It is possible to switch between + * different modees during encoding. Dynamic switching is only allowed between LC3PLUS_EP_ZERO, + * LC3PLUS_EP_LOW, LC3_EP_MEDIUM, and LC3PLUS_EP_HIGH. The the decoder must be notified with + * lc3plus_dec_set_ep_enabled() to expect protected data if epmode is other than LC3PLUS_EP_OFF. + * + * \param[in] encoder Encoder handle. + * \param[in] epmode Error protection mode. + * \return LC3PLUS_OK on success or appropriate error code. + */ +LC3PLUS_Error lc3plus_enc_set_ep_mode(LC3PLUS_Enc *encoder, LC3PLUS_EpMode epmode); + +/*! Sets error protection mode request transmitted in each channel encoded frame. + * The channel coder includes an error protection mode request (EPMR) in every frame. + * The EPMR takes value 0, 1, 2, and 3 which request ep modes 1, 2, 3, and 4 from the + * decoding device. The EPMR can be retrieved from the channel decoder via the interface + * routine lc3plus_dec_get_ep_mode_request(). + * + * \param[in] encoder Encoder handle. + * \param[in] epmr Error Protection Mode Request + * \return LC3PLUS_OK on success or appropriate error code. + */ +LC3PLUS_Error lc3plus_enc_set_ep_mode_request(LC3PLUS_Enc *encoder, LC3PLUS_EpModeRequest epmr); + +/*! Set encoder bandwidth to a different value. All frequency bins above the cutoff + * frequency are cut off. Allowed frequencies are: 4 kHz, 8 kHz, 12 kHz, 16 kHz and 24 kHz. + * + * \param[in] encoder Encoder handle. + * \param[in] bandwidth Cutoff Frequency in Hz + * \return LC3PLUS_OK on success or appropriate error code. + */ +LC3PLUS_Error lc3plus_enc_set_bandwidth(LC3PLUS_Enc *encoder, int bandwidth); + +/*! \} + * \addtogroup Decoder + * \{ */ + + +/*! + * Initialize LC3plus decoder. + * + * This function is used to fill a user-allocated decoder struct. This is typically + * called once for a samplerate / channel / plc_mode configuration. + * + * The samplerate and channel arguments must have the same values that were used for encoding. + * LC3plus does not provide a signalling scheme, transporting these values is the responsibility + * of the application. + * + * \param[out] decoder Pointer to decoder memory. It must have as size of least + * lc3plus_dec_get_size() or at most LC3PLUS_DEC_MAX_SIZE. + * \param[in] samplerate Bitstream sampling rate. + * \param[in] channels Bitstream number of channels. + * \param[in] plc_mode Packet loss concealment mode. + * \param[in] hrmode High resolution mode mode. + * + * \return LC3PLUS_OK on success or appropriate error code. + */ +LC3PLUS_Error lc3plus_dec_init(LC3PLUS_Dec *decoder, int samplerate, int channels, LC3PLUS_PlcMode plc_mode +#ifdef ENABLE_HR_MODE + , int hrmode +#endif + ); + +/*! + * Decode compressed LC3plus frame to 16 bit PCM output. + * + * Each call decodes a fixed number of samples. Use lc3plus_dec_get_output_samples() to obtain this + * number. When the input is corrupted and can not be decoded, LC3PLUS_DECODE_ERROR is returned and + * packet loss concealment is applied, so the output is still usable. + * If error protection is enabled and the errors can be corrected the frame is corrected and + * normally decoded. Use lc3plus_dec_get_error_report() to check if errors were corrected. + * + * \param[in] decoder Decoder initialized by lc3plus_dec_init(). + * \param[in] input_bytes Input bytes. If error protection is enabled the input bytes can be + * altered when error correction is applied. This is why this buffer + * must be writable. + * \param[in] num_bytes Number of valid bytes in input_bytes. To signal a lost frame and + * generate concealment output this value must be set to 0. + * \param[out] output_samples Array of pointers to output channel buffers. Each channel buffer + * should provide enough space to hold at most LC3PLUS_MAX_SAMPLES. The + * left channel is stored in output_samples[0], the right channel in + * output_samples[1]. + * \param scratch A pointer to an allocated work buffer of at least + * lc3plus_dec_get_scratch_size() or at most LC3PLUS_DEC_MAX_SCRATCH_SIZE + * bytes. The scratch buffer does not have to persist, so it can be + * used for other purposes in between calls. + * \return Returns LC3PLUS_OK on success or appropriate error code. Note there is + * a special case for LC3PLUS_DECODE_ERROR where the output is still valid. + */ +LC3PLUS_Error lc3plus_dec16(LC3PLUS_Dec *decoder, void *input_bytes, int num_bytes, int16_t **output_samples, void *scratch, + int bfi_ext); + +/*! Decode compressed LC3plus frame to 24 bit PCM output. + * + * The output samples are 24-bit values, sign-extended to 32-bit. + * See lc3plus_dec16() for parameter documentation. + */ +LC3PLUS_Error lc3plus_dec24(LC3PLUS_Dec *decoder, void *input_bytes, int num_bytes, int32_t **output_samples, void *scratch, + int bfi_ext); + +/*! Get the size of the LC3plus decoder struct for a samplerate / channel / plc_mode configuration. + * If memory is not restricted LC3PLUS_DEC_MAX_SIZE can be used for all configurations. + * + * \param[in] channels Number of channels. + * \param[in] samplerate Sampling rate. + * \param[in] plc_mode Packet loss concealment mode. + * \return Size in bytes or 0 on error. + */ +int lc3plus_dec_get_size(int samplerate, int channels, LC3PLUS_PlcMode plc_mode); + +/*! Get the size of the scratch buffer required by lc3plus_dec16() or lc3plus_dec24() for the current + * decoder configuration. If memory is not restricted LC3PLUS_DEC_MAX_SCRATCH_SIZE can be used for + * all configurations. + * + * \param[in] decoder Decoder handle. + * \return Size in bytes or 0 on error. + */ +int lc3plus_dec_get_scratch_size(const LC3PLUS_Dec *decoder); + +/*! Get the number of samples per channel produced by lc3plus_dec16() or lc3plus_dec24(). + * + * \param[in] decoder Decoder handle. + * \return Number of samples or 0 on error. + */ + +int lc3plus_dec_get_output_samples(const LC3PLUS_Dec *decoder); + +/*! Get the decoder delay in number of samples. + * + * \param[in] decoder Decoder handle. + * \return Delay in samples or 0 on error. + */ +int lc3plus_dec_get_delay(const LC3PLUS_Dec *decoder); + +/*! Set the frame length for LC3plus decoder in deci milliseconds. + * Not all lengths may be enabled, in that case LC3PLUS_FRAMEMS_ERROR is returned. + * This only works correcly if the encoder was configured with the same vale. + * + * \param[in] decoder Decoder handle. + * \param[in] frame_ms Frame length in ms. + * \return LC3PLUS_OK on success or appropriate error code. + */ +LC3PLUS_Error lc3plus_dec_set_frame_dms(LC3PLUS_Dec *decoder, int frame_ms); + +/*! Enable or disable error protection. Default value is 0 (disabled). If error protection is + * enabled, the decoder expects that the frames were encoded with error protection mode + * LC3PLUS_EP_ZERO or higher. + * + * \param[in] decoder Decoder handle. + * \param[in] ep_enabled 1 (or any nonzero) for true, 0 for false. + * \return LC3PLUS_OK on success or appropriate error code. + */ +LC3PLUS_Error lc3plus_dec_set_ep_enabled(LC3PLUS_Dec *decoder, int ep_enabled); + +/*! Retrieves the error protection mode reqeust from channel decoder. + * + * The return value encodes both the error protection mode request (EPMR) + * and the confidence of the method by which it was retrieved. + * + * The requested error protection mode is (epmr % 4) + 1, where epmr is the + * function's return value. The confidence is specified as follows. + * + * Confidence | Range + * -----------|------------- + * high | 0 <= epmr < 4 + * medium | 4 <= epmr < 8 + * no | 8 <= epmr < 12 + * + * When receiving stereo content of separately channel encoded audio frames the + * return value is the minimum of two values retrieved from the individual channels. + * + * \param[in] decoder Decoder handle. + * \return Error protection mode reqeust. + */ +LC3PLUS_EpModeRequest lc3plus_dec_get_ep_mode_request(const LC3PLUS_Dec *decoder); + +/*! Get the number of corrected bit errors in the last decoded frame. This only works if + * error protection is active. If the number of errors is greater than the current error + * protection mode can correct, -1 is returned. If the last frame had no errors or the + * decoder handle is NULL, 0 is returned, + * + * \param[in] decoder Decoder handle. + * \return Number of corrected bits or -1. See description for details. + */ +int lc3plus_dec_get_error_report(const LC3PLUS_Dec *decoder); +/*! This function returns an set of flags indicating whether the last frame + * would have been channel decodable in epmode m, m ranging from 1 to 4. Note that + * this information is not available in case the last frame was not channel + * decodable in which case the return value is 0. If the last frame would have + * been decodable in epmode m, m-1th of the return value will be 1. + * Otherwise, if the frame would not have been decodable or if this information + * cannot be retrieved, the m-1th bit of the return value will be 0. + */ +int lc3plus_dec_get_epok_flags(const LC3PLUS_Dec *decoder); + +/*! \} */ +#endif /* LC3plus */ diff --git a/lib_lc3plus/levinson_fx.c b/lib_lc3plus/levinson_fx.c new file mode 100644 index 0000000000000000000000000000000000000000..9003173d04594dfe09c4d408b100883e7ec15cfc --- /dev/null +++ b/lib_lc3plus/levinson_fx.c @@ -0,0 +1,160 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.5 * +* 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 "functions.h" + +void processLevinson_fx(Word32 *lpc, Word32 *ac, Word16 N, Word16 *rc, Word32 *pred_err, Word8 *scratchBuffer) +{ + + Word32 *lpc_tmp; + Word32 rc32, err, sum; + Word16 shift, s, inv; + Counter n, m; + + +#ifdef DYNMEM_COUNT + Dyn_Mem_In("processLevinson_fx", sizeof(struct { + Word32 *lpc_tmp; + Word32 rc32, err, sum; + Word16 shift, s, inv; + Counter n, m; + Word32 params[2]; + })); +#endif + + lpc_tmp = (Word32 *)scratchAlign(scratchBuffer, 0); /* Size = 4 * (M_LTPF + 1) = 100 bytes */ + + /* Init Prediction Error */ + err = ac[0]; move32(); + shift = 0; move16(); + + /* LPC Coefficient 0 */ + lpc[0] = 0x8000000; move32(); + + /* Reflection Coefficient 0 */ + IF (ac[0] != 0) + { + inv = div_s(16383, extract_h(ac[0])); + rc32 = L_shl_pos(Mpy_32_32_lc3plus(L_abs(ac[1]), Mpy_32_16_lc3plus(L_sub(MAX_32, Mpy_32_16_lc3plus(ac[0], inv)), inv)), 2); + } + ELSE + { + rc32 = 0; move32(); + } + if (ac[1] > 0) + { + rc32 = L_negate(rc32); + } + if (rc != NULL) + { + rc[0] = round_fx(rc32); move16(); + } + + /* LPC Coefficient 1 */ + lpc[1] = L_shr_pos(rc32, 4); move32(); + + FOR (n = 2; n <= N; n++) + { + /* Update Prediction Error */ + err = Mpy_32_32_lc3plus(err, L_sub(MAX_32, Mpy_32_32_lc3plus(rc32, rc32))); + s = norm_l(err); + err = L_shl_pos(err, s); + shift = add(shift, s); + + /* Reflection Coefficient n-1 */ + sum = Mpy_32_32_lc3plus(ac[1], lpc[n - 1]); + FOR (m = 2; m < n; m++) + { + sum = L_add(sum, Mpy_32_32_lc3plus(ac[m], lpc[n - m])); + } + + sum = L_add(L_shl_pos(sum, 4), ac[n]); + IF (err != 0) + { + inv = div_s(16383, extract_h(err)); + rc32 = L_shl_pos(Mpy_32_32_lc3plus(L_abs(sum), Mpy_32_16_lc3plus(L_sub(MAX_32, Mpy_32_16_lc3plus(err, inv)), inv)), 2); + } + ELSE + { + rc32 = 0; + } + if (sum > 0) + { + rc32 = L_negate(rc32); + } + rc32 = L_shl(rc32, shift); + if (rc != NULL) + { + rc[n - 1] = round_fx(rc32); move16(); + } + +/* Recompute LPC Coefficients up to n-1 */ + FOR (m = 1; m < n; m++) + { + lpc_tmp[m] = L_add(lpc[m], Mpy_32_32_lc3plus(rc32, lpc[n - m])); move32(); + } + + basop_memmove(&lpc[1], &lpc_tmp[1], (n - 1) * sizeof(Word32)); + + /* LPC Coefficient n */ + lpc[n] = L_shr_pos(rc32, 4); move32(); + } + + /* Final Prediction Error */ + IF (pred_err != NULL) + { + err = Mpy_32_32_lc3plus(err, L_sub(MAX_32, Mpy_32_32_lc3plus(rc32, rc32))); + *pred_err = L_shr(err, shift); + } + +#ifdef DYNMEM_COUNT + Dyn_Mem_Out(); +#endif +} + + +void lpc2rc(Word32 *lpc, Word16 *rc, Word16 N) +{ + Word32 lpc_tmp[MAXLAG + 1]; + Word32 rc32, tmp0, tmp1; + Word16 inv; + Counter n, m; + +#ifdef DYNMEM_COUNT + Dyn_Mem_In("lpc2rc", sizeof(struct { + Word32 lpc_tmp[MAXLAG + 1]; + Word32 rc32, tmp0, tmp1; + Word16 inv; + Counter n, m; + })); +#endif + + FOR (n = N; n >= 2; n--) + { + rc32 = L_shl_pos(lpc[n], 4); + rc[n - 1] = round_fx(rc32); move16(); + + tmp0 = L_sub(MAX_32, L_abs(Mpy_32_32_lc3plus(rc32, rc32))); + FOR (m = 1; m < n; m++) + { + tmp1 = L_sub(lpc[m], Mpy_32_32_lc3plus(lpc[n - m], rc32)); + inv = div_s(16383, extract_h(tmp0)); + lpc_tmp[m] = L_shl_pos(Mpy_32_32_lc3plus(tmp1, Mpy_32_16_lc3plus(L_sub(MAX_32, Mpy_32_16_lc3plus(tmp0, inv)), inv)), 2); move32(); + } + + basop_memmove(&lpc[1], &lpc_tmp[1], (n - 1) * sizeof(Word32)); + } + + rc[0] = round_fx(L_shl_pos(lpc[1], 4)); move32(); + +#ifdef DYNMEM_COUNT + Dyn_Mem_Out(); +#endif +} + diff --git a/lib_lc3plus/license.h b/lib_lc3plus/license.h new file mode 100644 index 0000000000000000000000000000000000000000..22f25e9ff204310778be60d2104265f807a7d216 --- /dev/null +++ b/lib_lc3plus/license.h @@ -0,0 +1,21 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.5 * +* 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 "defines.h" + +static const char *const LICENSE = + "*******************************************************************************\n" + "* ETSI TS 103 634 V1.4.5 *\n" + "* Low Complexity Communication Codec Plus (LC3plus) *\n" + "* Fixed Point Software V%i.%i.%iETSI, " __DATE__ " *\n" + "* Copyright licence is solely granted through ETSI Intellectual Property *\n" + "* Rights Policy, 3rd April 2019. No patent licence is granted by implication, *\n" + "* estoppel or otherwise. *\n" + "*******************************************************************************\n" + "\n"; diff --git a/lib_lc3plus/ltpf_coder_fx.c b/lib_lc3plus/ltpf_coder_fx.c new file mode 100644 index 0000000000000000000000000000000000000000..d17daa1b9f77cc2be61f3aae0c8fc5122e8efb8b --- /dev/null +++ b/lib_lc3plus/ltpf_coder_fx.c @@ -0,0 +1,323 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.5 * +* 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 "functions.h" + +/*************************************************************************/ + + +void process_ltpf_coder_fx(Word16 *bits, Word16 ol_pitch, Word16 ltpf_enable, Word16 *mem_in_exp, Word16 mem_in[], + Word16 mem_in_len, Word16 param[], Word16 *xin, Word16 len, Word16 *mem_normcorr, + Word16 *mem_mem_normcorr, Word16 ol_normcorr, Word16 *mem_ltpf_on, Word16 *mem_ltpf_pitch, + Word16 xin_exp, Word16 frame_dms, Word8 *scratchBuffer +#ifdef CR9_K_REDUCE_NORM_CORR_TH + ,Word16 hrmode +#endif +) +{ + Word16 pitch_index, scale0, scale1, scale2, *x, x_exp, shift, prod_exp, ltpf_pitch; + Word32 L_tmp, cor_max32, sum0, sum1, sum2, prod, inv; + Word32 *ac32; + Word16 *ac, *currFrame, *predFrame; + Word16 min_pitch, max_pitch, ac_min_pitch, ac_max_pitch, ac_max; + Word16 pitch, pitch_res, min_pitch_fr, pitch_int, pitch_fr, norm_corr, ltpf_active; + Counter n, m, fr; + Word16 tmp, acflen; + +#ifdef DYNMEM_COUNT + Dyn_Mem_In("process_ltpf_coder_fx", sizeof(struct { + Word16 pitch_index, scale0, scale1, scale2, *x, x_exp, shift, prod_exp, ltpf_pitch; + Word32 L_tmp, cor_max32, sum0, sum1, sum2, prod, inv; + Word32 *ac32; + Word16 *ac, *currFrame, *predFrame; + Word16 min_pitch, max_pitch, ac_min_pitch, ac_max_pitch, ac_max; + Word16 pitch, pitch_res, min_pitch_fr, pitch_int, pitch_fr, norm_corr, ltpf_active; + Counter n, m, fr; + Word16 tmp, acflen; + })); +#endif + + + + ac32 = (Word32 *)scratchAlign(scratchBuffer, 0); /* Size = 4 * 17 = 68 bytes; */ + ac = (Word16 *)scratchAlign(ac32, sizeof(*ac32) * 17); /* Size = 2 * 17 = 34 bytes */ + currFrame = (Word16 *)scratchAlign(scratchBuffer, 0); /* Size = 2 * 128 = 256 bytes */ + predFrame = (Word16 *)scratchAlign(currFrame, sizeof(*currFrame) * LEN_12K8); /* Size = 2 * 128 = 256 bytes */ + /* Buffers 'overlap' since they are not used at the same time */ /* Total size used = 512 bytes */ + + ltpf_active = 0; move16(); + norm_corr = 0; move16(); + + /* Input buffer */ + x = mem_in + mem_in_len; + + basop_memmove(x, xin, (len + 1) * sizeof(Word16)); + + ASSERT(mem_in_len + len + 1 <= LTPF_MEMIN_LEN + LEN_12K8 + 1); + + /* Scaling */ + scale0 = sub(getScaleFactor16_0(mem_in, mem_in_len), 3); + *mem_in_exp = sub(*mem_in_exp, scale0); move16(); + scale1 = sub(getScaleFactor16_0(x, len + 1), 3); + x_exp = sub(xin_exp, scale1); + scale2 = sub(*mem_in_exp, x_exp); + IF (scale2 > 0) + { + Scale_sig(x, len + 1, sub(scale1, scale2)); + Scale_sig(mem_in, mem_in_len, scale0); + x_exp = *mem_in_exp; move16(); + } + ELSE + { + Scale_sig(x, len + 1, scale1); + Scale_sig(mem_in, mem_in_len, add(scale0, scale2)); + *mem_in_exp = x_exp; move16(); + } + +#ifdef CR9_K_REDUCE_NORM_CORR_TH + Word32 normCorrTh = 0; + if (hrmode) { + normCorrTh = 13107; + } else { + normCorrTh = 19660; + } +#endif + +#ifdef CR9_K_REDUCE_NORM_CORR_TH + IF (sub(ol_normcorr, normCorrTh) > 0) +#else + IF (sub(ol_normcorr, 19660) > 0) +#endif + { + /* Autocorrelation Bounds */ + min_pitch = sub(ol_pitch, 4); + max_pitch = add(ol_pitch, 4); + min_pitch = s_max(min_pitch, MIN_PITCH_12K8); + max_pitch = s_min(max_pitch, MAX_PITCH_12K8); + ac_min_pitch = sub(min_pitch, 4); + ac_max_pitch = add(max_pitch, 4); + acflen = len; move16(); + if (sub(frame_dms, 25) == 0) + { + acflen = shl(len, 1); + x = x - len; + } + + /* Compute norm */ + sum1 = L_mac0(1, x[0], x[0]); + sum2 = L_mac0(1, x[-ac_min_pitch], x[-ac_min_pitch]); + FOR (m = 1; m < acflen; m++) + { + sum1 = L_mac0(sum1, x[m], x[m]); + sum2 = L_mac0(sum2, x[m - ac_min_pitch], x[m - ac_min_pitch]); + } + scale1 = norm_l(sum1); + sum1 = L_shl_pos(sum1, scale1); + + /* Compute Autocorrelation */ + FOR (n = ac_min_pitch; n <= ac_max_pitch; n++) + { + sum0 = L_mac0(0L, x[0], x[0 - n]); + FOR (m = 1; m < acflen; m++) + { + sum0 = L_mac0(sum0, x[m], x[m - n]); + } + if (n > ac_min_pitch) + { + sum2 = L_msu0(sum2, x[acflen - 1 - (n - 1)], x[acflen - 1 - (n - 1)]); + sum2 = L_mac0_sat(sum2, x[-n], x[-n]); + } + scale2 = norm_l(sum2); + L_tmp = L_shl_pos(sum2, scale2); + prod = Mpy_32_32_lc3plus(sum1, L_tmp); + shift = norm_l(prod); + prod = L_shl_pos(prod, shift); + prod_exp = sub(62, add(add(scale1, scale2), shift)); + inv = Isqrt_lc3plus(prod, &prod_exp); + scale0 = norm_l(sum0); + sum0 = L_shl_pos(sum0, scale0); + prod = Mpy_32_32_lc3plus(sum0, inv); + prod_exp = add(sub(31, scale0), prod_exp); + test(); + IF (prod == 0 || sub(norm_l(prod), prod_exp) >= 0) + { + ac[n - ac_min_pitch] = s_max(0, round_fx_sat(L_shl_sat(prod, prod_exp))); move16(); + } + ELSE + { + ac[n - ac_min_pitch] = 32767; move16(); + } + } + + /* Find maximum */ + ac_max = ac[min_pitch - ac_min_pitch]; move16(); + pitch = min_pitch; move16(); + FOR (n = min_pitch + 1; n <= max_pitch; n++) + { + tmp = sub_sat(ac[n - ac_min_pitch], ac_max); + if (tmp > 0) + { + pitch = n; move16(); + } + ac_max = s_max(ac_max, ac[n - ac_min_pitch]); + } + pitch_int = pitch; move16(); + pitch_fr = 0; move16(); + pitch_index = add(pitch_int, 283); + + /* If the pitch is low -> estimate a fractional part */ + IF (sub(pitch, RES2_PITCH_12K8) < 0) + { + IF (sub(pitch, RES4_PITCH_12K8) < 0) + { + pitch_res = 1; move16(); + min_pitch_fr = -3; move16(); + } + ELSE + { + pitch_res = 2; move16(); + min_pitch_fr = -2; move16(); + } + if (sub(pitch, min_pitch) == 0) + { + min_pitch_fr = 0; + } + cor_max32 = MIN_32; + FOR (fr = min_pitch_fr; fr < 4; fr += pitch_res) + { + sum0 = L_mult0(ac[pitch_int - ac_min_pitch - 4], ltpf_ac_interp_filt[fr + 3][0]); + sum0 = L_mac0(sum0, ac[pitch_int - ac_min_pitch - 3], ltpf_ac_interp_filt[fr + 3][1]); + sum0 = L_mac0(sum0, ac[pitch_int - ac_min_pitch - 2], ltpf_ac_interp_filt[fr + 3][2]); + sum0 = L_mac0(sum0, ac[pitch_int - ac_min_pitch - 1], ltpf_ac_interp_filt[fr + 3][3]); + sum0 = L_mac0(sum0, ac[pitch_int - ac_min_pitch + 0], ltpf_ac_interp_filt[fr + 3][4]); + sum0 = L_mac0(sum0, ac[pitch_int - ac_min_pitch + 1], ltpf_ac_interp_filt[fr + 3][5]); + sum0 = L_mac0(sum0, ac[pitch_int - ac_min_pitch + 2], ltpf_ac_interp_filt[fr + 3][6]); + sum0 = L_mac0(sum0, ac[pitch_int - ac_min_pitch + 3], ltpf_ac_interp_filt[fr + 3][7]); + sum0 = L_mac0(sum0, ac[pitch_int - ac_min_pitch + 4], ltpf_ac_interp_filt[fr + 3][8]); + + L_tmp = L_sub_sat(sum0, cor_max32); + if (L_tmp > 0) + { + pitch_fr = fr; move16(); + } + cor_max32 = L_max(cor_max32, sum0); + } + IF (pitch_fr < 0) + { + pitch_int = sub(pitch_int, 1); + pitch_fr = add(pitch_fr, 4); + } + IF (sub(pitch_int, 127) >= 0) + { + pitch_index = add(add(shl_pos(pitch_int, 1), shr_pos(pitch_fr, 1)), 126); + } + ELSE + { + pitch_index = sub(add(shl_pos(pitch_int, 2), pitch_fr), 128); + } + } + ltpf_pitch = add(shl_pos(pitch_int, 2), pitch_fr); + + /* Filter current and predicted frame */ + + FOR (n = 0; n < acflen; n++) + { + sum0 = L_mult(x[n + 1], inter_filter[0][0][0]); + sum0 = L_mac(sum0, x[n], inter_filter[0][0][1]); + currFrame[n] = mac_r(sum0, x[n - 1], inter_filter[0][0][2]); + + sum0 = L_mult(x[n - pitch_int + 1], inter_filter[0][pitch_fr][0]); + sum0 = L_mac(sum0, x[n - pitch_int], inter_filter[0][pitch_fr][1]); + sum0 = L_mac(sum0, x[n - pitch_int - 1], inter_filter[0][pitch_fr][2]); + predFrame[n] = mac_r(sum0, x[n - pitch_int - 2], inter_filter[0][pitch_fr][3]); + } + + /* Normalized Correlation */ + sum0 = L_mult0(currFrame[0], predFrame[0]); + sum1 = L_mac0(1, predFrame[0], predFrame[0]); + sum2 = L_mac0(1, currFrame[0], currFrame[0]); + for (m = 1; m < acflen; m++) + { + sum0 = L_mac0(sum0, currFrame[m], predFrame[m]); + sum1 = L_mac0(sum1, predFrame[m], predFrame[m]); + sum2 = L_mac0(sum2, currFrame[m], currFrame[m]); + } + + scale1 = norm_l(sum1); + scale2 = norm_l(sum2); + sum1 = L_shl_pos(sum1, scale1); + sum2 = L_shl_pos(sum2, scale2); + prod = Mpy_32_32_lc3plus(sum1, sum2); + shift = norm_l(prod); + prod = L_shl_pos(prod, shift); + prod_exp = sub(62, add(add(scale1, scale2), shift)); + inv = Isqrt_lc3plus(prod, &prod_exp); + scale0 = norm_l(sum0); + sum0 = L_shl_pos(sum0, scale0); + prod = Mpy_32_32_lc3plus(sum0, inv); + prod_exp = add(sub(31, scale0), prod_exp); + test(); + IF (prod == 0 || sub(norm_l(prod), prod_exp) >= 0) + { + norm_corr = s_max(0, round_fx_sat(L_shl_sat(prod, prod_exp))); move16(); + } + ELSE + { + norm_corr = 32767; move16(); + } + if (norm_corr < 0) + { + norm_corr = 0; + } + + IF (sub(ltpf_enable, 1) == 0) + { + test(); test(); test(); test(); + /* Decision if lptf active */ + IF ((*mem_ltpf_on == 0 && sub(*mem_normcorr, 30802) > 0 && sub(norm_corr, 30802) > 0 && + (sub(frame_dms, 100) == 0 || sub(*mem_mem_normcorr, 30802) > 0)) || + (sub(*mem_ltpf_on, 1) == 0 && sub(norm_corr, 29491) > 0) || + (sub(*mem_ltpf_on, 1) == 0 && sub(abs_s(sub(ltpf_pitch, *mem_ltpf_pitch)), 8) < 0 && + add(sub(norm_corr, *mem_normcorr), 3277) > 0 && sub(norm_corr, 27525) > 0)) + { + ltpf_active = 1; move16(); + } + } + + param[0] = 1; move16(); + param[1] = ltpf_active; move16(); + param[2] = pitch_index; move16(); + *bits = 11; move16(); + } + ELSE + { + norm_corr = ol_normcorr; move16(); + param[0] = 0; move16(); + param[1] = 0; move16(); + param[2] = 0; move16(); + *bits = 1; move16(); + ltpf_pitch = 0; move16(); + } + +/* Update memory */ + FOR (n = 0; n < mem_in_len; n++) + { + mem_in[n] = mem_in[n + len]; move16(); + } + + *mem_mem_normcorr = *mem_normcorr; move16(); + *mem_normcorr = norm_corr; move16(); + *mem_ltpf_on = ltpf_active; move16(); + *mem_ltpf_pitch = ltpf_pitch; move16(); + +#ifdef DYNMEM_COUNT + Dyn_Mem_Out(); +#endif +} + diff --git a/lib_lc3plus/ltpf_decoder_fx.c b/lib_lc3plus/ltpf_decoder_fx.c new file mode 100644 index 0000000000000000000000000000000000000000..3bc82085ef6436548bc71bc769c8da9748ad5eb5 --- /dev/null +++ b/lib_lc3plus/ltpf_decoder_fx.c @@ -0,0 +1,394 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.5 * +* 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 "functions.h" + +static void ltpf_synth_filter(Word16 *synth_ltp, Word16 *synth, Word16 length, Word16 pitch_int, Word16 pitch_fr, + Word16 gain, Word16 scale_fac_idx, Word16 fs_idx, + Word16 fade /* 0=normal, +1=fade-in, -1=fade-out */); + +/*************************************************************************/ + + +void process_ltpf_decoder_fx(Word16 *x_e, Word16 L_frame, Word16 old_x_len, Word16 fs_idx, Word16 old_y_len, + Word16 *old_e, Word16 *x_in, Word16 *old_x, Word16 *y_out, Word16 *old_y, Word16 ltpf, + Word16 ltpf_active, Word16 pitch_index, Word16 *old_pitch_int, Word16 *old_pitch_fr, + Word16 *old_gain, Word16 *mem_ltpf_active, Word16 scale_fac_idx, Word16 bfi, + Word16 concealMethod, + Word16 damping, Word16 *old_scale_fac_idx, +#ifdef CR9_N_SHORT_FADE_FOR_UNSTABLE_PITCH + Word32 *rel_pitch_change, Word16 hrmode, Word16 frame_dms, +#endif + Word8 *scratchBuffer) +{ + Counter i; + Word16 gain, s, s0, s1, pitch, pitch_int, pitch_fr, N4, N34; + Word16 *x, *y; + Word16 *z; +#ifdef CR9_N_SHORT_FADE_FOR_UNSTABLE_PITCH + Word32 tmp32, pitch_delta; +#endif +#ifdef DYNMEM_COUNT + Dyn_Mem_In("process_ltpf_decoder_fx", sizeof(struct { + Counter i; + Word16 gain, s, s0, s1, pitch, pitch_int, pitch_fr, N4, N34; + Word16 *x, *y; + Word16 *z; +#ifdef CR9_N_SHORT_FADE_FOR_UNSTABLE_PITCH + Word32 tmp32, pitch_delta; +#endif + })); +#endif + + z = (Word16 *)scratchAlign(scratchBuffer, 0); /* Size = MAX_LEN / 4 + 10 */ + + + test(); + IF ((sub(bfi, 1) == 0) && (sub(concealMethod, LC3_CON_TEC_NS_STD) == 0)) + { + ltpf = 0; move16(); + ltpf_active = 0; move16(); + pitch_int = 0; move16(); + pitch_fr = 0; move16(); + gain = 0; move16(); + } + + /* Filter parameters */ + IF (sub(bfi, 1) != 0) + { + IF (ltpf == 0) + { + pitch_int = 0; move16(); + pitch_fr = 0; move16(); + } + ELSE + { + /* Decode pitch */ + IF (sub(pitch_index, 380) < 0) + { + pitch_int = shr_pos(add(pitch_index, 64), 2); + pitch_fr = add(sub(pitch_index, shl_pos(pitch_int, 2)), 128); + } + ELSE IF (sub(pitch_index, 440) < 0) + { + pitch_int = shr_pos(sub(pitch_index, 126), 1); + pitch_fr = sub(sub(shl_pos(pitch_index, 1), shl_pos(pitch_int, 2)), 252); + } + ELSE + { + pitch_int = sub(pitch_index, 283); + pitch_fr = 0; move16(); + } + pitch = add(shl_pos(pitch_int, 2), pitch_fr); +#ifdef ENABLE_HR_MODE + IF (sub(fs_idx, 5) == 0) + { + pitch = round_fx(L_shl_pos(L_mult(shl_pos(pitch, 2), pitch_scale[4]), 1)); + } + ELSE +#endif + { + pitch = mult_r(shl_pos(pitch, 2), pitch_scale[fs_idx]); + } + pitch_int = shr_pos(pitch, 2); + pitch_fr = sub(pitch, shl_pos(pitch_int, 2)); + } + + /* Decode gain */ + if (scale_fac_idx < 0) + { + ltpf_active = 0; + ASSERT(!(*old_scale_fac_idx < 0 && *mem_ltpf_active == 1)); + } + IF (ltpf_active == 0) + { + gain = 0; move16(); + } + ELSE + { + ASSERT(scale_fac_idx >= 0); + gain = gain_scale_fac[scale_fac_idx]; move16(); + } + } + ELSE IF (sub(concealMethod, LC3_CON_TEC_NS_STD) != 0) + { + /* fix to avoid not initialized filtering for concelament + might be necessary in case of bit errors or rate switching */ + if (scale_fac_idx < 0) { + if (*mem_ltpf_active && *old_scale_fac_idx>=0) + { + scale_fac_idx = *old_scale_fac_idx; + } + } + + ltpf_active = *mem_ltpf_active; move16(); + + if ((sub(concealMethod, LC3_CON_TEC_PHASE_ECU) == 0)) + { /* always start fade off to save filtering WMOPS for the remaining 7.5 ms */ + assert(bfi == 1); + ltpf_active = 0; move16(); /*always start fade off , still maintain *mem_ltpf_active */ + } + + pitch_int = *old_pitch_int; + pitch_fr = *old_pitch_fr; + gain = mult_r(*old_gain, damping); + } + + test(); test(); + IF (ltpf_active == 0 && *mem_ltpf_active == 0) + { + /* LTPF inactive */ + + basop_memmove(y_out, x_in, L_frame * sizeof(Word16)); + + /* Update */ + s = sub(*old_e, *x_e); + IF (s > 0) + { + basop_memmove(old_y, &old_y[L_frame], (old_y_len - L_frame) * sizeof(Word16)); + + IF (sub(s, 15) > 0) + { + basop_memset(&old_y[old_y_len - L_frame], 0, (L_frame) * sizeof(Word16)); + + basop_memset(old_x, 0, (old_x_len) * sizeof(Word16)); + } + ELSE + { + FOR (i = 0; i < L_frame; i++) + { + old_y[i + old_y_len - L_frame] = shr(x_in[i], s); move16(); + } + FOR (i = 0; i < old_x_len; i++) + { + old_x[i] = shr(x_in[i + L_frame - old_x_len], s); move16(); + } + } + } + ELSE + { + IF (sub(s, -15) < 0) + { + basop_memset(old_y, 0, (old_y_len - L_frame) * sizeof(Word16)); + } + ELSE + { + FOR (i = 0; i < old_y_len - L_frame; i++) + { + old_y[i] = shl(old_y[i + L_frame], s); move16(); + } + } + + basop_memmove(&old_y[old_y_len - L_frame], x_in, (L_frame) * sizeof(Word16)); + + basop_memmove(old_x, &x_in[L_frame - old_x_len], (old_x_len) * sizeof(Word16)); + + *old_e = *x_e; move16(); + } + +#ifdef CR9_N_SHORT_FADE_FOR_UNSTABLE_PITCH + if (bfi == 0 && sub(hrmode,1) == 0 && (sub(frame_dms,50) == 0 || sub(frame_dms,25) == 0)){ + pitch_delta = abs_s(add(sub(*old_pitch_int,pitch_int) , shr_pos(sub(*old_pitch_fr, pitch_fr),2))); //int_old -int_new + (fr_old-fr_new) / 4.0)); + tmp32 = BASOP_Util_Divide3216_Scale_lc3plus(pitch_delta, MAX(add(*old_pitch_int, shr_pos(*old_pitch_fr,2)), 1),&s0);// = pitch_delta *2^15 / MAX(pitch_fl_c_old, 1); + *rel_pitch_change = L_shl_pos(tmp32,s0+16); + } +#endif + + *old_pitch_int = pitch_int; move16(); + *old_pitch_fr = pitch_fr; move16(); + *old_gain = 0; move16(); + *mem_ltpf_active = 0; move16(); + } + ELSE + { + /* Input/Output buffers */ + x = old_x + old_x_len; + y = old_y + old_y_len; + +#ifdef ENABLE_HR_MODE + assert(fs_idx < 5 && "Ltpf not supported for 96kHz!\n"); +#endif + + N4 = ltpf_overlap_len[fs_idx]; move16(); + N34 = sub(L_frame, N4); move16(); + + /* Input */ + basop_memmove(x, x_in, (L_frame) * sizeof(Word16)); + + /* Scaling */ + s0 = sub(s_min(getScaleFactor16_0(old_x, old_x_len), getScaleFactor16_0(old_y, old_y_len)), 1); + *old_e = sub(*old_e, s0); move16(); + s1 = sub(getScaleFactor16(x, L_frame), 1); + *x_e = sub(*x_e, s1); move16(); + s = sub(*old_e, *x_e); + IF (s > 0) + { + Scale_sig(x, L_frame, sub(s1, s)); + Scale_sig(old_x, old_x_len, s0); + Scale_sig(old_y, old_y_len, s0); + *x_e = *old_e; move16(); + } + ELSE + { + Scale_sig(x, L_frame, s1); + Scale_sig(old_x, old_x_len, add(s0, s)); + Scale_sig(old_y, old_y_len, add(s0, s)); + *old_e = *x_e; move16(); + } + + /* Filtering */ + IF (ltpf_active == 0) + { + ltpf_synth_filter(y, x, N4, *old_pitch_int, *old_pitch_fr, *old_gain, *old_scale_fac_idx, fs_idx, + -1); + } + ELSE IF (*mem_ltpf_active == 0) + { + ltpf_synth_filter(y, x, N4, pitch_int, pitch_fr, gain, scale_fac_idx, fs_idx, 1); + } + ELSE IF (sub(pitch_int, *old_pitch_int) == 0 && sub(*old_pitch_fr, pitch_fr) == 0) + { + ltpf_synth_filter(y, x, N4, pitch_int, pitch_fr, gain, scale_fac_idx, fs_idx, 0); + } + ELSE + { + ltpf_synth_filter(y, x, N4, *old_pitch_int, *old_pitch_fr, *old_gain, *old_scale_fac_idx, fs_idx, + -1); + basop_memmove(z, y - tilt_filter_len[fs_idx], (N4 + tilt_filter_len[fs_idx]) * sizeof(Word16)); + ltpf_synth_filter(y, z + tilt_filter_len[fs_idx], N4, pitch_int, pitch_fr, gain, scale_fac_idx, + fs_idx, 1); + } + IF (ltpf_active > 0) + { + ltpf_synth_filter(y + N4, x + N4, N34, pitch_int, pitch_fr, gain, + scale_fac_idx, fs_idx, 0); + } + ELSE + { + basop_memmove(&y[N4], &x[N4], N34 * sizeof(Word16)); + } + + /* Output */ + basop_memmove(y_out, y, (L_frame) * sizeof(Word16)); + + /* Update */ + basop_memmove(old_x, &old_x[L_frame], (old_x_len) * sizeof(Word16)); + + basop_memmove(old_y, &old_y[L_frame], (old_y_len) * sizeof(Word16)); + + *old_pitch_int = pitch_int; move16(); + *old_pitch_fr = pitch_fr; move16(); + *old_gain = gain; move16(); + *mem_ltpf_active = ltpf_active; move16(); + } + + *old_scale_fac_idx = scale_fac_idx; move16(); + +#ifdef DYNMEM_COUNT + Dyn_Mem_Out(); +#endif +} + + +static void ltpf_synth_filter(Word16 *synth_ltp, Word16 *synth, Word16 length, Word16 pitch_int, Word16 pitch_fr, + Word16 gain, Word16 scale_fac_idx, Word16 fs_idx, + Word16 fade /* 0=normal, +1=fade-in, -1=fade-out */) +{ + Word16 *x0; + Word16 *y0; + Word32 s; + Word16 alpha, step; + Word16 i, k; + Counter j, l; + +#ifdef DYNMEM_COUNT + Dyn_Mem_In("ltpf_synth_filter", sizeof(struct { + Word16 *x0; + Word16 *y0; + Word32 s; + Word16 alpha, step; + Word16 i, k; + Counter j, l; + })); +#endif + + ASSERT(scale_fac_idx >= 0); + + step = 0; /* initialize just to avoid compiler warning */ + alpha = 0; /* initialize just to avoid compiler warning */ + x0 = &synth_ltp[-pitch_int + inter_filter_shift[fs_idx]]; + y0 = synth; + + alpha = 0; move16(); + IF (fade != 0) + { + if (fade < 0) + { + alpha = 0x7FFF; move16(); + } + +/* step = 1.f/(float)(length); */ + if (sub(length, 20) == 0) + { + step = 1638 /*1.f/20.f Q15*/; move16(); + } + if (sub(length, 40) == 0) + { + step = 819 /*1.f/40.f Q15*/; move16(); + } + if (sub(length, 60) == 0) + { + step = 546 /*1.f/60.f Q15*/; move16(); + } + if (sub(length, 80) == 0) + { + step = 409 /*1.f/80.f Q15*/; move16(); + } + if (sub(length, 120) == 0) + { + step = 273 /*1.f/120.f Q15*/; move16(); + } + + if (fade < 0) + step = negate(step); + } + + FOR (j = 0; j < length; j++) + { + s = L_mult(x0[0], inter_filter[fs_idx][pitch_fr][0]); + FOR (l = 1; l < inter_filter_len[fs_idx]; l++) + { + s = L_mac(s, x0[-l], inter_filter[fs_idx][pitch_fr][l]); + } + FOR (l = 0; l < tilt_filter_len[fs_idx]; l++) + { + s = L_msu(s, y0[-l], tilt_filter[fs_idx][scale_fac_idx][l]); + } + + i = msu_r(s, y0[-l], tilt_filter[fs_idx][scale_fac_idx][l]); + + k = mult_r(gain, i); + + if (fade != 0) + k = mult_r(k, alpha); + + synth_ltp[j] = add(synth[j], k); move16(); + + if (fade != 0) + alpha = add(alpha, step); + + x0++; + y0++; + } + +#ifdef DYNMEM_COUNT + Dyn_Mem_Out(); +#endif +} + diff --git a/lib_lc3plus/makefile b/lib_lc3plus/makefile new file mode 100644 index 0000000000000000000000000000000000000000..d86232d67a1887e421f561810dab7e78d2436437 --- /dev/null +++ b/lib_lc3plus/makefile @@ -0,0 +1,180 @@ +#****************************************************************************** +# ETSI TS 103 634 V1.4.5 * +# 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. * +#*****************************************************************************/ + +# Options +AFL = 0 +GCOV = 0 +NO_POST_REL_CHANGES_TEST = 0 +OPTIM = 0 +SUBSET = ALL +WMOPS = 1 +HR = 1 +CLANG = 0 +SHORT_PLC_FADEOUT = 0 + +# Paths +VPATH = . basic_op +BUILD = build +CC = gcc +LINK = $(CC) + +# Binary Name +NAME_LC3 = LC3plus +# Shared Library Name +LIB_LC3 = libLC3plus.so + +# Default tool settings +RM = rm -f + +ifndef VERBOSE +QUIET_CC = @echo ' ' Compiling $<; +QUIET_LINK= @echo ' ' Linking $@; +QUIET = @ +endif + +# C compiler flags +# Preprocessor(-I/-D) / Compiler / Linker flags +CPPFLAGS += -Ibasic_op -DSUBSET_$(SUBSET) +CFLAGS += -std=c99 -fPIC \ + -pedantic -Wcast-qual -Wall -W -Wextra -Wno-long-long \ + -Wpointer-arith -Wstrict-prototypes -Wmissing-prototypes \ + -Werror-implicit-function-declaration + +ifneq "$(DEBUG)" "0" +CFLAGS += -g3 +LDFLAGS += -g3 +endif + +ifeq "$(HR)" "0" +CFLAGS += -DDISABLE_HR_MODE +endif + +ifeq "$(SHORT_PLC_FADEOUT)" "1" +CFLAGS += -DPLC_TUNING_SHORT_FADEOUT +endif + +# memory sanitizer, find use of uninitialized memory +ifeq "$(CLANG)" "1" + CC = clang + CFLAGS += -fsanitize=memory -fsanitize-memory-track-origins -fno-omit-frame-pointer + LDFLAGS += -fsanitize=memory -fsanitize-memory-track-origins -fno-omit-frame-pointer + OPTIM = 2 +endif + +# address sanitizer, find buffer overflows +ifeq "$(CLANG)" "2" + CC = clang + CFLAGS += -fsanitize=address -fno-omit-frame-pointer + LDFLAGS += -fsanitize=address -fno-omit-frame-pointer + OPTIM = 2 +endif + +# undefined behavior sanitizer, find bugs like integer overflows +ifeq "$(CLANG)" "3" + CC = clang + CFLAGS += -fsanitize=undefined + LDFLAGS += -fsanitize=undefined + OPTIM = 2 +endif + +LDFLAGS += -lm + +DEPFLAGS = -MT $@ -MMD -MP -MF $(BUILD)/$*.Td + +ifeq "$(GCOV)" "1" +CFLAGS += -fprofile-arcs -ftest-coverage +LDFLAGS += -fprofile-arcs -ftest-coverage +endif + +OPTIM ?= 0 +CFLAGS += -O$(OPTIM) + +CFLAGS += $(foreach DIR,$(SRC_DIRS),-I$(DIR)) + +ifeq "$(NO_POST_REL_CHANGES_TEST)" "1" +CFLAGS += -DNO_POST_REL_CHANGES +endif + +# disable wmops instrumentation +ifeq "$(WMOPS)" "0" + CPPFLAGS += -DWMOPS=0 -DDONT_COUNT_MEM +endif + +# dependency magic +CC_FLAGS = '$(CC) $(CFLAGS) $(CPPFLAGS) $(LDFLAGS)' +POSTCOMPILE = mv -f $(BUILD)/$*.Td $(BUILD)/$*.d && touch $@ + +############################################################################### + +SRCS := $(notdir $(foreach DIR, $(VPATH), $(wildcard $(DIR)/*.c))) + +EXCL := ccConvert.c +SRCS := $(notdir $(foreach DIR, $(VPATH), $(wildcard $(DIR)/*.c))) +SRCS := $(filter-out $(EXCL), $(SRCS)) + +EXCL_CCC := $(BUILD)/codec_exe.o +OBJS_CCC_UNF := $(addprefix $(BUILD)/, $(SRCS:.c=.o)) +OBJS_CCC := $(filter-out $(EXCL_CCC), $(OBJS_CCC_UNF)) + +OBJS := $(addprefix $(BUILD)/, $(SRCS:.c=.o)) + +LIBSRCS := $(filter-out $(DIR)/ccConvert.c $(DIR)/codec_exe.c, $(SRCS)) +LIBOBJS := $(addprefix $(BUILD)/, $(LIBSRCS:.c=.o)) + +############################################################################### + +.PHONY: all clean help force + +all: $(NAME_LC3) + +help: + @echo 'Targets:' + @echo ' $(NAME_LC3) (default)' + @echo ' $(LIB_LC3)' + @echo ' ccConvert' + @echo 'Syntax: make [OPTION=VALUE ...]' + @echo 'Build options:' + @echo ' NO_POST_REL_CHANGES_TEST $(NO_POST_REL_CHANGES_TEST) [0,1]' + @echo ' OPTIM $(OPTIM) [0-3]' + @echo ' SUBSET $(SUBSET) [NB,WB,SSWB,SWB,FB,UB,ALL]' + @echo ' WMOPS $(WMOPS) [0,1]' + @echo ' SHORT_PLC_FADEOUT $(SHORT_PLC_FADEOUT) [0,1]' + @echo 'Debug options:' + @echo ' AFL $(AFL) [0,1]' + @echo ' CLANG $(CLANG) [0-3]' + @echo ' GCOV $(GCOV) [0,1]' + +$(NAME_LC3): $(OBJS) + @echo 'Linking' $@ + $(QUIET) $(LINK) $(OBJS) -o $@ $(LDFLAGS) + +$(LIB_LC3): $(LIBOBJS) + @echo 'Linking' $@ + $(QUIET) $(LINK) --shared $(OBJS) -o $@ $(LDFLAGS) + +ccConvert: $(BUILD)/ccConvert.o $(OBJS_CCC) + @echo 'Linking' $@ + $(QUIET) $(LINK) $? -o $@ $(LDFLAGS) + +clean: + $(QUIET) rm -rf $(NAME_LC3) $(LIB_LC3) $(BUILD) ccConvert + +$(BUILD)/%.o : %.c $(BUILD)/cc_flags + @echo 'Compiling' $< + $(QUIET) $(CC) $(DEPFLAGS) $(CFLAGS) $(CPPFLAGS) -c -o $@ $< + $(QUIET) $(POSTCOMPILE) + +# force rebuild if compilation flags changed +$(BUILD)/cc_flags: force + $(QUIET) mkdir -p $(BUILD) + $(QUIET) echo $(CC_FLAGS) | cmp -s - $@ || echo $(CC_FLAGS) > $@ + +# force rebuild if include dependency changed +$(BUILD)/%.d: ; +include $(wildcard $(patsubst %, $(BUILD)/%.d, $(basename $(SRCS)))) diff --git a/lib_lc3plus/mdct_fx.c b/lib_lc3plus/mdct_fx.c new file mode 100644 index 0000000000000000000000000000000000000000..9e9157204f6addd73df699cc858668a778ef8e0f --- /dev/null +++ b/lib_lc3plus/mdct_fx.c @@ -0,0 +1,223 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.5 * +* 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 "functions.h" + +/* Union holding buffers to conserve stack memory. */ + +void processMdct_fx( +#ifdef ENABLE_HR_MODE + Word32 x[], /* i: time input signal */ +#else + Word16 x[], /* i: time input signal */ +#endif + Word16 x_exp, Word16 N, /* i: block size N */ +#ifdef CR8_F_ADAPT_MDCT_DCT_PRECISION +# ifdef ENABLE_HR_MODE + Word16 hrmode, /* i: indicate high precision */ +# endif +#endif +#ifdef ENABLE_HR_MODE + const Word32 w[], /* i: window coefficients including normalization of sqrt(2/N) and scaled by 2^4 */ +#else + const Word16 w[], /* i: window coefficients including normalization of sqrt(2/N) and scaled by 2^4 */ +#endif + Word16 wLen, /* i: window length */ +#ifdef ENABLE_HR_MODE + Word32 mem[], /* i/o: last block of input samples */ +#else + Word16 mem[], /* i/o: last block of input samples */ +#endif + Word16 memLen, /* i: length of last sample block */ + Word32 y[], /* o: spectral data */ + Word16 * y_e, /* o: spectal data exponent */ + Word8 * scratchBuffer) +{ + Counter i; + Word16 z, s, m; +#ifdef ENABLE_HR_MODE + Word32 *buf; +#else + Word16 *buf; +#endif + Word32 *workBuffer; + +#ifdef DYNMEM_COUNT + Dyn_Mem_In("processMdct_fx", sizeof(struct { + Counter i; + Word16 z, s, m; + Word16 *buf; + Word32 *workBuffer; + })); +#endif + + /* Buffers overlap since they are not used at the same time */ +#ifdef ENABLE_HR_MODE + buf = (Word32 *)scratchAlign(scratchBuffer, 0); /* Size = 2 * MAX_LEN */ +#else + buf = (Word16 *)scratchAlign(scratchBuffer, 0); /* Size = 2 * MAX_LEN */ +#endif + workBuffer = (Word32 *)scratchAlign(scratchBuffer, 0); /* Size = 4 * MAX_LEN */ + + /* Init (constant per sample rate) */ + z = (N << 1) - wLen; /* number of leading zeros in window */ + m = N >> 1; /* half block size */ + +#ifdef ENABLE_HR_MODE + basop_memmove(buf, mem, memLen * sizeof(Word32)); + + basop_memmove(&buf[memLen], x, (N - memLen) * sizeof(Word32)); + + basop_memmove(mem, &x[N - memLen], memLen * sizeof(Word32)); +#else + basop_memmove(buf, mem, memLen * sizeof(Word16)); + + basop_memmove(&buf[memLen], x, (N - memLen) * sizeof(Word16)); + + basop_memmove(mem, &x[N - memLen], memLen * sizeof(Word16)); +#endif + +#ifdef CR8_F_ADAPT_MDCT_DCT_PRECISION + +# ifdef ENABLE_HR_MODE + if (hrmode) + { + FOR (i = 0; i < m; i++) + { + y[m + i] = Msu_32_32_0(Mpy_32_32_0(w[i], buf[i]), w[2 * m - 1 - i], buf[2 * m - 1 - i]); move32(); + } + + FOR (i = 0; i < z; i++) + { + y[m - 1 - i] = Mpy_32_32_0(w[2 * m + i], x[2 * m - memLen + i]); move32(); + } + + FOR (i = i; i < m; i++) + { + y[m - 1 - i] = Mac_32_32_0(Mpy_32_32_0(w[2 * m + i], x[2 * m - memLen + i]), w[4 * m - 1 - i], x[4 * m - memLen - 1 - i]); move32(); + } + } else { +# ifdef CR9_B_FIX_MDCT_OVERFLOW + FOR (i = 0; i < m; i++) + { + y[m + i] = L_msu0(L_mult0(round_fx_sat(buf[i]), round_fx(w[i])), round_fx_sat(buf[2 * m - 1 - i]), round_fx(w[2 * m - 1 - i])); move32(); + } + + FOR (i = 0; i < z; i++) + { + y[m - 1 - i] = L_mult0(round_fx_sat(x[2 * m - memLen + i]), round_fx(w[2 * m + i])); move32(); + } + + FOR (i = i; i < m; i++) + { + y[m - 1 - i] = L_mac0(L_mult0(round_fx_sat(x[2 * m - memLen + i]), round_fx(w[2 * m + i])), round_fx_sat(x[4 * m - memLen - 1 - i]), + round_fx(w[4 * m - 1 - i])); move32(); + } +# else /* CR9_B_FIX_MDCT_OVERFLOW */ + FOR (i = 0; i < m; i++) + { + y[m + i] = L_msu0(L_mult0(round_fx(buf[i]), round_fx(w[i])), round_fx(buf[2 * m - 1 - i]), round_fx(w[2 * m - 1 - i])); move32(); + } + + FOR (i = 0; i < z; i++) + { + y[m - 1 - i] = L_mult0(round_fx(x[2 * m - memLen + i]), round_fx(w[2 * m + i])); move32(); + } + + FOR (i = i; i < m; i++) + { + y[m - 1 - i] = L_mac0(L_mult0(round_fx(x[2 * m - memLen + i]), round_fx(w[2 * m + i])), round_fx(x[4 * m - memLen - 1 - i]), + round_fx(w[4 * m - 1 - i])); move32(); + } +# endif /* CR9_B_FIX_MDCT_OVERFLOW */ + } +# else + /* regular resolution only */ + FOR (i = 0; i < m; i++) + { + y[m + i] = L_msu0(L_mult0(buf[i], w[i]), buf[2 * m - 1 - i], w[2 * m - 1 - i]); move32(); + } + + FOR (i = 0; i < z; i++) + { + y[m - 1 - i] = L_mult0(x[2 * m - memLen + i], w[2 * m + i]); move32(); + } + + FOR (i = i; i < m; i++) + { + y[m - 1 - i] = L_mac0(L_mult0(x[2 * m - memLen + i], w[2 * m + i]), x[4 * m - memLen - 1 - i], + w[4 * m - 1 - i]); move32(); + } +# endif + +#else /* CR8_F_ADAPT_MDCT_DCT_PRECISION */ + + FOR (i = 0; i < m; i++) + { +# ifdef ENABLE_HR_MODE + y[m + i] = Msu_32_32_0(Mpy_32_32_0(w[i], buf[i]), w[2 * m - 1 - i], buf[2 * m - 1 - i]); move32(); +# else + y[m + i] = L_msu0(L_mult0(buf[i], w[i]), buf[2 * m - 1 - i], w[2 * m - 1 - i]); move32(); +# endif + } + + FOR (i = 0; i < z; i++) + { +# ifdef ENABLE_HR_MODE + y[m - 1 - i] = Mpy_32_32_0(w[2 * m + i], x[2 * m - memLen + i]); move32(); +# else + y[m - 1 - i] = L_mult0(x[2 * m - memLen + i], w[2 * m + i]); move32(); +# endif + } + + FOR (i = i; i < m; i++) + { +# ifdef ENABLE_HR_MODE + y[m - 1 - i] = Mac_32_32_0(Mpy_32_32_0(w[2 * m + i], x[2 * m - memLen + i]), w[4 * m - 1 - i], x[4 * m - memLen - 1 - i]); move32(); +# else + y[m - 1 - i] = L_mac0(L_mult0(x[2 * m - memLen + i], w[2 * m + i]), x[4 * m - memLen - 1 - i], + w[4 * m - 1 - i]); move32(); +# endif + } + +#endif /* CR8_F_ADAPT_MDCT_DCT_PRECISION */ + + s = s_max(0, getScaleFactor32_lc3plus(y, N)); + FOR (i = 0; i < N; i++) + { + y[i] = L_shl(y[i], s); move32(); + } + + *y_e = sub(sub(x_exp, 2), s); + + /* N=20 only for 2.5ms possible */ + /* maybe implement this a pre init of shift */ + if (sub(N, 20) <= 0) + { + *y_e = add(*y_e, 2); + } + else if (sub(N, 120) <= 0) + { + *y_e = add(*y_e, 1); + } +#ifdef ENABLE_HR_MODE + dct_IV(y, y_e, N, +# ifdef CR8_F_ADAPT_MDCT_DCT_PRECISION + hrmode, +# endif + workBuffer); +#else + dct_IV(y, y_e, N, workBuffer); +#endif + +#ifdef DYNMEM_COUNT + Dyn_Mem_Out(); +#endif +} + diff --git a/lib_lc3plus/mdct_shaping_fx.c b/lib_lc3plus/mdct_shaping_fx.c new file mode 100644 index 0000000000000000000000000000000000000000..3b36265fd4132cf28c7967e31b63e30b188408dc --- /dev/null +++ b/lib_lc3plus/mdct_shaping_fx.c @@ -0,0 +1,74 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.5 * +* 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 "functions.h" + +void processMdctShaping_fx(Word32 x[], +#ifdef ENABLE_HR_MODE + Word32 scf[], +#else + Word16 scf[], +#endif + Word16 scf_exp[], const Word16 bands_offset[], Word16 fdns_npts) +{ + Counter i, j; + +#ifdef DYNMEM_COUNT + Dyn_Mem_In("processMdctShaping_fx", sizeof(struct { Counter i, j; })); +#endif + + j = 0; move16(); + FOR (i = 0; i < fdns_npts; i++) + { + FOR (; j < bands_offset[i + 1]; j++) + { +#ifdef ENABLE_HR_MODE + x[j] = L_shl(Mpy_32_32_lc3plus(x[j], scf[i]), scf_exp[i]); move32(); +#else + x[j] = L_shl(Mpy_32_16_lc3plus(x[j], scf[i]), scf_exp[i]); move32(); +#endif + } + } + +#ifdef DYNMEM_COUNT + Dyn_Mem_Out(); +#endif +} + + +void processScfScaling(Word16 scf_exp[], Word16 fdns_npts, Word16 *x_e) +{ + Counter i; + Word16 scf_exp_max; + +#ifdef DYNMEM_COUNT + Dyn_Mem_In("processLpcGainScaling", sizeof(struct { + Counter i; + Word16 scf_exp_max; + })); +#endif + + scf_exp_max = scf_exp[0]; move16(); + + FOR (i = 1; i < fdns_npts; i++) + { + scf_exp_max = s_max(scf_exp_max, scf_exp[i]); + } + + FOR (i = 0; i < fdns_npts; i++) + { + scf_exp[i] = sub(scf_exp[i], scf_exp_max); move16(); + } + + *x_e = add(*x_e, scf_exp_max); move16(); +#ifdef DYNMEM_COUNT + Dyn_Mem_Out(); +#endif +} + diff --git a/lib_lc3plus/near_nyquist_detector_fx.c b/lib_lc3plus/near_nyquist_detector_fx.c new file mode 100644 index 0000000000000000000000000000000000000000..8ae29cbb84a72388e35216449857c0f300bea57b --- /dev/null +++ b/lib_lc3plus/near_nyquist_detector_fx.c @@ -0,0 +1,141 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.5 * +* 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 "functions.h" + +void processNearNyquistdetector_fx(Word16 *near_nyquist_flag, const Word16 fs_idx, const Word16 near_nyquist_index, + const Word16 bands_number, const Word32 *ener_fx, const Word16 ener_fx_exp +#ifdef CR8_E_TONE_DETECTOR +#ifdef ENABLE_HR_MODE + ,Word16 frame_dms, Word16 hrmode) +#else + ) +#endif +#else + ) +#endif +{ + *near_nyquist_flag = 0; +#ifdef CR8_E_TONE_DETECTOR +#ifdef ENABLE_HR_MODE + IF (hrmode == 0){ +#endif +#endif + IF (sub(fs_idx, 4) < 0) + { + Dyn_Mem_Deluxe_In( + Word16 i; + Word16 nrg_above_thresh; + Word16 ener_low_exp; + Word16 ener_high_exp; + Word16 comp_energy_exp; + Word32 comp_energy; + Word32 ener_low; + Word32 ener_high; + ); + + ener_low = 0; move32(); + ener_low_exp = 0; move16(); + FOR (i = 0; i < near_nyquist_index; i++) + { + ener_low = BASOP_Util_Add_Mant32Exp_lc3plus(ener_fx[i], ener_fx_exp, ener_low, ener_low_exp, &ener_low_exp); + } + + ener_high = 0; move32(); + ener_high_exp = 0; move16(); + FOR (i = near_nyquist_index; i < bands_number; i++) + { + ener_high = BASOP_Util_Add_Mant32Exp_lc3plus(ener_fx[i], ener_fx_exp, ener_high, ener_high_exp, &ener_high_exp); + } + + comp_energy = Mpy_32_16_lc3plus(ener_low, NN_thresh); /* Mpy_32_16_lc3plus -> 32Q15 */ + comp_energy_exp = add(add(ener_low_exp, NN_thresh_exp),15); + + nrg_above_thresh = BASOP_Util_Cmp_Mant32Exp_lc3plus(ener_high, ener_high_exp, comp_energy, comp_energy_exp); /* 1 if firstNumber > secondNumber */ + + if (sub(nrg_above_thresh, 1) == 0) + { + *near_nyquist_flag = 1; + } + + Dyn_Mem_Deluxe_Out(); + } +#ifdef CR8_E_TONE_DETECTOR +#ifdef ENABLE_HR_MODE + } + ELSE // hrmode == 1 + { + // inverse spectral flatness = mean(energy) ./ 2^(mean(log2(energy))); + Word32 td_thresh; + + SWITCH (frame_dms) + { + case 25: + td_thresh = TD_HR_thresh_2_5ms; + BREAK; + case 50: + td_thresh = TD_HR_thresh_5ms; + BREAK; + #ifdef ENABLE_075_DMS_MODE + case 75: + td_thresh = TD_HR_thresh_7_5ms; + BREAK; + #endif + default: /* 100 */ + td_thresh = TD_HR_thresh_10ms; + BREAK; + } + + Word16 mean_ener_exp = 0; + + Word32 sum_ener = 0; move32(); + Word16 sum_ener_exp = 0; move16(); + FOR (Word16 i = 0; i < bands_number; i++) + { + sum_ener = BASOP_Util_Add_Mant32Exp_lc3plus(ener_fx[i], ener_fx_exp, sum_ener, sum_ener_exp, &sum_ener_exp); + } + + Word16 denom = sub(14,norm_s(bands_number)); + IF (sub(frame_dms, 50) == 0){ + denom = sub(15,norm_s(bands_number)); move16(); + } + + Word32 mean_ener = L_shr(sum_ener, denom); move32(); // = sum_ener / bands_number + mean_ener_exp = sum_ener_exp; move16(); + + Word32 sum_ener_log2 = 0;move32(); + Word16 sum_ener_log2_exp = 0;move16(); + Word32 mean_ener_log2 = 0;move32(); + + FOR (Word16 i = 0; i < bands_number; i++) + { + IF (ener_fx[i] != 0) { + Word32 log2Value = L_add(BASOP_Util_Log2_lc3plus(ener_fx[i]), L_shl_pos(L_deposit_l(ener_fx_exp), 25)); + /* input argument is in Q7.25 , returns pow(2,(x/64) + floatingpoint value log2_fl = log2Value/pow(2,31-6) */ + sum_ener_log2 = BASOP_Util_Add_Mant32Exp_lc3plus(log2Value, 6, sum_ener_log2, sum_ener_log2_exp, &sum_ener_log2_exp); move32(); + } + } + mean_ener_log2 = L_shr(sum_ener_log2, denom); move32(); //mean_ener_log2 = sum_ener_log2 / bands_number + Word16 mean_ener_log2_exp = sum_ener_log2_exp; + Word32 mean_ener_log2_fl = L_shr_pos(mean_ener_log2 ,s_min(31, sub(31,mean_ener_log2_exp))); //mean_ener_log2_fl = mean_ener_log2 / 2^(31-mean_ener_log2_exp) + Word32 inv_flatness = 0; + if (L_sub(norm_l(mean_ener),sub(sub(mean_ener_exp,31),mean_ener_log2_fl)) < 0 ) { + inv_flatness = maxWord32; + } + else { + inv_flatness = L_shl(mean_ener, s_max(-31,sub(sub(mean_ener_exp,31),mean_ener_log2_fl))); + } + IF (L_sub(inv_flatness, td_thresh) > 0) { + *near_nyquist_flag = 1; move16(); + } + } + #endif // ENABLE_HR_MODE +#endif // CR8_E_TONE_DETECTOR +} diff --git a/lib_lc3plus/noise_factor_fx.c b/lib_lc3plus/noise_factor_fx.c new file mode 100644 index 0000000000000000000000000000000000000000..75ffb5fac3294e2c1dfa5be1a19588f1ddf88c3b --- /dev/null +++ b/lib_lc3plus/noise_factor_fx.c @@ -0,0 +1,252 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.5 * +* 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 "functions.h" + + +void processNoiseFactor_fx(Word16 *fac_ns_idx, Word16 x_e, Word32 x[], +# ifdef ENABLE_HR_MODE + Word32 xq[], +# else + Word16 xq[], +# endif + Word16 gg, Word16 gg_e, Word16 BW_cutoff_idx, Word16 frame_dms, Word16 target_bytes, + Word8 *scratchBuffer +# ifdef ENABLE_HR_MODE + ,Word16 hrmode +# endif +) +{ + Dyn_Mem_Deluxe_In(Counter k; Word16 nzeros, s1, s2, s3, c, idx, fac_unq, *ind; + Word16 noisefillwidth, noisefillstart, N; Word32 Lsum;); + + + + ind = (Word16 *)scratchAlign(scratchBuffer, 0); /* Size = 2 * MAX_LEN bytes */ + + noisefillwidth = 0; + noisefillstart = 0; + c = 0; + move16(); + +#ifdef ENABLE_HR_MODE + if (hrmode) + { + N = BW_cutoff_bin_all_HR[BW_cutoff_idx]; + move16(); + } + else +#endif + { + N = BW_cutoff_bin_all[BW_cutoff_idx]; + move16(); + } + + SWITCH (frame_dms) + { + case 25: + N = shr_pos(N, 2); + noisefillwidth = NOISEFILLWIDTH_2_5MS; + noisefillstart = NOISEFILLSTART_2_5MS; + BREAK; + case 50: + N = shr_pos(N, 1); + noisefillwidth = NOISEFILLWIDTH_5MS; + noisefillstart = NOISEFILLSTART_5MS; + BREAK; +#ifdef CR8_G_ADD_75MS + case 75: + N = add(shr_pos(N, 2), add(shr_pos(N, 2), shr_pos(N, 2))); + noisefillwidth = NOISEFILLWIDTH_7_5MS; + noisefillstart = NOISEFILLSTART_7_5MS; + BREAK; +# endif + case 100: + noisefillwidth = NOISEFILLWIDTH; + noisefillstart = NOISEFILLSTART; + BREAK; + } + + nzeros = -2 * noisefillwidth - 1; + move16(); + + FOR (k = noisefillstart - noisefillwidth; k < noisefillstart + noisefillwidth; k++) + { + if (xq[k] != 0) + { + nzeros = -2 * noisefillwidth - 1; + move16(); + } + if (xq[k] == 0) + { + nzeros = add(nzeros, 1); + } + } + + FOR (k = noisefillstart; k < N - noisefillwidth; k++) + { + if (xq[k + noisefillwidth] != 0) + { + nzeros = -2 * noisefillwidth - 1; + move16(); + } + if (xq[k + noisefillwidth] == 0) + { + nzeros = add(nzeros, 1); + } + if (nzeros >= 0) + { + ind[c++] = k; + move16(); + } + } + + FOR (k = N - noisefillwidth; k < N; k++) + { + nzeros = add(nzeros, 1); + if (nzeros >= 0) + { + ind[c++] = k; + move16(); + } + } + + IF (c == 0) + { + fac_unq = 0; + move16(); + } + ELSE + { + + IF (target_bytes <= 20 && frame_dms == 100) + { + Word32 ind_sum; + Word16 mean_ind; + + Word16 fac_unq1, fac_unq2; + + /* calculate mean index */ + ind_sum = ind[0]; + move32(); + FOR (k = 1; k < c; k++) + { + ind_sum = L_add(ind_sum, ind[k]); + } + + mean_ind = BASOP_Util_Divide3216_Scale_lc3plus(ind_sum, c, &s2); + mean_ind = shl(mean_ind, s2 + 1); + + assert(0 <= mean_ind && mean_ind <= ind[c - 1]); + + /* calculate noise filling gain for low frequencies */ + s2 = 0; move16(); + if (sub(mean_ind, ind[0]) > 0) + { + /* calculate scale to ensure that Lsum does not overflow */ + s2 = s_max(sub(sub(14, norm_s(c)), getScaleFactor32_lc3plus(&x[ind[0]], sub(mean_ind, ind[0]))), 0); + } + Lsum = L_shr_pos_pos(L_abs(x[ind[0]]), s2); + + FOR (k = 1; k < c && ind[k] <= mean_ind; k++) + { + /* scale before adding to Lsum */ + Lsum = L_add(Lsum, L_shr_pos_pos(L_abs(x[ind[k]]), s2)); + } + fac_unq1 = BASOP_Util_Divide3216_Scale_lc3plus(Lsum, k, &s1); + /* add scale applied during summing */ + s1 = add(s1, s2); + fac_unq1 = BASOP_Util_Divide1616_Scale_lc3plus(fac_unq1, gg, &s2); + s3 = sub(15, add(x_e, add(s1, sub(s2, gg_e)))); + s2 = norm_s(fac_unq1); + test(); + IF (fac_unq1 != 0 && add(s3, s2) < 0) + { + fac_unq1 = MAX_16; + move16(); + } + ELSE + { + s3 = s_min(s_max(s3, -15), 15); + fac_unq1 = shr_r(fac_unq1, s3); + } + + /* calculate noise filling gain for high frequencies */ + Lsum = 0; + move16(); + idx = sub(c, k); + FOR (; k < c; k++) + { + Lsum = L_add(Lsum, L_abs(x[ind[k]])); + } + fac_unq2 = BASOP_Util_Divide3216_Scale_lc3plus(Lsum, idx, &s1); + fac_unq2 = BASOP_Util_Divide1616_Scale_lc3plus(fac_unq2, gg, &s2); + s3 = sub(15, add(x_e, add(s1, sub(s2, gg_e)))); + s2 = norm_s(fac_unq1); + test(); + IF (fac_unq2 != 0 && add(s3, s2) < 0) + { + fac_unq2 = MAX_16; + move16(); + } + ELSE + { + s3 = s_min(s_max(s3, -15), 15); + fac_unq2 = shr_r(fac_unq2, s3); + } + + /* calculate noise filling gain as minimum over high and low frequencies */ + fac_unq = s_min(fac_unq1, fac_unq2); + } + ELSE + { + /* calculate scale to ensure that Lsum does not overflow */ + s2 = s_max(sub(sub(14, norm_s(c)), getScaleFactor32_lc3plus(&x[ind[0]], sub(N,ind[0]))), 0); + Lsum = L_abs(x[ind[0]]); + FOR (k = 1; k < c; k++) + { + /* scale before adding to Lsum */ + Lsum = L_add(Lsum, L_shr_pos_pos(L_abs(x[ind[k]]), s2)); + } + fac_unq = BASOP_Util_Divide3216_Scale_lc3plus(Lsum, c, &s1); + /* add scale applied during summing */ + s1 = add(s1, s2); + fac_unq = BASOP_Util_Divide1616_Scale_lc3plus(fac_unq, gg, &s2); + s3 = sub(15, add(x_e, add(s1, sub(s2, gg_e)))); + s2 = norm_s(fac_unq); + test(); + IF (fac_unq != 0 && add(s3, s2) < 0) + { + fac_unq = MAX_16; + move16(); + } + ELSE + { + fac_unq = shr_r(fac_unq, s_max(s_min(s3, 15), -15)); + } + } + } + + idx = round_fx(L_sub(0x80000, L_mult(fac_unq, 16))); + if (sub(idx, 7) > 0) + { + idx = 7; + move16(); + } + if (idx < 0) + { + idx = 0; + move16(); + } + *fac_ns_idx = idx; + move16(); + + Dyn_Mem_Deluxe_Out(); +} + diff --git a/lib_lc3plus/noise_filling_fx.c b/lib_lc3plus/noise_filling_fx.c new file mode 100644 index 0000000000000000000000000000000000000000..9da870553279a9ce8ce82c47a53780270b7d3313 --- /dev/null +++ b/lib_lc3plus/noise_filling_fx.c @@ -0,0 +1,149 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.5 * +* 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 "functions.h" + +/*************************************************************************/ + + + +void processNoiseFilling_fx(Word32 xq[], Word16 nfseed, Word16 xq_e, Word16 fac_ns_idx, Word16 BW_cutoff_idx, + Word16 frame_dms, Word16 fac_ns_pc, Word16 spec_inv_idx, Word8 *scratchBuffer +#ifdef ENABLE_HR_MODE + , Word16 hrmode +#endif +) +{ + Dyn_Mem_Deluxe_In( + Counter k; + Word16 nzeros, fac_ns, *ind, c; + Word16 noisefillwidth, noisefillstart, N; + Word32 L_tmp, L_tmp_neg, L_tmp_pc, L_tmp_neg_pc; + ); + + ind = (Word16 *)scratchAlign(scratchBuffer, 0); /* Size = 2 * MAX_LEN bytes */ + + c = 0; move16(); + +#ifdef ENABLE_HR_MODE + if (hrmode == 1) + { + N = BW_cutoff_bin_all_HR[BW_cutoff_idx]; + move16(); + } + else +#endif + { + N = BW_cutoff_bin_all[BW_cutoff_idx]; + move16(); + } + + SWITCH (frame_dms) + { + case 25: + N = shr_pos(N, 2); + noisefillwidth = NOISEFILLWIDTH_2_5MS; + noisefillstart = NOISEFILLSTART_2_5MS; + BREAK; + case 50: + N = shr_pos(N, 1); + noisefillwidth = NOISEFILLWIDTH_5MS; + noisefillstart = NOISEFILLSTART_5MS; + BREAK; +#ifdef CR8_G_ADD_75MS + case 75: + N = add(shr_pos(N, 2), add(shr_pos(N, 2), shr_pos(N, 2))); + noisefillwidth = NOISEFILLWIDTH_7_5MS; + noisefillstart = NOISEFILLSTART_7_5MS; + BREAK; +#endif + default: /* 100 */ + noisefillwidth = NOISEFILLWIDTH; + noisefillstart = NOISEFILLSTART; + BREAK; + } + + nzeros = -2 * noisefillwidth - 1; move16(); + + FOR (k = noisefillstart - noisefillwidth; k < noisefillstart + noisefillwidth; k++) + { + if (xq[k] != 0) + { + nzeros = -2 * noisefillwidth - 1; move16(); + } + if (xq[k] == 0) + { + nzeros = add(nzeros, 1); + } + } + + FOR (k = noisefillstart; k < N - noisefillwidth; k++) + { + if (xq[k + noisefillwidth] != 0) + { + nzeros = -2 * noisefillwidth - 1; move16(); + } + if (xq[k + noisefillwidth] == 0) + { + nzeros = add(nzeros, 1); + } + if (nzeros >= 0) + { + ind[c++] = k; move16(); + } + } + + FOR (k = N - noisefillwidth; k < N; k++) + { + nzeros = add(nzeros, 1); + if (nzeros >= 0) + { + ind[c++] = k; move16(); + } + } + + IF (c > 0) + { + fac_ns = shl_pos(sub(8, fac_ns_idx), 11); + L_tmp = L_shr_sat(L_deposit_l(fac_ns), sub(xq_e, 16)); + L_tmp_neg = L_negate(L_tmp); + L_tmp_pc = L_shr_sat(L_deposit_l(fac_ns_pc), sub(xq_e, 16)); + L_tmp_neg_pc = L_negate(L_tmp_pc); + + FOR (k = 0; k < c; k++) + { + nfseed = extract_l(L_mac0(13849, nfseed, 31821)); + IF (nfseed >= 0) + { + IF (ind[k] < spec_inv_idx) + { + xq[ind[k]] = L_tmp; move32(); + } + ELSE + { + xq[ind[k]] = L_tmp_pc; move32(); + } + } + IF (nfseed < 0) + { + IF (ind[k] < spec_inv_idx) + { + xq[ind[k]] = L_tmp_neg; move32(); + } + ELSE + { + xq[ind[k]] = L_tmp_neg_pc; move32(); + } + } + } + } + + Dyn_Mem_Deluxe_Out(); +} + diff --git a/lib_lc3plus/olpa_fx.c b/lib_lc3plus/olpa_fx.c new file mode 100644 index 0000000000000000000000000000000000000000..a93a0ba250b8efc478e047c0384e3045c0f2594b --- /dev/null +++ b/lib_lc3plus/olpa_fx.c @@ -0,0 +1,289 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.5 * +* 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 "functions.h" + +/*************************************************************************/ + + +void process_olpa_fx(Word16 *mem_s6k4_exp, Word16 mem_s12k8[], Word16 mem_s6k4[], Word16 *pitch, Word16 *s12k8, + Word16 len, Word16 *normcorr, Word16 *mem_pitch, +#ifdef CR9_F_PITCH_WIN_LEN_FIX + Word16 *pitch_flag, +#endif + Word16 s12k8_exp, Word16 frame_dms, Word8 *scratchBuffer) +{ + Word32 sum, sum0, sum1, sum2, prod, inv; + Word16 shift, s6k4_exp, prod_exp, min_pitch, max_pitch; + Word16 scale0, scale1, scale2, pitch2, normcorr2, len2, acflen, mem_in_len; + Word32 max32; + Word32 *ac; + Word16 *s6k4; + Counter n; + + Counter m; + Word32 L_tmp, L_tmp2; + + +#ifdef DYNMEM_COUNT + Dyn_Mem_In("process_olpa_fx", sizeof(struct { + Word32 sum, sum0, sum1, sum2, prod, inv; + Word16 shift, s6k4_exp, prod_exp, min_pitch, max_pitch; + Word16 scale0, scale1, scale2, pitch2, normcorr2, len2, acflen, mem_in_len; + Word32 max32; + Word32 *ac; + Word16 *s6k4; + Counter n; + Word32 sums[3]; + Counter m; + Word32 L_tmp, L_tmp2; + })); +#endif + + /* Buffer alignment */ + ac = (Word32 *)scratchAlign(scratchBuffer, 0); /* Size = 4 * RANGE_PITCH_6K4 = 392 bytes */ + + /* Downsample input signal by a factor of 2 (12.8kHz -> 6.4kHz) */ + mem_in_len = MAX_PITCH_6K4; move16(); + len2 = shr(len, 1); + acflen = len2; move16(); + +#ifdef CR9_F_PITCH_WIN_LEN_FIX + SWITCH(frame_dms) + { + case 50: + mem_in_len = add(mem_in_len, 32); + acflen = add(acflen, 32); + break; + + case 25: + mem_in_len = add(mem_in_len, 48); + acflen = add(acflen, 48); + break; + } +#endif + +#ifndef CR9_F_PITCH_WIN_LEN_FIX + IF (sub(frame_dms, 25) == 0) + { + mem_in_len = add(mem_in_len, 16); + acflen = add(acflen, 16); + } +#endif + + s6k4 = mem_s6k4 + mem_in_len; + sum = L_mac(L_mac(L_mult(mem_s12k8[0], 4053), mem_s12k8[1], 7712), mem_s12k8[2], 9239); + *s6k4++ = round_fx(L_mac_sat(L_mac(sum, s12k8[0], 7712), s12k8[1], 4053)); move16(); + sum = L_mac(L_mac(L_mult(mem_s12k8[2], 4053), s12k8[0], 7712), s12k8[1], 9239); + *s6k4++ = round_fx(L_mac_sat(L_mac(sum, s12k8[2], 7712), s12k8[3], 4053)); move16(); + + FOR (n = 5; n < len; n += 2) + { + sum = L_mac(L_mac(L_mult(s12k8[n - 4], 4053), s12k8[n - 3], 7712), s12k8[n - 2], 9239); + *s6k4++ = round_fx_sat(L_mac_sat(L_mac(sum, s12k8[n - 1], 7712), s12k8[n], 4053)); move16(); + } + + mem_s12k8[0] = s12k8[len - 3]; move16(); + mem_s12k8[1] = s12k8[len - 2]; move16(); + mem_s12k8[2] = s12k8[len - 1]; move16(); + + /* Scale downsampled signal */ + s6k4 = mem_s6k4 + mem_in_len; + scale0 = sub(getScaleFactor16_0(mem_s6k4, mem_in_len), 3); + *mem_s6k4_exp = sub(*mem_s6k4_exp, scale0); move16(); + scale1 = sub(getScaleFactor16_0(s6k4, len2), 3); + s6k4_exp = sub(s12k8_exp, scale1); + scale2 = sub(*mem_s6k4_exp, s6k4_exp); + IF (scale2 > 0) + { + Scale_sig(s6k4, len2, sub(scale1, scale2)); + shift = scale0; move16(); + s6k4_exp = *mem_s6k4_exp; move16(); + } + ELSE + { + Scale_sig(s6k4, len2, scale1); + shift = add(scale0, scale2); + *mem_s6k4_exp = s6k4_exp; move16(); + } +#ifdef CR9_F_PITCH_WIN_LEN_FIX + SWITCH(frame_dms) + { + case 50: + s6k4 = s6k4 - 32; + break; + + case 25: + s6k4 = s6k4 - 48; + break; + } +#endif + +#ifndef CR9_F_PITCH_WIN_LEN_FIX + if (sub(frame_dms, 25) == 0) + { + s6k4 = s6k4 - 16; + } +#endif + Scale_sig(mem_s6k4, mem_in_len, shift); + + /* Compute autocorrelation */ + FOR (n = MIN_PITCH_6K4; n <= MAX_PITCH_6K4; n++) + { + sum = L_mult0(s6k4[0], s6k4[0 - n]); + FOR (m = 1; m < acflen; m++) + { + sum = L_mac0(sum, s6k4[m], s6k4[m - n]); + } + ac[n - MIN_PITCH_6K4] = sum; move32(); + } + + /* Weight autocorrelation and find maximum */ + max32 = Mpy_32_16_lc3plus(ac[0], olpa_ac_weighting[0]); move32(); + *pitch = MIN_PITCH_6K4; move16(); + FOR (n = MIN_PITCH_6K4 + 1; n <= MAX_PITCH_6K4; n++) + { + L_tmp = Mpy_32_16_lc3plus(ac[n - MIN_PITCH_6K4], olpa_ac_weighting[n - MIN_PITCH_6K4]); + L_tmp2 = L_sub_sat(L_tmp, max32); + if (L_tmp2 > 0) + { + *pitch = n; move16(); + } + max32 = L_max(L_tmp, max32); + } + + /* Compute normalized correlation */ + sum0 = L_mult0(s6k4[0], s6k4[0 - *pitch]); + sum1 = L_mac0(1, s6k4[0 - *pitch], s6k4[0 - *pitch]); + sum2 = L_mac0(1, s6k4[0], s6k4[0]); + for (m = 1; m < acflen; m++) + { + sum0 = L_mac0(sum0, s6k4[m], s6k4[m - *pitch]); + sum1 = L_mac0(sum1, s6k4[m - *pitch], s6k4[m - *pitch]); + sum2 = L_mac0(sum2, s6k4[m], s6k4[m]); + } + scale1 = norm_l(sum1); + scale2 = norm_l(sum2); + sum1 = L_shl_pos(sum1, scale1); + sum2 = L_shl_pos(sum2, scale2); + prod = Mpy_32_32_lc3plus(sum1, sum2); + shift = norm_l(prod); + prod = L_shl_pos(prod, shift); + prod_exp = sub(62, add(add(scale1, scale2), shift)); + inv = Isqrt_lc3plus(prod, &prod_exp); + scale0 = norm_l(sum0); + sum0 = L_shl_pos(sum0, scale0); + prod = Mpy_32_32_lc3plus(sum0, inv); + prod_exp = add(sub(31, scale0), prod_exp); + test(); + IF (prod == 0 || sub(norm_l(prod), prod_exp) >= 0) + { + *normcorr = s_max(0, round_fx_sat(L_shl_sat(prod, prod_exp))); move16(); + } + ELSE + { + *normcorr = 32767; move16(); + } + + /* Second try in the neighborhood of the previous pitch */ + min_pitch = s_max(MIN_PITCH_6K4, sub(*mem_pitch, 4)); + max_pitch = s_min(MAX_PITCH_6K4, add(*mem_pitch, 4)); + + max32 = ac[min_pitch - MIN_PITCH_6K4]; move32(); + pitch2 = min_pitch; move16(); + FOR (n = min_pitch + 1; n <= max_pitch; n++) + { + L_tmp = L_sub_sat(ac[n - MIN_PITCH_6K4], max32); + if (L_tmp > 0) + { + pitch2 = n; move16(); + } + max32 = L_max(ac[n - MIN_PITCH_6K4], max32); + } + IF (sub(*pitch, pitch2) != 0) + { + sum0 = L_mult0(s6k4[0], s6k4[0 - pitch2]); + sum1 = L_mac0(1, s6k4[0 - pitch2], s6k4[0 - pitch2]); + sum2 = L_mac0(1, s6k4[0], s6k4[0]); + for (m = 1; m < acflen; m++) + { + sum0 = L_mac0(sum0, s6k4[m], s6k4[m - pitch2]); + sum1 = L_mac0(sum1, s6k4[m - pitch2], s6k4[m - pitch2]); + sum2 = L_mac0(sum2, s6k4[m], s6k4[m]); + } + scale1 = norm_l(sum1); + scale2 = norm_l(sum2); + sum1 = L_shl_pos(sum1, scale1); + sum2 = L_shl_pos(sum2, scale2); + prod = Mpy_32_32_lc3plus(sum1, sum2); + shift = norm_l(prod); + prod = L_shl_pos(prod, shift); + prod_exp = sub(62, add(add(scale1, scale2), shift)); + inv = Isqrt_lc3plus(prod, &prod_exp); + scale0 = norm_l(sum0); + sum0 = L_shl_pos(sum0, scale0); + prod = Mpy_32_32_lc3plus(sum0, inv); + prod_exp = add(sub(31, scale0), prod_exp); + test(); + IF (prod == 0 || sub(norm_l(prod), prod_exp) >= 0) + { + normcorr2 = s_max(0, round_fx_sat(L_shl_sat(prod, prod_exp))); move16(); + } + ELSE + { + normcorr2 = 32767; move16(); + } + IF (sub(normcorr2, mult_r(*normcorr, 27853)) > 0) + { + *pitch = pitch2; move16(); + *normcorr = normcorr2; move16(); + } + } + +#ifdef CR9_F_PITCH_WIN_LEN_FIX + SWITCH(frame_dms) + { + case 50: + if(*pitch_flag == 1) { + *mem_pitch = *pitch; move16(); + *pitch_flag = 0; + } + else { + *pitch_flag += 1; + } + break; + + case 25: + if (*pitch_flag == 3) { + *mem_pitch = *pitch; move16(); + *pitch_flag = 0; + } + else { + *pitch_flag += 1; + } + break; + + default: +#endif + *mem_pitch = *pitch; move16(); +#ifdef CR9_F_PITCH_WIN_LEN_FIX + } +#endif + + /* Update memory */ + basop_memmove(mem_s6k4, &mem_s6k4[len2], mem_in_len * sizeof(Word16)); + + /* Upsample pitch by a factor of 2 (6.4kHz -> 12.8kHz) */ + *pitch = shl_pos(*pitch, 1); move16(); + +#ifdef DYNMEM_COUNT + Dyn_Mem_Out(); +#endif +} + diff --git a/lib_lc3plus/pc_apply_fx.c b/lib_lc3plus/pc_apply_fx.c new file mode 100644 index 0000000000000000000000000000000000000000..42ddfb243fb0daf5b2c77abe83915e92ae220af4 --- /dev/null +++ b/lib_lc3plus/pc_apply_fx.c @@ -0,0 +1,315 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.5 * +* 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 "defines.h" +#include "constants.h" +#include "functions.h" + +#ifdef ENABLE_HR_MODE +static Word16 getScaleFactor32_withNegativeScaling(Word32 *data32, Word16 dataLen); +#else +static Word16 getScaleFactor16_withNegativeScaling(Word16 *data16, Word16 dataLen); +#endif + + +void processPCapply_fx(Word16 yLen, Word16 q_old_res_fx[], Word16 *q_old_res_fx_exp, +#ifdef ENABLE_HR_MODE + Word32 q_res_fx[], +#else + Word16 q_res_fx[], +#endif + Word16 q_old_d_fx[], Word16 spec_inv_idx, Word16 *fac, Word16 *fac_e, Word32 q_d_fx[], + Word16 *q_fx_exp, Word16 gg_idx, Word16 gg_idx_off, Word16 prev_gg, Word16 prev_gg_e, + Word16 *pc_nbLostFramesInRow) +{ + Counter i; + Word16 s, s2, s3, c, tmp16, tmp16_2, inv_gain, thr; + Word32 ener_curr, ener_prev, mean_nrg_high, mean_nrg_low; + Word16 global_gain, global_gain_e, gg2, gg2_e, prev_gg2, prev_gg2_e; + Word32 tmp32, ener_curr_gg2, ener_prev_gg2; + Word16 fac_local, fac_local_e; + +#ifdef DYNMEM_COUNT + struct _dynmem + { + Counter i; + Word16 s, s2, s3, c, tmp16, tmp16_2, inv_gain, thr; + Word32 ener_curr, ener_prev, mean_nrg_high, mean_nrg_low; + Word16 global_gain, global_gain_e, gg2, gg2_e, prev_gg2, prev_gg2_e; + Word32 tmp32, ener_curr_gg2, ener_prev_gg2; + Word16 fac_local, fac_local_e; + }; + Dyn_Mem_In("processPCapply_fx", sizeof(struct _dynmem)); +#endif + + assert(spec_inv_idx >= 0); + + *pc_nbLostFramesInRow = add(*pc_nbLostFramesInRow, 1); + + tmp32 = L_shl_pos(L_mult0(add(gg_idx, gg_idx_off), 0x797D), 7); + global_gain_e = add(extract_l(L_shr_pos(tmp32, 25)), 1); + global_gain = round_fx(BASOP_Util_InvLog2_lc3plus(L_or(tmp32, 0xFE000000))); + + /** Calculate rescaling factor **/ + + /* mean_nrg_low = mean(q_d_prev(1:spec_inv_idx-1).^2); + mean_nrg_high = mean(q_d_prev(spec_inv_idx:end).^2); */ + s = getScaleFactor16(q_old_d_fx, yLen); + + mean_nrg_low = 0; + move32(); + FOR (i = 0; i < spec_inv_idx; i++) + { + tmp16 = shl_sat(q_old_d_fx[i], sub(s, 4)); + mean_nrg_low = L_mac0(mean_nrg_low, tmp16, tmp16); /* exp = 2s - 8 */ + } + + mean_nrg_high = 0; + move32(); + FOR (i = spec_inv_idx; i < yLen; i++) + { + tmp16 = shl_sat(q_old_d_fx[i], sub(s, 4)); + mean_nrg_high = L_mac0(mean_nrg_high, tmp16, tmp16); /* exp = 2s - 8 */ + } + + IF (sub(spec_inv_idx, sub(yLen, spec_inv_idx)) < 0) + { + c = div_s(spec_inv_idx, sub(yLen, spec_inv_idx)); + mean_nrg_high = Mpy_32_16_lc3plus(mean_nrg_high, c); /* exp = 2s - 8 */ + } + ELSE + { + c = div_s(sub(yLen, spec_inv_idx), spec_inv_idx); + mean_nrg_low = Mpy_32_16_lc3plus(mean_nrg_low, c); /* exp = 2s - 8 */ + } + + /* ener_prev = sum(q_old_res(1:spec_inv_idx-1).^2); + ener_curr = sum( q_res(1:spec_inv_idx-1).^2); */ + s = getScaleFactor16(q_old_res_fx, spec_inv_idx); + ener_prev = 0; move32(); + FOR (i = 0; i < spec_inv_idx; i++) + { + tmp16 = shl_sat(q_old_res_fx[i], sub(s, 4)); + ener_prev = L_mac0(ener_prev, tmp16, tmp16); /* exp = - (2s - 8 - 2**q_old_res_fx_exp) */ + } + + ener_curr = 0; + move32(); + +#ifdef ENABLE_HR_MODE + s2 = getScaleFactor32_lc3plus(q_res_fx, spec_inv_idx); + FOR (i = 0; i < spec_inv_idx; i++) + { + tmp16 = extract_h(L_shl_sat(q_res_fx[i], sub(s2, 4))); + ener_curr = L_mac0(ener_curr, tmp16, tmp16); /* exp = - (2s2 - 8) */ + } + s2 = s2 - 16; +#else + s2 = getScaleFactor16(q_res_fx, spec_inv_idx); + FOR (i = 0; i < spec_inv_idx; i++) + { + tmp16 = shl_sat(q_res_fx[i], sub(s2, 4)); + ener_curr = L_mac0(ener_curr, tmp16, tmp16); /* exp = - (2s2 - 8) */ + } +#endif + + + s = shl(sub(s, *q_old_res_fx_exp), 1); + s2 = shl(s2, 1); + s3 = s_max(s, s2); + ener_prev = L_shr_sat(ener_prev, sub(s3, s2)); + ener_curr = L_shr_sat(ener_curr, sub(s3, s)); + + /* fac = 1; */ + *fac = 1; + /* if ener_prev > 0 */ + IF ( ener_prev > 0 ) + { + /* fac = sqrt(ener_curr/ener_prev); */ + s = getScaleFactor32_lc3plus(&ener_prev, 1); + s2 = getScaleFactor32_lc3plus(&ener_curr, 1); + s3 = s_min(s, s2); + tmp16 = extract_h(L_shl_sat(ener_curr, s3)); + tmp16_2 = extract_h(L_shl_sat(ener_prev, s3)); + + *fac_e = 0; move16(); + if ( tmp16_2 == 0) { + tmp16_2 = 32767; move16(); + *fac_e = 15; move16(); + } else { + tmp16_2 = Inv16_lc3plus(tmp16_2, fac_e); + } + + *fac = mult(tmp16, tmp16_2); + + IF (sub(*fac, 32767) < 0) + { + *fac = Sqrt16_lc3plus(*fac, fac_e); move16(); + } + } + + /* fac_local = fac; */ + fac_local = *fac; + fac_local_e = *fac_e; + + /* if (mean_nrg_low > mean_nrg_high) && (ener_prev * prev_gg^2 > ener_curr * gg^2) */ + prev_gg2 = mult(prev_gg, prev_gg); + prev_gg2_e = shl(prev_gg_e, 1); + ener_prev_gg2 = Mpy_32_16_lc3plus(ener_prev, prev_gg2); /* exp = prev_gg2_e */ + + gg2 = mult(global_gain, global_gain); + gg2_e = shl(global_gain_e, 1); + ener_curr_gg2 = Mpy_32_16_lc3plus(ener_curr, gg2); /* exp = gg2_e */ + + s3 = s_max(prev_gg2_e, gg2_e); + ener_prev_gg2 = L_shr_sat(ener_prev_gg2, sub(s3, prev_gg2_e)); + ener_curr_gg2 = L_shr_sat(ener_curr_gg2, sub(s3, gg2_e)); + + + test(); + IF ( (L_sub(mean_nrg_low, mean_nrg_high) <= 0) || (L_sub(ener_prev_gg2, ener_curr_gg2) <= 0) ) + { + /* fac = prev_gg/gg; */ + s = global_gain_e; move16(); + inv_gain = Inv16_lc3plus(global_gain, &s); + fac_local = mult(prev_gg, inv_gain); + fac_local_e = add(s, prev_gg_e); + } + + /* write synthesized samples */ + *q_old_res_fx_exp = add(*q_old_res_fx_exp, fac_local_e); + thr = shl_sat(20480, sub(-15, *q_old_res_fx_exp)); + FOR (i = spec_inv_idx; i < yLen; i++) + { + q_res_fx[i] = extract_h(L_mult(q_old_res_fx[i] /* exp = q_old_res_fx_exp' */, fac_local /* exp = fac_e */)); /* exp = q_old_res_fx_exp */ + + IF (sub(abs_s(q_res_fx[i]), thr) < 0) + { + q_res_fx[i] = 0; + move16(); + } + } + +#ifdef ENABLE_HR_MODE + s = getScaleFactor32_withNegativeScaling(&q_res_fx[0], spec_inv_idx) - 16; /* exp = 0 */ + s2 = getScaleFactor32_withNegativeScaling(&q_res_fx[spec_inv_idx], + sub(yLen, spec_inv_idx)) - 16; /* exp = q_old_res_fx_exp */ +#else + s = getScaleFactor16_withNegativeScaling(&q_res_fx[0], spec_inv_idx); /* exp = 0 */ + s2 = getScaleFactor16_withNegativeScaling(&q_res_fx[spec_inv_idx], + sub(yLen, spec_inv_idx)); /* exp = q_old_res_fx_exp */ +#endif + + s3 = add(s, *q_old_res_fx_exp); + IF (sub(s3, s2) > 0) + { + tmp16 = sub(s3, s2); + s = sub(s, tmp16); + s3 = sub(s3, tmp16); + } + *q_fx_exp = sub(15, s); + move16(); + +#ifdef ENABLE_HR_MODE + s = add(s, 16); + s3 = add(s3, 16); +#endif + + s = s_max(s, -31); + s = s_min(s, 31); + s3 = s_max(s3, -31); + s3 = s_min(s3, 31); + + FOR (i = 0; i < spec_inv_idx; i++) + { +#ifdef ENABLE_HR_MODE + q_d_fx[i] = L_shl(q_res_fx[i], s); +#else + q_d_fx[i] = L_shl(L_deposit_h(q_res_fx[i]), s); +#endif + move32(); + } + FOR (; i < yLen; i++) + { +#ifdef ENABLE_HR_MODE + q_d_fx[i] = L_shl(q_res_fx[i], s3); +#else + q_d_fx[i] = L_shl(L_deposit_h(q_res_fx[i]), s3); +#endif + move32(); + } + + +#ifdef DYNMEM_COUNT + Dyn_Mem_Out(); +#endif +} + +#ifndef ENABLE_HR_MODE +static Word16 getScaleFactor16_withNegativeScaling(Word16 *data16, Word16 dataLen) +{ + Counter i; + Dyn_Mem_Deluxe_In(Word16 tmp, shift; Word16 x_min, x_max;); + + x_max = 0; + move16(); + x_min = 0; + move16(); + + FOR (i = 0; i < dataLen; i++) + { + if (data16[i] > 0) + x_max = s_max(x_max, data16[i]); + if (data16[i] < 0) + x_min = s_min(x_min, data16[i]); + } + + tmp = s_max(x_max, negate(x_min)); + shift = norm_s(tmp); + if (tmp == 0) + { + shift = 15; + move16(); + } + + Dyn_Mem_Deluxe_Out(); + + return shift; +} + +#else +static Word16 getScaleFactor32_withNegativeScaling(Word32 *data32, Word16 dataLen) +{ + Counter i; + Dyn_Mem_Deluxe_In(Word32 tmp, shift; Word32 x_min, x_max;); + + x_max = L_add(0, 0); + x_min = L_add(0, 0); + + FOR (i = 0; i < dataLen; i++) + { + if (data32[i] >= 0) + x_max = L_max(x_max, data32[i]); + if (data32[i] < 0) + x_min = L_min(x_min, data32[i]); + } + + tmp = L_max(x_max, L_negate(x_min)); + shift = norm_l(tmp); + if (tmp == 0) + { + shift = 31; + move16(); + } + + Dyn_Mem_Deluxe_Out(); + + return shift; +} +#endif diff --git a/lib_lc3plus/pc_classify_fx.c b/lib_lc3plus/pc_classify_fx.c new file mode 100644 index 0000000000000000000000000000000000000000..28898f9638abe71bd6e23814681d0a8364654218 --- /dev/null +++ b/lib_lc3plus/pc_classify_fx.c @@ -0,0 +1,260 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.5 * +* 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 "defines.h" +#include "constants.h" +#include "functions.h" + +#define BLOCK_SIZE 3 +#define THR1 8 +#define FAC 9830 /* 0.3 */ + +void peakDetector_fx(Word16 in_sig[], Word16 yLen, Word16 *xover); + +void processPCclassify_fx(Word16 pitch_present, Word16 frame_dms, Word16 q_old_d_fx[], Word16 q_old_res_fx[], + Word16 yLen, Word16 spec_inv_idx, Word16 stab_fac, Word16 *bfi) +{ + Dyn_Mem_Deluxe_In( + Word16 maxPitchBin, xover; + Counter i; + Word16 s, tmp16, full_nrg16, part_nrg16; + Word32 full_nrg, part_nrg; + ); + + /* Apply classifier only if lower than 2kHz signal */ + IF (sub(DEPR_i_mult(spec_inv_idx, 10), shl_pos(frame_dms, 2)) < 0 ) + { + IF (sub(stab_fac, 16384 /* 0.5 */) < 0) + { + *bfi = 1; + } + ELSE IF (sub(pitch_present, 1) == 0) + { + maxPitchBin = 8; move16(); + IF (sub(frame_dms, 50) == 0) + { + maxPitchBin = 4; move16(); + } + + /* avoid phase discontinuity in low frequencies */ + peakDetector_fx(q_old_d_fx, yLen, &xover); + test(); + IF (sub(spec_inv_idx, xover) < 0 || sub(spec_inv_idx, maxPitchBin) < 0) + { + *bfi = 1; + } + } + ELSE + { + s = getScaleFactor16(q_old_res_fx, yLen); + + part_nrg = 0; move32(); + FOR (i = 0; i < spec_inv_idx; i++) + { + tmp16 = shl_sat(q_old_res_fx[i], sub(s, 4)); + part_nrg = L_mac0(part_nrg, tmp16, tmp16); /* exp = 2s - 8 */ + } + + full_nrg = part_nrg; move32(); + FOR (i = spec_inv_idx; i < yLen; i++) + { + tmp16 = shl_sat(q_old_res_fx[i], sub(s, 4)); + full_nrg = L_mac0(full_nrg, tmp16, tmp16); /* exp = 2s - 8 */ + } + + s = getScaleFactor32_lc3plus(&full_nrg, 1); + full_nrg16 = extract_h(L_shl(full_nrg, s)); + part_nrg16 = extract_h(L_shl(part_nrg, s)); + + tmp16 = mult(full_nrg16, 9830 /* 0.3 */); + + IF (part_nrg16 < tmp16) + { + *bfi = 1; + } + } + } + + Dyn_Mem_Deluxe_Out(); +} + +void peakDetector_fx(Word16 in_sig[], Word16 yLen, Word16 *xover) +{ + Dyn_Mem_Deluxe_In( + Counter i, j; + Word16 tmp16, c, s, s2, mean_block_nrg16; + Word32 maxPeak, tmp32; + Word32 mean_block_nrg, block_cent; + Word16 cur_max, prev_max, next_max; + ); + + *xover = 0; + + s = getScaleFactor16(in_sig, yLen); + + mean_block_nrg = 0; move32(); + FOR (i = 0; i < yLen; i++) + { + tmp16 = shl_sat(in_sig[i], sub(s, 4)); + mean_block_nrg = L_mac0(mean_block_nrg, tmp16, tmp16); /* exp = 2s - 8 */ + } + + s2 = getScaleFactor16(&yLen, 1); + c = shl(yLen, s2); + mean_block_nrg16 = div_l(mean_block_nrg, c); /* exp = 2s - 8 - s2 - 1 */ + mean_block_nrg = L_shl(L_mult0(mean_block_nrg16, BLOCK_SIZE * THR1), add(4, s2)); /* exp = 2s - 5 */ + + maxPeak = 0; move32(); + c = sub(yLen, 2 * BLOCK_SIZE); + + test(); + IF (abs_s(in_sig[0]) >= abs_s(in_sig[1])) + { + block_cent = 0; move32(); + FOR (j = 0; j <= 1; j++) + { + tmp16 = shl_sat(in_sig[j], sub(s, 2)); + block_cent = L_mac0(block_cent, tmp16, tmp16); /* -> exp = 2s - 4 */ + } + block_cent = L_shr(block_cent, 1); /* exp = 2s - 5 */ + + IF (L_sub(block_cent, mean_block_nrg) > 0) + { + cur_max = abs_s(in_sig[0]); + cur_max = MAX(abs_s(in_sig[1]), cur_max); + + next_max = abs_s(in_sig[-1 + BLOCK_SIZE]); + next_max = MAX(abs_s(in_sig[-1 + BLOCK_SIZE + 1]), next_max); + next_max = MAX(abs_s(in_sig[-1 + BLOCK_SIZE + 2]), next_max); + + IF (sub(cur_max, next_max) > 0) + { + maxPeak = block_cent; move32(); + *xover = 1; + } + } + } + + FOR (i = 0; i < BLOCK_SIZE; i++) + { + test(); + IF (abs_s(in_sig[i + 1]) >= abs_s(in_sig[i]) && abs_s(in_sig[i + 1]) >= abs_s(in_sig[i + 2])) + { + block_cent = 0; move32(); + FOR (j = 0; j < BLOCK_SIZE; j++) + { + tmp16 = shl_sat(in_sig[i + j], sub(s, 2)); + block_cent = L_mac0(block_cent, tmp16, tmp16); /* -> exp = 2s - 4 */ + } + block_cent = L_shr(block_cent, 1); /* exp = 2s - 5 */ + + IF (L_sub(block_cent, mean_block_nrg) > 0) + { + cur_max = abs_s(in_sig[i]); + cur_max = MAX(abs_s(in_sig[i + 1]), cur_max); + cur_max = MAX(abs_s(in_sig[i + 2]), cur_max); + + prev_max = 0; move16(); + FOR (j = i - BLOCK_SIZE; j <= i - 1; j++) + { + IF (j > 0) + { + prev_max = MAX(abs_s(in_sig[j]), prev_max); + } + } + + next_max = abs_s(in_sig[i + BLOCK_SIZE]); + next_max = MAX(abs_s(in_sig[i + BLOCK_SIZE + 1]), next_max); + next_max = MAX(abs_s(in_sig[i + BLOCK_SIZE + 2]), next_max); + + test(); + IF (sub(cur_max, prev_max) >= 0 && sub(cur_max, next_max) > 0) + { + IF (L_sub(block_cent, maxPeak) >= 0) + { + maxPeak = block_cent; move32(); + *xover = sub(add(i, BLOCK_SIZE), 1); + } + ELSE + { + tmp32 = L_mult(FAC, extract_h(maxPeak)); + + tmp16 = extract_l(L_shr(maxPeak, 1)); + tmp16 = s_and(tmp16, 0x7fff); + tmp16 = mult(FAC, tmp16); + tmp32 = L_add_sat(tmp32, tmp16); + + IF (L_sub(block_cent, tmp32) > 0) + { + *xover = sub(add(i, BLOCK_SIZE), 1); + } + } + } + } + } + } + + FOR (i = BLOCK_SIZE; i <= c; i++) + { + test(); + IF (abs_s(in_sig[i + 1]) >= abs_s(in_sig[i]) && abs_s(in_sig[i + 1]) >= abs_s(in_sig[i + 2])) + { + block_cent = 0; move32(); + FOR (j = 0; j < BLOCK_SIZE; j++) + { + tmp16 = shl_sat(in_sig[i + j], sub(s, 2)); + block_cent = L_mac0(block_cent, tmp16, tmp16); /* -> exp = 2s - 4 */ + } + block_cent = L_shr(block_cent, 1); /* exp = 2s - 5 */ + + IF (L_sub(block_cent, mean_block_nrg) > 0) + { + cur_max = abs_s(in_sig[i]); + cur_max = MAX(abs_s(in_sig[i + 1]), cur_max); + cur_max = MAX(abs_s(in_sig[i + 2]), cur_max); + + prev_max = abs_s(in_sig[i - BLOCK_SIZE]); + prev_max = MAX(abs_s(in_sig[i - BLOCK_SIZE + 1]), prev_max); + prev_max = MAX(abs_s(in_sig[i - BLOCK_SIZE + 2]), prev_max); + + next_max = abs_s(in_sig[i + BLOCK_SIZE]); + next_max = MAX(abs_s(in_sig[i + BLOCK_SIZE + 1]), next_max); + next_max = MAX(abs_s(in_sig[i + BLOCK_SIZE + 2]), next_max); + + test(); + IF (sub(cur_max, prev_max) >= 0 && sub(cur_max, next_max) > 0) + { + IF (L_sub(block_cent, maxPeak) >= 0) + { + maxPeak = block_cent; move32(); + *xover = sub(add(i, BLOCK_SIZE), 1); + } + ELSE + { + tmp32 = L_mult(FAC, extract_h(maxPeak)); + + tmp16 = extract_l(L_shr(maxPeak, 1)); + tmp16 = s_and(tmp16, 0x7fff); + tmp16 = mult(FAC, tmp16); + tmp32 = L_add_sat(tmp32, tmp16); + + IF (L_sub(block_cent, tmp32) > 0) + { + *xover = sub(add(i, BLOCK_SIZE), 1); + } + } + } + } + } + } + + Dyn_Mem_Deluxe_Out(); +} + + diff --git a/lib_lc3plus/pc_main_fx.c b/lib_lc3plus/pc_main_fx.c new file mode 100644 index 0000000000000000000000000000000000000000..708f79d748a758f4bdef3a2af8d9363e55ae3f6e --- /dev/null +++ b/lib_lc3plus/pc_main_fx.c @@ -0,0 +1,57 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.5 * +* 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 "defines.h" +#include "constants.h" +#include "functions.h" + +void processPCmain_fx(Word16 rframe, Word16 *bfi, Word16 yLen, Word16 frame_dms, Word16 q_old_res_fx[], + Word16 *q_old_res_fx_exp, +#ifdef ENABLE_HR_MODE + Word32 q_res_fx[], +#else + Word16 q_res_fx[], +#endif + Word16 q_old_d_fx[], Word16 spec_inv_idx, + Word16 pitch_present, Word16 stab_fac, Word32 q_d_fx[], Word16 *q_fx_exp, + Word16 gg_idx, Word16 gg_idx_off, Word16 *prev_gg, Word16 *prev_gg_e, Word16 *BW_cutoff_idx_nf, + Word16 *prev_BW_cutoff_idx_nf, Word16 fac_ns_idx, Word16 *prev_fac_ns_fx, Word16 *pc_nbLostFramesInRow) +{ + Dyn_Mem_Deluxe_In( + Word16 fac, fac_e; + ); + + fac = 32767; fac_e = 0; + + IF (sub(*bfi, 2) == 0) + { + processPCclassify_fx(pitch_present, frame_dms, q_old_d_fx, q_old_res_fx, yLen, spec_inv_idx, stab_fac, bfi); + } + + IF (sub(*bfi, 2) == 0) + { + processPCapply_fx(yLen, q_old_res_fx, q_old_res_fx_exp, q_res_fx, q_old_d_fx, spec_inv_idx, + &fac, &fac_e, q_d_fx, q_fx_exp, gg_idx, gg_idx_off, *prev_gg, *prev_gg_e, pc_nbLostFramesInRow); + } + + IF (sub(*bfi, 1) != 0) + { + processPCupdate_fx(*bfi, yLen, q_old_res_fx, q_old_res_fx_exp, q_res_fx, spec_inv_idx, gg_idx, gg_idx_off, prev_gg, + prev_gg_e, rframe, BW_cutoff_idx_nf, prev_BW_cutoff_idx_nf, fac_ns_idx, prev_fac_ns_fx, fac, fac_e); + } + + if (*bfi == 0) + { + *pc_nbLostFramesInRow = 0; move16(); + } + + Dyn_Mem_Deluxe_Out(); +} + + diff --git a/lib_lc3plus/pc_update_fx.c b/lib_lc3plus/pc_update_fx.c new file mode 100644 index 0000000000000000000000000000000000000000..17b719bcd224e8dee2cf0695a8a46ca28dfbefab --- /dev/null +++ b/lib_lc3plus/pc_update_fx.c @@ -0,0 +1,148 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.5 * +* 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 "defines.h" +#include "constants.h" +#include "functions.h" + +#ifdef ENABLE_HR_MODE + +void Copy_Scale_sig_32(const Word32 x[], /* i : signal to scale input Qx */ + Word16 y[], /* o : scaled signal output Qx */ + const Word16 lg, /* i : size of x[] Q0 */ + const Word16 exp0 /* i : exponent: x = round(x << exp) Qx ?exp */ +) +{ + Counter i; + Word16 tmp; + + if (exp0 == 0) + { + for (i = 0; i < lg; i++) + { + y[i] = extract_h(x[i]); + } + + return; + } + + tmp = s_max(exp0, -31); + tmp = s_min(tmp, 31); + + for (i = 0; i < lg; i++) + { + y[i] = extract_h(L_shr_r(x[i], -tmp)); + } +} +#endif + +void processPCupdate_fx(Word16 bfi, Word16 yLen, Word16 q_old_res_fx[], Word16 *q_old_res_fx_exp, +#ifdef ENABLE_HR_MODE + Word32 q_res_fx[], +#else + Word16 q_res_fx[], +#endif + Word16 spec_inv_idx, Word16 gg_idx, Word16 gg_idx_off, + Word16 *prev_gg, Word16 *prev_gg_e, Word16 rframe, Word16 *BW_cutoff_idx_nf, + Word16 *prev_BW_cutoff_idx_nf, Word16 fac_ns_idx, Word16 *prev_fac_ns_fx, Word16 fac, + Word16 fac_e) +{ + Word16 global_gain, global_gain_e, s, s2, s3, tmp16; + Word32 tmp32; + +#ifdef DYNMEM_COUNT + struct _dynmem + { + Word16 global_gain, global_gain_e, s, s2, s3, tmp16; + Word32 tmp32; + }; + Dyn_Mem_In("processPCupdate_fx", sizeof(struct _dynmem)); +#endif + + tmp32 = L_shl_pos(L_mult0(add(gg_idx, gg_idx_off), 0x797D), 7); + global_gain_e = add(extract_l(L_shr_pos(tmp32, 25)), 1); + global_gain = round_fx(BASOP_Util_InvLog2_lc3plus(L_or(tmp32, 0xFE000000))); + + *prev_gg = global_gain; move16(); + *prev_gg_e = global_gain_e; move16(); + +#ifdef ENABLE_HR_MODE + s = getScaleFactor32_lc3plus(q_res_fx, spec_inv_idx); /* exp = 0 */ +#else + s = getScaleFactor16(q_res_fx, spec_inv_idx); /* exp = 0 */ +#endif + + IF (bfi == 0) + { + *q_old_res_fx_exp = negate(s); +#ifdef ENABLE_HR_MODE + Copy_Scale_sig_32(q_res_fx, q_old_res_fx, yLen, s); + *q_old_res_fx_exp = *q_old_res_fx_exp + 16; +#else + Copy_Scale_sig(q_res_fx, q_old_res_fx, yLen, s); +#endif + } + ELSE + { +#ifdef ENABLE_HR_MODE + s2 = getScaleFactor32_lc3plus(&q_res_fx[spec_inv_idx], sub(yLen, spec_inv_idx)); /* exp = q_old_res_fx_exp */ + IF (s2 == 0) + s2 = 16; + s3 = add(s, *q_old_res_fx_exp); + IF (sub(s3, s2) > 0) + { + tmp16 = sub(s3, s2); + s = sub(s, tmp16); + } + s2 = add(s, *q_old_res_fx_exp); + *q_old_res_fx_exp = negate(s) + 16; + + + if (s2 > -32) + { + Copy_Scale_sig_32(&q_res_fx[spec_inv_idx], &q_old_res_fx[spec_inv_idx], sub(yLen, spec_inv_idx), s2); + } +#else + s2 = getScaleFactor16(&q_res_fx[spec_inv_idx], sub(yLen, spec_inv_idx)); /* exp = q_old_res_fx_exp */ + s3 = add(s, *q_old_res_fx_exp); + IF (sub(s3, s2) > 0) + { + tmp16 = sub(s3, s2); + s = sub(s, tmp16); + } + s2 = add(s, *q_old_res_fx_exp); + *q_old_res_fx_exp = negate(s); + + s = s_max(s_min(s, 15), -15); + s2 = s_max(s_min(s2, 15), -15); + Copy_Scale_sig(q_res_fx, q_old_res_fx, spec_inv_idx, s); + Copy_Scale_sig(&q_res_fx[spec_inv_idx], &q_old_res_fx[spec_inv_idx], sub(yLen, spec_inv_idx), s2); +#endif + } + + IF (rframe == 0) + { + *prev_BW_cutoff_idx_nf = *BW_cutoff_idx_nf; + *prev_fac_ns_fx = shl_pos(sub(8, fac_ns_idx), 11); + } + ELSE IF(sub(bfi, 2) == 0 && sub(*BW_cutoff_idx_nf, *prev_BW_cutoff_idx_nf) != 0 + && sub(spec_inv_idx, yLen) < 0) + { + *BW_cutoff_idx_nf = *prev_BW_cutoff_idx_nf; + *prev_fac_ns_fx = shl_sat(mult(*prev_fac_ns_fx, fac), fac_e); + *prev_fac_ns_fx = s_max(*prev_fac_ns_fx, 2048); + *prev_fac_ns_fx = s_min(*prev_fac_ns_fx, 16384); + } + +#ifdef DYNMEM_COUNT + Dyn_Mem_Out(); +#endif +} + + diff --git a/lib_lc3plus/per_band_energy_fx.c b/lib_lc3plus/per_band_energy_fx.c new file mode 100644 index 0000000000000000000000000000000000000000..3ba629a83175b81b959f5a27505d7aa8d3dc8685 --- /dev/null +++ b/lib_lc3plus/per_band_energy_fx.c @@ -0,0 +1,275 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.5 * +* 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 "functions.h" +#include "rom_basop_util_lc3plus.h" + +void processPerBandEnergy_fx(Word32 *d2_fx, Word16 *d2_fx_exp, Word32 *d_fx, Word16 d_fx_exp, + const Word16 *band_offsets, Word16 fs_idx, Word16 n_bands, Word16 linear, Word16 frame_dms, + Word8 *scratchBuffer +#ifdef ENABLE_HR_MODE + , Word16 hrmode +#endif +) +{ + Dyn_Mem_Deluxe_In(Counter i, k, band; Word16 s; Word16 s1; Word16 s2; Word32 nrg; Word16 smax; Word16 tmp16; + Word16 nbands; Word16 maxBwBin; Word16 stopBand; Word16 bandsOffsetOne; Word16 bandsOffsetTwo; + Word16 * d2_band_fx_exp;); + + + d2_band_fx_exp = (Word16 *)scratchAlign(scratchBuffer, 0); /* Size = 2 * MAX_BANDS_NUMBER_PLC bytes */ + +#ifdef ENABLE_HR_MODE + if (hrmode) + { + maxBwBin = MAX_BW_HR; + fs_idx = fs_idx + 1; + move16(); + } + else +#endif + { + maxBwBin = MAX_BW; + move16(); + } + + SWITCH (frame_dms) + { + case 25: maxBwBin = maxBwBin >> 2; move16(); + { + bandsOffsetOne = bands_offset_with_one_max_2_5ms[fs_idx]; + move16(); + bandsOffsetTwo = bands_offset_with_two_max_2_5ms[fs_idx]; + move16(); + } + BREAK; + case 50: maxBwBin = maxBwBin >> 1; move16(); + { + bandsOffsetOne = bands_offset_with_one_max_5ms[fs_idx]; + move16(); + bandsOffsetTwo = bands_offset_with_two_max_5ms[fs_idx]; + move16(); + } + BREAK; +#ifdef CR8_G_ADD_75MS + case 75: + maxBwBin = (maxBwBin >> 2) * 3; move16(); + bandsOffsetOne = bands_offset_with_one_max_7_5ms[fs_idx]; + move16(); + bandsOffsetTwo = bands_offset_with_two_max_7_5ms[fs_idx]; + move16(); + BREAK; +#endif + default: /* 100 */ + { + bandsOffsetOne = bands_offset_with_one_max[fs_idx]; + move16(); + bandsOffsetTwo = bands_offset_with_two_max[fs_idx]; + move16(); + } + BREAK; + } + + IF (sub(linear, 1) == 0) + { + + #ifdef ENABLE_HR_MODE + if (hrmode) + { + fs_idx = fs_idx - 1; + } + #endif + + SWITCH (frame_dms) + { + case 25: + bandsOffsetOne = bands_offset_with_one_max_lin_2_5ms[fs_idx]; + move16(); + bandsOffsetTwo = bands_offset_with_two_max_lin_2_5ms[fs_idx]; + move16(); + BREAK; + case 50: + bandsOffsetOne = bands_offset_with_one_max_lin_5ms[fs_idx]; + move16(); + bandsOffsetTwo = bands_offset_with_two_max_lin_5ms[fs_idx]; + move16(); + BREAK; +#ifdef CR8_G_ADD_75MS + case 75: + bandsOffsetOne = bands_offset_with_one_max_lin_7_5ms[fs_idx]; + move16(); + bandsOffsetTwo = bands_offset_with_two_max_lin_7_5ms[fs_idx]; + move16(); + BREAK; +#endif + case 100: + bandsOffsetOne = bands_offset_with_one_max_lin[fs_idx]; + move16(); + bandsOffsetTwo = bands_offset_with_two_max_lin[fs_idx]; + move16(); + BREAK; + } + } + + /* start processing with band offsets == 1 */ + FOR (band = 0; band < bandsOffsetOne; band++) + { + ASSERT((band_offsets[band + 1] - band_offsets[band]) == 1); + ASSERT(band < maxBwBin); + + s2 = 15; + move16(); + s = norm_l(d_fx[band]); + if (d_fx[band] != 0) + s2 = s_min(s2, s); + + tmp16 = extract_h(L_shl_pos(d_fx[band], s2)); + + d2_fx[band] = L_mult0(tmp16, tmp16); + move32(); + d2_band_fx_exp[band] = sub(1, shl_pos(s2, 1)); + move16(); + } + + /* start processing with band offsets == 2 */ + i = bandsOffsetOne; + move16(); + FOR (; band < bandsOffsetTwo; band++) + { + ASSERT((band_offsets[band + 1] - band_offsets[band]) == 2); + IF (sub(add(i, 1), maxBwBin) >= 0) + { + IF (sub(i, maxBwBin) >= 0) + { + d2_fx[band] = 0; + move32(); + d2_band_fx_exp[band] = sub(1, shl_pos(15, 1)); + move16(); + } + ELSE + { + s2 = 15; + move16(); + s = norm_l(d_fx[band]); + if (d_fx[band] != 0) + s2 = s_min(s2, s); + + tmp16 = extract_h(L_shl_pos(d_fx[band], s2)); + + d2_fx[band] = L_mult0(tmp16, tmp16); + move32(); + d2_band_fx_exp[band] = sub(1, shl_pos(s2, 1)); + move16(); + } + } + ELSE + { + ASSERT(i + 1 < maxBwBin); + + s2 = 15; + move16(); + s = norm_l(d_fx[i]); + if (d_fx[i] != 0) + s2 = s_min(s2, s); + s = norm_l(d_fx[i + 1]); + if (d_fx[i + 1] != 0) + s2 = s_min(s2, s); + + tmp16 = extract_h(L_shl_pos(d_fx[i], s2)); + nrg = L_mult0(tmp16, tmp16); + nrg = L_min(nrg, 0x3FFFFFFF); + tmp16 = extract_h(L_shl_pos(d_fx[i + 1], s2)); + + d2_fx[band] = L_shr_pos(L_mac0(nrg, tmp16, tmp16), 1); + move32(); + d2_band_fx_exp[band] = sub(1, shl_pos(s2, 1)); + move16(); + } + i = add(i, 2); + } + + /* proceed with band offsets > 2 */ + FOR (; band < n_bands; band++) + { + /* normalization */ + k = i; + move16(); + s1 = 15; + move16(); + + stopBand = s_min(band_offsets[band + 1], maxBwBin); + FOR (; k < stopBand; k++) + { + s = norm_l(d_fx[k]); + if (d_fx[k] != 0) + s1 = s_min(s1, s); + } + + nbands = sub(band_offsets[band + 1], band_offsets[band]); +#ifdef ENABLE_HR_MODE + if (nbands < 32) + { + nbands = s_min(s_max(0, nbands), 31); + /* specify headroom, it can be reduced by one due to use of L_mac0 */ + s2 = sub(s1, bands_nrg_scale[nbands]); + } + else + { + /* Active only in the 96 kHz case */ + s2 = sub(s1, 5); + } +#else + ASSERT(nbands < 32); + nbands = s_min(s_max(0, nbands), 31); + /* specify headroom, it can be reduced by one due to use of L_mac0 */ + s2 = sub(s1, bands_nrg_scale[nbands]); +#endif + + /* calculate energy per band */ + nrg = 0; + move32(); + + FOR (; i < stopBand; i++) + { + tmp16 = extract_h(L_shl(d_fx[i], s2)); + nrg = L_mac0(nrg, tmp16, tmp16); + } + i = band_offsets[band + 1]; + + /* calculate mean value of energy */ + nrg = Mpy_32_16_lc3plus(nrg, InvIntTable[nbands]); + + /* store normalized energy */ + s = norm_l(nrg); + d2_fx[band] = L_shl_pos(nrg, s); + move32(); + d2_band_fx_exp[band] = sub(1, add(shl_pos(s2, 1), s)); + move16(); + } + + /* Determine maximum exponent and rescale band energies */ + smax = -31; + move16(); + FOR (band = 0; band < n_bands; band++) + { + smax = s_max(smax, d2_band_fx_exp[band]); + } + FOR (band = 0; band < n_bands; band++) + { + d2_fx[band] = L_shr_pos(d2_fx[band], s_min(sub(smax, d2_band_fx_exp[band]), 31)); + move32(); + } + + /* Save exponent for all bands */ + *d2_fx_exp = s_max(add(shl_pos(d_fx_exp, 1), smax), -32); + move16(); + + Dyn_Mem_Deluxe_Out(); +} + diff --git a/lib_lc3plus/plc_apply_fx.c b/lib_lc3plus/plc_apply_fx.c new file mode 100644 index 0000000000000000000000000000000000000000..9430d155e1b9d774d24a1bc0ee6b4b824723720e --- /dev/null +++ b/lib_lc3plus/plc_apply_fx.c @@ -0,0 +1,419 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.5 * +* 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 "defines.h" +#include "constants.h" +#include "functions.h" + +void processPLCapply_fx( +#ifdef CR8_A_PLC_FADEOUT_TUNING + Word16 *concealMethod, +#else + Word16 concealMethod, +#endif + Word16 nbLostFramesInRow, Word16 bfi, Word16 prev_bfi, + Word16 frame_length, Word16 la_zeroes, +#ifdef ENABLE_HR_MODE + const Word32 w[], +#else + const Word16 w[], +#endif + Word16 x_fx[], Word16 ola_mem[], + Word16 *ola_mem_exp, Word16 q_old_d_fx[], Word16 *q_old_fx_exp, Word32 q_d_fx[], + Word16 *q_fx_exp, Word16 yLen, Word16 fs_idx, Word16 *damping, Word16 old_pitch_int, + Word16 old_pitch_fr, Word16 *ns_cum_alpha, Word16 *ns_seed, Word16 frame_dms, AplcSetup *plcAd, + Word8 *scratchBuffer +#ifdef ENABLE_HR_MODE + , Word16 hrmode +#endif +#ifdef CR9_N_SHORT_FADE_FOR_UNSTABLE_PITCH + , Word32 rel_pitch_change +#endif +#ifdef CR10_A_ATTENUATION_CURVE_SELECTOR + , Word16 *alpha_type_2_table +#endif + ) +{ + Dyn_Mem_Deluxe_In( + Counter i; + Word32 *d2_fx; + Word32 *q_old_d_fx32; + Word32 *r_fx; + Word32 *tdc_A_32; + Word16 d2_fx_exp; + Word16 r_fx_exp; + Word16 Q_syn; + Word8 * buffer_perBandEnergy, *buffer_preEmphasis, *buffer_InverseODFT, *buffer_Levinson, + *buffer_tdac, *buffer_phecu; + Word16 y_e; /*exponent of L_ecu_rec */ + Word16 tmp_is_trans[2]; /* may be changed to a single variable */ + Word16 env_stab; + + Word16 n_bands, prev_bfi_plc2; + const Word16 *band_offsets; + Word32 * L_ecu_rec; /* local xtda output is MAX_LEN -> input buffer, + as tmp buffer for w32 fft MAX_LPROT */ + ); +#ifdef CR8_A_PLC_FADEOUT_TUNING + Word16 consecutiveLostThreshold = 0; +#endif + +#ifdef CR9_L_RETRAIN_FADEOUT_TYPE_CLASSIFIER + Word16 thresh_tdc_cnt; + Word16 thresh_ns_cnt; + Word16 thresh_tdc_ns_cnt; +#endif + + band_offsets = NULL; + + d2_fx = (Word32 *)scratchAlign(scratchBuffer, 0); /* Size = 4 * MAX_BANDS_NUMBER_PLC */ + q_old_d_fx32 = (Word32 *)scratchAlign(d2_fx, sizeof(*d2_fx) * MAX_BANDS_NUMBER_PLC); /* Size = 4 * MAX_BW */ + r_fx = (Word32 *)scratchAlign(d2_fx, sizeof(*d2_fx) * MAX_BANDS_NUMBER_PLC); /* Size = 4 * (M + 1) */ + tdc_A_32 = (Word32 *)scratchAlign(r_fx, sizeof(*r_fx) * (M + 1)); /* Size = 4 * (M + 1) */ + + L_ecu_rec = (Word32 *)scratchAlign(tdc_A_32, sizeof(*tdc_A_32) * (M + 1)); /* Size = 4 * MAX_LPROT bytes */ + + buffer_perBandEnergy = + (Word8 *)scratchAlign(q_old_d_fx32, sizeof(*q_old_d_fx32) * (MAX_LEN)); /* Size = 2 * MAX_BANDS_NUMBER_PLC */ + buffer_preEmphasis = + (Word8 *)scratchAlign(tdc_A_32, sizeof(*tdc_A_32) * (M + 1)); /* Size = 2 * MAX_BANDS_NUMBER_PLC */ + buffer_InverseODFT = buffer_preEmphasis; /* Size = 640 bytes */ + buffer_Levinson = buffer_preEmphasis; /* Size = 4 * (M + 1) */ + + buffer_tdac = scratchBuffer; /* Size = 2 * MAX_LEN bytes */ + buffer_phecu = scratchBuffer; /* Size = 2 * MAX_LGW + 8 * MAX_LPROT + 12 * MAX_L_FRAME */ + /* Buffers overlap since they are not used at once */ + + + UNUSED(ns_cum_alpha); + UNUSED(ns_seed); + + /* Apply/Prepare PLC in bfi-case */ + IF (sub(bfi, 1) == 0) + { + +#ifdef CR8_A_PLC_FADEOUT_TUNING + SWITCH(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 (sub(fs_idx, 2) == 0 || sub(fs_idx, 4) >= 0) + { +#ifdef CR9_L_RETRAIN_FADEOUT_TYPE_CLASSIFIER + if (sub(plcAd->longterm_counter_plcTdc, thresh_tdc_cnt) < 0){ + plcAd->plc_fadeout_type = 1; + } + else if (sub(plcAd->longterm_counter_plcNsAdv, thresh_ns_cnt) < 0){ + plcAd->plc_fadeout_type = 1; + } + else if (sub(plcAd->longterm_counter_plcTdc + plcAd->longterm_counter_plcNsAdv, thresh_tdc_ns_cnt) < 0){ + plcAd->plc_fadeout_type = 1; + } + else { + plcAd->plc_fadeout_type = 0; + } + +#else + IF (((sub(plcAd->longterm_counter_plcPhaseEcu, L_shr_pos(Mpy_32_16_lc3plus(FAC1_FADEOUT, plcAd->longterm_counter_plcTdc), SHIFT1_FADEOUT)) < 0) || + (sub(plcAd->longterm_counter_plcPhaseEcu, L_shr_pos(Mpy_32_16_lc3plus(FAC1_FADEOUT, plcAd->longterm_counter_plcNsAdv), SHIFT1_FADEOUT)) < 0)) && + (sub(plcAd->longterm_counter_plcTdc, L_shr_pos(Mpy_32_16_lc3plus(FAC2_FADEOUT, plcAd->longterm_counter_plcNsAdv), SHIFT2_FADEOUT)) < 0)) + { + plcAd->plc_fadeout_type = 0; + } + ELSE + { + IF ((sub(plcAd->longterm_counter_plcPhaseEcu, L_shr_pos(Mpy_32_16_lc3plus(FAC3_FADEOUT, plcAd->longterm_counter_plcTdc), SHIFT3_FADEOUT)) > 0) || + (sub(plcAd->longterm_counter_plcPhaseEcu, L_shr_pos(Mpy_32_16_lc3plus(FAC3_FADEOUT, plcAd->longterm_counter_plcNsAdv), SHIFT3_FADEOUT)) > 0)) + { + plcAd->plc_fadeout_type = 1; + } ELSE { + plcAd->plc_fadeout_type = 0; + } + } +#endif + + + env_stab = norm_s(plcAd->longterm_analysis_counter_max); + IF(sub(shl_pos(plcAd->overall_counter, env_stab), mult(shl_pos(plcAd->longterm_analysis_counter_max, env_stab), PLC_LONGTERM_ANALYSIS_STARTUP_FILL)) < 0) + { + plcAd->plc_fadeout_type = 0; + } + +#ifndef CR9_H_REMOVE_SWITCH_TO_PLC_NS + IF (sub(nbLostFramesInRow, consecutiveLostThreshold) >= 0 && sub(plcAd->plc_fadeout_type, 1) == 0) + { + IF (sub(*concealMethod, LC3_CON_TEC_TDPLC) == 0) + { + *concealMethod = LC3_CON_TEC_NS_ADV; + } + } +#endif +#ifdef CR9_N_SHORT_FADE_FOR_UNSTABLE_PITCH + IF (L_sub(rel_pitch_change,REL_PITCH_THRESH) > 0 && sub(hrmode,1) == 0 && (sub(frame_dms,50) == 0 || sub(frame_dms,25) == 0)){ + plcAd->plc_fadeout_type = 2;move16(); + } ELSE +#endif + IF((sub(nbLostFramesInRow, consecutiveLostThreshold) < 0) && (*concealMethod != LC3_CON_TEC_PHASE_ECU)) + { + plcAd->plc_fadeout_type = 0; + } + } ELSE { + plcAd->plc_fadeout_type = 0; /*fs_idx == 0,1,3 */ + } +#endif /* CR8_A_PLC_FADEOUT_TUNING */ + +#ifdef CR8_A_PLC_FADEOUT_TUNING + SWITCH (*concealMethod) +#else + SWITCH (concealMethod) +#endif + { + case LC3_CON_TEC_PHASE_ECU: + ASSERT(frame_dms == 100); + /* call phaseEcu */ + env_stab = 32767; move16(); /* 1.0=stable , 0.0=dynamic Q15*/ + tmp_is_trans[0] = plcAd->PhECU_short_flag_prev; move16(); + tmp_is_trans[1] = plcAd->PhECU_short_flag_prev; move16(); + + ASSERT(prev_bfi == 0 || prev_bfi == 1|| prev_bfi == 2); /*PC prev_bfi has three states */ + prev_bfi_plc2 = prev_bfi; move16(); + if (sub(prev_bfi_plc2, 2) == 0) + { + prev_bfi_plc2 = 0; move16(); + } + + ASSERT(prev_bfi_plc2 == 0 || prev_bfi_plc2 == 1); /*PhEcu does not accept prev_bfi == 2 */ + IF(prev_bfi_plc2 == 0) + { /* convert pitch lag info at current fs to a normalized fractional bin-frequency */ + plcAd->PhECU_f0hzLtpBinQ7 = plc_phEcuSetF0Hz_fx(fs_idx, old_pitch_int, old_pitch_fr); move16(); + + + + /* first bfi frame calc decoded pcm energy 16,16 ms, in 26 ms buffer separated by 10 ms*/ + + { /* compute energy normalization needed for concealment method 2 Xavg and transient analysis */ + + /* left */ + processPLCUpdateXFP_w_E_hist_fx(0, 0, + &(plcAd->x_old_tot_fx[ sub(plcAd->max_len_pcm_plc , add(num_FsByResQ0[fs_idx],rectLengthTab[fs_idx] )) ]), plcAd->q_fx_old_exp,0, + + fs_idx, + &plcAd->PhECU_L_oold_xfp_w_E_fx, &plcAd->PhECU_oold_xfp_w_E_exp_fx, + &plcAd->PhECU_L_old_xfp_w_E_fx, &plcAd->PhECU_old_xfp_w_E_exp_fx, + &plcAd->PhECU_oold_Ltot_exp_fx, &plcAd->PhECU_old_Ltot_exp_fx); + + /* right */ + processPLCUpdateXFP_w_E_hist_fx(0, 0, plcAd->PhECU_xfp_fx, plcAd->PhECU_xfp_exp_fx, + plcAd->PhECU_margin_xfp, fs_idx, + &plcAd->PhECU_L_oold_xfp_w_E_fx, &plcAd->PhECU_oold_xfp_w_E_exp_fx, + &plcAd->PhECU_L_old_xfp_w_E_fx, &plcAd->PhECU_old_xfp_w_E_exp_fx, + &plcAd->PhECU_oold_Ltot_exp_fx, &plcAd->PhECU_old_Ltot_exp_fx); + } + } + + hq_phase_ecu_fx( + plcAd->PhECU_xfp_fx, /* i : only valid first Bfi frame , buffer of previous synt signal length */ + L_ecu_rec, /* o : reconstructed frame in folded tda domain xtda Word32 Q x */ + &plcAd->PhECU_time_offs, /* i/o: Sample offset for consecutive frame losses*/ + plcAd->PhECU_X_sav_fx, /* i(prev_bfi==1)/o(prev_bfi==0): Stored Complex spectrum of prototype frame */ + &plcAd->PhECU_X_savQ_fx, /* i/o: Q value of stored spectrum */ + &plcAd->PhECU_num_plocs, /* i/o: Number of identified peaks */ + plcAd->PhECU_plocs, /* i/o: Peak locations Q0 */ + plcAd->PhECU_f0est, /* i/o: Interpolated peak locations Q16 */ + env_stab, /* i : Envelope stability parameter */ + plcAd->PhECU_f0hzLtpBinQ7, /* i: LTP bin frequency in normalized Hz Q7 */ + plcAd->norm_corrQ15_fx, /* i : correlation for lag at f0hzLtpBinQ7 */ + prev_bfi_plc2, /* i : indicating burst frame error */ + tmp_is_trans, /* i : flags indicating previous transient frames */ + plcAd->PhECU_mag_chg_1st, /* i/o: per band magnitude modifier for transients*/ + NULL, /* o: dbg per band magnitude modifier, incl. burst attenuation */ + plcAd->PhECU_Xavg, /* i/o: Frequency group average gain to fade to */ + &plcAd->PhECU_beta_mute, /* o : Factor for long-term mute */ + fs_idx, /* i : Encoded bandwidth "nb(0),WB,sWB,WB,FB" */ + frame_length, /* i : frame length */ + NULL , /* o : seed synch dbg */ + NULL , /* o : evolved Spectrum dbg */ + plcAd->PhECU_t_adv, /* i : time adjustment excluding time_offs */ + PhECU_wins[fs_idx][2], /* i: 2 ms initial part pre_tda = mdct-ana */ + PhECU_wins[fs_idx][1], /* i: 16 ms pretda combined part IWHR+MDCT-ana */ + PhECU_wins[fs_idx][0], + plcAd->PhECU_xfp_exp_fx, + plcAd->max_lprot, + plcAd->max_plocs, + plcAd->PhECU_L_oold_xfp_w_E_fx,plcAd->PhECU_oold_xfp_w_E_exp_fx, plcAd->PhECU_oold_Ltot_exp_fx, + plcAd->PhECU_oold_grp_shape_fx, + plcAd->PhECU_L_old_xfp_w_E_fx,plcAd->PhECU_old_xfp_w_E_exp_fx, plcAd->PhECU_old_Ltot_exp_fx, + plcAd->PhECU_old_grp_shape_fx, + plcAd->PhECU_margin_xfp, +#ifdef CR8_A_PLC_FADEOUT_TUNING + plcAd->plc_fadeout_type , /* i : fadeout scheme */ + &(plcAd->PhECU_nonpure_tone_flag), /* i/o : non-pure single tone indicator state */ +#endif + buffer_phecu); + + y_e = 18; move16(); /* the fixed exponent (exp) from Lecu_rec from PhaseECU is 18 */ + + Processing_ITDA_WIN_OLA( + L_ecu_rec, /* i: X_TDA buffer data = "y" DCT-IV output */ + &y_e, /* i/o: x_tda exponent "y_e" */ + w, /* i: window coefficients including normalization of sqrt(2/N) and scaled by 2^4 */ + ola_mem, /* i/o: overlap add memory */ + ola_mem_exp, /* i/o: overlap add exponent */ + x_fx, /* o: time signal out */ + LowDelayShapes_n960_len[fs_idx], /* i: window length */ + frame_length, /* i: block size */ + sub(frame_length, LowDelayShapes_n960_la_zeroes[fs_idx]) /* i: overlap add buffer size */ + ); + *q_fx_exp = y_e; move16(); /* assign updated Q */ + BREAK; + + case LC3_CON_TEC_TDPLC: + IF (sub(nbLostFramesInRow, 1) == 0) + { + plcAd->tdc_fract = old_pitch_fr; move16(); + n_bands = s_min(frame_length, MAX_BANDS_NUMBER_PLC); + SWITCH (frame_dms) + { + case 25: + band_offsets = bands_offset_lin_2_5ms[fs_idx]; move16(); + IF (sub(fs_idx, 4) == 0) + { + n_bands = 60; move16(); + } + BREAK; + case 50: + band_offsets = bands_offset_lin_5ms[fs_idx]; move16(); + IF (sub(fs_idx, 2) == 0) + { + n_bands = 40; move16(); + } + BREAK; +# ifdef CR8_G_ADD_75MS + case 75: + band_offsets = bands_offset_lin_7_5ms[fs_idx]; move16(); +# ifdef ENABLE_HR_MODE + IF (sub(fs_idx, 5) != 0) + { +# endif + IF (sub(fs_idx, 3) != 0) + { + n_bands = 60; move16(); + } +# ifdef ENABLE_HR_MODE + } +# endif + BREAK; +# endif + case 100: + band_offsets = bands_offset_lin[fs_idx]; move16(); + BREAK; + } + + FOR (i = 0; i < yLen; i++) + { + q_old_d_fx32[i] = L_deposit_h(q_old_d_fx[i]); + } + + /* LPC Analysis */ + /* calculate per band energy*/ + processPerBandEnergy_fx(d2_fx, &d2_fx_exp, q_old_d_fx32, *q_old_fx_exp, band_offsets, fs_idx, n_bands, + 1, frame_dms, buffer_perBandEnergy +#ifdef ENABLE_HR_MODE + , hrmode +#endif + ); + + /* calculate pre-emphasis */ + processPreEmphasis_fx(d2_fx, &d2_fx_exp, fs_idx, n_bands, frame_dms, buffer_preEmphasis); + + /* inverse ODFT */ + processInverseODFT_fx(r_fx, &r_fx_exp, d2_fx, d2_fx_exp, n_bands, plcAd->tdc_lpc_order, buffer_InverseODFT); + + /* lag windowing */ + processLagwin_fx(r_fx, lag_win[fs_idx], plcAd->tdc_lpc_order); + + /* Levinson Durbin */ + processLevinson_fx(tdc_A_32, r_fx, plcAd->tdc_lpc_order, NULL, NULL, buffer_Levinson); + + /* 32Q27 -> 16Qx */ + processPLCLpcScaling_fx(tdc_A_32, plcAd->tdc_A, add(plcAd->tdc_lpc_order, 1)); + } + + /* call TD-PLC */ + /* Q_syn = plcAd->q_fx_old_exp; */ /* makes q_fx_old_exp + available in processTimeDomainConcealment_Apply_fx() for + debugging */ + processTimeDomainConcealment_Apply_fx( + old_pitch_int, plcAd->tdc_preemph_fac, plcAd->tdc_A, plcAd->tdc_lpc_order, plcAd->x_old_tot_fx, frame_length, frame_dms, + fs_idx, nbLostFramesInRow, sub(frame_length, la_zeroes), plcAd->stab_fac, &plcAd->tdc_fract, + &plcAd->tdc_seed, + &plcAd->tdc_gain_c, x_fx, &Q_syn, damping, + plcAd->max_len_pcm_plc, + plcAd->harmonicBuf_fx, plcAd->synthHist_fx, &plcAd->harmonicBuf_Q, scratchBuffer +#ifdef CR9_I_INC_TDC_FADEOUT_LEN + , plcAd->plc_fadeout_type +#endif +#ifdef CR10_A_ATTENUATION_CURVE_SELECTOR + , alpha_type_2_table +#endif +); + + /* exponent of TD-PLC output */ + Q_syn = add(Q_syn, sub(15, plcAd->q_fx_old_exp)); + *q_fx_exp = sub(15, Q_syn); move16(); + + /* TDAC */ + processTdac_fx(ola_mem, ola_mem_exp, x_fx, *q_fx_exp, w, la_zeroes, frame_length, buffer_tdac); + BREAK; + + case LC3_CON_TEC_NS_ADV: + *q_fx_exp = *q_old_fx_exp; move16(); + + /* call Noise Substitution */ + processPLCNoiseSubstitution_fx(q_d_fx, q_old_d_fx, yLen); + + BREAK; + default: ASSERT(!"Unsupported PLC method!"); + } + } + + Dyn_Mem_Deluxe_Out(); +} + + diff --git a/lib_lc3plus/plc_classify_fx.c b/lib_lc3plus/plc_classify_fx.c new file mode 100644 index 0000000000000000000000000000000000000000..cf455e68dc7717fad0bd00fa8485d9fc3b24a3cb --- /dev/null +++ b/lib_lc3plus/plc_classify_fx.c @@ -0,0 +1,424 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.5 * +* 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 "defines.h" +#include "functions.h" + +#ifdef CR8_A_PLC_FADEOUT_TUNING + +static Word32 change_bit_at_position(Word32 value, Word8 bit_position, UWord8 bit) +{ + Word32 helper_mask = ~L_shl_pos(1, bit_position); + Word32 tmp = L_and(value, helper_mask); + tmp = L_or(tmp, L_shl_pos(bit, bit_position)); + return tmp; +} + +static void update_bit_and_byte_positions(Word16 longterm_analysis_counter_max_bytebuffer, Word8 *byte_position, Word8 *bit_position) +{ +#ifdef CR11_A_FIX_IN_PLC_LONGTERM_STATISTIC + IF (sub(*bit_position, 29) == 0) +#else + IF (sub(*bit_position, 30) == 0) +#endif + { + *bit_position = 0; move16(); + + if (sub(*byte_position, longterm_analysis_counter_max_bytebuffer) < -1) + { + *byte_position = add(*byte_position, 1); + } else { + *byte_position = 0; move16(); + } + } ELSE { + *bit_position = add(*bit_position, 1); + } +} + +static void array_insert_and_shift(Word32 *array, UWord8 value, Word16 longterm_analysis_counter_max, Word16 *overall_counter, Word8 *byte_position, Word8 *bit_position) +{ + Word32 current_byte = 0; + +#ifdef WMOPS + push_wmops("PLC::array_insert_and_shift"); +#endif + + IF( overall_counter != NULL) + { + *overall_counter = s_min(add(*overall_counter, 1), longterm_analysis_counter_max); + } + + current_byte = array[*byte_position]; move16(); + current_byte = change_bit_at_position(current_byte, *bit_position, value); + array[*byte_position] = current_byte; move16(); + +#ifdef WMOPS + pop_wmops(); +#endif +} + +#ifdef CR9_L_RETRAIN_FADEOUT_TYPE_CLASSIFIER +static void array_calculate(Word32 *array_tdc, Word32 *array_ns, int length, Word16 *counter_tdc, Word16 *counter_ns, Word16 longterm_analysis_counter_max) +#else +static void array_calculate(Word32 *array_tdc, Word32 *array_ns, int length, Word16 *counter_tdc, Word16 *counter_ns, Word16 *counter_phecu, Word16 overall_counter, Word16 longterm_analysis_counter_max) +#endif +{ + int i, k; + Word32 current_byte_tdc = 0, current_byte_ns = 0; + Word16 counter_loc_tdc = 0, counter_loc_ns = 0, counter_tmp = 0; + +#ifdef WMOPS + push_wmops("PLC::array_calculate"); +#endif + + 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 = sub(sub(overall_counter, counter_loc_tdc), counter_loc_ns); +#endif +#ifdef WMOPS + pop_wmops(); +#endif +} +#endif + +static Word16 spectral_centroid_fx_lc(Word16 old_scf_q[], const Word16 *band_offsets, Word16 bands_number, Word16 frame_length, + Word16 fs_idx, Word8 *scratchBuffer +# ifdef ENABLE_HR_MODE + , Word16 hrmode +# endif + ); + +void processPLCclassify_fx(Word16 plcMeth, Word16 *concealMethod, Word16 *nbLostFramesInRow, Word16 bfi, + Word16 ltpf_mem_pitch_int, Word16 frame_length, Word16 frame_dms, Word16 fs_idx, Word16 yLen, + Word16 q_old_d_fx[], const Word16 *band_offsets, Word16 bands_number, AplcSetup *plcAd, Word8 *scratchBuffer +# ifdef ENABLE_HR_MODE + , Word16 hrmode +# endif + ) +{ + Dyn_Mem_Deluxe_In( + Word16 scQ15; + Word32 class; + ); + +#ifdef WMOPS + push_wmops("PLC::processPLCclassify_fx"); +#endif + + UNUSED(yLen); + UNUSED(q_old_d_fx); + + if (plcAd) + { + plcAd->norm_corrQ15_fx = 0; move16(); + } + +#ifdef CR8_A_PLC_FADEOUT_TUNING + /* assert(bfi != 2 && "Error bfi flag value, state of fadeout cntr is affected by PartialConcealment here "); */ + /* Save statistics for 24 kHz, 48 kHz and 96 kHz */ + IF((sub(bfi, 1) == 0) || (((bfi >= 0) && (sub(bfi, 2) <= 0)) && ((sub(fs_idx, 2) == 0) || (sub(fs_idx, 4) == 0) || (sub(fs_idx, 5) == 0)))) /* note for PC bfi==2 is possible */ +#else + IF (sub(bfi, 1) == 0) +#endif + { + /* increase counter of lost-frames-in-a-row */ +#ifdef CR8_A_PLC_FADEOUT_TUNING + IF (sub(bfi, 1) == 0) + { + *nbLostFramesInRow = add(*nbLostFramesInRow, 1); + *nbLostFramesInRow = s_min(*nbLostFramesInRow, 0x100); + } +#else + *nbLostFramesInRow = add(*nbLostFramesInRow, 1); + *nbLostFramesInRow = s_min(*nbLostFramesInRow, 0x100); +#endif + +#ifdef CR8_A_PLC_FADEOUT_TUNING + /*assert((bfi != 2) && "PartialConcealment checked vs bfi==0 can cause issues "); */ + IF ((sub(*nbLostFramesInRow, 1) == 0) || (bfi != 1) ) /* was "|| (bfi==0)" , NB only test bfi vs "1" as bfi can have the states [0(good),1(bad),2(good,partialConcealment) } */ +#else + IF (sub(*nbLostFramesInRow, 1) == 0) +#endif + { + *concealMethod = plcMeth; move16(); + + IF(sub(plcMeth, 1) == 0) + { + IF(ltpf_mem_pitch_int > 0) + { + *concealMethod = LC3_CON_TEC_TDPLC; move16(); /* TD-PLC */ + /* Calculate Features */ + + plcAd->norm_corrQ15_fx = plc_xcorr_lc_fx(plcAd->x_old_tot_fx, plcAd->max_len_pcm_plc, ltpf_mem_pitch_int, fs_idx); + scQ15 = spectral_centroid_fx_lc(plcAd->old_scf_q, band_offsets, bands_number, frame_length, + fs_idx, scratchBuffer +#ifdef ENABLE_HR_MODE + , hrmode +#endif + ); + + /* Classify */ + class = L_mult(plcAd->norm_corrQ15_fx, 7640); + class = L_mac(class, scQ15, -32768); + class = L_add_sat(class, -335020208); + + IF(class <= 0) + { +#ifdef ENABLE_HR_MODE + IF((frame_dms == 100) && (hrmode == 0)) +#else + IF(frame_dms == 100) +#endif + { + *concealMethod = LC3_CON_TEC_PHASE_ECU; move16(); /* Phase ECU 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 = LC3_CON_TEC_NS_ADV; move16(); /* 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 = LC3_CON_TEC_NS_ADV; move16(); /* 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 + } + + } + } + + Dyn_Mem_Deluxe_Out(); +#ifdef WMOPS + pop_wmops(); +#endif +} + + +Word16 spectral_centroid_fx_lc(Word16 old_scf_q[], const Word16 *band_offsets, Word16 bands_number, Word16 frame_length, + Word16 fs_idx, Word8 *scratchBuffer +#ifdef ENABLE_HR_MODE + , Word16 hrmode +#endif + ) +{ + Dyn_Mem_Deluxe_In( + Counter i, j; + Word32 den32, num32, tmp32; + Word16 s, sc, fac, freq, inv, startfreq, stopfreq; + Word16 s2; + Word16 *old_scf_q_mod; + Word16 *old_scf_q_mod_exp; + Word16 *band_offsets_local; + ); +#ifdef WMOPS + push_wmops("PLC::spectral_centroid_fx_lc"); +#endif + +#ifdef ENABLE_HR_MODE + s2 = 0; +#else + UNUSED(s2); +#endif + + + old_scf_q_mod = (Word16 *)scratchAlign(scratchBuffer, 0); /* Size = 2 * M */ + old_scf_q_mod_exp = (Word16 *)scratchAlign(old_scf_q_mod, sizeof(*old_scf_q_mod) * M); /* Size = 2 * M */ + band_offsets_local = (Word16 *)scratchAlign(old_scf_q_mod_exp, sizeof(*old_scf_q_mod_exp) * (M)); /* Size = 2 * bands_number */ + + /* Linear Domain */ + FOR (i = 0; i < M; i++) + { + old_scf_q_mod[i] = BASOP_Util_InvLog2_16(old_scf_q[i], &old_scf_q_mod_exp[i]); + } + + /* De-emphasis */ + FOR (i = 0; i < M; i++) + { + old_scf_q_mod[i] = mult(old_scf_q_mod[i], lpc_warp_dee_emphasis[fs_idx][i]); move16(); + old_scf_q_mod_exp[i] = add(old_scf_q_mod_exp[i], lpc_warp_dee_emphasis_e[fs_idx][i]); move16(); + } + + IF (sub(bands_number, 64) == 0) + { + basop_memmove(band_offsets_local, band_offsets, (bands_number + 1) * sizeof(Word16)); + } + IF (sub(bands_number, 32) < 0) + { + band_offsets_local[0] = 0; move16(); + s = sub(32, bands_number); + FOR (i = sub(bands_number, 1); i >= s; i--) + { + band_offsets_local[(i + s) * 2 + 1 + 1] = band_offsets[i + 1]; move16(); + band_offsets_local[(i + s) * 2 + 0 + 1] = band_offsets[i + 1]; move16(); + } + FOR (i = sub(s, 1); i >= 0; i--) + { + band_offsets_local[i * 4 + 3 + 1] = band_offsets[i + 1]; move16(); + band_offsets_local[i * 4 + 2 + 1] = band_offsets[i + 1]; move16(); + band_offsets_local[i * 4 + 1 + 1] = band_offsets[i + 1]; move16(); + band_offsets_local[i * 4 + 0 + 1] = band_offsets[i + 1]; move16(); + } + } + ELSE + IF (sub(bands_number, 64) < 0) + { + band_offsets_local[0] = 0; move16(); + s = sub(64, bands_number); + FOR (i = sub(bands_number, 1); i >= s; i--) + { + band_offsets_local[i + s + 1] = band_offsets[i + 1]; move16(); + } + FOR (i = sub(s, 1); i >= 0; i--) + { + band_offsets_local[i * 2 + 1 + 1] = band_offsets[i + 1]; move16(); + band_offsets_local[i * 2 + 0 + 1] = band_offsets[i + 1]; move16(); + } + } + + den32 = 1; move16(); + num32 = 0; move16(); + inv = div_s(1, frame_length); + + FOR (i = 0; i < M; i++) + { + freq = 0; move16(); + startfreq = add(band_offsets_local[i * 4], 1); + stopfreq = band_offsets_local[i * 4 + 4]; + +# ifdef ENABLE_HR_MODE + IF (hrmode != 0) + { + tmp32 = 0; move32(); + FOR (j = startfreq; j <= stopfreq; j++) + { + tmp32 = L_add(tmp32, j); + } + + s2 = norm_l(tmp32); + freq = extract_h(L_shl(tmp32, s2)); + s2 = sub(add(15, s2), 31); + tmp32 = L_mult(inv, freq); + s = norm_l(tmp32); + } + ELSE +# endif + { + FOR (j = startfreq; j <= stopfreq; j++) + { + freq = add(freq, j); + } + + tmp32 = L_mult(inv, freq); + s = norm_l(tmp32); + } + + tmp32 = L_mult(old_scf_q_mod[i], extract_h(L_shl(tmp32, s))); + +# ifdef ENABLE_HR_MODE + if (hrmode != 0) + { + s = add(s, s2); + } +# endif + + num32 = L_add(num32, L_shl(tmp32, add(add(-15, old_scf_q_mod_exp[i]), sub(15, s)))); + den32 = L_add(den32, L_shl(L_mult(old_scf_q_mod[i], stopfreq - startfreq + 1), old_scf_q_mod_exp[i])); + } + + s = norm_l(den32); + s = sub(16, s); + + sc = div_s(extract_l(L_shr(num32, s)), extract_l(L_shr(den32, s))); + + SWITCH (fs_idx) + { + case 0: + fac = 5461; move16(); + BREAK; + case 1: + fac = 10922; move16(); + BREAK; + case 2: + fac = 16384; move16(); + BREAK; + case 3: + fac = 21845; move16(); + BREAK; + default: /* case 4: */ + fac = 32767; move16(); + BREAK; + } + sc = round_fx(L_mult(sc, fac)); +# ifdef ENABLE_HR_MODE + if (sub(fs_idx, 5) == 0) + { + sc = shl_pos(sc, 1); + } +# endif + + Dyn_Mem_Deluxe_Out(); +#ifdef WMOPS + pop_wmops(); +#endif + return sc; +} + + diff --git a/lib_lc3plus/plc_damping_scrambling_fx.c b/lib_lc3plus/plc_damping_scrambling_fx.c new file mode 100644 index 0000000000000000000000000000000000000000..4c5641634867f3d803b0e10028851d98a7294e67 --- /dev/null +++ b/lib_lc3plus/plc_damping_scrambling_fx.c @@ -0,0 +1,430 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.5 * +* 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 "defines.h" +#include "functions.h" + +void processPLCDampingScrambling_main_fx(Word16 bfi, Word16 concealMethod, Word16 ns_nbLostFramesInRow, Word16 *cum_fflcAtten, + Word16 pc_nbLostFramesInRow, Word16 *ns_seed, Word16 *pc_seed, Word16 pitch_present_bfi1, + Word16 pitch_present_bfi2, Word32 spec[], Word16 *q_fx_exp, Word16 *q_old_d_fx, + Word16 *q_old_fx_exp, Word16 L_spec, Word16 stabFac, Word16 frame_dms, + Word16 *cum_fading_slow, Word16 *cum_fading_fast, Word16 spec_inv_idx +#ifdef CR8_A_PLC_FADEOUT_TUNING + , UWord8 plc_fadeout_type +#endif + ) +{ + Dyn_Mem_Deluxe_In( + Word16 processDampScramb; + ); + + IF ( bfi != 0 ) + { + processDampScramb = 0; move16(); + test(); + IF (sub(concealMethod, LC3_CON_TEC_NS_ADV) == 0 || sub(bfi, 2) == 0) + { + processDampScramb = 1; move16(); + } + +#ifdef CR8_A_PLC_FADEOUT_TUNING + IF (sub(ns_nbLostFramesInRow, 1) == 0) + { + *cum_fading_slow = 32767; move16(); + *cum_fading_fast = 32767; move16(); + *cum_fflcAtten = 32767; move16(); + } +#endif + + IF (sub(bfi, 1) == 0) + { + processPLCDampingScrambling_fx(spec, L_spec, ns_nbLostFramesInRow, stabFac, + processDampScramb, cum_fflcAtten, + pitch_present_bfi1, frame_dms, cum_fading_slow, + cum_fading_fast, ns_seed, 0 +#ifdef CR8_A_PLC_FADEOUT_TUNING + , plc_fadeout_type +#endif + ); + } + ELSE /* bfi == 2 */ + { + processPLCDampingScrambling_fx(spec, L_spec, pc_nbLostFramesInRow, stabFac, + processDampScramb, cum_fflcAtten, + pitch_present_bfi2, frame_dms, cum_fading_slow, + cum_fading_fast, pc_seed, spec_inv_idx +#ifdef CR8_A_PLC_FADEOUT_TUNING + , plc_fadeout_type +#endif + ); + + processPLCupdateSpec_fx(q_old_d_fx, q_old_fx_exp, spec, q_fx_exp, L_spec); + } + } + Dyn_Mem_Deluxe_Out(); +} + +void processPLCDampingScrambling_fx(Word32 spec[], Word16 L_spec, Word16 nbLostFramesInRow, Word16 stabFac, Word16 processDampScramb, + Word16 *cum_fflcAtten, Word16 pitch_present, Word16 frame_dms, Word16 *cum_fading_slow, + Word16 *cum_fading_fast, Word16 *seed, Word16 spec_inv_idx +#ifdef CR8_A_PLC_FADEOUT_TUNING + , UWord8 plc_fadeout_type +#endif + ) +{ + Counter i; + Word16 lossDuration_dms, slow, fast, tmp16; + Word16 plc_start_inFrames, plc_end_inFrames, plc_duration_inFrames, linFuncStartStop; + Word16 randThreshold, ad_threshFac, energThreshold, s, s2, s3, mean_energy16; + Word32 frame_energy, mean_nrg, fac; + Word16 fflcAtten, cum_fading_slow_local, cum_fading_fast_local; + +#ifdef DYNMEM_COUNT + Dyn_Mem_In("processPLCDampingScrambling_fx", sizeof(struct { + Counter i; + Word16 lossDuration_dms, slow, fast, tmp16; + Word16 plc_start_inFrames, plc_end_inFrames, plc_duration_inFrames, linFuncStartStop; + Word16 randThreshold, ad_threshFac, energThreshold, s, s2, s3, mean_energy16; + Word32 frame_energy, mean_nrg, fac; + Word16 fflcAtten, cum_fading_slow_local, cum_fading_fast_local; + })); +#endif + + /** preparation */ +#ifndef CR8_A_PLC_FADEOUT_TUNING + /* init cummulative damping factors at first loss */ + IF (sub(nbLostFramesInRow, 1) == 0) + { + *cum_fading_slow = 32767; move16(); + *cum_fading_fast = 32767; move16(); + *cum_fflcAtten = 32767; move16(); + } +#endif + + /* get damping factors */ + tmp16 = mult(6554 /*0.2*/, stabFac); + slow = add(26214 /*0.8*/, tmp16); + fast = add( 9830 /*0.3*/, tmp16); + + + SWITCH (frame_dms) + { + case 25: + IF (sub(slow, 32767) < 0) + { + tmp16 = 0; + slow = Sqrt16_lc3plus(slow, &tmp16); move16(); + slow = shl(slow, tmp16); + } + IF (sub(slow, 32767) < 0) + { + tmp16 = 0; + slow = Sqrt16_lc3plus(slow, &tmp16); move16(); + slow = shl(slow, tmp16); + } + IF (sub(fast, 32767) < 0) + { + tmp16 = 0; + fast = Sqrt16_lc3plus(fast, &tmp16); move16(); + fast = shl(fast, tmp16); + } + IF (sub(fast, 32767) < 0) + { + tmp16 = 0; + fast = Sqrt16_lc3plus(fast, &tmp16); move16(); + fast = shl(fast, tmp16); + } + BREAK; + case 50: + IF (sub(slow, 32767) < 0) + { + tmp16 = 0; + slow = Sqrt16_lc3plus(slow, &tmp16); move16(); + slow = shl(slow, tmp16); + } + IF (sub(fast, 32767) < 0) + { + tmp16 = 0; + fast = Sqrt16_lc3plus(fast, &tmp16); move16(); + fast = shl(fast, tmp16); + } + BREAK; +#ifdef ENABLE_075_DMS_MODE +# ifdef CR8_G_ADD_75MS + case 75: + IF (sub(slow, 32767) < 0) + { + slow = mult(slow, mult(slow, slow)); + } + IF (sub(slow, 32767) < 0) + { + tmp16 = 0; + slow = Sqrt16_lc3plus(slow, &tmp16); move16(); + slow = shl(slow, tmp16); + } + IF (sub(slow, 32767) < 0) + { + tmp16 = 0; + slow = Sqrt16_lc3plus(slow, &tmp16); move16(); + slow = shl(slow, tmp16); + } + IF (sub(fast, 32767) < 0) + { + fast = mult(fast, mult(fast, fast)); + } + IF (sub(fast, 32767) < 0) + { + tmp16 = 0; + fast = Sqrt16_lc3plus(fast, &tmp16); move16(); + fast = shl(fast, tmp16); + } + IF (sub(fast, 32767) < 0) + { + tmp16 = 0; + fast = Sqrt16_lc3plus(fast, &tmp16); move16(); + fast = shl(fast, tmp16); + } + BREAK; +# endif +#endif + } + +#ifdef CR8_A_PLC_FADEOUT_TUNING + if (plc_fadeout_type == 0) + { +#endif + *cum_fading_slow = mult_r(*cum_fading_slow, slow); + *cum_fading_fast = mult_r(*cum_fading_fast, fast); +#ifdef CR8_A_PLC_FADEOUT_TUNING + } +#endif + + IF ( sub(processDampScramb, 1) == 0 ) + { +#ifdef CR8_A_PLC_FADEOUT_TUNING + if (plc_fadeout_type != 0) + { + Word16 lost_frame_thr1 = 4; + Word16 lost_frame_thr2 = 8; + + SWITCH (frame_dms) + { + case 25: + lost_frame_thr1 = 16; + lost_frame_thr2 = 32; + BREAK; + case 50: + lost_frame_thr1 = 8; + lost_frame_thr2 = 16; + BREAK; +#ifdef ENABLE_075_DMS_MODE +# ifdef CR8_G_ADD_75MS + case 75: + lost_frame_thr1 = 6; + lost_frame_thr2 = 11; +# endif +#endif + } + IF (sub(nbLostFramesInRow, lost_frame_thr1) < 0) + { + cum_fading_slow_local = 32767; move16(); + } + ELSE IF (sub(nbLostFramesInRow, lost_frame_thr2) < 0) + { + cum_fading_slow_local = 29491; move16(); + } + ELSE + { + cum_fading_slow_local = 27852; move16(); + } + + *cum_fading_slow = mult_r(*cum_fading_slow, cum_fading_slow_local); move16(); + cum_fading_slow_local = *cum_fading_slow; move16(); + } else { +#endif + /** rapid fading for FFLC */ + fflcAtten = 32767; move16(); + cum_fading_slow_local = *cum_fading_slow; move16(); + cum_fading_fast_local = *cum_fading_fast; move16(); + + IF (spec_inv_idx == 0) + { + lossDuration_dms = DEPR_i_mult(nbLostFramesInRow, frame_dms); + IF (sub(lossDuration_dms, PLC_FADEOUT_IN_MS*10) > 0) + { + *cum_fflcAtten = 0; move16(); + fflcAtten = 0; move16(); + } + ELSE IF (sub(lossDuration_dms, 200) > 0) + { + SWITCH (frame_dms) + { + case 25: fflcAtten = PLC34_ATTEN_FAC_025_FX; BREAK; + case 50: fflcAtten = PLC34_ATTEN_FAC_050_FX; BREAK; +#ifdef ENABLE_075_DMS_MODE +# ifdef CR8_G_ADD_75MS + case 75: fflcAtten = PLC34_ATTEN_FAC_075_FX; BREAK; +# endif +#endif + case 100: fflcAtten = PLC34_ATTEN_FAC_100_FX; BREAK; + } + } + IF ( sub(fflcAtten, 32767) < 0 ) + { + *cum_fflcAtten = mult_r(*cum_fflcAtten, fflcAtten); + cum_fading_slow_local = mult_r(*cum_fading_slow, *cum_fflcAtten); + cum_fading_fast_local = mult_r(*cum_fading_fast, *cum_fflcAtten); + } + } + + /** prepare fade-out function */ + /* being 1 up to plc_start_inFrames, being 0 starting with + plc_end_inFrames; decreasing linearly in between */ + SWITCH (frame_dms) + { + case 25: + plc_start_inFrames = (10*PLC4_TRANSIT_START_IN_MS) / 25; move16(); + plc_end_inFrames = (10*PLC4_TRANSIT_END_IN_MS) / 25; move16(); + BREAK; + case 50: + plc_start_inFrames = (10*PLC4_TRANSIT_START_IN_MS) / 50; move16(); + plc_end_inFrames = (10*PLC4_TRANSIT_END_IN_MS) / 50; move16(); + BREAK; +#ifdef ENABLE_075_DMS_MODE +# ifdef CR8_G_ADD_75MS + case 75: + plc_start_inFrames = (10*PLC4_TRANSIT_START_IN_MS) / 75; move16(); + plc_end_inFrames = (10*PLC4_TRANSIT_END_IN_MS) / 75; move16(); + BREAK; +# endif +#endif + default: + plc_start_inFrames = (10*PLC4_TRANSIT_START_IN_MS) / 100; move16(); + plc_end_inFrames = (10*PLC4_TRANSIT_END_IN_MS) / 100; move16(); + } + + if (pitch_present == 0) + { + plc_start_inFrames = 1; move16(); + } + plc_duration_inFrames = sub(plc_end_inFrames, plc_start_inFrames); + + IF (sub(nbLostFramesInRow, plc_start_inFrames) <= 0) + { + linFuncStartStop = 32767; move16(); + } + ELSE IF (sub(nbLostFramesInRow, plc_end_inFrames) >= 0) + { + linFuncStartStop = 0; move16(); + } + ELSE + { + /* + x = xLostFramesInRow; + m = -1 / plc_duration_inFrames; + b = -plc_end_inFrames; % shift on x axis + linFuncStartStop = m * (x + b); + */ + linFuncStartStop = div_s(sub(plc_end_inFrames, nbLostFramesInRow), plc_duration_inFrames); + } + + /** sign scrambling */ + randThreshold = mult(-32768, linFuncStartStop); +#ifdef CR8_A_PLC_FADEOUT_TUNING + } +#endif + + tmp16 = *seed; move16(); + FOR (i = spec_inv_idx; i < L_spec; i++) + { + tmp16 = extract_l(L_mac0(16831, tmp16, 12821)); + + IF (tmp16 < 0) + { + test(); +#ifdef CR8_A_PLC_FADEOUT_TUNING + if (plc_fadeout_type != 0 || pitch_present == 0 || sub(tmp16, randThreshold) < 0 ) +#else + if (pitch_present == 0 || sub(tmp16, randThreshold) < 0) +#endif + { + spec[i] = L_negate(spec[i]); + } + } + + } + *seed = tmp16; move16(); + +#ifdef CR8_A_PLC_FADEOUT_TUNING + if (plc_fadeout_type == 0) + { +#endif + /** adaptive damping */ + tmp16 = mult(18022 /* 10 - 1.2 */, linFuncStartStop); + ad_threshFac = add(shr(tmp16, 1), 1228 /* 1.2 >> 1 */); /* exp = 5 */ + + s = getScaleFactor32_lc3plus(&spec[spec_inv_idx], sub(L_spec, spec_inv_idx)); + frame_energy = 0; move32(); + FOR (i = spec_inv_idx; i < L_spec; i++) + { + tmp16 = extract_h(L_shl_sat(spec[i], sub(s, 4))); + frame_energy = L_mac0(frame_energy, tmp16, tmp16); /* exp = -(2*(s-16) - 8) */ + } + mean_energy16 = BASOP_Util_Divide3216_Scale_lc3plus(frame_energy, sub(L_spec, spec_inv_idx), &s2); /* exp = -(2*(s-16) - 8) + 16 - (15-s2) */ + + energThreshold = mult(ad_threshFac, mean_energy16); /* exp = -(2*(s-16) - 8) + 16 - (15-s2) + 5 */ + + s3 = add(sub(29, shl(sub(s, 16), 1)), s2); + IF (sub(energThreshold, 32767) < 0) + { + energThreshold = Sqrt16_lc3plus(energThreshold, &s3); + } + s3 = sub(s3, 15); + + mean_nrg = L_shl_sat(L_deposit_l(energThreshold), s3); /* exp = 0 */ + fac = mult(sub(cum_fading_slow_local, cum_fading_fast_local), energThreshold); + fac = L_shl_sat(L_deposit_l(fac), s3); /* exp = 0 */ +#ifdef CR8_A_PLC_FADEOUT_TUNING + } +#endif + + FOR (i = spec_inv_idx; i < L_spec; i++) + { +#ifdef CR8_A_PLC_FADEOUT_TUNING + if ( ( plc_fadeout_type != 0 ) || (L_sub(L_abs(spec[i]), mean_nrg) < 0) ) +#else + if (L_sub(L_abs(spec[i]), mean_nrg) < 0) +#endif + { + spec[i] = Mpy_32_16_lc3plus(spec[i], cum_fading_slow_local); + } + else + { + if (spec[i] > 0) + { + spec[i] = L_add_sat(Mpy_32_16_lc3plus(spec[i], cum_fading_fast_local), fac); + } + else if (spec[i] == 0) + { + spec[i] = Mpy_32_16_lc3plus(spec[i], cum_fading_fast_local); + } + else + { + spec[i] = L_sub_sat(Mpy_32_16_lc3plus(spec[i], cum_fading_fast_local), fac); + } + } + } + } + +#ifdef DYNMEM_COUNT + Dyn_Mem_Out(); +#endif +} + + diff --git a/lib_lc3plus/plc_lpc_scaling_fx.c b/lib_lc3plus/plc_lpc_scaling_fx.c new file mode 100644 index 0000000000000000000000000000000000000000..85ffbf9422cf3517b0535cfdf573d3c6399320c1 --- /dev/null +++ b/lib_lc3plus/plc_lpc_scaling_fx.c @@ -0,0 +1,36 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.5 * +* 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 "defines.h" +#include "functions.h" + +void processPLCLpcScaling_fx(Word32 tdc_A_32[], Word16 tdc_A_16[], Word16 m) +{ + Counter i; + Word16 s; + +#ifdef DYNMEM_COUNT + Dyn_Mem_In("processPLCLpcScaling_fx", sizeof(struct { + Counter i; + Word16 s; + })); +#endif + + s = getScaleFactor32_lc3plus(tdc_A_32, m); + FOR (i = 0; i < m; i++) + { + tdc_A_16[i] = round_fx_sat(L_shl_sat(tdc_A_32[i], s)); move16(); + } + +#ifdef DYNMEM_COUNT + Dyn_Mem_Out(); +#endif +} + + diff --git a/lib_lc3plus/plc_main_fx.c b/lib_lc3plus/plc_main_fx.c new file mode 100644 index 0000000000000000000000000000000000000000..1948aa23a0683361b7fac146f6c6749e2c157d1f --- /dev/null +++ b/lib_lc3plus/plc_main_fx.c @@ -0,0 +1,85 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.5 * +* 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 "defines.h" +#include "functions.h" + +void processPLCmain_fx(Word16 plcMeth, Word16 *concealMethod, Word16 *nbLostFramesInRow, Word16 bfi, Word16 prev_bfi, + Word16 frame_length, Word16 la_zeroes, +#ifdef ENABLE_HR_MODE + const Word32 w[], +#else + const Word16 w[], +#endif + Word16 x_fx[], Word16 ola_mem[], + Word16 *ola_mem_exp, Word16 q_old_d_fx[], Word16 *q_old_fx_exp, Word32 q_d_fx[], + Word16 *q_fx_exp, Word16 yLen, Word16 fs_idx, const Word16 *band_offsets, Word16 bands_number, Word16 *damping, + Word16 old_pitch_int, Word16 old_pitch_fr, Word16 *ns_cum_alpha, Word16 *ns_seed, + AplcSetup *plcAd, Word16 frame_dms, Word8 *scratchBuffer, Word16 *pc_nbLostFramesInRow +#ifdef ENABLE_HR_MODE + , Word16 hrmode +#endif +#ifdef CR9_N_SHORT_FADE_FOR_UNSTABLE_PITCH + ,Word32 rel_pitch_change +#endif +#ifdef CR10_A_ATTENUATION_CURVE_SELECTOR + ,Word16 *alpha_type_2_table +#endif +) +{ + IF(sub(bfi, 1) == 0 && plcAd) + { + /* FFLC increases the PFLC counter */ + *pc_nbLostFramesInRow = add(*pc_nbLostFramesInRow, 1); + } + + processPLCclassify_fx(plcMeth, concealMethod, nbLostFramesInRow, bfi, old_pitch_int, frame_length, frame_dms, + fs_idx, yLen, q_old_d_fx, band_offsets, bands_number, plcAd, scratchBuffer +#ifdef ENABLE_HR_MODE + , hrmode +#endif + ); + + processPLCapply_fx( +#ifdef CR8_A_PLC_FADEOUT_TUNING + concealMethod, +#else + *concealMethod, +#endif + *nbLostFramesInRow, bfi, prev_bfi, frame_length, la_zeroes, w, x_fx, ola_mem, + ola_mem_exp, q_old_d_fx, q_old_fx_exp, q_d_fx, q_fx_exp, yLen, fs_idx, damping, old_pitch_int, + old_pitch_fr, ns_cum_alpha, ns_seed, frame_dms, plcAd, scratchBuffer +#ifdef ENABLE_HR_MODE + , hrmode +#endif +#ifdef CR9_N_SHORT_FADE_FOR_UNSTABLE_PITCH + , rel_pitch_change +#endif +#ifdef CR10_A_ATTENUATION_CURVE_SELECTOR + , alpha_type_2_table +#endif + ); + + IF (bfi == 0) + { + processPLCupdateSpec_fx(q_old_d_fx, q_old_fx_exp, q_d_fx, q_fx_exp, yLen); + } + +#ifdef ENABLE_HR_MODE + IF (plcAd != NULL && (sub(plcAd->PhECU_frame_ms , 10) == 0) && (hrmode == 0)) +#else + IF (plcAd != NULL && (sub(plcAd->PhECU_frame_ms , 10) == 0)) +#endif + { + processPLCspec2shape_fx(prev_bfi, bfi, q_old_d_fx, yLen, plcAd->PhECU_oold_grp_shape_fx, plcAd->PhECU_old_grp_shape_fx); + } + +} + + diff --git a/lib_lc3plus/plc_noise_substitution_fx.c b/lib_lc3plus/plc_noise_substitution_fx.c new file mode 100644 index 0000000000000000000000000000000000000000..ab618ae7e124429afc2721a496bcdb4c5419975c --- /dev/null +++ b/lib_lc3plus/plc_noise_substitution_fx.c @@ -0,0 +1,32 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.5 * +* 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 "defines.h" +#include "functions.h" + +void processPLCNoiseSubstitution_fx(Word32 spec[], Word16 spec_prev[], Word16 L_spec) +{ + Dyn_Mem_Deluxe_In( + Counter i; + ); + + FOR (i = 0; i < L_spec; i++) + { + spec[i] = L_deposit_h(spec_prev[i]); + } + + /* High pass to prevent overflows */ + spec[0] = Mpy_32_16_lc3plus(spec[0], 6553 /* 0.2 Q15*/); move32(); + spec[1] = Mpy_32_16_lc3plus(spec[1], 16384 /* 0.5 Q15*/); move32(); + + Dyn_Mem_Deluxe_Out(); +} + + + diff --git a/lib_lc3plus/plc_phecu_f0_refine_first_fx.c b/lib_lc3plus/plc_phecu_f0_refine_first_fx.c new file mode 100644 index 0000000000000000000000000000000000000000..5c01a00299b11d84ce760dbb71d0245f53066c1b --- /dev/null +++ b/lib_lc3plus/plc_phecu_f0_refine_first_fx.c @@ -0,0 +1,100 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.5 * +* 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 "defines.h" +#include "functions.h" + +void plc_phEcu_F0_refine_first_fx(Word16 * plocs, /* i/o */ + const Word16 n_plocs_in, Word32 *L_f0est, /* i/o Q16 */ + const Word16 stPhECU_f0hzLtpBinQ7, const Word16 stPhECU_f0gainLtpQ15, + const Word16 nSubm) + +{ + Counter subm, i; + Word16 ploc, n_plocs_ana; + Word32 L_tmp = 0, L_diff, L_f0EstQ7, L_sensitivity_Q7; + +#ifdef DYNMEM_COUNT + Dyn_Mem_In("plc_phEcu_F0_refine_first_fx", sizeof(struct { + Counter subm, i; + Word16 ploc, n_plocs_ana; + Word32 L_tmp, L_diff, L_f0EstQ7, L_sensitivity_Q7; + })); +#endif + + + + /* single initial peak F0 correction using available LTP information */ + + IF (sub(stPhECU_f0gainLtpQ15, ((Word16)(0.25 * 32768.0))) > 0) + { + ploc = -1; move16(); /* sentinel */ + n_plocs_ana = s_min(n_plocs_in, 4); /* only analyze at first 3 deteteced LF peaks */ + + /* only apply analysis below nsubm*pitmax_freq ~= 1600Hz */ + i = sub(n_plocs_ana, 1); + WHILE (i >= 0 && sub(plocs[i], (Word16)(1600.0 / 62.5)) > 0) + { + i--; + } + n_plocs_ana = add(i, 1); + + IF ((n_plocs_ana > 0)) + { + /* % find/correct first peak in f0est , that is a submultiple of n*f0Ltp*/ + FOR (i = 0; i < n_plocs_ana; i++) + { + + L_sensitivity_Q7 = L_deposit_l(((Word32)1) << (7 - 1)); /* 0.5 in Q7 */ + if (sub(stPhECU_f0gainLtpQ15, ((Word16)(0.75 * 32768.0))) < 0) + { + L_sensitivity_Q7 = L_shr_pos(L_sensitivity_Q7, 1); /* % more picky if correlation is rather low */ + } + + L_f0EstQ7 = L_shr_pos(L_f0est[i], 9); /* Q16 to Q7 */ + + FOR (subm = 1; subm <= nSubm; subm++) + { + /*adjf0 = abs(f0est - subm*stPhECU_f0hzLtpBin*ones(size(f0est))) < sensitivity ; % L1 difference, + vector operation over f0 + ind = find(adjf0==1,1); */ + L_diff = L_msu0(L_f0EstQ7, subm, stPhECU_f0hzLtpBinQ7); + L_diff = L_abs(L_diff); + IF (L_sub(L_diff, L_sensitivity_Q7) < 0) + { + L_tmp = L_shl_pos(L_mult0(subm, stPhECU_f0hzLtpBinQ7), 16 - 7); /* to Q16 */ + ploc = i; move16(); + BREAK; + } + L_sensitivity_Q7 = Mpy_32_16_lc3plus(L_sensitivity_Q7, (Word16)(0.875 * 32768.0 )); /* 2 cycles */ + } /* subm*/ + + IF (ploc >= 0) + { + BREAK; + } + } /* i, n_ploc_ana*/ + } + + if (ploc >= 0) + { + L_f0est[ploc] = L_tmp; move32(); /* in Q16 */ + /*ideally also integer plocs should be updated , e.g. if f0est goes from 1.45(plocs=1) to 1.6(plocs==2) + */ + /* but that is costly and not required as long as corr_phase width is large enough ]*/ + } + } + +#ifdef DYNMEM_COUNT + Dyn_Mem_Out(); +#endif + +} + + diff --git a/lib_lc3plus/plc_phecu_fec_hq_fx.c b/lib_lc3plus/plc_phecu_fec_hq_fx.c new file mode 100644 index 0000000000000000000000000000000000000000..e73a1faa818c1f60af03b5425f3d5b379bac77b9 --- /dev/null +++ b/lib_lc3plus/plc_phecu_fec_hq_fx.c @@ -0,0 +1,3157 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.5 * +* 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 "defines.h" +#include "functions.h" +#include "math.h" /*dbg*/ + +/*---------------------------------------------------------------------* + * Local constants + *---------------------------------------------------------------------*/ + +#define DELTA_CORR 5 /* Tuning parameter - defining range for phase correction around peak */ +#define DELTA_CORR_F0_INT 2 /* Tuning parameter - defining range for phase correction around peak */ + +#define MAX_INCREASE_GRPPOW_FX 0 /* max. amplification in case of transients (in dB scale) */ + +#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 */ +# define SIDE_LIM 12539859L /* 10^ (4.5/20.0) = 2^(a); --> x= 0.747433821 -> Lx_Q24 = round((1L<<(24))*0.747433821)) = 12539859 */ +# define LFHF_LIM 16719812L /* 10^ (6.0/20.0) = 2^(b); --> x= 0.996578428 -> Lx_Q24 = round((1L<<(24))*0.996578428)) = 16719812 */ +#endif + +#ifdef CR8_A_PLC_FADEOUT_TUNING +#else + +#if PLC2_FADEOUT_IN_MS == 0 +#define BURST_ATT_THRESH (4) /* speech start attenuate with losses in a row , stable content is +1 */ +#define ATT_PER_FRAME 2 /* ptr to a table , regular voiced attenuation settings table [0.4 dBx16 frames + 6dBx16 frames] 10 ms frame */ +/* #define ATT_PER_FRAME 1 */ /* ptr to a table , regular attenuation settings table [0.3 dBx16 frames + 6dBx16 frames] 10 ms frame */ +#define BETA_MUTE_THR 20 /* time threshold from BFI start to start of beta-noise further energy attenuation, by .5 each frame */ +/* #define OFF_FRAMES_LIMIT 30 in defines.h , table size and complete zero signal after BURST_ATT_THRESH + OFF_FRAMES_LIMIT */ +#endif + +#if PLC2_FADEOUT_IN_MS != 0 /* TD_PLC muting setting */ + /*% burst attenuation scheme is allowed to be indirectly controlled by a setting from TDC-PLC settings ,if negative PLC2_FADEOUT_IN_MS */ + +#if (PLC2_FADEOUT_IN_MS < 0) +#define FADEOUT_IN_MS PLC_FADEOUT_IN_MS /*% use TDC-SETTING as input */ +#else +#define FADEOUT_IN_MS PLC2_FADEOUT_IN_MS /* % use a PLC2 individual settings as basis */ +#endif + + /* %Examples + % FADEOUT_IN_MS ==30 ms --> shortest setting, att per frame idx = 10 for PLC2 + % FADEOUT_IN_MS ==40 ms --> att per frame idx = 8 setting for PLC2 + % FADEOUT_IN_MS ==60 ms --> att per frame idx = 6 setting for PLC2 (3+4) low decay then fast decay + % FADEOUT_IN_MS ==80 ms --> att per frame idx = 4 setting for PLC2 + % FADEOUT_IN_MS ==100 ms --> att per frame idx = 2 longest = near original setting for PLC2 + */ +#define PLC_P800_SPEECH_FADEOUT_IN_FRAMES (FADEOUT_IN_MS/10) +#define PLC2_FADEOUT_IN_FRAMES MIN(OFF_FRAMES_LIMIT,MAX(6, (3*PLC_P800_SPEECH_FADEOUT_IN_FRAMES))) /* help variable */ + +#define BURST_ATT_THRESH_PRE MIN(5,MAX(1,((1*PLC2_FADEOUT_IN_FRAMES)/6))) /* nominal 10-50 ms to start actual muting, will be thresh +1 */ + +#undef ATT_PER_FRAME +#define ATT_PER_FRAME MIN(10, MAX(2, 2*(6-BURST_ATT_THRESH_PRE))) /* we let the BURST_ATT_THRESH_PRE control the initial table selection */ +/* will eventually become ATT_PER_FRAME-1 = */ + /* table ptr 1,2 --> 16 low decay, 16 high decay, "0" */ + /* table ptr 3,4 --> 8 low decay, 24 high decay, "0" */ + /* table ptr 5,6 --> 4 low decay, 28 high decay , "0"*/ + /* table ptr 7,8 --> 2 low decay, 30 high decay, "0"*/ + /* table ptr 9,10 --> 1 low decay, 31 high decay, "0"*/ +#undef BURST_ATT_THRESH +#define BURST_ATT_THRESH MIN(BURST_ATT_THRESH_PRE, 4 ) /* nominal 10-40 ms, of no regular muting , 20-50 ms */ + + /* beta mute starts to become active when the low decay mute has ended */ +#undef BETA_MUTE_THR +#define BETA_MUTE_THR MIN( 4+(OFF_FRAMES_LIMIT/2)+1 , MAX(4, BURST_ATT_THRESH + 1 +(1<<(BURST_ATT_THRESH_PRE-1)))) /* nominal time to start mandatory decrease of Xavg */ + +#if (ATT_PER_FRAME < 2) || (ATT_PER_FRAME > 10) +#pragma message(" ROM table POW_ATT_TABLES needs update to change the ATT_PER FRAME constants supported are (1),2 (3), 4, (5) ,6 dB/frame ") +#endif + +#else +#if ( ATT_PER_FRAME != 2) +#pragma (" ROM table POW_ATT_TABLES needs update to change the ATT_PER FRAME constants supported are (1),2 dB/frame ") +#endif +#endif + + +#endif + + +#define CMPLMNT_PLOC_SENS_FX 2294 /* (1.0 - p_locator_sens) in Q15 */ +#define FEC_HQ_ECU_ROOT2 23170 /*(0x5a83) */ /* sqrt(2) in Q14 */ +#define FEC_TWOTHIRDS_Q15 21845 /* round(2^15*2/3) */ + +static void get_sin_cosQ10opt(Word16 phase, /* Q10 0..1023 i.e. 1024=2*pi */ + Word16 *ptrSin, /* Q15 */ + Word16 *ptrCos); /* Q15 */ + +static Word16 sqrt2ndOrder(const Word16); + +void my_wtda_fx(const Word16 *new_audio, /* i : input audio to be windowed Q0 20 ms , OPT can be output as well */ + const Word16 *const win2ms_init, /* i: 2 ms initial part of pre_tda window */ + const Word16 *const win16ms_center, /* i: 16 ms combined part of pre_tda IWHR+MDCT-ana */ + Word32 * L_wtda_audio, /* o : tda audio Q16 20 ms */ + const Word16 L, Word8 *scratchBuffer); + +static void windowing_L(const Word16 *, Word32 *, const Word16 *, const Word16, const Word16); +static void windowing_ola(const Word16 *, Word16 *, const Word16 *, const Word16); +static void ola_add(const Word16 *, const Word16 *, Word16 *, const Word16); +static void intlvW32_2_flippedW16(Word32 *L_x, const Word16 numPairs, const Word16 L_prot, Word16 *x); +static void flippedW16_2_intlvW32(Word16 *x, const Word16 numPairs, const Word16 Lprot, Word32 *L_x); +static Word16 imax_fx(const Word16 *, const Word16); + + +Word16 rand_phase_fx(const Word16 seed, Word16 *sin_F, Word16 *cos_F); + +static Word16 imax2_jacobsen_mag_fx(const Word16 *y_re, const Word16 *y_im, const Word16 special); +static void fft_spec2_sqrt_approx_fx(const Word16 x[], Word16 xMagSqrt[], const Word16 N); +static Word16 sqrtMagnApprox_fx(const Word16 re, const Word16 im); + +#ifdef CR8_A_PLC_FADEOUT_TUNING +static Word16 plc_phEcu_nonpure_tone_ana_fx(const Word16* plocs, const Word16 n_plocs, const Word16* X, + const Word32 *L_Xavg, /* i : Frequency group amp averages for tonal tilt analysis pref. Max upshifted */ + const Word16 Lprot, const Word16 fs_idx); +#endif + + +static void rotate_W16_fx(Word16 re_in, Word16 im_in, Word16 cosFactor, Word16 sinFactor, Word16 *re_out_ptr, + Word16 *im_out_ptr) +{ +#ifdef WMOPS + push_wmops("PhECU::rotate_W16_fx"); +#endif + *re_out_ptr = msu_r(L_mult(re_in, cosFactor), im_in, sinFactor); /* 2 ops no move when inlined */ + *im_out_ptr = mac_r(L_mult(re_in, sinFactor), im_in, cosFactor); /* 2 ops no move when inlined */ +#ifdef WMOPS + pop_wmops(); +#endif + return; +} + +static void valley_magnitude_adj_fx(Word16 *re_ptr, Word16 *im_ptr, Word16 uniFactor, Word16 cosFactor) +{ + Word16 scale_fx; +#ifdef WMOPS + push_wmops("PhECU::valley_magnitude_adj_fx"); +#endif + + /* y = 0.5*((2*rand(1,10000) + 1*cos(2*pi*x)) - 1 */ /* y will be in -1 to 1 range */ + /* y = 1*((1*rand(1,10000) + 0.5*cos(2*pi*x)) - 1 */ /* y will be in -1 to 1 range */ + + scale_fx /*Q15*/ = mac_r(L_mult(uniFactor, 16384), cosFactor, 16384); + /* make gain distribution more like N(0,1) than uniform */ + + scale_fx /*Q14*/ = round_fx(L_mac((Word32)(16384L << 16), scale_fx, 4096)); + /* create a random gain scaling value with mean 1.0 and max 1.25 and min 0.75 */ + ASSERT(scale_fx <= (16384 + 8192)); + ASSERT(scale_fx >= (-16384 - 8192)); + *re_ptr = mult_r(scale_fx, shl_sat(*re_ptr, 1)); /* no moves , should be inlined */ + *im_ptr = mult_r(scale_fx, shl_sat(*im_ptr, 1)); /* no moves , should be inlined */ + +#ifdef WMOPS + pop_wmops(); +#endif + return; +} + +/*------------------------------------------------------------------* + * rand_phase() + * + * randomized phase in form of sin and cos components + *------------------------------------------------------------------*/ +Word16 rand_phase_fx(const Word16 seed, Word16 *sin_F, Word16 *cos_F) +{ + /* 4x8+8 lookup scheme requiring ~40 Words of ROM freqRes 90/8 = 11.25 degrees */ + + /* x=(0:(5*8-1))*(2*pi)/32; y=sin(x);y_int=max(-32768,min(32767,round(y*32768))), y_int/32768 */ + + const Word16 *sincos_lowres_tab_cosQ15_fx = sincos_lowres_tab_sinQ15_fx + 8; + /* position at 90 degrees , ptr init */ + Word16 seed2; + Word16 seed2_shift; + +#ifdef DYNMEM_COUNT + Dyn_Mem_In("rand_phase_fx", sizeof(struct { + const Word16 *sincos_lowres_tab_cosQ15_fx; /* position at 90 degrees */ + Word16 seed2; /* 16 bit signed */ + Word16 seed2_shift; + })); +#endif + +#ifdef WMOPS + push_wmops("PhECU::rand_phase_fx"); +#endif + + seed2 = extract_l(L_mac0(13849, seed, 31821)); + seed2_shift = lshr(seed2, 11); + /* logical shift to get uniform random 5 msb bits; 0-31 , 0 degrees to 31*360/32= 348.75 */ + *sin_F = sincos_lowres_tab_sinQ15_fx[seed2_shift]; move16(); /* these moves can often be avoided by returning seed2shift and inlining */ + *cos_F = sincos_lowres_tab_cosQ15_fx[seed2_shift]; move16(); /* these moves can often be avoided by inlining */ +/* total WC 5 ops */ +#ifdef DYNMEM_COUNT + Dyn_Mem_Out(); +#endif +#ifdef WMOPS + pop_wmops(); +#endif + return seed2; +} + +/*----------------------------------------------------------------------------- + * trans_burst_ana_fx() + * + * Transient analysis + *----------------------------------------------------------------------------*/ +void trans_burst_ana_fx( + const Word16 *xfp, /* i : Input signal (, only used if time_offset==0) now in up_scaled *Q_spec */ + Word16 * mag_chg, /* o : Magnitude modification vector Q15 */ + Word16 * ph_dith, /* o : Phase dither, 2*PI is not included (Q15, i.e., between 0.0 and 1.0) */ + Word16 * mag_chg_1st, /* i/o: per band magnitude modifier for transients Q15 */ + const Word16 output_frame, /* i : Frame length */ + const Word16 time_offs, /* i : Time offset (integral multiple of output_frame) */ + const Word16 est_stab_content, /* i : 0.0=dynamic ... 1.0=Stable (==st->env_stab ) */ + Word16 * alpha, /* o : Magnitude modification factors for fade to average */ + Word16 * beta, /* : Magnitude modification factors for fade to average */ + Word16 * beta_mute, /* i/o : Factor for long-term mute */ + Word16 * Xavg, /* o : Frequency group average gain to fade to in same Q as X_sav */ + Word16 Q_spec, Word32 L_oold_xfp_w_E_fx, Word16 oold_xfp_w_E_exp_fx, Word16 oold_Ltot_exp_fx, + Word16 *oold_grp_shape_fx, + + Word32 L_old_xfp_w_E_fx, Word16 old_xfp_w_E_exp_fx, Word16 old_Ltot_exp_fx, Word16 *old_grp_shape_fx, +#ifdef CR8_A_PLC_FADEOUT_TUNING + Word16 fadeout, + Word32 * L_Xavg, /* full scale band amplitudes */ +#endif + Word8 *scratchBuffer /* Size = 4*4 * MAX_LTRANA + (2*4 + 1*2) * MAX_LGW + 8 */ +) +{ + Word16 att_val, attDegreeFrames; + Word32 * L_pGrPowLeft, *L_pGrPowRight; + Word32 * L_gr_pow_left, *L_gr_pow_right; + Word16 Lgw, i, k, burst_len; + Word16 man, expo; + Word16 att_always = 0; /* fixed attenuation per frequency group if set to 1 */ + Word16 oneOverFrame, roundEstMusContent, tmp16; +#ifdef CR8_A_PLC_FADEOUT_TUNING + Word16 burst_att_thresh; + Word16 att_per_frame; +#else + Word16 burst_att_thresh = BURST_ATT_THRESH; + Word16 att_per_frame = ATT_PER_FRAME; +#endif + Word16 * tr_dec; + Word32 L_acc; + Word16 fs_scale; + Word16 scale_sh; + + Word32 L_oold_tmp, L_old_tmp; + Word16 oold_exp_fx, old_exp_fx; + Word16 margin_oold, margin_old; + Word16 fs_idx; + Word16 exp_diff; + Word16 Xavg_exp_fx, Xavg_mod_exp_fx; + Word16 tr_rise[MAX_LGW]; + Word16 tr_decay[MAX_LGW]; + Word16 man_in, expo_in, tmp; + Word32 L_tmp, L_tmp2; + Word16 thresh_tr_rise_lin_Q15; + Word16 thresh_tr_decay_lin_Q15; +#ifdef CR8_A_PLC_FADEOUT_TUNING + Word16 beta_mute_thr; + Word16 fade_ms_ind; +#endif + +#ifdef DYNMEM_COUNT +#ifdef CR8_A_PLC_FADEOUT_TUNING + Dyn_Mem_In("trans_burst_ana_fx", sizeof(struct { + + Word16 att_val, attDegreeFrames; + Word32 * pGrPowLeft_L, *pGrPowRight_L; + Word32 * L_gr_pow_left, *L_gr_pow_right; + Word16 Lprot; + Word16 Lgw, i, k, burst_len; + Word16 man, expo; + Word16 att_always; /* fixed attenuation per frequency group if set to 1 */ + Word16 oneOverFrame, roundEstMusContent, tmp16; + + Word16 burst_att_thresh; + Word16 att_per_frame; + + Word16 * tr_dec; + UWord16 lsb; + Word32 L_acc; + Word16 fs_scale; + Word16 scale_sh; + + Word32 L_oold_tmp; + Word32 L_old_tmp; + Word16 fs_idx; + Word16 shift32; + Word16 margin_old; + Word16 margin_oold; + + Word16 Xavg_exp_fx, Xavg_mod_exp_fx; + Word16 tr_rise[MAX_LGW]; + Word16 tr_decay[MAX_LGW]; + + Word16 man_in, expo_in, tmp; + Word32 L_tmp, L_tmp2; + Word16 thresh_tr_rise_lin_Q15; + Word16 thresh_tr_decay_lin_Q15; + + Word16 beta_mute_thr; + Word16 fade_ms_ind; + })); +#else + Dyn_Mem_In("trans_burst_ana_fx", sizeof(struct { + + Word16 att_val, attDegreeFrames; + Word32 * pGrPowLeft_L, *pGrPowRight_L; + Word32 * L_gr_pow_left, *L_gr_pow_right; + Word16 Lprot; + Word16 Lgw, i, k, burst_len; + Word16 man, expo; + Word16 att_always; /* fixed attenuation per frequency group if set to 1 */ + Word16 oneOverFrame, roundEstMusContent, tmp16; + + Word16 burst_att_thresh; + Word16 att_per_frame; + + Word16 * tr_dec; + UWord16 lsb; + Word32 L_acc; + Word16 fs_scale; + Word16 scale_sh; + + Word32 L_oold_tmp; + Word32 L_old_tmp; + Word16 fs_idx; + Word16 shift32; + Word16 margin_old; + Word16 margin_oold; + + Word16 Xavg_exp_fx, Xavg_mod_exp_fx; + Word16 tr_rise[MAX_LGW]; + Word16 tr_decay[MAX_LGW]; + })); +#endif + +#endif + + UNUSED(xfp); + UNUSED(oold_xfp_w_E_exp_fx); + UNUSED(old_xfp_w_E_exp_fx); + + if (time_offs == 0) + { +#ifdef WMOPS + push_wmops("PhECU::trans_burst_ana_fx(1st)"); +#endif + } + else + { +#ifdef WMOPS + push_wmops("PhECU::trans_burst_ana_fx(N)"); +#endif + } + + fs_idx = mult(output_frame, (Word16)(32768.0 / 99.0)); /* truncation needed , i.e no rounding can be applied here */ + ASSERT(fs_idx == (output_frame / 100)); + + L_gr_pow_left = (Word32 *)scratchAlign(scratchBuffer, 0); /* Size = 4 * MAX_LGW */ /* Size = 4 * MAX_LGW */ + + L_gr_pow_right = (Word32 *)scratchAlign(L_gr_pow_left, sizeof(*L_gr_pow_left) * MAX_LGW); /* Size = 4 * MAX_LGW */ + + tr_dec = (Word16 *)scratchAlign(L_gr_pow_right, sizeof(*L_gr_pow_right) * MAX_LGW); /* Size = 2bytes * MAX_LGW */ + + oneOverFrame = oneOverFrameQ15Tab[fs_idx]; + Lgw = s_min(add(fs_idx, LGW8K), LGW48K); /* 4,5,6,7, (7/8) */ + + burst_len = add(mult_r(time_offs, oneOverFrame), 1); + + UNUSED(est_stab_content); + UNUSED(roundEstMusContent); +#ifndef CR8_A_PLC_FADEOUT_TUNING + burst_att_thresh = add(BURST_ATT_THRESH, 1); /* in Q0 , stable setting */ + att_per_frame = sub(ATT_PER_FRAME, 1); /* in Q0 , stable setting */ +#endif + +#ifdef CR8_A_PLC_FADEOUT_TUNING + move16(); + fade_ms_ind = (PLC2_FADEOUT_IN_MS - PLC2_FADEOUT_IN_MS_MIN) / PLC2_FADEOUT_RES; /* a shorter fading entry in fade_scheme_tab_fx */ + test(); + if (fadeout != 0) + { + fade_ms_ind = (PLC2_FADEOUT_LONG_IN_MS - PLC2_FADEOUT_IN_MS_MIN) / PLC2_FADEOUT_RES; move16(); + /* a long fading table entry in fade_scheme_tab */ + } + + move16(); move16(); move16(); + att_per_frame = fade_scheme_tab_fx[fade_ms_ind][0]; + burst_att_thresh = fade_scheme_tab_fx[fade_ms_ind][1]; /* number of 1.0 frames before muting phase */ + /* band gain muting can take place earlier due to a band transient */ + beta_mute_thr = fade_scheme_tab_fx[fade_ms_ind][2]; /* faster muting of added noise starts when slow main signal fadeout is over */ +#endif + + + + +#ifdef PLC_FADEOUT_IN_MS +#ifdef CR8_A_PLC_FADEOUT_TUNING + ASSERT(att_per_frame >= 1 && att_per_frame <= 12); /* table based lookup restriction */ +#else + ASSERT(att_per_frame >= 1 && att_per_frame <=10 ); /* table based lookup restriction */ +#endif +#else + ASSERT(att_per_frame == 1 || att_per_frame == 2); /* table based lookup restriction */ +#endif + + *ph_dith = 0; /* peak scrambling, not in use */ + + attDegreeFrames = 0; move16(); + IF(sub(burst_len, burst_att_thresh) > 0) + { + att_always = 1; move16(); + /* increase degree of attenuation */ + + /* N.B. To facilitate the subsequent 10^(-att_degree/20) implementation + * so as to use direct table-lookup, + * the first (burstLen - burst_att_thresh) are NOT multiplied by "att_per_frame". */ + attDegreeFrames = sub(burst_len, burst_att_thresh); /* multiplied by 1.0 , */ + /* Furthermore, in order to minimize the size of the lookup-table required to + * implement 10^(-att_degree/10), hard limit attDegreeFrames to (30% of 100)=30. + * If attDegreeFrames is greater than 30, it means there are more than 30 successive + * bad frames. */ + if (sub(attDegreeFrames, OFF_FRAMES_LIMIT) > 0) + {/* Hard limit the no. of frames, for table lookup */ + attDegreeFrames = OFF_FRAMES_LIMIT; move16(); + } + } + + plc_phEcu_initWord16(alpha, 32767, MAX_LGW); + basop_memset(beta, 0, (MAX_LGW) * sizeof(Word16)); + IF(sub(burst_len, 1) <= 0) + { + *beta_mute = BETA_MUTE_FAC_INI; move16(); + *beta_mute = shr_pos(*beta_mute , 1); /* perceptual decrease */ + } + + IF(sub(burst_len, 1) <= 0) + { + L_pGrPowLeft = &L_gr_pow_left[0]; /* ptr init*/ + L_pGrPowRight = &L_gr_pow_right[0]; /* ptr init*/ + + fs_scale = xfp_wE_MDCT2FFTQ11[fs_idx]; move16(); + scale_sh = 4; /* 15-11 */ move16(); + /* L_*old_xfp_w_E_fx, always upscaled to max from the calculating function */ + + + L_oold_tmp = Mpy_32_16_lc3plus(L_oold_xfp_w_E_fx, fs_scale); + L_old_tmp = Mpy_32_16_lc3plus(L_old_xfp_w_E_fx, fs_scale); + + oold_exp_fx = add(oold_Ltot_exp_fx, scale_sh); + old_exp_fx = add(old_Ltot_exp_fx, scale_sh); + + /*re-normalize L_mantissas and adjust exps */ + margin_oold = norm_l(L_oold_tmp); + L_oold_tmp = L_shl_pos(L_oold_tmp, margin_oold); + oold_exp_fx = sub(oold_exp_fx, margin_oold); + + margin_old = norm_l(L_old_tmp); + L_old_tmp = L_shl_pos(L_old_tmp, margin_old); + old_exp_fx = sub(old_exp_fx, margin_old); + + /* now time to analyze how the actual L_tot exponent scaling should be done */ + /* bring up the lowest exp to the same exp as the higher exp, and scale down the corresponding mantissa */ + exp_diff = sub(old_exp_fx, oold_exp_fx); /* energy increase from oold to old in log2 shifts */ + + /* Overflow2 fix */ + exp_diff = s_max(-31, exp_diff); + exp_diff = s_min(31, exp_diff); + if (exp_diff > 0) + { /* oold_exp < old_exp */ + /* old_exp is limiting, shift down oold mantissa */ + L_oold_tmp = L_shr_pos(L_oold_tmp, exp_diff); + } + if (exp_diff < 0) + { /* oold_exp > old_exp */ + /* oold_exp is limiting, shift down old mantissa */ + L_old_tmp = L_shr_pos(L_old_tmp, negate(exp_diff)); + } + oold_exp_fx = s_max(oold_exp_fx, old_exp_fx); + old_exp_fx = oold_exp_fx; move16(); + + /* safety set lowest energy to 2 , as one bit is shifted away in avg calculation */ + L_oold_tmp = L_max(L_oold_tmp, 2L); + L_old_tmp = L_max(L_old_tmp, 2L); + + FOR(k = 0; k < Lgw; k++) /* NB Lgw may be shorter than all defined bands , e.g at at 48k */ + { + L_gr_pow_left[k] = Mpy_32_16_lc3plus(L_oold_tmp, oold_grp_shape_fx[k]); move32(); + L_gr_pow_right[k] = Mpy_32_16_lc3plus(L_old_tmp, old_grp_shape_fx[k]); move32(); + + /*Xavg[k] = sqrt(0.5f*(gr_pow_left[k]+gr_pow_right[k])/(float)(gw[k+1]-gw[k]));*/ + Xavg_exp_fx = sub(old_exp_fx, 1); /* virtual pre divide X_avg by 2 too keep precision in summation */ + L_acc = L_add(L_shr_pos(L_gr_pow_left[k], 1), L_shr_pos(L_gr_pow_right[k], 1)); + L_acc = L_shr_pos(L_acc, gw_len_inv_shift_fx[k]); /* divide by (bandwidth/2) in bins */ + + { /* new Xavg_fx calculation */ + L_acc = L_max(L_acc, 1L); + tmp = norm_l(L_acc); + Xavg_exp_fx = sub(Xavg_exp_fx, tmp); + L_acc = L_shl_pos(L_acc, tmp); /* now between 0.5 an 1.0*/ + + expo_in = add(Xavg_exp_fx, 0); + man_in = round_fx_sat(L_acc); + + /* now allow both positive and negative expos into sqrt */ + man = sqrt2ndOrder(man_in); + if (s_and(expo_in, 1) != 0) + { + man = mult_r(man, FEC_HQ_ECU_ROOT2); /* odd exp operation */ /* 1/sqrt(2) */ + } + expo = shr_r(expo_in, 1); /* apply even part of exp , square root operation. shr_r needed for positive side exps */ + + + + L_acc = L_deposit_h(man); + Xavg_exp_fx = add(expo, 0); + /*Note: sqrt approximaton may overshoot e.g- sqrt(1.0) may become 1.0001 i.e. saturation is needed when eventually applying expo */ + + + /* Xavg (unscaled flt in L_acc*2^(exp-31)) needs to be saved in the same scale + Q as the stored 16bit + * Xsav_fx, for use in subst_spec() */ + /* move Xavg fft scale to fx domain fx-fft scale*/ + L_acc = Mpy_32_16_lc3plus(L_acc, PhEcu_Xsav_Flt2FxScaleQ15[fs_idx]); /* fs fixed fractional change */ + Xavg_mod_exp_fx = sub(Xavg_exp_fx, PhEcu_Xsav_Flt2FxDnShift[fs_idx]); /* fs fixed exp change*/ + Xavg_mod_exp_fx = add(Xavg_mod_exp_fx, Q_spec); /* signal adaptive exp change*/ + + /* :: move to Q_spec domain of Xsav , Q fixed in first BFI frames */ + + /* extract Q0 value shift so that the mantissa is in the high part with man*2,^(0-15) */ + exp_diff = sub(15, Xavg_mod_exp_fx); + + + exp_diff = s_min(31, exp_diff); /* limit to meaningfull DSP shifts as described by up to 6 bits */ + exp_diff = s_max(-32, exp_diff); + if (exp_diff > 0) + { + L_acc = L_shr_pos(L_acc, exp_diff); /* may underflow */ + } + + if (exp_diff < 0) + { + L_acc = L_shr_sat(L_acc, exp_diff); + } +#ifdef CR8_A_PLC_FADEOUT_TUNING + L_Xavg[k] = L_acc; /* export full 31 bit scale band amplitude */ +#endif + Xavg[k] = round_fx_sat(L_acc); /* extract high part */ + + } /*end of new Xavg_fx calculation */ + /* internal transition detection */ + + { /* pure percentage based transient detection */ + thresh_tr_rise_lin_Q15 = PhEcu_frac_thr_rise_lin_Q15[k]; + thresh_tr_decay_lin_Q15 = PhEcu_frac_thr_decay_lin_Q15[k]; + + /* analyse rise */ + /* one of L_left or L_right should be pre-upshifted to a near max mantissa, (in one band ) */ + L_tmp2 = L_deposit_h(0); + L_tmp = Mpy_32_16_lc3plus(*L_pGrPowRight, thresh_tr_rise_lin_Q15); + if (L_sub(*L_pGrPowLeft, L_tmp) <= 0) + { + L_tmp2 = L_deposit_l(1); + } + + if (*L_pGrPowLeft == 0) /* denominator zero special cases */ + { + /* rise: Right/Left ; " * / 0 " --> tr_rise=1 ; "0/0" --> tr_rise = 0 */ + L_tmp2 = L_min(*L_pGrPowRight, 1L); + } + tr_rise[k] = extract_l(L_tmp2); move16(); + + /* analyse decay */ + L_tmp2 = L_deposit_h(0); + L_tmp = Mpy_32_16_lc3plus(*L_pGrPowLeft, thresh_tr_decay_lin_Q15); + if (L_sub(L_tmp, *L_pGrPowRight) >= 0) + { + L_tmp2 = L_deposit_l(1); + } + if (*L_pGrPowRight == 0) /* right side no energy , special cases */ + { + /* decay: Right/Left ; " 0 / * " --> tr_decay=0 ; "0/0" --> tr_decay = 0 */ + L_tmp2 = L_deposit_h(0); + } + tr_decay[k] = extract_l(L_tmp2); move16(); + + tr_dec[k] = s_max(tr_rise[k], tr_decay[k]); move16(); + + } /* percentage tr_dec */ + /* magnitude modification, calculated for decay only */ + IF(add(tr_dec[k], att_always) != 0) + { + +#if MAX_INCREASE_GRPPOW_FX != 0 +#error trans_burst_ana_fx-- The following implementation is incorrect +#endif + att_val = 32767; move16(); + IF(L_sub(*L_pGrPowRight, 0) > 0) + { + IF(L_sub(*L_pGrPowRight, *L_pGrPowLeft) < 0) /* decay , i.e., (gr_pow_right/gr_pow_left) < 1.0 */ + { + /* Compute sqrt(grp_pow_chg), where grp_pow_chg = gr_pow_right/gr_pow_left. */ + tmp16 = plc_phEcu_ratio_fx(*L_pGrPowRight, *L_pGrPowLeft, &expo); /* output tmp16 in Q14 */ + + expo = sub(expo, (15 - 14)); /* Now, tmp16 is considered in Q15 */ + i = norm_s(tmp16); + man = shl_pos(tmp16, i); /* Mandatory normalization before sqrtNthOrder(). */ + expo = add(expo, i); + man = sqrt2ndOrder(man); + if (s_and(expo, 1) != 0) /* Check even or odd. */ + { + man = mult_r(man, FEC_HQ_ECU_ROOT2); + } + expo = shr_pos(expo, 1); /* Divided by 2-- square root operation. */ + att_val = shr(man, expo); /* Denormalize the mantissa back to Q15. */ + } + /* ELSE + { + do nothing because (gr_pow_right/gr_pow_left) >= 1.0 + } + */ + } + + mag_chg_1st[k] = att_val; move16(); + mag_chg[k] = att_val; move16(); + } + ELSE + { + mag_chg_1st[k] = 32767; move16(); + mag_chg[k] = 32767; move16(); /* Set to ]1.0 in Q15 */ + } + + L_pGrPowLeft++; + L_pGrPowRight++; + } /* FOR band k */ + } + ELSE /* sub(burst_len, 1) <= 0) */ + { + /* BURST path */ + + /* Since attDegreeFrames is discrete (integer) and hard limited to OFF_FRAMES_LIMIT, + * it is easier to implement 10^(-att_degree/20.0) by a simply direct + * table-lookup. Also, att_per_frame is discrete as well and can be + * either ATT_PER_FRAME-1 or ATT_PER_FRAME and nothing else. This + * means only 2 tables of size=(OFF_FRAMES_LIMIT+1) each are required. + * To take square root into account, it is divided by 20 instead of 10. */ + +#ifdef CR8_A_PLC_FADEOUT_TUNING + if (sub(burst_len, beta_mute_thr) > 0) /* beta_mute_thr coincides/close to stronger 6dB muting phase */ + { + *beta_mute = shr_pos_pos(*beta_mute, 1); + } +#endif + + + FOR(k = 0; k < Lgw; k++) /* Lgw may be shorter than all bands at 48k */ + { + /* global burst attenuation */ + #if PLC2_FADEOUT_IN_MS != 0 + #ifdef CR8_A_PLC_FADEOUT_TUNING + /* att_per_frame idx = "1:12") */ +#else + /* att_per_frame idx = "1:10") */ +#endif + att_val = POW_ATT_TABLES[att_per_frame][s_min(OFF_FRAMES_LIMIT, attDegreeFrames)]; move16(); +#else + /* att_per_frame idx = "1:2") */ + att_val = POW_ATT_TABLES[att_per_frame][s_min(OFF_FRAMES_LIMIT, attDegreeFrames)]; move16(); + /* 10^(-attDegreeFrames*(att_per_frame = "1 or 2")/20) */ +#endif + + mag_chg[k] = mult_r(mag_chg_1st[k], att_val); /* Q15 */ + +#ifndef CR8_A_PLC_FADEOUT_TUNING + if (sub(burst_len, BETA_MUTE_THR) > 0) /* BETA_MUTE_THR ~= (5+15) coincides/close to stronger 6dB muting phase */ + { + *beta_mute = shr_pos_pos(*beta_mute, 1); + } +#endif + alpha[k] = mag_chg[k]; move16(); + ASSERT(beta[k] == 0); /* initialization required */ + IF(sub(alpha[k], 32766) < 0) + { + /* beta_pre[k] = sqrt(1.0f - SQR(alpha[k])); */ + /* beta[k] = beta_pre[k]* *beta_mute;*/ + /* (1.0-alpha.^2), in exp 1 due to L_mult0; */ + + L_acc = L_sub((INT32_MAX >> 1) + 1, L_mult0(alpha[k], alpha[k])); + { + + /* use lower complex(WMOPS/ROM) 2nd-order sqrt approximation */ + Word32 L_man, L_acc2 = L_acc; + Word16 tmp, expo_in, expo2, man_in, man; + /* updated code using the 2nd order approximation routine */ + /* form is flt=(L_acc2*2.^(-31 + 1) */ + + tmp = norm_l(L_acc2); /* tmp is always 1 or higher due to Lmac0 downshift */ + man_in = round_fx_sat(L_shl_pos(L_acc2, tmp)); + expo_in = sub(1, tmp); /* 1 due to original 1 bit margin gain in L_mult0 */ + + /* both positive and negative expos into sqrt */ + man = sqrt2ndOrder(man_in); + if (s_and(expo_in, 1) != 0) + { + man = mult_r(man, FEC_HQ_ECU_ROOT2); /* odd exp operation */ /* sqrt(2)/2 */ + } + + expo2 = shr_r(expo_in, 1); /* apply square root operation. shr_r needed for pos and neg exps */ + ASSERT(expo2 <= 1); + + L_man = L_deposit_h(man); + L_man = L_shl_sat(L_man, expo2); /* move to a zero exp , _sat needed for 1.0 input (due to approximation overshoot) */ + + man = round_fx_sat(L_man); /* better perf with round here */ + + + beta[k] = mult_r(*beta_mute, man); move16(); + } + + /* bw Lowpass shape additive component */ + /* tab[LGW48K + 1] = { 1.0, ....1.0, 0.5,0.5, ... 0.1, 0.1 } */ + + IF(sub(k, LGW32K - 1) >= 0) + { + beta[k] = mult_r(beta[k], 3277); /* 0.1 in Q15 */ + } + ELSE IF(sub(k, LGW16K - 1) >= 0) + { + beta[k] = mult_r(beta[k], 16384); /* 0.5 in Q15 */ + } + + /* + % limit Xavg noise contribution further in case of offset/tr_decay + % attenuation was already active + + if (burst_len <= burst_att_thresh) && ( stPhECU_mag_chg_1st(k) < (32766/32768) ) + XavgFadeinFactor = (burst_len-1)/burst_att_thresh; + XavgFadeinFactor = min(1.0, XavgFadeinFactor); + beta(k) = beta(k)*XavgFadeinFactor; + % limit initial Xavg noise contribution until We have reached regular burst attenuation + end + end + */ + IF( sub(mag_chg_1st[k], 32767) <0 ) + { /* offset muting was started before burst muting phase */ + /* Xavg noise gradually increased during a short period */ + Word16 XavgFadeinFactor = 32767; + Word16 ratio2_3_4_5tab[4][5 - 1] = { + {(Word16)(.5 * 32768.0), (Word16)(1.0 * 32767.0), (Word16)(1.0 * 32767.0), (Word16)(1.0 * 32767.0)}, /* 1/2*/ + {(Word16)(.333 * 32768.0), (Word16)(.666 * 32768.0), (Word16)(1.0 * 32767.0), (Word16)(1.0 * 32767.0)}, /* 1/3*/ + {(Word16)(.25 * 32768.0), (Word16)(.5 * 32768.0), (Word16)(.75 * 32768.0), (Word16)(1.0 * 32767.0)}, /* 1/4 */ + {(Word16)(.2 * 32768.0), (Word16)(.4 * 32768.0), (Word16)(.6 * 32768.0), (Word16)(.8 * 32768.0)} /* 1/5 */ + + }; + ASSERT(burst_att_thresh >= 1 && burst_att_thresh <= 5); + ASSERT(burst_len >= 2); + if (sub(burst_len,burst_att_thresh) <= 0) + { + ASSERT(burst_len - 2 < (5-1)); + ASSERT(burst_att_thresh-1-1 < (4)); + XavgFadeinFactor = ratio2_3_4_5tab[burst_att_thresh-1-1][burst_len - 2]; /* second bfi frame burst_len= is 2 */ + } + beta[k] = mult_r(beta[k], XavgFadeinFactor); /* n Q15 */ + } + } /* IF (sub(alpha[k], 32766) < 0) */ + } /* FOR k*/ + + } /* BURST */ + + + + IF(sub(output_frame, L_FRAME48K) == 0) + { /* for 48kHz set/handle scalings of last group/band the same way as previous lower freq band(s) */ + + FOR(k = Lgw; k < MAX_LGW; k++) + { + tr_dec[k] = tr_dec[k - 1]; move16(); /* only available in first bfi frame */ + Xavg[k] = Xavg[k - 1]; move16(); + mag_chg_1st[k] = mag_chg_1st[k - 1]; move16(); + mag_chg[k] = mag_chg[k - 1]; move16(); + alpha[k] = alpha[k - 1]; move16(); + beta[k] = beta[k - 1]; move16(); + } + } + +#ifdef DYNMEM_COUNT + Dyn_Mem_Out(); +#endif +#ifdef WMOPS + pop_wmops(); +#endif +} + +/*----------------------------------------------------------------------------- + * imax_fx() + * + * Get interpolated maximum position + *-----------------------------------------------------------------------------*/ +static Word16 imax_fx( /* o: The location, relative to the middle of the 3 given data point, of the maximum. (Q15) */ + const Word16 *y, /* i: The 3 given data points. */ + const Word16 special /* i: -1 = left edge special case, 0 = normal, +1 = right edge special case */ +) +{ + Word16 posi; + Word16 man, expo, edge; + const Word16 *pY; + Word32 L_y1, L_y2, L_y3, L_numer, L_denom, L_sign, L_acc, L_y3_y1; + +#ifdef DYNMEM_COUNT + Dyn_Mem_In("imax_fx", sizeof(struct { + Word16 posi; + Word16 man, expo, edge; + const Word16 *pY; + Word32 L_y1, L_y2, L_y3, L_numer, L_denom, L_sign, L_acc, L_y3_y1; + })); +#endif + +#ifdef WMOPS + push_wmops("PhECU::imax_fx"); +#endif + + /* Seek the extremum of the parabola P(x) defined by 3 consecutive points + so that P([-1 0 1]) = [y1 y2 y3] */ + pY = y; + L_y1 = L_deposit_l(*pY++), L_y2 = L_deposit_l(*pY++), L_y3 = L_deposit_l(*pY); + + /* The extremum value: + * y2i = -0.125f * SQR(y3_y1) / (y1+y3-2*y2)+y2 + * is not computed. Alternatively, the derivative of the parabola evaluated at y=0, + * dP/dy|y=0, is used to determine whether the extremum is maximum or not. + */ + + /* Compute the extremum location: posi = (y3 - y1)/(4*y2 - 2*y1 - 2*y3). */ + L_y3_y1 = L_sub(L_y3, L_y1); + L_acc = L_shl_pos(L_y2, 1); /* N.B. y2 is multiplied by 2 not 4. */ + L_acc = L_sub(L_acc, L_y1); /* N.B. Y1 is not multiplied by 2. */ + L_denom = L_sub(L_acc, L_y3); /* N.B. Y3 is not multiplied by 2. */ + L_sign = L_xor(L_y3_y1, L_denom); /* Preserve the sign since div_s() only takes positive arguments. */ + L_numer = L_abs(L_y3_y1); + L_denom = L_abs(L_denom); + + test(); + IF(L_numer == 0 || L_denom == 0) + { + posi = 0; move16(); /* flat top , exit with center freq. */ + } + ELSE + { + + IF(L_sub(L_denom, L_shr_pos_pos(L_numer, 1)) > 0) + { + /* Although the output of ratio() is in Q14, adding the missing factor of 2 (See above) + * in the denominator, the output is now considered to be in Q15. */ + man = plc_phEcu_ratio_fx(L_numer, L_denom, &expo); /* The mantissa is considered in Q15 */ + + posi = shr_sat(man, expo); /* in Q15 (Due to saturation, it is automatically bound inside [-1.0,1.0].) */ + } + ELSE + { + posi = 0x7fff; move16(); + } + + if (L_sign < 0) /* Restore the sign. */ + { + posi = negate(posi); + } + + /* For both edges (left and right), the extremum found above may be minimum. + * It needs to reject the minimum. */ + IF(special != 0) /* Either edge special case. */ + { + edge = 0x7fff; /* 1 in Q15 for the right edge special case */ move16(); + if (special < 0) + { + edge = 0; /* Left edge special case */ move16(); + } + + /* The derivative (slope) of the interpolating parabola = 2*A*y + B, + * where A = (y3 + y1)/2 - y2 + * and B = (y3 - y1)/2. + * Therefore, the slope at y=0 is simply B. Use this slope to determine + * if the parabola is concave upward or downward. + */ + IF(posi > 0) /* The extremum is in between the middle and the right given data points. */ + { + posi = sub(0x7fff, posi); /* maximum case */ + if (L_sub(L_y3, L_y1) <= 0) /* Check the slope at y=0, i.e., at the middle given data point. */ + { + posi = edge; /* minimum case */ move16(); + } + } + ELSE /* The extremum is in between the left and the middle given data points. */ + { + posi = add(0x7fff, posi); /* maximum case */ + if (L_sub(L_y3, L_y1) >= 0) + { + posi = edge; /* minimum case */ move16(); + } + } + } + } +#ifdef DYNMEM_COUNT + Dyn_Mem_Out(); +#endif +#ifdef WMOPS + pop_wmops(); +#endif + return posi; + /* Q15. The position either left or right relative to the index of the middle of the 3 given data points. */ +} + + /*----------------------------------------------------------------------------- + * spec_ana_fx() + * + * Spectral analysis + *-----------------------------------------------------------------------------*/ + /* OPT add the FB transient input flags , and skip peakfinder if fullband transient is set */ + void spec_ana_fx(Word16 * xfp, /* i/o : Input 16ms pre-upscaled time signal, output xfp utility buffer */ + Word16 * plocs, /* o : The indicies of the identified peaks Q0 */ + Word32 * L_plocsi, /* o : Interpolated positions of the identified peaks Q16 */ + Word16 * num_plocs, /* o : Number of identified peaks Q0 */ + Word16 * X_sav, /* o : Stored fft spectrum */ + const Word16 output_frame, /* i : Frame length Q0 */ + const Word16 bwidth_fx, /* i : Encoded Fs index Q0 */ + const Word16 *sp_ana_win, /* i : spectral analysis window Q15 */ + const Word16 f0hzLtpBinQ7, /* i : LTP bin frequency in normalized Hz Q7 */ + const Word16 norm_corrQ15_fx, /* i : correlation for lag at f0hzLtpBinQ7 */ + Word16 maxLprot, Word16 maxPlocs, + Word8 *scratchBuffer /* Size = 4 * (MAX_LPROT + MAX_LPROT_RED + 1) + 2 * MAX_PLOCS */ + ) + { + Counter n, k; + Word16 nJacob, Lprot, hamm_len2 = 0, Lprot2, Lprot2p1; + Word32 *L_xfp; + + Word16 *pXfp; + Word16 *pPlocs; + Word16 Xmax, Xmin, sens; + Word16 rectLength, fraction; + Word32 *pPlocsi_L; + Word32 L_acc; + Word16 peak_range_1; + Word16 stop_band_start; + Word16 stop_band_length; + Word16 fft_scale; + Word8 * buffer_fft; + Word16 currPlocs, endPlocs; + Word16 P_in_plocs; + Word16 n_real_interp_tail; + +#ifdef WMOPS + push_wmops("PhECU::spec_ana_fx(1st)"); +#endif +#ifdef DYNMEM_COUNT + Dyn_Mem_In("spec_ana_fx", sizeof(struct { + Counter n, k; + Word16 nJacob ,Lprot, hamm_len2, Lprot2, Lprot2p1; + Word32 *L_xfp; + Word32 *pXfp_L; + Word16 *y_re_ptr, *y_im_ptr; /* otrs to Xsav as xfp was overwritten */ + Word16 *pXfp, *pXfp1, *pPlocs; + Word16 Xmax, Xmin, sel; + Word16 rectLength, fraction, special; + Word32 *pPlocsi_L; + Word32 L_acc; + Word16 peak_range_1; + Word16 stop_band_start; + Word16 stop_band_length; + Word16 fft_scale; + Word8 * buffer_fft; + Word16 fft_scale_by4; + Word16 currPlocs, endPlocs; + Word16 P_in_plocs; + Word16 n_real_interp_tail; + })); +#endif + /* Initialize for 48k to avoid warnings + Lprot - length of saved prototype samples + hamm_len2 - half Hamming window length + pFftTbl - Table for real input FFT + LprotLog2Minus1 - FFT stages for complex input FFT + */ + + + L_xfp = (Word32 *)scratchAlign(scratchBuffer, 0); /* Size = 4 * MAX_LPROT bytes */ + buffer_fft = scratchAlign(L_xfp, sizeof(*L_xfp) * maxLprot); /* Size = 4 * (MAX_LPROT_RED + 1) + 2 * MAX_PLOCS */ + + ASSERT(bwidth_fx >= 0 && bwidth_fx <= 4); /* avoid bwidth_fx variable warning */ + + Lprot = LprotSzPtr[bwidth_fx]; + move16(); + hamm_len2 = DEPR_i_mult(3, mult(output_frame, (Word16)(3277) /* divBy10 + floor */)); /* 3 ms */ + fft_scale = PhEcuFftScale[bwidth_fx]; + move16(); /* 32,16,8 kHz all have fft scale 0, 24 has 8, 48 has 4 */ + Lprot2 = shr_pos(Lprot, 1); + Lprot2p1 = add(Lprot2, 1); /* Magnitude lengths */ + rectLength = sub(Lprot, shl_pos(hamm_len2, 1)); + /* The length of the rectangular portion of the Hamming-Rectangular window. */ + { +#ifdef WMOPS + push_wmops("PhECU::WhrAnaWin+fft"); +#endif + + /* Apply hamming-rect window */ + windowing_L(xfp, L_xfp, sp_ana_win, rectLength, hamm_len2); + BASOP_rfftN(L_xfp, Lprot, &fft_scale, buffer_fft); + } +#ifdef WMOPS + pop_wmops(); /* anawin+fft */ +#endif + + /* Convert 32 Bit intlv FFT into phecu 16 bit flipped fft format */ + /* can not yet be an inplace operation */ + + intlvW32_2_flippedW16(L_xfp, sub(Lprot2, 1), Lprot, xfp); + + /* Apply zeroing of non-coded FFT spectrum above 20 kHz */ + IF(sub(output_frame, ((L_FRAME48K) * 40) / 48) >= 0) /* only relevant for 48kHz in LC3plus */ + { + stop_band_start = ((LPROT48K / 2) * 40) / 48; /* initial start position in real part , 320 */ + stop_band_length = ((LPROT48K * 8) / 48) - 1; /* real tail and into Im parts , 128-1 */ + stop_band_start = add(stop_band_start, 1); /* exclude DC ... */ + + basop_memset(xfp + stop_band_start, 0, (stop_band_length) * sizeof(Word16)); + } + + peak_range_1 = s_min(Lprot2p1, MAX_LPROT_RED / 2 + 1); /* limit preliminary only active for 48k to save WMOPS */ + + basop_memmove(X_sav, xfp, (Lprot) * sizeof(Word16)); + + /* Magnitude representation */ + fft_spec2_sqrt_approx_fx(xfp, xfp, Lprot); + /* inplace, i.e. [ Dc, real part of xfp ,Fs/2 ] will be replaced by magnitude(scaled by .5) */ + + /* Find global maximum and minimum. */ + plc_phEcu_maxval_fx(xfp, peak_range_1, &Xmax); + plc_phEcu_minval_fx(xfp, peak_range_1, &Xmin); + sens = mult_r(sub(Xmax, Xmin), CMPLMNT_PLOC_SENS_FX); + + + plc_phEcu_peak_locator_fx(xfp, peak_range_1, plocs, num_plocs, sens, Xmax, Xmin, MAX_LPROT_RED, buffer_fft); + + +#ifdef WMOPS + push_wmops("PhECU::Peaks_refine"); +#endif + + /* Refine peaks */ + pPlocsi_L = L_plocsi; + pPlocs = plocs; + /* n = sub(*num_plocs, 1); */ /* -1 so as to exclude the very last peak. */ + n = *num_plocs; /* number of peaks to process */ + /* Special case-- The very 1st peak if it is at 0 index position (DC) */ + /* With DELTA_CORR_F0_INT == 2 one needs to handle both *pPlocs==0 and *pPlocs==1 */ + logic16(); + IF((n > 0) && (sub(*pPlocs, 0) == 0)) /* Very 1st peak position possible to have a peak at 0/DC index position. */ + { + fraction = imax_fx(xfp, -1); /* -1 signifies special left edge case. */ + L_acc = L_deposit_h(*pPlocs++); /* N.B., (*pPlocs) must be zero here. */ + *pPlocsi_L++ = L_mac(L_acc, fraction, 1); move32(); /* in Q16 */ + n = sub(n, 1); /* This special case is taken care of -- one less peak to go */ + } + logic16(); + IF((n > 0) && (sub(*pPlocs, 1) == 0)) /* Also 2nd peak position uses DC which makes jacobsen unsuitable. */ + { + fraction = imax_fx(xfp, 0); /* for parabolic this is not a special case. */ + L_acc = L_deposit_h(*pPlocs++); /* N.B., (*pPlocs) must be 1 here. */ + *pPlocsi_L++ = L_mac(L_acc, fraction, 1); move32(); /* in Q16 */ + n = sub(n, 1); /* This special case is taken care of -- one less peak to go */ + } + + /* All remaining peaks except the very last two possible integer positions */ + currPlocs = *pPlocs++; move16(); + endPlocs = sub(Lprot2p1, DELTA_CORR_F0_INT); /* last *pPlocs position for Jacobsen */ + + /* precompute number of turns based on endpoint integer location and make into a proper FOR loop */ + IF(n > 0) + { + nJacob = n; move16(); + + /* catch all three xxx01 , xxx10 and xxx11 , + and not only xxx01, xxx10 */ + + n_real_interp_tail = 0; move16(); + if (sub(endPlocs, plocs[sub(*num_plocs, 1)]) <= 0) + { + n_real_interp_tail = add(n_real_interp_tail, 1); + } + + logic16(); + if (sub(n,1) > 0 && sub(endPlocs, plocs[sub(*num_plocs, 2)]) <= 0) + { + n_real_interp_tail = add(n_real_interp_tail, 1); + } + + nJacob = sub(nJacob, n_real_interp_tail); + + FOR (k = 0; k < nJacob; k++) + { + fraction = imax2_jacobsen_mag_fx(&(X_sav[currPlocs - 1]), &(X_sav[Lprot - 1 - currPlocs]), 0); /* in Q15 */ /* not endpoint */ + move16(); move16(); /* account for inloop indirect ptrs into Xsav */ + + L_acc = L_deposit_h(currPlocs); + *pPlocsi_L++ = L_mac(L_acc, fraction, 1); move32(); /* in Q16. Append the fractional part to the integral part. */ + currPlocs = *pPlocs++; move16(); + } + n = sub(n, nJacob); + } + + /* At this point there should at most two plocs left to process */ + /* the position before fs/2 and fs/2 both use the same magnitude points */ + + IF(n > 0) + { + /* [ . . . . . . . ] Lprot/2+1 positions */ + /* | | | */ + /* 0 (Lprot/2-2) (Lprot/2) */ + + pXfp = xfp + sub(Lprot2, 2); + IF(sub(currPlocs, sub(Lprot2p1, DELTA_CORR_F0_INT)) == 0) + /* Also 2nd last peak position uses fs/2 which makes jacobsen less suitable. */ + { + fraction = imax_fx(pXfp, 0); /* for parabolic this is not a special case. */ + + L_acc = L_deposit_h(currPlocs); /* N.B., (*pPlocs) must be 1 here. */ + *pPlocsi_L++ = L_mac(L_acc, fraction, 1); move32(); /* in Q16 */ + currPlocs = *pPlocs++; move16(); + n = sub(n, 1); /* This special case is taken care of -- one less peak to go */ + + if (n > 0) + { + /* allow for an additional consecutive final plocs after (Fs/2-1) at Fs/2 */ + currPlocs = *pPlocs++; move16(); + } + } + + /* Here the only remaining point would be a fs/2 plocs */ + /* pXfp = xfp + sub(Lprot2,1); already set just a reminder where it whould point */ + IF(n > 0) /* fs/2 which makes special case . */ + { + fraction = imax_fx(pXfp, 1); /* for parabolic this is a special case. */ + + L_acc = L_deposit_h(currPlocs); /* N.B., (*pPlocs) must be 1 here. */ + *pPlocsi_L++ = L_mac(L_acc, fraction, 1); move32(); /* in Q16 */ + currPlocs = *pPlocs++; move16(); + n = sub(n, 1); /* This special case is taken care of -- one less peak to go */ + } + } + + /* here n should be 0 if all peaks have been processed */ + ASSERT(n == 0); + + /* Check number of plocs within an assumed pitch range */ + P_in_plocs = 0; move16(); + FOR(n = 0; n < *num_plocs; n++) + { + /* count number of peaks in locations 1,2,3,4,5,6 , ~= 60 Hz ... 380 Hz */ + fraction = s_min(1, plocs[n]); /* 0 stays zero , otherwise 1 */ + if (sub(plocs[n], 7) < 0) + { + P_in_plocs = add(P_in_plocs, fraction); + } + } + +#ifdef WMOPS + pop_wmops(); /* peaks refine */ +#endif + + logic16(); + IF(f0hzLtpBinQ7 > 0 && P_in_plocs > 0) + { + Word16 n_plocs_in, n_plocs_out; + + n_plocs_in = *num_plocs; move16(); + + /* NB LF peak analysis may add adjacent peaks in { plocs, L_plocsi}, (output from peakfinder did not have + * adjacent peaks ) */ + plc_phEcu_LF_peak_analysis_fx(plocs /* i/o */, num_plocs /* i/o */, L_plocsi /* i/o */, xfp, f0hzLtpBinQ7, + norm_corrQ15_fx, 2, maxPlocs, buffer_fft); + n_plocs_out = *num_plocs; move16(); + + IF(sub(n_plocs_in, n_plocs_out) == 0) + { + /* adjust first peak coinciding with LTPF0 measures if it indicates so */ + plc_phEcu_F0_refine_first_fx(plocs /* i/o */, *num_plocs, L_plocsi /* i/o */, f0hzLtpBinQ7, norm_corrQ15_fx, + 3); + } + } + /* moved inside spec_ana_fx , to include validated pitch peak P_in_plocs*/ + { + Word16 peak_limits_fx[5] = { 14 /*NB*/, 14 /*WB*/, 14 /*sWB*/, 14 /*SWB*/, + 14 /* FB */ }; /* to be trained for each BW */ + + test(); + test(); + IF((sub(norm_corrQ15_fx, 0) > 0) && /* == 0 indicates a negative correlation, which could be likely stable */ + (sub((Word16)(0.5 * 32768), norm_corrQ15_fx) > 0) && (sub(*num_plocs, peak_limits_fx[bwidth_fx]) > 0)) + { + if (P_in_plocs > 0) + { + *num_plocs = 0; move16(); /*activate noise only path only if normcorr vas valid energywise */ + } + } + } + +#ifdef DYNMEM_COUNT + Dyn_Mem_Out(); +#endif +#ifdef WMOPS + pop_wmops(); +#endif + } + + /*-------------------------------------------------------------------* + * subst_spec_fx() + * + * Substitution spectrum calculation + *-------------------------------------------------------------------*/ + + void subst_spec_fx( + const Word16 *plocs, /* i : The indices of the identified peaks Q0 */ + const Word32 *L_plocsi, /* i : Interpolated positions of the identified peaks Q16 */ + Word16 * num_plocs, /* i/o : Number of identified peaks Q0 */ + const Word16 time_offs, /* i : Time offset Q0 */ + Word16 * X, /* i/o : FFT spectrum */ + const Word16 *mag_chg, /* i : Magnitude modification Q15 */ + const Word16 ph_dith, /* i : Phase dither, 2*PI is not included. (Q15, i.e., between 0.0 and 1.0) */ + const Word16 *is_trans, /* i : (Transient) noise generation flags (either 0 or not 1 ) */ + const Word16 output_frame, /* i : Frame length Q0 */ + Word16 * seed, /* i/o : Random seed */ + const Word16 *alpha, /* i : Magnitude modification factors for fade to average Q15 */ + const Word16 *beta, /* i : Magnitude modification factors for fade to average Q15 */ + const Word16 *Xavg, /* i : Frequency group averages to fade to Q0 */ + const Word16 t_adv /* i : time adjustement excluding time_offs Q0 */ +#ifdef CR8_A_PLC_FADEOUT_TUNING + ,const Word16 fadeout, /* need for DC muting */ + Word16 * nonpure_tone_flag_ptr, /* i/o : non-pure single tone indicator state */ + const Word32 * L_Xavg /* i : Frequency group amp averages for tonal tilt analysis Max upshifted */ +#endif + ) + { + Word16 Xph_short; + Word32 L_corr_phase[MAX_PLOCS], L_Xph; + Word32 *pCorrPhase_L; + Word16 cos_F, sin_F, tmp; + Word16 peak_sin_F = 0, peak_cos_F = 0; + Word16 sin_F_fade2avg, cos_F_fade2avg; + Word16 fs_idx; + Word16 Lprot, m, i, e, im_ind, delta_corr_up, delta_corr_dn, delta_tmp; + UWord16 lsb; + Word16 j, re, im, *pReX, *pImX, lastPeak, lprotBy2Minus1, segmentLen; + Word16 pkLocation_1, pkLocation, pkLocation1; + const Word16 *pPlocs; + const Word32 *pPlocsi_L; + Word32 L_acc; + Word16 Lprot_inv; + Word16 k; + Word16 tmp2; + Word16 alpha_local; + Word32 tmp_L; + Word16 mag_chg_local; + const Word16 *gwlpr_fxPlus1; + Word16 one_peak_flag_mask; + Word16 noise_mag_scale_neg; + Word16 up_shift_adj; + +#ifdef DYNMEM_COUNT + Dyn_Mem_In("subst_spec_fx", sizeof(struct { + Word16 Xph_short; + Word32 L_corr_phase[MAX_PLOCS], L_Xph; + Word32 *pCorrPhase_L; + Word16 cos_F, sin_F, tmp; + Word16 peak_sin_F, peak_cos_F; + Word16 sin_F_fade2avg, cos_F_fade2avg; + Word16 fs_idx; + Word16 Lprot, m, i, e, im_ind, delta_corr_up, delta_corr_dn, delta_tmp; + UWord16 lsb; + Word16 j, re, im, *pReX, *pImX, lastPeak, lprotBy2Minus1, segmentLen; + Word16 pkLocation_1, pkLocation, pkLocation1; + const Word16 *pPlocs; + const Word32 *pPlocsi_L; + Word32 L_acc; + Word16 Lprot_inv; + Word16 k; + Word16 tmp2; + Word16 alpha_local; + Word16 expo; + Word32 tmp_L; + Word16 mag_chg_local; + const Word16 *gwlpr_fxPlus1; + Word16 one_peak_flag_mask; + Word16 noise_mag_scale_neg; + Word16 up_shift_adj; + })); +#endif + + if (time_offs == 0) + { +#ifdef WMOPS + push_wmops("PhECU::subst_spec_fx(1st)"); +#endif + } + else + { +#ifdef WMOPS + push_wmops("PhECU::subst_spec_fx(N)"); +#endif + } + + + gwlpr_fxPlus1 = &(gwlpr_fx[1]); /* ptr init */ + fs_idx = mult(output_frame, (Word16)(32768.0 / 99.0)); /* truncation needed , i.e no rounding can be applied here */ + ASSERT(fs_idx == (output_frame / 100)); + Lprot = LprotSzPtr[fs_idx];move16(); + Lprot_inv = InvLprot_Q22[fs_idx]; move16(); + + tmp2 = add(mult_r(time_offs, oneOverFrameQ15Tab[fs_idx]), 1);/* save a local burst_len for securing DC and fs/2 muting */ + + /* Correction/evolution phase of the identified peaks */ + IF(s_or(is_trans[0], is_trans[1]) != 0) + { + *num_plocs = 0; move16(); + } + ELSE + { + + tmp = t_adv; + + tmp = add_sat(tmp, time_offs); + /* NB tmp can be stored in Word16 Q0 as max used value is 684+(OFF FRAMELIMIT==60)*480 = 29484 */ + tmp_L = L_mult0(tmp, Lprot_inv); + + + tmp = norm_l(tmp_L); + up_shift_adj = s_max(0, sub(4, tmp)); /* 48kHz : PLC frame 1..49 -> tmp_L<<4 , frame 50..60 -> tmpL<<3 */ + tmp_L = L_shl_sat(tmp_L, sub(4, up_shift_adj)); + tmp = round_fx_sat( tmp_L); + + + pPlocsi_L = L_plocsi; + pCorrPhase_L = L_corr_phase; + FOR(m = 0; m < *num_plocs; m++) + { + + /* tmp has variable resolution 10 or 9 bits */ + ASSERT( up_shift_adj >= 0); + Mpy_32_16_ss(L_shl_pos(*pPlocsi_L++, up_shift_adj), tmp, &L_acc, &lsb); + L_acc = L_add(L_shl_pos(L_acc, 5), lshr(lsb, 11)); + /* 5 lsb's actually unused though, as 6 bits are shifted out */ + *pCorrPhase_L++ = L_acc; move32();/* in Q16. 2*PI is not included. */ + } + } + + one_peak_flag_mask = (Word16)0xFFFF; move16(); /* all ones mask -> keep */ +#ifdef CR8_A_PLC_FADEOUT_TUNING + test(); logic16(); + IF((*num_plocs > 0) && sub(*num_plocs, 3) < 0) + { + one_peak_flag_mask = 0x0000; move16(); /* all zeroes mask -> zeroes in valleys, single clean tone assumed */ + + /* revert initial pure tone decision in some cases */ + logic16(); logic16(); + IF((sub(*nonpure_tone_flag_ptr, 0) < 0) && + ((sub(fs_idx, 2) == 0)/* SemiSWB 24 kHz */ || (sub(fs_idx, 4) >= 0)) /* FB 48 kHz */ + ) + { + /* in the first lost frame analyze spectra and spectral bands to possibly reverse an initial pure sine assumption */ + *nonpure_tone_flag_ptr = plc_phEcu_nonpure_tone_ana_fx(plocs, *num_plocs, X, L_Xavg, Lprot, fs_idx); + +#ifdef LOCAL_PLC2_TON_ANA_DEACTIVATE + *nonpure_tone_flag_ptr = 0; /* dbg of inactive tone analysis */ +#endif + } + + + if (sub(*nonpure_tone_flag_ptr, 0) > 0) + { + /* actually revert single pure tone detection */ /* 0-> mute all surrounding valley bins in evolution , 0xff -> generate noise in all valleys */ + one_peak_flag_mask = (Word16)0xFFFF; move16(); /* all ones mask -> keep */ + } + } +#else + logic16(); + if ((*num_plocs > 0) && sub(*num_plocs, 3) < 0) + { + one_peak_flag_mask = 0x0000; move16(); /* all zeroes mask -> zero */ + } +#endif + + + noise_mag_scale_neg = 0; move16(); /* no change of valley noise magnitude */ + logic16(); + if ((*num_plocs == 0) || (time_offs != 0)) + { /* only adj_scale noise amplitude when we have no WC path , or in all noise frame */ + noise_mag_scale_neg = -32768; move16(); /* all ones --> scale_noise */ + } + + IF(*num_plocs == 0) + { + X[0] = 0; move16(); /* reset DC if there are no peaks */ + X[shr_pos(Lprot, 1)] = 0; move16(); /* also reset fs/2 if there are no peaks */ + } + +#ifdef CR8_A_PLC_FADEOUT_TUNING + /* the binary selection of fadeout scheme */ + tmp = (PLC2_FADEOUT_IN_MS - PLC2_FADEOUT_IN_MS_MIN) / PLC2_FADEOUT_RES; move16(); + if (fadeout != 0) + { + tmp = (PLC2_FADEOUT_LONG_IN_MS - PLC2_FADEOUT_IN_MS_MIN) / PLC2_FADEOUT_RES; move16(); + } + + IF(sub(tmp2, add(fade_scheme_tab_fx[tmp][1],1) ) > 0) +#else + IF(sub(tmp2, (BURST_ATT_THRESH+1)) > 0) +#endif + { + /* also start DC scaling attenuation */ + X[0] = mult(alpha[0], X[0]); move16(); + /* start fs/by2 attenuation */ + X[shr_pos(Lprot, 1)] = mult(alpha[s_min(add(fs_idx, LGW8K), LGW48K)], X[shr_pos(Lprot, 1)]); move16(); + } + + + lprotBy2Minus1 = sub(shr_pos(Lprot, 1), 1); + + /* for 48k the last (63+1+63) 128/2-1 values above 20 kHz are always zeroes */ + { /* after a last, peak no need to evolve above 20kHz , those coeffs have been/ will be zeroed already */ + /* DC, Xused,ReZeroed, fs/2, ImZeroed, ImUsed */ + /*N: 1, 320 , 63 , 1 , 63 , 320 */ + /*Cind: 0, 1-320, 321-383 , 384 , 385-447, 448 -767 */ + lprotBy2Minus1 = s_min( lprotBy2Minus1, 320); + /*only process up to bin X[320] , 63 coeffs X[321] fwd should already be zeroed */ + } + + i = 1; move16(); /* index in the X[DC, ReX part of X_Sav ,i.e *pReX == X[i] */ + k = 0; move16(); + + pReX = X + i; + im_ind = (Lprot - 1); /* ptr init */ + pImX = X + im_ind; + pPlocs = plocs; + pCorrPhase_L = L_corr_phase; + + + pkLocation_1 = -4; move16(); /* dummy value to avoid Out of Array Read */ + pkLocation = -3; move16(); /* dummy value to avoid Out of Array Read for the *num_plocs==0 case */ + pkLocation1 = -2; move16(); /* dummy value to avoid Out of Array Read */ + + IF (*num_plocs != 0) + { + + pkLocation = *pPlocs; move16(); /* N.B. No post-increment */ + lastPeak = sub(*num_plocs, 1); + if (lastPeak >= 0) + { + pkLocation1 = *pPlocs++; move16(); /* get a next peak */ + } + } + + FOR(m = 0; m < *num_plocs; m++) + { + pkLocation_1 = pkLocation; /* plocs[m - 1] */ move16(); + pkLocation = pkLocation1; /* plocs[m] */move16(); + + /*location dependent update of plocs[m + 1] */ + if ( sub(lastPeak, m) > 0) + { /* only read additional peak when teher is a valid position to read */ + pkLocation1 = *pPlocs++; /* plocs[m + 1] */ move16(); + } + + delta_tmp = shr_pos(sub(sub(pkLocation, pkLocation_1), 1), 1); + if (m == 0) + { + delta_tmp = DELTA_CORR; move16(); /* first peak special case */ + } + delta_corr_dn = s_min(delta_tmp, DELTA_CORR); + + delta_tmp = shr_pos(sub(sub(pkLocation1, pkLocation), 1), 1); + if (sub(m, lastPeak) >= 0) + { + delta_tmp = DELTA_CORR; move16(); + } + delta_corr_up = s_min(delta_tmp, DELTA_CORR); /* last peak special case */ + + + /* Input Xph */ + segmentLen = sub(sub(pkLocation, delta_corr_dn), i); /* may be negative */ + + ASSERT(pReX == &(X[i])); + ASSERT(*pReX == X[i]); /*before first, nth valley*/ + + FOR(j = 0; j < segmentLen; j++) /* valley section , may be skipped for segmentlen < 0 */ + { + + *seed = rand_phase_fx(*seed, &sin_F, &cos_F); + + /* phase scrambling */ + rotate_W16_fx(*pReX, *pImX, cos_F, sin_F, &tmp, &im); /* tmp=real part, should be inlined */ + UNUSED(re); + + /* i.e. add a bit of magnitude scrambling around 1.0 in longer bursts */ + *seed = rand_phase_fx(*seed, &sin_F_fade2avg, &cos_F_fade2avg); + IF(noise_mag_scale_neg != 0) + { + valley_magnitude_adj_fx(&tmp, &im, *seed, cos_F); + /* use two random variables */ /*reuse cosF from regular X scrambling, + reuse *seed from fade2avg + */ + } + + IF( beta[k] != 0 ) + { + alpha_local = alpha[k]; /* no move as alpha_local is only needed for debug */ + /* the fade2avg mixing branch, fade2avg and transient downscaling and evolution rotation */ + tmp2 = mult_r(beta[k], Xavg[k]); + + { + tmp2 = s_and(tmp2, one_peak_flag_mask); + tmp = s_and(tmp, one_peak_flag_mask); + im = s_and(im, one_peak_flag_mask); + } + + *pReX++ = mac_r(L_mult(alpha_local, tmp), tmp2, cos_F_fade2avg); move16(); + *pImX-- = mac_r(L_mult(alpha_local, im), tmp2, sin_F_fade2avg); move16(); + } + ELSE + { /* the no fade2avg mixing branch, only transient downscaling and evolution rotation */ + { + tmp = s_and(tmp, one_peak_flag_mask); + im = s_and(im, one_peak_flag_mask); + } + + + *pReX++ = mult_r(mag_chg[k], tmp); move16(); + *pImX-- = mult_r(mag_chg[k], im); move16(); + } + i = add(i, 1); + ASSERT(pReX == &(X[i])); /* nth Valley */ + ASSERT(*pReX == X[i]); /* nth Valley */ + if (sub(i, gwlpr_fxPlus1[k]) >= 0) + { + k = add(k, 1); + } + } /* segment_len 1st++ etc valley excluding last */ + + /* peak area section */ + + e = s_min(lprotBy2Minus1, add(pkLocation, delta_corr_up)); + segmentLen = sub(e, sub(i, 1)); + + + L_Xph = *pCorrPhase_L; move32(); + /* rounding here, add "0.5" before extracting the 10 bits for table lookup */ + Xph_short = s_and(extract_l(L_shr_pos_pos(L_add(L_Xph, (1L << (16 - 10 - 1))), 16 - 10)), 0x3ff); + /* 10 bits precision after radix point, for a virtual 0-1023 sin/cos table lookup */ + + + get_sin_cosQ10opt(Xph_short, &peak_sin_F, &peak_cos_F); + + + ASSERT(pReX == &(X[i])); /*before peak*/ + FOR(j = 0; j < segmentLen; j++) + { + mag_chg_local = mag_chg[k]; /* mag_chg_local actually only need for debugging , no move16()*/ + + UNUSED(ph_dith); + *seed = extract_l(L_mac0(13849, *seed, 31821)); + rotate_W16_fx(*pReX, *pImX, peak_cos_F, peak_sin_F, &tmp, &im); /* should be inlined */ + UNUSED(re); + + *seed = rand_phase_fx(*seed, &sin_F, &cos_F); + + IF( beta[k] != 0 ) + { /* fade2avg path alpha*X_sav + beta *Xavg */ + alpha_local = mag_chg_local; /* no move alpha_local only needed for dbg */ + tmp2 = mult_r(beta[k], Xavg[k]); + + + *pReX++ = mac_r(L_mult(alpha_local, tmp), tmp2, cos_F); move16(); + *pImX-- = mac_r(L_mult(alpha_local, im), tmp2, sin_F); move16(); + } + ELSE + { + *pReX++ = mult_r(mag_chg_local, tmp); move16(); + *pImX-- = mult_r(mag_chg_local, im); move16(); + } + + i = add(i, 1); + ASSERT(pReX == &(X[i])); + ASSERT(*pReX == X[i]); + if (sub(i, gwlpr_fxPlus1[k]) > 0) + { + k = add(k, 1); + } + } /* segment_length Peak*/ + pCorrPhase_L++; + } + + segmentLen = sub(lprotBy2Minus1, sub(i, 1)); /* tail/valley noise-bins */ + + /* for 48k the last 63+1+63 = values above 20 kHz */ + { /* after last, peak no need to scramble above 20kHz , those coeffs have been/ will be zeroed already */ + /* DC, Xused,ReZeroed, fs/2, ImZeroed, ImUsed */ + /*N: 1, 320 , 63 , 1 , 63 , 320 */ + /*ind: 0, 1-320, 321-383 ,384 , 385-447, 448 -767 */ + /* segmentLen = sub(320, i-1); */ /*only process up to bin X[320] , 63 coeffs X[321] fwd should already be + zeroed */ + /* ASSERT(i-1+ segmentLen == lprotBy2Minus1 ); */ + } + + ASSERT(*pReX == X[i]); /* before a final valley*/ + FOR(j = 0; j < segmentLen; j++) + { + + + *seed = rand_phase_fx(*seed, &sin_F, &cos_F); + rotate_W16_fx(*pReX, *pImX, cos_F, sin_F, &tmp, &im); /* should be inlined , tmp=real part */ + + *seed = rand_phase_fx(*seed, &sin_F_fade2avg, &cos_F_fade2avg); + /* i.e. add a bit of magnitude scrambling around 1.0 in longer bursts */ + IF(noise_mag_scale_neg != 0) + { + valley_magnitude_adj_fx(&tmp, &im, *seed, cos_F); + /*reuse cosF from regular X scrambling, + reuse *seed from fade2avg */ + } + + tmp = s_and(tmp, one_peak_flag_mask); + im = s_and(im, one_peak_flag_mask); + IF(beta[k] != 0) + { /* fade2avg path never in first BFI frame */ + + alpha_local = alpha[k]; /* no move as alpha_local is only needed for debug */ + tmp2 = mult_r(beta[k], Xavg[k]); + { + tmp2 = s_and(tmp2, one_peak_flag_mask); + } + + + *pReX++ = mac_r(L_mult(alpha_local, tmp), tmp2, cos_F_fade2avg); move16(); + *pImX-- = mac_r(L_mult(alpha_local, im), tmp2, sin_F_fade2avg); move16(); + } + ELSE + { + + *pReX++ = mult_r(mag_chg[k], tmp); move16(); + *pImX-- = mult_r(mag_chg[k], im); move16(); + } + i = add(i, 1); + ASSERT(*pReX == X[i]); + if (sub(i, gwlpr_fxPlus1[k]) > 0) + { + k = add(k, 1); + } + } /* segment_len last valley */ + + + + +#ifdef DYNMEM_COUNT + Dyn_Mem_Out(); +#endif +#ifdef WMOPS + pop_wmops(); +#endif + } + + void my_wtda_fx(const Word16 *new_audio, /* i : input audio to be windowed Q0 20 ms , OPT can be output as well */ + const Word16 *const win2ms_init, /* i: 2 ms initial part of pre_tda window */ + const Word16 *const win16ms_center, /* i: 16 ms combined part of pre_tda IWHR+MDCT-ana */ + Word32 *L_wtda_audio, /* o : tda audio Q16 20 ms */ + const Word16 L, Word8 *scratchBuffer) /* Size = 8 * MAX_L_FRAME */ + { + Word16 i, L2; /*,L4;*/ + const Word16 *pX; + const Word16 *pW; + Word32 *p1_L, *p2_L, *p3_L, *p4_L; + Word32 *L_w_audio; /*OPt 1 use input buffer , OPT2, may be shortened from 20 ms to 16 ms due to + zeroed parts*/ + Word32 *pY_L, *pa1_L, *pa2_L; + +#ifdef DYNMEM_COUNT + Dyn_Mem_In("my_wtda_fx", sizeof(struct { + Word16 i, L2; /*,L4;*/ + const Word16 *pX; + const Word16 *pW; + Word32 *p1_L, *p2_L, *p3_L, *p4_L; + Word32 *L_w_audio; /*OPT 1 use input buffer, OPT2, may be shortened from 20 ms to 16.25+(1.75) ms + due to zeroed parts*/ + Word32 *pY_L, *pa1_L, *pa2_L; + })); +#endif + +#ifdef WMOPS + push_wmops("PhECU::my_wtda_fx"); +#endif + + L_w_audio = (Word32 *)scratchAlign(scratchBuffer, 0); /* Size = 4 * 2 * MAX_L_FRAME */ + + /* |111111|222222|333333|444444 */ + /* |p1 p2| p3||p4 */ + + /* Apply analysis window */ + + pX = new_audio; + pY_L = L_w_audio; + + pW = win2ms_init; + FOR(i = 0; i < ((2 * L / 10)); i++) /* Loop over 2ms window MDCT-ana length */ + { + *pY_L++ = L_mult(*pX++, *pW++); move32(); + } + + pW = win16ms_center; + /* 20 ms - 2ms - 3.75 ms = 14.25 ms */ + FOR(i = 0; i < (2 * L - (2 * L / 10) - ((3 * 2 * L) / 16)); + i++) /* Loop over remaining 14.25ms, currently out of a 16 ms stored length */ + { + *pY_L++ = L_mult(*pX++, *pW++); move32(); + } + + + /* tda */ + L2 = shr_pos_pos(L, 1); /* length of tda blocks */ + + p1_L = L_w_audio; /* block 1 fwd */ + p2_L = L_w_audio + L - 1; /* block 2 rev */ + p3_L = L_w_audio + L + L2 - 1; /* block 3 rev */ + p4_L = L_w_audio + L + L2; /* block 4 fwd */ + + pa1_L = L_wtda_audio; /* first part output */ + pa2_L = L_wtda_audio + L2; /* second part output */ + + FOR(i = 0; i < (L / 8); i++) + { + /* first 1.25ms part of tda signal -p3_rev -p4_fwd */ + *pa1_L++ = L_negate(L_add_sat(*p3_L--, *p4_L++)); move32(); + } + FOR(; i < L2; i++) + { + /* first front part 3.75 ms p4_l is zeroes -p3_rev + (-p4_fwd==0) */ + *pa1_L++ = L_negate(*p3_L--); move32(); + } + + FOR(i = 0; i < L2; i++) + { + /* second part of tda signal p1 -p2_rev */ + *pa2_L++ = L_sub_sat(*p1_L++, *p2_L--); move32(); + } + +#ifdef DYNMEM_COUNT + Dyn_Mem_Out(); +#endif +#ifdef WMOPS + pop_wmops(); +#endif + return; + } + + /*-------------------------------------------------------------------------- + * rec_wtda() + * + * Windowing and TDA of reconstructed frame + *--------------------------------------------------------------------------*/ + + + static void + rec_wtda_fx( + Word16 *X, /* i : iFFT(X-evolved) TD-signal o: dbg 16 ms */ + Word32 *L_ecu_rec, /* o : Reconstructed frame in tda domain Qx? */ + const Word16 output_frame, /* i : Frame length */ + const Word16 Lprot, /* i : Prototype frame length */ + const Word16 *const win2ms_init, /* i: 2 ms initial part of pre_tda window */ + const Word16 *const win16ms_center, /* i: 16 ms combined part of pre_tda IWHR+MDCT-ana */ + const Word16 maxLen, + const Word16 *prevsynth, + const Word16 Q_psMinus1, /*i: Q prev_synth minus 1 , (-1 to match Q of Xsav in first bfi frame ) */ + Word8 *scratchBuffer) /* Size = 12 * MAX_L_FRAME */ + { + Word16 l, Lprot2; + Word16 *rec_buf; + Word16 *xsubst_; /*,*out_ptr;*/ + + Word16 ola_old[COPY_LEN_48K + OLA_LEN_48K]; /* 3.75 ms */ + Word16 work_len; + Word16 copy_len; + Word16 ola_len; + + + Word8 *buffer_wtda; + +#ifdef DYNMEM_COUNT + Dyn_Mem_In("rec_wtda_fx", sizeof(struct { + Word16 l, Lprot2; + Word16 *rec_buf; + Word16 *xsubst_; /*,*out_ptr;*/ + Word8 *buffer_wtda; + })); +#endif + +#ifdef WMOPS + push_wmops("PhECU::rec_wtda_fx"); +#endif + + rec_buf = scratchAlign(scratchBuffer, 0); /* Size = 2 * 2 * MAX_L_FRAME */ + buffer_wtda = (Word8 *)scratchAlign(rec_buf, sizeof(*rec_buf) * (2 * maxLen)); /* Size = 4 * 2 * MAX_L_FRAME */ + + xsubst_ = rec_buf; + Lprot2 = shr_pos_pos(Lprot, 1); + + /* extract reconstructed frame with ld window into rec_buf */ + l = sub(output_frame, Lprot2); + basop_memmove(xsubst_ + l, X, (Lprot) * sizeof(Word16)); /* 16 ms IFFT raw output */ + copy_len = COPY_LEN[FRAME2FS_IDX(output_frame)]; + ola_len = OLA_LEN[FRAME2FS_IDX(output_frame)]; + work_len = add(copy_len, ola_len); + /* Copy and scale copy part 2ms from prevsynth */ + basop_memmove(rec_buf, &prevsynth[Lprot - work_len], (copy_len) * sizeof(Word16)); /* 2ms out of 3.75 ms copied */ + Scale_sig_sat(rec_buf, copy_len, sub(-3, Q_psMinus1)); /* inplace scaling by 2^(-Q_ps-4) */ + + + /* Copy, window and scale 1.75 ms ola part from prevsynth , into a temporary buffer ola_old */ + + + windowing_ola(&prevsynth[Lprot - ola_len], ola_old, w_old[FRAME2FS_IDX(output_frame)], ola_len); /* 1.75 ms */ + + Scale_sig_sat(ola_old, ola_len, sub(-3, Q_psMinus1)); /* inplace scaling by 2^(-Qps-4) */ + + /* Window 1.75 ms length inplace recreated X=IFFT(prototype) signal copied into rec_buf signal */ + windowing_ola(&rec_buf[copy_len], &rec_buf[copy_len], w_new[FRAME2FS_IDX(output_frame)], ola_len); + /* mix add the two windowed components */ + ola_add(&rec_buf[copy_len], ola_old, &rec_buf[copy_len], ola_len); /* OPT: sat check */ + + my_wtda_fx(rec_buf, + win2ms_init, /* i: 2 ms initial part of pre_tda window */ + win16ms_center, /* i: 16 ms combined part of pre_tda IWHR+MDCT-ana */ + L_ecu_rec, output_frame, buffer_wtda); /* */ + + +#ifdef DYNMEM_COUNT + Dyn_Mem_Out(); +#endif +#ifdef WMOPS + pop_wmops(); +#endif + + return; + } + + /*-------------------------------------------------------------------------- + * rec_frame_fx() + * + * Frame reconstruction + *--------------------------------------------------------------------------*/ + void rec_frame_fx(Word16 * x, /* i : FFT spectrum 16 ms, o: ifft() TD debug signal 16ms */ + Word32 * L_ecu_rec, /* o : Reconstructed frame in tda domain 10ms buffer */ + const Word16 output_frame, /* i : Frame length */ + const Word16 Q, /* i : Xsav Q */ + const Word16 *const win2ms_init, /* i: 2 ms initial part of pre_tda window */ + const Word16 *const win16ms_center, /* i: 16 ms combined part of pre_tda IWHR+MDCT-ana */ + Word16 maxLprot, + const Word16 *prevsynth, + const Word16 Q_prevsynthMinus1, /* i : prevsynthQ-1 or xfp Q */ + Word8 *scratchBuffer /* Size = 4 * MAX_LPROT + 12 * MAX_L_FRAME */ + ) + { + Counter i; + Word16 Lprot; + Word32 *L_x; + Word32 *pX_L; + Word16 *pX; + Word16 fft_scale; + Word8 * buffer_fft; + +#ifdef DYNMEM_COUNT + Dyn_Mem_In("rec_frame_fx", sizeof(struct { + Counter i; + Word16 Lprot; + Word32 *L_x; + Word32 *pX_L; + Word16 *pX; + Word16 fft_scale; + Word8 * buffer_fft; + })); +#endif + +#ifdef WMOPS + push_wmops("PhECU::rec_frame_fx"); +#endif + + L_x = (Word32 *)scratchAlign(scratchBuffer, 0); /* Size = 4 * MAX_LPROT */ + buffer_fft = (Word8 *)scratchAlign(L_x, sizeof(*L_x) * maxLprot); /* Size = 4* (2+1) * MAX_L_FRAME */ + + /* Initialize to FB constants */ + Lprot = mult(output_frame, (Word16)(32768.0 / 99.0)); /* truncation needed , i.e no rounding can be applied here */ + ASSERT(Lprot == (output_frame / 100)); + Lprot = LprotSzPtr[Lprot]; move16(); + + + /* Convert stored 16 bit into 32bit for fft */ + flippedW16_2_intlvW32(x, sub(shr_pos_pos(Lprot, 1), 1), Lprot, L_x); + /*scratch x now free for re-use */ + + fft_scale = -1; move16(); + +#ifdef WMOPS + push_wmops("PhECU::IFFT_fx"); +#endif + BASOP_irfftN(L_x, Lprot, &fft_scale, buffer_fft); +#ifdef WMOPS + pop_wmops(); +#endif + + pX_L = &L_x[0]; + pX = &x[0]; /* scratch x reused */ + + { + FOR(i = 0; i < Lprot; i++) + { + *pX++ = extract_h(L_shl_sat(*pX_L++, fft_scale)); move16(); + } + } + /* Scratch L_x may be released */ + + + /* Saturation possible when rescaling to Q0 if there are random bit errors in the bit stream + * One may use one guard bit to better handle this - though it should not be needed for normal + * operation. + */ + Scale_sig_sat(x, Lprot, negate(Q)); /* scale by 2^(-Q) */ + + /*scratch x is Lprot word16 */ + /* scatch need for win-TDA XXX */ + /* scrcatch need for TDA XXX */ + + rec_wtda_fx(x, L_ecu_rec, output_frame, Lprot, + win2ms_init, /* i: 2 ms initial part of pre_tda window */ + win16ms_center, /* i: 16 ms combined part of pre_tda IWHR+MDCT-ana */ + s_max(output_frame, 160), + prevsynth, + Q_prevsynthMinus1, /* NB: prevsynth Q may change from prev_bfi=0 to prev_bfi==1, due to phase + of signal or PLC2-muting */ + buffer_fft); + + +#ifdef DYNMEM_COUNT + Dyn_Mem_Out(); +#endif +#ifdef WMOPS + pop_wmops(); +#endif + return; + } + + /*-------------------------------------------------------------------------- + * hq_phase_ecu_fx() + * + * Main routine for HQ phase ECU + *--------------------------------------------------------------------------*/ + void hq_phase_ecu_fx( + const Word16 *prevsynth, /* i : buffer of previously synthesized signal currently 16ms */ + Word32 * L_ecu_rec, /* o : reconstructed frame in tda domain , also tmp w32_fft buffer */ + Word16 * time_offs, /* i/o: Sample offset for consecutive frame losses*/ + Word16 * X_sav, /* i/o: Stored spectrum of prototype frame */ + Word16 * Q_spec, /* o: Q value of stored spectrum */ + Word16 * num_p, /* i/o: Number of identified peaks */ + Word16 * plocs, /* i/o: Peak locations */ + Word32 * L_plocsi, /* i/o: Interpolated peak locations Q16 */ + const Word16 env_stab, /* i : Envelope stability parameter */ + const Word16 f0hzLtpBinQ7, /* i: LTP bin frequency in normalized Hz Q7 */ + const Word16 norm_corrQ15_fx, /*i : correlation for lag at f0hzLtpBinQ7 */ + const Word16 prev_bfi, /* i : indicating burst frame error */ + Word16 old_is_transient[2], /* i/o : flags indicating noise generation frames */ + Word16 * mag_chg_1st, /* i/o: per band magnitude modifier for transients*/ + Word16 * mag_chg_gr, /* o: per band magnitude modifier, incl burst attenuation */ + Word16 * Xavg, /* i/o: Frequency group average gain to fade to */ + Word16 * beta_mute, /* o : Factor for long-term mute */ + const Word16 bwidth_fx, /* i : Encoded bandwidth */ + const Word16 output_frame, /* i : frame length */ + Word16 * seed_out_fxPtr, /* o: utput dbg NULL may be used*/ + Word16 * X_out, /* o: utput dbg NUll may be used */ + const Word16 t_adv, /* i : time adjustment including time_offs */ + const Word16 *const win2ms_init, /* i: 2 ms initial part of pre_tda window */ + const Word16 *const win16ms_center, /* i: 16 ms combined part of pre_tda IWHR+MDCT-ana */ + const Word16 *sp_ana_win, /* i : whr 3+10+3 window */ + Word16 q_fx_old_exp, /* i : exp of prev_synth */ + + Word16 maxLprot, /* i : maz spectrum buffer size */ + Word16 maxPlocs, /* i : max nb of peaks */ + Word32 L_oold_xfp_w_E_fx, Word16 oold_xfp_w_E_exp_fx, /* exp of time signale */ + Word16 oold_Ltot_exp_fx, /*true exp of energy */ + Word16 *oold_grp_shape_fx, Word32 L_old_xfp_w_E_fx, Word16 old_xfp_w_E_exp_fx, /* exp of time signale */ + Word16 old_Ltot_exp_fx, /*true exp of energy */ + Word16 *old_grp_shape_fx, + Word16 margin_prevsynth, +#ifdef CR8_A_PLC_FADEOUT_TUNING + const Word16 fadeout, + Word16 *nonpure_tone_flag_ptr, /* i/o : non-pure single tone indicator state */ +#endif + Word8 *scratchBuffer /* Size = 2 * MAX_LGW + 8 * MAX_LPROT + 12 * MAX_L_FRAME */ + ) + { + Word16 lprot; + Word16 *mag_chg, ph_dith, *X; + Word16 *xfp; + Word16 seed; + Word16 alpha[MAX_LGW], beta[MAX_LGW] ; + Word16 prevsynth_man_upshift; + Word16 Q_prevsynthMinus1; + Word8 *buffer; +# ifdef CR8_A_PLC_FADEOUT_TUNING + Word32 L_Xavg[MAX_LGW]; /* i/o : Frequency group amp averages for tonal tilt analysis Max upshifted */ +# endif +#ifdef DYNMEM_COUNT + Dyn_Mem_In("hq_phase_ecu_fx", sizeof(struct { + Counter i; + Word16 lprot; + Word16 *mag_chg, ph_dith, *X; + Word16 seed; + Word16 alpha[MAX_LGW], beta[MAX_LGW]; + Word16 prevsynth_man_upshift; + Word16 Q_prevsynthMinus1; + Word8 *buffer; + // ToDO Word32 L_Xavg[MAX_LGW]; + })); +#endif + + if (!prev_bfi) + { +#ifdef WMOPS + push_wmops("PhECU::hq_phase_ecu_fx(1st)"); +#endif + } + else + { +#ifdef WMOPS + push_wmops("PhECU::hq_phase_ecu_fx(N)"); +#endif + } + + mag_chg = (Word16 *)scratchAlign(scratchBuffer, 0); /* Size = 2 * MAX_LGW */ + X = (Word16 *)scratchAlign(mag_chg, sizeof(*mag_chg) * MAX_LGW); /* Size = 2 * MAX_LPROT == 1 Word16*MAX_LPROT */ + xfp = (Word16 *)scratchAlign(X, sizeof(*X) * maxLprot); /* Size = 2 * MAX_LPROT == 1 Word16*MAX_LPROT */ + buffer = (Word8 *)scratchAlign(xfp, sizeof(*xfp) * maxLprot); /* Size = 4 * MAX_LPROT + 12 * MAX_L_FRAME */ + + /* buffer size = Word32 * MAX_LPROT (FFT, IFFT) DRAM + + 3*Word32 * MAX_L_FRAME */ + + basop_memset(alpha, 0, MAX_LGW*sizeof(Word16)); + basop_memset(beta, 0, MAX_LGW*sizeof(Word16)); + + lprot = LprotSzPtr[bwidth_fx]; move16(); + + test(); + ASSERT(prev_bfi >= 0 && prev_bfi <= 1); + IF( prev_bfi == 0 ) /* inside PhECU we can check vs 0 */ + { + *time_offs = 0; move16(); +#ifdef CR8_A_PLC_FADEOUT_TUNING + *nonpure_tone_flag_ptr = -1; move16(); /* flag nonpure tone flag for new analysis */ +#endif + /* analysis made outside, up/down scaling here from static RAM to dynamic RAM */ + /* prevsynth_in_flt = prev_synth_man*2.^(-15 + exp_old) */ + /* X_sav_flt = X_man/2.^(Q_spec) */ + + /* 1 bit headroom needed in xfp_tmp_buf for FFT processing into X_sav */ + /* margin_prevsynth = actual margin in incoming 16 ms xpf segment */ + /* q_fx_old_exp was computed on full 21+ ms updatepcm buffer) */ + + ASSERT(margin_prevsynth >= 0 && (margin_prevsynth <= 16)); + + prevsynth_man_upshift = + sub(margin_prevsynth, 1); /* 0 --> -1(==down), 1--> 0 , 2 --> 1(==up), ... */ + ASSERT(prevsynth_man_upshift >= -16 && prevsynth_man_upshift <= 15); /* avoid Overflow in shr, shl */ + *Q_spec = sub(15, sub(q_fx_old_exp, prevsynth_man_upshift)); + /* Q_spec target is to create 1 additional bit of margin in the xfp TD buffer , before converting to + * Xsav + */ + + if (margin_prevsynth == 0) + { + Word16 Qold = 15 - (q_fx_old_exp + 1); + Word16 tmp_man_upshift = margin_prevsynth - 1; /* 1 .. -15 */ + Word16 Qnew = 15 - (q_fx_old_exp - tmp_man_upshift); + assert(Qold == Qnew); + UNUSED(Qold); + UNUSED(Qnew); + } + if (margin_prevsynth == 1) + { + Word16 Qold = 15 - (q_fx_old_exp + 0); + assert(*Q_spec == Qold); + UNUSED(Qold); + } + if (margin_prevsynth == 2) + { + Word16 Qold = 15 - (q_fx_old_exp - 1); + assert(*Q_spec == Qold); + UNUSED(Qold); + } + + Q_prevsynthMinus1 = sub(15, add(q_fx_old_exp, +1)); /* dbg to use non-scaled prevsynth for OLA */ + + /* Q of prev_synth now separated from prev_bfi=0 and prev_bfi==1 */ + +#ifdef USE_TMPXFP_IN_OLA + Q_prevsynthMinus1 = *Q_spec; /* a possibly upscaled Q */ +#endif + + + Copy_Scale_sig( + prevsynth, xfp, lprot, + prevsynth_man_upshift); /* unscaled prevsynth is still used by rec_frame, copy to a temporary + xfp analysis buffer, and scale down to a margin of 1 bit */ + + + trans_burst_ana_fx( + ((void *)NULL), + mag_chg, &ph_dith, mag_chg_1st, output_frame, *time_offs, env_stab, alpha, beta, beta_mute, Xavg, + (*Q_spec), L_oold_xfp_w_E_fx, oold_xfp_w_E_exp_fx, oold_Ltot_exp_fx, oold_grp_shape_fx, + L_old_xfp_w_E_fx, old_xfp_w_E_exp_fx, old_Ltot_exp_fx, old_grp_shape_fx, +#ifdef CR8_A_PLC_FADEOUT_TUNING + fadeout, + L_Xavg, /* full scale band amplitudes in first bfi frame */ +#endif + buffer); + + spec_ana_fx(&(xfp[0]), plocs, L_plocsi, num_p, X_sav, output_frame, bwidth_fx, + sp_ana_win, f0hzLtpBinQ7, norm_corrQ15_fx, maxLprot, maxPlocs, buffer); + } + ELSE + { + /* analysis made outside, possible up/down scaling here from static RAM to dynamic RAM */ + ASSERT(margin_prevsynth >= 0 && (margin_prevsynth <= 15)); + + /* prev_synth may have been scaled outside by update_pcm() function */ + /* prevsynth_in_flt = prev_synth_man*2.^(-15 + exp_old) */ + /* first bfi frame: X_sav_flt = X_man/2.^(*Q_spec) */ + /* this bfi frame prev_synth(TD) is mixed with ifft signal(TD,from Q_spec) in rec_frame_fx + variable Q_prevsynthMinus1 provided to rec_frame for this TD+TD mixing + */ + + Q_prevsynthMinus1 = sub(15, add(q_fx_old_exp, +1)); /* for now, "old" use of unscaled prevsynth for added OLA */ + +#ifdef USE_TMPXFP_IN_OLA + { /* DBG target here is to instead upshift to a zero margin */ + /* but Q value is maintained to match the save Xsav *Q_spec which is used with an offset of " -1" */ + /* prevsynth_man_upshift = -prevsynth_margin ; */ + Word16 tmp, worklen = add(hamm_len2Tab[bwidth_fx], shr(hamm_len2Tab[bwidth_fx], 2)); + tmp = mult(7680, lprot); /* needs to truncate to integer */ + ASSERT(tmp == worklen); + Copy_Scale_sig(&prevsynth[lprot - worklen], &xfp[lprot - worklen], worklen, + margin_prevsynth); /* only scale up last 3.75 ms */ + Q_prevsynthMinus1 = sub(15, add(q_fx_old_exp, margin_prevsynth)); /*-1 does not make sense */ + } +#endif + + *time_offs = add_sat(*time_offs, output_frame); + + trans_burst_ana_fx( + ((void *)NULL), + mag_chg, &ph_dith, mag_chg_1st, output_frame, *time_offs, env_stab, alpha, beta, beta_mute, Xavg, + (0), /* *Q_spec input only used in first bfi frames for burst analysis */ + L_oold_xfp_w_E_fx, oold_xfp_w_E_exp_fx, oold_Ltot_exp_fx, oold_grp_shape_fx, L_old_xfp_w_E_fx, + old_xfp_w_E_exp_fx, old_Ltot_exp_fx, old_grp_shape_fx, +#ifdef CR8_A_PLC_FADEOUT_TUNING + fadeout, + NULL, /* full scale band amplitudes , only used in first bfi frame */ +#endif + buffer); + } + /* cpy LPROT Word16 from Static RAM Xsav to working DRAM/scratch buffer X ;*/ + basop_memmove(X, X_sav, (lprot) * sizeof(Word16)); + /* seed for own_rand2 */ + seed = *time_offs; move16(); + + if (mag_chg_gr != NULL) /* o: dbg per band magnitude modifier, incl. burst attenuation */ + { + Counter k; + Word16 lgw_local = s_min(add(bwidth_fx, LGW8K), LGW48K); /* 4,5,6,7, (7/8) */ + for (k = 0; k < lgw_local; k++) + { + mag_chg_gr[k] = mag_chg[k]; /* dbg SNR output */ + } + } + + subst_spec_fx(plocs, L_plocsi, num_p, *time_offs, X, mag_chg, ph_dith, old_is_transient, output_frame, + &seed, alpha, beta, + Xavg, t_adv +#ifdef CR8_A_PLC_FADEOUT_TUNING + ,fadeout, + nonpure_tone_flag_ptr, /* i/o : non-pure single tone indicator state */ + L_Xavg /*i : only used in first bfi frame */ +#endif + ); + + if (seed_out_fxPtr != NULL) + { + *seed_out_fxPtr = seed; /* verify seed synch after subst_spec */ + } + + + if (X_out != NULL) + { + Word16 ii; + for (ii = 0; ii < lprot; ii++) + { + X_out[ii] = X[ii]; /* evolve spectrum, no moves counted as this is a dbg-vector info cpy */ + } + } + + /* reconstructed frame in tda domain */ + /* NB *Q_spec only updated in first bfi frame */ + + /*Scratch Analysis at this point */ + /* X fft input needed as evolved spectrum Lprot* Word16 */ + /* xfp not needed any longer Word16* Lprot */ + /* IFFT operation needs Word32*Lprot in and Word32*Lprot out */ + /* MDCT win operation may be inplace 2x MAX_L_FRAME */ + /* TDA output is 1x MAX_L_FRAME */ + + rec_frame_fx(X, L_ecu_rec, output_frame, *Q_spec, + win2ms_init, win16ms_center, + maxLprot, +#ifdef USE_TMPXFP_IN_OLA + xfp, /* only last 3.75 ms used, in both prevbfi=0 and prevBfi=1 i.e frames, xfp is an + upscaled prev_synth */ +#else + prevsynth, /*only last 3.75 ms used in both prevbfi=0 and prevBfi=1 i.e frames */ +#endif + Q_prevsynthMinus1, + buffer); + + +#ifdef DYNMEM_COUNT + Dyn_Mem_Out(); +#endif +#ifdef WMOPS + pop_wmops(); +#endif + } + + + static Word16 sqrt2ndOrder( /* o: in Q15 (2nd order least square approx.) */ + const Word16 x /* i: x must be in between 0.5 and 1.0 (Q15). */ + ) + { + Word32 acc; + Word16 z; +#ifdef WMOPS + push_wmops("PhECU::sqrt2ndOrder"); +#endif + + ASSERT(x >= 16384); + + acc = 1890205600L; /* 0.880195572812922 in Q31 */ move32(); + z = mac_r(acc, x, -6506); /* -0.198537395405340 in Q15 */ + acc = 682030261L; /* 0.317595089462249 in Q31 */ move32(); + z = mac_r(acc, z, x); /* in Q15 */ + + +#ifdef WMOPS + pop_wmops(); +#endif + return z; + } + + + /* Modified version to produce Word32 input to FFT */ + static void windowing_L( + const Word16 *x, /* i: Input signal */ + Word32 * L_y, /* o: Windowed output */ + const Word16 *win, /* i: Window coefficients */ + const Word16 rectLength, /* i: Offset in between the 1st and 2nd symmetric halves of the Hamming window */ + const Word16 halfLength /* i: Half of the total length of a complete Hamming window. */ + ) + { + Counter i; + Word32 * pY_L; + const Word16 *pX, *pW; + Word16 tmp_RL; + +#ifdef DYNMEM_COUNT + Dyn_Mem_In("windowing_L", sizeof(struct { + Counter i; + Word32 * pY_L; + const Word16 *pX, *pW; + })); +#endif + +#ifdef WMOPS + push_wmops("PhECU::windowing_L"); +#endif + + pX = x; + pW = win; + pY_L = L_y; + + FOR(i = 0; i < halfLength; i++) /* 1st symmetric half of the Hamming window */ + { + *pY_L++ = L_mult(*pX++, *pW++); move32(); + } + /* Periodic filter - one more rect sample before end tapering */ + + tmp_RL = add(rectLength, 1); + + if (rectLength == 0) + { + tmp_RL = 0; move16(); + } + /* If rectLength is zero, it's a pure Hamming window; otherwise Hamming-Rectangular. */ + FOR(i = 0; i < tmp_RL;i++) + { + *pY_L++ = L_deposit_h(*pX++); move32(); + } + tmp_RL = sub(halfLength, 1); + if (rectLength == 0) + { + tmp_RL = halfLength; move16(); + } + FOR(i = 0; i < tmp_RL; i++) /* 2nd symmetric half of the Hamming window. */ + { + *pY_L++ = L_mult(*pX++, *(--pW)); move32(); + } + +#ifdef DYNMEM_COUNT + Dyn_Mem_Out(); +#endif +#ifdef WMOPS + pop_wmops(); +#endif + } + + /* Modified version to produce Word16 input to FFT */ + static void windowing_ola(const Word16 *x, /* i: Input signal */ + Word16 * y, /* o: Windowed output */ + const Word16 *win, /* i: Window coefficients */ + const Word16 Length /* i: Half of the total length of a complete Hamming window. */ + ) + { + Counter i; + Word16 * pY; + const Word16 *pX, *pW; + +#ifdef DYNMEM_COUNT + Dyn_Mem_In("windowing_ola", sizeof(struct { + Counter i; + Word16 * pY; + const Word16 *pX, *pW; + })); +#endif + +#ifdef WMOPS + push_wmops("PhECU::windowing_ola"); +#endif + + pX = x; + pW = win; + pY = y; + + FOR(i = 0; i < Length; i++) /* 1st symmetric half of the Hamming window */ + { + *pY++ = mult_r(*pX++, *pW++); move16(); + } + +#ifdef DYNMEM_COUNT + Dyn_Mem_Out(); +#endif +#ifdef WMOPS + pop_wmops(); +#endif + } + + /* Modified version to produce Word16 input to FFT */ + static void ola_add(const Word16 *x, /* i: Input signal 1 */ + const Word16 *y, /* i: Input signal 2 */ + Word16 * z, /* o: Output signal */ + const Word16 Length /* i: Half of the total length of a complete window. */ + ) + { + Counter i; + Word16 * pZ; + const Word16 *pX, *pY; + +#ifdef DYNMEM_COUNT + Dyn_Mem_In("windowing_ola", sizeof(struct { + Counter i; + Word16 * pY; + const Word16 *pX, *pW; + })); +#endif + + + + pX = x; + pY = y; + pZ = z; + + FOR(i = 0; i < Length; i++) /* 1st symmetric half of the Hamming window */ + { + *pZ++ = add_sat(*pX++, *pY++); move16(); + } + +#ifdef DYNMEM_COUNT + Dyn_Mem_Out(); +#endif + + } + + /*----------------------------------------------------------------------------- + * magnSqrtApprox_fx() + * + * Approximation of sqrt(Square magnitude) of fft spectrum + * if min_abs <= 0.4142135*max_abs + * abs = 0.99*max_abs + 0.197*min_abs + * else + * abs = 0.84*max_abs + 0.561*min_abs + * end + * + * Note: even to handle the dynamics of sqrt(re^2+im^2) located on + * a scaled unit circle. One need to scale down the results + * with a factor 2, that is Q_out = Q_in - 1 + * sqrt(32768.^2+32768.^2) results in = 23170 Q0-1, + * which corresponds to 46341 in the Q0 domain + *----------------------------------------------------------------------------*/ + Word16 sqrtMagnApprox_fx( /* o : sqrt of magnitude square spectrum Q_in-1*/ + const Word16 re, /* i : Real part Q_in */ + const Word16 im /* i : Imag part Q_in */ + ) + { + /* Constants for Approximation of sqrt(Square magnitude) of fft spectrum + * >> num2str(round(0.4142135]*2.^15)) + * ans = 13573 + * >> num2str(round([0.99 0.197 0.84 0.561]*2.^14)) + * ans = 16220 3228 13763 9191 + */ + +#define C_0p4142135_Q15 13573 + +#define C_0p99_Q14 16220 +#define C_0p197_Q14 3228 +#define C_0p84_Q14 13763 +#define C_0p561_Q14 9191 + Word16 sgn_bit, re_abs, im_abs, max_abs, min_abs, sum; + Word16 jcoeffs[2][2] = { {C_0p99_Q14, C_0p197_Q14}, {C_0p84_Q14, C_0p561_Q14} }; + +#ifdef DYNMEM_COUNT + Dyn_Mem_In("sqrtMagnApprox_fx", sizeof(struct { + Word16 sgn_bit, re_abs, im_abs, max_abs, min_abs, sum; + Word16 jcoeffs[2][2]; + })); +#endif + +#ifdef WMOPS + push_wmops("PhECU::sqrtMagnApprox_fx"); +#endif + + /* Get values and move pointers */ + re_abs = abs_s(re); /* 1 cycle */ + im_abs = abs_s(im); /* 1 cycle */ + + /* Find max and min value */ + min_abs = s_min(re_abs, im_abs); /* 1 cycle */ + max_abs = s_max(re_abs, im_abs); /* 1 cycle */ + + /* Calc approximation depending on relation */ + sgn_bit = lshr(sub(mult(max_abs, C_0p4142135_Q15), min_abs), 15); /* 3 cycles */ + sum = mac_r(L_mult(max_abs, jcoeffs[sgn_bit][0]), min_abs, jcoeffs[sgn_bit][1]); /* 2 cycles */ +#ifdef DYNMEM_COUNT + Dyn_Mem_Out(); +#endif +#ifdef WMOPS + pop_wmops(); +#endif + return sum; + } + + /*----------------------------------------------------------------------------- + * fft_spec2_sqrt_approx_fx() + * + * Approximation of sqrt(Square magnitude) of fft spectrum + * if min_abs <= 0.4142135*max_abs + * abs = 0.99 max_abs + 0.197*min_abs + * else + * abs = 0.84 max_abs + 0.561*min_abs + * end + * + * Note: even to handle the dynamics of sqrt(re^2+im^2) located on + * a scaled unit circle. One need to scale down the results + * with a factor 2, that is Q_out = Q_in - 1 + * sqrt( -32768.^2 + -32768.^2 ) results in = 23170 Qin-1, + * which corresponds to 46341 in the Qin domain + *----------------------------------------------------------------------------*/ + + void fft_spec2_sqrt_approx_fx(const Word16 x[], /* i : Input vector: complex spectrum , Qin */ + Word16 xMagSqrt[], /* o : sqrt of magnitude square spectrum Qout=Qin-1*/ + const Word16 N /* i : Input vector x length */ + ) + { + Counter i; + Word16 l; + const Word16 *pRe, *pIm; + Word16 * pMagSqrt; + +#ifdef DYNMEM_COUNT + Dyn_Mem_In("fft_spec2_sqrt_approx_fx", sizeof(struct { + Counter i; + Word16 l; + const Word16 *pRe, *pIm; + Word16 * pMagSqrt; + })); +#endif + +#ifdef WMOPS + push_wmops("PhECU::fft_spec2_sqrt_approx_fx"); +#endif + + /* Magnitude at 0. only real component */ + pMagSqrt = &xMagSqrt[0]; + pRe = &x[0]; + *pMagSqrt++ = mult(abs_s(*pRe++), C_0p99_Q14); move16(); + + /* From 1 to (N/2 - 1). */ + pIm = &x[N - 1]; + + l = sub(shr_pos_pos(N, 1), 1); /* N/2 - 1. */ + l = s_min(l, (LPROT48K_RED / 2 - 1) + DELTA_CORR_F0_INT); + /* at 48 k the top 8 khz are always zero, and further peaks are not + located above LPROT48K_RED 32 kHz */ + FOR(i = 0; i < l; i++) + { + *pMagSqrt++ = sqrtMagnApprox_fx(*pRe++, *pIm--); move16(); + } + + /* The sqrt magnitude square at N/2 - only real component */ + *pMagSqrt = mult(abs_s(*pRe), C_0p99_Q14); move16(); + +#ifdef DYNMEM_COUNT + Dyn_Mem_Out(); +#endif +#ifdef WMOPS + pop_wmops(); +#endif + return; + } + + Word16 + imax2_jacobsen_mag_fx(/* o: The location, relative to the middle of the 3 given data point, of the maximum. + (Q15) */ + const Word16 *y_re, /* i: The 3 given data points. real part order -1 0 1 */ + const Word16 *y_im, /* i: The 3 given data points. imag part order 1 0 -1 (from FFT)*/ + const Word16 + special /* i: -1 = left edge special case, 0 = normal, +1 = right edge special case */ + ) + { + Word16 posi; + Word16 man, expo; + const Word16 *pY; + Word16 y_m1_re, y_0_re, y_p1_re; + Word16 y_m1_im, y_0_im, y_p1_im; + + Word16 D_re, D_im, N_re, N_im; + + Word32 L_sign, L_denom, L_numer; + +#ifdef DYNMEM_COUNT + Dyn_Mem_In("imax2_jacobsen_mag_fx", sizeof(struct { + Word16 posi; + Word16 man, expo; + const Word16 *pY; + Word16 y_m1_re, y_0_re, y_p1_re; + Word16 y_m1_im, y_0_im, y_p1_im; + Word16 D_re, D_im, N_re, N_im; + Word32 L_sign, L_denom, L_numer; + })); +#endif + +#ifdef WMOPS + push_wmops("PhECU::imax2_jacobsen_mag_fx"); +#endif + + /* Jacobsen estimates peak offset relative y_0 using + * X_m1 - X_p1 + * d = REAL ( ------------------- ) * c_jacob + * 2*X_0 - X_m1 -Xp1 + * + * Where c_jacob is a window dependent constant + */ +#define C_JACOB_Q14 18725 /* c_jacob = 1.1429; % assume 0.1875 hammrect window 'periodic' */ + + ASSERT(special == 0); /* always use other imax for edges cases */ + UNUSED(special); + + /* Get the bin parameters into variables */ + pY = y_re; + y_m1_re = *pY++; + y_0_re = *pY++; + y_p1_re = *pY++; + + /* Same for imaginary parts - note reverse order from FFT */ + pY = y_im; + y_p1_im = *pY++; + y_0_im = *pY++; + y_m1_im = *pY++; + + test(); + IF( norm_s(y_0_re) == 0 || norm_s(y_0_im) == 0 ) + { +#define JACOB_MARGIN 2 + /* for very high peaks the Complex denominator values may need to be downshifted 2 steps */ + y_0_re = shr_pos(y_0_re, JACOB_MARGIN); + y_0_im = shr_pos(y_0_im, JACOB_MARGIN); + + y_m1_re = shr_pos(y_m1_re, JACOB_MARGIN); + y_m1_im = shr_pos(y_m1_im, JACOB_MARGIN); + + y_p1_re = shr_pos(y_p1_re, JACOB_MARGIN); + y_p1_im = shr_pos(y_p1_im, JACOB_MARGIN); + } + + /* prepare numerator real and imaginary parts*/ + N_re = sub(y_m1_re, y_p1_re); + N_im = sub(y_m1_im, y_p1_im); + + /* prepare denominator real and imaginary parts */ + + D_re = sub(sub(shl_pos(y_0_re, 1), y_m1_re), y_p1_re); + D_im = sub(sub(shl_pos(y_0_im, 1), y_m1_im), y_p1_im); + + /* REAL part of complex division */ + L_numer = L_mac0(L_mult0(N_re, D_re), N_im, D_im); + L_denom = L_mac0(L_mult0(D_re, D_re), D_im, D_im); + L_sign = L_xor(L_numer, L_denom); /* Preserve the sign since div_s() only takes positive arguments. */ + + L_numer = L_abs(L_numer); + L_denom = L_abs(L_denom); + + test(); + IF(L_numer != 0 && L_denom != 0) + { + + man = plc_phEcu_ratio_fx(L_numer, L_denom, &expo); /* The mantissa is considered in Q15 */ + + man = mult_r(man, C_JACOB_Q14); + posi = shr_sat( man, sub(expo, 2)); + /* to Q15 (and due to saturation, it is automatically bound inside [-1.0,1.0].) */ + + if (L_sign < 0) /* Restore the sign. */ + { + posi = negate(posi); + } + } + ELSE + { + posi = 0; move16(); /* flat top, division is not possible choose center freq */ + } + +#ifdef DYNMEM_COUNT + Dyn_Mem_Out(); +#endif +#ifdef WMOPS + pop_wmops(); +#endif + return posi; /* Q15. The position either left or right relative to the index of the middle of the 3 given + data points. */ + } + + /* Convert 32 Bit FFT into 16 bit fft domain */ + static void intlvW32_2_flippedW16( + Word32 * L_x, /* i : interleaved coeffs DC, Fs/2, Re(1),Im(1), Re(2),Im(2), ... ] */ + const Word16 numPairs, /* i: typically (fft-size/2 -1), re/im coeffs to copy */ + const Word16 Lprot, /* i: fft size , including DC+fs/2 */ + Word16 * x /* o : flipped coeffs , [DC, Re(1),.. Re(N-1/2) , Fs/2, Im(N-1/2) ... Im(1) ] */ + ) + { + + /* reorder real and imag components, and apply fractional scale for 24/48Khz */ + Counter m; + Counter numPairsLocal; + Word32 *pX_L = &L_x[2]; /*ptr init*/ + Word16 *pX_Re = &x[1]; /*ptr init*/ + Word16 *pX_Im = &x[Lprot - 1]; /*ptr init*/ + +#define FHG_FFT_UPSHIFT 2 + +#ifdef WMOPS + push_wmops("PhECU::intlvW32_2_flippedW16"); +#endif +#ifdef DYNMEM_COUNT + Dyn_Mem_In("intlvW32_2_flippedW16", sizeof(struct { + Counter m; + Counter numPairsLocal; + Word32 *pX_L; + Word16 *pX_Re; + Word16 *pX_Im; + })); +#endif + + /* make the scaling of 8/3= 4*0.666 here for 24 kHz and 48 kHz using 16x16 instead or 32x16 ops + a limited loss of SNR */ + + test(); + IF(sub(numPairs, 383) == 0 || sub(numPairs, 191) == 0) + { /* 24,48 kHz , 16 ms , scale by 8/3 = .666*4 */ + numPairsLocal = s_min(numPairs, 383 - 63); /* do not copy bins above 20 kHz */ + /* for 48 kHz is to only go up to 40 kHz pairs , */ + FOR(m = 0; m < numPairsLocal; m++) + { + /* multiply by (8/3)*(2.^FHG_FFT_UPSHIFT) */ + /* note: multiplication by 2/3 need to preceed upshift , due to FFT scaling being very close to the 48/24 3 + * split kHz bit margin */ + *pX_Re++ = extract_h(L_shl_pos(Mpy_32_16_lc3plus(*pX_L++, FEC_TWOTHIRDS_Q15), FHG_FFT_UPSHIFT + 2)); + move16(); + *pX_Im-- = extract_h(L_shl_pos(Mpy_32_16_lc3plus(*pX_L++, FEC_TWOTHIRDS_Q15), FHG_FFT_UPSHIFT + 2)); + move16(); + } + /* Place the two real only components */ + x[0] = extract_h(L_shl_pos(Mpy_32_16_lc3plus(L_x[0], FEC_TWOTHIRDS_Q15), FHG_FFT_UPSHIFT + 2)); /* DC */ + move16(); + m = shr_pos_pos(Lprot, 1); + x[m] = extract_h(L_shl_pos(Mpy_32_16_lc3plus(L_x[1], FEC_TWOTHIRDS_Q15), FHG_FFT_UPSHIFT + 2)); /* fs/2 */ + move16(); + } + ELSE + { /* 8,16,32 kHz 16 ms no additional scaling by 8/3 */ + + FOR(m = 0; m < numPairs; m++) + { + *pX_Re++ = extract_h(L_shl_pos(*pX_L++, FHG_FFT_UPSHIFT)); + move16(); + *pX_Im-- = extract_h(L_shl_pos(*pX_L++, FHG_FFT_UPSHIFT)); + move16(); + } + + /* Place the two real only components */ + x[0] = extract_h(L_shl_pos(L_x[0], FHG_FFT_UPSHIFT)); /* DC */ move16(); + m = shr_pos_pos(Lprot, 1); + x[m] = extract_h(L_shl_pos(L_x[1], FHG_FFT_UPSHIFT)); /* fs/2 */ move16(); + } + +#ifdef DYNMEM_COUNT + Dyn_Mem_Out(); +#endif +#ifdef WMOPS + pop_wmops(); +#endif + } + + static void flippedW16_2_intlvW32( + Word16 * x, /* i : flipped coeffs , [DC, Re(1),.. Re(N-1/2) , Fs/2, Im(N-1/2) ... Im(1) ] */ + const Word16 numPairs, /* i: typically (fft-size/2 -1), re/im coeffs to copy */ + const Word16 Lprot, /* i: fft size , including DC+fs/2 */ + Word32 * L_x /* o : interleaved coeffs DC, Fs/2, Re(1),Im(1), Re(2),Im(2), ... ] */ + ) + { + Counter i; + Counter numPairsLocal; + Word32 *pX_L; + Word16 *pX_re, *pX_im; +#ifdef WMOPS + push_wmops("PhECU::flippedW16_2_intlvW32"); +#endif +#ifdef DYNMEM_COUNT + Dyn_Mem_In("flippedW16_2_intlvW32", sizeof(struct { + Counter i; + Counter numPairsLocal; + Word32 *pX_L; + Word16 *pX_re, *pX_im; + })); +#endif + + /* Convert stored 16 bit into 32bit for fft */ + /* Note during save FFT output was left shifted FHG_FFT_UPSHIFT */ + /* this needs to be restored before one calls ifft to avoid overflow */ + + pX_L = &L_x[2]; /*ptr init*/ + pX_re = &x[1]; /*ptr init*/ + pX_im = &x[Lprot - 1]; /*ptr init*/ + + numPairsLocal = s_min(320, numPairs); /* 48kHz optimization */ + FOR(i = 0; i < numPairsLocal; i++) + { + *pX_L++ = L_shr_pos(L_deposit_h(*pX_re++), FHG_FFT_UPSHIFT); move32(); + *pX_L++ = L_shr_pos(L_deposit_h(*pX_im--), FHG_FFT_UPSHIFT); move32(); + } + /* at 48KHz zero tail 2x63= 126 bins for Word32 IFFT input */ + basop_memset(pX_L, 0, sizeof(Word32) * shl_pos(sub(numPairs, numPairsLocal), 1)); + + /* Place the two real only components */ + L_x[0] = L_shr_pos(L_deposit_h(x[0]), FHG_FFT_UPSHIFT); move32(); + L_x[1] = L_shr_pos(L_deposit_h(x[Lprot / 2]), FHG_FFT_UPSHIFT); move32(); + +#ifdef DYNMEM_COUNT + Dyn_Mem_Out(); +#endif +#ifdef WMOPS + pop_wmops(); +#endif + } + + void get_sin_cosQ10opt(Word16 phase, /* Q10 0..1023 i.e. 1024=2*pi */ + Word16 * ptrSin, /* Q15 */ + Word16 * ptrCos /* Q15 */ + ) + { + Word16 sign_val, idx, idx2, idx3; + +#ifdef DYNMEM_COUNT + Dyn_Mem_In("get_sin_cosQ10", sizeof(struct { Word16 sign_val, idx, idx2, idx3; })); +#endif + +#ifdef WMOPS + push_wmops("PhECU::get_sin_cosQ10opt"); +#endif + + /* sin table has a range up to pi/2 (256+1)=257 coeffs*/ + + sign_val = shr_pos_pos(phase, 9); /* highest bit is the sinus sign */ + idx = s_and(phase, 0x1ff); /* mask away sign */ + + idx2 = sub(idx, 256); + if (idx2 < 0) + { /*rising sine part */ + *ptrSin = sin_quarterQ15_fx[idx]; move16(); + } + + idx3 = sub(512, idx); + if (idx2 >= 0) + { /* decaying part, reverse idx */ + *ptrSin = sin_quarterQ15_fx[idx3]; move16(); + } + + if (sign_val != 0) + { + *ptrSin = negate(*ptrSin); /*no move when inlined , no sat as max in table is 32767 */ + } + + /*cos*/ + idx = add(phase, 256); /* +pi/2, i.e. move to cos phase */ + idx = s_and(idx, 0x3ff); /* wrap on 10 bits limit */ + + sign_val = shr_pos_pos(idx, 9); /* highest bit is the sign */ + idx = s_and(idx, 0x1ff); /* mask away sign */ + + idx2 = sub(idx, 256); + if (idx2 < 0) + { /*rising sine part */ + *ptrCos = sin_quarterQ15_fx[idx]; move16(); + } + + idx3 = sub(512, idx); + if (idx2 >= 0) + { /* decaying part, reverse idx*/ + *ptrCos = sin_quarterQ15_fx[idx3]; move16(); + } + + if (sign_val != 0) + { + *ptrCos = negate(*ptrCos); /* no move when inlined , no sat as max in table is 32767 */ + } + +#ifdef DYNMEM_COUNT + Dyn_Mem_Out(); +#endif +#ifdef WMOPS + pop_wmops(); +#endif + } + +#ifdef CR8_A_PLC_FADEOUT_TUNING + static Word16 plc_phEcu_nonpure_tone_ana_fx(const Word16* plocs, + const Word16 n_plocs, + const Word16* X, /*i: { DC, Re1,Re2 ,.....ReN , Fs/2, ImN... , Im2, Im1} */ + const Word32 *L_Xavg, /* i : Frequency group amp averages for tonal tilt analysis Max upshifted */ + const Word16 Lprot, + const Word16 fs_idx) + { +#ifdef DYNMEM_COUNT + Dyn_Mem_In("PhECU::nonpure_tone_ana", sizeof(struct { + Word16 nonpure_tone_detect; + Word16 n_ind, tone_ind, low_ind, high_ind; + Word16 peak_amp, peak_amp2, valley_amp, x_abs[(1 + 2 * ONE_SIDED_SINE_WIDTH + 2 * 1)]; + Word16 sineband_ind_low, sineband_ind_high; + Word16 i, N_grp; + Word16 tmp, tmp_dB; + Word32 L_tot_inc_HF, L_tot_inc_LF; + Word16* pRe; + Word16* pIm; + Word16* gwlpr_fxPlus1; + Word32 L_nf; + Word32 L_XavgL2_fx[MAX_LGW + 1]; + Word32 L_XavgUp_fx[MAX_LGW + 1]; + })); +#endif + +#ifdef WMOPS + push_wmops("PhEcu::nonpure_tone_ana_fx"); +#endif + + Word16 nonpure_tone_detect; /* output variable */ + Word16 n_ind, tone_ind, low_ind, high_ind; + Word16 peak_amp, peak_amp2, valley_amp, x_abs[(1 + 2 * ONE_SIDED_SINE_WIDTH + 2 * 1)]; + + Word16 sineband_ind_low, sineband_ind_high; + Word16 i, N_grp; + Word16 tmp; + + Word32 L_Ltot_inc_HF, L_Ltot_inc_LF; + Word32 L_tmp_dB; + + const Word16* pRe; + const Word16* pIm; + const Word16* gwlpr_fxPlus1; + Word32 L_nf; + Word32 L_XavgL2_fx[MAX_LGW + 1], L_tmp ; + Word32 L_XavgUp_fx[MAX_LGW + 1]; /* upscaled values , excluding peak band(s) */ + + /* use of a compressed hearing sensitivity curve allowing more energy deviation in highest and lowest bands */ + /* ROM table Word16 scATHFx[MAX_LGW - 1] */ + + /* init */ + nonpure_tone_detect = 0; move16(); /* Word16 register with decisions */ + + peak_amp = 0; move16(); + peak_amp2 = 0; move16(); + + /* limit single sine optimization to when 2 peaks are close enough to represent a single sinusoid */ + test(); + if ((sub(n_plocs, 2) == 0) && + (sub(sub(plocs[1], plocs[0]), ONE_SIDED_SINE_WIDTH) >= 0) + ) /* NB, plocs is an ordered vector */ + { + nonpure_tone_detect = s_or(nonpure_tone_detect, 0x01); + } + + /* local bin wise dynamics analysis, for 1 or 2 initial local maxima peaks , + if 2 peaks , we do the analysis based on the location of the largest abs peak */ + { + tone_ind = 0; move16(); /* one peak only , use position plocs[tone_ind], tone_ind==0 */ + + peak_amp = shr(abs_s(X[0]), 1); /* plocs[0]=0, simply multiply DC*0.5 to match scaling in function sqrtMagnApprox_fx */ + test(); + IF(plocs[0] != 0) + { + peak_amp = sqrtMagnApprox_fx(X[plocs[0]], X[sub(Lprot, plocs[0])]); + } + + IF(sub(n_plocs, 2) == 0) /* locate abs max peak */ + { + peak_amp2 = sqrtMagnApprox_fx(X[plocs[1]], X[sub(Lprot, plocs[1])]); /* Re-part and Im-part in different ends of array X */ + + tmp = sub(peak_amp, peak_amp2); + tone_ind = lshr(tmp, 15); /* mask out sign bit 0(for peak_amp0), 1( for peak_amp2), lshr --> no sign extension in shift */ + peak_amp = s_max(peak_amp, peak_amp2); + } + + low_ind = s_max(1, sub(plocs[tone_ind], (ONE_SIDED_SINE_WIDTH + 1))); /* DC is not allowed in the range */ + high_ind = s_min(sub(shr(Lprot, 1), 2), add(plocs[tone_ind], (ONE_SIDED_SINE_WIDTH + 1))); /* Fs/2 is not allowed in the range */ + + n_ind = add(sub(high_ind, low_ind), 1); + /* find lowest amplitude around the assumed main lobe center location */ + + pRe = &(X[low_ind]); /* ptr init */ + pIm = &(X[Lprot - low_ind]); /* ptr init*/ + FOR(i = 0; i < n_ind; i++) + { + x_abs[i] = sqrtMagnApprox_fx(*pRe++, *pIm--); move16(); /* x_abs is downscaled by 0.5 in abs(complex) approximation */ + } + + valley_amp = peak_amp; move16(); + FOR(i = 0; i < n_ind; i++) + { + valley_amp = s_min(x_abs[i], valley_amp); + } + + /* at least a localized amplitude ratio of 16 (24 dB) required to declare a pure noise-free sinusoid */ + if (sub(shr(peak_amp, 4), valley_amp) < 0) /* 1/16 */ + { + nonpure_tone_detect = s_or(nonpure_tone_detect, 0x02); /* not a pure tone due to too low local SNR P2V */ + } + } + + + /* analyze LF/ HF bands energy dynamics vs the assumed single tone band ( for one or two peaks found cases ) */ + { + /* Xavg , is a vector of rather rough MDCT based band amplitude 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 }; */ + N_grp = add(fs_idx, 4); + assert(fs_idx < 5); + + + /* establish band(s) with assumed sinusoid tone */ + /* if tone freq location is below first MDCT-band definition, use first band as band location anyway */ + + /* band 0 , 1 , 2 , 3 , ...*/ + /* dct-inds "c" "0"...11, 12...19, 20...35, 36 ... */ + /* gwplr_fx= [ 1 , 12(750Hz), 20(1250Hz) , 36 , ... */ /* lowest lim+1 in gwplr */ + + /* for-loop BASOP version */ + tmp = 0; move16(); + gwlpr_fxPlus1 = &(gwlpr_fx[1]); /* ptr init */ + FOR(i = 0; i < N_grp; i++) + { + if (sub(plocs[tone_ind], gwlpr_fxPlus1[i]) >= 0) + { + tmp = add(i, 1); + } + } + + sineband_ind_low = tmp; move16(); + sineband_ind_high = tmp; move16(); /* 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 */ + + test(); logic16(); + if ((sineband_ind_high > 0) && + (sub(sub(plocs[tone_ind], ONE_SIDED_SINE_WIDTH), gwlpr_fx[add(sineband_ind_high, 1)]) >= 0) + ) + { + sineband_ind_low = sub(sineband_ind_high, 1); + } + + logic16(); + if ((sub(sineband_ind_low, sub(N_grp, 1)) < 0) && + (sub(add(plocs[tone_ind], ONE_SIDED_SINE_WIDTH), gwlpr_fx[add(sineband_ind_low, 1)]) >= 0) + ) + { + sineband_ind_high = add(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 */ + + logic16(); + test(); logic16(); + IF( (nonpure_tone_detect == 0) && + ( (sub( add(sineband_ind_high, 2), N_grp) < 0 ) || + (sub(sineband_ind_low, 2+1 ) >= 0) + ) + ) + { + + /* delta taper-off analysis solution, less sensitive to input bandwidth limitation and levels */ + + /* test Xavg Word16 result above vs a high resolution Word32 L_Xavg */ + /* strong spectral tilt causes HF to be truncated in Word16 */ + + basop_memcpy(L_XavgUp_fx, L_Xavg, N_grp * sizeof(Word32) ) ; + + /* first remove all energy from the assumed tonal peak band(s) */ + L_XavgUp_fx[sineband_ind_low] = L_min(L_XavgUp_fx[sineband_ind_low], 1); move32(); + L_XavgUp_fx[sineband_ind_high] = L_min(L_XavgUp_fx[sineband_ind_high], 1); move32(); + + tmp = getScaleFactor32_0(L_XavgUp_fx, N_grp); /* o: measured headroom in range [0..32], 32 if all L_x[i] == 0 */ + if (sub(tmp, 32) == 0) + { + nonpure_tone_detect = s_or(nonpure_tone_detect, 0x100); /* also set a flag for an all zero L_Xavg coarse spectrum estimate signal */ + } + + + /* add noise floor to L_Xavg before log2 function call */ + L_nf = L_shl(1L, sub(tmp, 1)); + L_nf = L_max(L_nf, 1L); + for (i = 0; i < N_grp; i++) + { + L_XavgUp_fx[i] = L_shl_sat(L_XavgUp_fx[i], tmp); move32(); /* maximize precision before actual log2_fx(Word32) calc call */ + + L_tmp = L_XavgUp_fx[i]; move32(); + test(); + if (L_tmp <= 0) + { + L_tmp = L_nf; move32(); + } + + /* log2(Upshifted Word32) */ + /* maximize precision in BASOP Log2 function */ + L_XavgL2_fx[i] = BASOP_Util_Log2_lc3plus(L_tmp); /* L_input 1.0 or lower --> output always negative */ + /* add 31.0 to store as fractional bits of an upscaled positive Word32 integer input ) */ + L_XavgL2_fx[i] = L_add(31L << 25, L_XavgL2_fx[i]); /* only diffs added so 31.0 is cancelled out later , in total only values between +/- 2^6 = [-64 ... -64[ are possible */ + } /* band i for L_Xavg calc*/ + /* 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 */ + L_Ltot_inc_HF = 0; move32(); + for (i = (sineband_ind_high + 1); i < (N_grp - 1); i++) + { + L_tmp_dB = 0; move32(); + if (L_sub(L_Xavg[i], L_Xavg[i + 1]) < 0) /* only increases are accumulated */ + { + L_tmp_dB = L_sub(L_XavgL2_fx[i + 1], L_XavgL2_fx[i]); /* obtain ratio in log2 domain */ + } + L_tmp = Mpy_32_16_lc3plus(L_tmp_dB, scATHFx[i]); /* scATHFx[i] is the ATH weight for band i and band i+1 */ + L_tmp = L_shr_pos(L_tmp, 1); /* Q25 -> Q24 */ + + L_Ltot_inc_HF = L_add(L_Ltot_inc_HF, L_tmp); /* Q24 */ + } + + /* verify that an assumed clean sine does not have any odd LF content by thresholding the accumulated LF reverse up tilt */ + + L_Ltot_inc_LF = 0; move32(); + tmp = s_max(0, sub(sineband_ind_low, 1)); /* could also be pointer init */ + for (i = tmp; i > 0; i--) + { + L_tmp_dB = 0; move32(); + if (L_sub(L_Xavg[i - 1], L_Xavg[i]) > 0) /* only increases are accumulated */ + { + L_tmp_dB = L_sub(L_XavgL2_fx[i - 1], L_XavgL2_fx[i]); /* obtain ratio in log2 domain */ + } + L_tmp = Mpy_32_16_lc3plus(L_tmp_dB, scATHFx[i-1]); /* scATHFx[i-1] is the ATH weight in between band i-1 and band i */ + L_tmp = L_shr_pos(L_tmp, 1); /* Q25 -> Q24 */ + L_Ltot_inc_LF = L_add(L_Ltot_inc_LF, L_tmp); /* Q24 */ + } + + if (L_sub(L_Ltot_inc_HF, SIDE_LIM) > 0) /* side_lim=round(Q24x*0.7474) */ + { + /* 4.5 dB in log2 is 0.7474 */ + nonpure_tone_detect = s_or(nonpure_tone_detect, 0x10); /* still not a pure tone, too great HF side increase */ + } + + if (L_sub(L_Ltot_inc_LF, SIDE_LIM) > 0) /* side_lim=round(Q24x*0.7474) */ + { + /* 4.5 dB in log2 is 0.7474 */ + nonpure_tone_detect = s_or(nonpure_tone_detect, 0x20); /* still not a pure tone, too great HF 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 (L_sub(L_add_sat(L_Ltot_inc_LF, L_Ltot_inc_HF), LFHF_LIM) > 0) /* side_lim=round(Q24x*0.7474) */ + { + /* 6.0 dB in log2 is 0.996578428 */ + nonpure_tone_detect = s_or(nonpure_tone_detect, 0x40); /* still not a pure tone, too great LF+HF side increase */ + } + + } /* bands available*/ + +#ifdef WMOPS + pop_wmops(); +#endif + + return nonpure_tone_detect; + } +#endif /* CR8_A_PLC_FADEOUT_TUNING plc_phecu_non_pure_ana_fx */ + + + + diff --git a/lib_lc3plus/plc_phecu_lf_peak_analysis_fx.c b/lib_lc3plus/plc_phecu_lf_peak_analysis_fx.c new file mode 100644 index 0000000000000000000000000000000000000000..50b694e5ca75f16373cb719608419d5b7956eb9d --- /dev/null +++ b/lib_lc3plus/plc_phecu_lf_peak_analysis_fx.c @@ -0,0 +1,202 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.5 * +* 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 "defines.h" +#include "functions.h" + +void plc_phEcu_LF_peak_analysis_fx(Word16 * plocs, /* i/o 0 ... Lprot/2 +1*/ + Word16 * n_plocs, /* i/o 0.. MAX_PLOCS */ + Word32 * L_f0estQ16, /* i/o Q16*/ + const Word16 *mag, /* i: Qx */ + const Word16 stPhECU_f0hzLtpBinQ7, const Word16 stPhECU_f0gainLtpQ15, + const Word16 nSubm, Word16 maxPlocs, + Word8 *scratchBuffer /* Size = 6 * MAX_PLOCS + 42 */ +) + +{ + Counter i, j; + Word16 n_plocs_ana, peakLF_Xval, tmp, f_abs_ind, plocsIntersectFlag; + + Word32 L_fQ7, *L_f0est_prelQ16; + Word16 num_prel = 0, *plocs_prel; + Word16 prel_low, prel_high, start, fin; + Word16 *plocs_old; + Word32 *L_plocsi_old; + +#ifdef DYNMEM_COUNT + Dyn_Mem_In("plc_phEcu_LF_peak_analysis_fx", sizeof(struct { + Counter i, j; + Word16 n_plocs_ana, peakLF_Xval, tmp, f_abs_ind, plocsIntersectFlag; + Word32 L_fQ7, *L_f0est_prelQ16; + Word16 num_prel, *plocs_prel; + Word16 prel_low, prel_high, start, fin; + Word16 *plocs_old; + Word32 *L_plocsi_old; + })); +#endif + + + + L_f0est_prelQ16 = (Word32 *)scratchAlign(scratchBuffer, 0); /* Size = 4 * 7 */ + plocs_prel = (Word16 *)scratchAlign(L_f0est_prelQ16, sizeof(*L_f0est_prelQ16) * 7); /* Size = 2 * 7 */ + plocs_old = (Word16 *)scratchAlign(plocs_prel, sizeof(*plocs_prel) * 7); /* Size = 2 * MAX_PLOCS */ + L_plocsi_old = (Word32 *)scratchAlign(plocs_old, sizeof(*plocs_old) * maxPlocs); /* Size = 4 * MAX_PLOCS */ + + test(); test(); + IF ((*n_plocs > 0) && sub(stPhECU_f0gainLtpQ15, ((Word16)(0.25 * 32768.0))) > 0 && + sub(stPhECU_f0hzLtpBinQ7, (Word16)(2.75 * 128.0)) < 0) + { + + /* % analyze/apply f0Ltp to avoid intermodulation effects below f0 of ~180 Hz + % we only do the f0Ltp-replacement(s) if there is already an established + % fft peak in the region ~fRes to 2.5*fres + fft_peak_eval_plocs = 1:3; + plocsIntersectFlag = intersect(plocs, fft_peak_eval_plocs ); % check for 1,2,3 in plocs */ + + plocsIntersectFlag = 0; move16(); + peakLF_Xval = 0; move16(); + n_plocs_ana = s_min(*n_plocs, 3); + FOR (i = 0; i < n_plocs_ana; i++) + { + tmp = plocs[i]; move16(); + if (sub(tmp, 2) <= 0) /* C index 0, 1,2 checked , [DC, 62.5 Hz, 125Hz ] */ + { + plocsIntersectFlag = add(i, 1); + } + peakLF_Xval = s_max(mag[tmp], peakLF_Xval); + } + + num_prel = 0; move16(); + IF (plocsIntersectFlag != 0) + { /* fft-peak at 0, 62 or 125 Hz */ + /* analyze if ltp-based f0 need to be added or not */ + peakLF_Xval = mult_r(peakLF_Xval, (Word16)(.375 * 32768.0)); /* now as a limit */ + + FOR (i = 1; i <= nSubm; i++) + { + L_fQ7 = L_mult0(i, stPhECU_f0hzLtpBinQ7); /* fractional index stored in L_plocsi */ + f_abs_ind = L_shr_pos(L_add(L_fQ7, 64), 7); /* integer bin index stored in plocs */ + + test(); + IF ((L_sub(L_fQ7, 819) <= 0) && /* % only apply up to ~400hz , 819 = 400/62.5*128 */ + (sub(mag[f_abs_ind], peakLF_Xval) > + 0)) /* % only set as preliminary if relative peak strength is signficant*/ + { + L_f0est_prelQ16[num_prel] = L_shl_pos(L_fQ7, 9); move32(); + plocs_prel[num_prel] = f_abs_ind; move16(); + num_prel = add(num_prel, 1); + } + } + } /*intersectFlag*/ + + /* now replace/ merge new preliminary added peaks with existing plocs and L_f0estQ16 */ + /* note that a previous fake/merged magnitude-determined peak may be replaced by two separated side peaks */ + + /* a general non-optimized list-merging solution below */ + test(); + IF ((num_prel > 0) && (sub(add(num_prel, *n_plocs), MAX_PLOCS) <= 0) /* skip in case plocs list is too large */ + ) + { + prel_low = plocs_prel[0]; move16(); + prel_high = plocs_prel[sub(num_prel, 1)]; move16(); + + /* initial assumption:: all original peaks (1 or 2 of them) are positioned below prel_low */ + start = (*n_plocs); /* at this point 'start' is the location_c where to add any harmonics peaks */ + + FOR (i = sub(*n_plocs, 1); i >= 0; i--) + { + if (sub(plocs[i], prel_low) >= 0) + { + start = i; move16(); + } + } + start = sub(start, 1); /* end of old section to copy before the added/merged section */ + start = s_max(start, -1); /* limit for loop later */ + /*% dbg check low part for a sucessful replace/merge */ + if (start >= 0 && start < *n_plocs) + { + ASSERT(plocs[start] < plocs_prel[0]); + } + + sub(0, 0); + IF (prel_high < plocs[0]) + { + fin = 0; move16(); /*% keep all plocs , just concat */ + } + ELSE + { + fin = *n_plocs; + FOR (i = 0; i < *n_plocs; i++) + { + sub(0, 0); + if (plocs[i] <= prel_high) + { + fin = i; move16(); + } + } + fin = add(fin, 1); /* first element in high part of old plocs to be copied */ + } + + /*% dbg check high part for a sucessful replace/merge */ + if (fin >= 0 && fin < *n_plocs) + { + ASSERT(plocs_prel[sub(num_prel, 1)] < plocs[fin]); + } + + /* + % actual replace/merge of added integer locations and fractional freqs. into plocs/f0list list ; + % three loops in BASOP + plocs = [ plocs(1:(start)) ; plocs_prel ; plocs((fin):end) ]; + f0est = [ f0est(1:(start)) ; f0est_prel; f0est((fin):end) ]; + */ + + FOR (i = 0; i < *n_plocs; i++) + { + plocs_old[i] = plocs[i]; move16(); + L_plocsi_old[i] = L_f0estQ16[i]; move32(); + } + + /* + j=0; + FOR(i=0; i <= start; i++) + { + plocs[i] = plocs_old[i]; move16(); + L_f0estQ16[i] = L_plocsi_old[i]; move32(); + j++; + } + */ + + j = add(start, 1); + + ASSERT(j>=0); + + FOR (i = 0; i < num_prel; i++) /* NB this section may both insert or overwrite old plocs */ + { + plocs[j] = plocs_prel[i]; move16(); + L_f0estQ16[j] = L_f0est_prelQ16[i]; move32(); + j++; + } + FOR (i = fin; i < *n_plocs; i++) /* copy the tail of the list */ + { + plocs[j] = plocs_old[i]; move16(); + L_f0estQ16[j] = L_plocsi_old[i]; move32(); + j++; + } + + *n_plocs = j; move16(); /* update total length */ + } /* num_prel >0*/ +} /* gain/hz Limits */ + +#ifdef DYNMEM_COUNT +Dyn_Mem_Out(); +#endif + +} + + diff --git a/lib_lc3plus/plc_phecu_peak_locator_fx.c b/lib_lc3plus/plc_phecu_peak_locator_fx.c new file mode 100644 index 0000000000000000000000000000000000000000..42729e800fba9b283ca1dc2e4c32570d0228b786 --- /dev/null +++ b/lib_lc3plus/plc_phecu_peak_locator_fx.c @@ -0,0 +1,385 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.5 * +* 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 "defines.h" +#include "functions.h" + +#define RES_fx 1 /* fixed point resolution */ + +/*----------------------------------------------------------------------------- + * peak_locator_fx() + *----------------------------------------------------------------------------*/ +void plc_phEcu_peak_locator_fx(const Word16 *inp, /* i: vector with values >=0 ,Qx */ + const Word16 inp_len, /* i: length of inp */ + Word16 * int_plocs, /* o: array of filtered integer plocs Q0 */ + Word16 * n_fsc, /* o: total_ number of filtered located highs Q0 */ + const Word16 sens, /* i sensitivity, Qx */ + const Word16 inp_high, /* i global high , Qx */ + const Word16 inp_low, /* i: global low, Qx */ + Word16 maxLprot_Red, /* i: optional size for wc memory alloc of scratch buffer */ + Word8 *scratchBuffer /* i: : scratch buffer 2* 3*(1+1+(maxLprot_Red/2)+1) */ +) +{ + Counter j, k, n, idx_high, idx_low; + Word16 inp_len_minus1 ; + Word16 pairs_start, pairs_end; + Word16 *p_tmp; + Word16 prev_delta, curr_delta; + Word16 delta_predc, delta_fin; + Word16 add_dc_flag, add_fin_flag; + Word16 low_val_cand_pairs, val_range; + Word16 num_pairs, n_tail_values; + Word16 cand_phase_start, cand_idx, prev_low_plus_sens, tmp; + + Word16 cand_high, prev_low; + Word16 *sc_idx; /* 1+ 128/2+1, or 1+ 256/2+1 ... 1+ 640/2+1 or 1+ 768/2+1*/ + Word16 *cand_pairs_buf ; /* actually lowVal + [DC ] + (368/2)pairs + [FS/2] */ + Word16 *cand_pairs; /* actually [DC ] + pairs + [FS/2] */ + Word16 * fsc_idx; /* list of high locations in sc__idx 1+368/2+1 */ + + + + +#ifdef DYNMEM_COUNT + Dyn_Mem_In("peak_locator_fx", sizeof(struct { + Counter j, k, n, idx_high, idx_low; + Word16 inp_len_minus1; + Word16 pairs_start, pairs_end; + Word16 *p_tmp; + Word16 prev_delta, curr_delta; + Word16 delta_predc, delta_fin; + Word16 add_dc_flag, add_fin_flag; + Word16 low_val_cand_pairs, val_range; + Word16 num_pairs, n_tail_values; + Word16 cand_phase_start, cand_idx, prev_low_plus_sens, tmp; + Word16 cand_high, prev_low; + Word16 *sc_idx; + Word16 *cand_pairs_buf; + Word16 *cand_pairs; + Word16 *fsc_idx; + })); +#endif +#ifdef WMOPS + push_wmops("PhECU::peak_locator_fx(1st)"); +#endif + sc_idx = (Word16 *)scratchAlign(scratchBuffer, 0); /* ByteSize = 2 * (1+ inp_len+1) */ + cand_pairs_buf = (Word16 *)scratchAlign(sc_idx, sizeof(*sc_idx) * (1+inp_len+1)); /* ByteSize = 2 * (1+ 1+ inp_len+1 ) */ + fsc_idx = (Word16 *)scratchAlign(cand_pairs_buf , sizeof(*cand_pairs_buf) * (1+ 1+ inp_len+1)); /* ByteSize = 2 * ( 1+ inp_len + 1) */ + ASSERT((4 * maxLprot_Red) >= 3 * (1 + 1 + inp_len + 1)); /* basic buffer check */ + UNUSED(maxLprot_Red); + + inp_len_minus1 = sub(inp_len, 1); /* size of delta=derivative array ,and last index in inp */ + + cand_pairs = &cand_pairs_buf[1]; /* ptr init , make space for storing a lowest amplitude value in location -1 */ + pairs_start = 1; move16(); /* adjusted to zero or 1 or 2 when/if, DC is injected as sc_idx[0], or initial plateau skipped */ + + p_tmp = &(sc_idx[pairs_start]); /* ptr init */ + + + /* xor high/low pairs of delta_inp and save sign changes */ + prev_delta = sub(inp[1], inp[0]); /* precompute very first delta */ + + FOR(n = 1; n < inp_len_minus1; n++) + { /* sign change analysis */ + curr_delta = sub(inp[n + 1], inp[n]); /* n+1 ,n , are loop ptrs */ + if (s_xor(prev_delta, curr_delta) < 0) /* a "0" delta treated as a positive sign */ + { + *p_tmp++ = n; move16(); /* store sign change bin locations , location n in the inp[] signal */ + } + prev_delta = curr_delta; move16(); + } + + L_sub(0, 0); /* account for length calculaton */ + k = (Word16)(p_tmp - &(sc_idx[pairs_start])); + + + /* copy sign change location values to a pairs array */ + /* leave one initial sc_idx location open for a potential initial DC value */ + + ASSERT(pairs_start >= 0 && ((k - 1) + pairs_start) < (inp_len +2)); + FOR(j = 0; j < k; j++) + { + cand_pairs[j + pairs_start] = inp[sc_idx[j + pairs_start]]; move16(); move16(); /* the indirect should be calculated */ + } + + + /* filter away a potential single initial/trailing plateau + to enable correct analysis for adding DC or fs/2 bins */ + + logic16(); + IF((sub(k, 2) >= 0) && + (sub(cand_pairs[pairs_start], cand_pairs[pairs_start + 1]) == 0)) + { + pairs_start = add(pairs_start, 1); + k = sub(k, 1); + } + + /* filter away potential single trailing plateu */ + pairs_end = sub(add(pairs_start,k), 1); /* point to last established sign change element */ + logic16(); + if ((sub(k, 2) >= 0) && + (sub(cand_pairs[sub(pairs_end,1)], cand_pairs[pairs_end]) == 0)) + { + k = sub(k, 1); + } + pairs_end = sub(add(pairs_start,k), 1); /* recalc ptr to last element */ + + + /* conditionally add high/lows on both sides of input (pre_dc or fin) as candidates */ + add_dc_flag = 0; move16(); + add_fin_flag = 0; move16(); + + + IF(sub(k, 1) == 0) /* one single sign change found special case */ + { + if (sub(inp[0], cand_pairs[pairs_start]) != 0) + { + add_dc_flag = 1; move16(); /* not plateau */ + } + + if (sub(cand_pairs[pairs_end], inp[inp_len_minus1]) != 0) + { + add_fin_flag = 1; move16(); /* not plateau */ + } + } + + IF(sub(k, 2) >= 0) + { + delta_predc = sub(cand_pairs[pairs_start + 1], cand_pairs[pairs_start]); + delta_fin = sub(cand_pairs[pairs_end], cand_pairs[pairs_end - 1]); + + /* plateaus are allowed to be detected by xor sign change, + but still not allowed at the start nor at the end */ + + add_dc_flag = 1; move16(); + if (sub(inp[0], cand_pairs[pairs_start]) == 0) + { + add_dc_flag = 0; move16(); /* plateau down or , plateus up., --> do not add DC */ + } + + logic16(); + if ((sub(inp[0], cand_pairs[pairs_start]) < 0) && (delta_predc > 0)) + { + add_dc_flag = -1; move16(); /*UP - up ... replace */ + } + logic16(); + if ((sub(inp[0], cand_pairs[pairs_start]) > 0) && (delta_predc < 0)) + { + add_dc_flag = -1; move16(); /* DOWN - down ... % replace */ + } + + add_fin_flag = 1; move16(); + if (sub(cand_pairs[pairs_end], inp[inp_len_minus1]) == 0) + { + add_fin_flag = 0; move16(); /* up - plateau ... */ + } + logic16(); + if ((delta_fin > 0) && (sub(cand_pairs[pairs_end], inp[inp_len_minus1]) < 0)) + { + add_fin_flag = -1; move16(); /* up - UP ... % replace , hard to hit */ + } + logic16(); + if ((delta_fin < 0) && (sub(cand_pairs[pairs_end], inp[inp_len_minus1]) > 0)) + { + add_fin_flag = -1; move16(); /*down - DOWN ... % replace */ + } + + } + + IF(add_dc_flag > 0) + { /* add DC */ + pairs_start = sub(pairs_start, 1); + cand_pairs[pairs_start] = inp[0]; move16(); + sc_idx[pairs_start] = 0; move16(); + ASSERT(pairs_start >= 0 && pairs_start <= 2); + k = add(k, 1); + } + IF(add_dc_flag < 0) + { /* -1 --> replace with DC*/ + cand_pairs[pairs_start] = inp[0]; move16(); + sc_idx[pairs_start] = 0; move16(); + ASSERT(pairs_start >=0 && pairs_start <= 2); + } + + IF(add_fin_flag > 0) + { /* add FS/2 */ + pairs_end = add(pairs_end, 1); + cand_pairs[pairs_end] = inp[inp_len_minus1]; move16(); + sc_idx[pairs_end] = inp_len_minus1; move16(); + k = add(k, 1); + } + IF(add_fin_flag < 0) + { /* -1, replace tail with FS/2*/ + cand_pairs[pairs_end] = inp[inp_len_minus1]; move16(); + sc_idx[pairs_end] = inp_len_minus1; move16(); + } + /* preliminary cand_pairs now only have highs , lows , no initial/trailing plateaus */ + + + /* we allow the DC/FsBy2 lows to be used as the candidatelLow */ + low_val_cand_pairs = inp_low; move16(); + val_range = sub( inp_high, low_val_cand_pairs); /* used to determine if search is useful at all */ + + logic16(); + if ((sub(val_range, RES_fx) < 0) || + (sub( inp_high, sens) < 0)) + { + k = 0; move16(); + } + + logic16(); + if ((k == 0) && (sub(val_range, sens) >= 0)) + { + k = 1; move16(); + } + + + IF(sub(k, 2) > 0) + { + /* low, high, low, ... or + high, low, high, ...*/ + + cand_phase_start = pairs_start; move16(); /*assume first candidate is a high */ + if (sub(cand_pairs[pairs_start], cand_pairs[pairs_start + 1]) < 0) + { + cand_phase_start = add(pairs_start, 1); /* first is a low, --> skip to next higher cand */ + } + + /* high, low, high, ... */ + tmp = k; move16(); + if (sub(cand_phase_start, pairs_start) != 0) + { + tmp = sub(tmp, 1); + } + num_pairs = shr(tmp, 1); + n_tail_values = sub(tmp, shl(num_pairs, 1)); + + /* filter preliminary sign changes into sensitivity filtered sign changes */ + + *n_fsc = 0; move16(); /* counter of filtered fsc_idx */ + cand_high = low_val_cand_pairs; move16(); + cand_idx = -1; move16(); /* sentinel location for no high cand found yet. */ + cand_pairs[-1] = low_val_cand_pairs; move16(); + + prev_low = low_val_cand_pairs; move16(); + prev_low_plus_sens = add(prev_low, sens); + + /* filter loop for high - low sign change pairs */ + /* idx_high, idx_low are raw pointers into the cand_pairs and sc_idx arrays */ + + FOR( idx_high = cand_phase_start; idx_high < (cand_phase_start + 2 * num_pairs); idx_high += 2) + { + idx_low = idx_high+1; /* loop ptr increase */ + + /* new high candidate larger than previous candidate and */ + /* sensitivity still larger than the the previous low */ + tmp = s_max(cand_high, prev_low_plus_sens); + if(sub(cand_pairs[idx_high], tmp) > 0) + { + cand_idx = idx_high; move16(); /* enable or shift candidate position fwd */ + } + cand_high = cand_pairs[cand_idx]; move16(); /* NB, cand_pairs[-1] , has the low_val_cand_pairs value stored */ + + /* now check the fwd idx_low of the current {high,low} pair */ + prev_low = s_min(cand_pairs[idx_low], prev_low); + + tmp = sub(cand_high, sens); + IF(sub(tmp, cand_pairs[idx_low]) > 0) + { + /* this low point is now low enough to fix a previous high candidate */ + + fsc_idx[*n_fsc] = cand_idx; move16(); /*% add cand high idx -> output idx list*/ + *n_fsc = add(*n_fsc, 1); + + prev_low = cand_pairs[idx_low]; move16(); /* use this value as new low estimate */ + cand_idx = -1; move16(); /* no candidate until next pair or tail bin, and pt to lowVal */ + cand_high = low_val_cand_pairs; move16(); /* enable next candidate to be selected immediately */ + } + prev_low_plus_sens = add(prev_low, sens); + } /* { high, low} FOR loop */ + + logic16(); + IF((n_tail_values == 0) && (cand_idx >= 0)) + { + /* no tail low or high value to analyze + still may need to lock a non-locked but qualified candidate */ + fsc_idx[*n_fsc] = cand_idx; move16(); + *n_fsc = add(*n_fsc, 1); + } + + + /* cand_pairs vector may have a last orphan value */ + IF(n_tail_values > 0) + { + /* cand_pairs vector may have a last orphan tail value */ + /* + logic boils down to if (nTailValues > 0) && (cand_pairs(n_end) > tmp) + there is a last one trailing high to process + + a) the last high, may be a new high Peak if we have not yet + locked the current candidate + b) if we have locked the last candidate, the last high may also be + a highpeak if it is high enough from the(newly set previous) valley floor. + + tmp=a||b + */ + + tmp = s_max(cand_high, prev_low_plus_sens); + tmp = sub(cand_pairs[pairs_end], tmp); + IF(tmp > 0) + { + fsc_idx[*n_fsc] = pairs_end; move16(); + *n_fsc = add(*n_fsc, 1); + } + ELSE + { + IF(cand_idx >= 0) + { /* we have a previously established high candidate */ + fsc_idx[*n_fsc] = cand_idx; move16(); + *n_fsc = add(*n_fsc, 1); + } + + } + } + /* move high locations info from fsc_idx , to output */ + FOR(j = 0; j < *n_fsc; j++) + { + ASSERT(fsc_idx[j] >= 0 && fsc_idx[j] < (inp_len+2)); + int_plocs[j] = sc_idx[fsc_idx[j]]; move16(); move16(); /* the indirect moves are calculated */ + } + + } /* end of pairs + [tail] section filtering */ + ELSE + { + /* constant/single rise or constant decay or very low overall values, cases */ + *n_fsc = 0; move16(); + + logic16(); + tmp = sub(inp_high, sens); + IF((k != 0) && (sub(tmp, low_val_cand_pairs) > 0)) + { + /* low,high */ + /* high,low */ + tmp = plc_phEcu_find_ind_fx(inp, inp_len, inp_high); move16(); + int_plocs[0] = tmp; move16(); /* simply locate the high peak*/ + *n_fsc = 1; move16(); + if (tmp < 0) + { /*safety in case max value index was not found */ + *n_fsc = 0; move16(); + } + } + } +#ifdef DYNMEM_COUNT + Dyn_Mem_Out(); +#endif +#ifdef WMOPS + pop_wmops(); +#endif +} + diff --git a/lib_lc3plus/plc_phecu_setf0hz_fx.c b/lib_lc3plus/plc_phecu_setf0hz_fx.c new file mode 100644 index 0000000000000000000000000000000000000000..3dd5b1a0844025d9a1c4b6d80f000bf670da16e2 --- /dev/null +++ b/lib_lc3plus/plc_phecu_setf0hz_fx.c @@ -0,0 +1,60 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.5 * +* 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 "defines.h" +#include "functions.h" + +/* +st_PhECU_f0minLtp=55; % 55.4 Hz +st_PhECU_f0maxLtp=376; % 376.4706 Hz + +*/ + + +Word16 +plc_phEcuSetF0Hz_fx(/* output Q7 bin frequency [0.. 255.xxxx] "1 sign, 8 bits mantissa, 7 binomial" [0-255.9999] */ + Word16 fs_idx, Word16 old_pitch_int, Word16 old_pitch_fr) +{ + Word16 pitch_lagQ2, result, expo; + Word32 L_result, L_tmp; + +#ifdef DYNMEM_COUNT + Dyn_Mem_In("plc_phEcuSetF0Hz_fx", sizeof(struct { + Word16 pitch_lagQ2, result, expo; + Word32 L_result, L_tmp; + Word16 num_FsByResQ0[5]; + })); +#endif + +#ifdef WMOPS + push_wmops("PhECU::plc_phEcuSetF0Hz_fx"); +#endif + + result = 0; move16(); + IF (old_pitch_int != 0) + { + pitch_lagQ2 = add( + old_pitch_fr, + shl(old_pitch_int, 2)); /* lag at the current fs_idx , max lag_value is is 228(+.75)*48/12.8 = 858 in Q0 */ + + L_result = plc_phEcu_ratio_fx(L_deposit_h(num_FsByResQ0[fs_idx]), L_deposit_h(pitch_lagQ2), &expo); + L_tmp = L_shl_sat(L_result, sub(11, expo)); /* move to Q7, in high word to allow round*/ + result = round_fx(L_tmp); + } +#ifdef DYNMEM_COUNT + Dyn_Mem_Out(); +#endif +#ifdef WMOPS + pop_wmops(); +#endif + + return result; /*Q7*/ +} + + diff --git a/lib_lc3plus/plc_phecu_tools_fx.c b/lib_lc3plus/plc_phecu_tools_fx.c new file mode 100644 index 0000000000000000000000000000000000000000..c78d406a46e801b4594fd82ccc2dbc358ea2f356 --- /dev/null +++ b/lib_lc3plus/plc_phecu_tools_fx.c @@ -0,0 +1,247 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.5 * +* 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 "defines.h" +#include "functions.h" + +/* initilize a short vector */ +void plc_phEcu_initWord16(Word16 * vec, /*i/o : short vector pointer */ + const Word16 value, /*i : short initialization value */ + const Word16 len) /*i : number of elements */ +{ + Counter n; + + FOR (n = 0; n < len; n++) + { + vec[n] = value; move16(); + } +} + +/* scale inplace with allowed saturation in upscaling , function not available in basop_util */ +void Scale_sig_sat(Word16 x[], /* i/o: signal to scale Qx */ + const Word16 lg, /* i : size of x[] Q0 */ + const Word16 exp0 /* i : exponent: x = round(x << exp) Qx ?exp */ +) +{ + Counter i; + Word16 tmp; + IF (exp0 > 0) + { + FOR (i = 0; i < lg; i++) + { + x[i] = shl_sat(x[i], exp0); move16(); /* no saturation warnings triggered here */ + } + return; + } + IF (exp0 < 0) + { + tmp = shl(-32768, s_max(exp0, -15)); /* we use negative to correctly represent 1.0 */ + FOR (i = 0; i < lg; i++) + { + x[i] = msu_r(0, x[i], tmp); move16(); /* msu instead of mac because factor is negative */ + } + return; + } +} + +void plc_phEcu_minval_fx(const Word16 *inp, /* i : vector */ + const Word16 len, /* i : length */ + Word16 *minvalPtr /* o : min value Ptr */ +) +{ + Word16 minTmp; + Counter pos; + + minTmp = inp[0]; move16(); + assert(len>1); + FOR (pos = 1; pos < len; pos++) + { + minTmp = s_min(inp[pos], minTmp); + } + + *minvalPtr = minTmp; move16(); +} + +void plc_phEcu_maxval_fx(const Word16 *inp, /* i : vector */ + const Word16 len, /* i : length */ + Word16 *maxvalPtr /* o : *maxvalPtr */ +) +{ + Word16 maxTmp; + Counter pos; + + maxTmp = inp[0]; move16(); + + assert(len>1); + FOR (pos = 1; pos < len; pos++) + { + maxTmp = s_max(inp[pos], maxTmp); + } + *maxvalPtr = maxTmp; move16(); +} + +/* in case a value (e.g max or min) is already known , find the first corresponding array index */ +Word16 plc_phEcu_find_ind_fx( /* o : output maximum indx 0.. len-1 */ + const Word16 *inp, /* i : vector */ + const Word16 len, /* i : length */ + const Word16 val /* i : value to find */ +) +{ + Word16 val_ind; + Counter pos; + + val_ind = -1; move16(); + + FOR(pos = 0; pos < len; pos++) + { + if (sub(inp[pos], val) == 0) + { + val_ind = pos; move16(); + } + } + return val_ind; +} + +/*----------------------------------------------------------------------------- + * ratio_fx() + * + * Divide the numerator by the denominator. + *----------------------------------------------------------------------------*/ +Word16 plc_phEcu_ratio_fx( /* o : quotient in Q14 */ + const Word32 numer, /* i : numerator */ + const Word32 denom, /* i : denominator */ + Word16 *expo) /* o : req shift of quotient */ +{ + Word16 expNumer, expDenom; + Word16 manNumer, manDenom; + Word16 quotient; +#ifdef DYNMEM_COUNT + Dyn_Mem_In("plc_phEcu_ratio_fx", sizeof(struct { + Word16 expNumer, expDenom; + Word16 manNumer, manDenom; + Word16 quotient; + })); +#endif + + expDenom = norm_l(denom); /* exponent */ + manDenom = extract_h(L_shl(denom, expDenom)); /* mantissa */ + expNumer = norm_l(numer); /* exponent */ + manNumer = extract_h(L_shl(numer, expNumer)); /* mantissa */ + manNumer = shr_pos(manNumer, 1); /* Ensure the numerator < the denominator */ + quotient = div_s(manNumer, manDenom); /* in Q14 */ + + *expo = sub(expNumer, expDenom); +#ifdef DYNMEM_COUNT + Dyn_Mem_Out(); +#endif + return quotient; /* Q14 */ +} + +Word32 winEnCalc( /* o: output summed energy Ltot */ + const Word16 *x, /* i: Input signal */ + const Word16 headroom_shift, /* i: headroom_shift */ + const Word16 *win, /* i: left side Window coefficients */ + const Word16 rectLength, /* i: Offset in between the 1st and 2nd symmetric halves of the Hamming window */ + const Word16 halfLength, /* i: Half of the total length of a complete Hamming window. */ + Word16 *exp /* i/o : i exp of Word16 variable x , o:Lexp of output Word32 sum */ + ) +{ + Counter i; + Word32 L_tot; + const Word16 *pX, *pW; + Word16 tmp, tmp_RL; + +#ifdef DYNMEM_COUNT + Dyn_Mem_In("PhEcu::GF::winEnCalc", sizeof(struct { + Counter i; + Word32 L_tot; + const Word16 *pX, *pW; + Word16 tmp, tmp_RL; + })); +#endif + + +#ifdef WMOPS + push_wmops("PhECU::winEnCalc"); +#endif + + L_tot = INT32_MAX; move32(); /*acc is on negative side , but as all accumulation is positive, we make use of one extra bit */ + pX = x; + pW = win; + + + assert( headroom_shift>=0 ); + FOR (i = 0; i < halfLength; i++) /* 1st symmetric half of the Hamming window */ + { + tmp = mult(*pX++, *pW++); + tmp = shr_pos(tmp, headroom_shift); /* shr may/create bias on the negative side , costly options are shr_r or use msu_r */ + L_tot = L_msu0(L_tot, tmp, tmp); /* acc on negative energy side */ + } + + /* Periodic filter - one more rect sample before end tapering */ + tmp_RL = add(rectLength, 1); + ASSERT(rectLength != 0); + + FOR (i = 0; i < tmp_RL; i++) /* If rectLength is zero, it's a pure Hamming window; otherwise Hamming-Rectangular. */ + { + tmp = shr_pos( *pX++, headroom_shift); + L_tot = L_msu0(L_tot, tmp, tmp); /* acc on negative side */ + } + + tmp_RL = sub(halfLength, 1); + ASSERT(rectLength != 0); + + FOR (i = 0; i < tmp_RL; i++) /* 2nd symmetric half of the Hamming window. */ + { + tmp = mult(*pX++, *(--pW)); + tmp = shr_pos(tmp, headroom_shift); + L_tot = L_msu0(L_tot, tmp, tmp); + } + + /* Lexp = 2*(incoming_exp + dnshift) + 1 , 2x for square + 1(for msu0 DSP dn shift)*/ + *exp = add(shl_pos(add(*exp, headroom_shift),1),1); + + /* handle wrap on zero point */ + IF( L_tot >= 0 ) + { /* L_tot positive --> less than 32 bits needed, */ + L_tot = L_add(L_tot,(INT32_MIN+1)); + if( L_tot == 0 ) + { + *exp = LTOT_MIN_EXP; /* WC is actually (-(15+4)*2 + 1 +1 -31) */ ; move16(); + } + L_tot = L_min(L_tot, -1); /* make sure there is energy for future ratio calculations */ + } + ELSE + { /* L_tot negative --> more than 31 bits needed for sum , scale 32 bit sum within 31 bits and adjust exp */ + + L_tot = L_shr_pos(L_add(L_tot,1),1); /* rnd by adding 1, then use 50% contribution from negative side */ + L_tot = L_add(L_tot, INT32_MIN>>1); /* add 50% contribution from positive side */ + + *exp = add(*exp, 1); move16(); + } + + L_tot = L_max( -(INT32_MAX), L_tot); /* guard against max accumulation on the negative side , should only occur for rectangle windows */ + L_tot = L_negate(L_tot); /* no saturation here */ + + /* activate when xfp_exp is not used any longer */ + /* pre-maximize the mantissa for the following steps in burst_ana_dx */ + tmp = norm_l(L_tot); + L_tot = L_shl(L_tot,tmp); + *exp = sub(*exp, tmp); move16(); + +#ifdef WMOPS + pop_wmops(); +#endif +#ifdef DYNMEM_COUNT + Dyn_Mem_Out(); +#endif + + return L_tot; +} + diff --git a/lib_lc3plus/plc_tdac_fx.c b/lib_lc3plus/plc_tdac_fx.c new file mode 100644 index 0000000000000000000000000000000000000000..c27cc9e7a29083b56fc54b940870ab8f36b9bc35 --- /dev/null +++ b/lib_lc3plus/plc_tdac_fx.c @@ -0,0 +1,217 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.5 * +* 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 "defines.h" +#include "functions.h" + +/* + * processTdac_fx + * + * Parameters: + * ola_mem o: pointer of output signal Q0 + * ola_mem_exp o: exponent of output signal Q0 + * synth i: pointer of input signal Q0 + * synth_exp i: exponent of input signal Q0 + * win i: pointer of analysis and synthesis window Q0 + * la_zeroes i: number of zeroes Q0 + * frame_len i: frame length Q0 + * + * Function: + * + * + * Returns: + * void + */ +void processTdac_fx(Word16 *ola_mem, Word16 *ola_mem_exp, const Word16 *synth_inp, const Word16 synth_exp_inp, +#ifdef ENABLE_HR_MODE + const Word32 *win, +#else + const Word16 *win, +#endif + const Word16 la_zeroes, const Word16 frame_len, Word8 *scratchBuffer) +{ + Counter i; + Word16 s; + Word16 L; + Word16 N; + Word16 NZ; + Word16 LD2; + Word32 sz; + Word16 INV_NORM; + Word16 INV_NORM_E; + Word16 smax; + Word16 * synth; + Word16 synth_len; + Word16 synth_exp; +#ifdef ENABLE_HR_MODE + const Word32 *win1, *win2, *win3, *win4; +#else + const Word16 *win1, *win2, *win3, *win4; +#endif + const Word16 *synth1; + const Word16 *synth2; + Word16 * ola_mem1; + Word16 * ola_mem2; + +#ifdef DYNMEM_COUNT + Dyn_Mem_In("processTdac_fx", sizeof(struct { + Counter i; + Word16 s; + Word16 L; + Word16 N; + Word16 NZ; + Word16 LD2; + Word32 sz; + Word16 INV_NORM; + Word16 INV_NORM_E; + Word16 smax; + Word16 * synth; + Word16 synth_len; + Word16 synth_exp; + const Word16 *win1; + const Word16 *win2; + const Word16 *win3; + const Word16 *win4; + const Word16 *synth1; + const Word16 *synth2; + Word16 * ola_mem1; + Word16 * ola_mem2; + })); +#endif + + synth = (Word16 *)scratchAlign(scratchBuffer, 0); /* Size = 2 * MAX_LEN */ + + ASSERT(la_zeroes <= frame_len / 2); + + L = frame_len; move16(); + LD2 = shr_pos(L, 1); + NZ = sub(LD2, la_zeroes); + + /* inverse normalization of sqrt(2/N) inside window */ +#ifdef ENABLE_HR_MODE + IF ((sub(frame_len, 960) == 0) || (sub(frame_len, 720) == 0)) + { + INV_NORM = negate(shl_pos(frame_len, (15 - 10))); + INV_NORM_E = 3; move16(); + } + ELSE +#endif + { + INV_NORM = negate(shl_pos(frame_len, (15 - 9))); + INV_NORM_E = 2; move16(); + if (norm_s(INV_NORM) > 0) + { + INV_NORM = shl_pos(INV_NORM, 1); + INV_NORM_E = 1; move16(); + } + if (sub(frame_len, 120) <= 0) + { + INV_NORM_E = add(INV_NORM_E, 2); + } + if (sub(frame_len, 20) <= 0) + { + INV_NORM_E = add(INV_NORM_E, 2); + } + } + + /* Scale input */ + synth_len = sub(shl_pos(L, 1), la_zeroes); + s = getScaleFactor16(synth_inp, synth_len); + + FOR (i = 0; i < synth_len; i++) + { + synth[i] = shl(synth_inp[i], s); move16(); + } + synth_exp = sub(synth_exp_inp, s); + + /* calculate x_ov[L+la_zeroes] ... x_ov[2*L-1] */ + + win1 = &win[L + LD2 - 1]; + win2 = &win[L + LD2]; + + win3 = &win[LD2 - 1]; + win4 = &win[LD2]; + + synth1 = &synth[L + LD2 - 1 - la_zeroes]; + synth2 = &synth[L + LD2 - la_zeroes]; + + ola_mem1 = &ola_mem[LD2 - la_zeroes]; + ola_mem2 = &ola_mem[LD2 - la_zeroes - 1]; + + smax = 15; move16(); + + FOR (i = 0; i < NZ; i++) + { + /* analysis windowing + 2N -> N */ + sz = L_mac_sat(L_mult(*synth1, extractW16(*win1)), *synth2, extractW16(*win2)); + + /* N -> 2N + synthesis windowing */ + *ola_mem1 = round_fx(Mpy_32_16_lc3plus(sz, extractW16(*win3))); move16(); + *ola_mem2 = round_fx(Mpy_32_16_lc3plus(sz, extractW16(*win4))); move16(); + + /* determine headroom */ + s = norm_s(*ola_mem1); + if (*ola_mem1 != 0) + smax = s_min(smax, s); + s = norm_s(*ola_mem2); + if (*ola_mem2 != 0) + smax = s_min(smax, s); + + /* pointer update */ + win1--; + win2++; + win3--; + win4++; + synth1--; + synth2++; + ola_mem1++; + ola_mem2--; + } + + N = LD2; move16(); + + FOR (; i < N; i++) + { + /* analysis windowing + 2N -> N */ + sz = L_mult(*synth1, extractW16(*win1)); + + /* N -> 2N + synthesis windowing */ + *ola_mem1 = round_fx(Mpy_32_16_lc3plus(sz, extractW16(*win3))); move16(); + + /* determin headroom */ + s = norm_s(*ola_mem1); + if (*ola_mem1 != 0) + smax = s_min(smax, s); + + /* pointer update */ + win1--; + win2++; + win3--; + synth1--; + synth2++; + ola_mem1++; + } + + smax = s_min(smax, 15); + + N = add(N, NZ); + + FOR (i = 0; i < N; i++) + { + ola_mem[i] = round_fx(L_mult(shl(ola_mem[i], smax), INV_NORM)); move16(); + } + + *ola_mem_exp = sub(add(synth_exp, INV_NORM_E), smax); move16(); + +#ifdef DYNMEM_COUNT + Dyn_Mem_Out(); +#endif +} + + diff --git a/lib_lc3plus/plc_tdc_inverse_odft_fx.c b/lib_lc3plus/plc_tdc_inverse_odft_fx.c new file mode 100644 index 0000000000000000000000000000000000000000..1e8e3191c2ef81e074411e5913ca181da7c2277a --- /dev/null +++ b/lib_lc3plus/plc_tdc_inverse_odft_fx.c @@ -0,0 +1,130 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.5 * +* 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 "defines.h" +#include "functions.h" + +void processInverseODFT_fx(Word32 *r_fx, Word16 *r_fx_exp, Word32 *d2_fx, Word16 d2_fx_exp, Word16 n_bands, + Word16 lpc_order, Word8 *scratchBuffer) +{ + Counter i; + Word16 s; + Word16 n_bands2; + Word32 * x; + const Word32 *inv_odft_twiddle_re; + const Word32 *inv_odft_twiddle_im; + Word8 * buffer_BASOP_rfftN; + + +#ifdef DYNMEM_COUNT + Dyn_Mem_In("processInverseODFT_fx", sizeof(struct { + Counter i; + Word16 s; + Word16 n_bands2; + Word32 * x; + const Word32 *inv_odft_twiddle_re; + const Word32 *inv_odft_twiddle_im; + Word8 * buffer_BASOP_rfftN; + Word32 * params[2]; + })); +#endif + + x = scratchAlign(scratchBuffer, 0); /* Size = 320 bytes */ + buffer_BASOP_rfftN = scratchAlign(x, sizeof(*x) * (MAX_BANDS_NUMBER_PLC + MAX_BANDS_NUMBER_PLC/2)); /* Size = 480 bytes */ + + ASSERT(lpc_order <= M); + ASSERT(n_bands == 80 || n_bands == 60 || n_bands == 40 || n_bands == 20); + + n_bands2 = shr_pos_pos(n_bands, 1); + + test(); + IF (sub(n_bands, 20) == 0 || sub(n_bands, 60) == 0) + { + /* sort input samples */ + FOR (i = 0; i < n_bands2; i++) + { + x[2*i] = d2_fx[2 * i]; move32(); + x[2*i+1] = 0; move32(); + x[n_bands + 2*i] = d2_fx[n_bands - 1 - 2 * i]; move32(); + x[n_bands + 2*i + 1] = 0; move32(); + } + BASOP_cfft_lc3plus(&x[0], &x[1], n_bands, 2, &d2_fx_exp, (Word32*)buffer_BASOP_rfftN); + } + ELSE + { + /* sort input samples */ + FOR (i = 0; i < n_bands2; i++) + { + x[i] = d2_fx[2 * i]; move32(); + x[n_bands2 + i] = d2_fx[n_bands - 1 - 2 * i]; move32(); + } + + BASOP_rfftN(x, n_bands, &d2_fx_exp, buffer_BASOP_rfftN); + } + + inv_odft_twiddle_re = inv_odft_twiddle_80_re; + inv_odft_twiddle_im = inv_odft_twiddle_80_im; + IF (sub(n_bands, 20) == 0) + { + inv_odft_twiddle_re = inv_odft_twiddle_20_re; + inv_odft_twiddle_im = inv_odft_twiddle_20_im; + } + ELSE IF (sub(n_bands, 40) == 0) + { + inv_odft_twiddle_re = inv_odft_twiddle_40_re; + inv_odft_twiddle_im = inv_odft_twiddle_40_im; + } + ELSE IF (sub(n_bands, 60) == 0) + { + inv_odft_twiddle_re = inv_odft_twiddle_60_re; + inv_odft_twiddle_im = inv_odft_twiddle_60_im; + } + + s = norm_l(x[0]); + + /* imag[0] is always zero */ + r_fx[0] = L_shl_pos(x[0], s); move32(); + + /* r_fx[0] = r_fx[0] * 1.0001 */ + r_fx[0] = Mpy_32_32_lc3plus(r_fx[0], 0x4001A36E); move32(); + IF (norm_l(r_fx[0]) > 0) + { + r_fx[0] = L_shl_pos(r_fx[0], 1); + } + ELSE + { + s = sub(s, 1); + } + + /* post-twiddle */ + FOR (i = 1; i <= lpc_order; i++) + { + r_fx[i] = L_add(Mpy_32_32_lc3plus(L_shl(x[2 * i], s), inv_odft_twiddle_re[i - 1]), + Mpy_32_32_lc3plus(L_shl(x[2 * i + 1], s), inv_odft_twiddle_im[i - 1])); move32(); + } + + *r_fx_exp = sub(d2_fx_exp, s); move16(); + + /* r_fx[0] must not be zero */ + IF (r_fx[0] == 0) + { + r_fx[0] = (Word32)0x7FFFFFFF; move32(); + FOR (i = 1; i <= lpc_order; i++) + { + r_fx[i] = 0; move32(); + } + *r_fx_exp = 0; move16(); + } + +#ifdef DYNMEM_COUNT + Dyn_Mem_Out(); +#endif +} + + diff --git a/lib_lc3plus/plc_tdc_lagwin_fx.c b/lib_lc3plus/plc_tdc_lagwin_fx.c new file mode 100644 index 0000000000000000000000000000000000000000..e5bd94d66ffb985d19cb1ec48cd4fd3abbd629d0 --- /dev/null +++ b/lib_lc3plus/plc_tdc_lagwin_fx.c @@ -0,0 +1,32 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.5 * +* 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 "defines.h" +#include "functions.h" + +void processLagwin_fx(Word32 r[], const Word32 w[], Word16 m) +{ + /* Start Processing */ + Counter i; + +#ifdef DYNMEM_COUNT + Dyn_Mem_In("processLagwin_fx", sizeof(struct { Counter i; })); +#endif + + FOR (i = 0; i < m; i++) + { + r[i + 1] = Mpy_32_32_lc3plus(r[i + 1], w[i]); move32(); + } + +#ifdef DYNMEM_COUNT + Dyn_Mem_Out(); +#endif +} + + diff --git a/lib_lc3plus/plc_tdc_main_fx.c b/lib_lc3plus/plc_tdc_main_fx.c new file mode 100644 index 0000000000000000000000000000000000000000..c6558dd1b63d0bfad744af76ccdf48ec1c4ddd4b --- /dev/null +++ b/lib_lc3plus/plc_tdc_main_fx.c @@ -0,0 +1,1257 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.5 * +* 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 "defines.h" +#include "functions.h" + +/*****************************************************************************/ + +static Word16 TDC_Dot_product(const Word16 x[], const Word16 y[], const Word16 lg); +static Word32 TDC_L_Dot_product(const Word16 x[], const Word16 y[], const Word16 lg); +static void TDC_highPassFiltering_fx(const Word16 L_buffer, Word16 exc2[], const Word16 l_fir_fer, + const Word16 *hp_filt); +static Word32 TDC_calcGainp(Word16 x[], Word16 y[], Word16 lg); +static void TDC_calcGainc(Word16 *exc, Word16 Q_exc, Word16 old_fpitch, Word16 lg, Word16 frame_dms, Word16 lp_gainp, Word32 *lp_gainc); +static void TDC_random_fx(Word16 *seed, Word16 lg, Word16 *y); +static Word16 TDC_preemph(Word16 *x, const Word16 fac, const Word16 lg); +static void TDC_LPC_residu_fx(const Word16 *a, Word16 *x, Word16 *y, Word16 lg, Word16 m); +static void TDC_deemph_fx(const Word16 *x, Word16 *y, const Word16 fac, const Word16 lg, const Word16 mem); +static void TDC_LPC_synthesis_fx(const Word16 sh, const Word16 a[], const Word16 x[], Word16 y[], const Word16 lg, + const Word16 m); +static void TDC_normalize_energy_fx(Word16 *gain, Word16 *gain_exp, const Word16 *x, const Word16 lg); + +#ifdef CR8_G_ADD_75MS +const Word16 beforeNextIncArray_fx[4][4] = {{0,0,0,1}, + {0,1,0,1}, + {0,1,1,1}, + {1,1,1,1}}; +const Word16 nextIncArray_fx[4][4] = {{1,0,0,0}, + {1,0,1,0}, + {1,0,1,1}, + {1,1,1,1}}; +#endif +#ifdef CR10_A_ATTENUATION_CURVE_SELECTOR +static Word16 type_2_alpha_long(Word16 nbLostFramesInRow, Word16 frame_dms); +static Word16 powWord16rest(Word16 base, Word16 exp, Word16 rest); +#endif + +/*****************************************************************************/ + + +/* + * processTimeDomainConcealment_Apply_fx + * + * Parameters: + * pitch_int i : integer pitch lag Q0 + * preemphFac_fx i : preemphase factor Q15 + * A_fx i : lp filter coefficients Qx + * pcmbufHist_fx i : pointer to input signal Qq_fx_old_exp + * frame_length i : frame length Q0 + * fs_idx i : sample rate index Q0 + * nbLostFramesInRow i : number of consecutive lost frames Q0 + * overlap i : overlap length Q0 + * stabFac_fx i : stability factor Q15 + * fract i/o: fraction of lag Q0 + * seed_fx i/o: pointer to seed Q0 + * gain_p_fx i/o: pointer to gainp Q15 + * gain_c_fx i/o: pointer to gainc 15Q16 + * synth_fx o : pointer to synthesized signal Q_syn + * Q_syn o : exponent for synthesized signal Q0 + * alpha o : damping factor Q15 + * scratchBuffer i : scratch buffer + * + * Function: + * Perform the time domain concealment. + * + * Returns: + * void + */ +void processTimeDomainConcealment_Apply_fx(const Word16 pitch_int, const Word16 preemphFac_fx, const Word16 *A_fx, + const Word16 lpc_order, const Word16 *pcmbufHist_fx, const Word16 frame_length, + const Word16 frame_dms, const Word16 fs_idx, const Word16 nbLostFramesInRow, + const Word16 overlap, const Word16 stabFac_fx, Word16 *fract, + Word16 *seed_fx, + Word32 *gain_c_fx, Word16 *synth_fx, Word16 *Q_syn, Word16 *alpha, Word16 max_len_pcm_plc, + Word16 harmonicBuf_fx[MAX_PITCH], Word16 synthHist_fx[M], Word16 *const harmonicBuf_Q, + Word8 *scratchBuffer +#ifdef CR9_I_INC_TDC_FADEOUT_LEN + ,UWord8 plc_fadeout_type +#endif +#ifdef CR10_A_ATTENUATION_CURVE_SELECTOR + ,Word16 * alpha_type_2_table +#endif +) +{ + Counter i; + Word16 s, s1, c1, c2, len, cnt, g_fx, ilen, Tc, nextInc, beforeNextInc; + Word32 tmp32, tmp32_2, gainc_tmp; + Word16 gain_p_fx; + Word32 gain_c_32_fx; + Word16 gain_c_16_fx, gain_c_16_fx_exp, gain_inov_fx, gain_inov_fx_exp, ilen_exp; + Word16 hpBlendFac; + Word16 len_pi_lf_2, frame_length_2, step_fx, step_n_fx, gain_h_fx, nbLostCmpt_loc, mem_deemph; + Word16 * synth_mem_fx, *synth_tmp_fx, *exc2_fx, *exc_fx, *pt_exc, *pt1_exc, *x_pre_fx; + Word16 * harmonicBufPtr; + Word16 Q_exc = 0, exp_scale; + const Word16 *hp_filt_fx, *TDC_high_harm; + Word16 alphaPrev_fx; + Word16 throttle; +#ifdef CR8_G_ADD_75MS + Word16 frame_dms_idx, nbLostFramesInRow_mod; +#endif + +#ifdef DYNMEM_COUNT + Dyn_Mem_In("processTimeDomainConcealment_Apply_fx", sizeof(struct { + Counter i; + Word16 s, s1, c1, c2, len, cnt, g_fx, ilen, Tc, nextInc, beforeNextInc; + Word32 tmp32, tmp32_2, gainc_tmp; + Word16 gain_p_fx; + Word32 gain_c_32_fx; + Word16 gain_c_16_fx, gain_c_16_fx_exp, gain_inov_fx, gain_inov_fx_exp, ilen_exp; + Word16 hpBlendFac; + Word16 len_pi_lf_2, frame_length_2, step_fx, step_n_fx, gain_h_fx, nbLostCmpt_loc, mem_deemph; + Word16 * synth_mem_fx, *synth_tmp_fx, *exc2_fx, *exc_fx, *pt_exc, *pt1_exc, *x_pre_fx; + Word16 * harmonicBufPtr; + Word16 Q_exc, exp_scale; + const Word16 *hp_filt_fx, *TDC_high_harm; + Word16 alphaPrev_fx; + Word16 throttle; + Word16 frame_dms_idx, nbLostFramesInRow_mod; + })); +#endif + +#ifdef CR9_I_INC_TDC_FADEOUT_LEN + Word32 plc_fadeout_len = 0; +#ifdef CR10_A_ATTENUATION_CURVE_SELECTOR + if (plc_fadeout_type >= 1){ +#else + if (plc_fadeout_type == 1){ +#endif + plc_fadeout_len = PLC_FADEOUT_TYPE_1_IN_MS; + } + else{ + plc_fadeout_len = PLC_FADEOUT_IN_MS; + } +#endif + + /* len of output signal */ + len = add(frame_length, overlap); + +#ifdef CR8_G_ADD_75MS + nbLostFramesInRow_mod = sub(nbLostFramesInRow, 1) & 0x0003; + + frame_dms_idx = mult(frame_dms, 0x051F); + nbLostCmpt_loc = add(shr(L_mult0(frame_dms_idx, sub(nbLostFramesInRow, 1)), 2), 1); + frame_dms_idx = sub(frame_dms_idx, 1); + beforeNextInc = beforeNextIncArray_fx[frame_dms_idx][nbLostFramesInRow_mod]; move16(); + nextInc = nextIncArray_fx [frame_dms_idx][nbLostFramesInRow_mod]; move16(); +#else + nbLostCmpt_loc = nbLostFramesInRow; move16(); + nextInc = 1; move16(); + beforeNextInc = 1; move16(); + SWITCH (frame_dms) + { + case 25: + nbLostCmpt_loc = shr(add(nbLostFramesInRow, 3), 2); + nextInc = (nbLostFramesInRow & 0x0003) == 1; move16(); + beforeNextInc = (nbLostFramesInRow & 0x0003) == 0; move16(); + BREAK; + case 50: + nbLostCmpt_loc = shr(add(nbLostFramesInRow, 1), 1); + nextInc = (nbLostFramesInRow & 0x0001) == 1; move16(); + beforeNextInc = (nbLostFramesInRow & 0x0001) == 0; move16(); + BREAK; + } +#endif + +#ifdef CR9_I_INC_TDC_FADEOUT_LEN + IF (sub(nbLostCmpt_loc, plc_fadeout_len / 10) > 0) +#else + IF (sub(nbLostCmpt_loc, PLC_FADEOUT_IN_MS / 10) > 0) +#endif + { + gain_p_fx = 0; move16(); + *gain_c_fx = 0; move32(); + *Q_syn = 0; move16(); + *alpha = 0; move16(); + basop_memset(synth_fx, 0, len * sizeof(Word16)); +#ifdef DYNMEM_COUNT + Dyn_Mem_Out(); +#endif + return; + } + + frame_length_2 = shr_pos(frame_length, 1); + + Tc = pitch_int; move16(); + if (sub(*fract, 0) > 0) + { + Tc = add(Tc, 1); + } + + len_pi_lf_2 = add(Tc, frame_length_2); + + /*---------------------------------------------------------------- + * Buffer Initialization + * + * exc_fx synth_mem_fx + * |--exc_buf_past--|--exc_buf_curr--|--syn_mem--|--x_pre--| + * |--exc2--| + * |--syn--| + * + *---------------------------------------------------------------*/ + + /* pointer inits */ + exc_fx = (Word16 *)scratchAlign(scratchBuffer, + sizeof(Word16) * len_pi_lf_2); /* MAX_PITCH+MAX_LEN/2 + MAX_LEN+MDCT_MEM_LEN_MAX */ + synth_mem_fx = (Word16 *)scratchAlign(exc_fx, sizeof(*exc_fx) * len); /* M */ + x_pre_fx = (Word16 *)scratchAlign(synth_mem_fx, sizeof(*synth_mem_fx) * lpc_order); /* MAX_PITCH+MAX_LEN/2+M+1 */ + exc2_fx = (Word16 *)scratchAlign(synth_mem_fx, sizeof(*synth_mem_fx) * lpc_order); /* MAX_LEN+MDCT_MEM_LEN_MAX+TDC_L_FIR_HP-1 */ + synth_tmp_fx = (Word16 *)scratchAlign(synth_mem_fx, sizeof(*synth_mem_fx) * lpc_order); /* MAX_LEN+MDCT_MEM_LEN_MAX */ + /* Buffers 'overlap' since they are not used at the same time */ + + /*---------------------------------------------------------------* + * LPC Residual * + *---------------------------------------------------------------*/ + IF (sub(nbLostFramesInRow, 1) == 0) + { + + /* copy buffer to pre-emphasis buffer */ + cnt = add(len_pi_lf_2, lpc_order + 1); + basop_memmove(&x_pre_fx[0], &pcmbufHist_fx[max_len_pcm_plc - cnt], cnt * sizeof(Word16)); + + /* apply pre-emphasis to the signal; x_pre = x_pre_flt * 2^(q_fx_old_exp-15-Q_exc+1) */ + Q_exc = TDC_preemph(&(x_pre_fx[1]), preemphFac_fx, sub(cnt, 1)); + + /* copy memory for LPC synth */ + basop_memmove(&synth_mem_fx[0], &x_pre_fx[len_pi_lf_2 + 1], lpc_order * sizeof(Word16)); + + /* LPC Residual; exc = exc_fx * 2^(q_fx_old_exp-15-Q_exc) */ + TDC_LPC_residu_fx(A_fx, &(x_pre_fx[lpc_order + 1]), &(exc_fx[-len_pi_lf_2]), len_pi_lf_2, lpc_order); + } + + /*---------------------------------------------------------------* + * Calculate gains * + *---------------------------------------------------------------*/ + + IF (sub(nbLostFramesInRow, 1) == 0) + { + IF (sub(pitch_int, Tc) == 0) + { + gain_p_fx = + round_fx_sat(L_shl_sat(TDC_calcGainp(&(x_pre_fx[lpc_order + Tc + 1]), &(x_pre_fx[lpc_order + 1]), frame_length_2), 15)); + } + ELSE + { + tmp32 = TDC_calcGainp(&(x_pre_fx[lpc_order + Tc + 1]), &(x_pre_fx[lpc_order + 2]), frame_length_2); + tmp32_2 = TDC_calcGainp(&(x_pre_fx[lpc_order + Tc + 1]), &(x_pre_fx[lpc_order + 1]), frame_length_2); + + IF (L_sub(tmp32, tmp32_2) > 0) + { + Tc = pitch_int; move16(); + gain_p_fx = round_fx_sat(L_shl_sat(tmp32, 15)); + *fract = 0; move16(); + } + ELSE + { + gain_p_fx = round_fx_sat(L_shl_sat(tmp32_2, 15)); + } + } + + if (gain_p_fx < 0) + { + gain_p_fx = 0; move16(); + } + + IF (sub(pitch_int, Tc) == 0) + { + /* gain_c = gain_c_32_fx * 2^(q_fx_old_exp-31) */ + TDC_calcGainc(exc_fx, Q_exc, Tc, frame_length_2, frame_dms, gain_p_fx, &gain_c_32_fx); + } + ELSE + { + TDC_calcGainc(exc_fx, Q_exc, pitch_int, frame_length_2, frame_dms, gain_p_fx, &tmp32); + TDC_calcGainc(exc_fx, Q_exc, Tc , frame_length_2, frame_dms, gain_p_fx, &gain_c_32_fx); + + gain_c_32_fx = L_min(gain_c_32_fx, tmp32); move32(); + } + } + ELSE + { + gain_c_32_fx = *gain_c_fx; move32(); + gain_p_fx = *alpha; + } + + /*---------------------------------------------------------------* + * Damping factor * + *---------------------------------------------------------------*/ + + alphaPrev_fx = 0x7FFF; move16(); + IF (sub(nbLostFramesInRow,1) > 0) + { + alphaPrev_fx = *alpha; move16(); + } +#ifdef CR9_N_SHORT_FADE_FOR_UNSTABLE_PITCH + IF (sub(plc_fadeout_type,2) == 0 ){ +#ifdef CR10_A_ATTENUATION_CURVE_SELECTOR + *alpha = alpha_type_2_table[nbLostFramesInRow]; +#else + IF (sub(frame_dms,50) == 0){ + IF (sub(nbLostFramesInRow,30) >= 0){ + *alpha = 0; move16(); + } ELSE { + *alpha = FADE_OUT_TYPE_2_ALPHA_5MS[nbLostFramesInRow]; move16(); + } + } + IF (sub(frame_dms,25) == 0){ + IF (sub(nbLostFramesInRow,60) >= 0){ + *alpha = 0; move16(); + } ELSE { + *alpha = FADE_OUT_TYPE_2_ALPHA_2_5MS[nbLostFramesInRow]; move16(); + } + } +#endif + } + ELSE{ +#endif + IF (nextInc != 0) + { + IF (sub(nbLostCmpt_loc, 1) == 0) + { + /* Threshold 31470 is 0.98^2 in Q15 format */ + IF (sub(gain_p_fx, 31470) > 0) + { + *alpha = 0x7D71; /*0.98f*/ + move16(); + } + /* Threshold 28037 is 0.925^2 in Q15 format */ + ELSE IF (sub(gain_p_fx, 28037) < 0) + { + *alpha = 0x7666; /*0.925f*/ + move16(); + } + ELSE + { + exp_scale = 0; + *alpha = Sqrt16_lc3plus(gain_p_fx, &exp_scale); move16(); + *alpha = shl(*alpha, exp_scale); + } + } + ELSE + { + SWITCH (nbLostCmpt_loc) + { + case 2: + c1 = 0x50A4; /*0.630f*/ + move16(); + c2 = 0x2CCD; /*0.350f*/ + move16(); + BREAK; + default: + c1 = 0x5375; /*0.652f*/ + move16(); + c2 = 0x29FC; /*0.328f*/ + move16(); + BREAK; + } + + *alpha = mult_r(stabFac_fx, c2); + *alpha = add(*alpha, c1); + + *alpha = mult(gain_p_fx, *alpha); + + + IF (sub(nbLostCmpt_loc, 2) == 0) + { + if (sub(*alpha, 0x75A2 /*0.919f*/) < 0) + { + *alpha = 0x75A2; move16(); + } + } + ELSE IF (sub(nbLostCmpt_loc, 5) > 0) + { + gain_p_fx = *alpha; move16(); + } + } + } + + IF (sub(nbLostCmpt_loc,3) > 0) + { + SWITCH (frame_dms) + { + case 25: *alpha = mult(*alpha, PLC34_ATTEN_FAC_025_FX); BREAK; +#ifdef CR9_J_SLOW_TDC_FADEOUT + case 50: *alpha = mult(*alpha, PLC34_ATTEN_FAC_025_FX); BREAK; +#else + case 50: *alpha = mult(*alpha, PLC34_ATTEN_FAC_050_FX); BREAK; +#endif +#ifdef CR8_G_ADD_75MS + case 75: *alpha = mult(*alpha, PLC34_ATTEN_FAC_075_FX); BREAK; +#endif + case 100: *alpha = mult(*alpha, PLC34_ATTEN_FAC_100_FX); BREAK; + } + } + if (sub(nbLostCmpt_loc, 5) > 0) + { + gain_p_fx = *alpha; move16(); + } +#ifdef CR9_N_SHORT_FADE_FOR_UNSTABLE_PITCH + } +#endif + + /*---------------------------------------------------------------* + * Construct the harmonic part * + * Last pitch cycle of the previous frame is repeatedly copied. * + *---------------------------------------------------------------*/ + + pt_exc = harmonicBuf_fx; move16(); + pt1_exc = exc_fx - Tc; move16(); + s = s_min(len, Tc); move16(); + test(); + IF (sub(nbLostFramesInRow, 1) == 0) + { + *harmonicBuf_Q = Q_exc; move16(); + IF (sub(stabFac_fx, 32767 /*1.f Q15*/) >= 0) + { + basop_memmove(pt_exc, pt1_exc, Tc * sizeof(Word16)); + } + ELSE + { + /* These values are necessary for the last five filtered samples */ + basop_memmove(exc_fx, &exc_fx[-Tc], (TDC_L_FIR_HP-1)/2 * sizeof(Word16)); + TDC_high_harm = TDC_high_32_harm; + if (sub(fs_idx, 1) <= 0) + { + TDC_high_harm = TDC_high_16_harm; + } + FOR (i = 0; i < Tc; i++) + { + pt_exc[i] = TDC_Dot_product(&pt1_exc[i-(TDC_L_FIR_HP-1)/2], TDC_high_harm, TDC_L_FIR_HP); + } + } + } + ELSE + { + Q_exc = *harmonicBuf_Q; move16(); + } + + + /*---------------------------------------------------------------* + * Construct the random part of excitation * + *---------------------------------------------------------------*/ + + TDC_random_fx(seed_fx, add(len, sub(TDC_L_FIR_HP, 1)), exc2_fx); + + /* high pass noise */ + hp_filt_fx = TDC_high_32; + if (sub(fs_idx, 1) <= 0) + { + hp_filt_fx = TDC_high_16; + } + + IF (sub(nbLostFramesInRow, 1) == 0) + { + TDC_highPassFiltering_fx(len, exc2_fx, TDC_L_FIR_HP, hp_filt_fx); + } + ELSE + { + throttle = div_s(nbLostCmpt_loc, add(nbLostCmpt_loc, PLC3_HPBLENDTHROTTLE)); + hpBlendFac = mult(sub(0x7FFF, *alpha), throttle); + c1 = sub(0x7FFF, hpBlendFac); + FOR (i = 0; i < len; i++) + { + /* Return value of dot product is Q1 */ + tmp32 = Mpy_32_16_lc3plus(TDC_L_Dot_product(&exc2_fx[i], hp_filt_fx, TDC_L_FIR_HP), c1 /*Q15*/); + exc2_fx[i] = round_fx(L_mac0(tmp32, hpBlendFac, exc2_fx[i+TDC_L_FIR_HP/2])); move16(); + } + } + + /* normalize energy */ + TDC_normalize_energy_fx(&gain_inov_fx, &gain_inov_fx_exp, exc2_fx, frame_length); + tmp32 = Mpy_32_16_lc3plus( + L_sub(590558016l /*1.1 Q29*/, Mpy_32_16_lc3plus(L_shr_pos(L_deposit_h(gain_p_fx), 2), 24576 /*0.75*/)) /*Q29*/, + gain_inov_fx /*Q15,gain_inov_e*/); /*Q29,gain_inov_e*/ + s = norm_l(tmp32); + tmp32 = L_shl_pos(tmp32, s); + tmp32 = L_min(tmp32, 0x7FFEFFFF); + gain_inov_fx_exp = add(sub(gain_inov_fx_exp, s), 31 - 29); /*->Q31*/ + gain_inov_fx = round_fx(tmp32); /*Q15,gain_inov_e*/ + + /* gains */ + gain_h_fx = alphaPrev_fx; move16(); + + /* update steps */ + if (frame_length == 720) + { + ilen = BASOP_Util_Divide1616_Scale_lc3plus((Word16)1, 960, &ilen_exp); + } else { + ilen = BASOP_Util_Divide1616_Scale_lc3plus((Word16)1, frame_length, &ilen_exp); + } + step_fx = round_fx(L_shl(L_mult(sub(gain_h_fx, *alpha), ilen), ilen_exp)); + + s = norm_l(gain_c_32_fx); + tmp32 = L_shl_pos(gain_c_32_fx, s); + + gain_c_16_fx = extract_h(tmp32); + gain_c_16_fx_exp = sub(15, s); +#ifdef CR9_M_FIX_DIV_ZERO + gainc_tmp = L_mult (gain_c_16_fx, div_s(*alpha, s_max(alphaPrev_fx, 1))); +#else + gainc_tmp = L_mult (gain_c_16_fx, div_s(*alpha, alphaPrev_fx)); +#endif + tmp32 = L_sub (tmp32, gainc_tmp); + step_n_fx = round_fx(L_shl(Mpy_32_16_lc3plus(tmp32, ilen), ilen_exp)); + + /*---------------------------------------------------------------* + * Construct the total excitation * + *---------------------------------------------------------------*/ + + harmonicBufPtr = harmonicBuf_fx + ((nbLostFramesInRow - 1) * frame_length) % Tc; + + s1 = add(Q_exc, add(gain_inov_fx_exp, gain_c_16_fx_exp)); + cnt = add(frame_length, TDC_L_FIR_HP / 2); + + g_fx = mult_r(gain_c_16_fx, gain_inov_fx); + + FOR (i = 0; i < len; i++) + { + /* harmonic */ + if (harmonicBufPtr - harmonicBuf_fx >= Tc) { + harmonicBufPtr = harmonicBuf_fx; + } + exc_fx[i] = *harmonicBufPtr++; + tmp32 = L_mult(exc_fx[i], gain_h_fx); + /* random */ + tmp32_2 = L_shl_sat(L_mult(exc2_fx[i], g_fx), s1); + /* total */ + exc_fx[i] = round_fx_sat(L_add_sat(tmp32, tmp32_2)); move16(); + /* update */ + gain_h_fx = s_max(sub(gain_h_fx, step_fx), 0); + gain_c_16_fx = s_max(sub(gain_c_16_fx, step_n_fx), 0); + g_fx = mult_r(gain_c_16_fx, gain_inov_fx); + } + + /* update gain */ + *gain_c_fx = L_shl(gainc_tmp, sub(gain_c_16_fx_exp, 15)); move32(); + + + /*----------------------------------------------------------* + * Compute the synthesis speech * + *----------------------------------------------------------*/ + + /* introduce some headroom to avoid Overflows, 2 bit seem to be sufficient */ + *Q_syn = sub(Q_exc, 2); + *Q_syn = s_max(*Q_syn, -3); + + exp_scale = sub(*Q_syn, Q_exc - 1); + + IF (sub(nbLostFramesInRow, 1) != 0) + { + synth_mem_fx = synthHist_fx; + } + Copy_Scale_sig(synth_mem_fx, &synth_tmp_fx[-lpc_order], lpc_order, exp_scale); + TDC_LPC_synthesis_fx(sub(Q_exc, *Q_syn), A_fx, exc_fx, synth_tmp_fx, len, lpc_order); + + FOR (i=0; i= 0); + synth_fx[i] = mult(synth_fx[i], gain_h_fx); + gain_h_fx = sub(gain_h_fx, step_fx); + } + basop_memset(&synth_fx[frame_length], 0, overlap * sizeof(Word16)); + } + } + +#ifdef DYNMEM_COUNT + Dyn_Mem_Out(); +#endif +} + + +/*****************************************************************************/ + +static Word32 syn_kern_2(Word32 L_tmp, const Word16 a[], const Word16 y[]) +{ + L_tmp = L_msu_sat(L_tmp, y[-1], a[1]); + L_tmp = L_msu_sat(L_tmp, y[-2], a[2]); + return L_tmp; +} + +static Word32 syn_kern_4(Word32 L_tmp, const Word16 a[], const Word16 y[]) +{ + L_tmp = syn_kern_2(L_tmp, a, y); + return syn_kern_2(L_tmp, a + 2, y - 2); +} + +static Word32 syn_kern_8(Word32 L_tmp, const Word16 a[], const Word16 y[]) +{ + L_tmp = syn_kern_4(L_tmp, a, y); + return syn_kern_4(L_tmp, a + 4, y - 4); +} + +static Word32 syn_kern_16(Word32 L_tmp, const Word16 a[], const Word16 y[]) +{ + L_tmp = syn_kern_8(L_tmp, a, y); + return syn_kern_8(L_tmp, a + 8, y - 8); +} + +/* + * TDC_Dot_product + * + * Parameters: + * x i: x vector Q0 + * y i: y vector Q0 + * lg i: vector length Q0 + * + * Function: + * dot product + * + * Returns: + * dot product Q0 + */ +static Word16 TDC_Dot_product(const Word16 x[], const Word16 y[], const Word16 lg) +{ + Dyn_Mem_Deluxe_In( + Counter i; + Word32 sum; + ); + + sum = L_mult(x[0], y[0]); + FOR (i = 1; i < lg-1; i++) + { + sum = L_mac_sat(sum, x[i], y[i]); + } + + sum = mac_r_sat(sum, x[lg-1], y[lg-1]); + + Dyn_Mem_Deluxe_Out(); + + return sum; +} + +/* + * TDC_L_Dot_product + * + * Parameters: + * x i: x vector Q0 + * y i: y vector Q0 + * lg i: vector length Q0 + * + * Function: + * dot product + * + * Returns: + * dot product Q1 + */ +static Word32 TDC_L_Dot_product(const Word16 x[], const Word16 y[], const Word16 lg) +{ + Dyn_Mem_Deluxe_In( + Counter i; + Word32 sum; + ); + + sum = L_mac0(1L, x[0], y[0]); + FOR (i = 1; i < lg; i++) + { + sum = L_mac0(sum, x[i], y[i]); + } + + Dyn_Mem_Deluxe_Out(); + + return sum; +} + +/* + * TDC_highPassFiltering_fx + * + * Parameters: + * L_buffer i: buffer length + * exc2 i: unvoiced excitation before the high pass filtering Qx/Qx+1 + * l_fir_fer i: length highpass filter + * hp_filt i: highpass filter coefficients Q15 + * + * Function: + * Highpass filter + * + * Returns: + * void + */ +static void TDC_highPassFiltering_fx(const Word16 L_buffer, Word16 exc2[], const Word16 l_fir_fer, + const Word16 *hp_filt) +{ + Dyn_Mem_Deluxe_In( + Counter i; + ); + + FOR (i = 0; i < L_buffer; i++) + { + exc2[i] = round_fx(L_sub(TDC_L_Dot_product(&exc2[i], hp_filt, l_fir_fer), 1)); move16(); + } + + Dyn_Mem_Deluxe_Out(); +} + +/* + * TDC_calcGainc + * + * Parameters: + * exc i: pointer to excitation buffer + * Q_exc i: Q format of excitation buffer + * old_fpitch i: pitch_int + * lg i: length + * lp_gainp i: gain p + * lp_gainc o: pointer to gain (15Q16) + * + * Function: + * Gain calculation + * + * Returns: + * void + */ +static void TDC_calcGainc(Word16 *exc, Word16 Q_exc, Word16 old_fpitch, Word16 lg, Word16 frame_dms, Word16 lp_gainp, Word32 *lp_gainc) +{ + Dyn_Mem_Deluxe_In( + Word16 tmp16, tmp_e, tmp2_e; + Word32 L_tmp, L_tmp_max; + Counter i; + ); + + L_tmp = L_deposit_l(0); + + FOR (i = 0; i < lg; i++) + { + /* gain_c += ( exc[-i-1] - *gain_p * exc[-i-1-pitch_int] ) * ( exc[-i-1] - *gain_p * exc[-i-1-pitch_int] ); */ + tmp16 = sub_sat(exc[i - lg] /*Q1*/, mult_r(lp_gainp /*Q15*/, exc[i - lg - old_fpitch] /*Q1*/) /*Q1*/); + L_tmp = L_mac0_sat(L_tmp, tmp16, tmp16); /*Q3*/ + } + + IF (sub(frame_dms, 100) < 0) + { + L_tmp_max = L_deposit_l(0); + FOR (i = 0; i < lg; i++) + { + L_tmp_max = L_mac0_sat(L_tmp_max, exc[i - lg], exc[i - lg]); /*Q3*/ + } + L_tmp = L_min(L_tmp, L_tmp_max); + } + + tmp_e = norm_l(L_tmp); + L_tmp = L_shl(L_tmp, tmp_e); + tmp_e = sub(sub(31, shl_pos(Q_exc, 1)), tmp_e); /*L_tmp is Q31, now*/ + tmp16 = BASOP_Util_Divide3216_Scale_lc3plus(L_tmp /*Q31,norm,tmp_e*/, lg /*Q15,15*/, &tmp2_e) /*Q15,tmp2_e+tmp_e-15*/; + tmp_e = sub(add(tmp2_e, tmp_e), 15); + + IF (tmp16 != 0) + { + tmp16 = Sqrt16_lc3plus(tmp16, &tmp_e); /*Q15,norm,tmp_e*/ + tmp_e = L_min(tmp_e, 15); + *lp_gainc = L_shl_pos(L_deposit_l(tmp16), add(tmp_e, 1)); /*15Q16*/ + move32(); + } + ELSE + { + *lp_gainc = 0; + } + + Dyn_Mem_Deluxe_Out(); +} + +/* + * TDC_calcGainp + * + * Parameters: + * x i: input signal + * y i: shifted input signal + * lg i: vector length + * + * Function: + * Gain calculation + * + * Returns: + * gain (15Q16) + */ +static Word32 TDC_calcGainp(Word16 x[], Word16 y[], Word16 lg) +{ + Dyn_Mem_Deluxe_In( + Word32 tcorr, tener, Lgain, L_tmp1, L_tmp2; + Word16 m_corr, m_ener, negative, Q_corr, Q_ener; + Counter i; + ); + + negative = 0; move16(); + + L_tmp1 = L_deposit_l(0); + L_tmp2 = L_deposit_l(0); + FOR (i = 0; i < lg; i += 2) + { + L_tmp1 = L_mac0_sat(L_tmp1, x[i], y[i]); + L_tmp2 = L_mac0_sat(L_tmp2, x[i + 1], y[i + 1]); + } + tcorr = L_add(L_shr_pos(L_tmp1, 1), L_shr_pos(L_tmp2, 1)); + Q_corr = norm_l(tcorr); + tcorr = L_shl(tcorr, Q_corr); + Q_corr = sub(2, Q_corr); + + L_tmp1 = L_deposit_l(0); + L_tmp2 = L_deposit_l(0); + FOR (i = 0; i < lg; i += 2) + { + L_tmp1 = L_mac0_sat(L_tmp1, y[i], y[i]); + L_tmp2 = L_mac0_sat(L_tmp2, y[i + 1], y[i + 1]); + } + tener = L_add(L_shr_pos(L_tmp1, 1), L_shr_pos(L_tmp2, 1)); + Q_ener = norm_l(tener); + tener = L_shl(tener, Q_ener); + Q_ener = sub(2, Q_ener); + + tener = L_max(tener, 1); + + if (tcorr <= 0) + { + negative = 1; move16(); + } + tcorr = L_abs(tcorr); + + m_corr = extract_h(tcorr); + + m_ener = extract_h(tener); + + IF (sub(m_corr, m_ener) > 0) + { + m_corr = shr_pos(m_corr, 1); + Q_corr = add(Q_corr, 1); + } + if (m_ener == 0) + { + move16(); + m_corr = 0x7FFF; + } + if (m_ener != 0) + { + m_corr = div_s(m_corr, m_ener); + } + + Q_corr = sub(Q_corr, Q_ener); + + Lgain = L_shl(L_deposit_l(m_corr), add(Q_corr, 1)); + + if (negative != 0) + { + Lgain = L_negate(Lgain); + } + + Dyn_Mem_Deluxe_Out(); + + return Lgain; +} + +/* + * TDC_LPC_synthesis_fx + * + * Parameters: + * sh i : scaling to apply for a[0] Q0 + * a[] i : LP filter coefficients Qx + * x[] i : input signal Qx + * y[] o : output signal Qx-s + * lg i : size of filtering Q0 + * m i : order of LP filter Q0 + * + * Function: + * Apply LP filtering to obtain synthesis signal. + * Memory size is always m. + * + * Returns: + * void + */ +static void TDC_LPC_synthesis_fx(const Word16 sh, const Word16 a[], const Word16 x[], Word16 y[], const Word16 lg, + const Word16 m) +{ + Dyn_Mem_Deluxe_In( + Counter i; + Word16 a0; + Word16 q; + Word32(*syn_kern)(Word32 L_tmp, const Word16 a[], const Word16 y[] + );); + + ASSERT(m == 16 || m == 8); + + if (sub(m, 16) == 0) + { + syn_kern = syn_kern_16; + } + if (sub(m, 8) == 0) + { + syn_kern = syn_kern_8; + } + + q = add(norm_s(a[0]), 1); + a0 = shr_sat(a[0], sh); + + FOR (i = 0; i < lg; i++) + { + y[i] = round_fx_sat(L_shl_sat(syn_kern(L_mult(a0, x[i]), a, &y[i]), q)); move16(); + } + + Dyn_Mem_Deluxe_Out(); +} + +/* TDC_LPC_residu_fx + * + * Parameters: + * a I: LP filter coefficients (Qx) + * x I: input signal + * y O: output signal + * lg I: size of filtering + * m I: lpc order + * + * Function: + * Apply inverse filtering to obtain LP residual signal. + * + * Returns: + * void + */ +static void TDC_LPC_residu_fx(const Word16 *a, Word16 *x, Word16 *y, Word16 lg, Word16 m) +{ + Dyn_Mem_Deluxe_In( + Word16 a_exp; + Word32 s; + Counter i; + ); + + ASSERT(m == 16 || m == 8); + + a_exp = add(norm_s(a[0]), 1); + a_exp = add(a_exp, 1); + + IF (sub(m, 16) == 0) + { + FOR (i = 0; i < lg; i++) + { + s = L_mult(x[i], a[0]); + s = L_mac_sat(s, x[i - 1], a[1]); + s = L_mac_sat(s, x[i - 2], a[2]); + s = L_mac_sat(s, x[i - 3], a[3]); + s = L_mac_sat(s, x[i - 4], a[4]); + s = L_mac_sat(s, x[i - 5], a[5]); + s = L_mac_sat(s, x[i - 6], a[6]); + s = L_mac_sat(s, x[i - 7], a[7]); + s = L_mac_sat(s, x[i - 8], a[8]); + s = L_mac_sat(s, x[i - 9], a[9]); + s = L_mac_sat(s, x[i - 10], a[10]); + s = L_mac_sat(s, x[i - 11], a[11]); + s = L_mac_sat(s, x[i - 12], a[12]); + s = L_mac_sat(s, x[i - 13], a[13]); + s = L_mac_sat(s, x[i - 14], a[14]); + s = L_mac_sat(s, x[i - 15], a[15]); + s = L_mac_sat(s, x[i - 16], a[16]); + + s = L_shl_sat(s, a_exp); + y[i] = round_fx_sat(s); move16(); + } + } + IF (sub(m, 8) == 0) + { + FOR (i = 0; i < lg; i++) + { + s = L_mult(x[i], a[0]); + s = L_mac_sat(s, x[i - 1], a[1]); + s = L_mac_sat(s, x[i - 2], a[2]); + s = L_mac_sat(s, x[i - 3], a[3]); + s = L_mac_sat(s, x[i - 4], a[4]); + s = L_mac_sat(s, x[i - 5], a[5]); + s = L_mac_sat(s, x[i - 6], a[6]); + s = L_mac_sat(s, x[i - 7], a[7]); + s = L_mac_sat(s, x[i - 8], a[8]); + + s = L_shl_sat(s, a_exp); + y[i] = round_fx_sat(s); move16(); + } + } + + Dyn_Mem_Deluxe_Out(); +} + +/* TDC_random_fx + * + * Parameters: + * seed i/o: seed for random number + * lg i : vector length + * y o : output values + * + * Function: + * Uniform distributed random generator. + * + * Returns: + * random number + */ +static void TDC_random_fx(Word16 *seed, Word16 lg, Word16 *y) +{ + Dyn_Mem_Deluxe_In( + Counter i; + ); + + FOR (i = 0; i < lg; i++) + { + *seed = extract_l(L_mac0(16831L, *seed, 12821)); + *y++ = *seed; move16(); + } + + Dyn_Mem_Deluxe_Out(); +} + +/* + * TDC_preemph + * + * Parameters: + * x i/o: signal Qx + * fac i: preemphasis factor Q15 + * lg i: vector length + * + * Function: + * Filtering through 1 - fac z^-1 + * + * Returns: + * Q-factor + */ +static Word16 TDC_preemph(Word16 *x, const Word16 fac, const Word16 lg) +{ + Dyn_Mem_Deluxe_In( + Word16 fac_sh, Q_max_value, Q_out; + Word32 max_val; + Counter i; + ); + + fac_sh = shr(fac, 3); + Q_max_value = 4096; move16(); + Q_out = 12; move16(); + + max_val = 0; move32(); + FOR (i = sub(lg, 1); i >= 0; i--) + { + max_val = L_max(L_abs(L_msu(L_mult(x[i], Q_max_value), x[i - 1], fac_sh)), max_val); + } + + IF (extract_h(max_val) != 0) + { + Q_out = s_min(s_max(sub(norm_s(extract_h(max_val)), 3), 0), 12); + } + + FOR (i = sub(lg, 1); i >= 0; i--) + { + x[i] = round_fx(L_shl(L_msu(L_mult(x[i], Q_max_value), x[i - 1], fac_sh), Q_out)); move16(); + } + + Dyn_Mem_Deluxe_Out(); + + return sub(Q_out, 2); +} + +/* + * TDC_deemph_fx + * + * Parameters: + * x i: input signal Qx + * y o: output signal Qx + * fac i: deemphasis factor Q15 + * lg i: size of filtering Q0 + * mem i: memory (x[-1]) + * + * Function: + * Filtering through 1/(1-fac z^-1) + * + * Returns: + * void + */ +static void TDC_deemph_fx(const Word16 *x, Word16 *y, const Word16 fac, const Word16 lg, const Word16 mem) +{ + Dyn_Mem_Deluxe_In( + Counter i; + ); + + y[0] = round_fx_sat(L_mac_sat(L_deposit_h(x[0]), mem, fac)); move16(); + FOR (i = 1; i < lg; i++) + { + y[i] = round_fx_sat(L_mac_sat(L_deposit_h(x[i]), y[i - 1], fac)); move16(); + } + + Dyn_Mem_Deluxe_Out(); +} + +/* + * TDC_normalize_energy_fx + * + * Parameters: + * gain o: gain + * gain_exp o: exponent of gain + * x i: input signal + * lg i: length of input signal + * + * Function: + * Normalizes the energy. + * + * Returns: + * void + */ +static void TDC_normalize_energy_fx(Word16 *gain, Word16 *gain_exp, const Word16 *x, const Word16 lg) +{ + Dyn_Mem_Deluxe_In( + Counter i; + Word16 c; + Word16 e; + Word16 e1; + Word16 e2; + Word32 tmp; + Word16 tmp16; + ); + + tmp = 0; move32(); + FOR (i = 0; i < lg; i++) + { + tmp16 = mult_r(x[i], 2048); + tmp = L_mac(tmp, tmp16, tmp16); + } + + e = norm_l(tmp); + tmp = L_shl_pos(tmp, e); + e1 = sub(sub(30, e), -8); move16(); + tmp16 = BASOP_Util_Divide3216_Scale_lc3plus(tmp, lg, &e2); + + e = 0; move16(); + if (tmp16 != 0) + { + e = sub(add(e1, e2), 15); + } + + c = 0x0148; /* 0.01 */ + move16(); + IF (e > 0) + { + c = shr(c, s_min(e, 15)); + } + ELSE + { + tmp16 = shr(tmp16, s_min(negate(e), 15)); + e = 0; move16(); + } + + e2 = 2; move16(); + if (s_and(e, 1)) + { + e2 = 1; move16(); + } + + tmp16 = add(shr_pos(tmp16, e2), shr_pos(c, e2)); + e = add(e, e2); + + tmp16 = Sqrt16_lc3plus(tmp16, &e); + + *gain = BASOP_Util_Divide1616_Scale_lc3plus((Word16)0x7FFF, tmp16, &e1); move16(); + *gain_exp = sub(e1, e); move16(); + + Dyn_Mem_Deluxe_Out(); +} + +#ifdef CR10_A_ATTENUATION_CURVE_SELECTOR +static Word16 type_2_alpha_long(Word16 nbLostFramesInRow, Word16 frame_dms) +{ + Word16 n_help; + Word32 n_shift; + + if (nbLostFramesInRow <= 3*(100.0/frame_dms)){ + n_help = (nbLostFramesInRow + (100/frame_dms) - 1) * frame_dms; + return powWord16rest(31129,n_help/100,n_help%100); + } + else { + n_shift = (nbLostFramesInRow - 3*(100/frame_dms)) * 50/frame_dms; + n_help = (n_shift + (100/frame_dms) - 1) * frame_dms; + return powWord16rest(22937,n_help/100,n_help%100); + } +} + +Word16 type_2_fadeout_fx(Word16 nbLostFramesInRow, Word16 frame_dms) +{ + Word16 n_help; + Word16 selector = PLC_FADEOUT_TYPE_2_SELECTOR * 2 * (100/frame_dms); + + if (selector >= nbLostFramesInRow){ + return type_2_alpha_long(nbLostFramesInRow, frame_dms); + } + else { + n_help = (nbLostFramesInRow + (100/frame_dms) - 1) * frame_dms; + return powWord16rest(16383,n_help/100, n_help%100); + } +} + +static Word16 powWord16rest(Word16 base, Word16 exp, Word16 rest) { + Word32 exp_result = 32767; + Word32 tmp_result; + Word16 root, i, exp2; + + FOR (i = 0; i < exp; ++i) { + tmp_result = (Word32)exp_result * base; + exp_result = (Word16)(tmp_result >> 15); + } + + IF (rest != 0) { + exp2 = 0; + SWITCH (rest) + { + case 50: + root = Sqrt16_lc3plus(base, &exp2); + shr(root,exp2); + exp_result = L_shr(exp_result * root,15); /* 0.5^1.5 = 0.5^(3/2) = 0.5^3*sqrt(0.5) */ + BREAK; + case 25: + root = Sqrt16_lc3plus(base, &exp2); + shr(root,exp2); + exp2 = 0; + root = Sqrt16_lc3plus(root, &exp2); + shr(root,exp2); + exp_result = L_shr(exp_result * root,15); /* 0.5^(1/4) = 0.5^sqrt(sqrt(0.5)) */ + BREAK; + case 75: + root = Sqrt16_lc3plus(base, &exp2); + shr(root,exp2); + exp2 = 0; + root = Sqrt16_lc3plus(root, &exp2); + shr(root,exp2); + tmp_result = powWord16rest(root, 3, 0); + exp_result = L_shr( exp_result * tmp_result,15); + BREAK; + } + } + return (Word16) exp_result; +} +#endif diff --git a/lib_lc3plus/plc_tdc_pre_emphasis_fx.c b/lib_lc3plus/plc_tdc_pre_emphasis_fx.c new file mode 100644 index 0000000000000000000000000000000000000000..3a961acf7398235d16b5fc0d6b192076aee2e8ee --- /dev/null +++ b/lib_lc3plus/plc_tdc_pre_emphasis_fx.c @@ -0,0 +1,95 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.5 * +* 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 "defines.h" +#include "functions.h" + +void processPreEmphasis_fx(Word32 *d2_fx, Word16 *d2_fx_exp, Word16 fs_idx, Word16 n_bands, Word16 frame_dms, Word8 *scratchBuffer) +{ + Word16 s; + Word32 nrg; + Word16 smax; + Counter band; + const Word16 *pre_emph; + const Word16 *pre_emph_e; + Word16 * d2_band_fx_exp; + +#ifdef DYNMEM_COUNT + Dyn_Mem_In("processPreEmphasis_fx", sizeof(struct { + Word16 s; + Word32 nrg; + Word16 smax; + Counter band; + const Word16 *pre_emph; + const Word16 *pre_emph_e; + Word16 * d2_band_fx_exp; + })); +#endif + + d2_band_fx_exp = (Word16 *)scratchAlign(scratchBuffer, 0); /* Size = 2 * MAX_BANDS_NUMBER_PLC = 160 bytes */ + + pre_emph = lpc_lin_pre_emphasis[fs_idx]; + pre_emph_e = lpc_lin_pre_emphasis_e[fs_idx]; + SWITCH (frame_dms) + { + case 25: + pre_emph = lpc_lin_pre_emphasis_2_5ms[fs_idx]; + pre_emph_e = lpc_lin_pre_emphasis_e_2_5ms[fs_idx]; + BREAK; + case 50: + pre_emph = lpc_lin_pre_emphasis_5ms[fs_idx]; + pre_emph_e = lpc_lin_pre_emphasis_e_5ms[fs_idx]; + BREAK; +#ifdef CR8_G_ADD_75MS + case 75: + pre_emph = lpc_lin_pre_emphasis_7_5ms[fs_idx]; + pre_emph_e = lpc_lin_pre_emphasis_e_7_5ms[fs_idx]; + BREAK; +#endif + } + + ASSERT(n_bands==20 || n_bands==40 || n_bands==60 || n_bands ==80); + + /* start processing */ + smax = -31; move16(); + + FOR (band = 0; band < n_bands; band++) + { + nrg = Mpy_32_16_lc3plus(d2_fx[band], pre_emph[band]); + + if (nrg == 0) + { + s = 31; move16(); + } + + if (nrg != 0) + { + s = norm_l(nrg); + } + + d2_fx[band] = L_shl_pos(nrg, s); move32(); + d2_band_fx_exp[band] = sub(pre_emph_e[band], s); move16(); + + smax = s_max(smax, d2_band_fx_exp[band]); + } + +/* Rescale band energies */ + FOR (band = 0; band < n_bands; band++) + { + d2_fx[band] = L_shr_pos(d2_fx[band], s_min(sub(smax, d2_band_fx_exp[band]), 31)); move32(); + } + /* Save common exponent for all bands */ + *d2_fx_exp = add(*d2_fx_exp, smax); move16(); + +#ifdef DYNMEM_COUNT + Dyn_Mem_Out(); +#endif +} + + diff --git a/lib_lc3plus/plc_update_aft_imdct_fx.c b/lib_lc3plus/plc_update_aft_imdct_fx.c new file mode 100644 index 0000000000000000000000000000000000000000..9ba483792d2ee91590e667026c4b2372659d6ebf --- /dev/null +++ b/lib_lc3plus/plc_update_aft_imdct_fx.c @@ -0,0 +1,343 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.5 * +* 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 "defines.h" +#include "functions.h" + +static void processPLCcomputeStabFac(Word16 scf_q[], Word16 old_scf_q[], Word16 prev_bfi, Word16 *stab_fac); + +void processPLCUpdateAfterIMDCT_fx(Word16 x_fx[], Word16 q_fx_exp, Word16 concealMethod, Word16 xLen, Word16 fs_idx, + Word16 *nbLostFramesInRow, Word16 *prev_prev_bfi, Word16 *prev_bfi, Word16 bfi, Word16 scf_q[], + Word16 *ns_cum_alpha, AplcSetup *plcAd) +{ + Word16 oldLen, usedHistlen; + Word16 scale_fac_old, scale_fac_new, q_theo_new_old, q_theo_new_new, q_new, shift_old, shift_new; + Word16 frontLen, pastLen; + Word16 marginOldPast; + Word16 marginNewXlen, marginOldFront; + +#ifdef DYNMEM_COUNT + Dyn_Mem_In("processPLCUpdateAfterIMDCT_fx", sizeof(struct { + Word16 oldLen, usedHistlen; + Counter i; + Word16 scale_fac_old, scale_fac_new, q_theo_new_old, q_theo_new_new, q_new, shift_old, shift_new; + Word16 frontLen, pastLen; + Word16 marginOldPast; + Word16 scale_fac_old_dual; + Word16 marginNewXlen, marginOldFront; + })); +#endif + + + + +#ifdef WMOPS + push_wmops("processPLCUpdateAfterIMDCT "); +#endif + + + if (plcAd) + { + /* for short NB frames(2.5 ms) TDC-filtering requires more PCM samples than the plc_xcorr function */ + usedHistlen = plcAd->max_len_pcm_plc; + + + logic16(); + IF( (sub(bfi,1) == 0) && sub(concealMethod, LC3_CON_TEC_PHASE_ECU) == 0 && xLen == (Word16)(((double)LprotSzPtr[fs_idx])*0.625)) + { /* % reduced buffering update length during concealment method 2 as Xsav_fx is stored in the joint q_old_fx and pcmbufHist buffer */ + usedHistlen = sub(usedHistlen, sub(LprotSzPtr[fs_idx], s_min(MAX_BW_BIN, xLen))); + ASSERT(xLen == (Word16)(((double)LprotSzPtr[fs_idx])*0.625)); /*/ only enter here for 10 ms cases */ + + /* actually one can select to always update xLen(10 ms) less samples of x_old_tot, also in TDC-PLC bfi frames ,, and for PhECU.PLC */ + } + oldLen = sub(usedHistlen, xLen); + + /* update ltpf-free pcm history buffer for TD-PLC */ + + basop_memmove(&plcAd->x_old_tot_fx[plcAd->max_len_pcm_plc - usedHistlen], + &plcAd->x_old_tot_fx[plcAd->max_len_pcm_plc - usedHistlen + xLen], oldLen * sizeof(Word16)); + + basop_memcpy(&plcAd->x_old_tot_fx[plcAd->max_len_pcm_plc - xLen], &x_fx[0], xLen * sizeof(Word16)); + +#ifdef ENABLE_HR_MODE + frontLen = 0; + IF (sub(fs_idx, 5) < 0) +#endif + { + frontLen = sub(LprotSzPtr[fs_idx], xLen); /*16-10 = 6ms of the prev_synth/xfp part */ + } + pastLen = sub(oldLen, frontLen); /* ~11.8 ms*/ + + marginOldPast = getScaleFactor16_0(&(plcAd->x_old_tot_fx[plcAd->max_len_pcm_plc - usedHistlen]), pastLen); + marginOldFront = getScaleFactor16_0(&(plcAd->x_old_tot_fx[plcAd->max_len_pcm_plc - usedHistlen + pastLen]), frontLen); + + scale_fac_old = s_min(marginOldFront, marginOldPast); + + frontLen = 0; move16(); + logic16(); logic16(); + IF(bfi == 1 && *prev_bfi == 0 && sub(concealMethod, LC3_CON_TEC_PHASE_ECU) == 0) + { /* prepare localized margin_xfp value for a next bad concealment Method 2 frame */ + frontLen = *nbLostFramesInRow; + frontLen = add(hamm_len2Tab[fs_idx], shr(hamm_len2Tab[fs_idx], 2)); /* find margin in the 3.75 ms front part */ + pastLen = sub(xLen, frontLen); + scale_fac_new = getScaleFactor16_0(&(x_fx[0]), pastLen); + marginNewXlen = getScaleFactor16_0(&(x_fx[0]) + pastLen, frontLen); /* for pHEcuprev_synth in 2nd+ bfi frame */ + + scale_fac_new = s_min(scale_fac_new, marginNewXlen); + } + ELSE + { /* prepare margin value for any coming good frame or any coming first bad frame */ + + marginNewXlen = getScaleFactor16_0(&(x_fx[0]),xLen); /* prevsynth in first bfi frame */ + scale_fac_new = marginNewXlen; move16(); + } + + q_theo_new_old = s_max(plcAd->q_fx_old_exp - scale_fac_old, 0); + q_theo_new_new = s_max(q_fx_exp - scale_fac_new, 0); + + q_new = s_max(q_theo_new_old, q_theo_new_new); + + shift_old = plcAd->q_fx_old_exp - q_new; + shift_new = q_fx_exp - q_new; + + IF(shift_old != 0) + { + Scale_sig(&plcAd->x_old_tot_fx[plcAd->max_len_pcm_plc - usedHistlen], oldLen, shift_old); + logic16(); + test(); + IF ((sub(bfi,1) == 0) && (sub(concealMethod, LC3_CON_TEC_TDPLC) == 0)) + { + plcAd->harmonicBuf_Q -= shift_old; + plcAd->tdc_gain_c = L_shl_sat(plcAd->tdc_gain_c, shift_old); + } + move16(); /* count move to static RAM */ + + marginOldFront = s_min(16, sub(marginOldFront, shift_old)); + } + IF(shift_new) + { + Scale_sig(&plcAd->x_old_tot_fx[plcAd->max_len_pcm_plc - xLen], xLen, shift_new); /* positive shift_new means upshift=less margin */ + marginNewXlen = s_min(16, sub(marginNewXlen, shift_new)); + } + + plcAd->q_fx_old_exp = sub(q_fx_exp, shift_new); + + plcAd->PhECU_margin_xfp = s_min(marginNewXlen, marginOldFront); move16(); /* for pHECU winEncalc xfp energy calculations */ + if (frontLen != 0) + { /* prepare margin value for a first pHECU(16 ms) or a consecutive bad PhEcu frame (3.75ms) */ + plcAd->PhECU_margin_xfp = marginNewXlen; move16(); + } + if (sub(plcAd->PhECU_margin_xfp, 16) == 0) + { + plcAd->PhECU_margin_xfp = 1; move16(); /* "1" --> does not rescale the all-zero vector, inside PhECU */ + } + } + + /* Update PLC params */ + IF(sub(bfi, 1) != 0) + { + /* % reset counters in GF */ + *nbLostFramesInRow = 0; move16(); + *ns_cum_alpha = 32767; move16(); + + if (plcAd) + { + basop_memmove(plcAd->old_old_scf_q, plcAd->old_scf_q, M * sizeof(Word16)); + basop_memmove(plcAd->old_scf_q, scf_q, M * sizeof(Word16)); + + /* PLC fullband transient detector setting for non-bfi frames */ + plcAd->PhECU_short_flag_prev = 0; move16(); /* fullband transient not active */ + } + } + + /* values may be {0,1,2} */ + *prev_prev_bfi = *prev_bfi; move16(); + *prev_bfi = bfi; move16(); + +#ifdef WMOPS + pop_wmops(); +#endif + +#ifdef DYNMEM_COUNT + Dyn_Mem_Out(); +#endif +} + +void processPLCcomputeStabFac_main(Word16 scf_q[], Word16 old_scf_q[], Word16 old_old_scf_q[], Word16 bfi, Word16 prev_bfi, + Word16 prev_prev_bfi, Word16 *stab_fac) +{ + IF (sub(bfi, 1) == 0) + { + IF (sub(prev_bfi, 1) != 0) + { + processPLCcomputeStabFac(old_scf_q, old_old_scf_q, prev_prev_bfi, stab_fac); + } + } + ELSE IF(sub(bfi, 2) == 0) + { + processPLCcomputeStabFac(scf_q, old_scf_q, prev_bfi, stab_fac); + } +} + +static void processPLCcomputeStabFac(Word16 scf_q[], Word16 old_scf_q[], Word16 prev_bfi, Word16 *stab_fac) +{ + Counter i; + Word32 tmp32; + Word16 d; + +#ifdef DYNMEM_COUNT + Dyn_Mem_In("calculateStabFac", sizeof(struct { + Counter i; + Word32 tmp32; + Word16 d; + })); +#endif + + /* calculate stability factor */ + IF (sub(prev_bfi, 1) == 0) + { + *stab_fac = 26214; move16(); + } + ELSE + { + tmp32 = 0; move32(); + FOR (i = 0; i < M; i++) + { + d = sub(scf_q[i], old_scf_q[i]); + tmp32 = L_mac_sat(tmp32, d, d); + } + tmp32 = L_shl_sat(tmp32, 3); + IF (tmp32 > 0x7D000000 /*1.25*25*/) + { + *stab_fac = 0; move16(); + } + ELSE IF (tmp32 < 0x19003E82 /*0.25*25*/) + { + *stab_fac = 0x7FFF; move16(); + } + ELSE + { + tmp32 = L_shl_pos(L_sub(0x50000000 /*1.25/2*/, Mpy_32_16_lc3plus(tmp32, 0x51EC /*16/25*/)), 1); + *stab_fac = round_fx(tmp32); move16(); + } + } + +#ifdef DYNMEM_COUNT + Dyn_Mem_Out(); +#endif +} + +void processPLCUpdateXFP_w_E_hist_fx(Word16 prev_bfi, Word16 bfi, Word16 *xfp_fx, Word16 xfp_exp_fx, Word16 margin_xfp, + Word16 fs_idx, + Word32 *L_oold_xfp_w_E_fx, Word16 *oold_xfp_w_E_exp_fx, + Word32 *L_old_xfp_w_E_fx, Word16 *old_xfp_w_E_exp_fx, + + Word16 *oold_Ltot_exp_fx ,Word16 *old_Ltot_exp_fx ) + +{ + Word32 L_tot ; + Word16 dn_scale, exp_shift; + Word16 used_xfp_exp_fx; + Word16 exp_out ; + +#ifdef DYNMEM_COUNT + Dyn_Mem_In("PLCUpdateXFP_w_E_hist", sizeof(struct { + Word32 L_tot; + Word16 dn_scale, exp_shift; + Word16 used_xfp_exp_fx; + Word16 exp_out; + })); +#endif +#ifdef WMOPS + push_wmops("PhECU::UpdateXfp_w_E_hist_fx"); +#endif + + IF (sub(bfi,1) != 0) + { + + if (sub(prev_bfi,1) == 0) + { + /* only a single historic frame available in the next frame + , force artifical update of oold energy to be the same as old */ + *old_xfp_w_E_exp_fx = LTOT_INIT_FLAG ; move16(); + } + + /* Time shift energy state and xfp exp */ + IF (sub_sat(*old_xfp_w_E_exp_fx, LTOT_INIT_FLAG ) == 0) + { + *L_oold_xfp_w_E_fx = LTOT_MIN_MAN ; move32(); + *oold_xfp_w_E_exp_fx = UNINIT_OR_UNSAFE_OOLD_SENTINEL ; move16(); + } + ELSE + { + *L_oold_xfp_w_E_fx = *L_old_xfp_w_E_fx; move32(); /* regular update */ + *oold_xfp_w_E_exp_fx = *old_xfp_w_E_exp_fx; move16(); + } + + /* Time shift L_tot energy state and L_tot_exp */ + IF (sub_sat(*old_Ltot_exp_fx, LTOT_INIT_FLAG ) == 0) + { + *L_oold_xfp_w_E_fx = LTOT_MIN_MAN ; move32(); + *oold_Ltot_exp_fx = UNINIT_OR_UNSAFE_OOLD_SENTINEL ; move16(); + } + ELSE + { + *L_oold_xfp_w_E_fx = *L_old_xfp_w_E_fx; move32(); /* regular update */ + *oold_Ltot_exp_fx = *old_Ltot_exp_fx; move16(); + } + + + dn_scale = e_tot_headroom[fs_idx]; /* allowed minimum dn_scale for a max upshifted signal */ + used_xfp_exp_fx = xfp_exp_fx; + + IF( margin_xfp > 0 ) /* xfp_fx was normalized on a larger area than 16ms part of pcmBuffer */ + { + ASSERT(bfi !=1) ; /* if bfi was set the margin_xfp does not reflect the correct 16ms part of pcm_buf hist, prev_synth */ + dn_scale = s_max(0, sub(e_tot_headroom[fs_idx], margin_xfp)); + + exp_shift = sub(e_tot_headroom[fs_idx], dn_scale); + used_xfp_exp_fx = sub(xfp_exp_fx, exp_shift); /* the virtual change of the xfp_buffer due to reduced downscaling in L_tot calc */ + } + + /* use semifixed dn_scale as adjusted by margin_xfp in 16 ms region */ + exp_out = xfp_exp_fx; move16(); + L_tot = winEnCalc(xfp_fx, dn_scale , PhECU_wins[fs_idx][0], rectLengthTab[fs_idx], hamm_len2Tab[fs_idx], &exp_out ); + + *L_old_xfp_w_E_fx = L_tot; move32(); + + *old_xfp_w_E_exp_fx = used_xfp_exp_fx ; move16(); + /* this now needs to be in Q1 , used_fx_exp , (exp_out-1-2*e_tot_headroom[fs_idx])/2 */ + + *old_Ltot_exp_fx = exp_out; /* new proper _Ltot value from winEnCalc function */ + + + /* use true Word32 exponent of L_tot */ + + + /* restart oold and old from same state for init or prevBFI cases */ + logic16(); + IF (sub_sat(*oold_xfp_w_E_exp_fx, UNINIT_OR_UNSAFE_OOLD_SENTINEL) <= 0 || /* old xfp_Exp */ + sub_sat(*oold_Ltot_exp_fx, UNINIT_OR_UNSAFE_OOLD_SENTINEL) <= 0 ) /* new L_tot_exp */ + { + *L_oold_xfp_w_E_fx = L_tot; move32(); + *oold_xfp_w_E_exp_fx = used_xfp_exp_fx; move16(); + *oold_Ltot_exp_fx = *old_Ltot_exp_fx; /* use Ltot exp value */ + } + } + +#ifdef WMOPS + pop_wmops(); +#endif +#ifdef DYNMEM_COUNT + Dyn_Mem_Out(); +#endif +} + + + diff --git a/lib_lc3plus/plc_update_fx.c b/lib_lc3plus/plc_update_fx.c new file mode 100644 index 0000000000000000000000000000000000000000..7abb2b613ddfaa91068503689c12395bb0d840dd --- /dev/null +++ b/lib_lc3plus/plc_update_fx.c @@ -0,0 +1,224 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.5 * +* 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 "defines.h" +#include "functions.h" + +void processPLCupdate_fx(AplcSetup *plcAd, Word16 x_fx[], Word16 q_fx_exp, Word16 concealMethod, Word16 frame_length, + Word16 fs_idx, Word16 *nbLostFramesInRow, Word16 *prev_prev_bfi, Word16 *prev_bfi, Word16 bfi, Word16 scf_q[], + Word16 *ns_cum_alpha +#ifdef ENABLE_HR_MODE + , Word16 hrmode +#endif + ) +{ + processPLCUpdateAfterIMDCT_fx(x_fx, q_fx_exp, concealMethod, frame_length, fs_idx, nbLostFramesInRow, prev_prev_bfi, prev_bfi, bfi, + scf_q, ns_cum_alpha, plcAd); /* NB *prev_bfi updated here */ + + IF ( plcAd != 0 ) + { + /* reuse/inplace the most recent 16 ms of x_old_tot without additional rescaling, keep exponent aligned with tdc pitch buffer to save WMOPS */ + + +#ifdef ENABLE_HR_MODE + if (hrmode == 0) +#endif + { + ASSERT( (&plcAd->x_old_tot_fx[plcAd->max_len_pcm_plc - LprotSzPtr[fs_idx] ]) == plcAd->PhECU_xfp_fx ); + plcAd->PhECU_xfp_exp_fx = plcAd->q_fx_old_exp; move16(); /* exponent used by concealmethod 2 in prevBfi frames and also right after non bfi frames */ + } + } +} + +void processPLCupdateSpec_fx(Word16 q_old_d_fx[], Word16 *q_old_fx_exp, Word32 q_d_fx[], Word16 *q_fx_exp, Word16 yLen) +{ + Dyn_Mem_Deluxe_In( + Counter i; + Word16 s; + ); + + /* save spectrum and the corresponding exponent */ + s = getScaleFactor32_lc3plus(q_d_fx, yLen); + + *q_old_fx_exp = sub(*q_fx_exp, s); + + + FOR (i = 0; i < yLen; i++) + { + q_old_d_fx[i] = round_fx_sat(L_shl_sat(q_d_fx[i], s)); /* */ + } + + Dyn_Mem_Deluxe_Out(); +} + +void processPLCspec2shape_fx(Word16 prev_bfi, Word16 bfi, Word16 q_old_d_fx[], Word16 yLen, + Word16 *stPhECU_oold_grp_shape_fx, Word16 *stPhECU_old_grp_shape_fx) + +#define L_GRP_DC 4 + +{ + Counter i,l; + Word16 *pX, tmp; + Word16 N_grp,l_grp; + Word16 man, expo; + Word32 L_acc; + Word32 L_tot; + Word32 L_grp_shape[MAX_LGW]; + Word16 grp_shape[MAX_LGW]; /**/ + Word16 fs_idx,local_prev_bfi; + + +#ifdef DYNMEM_COUNT + Dyn_Mem_In("process_plc_spec_2_shape_fx", sizeof(struct { + Counter i,l; + Word16 *pX; + Word16 N_grp,l_grp; + Word32 L_acc; + Word32 L_tot; + Word32 L_grp_shape[MAX_LGW]; + Word16 fs_idx,local_prev_bfi; + })); +#endif +#ifdef WMOPS + push_wmops("PhECU::GF::process_plc_spec_2_shape_fx"); +#endif + + IF(sub(bfi, 1) != 0) + { + fs_idx = mult(yLen, (Word16)(32768.0 / (99.0))); /* truncation needed , i.e no rounding can be applied here */ + N_grp = xavg_N_grp_fx[fs_idx]; move16(); + + local_prev_bfi = prev_bfi; move16(); + if (sub(local_prev_bfi, 2)==0) + { + local_prev_bfi = 0; move16(); + } + + if( stPhECU_oold_grp_shape_fx[0] < 0 ) + { + local_prev_bfi = 1 ; move16(); /* handle startup in the case 2nd frame is a BFI frame */ + } + + /* Copy old to oold grp shape */ + FOR( i=0; i < MAX_LGW ; i++) + { + stPhECU_oold_grp_shape_fx[i] = stPhECU_old_grp_shape_fx[i]; move16(); + } + + + /* Accumulate DC bin(s) to total */ + pX = q_old_d_fx; /* ptr setup */ + L_tot = L_deposit_h(0); /* acc on negative side */ + + FOR( i= 0; i < L_GRP_DC; i++) + { + tmp = shr_pos(*pX++ ,spec_shape_headroom[fs_idx]); /* scale down upscaled MDCT to create some headroom */ + L_tot = L_msu0(L_tot, tmp, tmp); + + } + + /* Accumulate middle subbands and add to total */ + FOR( i=0; i < sub(N_grp,1) ; i++) + { + + L_acc = L_deposit_h(0); /* acc on negative side */ + l_grp = sub(mdct_grp_bins_fx[i+1], mdct_grp_bins_fx[i]); move16(); + + + + FOR(l=0;l 0) + { + FOR(i=0; i < N_grp ; i++) + { + man = plc_phEcu_ratio_fx(L_grp_shape[i], L_tot, &expo); /* The mantissa is considered in Q15 output in Q14 */ + grp_shape[i] = shr_sat(man, sub(expo,1)); /* gfrom Q14 to in Q15 (Due to saturation, it is automatically bound inside [-1.0,1.0].) */ + } + } + ELSE + { + FOR(i=0; i < N_grp ; i++) + { + grp_shape[i] = GRP_SHAPE_INIT; move16(); + + } + } + + /* copy to output */ + FOR(i=0; i < N_grp ; i++) + { + stPhECU_old_grp_shape_fx[i] = grp_shape[i]; move16(); + } + FOR(i = N_grp; i < MAX_LGW ; i++) + { + stPhECU_old_grp_shape_fx[i] = GRP_SHAPE_INIT; move16(); + } + + + + /* handle oold states for the frame sequence BAD, GOOD, NEXT_BAD */ + if(sub(local_prev_bfi, 1)==0) + { + FOR( i=0; i < MAX_LGW ; i++) + { + stPhECU_oold_grp_shape_fx[i] = stPhECU_old_grp_shape_fx[i] ; move16(); + } + } + + } + +#ifdef WMOPS + pop_wmops(); +#endif +#ifdef DYNMEM_COUNT + Dyn_Mem_Out(); +#endif + +} + + + + diff --git a/lib_lc3plus/plc_xcorr_fx.c b/lib_lc3plus/plc_xcorr_fx.c new file mode 100644 index 0000000000000000000000000000000000000000..d8c6d83904ef6955eee8d584709578625a4c8186 --- /dev/null +++ b/lib_lc3plus/plc_xcorr_fx.c @@ -0,0 +1,250 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.5 * +* 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 "defines.h" +#include "functions.h" + +#define MAX_ACCS 3 /* sum(x.*y), sum(x.*x), sum(y.*y), nb of always nonsaturated shorter sub_blocks*/ +#define MAX_BLOCKS 8 +#define MAX_ACC_LEN_BITS 7 +#define MIN_ACC_LEN_BITS 5 +#define MAX_ACC_LEN (1 << MAX_ACC_LEN_BITS) +#define MIN_PITCH_8K 20 /* 8000* MIN_PITCH_12k8/12800 */ + +static const Word16 pitch_min_2[] = {2 * MIN_PITCH_8K , 2 * MIN_PITCH_8K * 2, 2 * MIN_PITCH_8K * 3, + 2 * MIN_PITCH_8K * 4, 2 * MIN_PITCH_8K * 6, 2 * MIN_PITCH_8K * 12}; + +/* req headroom in bits, for safe summing of block results w/o downshift */ +/* also the safe pre subblock acc downshift for various number of blocks */ +static const Word16 tab_req_headroom[MAX_BLOCKS + 1] = {0, 0, 1, 2, 2, 3, 3, 3, 3}; +/*(0, 1, 2, 3,4, 5,6,7,8)*/ + +static Word16 plc_norm_corr_blocks_fx(Word16 tot_len, Word16 l2_base_len, Word16 n_blocks, Word16 inshift, + Word16 *currFrame, Word16 *predFrame); + +Word16 plc_norm_corr_blocks_fx( /* o: norm_corr range [-1 ... 1.0[ in Q15 */ + Word16 tot_len, /* i: total correlation length in Q0 */ + Word16 l2_base_len, /* i: size of subblocks in log2 */ + Word16 n_blocks, /* i: number of accumulator sub_blocks */ + Word16 inshift, /* i: required inshift of curr/pred Q0 */ + Word16 *currFrame, /* i: ptr to most recent section */ + Word16 *predFrame) /* i: ptr to historic section */ +{ + Word16 scale0, scale1, scale2, scale_min, shift, prod_exp, acc_margin; + Word32 L_prod, L_inv, L_tmp0 = 0, L_tmp1 = 0, L_tmp2 = 0; + Word16 norm_corr, curr, pred; + Counter m, b; + Word32 L_ce[MAX_ACCS][MAX_BLOCKS]; + +#ifdef DYNMEM_COUNT + Dyn_Mem_In("plc_norm_corr_blocks_fx", sizeof(struct { + Word16 scale0, scale1, scale2, scale_min, shift, prod_exp, acc_margin; + Word32 L_prod, L_inv, L_tmp0, L_tmp1, L_tmp2; + Word16 norm_corr, curr, pred; + Counter m, b; + Word32 L_ce[MAX_ACCS][MAX_BLOCKS]; + })); +#endif + +#ifdef WMOPS + push_wmops("plc_norm_corr_blocks_fx"); +#endif + + /* Calculate normalized correlation with added shift and block interleaving possibility */ + ASSERT(n_blocks <= MAX_BLOCKS && n_blocks > 0); + ASSERT(((float)tot_len / (float)n_blocks) <= (float)(1 << l2_base_len)); + ASSERT(inshift > 0); + UNUSED(l2_base_len); + + FOR (b = 0; b < n_blocks; b++) + { /* block loop with fixed pre_down shifting(inshift) of input signal */ + curr = shr_pos(currFrame[b], inshift); + pred = shr_pos(predFrame[b], inshift); + L_tmp2 = L_deposit_l(0); + L_tmp0 = L_msu0(L_tmp2, curr, pred); /* acc L_tmp0 on negative side to avoid saturation for (-1*-1) */ + L_tmp1 = L_msu0(L_tmp2, pred, pred); /* acc_energy on negative side */ + L_tmp2 = L_msu0(L_tmp2, curr, curr); /* acc_energy on negative side */ + + FOR (m = (b + n_blocks); m < tot_len; m += n_blocks) + { /* interleaved accumulation over total length */ + curr = shr_pos(currFrame[m], inshift); + pred = shr_pos(predFrame[m], inshift); + L_tmp0 = L_msu0(L_tmp0, curr, pred); + L_tmp1 = L_msu0(L_tmp1, pred, pred); + L_tmp2 = L_msu0(L_tmp2, curr, curr); + } + + L_ce[0][b] = L_add(L_tmp0, 0); /* account for moves from register to stack memory */ + L_ce[1][b] = L_add(L_tmp1, 0); + L_ce[2][b] = L_add(L_tmp2, 0); + } + + /* aggregate interleaved subsections */ + IF (sub(n_blocks, 1) >= 0) + { /* 100% safe non saturating L_ce with a safe acc_margin */ + acc_margin = tab_req_headroom[n_blocks]; move16(); + + L_tmp0 = L_shr_pos(L_ce[0][0], acc_margin); + L_tmp1 = L_shr_pos(L_ce[1][0], acc_margin); + L_tmp2 = L_shr_pos(L_ce[2][0], acc_margin); + + FOR (b = 1; b < n_blocks; b++) + { + L_tmp0 = L_add(L_tmp0, L_shr_pos(L_ce[0][b], acc_margin)); /* add negative values */ + L_tmp1 = L_add(L_tmp1, L_shr_pos(L_ce[1][b], acc_margin)); /* add negative values */ + L_tmp2 = L_add(L_tmp2, L_shr_pos(L_ce[2][b], acc_margin)); /* add negative values */ + } + + /* evaluate headroom margin in coarse representation */ + scale0 = norm_l(L_tmp0); + scale1 = norm_l(L_tmp1); + scale2 = norm_l(L_tmp2); + + scale_min = s_min(scale0, scale1); + scale_min = s_min(scale_min, scale2); + + shift = sub(scale_min, acc_margin); + IF (shift >= 0) + { /* re-accumulate blocks with highest possible precision */ + L_tmp0 = L_add(L_ce[0][0], 0); /* add negative values */ + L_tmp1 = L_add(L_ce[1][0], 0); /* add negative values */ + L_tmp2 = L_add(L_ce[2][0], 0); /* add negative values */ + + FOR (b = 1; b < n_blocks; b++) + { + L_tmp0 = L_add(L_tmp0, L_ce[0][b]); /* add negative values */ + L_tmp1 = L_add(L_tmp1, L_ce[1][b]); /* add negative values */ + L_tmp2 = L_add(L_tmp2, L_ce[2][b]); /* add negative values */ + } + } + } + + /* quota: norm_corr = corr/sqrt(en1*en2) = negate(L_tmp1)/sqrt(-L_tmp1*-L_tmp2) */ + L_tmp1 = L_min(L_tmp1, -1); /* make sure there is negative energy */ + L_tmp2 = L_min(L_tmp2, -1); /* make sure there is negative energy */ + + ASSERT(L_tmp1 < 0 && L_tmp2 < 0); + + /* negate correlation, due to the used safe msu0 accumulation, with a saturation pre-check ctrl */ + L_tmp0 = L_max(L_tmp0, (MIN_32 + 1)); + L_tmp0 = L_negate(L_tmp0); + + scale0 = norm_l(L_tmp0); + scale1 = norm_l(L_tmp1); + scale2 = norm_l(L_tmp2); + + L_tmp1 = L_shl_pos(L_tmp1, scale1); + L_tmp2 = L_shl_pos(L_tmp2, scale2); + L_prod = Mpy_32_32_lc3plus(L_tmp1, L_tmp2); /* neg * neg -> positive */ + shift = norm_l(L_prod); + L_prod = L_shl_pos(L_prod, shift); + prod_exp = sub(62, add(add(scale1, scale2), shift)); + L_inv = Isqrt_lc3plus(L_prod, &prod_exp); + + L_tmp0 = L_shl_pos(L_tmp0, scale0); + L_prod = Mpy_32_32_lc3plus(L_tmp0, L_inv); + prod_exp = add(sub(31, scale0), prod_exp); + + norm_corr = 32767; move16(); /* as close to 1.0 as possible in Q15 */ + if (L_tmp0 < 0) + { + norm_corr = -32768; move16(); /*-1.0*/ + } + + test(); + IF (L_prod == 0 || sub(norm_l(L_prod), prod_exp) >= 0) + { + norm_corr = round_fx_sat(L_shl_sat(L_prod, prod_exp)); + } + +#ifdef DYNMEM_COUNT + Dyn_Mem_Out(); +#endif +#ifdef WMOPS + pop_wmops(); +#endif + return norm_corr; +} + +Word16 plc_xcorr_lc_fx( /* o: quantized output xcorr in Q15 [ 0 ..32767 ] = [0. 1.0[ */ + Word16 *pcmbuf_fx, /* i: NB should be an already dynamically upscaled pcm buffer with about + 0...1(2) bits margin */ + Word16 max_len_pcm_plc, /* i: Q0 physical size of pcmbuf_fx */ + Word16 pitch_int, /* i: Q0 in Fs, lag value to evaluate, corresponding to the current f0 in + pcm_buf_Fx */ + Word16 fs_idx /*i: */) +{ + Word16 *range1Ptr; + Word16 *range2Ptr; + Word16 corr_len_fx, inshift, l2_base_len, n_blocks, norm_xcorr_est_q, pcm_max_corr_len, max_corr_len; + +#ifdef DYNMEM_COUNT + Dyn_Mem_In("plc_xcorr_lc_fx", sizeof(struct { + Word16 *range1Ptr; + Word16 *range2Ptr; + Word16 corr_len_fx, inshift, l2_base_len, n_blocks, norm_xcorr_est_q, pcm_max_corr_len, max_corr_len; + })); +#endif + +#ifdef WMOPS + push_wmops("plc_xcorr_lc_fx"); +#endif + + norm_xcorr_est_q = 0; move16(); + + IF (pitch_int > 0) + { + pcm_max_corr_len = sub(max_len_pcm_plc, pitch_int); + + max_corr_len = rectLengthTab[fs_idx]; /* maximum 10 ms */ + max_corr_len = s_min(max_corr_len, pcm_max_corr_len); + + corr_len_fx = s_min(max_corr_len, pitch_int); + corr_len_fx = s_max(corr_len_fx, pitch_min_2[fs_idx]); /* at least 5 ms (=2*pitchmin*) corr length */ + + ASSERT(corr_len_fx >= (pitch_min_2[fs_idx])); /* at least 2 x pitch min(fs) */ + ASSERT(corr_len_fx <= (MAX_ACC_LEN * MAX_BLOCKS)); + ASSERT(corr_len_fx <= max_corr_len); + ASSERT( max_len_pcm_plc - corr_len_fx - pitch_int + 1 > 0 ); + + range1Ptr = &(pcmbuf_fx[max_len_pcm_plc]) - corr_len_fx; /* ptr setup, start of head section */ + range2Ptr = range1Ptr - pitch_int; /* ptr setup, history = tail - lag distance */ + + /* assume 32 bit acc of up to 32 values -> sum(over 32, x_up>>2 * y_up>>2) */ + inshift = 2; move16(); + l2_base_len = MIN_ACC_LEN_BITS; move16(); + n_blocks = shr(add(corr_len_fx, (1 << MIN_ACC_LEN_BITS) - 1), MIN_ACC_LEN_BITS); + + IF (sub(n_blocks, MAX_BLOCKS) > 0) + { /* shift to 32 bit acc of up to 128 values -> sum(over 128, x_up>>3 * y_up>>3) */ + inshift = 3; move16(); + l2_base_len = MAX_ACC_LEN_BITS; move16(); + n_blocks = shr(add(corr_len_fx, ((1 << MAX_ACC_LEN_BITS) - 1)), MAX_ACC_LEN_BITS); + } + + ASSERT(n_blocks <= MAX_BLOCKS); /* MAX_BLOCKS*(32 or 128) is max possible total corr_length */ + ASSERT(n_blocks > 0); + + /* subblock accumulation of corr and energies, to achieve high low level precision */ + norm_xcorr_est_q = + plc_norm_corr_blocks_fx(corr_len_fx, l2_base_len, n_blocks, inshift, range1Ptr, /* curr_frame */ + range2Ptr); /* pred_frame = curr_frame-lag, i.e historic section */ + + norm_xcorr_est_q = s_max(0, norm_xcorr_est_q); /* do not allow negative output values */ + } +#ifdef DYNMEM_COUNT + Dyn_Mem_Out(); +#endif +#ifdef WMOPS + pop_wmops(); +#endif + return norm_xcorr_est_q; +} + + diff --git a/lib_lc3plus/pvq_dec_fx.c b/lib_lc3plus/pvq_dec_fx.c new file mode 100644 index 0000000000000000000000000000000000000000..d77aae80964e4db1d7296152cdfe33165ed7880b --- /dev/null +++ b/lib_lc3plus/pvq_dec_fx.c @@ -0,0 +1,153 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.5 * +* 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 "functions.h" + +Word16 pvq_dec_deidx_fx( /* out BER detected 1 , ok==0 */ + Word16 * y, /* o: decoded vector (non-scaled int) */ + const Word16 k_val, /* i: number of allocated pulses */ + const Word16 dim, /* i: Length of vector */ + const Word16 LS_ind, /* i; lS index 1 bit */ + const UWord32 UL_MPVQ_ind /* i; MPVQ index */ +) +{ + Dyn_Mem_Deluxe_In( + Word16 BER_flag; + UWord32 h_mem[1 + KMAX_FX + 1]; + PvqEntry_fx entry; + ); + + BER_flag = 0; move16(); + + /* get_size will likely be called before this function, as the range decoder needs the size to fetch the index + */ + entry = get_size_mpvq_calc_offset_fx(dim, k_val, h_mem); /* TBD should be made into tables for N=16,10,6 */ + + entry.lead_sign_ind = LS_ind; move16(); + entry.index = L_deposit_l(0); /* only in case dim == 1 */ + IF (sub(dim, 1) != 0) + { + entry.index = UL_MPVQ_ind; + + /* safety check in case of bit errors */ + IF (L_sub(entry.index, entry.size) >= 0) + { + BER_flag = 1; move16(); + entry.index = 0; move16(); /* return something deterministic/valid, and LOW complex */ + } + } + mpvq_deindex_fx(&entry, h_mem, y); /* actual deindexing */ + + Dyn_Mem_Deluxe_Out(); + return BER_flag; +} + + + +#ifdef ENABLE_HR_MODE +void pvq_dec_scale_vec_fx(const Word32 *inQ29, Word16 adjGainQ13, Word32 *outQ) +#else +void pvq_dec_scale_vec_fx(const Word16 *inQ14, Word16 adjGainQ13, Word16 *outQ14) +#endif +{ + Dyn_Mem_Deluxe_In( + Counter i; + ); + FOR (i = 0; i < M; i++) + { +#ifdef ENABLE_HR_MODE + outQ[i] = L_shr(L_add(outQ[i], Mpy_32_16_lc3plus(inQ29[i], adjGainQ13)), 1); + move16(); +#else + outQ14[i] = add(outQ14[i], mult_r(adjGainQ13, inQ14[i])); move16(); +#endif + } + Dyn_Mem_Deluxe_Out(); +} + + +void pvq_dec_en1_normQ14_fx(/* Have to be used EXACTLY the same way in both both encoder and decoder */ +#ifdef ENABLE_HR_MODE + Word32 * xq, /* o: en1 normalized decoded vector (Q14) */ +#else + Word16 * xq, /* o: en1 normalized decoded vector (Q14) */ +#endif + const Word16 *y, /* i: decoded vector (non-scaled int) */ + const Word16 k_val_max, + /* i: max possible K in Q0 kO or kA */ /* OPT: not BE , use dynamic max pulse + amplitude */ + const Word16 dim /* i: Length of vector */ +) +{ +#ifdef ENABLE_HR_MODE + Dyn_Mem_Deluxe_In( + Counter i; + Word32 L_tmp; + Word16 shift_num, shift_tot; + Word32 isqrtQ31_local; + Word16 tmp, exp, exp_shift; + Word32 L_yy; + ); +#else + Dyn_Mem_Deluxe_In( + Counter i; + Word32 L_tmp; + Word16 shift_num, shift_tot; + Word16 isqrtQ16_local, tmp, exp, exp_shift; + Word32 L_yy; + ); +#endif + +/* energy normalization starts here */ + L_yy = L_mult0(y[0], y[0]); + FOR (i = 1; i < dim; i++) + { + L_yy = L_mac0(L_yy, y[i], y[i]); /* stay in Q0 */ /* OPT: reuse some energies from PVQ linear search */ + } + /* 16 bit */ + IF (L_sub(L_yy, SQRT_EN_MAX_FX) < 0) + { + ASSERT(L_yy > 4); /* Q16 isqrt table lookup not valid below 5 */ +#ifdef ENABLE_HR_MODE + isqrtQ31_local = isqrt_Q31tab[L_yy]; move16(); /* 1 cycle */ +#else + isqrtQ16_local = isqrt_Q16tab[L_yy]; move16(); /* 1 cycle */ +#endif + } + ELSE + { + /* about 8-9 cycles */ + exp = 15; move16(); /* set ISqrt16() exp_in to get delta exp out near 0 when Lyy is in Q0 */ + tmp = ISqrt16(extract_l(L_yy), + &exp); /* exp out is now a delta shift with a later tmp Q15 multiplication in mind */ +#ifdef ENABLE_HR_MODE + exp_shift = add(exp, 16); /* up to Q16 */ + isqrtQ31_local = L_shl(L_deposit_l(tmp), exp_shift); /* new mantissa in a fixed Q16 */ +#else + exp_shift = add(exp, 16 - 15); /* up to Q16 */ + isqrtQ16_local = shl(tmp, exp_shift); /* new mantissa in a fixed Q16 */ +#endif + } + + shift_num = norm_s(k_val_max); /* simply account for the preknown fixed max possible pulseamp in y */ + shift_tot = sub(14 - 1, shift_num); /* upshift to get to Q14 */ + FOR (i = 0; i < dim; i++) /* upshifted y[i] used */ + { +#ifdef ENABLE_HR_MODE + L_tmp = Mpy_32_16_lc3plus(isqrtQ31_local, shl_pos(y[i], shift_num)); /* Q(16+0+shift_num +1 = shift_num+1 */ + xq[i] = L_shl(L_tmp, shift_tot + 1); move32(); /* Q30 , */ +#else + L_tmp = L_mult(isqrtQ16_local, shl_pos(y[i], shift_num)); /* Q(16+0+shift_num +1 = shift_num+1 */ + xq[i] = round_fx(L_shl(L_tmp, shift_tot)); move16(); /* Q14 , */ +#endif + } + + Dyn_Mem_Deluxe_Out(); +} + diff --git a/lib_lc3plus/pvq_enc_fx.c b/lib_lc3plus/pvq_enc_fx.c new file mode 100644 index 0000000000000000000000000000000000000000..b41d5ad0e50bcdb35dd1d739260452de07efed07 --- /dev/null +++ b/lib_lc3plus/pvq_enc_fx.c @@ -0,0 +1,369 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.5 * +* 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 "functions.h" + +static void pvq_pyr_project(const Word16 dim_proj, /* end vector dimension+1 */ + const Word16 *xabs, /* absolute vector values */ + Word32 L_xsum, /* absolute vector sum over dim */ + Word16 num, /* target number of pulses */ + Word16 * y, /* projected output vector */ + Word16 *pulse_tot_ptr, Word32 *L_xy_ptr, /* accumulated correlation Q(in+0+1) = Qin+1 */ + Word32 *L_yy_ptr /* accumulated energy Q0 */ +) +{ + + Dyn_Mem_Deluxe_In( + Counter i; + Word32 L_tmp, L_num; + Word16 den, shift_num, shift_den, shift_delta, proj_fac; + ); + + *pulse_tot_ptr = 0; move16(); + *L_xy_ptr = L_deposit_l(0); + *L_yy_ptr = L_deposit_l(0); + + shift_den = norm_l(L_xsum); /* x_sum input Qin */ + den = extract_h(L_shl_pos(L_xsum, shift_den)); /* now in Qin+shift_den */ + + L_num = L_deposit_l(num); + shift_num = sub(norm_l(L_num), 1); + L_num = L_shl_pos(L_num, shift_num); /* now in Q0 +shift_num -1 */ + proj_fac = div_l(L_num, den); /* L_num always has to be less than den<<16 , norm_l-1 makes that happen */ + + shift_delta = sub(shift_num, shift_den); + FOR (i = 0; i < dim_proj; i++) + { + L_tmp = L_mult(proj_fac, xabs[i]); /* Q shift_delta + PVQ_SEARCH_QIN */ + y[i] = extract_h(L_shr(L_tmp, shift_delta)); move16(); /* to Q0 with floor , and potential sturation */ + ; + + *pulse_tot_ptr = add(*pulse_tot_ptr, y[i]); /* Q0 */ + *L_yy_ptr = L_mac0(*L_yy_ptr, y[i], y[i]); /* Energy, Q0 */ + *L_xy_ptr = L_mac(*L_xy_ptr, xabs[i], y[i]); /* Corr, Q0*Q12 +1 --> Q13 */ + } + + Dyn_Mem_Deluxe_Out(); +} + + +static __forceinline Word16 one_pulse_search(const Word16 dim_start, /* start vector dimension */ + const Word16 dim_end, /* end vector dimension+1 */ + const Word16 *x_abs, /* absolute vector values */ + Word16 * y, /* output vector */ + Word16 * pulse_tot_ptr, + Word32 * L_xy_ptr, /* accumulated correlation Q(12+0+1) = Q13 */ + Word32 * L_yy_ptr, /* accumulated energy Q0 */ + Word16 max_xabs) /* current max amplitude for target */ +{ + Dyn_Mem_Deluxe_In( + Counter i; + Word16 corr_tmp, corr_sq_tmp, en_max_den, cmax_num, en_tmp; + Word32 L_tmp_en_lc, L_tmp_corr; + Word16 corr_up_shift, imax; + ); + + /* maximize correlation precision, prior to every unit pulse addition in the vector */ + corr_up_shift = norm_l(L_mac(*L_xy_ptr, 1, max_xabs)); /* pre analyze worst case L_xy update in the dim loop */ + imax = -1; /* not needed for search, only added to avoid compiler warning */ + { + en_max_den = 0; move16(); + cmax_num = -1; move16(); /* req. to force a 1st update for n==dim_start */ + + FOR (i = dim_start; i < dim_end; i++) + { + L_tmp_corr = L_shl_pos(L_mac(*L_xy_ptr, 1, x_abs[i]), corr_up_shift); /* actual in-loop target value */ + + corr_tmp = round_fx_sat(L_tmp_corr); + + corr_sq_tmp = mult(corr_tmp, corr_tmp); /* CorrSq_tmp for a 16bit low complexity cross multiplication */ + + L_tmp_en_lc = L_mac(*L_yy_ptr, 1, y[i]); /*Q0 x^2+ 2x , "+1" added once before loop , result , energy may + span up to ~14+1(Q1)+1(sign)=16 bits */ + /* extract_l without shift can always be used for this section as energy is guaranteed to stay in the lower + * word*/ + + en_tmp = extract_l(L_tmp_en_lc); /* L_shl + round_fx could also be used also but then adds an uphift cost */ + + /* 16/32 bit comparison WC (4 +1+1 + (1+1+1) = 9 */ + IF (L_msu(L_mult(corr_sq_tmp, en_max_den), cmax_num, en_tmp) > 0) /* use L_mult and then a L_msu */ + { + cmax_num = corr_sq_tmp; move16(); + en_max_den = en_tmp; move16(); + imax = i; move16(); + } + } /* dim */ + } + + + /* finally add found unit pulse contribution to past L_xy, Lyy, for next pulse loop */ + *L_xy_ptr = L_mac(*L_xy_ptr, x_abs[imax], 1); /* Qin+1 */ + *L_yy_ptr = L_mac(*L_yy_ptr, 1, y[imax]); + + y[imax] = add(y[imax], 1); move16(); /* Q0 added pulse */ + (*pulse_tot_ptr) = add((*pulse_tot_ptr), 1); /* increment total pulse sum */ + Dyn_Mem_Deluxe_Out(); + return imax; +} + + +void pvq_enc_search_fx( + const Word16 *x, /* i: target vector to quantize Qin */ + Word16 * y_far, /* o: outl_far o, raw pulses (non-scaled short) Q0 , length dim */ + Word16 * y, /* o: outl_near o, raw pulses (non-scaled short) Q0 , length dim */ + Word16 * yA, /* o: A section raw pulses (non-scaled short) Q0 , length dimA */ + Word16 * yB, /* o: B section raw pulses (non-scaled short) Q0 , length dim-dimA */ + Word32 * L_corr, /* o: 4 un-normalized correlation sums for outl_far, outl_near, A, AB */ + Word32 * L_search_en, /* o: 4 energy sums for outl_far, outl_near, A, AB */ + Word16 * pulses_fin, /* i: number of allocated pulses to outl_far, outl_near , A, AB sections */ + Word16 * pulses_proj, /* i: number of projection pulses for outl_far, outl_near, A, AB */ + + const Word16 dim, /* i: Length of outlier vector */ + const Word16 dimA /* i: Length of vector A section */ +) +{ + + Dyn_Mem_Deluxe_In( + Counter i; + Word16 pulse_tot_far, pulse_tot, pulse_totA, pulse_totB; + Word16 xabs[PVQ_MAX_VEC_SIZE]; + Word16 max_xabs, max_xabsA, max_xabsB; + Word32 L_xsum, L_xsumA; + Word32 L_yy, L_xy; + Word16 imax; + Counter k; + Word16 dim_m1; + Word16 dimB; + const Word16 *xBptr; + Word16 pulses_far, pulses, pulsesA, pulsesB; + ); + +#ifdef WMOPS + push_wmops("pvq_enc_search_fx"); +#endif + + pulses_far = pulses_fin[0]; move16(); + pulses = pulses_fin[1]; move16(); + pulsesA = pulses_fin[2]; move16(); + pulsesB = pulses_fin[3]; move16(); + + FOR (i = 0; i < N_SCF_SHAPES_ST2; i++) + { + L_corr[i] = L_deposit_l(0); + L_search_en[i] = L_deposit_l(0); + } + + dimB = sub(dim, dimA); + + L_xsum = L_deposit_h(0); + + max_xabs = -1; move16(); + max_xabsA = -1; move16(); + max_xabsB = -1; move16(); + FOR (i = 0; i < dimA; i++) + { + xabs[i] = abs_s(x[i]); move16(); /* Qx */ + max_xabsA = s_max(max_xabsA, xabs[i]); /* for efficient search correlation scaling */ + L_xsum = L_mac0(L_xsum, 1, xabs[i]); /* stay in Qx */ + } + + basop_memset(y_far, 0, dim * sizeof(Word16)); + basop_memset(y, 0, dimA * sizeof(Word16)); + basop_memset(yA, 0, dimA * sizeof(Word16)); + + L_xsumA = L_add(L_xsum, 0); /* save for section A projection */ + + FOR (i = dimA; i < dim; i++) + { + xabs[i] = abs_s(x[i]); move16(); /* Qx */ + max_xabsB = s_max(max_xabsB, xabs[i]); /* for efficient search correlation scaling */ + L_xsum = L_mac0(L_xsum, 1, xabs[i]); /* stay in Qx */ + } + + basop_memset(&y[dimA], 0, (dim - dimA) * sizeof(Word16)); + + basop_memset(yB, 0, dimB * sizeof(Word16)); + + max_xabs = s_max(max_xabsA, max_xabsB); /* global max abs value */ + + test(); + IF (L_xsum == 0) + { /* no shape in any section, projection in outl_far, outl_near, A, AB not possible, any search meaningless */ + + dim_m1 = sub(dim, 1); + y_far[0] = shr_pos(pulses_far, 1); move16(); + y_far[dim_m1] = add(y_far[dim_m1], sub(pulses_far, y_far[0])); move16(); + + dim_m1 = sub(dim, 1); + y[0] = shr_pos(pulses, 1); move16(); + y[dim_m1] = add(y[dim_m1], sub(pulses, y[0])); move16(); + + dim_m1 = sub(dimA, 1); + yA[0] = shr_pos(pulsesA, 1); move16(); + yA[dim_m1] = add(yA[dim_m1], sub(pulsesA, yA[0])); move16(); + + dim_m1 = sub(dimB, 1); + yB[0] = shr_pos(pulsesB, 1); move16(); + yB[dim_m1] = add(yB[dim_m1], sub(pulsesB, yB[0])); move16(); + } + ELSE + { + ASSERT(pulses_proj[0] > 0); + ASSERT(L_xsum > 0); + + pvq_pyr_project(dim, xabs, L_xsum, pulses_proj[0], y_far, &pulse_tot_far, &L_xy, + &L_yy); /* outlier submode projection */ + + ASSERT(pulses_far <= 127); + FOR (k = pulse_tot_far; k < pulses_far; k++) + { + L_yy = L_add(L_yy, 1); /* pre add 1 in Q0 in L_yyQ0 = (x^2 + 2*x + 1) */ + imax = one_pulse_search(0, dim, xabs, y_far, &pulse_tot_far, &L_xy, &L_yy, max_xabs); + } + ASSERT(pulse_tot_far == pulses_far); + /* outlier far submode result vector in y_far[0...15] */ + L_corr[0] = L_shr_pos(L_xy, 1); /* to Qin*Q0 */ + + basop_memmove(y, y_far, dim * sizeof(Word16)); /*y_far->y */ + + pulse_tot = pulse_tot_far; move16(); + + ASSERT(pulses <= 127); + FOR (k = pulse_tot; k < pulses; k++) + { + L_yy = L_add(L_yy, 1); /* pre add 1 in Q0 in L_yyQ0 = (x^2 + 2*x + 1) */ + imax = one_pulse_search(0, dim, xabs, y, &pulse_tot, &L_xy, &L_yy, max_xabs); + } + + /* outlier near submode result vector in y[0...15] */ + L_corr[1] = L_shr_pos(L_xy, 1); /* to Qin*Q0 */ + + ASSERT(pulse_tot == pulses); + + IF (L_xsumA == 0) + { + /* no shape in A section, projection in A not possible, search meaningless */ + dim_m1 = sub(dimA, 1); + yA[0] = shr_pos(pulsesA, 1); move16(); + yA[dim_m1] = add(yA[dim_m1], sub(pulsesA, yA[0])); move16(); + } + ELSE + { + IF (pulses_proj[2] != 0) /* fixed setup if bitrate is fixed */ + { + ASSERT(pulses_proj[2] > 0); + ASSERT(L_xsumA > 0); + pvq_pyr_project(dimA, xabs, L_xsumA, pulses_proj[2], yA, &pulse_totA, &L_xy, + &L_yy); /* section A , in submode 1 projection */ + } + ELSE + { + /* default, otherwise recalculate A from outlier result (to remove any section B pulses influence) + */ + pulse_totA = 0; move16(); + L_xy = L_deposit_l(0); + L_yy = L_deposit_l(0); + + basop_memmove(yA, y, dimA * sizeof(Word16)); + FOR (i = 0; i < dimA; i++) + { + pulse_totA = add(pulse_totA, yA[i]); /* Q0 */ + L_xy = L_mac(L_xy, xabs[i], yA[i]); /* Corr, Q0*Q12 +1 --> Q13 */ + L_yy = L_mac(L_yy, yA[i], yA[i]); /* Energy, Q(0+0)+1)= Q1 */ + } + L_yy = L_shr_pos(L_yy, 1); /* En to Q0 */ + } + + /* search remaining pulses in regular section A */ + FOR (k = pulse_totA; k < pulsesA; k++) + { + L_yy = L_add(L_yy, 1); /* 1 added in Q0 */ + imax = one_pulse_search(0, dimA, xabs, yA, &pulse_totA, &L_xy, &L_yy, max_xabsA); + } + ASSERT(pulse_totA == pulsesA); + } /* L_xsumA!=0 */ + + /* reg Set A result vector now in yA[0...9] */ + L_corr[2] = L_shr_pos(L_xy, 1); /* to Qin*Q0 */ + + /* search remaining pulses in regular section B, even if energy in B is zero */ + ASSERT(pulses_proj[3] == 0); + pulse_totB = 0; move16(); + + IF (sub(pulsesB, 1) == 0) + { /* LC search, sufficient to find a single max, as pulses can not be stacked, when nb-pulses==1 */ + imax = 0; move16(); /* safety */ + FOR (i = dimA; i < dim; i++) + { + if (xabs[i] == max_xabsB) + { + imax = sub(i, dimA); + } + } + pulse_totB = 1; move16(); + yB[imax] = 1; move16(); /* reg set B result vector in yB[0...5] */ + L_xy = L_mac(L_xy, xabs[add(imax, dimA)], 1); /* calc total corr for A+B sections */ + L_yy = L_add(L_yy, 1); + } + ELSE + { /* more than one target pulse in section B */ + /* keep A pulses influence, search section B pulses influence */ + FOR (k = pulse_totB; k < pulsesB; k++) + { + L_yy = L_add(L_yy, 1); /* 1 added in Q0*/ + imax = one_pulse_search(dimA, dim, xabs, &(yB[-dimA]), &pulse_totB, &L_xy, &L_yy, max_xabsB); + } + } + + L_corr[3] = L_shr_pos(L_xy, 1); move32(); /* to Qin*Q0 , corr of combined A and B */ + + ASSERT(pulse_totB == pulsesB); + /* reg set B result vector now in yB[0...5] */ + } /* L_xsum != 0 */ + +/* apply sign of (x) to first orthant result */ + FOR (i = 0; i < dim; i++) + { + if (x[i] < 0) + { + y_far[i] = negate(y_far[i]); /* apply sign for outlier far */ + } + } + + FOR (i = 0; i < dim; i++) + { + if (x[i] < 0) + { + y[i] = negate(y[i]); /* apply sign for outliers near */ + } + } + + xBptr = &(x[dimA]); move32(); /* ptr init to B target section */ + FOR (i = 0; i < dimA; i++) + { + if (x[i] < 0) + { + yA[i] = negate(yA[i]); /* apply sign in N_SETA */ + } + } + + FOR (i = 0; i < (dimB); i++) + { + if (xBptr[i] < 0) + { + yB[i] = negate(yB[i]); /* apply sign in N_SETB */ + } + } + + Dyn_Mem_Deluxe_Out(); +#ifdef WMOPS + pop_wmops(); +#endif +} + diff --git a/lib_lc3plus/pvq_index_fx.c b/lib_lc3plus/pvq_index_fx.c new file mode 100644 index 0000000000000000000000000000000000000000..966dd7d138538d320d139ada03d6ae8b41aef721 --- /dev/null +++ b/lib_lc3plus/pvq_index_fx.c @@ -0,0 +1,513 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.5 * +* 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 "functions.h" + +#define SIGNBIT_FX 0x80000000u +#define SIGNBIT_SHRT_FX 0x8000 + +static void initOffsets_fx(Word16 dim_in, UWord32 *h_mem, + Word16 k_val_in) /* may be removed with tables for N=16,10,6 */ +{ + UWord32 k_val_prev, k_val_curr; + UWord32 k_val, UL_k_val_in; +#ifdef DYNMEM_COUNT + Dyn_Mem_In("initOffsets_fx", sizeof(struct { + UWord32 k_val_prev, k_val_curr; + UWord32 k_val, UL_k_val_in; + })); +#endif + + h_mem[0] = UL_deposit_l(0); + h_mem[1] = UL_deposit_l(1); + + UL_k_val_in = UL_deposit_l(k_val_in); + IF (sub(dim_in, 2) == 0) + { + FOR (k_val = 2; k_val <= UL_k_val_in; k_val++) + { + h_mem[k_val] = UL_subNsD(UL_lshl(k_val, 1), 1U); move32(); + } + h_mem[k_val] = UL_k_val_in; move32(); + } + ELSE + { + k_val_prev = UL_deposit_l(1U); + FOR (k_val_curr = 2; k_val_curr <= UL_k_val_in; k_val_curr++) + { + h_mem[k_val_curr] = UL_addNsD(1U, UL_Mpy_32_32(k_val_curr, UL_lshl(k_val_prev, 1))); move32(); + k_val_prev = UL_addNsD(k_val_curr, 0U); + } + h_mem[k_val_curr] = UL_Mpy_32_32(k_val_curr, k_val_prev); move32(); + } + +#ifdef DYNMEM_COUNT + Dyn_Mem_Out(); +#endif +} + +static void a_fwd_fx(UWord32 *a_in, /* i/o: offsets */ + Word16 n_items /* i : items, k's */ +) +{ + UWord32 a_1, a_in0; + Counter i; + UWord32 *a_in_prev_ptr; + +#ifdef DYNMEM_COUNT + Dyn_Mem_In("a_fwd_fx", sizeof(struct { + UWord32 a_1, a_in0; + Counter i; + UWord32 *a_in_prev_ptr; + })); +#endif + + a_in0 = UL_deposit_l(1); + + a_in_prev_ptr = &(a_in[-1]); + FOR (i = 1; i <= n_items; i++) + { + a_1 = UL_addNsD(a_in0, UL_addNsD(a_in_prev_ptr[i], a_in[i])); + a_in_prev_ptr[i] = a_in0; move32(); + a_in0 = UL_addNsD(a_1, 0U); + } + a_in_prev_ptr[i] = a_in0; move32(); + +#ifdef DYNMEM_COUNT + Dyn_Mem_Out(); +#endif +} + +static void a_bwd_fx(UWord32 *a_in, /* i/o: offsets */ + Word16 n_items /* i: n_items */ +) +{ + UWord32 a_1, a_in0; + Counter i; + UWord32 *a_in_prev_ptr; + +#ifdef DYNMEM_COUNT + Dyn_Mem_In("a_bwd_fx", sizeof(struct { + UWord32 a_1, a_in0; + Counter i; + UWord32 *a_in_prev_ptr; + })); +#endif + + a_in0 = UL_deposit_l(0); + a_in_prev_ptr = &(a_in[-1]); + + FOR (i = 1; i <= n_items; i++) + { + a_1 = UL_subNsD(UL_subNsD(a_in[i], a_in0), a_in_prev_ptr[i]); + a_in_prev_ptr[i] = a_in0; move32(); + a_in0 = UL_addNsD(a_1, 0U); + } + a_in_prev_ptr[i] = a_in0; move32(); + +#ifdef DYNMEM_COUNT + Dyn_Mem_Out(); +#endif +} + +static void a_u_fwd_fx(UWord32 *a_u_in, Word16 k_val_in, Word16 mem_size_m1) +{ + UWord32 u_kp1_prev, u_kp1; + UWord32 u_k_prev; + +#ifdef DYNMEM_COUNT + Dyn_Mem_In("a_u_fwd_fx", sizeof(struct { + UWord32 u_kp1_prev, u_kp1; + UWord32 u_k_prev; + })); +#endif + + u_kp1_prev = a_u_in[mem_size_m1]; move32(); + u_k_prev = UL_lshr(a_u_in[k_val_in], 1); + + a_fwd_fx(&a_u_in[1], k_val_in); + + u_kp1 = UL_lshr(a_u_in[k_val_in], 1); + a_u_in[mem_size_m1] = UL_addNsD(1U, UL_addNsD(u_kp1_prev, UL_addNsD(u_k_prev, u_kp1))); + +#ifdef DYNMEM_COUNT + Dyn_Mem_Out(); +#endif +} + +static Word16 get_lead_sign_fx(UWord32 *ind) +{ + Word16 leading_sign; + +#ifdef DYNMEM_COUNT + Dyn_Mem_In("get_lead_sign_fx", sizeof(struct { Word16 leading_sign; })); +#endif + + leading_sign = 1; move16(); + if (UL_and(*ind, 1) != 0) + { + leading_sign = -1; move16(); + } + (*ind) = UL_lshr(*ind, 1); + +#ifdef DYNMEM_COUNT + Dyn_Mem_Out(); +#endif + + return leading_sign; +} + +/*-------------------------------------------------------------------* + * mind2vec_one_fx() + *-------------------------------------------------------------------*/ +static void mind2vec_one_fx(Word16 k_val_in, /* i: nb unit pulses , [ 0...K_MAX ] */ + Word16 leading_sign, /* i: leading sign -1, 0, 1*/ + UWord32 ind, /* i: index */ /* parameter could be omitted */ + Word16 *vec_out /* o: pulse train */ +) +{ + *vec_out = (Word16)ind; /* dummy assignment to handle the common ind parameter warning */ + + if (leading_sign < 0) + { + k_val_in = negate(k_val_in); + } + *vec_out = k_val_in; move16(); +} + +static Word16 setval_update_sign_fx(Word16 k_delta, Word16 k_max_local, Word16 *leading_sign, UWord32 *ind_in, + Word16 *vec_out) +{ + IF (k_delta != 0) + { + mind2vec_one_fx(k_delta, *leading_sign, *ind_in, vec_out); + *leading_sign = get_lead_sign_fx(ind_in); + k_max_local = sub(k_max_local, k_delta); + } + return k_max_local; +} + +/*-------------------------------------------------------------------* + * mind2vec_fx() + *-------------------------------------------------------------------*/ +static void mind2vec_fx(Word16 dim_in, /* i: dimension */ + Word16 k_max_local, /* i: nb unit pulses */ + Word16 leading_sign, /* i: leading sign */ + UWord32 ind, /* i: index */ + Word16 * vec_out, /* o: pulse train */ + UWord32 *h_in /* i: offset vector A=1+2U */ +) +{ + Counter pos; + Word16 k_acc, k_delta; + UWord32 UL_tmp_offset, UL_diff; + UWord16 sgn; + +#ifdef DYNMEM_COUNT + Dyn_Mem_In("mind2vec_fx", sizeof(struct { + Counter pos; + Word16 k_acc, k_delta; + UWord32 UL_tmp_offset, UL_diff; + UWord16 sgn; + })); +#endif + + k_acc = k_max_local; move16(); + FOR (pos = 0; pos < dim_in; pos++) + { + + IF (ind != 0) + { + + k_acc = k_max_local; move16(); + + UL_tmp_offset = UL_addNsD(h_in[k_acc], 0U); + + UL_diff = UL_subNs(ind, UL_tmp_offset, &sgn); + + WHILE (sgn) + { + UL_diff = UL_subNs(ind, h_in[--k_acc], &sgn); + } + + ind = UL_addNsD(UL_diff, 0U); + + k_delta = sub(k_max_local, k_acc); + } + ELSE + { + mind2vec_one_fx(k_max_local, leading_sign, ind, &vec_out[pos]); + BREAK; + } + + k_max_local = setval_update_sign_fx(k_delta, k_max_local, &leading_sign, &ind, &vec_out[pos]); + + a_bwd_fx(h_in, add(k_max_local, 1)); + } + +#ifdef DYNMEM_COUNT + Dyn_Mem_Out(); +#endif +} + +PvqEntry_fx get_size_mpvq_calc_offset_fx( /* o : size, dim, k_val */ + Word16 dim_in, /* i : dimension */ + Word16 k_val_in, /* i : nb unit pulses */ + UWord32 *h_mem /* o : offsets */ +) +{ + Counter i; + PvqEntry_fx entry; + Word16 kp1; + +#ifdef DYNMEM_COUNT + Dyn_Mem_In("get_size_mpvq_calc_offset_fx", sizeof(struct { + Counter i; + PvqEntry_fx entry; + Word16 kp1; + })); +#endif + + entry.dim = dim_in; move16(); + entry.k_val = k_val_in; move16(); + + entry.index = L_deposit_l(0); + entry.lead_sign_ind = 0; move16(); + + ASSERT(dim_in <= M); + ASSERT(tabledKMAX[dim_in] != 0); + + /* tabled values for worst case K */ /* made into table lookup for N=16, 10, 6 */ + kp1 = add(k_val_in, 1); + FOR (i = 0; i <= kp1; i++) /* A+U copying */ + { + h_mem[i] = + UL_addNsD(MPVQ_offs_ptr[dim_in][i], 0U); /* a vector copying is needed as MPVQ recursion is in place */ + } + /* special handling of last U offset in k+1 column */ + if (sub(k_val_in, tabledKMAX[dim_in]) != 0) + { + h_mem[kp1] = UL_lshr(h_mem[kp1], 1); /* (A+1)/2 , convert from A(K+1) to U(K+1) domain */ + } + entry.size = + UL_addNsD(1U, UL_addNsD(h_mem[kp1], UL_lshr(h_mem[k_val_in], 1))); /* MPVQ size calc. 1 + H(K+1) + (A(K)>>1) */ + +#ifdef DYNMEM_COUNT + Dyn_Mem_Out(); +#endif + + return entry; +} + +/*-------------------------------------------------------------------* + * mpvq_deindex_fx() + *-------------------------------------------------------------------*/ +void mpvq_deindex_fx( /* o : void */ + const PvqEntry_fx *entry, /* i : sign_ind, index, dim, k_val */ + UWord32 * h_mem, /* i : A/U offsets */ + Word16 * vec_out /* o : pulse train */ +) +{ + Word16 leading_sign; +#ifdef DYNMEM_COUNT + Dyn_Mem_In("mpvq_deindex_fx", sizeof(struct { Word16 leading_sign; })); +#endif +#ifdef WMOPS + push_wmops("mpvq_deindex_fx"); +#endif + + basop_memset(vec_out, 0, (entry->dim) * sizeof(Word16)); + + leading_sign = 1; move16(); + if (entry->lead_sign_ind != 0) + { + leading_sign = -1; move16(); + } + + IF (entry->k_val != 0) + { + mind2vec_fx(entry->dim, entry->k_val, leading_sign, entry->index, vec_out, h_mem); + } +#ifdef DYNMEM_COUNT + Dyn_Mem_Out(); +#endif +#ifdef WMOPS + pop_wmops(); +#endif +} + +/*-------------------------------------------------------------------* + * vec2mind_two_fx() + *-------------------------------------------------------------------*/ +static void vec2mind_two_fx(const Word16 *vec_in, /* i : PVQ pulse train */ + Word16 * k_val_out_ptr, /* o : number of unit pulses */ + UWord32 * next_sign_ind, /* i/o: next sign ind */ + UWord32 * ind /* o: MPVQ index */ +) +{ + UWord32 lead_sign_ind_add; + Word16 abs0, abs1, abs01, sptr; + +#ifdef DYNMEM_COUNT + Dyn_Mem_In("vec2mind_two_fx", sizeof(struct { + UWord32 lead_sign_ind_add; + Word16 abs0, abs1, abs01, sptr; + })); +#endif + + abs0 = abs_s(vec_in[0]); + abs1 = abs_s(vec_in[1]); + abs01 = add(abs0, abs1); + *k_val_out_ptr = abs01; move16(); + *ind = UL_deposit_l(0); + + *next_sign_ind = UL_deposit_h(SIGNBIT_SHRT_FX); + + IF (abs01 != 0) + { + sptr = 0; move16(); + *next_sign_ind = UL_deposit_l(sptr); + + test(); + IF (abs0 != 0 && abs1 != 0) + { + lead_sign_ind_add = UL_deposit_l(1); + if (vec_in[1] < 0) + { + lead_sign_ind_add = UL_deposit_l(2); + } + *ind = UL_addNsD(UL_deposit_l((UWord16)lshl(sub(abs1, 1), 1)), lead_sign_ind_add); + } + ELSE + { + IF (abs0 == 0) + { + *ind = UL_deposit_l((UWord16)sub(lshl(abs1, 1), 1)); + sptr = 1; move16(); + } + } + + if (vec_in[sptr] < 0) + { + *next_sign_ind = UL_deposit_l(1); + } + } + +#ifdef DYNMEM_COUNT + Dyn_Mem_Out(); +#endif +} + +static void enc_push_sign(Word16 val, UWord32 *next_sign_ind, UWord32 *index) +{ + test(); + IF ((UL_and(*next_sign_ind, SIGNBIT_FX) == 0) && (val != 0)) + { + *index = UL_addNsD(UL_lshl(*index, 1), *next_sign_ind); + } + if (val < 0) + { + *next_sign_ind = UL_deposit_l(1); + } + if (val > 0) + { + *next_sign_ind = UL_deposit_l(0); + } +} + +static void vec2mind_fx(Word16 dim_in, /* i : dim */ + Word16 k_val_in, /* i : number of unit pulses */ + const Word16 *vec_in, /* i : PVQ pulse train */ + UWord32 * next_sign_ind, /* o : pushed leading sign */ + UWord32 * index, /* o : MPVQ index */ + UWord32 * N_MPVQ_ptr, /* o : size(N_MPVQ(dim,K_val_in))*/ + UWord32 * h_mem) /* o : offsets */ +{ + Counter pos; + Word16 mem_size_m1, k_val_acc, tmp_val; + UWord32 tmp_h; + +#ifdef DYNMEM_COUNT + Dyn_Mem_In("vec2mind_fx", sizeof(struct { + Counter pos; + Word16 mem_size_m1, k_val_acc, tmp_val; + UWord32 tmp_h; + })); +#endif + + mem_size_m1 = add(k_val_in, 1); + *next_sign_ind = UL_deposit_h(SIGNBIT_SHRT_FX); + + pos = sub(dim_in, 2); + vec2mind_two_fx(&vec_in[pos], &k_val_acc, next_sign_ind, index); + initOffsets_fx(3, h_mem, k_val_in); + + tmp_h = h_mem[k_val_acc]; move32(); + FOR (pos--; pos >= 0; pos--) + { + tmp_val = vec_in[pos]; move16(); + enc_push_sign(tmp_val, next_sign_ind, index); + + *index = UL_addNsD(*index, tmp_h); + + k_val_acc = add(k_val_acc, abs_s(tmp_val)); + + IF (pos != 0) + { + a_u_fwd_fx(h_mem, k_val_in, mem_size_m1); + } + tmp_h = UL_addNsD(h_mem[k_val_acc], 0U); + } + *N_MPVQ_ptr = UL_addNsD(1U, UL_addNsD(UL_lshr(tmp_h, 1), h_mem[mem_size_m1])); move32(); + +#ifdef DYNMEM_COUNT + Dyn_Mem_Out(); +#endif +} + +PvqEntry_fx mpvq_index_fx( /* o : leading_sign_index, index, size, k_val */ + const Word16 *vec_in, /* i : signed pulse train */ + Word16 dim_in, /* i : dimension */ + Word16 k_val_local /* i : nb unit pulses */ +) +{ + PvqEntry_fx result; + UWord32 h_mem[1 + KMAX_FX + 1]; + UWord32 lead_sign_ind; + +#ifdef DYNMEM_COUNT + Dyn_Mem_In("mpvq_index_fx", sizeof(struct { + PvqEntry_fx result; + UWord32 h_mem[1 + KMAX_FX + 1]; + UWord32 lead_sign_ind; + })); +#endif +#ifdef WMOPS + push_wmops("mpvq_index_fx"); +#endif + + ASSERT(k_val_local <= KMAX_FX); + + result.k_val = k_val_local; move16(); + result.dim = dim_in; move16(); + + vec2mind_fx(dim_in, k_val_local, vec_in, &lead_sign_ind, &result.index, &result.size, h_mem); + + result.lead_sign_ind = u_extract_l(lead_sign_ind); + +#ifdef DYNMEM_COUNT + Dyn_Mem_Out(); +#endif +#ifdef WMOPS + pop_wmops(); +#endif + + return result; +} + diff --git a/lib_lc3plus/quantize_spec_fx.c b/lib_lc3plus/quantize_spec_fx.c new file mode 100644 index 0000000000000000000000000000000000000000..4667cf14639a9694b3c0e96fba394a7a97f804ff --- /dev/null +++ b/lib_lc3plus/quantize_spec_fx.c @@ -0,0 +1,1167 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.5 * +* 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 "functions.h" + +# ifdef ENABLE_HR_MODE +void processQuantizeSpec_fx(Word32 x[], Word16 x_e, Word32 gain, Word16 gain_e, Word32 xq[], Word16 nt, Word16 target, + Word16 totalBits, Word16 *nBits, Word16 *nBits2, Word16 fs_idx, Word16 *lastnzout, + Word16 *codingdata, Word16 *lsbMode, Word16 mode, Word16 hrmode) +{ + + Word32 a1, b1, a1_i, b1_i; + Word16 t, lev1; + Word16 lastnz, lastnz2; + Word16 rateFlag; + Word32 nbits32, nbits232, target32; + Word16 nt_half; + Word32 c, ab_max, msb, a1_msb, b1_msb; + Word16 levmax; + Word16 s; + Word16 totBits, nbits_lsb; + Counter k, lev; + Word16 maxlevs; +# ifndef FUNCTION_quantizeSpec_func1 + Word16 tmp16; + Word32 offs32; + Counter i; +# else + Word32 ARM_params[3]; +# endif + +# ifdef DYNMEM_COUNT + Dyn_Mem_In("processQuantizeSpec_fx", sizeof(struct { + Word32 a1, b1, a1_i, b1_i, ab_max, c; + Word16 t, lev1; + Word16 lastnz, lastnz2; + Word16 rateFlag; + Word32 nbits32, nbits232; + Word16 nt_half; + Word16 msb, a1_msb, b1_msb, levmax; + Counter k, lev, i; + Word16 s; + Word16 tmp16; + Word32 offs32, target32; + Word16 totBits, nbits_lsb; + Word16 maxlevs; + })); +# endif + + assert(target >= 0); + + /* Quantization */ + gain = invFixp(gain, &gain_e); + + maxlevs = 21; + IF (hrmode) + { + s = sub(add(x_e, gain_e), 23); + s = s_min(s, 31); +# ifdef FUNCTION_quantizeSpec_func1 + ARM_params[0] = gain; + ARM_params[1] = s; + + quantizeSpec_func1_hr_ip(xq, x, nt, ARM_params); +# else + IF(s > 4) + { + s = sub(s, 4); /* Use extra bits of precision for fine calculation */ + FOR(i = 0; i < nt; i++) + { + offs32 = Mpy_32_32_lc3plus(L_shl_pos(x[i], s), gain); /* multiply */ + xq[i] = L_shr_r_pos(offs32, 4); /* Convert to Q0 with rounding */ + /* rounding is the equivalent of adding 0.5, which is the offset in hrmode */ + + move32(); + } + } + ELSE + { + FOR(i = 0; i < nt; i++) + { + offs32 = Mpy_32_32_lc3plus(x[i], gain); /* multiply */ + offs32 = L_shl(offs32, s); /* convert to 23Q8 */ + xq[i] = L_shr_r_pos(offs32, 8); /* Convert to Q0 with rounding */ + /* rounding is the equivalent of adding 0.5, which is the offset in hrmode */ + + move32(); + } + } +# endif /* FUNCTION_quantizeSpec_func1 */ + } + ELSE + { + s = sub(add(x_e, gain_e), 15); + s = s_max(s_min(s, 15), -15); +# ifdef FUNCTION_quantizeSpec_func1 + ARM_params[0] = gain; + ARM_params[1] = s; + ARM_params[2] = -4096; + quantizeSpec_func1_ip(xq, x, nt, ARM_params); +# else + FOR (i = 0; i < nt; i++) + { + offs32 = Mpy_32_32_lc3plus(L_abs(x[i]), gain); /* multiply */ + offs32 = L_shl(offs32, s); /* convert to 15Q16 */ + tmp16 = mac_r(offs32, -4096, 1); /* add offset and truncate */ + + if (x[i] < 0) + tmp16 = negate(tmp16); /* restore sign */ + + /* Normal quantization: xq[i] = x[i] / gg + sign(x[i]) * 0.375 + quant_offset is -0.125 in Q15 and round adds 0.5 in Q16. Hence + mac_r results in abs(x[i])/gain - 0.125 + 0.5 = abs(x[i])/gain + 0.375. + Due to the abs and negate combination this achieves the same result + as spec. + */ + + xq[i] = tmp16; + move16(); + } +# endif /* FUNCTION_quantizeSpec_func1 */ + } + /* Rate flag */ + rateFlag = 0; + move16(); + if (fs_idx != 5) + { + if (sub(totalBits, add(160, DEPR_i_mult(fs_idx, 160))) > 0) + { + rateFlag = 2 << NBITS_CONTEXT; + move16(); + } + } + + /* Init */ + nt_half = shr_pos(nt, 1); + c = 0; + move16(); + t = 0; + move16(); + a1_i = 0; + move16(); + b1_i = 1; + move16(); + target32 = L_shl_pos(L_deposit_l(target), SYM_BITS_Q); + nbits32 = L_negate(target32); + nbits232 = 0; + move32(); + nbits_lsb = 0; + move16(); + + if (fs_idx != 5) + { + IF (mode == 0 && sub(totalBits, add(480, DEPR_i_mult(fs_idx, 160))) >= 0) + { + mode = 1; + move16(); + } + } + + /* Find last non-zero tuple */ + lastnz = find_last_nz_pair(xq, nt); + IF (mode >= 0) + { + lastnz2 = 2; + } + ELSE + { + lastnz2 = lastnz; + } + + IF (mode < 0) + { + /* Main Loop through the 2-tuples */ + FOR (k = 0; k < lastnz; k += 2) + { + + /* Get context */ + t = add(c, rateFlag); + if (sub(k, nt_half) > 0) + { + t = add(t, 1 << NBITS_CONTEXT); + } + codingdata[0] = t; + move16(); + + /* Init current 2-tuple encoding */ + a1 = L_abs(xq[a1_i]); + b1 = L_abs(xq[b1_i]); + ab_max = L_max(a1, b1); + + IF (ab_max == 0) + { + codingdata[1] = -1; + move16(); + codingdata[2] = 0; + move16(); + nbits32 = L_add(nbits32, ari_spec_bits[ari_spec_lookup[t]][0]); + c = add(shl_pos(s_and(c, 0xf), 4), 1); + } + ELSE IF (L_sub(ab_max, A_THRES) < 0) + { + codingdata[1] = 0; + move16(); + msb = L_add(a1, L_shl_pos(b1, A_THRES_SHIFT)); + codingdata[2] = msb; + move16(); + nbits32 = L_add(nbits32, ari_spec_bits[ari_spec_lookup[t]][msb]); + if (a1 != 0) + { + nbits32 = L_add(nbits32, 1 << SYM_BITS_Q); + } + if (b1 != 0) + { + nbits32 = L_add(nbits32, 1 << SYM_BITS_Q); + } + c = L_add(shl_pos(s_and(c, 0xf), 4), L_add(L_add(a1, b1), 1)); + } + ELSE IF (L_sub(ab_max, 2 * A_THRES) < 0) + { + codingdata[1] = 1; + move16(); + nbits32 = L_add(nbits32, ari_spec_bits[ari_spec_lookup[t]][VAL_ESC]); + nbits32 = L_add(nbits32, 2 << SYM_BITS_Q); + a1_msb = L_shr_pos_pos(a1, 1); + b1_msb = L_shr_pos_pos(b1, 1); + msb = L_add(a1_msb, shl_pos(b1_msb, A_THRES_SHIFT)); + codingdata[2] = msb; + move16(); + nbits32 = L_add(nbits32, ari_spec_bits[ari_spec_lookup[t + Tab_esc_nb[1]]][msb]); + if (a1 != 0) + { + nbits32 = L_add(nbits32, 1 << SYM_BITS_Q); + } + if (b1 != 0) + { + nbits32 = L_add(nbits32, 1 << SYM_BITS_Q); + } + c = L_add(shl_pos(s_and(c, 0xf), 4), L_add(L_shl_pos(L_add(a1_msb, b1_msb), 1), 1)); + } + ELSE + { + levmax = sub(maxlevs, sub(norm_l(ab_max), 8)); + codingdata[1] = levmax; + move16(); + FOR (lev = 0; lev < levmax; lev++) + { + lev1 = s_min(lev, 3); + nbits32 = L_add(nbits32, ari_spec_bits[ari_spec_lookup[t + Tab_esc_nb[lev1]]][VAL_ESC]); + } + nbits32 = L_add(nbits32, L_shl_pos(L_deposit_l(levmax), SYM_BITS_Q + 1)); + a1_msb = L_shr(a1, levmax); + b1_msb = L_shr(b1, levmax); + msb = L_add(a1_msb, L_shl_pos(b1_msb, A_THRES_SHIFT)); + codingdata[2] = msb; + move16(); + lev1 = s_min(levmax, 3); + nbits32 = L_add(nbits32, ari_spec_bits[ari_spec_lookup[t + Tab_esc_nb[lev1]]][msb]); + if (a1 != 0) + { + nbits32 = L_add(nbits32, 1 << SYM_BITS_Q); + } + if (b1 != 0) + { + nbits32 = L_add(nbits32, 1 << SYM_BITS_Q); + } + c = add(shl_pos(s_and(c, 0xf), 4), add(12, s_min(levmax, 3))); + } + + a1_i += 2; + b1_i += 2; + codingdata += 3; + + } /* end of the 2-tuples loop */ + } + ELSE IF (mode == 0) + { + /* Main Loop through the 2-tuples */ + FOR (k = 0; k < lastnz; k += 2) + { + + /* Get context */ + t = add(c, rateFlag); + if (sub(k, nt_half) > 0) + { + t = add(t, 1 << NBITS_CONTEXT); + } + + codingdata[0] = t; + move16(); + + /* Init current 2-tuple encoding */ + a1 = L_abs(xq[a1_i]); + b1 = L_abs(xq[b1_i]); + ab_max = L_max(a1, b1); + + IF (ab_max == 0) + { + codingdata[1] = -1; + move16(); + codingdata[2] = 0; + move16(); + nbits32 = L_add(nbits32, ari_spec_bits[ari_spec_lookup[t]][0]); + c = add(shl_pos(s_and(c, 0xf), 4), 1); + } + ELSE IF (L_sub(ab_max, A_THRES) < 0) + { + codingdata[1] = 0; + move16(); + msb = L_add(a1, L_shl_pos(b1, A_THRES_SHIFT)); + codingdata[2] = msb; + move16(); + nbits32 = L_add(nbits32, ari_spec_bits[ari_spec_lookup[t]][msb]); + if (a1 != 0) + { + nbits32 = L_add(nbits32, 1 << SYM_BITS_Q); + } + if (b1 != 0) + { + nbits32 = L_add(nbits32, 1 << SYM_BITS_Q); + } + + if (nbits32 <= 0) + { + lastnz2 = add(k, 2); + } + if (nbits32 <= 0) + { + nbits232 = nbits32; + move32(); + } + + c = L_add(shl_pos(s_and(c, 0xf), 4), L_add(L_add(a1, b1), 1)); + } + ELSE IF (L_sub(ab_max, 2 * A_THRES) < 0) + { + codingdata[1] = 1; + move16(); + nbits32 = L_add(nbits32, ari_spec_bits[ari_spec_lookup[t]][VAL_ESC]); + nbits32 = L_add(nbits32, 2 << SYM_BITS_Q); + a1_msb = L_shr_pos_pos(a1, 1); + b1_msb = L_shr_pos_pos(b1, 1); + msb = L_add(a1_msb, L_shl_pos(b1_msb, A_THRES_SHIFT)); + codingdata[2] = msb; + move16(); + nbits32 = L_add(nbits32, ari_spec_bits[ari_spec_lookup[t + Tab_esc_nb[1]]][msb]); + if (a1 != 0) + { + nbits32 = L_add(nbits32, 1 << SYM_BITS_Q); + } + if (b1 != 0) + { + nbits32 = L_add(nbits32, 1 << SYM_BITS_Q); + } + + if (nbits32 <= 0) + { + lastnz2 = add(k, 2); + } + if (nbits32 <= 0) + { + nbits232 = nbits32; + move32(); + } + + c = add(shl_pos(s_and(c, 0xf), 4), L_add(L_shl_pos(L_add(a1_msb, b1_msb), 1), 1)); + } + ELSE + { + levmax = sub(maxlevs, sub(norm_l(ab_max), 8)); + codingdata[1] = levmax; + move16(); + FOR (lev = 0; lev < levmax; lev++) + { + lev1 = s_min(lev, 3); + nbits32 = L_add(nbits32, ari_spec_bits[ari_spec_lookup[t + Tab_esc_nb[lev1]]][VAL_ESC]); + } + nbits32 = L_add(nbits32, L_shl_pos(L_deposit_l(levmax), SYM_BITS_Q + 1)); + a1_msb = L_shr(a1, levmax); + b1_msb = L_shr(b1, levmax); + msb = L_add(a1_msb, L_shl_pos(b1_msb, A_THRES_SHIFT)); + codingdata[2] = msb; + move16(); + lev1 = s_min(levmax, 3); + nbits32 = L_add(nbits32, ari_spec_bits[ari_spec_lookup[t + Tab_esc_nb[lev1]]][msb]); + if (a1 != 0) + { + nbits32 = L_add(nbits32, 1 << SYM_BITS_Q); + } + if (b1 != 0) + { + nbits32 = L_add(nbits32, 1 << SYM_BITS_Q); + } + + if (nbits32 <= 0) + { + lastnz2 = add(k, 2); + } + if (nbits32 <= 0) + { + nbits232 = nbits32; + move32(); + } + + c = add(shl_pos(s_and(c, 0xf), 4), add(12, s_min(levmax, 3))); + } + + a1_i += 2; + b1_i += 2; + codingdata += 3; + + } /* end of the 2-tuples loop */ + } + ELSE + { + /* Main Loop through the 2-tuples */ + FOR (k = 0; k < lastnz; k += 2) + { + + /* Get context */ + t = add(c, rateFlag); + + if (sub(k, nt_half) > 0) + { + t = add(t, 1 << NBITS_CONTEXT); + } + + codingdata[0] = t; + move16(); + + /* Init current 2-tuple encoding */ + a1 = L_abs(xq[a1_i]); + b1 = L_abs(xq[b1_i]); + ab_max = L_max(a1, b1); + + IF (ab_max == 0) + { + codingdata[1] = -1; + move16(); + codingdata[2] = 0; + move16(); + nbits32 = L_add(nbits32, ari_spec_bits[ari_spec_lookup[t]][0]); + c = add(shl_pos(s_and(c, 0xf), 4), 1); + } + ELSE IF (L_sub(ab_max, A_THRES) < 0) + { + codingdata[1] = 0; + move16(); + msb = L_add(a1, L_shl_pos(b1, A_THRES_SHIFT)); + codingdata[2] = msb; + move16(); + nbits32 = L_add(nbits32, ari_spec_bits[ari_spec_lookup[t]][msb]); + if (a1 != 0) + { + nbits32 = L_add(nbits32, 1 << SYM_BITS_Q); + } + if (b1 != 0) + { + nbits32 = L_add(nbits32, 1 << SYM_BITS_Q); + } + + if (nbits32 <= 0) + { + lastnz2 = add(k, 2); + } + if (nbits32 <= 0) + { + nbits232 = nbits32; + move32(); + } + + c = add(shl_pos(s_and(c, 0xf), 4), add(add(a1, b1), 1)); + } + ELSE IF (L_sub(ab_max, 2 * A_THRES) < 0) + { + codingdata[1] = 1; + move16(); + nbits32 = L_add(nbits32, ari_spec_bits[ari_spec_lookup[t]][VAL_ESC]); + a1_msb = L_shr_pos_pos(a1, 1); + b1_msb = L_shr_pos_pos(b1, 1); + msb = L_add(a1_msb, L_shl_pos(b1_msb, A_THRES_SHIFT)); + codingdata[2] = msb; + move16(); + nbits32 = L_add(nbits32, ari_spec_bits[ari_spec_lookup[t + Tab_esc_nb[1]]][msb]); + if (a1_msb != 0) + { + nbits32 = L_add(nbits32, 1 << SYM_BITS_Q); + } + if (b1_msb != 0) + { + nbits32 = L_add(nbits32, 1 << SYM_BITS_Q); + } + nbits_lsb = add(nbits_lsb, 2); + if (L_sub(a1, 1) == 0) + { + nbits_lsb = add(nbits_lsb, 1); + } + if (L_sub(b1, 1) == 0) + { + nbits_lsb = add(nbits_lsb, 1); + } + + if (nbits32 <= 0) + { + lastnz2 = add(k, 2); + } + if (nbits32 <= 0) + { + nbits232 = nbits32; + move32(); + } + + c = add(shl_pos(s_and(c, 0xf), 4), add(shl_pos(add(a1_msb, b1_msb), 1), 1)); + } + ELSE + { + levmax = sub(maxlevs, sub(norm_l(ab_max), 8)); + codingdata[1] = levmax; + move16(); + FOR (lev = 0; lev < levmax; lev++) + { + lev1 = s_min(lev, 3); + nbits32 = L_add(nbits32, ari_spec_bits[ari_spec_lookup[t + Tab_esc_nb[lev1]]][VAL_ESC]); + } + nbits32 = L_add(nbits32, L_shl_pos(L_deposit_l(sub(levmax, 1)), SYM_BITS_Q + 1)); + a1_msb = L_shr(a1, levmax); + b1_msb = L_shr(b1, levmax); + msb = L_add(a1_msb, L_shl_pos(b1_msb, A_THRES_SHIFT)); + codingdata[2] = msb; + move16(); + lev1 = s_min(levmax, 3); + nbits32 = L_add(nbits32, ari_spec_bits[ari_spec_lookup[t + Tab_esc_nb[lev1]]][msb]); + a1_msb = L_shr_pos(a1, 1); + b1_msb = L_shr_pos(b1, 1); + if (a1_msb != 0) + { + nbits32 = L_add(nbits32, 1 << SYM_BITS_Q); + } + if (b1_msb != 0) + { + nbits32 = L_add(nbits32, 1 << SYM_BITS_Q); + } + nbits_lsb = add(nbits_lsb, 2); + if (L_sub(a1, 1) == 0) + { + nbits_lsb = add(nbits_lsb, 1); + } + if (L_sub(b1, 1) == 0) + { + nbits_lsb = add(nbits_lsb, 1); + } + + if (nbits32 <= 0) + { + lastnz2 = add(k, 2); + } + if (nbits32 <= 0) + { + nbits232 = nbits32; + move32(); + } + + c = add(shl_pos(s_and(c, 0xf), 4), add(12, s_min(levmax, 3))); + } + + a1_i += 2; + b1_i += 2; + codingdata += 3; + + } /* end of the 2-tuples loop */ + } + + /* Number of consumed bits */ + nbits32 = L_add(nbits32, target32); + totBits = add(extract_l(L_shr_pos_pos(L_sub(nbits32, 1), SYM_BITS_Q)), 1); + IF (mode > 0) + { + totBits = add(totBits, nbits_lsb); + } + IF (nBits != NULL) + { + *nBits = totBits; + } + IF (mode >= 0) + { + nbits232 = L_add(nbits232, target32); + *nBits2 = add(extract_l(L_shr_pos(L_sub(nbits232, 1), SYM_BITS_Q)), 1); + } + ELSE + { + *nBits2 = *nBits; + move16(); + } + IF (mode > 0) + { + *nBits2 = add(*nBits2, nbits_lsb); + } + *lastnzout = lastnz2; + + /* Truncation of high frequency coefficients */ + IF (lastnz > lastnz2) + { + basop_memset(&xq[lastnz2], 0, (lastnz - lastnz2) * sizeof(*xq)); + } + + /* Truncation of LSBs */ + test(); + IF (mode > 0 && sub(totBits, target) > 0) + { + *lsbMode = 1; + move16(); + } + ELSE + { + *lsbMode = 0; + move16(); + } + +# ifdef DYNMEM_COUNT + Dyn_Mem_Out(); +# endif +} + +# else /* ENABLE_HR_MODE */ + +void processQuantizeSpec_fx(Word32 x[], Word16 x_e, Word16 gain, Word16 gain_e, Word16 xq[], Word16 nt, Word16 target, + Word16 totalBits, Word16 *nBits, Word16 *nBits2, Word16 fs_idx, Word16 *lastnzout, + Word16 *codingdata, Word16 *lsbMode, Word16 mode +) +{ + + Word16 a1, b1, a1_i, b1_i; + Word16 t, lev1; + Word16 lastnz, lastnz2; + Word16 rateFlag; + Word32 nbits32, nbits232, target32; + Word16 nt_half; + Word16 c, ab_max, msb, a1_msb, b1_msb, levmax; + Word16 s; + Word16 totBits, nbits_lsb; + Counter k, lev; + Word16 tmp16; + Word32 offs32; + Counter i; + +#ifdef DYNMEM_COUNT + Dyn_Mem_In("processQuantizeSpec_fx", sizeof(struct { + Word16 a1, b1, a1_i, b1_i; + Word16 t, lev1; + Word16 lastnz, lastnz2; + Word16 rateFlag; + Word32 nbits32, nbits232; + Word16 nt_half; + Word16 c, ab_max, msb, a1_msb, b1_msb, levmax; + Counter k, lev, i; + Word16 s; + Word16 tmp16; + Word32 offs32, target32; + Word16 totBits, nbits_lsb; + })); +#endif + + /* Quantization */ + gain = Inv16_lc3plus(gain, &gain_e); + s = sub(add(x_e, gain_e), 15); + s = s_max(s_min(s, 15), -15); + + FOR (i = 0; i < nt; i++) + { + offs32 = Mpy_32_16_lc3plus(L_abs(x[i]), gain); /* multiply */ + offs32 = L_shl(offs32, s); /* convert to 15Q16 */ + tmp16 = extract_h(L_add(offs32, 0x00006000)); /* add offset and truncate */ + Word16 x_sign = (Word16) L_shr(x[i], 31); + xq[i] = sub(s_xor(tmp16, x_sign), x_sign); + move16(); + /* + Normal quantization: xq[i] = x[i] / gg + sign(x[i]) * 0.375 + -> 0.375 = 0x00006000 in 15Q16 + */ + } + + /* Rate flag */ + rateFlag = 0; + move16(); + if (sub(totalBits, add(160, DEPR_i_mult(fs_idx, 160))) > 0) + { + rateFlag = 2 << NBITS_CONTEXT; + move16(); + } + + /* Init */ + nt_half = shr_pos(nt, 1); + c = 0; + move16(); + t = 0; + move16(); + a1_i = 0; + move16(); + b1_i = 1; + move16(); + target32 = L_shl_pos(L_deposit_l(target), SYM_BITS_Q); + nbits32 = L_negate(target32); + nbits232 = 0; + move32(); + nbits_lsb = 0; + move16(); + IF (mode == 0 && sub(totalBits, add(480, DEPR_i_mult(fs_idx, 160))) >= 0) + { + mode = 1; + move16(); + } + + /* Find last non-zero tuple */ + lastnz = find_last_nz_pair(xq, nt); + IF (mode >= 0) + { + lastnz2 = 2; + } + ELSE + { + lastnz2 = lastnz; + } + + IF (mode < 0) + { + /* Main Loop through the 2-tuples */ + FOR (k = 0; k < lastnz; k += 2) + { + + /* Get context */ + t = add(c, rateFlag); + if (sub(k, nt_half) > 0) + { + t = add(t, 1 << NBITS_CONTEXT); + } + codingdata[0] = t; + move16(); + + /* Init current 2-tuple encoding */ + a1 = abs_s(xq[a1_i]); + b1 = abs_s(xq[b1_i]); + ab_max = s_max(a1, b1); + + IF (ab_max == 0) + { + codingdata[1] = -1; + move16(); + codingdata[2] = 0; + move16(); + nbits32 = L_add(nbits32, ari_spec_bits[ari_spec_lookup[t]][0]); + c = add(shl_pos(s_and(c, 0xf), 4), 1); + } + ELSE IF (sub(ab_max, A_THRES) < 0) + { + codingdata[1] = 0; + move16(); + msb = add(a1, shl_pos(b1, A_THRES_SHIFT)); + codingdata[2] = msb; + move16(); + nbits32 = L_add(nbits32, ari_spec_bits[ari_spec_lookup[t]][msb]); + if (a1 != 0) + { + nbits32 = L_add(nbits32, 1 << SYM_BITS_Q); + } + if (b1 != 0) + { + nbits32 = L_add(nbits32, 1 << SYM_BITS_Q); + } + c = add(shl_pos(s_and(c, 0xf), 4), add(add(a1, b1), 1)); + } + ELSE IF (sub(ab_max, 2 * A_THRES) < 0) + { + codingdata[1] = 1; + move16(); + nbits32 = L_add(nbits32, ari_spec_bits[ari_spec_lookup[t]][VAL_ESC]); + nbits32 = L_add(nbits32, 2 << SYM_BITS_Q); + a1_msb = shr_pos_pos(a1, 1); + b1_msb = shr_pos_pos(b1, 1); + msb = add(a1_msb, shl_pos(b1_msb, A_THRES_SHIFT)); + codingdata[2] = msb; + move16(); + nbits32 = L_add(nbits32, ari_spec_bits[ari_spec_lookup[t + Tab_esc_nb[1]]][msb]); + if (a1 != 0) + { + nbits32 = L_add(nbits32, 1 << SYM_BITS_Q); + } + if (b1 != 0) + { + nbits32 = L_add(nbits32, 1 << SYM_BITS_Q); + } + c = add(shl_pos(s_and(c, 0xf), 4), add(shl_pos(add(a1_msb, b1_msb), 1), 1)); + } + ELSE + { + levmax = sub(13, norm_s(ab_max)); + codingdata[1] = levmax; + move16(); + FOR (lev = 0; lev < levmax; lev++) + { + lev1 = s_min(lev, 3); + nbits32 = L_add(nbits32, ari_spec_bits[ari_spec_lookup[t + Tab_esc_nb[lev1]]][VAL_ESC]); + } + nbits32 = L_add(nbits32, L_shl_pos(L_deposit_l(levmax), SYM_BITS_Q + 1)); + a1_msb = shr(a1, levmax); + b1_msb = shr(b1, levmax); + msb = add(a1_msb, shl_pos(b1_msb, A_THRES_SHIFT)); + codingdata[2] = msb; + move16(); + lev1 = s_min(levmax, 3); + nbits32 = L_add(nbits32, ari_spec_bits[ari_spec_lookup[t + Tab_esc_nb[lev1]]][msb]); + if (a1 != 0) + { + nbits32 = L_add(nbits32, 1 << SYM_BITS_Q); + } + if (b1 != 0) + { + nbits32 = L_add(nbits32, 1 << SYM_BITS_Q); + } + c = add(shl_pos(s_and(c, 0xf), 4), add(12, s_min(levmax, 3))); + } + + a1_i += 2; + b1_i += 2; + codingdata += 3; + + } /* end of the 2-tuples loop */ + } + ELSE IF (mode == 0) + { + /* Main Loop through the 2-tuples */ + FOR (k = 0; k < lastnz; k += 2) + { + + /* Get context */ + t = add(c, rateFlag); + if (sub(k, nt_half) > 0) + { + t = add(t, 1 << NBITS_CONTEXT); + } + codingdata[0] = t; + move16(); + + /* Init current 2-tuple encoding */ + a1 = abs_s(xq[a1_i]); + b1 = abs_s(xq[b1_i]); + ab_max = s_max(a1, b1); + + IF (ab_max == 0) + { + codingdata[1] = -1; + move16(); + codingdata[2] = 0; + move16(); + nbits32 = L_add(nbits32, ari_spec_bits[ari_spec_lookup[t]][0]); + c = add(shl_pos(s_and(c, 0xf), 4), 1); + } + ELSE IF (sub(ab_max, A_THRES) < 0) + { + codingdata[1] = 0; + move16(); + msb = add(a1, shl_pos(b1, A_THRES_SHIFT)); + codingdata[2] = msb; + move16(); + nbits32 = L_add(nbits32, ari_spec_bits[ari_spec_lookup[t]][msb]); + if (a1 != 0) + { + nbits32 = L_add(nbits32, 1 << SYM_BITS_Q); + } + if (b1 != 0) + { + nbits32 = L_add(nbits32, 1 << SYM_BITS_Q); + } + if (nbits32 <= 0) + { + lastnz2 = add(k, 2); + } + if (nbits32 <= 0) + { + nbits232 = nbits32; + move32(); + } + c = add(shl_pos(s_and(c, 0xf), 4), add(add(a1, b1), 1)); + } + ELSE IF (sub(ab_max, 2 * A_THRES) < 0) + { + codingdata[1] = 1; + move16(); + nbits32 = L_add(nbits32, ari_spec_bits[ari_spec_lookup[t]][VAL_ESC]); + nbits32 = L_add(nbits32, 2 << SYM_BITS_Q); + a1_msb = shr_pos_pos(a1, 1); + b1_msb = shr_pos_pos(b1, 1); + msb = add(a1_msb, shl_pos(b1_msb, A_THRES_SHIFT)); + codingdata[2] = msb; + move16(); + nbits32 = L_add(nbits32, ari_spec_bits[ari_spec_lookup[t + Tab_esc_nb[1]]][msb]); + if (a1 != 0) + { + nbits32 = L_add(nbits32, 1 << SYM_BITS_Q); + } + if (b1 != 0) + { + nbits32 = L_add(nbits32, 1 << SYM_BITS_Q); + } + if (nbits32 <= 0) + { + lastnz2 = add(k, 2); + } + if (nbits32 <= 0) + { + nbits232 = nbits32; + move32(); + } + c = add(shl_pos(s_and(c, 0xf), 4), add(shl_pos(add(a1_msb, b1_msb), 1), 1)); + } + ELSE + { + levmax = sub(13, norm_s(ab_max)); + codingdata[1] = levmax; + move16(); + FOR (lev = 0; lev < levmax; lev++) + { + lev1 = s_min(lev, 3); + nbits32 = L_add(nbits32, ari_spec_bits[ari_spec_lookup[t + Tab_esc_nb[lev1]]][VAL_ESC]); + } + nbits32 = L_add(nbits32, L_shl_pos(L_deposit_l(levmax), SYM_BITS_Q + 1)); + a1_msb = shr(a1, levmax); + b1_msb = shr(b1, levmax); + msb = add(a1_msb, shl_pos(b1_msb, A_THRES_SHIFT)); + codingdata[2] = msb; + move16(); + lev1 = s_min(levmax, 3); + nbits32 = L_add(nbits32, ari_spec_bits[ari_spec_lookup[t + Tab_esc_nb[lev1]]][msb]); + if (a1 != 0) + { + nbits32 = L_add(nbits32, 1 << SYM_BITS_Q); + } + if (b1 != 0) + { + nbits32 = L_add(nbits32, 1 << SYM_BITS_Q); + } + if (nbits32 <= 0) + { + lastnz2 = add(k, 2); + } + if (nbits32 <= 0) + { + nbits232 = nbits32; + move32(); + } + c = add(shl_pos(s_and(c, 0xf), 4), add(12, s_min(levmax, 3))); + } + + a1_i += 2; + b1_i += 2; + codingdata += 3; + + } /* end of the 2-tuples loop */ + } + ELSE + { + /* Main Loop through the 2-tuples */ + FOR (k = 0; k < lastnz; k += 2) + { + + /* Get context */ + t = add(c, rateFlag); + if (sub(k, nt_half) > 0) + { + t = add(t, 1 << NBITS_CONTEXT); + } + codingdata[0] = t; + move16(); + + /* Init current 2-tuple encoding */ + a1 = abs_s(xq[a1_i]); + b1 = abs_s(xq[b1_i]); + ab_max = s_max(a1, b1); + + IF (ab_max == 0) + { + codingdata[1] = -1; + move16(); + codingdata[2] = 0; + move16(); + nbits32 = L_add(nbits32, ari_spec_bits[ari_spec_lookup[t]][0]); + c = add(shl_pos(s_and(c, 0xf), 4), 1); + } + ELSE IF (sub(ab_max, A_THRES) < 0) + { + codingdata[1] = 0; + move16(); + msb = add(a1, shl_pos(b1, A_THRES_SHIFT)); + codingdata[2] = msb; + move16(); + nbits32 = L_add(nbits32, ari_spec_bits[ari_spec_lookup[t]][msb]); + if (a1 != 0) + { + nbits32 = L_add(nbits32, 1 << SYM_BITS_Q); + } + if (b1 != 0) + { + nbits32 = L_add(nbits32, 1 << SYM_BITS_Q); + } + if (nbits32 <= 0) + { + lastnz2 = add(k, 2); + } + if (nbits32 <= 0) + { + nbits232 = nbits32; + move32(); + } + c = add(shl_pos(s_and(c, 0xf), 4), add(add(a1, b1), 1)); + } + ELSE IF (sub(ab_max, 2 * A_THRES) < 0) + { + codingdata[1] = 1; + move16(); + nbits32 = L_add(nbits32, ari_spec_bits[ari_spec_lookup[t]][VAL_ESC]); + a1_msb = shr_pos_pos(a1, 1); + b1_msb = shr_pos_pos(b1, 1); + msb = add(a1_msb, shl_pos(b1_msb, A_THRES_SHIFT)); + codingdata[2] = msb; + move16(); + nbits32 = L_add(nbits32, ari_spec_bits[ari_spec_lookup[t + Tab_esc_nb[1]]][msb]); + if (a1_msb != 0) + { + nbits32 = L_add(nbits32, 1 << SYM_BITS_Q); + } + if (b1_msb != 0) + { + nbits32 = L_add(nbits32, 1 << SYM_BITS_Q); + } + nbits_lsb = add(nbits_lsb, 2); + if (sub(a1, 1) == 0) + { + nbits_lsb = add(nbits_lsb, 1); + } + if (sub(b1, 1) == 0) + { + nbits_lsb = add(nbits_lsb, 1); + } + if (nbits32 <= 0) + { + lastnz2 = add(k, 2); + } + if (nbits32 <= 0) + { + nbits232 = nbits32; + move32(); + } + c = add(shl_pos(s_and(c, 0xf), 4), add(shl_pos(add(a1_msb, b1_msb), 1), 1)); + } + ELSE + { + levmax = sub(13, norm_s(ab_max)); + codingdata[1] = levmax; + move16(); + FOR (lev = 0; lev < levmax; lev++) + { + lev1 = s_min(lev, 3); + nbits32 = L_add(nbits32, ari_spec_bits[ari_spec_lookup[t + Tab_esc_nb[lev1]]][VAL_ESC]); + } + nbits32 = L_add(nbits32, L_shl_pos(L_deposit_l(sub(levmax, 1)), SYM_BITS_Q + 1)); + a1_msb = shr(a1, levmax); + b1_msb = shr(b1, levmax); + msb = add(a1_msb, shl_pos(b1_msb, A_THRES_SHIFT)); + codingdata[2] = msb; + move16(); + lev1 = s_min(levmax, 3); + nbits32 = L_add(nbits32, ari_spec_bits[ari_spec_lookup[t + Tab_esc_nb[lev1]]][msb]); + a1_msb = shr_pos(a1, 1); + b1_msb = shr_pos(b1, 1); + if (a1_msb != 0) + { + nbits32 = L_add(nbits32, 1 << SYM_BITS_Q); + } + if (b1_msb != 0) + { + nbits32 = L_add(nbits32, 1 << SYM_BITS_Q); + } + nbits_lsb = add(nbits_lsb, 2); + if (sub(a1, 1) == 0) + { + nbits_lsb = add(nbits_lsb, 1); + } + if (sub(b1, 1) == 0) + { + nbits_lsb = add(nbits_lsb, 1); + } + if (nbits32 <= 0) + { + lastnz2 = add(k, 2); + } + if (nbits32 <= 0) + { + nbits232 = nbits32; + move32(); + } + c = add(shl_pos(s_and(c, 0xf), 4), add(12, s_min(levmax, 3))); + } + + a1_i += 2; + b1_i += 2; + codingdata += 3; + + } /* end of the 2-tuples loop */ + } + + /* Number of consumed bits */ + nbits32 = L_add(nbits32, target32); + totBits = add(extract_l(L_shr_pos_pos(L_sub(nbits32, 1), SYM_BITS_Q)), 1); + IF (mode > 0) + { + totBits = add(totBits, nbits_lsb); + } + IF (nBits != NULL) + { + *nBits = totBits; + } + IF (mode >= 0) + { + nbits232 = L_add(nbits232, target32); + *nBits2 = add(extract_l(L_shr_pos(L_sub(nbits232, 1), SYM_BITS_Q)), 1); + } + ELSE + { + *nBits2 = *nBits; + move16(); + } + IF (mode > 0) + { + *nBits2 = add(*nBits2, nbits_lsb); + } + *lastnzout = lastnz2; + + /* Truncation of high frequency coefficients */ + IF (lastnz > lastnz2) + { + basop_memset(&xq[lastnz2], 0, (lastnz - lastnz2) * sizeof(*xq)); + } + + /* Truncation of LSBs */ + test(); + IF (mode > 0 && sub(totBits, target) > 0) + { + *lsbMode = 1; + move16(); + } + ELSE + { + *lsbMode = 0; + move16(); + } + +#ifdef DYNMEM_COUNT + Dyn_Mem_Out(); +#endif +} + +# endif /* ENABLE_HR_MODE */ diff --git a/lib_lc3plus/reorder_bitstream_fx.c b/lib_lc3plus/reorder_bitstream_fx.c new file mode 100644 index 0000000000000000000000000000000000000000..281eef325c921bc0bea706bd50da2dcd83761437 --- /dev/null +++ b/lib_lc3plus/reorder_bitstream_fx.c @@ -0,0 +1,56 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.5 * +* 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 "defines.h" + +#include "constants.h" +#include "functions.h" + + +void processReorderBitstream_fx(UWord8 *bytes, Word16 n_pccw, Word16 n_pc, Word16 b_left, Word8 *scratchBuffer) +{ + Word16 block_bytes; + UWord8 * bytes_tmp; + +#ifdef DYNMEM_COUNT + struct _dynmem + { + Word16 block_bits, block_bytes; + UWord8 * bytes_tmp; + }; + Dyn_Mem_In("processReorderBitstream_fx", sizeof(struct _dynmem)); +#endif + + bytes_tmp = (UWord8 *)scratchAlign(scratchBuffer, 0); /* Size = LC3PLUS_MAX_BYTES */ + + if (n_pccw == 0) + { +#ifdef DYNMEM_COUNT + Dyn_Mem_Out(); +#endif + return; + } + + assert(b_left >= 0); + + /* set block size in bits and full bytes */ + block_bytes = shr_sat(add(n_pc, 1), 1); + + /* rearrange bitstream */ + basop_memmove(&bytes_tmp[0], &bytes[b_left], block_bytes * sizeof(UWord8)); + basop_memmove(&bytes_tmp[block_bytes], &bytes[0], b_left * sizeof(UWord8)); + + basop_memmove(&bytes[0], &bytes_tmp[0], add(block_bytes, b_left) * sizeof(UWord8)); + +#ifdef DYNMEM_COUNT + Dyn_Mem_Out(); +#endif +} + + diff --git a/lib_lc3plus/resamp12k8_fx.c b/lib_lc3plus/resamp12k8_fx.c new file mode 100644 index 0000000000000000000000000000000000000000..a54f6bc292028066fc378cee596208282d02c88d --- /dev/null +++ b/lib_lc3plus/resamp12k8_fx.c @@ -0,0 +1,121 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.5 * +* 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 "functions.h" + +void process_resamp12k8_fx(Word16 x[], Word16 x_len, Word16 mem_in[], Word16 mem_in_len, Word32 mem_50[], + Word16 mem_out[], Word16 mem_out_len, Word16 y[], Word16 *y_len, Word16 fs_idx, + Word16 frame_dms, Word8 *scratchBuffer + , Word16 bps + ) +{ + Dyn_Mem_Deluxe_In( + Word16 * buf; + Word16 index_int, index_frac, len_12k8; + Word16 resamp_upfac, resamp_off_int, resamp_off_frac, resamp_delay; + const Word16 *resamp_filt; + const Word16 *filt_coeff; + Word16 * filt_input; + Word32 filt_output, mem_50_0, mem_50_1; + Counter n, m; + Word32 L_tmp; + ); + + buf = (Word16 *)scratchAlign(scratchBuffer, 0); /* Size = 2 * (MAX_LEN + MAX_LEN / 8) bytes */ + + /* resamp parameters : {upsample-factor, 120 / upsample-factor, down_sample_int_part, down_sample_frac_part } + upsample is to 384 kHz. upsample-facor = 192000 / samp-freq + Fractional downsample parameters are calculated from : downsample samp-freq to 128000 + At 48000 sampling frequency: + upsample-factor = 192000 / 48000 = 4 + 120 / upsample-factor = 120 / 4 = 30 + downsample-ratio = 48000 / 12800 = 3.75 + down_sample_int_part = 3 + down_sample_frac_part = int(0.75 * upsample-factor ) = 0.75 * 4 = 3 + */ + resamp_upfac = resamp_params[fs_idx][0]; move16(); + resamp_delay = resamp_params[fs_idx][1]; move16(); + resamp_off_int = resamp_params[fs_idx][2]; move16(); + resamp_off_frac = resamp_params[fs_idx][3]; move16(); + resamp_filt = resamp_filts[fs_idx]; move16(); + + len_12k8 = LEN_12K8 / 4 * (frame_dms / 25); move16(); + *y_len = len_12k8; move16(); + + /* Init Input Buffer */ + basop_memmove(buf, mem_in, mem_in_len * sizeof(Word16)); + basop_memmove(&buf[mem_in_len], x, x_len * sizeof(Word16)); + basop_memmove(mem_in, &buf[x_len], mem_in_len * sizeof(Word16)); + + /* Init Input Indices */ + index_int = 1; move16(); + index_frac = 0; move16(); + + /* Resampling */ + FOR (n = 0; n < len_12k8; n++) + { + /* Init Filtering */ + filt_input = &buf[index_int]; + filt_coeff = &resamp_filt[index_frac * resamp_delay * 2]; + +/* Perform Filtering */ + filt_output = L_mult0(*filt_input, *filt_coeff); + FOR (m = 1; m < resamp_delay * 2; m++) + { + filt_coeff++; + filt_input++; + if (*filt_coeff) + { + filt_output = L_mac0(filt_output, *filt_input, *filt_coeff); + } + } + y[n] = round_fx(filt_output); move16(); + + /* Update Input Indices */ + index_int = add(index_int, resamp_off_int); + index_frac = add(index_frac, resamp_off_frac); + IF (sub(resamp_upfac, index_frac) <= 0) + { + index_int = add(index_int, 1); + index_frac = sub(index_frac, resamp_upfac); + } + } + + /* High Pass Filtering (-3dB at 50Hz) */ + mem_50_0 = mem_50[0]; move32(); + mem_50_1 = mem_50[1]; move32(); + + FOR (n = 0; n < len_12k8; n++) + { + filt_output = L_mac0_sat(mem_50_0, highpass50_filt_num[0], y[n]); + L_tmp = L_mac0(Mpy_32_16_lc3plus(filt_output, highpass50_filt_den[0]), highpass50_filt_num[1], y[n]); + + IF (sub(bps, 24) == 0) + { + mem_50_0 = L_shl_sat(L_add_sat(L_shr_pos(mem_50_1,1), L_tmp), 1); + } ELSE + { + mem_50_0 = L_add_sat(mem_50_1, L_shl_sat(L_tmp, 1)); + } + + mem_50_1 = L_mac0(Mpy_32_16_lc3plus(filt_output, highpass50_filt_den[1]), highpass50_filt_num[2], y[n]); + y[n] = round_fx_sat(filt_output); move16(); + } + mem_50[0] = mem_50_0; move32(); + mem_50[1] = mem_50_1; move32(); + +/* Output Buffer */ + basop_memmove(buf, mem_out, mem_out_len * sizeof(Word16)); + basop_memmove(&buf[mem_out_len], y, len_12k8 * sizeof(Word16)); + basop_memmove(y, buf, (*y_len + 1) * sizeof(Word16)); + basop_memmove(mem_out, &buf[len_12k8], mem_out_len * sizeof(Word16)); + + Dyn_Mem_Deluxe_Out(); +} + diff --git a/lib_lc3plus/residual_coding_fx.c b/lib_lc3plus/residual_coding_fx.c new file mode 100644 index 0000000000000000000000000000000000000000..2cb6c791f590f5d75300b52aa3d25cd92b78f5d7 --- /dev/null +++ b/lib_lc3plus/residual_coding_fx.c @@ -0,0 +1,238 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.5 * +* 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 "functions.h" + +#ifdef ENABLE_HR_MODE + +void processResidualCoding_fx(Word16 x_e, Word32 x[], + Word32 xq[], Word32 gain, + Word16 gain_e, Word16 L_spec, + Word16 targetBits, Word16 nBits, UWord8 *resBits, Word16 *numResBits + , Word16 hrmode +) +{ + + Counter i; + Word16 s, n, m; + Word32 L_tmp; + Word16 iter = 0; + Counter idx; + Word16 N_nz = 0; + Word16 n1, n2; + +#ifdef DYNMEM_COUNT + Dyn_Mem_In("processResidualCoding_fx", sizeof(struct { + Counter i; + Word16 s, n, m; + Word32 L_tmp; + Word16 iter; + Counter idx; + Word16 N_nz; + Word16 *nz_idx; + Word16 n1, n2; + })); +#endif + + n = 0; + move16(); + + IF (hrmode) + { + m = add(sub(targetBits, nBits), 14); + assert(m <= (MAX_RESBITS_LEN << RESBITS_PACK_SHIFT)); + } + ELSE + { + m = add(sub(targetBits, nBits), 4); + if (m > L_spec) + { + m = L_spec; + } + } + + basop_memset(resBits, 0, sizeof(*resBits)*((m + RESBITS_PACK_MASK) >> RESBITS_PACK_SHIFT)); + + s = sub(add(15, gain_e), x_e); + + IF(hrmode) + { + /* + x = xval * 2^(31 - x_e) + gain = gainval * 2^(15 - gain_e) + + To bring gain to the same q of x : + + gain (in_Qx_e) = gain * 2^(16 + gain_e - x_e) + + gain*offset (in Qx_e) = gain (in_Qx_e) * 0.25 = gain (in_Qx_e) / 4 = gain * 2^(16 - 2 + gain_e - x_e) + */ + Word16 shift_val; + shift_val = sub(sub(gain_e, x_e), 2); + + Word32 gain_offset; + + IF (shift_val <= -32) + gain_offset = 0; + ELSE + { + gain_offset = L_shl_sat(gain, shift_val); + } + + Word16 exit_iter = 0; + + Word16 nz_idx[MAX_LEN]; + + /* enumerate non-zero coefficients */ + FOR (i = 0; i < L_spec; i++) + { + IF (xq[i]) + { + nz_idx[N_nz] = i; move16(); + N_nz = add(N_nz, 1); + } + } + + s = sub(31, sub(x_e, gain_e)); + FOR (iter = 0; iter < EXT_RES_ITER_MAX; iter++) + { + FOR (i = 0; i < N_nz; i++) + { + idx = nz_idx[i]; + + L_tmp = L_sub(x[idx], Mpy_32_32_lc3plus(L_shl(xq[idx], s), gain)); + + IF (L_tmp >= 0) + { + n1 = shr(n, RESBITS_PACK_SHIFT); + n2 = s_and(n, RESBITS_PACK_MASK); + resBits[n1] = (UWord8)s_or(resBits[n1], shl(1, n2)); + move16(); + x[idx] = L_sub(x[idx], gain_offset); + move16(); + } + ELSE + { + move16(); + x[idx] = L_add(x[idx], gain_offset); + move16(); + } + n = add(n, 1); + IF (sub(n, m) == 0) + { + exit_iter = 1; + BREAK; + } + } + gain_offset = L_shr(gain_offset, 1); /* offset *= 0.5 */ + + IF (exit_iter) + { + BREAK; + } + } + } + ELSE + { + s = add(s, 16); + gain = round_fx(gain); + + FOR (i = 0; i < L_spec; i++) + { + IF (xq[i] != 0) + { + L_tmp = L_sub(x[i], Mpy_32_16_lc3plus(L_shl(xq[i], s), gain)); + if (L_tmp >= 0) + { + n1 = shr(n, RESBITS_PACK_SHIFT); + n2 = s_and(n, RESBITS_PACK_MASK); + resBits[n1] = (UWord8) s_or(resBits[n1], shl(1, n2)); + move16(); + } + n = add(n, 1); + IF (sub(n, m) == 0) + { + BREAK; + } + } + } + } + *numResBits = n; + move16(); + +#ifdef DYNMEM_COUNT + Dyn_Mem_Out(); +#endif +} + +#else + +void processResidualCoding_fx(Word16 x_e, Word32 x[], + Word16 xq[], + Word16 gain, Word16 gain_e, Word16 L_spec, + Word16 targetBits, Word16 nBits, UWord8 *resBits, Word16 *numResBits +) +{ + + Counter i; + Word16 s, n, m; + Word32 L_tmp; +#ifdef DYNMEM_COUNT + Dyn_Mem_In("processResidualCoding_fx", sizeof(struct { + Counter i; + Word16 s, n, m; + Word32 L_tmp; + })); +#endif + + n = 0; + move16(); + { + m = add(sub(targetBits, nBits), 4); + if (m > L_spec) + { + m = L_spec; + } + } + + + s = sub(add(15, gain_e), x_e); + { + FOR (i = 0; i < L_spec; i++) + { + IF (xq[i] != 0) + { + L_tmp = L_sub(x[i], L_shl(L_mult(xq[i], gain), s)); + if (L_tmp < 0) + { + resBits[n] = 0; + move16(); + } + if (L_tmp >= 0) + { + resBits[n] = 1; + move16(); + } + n = add(n, 1); + IF (sub(n, m) == 0) + { + BREAK; + } + } + } + } + *numResBits = n; + move16(); + +#ifdef DYNMEM_COUNT + Dyn_Mem_Out(); +#endif +} + +#endif diff --git a/lib_lc3plus/residual_decoding_fx.c b/lib_lc3plus/residual_decoding_fx.c new file mode 100644 index 0000000000000000000000000000000000000000..686398cdd89fd16444127a86ff9a1b45e773854b --- /dev/null +++ b/lib_lc3plus/residual_decoding_fx.c @@ -0,0 +1,207 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.5 * +* 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 "functions.h" + +#ifdef ENABLE_HR_MODE /* HRMODE enables packing of residual bits */ + +void processResidualDecoding_fx(Word32 x[], Word16 x_e, Word16 L_spec, UWord8 prm[], Word16 resQBits +#ifdef ENABLE_HR_MODE + , Word16 hrmode +#endif +) +{ + + Counter i; + Word32 fac_m, fac_p; + Word16 s, bits; + Word32 tmp; + Counter idx; + Word16 N_nz = 0; + Word16 iter; + Word32 fac_hr; + +#ifdef DYNMEM_COUNT + Dyn_Mem_In("processResidualDecoding_fx", sizeof(struct { + Counter i; + Word32 fac_m, fac_p; + Word16 s, bits; + Word32 tmp; + Counter idx; + Word16 N_nz; + Word16 *nz_idx; + Word16 iter; + })); +#endif + + tmp = 0; + s = sub(x_e, 1); + s = s_min(s, 31); + + IF (hrmode) + { + fac_hr = L_shr(0x10000000, s); /* 0.25 in 1Q30 */ + } + ELSE + { + fac_m = L_shr(0xC000000, s); /* 0.1875 in 1Q30 */ + fac_p = L_shr(0x14000000, s); /* 0.3125 in 1Q30 */ + } + + bits = 0; + move16(); + + Word16 nz_idx[MAX_LEN]; + + IF (hrmode) + { + FOR (i = 0; i < L_spec; i++) + { + IF (x[i]) + { + nz_idx[N_nz] = i; move16(); + N_nz = add(N_nz, 1); + } + } + FOR (iter = 0; iter < EXT_RES_ITER_MAX; iter++) + { + IF (sub(bits, resQBits) >= 0) + { + BREAK; + } + FOR (i = 0; i < N_nz; i++) + { + idx = nz_idx[i]; move16(); + + IF (sub(bits, resQBits) >= 0) + { + BREAK; + } + + IF (! (s_and(prm[shr(bits, RESBITS_PACK_SHIFT)], shl(1, s_and(bits, RESBITS_PACK_MASK))))) + { + tmp = L_sub_sat(x[idx], fac_hr); + } + ELSE + { + tmp = L_add_sat(x[idx], fac_hr); + } + x[idx] = tmp; + move32(); + bits = add(bits, 1); + } + fac_hr = L_shr(fac_hr, 1); + } + } + ELSE + { + FOR (i = 0; i < L_spec; i++) + { + IF (sub(bits, resQBits) >= 0) + { + BREAK; + } + + IF (x[i] != 0) + { + IF (! (s_and(prm[shr(bits, RESBITS_PACK_SHIFT)], shl(1, s_and(bits, RESBITS_PACK_MASK))))) + { + if (x[i] > 0) + tmp = L_sub(x[i], fac_m); + if (x[i] < 0) + tmp = L_sub(x[i], fac_p); + } + ELSE + { + if (x[i] > 0) + tmp = L_add(x[i], fac_p); + if (x[i] < 0) + tmp = L_add(x[i], fac_m); + } + x[i] = tmp; + move32(); + bits = add(bits, 1); + } + } + } + +#ifdef DYNMEM_COUNT + Dyn_Mem_Out(); +#endif +} + +#else + +void processResidualDecoding_fx(Word32 x[], Word16 x_e, Word16 L_spec, UWord8 prm[], Word16 resQBits +) +{ + + Counter i; + Word32 fac_m, fac_p; + Word16 s, bits; + Word32 tmp; + +#ifdef DYNMEM_COUNT + Dyn_Mem_In("processResidualDecoding_fx", sizeof(struct { + Counter i; + Word32 fac_m, fac_p; + Word16 s, bits; + Word32 tmp; + })); +#endif + + tmp = 0; + s = sub(x_e, 1); + s = s_min(s, 31); + + { + fac_m = L_shr(0xC000000, s); /* 0.1875 in 1Q30 */ + fac_p = L_shr(0x14000000, s); /* 0.3125 in 1Q30 */ + } + + bits = 0; + move16(); + + { + FOR (i = 0; i < L_spec; i++) + { + IF (sub(bits, resQBits) >= 0) + { + BREAK; + } + + IF (x[i] != 0) + { + IF (prm[bits] == 0) + { + if (x[i] > 0) + tmp = L_sub(x[i], fac_m); + if (x[i] < 0) + tmp = L_sub(x[i], fac_p); + } + ELSE + { + if (x[i] > 0) + tmp = L_add(x[i], fac_p); + if (x[i] < 0) + tmp = L_add(x[i], fac_m); + } + x[i] = tmp; + move32(); + bits = add(bits, 1); + } + } + } + +#ifdef DYNMEM_COUNT + Dyn_Mem_Out(); +#endif +} + +#endif diff --git a/lib_lc3plus/rom_basop_util_lc3plus.c b/lib_lc3plus/rom_basop_util_lc3plus.c new file mode 100644 index 0000000000000000000000000000000000000000..45629965d87d48a7f2650b833b1d0d03cf123ac5 --- /dev/null +++ b/lib_lc3plus/rom_basop_util_lc3plus.c @@ -0,0 +1,2904 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.5 * +* 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 "rom_basop_util_lc3plus.h" +#include "basop_util_lc3plus.h" +#include "functions.h" + + +/* clang-format off */ +# ifdef ENABLE_HR_MODE +# define STC(x) (x) +# define WTC(x) (x) +# define STCP(a, b) {{STC(a), STC(b)}} +# define WTCP(a, b) {{WTC(a), WTC(b)}} +# else +# define STC(x) WORD322WORD16(x) +# define WTC(x) WORD322WORD16(x) +# define STCP(a, b) {{STC(a), STC(b)}} +# define WTCP(a, b) {{WTC(a), WTC(b)}} +# endif +/* clang-format on */ + +/** + * \brief Lookup-Table for binary logarithm + */ +RAM_ALIGN const Word16 ldCoeff_lc3plus[7] = {-32768, -16384, -10923, -8192, -6554, -5461, -4681}; + +/** + \brief Lookup-Table for binary power algorithm + + This table is used for lookup 2^x with + x in range [0...1.0[ in steps of 1/32 +*/ +const UWord32 exp2_tab_long_lc3plus[32] = { + 0x40000000, 0x4166C34C, 0x42D561B4, 0x444C0740, 0x45CAE0F2, 0x47521CC6, 0x48E1E9BA, 0x4A7A77D4, + 0x4C1BF829, 0x4DC69CDD, 0x4F7A9930, 0x51382182, 0x52FF6B55, 0x54D0AD5A, 0x56AC1F75, 0x5891FAC1, + 0x5A82799A, 0x5C7DD7A4, 0x5E8451D0, 0x60962665, 0x62B39509, 0x64DCDEC3, 0x6712460B, 0x69540EC9, + 0x6BA27E65, 0x6DFDDBCC, 0x70666F76, 0x72DC8374, 0x75606374, 0x77F25CCE, 0x7A92BE8B, 0x7D41D96E, +}; + +/** + \brief Lookup-Table for binary power algorithm + + This table is used for lookup 2^x with + x in range [0...1/32[ in steps of 1/1024 +*/ +const UWord32 exp2w_tab_long_lc3plus[32] = { + 0x40000000, 0x400B1818, 0x4016321B, 0x40214E0C, 0x402C6BE9, 0x40378BB4, 0x4042AD6D, 0x404DD113, + 0x4058F6A8, 0x40641E2B, 0x406F479E, 0x407A7300, 0x4085A051, 0x4090CF92, 0x409C00C4, 0x40A733E6, + 0x40B268FA, 0x40BD9FFF, 0x40C8D8F5, 0x40D413DD, 0x40DF50B8, 0x40EA8F86, 0x40F5D046, 0x410112FA, + 0x410C57A2, 0x41179E3D, 0x4122E6CD, 0x412E3152, 0x41397DCC, 0x4144CC3B, 0x41501CA0, 0x415B6EFB, +}; + +/** + \brief Lookup-Table for binary power algorithm + + This table is used for lookup 2^x with + x in range [0...1/1024[ in steps of 1/32768 +*/ +const UWord32 exp2x_tab_long_lc3plus[32] = { + 0x40000000, 0x400058B9, 0x4000B173, 0x40010A2D, 0x400162E8, 0x4001BBA3, 0x4002145F, 0x40026D1B, + 0x4002C5D8, 0x40031E95, 0x40037752, 0x4003D011, 0x400428CF, 0x4004818E, 0x4004DA4E, 0x4005330E, + 0x40058BCE, 0x4005E48F, 0x40063D51, 0x40069613, 0x4006EED5, 0x40074798, 0x4007A05B, 0x4007F91F, + 0x400851E4, 0x4008AAA8, 0x4009036E, 0x40095C33, 0x4009B4FA, 0x400A0DC0, 0x400A6688, 0x400ABF4F, +}; + +/* square root tables */ +const Word32 SqrtTable_lc3plus[32] = { + /* Q31 */ + 0x5A82D429, 0x5BEA10FE, 0x5D4BE6E5, 0x5EA89270, 0x60004BE2, 0x615347A1, 0x62A1B68C, 0x63EBC651, + 0x6531A1B5, 0x667370D4, 0x67B1595F, 0x68EB7EC8, 0x6A220277, 0x6B5503F0, 0x6C84A0F9, 0x6DB0F5BD, + 0x6EDA1CE9, 0x70002FC7, 0x7123465A, 0x72437773, 0x7360D8C5, 0x747B7EFA, 0x75937DC4, 0x76A8E7EB, + 0x77BBCF60, 0x78CC4545, 0x79DA5A00, 0x7AE61D3E, 0x7BEF9E07, 0x7CF6EAC2, 0x7DFC113F, 0x7EFF1EC0, +}; + +const Word16 SqrtDiffTable_lc3plus[32] = { + /* Q21 */ + 0x59CF, 0x5875, 0x572B, 0x55EE, 0x54BF, 0x539C, 0x5284, 0x5177, 0x5074, 0x4F7A, 0x4E89, + 0x4DA1, 0x4CC0, 0x4BE7, 0x4B15, 0x4A4A, 0x4985, 0x48C6, 0x480C, 0x4758, 0x46AA, 0x4600, + 0x455B, 0x44BA, 0x441D, 0x4385, 0x42F1, 0x4260, 0x41D3, 0x414A, 0x40C3, 0x4040, +}; + +const Word32 ISqrtTable_lc3plus[32] = { + /* Q31 */ + 0x7FFE7F85, 0x7E0A4E25, 0x7C2C56C7, 0x7A63002C, 0x78ACD922, 0x7708939D, 0x75750088, 0x73F10C2D, + 0x727BBB1A, 0x71142774, 0x6FB97EA5, 0x6E6AFF54, 0x6D27F79D, 0x6BEFC388, 0x6AC1CBA4, 0x699D83DA, + 0x68826A53, 0x6770068E, 0x6665E882, 0x6563A7DF, 0x6468E364, 0x63754043, 0x62886999, 0x61A20FEE, + 0x60C1E8C8, 0x5FE7AE45, 0x5F131EBE, 0x5E43FC76, 0x5D7A0D4F, 0x5CB51A81, 0x5BF4F061, 0x5B395E26, +}; + +const Word16 ISqrtDiffTable_lc3plus[32] = { + /* Q21 */ + 0x7D0C, 0x777E, 0x7256, 0x6D8A, 0x6911, 0x64E5, 0x60FD, 0x5D54, 0x59E5, 0x56AA, 0x53A0, + 0x50C2, 0x4E0D, 0x4B7E, 0x4912, 0x46C6, 0x4499, 0x4288, 0x4090, 0x3EB1, 0x3CE9, 0x3B36, + 0x3996, 0x380A, 0x368F, 0x3524, 0x33C9, 0x327C, 0x313D, 0x300B, 0x2EE5, 0x2DCA, +}; + +/* 1/x tables */ +const Word32 InvTable_lc3plus[32] = { + /* Q31 */ + 0x7FFBFE40, 0x7C1B608E, 0x78752176, 0x750440BA, 0x71C44C49, 0x6EB14D0A, 0x6BC7B6B4, 0x69045A19, + 0x6664598A, 0x63E51EE2, 0x61845308, 0x5F3FD698, 0x5D15BB8E, 0x5B043FD0, 0x5909C861, 0x5724DD3C, + 0x555425B2, 0x53966532, 0x51EA787F, 0x504F5331, 0x4EC3FD84, 0x4D479267, 0x4BD93DBE, 0x4A783ADC, + 0x4923D31D, 0x47DB5CAE, 0x469E3974, 0x456BD608, 0x4443A8D9, 0x43253159, 0x420FF746, 0x41038A01, +}; + +#ifdef ENABLE_HR_MODE +const Word16 InvIntTable[74] = { + 32767, 32767, 16384, 10923, 8192, 6554, 5461, 4681, 4096, 3641, 3277, 2979, 2731, 2521, 2341, + 2185, 2048, 1928, 1820, 1725, 1638, 1560, 1489, 1425, 1365, 1311, 1260, 1214, 1170, 1130, + 1092, 1057, 1024, 993, 964, 936, 910, 886, 862, 840, 819, 799, 780, 762, 745, + 728, 712, 697, 683, 669, 655, 643, 630, 618, 607, 596, 585, 575, 565, 555, + 546, 537, 529, 520, 512, 504, 496, 489, 482, 475, 468, 462, 455, 449 +}; +#else +const Word16 InvIntTable[32] = { + 0x7FFF, 0x7FFF, 0x4000, 0x2AAB, 0x2000, 0x199A, 0x1555, 0x1249, 0x1000, 0x0E39, 0x0CCD, + 0x0BA3, 0x0AAB, 0x09D9, 0x0925, 0x0889, 0x0800, 0x0788, 0x071C, 0x06BD, 0x0666, 0x0618, + 0x05D1, 0x0591, 0x0555, 0x051F, 0x04EC, 0x04BE, 0x0492, 0x046A, 0x0444, 0x0421, +}; +#endif + +const Word16 InvDiffTable_lc3plus[32] = { + /* Q20 */ + 0x7C14, 0x74C8, 0x6E1C, 0x67FF, 0x6260, 0x5D33, 0x586C, 0x5400, 0x4FE7, 0x4C19, 0x4890, + 0x4543, 0x422F, 0x3F4F, 0x3C9D, 0x3A17, 0x37B8, 0x357E, 0x3365, 0x316B, 0x2F8D, 0x2DCB, + 0x2C20, 0x2A8D, 0x290F, 0x27A4, 0x264C, 0x2506, 0x23CF, 0x22A7, 0x218E, 0x2081, +}; + +/* + Sine tables + */ +# ifdef ENABLE_HR_MODE +const PWord32 SineTable480[] = { +# else +const PWord16 SineTable480[] = { +# endif + STCP(0x7fffffff, 0x00000000), STCP(0x7fffd315, 0x006b3b9b), STCP(0x7fff4c54, 0x00d676eb), + STCP(0x7ffe6bbf, 0x0141b1a5), STCP(0x7ffd3154, 0x01aceb7c), STCP(0x7ffb9d15, 0x02182427), + STCP(0x7ff9af04, 0x02835b5a), STCP(0x7ff76721, 0x02ee90c8), STCP(0x7ff4c56f, 0x0359c428), + STCP(0x7ff1c9ef, 0x03c4f52f), STCP(0x7fee74a2, 0x0430238f), STCP(0x7feac58d, 0x049b4f00), + STCP(0x7fe6bcb0, 0x05067734), STCP(0x7fe25a0f, 0x05719be2), STCP(0x7fdd9dad, 0x05dcbcbe), + STCP(0x7fd8878e, 0x0647d97c), STCP(0x7fd317b4, 0x06b2f1d2), STCP(0x7fcd4e24, 0x071e0575), + STCP(0x7fc72ae2, 0x07891418), STCP(0x7fc0adf2, 0x07f41d72), STCP(0x7fb9d759, 0x085f2137), + STCP(0x7fb2a71b, 0x08ca1f1b), STCP(0x7fab1d3d, 0x093516d4), STCP(0x7fa339c5, 0x09a00817), + STCP(0x7f9afcb9, 0x0a0af299), STCP(0x7f92661d, 0x0a75d60e), STCP(0x7f8975f9, 0x0ae0b22c), + STCP(0x7f802c52, 0x0b4b86a8), STCP(0x7f76892f, 0x0bb65336), STCP(0x7f6c8c96, 0x0c21178c), + STCP(0x7f62368f, 0x0c8bd35e), STCP(0x7f578721, 0x0cf68662), STCP(0x7f4c7e54, 0x0d61304e), + STCP(0x7f411c2f, 0x0dcbd0d5), STCP(0x7f3560b9, 0x0e3667ad), STCP(0x7f294bfd, 0x0ea0f48c), + STCP(0x7f1cde01, 0x0f0b7727), STCP(0x7f1016ce, 0x0f75ef33), STCP(0x7f02f66f, 0x0fe05c64), + STCP(0x7ef57cea, 0x104abe71), STCP(0x7ee7aa4c, 0x10b5150f), STCP(0x7ed97e9c, 0x111f5ff4), + STCP(0x7ecaf9e5, 0x11899ed3), STCP(0x7ebc1c31, 0x11f3d164), STCP(0x7eace58a, 0x125df75b), + STCP(0x7e9d55fc, 0x12c8106f), STCP(0x7e8d6d91, 0x13321c53), STCP(0x7e7d2c54, 0x139c1abf), + STCP(0x7e6c9251, 0x14060b68), STCP(0x7e5b9f93, 0x146fee03), STCP(0x7e4a5426, 0x14d9c245), + STCP(0x7e38b017, 0x154387e6), STCP(0x7e26b371, 0x15ad3e9a), STCP(0x7e145e42, 0x1616e618), + STCP(0x7e01b096, 0x16807e15), STCP(0x7deeaa7a, 0x16ea0646), STCP(0x7ddb4bfc, 0x17537e63), + STCP(0x7dc79529, 0x17bce621), STCP(0x7db3860f, 0x18263d36), STCP(0x7d9f1ebd, 0x188f8357), + STCP(0x7d8a5f40, 0x18f8b83c), STCP(0x7d7547a7, 0x1961db9b), STCP(0x7d5fd801, 0x19caed29), + STCP(0x7d4a105d, 0x1a33ec9c), STCP(0x7d33f0ca, 0x1a9cd9ac), STCP(0x7d1d7958, 0x1b05b40f), + STCP(0x7d06aa16, 0x1b6e7b7a), STCP(0x7cef8315, 0x1bd72fa4), STCP(0x7cd80464, 0x1c3fd045), + STCP(0x7cc02e15, 0x1ca85d12), STCP(0x7ca80038, 0x1d10d5c2), STCP(0x7c8f7ade, 0x1d793a0b), + STCP(0x7c769e18, 0x1de189a6), STCP(0x7c5d69f7, 0x1e49c447), STCP(0x7c43de8e, 0x1eb1e9a7), + STCP(0x7c29fbee, 0x1f19f97b), STCP(0x7c0fc22a, 0x1f81f37c), STCP(0x7bf53153, 0x1fe9d75f), + STCP(0x7bda497d, 0x2051a4dd), STCP(0x7bbf0aba, 0x20b95bac), STCP(0x7ba3751d, 0x2120fb83), + STCP(0x7b8788ba, 0x2188841a), STCP(0x7b6b45a5, 0x21eff528), STCP(0x7b4eabf1, 0x22574e65), + STCP(0x7b31bbb2, 0x22be8f87), STCP(0x7b1474fd, 0x2325b847), STCP(0x7af6d7e6, 0x238cc85d), + STCP(0x7ad8e482, 0x23f3bf7e), STCP(0x7aba9ae6, 0x245a9d65), STCP(0x7a9bfb27, 0x24c161c7), + STCP(0x7a7d055b, 0x25280c5e), STCP(0x7a5db997, 0x258e9ce0), STCP(0x7a3e17f2, 0x25f51307), + STCP(0x7a1e2082, 0x265b6e8a), STCP(0x79fdd35c, 0x26c1af22), STCP(0x79dd3098, 0x2727d486), + STCP(0x79bc384d, 0x278dde6e), STCP(0x799aea92, 0x27f3cc94), STCP(0x7979477d, 0x28599eb0), + STCP(0x79574f28, 0x28bf547b), STCP(0x793501a9, 0x2924edac), STCP(0x79125f19, 0x298a69fc), + STCP(0x78ef678f, 0x29efc925), STCP(0x78cc1b26, 0x2a550adf), STCP(0x78a879f4, 0x2aba2ee4), + STCP(0x78848414, 0x2b1f34eb), STCP(0x7860399e, 0x2b841caf), STCP(0x783b9aad, 0x2be8e5e8), + STCP(0x7816a759, 0x2c4d9050), STCP(0x77f15fbc, 0x2cb21ba0), STCP(0x77cbc3f2, 0x2d168792), + STCP(0x77a5d413, 0x2d7ad3de), STCP(0x777f903c, 0x2ddf0040), STCP(0x7758f886, 0x2e430c6f), + STCP(0x77320d0d, 0x2ea6f827), STCP(0x770acdec, 0x2f0ac320), STCP(0x76e33b3f, 0x2f6e6d16), + STCP(0x76bb5521, 0x2fd1f5c1), STCP(0x76931bae, 0x30355cdd), STCP(0x766a8f04, 0x3098a223), + STCP(0x7641af3d, 0x30fbc54d), STCP(0x76187c77, 0x315ec617), STCP(0x75eef6ce, 0x31c1a43b), + STCP(0x75c51e61, 0x32245f72), STCP(0x759af34c, 0x3286f779), STCP(0x757075ac, 0x32e96c09), + STCP(0x7545a5a0, 0x334bbcde), STCP(0x751a8346, 0x33ade9b3), STCP(0x74ef0ebc, 0x340ff242), + STCP(0x74c34820, 0x3471d647), STCP(0x74972f92, 0x34d3957e), STCP(0x746ac52f, 0x35352fa1), + STCP(0x743e0918, 0x3596a46c), STCP(0x7410fb6b, 0x35f7f39c), STCP(0x73e39c49, 0x36591cea), + STCP(0x73b5ebd1, 0x36ba2014), STCP(0x7387ea23, 0x371afcd5), STCP(0x73599760, 0x377bb2e9), + STCP(0x732af3a7, 0x37dc420c), STCP(0x72fbff1b, 0x383ca9fb), STCP(0x72ccb9db, 0x389cea72), + STCP(0x729d2409, 0x38fd032d), STCP(0x726d3dc6, 0x395cf3e9), STCP(0x723d0734, 0x39bcbc63), + STCP(0x720c8075, 0x3a1c5c57), STCP(0x71dba9ab, 0x3a7bd382), STCP(0x71aa82f7, 0x3adb21a1), + STCP(0x71790c7e, 0x3b3a4672), STCP(0x71474660, 0x3b9941b1), STCP(0x711530c2, 0x3bf8131c), + STCP(0x70e2cbc6, 0x3c56ba70), STCP(0x70b01790, 0x3cb5376b), STCP(0x707d1443, 0x3d1389cb), + STCP(0x7049c203, 0x3d71b14d), STCP(0x701620f5, 0x3dcfadb0), STCP(0x6fe2313c, 0x3e2d7eb1), + STCP(0x6fadf2fc, 0x3e8b240e), STCP(0x6f79665b, 0x3ee89d86), STCP(0x6f448b7e, 0x3f45ead8), + STCP(0x6f0f6289, 0x3fa30bc1), STCP(0x6ed9eba1, 0x40000000), STCP(0x6ea426ed, 0x405cc754), + STCP(0x6e6e1492, 0x40b9617d), STCP(0x6e37b4b6, 0x4115ce38), STCP(0x6e010780, 0x41720d46), + STCP(0x6dca0d14, 0x41ce1e65), STCP(0x6d92c59b, 0x422a0154), STCP(0x6d5b313b, 0x4285b5d4), + STCP(0x6d23501b, 0x42e13ba4), STCP(0x6ceb2261, 0x433c9283), STCP(0x6cb2a837, 0x4397ba32), + STCP(0x6c79e1c2, 0x43f2b271), STCP(0x6c40cf2c, 0x444d7aff), STCP(0x6c07709b, 0x44a8139e), + STCP(0x6bcdc639, 0x45027c0c), STCP(0x6b93d02e, 0x455cb40c), STCP(0x6b598ea3, 0x45b6bb5e), + STCP(0x6b1f01c0, 0x461091c2), STCP(0x6ae429ae, 0x466a36f9), STCP(0x6aa90697, 0x46c3aac5), + STCP(0x6a6d98a4, 0x471cece7), STCP(0x6a31e000, 0x4775fd1f), STCP(0x69f5dcd3, 0x47cedb31), + STCP(0x69b98f48, 0x482786dc), STCP(0x697cf78a, 0x487fffe4), STCP(0x694015c3, 0x48d84609), + STCP(0x6902ea1d, 0x4930590f), STCP(0x68c574c4, 0x498838b6), STCP(0x6887b5e2, 0x49dfe4c2), + STCP(0x6849ada3, 0x4a375cf5), STCP(0x680b5c33, 0x4a8ea111), STCP(0x67ccc1be, 0x4ae5b0da), + STCP(0x678dde6e, 0x4b3c8c12), STCP(0x674eb271, 0x4b93327c), STCP(0x670f3df3, 0x4be9a3db), + STCP(0x66cf8120, 0x4c3fdff4), STCP(0x668f7c25, 0x4c95e688), STCP(0x664f2f2e, 0x4cebb75c), + STCP(0x660e9a6a, 0x4d415234), STCP(0x65cdbe05, 0x4d96b6d3), STCP(0x658c9a2d, 0x4debe4fe), + STCP(0x654b2f10, 0x4e40dc79), STCP(0x65097cdb, 0x4e959d08), STCP(0x64c783bd, 0x4eea2670), + STCP(0x648543e4, 0x4f3e7875), STCP(0x6442bd7e, 0x4f9292dc), STCP(0x63fff0ba, 0x4fe6756a), + STCP(0x63bcddc7, 0x503a1fe5), STCP(0x637984d4, 0x508d9211), STCP(0x6335e611, 0x50e0cbb4), + STCP(0x62f201ac, 0x5133cc94), STCP(0x62add7d6, 0x51869476), STCP(0x626968be, 0x51d92321), + STCP(0x6224b495, 0x522b7859), STCP(0x61dfbb8a, 0x527d93e6), STCP(0x619a7dce, 0x52cf758f), + STCP(0x6154fb91, 0x53211d18), STCP(0x610f3505, 0x53728a4a), STCP(0x60c92a5a, 0x53c3bcea), + STCP(0x6082dbc1, 0x5414b4c1), STCP(0x603c496c, 0x54657194), STCP(0x5ff5738d, 0x54b5f32c), + STCP(0x5fae5a55, 0x55063951), STCP(0x5f66fdf5, 0x555643c8), STCP(0x5f1f5ea1, 0x55a6125c), + STCP(0x5ed77c8a, 0x55f5a4d2), STCP(0x5e8f57e2, 0x5644faf4), STCP(0x5e46f0dd, 0x5694148b), + STCP(0x5dfe47ad, 0x56e2f15d), STCP(0x5db55c86, 0x57319135), STCP(0x5d6c2f99, 0x577ff3da), + STCP(0x5d22c11c, 0x57ce1917), STCP(0x5cd91140, 0x581c00b3), STCP(0x5c8f203b, 0x5869aa79), + STCP(0x5c44ee40, 0x58b71632), STCP(0x5bfa7b82, 0x590443a7), STCP(0x5bafc837, 0x595132a2), + STCP(0x5b64d492, 0x599de2ee), STCP(0x5b19a0c8, 0x59ea5454), STCP(0x5ace2d0f, 0x5a36869f), + STCP(0x5a82799a, 0x5a82799a), +}; + +# ifdef ENABLE_HR_MODE +const PWord32 SineTable360[] = { +# else +const PWord16 SineTable360[] = { +# endif + STCP(0x7fffffff, 0x00000000), STCP(0x7fffb025, 0x008efa17), STCP(0x7ffec095, 0x011df37c), + STCP(0x7ffd3153, 0x01aceb7c), STCP(0x7ffb025f, 0x023be165), STCP(0x7ff833bc, 0x02cad485), + STCP(0x7ff4c56e, 0x0359c428), STCP(0x7ff0b779, 0x03e8af9e), STCP(0x7fec09e2, 0x04779632), + STCP(0x7fe6bcaf, 0x05067734), STCP(0x7fe0cfe6, 0x059551f1), STCP(0x7fda4390, 0x062425b6), + STCP(0x7fd317b3, 0x06b2f1d2), STCP(0x7fcb4c5a, 0x0741b592), STCP(0x7fc2e18d, 0x07d07044), + STCP(0x7fb9d758, 0x085f2136), STCP(0x7fb02dc5, 0x08edc7b7), STCP(0x7fa5e4e0, 0x097c6313), + STCP(0x7f9afcb8, 0x0a0af299), STCP(0x7f8f7558, 0x0a997597), STCP(0x7f834ecf, 0x0b27eb5c), + STCP(0x7f76892e, 0x0bb65336), STCP(0x7f692482, 0x0c44ac72), STCP(0x7f5b20de, 0x0cd2f660), + STCP(0x7f4c7e53, 0x0d61304e), STCP(0x7f3d3cf3, 0x0def5989), STCP(0x7f2d5cd0, 0x0e7d7162), + STCP(0x7f1cde00, 0x0f0b7727), STCP(0x7f0bc096, 0x0f996a26), STCP(0x7efa04a7, 0x102749ae), + STCP(0x7ee7aa4b, 0x10b5150f), STCP(0x7ed4b197, 0x1142cb98), STCP(0x7ec11aa4, 0x11d06c96), + STCP(0x7eace589, 0x125df75b), STCP(0x7e981261, 0x12eb6b35), STCP(0x7e82a145, 0x1378c774), + STCP(0x7e6c9250, 0x14060b68), STCP(0x7e55e59d, 0x1493365f), STCP(0x7e3e9b49, 0x152047ab), + STCP(0x7e26b370, 0x15ad3e9a), STCP(0x7e0e2e31, 0x163a1a7e), STCP(0x7df50baa, 0x16c6daa6), + STCP(0x7ddb4bfb, 0x17537e63), STCP(0x7dc0ef43, 0x17e00505), STCP(0x7da5f5a4, 0x186c6ddd), + STCP(0x7d8a5f3f, 0x18f8b83c), STCP(0x7d6e2c36, 0x1984e373), STCP(0x7d515cae, 0x1a10eed2), + STCP(0x7d33f0c9, 0x1a9cd9ac), STCP(0x7d15e8ac, 0x1b28a351), STCP(0x7cf7447e, 0x1bb44b13), + STCP(0x7cd80464, 0x1c3fd045), STCP(0x7cb82884, 0x1ccb3237), STCP(0x7c97b108, 0x1d56703b), + STCP(0x7c769e17, 0x1de189a5), STCP(0x7c54efdb, 0x1e6c7dc7), STCP(0x7c32a67d, 0x1ef74bf3), + STCP(0x7c0fc229, 0x1f81f37b), STCP(0x7bec430a, 0x200c73b4), STCP(0x7bc8294c, 0x2096cbf0), + STCP(0x7ba3751c, 0x2120fb83), STCP(0x7b7e26a9, 0x21ab01c0), STCP(0x7b583e20, 0x2234ddfa), + STCP(0x7b31bbb1, 0x22be8f87), STCP(0x7b0a9f8d, 0x234815ba), STCP(0x7ae2e9e3, 0x23d16fe8), + STCP(0x7aba9ae5, 0x245a9d64), STCP(0x7a91b2c6, 0x24e39d85), STCP(0x7a6831b9, 0x256c6f9f), + STCP(0x7a3e17f1, 0x25f51307), STCP(0x7a1365a4, 0x267d8713), STCP(0x79e81b05, 0x2705cb19), + STCP(0x79bc384c, 0x278dde6e), STCP(0x798fbdaf, 0x2815c069), STCP(0x7962ab66, 0x289d7061), + STCP(0x793501a8, 0x2924edab), STCP(0x7906c0af, 0x29ac37a0), STCP(0x78d7e8b5, 0x2a334d95), + STCP(0x78a879f3, 0x2aba2ee3), STCP(0x787874a6, 0x2b40dae2), STCP(0x7847d908, 0x2bc750e9), + STCP(0x7816a758, 0x2c4d9050), STCP(0x77e4dfd1, 0x2cd39870), STCP(0x77b282b3, 0x2d5968a2), + STCP(0x777f903b, 0x2ddf003f), STCP(0x774c08aa, 0x2e645ea0), STCP(0x7717ec40, 0x2ee9831f), + STCP(0x76e33b3e, 0x2f6e6d15), STCP(0x76adf5e5, 0x2ff31bdd), STCP(0x76781c79, 0x30778ed2), + STCP(0x7641af3c, 0x30fbc54d), STCP(0x760aae72, 0x317fbeaa), STCP(0x75d31a60, 0x32037a45), + STCP(0x759af34b, 0x3286f778), STCP(0x75623979, 0x330a35a1), STCP(0x7528ed31, 0x338d341a), + STCP(0x74ef0ebb, 0x340ff242), STCP(0x74b49e5f, 0x34926f74), STCP(0x74799c65, 0x3514ab0d), + STCP(0x743e0917, 0x3596a46c), STCP(0x7401e4c0, 0x36185aee), STCP(0x73c52faa, 0x3699cdf1), + STCP(0x7387ea22, 0x371afcd4), STCP(0x734a1474, 0x379be6f6), STCP(0x730baeec, 0x381c8bb5), + STCP(0x72ccb9da, 0x389cea71), STCP(0x728d358b, 0x391d028b), STCP(0x724d224e, 0x399cd362), + STCP(0x720c8074, 0x3a1c5c56), STCP(0x71cb504d, 0x3a9b9cc9), STCP(0x7189922b, 0x3b1a941c), + STCP(0x7147465f, 0x3b9941b0), STCP(0x71046d3d, 0x3c17a4e8), STCP(0x70c10717, 0x3c95bd25), + STCP(0x707d1442, 0x3d1389cb), STCP(0x70389513, 0x3d910a3c), STCP(0x6ff389de, 0x3e0e3ddb), + STCP(0x6fadf2fb, 0x3e8b240e), STCP(0x6f67d0c0, 0x3f07bc37), STCP(0x6f212384, 0x3f8405bb), + STCP(0x6ed9eba1, 0x3fffffff), STCP(0x6e92296d, 0x407baa69), STCP(0x6e49dd44, 0x40f7045f), + STCP(0x6e01077f, 0x41720d45), STCP(0x6db7a879, 0x41ecc483), STCP(0x6d6dc08e, 0x42672980), + STCP(0x6d23501a, 0x42e13ba3), STCP(0x6cd85779, 0x435afa54), STCP(0x6c8cd70a, 0x43d464fa), + STCP(0x6c40cf2b, 0x444d7aff), STCP(0x6bf4403a, 0x44c63bca), STCP(0x6ba72a97, 0x453ea6c7), + STCP(0x6b598ea2, 0x45b6bb5d), STCP(0x6b0b6cbc, 0x462e78f8), STCP(0x6abcc546, 0x46a5df02), + STCP(0x6a6d98a3, 0x471cece6), STCP(0x6a1de736, 0x4793a210), STCP(0x69cdb161, 0x4809fdeb), + STCP(0x697cf789, 0x487fffe3), STCP(0x692bba13, 0x48f5a767), STCP(0x68d9f964, 0x496af3e1), + STCP(0x6887b5e1, 0x49dfe4c2), STCP(0x6834eff2, 0x4a547975), STCP(0x67e1a7ff, 0x4ac8b16b), + STCP(0x678dde6e, 0x4b3c8c11), STCP(0x673993a8, 0x4bb008d8), STCP(0x66e4c817, 0x4c23272f), + STCP(0x668f7c24, 0x4c95e687), STCP(0x6639b03a, 0x4d084651), STCP(0x65e364c3, 0x4d7a45fd), + STCP(0x658c9a2d, 0x4debe4fe), STCP(0x653550e1, 0x4e5d22c5), STCP(0x64dd894f, 0x4ecdfec6), + STCP(0x648543e3, 0x4f3e7874), STCP(0x642c810b, 0x4fae8f42), STCP(0x63d34136, 0x501e42a5), + STCP(0x637984d4, 0x508d9211), STCP(0x631f4c54, 0x50fc7cfa), STCP(0x62c49826, 0x516b02d8), + STCP(0x626968be, 0x51d92320), STCP(0x620dbe8a, 0x5246dd48), STCP(0x61b19a00, 0x52b430c8), + STCP(0x6154fb90, 0x53211d17), STCP(0x60f7e3b0, 0x538da1ae), STCP(0x609a52d2, 0x53f9be04), + STCP(0x603c496c, 0x54657194), STCP(0x5fddc7f3, 0x54d0bbd6), STCP(0x5f7ecedd, 0x553b9c45), + STCP(0x5f1f5ea0, 0x55a6125b), STCP(0x5ebf77b4, 0x56101d94), STCP(0x5e5f1a90, 0x5679bd6b), + STCP(0x5dfe47ad, 0x56e2f15d), STCP(0x5d9cff82, 0x574bb8e6), STCP(0x5d3b428b, 0x57b41383), + STCP(0x5cd91140, 0x581c00b3), STCP(0x5c766c1c, 0x58837ff3), STCP(0x5c13539a, 0x58ea90c3), + STCP(0x5bafc836, 0x595132a2), STCP(0x5b4bca6c, 0x59b7650f), STCP(0x5ae75ab8, 0x5a1d278c), + STCP(0x5a827999, 0x5a827999), +}; + +# ifdef ENABLE_HR_MODE +const PWord32 SineTable320[] = { +# else +const PWord16 SineTable320[] = { +# endif + STCP(0x7fffffff, 0x00000000), STCP(0x7fff9aef, 0x00a0d951), STCP(0x7ffe6bbf, 0x0141b1a5), + STCP(0x7ffc726f, 0x01e287fc), STCP(0x7ff9af04, 0x02835b5a), STCP(0x7ff62182, 0x03242abf), + STCP(0x7ff1c9ef, 0x03c4f52f), STCP(0x7feca851, 0x0465b9aa), STCP(0x7fe6bcb0, 0x05067734), + STCP(0x7fe00716, 0x05a72ccf), STCP(0x7fd8878e, 0x0647d97c), STCP(0x7fd03e23, 0x06e87c3f), + STCP(0x7fc72ae2, 0x07891418), STCP(0x7fbd4dda, 0x0829a00c), STCP(0x7fb2a71b, 0x08ca1f1b), + STCP(0x7fa736b4, 0x096a9049), STCP(0x7f9afcb9, 0x0a0af299), STCP(0x7f8df93c, 0x0aab450d), + STCP(0x7f802c52, 0x0b4b86a8), STCP(0x7f719611, 0x0bebb66c), STCP(0x7f62368f, 0x0c8bd35e), + STCP(0x7f520de6, 0x0d2bdc80), STCP(0x7f411c2f, 0x0dcbd0d5), STCP(0x7f2f6183, 0x0e6baf61), + STCP(0x7f1cde01, 0x0f0b7727), STCP(0x7f0991c4, 0x0fab272b), STCP(0x7ef57cea, 0x104abe71), + STCP(0x7ee09f95, 0x10ea3bfd), STCP(0x7ecaf9e5, 0x11899ed3), STCP(0x7eb48bfb, 0x1228e5f8), + STCP(0x7e9d55fc, 0x12c8106f), STCP(0x7e85580c, 0x13671d3d), STCP(0x7e6c9251, 0x14060b68), + STCP(0x7e5304f2, 0x14a4d9f4), STCP(0x7e38b017, 0x154387e6), STCP(0x7e1d93ea, 0x15e21445), + STCP(0x7e01b096, 0x16807e15), STCP(0x7de50646, 0x171ec45c), STCP(0x7dc79529, 0x17bce621), + STCP(0x7da95d6c, 0x185ae269), STCP(0x7d8a5f40, 0x18f8b83c), STCP(0x7d6a9ad5, 0x199666a0), + STCP(0x7d4a105d, 0x1a33ec9c), STCP(0x7d28c00c, 0x1ad14938), STCP(0x7d06aa16, 0x1b6e7b7a), + STCP(0x7ce3ceb2, 0x1c0b826a), STCP(0x7cc02e15, 0x1ca85d12), STCP(0x7c9bc87a, 0x1d450a78), + STCP(0x7c769e18, 0x1de189a6), STCP(0x7c50af2b, 0x1e7dd9a4), STCP(0x7c29fbee, 0x1f19f97b), + STCP(0x7c02849f, 0x1fb5e836), STCP(0x7bda497d, 0x2051a4dd), STCP(0x7bb14ac5, 0x20ed2e7b), + STCP(0x7b8788ba, 0x2188841a), STCP(0x7b5d039e, 0x2223a4c5), STCP(0x7b31bbb2, 0x22be8f87), + STCP(0x7b05b13d, 0x2359436c), STCP(0x7ad8e482, 0x23f3bf7e), STCP(0x7aab55ca, 0x248e02cb), + STCP(0x7a7d055b, 0x25280c5e), STCP(0x7a4df380, 0x25c1db44), STCP(0x7a1e2082, 0x265b6e8a), + STCP(0x79ed8cad, 0x26f4c53e), STCP(0x79bc384d, 0x278dde6e), STCP(0x798a23b1, 0x2826b928), + STCP(0x79574f28, 0x28bf547b), STCP(0x7923bb01, 0x2957af74), STCP(0x78ef678f, 0x29efc925), + STCP(0x78ba5524, 0x2a87a09d), STCP(0x78848414, 0x2b1f34eb), STCP(0x784df4b3, 0x2bb68522), + STCP(0x7816a759, 0x2c4d9050), STCP(0x77de9c5b, 0x2ce45589), STCP(0x77a5d413, 0x2d7ad3de), + STCP(0x776c4edb, 0x2e110a62), STCP(0x77320d0d, 0x2ea6f827), STCP(0x76f70f05, 0x2f3c9c40), + STCP(0x76bb5521, 0x2fd1f5c1), STCP(0x767edfbe, 0x306703bf), STCP(0x7641af3d, 0x30fbc54d), + STCP(0x7603c3fd, 0x31903982), STCP(0x75c51e61, 0x32245f72), STCP(0x7585becb, 0x32b83634), + STCP(0x7545a5a0, 0x334bbcde), STCP(0x7504d345, 0x33def287), STCP(0x74c34820, 0x3471d647), + STCP(0x74810499, 0x35046736), STCP(0x743e0918, 0x3596a46c), STCP(0x73fa5607, 0x36288d03), + STCP(0x73b5ebd1, 0x36ba2014), STCP(0x7370cae2, 0x374b5cb9), STCP(0x732af3a7, 0x37dc420c), + STCP(0x72e4668f, 0x386ccf2a), STCP(0x729d2409, 0x38fd032d), STCP(0x72552c85, 0x398cdd32), + STCP(0x720c8075, 0x3a1c5c57), STCP(0x71c3204c, 0x3aab7fb7), STCP(0x71790c7e, 0x3b3a4672), + STCP(0x712e457f, 0x3bc8afa5), STCP(0x70e2cbc6, 0x3c56ba70), STCP(0x70969fca, 0x3ce465f3), + STCP(0x7049c203, 0x3d71b14d), STCP(0x6ffc32eb, 0x3dfe9ba1), STCP(0x6fadf2fc, 0x3e8b240e), + STCP(0x6f5f02b2, 0x3f1749b8), STCP(0x6f0f6289, 0x3fa30bc1), STCP(0x6ebf12ff, 0x402e694c), + STCP(0x6e6e1492, 0x40b9617d), STCP(0x6e1c67c4, 0x4143f379), STCP(0x6dca0d14, 0x41ce1e65), + STCP(0x6d770506, 0x4257e166), STCP(0x6d23501b, 0x42e13ba4), STCP(0x6cceeed8, 0x436a2c45), + STCP(0x6c79e1c2, 0x43f2b271), STCP(0x6c242960, 0x447acd50), STCP(0x6bcdc639, 0x45027c0c), + STCP(0x6b76b8d6, 0x4589bdcf), STCP(0x6b1f01c0, 0x461091c2), STCP(0x6ac6a180, 0x4696f710), + STCP(0x6a6d98a4, 0x471cece7), STCP(0x6a13e7b8, 0x47a27271), STCP(0x69b98f48, 0x482786dc), + STCP(0x695e8fe5, 0x48ac2957), STCP(0x6902ea1d, 0x4930590f), STCP(0x68a69e81, 0x49b41533), + STCP(0x6849ada3, 0x4a375cf5), STCP(0x67ec1817, 0x4aba2f84), STCP(0x678dde6e, 0x4b3c8c12), + STCP(0x672f013f, 0x4bbe71d1), STCP(0x66cf8120, 0x4c3fdff4), STCP(0x666f5ea6, 0x4cc0d5ae), + STCP(0x660e9a6a, 0x4d415234), STCP(0x65ad3505, 0x4dc154bb), STCP(0x654b2f10, 0x4e40dc79), + STCP(0x64e88926, 0x4ebfe8a5), STCP(0x648543e4, 0x4f3e7875), STCP(0x64215fe5, 0x4fbc8b22), + STCP(0x63bcddc7, 0x503a1fe5), STCP(0x6357be2a, 0x50b735f8), STCP(0x62f201ac, 0x5133cc94), + STCP(0x628ba8ef, 0x51afe2f6), STCP(0x6224b495, 0x522b7859), STCP(0x61bd253f, 0x52a68bfb), + STCP(0x6154fb91, 0x53211d18), STCP(0x60ec3830, 0x539b2af0), STCP(0x6082dbc1, 0x5414b4c1), + STCP(0x6018e6eb, 0x548db9cb), STCP(0x5fae5a55, 0x55063951), STCP(0x5f4336a7, 0x557e3292), + STCP(0x5ed77c8a, 0x55f5a4d2), STCP(0x5e6b2ca8, 0x566c8f55), STCP(0x5dfe47ad, 0x56e2f15d), + STCP(0x5d90ce45, 0x5758ca31), STCP(0x5d22c11c, 0x57ce1917), STCP(0x5cb420e0, 0x5842dd54), + STCP(0x5c44ee40, 0x58b71632), STCP(0x5bd529eb, 0x592ac2f7), STCP(0x5b64d492, 0x599de2ee), + STCP(0x5af3eee6, 0x5a107561), STCP(0x5a82799a, 0x5a82799a), +}; + + +# ifdef ENABLE_HR_MODE +#ifdef CR8_G_ADD_75MS + const PWord32 SineTable720[] = { + STCP(0x7fffffff, 0x00000000), STCP(0x7fffec08, 0x00477d17), STCP(0x7fffb025, 0x008efa17), + STCP(0x7fff4c53, 0x00d676eb), STCP(0x7ffec095, 0x011df37c), STCP(0x7ffe0cea, 0x01656fb4), + STCP(0x7ffd3153, 0x01aceb7c), STCP(0x7ffc2dcf, 0x01f466bf), STCP(0x7ffb025f, 0x023be165), + STCP(0x7ff9af03, 0x02835b59), STCP(0x7ff833bc, 0x02cad485), STCP(0x7ff6908a, 0x03124cd1), + STCP(0x7ff4c56e, 0x0359c428), STCP(0x7ff2d268, 0x03a13a74), STCP(0x7ff0b779, 0x03e8af9e), + STCP(0x7fee74a1, 0x0430238f), STCP(0x7fec09e2, 0x04779632), STCP(0x7fe9773c, 0x04bf0771), + STCP(0x7fe6bcaf, 0x05067734), STCP(0x7fe3da3d, 0x054de566), STCP(0x7fe0cfe6, 0x059551f1), + STCP(0x7fdd9dac, 0x05dcbcbe), STCP(0x7fda4390, 0x062425b6), STCP(0x7fd6c192, 0x066b8cc5), + STCP(0x7fd317b3, 0x06b2f1d2), STCP(0x7fcf45f6, 0x06fa54c9), STCP(0x7fcb4c5a, 0x0741b592), + STCP(0x7fc72ae1, 0x07891418), STCP(0x7fc2e18d, 0x07d07044), STCP(0x7fbe705f, 0x0817ca01), + STCP(0x7fb9d758, 0x085f2136), STCP(0x7fb51679, 0x08a675d0), STCP(0x7fb02dc5, 0x08edc7b7), + STCP(0x7fab1d3c, 0x093516d4), STCP(0x7fa5e4e0, 0x097c6313), STCP(0x7fa084b4, 0x09c3ac5c), + STCP(0x7f9afcb8, 0x0a0af299), STCP(0x7f954cee, 0x0a5235b4), STCP(0x7f8f7558, 0x0a997597), + STCP(0x7f8975f8, 0x0ae0b22c), STCP(0x7f834ecf, 0x0b27eb5c), STCP(0x7f7cffe1, 0x0b6f2112), + STCP(0x7f76892e, 0x0bb65336), STCP(0x7f6feab8, 0x0bfd81b3), STCP(0x7f692482, 0x0c44ac72), + STCP(0x7f62368e, 0x0c8bd35e), STCP(0x7f5b20de, 0x0cd2f660), STCP(0x7f53e374, 0x0d1a1562), + STCP(0x7f4c7e53, 0x0d61304e), STCP(0x7f44f17c, 0x0da8470d), STCP(0x7f3d3cf3, 0x0def5989), + STCP(0x7f3560b8, 0x0e3667ad), STCP(0x7f2d5cd0, 0x0e7d7162), STCP(0x7f25313c, 0x0ec47692), + STCP(0x7f1cde00, 0x0f0b7727), STCP(0x7f14631c, 0x0f52730a), STCP(0x7f0bc096, 0x0f996a26), + STCP(0x7f02f66e, 0x0fe05c64), STCP(0x7efa04a7, 0x102749ae), STCP(0x7ef0eb45, 0x106e31ef), + STCP(0x7ee7aa4b, 0x10b5150f), STCP(0x7ede41ba, 0x10fbf2fa), STCP(0x7ed4b197, 0x1142cb98), + STCP(0x7ecaf9e4, 0x11899ed3), STCP(0x7ec11aa4, 0x11d06c96), STCP(0x7eb713da, 0x121734cb), + STCP(0x7eace589, 0x125df75b), STCP(0x7ea28fb5, 0x12a4b431), STCP(0x7e981261, 0x12eb6b35), + STCP(0x7e8d6d90, 0x13321c53), STCP(0x7e82a145, 0x1378c774), STCP(0x7e77ad84, 0x13bf6c82), + STCP(0x7e6c9250, 0x14060b68), STCP(0x7e614fac, 0x144ca40e), STCP(0x7e55e59d, 0x1493365f), + STCP(0x7e4a5425, 0x14d9c245), STCP(0x7e3e9b49, 0x152047ab), STCP(0x7e32bb0b, 0x1566c679), + STCP(0x7e26b370, 0x15ad3e9a), STCP(0x7e1a847b, 0x15f3aff8), STCP(0x7e0e2e31, 0x163a1a7e), + STCP(0x7e01b095, 0x16807e14), STCP(0x7df50baa, 0x16c6daa6), STCP(0x7de83f76, 0x170d301d), + STCP(0x7ddb4bfb, 0x17537e63), STCP(0x7dce313e, 0x1799c562), STCP(0x7dc0ef43, 0x17e00505), + STCP(0x7db3860e, 0x18263d35), STCP(0x7da5f5a4, 0x186c6ddd), STCP(0x7d983e08, 0x18b296e7), + STCP(0x7d8a5f3f, 0x18f8b83c), STCP(0x7d7c594d, 0x193ed1c8), STCP(0x7d6e2c36, 0x1984e373), + STCP(0x7d5fd800, 0x19caed28), STCP(0x7d515cae, 0x1a10eed2), STCP(0x7d42ba45, 0x1a56e85b), + STCP(0x7d33f0c9, 0x1a9cd9ac), STCP(0x7d25003f, 0x1ae2c2b0), STCP(0x7d15e8ac, 0x1b28a351), + STCP(0x7d06aa15, 0x1b6e7b7a), STCP(0x7cf7447e, 0x1bb44b13), STCP(0x7ce7b7ec, 0x1bfa1209), + STCP(0x7cd80464, 0x1c3fd045), STCP(0x7cc829ea, 0x1c8585b0), STCP(0x7cb82884, 0x1ccb3237), + STCP(0x7ca80037, 0x1d10d5c1), STCP(0x7c97b108, 0x1d56703b), STCP(0x7c873afb, 0x1d9c018f), + STCP(0x7c769e17, 0x1de189a5), STCP(0x7c65da60, 0x1e27086a), STCP(0x7c54efdb, 0x1e6c7dc7), + STCP(0x7c43de8d, 0x1eb1e9a6), STCP(0x7c32a67d, 0x1ef74bf3), STCP(0x7c2147af, 0x1f3ca496), + STCP(0x7c0fc229, 0x1f81f37b), STCP(0x7bfe15f0, 0x1fc7388d), STCP(0x7bec430a, 0x200c73b4), + STCP(0x7bda497c, 0x2051a4dd), STCP(0x7bc8294c, 0x2096cbf0), STCP(0x7bb5e27f, 0x20dbe8da), + STCP(0x7ba3751c, 0x2120fb83), STCP(0x7b90e128, 0x216603d7), STCP(0x7b7e26a9, 0x21ab01c0), + STCP(0x7b6b45a4, 0x21eff528), STCP(0x7b583e20, 0x2234ddfa), STCP(0x7b451022, 0x2279bc21), + STCP(0x7b31bbb1, 0x22be8f87), STCP(0x7b1e40d3, 0x23035817), STCP(0x7b0a9f8d, 0x234815ba), + STCP(0x7af6d7e5, 0x238cc85c), STCP(0x7ae2e9e3, 0x23d16fe8), STCP(0x7aced58b, 0x24160c47), + STCP(0x7aba9ae5, 0x245a9d64), STCP(0x7aa639f7, 0x249f232b), STCP(0x7a91b2c6, 0x24e39d85), + STCP(0x7a7d055a, 0x25280c5d), STCP(0x7a6831b9, 0x256c6f9f), STCP(0x7a5337e9, 0x25b0c734), + STCP(0x7a3e17f1, 0x25f51307), STCP(0x7a28d1d8, 0x26395303), STCP(0x7a1365a4, 0x267d8713), + STCP(0x79fdd35b, 0x26c1af21), STCP(0x79e81b05, 0x2705cb19), STCP(0x79d23ca9, 0x2749dae4), + STCP(0x79bc384c, 0x278dde6e), STCP(0x79a60df7, 0x27d1d5a2), STCP(0x798fbdaf, 0x2815c069), + STCP(0x7979477c, 0x28599eb0), STCP(0x7962ab66, 0x289d7061), STCP(0x794be972, 0x28e13566), + STCP(0x793501a8, 0x2924edab), STCP(0x791df40f, 0x2968991b), STCP(0x7906c0af, 0x29ac37a0), + STCP(0x78ef678e, 0x29efc925), STCP(0x78d7e8b5, 0x2a334d95), STCP(0x78c04429, 0x2a76c4dc), + STCP(0x78a879f3, 0x2aba2ee3), STCP(0x78908a1a, 0x2afd8b97), STCP(0x787874a6, 0x2b40dae2), + STCP(0x7860399d, 0x2b841caf), STCP(0x7847d908, 0x2bc750e9), STCP(0x782f52ef, 0x2c0a777b), + STCP(0x7816a758, 0x2c4d9050), STCP(0x77fdd64b, 0x2c909b54), STCP(0x77e4dfd1, 0x2cd39870), + STCP(0x77cbc3f1, 0x2d168792), STCP(0x77b282b3, 0x2d5968a2), STCP(0x77991c1e, 0x2d9c3b8e), + STCP(0x777f903b, 0x2ddf003f), STCP(0x7765df12, 0x2e21b6a2), STCP(0x774c08aa, 0x2e645ea0), + STCP(0x77320d0c, 0x2ea6f826), STCP(0x7717ec40, 0x2ee9831f), STCP(0x76fda64e, 0x2f2bff76), + STCP(0x76e33b3e, 0x2f6e6d15), STCP(0x76c8ab18, 0x2fb0cbea), STCP(0x76adf5e5, 0x2ff31bdd), + STCP(0x76931bae, 0x30355cdc), STCP(0x76781c79, 0x30778ed2), STCP(0x765cf850, 0x30b9b1a9), + STCP(0x7641af3c, 0x30fbc54d), STCP(0x76264144, 0x313dc9aa), STCP(0x760aae72, 0x317fbeaa), + STCP(0x75eef6ce, 0x31c1a43a), STCP(0x75d31a60, 0x32037a45), STCP(0x75b71931, 0x324540b6), + STCP(0x759af34b, 0x3286f778), STCP(0x757ea8b5, 0x32c89e78), STCP(0x75623979, 0x330a35a1), + STCP(0x7545a59f, 0x334bbcde), STCP(0x7528ed31, 0x338d341a), STCP(0x750c1038, 0x33ce9b42), + STCP(0x74ef0ebb, 0x340ff242), STCP(0x74d1e8c5, 0x34513903), STCP(0x74b49e5f, 0x34926f74), + STCP(0x74972f91, 0x34d3957e), STCP(0x74799c65, 0x3514ab0d), STCP(0x745be4e4, 0x3555b00e), + STCP(0x743e0917, 0x3596a46c), STCP(0x74200908, 0x35d78813), STCP(0x7401e4c0, 0x36185aee), + STCP(0x73e39c48, 0x36591cea), STCP(0x73c52faa, 0x3699cdf1), STCP(0x73a69ef0, 0x36da6df1), + STCP(0x7387ea22, 0x371afcd4), STCP(0x7369114b, 0x375b7a87), STCP(0x734a1474, 0x379be6f6), + STCP(0x732af3a6, 0x37dc420c), STCP(0x730baeec, 0x381c8bb5), STCP(0x72ec4650, 0x385cc3de), + STCP(0x72ccb9da, 0x389cea71), STCP(0x72ad0995, 0x38dcff5d), STCP(0x728d358b, 0x391d028b), + STCP(0x726d3dc5, 0x395cf3e9), STCP(0x724d224e, 0x399cd362), STCP(0x722ce330, 0x39dca0e2), + STCP(0x720c8074, 0x3a1c5c56), STCP(0x71ebfa25, 0x3a5c05aa), STCP(0x71cb504d, 0x3a9b9cc9), + STCP(0x71aa82f6, 0x3adb21a0), STCP(0x7189922b, 0x3b1a941c), STCP(0x71687df5, 0x3b59f428), + STCP(0x7147465f, 0x3b9941b0), STCP(0x7125eb74, 0x3bd87ca1), STCP(0x71046d3d, 0x3c17a4e8), + STCP(0x70e2cbc5, 0x3c56ba70), STCP(0x70c10717, 0x3c95bd25), STCP(0x709f1f3d, 0x3cd4acf5), + STCP(0x707d1442, 0x3d1389cb), STCP(0x705ae630, 0x3d525394), STCP(0x70389513, 0x3d910a3c), + STCP(0x701620f4, 0x3dcfadaf), STCP(0x6ff389de, 0x3e0e3ddb), STCP(0x6fd0cfdd, 0x3e4cbaac), + STCP(0x6fadf2fb, 0x3e8b240e), STCP(0x6f8af343, 0x3ec979ed), STCP(0x6f67d0c0, 0x3f07bc37), + STCP(0x6f448b7d, 0x3f45ead7), STCP(0x6f212384, 0x3f8405bb), STCP(0x6efd98e2, 0x3fc20ccf), + STCP(0x6ed9eba1, 0x3fffffff), STCP(0x6eb61bcb, 0x403ddf39), STCP(0x6e92296d, 0x407baa69), + STCP(0x6e6e1492, 0x40b9617c), STCP(0x6e49dd44, 0x40f7045f), STCP(0x6e25838f, 0x413492fd), + STCP(0x6e01077f, 0x41720d45), STCP(0x6ddc691e, 0x41af7323), STCP(0x6db7a879, 0x41ecc483), + STCP(0x6d92c59a, 0x422a0154), STCP(0x6d6dc08e, 0x42672980), STCP(0x6d48995f, 0x42a43cf7), + STCP(0x6d23501a, 0x42e13ba3), STCP(0x6cfde4c9, 0x431e2573), STCP(0x6cd85779, 0x435afa54), + STCP(0x6cb2a836, 0x4397ba32), STCP(0x6c8cd70a, 0x43d464fa), STCP(0x6c66e403, 0x4410fa9a), + STCP(0x6c40cf2b, 0x444d7aff), STCP(0x6c1a988f, 0x4489e615), STCP(0x6bf4403a, 0x44c63bca), + STCP(0x6bcdc639, 0x45027c0c), STCP(0x6ba72a97, 0x453ea6c7), STCP(0x6b806d61, 0x457abbe8), + STCP(0x6b598ea2, 0x45b6bb5d), STCP(0x6b328e67, 0x45f2a513), STCP(0x6b0b6cbc, 0x462e78f8), + STCP(0x6ae429ad, 0x466a36f9), STCP(0x6abcc546, 0x46a5df02), STCP(0x6a953f94, 0x46e17102), + STCP(0x6a6d98a3, 0x471cece6), STCP(0x6a45d080, 0x4758529c), STCP(0x6a1de736, 0x4793a210), + STCP(0x69f5dcd2, 0x47cedb30), STCP(0x69cdb161, 0x4809fdeb), STCP(0x69a564ef, 0x48450a2d), + STCP(0x697cf789, 0x487fffe3), STCP(0x6954693b, 0x48badefd), STCP(0x692bba13, 0x48f5a767), + STCP(0x6902ea1c, 0x4930590e), STCP(0x68d9f964, 0x496af3e1), STCP(0x68b0e7f6, 0x49a577ce), + STCP(0x6887b5e1, 0x49dfe4c2), STCP(0x685e6331, 0x4a1a3aaa), STCP(0x6834eff2, 0x4a547975), + STCP(0x680b5c33, 0x4a8ea111), STCP(0x67e1a7ff, 0x4ac8b16b), STCP(0x67b7d363, 0x4b02aa71), + STCP(0x678dde6e, 0x4b3c8c11), STCP(0x6763c92b, 0x4b76563a), STCP(0x673993a8, 0x4bb008d8), + STCP(0x670f3df2, 0x4be9a3db), STCP(0x66e4c817, 0x4c23272f), STCP(0x66ba3223, 0x4c5c92c4), + STCP(0x668f7c24, 0x4c95e687), STCP(0x6664a627, 0x4ccf2267), STCP(0x6639b03a, 0x4d084651), + STCP(0x660e9a69, 0x4d415233), STCP(0x65e364c3, 0x4d7a45fd), STCP(0x65b80f55, 0x4db3219c), + STCP(0x658c9a2d, 0x4debe4fe), STCP(0x65610557, 0x4e249011), STCP(0x653550e1, 0x4e5d22c5), + STCP(0x65097cda, 0x4e959d07), STCP(0x64dd894f, 0x4ecdfec6), STCP(0x64b1764d, 0x4f0647f0), + STCP(0x648543e3, 0x4f3e7874), STCP(0x6458f21d, 0x4f769040), STCP(0x642c810b, 0x4fae8f42), + STCP(0x63fff0b9, 0x4fe6756a), STCP(0x63d34136, 0x501e42a5), STCP(0x63a6728f, 0x5055f6e2), + STCP(0x637984d4, 0x508d9211), STCP(0x634c7810, 0x50c5141e), STCP(0x631f4c54, 0x50fc7cfa), + STCP(0x62f201ac, 0x5133cc94), STCP(0x62c49826, 0x516b02d8), STCP(0x62970fd2, 0x51a21fb7), + STCP(0x626968be, 0x51d92320), STCP(0x623ba2f6, 0x52100d01), STCP(0x620dbe8a, 0x5246dd48), + STCP(0x61dfbb89, 0x527d93e6), STCP(0x61b19a00, 0x52b430c8), STCP(0x618359fd, 0x52eab3de), + STCP(0x6154fb90, 0x53211d17), STCP(0x61267ec7, 0x53576c62), STCP(0x60f7e3b0, 0x538da1ae), + STCP(0x60c92a59, 0x53c3bce9), STCP(0x609a52d2, 0x53f9be04), STCP(0x606b5d28, 0x542fa4ed), + STCP(0x603c496c, 0x54657194), STCP(0x600d17aa, 0x549b23e7), STCP(0x5fddc7f3, 0x54d0bbd6), + STCP(0x5fae5a54, 0x55063950), STCP(0x5f7ecedd, 0x553b9c45), STCP(0x5f4f259c, 0x5570e4a3), + STCP(0x5f1f5ea0, 0x55a6125b), STCP(0x5eef79f8, 0x55db255b), STCP(0x5ebf77b4, 0x56101d94), + STCP(0x5e8f57e2, 0x5644faf4), STCP(0x5e5f1a90, 0x5679bd6b), STCP(0x5e2ebfcf, 0x56ae64e9), + STCP(0x5dfe47ad, 0x56e2f15d), STCP(0x5dcdb239, 0x571762b6), STCP(0x5d9cff82, 0x574bb8e6), + STCP(0x5d6c2f99, 0x577ff3da), STCP(0x5d3b428b, 0x57b41383), STCP(0x5d0a3868, 0x57e817d1), + STCP(0x5cd91140, 0x581c00b3), STCP(0x5ca7cd21, 0x584fce19), STCP(0x5c766c1c, 0x58837ff3), + STCP(0x5c44ee3f, 0x58b71631), STCP(0x5c13539a, 0x58ea90c3), STCP(0x5be19c3c, 0x591def98), + STCP(0x5bafc836, 0x595132a2), STCP(0x5b7dd796, 0x598459ce), STCP(0x5b4bca6c, 0x59b7650f), + STCP(0x5b19a0c7, 0x59ea5454), STCP(0x5ae75ab8, 0x5a1d278c), STCP(0x5ab4f84f, 0x5a4fdea9), + STCP(0x5a827999, 0x5a827999) +}; +#endif +const PWord32 SineTable960[] = { + STCP(0x7fffffff, 0x00000000), STCP(0x7ffff4c4, 0x00359dd2), STCP(0x7fffd314, 0x006b3b9b), + STCP(0x7fff9aee, 0x00a0d951), STCP(0x7fff4c53, 0x00d676eb), STCP(0x7ffee743, 0x010c1460), + STCP(0x7ffe6bbe, 0x0141b1a5), STCP(0x7ffdd9c3, 0x01774eb2), STCP(0x7ffd3153, 0x01aceb7c), + STCP(0x7ffc726e, 0x01e287fc), STCP(0x7ffb9d14, 0x02182427), STCP(0x7ffab146, 0x024dbff4), + STCP(0x7ff9af03, 0x02835b59), STCP(0x7ff8964c, 0x02b8f64e), STCP(0x7ff76720, 0x02ee90c8), + STCP(0x7ff62181, 0x03242abf), STCP(0x7ff4c56e, 0x0359c428), STCP(0x7ff352e7, 0x038f5cfb), + STCP(0x7ff1c9ee, 0x03c4f52e), STCP(0x7ff02a81, 0x03fa8cb8), STCP(0x7fee74a1, 0x0430238f), + STCP(0x7feca850, 0x0465b9aa), STCP(0x7feac58c, 0x049b4f00), STCP(0x7fe8cc56, 0x04d0e386), + STCP(0x7fe6bcaf, 0x05067734), STCP(0x7fe49697, 0x053c0a01), STCP(0x7fe25a0e, 0x05719be2), + STCP(0x7fe00715, 0x05a72ccf), STCP(0x7fdd9dac, 0x05dcbcbe), STCP(0x7fdb1dd4, 0x06124ba5), + STCP(0x7fd8878d, 0x0647d97c), STCP(0x7fd5dad7, 0x067d6639), STCP(0x7fd317b3, 0x06b2f1d2), + STCP(0x7fd03e22, 0x06e87c3f), STCP(0x7fcd4e23, 0x071e0575), STCP(0x7fca47b8, 0x07538d6b), + STCP(0x7fc72ae1, 0x07891418), STCP(0x7fc3f79f, 0x07be9973), STCP(0x7fc0adf1, 0x07f41d72), + STCP(0x7fbd4dd9, 0x0829a00b), STCP(0x7fb9d758, 0x085f2136), STCP(0x7fb64a6d, 0x0894a0e9), + STCP(0x7fb2a71a, 0x08ca1f1b), STCP(0x7faeed5e, 0x08ff9bc2), STCP(0x7fab1d3c, 0x093516d4), + STCP(0x7fa736b3, 0x096a9049), STCP(0x7fa339c4, 0x09a00817), STCP(0x7f9f2670, 0x09d57e35), + STCP(0x7f9afcb8, 0x0a0af299), STCP(0x7f96bc9b, 0x0a40653a), STCP(0x7f92661c, 0x0a75d60e), + STCP(0x7f8df93b, 0x0aab450d), STCP(0x7f8975f8, 0x0ae0b22c), STCP(0x7f84dc54, 0x0b161d63), + STCP(0x7f802c51, 0x0b4b86a8), STCP(0x7f7b65ee, 0x0b80edf1), STCP(0x7f76892e, 0x0bb65336), + STCP(0x7f719610, 0x0bebb66c), STCP(0x7f6c8c95, 0x0c21178c), STCP(0x7f676cbf, 0x0c56768a), + STCP(0x7f62368e, 0x0c8bd35e), STCP(0x7f5cea04, 0x0cc12dff), STCP(0x7f578720, 0x0cf68662), + STCP(0x7f520de5, 0x0d2bdc80), STCP(0x7f4c7e53, 0x0d61304e), STCP(0x7f46d86b, 0x0d9681c2), + STCP(0x7f411c2e, 0x0dcbd0d5), STCP(0x7f3b499c, 0x0e011d7c), STCP(0x7f3560b8, 0x0e3667ad), + STCP(0x7f2f6182, 0x0e6baf61), STCP(0x7f294bfc, 0x0ea0f48c), STCP(0x7f232025, 0x0ed63727), + STCP(0x7f1cde00, 0x0f0b7727), STCP(0x7f16858d, 0x0f40b483), STCP(0x7f1016cd, 0x0f75ef32), + STCP(0x7f0991c3, 0x0fab272b), STCP(0x7f02f66e, 0x0fe05c64), STCP(0x7efc44cf, 0x10158ed4), + STCP(0x7ef57cea, 0x104abe71), STCP(0x7eee9ebd, 0x107feb33), STCP(0x7ee7aa4b, 0x10b5150f), + STCP(0x7ee09f94, 0x10ea3bfd), STCP(0x7ed97e9b, 0x111f5ff3), STCP(0x7ed24760, 0x115480e9), + STCP(0x7ecaf9e4, 0x11899ed3), STCP(0x7ec39629, 0x11beb9aa), STCP(0x7ebc1c30, 0x11f3d164), + STCP(0x7eb48bfa, 0x1228e5f7), STCP(0x7eace589, 0x125df75b), STCP(0x7ea528df, 0x12930586), + STCP(0x7e9d55fb, 0x12c8106e), STCP(0x7e956ce0, 0x12fd180b), STCP(0x7e8d6d90, 0x13321c53), + STCP(0x7e85580b, 0x13671d3d), STCP(0x7e7d2c53, 0x139c1abf), STCP(0x7e74ea69, 0x13d114d0), + STCP(0x7e6c9250, 0x14060b68), STCP(0x7e642407, 0x143afe7b), STCP(0x7e5b9f92, 0x146fee02), + STCP(0x7e5304f1, 0x14a4d9f3), STCP(0x7e4a5425, 0x14d9c245), STCP(0x7e418d31, 0x150ea6ef), + STCP(0x7e38b016, 0x154387e6), STCP(0x7e2fbcd5, 0x15786522), STCP(0x7e26b370, 0x15ad3e9a), + STCP(0x7e1d93e9, 0x15e21444), STCP(0x7e145e41, 0x1616e618), STCP(0x7e0b1279, 0x164bb40b), + STCP(0x7e01b095, 0x16807e14), STCP(0x7df83894, 0x16b5442b), STCP(0x7deeaa79, 0x16ea0646), + STCP(0x7de50645, 0x171ec45c), STCP(0x7ddb4bfb, 0x17537e63), STCP(0x7dd17b9b, 0x17883452), + STCP(0x7dc79528, 0x17bce621), STCP(0x7dbd98a3, 0x17f193c5), STCP(0x7db3860e, 0x18263d35), + STCP(0x7da95d6b, 0x185ae269), STCP(0x7d9f1ebc, 0x188f8357), STCP(0x7d94ca02, 0x18c41ff6), + STCP(0x7d8a5f3f, 0x18f8b83c), STCP(0x7d7fde75, 0x192d4c21), STCP(0x7d7547a6, 0x1961db9b), + STCP(0x7d6a9ad4, 0x199666a0), STCP(0x7d5fd800, 0x19caed28), STCP(0x7d54ff2d, 0x19ff6f2a), + STCP(0x7d4a105c, 0x1a33ec9c), STCP(0x7d3f0b8f, 0x1a686575), STCP(0x7d33f0c9, 0x1a9cd9ac), + STCP(0x7d28c00b, 0x1ad14938), STCP(0x7d1d7957, 0x1b05b40e), STCP(0x7d121caf, 0x1b3a1a27), + STCP(0x7d06aa15, 0x1b6e7b7a), STCP(0x7cfb218b, 0x1ba2d7fc), STCP(0x7cef8314, 0x1bd72fa4), + STCP(0x7ce3ceb1, 0x1c0b826a), STCP(0x7cd80464, 0x1c3fd045), STCP(0x7ccc242f, 0x1c74192a), + STCP(0x7cc02e14, 0x1ca85d12), STCP(0x7cb42216, 0x1cdc9bf2), STCP(0x7ca80037, 0x1d10d5c1), + STCP(0x7c9bc879, 0x1d450a78), STCP(0x7c8f7add, 0x1d793a0b), STCP(0x7c831766, 0x1dad6473), + STCP(0x7c769e17, 0x1de189a5), STCP(0x7c6a0ef1, 0x1e15a99a), STCP(0x7c5d69f6, 0x1e49c447), + STCP(0x7c50af2a, 0x1e7dd9a3), STCP(0x7c43de8d, 0x1eb1e9a6), STCP(0x7c36f823, 0x1ee5f447), + STCP(0x7c29fbed, 0x1f19f97b), STCP(0x7c1ce9ee, 0x1f4df93a), STCP(0x7c0fc229, 0x1f81f37b), + STCP(0x7c02849f, 0x1fb5e835), STCP(0x7bf53152, 0x1fe9d75f), STCP(0x7be7c846, 0x201dc0ef), + STCP(0x7bda497c, 0x2051a4dd), STCP(0x7bccb4f7, 0x2085831e), STCP(0x7bbf0ab9, 0x20b95bac), + STCP(0x7bb14ac4, 0x20ed2e7b), STCP(0x7ba3751c, 0x2120fb83), STCP(0x7b9589c2, 0x2154c2bb), + STCP(0x7b8788b9, 0x2188841a), STCP(0x7b797204, 0x21bc3f97), STCP(0x7b6b45a4, 0x21eff528), + STCP(0x7b5d039d, 0x2223a4c5), STCP(0x7b4eabf0, 0x22574e65), STCP(0x7b403ea1, 0x228af1fe), + STCP(0x7b31bbb1, 0x22be8f87), STCP(0x7b232324, 0x22f226f8), STCP(0x7b1474fc, 0x2325b847), + STCP(0x7b05b13c, 0x2359436c), STCP(0x7af6d7e5, 0x238cc85c), STCP(0x7ae7e8fb, 0x23c04710), + STCP(0x7ad8e481, 0x23f3bf7e), STCP(0x7ac9ca79, 0x2427319d), STCP(0x7aba9ae5, 0x245a9d64), + STCP(0x7aab55c9, 0x248e02ca), STCP(0x7a9bfb26, 0x24c161c7), STCP(0x7a8c8b00, 0x24f4ba50), + STCP(0x7a7d055a, 0x25280c5d), STCP(0x7a6d6a36, 0x255b57e6), STCP(0x7a5db997, 0x258e9ce0), + STCP(0x7a4df37f, 0x25c1db43), STCP(0x7a3e17f1, 0x25f51307), STCP(0x7a2e26f1, 0x26284421), + STCP(0x7a1e2081, 0x265b6e8a), STCP(0x7a0e04a3, 0x268e9238), STCP(0x79fdd35b, 0x26c1af21), + STCP(0x79ed8cac, 0x26f4c53e), STCP(0x79dd3097, 0x2727d485), STCP(0x79ccbf21, 0x275adcee), + STCP(0x79bc384c, 0x278dde6e), STCP(0x79ab9c1b, 0x27c0d8fe), STCP(0x799aea91, 0x27f3cc94), + STCP(0x798a23b0, 0x2826b928), STCP(0x7979477c, 0x28599eb0), STCP(0x796855f8, 0x288c7d24), + STCP(0x79574f27, 0x28bf547a), STCP(0x7946330b, 0x28f224aa), STCP(0x793501a8, 0x2924edab), + STCP(0x7923bb00, 0x2957af74), STCP(0x79125f18, 0x298a69fc), STCP(0x7900edf1, 0x29bd1d3a), + STCP(0x78ef678e, 0x29efc925), STCP(0x78ddcbf4, 0x2a226db4), STCP(0x78cc1b25, 0x2a550adf), + STCP(0x78ba5523, 0x2a87a09c), STCP(0x78a879f3, 0x2aba2ee3), STCP(0x78968997, 0x2aecb5ab), + STCP(0x78848413, 0x2b1f34eb), STCP(0x78726969, 0x2b51ac9a), STCP(0x7860399d, 0x2b841caf), + STCP(0x784df4b2, 0x2bb68521), STCP(0x783b9aac, 0x2be8e5e8), STCP(0x78292b8c, 0x2c1b3efb), + STCP(0x7816a758, 0x2c4d9050), STCP(0x78040e11, 0x2c7fd9df), STCP(0x77f15fbb, 0x2cb21ba0), + STCP(0x77de9c5a, 0x2ce45589), STCP(0x77cbc3f1, 0x2d168792), STCP(0x77b8d683, 0x2d48b1b1), + STCP(0x77a5d413, 0x2d7ad3de), STCP(0x7792bca4, 0x2dacee10), STCP(0x777f903b, 0x2ddf003f), + STCP(0x776c4eda, 0x2e110a62), STCP(0x7758f885, 0x2e430c6f), STCP(0x77458d3f, 0x2e75065e), + STCP(0x77320d0c, 0x2ea6f826), STCP(0x771e77ef, 0x2ed8e1bf), STCP(0x770acdeb, 0x2f0ac320), + STCP(0x76f70f04, 0x2f3c9c3f), STCP(0x76e33b3e, 0x2f6e6d15), STCP(0x76cf529b, 0x2fa03599), + STCP(0x76bb5520, 0x2fd1f5c1), STCP(0x76a742d0, 0x3003ad85), STCP(0x76931bae, 0x30355cdc), + STCP(0x767edfbd, 0x306703be), STCP(0x766a8f03, 0x3098a222), STCP(0x76562981, 0x30ca37ff), + STCP(0x7641af3c, 0x30fbc54d), STCP(0x762d2037, 0x312d4a02), STCP(0x76187c76, 0x315ec617), + STCP(0x7603c3fc, 0x31903982), STCP(0x75eef6ce, 0x31c1a43a), STCP(0x75da14ee, 0x31f30638), + STCP(0x75c51e60, 0x32245f72), STCP(0x75b01329, 0x3255afe0), STCP(0x759af34b, 0x3286f778), + STCP(0x7585beca, 0x32b83634), STCP(0x757075ab, 0x32e96c09), STCP(0x755b17f1, 0x331a98ef), + STCP(0x7545a59f, 0x334bbcde), STCP(0x75301eba, 0x337cd7cc), STCP(0x751a8345, 0x33ade9b2), + STCP(0x7504d344, 0x33def287), STCP(0x74ef0ebb, 0x340ff242), STCP(0x74d935ad, 0x3440e8da), + STCP(0x74c3481f, 0x3471d647), STCP(0x74ad4614, 0x34a2ba80), STCP(0x74972f91, 0x34d3957e), + STCP(0x74810498, 0x35046736), STCP(0x746ac52e, 0x35352fa1), STCP(0x74547157, 0x3565eeb6), + STCP(0x743e0917, 0x3596a46c), STCP(0x74278c71, 0x35c750bb), STCP(0x7410fb6a, 0x35f7f39b), + STCP(0x73fa5606, 0x36288d03), STCP(0x73e39c48, 0x36591cea), STCP(0x73ccce35, 0x3689a347), + STCP(0x73b5ebd0, 0x36ba2013), STCP(0x739ef51e, 0x36ea9345), STCP(0x7387ea22, 0x371afcd4), + STCP(0x7370cae1, 0x374b5cb8), STCP(0x7359975f, 0x377bb2e8), STCP(0x73424f9f, 0x37abff5c), + STCP(0x732af3a6, 0x37dc420c), STCP(0x73138379, 0x380c7aee), STCP(0x72fbff1a, 0x383ca9fb), + STCP(0x72e4668e, 0x386ccf29), STCP(0x72ccb9da, 0x389cea71), STCP(0x72b4f901, 0x38ccfbcb), + STCP(0x729d2408, 0x38fd032d), STCP(0x72853af2, 0x392d008f), STCP(0x726d3dc5, 0x395cf3e9), + STCP(0x72552c84, 0x398cdd32), STCP(0x723d0733, 0x39bcbc62), STCP(0x7224cdd7, 0x39ec9171), + STCP(0x720c8074, 0x3a1c5c56), STCP(0x71f41f0e, 0x3a4c1d09), STCP(0x71dba9aa, 0x3a7bd381), + STCP(0x71c3204b, 0x3aab7fb6), STCP(0x71aa82f6, 0x3adb21a0), STCP(0x7191d1b0, 0x3b0ab937), + STCP(0x71790c7d, 0x3b3a4671), STCP(0x71603360, 0x3b69c947), STCP(0x7147465f, 0x3b9941b0), + STCP(0x712e457e, 0x3bc8afa4), STCP(0x711530c1, 0x3bf8131b), STCP(0x70fc082d, 0x3c276c0c), + STCP(0x70e2cbc5, 0x3c56ba70), STCP(0x70c97b8f, 0x3c85fe3c), STCP(0x70b0178f, 0x3cb5376b), + STCP(0x70969fc9, 0x3ce465f2), STCP(0x707d1442, 0x3d1389cb), STCP(0x706374fe, 0x3d42a2ec), + STCP(0x7049c202, 0x3d71b14d), STCP(0x702ffb53, 0x3da0b4e6), STCP(0x701620f4, 0x3dcfadaf), + STCP(0x6ffc32ea, 0x3dfe9ba0), STCP(0x6fe2313b, 0x3e2d7eb0), STCP(0x6fc81be9, 0x3e5c56d8), + STCP(0x6fadf2fb, 0x3e8b240e), STCP(0x6f93b675, 0x3eb9e64b), STCP(0x6f79665a, 0x3ee89d86), + STCP(0x6f5f02b1, 0x3f1749b7), STCP(0x6f448b7d, 0x3f45ead7), STCP(0x6f2a00c3, 0x3f7480dd), + STCP(0x6f0f6288, 0x3fa30bc0), STCP(0x6ef4b0d0, 0x3fd18b79), STCP(0x6ed9eba1, 0x3fffffff), + STCP(0x6ebf12fe, 0x402e694b), STCP(0x6ea426ed, 0x405cc754), STCP(0x6e892772, 0x408b1a12), + STCP(0x6e6e1492, 0x40b9617c), STCP(0x6e52ee51, 0x40e79d8c), STCP(0x6e37b4b6, 0x4115ce38), + STCP(0x6e1c67c3, 0x4143f378), STCP(0x6e01077f, 0x41720d45), STCP(0x6de593ed, 0x41a01b96), + STCP(0x6dca0d14, 0x41ce1e64), STCP(0x6dae72f6, 0x41fc15a6), STCP(0x6d92c59a, 0x422a0154), + STCP(0x6d770505, 0x4257e166), STCP(0x6d5b313a, 0x4285b5d4), STCP(0x6d3f4a3f, 0x42b37e95), + STCP(0x6d23501a, 0x42e13ba3), STCP(0x6d0742ce, 0x430eecf5), STCP(0x6ceb2260, 0x433c9283), + STCP(0x6cceeed7, 0x436a2c44), STCP(0x6cb2a836, 0x4397ba32), STCP(0x6c964e82, 0x43c53c43), + STCP(0x6c79e1c1, 0x43f2b270), STCP(0x6c5d61f8, 0x44201cb2), STCP(0x6c40cf2b, 0x444d7aff), + STCP(0x6c24295f, 0x447acd50), STCP(0x6c07709b, 0x44a8139d), STCP(0x6beaa4e1, 0x44d54dde), + STCP(0x6bcdc639, 0x45027c0c), STCP(0x6bb0d4a6, 0x452f9e1e), STCP(0x6b93d02d, 0x455cb40c), + STCP(0x6b76b8d5, 0x4589bdce), STCP(0x6b598ea2, 0x45b6bb5d), STCP(0x6b3c5199, 0x45e3acb1), + STCP(0x6b1f01bf, 0x461091c1), STCP(0x6b019f19, 0x463d6a86), STCP(0x6ae429ad, 0x466a36f9), + STCP(0x6ac6a180, 0x4696f710), STCP(0x6aa90696, 0x46c3aac5), STCP(0x6a8b58f6, 0x46f0520f), + STCP(0x6a6d98a3, 0x471cece6), STCP(0x6a4fc5a5, 0x47497b44), STCP(0x6a31dfff, 0x4775fd1f), + STCP(0x6a13e7b7, 0x47a27270), STCP(0x69f5dcd2, 0x47cedb30), STCP(0x69d7bf56, 0x47fb3757), + STCP(0x69b98f47, 0x482786dc), STCP(0x699b4cac, 0x4853c9b8), STCP(0x697cf789, 0x487fffe3), + STCP(0x695e8fe4, 0x48ac2956), STCP(0x694015c2, 0x48d84609), STCP(0x69218928, 0x490455f3), + STCP(0x6902ea1c, 0x4930590e), STCP(0x68e438a3, 0x495c4f51), STCP(0x68c574c3, 0x498838b6), + STCP(0x68a69e80, 0x49b41533), STCP(0x6887b5e1, 0x49dfe4c2), STCP(0x6868baeb, 0x4a0ba75a), + STCP(0x6849ada3, 0x4a375cf4), STCP(0x682a8e0e, 0x4a630589), STCP(0x680b5c33, 0x4a8ea111), + STCP(0x67ec1816, 0x4aba2f83), STCP(0x67ccc1bd, 0x4ae5b0d9), STCP(0x67ad592e, 0x4b11250b), + STCP(0x678dde6e, 0x4b3c8c11), STCP(0x676e5182, 0x4b67e5e4), STCP(0x674eb270, 0x4b93327b), + STCP(0x672f013f, 0x4bbe71d0), STCP(0x670f3df2, 0x4be9a3db), STCP(0x66ef6890, 0x4c14c894), + STCP(0x66cf811f, 0x4c3fdff3), STCP(0x66af87a4, 0x4c6ae9f1), STCP(0x668f7c24, 0x4c95e687), + STCP(0x666f5ea5, 0x4cc0d5ad), STCP(0x664f2f2e, 0x4cebb75c), STCP(0x662eedc2, 0x4d168b8b), + STCP(0x660e9a69, 0x4d415233), STCP(0x65ee3528, 0x4d6c0b4e), STCP(0x65cdbe05, 0x4d96b6d3), + STCP(0x65ad3504, 0x4dc154bb), STCP(0x658c9a2d, 0x4debe4fe), STCP(0x656bed84, 0x4e166795), + STCP(0x654b2f0f, 0x4e40dc78), STCP(0x652a5ed5, 0x4e6b43a1), STCP(0x65097cda, 0x4e959d07), + STCP(0x64e88925, 0x4ebfe8a4), STCP(0x64c783bc, 0x4eea266f), STCP(0x64a66ca4, 0x4f145662), + STCP(0x648543e3, 0x4f3e7874), STCP(0x6464097e, 0x4f688c9f), STCP(0x6442bd7d, 0x4f9292db), + STCP(0x64215fe4, 0x4fbc8b21), STCP(0x63fff0b9, 0x4fe6756a), STCP(0x63de7003, 0x501051ad), + STCP(0x63bcddc6, 0x503a1fe4), STCP(0x639b3a0a, 0x5063e008), STCP(0x637984d4, 0x508d9211), + STCP(0x6357be29, 0x50b735f7), STCP(0x6335e610, 0x50e0cbb4), STCP(0x6313fc8f, 0x510a5340), + STCP(0x62f201ac, 0x5133cc94), STCP(0x62cff56c, 0x515d37a8), STCP(0x62add7d5, 0x51869476), + STCP(0x628ba8ef, 0x51afe2f5), STCP(0x626968be, 0x51d92320), STCP(0x62471748, 0x520254ee), + STCP(0x6224b494, 0x522b7859), STCP(0x620240a8, 0x52548d58), STCP(0x61dfbb89, 0x527d93e6), + STCP(0x61bd253e, 0x52a68bfa), STCP(0x619a7dcd, 0x52cf758e), STCP(0x6177c53c, 0x52f8509a), + STCP(0x6154fb90, 0x53211d17), STCP(0x613220d1, 0x5349daff), STCP(0x610f3504, 0x53728a49), + STCP(0x60ec382f, 0x539b2aef), STCP(0x60c92a59, 0x53c3bce9), STCP(0x60a60b87, 0x53ec4032), + STCP(0x6082dbc0, 0x5414b4c0), STCP(0x605f9b0b, 0x543d1a8e), STCP(0x603c496c, 0x54657194), + STCP(0x6018e6ea, 0x548db9cb), STCP(0x5ff5738c, 0x54b5f32c), STCP(0x5fd1ef58, 0x54de1db0), + STCP(0x5fae5a54, 0x55063950), STCP(0x5f8ab486, 0x552e4605), STCP(0x5f66fdf4, 0x555643c8), + STCP(0x5f4336a6, 0x557e3291), STCP(0x5f1f5ea0, 0x55a6125b), STCP(0x5efb75ea, 0x55cde31d), + STCP(0x5ed77c89, 0x55f5a4d2), STCP(0x5eb37284, 0x561d5771), STCP(0x5e8f57e2, 0x5644faf4), + STCP(0x5e6b2ca8, 0x566c8f54), STCP(0x5e46f0dc, 0x5694148a), STCP(0x5e22a487, 0x56bb8a8f), + STCP(0x5dfe47ad, 0x56e2f15d), STCP(0x5dd9da55, 0x570a48eb), STCP(0x5db55c85, 0x57319134), + STCP(0x5d90ce44, 0x5758ca31), STCP(0x5d6c2f99, 0x577ff3da), STCP(0x5d478089, 0x57a70e29), + STCP(0x5d22c11b, 0x57ce1916), STCP(0x5cfdf156, 0x57f5149c), STCP(0x5cd91140, 0x581c00b3), + STCP(0x5cb420df, 0x5842dd54), STCP(0x5c8f203a, 0x5869aa78), STCP(0x5c6a0f58, 0x5890681a), + STCP(0x5c44ee3f, 0x58b71631), STCP(0x5c1fbcf5, 0x58ddb4b7), STCP(0x5bfa7b81, 0x590443a6), + STCP(0x5bd529ea, 0x592ac2f6), STCP(0x5bafc836, 0x595132a2), STCP(0x5b8a566b, 0x597792a1), + STCP(0x5b64d491, 0x599de2ed), STCP(0x5b3f42ae, 0x59c42380), STCP(0x5b19a0c7, 0x59ea5454), + STCP(0x5af3eee5, 0x5a107560), STCP(0x5ace2d0e, 0x5a36869f), STCP(0x5aa85b48, 0x5a5c8809), + STCP(0x5a827999, 0x5a827999), +}; +# endif + +/* + Sine windows + */ + +# ifdef ENABLE_HR_MODE +const PWord32 SineWindow20[10] = { +# else +const PWord16 SineWindow20[10] = { +# endif + WTCP(0x7fe6bcaf, 0x5067734), WTCP(0x7f1cde00, 0xf0b7727), WTCP(0x7d8a5f3f, 0x18f8b83c), + WTCP(0x7b31bbb1, 0x22be8f87), WTCP(0x7816a758, 0x2c4d9050), WTCP(0x743e0917, 0x3596a46c), + WTCP(0x6fadf2fb, 0x3e8b240e), WTCP(0x6a6d98a3, 0x471cece6), WTCP(0x648543e3, 0x4f3e7874), + WTCP(0x5dfe47ad, 0x56e2f15d), +}; + +# ifdef ENABLE_HR_MODE +const PWord32 SineWindow40[20] = { +# else +const PWord16 SineWindow40[20] = { +# endif + WTCP(0x7ff9af04, 0x02835b5a), WTCP(0x7fc72ae2, 0x07891418), WTCP(0x7f62368f, 0x0c8bd35e), + WTCP(0x7ecaf9e5, 0x11899ed3), WTCP(0x7e01b096, 0x16807e15), WTCP(0x7d06aa16, 0x1b6e7b7a), + WTCP(0x7bda497d, 0x2051a4dd), WTCP(0x7a7d055b, 0x25280c5e), WTCP(0x78ef678f, 0x29efc925), + WTCP(0x77320d0d, 0x2ea6f827), WTCP(0x7545a5a0, 0x334bbcde), WTCP(0x732af3a7, 0x37dc420c), + WTCP(0x70e2cbc6, 0x3c56ba70), WTCP(0x6e6e1492, 0x40b9617d), WTCP(0x6bcdc639, 0x45027c0c), + WTCP(0x6902ea1d, 0x4930590f), WTCP(0x660e9a6a, 0x4d415234), WTCP(0x62f201ac, 0x5133cc94), + WTCP(0x5fae5a55, 0x55063951), WTCP(0x5c44ee40, 0x58b71632), +}; + +# ifdef ENABLE_HR_MODE +const PWord32 SineWindow60[30] = { +# else +const PWord16 SineWindow60[30] = { +# endif + WTCP(0x7ffd3153, 0x1aceb7c), WTCP(0x7fe6bcaf, 0x5067734), WTCP(0x7fb9d758, 0x85f2136), + WTCP(0x7f76892e, 0xbb65336), WTCP(0x7f1cde00, 0xf0b7727), WTCP(0x7eace589, 0x125df75b), + WTCP(0x7e26b370, 0x15ad3e9a), WTCP(0x7d8a5f3f, 0x18f8b83c), WTCP(0x7cd80464, 0x1c3fd045), + WTCP(0x7c0fc229, 0x1f81f37b), WTCP(0x7b31bbb1, 0x22be8f87), WTCP(0x7a3e17f1, 0x25f51307), + WTCP(0x793501a8, 0x2924edab), WTCP(0x7816a758, 0x2c4d9050), WTCP(0x76e33b3e, 0x2f6e6d15), + WTCP(0x759af34b, 0x3286f778), WTCP(0x743e0917, 0x3596a46c), WTCP(0x72ccb9da, 0x389cea71), + WTCP(0x7147465f, 0x3b9941b0), WTCP(0x6fadf2fb, 0x3e8b240e), WTCP(0x6e01077f, 0x41720d45), + WTCP(0x6c40cf2b, 0x444d7aff), WTCP(0x6a6d98a3, 0x471cece6), WTCP(0x6887b5e1, 0x49dfe4c2), + WTCP(0x668f7c24, 0x4c95e687), WTCP(0x648543e3, 0x4f3e7874), WTCP(0x626968be, 0x51d92320), + WTCP(0x603c496c, 0x54657194), WTCP(0x5dfe47ad, 0x56e2f15d), WTCP(0x5bafc836, 0x595132a2), +}; + +# ifdef ENABLE_HR_MODE +const PWord32 SineWindow80[40] = { +# else +const PWord16 SineWindow80[40] = { +# endif + WTCP(0x7ffe6bbf, 0x0141b1a5), WTCP(0x7ff1c9ef, 0x03c4f52f), WTCP(0x7fd8878e, 0x0647d97c), + WTCP(0x7fb2a71b, 0x08ca1f1b), WTCP(0x7f802c52, 0x0b4b86a8), WTCP(0x7f411c2f, 0x0dcbd0d5), + WTCP(0x7ef57cea, 0x104abe71), WTCP(0x7e9d55fc, 0x12c8106f), WTCP(0x7e38b017, 0x154387e6), + WTCP(0x7dc79529, 0x17bce621), WTCP(0x7d4a105d, 0x1a33ec9c), WTCP(0x7cc02e15, 0x1ca85d12), + WTCP(0x7c29fbee, 0x1f19f97b), WTCP(0x7b8788ba, 0x2188841a), WTCP(0x7ad8e482, 0x23f3bf7e), + WTCP(0x7a1e2082, 0x265b6e8a), WTCP(0x79574f28, 0x28bf547b), WTCP(0x78848414, 0x2b1f34eb), + WTCP(0x77a5d413, 0x2d7ad3de), WTCP(0x76bb5521, 0x2fd1f5c1), WTCP(0x75c51e61, 0x32245f72), + WTCP(0x74c34820, 0x3471d647), WTCP(0x73b5ebd1, 0x36ba2014), WTCP(0x729d2409, 0x38fd032d), + WTCP(0x71790c7e, 0x3b3a4672), WTCP(0x7049c203, 0x3d71b14d), WTCP(0x6f0f6289, 0x3fa30bc1), + WTCP(0x6dca0d14, 0x41ce1e65), WTCP(0x6c79e1c2, 0x43f2b271), WTCP(0x6b1f01c0, 0x461091c2), + WTCP(0x69b98f48, 0x482786dc), WTCP(0x6849ada3, 0x4a375cf5), WTCP(0x66cf8120, 0x4c3fdff4), + WTCP(0x654b2f10, 0x4e40dc79), WTCP(0x63bcddc7, 0x503a1fe5), WTCP(0x6224b495, 0x522b7859), + WTCP(0x6082dbc1, 0x5414b4c1), WTCP(0x5ed77c8a, 0x55f5a4d2), WTCP(0x5d22c11c, 0x57ce1917), + WTCP(0x5b64d492, 0x599de2ee), +}; + +# ifdef ENABLE_HR_MODE +const PWord32 SineWindow120[60] = { +# else +const PWord16 SineWindow120[60] = { +# endif + WTCP(0x7fff4c54, 0x00d676eb), WTCP(0x7ff9af04, 0x02835b5a), WTCP(0x7fee74a2, 0x0430238f), + WTCP(0x7fdd9dad, 0x05dcbcbe), WTCP(0x7fc72ae2, 0x07891418), WTCP(0x7fab1d3d, 0x093516d4), + WTCP(0x7f8975f9, 0x0ae0b22c), WTCP(0x7f62368f, 0x0c8bd35e), WTCP(0x7f3560b9, 0x0e3667ad), + WTCP(0x7f02f66f, 0x0fe05c64), WTCP(0x7ecaf9e5, 0x11899ed3), WTCP(0x7e8d6d91, 0x13321c53), + WTCP(0x7e4a5426, 0x14d9c245), WTCP(0x7e01b096, 0x16807e15), WTCP(0x7db3860f, 0x18263d36), + WTCP(0x7d5fd801, 0x19caed29), WTCP(0x7d06aa16, 0x1b6e7b7a), WTCP(0x7ca80038, 0x1d10d5c2), + WTCP(0x7c43de8e, 0x1eb1e9a7), WTCP(0x7bda497d, 0x2051a4dd), WTCP(0x7b6b45a5, 0x21eff528), + WTCP(0x7af6d7e6, 0x238cc85d), WTCP(0x7a7d055b, 0x25280c5e), WTCP(0x79fdd35c, 0x26c1af22), + WTCP(0x7979477d, 0x28599eb0), WTCP(0x78ef678f, 0x29efc925), WTCP(0x7860399e, 0x2b841caf), + WTCP(0x77cbc3f2, 0x2d168792), WTCP(0x77320d0d, 0x2ea6f827), WTCP(0x76931bae, 0x30355cdd), + WTCP(0x75eef6ce, 0x31c1a43b), WTCP(0x7545a5a0, 0x334bbcde), WTCP(0x74972f92, 0x34d3957e), + WTCP(0x73e39c49, 0x36591cea), WTCP(0x732af3a7, 0x37dc420c), WTCP(0x726d3dc6, 0x395cf3e9), + WTCP(0x71aa82f7, 0x3adb21a1), WTCP(0x70e2cbc6, 0x3c56ba70), WTCP(0x701620f5, 0x3dcfadb0), + WTCP(0x6f448b7e, 0x3f45ead8), WTCP(0x6e6e1492, 0x40b9617d), WTCP(0x6d92c59b, 0x422a0154), + WTCP(0x6cb2a837, 0x4397ba32), WTCP(0x6bcdc639, 0x45027c0c), WTCP(0x6ae429ae, 0x466a36f9), + WTCP(0x69f5dcd3, 0x47cedb31), WTCP(0x6902ea1d, 0x4930590f), WTCP(0x680b5c33, 0x4a8ea111), + WTCP(0x670f3df3, 0x4be9a3db), WTCP(0x660e9a6a, 0x4d415234), WTCP(0x65097cdb, 0x4e959d08), + WTCP(0x63fff0ba, 0x4fe6756a), WTCP(0x62f201ac, 0x5133cc94), WTCP(0x61dfbb8a, 0x527d93e6), + WTCP(0x60c92a5a, 0x53c3bcea), WTCP(0x5fae5a55, 0x55063951), WTCP(0x5e8f57e2, 0x5644faf4), + WTCP(0x5d6c2f99, 0x577ff3da), WTCP(0x5c44ee40, 0x58b71632), WTCP(0x5b19a0c8, 0x59ea5454), +}; + +# ifdef ENABLE_HR_MODE +const PWord32 SineWindow160[80] = { +# else +const PWord16 SineWindow160[80] = { +# endif + WTCP(0x7fff9aef, 0x00a0d951), WTCP(0x7ffc726f, 0x01e287fc), WTCP(0x7ff62182, 0x03242abf), + WTCP(0x7feca851, 0x0465b9aa), WTCP(0x7fe00716, 0x05a72ccf), WTCP(0x7fd03e23, 0x06e87c3f), + WTCP(0x7fbd4dda, 0x0829a00c), WTCP(0x7fa736b4, 0x096a9049), WTCP(0x7f8df93c, 0x0aab450d), + WTCP(0x7f719611, 0x0bebb66c), WTCP(0x7f520de6, 0x0d2bdc80), WTCP(0x7f2f6183, 0x0e6baf61), + WTCP(0x7f0991c4, 0x0fab272b), WTCP(0x7ee09f95, 0x10ea3bfd), WTCP(0x7eb48bfb, 0x1228e5f8), + WTCP(0x7e85580c, 0x13671d3d), WTCP(0x7e5304f2, 0x14a4d9f4), WTCP(0x7e1d93ea, 0x15e21445), + WTCP(0x7de50646, 0x171ec45c), WTCP(0x7da95d6c, 0x185ae269), WTCP(0x7d6a9ad5, 0x199666a0), + WTCP(0x7d28c00c, 0x1ad14938), WTCP(0x7ce3ceb2, 0x1c0b826a), WTCP(0x7c9bc87a, 0x1d450a78), + WTCP(0x7c50af2b, 0x1e7dd9a4), WTCP(0x7c02849f, 0x1fb5e836), WTCP(0x7bb14ac5, 0x20ed2e7b), + WTCP(0x7b5d039e, 0x2223a4c5), WTCP(0x7b05b13d, 0x2359436c), WTCP(0x7aab55ca, 0x248e02cb), + WTCP(0x7a4df380, 0x25c1db44), WTCP(0x79ed8cad, 0x26f4c53e), WTCP(0x798a23b1, 0x2826b928), + WTCP(0x7923bb01, 0x2957af74), WTCP(0x78ba5524, 0x2a87a09d), WTCP(0x784df4b3, 0x2bb68522), + WTCP(0x77de9c5b, 0x2ce45589), WTCP(0x776c4edb, 0x2e110a62), WTCP(0x76f70f05, 0x2f3c9c40), + WTCP(0x767edfbe, 0x306703bf), WTCP(0x7603c3fd, 0x31903982), WTCP(0x7585becb, 0x32b83634), + WTCP(0x7504d345, 0x33def287), WTCP(0x74810499, 0x35046736), WTCP(0x73fa5607, 0x36288d03), + WTCP(0x7370cae2, 0x374b5cb9), WTCP(0x72e4668f, 0x386ccf2a), WTCP(0x72552c85, 0x398cdd32), + WTCP(0x71c3204c, 0x3aab7fb7), WTCP(0x712e457f, 0x3bc8afa5), WTCP(0x70969fca, 0x3ce465f3), + WTCP(0x6ffc32eb, 0x3dfe9ba1), WTCP(0x6f5f02b2, 0x3f1749b8), WTCP(0x6ebf12ff, 0x402e694c), + WTCP(0x6e1c67c4, 0x4143f379), WTCP(0x6d770506, 0x4257e166), WTCP(0x6cceeed8, 0x436a2c45), + WTCP(0x6c242960, 0x447acd50), WTCP(0x6b76b8d6, 0x4589bdcf), WTCP(0x6ac6a180, 0x4696f710), + WTCP(0x6a13e7b8, 0x47a27271), WTCP(0x695e8fe5, 0x48ac2957), WTCP(0x68a69e81, 0x49b41533), + WTCP(0x67ec1817, 0x4aba2f84), WTCP(0x672f013f, 0x4bbe71d1), WTCP(0x666f5ea6, 0x4cc0d5ae), + WTCP(0x65ad3505, 0x4dc154bb), WTCP(0x64e88926, 0x4ebfe8a5), WTCP(0x64215fe5, 0x4fbc8b22), + WTCP(0x6357be2a, 0x50b735f8), WTCP(0x628ba8ef, 0x51afe2f6), WTCP(0x61bd253f, 0x52a68bfb), + WTCP(0x60ec3830, 0x539b2af0), WTCP(0x6018e6eb, 0x548db9cb), WTCP(0x5f4336a7, 0x557e3292), + WTCP(0x5e6b2ca8, 0x566c8f55), WTCP(0x5d90ce45, 0x5758ca31), WTCP(0x5cb420e0, 0x5842dd54), + WTCP(0x5bd529eb, 0x592ac2f7), WTCP(0x5af3eee6, 0x5a107561), +}; + +# ifdef ENABLE_HR_MODE +const PWord32 SineWindow180[90] = { +# else +const PWord16 SineWindow180[90] = { +# endif + WTCP(0x7fffb025, 0x008efa17), WTCP(0x7ffd3153, 0x01aceb7c), WTCP(0x7ff833bc, 0x02cad485), + WTCP(0x7ff0b779, 0x03e8af9e), WTCP(0x7fe6bcaf, 0x05067734), WTCP(0x7fda4390, 0x062425b6), + WTCP(0x7fcb4c5a, 0x0741b592), WTCP(0x7fb9d758, 0x085f2136), WTCP(0x7fa5e4e0, 0x097c6313), + WTCP(0x7f8f7558, 0x0a997597), WTCP(0x7f76892e, 0x0bb65336), WTCP(0x7f5b20de, 0x0cd2f660), + WTCP(0x7f3d3cf3, 0x0def5989), WTCP(0x7f1cde00, 0x0f0b7727), WTCP(0x7efa04a7, 0x102749ae), + WTCP(0x7ed4b197, 0x1142cb98), WTCP(0x7eace589, 0x125df75b), WTCP(0x7e82a145, 0x1378c774), + WTCP(0x7e55e59d, 0x1493365f), WTCP(0x7e26b370, 0x15ad3e9a), WTCP(0x7df50baa, 0x16c6daa6), + WTCP(0x7dc0ef43, 0x17e00505), WTCP(0x7d8a5f3f, 0x18f8b83c), WTCP(0x7d515cae, 0x1a10eed2), + WTCP(0x7d15e8ac, 0x1b28a351), WTCP(0x7cd80464, 0x1c3fd045), WTCP(0x7c97b108, 0x1d56703b), + WTCP(0x7c54efdb, 0x1e6c7dc7), WTCP(0x7c0fc229, 0x1f81f37b), WTCP(0x7bc8294c, 0x2096cbf0), + WTCP(0x7b7e26a9, 0x21ab01c0), WTCP(0x7b31bbb1, 0x22be8f87), WTCP(0x7ae2e9e3, 0x23d16fe8), + WTCP(0x7a91b2c6, 0x24e39d85), WTCP(0x7a3e17f1, 0x25f51307), WTCP(0x79e81b05, 0x2705cb19), + WTCP(0x798fbdaf, 0x2815c069), WTCP(0x793501a8, 0x2924edab), WTCP(0x78d7e8b5, 0x2a334d95), + WTCP(0x787874a6, 0x2b40dae2), WTCP(0x7816a758, 0x2c4d9050), WTCP(0x77b282b3, 0x2d5968a2), + WTCP(0x774c08aa, 0x2e645ea0), WTCP(0x76e33b3e, 0x2f6e6d15), WTCP(0x76781c79, 0x30778ed2), + WTCP(0x760aae72, 0x317fbeaa), WTCP(0x759af34b, 0x3286f778), WTCP(0x7528ed31, 0x338d341a), + WTCP(0x74b49e5f, 0x34926f74), WTCP(0x743e0917, 0x3596a46c), WTCP(0x73c52faa, 0x3699cdf1), + WTCP(0x734a1474, 0x379be6f6), WTCP(0x72ccb9da, 0x389cea71), WTCP(0x724d224e, 0x399cd362), + WTCP(0x71cb504d, 0x3a9b9cc9), WTCP(0x7147465f, 0x3b9941b0), WTCP(0x70c10717, 0x3c95bd25), + WTCP(0x70389513, 0x3d910a3c), WTCP(0x6fadf2fb, 0x3e8b240e), WTCP(0x6f212384, 0x3f8405bb), + WTCP(0x6e92296d, 0x407baa69), WTCP(0x6e01077f, 0x41720d45), WTCP(0x6d6dc08e, 0x42672980), + WTCP(0x6cd85779, 0x435afa54), WTCP(0x6c40cf2b, 0x444d7aff), WTCP(0x6ba72a97, 0x453ea6c7), + WTCP(0x6b0b6cbc, 0x462e78f8), WTCP(0x6a6d98a3, 0x471cece6), WTCP(0x69cdb161, 0x4809fdeb), + WTCP(0x692bba13, 0x48f5a767), WTCP(0x6887b5e1, 0x49dfe4c2), WTCP(0x67e1a7ff, 0x4ac8b16b), + WTCP(0x673993a8, 0x4bb008d8), WTCP(0x668f7c24, 0x4c95e687), WTCP(0x65e364c3, 0x4d7a45fd), + WTCP(0x653550e1, 0x4e5d22c5), WTCP(0x648543e3, 0x4f3e7874), WTCP(0x63d34136, 0x501e42a5), + WTCP(0x631f4c54, 0x50fc7cfa), WTCP(0x626968be, 0x51d92320), WTCP(0x61b19a00, 0x52b430c8), + WTCP(0x60f7e3b0, 0x538da1ae), WTCP(0x603c496c, 0x54657194), WTCP(0x5f7ecedd, 0x553b9c45), + WTCP(0x5ebf77b4, 0x56101d94), WTCP(0x5dfe47ad, 0x56e2f15d), WTCP(0x5d3b428b, 0x57b41383), + WTCP(0x5c766c1c, 0x58837ff3), WTCP(0x5bafc836, 0x595132a2), WTCP(0x5ae75ab8, 0x5a1d278c), +}; + +# ifdef ENABLE_HR_MODE +const PWord32 SineWindow240[120] = { +# else +const PWord16 SineWindow240[120] = { +# endif + WTCP(0x7fffd315, 0x006b3b9b), WTCP(0x7ffe6bbf, 0x0141b1a5), WTCP(0x7ffb9d15, 0x02182427), + WTCP(0x7ff76721, 0x02ee90c8), WTCP(0x7ff1c9ef, 0x03c4f52f), WTCP(0x7feac58d, 0x049b4f00), + WTCP(0x7fe25a0f, 0x05719be2), WTCP(0x7fd8878e, 0x0647d97c), WTCP(0x7fcd4e24, 0x071e0575), + WTCP(0x7fc0adf2, 0x07f41d72), WTCP(0x7fb2a71b, 0x08ca1f1b), WTCP(0x7fa339c5, 0x09a00817), + WTCP(0x7f92661d, 0x0a75d60e), WTCP(0x7f802c52, 0x0b4b86a8), WTCP(0x7f6c8c96, 0x0c21178c), + WTCP(0x7f578721, 0x0cf68662), WTCP(0x7f411c2f, 0x0dcbd0d5), WTCP(0x7f294bfd, 0x0ea0f48c), + WTCP(0x7f1016ce, 0x0f75ef33), WTCP(0x7ef57cea, 0x104abe71), WTCP(0x7ed97e9c, 0x111f5ff4), + WTCP(0x7ebc1c31, 0x11f3d164), WTCP(0x7e9d55fc, 0x12c8106f), WTCP(0x7e7d2c54, 0x139c1abf), + WTCP(0x7e5b9f93, 0x146fee03), WTCP(0x7e38b017, 0x154387e6), WTCP(0x7e145e42, 0x1616e618), + WTCP(0x7deeaa7a, 0x16ea0646), WTCP(0x7dc79529, 0x17bce621), WTCP(0x7d9f1ebd, 0x188f8357), + WTCP(0x7d7547a7, 0x1961db9b), WTCP(0x7d4a105d, 0x1a33ec9c), WTCP(0x7d1d7958, 0x1b05b40f), + WTCP(0x7cef8315, 0x1bd72fa4), WTCP(0x7cc02e15, 0x1ca85d12), WTCP(0x7c8f7ade, 0x1d793a0b), + WTCP(0x7c5d69f7, 0x1e49c447), WTCP(0x7c29fbee, 0x1f19f97b), WTCP(0x7bf53153, 0x1fe9d75f), + WTCP(0x7bbf0aba, 0x20b95bac), WTCP(0x7b8788ba, 0x2188841a), WTCP(0x7b4eabf1, 0x22574e65), + WTCP(0x7b1474fd, 0x2325b847), WTCP(0x7ad8e482, 0x23f3bf7e), WTCP(0x7a9bfb27, 0x24c161c7), + WTCP(0x7a5db997, 0x258e9ce0), WTCP(0x7a1e2082, 0x265b6e8a), WTCP(0x79dd3098, 0x2727d486), + WTCP(0x799aea92, 0x27f3cc94), WTCP(0x79574f28, 0x28bf547b), WTCP(0x79125f19, 0x298a69fc), + WTCP(0x78cc1b26, 0x2a550adf), WTCP(0x78848414, 0x2b1f34eb), WTCP(0x783b9aad, 0x2be8e5e8), + WTCP(0x77f15fbc, 0x2cb21ba0), WTCP(0x77a5d413, 0x2d7ad3de), WTCP(0x7758f886, 0x2e430c6f), + WTCP(0x770acdec, 0x2f0ac320), WTCP(0x76bb5521, 0x2fd1f5c1), WTCP(0x766a8f04, 0x3098a223), + WTCP(0x76187c77, 0x315ec617), WTCP(0x75c51e61, 0x32245f72), WTCP(0x757075ac, 0x32e96c09), + WTCP(0x751a8346, 0x33ade9b3), WTCP(0x74c34820, 0x3471d647), WTCP(0x746ac52f, 0x35352fa1), + WTCP(0x7410fb6b, 0x35f7f39c), WTCP(0x73b5ebd1, 0x36ba2014), WTCP(0x73599760, 0x377bb2e9), + WTCP(0x72fbff1b, 0x383ca9fb), WTCP(0x729d2409, 0x38fd032d), WTCP(0x723d0734, 0x39bcbc63), + WTCP(0x71dba9ab, 0x3a7bd382), WTCP(0x71790c7e, 0x3b3a4672), WTCP(0x711530c2, 0x3bf8131c), + WTCP(0x70b01790, 0x3cb5376b), WTCP(0x7049c203, 0x3d71b14d), WTCP(0x6fe2313c, 0x3e2d7eb1), + WTCP(0x6f79665b, 0x3ee89d86), WTCP(0x6f0f6289, 0x3fa30bc1), WTCP(0x6ea426ed, 0x405cc754), + WTCP(0x6e37b4b6, 0x4115ce38), WTCP(0x6dca0d14, 0x41ce1e65), WTCP(0x6d5b313b, 0x4285b5d4), + WTCP(0x6ceb2261, 0x433c9283), WTCP(0x6c79e1c2, 0x43f2b271), WTCP(0x6c07709b, 0x44a8139e), + WTCP(0x6b93d02e, 0x455cb40c), WTCP(0x6b1f01c0, 0x461091c2), WTCP(0x6aa90697, 0x46c3aac5), + WTCP(0x6a31e000, 0x4775fd1f), WTCP(0x69b98f48, 0x482786dc), WTCP(0x694015c3, 0x48d84609), + WTCP(0x68c574c4, 0x498838b6), WTCP(0x6849ada3, 0x4a375cf5), WTCP(0x67ccc1be, 0x4ae5b0da), + WTCP(0x674eb271, 0x4b93327c), WTCP(0x66cf8120, 0x4c3fdff4), WTCP(0x664f2f2e, 0x4cebb75c), + WTCP(0x65cdbe05, 0x4d96b6d3), WTCP(0x654b2f10, 0x4e40dc79), WTCP(0x64c783bd, 0x4eea2670), + WTCP(0x6442bd7e, 0x4f9292dc), WTCP(0x63bcddc7, 0x503a1fe5), WTCP(0x6335e611, 0x50e0cbb4), + WTCP(0x62add7d6, 0x51869476), WTCP(0x6224b495, 0x522b7859), WTCP(0x619a7dce, 0x52cf758f), + WTCP(0x610f3505, 0x53728a4a), WTCP(0x6082dbc1, 0x5414b4c1), WTCP(0x5ff5738d, 0x54b5f32c), + WTCP(0x5f66fdf5, 0x555643c8), WTCP(0x5ed77c8a, 0x55f5a4d2), WTCP(0x5e46f0dd, 0x5694148b), + WTCP(0x5db55c86, 0x57319135), WTCP(0x5d22c11c, 0x57ce1917), WTCP(0x5c8f203b, 0x5869aa79), + WTCP(0x5bfa7b82, 0x590443a7), WTCP(0x5b64d492, 0x599de2ee), WTCP(0x5ace2d0f, 0x5a36869f), +}; + +# ifdef ENABLE_HR_MODE +const PWord32 SineWindow320[160] = { +# else +const PWord16 SineWindow320[160] = { +# endif + WTCP(0x7fffe6bc, 0x00506cb9), WTCP(0x7fff1c9b, 0x00f145ab), WTCP(0x7ffd885a, 0x01921d20), + WTCP(0x7ffb29fd, 0x0232f21a), WTCP(0x7ff80186, 0x02d3c39b), WTCP(0x7ff40efa, 0x037490a5), + WTCP(0x7fef5260, 0x0415583b), WTCP(0x7fe9cbc0, 0x04b6195d), WTCP(0x7fe37b22, 0x0556d30f), + WTCP(0x7fdc608f, 0x05f78453), WTCP(0x7fd47c14, 0x06982c2b), WTCP(0x7fcbcdbc, 0x0738c998), + WTCP(0x7fc25596, 0x07d95b9e), WTCP(0x7fb813b0, 0x0879e140), WTCP(0x7fad081b, 0x091a597e), + WTCP(0x7fa132e8, 0x09bac35d), WTCP(0x7f949429, 0x0a5b1dde), WTCP(0x7f872bf3, 0x0afb6805), + WTCP(0x7f78fa5b, 0x0b9ba0d5), WTCP(0x7f69ff76, 0x0c3bc74f), WTCP(0x7f5a3b5e, 0x0cdbda79), + WTCP(0x7f49ae2a, 0x0d7bd954), WTCP(0x7f3857f6, 0x0e1bc2e4), WTCP(0x7f2638db, 0x0ebb962c), + WTCP(0x7f1350f8, 0x0f5b5231), WTCP(0x7effa069, 0x0ffaf5f6), WTCP(0x7eeb274d, 0x109a807e), + WTCP(0x7ed5e5c6, 0x1139f0cf), WTCP(0x7ebfdbf5, 0x11d945eb), WTCP(0x7ea909fc, 0x12787ed8), + WTCP(0x7e917000, 0x13179a9b), WTCP(0x7e790e25, 0x13b69836), WTCP(0x7e5fe493, 0x145576b1), + WTCP(0x7e45f371, 0x14f43510), WTCP(0x7e2b3ae8, 0x1592d257), WTCP(0x7e0fbb22, 0x16314d8e), + WTCP(0x7df3744b, 0x16cfa5b9), WTCP(0x7dd6668f, 0x176dd9de), WTCP(0x7db8921c, 0x180be904), + WTCP(0x7d99f721, 0x18a9d231), WTCP(0x7d7a95cf, 0x1947946c), WTCP(0x7d5a6e57, 0x19e52ebb), + WTCP(0x7d3980ec, 0x1a82a026), WTCP(0x7d17cdc2, 0x1b1fe7b3), WTCP(0x7cf5550e, 0x1bbd046c), + WTCP(0x7cd21707, 0x1c59f557), WTCP(0x7cae13e4, 0x1cf6b97c), WTCP(0x7c894bde, 0x1d934fe5), + WTCP(0x7c63bf2f, 0x1e2fb79a), WTCP(0x7c3d6e13, 0x1ecbefa4), WTCP(0x7c1658c5, 0x1f67f70b), + WTCP(0x7bee7f85, 0x2003ccdb), WTCP(0x7bc5e290, 0x209f701c), WTCP(0x7b9c8226, 0x213adfda), + WTCP(0x7b725e8a, 0x21d61b1e), WTCP(0x7b4777fe, 0x227120f3), WTCP(0x7b1bcec4, 0x230bf065), + WTCP(0x7aef6323, 0x23a6887f), WTCP(0x7ac23561, 0x2440e84d), WTCP(0x7a9445c5, 0x24db0edb), + WTCP(0x7a659496, 0x2574fb36), WTCP(0x7a362220, 0x260eac6a), WTCP(0x7a05eead, 0x26a82186), + WTCP(0x79d4fa89, 0x27415996), WTCP(0x79a34602, 0x27da53a9), WTCP(0x7970d165, 0x28730ecd), + WTCP(0x793d9d03, 0x290b8a12), WTCP(0x7909a92d, 0x29a3c485), WTCP(0x78d4f634, 0x2a3bbd37), + WTCP(0x789f846b, 0x2ad37338), WTCP(0x78695428, 0x2b6ae598), WTCP(0x783265c0, 0x2c021369), + WTCP(0x77fab989, 0x2c98fbba), WTCP(0x77c24fdb, 0x2d2f9d9f), WTCP(0x77892910, 0x2dc5f829), + WTCP(0x774f4581, 0x2e5c0a6b), WTCP(0x7714a58b, 0x2ef1d377), WTCP(0x76d94989, 0x2f875262), + WTCP(0x769d31d9, 0x301c863f), WTCP(0x76605edb, 0x30b16e23), WTCP(0x7622d0ef, 0x31460922), + WTCP(0x75e48874, 0x31da5651), WTCP(0x75a585cf, 0x326e54c7), WTCP(0x7565c962, 0x3302039b), + WTCP(0x75255392, 0x339561e1), WTCP(0x74e424c5, 0x34286eb3), WTCP(0x74a23d62, 0x34bb2927), + WTCP(0x745f9dd1, 0x354d9057), WTCP(0x741c467b, 0x35dfa35a), WTCP(0x73d837ca, 0x3671614b), + WTCP(0x7393722a, 0x3702c942), WTCP(0x734df607, 0x3793da5b), WTCP(0x7307c3d0, 0x382493b0), + WTCP(0x72c0dbf3, 0x38b4f45d), WTCP(0x72793edf, 0x3944fb7e), WTCP(0x7230ed07, 0x39d4a82f), + WTCP(0x71e7e6dc, 0x3a63f98d), WTCP(0x719e2cd2, 0x3af2eeb7), WTCP(0x7153bf5d, 0x3b8186ca), + WTCP(0x71089ef2, 0x3c0fc0e6), WTCP(0x70bccc09, 0x3c9d9c28), WTCP(0x70704718, 0x3d2b17b3), + WTCP(0x7023109a, 0x3db832a6), WTCP(0x6fd52907, 0x3e44ec22), WTCP(0x6f8690db, 0x3ed14349), + WTCP(0x6f374891, 0x3f5d373e), WTCP(0x6ee750a8, 0x3fe8c724), WTCP(0x6e96a99d, 0x4073f21d), + WTCP(0x6e4553ef, 0x40feb74f), WTCP(0x6df35020, 0x418915de), WTCP(0x6da09eb1, 0x42130cf0), + WTCP(0x6d4d4023, 0x429c9bab), WTCP(0x6cf934fc, 0x4325c135), WTCP(0x6ca47dbf, 0x43ae7cb7), + WTCP(0x6c4f1af2, 0x4436cd58), WTCP(0x6bf90d1d, 0x44beb240), WTCP(0x6ba254c7, 0x45462a9a), + WTCP(0x6b4af279, 0x45cd358f), WTCP(0x6af2e6bc, 0x4653d24b), WTCP(0x6a9a321d, 0x46d9fff8), + WTCP(0x6a40d527, 0x475fbdc3), WTCP(0x69e6d067, 0x47e50ad8), WTCP(0x698c246c, 0x4869e665), + WTCP(0x6930d1c4, 0x48ee4f98), WTCP(0x68d4d900, 0x497245a1), WTCP(0x68783ab1, 0x49f5c7ae), + WTCP(0x681af76a, 0x4a78d4f0), WTCP(0x67bd0fbd, 0x4afb6c98), WTCP(0x675e843e, 0x4b7d8dd8), + WTCP(0x66ff5584, 0x4bff37e2), WTCP(0x669f8425, 0x4c8069ea), WTCP(0x663f10b7, 0x4d012324), + WTCP(0x65ddfbd3, 0x4d8162c4), WTCP(0x657c4613, 0x4e012800), WTCP(0x6519f010, 0x4e80720e), + WTCP(0x64b6fa66, 0x4eff4025), WTCP(0x645365b2, 0x4f7d917c), WTCP(0x63ef3290, 0x4ffb654d), + WTCP(0x638a619e, 0x5078bad1), WTCP(0x6324f37d, 0x50f59141), WTCP(0x62bee8cc, 0x5171e7d9), + WTCP(0x6258422c, 0x51edbdd4), WTCP(0x61f1003f, 0x5269126e), WTCP(0x618923a9, 0x52e3e4e6), + WTCP(0x6120ad0d, 0x535e3479), WTCP(0x60b79d10, 0x53d80065), WTCP(0x604df459, 0x545147eb), + WTCP(0x5fe3b38d, 0x54ca0a4b), WTCP(0x5f78db56, 0x554246c6), WTCP(0x5f0d6c5b, 0x55b9fc9e), + WTCP(0x5ea16747, 0x56312b17), WTCP(0x5e34ccc3, 0x56a7d174), WTCP(0x5dc79d7c, 0x571deefa), + WTCP(0x5d59da1e, 0x579382ee), WTCP(0x5ceb8355, 0x58088c96), WTCP(0x5c7c99d1, 0x587d0b3b), + WTCP(0x5c0d1e41, 0x58f0fe23), WTCP(0x5b9d1154, 0x59646498), WTCP(0x5b2c73bb, 0x59d73de3), + WTCP(0x5abb4629, 0x5a498950), +}; + +# ifdef ENABLE_HR_MODE +const PWord32 SineWindow360[180] = { +# else +const PWord16 SineWindow360[180] = { +# endif + WTCP(0x7fffec08, 0x00477d17), WTCP(0x7fff4c53, 0x00d676eb), WTCP(0x7ffe0cea, 0x01656fb4), + WTCP(0x7ffc2dcf, 0x01f466bf), WTCP(0x7ff9af03, 0x02835b59), WTCP(0x7ff6908a, 0x03124cd1), + WTCP(0x7ff2d268, 0x03a13a74), WTCP(0x7fee74a1, 0x0430238f), WTCP(0x7fe9773c, 0x04bf0771), + WTCP(0x7fe3da3d, 0x054de566), WTCP(0x7fdd9dac, 0x05dcbcbe), WTCP(0x7fd6c192, 0x066b8cc5), + WTCP(0x7fcf45f6, 0x06fa54c9), WTCP(0x7fc72ae1, 0x07891418), WTCP(0x7fbe705f, 0x0817ca01), + WTCP(0x7fb51679, 0x08a675d0), WTCP(0x7fab1d3c, 0x093516d4), WTCP(0x7fa084b4, 0x09c3ac5c), + WTCP(0x7f954cee, 0x0a5235b4), WTCP(0x7f8975f8, 0x0ae0b22c), WTCP(0x7f7cffe1, 0x0b6f2112), + WTCP(0x7f6feab8, 0x0bfd81b3), WTCP(0x7f62368e, 0x0c8bd35e), WTCP(0x7f53e374, 0x0d1a1562), + WTCP(0x7f44f17c, 0x0da8470d), WTCP(0x7f3560b8, 0x0e3667ad), WTCP(0x7f25313c, 0x0ec47692), + WTCP(0x7f14631c, 0x0f52730a), WTCP(0x7f02f66e, 0x0fe05c64), WTCP(0x7ef0eb45, 0x106e31ef), + WTCP(0x7ede41ba, 0x10fbf2fa), WTCP(0x7ecaf9e4, 0x11899ed3), WTCP(0x7eb713da, 0x121734cb), + WTCP(0x7ea28fb5, 0x12a4b431), WTCP(0x7e8d6d90, 0x13321c53), WTCP(0x7e77ad84, 0x13bf6c82), + WTCP(0x7e614fac, 0x144ca40e), WTCP(0x7e4a5425, 0x14d9c245), WTCP(0x7e32bb0b, 0x1566c679), + WTCP(0x7e1a847b, 0x15f3aff8), WTCP(0x7e01b095, 0x16807e14), WTCP(0x7de83f76, 0x170d301d), + WTCP(0x7dce313e, 0x1799c562), WTCP(0x7db3860e, 0x18263d35), WTCP(0x7d983e08, 0x18b296e7), + WTCP(0x7d7c594d, 0x193ed1c8), WTCP(0x7d5fd800, 0x19caed28), WTCP(0x7d42ba45, 0x1a56e85b), + WTCP(0x7d25003f, 0x1ae2c2b0), WTCP(0x7d06aa15, 0x1b6e7b7a), WTCP(0x7ce7b7ec, 0x1bfa1209), + WTCP(0x7cc829ea, 0x1c8585b0), WTCP(0x7ca80037, 0x1d10d5c1), WTCP(0x7c873afb, 0x1d9c018f), + WTCP(0x7c65da60, 0x1e27086a), WTCP(0x7c43de8d, 0x1eb1e9a6), WTCP(0x7c2147af, 0x1f3ca496), + WTCP(0x7bfe15f0, 0x1fc7388d), WTCP(0x7bda497c, 0x2051a4dd), WTCP(0x7bb5e27f, 0x20dbe8da), + WTCP(0x7b90e128, 0x216603d7), WTCP(0x7b6b45a4, 0x21eff528), WTCP(0x7b451022, 0x2279bc21), + WTCP(0x7b1e40d3, 0x23035817), WTCP(0x7af6d7e5, 0x238cc85c), WTCP(0x7aced58b, 0x24160c47), + WTCP(0x7aa639f7, 0x249f232b), WTCP(0x7a7d055a, 0x25280c5d), WTCP(0x7a5337e9, 0x25b0c734), + WTCP(0x7a28d1d8, 0x26395303), WTCP(0x79fdd35b, 0x26c1af21), WTCP(0x79d23ca9, 0x2749dae4), + WTCP(0x79a60df7, 0x27d1d5a2), WTCP(0x7979477c, 0x28599eb0), WTCP(0x794be972, 0x28e13566), + WTCP(0x791df40f, 0x2968991b), WTCP(0x78ef678e, 0x29efc925), WTCP(0x78c04429, 0x2a76c4dc), + WTCP(0x78908a1a, 0x2afd8b97), WTCP(0x7860399d, 0x2b841caf), WTCP(0x782f52ef, 0x2c0a777b), + WTCP(0x77fdd64b, 0x2c909b54), WTCP(0x77cbc3f1, 0x2d168792), WTCP(0x77991c1e, 0x2d9c3b8e), + WTCP(0x7765df12, 0x2e21b6a2), WTCP(0x77320d0c, 0x2ea6f826), WTCP(0x76fda64e, 0x2f2bff76), + WTCP(0x76c8ab18, 0x2fb0cbea), WTCP(0x76931bae, 0x30355cdc), WTCP(0x765cf850, 0x30b9b1a9), + WTCP(0x76264144, 0x313dc9aa), WTCP(0x75eef6ce, 0x31c1a43a), WTCP(0x75b71931, 0x324540b6), + WTCP(0x757ea8b5, 0x32c89e78), WTCP(0x7545a59f, 0x334bbcde), WTCP(0x750c1038, 0x33ce9b42), + WTCP(0x74d1e8c5, 0x34513903), WTCP(0x74972f91, 0x34d3957e), WTCP(0x745be4e4, 0x3555b00e), + WTCP(0x74200908, 0x35d78813), WTCP(0x73e39c48, 0x36591cea), WTCP(0x73a69ef0, 0x36da6df1), + WTCP(0x7369114b, 0x375b7a87), WTCP(0x732af3a6, 0x37dc420c), WTCP(0x72ec4650, 0x385cc3de), + WTCP(0x72ad0995, 0x38dcff5d), WTCP(0x726d3dc5, 0x395cf3e9), WTCP(0x722ce330, 0x39dca0e2), + WTCP(0x71ebfa25, 0x3a5c05aa), WTCP(0x71aa82f6, 0x3adb21a0), WTCP(0x71687df5, 0x3b59f428), + WTCP(0x7125eb74, 0x3bd87ca1), WTCP(0x70e2cbc5, 0x3c56ba70), WTCP(0x709f1f3d, 0x3cd4acf5), + WTCP(0x705ae630, 0x3d525394), WTCP(0x701620f4, 0x3dcfadaf), WTCP(0x6fd0cfdd, 0x3e4cbaac), + WTCP(0x6f8af343, 0x3ec979ed), WTCP(0x6f448b7d, 0x3f45ead7), WTCP(0x6efd98e2, 0x3fc20ccf), + WTCP(0x6eb61bcb, 0x403ddf39), WTCP(0x6e6e1492, 0x40b9617c), WTCP(0x6e25838f, 0x413492fd), + WTCP(0x6ddc691e, 0x41af7323), WTCP(0x6d92c59a, 0x422a0154), WTCP(0x6d48995f, 0x42a43cf7), + WTCP(0x6cfde4c9, 0x431e2573), WTCP(0x6cb2a836, 0x4397ba32), WTCP(0x6c66e403, 0x4410fa9a), + WTCP(0x6c1a988f, 0x4489e615), WTCP(0x6bcdc639, 0x45027c0c), WTCP(0x6b806d61, 0x457abbe8), + WTCP(0x6b328e67, 0x45f2a513), WTCP(0x6ae429ad, 0x466a36f9), WTCP(0x6a953f94, 0x46e17102), + WTCP(0x6a45d080, 0x4758529c), WTCP(0x69f5dcd2, 0x47cedb30), WTCP(0x69a564ef, 0x48450a2d), + WTCP(0x6954693b, 0x48badefd), WTCP(0x6902ea1c, 0x4930590e), WTCP(0x68b0e7f6, 0x49a577ce), + WTCP(0x685e6331, 0x4a1a3aaa), WTCP(0x680b5c33, 0x4a8ea111), WTCP(0x67b7d363, 0x4b02aa71), + WTCP(0x6763c92b, 0x4b76563a), WTCP(0x670f3df2, 0x4be9a3db), WTCP(0x66ba3223, 0x4c5c92c4), + WTCP(0x6664a627, 0x4ccf2267), WTCP(0x660e9a69, 0x4d415233), WTCP(0x65b80f55, 0x4db3219c), + WTCP(0x65610557, 0x4e249011), WTCP(0x65097cda, 0x4e959d07), WTCP(0x64b1764d, 0x4f0647f0), + WTCP(0x6458f21d, 0x4f769040), WTCP(0x63fff0b9, 0x4fe6756a), WTCP(0x63a6728f, 0x5055f6e2), + WTCP(0x634c7810, 0x50c5141e), WTCP(0x62f201ac, 0x5133cc94), WTCP(0x62970fd2, 0x51a21fb7), + WTCP(0x623ba2f6, 0x52100d01), WTCP(0x61dfbb89, 0x527d93e6), WTCP(0x618359fd, 0x52eab3de), + WTCP(0x61267ec7, 0x53576c62), WTCP(0x60c92a59, 0x53c3bce9), WTCP(0x606b5d28, 0x542fa4ed), + WTCP(0x600d17aa, 0x549b23e7), WTCP(0x5fae5a54, 0x55063950), WTCP(0x5f4f259c, 0x5570e4a3), + WTCP(0x5eef79f8, 0x55db255b), WTCP(0x5e8f57e2, 0x5644faf4), WTCP(0x5e2ebfcf, 0x56ae64e9), + WTCP(0x5dcdb239, 0x571762b6), WTCP(0x5d6c2f99, 0x577ff3da), WTCP(0x5d0a3868, 0x57e817d1), + WTCP(0x5ca7cd21, 0x584fce19), WTCP(0x5c44ee3f, 0x58b71631), WTCP(0x5be19c3c, 0x591def98), + WTCP(0x5b7dd796, 0x598459ce), WTCP(0x5b19a0c7, 0x59ea5454), WTCP(0x5ab4f84f, 0x5a4fdea9), +}; + +# ifdef ENABLE_HR_MODE +const PWord32 SineWindow480[240] = { +# else +const PWord16 SineWindow480[240] = { +# endif + WTCP(0x7ffff4c5, 0x00359dd2), WTCP(0x7fff9aef, 0x00a0d951), WTCP(0x7ffee744, 0x010c1460), + WTCP(0x7ffdd9c4, 0x01774eb2), WTCP(0x7ffc726f, 0x01e287fc), WTCP(0x7ffab147, 0x024dbff4), + WTCP(0x7ff8964d, 0x02b8f64e), WTCP(0x7ff62182, 0x03242abf), WTCP(0x7ff352e8, 0x038f5cfb), + WTCP(0x7ff02a82, 0x03fa8cb8), WTCP(0x7feca851, 0x0465b9aa), WTCP(0x7fe8cc57, 0x04d0e386), + WTCP(0x7fe49698, 0x053c0a01), WTCP(0x7fe00716, 0x05a72ccf), WTCP(0x7fdb1dd5, 0x06124ba5), + WTCP(0x7fd5dad8, 0x067d6639), WTCP(0x7fd03e23, 0x06e87c3f), WTCP(0x7fca47b9, 0x07538d6b), + WTCP(0x7fc3f7a0, 0x07be9973), WTCP(0x7fbd4dda, 0x0829a00c), WTCP(0x7fb64a6e, 0x0894a0ea), + WTCP(0x7faeed5f, 0x08ff9bc2), WTCP(0x7fa736b4, 0x096a9049), WTCP(0x7f9f2671, 0x09d57e35), + WTCP(0x7f96bc9c, 0x0a40653a), WTCP(0x7f8df93c, 0x0aab450d), WTCP(0x7f84dc55, 0x0b161d63), + WTCP(0x7f7b65ef, 0x0b80edf1), WTCP(0x7f719611, 0x0bebb66c), WTCP(0x7f676cc0, 0x0c56768a), + WTCP(0x7f5cea05, 0x0cc12dff), WTCP(0x7f520de6, 0x0d2bdc80), WTCP(0x7f46d86c, 0x0d9681c2), + WTCP(0x7f3b499d, 0x0e011d7c), WTCP(0x7f2f6183, 0x0e6baf61), WTCP(0x7f232026, 0x0ed63727), + WTCP(0x7f16858e, 0x0f40b483), WTCP(0x7f0991c4, 0x0fab272b), WTCP(0x7efc44d0, 0x10158ed4), + WTCP(0x7eee9ebe, 0x107feb33), WTCP(0x7ee09f95, 0x10ea3bfd), WTCP(0x7ed24761, 0x115480e9), + WTCP(0x7ec3962a, 0x11beb9aa), WTCP(0x7eb48bfb, 0x1228e5f8), WTCP(0x7ea528e0, 0x12930586), + WTCP(0x7e956ce1, 0x12fd180b), WTCP(0x7e85580c, 0x13671d3d), WTCP(0x7e74ea6a, 0x13d114d0), + WTCP(0x7e642408, 0x143afe7b), WTCP(0x7e5304f2, 0x14a4d9f4), WTCP(0x7e418d32, 0x150ea6ef), + WTCP(0x7e2fbcd6, 0x15786522), WTCP(0x7e1d93ea, 0x15e21445), WTCP(0x7e0b127a, 0x164bb40b), + WTCP(0x7df83895, 0x16b5442b), WTCP(0x7de50646, 0x171ec45c), WTCP(0x7dd17b9c, 0x17883452), + WTCP(0x7dbd98a4, 0x17f193c5), WTCP(0x7da95d6c, 0x185ae269), WTCP(0x7d94ca03, 0x18c41ff6), + WTCP(0x7d7fde76, 0x192d4c21), WTCP(0x7d6a9ad5, 0x199666a0), WTCP(0x7d54ff2e, 0x19ff6f2a), + WTCP(0x7d3f0b90, 0x1a686575), WTCP(0x7d28c00c, 0x1ad14938), WTCP(0x7d121cb0, 0x1b3a1a28), + WTCP(0x7cfb218c, 0x1ba2d7fc), WTCP(0x7ce3ceb2, 0x1c0b826a), WTCP(0x7ccc2430, 0x1c74192a), + WTCP(0x7cb42217, 0x1cdc9bf2), WTCP(0x7c9bc87a, 0x1d450a78), WTCP(0x7c831767, 0x1dad6473), + WTCP(0x7c6a0ef2, 0x1e15a99a), WTCP(0x7c50af2b, 0x1e7dd9a4), WTCP(0x7c36f824, 0x1ee5f447), + WTCP(0x7c1ce9ef, 0x1f4df93a), WTCP(0x7c02849f, 0x1fb5e836), WTCP(0x7be7c847, 0x201dc0ef), + WTCP(0x7bccb4f8, 0x2085831f), WTCP(0x7bb14ac5, 0x20ed2e7b), WTCP(0x7b9589c3, 0x2154c2bb), + WTCP(0x7b797205, 0x21bc3f97), WTCP(0x7b5d039e, 0x2223a4c5), WTCP(0x7b403ea2, 0x228af1fe), + WTCP(0x7b232325, 0x22f226f8), WTCP(0x7b05b13d, 0x2359436c), WTCP(0x7ae7e8fc, 0x23c04710), + WTCP(0x7ac9ca7a, 0x2427319d), WTCP(0x7aab55ca, 0x248e02cb), WTCP(0x7a8c8b01, 0x24f4ba50), + WTCP(0x7a6d6a37, 0x255b57e6), WTCP(0x7a4df380, 0x25c1db44), WTCP(0x7a2e26f2, 0x26284422), + WTCP(0x7a0e04a4, 0x268e9238), WTCP(0x79ed8cad, 0x26f4c53e), WTCP(0x79ccbf22, 0x275adcee), + WTCP(0x79ab9c1c, 0x27c0d8fe), WTCP(0x798a23b1, 0x2826b928), WTCP(0x796855f9, 0x288c7d24), + WTCP(0x7946330c, 0x28f224ab), WTCP(0x7923bb01, 0x2957af74), WTCP(0x7900edf2, 0x29bd1d3a), + WTCP(0x78ddcbf5, 0x2a226db5), WTCP(0x78ba5524, 0x2a87a09d), WTCP(0x78968998, 0x2aecb5ac), + WTCP(0x7872696a, 0x2b51ac9a), WTCP(0x784df4b3, 0x2bb68522), WTCP(0x78292b8d, 0x2c1b3efb), + WTCP(0x78040e12, 0x2c7fd9e0), WTCP(0x77de9c5b, 0x2ce45589), WTCP(0x77b8d683, 0x2d48b1b1), + WTCP(0x7792bca5, 0x2dacee11), WTCP(0x776c4edb, 0x2e110a62), WTCP(0x77458d40, 0x2e75065e), + WTCP(0x771e77f0, 0x2ed8e1c0), WTCP(0x76f70f05, 0x2f3c9c40), WTCP(0x76cf529c, 0x2fa03599), + WTCP(0x76a742d1, 0x3003ad85), WTCP(0x767edfbe, 0x306703bf), WTCP(0x76562982, 0x30ca3800), + WTCP(0x762d2038, 0x312d4a03), WTCP(0x7603c3fd, 0x31903982), WTCP(0x75da14ef, 0x31f30638), + WTCP(0x75b01329, 0x3255afe0), WTCP(0x7585becb, 0x32b83634), WTCP(0x755b17f2, 0x331a98ef), + WTCP(0x75301ebb, 0x337cd7cd), WTCP(0x7504d345, 0x33def287), WTCP(0x74d935ae, 0x3440e8da), + WTCP(0x74ad4615, 0x34a2ba81), WTCP(0x74810499, 0x35046736), WTCP(0x74547158, 0x3565eeb6), + WTCP(0x74278c72, 0x35c750bc), WTCP(0x73fa5607, 0x36288d03), WTCP(0x73ccce36, 0x3689a348), + WTCP(0x739ef51f, 0x36ea9346), WTCP(0x7370cae2, 0x374b5cb9), WTCP(0x73424fa0, 0x37abff5d), + WTCP(0x73138379, 0x380c7aee), WTCP(0x72e4668f, 0x386ccf2a), WTCP(0x72b4f902, 0x38ccfbcb), + WTCP(0x72853af3, 0x392d008f), WTCP(0x72552c85, 0x398cdd32), WTCP(0x7224cdd8, 0x39ec9172), + WTCP(0x71f41f0f, 0x3a4c1d09), WTCP(0x71c3204c, 0x3aab7fb7), WTCP(0x7191d1b1, 0x3b0ab937), + WTCP(0x71603361, 0x3b69c947), WTCP(0x712e457f, 0x3bc8afa5), WTCP(0x70fc082d, 0x3c276c0d), + WTCP(0x70c97b90, 0x3c85fe3d), WTCP(0x70969fca, 0x3ce465f3), WTCP(0x706374ff, 0x3d42a2ec), + WTCP(0x702ffb54, 0x3da0b4e7), WTCP(0x6ffc32eb, 0x3dfe9ba1), WTCP(0x6fc81bea, 0x3e5c56d8), + WTCP(0x6f93b676, 0x3eb9e64b), WTCP(0x6f5f02b2, 0x3f1749b8), WTCP(0x6f2a00c4, 0x3f7480dd), + WTCP(0x6ef4b0d1, 0x3fd18b7a), WTCP(0x6ebf12ff, 0x402e694c), WTCP(0x6e892772, 0x408b1a12), + WTCP(0x6e52ee52, 0x40e79d8c), WTCP(0x6e1c67c4, 0x4143f379), WTCP(0x6de593ee, 0x41a01b97), + WTCP(0x6dae72f7, 0x41fc15a6), WTCP(0x6d770506, 0x4257e166), WTCP(0x6d3f4a40, 0x42b37e96), + WTCP(0x6d0742cf, 0x430eecf6), WTCP(0x6cceeed8, 0x436a2c45), WTCP(0x6c964e83, 0x43c53c44), + WTCP(0x6c5d61f9, 0x44201cb2), WTCP(0x6c242960, 0x447acd50), WTCP(0x6beaa4e2, 0x44d54ddf), + WTCP(0x6bb0d4a7, 0x452f9e1e), WTCP(0x6b76b8d6, 0x4589bdcf), WTCP(0x6b3c519a, 0x45e3acb1), + WTCP(0x6b019f1a, 0x463d6a87), WTCP(0x6ac6a180, 0x4696f710), WTCP(0x6a8b58f6, 0x46f0520f), + WTCP(0x6a4fc5a6, 0x47497b44), WTCP(0x6a13e7b8, 0x47a27271), WTCP(0x69d7bf57, 0x47fb3757), + WTCP(0x699b4cad, 0x4853c9b9), WTCP(0x695e8fe5, 0x48ac2957), WTCP(0x69218929, 0x490455f4), + WTCP(0x68e438a4, 0x495c4f52), WTCP(0x68a69e81, 0x49b41533), WTCP(0x6868baec, 0x4a0ba75b), + WTCP(0x682a8e0f, 0x4a63058a), WTCP(0x67ec1817, 0x4aba2f84), WTCP(0x67ad592f, 0x4b11250c), + WTCP(0x676e5183, 0x4b67e5e4), WTCP(0x672f013f, 0x4bbe71d1), WTCP(0x66ef6891, 0x4c14c894), + WTCP(0x66af87a4, 0x4c6ae9f2), WTCP(0x666f5ea6, 0x4cc0d5ae), WTCP(0x662eedc3, 0x4d168b8b), + WTCP(0x65ee3529, 0x4d6c0b4e), WTCP(0x65ad3505, 0x4dc154bb), WTCP(0x656bed84, 0x4e166795), + WTCP(0x652a5ed6, 0x4e6b43a2), WTCP(0x64e88926, 0x4ebfe8a5), WTCP(0x64a66ca5, 0x4f145662), + WTCP(0x6464097f, 0x4f688ca0), WTCP(0x64215fe5, 0x4fbc8b22), WTCP(0x63de7003, 0x501051ae), + WTCP(0x639b3a0b, 0x5063e008), WTCP(0x6357be2a, 0x50b735f8), WTCP(0x6313fc90, 0x510a5340), + WTCP(0x62cff56c, 0x515d37a9), WTCP(0x628ba8ef, 0x51afe2f6), WTCP(0x62471749, 0x520254ef), + WTCP(0x620240a8, 0x52548d59), WTCP(0x61bd253f, 0x52a68bfb), WTCP(0x6177c53c, 0x52f8509b), + WTCP(0x613220d2, 0x5349daff), WTCP(0x60ec3830, 0x539b2af0), WTCP(0x60a60b88, 0x53ec4032), + WTCP(0x605f9b0b, 0x543d1a8e), WTCP(0x6018e6eb, 0x548db9cb), WTCP(0x5fd1ef59, 0x54de1db1), + WTCP(0x5f8ab487, 0x552e4605), WTCP(0x5f4336a7, 0x557e3292), WTCP(0x5efb75ea, 0x55cde31e), + WTCP(0x5eb37285, 0x561d5771), WTCP(0x5e6b2ca8, 0x566c8f55), WTCP(0x5e22a487, 0x56bb8a90), + WTCP(0x5dd9da55, 0x570a48ec), WTCP(0x5d90ce45, 0x5758ca31), WTCP(0x5d47808a, 0x57a70e29), + WTCP(0x5cfdf157, 0x57f5149d), WTCP(0x5cb420e0, 0x5842dd54), WTCP(0x5c6a0f59, 0x5890681a), + WTCP(0x5c1fbcf6, 0x58ddb4b8), WTCP(0x5bd529eb, 0x592ac2f7), WTCP(0x5b8a566c, 0x597792a1), + WTCP(0x5b3f42ae, 0x59c42381), WTCP(0x5af3eee6, 0x5a107561), WTCP(0x5aa85b48, 0x5a5c880a), +}; + +# ifdef ENABLE_HR_MODE +#ifdef CR8_G_ADD_75MS +const PWord32 SineWindow720[360] = { + WTCP(0x7ffffb01, 0x0023be8d), WTCP(0x7fffd314, 0x006b3b9b), WTCP(0x7fff833a, 0x00b2b888), + WTCP(0x7fff0b72, 0x00fa353e), WTCP(0x7ffe6bbe, 0x0141b1a5), WTCP(0x7ffda41c, 0x01892da8), + WTCP(0x7ffcb48e, 0x01d0a930), WTCP(0x7ffb9d14, 0x02182427), WTCP(0x7ffa5dae, 0x025f9e77), + WTCP(0x7ff8f65d, 0x02a7180a), WTCP(0x7ff76720, 0x02ee90c8), WTCP(0x7ff5aff9, 0x0336089d), + WTCP(0x7ff3d0e8, 0x037d7f71), WTCP(0x7ff1c9ee, 0x03c4f52e), WTCP(0x7fef9b0a, 0x040c69bf), + WTCP(0x7fed443f, 0x0453dd0c), WTCP(0x7feac58c, 0x049b4f00), WTCP(0x7fe81ef2, 0x04e2bf83), + WTCP(0x7fe55073, 0x052a2e81), WTCP(0x7fe25a0e, 0x05719be2), WTCP(0x7fdf3bc6, 0x05b90791), + WTCP(0x7fdbf59a, 0x06007176), WTCP(0x7fd8878d, 0x0647d97c), WTCP(0x7fd4f19f, 0x068f3f8d), + WTCP(0x7fd133d0, 0x06d6a392), WTCP(0x7fcd4e23, 0x071e0575), WTCP(0x7fc94099, 0x0765651f), + WTCP(0x7fc50b33, 0x07acc27b), WTCP(0x7fc0adf1, 0x07f41d72), WTCP(0x7fbc28d6, 0x083b75ee), + WTCP(0x7fb77be3, 0x0882cbd8), WTCP(0x7fb2a71a, 0x08ca1f1b), WTCP(0x7fadaa7b, 0x09116fa0), + WTCP(0x7fa88608, 0x0958bd51), WTCP(0x7fa339c4, 0x09a00817), WTCP(0x7f9dc5b0, 0x09e74fdd), + WTCP(0x7f9829cc, 0x0a2e948c), WTCP(0x7f92661c, 0x0a75d60e), WTCP(0x7f8c7aa1, 0x0abd144d), + WTCP(0x7f86675c, 0x0b044f32), WTCP(0x7f802c51, 0x0b4b86a8), WTCP(0x7f79c980, 0x0b92ba97), + WTCP(0x7f733eeb, 0x0bd9eaeb), WTCP(0x7f6c8c95, 0x0c21178c), WTCP(0x7f65b280, 0x0c684064), + WTCP(0x7f5eb0ae, 0x0caf655e), WTCP(0x7f578720, 0x0cf68662), WTCP(0x7f5035da, 0x0d3da35c), + WTCP(0x7f48bcde, 0x0d84bc34), WTCP(0x7f411c2e, 0x0dcbd0d5), WTCP(0x7f3953cb, 0x0e12e128), + WTCP(0x7f3163ba, 0x0e59ed17), WTCP(0x7f294bfc, 0x0ea0f48c), WTCP(0x7f210c93, 0x0ee7f771), + WTCP(0x7f18a583, 0x0f2ef5b0), WTCP(0x7f1016cd, 0x0f75ef32), WTCP(0x7f076075, 0x0fbce3e2), + WTCP(0x7efe827e, 0x1003d3a9), WTCP(0x7ef57cea, 0x104abe71), WTCP(0x7eec4fbb, 0x1091a424), + WTCP(0x7ee2faf5, 0x10d884ad), WTCP(0x7ed97e9b, 0x111f5ff3), WTCP(0x7ecfdaaf, 0x116635e3), + WTCP(0x7ec60f35, 0x11ad0665), WTCP(0x7ebc1c30, 0x11f3d164), WTCP(0x7eb201a2, 0x123a96c9), + WTCP(0x7ea7bf90, 0x1281567f), WTCP(0x7e9d55fb, 0x12c8106e), WTCP(0x7e92c4e8, 0x130ec482), + WTCP(0x7e880c5a, 0x135572a5), WTCP(0x7e7d2c53, 0x139c1abf), WTCP(0x7e7224d8, 0x13e2bcbb), + WTCP(0x7e66f5ec, 0x14295884), WTCP(0x7e5b9f92, 0x146fee02), WTCP(0x7e5021ce, 0x14b67d21), + WTCP(0x7e447ca3, 0x14fd05c9), WTCP(0x7e38b016, 0x154387e6), WTCP(0x7e2cbc29, 0x158a0360), + WTCP(0x7e20a0e1, 0x15d07823), WTCP(0x7e145e41, 0x1616e618), WTCP(0x7e07f44d, 0x165d4d28), + WTCP(0x7dfb6309, 0x16a3ad3f), WTCP(0x7deeaa79, 0x16ea0646), WTCP(0x7de1caa1, 0x17305827), + WTCP(0x7dd4c384, 0x1776a2cd), WTCP(0x7dc79528, 0x17bce621), WTCP(0x7dba3f90, 0x1803220d), + WTCP(0x7dacc2c0, 0x1849567c), WTCP(0x7d9f1ebc, 0x188f8357), WTCP(0x7d915389, 0x18d5a889), + WTCP(0x7d83612b, 0x191bc5fc), WTCP(0x7d7547a6, 0x1961db9b), WTCP(0x7d6706ff, 0x19a7e94e), + WTCP(0x7d589f3a, 0x19edef00), WTCP(0x7d4a105c, 0x1a33ec9c), WTCP(0x7d3b5a69, 0x1a79e20c), + WTCP(0x7d2c7d66, 0x1abfcf39), WTCP(0x7d1d7957, 0x1b05b40e), WTCP(0x7d0e4e41, 0x1b4b9076), + WTCP(0x7cfefc29, 0x1b91645a), WTCP(0x7cef8314, 0x1bd72fa4), WTCP(0x7cdfe306, 0x1c1cf23f), + WTCP(0x7cd01c05, 0x1c62ac16), WTCP(0x7cc02e14, 0x1ca85d12), WTCP(0x7cb0193a, 0x1cee051d), + WTCP(0x7c9fdd7b, 0x1d33a422), WTCP(0x7c8f7add, 0x1d793a0b), WTCP(0x7c7ef164, 0x1dbec6c3), + WTCP(0x7c6e4115, 0x1e044a33), WTCP(0x7c5d69f6, 0x1e49c447), WTCP(0x7c4c6c0d, 0x1e8f34e8), + WTCP(0x7c3b475d, 0x1ed49c00), WTCP(0x7c29fbed, 0x1f19f97b), WTCP(0x7c1889c3, 0x1f5f4d42), + WTCP(0x7c06f0e2, 0x1fa49740), WTCP(0x7bf53152, 0x1fe9d75f), WTCP(0x7be34b17, 0x202f0d8a), + WTCP(0x7bd13e38, 0x207439aa), WTCP(0x7bbf0ab9, 0x20b95bac), WTCP(0x7bacb0a0, 0x20fe7378), + WTCP(0x7b9a2ff4, 0x214380f9), WTCP(0x7b8788b9, 0x2188841a), WTCP(0x7b74baf7, 0x21cd7cc5), + WTCP(0x7b61c6b2, 0x22126ae5), WTCP(0x7b4eabf0, 0x22574e65), WTCP(0x7b3b6ab8, 0x229c272e), + WTCP(0x7b28030f, 0x22e0f52b), WTCP(0x7b1474fc, 0x2325b847), WTCP(0x7b00c085, 0x236a706d), + WTCP(0x7aece5af, 0x23af1d86), WTCP(0x7ad8e481, 0x23f3bf7e), WTCP(0x7ac4bd02, 0x2438563f), + WTCP(0x7ab06f36, 0x247ce1b4), WTCP(0x7a9bfb26, 0x24c161c7), WTCP(0x7a8760d7, 0x2505d663), + WTCP(0x7a72a050, 0x254a3f72), WTCP(0x7a5db997, 0x258e9ce0), WTCP(0x7a48acb2, 0x25d2ee97), + WTCP(0x7a3379a8, 0x26173481), WTCP(0x7a1e2081, 0x265b6e8a), WTCP(0x7a08a141, 0x269f9c9c), + WTCP(0x79f2fbf1, 0x26e3bea1), WTCP(0x79dd3097, 0x2727d485), WTCP(0x79c73f3a, 0x276bde33), + WTCP(0x79b127e0, 0x27afdb94), WTCP(0x799aea91, 0x27f3cc94), WTCP(0x79848753, 0x2837b11e), + WTCP(0x796dfe2d, 0x287b891c), WTCP(0x79574f27, 0x28bf547a), WTCP(0x79407a47, 0x29031322), + WTCP(0x79297f95, 0x2946c4ff), WTCP(0x79125f18, 0x298a69fc), WTCP(0x78fb18d6, 0x29ce0204), + WTCP(0x78e3acd8, 0x2a118d01), WTCP(0x78cc1b25, 0x2a550adf), WTCP(0x78b463c3, 0x2a987b89), + WTCP(0x789c86bb, 0x2adbdee9), WTCP(0x78848413, 0x2b1f34eb), WTCP(0x786c5bd4, 0x2b627d79), + WTCP(0x78540e04, 0x2ba5b87f), WTCP(0x783b9aac, 0x2be8e5e8), WTCP(0x782301d2, 0x2c2c059e), + WTCP(0x780a4380, 0x2c6f178d), WTCP(0x77f15fbb, 0x2cb21ba0), WTCP(0x77d8568d, 0x2cf511c2), + WTCP(0x77bf27fd, 0x2d37f9dd), WTCP(0x77a5d413, 0x2d7ad3de), WTCP(0x778c5ad6, 0x2dbd9faf), + WTCP(0x7772bc4f, 0x2e005d3c), WTCP(0x7758f885, 0x2e430c6f), WTCP(0x773f0f81, 0x2e85ad34), + WTCP(0x7725014b, 0x2ec83f76), WTCP(0x770acdeb, 0x2f0ac320), WTCP(0x76f07569, 0x2f4d381e), + WTCP(0x76d5f7cd, 0x2f8f9e5a), WTCP(0x76bb5520, 0x2fd1f5c1), WTCP(0x76a08d6a, 0x30143e3d), + WTCP(0x7685a0b2, 0x305677ba), WTCP(0x766a8f03, 0x3098a222), WTCP(0x764f5863, 0x30dabd63), + WTCP(0x7633fcdc, 0x311cc966), WTCP(0x76187c76, 0x315ec617), WTCP(0x75fcd739, 0x31a0b362), + WTCP(0x75e10d2f, 0x31e29131), WTCP(0x75c51e60, 0x32245f72), WTCP(0x75a90ad4, 0x32661e0e), + WTCP(0x758cd295, 0x32a7ccf2), WTCP(0x757075ab, 0x32e96c09), WTCP(0x7553f41f, 0x332afb3e), + WTCP(0x75374dfa, 0x336c7a7d), WTCP(0x751a8345, 0x33ade9b2), WTCP(0x74fd9409, 0x33ef48c8), + WTCP(0x74e0804f, 0x343097ab), WTCP(0x74c3481f, 0x3471d647), WTCP(0x74a5eb84, 0x34b30487), + WTCP(0x74886a86, 0x34f42256), WTCP(0x746ac52e, 0x35352fa1), WTCP(0x744cfb86, 0x35762c53), + WTCP(0x742f0d97, 0x35b71858), WTCP(0x7410fb6a, 0x35f7f39b), WTCP(0x73f2c509, 0x3638be09), + WTCP(0x73d46a7d, 0x3679778d), WTCP(0x73b5ebd0, 0x36ba2013), WTCP(0x7397490b, 0x36fab787), + WTCP(0x73788237, 0x373b3dd5), WTCP(0x7359975f, 0x377bb2e8), WTCP(0x733a888b, 0x37bc16ad), + WTCP(0x731b55c6, 0x37fc690f), WTCP(0x72fbff1a, 0x383ca9fb), WTCP(0x72dc848f, 0x387cd95b), + WTCP(0x72bce631, 0x38bcf71d), WTCP(0x729d2408, 0x38fd032d), WTCP(0x727d3e1f, 0x393cfd75), + WTCP(0x725d347f, 0x397ce5e3), WTCP(0x723d0733, 0x39bcbc62), WTCP(0x721cb645, 0x39fc80df), + WTCP(0x71fc41be, 0x3a3c3345), WTCP(0x71dba9aa, 0x3a7bd381), WTCP(0x71baee11, 0x3abb617f), + WTCP(0x719a0eff, 0x3afadd2b), WTCP(0x71790c7d, 0x3b3a4671), WTCP(0x7157e696, 0x3b799d3e), + WTCP(0x71369d54, 0x3bb8e17d), WTCP(0x711530c1, 0x3bf8131b), WTCP(0x70f3a0e8, 0x3c373205), + WTCP(0x70d1edd4, 0x3c763e26), WTCP(0x70b0178f, 0x3cb5376b), WTCP(0x708e1e23, 0x3cf41dc0), + WTCP(0x706c019b, 0x3d32f112), WTCP(0x7049c202, 0x3d71b14d), WTCP(0x70275f63, 0x3db05e5d), + WTCP(0x7004d9c7, 0x3deef830), WTCP(0x6fe2313b, 0x3e2d7eb0), WTCP(0x6fbf65c8, 0x3e6bf1cc), + WTCP(0x6f9c7779, 0x3eaa516f), WTCP(0x6f79665a, 0x3ee89d86), WTCP(0x6f563276, 0x3f26d5fd), + WTCP(0x6f32dbd7, 0x3f64fac2), WTCP(0x6f0f6288, 0x3fa30bc0), WTCP(0x6eebc694, 0x3fe108e5), + WTCP(0x6ec80808, 0x401ef21d), WTCP(0x6ea426ed, 0x405cc754), WTCP(0x6e80234e, 0x409a8878), + WTCP(0x6e5bfd38, 0x40d83575), WTCP(0x6e37b4b6, 0x4115ce38), WTCP(0x6e1349d2, 0x415352ad), + WTCP(0x6deebc98, 0x4190c2c3), WTCP(0x6dca0d14, 0x41ce1e64), WTCP(0x6da53b50, 0x420b657f), + WTCP(0x6d804759, 0x42489800), WTCP(0x6d5b313a, 0x4285b5d4), WTCP(0x6d35f8ff, 0x42c2bee7), + WTCP(0x6d109eb2, 0x42ffb328), WTCP(0x6ceb2260, 0x433c9283), WTCP(0x6cc58415, 0x43795ce4), + WTCP(0x6c9fc3dc, 0x43b6123a), WTCP(0x6c79e1c1, 0x43f2b270), WTCP(0x6c53ddd0, 0x442f3d75), + WTCP(0x6c2db815, 0x446bb335), WTCP(0x6c07709b, 0x44a8139d), WTCP(0x6be1076e, 0x44e45e9b), + WTCP(0x6bba7c9b, 0x4520941b), WTCP(0x6b93d02d, 0x455cb40c), WTCP(0x6b6d0232, 0x4598be59), + WTCP(0x6b4612b3, 0x45d4b2f1), WTCP(0x6b1f01bf, 0x461091c1), WTCP(0x6af7cf60, 0x464c5ab6), + WTCP(0x6ad07ba4, 0x46880dbd), WTCP(0x6aa90696, 0x46c3aac5), WTCP(0x6a817043, 0x46ff31b9), + WTCP(0x6a59b8b7, 0x473aa288), WTCP(0x6a31dfff, 0x4775fd1f), WTCP(0x6a09e626, 0x47b1416c), + WTCP(0x69e1cb3a, 0x47ec6f5b), WTCP(0x69b98f47, 0x482786dc), WTCP(0x6991325a, 0x486287da), + WTCP(0x6968b47e, 0x489d7245), WTCP(0x694015c2, 0x48d84609), WTCP(0x69175630, 0x49130314), + WTCP(0x68ee75d7, 0x494da953), WTCP(0x68c574c3, 0x498838b6), WTCP(0x689c5300, 0x49c2b128), + WTCP(0x6873109c, 0x49fd1298), WTCP(0x6849ada3, 0x4a375cf4), WTCP(0x68202a22, 0x4a71902a), + WTCP(0x67f68626, 0x4aabac27), WTCP(0x67ccc1bd, 0x4ae5b0d9), WTCP(0x67a2dcf3, 0x4b1f9e2f), + WTCP(0x6778d7d5, 0x4b597416), WTCP(0x674eb270, 0x4b93327b), WTCP(0x67246cd3, 0x4bccd94e), + WTCP(0x66fa0708, 0x4c06687c), WTCP(0x66cf811f, 0x4c3fdff3), WTCP(0x66a4db24, 0x4c793fa1), + WTCP(0x667a1524, 0x4cb28775), WTCP(0x664f2f2e, 0x4cebb75c), WTCP(0x6624294d, 0x4d24cf44), + WTCP(0x65f90390, 0x4d5dcf1c), WTCP(0x65cdbe05, 0x4d96b6d3), WTCP(0x65a258b7, 0x4dcf8655), + WTCP(0x6576d3b6, 0x4e083d93), WTCP(0x654b2f0f, 0x4e40dc78), WTCP(0x651f6acf, 0x4e7962f6), + WTCP(0x64f38704, 0x4eb1d0f8), WTCP(0x64c783bc, 0x4eea266f), WTCP(0x649b6104, 0x4f226348), + WTCP(0x646f1eeb, 0x4f5a8772), WTCP(0x6442bd7d, 0x4f9292db), WTCP(0x64163cc9, 0x4fca8572), + WTCP(0x63e99cdd, 0x50025f26), WTCP(0x63bcddc6, 0x503a1fe4), WTCP(0x638fff93, 0x5071c79c), + WTCP(0x63630252, 0x50a9563d), WTCP(0x6335e610, 0x50e0cbb4), WTCP(0x6308aadc, 0x511827f0), + WTCP(0x62db50c4, 0x514f6ae1), WTCP(0x62add7d5, 0x51869476), WTCP(0x6280401f, 0x51bda49c), + WTCP(0x625289af, 0x51f49b42), WTCP(0x6224b494, 0x522b7859), WTCP(0x61f6c0dc, 0x52623bcd), + WTCP(0x61c8ae94, 0x5298e58f), WTCP(0x619a7dcd, 0x52cf758e), WTCP(0x616c2e93, 0x5305ebb8), + WTCP(0x613dc0f6, 0x533c47fc), WTCP(0x610f3504, 0x53728a49), WTCP(0x60e08acb, 0x53a8b28f), + WTCP(0x60b1c25b, 0x53dec0bc), WTCP(0x6082dbc0, 0x5414b4c0), WTCP(0x6053d70c, 0x544a8e8a), + WTCP(0x6024b44b, 0x54804e09), WTCP(0x5ff5738c, 0x54b5f32c), WTCP(0x5fc614df, 0x54eb7de2), + WTCP(0x5f969852, 0x5520ee1c), WTCP(0x5f66fdf4, 0x555643c8), WTCP(0x5f3745d4, 0x558b7ed5), + WTCP(0x5f077001, 0x55c09f33), WTCP(0x5ed77c89, 0x55f5a4d2), WTCP(0x5ea76b7c, 0x562a8fa0), + WTCP(0x5e773ce8, 0x565f5f8e), WTCP(0x5e46f0dc, 0x5694148a), WTCP(0x5e168769, 0x56c8ae85), + WTCP(0x5de6009c, 0x56fd2d6e), WTCP(0x5db55c85, 0x57319134), WTCP(0x5d849b33, 0x5765d9c8), + WTCP(0x5d53bcb5, 0x579a0719), WTCP(0x5d22c11b, 0x57ce1916), WTCP(0x5cf1a874, 0x58020fb0), + WTCP(0x5cc072ce, 0x5835ead6), WTCP(0x5c8f203a, 0x5869aa78), WTCP(0x5c5db0c7, 0x589d4e87), + WTCP(0x5c2c2484, 0x58d0d6f0), WTCP(0x5bfa7b81, 0x590443a6), WTCP(0x5bc8b5cd, 0x59379497), + WTCP(0x5b96d378, 0x596ac9b5), WTCP(0x5b64d491, 0x599de2ed), WTCP(0x5b32b928, 0x59d0e032), + WTCP(0x5b00814c, 0x5a03c172), WTCP(0x5ace2d0e, 0x5a36869f), WTCP(0x5a9bbc7c, 0x5a692fa7) +}; +#endif + +const PWord32 SineWindow960[480] = { + WTCP(0x7ffffd30, 0x001aceea), WTCP(0x7fffe6bb, 0x00506cb9), WTCP(0x7fffb9d0, 0x00860a79), + WTCP(0x7fff7670, 0x00bba822), WTCP(0x7fff1c9a, 0x00f145ab), WTCP(0x7ffeac4f, 0x0126e309), + WTCP(0x7ffe258f, 0x015c8033), WTCP(0x7ffd8859, 0x01921d20), WTCP(0x7ffcd4af, 0x01c7b9c6), + WTCP(0x7ffc0a90, 0x01fd561d), WTCP(0x7ffb29fc, 0x0232f21a), WTCP(0x7ffa32f3, 0x02688db4), + WTCP(0x7ff92576, 0x029e28e2), WTCP(0x7ff80185, 0x02d3c39b), WTCP(0x7ff6c71f, 0x03095dd5), + WTCP(0x7ff57646, 0x033ef786), WTCP(0x7ff40ef9, 0x037490a5), WTCP(0x7ff29139, 0x03aa292a), + WTCP(0x7ff0fd06, 0x03dfc109), WTCP(0x7fef525f, 0x0415583b), WTCP(0x7fed9147, 0x044aeeb5), + WTCP(0x7febb9bc, 0x0480846e), WTCP(0x7fe9cbbf, 0x04b6195d), WTCP(0x7fe7c751, 0x04ebad79), + WTCP(0x7fe5ac71, 0x052140b7), WTCP(0x7fe37b21, 0x0556d30f), WTCP(0x7fe13360, 0x058c6478), + WTCP(0x7fded52f, 0x05c1f4e7), WTCP(0x7fdc608e, 0x05f78453), WTCP(0x7fd9d57e, 0x062d12b3), + WTCP(0x7fd73400, 0x06629ffe), WTCP(0x7fd47c13, 0x06982c2b), WTCP(0x7fd1adb8, 0x06cdb72f), + WTCP(0x7fcec8f0, 0x07034101), WTCP(0x7fcbcdbb, 0x0738c998), WTCP(0x7fc8bc1a, 0x076e50eb), + WTCP(0x7fc5940d, 0x07a3d6f0), WTCP(0x7fc25595, 0x07d95b9e), WTCP(0x7fbf00b2, 0x080edeec), + WTCP(0x7fbb9566, 0x084460cf), WTCP(0x7fb813af, 0x0879e140), WTCP(0x7fb47b90, 0x08af6033), + WTCP(0x7fb0cd09, 0x08e4dda0), WTCP(0x7fad081a, 0x091a597e), WTCP(0x7fa92cc4, 0x094fd3c3), + WTCP(0x7fa53b08, 0x09854c66), WTCP(0x7fa132e7, 0x09bac35d), WTCP(0x7f9d1460, 0x09f0389f), + WTCP(0x7f98df76, 0x0a25ac22), WTCP(0x7f949428, 0x0a5b1dde), WTCP(0x7f903278, 0x0a908dc9), + WTCP(0x7f8bba65, 0x0ac5fbd9), WTCP(0x7f872bf2, 0x0afb6805), WTCP(0x7f82871e, 0x0b30d244), + WTCP(0x7f7dcbeb, 0x0b663a8c), WTCP(0x7f78fa5a, 0x0b9ba0d5), WTCP(0x7f74126a, 0x0bd10513), + WTCP(0x7f6f141e, 0x0c06673f), WTCP(0x7f69ff75, 0x0c3bc74f), WTCP(0x7f64d472, 0x0c71253a), + WTCP(0x7f5f9314, 0x0ca680f5), WTCP(0x7f5a3b5d, 0x0cdbda79), WTCP(0x7f54cd4e, 0x0d1131ba), + WTCP(0x7f4f48e7, 0x0d4686b1), WTCP(0x7f49ae29, 0x0d7bd954), WTCP(0x7f43fd17, 0x0db12998), + WTCP(0x7f3e35af, 0x0de67776), WTCP(0x7f3857f5, 0x0e1bc2e4), WTCP(0x7f3263e8, 0x0e510bd7), + WTCP(0x7f2c5989, 0x0e865248), WTCP(0x7f2638da, 0x0ebb962c), WTCP(0x7f2001dc, 0x0ef0d77b), + WTCP(0x7f19b490, 0x0f26162a), WTCP(0x7f1350f7, 0x0f5b5231), WTCP(0x7f0cd711, 0x0f908b86), + WTCP(0x7f0646e1, 0x0fc5c220), WTCP(0x7effa068, 0x0ffaf5f6), WTCP(0x7ef8e3a5, 0x103026fe), + WTCP(0x7ef2109c, 0x1065552e), WTCP(0x7eeb274c, 0x109a807e), WTCP(0x7ee427b8, 0x10cfa8e5), + WTCP(0x7edd11e0, 0x1104ce58), WTCP(0x7ed5e5c5, 0x1139f0cf), WTCP(0x7ecea36a, 0x116f1040), + WTCP(0x7ec74ace, 0x11a42ca2), WTCP(0x7ebfdbf4, 0x11d945eb), WTCP(0x7eb856dd, 0x120e5c13), + WTCP(0x7eb0bb89, 0x12436f10), WTCP(0x7ea909fb, 0x12787ed8), WTCP(0x7ea14234, 0x12ad8b63), + WTCP(0x7e996435, 0x12e294a7), WTCP(0x7e916fff, 0x13179a9a), WTCP(0x7e896594, 0x134c9d34), + WTCP(0x7e8144f5, 0x13819c6b), WTCP(0x7e790e24, 0x13b69836), WTCP(0x7e70c123, 0x13eb908c), + WTCP(0x7e685df1, 0x14208562), WTCP(0x7e5fe492, 0x145576b1), WTCP(0x7e575507, 0x148a646e), + WTCP(0x7e4eaf50, 0x14bf4e91), WTCP(0x7e45f370, 0x14f43510), WTCP(0x7e3d2168, 0x152917e1), + WTCP(0x7e34393a, 0x155df6fc), WTCP(0x7e2b3ae7, 0x1592d257), WTCP(0x7e222671, 0x15c7a9ea), + WTCP(0x7e18fbd9, 0x15fc7da9), WTCP(0x7e0fbb21, 0x16314d8e), WTCP(0x7e06644b, 0x1666198d), + WTCP(0x7dfcf758, 0x169ae19f), WTCP(0x7df3744a, 0x16cfa5b9), WTCP(0x7de9db22, 0x170465d2), + WTCP(0x7de02be3, 0x173921e2), WTCP(0x7dd6668e, 0x176dd9de), WTCP(0x7dcc8b24, 0x17a28dbe), + WTCP(0x7dc299a8, 0x17d73d79), WTCP(0x7db8921b, 0x180be904), WTCP(0x7dae747f, 0x18409058), + WTCP(0x7da440d5, 0x1875336a), WTCP(0x7d99f720, 0x18a9d231), WTCP(0x7d8f9761, 0x18de6ca5), + WTCP(0x7d85219b, 0x191302bb), WTCP(0x7d7a95ce, 0x1947946c), WTCP(0x7d6ff3fd, 0x197c21ac), + WTCP(0x7d653c2a, 0x19b0aa75), WTCP(0x7d5a6e56, 0x19e52ebb), WTCP(0x7d4f8a84, 0x1a19ae76), + WTCP(0x7d4490b5, 0x1a4e299c), WTCP(0x7d3980eb, 0x1a82a025), WTCP(0x7d2e5b29, 0x1ab71208), + WTCP(0x7d231f6f, 0x1aeb7f3a), WTCP(0x7d17cdc1, 0x1b1fe7b3), WTCP(0x7d0c6620, 0x1b544b6a), + WTCP(0x7d00e88e, 0x1b88aa55), WTCP(0x7cf5550d, 0x1bbd046c), WTCP(0x7ce9aba0, 0x1bf159a4), + WTCP(0x7cddec47, 0x1c25a9f5), WTCP(0x7cd21706, 0x1c59f557), WTCP(0x7cc62bde, 0x1c8e3bbe), + WTCP(0x7cba2ad2, 0x1cc27d23), WTCP(0x7cae13e3, 0x1cf6b97c), WTCP(0x7ca1e714, 0x1d2af0c0), + WTCP(0x7c95a466, 0x1d5f22e6), WTCP(0x7c894bdd, 0x1d934fe5), WTCP(0x7c7cdd7a, 0x1dc777b3), + WTCP(0x7c70593f, 0x1dfb9a48), WTCP(0x7c63bf2e, 0x1e2fb79a), WTCP(0x7c570f4a, 0x1e63cfa0), + WTCP(0x7c4a4995, 0x1e97e251), WTCP(0x7c3d6e12, 0x1ecbefa3), WTCP(0x7c307cc1, 0x1efff78f), + WTCP(0x7c2375a7, 0x1f33fa0a), WTCP(0x7c1658c4, 0x1f67f70b), WTCP(0x7c09261c, 0x1f9bee8a), + WTCP(0x7bfbddb0, 0x1fcfe07d), WTCP(0x7bee7f84, 0x2003ccdb), WTCP(0x7be10b98, 0x2037b39b), + WTCP(0x7bd381f0, 0x206b94b4), WTCP(0x7bc5e28f, 0x209f701c), WTCP(0x7bb82d75, 0x20d345cb), + WTCP(0x7baa62a7, 0x210715b8), WTCP(0x7b9c8225, 0x213adfda), WTCP(0x7b8e8bf4, 0x216ea426), + WTCP(0x7b808014, 0x21a26295), WTCP(0x7b725e89, 0x21d61b1d), WTCP(0x7b642755, 0x2209cdb6), + WTCP(0x7b55da7b, 0x223d7a55), WTCP(0x7b4777fd, 0x227120f3), WTCP(0x7b38ffdd, 0x22a4c185), + WTCP(0x7b2a721e, 0x22d85c03), WTCP(0x7b1bcec3, 0x230bf064), WTCP(0x7b0d15cf, 0x233f7e9f), + WTCP(0x7afe4743, 0x237306ab), WTCP(0x7aef6323, 0x23a6887e), WTCP(0x7ae06970, 0x23da0410), + WTCP(0x7ad15a2f, 0x240d7958), WTCP(0x7ac23560, 0x2440e84c), WTCP(0x7ab2fb08, 0x247450e4), + WTCP(0x7aa3ab28, 0x24a7b316), WTCP(0x7a9445c4, 0x24db0eda), WTCP(0x7a84cadd, 0x250e6427), + WTCP(0x7a753a78, 0x2541b2f3), WTCP(0x7a659495, 0x2574fb35), WTCP(0x7a55d939, 0x25a83ce5), + WTCP(0x7a460867, 0x25db77fa), WTCP(0x7a36221f, 0x260eac6a), WTCP(0x7a262667, 0x2641da2c), + WTCP(0x7a16153f, 0x26750139), WTCP(0x7a05eeac, 0x26a82185), WTCP(0x79f5b2b0, 0x26db3b0a), + WTCP(0x79e5614e, 0x270e4dbd), WTCP(0x79d4fa88, 0x27415996), WTCP(0x79c47e62, 0x27745e8b), + WTCP(0x79b3ecdf, 0x27a75c95), WTCP(0x79a34601, 0x27da53a9), WTCP(0x799289cb, 0x280d43bf), + WTCP(0x7981b841, 0x28402cce), WTCP(0x7970d164, 0x28730ecd), WTCP(0x795fd539, 0x28a5e9b3), + WTCP(0x794ec3c2, 0x28d8bd78), WTCP(0x793d9d02, 0x290b8a11), WTCP(0x792c60fd, 0x293e4f77), + WTCP(0x791b0fb4, 0x29710da1), WTCP(0x7909a92c, 0x29a3c485), WTCP(0x78f82d67, 0x29d6741a), + WTCP(0x78e69c68, 0x2a091c59), WTCP(0x78d4f633, 0x2a3bbd37), WTCP(0x78c33aca, 0x2a6e56ac), + WTCP(0x78b16a31, 0x2aa0e8af), WTCP(0x789f846a, 0x2ad37338), WTCP(0x788d897a, 0x2b05f63d), + WTCP(0x787b7963, 0x2b3871b5), WTCP(0x78695427, 0x2b6ae598), WTCP(0x785719cb, 0x2b9d51dd), + WTCP(0x7844ca52, 0x2bcfb67b), WTCP(0x783265bf, 0x2c021368), WTCP(0x781fec14, 0x2c34689e), + WTCP(0x780d5d56, 0x2c66b611), WTCP(0x77fab988, 0x2c98fbba), WTCP(0x77e800ac, 0x2ccb3990), + WTCP(0x77d532c6, 0x2cfd6f8a), WTCP(0x77c24fda, 0x2d2f9d9f), WTCP(0x77af57eb, 0x2d61c3c6), + WTCP(0x779c4afb, 0x2d93e1f7), WTCP(0x7789290f, 0x2dc5f829), WTCP(0x7775f229, 0x2df80653), + WTCP(0x7762a64e, 0x2e2a0c6b), WTCP(0x774f4580, 0x2e5c0a6b), WTCP(0x773bcfc3, 0x2e8e0047), + WTCP(0x7728451b, 0x2ebfedf9), WTCP(0x7714a58a, 0x2ef1d377), WTCP(0x7700f114, 0x2f23b0b8), + WTCP(0x76ed27bd, 0x2f5585b4), WTCP(0x76d94988, 0x2f875262), WTCP(0x76c55679, 0x2fb916b9), + WTCP(0x76b14e92, 0x2fead2b0), WTCP(0x769d31d9, 0x301c863f), WTCP(0x7689004f, 0x304e315d), + WTCP(0x7674b9f9, 0x307fd401), WTCP(0x76605eda, 0x30b16e22), WTCP(0x764beef7, 0x30e2ffb9), + WTCP(0x76376a51, 0x311488bb), WTCP(0x7622d0ee, 0x31460921), WTCP(0x760e22d0, 0x317780e2), + WTCP(0x75f95ffb, 0x31a8eff5), WTCP(0x75e48874, 0x31da5651), WTCP(0x75cf9c3c, 0x320bb3ee), + WTCP(0x75ba9b59, 0x323d08c3), WTCP(0x75a585ce, 0x326e54c7), WTCP(0x75905b9f, 0x329f97f2), + WTCP(0x757b1ccf, 0x32d0d23b), WTCP(0x7565c961, 0x3302039a), WTCP(0x7550615b, 0x33332c06), + WTCP(0x753ae4bf, 0x33644b76), WTCP(0x75255392, 0x339561e1), WTCP(0x750fadd6, 0x33c66f3f), + WTCP(0x74f9f390, 0x33f77388), WTCP(0x74e424c5, 0x34286eb3), WTCP(0x74ce4176, 0x345960b6), + WTCP(0x74b849a9, 0x348a498b), WTCP(0x74a23d61, 0x34bb2927), WTCP(0x748c1ca3, 0x34ebff83), + WTCP(0x7475e771, 0x351ccc95), WTCP(0x745f9dd0, 0x354d9056), WTCP(0x74493fc4, 0x357e4abd), + WTCP(0x7432cd51, 0x35aefbc1), WTCP(0x741c467a, 0x35dfa35a), WTCP(0x7405ab44, 0x3610417e), + WTCP(0x73eefbb2, 0x3640d627), WTCP(0x73d837c9, 0x3671614a), WTCP(0x73c15f8c, 0x36a1e2e0), + WTCP(0x73aa7300, 0x36d25ae0), WTCP(0x73937229, 0x3702c942), WTCP(0x737c5d0a, 0x37332dfc), + WTCP(0x736533a8, 0x37638907), WTCP(0x734df606, 0x3793da5a), WTCP(0x7336a42a, 0x37c421ed), + WTCP(0x731f3e16, 0x37f45fb7), WTCP(0x7307c3cf, 0x382493b0), WTCP(0x72f03559, 0x3854bdce), + WTCP(0x72d892b9, 0x3884de0b), WTCP(0x72c0dbf2, 0x38b4f45d), WTCP(0x72a91108, 0x38e500bb), + WTCP(0x72913200, 0x3915031e), WTCP(0x72793edf, 0x3944fb7d), WTCP(0x726137a7, 0x3974e9d0), + WTCP(0x72491c5d, 0x39a4ce0e), WTCP(0x7230ed06, 0x39d4a82e), WTCP(0x7218a9a6, 0x3a047829), + WTCP(0x72005241, 0x3a343df6), WTCP(0x71e7e6db, 0x3a63f98d), WTCP(0x71cf6779, 0x3a93aae5), + WTCP(0x71b6d41f, 0x3ac351f5), WTCP(0x719e2cd1, 0x3af2eeb7), WTCP(0x71857194, 0x3b228120), + WTCP(0x716ca26b, 0x3b520929), WTCP(0x7153bf5c, 0x3b8186ca), WTCP(0x713ac86a, 0x3bb0f9f9), + WTCP(0x7121bd9b, 0x3be062b0), WTCP(0x71089ef1, 0x3c0fc0e5), WTCP(0x70ef6c73, 0x3c3f1490), + WTCP(0x70d62624, 0x3c6e5da9), WTCP(0x70bccc08, 0x3c9d9c28), WTCP(0x70a35e25, 0x3cccd004), + WTCP(0x7089dc7e, 0x3cfbf935), WTCP(0x70704718, 0x3d2b17b3), WTCP(0x70569df7, 0x3d5a2b75), + WTCP(0x703ce121, 0x3d893473), WTCP(0x70231099, 0x3db832a5), WTCP(0x70092c64, 0x3de72603), + WTCP(0x6fef3487, 0x3e160e85), WTCP(0x6fd52906, 0x3e44ec22), WTCP(0x6fbb09e6, 0x3e73bed1), + WTCP(0x6fa0d72b, 0x3ea2868c), WTCP(0x6f8690da, 0x3ed14349), WTCP(0x6f6c36f7, 0x3efff500), + WTCP(0x6f51c988, 0x3f2e9baa), WTCP(0x6f374890, 0x3f5d373e), WTCP(0x6f1cb415, 0x3f8bc7b3), + WTCP(0x6f020c1b, 0x3fba4d02), WTCP(0x6ee750a7, 0x3fe8c723), WTCP(0x6ecc81bd, 0x4017360d), + WTCP(0x6eb19f63, 0x404599b8), WTCP(0x6e96a99c, 0x4073f21d), WTCP(0x6e7ba06e, 0x40a23f32), + WTCP(0x6e6083dd, 0x40d080f0), WTCP(0x6e4553ef, 0x40feb74f), WTCP(0x6e2a10a7, 0x412ce246), + WTCP(0x6e0eba0b, 0x415b01ce), WTCP(0x6df3501f, 0x418915de), WTCP(0x6dd7d2e9, 0x41b71e6e), + WTCP(0x6dbc426d, 0x41e51b77), WTCP(0x6da09eb0, 0x42130cf0), WTCP(0x6d84e7b6, 0x4240f2d1), + WTCP(0x6d691d86, 0x426ecd12), WTCP(0x6d4d4022, 0x429c9baa), WTCP(0x6d314f92, 0x42ca5e93), + WTCP(0x6d154bd8, 0x42f815c4), WTCP(0x6cf934fb, 0x4325c135), WTCP(0x6cdd0aff, 0x435360de), + WTCP(0x6cc0cde9, 0x4380f4b6), WTCP(0x6ca47dbe, 0x43ae7cb6), WTCP(0x6c881a83, 0x43dbf8d7), + WTCP(0x6c6ba43d, 0x4409690f), WTCP(0x6c4f1af2, 0x4436cd57), WTCP(0x6c327ea5, 0x446425a7), + WTCP(0x6c15cf5c, 0x449171f7), WTCP(0x6bf90d1c, 0x44beb240), WTCP(0x6bdc37eb, 0x44ebe678), + WTCP(0x6bbf4fcc, 0x45190e99), WTCP(0x6ba254c6, 0x45462a9a), WTCP(0x6b8546dd, 0x45733a73), + WTCP(0x6b682617, 0x45a03e1d), WTCP(0x6b4af278, 0x45cd358f), WTCP(0x6b2dac05, 0x45fa20c2), + WTCP(0x6b1052c5, 0x4626ffae), WTCP(0x6af2e6bb, 0x4653d24a), WTCP(0x6ad567ee, 0x46809890), + WTCP(0x6ab7d662, 0x46ad5277), WTCP(0x6a9a321c, 0x46d9fff7), WTCP(0x6a7c7b22, 0x4706a109), + WTCP(0x6a5eb179, 0x473335a5), WTCP(0x6a40d526, 0x475fbdc2), WTCP(0x6a22e62f, 0x478c3959), + WTCP(0x6a04e498, 0x47b8a863), WTCP(0x69e6d067, 0x47e50ad7), WTCP(0x69c8a9a1, 0x481160ae), + WTCP(0x69aa704b, 0x483da9e0), WTCP(0x698c246b, 0x4869e664), WTCP(0x696dc606, 0x48961634), + WTCP(0x694f5522, 0x48c23948), WTCP(0x6930d1c3, 0x48ee4f98), WTCP(0x69123bf0, 0x491a591b), + WTCP(0x68f393ad, 0x494655cb), WTCP(0x68d4d8ff, 0x497245a0), WTCP(0x68b60bed, 0x499e2892), + WTCP(0x68972c7c, 0x49c9fe99), WTCP(0x68783ab1, 0x49f5c7ad), WTCP(0x68593691, 0x4a2183c7), + WTCP(0x683a2022, 0x4a4d32e0), WTCP(0x681af769, 0x4a78d4ef), WTCP(0x67fbbc6c, 0x4aa469ed), + WTCP(0x67dc6f31, 0x4acff1d2), WTCP(0x67bd0fbc, 0x4afb6c97), WTCP(0x679d9e13, 0x4b26da34), + WTCP(0x677e1a3d, 0x4b523aa1), WTCP(0x675e843e, 0x4b7d8dd7), WTCP(0x673edc1b, 0x4ba8d3cf), + WTCP(0x671f21db, 0x4bd40c7f), WTCP(0x66ff5584, 0x4bff37e2), WTCP(0x66df7719, 0x4c2a55ef), + WTCP(0x66bf86a2, 0x4c55669f), WTCP(0x669f8424, 0x4c8069ea), WTCP(0x667f6fa4, 0x4cab5fc9), + WTCP(0x665f4928, 0x4cd64834), WTCP(0x663f10b6, 0x4d012324), WTCP(0x661ec653, 0x4d2bf090), + WTCP(0x65fe6a05, 0x4d56b073), WTCP(0x65ddfbd2, 0x4d8162c3), WTCP(0x65bd7bc0, 0x4dac077b), + WTCP(0x659ce9d3, 0x4dd69e91), WTCP(0x657c4612, 0x4e0127ff), WTCP(0x655b9083, 0x4e2ba3be), + WTCP(0x653ac92a, 0x4e5611c5), WTCP(0x6519f00f, 0x4e80720d), WTCP(0x64f90537, 0x4eaac48f), + WTCP(0x64d808a7, 0x4ed50944), WTCP(0x64b6fa65, 0x4eff4024), WTCP(0x6495da78, 0x4f296927), + WTCP(0x6474a8e5, 0x4f538447), WTCP(0x645365b1, 0x4f7d917c), WTCP(0x643210e3, 0x4fa790be), + WTCP(0x6410aa80, 0x4fd18206), WTCP(0x63ef328f, 0x4ffb654c), WTCP(0x63cda915, 0x50253a8b), + WTCP(0x63ac0e18, 0x504f01b9), WTCP(0x638a619e, 0x5078bad0), WTCP(0x6368a3ac, 0x50a265c8), + WTCP(0x6346d44a, 0x50cc029b), WTCP(0x6324f37c, 0x50f59140), WTCP(0x63030149, 0x511f11b1), + WTCP(0x62e0fdb7, 0x514883e6), WTCP(0x62bee8cb, 0x5171e7d8), WTCP(0x629cc28c, 0x519b3d80), + WTCP(0x627a8aff, 0x51c484d6), WTCP(0x6258422b, 0x51edbdd3), WTCP(0x6235e815, 0x5216e870), + WTCP(0x62137cc4, 0x524004a6), WTCP(0x61f1003e, 0x5269126e), WTCP(0x61ce7289, 0x529211c0), + WTCP(0x61abd3aa, 0x52bb0295), WTCP(0x618923a8, 0x52e3e4e5), WTCP(0x61666289, 0x530cb8ab), + WTCP(0x61439053, 0x53357dde), WTCP(0x6120ad0c, 0x535e3478), WTCP(0x60fdb8ba, 0x5386dc71), + WTCP(0x60dab364, 0x53af75c2), WTCP(0x60b79d0f, 0x53d80064), WTCP(0x609475c2, 0x54007c50), + WTCP(0x60713d83, 0x5428e97f), WTCP(0x604df458, 0x545147ea), WTCP(0x602a9a47, 0x54799789), + WTCP(0x60072f56, 0x54a1d856), WTCP(0x5fe3b38d, 0x54ca0a4a), WTCP(0x5fc026f0, 0x54f22d5d), + WTCP(0x5f9c8986, 0x551a4188), WTCP(0x5f78db55, 0x554246c5), WTCP(0x5f551c64, 0x556a3d0c), + WTCP(0x5f314cb9, 0x55922457), WTCP(0x5f0d6c5b, 0x55b9fc9d), WTCP(0x5ee97b4e, 0x55e1c5da), + WTCP(0x5ec5799b, 0x56098004), WTCP(0x5ea16746, 0x56312b16), WTCP(0x5e7d4457, 0x5658c709), + WTCP(0x5e5910d4, 0x568053d5), WTCP(0x5e34ccc3, 0x56a7d173), WTCP(0x5e10782a, 0x56cf3fdd), + WTCP(0x5dec1310, 0x56f69f0c), WTCP(0x5dc79d7b, 0x571deef9), WTCP(0x5da31772, 0x57452f9d), + WTCP(0x5d7e80fb, 0x576c60f0), WTCP(0x5d59da1d, 0x579382ed), WTCP(0x5d3522dd, 0x57ba958c), + WTCP(0x5d105b43, 0x57e198c6), WTCP(0x5ceb8355, 0x58088c96), WTCP(0x5cc69b18, 0x582f70f2), + WTCP(0x5ca1a295, 0x585645d6), WTCP(0x5c7c99d0, 0x587d0b3a), WTCP(0x5c5780d2, 0x58a3c117), + WTCP(0x5c3257a0, 0x58ca6767), WTCP(0x5c0d1e40, 0x58f0fe22), WTCP(0x5be7d4ba, 0x59178542), + WTCP(0x5bc27b13, 0x593dfcc1), WTCP(0x5b9d1153, 0x59646497), WTCP(0x5b779780, 0x598abcbe), + WTCP(0x5b520da0, 0x59b1052e), WTCP(0x5b2c73ba, 0x59d73de2), WTCP(0x5b06c9d6, 0x59fd66d3), + WTCP(0x5ae10ff8, 0x5a237ff9), WTCP(0x5abb4628, 0x5a49894f), WTCP(0x5a956c6d, 0x5a6f82cd), +}; +# endif + +// fs 48 32 24 16 8 +// ms +-------------------- +// 10.0 | 480 320 240 160 80 +// 7.5 | 360 240 180 120 60 +// 5.0 | 240 160 120 80 40 +// 2.5 | 120 80 60 40 20 + +void BASOP_getTables( +#ifdef ENABLE_HR_MODE + const PWord32 **twiddle, const PWord32 **sin, +#else + const PWord16 **twiddle, const PWord16 **sin, +#endif + Word16 *sin_step, Word16 length) +{ + SWITCH (length) + { + case 20: + *sin = SineTable320; + move16(); + *sin_step = 32; + move16(); + *twiddle = SineWindow20; + move16(); + BREAK; + case 40: + *sin = SineTable320; + move16(); + *sin_step = 16; + move16(); + *twiddle = SineWindow40; + move16(); + BREAK; + case 60: + *sin = SineTable480; + move16(); + *sin_step = 16; + move16(); + *twiddle = SineWindow60; + move16(); + BREAK; + case 80: + *sin = SineTable320; + move16(); + *sin_step = 8; + move16(); + *twiddle = SineWindow80; + move16(); + BREAK; + case 120: + *sin = SineTable480; + move16(); + *sin_step = 8; + move16(); + *twiddle = SineWindow120; + move16(); + BREAK; + case 160: + *sin = SineTable320; + move16(); + *sin_step = 4; + move16(); + *twiddle = SineWindow160; + move16(); + BREAK; + case 180: + *sin = SineTable360; + move16(); + *sin_step = 4; + move16(); + *twiddle = SineWindow180; + move16(); + BREAK; + case 240: + *sin = SineTable480; + move16(); + *sin_step = 4; + move16(); + *twiddle = SineWindow240; + move16(); + BREAK; + case 320: + *sin = SineTable320; + move16(); + *sin_step = 2; + move16(); + *twiddle = SineWindow320; + move16(); + BREAK; + case 360: + *sin = SineTable360; + move16(); + *sin_step = 2; + move16(); + *twiddle = SineWindow360; + move16(); + BREAK; + case 480: + *sin = SineTable480; + move16(); + *sin_step = 2; + move16(); + *twiddle = SineWindow480; + move16(); + BREAK; +#ifdef ENABLE_HR_MODE +# ifdef CR8_G_ADD_75MS + case 720: + *sin = SineTable720; + move16(); + *sin_step = 2; + move16(); + *twiddle = SineWindow720; + move16(); + break; +# endif + case 960: + *sin = SineTable960; + move16(); + *sin_step = 2; + move16(); + *twiddle = SineWindow960; + move16(); + break; +#endif + default: ASSERT(0); + } +} + +const Word32 RealFFT32_twid[10] = { + 0x7fffffff, 0x00000000, 0x7d8a5f40, 0x18f8b83c, 0x7641af3d, + 0x30fbc54d, 0x6a6d98a4, 0x471cece7, 0x5a82799a, 0x5a82799a, +}; + +const Word32 RealFFT40_twid[12] = { + 0x7fffffff, 0x00000000, 0x7e6c9251, 0x14060b68, 0x79bc384d, 0x278dde6e, + 0x720c8075, 0x3a1c5c57, 0x678dde6e, 0x4b3c8c12, 0x5a82799a, 0x5a82799a, +}; + +const Word32 RealFFT64_twid[18] = { + 0x7fffffff, 0x00000000, 0x7f62368f, 0x0c8bd35e, 0x7d8a5f40, 0x18f8b83c, 0x7a7d055b, 0x25280c5e, 0x7641af3d, + 0x30fbc54d, 0x70e2cbc6, 0x3c56ba70, 0x6a6d98a4, 0x471cece7, 0x62f201ac, 0x5133cc94, 0x5a82799a, 0x5a82799a, +}; + +const Word32 RealFFT80_twid[22] = { + 0x7fffffff, 0x00000000, 0x7f9afcb9, 0x0a0af299, 0x7e6c9251, 0x14060b68, 0x7c769e18, 0x1de189a6, + 0x79bc384d, 0x278dde6e, 0x7641af3d, 0x30fbc54d, 0x720c8075, 0x3a1c5c57, 0x6d23501b, 0x42e13ba4, + 0x678dde6e, 0x4b3c8c12, 0x6154fb91, 0x53211d18, 0x5a82799a, 0x5a82799a, +}; + +const Word32 RealFFT96_twid[26] = { + 0x7fffffff, 0x00000000, 0x7fb9d759, 0x085f2137, 0x7ee7aa4c, 0x10b5150f, 0x7d8a5f40, 0x18f8b83c, 0x7ba3751d, + 0x2120fb83, 0x793501a9, 0x2924edac, 0x7641af3d, 0x30fbc54d, 0x72ccb9db, 0x389cea72, 0x6ed9eba1, 0x40000000, + 0x6a6d98a4, 0x471cece7, 0x658c9a2d, 0x4debe4fe, 0x603c496c, 0x54657194, 0x5a82799a, 0x5a82799a, +}; + +const Word32 RealFFT128_twid[34] = { + 0x7fffffff, 0x00000000, 0x7fd8878e, 0x0647d97c, 0x7f62368f, 0x0c8bd35e, 0x7e9d55fc, 0x12c8106f, 0x7d8a5f40, + 0x18f8b83c, 0x7c29fbee, 0x1f19f97b, 0x7a7d055b, 0x25280c5e, 0x78848414, 0x2b1f34eb, 0x7641af3d, 0x30fbc54d, + 0x73b5ebd1, 0x36ba2014, 0x70e2cbc6, 0x3c56ba70, 0x6dca0d14, 0x41ce1e65, 0x6a6d98a4, 0x471cece7, 0x66cf8120, + 0x4c3fdff4, 0x62f201ac, 0x5133cc94, 0x5ed77c8a, 0x55f5a4d2, 0x5a82799a, 0x5a82799a, +}; + +const Word32 RealFFT192_twid[50] = { + 0x7fffffff, 0x00000000, 0x7fee74a2, 0x0430238f, 0x7fb9d759, 0x085f2137, 0x7f62368f, 0x0c8bd35e, 0x7ee7aa4c, + 0x10b5150f, 0x7e4a5426, 0x14d9c245, 0x7d8a5f40, 0x18f8b83c, 0x7ca80038, 0x1d10d5c2, 0x7ba3751d, 0x2120fb83, + 0x7a7d055b, 0x25280c5e, 0x793501a9, 0x2924edac, 0x77cbc3f2, 0x2d168792, 0x7641af3d, 0x30fbc54d, 0x74972f92, + 0x34d3957e, 0x72ccb9db, 0x389cea72, 0x70e2cbc6, 0x3c56ba70, 0x6ed9eba1, 0x40000000, 0x6cb2a837, 0x4397ba32, + 0x6a6d98a4, 0x471cece7, 0x680b5c33, 0x4a8ea111, 0x658c9a2d, 0x4debe4fe, 0x62f201ac, 0x5133cc94, 0x603c496c, + 0x54657194, 0x5d6c2f99, 0x577ff3da, 0x5a82799a, 0x5a82799a, +}; + +const Word32 RealFFT256_twid[66] = { + 0x7fffffff, 0x00000000, 0x7ff62182, 0x03242abf, 0x7fd8878e, 0x0647d97c, 0x7fa736b4, 0x096a9049, 0x7f62368f, + 0x0c8bd35e, 0x7f0991c4, 0x0fab272b, 0x7e9d55fc, 0x12c8106f, 0x7e1d93ea, 0x15e21445, 0x7d8a5f40, 0x18f8b83c, + 0x7ce3ceb2, 0x1c0b826a, 0x7c29fbee, 0x1f19f97b, 0x7b5d039e, 0x2223a4c5, 0x7a7d055b, 0x25280c5e, 0x798a23b1, + 0x2826b928, 0x78848414, 0x2b1f34eb, 0x776c4edb, 0x2e110a62, 0x7641af3d, 0x30fbc54d, 0x7504d345, 0x33def287, + 0x73b5ebd1, 0x36ba2014, 0x72552c85, 0x398cdd32, 0x70e2cbc6, 0x3c56ba70, 0x6f5f02b2, 0x3f1749b8, 0x6dca0d14, + 0x41ce1e65, 0x6c242960, 0x447acd50, 0x6a6d98a4, 0x471cece7, 0x68a69e81, 0x49b41533, 0x66cf8120, 0x4c3fdff4, + 0x64e88926, 0x4ebfe8a5, 0x62f201ac, 0x5133cc94, 0x60ec3830, 0x539b2af0, 0x5ed77c8a, 0x55f5a4d2, 0x5cb420e0, + 0x5842dd54, 0x5a82799a, 0x5a82799a, +}; + +const Word32 RealFFT384_twid[98] = { + 0x7fffffff, 0x00000000, 0x7ffb9d15, 0x02182427, 0x7fee74a2, 0x0430238f, 0x7fd8878e, 0x0647d97c, 0x7fb9d759, + 0x085f2137, 0x7f92661d, 0x0a75d60e, 0x7f62368f, 0x0c8bd35e, 0x7f294bfd, 0x0ea0f48c, 0x7ee7aa4c, 0x10b5150f, + 0x7e9d55fc, 0x12c8106f, 0x7e4a5426, 0x14d9c245, 0x7deeaa7a, 0x16ea0646, 0x7d8a5f40, 0x18f8b83c, 0x7d1d7958, + 0x1b05b40f, 0x7ca80038, 0x1d10d5c2, 0x7c29fbee, 0x1f19f97b, 0x7ba3751d, 0x2120fb83, 0x7b1474fd, 0x2325b847, + 0x7a7d055b, 0x25280c5e, 0x79dd3098, 0x2727d486, 0x793501a9, 0x2924edac, 0x78848414, 0x2b1f34eb, 0x77cbc3f2, + 0x2d168792, 0x770acdec, 0x2f0ac320, 0x7641af3d, 0x30fbc54d, 0x757075ac, 0x32e96c09, 0x74972f92, 0x34d3957e, + 0x73b5ebd1, 0x36ba2014, 0x72ccb9db, 0x389cea72, 0x71dba9ab, 0x3a7bd382, 0x70e2cbc6, 0x3c56ba70, 0x6fe2313c, + 0x3e2d7eb1, 0x6ed9eba1, 0x40000000, 0x6dca0d14, 0x41ce1e65, 0x6cb2a837, 0x4397ba32, 0x6b93d02e, 0x455cb40c, + 0x6a6d98a4, 0x471cece7, 0x694015c3, 0x48d84609, 0x680b5c33, 0x4a8ea111, 0x66cf8120, 0x4c3fdff4, 0x658c9a2d, + 0x4debe4fe, 0x6442bd7e, 0x4f9292dc, 0x62f201ac, 0x5133cc94, 0x619a7dce, 0x52cf758f, 0x603c496c, 0x54657194, + 0x5ed77c8a, 0x55f5a4d2, 0x5d6c2f99, 0x577ff3da, 0x5bfa7b82, 0x590443a7, 0x5a82799a, 0x5a82799a, +}; + +const Word32 RealFFT512_twid[130] = { + 0x7fffffff, 0x00000000, 0x7ffd885a, 0x01921d20, 0x7ff62182, 0x03242abf, 0x7fe9cbc0, 0x04b6195d, 0x7fd8878e, + 0x0647d97c, 0x7fc25596, 0x07d95b9e, 0x7fa736b4, 0x096a9049, 0x7f872bf3, 0x0afb6805, 0x7f62368f, 0x0c8bd35e, + 0x7f3857f6, 0x0e1bc2e4, 0x7f0991c4, 0x0fab272b, 0x7ed5e5c6, 0x1139f0cf, 0x7e9d55fc, 0x12c8106f, 0x7e5fe493, + 0x145576b1, 0x7e1d93ea, 0x15e21445, 0x7dd6668f, 0x176dd9de, 0x7d8a5f40, 0x18f8b83c, 0x7d3980ec, 0x1a82a026, + 0x7ce3ceb2, 0x1c0b826a, 0x7c894bde, 0x1d934fe5, 0x7c29fbee, 0x1f19f97b, 0x7bc5e290, 0x209f701c, 0x7b5d039e, + 0x2223a4c5, 0x7aef6323, 0x23a6887f, 0x7a7d055b, 0x25280c5e, 0x7a05eead, 0x26a82186, 0x798a23b1, 0x2826b928, + 0x7909a92d, 0x29a3c485, 0x78848414, 0x2b1f34eb, 0x77fab989, 0x2c98fbba, 0x776c4edb, 0x2e110a62, 0x76d94989, + 0x2f875262, 0x7641af3d, 0x30fbc54d, 0x75a585cf, 0x326e54c7, 0x7504d345, 0x33def287, 0x745f9dd1, 0x354d9057, + 0x73b5ebd1, 0x36ba2014, 0x7307c3d0, 0x382493b0, 0x72552c85, 0x398cdd32, 0x719e2cd2, 0x3af2eeb7, 0x70e2cbc6, + 0x3c56ba70, 0x7023109a, 0x3db832a6, 0x6f5f02b2, 0x3f1749b8, 0x6e96a99d, 0x4073f21d, 0x6dca0d14, 0x41ce1e65, + 0x6cf934fc, 0x4325c135, 0x6c242960, 0x447acd50, 0x6b4af279, 0x45cd358f, 0x6a6d98a4, 0x471cece7, 0x698c246c, + 0x4869e665, 0x68a69e81, 0x49b41533, 0x67bd0fbd, 0x4afb6c98, 0x66cf8120, 0x4c3fdff4, 0x65ddfbd3, 0x4d8162c4, + 0x64e88926, 0x4ebfe8a5, 0x63ef3290, 0x4ffb654d, 0x62f201ac, 0x5133cc94, 0x61f1003f, 0x5269126e, 0x60ec3830, + 0x539b2af0, 0x5fe3b38d, 0x54ca0a4b, 0x5ed77c8a, 0x55f5a4d2, 0x5dc79d7c, 0x571deefa, 0x5cb420e0, 0x5842dd54, + 0x5b9d1154, 0x59646498, 0x5a82799a, 0x5a82799a, +}; + +const Word32 RealFFT768_twid[194] = { + 0x7fffffff, 0x00000000, 0x7ffee744, 0x010c1460, 0x7ffb9d15, 0x02182427, 0x7ff62182, 0x03242abf, 0x7fee74a2, + 0x0430238f, 0x7fe49698, 0x053c0a01, 0x7fd8878e, 0x0647d97c, 0x7fca47b9, 0x07538d6b, 0x7fb9d759, 0x085f2137, + 0x7fa736b4, 0x096a9049, 0x7f92661d, 0x0a75d60e, 0x7f7b65ef, 0x0b80edf1, 0x7f62368f, 0x0c8bd35e, 0x7f46d86c, + 0x0d9681c2, 0x7f294bfd, 0x0ea0f48c, 0x7f0991c4, 0x0fab272b, 0x7ee7aa4c, 0x10b5150f, 0x7ec3962a, 0x11beb9aa, + 0x7e9d55fc, 0x12c8106f, 0x7e74ea6a, 0x13d114d0, 0x7e4a5426, 0x14d9c245, 0x7e1d93ea, 0x15e21445, 0x7deeaa7a, + 0x16ea0646, 0x7dbd98a4, 0x17f193c5, 0x7d8a5f40, 0x18f8b83c, 0x7d54ff2e, 0x19ff6f2a, 0x7d1d7958, 0x1b05b40f, + 0x7ce3ceb2, 0x1c0b826a, 0x7ca80038, 0x1d10d5c2, 0x7c6a0ef2, 0x1e15a99a, 0x7c29fbee, 0x1f19f97b, 0x7be7c847, + 0x201dc0ef, 0x7ba3751d, 0x2120fb83, 0x7b5d039e, 0x2223a4c5, 0x7b1474fd, 0x2325b847, 0x7ac9ca7a, 0x2427319d, + 0x7a7d055b, 0x25280c5e, 0x7a2e26f2, 0x26284422, 0x79dd3098, 0x2727d486, 0x798a23b1, 0x2826b928, 0x793501a9, + 0x2924edac, 0x78ddcbf5, 0x2a226db5, 0x78848414, 0x2b1f34eb, 0x78292b8d, 0x2c1b3efb, 0x77cbc3f2, 0x2d168792, + 0x776c4edb, 0x2e110a62, 0x770acdec, 0x2f0ac320, 0x76a742d1, 0x3003ad85, 0x7641af3d, 0x30fbc54d, 0x75da14ef, + 0x31f30638, 0x757075ac, 0x32e96c09, 0x7504d345, 0x33def287, 0x74972f92, 0x34d3957e, 0x74278c72, 0x35c750bc, + 0x73b5ebd1, 0x36ba2014, 0x73424fa0, 0x37abff5d, 0x72ccb9db, 0x389cea72, 0x72552c85, 0x398cdd32, 0x71dba9ab, + 0x3a7bd382, 0x71603361, 0x3b69c947, 0x70e2cbc6, 0x3c56ba70, 0x706374ff, 0x3d42a2ec, 0x6fe2313c, 0x3e2d7eb1, + 0x6f5f02b2, 0x3f1749b8, 0x6ed9eba1, 0x40000000, 0x6e52ee52, 0x40e79d8c, 0x6dca0d14, 0x41ce1e65, 0x6d3f4a40, + 0x42b37e96, 0x6cb2a837, 0x4397ba32, 0x6c242960, 0x447acd50, 0x6b93d02e, 0x455cb40c, 0x6b019f1a, 0x463d6a87, + 0x6a6d98a4, 0x471cece7, 0x69d7bf57, 0x47fb3757, 0x694015c3, 0x48d84609, 0x68a69e81, 0x49b41533, 0x680b5c33, + 0x4a8ea111, 0x676e5183, 0x4b67e5e4, 0x66cf8120, 0x4c3fdff4, 0x662eedc3, 0x4d168b8b, 0x658c9a2d, 0x4debe4fe, + 0x64e88926, 0x4ebfe8a5, 0x6442bd7e, 0x4f9292dc, 0x639b3a0b, 0x5063e008, 0x62f201ac, 0x5133cc94, 0x62471749, + 0x520254ef, 0x619a7dce, 0x52cf758f, 0x60ec3830, 0x539b2af0, 0x603c496c, 0x54657194, 0x5f8ab487, 0x552e4605, + 0x5ed77c8a, 0x55f5a4d2, 0x5e22a487, 0x56bb8a90, 0x5d6c2f99, 0x577ff3da, 0x5cb420e0, 0x5842dd54, 0x5bfa7b82, + 0x590443a7, 0x5b3f42ae, 0x59c42381, 0x5a82799a, 0x5a82799a, +}; + +const Word32 RotVector_32_32[2 * 20] = { + 0x7d8a5f00, 0xe70747c0, 0x7641b000, 0xcf043ac0, 0x6a6d9900, 0xb8e31300, 0x5a827980, 0xa57d8680, + 0x471ced80, 0x95926780, 0x30fbc600, 0x89be5100, 0x18f8b800, 0x8275a100, 0x7641b000, 0xcf043ac0, + 0x5a827980, 0xa57d8680, 0x30fbc600, 0x89be5100, 0xcf043b00, 0x89be5100, 0xa57d8680, 0xa57d8680, + 0x89be5100, 0xcf043ac0, 0x6a6d9900, 0xb8e31300, 0x30fbc600, 0x89be5100, 0xe7074800, 0x8275a100, + 0xa57d8680, 0xa57d8680, 0x8275a100, 0xe70747c0, 0x89be5000, 0x30fbc540, 0xb8e31280, 0x6a6d9880, +}; + +const Word32 RotVector_40_32[2 * 28] = { + 0x7e6c9251, 0x14060b68, 0x79bc384d, 0x278dde6e, 0x720c8075, 0x3a1c5c57, 0x678dde6e, 0x4b3c8c12, + 0x79bc384d, 0x278dde6e, 0x678dde6e, 0x4b3c8c12, 0x4b3c8c12, 0x678dde6e, 0x278dde6e, 0x79bc384d, + 0x720c8075, 0x3a1c5c57, 0x4b3c8c12, 0x678dde6e, 0x14060b68, 0x7e6c9251, 0xd8722192, 0x79bc384d, + 0x678dde6e, 0x4b3c8c12, 0x278dde6e, 0x79bc384d, 0xd8722192, 0x79bc384d, 0x98722192, 0x4b3c8c12, + 0x5a82799a, 0x5a82799a, 0x00000000, 0x7fffffff, 0xa57d8666, 0x5a82799a, 0x80000000, 0x00000000, + 0x4b3c8c12, 0x678dde6e, 0xd8722192, 0x79bc384d, 0x8643c7b3, 0x278dde6e, 0x98722192, 0xb4c373ee, + 0x3a1c5c57, 0x720c8075, 0xb4c373ee, 0x678dde6e, 0x81936daf, 0xebf9f498, 0xd8722192, 0x8643c7b3, +}; + +# ifdef ENABLE_HR_MODE +const Word32 RotVector_480[2 * (480 - 30)] = { +# else +const Word16 RotVector_480[2 * (480 - 30)] = { +# endif + SHC(0x7fffffff), SHC(0x00000000), SHC(0x7ff4c56f), SHC(0xfca63bd8), SHC(0x7fd317b4), SHC(0xf94d0e2e), + SHC(0x7f9afcb9), SHC(0xf5f50d67), SHC(0x7f4c7e54), SHC(0xf29ecfb2), SHC(0x7ee7aa4c), SHC(0xef4aeaf1), + SHC(0x7e6c9251), SHC(0xebf9f498), SHC(0x7ddb4bfc), SHC(0xe8ac819d), SHC(0x7d33f0ca), SHC(0xe5632654), + SHC(0x7c769e18), SHC(0xe21e765a), SHC(0x7ba3751d), SHC(0xdedf047d), SHC(0x7aba9ae6), SHC(0xdba5629b), + SHC(0x79bc384d), SHC(0xd8722192), SHC(0x78a879f4), SHC(0xd545d11c), SHC(0x777f903c), SHC(0xd220ffc0), + SHC(0x7641af3d), SHC(0xcf043ab3), SHC(0x74ef0ebc), SHC(0xcbf00dbe), SHC(0x7387ea23), SHC(0xc8e5032b), + SHC(0x720c8075), SHC(0xc5e3a3a9), SHC(0x707d1443), SHC(0xc2ec7635), SHC(0x6ed9eba1), SHC(0xc0000000), + SHC(0x6d23501b), SHC(0xbd1ec45c), SHC(0x6b598ea3), SHC(0xba4944a2), SHC(0x697cf78a), SHC(0xb780001c), + SHC(0x678dde6e), SHC(0xb4c373ee), SHC(0x658c9a2d), SHC(0xb2141b02), SHC(0x637984d4), SHC(0xaf726def), + SHC(0x6154fb91), SHC(0xacdee2e8), SHC(0x5f1f5ea1), SHC(0xaa59eda4), SHC(0x5cd91140), SHC(0xa7e3ff4d), + SHC(0x7fffffff), SHC(0x00000000), SHC(0x7fd317b4), SHC(0xf94d0e2e), SHC(0x7f4c7e54), SHC(0xf29ecfb2), + SHC(0x7e6c9251), SHC(0xebf9f498), SHC(0x7d33f0ca), SHC(0xe5632654), SHC(0x7ba3751d), SHC(0xdedf047d), + SHC(0x79bc384d), SHC(0xd8722192), SHC(0x777f903c), SHC(0xd220ffc0), SHC(0x74ef0ebc), SHC(0xcbf00dbe), + SHC(0x720c8075), SHC(0xc5e3a3a9), SHC(0x6ed9eba1), SHC(0xc0000000), SHC(0x6b598ea3), SHC(0xba4944a2), + SHC(0x678dde6e), SHC(0xb4c373ee), SHC(0x637984d4), SHC(0xaf726def), SHC(0x5f1f5ea1), SHC(0xaa59eda4), + SHC(0x5a82799a), SHC(0xa57d8666), SHC(0x55a6125c), SHC(0xa0e0a15f), SHC(0x508d9211), SHC(0x9c867b2c), + SHC(0x4b3c8c12), SHC(0x98722192), SHC(0x45b6bb5e), SHC(0x94a6715d), SHC(0x40000000), SHC(0x9126145f), + SHC(0x3a1c5c57), SHC(0x8df37f8b), SHC(0x340ff242), SHC(0x8b10f144), SHC(0x2ddf0040), SHC(0x88806fc4), + SHC(0x278dde6e), SHC(0x8643c7b3), SHC(0x2120fb83), SHC(0x845c8ae3), SHC(0x1a9cd9ac), SHC(0x82cc0f36), + SHC(0x14060b68), SHC(0x81936daf), SHC(0x0d61304e), SHC(0x80b381ac), SHC(0x06b2f1d2), SHC(0x802ce84c), + SHC(0x7fffffff), SHC(0x00000000), SHC(0x7f9afcb9), SHC(0xf5f50d67), SHC(0x7e6c9251), SHC(0xebf9f498), + SHC(0x7c769e18), SHC(0xe21e765a), SHC(0x79bc384d), SHC(0xd8722192), SHC(0x7641af3d), SHC(0xcf043ab3), + SHC(0x720c8075), SHC(0xc5e3a3a9), SHC(0x6d23501b), SHC(0xbd1ec45c), SHC(0x678dde6e), SHC(0xb4c373ee), + SHC(0x6154fb91), SHC(0xacdee2e8), SHC(0x5a82799a), SHC(0xa57d8666), SHC(0x53211d18), SHC(0x9eab046f), + SHC(0x4b3c8c12), SHC(0x98722192), SHC(0x42e13ba4), SHC(0x92dcafe5), SHC(0x3a1c5c57), SHC(0x8df37f8b), + SHC(0x30fbc54d), SHC(0x89be50c3), SHC(0x278dde6e), SHC(0x8643c7b3), SHC(0x1de189a6), SHC(0x838961e8), + SHC(0x14060b68), SHC(0x81936daf), SHC(0x0a0af299), SHC(0x80650347), SHC(0x00000000), SHC(0x80000000), + SHC(0xf5f50d67), SHC(0x80650347), SHC(0xebf9f498), SHC(0x81936daf), SHC(0xe21e765a), SHC(0x838961e8), + SHC(0xd8722192), SHC(0x8643c7b3), SHC(0xcf043ab3), SHC(0x89be50c3), SHC(0xc5e3a3a9), SHC(0x8df37f8b), + SHC(0xbd1ec45c), SHC(0x92dcafe5), SHC(0xb4c373ee), SHC(0x98722192), SHC(0xacdee2e8), SHC(0x9eab046f), + SHC(0x7fffffff), SHC(0x00000000), SHC(0x7f4c7e54), SHC(0xf29ecfb2), SHC(0x7d33f0ca), SHC(0xe5632654), + SHC(0x79bc384d), SHC(0xd8722192), SHC(0x74ef0ebc), SHC(0xcbf00dbe), SHC(0x6ed9eba1), SHC(0xc0000000), + SHC(0x678dde6e), SHC(0xb4c373ee), SHC(0x5f1f5ea1), SHC(0xaa59eda4), SHC(0x55a6125c), SHC(0xa0e0a15f), + SHC(0x4b3c8c12), SHC(0x98722192), SHC(0x40000000), SHC(0x9126145f), SHC(0x340ff242), SHC(0x8b10f144), + SHC(0x278dde6e), SHC(0x8643c7b3), SHC(0x1a9cd9ac), SHC(0x82cc0f36), SHC(0x0d61304e), SHC(0x80b381ac), + SHC(0x00000000), SHC(0x80000000), SHC(0xf29ecfb2), SHC(0x80b381ac), SHC(0xe5632654), SHC(0x82cc0f36), + SHC(0xd8722192), SHC(0x8643c7b3), SHC(0xcbf00dbe), SHC(0x8b10f144), SHC(0xc0000000), SHC(0x9126145f), + SHC(0xb4c373ee), SHC(0x98722192), SHC(0xaa59eda4), SHC(0xa0e0a15f), SHC(0xa0e0a15f), SHC(0xaa59eda4), + SHC(0x98722192), SHC(0xb4c373ee), SHC(0x9126145f), SHC(0xc0000000), SHC(0x8b10f144), SHC(0xcbf00dbe), + SHC(0x8643c7b3), SHC(0xd8722192), SHC(0x82cc0f36), SHC(0xe5632654), SHC(0x80b381ac), SHC(0xf29ecfb2), + SHC(0x7fffffff), SHC(0x00000000), SHC(0x7ee7aa4c), SHC(0xef4aeaf1), SHC(0x7ba3751d), SHC(0xdedf047d), + SHC(0x7641af3d), SHC(0xcf043ab3), SHC(0x6ed9eba1), SHC(0xc0000000), SHC(0x658c9a2d), SHC(0xb2141b02), + SHC(0x5a82799a), SHC(0xa57d8666), SHC(0x4debe4fe), SHC(0x9a7365d3), SHC(0x40000000), SHC(0x9126145f), + SHC(0x30fbc54d), SHC(0x89be50c3), SHC(0x2120fb83), SHC(0x845c8ae3), SHC(0x10b5150f), SHC(0x811855b4), + SHC(0x00000000), SHC(0x80000000), SHC(0xef4aeaf1), SHC(0x811855b4), SHC(0xdedf047d), SHC(0x845c8ae3), + SHC(0xcf043ab3), SHC(0x89be50c3), SHC(0xc0000000), SHC(0x9126145f), SHC(0xb2141b02), SHC(0x9a7365d3), + SHC(0xa57d8666), SHC(0xa57d8666), SHC(0x9a7365d3), SHC(0xb2141b02), SHC(0x9126145f), SHC(0xc0000000), + SHC(0x89be50c3), SHC(0xcf043ab3), SHC(0x845c8ae3), SHC(0xdedf047d), SHC(0x811855b4), SHC(0xef4aeaf1), + SHC(0x80000000), SHC(0x00000000), SHC(0x811855b4), SHC(0x10b5150f), SHC(0x845c8ae3), SHC(0x2120fb83), + SHC(0x89be50c3), SHC(0x30fbc54d), SHC(0x9126145f), SHC(0x40000000), SHC(0x9a7365d3), SHC(0x4debe4fe), + SHC(0x7fffffff), SHC(0x00000000), SHC(0x7e6c9251), SHC(0xebf9f498), SHC(0x79bc384d), SHC(0xd8722192), + SHC(0x720c8075), SHC(0xc5e3a3a9), SHC(0x678dde6e), SHC(0xb4c373ee), SHC(0x5a82799a), SHC(0xa57d8666), + SHC(0x4b3c8c12), SHC(0x98722192), SHC(0x3a1c5c57), SHC(0x8df37f8b), SHC(0x278dde6e), SHC(0x8643c7b3), + SHC(0x14060b68), SHC(0x81936daf), SHC(0x00000000), SHC(0x80000000), SHC(0xebf9f498), SHC(0x81936daf), + SHC(0xd8722192), SHC(0x8643c7b3), SHC(0xc5e3a3a9), SHC(0x8df37f8b), SHC(0xb4c373ee), SHC(0x98722192), + SHC(0xa57d8666), SHC(0xa57d8666), SHC(0x98722192), SHC(0xb4c373ee), SHC(0x8df37f8b), SHC(0xc5e3a3a9), + SHC(0x8643c7b3), SHC(0xd8722192), SHC(0x81936daf), SHC(0xebf9f498), SHC(0x80000000), SHC(0x00000000), + SHC(0x81936daf), SHC(0x14060b68), SHC(0x8643c7b3), SHC(0x278dde6e), SHC(0x8df37f8b), SHC(0x3a1c5c57), + SHC(0x98722192), SHC(0x4b3c8c12), SHC(0xa57d8666), SHC(0x5a82799a), SHC(0xb4c373ee), SHC(0x678dde6e), + SHC(0xc5e3a3a9), SHC(0x720c8075), SHC(0xd8722192), SHC(0x79bc384d), SHC(0xebf9f498), SHC(0x7e6c9251), + SHC(0x7fffffff), SHC(0x00000000), SHC(0x7ddb4bfc), SHC(0xe8ac819d), SHC(0x777f903c), SHC(0xd220ffc0), + SHC(0x6d23501b), SHC(0xbd1ec45c), SHC(0x5f1f5ea1), SHC(0xaa59eda4), SHC(0x4debe4fe), SHC(0x9a7365d3), + SHC(0x3a1c5c57), SHC(0x8df37f8b), SHC(0x245a9d65), SHC(0x8545651a), SHC(0x0d61304e), SHC(0x80b381ac), + SHC(0xf5f50d67), SHC(0x80650347), SHC(0xdedf047d), SHC(0x845c8ae3), SHC(0xc8e5032b), SHC(0x8c7815dd), + SHC(0xb4c373ee), SHC(0x98722192), SHC(0xa326eec0), SHC(0xa7e3ff4d), SHC(0x94a6715d), SHC(0xba4944a2), + SHC(0x89be50c3), SHC(0xcf043ab3), SHC(0x82cc0f36), SHC(0xe5632654), SHC(0x800b3a91), SHC(0xfca63bd8), + SHC(0x81936daf), SHC(0x14060b68), SHC(0x8757860c), SHC(0x2aba2ee4), SHC(0x9126145f), SHC(0x40000000), + SHC(0x9eab046f), SHC(0x53211d18), SHC(0xaf726def), SHC(0x637984d4), SHC(0xc2ec7635), SHC(0x707d1443), + SHC(0xd8722192), SHC(0x79bc384d), SHC(0xef4aeaf1), SHC(0x7ee7aa4c), SHC(0x06b2f1d2), SHC(0x7fd317b4), + SHC(0x1de189a6), SHC(0x7c769e18), SHC(0x340ff242), SHC(0x74ef0ebc), SHC(0x487fffe4), SHC(0x697cf78a), + SHC(0x7fffffff), SHC(0x00000000), SHC(0x7ffd3154), SHC(0xfe531484), SHC(0x7ff4c56f), SHC(0xfca63bd8), + SHC(0x7fe6bcb0), SHC(0xfaf988cc), SHC(0x7fd317b4), SHC(0xf94d0e2e), SHC(0x7fb9d759), SHC(0xf7a0dec9), + SHC(0x7f9afcb9), SHC(0xf5f50d67), SHC(0x7f76892f), SHC(0xf449acca), SHC(0x7f4c7e54), SHC(0xf29ecfb2), + SHC(0x7f1cde01), SHC(0xf0f488d9), SHC(0x7ee7aa4c), SHC(0xef4aeaf1), SHC(0x7eace58a), SHC(0xeda208a5), + SHC(0x7e6c9251), SHC(0xebf9f498), SHC(0x7e26b371), SHC(0xea52c166), SHC(0x7ddb4bfc), SHC(0xe8ac819d), + SHC(0x7d8a5f40), SHC(0xe70747c4), SHC(0x7d33f0ca), SHC(0xe5632654), SHC(0x7cd80464), SHC(0xe3c02fbb), + SHC(0x7c769e18), SHC(0xe21e765a), SHC(0x7c0fc22a), SHC(0xe07e0c84), SHC(0x7ba3751d), SHC(0xdedf047d), + SHC(0x7b31bbb2), SHC(0xdd417079), SHC(0x7aba9ae6), SHC(0xdba5629b), SHC(0x7a3e17f2), SHC(0xda0aecf9), + SHC(0x79bc384d), SHC(0xd8722192), SHC(0x793501a9), SHC(0xd6db1254), SHC(0x78a879f4), SHC(0xd545d11c), + SHC(0x7816a759), SHC(0xd3b26fb0), SHC(0x777f903c), SHC(0xd220ffc0), SHC(0x76e33b3f), SHC(0xd09192ea), + SHC(0x7fffffff), SHC(0x00000000), SHC(0x7fe6bcb0), SHC(0xfaf988cc), SHC(0x7f9afcb9), SHC(0xf5f50d67), + SHC(0x7f1cde01), SHC(0xf0f488d9), SHC(0x7e6c9251), SHC(0xebf9f498), SHC(0x7d8a5f40), SHC(0xe70747c4), + SHC(0x7c769e18), SHC(0xe21e765a), SHC(0x7b31bbb2), SHC(0xdd417079), SHC(0x79bc384d), SHC(0xd8722192), + SHC(0x7816a759), SHC(0xd3b26fb0), SHC(0x7641af3d), SHC(0xcf043ab3), SHC(0x743e0918), SHC(0xca695b94), + SHC(0x720c8075), SHC(0xc5e3a3a9), SHC(0x6fadf2fc), SHC(0xc174dbf2), SHC(0x6d23501b), SHC(0xbd1ec45c), + SHC(0x6a6d98a4), SHC(0xb8e31319), SHC(0x678dde6e), SHC(0xb4c373ee), SHC(0x648543e4), SHC(0xb0c1878b), + SHC(0x6154fb91), SHC(0xacdee2e8), SHC(0x5dfe47ad), SHC(0xa91d0ea3), SHC(0x5a82799a), SHC(0xa57d8666), + SHC(0x56e2f15d), SHC(0xa201b853), SHC(0x53211d18), SHC(0x9eab046f), SHC(0x4f3e7875), SHC(0x9b7abc1c), + SHC(0x4b3c8c12), SHC(0x98722192), SHC(0x471cece7), SHC(0x9592675c), SHC(0x42e13ba4), SHC(0x92dcafe5), + SHC(0x3e8b240e), SHC(0x90520d04), SHC(0x3a1c5c57), SHC(0x8df37f8b), SHC(0x3596a46c), SHC(0x8bc1f6e8), + SHC(0x7fffffff), SHC(0x00000000), SHC(0x7fb9d759), SHC(0xf7a0dec9), SHC(0x7ee7aa4c), SHC(0xef4aeaf1), + SHC(0x7d8a5f40), SHC(0xe70747c4), SHC(0x7ba3751d), SHC(0xdedf047d), SHC(0x793501a9), SHC(0xd6db1254), + SHC(0x7641af3d), SHC(0xcf043ab3), SHC(0x72ccb9db), SHC(0xc763158e), SHC(0x6ed9eba1), SHC(0xc0000000), + SHC(0x6a6d98a4), SHC(0xb8e31319), SHC(0x658c9a2d), SHC(0xb2141b02), SHC(0x603c496c), SHC(0xab9a8e6c), + SHC(0x5a82799a), SHC(0xa57d8666), SHC(0x54657194), SHC(0x9fc3b694), SHC(0x4debe4fe), SHC(0x9a7365d3), + SHC(0x471cece7), SHC(0x9592675c), SHC(0x40000000), SHC(0x9126145f), SHC(0x389cea72), SHC(0x8d334625), + SHC(0x30fbc54d), SHC(0x89be50c3), SHC(0x2924edac), SHC(0x86cafe57), SHC(0x2120fb83), SHC(0x845c8ae3), + SHC(0x18f8b83c), SHC(0x8275a0c0), SHC(0x10b5150f), SHC(0x811855b4), SHC(0x085f2137), SHC(0x804628a7), + SHC(0x00000000), SHC(0x80000000), SHC(0xf7a0dec9), SHC(0x804628a7), SHC(0xef4aeaf1), SHC(0x811855b4), + SHC(0xe70747c4), SHC(0x8275a0c0), SHC(0xdedf047d), SHC(0x845c8ae3), SHC(0xd6db1254), SHC(0x86cafe57), + SHC(0x7fffffff), SHC(0x00000000), SHC(0x7f76892f), SHC(0xf449acca), SHC(0x7ddb4bfc), SHC(0xe8ac819d), + SHC(0x7b31bbb2), SHC(0xdd417079), SHC(0x777f903c), SHC(0xd220ffc0), SHC(0x72ccb9db), SHC(0xc763158e), + SHC(0x6d23501b), SHC(0xbd1ec45c), SHC(0x668f7c25), SHC(0xb36a1978), SHC(0x5f1f5ea1), SHC(0xaa59eda4), + SHC(0x56e2f15d), SHC(0xa201b853), SHC(0x4debe4fe), SHC(0x9a7365d3), SHC(0x444d7aff), SHC(0x93bf30d4), + SHC(0x3a1c5c57), SHC(0x8df37f8b), SHC(0x2f6e6d16), SHC(0x891cc4c1), SHC(0x245a9d65), SHC(0x8545651a), + SHC(0x18f8b83c), SHC(0x8275a0c0), SHC(0x0d61304e), SHC(0x80b381ac), SHC(0x01aceb7c), SHC(0x8002ceac), + SHC(0xf5f50d67), SHC(0x80650347), SHC(0xea52c166), SHC(0x81d94c8f), SHC(0xdedf047d), SHC(0x845c8ae3), + SHC(0xd3b26fb0), SHC(0x87e958a7), SHC(0xc8e5032b), SHC(0x8c7815dd), SHC(0xbe8df2ba), SHC(0x91fef880), + SHC(0xb4c373ee), SHC(0x98722192), SHC(0xab9a8e6c), SHC(0x9fc3b694), SHC(0xa326eec0), SHC(0xa7e3ff4d), + SHC(0x9b7abc1c), SHC(0xb0c1878b), SHC(0x94a6715d), SHC(0xba4944a2), SHC(0x8eb8b9a0), SHC(0xc466be4f), + SHC(0x7fffffff), SHC(0x00000000), SHC(0x7f1cde01), SHC(0xf0f488d9), SHC(0x7c769e18), SHC(0xe21e765a), + SHC(0x7816a759), SHC(0xd3b26fb0), SHC(0x720c8075), SHC(0xc5e3a3a9), SHC(0x6a6d98a4), SHC(0xb8e31319), + SHC(0x6154fb91), SHC(0xacdee2e8), SHC(0x56e2f15d), SHC(0xa201b853), SHC(0x4b3c8c12), SHC(0x98722192), + SHC(0x3e8b240e), SHC(0x90520d04), SHC(0x30fbc54d), SHC(0x89be50c3), SHC(0x22be8f87), SHC(0x84ce444e), + SHC(0x14060b68), SHC(0x81936daf), SHC(0x05067734), SHC(0x80194350), SHC(0xf5f50d67), SHC(0x80650347), + SHC(0xe70747c4), SHC(0x8275a0c0), SHC(0xd8722192), SHC(0x8643c7b3), SHC(0xca695b94), SHC(0x8bc1f6e8), + SHC(0xbd1ec45c), SHC(0x92dcafe5), SHC(0xb0c1878b), SHC(0x9b7abc1c), SHC(0xa57d8666), SHC(0xa57d8666), + SHC(0x9b7abc1c), SHC(0xb0c1878b), SHC(0x92dcafe5), SHC(0xbd1ec45c), SHC(0x8bc1f6e8), SHC(0xca695b94), + SHC(0x8643c7b3), SHC(0xd8722192), SHC(0x8275a0c0), SHC(0xe70747c4), SHC(0x80650347), SHC(0xf5f50d67), + SHC(0x80194350), SHC(0x05067734), SHC(0x81936daf), SHC(0x14060b68), SHC(0x84ce444e), SHC(0x22be8f87), + SHC(0x7fffffff), SHC(0x00000000), SHC(0x7eace58a), SHC(0xeda208a5), SHC(0x7aba9ae6), SHC(0xdba5629b), + SHC(0x743e0918), SHC(0xca695b94), SHC(0x6b598ea3), SHC(0xba4944a2), SHC(0x603c496c), SHC(0xab9a8e6c), + SHC(0x53211d18), SHC(0x9eab046f), SHC(0x444d7aff), SHC(0x93bf30d4), SHC(0x340ff242), SHC(0x8b10f144), + SHC(0x22be8f87), SHC(0x84ce444e), SHC(0x10b5150f), SHC(0x811855b4), SHC(0xfe531484), SHC(0x8002ceac), + SHC(0xebf9f498), SHC(0x81936daf), SHC(0xda0aecf9), SHC(0x85c1e80e), SHC(0xc8e5032b), SHC(0x8c7815dd), + SHC(0xb8e31319), SHC(0x9592675c), SHC(0xaa59eda4), SHC(0xa0e0a15f), SHC(0x9d969742), SHC(0xae26dcdf), + SHC(0x92dcafe5), SHC(0xbd1ec45c), SHC(0x8a650cb4), SHC(0xcd790887), SHC(0x845c8ae3), SHC(0xdedf047d), + SHC(0x80e321ff), SHC(0xf0f488d9), SHC(0x800b3a91), SHC(0x0359c428), SHC(0x81d94c8f), SHC(0x15ad3e9a), + SHC(0x8643c7b3), SHC(0x278dde6e), SHC(0x8d334625), SHC(0x389cea72), SHC(0x96830876), SHC(0x487fffe4), + SHC(0xa201b853), SHC(0x56e2f15d), SHC(0xaf726def), SHC(0x637984d4), SHC(0xbe8df2ba), SHC(0x6e010780), + SHC(0x7fffffff), SHC(0x00000000), SHC(0x7e26b371), SHC(0xea52c166), SHC(0x78a879f4), SHC(0xd545d11c), + SHC(0x6fadf2fc), SHC(0xc174dbf2), SHC(0x637984d4), SHC(0xaf726def), SHC(0x54657194), SHC(0x9fc3b694), + SHC(0x42e13ba4), SHC(0x92dcafe5), SHC(0x2f6e6d16), SHC(0x891cc4c1), SHC(0x1a9cd9ac), SHC(0x82cc0f36), + SHC(0x05067734), SHC(0x80194350), SHC(0xef4aeaf1), SHC(0x811855b4), SHC(0xda0aecf9), SHC(0x85c1e80e), + SHC(0xc5e3a3a9), SHC(0x8df37f8b), SHC(0xb36a1978), SHC(0x997083db), SHC(0xa326eec0), SHC(0xa7e3ff4d), + SHC(0x9592675c), SHC(0xb8e31319), SHC(0x8b10f144), SHC(0xcbf00dbe), SHC(0x83f03dd6), SHC(0xe07e0c84), + SHC(0x80650347), SHC(0xf5f50d67), SHC(0x808976d1), SHC(0x0bb65336), SHC(0x845c8ae3), SHC(0x2120fb83), + SHC(0x8bc1f6e8), SHC(0x3596a46c), SHC(0x96830876), SHC(0x487fffe4), SHC(0xa45037c9), SHC(0x595132a2), + SHC(0xb4c373ee), SHC(0x678dde6e), SHC(0xc763158e), SHC(0x72ccb9db), SHC(0xdba5629b), SHC(0x7aba9ae6), + SHC(0xf0f488d9), SHC(0x7f1cde01), SHC(0x06b2f1d2), SHC(0x7fd317b4), SHC(0x1c3fd045), SHC(0x7cd80464), + SHC(0x7fffffff), SHC(0x00000000), SHC(0x7d8a5f40), SHC(0xe70747c4), SHC(0x7641af3d), SHC(0xcf043ab3), + SHC(0x6a6d98a4), SHC(0xb8e31319), SHC(0x5a82799a), SHC(0xa57d8666), SHC(0x471cece7), SHC(0x9592675c), + SHC(0x30fbc54d), SHC(0x89be50c3), SHC(0x18f8b83c), SHC(0x8275a0c0), SHC(0x00000000), SHC(0x80000000), + SHC(0xe70747c4), SHC(0x8275a0c0), SHC(0xcf043ab3), SHC(0x89be50c3), SHC(0xb8e31319), SHC(0x9592675c), + SHC(0xa57d8666), SHC(0xa57d8666), SHC(0x9592675c), SHC(0xb8e31319), SHC(0x89be50c3), SHC(0xcf043ab3), + SHC(0x8275a0c0), SHC(0xe70747c4), SHC(0x80000000), SHC(0x00000000), SHC(0x8275a0c0), SHC(0x18f8b83c), + SHC(0x89be50c3), SHC(0x30fbc54d), SHC(0x9592675c), SHC(0x471cece7), SHC(0xa57d8666), SHC(0x5a82799a), + SHC(0xb8e31319), SHC(0x6a6d98a4), SHC(0xcf043ab3), SHC(0x7641af3d), SHC(0xe70747c4), SHC(0x7d8a5f40), + SHC(0x00000000), SHC(0x7fffffff), SHC(0x18f8b83c), SHC(0x7d8a5f40), SHC(0x30fbc54d), SHC(0x7641af3d), + SHC(0x471cece7), SHC(0x6a6d98a4), SHC(0x5a82799a), SHC(0x5a82799a), SHC(0x6a6d98a4), SHC(0x471cece7)}; + +# ifdef ENABLE_HR_MODE +#ifdef CR8_G_ADD_75MS +const Word32 RotVector_720[2 * (720 - 30)] = { + SHC(0x7fffffff), SHC(0x00000000), SHC(0x7ffb0260), SHC(0xfdc41e9b), SHC(0x7fec09e3), SHC(0xfb8869ce), + SHC(0x7fd317b4), SHC(0xf94d0e2e), SHC(0x7fb02dc6), SHC(0xf7123849), SHC(0x7f834ed0), SHC(0xf4d814a4), + SHC(0x7f4c7e54), SHC(0xf29ecfb2), SHC(0x7f0bc097), SHC(0xf06695da), SHC(0x7ec11aa5), SHC(0xee2f9369), + SHC(0x7e6c9251), SHC(0xebf9f498), SHC(0x7e0e2e32), SHC(0xe9c5e582), SHC(0x7da5f5a5), SHC(0xe7939223), + SHC(0x7d33f0ca), SHC(0xe5632654), SHC(0x7cb82885), SHC(0xe334cdc9), SHC(0x7c32a67e), SHC(0xe108b40d), + SHC(0x7ba3751d), SHC(0xdedf047d), SHC(0x7b0a9f8d), SHC(0xdcb7ea46), SHC(0x7a6831ba), SHC(0xda939061), + SHC(0x79bc384d), SHC(0xd8722192), SHC(0x7906c0b0), SHC(0xd653c860), SHC(0x7847d909), SHC(0xd438af17), + SHC(0x777f903c), SHC(0xd220ffc0), SHC(0x76adf5e6), SHC(0xd00ce422), SHC(0x75d31a61), SHC(0xcdfc85bb), + SHC(0x74ef0ebc), SHC(0xcbf00dbe), SHC(0x7401e4c1), SHC(0xc9e7a512), SHC(0x730baeed), SHC(0xc7e3744b), + SHC(0x720c8075), SHC(0xc5e3a3a9), SHC(0x71046d3e), SHC(0xc3e85b18), SHC(0x6ff389df), SHC(0xc1f1c224), + SHC(0x7fffffff), SHC(0x00000000), SHC(0x7fec09e3), SHC(0xfb8869ce), SHC(0x7fb02dc6), SHC(0xf7123849), + SHC(0x7f4c7e54), SHC(0xf29ecfb2), SHC(0x7ec11aa5), SHC(0xee2f9369), SHC(0x7e0e2e32), SHC(0xe9c5e582), + SHC(0x7d33f0ca), SHC(0xe5632654), SHC(0x7c32a67e), SHC(0xe108b40d), SHC(0x7b0a9f8d), SHC(0xdcb7ea46), + SHC(0x79bc384d), SHC(0xd8722192), SHC(0x7847d909), SHC(0xd438af17), SHC(0x76adf5e6), SHC(0xd00ce422), + SHC(0x74ef0ebc), SHC(0xcbf00dbe), SHC(0x730baeed), SHC(0xc7e3744b), SHC(0x71046d3e), SHC(0xc3e85b18), + SHC(0x6ed9eba1), SHC(0xc0000000), SHC(0x6c8cd70b), SHC(0xbc2b9b05), SHC(0x6a1de737), SHC(0xb86c5df0), + SHC(0x678dde6e), SHC(0xb4c373ee), SHC(0x64dd8950), SHC(0xb1320139), SHC(0x620dbe8b), SHC(0xadb922b7), + SHC(0x5f1f5ea1), SHC(0xaa59eda4), SHC(0x5c13539b), SHC(0xa7156f3c), SHC(0x58ea90c4), SHC(0xa3ecac65), + SHC(0x55a6125c), SHC(0xa0e0a15f), SHC(0x5246dd49), SHC(0x9df24175), SHC(0x4ecdfec7), SHC(0x9b2276b0), + SHC(0x4b3c8c12), SHC(0x98722192), SHC(0x4793a210), SHC(0x95e218c9), SHC(0x43d464fb), SHC(0x937328f5), + SHC(0x7fffffff), SHC(0x00000000), SHC(0x7fd317b4), SHC(0xf94d0e2e), SHC(0x7f4c7e54), SHC(0xf29ecfb2), + SHC(0x7e6c9251), SHC(0xebf9f498), SHC(0x7d33f0ca), SHC(0xe5632654), SHC(0x7ba3751d), SHC(0xdedf047d), + SHC(0x79bc384d), SHC(0xd8722192), SHC(0x777f903c), SHC(0xd220ffc0), SHC(0x74ef0ebc), SHC(0xcbf00dbe), + SHC(0x720c8075), SHC(0xc5e3a3a9), SHC(0x6ed9eba1), SHC(0xc0000000), SHC(0x6b598ea3), SHC(0xba4944a2), + SHC(0x678dde6e), SHC(0xb4c373ee), SHC(0x637984d4), SHC(0xaf726def), SHC(0x5f1f5ea1), SHC(0xaa59eda4), + SHC(0x5a82799a), SHC(0xa57d8666), SHC(0x55a6125c), SHC(0xa0e0a15f), SHC(0x508d9211), SHC(0x9c867b2c), + SHC(0x4b3c8c12), SHC(0x98722192), SHC(0x45b6bb5e), SHC(0x94a6715d), SHC(0x40000000), SHC(0x9126145f), + SHC(0x3a1c5c57), SHC(0x8df37f8b), SHC(0x340ff242), SHC(0x8b10f144), SHC(0x2ddf0040), SHC(0x88806fc4), + SHC(0x278dde6e), SHC(0x8643c7b3), SHC(0x2120fb83), SHC(0x845c8ae3), SHC(0x1a9cd9ac), SHC(0x82cc0f36), + SHC(0x14060b68), SHC(0x81936daf), SHC(0x0d61304e), SHC(0x80b381ac), SHC(0x06b2f1d2), SHC(0x802ce84c), + SHC(0x7fffffff), SHC(0x00000000), SHC(0x7fb02dc6), SHC(0xf7123849), SHC(0x7ec11aa5), SHC(0xee2f9369), + SHC(0x7d33f0ca), SHC(0xe5632654), SHC(0x7b0a9f8d), SHC(0xdcb7ea46), SHC(0x7847d909), SHC(0xd438af17), + SHC(0x74ef0ebc), SHC(0xcbf00dbe), SHC(0x71046d3e), SHC(0xc3e85b18), SHC(0x6c8cd70b), SHC(0xbc2b9b05), + SHC(0x678dde6e), SHC(0xb4c373ee), SHC(0x620dbe8b), SHC(0xadb922b7), SHC(0x5c13539b), SHC(0xa7156f3c), + SHC(0x55a6125c), SHC(0xa0e0a15f), SHC(0x4ecdfec7), SHC(0x9b2276b0), SHC(0x4793a210), SHC(0x95e218c9), + SHC(0x40000000), SHC(0x9126145f), SHC(0x381c8bb5), SHC(0x8cf45113), SHC(0x2ff31bde), SHC(0x89520a1a), + SHC(0x278dde6e), SHC(0x8643c7b3), SHC(0x1ef74bf3), SHC(0x83cd5982), SHC(0x163a1a7e), SHC(0x81f1d1ce), + SHC(0x0d61304e), SHC(0x80b381ac), SHC(0x04779632), SHC(0x8013f61d), SHC(0xfb8869ce), SHC(0x8013f61d), + SHC(0xf29ecfb2), SHC(0x80b381ac), SHC(0xe9c5e582), SHC(0x81f1d1ce), SHC(0xe108b40d), SHC(0x83cd5982), + SHC(0xd8722192), SHC(0x8643c7b3), SHC(0xd00ce422), SHC(0x89520a1a), SHC(0xc7e3744b), SHC(0x8cf45113), + SHC(0x7fffffff), SHC(0x00000000), SHC(0x7f834ed0), SHC(0xf4d814a4), SHC(0x7e0e2e32), SHC(0xe9c5e582), + SHC(0x7ba3751d), SHC(0xdedf047d), SHC(0x7847d909), SHC(0xd438af17), SHC(0x7401e4c1), SHC(0xc9e7a512), + SHC(0x6ed9eba1), SHC(0xc0000000), SHC(0x68d9f964), SHC(0xb6950c1e), SHC(0x620dbe8b), SHC(0xadb922b7), + SHC(0x5a82799a), SHC(0xa57d8666), SHC(0x5246dd49), SHC(0x9df24175), SHC(0x496af3e2), SHC(0x9726069c), + SHC(0x40000000), SHC(0x9126145f), SHC(0x36185aee), SHC(0x8bfe1b3f), SHC(0x2bc750e9), SHC(0x87b826f7), + SHC(0x2120fb83), SHC(0x845c8ae3), SHC(0x163a1a7e), SHC(0x81f1d1ce), SHC(0x0b27eb5c), SHC(0x807cb130), + SHC(0x00000000), SHC(0x80000000), SHC(0xf4d814a4), SHC(0x807cb130), SHC(0xe9c5e582), SHC(0x81f1d1ce), + SHC(0xdedf047d), SHC(0x845c8ae3), SHC(0xd438af17), SHC(0x87b826f7), SHC(0xc9e7a512), SHC(0x8bfe1b3f), + SHC(0xc0000000), SHC(0x9126145f), SHC(0xb6950c1e), SHC(0x9726069c), SHC(0xadb922b7), SHC(0x9df24175), + SHC(0xa57d8666), SHC(0xa57d8666), SHC(0x9df24175), SHC(0xadb922b7), SHC(0x9726069c), SHC(0xb6950c1e), + SHC(0x7fffffff), SHC(0x00000000), SHC(0x7f4c7e54), SHC(0xf29ecfb2), SHC(0x7d33f0ca), SHC(0xe5632654), + SHC(0x79bc384d), SHC(0xd8722192), SHC(0x74ef0ebc), SHC(0xcbf00dbe), SHC(0x6ed9eba1), SHC(0xc0000000), + SHC(0x678dde6e), SHC(0xb4c373ee), SHC(0x5f1f5ea1), SHC(0xaa59eda4), SHC(0x55a6125c), SHC(0xa0e0a15f), + SHC(0x4b3c8c12), SHC(0x98722192), SHC(0x40000000), SHC(0x9126145f), SHC(0x340ff242), SHC(0x8b10f144), + SHC(0x278dde6e), SHC(0x8643c7b3), SHC(0x1a9cd9ac), SHC(0x82cc0f36), SHC(0x0d61304e), SHC(0x80b381ac), + SHC(0x00000000), SHC(0x80000000), SHC(0xf29ecfb2), SHC(0x80b381ac), SHC(0xe5632654), SHC(0x82cc0f36), + SHC(0xd8722192), SHC(0x8643c7b3), SHC(0xcbf00dbe), SHC(0x8b10f144), SHC(0xc0000000), SHC(0x9126145f), + SHC(0xb4c373ee), SHC(0x98722192), SHC(0xaa59eda4), SHC(0xa0e0a15f), SHC(0xa0e0a15f), SHC(0xaa59eda4), + SHC(0x98722192), SHC(0xb4c373ee), SHC(0x9126145f), SHC(0xc0000000), SHC(0x8b10f144), SHC(0xcbf00dbe), + SHC(0x8643c7b3), SHC(0xd8722192), SHC(0x82cc0f36), SHC(0xe5632654), SHC(0x80b381ac), SHC(0xf29ecfb2), + SHC(0x7fffffff), SHC(0x00000000), SHC(0x7f0bc097), SHC(0xf06695da), SHC(0x7c32a67e), SHC(0xe108b40d), + SHC(0x777f903c), SHC(0xd220ffc0), SHC(0x71046d3e), SHC(0xc3e85b18), SHC(0x68d9f964), SHC(0xb6950c1e), + SHC(0x5f1f5ea1), SHC(0xaa59eda4), SHC(0x53f9be05), SHC(0x9f65ad2d), SHC(0x4793a210), SHC(0x95e218c9), + SHC(0x3a1c5c57), SHC(0x8df37f8b), SHC(0x2bc750e9), SHC(0x87b826f7), SHC(0x1ccb3237), SHC(0x8347d77b), + SHC(0x0d61304e), SHC(0x80b381ac), SHC(0xfdc41e9b), SHC(0x8004fda0), SHC(0xee2f9369), SHC(0x813ee55b), + SHC(0xdedf047d), SHC(0x845c8ae3), SHC(0xd00ce422), SHC(0x89520a1a), SHC(0xc1f1c224), SHC(0x900c7621), + SHC(0xb4c373ee), SHC(0x98722192), SHC(0xa8b4471a), SHC(0xa263007d), SHC(0x9df24175), SHC(0xadb922b7), + SHC(0x94a6715d), SHC(0xba4944a2), SHC(0x8cf45113), SHC(0xc7e3744b), SHC(0x86f93f50), SHC(0xd653c860), + SHC(0x82cc0f36), SHC(0xe5632654), SHC(0x807cb130), SHC(0xf4d814a4), SHC(0x8013f61d), SHC(0x04779632), + SHC(0x81936daf), SHC(0x14060b68), SHC(0x84f56073), SHC(0x234815ba), SHC(0x8a2ce59f), SHC(0x32037a45), + SHC(0x7fffffff), SHC(0x00000000), SHC(0x7ec11aa5), SHC(0xee2f9369), SHC(0x7b0a9f8d), SHC(0xdcb7ea46), + SHC(0x74ef0ebc), SHC(0xcbf00dbe), SHC(0x6c8cd70b), SHC(0xbc2b9b05), SHC(0x620dbe8b), SHC(0xadb922b7), + SHC(0x55a6125c), SHC(0xa0e0a15f), SHC(0x4793a210), SHC(0x95e218c9), SHC(0x381c8bb5), SHC(0x8cf45113), + SHC(0x278dde6e), SHC(0x8643c7b3), SHC(0x163a1a7e), SHC(0x81f1d1ce), SHC(0x04779632), SHC(0x8013f61d), + SHC(0xf29ecfb2), SHC(0x80b381ac), SHC(0xe108b40d), SHC(0x83cd5982), SHC(0xd00ce422), SHC(0x89520a1a), + SHC(0xc0000000), SHC(0x9126145f), SHC(0xb1320139), SHC(0x9b2276b0), SHC(0xa3ecac65), SHC(0xa7156f3c), + SHC(0x98722192), SHC(0xb4c373ee), SHC(0x8efb92c2), SHC(0xc3e85b18), SHC(0x87b826f7), SHC(0xd438af17), + SHC(0x82cc0f36), SHC(0xe5632654), SHC(0x804fd23a), SHC(0xf7123849), SHC(0x804fd23a), SHC(0x08edc7b7), + SHC(0x82cc0f36), SHC(0x1a9cd9ac), SHC(0x87b826f7), SHC(0x2bc750e9), SHC(0x8efb92c2), SHC(0x3c17a4e8), + SHC(0x98722192), SHC(0x4b3c8c12), SHC(0xa3ecac65), SHC(0x58ea90c4), SHC(0xb1320139), SHC(0x64dd8950), + SHC(0x7fffffff), SHC(0x00000000), SHC(0x7e6c9251), SHC(0xebf9f498), SHC(0x79bc384d), SHC(0xd8722192), + SHC(0x720c8075), SHC(0xc5e3a3a9), SHC(0x678dde6e), SHC(0xb4c373ee), SHC(0x5a82799a), SHC(0xa57d8666), + SHC(0x4b3c8c12), SHC(0x98722192), SHC(0x3a1c5c57), SHC(0x8df37f8b), SHC(0x278dde6e), SHC(0x8643c7b3), + SHC(0x14060b68), SHC(0x81936daf), SHC(0x00000000), SHC(0x80000000), SHC(0xebf9f498), SHC(0x81936daf), + SHC(0xd8722192), SHC(0x8643c7b3), SHC(0xc5e3a3a9), SHC(0x8df37f8b), SHC(0xb4c373ee), SHC(0x98722192), + SHC(0xa57d8666), SHC(0xa57d8666), SHC(0x98722192), SHC(0xb4c373ee), SHC(0x8df37f8b), SHC(0xc5e3a3a9), + SHC(0x8643c7b3), SHC(0xd8722192), SHC(0x81936daf), SHC(0xebf9f498), SHC(0x80000000), SHC(0x00000000), + SHC(0x81936daf), SHC(0x14060b68), SHC(0x8643c7b3), SHC(0x278dde6e), SHC(0x8df37f8b), SHC(0x3a1c5c57), + SHC(0x98722192), SHC(0x4b3c8c12), SHC(0xa57d8666), SHC(0x5a82799a), SHC(0xb4c373ee), SHC(0x678dde6e), + SHC(0xc5e3a3a9), SHC(0x720c8075), SHC(0xd8722192), SHC(0x79bc384d), SHC(0xebf9f498), SHC(0x7e6c9251), + SHC(0x7fffffff), SHC(0x00000000), SHC(0x7e0e2e32), SHC(0xe9c5e582), SHC(0x7847d909), SHC(0xd438af17), + SHC(0x6ed9eba1), SHC(0xc0000000), SHC(0x620dbe8b), SHC(0xadb922b7), SHC(0x5246dd49), SHC(0x9df24175), + SHC(0x40000000), SHC(0x9126145f), SHC(0x2bc750e9), SHC(0x87b826f7), SHC(0x163a1a7e), SHC(0x81f1d1ce), + SHC(0x00000000), SHC(0x80000000), SHC(0xe9c5e582), SHC(0x81f1d1ce), SHC(0xd438af17), SHC(0x87b826f7), + SHC(0xc0000000), SHC(0x9126145f), SHC(0xadb922b7), SHC(0x9df24175), SHC(0x9df24175), SHC(0xadb922b7), + SHC(0x9126145f), SHC(0xc0000000), SHC(0x87b826f7), SHC(0xd438af17), SHC(0x81f1d1ce), SHC(0xe9c5e582), + SHC(0x80000000), SHC(0x00000000), SHC(0x81f1d1ce), SHC(0x163a1a7e), SHC(0x87b826f7), SHC(0x2bc750e9), + SHC(0x9126145f), SHC(0x40000000), SHC(0x9df24175), SHC(0x5246dd49), SHC(0xadb922b7), SHC(0x620dbe8b), + SHC(0xc0000000), SHC(0x6ed9eba1), SHC(0xd438af17), SHC(0x7847d909), SHC(0xe9c5e582), SHC(0x7e0e2e32), + SHC(0x00000000), SHC(0x7fffffff), SHC(0x163a1a7e), SHC(0x7e0e2e32), SHC(0x2bc750e9), SHC(0x7847d909), + SHC(0x7fffffff), SHC(0x00000000), SHC(0x7da5f5a5), SHC(0xe7939223), SHC(0x76adf5e6), SHC(0xd00ce422), + SHC(0x6b598ea3), SHC(0xba4944a2), SHC(0x5c13539b), SHC(0xa7156f3c), SHC(0x496af3e2), SHC(0x9726069c), + SHC(0x340ff242), SHC(0x8b10f144), SHC(0x1ccb3237), SHC(0x8347d77b), SHC(0x04779632), SHC(0x8013f61d), + SHC(0xebf9f498), SHC(0x81936daf), SHC(0xd438af17), SHC(0x87b826f7), SHC(0xbe133b7c), SHC(0x92485786), + SHC(0xaa59eda4), SHC(0xa0e0a15f), SHC(0x99c64fc5), SHC(0xb2f7b9af), SHC(0x8cf45113), SHC(0xc7e3744b), + SHC(0x845c8ae3), SHC(0xdedf047d), SHC(0x804fd23a), SHC(0xf7123849), SHC(0x80f43f69), SHC(0x0f996a26), + SHC(0x8643c7b3), SHC(0x278dde6e), SHC(0x900c7621), SHC(0x3e0e3ddc), SHC(0x9df24175), SHC(0x5246dd49), + SHC(0xaf726def), SHC(0x637984d4), SHC(0xc3e85b18), SHC(0x71046d3e), SHC(0xda939061), SHC(0x7a6831ba), + SHC(0xf29ecfb2), SHC(0x7f4c7e54), SHC(0x0b27eb5c), SHC(0x7f834ed0), SHC(0x234815ba), SHC(0x7b0a9f8d), + SHC(0x3a1c5c57), SHC(0x720c8075), SHC(0x4ecdfec7), SHC(0x64dd8950), SHC(0x609a52d3), SHC(0x53f9be05), + SHC(0x7fffffff), SHC(0x00000000), SHC(0x7f1cde01), SHC(0xf0f488d9), SHC(0x7c769e18), SHC(0xe21e765a), + SHC(0x7816a759), SHC(0xd3b26fb0), SHC(0x720c8075), SHC(0xc5e3a3a9), SHC(0x6a6d98a4), SHC(0xb8e31319), + SHC(0x6154fb91), SHC(0xacdee2e8), SHC(0x56e2f15d), SHC(0xa201b853), SHC(0x4b3c8c12), SHC(0x98722192), + SHC(0x3e8b240e), SHC(0x90520d04), SHC(0x30fbc54d), SHC(0x89be50c3), SHC(0x22be8f87), SHC(0x84ce444e), + SHC(0x14060b68), SHC(0x81936daf), SHC(0x05067734), SHC(0x80194350), SHC(0xf5f50d67), SHC(0x80650347), + SHC(0xe70747c4), SHC(0x8275a0c0), SHC(0xd8722192), SHC(0x8643c7b3), SHC(0xca695b94), SHC(0x8bc1f6e8), + SHC(0xbd1ec45c), SHC(0x92dcafe5), SHC(0xb0c1878b), SHC(0x9b7abc1c), SHC(0xa57d8666), SHC(0xa57d8666), + SHC(0x9b7abc1c), SHC(0xb0c1878b), SHC(0x92dcafe5), SHC(0xbd1ec45c), SHC(0x8bc1f6e8), SHC(0xca695b94), + SHC(0x8643c7b3), SHC(0xd8722192), SHC(0x8275a0c0), SHC(0xe70747c4), SHC(0x80650347), SHC(0xf5f50d67), + SHC(0x80194350), SHC(0x05067734), SHC(0x81936daf), SHC(0x14060b68), SHC(0x84ce444e), SHC(0x22be8f87), + SHC(0x7fffffff), SHC(0x00000000), SHC(0x7eace58a), SHC(0xeda208a5), SHC(0x7aba9ae6), SHC(0xdba5629b), + SHC(0x743e0918), SHC(0xca695b94), SHC(0x6b598ea3), SHC(0xba4944a2), SHC(0x603c496c), SHC(0xab9a8e6c), + SHC(0x53211d18), SHC(0x9eab046f), SHC(0x444d7aff), SHC(0x93bf30d4), SHC(0x340ff242), SHC(0x8b10f144), + SHC(0x22be8f87), SHC(0x84ce444e), SHC(0x10b5150f), SHC(0x811855b4), SHC(0xfe531484), SHC(0x8002ceac), + SHC(0xebf9f498), SHC(0x81936daf), SHC(0xda0aecf9), SHC(0x85c1e80e), SHC(0xc8e5032b), SHC(0x8c7815dd), + SHC(0xb8e31319), SHC(0x9592675c), SHC(0xaa59eda4), SHC(0xa0e0a15f), SHC(0x9d969742), SHC(0xae26dcdf), + SHC(0x92dcafe5), SHC(0xbd1ec45c), SHC(0x8a650cb4), SHC(0xcd790887), SHC(0x845c8ae3), SHC(0xdedf047d), + SHC(0x80e321ff), SHC(0xf0f488d9), SHC(0x800b3a91), SHC(0x0359c428), SHC(0x81d94c8f), SHC(0x15ad3e9a), + SHC(0x8643c7b3), SHC(0x278dde6e), SHC(0x8d334625), SHC(0x389cea72), SHC(0x96830876), SHC(0x487fffe4), + SHC(0xa201b853), SHC(0x56e2f15d), SHC(0xaf726def), SHC(0x637984d4), SHC(0xbe8df2ba), SHC(0x6e010780), + SHC(0x7fffffff), SHC(0x00000000), SHC(0x7e26b371), SHC(0xea52c166), SHC(0x78a879f4), SHC(0xd545d11c), + SHC(0x6fadf2fc), SHC(0xc174dbf2), SHC(0x637984d4), SHC(0xaf726def), SHC(0x54657194), SHC(0x9fc3b694), + SHC(0x42e13ba4), SHC(0x92dcafe5), SHC(0x2f6e6d16), SHC(0x891cc4c1), SHC(0x1a9cd9ac), SHC(0x82cc0f36), + SHC(0x05067734), SHC(0x80194350), SHC(0xef4aeaf1), SHC(0x811855b4), SHC(0xda0aecf9), SHC(0x85c1e80e), + SHC(0xc5e3a3a9), SHC(0x8df37f8b), SHC(0xb36a1978), SHC(0x997083db), SHC(0xa326eec0), SHC(0xa7e3ff4d), + SHC(0x9592675c), SHC(0xb8e31319), SHC(0x8b10f144), SHC(0xcbf00dbe), SHC(0x83f03dd6), SHC(0xe07e0c84), + SHC(0x80650347), SHC(0xf5f50d67), SHC(0x808976d1), SHC(0x0bb65336), SHC(0x845c8ae3), SHC(0x2120fb83), + SHC(0x8bc1f6e8), SHC(0x3596a46c), SHC(0x96830876), SHC(0x487fffe4), SHC(0xa45037c9), SHC(0x595132a2), + SHC(0xb4c373ee), SHC(0x678dde6e), SHC(0xc763158e), SHC(0x72ccb9db), SHC(0xdba5629b), SHC(0x7aba9ae6), + SHC(0xf0f488d9), SHC(0x7f1cde01), SHC(0x06b2f1d2), SHC(0x7fd317b4), SHC(0x1c3fd045), SHC(0x7cd80464), + SHC(0x7fffffff), SHC(0x00000000), SHC(0x7d8a5f40), SHC(0xe70747c4), SHC(0x7641af3d), SHC(0xcf043ab3), + SHC(0x6a6d98a4), SHC(0xb8e31319), SHC(0x5a82799a), SHC(0xa57d8666), SHC(0x471cece7), SHC(0x9592675c), + SHC(0x30fbc54d), SHC(0x89be50c3), SHC(0x18f8b83c), SHC(0x8275a0c0), SHC(0x00000000), SHC(0x80000000), + SHC(0xe70747c4), SHC(0x8275a0c0), SHC(0xcf043ab3), SHC(0x89be50c3), SHC(0xb8e31319), SHC(0x9592675c), + SHC(0xa57d8666), SHC(0xa57d8666), SHC(0x9592675c), SHC(0xb8e31319), SHC(0x89be50c3), SHC(0xcf043ab3), + SHC(0x8275a0c0), SHC(0xe70747c4), SHC(0x80000000), SHC(0x00000000), SHC(0x8275a0c0), SHC(0x18f8b83c), + SHC(0x89be50c3), SHC(0x30fbc54d), SHC(0x9592675c), SHC(0x471cece7), SHC(0xa57d8666), SHC(0x5a82799a), + SHC(0xb8e31319), SHC(0x6a6d98a4), SHC(0xcf043ab3), SHC(0x7641af3d), SHC(0xe70747c4), SHC(0x7d8a5f40), + SHC(0x00000000), SHC(0x7fffffff), SHC(0x18f8b83c), SHC(0x7d8a5f40), SHC(0x30fbc54d), SHC(0x7641af3d), + SHC(0x471cece7), SHC(0x6a6d98a4), SHC(0x5a82799a), SHC(0x5a82799a), SHC(0x6a6d98a4), SHC(0x471cece7), + SHC(0x00007fff), SHC(0x00007fff), SHC(0x00007fff), SHC(0x00007fff), SHC(0x00007fff), SHC(0x00007fff), + SHC(0x00007fff), SHC(0x00007fff), SHC(0x00007fff), SHC(0x00007fff), SHC(0x00007fff), SHC(0x00007fff), + SHC(0x00007fff), SHC(0x00007fff), SHC(0x00007fff), SHC(0x00007fff), SHC(0xfb887fec), SHC(0xf7127fb0), + SHC(0xf29f7f4c), SHC(0xee307ec1), SHC(0xe9c67e0e), SHC(0xe5637d34), SHC(0xe1097c33), SHC(0xdcb87b0b), + SHC(0xd87279bc), SHC(0xd4397848), SHC(0xd00d76ae), SHC(0xcbf074ef), SHC(0xc7e3730c), SHC(0xc3e87104), + SHC(0x00007fff), SHC(0xf7127fb0), SHC(0xee307ec1), SHC(0xe5637d34), SHC(0xdcb87b0b), SHC(0xd4397848), + SHC(0xcbf074ef), SHC(0xc3e87104), SHC(0xbc2c6c8d), SHC(0xb4c3678e), SHC(0xadb9620e), SHC(0xa7155c13), + SHC(0xa0e155a6), SHC(0x9b224ece), SHC(0x95e24794), SHC(0x00007fff), SHC(0xf29f7f4c), SHC(0xe5637d34), + SHC(0xd87279bc), SHC(0xcbf074ef), SHC(0xc0006eda), SHC(0xb4c3678e), SHC(0xaa5a5f1f), SHC(0xa0e155a6), + SHC(0x98724b3d), SHC(0x91264000), SHC(0x8b113410), SHC(0x8644278e), SHC(0x82cc1a9d), SHC(0x80b40d61), + SHC(0x00007fff), SHC(0xee307ec1), SHC(0xdcb87b0b), SHC(0xcbf074ef), SHC(0xbc2c6c8d), SHC(0xadb9620e), + SHC(0xa0e155a6), SHC(0x95e24794), SHC(0x8cf4381d), SHC(0x8644278e), SHC(0x81f2163a), SHC(0x80140478), + SHC(0x80b4f29f), SHC(0x83cde109), SHC(0x8952d00d), SHC(0x00007fff), SHC(0xe9c67e0e), SHC(0xd4397848), + SHC(0xc0006eda), SHC(0xadb9620e), SHC(0x9df25247), SHC(0x91264000), SHC(0x87b82bc7), SHC(0x81f2163a), + SHC(0x80000000), SHC(0x81f2e9c6), SHC(0x87b8d439), SHC(0x9126c000), SHC(0x9df2adb9), SHC(0xadb99df2), + SHC(0x00007fff), SHC(0xe5637d34), SHC(0xcbf074ef), SHC(0xb4c3678e), SHC(0xa0e155a6), SHC(0x91264000), + SHC(0x8644278e), SHC(0x80b40d61), SHC(0x80b4f29f), SHC(0x8644d872), SHC(0x9126c000), SHC(0xa0e1aa5a), + SHC(0xb4c39872), SHC(0xcbf08b11), SHC(0xe56382cc), SHC(0x00007fff), SHC(0xe1097c33), SHC(0xc3e87104), + SHC(0xaa5a5f1f), SHC(0x95e24794), SHC(0x87b82bc7), SHC(0x80b40d61), SHC(0x813fee30), SHC(0x8952d00d), + SHC(0x9872b4c3), SHC(0xadb99df2), SHC(0xc7e38cf4), SHC(0xe56382cc), SHC(0x04788014), SHC(0x234884f5), + SHC(0x00007fff), SHC(0xdcb87b0b), SHC(0xbc2c6c8d), SHC(0xa0e155a6), SHC(0x8cf4381d), SHC(0x81f2163a), + SHC(0x80b4f29f), SHC(0x8952d00d), SHC(0x9b22b132), SHC(0xb4c39872), SHC(0xd43987b8), SHC(0xf7128050), + SHC(0x1a9d82cc), SHC(0x3c188efc), SHC(0x58eba3ed), SHC(0x00007fff), SHC(0xd87279bc), SHC(0xb4c3678e), + SHC(0x98724b3d), SHC(0x8644278e), SHC(0x80000000), SHC(0x8644d872), SHC(0x9872b4c3), SHC(0xb4c39872), + SHC(0xd8728644), SHC(0x00008000), SHC(0x278e8644), SHC(0x4b3d9872), SHC(0x678eb4c3), SHC(0x79bcd872), + SHC(0x00007fff), SHC(0xd4397848), SHC(0xadb9620e), SHC(0x91264000), SHC(0x81f2163a), SHC(0x81f2e9c6), + SHC(0x9126c000), SHC(0xadb99df2), SHC(0xd43987b8), SHC(0x00008000), SHC(0x2bc787b8), SHC(0x52479df2), + SHC(0x6edac000), SHC(0x7e0ee9c6), SHC(0x7e0e163a), SHC(0x00007fff), SHC(0xd00d76ae), SHC(0xa7155c13), + SHC(0x8b113410), SHC(0x80140478), SHC(0x87b8d439), SHC(0xa0e1aa5a), SHC(0xc7e38cf4), SHC(0xf7128050), + SHC(0x278e8644), SHC(0x52479df2), SHC(0x7104c3e8), SHC(0x7f4cf29f), SHC(0x7b0b2348), SHC(0x64de4ece), + SHC(0x00007fff), SHC(0xe21e7c77), SHC(0xc5e4720d), SHC(0xacdf6155), SHC(0x98724b3d), SHC(0x89be30fc), + SHC(0x81931406), SHC(0x8065f5f5), SHC(0x8644d872), SHC(0x92ddbd1f), SHC(0xa57ea57e), SHC(0xbd1f92dd), + SHC(0xd8728644), SHC(0xf5f58065), SHC(0x14068193), SHC(0x00007fff), SHC(0xdba57abb), SHC(0xba496b5a), + SHC(0x9eab5321), SHC(0x8b113410), SHC(0x811810b5), SHC(0x8193ebfa), SHC(0x8c78c8e5), SHC(0xa0e1aa5a), + SHC(0xbd1f92dd), SHC(0xdedf845d), SHC(0x035a800b), SHC(0x278e8644), SHC(0x48809683), SHC(0x637aaf72), + SHC(0x00007fff), SHC(0xd54678a8), SHC(0xaf72637a), SHC(0x92dd42e1), SHC(0x82cc1a9d), SHC(0x8118ef4b), + SHC(0x8df3c5e4), SHC(0xa7e4a327), SHC(0xcbf08b11), SHC(0xf5f58065), SHC(0x2121845d), SHC(0x48809683), + SHC(0x678eb4c3), SHC(0x7abbdba5), SHC(0x7fd306b3), SHC(0x00007fff), SHC(0xcf047642), SHC(0xa57e5a82), + SHC(0x89be30fc), SHC(0x80000000), SHC(0x89becf04), SHC(0xa57ea57e), SHC(0xcf0489be), SHC(0x00008000), + SHC(0x30fc89be), SHC(0x5a82a57e), SHC(0x7642cf04), SHC(0x7fff0000), SHC(0x764230fc), SHC(0x5a825a82), + SHC(0xe2e1004b), SHC(0x00000000), SHC(0x00000000), SHC(0x6fb076e0), SHC(0x002fba9c), SHC(0x6fb079d0), + SHC(0x8d92be50), SHC(0x00000000), SHC(0x00000000), SHC(0x00000000), SHC(0x00000000), SHC(0x00000000), + SHC(0x00000000), SHC(0x00000000), SHC(0x00000000), SHC(0x00000000), SHC(0x00000000), SHC(0xffffffff), + SHC(0x00010000), SHC(0x00000000), SHC(0x00000000), SHC(0x00000000), SHC(0x00000000), SHC(0x00000000), + SHC(0x00000000), SHC(0x00000000), SHC(0x00000000), SHC(0xffffffff), SHC(0x00010000), SHC(0x00000000), + SHC(0x00000000), SHC(0x00000000), SHC(0x00000000), SHC(0xeabee318), SHC(0x00000000), SHC(0x4d55545a), + SHC(0000000000), SHC(0000000000), SHC(0x00000000), SHC(0x00000000), SHC(0xffffffff), SHC(0x904f882f), + SHC(0x4d55545a), SHC(0x00000000), SHC(0x00000000), SHC(0x006f5dd8), SHC(0x40000000), SHC(0x00666004), + SHC(0x006ec0b0), SHC(0x00660000), SHC(0x006f5dd8), SHC(0x42000000), SHC(0x00665fa0), SHC(0x006ec080), + SHC(0x6fb07880), SHC(0x00660000), SHC(0x00660000), SHC(0x00309ca0), SHC(0x00000000), SHC(0x00000000), + SHC(0x00000000), SHC(0x00000000), SHC(0x00000000), SHC(0x00000000), SHC(0x00000000), SHC(0x00000000), + SHC(0xffffffff), SHC(0x00010000), SHC(0x00000000), SHC(0x00000000), SHC(0x00000000), SHC(0x00000000), + SHC(0x00000000), SHC(0x00000000), SHC(0x00000000), SHC(0x00000000), SHC(0x0d888000), SHC(0x00000000), + SHC(0x00000000), SHC(0x00000000), SHC(0x00000000), SHC(0x00000000), SHC(0x00000000), SHC(0x00000000), + SHC(0x00000000), SHC(0x00000000), SHC(0x00000000), SHC(0x00000000), SHC(0x00000000), SHC(0x00000000), + SHC(0x00000170), SHC(0x00000000), SHC(0x00000000), SHC(0x6fb07880), SHC(0x6fb078a8), SHC(0x8d926000), + SHC(0x0d888000), SHC(0x8d888000), SHC(0x6fb079e0), SHC(0x00000000), SHC(0000000000), SHC(0x002f8000), + SHC(0x00000001), SHC(0x6fb07b40), SHC(0x00000000), SHC(0x6fb07b54), SHC(0x6fb07b70), SHC(0x6fb07b80), + SHC(0x6fb07b94), SHC(0x6fb07bcd), SHC(0x6fb07be6), SHC(0x6fb07c0e), SHC(0x6fb07c43), SHC(0x6fb07c4d), + SHC(0x6fb07c8f), SHC(0x6fb07d49), SHC(0x6fb07d71), SHC(0x6fb07d9e), SHC(0x6fb07daf), SHC(0x6fb07dbd), + SHC(0x6fb07dcc), SHC(0x6fb07ddf), SHC(0x6fb07de7), SHC(0x6fb07df8), SHC(0x6fb07e05), SHC(0x6fb07e45), + SHC(0x00000000), SHC(0x6fb07b18), SHC(0x6fb07e60), SHC(0x6fb07e70), SHC(0x6fb07e8f), SHC(0x6fb07ec4), + SHC(0x6fb07ee1), SHC(0x6fb07f17), SHC(0x6fb07f3e), SHC(0x6fb07f67), SHC(0x6fb07fa2), SHC(0x6fb07fdf), + SHC(0x6fb07fed), SHC(0x00000000), SHC(0x63657865), SHC(0x705f656c), SHC(0x65672f2e), SHC(0x6f526574), + SHC(0x00726f74), SHC(0x65672f2e), SHC(0x6f526574), SHC(0x00726f74), SHC(0x4f52505f), SHC(0x7070413d), + SHC(0x696d7265), SHC(0x4c454853), SHC(0x622f6e69), SHC(0x4d524554), SHC(0x322d6d72), SHC(0x00726f6c), + SHC(0x2f3d5249), SHC(0x646c6f66), SHC(0x6e2f3238), SHC(0x36737636), SHC(0x78663431), SHC(0x3031785f), + SHC(0x2f542f33), SHC(0x52505f4d), SHC(0x45565f4d), SHC(0x34343d4e), SHC(0x44575044), SHC(0x2f737265), + SHC(0x636f442f), SHC(0x6c2f7374), SHC(0x65747361), SHC(0x535f4d52), SHC(0x495f4e4f), SHC(0x34323939), + SHC(0x2d364133), SHC(0x4345382d), SHC(0x43344233), SHC(0x55003845), SHC(0x6d676c73), SHC(0x5455415f), + SHC(0x2f3d4b43), SHC(0x2f657461), SHC(0x2e6d6f63), SHC(0x616c2e65), SHC(0x64722e64), SHC(0x4b776b7a), + SHC(0x656e6574), SHC(0x3d485441), SHC(0x6d6f682f), SHC(0x69622f77), SHC(0x6c2f7273), SHC(0x6e69622f), + SHC(0x69622f72), SHC(0x2f3a6e69), SHC(0x6e696273), SHC(0x2f3a6e69), SHC(0x656d6f68), SHC(0x6e69622f), + SHC(0x31582f74), SHC(0x4c2f3a6e), SHC(0x412f7972), SHC(0x7273752f), SHC(0x70412f3a), SHC(0x6f697461), + SHC(0x61757369), SHC(0x6f696475), SHC(0x70612e65), SHC(0x6e65746e), SHC(0x756f7365), SHC(0x7070612f), + SHC(0x435f5f00), SHC(0x49656c64), SHC(0x65696669), SHC(0x70612e6d), SHC(0x6d726554), SHC(0x44575000), + SHC(0x2f737265), SHC(0x636f442f), SHC(0x6c2f7374), SHC(0x65747361), SHC(0x74706972), SHC(0x643d474e), + SHC(0x4654552e), SHC(0x465f4350), SHC(0x3078303d), SHC(0x40755c3d), SHC(0x00202477), SHC(0x56524553), + SHC(0x454d414e), SHC(0x4c564c48), SHC(0x3d454d4f), SHC(0x732f7372), SHC(0x4e474f4c), SHC(0x6d676c73), + SHC(0x59414c50), SHC(0x74617669), SHC(0x6f632f70), SHC(0x2e656c70), SHC(0x2e646863), SHC(0x53386438) + }; +#endif +const Word32 RotVector_960[2 * (480 - 60)] = { + SHC(0x7fffffff), SHC(0x00000000), SHC(0x7ffd3154), SHC(0xfe531484), SHC(0x7ff4c56f), SHC(0xfca63bd8), + SHC(0x7fe6bcb0), SHC(0xfaf988cc), SHC(0x7fd317b4), SHC(0xf94d0e2e), SHC(0x7fb9d759), SHC(0xf7a0dec9), + SHC(0x7f9afcb9), SHC(0xf5f50d67), SHC(0x7f76892f), SHC(0xf449acca), SHC(0x7f4c7e54), SHC(0xf29ecfb2), + SHC(0x7f1cde01), SHC(0xf0f488d9), SHC(0x7ee7aa4c), SHC(0xef4aeaf1), SHC(0x7eace58a), SHC(0xeda208a5), + SHC(0x7e6c9251), SHC(0xebf9f498), SHC(0x7e26b371), SHC(0xea52c166), SHC(0x7ddb4bfc), SHC(0xe8ac819d), + SHC(0x7d8a5f40), SHC(0xe70747c4), SHC(0x7d33f0ca), SHC(0xe5632654), SHC(0x7cd80464), SHC(0xe3c02fbb), + SHC(0x7c769e18), SHC(0xe21e765a), SHC(0x7c0fc22a), SHC(0xe07e0c84), SHC(0x7ba3751d), SHC(0xdedf047d), + SHC(0x7b31bbb2), SHC(0xdd417079), SHC(0x7aba9ae6), SHC(0xdba5629b), SHC(0x7a3e17f2), SHC(0xda0aecf9), + SHC(0x79bc384d), SHC(0xd8722192), SHC(0x793501a9), SHC(0xd6db1254), SHC(0x78a879f4), SHC(0xd545d11c), + SHC(0x7816a759), SHC(0xd3b26fb0), SHC(0x777f903c), SHC(0xd220ffc0), SHC(0x76e33b3f), SHC(0xd09192ea), + SHC(0x7641af3d), SHC(0xcf043ab3), SHC(0x759af34c), SHC(0xcd790887), SHC(0x74ef0ebc), SHC(0xcbf00dbe), + SHC(0x743e0918), SHC(0xca695b94), SHC(0x7387ea23), SHC(0xc8e5032b), SHC(0x72ccb9db), SHC(0xc763158e), + SHC(0x720c8075), SHC(0xc5e3a3a9), SHC(0x71474660), SHC(0xc466be4f), SHC(0x707d1443), SHC(0xc2ec7635), + SHC(0x6fadf2fc), SHC(0xc174dbf2), SHC(0x6ed9eba1), SHC(0xc0000000), SHC(0x6e010780), SHC(0xbe8df2ba), + SHC(0x6d23501b), SHC(0xbd1ec45c), SHC(0x6c40cf2c), SHC(0xbbb28501), SHC(0x6b598ea3), SHC(0xba4944a2), + SHC(0x6a6d98a4), SHC(0xb8e31319), SHC(0x697cf78a), SHC(0xb780001c), SHC(0x6887b5e2), SHC(0xb6201b3e), + SHC(0x678dde6e), SHC(0xb4c373ee), SHC(0x668f7c25), SHC(0xb36a1978), SHC(0x658c9a2d), SHC(0xb2141b02), + SHC(0x648543e4), SHC(0xb0c1878b), SHC(0x637984d4), SHC(0xaf726def), SHC(0x626968be), SHC(0xae26dcdf), + SHC(0x6154fb91), SHC(0xacdee2e8), SHC(0x603c496c), SHC(0xab9a8e6c), SHC(0x5f1f5ea1), SHC(0xaa59eda4), + SHC(0x5dfe47ad), SHC(0xa91d0ea3), SHC(0x5cd91140), SHC(0xa7e3ff4d), SHC(0x5bafc837), SHC(0xa6aecd5e), + SHC(0x7fffffff), SHC(0x00000000), SHC(0x7ff4c56f), SHC(0xfca63bd8), SHC(0x7fd317b4), SHC(0xf94d0e2e), + SHC(0x7f9afcb9), SHC(0xf5f50d67), SHC(0x7f4c7e54), SHC(0xf29ecfb2), SHC(0x7ee7aa4c), SHC(0xef4aeaf1), + SHC(0x7e6c9251), SHC(0xebf9f498), SHC(0x7ddb4bfc), SHC(0xe8ac819d), SHC(0x7d33f0ca), SHC(0xe5632654), + SHC(0x7c769e18), SHC(0xe21e765a), SHC(0x7ba3751d), SHC(0xdedf047d), SHC(0x7aba9ae6), SHC(0xdba5629b), + SHC(0x79bc384d), SHC(0xd8722192), SHC(0x78a879f4), SHC(0xd545d11c), SHC(0x777f903c), SHC(0xd220ffc0), + SHC(0x7641af3d), SHC(0xcf043ab3), SHC(0x74ef0ebc), SHC(0xcbf00dbe), SHC(0x7387ea23), SHC(0xc8e5032b), + SHC(0x720c8075), SHC(0xc5e3a3a9), SHC(0x707d1443), SHC(0xc2ec7635), SHC(0x6ed9eba1), SHC(0xc0000000), + SHC(0x6d23501b), SHC(0xbd1ec45c), SHC(0x6b598ea3), SHC(0xba4944a2), SHC(0x697cf78a), SHC(0xb780001c), + SHC(0x678dde6e), SHC(0xb4c373ee), SHC(0x658c9a2d), SHC(0xb2141b02), SHC(0x637984d4), SHC(0xaf726def), + SHC(0x6154fb91), SHC(0xacdee2e8), SHC(0x5f1f5ea1), SHC(0xaa59eda4), SHC(0x5cd91140), SHC(0xa7e3ff4d), + SHC(0x5a82799a), SHC(0xa57d8666), SHC(0x581c00b3), SHC(0xa326eec0), SHC(0x55a6125c), SHC(0xa0e0a15f), + SHC(0x53211d18), SHC(0x9eab046f), SHC(0x508d9211), SHC(0x9c867b2c), SHC(0x4debe4fe), SHC(0x9a7365d3), + SHC(0x4b3c8c12), SHC(0x98722192), SHC(0x487fffe4), SHC(0x96830876), SHC(0x45b6bb5e), SHC(0x94a6715d), + SHC(0x42e13ba4), SHC(0x92dcafe5), SHC(0x40000000), SHC(0x9126145f), SHC(0x3d1389cb), SHC(0x8f82ebbd), + SHC(0x3a1c5c57), SHC(0x8df37f8b), SHC(0x371afcd5), SHC(0x8c7815dd), SHC(0x340ff242), SHC(0x8b10f144), + SHC(0x30fbc54d), SHC(0x89be50c3), SHC(0x2ddf0040), SHC(0x88806fc4), SHC(0x2aba2ee4), SHC(0x8757860c), + SHC(0x278dde6e), SHC(0x8643c7b3), SHC(0x245a9d65), SHC(0x8545651a), SHC(0x2120fb83), SHC(0x845c8ae3), + SHC(0x1de189a6), SHC(0x838961e8), SHC(0x1a9cd9ac), SHC(0x82cc0f36), SHC(0x17537e63), SHC(0x8224b404), + SHC(0x14060b68), SHC(0x81936daf), SHC(0x10b5150f), SHC(0x811855b4), SHC(0x0d61304e), SHC(0x80b381ac), + SHC(0x0a0af299), SHC(0x80650347), SHC(0x06b2f1d2), SHC(0x802ce84c), SHC(0x0359c428), SHC(0x800b3a91), + SHC(0x7fffffff), SHC(0x00000000), SHC(0x7fe6bcb0), SHC(0xfaf988cc), SHC(0x7f9afcb9), SHC(0xf5f50d67), + SHC(0x7f1cde01), SHC(0xf0f488d9), SHC(0x7e6c9251), SHC(0xebf9f498), SHC(0x7d8a5f40), SHC(0xe70747c4), + SHC(0x7c769e18), SHC(0xe21e765a), SHC(0x7b31bbb2), SHC(0xdd417079), SHC(0x79bc384d), SHC(0xd8722192), + SHC(0x7816a759), SHC(0xd3b26fb0), SHC(0x7641af3d), SHC(0xcf043ab3), SHC(0x743e0918), SHC(0xca695b94), + SHC(0x720c8075), SHC(0xc5e3a3a9), SHC(0x6fadf2fc), SHC(0xc174dbf2), SHC(0x6d23501b), SHC(0xbd1ec45c), + SHC(0x6a6d98a4), SHC(0xb8e31319), SHC(0x678dde6e), SHC(0xb4c373ee), SHC(0x648543e4), SHC(0xb0c1878b), + SHC(0x6154fb91), SHC(0xacdee2e8), SHC(0x5dfe47ad), SHC(0xa91d0ea3), SHC(0x5a82799a), SHC(0xa57d8666), + SHC(0x56e2f15d), SHC(0xa201b853), SHC(0x53211d18), SHC(0x9eab046f), SHC(0x4f3e7875), SHC(0x9b7abc1c), + SHC(0x4b3c8c12), SHC(0x98722192), SHC(0x471cece7), SHC(0x9592675c), SHC(0x42e13ba4), SHC(0x92dcafe5), + SHC(0x3e8b240e), SHC(0x90520d04), SHC(0x3a1c5c57), SHC(0x8df37f8b), SHC(0x3596a46c), SHC(0x8bc1f6e8), + SHC(0x30fbc54d), SHC(0x89be50c3), SHC(0x2c4d9050), SHC(0x87e958a7), SHC(0x278dde6e), SHC(0x8643c7b3), + SHC(0x22be8f87), SHC(0x84ce444e), SHC(0x1de189a6), SHC(0x838961e8), SHC(0x18f8b83c), SHC(0x8275a0c0), + SHC(0x14060b68), SHC(0x81936daf), SHC(0x0f0b7727), SHC(0x80e321ff), SHC(0x0a0af299), SHC(0x80650347), + SHC(0x05067734), SHC(0x80194350), SHC(0x00000000), SHC(0x80000000), SHC(0xfaf988cc), SHC(0x80194350), + SHC(0xf5f50d67), SHC(0x80650347), SHC(0xf0f488d9), SHC(0x80e321ff), SHC(0xebf9f498), SHC(0x81936daf), + SHC(0xe70747c4), SHC(0x8275a0c0), SHC(0xe21e765a), SHC(0x838961e8), SHC(0xdd417079), SHC(0x84ce444e), + SHC(0xd8722192), SHC(0x8643c7b3), SHC(0xd3b26fb0), SHC(0x87e958a7), SHC(0xcf043ab3), SHC(0x89be50c3), + SHC(0xca695b94), SHC(0x8bc1f6e8), SHC(0xc5e3a3a9), SHC(0x8df37f8b), SHC(0xc174dbf2), SHC(0x90520d04), + SHC(0xbd1ec45c), SHC(0x92dcafe5), SHC(0xb8e31319), SHC(0x9592675c), SHC(0xb4c373ee), SHC(0x98722192), + SHC(0xb0c1878b), SHC(0x9b7abc1c), SHC(0xacdee2e8), SHC(0x9eab046f), SHC(0xa91d0ea3), SHC(0xa201b853), + SHC(0x7fffffff), SHC(0x00000000), SHC(0x7fd317b4), SHC(0xf94d0e2e), SHC(0x7f4c7e54), SHC(0xf29ecfb2), + SHC(0x7e6c9251), SHC(0xebf9f498), SHC(0x7d33f0ca), SHC(0xe5632654), SHC(0x7ba3751d), SHC(0xdedf047d), + SHC(0x79bc384d), SHC(0xd8722192), SHC(0x777f903c), SHC(0xd220ffc0), SHC(0x74ef0ebc), SHC(0xcbf00dbe), + SHC(0x720c8075), SHC(0xc5e3a3a9), SHC(0x6ed9eba1), SHC(0xc0000000), SHC(0x6b598ea3), SHC(0xba4944a2), + SHC(0x678dde6e), SHC(0xb4c373ee), SHC(0x637984d4), SHC(0xaf726def), SHC(0x5f1f5ea1), SHC(0xaa59eda4), + SHC(0x5a82799a), SHC(0xa57d8666), SHC(0x55a6125c), SHC(0xa0e0a15f), SHC(0x508d9211), SHC(0x9c867b2c), + SHC(0x4b3c8c12), SHC(0x98722192), SHC(0x45b6bb5e), SHC(0x94a6715d), SHC(0x40000000), SHC(0x9126145f), + SHC(0x3a1c5c57), SHC(0x8df37f8b), SHC(0x340ff242), SHC(0x8b10f144), SHC(0x2ddf0040), SHC(0x88806fc4), + SHC(0x278dde6e), SHC(0x8643c7b3), SHC(0x2120fb83), SHC(0x845c8ae3), SHC(0x1a9cd9ac), SHC(0x82cc0f36), + SHC(0x14060b68), SHC(0x81936daf), SHC(0x0d61304e), SHC(0x80b381ac), SHC(0x06b2f1d2), SHC(0x802ce84c), + SHC(0x00000000), SHC(0x80000000), SHC(0xf94d0e2e), SHC(0x802ce84c), SHC(0xf29ecfb2), SHC(0x80b381ac), + SHC(0xebf9f498), SHC(0x81936daf), SHC(0xe5632654), SHC(0x82cc0f36), SHC(0xdedf047d), SHC(0x845c8ae3), + SHC(0xd8722192), SHC(0x8643c7b3), SHC(0xd220ffc0), SHC(0x88806fc4), SHC(0xcbf00dbe), SHC(0x8b10f144), + SHC(0xc5e3a3a9), SHC(0x8df37f8b), SHC(0xc0000000), SHC(0x9126145f), SHC(0xba4944a2), SHC(0x94a6715d), + SHC(0xb4c373ee), SHC(0x98722192), SHC(0xaf726def), SHC(0x9c867b2c), SHC(0xaa59eda4), SHC(0xa0e0a15f), + SHC(0xa57d8666), SHC(0xa57d8666), SHC(0xa0e0a15f), SHC(0xaa59eda4), SHC(0x9c867b2c), SHC(0xaf726def), + SHC(0x98722192), SHC(0xb4c373ee), SHC(0x94a6715d), SHC(0xba4944a2), SHC(0x9126145f), SHC(0xc0000000), + SHC(0x8df37f8b), SHC(0xc5e3a3a9), SHC(0x8b10f144), SHC(0xcbf00dbe), SHC(0x88806fc4), SHC(0xd220ffc0), + SHC(0x8643c7b3), SHC(0xd8722192), SHC(0x845c8ae3), SHC(0xdedf047d), SHC(0x82cc0f36), SHC(0xe5632654), + SHC(0x81936daf), SHC(0xebf9f498), SHC(0x80b381ac), SHC(0xf29ecfb2), SHC(0x802ce84c), SHC(0xf94d0e2e), + SHC(0x7fffffff), SHC(0x00000000), SHC(0x7fb9d759), SHC(0xf7a0dec9), SHC(0x7ee7aa4c), SHC(0xef4aeaf1), + SHC(0x7d8a5f40), SHC(0xe70747c4), SHC(0x7ba3751d), SHC(0xdedf047d), SHC(0x793501a9), SHC(0xd6db1254), + SHC(0x7641af3d), SHC(0xcf043ab3), SHC(0x72ccb9db), SHC(0xc763158e), SHC(0x6ed9eba1), SHC(0xc0000000), + SHC(0x6a6d98a4), SHC(0xb8e31319), SHC(0x658c9a2d), SHC(0xb2141b02), SHC(0x603c496c), SHC(0xab9a8e6c), + SHC(0x5a82799a), SHC(0xa57d8666), SHC(0x54657194), SHC(0x9fc3b694), SHC(0x4debe4fe), SHC(0x9a7365d3), + SHC(0x471cece7), SHC(0x9592675c), SHC(0x40000000), SHC(0x9126145f), SHC(0x389cea72), SHC(0x8d334625), + SHC(0x30fbc54d), SHC(0x89be50c3), SHC(0x2924edac), SHC(0x86cafe57), SHC(0x2120fb83), SHC(0x845c8ae3), + SHC(0x18f8b83c), SHC(0x8275a0c0), SHC(0x10b5150f), SHC(0x811855b4), SHC(0x085f2137), SHC(0x804628a7), + SHC(0x00000000), SHC(0x80000000), SHC(0xf7a0dec9), SHC(0x804628a7), SHC(0xef4aeaf1), SHC(0x811855b4), + SHC(0xe70747c4), SHC(0x8275a0c0), SHC(0xdedf047d), SHC(0x845c8ae3), SHC(0xd6db1254), SHC(0x86cafe57), + SHC(0xcf043ab3), SHC(0x89be50c3), SHC(0xc763158e), SHC(0x8d334625), SHC(0xc0000000), SHC(0x9126145f), + SHC(0xb8e31319), SHC(0x9592675c), SHC(0xb2141b02), SHC(0x9a7365d3), SHC(0xab9a8e6c), SHC(0x9fc3b694), + SHC(0xa57d8666), SHC(0xa57d8666), SHC(0x9fc3b694), SHC(0xab9a8e6c), SHC(0x9a7365d3), SHC(0xb2141b02), + SHC(0x9592675c), SHC(0xb8e31319), SHC(0x9126145f), SHC(0xc0000000), SHC(0x8d334625), SHC(0xc763158e), + SHC(0x89be50c3), SHC(0xcf043ab3), SHC(0x86cafe57), SHC(0xd6db1254), SHC(0x845c8ae3), SHC(0xdedf047d), + SHC(0x8275a0c0), SHC(0xe70747c4), SHC(0x811855b4), SHC(0xef4aeaf1), SHC(0x804628a7), SHC(0xf7a0dec9), + SHC(0x80000000), SHC(0x00000000), SHC(0x804628a7), SHC(0x085f2137), SHC(0x811855b4), SHC(0x10b5150f), + SHC(0x8275a0c0), SHC(0x18f8b83c), SHC(0x845c8ae3), SHC(0x2120fb83), SHC(0x86cafe57), SHC(0x2924edac), + SHC(0x89be50c3), SHC(0x30fbc54d), SHC(0x8d334625), SHC(0x389cea72), SHC(0x9126145f), SHC(0x40000000), + SHC(0x9592675c), SHC(0x471cece7), SHC(0x9a7365d3), SHC(0x4debe4fe), SHC(0x9fc3b694), SHC(0x54657194), + SHC(0x7fffffff), SHC(0x00000000), SHC(0x7f9afcb9), SHC(0xf5f50d67), SHC(0x7e6c9251), SHC(0xebf9f498), + SHC(0x7c769e18), SHC(0xe21e765a), SHC(0x79bc384d), SHC(0xd8722192), SHC(0x7641af3d), SHC(0xcf043ab3), + SHC(0x720c8075), SHC(0xc5e3a3a9), SHC(0x6d23501b), SHC(0xbd1ec45c), SHC(0x678dde6e), SHC(0xb4c373ee), + SHC(0x6154fb91), SHC(0xacdee2e8), SHC(0x5a82799a), SHC(0xa57d8666), SHC(0x53211d18), SHC(0x9eab046f), + SHC(0x4b3c8c12), SHC(0x98722192), SHC(0x42e13ba4), SHC(0x92dcafe5), SHC(0x3a1c5c57), SHC(0x8df37f8b), + SHC(0x30fbc54d), SHC(0x89be50c3), SHC(0x278dde6e), SHC(0x8643c7b3), SHC(0x1de189a6), SHC(0x838961e8), + SHC(0x14060b68), SHC(0x81936daf), SHC(0x0a0af299), SHC(0x80650347), SHC(0x00000000), SHC(0x80000000), + SHC(0xf5f50d67), SHC(0x80650347), SHC(0xebf9f498), SHC(0x81936daf), SHC(0xe21e765a), SHC(0x838961e8), + SHC(0xd8722192), SHC(0x8643c7b3), SHC(0xcf043ab3), SHC(0x89be50c3), SHC(0xc5e3a3a9), SHC(0x8df37f8b), + SHC(0xbd1ec45c), SHC(0x92dcafe5), SHC(0xb4c373ee), SHC(0x98722192), SHC(0xacdee2e8), SHC(0x9eab046f), + SHC(0xa57d8666), SHC(0xa57d8666), SHC(0x9eab046f), SHC(0xacdee2e8), SHC(0x98722192), SHC(0xb4c373ee), + SHC(0x92dcafe5), SHC(0xbd1ec45c), SHC(0x8df37f8b), SHC(0xc5e3a3a9), SHC(0x89be50c3), SHC(0xcf043ab3), + SHC(0x8643c7b3), SHC(0xd8722192), SHC(0x838961e8), SHC(0xe21e765a), SHC(0x81936daf), SHC(0xebf9f498), + SHC(0x80650347), SHC(0xf5f50d67), SHC(0x80000000), SHC(0x00000000), SHC(0x80650347), SHC(0x0a0af299), + SHC(0x81936daf), SHC(0x14060b68), SHC(0x838961e8), SHC(0x1de189a6), SHC(0x8643c7b3), SHC(0x278dde6e), + SHC(0x89be50c3), SHC(0x30fbc54d), SHC(0x8df37f8b), SHC(0x3a1c5c57), SHC(0x92dcafe5), SHC(0x42e13ba4), + SHC(0x98722192), SHC(0x4b3c8c12), SHC(0x9eab046f), SHC(0x53211d18), SHC(0xa57d8666), SHC(0x5a82799a), + SHC(0xacdee2e8), SHC(0x6154fb91), SHC(0xb4c373ee), SHC(0x678dde6e), SHC(0xbd1ec45c), SHC(0x6d23501b), + SHC(0xc5e3a3a9), SHC(0x720c8075), SHC(0xcf043ab3), SHC(0x7641af3d), SHC(0xd8722192), SHC(0x79bc384d), + SHC(0xe21e765a), SHC(0x7c769e18), SHC(0xebf9f498), SHC(0x7e6c9251), SHC(0xf5f50d67), SHC(0x7f9afcb9), + SHC(0x7fffffff), SHC(0x00000000), SHC(0x7f76892f), SHC(0xf449acca), SHC(0x7ddb4bfc), SHC(0xe8ac819d), + SHC(0x7b31bbb2), SHC(0xdd417079), SHC(0x777f903c), SHC(0xd220ffc0), SHC(0x72ccb9db), SHC(0xc763158e), + SHC(0x6d23501b), SHC(0xbd1ec45c), SHC(0x668f7c25), SHC(0xb36a1978), SHC(0x5f1f5ea1), SHC(0xaa59eda4), + SHC(0x56e2f15d), SHC(0xa201b853), SHC(0x4debe4fe), SHC(0x9a7365d3), SHC(0x444d7aff), SHC(0x93bf30d4), + SHC(0x3a1c5c57), SHC(0x8df37f8b), SHC(0x2f6e6d16), SHC(0x891cc4c1), SHC(0x245a9d65), SHC(0x8545651a), + SHC(0x18f8b83c), SHC(0x8275a0c0), SHC(0x0d61304e), SHC(0x80b381ac), SHC(0x01aceb7c), SHC(0x8002ceac), + SHC(0xf5f50d67), SHC(0x80650347), SHC(0xea52c166), SHC(0x81d94c8f), SHC(0xdedf047d), SHC(0x845c8ae3), + SHC(0xd3b26fb0), SHC(0x87e958a7), SHC(0xc8e5032b), SHC(0x8c7815dd), SHC(0xbe8df2ba), SHC(0x91fef880), + SHC(0xb4c373ee), SHC(0x98722192), SHC(0xab9a8e6c), SHC(0x9fc3b694), SHC(0xa326eec0), SHC(0xa7e3ff4d), + SHC(0x9b7abc1c), SHC(0xb0c1878b), SHC(0x94a6715d), SHC(0xba4944a2), SHC(0x8eb8b9a0), SHC(0xc466be4f), + SHC(0x89be50c3), SHC(0xcf043ab3), SHC(0x85c1e80e), SHC(0xda0aecf9), SHC(0x82cc0f36), SHC(0xe5632654), + SHC(0x80e321ff), SHC(0xf0f488d9), SHC(0x800b3a91), SHC(0xfca63bd8), SHC(0x804628a7), SHC(0x085f2137), + SHC(0x81936daf), SHC(0x14060b68), SHC(0x83f03dd6), SHC(0x1f81f37c), SHC(0x8757860c), SHC(0x2aba2ee4), + SHC(0x8bc1f6e8), SHC(0x3596a46c), SHC(0x9126145f), SHC(0x40000000), SHC(0x97784a1e), SHC(0x49dfe4c2), + SHC(0x9eab046f), SHC(0x53211d18), SHC(0xa6aecd5e), SHC(0x5bafc837), SHC(0xaf726def), SHC(0x637984d4), + SHC(0xb8e31319), SHC(0x6a6d98a4), SHC(0xc2ec7635), SHC(0x707d1443), SHC(0xcd790887), SHC(0x759af34c), + SHC(0xd8722192), SHC(0x79bc384d), SHC(0xe3c02fbb), SHC(0x7cd80464), SHC(0xef4aeaf1), SHC(0x7ee7aa4c), + SHC(0xfaf988cc), SHC(0x7fe6bcb0), SHC(0x06b2f1d2), SHC(0x7fd317b4), SHC(0x125df75b), SHC(0x7eace58a), + SHC(0x1de189a6), SHC(0x7c769e18), SHC(0x2924edac), SHC(0x793501a9), SHC(0x340ff242), SHC(0x74ef0ebc), + SHC(0x3e8b240e), SHC(0x6fadf2fc), SHC(0x487fffe4), SHC(0x697cf78a), SHC(0x51d92321), SHC(0x626968be)}; +# endif + +#ifdef ENABLE_FFT_30X16 +/* Twiddle coefficients for 30x16 FFTs, generated by fft_tables.py */ +# ifdef ENABLE_HR_MODE +const Word32 RotVector_30_16[2 * (480 - 30)] = { + + SHC(0x7fffffff), SHC(0x00000000), SHC(0x7ffd3154), SHC(0xfe531484), SHC(0x7ff4c56f), SHC(0xfca63bd8), + SHC(0x7fe6bcb0), SHC(0xfaf988cc), SHC(0x7fd317b4), SHC(0xf94d0e2e), SHC(0x7fb9d759), SHC(0xf7a0dec9), + SHC(0x7f9afcb9), SHC(0xf5f50d67), SHC(0x7f76892f), SHC(0xf449acca), SHC(0x7f4c7e54), SHC(0xf29ecfb2), + SHC(0x7f1cde01), SHC(0xf0f488d9), SHC(0x7ee7aa4c), SHC(0xef4aeaf1), SHC(0x7eace58a), SHC(0xeda208a5), + SHC(0x7e6c9251), SHC(0xebf9f498), SHC(0x7e26b371), SHC(0xea52c166), SHC(0x7ddb4bfc), SHC(0xe8ac819d), + SHC(0x7d8a5f40), SHC(0xe70747c4), SHC(0x7d33f0ca), SHC(0xe5632654), SHC(0x7cd80464), SHC(0xe3c02fbb), + SHC(0x7c769e18), SHC(0xe21e765a), SHC(0x7c0fc22a), SHC(0xe07e0c84), SHC(0x7ba3751d), SHC(0xdedf047d), + SHC(0x7b31bbb2), SHC(0xdd417079), SHC(0x7aba9ae6), SHC(0xdba5629b), SHC(0x7a3e17f2), SHC(0xda0aecf9), + SHC(0x79bc384d), SHC(0xd8722192), SHC(0x793501a9), SHC(0xd6db1254), SHC(0x78a879f4), SHC(0xd545d11c), + SHC(0x7816a759), SHC(0xd3b26fb0), SHC(0x777f903c), SHC(0xd220ffc0), SHC(0x76e33b3f), SHC(0xd09192ea), + SHC(0x7fffffff), SHC(0x00000000), SHC(0x7ff4c56f), SHC(0xfca63bd8), SHC(0x7fd317b4), SHC(0xf94d0e2e), + SHC(0x7f9afcb9), SHC(0xf5f50d67), SHC(0x7f4c7e54), SHC(0xf29ecfb2), SHC(0x7ee7aa4c), SHC(0xef4aeaf1), + SHC(0x7e6c9251), SHC(0xebf9f498), SHC(0x7ddb4bfc), SHC(0xe8ac819d), SHC(0x7d33f0ca), SHC(0xe5632654), + SHC(0x7c769e18), SHC(0xe21e765a), SHC(0x7ba3751d), SHC(0xdedf047d), SHC(0x7aba9ae6), SHC(0xdba5629b), + SHC(0x79bc384d), SHC(0xd8722192), SHC(0x78a879f4), SHC(0xd545d11c), SHC(0x777f903c), SHC(0xd220ffc0), + SHC(0x7641af3d), SHC(0xcf043ab3), SHC(0x74ef0ebc), SHC(0xcbf00dbe), SHC(0x7387ea23), SHC(0xc8e5032b), + SHC(0x720c8075), SHC(0xc5e3a3a9), SHC(0x707d1443), SHC(0xc2ec7635), SHC(0x6ed9eba1), SHC(0xc0000000), + SHC(0x6d23501b), SHC(0xbd1ec45c), SHC(0x6b598ea3), SHC(0xba4944a2), SHC(0x697cf78a), SHC(0xb780001c), + SHC(0x678dde6e), SHC(0xb4c373ee), SHC(0x658c9a2d), SHC(0xb2141b02), SHC(0x637984d4), SHC(0xaf726def), + SHC(0x6154fb91), SHC(0xacdee2e8), SHC(0x5f1f5ea1), SHC(0xaa59eda4), SHC(0x5cd91140), SHC(0xa7e3ff4d), + SHC(0x7fffffff), SHC(0x00000000), SHC(0x7fe6bcb0), SHC(0xfaf988cc), SHC(0x7f9afcb9), SHC(0xf5f50d67), + SHC(0x7f1cde01), SHC(0xf0f488d9), SHC(0x7e6c9251), SHC(0xebf9f498), SHC(0x7d8a5f40), SHC(0xe70747c4), + SHC(0x7c769e18), SHC(0xe21e765a), SHC(0x7b31bbb2), SHC(0xdd417079), SHC(0x79bc384d), SHC(0xd8722192), + SHC(0x7816a759), SHC(0xd3b26fb0), SHC(0x7641af3d), SHC(0xcf043ab3), SHC(0x743e0918), SHC(0xca695b94), + SHC(0x720c8075), SHC(0xc5e3a3a9), SHC(0x6fadf2fc), SHC(0xc174dbf2), SHC(0x6d23501b), SHC(0xbd1ec45c), + SHC(0x6a6d98a4), SHC(0xb8e31319), SHC(0x678dde6e), SHC(0xb4c373ee), SHC(0x648543e4), SHC(0xb0c1878b), + SHC(0x6154fb91), SHC(0xacdee2e8), SHC(0x5dfe47ad), SHC(0xa91d0ea3), SHC(0x5a82799a), SHC(0xa57d8666), + SHC(0x56e2f15d), SHC(0xa201b853), SHC(0x53211d18), SHC(0x9eab046f), SHC(0x4f3e7875), SHC(0x9b7abc1c), + SHC(0x4b3c8c12), SHC(0x98722192), SHC(0x471cece7), SHC(0x9592675c), SHC(0x42e13ba4), SHC(0x92dcafe5), + SHC(0x3e8b240e), SHC(0x90520d04), SHC(0x3a1c5c57), SHC(0x8df37f8b), SHC(0x3596a46c), SHC(0x8bc1f6e8), + SHC(0x7fffffff), SHC(0x00000000), SHC(0x7fd317b4), SHC(0xf94d0e2e), SHC(0x7f4c7e54), SHC(0xf29ecfb2), + SHC(0x7e6c9251), SHC(0xebf9f498), SHC(0x7d33f0ca), SHC(0xe5632654), SHC(0x7ba3751d), SHC(0xdedf047d), + SHC(0x79bc384d), SHC(0xd8722192), SHC(0x777f903c), SHC(0xd220ffc0), SHC(0x74ef0ebc), SHC(0xcbf00dbe), + SHC(0x720c8075), SHC(0xc5e3a3a9), SHC(0x6ed9eba1), SHC(0xc0000000), SHC(0x6b598ea3), SHC(0xba4944a2), + SHC(0x678dde6e), SHC(0xb4c373ee), SHC(0x637984d4), SHC(0xaf726def), SHC(0x5f1f5ea1), SHC(0xaa59eda4), + SHC(0x5a82799a), SHC(0xa57d8666), SHC(0x55a6125c), SHC(0xa0e0a15f), SHC(0x508d9211), SHC(0x9c867b2c), + SHC(0x4b3c8c12), SHC(0x98722192), SHC(0x45b6bb5e), SHC(0x94a6715d), SHC(0x40000000), SHC(0x9126145f), + SHC(0x3a1c5c57), SHC(0x8df37f8b), SHC(0x340ff242), SHC(0x8b10f144), SHC(0x2ddf0040), SHC(0x88806fc4), + SHC(0x278dde6e), SHC(0x8643c7b3), SHC(0x2120fb83), SHC(0x845c8ae3), SHC(0x1a9cd9ac), SHC(0x82cc0f36), + SHC(0x14060b68), SHC(0x81936daf), SHC(0x0d61304e), SHC(0x80b381ac), SHC(0x06b2f1d2), SHC(0x802ce84c), + SHC(0x7fffffff), SHC(0x00000000), SHC(0x7fb9d759), SHC(0xf7a0dec9), SHC(0x7ee7aa4c), SHC(0xef4aeaf1), + SHC(0x7d8a5f40), SHC(0xe70747c4), SHC(0x7ba3751d), SHC(0xdedf047d), SHC(0x793501a9), SHC(0xd6db1254), + SHC(0x7641af3d), SHC(0xcf043ab3), SHC(0x72ccb9db), SHC(0xc763158e), SHC(0x6ed9eba1), SHC(0xc0000000), + SHC(0x6a6d98a4), SHC(0xb8e31319), SHC(0x658c9a2d), SHC(0xb2141b02), SHC(0x603c496c), SHC(0xab9a8e6c), + SHC(0x5a82799a), SHC(0xa57d8666), SHC(0x54657194), SHC(0x9fc3b694), SHC(0x4debe4fe), SHC(0x9a7365d3), + SHC(0x471cece7), SHC(0x9592675c), SHC(0x40000000), SHC(0x9126145f), SHC(0x389cea72), SHC(0x8d334625), + SHC(0x30fbc54d), SHC(0x89be50c3), SHC(0x2924edac), SHC(0x86cafe57), SHC(0x2120fb83), SHC(0x845c8ae3), + SHC(0x18f8b83c), SHC(0x8275a0c0), SHC(0x10b5150f), SHC(0x811855b4), SHC(0x085f2137), SHC(0x804628a7), + SHC(0x00000000), SHC(0x80000000), SHC(0xf7a0dec9), SHC(0x804628a7), SHC(0xef4aeaf1), SHC(0x811855b4), + SHC(0xe70747c4), SHC(0x8275a0c0), SHC(0xdedf047d), SHC(0x845c8ae3), SHC(0xd6db1254), SHC(0x86cafe57), + SHC(0x7fffffff), SHC(0x00000000), SHC(0x7f9afcb9), SHC(0xf5f50d67), SHC(0x7e6c9251), SHC(0xebf9f498), + SHC(0x7c769e18), SHC(0xe21e765a), SHC(0x79bc384d), SHC(0xd8722192), SHC(0x7641af3d), SHC(0xcf043ab3), + SHC(0x720c8075), SHC(0xc5e3a3a9), SHC(0x6d23501b), SHC(0xbd1ec45c), SHC(0x678dde6e), SHC(0xb4c373ee), + SHC(0x6154fb91), SHC(0xacdee2e8), SHC(0x5a82799a), SHC(0xa57d8666), SHC(0x53211d18), SHC(0x9eab046f), + SHC(0x4b3c8c12), SHC(0x98722192), SHC(0x42e13ba4), SHC(0x92dcafe5), SHC(0x3a1c5c57), SHC(0x8df37f8b), + SHC(0x30fbc54d), SHC(0x89be50c3), SHC(0x278dde6e), SHC(0x8643c7b3), SHC(0x1de189a6), SHC(0x838961e8), + SHC(0x14060b68), SHC(0x81936daf), SHC(0x0a0af299), SHC(0x80650347), SHC(0x00000000), SHC(0x80000000), + SHC(0xf5f50d67), SHC(0x80650347), SHC(0xebf9f498), SHC(0x81936daf), SHC(0xe21e765a), SHC(0x838961e8), + SHC(0xd8722192), SHC(0x8643c7b3), SHC(0xcf043ab3), SHC(0x89be50c3), SHC(0xc5e3a3a9), SHC(0x8df37f8b), + SHC(0xbd1ec45c), SHC(0x92dcafe5), SHC(0xb4c373ee), SHC(0x98722192), SHC(0xacdee2e8), SHC(0x9eab046f), + SHC(0x7fffffff), SHC(0x00000000), SHC(0x7f76892f), SHC(0xf449acca), SHC(0x7ddb4bfc), SHC(0xe8ac819d), + SHC(0x7b31bbb2), SHC(0xdd417079), SHC(0x777f903c), SHC(0xd220ffc0), SHC(0x72ccb9db), SHC(0xc763158e), + SHC(0x6d23501b), SHC(0xbd1ec45c), SHC(0x668f7c25), SHC(0xb36a1978), SHC(0x5f1f5ea1), SHC(0xaa59eda4), + SHC(0x56e2f15d), SHC(0xa201b853), SHC(0x4debe4fe), SHC(0x9a7365d3), SHC(0x444d7aff), SHC(0x93bf30d4), + SHC(0x3a1c5c57), SHC(0x8df37f8b), SHC(0x2f6e6d16), SHC(0x891cc4c1), SHC(0x245a9d65), SHC(0x8545651a), + SHC(0x18f8b83c), SHC(0x8275a0c0), SHC(0x0d61304e), SHC(0x80b381ac), SHC(0x01aceb7c), SHC(0x8002ceac), + SHC(0xf5f50d67), SHC(0x80650347), SHC(0xea52c166), SHC(0x81d94c8f), SHC(0xdedf047d), SHC(0x845c8ae3), + SHC(0xd3b26fb0), SHC(0x87e958a7), SHC(0xc8e5032b), SHC(0x8c7815dd), SHC(0xbe8df2ba), SHC(0x91fef880), + SHC(0xb4c373ee), SHC(0x98722192), SHC(0xab9a8e6c), SHC(0x9fc3b694), SHC(0xa326eec0), SHC(0xa7e3ff4d), + SHC(0x9b7abc1c), SHC(0xb0c1878b), SHC(0x94a6715d), SHC(0xba4944a2), SHC(0x8eb8b9a0), SHC(0xc466be4f), + SHC(0x7fffffff), SHC(0x00000000), SHC(0x7f4c7e54), SHC(0xf29ecfb2), SHC(0x7d33f0ca), SHC(0xe5632654), + SHC(0x79bc384d), SHC(0xd8722192), SHC(0x74ef0ebc), SHC(0xcbf00dbe), SHC(0x6ed9eba1), SHC(0xc0000000), + SHC(0x678dde6e), SHC(0xb4c373ee), SHC(0x5f1f5ea1), SHC(0xaa59eda4), SHC(0x55a6125c), SHC(0xa0e0a15f), + SHC(0x4b3c8c12), SHC(0x98722192), SHC(0x40000000), SHC(0x9126145f), SHC(0x340ff242), SHC(0x8b10f144), + SHC(0x278dde6e), SHC(0x8643c7b3), SHC(0x1a9cd9ac), SHC(0x82cc0f36), SHC(0x0d61304e), SHC(0x80b381ac), + SHC(0x00000000), SHC(0x80000000), SHC(0xf29ecfb2), SHC(0x80b381ac), SHC(0xe5632654), SHC(0x82cc0f36), + SHC(0xd8722192), SHC(0x8643c7b3), SHC(0xcbf00dbe), SHC(0x8b10f144), SHC(0xc0000000), SHC(0x9126145f), + SHC(0xb4c373ee), SHC(0x98722192), SHC(0xaa59eda4), SHC(0xa0e0a15f), SHC(0xa0e0a15f), SHC(0xaa59eda4), + SHC(0x98722192), SHC(0xb4c373ee), SHC(0x9126145f), SHC(0xc0000000), SHC(0x8b10f144), SHC(0xcbf00dbe), + SHC(0x8643c7b3), SHC(0xd8722192), SHC(0x82cc0f36), SHC(0xe5632654), SHC(0x80b381ac), SHC(0xf29ecfb2), + SHC(0x7fffffff), SHC(0x00000000), SHC(0x7f1cde01), SHC(0xf0f488d9), SHC(0x7c769e18), SHC(0xe21e765a), + SHC(0x7816a759), SHC(0xd3b26fb0), SHC(0x720c8075), SHC(0xc5e3a3a9), SHC(0x6a6d98a4), SHC(0xb8e31319), + SHC(0x6154fb91), SHC(0xacdee2e8), SHC(0x56e2f15d), SHC(0xa201b853), SHC(0x4b3c8c12), SHC(0x98722192), + SHC(0x3e8b240e), SHC(0x90520d04), SHC(0x30fbc54d), SHC(0x89be50c3), SHC(0x22be8f87), SHC(0x84ce444e), + SHC(0x14060b68), SHC(0x81936daf), SHC(0x05067734), SHC(0x80194350), SHC(0xf5f50d67), SHC(0x80650347), + SHC(0xe70747c4), SHC(0x8275a0c0), SHC(0xd8722192), SHC(0x8643c7b3), SHC(0xca695b94), SHC(0x8bc1f6e8), + SHC(0xbd1ec45c), SHC(0x92dcafe5), SHC(0xb0c1878b), SHC(0x9b7abc1c), SHC(0xa57d8666), SHC(0xa57d8666), + SHC(0x9b7abc1c), SHC(0xb0c1878b), SHC(0x92dcafe5), SHC(0xbd1ec45c), SHC(0x8bc1f6e8), SHC(0xca695b94), + SHC(0x8643c7b3), SHC(0xd8722192), SHC(0x8275a0c0), SHC(0xe70747c4), SHC(0x80650347), SHC(0xf5f50d67), + SHC(0x80194350), SHC(0x05067734), SHC(0x81936daf), SHC(0x14060b68), SHC(0x84ce444e), SHC(0x22be8f87), + SHC(0x7fffffff), SHC(0x00000000), SHC(0x7ee7aa4c), SHC(0xef4aeaf1), SHC(0x7ba3751d), SHC(0xdedf047d), + SHC(0x7641af3d), SHC(0xcf043ab3), SHC(0x6ed9eba1), SHC(0xc0000000), SHC(0x658c9a2d), SHC(0xb2141b02), + SHC(0x5a82799a), SHC(0xa57d8666), SHC(0x4debe4fe), SHC(0x9a7365d3), SHC(0x40000000), SHC(0x9126145f), + SHC(0x30fbc54d), SHC(0x89be50c3), SHC(0x2120fb83), SHC(0x845c8ae3), SHC(0x10b5150f), SHC(0x811855b4), + SHC(0x00000000), SHC(0x80000000), SHC(0xef4aeaf1), SHC(0x811855b4), SHC(0xdedf047d), SHC(0x845c8ae3), + SHC(0xcf043ab3), SHC(0x89be50c3), SHC(0xc0000000), SHC(0x9126145f), SHC(0xb2141b02), SHC(0x9a7365d3), + SHC(0xa57d8666), SHC(0xa57d8666), SHC(0x9a7365d3), SHC(0xb2141b02), SHC(0x9126145f), SHC(0xc0000000), + SHC(0x89be50c3), SHC(0xcf043ab3), SHC(0x845c8ae3), SHC(0xdedf047d), SHC(0x811855b4), SHC(0xef4aeaf1), + SHC(0x80000000), SHC(0x00000000), SHC(0x811855b4), SHC(0x10b5150f), SHC(0x845c8ae3), SHC(0x2120fb83), + SHC(0x89be50c3), SHC(0x30fbc54d), SHC(0x9126145f), SHC(0x40000000), SHC(0x9a7365d3), SHC(0x4debe4fe), + SHC(0x7fffffff), SHC(0x00000000), SHC(0x7eace58a), SHC(0xeda208a5), SHC(0x7aba9ae6), SHC(0xdba5629b), + SHC(0x743e0918), SHC(0xca695b94), SHC(0x6b598ea3), SHC(0xba4944a2), SHC(0x603c496c), SHC(0xab9a8e6c), + SHC(0x53211d18), SHC(0x9eab046f), SHC(0x444d7aff), SHC(0x93bf30d4), SHC(0x340ff242), SHC(0x8b10f144), + SHC(0x22be8f87), SHC(0x84ce444e), SHC(0x10b5150f), SHC(0x811855b4), SHC(0xfe531484), SHC(0x8002ceac), + SHC(0xebf9f498), SHC(0x81936daf), SHC(0xda0aecf9), SHC(0x85c1e80e), SHC(0xc8e5032b), SHC(0x8c7815dd), + SHC(0xb8e31319), SHC(0x9592675c), SHC(0xaa59eda4), SHC(0xa0e0a15f), SHC(0x9d969742), SHC(0xae26dcdf), + SHC(0x92dcafe5), SHC(0xbd1ec45c), SHC(0x8a650cb4), SHC(0xcd790887), SHC(0x845c8ae3), SHC(0xdedf047d), + SHC(0x80e321ff), SHC(0xf0f488d9), SHC(0x800b3a91), SHC(0x0359c428), SHC(0x81d94c8f), SHC(0x15ad3e9a), + SHC(0x8643c7b3), SHC(0x278dde6e), SHC(0x8d334625), SHC(0x389cea72), SHC(0x96830876), SHC(0x487fffe4), + SHC(0xa201b853), SHC(0x56e2f15d), SHC(0xaf726def), SHC(0x637984d4), SHC(0xbe8df2ba), SHC(0x6e010780), + SHC(0x7fffffff), SHC(0x00000000), SHC(0x7e6c9251), SHC(0xebf9f498), SHC(0x79bc384d), SHC(0xd8722192), + SHC(0x720c8075), SHC(0xc5e3a3a9), SHC(0x678dde6e), SHC(0xb4c373ee), SHC(0x5a82799a), SHC(0xa57d8666), + SHC(0x4b3c8c12), SHC(0x98722192), SHC(0x3a1c5c57), SHC(0x8df37f8b), SHC(0x278dde6e), SHC(0x8643c7b3), + SHC(0x14060b68), SHC(0x81936daf), SHC(0x00000000), SHC(0x80000000), SHC(0xebf9f498), SHC(0x81936daf), + SHC(0xd8722192), SHC(0x8643c7b3), SHC(0xc5e3a3a9), SHC(0x8df37f8b), SHC(0xb4c373ee), SHC(0x98722192), + SHC(0xa57d8666), SHC(0xa57d8666), SHC(0x98722192), SHC(0xb4c373ee), SHC(0x8df37f8b), SHC(0xc5e3a3a9), + SHC(0x8643c7b3), SHC(0xd8722192), SHC(0x81936daf), SHC(0xebf9f498), SHC(0x80000000), SHC(0x00000000), + SHC(0x81936daf), SHC(0x14060b68), SHC(0x8643c7b3), SHC(0x278dde6e), SHC(0x8df37f8b), SHC(0x3a1c5c57), + SHC(0x98722192), SHC(0x4b3c8c12), SHC(0xa57d8666), SHC(0x5a82799a), SHC(0xb4c373ee), SHC(0x678dde6e), + SHC(0xc5e3a3a9), SHC(0x720c8075), SHC(0xd8722192), SHC(0x79bc384d), SHC(0xebf9f498), SHC(0x7e6c9251), + SHC(0x7fffffff), SHC(0x00000000), SHC(0x7e26b371), SHC(0xea52c166), SHC(0x78a879f4), SHC(0xd545d11c), + SHC(0x6fadf2fc), SHC(0xc174dbf2), SHC(0x637984d4), SHC(0xaf726def), SHC(0x54657194), SHC(0x9fc3b694), + SHC(0x42e13ba4), SHC(0x92dcafe5), SHC(0x2f6e6d16), SHC(0x891cc4c1), SHC(0x1a9cd9ac), SHC(0x82cc0f36), + SHC(0x05067734), SHC(0x80194350), SHC(0xef4aeaf1), SHC(0x811855b4), SHC(0xda0aecf9), SHC(0x85c1e80e), + SHC(0xc5e3a3a9), SHC(0x8df37f8b), SHC(0xb36a1978), SHC(0x997083db), SHC(0xa326eec0), SHC(0xa7e3ff4d), + SHC(0x9592675c), SHC(0xb8e31319), SHC(0x8b10f144), SHC(0xcbf00dbe), SHC(0x83f03dd6), SHC(0xe07e0c84), + SHC(0x80650347), SHC(0xf5f50d67), SHC(0x808976d1), SHC(0x0bb65336), SHC(0x845c8ae3), SHC(0x2120fb83), + SHC(0x8bc1f6e8), SHC(0x3596a46c), SHC(0x96830876), SHC(0x487fffe4), SHC(0xa45037c9), SHC(0x595132a2), + SHC(0xb4c373ee), SHC(0x678dde6e), SHC(0xc763158e), SHC(0x72ccb9db), SHC(0xdba5629b), SHC(0x7aba9ae6), + SHC(0xf0f488d9), SHC(0x7f1cde01), SHC(0x06b2f1d2), SHC(0x7fd317b4), SHC(0x1c3fd045), SHC(0x7cd80464), + SHC(0x7fffffff), SHC(0x00000000), SHC(0x7ddb4bfc), SHC(0xe8ac819d), SHC(0x777f903c), SHC(0xd220ffc0), + SHC(0x6d23501b), SHC(0xbd1ec45c), SHC(0x5f1f5ea1), SHC(0xaa59eda4), SHC(0x4debe4fe), SHC(0x9a7365d3), + SHC(0x3a1c5c57), SHC(0x8df37f8b), SHC(0x245a9d65), SHC(0x8545651a), SHC(0x0d61304e), SHC(0x80b381ac), + SHC(0xf5f50d67), SHC(0x80650347), SHC(0xdedf047d), SHC(0x845c8ae3), SHC(0xc8e5032b), SHC(0x8c7815dd), + SHC(0xb4c373ee), SHC(0x98722192), SHC(0xa326eec0), SHC(0xa7e3ff4d), SHC(0x94a6715d), SHC(0xba4944a2), + SHC(0x89be50c3), SHC(0xcf043ab3), SHC(0x82cc0f36), SHC(0xe5632654), SHC(0x800b3a91), SHC(0xfca63bd8), + SHC(0x81936daf), SHC(0x14060b68), SHC(0x8757860c), SHC(0x2aba2ee4), SHC(0x9126145f), SHC(0x40000000), + SHC(0x9eab046f), SHC(0x53211d18), SHC(0xaf726def), SHC(0x637984d4), SHC(0xc2ec7635), SHC(0x707d1443), + SHC(0xd8722192), SHC(0x79bc384d), SHC(0xef4aeaf1), SHC(0x7ee7aa4c), SHC(0x06b2f1d2), SHC(0x7fd317b4), + SHC(0x1de189a6), SHC(0x7c769e18), SHC(0x340ff242), SHC(0x74ef0ebc), SHC(0x487fffe4), SHC(0x697cf78a), + SHC(0x7fffffff), SHC(0x00000000), SHC(0x7d8a5f40), SHC(0xe70747c4), SHC(0x7641af3d), SHC(0xcf043ab3), + SHC(0x6a6d98a4), SHC(0xb8e31319), SHC(0x5a82799a), SHC(0xa57d8666), SHC(0x471cece7), SHC(0x9592675c), + SHC(0x30fbc54d), SHC(0x89be50c3), SHC(0x18f8b83c), SHC(0x8275a0c0), SHC(0x00000000), SHC(0x80000000), + SHC(0xe70747c4), SHC(0x8275a0c0), SHC(0xcf043ab3), SHC(0x89be50c3), SHC(0xb8e31319), SHC(0x9592675c), + SHC(0xa57d8666), SHC(0xa57d8666), SHC(0x9592675c), SHC(0xb8e31319), SHC(0x89be50c3), SHC(0xcf043ab3), + SHC(0x8275a0c0), SHC(0xe70747c4), SHC(0x80000000), SHC(0x00000000), SHC(0x8275a0c0), SHC(0x18f8b83c), + SHC(0x89be50c3), SHC(0x30fbc54d), SHC(0x9592675c), SHC(0x471cece7), SHC(0xa57d8666), SHC(0x5a82799a), + SHC(0xb8e31319), SHC(0x6a6d98a4), SHC(0xcf043ab3), SHC(0x7641af3d), SHC(0xe70747c4), SHC(0x7d8a5f40), + SHC(0x00000000), SHC(0x7fffffff), SHC(0x18f8b83c), SHC(0x7d8a5f40), SHC(0x30fbc54d), SHC(0x7641af3d), + SHC(0x471cece7), SHC(0x6a6d98a4), SHC(0x5a82799a), SHC(0x5a82799a), SHC(0x6a6d98a4), SHC(0x471cece7)}; +# endif +#endif + +# ifdef ENABLE_HR_MODE +const Word32 RotVector_360[2 * (360 - 30)] = { +# else +const Word16 RotVector_360[2 * (360 - 30)] = { +# endif + SHC(0x7fffffff), SHC(0x00000000), SHC(0x7ffb0260), SHC(0xfdc41e9b), SHC(0x7fec09e3), SHC(0xfb8869ce), + SHC(0x7fd317b4), SHC(0xf94d0e2e), SHC(0x7fb02dc6), SHC(0xf7123849), SHC(0x7f834ed0), SHC(0xf4d814a4), + SHC(0x7f4c7e54), SHC(0xf29ecfb2), SHC(0x7f0bc097), SHC(0xf06695da), SHC(0x7ec11aa5), SHC(0xee2f9369), + SHC(0x7e6c9251), SHC(0xebf9f498), SHC(0x7e0e2e32), SHC(0xe9c5e582), SHC(0x7da5f5a5), SHC(0xe7939223), + SHC(0x7d33f0ca), SHC(0xe5632654), SHC(0x7cb82885), SHC(0xe334cdc9), SHC(0x7c32a67e), SHC(0xe108b40d), + SHC(0x7ba3751d), SHC(0xdedf047d), SHC(0x7b0a9f8d), SHC(0xdcb7ea46), SHC(0x7a6831ba), SHC(0xda939061), + SHC(0x79bc384d), SHC(0xd8722192), SHC(0x7906c0b0), SHC(0xd653c860), SHC(0x7847d909), SHC(0xd438af17), + SHC(0x777f903c), SHC(0xd220ffc0), SHC(0x76adf5e6), SHC(0xd00ce422), SHC(0x75d31a61), SHC(0xcdfc85bb), + SHC(0x74ef0ebc), SHC(0xcbf00dbe), SHC(0x7401e4c1), SHC(0xc9e7a512), SHC(0x730baeed), SHC(0xc7e3744b), + SHC(0x720c8075), SHC(0xc5e3a3a9), SHC(0x71046d3e), SHC(0xc3e85b18), SHC(0x6ff389df), SHC(0xc1f1c224), + SHC(0x7fffffff), SHC(0x00000000), SHC(0x7fec09e3), SHC(0xfb8869ce), SHC(0x7fb02dc6), SHC(0xf7123849), + SHC(0x7f4c7e54), SHC(0xf29ecfb2), SHC(0x7ec11aa5), SHC(0xee2f9369), SHC(0x7e0e2e32), SHC(0xe9c5e582), + SHC(0x7d33f0ca), SHC(0xe5632654), SHC(0x7c32a67e), SHC(0xe108b40d), SHC(0x7b0a9f8d), SHC(0xdcb7ea46), + SHC(0x79bc384d), SHC(0xd8722192), SHC(0x7847d909), SHC(0xd438af17), SHC(0x76adf5e6), SHC(0xd00ce422), + SHC(0x74ef0ebc), SHC(0xcbf00dbe), SHC(0x730baeed), SHC(0xc7e3744b), SHC(0x71046d3e), SHC(0xc3e85b18), + SHC(0x6ed9eba1), SHC(0xc0000000), SHC(0x6c8cd70b), SHC(0xbc2b9b05), SHC(0x6a1de737), SHC(0xb86c5df0), + SHC(0x678dde6e), SHC(0xb4c373ee), SHC(0x64dd8950), SHC(0xb1320139), SHC(0x620dbe8b), SHC(0xadb922b7), + SHC(0x5f1f5ea1), SHC(0xaa59eda4), SHC(0x5c13539b), SHC(0xa7156f3c), SHC(0x58ea90c4), SHC(0xa3ecac65), + SHC(0x55a6125c), SHC(0xa0e0a15f), SHC(0x5246dd49), SHC(0x9df24175), SHC(0x4ecdfec7), SHC(0x9b2276b0), + SHC(0x4b3c8c12), SHC(0x98722192), SHC(0x4793a210), SHC(0x95e218c9), SHC(0x43d464fb), SHC(0x937328f5), + SHC(0x7fffffff), SHC(0x00000000), SHC(0x7fd317b4), SHC(0xf94d0e2e), SHC(0x7f4c7e54), SHC(0xf29ecfb2), + SHC(0x7e6c9251), SHC(0xebf9f498), SHC(0x7d33f0ca), SHC(0xe5632654), SHC(0x7ba3751d), SHC(0xdedf047d), + SHC(0x79bc384d), SHC(0xd8722192), SHC(0x777f903c), SHC(0xd220ffc0), SHC(0x74ef0ebc), SHC(0xcbf00dbe), + SHC(0x720c8075), SHC(0xc5e3a3a9), SHC(0x6ed9eba1), SHC(0xc0000000), SHC(0x6b598ea3), SHC(0xba4944a2), + SHC(0x678dde6e), SHC(0xb4c373ee), SHC(0x637984d4), SHC(0xaf726def), SHC(0x5f1f5ea1), SHC(0xaa59eda4), + SHC(0x5a82799a), SHC(0xa57d8666), SHC(0x55a6125c), SHC(0xa0e0a15f), SHC(0x508d9211), SHC(0x9c867b2c), + SHC(0x4b3c8c12), SHC(0x98722192), SHC(0x45b6bb5e), SHC(0x94a6715d), SHC(0x40000000), SHC(0x9126145f), + SHC(0x3a1c5c57), SHC(0x8df37f8b), SHC(0x340ff242), SHC(0x8b10f144), SHC(0x2ddf0040), SHC(0x88806fc4), + SHC(0x278dde6e), SHC(0x8643c7b3), SHC(0x2120fb83), SHC(0x845c8ae3), SHC(0x1a9cd9ac), SHC(0x82cc0f36), + SHC(0x14060b68), SHC(0x81936daf), SHC(0x0d61304e), SHC(0x80b381ac), SHC(0x06b2f1d2), SHC(0x802ce84c), + SHC(0x7fffffff), SHC(0x00000000), SHC(0x7fb02dc6), SHC(0xf7123849), SHC(0x7ec11aa5), SHC(0xee2f9369), + SHC(0x7d33f0ca), SHC(0xe5632654), SHC(0x7b0a9f8d), SHC(0xdcb7ea46), SHC(0x7847d909), SHC(0xd438af17), + SHC(0x74ef0ebc), SHC(0xcbf00dbe), SHC(0x71046d3e), SHC(0xc3e85b18), SHC(0x6c8cd70b), SHC(0xbc2b9b05), + SHC(0x678dde6e), SHC(0xb4c373ee), SHC(0x620dbe8b), SHC(0xadb922b7), SHC(0x5c13539b), SHC(0xa7156f3c), + SHC(0x55a6125c), SHC(0xa0e0a15f), SHC(0x4ecdfec7), SHC(0x9b2276b0), SHC(0x4793a210), SHC(0x95e218c9), + SHC(0x40000000), SHC(0x9126145f), SHC(0x381c8bb5), SHC(0x8cf45113), SHC(0x2ff31bde), SHC(0x89520a1a), + SHC(0x278dde6e), SHC(0x8643c7b3), SHC(0x1ef74bf3), SHC(0x83cd5982), SHC(0x163a1a7e), SHC(0x81f1d1ce), + SHC(0x0d61304e), SHC(0x80b381ac), SHC(0x04779632), SHC(0x8013f61d), SHC(0xfb8869ce), SHC(0x8013f61d), + SHC(0xf29ecfb2), SHC(0x80b381ac), SHC(0xe9c5e582), SHC(0x81f1d1ce), SHC(0xe108b40d), SHC(0x83cd5982), + SHC(0xd8722192), SHC(0x8643c7b3), SHC(0xd00ce422), SHC(0x89520a1a), SHC(0xc7e3744b), SHC(0x8cf45113), + SHC(0x7fffffff), SHC(0x00000000), SHC(0x7f834ed0), SHC(0xf4d814a4), SHC(0x7e0e2e32), SHC(0xe9c5e582), + SHC(0x7ba3751d), SHC(0xdedf047d), SHC(0x7847d909), SHC(0xd438af17), SHC(0x7401e4c1), SHC(0xc9e7a512), + SHC(0x6ed9eba1), SHC(0xc0000000), SHC(0x68d9f964), SHC(0xb6950c1e), SHC(0x620dbe8b), SHC(0xadb922b7), + SHC(0x5a82799a), SHC(0xa57d8666), SHC(0x5246dd49), SHC(0x9df24175), SHC(0x496af3e2), SHC(0x9726069c), + SHC(0x40000000), SHC(0x9126145f), SHC(0x36185aee), SHC(0x8bfe1b3f), SHC(0x2bc750e9), SHC(0x87b826f7), + SHC(0x2120fb83), SHC(0x845c8ae3), SHC(0x163a1a7e), SHC(0x81f1d1ce), SHC(0x0b27eb5c), SHC(0x807cb130), + SHC(0x00000000), SHC(0x80000000), SHC(0xf4d814a4), SHC(0x807cb130), SHC(0xe9c5e582), SHC(0x81f1d1ce), + SHC(0xdedf047d), SHC(0x845c8ae3), SHC(0xd438af17), SHC(0x87b826f7), SHC(0xc9e7a512), SHC(0x8bfe1b3f), + SHC(0xc0000000), SHC(0x9126145f), SHC(0xb6950c1e), SHC(0x9726069c), SHC(0xadb922b7), SHC(0x9df24175), + SHC(0xa57d8666), SHC(0xa57d8666), SHC(0x9df24175), SHC(0xadb922b7), SHC(0x9726069c), SHC(0xb6950c1e), + SHC(0x7fffffff), SHC(0x00000000), SHC(0x7f4c7e54), SHC(0xf29ecfb2), SHC(0x7d33f0ca), SHC(0xe5632654), + SHC(0x79bc384d), SHC(0xd8722192), SHC(0x74ef0ebc), SHC(0xcbf00dbe), SHC(0x6ed9eba1), SHC(0xc0000000), + SHC(0x678dde6e), SHC(0xb4c373ee), SHC(0x5f1f5ea1), SHC(0xaa59eda4), SHC(0x55a6125c), SHC(0xa0e0a15f), + SHC(0x4b3c8c12), SHC(0x98722192), SHC(0x40000000), SHC(0x9126145f), SHC(0x340ff242), SHC(0x8b10f144), + SHC(0x278dde6e), SHC(0x8643c7b3), SHC(0x1a9cd9ac), SHC(0x82cc0f36), SHC(0x0d61304e), SHC(0x80b381ac), + SHC(0x00000000), SHC(0x80000000), SHC(0xf29ecfb2), SHC(0x80b381ac), SHC(0xe5632654), SHC(0x82cc0f36), + SHC(0xd8722192), SHC(0x8643c7b3), SHC(0xcbf00dbe), SHC(0x8b10f144), SHC(0xc0000000), SHC(0x9126145f), + SHC(0xb4c373ee), SHC(0x98722192), SHC(0xaa59eda4), SHC(0xa0e0a15f), SHC(0xa0e0a15f), SHC(0xaa59eda4), + SHC(0x98722192), SHC(0xb4c373ee), SHC(0x9126145f), SHC(0xc0000000), SHC(0x8b10f144), SHC(0xcbf00dbe), + SHC(0x8643c7b3), SHC(0xd8722192), SHC(0x82cc0f36), SHC(0xe5632654), SHC(0x80b381ac), SHC(0xf29ecfb2), + SHC(0x7fffffff), SHC(0x00000000), SHC(0x7f0bc097), SHC(0xf06695da), SHC(0x7c32a67e), SHC(0xe108b40d), + SHC(0x777f903c), SHC(0xd220ffc0), SHC(0x71046d3e), SHC(0xc3e85b18), SHC(0x68d9f964), SHC(0xb6950c1e), + SHC(0x5f1f5ea1), SHC(0xaa59eda4), SHC(0x53f9be05), SHC(0x9f65ad2d), SHC(0x4793a210), SHC(0x95e218c9), + SHC(0x3a1c5c57), SHC(0x8df37f8b), SHC(0x2bc750e9), SHC(0x87b826f7), SHC(0x1ccb3237), SHC(0x8347d77b), + SHC(0x0d61304e), SHC(0x80b381ac), SHC(0xfdc41e9b), SHC(0x8004fda0), SHC(0xee2f9369), SHC(0x813ee55b), + SHC(0xdedf047d), SHC(0x845c8ae3), SHC(0xd00ce422), SHC(0x89520a1a), SHC(0xc1f1c224), SHC(0x900c7621), + SHC(0xb4c373ee), SHC(0x98722192), SHC(0xa8b4471a), SHC(0xa263007d), SHC(0x9df24175), SHC(0xadb922b7), + SHC(0x94a6715d), SHC(0xba4944a2), SHC(0x8cf45113), SHC(0xc7e3744b), SHC(0x86f93f50), SHC(0xd653c860), + SHC(0x82cc0f36), SHC(0xe5632654), SHC(0x807cb130), SHC(0xf4d814a4), SHC(0x8013f61d), SHC(0x04779632), + SHC(0x81936daf), SHC(0x14060b68), SHC(0x84f56073), SHC(0x234815ba), SHC(0x8a2ce59f), SHC(0x32037a45), + SHC(0x7fffffff), SHC(0x00000000), SHC(0x7ec11aa5), SHC(0xee2f9369), SHC(0x7b0a9f8d), SHC(0xdcb7ea46), + SHC(0x74ef0ebc), SHC(0xcbf00dbe), SHC(0x6c8cd70b), SHC(0xbc2b9b05), SHC(0x620dbe8b), SHC(0xadb922b7), + SHC(0x55a6125c), SHC(0xa0e0a15f), SHC(0x4793a210), SHC(0x95e218c9), SHC(0x381c8bb5), SHC(0x8cf45113), + SHC(0x278dde6e), SHC(0x8643c7b3), SHC(0x163a1a7e), SHC(0x81f1d1ce), SHC(0x04779632), SHC(0x8013f61d), + SHC(0xf29ecfb2), SHC(0x80b381ac), SHC(0xe108b40d), SHC(0x83cd5982), SHC(0xd00ce422), SHC(0x89520a1a), + SHC(0xc0000000), SHC(0x9126145f), SHC(0xb1320139), SHC(0x9b2276b0), SHC(0xa3ecac65), SHC(0xa7156f3c), + SHC(0x98722192), SHC(0xb4c373ee), SHC(0x8efb92c2), SHC(0xc3e85b18), SHC(0x87b826f7), SHC(0xd438af17), + SHC(0x82cc0f36), SHC(0xe5632654), SHC(0x804fd23a), SHC(0xf7123849), SHC(0x804fd23a), SHC(0x08edc7b7), + SHC(0x82cc0f36), SHC(0x1a9cd9ac), SHC(0x87b826f7), SHC(0x2bc750e9), SHC(0x8efb92c2), SHC(0x3c17a4e8), + SHC(0x98722192), SHC(0x4b3c8c12), SHC(0xa3ecac65), SHC(0x58ea90c4), SHC(0xb1320139), SHC(0x64dd8950), + SHC(0x7fffffff), SHC(0x00000000), SHC(0x7e6c9251), SHC(0xebf9f498), SHC(0x79bc384d), SHC(0xd8722192), + SHC(0x720c8075), SHC(0xc5e3a3a9), SHC(0x678dde6e), SHC(0xb4c373ee), SHC(0x5a82799a), SHC(0xa57d8666), + SHC(0x4b3c8c12), SHC(0x98722192), SHC(0x3a1c5c57), SHC(0x8df37f8b), SHC(0x278dde6e), SHC(0x8643c7b3), + SHC(0x14060b68), SHC(0x81936daf), SHC(0x00000000), SHC(0x80000000), SHC(0xebf9f498), SHC(0x81936daf), + SHC(0xd8722192), SHC(0x8643c7b3), SHC(0xc5e3a3a9), SHC(0x8df37f8b), SHC(0xb4c373ee), SHC(0x98722192), + SHC(0xa57d8666), SHC(0xa57d8666), SHC(0x98722192), SHC(0xb4c373ee), SHC(0x8df37f8b), SHC(0xc5e3a3a9), + SHC(0x8643c7b3), SHC(0xd8722192), SHC(0x81936daf), SHC(0xebf9f498), SHC(0x80000000), SHC(0x00000000), + SHC(0x81936daf), SHC(0x14060b68), SHC(0x8643c7b3), SHC(0x278dde6e), SHC(0x8df37f8b), SHC(0x3a1c5c57), + SHC(0x98722192), SHC(0x4b3c8c12), SHC(0xa57d8666), SHC(0x5a82799a), SHC(0xb4c373ee), SHC(0x678dde6e), + SHC(0xc5e3a3a9), SHC(0x720c8075), SHC(0xd8722192), SHC(0x79bc384d), SHC(0xebf9f498), SHC(0x7e6c9251), + SHC(0x7fffffff), SHC(0x00000000), SHC(0x7e0e2e32), SHC(0xe9c5e582), SHC(0x7847d909), SHC(0xd438af17), + SHC(0x6ed9eba1), SHC(0xc0000000), SHC(0x620dbe8b), SHC(0xadb922b7), SHC(0x5246dd49), SHC(0x9df24175), + SHC(0x40000000), SHC(0x9126145f), SHC(0x2bc750e9), SHC(0x87b826f7), SHC(0x163a1a7e), SHC(0x81f1d1ce), + SHC(0x00000000), SHC(0x80000000), SHC(0xe9c5e582), SHC(0x81f1d1ce), SHC(0xd438af17), SHC(0x87b826f7), + SHC(0xc0000000), SHC(0x9126145f), SHC(0xadb922b7), SHC(0x9df24175), SHC(0x9df24175), SHC(0xadb922b7), + SHC(0x9126145f), SHC(0xc0000000), SHC(0x87b826f7), SHC(0xd438af17), SHC(0x81f1d1ce), SHC(0xe9c5e582), + SHC(0x80000000), SHC(0x00000000), SHC(0x81f1d1ce), SHC(0x163a1a7e), SHC(0x87b826f7), SHC(0x2bc750e9), + SHC(0x9126145f), SHC(0x40000000), SHC(0x9df24175), SHC(0x5246dd49), SHC(0xadb922b7), SHC(0x620dbe8b), + SHC(0xc0000000), SHC(0x6ed9eba1), SHC(0xd438af17), SHC(0x7847d909), SHC(0xe9c5e582), SHC(0x7e0e2e32), + SHC(0x00000000), SHC(0x7fffffff), SHC(0x163a1a7e), SHC(0x7e0e2e32), SHC(0x2bc750e9), SHC(0x7847d909), + SHC(0x7fffffff), SHC(0x00000000), SHC(0x7da5f5a5), SHC(0xe7939223), SHC(0x76adf5e6), SHC(0xd00ce422), + SHC(0x6b598ea3), SHC(0xba4944a2), SHC(0x5c13539b), SHC(0xa7156f3c), SHC(0x496af3e2), SHC(0x9726069c), + SHC(0x340ff242), SHC(0x8b10f144), SHC(0x1ccb3237), SHC(0x8347d77b), SHC(0x04779632), SHC(0x8013f61d), + SHC(0xebf9f498), SHC(0x81936daf), SHC(0xd438af17), SHC(0x87b826f7), SHC(0xbe133b7c), SHC(0x92485786), + SHC(0xaa59eda4), SHC(0xa0e0a15f), SHC(0x99c64fc5), SHC(0xb2f7b9af), SHC(0x8cf45113), SHC(0xc7e3744b), + SHC(0x845c8ae3), SHC(0xdedf047d), SHC(0x804fd23a), SHC(0xf7123849), SHC(0x80f43f69), SHC(0x0f996a26), + SHC(0x8643c7b3), SHC(0x278dde6e), SHC(0x900c7621), SHC(0x3e0e3ddc), SHC(0x9df24175), SHC(0x5246dd49), + SHC(0xaf726def), SHC(0x637984d4), SHC(0xc3e85b18), SHC(0x71046d3e), SHC(0xda939061), SHC(0x7a6831ba), + SHC(0xf29ecfb2), SHC(0x7f4c7e54), SHC(0x0b27eb5c), SHC(0x7f834ed0), SHC(0x234815ba), SHC(0x7b0a9f8d), + SHC(0x3a1c5c57), SHC(0x720c8075), SHC(0x4ecdfec7), SHC(0x64dd8950), SHC(0x609a52d3), SHC(0x53f9be05)}; + +# ifdef ENABLE_HR_MODE +const Word32 RotVector_320[2 * (320 - 20)] = { +# else +const Word16 RotVector_320[2 * (320 - 20)] = { +# endif + SHC(0x7fffffff), SHC(0x00000000), SHC(0x7fe6bcb0), SHC(0xfaf988cc), SHC(0x7f9afcb9), SHC(0xf5f50d67), + SHC(0x7f1cde01), SHC(0xf0f488d9), SHC(0x7e6c9251), SHC(0xebf9f498), SHC(0x7d8a5f40), SHC(0xe70747c4), + SHC(0x7c769e18), SHC(0xe21e765a), SHC(0x7b31bbb2), SHC(0xdd417079), SHC(0x79bc384d), SHC(0xd8722192), + SHC(0x7816a759), SHC(0xd3b26fb0), SHC(0x7641af3d), SHC(0xcf043ab3), SHC(0x743e0918), SHC(0xca695b94), + SHC(0x720c8075), SHC(0xc5e3a3a9), SHC(0x6fadf2fc), SHC(0xc174dbf2), SHC(0x6d23501b), SHC(0xbd1ec45c), + SHC(0x6a6d98a4), SHC(0xb8e31319), SHC(0x678dde6e), SHC(0xb4c373ee), SHC(0x648543e4), SHC(0xb0c1878b), + SHC(0x6154fb91), SHC(0xacdee2e8), SHC(0x5dfe47ad), SHC(0xa91d0ea3), SHC(0x7fffffff), SHC(0x00000000), + SHC(0x7f9afcb9), SHC(0xf5f50d67), SHC(0x7e6c9251), SHC(0xebf9f498), SHC(0x7c769e18), SHC(0xe21e765a), + SHC(0x79bc384d), SHC(0xd8722192), SHC(0x7641af3d), SHC(0xcf043ab3), SHC(0x720c8075), SHC(0xc5e3a3a9), + SHC(0x6d23501b), SHC(0xbd1ec45c), SHC(0x678dde6e), SHC(0xb4c373ee), SHC(0x6154fb91), SHC(0xacdee2e8), + SHC(0x5a82799a), SHC(0xa57d8666), SHC(0x53211d18), SHC(0x9eab046f), SHC(0x4b3c8c12), SHC(0x98722192), + SHC(0x42e13ba4), SHC(0x92dcafe5), SHC(0x3a1c5c57), SHC(0x8df37f8b), SHC(0x30fbc54d), SHC(0x89be50c3), + SHC(0x278dde6e), SHC(0x8643c7b3), SHC(0x1de189a6), SHC(0x838961e8), SHC(0x14060b68), SHC(0x81936daf), + SHC(0x0a0af299), SHC(0x80650347), SHC(0x7fffffff), SHC(0x00000000), SHC(0x7f1cde01), SHC(0xf0f488d9), + SHC(0x7c769e18), SHC(0xe21e765a), SHC(0x7816a759), SHC(0xd3b26fb0), SHC(0x720c8075), SHC(0xc5e3a3a9), + SHC(0x6a6d98a4), SHC(0xb8e31319), SHC(0x6154fb91), SHC(0xacdee2e8), SHC(0x56e2f15d), SHC(0xa201b853), + SHC(0x4b3c8c12), SHC(0x98722192), SHC(0x3e8b240e), SHC(0x90520d04), SHC(0x30fbc54d), SHC(0x89be50c3), + SHC(0x22be8f87), SHC(0x84ce444e), SHC(0x14060b68), SHC(0x81936daf), SHC(0x05067734), SHC(0x80194350), + SHC(0xf5f50d67), SHC(0x80650347), SHC(0xe70747c4), SHC(0x8275a0c0), SHC(0xd8722192), SHC(0x8643c7b3), + SHC(0xca695b94), SHC(0x8bc1f6e8), SHC(0xbd1ec45c), SHC(0x92dcafe5), SHC(0xb0c1878b), SHC(0x9b7abc1c), + SHC(0x7fffffff), SHC(0x00000000), SHC(0x7e6c9251), SHC(0xebf9f498), SHC(0x79bc384d), SHC(0xd8722192), + SHC(0x720c8075), SHC(0xc5e3a3a9), SHC(0x678dde6e), SHC(0xb4c373ee), SHC(0x5a82799a), SHC(0xa57d8666), + SHC(0x4b3c8c12), SHC(0x98722192), SHC(0x3a1c5c57), SHC(0x8df37f8b), SHC(0x278dde6e), SHC(0x8643c7b3), + SHC(0x14060b68), SHC(0x81936daf), SHC(0x00000000), SHC(0x80000000), SHC(0xebf9f498), SHC(0x81936daf), + SHC(0xd8722192), SHC(0x8643c7b3), SHC(0xc5e3a3a9), SHC(0x8df37f8b), SHC(0xb4c373ee), SHC(0x98722192), + SHC(0xa57d8666), SHC(0xa57d8666), SHC(0x98722192), SHC(0xb4c373ee), SHC(0x8df37f8b), SHC(0xc5e3a3a9), + SHC(0x8643c7b3), SHC(0xd8722192), SHC(0x81936daf), SHC(0xebf9f498), SHC(0x7fffffff), SHC(0x00000000), + SHC(0x7d8a5f40), SHC(0xe70747c4), SHC(0x7641af3d), SHC(0xcf043ab3), SHC(0x6a6d98a4), SHC(0xb8e31319), + SHC(0x5a82799a), SHC(0xa57d8666), SHC(0x471cece7), SHC(0x9592675c), SHC(0x30fbc54d), SHC(0x89be50c3), + SHC(0x18f8b83c), SHC(0x8275a0c0), SHC(0x00000000), SHC(0x80000000), SHC(0xe70747c4), SHC(0x8275a0c0), + SHC(0xcf043ab3), SHC(0x89be50c3), SHC(0xb8e31319), SHC(0x9592675c), SHC(0xa57d8666), SHC(0xa57d8666), + SHC(0x9592675c), SHC(0xb8e31319), SHC(0x89be50c3), SHC(0xcf043ab3), SHC(0x8275a0c0), SHC(0xe70747c4), + SHC(0x80000000), SHC(0x00000000), SHC(0x8275a0c0), SHC(0x18f8b83c), SHC(0x89be50c3), SHC(0x30fbc54d), + SHC(0x9592675c), SHC(0x471cece7), SHC(0x7fffffff), SHC(0x00000000), SHC(0x7c769e18), SHC(0xe21e765a), + SHC(0x720c8075), SHC(0xc5e3a3a9), SHC(0x6154fb91), SHC(0xacdee2e8), SHC(0x4b3c8c12), SHC(0x98722192), + SHC(0x30fbc54d), SHC(0x89be50c3), SHC(0x14060b68), SHC(0x81936daf), SHC(0xf5f50d67), SHC(0x80650347), + SHC(0xd8722192), SHC(0x8643c7b3), SHC(0xbd1ec45c), SHC(0x92dcafe5), SHC(0xa57d8666), SHC(0xa57d8666), + SHC(0x92dcafe5), SHC(0xbd1ec45c), SHC(0x8643c7b3), SHC(0xd8722192), SHC(0x80650347), SHC(0xf5f50d67), + SHC(0x81936daf), SHC(0x14060b68), SHC(0x89be50c3), SHC(0x30fbc54d), SHC(0x98722192), SHC(0x4b3c8c12), + SHC(0xacdee2e8), SHC(0x6154fb91), SHC(0xc5e3a3a9), SHC(0x720c8075), SHC(0xe21e765a), SHC(0x7c769e18), + SHC(0x7fffffff), SHC(0x00000000), SHC(0x7b31bbb2), SHC(0xdd417079), SHC(0x6d23501b), SHC(0xbd1ec45c), + SHC(0x56e2f15d), SHC(0xa201b853), SHC(0x3a1c5c57), SHC(0x8df37f8b), SHC(0x18f8b83c), SHC(0x8275a0c0), + SHC(0xf5f50d67), SHC(0x80650347), SHC(0xd3b26fb0), SHC(0x87e958a7), SHC(0xb4c373ee), SHC(0x98722192), + SHC(0x9b7abc1c), SHC(0xb0c1878b), SHC(0x89be50c3), SHC(0xcf043ab3), SHC(0x80e321ff), SHC(0xf0f488d9), + SHC(0x81936daf), SHC(0x14060b68), SHC(0x8bc1f6e8), SHC(0x3596a46c), SHC(0x9eab046f), SHC(0x53211d18), + SHC(0xb8e31319), SHC(0x6a6d98a4), SHC(0xd8722192), SHC(0x79bc384d), SHC(0xfaf988cc), SHC(0x7fe6bcb0), + SHC(0x1de189a6), SHC(0x7c769e18), SHC(0x3e8b240e), SHC(0x6fadf2fc), SHC(0x7fffffff), SHC(0x00000000), + SHC(0x7ff9af04), SHC(0xfd7ca4a6), SHC(0x7fe6bcb0), SHC(0xfaf988cc), SHC(0x7fc72ae2), SHC(0xf876ebe8), + SHC(0x7f9afcb9), SHC(0xf5f50d67), SHC(0x7f62368f), SHC(0xf3742ca2), SHC(0x7f1cde01), SHC(0xf0f488d9), + SHC(0x7ecaf9e5), SHC(0xee76612d), SHC(0x7e6c9251), SHC(0xebf9f498), SHC(0x7e01b096), SHC(0xe97f81eb), + SHC(0x7d8a5f40), SHC(0xe70747c4), SHC(0x7d06aa16), SHC(0xe4918486), SHC(0x7c769e18), SHC(0xe21e765a), + SHC(0x7bda497d), SHC(0xdfae5b23), SHC(0x7b31bbb2), SHC(0xdd417079), SHC(0x7a7d055b), SHC(0xdad7f3a2), + SHC(0x79bc384d), SHC(0xd8722192), SHC(0x78ef678f), SHC(0xd61036db), SHC(0x7816a759), SHC(0xd3b26fb0), + SHC(0x77320d0d), SHC(0xd15907d9), SHC(0x7fffffff), SHC(0x00000000), SHC(0x7fc72ae2), SHC(0xf876ebe8), + SHC(0x7f1cde01), SHC(0xf0f488d9), SHC(0x7e01b096), SHC(0xe97f81eb), SHC(0x7c769e18), SHC(0xe21e765a), + SHC(0x7a7d055b), SHC(0xdad7f3a2), SHC(0x7816a759), SHC(0xd3b26fb0), SHC(0x7545a5a0), SHC(0xccb44322), + SHC(0x720c8075), SHC(0xc5e3a3a9), SHC(0x6e6e1492), SHC(0xbf469e83), SHC(0x6a6d98a4), SHC(0xb8e31319), + SHC(0x660e9a6a), SHC(0xb2beadcc), SHC(0x6154fb91), SHC(0xacdee2e8), SHC(0x5c44ee40), SHC(0xa748e9ce), + SHC(0x56e2f15d), SHC(0xa201b853), SHC(0x5133cc94), SHC(0x9d0dfe54), SHC(0x4b3c8c12), SHC(0x98722192), + SHC(0x45027c0c), SHC(0x943239c7), SHC(0x3e8b240e), SHC(0x90520d04), SHC(0x37dc420c), SHC(0x8cd50c59), + SHC(0x7fffffff), SHC(0x00000000), SHC(0x7f62368f), SHC(0xf3742ca2), SHC(0x7d8a5f40), SHC(0xe70747c4), + SHC(0x7a7d055b), SHC(0xdad7f3a2), SHC(0x7641af3d), SHC(0xcf043ab3), SHC(0x70e2cbc6), SHC(0xc3a94590), + SHC(0x6a6d98a4), SHC(0xb8e31319), SHC(0x62f201ac), SHC(0xaecc336c), SHC(0x5a82799a), SHC(0xa57d8666), + SHC(0x5133cc94), SHC(0x9d0dfe54), SHC(0x471cece7), SHC(0x9592675c), SHC(0x3c56ba70), SHC(0x8f1d343a), + SHC(0x30fbc54d), SHC(0x89be50c3), SHC(0x25280c5e), SHC(0x8582faa5), SHC(0x18f8b83c), SHC(0x8275a0c0), + SHC(0x0c8bd35e), SHC(0x809dc971), SHC(0x00000000), SHC(0x80000000), SHC(0xf3742ca2), SHC(0x809dc971), + SHC(0xe70747c4), SHC(0x8275a0c0), SHC(0xdad7f3a2), SHC(0x8582faa5), SHC(0x7fffffff), SHC(0x00000000), + SHC(0x7ecaf9e5), SHC(0xee76612d), SHC(0x7b31bbb2), SHC(0xdd417079), SHC(0x7545a5a0), SHC(0xccb44322), + SHC(0x6d23501b), SHC(0xbd1ec45c), SHC(0x62f201ac), SHC(0xaecc336c), SHC(0x56e2f15d), SHC(0xa201b853), + SHC(0x4930590f), SHC(0x96fd15e3), SHC(0x3a1c5c57), SHC(0x8df37f8b), SHC(0x29efc925), SHC(0x87109871), + SHC(0x18f8b83c), SHC(0x8275a0c0), SHC(0x07891418), SHC(0x8038d51e), SHC(0xf5f50d67), SHC(0x80650347), + SHC(0xe4918486), SHC(0x82f955ea), SHC(0xd3b26fb0), SHC(0x87e958a7), SHC(0xc3a94590), SHC(0x8f1d343a), + SHC(0xb4c373ee), SHC(0x98722192), SHC(0xa748e9ce), SHC(0xa3bb11c0), SHC(0x9b7abc1c), SHC(0xb0c1878b), + SHC(0x9191eb6e), SHC(0xbf469e83), SHC(0x7fffffff), SHC(0x00000000), SHC(0x7e01b096), SHC(0xe97f81eb), + SHC(0x7816a759), SHC(0xd3b26fb0), SHC(0x6e6e1492), SHC(0xbf469e83), SHC(0x6154fb91), SHC(0xacdee2e8), + SHC(0x5133cc94), SHC(0x9d0dfe54), SHC(0x3e8b240e), SHC(0x90520d04), SHC(0x29efc925), SHC(0x87109871), + SHC(0x14060b68), SHC(0x81936daf), SHC(0xfd7ca4a6), SHC(0x800650fc), SHC(0xe70747c4), SHC(0x8275a0c0), + SHC(0xd15907d9), SHC(0x88cdf2f3), SHC(0xbd1ec45c), SHC(0x92dcafe5), SHC(0xaaf9c6af), SHC(0xa051a5ab), + SHC(0x9b7abc1c), SHC(0xb0c1878b), SHC(0x8f1d343a), SHC(0xc3a94590), SHC(0x8643c7b3), SHC(0xd8722192), + SHC(0x8135061b), SHC(0xee76612d), SHC(0x80194350), SHC(0x05067734), SHC(0x82f955ea), SHC(0x1b6e7b7a), + SHC(0x7fffffff), SHC(0x00000000), SHC(0x7d06aa16), SHC(0xe4918486), SHC(0x743e0918), SHC(0xca695b94), + SHC(0x660e9a6a), SHC(0xb2beadcc), SHC(0x53211d18), SHC(0x9eab046f), SHC(0x3c56ba70), SHC(0x8f1d343a), + SHC(0x22be8f87), SHC(0x84ce444e), SHC(0x07891418), SHC(0x8038d51e), SHC(0xebf9f498), SHC(0x81936daf), + SHC(0xd15907d9), SHC(0x88cdf2f3), SHC(0xb8e31319), SHC(0x9592675c), SHC(0xa3bb11c0), SHC(0xa748e9ce), + SHC(0x92dcafe5), SHC(0xbd1ec45c), SHC(0x87109871), SHC(0xd61036db), SHC(0x80e321ff), SHC(0xf0f488d9), + SHC(0x809dc971), SHC(0x0c8bd35e), SHC(0x8643c7b3), SHC(0x278dde6e), SHC(0x9191eb6e), SHC(0x40b9617d), + SHC(0xa201b853), SHC(0x56e2f15d), SHC(0xb6cfa6f1), SHC(0x6902ea1d), SHC(0x7fffffff), SHC(0x00000000), + SHC(0x7bda497d), SHC(0xdfae5b23), SHC(0x6fadf2fc), SHC(0xc174dbf2), SHC(0x5c44ee40), SHC(0xa748e9ce), + SHC(0x42e13ba4), SHC(0x92dcafe5), SHC(0x25280c5e), SHC(0x8582faa5), SHC(0x05067734), SHC(0x80194350), + SHC(0xe4918486), SHC(0x82f955ea), SHC(0xc5e3a3a9), SHC(0x8df37f8b), SHC(0xaaf9c6af), SHC(0xa051a5ab), + SHC(0x9592675c), SHC(0xb8e31319), SHC(0x87109871), SHC(0xd61036db), SHC(0x80650347), SHC(0xf5f50d67), + SHC(0x81fe4f6a), SHC(0x16807e15), SHC(0x8bc1f6e8), SHC(0x3596a46c), SHC(0x9d0dfe54), SHC(0x5133cc94), + SHC(0xb4c373ee), SHC(0x678dde6e), SHC(0xd15907d9), SHC(0x77320d0d), SHC(0xf0f488d9), SHC(0x7f1cde01), + SHC(0x11899ed3), SHC(0x7ecaf9e5), SHC(0x7fffffff), SHC(0x00000000), SHC(0x7a7d055b), SHC(0xdad7f3a2), + SHC(0x6a6d98a4), SHC(0xb8e31319), SHC(0x5133cc94), SHC(0x9d0dfe54), SHC(0x30fbc54d), SHC(0x89be50c3), + SHC(0x0c8bd35e), SHC(0x809dc971), SHC(0xe70747c4), SHC(0x8275a0c0), SHC(0xc3a94590), SHC(0x8f1d343a), + SHC(0xa57d8666), SHC(0xa57d8666), SHC(0x8f1d343a), SHC(0xc3a94590), SHC(0x8275a0c0), SHC(0xe70747c4), + SHC(0x809dc971), SHC(0x0c8bd35e), SHC(0x89be50c3), SHC(0x30fbc54d), SHC(0x9d0dfe54), SHC(0x5133cc94), + SHC(0xb8e31319), SHC(0x6a6d98a4), SHC(0xdad7f3a2), SHC(0x7a7d055b), SHC(0x00000000), SHC(0x7fffffff), + SHC(0x25280c5e), SHC(0x7a7d055b), SHC(0x471cece7), SHC(0x6a6d98a4), SHC(0x62f201ac), SHC(0x5133cc94)}; + + +/* Twiddle coefficients for 32x8 FFTs, generated by fft_tables.py */ +# ifdef ENABLE_HR_MODE +const Word32 RotVector_32_8[2 * (256 - 32)] = { +# else +const Word16 RotVector_32_8[2 * (256 - 32)] = { +# endif + SHC(0x7fffffff), SHC(0x00000000), SHC(0x7ff62182), SHC(0xfcdbd541), SHC(0x7fd8878e), SHC(0xf9b82684), + SHC(0x7fa736b4), SHC(0xf6956fb7), SHC(0x7f62368f), SHC(0xf3742ca2), SHC(0x7f0991c4), SHC(0xf054d8d5), + SHC(0x7e9d55fc), SHC(0xed37ef91), SHC(0x7e1d93ea), SHC(0xea1debbb), SHC(0x7d8a5f40), SHC(0xe70747c4), + SHC(0x7ce3ceb2), SHC(0xe3f47d96), SHC(0x7c29fbee), SHC(0xe0e60685), SHC(0x7b5d039e), SHC(0xdddc5b3b), + SHC(0x7a7d055b), SHC(0xdad7f3a2), SHC(0x798a23b1), SHC(0xd7d946d8), SHC(0x78848414), SHC(0xd4e0cb15), + SHC(0x776c4edb), SHC(0xd1eef59e), SHC(0x7641af3d), SHC(0xcf043ab3), SHC(0x7504d345), SHC(0xcc210d79), + SHC(0x73b5ebd1), SHC(0xc945dfec), SHC(0x72552c85), SHC(0xc67322ce), SHC(0x70e2cbc6), SHC(0xc3a94590), + SHC(0x6f5f02b2), SHC(0xc0e8b648), SHC(0x6dca0d14), SHC(0xbe31e19b), SHC(0x6c242960), SHC(0xbb8532b0), + SHC(0x6a6d98a4), SHC(0xb8e31319), SHC(0x68a69e81), SHC(0xb64beacd), SHC(0x66cf8120), SHC(0xb3c0200c), + SHC(0x64e88926), SHC(0xb140175b), SHC(0x62f201ac), SHC(0xaecc336c), SHC(0x60ec3830), SHC(0xac64d510), + SHC(0x5ed77c8a), SHC(0xaa0a5b2e), SHC(0x5cb420e0), SHC(0xa7bd22ac), SHC(0x7fffffff), SHC(0x00000000), + SHC(0x7fd8878e), SHC(0xf9b82684), SHC(0x7f62368f), SHC(0xf3742ca2), SHC(0x7e9d55fc), SHC(0xed37ef91), + SHC(0x7d8a5f40), SHC(0xe70747c4), SHC(0x7c29fbee), SHC(0xe0e60685), SHC(0x7a7d055b), SHC(0xdad7f3a2), + SHC(0x78848414), SHC(0xd4e0cb15), SHC(0x7641af3d), SHC(0xcf043ab3), SHC(0x73b5ebd1), SHC(0xc945dfec), + SHC(0x70e2cbc6), SHC(0xc3a94590), SHC(0x6dca0d14), SHC(0xbe31e19b), SHC(0x6a6d98a4), SHC(0xb8e31319), + SHC(0x66cf8120), SHC(0xb3c0200c), SHC(0x62f201ac), SHC(0xaecc336c), SHC(0x5ed77c8a), SHC(0xaa0a5b2e), + SHC(0x5a82799a), SHC(0xa57d8666), SHC(0x55f5a4d2), SHC(0xa1288376), SHC(0x5133cc94), SHC(0x9d0dfe54), + SHC(0x4c3fdff4), SHC(0x99307ee0), SHC(0x471cece7), SHC(0x9592675c), SHC(0x41ce1e65), SHC(0x9235f2ec), + SHC(0x3c56ba70), SHC(0x8f1d343a), SHC(0x36ba2014), SHC(0x8c4a142f), SHC(0x30fbc54d), SHC(0x89be50c3), + SHC(0x2b1f34eb), SHC(0x877b7bec), SHC(0x25280c5e), SHC(0x8582faa5), SHC(0x1f19f97b), SHC(0x83d60412), + SHC(0x18f8b83c), SHC(0x8275a0c0), SHC(0x12c8106f), SHC(0x8162aa04), SHC(0x0c8bd35e), SHC(0x809dc971), + SHC(0x0647d97c), SHC(0x80277872), SHC(0x7fffffff), SHC(0x00000000), SHC(0x7fa736b4), SHC(0xf6956fb7), + SHC(0x7e9d55fc), SHC(0xed37ef91), SHC(0x7ce3ceb2), SHC(0xe3f47d96), SHC(0x7a7d055b), SHC(0xdad7f3a2), + SHC(0x776c4edb), SHC(0xd1eef59e), SHC(0x73b5ebd1), SHC(0xc945dfec), SHC(0x6f5f02b2), SHC(0xc0e8b648), + SHC(0x6a6d98a4), SHC(0xb8e31319), SHC(0x64e88926), SHC(0xb140175b), SHC(0x5ed77c8a), SHC(0xaa0a5b2e), + SHC(0x5842dd54), SHC(0xa34bdf20), SHC(0x5133cc94), SHC(0x9d0dfe54), SHC(0x49b41533), SHC(0x9759617f), + SHC(0x41ce1e65), SHC(0x9235f2ec), SHC(0x398cdd32), SHC(0x8daad37b), SHC(0x30fbc54d), SHC(0x89be50c3), + SHC(0x2826b928), SHC(0x8675dc4f), SHC(0x1f19f97b), SHC(0x83d60412), SHC(0x15e21445), SHC(0x81e26c16), + SHC(0x0c8bd35e), SHC(0x809dc971), SHC(0x03242abf), SHC(0x8009de7e), SHC(0xf9b82684), SHC(0x80277872), + SHC(0xf054d8d5), SHC(0x80f66e3c), SHC(0xe70747c4), SHC(0x8275a0c0), SHC(0xdddc5b3b), SHC(0x84a2fc62), + SHC(0xd4e0cb15), SHC(0x877b7bec), SHC(0xcc210d79), SHC(0x8afb2cbb), SHC(0xc3a94590), SHC(0x8f1d343a), + SHC(0xbb8532b0), SHC(0x93dbd6a0), SHC(0xb3c0200c), SHC(0x99307ee0), SHC(0xac64d510), SHC(0x9f13c7d0), + SHC(0x7fffffff), SHC(0x00000000), SHC(0x7f62368f), SHC(0xf3742ca2), SHC(0x7d8a5f40), SHC(0xe70747c4), + SHC(0x7a7d055b), SHC(0xdad7f3a2), SHC(0x7641af3d), SHC(0xcf043ab3), SHC(0x70e2cbc6), SHC(0xc3a94590), + SHC(0x6a6d98a4), SHC(0xb8e31319), SHC(0x62f201ac), SHC(0xaecc336c), SHC(0x5a82799a), SHC(0xa57d8666), + SHC(0x5133cc94), SHC(0x9d0dfe54), SHC(0x471cece7), SHC(0x9592675c), SHC(0x3c56ba70), SHC(0x8f1d343a), + SHC(0x30fbc54d), SHC(0x89be50c3), SHC(0x25280c5e), SHC(0x8582faa5), SHC(0x18f8b83c), SHC(0x8275a0c0), + SHC(0x0c8bd35e), SHC(0x809dc971), SHC(0x00000000), SHC(0x80000000), SHC(0xf3742ca2), SHC(0x809dc971), + SHC(0xe70747c4), SHC(0x8275a0c0), SHC(0xdad7f3a2), SHC(0x8582faa5), SHC(0xcf043ab3), SHC(0x89be50c3), + SHC(0xc3a94590), SHC(0x8f1d343a), SHC(0xb8e31319), SHC(0x9592675c), SHC(0xaecc336c), SHC(0x9d0dfe54), + SHC(0xa57d8666), SHC(0xa57d8666), SHC(0x9d0dfe54), SHC(0xaecc336c), SHC(0x9592675c), SHC(0xb8e31319), + SHC(0x8f1d343a), SHC(0xc3a94590), SHC(0x89be50c3), SHC(0xcf043ab3), SHC(0x8582faa5), SHC(0xdad7f3a2), + SHC(0x8275a0c0), SHC(0xe70747c4), SHC(0x809dc971), SHC(0xf3742ca2), SHC(0x7fffffff), SHC(0x00000000), + SHC(0x7f0991c4), SHC(0xf054d8d5), SHC(0x7c29fbee), SHC(0xe0e60685), SHC(0x776c4edb), SHC(0xd1eef59e), + SHC(0x70e2cbc6), SHC(0xc3a94590), SHC(0x68a69e81), SHC(0xb64beacd), SHC(0x5ed77c8a), SHC(0xaa0a5b2e), + SHC(0x539b2af0), SHC(0x9f13c7d0), SHC(0x471cece7), SHC(0x9592675c), SHC(0x398cdd32), SHC(0x8daad37b), + SHC(0x2b1f34eb), SHC(0x877b7bec), SHC(0x1c0b826a), SHC(0x831c314e), SHC(0x0c8bd35e), SHC(0x809dc971), + SHC(0xfcdbd541), SHC(0x8009de7e), SHC(0xed37ef91), SHC(0x8162aa04), SHC(0xdddc5b3b), SHC(0x84a2fc62), + SHC(0xcf043ab3), SHC(0x89be50c3), SHC(0xc0e8b648), SHC(0x90a0fd4e), SHC(0xb3c0200c), SHC(0x99307ee0), + SHC(0xa7bd22ac), SHC(0xa34bdf20), SHC(0x9d0dfe54), SHC(0xaecc336c), SHC(0x93dbd6a0), SHC(0xbb8532b0), + SHC(0x8c4a142f), SHC(0xc945dfec), SHC(0x8675dc4f), SHC(0xd7d946d8), SHC(0x8275a0c0), SHC(0xe70747c4), + SHC(0x8058c94c), SHC(0xf6956fb7), SHC(0x80277872), SHC(0x0647d97c), SHC(0x81e26c16), SHC(0x15e21445), + SHC(0x8582faa5), SHC(0x25280c5e), SHC(0x8afb2cbb), SHC(0x33def287), SHC(0x9235f2ec), SHC(0x41ce1e65), + SHC(0x9b1776da), SHC(0x4ebfe8a5), SHC(0x7fffffff), SHC(0x00000000), SHC(0x7e9d55fc), SHC(0xed37ef91), + SHC(0x7a7d055b), SHC(0xdad7f3a2), SHC(0x73b5ebd1), SHC(0xc945dfec), SHC(0x6a6d98a4), SHC(0xb8e31319), + SHC(0x5ed77c8a), SHC(0xaa0a5b2e), SHC(0x5133cc94), SHC(0x9d0dfe54), SHC(0x41ce1e65), SHC(0x9235f2ec), + SHC(0x30fbc54d), SHC(0x89be50c3), SHC(0x1f19f97b), SHC(0x83d60412), SHC(0x0c8bd35e), SHC(0x809dc971), + SHC(0xf9b82684), SHC(0x80277872), SHC(0xe70747c4), SHC(0x8275a0c0), SHC(0xd4e0cb15), SHC(0x877b7bec), + SHC(0xc3a94590), SHC(0x8f1d343a), SHC(0xb3c0200c), SHC(0x99307ee0), SHC(0xa57d8666), SHC(0xa57d8666), + SHC(0x99307ee0), SHC(0xb3c0200c), SHC(0x8f1d343a), SHC(0xc3a94590), SHC(0x877b7bec), SHC(0xd4e0cb15), + SHC(0x8275a0c0), SHC(0xe70747c4), SHC(0x80277872), SHC(0xf9b82684), SHC(0x809dc971), SHC(0x0c8bd35e), + SHC(0x83d60412), SHC(0x1f19f97b), SHC(0x89be50c3), SHC(0x30fbc54d), SHC(0x9235f2ec), SHC(0x41ce1e65), + SHC(0x9d0dfe54), SHC(0x5133cc94), SHC(0xaa0a5b2e), SHC(0x5ed77c8a), SHC(0xb8e31319), SHC(0x6a6d98a4), + SHC(0xc945dfec), SHC(0x73b5ebd1), SHC(0xdad7f3a2), SHC(0x7a7d055b), SHC(0xed37ef91), SHC(0x7e9d55fc), + SHC(0x7fffffff), SHC(0x00000000), SHC(0x7e1d93ea), SHC(0xea1debbb), SHC(0x78848414), SHC(0xd4e0cb15), + SHC(0x6f5f02b2), SHC(0xc0e8b648), SHC(0x62f201ac), SHC(0xaecc336c), SHC(0x539b2af0), SHC(0x9f13c7d0), + SHC(0x41ce1e65), SHC(0x9235f2ec), SHC(0x2e110a62), SHC(0x8893b125), SHC(0x18f8b83c), SHC(0x8275a0c0), + SHC(0x03242abf), SHC(0x8009de7e), SHC(0xed37ef91), SHC(0x8162aa04), SHC(0xd7d946d8), SHC(0x8675dc4f), + SHC(0xc3a94590), SHC(0x8f1d343a), SHC(0xb140175b), SHC(0x9b1776da), SHC(0xa1288376), SHC(0xaa0a5b2e), + SHC(0x93dbd6a0), SHC(0xbb8532b0), SHC(0x89be50c3), SHC(0xcf043ab3), SHC(0x831c314e), SHC(0xe3f47d96), + SHC(0x80277872), SHC(0xf9b82684), SHC(0x80f66e3c), SHC(0x0fab272b), SHC(0x8582faa5), SHC(0x25280c5e), + SHC(0x8daad37b), SHC(0x398cdd32), SHC(0x99307ee0), SHC(0x4c3fdff4), SHC(0xa7bd22ac), SHC(0x5cb420e0), + SHC(0xb8e31319), SHC(0x6a6d98a4), SHC(0xcc210d79), SHC(0x7504d345), SHC(0xe0e60685), SHC(0x7c29fbee), + SHC(0xf6956fb7), SHC(0x7fa736b4), SHC(0x0c8bd35e), SHC(0x7f62368f), SHC(0x2223a4c5), SHC(0x7b5d039e), + SHC(0x36ba2014), SHC(0x73b5ebd1), SHC(0x49b41533), SHC(0x68a69e81)}; + + +# ifdef ENABLE_HR_MODE +const Word32 RotVector_15_6[2 * (90 - 15)] = { +# else +const Word16 RotVector_15_6[2 * (90 - 15)] = { +# endif + SHC(0x7fffffff), SHC(0x00000000), SHC(0x7fb02dc6), SHC(0xf7123849), SHC(0x7ec11aa5), SHC(0xee2f9369), + SHC(0x7d33f0ca), SHC(0xe5632654), SHC(0x7b0a9f8d), SHC(0xdcb7ea46), SHC(0x7847d909), SHC(0xd438af17), + SHC(0x74ef0ebc), SHC(0xcbf00dbe), SHC(0x71046d3e), SHC(0xc3e85b18), SHC(0x6c8cd70b), SHC(0xbc2b9b05), + SHC(0x678dde6e), SHC(0xb4c373ee), SHC(0x620dbe8b), SHC(0xadb922b7), SHC(0x5c13539b), SHC(0xa7156f3c), + SHC(0x55a6125c), SHC(0xa0e0a15f), SHC(0x4ecdfec7), SHC(0x9b2276b0), SHC(0x4793a210), SHC(0x95e218c9), + SHC(0x7fffffff), SHC(0x00000000), SHC(0x7ec11aa5), SHC(0xee2f9369), SHC(0x7b0a9f8d), SHC(0xdcb7ea46), + SHC(0x74ef0ebc), SHC(0xcbf00dbe), SHC(0x6c8cd70b), SHC(0xbc2b9b05), SHC(0x620dbe8b), SHC(0xadb922b7), + SHC(0x55a6125c), SHC(0xa0e0a15f), SHC(0x4793a210), SHC(0x95e218c9), SHC(0x381c8bb5), SHC(0x8cf45113), + SHC(0x278dde6e), SHC(0x8643c7b3), SHC(0x163a1a7e), SHC(0x81f1d1ce), SHC(0x04779632), SHC(0x8013f61d), + SHC(0xf29ecfb2), SHC(0x80b381ac), SHC(0xe108b40d), SHC(0x83cd5982), SHC(0xd00ce422), SHC(0x89520a1a), + SHC(0x7fffffff), SHC(0x00000000), SHC(0x7d33f0ca), SHC(0xe5632654), SHC(0x74ef0ebc), SHC(0xcbf00dbe), + SHC(0x678dde6e), SHC(0xb4c373ee), SHC(0x55a6125c), SHC(0xa0e0a15f), SHC(0x40000000), SHC(0x9126145f), + SHC(0x278dde6e), SHC(0x8643c7b3), SHC(0x0d61304e), SHC(0x80b381ac), SHC(0xf29ecfb2), SHC(0x80b381ac), + SHC(0xd8722192), SHC(0x8643c7b3), SHC(0xc0000000), SHC(0x9126145f), SHC(0xaa59eda4), SHC(0xa0e0a15f), + SHC(0x98722192), SHC(0xb4c373ee), SHC(0x8b10f144), SHC(0xcbf00dbe), SHC(0x82cc0f36), SHC(0xe5632654), + SHC(0x7fffffff), SHC(0x00000000), SHC(0x7b0a9f8d), SHC(0xdcb7ea46), SHC(0x6c8cd70b), SHC(0xbc2b9b05), + SHC(0x55a6125c), SHC(0xa0e0a15f), SHC(0x381c8bb5), SHC(0x8cf45113), SHC(0x163a1a7e), SHC(0x81f1d1ce), + SHC(0xf29ecfb2), SHC(0x80b381ac), SHC(0xd00ce422), SHC(0x89520a1a), SHC(0xb1320139), SHC(0x9b2276b0), + SHC(0x98722192), SHC(0xb4c373ee), SHC(0x87b826f7), SHC(0xd438af17), SHC(0x804fd23a), SHC(0xf7123849), + SHC(0x82cc0f36), SHC(0x1a9cd9ac), SHC(0x8efb92c2), SHC(0x3c17a4e8), SHC(0xa3ecac65), SHC(0x58ea90c4), + SHC(0x7fffffff), SHC(0x00000000), SHC(0x7847d909), SHC(0xd438af17), SHC(0x620dbe8b), SHC(0xadb922b7), + SHC(0x40000000), SHC(0x9126145f), SHC(0x163a1a7e), SHC(0x81f1d1ce), SHC(0xe9c5e582), SHC(0x81f1d1ce), + SHC(0xc0000000), SHC(0x9126145f), SHC(0x9df24175), SHC(0xadb922b7), SHC(0x87b826f7), SHC(0xd438af17), + SHC(0x80000000), SHC(0x00000000), SHC(0x87b826f7), SHC(0x2bc750e9), SHC(0x9df24175), SHC(0x5246dd49), + SHC(0xc0000000), SHC(0x6ed9eba1), SHC(0xe9c5e582), SHC(0x7e0e2e32), SHC(0x163a1a7e), SHC(0x7e0e2e32)}; + +#if defined(SUBSET_SSWB) || defined(SUBSET_SWB) || defined(SUBSET_FB) +/* Twiddle coefficients for 32x12 FFTs, generated by fft_tables.py */ +# ifdef ENABLE_HR_MODE +const Word32 RotVector_32_12[2 * (384 - 32)] = { +# else +const Word16 RotVector_32_12[2 * (384 - 32)] = { +# endif + SHC(0x7fffffff), SHC(0x00000000), SHC(0x7ffb9d15), SHC(0xfde7dbd9), SHC(0x7fee74a2), SHC(0xfbcfdc71), + SHC(0x7fd8878e), SHC(0xf9b82684), SHC(0x7fb9d759), SHC(0xf7a0dec9), SHC(0x7f92661d), SHC(0xf58a29f2), + SHC(0x7f62368f), SHC(0xf3742ca2), SHC(0x7f294bfd), SHC(0xf15f0b74), SHC(0x7ee7aa4c), SHC(0xef4aeaf1), + SHC(0x7e9d55fc), SHC(0xed37ef91), SHC(0x7e4a5426), SHC(0xeb263dbb), SHC(0x7deeaa7a), SHC(0xe915f9ba), + SHC(0x7d8a5f40), SHC(0xe70747c4), SHC(0x7d1d7958), SHC(0xe4fa4bf1), SHC(0x7ca80038), SHC(0xe2ef2a3e), + SHC(0x7c29fbee), SHC(0xe0e60685), SHC(0x7ba3751d), SHC(0xdedf047d), SHC(0x7b1474fd), SHC(0xdcda47b9), + SHC(0x7a7d055b), SHC(0xdad7f3a2), SHC(0x79dd3098), SHC(0xd8d82b7a), SHC(0x793501a9), SHC(0xd6db1254), + SHC(0x78848414), SHC(0xd4e0cb15), SHC(0x77cbc3f2), SHC(0xd2e9786e), SHC(0x770acdec), SHC(0xd0f53ce0), + SHC(0x7641af3d), SHC(0xcf043ab3), SHC(0x757075ac), SHC(0xcd1693f7), SHC(0x74972f92), SHC(0xcb2c6a82), + SHC(0x73b5ebd1), SHC(0xc945dfec), SHC(0x72ccb9db), SHC(0xc763158e), SHC(0x71dba9ab), SHC(0xc5842c7e), + SHC(0x70e2cbc6), SHC(0xc3a94590), SHC(0x6fe2313c), SHC(0xc1d2814f), SHC(0x7fffffff), SHC(0x00000000), + SHC(0x7fee74a2), SHC(0xfbcfdc71), SHC(0x7fb9d759), SHC(0xf7a0dec9), SHC(0x7f62368f), SHC(0xf3742ca2), + SHC(0x7ee7aa4c), SHC(0xef4aeaf1), SHC(0x7e4a5426), SHC(0xeb263dbb), SHC(0x7d8a5f40), SHC(0xe70747c4), + SHC(0x7ca80038), SHC(0xe2ef2a3e), SHC(0x7ba3751d), SHC(0xdedf047d), SHC(0x7a7d055b), SHC(0xdad7f3a2), + SHC(0x793501a9), SHC(0xd6db1254), SHC(0x77cbc3f2), SHC(0xd2e9786e), SHC(0x7641af3d), SHC(0xcf043ab3), + SHC(0x74972f92), SHC(0xcb2c6a82), SHC(0x72ccb9db), SHC(0xc763158e), SHC(0x70e2cbc6), SHC(0xc3a94590), + SHC(0x6ed9eba1), SHC(0xc0000000), SHC(0x6cb2a837), SHC(0xbc6845ce), SHC(0x6a6d98a4), SHC(0xb8e31319), + SHC(0x680b5c33), SHC(0xb5715eef), SHC(0x658c9a2d), SHC(0xb2141b02), SHC(0x62f201ac), SHC(0xaecc336c), + SHC(0x603c496c), SHC(0xab9a8e6c), SHC(0x5d6c2f99), SHC(0xa8800c26), SHC(0x5a82799a), SHC(0xa57d8666), + SHC(0x577ff3da), SHC(0xa293d067), SHC(0x54657194), SHC(0x9fc3b694), SHC(0x5133cc94), SHC(0x9d0dfe54), + SHC(0x4debe4fe), SHC(0x9a7365d3), SHC(0x4a8ea111), SHC(0x97f4a3cd), SHC(0x471cece7), SHC(0x9592675c), + SHC(0x4397ba32), SHC(0x934d57c9), SHC(0x7fffffff), SHC(0x00000000), SHC(0x7fd8878e), SHC(0xf9b82684), + SHC(0x7f62368f), SHC(0xf3742ca2), SHC(0x7e9d55fc), SHC(0xed37ef91), SHC(0x7d8a5f40), SHC(0xe70747c4), + SHC(0x7c29fbee), SHC(0xe0e60685), SHC(0x7a7d055b), SHC(0xdad7f3a2), SHC(0x78848414), SHC(0xd4e0cb15), + SHC(0x7641af3d), SHC(0xcf043ab3), SHC(0x73b5ebd1), SHC(0xc945dfec), SHC(0x70e2cbc6), SHC(0xc3a94590), + SHC(0x6dca0d14), SHC(0xbe31e19b), SHC(0x6a6d98a4), SHC(0xb8e31319), SHC(0x66cf8120), SHC(0xb3c0200c), + SHC(0x62f201ac), SHC(0xaecc336c), SHC(0x5ed77c8a), SHC(0xaa0a5b2e), SHC(0x5a82799a), SHC(0xa57d8666), + SHC(0x55f5a4d2), SHC(0xa1288376), SHC(0x5133cc94), SHC(0x9d0dfe54), SHC(0x4c3fdff4), SHC(0x99307ee0), + SHC(0x471cece7), SHC(0x9592675c), SHC(0x41ce1e65), SHC(0x9235f2ec), SHC(0x3c56ba70), SHC(0x8f1d343a), + SHC(0x36ba2014), SHC(0x8c4a142f), SHC(0x30fbc54d), SHC(0x89be50c3), SHC(0x2b1f34eb), SHC(0x877b7bec), + SHC(0x25280c5e), SHC(0x8582faa5), SHC(0x1f19f97b), SHC(0x83d60412), SHC(0x18f8b83c), SHC(0x8275a0c0), + SHC(0x12c8106f), SHC(0x8162aa04), SHC(0x0c8bd35e), SHC(0x809dc971), SHC(0x0647d97c), SHC(0x80277872), + SHC(0x7fffffff), SHC(0x00000000), SHC(0x7fb9d759), SHC(0xf7a0dec9), SHC(0x7ee7aa4c), SHC(0xef4aeaf1), + SHC(0x7d8a5f40), SHC(0xe70747c4), SHC(0x7ba3751d), SHC(0xdedf047d), SHC(0x793501a9), SHC(0xd6db1254), + SHC(0x7641af3d), SHC(0xcf043ab3), SHC(0x72ccb9db), SHC(0xc763158e), SHC(0x6ed9eba1), SHC(0xc0000000), + SHC(0x6a6d98a4), SHC(0xb8e31319), SHC(0x658c9a2d), SHC(0xb2141b02), SHC(0x603c496c), SHC(0xab9a8e6c), + SHC(0x5a82799a), SHC(0xa57d8666), SHC(0x54657194), SHC(0x9fc3b694), SHC(0x4debe4fe), SHC(0x9a7365d3), + SHC(0x471cece7), SHC(0x9592675c), SHC(0x40000000), SHC(0x9126145f), SHC(0x389cea72), SHC(0x8d334625), + SHC(0x30fbc54d), SHC(0x89be50c3), SHC(0x2924edac), SHC(0x86cafe57), SHC(0x2120fb83), SHC(0x845c8ae3), + SHC(0x18f8b83c), SHC(0x8275a0c0), SHC(0x10b5150f), SHC(0x811855b4), SHC(0x085f2137), SHC(0x804628a7), + SHC(0x00000000), SHC(0x80000000), SHC(0xf7a0dec9), SHC(0x804628a7), SHC(0xef4aeaf1), SHC(0x811855b4), + SHC(0xe70747c4), SHC(0x8275a0c0), SHC(0xdedf047d), SHC(0x845c8ae3), SHC(0xd6db1254), SHC(0x86cafe57), + SHC(0xcf043ab3), SHC(0x89be50c3), SHC(0xc763158e), SHC(0x8d334625), SHC(0x7fffffff), SHC(0x00000000), + SHC(0x7f92661d), SHC(0xf58a29f2), SHC(0x7e4a5426), SHC(0xeb263dbb), SHC(0x7c29fbee), SHC(0xe0e60685), + SHC(0x793501a9), SHC(0xd6db1254), SHC(0x757075ac), SHC(0xcd1693f7), SHC(0x70e2cbc6), SHC(0xc3a94590), + SHC(0x6b93d02e), SHC(0xbaa34bf4), SHC(0x658c9a2d), SHC(0xb2141b02), SHC(0x5ed77c8a), SHC(0xaa0a5b2e), + SHC(0x577ff3da), SHC(0xa293d067), SHC(0x4f9292dc), SHC(0x9bbd4282), SHC(0x471cece7), SHC(0x9592675c), + SHC(0x3e2d7eb1), SHC(0x901dcec4), SHC(0x34d3957e), SHC(0x8b68d06e), SHC(0x2b1f34eb), SHC(0x877b7bec), + SHC(0x2120fb83), SHC(0x845c8ae3), SHC(0x16ea0646), SHC(0x82115586), SHC(0x0c8bd35e), SHC(0x809dc971), + SHC(0x02182427), SHC(0x800462eb), SHC(0xf7a0dec9), SHC(0x804628a7), SHC(0xed37ef91), SHC(0x8162aa04), + SHC(0xe2ef2a3e), SHC(0x8357ffc8), SHC(0xd8d82b7a), SHC(0x8622cf68), SHC(0xcf043ab3), SHC(0x89be50c3), + SHC(0xc5842c7e), SHC(0x8e245655), SHC(0xbc6845ce), SHC(0x934d57c9), SHC(0xb3c0200c), SHC(0x99307ee0), + SHC(0xab9a8e6c), SHC(0x9fc3b694), SHC(0xa405847e), SHC(0xa6fbbc59), SHC(0x9d0dfe54), SHC(0xaecc336c), + SHC(0x96bfea3d), SHC(0xb727b9f7), SHC(0x7fffffff), SHC(0x00000000), SHC(0x7f62368f), SHC(0xf3742ca2), + SHC(0x7d8a5f40), SHC(0xe70747c4), SHC(0x7a7d055b), SHC(0xdad7f3a2), SHC(0x7641af3d), SHC(0xcf043ab3), + SHC(0x70e2cbc6), SHC(0xc3a94590), SHC(0x6a6d98a4), SHC(0xb8e31319), SHC(0x62f201ac), SHC(0xaecc336c), + SHC(0x5a82799a), SHC(0xa57d8666), SHC(0x5133cc94), SHC(0x9d0dfe54), SHC(0x471cece7), SHC(0x9592675c), + SHC(0x3c56ba70), SHC(0x8f1d343a), SHC(0x30fbc54d), SHC(0x89be50c3), SHC(0x25280c5e), SHC(0x8582faa5), + SHC(0x18f8b83c), SHC(0x8275a0c0), SHC(0x0c8bd35e), SHC(0x809dc971), SHC(0x00000000), SHC(0x80000000), + SHC(0xf3742ca2), SHC(0x809dc971), SHC(0xe70747c4), SHC(0x8275a0c0), SHC(0xdad7f3a2), SHC(0x8582faa5), + SHC(0xcf043ab3), SHC(0x89be50c3), SHC(0xc3a94590), SHC(0x8f1d343a), SHC(0xb8e31319), SHC(0x9592675c), + SHC(0xaecc336c), SHC(0x9d0dfe54), SHC(0xa57d8666), SHC(0xa57d8666), SHC(0x9d0dfe54), SHC(0xaecc336c), + SHC(0x9592675c), SHC(0xb8e31319), SHC(0x8f1d343a), SHC(0xc3a94590), SHC(0x89be50c3), SHC(0xcf043ab3), + SHC(0x8582faa5), SHC(0xdad7f3a2), SHC(0x8275a0c0), SHC(0xe70747c4), SHC(0x809dc971), SHC(0xf3742ca2), + SHC(0x7fffffff), SHC(0x00000000), SHC(0x7f294bfd), SHC(0xf15f0b74), SHC(0x7ca80038), SHC(0xe2ef2a3e), + SHC(0x78848414), SHC(0xd4e0cb15), SHC(0x72ccb9db), SHC(0xc763158e), SHC(0x6b93d02e), SHC(0xbaa34bf4), + SHC(0x62f201ac), SHC(0xaecc336c), SHC(0x590443a7), SHC(0xa405847e), SHC(0x4debe4fe), SHC(0x9a7365d3), + SHC(0x41ce1e65), SHC(0x9235f2ec), SHC(0x34d3957e), SHC(0x8b68d06e), SHC(0x2727d486), SHC(0x8622cf68), + SHC(0x18f8b83c), SHC(0x8275a0c0), SHC(0x0a75d60e), SHC(0x806d99e3), SHC(0xfbcfdc71), SHC(0x80118b5e), + SHC(0xed37ef91), SHC(0x8162aa04), SHC(0xdedf047d), SHC(0x845c8ae3), SHC(0xd0f53ce0), SHC(0x88f53214), + SHC(0xc3a94590), SHC(0x8f1d343a), SHC(0xb727b9f7), SHC(0x96bfea3d), SHC(0xab9a8e6c), SHC(0x9fc3b694), + SHC(0xa1288376), SHC(0xaa0a5b2e), SHC(0x97f4a3cd), SHC(0xb5715eef), SHC(0x901dcec4), SHC(0xc1d2814f), + SHC(0x89be50c3), SHC(0xcf043ab3), SHC(0x84eb8b03), SHC(0xdcda47b9), SHC(0x81b5abda), SHC(0xeb263dbb), + SHC(0x80277872), SHC(0xf9b82684), SHC(0x804628a7), SHC(0x085f2137), SHC(0x82115586), SHC(0x16ea0646), + SHC(0x8582faa5), SHC(0x25280c5e), SHC(0x8a8f8a54), SHC(0x32e96c09), SHC(0x7fffffff), SHC(0x00000000), + SHC(0x7ee7aa4c), SHC(0xef4aeaf1), SHC(0x7ba3751d), SHC(0xdedf047d), SHC(0x7641af3d), SHC(0xcf043ab3), + SHC(0x6ed9eba1), SHC(0xc0000000), SHC(0x658c9a2d), SHC(0xb2141b02), SHC(0x5a82799a), SHC(0xa57d8666), + SHC(0x4debe4fe), SHC(0x9a7365d3), SHC(0x40000000), SHC(0x9126145f), SHC(0x30fbc54d), SHC(0x89be50c3), + SHC(0x2120fb83), SHC(0x845c8ae3), SHC(0x10b5150f), SHC(0x811855b4), SHC(0x00000000), SHC(0x80000000), + SHC(0xef4aeaf1), SHC(0x811855b4), SHC(0xdedf047d), SHC(0x845c8ae3), SHC(0xcf043ab3), SHC(0x89be50c3), + SHC(0xc0000000), SHC(0x9126145f), SHC(0xb2141b02), SHC(0x9a7365d3), SHC(0xa57d8666), SHC(0xa57d8666), + SHC(0x9a7365d3), SHC(0xb2141b02), SHC(0x9126145f), SHC(0xc0000000), SHC(0x89be50c3), SHC(0xcf043ab3), + SHC(0x845c8ae3), SHC(0xdedf047d), SHC(0x811855b4), SHC(0xef4aeaf1), SHC(0x80000000), SHC(0x00000000), + SHC(0x811855b4), SHC(0x10b5150f), SHC(0x845c8ae3), SHC(0x2120fb83), SHC(0x89be50c3), SHC(0x30fbc54d), + SHC(0x9126145f), SHC(0x40000000), SHC(0x9a7365d3), SHC(0x4debe4fe), SHC(0xa57d8666), SHC(0x5a82799a), + SHC(0xb2141b02), SHC(0x658c9a2d), SHC(0x7fffffff), SHC(0x00000000), SHC(0x7e9d55fc), SHC(0xed37ef91), + SHC(0x7a7d055b), SHC(0xdad7f3a2), SHC(0x73b5ebd1), SHC(0xc945dfec), SHC(0x6a6d98a4), SHC(0xb8e31319), + SHC(0x5ed77c8a), SHC(0xaa0a5b2e), SHC(0x5133cc94), SHC(0x9d0dfe54), SHC(0x41ce1e65), SHC(0x9235f2ec), + SHC(0x30fbc54d), SHC(0x89be50c3), SHC(0x1f19f97b), SHC(0x83d60412), SHC(0x0c8bd35e), SHC(0x809dc971), + SHC(0xf9b82684), SHC(0x80277872), SHC(0xe70747c4), SHC(0x8275a0c0), SHC(0xd4e0cb15), SHC(0x877b7bec), + SHC(0xc3a94590), SHC(0x8f1d343a), SHC(0xb3c0200c), SHC(0x99307ee0), SHC(0xa57d8666), SHC(0xa57d8666), + SHC(0x99307ee0), SHC(0xb3c0200c), SHC(0x8f1d343a), SHC(0xc3a94590), SHC(0x877b7bec), SHC(0xd4e0cb15), + SHC(0x8275a0c0), SHC(0xe70747c4), SHC(0x80277872), SHC(0xf9b82684), SHC(0x809dc971), SHC(0x0c8bd35e), + SHC(0x83d60412), SHC(0x1f19f97b), SHC(0x89be50c3), SHC(0x30fbc54d), SHC(0x9235f2ec), SHC(0x41ce1e65), + SHC(0x9d0dfe54), SHC(0x5133cc94), SHC(0xaa0a5b2e), SHC(0x5ed77c8a), SHC(0xb8e31319), SHC(0x6a6d98a4), + SHC(0xc945dfec), SHC(0x73b5ebd1), SHC(0xdad7f3a2), SHC(0x7a7d055b), SHC(0xed37ef91), SHC(0x7e9d55fc), + SHC(0x7fffffff), SHC(0x00000000), SHC(0x7e4a5426), SHC(0xeb263dbb), SHC(0x793501a9), SHC(0xd6db1254), + SHC(0x70e2cbc6), SHC(0xc3a94590), SHC(0x658c9a2d), SHC(0xb2141b02), SHC(0x577ff3da), SHC(0xa293d067), + SHC(0x471cece7), SHC(0x9592675c), SHC(0x34d3957e), SHC(0x8b68d06e), SHC(0x2120fb83), SHC(0x845c8ae3), + SHC(0x0c8bd35e), SHC(0x809dc971), SHC(0xf7a0dec9), SHC(0x804628a7), SHC(0xe2ef2a3e), SHC(0x8357ffc8), + SHC(0xcf043ab3), SHC(0x89be50c3), SHC(0xbc6845ce), SHC(0x934d57c9), SHC(0xab9a8e6c), SHC(0x9fc3b694), + SHC(0x9d0dfe54), SHC(0xaecc336c), SHC(0x9126145f), SHC(0xc0000000), SHC(0x88343c0e), SHC(0xd2e9786e), + SHC(0x8275a0c0), SHC(0xe70747c4), SHC(0x80118b5e), SHC(0xfbcfdc71), SHC(0x811855b4), SHC(0x10b5150f), + SHC(0x8582faa5), SHC(0x25280c5e), SHC(0x8d334625), SHC(0x389cea72), SHC(0x97f4a3cd), SHC(0x4a8ea111), + SHC(0xa57d8666), SHC(0x5a82799a), SHC(0xb5715eef), SHC(0x680b5c33), SHC(0xc763158e), SHC(0x72ccb9db), + SHC(0xdad7f3a2), SHC(0x7a7d055b), SHC(0xef4aeaf1), SHC(0x7ee7aa4c), SHC(0x0430238f), SHC(0x7fee74a2), + SHC(0x18f8b83c), SHC(0x7d8a5f40), SHC(0x2d168792), SHC(0x77cbc3f2), SHC(0x7fffffff), SHC(0x00000000), + SHC(0x7deeaa7a), SHC(0xe915f9ba), SHC(0x77cbc3f2), SHC(0xd2e9786e), SHC(0x6dca0d14), SHC(0xbe31e19b), + SHC(0x603c496c), SHC(0xab9a8e6c), SHC(0x4f9292dc), SHC(0x9bbd4282), SHC(0x3c56ba70), SHC(0x8f1d343a), + SHC(0x2727d486), SHC(0x8622cf68), SHC(0x10b5150f), SHC(0x811855b4), SHC(0xf9b82684), SHC(0x80277872), + SHC(0xe2ef2a3e), SHC(0x8357ffc8), SHC(0xcd1693f7), SHC(0x8a8f8a54), SHC(0xb8e31319), SHC(0x9592675c), + SHC(0xa6fbbc59), SHC(0xa405847e), SHC(0x97f4a3cd), SHC(0xb5715eef), SHC(0x8c4a142f), SHC(0xc945dfec), + SHC(0x845c8ae3), SHC(0xdedf047d), SHC(0x806d99e3), SHC(0xf58a29f2), SHC(0x809dc971), SHC(0x0c8bd35e), + SHC(0x84eb8b03), SHC(0x2325b847), SHC(0x8d334625), SHC(0x389cea72), SHC(0x99307ee0), SHC(0x4c3fdff4), + SHC(0xa8800c26), SHC(0x5d6c2f99), SHC(0xbaa34bf4), SHC(0x6b93d02e), SHC(0xcf043ab3), SHC(0x7641af3d), + SHC(0xe4fa4bf1), SHC(0x7d1d7958), SHC(0xfbcfdc71), SHC(0x7fee74a2), SHC(0x12c8106f), SHC(0x7e9d55fc), + SHC(0x2924edac), SHC(0x793501a9), SHC(0x3e2d7eb1), SHC(0x6fe2313c), SHC(0x5133cc94), SHC(0x62f201ac), + SHC(0x619a7dce), SHC(0x52cf758f)}; + + +# endif /* !defined(__XTENSA__) */ + + +/* Inverse square root table for operands running from 0.5 to ~1.0 + + (Word32) (0.5 + 1.0/sqrt((op)/CDKpow(2.0,31))) + + Note: First value is not rounded for accuracy reasons + + Implicit exponent is 1 + + Example: 0x5A82799A = Isqrt(0x40000000), exponent=1 +*/ +const Word32 isqrt_table[128 + 2] = { + 0x5A827999, 0x5A287E03, 0x59CF8CBC, 0x5977A0AC, 0x5920B4DF, 0x58CAC480, 0x5875CADE, 0x5821C364, 0x57CEA99D, + 0x577C7930, 0x572B2DE0, 0x56DAC38E, 0x568B3632, 0x563C81E0, 0x55EEA2C4, 0x55A19522, 0x55555555, 0x5509DFD0, + 0x54BF311A, 0x547545D0, 0x542C1AA4, 0x53E3AC5B, 0x539BF7CD, 0x5354F9E7, 0x530EAFA5, 0x52C91618, 0x52842A5F, + 0x523FE9AC, 0x51FC5140, 0x51B95E6B, 0x51770E8F, 0x51355F1A, 0x50F44D89, 0x50B3D768, 0x5073FA50, 0x5034B3E7, + 0x4FF601E0, 0x4FB7E1FA, 0x4F7A5202, 0x4F3D4FCF, 0x4F00D944, 0x4EC4EC4F, 0x4E8986EA, 0x4E4EA718, 0x4E144AE9, + 0x4DDA7073, 0x4DA115DA, 0x4D683948, 0x4D2FD8F4, 0x4CF7F31B, 0x4CC08605, 0x4C899000, 0x4C530F65, 0x4C1D0294, + 0x4BE767F5, 0x4BB23DF9, 0x4B7D8317, 0x4B4935CF, 0x4B1554A6, 0x4AE1DE2A, 0x4AAED0F0, 0x4A7C2B93, 0x4A49ECB3, + 0x4A1812FA, 0x49E69D16, 0x49B589BB, 0x4984D7A4, 0x49548592, 0x49249249, 0x48F4FC97, 0x48C5C34B, 0x4896E53D, + 0x48686148, 0x483A364D, 0x480C6332, 0x47DEE6E1, 0x47B1C049, 0x4784EE60, 0x4758701C, 0x472C447C, 0x47006A81, + 0x46D4E130, 0x46A9A794, 0x467EBCBA, 0x46541FB4, 0x4629CF98, 0x45FFCB80, 0x45D6128A, 0x45ACA3D5, 0x45837E88, + 0x455AA1CB, 0x45320CC8, 0x4509BEB0, 0x44E1B6B4, 0x44B9F40B, 0x449275ED, 0x446B3B96, 0x44444444, 0x441D8F3B, + 0x43F71BBF, 0x43D0E917, 0x43AAF68F, 0x43854374, 0x435FCF15, 0x433A98C6, 0x43159FDC, 0x42F0E3AE, 0x42CC6398, + 0x42A81EF6, 0x42841527, 0x4260458E, 0x423CAF8D, 0x4219528B, 0x41F62DF2, 0x41D3412A, 0x41B08BA2, 0x418E0CC8, + 0x416BC40D, 0x4149B0E5, 0x4127D2C3, 0x41062920, 0x40E4B374, 0x40C3713B, 0x40A261EF, 0x40818512, 0x4060DA22, + 0x404060A1, 0x40201814, 0x40000000, 0x3FE017EC, +}; + +const Word32 Log2_16_table1[16] = { + 0, 2934766, 5701737, 8319067, 10802114, 13163988, 15415967, 17567824, + 19628084, 21604229, 23502857, 25329821, 27090336, 28789065, 30430199, 32017515, +}; + +const Word16 Log2_16_table2[16] = { + 1433, 1351, 1278, 1212, 1153, 1099, 1051, 1006, 965, 927, 892, 860, 829, 801, 775, 750, +}; + +const Word32 InvLog2_16_table1[64] = { + 1073741824, 1085434106, 1097253708, 1109202018, 1121280436, 1133490379, 1145833280, 1158310587, + 1170923762, 1183674286, 1196563654, 1209593378, 1222764986, 1236080024, 1249540052, 1263146652, + 1276901417, 1290805962, 1304861917, 1319070932, 1333434672, 1347954824, 1362633090, 1377471191, + 1392470869, 1407633882, 1422962010, 1438457051, 1454120821, 1469955159, 1485961921, 1502142985, + 1518500250, 1535035634, 1551751076, 1568648537, 1585730000, 1602997467, 1620452965, 1638098541, + 1655936265, 1673968228, 1692196547, 1710623359, 1729250827, 1748081133, 1767116489, 1786359126, + 1805811301, 1825475297, 1845353420, 1865448001, 1885761398, 1906295993, 1927054196, 1948038440, + 1969251188, 1990694927, 2012372174, 2034285470, 2056437387, 2078830522, 2101467502, 2124350982, +}; + +const Word16 InvLog2_16_table2[64] = { + 11418, 11543, 11668, 11795, 11924, 12054, 12185, 12318, 12452, 12587, 12724, 12863, 13003, 13145, 13288, 13432, + 13579, 13727, 13876, 14027, 14180, 14334, 14490, 14648, 14808, 14969, 15132, 15297, 15463, 15632, 15802, 15974, + 16148, 16324, 16501, 16681, 16863, 17046, 17232, 17420, 17609, 17801, 17995, 18191, 18389, 18589, 18792, 18996, + 19203, 19412, 19624, 19837, 20053, 20272, 20492, 20716, 20941, 21169, 21400, 21633, 21868, 22106, 22347, 22590, +}; + +const UWord8 gf16_mult_table[256] = { + /* gf16_mult_table[a | (b << 4)] contains the product of a and b in GF(16) */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, + 13, 14, 15, 0, 2, 4, 6, 8, 10, 12, 14, 3, 1, 7, 5, 11, 9, 15, 13, 0, 3, 6, 5, 12, 15, 10, 9, 11, 8, + 13, 14, 7, 4, 1, 2, 0, 4, 8, 12, 3, 7, 11, 15, 6, 2, 14, 10, 5, 1, 13, 9, 0, 5, 10, 15, 7, 2, 13, + 8, 14, 11, 4, 1, 9, 12, 3, 6, 0, 6, 12, 10, 11, 13, 7, 1, 5, 3, 9, 15, 14, 8, 2, 4, 0, 7, 14, 9, + 15, 8, 1, 6, 13, 10, 3, 4, 2, 5, 12, 11, 0, 8, 3, 11, 6, 14, 5, 13, 12, 4, 15, 7, 10, 2, 9, 1, 0, + 9, 1, 8, 2, 11, 3, 10, 4, 13, 5, 12, 6, 15, 7, 14, 0, 10, 7, 13, 14, 4, 9, 3, 15, 5, 8, 2, 1, 11, + 6, 12, 0, 11, 5, 14, 10, 1, 15, 4, 7, 12, 2, 9, 13, 6, 8, 3, 0, 12, 11, 7, 5, 9, 14, 2, 10, 6, 1, + 13, 15, 3, 4, 8, 0, 13, 9, 4, 1, 12, 8, 5, 2, 15, 11, 6, 3, 14, 10, 7, 0, 14, 15, 1, 13, 3, 2, 12, + 9, 7, 6, 8, 4, 10, 11, 5, 0, 15, 13, 2, 9, 6, 4, 11, 1, 14, 12, 3, 8, 7, 5, 10, +}; + +const UWord8 rs16_elp_deg2_table[256] = { + /* If the polynomial x^2 + ax + b has distinct non-zero roots z1 and z2 in GF(16), * + * then table entry a + 16*b contains log_g(z1) | log_g(z2) << 4, and otherwise it * + * contains 0. */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 165, 0, 0, 0, 0, + 105, 195, 0, 210, 0, 225, 0, 180, 120, 0, 0, 121, 0, 16, 0, 211, 0, 0, 181, 0, 0, 106, + 196, 226, 0, 0, 0, 214, 64, 0, 199, 0, 0, 0, 0, 0, 49, 184, 0, 154, 0, 229, 0, 227, + 182, 0, 0, 32, 0, 0, 0, 197, 0, 0, 122, 0, 212, 152, 0, 203, 0, 158, 128, 0, 0, 0, + 98, 113, 218, 0, 0, 0, 53, 0, 0, 65, 0, 0, 185, 110, 215, 80, 0, 0, 200, 0, 50, 0, + 0, 0, 0, 130, 205, 115, 0, 0, 160, 190, 145, 0, 0, 0, 0, 0, 0, 100, 0, 0, 168, 198, + 0, 183, 33, 0, 0, 48, 228, 213, 0, 0, 0, 0, 0, 0, 0, 0, 164, 0, 179, 0, 224, 104, + 0, 194, 149, 0, 0, 209, 0, 0, 0, 189, 99, 84, 0, 129, 0, 0, 0, 144, 0, 0, 234, 114, + 0, 0, 82, 0, 0, 0, 0, 217, 202, 0, 112, 52, 232, 0, 97, 0, 0, 0, 126, 0, 81, 201, + 0, 36, 216, 186, 0, 0, 0, 96, 0, 0, 0, 0, 0, 88, 0, 0, 0, 103, 0, 148, 178, 0, + 208, 193, 0, 58, 0, 0, 0, 0, 0, 161, 206, 0, 116, 0, 101, 0, 0, 56, 146, 176, 0, 0, + 147, 162, 222, 0, 132, 0, 0, 0, 0, 0, 177, 117, 192, 0, +}; + +const UWord16 rs16_elp_deg3_table[256] = { + /* If the polynomial x^3 + ax + b has distinct roots z1, z2 and z3 in GF(16), * + * then table entry a + 16*b contains z1) | z2 << 4 | z3 << 8, and otherwise it * + * contains 0. */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1889, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2977, 0, 0, 0, 0, 0, 3990, 1859, 0, + 0, 0, 0, 0, 0, 0, 3521, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1874, 0, 3718, 0, 0, 0, + 0, 0, 0, 2433, 0, 0, 1619, 0, 0, 0, 0, 3495, 0, 0, 0, 0, 0, 0, 4065, 0, 0, 0, + 0, 0, 0, 3255, 0, 0, 0, 1602, 0, 3735, 0, 0, 0, 0, 3238, 801, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 3510, 0, 0, 0, 0, 1345, 3975, 0, 0, 0, 0, 0, 0, 0, 0, 3778, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2947, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 3476, 0, 4005, 0, 3461, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 3748, 0, 0, 2962, 0, 0, 0, 0, 4035, 0, 0, 4020, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3221, 0, 0, 0, 0, 0, 0, 2690, + 0, 0, 0, 3795, 0, 0, 0, 4050, 0, 0, 0, 0, 0, 3204, 3765, 0, 0, 0, 0, 0, 2707, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +}; + +#ifdef ENABLE_HR_MODE +const Word32 invSqrtTab[(128 + 2)] = { + 0x5A827999, 0x5A287E03, 0x59CF8CBC, 0x5977A0AC, 0x5920B4DF, 0x58CAC480, 0x5875CADE, 0x5821C364, 0x57CEA99D, + 0x577C7930, 0x572B2DE0, 0x56DAC38E, 0x568B3632, 0x563C81E0, 0x55EEA2C4, 0x55A19522, 0x55555555, 0x5509DFD0, + 0x54BF311A, 0x547545D0, 0x542C1AA4, 0x53E3AC5B, 0x539BF7CD, 0x5354F9E7, 0x530EAFA5, 0x52C91618, 0x52842A5F, + 0x523FE9AC, 0x51FC5140, 0x51B95E6B, 0x51770E8F, 0x51355F1A, 0x50F44D89, 0x50B3D768, 0x5073FA50, 0x5034B3E7, + 0x4FF601E0, 0x4FB7E1FA, 0x4F7A5202, 0x4F3D4FCF, 0x4F00D944, 0x4EC4EC4F, 0x4E8986EA, 0x4E4EA718, 0x4E144AE9, + 0x4DDA7073, 0x4DA115DA, 0x4D683948, 0x4D2FD8F4, 0x4CF7F31B, 0x4CC08605, 0x4C899000, 0x4C530F65, 0x4C1D0294, + 0x4BE767F5, 0x4BB23DF9, 0x4B7D8317, 0x4B4935CF, 0x4B1554A6, 0x4AE1DE2A, 0x4AAED0F0, 0x4A7C2B93, 0x4A49ECB3, + 0x4A1812FA, 0x49E69D16, 0x49B589BB, 0x4984D7A4, 0x49548592, 0x49249249, 0x48F4FC97, 0x48C5C34B, 0x4896E53D, + 0x48686148, 0x483A364D, 0x480C6332, 0x47DEE6E1, 0x47B1C049, 0x4784EE60, 0x4758701C, 0x472C447C, 0x47006A81, + 0x46D4E130, 0x46A9A794, 0x467EBCBA, 0x46541FB4, 0x4629CF98, 0x45FFCB80, 0x45D6128A, 0x45ACA3D5, 0x45837E88, + 0x455AA1CB, 0x45320CC8, 0x4509BEB0, 0x44E1B6B4, 0x44B9F40B, 0x449275ED, 0x446B3B96, 0x44444444, 0x441D8F3B, + 0x43F71BBF, 0x43D0E917, 0x43AAF68F, 0x43854374, 0x435FCF15, 0x433A98C6, 0x43159FDC, 0x42F0E3AE, 0x42CC6398, + 0x42A81EF6, 0x42841527, 0x4260458E, 0x423CAF8D, 0x4219528B, 0x41F62DF2, 0x41D3412A, 0x41B08BA2, 0x418E0CC8, + 0x416BC40D, 0x4149B0E5, 0x4127D2C3, 0x41062920, 0x40E4B374, 0x40C3713B, 0x40A261EF, 0x40818512, 0x4060DA22, + 0x404060A1, 0x40201814, 0x40000000, 0x3FE017EC /* , 0x3FC05F61 */ +}; +#endif diff --git a/lib_lc3plus/rom_basop_util_lc3plus.h b/lib_lc3plus/rom_basop_util_lc3plus.h new file mode 100644 index 0000000000000000000000000000000000000000..11d90c77b21d7751eab95543c1dcfc562ce934c5 --- /dev/null +++ b/lib_lc3plus/rom_basop_util_lc3plus.h @@ -0,0 +1,172 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.5 * +* Low Complexity Communication Codec Plus (LC3plus) * +* * +* Copyright licence is solely granted through ETSI Intellectual Property * +* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * +* estoppel or otherwise. * +******************************************************************************/ + +#ifndef __ROM_BASOP_UTIL_LC3PLUS_H__ +#define __ROM_BASOP_UTIL_LC3PLUS_H__ + +#include "basop_util_lc3plus.h" +#include "functions.h" + +#define LD_INT_TAB_LEN 120 +#define INV_TABLE_SIZE 256 +#define SQRT_TABLE_SIZE 256 + +#ifndef CHEAP_NORM_SIZE +#define CHEAP_NORM_SIZE 161 +#endif + +#define MINSFTAB 7 +#define MAXSFTAB 25 + +#ifdef ENABLE_HR_MODE +#define SHC(x) ((Word32)x) +#else +#define SHC(x) WORD322WORD16((Word32)x) +#endif + +/** + * \brief Lookup-Table for binary logarithm + */ +extern const Word16 ldCoeff_lc3plus[7]; + +/** + \brief Lookup-Table for binary power algorithm +*/ +extern const UWord32 exp2_tab_long_lc3plus[32]; + +/** + \brief Lookup-Table for binary power algorithm +*/ +extern const UWord32 exp2w_tab_long_lc3plus[32]; + +/** + \brief Lookup-Table for binary power algorithm +*/ +extern const UWord32 exp2x_tab_long_lc3plus[32]; + +/** + * \brief 1/x, x=[0,1,2,3...] table + */ +#ifdef ENABLE_HR_MODE +extern const Word16 InvIntTable[74]; +#else +extern const Word16 InvIntTable[32]; +#endif + +/** + * \ brief Lookup for sine tables and windows. + */ +void BASOP_getTables( +#ifdef ENABLE_HR_MODE + const PWord32 **ptwiddle, + const PWord32 **sin_twiddle, +#else + const PWord16 **ptwiddle, + const PWord16 **sin_twiddle, +#endif + Word16 *sin_step, + Word16 length); + +extern const Word32 RealFFT20_twid[6]; +extern const Word32 RealFFT32_twid[10]; +extern const Word32 RealFFT40_twid[12]; +extern const Word32 RealFFT60_twid[17]; +extern const Word32 RealFFT64_twid[18]; +extern const Word32 RealFFT80_twid[22]; +extern const Word32 RealFFT96_twid[26]; +extern const Word32 RealFFT128_twid[34]; +extern const Word32 RealFFT192_twid[50]; +extern const Word32 RealFFT256_twid[66]; +extern const Word32 RealFFT384_twid[98]; +extern const Word32 RealFFT512_twid[130]; +extern const Word32 RealFFT768_twid[194]; + +#ifdef ENABLE_HR_MODE +extern const PWord32 SineTable480[241]; +extern const PWord32 SineTable320[161]; +extern const PWord32 SineTable960[481]; +#else +extern const PWord16 SineTable480[241]; +extern const PWord16 SineTable320[161]; +extern const PWord16 SineTable960[481]; +#endif + +#ifdef ENABLE_HR_MODE +extern const Word32 RotVector_15_6[2 * (90 - 15)]; +#else +extern const Word16 RotVector_15_6[2 * (90 - 15)]; +#endif + +extern const Word32 RotVector_32_32[2 * 20]; +extern const Word32 RotVector_40_32[2 * 28]; + +#ifdef ENABLE_HR_MODE +extern const Word32 RotVector_320[2 * (320 - 20)]; +#else +extern const Word16 RotVector_320[2 * (320 - 20)]; +#endif + +#ifdef ENABLE_HR_MODE +extern const Word32 RotVector_360[2 * (360 - 30)]; +#else +extern const Word16 RotVector_360[2 * (360 - 30)]; +#endif + +#ifdef ENABLE_HR_MODE +extern const Word32 RotVector_480[2 * (480 - 30)]; +#else +extern const Word16 RotVector_480[2 * (480 - 30)]; +#endif + +#ifdef ENABLE_HR_MODE +#ifdef CR8_G_ADD_75MS +extern const Word32 RotVector_720[2 * (720 - 30)]; +#endif +extern const Word32 RotVector_960[2 * (480 - 60)]; +#else +extern const Word16 RotVector_960[2 * (480 - 60)]; +#endif + +#ifdef ENABLE_HR_MODE +extern const Word32 RotVector_30_16[2 * (480 - 30)]; +#endif + +#ifdef ENABLE_HR_MODE +extern const Word32 RotVector_32_8[2 * (256 - 32)]; +#else +extern const Word16 RotVector_32_8[2 * (256 - 32)]; +#endif + +#if defined(SUBSET_SSWB) || defined(SUBSET_SWB) || defined(SUBSET_FB) +#ifdef ENABLE_HR_MODE +extern const Word32 RotVector_32_12[2 * (384 - 32)]; +#else +extern const Word16 RotVector_32_12[2 * (384 - 32)]; +#endif +#else +#define RotVector_32_12 NULL +#endif + +extern const Word32 isqrt_table[128 + 2]; + +extern const Word32 Log2_16_table1[16]; +extern const Word16 Log2_16_table2[16]; + +extern const Word32 InvLog2_16_table1[64]; +extern const Word16 InvLog2_16_table2[64]; + +extern const UWord8 gf16_mult_table[256]; +extern const UWord8 rs16_elp_deg2_table[256]; +extern const UWord16 rs16_elp_deg3_table[256]; + +#ifdef ENABLE_HR_MODE +extern const Word32 invSqrtTab[(128 + 2)]; +#endif + +#endif diff --git a/lib_lc3plus/scale_signal24_fx.c b/lib_lc3plus/scale_signal24_fx.c new file mode 100644 index 0000000000000000000000000000000000000000..548788d2a020f96bc64b48ff5ec6833edfa1e4f0 --- /dev/null +++ b/lib_lc3plus/scale_signal24_fx.c @@ -0,0 +1,121 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.5 * +* 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 "functions.h" + +void scale_signal24_fx(Word32 x[], /* i: time input signal */ +#ifdef ENABLE_HR_MODE + Word32 x_scaled[], +#else + Word16 x_scaled[], +#endif + Word16 *x_exp, +#ifdef ENABLE_HR_MODE + Word32 mdct_mem[], +#else + Word16 mdct_mem[], +#endif + Word16 mdct_mem_len, + Word16 resample_mem_in[], Word16 resample_mem_in_len, Word32 resample_mem_in50[], + Word16 resample_mem_out[], Word16 resample_mem_out_len, Word32 mdct_mem32[], Word16 N, + Word32 resamp_mem32[], Word16 mem_s12k8[], Word16 *resamp_scale) +{ + Word16 i; + Word16 s; + Word16 scales[6]; + +#ifdef DYNMEM_COUNT + Dyn_Mem_In("scale_signal24_fx", sizeof(struct { + Word16 i; + Word16 s; + Word16 scales[6]; + })); +#endif + + /* Scale input for 24 bit case */ + /* assure 24 bit input */ + FOR (i = 0; i < N; i++) + { + IF (x[i] >= 0) + { + x[i] = L_and(x[i], 0x007fffff); + } + ELSE + { + x[i] = (Word32)L_or( (UWord32)x[i], 0xff800000); + } + } + + /* Find maximum exponent */ + scales[0] = sub(15 + 8, getScaleFactor32_0(x, N)); + scales[1] = sub(15 + 8, getScaleFactor32_0(mdct_mem32, mdct_mem_len)); + scales[2] = sub(15 + 8, getScaleFactor32_0(resamp_mem32, resample_mem_in_len)); + scales[3] = sub(sub(*resamp_scale, 2), getScaleFactor32_0(resample_mem_in50, 2)); + scales[4] = sub(sub(*resamp_scale, 2), getScaleFactor16_0(resample_mem_out, resample_mem_out_len)); + scales[5] = sub(sub(*resamp_scale, 2), getScaleFactor16_0(mem_s12k8, 3)); + *x_exp = 7; move16(); + FOR (i = 0; i < 6; i++) + { + *x_exp = s_max(*x_exp, scales[i]); move16(); + } + + /* Shift input buffers */ + s = sub(15 + 8, *x_exp); + FOR (i = 0; i < N; i++) + { +#ifdef ENABLE_HR_MODE + x_scaled[i] = L_shl(x[i], s); +#else + x_scaled[i] = round_fx_sat(L_shl(x[i], s)); +#endif + } + + FOR (i = 0; i < mdct_mem_len; i++) + { +#ifdef ENABLE_HR_MODE + mdct_mem[i] = L_shl(mdct_mem32[i], s); +#else + mdct_mem[i] = round_fx_sat(L_shl(mdct_mem32[i], s)); +#endif + } + + FOR (i = 0; i < resample_mem_in_len; i++) + { + resample_mem_in[i] = round_fx_sat(L_shl(resamp_mem32[i], s)); + } + + /* Adjust resampler filter and output buffers */ + s = sub(sub(*resamp_scale, 2), *x_exp); + *resamp_scale = add(*x_exp, 2); + + IF (s) + { + FOR (i = 0; i < 2; i++) + { + resample_mem_in50[i] = L_shl(resample_mem_in50[i], s); + } + FOR (i = 0; i < resample_mem_out_len; i++) + { + resample_mem_out[i] = shl(resample_mem_out[i], s); + } + + FOR (i = 0; i < 3; i++) + { + mem_s12k8[i] = shl(mem_s12k8[i], s); + } + } + /* Store part of current frame as mdct memory buffer and resampler input buffer for next frame */ + basop_memcpy(mdct_mem32, &x[N - mdct_mem_len], mdct_mem_len * sizeof(Word32)); + basop_memmove(resamp_mem32, &x[N - resample_mem_in_len], resample_mem_in_len * sizeof(Word32)); + +#ifdef DYNMEM_COUNT + Dyn_Mem_Out(); +#endif +} + diff --git a/lib_lc3plus/setup_dec_lc3.c b/lib_lc3plus/setup_dec_lc3.c new file mode 100644 index 0000000000000000000000000000000000000000..1d2849f565386fa7cb61b400f15c7bc1d0234c4c --- /dev/null +++ b/lib_lc3plus/setup_dec_lc3.c @@ -0,0 +1,539 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.5 * +* 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 "functions.h" +#include "setup_dec_lc3.h" + +/* if decoder is null only size is reported */ +/*assume 10ms for memory allocation for now */ +int alloc_decoder(LC3PLUS_Dec *decoder, int samplerate, int channels) +{ + int ch = 0; + size_t size = sizeof(LC3PLUS_Dec); + void * ltpf_mem_x = NULL, *ltpf_mem_y = NULL, *stDec_ola_mem_fx = NULL; + int max_len = DYN_MAX_LEN_EXT(samplerate); /*NB sing 80 as minimum value changes BE for NB */ +#ifdef CR8_A_PLC_FADEOUT_TUNING + Word32 * plc_longterm_advc_tdc = NULL, *plc_longterm_advc_ns = NULL; + Word16 longterm_analysis_counter_max = 0, longterm_analysis_counter_max_bytebuffer = 0; +#endif + + void *q_old_res_fx = NULL; + Word16 *sharedBuf = NULL; +#if defined(ENABLE_PC) + void *q_old_d_fx = NULL; +#endif + void *plcAd = NULL, *PhECU_f0est = NULL, *PhECU_plocs = NULL; + + for (ch = 0; ch < channels; ch++) + { + DecSetup *setup = balloc(decoder, &size, sizeof(DecSetup)); +#ifdef ENABLE_HR_MODE + int q_old_len = MIN(CODEC_FS(samplerate) * 100 / 10000, MAX_BW_HR); +#else + int q_old_len = MIN(CODEC_FS(samplerate) * 100 / 10000, MAX_BW ); +#endif + int x_old_len = DYN_MAX_LEN_PCM_PLC(samplerate); /* max(pitchmax + frame ms, M+1 + pitchmax + frame/2) */ + int fs_idx = (samplerate / 10000); /* floor= integer truncation is needed here */ + + ltpf_mem_x = balloc(decoder, &size, sizeof(*setup->ltpf_mem_x) * (max_len + max_len / 40 - 2)); + ltpf_mem_y = + balloc(decoder, &size, + sizeof(*setup->ltpf_mem_y) * (max_len + CEILING(MAX_PITCH_12K8 * max_len, 128) + (max_len / 80))); + + stDec_ola_mem_fx = balloc(decoder, &size, sizeof(*setup->stDec_ola_mem_fx) * DYN_MAX_MDCT_LEN(samplerate)); + +#if defined(ENABLE_PC) + q_old_d_fx = balloc(decoder, &size, sizeof(*setup->q_old_d_fx) * q_old_len); +#endif + sharedBuf = balloc(decoder, &size, sizeof(*setup->q_old_d_fx) * q_old_len + sizeof(*setup->plcAd->x_old_tot_fx) * x_old_len); + + /* To save static RAM, a large buffer sharedBuf is used to share + * space for q_old_d_fx, x_old_tot_fx and X_sav_fx (note: + * PHASE_ECU operates only at 10ms and standard precision) + * + * If partial Concealment is active, q_old_d_fx is saved in a separate buffer + * + * The following graph provides an overview about the memory + * sharing for 10ms and normal resolution: + */ + + /* Total buffer | <--- sharedBuf ---> | */ + /* ConcealMethod 3or4 | <---q_old_d_fx---> | <-------------------- x_old_tot_fx ------------------> | */ + /* ConcealMethod 3 | <---q_old_d_fx---> | |<------- M+1+pitch_max+ (frame_len/2)----------> | */ /* first BFI-frame only? */ + /* Meth 2,prevBfi=0 | | <------- 16 ms xfp ------->| */ + /* Meth 2 | ^ X_sav_fx ptr | <-------- maintained old_tot_fx ---------> | */ /* pitchmax samples maintained */ + /* Meth 2 | <----- X_sav 16 ms ----------> | ^xfp_fx ptr | */ + /* Meth2 ,prevBfi=1 | | <-12.25(forTDC),3.75(PLC2)->| */ /*the part used by PhECU is 3.75ms */ + /* ConcealMethod 2 |<- <10ms ->| */ + int max_plocs = DYN_MAX_PLOCS(samplerate); + plcAd = balloc(decoder, &size, sizeof(*setup->plcAd)); + PhECU_f0est = balloc(decoder, &size, sizeof(*setup->plcAd->PhECU_f0est) * max_plocs); + PhECU_plocs = balloc(decoder, &size, sizeof(*setup->plcAd->PhECU_plocs) * max_plocs); +#ifdef ENABLE_HR_MODE + q_old_res_fx = balloc(decoder, &size, sizeof(*setup->q_old_res_fx) * max_len); +#else + q_old_res_fx = balloc(decoder, &size, sizeof(*setup->q_old_res_fx) * MIN(max_len, MAX_BW)); +#endif + +#ifdef CR8_A_PLC_FADEOUT_TUNING +/* longterm_analysis_counter_max = PLC_LONGTERM_ANALYSIS_MS * (100.0f / 25.0f);*/ +/* assert(longterm_analysis_counter_max == (PLC_LONGTERM_ANALYSIS_MS * (100 /25))); */ /* test integer division for compatibility */ +/* longterm_analysis_counter_max_bytebuffer = floor(longterm_analysis_counter_max / 30.0); */ +/* assert(longterm_analysis_counter_max_bytebuffer == (longterm_analysis_counter_max / 30)); */ /* test integer division for compatibility */ + +/* longterm_analysis_counter_max = (longterm_analysis_counter_max_bytebuffer+1) * 30; */ + + 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(Word32) * longterm_analysis_counter_max_bytebuffer); + plc_longterm_advc_ns = balloc(decoder, &size, sizeof(Word32) * longterm_analysis_counter_max_bytebuffer); +#endif + + if (decoder) + { + decoder->channel_setup[ch] = setup; + setup->ltpf_mem_x = ltpf_mem_x; + setup->ltpf_mem_y = ltpf_mem_y; + setup->stDec_ola_mem_fx = stDec_ola_mem_fx; + setup->q_old_res_fx = q_old_res_fx; +#if defined(ENABLE_PC) + setup->q_old_d_fx = q_old_d_fx; +#else + setup->q_old_d_fx = sharedBuf; +#endif + setup->plcAd = plcAd; + } + if (decoder && plcAd) + { +#ifdef ENABLE_HR_MODE + if (fs_idx > 4) + { + fs_idx = 4; + } +#endif + + setup->plcAd->x_old_tot_fx = &sharedBuf[q_old_len]; + setup->plcAd->PhECU_f0est = PhECU_f0est; + setup->plcAd->PhECU_xfp_fx = &(setup->plcAd->x_old_tot_fx[x_old_len-LprotSzPtr[fs_idx]]); /* point to the last 16ms of the x_old_tot_fx */ + setup->plcAd->PhECU_X_sav_fx = sharedBuf; /* reuse of lprot(=num_FsByResQ0[fs_idx]) values from this point fwd, i.e beyond the end of q_old_fx */ + setup->plcAd->PhECU_plocs = PhECU_plocs; + +#ifdef CR8_A_PLC_FADEOUT_TUNING + setup->plcAd->longterm_analysis_counter_max = longterm_analysis_counter_max; + setup->plcAd->longterm_analysis_counter_max_bytebuffer = longterm_analysis_counter_max_bytebuffer; + + setup->plcAd->plc_longterm_advc_tdc = plc_longterm_advc_tdc; + setup->plcAd->plc_longterm_advc_ns = plc_longterm_advc_ns; +#endif + } + } + + return (int)size; +} + +LC3PLUS_Error FillDecSetup(LC3PLUS_Dec *decoder, int samplerate, int channels, LC3PLUS_PlcMode plc_mode +#ifdef ENABLE_HR_MODE + , int hrmode +#endif + ) +{ + int ch = 0; + + memset(decoder, 0, lc3plus_dec_get_size(samplerate, channels, plc_mode)); + alloc_decoder(decoder, samplerate, channels); + +#ifdef ENABLE_HR_MODE + decoder->hrmode = hrmode != 0; +#endif + + decoder->fs = CODEC_FS(samplerate); + decoder->fs_out = samplerate; + decoder->fs_idx = FS2FS_IDX(decoder->fs); + decoder->channels = channels; + decoder->frame_dms = 100; + decoder->plcMeth = plc_mode; + { + decoder->BW_cutoff_bits = BW_cutoff_bits_all[decoder->fs_idx]; + } + decoder->ltpf_mem_x_len = extract_l(L_shr_pos(Mpy_32_16_lc3plus(L_max(16000, decoder->fs), 16778), 11)) - 2; + decoder->ltpf_mem_y_len = extract_l(L_shr_pos(Mpy_32_16_lc3plus(decoder->fs, 18678) - 1, 5)) + 1 + + extract_l(L_shr_pos(Mpy_32_16_lc3plus(L_max(16000, decoder->fs), 16778), 12)); + + set_dec_frame_params(decoder); + + for (ch = 0; ch < decoder->channels; ch++) + { + DecSetup *setup = decoder->channel_setup[ch]; + setup->plc_damping = 32767; + setup->ltpf_mem_scale_fac_idx = -1; + move16(); + + setup->pc_seed = 24607; + setup->ns_seed = 24607; + setup->ns_cum_alpha = 32767; + + int i = 0; + /* 0 = 0kHz 1= 8kHz, 2= 16 kHz 3= 24 , 4 = 32 5=40 6=48kHz */ +#if (PHECU_XFP_LA == 0) + Word16 oneMsTab_LA[5] = {0, 0, 0, 0, 0}; +#else +# if (PHECU_XFP_LA == 4) + Word16 oneMsTab_LA[7] = {0 /*unused*/, 2, 4, 6, 8, 10 /*unused*/, 12}; +# else + Word16 oneMsTab_LA[7] = {0 /*unused*/, 8, 16, 24, 32, 40 /*unused*/, 48}; +# endif +#endif + Word16 oneMsTab[5] = {8, 16, 24, 32, 48}; + + setup->plcAd->stab_fac = 32767; + setup->plcAd->tdc_seed = 24607; + setup->plcAd->tdc_preemph_fac = plc_preemph_fac[decoder->fs_idx]; + setup->plcAd->tdc_lpc_order = 16; + setup->plcAd->PhECU_fs_idx_fx = + mult(decoder->frame_length, + (Word16)(32768.0 / 99.0)); /* truncation needed , i.e no rounding can be applied here */ + /* idx=frame/80, 0=8kHZ, 1=16kHz, 2=24 kHz, 3=32 kHz 5=*, 4=48 */ + + setup->plcAd->max_len_pcm_plc = DYN_MAX_LEN_PCM_PLC(decoder->fs); + + if ((decoder->hrmode == 0) && (samplerate <= 48000)) + { + setup->plcAd->PhECU_frame_ms = (Word16)( + decoder->frame_dms * 0.1); /* needed in PLCUpdate and PLC main functions, adjusted in first frame */ + setup->plcAd->PhECU_seed_fx = 21845; + setup->plcAd->PhECU_LprotOrg_fx = + shl_pos(oneMsTab[setup->plcAd->PhECU_fs_idx_fx], 4); /* 16 *1ms = 1.6 *framelength */ + setup->plcAd->PhECU_Lprot_fx = setup->plcAd->PhECU_LprotOrg_fx; + setup->plcAd->PhECU_LA = oneMsTab_LA[setup->plcAd->PhECU_fs_idx_fx]; + setup->plcAd->PhECU_whr_tot_taper = sub(setup->plcAd->PhECU_Lprot_fx, decoder->frame_length); /* 3+3 ms */ + setup->plcAd->PhECU_whr_tot_flat = decoder->frame_length; /* 10 ms */ + setup->plcAd->PhECU_LDWIN_OLAP = shr_pos(decoder->frame_length, 2); /* 2.5 ms */ + setup->plcAd->max_lprot = DYN_MAX_LPROT(decoder->fs); + setup->plcAd->max_plocs = DYN_MAX_PLOCS(decoder->fs); + setup->plcAd->PhECU_margin_xfp = 0; + setup->plcAd->PhECU_L_oold_xfp_w_E_fx = LTOT_MIN_MAN; + setup->plcAd->PhECU_L_old_xfp_w_E_fx = LTOT_MIN_MAN; + + setup->plcAd->PhECU_oold_xfp_w_E_exp_fx = UNINIT_OR_UNSAFE_OOLD_SENTINEL; + setup->plcAd->PhECU_old_xfp_w_E_exp_fx = LTOT_INIT_FLAG; + + setup->plcAd->PhECU_oold_Ltot_exp_fx = UNINIT_OR_UNSAFE_OOLD_SENTINEL; + setup->plcAd->PhECU_old_Ltot_exp_fx = LTOT_INIT_FLAG; + + + for (i = 0; i < MAX_LGW; i++) + { + setup->plcAd->PhECU_oold_grp_shape_fx[i] = + GRP_SHAPE_INIT; /* negative value will be replaced in very first calculation */ + setup->plcAd->PhECU_old_grp_shape_fx[i] = GRP_SHAPE_INIT; + } + /* t_adv=ctrl.FRAME/2 + ctrl.PhECU.LprotOrg/2 - ctrl.PhECU.LA + LDWIN_OLAP/2; */ + i = add(add(decoder->frame_length, setup->plcAd->PhECU_LprotOrg_fx), setup->plcAd->PhECU_LDWIN_OLAP); + setup->plcAd->PhECU_t_adv = sub(shr_pos(i, 1), setup->plcAd->PhECU_LA); + + for (i = 0; i < MAX_LGW; i++) + { + setup->plcAd->PhECU_mag_chg_1st[i] = 32767; + } + setup->plcAd->PhECU_beta_mute = 16384; +#ifdef CR8_A_PLC_FADEOUT_TUNING + setup->plcAd->PhECU_nonpure_tone_flag = -1; +#endif + } + } + + lc3plus_dec_set_ep_enabled(decoder, 0); + return LC3PLUS_OK; +} + +/* set frame config params */ +void set_dec_frame_params(LC3PLUS_Dec *decoder) +{ +# ifdef CR8_G_ADD_75MS + Word16 tmp = 0; +# endif +#ifdef CR10_A_ATTENUATION_CURVE_SELECTOR + Word16 n; +#endif + + decoder->frame_length = extract_l(L_shr_pos(Mpy_32_16_lc3plus(decoder->fs, 20972), 6)); /* fs * 0.01*2^6 */ + +#ifdef ENABLE_HR_MODE + if (decoder->hrmode) + { + decoder->BW_cutoff_bits = 0; + } +#endif + + SWITCH (decoder->frame_dms) + { + case 25: + decoder->frame_length = shr_pos(decoder->frame_length, 2); + decoder->la_zeroes = LowDelayShapes_n960_la_zeroes_2_5ms[decoder->fs_idx]; + decoder->stDec_ola_mem_fx_len = sub(decoder->frame_length, decoder->la_zeroes); + +#ifdef ENABLE_HR_MODE + if (decoder->hrmode) + { + decoder->bands_number = bands_number_2_5ms_HR[decoder->fs_idx]; + decoder->bands_offset = bands_offset_2_5ms_HR[decoder->fs_idx - 4]; + decoder->W_fx = LowDelayShapes_n960_HRA_2_5ms[decoder->fs_idx - 4]; + decoder->W_size = LowDelayShapes_n960_len_2_5ms[decoder->fs_idx]; + decoder->yLen = decoder->frame_length; + } + else +#endif + { + decoder->bands_number = bands_number_2_5ms[decoder->fs_idx]; + decoder->bands_offset = bands_offset_2_5ms[decoder->fs_idx]; + decoder->W_fx = LowDelayShapes_n960_2_5ms[decoder->fs_idx]; + decoder->W_size = LowDelayShapes_n960_len_2_5ms[decoder->fs_idx]; + decoder->yLen = s_min(MAX_BW >> 2, decoder->frame_length); + } + + if (decoder->fs_idx == 0) + { + int ch; + for (ch = 0; ch < decoder->channels; ch++) + { + DecSetup *setup = decoder->channel_setup[ch]; + if (setup->plcAd != NULL) + { + setup->plcAd->tdc_lpc_order = 8; + } + } + } + BREAK; + case 50: + decoder->frame_length = shr_pos(decoder->frame_length, 1); + decoder->la_zeroes = LowDelayShapes_n960_la_zeroes_5ms[decoder->fs_idx]; + decoder->stDec_ola_mem_fx_len = sub(decoder->frame_length, decoder->la_zeroes); + +#ifdef ENABLE_HR_MODE + if (decoder->hrmode) + { + decoder->bands_offset = bands_offset_5ms_HR[decoder->fs_idx - 4]; + decoder->W_fx = LowDelayShapes_n960_HRA_5ms[decoder->fs_idx - 4]; + decoder->W_size = LowDelayShapes_n960_len_5ms[decoder->fs_idx]; + decoder->yLen = decoder->frame_length; + decoder->bands_number = bands_number_5ms[decoder->fs_idx]; + } + else +#endif + { + decoder->bands_offset = bands_offset_5ms[decoder->fs_idx]; + decoder->W_fx = LowDelayShapes_n960_5ms[decoder->fs_idx]; + decoder->W_size = LowDelayShapes_n960_len_5ms[decoder->fs_idx]; + decoder->yLen = s_min(MAX_BW >> 1, decoder->frame_length); + decoder->bands_number = bands_number_5ms[decoder->fs_idx]; + } + BREAK; + +#ifdef CR8_G_ADD_75MS + case 75: + tmp = shr_pos(decoder->frame_length, 2); + decoder->frame_length = add(tmp, add(tmp, tmp)); + decoder->la_zeroes = LowDelayShapes_n960_la_zeroes_7_5ms[decoder->fs_idx]; + decoder->stDec_ola_mem_fx_len = sub(decoder->frame_length, decoder->la_zeroes); +# ifdef ENABLE_HR_MODE + if (decoder->hrmode) + { + decoder->bands_offset = bands_offset_7_5ms_HR[decoder->fs_idx - 4]; + decoder->W_fx = LowDelayShapes_n960_HRA_7_5ms[decoder->fs_idx - 4]; + decoder->W_size = LowDelayShapes_n960_len_7_5ms[decoder->fs_idx]; + decoder->yLen = decoder->frame_length; + decoder->bands_number = bands_number_7_5ms[decoder->fs_idx]; + } + else +# endif + { + decoder->bands_offset = bands_offset_7_5ms[decoder->fs_idx]; + decoder->W_fx = LowDelayShapes_n960_7_5ms[decoder->fs_idx]; + decoder->W_size = LowDelayShapes_n960_len_7_5ms[decoder->fs_idx]; + decoder->yLen = s_min((MAX_BW >> 2) * 3, decoder->frame_length); + decoder->bands_number = bands_number_7_5ms[decoder->fs_idx]; + } + BREAK; +# endif + + case 100: + decoder->la_zeroes = LowDelayShapes_n960_la_zeroes[decoder->fs_idx]; + decoder->stDec_ola_mem_fx_len = sub(decoder->frame_length, decoder->la_zeroes); + decoder->bands_number = 64; + +#ifdef ENABLE_HR_MODE + if (decoder->hrmode) + { + decoder->bands_offset = bands_offset_HR[decoder->fs_idx - 4]; + decoder->W_fx = LowDelayShapes_n960_HRA[decoder->fs_idx - 4]; + decoder->W_size = LowDelayShapes_n960_len[decoder->fs_idx]; + decoder->yLen = decoder->frame_length; + } + else +#endif + { + decoder->W_fx = LowDelayShapes_n960[decoder->fs_idx]; + decoder->W_size = LowDelayShapes_n960_len[decoder->fs_idx]; + decoder->bands_offset = bands_offset[decoder->fs_idx]; + decoder->yLen = s_min(MAX_BW, decoder->frame_length); + } + BREAK; + } + + { + int ch; + for (ch = 0; ch < decoder->channels; ch++) + { + DecSetup *setup = decoder->channel_setup[ch]; + if (setup->plcAd != NULL) + { /*only set if plcAd was actually allocated */ +#ifdef CR8_A_PLC_FADEOUT_TUNING + setup->plcAd->longterm_analysis_counter_max = plc_fadeout_param_maxlen[(decoder->frame_dms / 25) - 1]; + setup->plcAd->longterm_analysis_counter_max_bytebuffer = plc_fadeout_param_maxbytes[(decoder->frame_dms / 25) - 1]; + +#endif + setup->plcAd->PhECU_frame_ms = (Word16)( + decoder->frame_dms * + 0.1); /* needed in processPLCupdate_fx(), now set properly set in first frame /second time */ + } + } + } +#ifdef CR10_A_ATTENUATION_CURVE_SELECTOR + FOR (n=0; n < PLC_FADEOUT_TYPE_1_IN_MS*10/decoder->frame_dms;n++){ + decoder->alpha_type_2_table[n] = type_2_fadeout_fx(n, decoder->frame_dms); + } +#endif +} + +LC3PLUS_Error update_dec_bitrate(LC3PLUS_Dec *decoder, int ch, Word16 nBytes) +{ + int tmp = 0, totalBits = 0; + int channel_bytes = 0; + int minBytes, maxBytes; + + DecSetup *setup = decoder->channel_setup[ch]; + channel_bytes = nBytes; + +#ifdef ENABLE_HR_MODE + if (decoder->hrmode) + { + SWITCH (decoder->frame_dms) + { + case 25: + maxBytes = 210; + minBytes = MIN_NBYTES; + BREAK; + case 50: + 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; + BREAK; + default: return LC3PLUS_HRMODE_ERROR; + } + } + else +#endif + { + minBytes = MIN_NBYTES; + maxBytes = MAX_NBYTES_100; + } + + if (channel_bytes < minBytes || channel_bytes > maxBytes) + { + return LC3PLUS_NUMBYTES_ERROR; + } + + setup->targetBytes = channel_bytes; + move16(); + setup->total_bits = shl(setup->targetBytes, 3); + setup->enable_lpc_weighting = (setup->total_bits < 480); + setup->quantizedGainOff = + -(s_min(115, setup->total_bits / (10 * (decoder->fs_idx + 1))) + 105 + 5 * (decoder->fs_idx + 1)); + tmp = DEPR_i_mult(80, decoder->fs_idx); + +#ifdef ENABLE_HR_MODE + if (decoder->hrmode && decoder->fs_idx == 5) + { + setup->quantizedGainOff = MAX(setup->quantizedGainOff, -181); + } +#endif + + totalBits = setup->total_bits; + + + SWITCH (decoder->frame_dms) + { + case 25: + setup->enable_lpc_weighting = 0; + /* total_bits * 2.4 */ + totalBits = extract_l(L_shr(L_mult0(19661, setup->total_bits), 13)); + BREAK; + case 50: + setup->enable_lpc_weighting = setup->total_bits < 240; + totalBits = sub(DEPR_i_mult(setup->total_bits, 2), 160); + BREAK; +#ifdef CR8_G_ADD_75MS + case 75: + setup->enable_lpc_weighting = setup->total_bits < 360; + totalBits = L_shr(L_mult0(10923, setup->total_bits), 13); + BREAK; +# endif + case 100: + BREAK; + } + + + if (sub(totalBits, add(320, tmp)) < 0) + { + setup->ltpf_scale_fac_idx = 0; + move16(); + } + else if (sub(totalBits, add(400, tmp)) < 0) + { + setup->ltpf_scale_fac_idx = 1; + move16(); + } + else if (sub(totalBits, add(480, tmp)) < 0) + { + setup->ltpf_scale_fac_idx = 2; + move16(); + } + else if (sub(totalBits, add(560, tmp)) < 0) + { + setup->ltpf_scale_fac_idx = 3; + move16(); + } + else + { + setup->ltpf_scale_fac_idx = -1; + move16(); + } + +#ifdef ENABLE_HR_MODE + /* No LTPF in hrmode */ + if (decoder->hrmode) + { + setup->ltpf_scale_fac_idx = -1; + move16(); + } +#endif + + return LC3PLUS_OK; +} + diff --git a/lib_lc3plus/setup_dec_lc3.h b/lib_lc3plus/setup_dec_lc3.h new file mode 100644 index 0000000000000000000000000000000000000000..3145cd21c6a3aa629cc954b5ede9672cea28a5e5 --- /dev/null +++ b/lib_lc3plus/setup_dec_lc3.h @@ -0,0 +1,185 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.5 * +* Low Complexity Communication Codec Plus (LC3plus) * +* * +* Copyright licence is solely granted through ETSI Intellectual Property * +* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * +* estoppel or otherwise. * +******************************************************************************/ + +#ifndef SETUP_DEC_LC3_H +#define SETUP_DEC_LC3_H + +#include "constants.h" + +typedef struct +{ + Word16 *x_old_tot_fx; /* MAX_LEN_PCM_PLC_TOT */ + Word32 *PhECU_f0est; /* MAX_PLOCS interpolated plocs */ + Word16 *PhECU_xfp_fx; /* MAX_LPROT */ + Word16 *PhECU_X_sav_fx; /* MAX_LPROT */ + Word16 *PhECU_plocs; /* MAX_PLOCS */ + Word16 *PhECU_fg_wintaper; /* MDCT_MEM_LEN_MAX */ + Word16 *PhECU_win_pre_tda; /* MAX_WIN_PRE_TDA */ + Word32 tdc_gain_c; + Word16 stab_fac; + Word16 tdc_fract; + Word16 tdc_seed; + Word16 tdc_preemph_fac; + Word16 tdc_lpc_order; + Word16 cum_fflcAtten; + Word16 harmonicBuf_fx[MAX_PITCH]; + Word16 harmonicBuf_Q; + Word16 synthHist_fx[M]; + Word16 cum_fading_slow; + Word16 cum_fading_fast; + Word16 PhECU_LprotOrg_fx; /* needed to change the Prot size adaptively */ + Word16 PhECU_Lprot_fx; + Word16 PhECU_fs_idx_fx; + Word16 PhECU_frame_ms; /* needed in PLC_Update and PLCMain functons*/ + Word16 PhECU_seed_fx; + Word16 PhECU_xfp_exp_fx; + Word16 PhECU_time_offs; + Word16 PhECU_X_savQ_fx; + Word16 PhECU_num_plocs; + Word16 PhECU_f0hzLtpBinQ7; /* ltp F0 in bins if available */ + Word16 PhECU_short_flag_prev; + Word16 PhECU_whr_tot_taper; + Word16 PhECU_whr_tot_flat; + Word16 PhECU_LDWIN_OLAP; + Word16 PhECU_LA; + Word16 PhECU_t_adv; + Word16 PhECU_beta_mute; + Word16 norm_corrQ15_fx; + Word16 q_fx_old_exp; + Word16 max_len_pcm_plc; + Word16 max_lprot; + Word16 max_plocs; + + /* Word32 L_tot W_energy sum exponent */ + Word16 PhECU_oold_Ltot_exp_fx; + Word16 PhECU_old_Ltot_exp_fx; + Word32 PhECU_L_oold_xfp_w_E_fx; + Word32 PhECU_L_old_xfp_w_E_fx; + Word16 PhECU_oold_xfp_w_E_exp_fx; /* input Word16 xfp exponnet */ + Word16 PhECU_old_xfp_w_E_exp_fx; + Word16 PhECU_oold_grp_shape_fx[MAX_LGW]; + Word16 PhECU_old_grp_shape_fx[MAX_LGW]; + Word16 PhECU_margin_xfp; +#ifdef CR8_A_PLC_FADEOUT_TUNING + Word16 PhECU_nonpure_tone_flag; /* non-pure single tone indicator state */ +#endif + Word16 PhECU_mag_chg_1st[MAX_LGW]; + Word16 PhECU_Xavg[MAX_LGW]; + Word16 old_scf_q[M]; + Word16 old_old_scf_q[M]; + Word16 tdc_A[M + 1]; + /* for now 20 ms saved Q14 or ptr to a combined ifft win and MDCT preTDA synthesis window 16 ms */ + +#ifdef CR8_A_PLC_FADEOUT_TUNING + Word16 longterm_counter_plcTdc; +# ifndef CR9_L_RETRAIN_FADEOUT_TYPE_CLASSIFIER + Word16 longterm_counter_plcPhaseEcu; +# endif + Word16 longterm_counter_plcNsAdv; + Word16 longterm_analysis_counter_max; /* Maximum longterm frames number */ + Word16 longterm_analysis_counter_max_bytebuffer; /* Same as above but reduced for circular bit-buffer */ + Word32 *plc_longterm_advc_tdc; + Word32 *plc_longterm_advc_ns; + UWord8 plc_fadeout_type; + Word16 overall_counter; + Word8 longterm_counter_byte_position; + Word8 longterm_counter_bit_position; +#endif +} AplcSetup; + +/* Channel state and bitrate-derived values go in this struct */ +typedef struct +{ + Word16 *ltpf_mem_x; /* LTPF_MEM_X_LEN */ + Word16 *ltpf_mem_y; /* LTPF_MEM_Y_LEN */ +#ifdef ENABLE_HR_MODE + Word32 *stDec_ola_mem_fx; /* MDCT_MEM_LEN_MAX */ +#else + Word16 *stDec_ola_mem_fx; /* MDCT_MEM_LEN_MAX */ +#endif + AplcSetup *plcAd; + Word16 * q_old_d_fx; /* MAX_BW */ + Word16 q_old_fx_exp; + Word16 ns_seed; + Word16 ns_cum_alpha; + Word16 pc_nbLostFramesInRow; + Word16 pc_seed; + Word16 *q_old_res_fx; + Word16 q_old_res_fx_exp; + Word16 prev_gg; + Word16 prev_gg_e; + Word16 prev_BW_cutoff_idx_nf; + Word16 prev_fac_ns_fx; + Word16 total_bits; + Word16 enable_lpc_weighting; + Word16 stDec_ola_mem_fx_exp; + Word16 targetBytes; + Word16 ltpf_mem_e; + Word16 ltpf_mem_pitch_int; + Word16 ltpf_mem_pitch_fr; + Word16 ltpf_mem_gain; + Word16 ltpf_mem_active; + Word16 ltpf_scale_fac_idx; + Word16 ltpf_mem_scale_fac_idx; + Word16 quantizedGainOff; + Word16 prev_bfi; + Word16 prev_prev_bfi; + Word16 concealMethod; + Word16 nbLostFramesInRow; + Word16 plc_damping; + Word16 last_size; +#ifdef CR9_N_SHORT_FADE_FOR_UNSTABLE_PITCH + Word32 rel_pitch_change; +#endif +} DecSetup; + +/* Constants and sampling rate derived values go in this struct */ +struct LC3PLUS_Dec +{ + DecSetup * channel_setup[MAX_CHANNELS]; +#ifdef ENABLE_HR_MODE + const Word32 *W_fx; +#else + const Word16 *W_fx; +#endif + const Word16 *bands_offset; + Word32 fs; /* sampling rate, 44.1 maps to 48 */ + Word32 fs_out; /* output sampling rate */ + Word16 fs_idx; /* sampling rate index */ + Word16 frame_length; /* sampling rate index */ + Word16 channels; /* number of channels */ + Word16 plcMeth; /* PLC method for all channels */ + Word16 frame_dms; /* frame length in dms (decimilliseconds, 10^-4)*/ + Word16 last_size; /* size of last frame, without error protection */ + Word16 ep_enabled; /* error protection enabled */ + Word16 error_report; /* corrected errors in last frame or -1 on error */ + + Word16 n_pccw; + Word16 be_bp_left; + Word16 be_bp_right; + Word16 n_pc; + Word16 m_fec; + Word16 epmr; + Word16 combined_channel_coding; + + Word16 yLen; + Word16 W_size; + Word16 la_zeroes; + Word16 stDec_ola_mem_fx_len; + Word16 bands_number; + Word16 ltpf_mem_x_len; + Word16 ltpf_mem_y_len; + Word16 BW_cutoff_bits; + Word16 hrmode; +#ifdef CR10_A_ATTENUATION_CURVE_SELECTOR + Word16 alpha_type_2_table[80];/* PLC_FADEOUT_TYPE_1_IN_MS*10/25 */ +#endif +}; + +#endif diff --git a/lib_lc3plus/setup_enc_lc3.c b/lib_lc3plus/setup_enc_lc3.c new file mode 100644 index 0000000000000000000000000000000000000000..7e20912bb078e46dac98e383414e7a43ff17a8dc --- /dev/null +++ b/lib_lc3plus/setup_enc_lc3.c @@ -0,0 +1,760 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.5 * +* 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 "functions.h" +#include "setup_enc_lc3.h" + +/* if encoder is null only size is reported */ +int alloc_encoder(LC3PLUS_Enc *encoder, int samplerate, int channels) +{ + int ch = 0; + size_t size = sizeof(LC3PLUS_Enc); + void * mdct_mem32 = NULL, *stEnc_mdct_mem = NULL; + + for (ch = 0; ch < channels; ch++) + { + EncSetup *setup = balloc(encoder, &size, sizeof(EncSetup)); + mdct_mem32 = balloc(encoder, &size, sizeof(*setup->mdct_mem32) * DYN_MAX_MDCT_LEN(samplerate)); + stEnc_mdct_mem = balloc(encoder, &size, sizeof(*setup->stEnc_mdct_mem) * DYN_MAX_MDCT_LEN(samplerate)); + if (encoder) + { + encoder->channel_setup[ch] = setup; + setup->mdct_mem32 = mdct_mem32; + setup->stEnc_mdct_mem = stEnc_mdct_mem; + } + } + + return (int)size; +} + +LC3PLUS_Error FillEncSetup(LC3PLUS_Enc *encoder, int samplerate, int channels +#ifdef ENABLE_HR_MODE + , int hrmode +#endif + , int32_t lfe_channel_array[] + ) +{ + int ch = 0; + + memset(encoder, 0, lc3plus_enc_get_size(samplerate, channels)); + alloc_encoder(encoder, samplerate, channels); + + encoder->fs = CODEC_FS(samplerate); + encoder->fs_in = samplerate; + encoder->fs_idx = FS2FS_IDX(encoder->fs); + +# ifdef ENABLE_HR_MODE + if (encoder->fs_idx > 4) + { + encoder->fs_idx = 5; + } + encoder->hrmode = hrmode != 0; +# endif + + encoder->channels = channels; + encoder->frame_dms = 100; + encoder->envelope_bits = 38; + encoder->global_gain_bits = 8; + encoder->noise_fac_bits = 3; + encoder->r12k8_mem_in_len = extract_l(L_shr_pos(Mpy_32_16_lc3plus(encoder->fs, 20972), 9)); + encoder->r12k8_mem_out_len = 24; + encoder->epmr = LC3PLUS_EPMR_ZERO; + encoder->bw_ctrl_active = 0; + encoder->bandwidth = L_shr_pos(encoder->fs, 1); + encoder->bandwidth_preset = L_shr_pos(encoder->fs, 1); + + for (ch = 0; ch < encoder->channels; ch++) + { + encoder->channel_setup[ch]->lfe = lfe_channel_array[ch] != 0; + } + + + for (ch = 0; ch < encoder->channels; ch++) + { + encoder->channel_setup[ch]->x_exp = 15; + encoder->channel_setup[ch]->resamp_exp = 17; + } + + set_enc_frame_params(encoder); + + return lc3plus_enc_set_ep_mode(encoder, LC3PLUS_EP_OFF); /* also calls update_enc_bitrate */ +} + +/* set frame config params */ +void set_enc_frame_params(LC3PLUS_Enc *encoder) +{ +#ifdef CR8_G_ADD_75MS +# ifdef ENABLE_075_DMS_MODE + Word16 tmp; +# endif +#endif + + encoder->frame_length = extract_l(L_shr_pos(Mpy_32_16_lc3plus(encoder->fs, 20972), 6)); /* fs * 0.01*2^6 */ + +# ifdef ENABLE_HR_MODE + if (encoder->hrmode) + { + encoder->BW_cutoff_bits = 0; + } + else +# endif + { + encoder->BW_cutoff_bits = BW_cutoff_bits_all[encoder->fs_idx]; + } + + SWITCH (encoder->frame_dms) + { + case 25: + encoder->frame_length = shr_pos(encoder->frame_length, 2); + encoder->la_zeroes = LowDelayShapes_n960_la_zeroes_2_5ms[encoder->fs_idx]; + encoder->stEnc_mdct_mem_len = sub(encoder->frame_length, encoder->la_zeroes); + encoder->nSubdivisions = 2; + encoder->ltpf_mem_in_len = LTPF_MEMIN_LEN + (LEN_12K8 >> 2); + +# ifdef ENABLE_HR_MODE + if (encoder->hrmode) + { + encoder->bands_number = bands_number_2_5ms_HR[encoder->fs_idx]; + encoder->bands_offset = bands_offset_2_5ms_HR[encoder->fs_idx - 4]; + encoder->W_fx = LowDelayShapes_n960_HRA_2_5ms[encoder->fs_idx - 4]; + encoder->W_size = LowDelayShapes_n960_len_2_5ms[encoder->fs_idx]; + encoder->yLen = encoder->frame_length; + } + else +# endif + { + encoder->yLen = s_min(MAX_BW >> 2, encoder->frame_length); + encoder->W_fx = LowDelayShapes_n960_2_5ms[encoder->fs_idx]; + encoder->W_size = LowDelayShapes_n960_len_2_5ms[encoder->fs_idx]; + encoder->bands_number = bands_number_2_5ms[encoder->fs_idx]; + encoder->bands_offset = bands_offset_2_5ms[encoder->fs_idx]; + encoder->near_nyquist_index = encoder->bands_number - 2; + encoder->near_nyquist_flag = 0; + } + + BREAK; + case 50: + encoder->frame_length = shr_pos(encoder->frame_length, 1); + encoder->la_zeroes = LowDelayShapes_n960_la_zeroes_5ms[encoder->fs_idx]; + encoder->stEnc_mdct_mem_len = sub(encoder->frame_length, encoder->la_zeroes); + encoder->nSubdivisions = 2; + encoder->ltpf_mem_in_len = LTPF_MEMIN_LEN + (LEN_12K8 >> 1); + +# ifdef ENABLE_HR_MODE + if (encoder->hrmode) + { + encoder->bands_offset = bands_offset_5ms_HR[encoder->fs_idx - 4]; + encoder->W_fx = LowDelayShapes_n960_HRA_5ms[encoder->fs_idx - 4]; + encoder->W_size = LowDelayShapes_n960_len_5ms[encoder->fs_idx]; + encoder->yLen = encoder->frame_length; + encoder->bands_number = bands_number_5ms[encoder->fs_idx]; + } + else +# endif + { + encoder->yLen = s_min(MAX_BW >> 1, encoder->frame_length); + encoder->W_fx = LowDelayShapes_n960_5ms[encoder->fs_idx]; + encoder->W_size = LowDelayShapes_n960_len_5ms[encoder->fs_idx]; + encoder->bands_number = bands_number_5ms[encoder->fs_idx]; + encoder->bands_offset = bands_offset_5ms[encoder->fs_idx]; + encoder->near_nyquist_index = encoder->bands_number - 3; + encoder->near_nyquist_flag = 0; + } + encoder->ltpf_mem_in_len = LTPF_MEMIN_LEN; + BREAK; + +#ifdef CR8_G_ADD_75MS + case 75: + tmp = shr_pos(encoder->frame_length, 2); + encoder->frame_length = add(tmp, add(tmp, tmp)); + encoder->la_zeroes = LowDelayShapes_n960_la_zeroes_7_5ms[encoder->fs_idx]; + encoder->stEnc_mdct_mem_len = sub(encoder->frame_length, encoder->la_zeroes); + encoder->bands_number = bands_number_7_5ms[encoder->fs_idx]; + encoder->nSubdivisions = 3; + encoder->ltpf_mem_in_len = LTPF_MEMIN_LEN; + encoder->attdec_nblocks = 3; + encoder->attdec_damping = 9830; + encoder->attdec_hangover_thresh = 1; + encoder->r12k8_mem_out_len = 44; + encoder->near_nyquist_index = encoder->bands_number - 4; + encoder->near_nyquist_flag = 0; +# ifdef ENABLE_HR_MODE + if (encoder->hrmode) + { + encoder->yLen = encoder->frame_length; + encoder->W_fx = LowDelayShapes_n960_HRA_7_5ms[encoder->fs_idx - 4]; + encoder->W_size = LowDelayShapes_n960_len_7_5ms[encoder->fs_idx]; + encoder->bands_number = bands_number_7_5ms[encoder->fs_idx]; + encoder->bands_offset = bands_offset_7_5ms_HR[encoder->fs_idx - 4]; + } + else +# endif + { + encoder->yLen = s_min((MAX_BW >> 2) * 3, encoder->frame_length); + encoder->W_fx = LowDelayShapes_n960_7_5ms[encoder->fs_idx]; + encoder->W_size = LowDelayShapes_n960_len_7_5ms[encoder->fs_idx]; + encoder->bands_number = bands_number_7_5ms[encoder->fs_idx]; + encoder->bands_offset = bands_offset_7_5ms[encoder->fs_idx]; + } + BREAK; +# endif + + case 100: + encoder->la_zeroes = LowDelayShapes_n960_la_zeroes[encoder->fs_idx]; + encoder->stEnc_mdct_mem_len = sub(encoder->frame_length, encoder->la_zeroes); + encoder->bands_number = 64; + encoder->nSubdivisions = 3; + encoder->ltpf_mem_in_len = LTPF_MEMIN_LEN; + encoder->attdec_nblocks = 4; + encoder->attdec_damping = 16384; + encoder->attdec_hangover_thresh = 2; + encoder->near_nyquist_index = encoder->bands_number - 2; + encoder->near_nyquist_flag = 0; + +# ifdef ENABLE_HR_MODE + if (encoder->hrmode) + { + encoder->bands_offset = bands_offset_HR[encoder->fs_idx - 4]; + encoder->W_fx = LowDelayShapes_n960_HRA[encoder->fs_idx - 4]; + encoder->W_size = LowDelayShapes_n960_len[encoder->fs_idx]; + encoder->yLen = encoder->frame_length; + } + else +# endif + { + encoder->yLen = s_min(MAX_BW, encoder->frame_length); + encoder->W_fx = LowDelayShapes_n960[encoder->fs_idx]; + encoder->W_size = LowDelayShapes_n960_len[encoder->fs_idx]; + encoder->bands_offset = bands_offset[encoder->fs_idx]; + } + BREAK; + } +} + +/* change encoder bitrate */ +LC3PLUS_Error update_enc_bitrate(LC3PLUS_Enc *encoder, int bitrate) +{ + int ch = 0; + int totalBytes = 0, maxBR = 0, minBR = 0, max_bytes = 0; + int channel_bytes = 0; + +# ifdef ENABLE_HR_MODE + if (encoder->hrmode) + { + switch (encoder->frame_dms) + { + case 25: + maxBR = 672000; + if (encoder->fs == 48000) + { + minBR = MIN_BR_25MS_48KHZ_HR; + } + else if (encoder->fs == 96000) + { + minBR = MIN_BR_25MS_96KHZ_HR; + } + else + { + return LC3PLUS_HRMODE_ERROR; + } + break; + case 50: + maxBR = 600000; + if (encoder->fs == 48000) + { + minBR = MIN_BR_50MS_48KHZ_HR; + } + 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; + } + else if (encoder->fs == 96000) + { + minBR = MIN_BR_100MS_96KHZ_HR; + } + else + { + return LC3PLUS_HRMODE_ERROR; + } + break; + default: return LC3PLUS_HRMODE_ERROR; + } + } + else + { + minBR = (MIN_NBYTES << 3); + maxBR = MAX_BR; + + switch (encoder->frame_dms) + { + case 25: + minBR = MIN_BR_025DMS; + maxBR = MAX_BR; + BREAK; + case 50: + minBR = MIN_BR_050DMS; + maxBR = MAX_BR; + /* have additional limitations for 5.0ms */ + SWITCH (encoder->fs_in) + { +# ifdef SUBSET_NB + case 8000: maxBR = MAX_BR_050DMS_NB; BREAK; +# endif + default: BREAK; + } + BREAK; +# ifdef CR8_G_ADD_75MS + case 75: + minBR = MIN_BR_075DMS; + maxBR = MAX_BR_075DMS; // special value for maxBR @ 7.5ms + /* have additional limitations for 7.5ms */ + SWITCH (encoder->fs_in) + { +# ifdef SUBSET_NB + case 8000: maxBR = MAX_BR_075DMS_NB ; BREAK; +# endif +# ifdef SUBSET_WB + case 16000: maxBR = MAX_BR_075DMS_WB ; BREAK; +# endif +# ifdef SUBSET_SSWB + case 24000: maxBR = MAX_BR_075DMS_SSWB; BREAK; +# endif + default: BREAK; + } + BREAK; +# endif + case 100: + /* have additional limitations for 10ms */ + minBR = MIN_BR_100DMS; + maxBR = MAX_BR; + SWITCH (encoder->fs_in) + { +# ifdef SUBSET_NB + case 8000: maxBR = MAX_BR_100DMS_NB ; BREAK; +# endif +# ifdef SUBSET_WB + case 16000: maxBR = MAX_BR_100DMS_WB ; BREAK; +# endif +# ifdef SUBSET_SSWB + case 24000: maxBR = MAX_BR_100DMS_SSWB; BREAK; +# endif + default: maxBR = MAX_BR; BREAK; + } + BREAK; + default: return LC3PLUS_FRAMEMS_ERROR; + } + + /* 441/480 in Q31 and 1000/75 in Q23 */ + if (encoder->fs_in == 44100) + { + minBR = Mpy_32_32_lc3plus(minBR, 1973000602); + maxBR = Mpy_32_32_lc3plus(maxBR, 1973000602); + } + } +#else /* ENABLE_HR_MODE */ + minBR = (MIN_NBYTES << 3); + maxBR = MAX_BR; + + switch (encoder->frame_dms) + { + case 25: + minBR = MIN_BR_025DMS; + maxBR = MAX_BR; + BREAK; + case 50: + minBR = MIN_BR_050DMS; + maxBR = MAX_BR; + /* have additional limitations for 5.0ms */ + SWITCH (encoder->fs_in) + { +# ifdef SUBSET_NB + case 8000: maxBR = MAX_BR_050DMS_NB; BREAK; +# endif + default: BREAK; + } + BREAK; +# ifdef CR8_G_ADD_75MS + case 75: + minBR = MIN_BR_075DMS; + maxBR = MAX_BR_075DMS; // special value for maxBR @ 7.5ms + /* have additional limitations for 7.5ms */ + SWITCH (encoder->fs_in) + { +# ifdef SUBSET_NB + case 8000: maxBR = MAX_BR_075DMS_NB ; BREAK; +# endif +# ifdef SUBSET_WB + case 16000: maxBR = MAX_BR_075DMS_WB ; BREAK; +# endif +# ifdef SUBSET_SSWB + case 24000: maxBR = MAX_BR_075DMS_SSWB; BREAK; +# endif + default: BREAK; + } + BREAK; +# endif + case 100: + /* have additional limitations for 10ms */ + minBR = MIN_BR_100DMS; + maxBR = MAX_BR; + SWITCH (encoder->fs_in) + { +# ifdef SUBSET_NB + case 8000: maxBR = MAX_BR_100DMS_NB ; BREAK; +# endif +# ifdef SUBSET_WB + case 16000: maxBR = MAX_BR_100DMS_WB ; BREAK; +# endif +# ifdef SUBSET_SSWB + case 24000: maxBR = MAX_BR_100DMS_SSWB; BREAK; +# endif + default: maxBR = MAX_BR; BREAK; + } + BREAK; + default: return LC3PLUS_FRAMEMS_ERROR; + } + + /* 441/480 in Q31 and 1000/75 in Q23 */ + if (encoder->fs_in == 44100) + { + minBR = Mpy_32_32_lc3plus(minBR, 1973000602); + maxBR = Mpy_32_32_lc3plus(maxBR, 1973000602); + } +#endif /* ENABLE_HR_MODE */ + + minBR *= encoder->channels; + maxBR *= encoder->channels; + + if (bitrate < minBR || bitrate > maxBR) + { + return LC3PLUS_BITRATE_ERROR; + } + + encoder->bitrate = bitrate; + encoder->lc3_br_set = 1; + + /* move stuff to encoder->channel_setup */ + + encoder->combined_channel_coding = 0; + if (encoder->channels > 1 && encoder->epmode) + { + if (encoder->bitrate * encoder->frame_length / (8 * encoder->fs_in) <= 160) + { + encoder->combined_channel_coding = 1; + } + } + + if (encoder->epmode > 0) + { + max_bytes = bitrate * encoder->frame_length / (8 * encoder->fs_in * encoder->channels); + + if (max_bytes < FEC_SLOT_BYTES_MIN || max_bytes > FEC_SLOT_BYTES_MAX) + { + return LC3PLUS_BITRATE_ERROR; + } + } + + if (encoder->combined_channel_coding) + { + totalBytes = fec_get_data_size(encoder->epmode, encoder->combined_channel_coding, + bitrate * (Word32)encoder->frame_length / (8 * encoder->fs_in)); + + encoder->channel_setup[0]->n_pccw = + fec_get_n_pccw(bitrate * (Word32)encoder->frame_length / (8 * encoder->fs_in), encoder->epmode, + encoder->combined_channel_coding); + + encoder->channel_setup[0]->n_pc = fec_get_n_pc(encoder->epmode, encoder->channel_setup[0]->n_pccw, + bitrate * (Word32)encoder->frame_length / (8 * encoder->fs_in)); + } + else + { + totalBytes = bitrate * (Word32)encoder->frame_length / (8 * encoder->fs_in); + } + + for (ch = 0; ch < encoder->channels; ch++) + { + EncSetup *setup = encoder->channel_setup[ch]; + channel_bytes = totalBytes / encoder->channels + (ch < (totalBytes % encoder->channels)); + + if (encoder->combined_channel_coding) + { + setup->targetBytes = channel_bytes; + } + else + { + setup->targetBytes = fec_get_data_size(encoder->epmode, encoder->combined_channel_coding, channel_bytes); + setup->n_pccw = fec_get_n_pccw(channel_bytes, encoder->epmode, encoder->combined_channel_coding); + setup->n_pc = fec_get_n_pc(encoder->epmode, setup->n_pccw, channel_bytes); + } + /* reduce bandwith to 12kHz if bitrate is low */ + if (sub(encoder->frame_dms, 100) == 0 && + ((sub(setup->targetBytes, 40) < 0 && L_sub(encoder->fs, 48000) == 0) || + (sub(setup->targetBytes, 36) < 0 && L_sub(encoder->fs, 32000) == 0))) + { + encoder->bandwidth = L_min(12000, encoder->bandwidth_preset); + } + else + { + /* channel with highest index has lowest bitrate. + For a second channel with lower targetBytes, bandwidth is overwritten */ + encoder->bandwidth = encoder->bandwidth_preset; + } + + { + Word16 tmp; + + SWITCH(encoder->frame_dms) + { + case 25: tmp = 1; BREAK; + case 50: tmp = 2; BREAK; + case 75: tmp = 3; BREAK; + default : tmp = 4; BREAK; + } + + encoder->bw_ctrl_cutoff_bin = L_mult0(Mpy_32_32_lc3plus(encoder->bandwidth, 10737419), tmp); /* bandwidth * frame_dms / 5000 */ + } + + encoder->bw_index = sub( Mpy_32_32_lc3plus(encoder->bandwidth, 536871), 1); /* (bandwidth / 4000 ) - 1 */ + switch (encoder->frame_dms) + { + case 25: max_bytes = MAX_NBYTES_025; break; + case 50: max_bytes = MAX_NBYTES_050; break; +#ifdef ENABLE_075_DMS_MODE +# ifdef CR8_G_ADD_75MS + case 75: max_bytes = MAX_NBYTES_075; BREAK; +# endif +#endif + case 100: max_bytes = MAX_NBYTES_100; break; + } +#ifdef ENABLE_HR_MODE + if (encoder->hrmode) + { + max_bytes = MAX_NBYTES_RED_HR; + } +#endif + if (setup->targetBytes < MIN_NBYTES || setup->targetBytes > max_bytes) + { + return LC3PLUS_BITRATE_ERROR; + } + + setup->total_bits = shl(setup->targetBytes, 3); + setup->targetBitsInit = + sub(setup->total_bits, + add(encoder->envelope_bits, + add(encoder->global_gain_bits, add(encoder->noise_fac_bits, encoder->BW_cutoff_bits)))); + setup->targetBitsInit = sub(setup->targetBitsInit, sub(17, norm_s(sub(encoder->yLen, 1)))); + if (setup->total_bits > 1280) + { + setup->targetBitsInit = sub(setup->targetBitsInit, 1); + } + if (setup->total_bits > 2560) + { + setup->targetBitsInit = sub(setup->targetBitsInit, 1); + } + +# ifdef ENABLE_HR_MODE + if (encoder->hrmode) + { + setup->targetBitsInit -= 1; + } +# endif + + setup->targetBitsAri = setup->total_bits; + + SWITCH (encoder->frame_dms) + { + case 25: + /* 9830 = 2.4 * 2^12 */ + setup->ltpf_enable = + sub(extract_l(L_shr(L_mult0(9830, setup->total_bits), 12)), add(560, DEPR_i_mult(80, encoder->fs_idx))) < 0; + setup->enable_lpc_weighting = 0; + BREAK; + case 50: + setup->ltpf_enable = sub(sub(DEPR_i_mult(setup->total_bits, 2), 160), add(560, DEPR_i_mult(80, encoder->fs_idx))) < 0; + setup->enable_lpc_weighting = setup->total_bits < 240; + BREAK; +#ifdef CR8_G_ADD_75MS + case 75: + setup->ltpf_enable = sub(L_shr(L_mult0(10923, setup->total_bits), 13), add(560, DEPR_i_mult(80, encoder->fs_idx))) < 0; + setup->enable_lpc_weighting = setup->total_bits < 360; + BREAK; +# endif + case 100: + setup->enable_lpc_weighting = setup->total_bits < 480; + setup->ltpf_enable = sub(setup->total_bits, add(560, DEPR_i_mult(80, encoder->fs_idx))) < 0; + BREAK; + } + + setup->quantizedGainOff = + -(s_min(115, setup->total_bits / (10 * (encoder->fs_idx + 1))) + 105 + 5 * (encoder->fs_idx + 1)); + +# ifdef ENABLE_HR_MODE + if (encoder->hrmode && encoder->fs_idx == 5) + { + setup->quantizedGainOff = MAX(setup->quantizedGainOff, -181); + } +# endif + +# ifdef ENABLE_HR_MODE + if (encoder->frame_dms == 100 && + ((encoder->fs_in >= 44100 && setup->targetBytes >= 100) || + (encoder->fs_in == 32000 && setup->targetBytes >= 81)) + && setup->targetBytes < 340 + && (encoder->hrmode == 0)) +# else + if (encoder->frame_dms == 100 && + ((encoder->fs_in >= 44100 && setup->targetBytes >= 100) || + (encoder->fs_in == 32000 && setup->targetBytes >= 81)) + && setup->targetBytes < 340 + ) +# endif + { + setup->attack_handling = 1; + } + else if (encoder->frame_dms == 75 && ((encoder->fs_in >= 44100 && setup->targetBytes >= 75) || + (encoder->fs_in == 32000 && setup->targetBytes >= 61)) && setup->targetBytes < 150 +# ifdef ENABLE_HR_MODE + && encoder->hrmode == 0 +# endif + ) + { + setup->attack_handling = 1; + } + else + { + /* reset attack detector for bitrate switching */ + setup->attack_handling = 0; + setup->attdec_filter_mem[0] = 0; + setup->attdec_filter_mem[1] = 0; + setup->attdec_detected = 0; + setup->attdec_position = 0; + setup->attdec_acc_energy = 0; + setup->attdec_scaling = 0; + } + +# ifdef ENABLE_HR_MODE + if (encoder->hrmode) + { + setup->ltpf_enable = 0; + } +# endif + encoder->sns_damping = SNS_DAMPING; + +# ifdef ENABLE_HR_MODE + IF (encoder->hrmode) + { + encoder->sns_damping = SNS_DAMPING_HRMODE; + IF (encoder->fs_idx >= 4) + { + IF ((encoder->frame_dms == 100) & (setup->total_bits > 4400)) + { + encoder->sns_damping = SNS_DAMPING_HRMODE_UB_10MS; + } +#ifdef CR8_G_ADD_75MS + IF ((encoder->frame_dms == 75) & (setup->total_bits > 3300)) + { + encoder->sns_damping = SNS_DAMPING_HRMODE_UB_7_5MS; + } +#endif + IF ((encoder->frame_dms == 50) & (setup->total_bits > 2300)) + { + encoder->sns_damping = SNS_DAMPING_HRMODE_UB_5MS; + } + IF ((encoder->frame_dms == 25) & (setup->total_bits > 1150)) + { + encoder->sns_damping = SNS_DAMPING_HRMODE_UB_2_5MS; + } + } + } + + if (encoder->hrmode && encoder->fs_idx >= 4) + { + int real_rate = setup->targetBytes * 8 * 10000 / encoder->frame_dms; + setup->regBits = real_rate / 12500; + + if (encoder->fs_idx == 5) + { + if (encoder->frame_dms == 100) + { + setup->regBits += 2; + } +#ifdef CR8_G_ADD_75MS + if (encoder->frame_dms == 75) + { + setup->regBits +=1; + } +#endif + if (encoder->frame_dms == 25) + { + setup->regBits -= 6; + } + } + else + { + if (encoder->frame_dms == 25) + { + setup->regBits -= 6; + } + else if (encoder->frame_dms == 50) + { + setup->regBits += 0; + } +#ifdef CR8_G_ADD_75MS + if (encoder->frame_dms == 75) + { + setup->regBits +=2; + } +#endif + if (encoder->frame_dms == 100) + { + setup->regBits += 5; + } + } + + + if (setup->regBits < 6) + { + setup->regBits = 6; + } + if (setup->regBits > 23) + { + setup->regBits = 23; + } + } + else + { + setup->regBits = -1; + } +# endif + } + + encoder->bitrate = bitrate; + + return LC3PLUS_OK; +} + diff --git a/lib_lc3plus/setup_enc_lc3.h b/lib_lc3plus/setup_enc_lc3.h new file mode 100644 index 0000000000000000000000000000000000000000..34e26a59dd8dd3f7831fb06068e0018e476c0ace --- /dev/null +++ b/lib_lc3plus/setup_enc_lc3.h @@ -0,0 +1,131 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.5 * +* Low Complexity Communication Codec Plus (LC3plus) * +* * +* Copyright licence is solely granted through ETSI Intellectual Property * +* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * +* estoppel or otherwise. * +******************************************************************************/ + +#ifndef SETUP_ENC_LC3_H +#define SETUP_ENC_LC3_H + +#include "constants.h" + +/* Channel state and bitrate-derived values go in this struct */ +typedef struct +{ +#ifdef ENABLE_HR_MODE + Word32 *stEnc_mdct_mem; /* MDCT_MEM_LEN_MAX */ +#else + Word16 *stEnc_mdct_mem; /* MDCT_MEM_LEN_MAX */ +#endif + Word32 *mdct_mem32; /* MDCT_MEM_LEN_MAX */ + Word32 targetBitsOff; + Word16 targetBytes; + Word16 total_bits; + Word16 targetBitsInit; + Word16 targetBitsAri; + Word16 enable_lpc_weighting; + Word16 ltpf_enable; + Word16 quantizedGainOff; + Word16 tns_bits; + Word16 targetBitsQuant; + Word16 olpa_mem_s6k4_exp; + Word16 olpa_mem_pitch; +#ifdef CR9_F_PITCH_WIN_LEN_FIX + Word16 pitch_flag; +#endif + Word16 ltpf_mem_in_exp; + Word16 ltpf_mem_normcorr; + Word16 ltpf_mem_mem_normcorr; + Word16 ltpf_mem_ltpf_on; + Word16 ltpf_mem_pitch; + Word16 mem_targetBits; + Word16 mem_specBits; + Word16 x_exp; + Word16 resamp_exp; + Word16 attack_handling; /* flag to enable attack handling */ + Word16 attdec_filter_mem[2]; + Word16 attdec_detected; + Word16 attdec_position; + Word32 attdec_acc_energy; + Word16 attdec_scaling; +#ifdef ENABLE_HR_MODE + Word16 regBits; + Word32 resamp_mem32[120]; +#else + Word32 resamp_mem32[60]; +#endif +#ifdef ENABLE_HR_MODE + Word16 r12k8_mem_in[120]; +#else + Word16 r12k8_mem_in[60]; +#endif + Word32 r12k8_mem_50[2]; +#ifdef CR8_G_ADD_75MS + Word16 r12k8_mem_out[44]; +#else + Word16 r12k8_mem_out[24]; +#endif + Word16 olpa_mem_s12k8[3]; + Word16 olpa_mem_s6k4[LEN_6K4 + MAX_PITCH_6K4 + 16]; + Word16 ltpf_mem_in[LTPF_MEMIN_LEN + LEN_12K8 + 1]; + Word16 n_pccw; + Word16 n_pc; + + Word16 lfe; +} EncSetup; + +/* Constants and sampling rate derived values go in this struct */ +struct LC3PLUS_Enc +{ + EncSetup *channel_setup[MAX_CHANNELS]; +#ifdef ENABLE_HR_MODE + const Word32 *W_fx; +#else + const Word16 *W_fx; +#endif + const Word16 *bands_offset; + + Word32 fs; /* encoder sampling rate 44.1 -> 48 */ + Word32 fs_in; /* input sampling rate */ + Word32 bitrate; /* global bitrate */ + Word16 fs_idx; /* sampling rate index */ + Word16 frame_length; /* audio samples / frame */ + Word16 channels; /* number of channels */ + Word16 epmode; /* error protection mode */ + Word16 frame_dms; /* frame length in dms (decimilliseconds, 10^-4)*/ + Word8 lc3_br_set; /* indicate if bitrate has been set */ + + Word16 yLen; + Word16 W_size; + Word16 la_zeroes; + Word16 stEnc_mdct_mem_len; + Word16 bands_number; + Word16 nSubdivisions; + Word16 ltpf_mem_in_len; + Word16 envelope_bits; + Word16 global_gain_bits; + Word16 noise_fac_bits; + Word16 BW_cutoff_bits; + Word16 r12k8_mem_in_len; + Word16 r12k8_mem_out_len; + Word16 near_nyquist_index; + Word16 near_nyquist_flag; + + Word16 epmr; + Word16 combined_channel_coding; + Word32 bandwidth; + Word32 bandwidth_preset; + Word32 bw_ctrl_active; + Word16 bw_ctrl_cutoff_bin; + Word16 bw_index; + Word16 attdec_nblocks; + Word16 attdec_damping; + Word16 attdec_hangover_thresh; + Word16 hrmode; + Word16 sns_damping; +}; + +#endif diff --git a/lib_lc3plus/sns_compute_scf_fx.c b/lib_lc3plus/sns_compute_scf_fx.c new file mode 100644 index 0000000000000000000000000000000000000000..d56a1a7f855636c31302a8d8a2da99461db9bf3f --- /dev/null +++ b/lib_lc3plus/sns_compute_scf_fx.c @@ -0,0 +1,166 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.5 * +* 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 "functions.h" + +void processSnsComputeScf_fx(Word32 *d2_fx, Word16 d2_fx_exp, Word16 fs_idx, Word16 n_bands, Word16 *scf, + Word16 scf_smoothing_enabled, Word16 attdec_damping_factor, Word8 *scratchBuffer, Word16 sns_damping + ) +{ + Dyn_Mem_Deluxe_In( + Word16 i, s, s2, nf, tmp; + Word32 L_mean, L_tmp; + Word32 *d3_fx; + Word16 *d3_fx_exp; + Word16 *d4_fx; + Word16 *scf_smooth; + ); + + UNUSED(attdec_damping_factor); + + d3_fx = scratchAlign(scratchBuffer, 0); /* Size = 4 * MAX_BANDS_NUMBER = 256 bytes */ + d3_fx_exp = scratchAlign(d3_fx, sizeof(*d3_fx) * MAX_BANDS_NUMBER); /* Size = 2 * MAX_BANDS_NUMBER = 128 bytes */ + d4_fx = scratchAlign(d3_fx_exp, sizeof(*d3_fx_exp) * MAX_BANDS_NUMBER); /* Size = 2 * MAX_BANDS_NUMBER = 128bytes */ + scf_smooth = scratchAlign(d4_fx, sizeof(*d4_fx) * MAX_BANDS_NUMBER); /* Size = 2 * 16 */ + +/* Smoothing and Pre-emphasis */ + IF (sub(n_bands, 32) < 0) + { + L_tmp = sub(32, n_bands); + FOR (i = sub(n_bands, 1); i >= L_tmp; i--) + { + d2_fx[(i + L_tmp) * 2 + 1] = d2_fx[i]; move32(); + d2_fx[(i + L_tmp) * 2 + 0] = d2_fx[i]; move32(); + } + FOR (i = sub(L_tmp, 1); i >= 0; i--) + { + d2_fx[i * 4 + 3] = d2_fx[i]; move32(); + d2_fx[i * 4 + 2] = d2_fx[i]; move32(); + d2_fx[i * 4 + 1] = d2_fx[i]; move32(); + d2_fx[i * 4 + 0] = d2_fx[i]; move32(); + } + n_bands = 64; move16(); + } + ELSE + IF (sub(n_bands, 64) < 0) + { + L_tmp = sub(64, n_bands); + FOR (i = sub(n_bands, 1); i >= L_tmp; i--) + { + d2_fx[i + L_tmp] = d2_fx[i]; move32(); + } + FOR (i = sub(L_tmp, 1); i >= 0; i--) + { + d2_fx[i * 2 + 1] = d2_fx[i]; move32(); + d2_fx[i * 2 + 0] = d2_fx[i]; move32(); + } + n_bands = 64; move16(); + } + + L_tmp = L_add(Mpy_32_16_lc3plus(d2_fx[0], 24576), L_shr_pos(d2_fx[1], 2)); + d3_fx[0] = Mpy_32_16_lc3plus(L_tmp, lpc_pre_emphasis[fs_idx][0]); move32(); + d3_fx_exp[0] = add(d2_fx_exp, lpc_pre_emphasis_e[fs_idx][0]); move16(); + FOR (i = 1; i < n_bands - 1; i++) + { + L_tmp = L_add(L_shr_pos(d2_fx[i], 1), L_add(L_shr_pos(d2_fx[i - 1], 2), L_shr_pos(d2_fx[i + 1], 2))); + d3_fx[i] = Mpy_32_16_lc3plus(L_tmp, lpc_pre_emphasis[fs_idx][i]); move32(); + d3_fx_exp[i] = add(d2_fx_exp, lpc_pre_emphasis_e[fs_idx][i]); move16(); + } + L_tmp = L_add(Mpy_32_16_lc3plus(d2_fx[n_bands - 1], 24576), L_shr_pos(d2_fx[n_bands - 2], 2)); + d3_fx[n_bands - 1] = Mpy_32_16_lc3plus(L_tmp, lpc_pre_emphasis[fs_idx][n_bands - 1]); move32(); + d3_fx_exp[n_bands - 1] = add(d2_fx_exp, lpc_pre_emphasis_e[fs_idx][n_bands - 1]); move16(); + + /* Mean */ + s = d3_fx_exp[MAX_BANDS_NUMBER - 1]; + s2 = add(s, 6); + + L_mean = L_shr(d3_fx[0], sub(s2, d3_fx_exp[0])); + FOR (i = 1; i < MAX_BANDS_NUMBER; i++) + { + L_mean = L_add(L_mean, L_shr(d3_fx[i], sub(s2, d3_fx_exp[i]))); + } + + /* Noise floor at -40dB */ + nf = BASOP_Util_Log2_16(L_mean, s); + nf = sub(s_max(nf, -25965), 6803); + +/* Log-domain */ + FOR (i = 0; i < MAX_BANDS_NUMBER; i++) + { + d4_fx[i] = s_max(nf, BASOP_Util_Log2_16(d3_fx[i], d3_fx_exp[i])); move16(); + } + + /* Downsampling */ + L_tmp = L_mult(d4_fx[0], 8192); + L_tmp = L_mac(L_tmp, d4_fx[1], 8192); + L_tmp = L_mac(L_tmp, d4_fx[2], 8192); + L_tmp = L_mac(L_tmp, d4_fx[3], 5461); + d3_fx[0] = L_mac(L_tmp, d4_fx[4], 2731); move32(); + FOR (i = 1; i < M - 1; i++) + { + L_tmp = L_mult(d4_fx[i * 4 - 1], 2731); + L_tmp = L_mac(L_tmp, d4_fx[i * 4 + 0], 5461); + L_tmp = L_mac(L_tmp, d4_fx[i * 4 + 1], 8192); + L_tmp = L_mac(L_tmp, d4_fx[i * 4 + 2], 8192); + L_tmp = L_mac(L_tmp, d4_fx[i * 4 + 3], 5461); + d3_fx[i] = L_mac(L_tmp, d4_fx[i * 4 + 4], 2731); move32(); + } + L_tmp = L_mult(d4_fx[59], 2731); + L_tmp = L_mac(L_tmp, d4_fx[60], 5461); + L_tmp = L_mac(L_tmp, d4_fx[61], 8192); + L_tmp = L_mac(L_tmp, d4_fx[62], 8192); + d3_fx[M - 1] = L_mac(L_tmp, d4_fx[63], 8192); move32(); + +/* Remove mean and scaling */ + L_mean = L_shr_pos(d3_fx[0], 4); + FOR (i = 1; i < M; i++) + { + L_mean = L_add(L_mean, L_shr_pos(d3_fx[i], 4)); + } + + FOR (i = 0; i < M; i++) + { + scf[i] = mult_r(sns_damping, round_fx(L_shl_pos(L_sub(d3_fx[i], L_mean), 1))); + move16(); + } + + /* scale factor smoothing */ + IF (scf_smoothing_enabled) + { + scf_smooth[0] = L_shr(L_mult0(L_add(L_add(scf[0], scf[1]), scf[2]), 10923), 15); + L_mean = scf_smooth[0]; move16(); + scf_smooth[1] = L_shr(L_add(L_add(L_add(scf[0], scf[1]), scf[2]), scf[3]), 2); + L_mean = L_add(L_mean, scf_smooth[1]); + FOR (i = 2; i < M - 2; i++) + { + L_tmp = L_add(L_add(L_add(L_add(scf[i - 2], scf[i - 1]), scf[i]), scf[i + 1]), scf[i + 2]); + tmp = norm_s(L_shr(L_abs(L_tmp), 15)); + if (tmp > 0) { + tmp = sub(16, tmp); + L_tmp = L_shr(L_tmp, tmp); + } + scf_smooth[i] = L_shr(L_mult0(L_tmp, 13107), sub(16, tmp)); + L_mean = L_add(L_mean, scf_smooth[i]); + } + scf_smooth[M - 2] = L_shr(L_add(L_add(L_add(scf[M - 4], scf[M - 3]), scf[M - 2]), scf[M - 1]), 2); + L_mean = L_add(L_mean, scf_smooth[M - 2]); + scf_smooth[M - 1] = L_shr(L_mult0(L_add(L_add(scf[M - 3], scf[M - 2]), scf[M - 1]), 10923), 15); + L_mean = L_add(L_mean, scf_smooth[M - 1]); + + L_mean = L_shr(L_mean, 4); + + FOR (i = 0; i < M; i++) + { + scf[i] = mult_r(attdec_damping_factor, sub(scf_smooth[i], L_mean)); + } + } + + Dyn_Mem_Deluxe_Out(); +} + diff --git a/lib_lc3plus/sns_interpolate_scf_fx.c b/lib_lc3plus/sns_interpolate_scf_fx.c new file mode 100644 index 0000000000000000000000000000000000000000..e71825d075dc6e04e0139ca0b554ddd8c556f13b --- /dev/null +++ b/lib_lc3plus/sns_interpolate_scf_fx.c @@ -0,0 +1,154 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.5 * +* 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 "functions.h" + +void processSnsInterpolateScf_fx( +#ifdef ENABLE_HR_MODE + Word32 *scf_q, Word32 mdct_scf[], +#else + Word16 *scf_q, Word16 mdct_scf[], +#endif + Word16 mdct_scf_exp[], Word16 inv_scf, + Word16 n_bands, Word8 *scratchBuffer) +{ +#ifdef ENABLE_HR_MODE + Dyn_Mem_Deluxe_In( + Word32 i, tmp2; + Word32 *scf_int; + Word32 tmp; + Word32 *scf_tmp; + ); +#else + Dyn_Mem_Deluxe_In( + Word16 i, tmp2; + Word16 *scf_int; + Word16 tmp; + Word16 *scf_tmp; + ); +#endif + +#ifdef ENABLE_HR_MODE + scf_int = (Word32 *)scratchAlign(scratchBuffer, 0); /* Size = 2 * MAX_BANDS_NUMBER = 128 bytes */ + scf_tmp = (Word32 *)scratchAlign(scf_int, 4 * MAX_BANDS_NUMBER); /* 2 * MAX_BANDS_NUMBER = 128 bytes */ +#else + scf_int = (Word16 *)scratchAlign(scratchBuffer, 0); /* Size = 2 * MAX_BANDS_NUMBER = 128 bytes */ + scf_tmp = (Word16 *)scratchAlign(scf_int, 2 * MAX_BANDS_NUMBER); /* 2 * MAX_BANDS_NUMBER = 128 bytes */ +#endif + + /* Interpolation */ + scf_int[0] = scf_q[0]; + scf_int[1] = scf_q[0]; + FOR (i = 1; i < M; i++) + { +#ifdef ENABLE_HR_MODE + tmp = L_sub(scf_q[i], scf_q[i - 1]); + tmp2 = L_shr(tmp, 2); + tmp = L_shr(tmp, 3); + scf_int[i * 4 - 2] = L_add(scf_q[i - 1], tmp); + scf_int[i * 4 - 1] = L_add(scf_int[i * 4 - 2], tmp2); + scf_int[i * 4] = L_add(scf_int[i * 4 - 1], tmp2); + scf_int[i * 4 + 1] = L_add(scf_int[i * 4], tmp2); +#else + tmp = sub(scf_q[i], scf_q[i - 1]); + tmp2 = mult_r(tmp, 8192); + tmp = mult_r(tmp, 4096); + scf_int[i * 4 - 2] = add(scf_q[i - 1], tmp); + scf_int[i * 4 - 1] = add(scf_int[i * 4 - 2], tmp2); + scf_int[i * 4] = add(scf_int[i * 4 - 1], tmp2); + scf_int[i * 4 + 1] = add(scf_int[i * 4], tmp2); +#endif + } +#ifdef ENABLE_HR_MODE + scf_int[62] = L_add(scf_int[61], tmp2); + scf_int[63] = L_add(scf_int[62], tmp2); +#else + scf_int[62] = add(scf_int[61], tmp2); + scf_int[63] = add(scf_int[62], tmp2); +#endif + + /* 8 kHz mode for 2.5 ms */ + IF (sub(n_bands, 32) < 0) + { +#ifdef ENABLE_HR_MODE + basop_memmove(scf_tmp, scf_int, 64 * sizeof(Word32)); +#else + basop_memmove(scf_tmp, scf_int, 64 * sizeof(Word16)); +#endif + tmp = sub(32, n_bands); + FOR (i = 0; i < tmp; i++) + { +#ifdef ENABLE_HR_MODE + scf_int[i] = L_add(L_shr(L_add(scf_tmp[4 * i], scf_tmp[4 * i + 1]), 2), + L_shr(L_add(scf_tmp[4 * i + 2], scf_tmp[4 * i + 3]), 2)); +#else + /* 8192 = 0.25 * 2^15 */ + scf_int[i] = add(mac_r(L_mult(scf_tmp[4 * i], 8192), scf_tmp[4 * i + 1], 8192), + mac_r(L_mult(scf_tmp[4 * i + 2], 8192), scf_tmp[4 * i + 3], 8192)); +#endif + } + + FOR (i = 0; i < n_bands - tmp; i++) + { +#ifdef ENABLE_HR_MODE + scf_int[tmp + i] = L_shr(L_add(scf_tmp[4 * tmp + 2 * i], scf_tmp[4 * tmp + 2 * i + 1]), 1); +#else + scf_int[tmp + i] = mac_r(L_mult(scf_tmp[4 * tmp + 2 * i], 16384), scf_tmp[4 * tmp + 2 * i + 1], 16384); +#endif + } + } + ELSE + /* For 5ms */ + IF (sub(n_bands, 64) < 0) + { + tmp = sub(64, n_bands); + FOR (i = 0; i < tmp; i++) + { +#ifdef ENABLE_HR_MODE + scf_int[i] = L_shr(L_add(scf_int[2 * i], scf_int[2 * i + 1]), 1); +#else + scf_int[i] = mac_r(L_mult(scf_int[2 * i], 16384), scf_int[2 * i + 1], 16384); +#endif + } + FOR (; i < n_bands; i++) + { + scf_int[i] = scf_int[tmp + i]; move16(); + } +#ifdef ENABLE_HR_MODE + move16(); // 32 bit operations have twice the complexity weight of 16 bit operations +#endif + } + + /* Inversion at encoder-side*/ + IF (inv_scf == 1) + { + FOR (i = 0; i < n_bands; i++) + { +#ifdef ENABLE_HR_MODE + scf_int[i] = L_negate(scf_int[i]); +#else + scf_int[i] = negate(scf_int[i]); +#endif + } + } + +/* Linear Domain */ + FOR (i = 0; i < n_bands; i++) + { +#ifdef ENABLE_HR_MODE + /* scf_int is in Q26, BASOP_Util_InvLog2_pos requires Q25 data */ + mdct_scf[i] = BASOP_Util_InvLog2_pos(L_shr(scf_int[i], 1), &mdct_scf_exp[i]); +#else + mdct_scf[i] = BASOP_Util_InvLog2_16(scf_int[i], &mdct_scf_exp[i]); +#endif + } + + Dyn_Mem_Deluxe_Out(); +} + diff --git a/lib_lc3plus/sns_quantize_scf_fx.c b/lib_lc3plus/sns_quantize_scf_fx.c new file mode 100644 index 0000000000000000000000000000000000000000..f1f0ba423ac32acb334b53cc9b024e024379aeef --- /dev/null +++ b/lib_lc3plus/sns_quantize_scf_fx.c @@ -0,0 +1,834 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.5 * +* 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 "functions.h" + +static Word16 stage1_base( /* o : idx */ + const Word16 *t, /* i : target SCFs */ +#ifdef ENABLE_HR_MODE + const Word32 *cdbk, /* i : SCFs cdbk */ +#else + const Word16 *cdbk, /* i : SCFs cdbk */ +#endif + const Word16 R /* i : number of rows in codebook */ +) +{ + Counter row; + Word16 k_ptr, idx; + Word32 L_min_mse, L_mse; + Counter col; +#ifdef ENABLE_HR_MODE + Word32 err; +#else + Word16 err; +#endif + +#ifdef DYNMEM_COUNT + Dyn_Mem_In("stage1_base", sizeof(struct { + Counter row, col; + Word16 k_ptr, idx, err; + Word32 L_min_mse, L_mse; + })); +#endif +#ifdef WMOPS + push_wmops("stage1_base"); +#endif + +/* find first vector error energy for */ +/* loop probably works with saturation , but it should not occur anyway */ + L_min_mse = L_add(0, 0); /* init acc with absolute min mse sofar */ + FOR (col = 0; col < M / 2; col++) /* fixed to 8 elements */ + { +#ifdef ENABLE_HR_MODE + err = L_sub(cdbk[col], L_deposit_h(t[col])); /* cdbk max abs value is 2048 = 2.^11 , max nb col is 2^3 max + target is approx similar (2.^14/M)*2 = +/- 2048 , errmax is 4096 */ + L_min_mse = L_add(L_min_mse, Mpy_32_32_lc3plus(err, err)); +#else + err = sub(cdbk[col], t[col]); /* cdbk max abs value is 2048 = 2.^11 , max nb col is 2^3 max target is approx + similar (2.^14/M)*2 = +/- 2048 , errmax is 4096 */ + L_min_mse = L_mac0(L_min_mse, err, err); /* max L_min_mse is 8*4096*4096 =2.^(3+12+12) = 2.^27 */ +#endif + } + + idx = 0; move16(); + + k_ptr = M / 2; move16(); /* ptr init to second row */ + FOR (row = 1; row < R; row++) + { + /* loop probably works with saturation , but it should not occur anyway */ + + L_mse = L_add(L_min_mse, 0); /* init acc with min mse sofar , */ + FOR (col = 0; col < M / 2; col++) /* fixed to 8 elements */ + { +#ifdef ENABLE_HR_MODE + err = L_sub(cdbk[k_ptr++], L_deposit_h(t[col])); + L_mse = L_sub(L_mse, Mpy_32_32_lc3plus(err, err)); +#else + err = sub(cdbk[k_ptr++], t[col]); + L_mse = L_msu0(L_mse, err, + err); /* NB subtraction from best MSE error sofar in acc , saturation may not occur */ +#endif + } + + L_min_mse = L_sub(L_min_mse, L_max(L_mse, 0L)); /* ALWAYS update best MSE error sofar */ + + if (L_mse > 0L) /* if acc value still is positive a new lower error energy vector was found in this row */ + { + idx = row; move16(); /* update 1-8 bits idx */ + } + + /* this inner loop(always updating L_min_mse), (L_msu, if ) consumes AV 19, WC ~20 STL cycles , + compared to a conventional(L_mac, IF( ) ) AV 21 WC ~23 STL cycles per + loop */ + } + ASSERT(idx >= 0 && idx < R); + +#ifdef WMOPS + pop_wmops(); +#endif +#ifdef DYNMEM_COUNT + Dyn_Mem_Out(); +#endif + + return idx; +} + +static void first_stage_split_search( +#ifdef ENABLE_HR_MODE + const Word32 *cbk_LF, const Word32 *cbk_HF, +#else + const Word16 *cbk_LF, const Word16 *cbk_HF, +#endif + const Word16 *target, + const Word16 nbCbkEntries, Word16 *idxLF, Word16 *idxHF) +{ + /* find base index for each SCF split */ + *idxLF = stage1_base(target, cbk_LF, nbCbkEntries); + *idxHF = stage1_base((&target[M / 2]), cbk_HF, nbCbkEntries); +} + +static void processDeQuantize_stage1ScfDecStage1_fx( +#ifdef ENABLE_HR_MODE + const Word32 *cbk_LF, const Word32 *cbk_HF, +#else + const Word16 *cbk_LF, const Word16 *cbk_HF, +#endif + Word16 st1_idx0, Word16 st1_idx1, +#ifdef ENABLE_HR_MODE + Word32 *st1_vector +#else + Word16 *st1_vector +#endif + ) +{ + Counter col; + Word16 offset0, offset1; +#ifdef DYNMEM_COUNT + Dyn_Mem_In("processDeQuantize_stage1ScfDecStage1_fx", sizeof(struct { + Word16 offset0, offset1; + Counter col; + })); +#endif + + offset0 = shl_pos(st1_idx0, 3); /* mult by M/2 */ + offset1 = shl_pos(st1_idx1, 3); + FOR (col = 0; col < M / 2; col++) + { + st1_vector[col] = cbk_LF[offset0++]; move16(); + st1_vector[col + 8] = cbk_HF[offset1++]; move16(); +#ifdef ENABLE_HR_MODE + move16(); + move16(); +#endif + } +#ifdef DYNMEM_COUNT + Dyn_Mem_Out(); +#endif +} + +void downshift_w32_arr(Word32 *w32_arr, Word16 *w16_arr, Word16 shft_val, Word32 len) +{ + Word32 i; + FOR (i = 0; i < len; i++) + { + w16_arr[i] = extract_l(L_shr_pos(w32_arr[i], shft_val)); + move16(); + } + return; +} + +void round_w32tow16_arr(Word32 *w32_arr, Word16 *w16_arr,Word32 len) +{ + Word32 i; + FOR (i = 0; i < len; i++) + { + w16_arr[i] = round_fx(w32_arr[i]); + move16(); + } + return; +} + +static void processQuantize_stage1ScfEncStage1_fx(const Word16 *target_st1, +#ifdef ENABLE_HR_MODE + Word32 *st1_vector, +#else + Word16 *st1_vector, +#endif + Word16 *st1_idx0Ptr, Word16 *st1_idx1Ptr) + +{ +#ifdef WMOPS + push_wmops("processQuantize_stage1ScfEncStage1_fx"); +#endif + +#ifdef ENABLE_HR_MODE + first_stage_split_search(st1SCF0_7_base5_32x8_Q27, st1SCF8_15_base5_32x8_Q27, target_st1, SCF_STAGE1_NBCDKENTRIES, + st1_idx0Ptr, st1_idx1Ptr); + + processDeQuantize_stage1ScfDecStage1_fx(st1SCF0_7_base5_32x8_Q27, st1SCF8_15_base5_32x8_Q27, *st1_idx0Ptr, + *st1_idx1Ptr, st1_vector); +#else + first_stage_split_search(st1SCF0_7_base5_32x8_Q11, st1SCF8_15_base5_32x8_Q11, target_st1, SCF_STAGE1_NBCDKENTRIES, + st1_idx0Ptr, st1_idx1Ptr); + + processDeQuantize_stage1ScfDecStage1_fx(st1SCF0_7_base5_32x8_Q11, st1SCF8_15_base5_32x8_Q11, *st1_idx0Ptr, + *st1_idx1Ptr, st1_vector); +#endif + +#ifdef WMOPS + pop_wmops(); +#endif + + return; +} + +/* gain-shape MSE search in warped SCF-residual domain, synthesis in SCF resiudal domain allows for easy weighting */ + +static void pvq_enc_find_best_submode_pre_post_fx( +#ifdef ENABLE_HR_MODE + const Word32 *target_st2, /* this target is in the linearized warped domain , same as input to PVQ search */ +#else + const Word16 *target_st2, /* this target is in the linearized warped domain , same as input to PVQ search */ +#endif + const Word16 *enc_pulses_far, Word16 *enc_pulses_near, const Word16 *enc_pulsesA, const Word16 *enc_pulsesB, + Word16 *sub_mode_ptr, Word16 *i_gain_ptr, +#ifdef ENABLE_HR_MODE + Word32 *enc_adj_glob_warped_vec, +#else + Word16 *enc_adj_glob_warped_vec, +#endif + Word8 *scratchBuffer) /* Size = 18 * M */ +{ + + Counter L_section, idx; +#ifdef ENABLE_HR_MODE + const Word32 *search_en1shape[N_SCF_SHAPES_ST2]; +#else + const Word16 *search_en1shape[N_SCF_SHAPES_ST2]; +#endif + const Word16 *search_gainTab[N_SCF_SHAPES_ST2]; + Word16 search_n_gains[N_SCF_SHAPES_ST2]; + Word32 L_mse, L_mse_min, L_idx; + Word16 * pulses_far, *pulses_near, *pulsesAB, *pulsesA; +#ifdef ENABLE_HR_MODE + Word32 * target_w, *shape_far, *shape_near, *shapeAB, *shapeA; +#else + Word16 * target_w, *shape_far, *shape_near, *shapeAB, *shapeA; +#endif +#ifdef ENABLE_HR_MODE + Word32 tmp, err; +#else + Word16 tmp, err; +#endif + Counter i; + +#ifdef DYNMEM_COUNT +#ifdef ENABLE_HR_MODE + Dyn_Mem_In("pvq_enc_find_best_submode_pre_post_fx", sizeof(struct { + Counter i, L_section, idx; + Word32 *search_en1shape[N_SCF_SHAPES_ST2]; + Word16 *search_gainTab[N_SCF_SHAPES_ST2]; + Word16 search_n_gains[N_SCF_SHAPES_ST2]; + Word32 L_mse, L_mse_min, L_idx; + Word16 *pulses_far, *pulses_near, *pulsesAB, *pulsesA; + Word32 *target_w, *shape_far, *shape_near, *shapeAB, *shapeA; + Word32 tmp, err; + })); +#else + Dyn_Mem_In("pvq_enc_find_best_submode_pre_post_fx", sizeof(struct { + Counter i, L_section, idx; + Word16 *search_en1shape[N_SCF_SHAPES_ST2]; + Word16 *search_gainTab[N_SCF_SHAPES_ST2]; + Word16 search_n_gains[N_SCF_SHAPES_ST2]; + Word32 L_mse, L_mse_min, L_idx; + Word16 *pulses_far, *pulses_near, *pulsesAB, *pulsesA; + Word16 *target_w, *shape_far, *shape_near, *shapeAB, *shapeA; + Word16 tmp, err; + })); +#endif /* ENABLE_HR_MODE */ +#endif /* DYNMEM_COUNT */ + + pulses_near = (Word16 *)scratchAlign(scratchBuffer, 0); /* Size = 2 * M */ + + pulsesAB = (Word16 *)scratchAlign(pulses_near, sizeof(*pulses_near) * M); /* Size = 2 * M */ + + pulsesA = (Word16 *)scratchAlign(pulsesAB, sizeof(*pulsesAB) * M); /* Size = 2 * M */ + +#ifdef ENABLE_HR_MODE + target_w = (Word32 *)scratchAlign(pulsesA, sizeof(*pulsesA) * M); /* Size = 2 * M */ + + shape_near = (Word32 *)scratchAlign(target_w, sizeof(*target_w) * M); /* Size = 4 * M */ + + shapeAB = (Word32 *)scratchAlign(shape_near, sizeof(*shape_near) * M); /* Size = 4 * M */ + + shapeA = (Word32 *)scratchAlign(shapeAB, sizeof(*shapeAB) * M); /* Size = 4 * M */ +#else + target_w = (Word16 *)scratchAlign(pulsesA, sizeof(*pulsesA) * M); /* Size = 2 * M */ + + shape_near = (Word16 *)scratchAlign(target_w, sizeof(*target_w) * M); /* Size = 2 * M */ + + shapeAB = (Word16 *)scratchAlign(shape_near, sizeof(*shape_near) * M); /* Size = 2 * M */ + + shapeA = (Word16 *)scratchAlign(shapeAB, sizeof(*shapeAB) * M); /* Size = 2 * M */ +#endif + + pulses_far = (Word16 *)scratchAlign(shapeA, sizeof(*shapeA) * M); /* Size = 2 * M */ + +#ifdef ENABLE_HR_MODE + shape_far = (Word32 *)scratchAlign(pulses_far, sizeof(*pulses_far) * M); /* Size = 2 * M */ +#else + shape_far = (Word16 *)scratchAlign(pulses_far, sizeof(*pulses_far) * M); /* Size = 2 * M */ +#endif + +#ifdef WMOPS + push_wmops("pvq_enc_find_best_submode_pre_post_fx"); +#endif + + /* construct pulse vectors and en1 normalized shape vectors */ /* use shape Q in Q14 */ + basop_memmove(pulses_far, enc_pulses_far, M * sizeof(*pulses_far)); + basop_memmove(pulses_near, enc_pulses_near, M * sizeof(*pulses_near)); + basop_memmove(target_w, target_st2, M * sizeof(*target_w)); + + pvq_dec_en1_normQ14_fx(shape_near, pulses_near, sns_Kval[2][0], M); /* near outlier mode */ + pvq_dec_en1_normQ14_fx(shape_far, pulses_far, sns_Kval[3][0], M); /* far outlier mode */ + + /* regular mode(with a split), prepare vectors of full length M */ + basop_memmove(pulsesAB, enc_pulsesA, N_SETA * sizeof(*pulsesAB)); + basop_memmove(pulsesA, enc_pulsesA, N_SETA * sizeof(*pulsesA)); + + FOR (i = N_SETA; i < M; i++) + { + pulsesAB[i] = enc_pulsesB[sub(i, N_SETA)]; move16(); + } + + IF (M > N_SETA) + { + basop_memset(&pulsesA[N_SETA], 0, (M - N_SETA) * sizeof(*pulsesA)); + } + + pvq_dec_en1_normQ14_fx(shapeAB, pulsesAB, sns_Kval[0][0], M); + /* regular AB , b_pulses = 1 ;*/ /* OPT: combine with shapeA */ + + pvq_dec_en1_normQ14_fx(shapeA, pulsesA, sns_Kval[1][0], M); + /* regular A , b_pulses = 0 */ /* OPT: M-> N_SETA */ + + /* setup search structure */ + + /* now aligned with order of j {regular=0, regular_lf=1, outlier_near=2, outlier far=3} */ + + search_en1shape[0] = shapeAB; + search_gainTab[0] = sns_gaintabPtr[0]; + search_n_gains[0] = sns_gainSz[0]; /* assumes whole bits */ + + search_en1shape[1] = shapeA; + search_gainTab[1] = sns_gaintabPtr[1]; + search_n_gains[1] = sns_gainSz[1]; /* assumes whole bits */ + + search_en1shape[2] = shape_near; + search_gainTab[2] = sns_gaintabPtr[2]; + search_n_gains[2] = sns_gainSz[2]; /*assume whole bits */ + + search_en1shape[3] = shape_far; + search_gainTab[3] = sns_gaintabPtr[3]; + search_n_gains[3] = sns_gainSz[3]; /*assume whole bits */ + + /* start actual search loop */ + + /* basic raw MSE loop, */ + L_mse_min = INT32_MAX; move32(); + L_idx = L_deposit_l(-1); /* section in low 2 bits* gain idx above */ + + FOR (L_section = 0; L_section < N_SCF_SHAPES_ST2; L_section++) + { + /* raw MSE over gain and shape */ + FOR (idx = 0; idx < search_n_gains[L_section]; idx++) + { + /* MSE ( proc_target_local[i]-adjGain[i]*en1Shape[i] ) */ + + L_mse = L_deposit_l(0); + FOR (i = 0; i < M; i++) + { +#ifdef ENABLE_HR_MODE + tmp = Mpy_32_16_lc3plus(search_en1shape[L_section][i], search_gainTab[L_section][idx]); /* Q30 + 14 - 15 = Q29 */ + err = L_sub(target_w[i], tmp); /* both in Q29 */ + L_mse = L_add(L_mse, L_shr_pos(Mpy_32_32_lc3plus(err, err), 1)); /* Q29+29-31 = Q27 */ +#else + tmp = mult_r(search_gainTab[L_section][idx], search_en1shape[L_section][i]); /* Q15+14+1-16= Q14 */ + err = sub(target_w[i], tmp); /* both in Q14 */ + L_mse = L_mac0(L_mse, err, err); /* Q14+14 = Q28 */ +#endif /* Q14+14 = Q28 */ + } + + IF (L_sub(L_mse, L_mse_min) < 0) /* OPT: always update L_mse_min) */ + { + L_mse_min = L_mse; move32(); + L_idx = L_mac0(L_section, idx, 1 << 2); /* save both section and gain idx */ + } + } /* gains */ + } /*submodes*/ + + L_section = L_and(0x3L, L_idx); /* section was stored in two lowest bits */ + ASSERT(L_section >= 0 && L_section <= 3); + *i_gain_ptr = extract_l(L_shr_pos(L_idx, 2)); /*1,2,3 bit gain */ + ASSERT(*i_gain_ptr >= 0 && *i_gain_ptr <= 7); + + /* returns a scaled and transformed vector, ___EXACTLY__ as a decoder would scale it */ + ASSERT(enc_adj_glob_warped_vec != NULL); + { + /* warp/rotate search result to SCF residual domain */ +#ifdef ENABLE_HR_MODE + idct32_32_fx(search_en1shape[L_section], target_w); +#else + idct16_fx(search_en1shape[L_section], target_w); /* fwd synthesis warping */ +#endif + /* actual synthesis gain scaling in SCF-residual domain, for easy weighting analysis */ + pvq_dec_scale_vec_fx(target_w, search_gainTab[L_section][*i_gain_ptr], enc_adj_glob_warped_vec); + } + + *sub_mode_ptr = extract_l(L_section); + move16(); /* 0,1,2,3 */ + +#ifdef WMOPS + pop_wmops(); +#endif +#ifdef DYNMEM_COUNT + Dyn_Mem_Out(); +#endif + return; +} + +static void processQuantize_stage2ScfEncStage2_fx( +#ifdef ENABLE_HR_MODE + const Word32 *target_st2, Word32 *st2_vector, +#else + const Word16 *target_st2, Word16 *st2_vector, +#endif + Word32 *L_prm_idx, + Word16 submodes, Word8 *scratchBuffer) /* Size = 26 * M + 48 */ +{ /*func */ +#ifdef ENABLE_HR_MODE + Word32 *proc_target; +#else + Word16 *proc_target; +#endif + + Word16 *enc_pulses_far, *enc_pulses_near, *enc_pulsesA, *enc_pulsesB; + + Word16 *pulses_fin, *pulses_proj; + Word32 L_tmp; + + Word8 *buffer_pvq_enc_find_best_submode_pre_post_fx; + + PvqEntry_fx enc_PVQ_OA, enc_PVQ_B; + Word16 submode, i_gain, submodeMSB, submodeLSB; + Word32 * L_search_corr, *L_search_en; +#ifdef ENABLE_HR_MODE + Word16 * proc_target_lp; +#endif + +#ifdef DYNMEM_COUNT +#ifdef ENABLE_HR_MODE + Dyn_Mem_In("processQuantize_stage2ScfEncStage2_fx", sizeof(struct { + Word32 *proc_target; + Word16 *enc_pulses_far, *enc_pulses_near, *enc_pulsesA, *enc_pulsesB; + Word16 *pulses_fin, *pulses_proj; + Word32 L_tmp; + Word8 *buffer_pvq_enc_find_best_submode_pre_post_fx; + PvqEntry_fx enc_PVQ_OA, enc_PVQ_B; + Word16 submode, i_gain, submodeMSB, submodeLSB; + Word32 * L_search_corr, *L_search_en; + Word16 * proc_target_lp; + })); +#else + Dyn_Mem_In("processQuantize_stage2ScfEncStage2_fx", sizeof(struct { + Word16 *proc_target; + Word16 *enc_pulses_far, *enc_pulses_near, *enc_pulsesA, *enc_pulsesB; + Word16 *pulses_fin, *pulses_proj; + Word32 L_tmp; + Word8 *buffer_pvq_enc_find_best_submode_pre_post_fx; + PvqEntry_fx enc_PVQ_OA, enc_PVQ_B; + Word16 submode, i_gain, submodeMSB, submodeLSB; + Word32 * L_search_corr, *L_search_en; + })); +#endif /* ENABLE_HR_MODE */ +#endif /* DYNMEM_COUNT */ + +#ifdef ENABLE_HR_MODE + buffer_pvq_enc_find_best_submode_pre_post_fx = (Word8 *) scratchAlign(scratchBuffer, 0); + proc_target = (Word32 *) scratchAlign(buffer_pvq_enc_find_best_submode_pre_post_fx, sizeof(*buffer_pvq_enc_find_best_submode_pre_post_fx) * 28 * M); +#else + buffer_pvq_enc_find_best_submode_pre_post_fx = scratchAlign(scratchBuffer, 0); /* Size = 18 * M */ + proc_target = + (Word16 *)scratchAlign(buffer_pvq_enc_find_best_submode_pre_post_fx, + sizeof(*buffer_pvq_enc_find_best_submode_pre_post_fx) * 18 * M); /* Size = 2 * M */ +#endif + + enc_pulses_near = (Word16 *)scratchAlign(proc_target, sizeof(*proc_target) * M); /* Size = 2 * M */ + enc_pulsesA = (Word16 *)scratchAlign(enc_pulses_near, sizeof(*enc_pulses_near) * M); /* Size = 2 * N_SETA */ + enc_pulsesB = (Word16 *)scratchAlign(enc_pulsesA, sizeof(*enc_pulsesA) * N_SETA); /* Size = 2 * N_SETB */ + pulses_fin = (Word16 *)scratchAlign(enc_pulsesB, sizeof(*enc_pulsesB) * N_SETB); /* Size = 2 * N_SCF_SHAPES_ST2 */ + pulses_proj = + (Word16 *)scratchAlign(pulses_fin, sizeof(*pulses_fin) * N_SCF_SHAPES_ST2); /* Size = 2 * N_SCF_SHAPES_ST2 */ + L_search_corr = + (Word32 *)scratchAlign(pulses_proj, sizeof(*pulses_proj) * N_SCF_SHAPES_ST2); /* Size = 4 * N_SCF_SHAPES_ST2 */ + L_search_en = (Word32 *)scratchAlign(L_search_corr, + sizeof(*L_search_corr) * N_SCF_SHAPES_ST2); /* Size = 4 * N_SCF_SHAPES_ST2 */ + enc_pulses_far = (Word16 *)scratchAlign(L_search_en, sizeof(*L_search_en) * N_SCF_SHAPES_ST2); /* Size = 2 * M */ + +#ifdef ENABLE_HR_MODE + proc_target_lp = (Word16 *)buffer_pvq_enc_find_best_submode_pre_post_fx; /* size = 2*M */ +#endif + +#ifdef WMOPS + push_wmops("processQuantize_stage2ScfEncStage2_fx"); +#endif + + /* fixed setup for a given bitrate of 38 , no moves needed */ + /* k_far = sns_Kval[3][0]; */ + /* k_near = sns_Kval[2][0]; */ + /* kA = sns_Kval[1][0]; */ /* regular, regular_lf */ + /* kB is always 1 */ + + /* NB these search indecese do not correspond exactly to specification shape_index j */ + + pulses_fin[0] = sns_Kval[3][0]; /* far 6 */ + pulses_fin[1] = sns_Kval[2][0]; /* near 8 */ + pulses_fin[2] = sns_Kval[1][0]; /* section A 10 */ + pulses_fin[3] = sns_Kval[0][1]; /* section B 1 */ + + pulses_proj[0] = sns_Kval[3][0]; + pulses_proj[1] = 0; + pulses_proj[2] = 0; + pulses_proj[3] = 0; + + /* pre_process */ +#ifdef ENABLE_HR_MODE + dct32_fx(target_st2, proc_target); /* enc analysis */ + downshift_w32_arr(proc_target, proc_target_lp, 16, M); + + /* get the initial four integer shape candidate vectors, no normalization at this stage */ + pvq_enc_search_fx(proc_target_lp, enc_pulses_far, enc_pulses_near, enc_pulsesA, enc_pulsesB, L_search_corr, + L_search_en, pulses_fin, pulses_proj, M, N_SETA); +#else + Word32 target_st2_32[M]; Word32 proc_target_32[M]; int i; + + FOR (i = 0; i < M; i++) + { + target_st2_32[i] = L_shl_pos(target_st2[i], 16); + } + + dct32_fx(target_st2_32, proc_target_32); /* enc analysis */ + + downshift_w32_arr(proc_target_32, proc_target, 16, M); + + /* get the initial four integer shape candidate vectors, no normalization at this stage */ + pvq_enc_search_fx(proc_target, enc_pulses_far, enc_pulses_near, enc_pulsesA, enc_pulsesB, L_search_corr, + L_search_en, pulses_fin, pulses_proj, M, N_SETA); +#endif + + /* scale with gains a after a unit energy fwd transform */ + /* apply transform to each candidate shape vector priot to gain-shape search loop */ + submode = submodes; /* used as input solely to debug/unit test a specific shape mode */ + + /*target should be in a linearized residual domain target */ + /* search pre, synthesis post*/ + pvq_enc_find_best_submode_pre_post_fx(proc_target, enc_pulses_far, enc_pulses_near, enc_pulsesA, enc_pulsesB, + &submode, &i_gain, st2_vector, + buffer_pvq_enc_find_best_submode_pre_post_fx); /* Q14 tr out */ + + /* send parameters to multiplexor as a series/vector of Long Words */ + /* 0 : 0..3 submode */ + /* 1 : 0..7 gain_ind */ + /* 2 : 0..1 LeadSign ind */ + /* 3 : 25 bit MPVQ index outl_near or A part */ + /* 4 : 3.7 to 21 bits MPVQ index B part OR -2 */ + + L_prm_idx[0] = L_deposit_l(submode); /* complete submode fwd'ed to ari_codec as 0,1,2,3 */ + + submodeMSB = shr_pos(submode, 1); /* LSB of submode , sent as main submode bit */ + submodeLSB = s_and(submode, 0x1); /* LSB of submode */ /* sent via shape param */ + + /* gain, shape indicese , incl. calls to MPVQ indexing */ + IF (submodeMSB == 0) + { /* regular modes:: j=0(reg=AB) or 1(reg_lf A) */ /* regular mode, with two or one shape indices */ + + /* assume regular_lf part , shape_j == 1 */ + enc_PVQ_OA = + mpvq_index_fx(enc_pulsesA, N_SETA, sns_Kval[submode][0]); /* o : leading_sign_index, index, size, k_val */ + L_prm_idx[2] = L_deposit_l(enc_PVQ_OA.lead_sign_ind); /*LS set A */ + + ASSERT(enc_PVQ_OA.size == (UWord32)sns_MPVQ_Sz[submode][0]); + L_prm_idx[3] = L_add(0L, (Word32)enc_PVQ_OA.index); /* MPVQ shape index set A fractional */ + + /* section B always have low indexing dynamics and is combined into one joint single index */ + IF (submodeLSB == 0) + { /* regular AB , shape_j == 0*/ + L_prm_idx[1] = L_deposit_l(i_gain); /* full established gain idx fwd'ed */ /* 2 possible values */ + enc_PVQ_B = mpvq_index_fx(enc_pulsesB, N_SETB, 1); + ASSERT(((enc_PVQ_B.size << 1)) == + (sns_MPVQ_Sz[submode][1])); /* two lowest indeces indicate all_zero B section */ + + L_tmp = L_shl_pos((Word32)enc_PVQ_B.index, 1); /* 2*section B MPVQ index */ + L_prm_idx[4] = L_add(L_tmp, enc_PVQ_B.lead_sign_ind); move32(); /* add joint section B and LS index */ + + ASSERT(L_prm_idx[4] >= 0 && L_prm_idx[4] < (Word32)sns_MPVQ_Sz[submode][0]); + } + ELSE + { + L_prm_idx[1] = L_deposit_l(i_gain); + /* MSBs of established gain idx */ /* 2 or 4 total possible values */ + L_prm_idx[4] = L_deposit_l(-2); + } + } + ELSE + { + /* outlier modes shape_j= 2(near, LSB=0) or 3(far, LSB=1) */ + + IF (submodeLSB == 0) + { + L_prm_idx[1] = L_deposit_l(i_gain); /* established gain idx */ /* 4 possible values */ + enc_PVQ_OA = mpvq_index_fx(enc_pulses_near, M, + sns_Kval[submode][0]); /* o : leading_sign_index, index, size, k_val */ + ASSERT(enc_PVQ_OA.size == sns_MPVQ_Sz[submode][0]); + L_prm_idx[3] = L_add(0L, enc_PVQ_OA.index); /* MPVQ index fractional bits */ + L_prm_idx[4] = L_deposit_l(-1); /* no gain LSBs */ + } + ELSE + { + L_prm_idx[1] = L_deposit_l(i_gain); /* established gain idx MSBs */ /* all 4 or 8 possible values */ + enc_PVQ_OA = mpvq_index_fx(enc_pulses_far, M, + sns_Kval[submode][0]); /* o : leading_sign_index, index, size, k_val */ + ASSERT(enc_PVQ_OA.size == sns_MPVQ_Sz[submode][0]); + L_prm_idx[3] = L_add(0L, enc_PVQ_OA.index); /* MPVQ index fractional bits */ + L_prm_idx[4] = L_deposit_l(-2); /* */ + } + L_prm_idx[2] = L_deposit_l(enc_PVQ_OA.lead_sign_ind); /* LS shape single bit */ + } + +#ifdef WMOPS + pop_wmops(); +#endif +#ifdef DYNMEM_COUNT + Dyn_Mem_Out(); +#endif + return; +} + +static Word16 scfdec_stage2_fx( /* o: ber flag */ + const Word32 *L_prm_idx, /* set to -1 if not used */ +#ifdef ENABLE_HR_MODE + Word32 * st2_vector, /*o: Q14 */ +#else + Word16 * st2_vector, /*o: Q14 */ +#endif + Word8 * scratchBuffer) +{ + /* MPVQ deindexing, gainscaling transform and transform */ +#ifdef ENABLE_HR_MODE + Dyn_Mem_Deluxe_In( + Word16 submode; + Word16 submodeLSB, submodeMSB; + Word16 gValQ13; + Word16 idxB; + Word16 maxK; + Word16 BER_dec; + Word16 *dec_pulses; + Word32 *dec_en1_vec; + Word32 *dec_adj_glob_vec; + ); +#else + Dyn_Mem_Deluxe_In( + Word16 submode; + Word16 submodeLSB, submodeMSB; + Word16 gValQ13; + Word16 idxB; + Word16 maxK; + Word16 BER_dec; + Word16 *dec_pulses; + Word16 *dec_en1_vec; + Word16 *dec_adj_glob_vec; + ); +#endif + +#ifdef WMOPS + push_wmops("scfdec_stage2_fx"); +#endif + + dec_pulses = (Word16 *)scratchAlign(scratchBuffer, 0); /* Size = 2 * M = 32 bytes */ +#ifdef ENABLE_HR_MODE + dec_en1_vec = (Word32 *)scratchAlign(dec_pulses, sizeof(*dec_pulses) * M); /* Size = 2 * M = 32 bytes */ + dec_adj_glob_vec = (Word32 *)scratchAlign(dec_en1_vec, sizeof(*dec_en1_vec) * M); /* Size = 2 * M = 32 bytes */ +#else + dec_en1_vec = (Word16 *)scratchAlign(dec_pulses, sizeof(*dec_pulses) * M); /* Size = 2 * M = 32 bytes */ + dec_adj_glob_vec = (Word16 *)scratchAlign(dec_en1_vec, sizeof(*dec_en1_vec) * M); /* Size = 2 * M = 32 bytes */ +#endif + + /* get submode */ + submode = extract_l(L_prm_idx[0]); /* 0..3 */ + + submodeLSB = s_and(submode, 0x1); + submodeMSB = shr_pos(submode, 1); + + /* get initial adjustment gain vector for regular, outl_near */ + ASSERT(L_prm_idx[1] >= 0 && L_prm_idx[1] < sns_gainSz[submode]); + gValQ13 = sns_gaintabPtr[submode][L_prm_idx[1]]; + ASSERT(gValQ13 >= 0); + + /* gain, shape indices, incl.calls to MPVQ deindexing */ + IF (submodeMSB != 0) + { + /* outlier_near or outlier_far mode decoding */ + maxK = sns_Kval[submode][0]; move16(); + BER_dec = pvq_dec_deidx_fx(dec_pulses, maxK, M, extract_l(L_prm_idx[2]), (UWord32)L_prm_idx[3]); + } + ELSE + { /* regular mode, with potentially two shape indices */ + + maxK = sns_Kval[submode][0]; move16(); + BER_dec = pvq_dec_deidx_fx(dec_pulses, maxK, N_SETA, extract_l(L_prm_idx[2]), (UWord32)L_prm_idx[3]); + + IF (submodeLSB == 0) + { + idxB = extract_l(L_prm_idx[4]); /* 0..11 */ + ASSERT(idxB >= 0 && idxB < (Word16)sns_MPVQ_Sz[0][1]); + BER_dec |= pvq_dec_deidx_fx(&(dec_pulses[N_SETA]), sns_Kval[submode][1], N_SETB, s_and(idxB, 0x1), + (UWord32)L_deposit_l(shr_pos(idxB, 1))); + /* maxK does not need to be increased as set B is not stacked */ + } + ELSE + { /* LSB gain bit already parsed */ + ASSERT(L_prm_idx[4] < 0); + basop_memset(&dec_pulses[N_SETA], 0, (N_SETB) * sizeof(*dec_pulses)); + } + } + + /* normalize decoded integer vector , exactly as on encoder side !! */ + pvq_dec_en1_normQ14_fx(dec_en1_vec, dec_pulses, maxK, M); + +#ifdef ENABLE_HR_MODE + idct32_32_fx(dec_en1_vec, dec_adj_glob_vec); +#else + idct16_fx(dec_en1_vec, dec_adj_glob_vec); /* fwd warping in unscaled domain */ +#endif + + /* scaling aligend with encoder search */ + pvq_dec_scale_vec_fx(dec_adj_glob_vec, gValQ13, st2_vector); + +#ifdef WMOPS + pop_wmops(); +#endif + Dyn_Mem_Deluxe_Out(); + return BER_dec; +} + +void processSnsQuantizeScfEncoder_fx(Word16 scf[], /* i: input scf M */ + Word32 *L_prm_idx, /* o: indeces . negative == unused */ +#ifdef ENABLE_HR_MODE + Word32 *scf_q, /* o: quantized scf M */ +#else + Word16 *scf_q, /* o: quantized scf M */ +#endif + Word8 * scratchBuffer) /* Size = 28 * M + 52 */ +{ +#ifdef ENABLE_HR_MODE + Dyn_Mem_Deluxe_In( + Word32 *target_st2; + Word16 *st1_idx; /* stage 1 indices */ + Word8 * buffer_processQuantize_stage2ScfEncStage2_fx; + Counter col; + ); +#else + Dyn_Mem_Deluxe_In( + Word16 *target_st2; + Word16 *st1_idx; /* stage 1 indices */ + Word8 * buffer_processQuantize_stage2ScfEncStage2_fx; + Counter col; + ); +#endif + +#ifdef ENABLE_HR_MODE + target_st2 = (Word32 *)scratchAlign(scratchBuffer, 0); /* Size = 2 * M */ +#else + target_st2 = (Word16 *)scratchAlign(scratchBuffer, 0); /* Size = 2 * M */ +#endif + st1_idx = (Word16 *)scratchAlign(target_st2, sizeof(*target_st2) * M); /* Size = 2 * 2 */ + buffer_processQuantize_stage2ScfEncStage2_fx = (Word8 *)scratchAlign(st1_idx, sizeof(*st1_idx) * M); + /* Size = 26 * M + 48 */ + + /* TBD needs update */ + + /* 1st stage trained VQ */ + processQuantize_stage1ScfEncStage1_fx(scf, scf_q, &st1_idx[0], &st1_idx[1]); + L_prm_idx[0] = L_deposit_l(st1_idx[0]); + L_prm_idx[1] = L_deposit_l(st1_idx[1]); + +/* 2nd stage PVQ-based SCF quantizer */ + FOR (col = 0; col < M; col++) + { +#ifdef ENABLE_HR_MODE + target_st2[col] = L_sub(L_deposit_h(scf[col]), scf_q[col]); +#else + target_st2[col] = sub(scf[col], scf_q[col]); +#endif + } + + processQuantize_stage2ScfEncStage2_fx(target_st2, scf_q, &L_prm_idx[2], VQMODES26, /* 0xF means all submodes */ + buffer_processQuantize_stage2ScfEncStage2_fx); /* PVQ in stage 2 */ + Dyn_Mem_Deluxe_Out(); +} + +Word16 processSnsQuantizeScfDecoder_fx( /* o: BER flag */ + Word32 *L_prm_idx, /* i: indeces */ +#ifdef ENABLE_HR_MODE + Word32 scf_q[], +#else + Word16 scf_q[], +#endif + Word8 *scratchBuffer) /* o: M */ +{ + Dyn_Mem_Deluxe_In( + Word16 BER_flag; + ); + + /* Decode First Stage */ +#ifdef ENABLE_HR_MODE + processDeQuantize_stage1ScfDecStage1_fx(st1SCF0_7_base5_32x8_Q27, st1SCF8_15_base5_32x8_Q27, + extract_l(L_prm_idx[0]), extract_l(L_prm_idx[1]), scf_q); +#else + processDeQuantize_stage1ScfDecStage1_fx(st1SCF0_7_base5_32x8_Q11, st1SCF8_15_base5_32x8_Q11, + extract_l(L_prm_idx[0]), extract_l(L_prm_idx[1]), scf_q); +#endif + + /* Decode Second Stage */ + BER_flag = scfdec_stage2_fx(&(L_prm_idx[2]), scf_q, scratchBuffer); + + Dyn_Mem_Deluxe_Out(); + return BER_flag; +} + diff --git a/lib_lc3plus/tinywavein_c.h b/lib_lc3plus/tinywavein_c.h new file mode 100644 index 0000000000000000000000000000000000000000..32789e31409c8ed4c633a53e464413122ee7d825 --- /dev/null +++ b/lib_lc3plus/tinywavein_c.h @@ -0,0 +1,603 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.5 * +* Low Complexity Communication Codec Plus (LC3plus) * +* * +* Copyright licence is solely granted through ETSI Intellectual Property * +* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * +* estoppel or otherwise. * +******************************************************************************/ + +#ifndef __TINYWAVEIN_C_H__ +#define __TINYWAVEIN_C_H__ + +/*#define SUPPORT_BWF*/ + +#include +#include +#include + +#if defined(__i386__) || defined(_M_IX86) || defined(__x86_64__) || defined(_M_X64) || defined(__arm__) || \ + defined(__aarch64__) +#define __TWI_LE /* _T_iny _W_ave _I_n _L_ittle _E_ndian */ +#endif + +#if defined(__POWERPC__) +#define __TWI_BE /* _T_iny _W_ave _I_n _B_ig _E_ndian */ +#endif + +#if !defined(__TWI_LE) && !defined(__TWI_BE) +#error unknown processor +#endif + +#define __TWI_SUCCESS (0) +#define __TWI_ERROR (-1) + +#ifdef SUPPORT_BWF +typedef struct +{ + float loudnessVal; + float loudnessRange; + float maxTruePeakLevel; + float maxMomentaryLoudnes; + float maxShortTermLoudness; +} WAVEIN_LOUDNESSINFO; +#endif + +typedef struct __tinyWaveInHandle +{ + FILE * theFile; + fpos_t dataChunkPos; + unsigned int position; + unsigned int length; + unsigned int bps; +#ifdef SUPPORT_BWF + WAVEIN_LOUDNESSINFO *loudnessInfo; +#endif +} __tinyWaveInHandle, WAVEFILEIN; + +typedef struct +{ + short compressionCode; + short numberOfChannels; + unsigned int sampleRate; + unsigned int averageBytesPerSecond; + short blockAlign; + short bitsPerSample; + /* short extraFormatBytes ; */ +} SWavInfo; + +#ifdef SUPPORT_BWF +typedef struct +{ + unsigned char description[256]; + unsigned char originator[32]; + unsigned char originatorReference[32]; + unsigned char originatorDate[10]; /* ASCII: <> */ + unsigned char originationTime[8]; /* ASCII: <> */ + unsigned int timeReferenceLow; + unsigned int timeReferenceHigh; + unsigned short version; + unsigned char UMID[64]; /* Binary Bytes of SMPTE UMID */ + + signed short loudnessVal; + signed short loudnessRange; + signed short maxTruePeakLevel; + signed short maxMomentaryLoudnes; + signed short maxShortTermLoudness; + + unsigned char Reserved[180]; + + unsigned char codingHistory; /* ASCII: <> */ +} SBwfWav; +#endif + +typedef struct +{ + char chunkID[4]; + unsigned int chunkSize; + /* long dataOffset ; */ /* never used */ +} SChunk; + +/* local wrapper, always returns correct endian */ +static size_t fread_LE(void *ptr, size_t size, size_t nmemb, FILE *stream); + +#ifdef __TWI_BE +static short BigEndian16(short v); +static int BigEndian32(int v); +#endif + +/*! + * \brief Read header from a WAVEfile. Host endianess is handled accordingly. + * \fp filepointer of type FILE*. + * \wavinfo SWavInfo struct where the decoded header info is stored into. + * \return 0 on success and non-zero on failure. + * + */ +static WAVEFILEIN *OpenWav(const char *filename, unsigned int *samplerate, short *channels, unsigned int *samplesInFile, + short *bps) +{ + WAVEFILEIN *self; + + SChunk fmt_chunk, data_chunk; + int offset; + unsigned int tmpSize; + char tmpFormat[4]; + SWavInfo wavinfo = {0, 0, 0, 0, 0, 0}; + + self = (WAVEFILEIN *)calloc(1, sizeof(WAVEFILEIN)); + if (!self) + goto bail; /* return NULL; */ + + if (!filename) + goto bail; + if (!samplerate) + goto bail; + if (!channels) + goto bail; + if (!samplesInFile) + goto bail; + if (!bps) + goto bail; + + self->theFile = fopen(filename, "rb"); + if (!self->theFile) + goto bail; + + /* read RIFF-chunk */ + if (fread(tmpFormat, 1, 4, self->theFile) != 4) + { + goto bail; + } + + if (strncmp("RIFF", tmpFormat, 4)) + { + goto bail; + } + + /* Read RIFF size. Ignored. */ + fread_LE(&tmpSize, 4, 1, self->theFile); + + /* read WAVE-chunk */ + if (fread(tmpFormat, 1, 4, self->theFile) != 4) + { + goto bail; + } + + if (strncmp("WAVE", tmpFormat, 4)) + { + goto bail; + } + + /* read format/bext-chunk */ + if (fread(fmt_chunk.chunkID, 1, 4, self->theFile) != 4) + { + goto bail; + } + +#ifdef SUPPORT_BWF + /* test for bext-chunk */ + if (!strncmp("bext", fmt_chunk.chunkID, 4)) + { + /*unsigned int i;*/ + unsigned int bextSize = 0; + + if (fread_LE(&bextSize, 1, 4, self->theFile) != 4) + { + goto bail; + } + + self->loudnessInfo = (WAVEIN_LOUDNESSINFO *)calloc(1, sizeof(WAVEIN_LOUDNESSINFO)); + + if (bextSize >= 602) + { /* minimum size bext-data, w/o 'CodingHistory' */ + int i; + signed short readBuf = 0; + signed int nulbuf = 0; + + /* first skip all descriptive data */ + for (i = 0; i < 412; i++) + { + if (fread_LE(&nulbuf, 1, 1, self->theFile) != 1) + { + goto bail; + } + bextSize -= 1; + } + /* second, read loudness data */ + fread_LE(&readBuf, 2, 1, self->theFile); + bextSize -= 2; + self->loudnessInfo->loudnessVal = (float)readBuf * 0.01f; + + fread_LE(&readBuf, 2, 1, self->theFile); + bextSize -= 2; + self->loudnessInfo->loudnessRange = (float)readBuf * 0.01f; + + fread_LE(&readBuf, 2, 1, self->theFile); + bextSize -= 2; + self->loudnessInfo->maxTruePeakLevel = (float)readBuf * 0.01f; + + fread_LE(&readBuf, 2, 1, self->theFile); + bextSize -= 2; + self->loudnessInfo->maxMomentaryLoudnes = (float)readBuf * 0.01f; + + fread_LE(&readBuf, 2, 1, self->theFile); + bextSize -= 2; + self->loudnessInfo->maxShortTermLoudness = (float)readBuf * 0.01f; + + /* skip reserved data */ + for (i = 0; i < 180; i++) + { + if (fread_LE(&nulbuf, 1, 1, self->theFile) != 1) + { + goto bail; + } + bextSize -= 1; + } + } + + /* skip remaining data */ + while (bextSize) + { + int nulbuf; + if (fread_LE(&nulbuf, 1, 1, self->theFile) != 1) + { + goto bail; + } + bextSize -= 1; + } + + /* read next chunk header */ + if (fread(fmt_chunk.chunkID, 1, 4, self->theFile) != 4) + { + goto bail; + } + } +#endif + + /* skip some potential chunks up to fmt chunk */ + + while (strncmp("fmt ", fmt_chunk.chunkID, 4) != 0) + { + unsigned int chunkSize = 0; + + if (fread_LE(&chunkSize, 1, 4, self->theFile) != 4) + { + goto bail; + } + + /* skip chunk data */ + while (chunkSize) + { + int nulbuf; + if (fread_LE(&nulbuf, 1, 1, self->theFile) != 1) + { + goto bail; + } + chunkSize -= 1; + } + + /* read next chunk header */ + if (fread(fmt_chunk.chunkID, 1, 4, self->theFile) != 4) + { + goto bail; + } + } + + /* go on with fmt-chunk */ + if (strncmp("fmt ", fmt_chunk.chunkID, 4)) + { + goto bail; + } + + if (fread_LE(&fmt_chunk.chunkSize, 4, 1, self->theFile) != 1) + { /* should be 16 for PCM-format (uncompressed) */ + goto bail; + } + + + /* read info */ + fread_LE(&(wavinfo.compressionCode), 2, 1, self->theFile); + fread_LE(&(wavinfo.numberOfChannels), 2, 1, self->theFile); + fread_LE(&(wavinfo.sampleRate), 4, 1, self->theFile); + fread_LE(&(wavinfo.averageBytesPerSecond), 4, 1, self->theFile); + fread_LE(&(wavinfo.blockAlign), 2, 1, self->theFile); + fread_LE(&(wavinfo.bitsPerSample), 2, 1, self->theFile); + + if (wavinfo.compressionCode == -2) + { + fseek(self->theFile, 8, SEEK_CUR); // skip channel mask + fread_LE(&(wavinfo.compressionCode), 2, 1, self->theFile); // part of GUID + fseek(self->theFile, 14, SEEK_CUR); // skip rest of GUID + offset = fmt_chunk.chunkSize - 40; + } + else + offset = fmt_chunk.chunkSize - 16; + + if (wavinfo.compressionCode == 0x01) + { + if ((wavinfo.bitsPerSample != 16) && (wavinfo.bitsPerSample != 24) && (wavinfo.bitsPerSample != 32)) + /* we do only support 16,24 and 32 bit PCM audio */ + goto bail; + } + else + { + /* if(wavinfo.bitsPerSample != 32) */ + printf("compressioncode: %02x\n", wavinfo.compressionCode); + puts("Error! We only support 16,24 and 32 bit PCM audio"); + exit(1); + goto bail; + } + + /* Skip rest of fmt header if any. */ + for (; offset > 0; offset--) + { + fread(&tmpSize, 1, 1, self->theFile); + } + + do + { + + /* Read data chunk ID */ + if (fread(data_chunk.chunkID, 1, 4, self->theFile) != 4) + { + goto bail; + } + + /* Read chunk length. */ + + if (fread_LE(&offset, 4, 1, self->theFile) != 1) + { + goto bail; + } + + /* Check for data chunk signature. */ + if (strncmp("data", data_chunk.chunkID, 4) == 0) + { + data_chunk.chunkSize = offset; + break; + } + + /* unused 1 byte present, if size is odd */ + /* see https://www.daubnet.com/en/file-format-riff */ + if (offset % 2) + { + offset++; + } + + /* Jump over non data chunk. */ + for (; offset > 0; offset--) + { + fread(&tmpSize, 1, 1, self->theFile); + } + + } while (!feof(self->theFile)); + + /* success so far */ + *samplerate = wavinfo.sampleRate; + *channels = wavinfo.numberOfChannels; + *samplesInFile = data_chunk.chunkSize / wavinfo.numberOfChannels; + *samplesInFile /= ((wavinfo.bitsPerSample + 7) / 8); + *bps = wavinfo.bitsPerSample; + + self->position = 0; + self->bps = wavinfo.bitsPerSample; + self->length = *samplesInFile * wavinfo.numberOfChannels; + + fgetpos(self->theFile, &self->dataChunkPos); + + return self; + +bail: + free(self); + return NULL; +} + +#ifdef SUPPORT_BWF +static void ReadBWF(WAVEFILEIN *self, WAVEIN_LOUDNESSINFO **wavInLoudness) +{ + *wavInLoudness = self->loudnessInfo; +} +#endif + +static int __ReadSample16(WAVEFILEIN *self, int *sample) +{ + size_t cnt; + short v = 0; + + cnt = fread(&v, 2, 1, self->theFile); + + if (cnt != 1) + { + return __TWI_ERROR; + } + + self->position += 1; + +#ifdef __TWI_BE + v = BigEndian16(v); +#endif + *sample = v; + return __TWI_SUCCESS; +} + +static int __ReadSample24(WAVEFILEIN *self, int *sample) +{ + size_t cnt; + int v = 0; + + cnt = fread(&v, 3, 1, self->theFile); + + if (cnt != 1) + { + return __TWI_ERROR; + } + + self->position += 1; + +#ifdef __TWI_BE + v = BigEndian32(v); +#endif + + if (v >= 0x800000) + { + v |= 0xff000000; + } + + *sample = v; + + return __TWI_SUCCESS; +} + +static int __ReadSample32(WAVEFILEIN *self, int *sample) +{ + size_t cnt; + int v = 0; + + cnt = fread(&v, 4, 1, self->theFile); + + if (cnt != 1) + { + return __TWI_ERROR; + } + + self->position += 1; + +#ifdef __TWI_BE + v = BigEndian32(v); +#endif + + *sample = v >> 8; + + return __TWI_SUCCESS; +} + +static int __ReadSampleInternal(WAVEFILEIN *self, int *sample, int scale) +{ + int err; + + if (!self) + { + return __TWI_ERROR; + } + + switch (scale) + { + + case 16: err = __ReadSample16(self, sample); break; + + case 24: err = __ReadSample24(self, sample); break; + + case 32: err = __ReadSample32(self, sample); break; + + default: err = __TWI_ERROR; break; + } + + return err; +} + +/* this function returns normalized values in the range +8388607..-8388608 */ +static int ReadWavInt(WAVEFILEIN *self, int sampleBuffer[], unsigned int nSamplesToRead, unsigned int *nSamplesRead) +{ + unsigned int i; + int err = __TWI_SUCCESS; + *nSamplesRead = 0; + + if (!sampleBuffer) + { + return __TWI_ERROR; + } + + /* check if we have enough samples left, if not, + set nSamplesToRead to number of samples left. */ + if (self->position + nSamplesToRead > self->length) + { + nSamplesToRead = self->length - self->position; + } + + for (i = 0; i < nSamplesToRead; i++) + { + + int tmp; + err = __ReadSampleInternal(self, &tmp, self->bps); + if (err != __TWI_SUCCESS) + { + return err; + } + sampleBuffer[i] = tmp; + *nSamplesRead += 1; + } + + return __TWI_SUCCESS; +} + +static int CloseWavIn(WAVEFILEIN *self) +{ + if (self) + { + if (self->theFile) + { + fclose(self->theFile); + } + } + free(self); + + return __TWI_SUCCESS; +} +/* +static int ResetWavIn(WAVEFILEIN* self) +{ + if (self) { + if (self->theFile) { + fsetpos(self->theFile, &self->dataChunkPos); + self->position = 0; + } + } + return __TWI_SUCCESS; +} +*/ +/*------------- local subs ----------------*/ + +static size_t fread_LE(void *ptr, size_t size, size_t nmemb, FILE *stream) +{ +#ifdef __TWI_LE + return fread(ptr, size, nmemb, stream); +#endif +#ifdef __TWI_BE + + unsigned char x[sizeof(int)]; + unsigned char *y = (unsigned char *)ptr; + int i; + int len; + + len = fread(x, size, nmemb, stream); + + for (i = 0; i < size * nmemb; i++) + { + *y++ = x[size * nmemb - i - 1]; + } + + return len; +#endif +} + +#ifdef __TWI_BE +static short BigEndian16(short v) +{ + short a = (v & 0x0ff); + short b = (v & 0x0ff00) >> 8; + + return a << 8 | b; +} + +static int BigEndian32(int v) +{ + int a = (v & 0x0ff); + int b = (v & 0x0ff00) >> 8; + int c = (v & 0x0ff0000) >> 16; + int d = (v & 0xff000000) >> 24; + + return a << 24 | b << 16 | c << 8 | d; +} +#endif + +#endif /* __TINYWAVEIN_C_H__ */ diff --git a/lib_lc3plus/tinywaveout_c.h b/lib_lc3plus/tinywaveout_c.h new file mode 100644 index 0000000000000000000000000000000000000000..67225427097acbd130a6f03b725338666ca73ddd --- /dev/null +++ b/lib_lc3plus/tinywaveout_c.h @@ -0,0 +1,889 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.5 * +* Low Complexity Communication Codec Plus (LC3plus) * +* * +* Copyright licence is solely granted through ETSI Intellectual Property * +* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * +* estoppel or otherwise. * +******************************************************************************/ + +#ifndef __TINYWAVEOUT_C_H__ +#define __TINYWAVEOUT_C_H__ + +/*#define TWO_SUPPORT_BWF*/ + +#include +#include +#include +#include +#ifdef TWO_SUPPORT_BWF +#include +#endif + +/***** Interface *********************************************************/ + +#ifndef TWO_UINT64 + #if !(defined(WIN32)) + #include + #define TWO_UINT64 uint64_t + #else + #define TWO_UINT64 unsigned __int64 + #endif +#endif + +typedef struct WAVEFILEOUT WAVEFILEOUT; +#ifdef TWO_SUPPORT_BWF +typedef struct WAVEOUT_LOUDNESSINFO WAVEOUT_LOUDNESSINFO; +#endif + +#define __TWO_SUCCESS (0) +#define __TWO_ERROR (-1) + +static WAVEFILEOUT* CreateWav( + const char *fileName, + const unsigned int sampleRate, + const unsigned int numChannels, + const unsigned int bps + ); + +#ifdef TWO_SUPPORT_BWF +static WAVEFILEOUT* CreateWavBWF( + const char *fileName, + const unsigned int sampleRate, + const unsigned int numChannels, + const unsigned int bps, + const WAVEOUT_LOUDNESSINFO *hBwfData + ); +#endif + +/* this function expects values in the 16 bit range +32767..-32768 */ +static int WriteWavShort( + WAVEFILEOUT* self, + short sampleBuffer[], + unsigned int nSamples + ); + +/* this function expects values in the 24 bit range +8388607..-8388608 */ +static int WriteWavLong( + WAVEFILEOUT* self, + int sampleBuffer[], + unsigned int nSamples + ); + +/* this function expects normalized values in the range +-1.0f */ +static int WriteWavFloat( + WAVEFILEOUT* self, + float sampleBuffer[], + unsigned int nSamples + ); + +static int CloseWav(WAVEFILEOUT* self); +#ifdef TWO_SUPPORT_BWF +static int CloseWavBWF(WAVEFILEOUT* self, WAVEOUT_LOUDNESSINFO bextData); +#endif + +/***** Implementation *********************************************************/ + +#if defined (__i386__) || defined (_M_IX86) || defined (_M_X64) || defined (__x86_64__) || defined (__arm__) || defined (__xtensa__) || defined (__aarch64__) || defined (__EMSCRIPTEN__) +#define __TWO_LE /* _T_iny _W_ave _O_ut _L_ittle _E_ndian */ +#endif + +#if defined (__POWERPC__) +#define __TWO_BE /* _T_iny _W_ave _O_ut _B_ig _E_ndian */ +#endif + +#if defined (__sparc__) +#define __TWO_BE /* _T_iny _W_ave _O_ut _B_ig _E_ndian */ +#endif + +#if ! defined (__TWO_LE) && ! defined (__TWO_BE) +#error unknown processor +#endif + +/*--- local types/structs ----------------------------------*/ + +#if defined(_MSC_VER) + #pragma pack(push, 1) +#else + #pragma pack(1) +#endif + + +#ifdef TWO_SUPPORT_BWF +struct WAVEOUT_LOUDNESSINFO { + float loudnessVal; + float loudnessRange; + float maxTruePeakLevel; + float maxMomentaryLoudnes; + float maxShortTermLoudness; +}; +#endif + + +typedef struct __tinyWaveOutHeader +{ + unsigned int riffType; /* 'RIFF/RF64' */ + unsigned int riffSize; /* file size/-1 */ + unsigned int waveType; /* 'WAVE' */ +} __tinyWaveOutHeader; + +typedef struct __tinyWaveOutDs64Chunk +{ + unsigned int formatType; /* = 'JUNK/ds64' */ + unsigned int formatSize; /* size info */ + TWO_UINT64 riffSize64; + TWO_UINT64 dataSize64; + TWO_UINT64 sampleCount64; + unsigned int tableLength; /* optional tables, always 0 for tinywaveout */ + /* here: optional tables */ +} __tinyWaveOutDs64Chunk; + +#ifdef TWO_SUPPORT_BWF +typedef struct __tinyWaveOutBextChunk +{ + unsigned int formatType; /* = 'bext' */ + unsigned int formatSize; /* size info */ + + unsigned char description[256]; + unsigned char originator[32]; + unsigned char originatorReference[32]; + unsigned char originatorDate[10]; /* ASCII: <> */ + unsigned char originationTime[8]; /* ASCII: <> */ + unsigned int timeReferenceLow; + unsigned int timeReferenceHigh; + unsigned short version; + unsigned char UMID[64]; /* Binary Bytes of SMPTE UMID */ + + signed short loudnessVal; + signed short loudnessRange; + signed short maxTruePeakLevel; + signed short maxMomentaryLoudnes; + signed short maxShortTermLoudness; + + unsigned char Reserved[180]; + + unsigned char codingHistory; /* ASCII: <> - undefined length! */ + /* for variable length, mve this out of this struct */ +} __tinyWaveOutBextChunk; +#endif + +typedef struct __tinyWaveOutFmtChunk +{ + unsigned int formatType; + unsigned int formatSize; + + unsigned short formatTag; + unsigned short numChannels; + unsigned int sampleRate; + unsigned int bytesPerSecond; + unsigned short blockAlignment; + unsigned short bitsPerSample; + + /* wav fmt ext hdr here */ +} __tinyWaveOutFmtChunk; + +typedef struct __tinyWaveOutDataChunk +{ + unsigned int dataType; + unsigned int dataSize; + +} __tinyWaveOutDataChunk; + + +struct WAVEFILEOUT { + /* for reasons of memory alignment, have 64 bit data types first */ + TWO_UINT64 dataSize; + TWO_UINT64 dataSizeLimit; /* maximum size for data chunk for 4 GB files */ + TWO_UINT64 dataSizeLimit64; /* maximum size for data chunk for 2^64 B addressable files */ + TWO_UINT64 clipCount; + FILE* theFile; + unsigned int junkChunkOffset; + unsigned int fmtChunkOffset; +#ifdef TWO_SUPPORT_BWF + unsigned int bextChunkOffset; +#endif + unsigned int dataChunkOffset; + unsigned int bps; + + /* only needed for RF64: */ + unsigned int blockAlign; /* only needed for close() of ds64 chunk */ +}; + + +/*--- local protos --------------------------------------------------*/ +static __inline unsigned int BigEndian32(char, char, char, char); +static __inline unsigned int LittleEndian32(unsigned int); +static __inline unsigned int LittleEndian32s(int); +static __inline short LittleEndian16(short); +static __inline TWO_UINT64 LittleEndian64(TWO_UINT64); +#ifdef TWO_SUPPORT_BWF +static unsigned int EncodeLoudness(float); +#endif +static __inline int __dataSizeChk( WAVEFILEOUT* self, int newbytes ); + +#if defined(_MSC_VER) + #pragma pack(pop) +#else + #pragma pack() +#endif + + +#ifdef TWO_SUPPORT_BWF +static void setDefaultLoudness(WAVEOUT_LOUDNESSINFO *x) +{ + x->loudnessVal = 1.0f; + x->loudnessRange = 2.0f; + x->maxTruePeakLevel = 3.0f; + x->maxMomentaryLoudnes = 4.0f; + x->maxShortTermLoudness = 5.0f; +} +#endif + +static WAVEFILEOUT* __CreateWavInternal( + const char *fileName, + const unsigned int sampleRate, + const unsigned int numChannels, + const unsigned int bps +#ifdef TWO_SUPPORT_BWF + , + const WAVEOUT_LOUDNESSINFO *hBwfData +#endif + ) +{ + WAVEFILEOUT* self = NULL; + __tinyWaveOutHeader whdr; + __tinyWaveOutDs64Chunk ds64ch; +#ifdef TWO_SUPPORT_BWF + __tinyWaveOutBextChunk wbextch; +#endif + __tinyWaveOutFmtChunk wfch; + __tinyWaveOutDataChunk wdch; + unsigned int blockAlignment = 0; + unsigned int ByteCnt = 0; /* Byte counter for fwrite */ + + /* pseudo use to avoid unused symbols */ + (void)WriteWavShort; + (void)WriteWavLong; + (void)WriteWavFloat; +#ifdef TWI_SUPPORT_BWF + (void)CreateWavBWF; + (void)CloseWavBWF; + (void)setDefaultLoudness; +#endif + + /* param check */ + if (!fileName) goto bail; + if (sampleRate == 0) goto bail; + if (sampleRate > 768000) goto bail; + if (numChannels == 0) goto bail; + if (numChannels > 64) goto bail; + if (bps != 16 && bps != 24 && bps != 32) goto bail; + + self = (WAVEFILEOUT*)calloc(1, sizeof(WAVEFILEOUT)); + if (!self) goto bail; /* return NULL; */ + + self->theFile = fopen(fileName, "wb+"); + if (!self->theFile) goto bail; + + /* WAV-Header */ + whdr.riffType = BigEndian32('R','I','F','F'); + whdr.riffSize = LittleEndian32(0xffffffff); /* set to maximum, if fseek() doesn't work later */ + whdr.waveType = BigEndian32('W','A','V','E'); + /* write to file */ + ByteCnt = 0; + ByteCnt += fwrite(&whdr, 1, sizeof(whdr), self->theFile); + + /* ds64/JUNK-Chunk */ + ds64ch.formatType = BigEndian32('J','U','N','K'); + ds64ch.formatSize = LittleEndian32(sizeof(__tinyWaveOutDs64Chunk) - 8); + ds64ch.riffSize64 = (TWO_UINT64) -1; + ds64ch.dataSize64 = (TWO_UINT64) -1; + ds64ch.sampleCount64 = (TWO_UINT64) -1; + ds64ch.tableLength = 0; + self->junkChunkOffset = ByteCnt; + ByteCnt += fwrite(&ds64ch, 1, sizeof(ds64ch), self->theFile); + +#ifdef TWO_SUPPORT_BWF + /* BEXT-Chunk */ + if (hBwfData) { + memset(&wbextch, 0, sizeof(__tinyWaveOutBextChunk)); + wbextch.formatType = BigEndian32('b','e','x','t'); + wbextch.formatSize = LittleEndian32(sizeof(__tinyWaveOutBextChunk) - 8); + wbextch.version = 0x0002; + wbextch.loudnessVal = EncodeLoudness(hBwfData->loudnessVal); + wbextch.loudnessRange = EncodeLoudness(hBwfData->loudnessRange); + wbextch.maxTruePeakLevel = EncodeLoudness(hBwfData->maxTruePeakLevel); + wbextch.maxMomentaryLoudnes = EncodeLoudness(hBwfData->maxMomentaryLoudnes); + wbextch.maxShortTermLoudness = EncodeLoudness(hBwfData->maxShortTermLoudness); + /* t.b.d.: more values */ + + /* write to file */ + self->bextChunkOffset = ByteCnt; + ByteCnt += fwrite(&wbextch, 1, sizeof(wbextch), self->theFile); + } +#endif + + /* FMT-Chunk */ + wfch.formatType = BigEndian32('f','m','t',' '); + wfch.formatSize = LittleEndian32(16); + switch (bps) { + case 16: + case 24: + wfch.formatTag = LittleEndian16(0x0001); /* WAVE_FORMAT_PCM */ + break; + case 32: + wfch.formatTag = LittleEndian16(0x0003); /* WAVE_FORMAT_IEEE_FLOAT */ + break; + default: + goto bail; + } + self->bps = bps; + wfch.bitsPerSample = LittleEndian16(bps); + wfch.numChannels = LittleEndian16(numChannels); + blockAlignment = numChannels * (bps >> 3); + wfch.blockAlignment = LittleEndian16(blockAlignment); + wfch.sampleRate = LittleEndian32(sampleRate); + wfch.bytesPerSecond = LittleEndian32(sampleRate * blockAlignment); + /* tbd: wavfmt ext hdr here */ + /* write to file */ + self->fmtChunkOffset = ByteCnt; + ByteCnt += fwrite(&wfch, 1, sizeof(wfch), self->theFile); + + /* DATA-Chunk */ + self->dataChunkOffset = ByteCnt; + wdch.dataType = BigEndian32('d','a','t','a'); + wdch.dataSize = LittleEndian32(0xffffffff - ByteCnt); /* yet unknown. set to maximum of 4 GB file */ + /* write to file */ + ByteCnt += fwrite(&wdch, 1, sizeof(wdch), self->theFile); + + self->dataSize = 0; + + /* self->dataSizeLimit = 0x7fffffff - ByteCnt; */ /* maximum size for data chunk for 2 GB files */ + self->dataSizeLimit = 0xffffffff - ByteCnt; /* maximum size for data chunk for 4 GB files */ + self->dataSizeLimit64 = 0xffffffffffffffff - ByteCnt; /* maximum size for data chunk for 64 bit addressable files */ + + self->clipCount = 0; + self->blockAlign = blockAlignment; + + return self; + + bail: + if ( NULL != self) { + free(self); + } + + return NULL; +} + +static WAVEFILEOUT* CreateWav( + const char* fileName, + const unsigned int sampleRate, + const unsigned int numChannels, + const unsigned int bps + ) +{ +#ifdef TWO_SUPPORT_BWF + return __CreateWavInternal(fileName, sampleRate, numChannels, bps, NULL); +#else + return __CreateWavInternal(fileName, sampleRate, numChannels, bps); +#endif +} + +#ifdef TWO_SUPPORT_BWF +static WAVEFILEOUT* CreateWavBWF( + const char *fileName, + const unsigned int sampleRate, + const unsigned int numChannels, + const unsigned int bps, + const WAVEOUT_LOUDNESSINFO *hBwfData + ) +{ + return __CreateWavInternal(fileName, sampleRate, numChannels, bps, hBwfData); +} +#endif + +#define MAX_PCM16 (+32767) +#define MIN_PCM16 (-32768) +static __inline int CLIP_PCM16(int sample, TWO_UINT64* clipcount) +{ + int tmp = sample; + + if (sample >= MAX_PCM16) { + tmp = MAX_PCM16; + (*clipcount)++; + } else { + if (sample <= MIN_PCM16) { + tmp = MIN_PCM16; + (*clipcount)++; + } + } + + return tmp; +} + +#define MAX_PCM24 (+8388607) +#define MIN_PCM24 (-8388608) +static __inline int CLIP_PCM24(int sample, TWO_UINT64* clipcount) +{ + int tmp = sample; + + if (sample >= MAX_PCM24) { + tmp = MAX_PCM24; + (*clipcount)++; + } else { + if (sample <= MIN_PCM24) { + tmp = MIN_PCM24; + (*clipcount)++; + } + } + + return tmp; +} + +#define MAX_FLOAT32 (+1.0f) +#define MIN_FLOAT32 (-1.0f) +static __inline float CLIP_FLOAT32(float sample, TWO_UINT64* clipcount) +{ + float tmp = sample; + + if (sample >= MAX_FLOAT32) { + tmp = MAX_FLOAT32; + (*clipcount)++; + } else { + if (sample <= MIN_FLOAT32) { + tmp = MIN_FLOAT32; + (*clipcount)++; + } + } + + return tmp; +} + + + +static int __WriteSample16( + WAVEFILEOUT* self, + int sample, + int scale + ) +{ + size_t cnt; + short v; + + if ((scale - 16) > 0) + sample = sample >> (scale - 16); + else + sample = (int) ((uint32_t) sample << (16 - scale)); + + v = (short)CLIP_PCM16(sample, &(self->clipCount)); +#ifdef __TWO_BE + v = LittleEndian16(v); +#endif + + cnt = fwrite(&v, sizeof(short), 1, self->theFile); + + if (cnt == 1) { + self->dataSize += 2; + return __TWO_SUCCESS; + } + + return __TWO_ERROR; +} + + +static int __WriteSample24( + WAVEFILEOUT* self, + int sample, + int scale + ) +{ + size_t cnt; + int v; + + if ((scale - 24) > 0) + sample = sample >> (scale - 24); + else + sample = (int) (((unsigned int)sample) << (24 - scale)); + + v = (int)CLIP_PCM24(sample, &(self->clipCount)); +#ifdef __TWO_BE + v = LittleEndian32s(v); +#endif + cnt = fwrite(&v, 3, 1, self->theFile); + + if (cnt == 1) { + self->dataSize += 3; + return __TWO_SUCCESS; + } + + return __TWO_ERROR; +} + + +static int __WriteSample32( + WAVEFILEOUT* self, + float sample + ) +{ + size_t cnt; + union fl_int { + float v_float; + int v_int; + }; + union fl_int v; + +#if CLIP_FLOAT + v.v_float = CLIP_FLOAT32(sample, &(self->clipCount)); +#else + v.v_float = sample; + if((sample > 1.0f) || (sample <-1.0f)) + self->clipCount++; +#endif + +#ifdef __TWO_BE + v.v_int = LittleEndian32s(v.v_int); +#endif + cnt = fwrite(&v, 4, 1, self->theFile); + + if (cnt == 1) { + self->dataSize += 4; + return __TWO_SUCCESS; + } + + return __TWO_ERROR; +} + + +static int __WriteSampleInt( + WAVEFILEOUT* self, + int sample, + int scale + ) +{ + int err; + + if (!self) return __TWO_ERROR; + + + switch (self->bps) { + + case 16: + err = __WriteSample16(self, sample, scale); + break; + + case 24: + err = __WriteSample24(self, sample, scale); + break; + + default: + err = __TWO_ERROR; + break; + } + + return err; +} + + +/* this function expects values in the 16 bit range +-32767/8 */ +static int WriteWavShort( + WAVEFILEOUT* self, + short sampleBuffer[], + unsigned int nSamples + ) +{ + unsigned long i; + int err = __TWO_SUCCESS; + + if (!self) return __TWO_ERROR; + if (!sampleBuffer) return __TWO_ERROR; + if (__dataSizeChk(self, nSamples * sizeof(short))) return __TWO_ERROR; + + for (i=0; i< nSamples; i++) { + if (self->bps == 32) + { + err = __WriteSample32(self, sampleBuffer[i] / 32768.0f); + } + else + { + err = __WriteSampleInt(self, (int)sampleBuffer[i], 16); + } + if (err != __TWO_SUCCESS) return err; + } + + return __TWO_SUCCESS; +} + + +/* this function expects values in the 24 bit range +-8388607/8 */ +static int WriteWavLong( + WAVEFILEOUT* self, + int sampleBuffer[], + unsigned int nSamples + ) +{ + unsigned long i; + int err = __TWO_SUCCESS; + + if (!self) return __TWO_ERROR; + if (!sampleBuffer) return __TWO_ERROR; + if (__dataSizeChk(self, nSamples * sizeof(int))) return __TWO_ERROR; + + for (i = 0; i < nSamples; i++) { + if (self->bps == 32) + { + err = __WriteSample32(self, sampleBuffer[i] / 8388608.0f); + } + else + { + err = __WriteSampleInt(self, sampleBuffer[i], 24); + } + if (err != __TWO_SUCCESS) return err; + } + + return __TWO_SUCCESS; +} + + +/* this function expects normalized values in the range +-1.0 */ +#define MAX_FL (+2.0f * 8388608.0f ) +#define MIN_FL (-2.0f * 8388608.0f ) +#define CLIP_FL(x) ( ((x) >= MAX_FL) ? MAX_FL : (((x) <= MIN_FL) ? MIN_FL : (x)) ) +static int WriteWavFloat( + WAVEFILEOUT* self, + float sampleBuffer[], + unsigned int nSamples + ) +{ + unsigned int i; + int err = __TWO_SUCCESS; + + if (!self) return __TWO_ERROR; + if (!sampleBuffer) return __TWO_ERROR; + if (__dataSizeChk(self, nSamples * sizeof(float))) return __TWO_ERROR; + + for (i=0; ibps == 32) + { + err = __WriteSample32(self, sampleBuffer[i]); + } + else + { + float tmp = CLIP_FL(sampleBuffer[i] * 8388608.0f); /* CLIP_FL is just to avoid an INT overrun before the actual cast to int, real clipping and counting is done below */ + err = __WriteSampleInt(self, (int) tmp, 24); + } + if (err != __TWO_SUCCESS) return err; + } + + return __TWO_SUCCESS; +} + + +static int CloseWav(WAVEFILEOUT* self) +{ + unsigned int riffSize_le = 0; + unsigned int dataSize_le = 0; + TWO_UINT64 riffSize64 = 0; + TWO_UINT64 dataSize64 = 0; + TWO_UINT64 sampleCount64 = 0; /* nr of samples in the WAVE sense: 1 sample are all pcm samples of all channels of one time slice */ + int mustWriteRF64 = 0; + + if (!self) return __TWO_ERROR; + + /* check for 4 GB (switch to RF64) */ + if ( self->dataSize > self->dataSizeLimit ) { + /* when we exceed 4 GB: switch from std wave header to RF64 header */ + mustWriteRF64 = 1; + } + + /* calc header values */ + if (mustWriteRF64 == 0) { + /* write padding byte if dataSize is uneven */ + int pad = 0; + if (self->dataSize % 2 > 0) { + char tmp= 0x00; + fwrite(&tmp, sizeof(char), 1, self->theFile); + pad = 1; + } + riffSize_le = LittleEndian32(self->dataChunkOffset - 8 + 8 + (unsigned int)self->dataSize + pad); /* sizeof(hdr) - (8 bytes of riff chunk header) + (8 bytes data chunk header) + sizeof(raw-pcm-data) + padding Byte */ + dataSize_le = LittleEndian32((unsigned int)self->dataSize); + } else { + riffSize_le = 0xffffffff; + dataSize_le = 0xffffffff; + riffSize64 = LittleEndian64( self->dataSize + (TWO_UINT64)self->dataChunkOffset ); + dataSize64 = LittleEndian64( self->dataSize ); + sampleCount64 = LittleEndian64( self->dataSize / (TWO_UINT64)self->blockAlign ); + } + + /* now overwrite length/size values in header with the actual/real ones */ + if (mustWriteRF64 == 0) { + /* riffsize32 */ + fseek(self->theFile, 4, SEEK_SET); + fwrite(&riffSize_le, sizeof(riffSize_le), 1, self->theFile); + /* datasize32 */ + fseek(self->theFile, self->dataChunkOffset + 4, SEEK_SET); + fwrite(&dataSize_le, sizeof(dataSize_le), 1, self->theFile); + } else { + unsigned int rf64sig = BigEndian32('R','F','6','4'); + unsigned int ds64sig = BigEndian32('d','s','6','4'); + + /* replace RIFF->RF64 */ + fseek(self->theFile, 0, SEEK_SET); + fwrite(&rf64sig, sizeof(rf64sig), 1, self->theFile); + + /* riffsize32 */ + fseek(self->theFile, 4, SEEK_SET); + fwrite(&riffSize_le, sizeof(riffSize_le), 1, self->theFile); + + /* replace JUNK->ds64 */ + fseek(self->theFile, self->junkChunkOffset, SEEK_SET); + fwrite(&ds64sig, sizeof(ds64sig), 1, self->theFile); + + /* riffSize64, dataSize64, sampleCount64 */ + fseek(self->theFile, self->junkChunkOffset + 8, SEEK_SET); + fwrite(&riffSize64, sizeof(riffSize64), 1, self->theFile); + fwrite(&dataSize64, sizeof(dataSize64), 1, self->theFile); + fwrite(&sampleCount64, sizeof(sampleCount64), 1, self->theFile); + + /* datasize32 */ + fseek(self->theFile, self->dataChunkOffset + 4, SEEK_SET); + fwrite(&dataSize_le, sizeof(dataSize_le), 1, self->theFile); + } + + fclose(self->theFile); + free(self); + + return __TWO_SUCCESS; +} + +#ifdef TWO_SUPPORT_BWF +static int CloseWavBWF( + WAVEFILEOUT* self, + WAVEOUT_LOUDNESSINFO bextData + ) +{ + int wordData; + + if (!self) return __TWO_ERROR; + + if (self->bextChunkOffset) { + /* Offset for Loudness Data in bext-chunk: 8: Chunk-Header, 412:prev.Data */ + fseek(self->theFile, self->bextChunkOffset+8+412, SEEK_SET); + + wordData = LittleEndian32(EncodeLoudness(bextData.loudnessVal)); + fwrite(&wordData, 2, 1, self->theFile); + + wordData = LittleEndian32(EncodeLoudness(bextData.loudnessRange)); + fwrite(&wordData, 2, 1, self->theFile); + + wordData = LittleEndian32(EncodeLoudness(bextData.maxTruePeakLevel)); + fwrite(&wordData, 2, 1, self->theFile); + + wordData = LittleEndian32(EncodeLoudness(bextData.maxMomentaryLoudnes)); + fwrite(&wordData, 2, 1, self->theFile); + + wordData = LittleEndian32(EncodeLoudness(bextData.maxShortTermLoudness)); + fwrite(&wordData, 2, 1, self->theFile); + } + + return CloseWav(self); +} +#endif + +/*------------- local subs ----------------*/ + +static __inline unsigned int BigEndian32(char a, char b, char c, char d) +{ +#ifdef __TWO_LE + return + (unsigned int) d << 24 | + (unsigned int) c << 16 | + (unsigned int) b << 8 | + (unsigned int) a ; +#else + return + (unsigned int) a << 24 | + (unsigned int) b << 16 | + (unsigned int) c << 8 | + (unsigned int) d ; +#endif +} + + +static __inline unsigned int LittleEndian32(unsigned int v) +{ +#ifdef __TWO_LE + return v; +#else + return + (v & 0x000000FF) << 24 | + (v & 0x0000FF00) << 8 | + (v & 0x00FF0000) >> 8 | + (v & 0xFF000000) >> 24 ; +#endif +} + + +/* signed version of the above */ +static __inline unsigned int LittleEndian32s(int v) +{ +#ifdef __TWO_LE + return v; +#else + return + (v & 0x000000FF) << 24 | + (v & 0x0000FF00) << 8 | + (v & 0x00FF0000) >> 8 | + (v & 0xFF000000) >> 24 ; +#endif +} + + +static __inline short LittleEndian16(short v) +{ +#ifdef __TWO_LE + return v; +#else + return ((v << 8) & 0xFF00) | ((v >> 8) & 0x00FF); +#endif +} + +static __inline TWO_UINT64 LittleEndian64(TWO_UINT64 v) +{ +#ifdef __TWO_LE + return v; +#else + return + (v & 0x00000000000000FF) << 56 | + (v & 0x000000000000FF00) << 40 | + (v & 0x0000000000FF0000) << 24 | + (v & 0x00000000FF000000) << 8 | + (v & 0x000000FF00000000) >> 8 | + (v & 0x0000FF0000000000) >> 24 | + (v & 0x00FF000000000000) >> 40 | + (v & 0xFF00000000000000) >> 56 ; +#endif +} + +#ifdef TWO_SUPPORT_BWF +static unsigned int EncodeLoudness(float x) +{ + int s = (x>0)-(x<0); + return (int)( x*100.0f + s*0.5f ); +} +#endif + +static __inline int __dataSizeChk( WAVEFILEOUT* self, int newbytes ) +{ + if (!self) return __TWO_ERROR; + + if ( (self->dataSize + ((TWO_UINT64)newbytes) ) > self->dataSizeLimit64 ) { + return __TWO_ERROR; + } + + return __TWO_SUCCESS; +} + +#endif /* __TINYWAVEOUT_C_H__ */ + + + diff --git a/lib_lc3plus/tns_coder_fx.c b/lib_lc3plus/tns_coder_fx.c new file mode 100644 index 0000000000000000000000000000000000000000..640e246cc7b42a83b1550f899bb4470105372bd4 --- /dev/null +++ b/lib_lc3plus/tns_coder_fx.c @@ -0,0 +1,378 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.5 * +* 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 "functions.h" + +static void Parcor2Index(const Word16 parCoeff[] /*Q15*/, Word16 index[], Word16 order); +static void Index2Parcor(const Word16 index[], Word16 parCoeff[], Word16 order); +static Word32 FIRLattice(Word16 order, const Word16 *parCoeff /*Q15*/, Word32 *state, Word32 x /* Q0 */); + +/*************************************************************************/ + +void processTnsCoder_fx(Word16 *bits, Word16 indexes[], Word32 x[], Word16 BW_cutoff_idx, Word16 order[], + Word16 *numfilters, Word16 enable_lpc_weighting, Word16 nSubdivisions, Word16 frame_dms, + Word16 maxLen, Word8 *scratchBuffer +#ifdef ENABLE_HR_MODE + , Word16 hrmode +#endif + , Word16 near_nyquist_flag +) +{ + Dyn_Mem_Deluxe_In(Word16 * tmpbuf; Word32 * rxx, epsP, *state, L_tmp, *A, predictionGain, alpha; Word16 * RC, inv; + Word16 n, n2, headroom, shift, tmp, shifts, facs, facs_e, stopfreq, xLen, maxOrder; + Word16 startfreq[TNS_NUMFILTERS_MAX]; const Word16 *subdiv_startfreq, *subdiv_stopfreq; + Counter i, j, iSubdivisions, lag; Word8 * LevinsonBuffer;); + + /* Buffer alignment */ + tmpbuf = (Word16 *)scratchAlign(scratchBuffer, 0); /* Size = 2 * MAX_LEN */ + + rxx = (Word32 *)scratchAlign(tmpbuf, sizeof(*tmpbuf) * maxLen); /* Size = 4 * (MAXLAG + 1) = 36 bytes */ + + state = (Word32 *)scratchAlign(rxx, sizeof(*rxx) * (MAXLAG + 1)); /* Size = 4 * MAXLAG = 32 bytes */ + + A = (Word32 *)scratchAlign(state, sizeof(*state) * MAXLAG); /* Size = 4 * (MAXLAG + 1) = 36 bytes */ + + RC = (Word16 *)scratchAlign(A, sizeof(*A) * (MAXLAG + 1)); /* Size = 2 * MAXLAG = 16 bytes */ + + LevinsonBuffer = (Word8 *)scratchAlign(RC, sizeof(*RC) * (MAXLAG)); /* Size = 4 * (M_LTPF + 1) = 100 bytes */ + + /* Init */ + *bits = 0; + move16(); + maxOrder = MAXLAG; + move16(); + *numfilters = 1; + move16(); + +#ifdef ENABLE_HR_MODE + if (hrmode) + { + xLen = BW_cutoff_bin_all_HR[BW_cutoff_idx]; + } + else +#endif + { + xLen = BW_cutoff_bin_all[BW_cutoff_idx]; + } + move16(); + + SWITCH (frame_dms) + { + case 25: + startfreq[0] = 3; + move16(); + +#ifdef ENABLE_HR_MODE + if (hrmode) + { + subdiv_startfreq = tns_subdiv_startfreq_2_5ms_HR[BW_cutoff_idx - 4]; + move16(); + subdiv_stopfreq = tns_subdiv_stopfreq_2_5ms_HR[BW_cutoff_idx - 4]; + move16(); + } + else +#endif + { + subdiv_startfreq = tns_subdiv_startfreq_2_5ms[BW_cutoff_idx]; + move16(); + subdiv_stopfreq = tns_subdiv_stopfreq_2_5ms[BW_cutoff_idx]; + move16(); + } + xLen = shr_pos(xLen, 2); + maxOrder = 4; + move16(); + BREAK; + case 50: + startfreq[0] = 6; + move16(); + +#ifdef ENABLE_HR_MODE + if (hrmode) + { + subdiv_startfreq = tns_subdiv_startfreq_5ms_HR[BW_cutoff_idx - 4]; + move16(); + subdiv_stopfreq = tns_subdiv_stopfreq_5ms_HR[BW_cutoff_idx - 4]; + move16(); + } + else +#endif + { + subdiv_startfreq = tns_subdiv_startfreq_5ms[BW_cutoff_idx]; + move16(); + subdiv_stopfreq = tns_subdiv_stopfreq_5ms[BW_cutoff_idx]; + move16(); + } + xLen = shr_pos(xLen, 1); + maxOrder = 4; + BREAK; +#ifdef CR8_G_ADD_75MS + case 75: + startfreq[0] = 9; + move16(); + subdiv_startfreq = tns_subdiv_startfreq_7_5ms[BW_cutoff_idx]; + move16(); + subdiv_stopfreq = tns_subdiv_stopfreq_7_5ms[BW_cutoff_idx]; + move16(); + tmp = shr_pos(xLen, 2); + xLen = add(tmp, add(tmp, tmp)); + maxOrder = 8; + BREAK; +#endif + default: /* 100 */ + startfreq[0] = 12; + move16(); + +#ifdef ENABLE_HR_MODE + if (hrmode) + { + subdiv_startfreq = tns_subdiv_startfreq_HR[BW_cutoff_idx - 4]; + move16(); + subdiv_stopfreq = tns_subdiv_stopfreq_HR[BW_cutoff_idx - 4]; + move16(); + } + else +#endif + { + subdiv_startfreq = tns_subdiv_startfreq[BW_cutoff_idx]; + move16(); + subdiv_stopfreq = tns_subdiv_stopfreq[BW_cutoff_idx]; + move16(); + } + BREAK; + } + + IF (sub(BW_cutoff_idx, 3) >= 0 && frame_dms >= 50) + { + *numfilters = 2; + startfreq[1] = shr_pos(xLen, 1); + } + + basop_memset(state, 0, MAXLAG * sizeof(*state)); + + FOR (j = 0; j < *numfilters; j++) + { + basop_memset(rxx, 0, (maxOrder + 1) * sizeof(*rxx)); + + FOR (iSubdivisions = 0; iSubdivisions < nSubdivisions; iSubdivisions++) + { + n = sub(subdiv_stopfreq[nSubdivisions * j + iSubdivisions], + subdiv_startfreq[nSubdivisions * j + iSubdivisions]); + + /*norms[iFilter][iSubdivisions] = norm2FLOAT(pSpectrum+iStartLine, iEndLine-iStartLine);*/ + headroom = getScaleFactor32_lc3plus(x + subdiv_startfreq[nSubdivisions * j + iSubdivisions], n); + + /* Calculate norm of spectrum band */ + L_tmp = Norm32Norm(x + subdiv_startfreq[nSubdivisions * j + iSubdivisions], headroom, n, &shift); + + /* Rounding to avoid overflow when computing the autocorrelation below */ + tmp = sub(norm_l(L_tmp), 1); + L_tmp = L_shl(L_tmp, tmp); + shift = sub(shift, tmp); + L_tmp = L_add(L_tmp, 0x8000); + L_tmp = L_and(L_tmp, 0x7FFF0000); + + IF (L_tmp == 0) + { + rxx[0] = 0x7FFFFFFF; + move32(); + basop_memset(&rxx[1], 0, (maxOrder) * sizeof(*rxx)); + BREAK; + } + + /* get pre-shift for autocorrelation */ + tmp = sub(shift, norm_l(L_tmp)); /* exponent for normalized L_tmp */ + tmp = shr_pos(sub(1, tmp), 1); /* pre-shift to apply before autocorrelation */ + shifts = s_min(tmp, headroom); + + /* calc normalization factor */ + facs_e = shl_pos(sub(tmp, shifts), 1); + + SWITCH (frame_dms) + { + case 25: facs_e = add(facs_e, 1); BREAK; + case 50: facs_e = add(facs_e, 1); BREAK; +#ifdef CR8_G_ADD_75MS + case 75: BREAK; +#endif + case 100: BREAK; + } + + tmp = sub(1, shl_pos(tmp, 1)); /* exponent of autocorrelation */ + L_tmp = L_shl(L_tmp, sub(shift, tmp)); /* shift L_tmp to that exponent */ + /* calc factor (with 2 bits headroom for sum of 3 subdivisions) */ + facs = div_s(0x2000, round_fx(L_tmp)); /* L_tmp is >= 0x2000000 */ + + FOR (i = 0; i < n; i++) + { + tmpbuf[i] = round_fx_sat(L_shl_sat(x[subdiv_startfreq[nSubdivisions * j + iSubdivisions] + i], shifts)); + move16(); + } + + FOR (lag = 0; lag <= maxOrder; lag++) + { + n2 = sub(n, lag); + L_tmp = L_deposit_l(0); + FOR (i = 0; i < n2; i++) + { + L_tmp = L_mac0(L_tmp, tmpbuf[i], tmpbuf[i + lag]); + } + if (lag != 0) + L_tmp = Mpy_32_32_lc3plus(L_tmp, tnsAcfWindow_lc3plus[lag - 1]); + + L_tmp = Mpy_32_16_lc3plus(L_tmp, facs); + L_tmp = L_shl(L_tmp, facs_e); + + rxx[lag] = L_add(rxx[lag], L_tmp); + move32(); + } + } + + /* Levinson-Durbin */ + processLevinson_fx(A, rxx, maxOrder, RC, &epsP, LevinsonBuffer); + + /* Prediction Gain */ + shift = norm_l(epsP); + inv = div_s(16383, extract_h(L_shl_pos(epsP, shift))); + predictionGain = Mpy_32_32_lc3plus(rxx[0], Mpy_32_16_lc3plus(L_sub(MAX_32, Mpy_32_16_lc3plus(L_shl(epsP, shift), inv)), inv)); + + IF (L_sub(predictionGain, L_shr_pos_pos(0x30000000, shift)) > 0 && near_nyquist_flag == 0) + { + /* If Prediction Gain is low */ + test(); + IF (enable_lpc_weighting != 0 && L_sub(predictionGain, L_shr_pos_pos(0x40000000, shift)) < 0) + { + /* LPC weighting */ + alpha = L_add(0x6CCCCCCD, + Mpy_32_32_lc3plus(0x13333333, L_shl_pos(L_sub(L_shl_pos(predictionGain, shift), 0x30000000), 3))); + L_tmp = alpha; + FOR (i = 1; i < maxOrder; i++) + { + A[i] = Mpy_32_32_lc3plus(A[i], L_tmp); + move32(); + L_tmp = Mpy_32_32_lc3plus(L_tmp, alpha); + } + A[maxOrder] = Mpy_32_32_lc3plus(A[maxOrder], L_tmp); + move32(); + + /* LPC -> RC */ + lpc2rc(A, RC, maxOrder); + } + + /* Reflection Coefficients Quantization */ + Parcor2Index(RC, &indexes[MAXLAG * j], maxOrder); + + /* reduce filter order by truncating trailing zeros */ + i = sub(maxOrder, 1); + WHILE ((i >= 0) && (indexes[MAXLAG * j + i] == INDEX_SHIFT)) + { + i = sub(i, 1); + } + order[j] = add(i, 1); + + // Disable TNS if order is 0: + IF (order[j] == 0) { + // Jump to else statement + goto tns_disabled; + } + /* Count bits */ + L_tmp = L_deposit_l(ac_tns_order_bits[enable_lpc_weighting][order[j] - 1]); + FOR (i = 0; i < order[j]; i++) + { + L_tmp = L_add(L_tmp, L_deposit_l(ac_tns_coef_bits[i][indexes[MAXLAG * j + i]])); + } + *bits = add(*bits, add(2, extract_l(L_shr_pos(L_sub(L_tmp, 1), 11)))); + move16(); + + /* Unquantize Reflection Coefficients */ + Index2Parcor(&indexes[MAXLAG * j], RC, order[j]); + + /* Stop frequency */ + stopfreq = xLen; + move16(); + IF (sub(*numfilters, 2) == 0 && j == 0) + { + stopfreq = startfreq[1]; + } + + /* Filter */ + FOR (i = startfreq[j]; i < stopfreq; i++) + { + x[i] = FIRLattice(order[j], RC, state, x[i]); + move32(); + } + } + ELSE + { +tns_disabled: + /* TNS disabled */ + *bits = add(*bits, 1); + order[j] = 0; + } + } + + Dyn_Mem_Deluxe_Out(); +} + +/*************************************************************************/ + +static void Parcor2Index(const Word16 parCoeff[] /*Q15*/, Word16 index[], Word16 order) +{ + Dyn_Mem_Deluxe_In(Counter i; Word16 iIndex; Word16 x;); + + FOR (i = 0; i < order; i++) + { + move16(); + move16(); + iIndex = 1; + x = parCoeff[i]; + + WHILE ((iIndex < TNS_COEF_RES) && (x > tnsQuantThr[iIndex - 1])) + { + iIndex = add(iIndex, 1); + } + index[i] = sub(iIndex, 1); + move16(); + } + + Dyn_Mem_Deluxe_Out(); +} + +static void Index2Parcor(const Word16 index[], Word16 parCoeff[], Word16 order) +{ + Counter i; + FOR (i = 0; i < order; i++) + { + parCoeff[i] = tnsQuantPts[index[i]]; + move16(); + } +} + +static Word32 FIRLattice(Word16 order, const Word16 *parCoeff /*Q15*/, Word32 *state, Word32 x /* Q0 */) +{ + Dyn_Mem_Deluxe_In(Counter i; Word32 tmpSave, tmp;); + + tmpSave = L_add(x, 0); + + FOR (i = 0; i < order - 1; i++) + { + tmp = L_add(state[i], Mpy_32_16_lc3plus(x, parCoeff[i])); + x = L_add(x, Mpy_32_16_lc3plus(state[i], parCoeff[i])); /* exponent: 31+0 */ + state[i] = tmpSave; + move32(); + tmpSave = L_add(tmp, 0); + } + + /* last stage: only need half operations */ + x = L_add(x, Mpy_32_16_lc3plus(state[order - 1], parCoeff[order - 1])); + state[order - 1] = tmpSave; + move32(); + Dyn_Mem_Deluxe_Out(); + return x; +} + diff --git a/lib_lc3plus/tns_decoder_fx.c b/lib_lc3plus/tns_decoder_fx.c new file mode 100644 index 0000000000000000000000000000000000000000..b138c451034c09ea1eb23c262fec6678d0290737 --- /dev/null +++ b/lib_lc3plus/tns_decoder_fx.c @@ -0,0 +1,150 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.5 * +* 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 "functions.h" + +static Word32 IIRLattice(Word16 order, const Word16 *parCoeff, Word32 *state, Word32 x); + +/*************************************************************************/ + +void processTnsDecoder_fx(Word16 rc_idx[], Word32 x[], Word16 xLen, Word16 order[], Word16 *x_e, Word16 BW_stopband_idx, + Word16 frame_dms, Word8 *scratchBuffer +#ifdef ENABLE_HR_MODE + , Word16 hrmode +#endif +) +{ + Dyn_Mem_Deluxe_In( + Word32 *state; + Counter i, j; + Word16 s1, s2, s, *rc, f, stopfreq, BW_stopband; + Word16 numfilters, startfreq[TNS_NUMFILTERS_MAX]; + ); + + state = (Word32 *)scratchAlign(scratchBuffer, 0); /* Size = MAXLAG */ + rc = (Word16 *)scratchAlign(state, sizeof(*state) * MAXLAG); /* Size = MAXLAG */ + + numfilters = 1; + +#ifdef ENABLE_HR_MODE + if (hrmode == 1) + { + BW_stopband = BW_cutoff_bin_all_HR[BW_stopband_idx]; move16(); + } + else +#endif + { + BW_stopband = BW_cutoff_bin_all[BW_stopband_idx]; move16(); + } + + SWITCH (frame_dms) + { + case 25: + startfreq[0] = 3; move16(); + BW_stopband = shr_pos(BW_stopband, 2); + BREAK; + case 50: + startfreq[0] = 6; move16(); + BW_stopband = shr_pos(BW_stopband, 1); + BREAK; +#ifdef CR8_G_ADD_75MS + case 75: + startfreq[0] = 9; move16(); + BW_stopband = add(shr_pos(BW_stopband, 2), add(shr_pos(BW_stopband, 2), shr_pos(BW_stopband, 2))); + BREAK; +#endif + case 100: startfreq[0] = 12; BREAK; + } + + IF (sub(BW_stopband_idx, 3) >= 0 && frame_dms >= 50) + { + numfilters = 2; + startfreq[1] = shr_pos(BW_stopband, 1); + } + stopfreq = 0; + + test(); test(); + IF (order[0] > 0 || (sub(numfilters, 2) == 0 && order[1] > 0)) + { + /* Scaling */ + f = startfreq[0]; move16(); + test(); + IF (sub(numfilters, 2) == 0 && order[0] == 0) + { + f = startfreq[1]; move16(); + } + s1 = getScaleFactor32_lc3plus(x, f); + s2 = getScaleFactor32_lc3plus(x + f, sub(xLen, f)); + s = s_min(s1, sub(s2, 7)); /* 7 bits of headroom for IIR filtering */ + *x_e = sub(*x_e, s); + +/* Init Filter */ + basop_memset(state, 0, MAXLAG * sizeof(Word32)); + FOR (i = 0; i < f; i++) + { + x[i] = L_shl(x[i], s); move32(); + } + + FOR (j = 0; j < numfilters; j++) + { + IF (order[j] > 0) + { + /* Unquantize coefficients */ + FOR (i = 0; i < order[j]; i++) + { + rc[i] = tnsQuantPts[rc_idx[j * MAXLAG + i]]; move16(); + } + + /* Stop frequency */ + stopfreq = BW_stopband; move16(); + IF (sub(numfilters, 2) == 0 && j == 0) + { + stopfreq = startfreq[1]; + } + + /* Filter */ + FOR (i = startfreq[j]; i < stopfreq; i++) + { + x[i] = IIRLattice(order[j], rc, state, L_shl(x[i], s)); move32(); + } + } + } + FOR (i = stopfreq; i < xLen; i++) + { + x[i] = L_shl(x[i], s); move32(); + } + } + Dyn_Mem_Deluxe_Out(); +} + +/*************************************************************************/ +/*************************************************************************/ +/*************************************************************************/ + +static Word32 IIRLattice(Word16 order, const Word16 *parCoeff, Word32 *state, Word32 x) +{ + Dyn_Mem_Deluxe_In( + Counter i; + ); + + /* first stage: no need to calculate state[order-1] */ + x = L_sub_sat(x, Mpy_32_16_lc3plus(state[order - 1], parCoeff[order - 1])); + + FOR (i = order - 2; i >= 0; i--) + { + x = L_sub(x, Mpy_32_16_lc3plus(state[i], parCoeff[i])); + state[i + 1] = L_add(state[i], Mpy_32_16_lc3plus(x, parCoeff[i])); move32(); + } + + state[0] = x; move32(); + + Dyn_Mem_Deluxe_Out(); + return x; +} + diff --git a/lib_rend/ivas_allrad_dec.c b/lib_rend/ivas_allrad_dec_fx.c similarity index 98% rename from lib_rend/ivas_allrad_dec.c rename to lib_rend/ivas_allrad_dec_fx.c index 193648a4e23bbda8f5ef9f3a994d7ea1f1f829c0..5023bee34db1aafdbf965096cbbc3722f62ec191 100644 --- a/lib_rend/ivas_allrad_dec.c +++ b/lib_rend/ivas_allrad_dec_fx.c @@ -1,7 +1,7 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other @@ -35,9 +35,8 @@ #include "options.h" #include #include -#include "prot.h" -#include "ivas_prot.h" -#include "ivas_prot_rend.h" +#include "prot_fx.h" +#include "ivas_prot_rend_fx.h" #include "ivas_rom_rend.h" #include "wmc_auto.h" #include "ivas_prot_fx.h" diff --git a/lib_rend/ivas_crend.c b/lib_rend/ivas_crend_fx.c similarity index 76% rename from lib_rend/ivas_crend.c rename to lib_rend/ivas_crend_fx.c index d8cfec1d133dbcce6d623e7edda4b0229afb9811..8daeb7cf4730927f6261064ce58835af2b67319b 100644 --- a/lib_rend/ivas_crend.c +++ b/lib_rend/ivas_crend_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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,15 +33,13 @@ #include #include #include "options.h" -#include "prot.h" -#include "ivas_prot.h" -#include "ivas_prot_rend.h" +#include "prot_fx.h" +#include "ivas_prot_rend_fx.h" #include "ivas_cnst.h" #include "ivas_rom_rend.h" #include "ivas_rom_binaural_crend_head.h" #include "ivas_stat_rend.h" #include "lib_rend.h" -#include "prot_fx.h" #include "ivas_prot_fx.h" #include "wmc_auto.h" #ifdef DEBUGGING @@ -193,7 +191,11 @@ static ivas_error ivas_rend_initCrend_fx( test(); test(); - IF( NE_16( outConfig, IVAS_AUDIO_CONFIG_BINAURAL ) && NE_16( outConfig, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR ) && NE_16( outConfig, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) ) + if ( NE_16( outConfig, IVAS_AUDIO_CONFIG_BINAURAL ) && NE_16( outConfig, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR ) && NE_16( outConfig, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) +#ifdef SPLIT_REND_WITH_HEAD_ROT + && NE_16( outConfig, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) && NE_16( outConfig, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) +#endif + ) { return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Encountered unsupported output type in Crend" ); } @@ -1397,10 +1399,19 @@ static ivas_error ivas_er_init_handle( *------------------------------------------------------------------------*/ ivas_error ivas_rend_initCrendWrapper( - CREND_WRAPPER_HANDLE *pCrend ) +#ifdef SPLIT_REND_WITH_HEAD_ROT + CREND_WRAPPER_HANDLE *pCrend, + const int16_t num_poses +#else + CREND_WRAPPER_HANDLE *pCrend +#endif +) { Word16 i; CREND_HANDLE hCrend; +#ifdef SPLIT_REND_WITH_HEAD_ROT + Word16 pos_idx; +#endif IF( pCrend == NULL ) { @@ -1416,6 +1427,9 @@ ivas_error ivas_rend_initCrendWrapper( move32(); ( *pCrend )->hHrtfCrend = NULL; +#ifdef SPLIT_REND_WITH_HEAD_ROT + FOR( pos_idx = 0; pos_idx < num_poses; pos_idx++ ) +#endif { hCrend = NULL; IF( ( hCrend = (CREND_HANDLE) malloc( sizeof( CREND_DATA ) ) ) == NULL ) @@ -1452,12 +1466,44 @@ ivas_error ivas_rend_initCrendWrapper( move32(); move32(); +#ifdef SPLIT_REND_WITH_HEAD_ROT + ( *pCrend )->hCrend[pos_idx] = hCrend; +#else ( *pCrend )->hCrend = hCrend; +#endif } return IVAS_ERR_OK; } +#ifdef SPLIT_REND_WITH_HEAD_ROT +/*------------------------------------------------------------------------- + * ivas_rend_openMultiBinCrend() + * + * Allocate and initialize crend renderer handle + *------------------------------------------------------------------------*/ + +ivas_error ivas_rend_openMultiBinCrend( + CREND_WRAPPER_HANDLE *pCrend, + const AUDIO_CONFIG inConfig, + const AUDIO_CONFIG outConfig, + const MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, + const Word32 output_Fs ) +{ + ivas_error error; + +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( ( error = ivas_rend_openCrend( pCrend, inConfig, outConfig, NULL /*hRendCfg*/, NULL, output_Fs, pMultiBinPoseData->num_poses ) ) != IVAS_ERR_OK ) +#else + if ( ( error = ivas_rend_openCrend( pCrend, inConfig, outConfig, NULL /*hRendCfg*/, NULL, output_Fs ) ) != IVAS_ERR_OK ) +#endif + { + return error; + } + + return error; +} +#endif /*------------------------------------------------------------------------- * ivas_rend_openCrend() @@ -1471,156 +1517,182 @@ ivas_error ivas_rend_openCrend( const AUDIO_CONFIG outConfig, RENDER_CONFIG_DATA *hRendCfg, HRTFS_CREND_HANDLE hSetOfHRTF, - const Word32 output_Fs ) +#ifdef SPLIT_REND_WITH_HEAD_ROT + const Word32 output_Fs, + const Word16 num_poses +#else + const Word32 output_Fs +#endif +) { Word16 i, subframe_length; Word16 max_total_ir_len; HRTFS_HANDLE hHrtf; CREND_HANDLE hCrend; ivas_error error; +#ifdef SPLIT_REND_WITH_HEAD_ROT + Word16 pos_idx; +#endif error = IVAS_ERR_OK; move16(); +#ifdef SPLIT_REND_WITH_HEAD_ROT + IF( ( error = ivas_rend_initCrendWrapper( pCrend, num_poses ) ) != IVAS_ERR_OK ) +#else IF( NE_32( ( error = ivas_rend_initCrendWrapper( pCrend ) ), IVAS_ERR_OK ) ) +#endif { return error; } subframe_length = extract_l( Mult_32_16( output_Fs, 164 ) ); /*( output_Fs / FRAMES_PER_SEC ) / MAX_PARAM_SPATIAL_SUBFRAMES(i/o:164=(32768/FRAMES_PER_SEC)/MAX_PARAM_SPATIAL_SUBFRAMES*/ - IF( ( *pCrend )->hHrtfCrend == NULL ){ - IF( NE_32( ( error = ivas_rend_initCrend_fx( *pCrend, inConfig, outConfig, hSetOfHRTF, output_Fs ) ), IVAS_ERR_OK ) ){ + IF( ( *pCrend )->hHrtfCrend == NULL ) + { + IF( NE_32( ( error = ivas_rend_initCrend_fx( *pCrend, inConfig, outConfig, hSetOfHRTF, output_Fs ) ), IVAS_ERR_OK ) ) + { return error; -} -} - -{ - hCrend = ( *pCrend )->hCrend; - hHrtf = ( *pCrend )->hHrtfCrend; + } + } - IF( hHrtf != NULL ) +#ifdef SPLIT_REND_WITH_HEAD_ROT + for ( pos_idx = 0; pos_idx < num_poses; pos_idx++ ) +#endif { - max_total_ir_len = imult1616( hHrtf->max_num_iterations, subframe_length ); +#ifdef SPLIT_REND_WITH_HEAD_ROT + hCrend = ( *pCrend )->hCrend[pos_idx]; +#else + hCrend = ( *pCrend )->hCrend; +#endif + hHrtf = ( *pCrend )->hHrtfCrend; - FOR( i = 0; i < hHrtf->max_num_ir; i++ ) + IF( hHrtf != NULL ) { - IF( ( hCrend->freq_buffer_re_fx[i] = (Word32 *) malloc( sizeof( Word32 ) * max_total_ir_len ) ) == NULL ) - { - return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Crend" ); - } - set_zero_fx( hCrend->freq_buffer_re_fx[i], max_total_ir_len ); - IF( ( hCrend->freq_buffer_im_fx[i] = (Word32 *) malloc( sizeof( Word32 ) * max_total_ir_len ) ) == NULL ) + max_total_ir_len = imult1616( hHrtf->max_num_iterations, subframe_length ); + + FOR( i = 0; i < hHrtf->max_num_ir; i++ ) { - return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Crend" ); + IF( ( hCrend->freq_buffer_re_fx[i] = (Word32 *) malloc( sizeof( Word32 ) * max_total_ir_len ) ) == NULL ) + { + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Crend" ); + } + set_zero_fx( hCrend->freq_buffer_re_fx[i], max_total_ir_len ); + IF( ( hCrend->freq_buffer_im_fx[i] = (Word32 *) malloc( sizeof( Word32 ) * max_total_ir_len ) ) == NULL ) + { + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Crend" ); + } + set_zero_fx( hCrend->freq_buffer_im_fx[i], max_total_ir_len ); } - set_zero_fx( hCrend->freq_buffer_im_fx[i], max_total_ir_len ); - } - FOR( i = 0; i < BINAURAL_CHANNELS; i++ ) - { - IF( ( hCrend->prev_out_buffer_fx[i] = (Word32 *) malloc( sizeof( Word32 ) * subframe_length ) ) == NULL ) + FOR( i = 0; i < BINAURAL_CHANNELS; i++ ) { - return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Crend" ); + IF( ( hCrend->prev_out_buffer_fx[i] = (Word32 *) malloc( sizeof( Word32 ) * subframe_length ) ) == NULL ) + { + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Crend" ); + } + set_zero_fx( hCrend->prev_out_buffer_fx[i], subframe_length ); } - set_zero_fx( hCrend->prev_out_buffer_fx[i], subframe_length ); - } - max_total_ir_len = imult1616( (Word16) hHrtf->num_iterations_diffuse[0], subframe_length ); + max_total_ir_len = imult1616( (Word16) hHrtf->num_iterations_diffuse[0], subframe_length ); - IF( max_total_ir_len > 0 ) - { - IF( ( hCrend->freq_buffer_re_diffuse_fx = (Word32 *) malloc( sizeof( Word32 ) * max_total_ir_len ) ) == NULL ) + IF( max_total_ir_len > 0 ) { - return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Crend" ); + IF( ( hCrend->freq_buffer_re_diffuse_fx = (Word32 *) malloc( sizeof( Word32 ) * max_total_ir_len ) ) == NULL ) + { + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Crend" ); + } + set_zero_fx( hCrend->freq_buffer_re_diffuse_fx, max_total_ir_len ); + IF( ( hCrend->freq_buffer_im_diffuse_fx = (Word32 *) malloc( sizeof( Word32 ) * max_total_ir_len ) ) == NULL ) + { + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Crend" ); + } + set_zero_fx( hCrend->freq_buffer_im_diffuse_fx, max_total_ir_len ); } - set_zero_fx( hCrend->freq_buffer_re_diffuse_fx, max_total_ir_len ); - IF( ( hCrend->freq_buffer_im_diffuse_fx = (Word32 *) malloc( sizeof( Word32 ) * max_total_ir_len ) ) == NULL ) + ELSE { - return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Crend" ); + hCrend->freq_buffer_re_diffuse_fx = NULL; + hCrend->freq_buffer_im_diffuse_fx = NULL; } - set_zero_fx( hCrend->freq_buffer_im_diffuse_fx, max_total_ir_len ); - } - ELSE - { - hCrend->freq_buffer_re_diffuse_fx = NULL; - hCrend->freq_buffer_im_diffuse_fx = NULL; - } - max_total_ir_len = add( extract_l( L_shr( L_add( L_shl( Mult_32_32( hHrtf->latency_s_fx, output_Fs ), 1 ), 1 ), 1 ) ), subframe_length ); /*(int16_t) ( hHrtf->latency_s * output_Fs + 0.5f ) + subframe_length;*/ - IF( max_total_ir_len > 0 ) - { - IF( ( hCrend->lfe_delay_line_fx = (Word32 *) malloc( sizeof( Word32 ) * max_total_ir_len ) ) == NULL ) + max_total_ir_len = add( extract_l( L_shr( L_add( L_shl( Mult_32_32( hHrtf->latency_s_fx, output_Fs ), 1 ), 1 ), 1 ) ), subframe_length ); /*(int16_t) ( hHrtf->latency_s * output_Fs + 0.5f ) + subframe_length;*/ + IF( max_total_ir_len > 0 ) { - return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Crend" ); + IF( ( hCrend->lfe_delay_line_fx = (Word32 *) malloc( sizeof( Word32 ) * max_total_ir_len ) ) == NULL ) + { + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Crend" ); + } + set_zero_fx( hCrend->lfe_delay_line_fx, max_total_ir_len ); } - set_zero_fx( hCrend->lfe_delay_line_fx, max_total_ir_len ); - } - ELSE - { - hCrend->lfe_delay_line_fx = NULL; - } - - IF( outConfig == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) - { - IF( NE_32( ( error = ivas_reverb_open_fx( &( hCrend->hReverb ), inConfig, ( *pCrend )->hHrtfCrend, NULL, hRendCfg, output_Fs ) ), IVAS_ERR_OK ) ) + ELSE { - return error; + hCrend->lfe_delay_line_fx = NULL; } - IF( EQ_16( hRendCfg->roomAcoustics.use_er, 1 ) ) + IF( outConfig == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) { - - /* Allocate memory for reflections */ - hCrend->reflections = (er_struct_t *) malloc( sizeof( er_struct_t ) ); - IF( !hCrend->reflections ) - { - return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Early Reflections" ); - } - IF( NE_32( ( error = ivas_er_init_handle( hCrend->reflections ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = ivas_reverb_open_fx( &( hCrend->hReverb ), inConfig, ( *pCrend )->hHrtfCrend, NULL, hRendCfg, output_Fs ) ), IVAS_ERR_OK ) ) { return error; } - hCrend->reflections->use_er = hRendCfg->roomAcoustics.use_er; - hCrend->reflections->lowComplexity = hRendCfg->roomAcoustics.lowComplexity; - move16(); - move32(); + IF( EQ_16( hRendCfg->roomAcoustics.use_er, 1 ) ) + { - /* Set sample rate and frame size */ + /* Allocate memory for reflections */ + hCrend->reflections = (er_struct_t *) malloc( sizeof( er_struct_t ) ); + IF( !hCrend->reflections ) + { + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Early Reflections" ); + } + IF( NE_32( ( error = ivas_er_init_handle( hCrend->reflections ) ), IVAS_ERR_OK ) ) + { + return error; + } - hCrend->reflections->output_Fs_fx = output_Fs; // Q0 - move32(); + hCrend->reflections->use_er = hRendCfg->roomAcoustics.use_er; + hCrend->reflections->lowComplexity = hRendCfg->roomAcoustics.lowComplexity; + move16(); + move32(); - hCrend->reflections->max_frame_size = extract_l( Mult_32_16( output_Fs, INV_FRAME_PER_SEC_Q15 ) ); - move32(); + /* Set sample rate and frame size */ + + hCrend->reflections->output_Fs_fx = output_Fs; // Q0 + move32(); - /* Init Shoebox */ - ivas_shoebox_config_init( &hCrend->reflections->shoebox_lib.cal, hRendCfg ); + hCrend->reflections->max_frame_size = extract_l( Mult_32_16( output_Fs, INV_FRAME_PER_SEC_Q15 ) ); + move32(); + + /* Init Shoebox */ + ivas_shoebox_config_init( &hCrend->reflections->shoebox_lib.cal, hRendCfg ); - /* Init and compute Reflections */ - IF( NE_32( ( error = ivas_er_init( hCrend->reflections, inConfig ) ), IVAS_ERR_OK ) ) + /* Init and compute Reflections */ + IF( NE_32( ( error = ivas_er_init( hCrend->reflections, inConfig ) ), IVAS_ERR_OK ) ) + { + return error; + } + } + ELSE { - return error; + hCrend->reflections = NULL; } } ELSE { - hCrend->reflections = NULL; + hCrend->hReverb = NULL; } - } - ELSE - { - hCrend->hReverb = NULL; + + ( *pCrend )->binaural_latency_ns = Mult_32_32( ( *pCrend )->hHrtfCrend->latency_s_fx, (Word32) 1000000000 ); + move32(); } - ( *pCrend )->binaural_latency_ns = Mult_32_32( ( *pCrend )->hHrtfCrend->latency_s_fx, (Word32) 1000000000 ); - move32(); +#ifdef SPLIT_REND_WITH_HEAD_ROT + ( *pCrend )->hCrend[pos_idx] = hCrend; +#else + ( *pCrend )->hCrend = hCrend; +#endif } - - ( *pCrend )->hCrend = hCrend; -} -return IVAS_ERR_OK; + return IVAS_ERR_OK; } /*------------------------------------------------------------------------- @@ -1630,9 +1702,18 @@ return IVAS_ERR_OK; *------------------------------------------------------------------------*/ void ivas_rend_closeCrend( - CREND_WRAPPER_HANDLE *pCrend ) +#ifdef SPLIT_REND_WITH_HEAD_ROT + CREND_WRAPPER_HANDLE *pCrend, + const Word16 num_poses +#else + CREND_WRAPPER_HANDLE *pCrend +#endif +) { Word16 i; +#ifdef SPLIT_REND_WITH_HEAD_ROT + Word16 pos_idx; +#endif CREND_HANDLE hCrend; test(); @@ -1646,8 +1727,15 @@ void ivas_rend_closeCrend( ivas_hrtf_close( &( *pCrend )->hHrtfCrend ); } +#ifdef SPLIT_REND_WITH_HEAD_ROT + FOR( pos_idx = 0; pos_idx < num_poses; pos_idx++ ) +#endif { +#ifdef SPLIT_REND_WITH_HEAD_ROT + hCrend = ( *pCrend )->hCrend[pos_idx]; +#else hCrend = ( *pCrend )->hCrend; +#endif IF( hCrend != NULL ) { FOR( i = 0; i < MAX_INTERN_CHANNELS; i++ ) @@ -1714,7 +1802,11 @@ void ivas_rend_closeCrend( } free( hCrend ); hCrend = NULL; +#ifdef SPLIT_REND_WITH_HEAD_ROT + ( *pCrend )->hCrend[pos_idx] = hCrend; +#else ( *pCrend )->hCrend = hCrend; +#endif } } @@ -1725,6 +1817,30 @@ void ivas_rend_closeCrend( } +#ifdef SPLIT_REND_WITH_HEAD_ROT +/*------------------------------------------------------------------------- + * ivas_rend_closeCldfbRend() + * + * Close CLDFB based fastconv binaural renderer memories + *------------------------------------------------------------------------*/ + +void ivas_rend_closeCldfbRend( + CLDFB_REND_WRAPPER *pCldfbRend ) +{ + IF( pCldfbRend->hCldfbRend->hInputSetup != NULL ) + { + free( pCldfbRend->hCldfbRend->hInputSetup ); + pCldfbRend->hCldfbRend->hInputSetup = NULL; + } + + ivas_binRenderer_close_fx( &pCldfbRend->hCldfbRend ); + ivas_binaural_hrtf_close( &pCldfbRend->hHrtfFastConv ); + ivas_HRTF_fastconv_binary_close_fx( &pCldfbRend->hHrtfFastConv ); + + return; +} +#endif + /*-----------------------------------------------------------------------------------------* * Function ivas_rend_crendConvolver() * @@ -1738,7 +1854,13 @@ static ivas_error ivas_rend_crendConvolver( Word32 *pcm_in[], // Qx Word32 *pcm_out[], // Qx const Word32 output_Fs, - const Word16 i_ts ) +#ifdef SPLIT_REND_WITH_HEAD_ROT + const Word16 i_ts, + const Word16 pos_idx +#else + const Word16 i_ts +#endif +) { Word16 i, j, k, m; Word16 subframe_length, idx_in; @@ -1755,7 +1877,11 @@ static ivas_error ivas_rend_crendConvolver( ivas_error error; +#ifdef SPLIT_REND_WITH_HEAD_ROT + hCrend = pCrend->hCrend[pos_idx]; +#else hCrend = pCrend->hCrend; +#endif IF( NE_32( ( error = getAudioConfigNumChannels( inConfig, &nchan_in ) ), IVAS_ERR_OK ) ) { @@ -1854,8 +1980,8 @@ static ivas_error ivas_rend_crendConvolver( FOR( k = 0; k < pCrend->hHrtfCrend->pIndex_frequency_max[i][j][m]; k++ ) { - tmp_out_re[k] = L_add( L_shl( Msub_32_32( Mpy_32_32( pFreq_buf_re[k], pFreq_filt_re[k] ), pFreq_buf_im[k], pFreq_filt_im[k] ), 2 ), tmp_out_re[k] ); // Qx - tmp_out_im[k] = L_add( L_shl( Madd_32_32( Mpy_32_32( pFreq_buf_re[k], pFreq_filt_im[k] ), pFreq_buf_im[k], pFreq_filt_re[k] ), 2 ), tmp_out_im[k] ); // Qx + tmp_out_re[k] = L_add( Msub_32_32( Mpy_32_32( pFreq_buf_re[k], pFreq_filt_re[k] ), pFreq_buf_im[k], pFreq_filt_im[k] ), tmp_out_re[k] ); // Qx - 2 + tmp_out_im[k] = L_add( Madd_32_32( Mpy_32_32( pFreq_buf_re[k], pFreq_filt_im[k] ), pFreq_buf_im[k], pFreq_filt_re[k] ), tmp_out_im[k] ); // Qx - 2 move32(); move32(); } @@ -1879,8 +2005,8 @@ static ivas_error ivas_rend_crendConvolver( pFreq_filt_im = &pCrend->hHrtfCrend->pOut_to_bin_diffuse_im_fx[j][offset]; // Q31 FOR( k = 0; k < pCrend->hHrtfCrend->pIndex_frequency_max_diffuse[j][m]; k++ ) { - tmp_out_re[k] = L_add( Msub_32_32( Mpy_32_32( pFreq_buf_re[k], pFreq_filt_re[k] ), pFreq_buf_im[k], pFreq_filt_im[k] ), tmp_out_re[k] ); // Qx - tmp_out_im[k] = L_add( Madd_32_32( Mpy_32_32( pFreq_buf_re[k], pFreq_filt_im[k] ), pFreq_buf_im[k], pFreq_filt_re[k] ), tmp_out_im[k] ); // Qx + tmp_out_re[k] = L_add( L_shr( Msub_32_32( Mpy_32_32( pFreq_buf_re[k], pFreq_filt_re[k] ), pFreq_buf_im[k], pFreq_filt_im[k] ), 2 ), tmp_out_re[k] ); // Qx - 2 + tmp_out_im[k] = L_add( L_shr( Madd_32_32( Mpy_32_32( pFreq_buf_re[k], pFreq_filt_im[k] ), pFreq_buf_im[k], pFreq_filt_re[k] ), 2 ), tmp_out_im[k] ); // Qx - 2 move32(); move32(); } @@ -1888,7 +2014,7 @@ static ivas_error ivas_rend_crendConvolver( } ivas_imdft_fx( tmp_out_re, tmp_out_im, pOut, subframe_length ); - + scale_sig32( pOut, shl( subframe_length, 1 ), 2 ); #ifdef DEBUGGING dbgwrite_txt( (const float *) pOut, subframe_length << 1, "Fixed_imdft_out.txt", NULL ); #endif @@ -1933,7 +2059,12 @@ ivas_error ivas_rend_crendProcess( EFAP_HANDLE hEFAPdata, Word32 *output_fx[], /* i/o: input/output audio channels Qx */ const Word32 output_Fs, +#ifdef SPLIT_REND_WITH_HEAD_ROT + const Word16 num_subframes /* i : number of subframes to render */, + const Word16 pos_idx +#else const Word16 num_subframes /* i : number of subframes to render */ +#endif ) { Word16 i, subframe_idx, subframe_len; @@ -1945,7 +2076,11 @@ ivas_error ivas_rend_crendProcess( ivas_error error; CREND_HANDLE hCrend; +#ifdef SPLIT_REND_WITH_HEAD_ROT + hCrend = pCrend->hCrend[pos_idx]; +#else hCrend = pCrend->hCrend; +#endif combinedOrientationEnabled = 0; move16(); @@ -2039,15 +2174,22 @@ ivas_error ivas_rend_crendProcess( test(); IF( EQ_16( inConfigType, IVAS_REND_AUDIO_CONFIG_TYPE_CHANNEL_BASED ) || EQ_16( inConfigType, IVAS_REND_AUDIO_CONFIG_TYPE_AMBISONICS ) ) { - +#ifdef SPLIT_REND_WITH_HEAD_ROT + IF( NE_32( ( error = ivas_rend_crendConvolver( pCrend, inConfig, outConfig, output_fx, p_pcm_tmp_fx, output_Fs, subframe_idx, pos_idx ) ), IVAS_ERR_OK ) ) +#else IF( NE_32( ( error = ivas_rend_crendConvolver( pCrend, inConfig, outConfig, output_fx, p_pcm_tmp_fx, output_Fs, subframe_idx ) ), IVAS_ERR_OK ) ) +#endif { return error; } IF( hCrend->hReverb != NULL ) { +#ifdef SPLIT_REND_WITH_HEAD_ROT + IF( NE_32( ( error = ivas_reverb_process_fx( pCrend->hCrend[pos_idx]->hReverb, inConfig, 1, output_fx, p_pcm_tmp_fx, subframe_idx ) ), IVAS_ERR_OK ) ) +#else IF( NE_32( ( error = ivas_reverb_process_fx( pCrend->hCrend->hReverb, inConfig, 1, output_fx, p_pcm_tmp_fx, subframe_idx ) ), IVAS_ERR_OK ) ) +#endif { return error; } @@ -2090,6 +2232,10 @@ ivas_error ivas_rend_crendProcessSubframe( Word32 *output[], /* i/o: input/output audio channels Qx */ const Word16 n_samples_to_render, /* i : output frame length per channel */ const Word32 output_Fs /* i : output sampling rate */ +#ifdef SPLIT_REND_WITH_HEAD_ROT + , + const Word16 pos_idx +#endif ) { Word16 subframe_idx, subframe_len; @@ -2101,7 +2247,11 @@ ivas_error ivas_rend_crendProcessSubframe( ivas_error error; Word8 combinedOrientationEnabled; CREND_HANDLE hCrend; +#ifdef SPLIT_REND_WITH_HEAD_ROT + hCrend = pCrend->hCrend[pos_idx]; +#else hCrend = pCrend->hCrend; +#endif combinedOrientationEnabled = 0; move16(); @@ -2190,13 +2340,24 @@ ivas_error ivas_rend_crendProcessSubframe( test(); IF( EQ_32( inConfigType, IVAS_REND_AUDIO_CONFIG_TYPE_CHANNEL_BASED ) || EQ_32( inConfigType, IVAS_REND_AUDIO_CONFIG_TYPE_AMBISONICS ) ) { - +#ifdef SPLIT_REND_WITH_HEAD_ROT + IF( NE_32( ( error = ivas_rend_crendConvolver( pCrend, inConfig, outConfig, tc_local_fx, p_pcm_tmp_fx, output_Fs, 0, pos_idx ) ), IVAS_ERR_OK ) ) +#else IF( NE_32( ( error = ivas_rend_crendConvolver( pCrend, inConfig, outConfig, tc_local_fx, p_pcm_tmp_fx, output_Fs, 0 ) ), IVAS_ERR_OK ) ) - +#endif { return error; } +#ifdef SPLIT_REND_WITH_HEAD_ROT + IF( pCrend->hCrend[0]->hReverb != NULL ) + { + IF( NE_32( ( error = ivas_reverb_process_fx( pCrend->hCrend[pos_idx]->hReverb, inConfig, 1, tc_local_fx, p_pcm_tmp_fx, 0 ) ), IVAS_ERR_OK ) ) + { + return error; + } + } +#else IF( pCrend->hCrend->hReverb != NULL ) { IF( NE_32( ( error = ivas_reverb_process_fx( pCrend->hCrend->hReverb, inConfig, 1, tc_local_fx, p_pcm_tmp_fx, 0 ) ), IVAS_ERR_OK ) ) @@ -2204,6 +2365,7 @@ ivas_error ivas_rend_crendProcessSubframe( return error; } } +#endif FOR( ch = 0; ch < nchan_in; ch++ ) { tc_local_fx[ch] += subframe_len; @@ -2222,7 +2384,12 @@ ivas_error ivas_rend_crendProcessSubframe( /* update combined orientation access index */ ivas_combined_orientation_update_index( hCombinedOrientationData, subframe_len ); } + +#ifdef SPLIT_REND_WITH_HEAD_ROT + IF( pCrend->hCrend[0]->hReverb != NULL ) +#else IF( pCrend->hCrend->hReverb != NULL ) +#endif { *pCrend->p_io_qfactor = sub( *pCrend->p_io_qfactor, 2 ); move16(); @@ -2247,3 +2414,344 @@ ivas_error ivas_rend_crendProcessSubframe( return IVAS_ERR_OK; } + +#ifdef SPLIT_REND_WITH_HEAD_ROT +/*-----------------------------------------------------------------------------------------* + * Function ivas_rend_crend_ProcessSplitBin() + * + * Process call for IVAS Crend renderer + *-----------------------------------------------------------------------------------------*/ + +ivas_error ivas_rend_crendProcessSplitBin( + const CREND_WRAPPER *pCrend, + const AUDIO_CONFIG inConfig, + const AUDIO_CONFIG outConfig, + const MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, + const DECODER_CONFIG_HANDLE hDecoderConfig, + const COMBINED_ORIENTATION_HANDLE hCombinedOrientationData, + const IVAS_OUTPUT_SETUP_HANDLE hIntSetup, + EFAP_HANDLE hEFAPdata, + Word32 *output[], + const Word32 output_Fs ) +{ + Word16 i, j; + Word16 sf; + Word16 pos_idx, output_frame; + ivas_error error; + Word16 gain_lfe; + Word32 tmpLfeBuffer[L_FRAME48k]; + Word32 tmpInputBuffer[MAX_OUTPUT_CHANNELS][L_FRAME48k]; + Word32 *p_tmpInputBuffer[MAX_OUTPUT_CHANNELS]; + Word32 tmpSplitBinBuffer[MAX_OUTPUT_CHANNELS][L_FRAME48k]; + COMBINED_ORIENTATION_DATA combinedOrientationDataLocal; + COMBINED_ORIENTATION_HANDLE pCombinedOrientationDataLocal; + + output_frame = extract_l( Mpy_32_32( output_Fs, ONE_BY_FRAMES_PER_SEC_Q31 ) ); + + /* copy input */ + FOR( i = 0; i < hIntSetup->nchan_out_woLFE; ++i ) + { + Copy32( output[i], tmpInputBuffer[i], output_frame ); + } + + FOR( i = 0; i < MAX_OUTPUT_CHANNELS; ++i ) + { + p_tmpInputBuffer[i] = tmpInputBuffer[i]; + move32(); + } + + /* save current head positions */ + pCombinedOrientationDataLocal = hCombinedOrientationData; + move32(); + combinedOrientationDataLocal = *pCombinedOrientationDataLocal; + move32(); + IF( EQ_32( pMultiBinPoseData->poseCorrectionMode, ISAR_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB ) ) + { + FOR( sf = 1; sf < hCombinedOrientationData->num_subframes; ++sf ) + { + Copy_Quat_fx( &combinedOrientationDataLocal.Quaternions[0], &combinedOrientationDataLocal.Quaternions[sf] ); + FOR( i = 0; i < 3; i++ ) + { + FOR( j = 0; j < 3; j++ ) + { + combinedOrientationDataLocal.Rmat_fx[sf][i][j] = combinedOrientationDataLocal.Rmat_fx[0][i][j]; + move32(); + } + } + } + } + + /* copy LFE to tmpLfeBuffer and apply gain only once */ + IF( GT_16( hIntSetup->num_lfe, 0 ) && NE_16( hIntSetup->index_lfe[0], -1 ) ) + { + Copy32( output[hIntSetup->index_lfe[0]], tmpLfeBuffer, output_frame ); + gain_lfe = ( ( pCrend != NULL ) && ( pCrend->hHrtfCrend != NULL ) ) ? pCrend->hHrtfCrend->gain_lfe_fx : GAIN_LFE_FX; + v_multc_fixed_16( tmpLfeBuffer, gain_lfe, tmpLfeBuffer, output_frame ); // q_input_fx - 1 + Scale_sig32( tmpLfeBuffer, output_frame, 1 ); // q_input_fx + } + ELSE + { + set32_fx( tmpLfeBuffer, 0, output_frame ); + } + + FOR( pos_idx = 0; pos_idx < pMultiBinPoseData->num_poses; ++pos_idx ) + { + /* Update head positions */ + + IVAS_QUATERNION Quaternions_orig[MAX_PARAM_SPATIAL_SUBFRAMES], Quaternions_abs; + FOR( i = 0; i < hCombinedOrientationData->num_subframes; i++ ) + { + Copy_Quat_fx( &combinedOrientationDataLocal.Quaternions[i], &Quaternions_orig[i] ); + Quaternions_abs.w_fx = L_negate( 12582912 ); // Q22 + move32(); + modify_Quat_q_fx( &combinedOrientationDataLocal.Quaternions[i], &combinedOrientationDataLocal.Quaternions[i], Q22 ); + Quat2EulerDegree_fx( combinedOrientationDataLocal.Quaternions[i], &Quaternions_abs.z_fx, &Quaternions_abs.y_fx, &Quaternions_abs.x_fx ); /*order in Quat2Euler seems to be reversed ?*/ + + Quaternions_abs.x_fx = L_add( Quaternions_abs.x_fx, pMultiBinPoseData->relative_head_poses_fx[pos_idx][0] ); + Quaternions_abs.y_fx = L_add( Quaternions_abs.y_fx, pMultiBinPoseData->relative_head_poses_fx[pos_idx][1] ); + Quaternions_abs.z_fx = L_add( Quaternions_abs.z_fx, pMultiBinPoseData->relative_head_poses_fx[pos_idx][2] ); + combinedOrientationDataLocal.Quaternions[i] = Quaternions_abs; + move32(); + move32(); + move32(); + move32(); + modify_Quat_q_fx( &combinedOrientationDataLocal.Quaternions[i], &combinedOrientationDataLocal.Quaternions[i], Quaternions_orig[i].q_fact ); + QuatToRotMat_fx( combinedOrientationDataLocal.Quaternions[i], combinedOrientationDataLocal.Rmat_fx[i] ); + modify_Rmat_q_fx( combinedOrientationDataLocal.Rmat_fx[i], combinedOrientationDataLocal.Rmat_fx[i], sub( shl( Quaternions_orig[i].q_fact, 1 ), 32 ), Q30 ); + } + + + /* render inplace to first two channels of tmpInputBuffer */ + pCombinedOrientationDataLocal = &combinedOrientationDataLocal; + move32(); + + FOR( i = 0; i < 3; i++ ) + { + Copy32( hCombinedOrientationData->Rmat_prev_fx[pos_idx][i], pCombinedOrientationDataLocal->Rmat_prev_fx[0][i], 3 ); + } + + IF( ( error = ivas_rend_crendProcessSubframe( pCrend, inConfig, outConfig, hDecoderConfig, pCombinedOrientationDataLocal, hIntSetup, hEFAPdata, + NULL, p_tmpInputBuffer, p_tmpInputBuffer, output_frame, output_Fs, pos_idx ) ) != IVAS_ERR_OK ) + { + return error; + } + + FOR( i = 0; i < 3; i++ ) + { + Copy32( pCombinedOrientationDataLocal->Rmat_prev_fx[0][i], hCombinedOrientationData->Rmat_prev_fx[pos_idx][i], 3 ); + } + + FOR( i = 0; i < BINAURAL_CHANNELS; ++i ) + { + /* accumulate LFE to output */ + v_add_fx( tmpInputBuffer[i], tmpLfeBuffer, tmpInputBuffer[i], output_frame ); + + /* move to split bin output buffer */ + Copy32( tmpInputBuffer[i], tmpSplitBinBuffer[add( i_mult( pos_idx, BINAURAL_CHANNELS ), i )], output_frame ); + } + + /* overwrite rendered channels with input again for next iteration */ + FOR( i = 0; i < hIntSetup->nchan_out_woLFE; ++i ) + { + Copy32( output[i], tmpInputBuffer[i], output_frame ); + } + + /* restore original headrotation data */ + FOR( i = 0; i < hCombinedOrientationData->num_subframes; i++ ) + { + Copy_Quat_fx( &Quaternions_orig[i], &combinedOrientationDataLocal.Quaternions[i] ); + } + } + + /* copy split binaural rendered signals to final output */ + FOR( i = 0; i < BINAURAL_CHANNELS * pMultiBinPoseData->num_poses; ++i ) + { + Copy32( tmpSplitBinBuffer[i], output[i], output_frame ); + } + + return IVAS_ERR_OK; +} + + +/*-----------------------------------------------------------------------------------------* + * Function ivas_rend_crend_ProcessSubframesSplitBin() + * + * Process call for IVAS Crend renderer + *-----------------------------------------------------------------------------------------*/ + +ivas_error ivas_rend_crendProcessSubframesSplitBin( + const CREND_WRAPPER *pCrend, /* i/o: Crend wrapper handle */ + const AUDIO_CONFIG inConfig, /* i : input audio configuration */ + const AUDIO_CONFIG outConfig, /* i : output audio configuration */ + const MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, + const DECODER_CONFIG_HANDLE hDecoderConfig, /* i : decoder config. structure */ + const COMBINED_ORIENTATION_HANDLE hCombinedOrientationData, /* i : combined orientation handle */ + const IVAS_OUTPUT_SETUP_HANDLE hIntSetup, /* i : internal setup handle */ + const EFAP_HANDLE hEFAPdata, /* i : EFAP handle */ + DECODER_TC_BUFFER_HANDLE hTcBuffer, /* i/o: JBM handle */ + Word32 *input_f[], /* i : transport channels */ + Word32 *output[], /* i/o: input/output audio channels */ + const Word16 n_samples_to_render, /* i : output frame length per channel */ + const Word32 output_Fs /* i : output sampling rate */ +) +{ + Word16 i, j; + Word16 sf; + Word16 pos_idx; + ivas_error error; + Word16 gain_lfe; + Word32 tmpLfeBuffer[L_FRAME48k]; + Word16 original_subframes_rendered, original_slots_rendered; + Word32 tmpInputBuffer[MAX_OUTPUT_CHANNELS][L_FRAME48k]; + Word32 *p_tmpInputBuffer[MAX_OUTPUT_CHANNELS]; + Word32 tmpSplitBinBuffer[MAX_OUTPUT_CHANNELS][L_FRAME48k]; + + COMBINED_ORIENTATION_DATA combinedOrientationDataLocal; + COMBINED_ORIENTATION_HANDLE pCombinedOrientationDataLocal; + + /* save current head positions */ + pCombinedOrientationDataLocal = hCombinedOrientationData; + combinedOrientationDataLocal = *pCombinedOrientationDataLocal; + original_subframes_rendered = hTcBuffer->subframes_rendered; + move16(); + original_slots_rendered = hTcBuffer->slots_rendered; + move16(); + + /* copy input */ + FOR( i = 0; i < hIntSetup->nchan_out_woLFE; ++i ) + { + Copy32( input_f[i], tmpInputBuffer[i], n_samples_to_render ); + } + + FOR( i = 0; i < MAX_OUTPUT_CHANNELS; ++i ) + { + p_tmpInputBuffer[i] = tmpInputBuffer[i]; + move32(); + } + + /* save current head positions */ + pCombinedOrientationDataLocal = hCombinedOrientationData; + combinedOrientationDataLocal = *pCombinedOrientationDataLocal; + move32(); + move32(); + IF( EQ_32( pMultiBinPoseData->poseCorrectionMode, ISAR_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB ) ) + { + FOR( sf = 1; sf < hCombinedOrientationData->num_subframes; ++sf ) + { + Copy_Quat_fx( &combinedOrientationDataLocal.Quaternions[0], &combinedOrientationDataLocal.Quaternions[sf] ); + FOR( i = 0; i < 3; i++ ) + { + FOR( j = 0; j < 3; j++ ) + { + combinedOrientationDataLocal.Rmat_fx[sf][i][j] = combinedOrientationDataLocal.Rmat_fx[0][i][j]; + move32(); + } + } + } + } + + /* copy LFE to tmpLfeBuffer and apply gain only once */ + IF( GT_16( hIntSetup->num_lfe, 0 ) && NE_16( hIntSetup->index_lfe[0], -1 ) ) + { + Copy32( output[hIntSetup->index_lfe[0]], tmpLfeBuffer, n_samples_to_render ); + gain_lfe = ( ( pCrend != NULL ) && ( pCrend->hHrtfCrend != NULL ) ) ? pCrend->hHrtfCrend->gain_lfe_fx : GAIN_LFE_FX; + v_multc_fixed_16( tmpLfeBuffer, gain_lfe, tmpLfeBuffer, n_samples_to_render ); // q_input_fx - 1 + Scale_sig32( tmpLfeBuffer, n_samples_to_render, 1 ); // q_input_fx + } + ELSE + { + set32_fx( tmpLfeBuffer, 0, n_samples_to_render ); + } + + FOR( pos_idx = 0; pos_idx < pMultiBinPoseData->num_poses; ++pos_idx ) + { + /* Update head positions */ + IVAS_QUATERNION Quaternions_orig[MAX_PARAM_SPATIAL_SUBFRAMES], Quaternions_abs; + + FOR( i = 0; i < hCombinedOrientationData->num_subframes; i++ ) + { + Copy_Quat_fx( &combinedOrientationDataLocal.Quaternions[i], &Quaternions_orig[i] ); + Quaternions_abs.w_fx = L_negate( 12582912 ); // Q22 + move32(); + modify_Quat_q_fx( &combinedOrientationDataLocal.Quaternions[i], &combinedOrientationDataLocal.Quaternions[i], Q22 ); + Quat2EulerDegree_fx( combinedOrientationDataLocal.Quaternions[i], &Quaternions_abs.z_fx, &Quaternions_abs.y_fx, &Quaternions_abs.x_fx ); /*order in Quat2Euler seems to be reversed ?*/ + + Quaternions_abs.x_fx = L_add( Quaternions_abs.x_fx, pMultiBinPoseData->relative_head_poses_fx[pos_idx][0] ); + Quaternions_abs.y_fx = L_add( Quaternions_abs.y_fx, pMultiBinPoseData->relative_head_poses_fx[pos_idx][1] ); + Quaternions_abs.z_fx = L_add( Quaternions_abs.z_fx, pMultiBinPoseData->relative_head_poses_fx[pos_idx][2] ); + combinedOrientationDataLocal.Quaternions[i] = Quaternions_abs; + move32(); + move32(); + move32(); + move32(); + Euler2Quat_fx( deg2rad_fx( combinedOrientationDataLocal.Quaternions[i].x_fx ), + deg2rad_fx( combinedOrientationDataLocal.Quaternions[i].y_fx ), + deg2rad_fx( combinedOrientationDataLocal.Quaternions[i].z_fx ), + &combinedOrientationDataLocal.Quaternions[i] ); + modify_Quat_q_fx( &combinedOrientationDataLocal.Quaternions[i], &combinedOrientationDataLocal.Quaternions[i], Quaternions_orig[i].q_fact ); + QuatToRotMat_fx( combinedOrientationDataLocal.Quaternions[i], combinedOrientationDataLocal.Rmat_fx[i] ); + modify_Rmat_q_fx( combinedOrientationDataLocal.Rmat_fx[i], combinedOrientationDataLocal.Rmat_fx[i], sub( shl( Quaternions_orig[i].q_fact, 1 ), 32 ), Q30 ); + } + + + pCombinedOrientationDataLocal = &combinedOrientationDataLocal; + move32(); + + hTcBuffer->subframes_rendered = original_subframes_rendered; + hTcBuffer->slots_rendered = original_slots_rendered; + move16(); + move16(); + + /* update combined orientation access index */ + ivas_combined_orientation_set_to_start_index( pCombinedOrientationDataLocal ); + + FOR( i = 0; i < 3; i++ ) + { + Copy32( hCombinedOrientationData->Rmat_prev_fx[pos_idx][i], pCombinedOrientationDataLocal->Rmat_prev_fx[0][i], 3 ); + } + + IF( ( error = ivas_rend_crendProcessSubframe( pCrend, inConfig, outConfig, hDecoderConfig, pCombinedOrientationDataLocal, + hIntSetup, hEFAPdata, hTcBuffer, p_tmpInputBuffer, p_tmpInputBuffer, n_samples_to_render, output_Fs, pos_idx ) ) != IVAS_ERR_OK ) + { + return error; + } + + FOR( i = 0; i < 3; i++ ) + { + Copy32( pCombinedOrientationDataLocal->Rmat_prev_fx[0][i], hCombinedOrientationData->Rmat_prev_fx[pos_idx][i], 3 ); + } + + FOR( i = 0; i < BINAURAL_CHANNELS; ++i ) + { + /* accumulate LFE to output */ + v_add_fx( tmpInputBuffer[i], tmpLfeBuffer, tmpInputBuffer[i], n_samples_to_render ); + + /* move to split bin output buffer */ + Copy32( tmpInputBuffer[i], tmpSplitBinBuffer[add( i_mult( pos_idx, BINAURAL_CHANNELS ), i )], n_samples_to_render ); + } + + /* overwrite rendered channels with input again for next iteration */ + FOR( i = 0; i < hIntSetup->nchan_out_woLFE; ++i ) + { + Copy32( output[i], tmpInputBuffer[i], n_samples_to_render ); + } + + /* restore original headrotation data */ + FOR( i = 0; i < hCombinedOrientationData->num_subframes; i++ ) + { + Copy_Quat_fx( &Quaternions_orig[i], &combinedOrientationDataLocal.Quaternions[i] ); + } + } + + /* copy split binaural rendered signals to final output */ + FOR( i = 0; i < i_mult( BINAURAL_CHANNELS, pMultiBinPoseData->num_poses ); ++i ) + { + Copy32( tmpSplitBinBuffer[i], output[i], n_samples_to_render ); + } + + /* update main combined orientation access index */ + ivas_combined_orientation_update_index( hCombinedOrientationData, n_samples_to_render ); + + return IVAS_ERR_OK; +} +#endif diff --git a/lib_rend/ivas_dirac_ana.c b/lib_rend/ivas_dirac_ana_fx.c similarity index 99% rename from lib_rend/ivas_dirac_ana.c rename to lib_rend/ivas_dirac_ana_fx.c index f2bc10e6adb03b388bf941bf349c2f33964b92b6..8124c4967cdeac890fdaf3c55d94f20489afe838 100644 --- a/lib_rend/ivas_dirac_ana.c +++ b/lib_rend/ivas_dirac_ana_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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,13 +33,11 @@ #include "options.h" #include #include "ivas_cnst.h" -#include "ivas_prot_rend.h" -#include "ivas_prot.h" -#include "prot.h" +#include "ivas_prot_rend_fx.h" +#include "prot_fx.h" #include "ivas_stat_rend.h" #include "ivas_rom_com.h" #include "wmc_auto.h" -#include "prot_fx.h" #include "ivas_prot_fx.h" /*------------------------------------------------------------------------- @@ -109,7 +107,7 @@ ivas_error ivas_dirac_ana_open_fx( move16(); FOR( i = 0; i < hDirAC->num_Cldfb_instances; i++ ) { - IF( NE_32( ( error = openCldfb_ivas_fx( &( hDirAC->cldfbAnaEnc[i] ), CLDFB_ANALYSIS, input_Fs, CLDFB_PROTOTYPE_5_00MS ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &( hDirAC->cldfbAnaEnc[i] ), CLDFB_ANALYSIS, input_Fs, CLDFB_PROTOTYPE_5_00MS, DEC ) ), IVAS_ERR_OK ) ) { return error; } diff --git a/lib_rend/ivas_dirac_dec_binaural_functions.c b/lib_rend/ivas_dirac_dec_binaural_functions_fx.c similarity index 69% rename from lib_rend/ivas_dirac_dec_binaural_functions.c rename to lib_rend/ivas_dirac_dec_binaural_functions_fx.c index 204ba19967d227778b32b82e54fda3d659f163be..b224564f3bad4430481149ae5c789ec66a6a7fe5 100644 --- a/lib_rend/ivas_dirac_dec_binaural_functions.c +++ b/lib_rend/ivas_dirac_dec_binaural_functions_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other @@ -31,13 +31,11 @@ *******************************************************************************************************/ #include +#include "options.h" #include #include -#include "options.h" -#include "prot.h" #include "prot_fx.h" -#include "ivas_prot.h" -#include "ivas_prot_rend.h" +#include "ivas_prot_rend_fx.h" #include "ivas_cnst.h" #include "ivas_rom_binauralRenderer.h" #include "ivas_rom_binaural_crend_head.h" @@ -72,16 +70,20 @@ Word16 slot_fx[4] = { 32767, 16384, 10922, 8192 }; #define LOG_10_BASE_2_Q29 1783446528 // Q29 #define TAN_30_FX 17157 // Q15 #define INV_TAN30_FX 28377 // Q14 -#define EPSILON_MANT 1180591621 /* 1e-12 in Q70 */ +#define EPSILON_MANT 1180591621 /* 1e-12 = 0.5497558*(2^-39) in Q70 */ #define EPSILON_EXP ( -39 ) -#define ADAPT_HTPROTO_ROT_LIM_1 0.8f +#ifdef FIX_1009_REPLACE_DIV_SQRT_BY_ISQRT_LC +#define ONE_DIV_EPSILON_MANT 1953125000 /* 1e+12 = 0.9094947*(2^40) */ +#define ONE_DIV_EPSILON_EXP ( 40 ) +#endif +#define ADAPT_HTPROTO_ROT_LIM_1 0.8f #define MAX_GAIN_CACHE_SIZE ( ( MASA_MAXIMUM_DIRECTIONS * 3 ) + MAX_NUM_OBJECTS ) /* == different calls to get gains */ typedef struct hrtfGainCache { - int16_t azi; - int16_t ele; + Word16 azi; + Word16 ele; Word32 shVec_fx[HRTF_SH_CHANNELS]; @@ -89,13 +91,13 @@ typedef struct hrtfGainCache typedef struct parambin_rend_config_data { - int16_t separateCenterChannelRendering; + Word16 separateCenterChannelRendering; IVAS_FORMAT ivas_format; MC_MODE mc_mode; - int32_t ivas_total_brate; - int16_t nchan_transport; + Word32 ivas_total_brate; + Word16 nchan_transport; Word32 qualityBasedSmFactor_fx; /* Q31 */ - int16_t processReverb; + Word16 processReverb; ISM_MODE ism_mode; } PARAMBIN_REND_CONFIG, *PARAMBIN_REND_CONFIG_HANDLE; @@ -108,11 +110,21 @@ static void ivas_dirac_dec_binaural_internal_fx( Decoder_Struct *st_ivas, COMBIN static void ivas_dirac_dec_decorrelate_slot_fx( DIRAC_DEC_BIN_HANDLE hDiracDecBin, const Word16 num_freq_bands, const Word16 slot, Word32 inRe[][CLDFB_SLOTS_PER_SUBFRAME] /*q_inp*/[CLDFB_NO_CHANNELS_MAX], Word32 inIm[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX] /*q_inp*/, Word16 q_inp, Word32 decRe[][CLDFB_NO_CHANNELS_MAX] /*q_inp*/, Word32 decIm[] /*q_inp*/[CLDFB_NO_CHANNELS_MAX] ); +#ifdef SPLIT_REND_WITH_HEAD_ROT +static void ivas_dirac_dec_binaural_formulate_input_covariance_matrices_fx( DIRAC_DEC_BIN_HANDLE hDiracDecBin, SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom, PARAMBIN_REND_CONFIG_HANDLE hConfig, Word32 inRe[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], Word32 inIm[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], const Word16 subframe, Word32 *subFrameTotalEne, Word16 *subFrameTotalEne_e, Word32 *IIReneLimiter, Word16 q ); + +static void ivas_dirac_dec_binaural_formulate_target_covariance_matrices_fx( DIRAC_DEC_BIN_HANDLE hDiracDecBin, const SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom, const PARAMBIN_REND_CONFIG_HANDLE hConfig, Word32 Rmat[3][3], const Word16 subframe, const Word16 isHeadtracked, const Word32 *subFrameTotalEne, Word16 *subFrameTotalEne_e, const Word32 *IIReneLimiter, const MASA_ISM_DATA_HANDLE hMasaIsmData ); +#else static void ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matrices_fx( DIRAC_DEC_BIN_HANDLE hDiracDecBin, SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom, PARAMBIN_REND_CONFIG_HANDLE hConfig, Word32 inRe_fx[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX] /*q*/, Word32 inIm_fx[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX] /*q*/, Word32 Rmat_fx[3][3] /*Q30*/, const Word16 subframe, const Word16 isHeadtracked, const MASA_ISM_DATA_HANDLE hMasaIsmData, Word16 q ); +#endif -static void ivas_dirac_dec_binaural_determine_processing_matrices_fx( DIRAC_DEC_BIN_HANDLE hDiracDecBin, SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom, PARAMBIN_REND_CONFIG_HANDLE hConfig, const int16_t max_band_decorr, Word32 Rmat[3][3] /*Q30*/, const Word16 subframe, const Word16 isHeadtracked, const Word16 nchanSeparateChannels, const MASA_ISM_DATA_HANDLE hMasaIsmData ); +static void ivas_dirac_dec_binaural_determine_processing_matrices_fx( DIRAC_DEC_BIN_HANDLE hDiracDecBin, SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom, PARAMBIN_REND_CONFIG_HANDLE hConfig, const Word16 max_band_decorr, Word32 Rmat[3][3] /*Q30*/, const Word16 subframe, const Word16 isHeadtracked, const Word16 nchanSeparateChannels, const MASA_ISM_DATA_HANDLE hMasaIsmData ); +#ifdef SPLIT_REND_WITH_HEAD_ROT +static void ivas_dirac_dec_binaural_process_output_fx( DIRAC_DEC_BIN_HANDLE hDiracDecBin, SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom, HANDLE_CLDFB_FILTER_BANK cldfbSynDec[MAX_OUTPUT_CHANNELS], Word32 *output_fx[] /*q_out*/, Word16 *q_out, Word32 inRe[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX] /*q_inp*/, Word32 inIm[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX] /*q_inp*/, const Word16 q_inp, const Word16 max_band_decorr, const Word16 numInChannels, const Word16 processReverb, const Word16 subframe, const Word16 q_mat, Word32 outRe[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], Word32 outIm[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], Word32 reverbRe[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], Word32 reverbIm[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], Word32 decorrRe[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], Word32 decorrIm[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], Word16 *Q_inp_mix, const Word8 recompute ); +#else static void ivas_dirac_dec_binaural_process_output_fx( DIRAC_DEC_BIN_HANDLE hDiracDecBin, SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom, HANDLE_CLDFB_FILTER_BANK cldfbSynDec[MAX_OUTPUT_CHANNELS], Word32 *output_fx[] /*q_out*/, Word16 *q_out, Word32 inRe[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX] /*q_inp*/, Word32 inIm[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX] /*q_inp*/, const Word16 q_inp, const Word16 max_band_decorr, const Word16 numInChannels, const Word16 processReverb, const Word16 subframe, const Word16 q_mat ); +#endif static void adaptTransportSignalsHeadtracked_fx( COMBINED_ORIENTATION_HANDLE hHeadTrackData, Word32 inRe[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX] /*q_inp*/, Word32 inIm[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX] /*q_inp*/, Word16 q_inp, const Word16 nBins, const Word16 nSlots, Word32 Rmat[3][3] /*Q30*/ ); @@ -121,12 +133,31 @@ static void ivas_dirac_dec_binaural_check_and_switch_transports_headtracked_fx( static void hrtfShGetHrtf_fx( const Word16 bin, const Word16 aziDeg, const Word16 eleDeg, Word32 *lRealp, Word32 *lImagp, Word32 *rRealp, Word32 *rImagp, PARAMBIN_HRTF_GAIN_CACHE *gainCache, const Word16 useCachedValue ); static void getDirectPartGains_fx( const Word16 bin, Word16 aziDeg, Word16 eleDeg, Word32 *lRealp, Word32 *lImagp, Word32 *rRealp, Word32 *rImagp, const UWord8 renderStereoOutputInsteadOfBinaural, Word32 Rmat[3][3] /*Q30*/, PARAMBIN_HRTF_GAIN_CACHE *gainCache, const Word16 isHeadtracked ); + +#ifdef SPLIT_REND_WITH_HEAD_ROT +static void ivas_masa_ext_rend_parambin_internal_fx( MASA_EXT_REND_HANDLE hMasaExtRend, COMBINED_ORIENTATION_HANDLE hCombinedOrientationData, Word32 *output_fx[] /*Q11*/, const Word16 subframe, const SPLIT_REND_WRAPPER *hSplitRendWrapper, Word32 Cldfb_Out_Real[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], Word32 Cldfb_Out_Imag[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX] ); +#else static void ivas_masa_ext_rend_parambin_internal_fx( MASA_EXT_REND_HANDLE hMasaExtRend, COMBINED_ORIENTATION_HANDLE hCombinedOrientationData, Word32 *output_fx[] /*Q11*/, const Word16 subframe ); +#endif + static void formulate2x2MixingMatrix_fx( Word32 Ein1_fx /*q_Ein*/, Word32 Ein2_fx /*q_Ein*/, Word16 q_Ein, Word32 CinRe_fx /*q_Cin*/, Word32 CinIm_fx /*q_Cin*/, Word16 q_Cin, Word32 Eout1_fx /*q_Eout*/, Word32 Eout2_fx /*q_Eout*/, Word16 q_Eout, Word32 CoutRe_fx /*q_Cout*/, Word32 CoutIm_fx /*q_Cout*/, Word16 q_Cout, Word32 Q_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS] /*Q31*/, Word32 Mre_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS] /*q_M*/, Word32 Mim_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS] /*q_M*/, Word16 *q_M, const Word16 regularizationFactor_fx /*Q14*/ ); static void matrixMul_fx( Word32 Are[BINAURAL_CHANNELS][BINAURAL_CHANNELS] /*q_A*/, Word32 Aim[BINAURAL_CHANNELS][BINAURAL_CHANNELS] /*q_A*/, Word16 *q_A, Word32 Bre[BINAURAL_CHANNELS][BINAURAL_CHANNELS] /*q_B*/, Word32 Bim[BINAURAL_CHANNELS][BINAURAL_CHANNELS] /*q_B*/, Word16 *q_B, Word32 outRe[BINAURAL_CHANNELS][BINAURAL_CHANNELS] /*q_out*/, Word32 outIm[BINAURAL_CHANNELS][BINAURAL_CHANNELS] /*q_out*/, Word16 *q_out ); -static void matrixTransp2Mul_fx( Word32 Are[BINAURAL_CHANNELS][BINAURAL_CHANNELS] /*q_A*/, Word32 Aim[BINAURAL_CHANNELS][BINAURAL_CHANNELS] /*q_A*/, Word16 *q_A, Word32 Bre[BINAURAL_CHANNELS][BINAURAL_CHANNELS] /*q_B*/, Word32 Bim[BINAURAL_CHANNELS][BINAURAL_CHANNELS] /*q_B*/, Word16 *q_B, Word32 outRe[BINAURAL_CHANNELS][BINAURAL_CHANNELS] /*q_out*/, Word32 outIm[BINAURAL_CHANNELS][BINAURAL_CHANNELS] /*q_out*/, Word16 *q_out ); +static void matrixTransp2Mul_fx( + Word32 Are[BINAURAL_CHANNELS][BINAURAL_CHANNELS] /*q_A*/, + Word32 Aim[BINAURAL_CHANNELS][BINAURAL_CHANNELS] /*q_A*/, + Word16 *q_A, + Word32 Bre[BINAURAL_CHANNELS][BINAURAL_CHANNELS] /*q_B*/, + Word32 Bim[BINAURAL_CHANNELS][BINAURAL_CHANNELS] /*q_B*/, + Word16 *q_B, +#ifdef FIX_1072_SPEEDUP_matrixTransp2Mul_fx + Word32 Ascale, + Word32 Bscale, +#endif + Word32 outRe[BINAURAL_CHANNELS][BINAURAL_CHANNELS] /*q_out*/, + Word32 outIm[BINAURAL_CHANNELS][BINAURAL_CHANNELS] /*q_out*/, + Word16 *q_out ); /*------------------------------------------------------------------------- * ivas_dirac_dec_init_binaural_data() @@ -149,189 +180,226 @@ ivas_error ivas_dirac_dec_init_binaural_data_fx( Word16 tmp_e; Word16 tmp2; ivas_error error; - hDiracDecBin = st_ivas->hDiracDecBin; - IF( hDiracDecBin == NULL ) - { - IF( ( hDiracDecBin = (DIRAC_DEC_BIN_HANDLE) malloc( sizeof( DIRAC_DEC_BIN_DATA ) ) ) == NULL ) - { - return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC binaural handle " ); - } +#ifdef SPLIT_REND_WITH_HEAD_ROT + Word16 num_poses, pos_idx; - hDiracDecBin->hTdDecorr = NULL; - hDiracDecBin->hReverb = NULL; - hDiracDecBin->h_freq_domain_decorr_ap_params = NULL; - hDiracDecBin->h_freq_domain_decorr_ap_state = NULL; + num_poses = 1; + IF( st_ivas->hSplitBinRend != NULL ) + { + num_poses = st_ivas->hSplitBinRend->splitrend.multiBinPoseData.num_poses; + move16(); } - output_Fs = st_ivas->hDecoderConfig->output_Fs; - move32(); - nBins = st_ivas->hSpatParamRendCom->num_freq_bands; - move16(); - renderer_type = st_ivas->renderer_type; - move32(); - - FOR( j = 0; j < BINAURAL_CHANNELS; j++ ) + FOR( pos_idx = 0; pos_idx < num_poses; pos_idx++ ) { - FOR( k = 0; k < BINAURAL_CHANNELS + MAX_NUM_OBJECTS; k++ ) - { - set16_fx( hDiracDecBin->processMtxRe_fx[j][k], 0, nBins ); - set16_fx( hDiracDecBin->processMtxIm_fx[j][k], 0, nBins ); - set16_fx( hDiracDecBin->processMtxRePrev_fx[j][k], 0, nBins ); - set16_fx( hDiracDecBin->processMtxImPrev_fx[j][k], 0, nBins ); - } + hDiracDecBin = st_ivas->hDiracDecBin[pos_idx]; + move32(); +#else + hDiracDecBin = st_ivas->hDiracDecBin; +#endif - FOR( k = 0; k < BINAURAL_CHANNELS; k++ ) + IF( hDiracDecBin == NULL ) { - set16_fx( hDiracDecBin->processMtxDecRe_fx[j][k], 0, nBins ); - set16_fx( hDiracDecBin->processMtxDecIm_fx[j][k], 0, nBins ); - } - set32_fx( hDiracDecBin->ChEnePrev_fx[j], 0, nBins ); - set32_fx( hDiracDecBin->ChEneOutPrev_fx[j], 0, nBins ); - set16_fx( hDiracDecBin->ChEnePrev_e[j], 0, nBins ); - set16_fx( hDiracDecBin->ChEneOutPrev_e[j], 0, nBins ); - } - set32_fx( hDiracDecBin->ChCrossRePrev_fx, 0, nBins ); - set32_fx( hDiracDecBin->ChCrossImPrev_fx, 0, nBins ); - set16_fx( hDiracDecBin->ChCrossRePrev_e, 0, nBins ); - set16_fx( hDiracDecBin->ChCrossImPrev_e, 0, nBins ); - set32_fx( hDiracDecBin->ChCrossReOutPrev_fx, 0, nBins ); - set32_fx( hDiracDecBin->ChCrossImOutPrev_fx, 0, nBins ); - set16_fx( hDiracDecBin->ChCrossReOutPrev_e, 0, nBins ); - set16_fx( hDiracDecBin->ChCrossImOutPrev_e, 0, nBins ); - hDiracDecBin->renderStereoOutputInsteadOfBinaural = 0; - move16(); - - hDiracDecBin->q_processMtx = Q15; - hDiracDecBin->q_processMtxSCCR = Q15; - hDiracDecBin->q_processMtxPrev = Q15; - hDiracDecBin->q_processMtxPrevSCCR = Q15; - hDiracDecBin->q_processMtxDec = Q15; - hDiracDecBin->q_processMtxDecPrev = Q15; - move16(); - move16(); - move16(); - move16(); - move16(); - move16(); + IF( ( hDiracDecBin = (DIRAC_DEC_BIN_HANDLE) malloc( sizeof( DIRAC_DEC_BIN_DATA ) ) ) == NULL ) + { + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC binaural handle " ); + } - FOR( bin = 0; bin < nBins; bin++ ) - { - binCenterFreq_fx = L_mult0( extract_l( L_shr( output_Fs, 1 ) ), div_s( add( shl( bin, 1 ), 1 ), shl( nBins, 1 ) ) ) /*( (float) bin + 0.5f ) / (float) nBins * ( (float) output_Fs / 2.0f )*/; /*Q15*/ - /* These formulas and values are from Christian Borss's publication for binaural diffuse field coherence */ - tmp = BASOP_Util_Divide3232_Scale( binCenterFreq_fx, 2700 << Q15, &tmp_e ); - IF( tmp_e < 0 ) - { - tmp = shl( tmp, tmp_e ); /*q15*/ - tmp_e = 0; - move16(); + hDiracDecBin->hTdDecorr = NULL; + hDiracDecBin->hReverb = NULL; + hDiracDecBin->h_freq_domain_decorr_ap_params = NULL; + hDiracDecBin->h_freq_domain_decorr_ap_state = NULL; } - tmpFloat_fx = s_max( 0, sub( shl_sat( 1, sub( 15, tmp_e ) ), tmp ) ) /*max( 0.0f, 1.0f - binCenterFreq / 2700.0f )*/; /*Q15-tmp_e*/ - tmp2 = extract_l( Mult_32_32( binCenterFreq_fx, 1952258 /*=2^31*180/(550)/360*/ ) % 32767 ); /* Q15 */ //*binCenterFreq_fx * EVS_PI / 550.0f*/ - hDiracDecBin->diffuseFieldCoherence_fx[bin] = L_shl( L_mult0( divide3232( tmpFloat_fx, Mult_32_16( binCenterFreq_fx, 187 /*2^15*pi/550*/ ) ), getSineWord16R2( tmp2 ) ), tmp_e ); /*tmpFloat * sinf( binCenterFreq * EVS_PI / 550.0f ) / ( binCenterFreq * EVS_PI / 550.0f );*/ /* Q30 */ - hDiracDecBin->diffuseFieldCoherence_fx[bin] = L_shl( hDiracDecBin->diffuseFieldCoherence_fx[bin], 1 ); /* Q31 */ - move32(); - move32(); - } - FOR( bin = 0; bin < BINAURAL_COHERENCE_DIFFERENCE_BINS; bin++ ) - { - hDiracDecBin->diffuseFieldCoherenceX_fx[bin] = L_add( hDiracDecBin->diffuseFieldCoherence_fx[bin], diffuseFieldCoherenceDifferenceX_fx[bin] ); - hDiracDecBin->diffuseFieldCoherenceY_fx[bin] = L_add( hDiracDecBin->diffuseFieldCoherence_fx[bin], diffuseFieldCoherenceDifferenceY_fx[bin] ); - hDiracDecBin->diffuseFieldCoherenceZ_fx[bin] = L_add( hDiracDecBin->diffuseFieldCoherence_fx[bin], diffuseFieldCoherenceDifferenceZ_fx[bin] ); - move32(); + output_Fs = st_ivas->hDecoderConfig->output_Fs; move32(); + nBins = st_ivas->hSpatParamRendCom->num_freq_bands; + move16(); + renderer_type = st_ivas->renderer_type; move32(); - } - IF( EQ_32( renderer_type, RENDERER_BINAURAL_PARAMETRIC ) ) /* Indication of binaural rendering without room effect */ - { - set32_fx( hDiracDecBin->earlyPartEneCorrection_fx, ONE_IN_Q28, CLDFB_NO_CHANNELS_MAX ); - hDiracDecBin->q_earlyPartEneCorrection = Q28; + FOR( j = 0; j < BINAURAL_CHANNELS; j++ ) + { + FOR( k = 0; k < BINAURAL_CHANNELS + MAX_NUM_OBJECTS; k++ ) + { + set16_fx( hDiracDecBin->processMtxRe_fx[j][k], 0, nBins ); + set16_fx( hDiracDecBin->processMtxIm_fx[j][k], 0, nBins ); + set16_fx( hDiracDecBin->processMtxRePrev_fx[j][k], 0, nBins ); + set16_fx( hDiracDecBin->processMtxImPrev_fx[j][k], 0, nBins ); + } + + FOR( k = 0; k < BINAURAL_CHANNELS; k++ ) + { + set16_fx( hDiracDecBin->processMtxDecRe_fx[j][k], 0, nBins ); + set16_fx( hDiracDecBin->processMtxDecIm_fx[j][k], 0, nBins ); + } + set32_fx( hDiracDecBin->ChEnePrev_fx[j], 0, nBins ); + set32_fx( hDiracDecBin->ChEneOutPrev_fx[j], 0, nBins ); + set16_fx( hDiracDecBin->ChEnePrev_e[j], 0, nBins ); + set16_fx( hDiracDecBin->ChEneOutPrev_e[j], 0, nBins ); + } + set32_fx( hDiracDecBin->ChCrossRePrev_fx, 0, nBins ); + set32_fx( hDiracDecBin->ChCrossImPrev_fx, 0, nBins ); + set16_fx( hDiracDecBin->ChCrossRePrev_e, 0, nBins ); + set16_fx( hDiracDecBin->ChCrossImPrev_e, 0, nBins ); + set32_fx( hDiracDecBin->ChCrossReOutPrev_fx, 0, nBins ); + set32_fx( hDiracDecBin->ChCrossImOutPrev_fx, 0, nBins ); + set16_fx( hDiracDecBin->ChCrossReOutPrev_e, 0, nBins ); + set16_fx( hDiracDecBin->ChCrossImOutPrev_e, 0, nBins ); + hDiracDecBin->renderStereoOutputInsteadOfBinaural = 0; move16(); - hDiracDecBin->hReverb = NULL; - } - ELSE IF( EQ_32( renderer_type, RENDERER_BINAURAL_PARAMETRIC_ROOM ) ) /* Indication of binaural rendering with room effect */ - { - Copy32( hHrtfParambin->parametricEarlyPartEneCorrection_fx, hDiracDecBin->earlyPartEneCorrection_fx, nBins ); - hDiracDecBin->q_earlyPartEneCorrection = Q28; + + hDiracDecBin->q_processMtx = Q15; + hDiracDecBin->q_processMtxSCCR = Q15; + hDiracDecBin->q_processMtxPrev = Q15; + hDiracDecBin->q_processMtxPrevSCCR = Q15; + hDiracDecBin->q_processMtxDec = Q15; + hDiracDecBin->q_processMtxDecPrev = Q15; move16(); - /* reconfiguration needed when Reverb. parameters are changed -> close and open the handle again */ - test(); - test(); - IF( hDiracDecBin->hReverb != NULL && ( ( NE_16( hDiracDecBin->hReverb->numBins, nBins ) ) || - ( NE_16( hDiracDecBin->hReverb->blockSize, CLDFB_SLOTS_PER_SUBFRAME ) ) ) ) + move16(); + move16(); + move16(); + move16(); + move16(); + + FOR( bin = 0; bin < nBins; bin++ ) + { + binCenterFreq_fx = L_mult0( extract_l( L_shr( output_Fs, 1 ) ), div_s( add( shl( bin, 1 ), 1 ), shl( nBins, 1 ) ) ) /*( (float) bin + 0.5f ) / (float) nBins * ( (float) output_Fs / 2.0f )*/; /*Q15*/ + /* These formulas and values are from Christian Borss's publication for binaural diffuse field coherence */ + tmp = BASOP_Util_Divide3232_Scale( binCenterFreq_fx, 2700 << Q15, &tmp_e ); + IF( tmp_e < 0 ) + { + tmp = shl( tmp, tmp_e ); /*q15*/ + tmp_e = 0; + move16(); + } + tmpFloat_fx = s_max( 0, sub( shl_sat( 1, sub( 15, tmp_e ) ), tmp ) ) /*max( 0.0f, 1.0f - binCenterFreq / 2700.0f )*/; /*Q15-tmp_e*/ + tmp2 = extract_l( Mult_32_32( binCenterFreq_fx, 1952258 /*=2^31*180/(550)/360*/ ) % 32767 ); /* Q15 */ //*binCenterFreq_fx * EVS_PI / 550.0f*/ + hDiracDecBin->diffuseFieldCoherence_fx[bin] = L_shl( L_mult0( divide3232( tmpFloat_fx, Mult_32_16( binCenterFreq_fx, 187 /*2^15*pi/550*/ ) ), getSineWord16R2( tmp2 ) ), tmp_e ); /*tmpFloat * sinf( binCenterFreq * EVS_PI / 550.0f ) / ( binCenterFreq * EVS_PI / 550.0f );*/ /* Q30 */ + hDiracDecBin->diffuseFieldCoherence_fx[bin] = L_shl( hDiracDecBin->diffuseFieldCoherence_fx[bin], 1 ); /* Q31 */ + move32(); + move32(); + } + + FOR( bin = 0; bin < BINAURAL_COHERENCE_DIFFERENCE_BINS; bin++ ) { - ivas_binaural_reverb_close_fx( &( hDiracDecBin->hReverb ) ); + hDiracDecBin->diffuseFieldCoherenceX_fx[bin] = L_add( hDiracDecBin->diffuseFieldCoherence_fx[bin], diffuseFieldCoherenceDifferenceX_fx[bin] ); + hDiracDecBin->diffuseFieldCoherenceY_fx[bin] = L_add( hDiracDecBin->diffuseFieldCoherence_fx[bin], diffuseFieldCoherenceDifferenceY_fx[bin] ); + hDiracDecBin->diffuseFieldCoherenceZ_fx[bin] = L_add( hDiracDecBin->diffuseFieldCoherence_fx[bin], diffuseFieldCoherenceDifferenceZ_fx[bin] ); + move32(); + move32(); + move32(); } - IF( hDiracDecBin->hReverb == NULL ) + IF( EQ_32( renderer_type, RENDERER_BINAURAL_PARAMETRIC ) ) /* Indication of binaural rendering without room effect */ + { + set32_fx( hDiracDecBin->earlyPartEneCorrection_fx, ONE_IN_Q28, CLDFB_NO_CHANNELS_MAX ); + hDiracDecBin->q_earlyPartEneCorrection = Q28; + move16(); + hDiracDecBin->hReverb = NULL; + } + ELSE IF( EQ_32( renderer_type, RENDERER_BINAURAL_PARAMETRIC_ROOM ) ) /* Indication of binaural rendering with room effect */ { - /* 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( NE_32( ( 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 ) ) + Copy32( hHrtfParambin->parametricEarlyPartEneCorrection_fx, hDiracDecBin->earlyPartEneCorrection_fx, nBins ); + hDiracDecBin->q_earlyPartEneCorrection = Q28; + move16(); + /* reconfiguration needed when Reverb. parameters are changed -> close and open the handle again */ + test(); + test(); + IF( hDiracDecBin->hReverb != NULL && ( ( NE_16( hDiracDecBin->hReverb->numBins, nBins ) ) || + ( NE_16( hDiracDecBin->hReverb->blockSize, CLDFB_SLOTS_PER_SUBFRAME ) ) ) ) { - return error; + ivas_binaural_reverb_close_fx( &( hDiracDecBin->hReverb ) ); + } + +#ifdef SPLIT_REND_WITH_HEAD_ROT + IF( hDiracDecBin->hReverb == NULL && EQ_16( pos_idx, 0 ) ) /* open reverb only for the main direction */ +#else + IF( hDiracDecBin->hReverb == NULL ) +#endif + { + /* 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( NE_32( ( 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 ) ) + { + return error; + } } } - } - ELSE IF( EQ_32( renderer_type, RENDERER_STEREO_PARAMETRIC ) ) - { - set32_fx( hDiracDecBin->earlyPartEneCorrection_fx, ONE_IN_Q28, CLDFB_NO_CHANNELS_MAX ); - hDiracDecBin->q_earlyPartEneCorrection = Q28; - hDiracDecBin->hReverb = NULL; - hDiracDecBin->renderStereoOutputInsteadOfBinaural = 1; - move16(); - move16(); - } - ELSE /* Not valid renderer type for this renderer */ - { - assert( false ); - } + ELSE IF( EQ_32( renderer_type, RENDERER_STEREO_PARAMETRIC ) ) + { + set32_fx( hDiracDecBin->earlyPartEneCorrection_fx, ONE_IN_Q28, CLDFB_NO_CHANNELS_MAX ); + hDiracDecBin->q_earlyPartEneCorrection = Q28; + hDiracDecBin->hReverb = NULL; + hDiracDecBin->renderStereoOutputInsteadOfBinaural = 1; + move16(); + move16(); + } + ELSE /* Not valid renderer type for this renderer */ + { + assert( false ); + } - hDiracDecBin->hDiffuseDist = NULL; /* Memory is allocated from stack during runtime when needed */ + hDiracDecBin->hDiffuseDist = NULL; /* Memory is allocated from stack during runtime when needed */ - if ( hDiracDecBin->hTdDecorr == NULL ) - { - hDiracDecBin->useTdDecorr = 0; - move16(); - } + if ( hDiracDecBin->hTdDecorr == NULL ) + { + hDiracDecBin->useTdDecorr = 0; + move16(); + } - IF( hDiracDecBin->h_freq_domain_decorr_ap_params != NULL ) - { - ivas_dirac_dec_decorr_close_fx( &hDiracDecBin->h_freq_domain_decorr_ap_params, &hDiracDecBin->h_freq_domain_decorr_ap_state ); - } + IF( hDiracDecBin->h_freq_domain_decorr_ap_params != NULL ) + { + ivas_dirac_dec_decorr_close_fx( &hDiracDecBin->h_freq_domain_decorr_ap_params, &hDiracDecBin->h_freq_domain_decorr_ap_state ); + } - IF( NE_32( ( error = ivas_td_decorr_reconfig_dec( st_ivas->ivas_format, st_ivas->hDecoderConfig->ivas_total_brate, st_ivas->nchan_transport, st_ivas->hDecoderConfig->output_Fs, &( hDiracDecBin->hTdDecorr ), &( hDiracDecBin->useTdDecorr ) ) ), IVAS_ERR_OK ) ) - { - return error; - } +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( pos_idx == 0 ) /* open decorrelator only for the main direction */ + { +#endif + IF( NE_32( ( error = ivas_td_decorr_reconfig_dec( st_ivas->ivas_format, st_ivas->hDecoderConfig->ivas_total_brate, st_ivas->nchan_transport, st_ivas->hDecoderConfig->output_Fs, &( hDiracDecBin->hTdDecorr ), &( hDiracDecBin->useTdDecorr ) ) ), IVAS_ERR_OK ) ) + { + return error; + } - test(); - test(); - IF( !hDiracDecBin->useTdDecorr && !( EQ_32( st_ivas->ivas_format, ISM_FORMAT ) && EQ_32( st_ivas->ism_mode, ISM_MODE_PARAM ) ) ) - { - Word16 frequency_axis_fx[CLDFB_NO_CHANNELS_MAX]; - ivas_dirac_dec_get_frequency_axis_fx( frequency_axis_fx, output_Fs, nBins ); - - IF( NE_32( ( error = ivas_dirac_dec_decorr_open_fx( &( hDiracDecBin->h_freq_domain_decorr_ap_params ), - &( hDiracDecBin->h_freq_domain_decorr_ap_state ), - nBins, - BINAURAL_CHANNELS, - BINAURAL_CHANNELS, - DIRAC_SYNTHESIS_PSD_LS, - frequency_axis_fx, - BINAURAL_CHANNELS, - output_Fs ) ), - IVAS_ERR_OK ) ) + test(); + test(); + IF( !hDiracDecBin->useTdDecorr && !( EQ_32( st_ivas->ivas_format, ISM_FORMAT ) && EQ_32( st_ivas->ism_mode, ISM_MODE_PARAM ) ) ) + { + Word16 frequency_axis_fx[CLDFB_NO_CHANNELS_MAX]; + ivas_dirac_dec_get_frequency_axis_fx( frequency_axis_fx, output_Fs, nBins ); + + IF( NE_32( ( error = ivas_dirac_dec_decorr_open_fx( &( hDiracDecBin->h_freq_domain_decorr_ap_params ), + &( hDiracDecBin->h_freq_domain_decorr_ap_state ), + nBins, + BINAURAL_CHANNELS, + BINAURAL_CHANNELS, + DIRAC_SYNTHESIS_PSD_LS, + frequency_axis_fx, + BINAURAL_CHANNELS, + output_Fs ) ), + IVAS_ERR_OK ) ) + { + return error; + } + } +#ifdef SPLIT_REND_WITH_HEAD_ROT + } + else { - return error; + hDiracDecBin->useTdDecorr = st_ivas->hDiracDecBin[0]->useTdDecorr; /* copy the flag, but the implementation re-uses the decorrelated signal */ } - } +#endif - hDiracDecBin->reqularizationFactor_fx = configure_reqularization_factor_fx( st_ivas->ivas_format, st_ivas->hDecoderConfig->ivas_total_brate ); /* Q14 */ - move16(); + hDiracDecBin->reqularizationFactor_fx = configure_reqularization_factor_fx( st_ivas->ivas_format, st_ivas->hDecoderConfig->ivas_total_brate ); /* Q14 */ + move16(); +#ifdef SPLIT_REND_WITH_HEAD_ROT + st_ivas->hDiracDecBin[pos_idx] = hDiracDecBin; + } +#else st_ivas->hDiracDecBin = hDiracDecBin; +#endif /* allocate transport channels */ IF( st_ivas->hTcBuffer == NULL ) @@ -372,13 +440,37 @@ void ivas_dirac_dec_close_binaural_data( DIRAC_DEC_BIN_HANDLE *hBinaural /* i/o: decoder DirAC binaural data handle */ ) { - +#ifdef SPLIT_REND_WITH_HEAD_ROT + int16_t pos_idx; +#endif test(); IF( hBinaural == NULL || *hBinaural == NULL ) { return; } +#ifdef SPLIT_REND_WITH_HEAD_ROT + FOR( pos_idx = 0; pos_idx < MAX_HEAD_ROT_POSES; pos_idx++ ) + { + IF( hBinaural[pos_idx] != NULL ) + { + IF( hBinaural[pos_idx]->hReverb != NULL ) + { + ivas_binaural_reverb_close_fx( &( hBinaural[pos_idx]->hReverb ) ); + } + + ivas_td_decorr_dec_close( &( hBinaural[pos_idx]->hTdDecorr ) ); + + if ( hBinaural[pos_idx]->h_freq_domain_decorr_ap_params != NULL ) + { + ivas_dirac_dec_decorr_close_fx( &( hBinaural[pos_idx]->h_freq_domain_decorr_ap_params ), &( hBinaural[pos_idx]->h_freq_domain_decorr_ap_state ) ); + } + + free( hBinaural[pos_idx] ); + hBinaural[pos_idx] = NULL; + } + } +#else IF( ( *hBinaural )->hReverb != NULL ) { ivas_binaural_reverb_close_fx( &( ( *hBinaural )->hReverb ) ); @@ -392,6 +484,7 @@ void ivas_dirac_dec_close_binaural_data( free( *hBinaural ); *hBinaural = NULL; +#endif return; } @@ -599,7 +692,25 @@ static void ivas_dirac_dec_binaural_internal_fx( Word16 nBins, offsetSamples; Word16 i, j; Word16 q_mat, q_out; +#ifdef SPLIT_REND_WITH_HEAD_ROT + Word16 pos_idx; + MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData; + Word32 tmp_Cldfb_out_re[BINAURAL_CHANNELS][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX]; + Word32 tmp_Cldfb_out_im[BINAURAL_CHANNELS][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX]; + /* these allow re-using the reverb and freq-domain decorrelator signals from ivas_dirac_dec_binaural_process_output() in split rendering for the side renderings */ + Word32 reverbRe_fx[BINAURAL_CHANNELS][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX]; + Word32 reverbIm_fx[BINAURAL_CHANNELS][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX]; + Word32 decorrRe_fx[BINAURAL_CHANNELS][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX]; + Word32 decorrIm_fx[BINAURAL_CHANNELS][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX]; + Word32 subFrameTotalEne_fx[CLDFB_NO_CHANNELS_MAX]; + Word16 subFrameTotalEne_e[CLDFB_NO_CHANNELS_MAX]; + Word32 IIReneLimiter_fx[CLDFB_NO_CHANNELS_MAX]; + Word16 Q_inp_mix; + + hDiracDecBin = st_ivas->hDiracDecBin[0]; +#else hDiracDecBin = st_ivas->hDiracDecBin; +#endif assert( hDiracDecBin ); hSpatParamRendCom = st_ivas->hSpatParamRendCom; nBins = hSpatParamRendCom->num_freq_bands; @@ -798,8 +909,30 @@ static void ivas_dirac_dec_binaural_internal_fx( IF( hDiracDecBin->useTdDecorr ) { +#ifdef FIX_ISSUE_1185 + Word32 tmp_arr[60]; +#endif FOR( ch = BINAURAL_CHANNELS; ch < ( 2 * BINAURAL_CHANNELS ); ch++ ) { +#ifdef FIX_ISSUE_1185 + q_cldfb[ch][slot] = sub( q_input, 1 ); + move16(); + + Copy_Scale_sig32( &( st_ivas->hTcBuffer->tc_fx[ch][nBins * slot + offsetSamples] ), tmp_arr, 60, -1 ); + scale_sig32( st_ivas->cldfbAnaDec[ch]->cldfb_state_fx, sub( st_ivas->cldfbAnaDec[ch]->p_filter_length, st_ivas->cldfbAnaDec[ch]->no_channels ), sub( sub( q_input, 1 ), st_ivas->cldfbAnaDec[ch]->Q_cldfb_state ) ); + st_ivas->cldfbAnaDec[ch]->Q_cldfb_state = sub( q_input, 1 ); + move16(); + + cldfbAnalysis_ts_fx_fixed_q( + tmp_arr, + Cldfb_RealBuffer_in_fx[ch][slot], + Cldfb_ImagBuffer_in_fx[ch][slot], + nBins, st_ivas->cldfbAnaDec[ch], &q_cldfb[ch][slot] ); + + scale_sig32( st_ivas->cldfbAnaDec[ch]->cldfb_state_fx, sub( st_ivas->cldfbAnaDec[ch]->p_filter_length, st_ivas->cldfbAnaDec[ch]->no_channels ), sub( q_input, st_ivas->cldfbAnaDec[ch]->Q_cldfb_state ) ); + st_ivas->cldfbAnaDec[ch]->Q_cldfb_state = q_input; + move16(); +#else q_cldfb[ch][slot] = q_input; move16(); cldfbAnalysis_ts_fx_fixed_q( @@ -807,6 +940,8 @@ static void ivas_dirac_dec_binaural_internal_fx( Cldfb_RealBuffer_in_fx[ch][slot], Cldfb_ImagBuffer_in_fx[ch][slot], nBins, st_ivas->cldfbAnaDec[ch], &q_cldfb[ch][slot] ); +#endif /*FIX_ISSUE_1185*/ + test(); test(); IF( EQ_16( config_data.nchan_transport, 1 ) && @@ -847,6 +982,10 @@ static void ivas_dirac_dec_binaural_internal_fx( { scale_sig32( Cldfb_RealBuffer_in_fx[cha][slot], 60, sub( q_inp, q_cldfb[cha][slot] ) ); // Q6 scale_sig32( Cldfb_ImagBuffer_in_fx[cha][slot], 60, sub( q_inp, q_cldfb[cha][slot] ) ); // Q6 +#ifdef FIX_ISSUE_1185 + q_cldfb[cha][slot] = 6; + move16(); +#endif } } @@ -872,14 +1011,18 @@ static void ivas_dirac_dec_binaural_internal_fx( IF( EQ_16( nchan_transport, 2 ) ) { +#ifdef SPLIT_REND_WITH_HEAD_ROT + /* in case of split rendering, determine the prototype rotation based on the main direction and use the same prototypes for the offset directions */ +#endif adaptTransportSignalsHeadtracked_fx( hCombinedOrientationData, Cldfb_RealBuffer_in_fx, Cldfb_ImagBuffer_in_fx, q_inp, nBins, hSpatParamRendCom->subframe_nbslots[subframe], Rmat_fx ); ivas_dirac_dec_binaural_check_and_switch_transports_headtracked_fx( hCombinedOrientationData, Cldfb_RealBuffer_in_fx, Cldfb_ImagBuffer_in_fx, nBins, hSpatParamRendCom->subframe_nbslots[subframe], Rmat_fx ); } } test(); - ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matrices_fx( hDiracDecBin, hSpatParamRendCom, &config_data, Cldfb_RealBuffer_in_fx, Cldfb_ImagBuffer_in_fx, Rmat_fx, subframe, - hCombinedOrientationData && hCombinedOrientationData->enableCombinedOrientation[hCombinedOrientationData->subframe_idx] > 0, st_ivas->hMasaIsmData, q_inp ); +#ifndef SPLIT_REND_WITH_HEAD_ROT + ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matrices_fx( hDiracDecBin, hSpatParamRendCom, &config_data, Cldfb_RealBuffer_in_fx, Cldfb_ImagBuffer_in_fx, Rmat_fx, subframe, hCombinedOrientationData && hCombinedOrientationData->enableCombinedOrientation[hCombinedOrientationData->subframe_idx] > 0, st_ivas->hMasaIsmData, q_inp ); +#endif IF( EQ_32( config_data.ivas_format, ISM_FORMAT ) ) { @@ -897,158 +1040,1070 @@ static void ivas_dirac_dec_binaural_internal_fx( move16(); } +#ifdef SPLIT_REND_WITH_HEAD_ROT + ivas_dirac_dec_binaural_formulate_input_covariance_matrices_fx( hDiracDecBin, hSpatParamRendCom, &config_data, Cldfb_RealBuffer_in_fx, Cldfb_ImagBuffer_in_fx, subframe, + subFrameTotalEne_fx, subFrameTotalEne_e, IIReneLimiter_fx, q_inp ); + + ivas_dirac_dec_binaural_formulate_target_covariance_matrices_fx( hDiracDecBin, hSpatParamRendCom, &config_data, Rmat_fx, subframe, + hCombinedOrientationData && hCombinedOrientationData->enableCombinedOrientation[hCombinedOrientationData->subframe_idx] > 0, subFrameTotalEne_fx, subFrameTotalEne_e, IIReneLimiter_fx, st_ivas->hMasaIsmData ); +#endif + + nchanSeparateChannels = 0; + move16(); + test(); + test(); + test(); + test(); + test(); + test(); + IF( config_data.separateCenterChannelRendering || ( EQ_32( st_ivas->ivas_format, MASA_ISM_FORMAT ) && ( EQ_32( st_ivas->ism_mode, ISM_MASA_MODE_MASA_ONE_OBJ ) || EQ_32( st_ivas->ism_mode, ISM_MASA_MODE_PARAM_ONE_OBJ ) ) ) ) + { + nchanSeparateChannels = 1; + move16(); + } + ELSE IF( EQ_32( st_ivas->ivas_format, MASA_ISM_FORMAT ) && EQ_32( st_ivas->ism_mode, ISM_MASA_MODE_DISC ) && ( EQ_32( st_ivas->renderer_type, RENDERER_STEREO_PARAMETRIC ) || EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_PARAMETRIC_ROOM ) ) ) + { + nchanSeparateChannels = (UWord8) st_ivas->nchan_ism; + move16(); + } + + ivas_dirac_dec_binaural_determine_processing_matrices_fx( hDiracDecBin, hSpatParamRendCom, &config_data, max_band_decorr, Rmat_fx, subframe, hCombinedOrientationData && hCombinedOrientationData->enableCombinedOrientation[hCombinedOrientationData->subframe_idx] > 0, nchanSeparateChannels, st_ivas->hMasaIsmData ); + + q_inp = Q6; + move16(); + FOR( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) + { + st_ivas->cldfbSynDec[ch]->Q_cldfb_state = Q11; + move16(); + } + + q_mat = hDiracDecBin->q_processMtx; + move16(); + q_mat = s_min( q_mat, hDiracDecBin->q_processMtxPrev ); + q_mat = s_min( q_mat, hDiracDecBin->q_processMtxDec ); + q_mat = s_min( q_mat, hDiracDecBin->q_processMtxDecPrev ); + + FOR( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) + { + FOR( slot = 0; slot < BINAURAL_CHANNELS; slot++ ) + { + Scale_sig( hDiracDecBin->processMtxRe_fx[ch][slot], nBins, sub( q_mat, hDiracDecBin->q_processMtx ) ); // scaling to q_mat + Scale_sig( hDiracDecBin->processMtxIm_fx[ch][slot], nBins, sub( q_mat, hDiracDecBin->q_processMtx ) ); // scaling to q_mat + Scale_sig( hDiracDecBin->processMtxRePrev_fx[ch][slot], nBins, sub( q_mat, hDiracDecBin->q_processMtxPrev ) ); // scaling to q_mat + Scale_sig( hDiracDecBin->processMtxImPrev_fx[ch][slot], nBins, sub( q_mat, hDiracDecBin->q_processMtxPrev ) ); // scaling to q_mat + Scale_sig( hDiracDecBin->processMtxDecRe_fx[ch][slot], nBins, sub( q_mat, hDiracDecBin->q_processMtxDec ) ); // scaling to q_mat + Scale_sig( hDiracDecBin->processMtxDecIm_fx[ch][slot], nBins, sub( q_mat, hDiracDecBin->q_processMtxDec ) ); // scaling to q_mat + Scale_sig( hDiracDecBin->processMtxDecRePrev_fx[ch][slot], nBins, sub( q_mat, hDiracDecBin->q_processMtxDecPrev ) ); // scaling to q_mat + Scale_sig( hDiracDecBin->processMtxDecImPrev_fx[ch][slot], nBins, sub( q_mat, hDiracDecBin->q_processMtxDecPrev ) ); // scaling to q_mat + } + FOR( slot = 0; slot < nchanSeparateChannels; slot++ ) + { + Scale_sig( hDiracDecBin->processMtxRe_fx[ch][slot + BINAURAL_CHANNELS], nBins, sub( q_mat, hDiracDecBin->q_processMtx ) ); // scaling to q_mat + Scale_sig( hDiracDecBin->processMtxIm_fx[ch][slot + BINAURAL_CHANNELS], nBins, sub( q_mat, hDiracDecBin->q_processMtx ) ); // scaling to q_mat + Scale_sig( hDiracDecBin->processMtxRePrev_fx[ch][slot + BINAURAL_CHANNELS], nBins, sub( q_mat, hDiracDecBin->q_processMtxPrev ) ); // scaling to q_mat + Scale_sig( hDiracDecBin->processMtxImPrev_fx[ch][slot + BINAURAL_CHANNELS], nBins, sub( q_mat, hDiracDecBin->q_processMtxPrev ) ); // scaling to q_mat + } + } + hDiracDecBin->q_processMtx = q_mat; + move16(); + hDiracDecBin->q_processMtxPrev = q_mat; + move16(); + hDiracDecBin->q_processMtxDec = q_mat; + move16(); + hDiracDecBin->q_processMtxDecPrev = q_mat; + move16(); + +#ifdef SPLIT_REND_WITH_HEAD_ROT + pMultiBinPoseData = NULL; + IF( st_ivas->hSplitBinRend != NULL ) + { + pMultiBinPoseData = &st_ivas->hSplitBinRend->splitrend.multiBinPoseData; + move32(); + } + +#ifdef SPLIT_REND_WITH_HEAD_ROT + IF( EQ_32( st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) || EQ_32( st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ) +#else + if ( pMultiBinPoseData != NULL && pMultiBinPoseData->num_poses > 1 ) +#endif + { + ivas_dirac_dec_binaural_process_output_fx( hDiracDecBin, hSpatParamRendCom, st_ivas->cldfbSynDec, output_fx, &q_out, Cldfb_RealBuffer_in_fx, Cldfb_ImagBuffer_in_fx, q_inp, max_band_decorr, numInChannels, config_data.processReverb, subframe, q_mat, + tmp_Cldfb_out_re, tmp_Cldfb_out_im, reverbRe_fx, reverbIm_fx, decorrRe_fx, decorrIm_fx, &Q_inp_mix, 1 ); + + FOR( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) + { + FOR( i = 0; i < hSpatParamRendCom->subframe_nbslots[subframe]; i++ ) + { + Copy32( tmp_Cldfb_out_re[ch][i], st_ivas->hSplitBinRend->hMultiBinCldfbData->Cldfb_RealBuffer_Binaural_fx[ch][hSpatParamRendCom->slots_rendered + i], CLDFB_NO_CHANNELS_MAX ); + Copy32( tmp_Cldfb_out_im[ch][i], st_ivas->hSplitBinRend->hMultiBinCldfbData->Cldfb_ImagBuffer_Binaural_fx[ch][hSpatParamRendCom->slots_rendered + i], CLDFB_NO_CHANNELS_MAX ); + } + } + } + ELSE + { + ivas_dirac_dec_binaural_process_output_fx( hDiracDecBin, hSpatParamRendCom, st_ivas->cldfbSynDec, output_fx, &q_out, Cldfb_RealBuffer_in_fx, Cldfb_ImagBuffer_in_fx, q_inp, max_band_decorr, numInChannels, config_data.processReverb, subframe, q_mat, NULL, NULL, + reverbRe_fx, reverbIm_fx, decorrRe_fx, decorrIm_fx, &Q_inp_mix, 1 ); + } +#else + ivas_dirac_dec_binaural_process_output_fx( hDiracDecBin, hSpatParamRendCom, st_ivas->cldfbSynDec, output_fx, &q_out, Cldfb_RealBuffer_in_fx, Cldfb_ImagBuffer_in_fx, q_inp, max_band_decorr, numInChannels, config_data.processReverb, subframe, q_mat ); +#endif + hDiracDecBin->hDiffuseDist = NULL; + + +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( pMultiBinPoseData != NULL && pMultiBinPoseData->num_poses > 1 ) + { + /* quaternion-based rotation from ivas_binRenderer_internal.c:ivas_binRenderer(), but using absolute rotation instead of delta rotations */ + IVAS_QUATERNION Quaternions_rot, Quaternions_abs, *Quaternions_ref; + Word32 Rmat_local[3][3]; + + if ( hCombinedOrientationData ) + { + Quaternions_ref = &hCombinedOrientationData->Quaternions[0]; + Copy_Quat_fx( Quaternions_ref, &Quaternions_abs ); + modify_Quat_q_fx( &Quaternions_abs, &Quaternions_abs, Q22 ); + Quaternions_rot.w_fx = L_negate( 12582912 ); /* signal to use Euler */ + Quat2EulerDegree_fx( Quaternions_abs, &Quaternions_abs.z_fx, &Quaternions_abs.y_fx, &Quaternions_abs.x_fx ); /*order in Quat2Euler seems to be reversed ?*/ + Quaternions_abs.w_fx = L_negate( 12582912 ); /* signal to use Euler */ + + FOR( pos_idx = 1; pos_idx < pMultiBinPoseData->num_poses; pos_idx++ ) + { + Quaternions_rot.x_fx = L_add( Quaternions_abs.x_fx, pMultiBinPoseData->relative_head_poses_fx[pos_idx][0] ); + Quaternions_rot.y_fx = L_add( Quaternions_abs.y_fx, pMultiBinPoseData->relative_head_poses_fx[pos_idx][1] ); + Quaternions_rot.z_fx = L_add( Quaternions_abs.z_fx, pMultiBinPoseData->relative_head_poses_fx[pos_idx][2] ); + move32(); + move32(); + move32(); + Euler2Quat_fx( deg2rad_fx( Quaternions_rot.x_fx ), deg2rad_fx( Quaternions_rot.y_fx ), deg2rad_fx( Quaternions_rot.z_fx ), &Quaternions_rot ); + modify_Quat_q_fx( &Quaternions_rot, &Quaternions_rot, Quaternions_ref->q_fact ); + QuatToRotMat_fx( Quaternions_rot, Rmat_local ); + modify_Rmat_q_fx( Rmat_local, Rmat_local, sub( shl( Quaternions_ref->q_fact, 1 ), 32 ), Q30 ); + + hDiracDecBin = st_ivas->hDiracDecBin[pos_idx]; + assert( hDiracDecBin != NULL && "No DiracDecBin handle for this position" ); + if ( config_data.ivas_format == SBA_FORMAT || config_data.ivas_format == SBA_ISM_FORMAT ) + { + hDiracDecBin->hDiffuseDist = &diffuseDistData; + } + + /* re-use input covariance for the side renderings */ + FOR( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) + { + Copy32( st_ivas->hDiracDecBin[0]->ChEne_fx[ch], hDiracDecBin->ChEne_fx[ch], hSpatParamRendCom->num_freq_bands ); + Copy( st_ivas->hDiracDecBin[0]->ChEne_e[ch], hDiracDecBin->ChEne_e[ch], hSpatParamRendCom->num_freq_bands ); + } + Copy32( st_ivas->hDiracDecBin[0]->ChCrossRe_fx, hDiracDecBin->ChCrossRe_fx, hSpatParamRendCom->num_freq_bands ); + Copy32( st_ivas->hDiracDecBin[0]->ChCrossIm_fx, hDiracDecBin->ChCrossIm_fx, hSpatParamRendCom->num_freq_bands ); + Copy( st_ivas->hDiracDecBin[0]->ChCrossRe_e, hDiracDecBin->ChCrossRe_e, hSpatParamRendCom->num_freq_bands ); + Copy( st_ivas->hDiracDecBin[0]->ChCrossIm_e, hDiracDecBin->ChCrossIm_e, hSpatParamRendCom->num_freq_bands ); + + ivas_dirac_dec_binaural_formulate_target_covariance_matrices_fx( hDiracDecBin, hSpatParamRendCom, &config_data, Rmat_local, subframe, + hCombinedOrientationData && hCombinedOrientationData->enableCombinedOrientation[subframe] > 0, + subFrameTotalEne_fx, subFrameTotalEne_e, IIReneLimiter_fx, st_ivas->hMasaIsmData ); + + ivas_dirac_dec_binaural_determine_processing_matrices_fx( hDiracDecBin, hSpatParamRendCom, &config_data, max_band_decorr, Rmat_local, subframe, + hCombinedOrientationData && hCombinedOrientationData->enableCombinedOrientation[subframe] > 0, + nchanSeparateChannels, st_ivas->hMasaIsmData ); + + + q_mat = hDiracDecBin->q_processMtx; + move16(); + q_mat = s_min( q_mat, hDiracDecBin->q_processMtxPrev ); + q_mat = s_min( q_mat, hDiracDecBin->q_processMtxDec ); + q_mat = s_min( q_mat, hDiracDecBin->q_processMtxDecPrev ); + + FOR( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) + { + FOR( slot = 0; slot < BINAURAL_CHANNELS; slot++ ) + { + Scale_sig( hDiracDecBin->processMtxRe_fx[ch][slot], nBins, sub( q_mat, hDiracDecBin->q_processMtx ) ); // scaling to q_mat + Scale_sig( hDiracDecBin->processMtxIm_fx[ch][slot], nBins, sub( q_mat, hDiracDecBin->q_processMtx ) ); // scaling to q_mat + Scale_sig( hDiracDecBin->processMtxRePrev_fx[ch][slot], nBins, sub( q_mat, hDiracDecBin->q_processMtxPrev ) ); // scaling to q_mat + Scale_sig( hDiracDecBin->processMtxImPrev_fx[ch][slot], nBins, sub( q_mat, hDiracDecBin->q_processMtxPrev ) ); // scaling to q_mat + Scale_sig( hDiracDecBin->processMtxDecRe_fx[ch][slot], nBins, sub( q_mat, hDiracDecBin->q_processMtxDec ) ); // scaling to q_mat + Scale_sig( hDiracDecBin->processMtxDecIm_fx[ch][slot], nBins, sub( q_mat, hDiracDecBin->q_processMtxDec ) ); // scaling to q_mat + Scale_sig( hDiracDecBin->processMtxDecRePrev_fx[ch][slot], nBins, sub( q_mat, hDiracDecBin->q_processMtxDecPrev ) ); // scaling to q_mat + Scale_sig( hDiracDecBin->processMtxDecImPrev_fx[ch][slot], nBins, sub( q_mat, hDiracDecBin->q_processMtxDecPrev ) ); // scaling to q_mat + } + FOR( slot = 0; slot < nchanSeparateChannels; slot++ ) + { + Scale_sig( hDiracDecBin->processMtxRe_fx[ch][slot + BINAURAL_CHANNELS], nBins, sub( q_mat, hDiracDecBin->q_processMtx ) ); // scaling to q_mat + Scale_sig( hDiracDecBin->processMtxIm_fx[ch][slot + BINAURAL_CHANNELS], nBins, sub( q_mat, hDiracDecBin->q_processMtx ) ); // scaling to q_mat + Scale_sig( hDiracDecBin->processMtxRePrev_fx[ch][slot + BINAURAL_CHANNELS], nBins, sub( q_mat, hDiracDecBin->q_processMtxPrev ) ); // scaling to q_mat + Scale_sig( hDiracDecBin->processMtxImPrev_fx[ch][slot + BINAURAL_CHANNELS], nBins, sub( q_mat, hDiracDecBin->q_processMtxPrev ) ); // scaling to q_mat + } + } + hDiracDecBin->q_processMtx = q_mat; + move16(); + hDiracDecBin->q_processMtxPrev = q_mat; + move16(); + hDiracDecBin->q_processMtxDec = q_mat; + move16(); + hDiracDecBin->q_processMtxDecPrev = q_mat; + move16(); + + /* re-use reverb and decorr from main direction for the sides */ + ivas_dirac_dec_binaural_process_output_fx( hDiracDecBin, hSpatParamRendCom, st_ivas->cldfbSynDec, output_fx, &q_out, Cldfb_RealBuffer_in_fx, Cldfb_ImagBuffer_in_fx, q_inp, max_band_decorr, numInChannels, config_data.processReverb, subframe, q_mat, + tmp_Cldfb_out_re, tmp_Cldfb_out_im, reverbRe_fx, reverbIm_fx, decorrRe_fx, decorrIm_fx, &Q_inp_mix, 0 ); + + /* copy from temporary buffer to the main split rendering buffer */ + FOR( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) + { + FOR( i = 0; i < hSpatParamRendCom->subframe_nbslots[subframe]; i++ ) + { + Copy32( tmp_Cldfb_out_re[ch][i], st_ivas->hSplitBinRend->hMultiBinCldfbData->Cldfb_RealBuffer_Binaural_fx[pos_idx * BINAURAL_CHANNELS + ch][hSpatParamRendCom->slots_rendered + i], CLDFB_NO_CHANNELS_MAX ); + Copy32( tmp_Cldfb_out_im[ch][i], st_ivas->hSplitBinRend->hMultiBinCldfbData->Cldfb_ImagBuffer_Binaural_fx[pos_idx * BINAURAL_CHANNELS + ch][hSpatParamRendCom->slots_rendered + i], CLDFB_NO_CHANNELS_MAX ); + } + } + + hDiracDecBin->hDiffuseDist = NULL; + } + } + } + + /* update this counter only after the last rendering of split directions */ +#endif + + hSpatParamRendCom->slots_rendered = add( hSpatParamRendCom->slots_rendered, hSpatParamRendCom->subframe_nbslots[subframe] ); + hSpatParamRendCom->subframes_rendered = add( hSpatParamRendCom->subframes_rendered, 1 ); + + move16(); + move16(); + FOR( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) + { + scale_sig32( output_fx[ch], imult1616( nBins, hSpatParamRendCom->subframe_nbslots[subframe] ), sub( 11, q_out ) ); // Scaling to Q11 + scale_sig32( st_ivas->cldfbSynDec[ch]->cldfb_state_fx, st_ivas->cldfbSynDec[ch]->cldfb_size, sub( Q11, st_ivas->cldfbSynDec[ch]->Q_cldfb_state ) ); + st_ivas->cldfbSynDec[ch]->Q_cldfb_state = Q11; + move16(); + } + + return; +} + + +static void ivas_dirac_dec_decorrelate_slot_fx( + DIRAC_DEC_BIN_HANDLE hDiracDecBin, + const Word16 num_freq_bands, + const Word16 slot, + Word32 inRe[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], /*q_inp*/ + Word32 inIm[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], /*q_inp*/ + Word16 q_inp, + Word32 decRe[][CLDFB_NO_CHANNELS_MAX], /*q_inp*/ + Word32 decIm[][CLDFB_NO_CHANNELS_MAX] /*q_inp*/ ) +{ + Word16 offset, ch, bin; + Word32 onset_filter_fx[BINAURAL_CHANNELS * CLDFB_NO_CHANNELS_MAX]; /* 2 ch, 60 bins */ + Word32 decorrelatedFrameInterleaved_fx[2 * BINAURAL_CHANNELS * CLDFB_NO_CHANNELS_MAX]; /* 2 ch, real + imag, 60 bins */ + Word32 protoFrame_fx[2 * BINAURAL_CHANNELS * CLDFB_NO_CHANNELS_MAX]; /* 2 ch, real + imag, 60 bins */ + Word16 q_decorrelatedFrameInterleaved, q_protoFrame; + const Word16 protoIndexDir[BINAURAL_CHANNELS] = { 0, 1 }; + move16(); + q_protoFrame = q_inp; + move16(); + /* Decorrelation needs interleaved data. Copy left and right signals to proto_frame_f */ + FOR( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) + { + offset = imult1616( imult1616( num_freq_bands, BINAURAL_CHANNELS ), ch ); + FOR( bin = 0; bin < num_freq_bands; bin++ ) + { + protoFrame_fx[add( imult1616( bin, BINAURAL_CHANNELS ), offset )] = inRe[ch][slot][bin]; // q_protoFrame + protoFrame_fx[add( imult1616( bin, BINAURAL_CHANNELS ), add( offset, 1 ) )] = inIm[ch][slot][bin]; // q_protoFrame + move32(); + move32(); + } + } + + /* Decorrelate proto signal to decorrelatedFrameInterleaved */ + ivas_dirac_dec_decorr_process_fx( num_freq_bands, + BINAURAL_CHANNELS, + BINAURAL_CHANNELS, + DIRAC_SYNTHESIS_PSD_LS, + BINAURAL_CHANNELS, + protoFrame_fx, + q_protoFrame, + BINAURAL_CHANNELS, + protoIndexDir, + decorrelatedFrameInterleaved_fx, + &q_decorrelatedFrameInterleaved, + onset_filter_fx, + hDiracDecBin->h_freq_domain_decorr_ap_params, + hDiracDecBin->h_freq_domain_decorr_ap_state ); + + /* De-interleave decorrelated signals*/ + FOR( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) + { + offset = imult1616( imult1616( num_freq_bands, BINAURAL_CHANNELS ), ch ); + FOR( bin = 0; bin < num_freq_bands; bin++ ) + { + decRe[ch][bin] = decorrelatedFrameInterleaved_fx[add( imult1616( bin, BINAURAL_CHANNELS ), offset )]; // q_inp + decIm[ch][bin] = decorrelatedFrameInterleaved_fx[add( imult1616( bin, BINAURAL_CHANNELS ), add( offset, 1 ) )]; // q_inp + move32(); + move32(); + } + } + // q_decorrelatedFrameInterleaved will be same as q_inp/q_protoFrame // + return; +} + + +#ifdef SPLIT_REND_WITH_HEAD_ROT +static void ivas_dirac_dec_binaural_formulate_input_covariance_matrices_fx( + DIRAC_DEC_BIN_HANDLE hDiracDecBin, + SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom, + PARAMBIN_REND_CONFIG_HANDLE hConfig, + Word32 inRe_fx[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], /*q*/ + Word32 inIm_fx[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], /*q*/ + const Word16 subframe, + Word32 *subFrameTotalEne_fx, + Word16 *subFrameTotalEne_e, + Word32 *IIReneLimiter_fx, + Word16 q ) +{ + Word16 ch, slot, bin; + Word16 nBins; + Word32 IIReneLimiterFactor_fx; // Q26 + Word32 qualityBasedSmFactor_fx; + Word32 lowBitRateEQ_fx[CLDFB_NO_CHANNELS_MAX]; + UWord8 applyLowBitRateEQ; + IVAS_FORMAT ivas_format; + Word32 ivas_total_brate; + Word16 nchan_transport; + Word16 exp, exp1; + Word64 temp64; + Word32 temp; + + ivas_format = hConfig->ivas_format; + move32(); + ivas_total_brate = hConfig->ivas_total_brate; + move32(); + nchan_transport = hConfig->nchan_transport; + move16(); + qualityBasedSmFactor_fx = hConfig->qualityBasedSmFactor_fx; /*Q31*/ + move32(); + qualityBasedSmFactor_fx = Mpy_32_32( qualityBasedSmFactor_fx, qualityBasedSmFactor_fx ); /*Q31*/ + + nBins = hSpatParamRendCom->num_freq_bands; /* Actually bins */ + move16(); + + + set32_fx( hDiracDecBin->ChCrossRe_fx, 0, nBins ); + set32_fx( hDiracDecBin->ChCrossIm_fx, 0, nBins ); + + + set16_fx( hDiracDecBin->ChCrossRe_e, 0, nBins ); + set16_fx( hDiracDecBin->ChCrossIm_e, 0, nBins ); + + FOR( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) + { + set32_fx( hDiracDecBin->ChEne_fx[ch], 0, nBins ); + + set16_fx( hDiracDecBin->ChEne_e[ch], 0, nBins ); + } + + set16_fx( subFrameTotalEne_e, 0, CLDFB_NO_CHANNELS_MAX ); + + /* Determine EQ for low bit rates (13.2 and 16.4 kbps) */ + applyLowBitRateEQ = 0; + move16(); + test(); + test(); + IF( ( EQ_32( ivas_format, MASA_FORMAT ) || EQ_32( ivas_format, MC_FORMAT ) ) && LT_32( ivas_total_brate, MASA_STEREO_MIN_BITRATE ) ) + { + applyLowBitRateEQ = 1; + move16(); + IF( EQ_32( ivas_total_brate, IVAS_16k4 ) ) + { + FOR( bin = 0; bin < LOW_BIT_RATE_BINAURAL_EQ_BINS; bin++ ) + { + lowBitRateEQ_fx[bin + LOW_BIT_RATE_BINAURAL_EQ_OFFSET] = L_add( L_shr( lowBitRateBinauralEQ_fx[bin], 1 ), ONE_IN_Q30 ); // Q31 + move32(); + } + } + ELSE + { + FOR( bin = 0; bin < LOW_BIT_RATE_BINAURAL_EQ_BINS; bin++ ) + { + lowBitRateEQ_fx[bin + LOW_BIT_RATE_BINAURAL_EQ_OFFSET] = lowBitRateBinauralEQ_fx[bin]; // Q31 + move32(); + } + } + } + + /* Formulate input and target covariance matrices for this subframe */ + set32_fx( subFrameTotalEne_fx, 0, CLDFB_NO_CHANNELS_MAX ); + + exp = sub( 63, shl( q, 1 ) ); // exp for the energy (inRe_fx * inRe_fx + inIm_fx * inIm_fx) computed below + + /* Calculate input covariance matrix */ + FOR( slot = 0; slot < hSpatParamRendCom->subframe_nbslots[subframe]; slot++ ) + { + FOR( bin = 0; bin < nBins; bin++ ) + { + FOR( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) + { + Word32 instEne_fx; + temp64 = W_mult0_32_32( inRe_fx[ch][slot][bin], inRe_fx[ch][slot][bin] ); // 2q + temp64 = W_add( temp64, W_mult0_32_32( inIm_fx[ch][slot][bin], inIm_fx[ch][slot][bin] ) ); // 2q + exp1 = W_norm( temp64 ); + instEne_fx = W_extract_h( W_shl( temp64, exp1 ) ); // 2q - 32 + exp1 + /* exp of instEne_fx = 31 - (2q -32 + exp1) = 63 - 2q - exp1 = exp - exp1*/ + + hDiracDecBin->ChEne_fx[ch][bin] = BASOP_Util_Add_Mant32Exp( hDiracDecBin->ChEne_fx[ch][bin], hDiracDecBin->ChEne_e[ch][bin], instEne_fx, sub( exp, exp1 ), &hDiracDecBin->ChEne_e[ch][bin] ); + subFrameTotalEne_fx[bin] = BASOP_Util_Add_Mant32Exp( subFrameTotalEne_fx[bin], subFrameTotalEne_e[bin], instEne_fx, sub( exp, exp1 ), &subFrameTotalEne_e[bin] ); + move32(); + move32(); + } + temp64 = W_mult0_32_32( inRe_fx[0][slot][bin], inRe_fx[1][slot][bin] ); // 2q + temp64 = W_add( temp64, W_mult0_32_32( inIm_fx[0][slot][bin], inIm_fx[1][slot][bin] ) ); // 2q + exp1 = W_norm( temp64 ); + temp = W_extract_h( W_shl( temp64, exp1 ) ); // // 2q - 32 + exp1 + hDiracDecBin->ChCrossRe_fx[bin] = BASOP_Util_Add_Mant32Exp( hDiracDecBin->ChCrossRe_fx[bin], hDiracDecBin->ChCrossRe_e[bin], temp, sub( exp, exp1 ), &hDiracDecBin->ChCrossRe_e[bin] ); + move32(); + + temp64 = W_mult0_32_32( inRe_fx[0][slot][bin], inIm_fx[1][slot][bin] ); // 2q + temp64 = W_sub( temp64, W_mult0_32_32( inIm_fx[0][slot][bin], inRe_fx[1][slot][bin] ) ); // 2q + exp1 = W_norm( temp64 ); + temp = W_extract_h( W_shl( temp64, exp1 ) ); // // 2q - 32 + exp1 + hDiracDecBin->ChCrossIm_fx[bin] = BASOP_Util_Add_Mant32Exp( hDiracDecBin->ChCrossIm_fx[bin], hDiracDecBin->ChCrossIm_e[bin], temp, sub( exp, exp1 ), &hDiracDecBin->ChCrossIm_e[bin] ); + move32(); + } + } + + /* Apply EQ at low bit rates */ + IF( applyLowBitRateEQ != 0 ) + { + Word16 lastEqBin = LOW_BIT_RATE_BINAURAL_EQ_OFFSET + LOW_BIT_RATE_BINAURAL_EQ_BINS - 1; + + FOR( bin = LOW_BIT_RATE_BINAURAL_EQ_OFFSET; bin < lastEqBin; bin++ ) + { + subFrameTotalEne_fx[bin] = Mpy_32_32( subFrameTotalEne_fx[bin], lowBitRateEQ_fx[bin] ); // exp = subFrameTotalEne_e[bin] + move32(); + } + FOR( ; bin < nBins; bin++ ) + { + subFrameTotalEne_fx[bin] = Mpy_32_32( subFrameTotalEne_fx[bin], lowBitRateEQ_fx[lastEqBin] ); // exp = subFrameTotalEne_e[bin] + move32(); + } + } + + test(); + test(); + IF( ( EQ_32( ivas_format, SBA_FORMAT ) || EQ_32( ivas_format, SBA_ISM_FORMAT ) ) && EQ_16( nchan_transport, 2 ) ) + { + Word32 tempRe, tempIm; + Word32 subFrameSumEne_fx[CLDFB_NO_CHANNELS_MAX]; + Word16 subFrameSumEne_e[CLDFB_NO_CHANNELS_MAX]; + + set32_fx( subFrameSumEne_fx, 0, CLDFB_NO_CHANNELS_MAX ); + set16_fx( subFrameSumEne_e, 0, CLDFB_NO_CHANNELS_MAX ); + FOR( slot = 0; slot < hSpatParamRendCom->subframe_nbslots[subframe]; slot++ ) + { + FOR( bin = 0; bin < nBins; bin++ ) + { + tempRe = L_add( inRe_fx[0][slot][bin], inRe_fx[1][slot][bin] ); // q + tempIm = L_add( inIm_fx[0][slot][bin], inIm_fx[1][slot][bin] ); // q + temp64 = W_add( W_mult0_32_32( tempRe, tempRe ), W_mult0_32_32( tempIm, tempIm ) ); // 2q + exp1 = W_norm( temp64 ); + temp64 = W_shl( temp64, exp1 ); // 2q + exp1 + subFrameSumEne_fx[bin] = BASOP_Util_Add_Mant32Exp( subFrameSumEne_fx[bin], subFrameTotalEne_e[bin], W_extract_h( temp64 ), sub( exp /* 63 - 2q */, exp1 ) /*31 - (2q + exp1 - 32)*/, &subFrameTotalEne_e[bin] ); + move32(); + } + } + FOR( bin = 0; bin < nBins; bin++ ) + { + temp = L_shl_sat( subFrameTotalEne_fx[bin], sub( subFrameTotalEne_e[bin], subFrameSumEne_e[bin] ) ); // subFrameSumEne_e[bin] + IF( GT_32( subFrameSumEne_fx[bin], temp ) ) + { + subFrameTotalEne_fx[bin] = subFrameSumEne_fx[bin]; + move32(); + subFrameTotalEne_e[bin] = subFrameSumEne_e[bin]; + move16(); + } + } + } + + + test(); + /* Temporal IIR-type smoothing of covariance matrices. Also apply encoding quality based smoothing factor. */ + IF( EQ_32( ivas_format, MASA_FORMAT ) && LT_32( ivas_total_brate, MASA_STEREO_MIN_BITRATE ) ) + { + IIReneLimiterFactor_fx = L_add( L_shl( 16, Q26 ), L_sub( L_shl( 1, Q26 ), L_shr( qualityBasedSmFactor_fx, 5 ) ) ); // Q26 + } + ELSE + { + IIReneLimiterFactor_fx = L_add( L_shl( 8, Q26 ), L_sub( L_shl( 1, Q26 ), L_shr( qualityBasedSmFactor_fx, 5 ) ) ); // Q26 + } + + FOR( bin = 0; bin < nBins; bin++ ) + { + + /* Temporally smooth cov mtx estimates for resulting mixing matrix stability. The design principle is that + * the energy history (IIR) must not be more than double of the current frame energy. This provides more + * robust performance at energy offsets when compared to typical IIR averaging. */ + Word16 num_e, den_e; + Word32 num, den; + num = BASOP_Util_Add_Mant32Exp( hDiracDecBin->ChEne_fx[0][bin], hDiracDecBin->ChEne_e[0][bin], hDiracDecBin->ChEne_fx[1][bin], hDiracDecBin->ChEne_e[1][bin], &num_e ); + num = Mpy_32_32( num, IIReneLimiterFactor_fx ); /*Q = (31 - num_e + 26 - 31) = (26 - num_e)*/ + den_e = 0; + move16(); + den = BASOP_Util_Add_Mant32Exp( hDiracDecBin->ChEnePrev_fx[0][bin], hDiracDecBin->ChEnePrev_e[0][bin], hDiracDecBin->ChEnePrev_fx[1][bin], hDiracDecBin->ChEnePrev_e[1][bin], &den_e ); + den = L_max( 1, den ); + IIReneLimiter_fx[bin] = BASOP_Util_Divide3232_Scale_cadence( num, den, &exp ); + exp = add( sub( num_e, den_e ), add( 5, exp ) ); + IF( L_shr_sat( IIReneLimiter_fx[bin], sub( 31, exp ) ) > 0 ) + { + IIReneLimiter_fx[bin] = ONE_IN_Q31; /*Q31*/ + move32(); + } + ELSE + { + IIReneLimiter_fx[bin] = L_shl( IIReneLimiter_fx[bin], exp ); /*Q31*/ + } + + hDiracDecBin->ChCrossRe_fx[bin] = Mpy_32_32( hDiracDecBin->ChCrossRe_fx[bin], qualityBasedSmFactor_fx ); + hDiracDecBin->ChCrossIm_fx[bin] = Mpy_32_32( hDiracDecBin->ChCrossIm_fx[bin], qualityBasedSmFactor_fx ); + + move32(); + move32(); + move32(); + move32(); + + FOR( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) + { + hDiracDecBin->ChEne_fx[ch][bin] = Mpy_32_32( hDiracDecBin->ChEne_fx[ch][bin], qualityBasedSmFactor_fx ); + move32(); + } + + hDiracDecBin->ChCrossRe_fx[bin] = BASOP_Util_Add_Mant32Exp( hDiracDecBin->ChCrossRe_fx[bin], hDiracDecBin->ChCrossRe_e[bin], Mpy_32_32( hDiracDecBin->ChCrossRePrev_fx[bin], IIReneLimiter_fx[bin] ), hDiracDecBin->ChCrossRePrev_e[bin], &hDiracDecBin->ChCrossRe_e[bin] ); + hDiracDecBin->ChCrossIm_fx[bin] = BASOP_Util_Add_Mant32Exp( hDiracDecBin->ChCrossIm_fx[bin], hDiracDecBin->ChCrossIm_e[bin], Mpy_32_32( hDiracDecBin->ChCrossImPrev_fx[bin], IIReneLimiter_fx[bin] ), hDiracDecBin->ChCrossImPrev_e[bin], &hDiracDecBin->ChCrossIm_e[bin] ); + move32(); + move32(); + + FOR( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) + { + hDiracDecBin->ChEne_fx[ch][bin] = BASOP_Util_Add_Mant32Exp( hDiracDecBin->ChEne_fx[ch][bin], hDiracDecBin->ChEne_e[ch][bin], Mpy_32_32( hDiracDecBin->ChEnePrev_fx[ch][bin], IIReneLimiter_fx[bin] ), hDiracDecBin->ChEnePrev_e[ch][bin], &hDiracDecBin->ChEne_e[ch][bin] ); + move32(); + } + + /* Store energy values and coefficients for next round */ + hDiracDecBin->ChCrossRePrev_fx[bin] = hDiracDecBin->ChCrossRe_fx[bin]; + move32(); + hDiracDecBin->ChCrossImPrev_fx[bin] = hDiracDecBin->ChCrossIm_fx[bin]; + move32(); + hDiracDecBin->ChCrossRePrev_e[bin] = hDiracDecBin->ChCrossRe_e[bin]; + move16(); + hDiracDecBin->ChCrossImPrev_e[bin] = hDiracDecBin->ChCrossIm_e[bin]; + move16(); + + FOR( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) + { + hDiracDecBin->ChEnePrev_fx[ch][bin] = hDiracDecBin->ChEne_fx[ch][bin]; + move32(); + hDiracDecBin->ChEnePrev_e[ch][bin] = hDiracDecBin->ChEne_e[ch][bin]; + move16(); + } + } + + return; +} + +static void ivas_dirac_dec_binaural_formulate_target_covariance_matrices_fx( + DIRAC_DEC_BIN_HANDLE hDiracDecBin, + const SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom, + const PARAMBIN_REND_CONFIG_HANDLE hConfig, + Word32 Rmat_fx[3][3], + const int16_t subframe, + const int16_t isHeadtracked, + const Word32 *subFrameTotalEne_fx, + Word16 *subFrameTotalEne_e, + const Word32 *IIReneLimiter_fx, + const MASA_ISM_DATA_HANDLE hMasaIsmData ) +{ + Word16 ch, bin; + Word16 separateCenterChannelRendering; + Word16 nBins, idx, shift; + Word32 frameMeanDiffusenessEneWeight_fx[CLDFB_NO_CHANNELS_MAX]; + Word32 qualityBasedSmFactor_fx; + Word16 dirac_read_idx; + PARAMBIN_HRTF_GAIN_CACHE gainCache[MAX_GAIN_CACHE_SIZE]; + IVAS_FORMAT ivas_format; + MC_MODE mc_mode; + Word16 gainCacheBaseIndex; + Word16 q_earlyPartEneCorrection; + Word16 exp, exp1; + Word32 temp; + + separateCenterChannelRendering = hConfig->separateCenterChannelRendering; + move16(); + ivas_format = hConfig->ivas_format; + move32(); + mc_mode = hConfig->mc_mode; + move32(); + qualityBasedSmFactor_fx = hConfig->qualityBasedSmFactor_fx; /*Q31*/ + move32(); + qualityBasedSmFactor_fx = Mpy_32_32( qualityBasedSmFactor_fx, qualityBasedSmFactor_fx ); /*Q31*/ + + nBins = hSpatParamRendCom->num_freq_bands; /* Actually bins */ + move16(); + + q_earlyPartEneCorrection = s_min( Q31, add( getScaleFactor32( hDiracDecBin->earlyPartEneCorrection_fx, nBins ), hDiracDecBin->q_earlyPartEneCorrection ) ); + scale_sig32( hDiracDecBin->earlyPartEneCorrection_fx, nBins, sub( q_earlyPartEneCorrection, hDiracDecBin->q_earlyPartEneCorrection ) ); + hDiracDecBin->q_earlyPartEneCorrection = q_earlyPartEneCorrection; + move16(); + + set32_fx( hDiracDecBin->ChCrossReOut_fx, 0, nBins ); + set32_fx( hDiracDecBin->ChCrossImOut_fx, 0, nBins ); + set16_fx( hDiracDecBin->ChCrossReOut_e, 0, nBins ); + set16_fx( hDiracDecBin->ChCrossImOut_e, 0, nBins ); + + FOR( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) + { + set32_fx( hDiracDecBin->ChEneOut_fx[ch], 0, nBins ); + set16_fx( hDiracDecBin->ChEneOut_e[ch], 0, nBins ); + } + set32_fx( hDiracDecBin->frameMeanDiffuseness_fx, 0, nBins ); + + set32_fx( frameMeanDiffusenessEneWeight_fx, 0, CLDFB_NO_CHANNELS_MAX ); + + FOR( idx = 0; idx < MAX_GAIN_CACHE_SIZE; idx++ ) + { + gainCache[idx].azi = -1000; /* Use -1000 as value for uninitialized cache. */ + move16(); + } + + dirac_read_idx = hSpatParamRendCom->render_to_md_map[subframe]; + + /* Determine target covariance matrix containing target binaural properties */ + FOR( bin = 0; bin < nBins; bin++ ) + { + Word32 diffuseness_fx = ONE_IN_Q30; /* ratio1 and ratio2 are subtracted from diffuseness further below */ + Word32 diffusenessValForDecorrelationReduction_fx = ONE_IN_Q30; + Word32 diffEneValForDecorrelationReduction_fx; + Word16 q_diffEneValForDecorrelationReduction; + Word16 surCoh_fx = 0, spreadCoh_fx = 0; /* Default values if spreadSurroundCoherenceApplied == false */ + Word32 diffEne_fx, dirEne_fx, meanEnePerCh_fx; + Word16 q_meanEnePerCh; + Word16 q_diffEne, q_dirEne; + Word16 dirIndex; + move16(); + move16(); + move32(); + move32(); + + /* When BINAURAL_ROOM is not indicated, hBinaural->earlyPartEneCorrection[bin] values are all 1.0f. + * When BINAURAL_ROOM is indicated, the binaural audio output is based on combined use of the + * HRTF data set and a BRIR-based data set. The HRTF data set is spectrally corrected to match + * the early spectrum of the BRIR data, using the spectral correction data in + * hBinaural->earlyPartEneCorrection[bin], based on the BRIR set. */ + meanEnePerCh_fx = Mpy_32_32( hDiracDecBin->earlyPartEneCorrection_fx[bin], subFrameTotalEne_fx[bin] ); // Q( q_meanEnePerCh ) + q_meanEnePerCh = add( sub( q_earlyPartEneCorrection, subFrameTotalEne_e[bin] ), 1 ); // q_earlyPartEneCorrection + 31 - subFrameTotalEne_e[bin] - 31 + Q1(0.5f) + /* Determine direct part target covariance matrix (for 1 or 2 directions) */ + FOR( dirIndex = 0; dirIndex < hSpatParamRendCom->numSimultaneousDirections; dirIndex++ ) + { + Word16 aziDeg, eleDeg; + Word32 lRealp_fx, lImagp_fx, rRealp_fx, rImagp_fx; + Word32 lRealpTmp_fx, lImagpTmp_fx, rRealpTmp_fx, rImagpTmp_fx; + Word32 hrtfEne_fx[BINAURAL_CHANNELS], hrtfCrossRe_fx, hrtfCrossIm_fx, ratio_fx; + UWord8 isIsmDirection = 0; + move16(); + + test(); + test(); + IF( dirIndex == 0 ) /* For first of the two simultaneous directions */ + { + aziDeg = hSpatParamRendCom->azimuth[dirac_read_idx][bin]; + move16(); + eleDeg = hSpatParamRendCom->elevation[dirac_read_idx][bin]; + move16(); + ratio_fx = hSpatParamRendCom->energy_ratio1_fx[dirac_read_idx][bin]; + move32(); + spreadCoh_fx = hSpatParamRendCom->spreadCoherence_fx[dirac_read_idx][bin]; + move16(); + gainCacheBaseIndex = 0; + move16(); + } + ELSE IF( NE_32( ivas_format, MASA_ISM_FORMAT ) || ( EQ_32( ivas_format, MASA_ISM_FORMAT ) && LT_16( dirIndex, hSpatParamRendCom->numParametricDirections ) ) ) /* For second of the two simultaneous directions */ + { + IF( LT_32( ( ratio_fx = hSpatParamRendCom->energy_ratio2_fx[dirac_read_idx][bin] ), 10737418 /* 0.01 in Q30 */ ) ) + { + /* This touches only MASA path where second direction always has smaller ratio and + * for non-2dir it is zero. As the whole direction contribution is multiplied with + * the ratio, a very small ratio does not contribute any energy to output. Thus, + * it is better to save complexity. */ + CONTINUE; + } + aziDeg = hSpatParamRendCom->azimuth2[dirac_read_idx][bin]; + move16(); + eleDeg = hSpatParamRendCom->elevation2[dirac_read_idx][bin]; + move16(); + spreadCoh_fx = hSpatParamRendCom->spreadCoherence2_fx[dirac_read_idx][bin]; + move16(); + gainCacheBaseIndex = 3; + move16(); + } + ELSE /* For object directions of MASA_ISM_FORMAT */ + { + isIsmDirection = 1; + move16(); + UWord16 ismDirIndex; + ismDirIndex = sub( dirIndex, hSpatParamRendCom->numParametricDirections ); + assert( hMasaIsmData != NULL && "hMasaIsmData should not be NULL if we use it" ); + IF( hMasaIsmData->ism_is_edited[ismDirIndex] ) + { + aziDeg = hMasaIsmData->azimuth_ism_edited[ismDirIndex]; + move16(); + eleDeg = hMasaIsmData->elevation_ism_edited[ismDirIndex]; + move16(); + } + ELSE + { + aziDeg = hMasaIsmData->azimuth_ism[ismDirIndex][dirac_read_idx]; + move16(); + eleDeg = hMasaIsmData->elevation_ism[ismDirIndex][dirac_read_idx]; + move16(); + } + ratio_fx = hMasaIsmData->energy_ratio_ism_fx[ismDirIndex][dirac_read_idx][bin]; + move32(); + spreadCoh_fx = 0; + move16(); + gainCacheBaseIndex = add( 6, ismDirIndex ); + } + + diffuseness_fx = L_sub( diffuseness_fx, ratio_fx ); /* diffuseness = 1 - ratio1 - ratio2 */ + + if ( diffuseness_fx < 0 ) + { + diffuseness_fx = 0; + move32(); + } + IF( isIsmDirection ) + { + /* Objects cause lesser decorrelation reduction, to avoid removing all decorrelation when only objects are present */ + diffusenessValForDecorrelationReduction_fx = L_sub( diffusenessValForDecorrelationReduction_fx, L_shr( ratio_fx, 1 ) ); /*Q30*/ + } + ELSE + { + diffusenessValForDecorrelationReduction_fx = L_sub( diffusenessValForDecorrelationReduction_fx, ratio_fx ); /*Q30*/ + } + + IF( separateCenterChannelRendering ) + { + /* In masa + mono rendering mode, the center directions originate from phantom sources, so the + * spread coherence is increased */ + Word16 azi_scaled, ele_scaled; + Word32 doaVectorX_fx, num, den; + Word16 e = 0, spatialAngleDeg_fx, altSpreadCoh_fx; + move16(); + + azi_scaled = i_mult( aziDeg, 91 ); + ele_scaled = i_mult( eleDeg, 91 ); + doaVectorX_fx = L_mult( getCosWord16R2( azi_scaled ), getCosWord16R2( ele_scaled ) ); /*Q31*/ + num = Sqrt32( L_sub( ONE_IN_Q31, Mpy_32_32( doaVectorX_fx, doaVectorX_fx ) ), &e ); + den = doaVectorX_fx; + move32(); + spatialAngleDeg_fx = BASOP_util_atan2( num, den, e ); // Q13 + Word16 numr, num_e = 0, denr, den_e; + move16(); + num_e = sub( norm_s( spatialAngleDeg_fx ), 1 ); + numr = shl( spatialAngleDeg_fx, num_e ); + denr = 17157; + move16(); + den_e = 4; + move16(); + altSpreadCoh_fx = sub( 32767, shl_sat( div_s( numr, denr ), sub( den_e, num_e ) ) ); // 4289 = pi/6 in Q13 + spreadCoh_fx = s_max( spreadCoh_fx, altSpreadCoh_fx ); + } + + getDirectPartGains_fx( bin, aziDeg, eleDeg, &lRealp_fx, &lImagp_fx, &rRealp_fx, &rImagp_fx, hDiracDecBin->renderStereoOutputInsteadOfBinaural, Rmat_fx, &gainCache[gainCacheBaseIndex], isHeadtracked ); + + Word16 q_lr = Q28; + move16(); + if ( hDiracDecBin->renderStereoOutputInsteadOfBinaural ) + { + /* Synthesizing spread coherence is not needed for stereo loudspeaker output, + * as directional sound is reproduced with two loudspeakers in any case */ + spreadCoh_fx = 0; + move32(); + } + + IF( spreadCoh_fx > 0 ) + { + Word32 centerMul_fx, sidesMul_fx; + Word32 hrtfEneCenter_fx, hrtfEneSides_fx, hrtfEneRealized_fx; + Word16 eneCorrectionFactor_fx, eneCorrectionFactor_e; + Word16 w1_fx, w2_fx, w3_fx, eq_fx; + + hrtfEneCenter_fx = L_add( Mpy_32_32( lRealp_fx, lRealp_fx ), // Q25 + L_add( Mpy_32_32( lImagp_fx, lImagp_fx ), // Q25 + L_add( Mpy_32_32( rRealp_fx, rRealp_fx ), // Q25 + Mpy_32_32( rImagp_fx, rImagp_fx ) ) ) ); // Q25 + + /* Spread coherence is synthesized as coherent sources at 30 degree horizontal spacing. + * The following formulas determine the gains for these sources. + * spreadCoh = 0: Only panning + * spreadCoh = 0.5: Three sources coherent panning (e.g. 30 0 -30 deg azi) + * spreadCoh = 1.0: Two sources coherent panning with gap (as above, but center is silent) */ + IF( LT_16( spreadCoh_fx, 16384 ) ) + { + /* 0.0f < spreadCoh < 0.5f */ + sidesMul_fx = L_mult0( spreadCoh_fx, 9459 ); /* 2*sqrt(1/3) in Q13 = 9459 */ // Q28 + centerMul_fx = L_add( L_sub( ONE_IN_Q28, L_shl( spreadCoh_fx, 14 ) ), sidesMul_fx ); // Q28 + } + ELSE + { + /* 0.5f <= spreadCoh < 1.0f */ + // centerMul = 2.0f - ( 2.0f * spreadCoh ); + centerMul_fx = L_shl( sub( 32767, spreadCoh_fx ), 14 ); // Q28 + sidesMul_fx = Isqrt( L_add( L_shr( centerMul_fx, 22 ), L_shl( 2, Q6 ) ) ); // Q28 + centerMul_fx = L_shl( Mpy_32_32( centerMul_fx, sidesMul_fx ), 3 ); // Q28 + } + + /* Apply the gain for the center source of the three coherent sources */ + lRealp_fx = Mpy_32_32( lRealp_fx, centerMul_fx ); // Q25 + lImagp_fx = Mpy_32_32( lImagp_fx, centerMul_fx ); // Q25 + rRealp_fx = Mpy_32_32( rRealp_fx, centerMul_fx ); // Q25 + rImagp_fx = Mpy_32_32( rImagp_fx, centerMul_fx ); // Q25 + + /* Apply the gain for the left source of the three coherent sources */ + getDirectPartGains_fx( bin, add( aziDeg, 30 ), eleDeg, &lRealpTmp_fx, &lImagpTmp_fx, &rRealpTmp_fx, &rImagpTmp_fx, hDiracDecBin->renderStereoOutputInsteadOfBinaural, Rmat_fx, &gainCache[gainCacheBaseIndex + 1], isHeadtracked ); + + hrtfEneSides_fx = L_add( Mpy_32_32( lRealpTmp_fx, lRealpTmp_fx ), // Q25 + L_add( Mpy_32_32( lImagpTmp_fx, lImagpTmp_fx ), // Q25 + L_add( Mpy_32_32( rRealpTmp_fx, rRealpTmp_fx ), // Q25 + Mpy_32_32( rImagpTmp_fx, rImagpTmp_fx ) ) ) ); // Q25 + lRealp_fx = L_add( lRealp_fx, Mpy_32_32( sidesMul_fx, lRealpTmp_fx ) ); // Q25 + lImagp_fx = L_add( lImagp_fx, Mpy_32_32( sidesMul_fx, lImagpTmp_fx ) ); // Q25 + rRealp_fx = L_add( rRealp_fx, Mpy_32_32( sidesMul_fx, rRealpTmp_fx ) ); // Q25 + rImagp_fx = L_add( rImagp_fx, Mpy_32_32( sidesMul_fx, rImagpTmp_fx ) ); // Q25 + + /* Apply the gain for the right source of the three coherent sources. + * -30 degrees to 330 wrapping due to internal functions. */ + + getDirectPartGains_fx( bin, aziDeg + 330, eleDeg, &lRealpTmp_fx, &lImagpTmp_fx, &rRealpTmp_fx, &rImagpTmp_fx, hDiracDecBin->renderStereoOutputInsteadOfBinaural, Rmat_fx, &gainCache[gainCacheBaseIndex + 2], isHeadtracked ); + + hrtfEneSides_fx = L_add( hrtfEneSides_fx, + L_add( Mpy_32_32( lRealpTmp_fx, lRealpTmp_fx ), // Q25 + L_add( Mpy_32_32( lImagpTmp_fx, lImagpTmp_fx ), // Q25 + L_add( Mpy_32_32( rRealpTmp_fx, rRealpTmp_fx ), // Q25 + Mpy_32_32( rImagpTmp_fx, rImagpTmp_fx ) ) ) ) ); // Q25 + lRealp_fx = L_add( lRealp_fx, Mpy_32_32( sidesMul_fx, lRealpTmp_fx ) ); // Q25 + lImagp_fx = L_add( lImagp_fx, Mpy_32_32( sidesMul_fx, lImagpTmp_fx ) ); // Q25 + rRealp_fx = L_add( rRealp_fx, Mpy_32_32( sidesMul_fx, rRealpTmp_fx ) ); // Q25 + rImagp_fx = L_add( rImagp_fx, Mpy_32_32( sidesMul_fx, rImagpTmp_fx ) ); // Q25 + + /* Formulate an eneCorrectionFactor that compensates for the coherent summation of the HRTFs */ + hrtfEneRealized_fx = L_add( Mpy_32_32( lRealp_fx, lRealp_fx ), // Q19 + L_add( Mpy_32_32( lImagp_fx, lImagp_fx ), // Q19 + L_add( Mpy_32_32( rRealp_fx, rRealp_fx ), // Q19 + Mpy_32_32( rImagp_fx, rImagp_fx ) ) ) ); // Q19 + + eneCorrectionFactor_fx = BASOP_Util_Divide3232_Scale( L_add( Mpy_32_32( hrtfEneSides_fx, Mpy_32_32( sidesMul_fx, sidesMul_fx ) ), + Mpy_32_32( hrtfEneCenter_fx, Mpy_32_32( centerMul_fx, centerMul_fx ) ) ), + L_max( 1, hrtfEneRealized_fx ), &eneCorrectionFactor_e ); + + /* Weighting factors to determine appropriate target spectrum for spread coherent sound */ + IF( LT_16( spreadCoh_fx, 16384 ) ) + { + w1_fx = sub( 32767, shl( spreadCoh_fx, 1 ) ); /*Q15*/ + w2_fx = shl( spreadCoh_fx, 1 ); /*Q15*/ + w3_fx = 0; + move16(); + } + ELSE + { + w1_fx = 0; + move16(); + w2_fx = shl( sub( 32767, spreadCoh_fx ), 1 ); /*Q15*/ + w3_fx = shl( sub( spreadCoh_fx, 16384 ), 1 ); /*Q15*/ + } + + test(); + IF( ( EQ_32( ivas_format, MC_FORMAT ) && EQ_32( mc_mode, MC_MODE_MCMASA ) ) ) + { + idx = s_min( bin, MASA_NUM_DEFINED_SUR_SPR_COH_ENE_BINS - 1 ); + + /* Apply the target spectrum to the eneCorrectionFactor */ + IF( separateCenterChannelRendering ) /* spreadCoh mostly originates from phantom sources in separate channel rendering mode */ + { + eneCorrectionFactor_fx = mult_r( eneCorrectionFactor_fx, add( mult_r( w1_fx, 8192 ), shr( mult_r( add( w2_fx, w3_fx ), spreadCohEne1_fx[idx] ), 1 ) ) ); + eneCorrectionFactor_e = add( eneCorrectionFactor_e, 2 ); + } + ELSE + { + eneCorrectionFactor_fx = mult_r( eneCorrectionFactor_fx, add( mult_r( w1_fx, 4096 ), add( shr( mult_r( w2_fx, spreadCohEne05_fx[idx] ), 1 ), shr( mult_r( w3_fx, spreadCohEne1_fx[idx] ), 2 ) ) ) ); + eneCorrectionFactor_e = add( eneCorrectionFactor_e, 3 ); + } + } + + /* Equalize the spread coherent combined HRTFs */ + Word16 tmp, tmp_e; + tmp_e = eneCorrectionFactor_e; + move16(); + tmp = Sqrt16( eneCorrectionFactor_fx, &tmp_e ); + IF( GE_16( shr( tmp, sub( 15, tmp_e ) ), 4 ) ) + { + eq_fx = 32767; // Q13 + move16(); + } + ELSE + { + eq_fx = shl( tmp, sub( tmp_e, 2 ) ); // Q13 + } + + lRealp_fx = Mpy_32_16_1( lRealp_fx, eq_fx ); // Q23 + lImagp_fx = Mpy_32_16_1( lImagp_fx, eq_fx ); // Q23 + rRealp_fx = Mpy_32_16_1( rRealp_fx, eq_fx ); // Q23 + rImagp_fx = Mpy_32_16_1( rImagp_fx, eq_fx ); // Q23 + q_lr = Q23; + move16(); + } + + hrtfEne_fx[0] = L_add( Mpy_32_32( lRealp_fx, lRealp_fx ), Mpy_32_32( lImagp_fx, lImagp_fx ) ); // Q( 2*q_lr - 31 ) + hrtfEne_fx[1] = L_add( Mpy_32_32( rRealp_fx, rRealp_fx ), Mpy_32_32( rImagp_fx, rImagp_fx ) ); // Q( 2*q_lr - 31 ) + move32(); + move32(); + hrtfCrossRe_fx = L_add( Mpy_32_32( lRealp_fx, rRealp_fx ), Mpy_32_32( lImagp_fx, rImagp_fx ) ); // Q( 2*q_lr - 31 ) + hrtfCrossIm_fx = L_add( Mpy_32_32( -lImagp_fx, rRealp_fx ), Mpy_32_32( lRealp_fx, rImagp_fx ) ); // Q( 2*q_lr - 31 ) + + /* Add direct part (1 or 2) covariance matrix */ + dirEne_fx = Mpy_32_32( ratio_fx, meanEnePerCh_fx ); // Q(q_meanEnePerCh - 1) + shift = norm_l( dirEne_fx ); + dirEne_fx = L_shl( dirEne_fx, shift ); + q_dirEne = add( sub( q_meanEnePerCh, 1 ), shift ); + + hDiracDecBin->ChEneOut_fx[0][bin] = BASOP_Util_Add_Mant32Exp( hDiracDecBin->ChEneOut_fx[0][bin], hDiracDecBin->ChEneOut_e[0][bin], Mpy_32_32( dirEne_fx, hrtfEne_fx[0] ), sub( 31, sub( add( q_dirEne, shl( q_lr, 1 ) ), 62 ) ), &hDiracDecBin->ChEneOut_e[0][bin] ); /* Dir ene part*/ + hDiracDecBin->ChEneOut_fx[1][bin] = BASOP_Util_Add_Mant32Exp( hDiracDecBin->ChEneOut_fx[1][bin], hDiracDecBin->ChEneOut_e[1][bin], Mpy_32_32( dirEne_fx, hrtfEne_fx[1] ), sub( 31, sub( add( q_dirEne, shl( q_lr, 1 ) ), 62 ) ), &hDiracDecBin->ChEneOut_e[1][bin] ); + hDiracDecBin->ChCrossReOut_fx[bin] = BASOP_Util_Add_Mant32Exp( hDiracDecBin->ChCrossReOut_fx[bin], hDiracDecBin->ChCrossReOut_e[bin], Mpy_32_32( dirEne_fx, hrtfCrossRe_fx ), sub( 31, sub( add( q_dirEne, shl( q_lr, 1 ) ), 62 ) ), &hDiracDecBin->ChCrossReOut_e[bin] ); /* Dir cross re */ + hDiracDecBin->ChCrossImOut_fx[bin] = BASOP_Util_Add_Mant32Exp( hDiracDecBin->ChCrossImOut_fx[bin], hDiracDecBin->ChCrossImOut_e[bin], Mpy_32_32( dirEne_fx, hrtfCrossIm_fx ), sub( 31, sub( add( q_dirEne, shl( q_lr, 1 ) ), 62 ) ), &hDiracDecBin->ChCrossImOut_e[bin] ); /* Dir cross im */ + move32(); + move32(); + move32(); + move32(); + } + + /* Add diffuse / ambient part covariance matrix */ + diffuseness_fx = L_max( 0, diffuseness_fx ); // Q30 + diffEne_fx = Mpy_32_32( diffuseness_fx, meanEnePerCh_fx ); // Q(2q - 32) + shift = norm_l( diffEne_fx ); + diffEne_fx = L_shl( diffEne_fx, shift ); + q_diffEne = add( shift, sub( q_meanEnePerCh, 1 ) ); - nchanSeparateChannels = 0; - move16(); - test(); - test(); - test(); - test(); - test(); - test(); - IF( config_data.separateCenterChannelRendering || ( EQ_32( st_ivas->ivas_format, MASA_ISM_FORMAT ) && ( EQ_32( st_ivas->ism_mode, ISM_MASA_MODE_MASA_ONE_OBJ ) || EQ_32( st_ivas->ism_mode, ISM_MASA_MODE_PARAM_ONE_OBJ ) ) ) ) - { - nchanSeparateChannels = 1; - move16(); - } - ELSE IF( EQ_32( st_ivas->ivas_format, MASA_ISM_FORMAT ) && EQ_32( st_ivas->ism_mode, ISM_MASA_MODE_DISC ) && ( EQ_32( st_ivas->renderer_type, RENDERER_STEREO_PARAMETRIC ) || EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_PARAMETRIC_ROOM ) ) ) - { - nchanSeparateChannels = (UWord8) st_ivas->nchan_ism; + surCoh_fx = hSpatParamRendCom->surroundingCoherence_fx[dirac_read_idx][bin]; // Q15 move16(); - } - ivas_dirac_dec_binaural_determine_processing_matrices_fx( hDiracDecBin, hSpatParamRendCom, &config_data, max_band_decorr, Rmat_fx, subframe, - hCombinedOrientationData && hCombinedOrientationData->enableCombinedOrientation[hCombinedOrientationData->subframe_idx] > 0, nchanSeparateChannels, st_ivas->hMasaIsmData ); + diffusenessValForDecorrelationReduction_fx = L_max( 0, diffusenessValForDecorrelationReduction_fx ); // Q30 + diffEneValForDecorrelationReduction_fx = Mpy_32_32( diffusenessValForDecorrelationReduction_fx, meanEnePerCh_fx ); // resulting Q = q_meanEnePerCh - 1 + q_diffEneValForDecorrelationReduction = sub( q_meanEnePerCh, 1 ); - q_inp = Q6; - move16(); - FOR( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) - { - st_ivas->cldfbSynDec[ch]->Q_cldfb_state = Q11; - move16(); - } + test(); + IF( ( EQ_32( ivas_format, MC_FORMAT ) && EQ_32( mc_mode, MC_MODE_MCMASA ) ) ) + { + IF( !hDiracDecBin->renderStereoOutputInsteadOfBinaural ) + { + Word32 spectrumModVal; - q_mat = hDiracDecBin->q_processMtx; - move16(); - q_mat = s_min( q_mat, hDiracDecBin->q_processMtxPrev ); - q_mat = s_min( q_mat, hDiracDecBin->q_processMtxDec ); - q_mat = s_min( q_mat, hDiracDecBin->q_processMtxDecPrev ); + idx = s_min( bin, MASA_NUM_DEFINED_SUR_SPR_COH_ENE_BINS - 1 ); + /* Apply target spectrum that emphasizes low frequencies when the sound is surround coherent */ + spectrumModVal = L_add( L_sub( ONE_IN_Q29, L_shl( surCoh_fx, 14 ) ), L_mult( surCoh_fx, surCohEne_fx[idx] ) ); // Q29 + diffEne_fx = Mpy_32_32( diffEne_fx, spectrumModVal ); // Q-2 + q_diffEne = sub( q_diffEne, 2 ); + /* Modify also the value for decorrelation reduction */ + diffEneValForDecorrelationReduction_fx = Mpy_32_32( diffEneValForDecorrelationReduction_fx, spectrumModVal ); // Q-2 + q_diffEneValForDecorrelationReduction = sub( q_diffEneValForDecorrelationReduction, 2 ); + } + } + hDiracDecBin->ChEneOut_fx[0][bin] = BASOP_Util_Add_Mant32Exp( hDiracDecBin->ChEneOut_fx[0][bin], hDiracDecBin->ChEneOut_e[0][bin], diffEne_fx, sub( 31, q_diffEne ), &hDiracDecBin->ChEneOut_e[0][bin] ); /* Diff ene part*/ + hDiracDecBin->ChEneOut_fx[1][bin] = BASOP_Util_Add_Mant32Exp( hDiracDecBin->ChEneOut_fx[1][bin], hDiracDecBin->ChEneOut_e[1][bin], diffEne_fx, sub( 31, q_diffEne ), &hDiracDecBin->ChEneOut_e[1][bin] ); - FOR( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) - { - FOR( slot = 0; slot < BINAURAL_CHANNELS; slot++ ) + move32(); + move32(); + IF( hDiracDecBin->renderStereoOutputInsteadOfBinaural ) { - Scale_sig( hDiracDecBin->processMtxRe_fx[ch][slot], nBins, sub( q_mat, hDiracDecBin->q_processMtx ) ); // scaling to q_mat - Scale_sig( hDiracDecBin->processMtxIm_fx[ch][slot], nBins, sub( q_mat, hDiracDecBin->q_processMtx ) ); // scaling to q_mat - Scale_sig( hDiracDecBin->processMtxRePrev_fx[ch][slot], nBins, sub( q_mat, hDiracDecBin->q_processMtxPrev ) ); // scaling to q_mat - Scale_sig( hDiracDecBin->processMtxImPrev_fx[ch][slot], nBins, sub( q_mat, hDiracDecBin->q_processMtxPrev ) ); // scaling to q_mat - Scale_sig( hDiracDecBin->processMtxDecRe_fx[ch][slot], nBins, sub( q_mat, hDiracDecBin->q_processMtxDec ) ); // scaling to q_mat - Scale_sig( hDiracDecBin->processMtxDecIm_fx[ch][slot], nBins, sub( q_mat, hDiracDecBin->q_processMtxDec ) ); // scaling to q_mat - Scale_sig( hDiracDecBin->processMtxDecRePrev_fx[ch][slot], nBins, sub( q_mat, hDiracDecBin->q_processMtxDecPrev ) ); // scaling to q_mat - Scale_sig( hDiracDecBin->processMtxDecImPrev_fx[ch][slot], nBins, sub( q_mat, hDiracDecBin->q_processMtxDecPrev ) ); // scaling to q_mat + /* When rendering stereo, ambience (except for surround coherent sound) has zero ICC. */ + hDiracDecBin->ChCrossReOut_fx[bin] = BASOP_Util_Add_Mant32Exp( hDiracDecBin->ChCrossReOut_fx[bin], hDiracDecBin->ChCrossReOut_e[bin], Mpy_32_16_1( diffEne_fx, surCoh_fx ), sub( 31, q_diffEne ), &hDiracDecBin->ChCrossReOut_e[bin] ); + move32(); } - FOR( slot = 0; slot < nchanSeparateChannels; slot++ ) + ELSE /* When rendering binaural, ambience has frequency dependent ICC. */ { - Scale_sig( hDiracDecBin->processMtxRe_fx[ch][slot + BINAURAL_CHANNELS], nBins, sub( q_mat, hDiracDecBin->q_processMtx ) ); // scaling to q_mat - Scale_sig( hDiracDecBin->processMtxIm_fx[ch][slot + BINAURAL_CHANNELS], nBins, sub( q_mat, hDiracDecBin->q_processMtx ) ); // scaling to q_mat - Scale_sig( hDiracDecBin->processMtxRePrev_fx[ch][slot + BINAURAL_CHANNELS], nBins, sub( q_mat, hDiracDecBin->q_processMtxPrev ) ); // scaling to q_mat - Scale_sig( hDiracDecBin->processMtxImPrev_fx[ch][slot + BINAURAL_CHANNELS], nBins, sub( q_mat, hDiracDecBin->q_processMtxPrev ) ); // scaling to q_mat + test(); + test(); + IF( ( EQ_32( ivas_format, SBA_FORMAT ) || EQ_32( ivas_format, SBA_ISM_FORMAT ) ) && LT_16( bin, BINAURAL_COHERENCE_DIFFERENCE_BINS ) ) + { + Word32 diffuseFieldCoherence_fx; + Word16 tmp_exp; + temp = BASOP_Util_Add_Mant32Exp( Mpy_32_32( hDiracDecBin->hDiffuseDist->diffuseRatioX_fx[bin], hDiracDecBin->diffuseFieldCoherenceX_fx[bin] ), 0, Mpy_32_32( hDiracDecBin->hDiffuseDist->diffuseRatioY_fx[bin], hDiracDecBin->diffuseFieldCoherenceY_fx[bin] ), 0, &tmp_exp ); + diffuseFieldCoherence_fx = BASOP_Util_Add_Mant32Exp( temp, tmp_exp, Mpy_32_32( hDiracDecBin->hDiffuseDist->diffuseRatioZ_fx[bin], hDiracDecBin->diffuseFieldCoherenceZ_fx[bin] ), 0, &tmp_exp ); + temp = BASOP_Util_Add_Mant32Exp( Mpy_32_16_1( diffuseFieldCoherence_fx, sub( 32767, surCoh_fx ) ), tmp_exp, L_shl( surCoh_fx, 16 ), 0, &tmp_exp ); + hDiracDecBin->ChCrossReOut_fx[bin] = BASOP_Util_Add_Mant32Exp( hDiracDecBin->ChCrossReOut_fx[bin], hDiracDecBin->ChCrossReOut_e[bin], Mpy_32_32( temp, diffEne_fx ), add( tmp_exp, sub( 31, q_diffEne ) ), &hDiracDecBin->ChCrossReOut_e[bin] ); + } + ELSE + { + hDiracDecBin->ChCrossReOut_fx[bin] = BASOP_Util_Add_Mant32Exp( hDiracDecBin->ChCrossReOut_fx[bin], hDiracDecBin->ChCrossReOut_e[bin], Mpy_32_32( L_add( Mpy_32_16_1( hDiracDecBin->diffuseFieldCoherence_fx[bin], sub( 32767, surCoh_fx ) ), L_shl( surCoh_fx, 16 ) ), diffEne_fx ), sub( 31, q_diffEne ), &hDiracDecBin->ChCrossReOut_e[bin] ); + } + move32(); } - } - hDiracDecBin->q_processMtx = q_mat; - move16(); - hDiracDecBin->q_processMtxPrev = q_mat; - move16(); - hDiracDecBin->q_processMtxDec = q_mat; - move16(); - hDiracDecBin->q_processMtxDecPrev = q_mat; - move16(); - - ivas_dirac_dec_binaural_process_output_fx( hDiracDecBin, hSpatParamRendCom, st_ivas->cldfbSynDec, output_fx, &q_out, Cldfb_RealBuffer_in_fx, Cldfb_ImagBuffer_in_fx, q_inp, max_band_decorr, numInChannels, config_data.processReverb, subframe, q_mat ); - - hDiracDecBin->hDiffuseDist = NULL; - hSpatParamRendCom->slots_rendered = add( hSpatParamRendCom->slots_rendered, hSpatParamRendCom->subframe_nbslots[subframe] ); - hSpatParamRendCom->subframes_rendered = add( hSpatParamRendCom->subframes_rendered, 1 ); + /* Store parameters for formulating average diffuseness over frame */ + Word32 frameMeanDiffuseness = BASOP_Util_Add_Mant32Exp( hDiracDecBin->frameMeanDiffuseness_fx[bin], 2 /*Q29*/, diffEneValForDecorrelationReduction_fx, sub( 31, q_diffEneValForDecorrelationReduction ), &exp1 ); // exp = exp1 + frameMeanDiffusenessEneWeight_fx[bin] = L_add( frameMeanDiffusenessEneWeight_fx[bin], meanEnePerCh_fx ); + move32(); - move16(); - move16(); - FOR( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) - { - scale_sig32( output_fx[ch], imult1616( nBins, hSpatParamRendCom->subframe_nbslots[subframe] ), sub( 11, q_out ) ); // Scaling to Q11 - scale_sig32( st_ivas->cldfbSynDec[ch]->cldfb_state_fx, st_ivas->cldfbSynDec[ch]->cldfb_size, sub( Q11, st_ivas->cldfbSynDec[ch]->Q_cldfb_state ) ); - st_ivas->cldfbSynDec[ch]->Q_cldfb_state = Q11; - move16(); + /* Formulate average diffuseness over frame */ + frameMeanDiffuseness = BASOP_Util_Divide3232_Scale_cadence( frameMeanDiffuseness, L_max( EPSILLON_FX, frameMeanDiffusenessEneWeight_fx[bin] ), &exp ); // exp = exp + 31 - q_meanEnePerCh - exp1 + exp = sub( exp, sub( sub( 31, q_meanEnePerCh ), exp1 ) ); + hDiracDecBin->frameMeanDiffuseness_fx[bin] = L_shl( frameMeanDiffuseness, sub( exp, 2 ) ); // Q29 + move32(); } - return; -} - - -static void ivas_dirac_dec_decorrelate_slot_fx( - DIRAC_DEC_BIN_HANDLE hDiracDecBin, - const Word16 num_freq_bands, - const Word16 slot, - Word32 inRe[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], /*q_inp*/ - Word32 inIm[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], /*q_inp*/ - Word16 q_inp, - Word32 decRe[][CLDFB_NO_CHANNELS_MAX], /*q_inp*/ - Word32 decIm[][CLDFB_NO_CHANNELS_MAX] /*q_inp*/ ) -{ - Word16 offset, ch, bin; - Word32 onset_filter_fx[BINAURAL_CHANNELS * CLDFB_NO_CHANNELS_MAX]; /* 2 ch, 60 bins */ - Word32 decorrelatedFrameInterleaved_fx[2 * BINAURAL_CHANNELS * CLDFB_NO_CHANNELS_MAX]; /* 2 ch, real + imag, 60 bins */ - Word32 protoFrame_fx[2 * BINAURAL_CHANNELS * CLDFB_NO_CHANNELS_MAX]; /* 2 ch, real + imag, 60 bins */ - Word16 q_decorrelatedFrameInterleaved, q_protoFrame; - const Word16 protoIndexDir[BINAURAL_CHANNELS] = { 0, 1 }; - move16(); - q_protoFrame = q_inp; - move16(); - /* Decorrelation needs interleaved data. Copy left and right signals to proto_frame_f */ - FOR( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) + FOR( bin = 0; bin < nBins; bin++ ) { - offset = imult1616( imult1616( num_freq_bands, BINAURAL_CHANNELS ), ch ); - FOR( bin = 0; bin < num_freq_bands; bin++ ) + hDiracDecBin->ChCrossReOut_fx[bin] = Mpy_32_32( hDiracDecBin->ChCrossReOut_fx[bin], qualityBasedSmFactor_fx ); + hDiracDecBin->ChCrossImOut_fx[bin] = Mpy_32_32( hDiracDecBin->ChCrossImOut_fx[bin], qualityBasedSmFactor_fx ); + + FOR( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) { - protoFrame_fx[add( imult1616( bin, BINAURAL_CHANNELS ), offset )] = inRe[ch][slot][bin]; // q_protoFrame - protoFrame_fx[add( imult1616( bin, BINAURAL_CHANNELS ), add( offset, 1 ) )] = inIm[ch][slot][bin]; // q_protoFrame + hDiracDecBin->ChEneOut_fx[ch][bin] = Mpy_32_32( hDiracDecBin->ChEneOut_fx[ch][bin], qualityBasedSmFactor_fx ); move32(); + } + hDiracDecBin->ChCrossReOut_fx[bin] = BASOP_Util_Add_Mant32Exp( hDiracDecBin->ChCrossReOut_fx[bin], hDiracDecBin->ChCrossReOut_e[bin], Mpy_32_32( hDiracDecBin->ChCrossReOutPrev_fx[bin], IIReneLimiter_fx[bin] ), hDiracDecBin->ChCrossReOutPrev_e[bin], &hDiracDecBin->ChCrossReOut_e[bin] ); + hDiracDecBin->ChCrossImOut_fx[bin] = BASOP_Util_Add_Mant32Exp( hDiracDecBin->ChCrossImOut_fx[bin], hDiracDecBin->ChCrossImOut_e[bin], Mpy_32_32( hDiracDecBin->ChCrossImOutPrev_fx[bin], IIReneLimiter_fx[bin] ), hDiracDecBin->ChCrossImOutPrev_e[bin], &hDiracDecBin->ChCrossImOut_e[bin] ); + move32(); + move32(); + + FOR( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) + { + hDiracDecBin->ChEneOut_fx[ch][bin] = BASOP_Util_Add_Mant32Exp( hDiracDecBin->ChEneOut_fx[ch][bin], hDiracDecBin->ChEneOut_e[ch][bin], Mpy_32_32( hDiracDecBin->ChEneOutPrev_fx[ch][bin], IIReneLimiter_fx[bin] ), hDiracDecBin->ChEneOutPrev_e[ch][bin], &hDiracDecBin->ChEneOut_e[ch][bin] ); move32(); } - } - /* Decorrelate proto signal to decorrelatedFrameInterleaved */ - ivas_dirac_dec_decorr_process_fx( num_freq_bands, - BINAURAL_CHANNELS, - BINAURAL_CHANNELS, - DIRAC_SYNTHESIS_PSD_LS, - BINAURAL_CHANNELS, - protoFrame_fx, - q_protoFrame, - BINAURAL_CHANNELS, - protoIndexDir, - decorrelatedFrameInterleaved_fx, - &q_decorrelatedFrameInterleaved, - onset_filter_fx, - hDiracDecBin->h_freq_domain_decorr_ap_params, - hDiracDecBin->h_freq_domain_decorr_ap_state ); - /* De-interleave decorrelated signals*/ - FOR( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) - { - offset = imult1616( imult1616( num_freq_bands, BINAURAL_CHANNELS ), ch ); - FOR( bin = 0; bin < num_freq_bands; bin++ ) + hDiracDecBin->ChCrossReOutPrev_fx[bin] = hDiracDecBin->ChCrossReOut_fx[bin]; + move32(); + hDiracDecBin->ChCrossImOutPrev_fx[bin] = hDiracDecBin->ChCrossImOut_fx[bin]; + move32(); + hDiracDecBin->ChCrossReOutPrev_e[bin] = hDiracDecBin->ChCrossReOut_e[bin]; + move16(); + hDiracDecBin->ChCrossImOutPrev_e[bin] = hDiracDecBin->ChCrossImOut_e[bin]; + move16(); + + FOR( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) { - decRe[ch][bin] = decorrelatedFrameInterleaved_fx[add( imult1616( bin, BINAURAL_CHANNELS ), offset )]; // q_inp - decIm[ch][bin] = decorrelatedFrameInterleaved_fx[add( imult1616( bin, BINAURAL_CHANNELS ), add( offset, 1 ) )]; // q_inp + hDiracDecBin->ChEnePrev_fx[ch][bin] = hDiracDecBin->ChEne_fx[ch][bin]; move32(); + hDiracDecBin->ChEnePrev_e[ch][bin] = hDiracDecBin->ChEne_e[ch][bin]; + move16(); + hDiracDecBin->ChEneOutPrev_fx[ch][bin] = hDiracDecBin->ChEneOut_fx[ch][bin]; move32(); + hDiracDecBin->ChEneOutPrev_e[ch][bin] = hDiracDecBin->ChEneOut_e[ch][bin]; + move16(); } } - // q_decorrelatedFrameInterleaved will be same as q_inp/q_protoFrame // + return; } + +#else static void ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matrices_fx( DIRAC_DEC_BIN_HANDLE hDiracDecBin, SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom, @@ -1743,6 +2798,7 @@ static void ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matric return; } +#endif static void ivas_dirac_dec_binaural_determine_processing_matrices_fx( DIRAC_DEC_BIN_HANDLE hDiracDecBin, @@ -1940,7 +2996,13 @@ static void ivas_dirac_dec_binaural_determine_processing_matrices_fx( /* Make matrix multiplication M*Cx*M' to determine resulting covariance matrix of processing input with M */ matrixMul_fx( Mre_fx, Mim_fx, &q_M, CxRe_fx, CxIm_fx, &q_Cx, tmpMtxRe_fx, tmpMtxIm_fx, &q_tmp ); - matrixTransp2Mul_fx( tmpMtxRe_fx, tmpMtxIm_fx, &q_tmp, Mre_fx, Mim_fx, &q_M, resultMtxRe_fx, resultMtxIm_fx, &q_res ); + matrixTransp2Mul_fx( + tmpMtxRe_fx, tmpMtxIm_fx, &q_tmp, Mre_fx, Mim_fx, &q_M, +#ifdef FIX_1072_SPEEDUP_matrixTransp2Mul_fx + 1 /*int Ascale*/, + 0 /*int Bscale*/, +#endif + resultMtxRe_fx, resultMtxIm_fx, &q_res ); /* When below the frequency limit where decorrelation is applied, we inject the decorrelated * residual (or missing) signal component. The procedure is active when there are not enough independent @@ -2351,7 +3413,19 @@ static void ivas_dirac_dec_binaural_process_output_fx( const Word16 numInChannels, const Word16 processReverb, const Word16 subframe, - const Word16 q_mat ) + const Word16 q_mat +#ifdef SPLIT_REND_WITH_HEAD_ROT + , + Word32 outRe_fx[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], + Word32 outIm_fx[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], + Word32 reverbRe_fx[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], + Word32 reverbIm_fx[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], + Word32 decorrRe_fx[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], + Word32 decorrIm_fx[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], + Word16 *Q_inp_mix, + const Word8 recompute +#endif +) { Word16 slot, bin, chA, chB; Word16 nBins; @@ -2367,8 +3441,10 @@ static void ivas_dirac_dec_binaural_process_output_fx( Word32 decSlotRe_fx[BINAURAL_CHANNELS][CLDFB_NO_CHANNELS_MAX], decSlotIm_fx[BINAURAL_CHANNELS][CLDFB_NO_CHANNELS_MAX]; Word32 outSlotRe_fx[CLDFB_NO_CHANNELS_MAX], outSlotIm_fx[CLDFB_NO_CHANNELS_MAX]; +#ifndef SPLIT_REND_WITH_HEAD_ROT Word32 reverbRe_fx[BINAURAL_CHANNELS][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX]; Word32 reverbIm_fx[BINAURAL_CHANNELS][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX]; +#endif Word16 q_inp[6][CLDFB_SLOTS_PER_SUBFRAME]; Word16 interpVal_fx; Word32 *decSlotRePointer_fx; @@ -2379,65 +3455,93 @@ static void ivas_dirac_dec_binaural_process_output_fx( IF( processReverb ) { - /* Process second / room effect part of binaural output when needed */ - ivas_binaural_reverb_processSubframe_fx( hDiracDecBin->hReverb, numInChannels, nSlots, inRe_fx, inIm_fx, reverbRe_fx, reverbIm_fx ); +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( recompute == 1 ) + { +#endif + /* Process second / room effect part of binaural output when needed */ + ivas_binaural_reverb_processSubframe_fx( hDiracDecBin->hReverb, numInChannels, nSlots, inRe_fx, inIm_fx, reverbRe_fx, reverbIm_fx ); +#ifdef SPLIT_REND_WITH_HEAD_ROT + } +#endif } - // scaling input and reverb to same q// - // input scaling is to maintain precision in ivas_dirac_dec_decorrelate_slot fn// - Word16 shift = s_min( L_norm_arr( cldfbSynDec[0]->cldfb_state_fx, cldfbSynDec[0]->p_filter_length ), L_norm_arr( cldfbSynDec[1]->cldfb_state_fx, cldfbSynDec[1]->p_filter_length ) ); - q_inp_mix = 31; - move16(); - FOR( Word16 i = 0; i < 6; i++ ) +#ifdef SPLIT_REND_WITH_HEAD_ROT + IF( EQ_16( recompute, 1 ) ) { - FOR( Word16 j = 0; j < nSlots; j++ ) +#endif + // scaling input and reverb to same q// + // input scaling is to maintain precision in ivas_dirac_dec_decorrelate_slot fn// + Word16 shift = s_min( L_norm_arr( cldfbSynDec[0]->cldfb_state_fx, cldfbSynDec[0]->p_filter_length ), L_norm_arr( cldfbSynDec[1]->cldfb_state_fx, cldfbSynDec[1]->p_filter_length ) ); + q_inp_mix = 31; + move16(); + FOR( Word16 i = 0; i < 6; i++ ) { - q_inp[i][j] = s_min( L_norm_arr( inRe_fx[i][j], nBins ), L_norm_arr( inIm_fx[i][j], nBins ) ); - move16(); - test(); - IF( ( processReverb ) && LT_16( i, 2 ) ) + FOR( Word16 j = 0; j < nSlots; j++ ) { - q_reverb = s_min( L_norm_arr( reverbRe_fx[i][j], CLDFB_NO_CHANNELS_MAX ), L_norm_arr( reverbIm_fx[i][j], CLDFB_NO_CHANNELS_MAX ) ); - q_inp[i][j] = s_min( q_reverb, q_inp[i][j] ); + q_inp[i][j] = s_min( L_norm_arr( inRe_fx[i][j], nBins ), L_norm_arr( inIm_fx[i][j], nBins ) ); move16(); + test(); +#ifdef SPLIT_REND_WITH_HEAD_ROT + IF( ( processReverb && EQ_16( recompute, 1 ) ) && LT_16( i, 2 ) ) +#else + IF( ( processReverb ) && LT_16( i, 2 ) ) +#endif + { + q_reverb = s_min( L_norm_arr( reverbRe_fx[i][j], CLDFB_NO_CHANNELS_MAX ), L_norm_arr( reverbIm_fx[i][j], CLDFB_NO_CHANNELS_MAX ) ); + q_inp[i][j] = s_min( q_reverb, q_inp[i][j] ); + move16(); + } + q_inp_mix = s_min( q_inp[i][j], q_inp_mix ); } - q_inp_mix = s_min( q_inp[i][j], q_inp_mix ); } - } - q_inp_mix = sub( q_inp_mix, 3 ); // gaurded bits// - - Word16 cldfb_state_shift = sub( add( add( q_inp_mix, q_mat ), sub( q_input, 16 ) ), cldfbSynDec[0]->Q_cldfb_state ); - IF( GT_16( cldfb_state_shift, shift ) ) - { - q_inp_mix = sub( add( q_inp_mix, shift ), cldfb_state_shift ); - cldfb_state_shift = shift; - move16(); - } + q_inp_mix = sub( q_inp_mix, 3 ); // gaurded bits// - FOR( Word16 i = 0; i < 6; i++ ) - { - FOR( Word16 j = 0; j < nSlots; j++ ) + Word16 cldfb_state_shift = sub( add( add( q_inp_mix, q_mat ), sub( q_input, 16 ) ), cldfbSynDec[0]->Q_cldfb_state ); + IF( GT_16( cldfb_state_shift, shift ) ) { + q_inp_mix = sub( add( q_inp_mix, shift ), cldfb_state_shift ); + cldfb_state_shift = shift; + move16(); + } - scale_sig32( inRe_fx[i][j], nBins, q_inp_mix ); /*q_input + q_inp_mix*/ - scale_sig32( inIm_fx[i][j], nBins, q_inp_mix ); /*q_input + q_inp_mix*/ - test(); - IF( processReverb && LT_16( i, 2 ) ) + FOR( Word16 i = 0; i < 6; i++ ) + { + FOR( Word16 j = 0; j < nSlots; j++ ) { - scale_sig32( reverbRe_fx[i][j], CLDFB_NO_CHANNELS_MAX, sub( add( q_inp_mix, q_mat ), 15 ) ); /*q_inp_mix+q_mat-15*/ - scale_sig32( reverbIm_fx[i][j], CLDFB_NO_CHANNELS_MAX, sub( add( q_inp_mix, q_mat ), 15 ) ); /*q_inp_mix+q_mat-15*/ + + scale_sig32( inRe_fx[i][j], nBins, q_inp_mix ); /*q_input + q_inp_mix*/ + scale_sig32( inIm_fx[i][j], nBins, q_inp_mix ); /*q_input + q_inp_mix*/ + test(); +#ifdef SPLIT_REND_WITH_HEAD_ROT + IF( ( processReverb && EQ_16( recompute, 1 ) ) && LT_16( i, 2 ) ) +#else + IF( ( processReverb ) && LT_16( i, 2 ) ) +#endif + { + scale_sig32( reverbRe_fx[i][j], CLDFB_NO_CHANNELS_MAX, sub( add( q_inp_mix, q_mat ), 15 ) ); /*q_inp_mix+q_mat-15*/ + scale_sig32( reverbIm_fx[i][j], CLDFB_NO_CHANNELS_MAX, sub( add( q_inp_mix, q_mat ), 15 ) ); /*q_inp_mix+q_mat-15*/ + } } } - } - // scaling cldfb states to q_result-1// - scale_sig32( cldfbSynDec[0]->cldfb_state_fx, cldfbSynDec[0]->p_filter_length, cldfb_state_shift ); - cldfbSynDec[0]->Q_cldfb_state = add( cldfbSynDec[0]->Q_cldfb_state, cldfb_state_shift ); - scale_sig32( cldfbSynDec[1]->cldfb_state_fx, cldfbSynDec[1]->p_filter_length, cldfb_state_shift ); - cldfbSynDec[1]->Q_cldfb_state = add( cldfbSynDec[1]->Q_cldfb_state, cldfb_state_shift ); - move16(); - move16(); + // scaling cldfb states to q_result-1// + scale_sig32( cldfbSynDec[0]->cldfb_state_fx, cldfbSynDec[0]->p_filter_length, cldfb_state_shift ); + cldfbSynDec[0]->Q_cldfb_state = add( cldfbSynDec[0]->Q_cldfb_state, cldfb_state_shift ); + scale_sig32( cldfbSynDec[1]->cldfb_state_fx, cldfbSynDec[1]->p_filter_length, cldfb_state_shift ); + cldfbSynDec[1]->Q_cldfb_state = add( cldfbSynDec[1]->Q_cldfb_state, cldfb_state_shift ); + move16(); + move16(); +#ifdef SPLIT_REND_WITH_HEAD_ROT + *Q_inp_mix = q_inp_mix; + move16(); + } + ELSE + { + q_inp_mix = *Q_inp_mix; + } +#endif q_inp_mix = add( q_inp_mix, q_input ); @@ -2463,7 +3567,27 @@ static void ivas_dirac_dec_binaural_process_output_fx( test(); IF( !hDiracDecBin->useTdDecorr && ( max_band_decorr > 0 ) ) { - ivas_dirac_dec_decorrelate_slot_fx( hDiracDecBin, nBins, slot, inRe_fx, inIm_fx, q_inp_mix, decSlotRe_fx, decSlotIm_fx ); +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( recompute == 1 ) + { +#endif + ivas_dirac_dec_decorrelate_slot_fx( hDiracDecBin, nBins, slot, inRe_fx, inIm_fx, q_inp_mix, decSlotRe_fx, decSlotIm_fx ); +#ifdef SPLIT_REND_WITH_HEAD_ROT + FOR( chA = 0; chA < BINAURAL_CHANNELS; chA++ ) + { + Copy32( decSlotRe_fx[chA], decorrRe_fx[chA][slot], CLDFB_NO_CHANNELS_MAX ); + Copy32( decSlotIm_fx[chA], decorrIm_fx[chA][slot], CLDFB_NO_CHANNELS_MAX ); + } + } + else + { + FOR( chA = 0; chA < BINAURAL_CHANNELS; chA++ ) + { + Copy32( decorrRe_fx[chA][slot], decSlotRe_fx[chA], CLDFB_NO_CHANNELS_MAX ); + Copy32( decorrIm_fx[chA][slot], decSlotIm_fx[chA], CLDFB_NO_CHANNELS_MAX ); + } + } +#endif } FOR( chA = 0; chA < BINAURAL_CHANNELS; chA++ ) @@ -2553,13 +3677,40 @@ static void ivas_dirac_dec_binaural_process_output_fx( outSlotRePr_fx = &( outSlotRe_fx[0] ); outSlotImPr_fx = &( outSlotIm_fx[0] ); +#ifdef SPLIT_REND_WITH_HEAD_ROT + IF( outRe_fx != NULL && outIm_fx != NULL ) + { + /* provide the data outside in CLDFB domain => mainly for split rendering */ + Copy32( outSlotRePr_fx, outRe_fx[chA][slot], CLDFB_NO_CHANNELS_MAX ); + Copy32( outSlotImPr_fx, outIm_fx[chA][slot], CLDFB_NO_CHANNELS_MAX ); + Scale_sig32( outRe_fx[chA][slot], CLDFB_NO_CHANNELS_MAX, sub( Q6, q_result ) ); // Q6 + Scale_sig32( outIm_fx[chA][slot], CLDFB_NO_CHANNELS_MAX, sub( Q6, q_result ) ); // Q6 + } + if ( recompute == 1 ) + { + /* Inverse filter bank */ + cldfbSynthesis_ivas_fx( &outSlotRePr_fx, &outSlotImPr_fx, &( output_fx[chA][nBins * slot + offsetSamples] ), nBins, cldfbSynDec[chA] ); + cldfbSynDec[chA]->Q_cldfb_state = sub( q_result, 1 ); + move16(); + } +#else cldfbSynthesis_ivas_fx( &outSlotRePr_fx, &outSlotImPr_fx, &( output_fx[chA][nBins * slot + offsetSamples] ), nBins, cldfbSynDec[chA] ); cldfbSynDec[chA]->Q_cldfb_state = sub( q_result, 1 ); move16(); +#endif } } +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( recompute == 1 ) + { + *q_out = sub( q_result, 1 ); + move16(); + } +#else *q_out = sub( q_result, 1 ); move16(); +#endif + return; } @@ -3278,10 +4429,17 @@ static void eig2x2_fx( tmp3 = BASOP_Util_Add_Mant32Exp( tmp2, sub( 31, q_tmp2 ), epsilon_mant, epsilon_exp, &exp_tmp3 ); +#if 1 tmp2 = BASOP_Util_Divide3232_Scale_cadence( ONE_IN_Q30, tmp3, &exp ); exp = sub( exp, sub( Q30, sub( 31, exp_tmp3 ) ) ); normVal_fx = Sqrt32( tmp2, &exp ); // q_tmp2 q_tmp2 = sub( 31, exp ); +#else + /* Note: This code part does not work yet, see pipeline issue for BASOP #1009 */ + /* although the same code works at other places: mantissa and q_format is fine */ + normVal_fx = ISqrt32( tmp3, &exp ); + q_tmp2 = sub( 31, exp ); +#endif IF( LT_16( q_tmp1, q_c ) ) { @@ -3347,10 +4505,17 @@ static void eig2x2_fx( tmp3 = BASOP_Util_Add_Mant32Exp( tmp2, sub( 31, q_tmp2 ), epsilon_mant, epsilon_exp, &exp_tmp3 ); +#if 1 tmp2 = BASOP_Util_Divide3232_Scale_cadence( ONE_IN_Q30, tmp3, &exp ); exp = sub( exp, sub( Q30, sub( 31, exp_tmp3 ) ) ); normVal_fx = Sqrt32( tmp2, &exp ); // q_tmp2 q_tmp2 = sub( 31, exp ); +#else + /* Note: This code part does not work yet, see pipeline issue for BASOP #1009 */ + /* although the same code works at other places: mantissa and q_format is fine */ + normVal_fx = ISqrt32( tmp3, &exp_tmp3 ); + q_tmp2 = sub( 31, exp_tmp3 ); +#endif IF( LT_16( q_tmp1, q_c ) ) { @@ -3405,9 +4570,13 @@ static void eig2x2_fx( } IF( q_U_1 != 0 ) - *q_U = q_U_1; + { + *q_U = q_U_1; + } ELSE + { *q_U = q_U_2; + } move16(); return; @@ -3463,8 +4632,10 @@ static void matrixMul_fx( Word16 chA, chB; Word16 min_q_shift1, min_q_shift2; Word16 size = i_mult( BINAURAL_CHANNELS, BINAURAL_CHANNELS ); +#ifndef FIX_1113_OPT_DIRAC_BIN_REND #ifndef IVAS_ENH64_CADENCE_CHANGES Word32 tmp1, tmp2; +#endif #endif min_q_shift1 = sub( s_min( L_norm_arr( Are_fx[0], size ), L_norm_arr( Aim_fx[0], size ) ), 1 ); @@ -3493,6 +4664,18 @@ static void matrixMul_fx( move32(); outIm_fx[chA][chB] = L_add( outIm_fx[chA][chB], W_extract_h( W_mac_32_32( W_mult_32_32( Are_fx[chA][0], Bim_fx[0][chB] ), Are_fx[chA][1], Bim_fx[1][chB] ) ) ); move32(); +#else +#ifdef FIX_1113_OPT_DIRAC_BIN_REND + outRe_fx[chA][chB] = Msub_32_32( Msub_32_32( Madd_32_32( Mpy_32_32( Are_fx[chA][0], Bre_fx[0][chB] ), + Are_fx[chA][1], Bre_fx[1][chB] ), + Aim_fx[chA][0], Bim_fx[0][chB] ), + Aim_fx[chA][1], Bim_fx[1][chB] ); + move32(); + outIm_fx[chA][chB] = Madd_32_32( Madd_32_32( Madd_32_32( Mpy_32_32( Aim_fx[chA][0], Bre_fx[0][chB] ), + Aim_fx[chA][1], Bre_fx[1][chB] ), + Are_fx[chA][0], Bim_fx[0][chB] ), + Are_fx[chA][1], Bim_fx[1][chB] ); + move32(); #else test(); test(); @@ -3592,6 +4775,7 @@ static void matrixMul_fx( } outIm_fx[chA][chB] = L_add( outIm_fx[chA][chB], L_add( tmp1, tmp2 ) ); move32(); +#endif #endif /* #ifdef IVAS_ENH64_CADENCE_CHANGES */ } } @@ -3620,12 +4804,26 @@ static void matrixTransp1Mul_fx( { Word16 chA, chB; Word16 size = i_mult( BINAURAL_CHANNELS, BINAURAL_CHANNELS ); +#ifndef FIX_1113_OPT_DIRAC_BIN_REND Word32 tmp1, tmp2; +#endif FOR( chA = 0; chA < BINAURAL_CHANNELS; chA++ ) { FOR( chB = 0; chB < BINAURAL_CHANNELS; chB++ ) { +#ifdef FIX_1113_OPT_DIRAC_BIN_REND + outRe_fx[chA][chB] = Madd_32_32( Madd_32_32( Madd_32_32( Mpy_32_32( Are_fx[0][chA], Bre_fx[0][chB] ), + Are_fx[1][chA], Bre_fx[1][chB] ), + Aim_fx[0][chA], Bim_fx[0][chB] ), + Aim_fx[1][chA], Bim_fx[1][chB] ); + move32(); + outIm_fx[chA][chB] = Msub_32_32( Msub_32_32( Madd_32_32( Mpy_32_32( Are_fx[0][chA], Bim_fx[0][chB] ), + Are_fx[1][chA], Bim_fx[1][chB] ), + Aim_fx[0][chA], Bre_fx[0][chB] ), + Aim_fx[1][chA], Bre_fx[1][chB] ); + move32(); +#else test(); test(); test(); @@ -3692,6 +4890,7 @@ static void matrixTransp1Mul_fx( tmp2 = L_negate( Mpy_32_32( L_abs( Are_fx[1][chA] ), L_abs( Bim_fx[1][chB] ) ) ); outIm_fx[chA][chB] = L_add( outIm_fx[chA][chB], L_add( tmp1, tmp2 ) ); move32(); +#endif } } *q_out = sub( add( q_A, q_B ), 31 ); @@ -3713,6 +4912,10 @@ static void matrixTransp2Mul_fx( Word32 Bre_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], /*q_B*/ Word32 Bim_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], /*q_B*/ Word16 *q_B, +#ifdef FIX_1072_SPEEDUP_matrixTransp2Mul_fx + Word32 Ascale, + Word32 Bscale, +#endif Word32 outRe_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], /*q_out*/ Word32 outIm_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], /*q_out*/ Word16 *q_out ) @@ -3720,20 +4923,33 @@ static void matrixTransp2Mul_fx( Word16 chA, chB; Word16 min_q_shift; Word16 size = i_mult( BINAURAL_CHANNELS, BINAURAL_CHANNELS ); +#ifndef FIX_1113_OPT_DIRAC_BIN_REND #ifndef IVAS_ENH64_CADENCE_CHANGES Word32 tmp1, tmp2; #endif +#endif - min_q_shift = sub( s_min( L_norm_arr( Are_fx[0], size ), L_norm_arr( Aim_fx[0], size ) ), 1 ); - scale_sig32( Are_fx[0], size, min_q_shift ); - scale_sig32( Aim_fx[0], size, min_q_shift ); - *q_A = add( *q_A, min_q_shift ); - move16(); - min_q_shift = sub( s_min( L_norm_arr( Bre_fx[0], size ), L_norm_arr( Bim_fx[0], size ) ), 1 ); - scale_sig32( Bre_fx[0], size, min_q_shift ); - scale_sig32( Bim_fx[0], size, min_q_shift ); - *q_B = add( *q_B, min_q_shift ); - move16(); +#ifdef FIX_1072_SPEEDUP_matrixTransp2Mul_fx + IF( Ascale == 1 ) +#endif + { + min_q_shift = sub( s_min( L_norm_arr( Are_fx[0], size ), L_norm_arr( Aim_fx[0], size ) ), 1 ); + scale_sig32( Are_fx[0], size, min_q_shift ); + scale_sig32( Aim_fx[0], size, min_q_shift ); + *q_A = add( *q_A, min_q_shift ); + move16(); + } + +#ifdef FIX_1072_SPEEDUP_matrixTransp2Mul_fx + IF( Bscale == 1 ) +#endif + { + min_q_shift = sub( s_min( L_norm_arr( Bre_fx[0], size ), L_norm_arr( Bim_fx[0], size ) ), 1 ); + scale_sig32( Bre_fx[0], size, min_q_shift ); + scale_sig32( Bim_fx[0], size, min_q_shift ); + *q_B = add( *q_B, min_q_shift ); + move16(); + } FOR( chA = 0; chA < BINAURAL_CHANNELS; chA++ ) { @@ -3748,6 +4964,18 @@ static void matrixTransp2Mul_fx( move32(); outIm_fx[chA][chB] = L_add( outIm_fx[chA][chB], W_extract_h( W_mac_32_32( W_mult_32_32( Are_fx[chA][0], L_negate( Bim_fx[chB][0] ) ), Are_fx[chA][1], L_negate( Bim_fx[chB][1] ) ) ) ); move32(); +#else +#ifdef FIX_1113_OPT_DIRAC_BIN_REND + outRe_fx[chA][chB] = Madd_32_32( Madd_32_32( Madd_32_32( Mpy_32_32( Are_fx[chA][0], Bre_fx[chB][0] ), + Are_fx[chA][1], Bre_fx[chB][1] ), + Aim_fx[chA][0], Bim_fx[chB][0] ), + Aim_fx[chA][1], Bim_fx[chB][1] ); + move32(); + outIm_fx[chA][chB] = Msub_32_32( Msub_32_32( Madd_32_32( Mpy_32_32( Aim_fx[chA][0], Bre_fx[chB][0] ), + Aim_fx[chA][1], Bre_fx[chB][1] ), + Are_fx[chA][0], Bim_fx[chB][0] ), + Are_fx[chA][1], Bim_fx[chB][1] ); + move32(); #else test(); test(); @@ -3816,6 +5044,7 @@ static void matrixTransp2Mul_fx( tmp2 = L_negate( Mpy_32_32( L_abs( Are_fx[chA][1] ), L_abs( -Bim_fx[chB][1] ) ) ); outIm_fx[chA][chB] = L_add( outIm_fx[chA][chB], L_add( tmp1, tmp2 ) ); move32(); +#endif #endif /* #ifdef IVAS_ENH64_CADENCE_CHANGES */ } } @@ -3890,6 +5119,7 @@ static void chol2x2_fx( } ELSE { +#ifndef FIX_1009_REPLACE_DIV_SQRT_BY_ISQRT_LC outRe[1][0] = BASOP_Util_Divide3232_Scale_cadence( c_re, outRe[0][0], &exp ); move32(); q_re2 = add( sub( 31, exp ), sub( q_c, q_re1 ) ); @@ -3897,6 +5127,33 @@ static void chol2x2_fx( outIm[1][0] = BASOP_Util_Divide3232_Scale_cadence( c_im, outRe[0][0], &exp ); move32(); q_im = add( sub( 31, exp ), sub( q_c, q_re1 ) ); +#else + Word32 denom; + Word16 den_exp; + Word32 my_outRe, my_outIm; + + /* Compute denom = 1.0 / outRe[0][0] */ + denom = ISqrt32( outRe[0][0], &exp ); + denom = Mpy_32_32( denom, denom ); + den_exp = shl( exp, 1 ); + + /* Normalise c_re, c_im */ + exp = norm_l( c_re ); + my_outRe = L_shl( c_re, exp ); + q_re2 = add( q_c, exp ); + exp = norm_l( c_im ); + my_outIm = L_shl( c_im, exp ); + q_im = add( q_c, exp ); + + /* Multiply and store c_re*denom and c_im*denom */ + outRe[1][0] = Mpy_32_32( denom, my_outRe ); + move32(); + q_re2 = sub( q_re2, den_exp ); + + outIm[1][0] = Mpy_32_32( denom, my_outIm ); + move32(); + q_im = sub( q_im, den_exp ); +#endif } if ( outRe[1][0] == 0 ) { @@ -3915,8 +5172,16 @@ static void chol2x2_fx( // 4611686 = Q62 IF( e1 == 0 ) { +#ifndef FIX_1009_REPLACE_DIV_SQRT_BY_ISQRT_LC temp = BASOP_Util_Divide3232_Scale_cadence( temp, 4611686, &exp ); q_tmp = add( sub( 31, exp ), sub( q_tmp, 62 ) ); +#else + Word16 norm = norm_l( temp ); + temp = L_shl( temp, norm ); + q_tmp = add( q_tmp, norm ); + temp = Mpy_32_32( temp, ONE_DIV_EPSILON_MANT ); + q_tmp = sub( q_tmp, ONE_DIV_EPSILON_EXP ); +#endif } ELSE { @@ -3965,6 +5230,7 @@ static void chol2x2_fx( // 4611686 = Q62 IF( outRe[1][1] == 0 ) { +#if !defined( FIX_1072_REDUCE_DIVS ) outRe[0][1] = BASOP_Util_Divide3232_Scale_cadence( c_re, 4611686, &exp ); move32(); q_re2 = add( sub( 31, exp ), sub( q_c, 62 ) ); @@ -3972,9 +5238,25 @@ static void chol2x2_fx( outIm[0][1] = BASOP_Util_Divide3232_Scale_cadence( -c_im, 4611686, &exp ); move32(); q_im = add( sub( 31, exp ), sub( q_c, 62 ) ); + +#else + // outRe[0][1] = BASOP_Util_Divide3232_Scale_cadence( c_re, 4611686, &exp ); + Word32 tmp1 = 1953125005; /* 1/4611686 Q62 */ + exp = 9; + + outRe[0][1] = Mpy_32_32( tmp1, c_re ); + move32(); + q_re2 = add( sub( 31, exp ), sub( q_c, 62 ) ); + + // outIm[0][1] = BASOP_Util_Divide3232_Scale_cadence( -c_im, 4611686, &exp ); + outIm[0][1] = Mpy_32_32( tmp1, -c_im ); + move32(); + q_im = add( sub( 31, exp ), sub( q_c, 62 ) ); +#endif } ELSE { +#if !defined( FIX_1072_REDUCE_DIVS ) outRe[0][1] = BASOP_Util_Divide3232_Scale_cadence( c_re, outRe[1][1], &exp ); move32(); q_re2 = add( sub( 31, exp ), sub( q_c, q_re1 ) ); @@ -3982,6 +5264,20 @@ static void chol2x2_fx( outIm[0][1] = BASOP_Util_Divide3232_Scale_cadence( -c_im, outRe[1][1], &exp ); move32(); q_im = add( sub( 31, exp ), sub( q_c, q_re1 ) ); +#else + { + // outRe[0][1] = BASOP_Util_Divide3232_Scale_cadence( c_re, outRe[1][1], &exp ); + Word32 tmp1 = BASOP_Util_Divide3232_Scale_cadence( 0x7FFFFFFF, outRe[1][1], &exp ); + outRe[0][1] = Mpy_32_32( tmp1, c_re ); + move32(); + q_re2 = add( sub( 31, exp ), sub( q_c, q_re1 ) ); + + // outIm[0][1] = BASOP_Util_Divide3232_Scale_cadence( -c_im, outRe[1][1], &exp ); + outIm[0][1] = Mpy_32_32( tmp1, -c_im ); + move32(); + q_im = add( sub( 31, exp ), sub( q_c, q_re1 ) ); + } +#endif } if ( outRe[0][1] == 0 ) { @@ -4146,8 +5442,15 @@ static void formulate2x2MixingMatrix_fx( // 4611686 = Q62 IF( maxEne_fx == 0 ) { +#ifdef FIX_1009_REPLACE_DIV_SQRT_BY_ISQRT_LC + maxEneDiv_fx = ONE_DIV_EPSILON_MANT; + move32(); + q_maxEneDiv = 31 - ONE_DIV_EPSILON_EXP; + move16(); +#else maxEneDiv_fx = BASOP_Util_Divide3232_Scale_cadence( ONE_IN_Q30, 4611686, &exp ); // 4611686 = 1e-12f in Q62 q_maxEneDiv = add( sub( 31, exp ), sub( Q30, 62 ) ); +#endif } ELSE { @@ -4207,8 +5510,24 @@ static void formulate2x2MixingMatrix_fx( IF( temp == 0 ) { - BASOP_Util_Divide3232_Scale_cadence( E_out1, 4611686, &exp ); // 4611686 = Q62 +#ifdef FIX_1009_REPLACE_DIV_SQRT_BY_ISQRT_LC + IF( E_out1 == 0 ) + { + Ghat_fx[0] = 0; + exp = -19; + move32(); + move16(); + } + ELSE + { + temp = BASOP_Util_Divide3232_Scale_cadence( E_out1, 4611686, &exp ); // 4611686 = Q62 + exp = sub( exp, sub( q_eout, 62 ) ); + Ghat_fx[0] = Sqrt32( temp, &exp ); // Q = 31 - exp + } +#else + temp = BASOP_Util_Divide3232_Scale_cadence( E_out1, 4611686, &exp ); // 4611686 = Q62 exp = sub( exp, sub( q_eout, 62 ) ); +#endif } ELSE { @@ -4216,16 +5535,36 @@ static void formulate2x2MixingMatrix_fx( temp = BASOP_Util_Divide3232_Scale_cadence( E_out1, temp, &exp ); exp = sub( exp, sub( q_eout, sub( 31, exp_temp ) ) ); +#ifdef FIX_1009_REPLACE_DIV_SQRT_BY_ISQRT_LC + Ghat_fx[0] = Sqrt32( temp, &exp ); // Q = 31 - exp +#endif } +#ifndef FIX_1009_REPLACE_DIV_SQRT_BY_ISQRT_LC Ghat_fx[0] = Sqrt32( temp, &exp ); // Q = 31 - exp +#endif move32(); temp = Mpy_32_32( E_in1, 2147484 ); // 2147484 = 0.001f in Q31 temp = L_max( temp, E_in2 ); // q_ein IF( temp == 0 ) { - BASOP_Util_Divide3232_Scale_cadence( E_out2, 4611686, &exp1 ); // 4611686 = Q62 +#ifdef FIX_1009_REPLACE_DIV_SQRT_BY_ISQRT_LC + IF( E_out2 == 0 ) + { /* We can set hard-coded results */ + Ghat_fx[1] = 0; + exp1 = -19; + move16(); + } + ELSE + { + temp = BASOP_Util_Divide3232_Scale_cadence( E_out2, 4611686, &exp1 ); // 4611686 = Q62 + exp1 = sub( exp1, sub( q_eout, 62 ) ); + Ghat_fx[1] = Sqrt32( temp, &exp1 ); // Q = 31 - exp1 + } +#else + temp = BASOP_Util_Divide3232_Scale_cadence( E_out2, 4611686, &exp1 ); // 4611686 = Q62 exp1 = sub( exp1, sub( q_eout, 62 ) ); +#endif } ELSE { @@ -4233,8 +5572,13 @@ static void formulate2x2MixingMatrix_fx( temp = BASOP_Util_Divide3232_Scale_cadence( E_out2, temp, &exp1 ); exp1 = sub( exp1, sub( q_eout, sub( 31, exp_temp ) ) ); +#ifdef FIX_1009_REPLACE_DIV_SQRT_BY_ISQRT_LC + Ghat_fx[1] = Sqrt32( temp, &exp1 ); // Q = 31 - exp1 +#endif } +#ifndef FIX_1009_REPLACE_DIV_SQRT_BY_ISQRT_LC Ghat_fx[1] = Sqrt32( temp, &exp1 ); // Q = 31 - exp1 +#endif move32(); q_Ghat = sub( 31, s_max( exp, exp1 ) ); @@ -4283,8 +5627,13 @@ static void formulate2x2MixingMatrix_fx( IF( D_fx[0] == 0 ) { +#ifndef FIX_1009_REPLACE_DIV_SQRT_BY_ISQRT_LC temp = BASOP_Util_Divide3232_Scale_cadence( ONE_IN_Q30, 4611686, &exp ); // 4611686 = 1e-12 in Q62 exp = sub( exp, sub( Q30, 62 ) ); +#else + temp = ONE_DIV_EPSILON_MANT; /* Result of 1.0/eps with full precision */ + exp = ONE_DIV_EPSILON_EXP; +#endif } ELSE { @@ -4296,8 +5645,13 @@ static void formulate2x2MixingMatrix_fx( IF( D_fx[1] == 0 ) { +#ifndef FIX_1009_REPLACE_DIV_SQRT_BY_ISQRT_LC temp = BASOP_Util_Divide3232_Scale_cadence( ONE_IN_Q30, 4611686, &exp1 ); // 4611686 = 1e-12 in Q62 exp1 = sub( exp1, sub( Q30, 62 ) ); +#else + temp = ONE_DIV_EPSILON_MANT; /* Result of 1.0/eps with full precision */ + exp1 = ONE_DIV_EPSILON_EXP; +#endif } ELSE { @@ -4397,28 +5751,69 @@ static void formulate2x2MixingMatrix_fx( } } - matrixTransp2Mul_fx( tmpRe_fx, tmpIm_fx, &q_temp, Ure_fx, Uim_fx, &q_U, Pre_fx, Pim_fx, &q_P ); /* Nearest orthonormal matrix P to matrix A formulated */ + matrixTransp2Mul_fx( tmpRe_fx, tmpIm_fx, &q_temp, Ure_fx, Uim_fx, &q_U, +#ifdef FIX_1072_SPEEDUP_matrixTransp2Mul_fx + 1 /*int Ascale*/, + 0 /*int Bscale*/, +#endif + Pre_fx, Pim_fx, &q_P ); /* Nearest orthonormal matrix P to matrix A formulated */ /* These are the final formulas of the JAES publication M = Ky P Kx^(-1) */ +#if ( BINAURAL_CHANNELS != 2 ) FOR( chA = 0; chA < BINAURAL_CHANNELS; chA++ ) { FOR( chB = 0; chB < BINAURAL_CHANNELS; chB++ ) { IF( Sx_fx[chB] == 0 ) { +#ifdef FIX_1009_REPLACE_DIV_SQRT_BY_ISQRT_LC + Pre_fx[chA][chB] = Mpy_32_32( Pre_fx[chA][chB], ONE_DIV_EPSILON_MANT ); + // q_Pre[chA][chB] = add(sub(31, q_P), 31 - ONE_DIV_EPSILON_EXP); + q_Pre[chA][chB] = sub( 62 - ONE_DIV_EPSILON_EXP, q_P ); + + + Pim_fx[chA][chB] = Mpy_32_32( Pim_fx[chA][chB], ONE_DIV_EPSILON_MANT ); + // q_Pim[chA][chB] = add(sub(31, q_P), 31 - ONE_DIV_EPSILON_EXP); + q_Pim[chA][chB] = sub( 62 - ONE_DIV_EPSILON_EXP, q_P ); +#else Pre_fx[chA][chB] = BASOP_Util_Divide3232_Scale_cadence( Pre_fx[chA][chB], 4611686, &exp ); // 4611686 = 1e-12 in Q62 q_Pre[chA][chB] = add( sub( q_P, 62 ), sub( 31, exp ) ); Pim_fx[chA][chB] = BASOP_Util_Divide3232_Scale_cadence( Pim_fx[chA][chB], 4611686, &exp ); // 4611686 = 1e-12 in Q62 q_Pim[chA][chB] = add( sub( q_P, 62 ), sub( 31, exp ) ); +#endif } ELSE { +#ifdef FIX_1009_REPLACE_DIV_SQRT_BY_ISQRT_LC + Word16 Pre_shift, Pim_shift; +#endif temp = BASOP_Util_Add_Mant32Exp( Sx_fx[chB], sub( 31, q_Sx ), EPSILON_MANT, EPSILON_EXP, &exp_temp ); +#ifndef FIX_1009_REPLACE_DIV_SQRT_BY_ISQRT_LC Pre_fx[chA][chB] = BASOP_Util_Divide3232_Scale_cadence( Pre_fx[chA][chB], temp, &exp ); q_Pre[chA][chB] = add( sub( q_P, sub( 31, exp_temp ) ), sub( 31, exp ) ); Pim_fx[chA][chB] = BASOP_Util_Divide3232_Scale_cadence( Pim_fx[chA][chB], temp, &exp ); q_Pim[chA][chB] = add( sub( q_P, sub( 31, exp_temp ) ), sub( 31, exp ) ); +#else + temp = BASOP_Util_Divide3232_Scale_cadence( ONE_IN_Q30, temp, &exp ); + Pre_shift = norm_l( Pre_fx[chA][chB] ); + Pim_shift = norm_l( Pim_fx[chA][chB] ); + Pre_fx[chA][chB] = Mpy_32_32( L_shl( Pre_fx[chA][chB], Pre_shift ), temp ); + Pim_fx[chA][chB] = Mpy_32_32( L_shl( Pim_fx[chA][chB], Pim_shift ), temp ); + q_temp = add( sub( sub( q_P, exp ), sub( 31, Q30 ) ), exp_temp ); + q_Pre[chA][chB] = add( q_temp, Pre_shift ); + q_Pim[chA][chB] = add( q_temp, Pim_shift ); +#endif + } + if ( Pre_fx[chA][chB] == 0 ) + { + q_Pre[chA][chB] = 31; + move16(); + } + if ( Pim_fx[chA][chB] == 0 ) + { + q_Pim[chA][chB] = 31; + move16(); } move32(); move32(); @@ -4426,6 +5821,72 @@ static void formulate2x2MixingMatrix_fx( move16(); } } +#else + /* BINAURAL_CHANNEL == 2 */ + FOR( chB = 0; chB < BINAURAL_CHANNELS; chB++ ) + { + IF( Sx_fx[chB] == 0 ) + { + Pre_fx[0][chB] = Mpy_32_32( Pre_fx[0][chB], ONE_DIV_EPSILON_MANT ); + q_Pre[0][chB] = sub( 62 - ONE_DIV_EPSILON_EXP, q_P ); + Pim_fx[0][chB] = Mpy_32_32( Pim_fx[0][chB], ONE_DIV_EPSILON_MANT ); + q_Pim[0][chB] = sub( 62 - ONE_DIV_EPSILON_EXP, q_P ); + Pre_fx[1][chB] = Mpy_32_32( Pre_fx[1][chB], ONE_DIV_EPSILON_MANT ); + q_Pre[1][chB] = sub( 62 - ONE_DIV_EPSILON_EXP, q_P ); + Pim_fx[1][chB] = Mpy_32_32( Pim_fx[1][chB], ONE_DIV_EPSILON_MANT ); + q_Pim[1][chB] = sub( 62 - ONE_DIV_EPSILON_EXP, q_P ); + } + ELSE + { + Word16 Pre_shift, Pim_shift; + temp = BASOP_Util_Add_Mant32Exp( Sx_fx[chB], sub( 31, q_Sx ), EPSILON_MANT, EPSILON_EXP, &exp_temp ); + temp = BASOP_Util_Divide3232_Scale_cadence( ONE_IN_Q30, temp, &exp ); + q_temp = add( sub( sub( q_P, exp ), sub( 31, Q30 ) ), exp_temp ); + + Pre_shift = norm_l( Pre_fx[0][chB] ); + Pim_shift = norm_l( Pim_fx[0][chB] ); + Pre_fx[0][chB] = Mpy_32_32( L_shl( Pre_fx[0][chB], Pre_shift ), temp ); + Pim_fx[0][chB] = Mpy_32_32( L_shl( Pim_fx[0][chB], Pim_shift ), temp ); + q_Pre[0][chB] = add( q_temp, Pre_shift ); + q_Pim[0][chB] = add( q_temp, Pim_shift ); + + Pre_shift = norm_l( Pre_fx[1][chB] ); + Pim_shift = norm_l( Pim_fx[1][chB] ); + Pre_fx[1][chB] = Mpy_32_32( L_shl( Pre_fx[1][chB], Pre_shift ), temp ); + Pim_fx[1][chB] = Mpy_32_32( L_shl( Pim_fx[1][chB], Pim_shift ), temp ); + q_Pre[1][chB] = add( q_temp, Pre_shift ); + q_Pim[1][chB] = add( q_temp, Pim_shift ); + } + if ( Pre_fx[0][chB] == 0 ) + { + q_Pre[0][chB] = 31; + move16(); + } + if ( Pim_fx[0][chB] == 0 ) + { + q_Pim[0][chB] = 31; + move16(); + } + if ( Pre_fx[1][chB] == 0 ) + { + q_Pre[1][chB] = 31; + move16(); + } + if ( Pim_fx[1][chB] == 0 ) + { + q_Pim[1][chB] = 31; + move16(); + } + move32(); + move32(); + move16(); + move16(); + move32(); + move32(); + move16(); + move16(); + } +#endif minimum_s( q_Pre[0], i_mult( BINAURAL_CHANNELS, BINAURAL_CHANNELS ), &exp ); q_P = s_min( q_P, exp ); minimum_s( q_Pim[0], i_mult( BINAURAL_CHANNELS, BINAURAL_CHANNELS ), &exp ); @@ -4444,8 +5905,12 @@ static void formulate2x2MixingMatrix_fx( matrixMul_fx( KyRe_fx, KyIm_fx, &q_ky, Pre_fx, Pim_fx, &q_P, tmpRe_fx, tmpIm_fx, &q_temp ); - matrixTransp2Mul_fx( tmpRe_fx, tmpIm_fx, &q_temp, Uxre_fx, Uxim_fx, &q_Ux, Mre_fx, Mim_fx, q_M ); - + matrixTransp2Mul_fx( tmpRe_fx, tmpIm_fx, &q_temp, Uxre_fx, Uxim_fx, &q_Ux, +#ifdef FIX_1072_SPEEDUP_matrixTransp2Mul_fx + 1 /*int Ascale*/, + 0 /*int Bscale*/, +#endif + Mre_fx, Mim_fx, q_M ); return; } @@ -5105,9 +6570,16 @@ static void ivas_masa_ext_rend_parambin_internal_fx( MASA_EXT_REND_HANDLE hMasaExtRend, COMBINED_ORIENTATION_HANDLE hCombinedOrientationData, Word32 *output_fx[], /* Q11*/ - const Word16 subframe ) +#ifdef SPLIT_REND_WITH_HEAD_ROT + const Word16 subframe, + const SPLIT_REND_WRAPPER *hSplitRendWrapper, + Word32 Cldfb_Out_Real[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + Word32 Cldfb_Out_Imag[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX] +#else + const Word16 subframe +#endif +) { - DIRAC_DEC_BIN_HANDLE hDiracDecBin; SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom; PARAMBIN_REND_CONFIG config_data; @@ -5117,7 +6589,26 @@ static void ivas_masa_ext_rend_parambin_internal_fx( Word16 i, j; Word16 nchan_transport; Word16 q_mat; +#ifdef SPLIT_REND_WITH_HEAD_ROT + int16_t pos_idx; + const MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData; + Word32 tmp_Cldfb_out_re[BINAURAL_CHANNELS][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX]; + Word32 tmp_Cldfb_out_im[BINAURAL_CHANNELS][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX]; + + /* these allow re-using the reverb and freq-domain decorrelator signals from ivas_dirac_dec_binaural_process_output() in split rendering for the side renderings */ + Word32 reverbRe_fx[BINAURAL_CHANNELS][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX]; + Word32 reverbIm_fx[BINAURAL_CHANNELS][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX]; + Word32 decorrRe_fx[BINAURAL_CHANNELS][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX]; + Word32 decorrIm_fx[BINAURAL_CHANNELS][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX]; + Word32 subFrameTotalEne_fx[CLDFB_NO_CHANNELS_MAX]; + Word16 subFrameTotalEne_e[CLDFB_NO_CHANNELS_MAX]; + Word32 IIReneLimiter_fx[CLDFB_NO_CHANNELS_MAX]; + Word16 Q_inp_mix; + + hDiracDecBin = hMasaExtRend->hDiracDecBin[0]; +#else hDiracDecBin = hMasaExtRend->hDiracDecBin; +#endif hSpatParamRendCom = hMasaExtRend->hSpatParamRendCom; Word32 Cldfb_RealBuffer_in_fx[6][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX]; @@ -5132,8 +6623,11 @@ static void ivas_masa_ext_rend_parambin_internal_fx( } } Word32 Rmat_fx[3][3]; - +#ifdef SPLIT_REND_WITH_HEAD_ROT + hDiracDecBin = hMasaExtRend->hDiracDecBin[0]; +#else hDiracDecBin = hMasaExtRend->hDiracDecBin; +#endif assert( hDiracDecBin ); hSpatParamRendCom = hMasaExtRend->hSpatParamRendCom; nBins = hSpatParamRendCom->num_freq_bands; @@ -5237,18 +6731,30 @@ static void ivas_masa_ext_rend_parambin_internal_fx( IF( EQ_16( nchan_transport, 2 ) ) { +#ifdef SPLIT_REND_WITH_HEAD_ROT + /* in case of split rendering, determine the prototype rotation based on the main direction and use the same prototypes for the offset directions */ +#endif adaptTransportSignalsHeadtracked_fx( hCombinedOrientationData, Cldfb_RealBuffer_in_fx, Cldfb_ImagBuffer_in_fx, q_inp, nBins, hSpatParamRendCom->subframe_nbslots[subframe], Rmat_fx ); ivas_dirac_dec_binaural_check_and_switch_transports_headtracked_fx( hCombinedOrientationData, Cldfb_RealBuffer_in_fx, Cldfb_ImagBuffer_in_fx, nBins, hSpatParamRendCom->subframe_nbslots[subframe], Rmat_fx ); } } test(); +#ifndef SPLIT_REND_WITH_HEAD_ROT ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matrices_fx( hDiracDecBin, hSpatParamRendCom, &config_data, Cldfb_RealBuffer_in_fx, Cldfb_ImagBuffer_in_fx, Rmat_fx, subframe, hCombinedOrientationData && hCombinedOrientationData->enableCombinedOrientation[hCombinedOrientationData->subframe_idx] > 0, NULL, q_inp ); - +#endif /* Always using CLDFB decorrelation in MASA EXT renderer */ max_band_decorr = hDiracDecBin->h_freq_domain_decorr_ap_params->max_band_decorr; +#ifdef SPLIT_REND_WITH_HEAD_ROT + ivas_dirac_dec_binaural_formulate_input_covariance_matrices_fx( hDiracDecBin, hSpatParamRendCom, &config_data, Cldfb_RealBuffer_in_fx, Cldfb_ImagBuffer_in_fx, subframe, + subFrameTotalEne_fx, subFrameTotalEne_e, IIReneLimiter_fx, q_inp ); + ivas_dirac_dec_binaural_formulate_target_covariance_matrices_fx( hDiracDecBin, hSpatParamRendCom, &config_data, Rmat_fx, subframe, + hCombinedOrientationData && hCombinedOrientationData->enableCombinedOrientation[hCombinedOrientationData->subframe_idx] > 0, + subFrameTotalEne_fx, subFrameTotalEne_e, IIReneLimiter_fx, NULL ); +#endif + ivas_dirac_dec_binaural_determine_processing_matrices_fx( hDiracDecBin, hSpatParamRendCom, &config_data, max_band_decorr, Rmat_fx, subframe, hCombinedOrientationData && hCombinedOrientationData->enableCombinedOrientation[hCombinedOrientationData->subframe_idx] > 0, 0, NULL ); @@ -5298,11 +6804,144 @@ static void ivas_masa_ext_rend_parambin_internal_fx( move16(); move16(); - ivas_dirac_dec_binaural_process_output_fx( hDiracDecBin, hSpatParamRendCom, hMasaExtRend->cldfbSynRend, output_fx, &q_out, Cldfb_RealBuffer_in_fx, Cldfb_ImagBuffer_in_fx, q_inp, max_band_decorr, numInChannels, config_data.processReverb, subframe, q_mat ); +#ifdef SPLIT_REND_WITH_HEAD_ROT + pMultiBinPoseData = NULL; + if ( hSplitRendWrapper != NULL ) + { + pMultiBinPoseData = &( hSplitRendWrapper->multiBinPoseData ); + + ivas_dirac_dec_binaural_process_output_fx( hDiracDecBin, hSpatParamRendCom, hMasaExtRend->cldfbSynRend, output_fx, &q_out, Cldfb_RealBuffer_in_fx, Cldfb_ImagBuffer_in_fx, q_inp, max_band_decorr, numInChannels, config_data.processReverb, subframe, q_mat, tmp_Cldfb_out_re, tmp_Cldfb_out_im, + reverbRe_fx, reverbIm_fx, decorrRe_fx, decorrIm_fx, &Q_inp_mix, 1 ); + for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) + { + for ( i = 0; i < CLDFB_SLOTS_PER_SUBFRAME; i++ ) + { + Copy32( tmp_Cldfb_out_re[ch][i], Cldfb_Out_Real[ch][subframe * CLDFB_SLOTS_PER_SUBFRAME + i], CLDFB_NO_CHANNELS_MAX ); + Copy32( tmp_Cldfb_out_im[ch][i], Cldfb_Out_Imag[ch][subframe * CLDFB_SLOTS_PER_SUBFRAME + i], CLDFB_NO_CHANNELS_MAX ); + } + } + } + else + { + ivas_dirac_dec_binaural_process_output_fx( hDiracDecBin, hSpatParamRendCom, hMasaExtRend->cldfbSynRend, output_fx, &q_out, Cldfb_RealBuffer_in_fx, Cldfb_ImagBuffer_in_fx, q_inp, max_band_decorr, numInChannels, config_data.processReverb, subframe, q_mat, NULL, NULL, + reverbRe_fx, reverbIm_fx, decorrRe_fx, decorrIm_fx, &Q_inp_mix, 1 ); + } +#else + ivas_dirac_dec_binaural_process_output_fx( hDiracDecBin, hSpatParamRendCom, hMasaExtRend->cldfbSynRend, output_fx, &q_out, Cldfb_RealBuffer_in_fx, Cldfb_ImagBuffer_in_fx, q_inp, max_band_decorr, numInChannels, config_data.processReverb, subframe, q_mat ); +#endif hDiracDecBin->hDiffuseDist = NULL; +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( pMultiBinPoseData != NULL && pMultiBinPoseData->num_poses > 1 ) + { + /* quaternion-based rotation from ivas_binRenderer_internal.c:ivas_binRenderer(), but using absolute rotation instead of delta rotations */ + IVAS_QUATERNION Quaternions_rot, Quaternions_abs, *Quaternions_ref; + Word32 Rmat_local[3][3]; + + + if ( hCombinedOrientationData ) + { + Quaternions_ref = &hCombinedOrientationData->Quaternions[0]; + Copy_Quat_fx( Quaternions_ref, &Quaternions_abs ); + modify_Quat_q_fx( &Quaternions_abs, &Quaternions_abs, Q22 ); + Quaternions_rot.w_fx = L_negate( 12582912 ); /* signal to use Euler */ + Quat2EulerDegree_fx( Quaternions_abs, &Quaternions_abs.z_fx, &Quaternions_abs.y_fx, &Quaternions_abs.x_fx ); /*order in Quat2Euler seems to be reversed ?*/ + Quaternions_abs.w_fx = L_negate( 12582912 ); /* signal to use Euler */ + + FOR( pos_idx = 1; pos_idx < pMultiBinPoseData->num_poses; pos_idx++ ) + { + Quaternions_rot.x_fx = L_add( Quaternions_abs.x_fx, pMultiBinPoseData->relative_head_poses_fx[pos_idx][0] ); + Quaternions_rot.y_fx = L_add( Quaternions_abs.y_fx, pMultiBinPoseData->relative_head_poses_fx[pos_idx][1] ); + Quaternions_rot.z_fx = L_add( Quaternions_abs.z_fx, pMultiBinPoseData->relative_head_poses_fx[pos_idx][2] ); + move32(); + move32(); + move32(); + Euler2Quat_fx( deg2rad_fx( Quaternions_rot.x_fx ), deg2rad_fx( Quaternions_rot.y_fx ), deg2rad_fx( Quaternions_rot.z_fx ), &Quaternions_rot ); + modify_Quat_q_fx( &Quaternions_rot, &Quaternions_rot, Quaternions_ref->q_fact ); + QuatToRotMat_fx( Quaternions_rot, Rmat_local ); + modify_Rmat_q_fx( Rmat_local, Rmat_local, sub( shl( Quaternions_ref->q_fact, 1 ), 32 ), Q30 ); + + hDiracDecBin = hMasaExtRend->hDiracDecBin[pos_idx]; + assert( hDiracDecBin != NULL && "No DiracDecBin handle for this position" ); + + /* re-use input covariance for the side renderings */ + FOR( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) + { + Copy32( hMasaExtRend->hDiracDecBin[0]->ChEne_fx[ch], hDiracDecBin->ChEne_fx[ch], hSpatParamRendCom->num_freq_bands ); + Copy( hMasaExtRend->hDiracDecBin[0]->ChEne_e[ch], hDiracDecBin->ChEne_e[ch], hSpatParamRendCom->num_freq_bands ); + } + Copy32( hMasaExtRend->hDiracDecBin[0]->ChCrossRe_fx, hDiracDecBin->ChCrossRe_fx, hSpatParamRendCom->num_freq_bands ); + Copy32( hMasaExtRend->hDiracDecBin[0]->ChCrossIm_fx, hDiracDecBin->ChCrossIm_fx, hSpatParamRendCom->num_freq_bands ); + Copy( hMasaExtRend->hDiracDecBin[0]->ChCrossRe_e, hDiracDecBin->ChCrossRe_e, hSpatParamRendCom->num_freq_bands ); + Copy( hMasaExtRend->hDiracDecBin[0]->ChCrossIm_e, hDiracDecBin->ChCrossIm_e, hSpatParamRendCom->num_freq_bands ); + + ivas_dirac_dec_binaural_formulate_target_covariance_matrices_fx( hDiracDecBin, hSpatParamRendCom, &config_data, Rmat_local, subframe, + hCombinedOrientationData && hCombinedOrientationData->enableCombinedOrientation[subframe] > 0, + subFrameTotalEne_fx, subFrameTotalEne_e, IIReneLimiter_fx, NULL ); + + ivas_dirac_dec_binaural_determine_processing_matrices_fx( hDiracDecBin, hSpatParamRendCom, &config_data, max_band_decorr, Rmat_local, subframe, + hCombinedOrientationData && hCombinedOrientationData->enableCombinedOrientation[subframe] > 0, + 0, NULL ); + + + q_mat = hDiracDecBin->q_processMtx; + move16(); + q_mat = s_min( q_mat, hDiracDecBin->q_processMtxPrev ); + q_mat = s_min( q_mat, hDiracDecBin->q_processMtxDec ); + q_mat = s_min( q_mat, hDiracDecBin->q_processMtxDecPrev ); + + FOR( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) + { + FOR( slot = 0; slot < BINAURAL_CHANNELS; slot++ ) + { + Scale_sig( hDiracDecBin->processMtxDecRe_fx[ch][slot], nBins, sub( q_mat, hDiracDecBin->q_processMtxDec ) ); // scaling to q_mat + Scale_sig( hDiracDecBin->processMtxDecIm_fx[ch][slot], nBins, sub( q_mat, hDiracDecBin->q_processMtxDec ) ); // scaling to q_mat + Scale_sig( hDiracDecBin->processMtxDecRePrev_fx[ch][slot], nBins, sub( q_mat, hDiracDecBin->q_processMtxDecPrev ) ); // scaling to q_mat + Scale_sig( hDiracDecBin->processMtxDecImPrev_fx[ch][slot], nBins, sub( q_mat, hDiracDecBin->q_processMtxDecPrev ) ); // scaling to q_mat + } + } + FOR( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) + { + FOR( slot = 0; slot < numInChannels; slot++ ) + { + Scale_sig( hDiracDecBin->processMtxRe_fx[ch][slot], nBins, sub( q_mat, hDiracDecBin->q_processMtx ) ); // scaling to q_mat + Scale_sig( hDiracDecBin->processMtxIm_fx[ch][slot], nBins, sub( q_mat, hDiracDecBin->q_processMtx ) ); // scaling to q_mat + Scale_sig( hDiracDecBin->processMtxRePrev_fx[ch][slot], nBins, sub( q_mat, hDiracDecBin->q_processMtxPrev ) ); // scaling to q_mat + Scale_sig( hDiracDecBin->processMtxImPrev_fx[ch][slot], nBins, sub( q_mat, hDiracDecBin->q_processMtxPrev ) ); // scaling to q_mat + } + } + hDiracDecBin->q_processMtx = q_mat; + hDiracDecBin->q_processMtxPrev = q_mat; + hDiracDecBin->q_processMtxDec = q_mat; + hDiracDecBin->q_processMtxDecPrev = q_mat; + move16(); + move16(); + move16(); + move16(); + /* re-use reverb and decorr from main direction for the sides */ + ivas_dirac_dec_binaural_process_output_fx( hDiracDecBin, hSpatParamRendCom, hMasaExtRend->cldfbSynRend, output_fx, &q_out, Cldfb_RealBuffer_in_fx, Cldfb_ImagBuffer_in_fx, q_inp, max_band_decorr, numInChannels, config_data.processReverb, subframe, q_mat, tmp_Cldfb_out_re, tmp_Cldfb_out_im, + reverbRe_fx, reverbIm_fx, decorrRe_fx, decorrIm_fx, &Q_inp_mix, 0 ); + + /* copy from temporary buffer to the main split rendering buffer */ + for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) + { + for ( i = 0; i < CLDFB_SLOTS_PER_SUBFRAME; i++ ) + { + Copy32( tmp_Cldfb_out_re[ch][i], Cldfb_Out_Real[pos_idx * BINAURAL_CHANNELS + ch][subframe * CLDFB_SLOTS_PER_SUBFRAME + i], CLDFB_NO_CHANNELS_MAX ); + Copy32( tmp_Cldfb_out_im[ch][i], Cldfb_Out_Imag[pos_idx * BINAURAL_CHANNELS + ch][subframe * CLDFB_SLOTS_PER_SUBFRAME + i], CLDFB_NO_CHANNELS_MAX ); + } + } + + hDiracDecBin->hDiffuseDist = NULL; + } + } + } + + /* update this counter only after the last rendering of split directions */ +#endif + hSpatParamRendCom->slots_rendered = add( hSpatParamRendCom->slots_rendered, hSpatParamRendCom->subframe_nbslots[subframe] ); hSpatParamRendCom->subframes_rendered = add( hSpatParamRendCom->subframes_rendered, 1 ); move16(); @@ -5322,7 +6961,15 @@ void ivas_masa_ext_rend_parambin_render_fx( MASA_EXT_REND_HANDLE hMasaExtRend, /* i/o: MASA ext rend structure */ COMBINED_ORIENTATION_HANDLE hCombinedOrientationData, /* i : combined orientation handle */ Word32 *output_f[], /* i/o: synthesized core-coder transport channels/DirAC output Q11*/ - const Word16 num_subframes ) /* i : number of subframes to render */ +#ifdef SPLIT_REND_WITH_HEAD_ROT + const Word16 num_subframes, /* i : number of subframes to render */ + const SPLIT_REND_WRAPPER *hSplitRendWrapper, /* i : split rendering orientation data */ + Word32 Cldfb_Out_Real[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], /* o : rendered orientations for split rend. real part of cldfb */ + Word32 Cldfb_Out_Imag[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX] /* o : rendered orientations for split rend. imag part of cldfb */ +#else + const Word16 num_subframes /* i : number of subframes to render */ +#endif +) { Word16 subframe; SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom; @@ -5344,8 +6991,11 @@ void ivas_masa_ext_rend_parambin_render_fx( hSpatParamRendCom->slots_rendered = 0; move16(); +#ifdef SPLIT_REND_WITH_HEAD_ROT + ivas_masa_ext_rend_parambin_internal_fx( hMasaExtRend, hCombinedOrientationData, p_output, hSpatParamRendCom->dirac_read_idx, hSplitRendWrapper, Cldfb_Out_Real, Cldfb_Out_Imag ); +#else ivas_masa_ext_rend_parambin_internal_fx( hMasaExtRend, hCombinedOrientationData, p_output, hSpatParamRendCom->dirac_read_idx ); - +#endif FOR( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) { p_output[ch] += n_samples_sf; diff --git a/lib_rend/ivas_dirac_decorr_dec.c b/lib_rend/ivas_dirac_decorr_dec_fx.c similarity index 92% rename from lib_rend/ivas_dirac_decorr_dec.c rename to lib_rend/ivas_dirac_decorr_dec_fx.c index c50d690c5b80f4812770e4aab2d6bbb26aabc62f..1ffe0da7424b728fc644a9f70c40b1d3a50eb587 100644 --- a/lib_rend/ivas_dirac_decorr_dec.c +++ b/lib_rend/ivas_dirac_decorr_dec_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other @@ -35,13 +35,11 @@ #include "options.h" #include #include "cnst.h" -#include "prot.h" -#include "ivas_prot.h" -#include "ivas_prot_rend.h" +#include "prot_fx.h" +#include "ivas_prot_rend_fx.h" #include "ivas_cnst.h" #include "ivas_rom_rend.h" #include "wmc_auto.h" -#include "prot_fx.h" #include "ivas_prot_fx.h" /*------------------------------------------------------------------------- @@ -68,7 +66,7 @@ *------------------------------------------------------------------------*/ static void get_lattice_coeffs_fx( const Word16 band_index, const Word16 channel_index, Word16 *lattice_coeffs ); -static void lattice2allpass_fx( const int16_t filter_length, const Word16 *lattice_coeffs_fx, Word16 *filter_coeffs_num_real_fx, Word16 *filter_coeffs_den_real_fx ); +static void lattice2allpass_fx( const Word16 filter_length, const Word16 *lattice_coeffs_fx, Word16 *filter_coeffs_num_real_fx, Word16 *filter_coeffs_den_real_fx ); /*------------------------------------------------------------------------- * ivas_dirac_dec_decorr_open() @@ -409,7 +407,7 @@ void ivas_dirac_dec_decorr_process_fx( HANDLE_DIRAC_DECORR_STATE h_freq_domain_decorr_ap_state ) { - Word16 ch_idx, k, l, idx_in_out, max_band_decorr; + Word16 ch_idx, k, l, max_band_decorr; Word16 split_bands_idx, band_idx, decorr_buffer_len, time_idx; Word16 offset, idx_filter, incr_aux; Word16 k_1, k_2, num_bands, filter_length, pre_delay, decorr_buffer_step; @@ -506,22 +504,24 @@ void ivas_dirac_dec_decorr_process_fx( set32_fx( onset_filter_fx, ONE_IN_Q31, imult1616( num_protos_diff, num_freq_bands ) ); Word16 q_temp = s_min( q_onset_dec, q_aux_buffer ); + Word16 shift_q = sub( q_onset_dec, q_temp ); - IF( NE_16( q_temp, q_onset_dec ) ) + IF( shift_q != 0 ) { - FOR( Word16 i = 0; i < imult1616( num_protos_diff, max_band_decorr_temp ); i++ ) + FOR( Word16 i = 0; i < num_protos_diff * max_band_decorr_temp; i++ ) { - h_freq_domain_decorr_ap_state->h_onset_detection_power_state.onset_detector_2_fx[i] = L_shr( h_freq_domain_decorr_ap_state->h_onset_detection_power_state.onset_detector_2_fx[i], sub( q_onset_dec, q_temp ) ); // q_temp - h_freq_domain_decorr_ap_state->h_onset_detection_power_state.onset_detector_1_fx[i] = L_shr( h_freq_domain_decorr_ap_state->h_onset_detection_power_state.onset_detector_1_fx[i], sub( q_onset_dec, q_temp ) ); // q_temp + h_freq_domain_decorr_ap_state->h_onset_detection_power_state.onset_detector_2_fx[i] = L_shr( h_freq_domain_decorr_ap_state->h_onset_detection_power_state.onset_detector_2_fx[i], shift_q ); // q_temp + h_freq_domain_decorr_ap_state->h_onset_detection_power_state.onset_detector_1_fx[i] = L_shr( h_freq_domain_decorr_ap_state->h_onset_detection_power_state.onset_detector_1_fx[i], shift_q ); // q_temp move32(); move32(); } } - IF( NE_16( q_temp, q_aux_buffer ) ) + shift_q = sub( q_aux_buffer, q_temp ); + IF( shift_q != 0 ) { - FOR( Word16 i = 0; i < shl( imult1616( num_protos_diff, max_band_decorr_temp ), 1 ); i++ ) + FOR( Word16 i = 0; i < 2 * num_protos_diff * max_band_decorr_temp; i++ ) { - aux_buffer_fx[i] = L_shr( aux_buffer_fx[i], sub( q_aux_buffer, q_temp ) ); // q_temp + aux_buffer_fx[i] = L_shr( aux_buffer_fx[i], shift_q ); // q_temp move32(); } } @@ -566,9 +566,9 @@ void ivas_dirac_dec_decorr_process_fx( /* final phase rotation */ FOR( k = 0; k < max_band_decorr; k++ ) { - *p_frame_dec_fx = L_sub( Mpy_32_16_1( ( *decorr_buffer_fx ), ( *phase_coeff_real_fx ) ), Mpy_32_16_1( ( *( decorr_buffer_fx + 1 ) ), ( *phase_coeff_imag_fx ) ) ); // sub( q_decorr_buf, 1 ) + *p_frame_dec_fx = Msub_32_16( Mpy_32_16_1( *decorr_buffer_fx, ( *phase_coeff_real_fx ) ), *( decorr_buffer_fx + 1 ), ( *phase_coeff_imag_fx ) ); // sub( q_decorr_buf, 1 ) p_frame_dec_fx++; - *p_frame_dec_fx = L_add( Mpy_32_16_1( ( *decorr_buffer_fx ), ( *phase_coeff_imag_fx ) ), Mpy_32_16_1( ( *( decorr_buffer_fx + 1 ) ), ( *phase_coeff_real_fx ) ) ); // sub( q_decorr_buf, 1 ) + *p_frame_dec_fx = Madd_32_16( Mpy_32_16_1( *decorr_buffer_fx, ( *phase_coeff_imag_fx ) ), ( *( decorr_buffer_fx + 1 ) ), ( *phase_coeff_real_fx ) ); // sub( q_decorr_buf, 1 ) p_frame_dec_fx++; phase_coeff_imag_fx++; phase_coeff_real_fx++; @@ -620,8 +620,8 @@ void ivas_dirac_dec_decorr_process_fx( #endif q_shift = getScaleFactor32( aux_buffer_fx, imult1616( imult1616( 2, num_protos_dir ), max_band_decorr_temp ) ); - - FOR( Word16 j = 0; j < shl( imult1616( num_protos_dir, max_band_decorr_temp ), 1 ); j++ ) + Word16 buf_len = shl( imult1616( num_protos_dir, max_band_decorr_temp ), 1 ); + FOR( Word16 j = 0; j < buf_len; j++ ) { aux_buffer_fx[j] = L_shl( aux_buffer_fx[j], q_shift ); // add( q_aux_buffer, q_shift ) move32(); @@ -674,8 +674,9 @@ void ivas_dirac_dec_decorr_process_fx( filter_coeff_num_real_fx = &h_freq_domain_decorr_ap_params->filter_coeff_num_real_fx[idx_filter]; // Q12 filter_coeff_den_real_fx = &h_freq_domain_decorr_ap_params->filter_coeff_den_real_fx[idx_filter]; // Q12 decorr_buffer_start_ptr_fx = &h_freq_domain_decorr_ap_state->decorr_buffer_fx[2 * ( ch_idx * max_band_decorr + band_idx )]; - input_real_fx = aux_buffer_fx[shl( add( imult1616( proto_index_dir[ch_idx], max_band_decorr ), band_idx ), 1 )]; // q_aux - input_imag_fx = aux_buffer_fx[add( shl( add( imult1616( proto_index_dir[ch_idx], max_band_decorr ), band_idx ), 1 ), 1 )]; // q_aux + Word16 idx = shl( add( imult1616( proto_index_dir[ch_idx], max_band_decorr ), band_idx ), 1 ); + input_real_fx = aux_buffer_fx[idx]; // q_aux + input_imag_fx = aux_buffer_fx[idx + 1]; // q_aux /* MA part of filter impulse response */ FOR( l = 0; l < filter_length; l++ ) @@ -766,14 +767,15 @@ void ivas_dirac_dec_decorr_process_fx( #ifdef MSAN_FIX q_shift = Q31; move16(); + offset = shl( max_band_decorr, 1 ); FOR( ch_idx = 0; ch_idx < num_channels; ++ch_idx ) { q_shift = s_min( q_shift, - L_norm_arr( &frame_dec_fx[shl( imult1616( ch_idx, num_freq_bands ), 1 )], shl( max_band_decorr, 1 ) ) ); + L_norm_arr( &frame_dec_fx[2 * ch_idx * num_freq_bands], offset ) ); } FOR( ch_idx = 0; ch_idx < num_channels; ++ch_idx ) { - Scale_sig32( &frame_dec_fx[shl( imult1616( ch_idx, num_freq_bands ), 1 )], shl( max_band_decorr, 1 ), q_shift ); + scale_sig32( &frame_dec_fx[2 * ch_idx * num_freq_bands], offset, q_shift ); } #else q_shift = L_norm_arr( frame_dec_fx, ( 2 * max_band_decorr + incr_aux ) * num_channels ); @@ -784,13 +786,14 @@ void ivas_dirac_dec_decorr_process_fx( IF( h_freq_domain_decorr_ap_params->use_ducker ) { + Word16 len1 = shl( imult1616( max_band_decorr, num_protos_dir ), 1 ); /* compute direct power w/o onsets for the energy ratio, signal is still in the aux buffer */ - v_mult_fixed( aux_buffer_fx, aux_buffer_fx, aux_buffer_fx, shl( imult1616( max_band_decorr, num_protos_dir ), 1 ) ); // 2 *q_aux -31 + v_mult_fixed( aux_buffer_fx, aux_buffer_fx, aux_buffer_fx, len1 ); // 2 *q_aux -31 - q_aux_buffer = sub( imult1616( 2, q_aux_buffer ), 31 ); + q_aux_buffer = sub( shl( q_aux_buffer, 1 ), 31 ); // if this scaling is eliminated overflow is happening fot v_add_inc_fix - q_shift = sub( L_norm_arr( aux_buffer_fx, shl( imult1616( num_protos_dir, max_band_decorr ), 1 ) ), find_guarded_bits_fx( 2 ) ); + q_shift = sub( L_norm_arr( aux_buffer_fx, len1 ), 1 /*find_guarded_bits_fx( 2 )*/ ); Scale_sig32( aux_buffer_fx, shl( imult1616( num_protos_dir, max_band_decorr_temp ), 1 ), q_shift ); q_aux_buffer = add( q_aux_buffer, q_shift ); @@ -847,18 +850,18 @@ void ivas_dirac_dec_decorr_process_fx( } norm = W_norm( min64 ); #endif - - FOR( Word16 i = 0; i < shl( imult1616( num_channels, max_band_decorr ), 1 ); i++ ) + norm = sub( norm, 1 /*find_guarded_bits_fx( 2 )*/ ); + FOR( Word16 i = 0; i < 2 * num_channels * max_band_decorr; i++ ) { - aux_buffer_fx[i] = W_extract_h( W_shl( aux_64[i], sub( norm, find_guarded_bits_fx( 2 ) ) ) ); + aux_buffer_fx[i] = W_extract_h( W_shl( aux_64[i], norm ) ); move32(); } - q_aux_buffer = add( imult1616( 2, q_frame_f ), sub( sub( norm, 1 ), 32 ) ); + q_aux_buffer = add( shl( q_frame_f, 1 ), sub( norm, 32 ) ); FOR( ch_idx = 0; ch_idx < num_channels; ++ch_idx ) { - v_add_inc_fx( &aux_buffer_fx[shl( imult1616( ch_idx, max_band_decorr ), 1 )], 2, &aux_buffer_fx[add( shl( imult1616( ch_idx, max_band_decorr ), 1 ), 1 )], 2, &aux_buffer_fx[imult1616( ch_idx, max_band_decorr )], 1, max_band_decorr ); + v_add_inc_fx( &aux_buffer_fx[2 * ch_idx * max_band_decorr], 2, &aux_buffer_fx[2 * ch_idx * max_band_decorr + 1], 2, &aux_buffer_fx[ch_idx * max_band_decorr], 1, max_band_decorr ); } /* smooth energies */ @@ -945,8 +948,8 @@ void ivas_dirac_dec_decorr_process_fx( h_freq_domain_decorr_ap_state->q_reverb_energy_smooth = add( h_freq_domain_decorr_ap_state->q_reverb_energy_smooth, q_shift ); move16(); } - h_freq_domain_decorr_ap_state->q_reverb_energy_smooth = min( MAX_Q_FX, h_freq_domain_decorr_ap_state->q_reverb_energy_smooth ); - h_freq_domain_decorr_ap_state->q_direct_energy_smooth = min( MAX_Q_FX, h_freq_domain_decorr_ap_state->q_direct_energy_smooth ); + h_freq_domain_decorr_ap_state->q_reverb_energy_smooth = s_min( MAX_Q_FX, h_freq_domain_decorr_ap_state->q_reverb_energy_smooth ); + h_freq_domain_decorr_ap_state->q_direct_energy_smooth = s_min( MAX_Q_FX, h_freq_domain_decorr_ap_state->q_direct_energy_smooth ); #endif e_reverb_energy_smooth = sub( 31, h_freq_domain_decorr_ap_state->q_reverb_energy_smooth ); @@ -959,7 +962,7 @@ void ivas_dirac_dec_decorr_process_fx( FOR( ch_idx = 0; ch_idx < num_channels; ++ch_idx ) { q_shift = s_min( q_shift, - sub( L_norm_arr( &frame_dec_fx[shl( imult1616( ch_idx, num_freq_bands ), 1 )], shl( max_band_decorr, 1 ) ), + sub( L_norm_arr( &frame_dec_fx[2 * ch_idx * num_freq_bands], shl( max_band_decorr, 1 ) ), Q2 ) ); } FOR( ch_idx = 0; ch_idx < num_channels; ++ch_idx ) @@ -974,7 +977,7 @@ void ivas_dirac_dec_decorr_process_fx( FOR( ch_idx = 0; ch_idx < num_channels; ch_idx++ ) { - Word32 *frame_dec_fx_ptr = &frame_dec_fx[shl( imult1616( ch_idx, num_freq_bands ), 1 )]; + Word32 *frame_dec_fx_ptr = &frame_dec_fx[2 * ch_idx * num_freq_bands]; Word16 cur_proto_index = imult1616( proto_index_dir[ch_idx], max_band_decorr ); Word16 cur_reverb_index = imult1616( ch_idx, max_band_decorr ); Word32 *reverb_energy_smooth_ptr = &h_freq_domain_decorr_ap_state->reverb_energy_smooth_fx[cur_reverb_index]; // q_aux @@ -1020,22 +1023,18 @@ void ivas_dirac_dec_decorr_process_fx( e_duck_gain = add( e_duck_gain, sub( e_direct_energy_smooth, add( e_reverb_energy_smooth, 1 ) ) ); duck_gain = Sqrt16( duck_gain, &e_duck_gain ); - Word16 comp_flag = BASOP_Util_Cmp_Mant32Exp( duck_gain, e_duck_gain, 16384, 2 ); - IF( EQ_16( comp_flag, 1 ) ) + /* if ( duck_gain > 2.0f ) { - duck_gain = 16384; // 2inQ13 - move16(); - } - ELSE - { - duck_gain = shl( duck_gain, sub( e_duck_gain, 2 ) ); // Q13 - } + duck_gain = 2.0f; + } */ + duck_gain = shl_sat( duck_gain, sub( e_duck_gain, 1 ) ); // Q14 + #ifndef FIX_1110_OPTIM_DIRAC_DECORR_PROC frame_dec_fx_ptr[2 * band_idx] = L_shl( Mpy_32_16_1( frame_dec_fx_ptr[2 * band_idx], duck_gain ), 2 ); // q_frame_dec frame_dec_fx_ptr[add( shl( band_idx, 1 ), 1 )] = L_shl( Mpy_32_16_1( frame_dec_fx_ptr[add( shl( band_idx, 1 ), 1 )], duck_gain ), 2 ); // q_frame_dec #else - frame_dec_fx_ptr[2 * band_idx] = L_shl( Mpy_32_16_1( frame_dec_fx_ptr[2 * band_idx], duck_gain ), 2 ); // q_frame_dec - frame_dec_fx_ptr[2 * band_idx + 1] = L_shl( Mpy_32_16_1( frame_dec_fx_ptr[2 * band_idx + 1], duck_gain ), 2 ); // q_frame_dec + frame_dec_fx_ptr[2 * band_idx] = L_shl( Mpy_32_16_1( frame_dec_fx_ptr[2 * band_idx], duck_gain ), 1 ); // q_frame_dec + frame_dec_fx_ptr[2 * band_idx + 1] = L_shl( Mpy_32_16_1( frame_dec_fx_ptr[2 * band_idx + 1], duck_gain ), 1 ); // q_frame_dec #endif move32(); move32(); @@ -1055,7 +1054,7 @@ void ivas_dirac_dec_decorr_process_fx( Word16 sf = MAX_16; FOR( ch_idx = 0; ch_idx < num_channels; ++ch_idx ) { - sf = s_min( sf, getScaleFactor32( &frame_dec_fx[shl( imult1616( ch_idx, num_freq_bands ), 1 )], shl( max_band_decorr, 1 ) ) ); + sf = s_min( sf, getScaleFactor32( &frame_dec_fx[2 * ch_idx * num_freq_bands], shl( max_band_decorr, 1 ) ) ); } sf = s_min( sub( sf, 1 ), q_shift ); q_if_local = sub( q_shift, sf ); @@ -1065,7 +1064,7 @@ void ivas_dirac_dec_decorr_process_fx( #ifdef MSAN_FIX FOR( ch_idx = 0; ch_idx < num_channels; ++ch_idx ) { - scale_sig32( &frame_dec_fx[shl( imult1616( ch_idx, num_freq_bands ), 1 )], shl( max_band_decorr, 1 ), q_shift ); + scale_sig32( &frame_dec_fx[2 * ch_idx * num_freq_bands], shl( max_band_decorr, 1 ), q_shift ); } #else Scale_sig32( frame_dec_fx, ( 2 * max_band_decorr + incr_aux ) * num_channels, q_shift ); // scaling it to input q @@ -1078,7 +1077,7 @@ void ivas_dirac_dec_decorr_process_fx( #ifdef MSAN_FIX FOR( ch_idx = 0; ch_idx < num_channels; ++ch_idx ) { - scale_sig32( &frame_dec_fx[shl( imult1616( ch_idx, num_freq_bands ), 1 )], shl( max_band_decorr, 1 ), q_shift ); + scale_sig32( &frame_dec_fx[2 * ch_idx * num_freq_bands], shl( max_band_decorr, 1 ), q_shift ); } #else Scale_sig32( frame_dec_fx, ( 2 * max_band_decorr + incr_aux ) * num_channels, q_shift ); // scaling it to input q @@ -1098,24 +1097,22 @@ void ivas_dirac_dec_decorr_process_fx( FOR( k = 0; k < max_band_decorr; ++k ) { - aux_buffer_fx[2 * k] = Mpy_32_32( L_shr_r( input_frame_fx[add( shl( offset, 1 ), shl( k, 1 ) )], q_if_local ), L_sub( ONE_IN_Q31, onset_filter_fx[add( offset, k )] ) ); - aux_buffer_fx[add( shl( k, 1 ), 1 )] = Mpy_32_32( L_shr_r( input_frame_fx[add( add( shl( offset, 1 ), shl( k, 1 ) ), 1 )], q_if_local ), L_sub( ONE_IN_Q31, onset_filter_fx[add( offset, k )] ) ); // q_frame_f + aux_buffer_fx[2 * k] = Mpy_32_32( L_shr_r( input_frame_fx[2 * ( offset + k )], q_if_local ), L_sub( ONE_IN_Q31, onset_filter_fx[offset + k] ) ); + aux_buffer_fx[add( shl( k, 1 ), 1 )] = Mpy_32_32( L_shr_r( input_frame_fx[2 * ( offset + k ) + 1], q_if_local ), L_sub( ONE_IN_Q31, onset_filter_fx[offset + k] ) ); // q_frame_f move32(); move32(); } - v_add_fx( &frame_dec_fx[imult1616( ch_idx, shl( num_freq_bands, 1 ) )], aux_buffer_fx, &frame_dec_fx[imult1616( ch_idx, shl( num_freq_bands, 1 ) )], shl( max_band_decorr, 1 ) ); + v_add_fx( &frame_dec_fx[2 * ch_idx * num_freq_bands], aux_buffer_fx, &frame_dec_fx[2 * ch_idx * num_freq_bands], shl( max_band_decorr, 1 ) ); } } /* avoid decorrelation above maximum frequency -> set to zero the remaining frequencies*/ + Word16 val = shl( sub( num_freq_bands, h_freq_domain_decorr_ap_params->max_band_decorr ), 1 ); FOR( ch_idx = 0; ch_idx < num_channels; ++ch_idx ) { - /* calc output indices */ - idx_in_out = shl( ( add( imult1616( ch_idx, num_freq_bands ), h_freq_domain_decorr_ap_params->max_band_decorr ) ), 1 ); - /* copy to output signal */ - set32_fx( &frame_dec_fx[idx_in_out], 0, shl( sub( num_freq_bands, h_freq_domain_decorr_ap_params->max_band_decorr ), 1 ) ); + set32_fx( &frame_dec_fx[2 * ( ch_idx * num_freq_bands + h_freq_domain_decorr_ap_params->max_band_decorr )], 0, val ); } *q_frame_dec = q_frame_f; move16(); @@ -1282,7 +1279,7 @@ static void get_lattice_coeffs_fx( /* convert lattice filter coeffs to all pass transfer function coeffs */ static void lattice2allpass_fx( - const int16_t filter_length, // Q0 + const Word16 filter_length, // Q0 const Word16 *lattice_coeffs_fx, // Q15 Word16 *filter_coeffs_num_real_fx, // Q12 Word16 *filter_coeffs_den_real_fx ) // Q12 diff --git a/lib_rend/ivas_dirac_onsets_dec.c b/lib_rend/ivas_dirac_onsets_dec_fx.c similarity index 70% rename from lib_rend/ivas_dirac_onsets_dec.c rename to lib_rend/ivas_dirac_onsets_dec_fx.c index 9e82fa02269f2456dac58a477d3916a05d34f13c..80adebfdd18661e0160e31f6c753bfd60cd6930a 100644 --- a/lib_rend/ivas_dirac_onsets_dec.c +++ b/lib_rend/ivas_dirac_onsets_dec_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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,118 +34,12 @@ #include #include "options.h" #include "cnst.h" -#include "prot.h" -#include "ivas_prot.h" -#include "ivas_prot_rend.h" +#include "prot_fx.h" +#include "ivas_prot_rend_fx.h" #include "ivas_cnst.h" #include "ivas_rom_com.h" #include "ivas_rom_dec.h" #include "wmc_auto.h" -#include "prot_fx.h" - -static Word16 BASOP_Util_Cmp_Mant32Exp_sat( Word32 a_m, Word16 a_e, Word32 b_m, Word16 b_e ); -Word16 BASOP_Util_Cmp_Mant32Exp_sat /*!< o: flag: result of comparison */ - /* 0, if a == b */ - /* 1, if a > b */ - /* -1, if a < b */ - ( Word32 a_m, /*!< i: Mantissa of 1st operand a */ - Word16 a_e, /*!< i: Exponent of 1st operand a */ - Word32 b_m, /*!< i: Mantissa of 2nd operand b */ - Word16 b_e ) /*!< i: Exponent of 2nd operand b */ - -{ - Word32 diff_m; - Word16 diff_e, shift, result; - - - /* - This function compares two input parameters, both represented by a 32-bit mantissa and a 16-bit exponent. - If both values are identical, 0 is returned. - If a is greater b, 1 is returned. - If a is less than b, -1 is returned. - */ - - /* Check, if both mantissa and exponents are identical, when normalized: return 0 */ - shift = norm_l( a_m ); - IF( shift ) - { - a_m = L_shl( a_m, shift ); - } - IF( shift ) - { - a_e = sub( a_e, shift ); - } - - shift = norm_l( b_m ); - IF( shift ) - { - b_m = L_shl( b_m, shift ); - } - IF( shift ) - { - b_e = sub( b_e, shift ); - } - - /* align exponent, if any mantissa is zero */ - if ( !a_m ) - { - a_e = b_e; - move16(); - } - if ( !b_m ) - { - b_e = a_e; - move16(); - } - - BASOP_SATURATE_WARNING_OFF_EVS - diff_m = L_sub_sat( a_m, b_m ); - BASOP_SATURATE_WARNING_ON_EVS - diff_e = sub( a_e, b_e ); - - test(); - IF( diff_m == 0 && diff_e == 0 ) - { - return 0; - } - - /* Check sign, exponent and mantissa to identify, whether a is greater b or not */ - result = -1; - move16(); - - IF( a_m >= 0 ) - { - /* a is positive */ - if ( b_m < 0 ) - { - result = 1; - move16(); - } - - test(); - test(); - test(); - if ( ( b_m >= 0 ) && ( ( diff_e > 0 ) || ( diff_e == 0 && diff_m > 0 ) ) ) - { - result = 1; - move16(); - } - } - ELSE - { - /* a is negative */ - test(); - test(); - test(); - if ( ( b_m < 0 ) && ( ( diff_e < 0 ) || ( diff_e == 0 && diff_m > 0 ) ) ) - { - result = 1; - move16(); - } - } - return result; -} - /*------------------------------------------------------------------------- * ivas_dirac_dec_onset_detection_open() @@ -247,31 +141,22 @@ void ivas_dirac_dec_onset_detection_process_fx( move32(); } - IF( *p_onset_detector_1_fx == 0 ) + if ( *p_onset_detector_1_fx == 0 ) { - *p_onset_detector_1_fx = L_add( *p_onset_detector_1_fx, EPSILON_FX ); /* Q(q_onset_detector) */ + *p_onset_detector_1_fx = EPSILON_FX; /* Q(q_onset_detector) */ move32(); } /*onset filter limited between 0 and 1*/ tmp_fx = BASOP_Util_Divide3232_Scale( *p_onset_detector_2_fx, *p_onset_detector_1_fx, &e_scale ); - tmp32_fx = L_mult0( tmp_fx, DIRAC_ONSET_GAIN_FX ); + tmp32_fx = L_mult0( tmp_fx, DIRAC_ONSET_GAIN_FX ); // Q= Q12 + (15-e_scale) if ( tmp32_fx < 0 ) { tmp32_fx = 0; move32(); } - Word16 comp_flag = BASOP_Util_Cmp_Mant32Exp_sat( tmp32_fx, add( e_scale, 4 ), ONE_IN_Q30, 1 ); - test(); - IF( EQ_16( comp_flag, 1 ) || comp_flag == 0 ) - { - tmp32_fx = ONE_IN_Q31; - move32(); - } - ELSE - { - tmp32_fx = L_shl( tmp32_fx, add( e_scale, 4 ) ); - } + tmp32_fx = L_shl_sat( tmp32_fx, add( e_scale, 4 ) ); + onset_filter[b] = tmp32_fx; move32(); diff --git a/lib_rend/ivas_dirac_output_synthesis_dec.c b/lib_rend/ivas_dirac_output_synthesis_dec_fx.c similarity index 95% rename from lib_rend/ivas_dirac_output_synthesis_dec.c rename to lib_rend/ivas_dirac_output_synthesis_dec_fx.c index 54ff2943952f2381af341ff2f5b00a6340647759..6cf11887e247d3145595ff8c24455f75a7cf10f9 100644 --- a/lib_rend/ivas_dirac_output_synthesis_dec.c +++ b/lib_rend/ivas_dirac_output_synthesis_dec_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other @@ -35,15 +35,13 @@ #include "options.h" #include #include "cnst.h" -#include "prot.h" -#include "ivas_prot.h" -#include "ivas_prot_rend.h" +#include "prot_fx.h" +#include "ivas_prot_rend_fx.h" #include "ivas_stat_dec.h" #include "ivas_cnst.h" #include "ivas_rom_com.h" #include "ivas_rom_dec.h" #include "wmc_auto.h" -#include "prot_fx.h" /* Function prototypes */ #include "ivas_prot_fx.h" #include "ivas_rom_com_fx.h" @@ -823,6 +821,7 @@ void ivas_dirac_dec_output_synthesis_process_slot_fx( Word32 sqr_inp, sqr; /*Directonal sound gain nrg compensation*/ + c = L_add( ONE_IN_Q29 /*1 Q29*/, Mpy_32_16_1( L_sub( h_dirac_output_synthesis_params->diffuse_compensation_factor_decorr_fx, ONE_IN_Q29 /*1 Q29*/ ), 5461 /*1.0 / 6.0 Q15*/ ) ); /*Diffuseness modellling nrg compensation*/ /*Q29*/ FOR( k = 0; k < num_freq_bands_diff; k++ ) { a = h_dirac_output_synthesis_state->direct_responses_fx[ch_idx * num_freq_bands + k]; // Q = h_dirac_output_synthesis_state->q_direct_responses @@ -838,15 +837,16 @@ void ivas_dirac_dec_output_synthesis_process_slot_fx( { IF( reference_power[k + ( ch_idx + 1 ) * num_freq_bands] == 0 ) { - b = BASOP_Util_Divide3232_Scale( reference_power[k + num_freq_bands], 232831 /* EPSILON in exp 63 */, &b_exp ); - b_exp = add( b_exp, sub( sub( 31, q_reference_power ), 63 ) ); + b = MAX_16; + move16(); + b_exp = 0; + move16(); } ELSE { b = BASOP_Util_Divide3232_Scale( reference_power[k + num_freq_bands], reference_power[k + ( ch_idx + 1 ) * num_freq_bands], &b_exp ); /*Q(15-b_exp)*/ } } - c = L_add( ONE_IN_Q29 /*1 Q29*/, Mpy_32_16_1( L_sub( h_dirac_output_synthesis_params->diffuse_compensation_factor_decorr_fx, ONE_IN_Q29 /*1 Q29*/ ), 5461 /*1.0 / 6.0 Q15*/ ) ); /*Diffuseness modellling nrg compensation*/ /*Q29*/ mpy_a_a_b = Mpy_32_32( a, Mpy_32_16_1( a, b ) ); // Q = (h_dirac_output_synthesis_state->q_direct_responses + (15 - b_exp) - 15) + (h_dirac_output_synthesis_state->q_direct_responses) - 31 mpy_diff_aab = Mpy_32_32( L_sub( L_shl( 1, q_diffuseness ), diffuseness[k] ), mpy_a_a_b ); // Q(q_diff_aab) = 2*(h_dirac_output_synthesis_state->q_direct_responses) - b_exp - 31 + q_diffuseness -31 @@ -903,6 +903,7 @@ void ivas_dirac_dec_output_synthesis_process_slot_fx( move16(); } } + c = Madd_32_16( ONE_IN_Q27 /*1 Q27*/, L_sub( h_dirac_output_synthesis_params->diffuse_compensation_factor_fx, ONE_IN_Q27 /*1 Q27*/ ), 5461 ); /*Diffuseness modellling nrg compensation*/ /* 1.0 / 6.0 = 5461 in Q15*/ /*Q27*/ FOR( ; k < num_freq_bands; k++ ) { a = h_dirac_output_synthesis_state->direct_responses_fx[ch_idx * num_freq_bands + k]; // Q = h_dirac_output_synthesis_state->q_direct_responses @@ -918,22 +919,23 @@ void ivas_dirac_dec_output_synthesis_process_slot_fx( { IF( reference_power[k + ( ch_idx + 1 ) * num_freq_bands] == 0 ) { - b = BASOP_Util_Divide3232_Scale( reference_power[k + num_freq_bands], 232831 /* EPSILON in exp 63 */, &b_exp ); - b_exp = add( b_exp, sub( sub( 31, q_reference_power ), 63 ) ); + b = MAX_16; + move16(); + b_exp = 0; + move16(); } ELSE { b = BASOP_Util_Divide3232_Scale( reference_power[k + num_freq_bands], reference_power[k + ( ch_idx + 1 ) * num_freq_bands], &b_exp ); /*q(15-b_exp)*/ } } - c = L_add( ONE_IN_Q29 /*1 Q29*/, Mpy_32_16_1( L_sub( h_dirac_output_synthesis_params->diffuse_compensation_factor_decorr_fx, ONE_IN_Q29 /*1 Q29*/ ), 5461 ) ); /*Diffuseness modellling nrg compensation*/ /* 1.0 / 6.0 = 5461 in Q15*/ /*Q29*/ mpy_a_a_b = Mpy_32_32( a, Mpy_32_16_1( a, b ) ); // Q = (h_dirac_output_synthesis_state->q_direct_responses + (15 - b_exp) - 15) + (h_dirac_output_synthesis_state->q_direct_responses) - 31 mpy_diff_aab = Mpy_32_32( L_sub( L_shl( 1, q_diffuseness ), diffuseness[k] ), mpy_a_a_b ); // Q = 2*(h_dirac_output_synthesis_state->q_direct_responses) - b_exp - 31 + q_diffuseness -31 - mpy_diff_c = Mpy_32_32( diffuseness[k], c ); // Q = q_diffuseness - 2 + mpy_diff_c = Mpy_32_32( diffuseness[k], c ); // Q = q_diffuseness - 4 q_diff_aab = add( h_dirac_output_synthesis_state->direct_responses_q + sub( sub( 15, b_exp ), 15 ), add( sub( h_dirac_output_synthesis_state->direct_responses_q, 31 ), sub( q_diffuseness, 31 ) ) ); - q_diff_c = sub( q_diffuseness, 2 ); + q_diff_c = sub( q_diffuseness, 4 ); test(); IF( mpy_diff_c != 0 && mpy_diff_aab != 0 ) @@ -1077,6 +1079,16 @@ void ivas_dirac_dec_output_synthesis_process_slot_fx( Word16 temp_q = sub( add( h_dirac_output_synthesis_state->direct_power_factor_q, h_dirac_output_synthesis_state->direct_responses_q ), 31 ); IF( LT_16( temp_q, h_dirac_output_synthesis_state->q_cy_cross_dir_smooth ) ) { +#ifdef FIX_1072_SPEEDUP_gainpanning /*is there any difference in any bitstream?*/ + Word16 temp_q1 = sub( temp_q, h_dirac_output_synthesis_state->q_cy_cross_dir_smooth ); + FOR( Word16 kk = 0; kk < tmp16; kk++ ) + { + h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx[kk] = L_shl( h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx[kk], temp_q1 ); /*h_dirac_output_synthesis_state->q_cy_cross_dir_smooth ->temp_q*/ + move32(); + } + h_dirac_output_synthesis_state->q_cy_cross_dir_smooth = temp_q; + move16(); +#else FOR( Word16 kk = 0; kk < tmp16; kk++ ) { h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx[kk] = L_shl( h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx[kk], sub( temp_q, h_dirac_output_synthesis_state->q_cy_cross_dir_smooth ) ); /*h_dirac_output_synthesis_state->q_cy_cross_dir_smooth ->temp_q*/ @@ -1084,7 +1096,53 @@ void ivas_dirac_dec_output_synthesis_process_slot_fx( } h_dirac_output_synthesis_state->q_cy_cross_dir_smooth = temp_q; move16(); +#endif } +#ifdef FIX_1072_SPEEDUP_gainpanning + Word16 temp_q1 = sub( h_dirac_output_synthesis_state->q_cy_cross_dir_smooth, temp_q ); + FOR( ch_idx = s_min( 4, nchan_transport ); ch_idx < num_channels_dir; ch_idx++ ) + { + IF( NE_16( temp_q, h_dirac_output_synthesis_state->q_cy_cross_dir_smooth ) ) + { + Word16 i; + Word32 aux; + IF( temp_q1 < 0 ) + { +#ifdef FIX_USAN_ISSUES + Word32 temp_q1_equiv = L_lshl( (Word32) 0x80000000, temp_q1 ); +#else + Word32 temp_q1_equiv = L_lshl( 0x80000000, temp_q1 ); +#endif + FOR( i = 0; i < num_freq_bands; i++ ) + { + aux = Mpy_32_32( h_dirac_output_synthesis_state->direct_power_factor_fx[i], h_dirac_output_synthesis_state->direct_responses_fx[ch_idx * num_freq_bands + i] ); + h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + i] = Madd_32_32( h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + i], aux, temp_q1_equiv ); + move32(); + } + } + ELSE + { + FOR( i = 0; i < num_freq_bands; i++ ) + { + aux = Mpy_32_32( h_dirac_output_synthesis_state->direct_power_factor_fx[i], h_dirac_output_synthesis_state->direct_responses_fx[ch_idx * num_freq_bands + i] ); + aux = L_shl( aux, temp_q1 ); + h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + i] = L_add( h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + i], aux ); + move32(); + } + } + } + ELSE + { + Word16 i; + FOR( i = 0; i < num_freq_bands; i++ ) + { + h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + i] = Madd_32_32( h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + i], h_dirac_output_synthesis_state->direct_power_factor_fx[i], h_dirac_output_synthesis_state->direct_responses_fx[ch_idx * num_freq_bands + i] ); + move32(); + } + } + } + +#else FOR( ch_idx = s_min( 4, nchan_transport ); ch_idx < num_channels_dir; ch_idx++ ) { v_mult_fixed( h_dirac_output_synthesis_state->direct_power_factor_fx, @@ -1102,6 +1160,7 @@ void ivas_dirac_dec_output_synthesis_process_slot_fx( &h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx[ch_idx * num_freq_bands], num_freq_bands, 0 ); /*Q(h_dirac_output_synthesis_state->q_cy_cross_dir_smooth)*/ } +#endif /*Diffuse gain*/ FOR( ch_idx = s_min( 4, nchan_transport ); ch_idx < num_channels_diff; ch_idx++ ) @@ -1195,7 +1254,7 @@ void ivas_dirac_dec_output_synthesis_process_subframe_gain_shd_fx( Word16 buf_idx, ch_idx, i, l; Word16 num_freq_bands, num_freq_bands_diff; Word16 num_channels_dir, num_channels_diff; - Word32 g, g1, g2; + Word32 g, g1[MAX_FREQUENCY_BANDS], g2; Word32 *p_gains_dir, *p_gains_diff; Word32 *p_gains_dir_prev, *p_gains_diff_prev; Word32 *p_cy_cross_dir_smooth; @@ -1209,12 +1268,14 @@ void ivas_dirac_dec_output_synthesis_process_subframe_gain_shd_fx( DIRAC_OUTPUT_SYNTHESIS_STATE h_dirac_output_synthesis_state; Word16 nchan_transport_foa; Word16 ch_idx_diff; + Word32 cmp1, cmp2; Word32 aux_buf[CLDFB_NO_CHANNELS_MAX]; Word32 ratio_float[DIRAC_HO_NUMSECTORS * CLDFB_NO_CHANNELS_MAX]; Word16 q_com = 0; move16(); Word16 exp = 0; move16(); + Word16 q_shift; /* collect some often used parameters */ h_dirac_output_synthesis_params = hDirACRend->h_output_synthesis_psd_params; @@ -1234,6 +1295,7 @@ void ivas_dirac_dec_output_synthesis_process_subframe_gain_shd_fx( nchan_transport_foa = s_min( 4, nchan_transport ); move16(); + Word16 prod = imult1616( num_freq_bands, num_channels_dir ); /*-----------------------------------------------------------------* * comput target Gains *-----------------------------------------------------------------*/ @@ -1401,6 +1463,7 @@ void ivas_dirac_dec_output_synthesis_process_subframe_gain_shd_fx( move16(); /*Diffuse gain*/ + q_com = s_min( h_dirac_output_synthesis_state.q_cy_auto_diff_smooth_prev, Q31 ); FOR( ch_idx = nchan_transport_foa; ch_idx < num_channels_diff; ch_idx++ ) { v_multc_fixed_16( h_dirac_output_synthesis_state.diffuse_power_factor_fx, // Q31 @@ -1409,7 +1472,6 @@ void ivas_dirac_dec_output_synthesis_process_subframe_gain_shd_fx( num_freq_bands_diff ); // Scale to bring in common Q-factor - q_com = s_min( h_dirac_output_synthesis_state.q_cy_auto_diff_smooth_prev, Q31 ); Scale_sig32( &h_dirac_output_synthesis_state.cy_auto_diff_smooth_fx[ch_idx * num_freq_bands_diff], num_freq_bands_diff, sub( q_com, Q31 ) ); /*q31->q_com*/ @@ -1431,59 +1493,71 @@ void ivas_dirac_dec_output_synthesis_process_subframe_gain_shd_fx( p_cy_cross_dir_smooth = h_dirac_output_synthesis_state.cy_cross_dir_smooth_fx; p_gains_dir = h_dirac_output_synthesis_state.cy_cross_dir_smooth_prev_fx; + FOR( l = 0; l < num_freq_bands; l++ ) + { + g1[l] = Madd_32_32( POINT_3679_Q31, onset_filter[l], POINT_1175_Q31 - POINT_3679_Q31 ); // Q31, (Q31, Q31) -> Q31 + move32(); + } + + q_shift = sub( 26, h_dirac_output_synthesis_state.q_cy_cross_dir_smooth_prev ); + move16(); + /* Direct gains */ IF( hodirac_flag ) { + cmp1 = L_shr( 66437775 /* 0.99f in Q26 */, q_shift ); + cmp2 = L_shr( ONE_IN_Q27 /* 2.0f in Q26 */, q_shift ); FOR( ch_idx = 0; ch_idx < nchan_transport_foa; ch_idx++ ) { FOR( l = 0; l < num_freq_bands; l++ ) { - g1 = Madd_32_32( POINT_3679_Q31, onset_filter[l], POINT_1175_Q31 - POINT_3679_Q31 ); // Q31, (Q31, Q31) -> Q31 - g2 = Mpy_32_32( L_sub( ONE_IN_Q31, g1 ), *( p_gains_dir ) ); // (Q31, p_gains_dir_q) -> p_gains_dir_q - g2 = L_add_sat( g2, Mpy_32_32( g1, ( *( p_cy_cross_dir_smooth++ ) ) ) ); // p_gains_diff_q, (Q31, p_gains_diff_q) -> p_gains_diff_q - g2 = L_max( g2, Mpy_32_32( 2126008812 /* 0.99f in Q31 */, L_shl( 1, h_dirac_output_synthesis_state.q_cy_cross_dir_smooth_prev ) ) ); // p_gains_dir_q - g2 = L_min( g2, Mpy_32_32( ONE_IN_Q31 /* 2.0f in Q30 */, L_shl( 1, add( h_dirac_output_synthesis_state.q_cy_cross_dir_smooth_prev, 1 ) ) ) ); // p_gains_dir_q - *( p_gains_dir++ ) = g2; // p_gains_dir_q + g2 = Mpy_32_32( L_sub( ONE_IN_Q31, g1[l] ), *( p_gains_dir ) ); // (Q31, p_gains_dir_q) -> p_gains_dir_q + g2 = L_add_sat( g2, Mpy_32_32( g1[l], ( *( p_cy_cross_dir_smooth++ ) ) ) ); // p_gains_diff_q, (Q31, p_gains_diff_q) -> p_gains_diff_q + g2 = L_max( g2, cmp1 ); // p_gains_dir_q + g2 = L_min( g2, cmp2 ); // p_gains_dir_q + *( p_gains_dir++ ) = g2; // p_gains_dir_q move32(); } } } ELSE { + cmp1 = L_shr( 57042534 /* 0.85f in Q26 */, q_shift ); + cmp2 = L_shr( 77175193 /* 1.15f in Q26 */, q_shift ); FOR( ch_idx = 0; ch_idx < nchan_transport_foa; ch_idx++ ) { FOR( l = 0; l < num_freq_bands; l++ ) { - g1 = Madd_32_32( POINT_3679_Q31, onset_filter[l], POINT_1175_Q31 - POINT_3679_Q31 ); // Q31, (Q31, Q31) -> Q31 - g2 = Mpy_32_32( L_sub( ONE_IN_Q31, g1 ), *( p_gains_dir ) ); // (Q31, p_gains_dir_q) -> p_gains_dir_q - g2 = L_add_sat( g2, Mpy_32_32( g1, ( *( p_cy_cross_dir_smooth++ ) ) ) ); // p_gains_diff_q, (Q31, p_gains_diff_q) -> p_gains_diff_q - g2 = L_max( g2, Mpy_32_32( 1825361101 /* 0.85f in Q31 */, L_shl( 1, h_dirac_output_synthesis_state.q_cy_cross_dir_smooth_prev ) ) ); // p_gains_dir_q - g2 = L_min( g2, Mpy_32_32( 1234803098 /* 1.15f in Q30 */, L_shl( 1, add( h_dirac_output_synthesis_state.q_cy_cross_dir_smooth_prev, 1 ) ) ) ); // p_gains_dir_q - *( p_gains_dir++ ) = g2; // p_gains_dir_q + g2 = Mpy_32_32( L_sub( ONE_IN_Q31, g1[l] ), *( p_gains_dir ) ); // (Q31, p_gains_dir_q) -> p_gains_dir_q + g2 = L_add_sat( g2, Mpy_32_32( g1[l], ( *( p_cy_cross_dir_smooth++ ) ) ) ); // p_gains_diff_q, (Q31, p_gains_diff_q) -> p_gains_diff_q + g2 = L_max( g2, cmp1 ); // p_gains_dir_q + g2 = L_min( g2, cmp2 ); // p_gains_dir_q + *( p_gains_dir++ ) = g2; // p_gains_dir_q move32(); } } } /*Directional gains*/ + cmp1 = L_shr( -DIRAC_GAIN_LIMIT_Q26, q_shift ); + cmp2 = L_negate( cmp1 ); FOR( ch_idx = nchan_transport_foa; ch_idx < num_channels_dir; ch_idx++ ) { FOR( l = 0; l < num_freq_bands; l++ ) { - g1 = Madd_32_32( POINT_3679_Q31, onset_filter[l], POINT_1175_Q31 - POINT_3679_Q31 ); // Q31, (Q31, Q31) -> Q31 - g2 = Mpy_32_32( L_sub( ONE_IN_Q31, g1 ), *( p_gains_dir ) ); // (Q31, p_gains_dir_q) -> p_gains_dir_q - g2 = L_add_sat( g2, Mpy_32_32( g1, ( *( p_cy_cross_dir_smooth++ ) ) ) ); // p_gains_diff_q, (Q31, p_gains_diff_q) -> p_gains_diff_q - g2 = L_max( g2, W_extract_h( W_shl( W_mult_32_32( -DIRAC_GAIN_LIMIT_Q26, L_shl( 1, h_dirac_output_synthesis_state.q_cy_cross_dir_smooth_prev ) ), Q5 ) ) ); // p_gains_dir_q - g2 = L_min( g2, W_extract_h( W_shl( W_mult_32_32( DIRAC_GAIN_LIMIT_Q26, L_shl( 1, h_dirac_output_synthesis_state.q_cy_cross_dir_smooth_prev ) ), Q5 ) ) ); // p_gains_dir_q - *( p_gains_dir++ ) = g2; // p_gains_dir_q + g2 = Mpy_32_32( L_sub( ONE_IN_Q31, g1[l] ), *( p_gains_dir ) ); // (Q31, p_gains_dir_q) -> p_gains_dir_q + g2 = L_add_sat( g2, Mpy_32_32( g1[l], ( *( p_cy_cross_dir_smooth++ ) ) ) ); // p_gains_diff_q, (Q31, p_gains_diff_q) -> p_gains_diff_q + g2 = L_max( g2, cmp1 ); // p_gains_dir_q + g2 = L_min( g2, cmp2 ); // p_gains_dir_q + *( p_gains_dir++ ) = g2; // p_gains_dir_q move32(); } } IF( hodirac_flag ) { - p_cy_cross_dir_smooth = h_dirac_output_synthesis_state.cy_cross_dir_smooth_fx + imult1616( num_freq_bands, num_channels_dir ); - p_gains_dir = h_dirac_output_synthesis_state.cy_cross_dir_smooth_prev_fx + imult1616( num_freq_bands, num_channels_dir ); + p_cy_cross_dir_smooth = h_dirac_output_synthesis_state.cy_cross_dir_smooth_fx + prod; + p_gains_dir = h_dirac_output_synthesis_state.cy_cross_dir_smooth_prev_fx + prod; /*Direct gains*/ FOR( ch_idx = 0; ch_idx < nchan_transport_foa; ch_idx++ ) @@ -1500,12 +1574,11 @@ void ivas_dirac_dec_output_synthesis_process_subframe_gain_shd_fx( { FOR( l = 0; l < num_freq_bands; l++ ) { - g1 = Madd_32_32( POINT_3679_Q31, onset_filter[l], POINT_1175_Q31 - POINT_3679_Q31 ); // Q31, (Q31, Q31) -> Q31 - g2 = Mpy_32_32( L_sub( ONE_IN_Q31, g1 ), *( p_gains_dir ) ); // (Q31, p_gains_dir_q) -> p_gains_dir_q - g2 = L_add_sat( g2, Mpy_32_32( g1, ( *( p_cy_cross_dir_smooth++ ) ) ) ); // (p_gains_diff_q, (Q31, p_gains_diff_q) -> p_gains_diff_q - g2 = L_max( g2, W_extract_h( W_shl( W_mult_32_32( -DIRAC_GAIN_LIMIT_Q26, L_shl( 1, h_dirac_output_synthesis_state.q_cy_cross_dir_smooth_prev ) ), Q5 ) ) ); // p_gains_dir_q - g2 = L_min( g2, W_extract_h( W_shl( W_mult_32_32( DIRAC_GAIN_LIMIT_Q26, L_shl( 1, h_dirac_output_synthesis_state.q_cy_cross_dir_smooth_prev ) ), Q5 ) ) ); // p_gains_dir_q - *( p_gains_dir++ ) = g2; // p_gains_dir_q + g2 = Mpy_32_32( L_sub( ONE_IN_Q31, g1[l] ), *( p_gains_dir ) ); // (Q31, p_gains_dir_q) -> p_gains_dir_q + g2 = L_add_sat( g2, Mpy_32_32( g1[l], ( *( p_cy_cross_dir_smooth++ ) ) ) ); // (p_gains_diff_q, (Q31, p_gains_diff_q) -> p_gains_diff_q + g2 = L_max( g2, cmp1 ); // p_gains_dir_q + g2 = L_min( g2, cmp2 ); // p_gains_dir_q + *( p_gains_dir++ ) = g2; // p_gains_dir_q move32(); } } @@ -1514,17 +1587,18 @@ void ivas_dirac_dec_output_synthesis_process_subframe_gain_shd_fx( /*Diffuse gains*/ p_cy_auto_diff_smooth = h_dirac_output_synthesis_state.cy_auto_diff_smooth_fx + imult1616( nchan_transport_foa, num_freq_bands_diff ); p_gains_diff = h_dirac_output_synthesis_state.cy_auto_diff_smooth_prev_fx + imult1616( nchan_transport_foa, num_freq_bands_diff ); + g1[0] = POINT_1175_Q31; // Q31 + move32(); FOR( ch_idx = nchan_transport_foa; ch_idx < num_channels_diff; ch_idx++ ) { FOR( l = 0; l < num_freq_bands_diff; l++ ) { - g1 = POINT_1175_Q31; // Q31 move32(); - g2 = Mpy_32_32( L_sub( ONE_IN_Q31, g1 ), *( p_gains_diff ) ); // (Q31, p_gains_dir_q) -> p_gains_dir_q - g2 = L_add_sat( g2, Mpy_32_32( g1, ( *( p_cy_auto_diff_smooth++ ) ) ) ); // p_gains_diff_q, (Q31, p_gains_diff_q) -> p_gains_diff_q - g2 = L_max( g2, 0 ); // p_gains_diff_q - g2 = L_min( g2, W_extract_h( W_shl( W_mult_32_32( DIRAC_GAIN_LIMIT_Q26, L_shl( 1, h_dirac_output_synthesis_state.q_cy_auto_diff_smooth_prev ) ), Q5 ) ) ); // p_gains_diff_q - *( p_gains_diff++ ) = g2; // p_gains_diff_q + g2 = Mpy_32_32( L_sub( ONE_IN_Q31, g1[0] ), *( p_gains_diff ) ); // (Q31, p_gains_dir_q) -> p_gains_dir_q + g2 = L_add_sat( g2, Mpy_32_32( g1[0], ( *( p_cy_auto_diff_smooth++ ) ) ) ); // p_gains_diff_q, (Q31, p_gains_diff_q) -> p_gains_diff_q + g2 = L_max( g2, 0 ); // p_gains_diff_q + g2 = L_min( g2, cmp2 ); // p_gains_diff_q + *( p_gains_diff++ ) = g2; // p_gains_diff_q move32(); } } @@ -1535,8 +1609,9 @@ void ivas_dirac_dec_output_synthesis_process_subframe_gain_shd_fx( FOR( buf_idx = 0; buf_idx < nbslots; ++buf_idx ) { - g1 = L_deposit_h( h_dirac_output_synthesis_params.interpolator_fx[buf_idx] ); // Q31 - g2 = L_sub( ONE_IN_Q31, g1 ); // Q31 + g1[0] = L_deposit_h( h_dirac_output_synthesis_params.interpolator_fx[buf_idx] ); // Q31 + move32(); + g2 = L_sub( ONE_IN_Q31, g1[0] ); // Q31 /*Direct input->output*/ p_gains_dir = h_dirac_output_synthesis_state.cy_cross_dir_smooth_prev_fx; // (p_gains_dir_q) @@ -1557,7 +1632,7 @@ void ivas_dirac_dec_output_synthesis_process_subframe_gain_shd_fx( shl( ch_idx * num_freq_bands, Q1 ); FOR( l = 0; l < num_freq_bands; l++ ) { - g = Madd_32_32( Mpy_32_32( g1, ( *( p_gains_dir++ ) ) ), g2, ( *( p_gains_dir_prev++ ) ) ); // (Q31, p_gains_dir_q) -> (p_gains_dir_q) + g = Madd_32_32( Mpy_32_32( g1[0], ( *( p_gains_dir++ ) ) ), g2, ( *( p_gains_dir_prev++ ) ) ); // (Q31, p_gains_dir_q) -> (p_gains_dir_q) output_real[l * num_channels_dir + ch_idx] = Mpy_32_32( g, ( *( p_proto_diff++ ) ) ); // (p_gains_dir_q, p_proto_diff_q) -> (p_gains_dir_q + p_proto_diff_q - 31) move32(); @@ -1583,25 +1658,31 @@ void ivas_dirac_dec_output_synthesis_process_subframe_gain_shd_fx( shl( i_mult( proto_direct_index[1], num_freq_bands ), Q1 ); FOR( l = 0; l < num_freq_bands; l++ ) { - gs1 = Madd_32_32( Mpy_32_32( g1, ( *( p_gains_dir ) ) ), g2, ( *( p_gains_dir_prev ) ) ); // (Q31, p_gains_dir_q) -> (p_gains_dir_q) - gs2 = Madd_32_32( Mpy_32_32( g1, ( *( p_gains_dir + imult1616( num_freq_bands, num_channels_dir ) ) ) ), g2, ( *( p_gains_dir_prev + imult1616( num_freq_bands, num_channels_dir ) ) ) ); // (Q31, p_gains_dir_q) -> (p_gains_dir_q) + + Word32 temp1, temp2; + gs1 = Madd_32_32( Mpy_32_32( g1[0], ( *( p_gains_dir ) ) ), g2, ( *( p_gains_dir_prev ) ) ); // (Q31, p_gains_dir_q) -> (p_gains_dir_q) + gs2 = Madd_32_32( Mpy_32_32( g1[0], ( *( p_gains_dir + prod ) ) ), g2, ( *( p_gains_dir_prev + prod ) ) ); // (Q31, p_gains_dir_q) -> (p_gains_dir_q) p_gains_dir++; p_gains_dir_prev++; + temp1 = Mpy_32_32( 1903158016 /* 1.772454e+00f / 2 in Q31 */, ( *p_proto ) ); + temp2 = Mpy_32_32( 1098788992 /* 1.023327e+00f / 2 in Q31 */, ( *p_proto2 ) ); // ((p_gains_dir_q, p_proto_dir_q) >> 1) -> (p_gains_dir_q + p_proto_dir_q - 31) output_real[l * num_channels_dir + ch_idx] = Madd_32_32( - Mpy_32_32( gs1, ( L_add( Mpy_32_32( 1903158016 /* 1.772454e+00f / 2 in Q31 */, ( *p_proto ) ), Mpy_32_32( 1098788992 /* 1.023327e+00f / 2 in Q31 */, ( *p_proto2 ) ) ) ) ), /* s1 */ - gs2, L_sub( Mpy_32_32( 1903158016 /* 1.772454e+00f / 2 in Q31 */, ( *p_proto ) ), Mpy_32_32( 1098788992 /* 1.023327e+00f / 2 in Q31 */, ( *p_proto2 ) ) ) ); /* s2 */ + Mpy_32_32( gs1, ( L_add( temp1, temp2 ) ) ), /* s1 */ + gs2, L_sub( temp1, temp2 ) ); /* s2 */ move32(); p_proto++; p_proto2++; + temp1 = Mpy_32_32( 1903158016 /* 1.772454e+00f / 2 in Q31 */, ( *p_proto ) ); + temp2 = Mpy_32_32( 1098788992 /* 1.023327e+00f / 2 in Q31 */, ( *p_proto2 ) ); // ((p_gains_dir_q, p_proto_dir_q) >> 1) -> (p_gains_dir_q + p_proto_dir_q - 31) output_imag[l * num_channels_dir + ch_idx] = Madd_32_32( - Mpy_32_32( gs1, ( L_add( Mpy_32_32( 1903158016 /* 1.772454e+00f / 2 in Q31 */, ( *p_proto ) ), Mpy_32_32( 1098788992 /* 1.023327e+00f / 2 in Q31 */, ( *p_proto2 ) ) ) ) ), - gs2, L_sub( Mpy_32_32( 1903158016 /* 1.772454e+00f / 2 in Q31 */, ( *p_proto ) ), Mpy_32_32( 1098788992 /* 1.023327e+00f / 2 in Q31 */, ( *p_proto2 ) ) ) ); + Mpy_32_32( gs1, ( L_add( temp1, temp2 ) ) ), + gs2, L_sub( temp1, temp2 ) ); move32(); p_proto++; p_proto2++; @@ -1612,14 +1693,15 @@ void ivas_dirac_dec_output_synthesis_process_subframe_gain_shd_fx( p_proto = h_dirac_output_synthesis_state.proto_direct_buffer_f_fx + shl( i_mult( buf_idx, i_mult( num_freq_bands, num_protos_dir ) ), Q1 ) + shl( i_mult( proto_direct_index[ch_idx], num_freq_bands ), Q1 ); + Word16 diff = sub( h_dirac_output_synthesis_state.q_cy_cross_dir_smooth_prev, 31 ); FOR( l = 0; l < num_freq_bands; l++ ) { p_gains_dir++; p_gains_dir_prev++; - output_real[l * num_channels_dir + ch_idx] = L_shl( *( p_proto++ ), sub( h_dirac_output_synthesis_state.q_cy_cross_dir_smooth_prev, 31 ) ); // p_proto_dir_q -> (p_gains_dir_q + p_proto_dir_q - 31) + output_real[l * num_channels_dir + ch_idx] = L_shl( *( p_proto++ ), diff ); // p_proto_dir_q -> (p_gains_dir_q + p_proto_dir_q - 31) move32(); - output_imag[l * num_channels_dir + ch_idx] = L_shl( *( p_proto++ ), sub( h_dirac_output_synthesis_state.q_cy_cross_dir_smooth_prev, 31 ) ); // p_proto_dir_q -> (p_gains_dir_q + p_proto_dir_q - 31) + output_imag[l * num_channels_dir + ch_idx] = L_shl( *( p_proto++ ), diff ); // p_proto_dir_q -> (p_gains_dir_q + p_proto_dir_q - 31) move32(); } } @@ -1633,7 +1715,7 @@ void ivas_dirac_dec_output_synthesis_process_subframe_gain_shd_fx( { FOR( l = 0; l < num_freq_bands; l++ ) { - g = Madd_32_32( Mpy_32_32( g1, ( *( p_gains_dir++ ) ) ), g2, ( *( p_gains_dir_prev++ ) ) ); // (Q31, p_gains_dir_q) -> (p_gains_dir_q) + g = Madd_32_32( Mpy_32_32( g1[0], ( *( p_gains_dir++ ) ) ), g2, ( *( p_gains_dir_prev++ ) ) ); // (Q31, p_gains_dir_q) -> (p_gains_dir_q) output_real[l * num_channels_dir + ch_idx] = Mpy_32_32( g, ( *( p_proto++ ) ) ); // (p_gains_dir_q, p_proto_dir_q) -> (p_gains_dir_q + p_proto_dir_q - 31) move32(); @@ -1643,14 +1725,15 @@ void ivas_dirac_dec_output_synthesis_process_subframe_gain_shd_fx( } ELSE { + Word16 shift_q = sub( h_dirac_output_synthesis_state.q_cy_cross_dir_smooth_prev, 31 ); FOR( l = 0; l < num_freq_bands; l++ ) { p_gains_dir++; p_gains_dir_prev++; - output_real[l * num_channels_dir + ch_idx] = L_shl( *( p_proto++ ), sub( h_dirac_output_synthesis_state.q_cy_cross_dir_smooth_prev, 31 ) ); // p_proto_dir_q -> (p_gains_dir_q + p_proto_dir_q - 31) + output_real[l * num_channels_dir + ch_idx] = L_shl( *( p_proto++ ), shift_q ); // p_proto_dir_q -> (p_gains_dir_q + p_proto_dir_q - 31) move32(); - output_imag[l * num_channels_dir + ch_idx] = L_shl( *( p_proto++ ), sub( h_dirac_output_synthesis_state.q_cy_cross_dir_smooth_prev, 31 ) ); // p_proto_dir_q -> (p_gains_dir_q + p_proto_dir_q - 31) + output_imag[l * num_channels_dir + ch_idx] = L_shl( *( p_proto++ ), shift_q ); // p_proto_dir_q -> (p_gains_dir_q + p_proto_dir_q - 31) move32(); } } @@ -1681,7 +1764,7 @@ void ivas_dirac_dec_output_synthesis_process_subframe_gain_shd_fx( ch_idx_diff = add( ch_idx_diff, 1 ); FOR( l = 0; l < num_freq_bands_diff; l++ ) { - g = Madd_32_32( Mpy_32_32( g1, ( *( p_gains_diff++ ) ) ), g2, ( *( p_gains_diff_prev++ ) ) ); // (Q31, p_gains_diff_q) -> p_gains_diff_q + g = Madd_32_32( Mpy_32_32( g1[0], ( *( p_gains_diff++ ) ) ), g2, ( *( p_gains_diff_prev++ ) ) ); // (Q31, p_gains_diff_q) -> p_gains_diff_q // ((p_gains_diff_q, p_proto_diff_q) >> Q1) -> (p_gains_diff_q + p_proto_diff_q - 31) output_real[l * num_channels_dir + hDirACRend->sba_map_tc[ch_idx]] = @@ -1765,11 +1848,11 @@ void ivas_dirac_dec_output_synthesis_process_subframe_gain_shd_fx( /* store estimates for next synthesis block */ IF( hodirac_flag ) { - Copy32( h_dirac_output_synthesis_state.cy_cross_dir_smooth_prev_fx, h_dirac_output_synthesis_state.gains_dir_prev_fx, imult1616( num_freq_bands, num_channels_dir ) * DIRAC_HO_NUMSECTORS ); /*h_dirac_output_synthesis_state.q_cy_cross_dir_smooth_prev*/ + Copy32( h_dirac_output_synthesis_state.cy_cross_dir_smooth_prev_fx, h_dirac_output_synthesis_state.gains_dir_prev_fx, prod * DIRAC_HO_NUMSECTORS ); /*h_dirac_output_synthesis_state.q_cy_cross_dir_smooth_prev*/ } ELSE { - Copy32( h_dirac_output_synthesis_state.cy_cross_dir_smooth_prev_fx, h_dirac_output_synthesis_state.gains_dir_prev_fx, imult1616( num_freq_bands, num_channels_dir ) ); /*h_dirac_output_synthesis_state.q_cy_cross_dir_smooth_prev*/ + Copy32( h_dirac_output_synthesis_state.cy_cross_dir_smooth_prev_fx, h_dirac_output_synthesis_state.gains_dir_prev_fx, prod ); /*h_dirac_output_synthesis_state.q_cy_cross_dir_smooth_prev*/ } *q_cy_cross_dir_smooth_prev = h_dirac_output_synthesis_state.q_cy_cross_dir_smooth_prev; move16(); @@ -1781,11 +1864,11 @@ void ivas_dirac_dec_output_synthesis_process_subframe_gain_shd_fx( /* reset values */ IF( hodirac_flag ) { - set_zero_fx( h_dirac_output_synthesis_state.cy_cross_dir_smooth_fx, imult1616( num_freq_bands, num_channels_dir ) * DIRAC_HO_NUMSECTORS ); + set_zero_fx( h_dirac_output_synthesis_state.cy_cross_dir_smooth_fx, prod * DIRAC_HO_NUMSECTORS ); } ELSE { - set_zero_fx( h_dirac_output_synthesis_state.cy_cross_dir_smooth_fx, imult1616( num_freq_bands, num_channels_dir ) ); + set_zero_fx( h_dirac_output_synthesis_state.cy_cross_dir_smooth_fx, prod ); } set_zero_fx( h_dirac_output_synthesis_state.cy_auto_diff_smooth_fx, imult1616( num_freq_bands_diff, num_channels_diff ) ); diff --git a/lib_rend/ivas_dirac_rend.c b/lib_rend/ivas_dirac_rend_fx.c similarity index 97% rename from lib_rend/ivas_dirac_rend.c rename to lib_rend/ivas_dirac_rend_fx.c index 1982862bfba0627955807d33f96e4beae4eab510..031a398559667c2aa3cf1bc56a6390463e556889 100644 --- a/lib_rend/ivas_dirac_rend.c +++ b/lib_rend/ivas_dirac_rend_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other @@ -35,13 +35,11 @@ #include "options.h" #include #include "cnst.h" -#include "prot.h" -#include "ivas_prot.h" -#include "ivas_prot_rend.h" +#include "prot_fx.h" +#include "ivas_prot_rend_fx.h" #include "ivas_cnst.h" #include "ivas_rom_rend.h" #include "wmc_auto.h" -#include "prot_fx.h" #include "ivas_prot_fx.h" #include "ivas_rom_binaural_crend_head.h" @@ -873,6 +871,8 @@ ivas_error ivas_dirac_alloc_mem_fx( } hDirACRend->h_output_synthesis_psd_state.proto_direct_buffer_f_len = imult1616( imult1616( 2 * MAX_PARAM_SPATIAL_SUBFRAMES, num_protos_dir ), num_freq_bands ); move16(); + hDirACRend->h_output_synthesis_psd_state.proto_direct_buffer_f_q = Q31; + move16(); IF( hDirACRend->proto_signal_decorr_on ) { @@ -1444,15 +1444,15 @@ void protoSignalComputation_shd_fx( reference_power_fx[l] = L_shr( reference_power_fx[l + num_freq_bands], 1 ); /*2*Q(q_cldfb+min_q_shift)-31-1*/ move32(); + re1 = L_shl( RealBuffer_fx[1][0][l], min_q_shift ); /*Q(q_cldfb+min_q_shift)*/ + re2 = L_shl( RealBuffer_fx[2][0][l], min_q_shift ); /*Q(q_cldfb+min_q_shift)*/ + re3 = L_shl( RealBuffer_fx[3][0][l], min_q_shift ); /*Q(q_cldfb+min_q_shift)*/ + im1 = L_shl( ImagBuffer_fx[1][0][l], min_q_shift ); /*Q(q_cldfb+min_q_shift)*/ + im2 = L_shl( ImagBuffer_fx[2][0][l], min_q_shift ); /*Q(q_cldfb+min_q_shift)*/ + im3 = L_shl( ImagBuffer_fx[3][0][l], min_q_shift ); /*Q(q_cldfb+min_q_shift)*/ + FOR( k = 1; k < 4; k++ ) { - re1 = L_shl( RealBuffer_fx[1][0][l], min_q_shift ); /*Q(q_cldfb+min_q_shift)*/ - re2 = L_shl( RealBuffer_fx[2][0][l], min_q_shift ); /*Q(q_cldfb+min_q_shift)*/ - re3 = L_shl( RealBuffer_fx[3][0][l], min_q_shift ); /*Q(q_cldfb+min_q_shift)*/ - im1 = L_shl( ImagBuffer_fx[1][0][l], min_q_shift ); /*Q(q_cldfb+min_q_shift)*/ - im2 = L_shl( ImagBuffer_fx[2][0][l], min_q_shift ); /*Q(q_cldfb+min_q_shift)*/ - im3 = L_shl( ImagBuffer_fx[3][0][l], min_q_shift ); /*Q(q_cldfb+min_q_shift)*/ - idx = i_mult( 3, Rmat_k[k] ); idx1 = add( l, i_mult( add( k, 1 ), num_freq_bands ) ); @@ -1477,13 +1477,16 @@ void protoSignalComputation_shd_fx( } *proto_direct_buffer_f_q = add( q_cldfb, min_q_shift ); + move16(); *reference_power_q = sub( add( *proto_direct_buffer_f_q, *proto_direct_buffer_f_q ), 31 ); + move16(); + Word16 shift = sub( *proto_direct_buffer_f_q, q_cldfb ); FOR( k = 1; k < 4; k++ ) { - RealBuffer_fx[k][0][l] = L_shr( p_proto_direct_buffer_fx[2 * ( k * num_freq_bands + l )], sub( *proto_direct_buffer_f_q, q_cldfb ) ); // proto_direct_buffer_f_q -> q_cldfb + RealBuffer_fx[k][0][l] = L_shr( p_proto_direct_buffer_fx[2 * ( k * num_freq_bands + l )], shift ); // proto_direct_buffer_f_q -> q_cldfb move32(); - ImagBuffer_fx[k][0][l] = L_shr( p_proto_direct_buffer_fx[2 * ( k * num_freq_bands + l ) + 1], sub( *proto_direct_buffer_f_q, q_cldfb ) ); // proto_direct_buffer_f_q -> q_cldfb + ImagBuffer_fx[k][0][l] = L_shr( p_proto_direct_buffer_fx[2 * ( k * num_freq_bands + l ) + 1], shift ); // proto_direct_buffer_f_q -> q_cldfb move32(); } } @@ -1690,7 +1693,7 @@ void protoSignalComputation2_fx( Word32 min_sum_total_ratio_fx, min_sum_total_ratio_db_fx; Word32 sum_total_ratio_fx[MASA_SUM_FREQ_RANGE_BINS]; Word16 q_sum_total_ratio; - Word32 a_fx, b_fx; + Word32 a_fx, b_fx, a2_fx, b2_fx; Word16 interpolatorSpaced_fx, interpolatorDmx_fx; Word32 tempSpaced_fx, tempDmx_fx; Word16 q_shift, min_q_shift, exp, q_temp, temp_q_shift, q_temp2; @@ -1698,6 +1701,7 @@ void protoSignalComputation2_fx( Word64 W_tmp1, W_tmp2; Word64 reference_power_64fx[CLDFB_NO_CHANNELS_MAX]; Word16 q_reference_power_64fx; + Word16 head_room, q_Left_Right_power; /* Calculate maximum possible shift for the buffers RealBuffer_fx and ImagBuffer_fx */ min_q_shift = Q31; move16(); @@ -1864,8 +1868,10 @@ void protoSignalComputation2_fx( a_fx = 21474836; /*0.01 in Q31*/ /* Temporal smoothing coefficient */ move32(); b_fx = L_sub( ONE_IN_Q31, a_fx ); /* Temporal smoothing coefficient q31*/ - // a2_fx = 214748365; /*0.1 in Q31*/ /* Temporal smoothing coefficient */ - // b2_fx = L_sub( ONE_IN_Q31, a2_fx ); /* Temporal smoothing coefficient */ + move32(); + a2_fx = 214748365; /*0.1 in Q31*/ /* Temporal smoothing coefficient */ + move32(); + b2_fx = L_sub( ONE_IN_Q31, a2_fx ); /* Temporal smoothing coefficient */ IF( stereo_type_detect->interpolator > 0 ) { @@ -1888,6 +1894,23 @@ void protoSignalComputation2_fx( q_temp = sub( add( add( q_cldfb, min_q_shift ), add( q_cldfb, min_q_shift ) ), 31 ); q_temp2 = sub( add( add( q_cldfb, temp_q_shift ), add( q_cldfb, temp_q_shift ) ), 31 ); + head_room = 63; + move16(); + FOR( l = 0; l < num_freq_bands; l++ ) + { + re1 = L_shl( RealBuffer_fx[0][0][l], min_q_shift ); // q_cldfb+min_q_shift + im1 = L_shl( ImagBuffer_fx[0][0][l], min_q_shift ); // q_cldfb+min_q_shift + re2 = L_shl( RealBuffer_fx[1][0][l], min_q_shift ); // q_cldfb+min_q_shift + im2 = L_shl( ImagBuffer_fx[1][0][l], min_q_shift ); // q_cldfb+min_q_shift + + W_tmp1 = W_add( W_mult0_32_32( re1, re1 ), W_mult0_32_32( im1, im1 ) ); + W_tmp2 = W_add( W_mult0_32_32( re2, re2 ), W_mult0_32_32( im2, im2 ) ); + + head_room = s_min( head_room, W_norm( W_add( W_tmp1, W_tmp2 ) ) ); + } + head_room = sub( head_room, find_guarded_bits_fx( num_freq_bands ) ); + q_Left_Right_power = add( shl( add( q_cldfb, min_q_shift ), 1 ), sub( head_room, 32 ) ); + FOR( l = 0; l < num_freq_bands; l++ ) { re1 = L_shl( RealBuffer_fx[0][0][l], min_q_shift ); // q_cldfb+min_q_shift @@ -1902,26 +1925,26 @@ void protoSignalComputation2_fx( /* Compute reference power */ // Left_power_fx = Madd_32_32( Mpy_32_32( re1, re1 ), im1, im1 ); W_tmp1 = W_add( W_mult0_32_32( re1, re1 ), W_mult0_32_32( im1, im1 ) ); // 2*(q_cldfb+min_q_shift) - Left_power_fx = W_extract_l( W_shr( W_tmp1, 31 ) ); + Left_power_fx = W_extract_h( W_shl( W_tmp1, head_room ) ); // q_Left_Right_power // Right_power_fx = Madd_32_32( Mpy_32_32( re2, re2 ), im2, im2 ); W_tmp2 = W_add( W_mult0_32_32( re2, re2 ), W_mult0_32_32( im2, im2 ) ); // 2*(q_cldfb+min_q_shift) - Right_power_fx = W_extract_l( W_shr( W_tmp2, 31 ) ); + Right_power_fx = W_extract_h( W_shl( W_tmp2, head_room ) ); // q_Left_Right_power // reference_power_fx[l] = L_add( Left_power_fx, Right_power_fx ); reference_power_64fx[l] = W_add( W_tmp1, W_tmp2 ); // 2*(q_cldfb+min_q_shift) move64(); - left_bb_power_fx = L_add( left_bb_power_fx, Left_power_fx ); // 2*(q_cldfb+min_q_shift) -31 - right_bb_power_fx = L_add( right_bb_power_fx, Right_power_fx ); // 2*(q_cldfb+min_q_shift) -31 + left_bb_power_fx = L_add( left_bb_power_fx, Left_power_fx ); // q_Left_Right_power + right_bb_power_fx = L_add( right_bb_power_fx, Right_power_fx ); // q_Left_Right_power // total_bb_power_fx = L_add( total_bb_power_fx, reference_power_fx[l] ); - total_bb_power_fx = L_add( total_bb_power_fx, W_extract_l( W_shr( reference_power_64fx[l], 31 ) ) ); // 2*(q_cldfb+min_q_shift) -31 + total_bb_power_fx = L_add( total_bb_power_fx, W_extract_h( W_shl( reference_power_64fx[l], head_room ) ) ); // q_Left_Right_power IF( GT_16( l, MASA_HI_FREQ_START_BIN ) ) { - left_hi_power_fx = L_add( left_hi_power_fx, Left_power_fx ); // 2*(q_cldfb+min_q_shift) -31 - right_hi_power_fx = L_add( right_hi_power_fx, Right_power_fx ); // 2*(q_cldfb+min_q_shift) -31 + left_hi_power_fx = L_add( left_hi_power_fx, Left_power_fx ); // q_Left_Right_power + right_hi_power_fx = L_add( right_hi_power_fx, Right_power_fx ); // q_Left_Right_power // total_hi_power_fx = L_add( total_hi_power_fx, reference_power_fx[l] ); - total_hi_power_fx = L_add( total_hi_power_fx, W_extract_l( W_shr( reference_power_64fx[l], 31 ) ) ); // 2*(q_cldfb+min_q_shift) -31 + total_hi_power_fx = L_add( total_hi_power_fx, W_extract_h( W_shl( reference_power_64fx[l], head_room ) ) ); // q_Left_Right_power } IF( LT_16( l, s_min( num_freq_bands, MASA_SUM_FREQ_RANGE_BINS ) ) ) @@ -1958,12 +1981,17 @@ void protoSignalComputation2_fx( test(); IF( ( stereo_type_detect->sum_power_fx[l] == 0 ) && ( stereo_type_detect->total_power_fx[l] == 0 ) ) { - sum_total_ratio_fx[l] = MAX_16; // q15 + sum_total_ratio_fx[l] = MAX_32; // q15 + move32(); + } + ELSE IF( stereo_type_detect->total_power_fx[l] == 0 ) + { + sum_total_ratio_fx[l] = MAX_32; // q15 move32(); } ELSE { - sum_total_ratio_fx[l] = BASOP_Util_Divide3232_Scale( stereo_type_detect->sum_power_fx[l], L_add( stereo_type_detect->total_power_fx[l], EPSILON_FX ), &exp ); // 15-(exp+s_min( stereo_type_detect->q_total_power, q_temp )-s_min( stereo_type_detect->q_sum_power, q_temp2 )) + sum_total_ratio_fx[l] = BASOP_Util_Divide3232_Scale( stereo_type_detect->sum_power_fx[l], stereo_type_detect->total_power_fx[l], &exp ); // 15-(exp+s_min( stereo_type_detect->q_total_power, q_temp )-s_min( stereo_type_detect->q_sum_power, q_temp2 )) move32(); q_sum_total_ratio = add( sub( 15, exp ), sub( s_min( stereo_type_detect->q_sum_power, q_temp2 ), s_min( stereo_type_detect->q_total_power, q_temp ) ) ); sum_total_ratio_fx[l] = L_shl( sum_total_ratio_fx[l], sub( Q15, q_sum_total_ratio ) ); // q15 @@ -2235,45 +2263,45 @@ void protoSignalComputation2_fx( } } - temp = Mpy_32_32( a_fx, left_bb_power_fx ); // 2*(q_cldfb+min_q_shift) -31 - IF( LT_16( q_temp, stereo_type_detect->q_left_bb_power ) ) + temp = Mpy_32_32( a_fx, left_bb_power_fx ); // q_Left_Right_power + IF( LT_16( q_Left_Right_power, stereo_type_detect->q_left_bb_power ) ) { - stereo_type_detect->left_bb_power_fx = L_add( temp, L_shr( Mpy_32_32( b_fx, stereo_type_detect->left_bb_power_fx ), sub( stereo_type_detect->q_left_bb_power, q_temp ) ) ); // q_temp + stereo_type_detect->left_bb_power_fx = L_add( temp, L_shr( Mpy_32_32( b_fx, stereo_type_detect->left_bb_power_fx ), sub( stereo_type_detect->q_left_bb_power, q_Left_Right_power ) ) ); // q_Left_Right_power move32(); - stereo_type_detect->q_left_bb_power = q_temp; + stereo_type_detect->q_left_bb_power = q_Left_Right_power; move16(); } ELSE { - stereo_type_detect->left_bb_power_fx = L_add( L_shr( temp, sub( q_temp, stereo_type_detect->q_left_bb_power ) ), Mpy_32_32( b_fx, stereo_type_detect->left_bb_power_fx ) ); // stereo_type_detect->q_left_bb_power + stereo_type_detect->left_bb_power_fx = Madd_32_32( L_shr( temp, sub( q_Left_Right_power, stereo_type_detect->q_left_bb_power ) ), b_fx, stereo_type_detect->left_bb_power_fx ); // stereo_type_detect->q_left_bb_power move32(); } - temp = Mpy_32_32( a_fx, right_bb_power_fx ); // 2*(q_cldfb+min_q_shift) -31 - IF( LT_16( q_temp, stereo_type_detect->q_right_bb_power ) ) + temp = Mpy_32_32( a_fx, right_bb_power_fx ); // q_Left_Right_power + IF( LT_16( q_Left_Right_power, stereo_type_detect->q_right_bb_power ) ) { - stereo_type_detect->right_bb_power_fx = L_add( temp, L_shr( Mpy_32_32( b_fx, stereo_type_detect->right_bb_power_fx ), sub( stereo_type_detect->q_right_bb_power, q_temp ) ) ); // q_temp + stereo_type_detect->right_bb_power_fx = L_add( temp, L_shr( Mpy_32_32( b_fx, stereo_type_detect->right_bb_power_fx ), sub( stereo_type_detect->q_right_bb_power, q_Left_Right_power ) ) ); // q_Left_Right_power move32(); - stereo_type_detect->q_right_bb_power = q_temp; + stereo_type_detect->q_right_bb_power = q_Left_Right_power; move16(); } ELSE { - stereo_type_detect->right_bb_power_fx = L_add( L_shr( temp, sub( q_temp, stereo_type_detect->q_right_bb_power ) ), Mpy_32_32( b_fx, stereo_type_detect->right_bb_power_fx ) ); // stereo_type_detect->q_right_bb_power + stereo_type_detect->right_bb_power_fx = Madd_32_32( L_shr( temp, sub( q_Left_Right_power, stereo_type_detect->q_right_bb_power ) ), b_fx, stereo_type_detect->right_bb_power_fx ); // stereo_type_detect->q_right_bb_power move32(); } - temp = Mpy_32_32( a_fx, total_bb_power_fx ); // 2*(q_cldfb+min_q_shift) -31 - IF( LT_16( q_temp, stereo_type_detect->q_total_bb_power ) ) + temp = Mpy_32_32( a_fx, total_bb_power_fx ); // q_Left_Right_power + IF( LT_16( q_Left_Right_power, stereo_type_detect->q_total_bb_power ) ) { - stereo_type_detect->total_bb_power_fx = L_add( temp, L_shr( Mpy_32_32( b_fx, stereo_type_detect->total_bb_power_fx ), sub( stereo_type_detect->q_total_bb_power, q_temp ) ) ); // q_temp + stereo_type_detect->total_bb_power_fx = L_add( temp, L_shr( Mpy_32_32( b_fx, stereo_type_detect->total_bb_power_fx ), sub( stereo_type_detect->q_total_bb_power, q_Left_Right_power ) ) ); // q_Left_Right_power move32(); - stereo_type_detect->q_total_bb_power = q_temp; + stereo_type_detect->q_total_bb_power = q_Left_Right_power; move16(); } ELSE { - stereo_type_detect->total_bb_power_fx = L_add( L_shr( temp, sub( q_temp, stereo_type_detect->q_total_bb_power ) ), Mpy_32_32( b_fx, stereo_type_detect->total_bb_power_fx ) ); // stereo_type_detect->q_total_bb_power + stereo_type_detect->total_bb_power_fx = Madd_32_32( L_shr( temp, sub( q_Left_Right_power, stereo_type_detect->q_total_bb_power ) ), b_fx, stereo_type_detect->total_bb_power_fx ); // stereo_type_detect->q_total_bb_power move32(); } @@ -2291,8 +2319,7 @@ void protoSignalComputation2_fx( q_lr_bb_power = stereo_type_detect->q_right_bb_power; move16(); } - q_lr_bb_power = sub( q_lr_bb_power, 1 ); /* = (lr_bb_power_fx * 2) */ - + q_lr_bb_power = sub( q_lr_bb_power, 1 ); /* = (lr_bb_power_fx * 2) */ temp = BASOP_Util_Divide3232_Scale_cadence( lr_bb_power_fx, L_add( stereo_type_detect->total_bb_power_fx, EPSILON_FX ), &exp ); // Q(31-(exp+stereo_type_detect->q_total_bb_power-q_lr_bb_power)) exp = sub( 31, add( sub( 31, exp ), sub( q_lr_bb_power, stereo_type_detect->q_total_bb_power ) ) ); temp = BASOP_Util_Log2( temp ); // q25 @@ -2303,15 +2330,15 @@ void protoSignalComputation2_fx( // 20480 = 10 in Q11 lr_total_bb_ratio_fx = Mpy_32_16_1( temp, 20480 ); // Q21 - stereo_type_detect->left_hi_power_fx = BASOP_Util_Add_Mant32Exp( Mpy_32_32( a_fx, left_hi_power_fx ), sub( 31, q_temp ), Mpy_32_32( b_fx, stereo_type_detect->left_hi_power_fx ), sub( 31, stereo_type_detect->q_left_hi_power ), &stereo_type_detect->q_left_hi_power ); + stereo_type_detect->left_hi_power_fx = BASOP_Util_Add_Mant32Exp( Mpy_32_32( a2_fx, left_hi_power_fx ), sub( 31, q_temp ), Mpy_32_32( b2_fx, stereo_type_detect->left_hi_power_fx ), sub( 31, stereo_type_detect->q_left_hi_power ), &stereo_type_detect->q_left_hi_power ); move32(); stereo_type_detect->q_left_hi_power = sub( 31, stereo_type_detect->q_left_hi_power ); move16(); - stereo_type_detect->right_hi_power_fx = BASOP_Util_Add_Mant32Exp( Mpy_32_32( a_fx, right_hi_power_fx ), sub( 31, q_temp ), Mpy_32_32( b_fx, stereo_type_detect->right_hi_power_fx ), sub( 31, stereo_type_detect->q_right_hi_power ), &stereo_type_detect->q_right_hi_power ); + stereo_type_detect->right_hi_power_fx = BASOP_Util_Add_Mant32Exp( Mpy_32_32( a2_fx, right_hi_power_fx ), sub( 31, q_temp ), Mpy_32_32( b2_fx, stereo_type_detect->right_hi_power_fx ), sub( 31, stereo_type_detect->q_right_hi_power ), &stereo_type_detect->q_right_hi_power ); move32(); stereo_type_detect->q_right_hi_power = sub( 31, stereo_type_detect->q_right_hi_power ); move16(); - stereo_type_detect->total_hi_power_fx = BASOP_Util_Add_Mant32Exp( Mpy_32_32( a_fx, total_hi_power_fx ), sub( 31, q_temp ), Mpy_32_32( b_fx, stereo_type_detect->total_hi_power_fx ), sub( 31, stereo_type_detect->q_total_hi_power ), &stereo_type_detect->q_total_hi_power ); + stereo_type_detect->total_hi_power_fx = BASOP_Util_Add_Mant32Exp( Mpy_32_32( a2_fx, total_hi_power_fx ), sub( 31, q_temp ), Mpy_32_32( b2_fx, stereo_type_detect->total_hi_power_fx ), sub( 31, stereo_type_detect->q_total_hi_power ), &stereo_type_detect->q_total_hi_power ); move32(); stereo_type_detect->q_total_hi_power = sub( 31, stereo_type_detect->q_total_hi_power ); move16(); @@ -2328,8 +2355,7 @@ void protoSignalComputation2_fx( move32(); q_lr_hi_power = stereo_type_detect->q_right_hi_power; } - q_lr_hi_power = sub( q_lr_hi_power, 1 ); /* = (q_lr_hi_power * 2) */ - + q_lr_hi_power = sub( q_lr_hi_power, 1 ); /* = (q_lr_hi_power * 2) */ temp = BASOP_Util_Divide3232_Scale_cadence( lr_hi_power_fx, L_add( stereo_type_detect->total_hi_power_fx, EPSILON_FX ), &exp ); // Q=31-(exp+ stereo_type_detect->q_total_hi_power-q_lr_hi_power) exp = sub( 31, add( sub( 31, exp ), sub( q_lr_hi_power, stereo_type_detect->q_total_hi_power ) ) ); temp = BASOP_Util_Log2( temp ); // q25 @@ -3809,7 +3835,7 @@ static void ivas_masa_ext_dirac_render_sf_fx( hDirACRend->h_output_synthesis_psd_state.proto_diffuse_buffer_f_q, hDirACRend->num_protos_diff, hDirACRend->proto_index_diff, - hDirACRend->h_output_synthesis_psd_state.proto_diffuse_buffer_f_fx + slot_idx * 2 * hSpatParamRendCom->num_freq_bands * hDirACRend->num_outputs_diff + 2 * hSpatParamRendCom->num_freq_bands * min( 4, nchan_transport ), + hDirACRend->h_output_synthesis_psd_state.proto_diffuse_buffer_f_fx + slot_idx * 2 * hSpatParamRendCom->num_freq_bands * hDirACRend->num_outputs_diff + 2 * hSpatParamRendCom->num_freq_bands * s_min( 4, nchan_transport ), &hDirACRend->h_output_synthesis_psd_state.proto_diffuse_buffer_f_q, onset_filter_fx, hDirACRend->h_freq_domain_decorr_ap_params, @@ -4011,20 +4037,6 @@ static void ivas_masa_ext_dirac_render_sf_fx( move16(); } - /*Buffer Scaling*/ - FOR( ch = 0; ch < hDirACRend->hOutSetup.nchan_out_woLFE; ch++ ) - { - FOR( slot_idx = 0; slot_idx < hSpatParamRendCom->subframe_nbslots[subframe_idx]; slot_idx++ ) - { - scale_sig32( Cldfb_RealBuffer_fx[ch][slot_idx], - hSpatParamRendCom->num_freq_bands, sub( 11, q_cldfb ) ); // q11 - scale_sig32( Cldfb_ImagBuffer_fx[ch][slot_idx], - hSpatParamRendCom->num_freq_bands, sub( 11, q_cldfb ) ); // q11 - } - } - q_cldfb = 11; - move16(); - Word16 reference_power_temp_q = getScaleFactor32( DirAC_mem.reference_power_fx, DirAC_mem.reference_power_len ); scale_sig32( DirAC_mem.reference_power_fx, DirAC_mem.reference_power_len, reference_power_temp_q ); /*DirAC_mem.reference_power_q + reference_power_temp_q*/ DirAC_mem.reference_power_q = add( DirAC_mem.reference_power_q, reference_power_temp_q ); diff --git a/lib_rend/ivas_efap.c b/lib_rend/ivas_efap_fx.c similarity index 96% rename from lib_rend/ivas_efap.c rename to lib_rend/ivas_efap_fx.c index 7d47f31747a32108ebaa0c11967eff4d34a88c9d..543decbddee50bf407465f629883234eb976979b 100644 --- a/lib_rend/ivas_efap.c +++ b/lib_rend/ivas_efap_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other @@ -35,10 +35,8 @@ #include #include #include "options.h" -#include "prot.h" #include "prot_fx.h" -#include "ivas_prot.h" -#include "ivas_prot_rend.h" +#include "ivas_prot_rend_fx.h" #include "ivas_stat_dec.h" #include "wmc_auto.h" #include "ivas_prot_fx.h" @@ -2479,7 +2477,7 @@ static Word16 in_tri_fx( Word16 tmp16, tmp_e; Word64 S[2]; /* Threshold adjusted */ - Word64 thresh_int = 4295; // 1e-6f in Q32 + Word64 thresh_int = 35184640; // 1e-6f in Q45 move64(); /* @@ -2490,7 +2488,7 @@ static Word16 in_tri_fx( */ v_sub_fixed( B, A, tmpDot1, 2, 0 ); // tmpDot1 q22 - v_sub_fixed( C, A, tmpDot2, 2, 0 ); // tmpDot 2q22 + v_sub_fixed( C, A, tmpDot2, 2, 0 ); // tmpDot2 q22 /* Verification of the non-colinearity : Q22 * Q22 = Q13 */ invFactor = L_sub( Mpy_32_32( tmpDot1[0], tmpDot2[1] ), Mpy_32_32( tmpDot1[1], tmpDot2[0] ) ); /*q22+q22-q31->q13*/ @@ -2516,68 +2514,18 @@ static Word16 in_tri_fx( move32(); matInv[1][1] = Mpy_32_32( tmpDot1[0], invFactor ); // q=22+invFactor_exp move32(); - - /* Computing S (Q13 + matInv_exp_final[i] + P_minus_A_exp_final + invFactor_exp - 1 ) = - matInv (Q22 + matInv_exp_final[i] + invFactor_exp) *(P-A) (Q22 + P_minus_A_exp_final) */ - Word16 matInv_exp[2][2], P_minus_A_exp[2]; - Word16 matInv_exp_final[2], P_minus_A_exp_final; - FOR( Word32 i = 0; i < 2; i++ ) - { - FOR( Word32 j = 0; j < 2; j++ ) - { - matInv_exp[i][j] = 31; - move16(); - IF( matInv[i][j] != 0 ) - { - matInv_exp[i][j] = norm_l( matInv[i][j] ); - move16(); - } - } - matInv_exp_final[i] = s_min( matInv_exp[i][0], matInv_exp[i][1] ); - move16(); - P_minus_A_exp[i] = 31; - move16(); - IF( P_minus_A[i] != 0 ) - { - P_minus_A_exp[i] = norm_l( P_minus_A[i] ); - move16(); - } - } - P_minus_A_exp_final = s_min( P_minus_A_exp[0], P_minus_A_exp[1] ); - - S[0] = L_add( L_shr( Mpy_32_32( L_shl( matInv[0][0], matInv_exp_final[0] ), L_shl( P_minus_A[0], P_minus_A_exp_final ) ), Q1 ), - L_shr( Mpy_32_32( L_shl( matInv[0][1], matInv_exp_final[0] ), L_shl( P_minus_A[1], P_minus_A_exp_final ) ), Q1 ) ); //(22+invFactor_exp+matInv_exp_final[0]+22+P_minus_A_exp_final-1)-31=>12+invFactor_exp+matInv_exp_final[0]+P_minus_A_exp_final + S[0] = W_mac_32_32( W_mult_32_32( matInv[0][0], P_minus_A[0] ), matInv[0][1], P_minus_A[1] ); // Q22+invFactor_exp +Q22 + 1 move64(); - S[1] = L_add( L_shr( Mpy_32_32( L_shl( matInv[1][0], matInv_exp_final[1] ), L_shl( P_minus_A[0], P_minus_A_exp_final ) ), Q1 ), - L_shr( Mpy_32_32( L_shl( matInv[1][1], matInv_exp_final[1] ), L_shl( P_minus_A[1], P_minus_A_exp_final ) ), Q1 ) ); //(22+invFactor_exp+matInv_exp_final[1]+22+P_minus_A_exp_final-1)-31=>12+invFactor_exp+matInv_exp_final[0]+P_minus_A_exp_final + S[0] = W_shr( S[0], invFactor_exp ); // q45 + move64(); + S[1] = W_mac_32_32( W_mult_32_32( matInv[1][0], P_minus_A[0] ), matInv[1][1], P_minus_A[1] ); // Q22+invFactor_exp +Q22 + 1 + move64(); + S[1] = W_shr( S[1], invFactor_exp ); // q45 move64(); - - /* Checking if we are in the triangle; For the theory, check Christian Borss article, section 3.2 */ - // Q32 S - IF( sub( sub( sub( Q20, matInv_exp_final[0] ), P_minus_A_exp_final ), invFactor_exp ) < 0 ) - { - S[0] = W_shr( S[0], sub( add( add( matInv_exp_final[0], P_minus_A_exp_final ), invFactor_exp ), Q20 ) ); // q32 - move64(); - } - ELSE - { - S[0] = W_shl( S[0], sub( sub( sub( Q20, matInv_exp_final[0] ), P_minus_A_exp_final ), invFactor_exp ) ); // q32 - move64(); - } - IF( sub( sub( sub( Q20, matInv_exp_final[1] ), P_minus_A_exp_final ), invFactor_exp ) < 0 ) - { - S[1] = W_shr( S[1], sub( add( add( matInv_exp_final[1], P_minus_A_exp_final ), invFactor_exp ), Q20 ) ); // q32 - move64(); - } - ELSE - { - S[1] = W_shl( S[1], sub( sub( sub( Q20, matInv_exp_final[1] ), P_minus_A_exp_final ), invFactor_exp ) ); // q32 - move64(); - } test(); test(); - IF( LT_64( S[0], -thresh_int ) || LT_64( S[1], -thresh_int ) || GT_64( W_add( S[0], S[1] ), W_add( W_shl( 1, 32 ), thresh_int ) ) ) + IF( LT_64( S[0], -thresh_int ) || LT_64( S[1], -thresh_int ) || GT_64( W_add( S[0], S[1] ), W_add( ONE_IN_Q45, thresh_int ) ) ) { return 0; } diff --git a/lib_rend/ivas_hrtf.c b/lib_rend/ivas_hrtf_fx.c similarity index 98% rename from lib_rend/ivas_hrtf.c rename to lib_rend/ivas_hrtf_fx.c index ab69784c78998530a767b3d404a15f1778443367..93f9fbd83ad15a678ebf73f29f0f0e2d4f617709 100644 --- a/lib_rend/ivas_hrtf.c +++ b/lib_rend/ivas_hrtf_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other @@ -32,11 +32,10 @@ #include #include "options.h" -#include "prot.h" -#include "ivas_prot_rend.h" +#include "prot_fx.h" +#include "ivas_prot_rend_fx.h" #include "ivas_error.h" #include "wmc_auto.h" -#include "ivas_prot.h" #include "ivas_prot_fx.h" /*-----------------------------------------------------------------------* diff --git a/lib_rend/ivas_masa_merge.c b/lib_rend/ivas_masa_merge_fx.c similarity index 99% rename from lib_rend/ivas_masa_merge.c rename to lib_rend/ivas_masa_merge_fx.c index 9e6807b00bb0b09570d05424a212fefd1bdecc8b..fd20a9fabb262fe00e70c28aa6319e405ec7707b 100644 --- a/lib_rend/ivas_masa_merge.c +++ b/lib_rend/ivas_masa_merge_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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,12 +33,10 @@ #include #include "options.h" #include "lib_rend.h" -#include "ivas_prot_rend.h" -#include "ivas_prot.h" +#include "ivas_prot_rend_fx.h" #include "ivas_cnst.h" -#include "prot.h" -#include "wmc_auto.h" #include "prot_fx.h" +#include "wmc_auto.h" #include "ivas_prot_fx.h" @@ -501,7 +499,7 @@ ivas_error masaPrerendOpen_fx( move16(); FOR( i = 0; i < hMasaPrerend->num_Cldfb_instances; i++ ) { - IF( ( error = openCldfb_ivas_fx( &( hMasaPrerend->cldfbAnaEnc[i] ), CLDFB_ANALYSIS, input_Fs, CLDFB_PROTOTYPE_5_00MS ) ) != IVAS_ERR_OK ) + IF( ( error = openCldfb_ivas_fx( &( hMasaPrerend->cldfbAnaEnc[i] ), CLDFB_ANALYSIS, input_Fs, CLDFB_PROTOTYPE_5_00MS, DEC ) ) != IVAS_ERR_OK ) { return error; } diff --git a/lib_rend/ivas_mcmasa_ana.c b/lib_rend/ivas_mcmasa_ana_fx.c similarity index 98% rename from lib_rend/ivas_mcmasa_ana.c rename to lib_rend/ivas_mcmasa_ana_fx.c index 5327cd3c5497af68e1e4402fa8fda4b4ec30b229..f3b4d175551867a1866ac1c6bdd7601e0fcdea4f 100644 --- a/lib_rend/ivas_mcmasa_ana.c +++ b/lib_rend/ivas_mcmasa_ana_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other @@ -35,14 +35,12 @@ #include #include "ivas_cnst.h" #include "options.h" -#include "ivas_prot_rend.h" -#include "ivas_prot.h" -#include "prot.h" +#include "ivas_prot_rend_fx.h" +#include "prot_fx.h" #include "ivas_stat_rend.h" #include "ivas_rom_com.h" #include "wmc_auto.h" #include "ivas_prot_fx.h" -#include "prot_fx.h" #include "ivas_rom_com_fx.h" /*------------------------------------------------------------------------- @@ -226,7 +224,7 @@ ivas_error ivas_mcmasa_ana_open( move16(); FOR( i = 0; i < hMcMasa->num_Cldfb_instances; i++ ) { - IF( NE_32( ( error = openCldfb_ivas_fx( &( hMcMasa->cldfbAnaEnc[i] ), CLDFB_ANALYSIS, input_Fs, CLDFB_PROTOTYPE_5_00MS ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &( hMcMasa->cldfbAnaEnc[i] ), CLDFB_ANALYSIS, input_Fs, CLDFB_PROTOTYPE_5_00MS, DEC ) ), IVAS_ERR_OK ) ) { return error; } @@ -755,7 +753,12 @@ void ivas_mcmasa_param_est_ana_fx( /* Direction estimation */ computeIntensityVector_ana_fx( hMcMasa->band_grouping, Foa_RealBuffer_fx, Foa_ImagBuffer_fx, num_freq_bands, intensity_real_fx ); /* Q intensity_real_fx = 2*inp_q-31, e = 31 - 2*inp_q + 31 = 62 - 2*inp_q = 2*(31-inp_q)=2*c_e */ - computeDirectionVectors_fixed( intensity_real_fx[0], intensity_real_fx[1], intensity_real_fx[2], 0, num_freq_bands, direction_vector_fx[0], direction_vector_fx[1], direction_vector_fx[2], shl( c_e, 1 ) ); /* Q direction_vector_fx = Q30*/ + computeDirectionVectors_fixed( intensity_real_fx[0], intensity_real_fx[1], intensity_real_fx[2], 0, num_freq_bands, direction_vector_fx[0], direction_vector_fx[1], direction_vector_fx[2], shl( c_e, 1 ) +#ifdef NONBE_IMPROVE_DIRAC_INTENSITY_PREC + , + NULL +#endif + ); /* Q direction_vector_fx = Q30*/ /* Power and intensity estimation for diffuseness */ computeIntensityVector_ana_fx( hMcMasa->band_grouping, FoaEven_RealBuffer_fx, FoaEven_ImagBuffer_fx, num_freq_bands, intensity_even_real_fx ); /*2*inp_q-31*/ @@ -899,12 +902,7 @@ void ivas_mcmasa_param_est_ana_fx( surrCoh_e = 0; move16(); surrCoh_fx = Mult_32_32( surrCoh_fx, surrCoh_fx ); - IF( LT_32( surrCoh_fx, ONE_IN_Q31 ) ) - { - surrCoh_fx = surrCoh_fx; - move32(); - } - ELSE + IF( GE_32( surrCoh_fx, ONE_IN_Q31 ) ) { surrCoh_fx = ONE_IN_Q31; move32(); @@ -1089,21 +1087,11 @@ void ivas_mcmasa_param_est_ana_fx( move16(); } - IF( ( LT_32( spreadCoh_fx, L_shl_sat( 1, sub( 31, spreadCoh_e ) ) ) ) ) - { - spreadCoh_fx = spreadCoh_fx; - move32(); - } - ELSE + IF( GE_32( spreadCoh_fx, L_shl_sat( 1, sub( 31, spreadCoh_e ) ) ) ) { spreadCoh_fx = L_shl_sat( 1, sub( 31, spreadCoh_e ) ); } - IF( ( spreadCoh_fx > 0 ) ) - { - spreadCoh_fx = spreadCoh_fx; - move32(); - } - ELSE + IF( ( spreadCoh_fx <= 0 ) ) { spreadCoh_fx = 0; move32(); @@ -1140,23 +1128,13 @@ void ivas_mcmasa_param_est_ana_fx( move32(); } - IF( LT_32( cohRatio_fx, ONE_IN_Q31 ) ) - { - cohRatio_fx = cohRatio_fx; - move32(); - } - ELSE + IF( GE_32( cohRatio_fx, ONE_IN_Q31 ) ) { cohRatio_fx = ONE_IN_Q31; move32(); } - IF( cohRatio_fx > 0 ) - { - cohRatio_fx = cohRatio_fx; - move32(); - } - ELSE + IF( cohRatio_fx <= 0 ) { cohRatio_fx = 0; move32(); diff --git a/lib_rend/ivas_objectRenderer.c b/lib_rend/ivas_objectRenderer_fx.c similarity index 99% rename from lib_rend/ivas_objectRenderer.c rename to lib_rend/ivas_objectRenderer_fx.c index f323b615dac3ca21d1b55958452e9ab8cbd9a544..1b5bc0d1b5e5644d47cd293d00556fb30dbe3cc0 100644 --- a/lib_rend/ivas_objectRenderer.c +++ b/lib_rend/ivas_objectRenderer_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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,14 +33,12 @@ #include "ivas_stat_rend.h" #include #include "options.h" -#include "prot.h" -#include "ivas_prot.h" -#include "ivas_prot_rend.h" +#include "prot_fx.h" +#include "ivas_prot_rend_fx.h" #include #include "ivas_rom_com.h" #include "wmc_auto.h" #include "ivas_prot_fx.h" -#include "prot_fx.h" #include "debug.h" #include "ivas_rom_com_fx.h" #define float_to_fixed( n, factor ) ( round( n * ( 1 << factor ) ) ) diff --git a/lib_rend/ivas_objectRenderer_hrFilt.c b/lib_rend/ivas_objectRenderer_hrFilt_fx.c similarity index 99% rename from lib_rend/ivas_objectRenderer_hrFilt.c rename to lib_rend/ivas_objectRenderer_hrFilt_fx.c index 4d5ad355a15083cc5185df1c319656fad59ca582..01e35efe1711b619d8dd6dfc821e79639d355904 100644 --- a/lib_rend/ivas_objectRenderer_hrFilt.c +++ b/lib_rend/ivas_objectRenderer_hrFilt_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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,13 +33,12 @@ #include #include #include "options.h" -#include "prot.h" +#include "prot_fx.h" #include -#include "ivas_prot_rend.h" +#include "ivas_prot_rend_fx.h" #include "ivas_rom_rend.h" #include "ivas_cnst.h" #include "wmc_auto.h" -#include "prot_fx.h" /*---------------------------------------------------------------------* * Local function prototypes diff --git a/lib_rend/ivas_objectRenderer_mix.c b/lib_rend/ivas_objectRenderer_mix_fx.c similarity index 99% rename from lib_rend/ivas_objectRenderer_mix.c rename to lib_rend/ivas_objectRenderer_mix_fx.c index 5616da037e477eb2fb272bbe1df6aea2f955de23..0e61282d474afcbfe1fafe00f76aced101e92bb7 100644 --- a/lib_rend/ivas_objectRenderer_mix.c +++ b/lib_rend/ivas_objectRenderer_mix_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other @@ -32,14 +32,13 @@ #include #include "options.h" -#include "prot.h" -#include "ivas_prot_rend.h" +#include "prot_fx.h" +#include "ivas_prot_rend_fx.h" #include "ivas_rom_TdBinauralRenderer.h" #include "ivas_error.h" #include "wmc_auto.h" #include "ivas_rom_rend.h" #include "ivas_prot_fx.h" -#include "prot_fx.h" /*-------------------------------------------------------------------* * Local constants diff --git a/lib_rend/ivas_objectRenderer_sfx.c b/lib_rend/ivas_objectRenderer_sfx_fx.c similarity index 99% rename from lib_rend/ivas_objectRenderer_sfx.c rename to lib_rend/ivas_objectRenderer_sfx_fx.c index 8c6fd8663440cda59f05535665f4546202a7b0b8..210706d5be5ff42adb52c59029465e96f58dfdcf 100644 --- a/lib_rend/ivas_objectRenderer_sfx.c +++ b/lib_rend/ivas_objectRenderer_sfx_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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,11 +33,10 @@ #include #include "options.h" #include -#include "ivas_prot_rend.h" +#include "ivas_prot_rend_fx.h" #include "ivas_rom_rend.h" -#include "prot.h" -#include "wmc_auto.h" #include "prot_fx.h" +#include "wmc_auto.h" /*---------------------------------------------------------------------* diff --git a/lib_rend/ivas_objectRenderer_sources.c b/lib_rend/ivas_objectRenderer_sources_fx.c similarity index 99% rename from lib_rend/ivas_objectRenderer_sources.c rename to lib_rend/ivas_objectRenderer_sources_fx.c index f01f667970f30f6c6a7e9a94a7e267f9c071d12a..5787ded3f45254dc9ffa2bd706c747e51a257c52 100644 --- a/lib_rend/ivas_objectRenderer_sources.c +++ b/lib_rend/ivas_objectRenderer_sources_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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,11 +33,10 @@ #include #include "options.h" #include -#include "prot.h" -#include "ivas_prot_rend.h" +#include "prot_fx.h" +#include "ivas_prot_rend_fx.h" #include "wmc_auto.h" #include "ivas_prot_fx.h" -#include "prot_fx.h" /*---------------------------------------------------------------------* diff --git a/lib_rend/ivas_objectRenderer_vec.c b/lib_rend/ivas_objectRenderer_vec_fx.c similarity index 86% rename from lib_rend/ivas_objectRenderer_vec.c rename to lib_rend/ivas_objectRenderer_vec_fx.c index 5e4d9d6ac462f4df22af2133616cfbfdcbd8cbc8..0d8c11aabc2d1f7bbbca125f01563c194a940636 100644 --- a/lib_rend/ivas_objectRenderer_vec.c +++ b/lib_rend/ivas_objectRenderer_vec_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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 @@ #include #include "options.h" #include -#include "prot.h" -#include "ivas_prot_rend.h" -#include "wmc_auto.h" #include "prot_fx.h" +#include "ivas_prot_rend_fx.h" +#include "wmc_auto.h" #include "ivas_prot_fx.h" @@ -88,28 +87,6 @@ Word32 TDREND_SPATIAL_VecNorm_fx( return tmp; } - -/*-------------------------------------------------------------------* - * TDREND_SPATIAL_VecNormalize() - * - * Normalize vector to unit norm - *-------------------------------------------------------------------*/ - -void TDREND_SPATIAL_VecNormalize( - const float *Vec_p, /* i : Input vector */ - float *VecNorm_p /* o : Output vector */ -) -{ - float scaler; - - scaler = inv_sqrt( Vec_p[0] * Vec_p[0] + Vec_p[1] * Vec_p[1] + Vec_p[2] * Vec_p[2] ); - VecNorm_p[0] = scaler * Vec_p[0]; - VecNorm_p[1] = scaler * Vec_p[1]; - VecNorm_p[2] = scaler * Vec_p[2]; - - return; -} - void TDREND_SPATIAL_VecNormalize_fx( const Word32 *Vec_p_fx, /* i : Input vector q */ Word16 q, /* i : Input vector Q-factor */ @@ -173,25 +150,6 @@ void TDREND_SPATIAL_VecMapToNewCoordSystem_fx( return; } -void TDREND_SPATIAL_VecMapToNewCoordSystem( - const float *Vec_p, /* i : Input vector */ - const float *TranslVec_p, /* i : Translation vector */ - const float *DirVec_p, /* i : Direction vector */ - const float *UpVec_p, /* i : Up vector */ - const float *RightVec_p, /* i : Right vector */ - float *MappedVec_p, /* o : Transformed vector */ - float *LisRelPosAbs /* o : Transformed vector ignoring orientation */ -) -{ - v_sub( Vec_p, TranslVec_p, LisRelPosAbs, 3 ); - /* Evalute the relative Vec in the coordinates of the Orientation vectors, */ - /* which form an orthonormal basis */ - MappedVec_p[0] = dotp( LisRelPosAbs, DirVec_p, 3 ); - MappedVec_p[1] = dotp( LisRelPosAbs, RightVec_p, 3 ); - MappedVec_p[2] = dotp( LisRelPosAbs, UpVec_p, 3 ); - return; -} - /*-------------------------------------------------------------------* * TDREND_SPATIAL_EvalOrthonormOrient() * diff --git a/lib_rend/ivas_omasa_ana.c b/lib_rend/ivas_omasa_ana_fx.c similarity index 99% rename from lib_rend/ivas_omasa_ana.c rename to lib_rend/ivas_omasa_ana_fx.c index 26f0cefcf77b49fe9c24644c32bb35894ec7e836..ba632c6ba13d6c9cb6cfda1d137ad77445dcd078 100644 --- a/lib_rend/ivas_omasa_ana.c +++ b/lib_rend/ivas_omasa_ana_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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,14 +34,12 @@ #include #include #include "ivas_cnst.h" -#include "ivas_prot_rend.h" -#include "ivas_prot.h" +#include "ivas_prot_rend_fx.h" #include "ivas_prot_fx.h" -#include "prot.h" +#include "prot_fx.h" #include "ivas_stat_rend.h" #include "ivas_rom_com.h" #include "wmc_auto.h" -#include "prot_fx.h" /*------------------------------------------------------------------------- @@ -135,7 +133,7 @@ ivas_error ivas_omasa_ana_open( hOMasa->num_Cldfb_instances = numAnalysisChannels; FOR( i = 0; i < hOMasa->num_Cldfb_instances; i++ ) { - IF( NE_32( ( error = openCldfb_ivas_fx( &( hOMasa->cldfbAnaEnc[i] ), CLDFB_ANALYSIS, input_Fs, CLDFB_PROTOTYPE_5_00MS ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &( hOMasa->cldfbAnaEnc[i] ), CLDFB_ANALYSIS, input_Fs, CLDFB_PROTOTYPE_5_00MS, DEC ) ), IVAS_ERR_OK ) ) { return error; } diff --git a/lib_rend/ivas_orient_trk.c b/lib_rend/ivas_orient_trk_fx.c similarity index 98% rename from lib_rend/ivas_orient_trk.c rename to lib_rend/ivas_orient_trk_fx.c index a3e833455b0bada1c1faef3247af1699d42ce741..34dd661d61e909725df830a1e913950ca86bbf6b 100644 --- a/lib_rend/ivas_orient_trk.c +++ b/lib_rend/ivas_orient_trk_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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,8 +33,8 @@ #include "common_api_types.h" #include #include "options.h" -#include "ivas_prot.h" -#include "ivas_prot_rend.h" +#include "ivas_prot_fx.h" +#include "ivas_prot_rend_fx.h" #include "ivas_cnst.h" #include #include @@ -696,11 +696,20 @@ ivas_error ivas_orient_trk_SetReferenceRotation_fx( return IVAS_ERR_UNEXPECTED_NULL_POINTER; } +#ifdef SPLIT_REND_WITH_HEAD_ROT + /* check for Euler angle signaling */ + IF( EQ_32( refRot.w_fx, L_negate( 12582912 ) ) && EQ_16( refRot.q_fact, Q22 ) ) + { + Euler2Quat_fx( deg2rad_fx( refRot.x_fx ), deg2rad_fx( refRot.y_fx ), deg2rad_fx( refRot.z_fx ), &pOTR->refRot ); + modify_Quat_q_fx( &pOTR->refRot, &pOTR->refRot, Q29 ); + } +#else /* check for Euler angle signaling */ IF( EQ_32( refRot.w_fx, -1610612736 /* -3.0f in Q29 */ ) ) { Euler2Quat_fx( deg2rad_fx( refRot.x_fx ), deg2rad_fx( refRot.y_fx ), deg2rad_fx( refRot.z_fx ), &pOTR->refRot ); } +#endif pOTR->refRot = refRot; return IVAS_ERR_OK; diff --git a/lib_rend/ivas_output_init.c b/lib_rend/ivas_output_init.c index 359bea7e670249df2dcb1e3259a77b4e9a97495a..c5271d06564129ee4b24bdeaa8d933ebb7d65729 100644 --- a/lib_rend/ivas_output_init.c +++ b/lib_rend/ivas_output_init.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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,11 +33,10 @@ #include #include "options.h" #include "ivas_cnst.h" -#include "prot.h" -#include "ivas_prot_rend.h" +#include "prot_fx.h" +#include "ivas_prot_rend_fx.h" #include "ivas_rom_com.h" #include "ivas_rom_com_fx.h" -#include "ivas_prot.h" #include "wmc_auto.h" #include "ivas_prot_fx.h" /*-------------------------------------------------------------------------* @@ -100,6 +99,10 @@ Word16 audioCfg2channels( move16(); BREAK; case IVAS_AUDIO_CONFIG_BINAURAL: +#ifdef SPLIT_REND_WITH_HEAD_ROT + case IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED: + case IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM: +#endif case IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR: case IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB: nchan_out = 2; @@ -266,6 +269,10 @@ void ivas_output_init( move16(); BREAK; case IVAS_AUDIO_CONFIG_BINAURAL: +#ifdef SPLIT_REND_WITH_HEAD_ROT + case IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED: + case IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM: +#endif case IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR: case IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB: case IVAS_AUDIO_CONFIG_ISM1: @@ -370,7 +377,12 @@ Word16 ivas_get_nchan_buffers_dec( { nchan_out_buff = s_max( nchan_out_buff, add( st_ivas->hOutSetup.nchan_out_woLFE, st_ivas->hOutSetup.num_lfe ) ); } - ELSE IF( EQ_32( output_config, IVAS_AUDIO_CONFIG_STEREO ) || EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL ) || EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR ) || EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) ) + else if ( EQ_32( output_config, IVAS_AUDIO_CONFIG_STEREO ) || EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL ) || EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR ) || EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) +#ifdef SPLIT_REND_WITH_HEAD_ROT + || EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) || + EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) +#endif + ) { nchan_out_buff = shl( CPE_CHANNELS, 1 ); } @@ -451,6 +463,12 @@ Word16 ivas_get_nchan_buffers_dec( } } +#ifdef SPLIT_REND_WITH_HEAD_ROT + IF( EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) || EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ) + { + nchan_out_buff = max( nchan_out_buff, st_ivas->hSplitBinRend->splitrend.multiBinPoseData.num_poses * BINAURAL_CHANNELS ); + } +#endif return nchan_out_buff; } diff --git a/lib_rend/ivas_output_init_fx.c b/lib_rend/ivas_output_init_fx.c index 77cfa9c553f73a8c028e1abf54c8e5279ad7f7b0..8beb5a0ecfd10a2b42e5a935127c62d97da94e05 100644 --- a/lib_rend/ivas_output_init_fx.c +++ b/lib_rend/ivas_output_init_fx.c @@ -1,7 +1,10 @@ #include "ivas_prot_fx.h" -#include "ivas_prot.h" -#include "ivas_prot_rend.h" +#include "ivas_prot_rend_fx.h" +#ifdef FIX_DISCLAIMER +#include +#endif + Word16 ivas_get_nchan_buffers_dec_ivas_fx( Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ const Word16 sba_analysis_order, /* i : SBA order evaluated in SBA decoder */ @@ -157,3 +160,116 @@ Word16 ivas_get_nchan_buffers_dec_ivas_fx( return nchan_out_buff; } + +#ifdef FIX_DISCLAIMER +/*---------------------------------------------------------------------* + * get_channel_config() + * + * Gets a str related to audio configuration + *---------------------------------------------------------------------*/ + +ivas_error get_channel_config( + const AUDIO_CONFIG config, /* i : audio configuration */ + Word8 *str /* o : string with the configuration name */ +) +{ + IF( EQ_16( (Word16) config, IVAS_AUDIO_CONFIG_MONO ) ) + { + strcpy( (char *) str, "Mono" ); + } + ELSE IF( EQ_16( (Word16) config, IVAS_AUDIO_CONFIG_STEREO ) ) + { + strcpy( (char *) str, "Stereo" ); + } + ELSE IF( EQ_16( (Word16) config, IVAS_AUDIO_CONFIG_ISM1 ) ) + { + strcpy( (char *) str, "Object-based audio (1 object)" ); + } + ELSE IF( EQ_16( (Word16) config, IVAS_AUDIO_CONFIG_ISM2 ) ) + { + strcpy( (char *) str, "Object-based audio (2 objects)" ); + } + ELSE IF( EQ_16( (Word16) config, IVAS_AUDIO_CONFIG_ISM3 ) ) + { + strcpy( (char *) str, "Object-based audio (3 objects)" ); + } + ELSE IF( EQ_16( (Word16) config, IVAS_AUDIO_CONFIG_ISM4 ) ) + { + strcpy( (char *) str, "Object-based audio (4 objects)" ); + } + ELSE IF( EQ_16( (Word16) config, IVAS_AUDIO_CONFIG_5_1 ) ) + { + strcpy( (char *) str, "Multichannel 5.1 (CICP6)" ); + } + ELSE IF( EQ_16( (Word16) config, IVAS_AUDIO_CONFIG_7_1 ) ) + { + strcpy( (char *) str, "Multichannel 7.1 (CICP12)" ); + } + ELSE IF( EQ_16( (Word16) config, IVAS_AUDIO_CONFIG_5_1_2 ) ) + { + strcpy( (char *) str, "Multichannel 5.1+2 (CICP14)" ); + } + ELSE IF( EQ_16( (Word16) config, IVAS_AUDIO_CONFIG_5_1_4 ) ) + { + strcpy( (char *) str, "Multichannel 5.1+4 (CICP16)" ); + } + ELSE IF( EQ_16( (Word16) config, IVAS_AUDIO_CONFIG_7_1_4 ) ) + { + strcpy( (char *) str, "Multichannel 7.1+4 (CICP19)" ); + } + ELSE IF( EQ_16( (Word16) config, IVAS_AUDIO_CONFIG_LS_CUSTOM ) ) + { + strcpy( (char *) str, "Multichannel (custom loudspeaker layout)" ); + } + ELSE IF( EQ_16( (Word16) config, IVAS_AUDIO_CONFIG_MASA1 ) ) + { + strcpy( (char *) str, "Metadata-Assisted Spatial Audio mono (MASA1)" ); + } + ELSE IF( EQ_16( (Word16) config, IVAS_AUDIO_CONFIG_MASA2 ) ) + { + strcpy( (char *) str, "Metadata-Assisted Spatial Audio stereo (MASA2)" ); + } + ELSE IF( EQ_16( (Word16) config, IVAS_AUDIO_CONFIG_FOA ) ) + { + strcpy( (char *) str, "Ambisonics: First Order (FOA)" ); + } + ELSE IF( EQ_16( (Word16) config, IVAS_AUDIO_CONFIG_HOA2 ) ) + { + strcpy( (char *) str, "Ambisonics: Second Order (HOA2)" ); + } + ELSE IF( EQ_16( (Word16) config, IVAS_AUDIO_CONFIG_HOA3 ) ) + { + strcpy( (char *) str, "Ambisonics: Third Order (HOA3)" ); + } + ELSE IF( EQ_16( (Word16) config, IVAS_AUDIO_CONFIG_BINAURAL ) ) + { + strcpy( (char *) str, "Binaural: no room" ); + } + ELSE IF( EQ_16( (Word16) config, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR ) ) + { + strcpy( (char *) str, "Binaural: room with impulse responses" ); + } + ELSE IF( EQ_16( (Word16) config, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) ) + { + strcpy( (char *) str, "Binaural: room with reverb" ); + } + ELSE IF( EQ_16( (Word16) config, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) ) + { + strcpy( (char *) str, "BINAURAL_SPLIT_CODED" ); + } + ELSE IF( EQ_16( (Word16) config, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ) + { + strcpy( (char *) str, "Binaural_Split_PCM" ); + } + ELSE IF( EQ_16( (Word16) config, IVAS_AUDIO_CONFIG_EXTERNAL ) ) + { + strcpy( (char *) str, "External renderer" ); + } + ELSE + { + return IVAS_ERROR( IVAS_ERR_INVALID_OUTPUT_FORMAT, "Error: Incorrect Input/Output Configuration" ); + } + + return IVAS_ERR_OK; +} +#endif diff --git a/lib_rend/ivas_prot_rend.h b/lib_rend/ivas_prot_rend_fx.h similarity index 69% rename from lib_rend/ivas_prot_rend.h rename to lib_rend/ivas_prot_rend_fx.h index 396b1163a214518338cb8ba5699a79715a5162c4..e44e81d05cc062c17cf19e3f16a851f9934eac44 100644 --- a/lib_rend/ivas_prot_rend.h +++ b/lib_rend/ivas_prot_rend_fx.h @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other @@ -81,29 +81,18 @@ Word16 ivas_get_nchan_buffers_dec_ivas_fx( const Word32 ivas_total_brate /* i : total IVAS bitrate */ ); +#ifdef FIX_DISCLAIMER +ivas_error get_channel_config( + const AUDIO_CONFIG config, /* i : audio configuration */ + Word8 *str /* o : string with the configuration name */ +); +#endif + + /*----------------------------------------------------------------------------------* * Limiter prototypes *----------------------------------------------------------------------------------*/ - -ivas_error ivas_limiter_open( - IVAS_LIMITER_HANDLE *hLimiter_out, /* o : limiter struct handle */ - const int16_t num_channels, /* i : number of I/O channels */ - const int32_t sampling_rate /* i : sampling rate for processing */ -); - -void ivas_limiter_close( - IVAS_LIMITER_HANDLE* phLimiter /* i/o: pointer to limiter handle, can be NULL */ -); - -void ivas_limiter_dec -( - IVAS_LIMITER_HANDLE hLimiter, /* i/o: limiter struct handle */ - float *output[MAX_OUTPUT_CHANNELS], /* i/o: input/output buffer */ - const int16_t num_channels, /* i : number of channels to be processed */ - const int16_t output_frame, /* i : number of samples per channel in the buffer */ - const int16_t BER_detect /* i : BER detect flag */ -); void ivas_limiter_dec_fx( IVAS_LIMITER_HANDLE hLimiter, /* i/o: limiter struct handle */ Word32 *output[MAX_OUTPUT_CHANNELS], /* i/o: input/output buffer */ @@ -112,13 +101,7 @@ void ivas_limiter_dec_fx( const Word16 BER_detect, /* i : BER detect flag */ Word16 q_factor /* i : Q factor of the output samples */ ); -void limiter_process( - IVAS_LIMITER_HANDLE hLimiter, /* i/o: limiter struct handle */ - const int16_t output_frame, /* i : number of samples to be processed per channel in the I/O buffer */ - const float threshold, /* i : signal amplitude above which limiting starts to be applied */ - const int16_t BER_detect, /* i : BER detect flag */ - int16_t *strong_saturation_cnt /* i/o: counter of strong saturations (can be NULL) */ -); + void limiter_process_fx( IVAS_LIMITER_HANDLE hLimiter, /* i/o: limiter struct handle */ const Word16 output_frame, /* i : number of samples to be processed per channel in the I/O buffer */ @@ -132,9 +115,9 @@ void limiter_process_fx( *----------------------------------------------------------------------------------*/ ivas_error ivas_td_decorr_dec_open_fx( ivas_td_decorr_state_t **hTdDecorr, /* i/o: TD decorrelator handle */ - const int32_t output_Fs, /* i : output sampling rate */ - const int16_t nchan_internal, /* i : number of internal channels */ - const int16_t ducking_flag /* i : ducking flag */ + const Word32 output_Fs, /* i : output sampling rate */ + const Word16 nchan_internal, /* i : number of internal channels */ + const Word16 ducking_flag /* i : ducking flag */ ); void ivas_td_decorr_dec_close( ivas_td_decorr_state_t **hTdDecorr /* i/o: TD decorrelator handle */ @@ -171,9 +154,6 @@ ivas_error efap_init_data_fx( const Word16 num_speaker_nodes, /* i : number of speaker nodes in the set */ const Word16 efap_mode /* i : indicates whether EFAP or EFIP is used */ ); -void efap_free_data( - EFAP_HANDLE *hEFAPdata /* i/o: EFAP handle to be freed */ -); void efap_determine_gains_fx( EFAP_HANDLE hEFAPdata, /* i : EFAP structure */ @@ -216,14 +196,7 @@ void ivas_sba_prototype_renderer_fx( Word32 inRe_fx[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], /* i : Input audio in CLDFB domain, real */ Word32 inIm_fx[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], /* i : Input audio in CLDFB domain, imag */ Word16 q_cldfb[6][CLDFB_SLOTS_PER_SUBFRAME], - const int16_t subframe /* i : Subframe to render */ -); - -void ivas_sba_prototype_renderer( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder struct */ - float inRe[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], /* i : Input audio in CLDFB domain, real */ - float inIm[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], /* i : Input audio in CLDFB domain, imag */ - const int16_t subframe /* i : Subframe to render */ + const Word16 subframe /* i : Subframe to render */ ); ivas_error ivas_sba_get_hoa_dec_matrix_fx( @@ -236,11 +209,7 @@ void ivas_dirac_dec_binaural_sba_gain_fx( const Word16 nchan_remapped, /* i : num channels after remapping of TCs */ const Word16 output_frame /* i : output frame length */ ); -void ivas_dirac_dec_binaural_sba_gain( - float *output[], /* i/o: synthesized core-coder transport channels/DirAC output */ - const int16_t nchan_remapped, /* i : num channels after remapping of TCs */ - const int16_t output_frame /* i : output frame length */ -); + void ivas_dirac_dec_binaural_render_fx( Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */ const UWord16 nSamplesAsked, /* i : number of CLDFB slots requested */ @@ -253,7 +222,15 @@ void ivas_masa_ext_rend_parambin_render_fx( MASA_EXT_REND_HANDLE hMasaExtRend, /* i/o: MASA ext rend structure */ COMBINED_ORIENTATION_HANDLE hCombinedOrientationData, /* i : combined orientation handle */ Word32 *output_f[], /* i/o: synthesized core-coder transport channels/DirAC output Q11*/ - const Word16 num_subframes ); /* i : number of subframes to render */ +#ifdef SPLIT_REND_WITH_HEAD_ROT + const Word16 num_subframes, /* i : number of subframes to render */ + const SPLIT_REND_WRAPPER *hSplitRendWrapper, /* i : split rendering orientation data */ + Word32 Cldfb_Out_Real[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], /* o : rendered orientations for split rend. real part of cldfb */ + Word32 Cldfb_Out_Imag[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX] /* o : rendered orientations for split rend. imag part of cldfb */ +#else + const Word16 num_subframes /* i : number of subframes to render */ +#endif +); ivas_error ivas_dirac_dec_init_binaural_data_fx( Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ HRTFS_PARAMBIN_HANDLE hHrtfParambin /* i : HRTF structure for rendering */ @@ -266,11 +243,6 @@ ivas_error ivas_dirac_dec_binaural_copy_hrtfs_fx( HRTFS_PARAMBIN_HANDLE *hHrtfParambin /* i/o: HRTF structure for rendering */ ); -ivas_error ivas_dirac_dec_binaural_copy_hrtfs( - HRTFS_PARAMBIN_HANDLE *hHrtfParambin /* i/o: HRTF structure for rendering */ -); - - ivas_error ivas_dirac_alloc_mem_fx( DIRAC_REND_HANDLE hDirACRend, const RENDERER_TYPE renderer_type, @@ -278,20 +250,6 @@ ivas_error ivas_dirac_alloc_mem_fx( DIRAC_DEC_STACK_MEM_HANDLE hDirAC_mem, const Word16 hodirac_flag); -void ivas_dirac_free_mem( - DIRAC_DEC_STACK_MEM_HANDLE hDirAC_mem -); - -void initDiffuseResponses( - float *diffuse_response_function, - const int16_t num_channels, - const AUDIO_CONFIG output_config, - const IVAS_OUTPUT_SETUP hOutSetup, - const int16_t ambisonics_order, - const IVAS_FORMAT ivas_format, - int16_t *num_ele_spk_no_diffuse_rendering, - const AUDIO_CONFIG transport_config -); void ivas_dirac_free_mem_fx( DIRAC_DEC_STACK_MEM_HANDLE hDirAC_mem ); @@ -333,18 +291,6 @@ void protoSignalComputation_shd_fx( Word32 *p_Rmat_fx, /* Q30 */ Word16 q_cldfb ); -void protoSignalComputation_shd( - float RealBuffer[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], - float ImagBuffer[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], - float *proto_direct_buffer_f, - float *proto_diffuse_buffer_f, - float *reference_power, - const int16_t slot_index, - const int16_t num_inputs, - const int16_t num_outputs_diff, - const int16_t num_freq_bands, - float *p_Rmat -); void protoSignalComputation1_fx( Word32 RealBuffer_fx[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /*q_cldfb*/ @@ -362,17 +308,6 @@ void protoSignalComputation1_fx( const Word16 num_freq_bands, Word16 q_cldfb ); -void protoSignalComputation1( - float RealBuffer[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], - float ImagBuffer[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], - float *proto_frame_f, - float *proto_direct_buffer_f, - float *reference_power, - float *proto_power_smooth, - const int16_t slot_index, - const int16_t num_outputs_diff, - const int16_t num_freq_bands -); void protoSignalComputation2_fx( Word32 RealBuffer_fx[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /*q_cldfb*/ @@ -391,18 +326,6 @@ void protoSignalComputation2_fx( MASA_STEREO_TYPE_DETECT *stereo_type_detect, Word16 q_cldfb ); -void protoSignalComputation2( - float RealBuffer[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], - float ImagBuffer[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], - float *proto_frame_f, - float *proto_direct_buffer_f, - float *reference_power, - float *proto_power_smooth, - const int16_t isloudspeaker, - const int16_t slot_index, - const int16_t num_freq_bands, - MASA_STEREO_TYPE_DETECT *stereo_type_detect -); void protoSignalComputation4_fx( Word32 RealBuffer_fx[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /*q_cldfb*/ @@ -424,11 +347,6 @@ void protoSignalComputation4_fx( Word16 q_cldfb ); -void ivas_dirac_dec_compute_diffuse_proto( - DIRAC_REND_HANDLE hDirACRend, - const int16_t num_freq_bands, - const int16_t slot_idx -); void ivas_dirac_dec_compute_diffuse_proto_fx( DIRAC_REND_HANDLE hDirACRend, const Word16 num_freq_bands, @@ -445,10 +363,6 @@ void computeDirectionAngles_fx( Word16 *elevation ); -void ivas_masa_init_stereotype_detection( - MASA_STEREO_TYPE_DETECT *stereo_type_detect -); - void ivas_masa_init_stereotype_detection_fx( MASA_STEREO_TYPE_DETECT *stereo_type_detect ); @@ -456,9 +370,6 @@ void ivas_masa_init_stereotype_detection_fx( void ivas_masa_stereotype_detection_fx( MASA_STEREO_TYPE_DETECT *stereo_type_detect ); -void ivas_masa_stereotype_detection( - MASA_STEREO_TYPE_DETECT *stereo_type_detect -); void ivas_lfe_synth_with_cldfb_fx( MCMASA_LFE_SYNTH_DATA_HANDLE hMasaLfeSynth, @@ -479,21 +390,6 @@ void rotateAziEle_DirAC_fx( const Word16 band2, /* i : bands to work on (upper bound) */ const Word32 *p_Rmat_fx /* i : pointer to real-space rotation matrix q30*/ ); -void rotateAziEle_DirAC( - int16_t *azi, - int16_t *ele, - const int16_t band1, - const int16_t band2, - const float *p_Rmat -); - -ivas_error ivas_dirac_dec_onset_detection_open( - const int16_t num_channels, - const int16_t num_freq_bands, - const int16_t max_band_decorr, - DIRAC_ONSET_DETECTION_PARAMS *ph_dirac_onset_detection_params, - DIRAC_ONSET_DETECTION_STATE *ph_dirac_onset_detection_state -); ivas_error ivas_dirac_dec_onset_detection_open_fx( const Word16 num_protos_diff, //Q0 @@ -514,14 +410,6 @@ ivas_error ivas_dirac_dec_decorr_open_fx( const Word32 output_Fs /* i : output sampling rate */ ); -void ivas_dirac_dec_onset_detection_process( - const float *input_power_f, - float *onset_filter, - const int16_t num_protos_diff, - DIRAC_ONSET_DETECTION_PARAMS h_dirac_onset_detection_params, - DIRAC_ONSET_DETECTION_STATE h_dirac_onset_detection_state -); - void ivas_dirac_dec_onset_detection_process_fx( const Word32 *input_power_f, /* Q(0) */ Word32 *onset_filter, /* Q(0) */ @@ -530,33 +418,6 @@ void ivas_dirac_dec_onset_detection_process_fx( DIRAC_ONSET_DETECTION_STATE h_dirac_onset_detection_state ); -ivas_error ivas_dirac_dec_decorr_open( - DIRAC_DECORR_PARAMS **ph_freq_domain_decorr_ap_params, - DIRAC_DECORR_STATE **ph_freq_domain_decorr_ap_state, - const int16_t num_freq_bands, - int16_t num_outputs_diff, - const int16_t num_protos_diff, - const DIRAC_SYNTHESIS_CONFIG synthesisConf, - float *frequency_axis, - const int16_t nchan_transport, /* i : number of transport channels */ - const int32_t output_Fs /* i : output sampling rate */ -); - -void ivas_dirac_dec_decorr_process( - const int16_t num_freq_bands, - int16_t num_channels, - const int16_t num_protos_diff, - const DIRAC_SYNTHESIS_CONFIG synthesisConf, - const int16_t nchan_transport, /* i : number of transport channels */ - const float *input_frame_f, - const int16_t num_protos_dir, - const int16_t *proto_index_dir, - float *frame_dec_f, - float *onset_filter, - HANDLE_DIRAC_DECORR_PARAMS h_freq_domain_decorr_ap_params, - HANDLE_DIRAC_DECORR_STATE h_freq_domain_decorr_ap_state -); - void ivas_dirac_dec_decorr_process_fx( const Word16 num_freq_bands, Word16 num_channels, @@ -574,32 +435,11 @@ void ivas_dirac_dec_decorr_process_fx( HANDLE_DIRAC_DECORR_STATE h_freq_domain_decorr_ap_state ); -void ivas_dirac_dec_decorr_close( - HANDLE_DIRAC_DECORR_PARAMS *ph_dirac_decorr_params, - HANDLE_DIRAC_DECORR_STATE *ph_dirac_decorr_state -); void ivas_dirac_dec_decorr_close_fx( HANDLE_DIRAC_DECORR_PARAMS *ph_dirac_decorr_params, HANDLE_DIRAC_DECORR_STATE *ph_dirac_decorr_state ); - -ivas_error ivas_dirac_dec_output_synthesis_open( - SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom, /* i/o: common spatial renderer data handle */ - DIRAC_REND_HANDLE hDirACRend, /* i/o: DirAC renderer handle */ - const RENDERER_TYPE renderer_type, /* i : renderer type */ - const int16_t nchan_transport, /* i : number of transport channels */ - const int32_t output_Fs, /* i : output sampling rate */ - const int16_t hodirac_flag /* i : flag to indicate HO-DirAC mode */ -); - -void ivas_dirac_dec_output_synthesis_init( - 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 nchan_out_woLFE, /* i : number of output audio channels without LFE */ - const int16_t hodirac_flag /* i : flag to indicate HO-DirAC mode */ -); - ivas_error ivas_dirac_dec_output_synthesis_open_fx( SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom, /* i/o: common spatial renderer data handle */ DIRAC_REND_HANDLE hDirACRend, /* i/o: DirAC renderer handle */ @@ -619,9 +459,7 @@ void ivas_dirac_dec_output_synthesis_init_fx( void ivas_dirac_dec_output_synthesis_close_fx( DIRAC_REND_HANDLE hDirACRend /* i/o: DirAC handle */ ); -void ivas_dirac_dec_output_synthesis_close( - DIRAC_REND_HANDLE hDirACRend /* i/o: DirAC handle */ -); + void ivas_dirac_dec_output_synthesis_process_slot_fx( const Word32 *reference_power, /* i : Estimated power */ const Word16 q_reference_power, /* i : Estimated power */ @@ -640,23 +478,6 @@ void ivas_dirac_dec_output_synthesis_process_slot_fx( const Word16 md_idx, const Word16 hodirac_flag, /* i : flag to indicate HO-DirAC mode */ const Word16 dec_param_estim); -void ivas_dirac_dec_output_synthesis_process_slot( - const float *reference_power, /* i : Estimated power */ - const float *onset, /* i : onset filter */ - const int16_t *azimuth, - const int16_t *elevation, - 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 int16_t ind_slot, /* i : index of the slot to be added to the input covariance */ - const int16_t hodirac_flag, /* i : flag to indicate HO-DirAC mode */ - const int16_t dec_param_estim /* i : flag to indicate parameter estimation mode */ -); void ivas_dirac_dec_output_synthesis_process_subframe_gain_shd_fx( Word32 RealBuffer[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX],/* i : LS signals */ @@ -673,19 +494,6 @@ void ivas_dirac_dec_output_synthesis_process_subframe_gain_shd_fx( Word16 *q_cy_auto_diff_smooth_prev ); -void ivas_dirac_dec_output_synthesis_process_subframe_gain_shd( - float RealBuffer[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX],/* i : LS signals */ - float ImagBuffer[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX],/* i : LS signals */ - 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 nchan_transport, /* i : number of transport channels */ - const int16_t nbslots, /* i : number of slots to process */ - const float *onset_filter, - float *diffuseness, - const int16_t hodirac_flag, /* i : flag to indicate HO-DirAC mode */ - const int16_t dec_param_estim /* i : flag to indicate parameter estimation mode */ -); - void ivas_dirac_dec_output_synthesis_process_subframe_psd_ls_fx( Word32 RealBuffer[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX],/* i : LS signals */ Word32 ImagBuffer[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX],/* i : LS signals */ @@ -700,25 +508,6 @@ void ivas_dirac_dec_output_synthesis_process_subframe_psd_ls_fx( Word16 *q_Cldfb ); -void ivas_dirac_dec_output_synthesis_process_subframe_psd_ls( - float RealBuffer[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX],/* i : LS signals */ - float ImagBuffer[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX],/* i : LS signals */ - 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 nbslots, /* i : number of slots to process */ - float *diffuseness_vector, /* i : diffuseness (needed for direction smoothing)*/ - float *reference_power_smooth, - float qualityBasedSmFactor, - const int16_t enc_param_start_band -); - -void compute_hoa_encoder_mtx( - const float *azimuth, - const float *elevation, - float *response, - const int16_t num_responses, - const int16_t ambisonics_order ); - void compute_hoa_encoder_mtx_fx( const Word32 *azimuth, /*q22*/ const Word32 *elevation, /*q22*/ @@ -743,21 +532,6 @@ void ivas_dirac_dec_compute_power_factors_fx( Word32 *diffuse_power_factor ); -void ivas_dirac_dec_compute_directional_responses( - SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom, /* i/o: common spatial renderer data handle */ - DIRAC_REND_HANDLE hDirACRend, /* i/o: DirAC renderer handle */ - const VBAP_HANDLE hVBAPdata, /* i : VBAP structure */ - const int16_t *masa_band_mapping, /* i : Band mapping for MASA, NULL assumes not using MASA in any form */ - MASA_ISM_DATA_HANDLE hMasaIsm, /* i : MASA_ISM data structure */ - const int16_t *azimuth, - 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 */ -); - void ivas_dirac_dec_compute_directional_responses_fx( SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom, /* i/o: common spatial renderer data handle */ DIRAC_REND_HANDLE hDirACRend, /* i/o: DirAC renderer handle */ @@ -774,36 +548,6 @@ void ivas_dirac_dec_compute_directional_responses_fx( const Word16 hodirac_flag /* i : flag to indicate HO-DirAC mode */ ); -void ivas_dirac_dec_get_frequency_axis( - float *frequency_axis, /* o : array of center frequencies of a real filter bank */ - const int32_t output_Fs, /* i : sampling frequency */ - const int16_t num_freq_bands /* i : number of frequency bands */ -); - -ivas_error ivas_spat_hSpatParamRendCom_config( - SPAT_PARAM_REND_COMMON_DATA_HANDLE *hSpatParamRendCom_out, - const DIRAC_CONFIG_FLAG flag_config_inp, /* i/ : Flag determining if we open or reconfigure the DirAC decoder */ - const int16_t dec_param_estim_flag, - const IVAS_FORMAT ivas_format, - const MC_MODE mc_mode, - const int32_t output_Fs, - const int16_t hodirac_flag, - const int16_t masa_ext_rend_flag -); - -void ivas_spat_hSpatParamRendCom_close( - SPAT_PARAM_REND_COMMON_DATA_HANDLE *hSpatParamRendCom_out -); - -void ivas_dirac_rend_close( - DIRAC_REND_HANDLE *hDirACRend_out -); - -ivas_error ivas_dirac_allocate_parameters( - SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom, /* i/o: common data for spatial parametric rendering */ - const int16_t params_flag /* i : set of parameters flag */ -); - void ivas_dirac_rend_close_fx( DIRAC_REND_HANDLE *hDirACRend_out ); @@ -825,18 +569,14 @@ ivas_error ivas_spat_hSpatParamRendCom_config_fx( ivas_error ivas_dirac_allocate_parameters_fx( SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom, /* i/o: common data for spatial parametric rendering */ - const int16_t params_flag /* i : set of parameters flag */ + const Word16 params_flag /* i : set of parameters flag */ ); void ivas_dirac_deallocate_parameters_fx( SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom, /* i/o: common data for spatial parametric rendering */ - const int16_t params_flag /* i : set of parameters flag */ + const Word16 params_flag /* i : set of parameters flag */ ); -void ivas_dirac_deallocate_parameters( - SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom, /* i/o: common data for spatial parametric rendering */ - const int16_t params_flag /* i : set of parameters flag */ -); void ivas_masa_ext_dirac_render_fx( MASA_EXT_REND_HANDLE hMasaExtRend, /* i/o: MASA renderer structure */ Word32 *output_f[], /* i/o: input/output signals in time domain q11*/ @@ -854,11 +594,6 @@ void ivas_HRTF_binary_close_fx( TDREND_HRFILT_FiltSet_t **hHrtfTD /* i/o: TD renderer HRTF handle */ ); -ivas_error ivas_HRTF_fastconv_binary_open( - HRTFS_FASTCONV **hHrtfFastConv /* i/o: FASTCONV HRTF structure */ -); - - ivas_error ivas_HRTF_fastconv_binary_open_fx( HRTFS_FASTCONV **hHrtfFastConv /* i/o: FASTCONV HRTF structure */ ); @@ -902,33 +637,6 @@ ivas_error ivas_td_binaural_renderer_unwrap_fx( const Word16 num_subframes /* i : number of subframes to render */ ); -ivas_error ivas_td_binaural_renderer_unwrap( - const REVERB_HANDLE hReverb, /* i : Reverberator handle */ - const AUDIO_CONFIG transport_config, /* i : Transport configuration */ - BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, /* i/o: TD binaural object renderer handle */ - const int16_t num_src, /* i : number of sources to render */ - const int16_t lfe_idx, /* i : LFE channel index */ - const IVAS_FORMAT ivas_format, /* i : IVAS format */ - ISM_METADATA_HANDLE *hIsmMetaData, /* i : ISM metadata handle */ - COMBINED_ORIENTATION_HANDLE hCombinedOrientationData, /* i/o: combined orientaton data handle */ - const int16_t ism_md_subframe_update, - float *output[], /* i/o: SCE channels / Binaural synthesis */ - const int16_t output_frame, /* i : output frame length */ - const int16_t num_subframes /* i : number of subframes to render */ -); - -ivas_error ivas_td_binaural_renderer_ext( - const TDREND_WRAPPER *pTDRend, /* i : TD Renderer wrapper structure */ - const AUDIO_CONFIG inConfig, /* i : Input audio configuration */ - const LSSETUP_CUSTOM_STRUCT *customLsInput, /* i : Input custom loudspeaker layout */ - const COMBINED_ORIENTATION_HANDLE *hCombinedOrientationData,/* i : Combined head and external orientations */ - const IVAS_ISM_METADATA *currentPos, /* i : Object position */ - const REVERB_HANDLE hReverb, /* i : Reverberator handle */ - const int16_t ism_md_subframe_update_ext, /* i : Metadata Delay in subframes to sync with audio delay */ - const int32_t output_Fs, /* i : output sampling rate */ - const int16_t output_frame, /* i : output frame length */ - float output[][L_FRAME48k] /* i/o: SCE channels / Binaural synthesis */ -); ivas_error ivas_td_binaural_renderer_ext_fx( const TDREND_WRAPPER *pTDRend, /* i : TD Renderer wrapper structure */ const AUDIO_CONFIG inConfig, /* i : Input audio configuration */ @@ -956,24 +664,12 @@ ivas_error ivas_td_binaural_open_unwrap_fx( Word16 *SrcInd ); -ivas_error ivas_td_binaural_open_unwrap( - TDREND_HRFILT_FiltSet_t **hHrtfTD, /* i/o: HR filter model (from file or NULL) */ - const int32_t output_Fs, /* i : Output sampling rate */ - const int16_t nchan_transport, /* i : Number of channels */ - const IVAS_FORMAT ivas_format, /* i : IVAS format (ISM/MC) */ - const AUDIO_CONFIG transport_config, /* i : Transport configuration */ - const float *directivity, /* i : Directivity pattern (used for ISM) */ - const IVAS_OUTPUT_SETUP hTransSetup, /* i : Loudspeaker layout */ - BINAURAL_TD_OBJECT_RENDERER_HANDLE *hBinRendererTd, /* o : TD renderer handle */ - int32_t *binaural_latency_ns /* i : Binauralization delay */ -); - ivas_error ivas_td_binaural_open_ext_fx( TDREND_WRAPPER *pTDRend, const AUDIO_CONFIG inConfig, RENDER_CONFIG_DATA *hRendCfg, /* i : Renderer configuration */ LSSETUP_CUSTOM_STRUCT *customLsInput, - const int32_t output_Fs, + const Word32 output_Fs, Word16 *SrcInd, Word16 *num_src ); @@ -982,17 +678,6 @@ void ivas_td_binaural_close_fx( BINAURAL_TD_OBJECT_RENDERER_HANDLE *hBinRendererTd /* i/o: TD binaural object renderer handle */ ); -void ivas_td_binaural_close( - BINAURAL_TD_OBJECT_RENDERER_HANDLE *hBinRendererTd /* i/o: TD binaural object renderer handle */ -); - -ivas_error TDREND_GetMix( - BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, /* i/o: TD renderer handle */ - float *output[], /* i/o: ISM object synth/rendered output in 0,1 */ - const int16_t subframe_length, /* i/o: subframe length */ - const int16_t subframe_idx, /* i : Subframe index to 5 ms subframe */ - const int16_t ism_md_subframe_update /* i : Number of subframes to delay metadata to sync with audio */ -); ivas_error TDREND_GetMix_fx( BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, /* i/o: TD renderer handle */ Word32 *output[], /* i/o: ISM object synth / rendered output in 0,1 */ @@ -1001,13 +686,6 @@ ivas_error TDREND_GetMix_fx( const Word16 ism_md_subframe_update /* i : Number of subframes to delay ism metadata to sync with audio */ ); - -ivas_error TDREND_Update_object_positions( - BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, /* i/o: TD Renderer handle */ - const int16_t num_src, /* i : number of sources to render */ - const IVAS_FORMAT in_format, /* i : Format of input sources */ - const ISM_METADATA_HANDLE *hIsmMetaData /* i : Input metadata for ISM objects */ -); void BSplineModelEvalDealloc_fx( ModelParams_t *model, /* i : Model parameters */ ModelEval_t *modelEval /* i : Model evaluation structure */ @@ -1049,16 +727,7 @@ ivas_error TDREND_MIX_SRC_SetPos_fx( const Word16 SrcInd, /* i : Source index */ const Word32 *Vec_p /* i : Position vector */ ); -ivas_error TDREND_MIX_SRC_SetPos( - BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, /* i/o: TD renderer handle */ - const int16_t SrcInd, /* i : Source index */ - const float *Vec_p /* i : Position vector */ -); -ivas_error TDREND_MIX_SRC_SetDir( - BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, /* i/o: TD renderer handle */ - const int16_t SrcInd, /* i : Source index */ - const float *Vec_p /* i : Direction vector */ -); + ivas_error TDREND_MIX_SRC_SetDir_fx( BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, /* i/o: TD renderer handle */ const Word16 SrcInd, /* i : Source index */ @@ -1108,19 +777,8 @@ void TDREND_SRC_Init_fx( TDREND_SRC_t *Src_p, /* i/o: Source to initialize */ const TDREND_PosType_t PosType /* i : Position type specifier */ ); -void TDREND_SRC_Init( - TDREND_SRC_t *Src_p, /* i/o: Source to initialize */ - const TDREND_PosType_t PosType /* i : Position type specifier */ -); /* ----- Object renderer - vec ----- */ - -void TDREND_SPATIAL_VecInit( - float *Pos_p, /* o : Output vector */ - const float PosX, /* i : X value */ - const float PosY, /* i : Y value */ - const float PosZ /* i : Z value */ -); void TDREND_SPATIAL_VecInit_fx( Word32 *Pos_p, /* o : Output vector */ const Word32 PosX, /* i : X value */ @@ -1136,21 +794,6 @@ void TDREND_SPATIAL_VecNormalize_fx( Word32 *VecNorm_p_fx /* o : Normalised output vector Q30 */ ); -void TDREND_SPATIAL_VecNormalize( - const float *Vec_p, /* i : Input vector */ - float *VecNorm_p /* o : Output vector */ -); - -void TDREND_SPATIAL_VecMapToNewCoordSystem( - const float *Vec_p, /* i : Input vector */ - const float *TranslVec_p, /* i : Translation vector */ - const float *DirVec_p, /* i : Direction vector */ - const float *UpVec_p, /* i : Up vector */ - const float *RightVec_p, /* i : Right vector */ - float *MappedVec_p, /* o : Transformed vector */ - float *LisRelPosAbs /* o : Transformed vector ignoring orientation */ -); - Word16 TDREND_SPATIAL_EvalOrthonormOrient_fx( Word32 *FrontVecON_p_fx, /* i/o: Normalized front vector Q30 */ Word32 *UpVecON_p_fx, /* i/o: Normalized up vector Q30 */ @@ -1159,14 +802,6 @@ Word16 TDREND_SPATIAL_EvalOrthonormOrient_fx( const Word32 *UpVec_p_fx, /* i : Input up vector orient_q */ const Word16 orient_q /* i : Input up Q-factor */ ); -/*! r: Flag if the orientation has been updated */ -int16_t TDREND_SPATIAL_EvalOrthonormOrient( - float *FrontVecON_p, /* o : Normalized front vector */ - float *UpVecON_p, /* o : Normalized up vector */ - float *RightVecON_p, /* o : Normalized right vector */ - const float *FrontVec_p, /* i : Input front vector */ - const float *UpVec_p /* i : Input up vector */ -); /* ----- Object renderer - mix ----- */ @@ -1175,11 +810,6 @@ ivas_error TDREND_MIX_AddSrc_fx( Word16 *SrcInd, /* o : Source index */ const TDREND_PosType_t PosType /* i : Position type (absolute/relative) */ ); -ivas_error TDREND_MIX_AddSrc( - BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, /* i/o: TD renderer handle */ - int16_t *SrcInd, /* o : Source index */ - const TDREND_PosType_t PosType /* i : Position type (absolute/relative) */ -); ivas_error TDREND_MIX_SetDistAttenModel( BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, /* i/o: TD renderer handle */ @@ -1190,35 +820,15 @@ void TDREND_MIX_Dealloc_fx( BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd /* i/o: TD renderer handle */ ); -void TDREND_MIX_Dealloc( - BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd /* i/o: TD renderer handle */ -); - ivas_error TDREND_MIX_Init_fx( BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, /* i/o: TD renderer handle */ TDREND_HRFILT_FiltSet_t **hHrtfTD, /* i/o: HRTF data (initialized in case of NULL) */ const TDREND_MixSpatSpec_t *MixSpatSpec_p, /* i : Mixer spatial specification */ const Word32 output_Fs /* i : Output sampling rate */ ); -ivas_error TDREND_MIX_Init( - BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, /* i/o: TD renderer handle */ - TDREND_HRFILT_FiltSet_t **hHrtfTD, /* i/o: HRTF data (initialized in case of NULL) */ - const TDREND_MixSpatSpec_t *MixSpatSpec_p, /* i : Mixer spatial specification */ - const int32_t output_Fs /* i : Output sampling rate */ -); /* ----- Object renderer - sfx ----- */ -void TDREND_Apply_ITD( - float *input, /* i : Input SCE subframe to be time adjusted */ - float *out_left, /* o : Output left channels with ITD applied */ - float *out_right, /* o : Output right channels with ITD applied */ - int16_t *previtd, /* i/o: Previous ITD value */ - const int16_t itd, /* i : Current subframe ITD value */ - float *mem_itd, /* i/o: ITD buffer memory */ - const int16_t length /* i : Subframe length */ -); - void TDREND_Apply_ITD_fx( Word32 *input_fx, /* i : Input subframe to be time adjusted Qx */ Word32 *out_left_fx, /* o : Output left channel with ITD applied Qx */ @@ -1253,11 +863,21 @@ ivas_error ivas_rend_openCrend( const AUDIO_CONFIG outConfig, RENDER_CONFIG_DATA *hRendCfg, HRTFS_CREND_HANDLE hSetOfHRTF, +#ifdef SPLIT_REND_WITH_HEAD_ROT + const Word32 output_Fs, + const Word16 num_poses +#else const Word32 output_Fs +#endif ); void ivas_rend_closeCrend( +#ifdef SPLIT_REND_WITH_HEAD_ROT + CREND_WRAPPER_HANDLE *pCrend , + const Word16 num_poses +#else CREND_WRAPPER_HANDLE *pCrend +#endif ); ivas_error ivas_hrtf_init( @@ -1265,7 +885,12 @@ ivas_error ivas_hrtf_init( ); ivas_error ivas_rend_initCrendWrapper( +#ifdef SPLIT_REND_WITH_HEAD_ROT + CREND_WRAPPER_HANDLE *pCrend, + const Word16 num_poses +#else CREND_WRAPPER_HANDLE *pCrend +#endif ); ivas_error ivas_rend_crendProcess( const CREND_WRAPPER *pCrend, @@ -1277,7 +902,12 @@ ivas_error ivas_rend_crendProcess( EFAP_HANDLE hEFAPdata, Word32 *output[], /* i/o: input/output audio channels */ const Word32 output_Fs, +#ifdef SPLIT_REND_WITH_HEAD_ROT + const Word16 num_subframes, /* i : number of subframes to render */ + const Word16 pos_idx /* i : pose index */ +#else const Word16 num_subframes /* i : number of subframes to render */ +#endif ); ivas_error ivas_rend_crendProcessSubframe( const CREND_WRAPPER *pCrend, /* i/o: Crend wrapper handle */ @@ -1292,6 +922,10 @@ ivas_error ivas_rend_crendProcessSubframe( Word32 *output[], /* i/o: input/output audio channels */ const Word16 n_samples_to_render, /* i : output frame length per channel */ const Word32 output_Fs /* i : output sampling rate */ +#ifdef SPLIT_REND_WITH_HEAD_ROT + , + const Word16 pos_idx +#endif ); @@ -1311,10 +945,10 @@ ivas_error ivas_binaural_reverb_open_fastconv_fx( 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 Q0 */ - const int16_t numCldfbSlotsPerFrame, /* i : number of CLDFB slots per frame Q0 */ + const Word16 numBins, /* i : number of CLDFB bins Q0 */ + const Word16 numCldfbSlotsPerFrame, /* i : number of CLDFB slots per frame Q0 */ IVAS_ROOM_ACOUSTICS_CONFIG_DATA *roomAcoustics, /* i/o: room acoustics parameters */ - const int32_t sampling_rate, /* i : sampling rate Q0 */ + const Word32 sampling_rate, /* i : sampling rate Q0 */ const HRTFS_PARAMBIN_HANDLE hHrtfParambin /* i : Parametric binauralizer HRTF handle */ ); @@ -1325,16 +959,6 @@ void ivas_binaural_reverb_close( REVERB_STRUCT_HANDLE *hReverb /* i/o: binaural reverb handle */ ); -void ivas_binaural_reverb_processSubframe( - REVERB_STRUCT_HANDLE hReverb, /* i/o: binaural reverb handle */ - const int16_t numInChannels, /* i : num input channels to be processed*/ - const int16_t numSlots, /* i : number of slots to be processed */ - float inReal[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], /* i : input CLDFB data real */ - float inImag[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], /* i : input CLDFB data imag */ - float outReal[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], /* o : output CLDFB data real */ - float outImag[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX] /* o : output CLDFB data imag */ -); - void ivas_binaural_reverb_processSubframe_fx( REVERB_STRUCT_HANDLE hReverb, /* i/o: binaural reverb handle */ const Word16 numInChannels, /* i : num inputs to be processed */ @@ -1365,14 +989,7 @@ ivas_error ivas_reverb_process_fx( Word32 *pcm_out[], /* o : the PCM audio with reverb applied */ const Word16 i_ts /* i : (Q0) subframe index */ ); -ivas_error ivas_reverb_process( - const REVERB_HANDLE hReverb, /* i : Reverberator handle */ - const AUDIO_CONFIG input_audio_config, /* i : reverb. input audio configuration */ - const int16_t mix_signals, /* i : add reverb to output signal */ - float *pcm_in[], /* i : the PCM audio to apply reverb on */ - float *pcm_out[], /* o : the PCM audio with reverb applied */ - const int16_t i_ts /* i : subframe index */ -); + void ivas_rev_delay_line_init( ivas_rev_delay_line_t *pDelay, /* o : the delay line to initialize */ Word32 *memory_buffer, /* i : the memory buffer to use for the delay line Q11 */ @@ -1402,7 +1019,7 @@ void ivas_rev_delay_line_feed_sample_blk_fx( ); void ivas_reverb_iir_filt_init( ivas_rev_iir_filter_t *iirFilter, /* o : IIR filter */ - const uint16_t maxTaps /* i : maximum number of filter taps */ + const UWord16 maxTaps /* i : maximum number of filter taps */ ); @@ -1461,17 +1078,6 @@ void ivas_reverb_fft_filter_CrossMix_fx( const Word16 fft_size ); -void ivas_reverb_fft_filter_CrossMix( - float *buffer0, - float *buffer1, - const int16_t fft_size -); - -void ivas_reverb_fft_filter_ConvertFFTWF_2_FFTR( - rv_fftwf_type_complex *spectrum, - float *fft_real, - const int16_t fft_size -); void ivas_reverb_fft_filter_ConvertFFTWF_2_FFTR_fx( rv_fftwf_type_complex_fx *spectrum, // i: Qx Word32 *fft_real, // o: Qx @@ -1612,11 +1218,8 @@ void ivas_headTrack_close_fx( HEAD_TRACK_DATA_HANDLE *hHeadTrackData /* i/o: head track handle */ ); -void Euler2Quat( - const float yaw, /* i : yaw (x) */ - const float pitch, /* i : pitch (y) */ - const float roll, /* i : roll (z) */ - IVAS_QUATERNION *quat /* o : quaternion describing the rotation */ +float rad2deg( + float radians ); void Euler2Quat_fx( const Word32 yaw, /* i : yaw (x) Q22 */ @@ -1624,35 +1227,15 @@ void Euler2Quat_fx( const Word32 roll, /* i : roll (z) Q22 */ IVAS_QUATERNION *quat /* o : quaternion describing the rotation */ ); -float deg2rad( - float degrees -); Word32 deg2rad_fx( Word32 degrees ); -float rad2deg( - float radians -); Word32 rad2deg_fx( Word32 radians ); -void QuatToRotMat( - const IVAS_QUATERNION quat, /* i : quaternion describing the rotation */ - float Rmat[3][3] /* o : real-space rotation matrix for this rotation */ -); - - -void rotateAziEle( - float azi_in, /* i : output elevation */ - float ele_in, /* i : input elevation */ - int16_t *azi, /* o : rotated azimuth */ - int16_t *ele, /* o : rotated elevation */ - float Rmat[3][3], /* i : real-space rotation matrix */ - const int16_t isPlanar /* i : is roation planar and elevation meaningless? */ -); void rotateAziEle_fx( Word16 azi_in, /* i : output elevation */ Word16 ele_in, /* i : input elevation */ @@ -1726,21 +1309,21 @@ void rotateFrame_sd_cldfb_fixed( Word32 Cldfb_ImagBuffer[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* i/o: unrotated HOA3 signal buffer in cldfb domain imag part */ const IVAS_OUTPUT_SETUP_HANDLE hOutputSetup, /* i : output format setup number of channels */ const EFAP_HANDLE hEFAPdata, /* i : EFAP structure */ - const int16_t numTimeSlots, /* i : number of time slots to process */ - const int16_t nb_band /* i : number of CLDFB bands to process */ + const Word16 numTimeSlots, /* i : number of time slots to process */ + const Word16 nb_band /* i : number of CLDFB bands to process */ ); ivas_error ivas_external_orientation_open( EXTERNAL_ORIENTATION_HANDLE *hExtOrientationData, /* o : external orientation handle */ - const int16_t num_subframes /* i : number of subframes */ + const Word16 num_subframes /* i : number of subframes */ ); void ivas_external_orientation_close_fx( EXTERNAL_ORIENTATION_HANDLE *hExtOrientationData /* i/o: external orientation handle */ ); ivas_error ivas_combined_orientation_open( COMBINED_ORIENTATION_HANDLE *hCombinedOrientationData, /* o : combined orientation handle */ - const int32_t fs, /* i : sampling rate */ - const int16_t num_subframes /* i : number of subframes */ + const Word32 fs, /* i : sampling rate */ + const Word16 num_subframes /* i : number of subframes */ ); void ivas_combined_orientation_close_fx( COMBINED_ORIENTATION_HANDLE *hCombinedOrientationData /* i/o: combined orientation handle */ @@ -1800,34 +1383,6 @@ void QuaternionSlerp_fx( * Orientation tracking *----------------------------------------------------------------------------------*/ -ivas_error ivas_orient_trk_Init( - ivas_orient_trk_state_t *pOTR /* i/o: orientation tracker handle */ -); - -ivas_error ivas_orient_trk_SetTrackingType( - ivas_orient_trk_state_t *pOTR, /* i/o: orientation tracker handle */ - const IVAS_HEAD_ORIENT_TRK_T orientation_tracking /* i : orientation tracking type */ -); - -ivas_error ivas_orient_trk_SetReferenceRotation( - ivas_orient_trk_state_t *pOTR, /* i/o: orientatoin trakcer handle */ - const IVAS_QUATERNION refRot /* i : reference rotation */ -); - - -ivas_error ivas_orient_trk_GetTrackedRotation( - ivas_orient_trk_state_t *pOTR, /* i/o: orientation tracker handle */ - IVAS_QUATERNION *pRotation /* i/o: processed rotation */ -); - -ivas_error ivas_orient_trk_Process( - ivas_orient_trk_state_t *pOTR, /* i/o: orientation tracker handle */ - IVAS_QUATERNION absRot, /* i : absolute head rotation */ - float updateRate, /* i : rotation update rate [Hz] */ - IVAS_QUATERNION *pTrkRot /* o : tracked rotation */ -); - - ivas_error ivas_orient_trk_Init_fx( ivas_orient_trk_state_t *pOTR /* i/o: orientation tracker handle */ ); @@ -1872,7 +1427,7 @@ ivas_error ivas_orient_trk_Process_fx( ivas_error ivas_mcmasa_ana_open( MCMASA_ANA_HANDLE *hMcMasaPtr, /* i/o: McMASA data handle pointer */ const AUDIO_CONFIG inConfig, /* i : Input config */ - int32_t input_Fs /* i : Sampling frequency */ + Word32 input_Fs /* i : Sampling frequency */ ); void ivas_mcmasa_ana_fx( MCMASA_ANA_HANDLE hMcMasa, /* i/o: McMASA encoder handle */ @@ -1893,14 +1448,6 @@ ivas_error ivas_omasa_ana_open( UWord16 total_num_objects /* i : Number of objects */ ); -void ivas_omasa_ana( - OMASA_ANA_HANDLE hOMasa, /* i/o: OMASA analysis handle */ - float data_in_f[][L_FRAME48k], /* i/o: Input / transport audio signals */ - const int16_t input_frame, /* i : Input frame size */ - const int16_t nchan_transport, /* i : Number of transport channels */ - const int16_t nchan_ism /* i : Number of objects for parameter analysis*/ -); - void ivas_omasa_ana_fx( OMASA_ANA_HANDLE hOMasa, /* i/o: OMASA analysis handle */ Word32 data_in_f_fx[][L_FRAME48k], /* i/o: Input / transport audio signals */ @@ -1920,13 +1467,7 @@ void computeIntensityVector_ana_fx( const Word16 num_frequency_bands, /* i : Number of frequency bands */ Word32 intensity_real[DIRAC_NUM_DIMS][MASA_FREQUENCY_BANDS] /* o : Intensity vector 2 * Qx -31 */ ); -void computeIntensityVector_ana( - const int16_t *band_grouping, /* i : Band grouping for estimation */ - float Cldfb_RealBuffer[FOA_CHANNELS][CLDFB_NO_CHANNELS_MAX], /* i : Real part of input signal */ - float Cldfb_ImagBuffer[FOA_CHANNELS][CLDFB_NO_CHANNELS_MAX], /* i : Imag part of input signal */ - const int16_t num_frequency_bands, /* i : Number of frequency bands */ - float intensity_real[DIRAC_NUM_DIMS][MASA_FREQUENCY_BANDS] /* o : Intensity vector */ -); + void computeReferencePower_ana_fx( const Word16 *band_grouping, /* i : Band grouping for estimation */ Word32 Cldfb_RealBuffer[FOA_CHANNELS][CLDFB_NO_CHANNELS_MAX], /* i : Real part of input signal input_q */ @@ -1934,13 +1475,6 @@ void computeReferencePower_ana_fx( Word32 *reference_power, /* o : Estimated power */ const Word16 num_freq_bands /* i : Number of frequency bands 2 * input_q - 31 */ ); -void computeReferencePower_ana( - const int16_t *band_grouping, /* i : Band grouping for estimation */ - float Cldfb_RealBuffer[FOA_CHANNELS][CLDFB_NO_CHANNELS_MAX], /* i : Real part of input signal */ - float Cldfb_ImagBuffer[FOA_CHANNELS][CLDFB_NO_CHANNELS_MAX], /* i : Imag part of input signal */ - float *reference_power, /* o : Estimated power */ - const int16_t num_freq_bands /* i : Number of frequency bands */ -); void ivas_create_masa_out_meta_fx( MASA_DECODER_EXT_OUT_META_HANDLE extOutMeta, /* i/o: MASA metadata handle */ @@ -1956,17 +1490,6 @@ void ivas_create_masa_out_meta_fx( Word16 surroundingCoherence_q ); -void ivas_create_masa_out_meta( - MASA_DECODER_EXT_OUT_META_HANDLE extOutMeta, /* i/o: MASA metadata handle */ - SPHERICAL_GRID_DATA *Sph_Grid16, /* i : Spherical grid */ - const int16_t nchan_transport, /* i : Number of transport channels */ - float elevation_m_values[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], /* i : Estimated elevation */ - float azimuth_m_values[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], /* i : Estimated azimuth */ - float energyRatio[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], /* i : Estimated direct-to-total ratio */ - float spreadCoherence[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], /* i : Estimated spread coherence */ - float surroundingCoherence[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS] /* i : Estimated surround coherence */ -); - ivas_error ivas_dirac_ana_open_fx( DIRAC_ANA_HANDLE *hDirACPtr, /* i/o: DIRAC data handle pointer */ Word32 input_Fs @@ -1995,11 +1518,6 @@ void ivas_prerend_merge_masa_metadata_fx( Word16 *inEne2_e /* i : TF-energy of input 2 Exponent */ ); -void copy_masa_descriptive_meta( - MASA_DECRIPTIVE_META *outMeta, /* o : metadata to be written */ - MASA_DECRIPTIVE_META *inMeta /* i : input metadata */ -); - ivas_error masaPrerendOpen_fx( MASA_PREREND_HANDLE *hMasaPrerendPtr, /* o : handle to the opened prerenderer */ Word16 numTransports, /* i : number of transport channels */ @@ -2009,6 +1527,86 @@ void masaPrerendClose_fx( MASA_PREREND_HANDLE *hMasaPrerendPtr /* i/o: prerenderer handle to be closed */ ); +#ifdef SPLIT_REND_WITH_HEAD_ROT +/*----------------------------------------------------------------------------------* + * Split rendering + *----------------------------------------------------------------------------------*/ + +ivas_error ivas_td_binaural_renderer_sf_splitBinaural( + Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ + Word32 *output[], /* i/o: SCE channels / Binaural synthesis */ + const int16_t nSamplesRendered /* i : number of samples to render */ +); + +ivas_error ivas_rend_crendProcessSubframesSplitBin( + const CREND_WRAPPER *pCrend, /* i/o: Crend wrapper handle */ + const AUDIO_CONFIG inConfig, /* i : input audio configuration */ + const AUDIO_CONFIG outConfig, /* i : output audio configuration */ + const MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, + const DECODER_CONFIG_HANDLE hDecoderConfig, /* i : decoder config. structure */ + const COMBINED_ORIENTATION_HANDLE hCombinedOrientationData, /* i : combined orientation handle */ + const IVAS_OUTPUT_SETUP_HANDLE hIntSetup, /* i : internal setup handle */ + const EFAP_HANDLE hEFAPdata, /* i : EFAP handle */ + DECODER_TC_BUFFER_HANDLE hTcBuffer, /* i/o: JBM handle */ + Word32 *input_f[], /* i : transport channels */ + Word32 *output[], /* i/o: input/output audio channels */ + const Word16 n_samples_to_render, /* i : output frame length per channel */ + const Word32 output_Fs /* i : output sampling rate */ +); + +ivas_error ivas_rend_crendProcessSplitBin( + const CREND_WRAPPER *pCrend, + const AUDIO_CONFIG inConfig, + const AUDIO_CONFIG outConfig, + const MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, + const DECODER_CONFIG_HANDLE hDecoderConfig, + const COMBINED_ORIENTATION_HANDLE hCombinedOrientationData, + const IVAS_OUTPUT_SETUP_HANDLE hIntSetup, + EFAP_HANDLE hEFAPdata, + Word32 *output[], + const Word32 output_Fs +); + +ivas_error ivas_rend_openMultiBinCrend( + CREND_WRAPPER_HANDLE *pCrend, + const AUDIO_CONFIG inConfig, + const AUDIO_CONFIG outConfig, + const MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, + const Word32 output_Fs +); + +void ivas_rend_CldfbMultiBinRendProcess( + const BINAURAL_RENDERER_HANDLE hCldfbRend, + const COMBINED_ORIENTATION_HANDLE *pCombinedOrientationData, + const MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, + Word32 Cldfb_In_Real[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + Word32 Cldfb_In_Imag[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + Word32 Cldfb_Out_Real[MAX_HEAD_ROT_POSES*BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], /* o : Binaural signals */ + Word32 Cldfb_Out_Imag[MAX_HEAD_ROT_POSES*BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + const Word16 low_res_pre_rend_rot, + const Word16 num_subframes, + const Word16 Q_in +); + +ivas_error ivas_rend_openCldfb( + HANDLE_CLDFB_FILTER_BANK cldfbAna[MAX_INPUT_CHANNELS], + const AUDIO_CONFIG inConfig, + const Word32 output_Fs +); + +ivas_error ivas_rend_openCldfbRend( + CLDFB_REND_WRAPPER *pCldfbRend, + const AUDIO_CONFIG inConfig, + const AUDIO_CONFIG outConfig, + const MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, + const Word32 output_Fs +); + +void ivas_rend_closeCldfbRend( + CLDFB_REND_WRAPPER *pCldfbRend +); + +#endif /* clang-format on */ diff --git a/lib_rend/ivas_reflections.c b/lib_rend/ivas_reflections_fx.c similarity index 98% rename from lib_rend/ivas_reflections.c rename to lib_rend/ivas_reflections_fx.c index c5d118858c5cda03a2b3bb9601652565c0694209..3b394af519eeb49fbd8174382446c4e4afcc675d 100644 --- a/lib_rend/ivas_reflections.c +++ b/lib_rend/ivas_reflections_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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,16 +33,14 @@ #include "options.h" #include #include -#include "prot.h" +#include "prot_fx.h" #include "rom_dec.h" #include "lib_rend.h" -#include "ivas_prot_rend.h" +#include "ivas_prot_rend_fx.h" #include "ivas_stat_rend.h" #include "ivas_cnst.h" -#include "ivas_prot.h" #include "ivas_rom_com.h" #include "wmc_auto.h" -#include "prot_fx.h" #include "debug.h" #include "ivas_rom_com_fx.h" @@ -340,10 +338,17 @@ ivas_error ivas_er_encoder_init( p_y_fx = reflections->shoebox_data.az_angle.data_fx[i]; // Q23 move32(); move32(); - - rad_el_angle = deg2rad_fx( p_x_fx ); // Q23 - rad_az_angle = deg2rad_fx( p_y_fx ); // Q23 - +#ifdef SPLIT_REND_WITH_HEAD_ROT + p_x_fx = L_shr( p_x_fx, 1 ); // Q22 + p_y_fx = L_shr( p_y_fx, 1 ); // Q22 +#endif + rad_el_angle = deg2rad_fx( p_x_fx ); // Q22 + rad_az_angle = deg2rad_fx( p_y_fx ); // Q22 + +#ifdef SPLIT_REND_WITH_HEAD_ROT + rad_el_angle = L_shl( rad_el_angle, 1 ); // Q23 + rad_az_angle = L_shl( rad_az_angle, 1 ); // Q23 +#endif rad_el_angle = L_shr( rad_el_angle, 10 ); // Q13 rad_az_angle = L_shr( rad_az_angle, 10 ); // Q13 diff --git a/lib_rend/ivas_render_config.c b/lib_rend/ivas_render_config_fx.c similarity index 84% rename from lib_rend/ivas_render_config.c rename to lib_rend/ivas_render_config_fx.c index d35a6c005af7ac003a58391e44e2e46769a1c5be..0ce576cb3416b17527a80e46d2df14a1b18ffe39 100644 --- a/lib_rend/ivas_render_config.c +++ b/lib_rend/ivas_render_config_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other @@ -32,12 +32,11 @@ #include #include "options.h" -#include "prot.h" -#include "ivas_prot_rend.h" +#include "prot_fx.h" +#include "ivas_prot_rend_fx.h" #include "ivas_rom_rend.h" #include "ivas_rom_TdBinauralRenderer.h" #include "wmc_auto.h" -#include "prot_fx.h" /*-----------------------------------------------------------------------* * Local constants @@ -138,5 +137,32 @@ ivas_error ivas_render_config_init_from_rom_fx( move16(); } +#ifdef SPLIT_REND_WITH_HEAD_ROT + ( *hRenderConfig )->split_rend_config.splitRendBitRate = SPLIT_REND_768k; + move32(); + ( *hRenderConfig )->split_rend_config.dof = 3; + move16(); + ( *hRenderConfig )->split_rend_config.hq_mode = 0; + move16(); + ( *hRenderConfig )->split_rend_config.codec_delay_ms = 0; + move16(); +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + ( *hRenderConfig )->split_rend_config.isar_frame_size_ms = 20; + move16(); +#endif + ( *hRenderConfig )->split_rend_config.codec_frame_size_ms = 0; /* 0 means "use default for selected codec" */ + move16(); + ( *hRenderConfig )->split_rend_config.codec = ISAR_SPLIT_REND_CODEC_DEFAULT; + move32(); + ( *hRenderConfig )->split_rend_config.poseCorrectionMode = ISAR_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB; + move32(); + ( *hRenderConfig )->split_rend_config.rendererSelection = ISAR_SPLIT_REND_RENDERER_SELECTION_DEFAULT; + move32(); +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + ( *hRenderConfig )->split_rend_config.lc3plus_highres = 0; + move16(); +#endif +#endif + return IVAS_ERR_OK; } diff --git a/lib_rend/ivas_reverb_delay_line.c b/lib_rend/ivas_reverb_delay_line_fx.c similarity index 98% rename from lib_rend/ivas_reverb_delay_line.c rename to lib_rend/ivas_reverb_delay_line_fx.c index c8db27955f0547d8d7e5b3fa5f96f72c4484889f..d2a6a0c44e2c825c0e31dfb09dca6aeb337d502c 100644 --- a/lib_rend/ivas_reverb_delay_line.c +++ b/lib_rend/ivas_reverb_delay_line_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other @@ -32,11 +32,9 @@ #include #include "options.h" -#include "ivas_prot.h" -#include "ivas_prot_rend.h" -#include "prot.h" -#include "wmc_auto.h" +#include "ivas_prot_rend_fx.h" #include "prot_fx.h" +#include "wmc_auto.h" #include "debug.h" /*-----------------------------------------------------------------------------------------* * Function ivas_rev_delay_line_init() diff --git a/lib_rend/ivas_reverb_fft_filter.c b/lib_rend/ivas_reverb_fft_filter_fx.c similarity index 99% rename from lib_rend/ivas_reverb_fft_filter.c rename to lib_rend/ivas_reverb_fft_filter_fx.c index 79cb544b214774e0972b61f0d282518497d456b4..bbe077f8bacdb8d40e1e1cba411dc34bf727a88f 100644 --- a/lib_rend/ivas_reverb_fft_filter.c +++ b/lib_rend/ivas_reverb_fft_filter_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other @@ -32,11 +32,10 @@ #include #include "options.h" -#include "prot.h" -#include "ivas_prot_rend.h" +#include "prot_fx.h" +#include "ivas_prot_rend_fx.h" #include #include "wmc_auto.h" -#include "prot_fx.h" #include "debug.h" #define float_to_fix( n, factor ) ( round( n * ( 1 << factor ) ) ) #define fix_to_float( n, factor ) ( (float) n / ( 1 << factor ) ) diff --git a/lib_rend/ivas_reverb_filter_design.c b/lib_rend/ivas_reverb_filter_design_fx.c similarity index 99% rename from lib_rend/ivas_reverb_filter_design.c rename to lib_rend/ivas_reverb_filter_design_fx.c index b1499839c1fee33c5b1fa03c237c4a5301a0a34d..62c97f88f4b4c78c399967ee85854c694ac44929 100644 --- a/lib_rend/ivas_reverb_filter_design.c +++ b/lib_rend/ivas_reverb_filter_design_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other @@ -32,9 +32,8 @@ #include #include "options.h" -#include "prot.h" #include "prot_fx.h" -#include "ivas_prot_rend.h" +#include "ivas_prot_rend_fx.h" #include #include #include @@ -741,7 +740,7 @@ void ivas_reverb_calc_color_levels_fx( Word16 temp = 0, result_e = 0; move16(); move16(); - cos_w = getCosWord16R2( (Word16) abs( L_shl( Mpy_32_32( pFc[freq_idx], fs_inverted ), 3 ) ) ); // q = 15 + cos_w = getCosWord16R2( (Word16) L_abs( L_shl( Mpy_32_32( pFc[freq_idx], fs_inverted ), 3 ) ) ); // q = 15 H_filter = L_add( L_shr( L_add( L_shr( Mpy_32_32( coefB[0], coefB[0] ), 1 ), L_shr( Mpy_32_32( coefB[1], coefB[1] ), 1 ) ), 2 ), L_shr( Mpy_32_32( coefB[0], Mpy_32_32( coefB[1], L_shl( cos_w, 15 ) ) ), 1 ) ); // q = 28 H_filter = BASOP_Util_Divide3232_Scale_cadence( H_filter, L_add( ONE_IN_Q28, L_shr( L_add( L_shr( Mpy_32_32( coefA[1], coefA[1] ), 2 ), Mpy_32_32( coefA[1], L_shl( cos_w, 15 ) ) ), 1 ) ), &temp ); H_filter = Sqrt32( H_filter, &temp ); @@ -1156,9 +1155,9 @@ void ivas_reverb_get_hrtf_set_properties_fx( IA_coherence[freq_idx] = L_shl( IA_coherence[freq_idx], sub( 27, sub( 15, temp ) ) ); // q = 27 move32(); /* Limiting to (0...1) range in case of small numerical errors or negative values */ - IA_coherence[freq_idx] = min( IA_coherence[freq_idx], ONE_IN_Q27 ); // Q27 + IA_coherence[freq_idx] = L_min( IA_coherence[freq_idx], ONE_IN_Q27 ); // Q27 move32(); - IA_coherence[freq_idx] = max( IA_coherence[freq_idx], 0 ); // Q27 + IA_coherence[freq_idx] = L_max( IA_coherence[freq_idx], 0 ); // Q27 move32(); } diff --git a/lib_rend/ivas_reverb.c b/lib_rend/ivas_reverb_fx.c similarity index 99% rename from lib_rend/ivas_reverb.c rename to lib_rend/ivas_reverb_fx.c index c70e325e38649e722522811052c18df7fbb6a9ff..870f8795dd4ab6fd0d1a45dbf17205e15df3fda5 100644 --- a/lib_rend/ivas_reverb.c +++ b/lib_rend/ivas_reverb_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other @@ -32,14 +32,13 @@ #include #include "options.h" -#include "prot.h" -#include "ivas_prot_rend.h" +#include "prot_fx.h" +#include "ivas_prot_rend_fx.h" #include "ivas_cnst.h" #include "math.h" #include "ivas_rom_rend.h" #include #include "wmc_auto.h" -#include "prot_fx.h" #include "debug.h" #define float_to_fix( n, factor ) ( round( n * ( 1 << factor ) ) ) #define float_to_fixQ31( n ) ( round( n * 0x7fffffff ) ) @@ -166,13 +165,13 @@ static ivas_error calc_jot_t60_coeffs_fx( Word16 *pH_dB_fx, Word16 pH_dB_exp, co * *------------------------------------------------------------------------*/ -static uint16_t binRend_rand( +static UWord16 binRend_rand( REVERB_STRUCT_HANDLE hReverb /* i/o: binaural reverb handle */ ) { hReverb->binRend_RandNext = hReverb->binRend_RandNext * 1103515245 + 12345; - return (uint16_t) ( hReverb->binRend_RandNext / 65536 ) % 32768; + return (UWord16) ( hReverb->binRend_RandNext / 65536 ) % 32768; } @@ -887,9 +886,9 @@ static ivas_error calc_jot_t60_coeffs_fx( Word32 L_tmp; Word16 f0_fx, tmp_fx, lf_target_gain_dB_fx, hf_target_gain_dB_fx, mid_crossing_gain_dB_fx; Word16 lin_gain_lf_fx, lin_gain_hf_fx, shift, expl, exph; - int16_t f_idx, e = pH_dB_exp; + Word16 f_idx, e = pH_dB_exp; move16(); - uint16_t n_points_lf, n_points_hf; + UWord16 n_points_lf, n_points_hf; lf_target_gain_dB_fx = 0; move16(); @@ -1472,7 +1471,7 @@ ivas_error ivas_reverb_open_fx( { ivas_error error; REVERB_HANDLE pState = NULL; - Word16 bin_idx, subframe_len, output_frame, predelay_bf_len, loop_idx; + Word16 bin_idx, subframe_len, output_frame, predelay_bf_len, loop_idx, i; ivas_reverb_params_t params; Word32 pColor_target_l_fx[RV_LENGTH_NR_FC]; Word32 pColor_target_r_fx[RV_LENGTH_NR_FC]; @@ -1560,7 +1559,7 @@ ivas_error ivas_reverb_open_fx( set_reverb_acoustic_data_fx( ¶ms, input_audio_config, hHrtf, &hRenderConfig->roomAcoustics, subframe_len, nr_fc_input, nr_fc_fft_filter ); Scale_sig32( params.pFc_fx, nr_fc_fft_filter, -2 ); - FOR( Word16 i = 0; i < nr_fc_fft_filter; i++ ) + FOR( i = 0; i < nr_fc_fft_filter; i++ ) { params.pRt60_fx[i] = L_abs( params.pRt60_fx[i] ); move32(); @@ -1602,7 +1601,7 @@ ivas_error ivas_reverb_open_fx( Word32 *pT60_filter_coeff = (Word32 *) malloc( ( lenT60_filter_coeff ) * sizeof( Word32 * ) ); - FOR( Word16 i = 0; i < nr_fc_fft_filter; i++ ) + FOR( i = 0; i < nr_fc_fft_filter; i++ ) { params.pDsr_fx[i] = L_shl( params.pDsr_fx[i], params.pDsr_e[i] ); move32(); @@ -1611,7 +1610,7 @@ ivas_error ivas_reverb_open_fx( pHrtf_avg_pwr_response_r_const[i] = L_shl( params.pHrtf_avg_pwr_response_r_const_fx[i], 5 ); /*Q23+5*/ move32(); } - FOR( Word16 i = 0; i < lenT60_filter_coeff; i++ ) + FOR( i = 0; i < lenT60_filter_coeff; i++ ) { pT60_filter_coeff[i] = L_shl_sat( params.pT60_filter_coeff_fx[i], 17 ); move32(); @@ -1649,20 +1648,20 @@ ivas_error ivas_reverb_open_fx( { /* Computing correlation filters on the basis of target IA coherence */ #ifdef MSAN_FIX - FOR( int i = 0; i < shl( sub( nr_fc_fft_filter, 1 ), 1 ); i++ ) + FOR( i = 0; i < shl( sub( nr_fc_fft_filter, 1 ), 1 ); i++ ) { pTime_window_fx[i] = L_shr( pTime_window_fx[i], 1 ); /*Scaling signal down to 30*/ move32(); } #else - FOR( int i = 0; i < RV_FILTER_MAX_FFT_SIZE; i++ ) + FOR( i = 0; i < RV_FILTER_MAX_FFT_SIZE; i++ ) { pTime_window_fx[i] = L_shr( pTime_window_fx[i], 1 ); /*Scaling signal down to 30*/ } #endif // MSAN_FIX Word32 *pHrtf_inter_aural_coherence_const = (Word32 *) malloc( nr_fc_fft_filter * sizeof( Word32 ) ); - FOR( Word16 i = 0; i < nr_fc_fft_filter; i++ ) + FOR( i = 0; i < nr_fc_fft_filter; i++ ) { pHrtf_inter_aural_coherence_const[i] = L_shl( params.pHrtf_inter_aural_coherence_const_fx[i], 3 ); /*Scaling up to Q30*/ move32(); @@ -1671,14 +1670,14 @@ ivas_error ivas_reverb_open_fx( free( pHrtf_inter_aural_coherence_const ); - FOR( Word16 i = 0; i < nr_fc_fft_filter; i++ ) + FOR( i = 0; i < nr_fc_fft_filter; i++ ) { pFft_wf_filter_ch0_fx[i][0] = L_shl( pFft_wf_filter_ch0_fx[i][0], sub( 31, q_pFft_wf_filter_ch0_fx ) ); move32(); pFft_wf_filter_ch0_fx[i][1] = L_shl( pFft_wf_filter_ch0_fx[i][1], sub( 31, q_pFft_wf_filter_ch0_fx ) ); move32(); } - FOR( Word16 i = 0; i < nr_fc_fft_filter; i++ ) + FOR( i = 0; i < nr_fc_fft_filter; i++ ) { pFft_wf_filter_ch1_fx[i][0] = L_shl( pFft_wf_filter_ch1_fx[i][0], sub( 31, q_pFft_wf_filter_ch1_fx ) ); move32(); @@ -1700,14 +1699,14 @@ ivas_error ivas_reverb_open_fx( /* Computing coloration filters on the basis of target responses */ ivas_reverb_calc_color_filters_fx( pColor_target_l_fx, pColor_target_r_fx, pTime_window_fx, pState->fft_size, pFft_wf_filter_ch0_fx, pFft_wf_filter_ch1_fx, &q_pFft_wf_filter_ch0_fx, &q_pFft_wf_filter_ch1_fx ); - FOR( int i = 0; i < nr_fc_fft_filter; i++ ) + FOR( i = 0; i < nr_fc_fft_filter; i++ ) { pFft_wf_filter_ch0_fx[i][0] = L_shl( pFft_wf_filter_ch0_fx[i][0], sub( 31, q_pFft_wf_filter_ch0_fx ) ); move32(); pFft_wf_filter_ch0_fx[i][1] = L_shl( pFft_wf_filter_ch0_fx[i][1], sub( 31, q_pFft_wf_filter_ch0_fx ) ); move32(); } - FOR( Word16 i = 0; i < nr_fc_fft_filter; i++ ) + FOR( i = 0; i < nr_fc_fft_filter; i++ ) { pFft_wf_filter_ch1_fx[i][0] = L_shl( pFft_wf_filter_ch1_fx[i][0], sub( 31, q_pFft_wf_filter_ch1_fx ) ); move32(); @@ -2493,7 +2492,7 @@ ivas_error ivas_binaural_reverb_open_parambin( const Word16 numBins, /* i : number of CLDFB bins Q0 */ const Word16 numCldfbSlotsPerFrame, /* i : number of CLDFB slots per frame Q0 */ IVAS_ROOM_ACOUSTICS_CONFIG_DATA *roomAcoustics, /* i/o: room acoustics parameters */ - const int32_t sampling_rate, /* i : sampling rate Q0 */ + const Word32 sampling_rate, /* i : sampling rate Q0 */ const HRTFS_PARAMBIN_HANDLE hHrtfParambin /* i : Parametric binauralizer HRTF handle */ ) { diff --git a/lib_rend/ivas_reverb_iir_filter.c b/lib_rend/ivas_reverb_iir_filter_fx.c similarity index 98% rename from lib_rend/ivas_reverb_iir_filter.c rename to lib_rend/ivas_reverb_iir_filter_fx.c index 7049fa580e75628c925b92bd93a4e284c5e3f643..e09ec70055ccf358879a06134430ec4765136b78 100644 --- a/lib_rend/ivas_reverb_iir_filter.c +++ b/lib_rend/ivas_reverb_iir_filter_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other @@ -32,10 +32,9 @@ #include #include "options.h" -#include "prot.h" -#include "ivas_prot_rend.h" -#include "wmc_auto.h" #include "prot_fx.h" +#include "ivas_prot_rend_fx.h" +#include "wmc_auto.h" #include "debug.h" #define float_to_fix( n, factor ) ( round( n * ( 1 << factor ) ) ) #define fix_to_float( n, factor ) ( (float) n / ( 1 << factor ) ) diff --git a/lib_rend/ivas_reverb_utils.c b/lib_rend/ivas_reverb_utils_fx.c similarity index 99% rename from lib_rend/ivas_reverb_utils.c rename to lib_rend/ivas_reverb_utils_fx.c index ddb95aaf024dce45714aac4023eb93d4d7e6f4e4..b3e1e72fa1f947d9930e486943970c422f2097a3 100644 --- a/lib_rend/ivas_reverb_utils.c +++ b/lib_rend/ivas_reverb_utils_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other @@ -32,12 +32,11 @@ #include #include "options.h" -#include "prot.h" -#include "ivas_prot_rend.h" +#include "prot_fx.h" +#include "ivas_prot_rend_fx.h" #include "ivas_rom_rend.h" #include #include "wmc_auto.h" -#include "prot_fx.h" #include "options_warnings.h" /*-----------------------------------------------------------------------------------------* diff --git a/lib_rend/ivas_rom_TdBinauralRenderer.h b/lib_rend/ivas_rom_TdBinauralRenderer.h index 7cdd84d6d9e566a898c044b5dede466af33d2b74..89d86f112bf712e86e7cf0f64b309464d8c148bc 100644 --- a/lib_rend/ivas_rom_TdBinauralRenderer.h +++ b/lib_rend/ivas_rom_TdBinauralRenderer.h @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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.c b/lib_rend/ivas_rom_TdBinauralRenderer_fx.c similarity index 99% rename from lib_rend/ivas_rom_TdBinauralRenderer.c rename to lib_rend/ivas_rom_TdBinauralRenderer_fx.c index f6921bc92637232dee3771ef03b49e72be69f668..cee2a9753ba9544860c85e301953e7bf59fcd8db 100644 --- a/lib_rend/ivas_rom_TdBinauralRenderer.c +++ b/lib_rend/ivas_rom_TdBinauralRenderer_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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 8e7bd4a55458f43ecd99c9f2ba26c3190bbf85c3..4b1428ac8b572025872d6acbb27a371c452f1aec 100644 --- a/lib_rend/ivas_rom_binauralRenderer.h +++ b/lib_rend/ivas_rom_binauralRenderer.h @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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_fx.c similarity index 99% rename from lib_rend/ivas_rom_binauralRenderer.c rename to lib_rend/ivas_rom_binauralRenderer_fx.c index fa4cbd7aad05b3a786bcd138dbd9881988afad35..e7dbbae70cec37257840afd3173d8aa4a751508f 100644 --- a/lib_rend/ivas_rom_binauralRenderer.c +++ b/lib_rend/ivas_rom_binauralRenderer_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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 0004a05d7b531419b508a426ba3632f28a1aa16e..2b4c3e919fcb39f74d9d8ae84b4a89ea1bf52ecf 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-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other @@ -56,13 +56,13 @@ extern Word32 CRendBin_Combined_HRIR_latency_s_fx; /* Sample Rate = 48000 */ -extern int16_t CRendBin_Combined_HRIR_max_num_iterations_48kHz; -extern uint16_t CRendBin_Combined_HRIR_num_iterations_48kHz[15][BINAURAL_CHANNELS]; -extern uint16_t CRendBin_Combined_HRIR_num_iterations_diffuse_48kHz[BINAURAL_CHANNELS]; -extern uint16_t CRendBin_Combined_HRIR_pIndex_frequency_max_48kHz[15][BINAURAL_CHANNELS][1]; -extern uint16_t CRendBin_Combined_HRIR_index_frequency_max_diffuse_48kHz; +extern Word16 CRendBin_Combined_HRIR_max_num_iterations_48kHz; +extern UWord16 CRendBin_Combined_HRIR_num_iterations_48kHz[15][BINAURAL_CHANNELS]; +extern UWord16 CRendBin_Combined_HRIR_num_iterations_diffuse_48kHz[BINAURAL_CHANNELS]; +extern UWord16 CRendBin_Combined_HRIR_pIndex_frequency_max_48kHz[15][BINAURAL_CHANNELS][1]; +extern UWord16 CRendBin_Combined_HRIR_index_frequency_max_diffuse_48kHz; extern Word16 CRendBin_Combined_HRIR_inv_diffuse_weight_48kHz_fx[15]; -extern uint16_t *CRendBin_Combined_HRIR_pIndex_frequency_max_diffuse_48kHz[BINAURAL_CHANNELS]; +extern UWord16 *CRendBin_Combined_HRIR_pIndex_frequency_max_diffuse_48kHz[BINAURAL_CHANNELS]; extern Word32 CRendBin_Combined_HRIR_coeff_re_48kHz_fx[15][BINAURAL_CHANNELS][240]; extern Word32 CRendBin_Combined_HRIR_coeff_im_48kHz_fx[15][BINAURAL_CHANNELS][240]; extern Word32 *CRendBin_Combined_HRIR_coeff_diffuse_re_48kHz_fx[BINAURAL_CHANNELS]; @@ -70,13 +70,13 @@ extern Word32 *CRendBin_Combined_HRIR_coeff_diffuse_im_48kHz_fx[BINAURAL_CHANNEL /* Sample Rate = 32000 */ -extern int16_t CRendBin_Combined_HRIR_max_num_iterations_32kHz; -extern uint16_t CRendBin_Combined_HRIR_num_iterations_32kHz[15][BINAURAL_CHANNELS]; -extern uint16_t CRendBin_Combined_HRIR_num_iterations_diffuse_32kHz[BINAURAL_CHANNELS]; -extern uint16_t CRendBin_Combined_HRIR_pIndex_frequency_max_32kHz[15][BINAURAL_CHANNELS][1]; -extern uint16_t CRendBin_Combined_HRIR_index_frequency_max_diffuse_32kHz; +extern Word16 CRendBin_Combined_HRIR_max_num_iterations_32kHz; +extern UWord16 CRendBin_Combined_HRIR_num_iterations_32kHz[15][BINAURAL_CHANNELS]; +extern UWord16 CRendBin_Combined_HRIR_num_iterations_diffuse_32kHz[BINAURAL_CHANNELS]; +extern UWord16 CRendBin_Combined_HRIR_pIndex_frequency_max_32kHz[15][BINAURAL_CHANNELS][1]; +extern UWord16 CRendBin_Combined_HRIR_index_frequency_max_diffuse_32kHz; extern Word16 CRendBin_Combined_HRIR_inv_diffuse_weight_32kHz_fx[15]; -extern uint16_t *CRendBin_Combined_HRIR_pIndex_frequency_max_diffuse_32kHz[BINAURAL_CHANNELS]; +extern UWord16 *CRendBin_Combined_HRIR_pIndex_frequency_max_diffuse_32kHz[BINAURAL_CHANNELS]; extern Word32 CRendBin_Combined_HRIR_coeff_re_32kHz_fx[15][BINAURAL_CHANNELS][160]; extern Word32 CRendBin_Combined_HRIR_coeff_im_32kHz_fx[15][BINAURAL_CHANNELS][160]; extern Word32 *CRendBin_Combined_HRIR_coeff_diffuse_re_32kHz_fx[BINAURAL_CHANNELS]; @@ -84,13 +84,13 @@ extern Word32 *CRendBin_Combined_HRIR_coeff_diffuse_im_32kHz_fx[BINAURAL_CHANNEL /* Sample Rate = 16000 */ -extern int16_t CRendBin_Combined_HRIR_max_num_iterations_16kHz; -extern uint16_t CRendBin_Combined_HRIR_num_iterations_16kHz[15][BINAURAL_CHANNELS]; -extern uint16_t CRendBin_Combined_HRIR_num_iterations_diffuse_16kHz[BINAURAL_CHANNELS]; -extern uint16_t CRendBin_Combined_HRIR_pIndex_frequency_max_16kHz[15][BINAURAL_CHANNELS][1]; -extern uint16_t CRendBin_Combined_HRIR_index_frequency_max_diffuse_16kHz; +extern Word16 CRendBin_Combined_HRIR_max_num_iterations_16kHz; +extern UWord16 CRendBin_Combined_HRIR_num_iterations_16kHz[15][BINAURAL_CHANNELS]; +extern UWord16 CRendBin_Combined_HRIR_num_iterations_diffuse_16kHz[BINAURAL_CHANNELS]; +extern UWord16 CRendBin_Combined_HRIR_pIndex_frequency_max_16kHz[15][BINAURAL_CHANNELS][1]; +extern UWord16 CRendBin_Combined_HRIR_index_frequency_max_diffuse_16kHz; extern Word16 CRendBin_Combined_HRIR_inv_diffuse_weight_16kHz_fx[15]; -extern uint16_t *CRendBin_Combined_HRIR_pIndex_frequency_max_diffuse_16kHz[BINAURAL_CHANNELS]; +extern UWord16 *CRendBin_Combined_HRIR_pIndex_frequency_max_diffuse_16kHz[BINAURAL_CHANNELS]; extern Word32 CRendBin_Combined_HRIR_coeff_re_16kHz_fx[15][BINAURAL_CHANNELS][80]; extern Word32 CRendBin_Combined_HRIR_coeff_im_16kHz_fx[15][BINAURAL_CHANNELS][80]; extern Word32 *CRendBin_Combined_HRIR_coeff_diffuse_re_16kHz_fx[BINAURAL_CHANNELS]; @@ -105,13 +105,13 @@ extern Word32 CRendBin_FOA_HRIR_latency_s_fx; /* Sample Rate = 48000 */ -extern int16_t CRendBin_FOA_HRIR_max_num_iterations_48kHz; -extern uint16_t CRendBin_FOA_HRIR_num_iterations_48kHz[4][BINAURAL_CHANNELS]; -extern uint16_t CRendBin_FOA_HRIR_num_iterations_diffuse_48kHz[BINAURAL_CHANNELS]; -extern uint16_t CRendBin_FOA_HRIR_pIndex_frequency_max_48kHz[4][BINAURAL_CHANNELS][1]; -extern uint16_t CRendBin_FOA_HRIR_index_frequency_max_diffuse_48kHz; +extern Word16 CRendBin_FOA_HRIR_max_num_iterations_48kHz; +extern UWord16 CRendBin_FOA_HRIR_num_iterations_48kHz[4][BINAURAL_CHANNELS]; +extern UWord16 CRendBin_FOA_HRIR_num_iterations_diffuse_48kHz[BINAURAL_CHANNELS]; +extern UWord16 CRendBin_FOA_HRIR_pIndex_frequency_max_48kHz[4][BINAURAL_CHANNELS][1]; +extern UWord16 CRendBin_FOA_HRIR_index_frequency_max_diffuse_48kHz; extern Word16 CRendBin_FOA_HRIR_inv_diffuse_weight_48kHz_fx[4]; -extern uint16_t *CRendBin_FOA_HRIR_pIndex_frequency_max_diffuse_48kHz[BINAURAL_CHANNELS]; +extern UWord16 *CRendBin_FOA_HRIR_pIndex_frequency_max_diffuse_48kHz[BINAURAL_CHANNELS]; extern Word32 CRendBin_FOA_HRIR_coeff_re_48kHz_fx[4][BINAURAL_CHANNELS][240]; extern Word32 CRendBin_FOA_HRIR_coeff_im_48kHz_fx[4][BINAURAL_CHANNELS][240]; extern Word32 *CRendBin_FOA_HRIR_coeff_diffuse_re_48kHz_fx[BINAURAL_CHANNELS]; @@ -119,13 +119,13 @@ extern Word32 *CRendBin_FOA_HRIR_coeff_diffuse_im_48kHz_fx[BINAURAL_CHANNELS]; /* Sample Rate = 32000 */ -extern int16_t CRendBin_FOA_HRIR_max_num_iterations_32kHz; -extern uint16_t CRendBin_FOA_HRIR_num_iterations_32kHz[4][BINAURAL_CHANNELS]; -extern uint16_t CRendBin_FOA_HRIR_num_iterations_diffuse_32kHz[BINAURAL_CHANNELS]; -extern uint16_t CRendBin_FOA_HRIR_pIndex_frequency_max_32kHz[4][BINAURAL_CHANNELS][1]; -extern uint16_t CRendBin_FOA_HRIR_index_frequency_max_diffuse_32kHz; +extern Word16 CRendBin_FOA_HRIR_max_num_iterations_32kHz; +extern UWord16 CRendBin_FOA_HRIR_num_iterations_32kHz[4][BINAURAL_CHANNELS]; +extern UWord16 CRendBin_FOA_HRIR_num_iterations_diffuse_32kHz[BINAURAL_CHANNELS]; +extern UWord16 CRendBin_FOA_HRIR_pIndex_frequency_max_32kHz[4][BINAURAL_CHANNELS][1]; +extern UWord16 CRendBin_FOA_HRIR_index_frequency_max_diffuse_32kHz; extern Word16 CRendBin_FOA_HRIR_inv_diffuse_weight_32kHz_fx[4]; -extern uint16_t *CRendBin_FOA_HRIR_pIndex_frequency_max_diffuse_32kHz[BINAURAL_CHANNELS]; +extern UWord16 *CRendBin_FOA_HRIR_pIndex_frequency_max_diffuse_32kHz[BINAURAL_CHANNELS]; extern Word32 CRendBin_FOA_HRIR_coeff_re_32kHz_fx[4][BINAURAL_CHANNELS][160]; extern Word32 CRendBin_FOA_HRIR_coeff_im_32kHz_fx[4][BINAURAL_CHANNELS][160]; extern Word32 *CRendBin_FOA_HRIR_coeff_diffuse_re_32kHz_fx[BINAURAL_CHANNELS]; @@ -133,13 +133,13 @@ extern Word32 *CRendBin_FOA_HRIR_coeff_diffuse_im_32kHz_fx[BINAURAL_CHANNELS]; /* Sample Rate = 16000 */ -extern int16_t CRendBin_FOA_HRIR_max_num_iterations_16kHz; -extern uint16_t CRendBin_FOA_HRIR_num_iterations_16kHz[4][BINAURAL_CHANNELS]; -extern uint16_t CRendBin_FOA_HRIR_num_iterations_diffuse_16kHz[BINAURAL_CHANNELS]; -extern uint16_t CRendBin_FOA_HRIR_pIndex_frequency_max_16kHz[4][BINAURAL_CHANNELS][1]; -extern uint16_t CRendBin_FOA_HRIR_index_frequency_max_diffuse_16kHz; +extern Word16 CRendBin_FOA_HRIR_max_num_iterations_16kHz; +extern UWord16 CRendBin_FOA_HRIR_num_iterations_16kHz[4][BINAURAL_CHANNELS]; +extern UWord16 CRendBin_FOA_HRIR_num_iterations_diffuse_16kHz[BINAURAL_CHANNELS]; +extern UWord16 CRendBin_FOA_HRIR_pIndex_frequency_max_16kHz[4][BINAURAL_CHANNELS][1]; +extern UWord16 CRendBin_FOA_HRIR_index_frequency_max_diffuse_16kHz; extern Word16 CRendBin_FOA_HRIR_inv_diffuse_weight_16kHz_fx[4]; -extern uint16_t *CRendBin_FOA_HRIR_pIndex_frequency_max_diffuse_16kHz[BINAURAL_CHANNELS]; +extern UWord16 *CRendBin_FOA_HRIR_pIndex_frequency_max_diffuse_16kHz[BINAURAL_CHANNELS]; extern Word32 CRendBin_FOA_HRIR_coeff_re_16kHz_fx[4][BINAURAL_CHANNELS][80]; extern Word32 CRendBin_FOA_HRIR_coeff_im_16kHz_fx[4][BINAURAL_CHANNELS][80]; extern Word32 *CRendBin_FOA_HRIR_coeff_diffuse_re_16kHz_fx[BINAURAL_CHANNELS]; @@ -153,13 +153,13 @@ extern Word32 CRendBin_HOA2_HRIR_latency_s_fx; /* Sample Rate = 48000 */ -extern int16_t CRendBin_HOA2_HRIR_max_num_iterations_48kHz; -extern uint16_t CRendBin_HOA2_HRIR_num_iterations_48kHz[9][BINAURAL_CHANNELS]; -extern uint16_t CRendBin_HOA2_HRIR_num_iterations_diffuse_48kHz[BINAURAL_CHANNELS]; -extern uint16_t CRendBin_HOA2_HRIR_pIndex_frequency_max_48kHz[9][BINAURAL_CHANNELS][1]; -extern uint16_t CRendBin_HOA2_HRIR_index_frequency_max_diffuse_48kHz; +extern Word16 CRendBin_HOA2_HRIR_max_num_iterations_48kHz; +extern UWord16 CRendBin_HOA2_HRIR_num_iterations_48kHz[9][BINAURAL_CHANNELS]; +extern UWord16 CRendBin_HOA2_HRIR_num_iterations_diffuse_48kHz[BINAURAL_CHANNELS]; +extern UWord16 CRendBin_HOA2_HRIR_pIndex_frequency_max_48kHz[9][BINAURAL_CHANNELS][1]; +extern UWord16 CRendBin_HOA2_HRIR_index_frequency_max_diffuse_48kHz; extern Word16 CRendBin_HOA2_HRIR_inv_diffuse_weight_48kHz_fx[9]; -extern uint16_t *CRendBin_HOA2_HRIR_pIndex_frequency_max_diffuse_48kHz[BINAURAL_CHANNELS]; +extern UWord16 *CRendBin_HOA2_HRIR_pIndex_frequency_max_diffuse_48kHz[BINAURAL_CHANNELS]; extern Word32 CRendBin_HOA2_HRIR_coeff_re_48kHz_fx[9][BINAURAL_CHANNELS][240]; extern Word32 CRendBin_HOA2_HRIR_coeff_im_48kHz_fx[9][BINAURAL_CHANNELS][240]; extern Word32 *CRendBin_HOA2_HRIR_coeff_diffuse_re_48kHz_fx[BINAURAL_CHANNELS]; @@ -167,13 +167,13 @@ extern Word32 *CRendBin_HOA2_HRIR_coeff_diffuse_im_48kHz_fx[BINAURAL_CHANNELS]; /* Sample Rate = 32000 */ -extern int16_t CRendBin_HOA2_HRIR_max_num_iterations_32kHz; -extern uint16_t CRendBin_HOA2_HRIR_num_iterations_32kHz[9][BINAURAL_CHANNELS]; -extern uint16_t CRendBin_HOA2_HRIR_num_iterations_diffuse_32kHz[BINAURAL_CHANNELS]; -extern uint16_t CRendBin_HOA2_HRIR_pIndex_frequency_max_32kHz[9][BINAURAL_CHANNELS][1]; -extern uint16_t CRendBin_HOA2_HRIR_index_frequency_max_diffuse_32kHz; +extern Word16 CRendBin_HOA2_HRIR_max_num_iterations_32kHz; +extern UWord16 CRendBin_HOA2_HRIR_num_iterations_32kHz[9][BINAURAL_CHANNELS]; +extern UWord16 CRendBin_HOA2_HRIR_num_iterations_diffuse_32kHz[BINAURAL_CHANNELS]; +extern UWord16 CRendBin_HOA2_HRIR_pIndex_frequency_max_32kHz[9][BINAURAL_CHANNELS][1]; +extern UWord16 CRendBin_HOA2_HRIR_index_frequency_max_diffuse_32kHz; extern Word16 CRendBin_HOA2_HRIR_inv_diffuse_weight_32kHz_fx[9]; -extern uint16_t *CRendBin_HOA2_HRIR_pIndex_frequency_max_diffuse_32kHz[BINAURAL_CHANNELS]; +extern UWord16 *CRendBin_HOA2_HRIR_pIndex_frequency_max_diffuse_32kHz[BINAURAL_CHANNELS]; extern Word32 CRendBin_HOA2_HRIR_coeff_re_32kHz_fx[9][BINAURAL_CHANNELS][160]; extern Word32 CRendBin_HOA2_HRIR_coeff_im_32kHz_fx[9][BINAURAL_CHANNELS][160]; extern Word32 *CRendBin_HOA2_HRIR_coeff_diffuse_re_32kHz_fx[BINAURAL_CHANNELS]; @@ -181,13 +181,13 @@ extern Word32 *CRendBin_HOA2_HRIR_coeff_diffuse_im_32kHz_fx[BINAURAL_CHANNELS]; /* Sample Rate = 16000 */ -extern int16_t CRendBin_HOA2_HRIR_max_num_iterations_16kHz; -extern uint16_t CRendBin_HOA2_HRIR_num_iterations_16kHz[9][BINAURAL_CHANNELS]; -extern uint16_t CRendBin_HOA2_HRIR_num_iterations_diffuse_16kHz[BINAURAL_CHANNELS]; -extern uint16_t CRendBin_HOA2_HRIR_pIndex_frequency_max_16kHz[9][BINAURAL_CHANNELS][1]; -extern uint16_t CRendBin_HOA2_HRIR_index_frequency_max_diffuse_16kHz; +extern Word16 CRendBin_HOA2_HRIR_max_num_iterations_16kHz; +extern UWord16 CRendBin_HOA2_HRIR_num_iterations_16kHz[9][BINAURAL_CHANNELS]; +extern UWord16 CRendBin_HOA2_HRIR_num_iterations_diffuse_16kHz[BINAURAL_CHANNELS]; +extern UWord16 CRendBin_HOA2_HRIR_pIndex_frequency_max_16kHz[9][BINAURAL_CHANNELS][1]; +extern UWord16 CRendBin_HOA2_HRIR_index_frequency_max_diffuse_16kHz; extern Word16 CRendBin_HOA2_HRIR_inv_diffuse_weight_16kHz_fx[9]; -extern uint16_t *CRendBin_HOA2_HRIR_pIndex_frequency_max_diffuse_16kHz[BINAURAL_CHANNELS]; +extern UWord16 *CRendBin_HOA2_HRIR_pIndex_frequency_max_diffuse_16kHz[BINAURAL_CHANNELS]; extern Word32 CRendBin_HOA2_HRIR_coeff_re_16kHz_fx[9][BINAURAL_CHANNELS][80]; extern Word32 CRendBin_HOA2_HRIR_coeff_im_16kHz_fx[9][BINAURAL_CHANNELS][80]; extern Word32 *CRendBin_HOA2_HRIR_coeff_diffuse_re_16kHz_fx[BINAURAL_CHANNELS]; @@ -200,13 +200,13 @@ extern Word32 CRendBin_HOA3_HRIR_latency_s_fx; /* Sample Rate = 48000 */ -extern int16_t CRendBin_HOA3_HRIR_max_num_iterations_48kHz; -extern uint16_t CRendBin_HOA3_HRIR_num_iterations_48kHz[16][BINAURAL_CHANNELS]; -extern uint16_t CRendBin_HOA3_HRIR_num_iterations_diffuse_48kHz[BINAURAL_CHANNELS]; -extern uint16_t CRendBin_HOA3_HRIR_pIndex_frequency_max_48kHz[16][BINAURAL_CHANNELS][1]; -extern uint16_t CRendBin_HOA3_HRIR_index_frequency_max_diffuse_48kHz; +extern Word16 CRendBin_HOA3_HRIR_max_num_iterations_48kHz; +extern UWord16 CRendBin_HOA3_HRIR_num_iterations_48kHz[16][BINAURAL_CHANNELS]; +extern UWord16 CRendBin_HOA3_HRIR_num_iterations_diffuse_48kHz[BINAURAL_CHANNELS]; +extern UWord16 CRendBin_HOA3_HRIR_pIndex_frequency_max_48kHz[16][BINAURAL_CHANNELS][1]; +extern UWord16 CRendBin_HOA3_HRIR_index_frequency_max_diffuse_48kHz; extern Word16 CRendBin_HOA3_HRIR_inv_diffuse_weight_48kHz_fx[16]; -extern uint16_t *CRendBin_HOA3_HRIR_pIndex_frequency_max_diffuse_48kHz[BINAURAL_CHANNELS]; +extern UWord16 *CRendBin_HOA3_HRIR_pIndex_frequency_max_diffuse_48kHz[BINAURAL_CHANNELS]; extern Word32 CRendBin_HOA3_HRIR_coeff_re_48kHz_fx[16][BINAURAL_CHANNELS][240]; extern Word32 CRendBin_HOA3_HRIR_coeff_im_48kHz_fx[16][BINAURAL_CHANNELS][240]; extern Word32 *CRendBin_HOA3_HRIR_coeff_diffuse_re_48kHz_fx[BINAURAL_CHANNELS]; @@ -214,13 +214,13 @@ extern Word32 *CRendBin_HOA3_HRIR_coeff_diffuse_im_48kHz_fx[BINAURAL_CHANNELS]; /* Sample Rate = 32000 */ -extern int16_t CRendBin_HOA3_HRIR_max_num_iterations_32kHz; -extern uint16_t CRendBin_HOA3_HRIR_num_iterations_32kHz[16][BINAURAL_CHANNELS]; -extern uint16_t CRendBin_HOA3_HRIR_num_iterations_diffuse_32kHz[BINAURAL_CHANNELS]; -extern uint16_t CRendBin_HOA3_HRIR_pIndex_frequency_max_32kHz[16][BINAURAL_CHANNELS][1]; -extern uint16_t CRendBin_HOA3_HRIR_index_frequency_max_diffuse_32kHz; +extern Word16 CRendBin_HOA3_HRIR_max_num_iterations_32kHz; +extern UWord16 CRendBin_HOA3_HRIR_num_iterations_32kHz[16][BINAURAL_CHANNELS]; +extern UWord16 CRendBin_HOA3_HRIR_num_iterations_diffuse_32kHz[BINAURAL_CHANNELS]; +extern UWord16 CRendBin_HOA3_HRIR_pIndex_frequency_max_32kHz[16][BINAURAL_CHANNELS][1]; +extern UWord16 CRendBin_HOA3_HRIR_index_frequency_max_diffuse_32kHz; extern Word16 CRendBin_HOA3_HRIR_inv_diffuse_weight_32kHz_fx[16]; -extern uint16_t *CRendBin_HOA3_HRIR_pIndex_frequency_max_diffuse_32kHz[BINAURAL_CHANNELS]; +extern UWord16 *CRendBin_HOA3_HRIR_pIndex_frequency_max_diffuse_32kHz[BINAURAL_CHANNELS]; extern Word32 CRendBin_HOA3_HRIR_coeff_re_32kHz_fx[16][BINAURAL_CHANNELS][160]; extern Word32 CRendBin_HOA3_HRIR_coeff_im_32kHz_fx[16][BINAURAL_CHANNELS][160]; extern Word32 *CRendBin_HOA3_HRIR_coeff_diffuse_re_32kHz_fx[BINAURAL_CHANNELS]; @@ -228,13 +228,13 @@ extern Word32 *CRendBin_HOA3_HRIR_coeff_diffuse_im_32kHz_fx[BINAURAL_CHANNELS]; /* Sample Rate = 16000 */ -extern int16_t CRendBin_HOA3_HRIR_max_num_iterations_16kHz; -extern uint16_t CRendBin_HOA3_HRIR_num_iterations_16kHz[16][BINAURAL_CHANNELS]; -extern uint16_t CRendBin_HOA3_HRIR_num_iterations_diffuse_16kHz[BINAURAL_CHANNELS]; -extern uint16_t CRendBin_HOA3_HRIR_pIndex_frequency_max_16kHz[16][BINAURAL_CHANNELS][1]; -extern uint16_t CRendBin_HOA3_HRIR_index_frequency_max_diffuse_16kHz; +extern Word16 CRendBin_HOA3_HRIR_max_num_iterations_16kHz; +extern UWord16 CRendBin_HOA3_HRIR_num_iterations_16kHz[16][BINAURAL_CHANNELS]; +extern UWord16 CRendBin_HOA3_HRIR_num_iterations_diffuse_16kHz[BINAURAL_CHANNELS]; +extern UWord16 CRendBin_HOA3_HRIR_pIndex_frequency_max_16kHz[16][BINAURAL_CHANNELS][1]; +extern UWord16 CRendBin_HOA3_HRIR_index_frequency_max_diffuse_16kHz; extern Word16 CRendBin_HOA3_HRIR_inv_diffuse_weight_16kHz_fx[16]; -extern uint16_t *CRendBin_HOA3_HRIR_pIndex_frequency_max_diffuse_16kHz[BINAURAL_CHANNELS]; +extern UWord16 *CRendBin_HOA3_HRIR_pIndex_frequency_max_diffuse_16kHz[BINAURAL_CHANNELS]; extern Word32 CRendBin_HOA3_HRIR_coeff_re_16kHz_fx[16][BINAURAL_CHANNELS][80]; extern Word32 CRendBin_HOA3_HRIR_coeff_im_16kHz_fx[16][BINAURAL_CHANNELS][80]; extern Word32 *CRendBin_HOA3_HRIR_coeff_diffuse_re_16kHz_fx[BINAURAL_CHANNELS]; @@ -248,13 +248,13 @@ extern Word32 CRendBin_Combined_BRIR_latency_s_fx; /* Sample Rate = 48000 */ -extern int16_t CRendBin_Combined_BRIR_max_num_iterations_48kHz; -extern uint16_t CRendBin_Combined_BRIR_num_iterations_48kHz[15][BINAURAL_CHANNELS]; -extern uint16_t CRendBin_Combined_BRIR_num_iterations_diffuse_48kHz[BINAURAL_CHANNELS]; -extern uint16_t CRendBin_Combined_BRIR_pIndex_frequency_max_48kHz[15][BINAURAL_CHANNELS][22]; -extern uint16_t CRendBin_Combined_BRIR_index_frequency_max_diffuse_48kHz; +extern Word16 CRendBin_Combined_BRIR_max_num_iterations_48kHz; +extern UWord16 CRendBin_Combined_BRIR_num_iterations_48kHz[15][BINAURAL_CHANNELS]; +extern UWord16 CRendBin_Combined_BRIR_num_iterations_diffuse_48kHz[BINAURAL_CHANNELS]; +extern UWord16 CRendBin_Combined_BRIR_pIndex_frequency_max_48kHz[15][BINAURAL_CHANNELS][22]; +extern UWord16 CRendBin_Combined_BRIR_index_frequency_max_diffuse_48kHz; extern Word16 CRendBin_Combined_BRIR_inv_diffuse_weight_48kHz_fx[15]; -extern uint16_t CRendBin_Combined_BRIR_pIndex_frequency_max_diffuse_48kHz[BINAURAL_CHANNELS][40]; +extern UWord16 CRendBin_Combined_BRIR_pIndex_frequency_max_diffuse_48kHz[BINAURAL_CHANNELS][40]; extern Word32 CRendBin_Combined_BRIR_coeff_re_48kHz_fx[15][BINAURAL_CHANNELS][2955]; extern Word32 CRendBin_Combined_BRIR_coeff_im_48kHz_fx[15][BINAURAL_CHANNELS][2955]; extern Word32 CRendBin_Combined_BRIR_coeff_diffuse_re_48kHz_fx[BINAURAL_CHANNELS][2885]; @@ -262,13 +262,13 @@ extern Word32 CRendBin_Combined_BRIR_coeff_diffuse_im_48kHz_fx[BINAURAL_CHANNELS /* Sample Rate = 32000 */ -extern int16_t CRendBin_Combined_BRIR_max_num_iterations_32kHz; -extern uint16_t CRendBin_Combined_BRIR_num_iterations_32kHz[15][BINAURAL_CHANNELS]; -extern uint16_t CRendBin_Combined_BRIR_num_iterations_diffuse_32kHz[BINAURAL_CHANNELS]; -extern uint16_t CRendBin_Combined_BRIR_pIndex_frequency_max_32kHz[15][BINAURAL_CHANNELS][22]; -extern uint16_t CRendBin_Combined_BRIR_index_frequency_max_diffuse_32kHz; +extern Word16 CRendBin_Combined_BRIR_max_num_iterations_32kHz; +extern UWord16 CRendBin_Combined_BRIR_num_iterations_32kHz[15][BINAURAL_CHANNELS]; +extern UWord16 CRendBin_Combined_BRIR_num_iterations_diffuse_32kHz[BINAURAL_CHANNELS]; +extern UWord16 CRendBin_Combined_BRIR_pIndex_frequency_max_32kHz[15][BINAURAL_CHANNELS][22]; +extern UWord16 CRendBin_Combined_BRIR_index_frequency_max_diffuse_32kHz; extern Word16 CRendBin_Combined_BRIR_inv_diffuse_weight_32kHz_fx[15]; -extern uint16_t CRendBin_Combined_BRIR_pIndex_frequency_max_diffuse_32kHz[BINAURAL_CHANNELS][40]; +extern UWord16 CRendBin_Combined_BRIR_pIndex_frequency_max_diffuse_32kHz[BINAURAL_CHANNELS][40]; extern Word32 CRendBin_Combined_BRIR_coeff_re_32kHz_fx[15][BINAURAL_CHANNELS][2819]; extern Word32 CRendBin_Combined_BRIR_coeff_im_32kHz_fx[15][BINAURAL_CHANNELS][2819]; extern Word32 CRendBin_Combined_BRIR_coeff_diffuse_re_32kHz_fx[BINAURAL_CHANNELS][2870]; @@ -276,13 +276,13 @@ extern Word32 CRendBin_Combined_BRIR_coeff_diffuse_im_32kHz_fx[BINAURAL_CHANNELS /* Sample Rate = 16000 */ -extern int16_t CRendBin_Combined_BRIR_max_num_iterations_16kHz; -extern uint16_t CRendBin_Combined_BRIR_num_iterations_16kHz[15][BINAURAL_CHANNELS]; -extern uint16_t CRendBin_Combined_BRIR_num_iterations_diffuse_16kHz[BINAURAL_CHANNELS]; -extern uint16_t CRendBin_Combined_BRIR_pIndex_frequency_max_16kHz[15][BINAURAL_CHANNELS][23]; -extern uint16_t CRendBin_Combined_BRIR_index_frequency_max_diffuse_16kHz; +extern Word16 CRendBin_Combined_BRIR_max_num_iterations_16kHz; +extern UWord16 CRendBin_Combined_BRIR_num_iterations_16kHz[15][BINAURAL_CHANNELS]; +extern UWord16 CRendBin_Combined_BRIR_num_iterations_diffuse_16kHz[BINAURAL_CHANNELS]; +extern UWord16 CRendBin_Combined_BRIR_pIndex_frequency_max_16kHz[15][BINAURAL_CHANNELS][23]; +extern UWord16 CRendBin_Combined_BRIR_index_frequency_max_diffuse_16kHz; extern Word16 CRendBin_Combined_BRIR_inv_diffuse_weight_16kHz_fx[15]; -extern uint16_t CRendBin_Combined_BRIR_pIndex_frequency_max_diffuse_16kHz[BINAURAL_CHANNELS][40]; +extern UWord16 CRendBin_Combined_BRIR_pIndex_frequency_max_diffuse_16kHz[BINAURAL_CHANNELS][40]; extern Word32 CRendBin_Combined_BRIR_coeff_re_16kHz_fx[15][BINAURAL_CHANNELS][1774]; extern Word32 CRendBin_Combined_BRIR_coeff_im_16kHz_fx[15][BINAURAL_CHANNELS][1774]; extern Word32 CRendBin_Combined_BRIR_coeff_diffuse_re_16kHz_fx[BINAURAL_CHANNELS][2522]; diff --git a/lib_rend/ivas_rom_binaural_crend_head.c b/lib_rend/ivas_rom_binaural_crend_head_fx.c similarity index 99% rename from lib_rend/ivas_rom_binaural_crend_head.c rename to lib_rend/ivas_rom_binaural_crend_head_fx.c index 60925a31fa9b898a5595cd853669cd0307ccbae5..be015058b11ea110a13953c52676ad6ac5cdc9b3 100644 --- a/lib_rend/ivas_rom_binaural_crend_head.c +++ b/lib_rend/ivas_rom_binaural_crend_head_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other @@ -56,35 +56,35 @@ const Word32 CRendBin_Combined_HRIR_latency_s_fx = 44741;/*Q-31*/ /* Sample Rate = 48000 */ -const int16_t CRendBin_Combined_HRIR_max_num_iterations_48kHz = 1; -const uint16_t CRendBin_Combined_HRIR_num_iterations_48kHz[15][BINAURAL_CHANNELS]={{1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1} }; -const uint16_t CRendBin_Combined_HRIR_num_iterations_diffuse_48kHz[BINAURAL_CHANNELS] = {0, 0}; -const uint16_t CRendBin_Combined_HRIR_pIndex_frequency_max_48kHz[15][BINAURAL_CHANNELS][1]={{{240},{240}},{{240},{240}},{{240},{240}},{{240},{240}},{{240},{240}},{{240},{240}},{{240},{240}},{{240},{240}},{{240},{240}},{{240},{240}},{{240},{240}},{{240},{240}},{{240},{240}},{{240},{240}},{{240},{240}}}; -const uint16_t CRendBin_Combined_HRIR_index_frequency_max_diffuse_48kHz = 0; +const Word16 CRendBin_Combined_HRIR_max_num_iterations_48kHz = 1; +const UWord16 CRendBin_Combined_HRIR_num_iterations_48kHz[15][BINAURAL_CHANNELS]={{1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1} }; +const UWord16 CRendBin_Combined_HRIR_num_iterations_diffuse_48kHz[BINAURAL_CHANNELS] = {0, 0}; +const UWord16 CRendBin_Combined_HRIR_pIndex_frequency_max_48kHz[15][BINAURAL_CHANNELS][1]={{{240},{240}},{{240},{240}},{{240},{240}},{{240},{240}},{{240},{240}},{{240},{240}},{{240},{240}},{{240},{240}},{{240},{240}},{{240},{240}},{{240},{240}},{{240},{240}},{{240},{240}},{{240},{240}},{{240},{240}}}; +const UWord16 CRendBin_Combined_HRIR_index_frequency_max_diffuse_48kHz = 0; const Word16 CRendBin_Combined_HRIR_inv_diffuse_weight_48kHz_fx[15]={0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,}; -const uint16_t *CRendBin_Combined_HRIR_pIndex_frequency_max_diffuse_48kHz[BINAURAL_CHANNELS]={NULL,NULL}; +const UWord16 *CRendBin_Combined_HRIR_pIndex_frequency_max_diffuse_48kHz[BINAURAL_CHANNELS]={NULL,NULL}; const Word32 *CRendBin_Combined_HRIR_coeff_diffuse_re_48kHz_fx[BINAURAL_CHANNELS]={NULL,NULL}; const Word32 *CRendBin_Combined_HRIR_coeff_diffuse_im_48kHz_fx[BINAURAL_CHANNELS]={NULL,NULL}; /* Sample Rate = 32000 */ -const int16_t CRendBin_Combined_HRIR_max_num_iterations_32kHz = 1; -const uint16_t CRendBin_Combined_HRIR_num_iterations_32kHz[15][BINAURAL_CHANNELS]={{1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1} }; -const uint16_t CRendBin_Combined_HRIR_num_iterations_diffuse_32kHz[BINAURAL_CHANNELS] = {0, 0}; -const uint16_t CRendBin_Combined_HRIR_pIndex_frequency_max_32kHz[15][BINAURAL_CHANNELS][1]={{{160},{160}},{{160},{160}},{{160},{160}},{{160},{160}},{{160},{160}},{{160},{160}},{{160},{160}},{{160},{160}},{{160},{160}},{{160},{160}},{{160},{160}},{{160},{160}},{{160},{160}},{{160},{160}},{{160},{160}}}; -const uint16_t CRendBin_Combined_HRIR_index_frequency_max_diffuse_32kHz = 0; +const Word16 CRendBin_Combined_HRIR_max_num_iterations_32kHz = 1; +const UWord16 CRendBin_Combined_HRIR_num_iterations_32kHz[15][BINAURAL_CHANNELS]={{1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1} }; +const UWord16 CRendBin_Combined_HRIR_num_iterations_diffuse_32kHz[BINAURAL_CHANNELS] = {0, 0}; +const UWord16 CRendBin_Combined_HRIR_pIndex_frequency_max_32kHz[15][BINAURAL_CHANNELS][1]={{{160},{160}},{{160},{160}},{{160},{160}},{{160},{160}},{{160},{160}},{{160},{160}},{{160},{160}},{{160},{160}},{{160},{160}},{{160},{160}},{{160},{160}},{{160},{160}},{{160},{160}},{{160},{160}},{{160},{160}}}; +const UWord16 CRendBin_Combined_HRIR_index_frequency_max_diffuse_32kHz = 0; const Word16 CRendBin_Combined_HRIR_inv_diffuse_weight_32kHz_fx[15]={0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,}; -const uint16_t *CRendBin_Combined_HRIR_pIndex_frequency_max_diffuse_32kHz[BINAURAL_CHANNELS]={NULL,NULL}; +const UWord16 *CRendBin_Combined_HRIR_pIndex_frequency_max_diffuse_32kHz[BINAURAL_CHANNELS]={NULL,NULL}; const Word32 *CRendBin_Combined_HRIR_coeff_diffuse_re_32kHz_fx[BINAURAL_CHANNELS]={NULL,NULL}; const Word32 *CRendBin_Combined_HRIR_coeff_diffuse_im_32kHz_fx[BINAURAL_CHANNELS]={NULL,NULL}; /* Sample Rate = 16000 */ -const int16_t CRendBin_Combined_HRIR_max_num_iterations_16kHz = 1; -const uint16_t CRendBin_Combined_HRIR_num_iterations_16kHz[15][BINAURAL_CHANNELS]={{1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1} }; -const uint16_t CRendBin_Combined_HRIR_num_iterations_diffuse_16kHz[BINAURAL_CHANNELS] = {0, 0}; -const uint16_t CRendBin_Combined_HRIR_pIndex_frequency_max_16kHz[15][BINAURAL_CHANNELS][1]={{{80},{80}},{{80},{80}},{{80},{80}},{{80},{80}},{{80},{80}},{{80},{80}},{{80},{80}},{{80},{80}},{{80},{80}},{{80},{80}},{{80},{80}},{{80},{80}},{{80},{80}},{{80},{80}},{{80},{80}}}; -const uint16_t CRendBin_Combined_HRIR_index_frequency_max_diffuse_16kHz = 0; +const Word16 CRendBin_Combined_HRIR_max_num_iterations_16kHz = 1; +const UWord16 CRendBin_Combined_HRIR_num_iterations_16kHz[15][BINAURAL_CHANNELS]={{1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1} }; +const UWord16 CRendBin_Combined_HRIR_num_iterations_diffuse_16kHz[BINAURAL_CHANNELS] = {0, 0}; +const UWord16 CRendBin_Combined_HRIR_pIndex_frequency_max_16kHz[15][BINAURAL_CHANNELS][1]={{{80},{80}},{{80},{80}},{{80},{80}},{{80},{80}},{{80},{80}},{{80},{80}},{{80},{80}},{{80},{80}},{{80},{80}},{{80},{80}},{{80},{80}},{{80},{80}},{{80},{80}},{{80},{80}},{{80},{80}}}; +const UWord16 CRendBin_Combined_HRIR_index_frequency_max_diffuse_16kHz = 0; const Word16 CRendBin_Combined_HRIR_inv_diffuse_weight_16kHz_fx[15]={0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,}; -const uint16_t *CRendBin_Combined_HRIR_pIndex_frequency_max_diffuse_16kHz[BINAURAL_CHANNELS]={NULL,NULL}; +const UWord16 *CRendBin_Combined_HRIR_pIndex_frequency_max_diffuse_16kHz[BINAURAL_CHANNELS]={NULL,NULL}; const Word32 *CRendBin_Combined_HRIR_coeff_diffuse_re_16kHz_fx[BINAURAL_CHANNELS]={NULL,NULL}; const Word32 *CRendBin_Combined_HRIR_coeff_diffuse_im_16kHz_fx[BINAURAL_CHANNELS]={NULL,NULL}; @@ -96,35 +96,35 @@ const Word32 CRendBin_FOA_HRIR_latency_s_fx = 44741; // Q31 /* Sample Rate = 48000 */ -const int16_t CRendBin_FOA_HRIR_max_num_iterations_48kHz = 1; -const uint16_t CRendBin_FOA_HRIR_num_iterations_48kHz[4][BINAURAL_CHANNELS]={{1, 1}, {1, 1}, {1, 1}, {1, 1} }; -const uint16_t CRendBin_FOA_HRIR_num_iterations_diffuse_48kHz[BINAURAL_CHANNELS] = {0, 0}; -const uint16_t CRendBin_FOA_HRIR_pIndex_frequency_max_48kHz[4][BINAURAL_CHANNELS][1]={{{240},{240}},{{240},{240}},{{240},{240}},{{240},{240}}}; -const uint16_t CRendBin_FOA_HRIR_index_frequency_max_diffuse_48kHz = 0; +const Word16 CRendBin_FOA_HRIR_max_num_iterations_48kHz = 1; +const UWord16 CRendBin_FOA_HRIR_num_iterations_48kHz[4][BINAURAL_CHANNELS]={{1, 1}, {1, 1}, {1, 1}, {1, 1} }; +const UWord16 CRendBin_FOA_HRIR_num_iterations_diffuse_48kHz[BINAURAL_CHANNELS] = {0, 0}; +const UWord16 CRendBin_FOA_HRIR_pIndex_frequency_max_48kHz[4][BINAURAL_CHANNELS][1]={{{240},{240}},{{240},{240}},{{240},{240}},{{240},{240}}}; +const UWord16 CRendBin_FOA_HRIR_index_frequency_max_diffuse_48kHz = 0; const Word16 CRendBin_FOA_HRIR_inv_diffuse_weight_48kHz_fx[4]={0, 0, 0, 0}; -const uint16_t *CRendBin_FOA_HRIR_pIndex_frequency_max_diffuse_48kHz[BINAURAL_CHANNELS]={NULL,NULL}; +const UWord16 *CRendBin_FOA_HRIR_pIndex_frequency_max_diffuse_48kHz[BINAURAL_CHANNELS]={NULL,NULL}; const Word32 *CRendBin_FOA_HRIR_coeff_diffuse_re_48kHz_fx[BINAURAL_CHANNELS]={NULL,NULL}; const Word32 *CRendBin_FOA_HRIR_coeff_diffuse_im_48kHz_fx[BINAURAL_CHANNELS]={NULL,NULL}; /* Sample Rate = 32000 */ -const int16_t CRendBin_FOA_HRIR_max_num_iterations_32kHz = 1; -const uint16_t CRendBin_FOA_HRIR_num_iterations_32kHz[4][BINAURAL_CHANNELS]={{1, 1}, {1, 1}, {1, 1}, {1, 1} }; -const uint16_t CRendBin_FOA_HRIR_num_iterations_diffuse_32kHz[BINAURAL_CHANNELS] = {0, 0}; -const uint16_t CRendBin_FOA_HRIR_pIndex_frequency_max_32kHz[4][BINAURAL_CHANNELS][1]={{{160},{160}},{{160},{160}},{{160},{160}},{{160},{160}}}; -const uint16_t CRendBin_FOA_HRIR_index_frequency_max_diffuse_32kHz = 0; +const Word16 CRendBin_FOA_HRIR_max_num_iterations_32kHz = 1; +const UWord16 CRendBin_FOA_HRIR_num_iterations_32kHz[4][BINAURAL_CHANNELS]={{1, 1}, {1, 1}, {1, 1}, {1, 1} }; +const UWord16 CRendBin_FOA_HRIR_num_iterations_diffuse_32kHz[BINAURAL_CHANNELS] = {0, 0}; +const UWord16 CRendBin_FOA_HRIR_pIndex_frequency_max_32kHz[4][BINAURAL_CHANNELS][1]={{{160},{160}},{{160},{160}},{{160},{160}},{{160},{160}}}; +const UWord16 CRendBin_FOA_HRIR_index_frequency_max_diffuse_32kHz = 0; const Word16 CRendBin_FOA_HRIR_inv_diffuse_weight_32kHz_fx[4]={0, 0, 0, 0}; -const uint16_t *CRendBin_FOA_HRIR_pIndex_frequency_max_diffuse_32kHz[BINAURAL_CHANNELS]={NULL,NULL}; +const UWord16 *CRendBin_FOA_HRIR_pIndex_frequency_max_diffuse_32kHz[BINAURAL_CHANNELS]={NULL,NULL}; const Word32 *CRendBin_FOA_HRIR_coeff_diffuse_re_32kHz_fx[BINAURAL_CHANNELS]={NULL,NULL}; const Word32 *CRendBin_FOA_HRIR_coeff_diffuse_im_32kHz_fx[BINAURAL_CHANNELS]={NULL,NULL}; /* Sample Rate = 16000 */ -const int16_t CRendBin_FOA_HRIR_max_num_iterations_16kHz = 1; -const uint16_t CRendBin_FOA_HRIR_num_iterations_16kHz[4][BINAURAL_CHANNELS]={{1, 1}, {1, 1}, {1, 1}, {1, 1} }; -const uint16_t CRendBin_FOA_HRIR_num_iterations_diffuse_16kHz[BINAURAL_CHANNELS] = {0, 0}; -const uint16_t CRendBin_FOA_HRIR_pIndex_frequency_max_16kHz[4][BINAURAL_CHANNELS][1]={{{80},{80}},{{80},{80}},{{80},{80}},{{80},{80}}}; -const uint16_t CRendBin_FOA_HRIR_index_frequency_max_diffuse_16kHz = 0; +const Word16 CRendBin_FOA_HRIR_max_num_iterations_16kHz = 1; +const UWord16 CRendBin_FOA_HRIR_num_iterations_16kHz[4][BINAURAL_CHANNELS]={{1, 1}, {1, 1}, {1, 1}, {1, 1} }; +const UWord16 CRendBin_FOA_HRIR_num_iterations_diffuse_16kHz[BINAURAL_CHANNELS] = {0, 0}; +const UWord16 CRendBin_FOA_HRIR_pIndex_frequency_max_16kHz[4][BINAURAL_CHANNELS][1]={{{80},{80}},{{80},{80}},{{80},{80}},{{80},{80}}}; +const UWord16 CRendBin_FOA_HRIR_index_frequency_max_diffuse_16kHz = 0; const Word16 CRendBin_FOA_HRIR_inv_diffuse_weight_16kHz_fx[4]={0, 0, 0, 0}; -const uint16_t *CRendBin_FOA_HRIR_pIndex_frequency_max_diffuse_16kHz[BINAURAL_CHANNELS]={NULL,NULL}; +const UWord16 *CRendBin_FOA_HRIR_pIndex_frequency_max_diffuse_16kHz[BINAURAL_CHANNELS]={NULL,NULL}; const Word32 *CRendBin_FOA_HRIR_coeff_diffuse_re_16kHz_fx[BINAURAL_CHANNELS]={NULL,NULL}; const Word32 *CRendBin_FOA_HRIR_coeff_diffuse_im_16kHz_fx[BINAURAL_CHANNELS]={NULL,NULL}; @@ -135,35 +135,35 @@ const Word32 CRendBin_HOA2_HRIR_latency_s_fx = 44741; // Q31 /* Sample Rate = 48000 */ -const int16_t CRendBin_HOA2_HRIR_max_num_iterations_48kHz = 1; -const uint16_t CRendBin_HOA2_HRIR_num_iterations_48kHz[9][BINAURAL_CHANNELS]={{1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1} }; -const uint16_t CRendBin_HOA2_HRIR_num_iterations_diffuse_48kHz[BINAURAL_CHANNELS] = {0, 0}; -const uint16_t CRendBin_HOA2_HRIR_pIndex_frequency_max_48kHz[9][BINAURAL_CHANNELS][1]={{{240},{240}},{{240},{240}},{{240},{240}},{{240},{240}},{{240},{240}},{{240},{240}},{{240},{240}},{{240},{240}},{{240},{240}}}; -const uint16_t CRendBin_HOA2_HRIR_index_frequency_max_diffuse_48kHz = 0; +const Word16 CRendBin_HOA2_HRIR_max_num_iterations_48kHz = 1; +const UWord16 CRendBin_HOA2_HRIR_num_iterations_48kHz[9][BINAURAL_CHANNELS]={{1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1} }; +const UWord16 CRendBin_HOA2_HRIR_num_iterations_diffuse_48kHz[BINAURAL_CHANNELS] = {0, 0}; +const UWord16 CRendBin_HOA2_HRIR_pIndex_frequency_max_48kHz[9][BINAURAL_CHANNELS][1]={{{240},{240}},{{240},{240}},{{240},{240}},{{240},{240}},{{240},{240}},{{240},{240}},{{240},{240}},{{240},{240}},{{240},{240}}}; +const UWord16 CRendBin_HOA2_HRIR_index_frequency_max_diffuse_48kHz = 0; const Word16 CRendBin_HOA2_HRIR_inv_diffuse_weight_48kHz_fx[9]={0, 0, 0, 0, 0, 0, 0, 0, 0}; -const uint16_t *CRendBin_HOA2_HRIR_pIndex_frequency_max_diffuse_48kHz[BINAURAL_CHANNELS]={NULL,NULL}; +const UWord16 *CRendBin_HOA2_HRIR_pIndex_frequency_max_diffuse_48kHz[BINAURAL_CHANNELS]={NULL,NULL}; const Word32 *CRendBin_HOA2_HRIR_coeff_diffuse_re_48kHz_fx[BINAURAL_CHANNELS]={NULL,NULL}; const Word32 *CRendBin_HOA2_HRIR_coeff_diffuse_im_48kHz_fx[BINAURAL_CHANNELS]={NULL,NULL}; /* Sample Rate = 32000 */ -const int16_t CRendBin_HOA2_HRIR_max_num_iterations_32kHz = 1; -const uint16_t CRendBin_HOA2_HRIR_num_iterations_32kHz[9][BINAURAL_CHANNELS]={{1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1} }; -const uint16_t CRendBin_HOA2_HRIR_num_iterations_diffuse_32kHz[BINAURAL_CHANNELS] = {0, 0}; -const uint16_t CRendBin_HOA2_HRIR_pIndex_frequency_max_32kHz[9][BINAURAL_CHANNELS][1]={{{160},{160}},{{160},{160}},{{160},{160}},{{160},{160}},{{160},{160}},{{160},{160}},{{160},{160}},{{160},{160}},{{160},{160}}}; -const uint16_t CRendBin_HOA2_HRIR_index_frequency_max_diffuse_32kHz = 0; +const Word16 CRendBin_HOA2_HRIR_max_num_iterations_32kHz = 1; +const UWord16 CRendBin_HOA2_HRIR_num_iterations_32kHz[9][BINAURAL_CHANNELS]={{1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1} }; +const UWord16 CRendBin_HOA2_HRIR_num_iterations_diffuse_32kHz[BINAURAL_CHANNELS] = {0, 0}; +const UWord16 CRendBin_HOA2_HRIR_pIndex_frequency_max_32kHz[9][BINAURAL_CHANNELS][1]={{{160},{160}},{{160},{160}},{{160},{160}},{{160},{160}},{{160},{160}},{{160},{160}},{{160},{160}},{{160},{160}},{{160},{160}}}; +const UWord16 CRendBin_HOA2_HRIR_index_frequency_max_diffuse_32kHz = 0; const Word16 CRendBin_HOA2_HRIR_inv_diffuse_weight_32kHz_fx[9]={0, 0, 0, 0, 0, 0, 0, 0, 0}; -const uint16_t *CRendBin_HOA2_HRIR_pIndex_frequency_max_diffuse_32kHz[BINAURAL_CHANNELS]={NULL,NULL}; +const UWord16 *CRendBin_HOA2_HRIR_pIndex_frequency_max_diffuse_32kHz[BINAURAL_CHANNELS]={NULL,NULL}; const Word32 *CRendBin_HOA2_HRIR_coeff_diffuse_re_32kHz_fx[BINAURAL_CHANNELS]={NULL,NULL}; const Word32 *CRendBin_HOA2_HRIR_coeff_diffuse_im_32kHz_fx[BINAURAL_CHANNELS]={NULL,NULL}; /* Sample Rate = 16000 */ -const int16_t CRendBin_HOA2_HRIR_max_num_iterations_16kHz = 1; -const uint16_t CRendBin_HOA2_HRIR_num_iterations_16kHz[9][BINAURAL_CHANNELS]={{1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1} }; -const uint16_t CRendBin_HOA2_HRIR_num_iterations_diffuse_16kHz[BINAURAL_CHANNELS] = {0, 0}; -const uint16_t CRendBin_HOA2_HRIR_pIndex_frequency_max_16kHz[9][BINAURAL_CHANNELS][1]={{{80},{80}},{{80},{80}},{{80},{80}},{{80},{80}},{{80},{80}},{{80},{80}},{{80},{80}},{{80},{80}},{{80},{80}}}; -const uint16_t CRendBin_HOA2_HRIR_index_frequency_max_diffuse_16kHz = 0; +const Word16 CRendBin_HOA2_HRIR_max_num_iterations_16kHz = 1; +const UWord16 CRendBin_HOA2_HRIR_num_iterations_16kHz[9][BINAURAL_CHANNELS]={{1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1} }; +const UWord16 CRendBin_HOA2_HRIR_num_iterations_diffuse_16kHz[BINAURAL_CHANNELS] = {0, 0}; +const UWord16 CRendBin_HOA2_HRIR_pIndex_frequency_max_16kHz[9][BINAURAL_CHANNELS][1]={{{80},{80}},{{80},{80}},{{80},{80}},{{80},{80}},{{80},{80}},{{80},{80}},{{80},{80}},{{80},{80}},{{80},{80}}}; +const UWord16 CRendBin_HOA2_HRIR_index_frequency_max_diffuse_16kHz = 0; const Word16 CRendBin_HOA2_HRIR_inv_diffuse_weight_16kHz_fx[9]={0, 0, 0, 0, 0, 0, 0, 0, 0}; -const uint16_t *CRendBin_HOA2_HRIR_pIndex_frequency_max_diffuse_16kHz[BINAURAL_CHANNELS]={NULL,NULL}; +const UWord16 *CRendBin_HOA2_HRIR_pIndex_frequency_max_diffuse_16kHz[BINAURAL_CHANNELS]={NULL,NULL}; const Word32 *CRendBin_HOA2_HRIR_coeff_diffuse_re_16kHz_fx[BINAURAL_CHANNELS]={NULL,NULL}; const Word32 *CRendBin_HOA2_HRIR_coeff_diffuse_im_16kHz_fx[BINAURAL_CHANNELS]={NULL,NULL}; @@ -173,36 +173,36 @@ const Word32 *CRendBin_HOA2_HRIR_coeff_diffuse_im_16kHz_fx[BINAURAL_CHANNELS]={N const Word32 CRendBin_HOA3_HRIR_latency_s_fx = 44741;/*Q-31*/ /* Sample Rate = 48000 */ -const int16_t CRendBin_HOA3_HRIR_max_num_iterations_48kHz = 1; -const uint16_t CRendBin_HOA3_HRIR_num_iterations_48kHz[16][BINAURAL_CHANNELS]={{1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1} }; -const uint16_t CRendBin_HOA3_HRIR_num_iterations_diffuse_48kHz[BINAURAL_CHANNELS] = {0, 0}; -const uint16_t CRendBin_HOA3_HRIR_pIndex_frequency_max_48kHz[16][BINAURAL_CHANNELS][1]={{{240},{240}},{{240},{240}},{{240},{240}},{{240},{240}},{{240},{240}},{{240},{240}},{{240},{240}},{{240},{240}},{{240},{240}},{{240},{240}},{{240},{240}},{{240},{240}},{{240},{240}},{{240},{240}},{{240},{240}},{{240},{240}}}; -const uint16_t CRendBin_HOA3_HRIR_index_frequency_max_diffuse_48kHz = 0; +const Word16 CRendBin_HOA3_HRIR_max_num_iterations_48kHz = 1; +const UWord16 CRendBin_HOA3_HRIR_num_iterations_48kHz[16][BINAURAL_CHANNELS]={{1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1} }; +const UWord16 CRendBin_HOA3_HRIR_num_iterations_diffuse_48kHz[BINAURAL_CHANNELS] = {0, 0}; +const UWord16 CRendBin_HOA3_HRIR_pIndex_frequency_max_48kHz[16][BINAURAL_CHANNELS][1]={{{240},{240}},{{240},{240}},{{240},{240}},{{240},{240}},{{240},{240}},{{240},{240}},{{240},{240}},{{240},{240}},{{240},{240}},{{240},{240}},{{240},{240}},{{240},{240}},{{240},{240}},{{240},{240}},{{240},{240}},{{240},{240}}}; +const UWord16 CRendBin_HOA3_HRIR_index_frequency_max_diffuse_48kHz = 0; const Word16 CRendBin_HOA3_HRIR_inv_diffuse_weight_48kHz_fx[16]={0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; -const uint16_t *CRendBin_HOA3_HRIR_pIndex_frequency_max_diffuse_48kHz[BINAURAL_CHANNELS]={NULL,NULL}; +const UWord16 *CRendBin_HOA3_HRIR_pIndex_frequency_max_diffuse_48kHz[BINAURAL_CHANNELS]={NULL,NULL}; const Word32 *CRendBin_HOA3_HRIR_coeff_diffuse_re_48kHz_fx[BINAURAL_CHANNELS]={NULL,NULL}; const Word32 *CRendBin_HOA3_HRIR_coeff_diffuse_im_48kHz_fx[BINAURAL_CHANNELS]={NULL,NULL}; /* Sample Rate = 32000 */ -const int16_t CRendBin_HOA3_HRIR_max_num_iterations_32kHz = 1; -const uint16_t CRendBin_HOA3_HRIR_num_iterations_32kHz[16][BINAURAL_CHANNELS]={{1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1} }; -const uint16_t CRendBin_HOA3_HRIR_num_iterations_diffuse_32kHz[BINAURAL_CHANNELS] = {0, 0}; -const uint16_t CRendBin_HOA3_HRIR_pIndex_frequency_max_32kHz[16][BINAURAL_CHANNELS][1]={{{160},{160}},{{160},{160}},{{160},{160}},{{160},{160}},{{160},{160}},{{160},{160}},{{160},{160}},{{160},{160}},{{160},{160}},{{160},{160}},{{160},{160}},{{160},{160}},{{160},{160}},{{160},{160}},{{160},{160}},{{160},{160}}}; -const uint16_t CRendBin_HOA3_HRIR_index_frequency_max_diffuse_32kHz = 0; +const Word16 CRendBin_HOA3_HRIR_max_num_iterations_32kHz = 1; +const UWord16 CRendBin_HOA3_HRIR_num_iterations_32kHz[16][BINAURAL_CHANNELS]={{1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1} }; +const UWord16 CRendBin_HOA3_HRIR_num_iterations_diffuse_32kHz[BINAURAL_CHANNELS] = {0, 0}; +const UWord16 CRendBin_HOA3_HRIR_pIndex_frequency_max_32kHz[16][BINAURAL_CHANNELS][1]={{{160},{160}},{{160},{160}},{{160},{160}},{{160},{160}},{{160},{160}},{{160},{160}},{{160},{160}},{{160},{160}},{{160},{160}},{{160},{160}},{{160},{160}},{{160},{160}},{{160},{160}},{{160},{160}},{{160},{160}},{{160},{160}}}; +const UWord16 CRendBin_HOA3_HRIR_index_frequency_max_diffuse_32kHz = 0; const Word16 CRendBin_HOA3_HRIR_inv_diffuse_weight_32kHz_fx[16]={0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; -const uint16_t *CRendBin_HOA3_HRIR_pIndex_frequency_max_diffuse_32kHz[BINAURAL_CHANNELS]={NULL,NULL}; +const UWord16 *CRendBin_HOA3_HRIR_pIndex_frequency_max_diffuse_32kHz[BINAURAL_CHANNELS]={NULL,NULL}; const Word32 *CRendBin_HOA3_HRIR_coeff_diffuse_re_32kHz_fx[BINAURAL_CHANNELS]={NULL,NULL}; const Word32 *CRendBin_HOA3_HRIR_coeff_diffuse_im_32kHz_fx[BINAURAL_CHANNELS]={NULL,NULL}; /* Sample Rate = 16000 */ -const int16_t CRendBin_HOA3_HRIR_max_num_iterations_16kHz = 1; -const uint16_t CRendBin_HOA3_HRIR_num_iterations_16kHz[16][BINAURAL_CHANNELS]={{1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1} }; -const uint16_t CRendBin_HOA3_HRIR_num_iterations_diffuse_16kHz[BINAURAL_CHANNELS] = {0, 0}; -const uint16_t CRendBin_HOA3_HRIR_pIndex_frequency_max_16kHz[16][BINAURAL_CHANNELS][1]={{{80},{80}},{{80},{80}},{{80},{80}},{{80},{80}},{{80},{80}},{{80},{80}},{{80},{80}},{{80},{80}},{{80},{80}},{{80},{80}},{{80},{80}},{{80},{80}},{{80},{80}},{{80},{80}},{{80},{80}},{{80},{80}}}; -const uint16_t CRendBin_HOA3_HRIR_index_frequency_max_diffuse_16kHz = 0; +const Word16 CRendBin_HOA3_HRIR_max_num_iterations_16kHz = 1; +const UWord16 CRendBin_HOA3_HRIR_num_iterations_16kHz[16][BINAURAL_CHANNELS]={{1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1} }; +const UWord16 CRendBin_HOA3_HRIR_num_iterations_diffuse_16kHz[BINAURAL_CHANNELS] = {0, 0}; +const UWord16 CRendBin_HOA3_HRIR_pIndex_frequency_max_16kHz[16][BINAURAL_CHANNELS][1]={{{80},{80}},{{80},{80}},{{80},{80}},{{80},{80}},{{80},{80}},{{80},{80}},{{80},{80}},{{80},{80}},{{80},{80}},{{80},{80}},{{80},{80}},{{80},{80}},{{80},{80}},{{80},{80}},{{80},{80}},{{80},{80}}}; +const UWord16 CRendBin_HOA3_HRIR_index_frequency_max_diffuse_16kHz = 0; const float CRendBin_HOA3_HRIR_inv_diffuse_weight_16kHz[16]={0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f}; const Word16 CRendBin_HOA3_HRIR_inv_diffuse_weight_16kHz_fx[16]={0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; -const uint16_t *CRendBin_HOA3_HRIR_pIndex_frequency_max_diffuse_16kHz[BINAURAL_CHANNELS]={NULL,NULL}; +const UWord16 *CRendBin_HOA3_HRIR_pIndex_frequency_max_diffuse_16kHz[BINAURAL_CHANNELS]={NULL,NULL}; const Word32 *CRendBin_HOA3_HRIR_coeff_diffuse_re_16kHz_fx[BINAURAL_CHANNELS]={NULL,NULL}; const Word32 *CRendBin_HOA3_HRIR_coeff_diffuse_im_16kHz_fx[BINAURAL_CHANNELS]={NULL,NULL}; @@ -212,34 +212,34 @@ const Word32 *CRendBin_HOA3_HRIR_coeff_diffuse_im_16kHz_fx[BINAURAL_CHANNELS]={N const Word32 CRendBin_Combined_BRIR_latency_s_fx = 313176;/*Q-31*/ /* Sample Rate = 48000 */ -const int16_t CRendBin_Combined_BRIR_max_num_iterations_48kHz = 22; -const uint16_t CRendBin_Combined_BRIR_num_iterations_48kHz[15][BINAURAL_CHANNELS]={{22, 22}, {22, 22}, {22, 22}, {22, 22}, {22, 22}, {22, 22}, {22, 22}, {22, 22}, {22, 22}, {22, 22}, {22, 22}, {22, 22}, {22, 22}, {22, 22}, {22, 22} }; -const uint16_t CRendBin_Combined_BRIR_num_iterations_diffuse_48kHz[BINAURAL_CHANNELS] = {40, 40}; -const uint16_t CRendBin_Combined_BRIR_pIndex_frequency_max_48kHz[15][BINAURAL_CHANNELS][22]={{{116, 118, 117, 121, 112, 119, 121, 131, 134, 131, 137, 127, 134, 135, 134, 135, 129, 139, 135, 130, 128, 240},{116, 118, 117, 121, 112, 119, 121, 131, 134, 131, 137, 127, 134, 135, 134, 135, 129, 139, 135, 130, 128, 240}},{{122, 106, 121, 114, 121, 123, 119, 126, 123, 126, 127, 130, 128, 136, 132, 131, 129, 141, 137, 131, 129, 240},{122, 106, 121, 114, 121, 123, 119, 126, 123, 126, 127, 130, 128, 136, 132, 131, 129, 141, 137, 131, 129, 240}},{{118, 104, 116, 104, 123, 123, 122, 125, 130, 128, 132, 135, 131, 132, 131, 132, 135, 137, 144, 129, 129, 240},{118, 104, 116, 104, 123, 123, 122, 125, 130, 128, 132, 135, 131, 132, 131, 132, 135, 137, 144, 129, 129, 240}},{{102, 117, 116, 121, 117, 114, 115, 125, 126, 124, 125, 142, 133, 124, 129, 132, 134, 137, 143, 125, 125, 240},{102, 117, 116, 121, 117, 114, 115, 125, 126, 124, 125, 142, 133, 124, 129, 132, 134, 137, 143, 125, 125, 240}},{{116, 115, 117, 120, 121, 119, 125, 129, 123, 129, 124, 127, 128, 143, 133, 131, 136, 141, 158, 127, 131, 240},{116, 115, 117, 120, 121, 119, 125, 129, 123, 129, 124, 127, 128, 143, 133, 131, 136, 141, 158, 127, 131, 240}},{{112, 106, 118, 123, 115, 120, 129, 123, 130, 127, 130, 130, 131, 131, 131, 135, 134, 153, 138, 132, 127, 240},{112, 106, 118, 123, 115, 120, 129, 123, 130, 127, 130, 130, 131, 131, 131, 135, 134, 153, 138, 132, 127, 240}},{{107, 112, 111, 120, 115, 125, 122, 123, 132, 123, 133, 138, 125, 134, 130, 131, 135, 137, 136, 127, 121, 240},{107, 112, 111, 120, 115, 125, 122, 123, 132, 123, 133, 138, 125, 134, 130, 131, 135, 137, 136, 127, 121, 240}},{{111, 113, 132, 115, 121, 123, 121, 127, 135, 128, 129, 128, 133, 130, 133, 138, 134, 137, 152, 138, 124, 240},{111, 113, 132, 115, 121, 123, 121, 127, 135, 128, 129, 128, 133, 130, 133, 138, 134, 137, 152, 138, 124, 240}},{{114, 104, 114, 117, 125, 127, 123, 129, 123, 127, 144, 131, 138, 132, 129, 129, 132, 134, 136, 127, 121, 240},{114, 104, 114, 117, 125, 127, 123, 129, 123, 127, 144, 131, 138, 132, 129, 129, 132, 134, 136, 127, 121, 240}},{{100, 102, 112, 118, 115, 116, 118, 116, 121, 124, 125, 121, 125, 130, 127, 132, 133, 134, 134, 129, 132, 240},{100, 102, 112, 118, 115, 116, 118, 116, 121, 124, 125, 121, 125, 130, 127, 132, 133, 134, 134, 129, 132, 240}},{{106, 93, 103, 108, 124, 111, 114, 115, 120, 121, 119, 123, 131, 130, 132, 132, 132, 131, 140, 129, 131, 240},{106, 93, 103, 108, 124, 111, 114, 115, 120, 121, 119, 123, 131, 130, 132, 132, 132, 131, 140, 129, 131, 240}},{{108, 101, 115, 115, 115, 110, 121, 124, 124, 120, 122, 129, 124, 128, 125, 132, 135, 133, 138, 160, 119, 240},{108, 101, 115, 115, 115, 110, 121, 124, 124, 120, 122, 129, 124, 128, 125, 132, 135, 133, 138, 160, 119, 240}},{{112, 106, 114, 110, 128, 117, 120, 126, 124, 128, 126, 132, 129, 127, 133, 134, 136, 133, 154, 197, 129, 240},{112, 106, 114, 110, 128, 117, 120, 126, 124, 128, 126, 132, 129, 127, 133, 134, 136, 133, 154, 197, 129, 240}},{{102, 107, 111, 116, 116, 120, 118, 115, 120, 119, 128, 131, 131, 130, 128, 126, 126, 132, 145, 136, 133, 240},{102, 107, 111, 116, 116, 120, 118, 115, 120, 119, 128, 131, 131, 130, 128, 126, 126, 132, 145, 136, 133, 240}},{{111, 117, 106, 120, 123, 121, 125, 125, 130, 125, 123, 123, 127, 131, 125, 131, 135, 134, 148, 134, 132, 240},{111, 117, 106, 120, 123, 121, 125, 125, 130, 125, 123, 123, 127, 131, 125, 131, 135, 134, 148, 134, 132, 240}}}; -const uint16_t CRendBin_Combined_BRIR_index_frequency_max_diffuse_48kHz = 98; +const Word16 CRendBin_Combined_BRIR_max_num_iterations_48kHz = 22; +const UWord16 CRendBin_Combined_BRIR_num_iterations_48kHz[15][BINAURAL_CHANNELS]={{22, 22}, {22, 22}, {22, 22}, {22, 22}, {22, 22}, {22, 22}, {22, 22}, {22, 22}, {22, 22}, {22, 22}, {22, 22}, {22, 22}, {22, 22}, {22, 22}, {22, 22} }; +const UWord16 CRendBin_Combined_BRIR_num_iterations_diffuse_48kHz[BINAURAL_CHANNELS] = {40, 40}; +const UWord16 CRendBin_Combined_BRIR_pIndex_frequency_max_48kHz[15][BINAURAL_CHANNELS][22]={{{116, 118, 117, 121, 112, 119, 121, 131, 134, 131, 137, 127, 134, 135, 134, 135, 129, 139, 135, 130, 128, 240},{116, 118, 117, 121, 112, 119, 121, 131, 134, 131, 137, 127, 134, 135, 134, 135, 129, 139, 135, 130, 128, 240}},{{122, 106, 121, 114, 121, 123, 119, 126, 123, 126, 127, 130, 128, 136, 132, 131, 129, 141, 137, 131, 129, 240},{122, 106, 121, 114, 121, 123, 119, 126, 123, 126, 127, 130, 128, 136, 132, 131, 129, 141, 137, 131, 129, 240}},{{118, 104, 116, 104, 123, 123, 122, 125, 130, 128, 132, 135, 131, 132, 131, 132, 135, 137, 144, 129, 129, 240},{118, 104, 116, 104, 123, 123, 122, 125, 130, 128, 132, 135, 131, 132, 131, 132, 135, 137, 144, 129, 129, 240}},{{102, 117, 116, 121, 117, 114, 115, 125, 126, 124, 125, 142, 133, 124, 129, 132, 134, 137, 143, 125, 125, 240},{102, 117, 116, 121, 117, 114, 115, 125, 126, 124, 125, 142, 133, 124, 129, 132, 134, 137, 143, 125, 125, 240}},{{116, 115, 117, 120, 121, 119, 125, 129, 123, 129, 124, 127, 128, 143, 133, 131, 136, 141, 158, 127, 131, 240},{116, 115, 117, 120, 121, 119, 125, 129, 123, 129, 124, 127, 128, 143, 133, 131, 136, 141, 158, 127, 131, 240}},{{112, 106, 118, 123, 115, 120, 129, 123, 130, 127, 130, 130, 131, 131, 131, 135, 134, 153, 138, 132, 127, 240},{112, 106, 118, 123, 115, 120, 129, 123, 130, 127, 130, 130, 131, 131, 131, 135, 134, 153, 138, 132, 127, 240}},{{107, 112, 111, 120, 115, 125, 122, 123, 132, 123, 133, 138, 125, 134, 130, 131, 135, 137, 136, 127, 121, 240},{107, 112, 111, 120, 115, 125, 122, 123, 132, 123, 133, 138, 125, 134, 130, 131, 135, 137, 136, 127, 121, 240}},{{111, 113, 132, 115, 121, 123, 121, 127, 135, 128, 129, 128, 133, 130, 133, 138, 134, 137, 152, 138, 124, 240},{111, 113, 132, 115, 121, 123, 121, 127, 135, 128, 129, 128, 133, 130, 133, 138, 134, 137, 152, 138, 124, 240}},{{114, 104, 114, 117, 125, 127, 123, 129, 123, 127, 144, 131, 138, 132, 129, 129, 132, 134, 136, 127, 121, 240},{114, 104, 114, 117, 125, 127, 123, 129, 123, 127, 144, 131, 138, 132, 129, 129, 132, 134, 136, 127, 121, 240}},{{100, 102, 112, 118, 115, 116, 118, 116, 121, 124, 125, 121, 125, 130, 127, 132, 133, 134, 134, 129, 132, 240},{100, 102, 112, 118, 115, 116, 118, 116, 121, 124, 125, 121, 125, 130, 127, 132, 133, 134, 134, 129, 132, 240}},{{106, 93, 103, 108, 124, 111, 114, 115, 120, 121, 119, 123, 131, 130, 132, 132, 132, 131, 140, 129, 131, 240},{106, 93, 103, 108, 124, 111, 114, 115, 120, 121, 119, 123, 131, 130, 132, 132, 132, 131, 140, 129, 131, 240}},{{108, 101, 115, 115, 115, 110, 121, 124, 124, 120, 122, 129, 124, 128, 125, 132, 135, 133, 138, 160, 119, 240},{108, 101, 115, 115, 115, 110, 121, 124, 124, 120, 122, 129, 124, 128, 125, 132, 135, 133, 138, 160, 119, 240}},{{112, 106, 114, 110, 128, 117, 120, 126, 124, 128, 126, 132, 129, 127, 133, 134, 136, 133, 154, 197, 129, 240},{112, 106, 114, 110, 128, 117, 120, 126, 124, 128, 126, 132, 129, 127, 133, 134, 136, 133, 154, 197, 129, 240}},{{102, 107, 111, 116, 116, 120, 118, 115, 120, 119, 128, 131, 131, 130, 128, 126, 126, 132, 145, 136, 133, 240},{102, 107, 111, 116, 116, 120, 118, 115, 120, 119, 128, 131, 131, 130, 128, 126, 126, 132, 145, 136, 133, 240}},{{111, 117, 106, 120, 123, 121, 125, 125, 130, 125, 123, 123, 127, 131, 125, 131, 135, 134, 148, 134, 132, 240},{111, 117, 106, 120, 123, 121, 125, 125, 130, 125, 123, 123, 127, 131, 125, 131, 135, 134, 148, 134, 132, 240}}}; +const UWord16 CRendBin_Combined_BRIR_index_frequency_max_diffuse_48kHz = 98; const float CRendBin_Combined_BRIR_inv_diffuse_weight_48kHz[15]={0.224183f, 0.227455f, 0.241830f, 0.207155f, 0.218087f, 0.222942f, 0.232158f, 0.248203f, 0.249262f, 0.261591f, 0.246276f, 0.279163f, 0.285701f, 0.262541f, 0.271844f}; const Word16 CRendBin_Combined_BRIR_inv_diffuse_weight_48kHz_fx[15]={7346, 7453, 7924, 6788, 7146, 7305, 7607, 8133, 8167, 8571, 8069, 9147, 9361, 8602, 8907,}; -const uint16_t CRendBin_Combined_BRIR_pIndex_frequency_max_diffuse_48kHz[BINAURAL_CHANNELS][40]={{47, 47, 47, 47, 47, 47, 51, 51, 58, 58, 58, 65, 65, 65, 65, 65, 72, 72, 72, 74, 74, 77, 77, 79, 81, 81, 81, 81, 87, 87, 87, 87, 87, 87, 91, 91, 93, 93, 93, 98},{47, 47, 47, 47, 47, 47, 51, 51, 58, 58, 58, 65, 65, 65, 65, 65, 72, 72, 72, 74, 74, 77, 77, 79, 81, 81, 81, 81, 87, 87, 87, 87, 87, 87, 91, 91, 93, 93, 93, 98}}; +const UWord16 CRendBin_Combined_BRIR_pIndex_frequency_max_diffuse_48kHz[BINAURAL_CHANNELS][40]={{47, 47, 47, 47, 47, 47, 51, 51, 58, 58, 58, 65, 65, 65, 65, 65, 72, 72, 72, 74, 74, 77, 77, 79, 81, 81, 81, 81, 87, 87, 87, 87, 87, 87, 91, 91, 93, 93, 93, 98},{47, 47, 47, 47, 47, 47, 51, 51, 58, 58, 58, 65, 65, 65, 65, 65, 72, 72, 72, 74, 74, 77, 77, 79, 81, 81, 81, 81, 87, 87, 87, 87, 87, 87, 91, 91, 93, 93, 93, 98}}; /* Sample Rate = 32000 */ -const int16_t CRendBin_Combined_BRIR_max_num_iterations_32kHz = 22; -const uint16_t CRendBin_Combined_BRIR_num_iterations_32kHz[15][BINAURAL_CHANNELS]={{22, 22}, {22, 22}, {22, 22}, {22, 22}, {22, 22}, {22, 22}, {22, 22}, {22, 22}, {22, 22}, {22, 22}, {22, 22}, {22, 22}, {22, 22}, {22, 22}, {22, 22} }; -const uint16_t CRendBin_Combined_BRIR_num_iterations_diffuse_32kHz[BINAURAL_CHANNELS] = {40, 40}; -const uint16_t CRendBin_Combined_BRIR_pIndex_frequency_max_32kHz[15][BINAURAL_CHANNELS][22]={{{115, 117, 117, 120, 112, 118, 121, 130, 126, 130, 136, 127, 133, 135, 132, 133, 129, 137, 134, 129, 128, 160},{115, 117, 117, 120, 112, 118, 121, 130, 126, 130, 136, 127, 133, 135, 132, 133, 129, 137, 134, 129, 128, 160}},{{121, 106, 119, 113, 120, 123, 114, 126, 123, 125, 127, 128, 127, 134, 132, 130, 129, 139, 133, 131, 128, 160},{121, 106, 119, 113, 120, 123, 114, 126, 123, 125, 127, 128, 127, 134, 132, 130, 129, 139, 133, 131, 128, 160}},{{113, 103, 116, 104, 123, 123, 122, 124, 130, 128, 132, 131, 131, 132, 130, 132, 130, 135, 137, 128, 128, 160},{113, 103, 116, 104, 123, 123, 122, 124, 130, 128, 132, 131, 131, 132, 130, 132, 130, 135, 137, 128, 128, 160}},{{102, 116, 116, 121, 116, 114, 115, 121, 125, 123, 124, 130, 132, 122, 127, 131, 131, 135, 133, 124, 125, 160},{102, 116, 116, 121, 116, 114, 115, 121, 125, 123, 124, 130, 132, 122, 127, 131, 131, 135, 133, 124, 125, 160}},{{115, 115, 115, 119, 121, 119, 125, 127, 123, 129, 122, 126, 128, 134, 130, 130, 131, 140, 146, 127, 131, 160},{115, 115, 115, 119, 121, 119, 125, 127, 123, 129, 122, 126, 128, 134, 130, 130, 131, 140, 146, 127, 131, 160}},{{112, 106, 118, 121, 115, 117, 129, 123, 128, 126, 130, 130, 131, 131, 130, 134, 133, 149, 130, 132, 126, 160},{112, 106, 118, 121, 115, 117, 129, 123, 128, 126, 130, 130, 131, 131, 130, 134, 133, 149, 130, 132, 126, 160}},{{107, 112, 110, 119, 114, 124, 121, 121, 132, 122, 131, 134, 124, 133, 130, 129, 134, 134, 135, 127, 120, 160},{107, 112, 110, 119, 114, 124, 121, 121, 132, 122, 131, 134, 124, 133, 130, 129, 134, 134, 135, 127, 120, 160}},{{110, 113, 123, 113, 121, 120, 120, 126, 131, 123, 128, 128, 132, 130, 132, 136, 133, 136, 135, 128, 124, 160},{110, 113, 123, 113, 121, 120, 120, 126, 131, 123, 128, 128, 132, 130, 132, 136, 133, 136, 135, 128, 124, 160}},{{114, 101, 113, 113, 124, 126, 123, 128, 122, 127, 132, 127, 136, 128, 128, 127, 132, 132, 129, 125, 120, 160},{114, 101, 113, 113, 124, 126, 123, 128, 122, 127, 132, 127, 136, 128, 128, 127, 132, 132, 129, 125, 120, 160}},{{99, 100, 111, 117, 114, 114, 118, 116, 121, 124, 124, 121, 125, 130, 127, 132, 132, 130, 133, 128, 131, 160},{99, 100, 111, 117, 114, 114, 118, 116, 121, 124, 124, 121, 125, 130, 127, 132, 132, 130, 133, 128, 131, 160}},{{105, 93, 103, 108, 119, 110, 111, 114, 120, 121, 119, 122, 130, 128, 130, 131, 132, 131, 136, 128, 128, 160},{105, 93, 103, 108, 119, 110, 111, 114, 120, 121, 119, 122, 130, 128, 130, 131, 132, 131, 136, 128, 128, 160}},{{105, 100, 112, 114, 115, 108, 117, 120, 123, 117, 122, 129, 124, 128, 124, 132, 135, 131, 139, 153, 116, 160},{105, 100, 112, 114, 115, 108, 117, 120, 123, 117, 122, 129, 124, 128, 124, 132, 135, 131, 139, 153, 116, 160}},{{110, 106, 113, 110, 122, 116, 119, 125, 123, 128, 125, 127, 128, 127, 133, 130, 132, 132, 143, 155, 127, 160},{110, 106, 113, 110, 122, 116, 119, 125, 123, 128, 125, 127, 128, 127, 133, 130, 132, 132, 143, 155, 127, 160}},{{102, 107, 110, 112, 115, 117, 117, 115, 120, 118, 127, 130, 130, 129, 126, 126, 125, 130, 141, 135, 127, 160},{102, 107, 110, 112, 115, 117, 117, 115, 120, 118, 127, 130, 130, 129, 126, 126, 125, 130, 141, 135, 127, 160}},{{110, 117, 106, 118, 118, 116, 121, 124, 128, 125, 122, 122, 126, 131, 124, 130, 133, 131, 139, 134, 131, 160},{110, 117, 106, 118, 118, 116, 121, 124, 128, 125, 122, 122, 126, 131, 124, 130, 133, 131, 139, 134, 131, 160}}}; -const uint16_t CRendBin_Combined_BRIR_index_frequency_max_diffuse_32kHz = 97; +const Word16 CRendBin_Combined_BRIR_max_num_iterations_32kHz = 22; +const UWord16 CRendBin_Combined_BRIR_num_iterations_32kHz[15][BINAURAL_CHANNELS]={{22, 22}, {22, 22}, {22, 22}, {22, 22}, {22, 22}, {22, 22}, {22, 22}, {22, 22}, {22, 22}, {22, 22}, {22, 22}, {22, 22}, {22, 22}, {22, 22}, {22, 22} }; +const UWord16 CRendBin_Combined_BRIR_num_iterations_diffuse_32kHz[BINAURAL_CHANNELS] = {40, 40}; +const UWord16 CRendBin_Combined_BRIR_pIndex_frequency_max_32kHz[15][BINAURAL_CHANNELS][22]={{{115, 117, 117, 120, 112, 118, 121, 130, 126, 130, 136, 127, 133, 135, 132, 133, 129, 137, 134, 129, 128, 160},{115, 117, 117, 120, 112, 118, 121, 130, 126, 130, 136, 127, 133, 135, 132, 133, 129, 137, 134, 129, 128, 160}},{{121, 106, 119, 113, 120, 123, 114, 126, 123, 125, 127, 128, 127, 134, 132, 130, 129, 139, 133, 131, 128, 160},{121, 106, 119, 113, 120, 123, 114, 126, 123, 125, 127, 128, 127, 134, 132, 130, 129, 139, 133, 131, 128, 160}},{{113, 103, 116, 104, 123, 123, 122, 124, 130, 128, 132, 131, 131, 132, 130, 132, 130, 135, 137, 128, 128, 160},{113, 103, 116, 104, 123, 123, 122, 124, 130, 128, 132, 131, 131, 132, 130, 132, 130, 135, 137, 128, 128, 160}},{{102, 116, 116, 121, 116, 114, 115, 121, 125, 123, 124, 130, 132, 122, 127, 131, 131, 135, 133, 124, 125, 160},{102, 116, 116, 121, 116, 114, 115, 121, 125, 123, 124, 130, 132, 122, 127, 131, 131, 135, 133, 124, 125, 160}},{{115, 115, 115, 119, 121, 119, 125, 127, 123, 129, 122, 126, 128, 134, 130, 130, 131, 140, 146, 127, 131, 160},{115, 115, 115, 119, 121, 119, 125, 127, 123, 129, 122, 126, 128, 134, 130, 130, 131, 140, 146, 127, 131, 160}},{{112, 106, 118, 121, 115, 117, 129, 123, 128, 126, 130, 130, 131, 131, 130, 134, 133, 149, 130, 132, 126, 160},{112, 106, 118, 121, 115, 117, 129, 123, 128, 126, 130, 130, 131, 131, 130, 134, 133, 149, 130, 132, 126, 160}},{{107, 112, 110, 119, 114, 124, 121, 121, 132, 122, 131, 134, 124, 133, 130, 129, 134, 134, 135, 127, 120, 160},{107, 112, 110, 119, 114, 124, 121, 121, 132, 122, 131, 134, 124, 133, 130, 129, 134, 134, 135, 127, 120, 160}},{{110, 113, 123, 113, 121, 120, 120, 126, 131, 123, 128, 128, 132, 130, 132, 136, 133, 136, 135, 128, 124, 160},{110, 113, 123, 113, 121, 120, 120, 126, 131, 123, 128, 128, 132, 130, 132, 136, 133, 136, 135, 128, 124, 160}},{{114, 101, 113, 113, 124, 126, 123, 128, 122, 127, 132, 127, 136, 128, 128, 127, 132, 132, 129, 125, 120, 160},{114, 101, 113, 113, 124, 126, 123, 128, 122, 127, 132, 127, 136, 128, 128, 127, 132, 132, 129, 125, 120, 160}},{{99, 100, 111, 117, 114, 114, 118, 116, 121, 124, 124, 121, 125, 130, 127, 132, 132, 130, 133, 128, 131, 160},{99, 100, 111, 117, 114, 114, 118, 116, 121, 124, 124, 121, 125, 130, 127, 132, 132, 130, 133, 128, 131, 160}},{{105, 93, 103, 108, 119, 110, 111, 114, 120, 121, 119, 122, 130, 128, 130, 131, 132, 131, 136, 128, 128, 160},{105, 93, 103, 108, 119, 110, 111, 114, 120, 121, 119, 122, 130, 128, 130, 131, 132, 131, 136, 128, 128, 160}},{{105, 100, 112, 114, 115, 108, 117, 120, 123, 117, 122, 129, 124, 128, 124, 132, 135, 131, 139, 153, 116, 160},{105, 100, 112, 114, 115, 108, 117, 120, 123, 117, 122, 129, 124, 128, 124, 132, 135, 131, 139, 153, 116, 160}},{{110, 106, 113, 110, 122, 116, 119, 125, 123, 128, 125, 127, 128, 127, 133, 130, 132, 132, 143, 155, 127, 160},{110, 106, 113, 110, 122, 116, 119, 125, 123, 128, 125, 127, 128, 127, 133, 130, 132, 132, 143, 155, 127, 160}},{{102, 107, 110, 112, 115, 117, 117, 115, 120, 118, 127, 130, 130, 129, 126, 126, 125, 130, 141, 135, 127, 160},{102, 107, 110, 112, 115, 117, 117, 115, 120, 118, 127, 130, 130, 129, 126, 126, 125, 130, 141, 135, 127, 160}},{{110, 117, 106, 118, 118, 116, 121, 124, 128, 125, 122, 122, 126, 131, 124, 130, 133, 131, 139, 134, 131, 160},{110, 117, 106, 118, 118, 116, 121, 124, 128, 125, 122, 122, 126, 131, 124, 130, 133, 131, 139, 134, 131, 160}}}; +const UWord16 CRendBin_Combined_BRIR_index_frequency_max_diffuse_32kHz = 97; const float CRendBin_Combined_BRIR_inv_diffuse_weight_32kHz[15]={0.224190f, 0.227445f, 0.241827f, 0.207131f, 0.218113f, 0.222941f, 0.232139f, 0.248192f, 0.249239f, 0.261572f, 0.246309f, 0.279145f, 0.285786f, 0.262528f, 0.271847f}; const Word16 CRendBin_Combined_BRIR_inv_diffuse_weight_32kHz_fx[15]={7346, 7452, 7924, 6787, 7147, 7305, 7606, 8132, 8167, 8571, 8071, 9147, 9364, 8602, 8907,}; -const uint16_t CRendBin_Combined_BRIR_pIndex_frequency_max_diffuse_32kHz[BINAURAL_CHANNELS][40]={{47, 47, 47, 47, 47, 47, 50, 50, 56, 56, 56, 63, 63, 63, 63, 63, 72, 72, 72, 74, 74, 77, 77, 79, 81, 81, 81, 81, 87, 87, 87, 87, 87, 87, 93, 93, 93, 93, 93, 97},{47, 47, 47, 47, 47, 47, 50, 50, 56, 56, 56, 63, 63, 63, 63, 63, 72, 72, 72, 74, 74, 77, 77, 79, 81, 81, 81, 81, 87, 87, 87, 87, 87, 87, 93, 93, 93, 93, 93, 97}}; +const UWord16 CRendBin_Combined_BRIR_pIndex_frequency_max_diffuse_32kHz[BINAURAL_CHANNELS][40]={{47, 47, 47, 47, 47, 47, 50, 50, 56, 56, 56, 63, 63, 63, 63, 63, 72, 72, 72, 74, 74, 77, 77, 79, 81, 81, 81, 81, 87, 87, 87, 87, 87, 87, 93, 93, 93, 93, 93, 97},{47, 47, 47, 47, 47, 47, 50, 50, 56, 56, 56, 63, 63, 63, 63, 63, 72, 72, 72, 74, 74, 77, 77, 79, 81, 81, 81, 81, 87, 87, 87, 87, 87, 87, 93, 93, 93, 93, 93, 97}}; /* Sample Rate = 16000 */ -const int16_t CRendBin_Combined_BRIR_max_num_iterations_16kHz = 23; -const uint16_t CRendBin_Combined_BRIR_num_iterations_16kHz[15][BINAURAL_CHANNELS]={{23, 23}, {23, 23}, {23, 23}, {23, 23}, {23, 23}, {23, 23}, {23, 23}, {23, 23}, {23, 23}, {23, 23}, {23, 23}, {23, 23}, {23, 23}, {23, 23}, {23, 23} }; -const uint16_t CRendBin_Combined_BRIR_num_iterations_diffuse_16kHz[BINAURAL_CHANNELS] = {40, 40}; -const uint16_t CRendBin_Combined_BRIR_pIndex_frequency_max_16kHz[15][BINAURAL_CHANNELS][23]={{{77, 76, 77, 77, 77, 76, 77, 76, 77, 76, 77, 77, 77, 78, 76, 76, 77, 77, 77, 77, 77, 76, 80},{77, 76, 77, 77, 77, 76, 77, 76, 77, 76, 77, 77, 77, 78, 76, 76, 77, 77, 77, 77, 77, 76, 80}},{{76, 77, 77, 75, 77, 78, 77, 76, 77, 77, 76, 77, 77, 77, 77, 77, 76, 77, 76, 76, 77, 78, 80},{76, 77, 77, 75, 77, 78, 77, 76, 77, 77, 76, 77, 77, 77, 77, 77, 76, 77, 76, 76, 77, 78, 80}},{{77, 76, 76, 78, 75, 76, 74, 78, 77, 76, 77, 77, 77, 76, 76, 77, 78, 78, 77, 77, 77, 77, 80},{77, 76, 76, 78, 75, 76, 74, 78, 77, 76, 77, 77, 77, 76, 76, 77, 78, 78, 77, 77, 77, 77, 80}},{{76, 76, 76, 76, 77, 77, 76, 78, 77, 77, 77, 77, 78, 78, 77, 77, 77, 77, 77, 78, 77, 78, 80},{76, 76, 76, 76, 77, 77, 76, 78, 77, 77, 77, 77, 78, 78, 77, 77, 77, 77, 77, 78, 77, 78, 80}},{{76, 77, 77, 76, 77, 77, 75, 77, 77, 77, 76, 77, 77, 77, 77, 78, 77, 77, 77, 77, 76, 76, 80},{76, 77, 77, 76, 77, 77, 75, 77, 77, 77, 76, 77, 77, 77, 77, 78, 77, 77, 77, 77, 76, 76, 80}},{{77, 76, 77, 77, 77, 77, 77, 77, 76, 78, 76, 78, 75, 76, 77, 77, 76, 76, 77, 78, 78, 77, 80},{77, 76, 77, 77, 77, 77, 77, 77, 76, 78, 76, 78, 75, 76, 77, 77, 76, 76, 77, 78, 78, 77, 80}},{{77, 77, 75, 76, 76, 77, 77, 77, 77, 77, 77, 75, 77, 76, 76, 76, 77, 77, 76, 77, 76, 77, 80},{77, 77, 75, 76, 76, 77, 77, 77, 77, 77, 77, 75, 77, 76, 76, 76, 77, 77, 76, 77, 76, 77, 80}},{{75, 76, 77, 77, 75, 77, 75, 76, 76, 77, 77, 77, 78, 78, 77, 77, 76, 77, 78, 78, 78, 76, 80},{75, 76, 77, 77, 75, 77, 75, 76, 76, 77, 77, 77, 78, 78, 77, 77, 76, 77, 78, 78, 78, 76, 80}},{{77, 77, 77, 76, 77, 77, 76, 76, 76, 77, 77, 75, 76, 78, 78, 77, 77, 78, 78, 77, 76, 76, 80},{77, 77, 77, 76, 77, 77, 76, 76, 76, 77, 77, 75, 76, 78, 78, 77, 77, 78, 78, 77, 76, 76, 80}},{{76, 75, 76, 76, 77, 77, 77, 77, 77, 77, 74, 78, 77, 78, 78, 77, 76, 77, 77, 77, 77, 76, 80},{76, 75, 76, 76, 77, 77, 77, 77, 77, 77, 74, 78, 77, 78, 78, 77, 76, 77, 77, 77, 77, 76, 80}},{{76, 76, 77, 76, 77, 77, 76, 76, 76, 76, 77, 77, 76, 76, 77, 75, 77, 76, 76, 76, 77, 77, 80},{76, 76, 77, 76, 77, 77, 76, 76, 76, 76, 77, 77, 76, 76, 77, 75, 77, 76, 76, 76, 77, 77, 80}},{{76, 76, 77, 75, 78, 77, 77, 77, 77, 77, 77, 77, 77, 76, 78, 77, 76, 78, 76, 77, 76, 77, 80},{76, 76, 77, 75, 78, 77, 77, 77, 77, 77, 77, 77, 77, 76, 78, 77, 76, 78, 76, 77, 76, 77, 80}},{{76, 77, 77, 76, 76, 77, 77, 75, 77, 77, 77, 77, 77, 77, 78, 78, 78, 78, 77, 76, 76, 78, 80},{76, 77, 77, 76, 76, 77, 77, 75, 77, 77, 77, 77, 77, 77, 78, 78, 78, 78, 77, 76, 76, 78, 80}},{{74, 76, 74, 76, 75, 76, 76, 76, 76, 77, 77, 78, 77, 78, 75, 76, 77, 76, 78, 76, 78, 77, 80},{74, 76, 74, 76, 75, 76, 76, 76, 76, 77, 77, 78, 77, 78, 75, 76, 77, 76, 78, 76, 78, 77, 80}},{{76, 77, 77, 77, 76, 78, 77, 76, 75, 77, 77, 77, 76, 78, 77, 78, 78, 78, 77, 76, 77, 75, 80},{76, 77, 77, 77, 76, 78, 77, 76, 75, 77, 77, 77, 76, 78, 77, 78, 78, 78, 77, 76, 77, 75, 80}}}; -const uint16_t CRendBin_Combined_BRIR_index_frequency_max_diffuse_16kHz = 77; +const Word16 CRendBin_Combined_BRIR_max_num_iterations_16kHz = 23; +const UWord16 CRendBin_Combined_BRIR_num_iterations_16kHz[15][BINAURAL_CHANNELS]={{23, 23}, {23, 23}, {23, 23}, {23, 23}, {23, 23}, {23, 23}, {23, 23}, {23, 23}, {23, 23}, {23, 23}, {23, 23}, {23, 23}, {23, 23}, {23, 23}, {23, 23} }; +const UWord16 CRendBin_Combined_BRIR_num_iterations_diffuse_16kHz[BINAURAL_CHANNELS] = {40, 40}; +const UWord16 CRendBin_Combined_BRIR_pIndex_frequency_max_16kHz[15][BINAURAL_CHANNELS][23]={{{77, 76, 77, 77, 77, 76, 77, 76, 77, 76, 77, 77, 77, 78, 76, 76, 77, 77, 77, 77, 77, 76, 80},{77, 76, 77, 77, 77, 76, 77, 76, 77, 76, 77, 77, 77, 78, 76, 76, 77, 77, 77, 77, 77, 76, 80}},{{76, 77, 77, 75, 77, 78, 77, 76, 77, 77, 76, 77, 77, 77, 77, 77, 76, 77, 76, 76, 77, 78, 80},{76, 77, 77, 75, 77, 78, 77, 76, 77, 77, 76, 77, 77, 77, 77, 77, 76, 77, 76, 76, 77, 78, 80}},{{77, 76, 76, 78, 75, 76, 74, 78, 77, 76, 77, 77, 77, 76, 76, 77, 78, 78, 77, 77, 77, 77, 80},{77, 76, 76, 78, 75, 76, 74, 78, 77, 76, 77, 77, 77, 76, 76, 77, 78, 78, 77, 77, 77, 77, 80}},{{76, 76, 76, 76, 77, 77, 76, 78, 77, 77, 77, 77, 78, 78, 77, 77, 77, 77, 77, 78, 77, 78, 80},{76, 76, 76, 76, 77, 77, 76, 78, 77, 77, 77, 77, 78, 78, 77, 77, 77, 77, 77, 78, 77, 78, 80}},{{76, 77, 77, 76, 77, 77, 75, 77, 77, 77, 76, 77, 77, 77, 77, 78, 77, 77, 77, 77, 76, 76, 80},{76, 77, 77, 76, 77, 77, 75, 77, 77, 77, 76, 77, 77, 77, 77, 78, 77, 77, 77, 77, 76, 76, 80}},{{77, 76, 77, 77, 77, 77, 77, 77, 76, 78, 76, 78, 75, 76, 77, 77, 76, 76, 77, 78, 78, 77, 80},{77, 76, 77, 77, 77, 77, 77, 77, 76, 78, 76, 78, 75, 76, 77, 77, 76, 76, 77, 78, 78, 77, 80}},{{77, 77, 75, 76, 76, 77, 77, 77, 77, 77, 77, 75, 77, 76, 76, 76, 77, 77, 76, 77, 76, 77, 80},{77, 77, 75, 76, 76, 77, 77, 77, 77, 77, 77, 75, 77, 76, 76, 76, 77, 77, 76, 77, 76, 77, 80}},{{75, 76, 77, 77, 75, 77, 75, 76, 76, 77, 77, 77, 78, 78, 77, 77, 76, 77, 78, 78, 78, 76, 80},{75, 76, 77, 77, 75, 77, 75, 76, 76, 77, 77, 77, 78, 78, 77, 77, 76, 77, 78, 78, 78, 76, 80}},{{77, 77, 77, 76, 77, 77, 76, 76, 76, 77, 77, 75, 76, 78, 78, 77, 77, 78, 78, 77, 76, 76, 80},{77, 77, 77, 76, 77, 77, 76, 76, 76, 77, 77, 75, 76, 78, 78, 77, 77, 78, 78, 77, 76, 76, 80}},{{76, 75, 76, 76, 77, 77, 77, 77, 77, 77, 74, 78, 77, 78, 78, 77, 76, 77, 77, 77, 77, 76, 80},{76, 75, 76, 76, 77, 77, 77, 77, 77, 77, 74, 78, 77, 78, 78, 77, 76, 77, 77, 77, 77, 76, 80}},{{76, 76, 77, 76, 77, 77, 76, 76, 76, 76, 77, 77, 76, 76, 77, 75, 77, 76, 76, 76, 77, 77, 80},{76, 76, 77, 76, 77, 77, 76, 76, 76, 76, 77, 77, 76, 76, 77, 75, 77, 76, 76, 76, 77, 77, 80}},{{76, 76, 77, 75, 78, 77, 77, 77, 77, 77, 77, 77, 77, 76, 78, 77, 76, 78, 76, 77, 76, 77, 80},{76, 76, 77, 75, 78, 77, 77, 77, 77, 77, 77, 77, 77, 76, 78, 77, 76, 78, 76, 77, 76, 77, 80}},{{76, 77, 77, 76, 76, 77, 77, 75, 77, 77, 77, 77, 77, 77, 78, 78, 78, 78, 77, 76, 76, 78, 80},{76, 77, 77, 76, 76, 77, 77, 75, 77, 77, 77, 77, 77, 77, 78, 78, 78, 78, 77, 76, 76, 78, 80}},{{74, 76, 74, 76, 75, 76, 76, 76, 76, 77, 77, 78, 77, 78, 75, 76, 77, 76, 78, 76, 78, 77, 80},{74, 76, 74, 76, 75, 76, 76, 76, 76, 77, 77, 78, 77, 78, 75, 76, 77, 76, 78, 76, 78, 77, 80}},{{76, 77, 77, 77, 76, 78, 77, 76, 75, 77, 77, 77, 76, 78, 77, 78, 78, 78, 77, 76, 77, 75, 80},{76, 77, 77, 77, 76, 78, 77, 76, 75, 77, 77, 77, 76, 78, 77, 78, 78, 78, 77, 76, 77, 75, 80}}}; +const UWord16 CRendBin_Combined_BRIR_index_frequency_max_diffuse_16kHz = 77; const float CRendBin_Combined_BRIR_inv_diffuse_weight_16kHz[15]={0.223532f, 0.226827f, 0.248830f, 0.208782f, 0.220391f, 0.219790f, 0.231187f, 0.248730f, 0.251408f, 0.263698f, 0.243858f, 0.281483f, 0.283080f, 0.261660f, 0.273527f}; const Word16 CRendBin_Combined_BRIR_inv_diffuse_weight_16kHz_fx[15]={7346, 7452, 7924, 6787, 7147, 7305, 7606, 8132, 8167, 8571, 8071, 9147, 9364, 8602, 8907}; -const uint16_t CRendBin_Combined_BRIR_pIndex_frequency_max_diffuse_16kHz[BINAURAL_CHANNELS][40]={{46, 46, 46, 46, 46, 46, 46, 49, 49, 53, 53, 53, 55, 55, 61, 61, 61, 65, 67, 67, 67, 67, 67, 67, 69, 72, 72, 72, 73, 73, 75, 75, 75, 75, 75, 75, 75, 75, 75, 77},{46, 46, 46, 46, 46, 46, 46, 49, 49, 53, 53, 53, 55, 55, 61, 61, 61, 65, 67, 67, 67, 67, 67, 67, 69, 72, 72, 72, 73, 73, 75, 75, 75, 75, 75, 75, 75, 75, 75, 77}}; +const UWord16 CRendBin_Combined_BRIR_pIndex_frequency_max_diffuse_16kHz[BINAURAL_CHANNELS][40]={{46, 46, 46, 46, 46, 46, 46, 49, 49, 53, 53, 53, 55, 55, 61, 61, 61, 65, 67, 67, 67, 67, 67, 67, 69, 72, 72, 72, 73, 73, 75, 75, 75, 75, 75, 75, 75, 75, 75, 77},{46, 46, 46, 46, 46, 46, 46, 49, 49, 53, 53, 53, 55, 55, 61, 61, 61, 65, 67, 67, 67, 67, 67, 67, 69, 72, 72, 72, 73, 73, 75, 75, 75, 75, 75, 75, 75, 75, 75, 77}}; //BRIR and HRIR coeff tables in Q29 const Word32 CRendBin_Combined_BRIR_coeff_re_48kHz_fx[15][BINAURAL_CHANNELS][2955] ={ { diff --git a/lib_rend/ivas_rom_rend.h b/lib_rend/ivas_rom_rend.h index c80fab8ce40466e4ffaad9811daceea1186b2380..a3f7bab5d8ac67690446a78360991b2ce9e52f4e 100644 --- a/lib_rend/ivas_rom_rend.h +++ b/lib_rend/ivas_rom_rend.h @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other @@ -125,8 +125,6 @@ extern const float ivas_reverb_default_fc[]; extern const float ivas_reverb_default_RT60[]; extern const float ivas_reverb_default_DSR[]; -extern const Word32 release_cnst_table[4][201]; // Q31 - /*----------------------------------------------------------------------------------* * Renderer SBA & MC enc/dec matrices *----------------------------------------------------------------------------------*/ diff --git a/lib_rend/ivas_rom_rend.c b/lib_rend/ivas_rom_rend_fx.c similarity index 71% rename from lib_rend/ivas_rom_rend.c rename to lib_rend/ivas_rom_rend_fx.c index d99a4ad767eb35559af5023fc47d78e116ac07a5..1fe8e6a3845f863f2a60b772e6458429e8ec6123 100644 --- a/lib_rend/ivas_rom_rend.c +++ b/lib_rend/ivas_rom_rend_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other @@ -49,9 +49,9 @@ const Word16 diffuse_response_CICP6_fx[5] = { 13824, 13824, 12137, 16495, 16495 const Word16 diffuse_response_CICP14_fx[7] = { 12507, 12507, 9237, 17691, 17691, 4977, 4977 };//Q15 const Word16 diffuse_response_CICP16_fx[9] = { 11324, 11324, 9945, 13513, 13513, 8853, 8853, 9905, 9905 };//Q15 -const int16_t ap_pre_delay[DIRAC_DECORR_NUM_SPLIT_BANDS] = { 7, 2, 1 }; +const Word16 ap_pre_delay[DIRAC_DECORR_NUM_SPLIT_BANDS] = { 7, 2, 1 }; -const int16_t ap_filter_length[DIRAC_DECORR_NUM_SPLIT_BANDS] = { 15, 6, 3 }; +const Word16 ap_filter_length[DIRAC_DECORR_NUM_SPLIT_BANDS] = { 15, 6, 3 }; const Word16 ap_lattice_delta_phi_fx[DIRAC_MAX_NUM_DECORR_FILTERS*DIRAC_MAX_DECORR_FILTER_LEN] /*Q14*/ = { @@ -91,11 +91,11 @@ const Word16 ap_split_frequencies_fx[DIRAC_DECORR_NUM_SPLIT_BANDS + 1]/*Q14*/ = 0 , 2048, 6144, 16384 }; -const int16_t sba_map_tc[11] = +const Word16 sba_map_tc[11] = { 0, 1, 2, 3, 4, 8, 9, 15, 5, 6, 7 }; -const int16_t sba_map_tc_512[11] = +const Word16 sba_map_tc_512[11] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 15 }; @@ -121,11 +121,11 @@ const int16_t sba_map_tc_512[11] = * 13 = 135, 35 * 14 = -135, 35 */ -const int16_t channelIndex_CICP6[5] = { 0, 1, 2, 5, 6 }; -const int16_t channelIndex_CICP12[7] = { 0, 1, 2, 5, 6, 3, 4 }; -const int16_t channelIndex_CICP14[7] = { 0, 1, 2, 5, 6, 9, 10 }; -const int16_t channelIndex_CICP16[9] = { 0, 1, 2, 5, 6, 9, 10, 11, 12 }; -const int16_t channelIndex_CICP19[11] = { 0, 1, 2, 3, 4, 7, 8, 9, 10, 13, 14 }; +const Word16 channelIndex_CICP6[5] = { 0, 1, 2, 5, 6 }; +const Word16 channelIndex_CICP12[7] = { 0, 1, 2, 5, 6, 3, 4 }; +const Word16 channelIndex_CICP14[7] = { 0, 1, 2, 5, 6, 9, 10 }; +const Word16 channelIndex_CICP16[9] = { 0, 1, 2, 5, 6, 9, 10, 11, 12 }; +const Word16 channelIndex_CICP19[11] = { 0, 1, 2, 3, 4, 7, 8, 9, 10, 13, 14 }; const Word16 surCohEne_fx[MASA_NUM_DEFINED_SUR_SPR_COH_ENE_BINS] /* Q13 */ = { @@ -160,7 +160,7 @@ const Word32 diffuseFieldCoherenceDifferenceZ_fx[BINAURAL_COHERENCE_DIFFERENCE_B * TD ISM binaural renderer ROM tables *----------------------------------------------------------------------------------*/ -const int16_t HRTF_MODEL_N_CPTS_VAR[HRTF_MODEL_N_SECTIONS] = +const Word16 HRTF_MODEL_N_CPTS_VAR[HRTF_MODEL_N_SECTIONS] = { 13, 12, 11 }; @@ -598,823 +598,6 @@ const float ivas_reverb_default_DSR[IVAS_REVERB_DEFAULT_N_BANDS] = 6.2001e-08f, 2.8483e-08f, 2.6267e-08f }; -const Word32 release_cnst_table[4][201] = // Q31 - { - { - 1913946752, - 1919716352, - 1925351680, - 1930855552, - 1936230784, - 1941479808, - 1946605312, - 1951609728, - 1956495744, - 1961265792, - 1965922304, - 1970467584, - 1974904320, - 1979234560, - 1983460736, - 1987585024, - 1991609856, - 1995537280, - 1999369344, - 2003108480, - 2006756480, - 2010315520, - 2013787520, - 2017174528, - 2020478464, - 2023701248, - 2026844672, - 2029910656, - 2032900992, - 2035817344, - 2038661376, - 2041435008, - 2044139648, - 2046777088, - 2049348864, - 2051856384, - 2054301440, - 2056685312, - 2059009536, - 2061275520, - 2063484672, - 2065638272, - 2067737856, - 2069784448, - 2071779584, - 2073724416, - 2075620096, - 2077467904, - 2079268992, - 2081024512, - 2082735488, - 2084403200, - 2086028416, - 2087612544, - 2089156352, - 2090660864, - 2092127104, - 2093555968, - 2094948480, - 2096305408, - 2097627776, - 2098916352, - 2100172032, - 2101395584, - 2102587776, - 2103749504, - 2104881408, - 2105984384, - 2107059072, - 2108106112, - 2109126400, - 2110120448, - 2111088896, - 2112032512, - 2112951808, - 2113847552, - 2114720128, - 2115570304, - 2116398592, - 2117205504, - 2117991552, - 2118757504, - 2119503616, - 2120230400, - 2120938496, - 2121628288, - 2122300288, - 2122954880, - 2123592576, - 2124213760, - 2124818944, - 2125408384, - 2125982592, - 2126541952, - 2127086848, - 2127617664, - 2128134656, - 2128638336, - 2129128832, - 2129606784, - 2130072192, - 2130525568, - 2130967296, - 2131397376, - 2131816448, - 2132224640, - 2132622080, - 2133009408, - 2133386496, - 2133753856, - 2134111744, - 2134460288, - 2134799744, - 2135130368, - 2135452416, - 2135766144, - 2136071680, - 2136369152, - 2136659072, - 2136941312, - 2137216256, - 2137484160, - 2137744896, - 2137998976, - 2138246400, - 2138487424, - 2138722176, - 2138950656, - 2139173376, - 2139390208, - 2139601408, - 2139807104, - 2140007424, - 2140202624, - 2140392576, - 2140577664, - 2140758016, - 2140933504, - 2141104512, - 2141271040, - 2141433216, - 2141591168, - 2141745024, - 2141894912, - 2142040832, - 2142182912, - 2142321408, - 2142456192, - 2142587392, - 2142715264, - 2142839808, - 2142961152, - 2143079296, - 2143194240, - 2143306240, - 2143415424, - 2143521664, - 2143625216, - 2143725952, - 2143824128, - 2143919744, - 2144012800, - 2144103424, - 2144191744, - 2144277760, - 2144361472, - 2144443136, - 2144522496, - 2144599936, - 2144675200, - 2144748544, - 2144820096, - 2144889600, - 2144957440, - 2145023488, - 2145087744, - 2145150336, - 2145211264, - 2145270656, - 2145328512, - 2145384832, - 2145439616, - 2145493120, - 2145545088, - 2145595776, - 2145645056, - 2145693184, - 2145739904, - 2145785472, - 2145829888, - 2145873152, - 2145915136, - 2145956224, - 2145996032, - 2146034944, - 2146072832, - 2146109696, - 2146145664, - 2146180608, - 2146214656, - 2146247808, - }, - { - 2027355264, - 2030408704, - 2033386624, - 2036290944, - 2039123328, - 2041885440, - 2044578944, - 2047205376, - 2049766528, - 2052263680, - 2054698496, - 2057072384, - 2059387008, - 2061643520, - 2063843328, - 2065987968, - 2068078720, - 2070116864, - 2072103552, - 2074040192, - 2075927936, - 2077767936, - 2079561472, - 2081309568, - 2083013376, - 2084673920, - 2086292352, - 2087869696, - 2089406976, - 2090905216, - 2092365184, - 2093788032, - 2095174528, - 2096525824, - 2097842432, - 2099125632, - 2100375808, - 2101594240, - 2102781312, - 2103938048, - 2105065216, - 2106163456, - 2107233536, - 2108276096, - 2109292032, - 2110281728, - 2111246080, - 2112185728, - 2113101056, - 2113992960, - 2114861824, - 2115708288, - 2116532992, - 2117336448, - 2118119168, - 2118881792, - 2119624704, - 2120348416, - 2121053440, - 2121740288, - 2122409344, - 2123061120, - 2123696128, - 2124314624, - 2124917120, - 2125504128, - 2126075776, - 2126632832, - 2127175296, - 2127703808, - 2128218624, - 2128720000, - 2129208448, - 2129684352, - 2130147712, - 2130599168, - 2131038976, - 2131467264, - 2131884416, - 2132290816, - 2132686592, - 2133072256, - 2133447680, - 2133813504, - 2134169856, - 2134516864, - 2134854784, - 2135184000, - 2135504640, - 2135816960, - 2136121216, - 2136417536, - 2136706048, - 2136987136, - 2137260928, - 2137527552, - 2137787264, - 2138040192, - 2138286592, - 2138526464, - 2138760192, - 2138987776, - 2139209472, - 2139425408, - 2139635712, - 2139840512, - 2140039936, - 2140234240, - 2140423424, - 2140607744, - 2140787200, - 2140962048, - 2141132288, - 2141298048, - 2141459584, - 2141616896, - 2141769984, - 2141919232, - 2142064512, - 2142205952, - 2142343808, - 2142478080, - 2142608768, - 2142736128, - 2142860032, - 2142980864, - 2143098368, - 2143212928, - 2143324544, - 2143433088, - 2143538944, - 2143641984, - 2143742336, - 2143840000, - 2143935232, - 2144027904, - 2144118144, - 2144206080, - 2144291712, - 2144375168, - 2144456320, - 2144535424, - 2144612480, - 2144687488, - 2144760448, - 2144831616, - 2144900992, - 2144968448, - 2145034112, - 2145098112, - 2145160448, - 2145221248, - 2145280256, - 2145337856, - 2145393920, - 2145448576, - 2145501696, - 2145553536, - 2145603968, - 2145653120, - 2145700992, - 2145747456, - 2145792896, - 2145837056, - 2145880064, - 2145922048, - 2145962880, - 2146002560, - 2146041344, - 2146078976, - 2146115712, - 2146151424, - 2146186240, - 2146220160, - 2146253184, - 2146285312, - 2146316672, - 2146347136, - 2146376832, - 2146405760, - 2146433920, - 2146461440, - 2146488192, - 2146514176, - 2146539520, - 2146564224, - 2146588160, - 2146611584, - 2146634368, - 2146656640, - 2146678272, - 2146699264, - 2146719744, - 2146739712, - 2146759168, - 2146778112, - 2146796544, - 2146814464, - 2146832000, - 2146849024, - 2146865664, - }, - { - 2086555136, - 2088125824, - 2089656576, - 2091148416, - 2092602240, - 2094018944, - 2095399680, - 2096745088, - 2098056192, - 2099333888, - 2100578816, - 2101792000, - 2102974080, - 2104125824, - 2105248128, - 2106341760, - 2107407232, - 2108445440, - 2109456896, - 2110442496, - 2111402624, - 2112338176, - 2113249664, - 2114137728, - 2115002880, - 2115845760, - 2116666880, - 2117466880, - 2118246272, - 2119005568, - 2119745280, - 2120465920, - 2121167872, - 2121851776, - 2122517888, - 2123166976, - 2123799168, - 2124414976, - 2125014912, - 2125599360, - 2126168704, - 2126723200, - 2127263360, - 2127789568, - 2128302208, - 2128801408, - 2129287808, - 2129761536, - 2130222976, - 2130672512, - 2131110272, - 2131536768, - 2131952128, - 2132356736, - 2132750848, - 2133134720, - 2133508736, - 2133872896, - 2134227584, - 2134573184, - 2134909696, - 2135237504, - 2135556736, - 2135867648, - 2136170624, - 2136465536, - 2136752896, - 2137032832, - 2137305344, - 2137570816, - 2137829376, - 2138081280, - 2138326528, - 2138565504, - 2138798080, - 2139024768, - 2139245440, - 2139460480, - 2139669888, - 2139873792, - 2140072320, - 2140265856, - 2140454144, - 2140637696, - 2140816384, - 2140990464, - 2141159936, - 2141325056, - 2141485824, - 2141642368, - 2141794944, - 2141943424, - 2142088064, - 2142228992, - 2142366208, - 2142499840, - 2142630016, - 2142756736, - 2142880128, - 2143000448, - 2143117440, - 2143231488, - 2143342592, - 2143450752, - 2143556096, - 2143658624, - 2143758592, - 2143855872, - 2143950592, - 2144043008, - 2144132864, - 2144220416, - 2144305664, - 2144388608, - 2144469504, - 2144548224, - 2144624896, - 2144699648, - 2144772352, - 2144843264, - 2144912256, - 2144979328, - 2145044864, - 2145108480, - 2145170560, - 2145231104, - 2145289856, - 2145347200, - 2145403008, - 2145457408, - 2145510400, - 2145561984, - 2145612160, - 2145661056, - 2145708672, - 2145755136, - 2145800192, - 2145844224, - 2145887104, - 2145928832, - 2145969408, - 2146008960, - 2146047616, - 2146085120, - 2146121600, - 2146157184, - 2146191872, - 2146225664, - 2146258560, - 2146290560, - 2146321792, - 2146352128, - 2146381696, - 2146410496, - 2146438528, - 2146465920, - 2146492416, - 2146518400, - 2146543616, - 2146568192, - 2146592128, - 2146615424, - 2146638080, - 2146660224, - 2146681728, - 2146702720, - 2146723072, - 2146743040, - 2146762368, - 2146781184, - 2146799616, - 2146817408, - 2146834816, - 2146851840, - 2146868352, - 2146884352, - 2146900096, - 2146915328, - 2146930176, - 2146944640, - 2146958720, - 2146972416, - 2146985856, - 2146998784, - 2147011456, - 2147023872, - 2147035904, - 2147047552, - 2147058944, - 2147070080, - 2147080832, - 2147091456, - 2147101696, - 2147111680, - 2147121408, - 2147130880, - 2147140096, - 2147149056, - 2147157760, - 2147166336, - 2147174656, - }, - { - 2106670080, - 2107727232, - 2108757120, - 2109760640, - 2110738432, - 2111691008, - 2112619136, - 2113523328, - 2114404352, - 2115262592, - 2116098816, - 2116913408, - 2117707136, - 2118480256, - 2119233536, - 2119967360, - 2120682240, - 2121378688, - 2122057088, - 2122717952, - 2123361792, - 2123988992, - 2124599936, - 2125195136, - 2125774848, - 2126339584, - 2126889728, - 2127425536, - 2127947520, - 2128456064, - 2128951296, - 2129433856, - 2129903744, - 2130361600, - 2130807424, - 2131241728, - 2131664768, - 2132076928, - 2132478208, - 2132869248, - 2133250048, - 2133620992, - 2133982208, - 2134334080, - 2134676864, - 2135010688, - 2135335936, - 2135652608, - 2135961088, - 2136261504, - 2136554112, - 2136839168, - 2137116800, - 2137387136, - 2137650560, - 2137907072, - 2138156928, - 2138400256, - 2138637184, - 2138867968, - 2139092864, - 2139311744, - 2139524992, - 2139732736, - 2139934976, - 2140131968, - 2140323840, - 2140510720, - 2140692736, - 2140870016, - 2141042688, - 2141210752, - 2141374592, - 2141534080, - 2141689344, - 2141840640, - 2141987968, - 2142131456, - 2142271232, - 2142407424, - 2142539904, - 2142669056, - 2142794752, - 2142917248, - 2143036544, - 2143152640, - 2143265792, - 2143375872, - 2143483264, - 2143587712, - 2143689472, - 2143788544, - 2143885056, - 2143979136, - 2144070656, - 2144159872, - 2144246656, - 2144331264, - 2144413568, - 2144493824, - 2144571904, - 2144647936, - 2144722048, - 2144794240, - 2144864512, - 2144932864, - 2144999552, - 2145064448, - 2145127680, - 2145189248, - 2145249152, - 2145307520, - 2145364480, - 2145419776, - 2145473792, - 2145526272, - 2145577472, - 2145627264, - 2145675776, - 2145723008, - 2145768960, - 2145813760, - 2145857408, - 2145899904, - 2145941376, - 2145981696, - 2146020864, - 2146059136, - 2146096384, - 2146132608, - 2146167936, - 2146202368, - 2146235776, - 2146268416, - 2146300160, - 2146331136, - 2146361216, - 2146390528, - 2146419200, - 2146446976, - 2146474112, - 2146500480, - 2146526208, - 2146551168, - 2146575488, - 2146599296, - 2146622464, - 2146644864, - 2146666880, - 2146688128, - 2146708992, - 2146729216, - 2146748928, - 2146768128, - 2146786816, - 2146805120, - 2146822784, - 2146840064, - 2146856960, - 2146873344, - 2146889216, - 2146904832, - 2146919936, - 2146934656, - 2146948992, - 2146962944, - 2146976640, - 2146989824, - 2147002752, - 2147015296, - 2147027584, - 2147039488, - 2147051136, - 2147062400, - 2147073408, - 2147084160, - 2147094528, - 2147104768, - 2147114624, - 2147124352, - 2147133696, - 2147142912, - 2147151744, - 2147160448, - 2147168896, - 2147177088, - 2147185152, - 2147192960, - 2147200512, - 2147207936, - 2147215104, - 2147222144, - 2147229056, - 2147235712, - 2147242112, - 2147248384, - 2147254656, - 2147260544, - 2147266432, - 2147272064, - 2147277568, - }, - - - }; /*----------------------------------------------------------------------------------* diff --git a/lib_rend/ivas_rotation.c b/lib_rend/ivas_rotation_fx.c similarity index 94% rename from lib_rend/ivas_rotation.c rename to lib_rend/ivas_rotation_fx.c index 758d787b196e56b0322c732312da721657e5d3b5..727a212be5ac8726ce5aeb8b574ffc01c709d812 100644 --- a/lib_rend/ivas_rotation.c +++ b/lib_rend/ivas_rotation_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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,11 +37,10 @@ #include "options.h" #include #include "cnst.h" -#include "prot.h" -#include "ivas_prot_rend.h" +#include "prot_fx.h" +#include "ivas_prot_rend_fx.h" #include "wmc_auto.h" #include -#include "prot_fx.h" #include "ivas_prot_fx.h" #include "debug.h" #include "ivas_rom_binaural_crend_head.h" @@ -88,6 +87,9 @@ Word16 square_root30_q12[31] = { static ivas_error combine_external_and_head_orientations( IVAS_QUATERNION *headRotQuaternions, IVAS_VECTOR3 *listenerPos, +#ifdef SPLIT_REND_WITH_HEAD_ROT + ISAR_SPLIT_REND_ROT_AXIS sr_pose_pred_axis, /* i : split rend pose prediction axis*/ +#endif EXTERNAL_ORIENTATION_HANDLE hExtOrientationData, COMBINED_ORIENTATION_HANDLE hCombinedOrientationData ); static void external_target_interpolation_fx( @@ -141,6 +143,10 @@ ivas_error ivas_headTrack_open_fx( move32(); } +#ifdef SPLIT_REND_WITH_HEAD_ROT + ( *hHeadTrackData )->sr_pose_pred_axis = DEFAULT_AXIS; + move32(); +#endif set32_fx( ( *hHeadTrackData )->chEneIIR_fx[0], 0, MASA_FREQUENCY_BANDS ); set32_fx( ( *hHeadTrackData )->chEneIIR_fx[1], 0, MASA_FREQUENCY_BANDS ); @@ -189,103 +195,70 @@ void QuatToRotMat_fx( Word32 Rmat[3][3] /* o : real-space rotation matrix for this rotation 2*Qx-32 */ ) { - Word32 w = quat.w_fx; // Qx - move32(); - Word32 x = quat.x_fx; - move32(); - Word32 y = quat.y_fx; - move32(); - Word32 z = quat.z_fx; - move32(); - - // Adding a guard bit to squared terms since 2*x is not being done in those - // statements (R[0][0], R[1][1], R[2][2]). This is done to avoid L_shl. - Word32 ww = L_shr( Mpy_32_32( w, w ), 1 ); // 2 * Qx - 31 - 1 = 2*Qx-32 - Word32 xx = L_shr( Mpy_32_32( x, x ), 1 ); - Word32 yy = L_shr( Mpy_32_32( y, y ), 1 ); - Word32 zz = L_shr( Mpy_32_32( z, z ), 1 ); - - Word32 wx = Mpy_32_32( w, x ); // 2 * Qx - 31 - Word32 wz = Mpy_32_32( w, z ); - Word32 wy = Mpy_32_32( w, y ); - - Word32 xy = Mpy_32_32( x, y ); - Word32 xz = Mpy_32_32( x, z ); - Word32 yz = Mpy_32_32( y, z ); +#ifdef SPLIT_REND_WITH_HEAD_ROT + IF( EQ_32( quat.w_fx, L_negate( 12582912 ) ) ) + { + assert( 0 ); + // IVAS_QUATERNION quat_local; + // Euler2Quat_fx( deg2rad( quat.x_fx ), deg2rad( quat.y_fx ), deg2rad( quat.z_fx ), &quat_local ); + // QuatToRotMat_fx( quat_local, Rmat ); + } + else + { +#endif + Word32 w = quat.w_fx; // Qx + move32(); + Word32 x = quat.x_fx; + move32(); + Word32 y = quat.y_fx; + move32(); + Word32 z = quat.z_fx; + move32(); - Rmat[0][0] = L_sub( L_sub( L_add( ww, xx ), yy ), zz ); // 2 * Qx - 31 - 1 = 2*Qx-32 - move32(); - Rmat[0][1] = L_sub( xy, wz ); - move32(); - Rmat[0][2] = L_add( xz, wy ); - move32(); + // Adding a guard bit to squared terms since 2*x is not being done in those + // statements (R[0][0], R[1][1], R[2][2]). This is done to avoid L_shl. + Word32 ww = L_shr( Mpy_32_32( w, w ), 1 ); // 2 * Qx - 31 - 1 = 2*Qx-32 + Word32 xx = L_shr( Mpy_32_32( x, x ), 1 ); + Word32 yy = L_shr( Mpy_32_32( y, y ), 1 ); + Word32 zz = L_shr( Mpy_32_32( z, z ), 1 ); - Rmat[1][0] = L_add( xy, wz ); // 2 * Qx - 32 - move32(); - Rmat[1][1] = L_sub( L_add( L_sub( ww, xx ), yy ), zz ); - move32(); - Rmat[1][2] = L_sub( yz, wx ); - move32(); + Word32 wx = Mpy_32_32( w, x ); // 2 * Qx - 31 + Word32 wz = Mpy_32_32( w, z ); + Word32 wy = Mpy_32_32( w, y ); - Rmat[2][0] = L_sub( xz, wy ); // 2 * Qx - 32 - move32(); - Rmat[2][1] = L_add( yz, wx ); - move32(); - Rmat[2][2] = L_add( L_sub( L_sub( ww, xx ), yy ), zz ); - move32(); + Word32 xy = Mpy_32_32( x, y ); + Word32 xz = Mpy_32_32( x, z ); - return; -} + Word32 yz = Mpy_32_32( y, z ); + Rmat[0][0] = L_sub( L_sub( L_add( ww, xx ), yy ), zz ); // 2 * Qx - 31 - 1 = 2*Qx-32 + move32(); + Rmat[0][1] = L_sub( xy, wz ); + move32(); + Rmat[0][2] = L_add( xz, wy ); + move32(); -void Euler2Quat_fx( - const Word32 yaw, /* i : yaw (x) Q22 */ - const Word32 pitch, /* i : pitch (y) Q22 */ - const Word32 roll, /* i : roll (z) Q22 */ - IVAS_QUATERNION *quat /* o : quaternion describing the rotation Q19 */ -) -{ - Word16 cr = getCosWord16( extract_l( L_shr_r( roll, 10 ) ) ); // Q14 - Word16 sr = getSinWord16( extract_l( L_shr_r( roll, 10 ) ) ); - Word16 cp = getCosWord16( extract_l( L_shr_r( pitch, 10 ) ) ); - Word16 sp = getSinWord16( extract_l( L_shr_r( pitch, 10 ) ) ); - Word16 cy = getCosWord16( extract_l( L_shr_r( yaw, 10 ) ) ); - Word16 sy = getSinWord16( extract_l( L_shr_r( yaw, 10 ) ) ); - quat->w_fx = L_shr_r( L_add( Mpy_32_16_1( L_mult0( cr, cp ), cy ), Mpy_32_16_1( L_mult0( sr, sp ), sy ) ), 5 ); // Q19 - move32(); - quat->x_fx = L_shr_r( L_sub( Mpy_32_16_1( L_mult0( sr, cp ), cy ), Mpy_32_16_1( L_mult0( cr, sp ), sy ) ), 5 ); // Q19 - move32(); - quat->y_fx = L_shr_r( L_add( Mpy_32_16_1( L_mult0( sr, cp ), sy ), Mpy_32_16_1( L_mult0( cr, sp ), cy ) ), 5 ); // Q19 - move32(); - quat->z_fx = L_shr_r( L_sub( Mpy_32_16_1( L_mult0( cr, cp ), sy ), Mpy_32_16_1( L_mult0( sr, sp ), cy ) ), 5 ); // Q19 - move32(); + Rmat[1][0] = L_add( xy, wz ); // 2 * Qx - 32 + move32(); + Rmat[1][1] = L_sub( L_add( L_sub( ww, xx ), yy ), zz ); + move32(); + Rmat[1][2] = L_sub( yz, wx ); + move32(); + Rmat[2][0] = L_sub( xz, wy ); // 2 * Qx - 32 + move32(); + Rmat[2][1] = L_add( yz, wx ); + move32(); + Rmat[2][2] = L_add( L_sub( L_sub( ww, xx ), yy ), zz ); + move32(); +#ifdef SPLIT_REND_WITH_HEAD_ROT + } +#endif return; } -/*------------------------------------------------------------------------- - * deg2rad() - * - * Converts degrees to normalized radians - *------------------------------------------------------------------------*/ -Word32 deg2rad_fx( - Word32 degrees // Q23 -) -{ - WHILE( GE_32( degrees, DEGREE_180 ) ) - { - degrees = L_sub( degrees, DEGREE_360 ); - } - WHILE( LE_32( degrees, -DEGREE_180 ) ) - { - degrees = L_add( degrees, DEGREE_360 ); - } - - return Mpy_32_32( PI_OVER_180_FX, degrees ); // Q23 -} - /*------------------------------------------------------------------------- * rad2deg() * @@ -400,7 +373,7 @@ void rotateAziEle_fx( angle = extract_l( L_shr( Mpy_32_16_1( _180_OVER_PI_Q25, radian ), 24 ) ); // Q0 } - *azi = s_max( -180, min( 180, angle ) ); + *azi = s_max( -180, s_min( 180, angle ) ); move16(); IF( isPlanar == 0 ) @@ -758,8 +731,11 @@ void rotateFrame_shd( } /* calculate ambisonics rotation matrices for the previous and current frames */ +#ifdef SPLIT_REND_WITH_HEAD_ROT + SHrotmatgen_fx( SHrotmat_prev, hCombinedOrientationData->Rmat_prev_fx[0], shd_rot_max_order ); +#else SHrotmatgen_fx( SHrotmat_prev, hCombinedOrientationData->Rmat_prev_fx, shd_rot_max_order ); - +#endif SHrotmatgen_fx( SHrotmat /*Q14*/, hCombinedOrientationData->Rmat_fx[hCombinedOrientationData->subframe_idx], shd_rot_max_order ); FOR( i = 0; i < subframe_len; i++ ) @@ -818,9 +794,13 @@ void rotateFrame_shd( /* move Rmat to Rmat_prev */ FOR( i = 0; i < 3; i++ ) { - MVR2R_WORD32( + Copy32( hCombinedOrientationData->Rmat_fx[subframe_idx][i], +#ifdef SPLIT_REND_WITH_HEAD_ROT + hCombinedOrientationData->Rmat_prev_fx[0][i], +#else hCombinedOrientationData->Rmat_prev_fx[i], +#endif 3 ); // Q14 } @@ -919,8 +899,11 @@ void rotateFrame_sd( } /* gains for previous subframe rotation */ +#ifdef SPLIT_REND_WITH_HEAD_ROT + rotateAziEle_fx( extract_l( L_shr( hTransSetup.ls_azimuth_fx[ch_in_woLFE], Q22 ) ), extract_l( L_shr( hTransSetup.ls_elevation_fx[ch_in_woLFE], Q22 ) ), &azimuth, &elevation, hCombinedOrientationData->Rmat_prev_fx[0], hTransSetup.is_planar_setup ); +#else rotateAziEle_fx( extract_l( L_shr( hTransSetup.ls_azimuth_fx[ch_in_woLFE], Q22 ) ), extract_l( L_shr( hTransSetup.ls_elevation_fx[ch_in_woLFE], Q22 ) ), &azimuth, &elevation, hCombinedOrientationData->Rmat_prev_fx, hTransSetup.is_planar_setup ); - +#endif test(); test(); IF( hEFAPdata != NULL && ( NE_16( extract_l( L_shr( hTransSetup.ls_azimuth_fx[ch_in_woLFE], Q22 ) ), azimuth ) || NE_16( extract_l( L_shr( hTransSetup.ls_elevation_fx[ch_in_woLFE], Q22 ) ), elevation ) ) ) @@ -1012,15 +995,19 @@ void rotateFrame_sd( /* move Rmat to Rmat_prev */ FOR( i = 0; i < 3; i++ ) { - MVR2R_WORD32( + Copy32( hCombinedOrientationData->Rmat_fx[hCombinedOrientationData->subframe_idx][i], // Q30 +#ifdef SPLIT_REND_WITH_HEAD_ROT + hCombinedOrientationData->Rmat_prev_fx[0][i], +#else hCombinedOrientationData->Rmat_prev_fx[i], +#endif 3 ); } /* copy to output */ FOR( ch_out = 0; ch_out < nchan; ch_out++ ) { - MVR2R_WORD32( &output_tmp_fx[ch_out][offset], &output[ch_out][offset], subframe_len ); // Q11 + Copy32( &output_tmp_fx[ch_out][offset], &output[ch_out][offset], subframe_len ); // Q11 } pop_wmops(); @@ -1358,6 +1345,9 @@ ivas_error ivas_combined_orientation_open( Word16 j; IVAS_QUATERNION identity; IVAS_VECTOR3 origo; +#ifdef SPLIT_REND_WITH_HEAD_ROT + Word16 pos_idx; +#endif identity.w_fx = ONE_IN_Q31; move32(); identity.x_fx = 0; @@ -1427,13 +1417,31 @@ ivas_error ivas_combined_orientation_open( } } +#ifdef SPLIT_REND_WITH_HEAD_ROT + FOR( pos_idx = 0; pos_idx < MAX_HEAD_ROT_POSES; pos_idx++ ) + { + FOR( j = 0; j < 3; j++ ) + { + set32_fx( ( *hCombinedOrientationData )->Rmat_prev_fx[pos_idx][j], 0, 3 ); + ( *hCombinedOrientationData )->Rmat_prev_fx[pos_idx][j][j] = ONE_IN_Q30; + move32(); + } + } + ( *hCombinedOrientationData )->sr_pose_pred_axis = DEFAULT_AXIS; + ( *hCombinedOrientationData )->sr_low_res_flag = 0; + move32(); + move16(); +#else FOR( j = 0; j < 3; j++ ) { set32_fx( ( *hCombinedOrientationData )->Rmat_prev_fx[j], 0, 3 ); ( *hCombinedOrientationData )->Rmat_prev_fx[j][j] = ONE_IN_Q30; move32(); } - ( *hCombinedOrientationData )->Quaternion_prev_extOrientation = identity; +#endif + + ( *hCombinedOrientationData ) + ->Quaternion_prev_extOrientation = identity; ( *hCombinedOrientationData )->Quaternion_frozen_ext = identity; ( *hCombinedOrientationData )->Quaternion_frozen_head = identity; set_zero_fx( ( *hCombinedOrientationData )->chEneIIR_fx[0], MASA_FREQUENCY_BANDS ); @@ -1494,6 +1502,9 @@ ivas_error combine_external_and_head_orientations_dec( COMBINED_ORIENTATION_HANDLE hCombinedOrientationData /* i/o: combined orientation handle */ ) { +#ifdef SPLIT_REND_WITH_HEAD_ROT + ISAR_SPLIT_REND_ROT_AXIS sr_pose_pred_axis; +#endif IVAS_QUATERNION *pHeadRotQuaternion = NULL; IVAS_VECTOR3 *listenerPos = NULL; @@ -1501,8 +1512,20 @@ ivas_error combine_external_and_head_orientations_dec( { pHeadRotQuaternion = hHeadTrackData->Quaternions; listenerPos = hHeadTrackData->Pos; +#ifdef SPLIT_REND_WITH_HEAD_ROT + sr_pose_pred_axis = hHeadTrackData->sr_pose_pred_axis; +#endif + } +#ifdef SPLIT_REND_WITH_HEAD_ROT + ELSE + { + sr_pose_pred_axis = DEFAULT_AXIS; } +#endif return combine_external_and_head_orientations( pHeadRotQuaternion, listenerPos, +#ifdef SPLIT_REND_WITH_HEAD_ROT + sr_pose_pred_axis, +#endif hExtOrientationData, hCombinedOrientationData ); } @@ -1519,10 +1542,17 @@ ivas_error combine_external_and_head_orientations_rend( COMBINED_ORIENTATION_HANDLE hCombinedOrientationData /* i/o: combined orientation handle */ ) { +#ifdef SPLIT_REND_WITH_HEAD_ROT + ISAR_SPLIT_REND_ROT_AXIS sr_pose_pred_axis; +#endif IVAS_QUATERNION *headRotQuaternions = NULL; IVAS_VECTOR3 *listenerPos = NULL; Word16 i; +#ifdef SPLIT_REND_WITH_HEAD_ROT + sr_pose_pred_axis = DEFAULT_AXIS; +#endif + IF( hHeadTrackData != NULL ) { IF( hHeadTrackData->headRotEnabled ) @@ -1530,6 +1560,9 @@ ivas_error combine_external_and_head_orientations_rend( headRotQuaternions = hHeadTrackData->headPositions; listenerPos = hHeadTrackData->Pos; } +#ifdef SPLIT_REND_WITH_HEAD_ROT + sr_pose_pred_axis = hHeadTrackData->sr_pose_pred_axis; +#endif } ELSE IF( hExtOrientationData != NULL ) { @@ -1545,6 +1578,9 @@ ivas_error combine_external_and_head_orientations_rend( } return combine_external_and_head_orientations( headRotQuaternions, listenerPos, +#ifdef SPLIT_REND_WITH_HEAD_ROT + sr_pose_pred_axis, +#endif hExtOrientationData, hCombinedOrientationData ); } @@ -1556,8 +1592,11 @@ ivas_error combine_external_and_head_orientations_rend( * NOTE that the external orientations are inversed. *------------------------------------------------------------------------*/ ivas_error combine_external_and_head_orientations( - IVAS_QUATERNION *headRotQuaternions, /* i : quaternions for head rotation */ - IVAS_VECTOR3 *listenerPos, /* i : listener position */ + IVAS_QUATERNION *headRotQuaternions, /* i : quaternions for head rotation */ + IVAS_VECTOR3 *listenerPos, /* i : listener position */ +#ifdef SPLIT_REND_WITH_HEAD_ROT + ISAR_SPLIT_REND_ROT_AXIS sr_pose_pred_axis, /* i : split rend pose prediction axis */ +#endif EXTERNAL_ORIENTATION_HANDLE hExtOrientationData, /* i : external orientation handle */ COMBINED_ORIENTATION_HANDLE hCombinedOrientationData /* i/o: combined orientation handle */ ) @@ -1905,6 +1944,10 @@ ivas_error combine_external_and_head_orientations( hCombinedOrientationData->Quaternions[i].q_fact = add( hCombinedOrientationData->Quaternions[i].q_fact, l_shift ); move16(); } + +#ifdef SPLIT_REND_WITH_HEAD_ROT + hCombinedOrientationData->sr_pose_pred_axis = sr_pose_pred_axis; +#endif return IVAS_ERR_OK; } @@ -2213,7 +2256,11 @@ static Word32 SHrot_w_fx( IF( m == 0 ) { +#ifdef SPLIT_REND_WITH_HEAD_ROT + assert( 0 && "ERROR should not be called\n" ); +#else printf( "ERROR should not be called\n" ); +#endif return 0; } ELSE @@ -2413,7 +2460,11 @@ void ivas_combined_orientation_update_index( Word16 exp, div_result; IF( hCombinedOrientationData != NULL ) { +#ifdef SPLIT_REND_WITH_HEAD_ROT + IF( EQ_16( hCombinedOrientationData->num_subframes, 1 ) || hCombinedOrientationData->sr_low_res_flag ) +#else IF( EQ_16( hCombinedOrientationData->num_subframes, 1 ) ) +#endif { /* only one orientation available anyway or split rendering with low resolution*/ hCombinedOrientationData->subframe_idx = 0; @@ -2470,7 +2521,11 @@ void ivas_combined_orientation_update_start_index( { IF( hCombinedOrientationData != NULL ) { +#ifdef SPLIT_REND_WITH_HEAD_ROT + IF( EQ_16( hCombinedOrientationData->num_subframes, 1 ) || hCombinedOrientationData->sr_low_res_flag ) +#else IF( EQ_16( hCombinedOrientationData->num_subframes, 1 ) ) +#endif { /* only one orientation available anyway or split rendering with low resolution*/ hCombinedOrientationData->subframe_idx = 0; diff --git a/lib_rend/ivas_sba_rendering.c b/lib_rend/ivas_sba_rendering_fx.c similarity index 99% rename from lib_rend/ivas_sba_rendering.c rename to lib_rend/ivas_sba_rendering_fx.c index 0309cf61ff3f6721aabaff91e7cfea3e59402562..5e097ab2bedc0622f73dbcc03bdb1431c21aeeab 100644 --- a/lib_rend/ivas_sba_rendering.c +++ b/lib_rend/ivas_sba_rendering_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other @@ -32,10 +32,8 @@ #include #include "options.h" -#include "prot.h" #include "prot_fx.h" -#include "ivas_prot.h" -#include "ivas_prot_rend.h" +#include "ivas_prot_rend_fx.h" #include "ivas_stat_dec.h" #include "ivas_cnst.h" #include diff --git a/lib_rend/ivas_shoebox.c b/lib_rend/ivas_shoebox_fx.c similarity index 99% rename from lib_rend/ivas_shoebox.c rename to lib_rend/ivas_shoebox_fx.c index 6e27da202e25473c707c9ef4f26d951037a3505f..1a1339f5d36a68accb819f417bd681d2fcaed54e 100644 --- a/lib_rend/ivas_shoebox.c +++ b/lib_rend/ivas_shoebox_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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,10 @@ #include "options.h" #include #include -#include "ivas_prot_rend.h" +#include "ivas_prot_rend_fx.h" #include "ivas_stat_rend.h" +#include "ivas_prot_fx.h" #include "ivas_cnst.h" -#include "prot.h" #include "prot_fx.h" #include "wmc_auto.h" #include "ivas_rom_com.h" diff --git a/lib_rend/ivas_stat_rend.h b/lib_rend/ivas_stat_rend.h index 38b2fe524c84a9eaccd902770f6fd8e5637c9afe..028afd9d7686ae7d895c5acfc426e9b076bc8946 100644 --- a/lib_rend/ivas_stat_rend.h +++ b/lib_rend/ivas_stat_rend.h @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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,7 +39,7 @@ #include "ivas_stat_com.h" // note: needed for DIRAC_DEC_BIN_HANDLE until #156 is solved #include "stat_com.h" /* Note: Currently needed for CLDFB. */ #include "common_api_types.h" - +#include "isar_stat.h" /*----------------------------------------------------------------------------------* * Output configuration for renderer (e.g. DirAC, MASA, Binaural Renderer...) @@ -664,9 +664,23 @@ typedef struct ivas_binaural_rendering_conv_module_struct_fx Word32 ***filterTapsRightReal_fx; Word32 ***filterTapsRightImag_fx; +#ifdef SPLIT_REND_WITH_HEAD_ROT + Word32 ****filterStatesLeftReal_fx; + Word32 ****filterStatesLeftImag_fx; +#ifdef OPT_BASOP_ADD_v1 + Word16 *Q_filterStates; +#else + Word16 ****Q_filterStatesLeft; +#endif +#else Word32 ***filterStatesLeftReal_fx; Word32 ***filterStatesLeftImag_fx; +#ifdef OPT_BASOP_ADD_v1 + Word16 Q_filterStatesLeft; +#else /* OPT_BASOP_ADD_v1 */ Word16 ***Q_filterStatesLeft; +#endif /* OPT_BASOP_ADD_v1 */ +#endif /* SPLIT_REND_WITH_HEAD_ROT */ Word16 numTapsArray[BINAURAL_CONVBANDS]; Word16 numTaps; @@ -762,6 +776,9 @@ typedef struct IVAS_QUATERNION headPositions[MAX_PARAM_SPATIAL_SUBFRAMES]; IVAS_VECTOR3 Pos[MAX_PARAM_SPATIAL_SUBFRAMES]; Word32 crossfade_fx[L_FRAME48k / MAX_PARAM_SPATIAL_SUBFRAMES]; /* Q31 */ +#ifdef SPLIT_REND_WITH_HEAD_ROT + ISAR_SPLIT_REND_ROT_AXIS sr_pose_pred_axis; +#endif ivas_orient_trk_state_t *hOrientationTracker; } IVAS_REND_HeadRotData; @@ -783,6 +800,9 @@ typedef struct ivas_binaural_head_track_struct Word16 shd_rot_max_order; ivas_orient_trk_state_t *OrientationTracker; +#ifdef SPLIT_REND_WITH_HEAD_ROT + ISAR_SPLIT_REND_ROT_AXIS sr_pose_pred_axis; +#endif } HEAD_TRACK_DATA, *HEAD_TRACK_DATA_HANDLE; /*----------------------------------------------------------------------------------* @@ -815,14 +835,22 @@ typedef struct ivas_combined_orientation_struct IVAS_QUATERNION Quaternion_prev_extOrientation; IVAS_QUATERNION Quaternions_ext_interpolation_start; IVAS_QUATERNION Quaternions_ext_interpolation_target; - Word32 Rmat_fx[MAX_PARAM_SPATIAL_SUBFRAMES][3][3]; /* Q30 */ - Word32 Rmat_prev_fx[3][3]; /* Q30 */ + Word32 Rmat_fx[MAX_PARAM_SPATIAL_SUBFRAMES][3][3]; /* Q30 */ +#ifdef SPLIT_REND_WITH_HEAD_ROT + Word32 Rmat_prev_fx[MAX_HEAD_ROT_POSES][3][3]; +#else + Word32 Rmat_prev_fx[3][3]; +#endif /* Q30 */ Word32 chEneIIR_fx[2][MASA_FREQUENCY_BANDS]; /* independent of the format. MASA bands are suitable for the task and readily available in ROM. */ /* Q(q_chEneIIR) */ Word16 q_chEneIIR; Word32 procChEneIIR_fx[2][MASA_FREQUENCY_BANDS]; /* Q(q_procChEneIIR) */ Word16 q_procChEneIIR; Word16 shd_rot_max_order; IVAS_VECTOR3 listenerPos[MAX_PARAM_SPATIAL_SUBFRAMES]; +#ifdef SPLIT_REND_WITH_HEAD_ROT + ISAR_SPLIT_REND_ROT_AXIS sr_pose_pred_axis; + Word16 sr_low_res_flag; +#endif IVAS_QUATERNION Quaternion_frozen_ext; IVAS_QUATERNION Quaternion_frozen_head; Word8 isExtOrientationFrozen; @@ -1320,13 +1348,45 @@ typedef struct ivas_crend_state_t typedef struct ivas_binaural_crend_wrapper_struct { Word32 binaural_latency_ns; +#ifdef SPLIT_REND_WITH_HEAD_ROT + CREND_HANDLE hCrend[MAX_HEAD_ROT_POSES]; +#else CREND_HANDLE hCrend; +#endif HRTFS_HANDLE hHrtfCrend; Word16 *p_io_qfactor; Word16 io_qfactor; } CREND_WRAPPER, *CREND_WRAPPER_HANDLE; +#ifdef SPLIT_REND_WITH_HEAD_ROT +/* Fastconv binaural data structure */ +typedef struct ivas_binaural_rendering_struct +{ + /* Common variables for all modules */ + IVAS_OUTPUT_SETUP_HANDLE hInputSetup; /* pointer to input spatial format for binaural renderer*/ + EFAP_HANDLE hEFAPdata; /* EFAP structure*/ + Word32 *hoa_dec_mtx; /* pointer to HOA decoder mtx */ /*Q29*/ + Word8 rotInCldfb; /* Flag to enable rotation within bin Renderer in CLDFB*/ + Word16 max_band; /* band upto which rendering is performed */ + Word16 conv_band; /* band upto which convolution in cldfb domain is performed */ + Word16 timeSlots; /* number of time slots of binaural renderer */ + Word16 nInChannels; /* number input channels */ + Word8 render_lfe; /* Flag to render LFE in binaural rendering*/ + IVAS_FORMAT ivas_format; /* format; corresponds to st_ivas->ivas_format, unless the signal gets transormed to a different domain for rendering */ + + /* Convolution module structure */ + BINRENDERER_CONV_MODULE_HANDLE_FX hBinRenConvModule; + + /* Variables related to reverberator module */ + Word32 earlyPartEneCorrection_fx[CLDFB_NO_CHANNELS_MAX]; + REVERB_STRUCT_HANDLE hReverb; + + Word16 numPoses; + +} BINAURAL_RENDERER, *BINAURAL_RENDERER_HANDLE; +#endif + /*------------------------------------------------------------------------------------------* * HRTF structures - hrtfs from binary files *------------------------------------------------------------------------------------------*/ @@ -1393,6 +1453,21 @@ typedef struct ivas_hrtfs_parambin_struct } HRTFS_PARAMBIN, *HRTFS_PARAMBIN_HANDLE; +#ifdef SPLIT_REND_WITH_HEAD_ROT + +/*----------------------------------------------------------------------------------* + * CLDFB renderer wrapper + *----------------------------------------------------------------------------------*/ + +typedef struct +{ + int32_t binaural_latency_ns; + BINAURAL_RENDERER_HANDLE hCldfbRend; + HRTFS_FASTCONV_HANDLE hHrtfFastConv; + +} CLDFB_REND_WRAPPER; + +#endif /*----------------------------------------------------------------------------------* * Limiter structure @@ -1407,6 +1482,10 @@ typedef struct Word32 release_heuristic_fx; /* Q30 */ Word32 attack_constant_fx; /* Q31 */ Word16 strong_saturation_count; +#ifdef DEBUGGING + int32_t cnt_frames_limited; /* counter of frames in which the limiter is applied */ +#endif + } IVAS_LIMITER, *IVAS_LIMITER_HANDLE; @@ -1426,6 +1505,7 @@ typedef struct ivas_LS_setupconversion_struct } LSSETUP_CONVERSION_STRUCT, *LSSETUP_CONVERSION_HANDLE; + typedef struct ivas_LS_setupconversion_matrix_fx { Word16 index; @@ -1485,7 +1565,11 @@ typedef struct ivas_masa_external_rendering_struct RENDERER_TYPE renderer_type; DIRAC_REND_HANDLE hDirACRend; SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom; +#ifdef SPLIT_REND_WITH_HEAD_ROT + DIRAC_DEC_BIN_HANDLE hDiracDecBin[MAX_HEAD_ROT_POSES]; +#else DIRAC_DEC_BIN_HANDLE hDiracDecBin; +#endif REVERB_STRUCT_HANDLE hReverb; HRTFS_PARAMBIN_HANDLE hHrtfParambin; diff --git a/lib_rend/ivas_td_decorr.c b/lib_rend/ivas_td_decorr_fx.c similarity index 99% rename from lib_rend/ivas_td_decorr.c rename to lib_rend/ivas_td_decorr_fx.c index c4507aae1d60243c3be4cfd0b6fa14bdc02fd47d..0c842e5bd97cc89da8857bff6bd6449d11fb62b7 100644 --- a/lib_rend/ivas_td_decorr.c +++ b/lib_rend/ivas_td_decorr_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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,11 +33,9 @@ #include #include #include "options.h" -#include "prot.h" #include "prot_fx.h" #include "ivas_prot_fx.h" -#include "ivas_prot.h" -#include "ivas_prot_rend.h" +#include "ivas_prot_rend_fx.h" #include "math.h" #include "wmc_auto.h" #ifdef DEBUGGING diff --git a/lib_rend/ivas_vbap.c b/lib_rend/ivas_vbap_fx.c similarity index 99% rename from lib_rend/ivas_vbap.c rename to lib_rend/ivas_vbap_fx.c index 24465c3e70edf0ab1e9de7507d4c8832cec124a1..7495953e3e462f5eca9be008502a81e7be8a6656 100644 --- a/lib_rend/ivas_vbap.c +++ b/lib_rend/ivas_vbap_fx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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,12 +34,10 @@ #include "options.h" #include #include -#include "prot.h" -#include "ivas_prot.h" -#include "ivas_prot_rend.h" +#include "prot_fx.h" +#include "ivas_prot_rend_fx.h" #include "ivas_stat_dec.h" #include "wmc_auto.h" -#include "prot_fx.h" #include "ivas_prot_fx.h" /*-----------------------------------------------------------------------* diff --git a/lib_rend/lib_rend.c b/lib_rend/lib_rend.c index 14bb3b95754fca390e83e823c07a324dfdbbbfb0..9ab74d1c96a39de03be7dd7cadd74ae341330cf0 100644 --- a/lib_rend/lib_rend.c +++ b/lib_rend/lib_rend.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other @@ -32,41 +32,33 @@ #include "basop_util.h" #include "options.h" #include "lib_rend.h" -#include "prot.h" -#include "ivas_prot.h" +#include "prot_fx.h" #include "ivas_prot_fx.h" -#include "ivas_prot_rend.h" +#include "ivas_prot_rend_fx.h" +#include "isar_prot.h" +#include "isar_stat.h" +#include "lib_isar_pre_rend.h" #include "ivas_cnst.h" #include "ivas_rom_com.h" +#include "ivas_rom_com_fx.h" #include "ivas_rom_rend.h" #include #include #include #include "wmc_auto.h" - -#include "ivas_rom_com_fx.h" -#include "ivas_prot_fx.h" -#include "prot_fx.h" +#ifdef DEBUGGING #include "debug.h" -#define float_to_fix( n, factor ) ( round( n * ( 1 << factor ) ) ) -#define fix_to_float( n, factor ) ( (float) n / ( 1 << factor ) ) -#define IVAS_FLOAT_FIXED_TO_BE_REMOVED +#endif + + /*-------------------------------------------------------------------* * Local constants *-------------------------------------------------------------------*/ /* Maximum buffer length (per channel) in samples. * Keep this separate from L_FRAME48k in case we want to support different size later */ -#define MAX_BUFFER_LENGTH_PER_CHANNEL ( L_FRAME48k ) - -/* Maximum buffer length (total) in samples. */ -/* Maximum buffer length (total) in samples. */ -#define MAX_BUFFER_LENGTH ( MAX_BUFFER_LENGTH_PER_CHANNEL * MAX_INPUT_CHANNELS ) - -#define MAX_BIN_DELAY_SAMPLES 50 /* Maximum supported rendering latency for binaural IRs */ - -/* Frame size required when rendering to binaural */ -#define BINAURAL_RENDERING_FRAME_SIZE_MS 5 +#define MAX_BUFFER_LENGTH ( MAX_BUFFER_LENGTH_PER_CHANNEL * MAX_INPUT_CHANNELS ) +#define MAX_BIN_DELAY_SAMPLES 150 /* Maximum supported rendering latency for binaural IRs */ /*-------------------------------------------------------------------* @@ -105,6 +97,11 @@ typedef struct const LSSETUP_CUSTOM_STRUCT *pCustomLsOut; const EFAP_WRAPPER *pEfapOutWrapper; IVAS_REND_HeadRotData *pHeadRotData; // for now removing the const qualifier TODO: will modify later +#ifdef SPLIT_REND_WITH_HEAD_ROT + const RENDER_CONFIG_HANDLE *hhRendererConfig; + const Word16 *pSplitRendBFI; + const SPLIT_REND_WRAPPER *pSplitRendWrapper; +#endif const COMBINED_ORIENTATION_HANDLE *pCombinedOrientationData; } rendering_context; /* Common base for input structs */ @@ -130,6 +127,9 @@ typedef struct rotation_matrix_fx rot_mat_prev_fx; pan_vector prev_pan_gains; Word8 firstFrameRendered; +#ifdef SPLIT_REND_WITH_HEAD_ROT + TDREND_WRAPPER splitTdRendWrappers[MAX_HEAD_ROT_POSES - 1]; /* Additional TD Rend instances used for split rendering */ +#endif Word32 *bufferData_fx; Word16 nonDiegeticPan; Word32 nonDiegeticPanGain_fx; /* Q31 */ @@ -162,8 +162,15 @@ typedef struct EFAP_WRAPPER efapInWrapper; TDREND_WRAPPER tdRendWrapper; CREND_WRAPPER_HANDLE crendWrapper; +#ifdef SPLIT_REND_WITH_HEAD_ROT + TDREND_WRAPPER splitTdRendWrappers[MAX_HEAD_ROT_POSES - 1]; /* Additional TD Rend instances used for split rendering */ +#endif REVERB_HANDLE hReverb; +#ifdef SPLIT_REND_WITH_HEAD_ROT + rotation_gains_Word32 rot_gains_prev_fx[MAX_HEAD_ROT_POSES]; +#else rotation_gains_Word32 rot_gains_prev_fx; +#endif Word16 nonDiegeticPan; Word32 nonDiegeticPanGain_fx; lfe_routing lfeRouting; @@ -177,8 +184,15 @@ typedef struct input_base base; // pan_matrix hoaDecMtx; pan_matrix_fx hoaDecMtx_fx; +#ifdef SPLIT_REND_WITH_HEAD_ROT + CLDFB_REND_WRAPPER cldfbRendWrapper; +#endif CREND_WRAPPER_HANDLE crendWrapper; +#ifdef SPLIT_REND_WITH_HEAD_ROT + rotation_gains_fx rot_gains_prev_fx[MAX_HEAD_ROT_POSES]; +#else rotation_gains_fx rot_gains_prev_fx; +#endif Word32 *bufferData_fx; DIRAC_ANA_HANDLE hDirAC; } input_sba; @@ -208,7 +222,14 @@ struct IVAS_REND EFAP_WRAPPER efapOutWrapper; IVAS_LSSETUP_CUSTOM_STRUCT customLsOut; +#ifdef SPLIT_REND_WITH_HEAD_ROT + SPLIT_REND_WRAPPER splitRendWrapper; + IVAS_REND_AudioBuffer splitRendEncBuffer; +#endif IVAS_REND_HeadRotData headRotData; +#ifdef SPLIT_REND_WITH_HEAD_ROT + Word16 splitRendBFI; +#endif EXTERNAL_ORIENTATION_HANDLE hExternalOrientationData; COMBINED_ORIENTATION_HANDLE hCombinedOrientationData; @@ -228,6 +249,22 @@ static void freeMasaExtRenderer( MASA_EXT_REND_HANDLE *hMasaExtRendOut ); static void intermidiate_ext_dirac_render( MASA_EXT_REND_HANDLE hMasaExtRend, /* i/o: MASA renderer structure */ Word16 to_fix ); + +#ifdef SPLIT_REND_WITH_HEAD_ROT +static ivas_error renderSbaToMultiBinauralCldfb( + input_sba *sbaInput, + Word32 Cldfb_Out_Real[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + Word32 Cldfb_Out_Imag[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + const Word16 low_res_pre_rend_rot, + const Word16 num_subframes, + const Word16 Q_in ); + +static ivas_error renderSbaToMultiBinaural( + input_sba *sbaInput, + const AUDIO_CONFIG outConfig, + Word32 out[][L_FRAME48k] ); +#endif + /*-------------------------------------------------------------------* * Local functions *-------------------------------------------------------------------*/ @@ -306,6 +343,111 @@ static Word32 *getSmplPtr_fx( { return buffer.data_fx + chnlIdx * buffer.config.numSamplesPerChannel + smplIdx; } + +#ifdef SPLIT_REND_WITH_HEAD_ROT +static void convertBitsBufferToInternalBitsBuff( + const IVAS_REND_BitstreamBuffer outBits, + ISAR_SPLIT_REND_BITS_HANDLE hBits ) +{ + hBits->bits_buf = outBits.bits; + hBits->bits_read = outBits.config.bitsRead; + hBits->bits_written = outBits.config.bitsWritten; + hBits->buf_len = outBits.config.bufLenInBytes; + hBits->codec = outBits.config.codec; + hBits->pose_correction = outBits.config.poseCorrection; + hBits->codec_frame_size_ms = outBits.config.codec_frame_size_ms; + + move16(); + move32(); + move32(); + move32(); + move32(); + move32(); + move32(); + + return; +} + +static void convertInternalBitsBuffToBitsBuffer( + IVAS_REND_BitstreamBuffer *hOutBits, + const ISAR_SPLIT_REND_BITS_DATA bits ) +{ + hOutBits->bits = bits.bits_buf; + hOutBits->config.bitsRead = bits.bits_read; + hOutBits->config.bitsWritten = bits.bits_written; + hOutBits->config.bufLenInBytes = bits.buf_len; + hOutBits->config.codec = bits.codec; + hOutBits->config.poseCorrection = bits.pose_correction; + hOutBits->config.codec_frame_size_ms = bits.codec_frame_size_ms; + + return; +} + +static void copyBufferToCLDFBarray_fx( + const IVAS_REND_AudioBuffer buffer, + Word32 re[MAX_OUTPUT_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + Word32 im[MAX_OUTPUT_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX] ) +{ + UWord32 smplIdx, slotIdx; + UWord32 numCldfbSamples, num_bands; + UWord32 chnlIdx; + const Word32 *readPtr; + + assert( ( buffer.config.is_cldfb == 1 ) && "for time domain input call copyBufferTo2dArray()" ); + readPtr = buffer.data_fx; + numCldfbSamples = (UWord32) shr( buffer.config.numSamplesPerChannel, 1 ); + num_bands = (UWord32) Mpy_32_32( numCldfbSamples, ONE_BY_CLDFB_NO_COL_MAX_Q31 ); + FOR( chnlIdx = 0; chnlIdx < (UWord32) buffer.config.numChannels; ++chnlIdx ) + { + FOR( slotIdx = 0; slotIdx < CLDFB_NO_COL_MAX; ++slotIdx ) + { + FOR( smplIdx = 0; smplIdx < num_bands; ++smplIdx ) + { + re[chnlIdx][slotIdx][smplIdx] = *readPtr++; + } + FOR( smplIdx = 0; smplIdx < num_bands; ++smplIdx ) + { + im[chnlIdx][slotIdx][smplIdx] = *readPtr++; + } + } + } + + return; +} + +static void accumulateCLDFBArrayToBuffer_fx( + Word32 re[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + Word32 im[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + IVAS_REND_AudioBuffer *buffer ) +{ + UWord32 smplIdx, slotIdx; + UWord32 numCldfbSamples, num_bands; + UWord32 chnlIdx; + Word32 *writePtr; + + assert( ( buffer->config.is_cldfb == 1 ) && "for time domain input call copyBufferTo2dArray()" ); + writePtr = buffer->data_fx; + numCldfbSamples = (UWord32) shr( buffer->config.numSamplesPerChannel, 1 ); + num_bands = (UWord32) Mpy_32_32( numCldfbSamples, ONE_BY_CLDFB_NO_COL_MAX_Q31 ); + FOR( chnlIdx = 0; chnlIdx < (uint32_t) buffer->config.numChannels; ++chnlIdx ) + { + FOR( slotIdx = 0; slotIdx < CLDFB_NO_COL_MAX; ++slotIdx ) + { + FOR( smplIdx = 0; smplIdx < num_bands; ++smplIdx ) + { + *writePtr++ += re[chnlIdx][slotIdx][smplIdx]; + } + FOR( smplIdx = 0; smplIdx < num_bands; ++smplIdx ) + { + *writePtr++ += im[chnlIdx][slotIdx][smplIdx]; + } + } + } + + return; +} +#endif + static void copyBufferTo2dArray_fx( const IVAS_REND_AudioBuffer buffer, Word32 array[][L_FRAME48k] ) @@ -314,6 +456,10 @@ static void copyBufferTo2dArray_fx( UWord32 chnlIdx; const Word32 *readPtr; +#ifdef SPLIT_REND_WITH_HEAD_ROT + assert( ( buffer.config.is_cldfb == 0 ) && "for CLDFB input call copyBufferToCLDFBarray()" ); +#endif + readPtr = buffer.data_fx; FOR( chnlIdx = 0; chnlIdx < (UWord32) buffer.config.numChannels; ++chnlIdx ) @@ -329,7 +475,7 @@ static void copyBufferTo2dArray_fx( } static void accumulate2dArrayToBuffer_fx( Word32 array[][L_FRAME48k], - IVAS_REND_AudioBuffer *buffer ) + const IVAS_REND_AudioBuffer *buffer ) { Word16 smplIdx, chnlIdx; Word32 *writePtr; @@ -420,6 +566,10 @@ static ivas_error validateOutputAudioConfig( case IVAS_AUDIO_CONFIG_HOA2: case IVAS_AUDIO_CONFIG_HOA3: case IVAS_AUDIO_CONFIG_BINAURAL: +#ifdef SPLIT_REND_WITH_HEAD_ROT + case IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED: + case IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM: +#endif case IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR: case IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB: case IVAS_AUDIO_CONFIG_MASA1: @@ -496,13 +646,20 @@ IVAS_REND_AudioConfigType getAudioConfigType( static ivas_error validateOutputSampleRate( const Word32 sampleRate, - const AUDIO_CONFIG outConfig ) -{ - IF( NE_32( getAudioConfigType( outConfig ), IVAS_REND_AUDIO_CONFIG_TYPE_BINAURAL ) ) - { + const AUDIO_CONFIG outConfig ){ + + IF( NE_32( getAudioConfigType( outConfig ), IVAS_REND_AUDIO_CONFIG_TYPE_BINAURAL ) ){ /* If no binaural rendering, any sampling rate is supported */ return IVAS_ERR_OK; - } +} +#ifdef SPLIT_REND_WITH_HEAD_ROT +ELSE IF( ( EQ_32( outConfig, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) || EQ_32( outConfig, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ) && NE_32( sampleRate, 48000 ) ) +{ + return IVAS_ERROR( IVAS_ERR_INVALID_SAMPLING_RATE, "Error: Only 48kHz output sampling rate is supported for split rendering." ); +} +ELSE +{ +#endif /* Otherwise rendering to binaural, support the same set as IVAS decoder */ SWITCH( sampleRate ) @@ -515,6 +672,9 @@ static ivas_error validateOutputSampleRate( } return IVAS_ERR_INVALID_SAMPLING_RATE; +#ifdef SPLIT_REND_WITH_HEAD_ROT +} +#endif } /*-------------------------------------------------------------------* * getAudioConfigNumChannels() @@ -536,6 +696,10 @@ ivas_error getAudioConfigNumChannels( BREAK; case IVAS_AUDIO_CONFIG_STEREO: case IVAS_AUDIO_CONFIG_BINAURAL: +#ifdef SPLIT_REND_WITH_HEAD_ROT + case IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED: + case IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM: +#endif case IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR: case IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB: case IVAS_AUDIO_CONFIG_MASA2: @@ -1045,6 +1209,10 @@ static ivas_error initHeadRotation_fx( hIvasRend->headRotData.headPositions[i] = quaternionInit_fx(); } +#ifdef SPLIT_REND_WITH_HEAD_ROT + hIvasRend->headRotData.sr_pose_pred_axis = DEFAULT_AXIS; + move32(); +#endif IF( ( hIvasRend->headRotData.hOrientationTracker = (ivas_orient_trk_state_t *) malloc( sizeof( ivas_orient_trk_state_t ) ) ) == NULL ) { @@ -1179,8 +1347,8 @@ static Word8 checkObjectPositionChanged_fx( IVAS_ISM_METADATA *previousPos ) { test(); - return !( LT_32( abs( L_sub( currentPos->azimuth_fx, previousPos->azimuth_fx ) ), EPSILLON_FX ) && - LT_32( abs( L_sub( currentPos->elevation_fx, previousPos->elevation_fx ) ), EPSILLON_FX ) ); + return !( LT_32( L_abs( L_sub( currentPos->azimuth_fx, previousPos->azimuth_fx ) ), EPSILLON_FX ) && + LT_32( L_abs( L_sub( currentPos->elevation_fx, previousPos->elevation_fx ) ), EPSILLON_FX ) ); } static rendering_context getRendCtx( @@ -1196,6 +1364,11 @@ static rendering_context getRendCtx( ctx.pCustomLsOut = &hIvasRend->customLsOut; ctx.pEfapOutWrapper = &hIvasRend->efapOutWrapper; ctx.pHeadRotData = &hIvasRend->headRotData; +#ifdef SPLIT_REND_WITH_HEAD_ROT + ctx.hhRendererConfig = &hIvasRend->hRendererConfig; + ctx.pSplitRendBFI = &hIvasRend->splitRendBFI; + ctx.pSplitRendWrapper = &hIvasRend->splitRendWrapper; +#endif ctx.pCombinedOrientationData = &hIvasRend->hCombinedOrientationData; return ctx; @@ -1244,8 +1417,11 @@ static ivas_error initIsmMasaRendering( inputIsm->tdRendWrapper.hHrtfTD = NULL; } +#ifdef SPLIT_REND_WITH_HEAD_ROT + ivas_rend_closeCrend( &inputIsm->crendWrapper, inputIsm->base.ctx.pSplitRendWrapper->multiBinPoseData.num_poses ); +#else ivas_rend_closeCrend( &inputIsm->crendWrapper ); - +#endif ivas_reverb_close( &inputIsm->hReverb ); IF( NE_32( ( error = ivas_omasa_ana_open( &inputIsm->hOMasa, inSampleRate, inputIsm->total_num_objects ) ), IVAS_ERR_OK ) ) @@ -1267,7 +1443,9 @@ static ivas_error setRendInputActiveIsm( rendering_context rendCtx; AUDIO_CONFIG outConfig; input_ism *inputIsm; - +#ifdef SPLIT_REND_WITH_HEAD_ROT + Word16 i; +#endif inputIsm = (input_ism *) input; rendCtx = inputIsm->base.ctx; outConfig = *rendCtx.pOutConfig; @@ -1296,57 +1474,97 @@ static ivas_error setRendInputActiveIsm( set_zero_fx( inputIsm->prev_pan_gains_fx, MAX_OUTPUT_CHANNELS ); +#ifdef SPLIT_REND_WITH_HEAD_ROT + FOR( i = 0; i < MAX_HEAD_ROT_POSES - 1; ++i ) + { + inputIsm->splitTdRendWrappers[i] = defaultTdRendWrapper(); + } +#endif + inputIsm->hOMasa = NULL; error = IVAS_ERR_OK; move32(); test(); - IF( EQ_16( outConfig, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR ) ) - { - IF( NE_32( ( error = ivas_rend_openCrend( &inputIsm->crendWrapper, IVAS_AUDIO_CONFIG_7_1_4, outConfig, hRendCfg, NULL, *rendCtx.pOutSampleRate ) ), IVAS_ERR_OK ) ) - { + IF( EQ_16( outConfig, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR ) ){ +#ifdef SPLIT_REND_WITH_HEAD_ROT + IF( NE_32( ( error = ivas_rend_openCrend( &inputIsm->crendWrapper, IVAS_AUDIO_CONFIG_7_1_4, outConfig, hRendCfg, NULL, *rendCtx.pOutSampleRate, rendCtx.pSplitRendWrapper->multiBinPoseData.num_poses ) ), IVAS_ERR_OK ) ){ return error; - } +} +#else + IF( NE_32( ( error = ivas_rend_openCrend( &inputIsm->crendWrapper, IVAS_AUDIO_CONFIG_7_1_4, outConfig, hRendCfg, NULL, *rendCtx.pOutSampleRate ) ), IVAS_ERR_OK ) ){ + return error; +} +#endif +} +ELSE IF( EQ_16( outConfig, IVAS_AUDIO_CONFIG_MASA1 ) || EQ_16( outConfig, IVAS_AUDIO_CONFIG_MASA2 ) ) +{ + IF( NE_32( ( error = initIsmMasaRendering( inputIsm, *rendCtx.pOutSampleRate ) ), IVAS_ERR_OK ) ) + { + return error; } - ELSE IF( EQ_16( outConfig, IVAS_AUDIO_CONFIG_MASA1 ) || EQ_16( outConfig, IVAS_AUDIO_CONFIG_MASA2 ) ) +} +ELSE +{ + Word16 SrcInd[MAX_NUM_TDREND_CHANNELS]; + Word16 num_src; + Word16 ivas_format; + IF( EQ_32( getAudioConfigType( inConfig ), IVAS_REND_AUDIO_CONFIG_TYPE_CHANNEL_BASED ) ) { - IF( NE_32( ( error = initIsmMasaRendering( inputIsm, *rendCtx.pOutSampleRate ) ), IVAS_ERR_OK ) ) - { - return error; - } + ivas_format = MC_FORMAT; } ELSE { - Word16 SrcInd[MAX_NUM_TDREND_CHANNELS]; - Word16 num_src; - Word16 ivas_format; - IF( EQ_32( getAudioConfigType( inConfig ), IVAS_REND_AUDIO_CONFIG_TYPE_CHANNEL_BASED ) ) - { - ivas_format = MC_FORMAT; - } - ELSE + ivas_format = ISM_FORMAT; + } + + move16(); + IF( NE_32( ( error = ivas_td_binaural_open_ext_fx( &inputIsm->tdRendWrapper, inConfig, hRendCfg, NULL, *rendCtx.pOutSampleRate, SrcInd, &num_src ) ), IVAS_ERR_OK ) ) + { + return error; + } + + + Word16 nchan_rend = num_src; + move16(); + + test(); + IF( EQ_16( ivas_format, MC_FORMAT ) && NE_32( inConfig, IVAS_AUDIO_CONFIG_LS_CUSTOM ) ) + { + nchan_rend = sub( nchan_rend, 1 ); /* Skip LFE channel -- added to the others */ + } + FOR( Word16 nS = 0; nS < nchan_rend; nS++ ) + { + TDREND_SRC_t *Src_p = inputIsm->tdRendWrapper.hBinRendererTd->Sources[SrcInd[nS]]; + IF( Src_p != NULL ) { - ivas_format = ISM_FORMAT; + IF( Src_p->SrcSpatial_p != NULL ) + { + Src_p->SrcSpatial_p->q_Pos_p = Q31; + move16(); + } + TDREND_SRC_SPATIAL_t *SrcSpatial_p = inputIsm->tdRendWrapper.hBinRendererTd->Sources[nS]->SrcSpatial_p; + SrcSpatial_p->q_Pos_p = Q31; + move16(); } + } - move16(); - IF( NE_32( ( error = ivas_td_binaural_open_ext_fx( &inputIsm->tdRendWrapper, inConfig, hRendCfg, NULL, *rendCtx.pOutSampleRate, SrcInd, &num_src ) ), IVAS_ERR_OK ) ) +#ifdef SPLIT_REND_WITH_HEAD_ROT + /* Open TD renderer wrappers */ + FOR( i = 0; i < MAX_HEAD_ROT_POSES - 1; ++i ) + { + if ( ( error = ivas_td_binaural_open_ext_fx( &inputIsm->splitTdRendWrappers[i], inConfig, hRendCfg, NULL, *inputIsm->base.ctx.pOutSampleRate, SrcInd, &num_src ) ) != IVAS_ERR_OK ) { return error; } - Word16 nchan_rend = num_src; - move16(); + /* Assert same delay as main TD renderer */ + assert( inputIsm->splitTdRendWrappers[i].binaural_latency_ns == inputIsm->tdRendWrapper.binaural_latency_ns ); - test(); - IF( EQ_16( ivas_format, MC_FORMAT ) && NE_32( inConfig, IVAS_AUDIO_CONFIG_LS_CUSTOM ) ) - { - nchan_rend = sub( nchan_rend, 1 ); /* Skip LFE channel -- added to the others */ - } FOR( Word16 nS = 0; nS < nchan_rend; nS++ ) { - TDREND_SRC_t *Src_p = inputIsm->tdRendWrapper.hBinRendererTd->Sources[SrcInd[nS]]; + TDREND_SRC_t *Src_p = inputIsm->splitTdRendWrappers[i].hBinRendererTd->Sources[SrcInd[nS]]; IF( Src_p != NULL ) { IF( Src_p->SrcSpatial_p != NULL ) @@ -1354,28 +1572,34 @@ static ivas_error setRendInputActiveIsm( Src_p->SrcSpatial_p->q_Pos_p = Q31; move16(); } - TDREND_SRC_SPATIAL_t *SrcSpatial_p = inputIsm->tdRendWrapper.hBinRendererTd->Sources[nS]->SrcSpatial_p; + TDREND_SRC_SPATIAL_t *SrcSpatial_p = inputIsm->splitTdRendWrappers[i].hBinRendererTd->Sources[nS]->SrcSpatial_p; SrcSpatial_p->q_Pos_p = Q31; move16(); } } + } + +#endif - IF( EQ_16( outConfig, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) ) + IF( EQ_16( outConfig, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) ) + { + IF( NE_32( ( error = ivas_reverb_open_fx( &( inputIsm->hReverb ), outConfig, NULL, inputIsm->tdRendWrapper.hBinRendererTd->HrFiltSet_p->lr_energy_and_iac_fx, hRendCfg, *rendCtx.pOutSampleRate ) ), IVAS_ERR_OK ) ) { - IF( NE_32( ( error = ivas_reverb_open_fx( &( inputIsm->hReverb ), outConfig, NULL, inputIsm->tdRendWrapper.hBinRendererTd->HrFiltSet_p->lr_energy_and_iac_fx, hRendCfg, *rendCtx.pOutSampleRate ) ), IVAS_ERR_OK ) ) - { - return error; - } + return error; } } +} - return IVAS_ERR_OK; +return IVAS_ERR_OK; } static void clearInputIsm( input_ism *inputIsm ) { rendering_context rendCtx; +#ifdef SPLIT_REND_WITH_HEAD_ROT + int16_t i; +#endif rendCtx = inputIsm->base.ctx; @@ -1384,7 +1608,11 @@ static void clearInputIsm( initRendInputBase_fx( &inputIsm->base, IVAS_AUDIO_CONFIG_INVALID, 0, rendCtx, NULL, 0 ); /* Free input's internal handles */ +#ifdef SPLIT_REND_WITH_HEAD_ROT + ivas_rend_closeCrend( &inputIsm->crendWrapper, inputIsm->base.ctx.pSplitRendWrapper->multiBinPoseData.num_poses ); +#else ivas_rend_closeCrend( &inputIsm->crendWrapper ); +#endif ivas_reverb_close( &inputIsm->hReverb ); @@ -1394,6 +1622,13 @@ static void clearInputIsm( inputIsm->tdRendWrapper.hHrtfTD = NULL; } +#ifdef SPLIT_REND_WITH_HEAD_ROT + FOR( i = 0; i < MAX_HEAD_ROT_POSES - 1; ++i ) + { + ivas_td_binaural_close_fx( &inputIsm->splitTdRendWrappers[i].hBinRendererTd ); + inputIsm->splitTdRendWrappers[i].hHrtfTD = NULL; + } +#endif ivas_omasa_ana_close( &( inputIsm->hOMasa ) ); @@ -2020,7 +2255,7 @@ static ivas_error updateMcPanGainsForAmbiOut( Word32 temp = inputMc->panGains_fx[ch_out][i]; move32(); - IF( GE_32( abs( temp ), ONE_IN_Q29 ) ) + IF( GE_32( L_abs( temp ), ONE_IN_Q29 ) ) { IF( temp > 0 ) { @@ -2068,7 +2303,7 @@ static ivas_error updateMcPanGainsForAmbiOut( { Word32 temp = inputMc->panGains_fx[ch_out][i]; move32(); - IF( GE_32( abs( temp ), ONE_IN_Q29 ) ) + IF( GE_32( L_abs( temp ), ONE_IN_Q29 ) ) { IF( temp > 0 ) { @@ -2123,6 +2358,10 @@ static ivas_error updateMcPanGains( SWITCH( outConfig ) { case IVAS_AUDIO_CONFIG_BINAURAL: +#ifdef SPLIT_REND_WITH_HEAD_ROT + case IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED: + case IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM: +#endif BREAK; /* Do nothing */ case IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR: case IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB: @@ -2172,6 +2411,9 @@ static ivas_error initMcBinauralRendering( Word32 binauralDelayNs; Word32 outSampleRate; Word8 useTDRend; +#ifdef SPLIT_REND_WITH_HEAD_ROT + int16_t i; +#endif /* Allocate TD binaural renderer for custom loudspeaker layouts (regardless of headrotation) or planar MC layouts with headrotation, CREND for the rest */ @@ -2203,11 +2445,28 @@ static ivas_error initMcBinauralRendering( inputMc->tdRendWrapper.hHrtfTD = NULL; } +#ifdef SPLIT_REND_WITH_HEAD_ROT + IF( !reconfigureFlag || !useTDRend ) + { + FOR( i = 0; i < MAX_HEAD_ROT_POSES - 1; ++i ) + { + IF( inputMc->splitTdRendWrappers[i].hBinRendererTd != NULL ) + { + ivas_td_binaural_close_fx( &inputMc->splitTdRendWrappers[i].hBinRendererTd ); + inputMc->splitTdRendWrappers[i].hHrtfTD = NULL; + } + } + } +#endif /* if we need to use TD renderer and CREND was open, close it */ IF( useTDRend ) { +#ifdef SPLIT_REND_WITH_HEAD_ROT + ivas_rend_closeCrend( &inputMc->crendWrapper, inputMc->base.ctx.pSplitRendWrapper->multiBinPoseData.num_poses ); +#else ivas_rend_closeCrend( &inputMc->crendWrapper ); +#endif } test(); @@ -2266,6 +2525,44 @@ static ivas_error initMcBinauralRendering( } } } + +#ifdef SPLIT_REND_WITH_HEAD_ROT + IF( EQ_32( outConfig, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) || EQ_32( outConfig, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ) + { + /* Open TD renderer wrappers */ + FOR( i = 0; i < MAX_HEAD_ROT_POSES - 1; ++i ) + { + IF( ( error = ivas_td_binaural_open_ext_fx( &inputMc->splitTdRendWrappers[i], inConfig, hRendCfg, &inputMc->customLsInput, outSampleRate, SrcInd, &num_src ) ) != IVAS_ERR_OK ) + { + return error; + } + + /* Assert same delay as main TD renderer */ + assert( inputMc->splitTdRendWrappers[i].binaural_latency_ns == inputMc->tdRendWrapper.binaural_latency_ns ); + + FOR( Word16 nS = 0; nS < nchan_rend; nS++ ) + { + TDREND_SRC_t *Src_p = inputMc->splitTdRendWrappers[i].hBinRendererTd->Sources[SrcInd[nS]]; + IF( Src_p != NULL ) + { + IF( Src_p->SrcSpatial_p != NULL ) + { + Src_p->SrcSpatial_p->q_Pos_p = 31; + move16(); + } + IF( inputMc->splitTdRendWrappers[i].hBinRendererTd->Sources[nS] != NULL ) + { + TDREND_SRC_SPATIAL_t *SrcSpatial_p = inputMc->splitTdRendWrappers[i].hBinRendererTd->Sources[nS]->SrcSpatial_p; + SrcSpatial_p->q_Pos_p = 31; + move16(); + } + } + } + } + } + +#endif + test(); IF( EQ_32( outConfig, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) && inputMc->hReverb == NULL ) { @@ -2278,7 +2575,11 @@ static ivas_error initMcBinauralRendering( ELSE IF( !useTDRend && inputMc->crendWrapper == NULL ) { /* open CREND */ +#ifdef SPLIT_REND_WITH_HEAD_ROT + IF( NE_32( ( error = ivas_rend_openCrend( &inputMc->crendWrapper, ( EQ_16( inConfig, IVAS_AUDIO_CONFIG_LS_CUSTOM ) ) ? IVAS_AUDIO_CONFIG_7_1_4 : inConfig, outConfig, hRendCfg, NULL, 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( NE_32( ( error = ivas_rend_openCrend( &inputMc->crendWrapper, ( EQ_16( inConfig, IVAS_AUDIO_CONFIG_LS_CUSTOM ) ) ? IVAS_AUDIO_CONFIG_7_1_4 : inConfig, outConfig, hRendCfg, NULL, outSampleRate ) ), IVAS_ERR_OK ) ) +#endif { return error; } @@ -2337,7 +2638,11 @@ static ivas_error initMcMasaRendering( inputMc->tdRendWrapper.hHrtfTD = NULL; } +#ifdef SPLIT_REND_WITH_HEAD_ROT + ivas_rend_closeCrend( &inputMc->crendWrapper, inputMc->base.ctx.pSplitRendWrapper->multiBinPoseData.num_poses ); +#else ivas_rend_closeCrend( &inputMc->crendWrapper ); +#endif ivas_reverb_close( &inputMc->hReverb ); @@ -2423,10 +2728,16 @@ static ivas_error setRendInputActiveMc( const IVAS_REND_InputId id, RENDER_CONFIG_DATA *hRendCfg ) { +#ifdef SPLIT_REND_WITH_HEAD_ROT + Word16 i; +#endif ivas_error error; rendering_context rendCtx; AUDIO_CONFIG outConfig; input_mc *inputMc; +#ifdef SPLIT_REND_WITH_HEAD_ROT + Word16 pos_idx; +#endif inputMc = (input_mc *) input; rendCtx = inputMc->base.ctx; @@ -2455,7 +2766,14 @@ static ivas_error setRendInputActiveMc( inputMc->hReverb = NULL; inputMc->hMcMasa = NULL; +#ifdef SPLIT_REND_WITH_HEAD_ROT + FOR( pos_idx = 0; pos_idx < MAX_HEAD_ROT_POSES; pos_idx++ ) + { + initRotGainsWord32_fx( inputMc->rot_gains_prev_fx[pos_idx] ); + } +#else initRotGainsWord32_fx( inputMc->rot_gains_prev_fx ); +#endif inputMc->lfeRouting = defaultLfeRouting( inConfig, inputMc->customLsInput, outConfig, *inputMc->base.ctx.pCustomLsOut ); set32_fx( inputMc->lfeDelayBuffer_fx, 0, MAX_BIN_DELAY_SAMPLES ); inputMc->binauralDelaySmp = 0; @@ -2463,7 +2781,16 @@ static ivas_error setRendInputActiveMc( test(); test(); +#ifdef SPLIT_REND_WITH_HEAD_ROT + FOR( i = 0; i < MAX_HEAD_ROT_POSES - 1; ++i ) + { + inputMc->splitTdRendWrappers[i] = defaultTdRendWrapper(); + } + + IF( EQ_32( getAudioConfigType( outConfig ), IVAS_REND_AUDIO_CONFIG_TYPE_BINAURAL ) ) +#else IF( EQ_16( outConfig, IVAS_AUDIO_CONFIG_BINAURAL ) || EQ_16( outConfig, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR ) || EQ_16( outConfig, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) ) +#endif { IF( NE_32( ( error = initMcBinauralRendering( inputMc, inConfig, outConfig, hRendCfg, FALSE ) ), IVAS_ERR_OK ) ) { @@ -2491,6 +2818,9 @@ static void clearInputMc( input_mc *inputMc ) { rendering_context rendCtx; +#ifdef SPLIT_REND_WITH_HEAD_ROT + Word16 i; +#endif rendCtx = inputMc->base.ctx; freeMcLfeDelayBuffer_fx( &inputMc->lfeDelayBuffer_fx ); @@ -2503,7 +2833,11 @@ static void clearInputMc( efap_free_data_fx( &inputMc->efapInWrapper.hEfap ); } +#ifdef SPLIT_REND_WITH_HEAD_ROT + ivas_rend_closeCrend( &inputMc->crendWrapper, inputMc->base.ctx.pSplitRendWrapper->multiBinPoseData.num_poses ); +#else ivas_rend_closeCrend( &inputMc->crendWrapper ); +#endif ivas_reverb_close( &inputMc->hReverb ); @@ -2513,6 +2847,16 @@ static void clearInputMc( inputMc->tdRendWrapper.hHrtfTD = NULL; } +#ifdef SPLIT_REND_WITH_HEAD_ROT + FOR( i = 0; i < MAX_HEAD_ROT_POSES - 1; ++i ) + { + IF( inputMc->splitTdRendWrappers[i].hBinRendererTd != NULL ) + { + ivas_td_binaural_close_fx( &inputMc->splitTdRendWrappers[i].hBinRendererTd ); + inputMc->splitTdRendWrappers[i].hHrtfTD = NULL; + } + } +#endif ivas_mcmasa_ana_close( &( inputMc->hMcMasa ) ); @@ -2634,12 +2978,58 @@ static ivas_error updateSbaPanGains( case IVAS_REND_AUDIO_CONFIG_TYPE_BINAURAL: SWITCH( outConfig ) { - case IVAS_AUDIO_CONFIG_BINAURAL: +#ifdef SPLIT_REND_WITH_HEAD_ROT + case IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED: + case IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM: { - IF( NE_32( ( error = ivas_rend_openCrend( &inputSba->crendWrapper, inConfig, outConfig, hRendCfg, NULL, *rendCtx.pOutSampleRate ) ), IVAS_ERR_OK ) ) + IF( EQ_32( hRendCfg->split_rend_config.rendererSelection, ISAR_SPLIT_REND_RENDERER_SELECTION_FASTCONV ) ) { - return error; + assert( inConfig == IVAS_AUDIO_CONFIG_HOA3 && ( *rendCtx.pOutSampleRate == 48000 ) && "split binaural fast conv mode is currently supported with HOA3 input and 48k sampling rate only" ); + if ( ( error = ivas_rend_openCldfbRend( &inputSba->cldfbRendWrapper, inConfig, outConfig, &rendCtx.pSplitRendWrapper->multiBinPoseData, *rendCtx.pOutSampleRate ) ) != IVAS_ERR_OK ) + { + return error; + } + } + else + { + assert( ( *rendCtx.pOutSampleRate == 48000 ) && "split binaural crend mode is currently supported with 48k sampling rate only" ); + if ( ( error = ivas_rend_openMultiBinCrend( &inputSba->crendWrapper, inConfig, outConfig, + &rendCtx.pSplitRendWrapper->multiBinPoseData, *rendCtx.pOutSampleRate ) ) != IVAS_ERR_OK ) + { + return error; + } + } + break; + } +#endif + case IVAS_AUDIO_CONFIG_BINAURAL: + { +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( hRendCfg->split_rend_config.rendererSelection == ISAR_SPLIT_REND_RENDERER_SELECTION_FASTCONV ) + { + if ( ( error = ivas_rend_openCldfbRend( &inputSba->cldfbRendWrapper, inConfig, outConfig, + &rendCtx.pSplitRendWrapper->multiBinPoseData, *rendCtx.pOutSampleRate ) ) != IVAS_ERR_OK ) + { + return error; + } + } + else +#endif + { +#ifdef SPLIT_REND_WITH_HEAD_ROT + IF( NE_32( ( error = ivas_rend_openCrend( &inputSba->crendWrapper, inConfig, outConfig, hRendCfg, NULL, *rendCtx.pOutSampleRate, rendCtx.pSplitRendWrapper->multiBinPoseData.num_poses ) ), IVAS_ERR_OK ) ) + + { + return error; + } +#else + IF( NE_32( ( error = ivas_rend_openCrend( &inputSba->crendWrapper, inConfig, outConfig, hRendCfg, NULL, *rendCtx.pOutSampleRate ) ), IVAS_ERR_OK ) ) + + { + return error; + } +#endif } } BREAK; @@ -2649,11 +3039,17 @@ static ivas_error updateSbaPanGains( { return error; } - +#ifdef SPLIT_REND_WITH_HEAD_ROT + IF( NE_32( ( error = ivas_rend_openCrend( &inputSba->crendWrapper, IVAS_AUDIO_CONFIG_7_1_4, outConfig, hRendCfg, NULL, *rendCtx.pOutSampleRate, rendCtx.pSplitRendWrapper->multiBinPoseData.num_poses ) ), IVAS_ERR_OK ) ) + { + return error; + } +#else IF( NE_32( ( error = ivas_rend_openCrend( &inputSba->crendWrapper, IVAS_AUDIO_CONFIG_7_1_4, outConfig, hRendCfg, NULL, *rendCtx.pOutSampleRate ) ), IVAS_ERR_OK ) ) { return error; } +#endif BREAK; default: return IVAS_ERR_INVALID_OUTPUT_FORMAT; @@ -2682,7 +3078,11 @@ static ivas_error initSbaMasaRendering( { ivas_error error; +#ifdef SPLIT_REND_WITH_HEAD_ROT + ivas_rend_closeCrend( &inputSba->crendWrapper, inputSba->base.ctx.pSplitRendWrapper->multiBinPoseData.num_poses ); +#else ivas_rend_closeCrend( &inputSba->crendWrapper ); +#endif IF( NE_32( ( error = ivas_dirac_ana_open_fx( &inputSba->hDirAC, inSampleRate ) ), IVAS_ERR_OK ) ) { @@ -2702,6 +3102,9 @@ static ivas_error setRendInputActiveSba( rendering_context rendCtx; AUDIO_CONFIG outConfig; input_sba *inputSba; +#ifdef SPLIT_REND_WITH_HEAD_ROT + int16_t pos_idx; +#endif inputSba = (input_sba *) input; rendCtx = inputSba->base.ctx; @@ -2713,17 +3116,36 @@ static ivas_error setRendInputActiveSba( return IVAS_ERR_IO_CONFIG_PAIR_NOT_SUPPORTED; } +#ifdef SPLIT_REND_WITH_HEAD_ROT + IF( NE_32( ( error = allocateInputBaseBufferData_fx( &inputSba->bufferData_fx, MAX_CLDFB_BUFFER_LENGTH ) ), IVAS_ERR_OK ) ) + { + return error; + } +#else IF( NE_32( ( error = allocateInputBaseBufferData_fx( &inputSba->bufferData_fx, MAX_BUFFER_LENGTH ) ), IVAS_ERR_OK ) ) { return error; } +#endif + +#ifdef SPLIT_REND_WITH_HEAD_ROT + initRendInputBase_fx( &inputSba->base, inConfig, id, rendCtx, inputSba->bufferData_fx, MAX_CLDFB_BUFFER_LENGTH ); +#else initRendInputBase_fx( &inputSba->base, inConfig, id, rendCtx, inputSba->bufferData_fx, MAX_BUFFER_LENGTH ); +#endif setZeroPanMatrix_fx( inputSba->hoaDecMtx_fx ); inputSba->crendWrapper = NULL; inputSba->hDirAC = NULL; - initRotGains_fx( inputSba->rot_gains_prev_fx ); +#ifdef SPLIT_REND_WITH_HEAD_ROT + FOR( pos_idx = 0; pos_idx < MAX_HEAD_ROT_POSES; pos_idx++ ) + { + initRotGains_fx( inputSba->rot_gains_prev_fx[pos_idx] ); + } +#else + initRotGains_fx( inputSba->rot_gains_prev_fx ); +#endif test(); IF( EQ_32( outConfig, IVAS_AUDIO_CONFIG_MASA1 ) || EQ_32( outConfig, IVAS_AUDIO_CONFIG_MASA2 ) ) @@ -2752,8 +3174,17 @@ static void clearInputSba( initRendInputBase_fx( &inputSba->base, IVAS_AUDIO_CONFIG_INVALID, 0, rendCtx, NULL, 0 ); +#ifdef SPLIT_REND_WITH_HEAD_ROT + ivas_rend_closeCrend( &inputSba->crendWrapper, rendCtx.pSplitRendWrapper->multiBinPoseData.num_poses ); + + IF( inputSba->cldfbRendWrapper.hCldfbRend != NULL ) + { + ivas_rend_closeCldfbRend( &inputSba->cldfbRendWrapper ); + } +#else /* Free input's internal handles */ ivas_rend_closeCrend( &inputSba->crendWrapper ); +#endif ivas_dirac_ana_close_fx( &( inputSba->hDirAC ) ); @@ -2860,6 +3291,9 @@ ivas_error IVAS_REND_Open( const Word16 num_subframes ) { Word16 i; +#ifdef SPLIT_REND_WITH_HEAD_ROT + Word16 j; +#endif IVAS_REND_HANDLE hIvasRend; ivas_error error; Word16 numOutChannels; @@ -2929,6 +3363,10 @@ ivas_error IVAS_REND_Open( } /* Initialize inputs */ +#ifdef SPLIT_REND_WITH_HEAD_ROT + isar_init_split_rend_handles( &hIvasRend->splitRendWrapper ); + hIvasRend->splitRendEncBuffer.data_fx = NULL; +#endif FOR( i = 0; i < RENDERER_MAX_ISM_INPUTS; ++i ) { @@ -2936,6 +3374,13 @@ ivas_error IVAS_REND_Open( hIvasRend->inputsIsm[i].crendWrapper = NULL; hIvasRend->inputsIsm[i].hReverb = NULL; hIvasRend->inputsIsm[i].tdRendWrapper.hBinRendererTd = NULL; +#ifdef SPLIT_REND_WITH_HEAD_ROT + FOR( j = 0; j < MAX_HEAD_ROT_POSES - 1; ++j ) + { + hIvasRend->inputsIsm[i].splitTdRendWrappers[j].hBinRendererTd = NULL; + hIvasRend->inputsIsm[i].splitTdRendWrappers[j].hHrtfTD = NULL; + } +#endif hIvasRend->inputsIsm[i].nonDiegeticPan = nonDiegeticPan; move16(); hIvasRend->inputsIsm[i].nonDiegeticPanGain_fx = nonDiegeticPanGain; @@ -2959,6 +3404,13 @@ ivas_error IVAS_REND_Open( hIvasRend->inputsMc[i].nonDiegeticPanGain_fx = nonDiegeticPanGain; move32(); hIvasRend->inputsMc[i].hMcMasa = NULL; +#ifdef SPLIT_REND_WITH_HEAD_ROT + FOR( j = 0; j < MAX_HEAD_ROT_POSES - 1; ++j ) + { + hIvasRend->inputsMc[i].splitTdRendWrappers[j].hBinRendererTd = NULL; + hIvasRend->inputsMc[i].splitTdRendWrappers[j].hHrtfTD = NULL; + } +#endif } FOR( i = 0; i < RENDERER_MAX_SBA_INPUTS; ++i ) @@ -2966,6 +3418,10 @@ ivas_error IVAS_REND_Open( initRendInputBase_fx( &hIvasRend->inputsSba[i].base, IVAS_AUDIO_CONFIG_INVALID, 0, getRendCtx( hIvasRend ), NULL, 0 ); hIvasRend->inputsSba[i].crendWrapper = NULL; +#ifdef SPLIT_REND_WITH_HEAD_ROT + hIvasRend->inputsSba[i].cldfbRendWrapper.hCldfbRend = NULL; + hIvasRend->inputsSba[i].cldfbRendWrapper.hHrtfFastConv = NULL; +#endif hIvasRend->inputsSba[i].bufferData_fx = NULL; hIvasRend->inputsSba[i].hDirAC = NULL; } @@ -3361,6 +3817,138 @@ static ivas_error findFreeInputSlot_fx( } +#ifdef SPLIT_REND_WITH_HEAD_ROT +static Word16 getCldfbRendFlag( + IVAS_REND_HANDLE hIvasRend, /* i : Renderer handle */ + const IVAS_REND_AudioConfigType new_configType ) +{ + Word16 i; + Word16 numMasaInputs = 0, numSbaInputs = 0, numIsmInputs = 0, numMcInputs = 0; + Word16 isCldfbRend; + + move16(); + move16(); + move16(); + move16(); + + isCldfbRend = 0; + move16(); + + IF( hIvasRend->hRendererConfig != NULL ) + { + FOR( i = 0; i < RENDERER_MAX_MASA_INPUTS; ++i ) + { + numMasaInputs = add( numMasaInputs, ( hIvasRend->inputsMasa[i].base.inConfig == IVAS_AUDIO_CONFIG_INVALID && new_configType != IVAS_REND_AUDIO_CONFIG_TYPE_MASA ) ? 0 : 1 ); + move16(); + } + FOR( i = 0; i < RENDERER_MAX_SBA_INPUTS; ++i ) + { + numSbaInputs = add( numSbaInputs, ( hIvasRend->inputsSba[i].base.inConfig == IVAS_AUDIO_CONFIG_INVALID && new_configType != IVAS_REND_AUDIO_CONFIG_TYPE_AMBISONICS ) ? 0 : 1 ); + move16(); + } + FOR( i = 0; i < RENDERER_MAX_ISM_INPUTS; ++i ) + { + numIsmInputs = add( numIsmInputs, ( hIvasRend->inputsIsm[i].base.inConfig == IVAS_AUDIO_CONFIG_INVALID && new_configType != IVAS_REND_AUDIO_CONFIG_TYPE_OBJECT_BASED ) ? 0 : 1 ); + move16(); + } + FOR( i = 0; i < RENDERER_MAX_MC_INPUTS; ++i ) + { + numMcInputs = add( numMcInputs, ( hIvasRend->inputsMc[i].base.inConfig == IVAS_AUDIO_CONFIG_INVALID && new_configType != IVAS_REND_AUDIO_CONFIG_TYPE_CHANNEL_BASED ) ? 0 : 1 ); + move16(); + } + + IF( GT_16( numIsmInputs, 0 ) || GT_16( numMcInputs, 0 ) ) + { + isCldfbRend = 0; + move16(); + } + ELSE IF( GT_16( numMasaInputs, 0 ) || ( GT_16( numSbaInputs, 0 ) && EQ_32( hIvasRend->hRendererConfig->split_rend_config.rendererSelection, ISAR_SPLIT_REND_RENDERER_SELECTION_FASTCONV ) ) ) + { + isCldfbRend = 1; + move16(); + } + } + + return isCldfbRend; +} + +/*------------------------------------------------------------------------- + * Function ivas_pre_rend_init() + * + * + *------------------------------------------------------------------------*/ + +static ivas_error ivas_pre_rend_init( + SPLIT_REND_WRAPPER *pSplitRendWrapper, + IVAS_REND_AudioBuffer *pSplitRendEncBuffer, + ISAR_SPLIT_REND_CONFIG_DATA *pSplit_rend_config, + IVAS_REND_HeadRotData headRotData, + const Word32 outputSampleRate, + const AUDIO_CONFIG outConfig, + const Word16 cldfb_in_flag, + const Word16 num_subframes ) +{ + ivas_error error; + IVAS_REND_AudioBufferConfig bufConfig; + + IF( EQ_32( outConfig, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) || EQ_32( outConfig, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ) + { + IF( EQ_32( pSplit_rend_config->poseCorrectionMode, ISAR_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB ) ) + { + ISAR_PRE_REND_GetMultiBinPoseData( pSplit_rend_config, &pSplitRendWrapper->multiBinPoseData, headRotData.sr_pose_pred_axis ); + } + ELSE IF( EQ_32( pSplit_rend_config->poseCorrectionMode, ISAR_SPLIT_REND_POSE_CORRECTION_MODE_NONE ) ) + { + isar_renderSplitUpdateNoCorrectionPoseData( pSplit_rend_config, &pSplitRendWrapper->multiBinPoseData ); + } + + IF( ( error = ISAR_PRE_REND_open( pSplitRendWrapper, pSplit_rend_config, outputSampleRate, cldfb_in_flag, outConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM, num_subframes, 0 ) ) != IVAS_ERR_OK ) + { + return error; + } + + /*allocate for CLDFB in and change to TD during process if needed*/ + bufConfig.numSamplesPerChannel = MAX_CLDFB_BUFFER_LENGTH_PER_CHANNEL; + bufConfig.numChannels = i_mult( BINAURAL_CHANNELS, pSplitRendWrapper->multiBinPoseData.num_poses ); + bufConfig.is_cldfb = 1; + pSplitRendEncBuffer->config = bufConfig; + move16(); + move16(); + move16(); + move32(); + + IF( ( pSplitRendEncBuffer->data_fx = malloc( bufConfig.numChannels * bufConfig.numSamplesPerChannel * sizeof( float ) ) ) == NULL ) + { + return IVAS_ERR_FAILED_ALLOC; + } + + pSplitRendEncBuffer->q_factor = 0; + pSplitRendEncBuffer->pq_fact = &pSplitRendEncBuffer->q_factor; + } + ELSE + { + IVAS_REND_AudioBufferConfig bufConfig2; + + bufConfig2.numSamplesPerChannel = 0; + bufConfig2.numChannels = 0; + bufConfig2.is_cldfb = 0; + pSplitRendEncBuffer->config = bufConfig2; + pSplitRendEncBuffer->data_fx = NULL; + pSplitRendEncBuffer->pq_fact = NULL; + pSplitRendEncBuffer->q_factor = 0; + move16(); + move16(); + move16(); + move32(); + move32(); + } + + return IVAS_ERR_OK; +} + +#endif + + /*-------------------------------------------------------------------* * IVAS_REND_AddInput() * @@ -3386,6 +3974,19 @@ ivas_error IVAS_REND_AddInput_fx( return IVAS_ERR_UNEXPECTED_NULL_POINTER; } +#ifdef SPLIT_REND_WITH_HEAD_ROT + IF( ( EQ_32( hIvasRend->outputConfig, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) || EQ_32( hIvasRend->outputConfig, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ) && hIvasRend->splitRendEncBuffer.data_fx == NULL && hIvasRend->hRendererConfig != NULL ) + { + Word16 cldfb_in_flag; + cldfb_in_flag = getCldfbRendFlag( hIvasRend, getAudioConfigType( inConfig ) ); + + IF( ( error = ivas_pre_rend_init( &hIvasRend->splitRendWrapper, &hIvasRend->splitRendEncBuffer, &hIvasRend->hRendererConfig->split_rend_config, hIvasRend->headRotData, hIvasRend->sampleRateOut, hIvasRend->outputConfig, cldfb_in_flag, hIvasRend->num_subframes ) ) != IVAS_ERR_OK ) + { + return error; + } + } +#endif + SWITCH( getAudioConfigType( inConfig ) ) { @@ -3494,7 +4095,11 @@ ivas_error IVAS_REND_ConfigureCustomInputLoudspeakerLayout( test(); test(); +#ifdef SPLIT_REND_WITH_HEAD_ROT + IF( EQ_32( getAudioConfigType( hIvasRend->outputConfig ), IVAS_REND_AUDIO_CONFIG_TYPE_BINAURAL ) ) +#else IF( EQ_16( hIvasRend->outputConfig, IVAS_AUDIO_CONFIG_BINAURAL ) || EQ_16( hIvasRend->outputConfig, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR ) || EQ_16( hIvasRend->outputConfig, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) ) +#endif { IF( NE_32( ( error = initMcBinauralRendering( inputMc, inputMc->base.inConfig, hIvasRend->outputConfig, hIvasRend->hRendererConfig, FALSE ) ), IVAS_ERR_OK ) ) { @@ -3836,6 +4441,27 @@ ivas_error IVAS_REND_GetDelay_fx( { IF( NE_32( hIvasRend->inputsSba[i].base.inConfig, IVAS_AUDIO_CONFIG_INVALID ) ) { +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( hIvasRend->splitRendWrapper.hBinHrSplitPreRend != NULL ) + { + if ( hIvasRend->hRendererConfig->split_rend_config.rendererSelection == ISAR_SPLIT_REND_RENDERER_SELECTION_FASTCONV ) + { + latency_ns = hIvasRend->inputsSba[i].cldfbRendWrapper.binaural_latency_ns; + } + else + { + latency_ns = ( hIvasRend->inputsSba[i].crendWrapper != NULL ) ? hIvasRend->inputsSba[i].crendWrapper->binaural_latency_ns : 0; + } + max_latency_ns = max( max_latency_ns, latency_ns ); + } + else if ( hIvasRend->inputsSba[i].cldfbRendWrapper.hCldfbRend != NULL ) + { + latency_ns = hIvasRend->inputsSba[i].cldfbRendWrapper.binaural_latency_ns; + latency_ns += IVAS_FB_DEC_DELAY_NS; + max_latency_ns = max( max_latency_ns, latency_ns ); + } + else +#endif { IF( hIvasRend->inputsSba[i].crendWrapper != NULL ) { @@ -3886,6 +4512,9 @@ ivas_error IVAS_REND_FeedInputAudio_fx( ivas_error error; input_base *inputBase; Word16 numInputChannels; +#ifdef SPLIT_REND_WITH_HEAD_ROT + Word16 cldfb2tdShift; +#endif /* Validate function arguments */ test(); @@ -3895,7 +4524,14 @@ ivas_error IVAS_REND_FeedInputAudio_fx( } test(); +#ifdef SPLIT_REND_WITH_HEAD_ROT + cldfb2tdShift = ( inputAudio.config.is_cldfb ) ? 1 : 0; + + IF( inputAudio.config.numSamplesPerChannel <= 0 || ( MAX_BUFFER_LENGTH_PER_CHANNEL < inputAudio.config.numSamplesPerChannel && inputAudio.config.is_cldfb == 0 ) || + ( ( shl( MAX_BUFFER_LENGTH_PER_CHANNEL, cldfb2tdShift ) ) < inputAudio.config.numSamplesPerChannel && inputAudio.config.is_cldfb == 1 ) ) +#else IF( inputAudio.config.numSamplesPerChannel <= 0 || LT_16( MAX_BUFFER_LENGTH_PER_CHANNEL, inputAudio.config.numSamplesPerChannel ) ) +#endif { return IVAS_ERROR( IVAS_ERR_INVALID_BUFFER_SIZE, "Buffer size outside of supported range" ); } @@ -3908,8 +4544,15 @@ ivas_error IVAS_REND_FeedInputAudio_fx( test(); move32(); // move added for typecasting +#ifdef SPLIT_REND_WITH_HEAD_ROT + IF( EQ_32( getAudioConfigType( hIvasRend->outputConfig ), IVAS_REND_AUDIO_CONFIG_TYPE_BINAURAL ) && + NE_32( hIvasRend->outputConfig, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) && + NE_32( hIvasRend->outputConfig, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) && + NE_32( L_shr( L_mult0( inputAudio.config.numSamplesPerChannel, 1000 ), cldfb2tdShift ), (Word32) W_mult0_32_32( L_mult0( BINAURAL_RENDERING_FRAME_SIZE_MS, hIvasRend->num_subframes ), hIvasRend->sampleRateOut ) ) ) +#else IF( EQ_32( getAudioConfigType( hIvasRend->outputConfig ), IVAS_REND_AUDIO_CONFIG_TYPE_BINAURAL ) && NE_32( L_mult0( inputAudio.config.numSamplesPerChannel, 1000 ), (Word32) W_mult0_32_32( L_mult0( BINAURAL_RENDERING_FRAME_SIZE_MS, hIvasRend->num_subframes ), hIvasRend->sampleRateOut ) ) ) +#endif { return IVAS_ERROR( IVAS_ERR_INVALID_BUFFER_SIZE, "Binaural rendering requires specific frame size" ); } @@ -3940,7 +4583,11 @@ ivas_error IVAS_REND_FeedInputAudio_fx( MVR2R_WORD32( inputAudio.data_fx, inputBase->inputBuffer.data_fx, inputAudio.config.numSamplesPerChannel * inputAudio.config.numChannels ); +#ifdef SPLIT_REND_WITH_HEAD_ROT + inputBase->numNewSamplesPerChannel = shr( inputAudio.config.numSamplesPerChannel, cldfb2tdShift ); +#else inputBase->numNewSamplesPerChannel = inputAudio.config.numSamplesPerChannel; +#endif move32(); return IVAS_ERR_OK; @@ -4136,6 +4783,23 @@ Word16 IVAS_REND_GetRenderConfig( Copy32( hRCin->roomAcoustics.pAcoustic_rt60_fx, hRCout->roomAcoustics.pAcoustic_rt60_fx, CLDFB_NO_CHANNELS_MAX ); Copy32( hRCin->roomAcoustics.pAcoustic_dsr_fx, hRCout->roomAcoustics.pAcoustic_dsr_fx, CLDFB_NO_CHANNELS_MAX ); +#ifdef SPLIT_REND_WITH_HEAD_ROT + hRCout->split_rend_config.splitRendBitRate = SPLIT_REND_768k; + hRCout->split_rend_config.dof = 3; + hRCout->split_rend_config.hq_mode = 0; + hRCout->split_rend_config.codec_delay_ms = 0; +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + hRCout->split_rend_config.isar_frame_size_ms = 20; +#endif + hRCout->split_rend_config.codec_frame_size_ms = 0; /* 0 means "use default for selected codec" */ + hRCout->split_rend_config.codec = ISAR_SPLIT_REND_CODEC_DEFAULT; + hRCout->split_rend_config.poseCorrectionMode = ISAR_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB; + hRCout->split_rend_config.rendererSelection = hRCin->split_rend_config.rendererSelection; +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + hRCout->split_rend_config.lc3plus_highres = 0; +#endif +#endif + hRCout->roomAcoustics.use_er = hRCin->roomAcoustics.use_er; hRCout->roomAcoustics.lowComplexity = hRCin->roomAcoustics.lowComplexity; @@ -4158,6 +4822,9 @@ Word16 IVAS_REND_FeedRenderConfig( ) { RENDER_CONFIG_HANDLE hRenderConfig; +#ifdef SPLIT_REND_WITH_HEAD_ROT + ivas_error error; +#endif test(); IF( hIvasRend == NULL || hIvasRend->hRendererConfig == NULL ) @@ -4193,6 +4860,35 @@ Word16 IVAS_REND_FeedRenderConfig( Copy32( renderConfig.roomAcoustics.AbsCoeff_fx, hRenderConfig->roomAcoustics.AbsCoeff_fx, IVAS_ROOM_ABS_COEFF ); } +#ifdef SPLIT_REND_WITH_HEAD_ROT + hRenderConfig->split_rend_config = renderConfig.split_rend_config; + /* Overwrite any pose correction settings if 0 DOF (no pose correction) was selected */ + IF( EQ_16( hRenderConfig->split_rend_config.dof, 0 ) ) + { + hRenderConfig->split_rend_config.poseCorrectionMode = ISAR_SPLIT_REND_POSE_CORRECTION_MODE_NONE; + } + + hRenderConfig->split_rend_config.codec = renderConfig.split_rend_config.codec; + + IF( ( error = isar_split_rend_validate_config( &hRenderConfig->split_rend_config, ( hIvasRend->outputConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ? 1 : 0 ) ) != IVAS_ERR_OK ) + { + return error; + } + + /* Must re-initialize split rendering config in case renderer config is updated after adding renderer inputs */ + /* if its not initialized yet then no need to re-initialize, initialization will happen while adding inputs*/ + IF( hIvasRend->splitRendEncBuffer.data_fx != NULL && hIvasRend->hRendererConfig != NULL ) + { + int16_t cldfb_in_flag; + cldfb_in_flag = getCldfbRendFlag( hIvasRend, IVAS_REND_AUDIO_CONFIG_TYPE_UNKNOWN ); + ISAR_PRE_REND_close( &hIvasRend->splitRendWrapper, &hIvasRend->splitRendEncBuffer ); + + IF( ( error = ivas_pre_rend_init( &hIvasRend->splitRendWrapper, &hIvasRend->splitRendEncBuffer, &hIvasRend->hRendererConfig->split_rend_config, hIvasRend->headRotData, hIvasRend->sampleRateOut, hIvasRend->outputConfig, cldfb_in_flag, hIvasRend->num_subframes ) ) != IVAS_ERR_OK ) + { + return error; + } + } +#endif return IVAS_ERR_OK; } @@ -4206,7 +4902,10 @@ ivas_error IVAS_REND_SetHeadRotation( IVAS_REND_HANDLE hIvasRend, /* i/o: Renderer handle */ const IVAS_QUATERNION headRot, /* i : head orientations for next rendering call */ const IVAS_VECTOR3 Pos, /* i : listener positions for next rendering call */ - const Word16 sf_idx /* i : subframe index */ +#ifdef SPLIT_REND_WITH_HEAD_ROT + const ISAR_SPLIT_REND_ROT_AXIS rot_axis, /* i : external control for rotation axis for split rendering */ +#endif + const Word16 sf_idx /* i : subframe index */ ) { Word16 i; @@ -4240,11 +4939,20 @@ ivas_error IVAS_REND_SetHeadRotation( } } +#ifdef SPLIT_REND_WITH_HEAD_ROT + /* check for Euler angle signaling */ + IF( EQ_32( headRot.w_fx, L_negate( 12582912 ) ) && EQ_16( headRot.q_fact, Q22 ) ) + { + Euler2Quat_fx( deg2rad_fx( headRot.x_fx ), deg2rad_fx( headRot.y_fx ), deg2rad_fx( headRot.z_fx ), &rotQuat ); + modify_Quat_q_fx( &rotQuat, &rotQuat, Q29 ); + } +#else /* check for Euler angle signaling */ IF( EQ_32( headRot.w_fx, -1610612736 /* -3.0f in Q29 */ ) ) { Euler2Quat_fx( deg2rad_fx( headRot.x_fx ), deg2rad_fx( headRot.y_fx ), deg2rad_fx( headRot.z_fx ), &rotQuat ); } +#endif ELSE { rotQuat = headRot; @@ -4291,6 +4999,10 @@ ivas_error IVAS_REND_SetHeadRotation( return error; } +#ifdef SPLIT_REND_WITH_HEAD_ROT + hIvasRend->headRotData.sr_pose_pred_axis = rot_axis; +#endif + hIvasRend->headRotData.Pos[sf_idx] = Pos; return IVAS_ERR_OK; @@ -4336,6 +5048,25 @@ ivas_error IVAS_REND_DisableHeadRotation( return IVAS_ERR_OK; } +#ifdef SPLIT_REND_WITH_HEAD_ROT +/*-------------------------------------------------------------------* + * IVAS_REND_SetSplitRendBFI() + * + * + *-------------------------------------------------------------------*/ + +ivas_error +IVAS_REND_SetSplitRendBFI( + IVAS_REND_HANDLE hIvasRend, + const int16_t bfi ) +{ + hIvasRend->splitRendBFI = bfi; + + return IVAS_ERR_OK; +} +#endif + + /*-------------------------------------------------------------------* * IVAS_REND_SetOrientationTrackingMode() * @@ -4539,7 +5270,7 @@ static void renderBufferChannelLerp_fx( /* Process current output channel only if applying non-zero gains */ test(); test(); - IF( GT_32( abs( currentGain ), EPSILON_FX ) || ( gainsPrev != NULL && GT_32( abs( previousGain ), EPSILON_FX ) ) ) + IF( GT_32( L_abs( currentGain ), EPSILON_FX ) || ( gainsPrev != NULL && GT_32( L_abs( previousGain ), EPSILON_FX ) ) ) { /* Reset input pointer to the beginning of input channel */ inSmpl = getSmplPtr_fx( inAudio, inChannelIdx, 0 ); @@ -4548,7 +5279,7 @@ static void renderBufferChannelLerp_fx( outSmpl = getSmplPtr_fx( outAudio, outChnlIdx, 0 ); test(); - IF( gainsPrev == NULL || LE_32( abs( L_sub( L_shr( previousGain, 1 ), L_shr( currentGain, 1 ) ) ), EPSILON_FX ) ) + IF( gainsPrev == NULL || LE_32( L_abs( L_sub( L_shr( previousGain, 1 ), L_shr( currentGain, 1 ) ) ), EPSILON_FX ) ) { /* If no interpolation from previous frame, apply current gain */ DO @@ -4564,40 +5295,58 @@ static void renderBufferChannelLerp_fx( { i = 0; Word32 tmp = Q31_BY_SUB_FRAME_240; + Word32 tmp1 = 239; /* L_SUBFRAME_48k - 1 */ + move32(); move32(); move32(); SWITCH( outAudio.config.numSamplesPerChannel ) { case NUM_SAMPLES_960: tmp = Q31_BY_NUM_SAMPLES_960; + tmp1 = 959; /* NUM_SAMPLES_960 - 1 */ + move32(); move32(); BREAK; case NUM_SAMPLES_720: tmp = Q31_BY_NUM_SAMPLES_720; + tmp1 = 719; /* NUM_SAMPLES_720 - 1 */ + move32(); move32(); BREAK; case NUM_SAMPLES_320: tmp = Q31_BY_NUM_SAMPLES_320; + tmp1 = 319; /* NUM_SAMPLES_320 - 1 */ + move32(); move32(); BREAK; case NUM_SAMPLES_160: tmp = Q31_BY_NUM_SAMPLES_160; + tmp1 = 159; /* NUM_SAMPLES_160 - 1 */ + move32(); move32(); BREAK; case L_SUBFRAME_48k: tmp = Q31_BY_SUB_FRAME_240; + tmp1 = 239; /* L_SUBFRAME_48k - 1 */ + move32(); move32(); BREAK; case L_SUBFRAME_32k: tmp = Q31_BY_SUB_FRAME_180; + tmp1 = 179; /* L_SUBFRAME_32k - 1 */ + move32(); move32(); BREAK; case L_SUBFRAME_16k: tmp = Q31_BY_SUB_FRAME_80; + tmp1 = 79; /* L_SUBFRAME_16k - 1 */ + move32(); move32(); BREAK; case L_SUBFRAME_8k: tmp = Q31_BY_SUB_FRAME_40; + tmp1 = 39; /* L_SUBFRAME_8k - 1 */ + move32(); move32(); BREAK; default: @@ -4606,7 +5355,15 @@ static void renderBufferChannelLerp_fx( /* Otherwise use weighted average between previous and current gain */ DO { - fadeIn = UL_Mpy_32_32( i, tmp ); + IF( EQ_32( i, tmp1 ) ) + { + fadeIn = ONE_IN_Q31; + move32(); + } + ELSE + { + fadeIn = UL_Mpy_32_32( i, tmp ); + } fadeOut = L_sub( ONE_IN_Q31, fadeIn ); *outSmpl = L_add( Mpy_32_32( L_add( Mpy_32_32( fadeIn, currentGain ), Mpy_32_32( fadeOut, previousGain ) ), ( *inSmpl ) ), *outSmpl ); @@ -5013,9 +5770,20 @@ static Word16 getNumSubframesInBuffer( const IVAS_REND_AudioBuffer *buffer, const Word32 sampleRate ) { +#ifdef SPLIT_REND_WITH_HEAD_ROT + Word16 cldfb2tdShift; + + cldfb2tdShift = buffer->config.is_cldfb ? 1 : 0; + + Word16 scale, temp = extract_l( Mpy_32_32( sampleRate, 10737418 /* 1 / FRAMES_PER_SEC * MAX_PARAM_SPATIAL_SUBFRAMES in Q31 */ ) ); + temp = BASOP_Util_Divide1616_Scale( buffer->config.numSamplesPerChannel, temp, &scale ); + temp = shr( temp, sub( 15, scale ) ); /* Q0 */ + temp = shr( temp, cldfb2tdShift ); +#else Word16 scale, temp = extract_l( Mpy_32_32( sampleRate, 10737418 /* 1 / FRAMES_PER_SEC * MAX_PARAM_SPATIAL_SUBFRAMES in Q31 */ ) ); temp = BASOP_Util_Divide1616_Scale( buffer->config.numSamplesPerChannel, temp, &scale ); temp = shr( temp, sub( 15, scale ) ); /* Q0 */ +#endif return temp; } @@ -5192,7 +5960,11 @@ static ivas_error renderIsmToBinauralRoom( } // Crend_process porting CREND_HANDLE hCrend; +#ifdef SPLIT_REND_WITH_HEAD_ROT + hCrend = ismInput->crendWrapper->hCrend[0]; +#else hCrend = ismInput->crendWrapper->hCrend; +#endif IF( hCrend->reflections != NULL ) { test(); @@ -5208,12 +5980,19 @@ static ivas_error renderIsmToBinauralRoom( move16(); +#ifdef SPLIT_REND_WITH_HEAD_ROT + /* render 7_1_4 with BRIRs */ + IF( NE_32( ( error = ivas_rend_crendProcess( ismInput->crendWrapper, IVAS_AUDIO_CONFIG_7_1_4, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR, + NULL, NULL, NULL, NULL, p_tmpRendBuffer, *ismInput->base.ctx.pOutSampleRate, + getNumSubframesInBuffer( &outAudio, *ismInput->base.ctx.pOutSampleRate ), 0 ) ), + IVAS_ERR_OK ) ) +#else /* render 7_1_4 with BRIRs */ IF( NE_32( ( error = ivas_rend_crendProcess( ismInput->crendWrapper, IVAS_AUDIO_CONFIG_7_1_4, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR, NULL, NULL, NULL, NULL, p_tmpRendBuffer, *ismInput->base.ctx.pOutSampleRate, getNumSubframesInBuffer( &outAudio, *ismInput->base.ctx.pOutSampleRate ) ) ), IVAS_ERR_OK ) ) - +#endif { return error; } @@ -5501,6 +6280,132 @@ static ivas_error renderIsmToSba( return error; } +#ifdef SPLIT_REND_WITH_HEAD_ROT +static ivas_error renderIsmToSplitBinaural( + input_ism *ismInput, + const IVAS_REND_AudioBuffer outAudio ) +{ + ivas_error error; + Word32 tmpProcessing[MAX_NUM_OBJECTS][L_FRAME48k]; + Word16 pos_idx; + const MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData; + const SPLIT_REND_WRAPPER *pSplitRendWrapper; + IVAS_QUATERNION originalHeadRot[MAX_PARAM_SPATIAL_SUBFRAMES]; + IVAS_QUATERNION localHeadRot[MAX_PARAM_SPATIAL_SUBFRAMES]; + Word16 i; + Word32 tmpBinaural[MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS][L_FRAME48k]; + Word16 output_frame = ismInput->base.inputBuffer.config.numSamplesPerChannel; + COMBINED_ORIENTATION_HANDLE pCombinedOrientationData; + Word16 ism_md_subframe_update_ext, exp; + + push_wmops( "renderIsmToSplitBinaural" ); + + pSplitRendWrapper = ismInput->base.ctx.pSplitRendWrapper; + pMultiBinPoseData = &pSplitRendWrapper->multiBinPoseData; + + exp = *outAudio.pq_fact; + /* Metadata Delay to sync with audio delay converted from ms to 5ms (1000/50/4) subframe index */ + ism_md_subframe_update_ext = (Word16) Mpy_32_32( ismInput->ism_metadata_delay_ms_fx, ONE_BY_SUBFRAME_LEN_MS_Q31 ); + + pCombinedOrientationData = *ismInput->base.ctx.pCombinedOrientationData; + + IF( EQ_32( pMultiBinPoseData->poseCorrectionMode, ISAR_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB ) ) + { + FOR( i = 1; i < pCombinedOrientationData->num_subframes; ++i ) + { + Copy_Quat_fx( &pCombinedOrientationData->Quaternions[0], &pCombinedOrientationData->Quaternions[i] ); + } + } + + /* Save current head positions */ + FOR( i = 0; i < pCombinedOrientationData->num_subframes; ++i ) + { + Copy_Quat_fx( &pCombinedOrientationData->Quaternions[i], &originalHeadRot[i] ); + } + + /* Copy input audio to a processing buffer. */ + copyBufferTo2dArray_fx( ismInput->base.inputBuffer, tmpProcessing ); + + + FOR( pos_idx = 0; pos_idx < pMultiBinPoseData->num_poses; pos_idx++ ) + { + /* Update head positions */ + IF( NE_16( pos_idx, 0 ) ) + { + Word16 q_fact_orig; + FOR( i = 0; i < pCombinedOrientationData->num_subframes; ++i ) + { + pCombinedOrientationData->Quaternions[i].w_fx = L_negate( 12582912 ); // Q22 + q_fact_orig = originalHeadRot[i].q_fact; + modify_Quat_q_fx( &originalHeadRot[i], &localHeadRot[i], Q22 ); + /*euler*/ + Quat2EulerDegree_fx( localHeadRot[i], + &pCombinedOrientationData->Quaternions[i].z_fx, + &pCombinedOrientationData->Quaternions[i].y_fx, + &pCombinedOrientationData->Quaternions[i].x_fx ); + pCombinedOrientationData->Quaternions[i].x_fx = L_add( pCombinedOrientationData->Quaternions[i].x_fx, pMultiBinPoseData->relative_head_poses_fx[pos_idx][0] ); + pCombinedOrientationData->Quaternions[i].y_fx = L_add( pCombinedOrientationData->Quaternions[i].y_fx, pMultiBinPoseData->relative_head_poses_fx[pos_idx][1] ); + pCombinedOrientationData->Quaternions[i].z_fx = L_add( pCombinedOrientationData->Quaternions[i].z_fx, pMultiBinPoseData->relative_head_poses_fx[pos_idx][2] ); + + Euler2Quat_fx( deg2rad_fx( pCombinedOrientationData->Quaternions[i].x_fx ), + deg2rad_fx( pCombinedOrientationData->Quaternions[i].y_fx ), + deg2rad_fx( pCombinedOrientationData->Quaternions[i].z_fx ), &pCombinedOrientationData->Quaternions[i] ); + + modify_Quat_q_fx( &pCombinedOrientationData->Quaternions[i], &pCombinedOrientationData->Quaternions[i], q_fact_orig ); + } + } + + + FOR( i = 0; i < MAX_NUM_OBJECTS; ++i ) + { + Scale_sig32( tmpProcessing[i], L_FRAME48k, sub( Q11, exp ) ); /* Q11 */ + } + /* Render */ + IF( ( error = ivas_td_binaural_renderer_ext_fx( ( pos_idx == 0 ) ? &ismInput->tdRendWrapper : &ismInput->splitTdRendWrappers[sub( pos_idx, 1 )], ismInput->base.inConfig, NULL, ismInput->base.ctx.pCombinedOrientationData, &ismInput->currentPos, + NULL, ism_md_subframe_update_ext, *ismInput->base.ctx.pOutSampleRate, output_frame, tmpProcessing, &exp ) ) != IVAS_ERR_OK ) + { + return error; + } + FOR( i = 0; i < BINAURAL_CHANNELS; ++i ) + { + Scale_sig32( tmpProcessing[i], L_FRAME48k, negate( sub( Q11, exp ) ) ); /* Q(exp) */ + } + + IF( ismInput->hReverb != NULL ) + { + FOR( i = 0; i < BINAURAL_CHANNELS; i++ ) + { + FOR( Word16 j = 0; j < outAudio.config.numSamplesPerChannel; j++ ) + { + tmpProcessing[i][j] = L_shl( tmpProcessing[i][j], Q2 ); /* Q(exp + 2) */ + move32(); + } + } + } + /* Copy rendered audio to tmp storage buffer. Copying directly to output would + * overwrite original audio, which is still needed for rendering next head pose. */ + Copy32( tmpProcessing[0], tmpBinaural[i_mult( 2, pos_idx )], output_frame ); + Copy32( tmpProcessing[1], tmpBinaural[add( i_mult( 2, pos_idx ), 1 )], output_frame ); + + /* Overwrite processing buffer with original input audio again */ + copyBufferTo2dArray_fx( ismInput->base.inputBuffer, tmpProcessing ); + } + + /* Restore original head rotation */ + FOR( i = 0; i < pCombinedOrientationData->num_subframes; ++i ) + { + Copy_Quat_fx( &originalHeadRot[i], &pCombinedOrientationData->Quaternions[i] ); + } + + accumulate2dArrayToBuffer_fx( tmpBinaural, &outAudio ); + pop_wmops(); + + /* Encoding to split rendering bitstream done at a higher level */ + return IVAS_ERR_OK; +} +#endif + + static void renderIsmToMasa( input_ism *ismInput, IVAS_REND_AudioBuffer outAudio, @@ -5612,6 +6517,12 @@ static ivas_error renderInputIsm( case IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR: error = renderIsmToBinauralRoom( ismInput, outAudio, &exp ); BREAK; +#ifdef SPLIT_REND_WITH_HEAD_ROT + case IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED: + case IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM: + error = renderIsmToSplitBinaural( ismInput, outAudio ); + break; +#endif case IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB: error = renderIsmToBinauralReverb( ismInput, outAudio ); BREAK; @@ -5679,13 +6590,20 @@ static ivas_error renderActiveInputsIsm( } return IVAS_ERR_OK; } + static ivas_error renderLfeToBinaural_fx( const input_mc *mcInput, +#ifdef SPLIT_REND_WITH_HEAD_ROT + const AUDIO_CONFIG outConfig, +#endif IVAS_REND_AudioBuffer outAudio, Word16 in_q, Word16 out_q ) { Word16 lfe_idx; +#ifdef SPLIT_REND_WITH_HEAD_ROT + Word16 pose_idx, num_poses; +#endif Word32 gain_fx; Word16 ear_idx, i, r_shift; Word32 tmpLfeBuffer[MAX_BUFFER_LENGTH_PER_CHANNEL]; @@ -5693,7 +6611,11 @@ static ivas_error renderLfeToBinaural_fx( const Word32 *lfeInput; Word32 *writePtr; +#ifdef SPLIT_REND_WITH_HEAD_ROT + assert( ( getAudioConfigType( outConfig ) == IVAS_REND_AUDIO_CONFIG_TYPE_BINAURAL ) && "Must be binaural output" ); +#else assert( ( outAudio.config.numChannels == 2 ) && "Must be binaural output" ); +#endif push_wmops( "renderLfeToBinaural" ); gain_fx = GAIN_LFE_WORD32; /* 1.88364911f in Q30 */ @@ -5744,6 +6666,29 @@ static ivas_error renderLfeToBinaural_fx( move32(); } } + +#ifdef SPLIT_REND_WITH_HEAD_ROT + /* Copy LFE to left and right binaural channels for all poses */ + IF( mcInput->base.ctx.pSplitRendWrapper != NULL ) + { + num_poses = mcInput->base.ctx.pSplitRendWrapper->multiBinPoseData.num_poses; + move16(); + } + ELSE + { + num_poses = 1; + move16(); + } + + FOR( pose_idx = 0; pose_idx < num_poses; ++pose_idx ) + { + FOR( ear_idx = 0; ear_idx < BINAURAL_CHANNELS; ++ear_idx ) + { + writePtr = getSmplPtr_fx( outAudio, add( i_mult( pose_idx, BINAURAL_CHANNELS ), ear_idx ), 0 ); + v_add_fixed( writePtr, tmpLfeBuffer, writePtr, frame_size, 0 ); /* Q(out_q) */ + } + } +#else /* SPLIT_REND_WITH_HEAD_ROT */ /* Copy LFE to left and right ears */ FOR( ear_idx = 0; ear_idx < BINAURAL_CHANNELS; ++ear_idx ) { @@ -5751,6 +6696,7 @@ static ivas_error renderLfeToBinaural_fx( move32(); v_add_fixed( writePtr, tmpLfeBuffer, writePtr, frame_size, 0 ); /* Q(out_q) */ } +#endif pop_wmops(); @@ -5827,7 +6773,11 @@ static ivas_error renderMcToBinaural( tmpRotBuffer.data_fx = malloc( tmpRotBuffer.config.numSamplesPerChannel * tmpRotBuffer.config.numChannels * sizeof( Word32 ) ); set32_fx( tmpRotBuffer.data_fx, 0, imult1616( tmpRotBuffer.config.numSamplesPerChannel, tmpRotBuffer.config.numChannels ) ); +#ifdef SPLIT_REND_WITH_HEAD_ROT + IF( NE_32( ( error = rotateFrameMc_fx( mcInput->base.inputBuffer, mcInput->base.inConfig, &mcInput->customLsInput, mcInput->base.ctx.pHeadRotData, mcInput->base.ctx.pCombinedOrientationData, mcInput->rot_gains_prev_fx[0], mcInput->efapInWrapper.hEfap, tmpRotBuffer ) ), IVAS_ERR_OK ) ) +#else IF( NE_32( ( error = rotateFrameMc_fx( mcInput->base.inputBuffer, mcInput->base.inConfig, &mcInput->customLsInput, mcInput->base.ctx.pHeadRotData, mcInput->base.ctx.pCombinedOrientationData, mcInput->rot_gains_prev_fx, mcInput->efapInWrapper.hEfap, tmpRotBuffer ) ), IVAS_ERR_OK ) ) +#endif { return error; } @@ -5844,12 +6794,22 @@ static ivas_error renderMcToBinaural( } // Porting Crend_process function CREND_HANDLE hCrend; +#ifdef SPLIT_REND_WITH_HEAD_ROT + hCrend = mcInput->crendWrapper->hCrend[0]; +#else hCrend = mcInput->crendWrapper->hCrend; +#endif /* call CREND */ +#ifdef SPLIT_REND_WITH_HEAD_ROT + IF( NE_32( ( error = ivas_rend_crendProcess( mcInput->crendWrapper, mcInput->base.inConfig, outConfig, NULL, NULL, NULL, NULL, p_tmpRendBuffer_fx, *mcInput->base.ctx.pOutSampleRate, + getNumSubframesInBuffer( &outAudio, *mcInput->base.ctx.pOutSampleRate ), 0 ) ), + IVAS_ERR_OK ) ) +#else IF( NE_32( ( error = ivas_rend_crendProcess( mcInput->crendWrapper, mcInput->base.inConfig, outConfig, NULL, NULL, NULL, NULL, p_tmpRendBuffer_fx, *mcInput->base.ctx.pOutSampleRate, getNumSubframesInBuffer( &outAudio, *mcInput->base.ctx.pOutSampleRate ) ) ), IVAS_ERR_OK ) ) +#endif { return error; } @@ -5861,11 +6821,19 @@ static ivas_error renderMcToBinaural( accumulate2dArrayToBuffer_fx( tmpRendBuffer_fx, &outAudio ); +#ifdef SPLIT_REND_WITH_HEAD_ROT + IF( NE_32( ( error = renderLfeToBinaural_fx( mcInput, outConfig, outAudio, *outAudio.pq_fact, exp ) ), IVAS_ERR_OK ) ) + + { + return error; + } +#else IF( NE_32( ( error = renderLfeToBinaural_fx( mcInput, outAudio, *outAudio.pq_fact, exp ) ), IVAS_ERR_OK ) ) { return error; } +#endif *outAudio.pq_fact = exp; move16(); pop_wmops(); @@ -5946,10 +6914,17 @@ static ivas_error renderMcToBinauralRoom( tmpRotBuffer.data_fx = malloc( tmpRotBuffer.config.numSamplesPerChannel * tmpRotBuffer.config.numChannels * sizeof( Word32 ) ); set32_fx( tmpRotBuffer.data_fx, 0, tmpRotBuffer.config.numSamplesPerChannel * tmpRotBuffer.config.numChannels ); +#ifdef SPLIT_REND_WITH_HEAD_ROT + IF( NE_32( ( error = rotateFrameMc_fx( mcInput->base.inputBuffer, mcInput->base.inConfig, &mcInput->customLsInput, mcInput->base.ctx.pHeadRotData, mcInput->base.ctx.pCombinedOrientationData, + mcInput->rot_gains_prev_fx[0], + mcInput->efapInWrapper.hEfap, tmpRotBuffer ) ), + IVAS_ERR_OK ) ) +#else IF( NE_32( ( error = rotateFrameMc_fx( mcInput->base.inputBuffer, mcInput->base.inConfig, &mcInput->customLsInput, mcInput->base.ctx.pHeadRotData, mcInput->base.ctx.pCombinedOrientationData, mcInput->rot_gains_prev_fx, mcInput->efapInWrapper.hEfap, tmpRotBuffer ) ), IVAS_ERR_OK ) ) +#endif { return error; } @@ -5965,12 +6940,22 @@ static ivas_error renderMcToBinauralRoom( } // Porting Crend_process function CREND_HANDLE hCrend; +#ifdef SPLIT_REND_WITH_HEAD_ROT + hCrend = mcInput->crendWrapper->hCrend[0]; +#else hCrend = mcInput->crendWrapper->hCrend; +#endif /* call CREND */ +#ifdef SPLIT_REND_WITH_HEAD_ROT + IF( NE_32( ( error = ivas_rend_crendProcess( mcInput->crendWrapper, mcInput->base.inConfig, outConfig, NULL, NULL, NULL, NULL, p_tmpRendBuffer, *mcInput->base.ctx.pOutSampleRate, + getNumSubframesInBuffer( &outAudio, *mcInput->base.ctx.pOutSampleRate ), 0 ) ), + IVAS_ERR_OK ) ) +#else IF( NE_32( ( error = ivas_rend_crendProcess( mcInput->crendWrapper, mcInput->base.inConfig, outConfig, NULL, NULL, NULL, NULL, p_tmpRendBuffer, *mcInput->base.ctx.pOutSampleRate, getNumSubframesInBuffer( &outAudio, *mcInput->base.ctx.pOutSampleRate ) ) ), IVAS_ERR_OK ) ) +#endif { return error; } @@ -5982,7 +6967,11 @@ static ivas_error renderMcToBinauralRoom( accumulate2dArrayToBuffer_fx( tmpRendBuffer, &outAudio ); +#ifdef SPLIT_REND_WITH_HEAD_ROT + IF( NE_32( ( error = renderLfeToBinaural_fx( mcInput, outConfig, outAudio, *outAudio.pq_fact, exp ) ), IVAS_ERR_OK ) ) +#else IF( NE_32( ( error = renderLfeToBinaural_fx( mcInput, outAudio, *outAudio.pq_fact, exp ) ), IVAS_ERR_OK ) ) +#endif { return error; } @@ -6040,10 +7029,17 @@ static ivas_error renderMcCustomLsToBinauralRoom( tmpRotBuffer.data_fx = malloc( tmpRotBuffer.config.numSamplesPerChannel * tmpRotBuffer.config.numChannels * sizeof( Word32 ) ); set32_fx( tmpRotBuffer.data_fx, 0, tmpRotBuffer.config.numSamplesPerChannel * tmpRotBuffer.config.numChannels ); +#ifdef SPLIT_REND_WITH_HEAD_ROT + IF( NE_32( ( error = rotateFrameMc_fx( mcInput->base.inputBuffer, mcInput->base.inConfig, &mcInput->customLsInput, mcInput->base.ctx.pHeadRotData, mcInput->base.ctx.pCombinedOrientationData, + mcInput->rot_gains_prev_fx[0], + mcInput->efapInWrapper.hEfap, tmpRotBuffer ) ), + IVAS_ERR_OK ) ) +#else IF( NE_32( ( error = rotateFrameMc_fx( mcInput->base.inputBuffer, mcInput->base.inConfig, &mcInput->customLsInput, mcInput->base.ctx.pHeadRotData, mcInput->base.ctx.pCombinedOrientationData, mcInput->rot_gains_prev_fx, mcInput->efapInWrapper.hEfap, tmpRotBuffer ) ), IVAS_ERR_OK ) ) +#endif { return error; } @@ -6078,11 +7074,21 @@ static ivas_error renderMcCustomLsToBinauralRoom( copyBufferTo2dArray_fx( tmpMcBuffer, tmpCrendBuffer ); CREND_HANDLE hCrend; +#ifdef SPLIT_REND_WITH_HEAD_ROT + hCrend = mcInput->crendWrapper->hCrend[0]; +#else hCrend = mcInput->crendWrapper->hCrend; +#endif /* call CREND */ +#ifdef SPLIT_REND_WITH_HEAD_ROT + IF( NE_32( ( error = ivas_rend_crendProcess( mcInput->crendWrapper, IVAS_AUDIO_CONFIG_7_1_4, outConfig, NULL, NULL, NULL, NULL, + p_tmpCrendBuffer, *mcInput->base.ctx.pOutSampleRate, getNumSubframesInBuffer( &outAudio, *mcInput->base.ctx.pOutSampleRate ), 0 ) ), + IVAS_ERR_OK ) ) +#else IF( NE_32( ( error = ivas_rend_crendProcess( mcInput->crendWrapper, IVAS_AUDIO_CONFIG_7_1_4, outConfig, NULL, NULL, NULL, NULL, p_tmpCrendBuffer, *mcInput->base.ctx.pOutSampleRate, getNumSubframesInBuffer( &outAudio, *mcInput->base.ctx.pOutSampleRate ) ) ), IVAS_ERR_OK ) ) +#endif { return error; } @@ -6093,7 +7099,11 @@ static ivas_error renderMcCustomLsToBinauralRoom( accumulate2dArrayToBuffer_fx( tmpCrendBuffer, &outAudio ); +#ifdef SPLIT_REND_WITH_HEAD_ROT + IF( NE_32( ( error = renderLfeToBinaural_fx( mcInput, outConfig, outAudio, *outAudio.pq_fact, exp ) ), IVAS_ERR_OK ) ) +#else IF( NE_32( ( error = renderLfeToBinaural_fx( mcInput, outAudio, *outAudio.pq_fact, exp ) ), IVAS_ERR_OK ) ) +#endif { return error; } @@ -6158,6 +7168,221 @@ static void renderMcToMasa( return; } +#ifdef SPLIT_REND_WITH_HEAD_ROT +static ivas_error renderMcToSplitBinaural( + input_mc *mcInput, + const AUDIO_CONFIG outConfig, + IVAS_REND_AudioBuffer outAudio ) +{ + Word16 i, j, pos_idx; + Word16 sf; + Word16 output_frame; + ivas_error error; + const MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData; + const SPLIT_REND_WRAPPER *pSplitRendWrapper; + Word32 tmpRendBuffer[MAX_OUTPUT_CHANNELS][L_FRAME48k]; + Word32 *p_tmpRendBuffer[MAX_OUTPUT_CHANNELS]; + Word32 tmpSplitBinauralBuffer[MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS][L_FRAME48k]; + AUDIO_CONFIG inConfig; + IVAS_REND_AudioBuffer tmpRotBuffer; + COMBINED_ORIENTATION_DATA combinedOrientationDataLocal; + COMBINED_ORIENTATION_HANDLE pCombinedOrientationDataLocal; + Word16 exp = *outAudio.pq_fact; + move16(); + CREND_HANDLE hCrend; + IVAS_QUATERNION Quaternions_orig[MAX_PARAM_SPATIAL_SUBFRAMES], Quaternions_abs; + Word16 q_fact_orig; + + push_wmops( "renderMcToSplitBinaural" ); + inConfig = mcInput->base.inConfig; + move32(); + output_frame = mcInput->base.inputBuffer.config.numSamplesPerChannel; + move16(); + + pSplitRendWrapper = mcInput->base.ctx.pSplitRendWrapper; + pMultiBinPoseData = &pSplitRendWrapper->multiBinPoseData; + move32(); + move32(); + + FOR( i = 0; i < MAX_OUTPUT_CHANNELS; ++i ) + { + p_tmpRendBuffer[i] = tmpRendBuffer[i]; + move32(); + } + + /* save current head positions */ + pCombinedOrientationDataLocal = *mcInput->base.ctx.pCombinedOrientationData; + move32(); + combinedOrientationDataLocal = *pCombinedOrientationDataLocal; + move32(); + IF( EQ_32( pMultiBinPoseData->poseCorrectionMode, ISAR_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB ) ) + { + FOR( sf = 1; sf < combinedOrientationDataLocal.num_subframes; ++sf ) + { + Copy_Quat_fx( &combinedOrientationDataLocal.Quaternions[0], &combinedOrientationDataLocal.Quaternions[sf] ); + FOR( i = 0; i < 3; i++ ) + { + FOR( j = 0; j < 3; j++ ) + { + combinedOrientationDataLocal.Rmat_fx[sf][i][j] = combinedOrientationDataLocal.Rmat_fx[0][i][j]; + move32(); + } + } + } + } + + /* temporary buffer for rotation in source format for CREND */ + tmpRotBuffer = mcInput->base.inputBuffer; + move32(); + IF( NE_32( inConfig, IVAS_AUDIO_CONFIG_LS_CUSTOM ) && NE_32( inConfig, IVAS_AUDIO_CONFIG_5_1 ) && NE_32( inConfig, IVAS_AUDIO_CONFIG_7_1 ) ) + { + tmpRotBuffer.data_fx = malloc( tmpRotBuffer.config.numSamplesPerChannel * tmpRotBuffer.config.numChannels * sizeof( Word32 ) ); + } + + FOR( i = 0; i < combinedOrientationDataLocal.num_subframes; i++ ) + { + Copy_Quat_fx( &combinedOrientationDataLocal.Quaternions[i], &Quaternions_orig[i] ); + } + + FOR( pos_idx = 0; pos_idx < pMultiBinPoseData->num_poses; pos_idx++ ) + { + /* Update head positions */ + FOR( i = 0; i < combinedOrientationDataLocal.num_subframes; i++ ) + { + Quaternions_abs.w_fx = L_negate( 12582912 ); // Q22 + q_fact_orig = Quaternions_orig[i].q_fact; + modify_Quat_q_fx( &combinedOrientationDataLocal.Quaternions[i], &combinedOrientationDataLocal.Quaternions[i], Q22 ); + /*euler*/ + Quat2EulerDegree_fx( combinedOrientationDataLocal.Quaternions[i], + &Quaternions_abs.z_fx, + &Quaternions_abs.y_fx, + &Quaternions_abs.x_fx ); + Quaternions_abs.x_fx = L_add( Quaternions_abs.x_fx, pMultiBinPoseData->relative_head_poses_fx[pos_idx][0] ); + Quaternions_abs.y_fx = L_add( Quaternions_abs.y_fx, pMultiBinPoseData->relative_head_poses_fx[pos_idx][1] ); + Quaternions_abs.z_fx = L_add( Quaternions_abs.z_fx, pMultiBinPoseData->relative_head_poses_fx[pos_idx][2] ); + + Euler2Quat_fx( deg2rad_fx( Quaternions_abs.x_fx ), + deg2rad_fx( Quaternions_abs.y_fx ), + deg2rad_fx( Quaternions_abs.z_fx ), &Quaternions_abs ); + + modify_Quat_q_fx( &Quaternions_abs, &Quaternions_abs, q_fact_orig ); + + Copy_Quat_fx( &Quaternions_abs, &combinedOrientationDataLocal.Quaternions[i] ); + QuatToRotMat_fx( combinedOrientationDataLocal.Quaternions[i], combinedOrientationDataLocal.Rmat_fx[i] ); + modify_Rmat_q_fx( combinedOrientationDataLocal.Rmat_fx[i], combinedOrientationDataLocal.Rmat_fx[i], sub( shl( q_fact_orig, 1 ), 32 ), Q30 ); + } + + IF( EQ_32( inConfig, IVAS_AUDIO_CONFIG_LS_CUSTOM ) || EQ_32( inConfig, IVAS_AUDIO_CONFIG_5_1 ) || EQ_32( inConfig, IVAS_AUDIO_CONFIG_7_1 ) ) + { + /* tdrend processing overview: + * 1. copy from inputBuffer to tmpRendBuffer + * 2. td_binaural_renderer_ext: inplace processing in tmpRendBuffer + * 3. copy from tmpRendBuffer to tmpSplitBinBuffer + * 4. LFE mixing + * 5. tmpSplitBinBuffer accumulated to outBuffer */ + + /* copy input to tdrend input/output buffer */ + copyBufferTo2dArray_fx( mcInput->base.inputBuffer, tmpRendBuffer ); + + /* perform rotation in source format to tmpRotBuffer */ + pCombinedOrientationDataLocal = &combinedOrientationDataLocal; + + FOR( i = 0; i < MAX_OUTPUT_CHANNELS; ++i ) + { + Scale_sig32( tmpRendBuffer[i], L_FRAME48k, sub( Q11, exp ) ); /* Q11 */ + } + /* Render */ + IF( ( error = ivas_td_binaural_renderer_ext_fx( ( pos_idx == 0 ) ? &mcInput->tdRendWrapper : &mcInput->splitTdRendWrappers[pos_idx - 1], mcInput->base.inConfig, &mcInput->customLsInput, &pCombinedOrientationDataLocal, NULL, mcInput->hReverb, 0, /* Ism Audio Metadata Delay Sync in ms for External Renderer */ *mcInput->base.ctx.pOutSampleRate, mcInput->base.inputBuffer.config.numSamplesPerChannel, tmpRendBuffer, &exp ) ) != IVAS_ERR_OK ) + { + return error; + } + FOR( i = 0; i < BINAURAL_CHANNELS; ++i ) + { + Scale_sig32( tmpRendBuffer[i], L_FRAME48k, negate( sub( Q11, exp ) ) ); /* Q(exp) */ + } + + /* Copy rendered audio to tmp storage buffer. Copying directly to output would + * overwrite original audio, which is still needed for rendering next head pose. */ + Copy32( tmpRendBuffer[0], tmpSplitBinauralBuffer[i_mult( 2, pos_idx )], output_frame ); + Copy32( tmpRendBuffer[1], tmpSplitBinauralBuffer[add( i_mult( 2, pos_idx ), 1 )], output_frame ); + } + ELSE + { +#ifdef SPLIT_REND_WITH_HEAD_ROT + hCrend = mcInput->crendWrapper->hCrend[0]; +#else + hCrend = mcInput->crendWrapper->hCrend; +#endif + /* crend processing overview: + * 1. rotateFrameMc: inputBuffer to tmpRotBuffer + * 2. crend_process: tmpRotBuffer to tmpRendBuffer + * 3. copy from tmpRendBuffer to tmpSplitBinBuffer + * 4. LFE mixing + * 5. tmpSplitBinBuffer accumulated to outBuffer */ + + + /* copy input for in-place rotation */ + set32_fx( tmpRotBuffer.data_fx, 0, i_mult( tmpRotBuffer.config.numSamplesPerChannel, tmpRotBuffer.config.numChannels ) ); + + /* perform rotation in source format to tmpRotBuffer */ + pCombinedOrientationDataLocal = &combinedOrientationDataLocal; + IF( ( error = rotateFrameMc_fx( mcInput->base.inputBuffer, mcInput->base.inConfig, &mcInput->customLsInput, mcInput->base.ctx.pHeadRotData, &pCombinedOrientationDataLocal, mcInput->rot_gains_prev_fx[pos_idx], mcInput->efapInWrapper.hEfap, tmpRotBuffer ) ) != IVAS_ERR_OK ) + { + return error; + } + IF( EQ_16( pos_idx, 0 ) ) + { + exp = sub( *outAudio.pq_fact, 1 ); + } + + copyBufferTo2dArray_fx( tmpRotBuffer, tmpRendBuffer ); + + /* call CREND (rotation already performed) */ + IF( NE_32( ( error = ivas_rend_crendProcess( mcInput->crendWrapper, mcInput->base.inConfig, outConfig, NULL, NULL, NULL, NULL, + p_tmpRendBuffer, *mcInput->base.ctx.pOutSampleRate, getNumSubframesInBuffer( &tmpRotBuffer, *mcInput->base.ctx.pOutSampleRate ), pos_idx ) ), + IVAS_ERR_OK ) ) + + IF( EQ_16( pos_idx, 0 ) ) + { + IF( hCrend->hReverb != NULL ) + { + exp = sub( exp, 2 ); + } + } + + /* Copy rendererd audio to tmp storage buffer, Copying directly to output would + * overwrite original audio, which is still needed for rendering next head pose. */ + Copy32( tmpRendBuffer[0], tmpSplitBinauralBuffer[i_mult( 2, pos_idx )], output_frame ); + Copy32( tmpRendBuffer[1], tmpSplitBinauralBuffer[add( i_mult( 2, pos_idx ), 1 )], output_frame ); + } + + /* restore original headrotation data */ + FOR( i = 0; i < combinedOrientationDataLocal.num_subframes; i++ ) + { + Copy_Quat_fx( &Quaternions_orig[i], &combinedOrientationDataLocal.Quaternions[i] ); + } + } + + IF( NE_32( inConfig, IVAS_AUDIO_CONFIG_LS_CUSTOM ) && NE_32( inConfig, IVAS_AUDIO_CONFIG_5_1 ) && NE_32( inConfig, IVAS_AUDIO_CONFIG_7_1 ) ) + { + /* free temporary buffer for rotation in source format for CREND */ + free( tmpRotBuffer.data_fx ); + } + + accumulate2dArrayToBuffer_fx( tmpSplitBinauralBuffer, &outAudio ); + + IF( ( error = renderLfeToBinaural_fx( mcInput, outConfig, outAudio, *outAudio.pq_fact, exp ) ) != IVAS_ERR_OK ) + { + return error; + } + *outAudio.pq_fact = exp; + + pop_wmops(); + return IVAS_ERR_OK; +} +#endif + + static ivas_error renderInputMc( input_mc *mcInput, const AUDIO_CONFIG outConfig, @@ -6207,6 +7432,12 @@ static ivas_error renderInputMc( error = renderMcToBinauralRoom( mcInput, outConfig, outAudio ); } BREAK; +#ifdef SPLIT_REND_WITH_HEAD_ROT + case IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED: + case IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM: + error = renderMcToSplitBinaural( mcInput, outConfig, outAudio ); + break; +#endif default: return IVAS_ERR_INVALID_OUTPUT_FORMAT; } @@ -6282,6 +7513,197 @@ static void renderSbaToSba( pop_wmops(); return; } + + +#ifdef SPLIT_REND_WITH_HEAD_ROT + +static ivas_error renderSbaToMultiBinaural( + input_sba *sbaInput, + const AUDIO_CONFIG outConfig, + Word32 out[][L_FRAME48k] ) +{ + Word32 tmpCrendBuffer[MAX_OUTPUT_CHANNELS][L_FRAME48k]; + Word32 *p_tmpCrendBuffer[MAX_OUTPUT_CHANNELS]; + Word16 sf; + Word16 i, j, pos_idx; + COMBINED_ORIENTATION_DATA combinedOrientationDataLocal; + COMBINED_ORIENTATION_HANDLE pCombinedOrientationDataLocal; + ivas_error error; + IVAS_REND_AudioBuffer tmpRotBuffer; + const MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData; + + FOR( i = 0; i < MAX_OUTPUT_CHANNELS; i++ ) + { + p_tmpCrendBuffer[i] = tmpCrendBuffer[i]; + move32(); + } + push_wmops( "renderSbaToMultiBinaural" ); + pMultiBinPoseData = &sbaInput->base.ctx.pSplitRendWrapper->multiBinPoseData; + move32(); + + pCombinedOrientationDataLocal = *sbaInput->base.ctx.pCombinedOrientationData; + combinedOrientationDataLocal = *pCombinedOrientationDataLocal; + move32(); + move32(); + + IF( EQ_32( pMultiBinPoseData->poseCorrectionMode, ISAR_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB ) ) + { + FOR( sf = 1; sf < combinedOrientationDataLocal.num_subframes; ++sf ) + { + Copy_Quat_fx( &combinedOrientationDataLocal.Quaternions[0], &combinedOrientationDataLocal.Quaternions[sf] ); + FOR( i = 0; i < 3; i++ ) + { + FOR( j = 0; j < 3; j++ ) + { + combinedOrientationDataLocal.Rmat_fx[sf][i][j] = combinedOrientationDataLocal.Rmat_fx[0][i][j]; + move32(); + } + } + } + } + + tmpRotBuffer = sbaInput->base.inputBuffer; + tmpRotBuffer.data_fx = malloc( tmpRotBuffer.config.numSamplesPerChannel * tmpRotBuffer.config.numChannels * sizeof( Word32 ) ); + + FOR( pos_idx = 0; pos_idx < pMultiBinPoseData->num_poses; pos_idx++ ) + { + IVAS_QUATERNION Quaternions_orig[MAX_PARAM_SPATIAL_SUBFRAMES], Quaternions_abs; + Word16 q_fact_orig; + FOR( i = 0; i < combinedOrientationDataLocal.num_subframes; i++ ) + { + Copy_Quat_fx( &combinedOrientationDataLocal.Quaternions[i], &Quaternions_orig[i] ); + + Quaternions_abs.w_fx = L_negate( 12582912 ); // Q22 + q_fact_orig = combinedOrientationDataLocal.Quaternions[i].q_fact; + modify_Quat_q_fx( &combinedOrientationDataLocal.Quaternions[i], &combinedOrientationDataLocal.Quaternions[i], Q22 ); + /*euler*/ + Quat2EulerDegree_fx( combinedOrientationDataLocal.Quaternions[i], + &Quaternions_abs.z_fx, + &Quaternions_abs.y_fx, + &Quaternions_abs.x_fx ); + Quaternions_abs.x_fx = L_add( Quaternions_abs.x_fx, pMultiBinPoseData->relative_head_poses_fx[pos_idx][0] ); + Quaternions_abs.y_fx = L_add( Quaternions_abs.y_fx, pMultiBinPoseData->relative_head_poses_fx[pos_idx][1] ); + Quaternions_abs.z_fx = L_add( Quaternions_abs.z_fx, pMultiBinPoseData->relative_head_poses_fx[pos_idx][2] ); + + Euler2Quat_fx( deg2rad_fx( Quaternions_abs.x_fx ), + deg2rad_fx( Quaternions_abs.y_fx ), + deg2rad_fx( Quaternions_abs.z_fx ), &Quaternions_abs ); + + modify_Quat_q_fx( &Quaternions_abs, &Quaternions_abs, q_fact_orig ); + + Copy_Quat_fx( &Quaternions_abs, &combinedOrientationDataLocal.Quaternions[i] ); + QuatToRotMat_fx( combinedOrientationDataLocal.Quaternions[i], combinedOrientationDataLocal.Rmat_fx[i] ); + modify_Rmat_q_fx( combinedOrientationDataLocal.Rmat_fx[i], combinedOrientationDataLocal.Rmat_fx[i], sub( shl( q_fact_orig, 1 ), 32 ), Q30 ); + } + + /* copy input for in-place rotation */ + Copy32( sbaInput->base.inputBuffer.data_fx, tmpRotBuffer.data_fx, tmpRotBuffer.config.numChannels * tmpRotBuffer.config.numSamplesPerChannel ); + + pCombinedOrientationDataLocal = &combinedOrientationDataLocal; + + IF( ( error = rotateFrameSba_fx( sbaInput->base.inputBuffer, sbaInput->base.inConfig, sbaInput->base.ctx.pHeadRotData, &pCombinedOrientationDataLocal, sbaInput->rot_gains_prev_fx[pos_idx], tmpRotBuffer ) ) != IVAS_ERR_OK ) + { + return error; + } + + copyBufferTo2dArray_fx( tmpRotBuffer, tmpCrendBuffer ); + + assert( sbaInput->crendWrapper->hCrend[0]->hReverb == NULL ); + + /* call CREND */ + IF( NE_32( ( error = ivas_rend_crendProcess( sbaInput->crendWrapper, sbaInput->base.inConfig, outConfig, NULL, NULL, NULL, NULL, p_tmpCrendBuffer, *sbaInput->base.ctx.pOutSampleRate, + getNumSubframesInBuffer( &tmpRotBuffer, *sbaInput->base.ctx.pOutSampleRate ), pos_idx ) ), + IVAS_ERR_OK ) ) + { + return error; + } + + FOR( i = 0; i < combinedOrientationDataLocal.num_subframes; i++ ) + { + Copy_Quat_fx( &Quaternions_orig[i], &combinedOrientationDataLocal.Quaternions[i] ); + } + + /* move to output */ + FOR( i = 0; i < BINAURAL_CHANNELS; i++ ) + { + Copy32( tmpCrendBuffer[i], out[pos_idx * BINAURAL_CHANNELS + i], tmpRotBuffer.config.numSamplesPerChannel ); + } + } + + free( tmpRotBuffer.data_fx ); + + pop_wmops(); + return IVAS_ERR_OK; +} + + +static ivas_error renderSbaToMultiBinauralCldfb( + input_sba *sbaInput, + Word32 Cldfb_Out_Real[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + Word32 Cldfb_Out_Imag[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + const Word16 low_res_pre_rend_rot, + const Word16 num_subframes, + const Word16 Q_in ) +{ + Word32 Cldfb_RealBuffer[MAX_OUTPUT_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX]; + Word32 Cldfb_ImagBuffer[MAX_OUTPUT_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX]; + + copyBufferToCLDFBarray_fx( sbaInput->base.inputBuffer, Cldfb_RealBuffer, Cldfb_ImagBuffer ); + + ivas_rend_CldfbMultiBinRendProcess( sbaInput->cldfbRendWrapper.hCldfbRend, sbaInput->base.ctx.pCombinedOrientationData, &sbaInput->base.ctx.pSplitRendWrapper->multiBinPoseData, + Cldfb_RealBuffer, Cldfb_ImagBuffer, Cldfb_Out_Real, Cldfb_Out_Imag, low_res_pre_rend_rot, num_subframes, Q_in ); + + return IVAS_ERR_OK; +} + + +static ivas_error renderSbaToSplitBinaural( + input_sba *sbaInput, + const AUDIO_CONFIG outConfig, + IVAS_REND_AudioBuffer outAudio ) +{ + Word32 tmpCrendBuffer[MAX_OUTPUT_CHANNELS][L_FRAME48k]; + ivas_error error; + Word32 Cldfb_RealBuffer_Binaural[MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX]; + Word32 Cldfb_ImagBuffer_Binaural[MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX]; + Word16 low_res_pre_rend_rot; + + low_res_pre_rend_rot = 1; + + push_wmops( "renderSbaToSplitBinaural" ); + error = IVAS_ERR_OK; + move32(); + + IF( EQ_32( sbaInput->base.ctx.hhRendererConfig[0]->split_rend_config.rendererSelection, ISAR_SPLIT_REND_RENDERER_SELECTION_FASTCONV ) ) + { + if ( ( renderSbaToMultiBinauralCldfb( sbaInput, Cldfb_RealBuffer_Binaural, Cldfb_ImagBuffer_Binaural, low_res_pre_rend_rot, + getNumSubframesInBuffer( &outAudio, *sbaInput->base.ctx.pOutSampleRate ), *outAudio.pq_fact ) ) != IVAS_ERR_OK ) + { + return error; + } + + accumulateCLDFBArrayToBuffer_fx( Cldfb_RealBuffer_Binaural, Cldfb_ImagBuffer_Binaural, &outAudio ); + } + else + { + if ( ( renderSbaToMultiBinaural( sbaInput, outConfig, tmpCrendBuffer ) ) != IVAS_ERR_OK ) + { + return error; + } + IF( sbaInput->crendWrapper->hCrend[0]->hReverb != NULL ) + { + *outAudio.pq_fact = sub( *outAudio.pq_fact, Q2 ); + move16(); + } + + accumulate2dArrayToBuffer_fx( tmpCrendBuffer, &outAudio ); + } + + pop_wmops(); + return error; +} +#endif + static ivas_error renderSbaToBinaural( input_sba *sbaInput, const AUDIO_CONFIG outConfig, @@ -6297,11 +7719,29 @@ static ivas_error renderSbaToBinaural( Word32 *output_fx[MAX_OUTPUT_CHANNELS]; push_wmops( "renderSbaToBinaural" ); + +#ifdef SPLIT_REND_WITH_HEAD_ROT + IF( EQ_32( sbaInput->base.ctx.hhRendererConfig[0]->split_rend_config.rendererSelection, ISAR_SPLIT_REND_RENDERER_SELECTION_FASTCONV ) ) + { + Word32 Cldfb_RealBuffer_Binaural[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX]; + Word32 Cldfb_ImagBuffer_Binaural[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX]; + + IF( ( error = renderSbaToMultiBinauralCldfb( sbaInput, Cldfb_RealBuffer_Binaural, Cldfb_ImagBuffer_Binaural, 0, + getNumSubframesInBuffer( &outAudio, *sbaInput->base.ctx.pOutSampleRate ), *outAudio.pq_fact ) ) != IVAS_ERR_OK ) + { + return error; + } + + accumulateCLDFBArrayToBuffer_fx( Cldfb_RealBuffer_Binaural, Cldfb_ImagBuffer_Binaural, &outAudio ); + } + ELSE +#endif { FOR( i = 0; i < MAX_OUTPUT_CHANNELS; i++ ) { output_fx[i] = output_buffer_fx[i]; + move32(); } hCombinedOrientationData = sbaInput->base.ctx.pCombinedOrientationData; @@ -6329,12 +7769,22 @@ static ivas_error renderSbaToBinaural( Copy32( sbaInput->base.inputBuffer.data_fx, tmpRotBuffer.data_fx, i_mult( tmpRotBuffer.config.numChannels, tmpRotBuffer.config.numSamplesPerChannel ) ); + +#ifdef SPLIT_REND_WITH_HEAD_ROT + IF( NE_16( ( error = rotateFrameSba_fx( sbaInput->base.inputBuffer, sbaInput->base.inConfig, sbaInput->base.ctx.pHeadRotData, + sbaInput->base.ctx.pCombinedOrientationData, sbaInput->rot_gains_prev_fx[0], tmpRotBuffer ) ), + IVAS_ERR_OK ) ) + { + return error; + } +#else IF( NE_16( ( error = rotateFrameSba_fx( sbaInput->base.inputBuffer, sbaInput->base.inConfig, sbaInput->base.ctx.pHeadRotData, sbaInput->base.ctx.pCombinedOrientationData, sbaInput->rot_gains_prev_fx, tmpRotBuffer ) ), IVAS_ERR_OK ) ) { return error; } +#endif copyBufferTo2dArray_fx( tmpRotBuffer, output_buffer_fx ); free( tmpRotBuffer.data_fx ); @@ -6345,12 +7795,22 @@ static ivas_error renderSbaToBinaural( } // Porting Crend_process function CREND_HANDLE hCrend; +#ifdef SPLIT_REND_WITH_HEAD_ROT + hCrend = sbaInput->crendWrapper->hCrend[0]; +#else hCrend = sbaInput->crendWrapper->hCrend; +#endif /* call CREND */ +#ifdef SPLIT_REND_WITH_HEAD_ROT + IF( NE_32( ( error = ivas_rend_crendProcess( sbaInput->crendWrapper, sbaInput->base.inConfig, outConfig, NULL, NULL, NULL, NULL, output_fx, *sbaInput->base.ctx.pOutSampleRate, + getNumSubframesInBuffer( &outAudio, *sbaInput->base.ctx.pOutSampleRate ), 0 ) ), + IVAS_ERR_OK ) ) +#else IF( NE_32( ( error = ivas_rend_crendProcess( sbaInput->crendWrapper, sbaInput->base.inConfig, outConfig, NULL, NULL, NULL, NULL, output_fx, *sbaInput->base.ctx.pOutSampleRate, getNumSubframesInBuffer( &outAudio, *sbaInput->base.ctx.pOutSampleRate ) ) ), IVAS_ERR_OK ) ) +#endif { return error; } @@ -6386,8 +7846,11 @@ static ivas_error renderSbaToBinauralRoom( push_wmops( "renderSbaToBinauralRoom" ); Word16 nchan_out; CREND_HANDLE hCrend; - +#ifdef SPLIT_REND_WITH_HEAD_ROT + hCrend = sbaInput->crendWrapper->hCrend[0]; +#else hCrend = sbaInput->crendWrapper->hCrend; +#endif IF( NE_32( ( error = getAudioConfigNumChannels( outConfig, &nchan_out ) ), IVAS_ERR_OK ) ) { @@ -6424,11 +7887,19 @@ static ivas_error renderSbaToBinauralRoom( /* copy input for in-place rotation */ Copy32( sbaInput->base.inputBuffer.data_fx, tmpRotBuffer.data_fx, i_mult( tmpRotBuffer.config.numChannels, tmpRotBuffer.config.numSamplesPerChannel ) ); +#ifdef SPLIT_REND_WITH_HEAD_ROT + IF( NE_32( ( error = rotateFrameSba_fx( sbaInput->base.inputBuffer, sbaInput->base.inConfig, sbaInput->base.ctx.pHeadRotData, + sbaInput->base.ctx.pCombinedOrientationData, + sbaInput->rot_gains_prev_fx[0], + tmpRotBuffer ) ), + IVAS_ERR_OK ) ) +#else IF( NE_32( ( error = rotateFrameSba_fx( sbaInput->base.inputBuffer, sbaInput->base.inConfig, sbaInput->base.ctx.pHeadRotData, sbaInput->base.ctx.pCombinedOrientationData, sbaInput->rot_gains_prev_fx, tmpRotBuffer ) ), IVAS_ERR_OK ) ) +#endif { return error; } @@ -6463,10 +7934,17 @@ static ivas_error renderSbaToBinauralRoom( // Porting Crend_process function /* call CREND */ +#ifdef SPLIT_REND_WITH_HEAD_ROT + IF( NE_32( ( error = ivas_rend_crendProcess( sbaInput->crendWrapper, IVAS_AUDIO_CONFIG_7_1_4, outConfig, + NULL, NULL, NULL, NULL, p_tmpCrendBuffer, *sbaInput->base.ctx.pOutSampleRate, + getNumSubframesInBuffer( &outAudio, *sbaInput->base.ctx.pOutSampleRate ), 0 ) ), + IVAS_ERR_OK ) ) +#else IF( NE_32( ( error = ivas_rend_crendProcess( sbaInput->crendWrapper, IVAS_AUDIO_CONFIG_7_1_4, outConfig, NULL, NULL, NULL, NULL, p_tmpCrendBuffer, *sbaInput->base.ctx.pOutSampleRate, getNumSubframesInBuffer( &outAudio, *sbaInput->base.ctx.pOutSampleRate ) ) ), IVAS_ERR_OK ) ) +#endif { return error; } @@ -6508,11 +7986,20 @@ static ivas_error renderInputSba( { ivas_error error; IVAS_REND_AudioBuffer inAudio; +#ifdef SPLIT_REND_WITH_HEAD_ROT + int16_t cldfb2tdShift; +#endif error = IVAS_ERR_OK; move32(); inAudio = sbaInput->base.inputBuffer; +#ifdef SPLIT_REND_WITH_HEAD_ROT + cldfb2tdShift = outAudio.config.is_cldfb ? 1 : 0; + IF( NE_32( L_shl( sbaInput->base.numNewSamplesPerChannel, cldfb2tdShift ), outAudio.config.numSamplesPerChannel ) && + NE_32( outConfig, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) && NE_32( outConfig, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ) +#else IF( NE_32( sbaInput->base.numNewSamplesPerChannel, outAudio.config.numSamplesPerChannel ) ) +#endif { return IVAS_ERROR( IVAS_ERR_INVALID_BUFFER_SIZE, "Mismatch between the number of input samples vs number of requested output samples - currently not allowed" ); } @@ -6539,6 +8026,12 @@ static ivas_error renderInputSba( case IVAS_REND_AUDIO_CONFIG_TYPE_BINAURAL: SWITCH( outConfig ) { +#ifdef SPLIT_REND_WITH_HEAD_ROT + case IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED: + case IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM: + error = renderSbaToSplitBinaural( sbaInput, outConfig, outAudio ); + break; +#endif case IVAS_AUDIO_CONFIG_BINAURAL: error = renderSbaToBinaural( sbaInput, outConfig, outAudio ); BREAK; @@ -6868,6 +8361,11 @@ static ivas_error renderInputMasa( Word16 maxBin; Word32 *tmpBuffer_fx[MAX_OUTPUT_CHANNELS]; Word32 tmpBuffer_buff_fx[MAX_OUTPUT_CHANNELS][L_FRAME48k]; +#ifdef SPLIT_REND_WITH_HEAD_ROT + int16_t cldfb2tdShift; + Word32 Cldfb_RealBuffer_Binaural[MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX]; + Word32 Cldfb_ImagBuffer_Binaural[MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX]; +#endif IF( !masaInput->metadataHasBeenFed ) { @@ -6875,7 +8373,14 @@ static ivas_error renderInputMasa( } inAudio = masaInput->base.inputBuffer; + +#ifdef SPLIT_REND_WITH_HEAD_ROT + cldfb2tdShift = outAudio.config.is_cldfb ? 1 : 0; + IF( ( NE_32( L_shl( masaInput->base.numNewSamplesPerChannel, cldfb2tdShift ), outAudio.config.numSamplesPerChannel ) ) && + NE_32( outConfig, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) && NE_32( outConfig, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ) +#else IF( NE_32( masaInput->base.numNewSamplesPerChannel, outAudio.config.numSamplesPerChannel ) ) +#endif { return IVAS_ERROR( IVAS_ERR_INVALID_BUFFER_SIZE, "Mismatch between the number of input samples vs number of requested output samples - currently not allowed" ); } @@ -6912,60 +8417,105 @@ static ivas_error renderInputMasa( num_subframes = BASOP_Util_Divide3232_Scale( L_mult0( masaInput->base.inputBuffer.config.numSamplesPerChannel, IVAS_NUM_FRAMES_PER_SEC * MAX_PARAM_SPATIAL_SUBFRAMES ), *masaInput->base.ctx.pOutSampleRate, &exp ); num_subframes = shr( num_subframes, sub( 15, exp ) ); /* Q0 */ - SWITCH( masaInput->hMasaExtRend->renderer_type ) +#ifdef SPLIT_REND_WITH_HEAD_ROT + IF( EQ_32( outConfig, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) || EQ_32( outConfig, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) ) { - case RENDERER_DIRAC: - - copyMasaMetadataToDiracRenderer_fx( &masaInput->masaMetadata, masaInput->hMasaExtRend->hSpatParamRendCom, maxBin ); - intermidiate_ext_dirac_render( masaInput->hMasaExtRend, 1 ); - FOR( ch = 0; ch < masaInput->hMasaExtRend->hDirACRend->hOutSetup.nchan_out_woLFE + masaInput->hMasaExtRend->hDirACRend->hOutSetup.num_lfe; ch++ ) - { - masaInput->hMasaExtRend->cldfbAnaRend[0]->Q_cldfb_state = Q11; - move16(); - } - FOR( ch = 0; ch < MAX_OUTPUT_CHANNELS; ch++ ) + /* split rendering. use the combined of the first subframe in all subframes */ + Word16 sf, i, j; + COMBINED_ORIENTATION_HANDLE pCombinedOrientationData; + pCombinedOrientationData = *masaInput->base.ctx.pCombinedOrientationData; + FOR( sf = 1; sf < pCombinedOrientationData->num_subframes; sf++ ) + { + Copy_Quat_fx( &pCombinedOrientationData->Quaternions[0], &pCombinedOrientationData->Quaternions[sf] ); + FOR( i = 0; i < 3; i++ ) { - Scale_sig32( tmpBuffer_buff_fx[ch], L_FRAME48k, sub( Q11, *outAudio.pq_fact ) ); /* Q11 */ + FOR( j = 0; j < 3; j++ ) + { + pCombinedOrientationData->Rmat_fx[sf][i][j] = pCombinedOrientationData->Rmat_fx[0][i][j]; + move32(); + } } + } - scale_sig32( outAudio.data_fx, i_mult( outAudio.config.numChannels, outAudio.config.numSamplesPerChannel ), sub( Q11, *outAudio.pq_fact ) ); /* Q11 */ + copyMasaMetadataToDiracRenderer_fx( &masaInput->masaMetadata, masaInput->hMasaExtRend->hSpatParamRendCom, maxBin ); + Scale_sig32( tmpBuffer_buff_fx[0], L_FRAME48k, sub( Q11, *outAudio.pq_fact ) ); /* Q11 */ + Scale_sig32( tmpBuffer_buff_fx[1], L_FRAME48k, sub( Q11, *outAudio.pq_fact ) ); /* Q11 */ - ivas_masa_ext_dirac_render_fx( masaInput->hMasaExtRend, tmpBuffer_fx, num_subframes ); + // scale_sig32( outAudio.data_fx, i_mult( outAudio.config.numChannels, outAudio.config.numSamplesPerChannel ), sub( Q11, *outAudio.pq_fact ) ); - *outAudio.pq_fact = Q11; - move16(); - FOR( ch = 0; ch < masaInput->hMasaExtRend->hDirACRend->hOutSetup.nchan_out_woLFE + masaInput->hMasaExtRend->hDirACRend->hOutSetup.num_lfe; ch++ ) - { - scale_sig32( masaInput->hMasaExtRend->cldfbSynRend[ch]->cldfb_state_fx, masaInput->hMasaExtRend->cldfbSynRend[ch]->cldfb_size, sub( Q11, masaInput->hMasaExtRend->cldfbSynRend[ch]->Q_cldfb_state ) ); /* Q11 */ - masaInput->hMasaExtRend->cldfbSynRend[ch]->Q_cldfb_state = Q11; + ivas_masa_ext_rend_parambin_render_fx( masaInput->hMasaExtRend, *masaInput->base.ctx.pCombinedOrientationData, tmpBuffer_fx, num_subframes, masaInput->base.ctx.pSplitRendWrapper, Cldfb_RealBuffer_Binaural, Cldfb_ImagBuffer_Binaural ); + + accumulateCLDFBArrayToBuffer_fx( Cldfb_RealBuffer_Binaural, Cldfb_ImagBuffer_Binaural, &outAudio ); + + + *outAudio.pq_fact = Q6; + move16(); + } + ELSE + { + /* non-split path */ +#endif + SWITCH( masaInput->hMasaExtRend->renderer_type ) + { + case RENDERER_DIRAC: + + copyMasaMetadataToDiracRenderer_fx( &masaInput->masaMetadata, masaInput->hMasaExtRend->hSpatParamRendCom, maxBin ); + intermidiate_ext_dirac_render( masaInput->hMasaExtRend, 1 ); + FOR( ch = 0; ch < masaInput->hMasaExtRend->hDirACRend->hOutSetup.nchan_out_woLFE + masaInput->hMasaExtRend->hDirACRend->hOutSetup.num_lfe; ch++ ) + { + masaInput->hMasaExtRend->cldfbAnaRend[0]->Q_cldfb_state = Q11; + move16(); + } + FOR( ch = 0; ch < MAX_OUTPUT_CHANNELS; ch++ ) + { + Scale_sig32( tmpBuffer_buff_fx[ch], L_FRAME48k, sub( Q11, *outAudio.pq_fact ) ); /* Q11 */ + } + + scale_sig32( outAudio.data_fx, i_mult( outAudio.config.numChannels, outAudio.config.numSamplesPerChannel ), sub( Q11, *outAudio.pq_fact ) ); /* Q11 */ + + ivas_masa_ext_dirac_render_fx( masaInput->hMasaExtRend, tmpBuffer_fx, num_subframes ); + + *outAudio.pq_fact = Q11; move16(); - } - intermidiate_ext_dirac_render( masaInput->hMasaExtRend, 0 ); - BREAK; - case RENDERER_STEREO_PARAMETRIC: - case RENDERER_BINAURAL_PARAMETRIC: - case RENDERER_BINAURAL_PARAMETRIC_ROOM: + FOR( ch = 0; ch < masaInput->hMasaExtRend->hDirACRend->hOutSetup.nchan_out_woLFE + masaInput->hMasaExtRend->hDirACRend->hOutSetup.num_lfe; ch++ ) + { + scale_sig32( masaInput->hMasaExtRend->cldfbSynRend[ch]->cldfb_state_fx, masaInput->hMasaExtRend->cldfbSynRend[ch]->cldfb_size, sub( Q11, masaInput->hMasaExtRend->cldfbSynRend[ch]->Q_cldfb_state ) ); /* Q11 */ + masaInput->hMasaExtRend->cldfbSynRend[ch]->Q_cldfb_state = Q11; + move16(); + } - copyMasaMetadataToDiracRenderer_fx( &masaInput->masaMetadata, masaInput->hMasaExtRend->hSpatParamRendCom, maxBin ); + intermidiate_ext_dirac_render( masaInput->hMasaExtRend, 0 ); + BREAK; + case RENDERER_STEREO_PARAMETRIC: + case RENDERER_BINAURAL_PARAMETRIC: + case RENDERER_BINAURAL_PARAMETRIC_ROOM: + + copyMasaMetadataToDiracRenderer_fx( &masaInput->masaMetadata, masaInput->hMasaExtRend->hSpatParamRendCom, maxBin ); - Scale_sig32( tmpBuffer_buff_fx[0], L_FRAME48k, sub( Q11, *outAudio.pq_fact ) ); /* Q11 */ - Scale_sig32( tmpBuffer_buff_fx[1], L_FRAME48k, sub( Q11, *outAudio.pq_fact ) ); /* Q11 */ + Scale_sig32( tmpBuffer_buff_fx[0], L_FRAME48k, sub( Q11, *outAudio.pq_fact ) ); /* Q11 */ + Scale_sig32( tmpBuffer_buff_fx[1], L_FRAME48k, sub( Q11, *outAudio.pq_fact ) ); /* Q11 */ - scale_sig32( outAudio.data_fx, i_mult( outAudio.config.numChannels, outAudio.config.numSamplesPerChannel ), sub( Q11, *outAudio.pq_fact ) ); + scale_sig32( outAudio.data_fx, i_mult( outAudio.config.numChannels, outAudio.config.numSamplesPerChannel ), sub( Q11, *outAudio.pq_fact ) ); +#ifdef SPLIT_REND_WITH_HEAD_ROT + ivas_masa_ext_rend_parambin_render_fx( masaInput->hMasaExtRend, *masaInput->base.ctx.pCombinedOrientationData, tmpBuffer_fx, num_subframes, NULL, NULL, NULL ); +#else ivas_masa_ext_rend_parambin_render_fx( masaInput->hMasaExtRend, *masaInput->base.ctx.pCombinedOrientationData, tmpBuffer_fx, num_subframes ); - *outAudio.pq_fact = Q11; - move16(); - BREAK; - case RENDERER_DISABLE: - BREAK; /* This happens for 1TC MASA to MONO where we just copy input transport to output */ - default: - return ( IVAS_ERROR( IVAS_ERR_IO_CONFIG_PAIR_NOT_SUPPORTED, "Wrong output config for MASA input in external renderer\n" ) ); +#endif + *outAudio.pq_fact = Q11; + move16(); + BREAK; + case RENDERER_DISABLE: + BREAK; /* This happens for 1TC MASA to MONO where we just copy input transport to output */ + default: + return ( IVAS_ERROR( IVAS_ERR_IO_CONFIG_PAIR_NOT_SUPPORTED, "Wrong output config for MASA input in external renderer\n" ) ); + } + accumulate2dArrayToBuffer_fx( tmpBuffer_buff_fx, &outAudio ); +#ifdef SPLIT_REND_WITH_HEAD_ROT } - - accumulate2dArrayToBuffer_fx( tmpBuffer_buff_fx, &outAudio ); +#endif } return IVAS_ERR_OK; @@ -7195,12 +8745,21 @@ ivas_error IVAS_REND_SetIsmMetadataDelay( *-------------------------------------------------------------------*/ static ivas_error getSamplesInternal( - IVAS_REND_HANDLE hIvasRend, /* i/o: Renderer handle */ + IVAS_REND_HANDLE hIvasRend, /* i/o: Renderer handle */ +#ifdef SPLIT_REND_WITH_HEAD_ROT + IVAS_REND_AudioBuffer outAudio /* i/o: buffer for output audio */, + IVAS_REND_BitstreamBuffer *hBits /*i/o: buffer for input/output bitstream. Needed in split rendering mode*/ +#else IVAS_REND_AudioBuffer outAudio /* i/o: buffer for output audio */ +#endif ) { ivas_error error; Word16 numOutChannels; +#ifdef SPLIT_REND_WITH_HEAD_ROT + int16_t cldfb2tdSampleShift; + IVAS_REND_AudioBuffer outAudioOrig; +#endif /* Validate function arguments */ test(); IF( hIvasRend == NULL || outAudio.data_fx == NULL ) @@ -7209,20 +8768,35 @@ static ivas_error getSamplesInternal( } test(); +#ifdef SPLIT_REND_WITH_HEAD_ROT + cldfb2tdSampleShift = ( outAudio.config.is_cldfb ) ? 1 : 0; + + IF( outAudio.config.numSamplesPerChannel <= 0 || ( MAX_BUFFER_LENGTH_PER_CHANNEL < outAudio.config.numSamplesPerChannel && outAudio.config.is_cldfb == 0 ) || + ( ( shl( MAX_BUFFER_LENGTH_PER_CHANNEL, cldfb2tdSampleShift ) ) < outAudio.config.numSamplesPerChannel && outAudio.config.is_cldfb == 1 ) ) +#else IF( outAudio.config.numSamplesPerChannel <= 0 || LT_16( MAX_BUFFER_LENGTH_PER_CHANNEL, outAudio.config.numSamplesPerChannel ) ) +#endif { return IVAS_ERR_INVALID_BUFFER_SIZE; } test(); - IF( outAudio.config.numChannels <= 0 || LT_16( MAX_OUTPUT_CHANNELS, outAudio.config.numChannels ) ) + IF( LE_16( outAudio.config.numChannels, 0 ) || LT_16( MAX_OUTPUT_CHANNELS, outAudio.config.numChannels ) ) { return IVAS_ERR_WRONG_NUM_CHANNELS; } test(); +#ifdef SPLIT_REND_WITH_HEAD_ROT + IF( EQ_32( getAudioConfigType( hIvasRend->outputConfig ), IVAS_REND_AUDIO_CONFIG_TYPE_BINAURAL ) && + NE_32( hIvasRend->outputConfig, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) && + NE_32( hIvasRend->outputConfig, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) && + NE_32( L_shr( L_mult0( outAudio.config.numSamplesPerChannel, 1000 ), cldfb2tdSampleShift ), + imult3216( hIvasRend->sampleRateOut, i_mult( hIvasRend->num_subframes, BINAURAL_RENDERING_FRAME_SIZE_MS ) ) ) ) +#else IF( EQ_32( getAudioConfigType( hIvasRend->outputConfig ), IVAS_REND_AUDIO_CONFIG_TYPE_BINAURAL ) && NE_32( L_mult0( outAudio.config.numSamplesPerChannel, 1000 ), imult3216( hIvasRend->sampleRateOut, i_mult( hIvasRend->num_subframes, BINAURAL_RENDERING_FRAME_SIZE_MS ) ) ) ) +#endif { return IVAS_ERROR( IVAS_ERR_INVALID_BUFFER_SIZE, "Binaural rendering requires specific frame size" ); } @@ -7301,7 +8875,11 @@ static ivas_error getSamplesInternal( return error; } +#ifdef SPLIT_REND_WITH_HEAD_ROT + IF( NE_16( numOutChannels, outAudio.config.numChannels ) && NE_32( hIvasRend->outputConfig, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) && NE_32( hIvasRend->outputConfig, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ) +#else IF( NE_16( numOutChannels, outAudio.config.numChannels ) ) +#endif { return IVAS_ERR_WRONG_NUM_CHANNELS; } @@ -7309,6 +8887,27 @@ static ivas_error getSamplesInternal( /* Clear original output buffer */ set32_fx( outAudio.data_fx, 0, imult1616( outAudio.config.numChannels, outAudio.config.numSamplesPerChannel ) ); +#ifdef SPLIT_REND_WITH_HEAD_ROT + outAudioOrig = outAudio; + /* Use internal buffer if outputting split rendering bitstream */ + IF( EQ_32( hIvasRend->outputConfig, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) || + EQ_32( hIvasRend->outputConfig, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ) + { + Word16 num_poses_orig; + num_poses_orig = hIvasRend->splitRendWrapper.multiBinPoseData.num_poses; + move16(); + outAudio.config = hIvasRend->splitRendEncBuffer.config; + outAudio.data_fx = hIvasRend->splitRendEncBuffer.data_fx; + + ISAR_PRE_REND_GetMultiBinPoseData( &hIvasRend->hRendererConfig->split_rend_config, &hIvasRend->splitRendWrapper.multiBinPoseData, hIvasRend->headRotData.sr_pose_pred_axis ); + + assert( num_poses_orig == hIvasRend->splitRendWrapper.multiBinPoseData.num_poses && "number of poses should not change dynamically" ); + + /* Clear output buffer for split rendering bitstream */ + set32_fx( outAudio.data_fx, 0, outAudio.config.numChannels * outAudio.config.numSamplesPerChannel ); + } +#endif + IF( NE_32( ( error = renderActiveInputsIsm( hIvasRend, outAudio ) ), IVAS_ERR_OK ) ) { return error; @@ -7329,8 +8928,150 @@ static ivas_error getSamplesInternal( test(); test(); +#ifndef SPLIT_REND_WITH_HEAD_ROT + Word32 limiter_thresold = L_lshl( IVAS_LIMITER_THRESHOLD, *outAudio.pq_fact ); limitRendererOutput_fx( hIvasRend->hLimiter, outAudio.data_fx, outAudio.config.numSamplesPerChannel, limiter_thresold, *outAudio.pq_fact ); +#endif + +#ifdef SPLIT_REND_WITH_HEAD_ROT + IF( EQ_32( hIvasRend->outputConfig, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) || EQ_32( hIvasRend->outputConfig, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ) + { + ISAR_SPLIT_REND_BITS_DATA bits; + Word16 cldfb_in_flag, i, j, k, ch, ro_md_flag; + Word32 Cldfb_RealBuffer_Binaural[MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX]; + Word32 Cldfb_ImagBuffer_Binaural[MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX]; + FOR( i = 0; i < MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS; i++ ) + { + FOR( j = 0; j < CLDFB_NO_COL_MAX; j++ ) + { + FOR( k = 0; k < CLDFB_NO_CHANNELS_MAX; k++ ) + { + Cldfb_RealBuffer_Binaural[i][j][k] = 0; + Cldfb_ImagBuffer_Binaural[i][j][k] = 0; + move32(); + move32(); + } + } + } + + Word32 *tmpBinaural[MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS], tmpBinaural_buff[MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS][L_FRAME48k]; + + FOR( ch = 0; ch < MAX_OUTPUT_CHANNELS; ch++ ) + { + tmpBinaural[ch] = tmpBinaural_buff[ch]; + move32(); + } + + IF( EQ_16( outAudio.config.is_cldfb, 1 ) ) + { + cldfb_in_flag = 1; + move16(); + copyBufferToCLDFBarray_fx( outAudio, Cldfb_RealBuffer_Binaural, Cldfb_ImagBuffer_Binaural ); + } + ELSE + { + cldfb_in_flag = 0; + move16(); + copyBufferTo2dArray_fx( outAudio, tmpBinaural_buff ); + } + + /* Encode split rendering bitstream */ + convertBitsBufferToInternalBitsBuff( *hBits, &bits ); + + ro_md_flag = 0; + move16(); + FOR( i = 0; i < RENDERER_MAX_ISM_INPUTS; ++i ) + { + IF( NE_32( hIvasRend->inputsIsm[i].base.inConfig, IVAS_AUDIO_CONFIG_INVALID ) ) + { + ro_md_flag = 1; + move16(); + break; + } + } + + Word16 q1 = 31, q2 = 31, Q_buff; + Word16 Q_out[CLDFB_NO_COL_MAX]; + Q_out[0] = 31; + Word16 num_poses = hIvasRend->splitRendWrapper.multiBinPoseData.num_poses; + + for ( i = 0; i < num_poses * BINAURAL_CHANNELS; i++ ) + { + for ( j = 0; j < CLDFB_NO_COL_MAX; j++ ) + { + q1 = s_min( q1, L_norm_arr( Cldfb_RealBuffer_Binaural[i][j], CLDFB_NO_CHANNELS_MAX ) ); + q2 = s_min( q2, L_norm_arr( Cldfb_ImagBuffer_Binaural[i][j], CLDFB_NO_CHANNELS_MAX ) ); + } + } + Q_buff = s_min( q1, q2 ); + for ( i = 0; i < num_poses * BINAURAL_CHANNELS; i++ ) + { + for ( j = 0; j < CLDFB_NO_COL_MAX; j++ ) + { + scale_sig32( Cldfb_RealBuffer_Binaural[i][j], CLDFB_NO_CHANNELS_MAX, Q_buff ); + scale_sig32( Cldfb_ImagBuffer_Binaural[i][j], CLDFB_NO_CHANNELS_MAX, Q_buff ); + } + } + Q_buff = Q_buff + *outAudio.pq_fact; + + IF( EQ_16( cldfb_in_flag, 0 ) ) + { + /*TD input*/ + num_poses = hIvasRend->splitRendWrapper.multiBinPoseData.num_poses; + + FOR( i = 0; i < num_poses * BINAURAL_CHANNELS; ++i ) + { + Q_out[0] = s_min( Q_out[0], L_norm_arr( tmpBinaural_buff[i], L_FRAME48k ) ); + } + + FOR( i = 0; i < num_poses * BINAURAL_CHANNELS; ++i ) + { + scale_sig32( tmpBinaural_buff[i], L_FRAME48k, Q_out[0] ); + } + + Q_out[0] = Q_out[0] + *outAudio.pq_fact; + } + + if ( ( error = ISAR_PRE_REND_MultiBinToSplitBinaural( &hIvasRend->splitRendWrapper, hIvasRend->headRotData.headPositions[0], hIvasRend->hRendererConfig->split_rend_config.splitRendBitRate, hIvasRend->hRendererConfig->split_rend_config.codec, +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + hIvasRend->hRendererConfig->split_rend_config.isar_frame_size_ms, +#endif + hIvasRend->hRendererConfig->split_rend_config.codec_frame_size_ms, + &bits, Cldfb_RealBuffer_Binaural, Cldfb_ImagBuffer_Binaural, ( const int16_t )( ( BINAURAL_MAXBANDS * hIvasRend->sampleRateOut ) / 48000 ), tmpBinaural, 1, cldfb_in_flag, ( hIvasRend->outputConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ? 1 : 0, ro_md_flag, Q_buff, &Q_out[0] ) ) != IVAS_ERR_OK ) + { + return error; + } + + Word16 pcm_out_flag = ( hIvasRend->outputConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ? 1 : 0; + IF( NE_16( pcm_out_flag, 0 ) ) + { + FOR( j = 0; j < BINAURAL_CHANNELS; j++ ) + { + scale_sig32( tmpBinaural_buff[j], L_FRAME48k, sub( *outAudio.pq_fact, Q_out[j] ) ); // *outAudio.pq_fact + } + } + + convertInternalBitsBuffToBitsBuffer( hBits, bits ); + + /* reset to outAudioOrig in case of PCM output */ + outAudio.config = outAudioOrig.config; + outAudio.data_fx = outAudioOrig.data_fx; + + IF( NE_16( pcm_out_flag, 0 ) ) + { + accumulate2dArrayToBuffer_fx( tmpBinaural_buff, &outAudio ); + } + } +#endif + +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( outAudio.config.is_cldfb == 0 ) + { + Word32 limiter_thresold = L_lshl( IVAS_LIMITER_THRESHOLD, *outAudio.pq_fact ); + limitRendererOutput_fx( hIvasRend->hLimiter, outAudio.data_fx, outAudio.config.numSamplesPerChannel, limiter_thresold, *outAudio.pq_fact ); + } +#endif /* update global cominbed orientation start index */ ivas_combined_orientation_update_start_index( hIvasRend->hCombinedOrientationData, outAudio.config.numSamplesPerChannel ); @@ -7338,21 +9079,83 @@ static ivas_error getSamplesInternal( return IVAS_ERR_OK; } -/*-------------------------------------------------------------------* - * IVAS_REND_GetSamples() - * - * - *-------------------------------------------------------------------*/ +/*-------------------------------------------------------------------* + * IVAS_REND_GetSamples() + * + * + *-------------------------------------------------------------------*/ + +ivas_error IVAS_REND_GetSamples( + IVAS_REND_HANDLE hIvasRend, /* i/o: Renderer handle */ + IVAS_REND_AudioBuffer outAudio /* i/o: buffer for output audio */ +) +{ + +#ifdef SPLIT_REND_WITH_HEAD_ROT + return getSamplesInternal( hIvasRend, outAudio, NULL ); +#else + return getSamplesInternal( hIvasRend, outAudio ); +#endif +} + +#ifdef SPLIT_REND_WITH_HEAD_ROT +/*-------------------------------------------------------------------* + * IVAS_REND_GetSplitBinauralBitstream() + * + * + *-------------------------------------------------------------------*/ + +ivas_error +IVAS_REND_GetSplitBinauralBitstream( + IVAS_REND_HANDLE hIvasRend, /* i/o: Renderer handle */ + IVAS_REND_AudioBuffer outAudio, /* i/o: buffer for output audio */ + IVAS_REND_BitstreamBuffer *hBits /* o : buffer for output bitstream */ +) +{ + int16_t cldfb_in_flag; + + cldfb_in_flag = getCldfbRendFlag( hIvasRend, IVAS_REND_AUDIO_CONFIG_TYPE_UNKNOWN ); + hIvasRend->splitRendEncBuffer.config.is_cldfb = cldfb_in_flag; + if ( hIvasRend->hRendererConfig->split_rend_config.dof == 0 || hIvasRend->hRendererConfig->split_rend_config.poseCorrectionMode == ISAR_SPLIT_REND_POSE_CORRECTION_MODE_NONE ) + { + hIvasRend->splitRendEncBuffer.config.numSamplesPerChannel = outAudio.config.numSamplesPerChannel; + } + else + { + hIvasRend->splitRendEncBuffer.config.numSamplesPerChannel = (int16_t) ( hIvasRend->sampleRateOut / FRAMES_PER_SEC ); + } + hIvasRend->splitRendEncBuffer.config.numSamplesPerChannel *= cldfb_in_flag ? 2 : 1; + + /* hIvasRend->splitRendEncBuffer used for BINAURAL_SPLIT_CODED output + outAudio used for BINAURAL_SPLIT_PCM output */ + return getSamplesInternal( hIvasRend, outAudio, hBits ); +} -ivas_error IVAS_REND_GetSamples( - IVAS_REND_HANDLE hIvasRend, /* i/o: Renderer handle */ - IVAS_REND_AudioBuffer outAudio /* i/o: buffer for output audio */ +ivas_error IVAS_REND_GetSplitRendBitstreamHeader( + IVAS_REND_HANDLE hIvasRend, /* i/o: IVAS renderer handle */ + ISAR_SPLIT_REND_CODEC *pCodec, /* o: pointer to codec setting */ + ISAR_SPLIT_REND_POSE_CORRECTION_MODE *poseCorrection, /* o: pointer to pose correction mode */ + int16_t *pCodec_frame_size_ms /* o: pointer to codec frame size setting */ +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + , + int16_t *pIsar_frame_size_ms /* o: pointer to isar frame size setting */ +#endif ) { - - return getSamplesInternal( hIvasRend, outAudio ); + if ( hIvasRend == NULL || hIvasRend->hRendererConfig == NULL ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } + *pCodec = hIvasRend->hRendererConfig->split_rend_config.codec; + *pCodec_frame_size_ms = hIvasRend->hRendererConfig->split_rend_config.codec_frame_size_ms; +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + *pIsar_frame_size_ms = hIvasRend->hRendererConfig->split_rend_config.isar_frame_size_ms; +#endif + *poseCorrection = hIvasRend->hRendererConfig->split_rend_config.poseCorrectionMode; + return IVAS_ERR_OK; } +#endif /*-------------------------------------------------------------------* * IVAS_REND_Close() @@ -7404,6 +9207,11 @@ void IVAS_REND_Close( ivas_limiter_close_fx( &hIvasRend->hLimiter ); +#ifdef SPLIT_REND_WITH_HEAD_ROT + /* Split binaural rendering */ + ISAR_PRE_REND_close( &hIvasRend->splitRendWrapper, &hIvasRend->splitRendEncBuffer ); +#endif + closeHeadRotation( hIvasRend ); @@ -7416,6 +9224,140 @@ void IVAS_REND_Close( return; } +#ifdef SPLIT_REND_WITH_HEAD_ROT +/*-------------------------------------------------------------------* + * IVAS_REND_openCldfb() + * + * + *-------------------------------------------------------------------*/ + +ivas_error +IVAS_REND_openCldfb( + IVAS_CLDFB_FILTER_BANK_HANDLE cldfbAna[IVAS_MAX_INPUT_CHANNELS], + IVAS_CLDFB_FILTER_BANK_HANDLE cldfbSyn[IVAS_MAX_OUTPUT_CHANNELS], + const int16_t num_in_chs, + const int16_t num_out_chs, + const int32_t output_Fs ) +{ + int16_t n; + ivas_error error; + + for ( n = 0; n < num_in_chs; n++ ) + { + if ( ( error = openCldfb_ivas_fx( &( cldfbAna[n] ), CLDFB_ANALYSIS, output_Fs, CLDFB_PROTOTYPE_5_00MS, DEC ) ) != IVAS_ERR_OK ) + { + return error; + } + } + for ( ; n < IVAS_MAX_INPUT_CHANNELS; n++ ) + { + cldfbAna[n] = NULL; + } + + for ( n = 0; n < num_out_chs; n++ ) + { + if ( ( error = openCldfb_ivas_fx( &( cldfbSyn[n] ), CLDFB_SYNTHESIS, output_Fs, CLDFB_PROTOTYPE_5_00MS, DEC ) ) != IVAS_ERR_OK ) + { + return error; + } + } + for ( ; n < IVAS_MAX_OUTPUT_CHANNELS; n++ ) + { + cldfbSyn[n] = NULL; + } + + return IVAS_ERR_OK; +} + +/*-------------------------------------------------------------------* + * IVAS_REND_closeCldfb() + * + * + *-------------------------------------------------------------------*/ + +void IVAS_REND_closeCldfb( + IVAS_CLDFB_FILTER_BANK_HANDLE cldfbAna[IVAS_MAX_INPUT_CHANNELS], + IVAS_CLDFB_FILTER_BANK_HANDLE cldfbSyn[IVAS_MAX_OUTPUT_CHANNELS] ) +{ + int16_t n; + + for ( n = 0; n < IVAS_MAX_INPUT_CHANNELS; n++ ) + { + if ( cldfbAna[n] != NULL ) + { + deleteCldfb( &( cldfbAna[n] ) ); + cldfbAna[n] = NULL; + } + } + + for ( n = 0; n < IVAS_MAX_OUTPUT_CHANNELS; n++ ) + { + if ( cldfbSyn[n] != NULL ) + { + deleteCldfb( &( cldfbSyn[n] ) ); + cldfbSyn[n] = NULL; + } + } + + return; +} + + +/*-------------------------------------------------------------------* + * IVAS_REND_cldfbSynthesis_wrapper() + * + * + *-------------------------------------------------------------------*/ + +void IVAS_REND_cldfbAnalysis_ts_wrapper( + const Word32 *timeIn, /* i : time buffer */ + Word32 realBuffer[IVAS_CLDFB_NO_CHANNELS_MAX], /* o : real value buffer */ + Word32 imagBuffer[IVAS_CLDFB_NO_CHANNELS_MAX], /* o : imag value buffer */ + const Word16 samplesToProcess, /* i : samples to process */ + IVAS_CLDFB_FILTER_BANK_HANDLE h_cldfb, /* i : filterbank state */ + Word16 Q_in, + Word16 *Q_out ) +{ + + Word16 Q_cldfb = Q_in; + assert( Q_in == h_cldfb->Q_cldfb_state ); + cldfbAnalysis_ts_fx_fixed_q( timeIn, realBuffer, imagBuffer, samplesToProcess, h_cldfb, + &Q_cldfb ); + + *Q_out = sub( Q_in, 5 ); + + return; +} + + +/*-------------------------------------------------------------------* + * IVAS_REND_cldfbSynthesis_wrapper() + * + * + *-------------------------------------------------------------------*/ + +void IVAS_REND_cldfbSynthesis_wrapper( + Word32 **realBuffer, /* i : real values */ + Word32 **imagBuffer, /* i : imag values */ + Word32 *timeOut, /* o : output time domain samples */ + const int16_t samplesToProcess, /* i : number of processed samples */ + IVAS_CLDFB_FILTER_BANK_HANDLE h_cldfb, /* i : filter bank state */ + Word16 Q_cldfb, + Word16 *Q_out ) +{ + + Scale_sig32( h_cldfb->cldfb_state_fx, h_cldfb->p_filter_length, sub( sub( Q_cldfb, 1 ), h_cldfb->Q_cldfb_state ) ); + cldfbSynthesis_ivas_fx( realBuffer, imagBuffer, timeOut, samplesToProcess, h_cldfb ); // Q_cldfb - 1 + *Q_out = sub( Q_cldfb, 1 ); + move16(); + h_cldfb->Q_cldfb_state = *Q_out; + move16(); + + return; +} +#endif + + static ivas_error ivas_masa_ext_rend_dirac_rend_init( input_masa *inputMasa ) { @@ -7858,6 +9800,10 @@ static ivas_error ivas_masa_ext_rend_parambin_init( Word16 tmpFloat_fx; ivas_error error; Word16 frequency_axis_fx[CLDFB_NO_CHANNELS_MAX]; +#ifdef SPLIT_REND_WITH_HEAD_ROT + int16_t pos_idx; +#endif + Word16 tmp; Word16 tmp_e; Word16 tmp2; @@ -7875,144 +9821,165 @@ static ivas_error ivas_masa_ext_rend_parambin_init( renderer_type = inputMasa->hMasaExtRend->renderer_type; move32(); - hDiracDecBin = inputMasa->hMasaExtRend->hDiracDecBin; - - /* Init assumes that no reconfiguration is required in external renderer. Instead, free and rebuild whole rendering. */ - IF( ( hDiracDecBin = (DIRAC_DEC_BIN_HANDLE) malloc( sizeof( DIRAC_DEC_BIN_DATA ) ) ) == NULL ) +#ifdef SPLIT_REND_WITH_HEAD_ROT + for ( pos_idx = 0; pos_idx < inputMasa->base.ctx.pSplitRendWrapper->multiBinPoseData.num_poses; pos_idx++ ) { - return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC binaural handle " ); - } - - hDiracDecBin->hTdDecorr = NULL; - hDiracDecBin->hReverb = NULL; - hDiracDecBin->h_freq_domain_decorr_ap_params = NULL; - hDiracDecBin->h_freq_domain_decorr_ap_state = NULL; - hDiracDecBin->hDiffuseDist = NULL; /* Not used in external renderer */ - hDiracDecBin->useTdDecorr = 0; /* Always use frequency domain decorrelator in external renderer */ - move16(); + hDiracDecBin = inputMasa->hMasaExtRend->hDiracDecBin[pos_idx]; +#else + hDiracDecBin = inputMasa->hMasaExtRend->hDiracDecBin; +#endif - FOR( j = 0; j < BINAURAL_CHANNELS; j++ ) - { - FOR( k = 0; k < BINAURAL_CHANNELS + MAX_NUM_OBJECTS; k++ ) + /* Init assumes that no reconfiguration is required in external renderer. Instead, free and rebuild whole rendering. */ + IF( ( hDiracDecBin = (DIRAC_DEC_BIN_HANDLE) malloc( sizeof( DIRAC_DEC_BIN_DATA ) ) ) == NULL ) { - set16_fx( hDiracDecBin->processMtxRe_fx[j][k], 0, nBins ); - set16_fx( hDiracDecBin->processMtxIm_fx[j][k], 0, nBins ); + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC binaural handle " ); } - FOR( k = 0; k < BINAURAL_CHANNELS; k++ ) - { - set16_fx( hDiracDecBin->processMtxDecRe_fx[j][k], 0, nBins ); - set16_fx( hDiracDecBin->processMtxDecIm_fx[j][k], 0, nBins ); - } - hDiracDecBin->q_processMtx = Q15; - hDiracDecBin->q_processMtxSCCR = Q15; - hDiracDecBin->q_processMtxPrev = Q15; - hDiracDecBin->q_processMtxPrevSCCR = Q15; - hDiracDecBin->q_processMtxDec = Q15; - hDiracDecBin->q_processMtxDecPrev = Q15; - move16(); - move16(); - move16(); - move16(); - move16(); + hDiracDecBin->hTdDecorr = NULL; + hDiracDecBin->hReverb = NULL; + hDiracDecBin->h_freq_domain_decorr_ap_params = NULL; + hDiracDecBin->h_freq_domain_decorr_ap_state = NULL; + hDiracDecBin->hDiffuseDist = NULL; /* Not used in external renderer */ + hDiracDecBin->useTdDecorr = 0; /* Always use frequency domain decorrelator in external renderer */ move16(); - set_zero_fx( hDiracDecBin->ChEnePrev_fx[j], nBins ); - set_zero_fx( hDiracDecBin->ChEneOutPrev_fx[j], nBins ); - set16_fx( hDiracDecBin->ChEnePrev_e[j], 0, nBins ); - set16_fx( hDiracDecBin->ChEneOutPrev_e[j], 0, nBins ); - } - set_zero_fx( hDiracDecBin->ChCrossRePrev_fx, nBins ); - set_zero_fx( hDiracDecBin->ChCrossImPrev_fx, nBins ); - set_zero_fx( hDiracDecBin->ChCrossReOutPrev_fx, nBins ); - set_zero_fx( hDiracDecBin->ChCrossImOutPrev_fx, nBins ); - set16_fx( hDiracDecBin->ChCrossRePrev_e, 0, nBins ); - set16_fx( hDiracDecBin->ChCrossImPrev_e, 0, nBins ); - set16_fx( hDiracDecBin->ChCrossReOutPrev_e, 0, nBins ); - set16_fx( hDiracDecBin->ChCrossImOutPrev_e, 0, nBins ); - hDiracDecBin->renderStereoOutputInsteadOfBinaural = 0; - move16(); - FOR( bin = 0; bin < nBins; bin++ ) - { - binCenterFreq_fx = L_mult0( extract_l( L_shr( output_Fs, 1 ) ), div_s( add( shl( bin, 1 ), 1 ), shl( nBins, 1 ) ) ) /*( (float) bin + 0.5f ) / (float) nBins * ( (float) output_Fs / 2.0f )*/; /*Q15*/ - /* These formulas and values are from Christian Borss's publication for binaural diffuse field coherence */ - tmp = BASOP_Util_Divide3232_Scale( binCenterFreq_fx, L_shl( 2700, Q15 ), &tmp_e ); - IF( tmp_e < 0 ) + FOR( j = 0; j < BINAURAL_CHANNELS; j++ ) { - tmp = shl( tmp, tmp_e ); /*q15*/ - tmp_e = 0; + FOR( k = 0; k < BINAURAL_CHANNELS + MAX_NUM_OBJECTS; k++ ) + { + set16_fx( hDiracDecBin->processMtxRe_fx[j][k], 0, nBins ); + set16_fx( hDiracDecBin->processMtxIm_fx[j][k], 0, nBins ); + } + + FOR( k = 0; k < BINAURAL_CHANNELS; k++ ) + { + set16_fx( hDiracDecBin->processMtxDecRe_fx[j][k], 0, nBins ); + set16_fx( hDiracDecBin->processMtxDecIm_fx[j][k], 0, nBins ); + } + hDiracDecBin->q_processMtx = Q15; + hDiracDecBin->q_processMtxSCCR = Q15; + hDiracDecBin->q_processMtxPrev = Q15; + hDiracDecBin->q_processMtxPrevSCCR = Q15; + hDiracDecBin->q_processMtxDec = Q15; + hDiracDecBin->q_processMtxDecPrev = Q15; + move16(); + move16(); + move16(); move16(); + move16(); + move16(); + set_zero_fx( hDiracDecBin->ChEnePrev_fx[j], nBins ); + set_zero_fx( hDiracDecBin->ChEneOutPrev_fx[j], nBins ); + set16_fx( hDiracDecBin->ChEnePrev_e[j], 0, nBins ); + set16_fx( hDiracDecBin->ChEneOutPrev_e[j], 0, nBins ); + } + set_zero_fx( hDiracDecBin->ChCrossRePrev_fx, nBins ); + set_zero_fx( hDiracDecBin->ChCrossImPrev_fx, nBins ); + set_zero_fx( hDiracDecBin->ChCrossReOutPrev_fx, nBins ); + set_zero_fx( hDiracDecBin->ChCrossImOutPrev_fx, nBins ); + set16_fx( hDiracDecBin->ChCrossRePrev_e, 0, nBins ); + set16_fx( hDiracDecBin->ChCrossImPrev_e, 0, nBins ); + set16_fx( hDiracDecBin->ChCrossReOutPrev_e, 0, nBins ); + set16_fx( hDiracDecBin->ChCrossImOutPrev_e, 0, nBins ); + hDiracDecBin->renderStereoOutputInsteadOfBinaural = 0; + move16(); + + FOR( bin = 0; bin < nBins; bin++ ) + { + binCenterFreq_fx = L_mult0( extract_l( L_shr( output_Fs, 1 ) ), div_s( add( shl( bin, 1 ), 1 ), shl( nBins, 1 ) ) ) /*( (float) bin + 0.5f ) / (float) nBins * ( (float) output_Fs / 2.0f )*/; /*Q15*/ + /* These formulas and values are from Christian Borss's publication for binaural diffuse field coherence */ + tmp = BASOP_Util_Divide3232_Scale( binCenterFreq_fx, L_shl( 2700, Q15 ), &tmp_e ); + IF( tmp_e < 0 ) + { + tmp = shl( tmp, tmp_e ); /*q15*/ + tmp_e = 0; + move16(); + } + tmpFloat_fx = s_max( 0, sub( shl_sat( 1, sub( 15, tmp_e ) ), tmp ) ) /*max( 0.0f, 1.0f - binCenterFreq / 2700.0f )*/; /*Q30*/ + tmp2 = extract_l( Mult_32_32( binCenterFreq_fx, 1952258 /*=2^31*180/(550)/360*/ ) % 32767 ); //*binCenterFreq_fx * EVS_PI / 550.0f*/ + hDiracDecBin->diffuseFieldCoherence_fx[bin] = L_shl( L_mult0( divide3232( tmpFloat_fx, Mult_32_16( binCenterFreq_fx, 187 /*2^15*pi/550*/ ) ), getSineWord16R2( tmp2 ) ), tmp_e ); /*tmpFloat * sinf( binCenterFreq * EVS_PI / 550.0f ) / ( binCenterFreq * EVS_PI / 550.0f );*/ + hDiracDecBin->diffuseFieldCoherence_fx[bin] = L_shl( hDiracDecBin->diffuseFieldCoherence_fx[bin], 1 ); /* Q31 */ + move32(); + move32(); } - tmpFloat_fx = s_max( 0, sub( shl_sat( 1, sub( 15, tmp_e ) ), tmp ) ) /*max( 0.0f, 1.0f - binCenterFreq / 2700.0f )*/; /*Q30*/ - tmp2 = extract_l( Mult_32_32( binCenterFreq_fx, 1952258 /*=2^31*180/(550)/360*/ ) % 32767 ); //*binCenterFreq_fx * EVS_PI / 550.0f*/ - hDiracDecBin->diffuseFieldCoherence_fx[bin] = L_shl( L_mult0( divide3232( tmpFloat_fx, Mult_32_16( binCenterFreq_fx, 187 /*2^15*pi/550*/ ) ), getSineWord16R2( tmp2 ) ), tmp_e ); /*tmpFloat * sinf( binCenterFreq * EVS_PI / 550.0f ) / ( binCenterFreq * EVS_PI / 550.0f );*/ - hDiracDecBin->diffuseFieldCoherence_fx[bin] = L_shl( hDiracDecBin->diffuseFieldCoherence_fx[bin], 1 ); /* Q31 */ - move32(); - move32(); - } - /* No SPAR in external renderer so set directive diffuse field coherence tables to zero */ - set_zero_fx( hDiracDecBin->diffuseFieldCoherenceX_fx, BINAURAL_COHERENCE_DIFFERENCE_BINS ); - set_zero_fx( hDiracDecBin->diffuseFieldCoherenceY_fx, BINAURAL_COHERENCE_DIFFERENCE_BINS ); - set_zero_fx( hDiracDecBin->diffuseFieldCoherenceZ_fx, BINAURAL_COHERENCE_DIFFERENCE_BINS ); + /* No SPAR in external renderer so set directive diffuse field coherence tables to zero */ + set_zero_fx( hDiracDecBin->diffuseFieldCoherenceX_fx, BINAURAL_COHERENCE_DIFFERENCE_BINS ); + set_zero_fx( hDiracDecBin->diffuseFieldCoherenceY_fx, BINAURAL_COHERENCE_DIFFERENCE_BINS ); + set_zero_fx( hDiracDecBin->diffuseFieldCoherenceZ_fx, BINAURAL_COHERENCE_DIFFERENCE_BINS ); - IF( EQ_16( renderer_type, RENDERER_BINAURAL_PARAMETRIC ) ) /* Indication of binaural rendering without room effect */ - { - set32_fx( hDiracDecBin->earlyPartEneCorrection_fx, ONE_IN_Q28 /*1.0f Q28*/, CLDFB_NO_CHANNELS_MAX ); - hDiracDecBin->q_earlyPartEneCorrection = Q28; - move16(); - hDiracDecBin->hReverb = NULL; - } - ELSE IF( EQ_16( renderer_type, RENDERER_BINAURAL_PARAMETRIC_ROOM ) ) /* Indication of binaural rendering with room effect */ - { - Copy32( hHrtfParambin->parametricEarlyPartEneCorrection_fx, hDiracDecBin->earlyPartEneCorrection_fx, nBins ); - hDiracDecBin->q_earlyPartEneCorrection = Q28; - move16(); + IF( EQ_16( renderer_type, RENDERER_BINAURAL_PARAMETRIC ) ) /* Indication of binaural rendering without room effect */ + { + set32_fx( hDiracDecBin->earlyPartEneCorrection_fx, ONE_IN_Q28 /*1.0f Q28*/, CLDFB_NO_CHANNELS_MAX ); + hDiracDecBin->q_earlyPartEneCorrection = Q28; + move16(); + hDiracDecBin->hReverb = NULL; + } + ELSE IF( EQ_16( renderer_type, RENDERER_BINAURAL_PARAMETRIC_ROOM ) ) /* Indication of binaural rendering with room effect */ + { + Copy32( hHrtfParambin->parametricEarlyPartEneCorrection_fx, hDiracDecBin->earlyPartEneCorrection_fx, nBins ); + hDiracDecBin->q_earlyPartEneCorrection = Q28; + move16(); +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( hDiracDecBin->hReverb == NULL && pos_idx == 0 ) /* open reverb only for the main direction */ +#else IF( hDiracDecBin->hReverb == NULL ) +#endif + { + /* 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( NE_32( ( error = ivas_binaural_reverb_open_parambin( &hDiracDecBin->hReverb, nBins, CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES, NULL, output_Fs, hHrtfParambin ) ), IVAS_ERR_OK ) ) + { + return error; + } + } + } + ELSE IF( EQ_16( renderer_type, RENDERER_STEREO_PARAMETRIC ) ) + { + set32_fx( hDiracDecBin->earlyPartEneCorrection_fx, ONE_IN_Q28 /*1.0f Q28*/, CLDFB_NO_CHANNELS_MAX ); + hDiracDecBin->q_earlyPartEneCorrection = Q28; + move16(); + hDiracDecBin->hReverb = NULL; + hDiracDecBin->renderStereoOutputInsteadOfBinaural = 1; + move16(); + } + ELSE /* Not valid renderer type for this renderer */ { - /* 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( NE_32( ( error = ivas_binaural_reverb_open_parambin( &hDiracDecBin->hReverb, nBins, CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES, NULL, output_Fs, hHrtfParambin ) ), IVAS_ERR_OK ) ) + assert( false ); + } + +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( pos_idx == 0 ) /* open decorrelator only for the main direction */ + { +#endif + /* Always open frequency domain decorrelator */ + ivas_dirac_dec_get_frequency_axis_fx( frequency_axis_fx, output_Fs, nBins ); + + IF( NE_32( ( error = ivas_dirac_dec_decorr_open_fx( &( hDiracDecBin->h_freq_domain_decorr_ap_params ), + &( hDiracDecBin->h_freq_domain_decorr_ap_state ), + nBins, + BINAURAL_CHANNELS, + BINAURAL_CHANNELS, + DIRAC_SYNTHESIS_PSD_LS, + frequency_axis_fx, + BINAURAL_CHANNELS, + output_Fs ) ), + IVAS_ERR_OK ) ) { return error; } +#ifdef SPLIT_REND_WITH_HEAD_ROT } - } - ELSE IF( EQ_16( renderer_type, RENDERER_STEREO_PARAMETRIC ) ) - { - set32_fx( hDiracDecBin->earlyPartEneCorrection_fx, ONE_IN_Q28 /*1.0f Q28*/, CLDFB_NO_CHANNELS_MAX ); - hDiracDecBin->q_earlyPartEneCorrection = Q28; - move16(); - hDiracDecBin->hReverb = NULL; - hDiracDecBin->renderStereoOutputInsteadOfBinaural = 1; +#endif + /* External renderer uses constant regularization factor */ + hDiracDecBin->reqularizationFactor_fx = 6554; /* 0.4f in Q14 */ move16(); +#ifdef SPLIT_REND_WITH_HEAD_ROT + inputMasa->hMasaExtRend->hDiracDecBin[pos_idx] = hDiracDecBin; } - ELSE /* Not valid renderer type for this renderer */ - { - assert( false ); - } - - /* Always open frequency domain decorrelator */ - ivas_dirac_dec_get_frequency_axis_fx( frequency_axis_fx, output_Fs, nBins ); - - IF( NE_32( ( error = ivas_dirac_dec_decorr_open_fx( &( hDiracDecBin->h_freq_domain_decorr_ap_params ), - &( hDiracDecBin->h_freq_domain_decorr_ap_state ), - nBins, - BINAURAL_CHANNELS, - BINAURAL_CHANNELS, - DIRAC_SYNTHESIS_PSD_LS, - frequency_axis_fx, - BINAURAL_CHANNELS, - output_Fs ) ), - IVAS_ERR_OK ) ) - { - return error; - } - /* External renderer uses constant regularization factor */ - hDiracDecBin->reqularizationFactor_fx = 6554; /* 0.4f in Q14 */ - move16(); - +#else inputMasa->hMasaExtRend->hDiracDecBin = hDiracDecBin; +#endif return error; } @@ -8040,7 +10007,14 @@ static ivas_error initMasaExtRenderer( move32(); hMasaExtRend->hDirACRend = NULL; hMasaExtRend->hSpatParamRendCom = NULL; +#ifdef SPLIT_REND_WITH_HEAD_ROT + for ( i = 0; i < MAX_HEAD_ROT_POSES; i++ ) + { + hMasaExtRend->hDiracDecBin[i] = NULL; + } +#else hMasaExtRend->hDiracDecBin = NULL; +#endif hMasaExtRend->hReverb = NULL; hMasaExtRend->hHrtfParambin = NULL; hMasaExtRend->hVBAPdata = NULL; @@ -8091,6 +10065,10 @@ static ivas_error initMasaExtRenderer( BREAK; case IVAS_AUDIO_CONFIG_BINAURAL: +#ifdef SPLIT_REND_WITH_HEAD_ROT + case IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM: + case IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED: +#endif hMasaExtRend->renderer_type = RENDERER_BINAURAL_PARAMETRIC; move32(); BREAK; @@ -8164,7 +10142,7 @@ static ivas_error initMasaExtRenderer( { FOR( i = 0; i < hMasaExtRend->nchan_input; i++ ) { - IF( NE_32( ( error = openCldfb_ivas_fx( &( hMasaExtRend->cldfbAnaRend[i] ), CLDFB_ANALYSIS, *inputMasa->base.ctx.pOutSampleRate, CLDFB_PROTOTYPE_5_00MS ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &( hMasaExtRend->cldfbAnaRend[i] ), CLDFB_ANALYSIS, *inputMasa->base.ctx.pOutSampleRate, CLDFB_PROTOTYPE_5_00MS, DEC ) ), IVAS_ERR_OK ) ) { return error; } @@ -8172,7 +10150,7 @@ static ivas_error initMasaExtRenderer( FOR( i = 0; i < hMasaExtRend->nchan_output; i++ ) { - IF( NE_32( ( error = openCldfb_ivas_fx( &( hMasaExtRend->cldfbSynRend[i] ), CLDFB_SYNTHESIS, *inputMasa->base.ctx.pOutSampleRate, CLDFB_PROTOTYPE_5_00MS ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = openCldfb_ivas_fx( &( hMasaExtRend->cldfbSynRend[i] ), CLDFB_SYNTHESIS, *inputMasa->base.ctx.pOutSampleRate, CLDFB_PROTOTYPE_5_00MS, DEC ) ), IVAS_ERR_OK ) ) { return error; } @@ -8208,10 +10186,21 @@ static void freeMasaExtRenderer( ivas_spat_hSpatParamRendCom_close_fx( &hMasaExtRend->hSpatParamRendCom ); } +#ifdef SPLIT_REND_WITH_HEAD_ROT + for ( i = 0; i < MAX_HEAD_ROT_POSES; i++ ) + { + if ( hMasaExtRend->hDiracDecBin[i] != NULL ) + { + ivas_dirac_dec_close_binaural_data( &hMasaExtRend->hDiracDecBin[i] ); + } + } + +#else IF( hMasaExtRend->hDiracDecBin != NULL ) { ivas_dirac_dec_close_binaural_data( &hMasaExtRend->hDiracDecBin ); } +#endif IF( hMasaExtRend->hReverb != NULL ) { @@ -8457,3 +10446,98 @@ static void intermidiate_ext_dirac_render( } } } + +#ifdef FIX_DISCLAIMER +static ivas_error printConfigInfo_rend( + IVAS_REND_HANDLE hIvasRend /* i : IVAS renderer handle */ +) +{ + ivas_error error; + Word8 config_str[50]; + + /*-----------------------------------------------------------------* + * Print output audio configuration + *-----------------------------------------------------------------*/ + + IF( NE_32( ( error = get_channel_config( hIvasRend->outputConfig, &config_str[0] ) ), IVAS_ERR_OK ) ) + { + return error; + } + + fprintf( stdout, "Output configuration: %s\n", config_str ); + + /*-----------------------------------------------------------------* + * Print renderer configurations + *-----------------------------------------------------------------*/ + + fprintf( stdout, "Output sampling rate: %d Hz\n", hIvasRend->sampleRateOut ); + + if ( hIvasRend->headRotData.headRotEnabled ) + { + fprintf( stdout, "Head-tracking: ON\n" ); + } + + IF( EQ_16( hIvasRend->outputConfig, IVAS_AUDIO_CONFIG_BINAURAL ) || + EQ_16( hIvasRend->outputConfig, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR ) || + EQ_16( hIvasRend->outputConfig, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) || + EQ_16( hIvasRend->outputConfig, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) || + EQ_16( hIvasRend->outputConfig, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ) + { + fprintf( stdout, "Render framesize: %dms\n", mult( hIvasRend->num_subframes, 5 ) ); + } + + return IVAS_ERR_OK; +} + + +/*---------------------------------------------------------------------* + * IVAS_REND_PrintInputConfig() + * + * + *---------------------------------------------------------------------*/ + +void IVAS_REND_PrintInputConfig( + const IVAS_AUDIO_CONFIG inputConfig /* i : input audio configuration */ +) +{ + Word8 config_str[50]; + + get_channel_config( inputConfig, &config_str[0] ); + fprintf( stdout, "Input configuration: %s\n", config_str ); + + return; +} + + +/*---------------------------------------------------------------------* + * IVAS_REND_PrintConfig() + * + * + *---------------------------------------------------------------------*/ + +ivas_error IVAS_REND_PrintConfig( + IVAS_REND_HANDLE hIvasRend /* i : IVAS renderer handle */ +) +{ + if ( hIvasRend == NULL ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } + + return printConfigInfo_rend( hIvasRend ); +} + + +/*---------------------------------------------------------------------* + * IVAS_REND_PrintDisclaimer() + * + * Print IVAS disclaimer to console + *---------------------------------------------------------------------*/ + +void IVAS_REND_PrintDisclaimer( void ) +{ + print_disclaimer( stderr ); + + return; +} +#endif diff --git a/lib_rend/lib_rend.h b/lib_rend/lib_rend.h index f3726a05b216041c6de9274204c369ff6051a92b..c3d6ca703251c8b6ce11414b263b63b9da5b7847 100644 --- a/lib_rend/lib_rend.h +++ b/lib_rend/lib_rend.h @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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 LIB_REND_H #include "common_api_types.h" +#include "ivas_stat_rend.h" #include "basop_util.h" #include @@ -55,20 +56,26 @@ typedef float IVAS_REND_LfePanMtx[RENDERER_MAX_INPUT_LFE_CHANNELS][IVAS_MAX_OUTPUT_CHANNELS]; typedef Word32 IVAS_REND_LfePanMtx_fx[RENDERER_MAX_INPUT_LFE_CHANNELS][IVAS_MAX_OUTPUT_CHANNELS]; +#ifdef SPLIT_REND_WITH_HEAD_ROT typedef struct { - Word16 numSamplesPerChannel; - Word16 numChannels; -} IVAS_REND_AudioBufferConfig; + Word32 bufLenInBytes; + Word32 bitsWritten; + Word32 bitsRead; + ISAR_SPLIT_REND_CODEC codec; + ISAR_SPLIT_REND_POSE_CORRECTION_MODE poseCorrection; + Word16 codec_frame_size_ms; +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + Word16 isar_frame_size_ms; + Word16 lc3plus_highres; +#endif +} IVAS_REND_BitstreamBufferConfig; typedef struct { - IVAS_REND_AudioBufferConfig config; - Word16 q_factor; - Word16 *pq_fact; - Word32 *data_fx; - // Word16 Q_data; -} IVAS_REND_AudioBuffer; - + IVAS_REND_BitstreamBufferConfig config; + UWord8 *bits; +} IVAS_REND_BitstreamBuffer; +#endif typedef struct { @@ -88,7 +95,7 @@ typedef enum IVAS_REND_AUDIO_CONFIG_TYPE_UNKNOWN, } IVAS_REND_AudioConfigType; -typedef uint16_t IVAS_REND_InputId; +typedef UWord16 IVAS_REND_InputId; typedef enum _IVAS_REND_COMPLEXITY_LEVEL { @@ -226,11 +233,45 @@ Word16 IVAS_REND_FeedRenderConfig( const IVAS_RENDER_CONFIG_DATA renderConfig /* i : Render configuration struct */ ); +#ifdef SPLIT_REND_WITH_HEAD_ROT +ivas_error IVAS_REND_FeedSplitBinauralBitstream( + IVAS_REND_HANDLE hIvasRend, /* i/o: Renderer handle */ + const IVAS_REND_InputId inputId, /* i : ID of the input */ + IVAS_REND_BitstreamBuffer *hBits /* i : buffer for input bitstream */ +); + +ivas_error IVAS_REND_GetSplitBinauralSamples( + IVAS_REND_HANDLE hIvasRend, /* i/o: Renderer handle */ + IVAS_REND_AudioBuffer outAudio, /* i/o: buffer for output audio */ + bool* needNewFrame +); + +ivas_error IVAS_REND_GetSplitBinauralBitstream( + IVAS_REND_HANDLE hIvasRend, /* i/o: Renderer handle */ + IVAS_REND_AudioBuffer outAudio, /* i/o: buffer for output audio */ + IVAS_REND_BitstreamBuffer *hBits /* o : buffer for output bitstream */ +); + +ivas_error IVAS_REND_GetSplitRendBitstreamHeader( + IVAS_REND_HANDLE hIvasRend, /* i/o: IVAS renderer handle */ + ISAR_SPLIT_REND_CODEC *pCodec, /* o: pointer to codec setting */ + ISAR_SPLIT_REND_POSE_CORRECTION_MODE *poseCorrection, /* o: pointer to pose correction mode */ + Word16 *pCodec_frame_size_ms /* o: pointer to codec frame size setting */ +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + , + Word16 *pIsar_frame_size_ms /* o: pointer to isar frame size setting */ +#endif +); +#endif + ivas_error IVAS_REND_SetHeadRotation( IVAS_REND_HANDLE hIvasRend, /* i/o: Renderer handle */ const IVAS_QUATERNION headRot, /* i : head orientations for next rendering call */ const IVAS_VECTOR3 Pos, /* i : listener positions for next rendering call */ - const Word16 sf_idx /* i : subframe index */ +#ifdef SPLIT_REND_WITH_HEAD_ROT + const ISAR_SPLIT_REND_ROT_AXIS rot_axis, /* i : external control for rotation axis for split rendering*/ +#endif + const Word16 sf_idx /* i : subframe index */ ); /* Head rotation becomes enabled by calling IVAS_REND_SetHeadRotation. Use this to disable. */ @@ -264,6 +305,11 @@ ivas_error IVAS_REND_SetReferenceVector( const IVAS_VECTOR3 refPos /* i : Reference position */ ); +#ifdef SPLIT_REND_WITH_HEAD_ROT +ivas_error IVAS_REND_SetSplitRendBFI( + IVAS_REND_HANDLE hIvasRend, + const Word16 bfi); +#endif ivas_error IVAS_REND_SetExternalOrientation( IVAS_REND_HANDLE hIvasRend, /* i/o: Renderer handle */ @@ -323,6 +369,57 @@ void IVAS_REND_Close( IVAS_REND_HANDLE* phIvasRend /* i/o: Pointer to renderer handle */ ); +#ifdef SPLIT_REND_WITH_HEAD_ROT +/* Split binaural rendering functions */ + +ivas_error IVAS_REND_openCldfb( + IVAS_CLDFB_FILTER_BANK_HANDLE cldfbAna[IVAS_MAX_INPUT_CHANNELS], + IVAS_CLDFB_FILTER_BANK_HANDLE cldfbSyn[IVAS_MAX_OUTPUT_CHANNELS], + const Word16 num_in_chs, + const Word16 num_out_chs, + const Word32 output_Fs +); + +void IVAS_REND_closeCldfb( + IVAS_CLDFB_FILTER_BANK_HANDLE cldfbAna[IVAS_MAX_INPUT_CHANNELS], + IVAS_CLDFB_FILTER_BANK_HANDLE cldfbSyn[IVAS_MAX_OUTPUT_CHANNELS] +); + +void IVAS_REND_cldfbAnalysis_ts_wrapper( + const Word32 *timeIn, /* i : time buffer */ + Word32 realBuffer[IVAS_CLDFB_NO_CHANNELS_MAX], /* o : real value buffer */ + Word32 imagBuffer[IVAS_CLDFB_NO_CHANNELS_MAX], /* o : imag value buffer */ + const Word16 samplesToProcess, /* i : samples to process */ + IVAS_CLDFB_FILTER_BANK_HANDLE h_cldfb, /* i : filterbank state */ + Word16 Q_in, + Word16 *Q_out ); + +void IVAS_REND_cldfbSynthesis_wrapper( + Word32 **realBuffer, /* i : real values */ + Word32 **imagBuffer, /* i : imag values */ + Word32 *timeOut, /* o : output time domain samples */ + const int16_t samplesToProcess, /* i : number of processed samples */ + IVAS_CLDFB_FILTER_BANK_HANDLE h_cldfb, /* i : filter bank state */ + Word16 Q_cldfb, + Word16 *Q_out ); +#endif + + +#ifdef FIX_DISCLAIMER +/* Disclaimer and info printing */ + +void IVAS_REND_PrintInputConfig( + const IVAS_AUDIO_CONFIG inputConfig /* i : input audio configuration */ +); + +ivas_error IVAS_REND_PrintConfig( + IVAS_REND_HANDLE hIvasRend /* i : IVAS renderer handle */ +); + +void IVAS_REND_PrintDisclaimer( + void +); +#endif /* clang-format on */ diff --git a/lib_util/audio_file_reader.c b/lib_util/audio_file_reader.c index ff9a9b33bea53240938fac15d58be6ed1766cd4e..ca5e6e4963b676da58526fbb30a3cf07d9f34f77 100644 --- a/lib_util/audio_file_reader.c +++ b/lib_util/audio_file_reader.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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 185d8c077475812f10c821a1c1ec4740b9fbd7f8..571c1e765637e1cb30ac9afa9cb49b45127886b7 100644 --- a/lib_util/audio_file_reader.h +++ b/lib_util/audio_file_reader.h @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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 0f2f5335d785438e2e743e86a32aa5643921d3e6..fb7a64c425b6f648667a969290b6086c11158887 100644 --- a/lib_util/audio_file_writer.c +++ b/lib_util/audio_file_writer.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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 0b1c3315f23279a176e481743e88d2d31466f599..2622992cecbbb4875a6aa5d7440492bc0d9ccb86 100644 --- a/lib_util/audio_file_writer.h +++ b/lib_util/audio_file_writer.h @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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 841d6e1de73b83a97f661b8c7f1b50ffe97b6ccb..2bd6f46aa6014e8e37f1c77bd051d49eabb47da4 100644 --- a/lib_util/bitstream_reader.c +++ b/lib_util/bitstream_reader.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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 e33de489777e6493615f382bba69b05e1de96802..fb6f9f9b9dac7304cd1bf029cdf2c2822991f62c 100644 --- a/lib_util/bitstream_reader.h +++ b/lib_util/bitstream_reader.h @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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 d19a05898d620e82c40288b1f40ba6717793d327..8c4b64cd4816649cb6833ccd6bda13270eb0e179 100644 --- a/lib_util/bitstream_writer.c +++ b/lib_util/bitstream_writer.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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 b0fab9e44902ef2b903fbbeb6e6bbed5fbc31c08..f3efd4ddf2ec85beea05af186ffa68cbed225b2f 100644 --- a/lib_util/bitstream_writer.h +++ b/lib_util/bitstream_writer.h @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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 337583ab9fd5f978cc32c2b22348e2bf6a8490bb..bec772ce42f96eb8373d44aebc6cba944cdb288e 100644 --- a/lib_util/cmdl_tools.c +++ b/lib_util/cmdl_tools.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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 7c3c05ba16b5265d220c9fa16bab84870e375791..327acb93d0b1d528874de8ef018a36686379b778 100644 --- a/lib_util/cmdl_tools.h +++ b/lib_util/cmdl_tools.h @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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 fe2c1b1dbec8a543298089bb433e31a056bf77f9..b2c8f85bc4dc7119e7268271f44fcce2af9c703c 100644 --- a/lib_util/cmdln_parser.c +++ b/lib_util/cmdln_parser.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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 4721d968f4e35d28a19eae79d71a60f7fa095bd0..2627d556624dc0de59ca01a5f342d684d066d277 100644 --- a/lib_util/cmdln_parser.h +++ b/lib_util/cmdln_parser.h @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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 c122716f3110a7ca183af914c9b173ba6ac85a6b..a0c514bad3ac1495178debf42f7b6736ec770bd3 100644 --- a/lib_util/evs_rtp_payload.c +++ b/lib_util/evs_rtp_payload.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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 004ecf79b695ebfff70c8f0ea69e81c44a8aaf65..357d985578ba9616980b33e62b75c62ee6ad5604 100644 --- a/lib_util/evs_rtp_payload.h +++ b/lib_util/evs_rtp_payload.h @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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 bec637464fd400721ef093f42ef819aa9ab2338e..d6c6ec4755dc8f3b4f07ba3990389888547a31ee 100644 --- a/lib_util/g192.c +++ b/lib_util/g192.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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 6d6104d45327ffea1aaa885b2af085783bd9f287..8014f523687f9c50404d39dbe3e1242b00f813c7 100644 --- a/lib_util/g192.h +++ b/lib_util/g192.h @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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 874ff6cfa8a83296d81987e8bf7549a1b38bffed..e667dcfe5179500d1f08c3310dd27ead8b4dc2bc 100644 --- a/lib_util/hrtf_file_reader.c +++ b/lib_util/hrtf_file_reader.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other @@ -32,10 +32,8 @@ #include "hrtf_file_reader.h" #include -#include "prot.h" -#include "ivas_prot_rend.h" #include "prot_fx.h" -#include "ivas_prot.h" +#include "ivas_prot_rend_fx.h" #include "ivas_prot_fx.h" /*---------------------------------------------------------------------* @@ -848,7 +846,7 @@ static ivas_error create_HRTF_from_rawdata( /* latency_s */ //( *hHRTF )->latency_s = *( (float *) ( hrtf_data_rptr ) ); - ( *hHRTF )->latency_s_fx = (Word32) ( *( (float *) ( hrtf_data_rptr ) ) * ONE_IN_Q31 ); + ( *hHRTF )->latency_s_fx = (Word32) ( *( (float *) ( hrtf_data_rptr ) ) * (float) ONE_IN_Q31 ); hrtf_data_rptr += sizeof( float ); /* max_num_ir */ diff --git a/lib_util/hrtf_file_reader.h b/lib_util/hrtf_file_reader.h index e222fd4d1730794e806b41cd195bd4281a6bc214..104cc5c7a8a93f778a0e3e78438a4660576e77c4 100644 --- a/lib_util/hrtf_file_reader.h +++ b/lib_util/hrtf_file_reader.h @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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.c b/lib_util/ism_file_reader.c index f6f0206392b93aaddc2ee8a3dfea8b175a1c276b..f3d782aeb7484e7c38b80c103fba546c8f57e216 100644 --- a/lib_util/ism_file_reader.c +++ b/lib_util/ism_file_reader.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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 886ebb34be8b57a4e5b869e2cd75ceb7573918ca..c785cc294bde7cbd4c37e9bfb76856f9b172f5c8 100644 --- a/lib_util/ism_file_reader.h +++ b/lib_util/ism_file_reader.h @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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 093414293250ef712320a3698fe79f3e88ad9d95..94bab6dd279ae62eed74ef6a52dd6df614dcb667 100644 --- a/lib_util/ism_file_writer.c +++ b/lib_util/ism_file_writer.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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 34cc4e711c0da47e670b9eb38c93af823e0ca08c..6bf1a3e3171dc2f63a598554a88415a3335d425b 100644 --- a/lib_util/ism_file_writer.h +++ b/lib_util/ism_file_writer.h @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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 01ca956f75a8527b62b560b9e183f1f07b1ff51f..b657ab78929f906eb29dd6c3435af8a7f91c73ca 100644 --- a/lib_util/jbm_file_reader.c +++ b/lib_util/jbm_file_reader.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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 379506ee6a63b86a440b55d861a3cb981a5ff899..e824e1eee9f00bbb821664a0515a69f1ce987d38 100644 --- a/lib_util/jbm_file_reader.h +++ b/lib_util/jbm_file_reader.h @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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 6e26fe7035d2bfb21de508f8906040049a5556b6..76a5a67d2566db5d87ecefb0bb7d21bbeb9afcaf 100644 --- a/lib_util/jbm_file_writer.c +++ b/lib_util/jbm_file_writer.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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 fad5ec81e8bd2d0cb0d4cf5ffae8052760d3ebf9..aca768a1a0e75c88dd01910bf00854cabc0dc2f2 100644 --- a/lib_util/jbm_file_writer.h +++ b/lib_util/jbm_file_writer.h @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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 90b734d07a083d6026b7385377111c27dddba664..f4f43e496e358d9dae0ca00a8478fe342a3fc121 100644 --- a/lib_util/ls_custom_file_reader.c +++ b/lib_util/ls_custom_file_reader.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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,8 +33,8 @@ #include "ls_custom_file_reader.h" #include #include -#include "ivas_prot.h" -#include "prot.h" +#include "ivas_prot_fx.h" +#include "prot_fx.h" struct LsCustomFileReader diff --git a/lib_util/ls_custom_file_reader.h b/lib_util/ls_custom_file_reader.h index b5def337621e2465952aa70d087c236cc0835b82..46b20a4ff013827acf56198b2b6f917952f21201 100644 --- a/lib_util/ls_custom_file_reader.h +++ b/lib_util/ls_custom_file_reader.h @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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 5b8d759c24748eb6a86669c76d7ffcd68cffe235..efab80b79547db87abeb0a4f44e1e72dbc1a3637 100644 --- a/lib_util/masa_file_reader.c +++ b/lib_util/masa_file_reader.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other @@ -31,7 +31,6 @@ *******************************************************************************************************/ #include "masa_file_reader.h" -#include "ivas_prot.h" #include "ivas_stat_com.h" #include #include diff --git a/lib_util/masa_file_reader.h b/lib_util/masa_file_reader.h index de55035c7b072740dbd3678921e5eaaf5899d0c7..7510598c3bf16a9690be159e7da3fd1187fc6d1d 100644 --- a/lib_util/masa_file_reader.h +++ b/lib_util/masa_file_reader.h @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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 8bf55ba86ac8fc3f45786d1d0c441faf5f03d9ab..0939d0829ce7a4a2bc7a8b1718eea70694c37bf5 100644 --- a/lib_util/masa_file_writer.c +++ b/lib_util/masa_file_writer.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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.h b/lib_util/masa_file_writer.h index d7f53d4b6c7b3aa307142d25f635e24e009e4ad5..2d476e28f037e45af8a957b77015c1582bff2ef0 100644 --- a/lib_util/masa_file_writer.h +++ b/lib_util/masa_file_writer.h @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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.c b/lib_util/mime_io.c index 8a6262953780bd20d6ca31f0de50c99af7e0f210..2976e1895feea86a4a9d03cdca6571ee8ebd3d5a 100644 --- a/lib_util/mime_io.c +++ b/lib_util/mime_io.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other @@ -32,7 +32,7 @@ #include "mime_io.h" #include "mime.h" -#include "prot.h" +#include "prot_fx.h" #include "string.h" #include #include diff --git a/lib_util/mime_io.h b/lib_util/mime_io.h index 6ce5070c44bf5817a76a78d3ee542acad801aed7..dbd21c9c79d2fd67d834b4e3364b0f714546bc36 100644 --- a/lib_util/mime_io.h +++ b/lib_util/mime_io.h @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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 692f8c58d06492d4efb6f8a0bc3b2c35fc74c154..92c1a2fedaeeea30a34e56f5cdbd0d1444940224 100644 --- a/lib_util/render_config_reader.c +++ b/lib_util/render_config_reader.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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,7 +37,7 @@ #include #include #include "cmdl_tools.h" -#include "prot.h" +#include "prot_fx.h" /*------------------------------------------------------------------------------------------* @@ -1069,7 +1069,11 @@ static void strip_spaces( while ( pStr[read_idx] ) { +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( !isspace( (int32_t) pStr[read_idx] ) && !iscntrl( (int32_t) pStr[read_idx] ) ) +#else if ( !isspace( pStr[read_idx] ) && !iscntrl( pStr[read_idx] ) ) +#endif { pStr[write_idx++] = pStr[read_idx]; } @@ -1833,6 +1837,10 @@ ivas_error RenderConfigReader_read( uint32_t fgHasMethod, fgHasNBands, fgHasFreqs, fgHasDefaultGrid, fgHasStartFreq, fgHasFreqHop; uint32_t aeHasFgIdx, aeHasPredelay, aeHasRt60, aeHasDsr; uint32_t aeHasERsize, aeHasERabs; +#ifdef SPLIT_REND_WITH_HEAD_ROT + bool dofProvided = false; + bool poseCorrProvided = false; +#endif uint32_t nDP; uint32_t accDPIdx; @@ -2349,7 +2357,142 @@ ivas_error RenderConfigReader_read( free( pValue ); acIdx++; } - +#ifdef SPLIT_REND_WITH_HEAD_ROT + else if ( strcmp( chapter, "SPLITREND" ) == 0 && strlen( pParams ) != 0 ) + { + params_idx = 0; + pValue = (char *) calloc( strlen( pParams ), sizeof( char ) ); + 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 ) ) + { + errorHandler( item, ERROR_VALUE_INVALID ); + } + } + else if ( strcmp( item, "HQMODE" ) == 0 ) + { + if ( !sscanf( pValue, "%hd", &hRenderConfig->split_rend_config.hq_mode ) ) + { + errorHandler( item, ERROR_VALUE_INVALID ); + } + } + else if ( strcmp( item, "BITRATE" ) == 0 ) + { + if ( !sscanf( pValue, "%d", &hRenderConfig->split_rend_config.splitRendBitRate ) ) + { + errorHandler( item, ERROR_VALUE_INVALID ); + } + } + else if ( strcmp( item, "DOF" ) == 0 ) + { + dofProvided = true; + if ( !sscanf( pValue, "%hd", &hRenderConfig->split_rend_config.dof ) ) + { + errorHandler( item, ERROR_VALUE_INVALID ); + } + /* 0 DOF implies no pose correction */ + if ( hRenderConfig->split_rend_config.dof == 0 && !poseCorrProvided ) + { + hRenderConfig->split_rend_config.poseCorrectionMode = ISAR_SPLIT_REND_POSE_CORRECTION_MODE_NONE; + } + } + else if ( strcmp( item, "CODEC" ) == 0 ) + { + if ( strcmp( pValue, "LCLD" ) == 0 ) + { + hRenderConfig->split_rend_config.codec = ISAR_SPLIT_REND_CODEC_LCLD; + } + else if ( strcmp( pValue, "LC3PLUS" ) == 0 ) + { + hRenderConfig->split_rend_config.codec = ISAR_SPLIT_REND_CODEC_LC3PLUS; + } + else + { + errorHandler( pValue, ERROR_VALUE_INVALID ); + } + } + else if ( strcmp( item, "FRAMESIZE" ) == 0 ) + { + if ( !sscanf( pValue, "%hd", &hRenderConfig->split_rend_config.codec_frame_size_ms ) ) + { + errorHandler( item, ERROR_VALUE_INVALID ); + } + if ( hRenderConfig->split_rend_config.codec_frame_size_ms != 5 && + hRenderConfig->split_rend_config.codec_frame_size_ms != 10 && + hRenderConfig->split_rend_config.codec_frame_size_ms != 20 ) + { + errorHandler( item, ERROR_VALUE_INVALID ); + } + } + else if ( strcmp( item, "POSECORRECTION" ) == 0 ) + { + poseCorrProvided = true; + if ( strcmp( pValue, "CLDFB" ) == 0 ) + { + hRenderConfig->split_rend_config.poseCorrectionMode = ISAR_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB; + } + else if ( strcmp( pValue, "NONE" ) == 0 ) + { + hRenderConfig->split_rend_config.poseCorrectionMode = ISAR_SPLIT_REND_POSE_CORRECTION_MODE_NONE; + /* no pose correction implies 0 DOF */ + if ( !dofProvided ) + { + hRenderConfig->split_rend_config.dof = 0; + } + } + else + { + errorHandler( pValue, ERROR_VALUE_INVALID ); + } + } + else if ( strcmp( item, "RENDERER" ) == 0 ) + { + if ( strcmp( pValue, "CREND" ) == 0 ) + { + hRenderConfig->split_rend_config.rendererSelection = ISAR_SPLIT_REND_RENDERER_SELECTION_CREND; + } + else if ( strcmp( pValue, "FASTCONV" ) == 0 ) + { + hRenderConfig->split_rend_config.rendererSelection = ISAR_SPLIT_REND_RENDERER_SELECTION_FASTCONV; + } + else if ( strcmp( pValue, "PARAMBIN" ) == 0 ) + { + hRenderConfig->split_rend_config.rendererSelection = ISAR_SPLIT_REND_RENDERER_SELECTION_PARAMBIN; + } + else if ( strcmp( pValue, "TDREND" ) == 0 ) + { + hRenderConfig->split_rend_config.rendererSelection = ISAR_SPLIT_REND_RENDERER_SELECTION_TDREND; + } + else + { + errorHandler( pValue, ERROR_VALUE_INVALID ); + } + } +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + else if ( strcmp( item, "LC3PLUS_HIGHRES" ) == 0 ) + { + if ( !sscanf( pValue, "%hd", &hRenderConfig->split_rend_config.lc3plus_highres ) ) + { + errorHandler( item, ERROR_VALUE_INVALID ); + } + } +#endif +#ifdef DEBUGGING + else + { + fprintf( stderr, "Unsupported configuration property %s\n", item ); + } +#endif + } + free( pValue ); + } +#endif else if ( strcmp( chapter, "DIRECTIVITYSETTING" ) == 0 && strlen( pParams ) != 0 ) { params_idx = 0; diff --git a/lib_util/render_config_reader.h b/lib_util/render_config_reader.h index 445ced79abdb905cc094a5b8d51311d4f3f8f4ba..5edf73ded33d2cc91653c86276a86a92bc496432 100644 --- a/lib_util/render_config_reader.h +++ b/lib_util/render_config_reader.h @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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 987d40c85be0d83ee0cec3535529f808812d2ef7..a3f9544c8bec21ef677923ed1c382baf58308d81 100644 --- a/lib_util/rotation_file_reader.c +++ b/lib_util/rotation_file_reader.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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,7 +34,6 @@ #include #include #include -#include "prot.h" #include "prot_fx.h" @@ -121,15 +120,32 @@ ivas_error HeadRotationFileReading( ( headRotReader->frameCounter )++; - pQuaternion->w = w; - pQuaternion->x = x; - pQuaternion->y = y; - pQuaternion->z = z; + +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( w == -3.0f ) + { + pQuaternion->w_fx = floatToFixed_32( w, Q22 ); + pQuaternion->x_fx = floatToFixed_32( x, Q22 ); + pQuaternion->y_fx = floatToFixed_32( y, Q22 ); + pQuaternion->z_fx = floatToFixed_32( z, Q22 ); + pQuaternion->q_fact = Q22; + } + else + { + pQuaternion->w_fx = floatToFixed_32( w, Q31 ); + pQuaternion->x_fx = floatToFixed_32( x, Q31 ); + pQuaternion->y_fx = floatToFixed_32( y, Q31 ); + pQuaternion->z_fx = floatToFixed_32( z, Q31 ); + pQuaternion->q_fact = Q31; + } +#else pQuaternion->w_fx = floatToFixed_32( w, Q31 ); pQuaternion->x_fx = floatToFixed_32( x, Q31 ); pQuaternion->y_fx = floatToFixed_32( y, Q31 ); pQuaternion->z_fx = floatToFixed_32( z, Q31 ); pQuaternion->q_fact = Q31; +#endif + if ( pPos != NULL ) { pPos->x = posx; diff --git a/lib_util/rotation_file_reader.h b/lib_util/rotation_file_reader.h index 3f98ea5b0c8473bb691e2dcda2143d2ac7f393c3..8d6206bd6331744bb16e22a24ba0205c0a4ac4ca 100644 --- a/lib_util/rotation_file_reader.h +++ b/lib_util/rotation_file_reader.h @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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 9f8784947314990b7d0a41aae0a357510c1b7bec..e3eb4c1f4acb3329e0183bd97f820b318cb81400 100644 --- a/lib_util/rtpdump.c +++ b/lib_util/rtpdump.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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 b97ec97d839a231fa1aa98ee82016a719f1a94fa..5b8b31e8de3b7a6eda80cd7e6d8e808c6e9446b5 100644 --- a/lib_util/rtpdump.h +++ b/lib_util/rtpdump.h @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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_dec/core_dec_init.c b/lib_util/split_rend_bfi_file_reader.c similarity index 50% rename from lib_dec/core_dec_init.c rename to lib_util/split_rend_bfi_file_reader.c index 48464fb35ab2a99e1f471e34d301c609a2ab0b8f..4c5770f45930b668c5a6f83ebe20bc3801b130fd 100644 --- a/lib_dec/core_dec_init.c +++ b/lib_util/split_rend_bfi_file_reader.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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,55 +30,133 @@ *******************************************************************************************************/ -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - #include #include "options.h" -#include "stat_com.h" -#include "cnst.h" -#include "prot.h" -#include "rom_com.h" -#include "wmc_auto.h" +#include "split_rend_bfi_file_reader.h" +#ifdef SPLIT_REND_WITH_HEAD_ROT +#include #include "prot_fx.h" + +struct SplitRendBFIFileReader +{ + FILE *bfiFile; + int32_t frameCounter; + char *file_path; + bool fileRewind; + bool txtfile; +}; + + /*-----------------------------------------------------------------------* - * open_decoder_LPD() + * SplitRendBFIFileReader_open() * - * Initialization of state variables + * Allocate and initialize Split Renderer Frameloss file reader *-----------------------------------------------------------------------*/ + +ivas_error SplitRendBFIFileReader_open( + char *bfiFilePath, /* i : frame loss file name */ + SplitRendBFIFileReader **SplitRendBFIReader /* o : SplitRendBFIFileReader handle */ +) +{ + SplitRendBFIFileReader *self; + FILE *bfiFile; + bool txtfile; + + /* Open bfi file */ + if ( strlen( bfiFilePath ) < 1 ) + { + return IVAS_ERR_FAILED_FILE_OPEN; + } + + bfiFile = fopen( bfiFilePath, "r" ); + + if ( !bfiFile ) + { + return IVAS_ERR_FAILED_FILE_OPEN; + } + + txtfile = ( strcmp( bfiFilePath + strlen( bfiFilePath ) - 4, ".txt" ) ? false : true ); + + self = calloc( sizeof( SplitRendBFIFileReader ), 1 ); + self->bfiFile = bfiFile; + self->frameCounter = 0; + self->file_path = calloc( sizeof( char ), strlen( bfiFilePath ) + 1 ); + strcpy( self->file_path, bfiFilePath ); + self->fileRewind = false; + self->txtfile = txtfile; + + *SplitRendBFIReader = self; + + return IVAS_ERR_OK; +} + + /*-----------------------------------------------------------------------* - * tcxltp_dec_init() + * SplitRendBFIFileReading() * - * Initialization TCX-LTP handle + * Read values from the bfi file *-----------------------------------------------------------------------*/ + +ivas_error SplitRendBFIFileReading( + SplitRendBFIFileReader *SplitRendBFIReader, /* i/o: SplitRendBFIFileReader handle */ + int16_t *bfi ) +{ + if ( SplitRendBFIReader->txtfile ? 1 != fscanf( SplitRendBFIReader->bfiFile, "%hd", bfi ) : 1 != fread( bfi, sizeof( *bfi ), 1, SplitRendBFIReader->bfiFile ) ) + { + if ( feof( SplitRendBFIReader->bfiFile ) ) + { + rewind( SplitRendBFIReader->bfiFile ); + SplitRendBFIReader->fileRewind = true; + return SplitRendBFIFileReading( SplitRendBFIReader, bfi ); + } + return IVAS_ERR_FAILED_FILE_PARSE; + } + + ( SplitRendBFIReader->frameCounter )++; + + return IVAS_ERR_OK; +} + + /*-----------------------------------------------------------------------* - * reset_tcx_overl_buf() + * SplitRendBFIationFileReader_close() * - * Reset TCX core overlap buffers + * Deallocates memory for the Head-Tracking reader *-----------------------------------------------------------------------*/ -void reset_tcx_overl_buf_fx( - TCX_DEC_HANDLE hTcxDec /* i/o: TCX decoder handle */ +void SplitRendBFIFileReader_close( + SplitRendBFIFileReader **SplitRendBFIReader /* i/o: SplitRendBFIFileReader handle */ ) { - set16_fx( hTcxDec->old_syn_Overl, 0, L_FRAME32k / 2 ); /*HQ-CORE(bfi)->TCX don't need it*/ - hTcxDec->Q_old_syn_Overl = 0; - move16(); - set16_fx( hTcxDec->syn_Overl_TDAC, 0, L_FRAME32k / 2 ); /*HQ-CORE(bfi)->TCX don't need it*/ - hTcxDec->Q_syn_Overl_TDAC = 0; - move16(); - set16_fx( hTcxDec->syn_Overl, 0, L_FRAME32k / 2 ); /*HQ-CORE(bfi)->TCX don't need it*/ - hTcxDec->Q_syn_Overl = 0; - move16(); - set16_fx( hTcxDec->syn_Overl_TDACFB, 0, L_FRAME_MAX / 2 ); /*HQ-CORE(bfi)->TCX don't need it*/ - hTcxDec->Q_syn_Overl_TDACFB = 0; - move16(); + if ( SplitRendBFIReader == NULL || *SplitRendBFIReader == NULL ) + { + return; + } + + fclose( ( *SplitRendBFIReader )->bfiFile ); + free( ( *SplitRendBFIReader )->file_path ); + free( *SplitRendBFIReader ); + *SplitRendBFIReader = NULL; + return; } + /*-----------------------------------------------------------------------* - * acelp_plc_mdct_transition() + * SplitRendBFIFileReader_getFilePath() + * * - * Prepare MDCT OLA memories in TCX/HQ after ACELP PLC *-----------------------------------------------------------------------*/ + +const char *SplitRendBFIFileReader_getFilePath( + SplitRendBFIFileReader *SplitRendBFIReader /* i/o: SplitRendBFIFileReader handle */ +) +{ + if ( SplitRendBFIReader == NULL ) + { + return NULL; + } + + return SplitRendBFIReader->file_path; +} +#endif /* SPLIT_REND_WITH_HEAD_ROT */ diff --git a/lib_com/cng_exc.c b/lib_util/split_rend_bfi_file_reader.h similarity index 69% rename from lib_com/cng_exc.c rename to lib_util/split_rend_bfi_file_reader.h index 794b6de29ea09726ab410057f32ec3951a359579..679c424a1563cc4fd8de76651ef439565a03269c 100644 --- a/lib_com/cng_exc.c +++ b/lib_util/split_rend_bfi_file_reader.h @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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,28 +30,31 @@ *******************************************************************************************************/ -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ +#ifndef IVAS_SR_BFI_FILE_READER_H +#define IVAS_SR_BFI_FILE_READER_H -#include -#include "options.h" -#include -#include "cnst.h" -#include "prot.h" -#include "rom_com.h" -#include "wmc_auto.h" +#include "common_api_types.h" +#ifdef SPLIT_REND_WITH_HEAD_ROT -/*---------------------------------------------------------------------* - * Local constants - *---------------------------------------------------------------------*/ +typedef struct SplitRendBFIFileReader SplitRendBFIFileReader; -#define A2 0.2f -#define GAIN_VAR 0.000011f +ivas_error SplitRendBFIFileReader_open( + char *trajFilePath, /* i : head rotation trajectory file name */ + SplitRendBFIFileReader **SplitRendBFIReader /* o : SplitRendBFIFileReader handle */ +); +ivas_error SplitRendBFIFileReading( + SplitRendBFIFileReader *SplitRendBFIReader, /* i/o: SplitRendBFIFileReader handle */ + int16_t *bfi ); -/*-------------------------------------------------------* - * cng_params_upd() - * - * update CNG parameters - *-------------------------------------------------------*/ +void SplitRendBFIFileReader_close( + SplitRendBFIFileReader **SplitRendBFIReader /* i/o: SplitRendBFIFileReader handle */ +); + +const char *SplitRendBFIFileReader_getFilePath( + SplitRendBFIFileReader *SplitRendBFIReader /* i/o: SplitRendBFIFileReader handle */ +); + + +#endif /* SPLIT_REND_WITH_HEAD_ROT */ +#endif /* IVAS_SR_BFI_FILE_READER_H */ diff --git a/lib_util/split_render_file_read_write.c b/lib_util/split_render_file_read_write.c new file mode 100644 index 0000000000000000000000000000000000000000..065300c10ea94056103cc35668a7098a9ab7a9bc --- /dev/null +++ b/lib_util/split_render_file_read_write.c @@ -0,0 +1,431 @@ +/****************************************************************************************************** + + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository. All Rights Reserved. + + This software is protected by copyright law and by international treaties. + The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository retain full ownership rights in their respective contributions in + the software. This notice grants no license of any kind, including but not limited to patent + license, nor is any license granted by implication, estoppel or otherwise. + + Contributors are required to enter into the IVAS codec Public Collaboration agreement before making + contributions. + + This software is provided "AS IS", without any express or implied warranties. The software is in the + development stage. It is intended exclusively for experts who have experience with such software and + solely for the purpose of inspection. All implied warranties of non-infringement, merchantability + and fitness for a particular purpose are hereby disclaimed and excluded. + + Any dispute, controversy or claim arising under or in relation to providing this software shall be + submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in + accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and + the United Nations Convention on Contracts on the International Sales of Goods. + +*******************************************************************************************************/ + +#include +#include "options.h" +#include "split_render_file_read_write.h" +#ifdef SPLIT_REND_WITH_HEAD_ROT +#include +#include "prot_fx.h" + + +/*------------------------------------------------------------------------------------------* + * PreProc Macros + *------------------------------------------------------------------------------------------*/ + +#define SPLIT_RENDERER_FRAME_HEADER_LEN ( 12 ) + +/*------------------------------------------------------------------------------------------* + * Type definitions + *------------------------------------------------------------------------------------------*/ + +struct SplitFileReadWrite +{ + FILE *file; + uint32_t delay_ns; +}; + + +/*-----------------------------------------------------------------------------------------* + * Function split_rend_reader_open() + * + * open in read mode + *-----------------------------------------------------------------------------------------*/ + +ivas_error split_rend_reader_open( + SplitFileReadWrite **hhSplitRendFileReadWrite, + char *filename, + ISAR_SPLIT_REND_CODEC *codec, + ISAR_SPLIT_REND_POSE_CORRECTION_MODE *poseCorrection, + int16_t *codec_frame_size_ms +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + , + int16_t *isar_frame_size_ms, + int32_t *sampling_rate, + int16_t *lc3plus_highres +#endif +) +{ + SplitFileReadWrite *hSplitRendFileReadWrite; + size_t header_len, h; + char header[SPLIT_RENDERER_FRAME_HEADER_LEN] = "MAIN_SPLITH"; + char header_read[SPLIT_RENDERER_FRAME_HEADER_LEN]; + + if ( ( hSplitRendFileReadWrite = (SplitFileReadWrite *) malloc( sizeof( SplitFileReadWrite ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for split rendering writer\n" ) ); + } + + hSplitRendFileReadWrite->file = fopen( filename, "rb" ); + if ( hSplitRendFileReadWrite->file == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_FILE_READ, "\nCould not open split rend metadata file %s\n", filename ) ); + } + + header_len = strlen( header ); + + /*read frame header*/ + for ( h = 0; h < header_len; h++ ) + { + if ( fread( &header_read[h], sizeof( char ), 1, hSplitRendFileReadWrite->file ) != 1 ) + { + return IVAS_ERR_FAILED_FILE_READ; + } + } + + if ( strncmp( header_read, header, header_len ) ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_FILE_READ, "\nError split rend bitstream main header mismatch\n" ) ); + } + + fread( &hSplitRendFileReadWrite->delay_ns, sizeof( uint32_t ), 1, hSplitRendFileReadWrite->file ); + + /* read codec signalling */ + if ( fread( codec, sizeof( *codec ), 1, hSplitRendFileReadWrite->file ) != 1 ) + { + return IVAS_ERR_FAILED_FILE_READ; + } + + /* read pose correction signalling */ + if ( fread( poseCorrection, sizeof( *poseCorrection ), 1, hSplitRendFileReadWrite->file ) != 1 ) + { + return IVAS_ERR_FAILED_FILE_READ; + } + /* read transport codec frame size signalling */ + if ( fread( codec_frame_size_ms, sizeof( *codec_frame_size_ms ), 1, hSplitRendFileReadWrite->file ) != 1 ) + { + return IVAS_ERR_FAILED_FILE_READ; + } +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + /* read isar bitstream frame size signalling */ + if ( fread( isar_frame_size_ms, sizeof( *isar_frame_size_ms ), 1, hSplitRendFileReadWrite->file ) != 1 ) + { + return IVAS_ERR_FAILED_FILE_READ; + } + /* read sampling rate signalling */ + if ( fread( sampling_rate, sizeof( *sampling_rate ), 1, hSplitRendFileReadWrite->file ) != 1 ) + { + return IVAS_ERR_FAILED_FILE_READ; + } + /* read LC3plus highres signalling */ + if ( fread( lc3plus_highres, sizeof( *lc3plus_highres ), 1, hSplitRendFileReadWrite->file ) != 1 ) + { + return IVAS_ERR_FAILED_FILE_READ; + } +#endif + + *hhSplitRendFileReadWrite = hSplitRendFileReadWrite; + + return IVAS_ERR_OK; +} + + +/*-----------------------------------------------------------------------------------------* + * Function split_rend_writer_open() + * + * open in write mode + *-----------------------------------------------------------------------------------------*/ + +ivas_error split_rend_writer_open( + SplitFileReadWrite **hhSplitRendFileReadWrite, + char *filename, + const int16_t delayNumSamples, + const int32_t delayTimeScale, + ISAR_SPLIT_REND_CODEC codec, + ISAR_SPLIT_REND_POSE_CORRECTION_MODE poseCorrection, + int16_t codec_frame_size_ms +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + , + const int16_t isar_frame_size_ms, + const int32_t sampling_rate, + const int16_t lc3plus_highres +#endif +) +{ + SplitFileReadWrite *hSplitRendFileReadWrite; + size_t header_len, h; + char header[SPLIT_RENDERER_FRAME_HEADER_LEN] = "MAIN_SPLITH"; + + if ( filename == NULL ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } + + if ( ( hSplitRendFileReadWrite = (SplitFileReadWrite *) malloc( sizeof( SplitFileReadWrite ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for split rendering writer\n" ) ); + } + + hSplitRendFileReadWrite->file = fopen( filename, "wb" ); + if ( hSplitRendFileReadWrite->file == NULL ) + { + return IVAS_ERR_FAILED_FILE_OPEN; + } + + header_len = strlen( header ); + + /* write frame header */ + for ( h = 0; h < header_len; h++ ) + { + if ( fwrite( &header[h], sizeof( char ), 1, hSplitRendFileReadWrite->file ) != 1 ) + { + return IVAS_ERR_END_OF_FILE; + } + } + hSplitRendFileReadWrite->delay_ns = (int32_t) ( (float) delayNumSamples * 1000000000.0f / (float) delayTimeScale ); + fwrite( &hSplitRendFileReadWrite->delay_ns, sizeof( int32_t ), 1, hSplitRendFileReadWrite->file ); + + /* Write codec signalling */ + if ( fwrite( &codec, sizeof( codec ), 1, hSplitRendFileReadWrite->file ) != 1 ) + { + return IVAS_ERR_FAILED_FILE_WRITE; + } + + /* Write pose correction signalling */ + if ( fwrite( &poseCorrection, sizeof( poseCorrection ), 1, hSplitRendFileReadWrite->file ) != 1 ) + { + return IVAS_ERR_FAILED_FILE_WRITE; + } + /* Write transport codec frame size signalling */ + if ( fwrite( &codec_frame_size_ms, sizeof( codec_frame_size_ms ), 1, hSplitRendFileReadWrite->file ) != 1 ) + { + return IVAS_ERR_FAILED_FILE_WRITE; + } +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + /* Write isar bit stream frame size signalling */ + if ( fwrite( &isar_frame_size_ms, sizeof( isar_frame_size_ms ), 1, hSplitRendFileReadWrite->file ) != 1 ) + { + return IVAS_ERR_FAILED_FILE_WRITE; + } + /* Write sampling rate signalling */ + if ( fwrite( &sampling_rate, sizeof( sampling_rate ), 1, hSplitRendFileReadWrite->file ) != 1 ) + { + return IVAS_ERR_FAILED_FILE_WRITE; + } + /* Write LC3plus highres signalling */ + if ( fwrite( &lc3plus_highres, sizeof( lc3plus_highres ), 1, hSplitRendFileReadWrite->file ) != 1 ) + { + return IVAS_ERR_FAILED_FILE_WRITE; + } +#endif + + *hhSplitRendFileReadWrite = hSplitRendFileReadWrite; + + return IVAS_ERR_OK; +} + + +/*-----------------------------------------------------------------------------------------* + * Function split_rend_reader_writer_close() + * + * + *-----------------------------------------------------------------------------------------*/ + +void split_rend_reader_writer_close( + SplitFileReadWrite **hhSplitRendFileReadWrite ) +{ + if ( ( *hhSplitRendFileReadWrite ) != NULL ) + { + if ( ( *hhSplitRendFileReadWrite )->file != NULL ) + { + fclose( ( *hhSplitRendFileReadWrite )->file ); + ( *hhSplitRendFileReadWrite )->file = NULL; + } + + free( *hhSplitRendFileReadWrite ); + *hhSplitRendFileReadWrite = NULL; + } + + return; +} + + +/*-----------------------------------------------------------------------------------------* + * Function split_rend_write_bitstream_to_file() + * + * + *-----------------------------------------------------------------------------------------*/ + +ivas_error split_rend_write_bitstream_to_file( + SplitFileReadWrite *hSplitRendFileReadWrite, + uint8_t *bits, + int32_t *bits_read, + int32_t *bits_written ) +{ + char header[SPLIT_RENDERER_FRAME_HEADER_LEN] = "SPLIT_FRAME"; + size_t header_len, i, num_bytes; + uint8_t version = 0; + + if ( hSplitRendFileReadWrite == NULL ) + { + return IVAS_ERR_FAILED_FILE_READ; + } + + if ( hSplitRendFileReadWrite->file == NULL ) + { + return IVAS_ERR_FAILED_FILE_WRITE; + } + + header_len = strlen( header ); + + /* write frame header */ + for ( i = 0; i < header_len; i++ ) + { + if ( fwrite( &header[i], sizeof( char ), 1, hSplitRendFileReadWrite->file ) != 1 ) + { + return IVAS_ERR_FAILED_FILE_WRITE; + } + } + + /* Write versioning signalling */ + if ( fwrite( &version, 1, 1, hSplitRendFileReadWrite->file ) != 1 ) + { + return IVAS_ERR_FAILED_FILE_WRITE; + } + + /* write num bytes */ + if ( fwrite( bits_written, sizeof( int32_t ), 1, hSplitRendFileReadWrite->file ) != 1 ) + { + return IVAS_ERR_FAILED_FILE_WRITE; + } + + num_bytes = ( *bits_written + 7 ) >> 3; + if ( fwrite( bits, sizeof( uint8_t ), num_bytes, hSplitRendFileReadWrite->file ) != num_bytes ) + { + return IVAS_ERR_FAILED_FILE_WRITE; + } + + *bits_read = 0; + *bits_written = 0; + + return IVAS_ERR_OK; +} + + +/*-----------------------------------------------------------------------------------------* + * Function split_rend_read_bits_from_file() + * + * + *-----------------------------------------------------------------------------------------*/ + +ivas_error split_rend_read_bits_from_file( + SplitFileReadWrite *hSplitRendFileReadWrite, + uint8_t *bits, + int32_t *bits_read, + int32_t *bits_written ) +{ + char header[SPLIT_RENDERER_FRAME_HEADER_LEN] = "SPLIT_FRAME"; + char header_read[SPLIT_RENDERER_FRAME_HEADER_LEN]; + int32_t header_len, i, num_bytes, bit_len = 0; + uint8_t version; + + if ( hSplitRendFileReadWrite == NULL ) + { + return IVAS_ERR_FAILED_FILE_READ; + } + + if ( hSplitRendFileReadWrite->file == NULL ) + { + return IVAS_ERR_FAILED_FILE_READ; + } + + header_len = (int32_t) strlen( header ); + + /* read frame header */ + for ( i = 0; i < header_len; i++ ) + { + if ( fread( &header_read[i], sizeof( char ), 1, hSplitRendFileReadWrite->file ) != 1 ) + { + return IVAS_ERR_END_OF_FILE; + } + } + + if ( strncmp( header_read, header, header_len ) ) + { + fprintf( stderr, "Error bitstream frame header mismatch\n" ); + return IVAS_ERR_FAILED_FILE_READ; + } + + /* read versioning signalling */ + if ( fread( &version, 1, 1, hSplitRendFileReadWrite->file ) != 1 ) + { + return IVAS_ERR_FAILED_FILE_WRITE; + } + if ( version != 0 ) + { + fprintf( stderr, "Error bitstream version mismatch\n" ); + return IVAS_ERR_FAILED_FILE_READ; + } + + /* write num bytes */ + if ( fread( &bit_len, sizeof( int32_t ), 1, hSplitRendFileReadWrite->file ) != 1 ) + { + return IVAS_ERR_FAILED_FILE_READ; + } + num_bytes = ( bit_len + 7 ) >> 3; + + if ( fread( bits, sizeof( uint8_t ), num_bytes, hSplitRendFileReadWrite->file ) != (uint32_t) num_bytes ) + { + return IVAS_ERR_FAILED_FILE_READ; + } + for ( i = 0; i < ISAR_SPLIT_REND_ADDITIONAL_BYTES_TO_READ; i++ ) + { + bits[num_bytes + i] = 0; + } + + *bits_read = 0; + *bits_written = bit_len; + + return IVAS_ERR_OK; +} + + +/*-----------------------------------------------------------------------------------------* + * Function split_rend_read_pre_rend_delay_ns() + * + * + *-----------------------------------------------------------------------------------------*/ + +ivas_error split_rend_read_pre_rend_delay_ns( + SplitFileReadWrite *hSplitRendFileReadWrite, + uint32_t *delay_ns ) +{ + if ( hSplitRendFileReadWrite == NULL ) + { + return IVAS_ERR_FAILED_FILE_READ; + } + + *delay_ns = hSplitRendFileReadWrite->delay_ns; + + return IVAS_ERR_OK; +} +#endif /* SPLIT_REND_WITH_HEAD_ROT */ diff --git a/lib_dec/peak_vq_dec.c b/lib_util/split_render_file_read_write.h similarity index 51% rename from lib_dec/peak_vq_dec.c rename to lib_util/split_render_file_read_write.h index 7b039f26f64469656acd050fba743ef13c496c80..bdda7e59893446ef9501f87464f1463474c119a9 100644 --- a/lib_dec/peak_vq_dec.c +++ b/lib_util/split_render_file_read_write.h @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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,48 +30,70 @@ *******************************************************************************************************/ -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include -#include "options.h" -#include -#include "cnst.h" -#include "prot.h" -#include "rom_com.h" -#include "wmc_auto.h" - - -/*------------------------------------------------------------------------* - * Local function prototypes - *------------------------------------------------------------------------*/ - - -/*-------------------------------------------------------------------------- - * hvq_dec() - * - * HVQ decoder - *--------------------------------------------------------------------------*/ - - -/*-------------------------------------------------------------------------- - * peak_vq_dec() - * - * Vector de-quantization of MDCT peaks - *--------------------------------------------------------------------------*/ - - -/*-------------------------------------------------------------------------- - * dequant_peaks() - * - * Reads codebook vector and scales peak - *--------------------------------------------------------------------------*/ - - -/*-------------------------------------------------------------------------- - * hvq_dec_pos() - * - * HVQ decode peak positions - *--------------------------------------------------------------------------*/ +#ifndef SPLIT_RENDER_FILE_READ_WRITE_H +#define SPLIT_RENDER_FILE_READ_WRITE_H + +#include "common_api_types.h" +#ifdef SPLIT_REND_WITH_HEAD_ROT + +typedef struct SplitFileReadWrite SplitFileReadWrite; + +/* Allocates and initializes a a split renderer reader instance */ +ivas_error split_rend_reader_open( + SplitFileReadWrite **hhSplitRendFileReadWrite, + char *filename, + ISAR_SPLIT_REND_CODEC *codec, + ISAR_SPLIT_REND_POSE_CORRECTION_MODE *poseCorrection, + int16_t *codec_frame_size_ms +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + , + int16_t *isar_frame_size_ms, + int32_t *sampling_rate, + int16_t *lc3plus_highres +#endif +); + + +/* Allocates and initializes a a split renderer writer instance */ +ivas_error split_rend_writer_open( + SplitFileReadWrite **hhSplitRendFileReadWrite, + char *filename, + const int16_t delayNumSamples, + const int32_t delayTimeScale, + ISAR_SPLIT_REND_CODEC codec, + ISAR_SPLIT_REND_POSE_CORRECTION_MODE poseCorrection, + int16_t codec_frame_size_ms +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + , + const int16_t isar_frame_size_ms, + const int32_t sampling_rate, + const int16_t lc3plus_highres +#endif +); + + +/* Closes the split renderer reader/writer and deallocates memory */ +void split_rend_reader_writer_close( + SplitFileReadWrite **hhSplitRendFileReadWrite ); + +/*write split rend coded bitstream to file */ +ivas_error split_rend_write_bitstream_to_file( + SplitFileReadWrite *hSplitRendFileReadWrite, + uint8_t *bits, + int32_t *bits_read, + int32_t *bits_written ); + +/* read split rend coded bits from file */ +ivas_error split_rend_read_bits_from_file( + SplitFileReadWrite *hSplitRendFileReadWrite, + uint8_t *bits, + int32_t *bits_read, + int32_t *bits_written ); + +/* read split pre rend delay */ +ivas_error split_rend_read_pre_rend_delay_ns( + SplitFileReadWrite *hSplitRendFileReadWrite, + uint32_t *delay_ns ); + +#endif /* SPLIT_REND_WITH_HEAD_ROT */ +#endif /* SPLIT_RENDER_FILE_READ_WRITE_H */ diff --git a/lib_util/test_fft.c b/lib_util/test_fft.c index 5c0e2b33f618e4ae557dd3caa9a648146d59690c..1b52fe3512080b239eba547175ecc7bd3e758bfc 100644 --- a/lib_util/test_fft.c +++ b/lib_util/test_fft.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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/test_fft.h b/lib_util/test_fft.h index 7a3567f895e39442e711a9d463d932932be92689..6c962909072a7f02a71735bc6c860c44c8975abf 100644 --- a/lib_util/test_fft.h +++ b/lib_util/test_fft.h @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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/test_mdct.c b/lib_util/test_mdct.c index 91095df388e134832d9d2c985626eb88f088b635..69d83588da32356d4ea43d4512beea7be73244e2 100644 --- a/lib_util/test_mdct.c +++ b/lib_util/test_mdct.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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 0fd1b7a65b47e0ee1276fd937cbd9abce4d55b25..b86d97c9640f1e91427a4b6cf8731df62a1596bb 100644 --- a/lib_util/tinywavein_c.h +++ b/lib_util/tinywavein_c.h @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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 9b11e325a72f5bf33ad5a84763244b00c2b841df..693beccf9557dfaf7d6a507cb614064f76049f03 100644 --- a/lib_util/tinywaveout_c.h +++ b/lib_util/tinywaveout_c.h @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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.c b/lib_util/vector3_pair_file_reader.c index 380e69e278188f84d66a2456f594038f855767af..5745e95955616a19c7e95adf68d2dda74a908ff9 100644 --- a/lib_util/vector3_pair_file_reader.c +++ b/lib_util/vector3_pair_file_reader.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other @@ -35,7 +35,6 @@ #include #include #include -#include "prot.h" #include "options.h" /* only included to get access to the feature-defines */ #include "prot_fx.h" #include "ivas_prot_fx.h" diff --git a/lib_util/vector3_pair_file_reader.h b/lib_util/vector3_pair_file_reader.h index 3255fb315442f4f5544e88d1cf62595be837e4af..6515d32d58f68c5088204f7fa1aae667ad3140cb 100644 --- a/lib_util/vector3_pair_file_reader.h +++ b/lib_util/vector3_pair_file_reader.h @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. 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 25275a79516b91aa8a0d3fa8131155cd441f5e68..9b1ab852d136d9976a04d7d1bdb1b54cbd30d6ff 100644 --- a/readme.txt +++ b/readme.txt @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other